diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..59b2e91 --- /dev/null +++ b/.gitignore @@ -0,0 +1,15 @@ +node_modules +.env +coverage +coverage.json +typechain +typechain-types +.DS_Store + +# Hardhat files +cache +artifacts + +# Foundry files +out +cache_forge \ No newline at end of file diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..888d42d --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "lib/forge-std"] + path = lib/forge-std + url = https://github.com/foundry-rs/forge-std diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..2da4e1f --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2023 TrustWallet + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..2c3cb53 --- /dev/null +++ b/README.md @@ -0,0 +1,118 @@ +# Barz + +A Secure, Modular, Upgradeable Smart Contract Wallet enabling mass adoption of Web3 +```bash + ________ ________ ________ ________ +|\ __ \|\ __ \|\ __ \\_____ \ +\ \ \|\ /\ \ \|\ \ \ \|\ \|___/ /| + \ \ __ \ \ __ \ \ _ _\ / / / + \ \ \|\ \ \ \ \ \ \ \\ \|/ /_/__ + \ \_______\ \__\ \__\ \__\\ _\\________\ + \|_______|\|__|\|__|\|__|\|__\|_______| +``` + +- [Barz](#barz) + - [Architecture](#architecture) + - [Modularity](#modularity) + - [Storage](#storage) + - [Upgrade](#upgrade) + - [Security](#security) + - [Architecture Diagram](#architecture-diagram) + - [Modular Signature](#modular-signature) + - [Project setup](#project-setup) + - [Install dependencies](#install-dependencies) + - [Test contracts](#test-contracts) + - [Compile contracts](#compile-contracts) + + +## Architecture + +### Modularity +Modularity is one of the key principles in software engineering. Modular architecture and code enable high reusability, easy maintainability & testing, lesser interdependency between components, and most importantly provide straightforward purpose and functionality that reduce code bugs and security issues. + +Barz also considers Modularity as the key principle across the overall architecture and at the code level. + +For modularity, we impose the [EIP-2535 Diamond, Multi-Facet Proxy](https://eips.ethereum.org/EIPS/eip-2535) standard and provide each feature-set in a single facet attached to Diamond(Barz). +These modules include: +* Account Facet +* Signature Verification Facet + * Secp256k1 Verification Facet (ECDSA on K1 curve) + * Secp256r1 Verification Facet (P256 - Passkey) + * Multi-sig Facet +* DiamondCut Facet +* DiamondLoupe Facet +* Signature Migration Facet +* Restrictions Facet +* Guardian Facet +* Account Recovery Facet +* Lock Facet +* Token Receiver Facet + +Each of these modules can be attached and detached by the owner whenever they want. + +#### Storage +Barz detaches the storage of each module through `FacetStorage`, and Barz modules will only access the `FacetStorage` the module needs. This reduces the chance of accessing unneeded storage and unwanted modification of storage from modules, especially during implementation upgrade. +With this architecture of detaching the storage each module use, Barz helps prevent each module from having storage collisions which reduces introducing potential vulnerability in proxy pattern. + +#### Upgrade +Barz's architecture also provides benefits on upgrades. While the conventional proxy pattern requires upgrading the whole logic implementation to upgrade a part of it, Barz only needs relevant modules to be replaced accordingly, which introduces *Modular Upgradeability* to Accounts. + +#### Security +Modular architecture helps to break down the code into smaller modules, which contributes to isolating and limiting the functionality of each module. This helps to reduce the attack surface and limit the potential damage caused by a security breach in a module. This is maximized together with Barz's architecture of only accessing to the storage the module needs. + +### Architecture Diagram +![Barz Facet Architecture](./docs/images/Barz_Facet_Architecture.png) + +### Storage Architecture Diagram +![Barz Storage Architecture](./docs/images/Barz_Storage_Architecture.png) + +### Modular signature +![Barz Modular Signature Architecture](./docs/images/Barz_Modular_Signature_Architecture.png) +Unlike other upgradeable architecture which needs an upgrade of the whole logic contract or the whole module containing the feature set, the architecture of Barz supports modular upgradeability for each function, allowing maximum modularity and upgradeability in the wallet contract. + +As a form of this, our account contract **"Barz"** supports multiple signature scheme. Users will be able to change the signature scheme very seamlessly with function calls on the account contract. +This enables users to multiple options of wallet UX, for example: + +* Users wanting a seamless interaction, and no privateKey back up. +They can use **ECDSA on Secp256r1** signature scheme and use the passkey("WebAuthn") to securely protect their private key in the password manager (e.g., iCloud keychain). + +* Users wanting to use the conventional wallet style or hardware wallets might want to use the ECDSA("Secp256k1") signature scheme for signature verification. + +*Currently, we are supporting 2 signature schemes(ECDSA on Secp256k1 & Secp256r1 Curve), however, we'll continue to expand our support for multiple different signature schemes including BLS & PQC, etc* + +This is enabled by a modular architecture of having signature facets being attached and detached to the account facet according to the preference of the user's regarding the UX each signature scheme could provide. + +#### Signature Scheme Update process +During the signature scheme update, the updating function should check the following: +* Check the signature of Owner and Guardians (if exists) +* Check if the new signature facet contract is registered to the Facet Registry +* Initialize the storage of existing signature to 0 +* Initialize the storage of new signature to new signer + + +## Project setup + +### Install dependencies +``` +yarn +``` + +### Compile contracts +``` +yarn compile +``` + +### Test contracts +``` +yarn test +``` + +### Check Contract size +``` +yarn size +``` + +### Foundry test +``` +forge test +``` \ No newline at end of file diff --git a/audit/Certik_Trustwallet-barz-Audit.pdf b/audit/Certik_Trustwallet-barz-Audit.pdf new file mode 100644 index 0000000..537a003 Binary files /dev/null and b/audit/Certik_Trustwallet-barz-Audit.pdf differ diff --git a/audit/Halborn_Trustwallet-barz-Audit.pdf b/audit/Halborn_Trustwallet-barz-Audit.pdf new file mode 100644 index 0000000..fd00100 Binary files /dev/null and b/audit/Halborn_Trustwallet-barz-Audit.pdf differ diff --git a/contracts/Barz.sol b/contracts/Barz.sol new file mode 100644 index 0000000..7b54e39 --- /dev/null +++ b/contracts/Barz.sol @@ -0,0 +1,89 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.21; + +import {LibDiamond} from "./libraries/LibDiamond.sol"; +import {IBarz} from "./interfaces/IBarz.sol"; + +/** + * @title Barz + * @dev A diamond proxy wallet with a modular & upgradeable architecture + * @author David Yongjun Kim (@Powerstream3604) + */ +contract Barz is IBarz { + /** + * @notice Initializes Barz with the given parameters. Barz account is intended to be created from Barz Factory for stable deployment. + * @dev This method makes a delegate call to account facet and account facet handles the initialization. + * With modular architecture, Barz encompasses wide spectrum of architecture and logic. + * The only requirement is account facet to comply with initialize() interface. + * Barz doesn't include built-in functions and is a full proxy, for maximum extensibility and modularity. + * @param _accountFacet Address of Account Facet in charge of the Barz initialization + * @param _verificationFacet Address of Verification Facet for verifying the signature. Could be any signature scheme + * @param _entryPoint Address of Entry Point contract + * @param _facetRegistry Address of Facet Registry. Facet Registry is a registry holding trusted facets that could be added to user's wallet + * @param _defaultFallBack Address of Default FallBack Handler. Middleware contract for more efficient deployment + * @param _ownerPublicKey Bytes of Owner Public Key using for initialization + */ + constructor( + address _accountFacet, + address _verificationFacet, + address _entryPoint, + address _facetRegistry, + address _defaultFallBack, + bytes memory _ownerPublicKey + ) payable { + bytes memory initCall = abi.encodeWithSignature( + "initialize(address,address,address,address,bytes)", + _verificationFacet, + _entryPoint, + _facetRegistry, + _defaultFallBack, + _ownerPublicKey + ); + (bool success, bytes memory result) = _accountFacet.delegatecall( + initCall + ); + if (!success || uint256(bytes32(result)) != 1) { + revert Barz__InitializationFailure(); + } + } + + /** + * @notice Fallback function for Barz complying with Diamond Standard with customization of adding Default Fallback Handler + * @dev Find facet for function that is called and execute the function if a facet is found and return any value. + */ + fallback() external payable { + LibDiamond.DiamondStorage storage ds; + bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION; + // get diamond storage + assembly { + ds.slot := position + } + // get facet from function selector + address facet = address(bytes20(ds.facets[msg.sig])); + if (facet == address(0)) + facet = ds.defaultFallbackHandler.facetAddress(msg.sig); + require(facet != address(0), "Barz: Function does not exist"); + // Execute external function from facet using delegatecall and return any value. + assembly { + // copy function selector and any arguments + calldatacopy(0, 0, calldatasize()) + // execute function call using the facet + let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0) + // get any return value + returndatacopy(0, 0, returndatasize()) + // return any return value or error back to the caller + switch result + case 0 { + revert(0, returndatasize()) + } + default { + return(0, returndatasize()) + } + } + } + + /** + * @notice Receive function to receive native token without data + */ + receive() external payable {} +} diff --git a/contracts/BarzFactory.sol b/contracts/BarzFactory.sol new file mode 100644 index 0000000..f460102 --- /dev/null +++ b/contracts/BarzFactory.sol @@ -0,0 +1,140 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.21; + +import {Barz} from "./Barz.sol"; +import {IBarzFactory} from "./interfaces/IBarzFactory.sol"; + +/** + * @title Barz Factory + * @dev Contract to easily deploy Barz to a pre-computed address with a single call + * @author David Yongjun Kim (@Powerstream3604) + */ +contract BarzFactory is IBarzFactory { + address public immutable accountFacet; + address public immutable entryPoint; + address public immutable facetRegistry; + address public immutable defaultFallback; + + /** + * @notice Sets the initialization data for Barz contract initialization + * @param _accountFacet Account Facet to be used to create Barz + * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF + * @param _facetRegistry Facet Registry to be used to create Barz + * @param _defaultFallback Default Fallback Handler to be used to create Barz + */ + constructor( + address _accountFacet, + address _entryPoint, + address _facetRegistry, + address _defaultFallback + ) { + accountFacet = _accountFacet; + entryPoint = _entryPoint; + facetRegistry = _facetRegistry; + defaultFallback = _defaultFallback; + } + + /** + * @notice Creates the Barz with a single call. It creates the Barz contract with the givent verification facet + * @param _verificationFacet Address of verification facet used for creating the barz account + * @param _owner Public Key of the owner to initialize barz account + * @param _salt Salt used for deploying barz with create2 + * @return barz Instance of Barz contract deployed with the given parameters + */ + function createAccount( + address _verificationFacet, + bytes calldata _owner, + uint256 _salt + ) external override returns (Barz barz) { + address addr = getAddress(_verificationFacet, _owner, _salt); + uint codeSize = addr.code.length; + if (codeSize > 0) { + return Barz(payable(addr)); + } + barz = new Barz{salt: bytes32(_salt)}( + accountFacet, + _verificationFacet, + entryPoint, + facetRegistry, + defaultFallback, + _owner + ); + emit BarzDeployed(address(barz)); + } + + /** + * @notice Calculates the address of Barz with the given parameters + * @param _verificationFacet Address of verification facet used for creating the barz account + * @param _owner Public Key of the owner to initialize barz account + * @param _salt Salt used for deploying barz with create2 + * @return barzAddress Precalculated Barz address + */ + function getAddress( + address _verificationFacet, + bytes calldata _owner, + uint256 _salt + ) public view override returns (address barzAddress) { + bytes memory bytecode = getBytecode( + accountFacet, + _verificationFacet, + entryPoint, + facetRegistry, + defaultFallback, + _owner + ); + bytes32 hash = keccak256( + abi.encodePacked( + bytes1(0xff), + address(this), + _salt, + keccak256(bytecode) + ) + ); + barzAddress = address(uint160(uint256(hash))); + } + + /** + * @notice Returns the bytecode of Barz with the given parameter + * @param _accountFacet Account Facet to be used to create Barz + * @param _verificationFacet Verification Facet to be used to create Barz + * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF + * @param _facetRegistry Facet Registry to be used to create Barz + * @param _defaultFallback Default Fallback Handler to be used to create Barz + * @param _ownerPublicKey Public Key of owner to be used to initialize Barz ownership + * @return barzBytecode Bytecode of Barz + */ + function getBytecode( + address _accountFacet, + address _verificationFacet, + address _entryPoint, + address _facetRegistry, + address _defaultFallback, + bytes calldata _ownerPublicKey + ) public pure override returns (bytes memory barzBytecode) { + bytes memory bytecode = type(Barz).creationCode; + barzBytecode = abi.encodePacked( + bytecode, + abi.encode( + _accountFacet, + _verificationFacet, + _entryPoint, + _facetRegistry, + _defaultFallback, + _ownerPublicKey + ) + ); + } + + /** + * @notice Returns the creation code of the Barz contract + * @return creationCode Creation code of Barz + */ + function getCreationCode() + public + pure + override + returns (bytes memory creationCode) + { + creationCode = type(Barz).creationCode; + } +} diff --git a/contracts/aa-4337/core/BaseAccount.sol b/contracts/aa-4337/core/BaseAccount.sol new file mode 100644 index 0000000..fcd2d94 --- /dev/null +++ b/contracts/aa-4337/core/BaseAccount.sol @@ -0,0 +1,117 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity 0.8.21; + +/* solhint-disable avoid-low-level-calls */ +/* solhint-disable no-empty-blocks */ + +import "../interfaces/IAccount.sol"; +import "../interfaces/IEntryPoint.sol"; +import "./Helpers.sol"; + +/** + * Basic account implementation. + * this contract provides the basic logic for implementing the IAccount interface - validateUserOp + * specific account implementation should inherit it and provide the account-specific logic + */ +abstract contract BaseAccount is IAccount { + using UserOperationLib for UserOperation; + + //return value in case of signature failure, with no time-range. + // equivalent to _packValidationData(true,0,0); + uint256 internal constant SIG_VALIDATION_FAILED = 1; + + /** + * Return the account nonce. + * This method returns the next sequential nonce. + * For a nonce of a specific key, use `entrypoint.getNonce(account, key)` + */ + function getNonce() public view virtual returns (uint256) { + return entryPoint().getNonce(address(this), 0); + } + + /** + * return the entryPoint used by this account. + * subclass should return the current entryPoint used by this account. + */ + function entryPoint() public view virtual returns (IEntryPoint); + + /** + * Validate user's signature and nonce. + * subclass doesn't need to override this method. Instead, it should override the specific internal validation methods. + */ + function validateUserOp( + UserOperation calldata userOp, + bytes32 userOpHash, + uint256 missingAccountFunds + ) external virtual override returns (uint256 validationData) { + _requireFromEntryPoint(); + validationData = _validateSignature(userOp, userOpHash); + _validateNonce(userOp.nonce); + _payPrefund(missingAccountFunds); + } + + /** + * ensure the request comes from the known entrypoint. + */ + function _requireFromEntryPoint() internal view virtual { + require( + msg.sender == address(entryPoint()), + "account: not from EntryPoint" + ); + } + + /** + * validate the signature is valid for this message. + * @param userOp validate the userOp.signature field + * @param userOpHash convenient field: the hash of the request, to check the signature against + * (also hashes the entrypoint and chain id) + * @return validationData signature and time-range of this operation + * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure, + * otherwise, an address of an "authorizer" contract. + * <6-byte> validUntil - last timestamp this operation is valid. 0 for "indefinite" + * <6-byte> validAfter - first timestamp this operation is valid + * If the account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure. + * Note that the validation code cannot use block.timestamp (or block.number) directly. + */ + function _validateSignature( + UserOperation calldata userOp, + bytes32 userOpHash + ) internal virtual returns (uint256 validationData); + + /** + * Validate the nonce of the UserOperation. + * This method may validate the nonce requirement of this account. + * e.g. + * To limit the nonce to use sequenced UserOps only (no "out of order" UserOps): + * `require(nonce < type(uint64).max)` + * For a hypothetical account that *requires* the nonce to be out-of-order: + * `require(nonce & type(uint64).max == 0)` + * + * The actual nonce uniqueness is managed by the EntryPoint, and thus no other + * action is needed by the account itself. + * + * @param nonce to validate + * + * solhint-disable-next-line no-empty-blocks + */ + function _validateNonce(uint256 nonce) internal view virtual {} + + /** + * sends to the entrypoint (msg.sender) the missing funds for this transaction. + * subclass MAY override this method for better funds management + * (e.g. send to the entryPoint more than the minimum required, so that in future transactions + * it will not be required to send again) + * @param missingAccountFunds the minimum value this method should send the entrypoint. + * this value MAY be zero, in case there is enough deposit, or the userOp has a paymaster. + */ + function _payPrefund(uint256 missingAccountFunds) internal virtual { + if (missingAccountFunds != 0) { + (bool success, ) = payable(msg.sender).call{ + value: missingAccountFunds, + gas: type(uint256).max + }(""); + (success); + //ignore failure (its EntryPoint's job to verify, not account.) + } + } +} diff --git a/contracts/aa-4337/core/EntryPoint.sol b/contracts/aa-4337/core/EntryPoint.sol new file mode 100644 index 0000000..3213208 --- /dev/null +++ b/contracts/aa-4337/core/EntryPoint.sol @@ -0,0 +1,864 @@ +/** + ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation. + ** Only one instance required on each chain. + **/ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity 0.8.21; + +/* solhint-disable avoid-low-level-calls */ +/* solhint-disable no-inline-assembly */ + +import "../interfaces/IAccount.sol"; +import "../interfaces/IPaymaster.sol"; +import "../interfaces/IEntryPoint.sol"; + +import "../utils/Exec.sol"; +import "./StakeManager.sol"; +import "./SenderCreator.sol"; +import "./Helpers.sol"; +import "./NonceManager.sol"; +import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; + +contract EntryPoint is + IEntryPoint, + StakeManager, + NonceManager, + ReentrancyGuard +{ + using UserOperationLib for UserOperation; + + SenderCreator private immutable senderCreator = new SenderCreator(); + + // internal value used during simulation: need to query aggregator. + address private constant SIMULATE_FIND_AGGREGATOR = address(1); + + // marker for inner call revert on out of gas + bytes32 private constant INNER_OUT_OF_GAS = hex"deaddead"; + + uint256 private constant REVERT_REASON_MAX_LEN = 2048; + + /** + * for simulation purposes, validateUserOp (and validatePaymasterUserOp) must return this value + * in case of signature failure, instead of revert. + */ + uint256 public constant SIG_VALIDATION_FAILED = 1; + + /** + * compensate the caller's beneficiary address with the collected fees of all UserOperations. + * @param beneficiary the address to receive the fees + * @param amount amount to transfer. + */ + function _compensate(address payable beneficiary, uint256 amount) internal { + require(beneficiary != address(0), "AA90 invalid beneficiary"); + (bool success, ) = beneficiary.call{value: amount}(""); + require(success, "AA91 failed send to beneficiary"); + } + + /** + * execute a user op + * @param opIndex index into the opInfo array + * @param userOp the userOp to execute + * @param opInfo the opInfo filled by validatePrepayment for this userOp. + * @return collected the total amount this userOp paid. + */ + function _executeUserOp( + uint256 opIndex, + UserOperation calldata userOp, + UserOpInfo memory opInfo + ) private returns (uint256 collected) { + uint256 preGas = gasleft(); + bytes memory context = getMemoryBytesFromOffset(opInfo.contextOffset); + + try this.innerHandleOp(userOp.callData, opInfo, context) returns ( + uint256 _actualGasCost + ) { + collected = _actualGasCost; + } catch { + bytes32 innerRevertCode; + assembly { + returndatacopy(0, 0, 32) + innerRevertCode := mload(0) + } + // handleOps was called with gas limit too low. abort entire bundle. + if (innerRevertCode == INNER_OUT_OF_GAS) { + //report paymaster, since if it is not deliberately caused by the bundler, + // it must be a revert caused by paymaster. + revert FailedOp(opIndex, "AA95 out of gas"); + } + + uint256 actualGas = preGas - gasleft() + opInfo.preOpGas; + collected = _handlePostOp( + opIndex, + IPaymaster.PostOpMode.postOpReverted, + opInfo, + context, + actualGas + ); + } + } + + /** + * Execute a batch of UserOperations. + * no signature aggregator is used. + * if any account requires an aggregator (that is, it returned an aggregator when + * performing simulateValidation), then handleAggregatedOps() must be used instead. + * @param ops the operations to execute + * @param beneficiary the address to receive the fees + */ + function handleOps( + UserOperation[] calldata ops, + address payable beneficiary + ) public nonReentrant { + uint256 opslen = ops.length; + UserOpInfo[] memory opInfos = new UserOpInfo[](opslen); + + unchecked { + for (uint256 i = 0; i < opslen; i++) { + UserOpInfo memory opInfo = opInfos[i]; + ( + uint256 validationData, + uint256 pmValidationData + ) = _validatePrepayment(i, ops[i], opInfo); + _validateAccountAndPaymasterValidationData( + i, + validationData, + pmValidationData, + address(0) + ); + } + + uint256 collected = 0; + emit BeforeExecution(); + + for (uint256 i = 0; i < opslen; i++) { + collected += _executeUserOp(i, ops[i], opInfos[i]); + } + + _compensate(beneficiary, collected); + } //unchecked + } + + /** + * Execute a batch of UserOperation with Aggregators + * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts) + * @param beneficiary the address to receive the fees + */ + function handleAggregatedOps( + UserOpsPerAggregator[] calldata opsPerAggregator, + address payable beneficiary + ) public nonReentrant { + uint256 opasLen = opsPerAggregator.length; + uint256 totalOps = 0; + for (uint256 i = 0; i < opasLen; i++) { + UserOpsPerAggregator calldata opa = opsPerAggregator[i]; + UserOperation[] calldata ops = opa.userOps; + IAggregator aggregator = opa.aggregator; + + //address(1) is special marker of "signature error" + require( + address(aggregator) != address(1), + "AA96 invalid aggregator" + ); + + if (address(aggregator) != address(0)) { + // solhint-disable-next-line no-empty-blocks + try aggregator.validateSignatures(ops, opa.signature) {} catch { + revert SignatureValidationFailed(address(aggregator)); + } + } + + totalOps += ops.length; + } + + UserOpInfo[] memory opInfos = new UserOpInfo[](totalOps); + + emit BeforeExecution(); + + uint256 opIndex = 0; + for (uint256 a = 0; a < opasLen; a++) { + UserOpsPerAggregator calldata opa = opsPerAggregator[a]; + UserOperation[] calldata ops = opa.userOps; + IAggregator aggregator = opa.aggregator; + + uint256 opslen = ops.length; + for (uint256 i = 0; i < opslen; i++) { + UserOpInfo memory opInfo = opInfos[opIndex]; + ( + uint256 validationData, + uint256 paymasterValidationData + ) = _validatePrepayment(opIndex, ops[i], opInfo); + _validateAccountAndPaymasterValidationData( + i, + validationData, + paymasterValidationData, + address(aggregator) + ); + opIndex++; + } + } + + uint256 collected = 0; + opIndex = 0; + for (uint256 a = 0; a < opasLen; a++) { + UserOpsPerAggregator calldata opa = opsPerAggregator[a]; + emit SignatureAggregatorChanged(address(opa.aggregator)); + UserOperation[] calldata ops = opa.userOps; + uint256 opslen = ops.length; + + for (uint256 i = 0; i < opslen; i++) { + collected += _executeUserOp(opIndex, ops[i], opInfos[opIndex]); + opIndex++; + } + } + emit SignatureAggregatorChanged(address(0)); + + _compensate(beneficiary, collected); + } + + /// @inheritdoc IEntryPoint + function simulateHandleOp( + UserOperation calldata op, + address target, + bytes calldata targetCallData + ) external override { + UserOpInfo memory opInfo; + _simulationOnlyValidations(op); + ( + uint256 validationData, + uint256 paymasterValidationData + ) = _validatePrepayment(0, op, opInfo); + ValidationData memory data = _intersectTimeRange( + validationData, + paymasterValidationData + ); + + numberMarker(); + uint256 paid = _executeUserOp(0, op, opInfo); + numberMarker(); + bool targetSuccess; + bytes memory targetResult; + if (target != address(0)) { + (targetSuccess, targetResult) = target.call(targetCallData); + } + revert ExecutionResult( + opInfo.preOpGas, + paid, + data.validAfter, + data.validUntil, + targetSuccess, + targetResult + ); + } + + // A memory copy of UserOp static fields only. + // Excluding: callData, initCode and signature. Replacing paymasterAndData with paymaster. + struct MemoryUserOp { + address sender; + uint256 nonce; + uint256 callGasLimit; + uint256 verificationGasLimit; + uint256 preVerificationGas; + address paymaster; + uint256 maxFeePerGas; + uint256 maxPriorityFeePerGas; + } + + struct UserOpInfo { + MemoryUserOp mUserOp; + bytes32 userOpHash; + uint256 prefund; + uint256 contextOffset; + uint256 preOpGas; + } + + /** + * inner function to handle a UserOperation. + * Must be declared "external" to open a call context, but it can only be called by handleOps. + */ + function innerHandleOp( + bytes memory callData, + UserOpInfo memory opInfo, + bytes calldata context + ) external returns (uint256 actualGasCost) { + uint256 preGas = gasleft(); + require(msg.sender == address(this), "AA92 internal call only"); + MemoryUserOp memory mUserOp = opInfo.mUserOp; + + uint callGasLimit = mUserOp.callGasLimit; + unchecked { + // handleOps was called with gas limit too low. abort entire bundle. + if ( + gasleft() < callGasLimit + mUserOp.verificationGasLimit + 5000 + ) { + assembly { + mstore(0, INNER_OUT_OF_GAS) + revert(0, 32) + } + } + } + + IPaymaster.PostOpMode mode = IPaymaster.PostOpMode.opSucceeded; + if (callData.length > 0) { + bool success = Exec.call(mUserOp.sender, 0, callData, callGasLimit); + if (!success) { + bytes memory result = Exec.getReturnData(REVERT_REASON_MAX_LEN); + if (result.length > 0) { + emit UserOperationRevertReason( + opInfo.userOpHash, + mUserOp.sender, + mUserOp.nonce, + result + ); + } + mode = IPaymaster.PostOpMode.opReverted; + } + } + + unchecked { + uint256 actualGas = preGas - gasleft() + opInfo.preOpGas; + //note: opIndex is ignored (relevant only if mode==postOpReverted, which is only possible outside of innerHandleOp) + return _handlePostOp(0, mode, opInfo, context, actualGas); + } + } + + /** + * generate a request Id - unique identifier for this request. + * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid. + */ + function getUserOpHash( + UserOperation calldata userOp + ) public view returns (bytes32) { + return + keccak256(abi.encode(userOp.hash(), address(this), block.chainid)); + } + + /** + * copy general fields from userOp into the memory opInfo structure. + */ + function _copyUserOpToMemory( + UserOperation calldata userOp, + MemoryUserOp memory mUserOp + ) internal pure { + mUserOp.sender = userOp.sender; + mUserOp.nonce = userOp.nonce; + mUserOp.callGasLimit = userOp.callGasLimit; + mUserOp.verificationGasLimit = userOp.verificationGasLimit; + mUserOp.preVerificationGas = userOp.preVerificationGas; + mUserOp.maxFeePerGas = userOp.maxFeePerGas; + mUserOp.maxPriorityFeePerGas = userOp.maxPriorityFeePerGas; + bytes calldata paymasterAndData = userOp.paymasterAndData; + if (paymasterAndData.length > 0) { + require( + paymasterAndData.length >= 20, + "AA93 invalid paymasterAndData" + ); + mUserOp.paymaster = address(bytes20(paymasterAndData[:20])); + } else { + mUserOp.paymaster = address(0); + } + } + + /** + * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp. + * @dev this method always revert. Successful result is ValidationResult error. other errors are failures. + * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data. + * @param userOp the user operation to validate. + */ + function simulateValidation(UserOperation calldata userOp) external { + UserOpInfo memory outOpInfo; + + _simulationOnlyValidations(userOp); + ( + uint256 validationData, + uint256 paymasterValidationData + ) = _validatePrepayment(0, userOp, outOpInfo); + StakeInfo memory paymasterInfo = _getStakeInfo( + outOpInfo.mUserOp.paymaster + ); + StakeInfo memory senderInfo = _getStakeInfo(outOpInfo.mUserOp.sender); + StakeInfo memory factoryInfo; + { + bytes calldata initCode = userOp.initCode; + address factory = initCode.length >= 20 + ? address(bytes20(initCode[0:20])) + : address(0); + factoryInfo = _getStakeInfo(factory); + } + + ValidationData memory data = _intersectTimeRange( + validationData, + paymasterValidationData + ); + address aggregator = data.aggregator; + bool sigFailed = aggregator == address(1); + ReturnInfo memory returnInfo = ReturnInfo( + outOpInfo.preOpGas, + outOpInfo.prefund, + sigFailed, + data.validAfter, + data.validUntil, + getMemoryBytesFromOffset(outOpInfo.contextOffset) + ); + + if (aggregator != address(0) && aggregator != address(1)) { + AggregatorStakeInfo memory aggregatorInfo = AggregatorStakeInfo( + aggregator, + _getStakeInfo(aggregator) + ); + revert ValidationResultWithAggregation( + returnInfo, + senderInfo, + factoryInfo, + paymasterInfo, + aggregatorInfo + ); + } + revert ValidationResult( + returnInfo, + senderInfo, + factoryInfo, + paymasterInfo + ); + } + + function _getRequiredPrefund( + MemoryUserOp memory mUserOp + ) internal pure returns (uint256 requiredPrefund) { + unchecked { + //when using a Paymaster, the verificationGasLimit is used also to as a limit for the postOp call. + // our security model might call postOp eventually twice + uint256 mul = mUserOp.paymaster != address(0) ? 3 : 1; + uint256 requiredGas = mUserOp.callGasLimit + + mUserOp.verificationGasLimit * + mul + + mUserOp.preVerificationGas; + + requiredPrefund = requiredGas * mUserOp.maxFeePerGas; + } + } + + // create the sender's contract if needed. + function _createSenderIfNeeded( + uint256 opIndex, + UserOpInfo memory opInfo, + bytes calldata initCode + ) internal { + if (initCode.length != 0) { + address sender = opInfo.mUserOp.sender; + if (sender.code.length != 0) + revert FailedOp(opIndex, "AA10 sender already constructed"); + address sender1 = senderCreator.createSender{ + gas: opInfo.mUserOp.verificationGasLimit + }(initCode); + if (sender1 == address(0)) + revert FailedOp(opIndex, "AA13 initCode failed or OOG"); + if (sender1 != sender) + revert FailedOp(opIndex, "AA14 initCode must return sender"); + if (sender1.code.length == 0) + revert FailedOp(opIndex, "AA15 initCode must create sender"); + address factory = address(bytes20(initCode[0:20])); + emit AccountDeployed( + opInfo.userOpHash, + sender, + factory, + opInfo.mUserOp.paymaster + ); + } + } + + /** + * Get counterfactual sender address. + * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation. + * this method always revert, and returns the address in SenderAddressResult error + * @param initCode the constructor code to be passed into the UserOperation. + */ + function getSenderAddress(bytes calldata initCode) public { + address sender = senderCreator.createSender(initCode); + revert SenderAddressResult(sender); + } + + function _simulationOnlyValidations( + UserOperation calldata userOp + ) internal view { + // solhint-disable-next-line no-empty-blocks + try + this._validateSenderAndPaymaster( + userOp.initCode, + userOp.sender, + userOp.paymasterAndData + ) + {} catch Error(string memory revertReason) { + if (bytes(revertReason).length != 0) { + revert FailedOp(0, revertReason); + } + } + } + + /** + * Called only during simulation. + * This function always reverts to prevent warm/cold storage differentiation in simulation vs execution. + */ + function _validateSenderAndPaymaster( + bytes calldata initCode, + address sender, + bytes calldata paymasterAndData + ) external view { + if (initCode.length == 0 && sender.code.length == 0) { + // it would revert anyway. but give a meaningful message + revert("AA20 account not deployed"); + } + if (paymasterAndData.length >= 20) { + address paymaster = address(bytes20(paymasterAndData[0:20])); + if (paymaster.code.length == 0) { + // it would revert anyway. but give a meaningful message + revert("AA30 paymaster not deployed"); + } + } + // always revert + revert(""); + } + + /** + * call account.validateUserOp. + * revert (with FailedOp) in case validateUserOp reverts, or account didn't send required prefund. + * decrement account's deposit if needed + */ + function _validateAccountPrepayment( + uint256 opIndex, + UserOperation calldata op, + UserOpInfo memory opInfo, + uint256 requiredPrefund + ) + internal + returns ( + uint256 gasUsedByValidateAccountPrepayment, + uint256 validationData + ) + { + unchecked { + uint256 preGas = gasleft(); + MemoryUserOp memory mUserOp = opInfo.mUserOp; + address sender = mUserOp.sender; + _createSenderIfNeeded(opIndex, opInfo, op.initCode); + address paymaster = mUserOp.paymaster; + numberMarker(); + uint256 missingAccountFunds = 0; + if (paymaster == address(0)) { + uint256 bal = balanceOf(sender); + missingAccountFunds = bal > requiredPrefund + ? 0 + : requiredPrefund - bal; + } + try + IAccount(sender).validateUserOp{ + gas: mUserOp.verificationGasLimit + }(op, opInfo.userOpHash, missingAccountFunds) + returns (uint256 _validationData) { + validationData = _validationData; + } catch Error(string memory revertReason) { + revert FailedOp( + opIndex, + string.concat("AA23 reverted: ", revertReason) + ); + } catch { + revert FailedOp(opIndex, "AA23 reverted (or OOG)"); + } + if (paymaster == address(0)) { + DepositInfo storage senderInfo = deposits[sender]; + uint256 deposit = senderInfo.deposit; + if (requiredPrefund > deposit) { + revert FailedOp(opIndex, "AA21 didn't pay prefund"); + } + senderInfo.deposit = uint112(deposit - requiredPrefund); + } + gasUsedByValidateAccountPrepayment = preGas - gasleft(); + } + } + + /** + * In case the request has a paymaster: + * Validate paymaster has enough deposit. + * Call paymaster.validatePaymasterUserOp. + * Revert with proper FailedOp in case paymaster reverts. + * Decrement paymaster's deposit + */ + function _validatePaymasterPrepayment( + uint256 opIndex, + UserOperation calldata op, + UserOpInfo memory opInfo, + uint256 requiredPreFund, + uint256 gasUsedByValidateAccountPrepayment + ) internal returns (bytes memory context, uint256 validationData) { + unchecked { + MemoryUserOp memory mUserOp = opInfo.mUserOp; + uint256 verificationGasLimit = mUserOp.verificationGasLimit; + require( + verificationGasLimit > gasUsedByValidateAccountPrepayment, + "AA41 too little verificationGas" + ); + uint256 gas = verificationGasLimit - + gasUsedByValidateAccountPrepayment; + + address paymaster = mUserOp.paymaster; + DepositInfo storage paymasterInfo = deposits[paymaster]; + uint256 deposit = paymasterInfo.deposit; + if (deposit < requiredPreFund) { + revert FailedOp(opIndex, "AA31 paymaster deposit too low"); + } + paymasterInfo.deposit = uint112(deposit - requiredPreFund); + try + IPaymaster(paymaster).validatePaymasterUserOp{gas: gas}( + op, + opInfo.userOpHash, + requiredPreFund + ) + returns (bytes memory _context, uint256 _validationData) { + context = _context; + validationData = _validationData; + } catch Error(string memory revertReason) { + revert FailedOp( + opIndex, + string.concat("AA33 reverted: ", revertReason) + ); + } catch { + revert FailedOp(opIndex, "AA33 reverted (or OOG)"); + } + } + } + + /** + * revert if either account validationData or paymaster validationData is expired + */ + function _validateAccountAndPaymasterValidationData( + uint256 opIndex, + uint256 validationData, + uint256 paymasterValidationData, + address expectedAggregator + ) internal view { + (address aggregator, bool outOfTimeRange) = _getValidationData( + validationData + ); + if (expectedAggregator != aggregator) { + revert FailedOp(opIndex, "AA24 signature error"); + } + if (outOfTimeRange) { + revert FailedOp(opIndex, "AA22 expired or not due"); + } + //pmAggregator is not a real signature aggregator: we don't have logic to handle it as address. + // non-zero address means that the paymaster fails due to some signature check (which is ok only during estimation) + address pmAggregator; + (pmAggregator, outOfTimeRange) = _getValidationData( + paymasterValidationData + ); + if (pmAggregator != address(0)) { + revert FailedOp(opIndex, "AA34 signature error"); + } + if (outOfTimeRange) { + revert FailedOp(opIndex, "AA32 paymaster expired or not due"); + } + } + + function _getValidationData( + uint256 validationData + ) internal view returns (address aggregator, bool outOfTimeRange) { + if (validationData == 0) { + return (address(0), false); + } + ValidationData memory data = _parseValidationData(validationData); + // solhint-disable-next-line not-rely-on-time + outOfTimeRange = + block.timestamp > data.validUntil || + block.timestamp < data.validAfter; + aggregator = data.aggregator; + } + + /** + * validate account and paymaster (if defined). + * also make sure total validation doesn't exceed verificationGasLimit + * this method is called off-chain (simulateValidation()) and on-chain (from handleOps) + * @param opIndex the index of this userOp into the "opInfos" array + * @param userOp the userOp to validate + */ + function _validatePrepayment( + uint256 opIndex, + UserOperation calldata userOp, + UserOpInfo memory outOpInfo + ) + private + returns (uint256 validationData, uint256 paymasterValidationData) + { + uint256 preGas = gasleft(); + MemoryUserOp memory mUserOp = outOpInfo.mUserOp; + _copyUserOpToMemory(userOp, mUserOp); + outOpInfo.userOpHash = getUserOpHash(userOp); + + // validate all numeric values in userOp are well below 128 bit, so they can safely be added + // and multiplied without causing overflow + uint256 maxGasValues = mUserOp.preVerificationGas | + mUserOp.verificationGasLimit | + mUserOp.callGasLimit | + userOp.maxFeePerGas | + userOp.maxPriorityFeePerGas; + require(maxGasValues <= type(uint120).max, "AA94 gas values overflow"); + + uint256 gasUsedByValidateAccountPrepayment; + uint256 requiredPreFund = _getRequiredPrefund(mUserOp); + ( + gasUsedByValidateAccountPrepayment, + validationData + ) = _validateAccountPrepayment( + opIndex, + userOp, + outOpInfo, + requiredPreFund + ); + + if (!_validateAndUpdateNonce(mUserOp.sender, mUserOp.nonce)) { + revert FailedOp(opIndex, "AA25 invalid account nonce"); + } + + //a "marker" where account opcode validation is done and paymaster opcode validation is about to start + // (used only by off-chain simulateValidation) + numberMarker(); + + bytes memory context; + if (mUserOp.paymaster != address(0)) { + (context, paymasterValidationData) = _validatePaymasterPrepayment( + opIndex, + userOp, + outOpInfo, + requiredPreFund, + gasUsedByValidateAccountPrepayment + ); + } + unchecked { + uint256 gasUsed = preGas - gasleft(); + + if (userOp.verificationGasLimit < gasUsed) { + revert FailedOp(opIndex, "AA40 over verificationGasLimit"); + } + outOpInfo.prefund = requiredPreFund; + outOpInfo.contextOffset = getOffsetOfMemoryBytes(context); + outOpInfo.preOpGas = preGas - gasleft() + userOp.preVerificationGas; + } + } + + /** + * process post-operation. + * called just after the callData is executed. + * if a paymaster is defined and its validation returned a non-empty context, its postOp is called. + * the excess amount is refunded to the account (or paymaster - if it was used in the request) + * @param opIndex index in the batch + * @param mode - whether is called from innerHandleOp, or outside (postOpReverted) + * @param opInfo userOp fields and info collected during validation + * @param context the context returned in validatePaymasterUserOp + * @param actualGas the gas used so far by this user operation + */ + function _handlePostOp( + uint256 opIndex, + IPaymaster.PostOpMode mode, + UserOpInfo memory opInfo, + bytes memory context, + uint256 actualGas + ) private returns (uint256 actualGasCost) { + uint256 preGas = gasleft(); + unchecked { + address refundAddress; + MemoryUserOp memory mUserOp = opInfo.mUserOp; + uint256 gasPrice = getUserOpGasPrice(mUserOp); + + address paymaster = mUserOp.paymaster; + if (paymaster == address(0)) { + refundAddress = mUserOp.sender; + } else { + refundAddress = paymaster; + if (context.length > 0) { + actualGasCost = actualGas * gasPrice; + if (mode != IPaymaster.PostOpMode.postOpReverted) { + IPaymaster(paymaster).postOp{ + gas: mUserOp.verificationGasLimit + }(mode, context, actualGasCost); + } else { + // solhint-disable-next-line no-empty-blocks + try + IPaymaster(paymaster).postOp{ + gas: mUserOp.verificationGasLimit + }(mode, context, actualGasCost) + {} catch Error(string memory reason) { + revert FailedOp( + opIndex, + string.concat("AA50 postOp reverted: ", reason) + ); + } catch { + revert FailedOp(opIndex, "AA50 postOp revert"); + } + } + } + } + actualGas += preGas - gasleft(); + actualGasCost = actualGas * gasPrice; + if (opInfo.prefund < actualGasCost) { + revert FailedOp(opIndex, "AA51 prefund below actualGasCost"); + } + uint256 refund = opInfo.prefund - actualGasCost; + _incrementDeposit(refundAddress, refund); + bool success = mode == IPaymaster.PostOpMode.opSucceeded; + emit UserOperationEvent( + opInfo.userOpHash, + mUserOp.sender, + mUserOp.paymaster, + mUserOp.nonce, + success, + actualGasCost, + actualGas + ); + } // unchecked + } + + /** + * the gas price this UserOp agrees to pay. + * relayer/block builder might submit the TX with higher priorityFee, but the user should not + */ + function getUserOpGasPrice( + MemoryUserOp memory mUserOp + ) internal view returns (uint256) { + unchecked { + uint256 maxFeePerGas = mUserOp.maxFeePerGas; + uint256 maxPriorityFeePerGas = mUserOp.maxPriorityFeePerGas; + if (maxFeePerGas == maxPriorityFeePerGas) { + //legacy mode (for networks that don't support basefee opcode) + return maxFeePerGas; + } + return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee); + } + } + + function min(uint256 a, uint256 b) internal pure returns (uint256) { + return a < b ? a : b; + } + + function getOffsetOfMemoryBytes( + bytes memory data + ) internal pure returns (uint256 offset) { + assembly { + offset := data + } + } + + function getMemoryBytesFromOffset( + uint256 offset + ) internal pure returns (bytes memory data) { + assembly { + data := offset + } + } + + //place the NUMBER opcode in the code. + // this is used as a marker during simulation, as this OP is completely banned from the simulated code of the + // account and paymaster. + function numberMarker() internal view { + assembly { + mstore(0, number()) + } + } +} diff --git a/contracts/aa-4337/core/Helpers.sol b/contracts/aa-4337/core/Helpers.sol new file mode 100644 index 0000000..71e2fa5 --- /dev/null +++ b/contracts/aa-4337/core/Helpers.sol @@ -0,0 +1,101 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity 0.8.21; + +/* solhint-disable no-inline-assembly */ + +/** + * returned data from validateUserOp. + * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData` + * @param aggregator - address(0) - the account validated the signature by itself. + * address(1) - the account failed to validate the signature. + * otherwise - this is an address of a signature aggregator that must be used to validate the signature. + * @param validAfter - this UserOp is valid only after this timestamp. + * @param validaUntil - this UserOp is valid only up to this timestamp. + */ +struct ValidationData { + address aggregator; + uint48 validAfter; + uint48 validUntil; +} + +//extract sigFailed, validAfter, validUntil. +// also convert zero validUntil to type(uint48).max +function _parseValidationData( + uint validationData +) pure returns (ValidationData memory data) { + address aggregator = address(uint160(validationData)); + uint48 validUntil = uint48(validationData >> 160); + if (validUntil == 0) { + validUntil = type(uint48).max; + } + uint48 validAfter = uint48(validationData >> (48 + 160)); + return ValidationData(aggregator, validAfter, validUntil); +} + +// intersect account and paymaster ranges. +function _intersectTimeRange( + uint256 validationData, + uint256 paymasterValidationData +) pure returns (ValidationData memory) { + ValidationData memory accountValidationData = _parseValidationData( + validationData + ); + ValidationData memory pmValidationData = _parseValidationData( + paymasterValidationData + ); + address aggregator = accountValidationData.aggregator; + if (aggregator == address(0)) { + aggregator = pmValidationData.aggregator; + } + uint48 validAfter = accountValidationData.validAfter; + uint48 validUntil = accountValidationData.validUntil; + uint48 pmValidAfter = pmValidationData.validAfter; + uint48 pmValidUntil = pmValidationData.validUntil; + + if (validAfter < pmValidAfter) validAfter = pmValidAfter; + if (validUntil > pmValidUntil) validUntil = pmValidUntil; + return ValidationData(aggregator, validAfter, validUntil); +} + +/** + * helper to pack the return value for validateUserOp + * @param data - the ValidationData to pack + */ +function _packValidationData( + ValidationData memory data +) pure returns (uint256) { + return + uint160(data.aggregator) | + (uint256(data.validUntil) << 160) | + (uint256(data.validAfter) << (160 + 48)); +} + +/** + * helper to pack the return value for validateUserOp, when not using an aggregator + * @param sigFailed - true for signature failure, false for success + * @param validUntil last timestamp this UserOperation is valid (or zero for infinite) + * @param validAfter first timestamp this UserOperation is valid + */ +function _packValidationData( + bool sigFailed, + uint48 validUntil, + uint48 validAfter +) pure returns (uint256) { + return + (sigFailed ? 1 : 0) | + (uint256(validUntil) << 160) | + (uint256(validAfter) << (160 + 48)); +} + +/** + * keccak function over calldata. + * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it. + */ +function calldataKeccak(bytes calldata data) pure returns (bytes32 ret) { + assembly { + let mem := mload(0x40) + let len := data.length + calldatacopy(mem, data.offset, len) + ret := keccak256(mem, len) + } +} diff --git a/contracts/aa-4337/core/NonceManager.sol b/contracts/aa-4337/core/NonceManager.sol new file mode 100644 index 0000000..c64025f --- /dev/null +++ b/contracts/aa-4337/core/NonceManager.sol @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity 0.8.21; + +import "../interfaces/IEntryPoint.sol"; + +/** + * nonce management functionality + */ +contract NonceManager is INonceManager { + /** + * The next valid sequence number for a given nonce key. + */ + mapping(address => mapping(uint192 => uint256)) public nonceSequenceNumber; + + function getNonce( + address sender, + uint192 key + ) public view override returns (uint256 nonce) { + return nonceSequenceNumber[sender][key] | (uint256(key) << 64); + } + + // allow an account to manually increment its own nonce. + // (mainly so that during construction nonce can be made non-zero, + // to "absorb" the gas cost of first nonce increment to 1st transaction (construction), + // not to 2nd transaction) + function incrementNonce(uint192 key) public override { + nonceSequenceNumber[msg.sender][key]++; + } + + /** + * validate nonce uniqueness for this account. + * called just after validateUserOp() + */ + function _validateAndUpdateNonce( + address sender, + uint256 nonce + ) internal returns (bool) { + uint192 key = uint192(nonce >> 64); + uint64 seq = uint64(nonce); + return nonceSequenceNumber[sender][key]++ == seq; + } +} diff --git a/contracts/aa-4337/core/SenderCreator.sol b/contracts/aa-4337/core/SenderCreator.sol new file mode 100644 index 0000000..9669abe --- /dev/null +++ b/contracts/aa-4337/core/SenderCreator.sol @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity 0.8.21; + +/** + * helper contract for EntryPoint, to call userOp.initCode from a "neutral" address, + * which is explicitly not the entryPoint itself. + */ +contract SenderCreator { + /** + * call the "initCode" factory to create and return the sender account address + * @param initCode the initCode value from a UserOp. contains 20 bytes of factory address, followed by calldata + * @return sender the returned address of the created account, or zero address on failure. + */ + function createSender( + bytes calldata initCode + ) external returns (address sender) { + address factory = address(bytes20(initCode[0:20])); + bytes memory initCallData = initCode[20:]; + bool success; + /* solhint-disable no-inline-assembly */ + assembly { + success := call( + gas(), + factory, + 0, + add(initCallData, 0x20), + mload(initCallData), + 0, + 32 + ) + sender := mload(0) + } + if (!success) { + sender = address(0); + } + } +} diff --git a/contracts/aa-4337/core/StakeManager.sol b/contracts/aa-4337/core/StakeManager.sol new file mode 100644 index 0000000..96a7c54 --- /dev/null +++ b/contracts/aa-4337/core/StakeManager.sol @@ -0,0 +1,135 @@ +// SPDX-License-Identifier: GPL-3.0-only +pragma solidity 0.8.21; + +import "../interfaces/IStakeManager.sol"; + +/* solhint-disable avoid-low-level-calls */ +/* solhint-disable not-rely-on-time */ +/** + * manage deposits and stakes. + * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account) + * stake is value locked for at least "unstakeDelay" by a paymaster. + */ +abstract contract StakeManager is IStakeManager { + /// maps paymaster to their deposits and stakes + mapping(address => DepositInfo) public deposits; + + /// @inheritdoc IStakeManager + function getDepositInfo( + address account + ) public view returns (DepositInfo memory info) { + return deposits[account]; + } + + // internal method to return just the stake info + function _getStakeInfo( + address addr + ) internal view returns (StakeInfo memory info) { + DepositInfo storage depositInfo = deposits[addr]; + info.stake = depositInfo.stake; + info.unstakeDelaySec = depositInfo.unstakeDelaySec; + } + + /// return the deposit (for gas payment) of the account + function balanceOf(address account) public view returns (uint256) { + return deposits[account].deposit; + } + + receive() external payable { + depositTo(msg.sender); + } + + function _incrementDeposit(address account, uint256 amount) internal { + DepositInfo storage info = deposits[account]; + uint256 newAmount = info.deposit + amount; + require(newAmount <= type(uint112).max, "deposit overflow"); + info.deposit = uint112(newAmount); + } + + /** + * add to the deposit of the given account + */ + function depositTo(address account) public payable { + _incrementDeposit(account, msg.value); + DepositInfo storage info = deposits[account]; + emit Deposited(account, info.deposit); + } + + /** + * add to the account's stake - amount and delay + * any pending unstake is first cancelled. + * @param unstakeDelaySec the new lock duration before the deposit can be withdrawn. + */ + function addStake(uint32 unstakeDelaySec) public payable { + DepositInfo storage info = deposits[msg.sender]; + require(unstakeDelaySec > 0, "must specify unstake delay"); + require( + unstakeDelaySec >= info.unstakeDelaySec, + "cannot decrease unstake time" + ); + uint256 stake = info.stake + msg.value; + require(stake > 0, "no stake specified"); + require(stake <= type(uint112).max, "stake overflow"); + deposits[msg.sender] = DepositInfo( + info.deposit, + true, + uint112(stake), + unstakeDelaySec, + 0 + ); + emit StakeLocked(msg.sender, stake, unstakeDelaySec); + } + + /** + * attempt to unlock the stake. + * the value can be withdrawn (using withdrawStake) after the unstake delay. + */ + function unlockStake() external { + DepositInfo storage info = deposits[msg.sender]; + require(info.unstakeDelaySec != 0, "not staked"); + require(info.staked, "already unstaking"); + uint48 withdrawTime = uint48(block.timestamp) + info.unstakeDelaySec; + info.withdrawTime = withdrawTime; + info.staked = false; + emit StakeUnlocked(msg.sender, withdrawTime); + } + + /** + * withdraw from the (unlocked) stake. + * must first call unlockStake and wait for the unstakeDelay to pass + * @param withdrawAddress the address to send withdrawn value. + */ + function withdrawStake(address payable withdrawAddress) external { + DepositInfo storage info = deposits[msg.sender]; + uint256 stake = info.stake; + require(stake > 0, "No stake to withdraw"); + require(info.withdrawTime > 0, "must call unlockStake() first"); + require( + info.withdrawTime <= block.timestamp, + "Stake withdrawal is not due" + ); + info.unstakeDelaySec = 0; + info.withdrawTime = 0; + info.stake = 0; + emit StakeWithdrawn(msg.sender, withdrawAddress, stake); + (bool success, ) = withdrawAddress.call{value: stake}(""); + require(success, "failed to withdraw stake"); + } + + /** + * withdraw from the deposit. + * @param withdrawAddress the address to send withdrawn value. + * @param withdrawAmount the amount to withdraw. + */ + function withdrawTo( + address payable withdrawAddress, + uint256 withdrawAmount + ) external { + DepositInfo storage info = deposits[msg.sender]; + require(withdrawAmount <= info.deposit, "Withdraw amount too large"); + info.deposit = uint112(info.deposit - withdrawAmount); + emit Withdrawn(msg.sender, withdrawAddress, withdrawAmount); + (bool success, ) = withdrawAddress.call{value: withdrawAmount}(""); + require(success, "failed to withdraw"); + } +} diff --git a/contracts/aa-4337/interfaces/IAccount.sol b/contracts/aa-4337/interfaces/IAccount.sol new file mode 100644 index 0000000..64c4321 --- /dev/null +++ b/contracts/aa-4337/interfaces/IAccount.sol @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity ^0.8.12; + +import "./UserOperation.sol"; + +interface IAccount { + /** + * Validate user's signature and nonce + * the entryPoint will make the call to the recipient only if this validation call returns successfully. + * signature failure should be reported by returning SIG_VALIDATION_FAILED (1). + * This allows making a "simulation call" without a valid signature + * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure. + * + * @dev Must validate caller is the entryPoint. + * Must validate the signature and nonce + * @param userOp the operation that is about to be executed. + * @param userOpHash hash of the user's request data. can be used as the basis for signature. + * @param missingAccountFunds missing funds on the account's deposit in the entrypoint. + * This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call. + * The excess is left as a deposit in the entrypoint, for future calls. + * can be withdrawn anytime using "entryPoint.withdrawTo()" + * In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero. + * @return validationData packaged ValidationData structure. use `_packValidationData` and `_unpackValidationData` to encode and decode + * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure, + * otherwise, an address of an "authorizer" contract. + * <6-byte> validUntil - last timestamp this operation is valid. 0 for "indefinite" + * <6-byte> validAfter - first timestamp this operation is valid + * If an account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure. + * Note that the validation code cannot use block.timestamp (or block.number) directly. + */ + function validateUserOp( + UserOperation calldata userOp, + bytes32 userOpHash, + uint256 missingAccountFunds + ) external returns (uint256 validationData); +} diff --git a/contracts/aa-4337/interfaces/IAggregator.sol b/contracts/aa-4337/interfaces/IAggregator.sol new file mode 100644 index 0000000..bc332b8 --- /dev/null +++ b/contracts/aa-4337/interfaces/IAggregator.sol @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity ^0.8.12; + +import "./UserOperation.sol"; + +/** + * Aggregated Signatures validator. + */ +interface IAggregator { + /** + * validate aggregated signature. + * revert if the aggregated signature does not match the given list of operations. + */ + function validateSignatures( + UserOperation[] calldata userOps, + bytes calldata signature + ) external view; + + /** + * validate signature of a single userOp + * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation + * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps. + * @param userOp the userOperation received from the user. + * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps. + * (usually empty, unless account and aggregator support some kind of "multisig" + */ + function validateUserOpSignature( + UserOperation calldata userOp + ) external view returns (bytes memory sigForUserOp); + + /** + * aggregate multiple signatures into a single value. + * This method is called off-chain to calculate the signature to pass with handleOps() + * bundler MAY use optimized custom code perform this aggregation + * @param userOps array of UserOperations to collect the signatures from. + * @return aggregatedSignature the aggregated signature + */ + function aggregateSignatures( + UserOperation[] calldata userOps + ) external view returns (bytes memory aggregatedSignature); +} diff --git a/contracts/aa-4337/interfaces/IEntryPoint.sol b/contracts/aa-4337/interfaces/IEntryPoint.sol new file mode 100644 index 0000000..52200f5 --- /dev/null +++ b/contracts/aa-4337/interfaces/IEntryPoint.sol @@ -0,0 +1,243 @@ +/** + ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation. + ** Only one instance required on each chain. + **/ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity ^0.8.12; + +/* solhint-disable avoid-low-level-calls */ +/* solhint-disable no-inline-assembly */ +/* solhint-disable reason-string */ + +import "./UserOperation.sol"; +import "./IStakeManager.sol"; +import "./IAggregator.sol"; +import "./INonceManager.sol"; + +interface IEntryPoint is IStakeManager, INonceManager { + /*** + * An event emitted after each successful request + * @param userOpHash - unique identifier for the request (hash its entire content, except signature). + * @param sender - the account that generates this request. + * @param paymaster - if non-null, the paymaster that pays for this request. + * @param nonce - the nonce value from the request. + * @param success - true if the sender transaction succeeded, false if reverted. + * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation. + * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution). + */ + event UserOperationEvent( + bytes32 indexed userOpHash, + address indexed sender, + address indexed paymaster, + uint256 nonce, + bool success, + uint256 actualGasCost, + uint256 actualGasUsed + ); + + /** + * account "sender" was deployed. + * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow. + * @param sender the account that is deployed + * @param factory the factory used to deploy this account (in the initCode) + * @param paymaster the paymaster used by this UserOp + */ + event AccountDeployed( + bytes32 indexed userOpHash, + address indexed sender, + address factory, + address paymaster + ); + + /** + * An event emitted if the UserOperation "callData" reverted with non-zero length + * @param userOpHash the request unique identifier. + * @param sender the sender of this request + * @param nonce the nonce used in the request + * @param revertReason - the return bytes from the (reverted) call to "callData". + */ + event UserOperationRevertReason( + bytes32 indexed userOpHash, + address indexed sender, + uint256 nonce, + bytes revertReason + ); + + /** + * an event emitted by handleOps(), before starting the execution loop. + * any event emitted before this event, is part of the validation. + */ + event BeforeExecution(); + + /** + * signature aggregator used by the following UserOperationEvents within this bundle. + */ + event SignatureAggregatorChanged(address indexed aggregator); + + /** + * a custom revert error of handleOps, to identify the offending op. + * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it. + * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero) + * @param reason - revert reason + * The string starts with a unique code "AAmn", where "m" is "1" for factory, "2" for account and "3" for paymaster issues, + * so a failure can be attributed to the correct entity. + * Should be caught in off-chain handleOps simulation and not happen on-chain. + * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts. + */ + error FailedOp(uint256 opIndex, string reason); + + /** + * error case when a signature aggregator fails to verify the aggregated signature it had created. + */ + error SignatureValidationFailed(address aggregator); + + /** + * Successful result from simulateValidation. + * @param returnInfo gas and time-range returned values + * @param senderInfo stake information about the sender + * @param factoryInfo stake information about the factory (if any) + * @param paymasterInfo stake information about the paymaster (if any) + */ + error ValidationResult( + ReturnInfo returnInfo, + StakeInfo senderInfo, + StakeInfo factoryInfo, + StakeInfo paymasterInfo + ); + + /** + * Successful result from simulateValidation, if the account returns a signature aggregator + * @param returnInfo gas and time-range returned values + * @param senderInfo stake information about the sender + * @param factoryInfo stake information about the factory (if any) + * @param paymasterInfo stake information about the paymaster (if any) + * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator) + * bundler MUST use it to verify the signature, or reject the UserOperation + */ + error ValidationResultWithAggregation( + ReturnInfo returnInfo, + StakeInfo senderInfo, + StakeInfo factoryInfo, + StakeInfo paymasterInfo, + AggregatorStakeInfo aggregatorInfo + ); + + /** + * return value of getSenderAddress + */ + error SenderAddressResult(address sender); + + /** + * return value of simulateHandleOp + */ + error ExecutionResult( + uint256 preOpGas, + uint256 paid, + uint48 validAfter, + uint48 validUntil, + bool targetSuccess, + bytes targetResult + ); + + //UserOps handled, per aggregator + struct UserOpsPerAggregator { + UserOperation[] userOps; + // aggregator address + IAggregator aggregator; + // aggregated signature + bytes signature; + } + + /** + * Execute a batch of UserOperation. + * no signature aggregator is used. + * if any account requires an aggregator (that is, it returned an aggregator when + * performing simulateValidation), then handleAggregatedOps() must be used instead. + * @param ops the operations to execute + * @param beneficiary the address to receive the fees + */ + function handleOps( + UserOperation[] calldata ops, + address payable beneficiary + ) external; + + /** + * Execute a batch of UserOperation with Aggregators + * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts) + * @param beneficiary the address to receive the fees + */ + function handleAggregatedOps( + UserOpsPerAggregator[] calldata opsPerAggregator, + address payable beneficiary + ) external; + + /** + * generate a request Id - unique identifier for this request. + * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid. + */ + function getUserOpHash( + UserOperation calldata userOp + ) external view returns (bytes32); + + /** + * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp. + * @dev this method always revert. Successful result is ValidationResult error. other errors are failures. + * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data. + * @param userOp the user operation to validate. + */ + function simulateValidation(UserOperation calldata userOp) external; + + /** + * gas and return values during simulation + * @param preOpGas the gas used for validation (including preValidationGas) + * @param prefund the required prefund for this operation + * @param sigFailed validateUserOp's (or paymaster's) signature check failed + * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range) + * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range) + * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp) + */ + struct ReturnInfo { + uint256 preOpGas; + uint256 prefund; + bool sigFailed; + uint48 validAfter; + uint48 validUntil; + bytes paymasterContext; + } + + /** + * returned aggregated signature info. + * the aggregator returned by the account, and its current stake. + */ + struct AggregatorStakeInfo { + address aggregator; + StakeInfo stakeInfo; + } + + /** + * Get counterfactual sender address. + * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation. + * this method always revert, and returns the address in SenderAddressResult error + * @param initCode the constructor code to be passed into the UserOperation. + */ + function getSenderAddress(bytes memory initCode) external; + + /** + * simulate full execution of a UserOperation (including both validation and target execution) + * this method will always revert with "ExecutionResult". + * it performs full validation of the UserOperation, but ignores signature error. + * an optional target address is called after the userop succeeds, and its value is returned + * (before the entire call is reverted) + * Note that in order to collect the the success/failure of the target call, it must be executed + * with trace enabled to track the emitted events. + * @param op the UserOperation to simulate + * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult + * are set to the return from that call. + * @param targetCallData callData to pass to target address + */ + function simulateHandleOp( + UserOperation calldata op, + address target, + bytes calldata targetCallData + ) external; +} diff --git a/contracts/aa-4337/interfaces/INonceManager.sol b/contracts/aa-4337/interfaces/INonceManager.sol new file mode 100644 index 0000000..7d4602f --- /dev/null +++ b/contracts/aa-4337/interfaces/INonceManager.sol @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity ^0.8.12; + +interface INonceManager { + /** + * Return the next nonce for this sender. + * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop) + * But UserOp with different keys can come with arbitrary order. + * + * @param sender the account address + * @param key the high 192 bit of the nonce + * @return nonce a full nonce to pass for next UserOp with this sender. + */ + function getNonce( + address sender, + uint192 key + ) external view returns (uint256 nonce); + + /** + * Manually increment the nonce of the sender. + * This method is exposed just for completeness.. + * Account does NOT need to call it, neither during validation, nor elsewhere, + * as the EntryPoint will update the nonce regardless. + * Possible use-case is call it with various keys to "initialize" their nonces to one, so that future + * UserOperations will not pay extra for the first transaction with a given key. + */ + function incrementNonce(uint192 key) external; +} diff --git a/contracts/aa-4337/interfaces/IPaymaster.sol b/contracts/aa-4337/interfaces/IPaymaster.sol new file mode 100644 index 0000000..ee4866e --- /dev/null +++ b/contracts/aa-4337/interfaces/IPaymaster.sol @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity ^0.8.12; + +import "./UserOperation.sol"; + +/** + * the interface exposed by a paymaster contract, who agrees to pay the gas for user's operations. + * a paymaster must hold a stake to cover the required entrypoint stake and also the gas for the transaction. + */ +interface IPaymaster { + enum PostOpMode { + opSucceeded, // user op succeeded + opReverted, // user op reverted. still has to pay for gas. + postOpReverted //user op succeeded, but caused postOp to revert. Now it's a 2nd call, after user's op was deliberately reverted. + } + + /** + * payment validation: check if paymaster agrees to pay. + * Must verify sender is the entryPoint. + * Revert to reject this request. + * Note that bundlers will reject this method if it changes the state, unless the paymaster is trusted (whitelisted) + * The paymaster pre-pays using its deposit, and receive back a refund after the postOp method returns. + * @param userOp the user operation + * @param userOpHash hash of the user's request data. + * @param maxCost the maximum cost of this transaction (based on maximum gas and gas price from userOp) + * @return context value to send to a postOp + * zero length to signify postOp is not required. + * @return validationData signature and time-range of this operation, encoded the same as the return value of validateUserOperation + * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure, + * otherwise, an address of an "authorizer" contract. + * <6-byte> validUntil - last timestamp this operation is valid. 0 for "indefinite" + * <6-byte> validAfter - first timestamp this operation is valid + * Note that the validation code cannot use block.timestamp (or block.number) directly. + */ + function validatePaymasterUserOp( + UserOperation calldata userOp, + bytes32 userOpHash, + uint256 maxCost + ) external returns (bytes memory context, uint256 validationData); + + /** + * post-operation handler. + * Must verify sender is the entryPoint + * @param mode enum with the following options: + * opSucceeded - user operation succeeded. + * opReverted - user op reverted. still has to pay for gas. + * postOpReverted - user op succeeded, but caused postOp (in mode=opSucceeded) to revert. + * Now this is the 2nd call, after user's op was deliberately reverted. + * @param context - the context value returned by validatePaymasterUserOp + * @param actualGasCost - actual gas used so far (without this postOp call). + */ + function postOp( + PostOpMode mode, + bytes calldata context, + uint256 actualGasCost + ) external; +} diff --git a/contracts/aa-4337/interfaces/IStakeManager.sol b/contracts/aa-4337/interfaces/IStakeManager.sol new file mode 100644 index 0000000..8abdb02 --- /dev/null +++ b/contracts/aa-4337/interfaces/IStakeManager.sol @@ -0,0 +1,102 @@ +// SPDX-License-Identifier: GPL-3.0-only +pragma solidity ^0.8.12; + +/** + * manage deposits and stakes. + * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account) + * stake is value locked for at least "unstakeDelay" by the staked entity. + */ +interface IStakeManager { + event Deposited(address indexed account, uint256 totalDeposit); + + event Withdrawn( + address indexed account, + address withdrawAddress, + uint256 amount + ); + + /// Emitted when stake or unstake delay are modified + event StakeLocked( + address indexed account, + uint256 totalStaked, + uint256 unstakeDelaySec + ); + + /// Emitted once a stake is scheduled for withdrawal + event StakeUnlocked(address indexed account, uint256 withdrawTime); + + event StakeWithdrawn( + address indexed account, + address withdrawAddress, + uint256 amount + ); + + /** + * @param deposit the entity's deposit + * @param staked true if this entity is staked. + * @param stake actual amount of ether staked for this entity. + * @param unstakeDelaySec minimum delay to withdraw the stake. + * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked + * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps) + * and the rest fit into a 2nd cell. + * 112 bit allows for 10^15 eth + * 48 bit for full timestamp + * 32 bit allows 150 years for unstake delay + */ + struct DepositInfo { + uint112 deposit; + bool staked; + uint112 stake; + uint32 unstakeDelaySec; + uint48 withdrawTime; + } + + //API struct used by getStakeInfo and simulateValidation + struct StakeInfo { + uint256 stake; + uint256 unstakeDelaySec; + } + + /// @return info - full deposit information of given account + function getDepositInfo( + address account + ) external view returns (DepositInfo memory info); + + /// @return the deposit (for gas payment) of the account + function balanceOf(address account) external view returns (uint256); + + /** + * add to the deposit of the given account + */ + function depositTo(address account) external payable; + + /** + * add to the account's stake - amount and delay + * any pending unstake is first cancelled. + * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn. + */ + function addStake(uint32 _unstakeDelaySec) external payable; + + /** + * attempt to unlock the stake. + * the value can be withdrawn (using withdrawStake) after the unstake delay. + */ + function unlockStake() external; + + /** + * withdraw from the (unlocked) stake. + * must first call unlockStake and wait for the unstakeDelay to pass + * @param withdrawAddress the address to send withdrawn value. + */ + function withdrawStake(address payable withdrawAddress) external; + + /** + * withdraw from the deposit. + * @param withdrawAddress the address to send withdrawn value. + * @param withdrawAmount the amount to withdraw. + */ + function withdrawTo( + address payable withdrawAddress, + uint256 withdrawAmount + ) external; +} diff --git a/contracts/aa-4337/interfaces/UserOperation.sol b/contracts/aa-4337/interfaces/UserOperation.sol new file mode 100644 index 0000000..be80b87 --- /dev/null +++ b/contracts/aa-4337/interfaces/UserOperation.sol @@ -0,0 +1,105 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity ^0.8.12; + +/* solhint-disable no-inline-assembly */ + +import {calldataKeccak} from "../core/Helpers.sol"; + +/** + * User Operation struct + * @param sender the sender account of this request. + * @param nonce unique value the sender uses to verify it is not a replay. + * @param initCode if set, the account contract will be created by this constructor/ + * @param callData the method call to execute on this account. + * @param callGasLimit the gas limit passed to the callData method call. + * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp. + * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead. + * @param maxFeePerGas same as EIP-1559 gas parameter. + * @param maxPriorityFeePerGas same as EIP-1559 gas parameter. + * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender. + * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID. + */ +struct UserOperation { + address sender; + uint256 nonce; + bytes initCode; + bytes callData; + uint256 callGasLimit; + uint256 verificationGasLimit; + uint256 preVerificationGas; + uint256 maxFeePerGas; + uint256 maxPriorityFeePerGas; + bytes paymasterAndData; + bytes signature; +} + +/** + * Utility functions helpful when working with UserOperation structs. + */ +library UserOperationLib { + function getSender( + UserOperation calldata userOp + ) internal pure returns (address) { + address data; + //read sender from userOp, which is first userOp member (saves 800 gas...) + assembly { + data := calldataload(userOp) + } + return address(uint160(data)); + } + + //relayer/block builder might submit the TX with higher priorityFee, but the user should not + // pay above what he signed for. + function gasPrice( + UserOperation calldata userOp + ) internal view returns (uint256) { + unchecked { + uint256 maxFeePerGas = userOp.maxFeePerGas; + uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas; + if (maxFeePerGas == maxPriorityFeePerGas) { + //legacy mode (for networks that don't support basefee opcode) + return maxFeePerGas; + } + return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee); + } + } + + function pack( + UserOperation calldata userOp + ) internal pure returns (bytes memory ret) { + address sender = getSender(userOp); + uint256 nonce = userOp.nonce; + bytes32 hashInitCode = calldataKeccak(userOp.initCode); + bytes32 hashCallData = calldataKeccak(userOp.callData); + uint256 callGasLimit = userOp.callGasLimit; + uint256 verificationGasLimit = userOp.verificationGasLimit; + uint256 preVerificationGas = userOp.preVerificationGas; + uint256 maxFeePerGas = userOp.maxFeePerGas; + uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas; + bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData); + + return + abi.encode( + sender, + nonce, + hashInitCode, + hashCallData, + callGasLimit, + verificationGasLimit, + preVerificationGas, + maxFeePerGas, + maxPriorityFeePerGas, + hashPaymasterAndData + ); + } + + function hash( + UserOperation calldata userOp + ) internal pure returns (bytes32) { + return keccak256(pack(userOp)); + } + + function min(uint256 a, uint256 b) internal pure returns (uint256) { + return a < b ? a : b; + } +} diff --git a/contracts/aa-4337/utils/Exec.sol b/contracts/aa-4337/utils/Exec.sol new file mode 100644 index 0000000..5343112 --- /dev/null +++ b/contracts/aa-4337/utils/Exec.sol @@ -0,0 +1,90 @@ +// SPDX-License-Identifier: LGPL-3.0-only +pragma solidity >=0.7.5 <0.9.0; + +// solhint-disable no-inline-assembly + +/** + * Utility functions helpful when making different kinds of contract calls in Solidity. + */ +library Exec { + function call( + address to, + uint256 value, + bytes memory data, + uint256 txGas + ) internal returns (bool success) { + assembly { + success := call( + txGas, + to, + value, + add(data, 0x20), + mload(data), + 0, + 0 + ) + } + } + + function staticcall( + address to, + bytes memory data, + uint256 txGas + ) internal view returns (bool success) { + assembly { + success := staticcall(txGas, to, add(data, 0x20), mload(data), 0, 0) + } + } + + function delegateCall( + address to, + bytes memory data, + uint256 txGas + ) internal returns (bool success) { + assembly { + success := delegatecall( + txGas, + to, + add(data, 0x20), + mload(data), + 0, + 0 + ) + } + } + + // get returned data from last call or calldelegate + function getReturnData( + uint256 maxLen + ) internal pure returns (bytes memory returnData) { + assembly { + let len := returndatasize() + if gt(len, maxLen) { + len := maxLen + } + let ptr := mload(0x40) + mstore(0x40, add(ptr, add(len, 0x20))) + mstore(ptr, len) + returndatacopy(add(ptr, 0x20), 0, len) + returnData := ptr + } + } + + // revert with explicit byte array (probably reverted info from call) + function revertWithData(bytes memory returnData) internal pure { + assembly { + revert(add(returnData, 32), mload(returnData)) + } + } + + function callAndRevert( + address to, + bytes memory data, + uint256 maxLen + ) internal { + bool success = call(to, 0, data, gasleft()); + if (!success) { + revertWithData(getReturnData(maxLen)); + } + } +} diff --git a/contracts/facets/AccountFacet.sol b/contracts/facets/AccountFacet.sol new file mode 100644 index 0000000..3ff2a2f --- /dev/null +++ b/contracts/facets/AccountFacet.sol @@ -0,0 +1,267 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.21; + +import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; +import {UserOperation} from "../aa-4337/interfaces/UserOperation.sol"; +import {IEntryPoint} from "../aa-4337/interfaces/IEntryPoint.sol"; +import {BaseAccount} from "../aa-4337/core/BaseAccount.sol"; +import {LibAppStorage, BarzStorage} from "../libraries/LibAppStorage.sol"; +import {LibDiamond} from "../libraries/LibDiamond.sol"; +import {LibLoupe} from "../libraries/LibLoupe.sol"; +import {IFacetRegistry} from "../infrastructure/interfaces/IFacetRegistry.sol"; +import {IDiamondCut} from "../facets/base/interfaces/IDiamondCut.sol"; +import {IDiamondLoupe} from "../facets/base/interfaces/IDiamondLoupe.sol"; +import {IVerificationFacet} from "./interfaces/IVerificationFacet.sol"; +import {IERC1271} from "../interfaces/ERC/IERC1271.sol"; +import {IAccountFacet} from "./interfaces/IAccountFacet.sol"; + +/** + * @title Account Facet + * @dev Account module contract that provides the account features and initialization of signer + * compatible with EIP-1271 & EIP-4337 + * @author David Yongjun Kim (@Powerstream3604) + */ +contract AccountFacet is IAccountFacet, BarzStorage, BaseAccount { + using ECDSA for bytes32; + + /** + * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts + */ + constructor() { + LibAppStorage.enforceAccountInitialize(); + } + + /** + * @notice Returns the address of EntryPoint contract registered to Barz account + */ + function entryPoint() public view override returns (IEntryPoint) { + return s.entryPoint; + } + + /** + * @notice Initializes the initial storage of the Barz contract. + * @dev This method can only be called during the initialization or signature migration. + * If the proxy contract was created without initialization, anyone can call initialize. + * Barz calls initialize in constructor in an atomic transaction during deployment + * @param _verificationFacet Facet contract handling the verificationi + * @param _anEntryPoint Entrypoint contract defined in EIP-4337 handling the flow of UserOp + * @param _facetRegistry Registry of Facets that hold all facet information + * @param _defaultFallBackHandler Middleware contract for default facets + * @param _ownerPublicKey Bytes of owner public key + */ + function initialize( + address _verificationFacet, + address _anEntryPoint, + address _facetRegistry, + address _defaultFallBackHandler, + bytes calldata _ownerPublicKey + ) public override returns (uint256 initSuccess) { + LibAppStorage.enforceAccountInitialize(); + s.entryPoint = IEntryPoint(_anEntryPoint); + s.facetRegistry = IFacetRegistry(_facetRegistry); + LibDiamond.diamondStorage().defaultFallbackHandler = IDiamondLoupe( + _defaultFallBackHandler + ); + + _cutDiamondAccountFacet(_verificationFacet); + + bytes memory initCall = abi.encodeWithSignature( + "initializeSigner(bytes)", + _ownerPublicKey + ); + // Every Verification Facet should comply with initializeSigner(bytes) + // to be compatible with the Barz contract(for initialization) + (bool success, bytes memory result) = _verificationFacet.delegatecall( + initCall + ); + if (!success || uint256(bytes32(result)) != 1) { + revert AccountFacet__InitializationFailure(); + } + + initSuccess = 1; + emit AccountInitialized(s.entryPoint, _ownerPublicKey); + } + + function _cutDiamondAccountFacet(address _verificationFacet) internal { + IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](1); + + bytes4 ownerVerificationFuncSelector = IVerificationFacet( + _verificationFacet + ).validateOwnerSignatureSelector(); + + bytes4[] memory verificationFunctionSelectors = new bytes4[](3); + verificationFunctionSelectors[0] = IERC1271.isValidSignature.selector; + verificationFunctionSelectors[1] = ownerVerificationFuncSelector; + verificationFunctionSelectors[2] = IVerificationFacet.owner.selector; + cut[0] = IDiamondCut.FacetCut({ + facetAddress: _verificationFacet, + action: IDiamondCut.FacetCutAction.Add, + functionSelectors: verificationFunctionSelectors + }); + + LibDiamond.diamondCut(cut, address(0), ""); + } + + /** + * @notice Calls the destination with inputted calldata and value from EntryPoint + * @dev This method executes the calldata coming from the EntryPoint. + * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer) + * @param _dest Address of destination where the call will be forwarded to + * @param _value Amount of native coin the owner is willing to send(e.g. ETH, BNB) + * @param _func Bytes of calldata to execute in the destination address + */ + function execute( + address _dest, + uint256 _value, + bytes calldata _func + ) external override onlyWhenUnlocked { + _requireFromEntryPoint(); + address restrictionsFacet = LibDiamond.restrictionsFacet(); + if (restrictionsFacet == address(0)) _call(_dest, _value, _func); + else _callWithRestrictions(_dest, _value, _func, restrictionsFacet); + } + + /** + * @notice Batch calls the destination with inputted calldata and value from EntryPoint + * @dev This method batch executes the calldata coming from the EntryPoint. + * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer) + * @param _dest Array of addresses of destination where the call will be forwarded to + * @param _value Array of amount of native coin the owner is willing to send(e.g. ETH, BNB) + * @param _func Array of bytes of calldata to execute in the destination address + */ + function executeBatch( + address[] calldata _dest, + uint256[] calldata _value, + bytes[] calldata _func + ) external override onlyWhenUnlocked { + _requireFromEntryPoint(); + if (_dest.length != _func.length || _dest.length != _value.length) + revert AccountFacet__InvalidArrayLength(); + address restrictionsFacet = LibDiamond.restrictionsFacet(); + if (restrictionsFacet == address(0)) { + for (uint256 i; i < _dest.length; ) { + _call(_dest[i], _value[i], _func[i]); + unchecked { + ++i; + } + } + } else { + for (uint256 i; i < _dest.length; ) { + _callWithRestrictions( + _dest[i], + _value[i], + _func[i], + restrictionsFacet + ); + unchecked { + ++i; + } + } + } + } + + /** + * @notice Validates the signature field of UserOperation + * @dev This method validates if the signature of UserOp is indeed valid by delegating the call to Verification Facet + * Barz makes a call to the pre-registered Verification Facet address in App Storage + * @param _userOp UserOperation from owner to be validated + * @param _userOpHash Hash of UserOperation given from the EntryPoint contract + */ + function _validateSignature( + UserOperation calldata _userOp, + bytes32 _userOpHash + ) internal override returns (uint256 validationData) { + // Get Facet with Function Selector + address facet = LibLoupe.facetAddress(s.validateOwnerSignatureSelector); + if (facet == address(0)) + revert AccountFacet__NonExistentVerificationFacet(); + + // Make function call to VerificationFacet + bytes memory validateCall = abi.encodeWithSelector( + s.validateOwnerSignatureSelector, + _userOp, + _userOpHash + ); + (bool success, bytes memory result) = facet.delegatecall(validateCall); + if (!success) revert AccountFacet__CallNotSuccessful(); + validationData = uint256(bytes32(result)); + if (validationData == 0) emit VerificationSuccess(_userOpHash); + else emit VerificationFailure(_userOpHash); + } + + /** + * @notice Calls the target with the inputted value and calldata + * @dev This method is the actual function in Barz that makes a call with an arbitrary owner-given data + * @param _target Address of the destination contract which the call is getting forwarded to + * @param _value Amount of Native coin the owner is wanting to make in this call + * @param _data Calldata the owner is forwarding together in the call e.g. Swap/Token Transfer + */ + function _call( + address _target, + uint256 _value, + bytes memory _data + ) internal { + (bool success, bytes memory result) = _target.call{value: _value}( + _data + ); + if (!success) { + assembly { + revert(add(result, 32), mload(result)) + } + } + } + + /** + * @notice Calls the target with the inputted value and calldata together with restrictions check + * @dev This method is the actual function in Barz that makes a call with an arbitrary owner-given data + * @param _target Address of the destination contract which the call is getting forwarded to + * @param _value Amount of Native coin the owner is wanting to make in this call + * @param _data Calldata the owner is forwarding together in the call e.g. Swap/Token Transfer + * @param _restrictionsFacet Address of Facet to validate restrictions + */ + function _callWithRestrictions( + address _target, + uint256 _value, + bytes memory _data, + address _restrictionsFacet + ) internal { + // NOTE: No restrictions facet, so restriction validation passes + if (_checkRestrictions(_restrictionsFacet, _target, _value, _data) != 0) + revert AccountFacet__RestrictionsFailure(); + + (bool success, bytes memory result) = _target.call{value: _value}( + _data + ); + if (!success) { + assembly { + revert(add(result, 32), mload(result)) + } + } + } + + /** + * @notice Checks restrictions if the restrictions facet exists + * @dev This method checks if the restrictions facet exists and makes a verification call to an array of restrictions facet + * @param _facet Address that holds the restrictions logic + * @param _target Address the call is getting forwarded to + * @param _value Amount of native coin the call is sending together with the call + * @param _data Calldata to trigger execution in target address + */ + function _checkRestrictions( + address _facet, + address _target, + uint256 _value, + bytes memory _data + ) internal returns (uint256 result) { + bytes memory call = abi.encodeWithSignature( + "verifyRestrictions(address,address,uint256,bytes)", + address(this), + _target, + _value, + _data + ); + (bool success, bytes memory response) = _facet.delegatecall(call); + if (!success) revert AccountFacet__RestrictionsFailure(); + result = uint256(bytes32(response)); + } +} diff --git a/contracts/facets/AccountRecoveryFacet.sol b/contracts/facets/AccountRecoveryFacet.sol new file mode 100644 index 0000000..6a2e7d8 --- /dev/null +++ b/contracts/facets/AccountRecoveryFacet.sol @@ -0,0 +1,573 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.21; + +import {SignatureChecker} from "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol"; +import {LibAppStorage} from "../libraries/LibAppStorage.sol"; +import {LibDiamond} from "../libraries/LibDiamond.sol"; +import {LibLoupe} from "../libraries/LibLoupe.sol"; +import {LibGuardian} from "../libraries/LibGuardian.sol"; +import {LibFacetStorage, RecoveryStorage, RecoveryConfig, RecoveryApprovalConfig, ApprovalConfig} from "../libraries/LibFacetStorage.sol"; +import {Modifiers} from "./Modifiers.sol"; +import {ISecurityManager} from "../infrastructure/interfaces/ISecurityManager.sol"; +import {IVerificationFacet} from "./interfaces/IVerificationFacet.sol"; +import {IAccountRecoveryFacet} from "./interfaces/IAccountRecoveryFacet.sol"; + +/** + * @title Account Recovery Facet + * @dev Contract that enables recovery of accounts when owner key is unavailable + * @author David Yongjun Kim (@Powerstream3604) + */ +contract AccountRecoveryFacet is IAccountRecoveryFacet, Modifiers { + bytes constant UNINIT_CALL = + abi.encodeWithSignature("uninitializeSigner()"); + ISecurityManager public immutable securityManager; + + /** + * @notice This constructor sets the Security Manager address which is an immutable variable. + * Immutable variables do not impact the storage of diamond + * @param _securityManager Security Manager contract that holds the security related variables for all wallets + */ + constructor(address _securityManager) { + securityManager = ISecurityManager(_securityManager); + } + + /** + * @notice Approve recovery of account as guardian + * @dev This method can only be called by guardian and guardian inputs the public key of the new owner + * When the threshold(majority of guardians) passes, it automatically executes account recovery + * @param _recoveryPublicKey Bytes of newly recovered public key of the owner + */ + function approveAccountRecovery( + bytes calldata _recoveryPublicKey + ) external override onlyGuardian { + if (_isRecoveryPending()) { + revert AccountRecoveryFacet__RecoveryAlreadyOngoing(); + } + RecoveryApprovalConfig storage rs = LibFacetStorage + .recoveryStorage() + .recoveryApprovalConfigs[INNER_STRUCT]; + validateNewOwner(_recoveryPublicKey); + bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash( + _recoveryPublicKey, + "ExecuteRecovery" + ); + uint64 approvalValidUntil = uint64( + block.timestamp + _getApprovalValidationPeriod() + ); + rs.isNewOwnerApproved[recoveryPublicKeyHash][ + msg.sender + ] = ApprovalConfig(true, approvalValidUntil); + emit RecoveryApproved( + _recoveryPublicKey, + msg.sender, + approvalValidUntil + ); + if ( + getRecoveryApprovalCountWithTimeValidity(recoveryPublicKeyHash) >= + LibGuardian.majorityOfGuardians() + ) { + _executeRecovery(_recoveryPublicKey); + } + } + + /** + * @notice Revoke recovery of account as guardian + * @dev This method can only be called by guardian and guardian inputs the public key of the new owner + When the threshold(majority of guardians) passes, it automatically revokes account recovery when recovery is pending + * @param _recoveryPublicKey Bytes of newly recovered public key of the owner + */ + function revokeAccountRecoveryApproval( + bytes calldata _recoveryPublicKey + ) external override onlyGuardian { + RecoveryApprovalConfig storage rs = LibFacetStorage + .recoveryStorage() + .recoveryApprovalConfigs[INNER_STRUCT]; + validateNewOwner(_recoveryPublicKey); + bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash( + _recoveryPublicKey, + "ExecuteRecovery" + ); + if ( + !rs + .isNewOwnerApproved[recoveryPublicKeyHash][msg.sender].isApproved || + !(block.timestamp < + rs + .isNewOwnerApproved[recoveryPublicKeyHash][msg.sender] + .validUntil) + ) { + revert AccountRecoveryFacet__NonExistentApproval(); + } + + rs.isNewOwnerApproved[recoveryPublicKeyHash][ + msg.sender + ] = ApprovalConfig(false, 0); + emit RecoveryApprovalRevoked(_recoveryPublicKey, msg.sender); + } + + /** + * @notice Executes recovery with signatures or on-chain pre-approvals + * @dev This method validates the signatures of guardians or checks the on-chain pre-approved calls to check if the threshold passes + * When the threshold passes, account recovery is executed and revert otherwise + * @param _recoveryPublicKey Bytes of newly recovered public key of the owner + * @param _guardians Array of guardians address that are approving the recovery of Account + * @param _signatures Array of signature bytes that signed the approval hash + */ + function executeRecovery( + bytes calldata _recoveryPublicKey, + address[] calldata _guardians, + bytes[] calldata _signatures + ) external override { + if (_isRecoveryPending()) { + revert AccountRecoveryFacet__RecoveryAlreadyOngoing(); + } + if (_guardians.length != _signatures.length) { + revert AccountRecoveryFacet__InvalidArrayLength(); + } + validateNewOwner(_recoveryPublicKey); + + bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash( + _recoveryPublicKey, + "ExecuteRecovery" + ); + + _checkApprover(_guardians); + _checkDuplicateOnChainApprover(recoveryPublicKeyHash, _guardians); + + if ( + _guardians.length + + getRecoveryApprovalCountWithTimeValidity( + recoveryPublicKeyHash + ) < + LibGuardian.majorityOfGuardians() + ) { + revert AccountRecoveryFacet__InsufficientGuardians(); + } + for (uint256 i; i < _guardians.length; ) { + if (!LibGuardian.isGuardian(_guardians[i])) { + revert AccountRecoveryFacet__InvalidGuardian(); + } + if ( + !SignatureChecker.isValidSignatureNow( + _guardians[i], + recoveryPublicKeyHash, + _signatures[i] + ) + ) { + revert AccountRecoveryFacet__InvalidGuardianSignature(); + } + unchecked { + ++i; + } + } + _executeRecovery(_recoveryPublicKey); + } + + /** + * @notice Executes recovery of the account. Note that execution and finalization is a different process + * @dev Executes the recovery and adds recovery data to recovery configuration. Locks the account + * @param _recoveryPublicKey Public Key of the account for recovery + */ + function _executeRecovery(bytes memory _recoveryPublicKey) internal { + RecoveryStorage storage rs = LibFacetStorage.recoveryStorage(); + unchecked { + ++rs.nonce; + } + uint64 executeAfter = uint64(block.timestamp + _getRecoveryPeriod()); + rs.recoveryConfigs[INNER_STRUCT] = RecoveryConfig( + _recoveryPublicKey, + executeAfter // NOTE: Remove guardian Count + ); + LibAppStorage.setLock( + block.timestamp + _getLockPeriod(), + AccountRecoveryFacet.executeRecovery.selector + ); + emit RecoveryExecuted(_recoveryPublicKey, executeAfter); + } + + /** + * @notice Finalize recovery after recovery pending period. Recovery pending period can be set by user beforehand in SecurityManager + * @dev This method finalizes recovery and fully changes the ownership of the account to the newly inputted recovery public key + */ + function finalizeRecovery() external override { + RecoveryStorage storage rs = LibFacetStorage.recoveryStorage(); + + if (!_isRecoveryPending()) { + revert AccountRecoveryFacet__NonexistentRecovery(); + } + if ( + uint64(block.timestamp) <= + rs.recoveryConfigs[INNER_STRUCT].executeAfter + ) { + revert AccountRecoveryFacet__RecoveryPeriodNotOver(); + } + bytes memory recoveryOwner = rs + .recoveryConfigs[INNER_STRUCT] + .recoveryPublicKey; + + delete rs.recoveryConfigs[INNER_STRUCT]; + + LibAppStorage.setLock(0, bytes4(0)); + + LibAppStorage.initiateSignerMigration(); + address verificationFacet = address( + bytes20( + LibDiamond.diamondStorage().facets[ + s.validateOwnerSignatureSelector + ] + ) + ); + (bool uninitSuccess, bytes memory uninitResult) = verificationFacet + .delegatecall(UNINIT_CALL); + if (!uninitSuccess) { + revert AccountRecoveryFacet__CallNotSuccesful(); + } + if (uint256(bytes32(uninitResult)) != 1) { + revert AccountRecoveryFacet__SignerUninitializationFailure(); + } + bytes memory initCall = abi.encodeWithSignature( + "initializeSigner(bytes)", + recoveryOwner + ); + (bool initSuccess, bytes memory initResult) = verificationFacet + .delegatecall(initCall); + if (!initSuccess) { + revert AccountRecoveryFacet__CallNotSuccesful(); + } + if (uint256(bytes32(initResult)) != 1) { + revert AccountRecoveryFacet__SignerInitializationFailure(); + } + LibAppStorage.finalizeSignerMigration(); + emit RecoveryFinalized(recoveryOwner); + } + + /** + * @notice Approves the cancellation of recovery + * @dev This method approves the cancellation of recovery when recovery is still pending - waiting for finalization + * @param _recoveryPublicKey Bytes of public key which is pending for recovery + */ + function approveCancelRecovery( + bytes calldata _recoveryPublicKey + ) external override onlyGuardian { + RecoveryApprovalConfig storage rs = LibFacetStorage + .recoveryStorage() + .recoveryApprovalConfigs[INNER_STRUCT]; + validateNewOwner(_recoveryPublicKey); + bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash( + _recoveryPublicKey, + "CancelRecovery" + ); + uint64 approvalValidUntil = uint64( + block.timestamp + _getApprovalValidationPeriod() + ); + rs.isNewOwnerApproved[recoveryPublicKeyHash][ + msg.sender + ] = ApprovalConfig(true, approvalValidUntil); + emit RecoveryCancellationApproved(_recoveryPublicKey, msg.sender); + if ( + getRecoveryApprovalCountWithTimeValidity(recoveryPublicKeyHash) >= + LibGuardian.majorityOfGuardians() + ) { + _cancelRecovery(_recoveryPublicKey); + } + } + + /** + * @notice Hardstops an ongoing recovery + * @dev This method provides a safety mechanism to protect owners of malicious guardians. + * Owners can hardstop recovery when an malicious guardians starts the recovery process. + * @param _signature Signature of the owner that signs the hash to hardstop recovery + */ + function hardstopRecovery(bytes calldata _signature) external override { + if (!_isRecoveryPending()) + revert AccountRecoveryFacet__NonexistentRecovery(); + bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash( + "0", + "HardstopRecovery" + ); + if ( + !SignatureChecker.isValidSignatureNow( + address(this), + recoveryPublicKeyHash, + _signature + ) + ) { + revert AccountRecoveryFacet__InvalidOwnerSignature(); + } + RecoveryStorage storage rs = LibFacetStorage.recoveryStorage(); + unchecked { + ++rs.nonce; + } + delete rs.recoveryConfigs[INNER_STRUCT]; + LibAppStorage.setLock(0, bytes4(0)); + emit RecoveryHardstopped(); + } + + /** + * @notice Cancels recovery with signatures or on-chain pre-approvals + * @dev This method validates the signatures of guardians or checks the on-chain pre-approved calls to check if the threshold passes + * When the threshold passes, account recovery is canceled and revert otherwise + * @param _recoveryPublicKey Bytes of newly recovered public key of the owner + * @param _guardians Array of guardians address that are approving the recovery of Account + * @param _signatures Array of signature bytes that signed the cancellation approval hash + */ + function cancelRecovery( + bytes calldata _recoveryPublicKey, + address[] calldata _guardians, + bytes[] calldata _signatures + ) external override { + if (_guardians.length != _signatures.length) { + revert AccountRecoveryFacet__InvalidArrayLength(); + } + validateNewOwner(_recoveryPublicKey); + + bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash( + _recoveryPublicKey, + "CancelRecovery" + ); + + _checkApprover(_guardians); + _checkDuplicateOnChainApprover(recoveryPublicKeyHash, _guardians); + + if ( + _guardians.length + + getRecoveryApprovalCountWithTimeValidity( + recoveryPublicKeyHash + ) < + LibGuardian.majorityOfGuardians() + ) { + revert AccountRecoveryFacet__InsufficientGuardians(); + } + for (uint256 i; i < _guardians.length; ) { + if (!LibGuardian.isGuardian(_guardians[i])) { + revert AccountRecoveryFacet__CallerNotGuardian(); + } + if ( + !SignatureChecker.isValidSignatureNow( + _guardians[i], + recoveryPublicKeyHash, + _signatures[i] + ) + ) { + revert AccountRecoveryFacet__InvalidGuardianSignature(); + } + unchecked { + ++i; + } + } + _cancelRecovery(_recoveryPublicKey); + } + + /** + * @notice Cancel recovery when the recovery is pending. Unlock the account as well + * @dev This method checks if the recovery is pending and reverts if not pending. + * It increases the recovery nonce and deletes the recovery information and gets a small portion of gas in return + * @param _recoveryPublicKey Bytes of newly recovered public key of the owner + */ + function _cancelRecovery(bytes memory _recoveryPublicKey) internal { + if (!_isRecoveryPending()) { + revert AccountRecoveryFacet__NonexistentRecovery(); + } + LibAppStorage.setLock(0, bytes4(0)); + RecoveryStorage storage rs = LibFacetStorage.recoveryStorage(); + unchecked { + ++rs.nonce; + } + delete rs.recoveryConfigs[INNER_STRUCT]; + emit RecoveryCanceled(_recoveryPublicKey); + } + + /** + * @notice Validates the format of public key to be used for recovery + * @dev This method checks if the public key format is correct and reverts otherwise + * @param _recoveryPublicKey Bytes of newly recovered public key of the owner + */ + function validateNewOwner( + bytes calldata _recoveryPublicKey + ) public view override { + if ( + !IVerificationFacet( + LibLoupe.facetAddress(s.validateOwnerSignatureSelector) + ).isValidKeyType(_recoveryPublicKey) + ) { + revert AccountRecoveryFacet__InvalidRecoveryPublicKey(); + } + } + + /** + * @notice Checks if recovery is currently pending + * @return isPending Boolean indicating if recovery is pending + */ + function _isRecoveryPending() internal view returns (bool isPending) { + RecoveryStorage storage rs = LibFacetStorage.recoveryStorage(); + isPending = (rs.recoveryConfigs[INNER_STRUCT].executeAfter > 0); + } + + /** + * @notice Calculate the recovery hash dependent on chain, wallet address, nonce with EIP-191 prefix for safety + * @dev Returns the keccak256 hash of EIP-191 msg hash packed with public key, salt, nonce, wallet address, etc + * @param _recoveryPublicKey Bytes of newly recovered public key of the owner + * @param _saltString Salt string to uniquely identify each recovery hash and for security + * @return recoveryKeyHash Bytes32 string of the recovery hash + */ + function getApprovalRecoveryKeyHash( + bytes memory _recoveryPublicKey, + string memory _saltString + ) public view override returns (bytes32 recoveryKeyHash) { + recoveryKeyHash = keccak256( + abi.encodePacked( + "\x19Ethereum Signed Message:\n32", + keccak256( + abi.encode( + _recoveryPublicKey, + _saltString, + address(this), + block.chainid, + LibFacetStorage.recoveryStorage().nonce + ) + ) + ) + ); + } + + /** + * @notice Check the onchain approval of guardians and returns the number of guardians that approved + * @dev Loop through the guardian addresses and returns the number of guardians that approved this recovery hash + * @param _recoveryPublicKeyHash Bytes hash of newly recovered public key and recovery value of the account + * @return approvalCount Number of guardians that approved + */ + function getRecoveryApprovalCountWithTimeValidity( + bytes32 _recoveryPublicKeyHash + ) public view override returns (uint256 approvalCount) { + address[] memory guardians = LibGuardian.getGuardians(); + uint256 guardianLength = guardians.length; + for (uint256 i; i < guardianLength; ) { + if (isRecoveryApproved(_recoveryPublicKeyHash, guardians[i])) { + unchecked { + ++approvalCount; + } + } + unchecked { + ++i; + } + } + } + + /** + * @notice Checks if the recovery is approved by the given approver + * @param _recoveryPublicKeyHash Hash of the public key and configuration for recovery + * @param _approver Address of approver + * @return isApproved Bool value if recovery hash is approved + */ + function isRecoveryApproved( + bytes32 _recoveryPublicKeyHash, + address _approver + ) public view override returns (bool isApproved) { + RecoveryApprovalConfig storage rs = LibFacetStorage + .recoveryStorage() + .recoveryApprovalConfigs[INNER_STRUCT]; + if ( + rs + .isNewOwnerApproved[_recoveryPublicKeyHash][_approver].isApproved && + block.timestamp < + rs.isNewOwnerApproved[_recoveryPublicKeyHash][_approver].validUntil + ) { + isApproved = true; + } + } + + /** + * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval + * Approvers who approved on-chain should not be included in the off-chain approval + * @param _recoveryPublicKeyHash Hash of recovery information + * @param _approvers List of approver addresses + */ + function _checkDuplicateOnChainApprover( + bytes32 _recoveryPublicKeyHash, + address[] memory _approvers + ) public view { + address[] memory guardians = LibGuardian.getGuardians(); + uint256 guardianLength = guardians.length; + uint256 approversLength = _approvers.length; + for (uint256 i; i < guardianLength; ) { + if (isRecoveryApproved(_recoveryPublicKeyHash, guardians[i])) { + for (uint256 j; j < approversLength; ) { + if (_approvers[j] == guardians[i]) { + revert AccountRecoveryFacet__DuplicateApproval(); + } + unchecked { + ++j; + } + } + } + unchecked { + ++i; + } + } + } + + /** + * @notice Returns the lock period of this wallet address from security manager + * @return lockPeriod value of lock period + */ + function _getLockPeriod() internal view returns (uint256 lockPeriod) { + lockPeriod = securityManager.lockPeriodOf(address(this)); + if (lockPeriod == 0) { + revert AccountRecoveryFacet__InvalidLockPeriod(); + } + } + + /** + * @notice Returns the lock period of this wallet address from security manager + * @return recoveryPeriod value of recovery period + */ + function _getRecoveryPeriod() + internal + view + returns (uint256 recoveryPeriod) + { + recoveryPeriod = securityManager.recoveryPeriodOf(address(this)); + if (recoveryPeriod == 0) { + revert AccountRecoveryFacet__InvalidRecoveryPeriod(); + } + } + + /** + * @notice Returns the approval validation period of this wallet address from security manager + * @return approvalValidationPeriod value of approval validation period + */ + function _getApprovalValidationPeriod() + internal + view + returns (uint256 approvalValidationPeriod) + { + approvalValidationPeriod = securityManager.approvalValidationPeriodOf( + address(this) + ); + if (approvalValidationPeriod == 0) { + revert AccountRecoveryFacet__InvalidApprovalValidationPeriod(); + } + } + + /** + * @notice Returns the recovery nonce of this wallet address from security manager + * @return nonce value of recovery nonce + */ + function getRecoveryNonce() public view override returns (uint128 nonce) { + nonce = LibFacetStorage.recoveryStorage().nonce; + } + + /** + * @notice Returns the recovery information of the pending recovery + * @return recoveryConfig value struct of pending recovery + */ + function getPendingRecovery() + public + view + override + returns (RecoveryConfig memory recoveryConfig) + { + recoveryConfig = LibFacetStorage.recoveryStorage().recoveryConfigs[ + INNER_STRUCT + ]; + } +} diff --git a/contracts/facets/GuardianFacet.sol b/contracts/facets/GuardianFacet.sol new file mode 100644 index 0000000..83875be --- /dev/null +++ b/contracts/facets/GuardianFacet.sol @@ -0,0 +1,470 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.21; + +import {LibDiamond} from "../libraries/LibDiamond.sol"; +import {LibFacetStorage, GuardianStorage, StorageConfig} from "../libraries/LibFacetStorage.sol"; +import {LibGuardian} from "../libraries/LibGuardian.sol"; +import {ISecurityManager} from "../infrastructure/interfaces/ISecurityManager.sol"; +import {IGuardianFacet} from "./interfaces/IGuardianFacet.sol"; +import {IVerificationFacet} from "./interfaces/IVerificationFacet.sol"; + +/** + * @title Guardian Facet + * @dev Contract that enables addition/removal of guardians from Barz + * @author David Yongjun Kim (@Powerstream3604) + */ +contract GuardianFacet is IGuardianFacet { + ISecurityManager public immutable securityManager; + uint8 public constant INNER_STRUCT = 0; + + /** + * @notice This constructor sets the Security Manager address which is an immutable variable. + * Immutable variables do not impact the storage of diamond + * @param _securityManager Security Manager contract that holds the security related variables for all wallets + */ + constructor(address _securityManager) { + securityManager = ISecurityManager(_securityManager); + } + + /** + * @notice Add guardians to Barz. + * @dev This method internally calls addGuardian which checks the validity of guardian address and adds + * as guardian if valid + * @param _guardians Array of addresses to add as guardian + */ + function addGuardians(address[] calldata _guardians) external override { + LibDiamond.enforceIsSelf(); + for (uint256 i; i < _guardians.length; ) { + addGuardian(_guardians[i]); + unchecked { + ++i; + } + } + } + + /** + * @notice Add a guardian to Barz. + * @dev This method checks if the function is called by the owner and validates the address of guardian + * When the validation passes, guardian address is added to the pending state waiting for confirmation + * @param _guardian Address to add as guardian + */ + function addGuardian(address _guardian) public override { + LibDiamond.enforceIsSelf(); + GuardianStorage storage gs = LibFacetStorage.guardianStorage(); + if (_guardian == address(this)) { + revert GuardianFacet__GuardianCannotBeSelf(); + } + if (isGuardian(_guardian)) { + revert GuardianFacet__DuplicateGuardian(); + } + if (_guardian == address(0)) { + revert GuardianFacet__ZeroAddressGuardian(); + } + if ( + keccak256(abi.encodePacked(_guardian)) == + keccak256(IVerificationFacet(address(this)).owner()) + ) { + revert GuardianFacet__OwnerCannotBeGuardian(); + } + + bytes32 id = keccak256(abi.encodePacked(_guardian, "ADD")); + if ( + gs.pending[id] != 0 || + block.timestamp <= gs.pending[id] + getSecurityWindow() + ) { + revert GuardianFacet__DuplicateGuardianAddition(); + } + + uint256 securityPeriod = getAdditionSecurityPeriod(); + gs.pending[id] = block.timestamp + securityPeriod; + emit GuardianAdditionRequested( + _guardian, + block.timestamp + securityPeriod + ); + } + + /** + * @notice Remove guardians from Barz. + * @dev This method internally calls removeGuardian which checks the validity of guardian and removes + * guardian when the request is valid + * @param _guardians Array of addresses to be removed + */ + function removeGuardians(address[] calldata _guardians) external override { + LibDiamond.enforceIsSelf(); + for (uint256 i; i < _guardians.length; ) { + removeGuardian(_guardians[i]); + unchecked { + ++i; + } + } + } + + /** + * @notice Remove a guardian from Barz. + * @dev This method validates if the guardian to be removed is a guardian and puts the guardian removal + * to a pending state waiting to be confirmed. + * @param _guardian Address of guardian to be removed + */ + function removeGuardian(address _guardian) public override { + LibDiamond.enforceIsSelf(); + if (!isGuardian(_guardian)) { + revert GuardianFacet__NonExistentGuardian(); + } + GuardianStorage storage gs = LibFacetStorage.guardianStorage(); + bytes32 id = keccak256(abi.encodePacked(_guardian, "REMOVE")); + if ( + gs.pending[id] != 0 || + block.timestamp <= gs.pending[id] + getSecurityWindow() + ) { + revert GuardianFacet__DuplicateGuardianRemoval(); + } + + uint256 securityPeriod = getRemovalSecurityPeriod(); + gs.pending[id] = block.timestamp + securityPeriod; + emit GuardianRemovalRequested( + _guardian, + block.timestamp + securityPeriod + ); + } + + /** + * @notice Confirm addition of guardians + * @dev This method internally calls confirmGuardianAddition which checks the validity of pending request. + * Guardians are fully added when they pass the validation. Anyone can call this function. + * @param _guardians Array of guardian addresses to be added + */ + function confirmGuardianAdditions( + address[] calldata _guardians + ) external override { + for (uint256 i; i < _guardians.length; ) { + confirmGuardianAddition(_guardians[i]); + unchecked { + ++i; + } + } + } + + /** + * @notice Confirm addition of a guardian + * @dev This method checks the validity of pending request. + * Guardians are fully added when they pass the validation. Anyone can call this function. + * @param _guardian Guardian address to be added + */ + function confirmGuardianAddition(address _guardian) public override { + bytes32 id = keccak256(abi.encodePacked(_guardian, "ADD")); + GuardianStorage storage gs = LibFacetStorage.guardianStorage(); + if (gs.pending[id] == 0) { + revert GuardianFacet__UnknownPendingAddition(); + } + if (gs.pending[id] >= block.timestamp) { + revert GuardianFacet__PendingAdditionNotOver(); + } + if (block.timestamp >= gs.pending[id] + getSecurityWindow()) { + revert GuardianFacet__PendingAdditionExpired(); + } + + _addGuardian(_guardian); + + delete gs.pending[id]; + emit GuardianAdded(_guardian); + } + + /** + * @notice Confirm removal of guardians + * @dev This method internally calls confirmGuardianRemoval to check the validity guardian removal confirmation. + * Guardians are fully removed when they pass the validation. Anyone can call this function. + * @param _guardians Array of guardian addresses to be removed + */ + function confirmGuardianRemovals( + address[] calldata _guardians + ) external override { + for (uint256 i; i < _guardians.length; ) { + confirmGuardianRemoval(_guardians[i]); + unchecked { + ++i; + } + } + } + + /** + * @notice Confirm removal of a guardian + * @dev This method checks the validity guardian removal confirmation. + * Guardian is fully removed when they pass the validation. Anyone can call this function. + * @param _guardian Guardian address to be removed + */ + function confirmGuardianRemoval(address _guardian) public override { + bytes32 id = keccak256(abi.encodePacked(_guardian, "REMOVE")); + GuardianStorage storage gs = LibFacetStorage.guardianStorage(); + if (gs.pending[id] == 0) { + revert GuardianFacet__UnknownPendingRemoval(); + } + if (gs.pending[id] >= block.timestamp) { + revert GuardianFacet__PendingRemovalNotOver(); + } + if (block.timestamp >= gs.pending[id] + getSecurityWindow()) { + revert GuardianFacet__PendingAdditionExpired(); + } + + _removeGuardian(_guardian); + delete gs.pending[id]; + emit GuardianRemoved(_guardian); + } + + /** + * @notice Cancel pending guardian addition + * @dev This method checks if the previous request for guardian request exists. + * It reverts if previous request is not pending and cancels the addition otherwise. + * @param _guardian Guardian address to be canceled from addition + */ + function cancelGuardianAddition(address _guardian) external override { + LibDiamond.enforceIsSelf(); + bytes32 id = keccak256(abi.encodePacked(_guardian, "ADD")); + GuardianStorage storage gs = LibFacetStorage.guardianStorage(); + if (gs.pending[id] == 0) { + revert GuardianFacet__UnknownPendingAddition(); + } + delete gs.pending[id]; + emit GuardianAdditionCancelled(_guardian); + } + + /** + * @notice Cancel pending guardian removal + * @dev This method checks if the previous request for guardian request exists. + * It reverts if previous request is not pending and cancels the removal otherwise. + * @param _guardian Guardian address to be canceled from removal + */ + function cancelGuardianRemoval(address _guardian) external override { + LibDiamond.enforceIsSelf(); + bytes32 id = keccak256(abi.encodePacked(_guardian, "REMOVE")); + GuardianStorage storage gs = LibFacetStorage.guardianStorage(); + if (gs.pending[id] == 0) { + revert GuardianFacet__UnknownPendingRemoval(); + } + delete gs.pending[id]; + emit GuardianRemovalCancelled(_guardian); + } + + /** + * @notice Get the addition security period of current account from security manager + * @dev This method returns the uint value if addition security period + * @return additionSecurityPeriod Uint256 value of addition security period + */ + function getAdditionSecurityPeriod() + public + view + override + returns (uint256 additionSecurityPeriod) + { + additionSecurityPeriod = securityManager.additionSecurityPeriodOf( + address(this) + ); + if (additionSecurityPeriod == 0) { + revert GuardianFacet__InvalidAdditionSecurityPeriod(); + } + } + + /** + * @notice Get the removal security period of current account from security manager + * @dev This method returns the uint value if removal security period + * @return removalSecurityPeriod Uint256 value of removal security period + */ + function getRemovalSecurityPeriod() + public + view + override + returns (uint256 removalSecurityPeriod) + { + removalSecurityPeriod = securityManager.removalSecurityPeriodOf( + address(this) + ); + if (removalSecurityPeriod == 0) { + revert GuardianFacet__InvalidRemovalSecurityPeriod(); + } + } + + /** + * @notice Get the security window of current account from security manager + * @dev This method returns the uint value if security window + * @return securityWindow Uint256 value of removal security period + */ + function getSecurityWindow() + public + view + override + returns (uint256 securityWindow) + { + securityWindow = securityManager.securityWindowOf(address(this)); + if (securityWindow == 0) { + revert GuardianFacet__InvalidSecurityWindow(); + } + } + + /** + * @notice Checks if the addition of the given guardian address is pending + * @dev This method returns the bool value of whether the guardian address is pending addition + * @return isPending Bool value of representing the pending of guardian addition + */ + function isAdditionPending( + address _guardian + ) public view override returns (bool isPending) { + bytes32 id = keccak256(abi.encodePacked(_guardian, "ADD")); + isPending = _isPending(id); + } + + /** + * @notice Checks if the removal of the given guardian address is pending + * @dev This method returns the bool value of whether the guardian address is pending removal + * @return isPending Bool value of representing the pending of guardian removal + */ + function isRemovalPending( + address _guardian + ) public view override returns (bool isPending) { + bytes32 id = keccak256(abi.encodePacked(_guardian, "REMOVE")); + isPending = _isPending(id); + } + + /** + * @notice Checks if the given hash is pending + * @dev This method returns the bool value whether the hash is pending + * @return isPending Bool value of representing the pending of guardian operation + */ + function _isPending( + bytes32 _idHash + ) internal view returns (bool isPending) { + GuardianStorage storage gs = LibFacetStorage.guardianStorage(); + isPending = ((gs.pending[_idHash] > 0 && + gs.pending[_idHash] < block.timestamp) && + block.timestamp < gs.pending[_idHash] + getSecurityWindow()); + } + + /** + * @notice Adds guardian to storage config. This is called when guardian is fully added. + * @dev This method add guardian address and config information to Facet Storage dedicated for guardian + * When this function is called, guardian is fully added to this Barz Smart Account + * @param _guardian Address of guardian to be added + */ + function _addGuardian(address _guardian) internal { + if (!isAdditionPending(_guardian)) { + revert GuardianFacet__InvalidGuardianAddition(); + } + StorageConfig storage config = LibFacetStorage + .guardianStorage() + .configs[INNER_STRUCT]; + if (config.info[_guardian].exists) { + revert GuardianFacet__AlreadyExists(); + } + + config.info[_guardian].exists = true; + config.info[_guardian].index = uint128(config.addresses.length); + config.addresses.push(_guardian); + } + + /** + * @notice Removes guardian to storage config. This is called when guardian is fully removed. + * @dev This method remove guardian address and config information to Facet Storage dedicated for guardian + * When this function is called, guardian is fully removed from this Barz Smart Account + * @param _guardian Address of guardian to be removed + */ + function _removeGuardian(address _guardian) internal { + if (!isRemovalPending(_guardian)) { + revert GuardianFacet__InvalidGuardianRemoval(); + } + StorageConfig storage config = LibFacetStorage + .guardianStorage() + .configs[INNER_STRUCT]; + if (!config.info[_guardian].exists) { + revert GuardianFacet__NonExistentGuardian(); + } + + address lastAddress = config.addresses[config.addresses.length - 1]; + if (_guardian != lastAddress) { + uint128 targetIndex = config.info[_guardian].index; + config.addresses[targetIndex] = lastAddress; + config.info[lastAddress].index = targetIndex; + } + config.addresses.pop(); + delete config.info[_guardian]; + + emit GuardianRemoved(_guardian); + } + + /** + * @notice Reads guardian storage and fetches the addresses into an array from the storage + * @dev This method fetches the guardian storage and returns the list of guardian addresses + * @return guardians Array of addresses comprised of guardian + */ + function getGuardians() + public + view + override + returns (address[] memory guardians) + { + StorageConfig storage config = LibFacetStorage + .guardianStorage() + .configs[INNER_STRUCT]; + uint256 guardiansLen = config.addresses.length; + guardians = new address[](guardiansLen); + for (uint256 i; i < guardiansLen; ) { + guardians[i] = config.addresses[i]; + unchecked { + ++i; + } + } + } + + /** + * @notice Returns the number of majority of guardians + * @return majorityOfGuardians_ Number of majority of guardians e.g., 2 if 3 guardians / 3 if 5 guardians + */ + function majorityOfGuardians() + public + view + override + returns (uint256 majorityOfGuardians_) + { + majorityOfGuardians_ = LibGuardian.majorityOfGuardians(); + } + + /** + * @notice Reads guardian storage and fetches the addresses into an array from the storage + * @dev This method fetches the guardian storage and returns the list of guardian addresses + * @return guardianNumber Array of guardians in the account + */ + function guardianCount() + public + view + override + returns (uint256 guardianNumber) + { + StorageConfig storage config = LibFacetStorage + .guardianStorage() + .configs[INNER_STRUCT]; + guardianNumber = config.addresses.length; + } + + /** + * @notice Reads guardian storage and checks if the given address is a guardian + * @return isGuardian_ Bool value representing if the given address is guardian + */ + function isGuardian( + address _guardian + ) public view override returns (bool isGuardian_) { + StorageConfig storage config = LibFacetStorage + .guardianStorage() + .configs[INNER_STRUCT]; + isGuardian_ = config.info[_guardian].exists; + } + + /** + * @notice Checks if the guardian number is zero and returns of guardian facet is okay to be removed + * @return isRemovable Bool value representing if guardian facet is removable + */ + function isGuardianFacetRemovable() + external + view + override + returns (bool isRemovable) + { + isRemovable = (0 == guardianCount()); + } +} diff --git a/contracts/facets/LockFacet.sol b/contracts/facets/LockFacet.sol new file mode 100644 index 0000000..7a35d93 --- /dev/null +++ b/contracts/facets/LockFacet.sol @@ -0,0 +1,148 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.21; + +import {SignatureChecker} from "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol"; +import {LibAppStorage, Lock} from "../libraries/LibAppStorage.sol"; +import {LibGuardian} from "../libraries/LibGuardian.sol"; +import {LibFacetStorage} from "../libraries/LibFacetStorage.sol"; +import {Modifiers} from "./Modifiers.sol"; +import {ISecurityManager} from "../infrastructure/interfaces/ISecurityManager.sol"; +import {ILockFacet} from "./interfaces/ILockFacet.sol"; + +/** + * @title Lock Facet + * @dev Contract that enables full lock/unlock of Barz + * @author David Yongjun Kim (@Powerstream3604) + */ +contract LockFacet is ILockFacet, Modifiers { + ISecurityManager public immutable securityManager; + + /** + * @notice This constructor sets the Security Manager address which is an immutable variable. + * Immutable variables do not impact the storage of diamond + * @param _securityManager Security Manager contract that holds the security related variables for all wallets + */ + constructor(address _securityManager) { + securityManager = ISecurityManager(_securityManager); + } + + /** + * @notice Locks the account for the lock period. Lock period is defined in the security manager and it's customizable + * This function can only be called when account is unlocked by owner or guardians + * @dev This method checks the caller and if the account is currently locked and locks the account after fetching the + * Lock period from the owner. + */ + function lock() external override onlyGuardianOrOwner onlyWhenUnlocked { + uint256 unlockTime = block.timestamp + getLockPeriod(); + unchecked { + ++LibFacetStorage.lockStorage().nonce; + } + LibAppStorage.setLock(unlockTime, LockFacet.lock.selector); + emit Locked(uint64(unlockTime)); + } + + /** + * @notice Locks the account when the account is locked. This function can be called by anyone but must provide the approver address and signature. + * The approver should be one of the guardians or owner. + * @dev This method takes the approver address and the signature. After validating the address and the signature, it unlocks the account immediately. + * Only one of the guardian or owner is required to lock and unlock the account. + * @param _approver Address of approver approving the unlock of Barz account + * @param _signature Signature of the approver that signed the msg hash for unlocking the account + */ + function unlock( + address _approver, + bytes calldata _signature + ) external override onlyWhenLocked { + if (_approver != address(this) && !LibGuardian.isGuardian(_approver)) { + revert LockFacet__InvalidApprover(); + } + if ( + !SignatureChecker.isValidSignatureNow( + _approver, + getUnlockHash(), + _signature + ) + ) { + revert LockFacet__InvalidSignature(); + } + _unlock(); + } + + /** + * @notice Unlocks the account and increments the lock nonce + */ + function _unlock() private { + if (s.locks[INNER_STRUCT].locker != LockFacet.lock.selector) { + revert LockFacet__CannotUnlock(); + } + unchecked { + ++LibFacetStorage.lockStorage().nonce; + } + LibAppStorage.setLock(0, bytes4(0)); + emit Unlocked(); + } + + /** + * @notice Returns the lock period of current Barz account. Lock period information is held by Security Manager + * @return lockPeriod Uint value of lock period in seconds + */ + function getLockPeriod() public view override returns (uint256 lockPeriod) { + lockPeriod = securityManager.lockPeriodOf(address(this)); + if (lockPeriod == 0) { + revert LockFacet__InvalidRecoveryPeriod(); + } + } + + /** + * @notice Returns if the account is locked or not + * @dev This method fetches the current block timestamp and compares that with release time. + * After checking the timestamp and release time, it returns if the account is still locked or not. + * @return isLocked_ Uint value of lock period in seconds + */ + function isLocked() public view override returns (bool isLocked_) { + isLocked_ = uint64(block.timestamp) < s.locks[INNER_STRUCT].release; + } + + /** + * @notice Calculates the unlock hash and returns the unlock hash safe from signature reply attack + * @dev This method calculates the unlock hash with EIP-191 prefix, wallet address, chainID, and nonce + * It packs the result and packs them and hashes it. + * @return unlockHash Bytes32 unlock hash + */ + function getUnlockHash() public view override returns (bytes32 unlockHash) { + unlockHash = keccak256( + abi.encodePacked( + "\x19Ethereum Signed Message:\n32", + keccak256( + abi.encode( + "Unlock", + address(this), + block.chainid, + lockNonce() + ) + ) + ) + ); + } + + /** + * @notice Returns lock nonce of account. Reads nonce from lock storage within facet storage + * @return lockNonce_ Uint128 value of lock nonce. This is incremented whenever the account is lock/unlocked + */ + function lockNonce() public view override returns (uint128 lockNonce_) { + lockNonce_ = LibFacetStorage.lockStorage().nonce; + } + + /** + * @notice Returns the overall information of current lock + * @return pendingLock Struct value including all information of pending lock + */ + function getPendingLock() + public + view + override + returns (Lock memory pendingLock) + { + pendingLock = s.locks[INNER_STRUCT]; + } +} diff --git a/contracts/facets/Modifiers.sol b/contracts/facets/Modifiers.sol new file mode 100644 index 0000000..fff70b8 --- /dev/null +++ b/contracts/facets/Modifiers.sol @@ -0,0 +1,91 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.21; + +import {LibGuardian} from "../libraries/LibGuardian.sol"; +import {BarzStorage} from "../libraries/LibAppStorage.sol"; +import {IDiamondCut} from "../facets/base/interfaces/IDiamondCut.sol"; + +/** + * @title Modifiers + * @dev Responsible for providing modifiers/util functions to Facet contracts + * @author David Yongjun Kim (@Powerstream3604) + */ +abstract contract Modifiers is BarzStorage { + uint8 constant INNER_STRUCT = 0; + + error CallerNotGuardian(); + error CallerNotGuardianOrOwner(); + error DuplicateApprover(); + error ZeroApproverLength(); + error UnregisteredFacetAndSelectors(); + + /** + * @notice Modifier to only allow guardian to make a call, reverts if any other entity is the caller + */ + modifier onlyGuardian() { + if (!LibGuardian.isGuardian(msg.sender)) revert CallerNotGuardian(); + _; + } + + /** + * @notice Modifier to only allow guardian or owner to make a call, reverts if any other entity is the caller + */ + modifier onlyGuardianOrOwner() { + if (!LibGuardian.isGuardian(msg.sender) && address(this) != msg.sender) + revert CallerNotGuardianOrOwner(); + _; + } + + /** + * @notice Checks if the approver address is the array is unique with no duplicate + * @dev This method loops through the array and checks if a duplicate address exists, it reverts if duplicate address exists + * @param approvers Array of address + */ + function _checkApprover( + address[] memory approvers + ) internal pure returns (bool) { + uint256 approverLength = approvers.length; + if (0 == approverLength) revert ZeroApproverLength(); + for (uint256 i; i < approverLength - 1; ) { + for (uint256 j = i + 1; j < approverLength; ) { + if (approvers[i] == approvers[j]) { + revert DuplicateApprover(); // Found a duplicate + } + unchecked { + ++j; + } + } + unchecked { + ++i; + } + } + return false; // No duplicates found + } + + /** + * @notice Checks if the facet getting added or replaced is registered to facet registry + * @dev This method loops through the cut and checks if the facet getting added/replaced is registered to facet registry + * @param _diamondCut Array of FacetCut, data for diamondCut defined in EIP-2535 + */ + function _checkFacetCutValidity( + IDiamondCut.FacetCut[] memory _diamondCut + ) internal view { + uint256 diamondCutLength = _diamondCut.length; + for (uint256 i; i < diamondCutLength; ) { + if ( + _diamondCut[i].action == IDiamondCut.FacetCutAction.Add || + _diamondCut[i].action == IDiamondCut.FacetCutAction.Replace + ) { + if ( + !s.facetRegistry.areFacetFunctionSelectorsRegistered( + _diamondCut[i].facetAddress, + _diamondCut[i].functionSelectors + ) + ) revert UnregisteredFacetAndSelectors(); + } + unchecked { + ++i; + } + } + } +} diff --git a/contracts/facets/ReentrancyGuard.sol b/contracts/facets/ReentrancyGuard.sol new file mode 100644 index 0000000..11c429b --- /dev/null +++ b/contracts/facets/ReentrancyGuard.sol @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.21; + +import {LibReentrancyGuardStorage, ReentrancyGuardStorage} from "../libraries/LibReentrancyGuardStorage.sol"; + +abstract contract ReentrancyGuard { + uint256 private constant _NOT_ENTERED = 0; + uint256 private constant _ENTERED = 1; + + error ReentrancyGuard__ReentrantCall(); + + modifier nonReentrant() { + ReentrancyGuardStorage storage rgs = LibReentrancyGuardStorage + .reentrancyguardStorage(); + + if (rgs.status == _ENTERED) { + revert ReentrancyGuard__ReentrantCall(); + } + + rgs.status = _ENTERED; + + _; // Execute function + + rgs.status = _NOT_ENTERED; + } +} diff --git a/contracts/facets/RestrictionsFacet.sol b/contracts/facets/RestrictionsFacet.sol new file mode 100644 index 0000000..5423a9c --- /dev/null +++ b/contracts/facets/RestrictionsFacet.sol @@ -0,0 +1,208 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.21; + +import {ReentrancyGuard} from "./ReentrancyGuard.sol"; +import {LibDiamond} from "../libraries/LibDiamond.sol"; +import {LibAppStorage} from "../libraries/LibAppStorage.sol"; +import {LibFacetStorage, RestrictionsStorage} from "../libraries/LibFacetStorage.sol"; +import {IRestriction} from "../restrictions/IRestriction.sol"; +import {IRestrictionsFacet} from "./interfaces/IRestrictionsFacet.sol"; + +/** + * @title Restrictions facet + * @dev Responsible for storing and verifying different kinds of restrictions, for example: + * - Whitelist / Blacklist + * - Daily limits + * - Trading time restrictions + * @author Ruslan Serebriakov (@rsrbk) + */ +contract RestrictionsFacet is IRestrictionsFacet, ReentrancyGuard { + /** + * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts + */ + constructor() { + LibAppStorage.enforceRestrictionsInitialize(); + } + + /** + * @notice Intialize restrictions of Barz. Restrictions facet call restriction contracts for restriction validation + * before each call + * @param _restrictions The initial array of restrictions. + * @return initSuccess Int value showing if the initialization of restriction is successful + */ + function initializeRestrictions( + address[] calldata _restrictions + ) public override returns (uint256 initSuccess) { + LibDiamond.enforceIsSelf(); + LibAppStorage.enforceRestrictionsInitialize(); + + if (_restrictions.length == 0) { + // You can't initialize RestrictionsFacet with an empty list of restrictions + revert RestrictionsFacet__EmptyRestrictionsList(); + } + for (uint256 i; i < _restrictions.length; ) { + if (_restrictions[i] == address(0)) + revert RestrictionsFacet__ZeroAddressRestrictions(); + unchecked { + ++i; + } + } + + LibFacetStorage.restrictionsStorage().restrictions = _restrictions; + _updateRestrictionsMap(_restrictions, true); + initSuccess = 1; + } + + /** + * @notice Unitialize restrictions of Barz + * @return uninitSuccess Int value showing if the initialization of restriction is successful + */ + function uninitializeRestrictions() + external + override + returns (uint256 uninitSuccess) + { + LibDiamond.enforceIsSelf(); + LibAppStorage.setRestrictionsUninitialized(); + RestrictionsStorage storage restrictionsStorage = LibFacetStorage + .restrictionsStorage(); + _updateRestrictionsMap(restrictionsStorage.restrictions, false); + restrictionsStorage.restrictions = new address[](0); + uninitSuccess = 1; + } + + /** + * @notice Returns the list of Restrictions contract address + * @return restrictions Addresses of IRestriction which are currently active + */ + function getRestrictions() + public + view + override + returns (address[] memory restrictions) + { + RestrictionsStorage storage restrictionsStorage = LibFacetStorage + .restrictionsStorage(); + restrictions = restrictionsStorage.restrictions; + } + + /** + * @notice Adds restrictions to Barz with validation on the restriction contract address. + * This method is only callable by the owner(self). + * @param _restriction The address of the restriction to be added. + */ + function addRestriction(address _restriction) external override { + LibDiamond.enforceIsSelf(); + if (LibDiamond.restrictionsFacet() == address(0)) { + revert RestrictionsFacet__ZeroAddressRestrictionsFacet(); + } + RestrictionsStorage storage restrictionsStorage = LibFacetStorage + .restrictionsStorage(); + if (_restriction == address(0)) { + revert RestrictionsFacet__ZeroAddressRestrictions(); + } + if (restrictionsStorage.exists[_restriction]) { + revert RestrictionsFacet__RestrictionAlreadyExists(); + } + + restrictionsStorage.restrictions.push(_restriction); + restrictionsStorage.exists[_restriction] = true; + + emit RestrictionAdded(_restriction); + } + + /** + * @notice Remove restrictions from Barz if it existed. This method is only callable by the owner(self). + * @param _restriction The address of the restriction to be removed. + */ + function removeRestriction(address _restriction) external override { + LibDiamond.enforceIsSelf(); + RestrictionsStorage storage restrictionsStorage = LibFacetStorage + .restrictionsStorage(); + + if (!restrictionsStorage.exists[_restriction]) { + revert RestrictionsFacet__RestrictionNotFound(); + } + + address[] storage restrictions = restrictionsStorage.restrictions; + + uint256 indexToDelete = restrictions.length; + uint256 restrictionsLen = restrictions.length; + for (uint256 i; i < restrictionsLen; ) { + if (restrictions[i] == _restriction) { + indexToDelete = i; + break; + } + unchecked { + ++i; + } + } + + if (indexToDelete == 0 && restrictionsLen == 1) { + revert RestrictionsFacet__RemainingRestrictionsCantBeEmpty(); + } else if (indexToDelete == restrictionsLen) { + revert RestrictionsFacet__RestrictionNotFound(); + } else { + restrictions[indexToDelete] = restrictions[restrictionsLen - 1]; + restrictions.pop(); + } + + restrictionsStorage.exists[_restriction] = false; + emit RestrictionRemoved(_restriction); + } + + /** + * @notice Sets the restrictions address value mapping to true or false when adding/removing restriction contracts + * @param _restrictions List of restriction contracts address + * @param _newValue Bool value to flag to the list of restrictions contracts + */ + function _updateRestrictionsMap( + address[] memory _restrictions, + bool _newValue + ) internal { + RestrictionsStorage storage restrictionsStorage = LibFacetStorage + .restrictionsStorage(); + + uint restrictionsLen = _restrictions.length; + for (uint256 i; i < restrictionsLen; ) { + restrictionsStorage.exists[_restrictions[i]] = _newValue; + unchecked { + ++i; + } + } + } + + /** + * @dev Iterates over all restrictions and verifies each of them with the transaction parameters. + * @param _from The address of the sender, that will be signing the transaction. + * @param _to The receiving address. + * @param _value Amount of ETH to transfer from sender to recipient. + * @param _calldata Optional field to include arbitrary data. + * @return 0 if all the checks passed, 1 otherwise. + */ + function verifyRestrictions( + address _from, + address _to, + uint256 _value, + bytes calldata _calldata + ) external nonReentrant returns (uint256) { + RestrictionsStorage storage restrictionsStorage = LibFacetStorage + .restrictionsStorage(); + + uint restrictionsLen = restrictionsStorage.restrictions.length; + for (uint256 i; i < restrictionsLen; ) { + IRestriction restriction = IRestriction( + restrictionsStorage.restrictions[i] + ); + bool checkPassed = restriction.check(_from, _to, _value, _calldata); + if (!checkPassed) { + return 1; + } + unchecked { + ++i; + } + } + + return 0; + } +} diff --git a/contracts/facets/SignatureMigrationFacet.sol b/contracts/facets/SignatureMigrationFacet.sol new file mode 100644 index 0000000..0b79991 --- /dev/null +++ b/contracts/facets/SignatureMigrationFacet.sol @@ -0,0 +1,820 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.21; + +import {SignatureChecker} from "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol"; +import {LibAppStorage} from "../libraries/LibAppStorage.sol"; +import {LibFacetStorage, SignatureMigrationStorage, SignatureMigrationConfig, SignatureMigrationApprovalConfig, ApprovalConfig} from "../libraries/LibFacetStorage.sol"; +import {LibDiamond} from "../libraries/LibDiamond.sol"; +import {LibGuardian} from "../libraries/LibGuardian.sol"; +import {LibLoupe} from "../libraries/LibLoupe.sol"; +import {Modifiers} from "./Modifiers.sol"; +import {ISecurityManager} from "../infrastructure/interfaces/ISecurityManager.sol"; +import {IDiamondCut} from "./base/interfaces/IDiamondCut.sol"; +import {IVerificationFacet} from "./interfaces/IVerificationFacet.sol"; +import {ISignatureMigrationFacet} from "./interfaces/ISignatureMigrationFacet.sol"; + +/** + * @title Signature Migration Facet + * @dev Responsible for migrating user signature scheme to a new scheme user sets + * Which could include + * - ECDSA on Secp256K1 Curve + * - ECDSA on Secp256R1 Curve + * - BLS, Schnorr, etc + * @author David Yongjun Kim (@Powerstream3604) + */ +contract SignatureMigrationFacet is ISignatureMigrationFacet, Modifiers { + bytes constant UNINIT_CALL = + abi.encodeWithSignature("uninitializeSigner()"); + ISecurityManager public immutable securityManager; + + /** + * @notice This modifier verifies if the public key format matches with the new verification facet + * @param _publicKey Bytes of public key to be validated for the new verification facet + * @param _newVerificationFacet Address of new verification facet + */ + modifier validateKeyType( + bytes memory _publicKey, + address _newVerificationFacet + ) { + if ( + !IVerificationFacet(_newVerificationFacet).isValidKeyType( + _publicKey + ) + ) { + revert SignatureMigrationFacet__InvalidKeyType(); + } + _; + } + + /** + * @notice This constructor sets the Security Manager address which is an immutable variable. + * Immutable variables do not impact the storage of diamond + * @param _securityManager Security Manager contract that holds the security related variables for all wallets + */ + constructor(address _securityManager) { + securityManager = ISecurityManager(_securityManager); + } + + // IMPORTANT NOTE: In the client side when they call this function, the func selectors should be sorted in ascending order + // to prevent different hash with same items in the array + /** + * @notice Moves the state of migration to a pending state. When pending state is over after pending period time, + * Migration can be finalized. This function can only be called by self and when the account is unlocked. + * @dev This method checks if the caller is self and if guardians exists. It migrates signature request to a pending state + * @param _newVerificationFacet Verification facet that will replace the existing verification facet + * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one + * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond + */ + function migrateSignatureScheme( + address _newVerificationFacet, + bytes calldata _newPublicKey, + bytes4[] calldata _newVerificationFuncSelectors + ) + public + override + onlyWhenUnlocked + validateKeyType(_newPublicKey, _newVerificationFacet) + { + // Only self contract can call this function + LibDiamond.enforceIsSelf(); + // Should revert if guardian exist + if (0 != LibGuardian.guardianCount()) { + revert SignatureMigrationFacet__InvalidRouteWithGuardian(); + } + { + _checkMigrationCutValidity( + _newVerificationFacet, + _newVerificationFuncSelectors + ); + } + _migrateSignatureScheme( + _newVerificationFacet, + _newPublicKey, + _newVerificationFuncSelectors + ); + } + + // NOTE: Migration requires a pending period & confirmation from owner to prevent a + // single call changing the ownership of the wallet + /** + * @notice Migrate signature scheme when guardians exists. Verifies the signature of guardians and moves migration to pending state. + * Which can then be finalized when pending period is over. Owner's approval is mandatory for migration to happen + * @param _newVerificationFacet Verification facet that will replace the existing verification facet + * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one + * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond + * @param _approvers List of approvers. This could include owner + */ + function migrateSignatureSchemeWithGuardian( + address _newVerificationFacet, + bytes calldata _newPublicKey, + bytes4[] calldata _newVerificationFuncSelectors, + address[] calldata _approvers, + bytes[] calldata _signatures + ) + public + override + onlyWhenUnlocked + validateKeyType(_newPublicKey, _newVerificationFacet) + { + // Should revert if does not guardian exist + if (0 == LibGuardian.guardianCount()) { + revert SignatureMigrationFacet__InvalidRouteWithGuardian(); + } + if (_approvers.length != _signatures.length) { + revert SignatureMigrationFacet__InvalidArrayLength(); + } + + { + _checkMigrationCutValidity( + _newVerificationFacet, + _newVerificationFuncSelectors + ); + } + bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash( + _newPublicKey, + _newVerificationFacet, + _newVerificationFuncSelectors, + "MigrateSignature" + ); + + _checkApprover(_approvers); + _checkDuplicateOnChainApprover(migrationPublicKeyHash, _approvers); + + bool onChainOwnerApproval = getMigrationOwnerApprovalWithTimeValidity( + migrationPublicKeyHash + ); + uint256 threshold = onChainOwnerApproval ? 0 : 1; + + if ( + _approvers.length + + getMigrationApprovalCountWithTimeValidity( + migrationPublicKeyHash + ) < + LibGuardian.majorityOfGuardians() + threshold + ) { + revert SignatureMigrationFacet__InsufficientApprovers(); + } + { + // To prevent Stack too deep + bool ownerApproved; + for (uint256 i; i < _approvers.length; ) { + if ( + !LibGuardian.isGuardian(_approvers[i]) && + address(this) != _approvers[i] + ) { + revert SignatureMigrationFacet__InvalidGuardian(); + } + if (_approvers[i] == address(this)) { + if (onChainOwnerApproval) { + revert SignatureMigrationFacet__OwnerAlreadyApproved(); + } + ownerApproved = true; + } + if ( + !SignatureChecker.isValidSignatureNow( + _approvers[i], + migrationPublicKeyHash, + _signatures[i] + ) + ) { + revert SignatureMigrationFacet__InvalidApproverSignature(); + } + unchecked { + ++i; + } + } + + if (!ownerApproved && !onChainOwnerApproval) { + revert SignatureMigrationFacet__LackOfOwnerApproval(); + } + } + _migrateSignatureScheme( + _newVerificationFacet, + _newPublicKey, + _newVerificationFuncSelectors + ); + } + + /** + * @notice Internal function that moves signature mgiration to a pending state. + * @dev This method increments migration nonce and sets the migration in the migration config. Emits events for migration execution + * @param _newVerificationFacet Verification facet that will replace the existing verification facet + * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one + * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond + */ + function _migrateSignatureScheme( + address _newVerificationFacet, + bytes memory _newPublicKey, + bytes4[] memory _newVerificationFuncSelectors + ) internal { + SignatureMigrationStorage storage ms = LibFacetStorage + .migrationStorage(); + unchecked { + ++ms.nonce; + } + uint64 migrateAfter = uint64(block.timestamp + getMigrationPeriod()); + + ms.migrationConfigs[INNER_STRUCT] = SignatureMigrationConfig( + _newPublicKey, + _newVerificationFacet, + _newVerificationFuncSelectors, + migrateAfter + ); + + emit SignatureMigrationExecuted( + _newVerificationFacet, + _newPublicKey, + _newVerificationFuncSelectors, + migrateAfter + ); + } + + /** + * @notice Approves signature scheme migration on-chain. This can be called by owner or guardian only when the account is unlocked. + * When the threshold of the migration approval passed and owner approval is granted, it automatically moves migration to a pending state + * @param _newVerificationFacet Verification facet that will replace the existing verification facet + * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one + * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond + */ + function approveSignatureSchemeMigration( + address _newVerificationFacet, + bytes calldata _newPublicKey, + bytes4[] calldata _newVerificationFuncSelectors + ) + public + override + onlyGuardianOrOwner + onlyWhenUnlocked + validateKeyType(_newPublicKey, _newVerificationFacet) + { + { + _checkMigrationCutValidity( + _newVerificationFacet, + _newVerificationFuncSelectors + ); + } + + SignatureMigrationApprovalConfig storage ms = LibFacetStorage + .migrationStorage() + .migrationApprovalConfigs[INNER_STRUCT]; + bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash( + _newPublicKey, + _newVerificationFacet, + _newVerificationFuncSelectors, + "MigrateSignature" + ); + uint64 approvalValidUntil = uint64( + block.timestamp + getApprovalValidationPeriod() + ); + ms.isMigrationApproved[migrationPublicKeyHash][ + msg.sender + ] = ApprovalConfig(true, approvalValidUntil); + emit SignatureMigrationApproved( + _newPublicKey, + _newVerificationFacet, + _newVerificationFuncSelectors, + msg.sender, + approvalValidUntil + ); + if ( + getMigrationApprovalCountWithTimeValidity(migrationPublicKeyHash) >= + LibGuardian.majorityOfGuardians() && + getMigrationOwnerApprovalWithTimeValidity(migrationPublicKeyHash) + ) { + _migrateSignatureScheme( + _newVerificationFacet, + _newPublicKey, + _newVerificationFuncSelectors + ); + } + } + + /** + * @notice Revokes the approval of signature migration done on-chain. Emits revoke event when revoked. + * @param _newVerificationFacet Verification facet that will replace the existing verification facet + * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one + * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond + */ + function revokeSignatureMigrationApproval( + address _newVerificationFacet, + bytes calldata _newPublicKey, + bytes4[] calldata _newVerificationFuncSelectors + ) + external + override + onlyGuardianOrOwner + onlyWhenUnlocked + validateKeyType(_newPublicKey, _newVerificationFacet) + { + SignatureMigrationApprovalConfig storage ms = LibFacetStorage + .migrationStorage() + .migrationApprovalConfigs[INNER_STRUCT]; + bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash( + _newPublicKey, + _newVerificationFacet, + _newVerificationFuncSelectors, + "MigrateSignature" + ); + if (!isMigrationApproved(migrationPublicKeyHash, msg.sender)) { + revert SignatureMigrationFacet__CannotRevokeUnapproved(); + } + + ms.isMigrationApproved[migrationPublicKeyHash][ + msg.sender + ] = ApprovalConfig(false, 0); + emit SignatureMigrationApprovalRevoked( + _newPublicKey, + _newVerificationFacet, + _newVerificationFuncSelectors, + msg.sender + ); + } + + /** + * @notice Finalizes the pending signature scheme migration. This function can only be called by owner. + * It removes the facets of the previous verification facet and adds the new verification facet. + * After finalizing migration, it emits migration event which shows the change of the verification facet + */ + function finalizeSignatureMigration() external override { + // NOTE: Only owner can call this function + LibDiamond.enforceIsSelf(); + + SignatureMigrationStorage storage ms = LibFacetStorage + .migrationStorage(); + + if (!isMigrationPending()) { + revert SignatureMigrationFacet__NonexistentMigration(); + } + + if ( + uint64(block.timestamp) <= + ms.migrationConfigs[INNER_STRUCT].migrateAfter + ) { + revert SignatureMigrationFacet__MigrationPeriodNotOver(); + } + address newVerificationFacet = ms + .migrationConfigs[INNER_STRUCT] + .migrationVerificationFacet; + bytes4[] memory newVerificationFuncSelectors = ms + .migrationConfigs[INNER_STRUCT] + .migrationSelectors; + bytes memory newPublicKey = ms + .migrationConfigs[INNER_STRUCT] + .migrationPublicKey; + + address prevVerificationFacet = LibLoupe.facetAddress( + s.validateOwnerSignatureSelector + ); + if (prevVerificationFacet == address(0)) { + revert SignatureMigrationFacet__NonExistentVerificationFacet(); + } + + IDiamondCut.FacetCut[] memory UninitCut; + IDiamondCut.FacetCut[] memory InitCut; + { + bytes4[] memory prevVerificationFuncSelectors = LibLoupe + .facetFunctionSelectors(prevVerificationFacet); + + UninitCut = new IDiamondCut.FacetCut[](1); + InitCut = new IDiamondCut.FacetCut[](1); + UninitCut[0] = IDiamondCut.FacetCut({ + facetAddress: address(0), + action: IDiamondCut.FacetCutAction.Remove, + functionSelectors: prevVerificationFuncSelectors + }); + InitCut[0] = IDiamondCut.FacetCut({ + facetAddress: newVerificationFacet, + action: IDiamondCut.FacetCutAction.Add, + functionSelectors: newVerificationFuncSelectors + }); + { + IDiamondCut.FacetCut[] + memory facetCuts = new IDiamondCut.FacetCut[](2); + facetCuts[0] = UninitCut[0]; + facetCuts[1] = InitCut[0]; + _checkFacetCutValidity(facetCuts); + } + LibAppStorage.initiateSignerMigration(); + address verificationFacet = address( + bytes20( + LibDiamond.diamondStorage().facets[ + s.validateOwnerSignatureSelector + ] + ) + ); + + (bool uninitSuccess, bytes memory uninitResult) = verificationFacet + .delegatecall(UNINIT_CALL); + if (!uninitSuccess || uint256(bytes32(uninitResult)) != 1) { + revert SignatureMigrationFacet__SignerUninitializationFailure(); + } + LibAppStorage.finalizeSignerMigration(); + + LibDiamond.diamondCut(UninitCut, address(0), ""); + } + { + bytes memory initCall = abi.encodeWithSignature( + "initializeSigner(bytes)", + newPublicKey + ); + + // Every Verification Facet should comply with initializeSigner(bytes) + // to be compatible with the Barz contract(for initialization) + LibDiamond.diamondCut(InitCut, address(0), ""); + (bool initSuccess, bytes memory initResult) = newVerificationFacet + .delegatecall(initCall); + if (!initSuccess || uint256(bytes32(initResult)) != 1) { + revert SignatureMigrationFacet__SignerInitializationFailure(); + } + + emit SignatureSchemeMigration( + prevVerificationFacet, + newVerificationFacet, + newPublicKey, + newVerificationFuncSelectors + ); + } + } + + /** + * @notice Approve cancellation of signature migration. If cancellation approval passes guardian threshold with owner approval + * it automatically cancels the migration. + * @dev This method checks if the caller is one of guardian or owner and sets true for the cancellation hash in the approval config. + * It internally calls _cancelSignatureMigration for canceling the migration + * @param _newVerificationFacet Verification facet that will replace the existing verification facet + * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one + * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond + */ + function approveCancelSignatureMigration( + address _newVerificationFacet, + bytes calldata _newPublicKey, + bytes4[] calldata _newVerificationFuncSelectors + ) + external + override + onlyGuardianOrOwner + onlyWhenUnlocked + validateKeyType(_newPublicKey, _newVerificationFacet) + { + SignatureMigrationApprovalConfig storage ms = LibFacetStorage + .migrationStorage() + .migrationApprovalConfigs[INNER_STRUCT]; + bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash( + _newPublicKey, + _newVerificationFacet, + _newVerificationFuncSelectors, + "CancelSignatureMigration" + ); + uint64 approvalValidUntil = uint64( + block.timestamp + getApprovalValidationPeriod() + ); + ms.isMigrationApproved[migrationPublicKeyHash][ + msg.sender + ] = ApprovalConfig(true, approvalValidUntil); + emit SignatureMigrationCancellationApproved( + _newVerificationFacet, + _newPublicKey, + _newVerificationFuncSelectors + ); + if ( + getMigrationApprovalCountWithTimeValidity(migrationPublicKeyHash) >= + LibGuardian.majorityOfGuardians() && + getMigrationOwnerApprovalWithTimeValidity(migrationPublicKeyHash) + ) { + _cancelSignatureMigration( + _newVerificationFacet, + _newPublicKey, + _newVerificationFuncSelectors + ); + } + } + + /** + * @notice Verifies the signature of guardians/owner and cancels the signature migration. + * @param _newVerificationFacet Verification facet that will replace the existing verification facet + * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one + * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond + * @param _approvers List of approvers. This could include owner + */ + function cancelSignatureMigration( + address _newVerificationFacet, + bytes calldata _newPublicKey, + bytes4[] calldata _newVerificationFuncSelectors, + address[] calldata _approvers, + bytes[] calldata _signatures + ) + external + override + validateKeyType(_newPublicKey, _newVerificationFacet) + onlyWhenUnlocked + { + if (_approvers.length != _signatures.length) { + revert SignatureMigrationFacet__InvalidArrayLength(); + } + + bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash( + _newPublicKey, + _newVerificationFacet, + _newVerificationFuncSelectors, + "CancelSignatureMigration" + ); + + _checkApprover(_approvers); + _checkDuplicateOnChainApprover(migrationPublicKeyHash, _approvers); + + bool onChainOwnerApproval = getMigrationOwnerApprovalWithTimeValidity( + migrationPublicKeyHash + ); + uint256 threshold = onChainOwnerApproval ? 0 : 1; + if ( + _approvers.length + + getMigrationApprovalCountWithTimeValidity( + migrationPublicKeyHash + ) < + LibGuardian.majorityOfGuardians() + threshold + ) { + revert SignatureMigrationFacet__InsufficientApprovers(); + } + { + // To prevent stack too deep + bool ownerApproved; + for (uint256 i; i < _approvers.length; ) { + if ( + !LibGuardian.isGuardian(_approvers[i]) && + address(this) != _approvers[i] + ) { + revert SignatureMigrationFacet__NonExistentApprover(); + } + if (_approvers[i] == address(this)) { + if (onChainOwnerApproval) { + revert SignatureMigrationFacet__OwnerAlreadyApproved(); + } + ownerApproved = true; + } + if ( + !SignatureChecker.isValidSignatureNow( + _approvers[i], + migrationPublicKeyHash, + _signatures[i] + ) + ) { + revert SignatureMigrationFacet__InvalidApproverSignature(); + } + unchecked { + ++i; + } + } + if (!ownerApproved && !onChainOwnerApproval) { + revert SignatureMigrationFacet__LackOfOwnerApproval(); + } + } + _cancelSignatureMigration( + _newVerificationFacet, + _newPublicKey, + _newVerificationFuncSelectors + ); + } + + /** + * @notice Internal function that cancels signature migration. + * @dev This method increments migration nonce and deletes the migration from the migration config. Emits events for migration cancellation + * @param _newVerificationFacet Verification facet that will replace the existing verification facet + * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one + * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond + */ + function _cancelSignatureMigration( + address _newVerificationFacet, + bytes memory _newPublicKey, + bytes4[] memory _newVerificationFuncSelectors + ) internal { + if (!isMigrationPending()) + revert SignatureMigrationFacet__NonexistentMigration(); + SignatureMigrationStorage storage ms = LibFacetStorage + .migrationStorage(); + unchecked { + ++ms.nonce; + } + delete ms.migrationConfigs[INNER_STRUCT]; + emit SignatureMigrationCanceled( + _newVerificationFacet, + _newPublicKey, + _newVerificationFuncSelectors + ); + } + + /** + * @notice Checks if the facets to be added from new verification facet is registered to facet registry + * @param _newVerificationFacet Verification facet that will replace the existing verification facet + * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond + */ + function _checkMigrationCutValidity( + address _newVerificationFacet, + bytes4[] memory _newVerificationFuncSelectors + ) internal view { + IDiamondCut.FacetCut[] memory facetCuts = new IDiamondCut.FacetCut[](1); + facetCuts[0] = IDiamondCut.FacetCut({ + facetAddress: _newVerificationFacet, + action: IDiamondCut.FacetCutAction.Add, + functionSelectors: _newVerificationFuncSelectors + }); + _checkFacetCutValidity(facetCuts); + } + + /** + * @notice Returns if the migration is pending of not + * @dev This method fetches the migration storage and checks if the migrate after is above 0 value + * @return isPending Bool value that shows if the migration is pending + */ + function isMigrationPending() + public + view + override + returns (bool isPending) + { + SignatureMigrationStorage storage rs = LibFacetStorage + .migrationStorage(); + isPending = rs.migrationConfigs[INNER_STRUCT].migrateAfter > 0; + } + + /** + * @notice Returns the migration hash. This function ensures that this hash is safe from replay attack by including + * public key, verification facet, function selectors, salt, address, chainId, and nonce. + * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one + * @param _newVerificationFacet Verification facet that will replace the existing verification facet + * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond + * @param _saltString Salt value for generating the migration hash + * @return migrationKeyHash Bytes32 string of the migration key hash + */ + function getApprovalMigrationKeyHash( + bytes memory _newPublicKey, + address _newVerificationFacet, + bytes4[] memory _newVerificationFuncSelectors, + string memory _saltString + ) public view override returns (bytes32 migrationKeyHash) { + migrationKeyHash = keccak256( + abi.encodePacked( + "\x19Ethereum Signed Message:\n32", + keccak256( + abi.encode( + _newPublicKey, + _newVerificationFacet, + keccak256(abi.encode(_newVerificationFuncSelectors)), + _saltString, + address(this), + block.chainid, + LibFacetStorage.migrationStorage().nonce + ) + ) + ) + ); + } + + /** + * @notice Checks if the owner approved the hash for migration + * @param _migrationPublicKeyHash Hash of the public key and configuration for migration + * @return isApprovedByOwner Bool value of showing if the owner approved it or not + */ + function getMigrationOwnerApprovalWithTimeValidity( + bytes32 _migrationPublicKeyHash + ) public view override returns (bool isApprovedByOwner) { + isApprovedByOwner = isMigrationApproved( + _migrationPublicKeyHash, + address(this) + ); + } + + /** + * @notice Checks how many of the guardians approved the migration hash + * @param _migrationPublicKeyHash Hash of the public key and configuration for migration + * @return approvalCount Number of approvals + */ + function getMigrationApprovalCountWithTimeValidity( + bytes32 _migrationPublicKeyHash + ) public view override returns (uint256 approvalCount) { + address[] memory guardians = LibGuardian.getGuardians(); + uint256 guardiansLength = guardians.length; + for (uint256 i; i < guardiansLength; ) { + if (isMigrationApproved(_migrationPublicKeyHash, guardians[i])) { + unchecked { + ++approvalCount; + } + } + unchecked { + ++i; + } + } + return approvalCount; + } + + /** + * @notice Checks if the migration is approved by the given approver + * @param _migrationPublicKeyHash Hash of the public key and configuration for migration + * @param _approver Address of approver + * @return isApproved Bool value if migration hash is approved + */ + function isMigrationApproved( + bytes32 _migrationPublicKeyHash, + address _approver + ) public view override returns (bool isApproved) { + SignatureMigrationApprovalConfig storage ms = LibFacetStorage + .migrationStorage() + .migrationApprovalConfigs[INNER_STRUCT]; + isApproved = (ms + .isMigrationApproved[_migrationPublicKeyHash][_approver].isApproved && + block.timestamp < + ms + .isMigrationApproved[_migrationPublicKeyHash][_approver] + .validUntil); + } + + /** + * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval + * Approvers who approved on-chain should not be included in the off-chain approval + * @param _migrationPublicKeyHash Hash of migration information + * @param _approvers List of approver addresses + */ + function _checkDuplicateOnChainApprover( + bytes32 _migrationPublicKeyHash, + address[] memory _approvers + ) public view { + address[] memory guardians = LibGuardian.getGuardians(); + uint256 guardianLength = guardians.length; + uint256 approversLength = _approvers.length; + for (uint256 i; i < guardianLength; ) { + if (isMigrationApproved(_migrationPublicKeyHash, guardians[i])) { + for (uint256 j; j < approversLength; ) { + if (_approvers[j] == guardians[i]) + revert SignatureMigrationFacet__DuplicateApproval(); + unchecked { + ++j; + } + } + } + unchecked { + ++i; + } + } + } + + /** + * @notice Returns the migration period of this wallet + * @dev This method fetches the migration period from the security manager + * @return migrationPeriod Migration period of Barz contract fetched from security manager + */ + function getMigrationPeriod() + internal + view + returns (uint128 migrationPeriod) + { + migrationPeriod = securityManager.migrationPeriodOf(address(this)); + if (migrationPeriod == 0) + revert SignatureMigrationFacet__InvalidMigrationPeriod(); + } + + /** + * @notice Returns the validation period of this wallet + * @dev This method fetches the validation period from the security manager + * @return approvalValidationPeriod Validation period of Barz contract fetched from security manager + */ + function getApprovalValidationPeriod() + internal + view + returns (uint256 approvalValidationPeriod) + { + approvalValidationPeriod = securityManager.approvalValidationPeriodOf( + address(this) + ); + if (approvalValidationPeriod == 0) + revert SignatureMigrationFacet__InvalidApprovalValidationPeriod(); + } + + /** + * @notice Returns the migration nonce of this wallet + * @dev This method fetches the nonce from migration storage + * @return migrationNonce Nonce of migration to protect from reply attacks + */ + function getMigrationNonce() + public + view + override + returns (uint128 migrationNonce) + { + migrationNonce = LibFacetStorage.migrationStorage().nonce; + } + + /** + * @notice Returns the migration configuration of this wallet + * @dev This method fetches the migration config from the migration storage + * @return pendingMigrationConfig Migration config currently pending for signature migration + */ + function getPendingMigration() + external + view + override + returns (SignatureMigrationConfig memory pendingMigrationConfig) + { + pendingMigrationConfig = LibFacetStorage + .migrationStorage() + .migrationConfigs[INNER_STRUCT]; + } +} diff --git a/contracts/facets/TokenReceiverFacet.sol b/contracts/facets/TokenReceiverFacet.sol new file mode 100644 index 0000000..a078b46 --- /dev/null +++ b/contracts/facets/TokenReceiverFacet.sol @@ -0,0 +1,85 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.21; + +import {IERC721Receiver} from "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol"; +import {IERC777Recipient} from "@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol"; +import {IERC1155Receiver} from "../interfaces/ERC/IERC1155Receiver.sol"; +import {IERC677Receiver} from "../interfaces/ERC/IERC677Receiver.sol"; + +/** + * @title TokenReceiver Facet + * @dev Contract that enables receiving ERC721/ERC1155/ERC777/ERC677 Tokens with safe transfer + * @author David Yongjun Kim (@Powerstream3604) + */ +contract TokenReceiverFacet is + IERC721Receiver, + IERC1155Receiver, + IERC777Recipient, + IERC677Receiver +{ + /** + * @notice Handles ERC721 Token callback. + * return Standardized onERC721Received return value. + */ + function onERC721Received( + address, + address, + uint256, + bytes calldata + ) external pure override returns (bytes4) { + return IERC721Receiver.onERC721Received.selector; + } + + /** + * @notice Handles ERC1155 Token callback. + * return Standardized onERC1155Received return value. + */ + function onERC1155Received( + address, + address, + uint256, + uint256, + bytes calldata + ) external pure override returns (bytes4) { + return IERC1155Receiver.onERC1155Received.selector; + } + + /** + * @notice Handles ERC1155 Token batch callback. + * return Standardized onERC1155BatchReceived return value. + */ + function onERC1155BatchReceived( + address, + address, + uint256[] calldata, + uint256[] calldata, + bytes calldata + ) external pure override returns (bytes4) { + return IERC1155Receiver.onERC1155BatchReceived.selector; + } + + /** + * @notice Handles ERC777 Token callback. + * Does not return value, empty implementation. + */ + function tokensReceived( + address, + address, + address, + uint256, + bytes calldata, + bytes calldata + ) external pure override {} + + /** + * @notice Handles ERC677 Token callback. + * return true. + */ + function onTokenTransfer( + address, + uint256, + bytes calldata + ) external pure override returns (bool) { + return true; + } +} diff --git a/contracts/facets/base/DiamondCutFacet.sol b/contracts/facets/base/DiamondCutFacet.sol new file mode 100644 index 0000000..a8b6973 --- /dev/null +++ b/contracts/facets/base/DiamondCutFacet.sol @@ -0,0 +1,320 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.21; + +import {LibDiamond} from "../../libraries/LibDiamond.sol"; +import {LibGuardian} from "../../libraries/LibGuardian.sol"; +import {ISecurityManager} from "../../infrastructure/interfaces/ISecurityManager.sol"; +import {SignatureChecker} from "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol"; +import {LibFacetStorage, DiamondCutApprovalConfig, ApprovalConfig} from "../../libraries/LibFacetStorage.sol"; +import {Modifiers} from "../Modifiers.sol"; +import {IDiamondCut} from "./interfaces/IDiamondCut.sol"; + +/** + * @title DiamondCut Facet + * @dev Responsible for adding/removing/replace facets in Barz + * @author David Yongjun Kim (@Powerstream3604) + */ +contract DiamondCutFacet is Modifiers, IDiamondCut { + ISecurityManager public immutable securityManager; + + /** + * @notice This constructor sets the Security Manager address which is an immutable variable. + * Immutable variables do not impact the storage of diamond + * @param _securityManager Security Manager contract that holds the security related variables for all wallets + */ + constructor(address _securityManager) { + securityManager = ISecurityManager(_securityManager); + } + + /** + * @notice Updates the flag for the interfaceId + * @param _interfaceId InterfaceID to update the mapping + * @param _flag Bool value to update the mapping of the given interface ID + */ + function updateSupportsInterface( + bytes4 _interfaceId, + bool _flag + ) external override onlyWhenUnlocked { + LibDiamond.enforceIsSelf(); + LibDiamond.diamondStorage().supportedInterfaces[_interfaceId] = _flag; + emit SupportsInterfaceUpdated(_interfaceId, _flag); + } + + /** + * @notice Add/replace/remove any number of functions and optionally execute + * a function with delegatecall when guardians don't exist + * @param _diamondCut Contains the facet addresses and function selectors + * @param _init The address of the contract or facet to execute _calldata. It's prohibited in Barz + */ + function diamondCut( + FacetCut[] calldata _diamondCut, + address _init, + bytes calldata + ) external override onlyWhenUnlocked { + LibDiamond.enforceIsSelf(); + + _checkFacetCutValidity(_diamondCut); + // require approval from guardian if guardian exists + if (0 != LibGuardian.guardianCount()) + revert DiamondCutFacet__InvalidRouteWithGuardian(); + if (address(0) != _init) revert DiamondCutFacet__InvalidInitAddress(); + + unchecked { + ++LibFacetStorage.diamondCutStorage().nonce; + } + LibDiamond.diamondCut(_diamondCut, address(0), ""); + } + + /** + * @notice Add/replace/remove any number of functions and optionally execute + * a function with delegatecall when guardians exist + * @param _diamondCut Contains the facet addresses and function selectors + * @param _approvers Guardian or owner address that approves the diamond cut + * @param _signatures Signature of Guardians or owner that approves the diamond cut + */ + function diamondCutWithGuardian( + FacetCut[] calldata _diamondCut, + address[] calldata _approvers, + bytes[] calldata _signatures + ) external override onlyWhenUnlocked { + if (_approvers.length != _signatures.length) + revert DiamondCutFacet__InvalidArrayLength(); + _checkFacetCutValidity(_diamondCut); + if (0 == LibGuardian.guardianCount()) + revert DiamondCutFacet__InvalidRouteWithGuardian(); + + bytes32 cutHash = getDiamondCutHash(_diamondCut); + + _checkApprover(_approvers); + _checkDuplicateOnChainApprover(cutHash, _approvers); + + bool onChainOwnerApproval = getOwnerCutApprovalWithTimeValidity( + cutHash + ); + + uint256 threshold = onChainOwnerApproval ? 0 : 1; + if ( + _approvers.length + + getDiamondCutApprovalCountWithTimeValidity(cutHash) < + LibGuardian.majorityOfGuardians() + threshold + ) revert DiamondCutFacet__InsufficientApprovers(); + + bool ownerApproved; + for (uint256 i; i < _approvers.length; ) { + if ( + !LibGuardian.isGuardian(_approvers[i]) && + _approvers[i] != address(this) + ) revert DiamondCutFacet__InvalidApprover(); + if (_approvers[i] == address(this)) { + if (onChainOwnerApproval) + revert DiamondCutFacet__OwnerAlreadyApproved(); + ownerApproved = true; + } + if ( + !SignatureChecker.isValidSignatureNow( + _approvers[i], + cutHash, + _signatures[i] + ) + ) revert DiamondCutFacet__InvalidApproverSignature(); + unchecked { + ++i; + } + } + if (!ownerApproved && !onChainOwnerApproval) + revert DiamondCutFacet__LackOfOwnerApproval(); + + unchecked { + ++LibFacetStorage.diamondCutStorage().nonce; + } + LibDiamond.diamondCut(_diamondCut, address(0), ""); + } + + /** + * @notice Approves diamond cut. This can only be called directly from guardian or owner + * @param _diamondCut Contains the facet addresses and function selectors + */ + function approveDiamondCut( + FacetCut[] calldata _diamondCut + ) public override onlyGuardianOrOwner onlyWhenUnlocked { + if (LibGuardian.guardianCount() == 0) + revert DiamondCutFacet__InvalidRouteWithoutGuardian(); + DiamondCutApprovalConfig storage ds = LibFacetStorage + .diamondCutStorage() + .diamondCutApprovalConfigs[INNER_STRUCT]; + _checkFacetCutValidity(_diamondCut); + + bytes32 cutHash = getDiamondCutHash(_diamondCut); + uint64 approvalValidUntil = uint64( + block.timestamp + getApprovalValidationPeriod() + ); + ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig( + true, + approvalValidUntil + ); + emit DiamondCutApproved(_diamondCut); + if ( + (getDiamondCutApprovalCountWithTimeValidity(cutHash) >= + LibGuardian.majorityOfGuardians()) && + getOwnerCutApprovalWithTimeValidity(cutHash) + ) { + unchecked { + ++LibFacetStorage.diamondCutStorage().nonce; + } + LibDiamond.diamondCut(_diamondCut, address(0), ""); + } + } + + /** + * @notice Revokes the approval of diamond cut. This can only be called directly from guardian or owner + * @param _diamondCut Contains the facet addresses and function selectors + */ + function revokeDiamondCutApproval( + FacetCut[] calldata _diamondCut + ) public override onlyGuardianOrOwner onlyWhenUnlocked { + DiamondCutApprovalConfig storage ds = LibFacetStorage + .diamondCutStorage() + .diamondCutApprovalConfigs[INNER_STRUCT]; + bytes32 cutHash = getDiamondCutHash(_diamondCut); + if (!ds.isDiamondCutApproved[cutHash][msg.sender].isApproved) + revert DiamondCutFacet__CannotRevokeUnapproved(); + ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(false, 0); + emit DiamondCutApprovalRevoked(_diamondCut); + } + + /** + * @notice Gets the number of approvals of diamond cut from guardians + * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors + */ + function getDiamondCutApprovalCountWithTimeValidity( + bytes32 _diamondCutHash + ) public view override returns (uint256 approvalCount) { + address[] memory guardians = LibGuardian.getGuardians(); + uint256 guardiansLength = guardians.length; + for (uint256 i; i < guardiansLength; ) { + if (isCutApproved(_diamondCutHash, guardians[i])) { + unchecked { + ++approvalCount; + } + } + unchecked { + ++i; + } + } + return approvalCount; + } + + /** + * @notice Returns if the owner has approved the diamond cut + * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors + * @return isApprovedByOwner Bool value showing if the owner approved the cut + */ + function getOwnerCutApprovalWithTimeValidity( + bytes32 _diamondCutHash + ) public view override returns (bool isApprovedByOwner) { + isApprovedByOwner = isCutApproved(_diamondCutHash, address(this)); + } + + /** + * @notice Returns if the given approver has approved the diamond cut + * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors + * @param _approver Address of approver + * @return isApproved Bool value showing if the approver approved the cut + */ + function isCutApproved( + bytes32 _diamondCutHash, + address _approver + ) public view override returns (bool isApproved) { + DiamondCutApprovalConfig storage ds = LibFacetStorage + .diamondCutStorage() + .diamondCutApprovalConfigs[INNER_STRUCT]; + isApproved = (ds + .isDiamondCutApproved[_diamondCutHash][_approver].isApproved && + block.timestamp < + ds.isDiamondCutApproved[_diamondCutHash][_approver].validUntil); + } + + /** + * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval + * Approvers who approved on-chain should not be included in the off-chain approval + * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors + * @param _approvers List of approver addresses + */ + function _checkDuplicateOnChainApprover( + bytes32 _diamondCutHash, + address[] memory _approvers + ) public view { + address[] memory guardians = LibGuardian.getGuardians(); + uint256 guardianLength = guardians.length; + uint256 approversLength = _approvers.length; + for (uint256 i; i < guardianLength; ) { + if (isCutApproved(_diamondCutHash, guardians[i])) { + for (uint256 j; j < approversLength; ) { + if (_approvers[j] == guardians[i]) + revert DiamondCutFacet__DuplicateApproval(); + unchecked { + ++j; + } + } + } + unchecked { + ++i; + } + } + } + + /** + * @notice Returns the diamond cut hash. This function ensures that this hash is safe from replay attack by including + * salt, address, chainId, and nonce, etc. + * @param _diamondCut Contains the facet addresses and function selectors + * @return cutHash Diamond Cut Hash + */ + function getDiamondCutHash( + FacetCut[] calldata _diamondCut + ) public view override returns (bytes32 cutHash) { + cutHash = keccak256( + abi.encodePacked( + "\x19Ethereum Signed Message:\n32", + keccak256( + abi.encode( + keccak256(abi.encode(_diamondCut)), + address(this), + block.chainid, + LibFacetStorage.diamondCutStorage().nonce + ) + ) + ) + ); + } + + /** + * @notice Returns the approval validation Period + * @dev This method fetches the validation period from the security manager + * @return approvalValidationPeriod Approval validation period of Barz contract fetched from security manager + */ + function getApprovalValidationPeriod() + internal + view + returns (uint256 approvalValidationPeriod) + { + approvalValidationPeriod = securityManager.approvalValidationPeriodOf( + address(this) + ); + if (approvalValidationPeriod <= 0) + revert DiamondCutFacet__InvalidApprovalValidationPeriod(); + } + + /** + * @notice Returns the diamond cut nonce of this wallet + * @dev This method fetches the nonce from diamond cut storage + * @return cutNonce Nonce of diamond cut to protect from reply attacks + */ + function getDiamondCutNonce() + public + view + override + returns (uint128 cutNonce) + { + cutNonce = LibFacetStorage.diamondCutStorage().nonce; + } +} diff --git a/contracts/facets/base/DiamondLoupeFacet.sol b/contracts/facets/base/DiamondLoupeFacet.sol new file mode 100644 index 0000000..ec8072d --- /dev/null +++ b/contracts/facets/base/DiamondLoupeFacet.sol @@ -0,0 +1,284 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.21; + +import {IERC777Recipient} from "@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol"; +import {IERC165} from "../../interfaces/ERC/IERC165.sol"; +import {IERC1271} from "../../interfaces/ERC/IERC1271.sol"; +import {IERC677Receiver} from "../../interfaces/ERC/IERC677Receiver.sol"; +import {IERC721Receiver} from "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol"; +import {IERC1155Receiver} from "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol"; +import {LibDiamond} from "../../libraries/LibDiamond.sol"; +import {LibLoupe} from "../../libraries/LibLoupe.sol"; +import {LibUtils} from "../../libraries/LibUtils.sol"; +import {IDiamondCut} from "../../facets/base/interfaces/IDiamondCut.sol"; +import {IStorageLoupe} from "./interfaces/IStorageLoupe.sol"; +import {IDiamondLoupe} from "./interfaces/IDiamondLoupe.sol"; + +/** + * @title DiamondLoupe Facet + * @dev DiamondLoupe contract compatible with EIP-2535 + * @author David Yongjun Kim (@Powerstream3604) + */ +contract DiamondLoupeFacet is IDiamondLoupe, IStorageLoupe, IERC165 { + // Diamond Loupe Functions + //////////////////////////////////////////////////////////////////// + /// These functions are expected to be called frequently by tools off-chain. + + /** + * @notice Gets all facets and their selectors. + * @dev Barz uses a special architecture called default fallback handler. Default Fallback handler is used as a middleware + * that holds the mapping of facet function selector and facet address that Barz uses. This helps Barz to reduce + * significant amount of gas during the initialization process. + * Hence, this method aggregates both the facet information from DefaulFallbackHandler and in diamond storage and shows the data to users. + * @return facets_ Facet + */ + function facets() public view override returns (Facet[] memory facets_) { + Facet[] memory defaultFacet = LibDiamond + .diamondStorage() + .defaultFallbackHandler + .facets(); + Facet[] memory _facets = LibLoupe.facets(); + uint256 numFacets = _facets.length; + bytes4[] memory keys; + address[] memory values; + for (uint256 i; i < numFacets; ) { + uint256 selectorsLength = _facets[i].functionSelectors.length; + for (uint256 j; j < selectorsLength; ) { + (keys, values) = LibUtils.setValue( + keys, + values, + _facets[i].functionSelectors[j], + _facets[i].facetAddress + ); + unchecked { + ++j; + } + } + unchecked { + ++i; + } + } + { + bool iIncrement; + for (uint256 i; i < defaultFacet.length; ) { + bool jIncrement; + for ( + uint256 j; + j < defaultFacet[i].functionSelectors.length; + + ) { + if ( + LibUtils.getValue( + keys, + values, + defaultFacet[i].functionSelectors[j] + ) != address(0) + ) { + if (defaultFacet[i].functionSelectors.length == 1) { + defaultFacet = LibUtils.removeFacetElement( + defaultFacet, + i + ); + iIncrement = true; + break; + } + defaultFacet[i].functionSelectors = LibUtils + .removeElement( + defaultFacet[i].functionSelectors, + j + ); + jIncrement = true; + } + if (!jIncrement) { + unchecked { + ++j; + } + } else { + jIncrement = false; + } + } + if (!iIncrement) { + unchecked { + ++i; + } + } else { + iIncrement = false; + } + } + } + { + uint256 facetLength = numFacets + defaultFacet.length; + facets_ = new Facet[](facetLength); + uint256 defaultFacetIndex; + for (uint256 i; i < facetLength; ) { + if (i < numFacets) { + facets_[i] = _facets[i]; + bool jIncrementor; + for (uint256 j; j < defaultFacet.length; ) { + if ( + facets_[i].facetAddress == + defaultFacet[j].facetAddress + ) { + facets_[i].functionSelectors = LibUtils.mergeArrays( + _facets[i].functionSelectors, + defaultFacet[j].functionSelectors + ); + defaultFacet = LibUtils.removeFacetElement( + defaultFacet, + j + ); + jIncrementor = true; + { + facets_ = LibUtils.removeFacetElement( + facets_, + facets_.length - 1 + ); + } + --facetLength; + } + if (!jIncrementor) { + unchecked { + ++j; + } + } else { + jIncrementor = false; + } + } + } else { + facets_[i] = defaultFacet[defaultFacetIndex]; + ++defaultFacetIndex; + } + unchecked { + ++i; + } + } + } + } + + /** + * @notice Gets all the function selectors provided by a facet. + * @param _facet The facet address. + * @return facetFunctionSelectors_ + */ + function facetFunctionSelectors( + address _facet + ) external view override returns (bytes4[] memory facetFunctionSelectors_) { + Facet[] memory facet = facets(); + uint256 facetLength = facet.length; + for (uint256 i; i < facetLength; ) { + if (facet[i].facetAddress == _facet) + return facet[i].functionSelectors; + unchecked { + ++i; + } + } + return facetFunctionSelectors_; + } + + /** + * @notice Get all the facet addresses used by Barz. + * @return facetAddresses_ + */ + function facetAddresses() + external + view + override + returns (address[] memory facetAddresses_) + { + Facet[] memory facet = facets(); + uint256 facetLength = facet.length; + facetAddresses_ = new address[](facetLength); + for (uint256 i; i < facetLength; ) { + facetAddresses_[i] = facet[i].facetAddress; + unchecked { + ++i; + } + } + } + + /** + * @notice Gets the facet that supports the given selector. + * @dev If facet is not found return address(0). + * @param _functionSelector The function selector. + * @return facetAddress_ The facet address. + */ + function facetAddress( + bytes4 _functionSelector + ) external view override returns (address facetAddress_) { + LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage(); + + facetAddress_ = address(bytes20(ds.facets[_functionSelector])); + if (facetAddress_ == address(0)) { + facetAddress_ = IDiamondLoupe(ds.defaultFallbackHandler) + .facetAddress(_functionSelector); + } + } + + /** + * @notice SupportInterface to be compatible with EIP 165 + * @param _interfaceId Interface ID for detecting the interface + * @return isSupported Bool value showing if the standard is supported in the contract + */ + function supportsInterface( + bytes4 _interfaceId + ) external view override returns (bool isSupported) { + isSupported = + _interfaceId == type(IERC165).interfaceId || + _interfaceId == IDiamondCut.diamondCut.selector || + _interfaceId == type(IDiamondLoupe).interfaceId || + _interfaceId == type(IERC1155Receiver).interfaceId || + _interfaceId == type(IERC721Receiver).interfaceId || + _interfaceId == type(IERC777Recipient).interfaceId || + _interfaceId == IERC1271.isValidSignature.selector || + _interfaceId == type(IERC677Receiver).interfaceId || + LibDiamond.diamondStorage().supportedInterfaces[_interfaceId]; + } + + /** + * @notice Returns the facet from the diamond storage. This excludes the facets from the default fallback handler + * @return facets_ Facet information attached directly to diamond storage + */ + function facetsFromStorage() + external + view + override + returns (Facet[] memory facets_) + { + facets_ = LibLoupe.facets(); + } + + /** + * @notice Returns the facet address attached to the given function selector. This excludes the facets from the default fallback handler + * @param _functionSelector Function selector to fetch the facet address from diamond storage + * @return facetAddress_ Facet address mapped with the function selector + */ + function facetAddressFromStorage( + bytes4 _functionSelector + ) external view override returns (address facetAddress_) { + facetAddress_ = LibLoupe.facetAddress(_functionSelector); + } + + /** + * @notice Returns all facet addresses attached directly to diamond storage. This excludes the facets from the default fallback handler + * @return facetAddresses_ All facet addresses attached directly to diamond storage + */ + function facetAddressesFromStorage() + external + view + override + returns (address[] memory facetAddresses_) + { + facetAddresses_ = LibLoupe.facetAddresses(); + } + + /** + * @notice Returns function selectors of given facet address attached directly to diamond storage. This excludes the facets from the default fallback handler + * @param _facet Facet address to fetch the facet function selectors from diamond storage + * @return facetFunctionSelectors_ Facet function selectors of the given facet address + */ + function facetFunctionSelectorsFromStorage( + address _facet + ) external view override returns (bytes4[] memory facetFunctionSelectors_) { + facetFunctionSelectors_ = LibLoupe.facetFunctionSelectors(_facet); + } +} diff --git a/contracts/facets/base/interfaces/IDiamondCut.sol b/contracts/facets/base/interfaces/IDiamondCut.sol new file mode 100644 index 0000000..8354527 --- /dev/null +++ b/contracts/facets/base/interfaces/IDiamondCut.sol @@ -0,0 +1,83 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.21; + +/** + * @title DiamondCut Facet Interface + * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz + * @author David Yongjun Kim (@Powerstream3604) + */ +interface IDiamondCut { + error DiamondCutFacet__InvalidRouteWithGuardian(); + error DiamondCutFacet__InvalidRouteWithoutGuardian(); + error DiamondCutFacet__InvalidArrayLength(); + error DiamondCutFacet__InsufficientApprovers(); + error DiamondCutFacet__InvalidApprover(); + error DiamondCutFacet__InvalidApproverSignature(); + error DiamondCutFacet__InvalidApprovalValidationPeriod(); + error DiamondCutFacet__CannotRevokeUnapproved(); + error DiamondCutFacet__LackOfOwnerApproval(); + error DiamondCutFacet__OwnerAlreadyApproved(); + error DiamondCutFacet__DuplicateApproval(); + error DiamondCutFacet__InvalidInitAddress(); + + event DiamondCutApproved(FacetCut[] diamondCut); + event DiamondCutApprovalRevoked(FacetCut[] diamondCut); + + event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag); + + enum FacetCutAction { + Add, + Replace, + Remove + } + // Add=0, Replace=1, Remove=2 + + struct FacetCut { + address facetAddress; + FacetCutAction action; + bytes4[] functionSelectors; + } + + /// @notice Add/replace/remove any number of functions and optionally execute + /// a function with delegatecall + /// @param diamondCut Contains the facet addresses and function selectors + /// @param init The address of the contract or facet to execute _calldata + /// @param _calldata A function call, including function selector and arguments + /// _calldata is executed with delegatecall on _init + function diamondCut( + FacetCut[] calldata diamondCut, + address init, + bytes calldata _calldata + ) external; + + function updateSupportsInterface(bytes4 interfaceId, bool flag) external; + + function diamondCutWithGuardian( + FacetCut[] calldata diamondCut, + address[] calldata approvers, + bytes[] calldata signatures + ) external; + + function approveDiamondCut(FacetCut[] calldata diamondCut) external; + + function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external; + + function getDiamondCutApprovalCountWithTimeValidity( + bytes32 diamondCutHash + ) external view returns (uint256); + + function getOwnerCutApprovalWithTimeValidity( + bytes32 diamondCutHash + ) external view returns (bool); + + function isCutApproved( + bytes32 diamondCutHash, + address approver + ) external view returns (bool); + + function getDiamondCutHash( + FacetCut[] calldata diamondCut + ) external view returns (bytes32); + + function getDiamondCutNonce() external view returns (uint128); +} diff --git a/contracts/facets/base/interfaces/IDiamondLoupe.sol b/contracts/facets/base/interfaces/IDiamondLoupe.sol new file mode 100644 index 0000000..e2d3e77 --- /dev/null +++ b/contracts/facets/base/interfaces/IDiamondLoupe.sol @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.21; + +// A loupe is a small magnifying glass used to look at diamonds. +// These functions look at diamonds +interface IDiamondLoupe { + /// These functions are expected to be called frequently + /// by tools. + + struct Facet { + address facetAddress; + bytes4[] functionSelectors; + } + + /// @notice Gets all facet addresses and their four byte function selectors. + /// @return facets_ Facet + function facets() external view returns (Facet[] memory facets_); + + /// @notice Gets all the function selectors supported by a specific facet. + /// @param _facet The facet address. + /// @return facetFunctionSelectors_ + function facetFunctionSelectors( + address _facet + ) external view returns (bytes4[] memory facetFunctionSelectors_); + + /// @notice Get all the facet addresses used by a diamond. + /// @return facetAddresses_ + function facetAddresses() + external + view + returns (address[] memory facetAddresses_); + + /// @notice Gets the facet that supports the given selector. + /// @dev If facet is not found return address(0). + /// @param _functionSelector The function selector. + /// @return facetAddress_ The facet address. + function facetAddress( + bytes4 _functionSelector + ) external view returns (address facetAddress_); +} diff --git a/contracts/facets/base/interfaces/IStorageLoupe.sol b/contracts/facets/base/interfaces/IStorageLoupe.sol new file mode 100644 index 0000000..226a821 --- /dev/null +++ b/contracts/facets/base/interfaces/IStorageLoupe.sol @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.21; + +import {IDiamondLoupe} from "./IDiamondLoupe.sol"; + +/** + * @title LoupeFromStorage Interface + * @dev Interface contract to function as a loupe facet directly attached to diamond storage of Barz + * @author David Yongjun Kim (@Powerstream3604) + */ +interface IStorageLoupe { + /// These functions are expected to be called frequently + /// by tools. + + /// @notice Gets all facet addresses and their four byte function selectors. + /// @return facets_ Facet + function facetsFromStorage() + external + view + returns (IDiamondLoupe.Facet[] memory); + + /// @notice Gets all the function selectors supported by a specific facet. + /// @param _facet The facet address. + function facetFunctionSelectorsFromStorage( + address _facet + ) external view returns (bytes4[] memory); + + /// @notice Get all the facet addresses used by a diamond. + function facetAddressesFromStorage() + external + view + returns (address[] memory); + + /// @notice Gets the facet that supports the given selector. + /// @dev If facet is not found return address(0). + /// @param _functionSelector The function selector. + function facetAddressFromStorage( + bytes4 _functionSelector + ) external view returns (address); +} diff --git a/contracts/facets/interfaces/IAccountFacet.sol b/contracts/facets/interfaces/IAccountFacet.sol new file mode 100644 index 0000000..652b679 --- /dev/null +++ b/contracts/facets/interfaces/IAccountFacet.sol @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.21; + +import {IEntryPoint} from "../../aa-4337/interfaces/IEntryPoint.sol"; + +/** + * @title Account Facet Interface + * @dev Interface of module contract that provides the account features and init/unitialization of signer + * compatible with EIP-1271 & EIP-4337 + * @author David Yongjun Kim (@Powerstream3604) + */ +interface IAccountFacet { + event AccountInitialized( + IEntryPoint indexed entryPoint, + bytes indexed ownerPublicKey + ); + // NOTE: Added Below Event + event VerificationSuccess(bytes32); + event VerificationFailure(bytes32); + + error AccountFacet__InitializationFailure(); + error AccountFacet__RestrictionsFailure(); + error AccountFacet__NonExistentVerificationFacet(); + error AccountFacet__CallNotSuccessful(); + error AccountFacet__InvalidArrayLength(); + + function initialize( + address verificationFacet, + address anEntryPoint, + address facetRegistry, + address _defaultFallBack, + bytes calldata _ownerPublicKey + ) external returns (uint256); + + function execute(address dest, uint256 value, bytes calldata func) external; + + function executeBatch( + address[] calldata dest, + uint256[] calldata value, + bytes[] calldata func + ) external; +} diff --git a/contracts/facets/interfaces/IAccountRecoveryFacet.sol b/contracts/facets/interfaces/IAccountRecoveryFacet.sol new file mode 100644 index 0000000..60804e9 --- /dev/null +++ b/contracts/facets/interfaces/IAccountRecoveryFacet.sol @@ -0,0 +1,95 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.21; + +import {RecoveryConfig} from "../../libraries/LibFacetStorage.sol"; + +/** + * @title Account Recovery Facet Interface + * @dev Interface of contract that enables recovery of accounts when owner key is unavailable + * @author David Yongjun Kim (@Powerstream3604) + */ +interface IAccountRecoveryFacet { + event RecoveryExecuted( + bytes indexed recoveryPublicKey, + uint64 executeAfter + ); + event RecoveryFinalized(bytes indexed recoveryPublicKey); + event RecoveryCanceled(bytes indexed recoveryPublicKey); + event RecoveryApproved( + bytes indexed recoveryPublicKey, + address indexed guardian, + uint64 validUntil + ); + event RecoveryApprovalRevoked( + bytes indexed recoveryPublicKey, + address indexed guardian + ); + event RecoveryCancellationApproved( + bytes indexed recoveryPublicKey, + address indexed guardian + ); + event RecoveryHardstopped(); + + error AccountRecoveryFacet__CallerNotGuardian(); + error AccountRecoveryFacet__InvalidRecoveryPublicKey(); + error AccountRecoveryFacet__SignerInitializationFailure(); + error AccountRecoveryFacet__SignerUninitializationFailure(); + error AccountRecoveryFacet__InvalidArrayLength(); + error AccountRecoveryFacet__InsufficientGuardians(); + error AccountRecoveryFacet__RecoveryAlreadyOngoing(); + error AccountRecoveryFacet__NonexistentRecovery(); + error AccountRecoveryFacet__NonExistentApproval(); + error AccountRecoveryFacet__RecoveryPeriodNotOver(); + error AccountRecoveryFacet__InvalidLockPeriod(); + error AccountRecoveryFacet__InvalidRecoveryPeriod(); + error AccountRecoveryFacet__InvalidApprovalValidationPeriod(); + error AccountRecoveryFacet__InvalidGuardian(); + error AccountRecoveryFacet__InvalidGuardianSignature(); + error AccountRecoveryFacet__InvalidOwnerSignature(); + error AccountRecoveryFacet__CallNotSuccesful(); + error AccountRecoveryFacet__DuplicateApproval(); + + function approveAccountRecovery(bytes calldata recoveryPublicKey) external; + + function revokeAccountRecoveryApproval( + bytes calldata recoveryPublicKey + ) external; + + function executeRecovery( + bytes calldata recoveryPublicKey, + address[] calldata guardians, + bytes[] calldata signatures + ) external; + + function finalizeRecovery() external; + + function approveCancelRecovery(bytes calldata recoveryPublicKey) external; + + function cancelRecovery( + bytes calldata recoveryPublicKey, + address[] calldata guardians, + bytes[] calldata signatures + ) external; + + function hardstopRecovery(bytes calldata signature) external; + + function validateNewOwner(bytes calldata recoveryPublicKey) external view; + + function getApprovalRecoveryKeyHash( + bytes memory recoveryPublicKey, + string memory saltString + ) external view returns (bytes32); + + function getRecoveryApprovalCountWithTimeValidity( + bytes32 recoveryPublicKeyHash + ) external view returns (uint256); + + function isRecoveryApproved( + bytes32 recoveryPublicKeyHash, + address approver + ) external view returns (bool); + + function getRecoveryNonce() external view returns (uint128); + + function getPendingRecovery() external view returns (RecoveryConfig memory); +} diff --git a/contracts/facets/interfaces/IGuardianFacet.sol b/contracts/facets/interfaces/IGuardianFacet.sol new file mode 100644 index 0000000..9691082 --- /dev/null +++ b/contracts/facets/interfaces/IGuardianFacet.sol @@ -0,0 +1,81 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.21; + +/** + * @title Guardian Facet Interface + * @dev Interface of guaridna contract that enables addition/removal of guardians from Barz + * @author David Yongjun Kim (@Powerstream3604) + */ +interface IGuardianFacet { + event GuardianAdditionRequested( + address indexed guardian, + uint256 executeAfter + ); + event GuardianRemovalRequested( + address indexed guardian, + uint256 executeAfter + ); + event GuardianAdditionCancelled(address indexed guardian); + event GuardianRemovalCancelled(address indexed guardian); + event GuardianAdded(address indexed guardian); + event GuardianRemoved(address indexed guardian); + + error GuardianFacet__GuardianCannotBeSelf(); + error GuardianFacet__DuplicateGuardian(); + error GuardianFacet__OwnerCannotBeGuardian(); + error GuardianFacet__DuplicateGuardianAddition(); + error GuardianFacet__DuplicateGuardianRemoval(); + error GuardianFacet__UnknownPendingAddition(); + error GuardianFacet__PendingAdditionNotOver(); + error GuardianFacet__UnknownPendingRemoval(); + error GuardianFacet__PendingRemovalNotOver(); + error GuardianFacet__PendingAdditionExpired(); + error GuardianFacet__InvalidAdditionSecurityPeriod(); + error GuardianFacet__InvalidRemovalSecurityPeriod(); + error GuardianFacet__InvalidSecurityWindow(); + error GuardianFacet__NonExistentGuardian(); + error GuardianFacet__AlreadyExists(); + error GuardianFacet__InvalidGuardianAddition(); + error GuardianFacet__InvalidGuardianRemoval(); + error GuardianFacet__ZeroAddressGuardian(); + + function addGuardian(address guardian) external; + + function addGuardians(address[] calldata guardians) external; + + function removeGuardian(address guardian) external; + + function removeGuardians(address[] calldata guardians) external; + + function confirmGuardianAddition(address guardian) external; + + function confirmGuardianAdditions(address[] calldata guardian) external; + + function confirmGuardianRemoval(address guardian) external; + + function confirmGuardianRemovals(address[] calldata guardian) external; + + function cancelGuardianAddition(address guardian) external; + + function cancelGuardianRemoval(address guardian) external; + + function isGuardian(address guardian) external view returns (bool); + + function isAdditionPending(address guardian) external view returns (bool); + + function isRemovalPending(address guardian) external view returns (bool); + + function isGuardianFacetRemovable() external view returns (bool); + + function getAdditionSecurityPeriod() external view returns (uint256); + + function getRemovalSecurityPeriod() external view returns (uint256); + + function getSecurityWindow() external view returns (uint256); + + function getGuardians() external view returns (address[] memory); + + function majorityOfGuardians() external view returns (uint256); + + function guardianCount() external view returns (uint256); +} diff --git a/contracts/facets/interfaces/ILockFacet.sol b/contracts/facets/interfaces/ILockFacet.sol new file mode 100644 index 0000000..14164a6 --- /dev/null +++ b/contracts/facets/interfaces/ILockFacet.sol @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.21; + +import {Lock} from "../../libraries/LibAppStorage.sol"; + +/** + * @title Lock Facet Interface + * @dev Interface of Lock contract that enables full lock/unlock of Barz + * @author David Yongjun Kim (@Powerstream3604) + */ +interface ILockFacet { + event Locked(uint64 releaseAfter); + event Unlocked(); + + error LockFacet__InvalidRecoveryPeriod(); + error LockFacet__CannotUnlock(); + error LockFacet__InvalidSignature(); + error LockFacet__InvalidApprover(); + + function lock() external; + + function unlock(address approver, bytes calldata signature) external; + + function getLockPeriod() external view returns (uint256); + + function isLocked() external view returns (bool); + + function getUnlockHash() external view returns (bytes32); + + function lockNonce() external view returns (uint128); + + function getPendingLock() external view returns (Lock memory); +} diff --git a/contracts/facets/interfaces/IMultiSigFacet.sol b/contracts/facets/interfaces/IMultiSigFacet.sol new file mode 100644 index 0000000..f2b170d --- /dev/null +++ b/contracts/facets/interfaces/IMultiSigFacet.sol @@ -0,0 +1,70 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.21; + +/** + * @title Multi-sig facet Interface + * @dev Interface of Multi-signature Facet with custom threshold. + Wallet that adds this facet becomes a multi-sig wallet + * @author David Yongjun Kim (@Powerstream3604) + */ +interface IMultiSigFacet { + event ThresholdChanged(uint256 threshold); + event OwnerAdded(address indexed newOwner); + event OwnerRemoved(address indexed prevOwner); + event HashApproved(bytes32 hashToApprove, address indexed owner); + + error MultiSigFacet__InvalidThreshold(); + error MultisigFacet__InvalidOwnerCount(); + error MultiSigFacet__InvalidRoute(); + error MultiSigFacet__InsufficientSignerLength(); + error MultiSigFacet__InvalidInitData(); + error MultiSigFacet__InvalidOwnerAddress(); + error MultiSigFacet__InvalidOwnerPair(); + error MultiSigFacet__InvalidSignatureLength(); + error MultiSigFacet__InvalidSignatureType(); + error MultiSigFacet__DuplicateOwner(); + error MultiSigFacet__OnlyOwner(); + + function checkSignatures( + bytes32 _dataHash, + bytes calldata _signatures, + uint256 _threshold + ) external view returns (uint256); + + function splitSignatures( + bytes calldata _signatures, + uint256 _nextOffset + ) + external + pure + returns ( + address owner, + bytes memory signature, + uint256 signatureType, + uint256 nextOffset + ); + + function approveHash(bytes32 hashToApprove) external; + + function addOwner(address newOwner, uint256 threshold) external; + + function removeOwner( + address prevOwner, + address removedOwner, + uint256 threshold + ) external; + + function swapOwner( + address prevOwner, + address oldOwner, + address newOwner + ) external; + + function changeThreshold(uint256 _threshold) external; + + function isOwner(address owner) external view returns (bool); + + function getThreshold() external view returns (uint256); + + function getOwners() external view returns (address[] memory); +} diff --git a/contracts/facets/interfaces/IRestrictionsFacet.sol b/contracts/facets/interfaces/IRestrictionsFacet.sol new file mode 100644 index 0000000..a941089 --- /dev/null +++ b/contracts/facets/interfaces/IRestrictionsFacet.sol @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.21; + +/** + * @title Restrictions Facet Interface + * @dev Interface of Restrictions contract that enables modular restrictions in Barz + * @author Ruslan Serebriakov (@rsrbk) + * @author David Yongjun Kim (@Powerstream3604) + */ +interface IRestrictionsFacet { + event RestrictionAdded(address indexed restriction); + event RestrictionRemoved(address indexed restriction); + + error RestrictionsFacet__EmptyRestrictionsList(); + error RestrictionsFacet__RestrictionNotFound(); + error RestrictionsFacet__RestrictionAlreadyExists(); + error RestrictionsFacet__ZeroAddressRestrictions(); + error RestrictionsFacet__ZeroAddressRestrictionsFacet(); + error RestrictionsFacet__RemainingRestrictionsCantBeEmpty(); + + function initializeRestrictions( + address[] memory _restrictions + ) external returns (uint256); + + function uninitializeRestrictions() external returns (uint256); + + function getRestrictions() external view returns (address[] memory); + + function addRestriction(address restriction) external; + + function removeRestriction(address restriction) external; + + function verifyRestrictions( + address from, + address to, + uint256 value, + bytes calldata _calldata + ) external returns (uint256); +} diff --git a/contracts/facets/interfaces/ISignatureMigrationFacet.sol b/contracts/facets/interfaces/ISignatureMigrationFacet.sol new file mode 100644 index 0000000..6d065b6 --- /dev/null +++ b/contracts/facets/interfaces/ISignatureMigrationFacet.sol @@ -0,0 +1,141 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.21; + +import {SignatureMigrationConfig} from "../../libraries/LibFacetStorage.sol"; + +/** + * @title Signature Migration Facet Interface + * @dev Interface of Signature Migration contract for migrating user signature scheme to a new scheme user sets + * Which could include + * - ECDSA on Secp256K1 Curve + * - ECDSA on Secp256R1 Curve + * - BLS, Schnorr, etc + * @author David Yongjun Kim (@Powerstream3604) + */ +interface ISignatureMigrationFacet { + event SignatureSchemeMigration( + address indexed prevVerificationFacet, + address indexed newVerificationFacet, + bytes newOwner, + bytes4[] verificationFuncSelectors + ); + event SignatureMigrationApproved( + bytes newPublicKey, + address indexed newVerificationFacet, + bytes4[] verificationFuncSelectors, + address indexed guardian, + uint128 approvalValidUntil + ); + event SignatureMigrationApprovalRevoked( + bytes newPublicKey, + address indexed newVerificationFacet, + bytes4[] verificationFuncSelectors, + address indexed guardian + ); + event SignatureMigrationExecuted( + address indexed newVerificationFacet, + bytes newOwner, + bytes4[] verificationFuncSelectors, + uint128 migrateAfter + ); + event SignatureMigrationCanceled( + address indexed newVerificationFacet, + bytes newOwner, + bytes4[] verificationFuncSelectors + ); + event SignatureMigrationCancellationApproved( + address indexed newVerificationFacet, + bytes newOwner, + bytes4[] verificationFuncSelectors + ); + + error SignatureMigrationFacet__SignerUninitializationFailure(); + error SignatureMigrationFacet__SignerInitializationFailure(); + error SignatureMigrationFacet__InvalidRouteWithGuardian(); + error SignatureMigrationFacet__InvalidKeyType(); + error SignatureMigrationFacet__InsufficientApprovers(); + error SignatureMigrationFacet__InvalidApproverSignature(); + error SignatureMigrationFacet__InvalidGuardian(); + error SignatureMigrationFacet__NonExistentApprover(); + error SignatureMigrationFacet__InvalidMigrationPeriod(); + error SignatureMigrationFacet__NonexistentMigration(); + error SignatureMigrationFacet__MigrationPeriodNotOver(); + error SignatureMigrationFacet__InvalidArrayLength(); + error SignatureMigrationFacet__InvalidApprovalValidationPeriod(); + error SignatureMigrationFacet__CannotRevokeUnapproved(); + error SignatureMigrationFacet__LackOfOwnerApproval(); + error SignatureMigrationFacet__OwnerAlreadyApproved(); + error SignatureMigrationFacet__NonExistentVerificationFacet(); + error SignatureMigrationFacet__DuplicateApproval(); + + function migrateSignatureScheme( + address newVerificationFacet, + bytes calldata newPublicKey, + bytes4[] calldata newVerificationFuncSelectors + ) external; + + function migrateSignatureSchemeWithGuardian( + address newVerificationFacet, + bytes calldata newPublicKey, + bytes4[] calldata newVerificationFuncSelectors, + address[] calldata approvers, + bytes[] calldata signatures + ) external; + + function approveSignatureSchemeMigration( + address newVerificationFacet, + bytes calldata newPublicKey, + bytes4[] calldata newVerificationFuncSelectors + ) external; + + function revokeSignatureMigrationApproval( + address newVerificationFacet, + bytes calldata newPublicKey, + bytes4[] calldata newVerificationFuncSelectors + ) external; + + function finalizeSignatureMigration() external; + + function approveCancelSignatureMigration( + address newVerificationFacet, + bytes calldata newPublicKey, + bytes4[] calldata newVerificationFuncSelectors + ) external; + + function cancelSignatureMigration( + address newVerificationFacet, + bytes calldata newPublicKey, + bytes4[] calldata newVerificationFuncSelectors, + address[] calldata guardians, + bytes[] calldata signatures + ) external; + + function getApprovalMigrationKeyHash( + bytes memory recoveryPublicKey, + address newVerificationFacet, + bytes4[] memory newVerificationFuncSelectors, + string memory saltString + ) external view returns (bytes32); + + function getMigrationOwnerApprovalWithTimeValidity( + bytes32 publicKeyHash + ) external view returns (bool); + + function getMigrationApprovalCountWithTimeValidity( + bytes32 publicKeyHash + ) external view returns (uint256); + + function isMigrationApproved( + bytes32 migrationPublicKeyHash, + address approver + ) external view returns (bool); + + function getMigrationNonce() external view returns (uint128); + + function isMigrationPending() external view returns (bool); + + function getPendingMigration() + external + view + returns (SignatureMigrationConfig memory); +} diff --git a/contracts/facets/interfaces/IVerificationFacet.sol b/contracts/facets/interfaces/IVerificationFacet.sol new file mode 100644 index 0000000..f719d32 --- /dev/null +++ b/contracts/facets/interfaces/IVerificationFacet.sol @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.21; + +import {UserOperation} from "../../aa-4337/interfaces/UserOperation.sol"; + +/** + * @title Verification Facet Interface + * @dev Implements logic for user ops signature verification + * @author David Yongjun Kim (@Powerstream3604) + * @author Ruslan Serebriakov (@rsrbk) + */ +interface IVerificationFacet { + event SignerInitialized(bytes); + event SignerUninitialized(); + + error VerificationFacet__ValidateOwnerSignatureSelectorNotSet(); + error VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet(); + error VerificationFacet__InitializationFailure(); + error VerificationFacet__InvalidFacetMapping(); + + function initializeSigner(bytes memory) external returns (uint256); + + function uninitializeSigner() external returns (uint256); + + function validateOwnerSignatureSelector() external view returns (bytes4); + + function owner() external view returns (bytes memory); + + function isValidKeyType(bytes calldata) external view returns (bool); + + function validateOwnerSignature( + UserOperation calldata userOp, + bytes32 userOpHash + ) external view returns (uint256); +} diff --git a/contracts/facets/verification/MultiSigFacet.sol b/contracts/facets/verification/MultiSigFacet.sol new file mode 100644 index 0000000..2634c7d --- /dev/null +++ b/contracts/facets/verification/MultiSigFacet.sol @@ -0,0 +1,606 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.21; + +import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; +import {SignatureChecker} from "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol"; +import {UserOperation} from "../../aa-4337/interfaces/UserOperation.sol"; +import {LibDiamond} from "../../libraries/LibDiamond.sol"; +import {LibLoupe} from "../../libraries/LibLoupe.sol"; +import {LibAppStorage} from "../../libraries/LibAppStorage.sol"; +import {LibVerification} from "../../libraries/LibVerification.sol"; +import {LibMultiSigStorage, MultiSigStorage} from "../../libraries/LibMultiSigStorage.sol"; +import {IERC1271} from "../../interfaces/ERC/IERC1271.sol"; +import {IVerificationFacet} from "../interfaces/IVerificationFacet.sol"; +import {IMultiSigFacet} from "../interfaces/IMultiSigFacet.sol"; + +/** + * @title Multi-sig facet + * @dev Multi-signature Facet with custom threshold. + * Wallet that adds this facet becomes a multi-sig wallet. + * Reference signature_format.md documentation for Multi-sig facet details + * @author David Yongjun Kim (@Powerstream3604) + * NOTE: This Facet hasn't been audited yet and it's planning to be audited soon. + */ +contract MultiSigFacet is IMultiSigFacet, IVerificationFacet, IERC1271 { + using ECDSA for bytes32; + + address public immutable self; + + address internal constant SENTINEL_OWNERS = address(0x1); + uint256 internal constant ADDRESS = 20; + uint256 internal constant SIG_TYPE = 1; + uint256 internal constant SIG_LEN = 4; + uint256 internal constant THRESHOLD = 4; + uint256 internal constant INVALID_SIG = 1; + uint256 internal constant VALID_SIG = 0; + + /** + * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts + */ + constructor() { + LibAppStorage.enforceSignerInitialize(); + self = address(this); + } + + /** + * @notice Initializes the signer in Multisig Facet Storage. This can only be called when the account is uninitialized or during signature migration. + * @dev This method checks if the signer has already been initialized. If already initialized, it reverts. + * It checks if the public key is in the right format and initializes signer storage in k1 storage. + * @param _owners Bytes of owner public key + * @return initSuccess Uint value representing the success of init operation + */ + function initializeSigner( + bytes calldata _owners + ) public override returns (uint256 initSuccess) { + LibAppStorage.enforceSignerInitialize(); + + if (!isValidKeyType(_owners)) { + revert MultiSigFacet__InvalidInitData(); + } + + MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage(); + + uint256 threshold = uint256(uint32(bytes4(_owners))); + uint256 ownerCount = (_owners.length - THRESHOLD) / ADDRESS; + + if (threshold == 0) { + revert MultiSigFacet__InvalidThreshold(); + } + if (ownerCount == 0) { + revert MultisigFacet__InvalidOwnerCount(); + } + + address currentOwner = SENTINEL_OWNERS; + uint256 ptr = THRESHOLD; + address owner_; + for (uint256 i; i < ownerCount; ) { + owner_ = address(bytes20(_owners[ptr:ptr + ADDRESS])); + ptr += ADDRESS; + if ( + owner_ == address(0) || + owner_ == SENTINEL_OWNERS || + owner_ == address(this) || + owner_ == currentOwner + ) { + revert MultiSigFacet__InvalidOwnerAddress(); + } + if (ms.owners[owner_] != address(0)) { + revert MultiSigFacet__DuplicateOwner(); + } + + ms.owners[currentOwner] = owner_; + currentOwner = owner_; + + unchecked { + ++i; + } + } + ms.owners[currentOwner] = SENTINEL_OWNERS; + ms.ownerCount = ownerCount; + ms.threshold = threshold; + + bytes4 validateSelector = validateOwnerSignatureSelector(); + + if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0)) { + revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet(); + } + if (LibLoupe.facetAddress(validateSelector) != self) { + revert VerificationFacet__InvalidFacetMapping(); + } + + // initialize verification function selector + LibAppStorage.setValidateOwnerSignatureSelector(validateSelector); + + initSuccess = 1; + + emit SignerInitialized(_owners); + } + + /** + * @notice Uninitialize signer in K1 Facet Storage. This can only be called when the account is undergoing signature migration + * and has already been initialized. + * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value. + * @return uninitSuccess Uint value representing the success of uninit operation + */ + function uninitializeSigner() + external + override + returns (uint256 uninitSuccess) + { + LibAppStorage.enforceSignerMigration(); + LibAppStorage.setSignerUninitialized(); + + MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage(); + ++ms.counter; + address[] memory ownerlist = getOwners(); + uint256 ownerlistLength = ownerlist.length; + for (uint256 i; i < ownerlistLength; ) { + ms.owners[ownerlist[i]] = address(0); + unchecked { + ++i; + } + } + ms.owners[SENTINEL_OWNERS] = address(0); + + if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0)) + revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet(); + LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0)); + + uninitSuccess = 1; + + emit SignerUninitialized(); + } + + /** + * @notice Validates if the user operation is signed by the owner. + * @dev This method validates if the user operation is signed by the owner. It internally calls checkSignatures with + * user operation hash and signature together with the threshold. + * @param userOp UserOperation including all information for execution + * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation + * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure + */ + function validateOwnerSignature( + UserOperation calldata userOp, + bytes32 userOpHash + ) public view override returns (uint256 validationData) { + // Data 1 is invalid, Data 0 is valid + validationData = checkSignatures( + userOpHash, + userOp.signature, + LibMultiSigStorage.multisigStorage().threshold + ); + } + + /** + * @notice Returns the selector of function to validate the signature of UserOperation + * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature + */ + function validateOwnerSignatureSelector() + public + pure + override + returns (bytes4 ownerSignatureValidatorSelector) + { + return this.validateOwnerSignature.selector; + // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change + } + + /** + * @notice Returns the owner of the account + * @return signer Bytes of owner address + */ + function owner() public view override returns (bytes memory) { + MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage(); + + uint totalLength = ms.ownerCount * ADDRESS; + bytes memory result = new bytes(totalLength); + + // populate return array + uint256 index; + address currentOwner = ms.owners[SENTINEL_OWNERS]; + while (currentOwner != SENTINEL_OWNERS) { + assembly { + mstore( + add(result, add(32, mul(index, ADDRESS))), + shl(96, currentOwner) + ) + } + currentOwner = ms.owners[currentOwner]; + index++; + } + + return result; + } + + /** + * @notice Validates if the format of public key is valid for this verification facet + * @dev For this Secp256k1Verification Facet, the public key should comply with the format in the signature_format.md doc + * @param _publicKey Bytes of public key for format check + * @return isValid Boolean variable representing if the format of public key is valid + */ + function isValidKeyType( + bytes memory _publicKey + ) public pure override returns (bool isValid) { + uint256 publicKeyLength = _publicKey.length; + if ( + publicKeyLength < ADDRESS + THRESHOLD || + (publicKeyLength - THRESHOLD) % ADDRESS != 0 + ) { + return false; + } + + uint256 threshold = uint256(uint32(bytes4(_publicKey))); + uint256 ownerCount = (publicKeyLength - THRESHOLD) / ADDRESS; + + isValid = !(ownerCount < threshold || threshold == 0); + } + + /** + * @notice Validates if the signature is valid. Function to be compatible with EIP-1271 + * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true + * @param _hash Hash value the owner signed + * @param _signature Signature that signed the above hash + * @return magicValue Bytes4 value representing the success/failure of validation + */ + function isValidSignature( + bytes32 _hash, + bytes calldata _signature + ) public view override returns (bytes4 magicValue) { + bytes32 messageData = LibVerification.getMessageHash(_hash); + magicValue = (checkSignatures( + messageData, + _signature, + LibMultiSigStorage.multisigStorage().threshold + ) == VALID_SIG) + ? this.isValidSignature.selector + : bytes4(0xffffffff); + } + + /** + * @notice Validates the format of the signature and verifies if the signature is signed by the expected key. + * Reference signature_format.md doc for details about signature format and signature types + * @param _dataHash Bytes value of data hash signed by the owners + * @param _signatures Bytes value of signature which should comply with signature format + * @param _threshold Uint256 value of current Multi-sig Barz's threshold + */ + function checkSignatures( + bytes32 _dataHash, + bytes calldata _signatures, + uint256 _threshold + ) public view returns (uint256) { + MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage(); + + address lastOwner = address(0); + address currentOwner; + bytes memory signature; + uint256 signatureType; + uint256 nextOffset; + uint256 i; + for (i; i < _threshold; ) { + ( + currentOwner, + signature, + signatureType, + nextOffset + ) = splitSignatures(_signatures, nextOffset); + if (nextOffset == 0 && i + 1 < _threshold) { + return INVALID_SIG; + } + if (signatureType == 1) { + // If signatureType is 1 then it is default dataHash signed. + // This also includes the contract signature + if ( + !SignatureChecker.isValidSignatureNow( + currentOwner, + _dataHash, + signature + ) + ) { + return INVALID_SIG; + } + } else if (signatureType == 2) { + // If signatureType is 2 then it is an approved hash + if (ms.approvedHashes[ms.counter][currentOwner][_dataHash] == 0) { + return INVALID_SIG; + } + } else if (signatureType == 3) { + // If signatureType is 3 then it is a signed message hash + // This also includes the contract signature + bytes32 msgHash = _dataHash.toEthSignedMessageHash(); + if ( + !SignatureChecker.isValidSignatureNow( + currentOwner, + msgHash, + signature + ) + ) { + return INVALID_SIG; + } + } else revert MultiSigFacet__InvalidRoute(); + if ( + currentOwner <= lastOwner || + ms.owners[currentOwner] == address(0) || + currentOwner == SENTINEL_OWNERS + ) { + return INVALID_SIG; + } + lastOwner = currentOwner; + + unchecked { + ++i; + } + } + return VALID_SIG; + } + + /** + * @notice Split signatures into each individual signatures. Should comply with signature format to be split + * @param _signatures Bytes value of signature + * @param _nextOffset Uint256 value of next offset to start splitting the signature + */ + function splitSignatures( + bytes calldata _signatures, + uint256 _nextOffset + ) + public + pure + returns ( + address owner_, + bytes memory signature, + uint256 signatureType, + uint256 nextOffset + ) + { + uint256 signaturesLength = _signatures.length; + + if (signaturesLength <= _nextOffset + ADDRESS + SIG_LEN) { + revert MultiSigFacet__InsufficientSignerLength(); + } + + owner_ = address( + bytes20(_signatures[_nextOffset:_nextOffset + ADDRESS]) + ); + + signatureType = uint256( + uint8( + bytes1( + _signatures[_nextOffset + ADDRESS:_nextOffset + + ADDRESS + + SIG_TYPE] + ) + ) + ); + + if (signatureType > 3 || signatureType == 0) { + revert MultiSigFacet__InvalidSignatureType(); + } + uint256 offSet = _nextOffset + ADDRESS + SIG_TYPE; + uint256 siglen = uint256( + uint32(bytes4(_signatures[offSet:offSet + SIG_LEN])) + ); + if (offSet + siglen > signaturesLength) { + revert MultiSigFacet__InvalidSignatureLength(); + } + + offSet += SIG_LEN; + if (offSet + siglen == signaturesLength) { + nextOffset = 0; + } else { + nextOffset = offSet + siglen; + } + + signature = _signatures[offSet:offSet + siglen]; + } + + /** + * @notice Approves the hash of userOperation on-chain. This can only be called by owners. + * @param _hashToApprove Bytes value of UserOperation hash to approve + */ + function approveHash(bytes32 _hashToApprove) external { + MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage(); + + if (ms.owners[msg.sender] == address(0)) { + revert MultiSigFacet__OnlyOwner(); + } + + ms.approvedHashes[ms.counter][msg.sender][_hashToApprove] = 1; + emit HashApproved(_hashToApprove, msg.sender); + } + + /** + * @notice Add owner to Barz. Update thresold if threshold is given different from current threshold + * @dev This can only be done via a Self call. + * @param _newOwner Address of new owner to be added + * @param _threshold Uint256 value of threshold + */ + function addOwner(address _newOwner, uint256 _threshold) external { + LibDiamond.enforceIsSelf(); + + MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage(); + + if ( + _newOwner == address(0) || + _newOwner == SENTINEL_OWNERS || + _newOwner == address(this) + ) { + revert MultiSigFacet__InvalidOwnerAddress(); + } + if (ms.owners[_newOwner] != address(0)) { + revert MultiSigFacet__DuplicateOwner(); + } + + ms.owners[_newOwner] = ms.owners[SENTINEL_OWNERS]; + ms.owners[SENTINEL_OWNERS] = _newOwner; + ++ms.ownerCount; + emit OwnerAdded(_newOwner); + + if (ms.threshold != _threshold) { + changeThreshold(_threshold); + } + } + + /** + * @notice Remove owner from Barz. Update thresold if threshold is given different from current threshold + * @dev This can only be done via a Self call. + * @param _prevOwner Address of owner located right behind the removed owner address in the linked list + * @param _removedOwner Address of owner to be removed + * @param _threshold Uint256 value of threshold + */ + function removeOwner( + address _prevOwner, + address _removedOwner, + uint256 _threshold + ) external { + LibDiamond.enforceIsSelf(); + + MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage(); + + if (ms.ownerCount - 1 < _threshold) { + revert MultiSigFacet__InvalidThreshold(); + } + if (_removedOwner == address(0) || _removedOwner == SENTINEL_OWNERS) { + revert MultiSigFacet__InvalidOwnerAddress(); + } + if (ms.owners[_prevOwner] != _removedOwner) { + revert MultiSigFacet__InvalidOwnerPair(); + } + + ms.owners[_prevOwner] = ms.owners[_removedOwner]; + ms.owners[_removedOwner] = address(0); + --ms.ownerCount; + emit OwnerRemoved(_removedOwner); + + if (ms.threshold != _threshold) { + changeThreshold(_threshold); + } + } + + /** + * @notice Swap owner in Barz. + * @dev This can only be done via a Self call. + * @param _prevOwner Address of owner located right behind the removed owner address in the linked list + * @param _oldOwner Address of owner to be removed + * @param _newOwner Address of owner to be added + */ + function swapOwner( + address _prevOwner, + address _oldOwner, + address _newOwner + ) public { + LibDiamond.enforceIsSelf(); + + MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage(); + + if ( + _newOwner == address(0) || + _newOwner == SENTINEL_OWNERS || + _newOwner == address(this) + ) { + revert MultiSigFacet__InvalidOwnerAddress(); + } + if (ms.owners[_newOwner] != address(0)) { + revert MultiSigFacet__DuplicateOwner(); + } + if (_oldOwner == address(0) || _oldOwner == SENTINEL_OWNERS) { + revert MultiSigFacet__InvalidOwnerAddress(); + } + if (ms.owners[_prevOwner] != _oldOwner) { + revert MultiSigFacet__InvalidOwnerPair(); + } + + ms.owners[_newOwner] = ms.owners[_oldOwner]; + ms.owners[_prevOwner] = _newOwner; + ms.owners[_oldOwner] = address(0); + emit OwnerRemoved(_oldOwner); + emit OwnerAdded(_newOwner); + } + + /** + * @notice Changes the threshold of the Barz to `_threshold`. + * @dev This can only be done via a Self call. + * @param _threshold New threshold + */ + function changeThreshold(uint256 _threshold) public { + LibDiamond.enforceIsSelf(); + + MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage(); + + if (_threshold > ms.ownerCount || _threshold == 0) { + revert MultiSigFacet__InvalidThreshold(); + } + + ms.threshold = _threshold; + emit ThresholdChanged(_threshold); + } + + /** + * @notice Checks if the given address is owner + * @param _owner Address to be checked if it's owner + * @return isOwner_ Bool value showing if it's owner address + */ + function isOwner(address _owner) public view returns (bool isOwner_) { + isOwner_ = (_owner != SENTINEL_OWNERS && + LibMultiSigStorage.multisigStorage().owners[_owner] != address(0)); + } + + /** + * @notice Returns the threshold of Barz + * @return threshold Threshold of the Barz account + */ + function getThreshold() public view returns (uint256 threshold) { + threshold = LibMultiSigStorage.multisigStorage().threshold; + } + + /** + * @notice Returns the list of owner addresses + * @return owners List of owners + */ + function getOwners() public view returns (address[] memory owners) { + MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage(); + owners = new address[](ms.ownerCount); + + uint256 index; + address currentOwner = ms.owners[SENTINEL_OWNERS]; + while (currentOwner != SENTINEL_OWNERS) { + owners[index] = currentOwner; + currentOwner = ms.owners[currentOwner]; + index++; + } + } + + /** + * @notice Returns the previous owner in the linked list + * @param _owner Address of owner + * @return prevOwner Address of previous owner + */ + function getPrevOwner( + address _owner + ) public view returns (address prevOwner) { + MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage(); + + address currentOwner = ms.owners[SENTINEL_OWNERS]; + if (currentOwner == _owner) return SENTINEL_OWNERS; + while (currentOwner != SENTINEL_OWNERS) { + if (ms.owners[currentOwner] == _owner) { + return currentOwner; + } + + currentOwner = ms.owners[currentOwner]; + } + return address(0); + } + + /** + * @notice Returns of the owner is approved by given owner address + * @param _owner Address of owner + * @param _hash Hash of UserOperation + * @return isApproved Bool value showing if the hash is approved by owner + */ + function isApprovedHash( + address _owner, + bytes32 _hash + ) public view returns (bool isApproved) { + MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage(); + isApproved = (ms.approvedHashes[ms.counter][_owner][_hash] == 1); + } +} diff --git a/contracts/facets/verification/secp256k1/Secp256k1VerificationFacet.sol b/contracts/facets/verification/secp256k1/Secp256k1VerificationFacet.sol new file mode 100644 index 0000000..0efd2ec --- /dev/null +++ b/contracts/facets/verification/secp256k1/Secp256k1VerificationFacet.sol @@ -0,0 +1,205 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.21; + +import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; +import {UserOperation} from "../../../aa-4337/interfaces/UserOperation.sol"; +import {LibAppStorage} from "../../../libraries/LibAppStorage.sol"; +import {LibVerification} from "../../../libraries/LibVerification.sol"; +import {LibFacetStorage, Secp256k1VerificationStorage} from "../../../libraries/LibFacetStorage.sol"; +import {LibLoupe} from "../../../libraries/LibLoupe.sol"; +import {IERC1271} from "../../../interfaces/ERC/IERC1271.sol"; +import {IVerificationFacet} from "../../interfaces/IVerificationFacet.sol"; + +/** + * @title Secp256k1 verification facet + * @dev Default Ethereum's elliptic curve + * @author David Yongjun Kim (@Powerstream3604) + * @author Ruslan Serebriakov (@rsrbk) + */ +contract Secp256k1VerificationFacet is IVerificationFacet, IERC1271 { + using ECDSA for bytes32; + error Secp256k1VerificationFacet__InvalidSignerLength(); + address public immutable self; + + /** + * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts + */ + constructor() { + LibAppStorage.enforceSignerInitialize(); + self = address(this); + } + + /** + * @notice Initializes the signer in K1 Facet Storage. This can only be called when the account is uninitialized or during signature migration. + * @dev This method checks if the signer has already been initialized. If already initialized, it reverts. + * It checks if the public key is in the light format and initializes signer storage in k1 storage. + * @param _publicKey Bytes of owner public key + * @return initSuccess Uint value representing the success of init operation + */ + function initializeSigner( + bytes calldata _publicKey + ) public override returns (uint256 initSuccess) { + LibAppStorage.enforceSignerInitialize(); + if (!isValidKeyType(_publicKey)) { + revert Secp256k1VerificationFacet__InvalidSignerLength(); + } + + Secp256k1VerificationStorage storage k1Storage = LibFacetStorage + .k1Storage(); + address signer; + assembly { + // Check if the length of the publicKey is 20 bytes + switch eq(_publicKey.length, 20) + case 0 { + let ptr := mload(0x40) + calldatacopy(ptr, add(_publicKey.offset, 1), 64) + signer := keccak256(ptr, sub(_publicKey.length, 1)) + } + case 1 { + // address is encoded with zero padded at the end part. e,g,m 0x1234...0000 + // calldataload will load the 32 bytes and assigning it to signer(with type address) will truncate the first 12bytes, which returns invalid address + // hence, we sub 12 to the offset so the signer will be a valid address + signer := calldataload(sub(_publicKey.offset, 12)) + } + default { + revert (0, 0) + } + } + k1Storage.signer = signer; + + bytes4 validateSelector = validateOwnerSignatureSelector(); + + if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0)) { + revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet(); + } + if (LibLoupe.facetAddress(validateSelector) != self) { + revert VerificationFacet__InvalidFacetMapping(); + } + + // initialize verification function selector + LibAppStorage.setValidateOwnerSignatureSelector(validateSelector); + + initSuccess = 1; + + emit SignerInitialized(_publicKey); + } + + /** + * @notice Uninitialize signer in K1 Facet Storage. This can only be called when the account is undergoing signature migration + * and has already been initialized. + * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value. + * @return uninitSuccess Uint value representing the success of uninit operation + */ + function uninitializeSigner() + external + override + returns (uint256 uninitSuccess) + { + LibAppStorage.enforceSignerMigration(); + LibAppStorage.setSignerUninitialized(); + Secp256k1VerificationStorage storage k1Storage = LibFacetStorage + .k1Storage(); + k1Storage.signer = address(0); + + if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0)) { + revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet(); + } + LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0)); + + uninitSuccess = 1; + + emit SignerUninitialized(); + } + + /** + * @notice Validates if the user operation is signed by the owner. + * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with + * signer public key. + * @param userOp UserOperation including all information for execution + * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation + * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure + */ + function validateOwnerSignature( + UserOperation calldata userOp, + bytes32 userOpHash + ) public view override returns (uint256 validationData) { + Secp256k1VerificationStorage storage k1Storage = LibFacetStorage + .k1Storage(); + validationData = validateSignature( + userOp, + userOpHash, + k1Storage.signer + ); + } + + /** + * @notice Validates if the signature of UserOperation is signed by the given signer + * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address + * @param userOp UserOperation including all information for execution + * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation + * @param signer Address of signer who signed the contract, to be validated + * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure + */ + function validateSignature( + UserOperation calldata userOp, + bytes32 userOpHash, + address signer + ) public pure returns (uint256 isValid) { + bytes32 hash = userOpHash.toEthSignedMessageHash(); + isValid = (signer != hash.recover(userOp.signature)) ? 1 : 0; + } + + /** + * @notice Returns the selector of function to validate the signature of UserOperation + * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature + */ + function validateOwnerSignatureSelector() + public + pure + override + returns (bytes4 ownerSignatureValidatorSelector) + { + ownerSignatureValidatorSelector = this.validateOwnerSignature.selector; + // NOTE: The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change + } + + /** + * @notice Returns the owner of the account + * @return signer Bytes of owner address + */ + function owner() public view override returns (bytes memory signer) { + Secp256k1VerificationStorage storage k1Storage = LibFacetStorage + .k1Storage(); + signer = abi.encodePacked(k1Storage.signer); + } + + /** + * @notice Validates if the format of public key is valid for this verification facet + * @dev For this Secp256k1Verification Facet, the public key length should be 65 in an uncompressed public key format + * @param _publicKey Bytes of public key for format check + * @return isValid Boolean variable representing if the format of public key is valid + */ + function isValidKeyType( + bytes memory _publicKey + ) public pure override returns (bool isValid) { + isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04) || (_publicKey.length == 20); + } + + /** + * @notice Validates if the signature is valid. Function to be compatible with EIP-1271 + * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true + * @param _hash Hash value the owner signed + * @param _signature Signature that signed the above hash + * @return magicValue Bytes4 value representing the success/failure of validation + */ + function isValidSignature( + bytes32 _hash, + bytes memory _signature + ) public view override returns (bytes4 magicValue) { + bytes32 messageData = LibVerification.getMessageHash(_hash); + magicValue = (messageData.recover(_signature) == + LibFacetStorage.k1Storage().signer) + ? this.isValidSignature.selector + : bytes4(0xffffffff); + } +} diff --git a/contracts/facets/verification/secp256r1/Secp256r1VerificationFacet.sol b/contracts/facets/verification/secp256r1/Secp256r1VerificationFacet.sol new file mode 100644 index 0000000..801026a --- /dev/null +++ b/contracts/facets/verification/secp256r1/Secp256r1VerificationFacet.sol @@ -0,0 +1,212 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.21; + +import {UserOperation} from "../../../aa-4337/interfaces/UserOperation.sol"; +import {LibAppStorage} from "../../../libraries/LibAppStorage.sol"; +import {LibLoupe} from "../../../libraries/LibLoupe.sol"; +import {LibFacetStorage, Secp256r1VerificationStorage} from "../../../libraries/LibFacetStorage.sol"; +import {Base64} from "./utils/Base64.sol"; +import {LibSecp256r1} from "./utils/LibSecp256r1.sol"; +import {IERC1271} from "../../../interfaces/ERC/IERC1271.sol"; +import {IVerificationFacet} from "../../interfaces/IVerificationFacet.sol"; + +/** + * @title Secp256r1 verification facet + * @dev Primarily used to verify user ops signed with passkeys + * @author Ruslan Serebriakov (@rsrbk) + * @author David Yongjun Kim (@Powerstream3604) + */ +contract Secp256r1VerificationFacet is IVerificationFacet, IERC1271 { + error Secp256r1VerificationFacet__InvalidSignerLength(); + address public immutable self; + + /** + * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts + */ + constructor() { + LibAppStorage.enforceSignerInitialize(); + self = address(this); + } + + /** + * @notice Initializes the signer in R1 Facet Storage. This can only be called when the account is uninitialized or during signature migration. + * @dev This method checks if the signer has already been initialized. If already initialized, it reverts. + * It checks if the public key is in the light format and initializes signer storage in k1 storage. + * @param _publicKey Bytes of owner public key + * @return initSuccess Uint value representing the success of init operation + */ + function initializeSigner( + bytes calldata _publicKey + ) public override returns (uint256 initSuccess) { + LibAppStorage.enforceSignerInitialize(); + + if (!isValidKeyType(_publicKey)) + revert Secp256r1VerificationFacet__InvalidSignerLength(); + + bytes memory publicKeyCoordinates = _publicKey[1:]; + uint256[2] memory q; + assembly { + // Copy the bytes from the input data into the uint256 array + mstore(q, mload(add(publicKeyCoordinates, 32))) + mstore(add(q, 32), mload(add(publicKeyCoordinates, 64))) + } + Secp256r1VerificationStorage storage r1Storage = LibFacetStorage + .r1Storage(); + r1Storage.q = q; + + bytes4 validateSelector = validateOwnerSignatureSelector(); + + if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0)) + revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet(); + if (LibLoupe.facetAddress(validateSelector) != self) + revert VerificationFacet__InvalidFacetMapping(); + + // initialize verification function selector + LibAppStorage.setValidateOwnerSignatureSelector(validateSelector); + + initSuccess = 1; + + emit SignerInitialized(_publicKey); + } + + /** + * @notice Uninitialize signer in R1 Facet Storage. This can only be called when the account is undergoing signature migration + * and has already been initialized. + * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value. + * @return uninitSuccess Uint value representing the success of uninit operation + */ + function uninitializeSigner() + external + override + returns (uint256 uninitSuccess) + { + LibAppStorage.enforceSignerMigration(); + LibAppStorage.setSignerUninitialized(); + Secp256r1VerificationStorage storage r1Storage = LibFacetStorage + .r1Storage(); + r1Storage.q = [0, 0]; + + if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0)) + revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet(); + LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0)); + + uninitSuccess = 1; + + emit SignerUninitialized(); + } + + /** + * @notice Validates if the user operation is signed by the owner. + * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with + * signer public key. + * @param userOp UserOperation including all information for execution + * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation + * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure + */ + function validateOwnerSignature( + UserOperation calldata userOp, + bytes32 userOpHash + ) public view override returns (uint256 validationData) { + Secp256r1VerificationStorage storage r1Storage = LibFacetStorage + .r1Storage(); + validationData = validateSignature(userOp, userOpHash, r1Storage.q); + } + + /** + * @notice Validates if the signature of UserOperation is signed by the given signer + * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address + * @param userOp UserOperation including all information for execution + * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation + * @param q Public Key of signer who signed the contract, to be validated + * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure + */ + function validateSignature( + UserOperation calldata userOp, + bytes32 userOpHash, + uint256[2] memory q + ) public view returns (uint256 isValid) { + isValid = (_validateSignature(q, userOpHash, userOp.signature)) ? 0 : 1; + } + + /** + * @notice Returns the selector of function to validate the signature of UserOperation + * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature + */ + function validateOwnerSignatureSelector() + public + pure + override + returns (bytes4 ownerSignatureValidatorSelector) + { + return this.validateOwnerSignature.selector; // validateOwnerSignature(UserOperation calldata userOp,bytes32 userOpHash) + // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change + } + + /** + * @notice Returns the owner of the account + * @return signer Bytes of owner address + */ + function owner() public view override returns (bytes memory signer) { + Secp256r1VerificationStorage storage r1Storage = LibFacetStorage + .r1Storage(); + signer = abi.encodePacked(r1Storage.q); + } + + /** + * @notice Validates if the format of public key is valid for this verification facet + * @dev For this Secp256k1Verification Facet, the public key should in an uncompressed public key format + * @param _publicKey Bytes of public key for format check + * @return isValid Boolean variable representing if the format of public key is valid + */ + function isValidKeyType( + bytes memory _publicKey + ) public pure override returns (bool isValid) { + isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04); + } + + /** + * @notice Validates if the signature is valid. Function to be compatible with EIP-1271 + * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true + * @param _hash Hash value the owner signed + * @param _signature Signature that signed the above hash + * @return magicValue Bytes4 value representing the success/failure of validation + */ + function isValidSignature( + bytes32 _hash, + bytes memory _signature + ) public view override returns (bytes4 magicValue) { + magicValue = _validateSignature( + LibFacetStorage.r1Storage().q, + _hash, + _signature + ) + ? this.isValidSignature.selector + : bytes4(0xffffffff); + } + + function _validateSignature( + uint256[2] memory q, + bytes32 _hash, + bytes memory _signature + ) internal view returns (bool) { + ( + uint256 rValue, + uint256 sValue, + bytes memory authenticatorData, + string memory clientDataJSONPre, + string memory clientDataJSONPost + ) = abi.decode(_signature, (uint256, uint256, bytes, string, string)); + bytes32 clientHash; + { + string memory opHashBase64 = Base64.encode(bytes.concat(_hash)); + string memory clientDataJSON = string.concat( + clientDataJSONPre, + opHashBase64, + clientDataJSONPost + ); + clientHash = sha256(bytes(clientDataJSON)); + } + bytes32 sigHash = sha256(bytes.concat(authenticatorData, clientHash)); + return LibSecp256r1.Verify(q, rValue, sValue, uint256(sigHash)); + } +} diff --git a/contracts/facets/verification/secp256r1/Secp256r1VerificationFacetV2.sol b/contracts/facets/verification/secp256r1/Secp256r1VerificationFacetV2.sol new file mode 100644 index 0000000..de638aa --- /dev/null +++ b/contracts/facets/verification/secp256r1/Secp256r1VerificationFacetV2.sol @@ -0,0 +1,233 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.21; + +import {UserOperation} from "../../../aa-4337/interfaces/UserOperation.sol"; +import {LibAppStorage} from "../../../libraries/LibAppStorage.sol"; +import {LibLoupe} from "../../../libraries/LibLoupe.sol"; +import {LibFacetStorage, Secp256r1VerificationStorage} from "../../../libraries/LibFacetStorage.sol"; +import {LibVerification} from "../../../libraries/LibVerification.sol"; +import {Base64} from "./utils/Base64.sol"; +import {FCLSecp256} from "./utils/FCLSecp256.sol"; +import {IERC1271} from "../../../interfaces/ERC/IERC1271.sol"; +import {IVerificationFacet} from "../../interfaces/IVerificationFacet.sol"; + +/** + * @title Secp256r1 verification facet V2 + * @dev Facet to verify Secp256r1 signature. Uses RIP 7212 precompile if exists, fallback to verification library if not. + * @author David Yongjun Kim (@Powerstream3604) + * NOTE: This Facet hasn't been audited yet and it's planning to be audited soon. + */ +contract Secp256r1VerificationFacetV2 is IVerificationFacet, IERC1271 { + error Secp256r1VerificationFacet__InvalidSignerLength(); + address public constant P256_VERIFIER = address(0x100); + address public immutable self; + + /** + * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts + */ + constructor() { + LibAppStorage.enforceSignerInitialize(); + self = address(this); + } + + /** + * @notice Initializes the signer in R1 Facet Storage. This can only be called when the account is uninitialized or during signature migration. + * @dev This method checks if the signer has already been initialized. If already initialized, it reverts. + * It checks if the public key is in the light format and initializes signer storage in k1 storage. + * @param _publicKey Bytes of owner public key + * @return initSuccess Uint value representing the success of init operation + */ + function initializeSigner( + bytes calldata _publicKey + ) public override returns (uint256 initSuccess) { + LibAppStorage.enforceSignerInitialize(); + + if (!isValidKeyType(_publicKey)) { + revert Secp256r1VerificationFacet__InvalidSignerLength(); + } + + bytes memory publicKeyCoordinates = _publicKey[1:]; + uint256[2] memory q; + assembly { + // Copy the bytes from the input data into the uint256 array + mstore(q, mload(add(publicKeyCoordinates, 32))) + mstore(add(q, 32), mload(add(publicKeyCoordinates, 64))) + } + Secp256r1VerificationStorage storage r1Storage = LibFacetStorage + .r1Storage(); + r1Storage.q = q; + + bytes4 validateSelector = validateOwnerSignatureSelector(); + + if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0)) { + revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet(); + } + if (LibLoupe.facetAddress(validateSelector) != self) { + revert VerificationFacet__InvalidFacetMapping(); + } + + // initialize verification function selector + LibAppStorage.setValidateOwnerSignatureSelector(validateSelector); + + initSuccess = 1; + + emit SignerInitialized(_publicKey); + } + + /** + * @notice Uninitialize signer in R1 Facet Storage. This can only be called when the account is undergoing signature migration + * and has already been initialized. + * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value. + * @return uninitSuccess Uint value representing the success of uninit operation + */ + function uninitializeSigner() + external + override + returns (uint256 uninitSuccess) + { + LibAppStorage.enforceSignerMigration(); + LibAppStorage.setSignerUninitialized(); + Secp256r1VerificationStorage storage r1Storage = LibFacetStorage + .r1Storage(); + r1Storage.q = [0, 0]; + + if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0)) { + revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet(); + } + LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0)); + + uninitSuccess = 1; + + emit SignerUninitialized(); + } + + /** + * @notice Validates if the user operation is signed by the owner. + * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with + * signer public key. + * @param userOp UserOperation including all information for execution + * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation + * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure + */ + function validateOwnerSignature( + UserOperation calldata userOp, + bytes32 userOpHash + ) public view override returns (uint256 validationData) { + Secp256r1VerificationStorage storage r1Storage = LibFacetStorage + .r1Storage(); + validationData = validateSignature(userOp, userOpHash, r1Storage.q); + } + + /** + * @notice Validates if the signature of UserOperation is signed by the given signer + * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address + * @param userOp UserOperation including all information for execution + * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation + * @param q Public Key of signer who signed the contract, to be validated + * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure + */ + function validateSignature( + UserOperation calldata userOp, + bytes32 userOpHash, + uint256[2] memory q + ) public view returns (uint256 isValid) { + isValid = (_validateSignature(q, userOpHash, userOp.signature)) ? 0 : 1; + } + + /** + * @notice Returns the selector of function to validate the signature of UserOperation + * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature + */ + function validateOwnerSignatureSelector() + public + pure + override + returns (bytes4 ownerSignatureValidatorSelector) + { + return this.validateOwnerSignature.selector; // validateOwnerSignature(UserOperation calldata userOp,bytes32 userOpHash) + // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change + } + + /** + * @notice Returns the owner of the account + * @return signer Bytes of owner address + */ + function owner() public view override returns (bytes memory signer) { + Secp256r1VerificationStorage storage r1Storage = LibFacetStorage + .r1Storage(); + signer = abi.encodePacked(r1Storage.q); + } + + /** + * @notice Validates if the format of public key is valid for this verification facet + * @dev For this Secp256k1Verification Facet, the public key should in an uncompressed public key format + * @param _publicKey Bytes of public key for format check + * @return isValid Boolean variable representing if the format of public key is valid + */ + function isValidKeyType( + bytes memory _publicKey + ) public pure override returns (bool isValid) { + isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04); + } + + /** + * @notice Validates if the signature is valid. Function to be compatible with EIP-1271 + * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true + * @param _hash Hash value the owner signed + * @param _signature Signature that signed the above hash + * @return magicValue Bytes4 value representing the success/failure of validation + */ + function isValidSignature( + bytes32 _hash, + bytes memory _signature + ) public view override returns (bytes4 magicValue) { + bytes32 messageData = LibVerification.getMessageHash(_hash); + magicValue = _validateSignature( + LibFacetStorage.r1Storage().q, + messageData, + _signature + ) + ? this.isValidSignature.selector + : bytes4(0xffffffff); + } + + function _validateSignature( + uint256[2] memory q, + bytes32 _hash, + bytes memory _signature + ) internal view returns (bool) { + ( + uint256 rValue, + uint256 sValue, + bytes memory authenticatorData, + string memory clientDataJSONPre, + string memory clientDataJSONPost + ) = abi.decode(_signature, (uint256, uint256, bytes, string, string)); + bytes32 clientHash; + { + string memory opHashBase64 = Base64.encode(bytes.concat(_hash)); + string memory clientDataJSON = string.concat( + clientDataJSONPre, + opHashBase64, + clientDataJSONPost + ); + clientHash = sha256(bytes(clientDataJSON)); + } + bytes32 sigHash = sha256(bytes.concat(authenticatorData, clientHash)); + + if (!FCLSecp256.sanity_check([rValue, sValue], q)) { + return false; + } + + { + bytes memory args = abi.encode(sigHash, rValue, sValue, q[0], q[1]); + (bool success, bytes memory ret) = P256_VERIFIER.staticcall(args); + + if (success && ret.length > 0) { + return abi.decode(ret, (uint256)) == 1; + } + } + + return FCLSecp256.ecdsa_verify(sigHash, [rValue, sValue], q); + } +} diff --git a/contracts/facets/verification/secp256r1/utils/Base64.sol b/contracts/facets/verification/secp256r1/utils/Base64.sol new file mode 100644 index 0000000..e787e6d --- /dev/null +++ b/contracts/facets/verification/secp256r1/utils/Base64.sol @@ -0,0 +1,93 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.21; + +/** + * @dev Provides a set of functions to operate with Base64 strings. + * modified for base64url https://datatracker.ietf.org/doc/html/rfc4648#section-5 + * _Available since v4.5._ + */ +library Base64 { + /** + * @dev Base64 Encoding/Decoding Table + */ + string internal constant _TABLE = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; + + /** + * @dev Converts a `bytes` to its Bytes64 `string` representation. + */ + function encode(bytes memory data) internal pure returns (string memory) { + /** + * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence + * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol + */ + if (data.length == 0) return ""; + + // Loads the table into memory + string memory table = _TABLE; + + // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter + // and split into 4 numbers of 6 bits. + // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up + // - `data.length + 2` -> Round up + // - `/ 3` -> Number of 3-bytes chunks + // - `4 *` -> 4 characters for each chunk + uint256 newlength = (data.length * 8) / 6; + if (data.length % 6 > 0) { + newlength++; + } + string memory result = new string(newlength); + + /// @solidity memory-safe-assembly + assembly { + // Prepare the lookup table (skip the first "length" byte) + let tablePtr := add(table, 1) + + // Prepare result pointer, jump over length + let resultPtr := add(result, 32) + + // Run over the input, 3 bytes at a time + for { + let dataPtr := data + let endPtr := add(data, mload(data)) + } lt(dataPtr, endPtr) { + + } { + // Advance 3 bytes + dataPtr := add(dataPtr, 3) + let input := mload(dataPtr) + + // To write each character, shift the 3 bytes (18 bits) chunk + // 4 times in blocks of 6 bits for each character (18, 12, 6, 0) + // and apply logical AND with 0x3F which is the number of + // the previous character in the ASCII table prior to the Base64 Table + // The result is then added to the table to get the character to write, + // and finally write it in the result pointer but with a left shift + // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits + + mstore8( + resultPtr, + mload(add(tablePtr, and(shr(18, input), 0x3F))) + ) + resultPtr := add(resultPtr, 1) // Advance + + mstore8( + resultPtr, + mload(add(tablePtr, and(shr(12, input), 0x3F))) + ) + resultPtr := add(resultPtr, 1) // Advance + + mstore8( + resultPtr, + mload(add(tablePtr, and(shr(6, input), 0x3F))) + ) + resultPtr := add(resultPtr, 1) // Advance + + mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F)))) + resultPtr := add(resultPtr, 1) // Advance + } + } + + return result; + } +} diff --git a/contracts/facets/verification/secp256r1/utils/FCLSecp256.sol b/contracts/facets/verification/secp256r1/utils/FCLSecp256.sol new file mode 100644 index 0000000..1281194 --- /dev/null +++ b/contracts/facets/verification/secp256r1/utils/FCLSecp256.sol @@ -0,0 +1,1192 @@ +//********************************************************************************************/ +// ___ _ ___ _ _ _ _ +// | __| _ ___ __| |_ / __|_ _ _ _ _ __| |_ ___ | | (_) |__ +// | _| '_/ -_|_-< ' \ | (__| '_| || | '_ \ _/ _ \ | |__| | '_ \ +// |_||_| \___/__/_||_| \___|_| \_, | .__/\__\___/ |____|_|_.__/ +// |__/|_| +///* Copyright (C) 2022 - Renaud Dubois - This file is part of FCL (Fresh CryptoLib) project +///* License: This software is licensed under MIT License +///* This Code may be reused including license and copyright notice. +///* See LICENSE file at the root folder of the project. +///* FILE: FCL_elliptic.sol +///* +///* +///* DESCRIPTION: modified XYZZ system coordinates for EVM elliptic point multiplication +///* optimization +///* +//**************************************************************************************/ +//* WARNING: this code SHALL not be used for non prime order curves for security reasons. +// Code is optimized for a=-3 only curves with prime order, constant like -1, -2 shall be replaced +// if ever used for other curve than sec256R1 +// SPDX-License-Identifier: MIT +pragma solidity 0.8.21; + +library FCLSecp256 { + // Set parameters for curve sec256r1. + + //curve prime field modulus + uint256 constant p = + 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF; + //short weierstrass first coefficient + uint256 constant a = + 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC; + //short weierstrass second coefficient + uint256 constant b = + 0x5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B; + //generating point affine coordinates + uint256 constant gx = + 0x6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296; + uint256 constant gy = + 0x4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5; + //curve order (number of points) + uint256 constant n = + 0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551; + /* -2 mod p constant, used to speed up inversion and doubling (avoid negation)*/ + uint256 constant minus_2 = + 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFD; + /* -2 mod n constant, used to speed up inversion*/ + uint256 constant minus_2modn = + 0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC63254F; + + uint256 constant minus_1 = + 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; + uint256 constant P256_N_DIV_2 = + 57896044605178124381348723474703786764998477612067880171211129530534256022184; + + /** + * /* inversion mod n via a^(n-2), use of precompiled using little Fermat theorem + */ + function FCL_nModInv(uint256 u) internal view returns (uint256 result) { + uint256[6] memory pointer; + assembly { + // Define length of base, exponent and modulus. 0x20 == 32 bytes + mstore(pointer, 0x20) + mstore(add(pointer, 0x20), 0x20) + mstore(add(pointer, 0x40), 0x20) + // Define variables base, exponent and modulus + mstore(add(pointer, 0x60), u) + mstore(add(pointer, 0x80), minus_2modn) + mstore(add(pointer, 0xa0), n) + + // Call the precompiled contract 0x05 = ModExp + if iszero(staticcall(14000, 0x05, pointer, 0xc0, pointer, 0x20)) { + revert(0, 0) + } + result := mload(pointer) + } + } + + /** + * /* @dev inversion mod nusing little Fermat theorem via a^(n-2), use of precompiled + */ + + function FCL_pModInv(uint256 u) internal view returns (uint256 result) { + uint256[6] memory pointer; + assembly { + // Define length of base, exponent and modulus. 0x20 == 32 bytes + mstore(pointer, 0x20) + mstore(add(pointer, 0x20), 0x20) + mstore(add(pointer, 0x40), 0x20) + // Define variables base, exponent and modulus + mstore(add(pointer, 0x60), u) + mstore(add(pointer, 0x80), minus_2) + mstore(add(pointer, 0xa0), p) + + // Call the precompiled contract 0x05 = ModExp + if iszero(staticcall(14000, 0x05, pointer, 0xc0, pointer, 0x20)) { + revert(0, 0) + } + result := mload(pointer) + } + } + + /** + * /* @dev Convert from affine rep to XYZZ rep + */ + function ecAff_SetZZ( + uint256 x0, + uint256 y0 + ) internal pure returns (uint256[4] memory P) { + unchecked { + P[2] = 1; //ZZ + P[3] = 1; //ZZZ + P[0] = x0; + P[1] = y0; + } + } + + /** + * /* @dev Convert from XYZZ rep to affine rep + */ + /* https://hyperelliptic.org/EFD/g1p/auto-shortw-xyzz-3.html#addition-add-2008-s*/ + function ecZZ_SetAff( + uint256 x, + uint256 y, + uint256 zz, + uint256 zzz + ) internal view returns (uint256 x1, uint256 y1) { + uint256 zzzInv = FCL_pModInv(zzz); //1/zzz + y1 = mulmod(y, zzzInv, p); //Y/zzz + uint256 _b = mulmod(zz, zzzInv, p); //1/z + zzzInv = mulmod(_b, _b, p); //1/zz + x1 = mulmod(x, zzzInv, p); //X/zz + } + + /** + * /* @dev Sutherland2008 doubling + */ + /* The "dbl-2008-s-1" doubling formulas */ + + function ecZZ_Dbl( + uint256 x, + uint256 y, + uint256 zz, + uint256 zzz + ) internal pure returns (uint256 P0, uint256 P1, uint256 P2, uint256 P3) { + unchecked { + assembly { + P0 := mulmod(2, y, p) //U = 2*Y1 + P2 := mulmod(P0, P0, p) // V=U^2 + P3 := mulmod(x, P2, p) // S = X1*V + P1 := mulmod(P0, P2, p) // W=UV + P2 := mulmod(P2, zz, p) //zz3=V*ZZ1 + zz := mulmod( + 3, + mulmod(addmod(x, sub(p, zz), p), addmod(x, zz, p), p), + p + ) //M=3*(X1-ZZ1)*(X1+ZZ1) + P0 := addmod(mulmod(zz, zz, p), mulmod(minus_2, P3, p), p) //X3=M^2-2S + x := mulmod(zz, addmod(P3, sub(p, P0), p), p) //M(S-X3) + P3 := mulmod(P1, zzz, p) //zzz3=W*zzz1 + P1 := addmod(x, sub(p, mulmod(P1, y, p)), p) //Y3= M(S-X3)-W*Y1 + } + } + return (P0, P1, P2, P3); + } + + /** + * @dev Sutherland2008 add a ZZ point with a normalized point and greedy formulae + * warning: assume that P1(x1,y1)!=P2(x2,y2), true in multiplication loop with prime order (cofactor 1) + */ + + //tbd: return -x1 and -Y1 in double to avoid two substractions + function ecZZ_AddN( + uint256 x1, + uint256 y1, + uint256 zz1, + uint256 zzz1, + uint256 x2, + uint256 y2 + ) internal pure returns (uint256 P0, uint256 P1, uint256 P2, uint256 P3) { + unchecked { + if (y1 == 0) { + return (x2, y2, 1, 1); + } + + assembly { + y1 := sub(p, y1) + y2 := addmod(mulmod(y2, zzz1, p), y1, p) + x2 := addmod(mulmod(x2, zz1, p), sub(p, x1), p) + P0 := mulmod(x2, x2, p) //PP = P^2 + P1 := mulmod(P0, x2, p) //PPP = P*PP + P2 := mulmod(zz1, P0, p) ////ZZ3 = ZZ1*PP + P3 := mulmod(zzz1, P1, p) ////ZZZ3 = ZZZ1*PPP + zz1 := mulmod(x1, P0, p) //Q = X1*PP + P0 := addmod( + addmod(mulmod(y2, y2, p), sub(p, P1), p), + mulmod(minus_2, zz1, p), + p + ) //R^2-PPP-2*Q + P1 := addmod( + mulmod(addmod(zz1, sub(p, P0), p), y2, p), + mulmod(y1, P1, p), + p + ) //R*(Q-X3) + } + //end assembly + } //end unchecked + return (P0, P1, P2, P3); + } + + /** + * @dev Return the zero curve in XYZZ coordinates. + */ + function ecZZ_SetZero() + internal + pure + returns (uint256 x, uint256 y, uint256 zz, uint256 zzz) + { + return (0, 0, 0, 0); + } + + /** + * @dev Check if point is the neutral of the curve + */ + + function ecZZ_IsZero( + uint256, + uint256 y0, + uint256, + uint256 + ) internal pure returns (bool) { + if ((y0 == 0)) { + return true; + } + return false; + } + + /** + * @dev Return the zero curve in affine coordinates. Compatible with the double formulae (no special case) + */ + + function ecAff_SetZero() internal pure returns (uint256 x, uint256 y) { + return (0, 0); + } + + /** + * @dev Check if the curve is the zero curve in affine rep. + */ + function ecAff_IsZero( + uint256, + uint256 y + ) internal pure returns (bool flag) { + return (y == 0); + } + + /** + * @dev Check if a point in affine coordinates is on the curve (reject Neutral that is indeed on the curve). + */ + function ecAff_isOnCurve( + uint256 x, + uint256 y + ) internal pure returns (bool) { + if (0 == x || x == p || 0 == y || y == p) { + return false; + } + unchecked { + uint256 LHS = mulmod(y, y, p); // y^2 + uint256 RHS = addmod( + mulmod(mulmod(x, x, p), x, p), + mulmod(x, a, p), + p + ); // x^3+ax + RHS = addmod(RHS, b, p); // x^3 + a*x + b + + return LHS == RHS; + } + } + + /** + * @dev Add two elliptic curve points in affine coordinates. + */ + + function ecAff_add( + uint256 x0, + uint256 y0, + uint256 x1, + uint256 y1 + ) internal view returns (uint256, uint256) { + uint256 zz0; + uint256 zzz0; + + if (ecAff_IsZero(x0, y0)) return (x1, y1); + if (ecAff_IsZero(x1, y1)) return (x0, y0); + + (x0, y0, zz0, zzz0) = ecZZ_AddN(x0, y0, 1, 1, x1, y1); + + return ecZZ_SetAff(x0, y0, zz0, zzz0); + } + + /** + * @dev Computation of uG+vQ using Strauss-Shamir's trick, G basepoint, Q public key + */ + function ecZZ_mulmuladd_S_asm( + uint256 Q0, + uint256 Q1, //affine rep for input point Q + uint256 scalar_u, + uint256 scalar_v + ) internal view returns (uint256 X) { + uint256 zz; + uint256 zzz; + uint256 Y; + uint256 index = 255; + uint256[6] memory T; + uint256 H0; + uint256 H1; + + unchecked { + if (scalar_u == 0 && scalar_v == 0) return 0; + + (H0, H1) = ecAff_add(gx, gy, Q0, Q1); //will not work if Q=P, obvious forbidden private key + + /* + while( ( ((scalar_u>>index)&1)+2*((scalar_v>>index)&1) ) ==0){ + index=index-1; + } + */ + + assembly { + for { + let T4 := add( + shl(1, and(shr(index, scalar_v), 1)), + and(shr(index, scalar_u), 1) + ) + } eq(T4, 0) { + index := sub(index, 1) + T4 := add( + shl(1, and(shr(index, scalar_v), 1)), + and(shr(index, scalar_u), 1) + ) + } { + + } + zz := add( + shl(1, and(shr(index, scalar_v), 1)), + and(shr(index, scalar_u), 1) + ) + + if eq(zz, 1) { + X := gx + Y := gy + } + if eq(zz, 2) { + X := Q0 + Y := Q1 + } + if eq(zz, 3) { + X := H0 + Y := H1 + } + + index := sub(index, 1) + zz := 1 + zzz := 1 + + for { + + } gt(minus_1, index) { + index := sub(index, 1) + } { + // inlined EcZZ_Dbl + let T1 := mulmod(2, Y, p) //U = 2*Y1, y free + let T2 := mulmod(T1, T1, p) // V=U^2 + let T3 := mulmod(X, T2, p) // S = X1*V + T1 := mulmod(T1, T2, p) // W=UV + let T4 := mulmod( + 3, + mulmod(addmod(X, sub(p, zz), p), addmod(X, zz, p), p), + p + ) //M=3*(X1-ZZ1)*(X1+ZZ1) + zzz := mulmod(T1, zzz, p) //zzz3=W*zzz1 + zz := mulmod(T2, zz, p) //zz3=V*ZZ1, V free + + X := addmod(mulmod(T4, T4, p), mulmod(minus_2, T3, p), p) //X3=M^2-2S + //T2:=mulmod(T4,addmod(T3, sub(p, X),p),p)//M(S-X3) + T2 := mulmod(T4, addmod(X, sub(p, T3), p), p) //-M(S-X3)=M(X3-S) + + //Y:= addmod(T2, sub(p, mulmod(T1, Y ,p)),p )//Y3= M(S-X3)-W*Y1 + Y := addmod(mulmod(T1, Y, p), T2, p) //-Y3= W*Y1-M(S-X3), we replace Y by -Y to avoid a sub in ecAdd + + { + //value of dibit + T4 := add( + shl(1, and(shr(index, scalar_v), 1)), + and(shr(index, scalar_u), 1) + ) + + if iszero(T4) { + Y := sub(p, Y) //restore the -Y inversion + continue + } // if T4!=0 + + if eq(T4, 1) { + T1 := gx + T2 := gy + } + if eq(T4, 2) { + T1 := Q0 + T2 := Q1 + } + if eq(T4, 3) { + T1 := H0 + T2 := H1 + } + if eq(zz, 0) { + X := T1 + Y := T2 + zz := 1 + zzz := 1 + continue + } + // inlined EcZZ_AddN + + //T3:=sub(p, Y) + //T3:=Y + let y2 := addmod(mulmod(T2, zzz, p), Y, p) //R + T2 := addmod(mulmod(T1, zz, p), sub(p, X), p) //P + + //special extremely rare case accumulator where EcAdd is replaced by EcDbl, no need to optimize this + //todo : construct edge vector case + if eq(y2, 0) { + if eq(T2, 0) { + T1 := mulmod(minus_2, Y, p) //U = 2*Y1, y free + T2 := mulmod(T1, T1, p) // V=U^2 + T3 := mulmod(X, T2, p) // S = X1*V + + let TT1 := mulmod(T1, T2, p) // W=UV + y2 := addmod(X, zz, p) + TT1 := addmod(X, sub(p, zz), p) + y2 := mulmod(y2, TT1, p) //(X-ZZ)(X+ZZ) + T4 := mulmod(3, y2, p) //M + + zzz := mulmod(TT1, zzz, p) //zzz3=W*zzz1 + zz := mulmod(T2, zz, p) //zz3=V*ZZ1, V free + + X := addmod( + mulmod(T4, T4, p), + mulmod(minus_2, T3, p), + p + ) //X3=M^2-2S + T2 := mulmod(T4, addmod(T3, sub(p, X), p), p) //M(S-X3) + + Y := addmod(T2, mulmod(T1, Y, p), p) //Y3= M(S-X3)-W*Y1 + + continue + } + } + + T4 := mulmod(T2, T2, p) //PP + let TT1 := mulmod(T4, T2, p) //PPP, this one could be spared, but adding this register spare gas + zz := mulmod(zz, T4, p) + zzz := mulmod(zzz, TT1, p) //zz3=V*ZZ1 + let TT2 := mulmod(X, T4, p) + T4 := addmod( + addmod(mulmod(y2, y2, p), sub(p, TT1), p), + mulmod(minus_2, TT2, p), + p + ) + Y := addmod( + mulmod(addmod(TT2, sub(p, T4), p), y2, p), + mulmod(Y, TT1, p), + p + ) + + X := T4 + } + } //end loop + mstore(add(T, 0x60), zz) + //(X,Y)=ecZZ_SetAff(X,Y,zz, zzz); + //T[0] = inverseModp_Hard(T[0], p); //1/zzz, inline modular inversion using precompile: + // Define length of base, exponent and modulus. 0x20 == 32 bytes + mstore(T, 0x20) + mstore(add(T, 0x20), 0x20) + mstore(add(T, 0x40), 0x20) + // Define variables base, exponent and modulus + //mstore(add(pointer, 0x60), u) + mstore(add(T, 0x80), minus_2) + mstore(add(T, 0xa0), p) + + // Call the precompiled contract 0x05 = ModExp + if iszero(staticcall(14000, 0x05, T, 0xc0, T, 0x20)) { + revert(0, 0) + } + + //Y:=mulmod(Y,zzz,p)//Y/zzz + //zz :=mulmod(zz, mload(T),p) //1/z + //zz:= mulmod(zz,zz,p) //1/zz + X := mulmod(X, mload(T), p) //X/zz + } //end assembly + } //end unchecked + + return X; + } + + //8 dimensions Shamir's trick, using precomputations stored in Shamir8, stored as Bytecode of an external + //contract at given address dataPointer + //(thx to Lakhdar https://github.com/Kelvyne for EVM storage explanations and tricks) + // the external tool to generate tables from public key is in the /sage directory + function ecZZ_mulmuladd_S8_extcode( + uint256 scalar_u, + uint256 scalar_v, + address dataPointer + ) internal view returns (uint256 X /*, uint Y*/) { + unchecked { + uint256 zz; // third and coordinates of the point + + uint256[6] memory T; + zz = 256; //start index + + while (T[0] == 0) { + zz = zz - 1; + //tbd case of msb octobit is null + T[0] = + 64 * + (128 * + ((scalar_v >> zz) & 1) + + 64 * + ((scalar_v >> (zz - 64)) & 1) + + 32 * + ((scalar_v >> (zz - 128)) & 1) + + 16 * + ((scalar_v >> (zz - 192)) & 1) + + 8 * + ((scalar_u >> zz) & 1) + + 4 * + ((scalar_u >> (zz - 64)) & 1) + + 2 * + ((scalar_u >> (zz - 128)) & 1) + + ((scalar_u >> (zz - 192)) & 1)); + } + assembly { + extcodecopy(dataPointer, T, mload(T), 64) + + X := mload(T) + let Y := mload(add(T, 32)) + let zzz := 1 + zz := 1 + + //loop over 1/4 of scalars thx to Shamir's trick over 8 points + for { + let index := 254 + } gt(index, 191) { + index := add(index, 191) + } { + { + let TT1 := mulmod(2, Y, p) //U = 2*Y1, y free + let T2 := mulmod(TT1, TT1, p) // V=U^2 + let T3 := mulmod(X, T2, p) // S = X1*V + let T1 := mulmod(TT1, T2, p) // W=UV + let T4 := mulmod( + 3, + mulmod( + addmod(X, sub(p, zz), p), + addmod(X, zz, p), + p + ), + p + ) //M=3*(X1-ZZ1)*(X1+ZZ1) + zzz := mulmod(T1, zzz, p) //zzz3=W*zzz1 + zz := mulmod(T2, zz, p) //zz3=V*ZZ1, V free + + X := addmod( + mulmod(T4, T4, p), + mulmod(minus_2, T3, p), + p + ) //X3=M^2-2S + //T2:=mulmod(T4,addmod(T3, sub(p, X),p),p)//M(S-X3) + let T5 := mulmod(T4, addmod(X, sub(p, T3), p), p) //-M(S-X3)=M(X3-S) + + //Y:= addmod(T2, sub(p, mulmod(T1, Y ,p)),p )//Y3= M(S-X3)-W*Y1 + Y := addmod(mulmod(T1, Y, p), T5, p) //-Y3= W*Y1-M(S-X3), we replace Y by -Y to avoid a sub in ecAdd + + /* compute element to access in precomputed table */ + } + { + let T4 := add( + shl(13, and(shr(index, scalar_v), 1)), + shl(9, and(shr(index, scalar_u), 1)) + ) + let index2 := sub(index, 64) + let T3 := add( + T4, + add( + shl(12, and(shr(index2, scalar_v), 1)), + shl(8, and(shr(index2, scalar_u), 1)) + ) + ) + let index3 := sub(index2, 64) + let T2 := add( + T3, + add( + shl(11, and(shr(index3, scalar_v), 1)), + shl(7, and(shr(index3, scalar_u), 1)) + ) + ) + index := sub(index3, 64) + let T1 := add( + T2, + add( + shl(10, and(shr(index, scalar_v), 1)), + shl(6, and(shr(index, scalar_u), 1)) + ) + ) + + //index:=add(index,192), restore index, interleaved with loop + + //tbd: check validity of formulae with (0,1) to remove conditional jump + if iszero(T1) { + Y := sub(p, Y) + + continue + } + extcodecopy(dataPointer, T, T1, 64) + } + + { + /* Access to precomputed table using extcodecopy hack */ + + // inlined EcZZ_AddN + if iszero(zz) { + X := mload(T) + Y := mload(add(T, 32)) + zz := 1 + zzz := 1 + + continue + } + + let y2 := addmod( + mulmod(mload(add(T, 32)), zzz, p), + Y, + p + ) + let T2 := addmod(mulmod(mload(T), zz, p), sub(p, X), p) + + //special case ecAdd(P,P)=EcDbl + if eq(y2, 0) { + if eq(T2, 0) { + let T1 := mulmod(minus_2, Y, p) //U = 2*Y1, y free + T2 := mulmod(T1, T1, p) // V=U^2 + let T3 := mulmod(X, T2, p) // S = X1*V + + let TT1 := mulmod(T1, T2, p) // W=UV + y2 := addmod(X, zz, p) + TT1 := addmod(X, sub(p, zz), p) + y2 := mulmod(y2, TT1, p) //(X-ZZ)(X+ZZ) + let T4 := mulmod(3, y2, p) //M + + zzz := mulmod(TT1, zzz, p) //zzz3=W*zzz1 + zz := mulmod(T2, zz, p) //zz3=V*ZZ1, V free + + X := addmod( + mulmod(T4, T4, p), + mulmod(minus_2, T3, p), + p + ) //X3=M^2-2S + T2 := mulmod(T4, addmod(T3, sub(p, X), p), p) //M(S-X3) + + Y := addmod(T2, mulmod(T1, Y, p), p) //Y3= M(S-X3)-W*Y1 + + continue + } + } + + let T4 := mulmod(T2, T2, p) + let T1 := mulmod(T4, T2, p) // + zz := mulmod(zz, T4, p) + //zzz3=V*ZZ1 + zzz := mulmod(zzz, T1, p) // W=UV/ + let zz1 := mulmod(X, T4, p) + X := addmod( + addmod(mulmod(y2, y2, p), sub(p, T1), p), + mulmod(minus_2, zz1, p), + p + ) + Y := addmod( + mulmod(addmod(zz1, sub(p, X), p), y2, p), + mulmod(Y, T1, p), + p + ) + } + } //end loop + mstore(add(T, 0x60), zz) + + //(X,Y)=ecZZ_SetAff(X,Y,zz, zzz); + //T[0] = inverseModp_Hard(T[0], p); //1/zzz, inline modular inversion using precompile: + // Define length of base, exponent and modulus. 0x20 == 32 bytes + mstore(T, 0x20) + mstore(add(T, 0x20), 0x20) + mstore(add(T, 0x40), 0x20) + // Define variables base, exponent and modulus + //mstore(add(pointer, 0x60), u) + mstore(add(T, 0x80), minus_2) + mstore(add(T, 0xa0), p) + + // Call the precompiled contract 0x05 = ModExp + if iszero(staticcall(14000, 0x05, T, 0xc0, T, 0x20)) { + revert(0, 0) + } + + zz := mload(T) + X := mulmod(X, zz, p) //X/zz + } + } //end unchecked + } + + //8 dimensions Shamir's trick, using precomputations stored in Shamir8, stored as Bytecode of an external + //contract at given address dataPointer + //(thx to Lakhdar https://github.com/Kelvyne for EVM storage explanations and tricks) + // the external tool to generate tables from public key is in the /sage directory + function ecZZ_mulmuladd_S8_hackmem( + uint256 scalar_u, + uint256 scalar_v, + uint256 dataPointer + ) internal returns (uint256 X /*, uint Y*/) { + unchecked { + uint256 zz; // third and coordinates of the point + + uint256[6] memory T; + zz = 256; //start index + + while (T[0] == 0) { + zz = zz - 1; + //tbd case of msb octobit is null + T[0] = + 64 * + (128 * + ((scalar_v >> zz) & 1) + + 64 * + ((scalar_v >> (zz - 64)) & 1) + + 32 * + ((scalar_v >> (zz - 128)) & 1) + + 16 * + ((scalar_v >> (zz - 192)) & 1) + + 8 * + ((scalar_u >> zz) & 1) + + 4 * + ((scalar_u >> (zz - 64)) & 1) + + 2 * + ((scalar_u >> (zz - 128)) & 1) + + ((scalar_u >> (zz - 192)) & 1)); + } + assembly { + extcodecopy(dataPointer, T, mload(T), 64) + + X := mload(T) + let Y := mload(add(T, 32)) + let zzz := 1 + zz := 1 + + //loop over 1/4 of scalars thx to Shamir's trick over 8 points + for { + let index := 254 + } gt(index, 191) { + index := add(index, 191) + } { + { + let TT1 := mulmod(2, Y, p) //U = 2*Y1, y free + let T2 := mulmod(TT1, TT1, p) // V=U^2 + let T3 := mulmod(X, T2, p) // S = X1*V + let T1 := mulmod(TT1, T2, p) // W=UV + let T4 := mulmod( + 3, + mulmod( + addmod(X, sub(p, zz), p), + addmod(X, zz, p), + p + ), + p + ) //M=3*(X1-ZZ1)*(X1+ZZ1) + zzz := mulmod(T1, zzz, p) //zzz3=W*zzz1 + zz := mulmod(T2, zz, p) //zz3=V*ZZ1, V free + + X := addmod( + mulmod(T4, T4, p), + mulmod(minus_2, T3, p), + p + ) //X3=M^2-2S + //T2:=mulmod(T4,addmod(T3, sub(p, X),p),p)//M(S-X3) + let T5 := mulmod(T4, addmod(X, sub(p, T3), p), p) //-M(S-X3)=M(X3-S) + + //Y:= addmod(T2, sub(p, mulmod(T1, Y ,p)),p )//Y3= M(S-X3)-W*Y1 + Y := addmod(mulmod(T1, Y, p), T5, p) //-Y3= W*Y1-M(S-X3), we replace Y by -Y to avoid a sub in ecAdd + + /* compute element to access in precomputed table */ + } + { + let T4 := add( + shl(13, and(shr(index, scalar_v), 1)), + shl(9, and(shr(index, scalar_u), 1)) + ) + let index2 := sub(index, 64) + let T3 := add( + T4, + add( + shl(12, and(shr(index2, scalar_v), 1)), + shl(8, and(shr(index2, scalar_u), 1)) + ) + ) + let index3 := sub(index2, 64) + let T2 := add( + T3, + add( + shl(11, and(shr(index3, scalar_v), 1)), + shl(7, and(shr(index3, scalar_u), 1)) + ) + ) + index := sub(index3, 64) + let T1 := add( + T2, + add( + shl(10, and(shr(index, scalar_v), 1)), + shl(6, and(shr(index, scalar_u), 1)) + ) + ) + + //index:=add(index,192), restore index, interleaved with loop + + //tbd: check validity of formulae with (0,1) to remove conditional jump + if iszero(T1) { + Y := sub(p, Y) + + continue + } + codecopy(T, add(dataPointer, T1), 64) + } + + { + /* Access to precomputed table using extcodecopy hack */ + + // inlined EcZZ_AddN + if iszero(zz) { + X := mload(T) + Y := mload(add(T, 32)) + zz := 1 + zzz := 1 + + continue + } + + let y2 := addmod( + mulmod(mload(add(T, 32)), zzz, p), + Y, + p + ) + let T2 := addmod(mulmod(mload(T), zz, p), sub(p, X), p) + + //special case ecAdd(P,P)=EcDbl + if eq(y2, 0) { + if eq(T2, 0) { + let T1 := mulmod(minus_2, Y, p) //U = 2*Y1, y free + T2 := mulmod(T1, T1, p) // V=U^2 + let T3 := mulmod(X, T2, p) // S = X1*V + + let TT1 := mulmod(T1, T2, p) // W=UV + y2 := addmod(X, zz, p) + TT1 := addmod(X, sub(p, zz), p) + y2 := mulmod(y2, TT1, p) //(X-ZZ)(X+ZZ) + let T4 := mulmod(3, y2, p) //M + + zzz := mulmod(TT1, zzz, p) //zzz3=W*zzz1 + zz := mulmod(T2, zz, p) //zz3=V*ZZ1, V free + + X := addmod( + mulmod(T4, T4, p), + mulmod(minus_2, T3, p), + p + ) //X3=M^2-2S + T2 := mulmod(T4, addmod(T3, sub(p, X), p), p) //M(S-X3) + + Y := addmod(T2, mulmod(T1, Y, p), p) //Y3= M(S-X3)-W*Y1 + + continue + } + } + + let T4 := mulmod(T2, T2, p) + let T1 := mulmod(T4, T2, p) // + zz := mulmod(zz, T4, p) + //zzz3=V*ZZ1 + zzz := mulmod(zzz, T1, p) // W=UV/ + let zz1 := mulmod(X, T4, p) + X := addmod( + addmod(mulmod(y2, y2, p), sub(p, T1), p), + mulmod(minus_2, zz1, p), + p + ) + Y := addmod( + mulmod(addmod(zz1, sub(p, X), p), y2, p), + mulmod(Y, T1, p), + p + ) + } + } //end loop + mstore(add(T, 0x60), zz) + + //(X,Y)=ecZZ_SetAff(X,Y,zz, zzz); + //T[0] = inverseModp_Hard(T[0], p); //1/zzz, inline modular inversion using precompile: + // Define length of base, exponent and modulus. 0x20 == 32 bytes + mstore(T, 0x20) + mstore(add(T, 0x20), 0x20) + mstore(add(T, 0x40), 0x20) + // Define variables base, exponent and modulus + //mstore(add(pointer, 0x60), u) + mstore(add(T, 0x80), minus_2) + mstore(add(T, 0xa0), p) + + // Call the precompiled contract 0x05 = ModExp + if iszero(call(not(0), 0x05, 0, T, 0xc0, T, 0x20)) { + revert(0, 0) + } + + zz := mload(T) + X := mulmod(X, zz, p) //X/zz + } + } //end unchecked + } + + // improving the extcodecopy trick : append array at end of contract + function ecZZ_mulmuladd_S8_hackmem_back( + uint256 scalar_u, + uint256 scalar_v, + uint256 dataPointer + ) internal returns (uint256 X /*, uint Y*/) { + uint256 zz; // third and coordinates of the point + + uint256[6] memory T; + zz = 256; //start index + + unchecked { + while (T[0] == 0) { + zz = zz - 1; + //tbd case of msb octobit is null + T[0] = + 64 * + (128 * + ((scalar_v >> zz) & 1) + + 64 * + ((scalar_v >> (zz - 64)) & 1) + + 32 * + ((scalar_v >> (zz - 128)) & 1) + + 16 * + ((scalar_v >> (zz - 192)) & 1) + + 8 * + ((scalar_u >> zz) & 1) + + 4 * + ((scalar_u >> (zz - 64)) & 1) + + 2 * + ((scalar_u >> (zz - 128)) & 1) + + ((scalar_u >> (zz - 192)) & 1)); + } + assembly { + codecopy(T, add(mload(T), dataPointer), 64) + X := mload(T) + let Y := mload(add(T, 32)) + let zzz := 1 + zz := 1 + + //loop over 1/4 of scalars thx to Shamir's trick over 8 points + for { + let index := 254 + } gt(index, 191) { + index := add(index, 191) + } { + let T1 := mulmod(2, Y, p) //U = 2*Y1, y free + let T2 := mulmod(T1, T1, p) // V=U^2 + let T3 := mulmod(X, T2, p) // S = X1*V + T1 := mulmod(T1, T2, p) // W=UV + let T4 := mulmod( + 3, + mulmod(addmod(X, sub(p, zz), p), addmod(X, zz, p), p), + p + ) //M=3*(X1-ZZ1)*(X1+ZZ1) + zzz := mulmod(T1, zzz, p) //zzz3=W*zzz1 + zz := mulmod(T2, zz, p) //zz3=V*ZZ1, V free + + X := addmod(mulmod(T4, T4, p), mulmod(minus_2, T3, p), p) //X3=M^2-2S + //T2:=mulmod(T4,addmod(T3, sub(p, X),p),p)//M(S-X3) + T2 := mulmod(T4, addmod(X, sub(p, T3), p), p) //-M(S-X3)=M(X3-S) + + //Y:= addmod(T2, sub(p, mulmod(T1, Y ,p)),p )//Y3= M(S-X3)-W*Y1 + Y := addmod(mulmod(T1, Y, p), T2, p) //-Y3= W*Y1-M(S-X3), we replace Y by -Y to avoid a sub in ecAdd + + /* compute element to access in precomputed table */ + + T4 := add( + shl(13, and(shr(index, scalar_v), 1)), + shl(9, and(shr(index, scalar_u), 1)) + ) + index := sub(index, 64) + T4 := add( + T4, + add( + shl(12, and(shr(index, scalar_v), 1)), + shl(8, and(shr(index, scalar_u), 1)) + ) + ) + index := sub(index, 64) + T4 := add( + T4, + add( + shl(11, and(shr(index, scalar_v), 1)), + shl(7, and(shr(index, scalar_u), 1)) + ) + ) + index := sub(index, 64) + T4 := add( + T4, + add( + shl(10, and(shr(index, scalar_v), 1)), + shl(6, and(shr(index, scalar_u), 1)) + ) + ) + //index:=add(index,192), restore index, interleaved with loop + + //tbd: check validity of formulae with (0,1) to remove conditional jump + if iszero(T4) { + Y := sub(p, Y) + + continue + } + { + /* Access to precomputed table using codecopy hack */ + codecopy(T, add(T4, dataPointer), 64) + + // inlined EcZZ_AddN + + let y2 := addmod( + mulmod(mload(add(T, 32)), zzz, p), + Y, + p + ) + T2 := addmod(mulmod(mload(T), zz, p), sub(p, X), p) + T4 := mulmod(T2, T2, p) + T1 := mulmod(T4, T2, p) + T2 := mulmod(zz, T4, p) // W=UV + zzz := mulmod(zzz, T1, p) //zz3=V*ZZ1 + let zz1 := mulmod(X, T4, p) + T4 := addmod( + addmod(mulmod(y2, y2, p), sub(p, T1), p), + mulmod(minus_2, zz1, p), + p + ) + Y := addmod( + mulmod(addmod(zz1, sub(p, T4), p), y2, p), + mulmod(Y, T1, p), + p + ) + zz := T2 + X := T4 + } + } //end loop + mstore(add(T, 0x60), zz) + + //(X,Y)=ecZZ_SetAff(X,Y,zz, zzz); + //T[0] = inverseModp_Hard(T[0], p); //1/zzz, inline modular inversion using precompile: + // Define length of base, exponent and modulus. 0x20 == 32 bytes + mstore(T, 0x20) + mstore(add(T, 0x20), 0x20) + mstore(add(T, 0x40), 0x20) + // Define variables base, exponent and modulus + //mstore(add(pointer, 0x60), u) + mstore(add(T, 0x80), minus_2) + mstore(add(T, 0xa0), p) + + // Call the precompiled contract 0x05 = ModExp + if iszero(call(not(0), 0x05, 0, T, 0xc0, T, 0x20)) { + revert(0, 0) + } + + zz := mload(T) + X := mulmod(X, zz, p) //X/zz + } + } //end unchecked + } + + function sanity_check( + uint256[2] memory rs, + uint256[2] memory Q + ) internal pure returns (bool) { + return + ((rs[0] == 0 || rs[0] >= n || rs[1] == 0 || rs[1] >= n) || + !ecAff_isOnCurve(Q[0], Q[1]) || + rs[1] > P256_N_DIV_2) + ? false + : true; + } + + /** + * @dev ECDSA verification, given , signature, and public key. + */ + function ecdsa_verify( + bytes32 message, + uint256[2] memory rs, + uint256[2] memory Q + ) internal view returns (bool) { + uint256 sInv = FCL_nModInv(rs[1]); + + uint256 scalar_u = mulmod(uint256(message), sInv, n); + uint256 scalar_v = mulmod(rs[0], sInv, n); + uint256 x1; + + x1 = ecZZ_mulmuladd_S_asm(Q[0], Q[1], scalar_u, scalar_v); + + assembly { + x1 := addmod(x1, sub(n, mload(rs)), n) + } + //return true; + return x1 == 0; + } + + /** + * @dev ECDSA verification using a precomputed table of multiples of P and Q stored in contract at address Shamir8 + * generation of contract bytecode for precomputations is done using sagemath code + * (see sage directory, WebAuthn_precompute.sage) + */ + + function ecdsa_precomputed_verify( + bytes32 message, + uint256[2] memory rs + ) internal view returns (bool) { + if (rs[0] == 0 || rs[0] >= n || rs[1] == 0) { + return false; + } + /* Q is pushed via bytecode assumed to be correct + if (!isOnCurve(Q[0], Q[1])) { + return false; + }*/ + + uint256 sInv = FCL_nModInv(rs[1]); + //uint sInv =2; + + uint256 X; + + //Shamir 8 dimensions + X = ecZZ_mulmuladd_S8_extcode( + mulmod(uint256(message), sInv, n), + mulmod(rs[0], sInv, n), + 0x0000000000000000000000000000000000001234 + ); + + assembly { + X := addmod(X, sub(n, mload(rs)), n) + } + + return X == 0; + } //end ecdsa_precomputed_verify() + + /** + * @dev ECDSA verification using a precomputed table of multiples of P and Q appended at end of contract at address endcontract + * generation of contract bytecode for precomputations is done using sagemath code + * (see sage directory, WebAuthn_precompute.sage) + */ + + function ecdsa_precomputed_hackmem( + bytes32 message, + uint256[2] calldata rs, + uint256 endcontract + ) internal returns (bool) { + if (rs[0] == 0 || rs[0] >= n || rs[1] == 0) { + return false; + } + /* Q is pushed via bytecode assumed to be correct + if (!isOnCurve(Q[0], Q[1])) { + return false; + }*/ + + uint256 sInv = FCL_nModInv(rs[1]); + uint256 X; + + //Shamir 8 dimensions + X = ecZZ_mulmuladd_S8_hackmem( + mulmod(uint256(message), sInv, n), + mulmod(rs[0], sInv, n), + endcontract + ); + + assembly { + X := addmod(X, sub(n, calldataload(rs)), n) + } + return X == 0; + } //end ecdsa_precomputed_verify() +} //EOF diff --git a/contracts/facets/verification/secp256r1/utils/LibSecp256r1.sol b/contracts/facets/verification/secp256r1/utils/LibSecp256r1.sol new file mode 100644 index 0000000..b2ad086 --- /dev/null +++ b/contracts/facets/verification/secp256r1/utils/LibSecp256r1.sol @@ -0,0 +1,376 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity 0.8.21; + +// Heavily inspired from +// https://github.com/maxrobot/elliptic-solidity/blob/master/contracts/Secp256r1.sol +// https://github.com/tdrerup/elliptic-curve-solidity/blob/master/contracts/curves/EllipticCurve.sol +// modified to use precompile 0x05 modexp +// and modified jacobian double +// optimisations to avoid to an from from affine and jacobian coordinates + +// Additional Elliptic curve Public key / Signature validation added by +// David Yonjun Kim (@Powerstream3604) + +struct JPoint { + uint256 x; + uint256 y; + uint256 z; +} + +library LibSecp256r1 { + uint256 constant gx = + 0x6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296; + uint256 constant gy = + 0x4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5; + uint256 public constant pp = + 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF; + + uint256 public constant nn = + 0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551; + uint256 constant a = + 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC; + uint256 constant b = + 0x5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B; + uint256 constant MOST_SIGNIFICANT = + 0xc000000000000000000000000000000000000000000000000000000000000000; + + /* + * Verify + * @description - verifies that a public key has signed a given message + * @param Q - public key coordinates X & Y + * @param R - signature half R + * @param S - signature half S + * @param input - hashed message + */ + function Verify( + uint256[2] memory q, + uint r, + uint s, + uint e + ) internal view returns (bool) { + if (q[0] > pp - 1 || q[1] > pp - 1) { + return false; + } + if (r == 0 || s == 0 || r >= nn || s >= nn) { + return false; + } + if ( + mulmod(q[1], q[1], pp) != + addmod( + addmod( + mulmod(q[0], mulmod(q[0], q[0], pp), pp), + mulmod(a, q[0], pp), + pp + ), + b, + pp + ) + ) { + return false; + } + + JPoint[16] memory points = _preComputeJacobianPoints(q); + return VerifyWithPrecompute(points, r, s, e); + } + + function VerifyWithPrecompute( + JPoint[16] memory points, + uint r, + uint s, + uint e + ) internal view returns (bool) { + if (r == 0 || s == 0 || r >= nn || s >= nn) { + return false; + } + + uint w = _primemod(s, nn); + + uint u1 = mulmod(e, w, nn); + uint u2 = mulmod(r, w, nn); + + uint x; + uint y; + + (x, y) = ShamirMultJacobian(points, u1, u2); + return (x == r); + } + + /* + * Strauss Shamir trick for EC multiplication + * https://stackoverflow.com/questions/50993471/ec-scalar-multiplication-with-strauss-shamir-method + * we optimise on this a bit to do with 2 bits at a time rather than a single bit + * the individual points for a single pass are precomputed + * overall this reduces the number of additions while keeping the same number of doublings + */ + function ShamirMultJacobian( + JPoint[16] memory points, + uint u1, + uint u2 + ) internal view returns (uint, uint) { + uint x = 0; + uint y = 0; + uint z = 0; + uint bits = 128; + uint index = 0; + + while (bits > 0) { + if (z > 0) { + (x, y, z) = _modifiedJacobianDouble(x, y, z); + (x, y, z) = _modifiedJacobianDouble(x, y, z); + } + index = + ((u1 & MOST_SIGNIFICANT) >> 252) | + ((u2 & MOST_SIGNIFICANT) >> 254); + if (index > 0) { + (x, y, z) = _jAdd( + x, + y, + z, + points[index].x, + points[index].y, + points[index].z + ); + } + u1 <<= 2; + u2 <<= 2; + bits--; + } + (x, y) = _affineFromJacobian(x, y, z); + return (x, y); + } + + function _preComputeJacobianPoints( + uint256[2] memory q + ) internal pure returns (JPoint[16] memory points) { + points[0] = JPoint(0, 0, 0); + points[1] = JPoint(q[0], q[1], 1); // u2 + points[2] = _jPointDouble(points[1]); + points[3] = _jPointAdd(points[1], points[2]); + + points[4] = JPoint(gx, gy, 1); // u1Points[1] + points[5] = _jPointAdd(points[4], points[1]); + points[6] = _jPointAdd(points[4], points[2]); + points[7] = _jPointAdd(points[4], points[3]); + + points[8] = _jPointDouble(points[4]); // u1Points[2] + points[9] = _jPointAdd(points[8], points[1]); + points[10] = _jPointAdd(points[8], points[2]); + points[11] = _jPointAdd(points[8], points[3]); + + points[12] = _jPointAdd(points[4], points[8]); // u1Points[3] + points[13] = _jPointAdd(points[12], points[1]); + points[14] = _jPointAdd(points[12], points[2]); + points[15] = _jPointAdd(points[12], points[3]); + } + + function _jPointAdd( + JPoint memory p1, + JPoint memory p2 + ) internal pure returns (JPoint memory) { + uint x; + uint y; + uint z; + (x, y, z) = _jAdd(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z); + return JPoint(x, y, z); + } + + function _jPointDouble( + JPoint memory p + ) internal pure returns (JPoint memory) { + uint x; + uint y; + uint z; + (x, y, z) = _modifiedJacobianDouble(p.x, p.y, p.z); + return JPoint(x, y, z); + } + + /* _affineFromJacobian + * @desription returns affine coordinates from a jacobian input follows + * golang elliptic/crypto library + */ + function _affineFromJacobian( + uint x, + uint y, + uint z + ) internal view returns (uint ax, uint ay) { + if (z == 0) { + return (0, 0); + } + + uint zinv = _primemod(z, pp); + uint zinvsq = mulmod(zinv, zinv, pp); + + ax = mulmod(x, zinvsq, pp); + ay = mulmod(y, mulmod(zinvsq, zinv, pp), pp); + } + + /* + * _jAdd + * @description performs Jacobian addition as defined below: + * http://www.hyperelliptic.org/EFD/g1p/data/shortw/jacobian/addition/add-2007-bl + */ + function _jAdd( + uint p1, + uint p2, + uint p3, + uint q1, + uint q2, + uint q3 + ) internal pure returns (uint r1, uint r2, uint r3) { + if (p3 == 0) { + r1 = q1; + r2 = q2; + r3 = q3; + + return (r1, r2, r3); + } else if (q3 == 0) { + r1 = p1; + r2 = p2; + r3 = p3; + + return (r1, r2, r3); + } + + assembly { + let + pd + := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF + let z1z1 := mulmod(p3, p3, pd) // Z1Z1 = Z1^2 + let z2z2 := mulmod(q3, q3, pd) // Z2Z2 = Z2^2 + + let u1 := mulmod(p1, z2z2, pd) // U1 = X1*Z2Z2 + let u2 := mulmod(q1, z1z1, pd) // U2 = X2*Z1Z1 + + let s1 := mulmod(p2, mulmod(z2z2, q3, pd), pd) // S1 = Y1*Z2*Z2Z2 + let s2 := mulmod(q2, mulmod(z1z1, p3, pd), pd) // S2 = Y2*Z1*Z1Z1 + + let p3q3 := addmod(p3, q3, pd) + + if lt(u2, u1) { + u2 := add(pd, u2) // u2 = u2+pd + } + let h := sub(u2, u1) // H = U2-U1 + + let i := mulmod(0x02, h, pd) + i := mulmod(i, i, pd) // I = (2*H)^2 + + let j := mulmod(h, i, pd) // J = H*I + if lt(s2, s1) { + s2 := add(pd, s2) // u2 = u2+pd + } + let rr := mulmod(0x02, sub(s2, s1), pd) // r = 2*(S2-S1) + r1 := mulmod(rr, rr, pd) // X3 = R^2 + + let v := mulmod(u1, i, pd) // V = U1*I + let j2v := addmod(j, mulmod(0x02, v, pd), pd) + if lt(r1, j2v) { + r1 := add(pd, r1) // X3 = X3+pd + } + r1 := sub(r1, j2v) + + // Y3 = r*(V-X3)-2*S1*J + let s12j := mulmod(mulmod(0x02, s1, pd), j, pd) + + if lt(v, r1) { + v := add(pd, v) + } + r2 := mulmod(rr, sub(v, r1), pd) + + if lt(r2, s12j) { + r2 := add(pd, r2) + } + r2 := sub(r2, s12j) + + // Z3 = ((Z1+Z2)^2-Z1Z1-Z2Z2)*H + z1z1 := addmod(z1z1, z2z2, pd) + j2v := mulmod(p3q3, p3q3, pd) + if lt(j2v, z1z1) { + j2v := add(pd, j2v) + } + r3 := mulmod(sub(j2v, z1z1), h, pd) + } + return (r1, r2, r3); + } + + // Point doubling on the modified jacobian coordinates + // http://point-at-infinity.org/ecc/Prime_Curve_Modified_Jacobian_Coordinates.html + function _modifiedJacobianDouble( + uint x, + uint y, + uint z + ) internal pure returns (uint x3, uint y3, uint z3) { + if (y == 0) return (0, 0, 0); + assembly { + let + pd + := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF + let z2 := mulmod(z, z, pd) + let az4 := mulmod( + 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC, + mulmod(z2, z2, pd), + pd + ) + let y2 := mulmod(y, y, pd) + let s := mulmod(0x04, mulmod(x, y2, pd), pd) + let u := mulmod(0x08, mulmod(y2, y2, pd), pd) + let m := addmod(mulmod(0x03, mulmod(x, x, pd), pd), az4, pd) + let twos := mulmod(0x02, s, pd) + let m2 := mulmod(m, m, pd) + if lt(m2, twos) { + m2 := add(pd, m2) + } + x3 := sub(m2, twos) + if lt(s, x3) { + s := add(pd, s) + } + y3 := mulmod(m, sub(s, x3), pd) + if lt(y3, u) { + y3 := add(pd, y3) + } + y3 := sub(y3, u) + z3 := mulmod(0x02, mulmod(y, z, pd), pd) + } + } + + // Fermats little theorem https://en.wikipedia.org/wiki/Fermat%27s_little_theorem + // a^(p-1) = 1 mod p + // a^(-1) ≅ a^(p-2) (mod p) + // we then use the precompile bigModExp to compute a^(-1) + function _primemod(uint value, uint p) internal view returns (uint ret) { + ret = modexp(value, p - 2, p); + return ret; + } + + // Wrapper for built-in BigNumber_modexp (contract 0x5) as described here. https://github.com/ethereum/EIPs/pull/198 + function modexp( + uint _base, + uint _exp, + uint _mod + ) internal view returns (uint ret) { + // bigModExp(_base, _exp, _mod); + assembly { + if gt(_base, _mod) { + _base := mod(_base, _mod) + } + // Free memory pointer is always stored at 0x40 + let freemem := mload(0x40) + + mstore(freemem, 0x20) + mstore(add(freemem, 0x20), 0x20) + mstore(add(freemem, 0x40), 0x20) + + mstore(add(freemem, 0x60), _base) + mstore(add(freemem, 0x80), _exp) + mstore(add(freemem, 0xa0), _mod) + + let success := staticcall(14000, 0x5, freemem, 0xc0, freemem, 0x20) + switch success + case 0 { + revert(0x0, 0x0) + } + default { + ret := mload(freemem) + } + } + } +} diff --git a/contracts/infrastructure/DefaultFallbackHandler.sol b/contracts/infrastructure/DefaultFallbackHandler.sol new file mode 100644 index 0000000..2375d6b --- /dev/null +++ b/contracts/infrastructure/DefaultFallbackHandler.sol @@ -0,0 +1,159 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.21; + +import {IERC721Receiver} from "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol"; +import {IERC1155Receiver} from "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol"; +import {IERC777Recipient} from "@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol"; +import {BaseAccount} from "../aa-4337/core/BaseAccount.sol"; +import {DefaultLibDiamond} from "../libraries/DefaultLibDiamond.sol"; +import {IDiamondCut} from "../facets/base/interfaces/IDiamondCut.sol"; +import {IAccountFacet} from "../facets/interfaces/IAccountFacet.sol"; +import {IStorageLoupe} from "../facets/base/interfaces/IStorageLoupe.sol"; +import {IDiamondLoupe} from "../facets/base/interfaces/IDiamondLoupe.sol"; +import {IERC677Receiver} from "../interfaces/ERC/IERC677Receiver.sol"; +import {IERC165} from "../interfaces/ERC/IERC165.sol"; + +/** + * @title DefaultFallbackHandler + * @dev A default fallback handler for Barz + * @author David Yongjun Kim (@Powerstream3604) + */ +contract DefaultFallbackHandler is IDiamondLoupe { + /** + * @notice Sets the middleware diamond for Barz wallet as a fallback handler + * @dev This contract is also a diamond that holds the default facets to reduce gas cost for wallet activation. + * Within the constructor this conducts diamond cut to initially setup the diamond. This is a non-upgradeable contract + * @param _diamondCutFacet Address if diamond cut facet + * @param _accountFacet Address account facet + * @param _tokenReceiverFacet Address of token receiver facet + * @param _diamondLoupeFacet Address of diamond loupe facet + */ + constructor( + address _diamondCutFacet, + address _accountFacet, + address _tokenReceiverFacet, + address _diamondLoupeFacet + ) payable { + IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](4); + bytes4[] memory functionSelectors = new bytes4[](1); + functionSelectors[0] = IDiamondCut.diamondCut.selector; + + bytes4[] memory accountFunctionSelectors = new bytes4[](5); + accountFunctionSelectors[0] = IAccountFacet.execute.selector; + accountFunctionSelectors[1] = IAccountFacet.executeBatch.selector; + accountFunctionSelectors[2] = BaseAccount.validateUserOp.selector; + accountFunctionSelectors[3] = BaseAccount.getNonce.selector; + accountFunctionSelectors[4] = BaseAccount.entryPoint.selector; + + bytes4[] memory receiverFacetSelectors = new bytes4[](5); + receiverFacetSelectors[0] = IERC721Receiver.onERC721Received.selector; + receiverFacetSelectors[1] = IERC1155Receiver.onERC1155Received.selector; + receiverFacetSelectors[2] = IERC1155Receiver + .onERC1155BatchReceived + .selector; + receiverFacetSelectors[3] = IERC777Recipient.tokensReceived.selector; + receiverFacetSelectors[4] = IERC677Receiver.onTokenTransfer.selector; + + bytes4[] memory loupeFacetSelectors = new bytes4[](9); + loupeFacetSelectors[0] = IDiamondLoupe.facets.selector; + loupeFacetSelectors[1] = IDiamondLoupe.facetFunctionSelectors.selector; + loupeFacetSelectors[2] = IDiamondLoupe.facetAddresses.selector; + loupeFacetSelectors[3] = IDiamondLoupe.facetAddress.selector; + loupeFacetSelectors[4] = IERC165.supportsInterface.selector; + loupeFacetSelectors[5] = IStorageLoupe.facetsFromStorage.selector; + loupeFacetSelectors[6] = IStorageLoupe + .facetFunctionSelectorsFromStorage + .selector; + loupeFacetSelectors[7] = IStorageLoupe + .facetAddressesFromStorage + .selector; + loupeFacetSelectors[8] = IStorageLoupe.facetAddressFromStorage.selector; + + { + cut[0] = IDiamondCut.FacetCut({ + facetAddress: _diamondCutFacet, + action: IDiamondCut.FacetCutAction.Add, + functionSelectors: functionSelectors + }); + cut[1] = IDiamondCut.FacetCut({ + facetAddress: _accountFacet, + action: IDiamondCut.FacetCutAction.Add, + functionSelectors: accountFunctionSelectors + }); + cut[2] = IDiamondCut.FacetCut({ + facetAddress: _tokenReceiverFacet, + action: IDiamondCut.FacetCutAction.Add, + functionSelectors: receiverFacetSelectors + }); + cut[3] = IDiamondCut.FacetCut({ + facetAddress: _diamondLoupeFacet, + action: IDiamondCut.FacetCutAction.Add, + functionSelectors: loupeFacetSelectors + }); + + DefaultLibDiamond.diamondCut(cut, address(0), ""); + } + } + + /** + * @notice Returns the facet information of call facets registered to this diamond. + * @return facets_ The facet struct array including all facet information + */ + function facets() external view override returns (Facet[] memory facets_) { + DefaultLibDiamond.DiamondStorage storage ds = DefaultLibDiamond + .diamondStorage(); + uint256 numFacets = ds.facetAddresses.length; + facets_ = new Facet[](numFacets); + for (uint256 i; i < numFacets; ) { + address facetAddress_ = ds.facetAddresses[i]; + facets_[i].facetAddress = facetAddress_; + facets_[i].functionSelectors = ds + .facetFunctionSelectors[facetAddress_] + .functionSelectors; + unchecked { + ++i; + } + } + } + + /** + * @notice Gets all the function selectors provided by a facet. + * @param _facet The facet address. + * @return facetFunctionSelectors_ + */ + function facetFunctionSelectors( + address _facet + ) external view override returns (bytes4[] memory facetFunctionSelectors_) { + facetFunctionSelectors_ = DefaultLibDiamond + .diamondStorage() + .facetFunctionSelectors[_facet] + .functionSelectors; + } + + /** + * @notice Get all the facet addresses used by a diamond. + * @return facetAddresses_ + */ + function facetAddresses() + external + view + override + returns (address[] memory facetAddresses_) + { + facetAddresses_ = DefaultLibDiamond.diamondStorage().facetAddresses; + } + + /** @notice Gets the facet that supports the given selector. + * @dev If facet is not found return address(0). + * @param _functionSelector The function selector. + * @return facetAddress_ The facet address. + */ + function facetAddress( + bytes4 _functionSelector + ) external view override returns (address facetAddress_) { + facetAddress_ = DefaultLibDiamond + .diamondStorage() + .selectorToFacetAndPosition[_functionSelector] + .facetAddress; + } +} diff --git a/contracts/infrastructure/FacetRegistry.sol b/contracts/infrastructure/FacetRegistry.sol new file mode 100644 index 0000000..cda66c3 --- /dev/null +++ b/contracts/infrastructure/FacetRegistry.sol @@ -0,0 +1,129 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.21; + +import {Ownable2Step} from "@openzeppelin/contracts/access/Ownable2Step.sol"; +import {IFacetRegistry} from "./interfaces/IFacetRegistry.sol"; + +/** + * @title Facet Registry + * @dev Contract to keep track of facets & function selectors addable to user wallets + * @author David Yongjun Kim (@Powerstream3604) + */ +contract FacetRegistry is IFacetRegistry, Ownable2Step { + mapping(address => FacetRegistryConfig) private facets; + + /** + * @notice Transfers the ownership of the contract to the given owner + * @param _owner Address of owner who has access to initialize the default security variables for security manager + */ + constructor(address _owner) { + transferOwnership(_owner); + _transferOwnership(_owner); + } + + /** + * @dev Registers a facet and it's function selectors to registry + * @param _facet address of facet + * @param _facetSelectors list of function selectors of the facet + */ + function registerFacetFunctionSelectors( + address _facet, + bytes4[] calldata _facetSelectors + ) external override onlyOwner { + FacetRegistryConfig storage facetConfig = facets[_facet]; + for (uint256 i; i < _facetSelectors.length; ) { + if (facetConfig.info[_facetSelectors[i]].exists) + revert FacetRegistry__FacetSelectorAlreadyRegistered(); + + facetConfig.info[_facetSelectors[i]].exists = true; + facetConfig.info[_facetSelectors[i]].index = uint128( + facetConfig.selectors.length + ); + facetConfig.selectors.push(_facetSelectors[i]); + unchecked { + ++i; + } + } + emit FacetFunctionSelectorsRegistered(_facet, _facetSelectors); + } + + /** + * @dev Removes a registered facet and it's corresponding selectors from registry + * @param _facet address of facet + * @param _facetSelectors list of function selectors of the facet + */ + function removeFacetFunctionSelectors( + address _facet, + bytes4[] calldata _facetSelectors + ) external override onlyOwner { + FacetRegistryConfig storage facetConfig = facets[_facet]; + for (uint256 i; i < _facetSelectors.length; ) { + if (!facetConfig.info[_facetSelectors[i]].exists) + revert FacetRegistry__UnregisteredFacetSelector(); + + bytes4 lastSelector = facetConfig.selectors[ + facetConfig.selectors.length - 1 + ]; + if (_facetSelectors[i] != lastSelector) { + uint128 targetIndex = facetConfig + .info[_facetSelectors[i]] + .index; + facetConfig.selectors[targetIndex] = lastSelector; + facetConfig.info[lastSelector].index = targetIndex; + } + facetConfig.selectors.pop(); + delete facetConfig.info[_facetSelectors[i]]; + + unchecked { + ++i; + } + } + emit FacetFunctionSelectorsRemoved(_facet, _facetSelectors); + } + + /** + * @dev Checks if a facet and it's selectors given is registered to facet registry + * @param _facet Address of facet + * @param _facetSelectors List of function selectors of the facet + */ + function areFacetFunctionSelectorsRegistered( + address _facet, + bytes4[] calldata _facetSelectors + ) external view override returns (bool) { + FacetRegistryConfig storage facetConfig = facets[_facet]; + if (_facetSelectors.length == 0) return false; + for (uint256 i; i < _facetSelectors.length; ) { + if (!facetConfig.info[_facetSelectors[i]].exists) return false; + unchecked { + ++i; + } + } + return true; + } + + /** + * @dev Checks if a facet and it's selector given is registered to facet registry + * @param _facet Address of facet + * @param _facetSelector List of function selectors of the facet + * @return isRegistered Bool value showing if the selector is registered + */ + function isFacetFunctionSelectorRegistered( + address _facet, + bytes4 _facetSelector + ) external view override returns (bool isRegistered) { + FacetRegistryConfig storage facetConfig = facets[_facet]; + isRegistered = facetConfig.info[_facetSelector].exists; + } + + /** + * @dev Get the registered selectors of facet from registry + * @param _facet Address of facet + * @return selectors Selectors registered to facet + */ + function getFacetFunctionSelectors( + address _facet + ) external view override returns (bytes4[] memory selectors) { + FacetRegistryConfig storage facetConfig = facets[_facet]; + selectors = facetConfig.selectors; + } +} diff --git a/contracts/infrastructure/RemoteStorage.sol b/contracts/infrastructure/RemoteStorage.sol new file mode 100644 index 0000000..0e2d17c --- /dev/null +++ b/contracts/infrastructure/RemoteStorage.sol @@ -0,0 +1,163 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.21; + +import {IDiamondLoupe} from "../facets/base/interfaces/IDiamondLoupe.sol"; +import {IGuardianFacet} from "../facets/interfaces/IGuardianFacet.sol"; + +/** + * @title Remote Storage + * @dev Remote storage allows you to associate addresses with an array of addresses on a standalone smart contract. + * This could be useful when you don't want to use the local diamond storage for some purpose. + * @author Ruslan Serebriakov (@rsrbk) + * @author David Yongjun Kim (@Powerstream3604) + */ +abstract contract RemoteStorage { + struct StorageConfig { + address[] addresses; + mapping(address => Info) info; + } + + struct Info { + bool exists; + uint128 index; + } + + mapping(address => StorageConfig) internal configs; + + event Added(address _address); + event Removed(address _address); + + error RemoteStorage__CallerNotOwner(); + error RemoteStorage__CallerNotGuardianOrOwner(); + error RemoteStorage__AlreadyExists(); + error RemoteStorage__NotFound(); + error RemoteStorage__CallerNotGuardian(); + + bytes4 constant IS_GUARDIAN_SELECTOR = + bytes4(keccak256("isGuardian(address)")); + bytes4 constant GUARDIAN_COUNT = bytes4(keccak256("guardianCount()")); + + /** + * @notice Modifier to only allow the self to call. Reverts otherwise + */ + modifier onlyWallet(address _wallet) { + if (msg.sender != _wallet) revert RemoteStorage__CallerNotOwner(); + _; + } + + /** + * @notice Enfore the callet to be wallet of guardian of the wallet + * @param _wallet Address of wallet + */ + function enforceGuardianOrWallet(address _wallet) internal view { + if (msg.sender == _wallet) return; + address facetAddress = IDiamondLoupe(_wallet).facetAddress( + IS_GUARDIAN_SELECTOR + ); + if (facetAddress != address(0)) + if (IGuardianFacet(_wallet).isGuardian(msg.sender)) return; + revert RemoteStorage__CallerNotGuardianOrOwner(); + } + + /** + * @notice Enforce the caller to be wallet IF guardians doesn't exists and only guardian when guardians exists + * @param _wallet Target wallet address to be handled by infrastructure contracts + */ + function enforceWalletOrGuardianIfExists(address _wallet) internal view { + address facetAddress; + if (msg.sender == _wallet) { + facetAddress = IDiamondLoupe(_wallet).facetAddress(GUARDIAN_COUNT); + if (facetAddress == address(0)) return; + uint256 guardianCount = IGuardianFacet(_wallet).guardianCount(); + if (guardianCount != 0) revert RemoteStorage__CallerNotGuardian(); + return; + } + facetAddress = IDiamondLoupe(_wallet).facetAddress( + IS_GUARDIAN_SELECTOR + ); + if (facetAddress != address(0)) + if (IGuardianFacet(_wallet).isGuardian(msg.sender)) return; + + revert RemoteStorage__CallerNotGuardianOrOwner(); + } + + /** + * @notice Add address to storage and reverts if the address already exists. + * This is an internal function callable from contracts that inherit this abstract contract + * @param _wallet Address of wallet to add the address + * @param _address Address to be added to wallet + */ + function addAddress(address _wallet, address _address) internal { + StorageConfig storage config = configs[_wallet]; + if (config.info[_address].exists) revert RemoteStorage__AlreadyExists(); + + config.info[_address].exists = true; + config.info[_address].index = uint128(config.addresses.length); + config.addresses.push(_address); + + emit Added(_address); + } + + /** + * @notice Remove address from storage and reverts if the address already exists. + * This is an internal function callable from contracts that inherit this abstract contract + * @param _wallet Address of wallet to remove the address + * @param _address Address to be removed from wallet + */ + function removeAddress(address _wallet, address _address) internal { + StorageConfig storage config = configs[_wallet]; + if (!config.info[_address].exists) revert RemoteStorage__NotFound(); + + address lastAddress = config.addresses[config.addresses.length - 1]; + if (_address != lastAddress) { + uint128 targetIndex = config.info[_address].index; + config.addresses[targetIndex] = lastAddress; + config.info[lastAddress].index = targetIndex; + } + config.addresses.pop(); + delete config.info[_address]; + + emit Removed(_address); + } + + /** + * @notice Returns the address added to the given wallet + * @param _wallet Address of wallet to fetch the addresses added to it + * @return addresses List of addresses added to the wallet + */ + function getAddresses( + address _wallet + ) internal view returns (address[] memory addresses) { + StorageConfig storage config = configs[_wallet]; + addresses = new address[](config.addresses.length); + uint addressesLen = config.addresses.length; + for (uint256 i; i < addressesLen; ) { + addresses[i] = config.addresses[i]; + unchecked { + ++i; + } + } + } + + /** + * @notice Returns bool value checking if the address exists in the given wallet address + * @param _wallet Wallet address to check + * @param _address Address to fetch if the address if added to given wallet + * @return exists_ Bool value showing if the address exists in wallet + */ + function exists( + address _wallet, + address _address + ) internal view returns (bool exists_) { + exists_ = configs[_wallet].info[_address].exists; + } + + /** + * @notice Returns the number of addresses added to the wallet + * @param _wallet Address of wallet to check + * @return count_ Number of addresses added to wallet + */ + function count(address _wallet) internal view returns (uint256 count_) { + count_ = configs[_wallet].addresses.length; + } +} diff --git a/contracts/infrastructure/SecurityManager.sol b/contracts/infrastructure/SecurityManager.sol new file mode 100644 index 0000000..dacc81f --- /dev/null +++ b/contracts/infrastructure/SecurityManager.sol @@ -0,0 +1,549 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.21; + +import {Ownable2Step} from "@openzeppelin/contracts/access/Ownable2Step.sol"; +import {ISecurityManager} from "./interfaces/ISecurityManager.sol"; + +/** + * @title Security Manager + * @dev Infrastructure contract to manage security parameters of users + * @author David Yongjun Kim (@Powerstream3604) + */ +contract SecurityManager is ISecurityManager, Ownable2Step { + uint128 public minAdditionSecurityPeriod; + uint128 public maxAdditionSecurityPeriod; + uint128 private defaultAdditionSecurityPeriod; + + uint128 public minRemovalSecurityPeriod; + uint128 public maxRemovalSecurityPeriod; + uint128 private defaultRemovalSecurityPeriod; + + uint128 public minSecurityWindow; + uint128 public maxSecurityWindow; + uint128 private defaultSecurityWindow; + + uint128 public minRecoveryPeriod; + uint128 public maxRecoveryPeriod; + uint128 private defaultRecoveryPeriod; + + uint128 public minLockPeriod; + uint128 public maxLockPeriod; + uint128 private defaultLockPeriod; + + uint128 public minApprovalValidationPeriod; + uint128 public maxApprovalValidationPeriod; + uint128 private defaultApprovalValidationPeriod; + + uint128 public minMigrationPeriod; + uint128 public maxMigrationPeriod; + uint128 private defaultMigrationPeriod; + + bool public _isAdditionSecurityPeriodInitialized; + bool public _isRemovalSecurityPeriodInitialized; + bool public _isSecurityWindowInitialized; + bool public _isRecoveryPeriodInitialized; + bool public _isLockPeriodInitialized; + bool public _isApprovalValidationPeriodInitialized; + bool public _isMigrationPeriodInitialized; + + mapping(address => CustomSecurityConfig) securityConfigs; + + struct CustomSecurityConfig { + uint128 additionSecurityPeriod; + uint128 removalSecurityPeriod; + uint128 securityWindow; + uint128 recoveryPeriod; + uint128 lockPeriod; + uint128 approvalValidationPeriod; + uint128 migrationPeriod; + } + + /** + * @notice Modifier to only allow wallet itself to make a call to wallet + */ + modifier onlyWallet(address _wallet) { + if (msg.sender != _wallet) revert SecurityManager__CallerNotWallet(); + _; + } + + /** + * @notice Modifier to revert if the variable is already initialized + */ + modifier initializer(bool _isInitialized) { + if (_isInitialized) revert SecurityManager__AlreadyIntialized(); + _; + } + + /** + * @notice Transfers the ownership of the contract to the given owner + * @param _owner Address of owner who has access to initialize the default security variables for security manager + */ + constructor(address _owner) { + transferOwnership(_owner); + _transferOwnership(_owner); + } + + /** + * @notice Sets the initial default/min/max addition security period for all Barz contracts that use this as Security Manager + * This function can only be called by the owner of the SecurityManager + * Default value should be bigger than the min and smaller than the max + * @param _defaultAdditionSecurityPeriod Default Addition Security Period for all Barz contracts + * @param _minAdditionSecurityPeriod Minimum Addition Security Period for all Barz contracts + * @param _maxAdditionSecurityPeriod Maximum Addition Security Period for all Barz contracts + */ + function initializeAdditionSecurityPeriod( + uint128 _defaultAdditionSecurityPeriod, + uint128 _minAdditionSecurityPeriod, + uint128 _maxAdditionSecurityPeriod + ) + external + override + onlyOwner + initializer(_isAdditionSecurityPeriodInitialized) + { + _isAdditionSecurityPeriodInitialized = true; + + _validatePeriodBoundaries( + _defaultAdditionSecurityPeriod, + _minAdditionSecurityPeriod, + _maxAdditionSecurityPeriod + ); + defaultAdditionSecurityPeriod = _defaultAdditionSecurityPeriod; + minAdditionSecurityPeriod = _minAdditionSecurityPeriod; + maxAdditionSecurityPeriod = _maxAdditionSecurityPeriod; + } + + /** + * @notice Sets the initial default/min/max removal security period for all Barz contracts that use this as Security Manager + * This function can only be called by the owner of the SecurityManager + * Default value should be bigger than the min and smaller than the max + * @param _defaultRemovalSecurityPeriod Default Removal Security Period for all Barz contracts + * @param _minRemovalSecurityPeriod Minimum Removal Security Period for all Barz contracts + * @param _maxRemovalSecurityPeriod Maximum Removal Security Period for all Barz contracts + */ + function initializeRemovalSecurityPeriod( + uint128 _defaultRemovalSecurityPeriod, + uint128 _minRemovalSecurityPeriod, + uint128 _maxRemovalSecurityPeriod + ) + external + override + onlyOwner + initializer(_isRemovalSecurityPeriodInitialized) + { + _isRemovalSecurityPeriodInitialized = true; + + _validatePeriodBoundaries( + _defaultRemovalSecurityPeriod, + _minRemovalSecurityPeriod, + _maxRemovalSecurityPeriod + ); + defaultRemovalSecurityPeriod = _defaultRemovalSecurityPeriod; + minRemovalSecurityPeriod = _minRemovalSecurityPeriod; + maxRemovalSecurityPeriod = _maxRemovalSecurityPeriod; + } + + /** + * @notice Sets the initial default/min/maxd security window for all Barz contracts that use this as Security Manager + * This function can only be called by the owner of the SecurityManager + * Default value should be bigger than the min and smaller than the max + * @param _defaultSecurityWindow Default Security Window for all Barz contracts + * @param _minSecurityWindow Minimum Security Window for all Barz contracts + * @param _maxSecurityWindow Maximum Security Window for all Barz contracts + */ + function initializeSecurityWindow( + uint128 _defaultSecurityWindow, + uint128 _minSecurityWindow, + uint128 _maxSecurityWindow + ) external override onlyOwner initializer(_isSecurityWindowInitialized) { + _isSecurityWindowInitialized = true; + + _validatePeriodBoundaries( + _defaultSecurityWindow, + _minSecurityWindow, + _maxSecurityWindow + ); + defaultSecurityWindow = _defaultSecurityWindow; + minSecurityWindow = _minSecurityWindow; + maxSecurityWindow = _maxSecurityWindow; + } + + /** + * @notice Sets the initial default/min/max recovery period for all Barz contracts that use this as Security Manager + * This function can only be called by the owner of the SecurityManager + * Default value should be bigger than the min and smaller than the max + * @param _defaultRecoveryPeriod Default Recovery Period for all Barz contracts + * @param _minRecoveryPeriod Minimum Recovery Period for all Barz contracts + * @param _maxRecoveryPeriod Maximum Recovery Period for all Barz contracts + */ + function initializeRecoveryPeriod( + uint128 _defaultRecoveryPeriod, + uint128 _minRecoveryPeriod, + uint128 _maxRecoveryPeriod + ) external override onlyOwner initializer(_isRecoveryPeriodInitialized) { + _isRecoveryPeriodInitialized = true; + + _validatePeriodBoundaries( + _defaultRecoveryPeriod, + _minRecoveryPeriod, + _maxRecoveryPeriod + ); + defaultRecoveryPeriod = _defaultRecoveryPeriod; + minRecoveryPeriod = _minRecoveryPeriod; + maxRecoveryPeriod = _maxRecoveryPeriod; + } + + /** + * @notice Sets the initial default/min/max lock period for all Barz contracts that use this as Security Manager + * This function can only be called by the owner of the SecurityManager + * Default value should be bigger than the min and smaller than the max + * @param _defaultLockPeriod Default Lock Period for all Barz contracts + * @param _minLockPeriod Minimum Lock Period for all Barz contracts + * @param _maxLockPeriod Maximum Lock Period for all Barz contracts + */ + function initializeLockPeriod( + uint128 _defaultLockPeriod, + uint128 _minLockPeriod, + uint128 _maxLockPeriod + ) external override onlyOwner initializer(_isLockPeriodInitialized) { + _isLockPeriodInitialized = true; + + _validatePeriodBoundaries( + _defaultLockPeriod, + _minLockPeriod, + _maxLockPeriod + ); + defaultLockPeriod = _defaultLockPeriod; + minLockPeriod = _minLockPeriod; + maxLockPeriod = _maxLockPeriod; + } + + /** + * @notice Sets the initial default/min/max approval validation period for all Barz contracts that use this as Security Manager + * This function can only be called by the owner of the SecurityManager + * Default value should be bigger than the min and smaller than the max + * @param _defaultApprovalValidationPeriod Default Approval Validation Period for all Barz contracts + * @param _minApprovalValidationPeriod Minimum Approval Validation Period for all Barz contracts + * @param _maxApprovalValidationPeriod Maximum Approval Validation Period for all Barz contracts + */ + function initializeApprovalValidationPeriod( + uint128 _defaultApprovalValidationPeriod, + uint128 _minApprovalValidationPeriod, + uint128 _maxApprovalValidationPeriod + ) + external + override + onlyOwner + initializer(_isApprovalValidationPeriodInitialized) + { + _isApprovalValidationPeriodInitialized = true; + + _validatePeriodBoundaries( + _defaultApprovalValidationPeriod, + _minApprovalValidationPeriod, + _maxApprovalValidationPeriod + ); + defaultApprovalValidationPeriod = _defaultApprovalValidationPeriod; + minApprovalValidationPeriod = _minApprovalValidationPeriod; + maxApprovalValidationPeriod = _maxApprovalValidationPeriod; + } + + /** + * @notice Sets the initial default/min/max migration period for all Barz contracts that use this as Security Manager + * This function can only be called by the owner of the SecurityManager + * Default value should be bigger than the min and smaller than the max + * @param _defaultMigrationPeriod Default Migration Period for all Barz contracts + * @param _minMigrationPeriod Minimum Migration Period for all Barz contracts + * @param _maxMigrationPeriod Maximum Migration Period for all Barz contracts + */ + function initializeMigrationPeriod( + uint128 _defaultMigrationPeriod, + uint128 _minMigrationPeriod, + uint128 _maxMigrationPeriod + ) external override onlyOwner initializer(_isMigrationPeriodInitialized) { + _isMigrationPeriodInitialized = true; + + _validatePeriodBoundaries( + _defaultMigrationPeriod, + _minMigrationPeriod, + _maxMigrationPeriod + ); + defaultMigrationPeriod = _defaultMigrationPeriod; + minMigrationPeriod = _minMigrationPeriod; + maxMigrationPeriod = _maxMigrationPeriod; + } + + /** + * @notice Wallet owner sets the addition security period for the wallet. Only the owner of wallet can call this function. + * The addition security period should be within the boundry of min and max value set by the owner + * @param _wallet Address of wallet + * @param _additionSecurityPeriod Custom Addition Security Period for the wallet + */ + function setAdditionSecurityPeriod( + address _wallet, + uint128 _additionSecurityPeriod + ) external override onlyWallet(_wallet) { + _validatePeriodBoundaries( + _additionSecurityPeriod, + minAdditionSecurityPeriod, + maxAdditionSecurityPeriod + ); + securityConfigs[_wallet] + .additionSecurityPeriod = _additionSecurityPeriod; + } + + /** + * @notice Wallet owner sets the removal security period for the wallet. Only the owner of wallet can call this function. + * The removal security period should be within the boundry of min and max value set by the owner + * @param _wallet Address of wallet + * @param _removalSecurityPeriod Custom Removal Security Period for the wallet + */ + function setRemovalSecurityPeriod( + address _wallet, + uint128 _removalSecurityPeriod + ) external override onlyWallet(_wallet) { + _validatePeriodBoundaries( + _removalSecurityPeriod, + minRemovalSecurityPeriod, + maxRemovalSecurityPeriod + ); + securityConfigs[_wallet].removalSecurityPeriod = _removalSecurityPeriod; + } + + /** + * @notice Wallet owner sets the security window for the wallet. Only the owner of wallet can call this function. + * The security window should be within the boundry of min and max value set by the owner + * @param _wallet Address of wallet + * @param _securityWindow Custom Security Window for the wallet + */ + function setSecurityWindow( + address _wallet, + uint128 _securityWindow + ) external override onlyWallet(_wallet) { + _validatePeriodBoundaries( + _securityWindow, + minSecurityWindow, + maxSecurityWindow + ); + securityConfigs[_wallet].securityWindow = _securityWindow; + } + + /** + * @notice Wallet owner sets the recovery period for the wallet. Only the owner of wallet can call this function. + * The recovery period should be within the boundry of min and max value set by the owner + * @param _wallet Address of wallet + * @param _recoveryPeriod Custom recovery period for the wallet + */ + function setRecoveryPeriod( + address _wallet, + uint128 _recoveryPeriod + ) external override onlyWallet(_wallet) { + _validatePeriodBoundaries( + _recoveryPeriod, + minRecoveryPeriod, + maxRecoveryPeriod + ); + securityConfigs[_wallet].recoveryPeriod = _recoveryPeriod; + } + + /** + * @notice Wallet owner sets the lock period for the wallet. Only the owner of wallet can call this function. + * The lock period should be within the boundry of min and max value set by the owner + * @param _wallet Address of wallet + * @param _lockPeriod Custom Lock period for the wallet + */ + function setLockPeriod( + address _wallet, + uint128 _lockPeriod + ) external override onlyWallet(_wallet) { + _validatePeriodBoundaries(_lockPeriod, minLockPeriod, maxLockPeriod); + securityConfigs[_wallet].lockPeriod = _lockPeriod; + } + + /** + * @notice Wallet owner sets the approval validation period for the wallet. Only the owner of wallet can call this function. + * The approval validation period should be within the boundry of min and max value set by the owner + * @param _wallet Address of wallet + * @param _approvalValidationPeriod Custom approval validation period for the wallet + */ + function setApprovalValidationPeriod( + address _wallet, + uint128 _approvalValidationPeriod + ) external override onlyWallet(_wallet) { + _validatePeriodBoundaries( + _approvalValidationPeriod, + minApprovalValidationPeriod, + maxApprovalValidationPeriod + ); + securityConfigs[_wallet] + .approvalValidationPeriod = _approvalValidationPeriod; + } + + /** + * @notice Wallet owner sets the migration period for the wallet. Only the owner of wallet can call this function. + * The migration period should be within the boundry of min and max value set by the owner + * @param _wallet Address of wallet + * @param _migrationPeriod Custom migration period for the wallet + */ + + function setMigrationPeriod( + address _wallet, + uint128 _migrationPeriod + ) external override onlyWallet(_wallet) { + _validatePeriodBoundaries( + _migrationPeriod, + minMigrationPeriod, + maxMigrationPeriod + ); + securityConfigs[_wallet].migrationPeriod = _migrationPeriod; + } + + /** + * @notice Returns the addition security period. Returns default value when custom addition security period is not set + * @param _wallet Address of wallet + * @return additionSecurityPeriod Addition Security Period of the given Barz account or wallet + */ + function additionSecurityPeriodOf( + address _wallet + ) + public + view + override + onlyWallet(_wallet) + returns (uint128 additionSecurityPeriod) + { + additionSecurityPeriod = securityConfigs[_wallet] + .additionSecurityPeriod; + additionSecurityPeriod = (additionSecurityPeriod == 0) + ? defaultAdditionSecurityPeriod + : additionSecurityPeriod; + } + + /** + * @notice Returns the removal security period. Returns default value when custom removal security period is not set + * @param _wallet Address of wallet + * @return removalSecurityPeriod Removal Security Period of the given Barz account or wallet + */ + function removalSecurityPeriodOf( + address _wallet + ) + public + view + override + onlyWallet(_wallet) + returns (uint128 removalSecurityPeriod) + { + removalSecurityPeriod = securityConfigs[_wallet].removalSecurityPeriod; + removalSecurityPeriod = (removalSecurityPeriod == 0) + ? defaultRemovalSecurityPeriod + : removalSecurityPeriod; + } + + /** + * @notice Returns the security window. Returns default value when custom security window is not set + * @param _wallet Address of wallet + * @return securityWindow Security window of the given Barz account or wallet + */ + function securityWindowOf( + address _wallet + ) + public + view + override + onlyWallet(_wallet) + returns (uint128 securityWindow) + { + securityWindow = securityConfigs[_wallet].securityWindow; + securityWindow = (securityWindow == 0) + ? defaultSecurityWindow + : securityWindow; + } + + /** + * @notice Returns the recovery period. Returns default value when custom recovery period is not set + * @param _wallet Address of wallet + * @return recoveryPeriod Recovery Period of the given Barz account or wallet + */ + function recoveryPeriodOf( + address _wallet + ) + public + view + override + onlyWallet(_wallet) + returns (uint128 recoveryPeriod) + { + recoveryPeriod = securityConfigs[_wallet].recoveryPeriod; + recoveryPeriod = (recoveryPeriod == 0) + ? defaultRecoveryPeriod + : recoveryPeriod; + } + + /** + * @notice Returns the lock period. Returns default value when custom lock period is not set + * @param _wallet Address of wallet + * @return lockPeriod Lock Period of the given Barz account or wallet + */ + function lockPeriodOf( + address _wallet + ) public view override onlyWallet(_wallet) returns (uint128 lockPeriod) { + lockPeriod = securityConfigs[_wallet].lockPeriod; + lockPeriod = (lockPeriod == 0) ? defaultLockPeriod : lockPeriod; + } + + /** + * @notice Returns the approval validation period. Returns default value when custom approval validation period is not set + * @param _wallet Address of wallet + * @return approvalValidationPeriod Approval Validation Period of the given Barz account or wallet + */ + function approvalValidationPeriodOf( + address _wallet + ) + public + view + override + onlyWallet(_wallet) + returns (uint128 approvalValidationPeriod) + { + approvalValidationPeriod = securityConfigs[_wallet] + .approvalValidationPeriod; + approvalValidationPeriod = (approvalValidationPeriod == 0) + ? defaultApprovalValidationPeriod + : approvalValidationPeriod; + } + + /** + * @notice Returns the migration period. Returns default value when custom migration period is not set + * @param _wallet Address of wallet + * @return migrationPeriod Migration Period of the given Barz account or wallet + */ + function migrationPeriodOf( + address _wallet + ) + public + view + override + onlyWallet(_wallet) + returns (uint128 migrationPeriod) + { + migrationPeriod = securityConfigs[_wallet].migrationPeriod; + migrationPeriod = (migrationPeriod == 0) + ? defaultMigrationPeriod + : migrationPeriod; + } + + /** + * @notice Validates if the period is smaller than the max period or bigger than the min period + * @param _period Period to be checked + * @param _minPeriod Minimum period + * @param _maxPeriod Maximum period + */ + function _validatePeriodBoundaries( + uint128 _period, + uint128 _minPeriod, + uint128 _maxPeriod + ) internal pure { + if (_period >= _maxPeriod || _period <= _minPeriod) + revert SecurityManager__OutOfBoundary(); + } +} diff --git a/contracts/infrastructure/WhitelistStorage.sol b/contracts/infrastructure/WhitelistStorage.sol new file mode 100644 index 0000000..b148ec3 --- /dev/null +++ b/contracts/infrastructure/WhitelistStorage.sol @@ -0,0 +1,53 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.21; + +import {RemoteStorage} from "./RemoteStorage.sol"; + +/** + * @title Whitelist storage + * @dev Maps addresses to the corresponsing array of whitelisted addresses for each of them. + * @author Ruslan Serebriakov (@rsrbk) + */ +contract WhitelistStorage is RemoteStorage { + /** + * @dev Add the address to the whitelist storage + * @param _wallet User wallet + * @param _address Address to be whitelisted + */ + function whitelistAddress(address _wallet, address _address) external { + enforceWalletOrGuardianIfExists(_wallet); + addAddress(_wallet, _address); + } + + /** + * @dev Removes the address from the whitelist storage + * @param _wallet User wallet + * @param _address Address to be removed from the whitelist + */ + function blacklistAddress(address _wallet, address _address) external { + enforceGuardianOrWallet(_wallet); + removeAddress(_wallet, _address); + } + + /** + * @dev Returns whether the address exists in the whitelist storage, associated with the wallet + * @param _wallet User wallet + * @param _address Address to be whitelisted + */ + function isWhitelisted( + address _wallet, + address _address + ) external view returns (bool) { + return exists(_wallet, _address); + } + + /** + * @dev Returns all whitelisted addresses associated with the wallet + * @param _wallet User wallet + */ + function getWhitelistedAddresses( + address _wallet + ) external view returns (address[] memory) { + return getAddresses(_wallet); + } +} diff --git a/contracts/infrastructure/interfaces/IFacetRegistry.sol b/contracts/infrastructure/interfaces/IFacetRegistry.sol new file mode 100644 index 0000000..7bd0a7d --- /dev/null +++ b/contracts/infrastructure/interfaces/IFacetRegistry.sol @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.21; + +/** + * @title Facet Registry Interface + * @dev Interface for Facet Registry contract to keep track of facets & function selectors addable to user wallets + * @author David Yongjun Kim (@Powerstream3604) + */ +interface IFacetRegistry { + struct FacetRegistryConfig { + bytes4[] selectors; + mapping(bytes4 => FacetInfo) info; + } + struct FacetInfo { + bool exists; + uint128 index; + } + + event FacetFunctionSelectorsRegistered( + address facet, + bytes4[] facetSelectors + ); + event FacetFunctionSelectorsRemoved(address facet, bytes4[] facetSelectors); + + error FacetRegistry__FacetSelectorAlreadyRegistered(); + error FacetRegistry__UnregisteredFacetSelector(); + + function registerFacetFunctionSelectors( + address facet, + bytes4[] calldata facetSelectors + ) external; + + function removeFacetFunctionSelectors( + address facet, + bytes4[] calldata facetSelectors + ) external; + + function areFacetFunctionSelectorsRegistered( + address facet, + bytes4[] calldata facetSelectors + ) external view returns (bool); + + function isFacetFunctionSelectorRegistered( + address facet, + bytes4 facetSelector + ) external view returns (bool); + + function getFacetFunctionSelectors( + address facet + ) external view returns (bytes4[] memory); +} diff --git a/contracts/infrastructure/interfaces/ISecurityManager.sol b/contracts/infrastructure/interfaces/ISecurityManager.sol new file mode 100644 index 0000000..d61116e --- /dev/null +++ b/contracts/infrastructure/interfaces/ISecurityManager.sol @@ -0,0 +1,102 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.21; + +/** + * @title Facet Registry Interface + * @dev Infrastructure contract to manage security parameters of users + * @author David Yongjun Kim (@Powerstream3604) + * @author Ruslan Serebriakov (@rsrbk) + */ +interface ISecurityManager { + error SecurityManager__OutOfBoundary(); + error SecurityManager__CallerNotWallet(); + error SecurityManager__AlreadyIntialized(); + + function initializeAdditionSecurityPeriod( + uint128 defaultAdditionSecurityPeriod, + uint128 minAdditionSecurityPeriod, + uint128 maxAdditionSecurityPeriod + ) external; + + function initializeRemovalSecurityPeriod( + uint128 defaultRemovalSecurityPeriod, + uint128 minRemovalSecurityPeriod, + uint128 maxRemovalSecurityPeriod + ) external; + + function initializeApprovalValidationPeriod( + uint128 defaultApprovalValidationPeriod, + uint128 minApprovalValidationPeriod, + uint128 maxApprovalValidationPeriod + ) external; + + function initializeMigrationPeriod( + uint128 defaultMigrationPeriod, + uint128 minMigrationPeriod, + uint128 maxMigrationPeriod + ) external; + + function initializeLockPeriod( + uint128 defaultLockPeriod, + uint128 minLockPeriod, + uint128 maxLockPeriod + ) external; + + function initializeRecoveryPeriod( + uint128 defaultRecoveryPeriod, + uint128 minRecoveryPeriod, + uint128 maxRecoveryPeriod + ) external; + + function initializeSecurityWindow( + uint128 defaultSecurityWindow, + uint128 minSecurityWindow, + uint128 maxSecurityWindow + ) external; + + function setAdditionSecurityPeriod( + address wallet, + uint128 additionSecurityPeriod + ) external; + + function setRemovalSecurityPeriod( + address wallet, + uint128 removalSecurityPeriod + ) external; + + function setSecurityWindow(address wallet, uint128 securityWindow) external; + + function setRecoveryPeriod(address wallet, uint128 recoveryPeriod) external; + + function setLockPeriod(address wallet, uint128 lockPeriod) external; + + function setApprovalValidationPeriod( + address wallet, + uint128 approvalValidationPeriod + ) external; + + function setMigrationPeriod( + address wallet, + uint128 migrationPeriod + ) external; + + function additionSecurityPeriodOf( + address wallet + ) external view returns (uint128); + + function removalSecurityPeriodOf( + address wallet + ) external view returns (uint128); + + function securityWindowOf(address wallet) external view returns (uint128); + + function recoveryPeriodOf(address wallet) external view returns (uint128); + + function lockPeriodOf(address wallet) external view returns (uint128); + + function migrationPeriodOf(address wallet) external view returns (uint128); + + function approvalValidationPeriodOf( + address wallet + ) external view returns (uint128); +} diff --git a/contracts/interfaces/ERC/IERC1155Receiver.sol b/contracts/interfaces/ERC/IERC1155Receiver.sol new file mode 100644 index 0000000..2db40ab --- /dev/null +++ b/contracts/interfaces/ERC/IERC1155Receiver.sol @@ -0,0 +1,55 @@ +// SPDX-License-Identifier: Apache-2.0 + +pragma solidity 0.8.21; + +/** + * @dev _Available since v3.1._ + */ +interface IERC1155Receiver { + /** + * @dev Handles the receipt of a single ERC1155 token type. This function is + * called at the end of a `safeTransferFrom` after the balance has been updated. + * + * NOTE: To accept the transfer, this must return + * `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` + * (i.e. 0xf23a6e61, or its own function selector). + * + * @param operator The address which initiated the transfer (i.e. msg.sender) + * @param from The address which previously owned the token + * @param id The ID of the token being transferred + * @param value The amount of tokens being transferred + * @param data Additional data with no specified format + * @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed + */ + function onERC1155Received( + address operator, + address from, + uint256 id, + uint256 value, + bytes calldata data + ) external returns (bytes4); + + /** + * @dev Handles the receipt of a multiple ERC1155 token types. This function + * is called at the end of a `safeBatchTransferFrom` after the balances have + * been updated. + * + * NOTE: To accept the transfer(s), this must return + * `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` + * (i.e. 0xbc197c81, or its own function selector). + * + * @param operator The address which initiated the batch transfer (i.e. msg.sender) + * @param from The address which previously owned the token + * @param ids An array containing ids of each token being transferred (order and length must match values array) + * @param values An array containing amounts of each token being transferred (order and length must match ids array) + * @param data Additional data with no specified format + * @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed + */ + function onERC1155BatchReceived( + address operator, + address from, + uint256[] calldata ids, + uint256[] calldata values, + bytes calldata data + ) external returns (bytes4); +} diff --git a/contracts/interfaces/ERC/IERC1271.sol b/contracts/interfaces/ERC/IERC1271.sol new file mode 100644 index 0000000..7678ce1 --- /dev/null +++ b/contracts/interfaces/ERC/IERC1271.sol @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.21; + +interface IERC1271 { + function isValidSignature( + bytes32 hash, + bytes memory signature + ) external view returns (bytes4); +} diff --git a/contracts/interfaces/ERC/IERC165.sol b/contracts/interfaces/ERC/IERC165.sol new file mode 100644 index 0000000..57e614e --- /dev/null +++ b/contracts/interfaces/ERC/IERC165.sol @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.21; + +interface IERC165 { + /// @notice Query if a contract implements an interface + /// @param interfaceId The interface identifier, as specified in ERC-165 + /// @dev Interface identification is specified in ERC-165. This function + /// uses less than 30,000 gas. + /// @return `true` if the contract implements `interfaceID` and + /// `interfaceID` is not 0xffffffff, `false` otherwise + function supportsInterface(bytes4 interfaceId) external view returns (bool); +} diff --git a/contracts/interfaces/ERC/IERC173.sol b/contracts/interfaces/ERC/IERC173.sol new file mode 100644 index 0000000..fee07e5 --- /dev/null +++ b/contracts/interfaces/ERC/IERC173.sol @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.21; + +/// @title ERC-173 Contract Ownership Standard +/// Note: the ERC-165 identifier for this interface is 0x7f5828d0 +/* is ERC165 */ +interface IERC173 { + /// @dev This emits when ownership of a contract changes. + event OwnershipTransferred( + address indexed previousOwner, + address indexed newOwner + ); + + /// @notice Get the address of the owner + /// @return owner_ The address of the owner. + function owner() external view returns (address owner_); + + /// @notice Set the address of the new owner of the contract + /// @dev Set _newOwner to address(0) to renounce any ownership. + /// @param _newOwner The address of the new owner of the contract + function transferOwnership(address _newOwner) external; +} diff --git a/contracts/interfaces/ERC/IERC677Receiver.sol b/contracts/interfaces/ERC/IERC677Receiver.sol new file mode 100644 index 0000000..79a59aa --- /dev/null +++ b/contracts/interfaces/ERC/IERC677Receiver.sol @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.21; + +interface IERC677Receiver { + function onTokenTransfer( + address sender, + uint value, + bytes calldata data + ) external pure returns (bool); +} diff --git a/contracts/interfaces/ERC/Tokens/IERC1155.sol b/contracts/interfaces/ERC/Tokens/IERC1155.sol new file mode 100644 index 0000000..d277691 --- /dev/null +++ b/contracts/interfaces/ERC/Tokens/IERC1155.sol @@ -0,0 +1,141 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol) + +pragma solidity ^0.8.0; + +import "../IERC165.sol"; + +/** + * @dev Required interface of an ERC1155 compliant contract, as defined in the + * https://eips.ethereum.org/EIPS/eip-1155[EIP]. + * + * _Available since v3.1._ + */ +interface IERC1155 is IERC165 { + /** + * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`. + */ + event TransferSingle( + address indexed operator, + address indexed from, + address indexed to, + uint256 id, + uint256 value + ); + + /** + * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all + * transfers. + */ + event TransferBatch( + address indexed operator, + address indexed from, + address indexed to, + uint256[] ids, + uint256[] values + ); + + /** + * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to + * `approved`. + */ + event ApprovalForAll( + address indexed account, + address indexed operator, + bool approved + ); + + /** + * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI. + * + * If an {URI} event was emitted for `id`, the standard + * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value + * returned by {IERC1155MetadataURI-uri}. + */ + event URI(string value, uint256 indexed id); + + /** + * @dev Returns the amount of tokens of token type `id` owned by `account`. + * + * Requirements: + * + * - `account` cannot be the zero address. + */ + function balanceOf( + address account, + uint256 id + ) external view returns (uint256); + + /** + * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}. + * + * Requirements: + * + * - `accounts` and `ids` must have the same length. + */ + function balanceOfBatch( + address[] calldata accounts, + uint256[] calldata ids + ) external view returns (uint256[] memory); + + /** + * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`, + * + * Emits an {ApprovalForAll} event. + * + * Requirements: + * + * - `operator` cannot be the caller. + */ + function setApprovalForAll(address operator, bool approved) external; + + /** + * @dev Returns true if `operator` is approved to transfer ``account``'s tokens. + * + * See {setApprovalForAll}. + */ + function isApprovedForAll( + address account, + address operator + ) external view returns (bool); + + /** + * @dev Transfers `amount` tokens of token type `id` from `from` to `to`. + * + * Emits a {TransferSingle} event. + * + * Requirements: + * + * - `to` cannot be the zero address. + * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}. + * - `from` must have a balance of tokens of type `id` of at least `amount`. + * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the + * acceptance magic value. + */ + function safeTransferFrom( + address from, + address to, + uint256 id, + uint256 amount, + bytes calldata data + ) external; + + /** + * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}. + * + * Emits a {TransferBatch} event. + * + * Requirements: + * + * - `ids` and `amounts` must have the same length. + * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the + * acceptance magic value. + */ + function safeBatchTransferFrom( + address from, + address to, + uint256[] calldata ids, + uint256[] calldata amounts, + bytes calldata data + ) external; +} diff --git a/contracts/interfaces/ERC/Tokens/IERC20.sol b/contracts/interfaces/ERC/Tokens/IERC20.sol new file mode 100644 index 0000000..ebdeccd --- /dev/null +++ b/contracts/interfaces/ERC/Tokens/IERC20.sol @@ -0,0 +1,123 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.21; + +/** + * @dev Interface of the ERC20 standard as defined in the EIP. + */ +interface IERC20 { + /** + * @dev Emitted when `value` tokens are moved from one account (`from`) to + * another (`to`). + * + * Note that `value` may be zero. + */ + event Transfer(address indexed from, address indexed to, uint256 value); + + /** + * @dev Emitted when the allowance of a `spender` for an `owner` is set by + * a call to {approve}. `value` is the new allowance. + */ + event Approval( + address indexed owner, + address indexed spender, + uint256 value + ); + + /** + * @dev Returns the amount of tokens in existence. + */ + function totalSupply() external view returns (uint256); + + /** + * @dev Returns the amount of tokens owned by `account`. + */ + function balanceOf(address account) external view returns (uint256); + + /** + * @dev Moves `amount` tokens from the caller's account to `to`. + * + * Returns a boolean value indicating whether the operation succeeded. + * + * Emits a {Transfer} event. + */ + function transfer(address to, uint256 amount) external returns (bool); + + /** + * @dev Returns the remaining number of tokens that `spender` will be + * allowed to spend on behalf of `owner` through {transferFrom}. This is + * zero by default. + * + * This value changes when {approve} or {transferFrom} are called. + */ + function allowance( + address owner, + address spender + ) external view returns (uint256); + + /** + * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. + * + * Returns a boolean value indicating whether the operation succeeded. + * + * IMPORTANT: Beware that changing an allowance with this method brings the risk + * that someone may use both the old and the new allowance by unfortunate + * transaction ordering. One possible solution to mitigate this race + * condition is to first reduce the spender's allowance to 0 and set the + * desired value afterwards: + * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 + * + * Emits an {Approval} event. + */ + function approve(address spender, uint256 amount) external returns (bool); + + /** + * @dev Moves `amount` tokens from `from` to `to` using the + * allowance mechanism. `amount` is then deducted from the caller's + * allowance. + * + * Returns a boolean value indicating whether the operation succeeded. + * + * Emits a {Transfer} event. + */ + function transferFrom( + address from, + address to, + uint256 amount + ) external returns (bool); + + /** + * @dev Atomically increases the allowance granted to `spender` by the caller. + * + * This is an alternative to {approve} that can be used as a mitigation for + * problems described in {IERC20-approve}. + * + * Emits an {Approval} event indicating the updated allowance. + * + * Requirements: + * + * - `spender` cannot be the zero address. + */ + function increaseAllowance( + address spender, + uint256 addedValue + ) external returns (bool); + + /** + * @dev Atomically decreases the allowance granted to `spender` by the caller. + * + * This is an alternative to {approve} that can be used as a mitigation for + * problems described in {IERC20-approve}. + * + * Emits an {Approval} event indicating the updated allowance. + * + * Requirements: + * + * - `spender` cannot be the zero address. + * - `spender` must have allowance for the caller of at least + * `subtractedValue`. + */ + function decreaseAllowance( + address spender, + uint256 subtractedValue + ) external returns (bool); +} diff --git a/contracts/interfaces/ERC/Tokens/IERC721.sol b/contracts/interfaces/ERC/Tokens/IERC721.sol new file mode 100644 index 0000000..fc4eae4 --- /dev/null +++ b/contracts/interfaces/ERC/Tokens/IERC721.sol @@ -0,0 +1,158 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol) + +pragma solidity ^0.8.0; + +import "../IERC165.sol"; + +/** + * @dev Required interface of an ERC721 compliant contract. + */ +interface IERC721 is IERC165 { + /** + * @dev Emitted when `tokenId` token is transferred from `from` to `to`. + */ + event Transfer( + address indexed from, + address indexed to, + uint256 indexed tokenId + ); + + /** + * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. + */ + event Approval( + address indexed owner, + address indexed approved, + uint256 indexed tokenId + ); + + /** + * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. + */ + event ApprovalForAll( + address indexed owner, + address indexed operator, + bool approved + ); + + /** + * @dev Returns the number of tokens in ``owner``'s account. + */ + function balanceOf(address owner) external view returns (uint256 balance); + + /** + * @dev Returns the owner of the `tokenId` token. + * + * Requirements: + * + * - `tokenId` must exist. + */ + function ownerOf(uint256 tokenId) external view returns (address owner); + + /** + * @dev Safely transfers `tokenId` token from `from` to `to`. + * + * Requirements: + * + * - `from` cannot be the zero address. + * - `to` cannot be the zero address. + * - `tokenId` token must exist and be owned by `from`. + * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. + * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. + * + * Emits a {Transfer} event. + */ + function safeTransferFrom( + address from, + address to, + uint256 tokenId, + bytes calldata data + ) external; + + /** + * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients + * are aware of the ERC721 protocol to prevent tokens from being forever locked. + * + * Requirements: + * + * - `from` cannot be the zero address. + * - `to` cannot be the zero address. + * - `tokenId` token must exist and be owned by `from`. + * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}. + * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. + * + * Emits a {Transfer} event. + */ + function safeTransferFrom( + address from, + address to, + uint256 tokenId + ) external; + + /** + * @dev Transfers `tokenId` token from `from` to `to`. + * + * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721 + * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must + * understand this adds an external call which potentially creates a reentrancy vulnerability. + * + * Requirements: + * + * - `from` cannot be the zero address. + * - `to` cannot be the zero address. + * - `tokenId` token must be owned by `from`. + * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. + * + * Emits a {Transfer} event. + */ + function transferFrom(address from, address to, uint256 tokenId) external; + + /** + * @dev Gives permission to `to` to transfer `tokenId` token to another account. + * The approval is cleared when the token is transferred. + * + * Only a single account can be approved at a time, so approving the zero address clears previous approvals. + * + * Requirements: + * + * - The caller must own the token or be an approved operator. + * - `tokenId` must exist. + * + * Emits an {Approval} event. + */ + function approve(address to, uint256 tokenId) external; + + /** + * @dev Approve or remove `operator` as an operator for the caller. + * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. + * + * Requirements: + * + * - The `operator` cannot be the caller. + * + * Emits an {ApprovalForAll} event. + */ + function setApprovalForAll(address operator, bool approved) external; + + /** + * @dev Returns the account approved for `tokenId` token. + * + * Requirements: + * + * - `tokenId` must exist. + */ + function getApproved( + uint256 tokenId + ) external view returns (address operator); + + /** + * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. + * + * See {setApprovalForAll} + */ + function isApprovedForAll( + address owner, + address operator + ) external view returns (bool); +} diff --git a/contracts/interfaces/IBarz.sol b/contracts/interfaces/IBarz.sol new file mode 100644 index 0000000..3ffa413 --- /dev/null +++ b/contracts/interfaces/IBarz.sol @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.21; + +/** + * @title Barz Interface + * @dev Interface of Barz + * @author David Yongjun Kim (@Powerstream3604) + */ +interface IBarz { + error Barz__InitializationFailure(); +} diff --git a/contracts/interfaces/IBarzFactory.sol b/contracts/interfaces/IBarzFactory.sol new file mode 100644 index 0000000..28ca16a --- /dev/null +++ b/contracts/interfaces/IBarzFactory.sol @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.21; + +import {Barz} from "../Barz.sol"; + +/** + * @title Barz Factory Interface + * @dev Interface of contract to easily deploy Barz to a pre-computed address with a single call + * @author David Yongjun Kim (@Powerstream3604) + */ +interface IBarzFactory { + event BarzDeployed(address); + + function createAccount( + address verificationFacet, + bytes calldata owner, + uint256 salt + ) external returns (Barz); + + function getAddress( + address verificationFacet, + bytes calldata owner, + uint256 salt + ) external view returns (address); + + function getBytecode( + address accountFacet, + address verificationFacet, + address entryPoint, + address facetRegistry, + address defaultFallback, + bytes memory ownerPublicKey + ) external pure returns (bytes memory); + + function getCreationCode() external pure returns (bytes memory); +} diff --git a/contracts/libraries/DefaultLibDiamond.sol b/contracts/libraries/DefaultLibDiamond.sol new file mode 100644 index 0000000..ccea294 --- /dev/null +++ b/contracts/libraries/DefaultLibDiamond.sol @@ -0,0 +1,323 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.21; + +import {IDiamondCut} from "../facets/base/interfaces/IDiamondCut.sol"; + +error InitializationFunctionReverted( + address _initializationContractAddress, + bytes _calldata +); + +library DefaultLibDiamond { + bytes32 constant DIAMOND_STORAGE_POSITION = + keccak256("trustwallet.barz.diamond.storage"); + + struct FacetAddressAndPosition { + address facetAddress; + uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array + } + + struct FacetFunctionSelectors { + bytes4[] functionSelectors; + uint256 facetAddressPosition; // position of facetAddress in facetAddresses array + } + + struct DiamondStorage { + // maps function selector to the facet address and + // the position of the selector in the facetFunctionSelectors.selectors array + mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition; + // maps facet addresses to function selectors + mapping(address => FacetFunctionSelectors) facetFunctionSelectors; + // facet addresses + address[] facetAddresses; + // Used to query if a contract implements an interface. + // Used to implement ERC-165. + mapping(bytes4 => bool) supportedInterfaces; + } + + function diamondStorage() + internal + pure + returns (DiamondStorage storage ds) + { + bytes32 position = DIAMOND_STORAGE_POSITION; + assembly { + ds.slot := position + } + } + + event DiamondCut( + IDiamondCut.FacetCut[] _diamondCut, + address _init, + bytes _calldata + ); + + // Internal function version of diamondCut + function diamondCut( + IDiamondCut.FacetCut[] memory _diamondCut, + address _init, + bytes memory _calldata + ) internal { + for ( + uint256 facetIndex; + facetIndex < _diamondCut.length; + facetIndex++ + ) { + IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action; + if (action == IDiamondCut.FacetCutAction.Add) { + addFunctions( + _diamondCut[facetIndex].facetAddress, + _diamondCut[facetIndex].functionSelectors + ); + } else if (action == IDiamondCut.FacetCutAction.Replace) { + replaceFunctions( + _diamondCut[facetIndex].facetAddress, + _diamondCut[facetIndex].functionSelectors + ); + } else if (action == IDiamondCut.FacetCutAction.Remove) { + removeFunctions( + _diamondCut[facetIndex].facetAddress, + _diamondCut[facetIndex].functionSelectors + ); + } else { + revert("LibDiamondCut: Incorrect FacetCutAction"); + } + } + emit DiamondCut(_diamondCut, _init, _calldata); + initializeDiamondCut(_init, _calldata); + } + + function addFunctions( + address _facetAddress, + bytes4[] memory _functionSelectors + ) internal { + uint256 funcSelectorsLength = _functionSelectors.length; + require( + funcSelectorsLength > 0, + "LibDiamondCut: No selectors in facet to cut" + ); + DiamondStorage storage ds = diamondStorage(); + require( + _facetAddress != address(0), + "LibDiamondCut: Add facet can't be address(0)" + ); + uint96 selectorPosition = uint96( + ds.facetFunctionSelectors[_facetAddress].functionSelectors.length + ); + // add new facet address if it does not exist + if (selectorPosition == 0) { + addFacet(ds, _facetAddress); + } + for ( + uint256 selectorIndex; + selectorIndex < funcSelectorsLength; + selectorIndex++ + ) { + bytes4 selector = _functionSelectors[selectorIndex]; + address oldFacetAddress = ds + .selectorToFacetAndPosition[selector] + .facetAddress; + require( + oldFacetAddress == address(0), + "LibDiamondCut: Can't add function that already exists" + ); + addFunction(ds, selector, selectorPosition, _facetAddress); + selectorPosition++; + } + } + + function replaceFunctions( + address _facetAddress, + bytes4[] memory _functionSelectors + ) internal { + uint256 funcSelectorsLength = _functionSelectors.length; + require( + funcSelectorsLength > 0, + "LibDiamondCut: No selectors in facet to cut" + ); + DiamondStorage storage ds = diamondStorage(); + require( + _facetAddress != address(0), + "LibDiamondCut: Replace facet can't be address(0)" + ); + uint96 selectorPosition = uint96( + ds.facetFunctionSelectors[_facetAddress].functionSelectors.length + ); + // add new facet address if it does not exist + if (selectorPosition == 0) { + addFacet(ds, _facetAddress); + } + for ( + uint256 selectorIndex; + selectorIndex < funcSelectorsLength; + selectorIndex++ + ) { + bytes4 selector = _functionSelectors[selectorIndex]; + address oldFacetAddress = ds + .selectorToFacetAndPosition[selector] + .facetAddress; + require( + oldFacetAddress != _facetAddress, + "LibDiamondCut: Can't replace function with same facet" + ); + removeFunction(ds, oldFacetAddress, selector); + addFunction(ds, selector, selectorPosition, _facetAddress); + selectorPosition++; + } + } + + function removeFunctions( + address _facetAddress, + bytes4[] memory _functionSelectors + ) internal { + uint256 funcSelectorsLength = _functionSelectors.length; + require( + funcSelectorsLength > 0, + "LibDiamondCut: No selectors in facet to cut" + ); + DiamondStorage storage ds = diamondStorage(); + // if function does not exist then do nothing and return + require( + _facetAddress == address(0), + "LibDiamondCut: Remove facet address must be address(0)" + ); + for ( + uint256 selectorIndex; + selectorIndex < funcSelectorsLength; + selectorIndex++ + ) { + bytes4 selector = _functionSelectors[selectorIndex]; + address oldFacetAddress = ds + .selectorToFacetAndPosition[selector] + .facetAddress; + removeFunction(ds, oldFacetAddress, selector); + } + } + + function addFacet( + DiamondStorage storage ds, + address _facetAddress + ) internal { + enforceHasContractCode( + _facetAddress, + "LibDiamondCut: New facet has no code" + ); + ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds + .facetAddresses + .length; + ds.facetAddresses.push(_facetAddress); + } + + function addFunction( + DiamondStorage storage ds, + bytes4 _selector, + uint96 _selectorPosition, + address _facetAddress + ) internal { + ds + .selectorToFacetAndPosition[_selector] + .functionSelectorPosition = _selectorPosition; + ds.facetFunctionSelectors[_facetAddress].functionSelectors.push( + _selector + ); + ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress; + } + + function removeFunction( + DiamondStorage storage ds, + address _facetAddress, + bytes4 _selector + ) internal { + require( + _facetAddress != address(0), + "LibDiamondCut: Can't remove function that doesn't exist" + ); + // an immutable function is a function defined directly in a diamond + require( + _facetAddress != address(this), + "LibDiamondCut: Can't remove immutable function" + ); + // replace selector with last selector, then delete last selector + uint256 selectorPosition = ds + .selectorToFacetAndPosition[_selector] + .functionSelectorPosition; + uint256 lastSelectorPosition = ds + .facetFunctionSelectors[_facetAddress] + .functionSelectors + .length - 1; + // if not the same then replace _selector with lastSelector + if (selectorPosition != lastSelectorPosition) { + bytes4 lastSelector = ds + .facetFunctionSelectors[_facetAddress] + .functionSelectors[lastSelectorPosition]; + ds.facetFunctionSelectors[_facetAddress].functionSelectors[ + selectorPosition + ] = lastSelector; + ds + .selectorToFacetAndPosition[lastSelector] + .functionSelectorPosition = uint96(selectorPosition); + } + // delete the last selector + ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop(); + delete ds.selectorToFacetAndPosition[_selector]; + + // if no more selectors for facet address then delete the facet address + if (lastSelectorPosition == 0) { + // replace facet address with last facet address and delete last facet address + uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1; + uint256 facetAddressPosition = ds + .facetFunctionSelectors[_facetAddress] + .facetAddressPosition; + if (facetAddressPosition != lastFacetAddressPosition) { + address lastFacetAddress = ds.facetAddresses[ + lastFacetAddressPosition + ]; + ds.facetAddresses[facetAddressPosition] = lastFacetAddress; + ds + .facetFunctionSelectors[lastFacetAddress] + .facetAddressPosition = facetAddressPosition; + } + ds.facetAddresses.pop(); + delete ds + .facetFunctionSelectors[_facetAddress] + .facetAddressPosition; + } + } + + function initializeDiamondCut( + address _init, + bytes memory _calldata + ) internal { + if (_init == address(0)) { + return; + } + enforceHasContractCode( + _init, + "LibDiamondCut: _init address has no code" + ); + (bool success, bytes memory error) = _init.delegatecall(_calldata); + if (!success) { + if (error.length > 0) { + // bubble up error + /// @solidity memory-safe-assembly + assembly { + let returndata_size := mload(error) + revert(add(32, error), returndata_size) + } + } else { + revert InitializationFunctionReverted(_init, _calldata); + } + } + } + + function enforceHasContractCode( + address _contract, + string memory _errorMessage + ) internal view { + uint256 contractSize; + assembly { + contractSize := extcodesize(_contract) + } + require(contractSize > 0, _errorMessage); + } +} diff --git a/contracts/libraries/LibAppStorage.sol b/contracts/libraries/LibAppStorage.sol new file mode 100644 index 0000000..dde5aa6 --- /dev/null +++ b/contracts/libraries/LibAppStorage.sol @@ -0,0 +1,136 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.21; + +import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol"; +import {IEntryPoint} from "../aa-4337/interfaces/IEntryPoint.sol"; +import {IFacetRegistry} from "../infrastructure/interfaces/IFacetRegistry.sol"; + +/* + * @title App Storage + * @dev App storage for Barz contract to prevent storage collision + * @author David Yongjun Kim (@Powerstream3604) + * @author Ruslan Serebriakov (@rsrbk) + */ + +struct Lock { + uint64 release; + bytes4 locker; +} + +struct InitializersStorage { + // NOTE: initialized is a variable to make sure the initialization is only done once. + uint8 signerInitialized; + uint8 accountInitialized; + uint8 restrictionsInitialized; +} + +struct AppStorage { + mapping(uint256 => InitializersStorage) initStorage; + uint8 signerMigration; + bytes4 validateOwnerSignatureSelector; + IEntryPoint entryPoint; + IFacetRegistry facetRegistry; + mapping(uint256 => Lock) locks; +} + +library LibAppStorage { + error LibAppStorage__AccountAlreadyUninitialized(); + error LibAppStorage__AccountMustBeUninitialized(); + error LibAppStorage__SignerAlreadyUninitialized(); + error LibAppStorage__SignerMustBeUninitialized(); + + function appStorage() internal pure returns (AppStorage storage ds) { + assembly { + ds.slot := 0 + } + } + + function setSignerUninitialized() internal { + AppStorage storage s = appStorage(); + if (1 != s.initStorage[0].signerInitialized) { + revert LibAppStorage__SignerAlreadyUninitialized(); + } + s.initStorage[0].signerInitialized = 0; + } + + function getValidateOwnerSignatureSelector() + internal + view + returns (bytes4 selector) + { + selector = appStorage().validateOwnerSignatureSelector; + } + + function setValidateOwnerSignatureSelector( + bytes4 _validateOwnerSignatureSelector + ) internal { + appStorage() + .validateOwnerSignatureSelector = _validateOwnerSignatureSelector; + } + + function enforceSignerInitialize() internal { + AppStorage storage s = appStorage(); + if (0 != s.initStorage[0].signerInitialized) { + revert LibAppStorage__SignerMustBeUninitialized(); + } + s.initStorage[0].signerInitialized = 1; + } + + function enforceAccountInitialize() internal { + AppStorage storage s = appStorage(); + if (0 != s.initStorage[0].accountInitialized) { + revert LibAppStorage__AccountMustBeUninitialized(); + } + s.initStorage[0].accountInitialized = 1; + } + + function initiateSignerMigration() internal { + appStorage().signerMigration = 1; + } + + function enforceSignerMigration() internal view { + if (1 != appStorage().signerMigration) { + revert LibAppStorage__AccountMustBeUninitialized(); + } + } + + function finalizeSignerMigration() internal { + appStorage().signerMigration = 0; + } + + function setLock(uint256 _releaseAfter, bytes4 _locker) internal { + appStorage().locks[0] = Lock(SafeCast.toUint64(_releaseAfter), _locker); + } + + function enforceRestrictionsInitialize() internal { + AppStorage storage s = appStorage(); + if (0 != s.initStorage[0].restrictionsInitialized) + revert LibAppStorage__SignerMustBeUninitialized(); + s.initStorage[0].restrictionsInitialized = 1; + } + + function setRestrictionsUninitialized() internal { + AppStorage storage s = appStorage(); + if (1 != s.initStorage[0].restrictionsInitialized) + revert LibAppStorage__AccountAlreadyUninitialized(); + s.initStorage[0].restrictionsInitialized = 0; + } +} + +contract BarzStorage { + AppStorage internal s; + modifier onlyWhenUnlocked() { + require( + uint64(block.timestamp) >= s.locks[0].release, + "Account Locked" + ); + _; + } + modifier onlyWhenLocked() { + require( + uint64(block.timestamp) < s.locks[0].release, + "Account Unlocked" + ); + _; + } +} diff --git a/contracts/libraries/LibDiamond.sol b/contracts/libraries/LibDiamond.sol new file mode 100644 index 0000000..07821fe --- /dev/null +++ b/contracts/libraries/LibDiamond.sol @@ -0,0 +1,321 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.21; + +import {IDiamondCut} from "../facets/base/interfaces/IDiamondCut.sol"; +import {IDiamondLoupe} from "../facets/base/interfaces/IDiamondLoupe.sol"; + +error InitializationFunctionReverted( + address _initializationContractAddress, + bytes _calldata +); + +library LibDiamond { + bytes32 constant DIAMOND_STORAGE_POSITION = + keccak256("trustwallet.barz.diamond.storage"); + bytes4 constant RESTRICTIONS_FACET_SELECTOR = + bytes4(keccak256("verifyRestrictions(address,address,uint256,bytes)")); + struct DiamondStorage { + // maps function selectors to the facets that execute the functions. + // and maps the selectors to their position in the selectorSlots array. + // func selector => address facet, selector position + mapping(bytes4 => bytes32) facets; + // array of slots of function selectors. + // each slot holds 8 function selectors. + mapping(uint256 => bytes32) selectorSlots; + // The number of function selectors in selectorSlots + uint16 selectorCount; + // Used to query if a contract implements an interface. + // Used to implement ERC-165. + mapping(bytes4 => bool) supportedInterfaces; + // Default Fallback Handler of the barz. + IDiamondLoupe defaultFallbackHandler; + } + + function diamondStorage() + internal + pure + returns (DiamondStorage storage ds) + { + bytes32 position = DIAMOND_STORAGE_POSITION; + assembly { + ds.slot := position + } + } + + function enforceIsSelf() internal view { + require(msg.sender == address(this), "LibDiamond: Caller not self"); + } + + event DiamondCut( + IDiamondCut.FacetCut[] _diamondCut, + address _init, + bytes _calldata + ); + + bytes32 constant CLEAR_ADDRESS_MASK = + bytes32(uint256(0xffffffffffffffffffffffff)); + bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224)); + + // Internal function version of diamondCut + // This code is almost the same as the external diamondCut, + // except it is using 'Facet[] memory _diamondCut' instead of + // 'Facet[] calldata _diamondCut'. + // The code is duplicated to prevent copying calldata to memory which + // causes an error for a two dimensional array. + function diamondCut( + IDiamondCut.FacetCut[] memory _diamondCut, + address _init, + bytes memory _calldata + ) internal { + DiamondStorage storage ds = diamondStorage(); + uint256 originalSelectorCount = ds.selectorCount; + uint256 selectorCount = originalSelectorCount; + bytes32 selectorSlot; + // Check if last selector slot is not full + // "selectorCount & 7" is a gas efficient modulo by eight "selectorCount % 8" + if (selectorCount & 7 > 0) { + // get last selectorSlot + // "selectorSlot >> 3" is a gas efficient division by 8 "selectorSlot / 8" + selectorSlot = ds.selectorSlots[selectorCount >> 3]; + } + // loop through diamond cut + for (uint256 facetIndex; facetIndex < _diamondCut.length; ) { + (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors( + selectorCount, + selectorSlot, + _diamondCut[facetIndex].facetAddress, + _diamondCut[facetIndex].action, + _diamondCut[facetIndex].functionSelectors + ); + + unchecked { + facetIndex++; + } + } + if (selectorCount != originalSelectorCount) { + ds.selectorCount = uint16(selectorCount); + } + // If last selector slot is not full + // "selectorCount & 7" is a gas efficient modulo by eight "selectorCount % 8" + if (selectorCount & 7 > 0) { + // "selectorSlot >> 3" is a gas efficient division by 8 "selectorSlot / 8" + ds.selectorSlots[selectorCount >> 3] = selectorSlot; + } + emit DiamondCut(_diamondCut, _init, _calldata); + initializeDiamondCut(_init, _calldata); + } + + function addReplaceRemoveFacetSelectors( + uint256 _selectorCount, + bytes32 _selectorSlot, + address _newFacetAddress, + IDiamondCut.FacetCutAction _action, + bytes4[] memory _selectors + ) internal returns (uint256, bytes32) { + DiamondStorage storage ds = diamondStorage(); + require( + _selectors.length > 0, + "LibDiamondCut: No selectors in facet to cut" + ); + if (_action == IDiamondCut.FacetCutAction.Add) { + enforceHasContractCode( + _newFacetAddress, + "LibDiamondCut: Add facet has no code" + ); + for (uint256 selectorIndex; selectorIndex < _selectors.length; ) { + bytes4 selector = _selectors[selectorIndex]; + bytes32 oldFacet = ds.facets[selector]; + require( + address(bytes20(oldFacet)) == address(0), + "LibDiamondCut: Can't add function that already exists" + ); + // add facet for selector + ds.facets[selector] = + bytes20(_newFacetAddress) | + bytes32(_selectorCount); + // "_selectorCount & 7" is a gas efficient modulo by eight "_selectorCount % 8" + // " << 5 is the same as multiplying by 32 ( * 32) + uint256 selectorInSlotPosition = (_selectorCount & 7) << 5; + // clear selector position in slot and add selector + _selectorSlot = + (_selectorSlot & + ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) | + (bytes32(selector) >> selectorInSlotPosition); + // if slot is full then write it to storage + if (selectorInSlotPosition == 224) { + // "_selectorSlot >> 3" is a gas efficient division by 8 "_selectorSlot / 8" + ds.selectorSlots[_selectorCount >> 3] = _selectorSlot; + _selectorSlot = 0; + } + _selectorCount++; + + unchecked { + selectorIndex++; + } + } + } else if (_action == IDiamondCut.FacetCutAction.Replace) { + enforceHasContractCode( + _newFacetAddress, + "LibDiamondCut: Replace facet has no code" + ); + for (uint256 selectorIndex; selectorIndex < _selectors.length; ) { + bytes4 selector = _selectors[selectorIndex]; + bytes32 oldFacet = ds.facets[selector]; + address oldFacetAddress = address(bytes20(oldFacet)); + // only useful if immutable functions exist + require( + oldFacetAddress != address(this), + "LibDiamondCut: Can't replace immutable function" + ); + require( + oldFacetAddress != _newFacetAddress, + "LibDiamondCut: Can't replace function with same function" + ); + require( + oldFacetAddress != address(0), + "LibDiamondCut: Can't replace function that doesn't exist" + ); + // replace old facet address + ds.facets[selector] = + (oldFacet & CLEAR_ADDRESS_MASK) | + bytes20(_newFacetAddress); + + unchecked { + selectorIndex++; + } + } + } else if (_action == IDiamondCut.FacetCutAction.Remove) { + require( + _newFacetAddress == address(0), + "LibDiamondCut: Remove facet address must be address(0)" + ); + // "_selectorCount >> 3" is a gas efficient division by 8 "_selectorCount / 8" + uint256 selectorSlotCount = _selectorCount >> 3; + // "_selectorCount & 7" is a gas efficient modulo by eight "_selectorCount % 8" + uint256 selectorInSlotIndex = _selectorCount & 7; + for (uint256 selectorIndex; selectorIndex < _selectors.length; ) { + if (_selectorSlot == 0) { + // get last selectorSlot + selectorSlotCount--; + _selectorSlot = ds.selectorSlots[selectorSlotCount]; + selectorInSlotIndex = 7; + } else { + selectorInSlotIndex--; + } + bytes4 lastSelector; + uint256 oldSelectorsSlotCount; + uint256 oldSelectorInSlotPosition; + // adding a block here prevents stack too deep error + { + bytes4 selector = _selectors[selectorIndex]; + bytes32 oldFacet = ds.facets[selector]; + require( + address(bytes20(oldFacet)) != address(0), + "LibDiamondCut: Can't remove function that doesn't exist" + ); + // only useful if immutable functions exist + require( + address(bytes20(oldFacet)) != address(this), + "LibDiamondCut: Can't remove immutable function" + ); + // replace selector with last selector in ds.facets + // gets the last selector + // " << 5 is the same as multiplying by 32 ( * 32) + lastSelector = bytes4( + _selectorSlot << (selectorInSlotIndex << 5) + ); + if (lastSelector != selector) { + // update last selector slot position info + ds.facets[lastSelector] = + (oldFacet & CLEAR_ADDRESS_MASK) | + bytes20(ds.facets[lastSelector]); + } + delete ds.facets[selector]; + uint256 oldSelectorCount = uint16(uint256(oldFacet)); + // "oldSelectorCount >> 3" is a gas efficient division by 8 "oldSelectorCount / 8" + oldSelectorsSlotCount = oldSelectorCount >> 3; + // "oldSelectorCount & 7" is a gas efficient modulo by eight "oldSelectorCount % 8" + // " << 5 is the same as multiplying by 32 ( * 32) + oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5; + } + if (oldSelectorsSlotCount != selectorSlotCount) { + bytes32 oldSelectorSlot = ds.selectorSlots[ + oldSelectorsSlotCount + ]; + // clears the selector we are deleting and puts the last selector in its place. + oldSelectorSlot = + (oldSelectorSlot & + ~(CLEAR_SELECTOR_MASK >> + oldSelectorInSlotPosition)) | + (bytes32(lastSelector) >> oldSelectorInSlotPosition); + // update storage with the modified slot + ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot; + } else { + // clears the selector we are deleting and puts the last selector in its place. + _selectorSlot = + (_selectorSlot & + ~(CLEAR_SELECTOR_MASK >> + oldSelectorInSlotPosition)) | + (bytes32(lastSelector) >> oldSelectorInSlotPosition); + } + if (selectorInSlotIndex == 0) { + delete ds.selectorSlots[selectorSlotCount]; + _selectorSlot = 0; + } + + unchecked { + selectorIndex++; + } + } + _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex; + } else { + revert("LibDiamondCut: Incorrect FacetCutAction"); + } + return (_selectorCount, _selectorSlot); + } + + function initializeDiamondCut( + address _init, + bytes memory _calldata + ) internal { + if (_init == address(0)) { + return; + } + enforceHasContractCode( + _init, + "LibDiamondCut: _init address has no code" + ); + (bool success, bytes memory error) = _init.delegatecall(_calldata); + if (!success) { + if (error.length > 0) { + // bubble up error + /// @solidity memory-safe-assembly + assembly { + let returndata_size := mload(error) + revert(add(32, error), returndata_size) + } + } else { + revert InitializationFunctionReverted(_init, _calldata); + } + } + } + + function enforceHasContractCode( + address _contract, + string memory _errorMessage + ) internal view { + uint256 contractSize; + assembly { + contractSize := extcodesize(_contract) + } + require(contractSize > 0, _errorMessage); + } + + function restrictionsFacet() internal view returns (address facetAddress_) { + facetAddress_ = address( + bytes20( + LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR] + ) + ); + } +} diff --git a/contracts/libraries/LibFacetStorage.sol b/contracts/libraries/LibFacetStorage.sol new file mode 100644 index 0000000..f3a640f --- /dev/null +++ b/contracts/libraries/LibFacetStorage.sol @@ -0,0 +1,194 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.21; + +/** + * @title Facet Storage + * @dev Storage contract to store each facets variables with diamond storage + * @author David Yongjun Kim (@Powerstream3604) + * @author Ruslan Serebriakov (@rsrbk) + */ + +struct Secp256k1VerificationStorage { + address signer; +} + +struct Secp256r1VerificationStorage { + uint256[2] q; +} + +struct GuardianStorage { + mapping(bytes32 => uint256) pending; + mapping(uint8 => StorageConfig) configs; +} + +struct Info { + bool exists; + uint128 index; +} + +struct StorageConfig { + address[] addresses; + mapping(address => Info) info; +} + +struct RecoveryConfig { + bytes recoveryPublicKey; + uint64 executeAfter; +} + +struct ApprovalConfig { + bool isApproved; + uint64 validUntil; +} + +struct RecoveryApprovalConfig { + mapping(bytes32 => mapping(address => ApprovalConfig)) isNewOwnerApproved; +} + +struct RecoveryStorage { + mapping(uint8 => RecoveryConfig) recoveryConfigs; + mapping(uint8 => RecoveryApprovalConfig) recoveryApprovalConfigs; + uint128 nonce; +} + +struct RestrictionsStorage { + address[] restrictions; + mapping(address => bool) exists; +} + +struct SignatureMigrationConfig { + bytes migrationPublicKey; + address migrationVerificationFacet; + bytes4[] migrationSelectors; + uint64 migrateAfter; +} + +struct SignatureMigrationApprovalConfig { + mapping(bytes32 => mapping(address => ApprovalConfig)) isMigrationApproved; +} + +struct SignatureMigrationStorage { + mapping(uint8 => SignatureMigrationConfig) migrationConfigs; + mapping(uint8 => SignatureMigrationApprovalConfig) migrationApprovalConfigs; + uint128 nonce; +} + +struct DiamondCutApprovalConfig { + mapping(bytes32 => mapping(address => ApprovalConfig)) isDiamondCutApproved; +} + +struct DiamondCutStorage { + mapping(uint8 => DiamondCutApprovalConfig) diamondCutApprovalConfigs; + uint128 nonce; +} + +struct LockStorage { + uint128 nonce; +} + +library LibFacetStorage { + bytes32 constant K1_STORAGE_POSITION = + keccak256( + "v0.trustwallet.diamond.storage.Secp256k1VerificationStorage" + ); + bytes32 constant R1_STORAGE_POSITION = + keccak256( + "v0.trustwallet.diamond.storage.Secp256r1VerificationStorage" + ); + bytes32 constant GUARDIAN_STORAGE_POSITION = + keccak256("v0.trustwallet.diamond.storage.GuardianStorage"); + bytes32 constant RECOVERY_STORAGE_POSITION = + keccak256("v0.trustwallet.diamond.storage.RecoveryStorage"); + bytes32 constant RESTRICTION_STORAGE_POSITION = + keccak256("v0.trustwallet.diamond.storage.RestrictionsStorage"); + bytes32 constant MIGRATION_STORAGE_POSITION = + keccak256("v0.trustwallet.diamond.storage.SignatureMigrationStorage"); + bytes32 constant DIAMONDCUT_STORAGE_POSITION = + keccak256("v0.trustwallet.diamond.storage.DiamondCutStorage"); + bytes32 constant LOCK_STORAGE_POSITION = + keccak256("v0.trustwallet.diamond.storage.LockStorage"); + + function k1Storage() + internal + pure + returns (Secp256k1VerificationStorage storage ds) + { + bytes32 storagePosition = K1_STORAGE_POSITION; + assembly { + ds.slot := storagePosition + } + } + + function r1Storage() + internal + pure + returns (Secp256r1VerificationStorage storage ds) + { + bytes32 storagePosition = R1_STORAGE_POSITION; + assembly { + ds.slot := storagePosition + } + } + + function guardianStorage() + internal + pure + returns (GuardianStorage storage ds) + { + bytes32 storagePosition = GUARDIAN_STORAGE_POSITION; + assembly { + ds.slot := storagePosition + } + } + + function recoveryStorage() + internal + pure + returns (RecoveryStorage storage ds) + { + bytes32 storagePosition = RECOVERY_STORAGE_POSITION; + assembly { + ds.slot := storagePosition + } + } + + function restrictionsStorage() + internal + pure + returns (RestrictionsStorage storage ds) + { + bytes32 storagePosition = RESTRICTION_STORAGE_POSITION; + assembly { + ds.slot := storagePosition + } + } + + function migrationStorage() + internal + pure + returns (SignatureMigrationStorage storage ds) + { + bytes32 storagePosition = MIGRATION_STORAGE_POSITION; + assembly { + ds.slot := storagePosition + } + } + + function diamondCutStorage() + internal + pure + returns (DiamondCutStorage storage ds) + { + bytes32 storagePosition = DIAMONDCUT_STORAGE_POSITION; + assembly { + ds.slot := storagePosition + } + } + + function lockStorage() internal pure returns (LockStorage storage ds) { + bytes32 storagePosition = LOCK_STORAGE_POSITION; + assembly { + ds.slot := storagePosition + } + } +} diff --git a/contracts/libraries/LibGuardian.sol b/contracts/libraries/LibGuardian.sol new file mode 100644 index 0000000..2f8748e --- /dev/null +++ b/contracts/libraries/LibGuardian.sol @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.21; + +import {LibFacetStorage, StorageConfig} from "./LibFacetStorage.sol"; + +/** + * @title LibGuardian + * @dev Internal Library to provide utility feature for Guardians stored in Guardian Facet Storage + * @author David Yongjun Kim (@Powerstream3604) + */ +library LibGuardian { + function majorityOfGuardians() + internal + view + returns (uint256 guardianNumber) + { + uint256 guardianLength = guardianCount(); + guardianNumber = (guardianLength == 0) ? 0 : guardianLength / 2 + 1; + } + + function isGuardian(address _guardian) internal view returns (bool) { + StorageConfig storage config = LibFacetStorage + .guardianStorage() + .configs[0]; + return config.info[_guardian].exists; + } + + function guardianCount() internal view returns (uint256) { + StorageConfig storage config = LibFacetStorage + .guardianStorage() + .configs[0]; + return config.addresses.length; + } + + function getGuardians() internal view returns (address[] memory) { + StorageConfig storage config = LibFacetStorage + .guardianStorage() + .configs[0]; + address[] memory addresses = new address[](config.addresses.length); + uint256 addressesLen = config.addresses.length; + for (uint256 i; i < addressesLen; ) { + addresses[i] = config.addresses[i]; + unchecked { + ++i; + } + } + return addresses; + } +} diff --git a/contracts/libraries/LibLoupe.sol b/contracts/libraries/LibLoupe.sol new file mode 100644 index 0000000..d2a6ee4 --- /dev/null +++ b/contracts/libraries/LibLoupe.sol @@ -0,0 +1,173 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.21; + +import {IDiamondLoupe} from "../facets/base/interfaces/IDiamondLoupe.sol"; +import {LibDiamond} from "./LibDiamond.sol"; + +/** + * @title LibLoupe + * @dev Internal Library to provide utility feature for reading the state of diamond facets + * Originally from Diamond's implementation of Mudgen(author of EIP-2535) + */ +library LibLoupe { + /// @notice Gets all facets and their selectors. + /// @return facets_ Facet + function facets() + internal + view + returns (IDiamondLoupe.Facet[] memory facets_) + { + LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage(); + facets_ = new IDiamondLoupe.Facet[](ds.selectorCount); + uint16[] memory numFacetSelectors = new uint16[](ds.selectorCount); + uint256 numFacets; + uint256 selectorIndex; + // loop through function selectors + for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) { + bytes32 slot = ds.selectorSlots[slotIndex]; + for ( + uint256 selectorSlotIndex; + selectorSlotIndex < 8; + selectorSlotIndex++ + ) { + selectorIndex++; + if (selectorIndex > ds.selectorCount) { + break; + } + // " << 5 is the same as multiplying by 32 ( * 32) + bytes4 selector = bytes4(slot << (selectorSlotIndex << 5)); + address facetAddress_ = address(bytes20(ds.facets[selector])); + bool continueLoop; + for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) { + if (facets_[facetIndex].facetAddress == facetAddress_) { + facets_[facetIndex].functionSelectors[ + numFacetSelectors[facetIndex] + ] = selector; + // probably will never have more than 256 functions from one facet contract + require(numFacetSelectors[facetIndex] < 255); + numFacetSelectors[facetIndex]++; + continueLoop = true; + break; + } + } + if (continueLoop) { + continue; + } + facets_[numFacets].facetAddress = facetAddress_; + facets_[numFacets].functionSelectors = new bytes4[]( + ds.selectorCount + ); + facets_[numFacets].functionSelectors[0] = selector; + numFacetSelectors[numFacets] = 1; + numFacets++; + } + } + for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) { + uint256 numSelectors = numFacetSelectors[facetIndex]; + bytes4[] memory selectors = facets_[facetIndex].functionSelectors; + // setting the number of selectors + assembly { + mstore(selectors, numSelectors) + } + } + // setting the number of facets + assembly { + mstore(facets_, numFacets) + } + } + + /// @notice Gets all the function selectors supported by a specific facet. + /// @param _facet The facet address. + /// @return _facetFunctionSelectors The selectors associated with a facet address. + function facetFunctionSelectors( + address _facet + ) internal view returns (bytes4[] memory _facetFunctionSelectors) { + LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage(); + uint256 numSelectors; + _facetFunctionSelectors = new bytes4[](ds.selectorCount); + uint256 selectorIndex; + // loop through function selectors + for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) { + bytes32 slot = ds.selectorSlots[slotIndex]; + for ( + uint256 selectorSlotIndex; + selectorSlotIndex < 8; + selectorSlotIndex++ + ) { + selectorIndex++; + if (selectorIndex > ds.selectorCount) { + break; + } + // " << 5 is the same as multiplying by 32 ( * 32) + bytes4 selector = bytes4(slot << (selectorSlotIndex << 5)); + address facet = address(bytes20(ds.facets[selector])); + if (_facet == facet) { + _facetFunctionSelectors[numSelectors] = selector; + numSelectors++; + } + } + } + // Set the number of selectors in the array + assembly { + mstore(_facetFunctionSelectors, numSelectors) + } + } + + /// @notice Get all the facet addresses used by a diamond. + /// @return facetAddresses_ + function facetAddresses() + internal + view + returns (address[] memory facetAddresses_) + { + LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage(); + facetAddresses_ = new address[](ds.selectorCount); + uint256 numFacets; + uint256 selectorIndex; + // loop through function selectors + for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) { + bytes32 slot = ds.selectorSlots[slotIndex]; + for ( + uint256 selectorSlotIndex; + selectorSlotIndex < 8; + selectorSlotIndex++ + ) { + selectorIndex++; + if (selectorIndex > ds.selectorCount) { + break; + } + // " << 5 is the same as multiplying by 32 ( * 32) + bytes4 selector = bytes4(slot << (selectorSlotIndex << 5)); + address facetAddress_ = address(bytes20(ds.facets[selector])); + bool continueLoop; + for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) { + if (facetAddress_ == facetAddresses_[facetIndex]) { + continueLoop = true; + break; + } + } + if (continueLoop) { + continue; + } + facetAddresses_[numFacets] = facetAddress_; + numFacets++; + } + } + // Set the number of facet addresses in the array + assembly { + mstore(facetAddresses_, numFacets) + } + } + + /// @notice Gets the facet that supports the given selector. + /// @dev If facet is not found return address(0). + /// @param _functionSelector The function selector. + /// @return facetAddress_ The facet address. + function facetAddress( + bytes4 _functionSelector + ) internal view returns (address facetAddress_) { + facetAddress_ = address( + bytes20(LibDiamond.diamondStorage().facets[_functionSelector]) + ); + } +} diff --git a/contracts/libraries/LibMultiSigStorage.sol b/contracts/libraries/LibMultiSigStorage.sol new file mode 100644 index 0000000..36c2ea8 --- /dev/null +++ b/contracts/libraries/LibMultiSigStorage.sol @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.21; + +/** + * @title Multi-sig Storage + * @dev Storage contract for storing Multi-sig Facet variables in diamond storage pattern + * @author David Yongjun Kim (@Powerstream3604) + */ + +struct MultiSigStorage { + mapping(address => address) owners; + mapping(uint256 => mapping(address => mapping(bytes32 => uint256))) approvedHashes; + uint256 ownerCount; + uint256 threshold; + uint256 counter; +} + +library LibMultiSigStorage { + function multisigStorage() + internal + pure + returns (MultiSigStorage storage ds) + { + bytes32 storagePosition = keccak256( + "v0.trustwallet.diamond.storage.MultiSigStorage" + ); + assembly { + ds.slot := storagePosition + } + } +} diff --git a/contracts/libraries/LibRecoverSpender.sol b/contracts/libraries/LibRecoverSpender.sol new file mode 100644 index 0000000..67bedff --- /dev/null +++ b/contracts/libraries/LibRecoverSpender.sol @@ -0,0 +1,85 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.21; + +/** + * @title RecoverSpender + * @dev Library to determine the action and spender of calldata + * @author Ruslan Serebriakov (@rsrbk) + */ +library LibRecoverSpender { + // ERC20, ERC721 & ERC1155 transfers & approvals + bytes4 private constant ERC20_TRANSFER = + bytes4(keccak256("transfer(address,uint256)")); + bytes4 private constant ERC20_APPROVE = + bytes4(keccak256("approve(address,uint256)")); + bytes4 private constant ERC20_INCREASE_ALLOWANCE = + bytes4(keccak256("increaseAllowance(address,uint256)")); + bytes4 private constant ERC20_DECREASE_ALLOWANCE = + bytes4(keccak256("decreaseAllowance(address,uint256)")); + bytes4 private constant ERC721_SET_APPROVAL_FOR_ALL = + bytes4(keccak256("setApprovalForAll(address,bool)")); + bytes4 private constant ERC721_TRANSFER_FROM = + bytes4(keccak256("transferFrom(address,address,uint256)")); + bytes4 private constant ERC721_SAFE_TRANSFER_FROM = + bytes4(keccak256("safeTransferFrom(address,address,uint256)")); + bytes4 private constant ERC721_SAFE_TRANSFER_FROM_BYTES = + bytes4(keccak256("safeTransferFrom(address,address,uint256,bytes)")); + bytes4 private constant ERC1155_SAFE_TRANSFER_FROM = + bytes4( + keccak256("safeTransferFrom(address,address,uint256,uint256,bytes)") + ); + bytes4 private constant ERC1155_SAFE_BATCH_TRANSFER_FROM = + bytes4( + keccak256( + "safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)" + ) + ); + + /** + * @notice Helper method to recover the spender from a contract call. + * The method returns the contract unless the call is to a standard method of a ERC20/ERC721/ERC1155 token + * in which case the spender is recovered from the data. + * @param _to The target contract. + * @param _data The data payload. + */ + function _recover( + address _to, + bytes memory _data + ) internal pure returns (address spender) { + if (_data.length >= 68) { + bytes4 methodId; + // solhint-disable-next-line no-inline-assembly + assembly { + methodId := mload(add(_data, 0x20)) + } + if ( + methodId == ERC20_TRANSFER || + methodId == ERC20_APPROVE || + methodId == ERC20_INCREASE_ALLOWANCE || + methodId == ERC20_DECREASE_ALLOWANCE || + methodId == ERC721_SET_APPROVAL_FOR_ALL + ) { + // solhint-disable-next-line no-inline-assembly + assembly { + spender := mload(add(_data, 0x24)) + } + return spender; + } + if ( + methodId == ERC721_TRANSFER_FROM || + methodId == ERC721_SAFE_TRANSFER_FROM || + methodId == ERC721_SAFE_TRANSFER_FROM_BYTES || + methodId == ERC1155_SAFE_TRANSFER_FROM || + methodId == ERC1155_SAFE_BATCH_TRANSFER_FROM + ) { + // solhint-disable-next-line no-inline-assembly + assembly { + spender := mload(add(_data, 0x44)) + } + return spender; + } + } + + spender = _to; + } +} diff --git a/contracts/libraries/LibReentrancyGuardStorage.sol b/contracts/libraries/LibReentrancyGuardStorage.sol new file mode 100644 index 0000000..4763f36 --- /dev/null +++ b/contracts/libraries/LibReentrancyGuardStorage.sol @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.21; + +struct ReentrancyGuardStorage { + uint256 status; +} + +library LibReentrancyGuardStorage { + bytes32 private constant REENTRANCY_GUARD_STORAGE_POSITION = + keccak256("v0.trustwallet.diamond.storage.ReentrancyGuardStorage"); + + function reentrancyguardStorage() + internal + pure + returns (ReentrancyGuardStorage storage ds) + { + bytes32 storagePosition = REENTRANCY_GUARD_STORAGE_POSITION; + assembly { + ds.slot := storagePosition + } + } +} diff --git a/contracts/libraries/LibUtils.sol b/contracts/libraries/LibUtils.sol new file mode 100644 index 0000000..fc94cce --- /dev/null +++ b/contracts/libraries/LibUtils.sol @@ -0,0 +1,145 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.21; + +import {IDiamondLoupe} from "../facets/base/interfaces/IDiamondLoupe.sol"; + +library LibUtils { + // Internal utility functions + function mergeArrays( + bytes4[] memory _array1, + bytes4[] memory _array2 + ) internal pure returns (bytes4[] memory) { + uint256 length1 = _array1.length; + uint256 length2 = _array2.length; + bytes4[] memory mergedArray = new bytes4[](length1 + length2); + + for (uint256 i; i < length1; ) { + mergedArray[i] = _array1[i]; + unchecked { + ++i; + } + } + + for (uint256 i; i < length2; ) { + mergedArray[length1 + i] = _array2[i]; + unchecked { + ++i; + } + } + + return mergedArray; + } + + function removeFacetElement( + IDiamondLoupe.Facet[] memory _facets, + uint256 _index + ) internal pure returns (IDiamondLoupe.Facet[] memory) { + require(_index < _facets.length, "Invalid index"); + require(_facets.length != 0, "Invalid array"); + + // Create a new array with a length of `_facets.length - 1` + IDiamondLoupe.Facet[] memory newArray = new IDiamondLoupe.Facet[]( + _facets.length - 1 + ); + uint256 newArrayLength = newArray.length; + // Iterate over the original array, skipping the element at the specified `index` + for (uint256 i; i < newArrayLength; ) { + if (i < _index) { + newArray[i] = _facets[i]; + } else { + newArray[i] = _facets[i + 1]; + } + unchecked { + ++i; + } + } + + return newArray; + } + + function removeElement( + bytes4[] memory _array, + uint256 _index + ) internal pure returns (bytes4[] memory) { + require(_index < _array.length, "Invalid index"); + require(_array.length != 0, "Invalid array"); + + bytes4[] memory newArray = new bytes4[](_array.length - 1); + uint256 newArrayLength = newArray.length; + for (uint256 i; i < newArrayLength; ) { + if (i < _index) { + newArray[i] = _array[i]; + } else { + newArray[i] = _array[i + 1]; + } + unchecked { + ++i; + } + } + + return newArray; + } + + function setValue( + bytes4[] memory _keys, + address[] memory _values, + bytes4 _key, + address _value + ) internal pure returns (bytes4[] memory, address[] memory) { + uint256 index = findIndex(_keys, _key); + uint256 keysLength = _keys.length; + if (index < keysLength) { + _values[index] = _value; + } else { + // Create new storage arrays + bytes4[] memory newKeys = new bytes4[](keysLength + 1); + address[] memory newValues = new address[](_values.length + 1); + + // Copy values to the new storage arrays + for (uint256 i; i < keysLength; ) { + newKeys[i] = _keys[i]; + newValues[i] = _values[i]; + + unchecked { + ++i; + } + } + + // Add the new key-value pair + newKeys[keysLength] = _key; + newValues[_values.length] = _value; + + return (newKeys, newValues); + } + + // If the key already exists, return the original arrays + return (_keys, _values); + } + + function getValue( + bytes4[] memory _keys, + address[] memory _values, + bytes4 _key + ) internal pure returns (address) { + uint256 index = findIndex(_keys, _key); + if (index >= _keys.length) return address(0); + + return _values[index]; + } + + function findIndex( + bytes4[] memory _keys, + bytes4 _key + ) internal pure returns (uint256) { + uint256 keysLength = _keys.length; + for (uint256 i; i < keysLength; ) { + if (_keys[i] == _key) { + return i; + } + unchecked { + ++i; + } + } + return keysLength; + } +} diff --git a/contracts/libraries/LibVerification.sol b/contracts/libraries/LibVerification.sol new file mode 100644 index 0000000..0ab9147 --- /dev/null +++ b/contracts/libraries/LibVerification.sol @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.21; + +library LibVerification { + // keccak256( + // "EIP712Domain(uint256 chainId,address verifyingContract)" + // ); + bytes32 internal constant DOMAIN_SEPARATOR_TYPEHASH = 0x47e79534a245952e8b16893a336b85a3d9ea9fa8c573f3d803afb92a79469218; + // keccak256("BarzMessage(bytes message)") + bytes32 internal constant BARZ_MSG_TYPEHASH = 0xb1bcb804a4a3a1af3ee7920d949bdfd417ea1b736c3552c8d6563a229a619100; + + function domainSeparator() internal view returns (bytes32) { + return keccak256(abi.encode(DOMAIN_SEPARATOR_TYPEHASH, block.chainid, address(this))); + } + + function encodeMessageData(bytes memory message) internal view returns (bytes memory) { + bytes32 messageHash = keccak256(abi.encode(BARZ_MSG_TYPEHASH, keccak256(message))); + return abi.encodePacked("\x19\x01", domainSeparator(), messageHash); + } + + function getMessageHash(bytes32 message) internal view returns (bytes32) { + return keccak256(encodeMessageData(abi.encode(message))); + } + +} \ No newline at end of file diff --git a/contracts/restrictions/IRestriction.sol b/contracts/restrictions/IRestriction.sol new file mode 100644 index 0000000..d1aabbd --- /dev/null +++ b/contracts/restrictions/IRestriction.sol @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.21; + +/** + * @title Interface for restrictions + * @dev Restriction is a contract which decides whether to approve a certain kind of transaction, based on its internal logic. + * @author Ruslan Serebriakov (@rsrbk) + */ +interface IRestriction { + /** + * @dev Based on restriction's internal logic, it should accept or reject a certain transaction. + * @param from The address of the sender, that will be signing the transaction. + * @param to The receiving address. + * @param value Amount of ETH to transfer from sender to recipient. + * @param _calldata Optional field to include arbitrary data. + * @return bool value for whether the check is passed + */ + function check( + address from, + address to, + uint256 value, + bytes calldata _calldata + ) external returns (bool); +} diff --git a/contracts/restrictions/WhitelistRestriction.sol b/contracts/restrictions/WhitelistRestriction.sol new file mode 100644 index 0000000..b541754 --- /dev/null +++ b/contracts/restrictions/WhitelistRestriction.sol @@ -0,0 +1,55 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.21; + +import {LibRecoverSpender} from "../libraries/LibRecoverSpender.sol"; +import {WhitelistStorage} from "../infrastructure/WhitelistStorage.sol"; +import {IRestriction} from "./IRestriction.sol"; + +/** + * @title Whitelist Restriction + * @dev This restriction defines a list of accepted addresses and denies any interaction with addresses outside of it. + * @author Ruslan Serebriakov (@rsrbk) + */ +contract WhitelistRestriction is IRestriction { + WhitelistStorage public immutable whitelistStorage; + + constructor(WhitelistStorage _whitelistStorage) { + whitelistStorage = _whitelistStorage; + } + + /** + * @notice Helper method to recover the spender from a contract call. + * The method returns the contract unless the call is to a standard method of a ERC20/ERC721/ERC1155 token + * in which case the spender is recovered from the data. + * @param _to The target contract. + * @param _data The data payload. + */ + function recoverSpender( + address _to, + bytes memory _data + ) public pure returns (address spender) { + return LibRecoverSpender._recover(_to, _data); + } + + /* + * @dev IRestriction's implementation. It will allow transaction if the sender is whitelisted, or user, or the whitelist storage. + * @param _from The address of the sender, that will be signing the transaction. + * @param _to The receiving address. + * @param _calldata Optional field to include arbitrary data. + * @return result value for whether the check is passed + */ + function check( + address _from, + address _to, + uint256 /*_value*/, + bytes calldata _calldata + ) external view override returns (bool result) { + return + whitelistStorage.isWhitelisted( + _from, + LibRecoverSpender._recover(_to, _calldata) + ) || + _to == address(whitelistStorage) || + _to == msg.sender; + } +} diff --git a/contracts/test/TestCounter.sol b/contracts/test/TestCounter.sol new file mode 100644 index 0000000..cb47933 --- /dev/null +++ b/contracts/test/TestCounter.sol @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.21; + +contract TestCounter { + int private count = 0; + + event CounterIncremented(int count); + event CounterDecremented(int count); + + function incrementCounter() public { + count += 1; + emit CounterIncremented(count); + } + + function decrementCounter() public { + count -= 1; + emit CounterIncremented(count); + } + + function getCount() public view returns (int) { + return count; + } +} diff --git a/contracts/test/TestERC1155.sol b/contracts/test/TestERC1155.sol new file mode 100644 index 0000000..4a599e3 --- /dev/null +++ b/contracts/test/TestERC1155.sol @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity ^0.8.0; + +import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol"; +import "@openzeppelin/contracts/utils/Counters.sol"; + +contract TestERC1155 is ERC1155 { + using Counters for Counters.Counter; + + Counters.Counter private _tokenIds; + + constructor() ERC1155("") {} + + function mint(address account, uint256 amount) external { + uint256 tokenId = _getNextTokenId(); + _mint(account, tokenId, amount, ""); + } + + function mintBatch( + address to, + uint256[] calldata ids, + uint256[] calldata amounts, + bytes memory data + ) external { + require( + ids.length == amounts.length, + "TestERC1155: arrays length mismatch" + ); + + _mintBatch(to, ids, amounts, data); + } + + function _getNextTokenId() private returns (uint256) { + _tokenIds.increment(); + return _tokenIds.current(); + } +} diff --git a/contracts/test/TestERC777.sol b/contracts/test/TestERC777.sol new file mode 100644 index 0000000..eec12a0 --- /dev/null +++ b/contracts/test/TestERC777.sol @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity ^0.8.0; + +import "@openzeppelin/contracts/token/ERC777/ERC777.sol"; + +contract TestERC777 is ERC777 { + constructor( + address[] memory _operators + ) ERC777("TestERC777", "TERC777", _operators) {} + + function mint(address account, uint256 amount) external { + _mint(account, amount, "", ""); + } +} diff --git a/contracts/test/TestInvalidSecp256k1VerificationFacet.sol b/contracts/test/TestInvalidSecp256k1VerificationFacet.sol new file mode 100644 index 0000000..c8b3c6e --- /dev/null +++ b/contracts/test/TestInvalidSecp256k1VerificationFacet.sol @@ -0,0 +1,93 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.21; + +import {IVerificationFacet} from "../facets/interfaces/IVerificationFacet.sol"; +import {IERC1271} from "../interfaces/ERC/IERC1271.sol"; +import {AppStorage, LibAppStorage, BarzStorage} from "../libraries/LibAppStorage.sol"; +import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; +import {LibFacetStorage, Secp256k1VerificationStorage} from "../libraries/LibFacetStorage.sol"; +import {UserOperation} from "../aa-4337/interfaces/UserOperation.sol"; + +/** + * @title Test Secp256k1 verification facet + * @dev Default Ethereum's elliptic curve + * @author David Yongjun Kim (@Powerstream3604) + * @author Ruslan Serebriakov (@rsrbk) + */ +contract TestInvalidSecp256k1VerificationFacet is BarzStorage, IERC1271 { + using ECDSA for bytes32; + error Secp256k1VerificationFacet__InvalidSignerLength(); + error VerificationFacet__ValidateOwnerSignatureSelectorNotSet(); + + event SignerUninitialized(); + + constructor() { + LibAppStorage.enforceSignerInitialize(); + } + + // THIS INVALID FACET DOES NOT INCLUDE initializeSigner() + // THIS FACET IS USED TO TEST WHEN initializeSigner() DOESN'T EXIST IN FACET + + function uninitializeSigner() external returns (uint256 uninitSuccess) { + LibAppStorage.enforceSignerMigration(); + LibAppStorage.setSignerUninitialized(); + Secp256k1VerificationStorage storage k1Storage = LibFacetStorage + .k1Storage(); + k1Storage.signer = address(0); + + if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0)) + revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet(); + LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0)); + + uninitSuccess = 1; + + emit SignerUninitialized(); + } + + function validateOwnerSignature( + UserOperation calldata userOp, + bytes32 userOpHash + ) public view returns (uint256 validationData) { + Secp256k1VerificationStorage storage k1Storage = LibFacetStorage + .k1Storage(); + return validateSignature(userOp, userOpHash, k1Storage.signer); + } + + function validateSignature( + UserOperation calldata userOp, + bytes32 userOpHash, + address signer + ) public pure returns (uint256) { + bytes32 hash = userOpHash.toEthSignedMessageHash(); + if (signer != hash.recover(userOp.signature)) return 1; + return 0; + } + + // This is REMOVED for testing purpose + function validateOwnerSignatureSelector() public pure returns (bytes4) { + // return this.validateOwnerSignature.selector; + // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change + } + + function owner() public view returns (bytes memory) { + Secp256k1VerificationStorage storage k1Storage = LibFacetStorage + .k1Storage(); + return abi.encodePacked(k1Storage.signer); + } + + function isValidKeyType( + bytes memory _publicKey + ) public pure returns (bool) { + return (_publicKey.length == 65 && _publicKey[0] == 0x04); + } + + function isValidSignature( + bytes32 _hash, + bytes memory _signature + ) public view override returns (bytes4 magicValue) { + magicValue = (_hash.recover(_signature) == + LibFacetStorage.k1Storage().signer) + ? this.isValidSignature.selector + : bytes4(0xffffffff); + } +} diff --git a/contracts/test/TestNFT.sol b/contracts/test/TestNFT.sol new file mode 100644 index 0000000..d1ae680 --- /dev/null +++ b/contracts/test/TestNFT.sol @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity ^0.8.0; + +import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; +import "@openzeppelin/contracts/utils/Counters.sol"; + +contract TestNFT is ERC721 { + using Counters for Counters.Counter; + Counters.Counter private currentTokenId; + + constructor() ERC721("TestNFT", "TNFT") {} + + function mint(address recipient) public returns (uint256) { + currentTokenId.increment(); + uint256 newItemId = currentTokenId.current(); + _safeMint(recipient, newItemId); + return newItemId; + } +} diff --git a/contracts/test/TestToken.sol b/contracts/test/TestToken.sol new file mode 100644 index 0000000..1501176 --- /dev/null +++ b/contracts/test/TestToken.sol @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity 0.8.21; + +import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; + +contract TestToken is ERC20 { + constructor() + // solhint-disable-next-line no-empty-blocks + ERC20("TST", "TestToken") + {} + + function mint(address sender, uint256 amount) external { + _mint(sender, amount); + } +} diff --git a/deploy/1_deploy_DiamondCutFacet.ts b/deploy/1_deploy_DiamondCutFacet.ts new file mode 100644 index 0000000..1c56872 --- /dev/null +++ b/deploy/1_deploy_DiamondCutFacet.ts @@ -0,0 +1,29 @@ +import { HardhatRuntimeEnvironment } from 'hardhat/types' +import { DeployFunction } from 'hardhat-deploy/types' +import { Create2Factory } from '../src/Create2Factory' +import { ethers } from 'hardhat' +import { validateAddresses } from '../src/Utils' + +const deployDiamondCutFacet: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { + const provider = ethers.provider + const from = await provider.getSigner().getAddress() + let securityManager = process.env.SECURITY_MANAGER + let args = [securityManager] + if (!validateAddresses(args)) { + console.error("Security Manager is not set/invalid") + process.exit(1) + } + + await new Create2Factory(ethers.provider).deployFactory() + + const ret = await hre.deployments.deploy( + 'DiamondCutFacet', { + from, + args: args, + gasLimit: 6e6, + deterministicDeployment: true + }) + console.log('==DiamondCutFacet addr=', ret.address) +} + +export default deployDiamondCutFacet diff --git a/deploy/2_deploy_DiamondLoupeFacet.ts b/deploy/2_deploy_DiamondLoupeFacet.ts new file mode 100644 index 0000000..1c4d2a2 --- /dev/null +++ b/deploy/2_deploy_DiamondLoupeFacet.ts @@ -0,0 +1,22 @@ +import { HardhatRuntimeEnvironment } from 'hardhat/types' +import { DeployFunction } from 'hardhat-deploy/types' +import { Create2Factory } from '../src/Create2Factory' +import { ethers } from 'hardhat' + +const deployDiamondLoupeFacet: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { + const provider = ethers.provider + const from = await provider.getSigner().getAddress() + + await new Create2Factory(ethers.provider).deployFactory() + + const ret = await hre.deployments.deploy( + 'DiamondLoupeFacet', { + from, + args: [], + gasLimit: 6e6, + deterministicDeployment: true + }) + console.log('==DiamondLoupeFacet addr=', ret.address) +} + +export default deployDiamondLoupeFacet diff --git a/deploy/3_deploy_Secp256r1VerificationFacet.ts b/deploy/3_deploy_Secp256r1VerificationFacet.ts new file mode 100644 index 0000000..ab8b936 --- /dev/null +++ b/deploy/3_deploy_Secp256r1VerificationFacet.ts @@ -0,0 +1,22 @@ +import { HardhatRuntimeEnvironment } from 'hardhat/types' +import { DeployFunction } from 'hardhat-deploy/types' +import { Create2Factory } from '../src/Create2Factory' +import { ethers } from 'hardhat' + +const deploySecp256r1VerificationFacet: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { + const provider = ethers.provider + const from = await provider.getSigner().getAddress() + + await new Create2Factory(ethers.provider).deployFactory() + + const ret = await hre.deployments.deploy( + 'Secp256r1VerificationFacet', { + from, + args: [], + gasLimit: 6e6, + deterministicDeployment: true + }) + console.log('==Secp256r1VerificationFacet addr=', ret.address) +} + +export default deploySecp256r1VerificationFacet diff --git a/deploy/4_deploy_AccountFacet.ts b/deploy/4_deploy_AccountFacet.ts new file mode 100644 index 0000000..8c3b00c --- /dev/null +++ b/deploy/4_deploy_AccountFacet.ts @@ -0,0 +1,22 @@ +import { HardhatRuntimeEnvironment } from 'hardhat/types' +import { DeployFunction } from 'hardhat-deploy/types' +import { Create2Factory } from '../src/Create2Factory' +import { ethers } from 'hardhat' + +const deployAccountFacet: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { + const provider = ethers.provider + const from = await provider.getSigner().getAddress() + + await new Create2Factory(ethers.provider).deployFactory() + + const ret = await hre.deployments.deploy( + 'AccountFacet', { + from, + args: [], + gasLimit: 6e6, + deterministicDeployment: true + }) + console.log('==AccountFacet addr=', ret.address) +} + +export default deployAccountFacet diff --git a/deploy/5_deploy_TokenReceiverFacet.ts b/deploy/5_deploy_TokenReceiverFacet.ts new file mode 100644 index 0000000..58fb48c --- /dev/null +++ b/deploy/5_deploy_TokenReceiverFacet.ts @@ -0,0 +1,22 @@ +import { HardhatRuntimeEnvironment } from 'hardhat/types' +import { DeployFunction } from 'hardhat-deploy/types' +import { Create2Factory } from '../src/Create2Factory' +import { ethers } from 'hardhat' + +const deployTokenReceiver: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { + const provider = ethers.provider + const from = await provider.getSigner().getAddress() + + await new Create2Factory(ethers.provider).deployFactory() + + const ret = await hre.deployments.deploy( + 'TokenReceiverFacet', { + from, + args: [], + gasLimit: 6e6, + deterministicDeployment: true + }) + console.log('==TokenReceiverFacet addr=', ret.address) +} + +export default deployTokenReceiver diff --git a/deploy/6_deploy_DefaultFallback.ts b/deploy/6_deploy_DefaultFallback.ts new file mode 100644 index 0000000..71359c7 --- /dev/null +++ b/deploy/6_deploy_DefaultFallback.ts @@ -0,0 +1,32 @@ +import { HardhatRuntimeEnvironment } from 'hardhat/types' +import { DeployFunction } from 'hardhat-deploy/types' +import { Create2Factory } from '../src/Create2Factory' +import { ethers } from 'hardhat' +import { validateAddresses } from '../src/Utils' + +const deployDefaultFallbackHandler: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { + const provider = ethers.provider + const from = await provider.getSigner().getAddress() + let diamondCutFacet = process.env.DIAMOND_CUT_FACET + let accountFacet = process.env.ACCOUNT_FACET + let tokenReceiverFacet = process.env.TOKEN_RECEIVER_FACET + let diamondLoupeFacet = process.env.DIAMOND_LOUPE_FACET + let args = [diamondCutFacet, accountFacet, tokenReceiverFacet, diamondLoupeFacet] + if (!validateAddresses(args)) { + console.error("Contructor parameter address is not set/invalid") + process.exit(1) + } + + await new Create2Factory(ethers.provider).deployFactory() + + const ret = await hre.deployments.deploy( + 'DefaultFallbackHandler', { + from, + args: args, + gasLimit: 6e6, + deterministicDeployment: true + }) + console.log('==DefaultFallbackHandler addr=', ret.address) +} + +export default deployDefaultFallbackHandler diff --git a/deploy/7_deploy_BarzFactory.ts b/deploy/7_deploy_BarzFactory.ts new file mode 100644 index 0000000..1db9b11 --- /dev/null +++ b/deploy/7_deploy_BarzFactory.ts @@ -0,0 +1,32 @@ +import { HardhatRuntimeEnvironment } from 'hardhat/types' +import { DeployFunction } from 'hardhat-deploy/types' +import { Create2Factory } from '../src/Create2Factory' +import { ethers } from 'hardhat' +import { validateAddresses } from '../src/Utils' + +const deployBarzFactory: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { + const provider = ethers.provider + const from = await provider.getSigner().getAddress() + let accountFacet = process.env.ACCOUNT_FACET + let entrypoint = process.env.ENTRYPOINT + let facetRegistry = process.env.FACET_REGISTRY + let defaultFallbackHandler = process.env.DEFAULT_FALLBACK_HANDLER + let args = [accountFacet, entrypoint, facetRegistry, defaultFallbackHandler] + if (!validateAddresses(args)) { + console.error("Contructor parameter address is not set/invalid") + process.exit(1) + } + + await new Create2Factory(ethers.provider).deployFactory() + + const ret = await hre.deployments.deploy( + 'BarzFactory', { + from, + args: args, + gasLimit: 6e6, + deterministicDeployment: true + }) + console.log('==BarzFactory addr=', ret.address) +} + +export default deployBarzFactory diff --git a/deployments/arbitrum/.chainId b/deployments/arbitrum/.chainId new file mode 100644 index 0000000..7df83ec --- /dev/null +++ b/deployments/arbitrum/.chainId @@ -0,0 +1 @@ +42161 \ No newline at end of file diff --git a/deployments/arbitrum/AccountFacet.json b/deployments/arbitrum/AccountFacet.json new file mode 100644 index 0000000..2f48669 --- /dev/null +++ b/deployments/arbitrum/AccountFacet.json @@ -0,0 +1,591 @@ +{ + "address": "0xFde53272dcd7938d16E031A6989753c321728332", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "AccountFacet__CallNotSuccessful", + "type": "error" + }, + { + "inputs": [], + "name": "AccountFacet__InitializationFailure", + "type": "error" + }, + { + "inputs": [], + "name": "AccountFacet__InvalidArrayLength", + "type": "error" + }, + { + "inputs": [], + "name": "AccountFacet__NonExistentVerificationFacet", + "type": "error" + }, + { + "inputs": [], + "name": "AccountFacet__RestrictionsFailure", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_initializationContractAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "InitializationFunctionReverted", + "type": "error" + }, + { + "inputs": [], + "name": "LibAppStorage__AccountMustBeUninitialized", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract IEntryPoint", + "name": "entryPoint", + "type": "address" + }, + { + "indexed": true, + "internalType": "bytes", + "name": "ownerPublicKey", + "type": "bytes" + } + ], + "name": "AccountInitialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "indexed": false, + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "DiamondCut", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "VerificationFailure", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "VerificationSuccess", + "type": "event" + }, + { + "inputs": [], + "name": "entryPoint", + "outputs": [ + { + "internalType": "contract IEntryPoint", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_dest", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_func", + "type": "bytes" + } + ], + "name": "execute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_dest", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "_value", + "type": "uint256[]" + }, + { + "internalType": "bytes[]", + "name": "_func", + "type": "bytes[]" + } + ], + "name": "executeBatch", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getNonce", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_verificationFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_anEntryPoint", + "type": "address" + }, + { + "internalType": "address", + "name": "_facetRegistry", + "type": "address" + }, + { + "internalType": "address", + "name": "_defaultFallBackHandler", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_ownerPublicKey", + "type": "bytes" + } + ], + "name": "initialize", + "outputs": [ + { + "internalType": "uint256", + "name": "initSuccess", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "initCode", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "callGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "verificationGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "preVerificationGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxFeePerGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPriorityFeePerGas", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "paymasterAndData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "internalType": "struct UserOperation", + "name": "userOp", + "type": "tuple" + }, + { + "internalType": "bytes32", + "name": "userOpHash", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "missingAccountFunds", + "type": "uint256" + } + ], + "name": "validateUserOp", + "outputs": [ + { + "internalType": "uint256", + "name": "validationData", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0x3bd48955a5ce54452416678d2f1917deb7df283335478a801b14f46c8eb4c1c5", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 1, + "gasUsed": "16290897", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x1376f866848f1b8d3287c2da6d352b269603444ef28b42d5dd971cf7e66a7947", + "transactionHash": "0x3bd48955a5ce54452416678d2f1917deb7df283335478a801b14f46c8eb4c1c5", + "logs": [], + "blockNumber": 152284144, + "cumulativeGasUsed": "16290897", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 3, + "solcInputHash": "4356503edd8ae34e73cb6dd1c8e2fc8a", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AccountFacet__CallNotSuccessful\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AccountFacet__InitializationFailure\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AccountFacet__InvalidArrayLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AccountFacet__NonExistentVerificationFacet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AccountFacet__RestrictionsFailure\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_initializationContractAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"InitializationFunctionReverted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LibAppStorage__AccountMustBeUninitialized\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract IEntryPoint\",\"name\":\"entryPoint\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes\",\"name\":\"ownerPublicKey\",\"type\":\"bytes\"}],\"name\":\"AccountInitialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"DiamondCut\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"VerificationFailure\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"VerificationSuccess\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"entryPoint\",\"outputs\":[{\"internalType\":\"contract IEntryPoint\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_dest\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_func\",\"type\":\"bytes\"}],\"name\":\"execute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_dest\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"_value\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes[]\",\"name\":\"_func\",\"type\":\"bytes[]\"}],\"name\":\"executeBatch\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_verificationFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_anEntryPoint\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_facetRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_defaultFallBackHandler\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_ownerPublicKey\",\"type\":\"bytes\"}],\"name\":\"initialize\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"initSuccess\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"userOp\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"missingAccountFunds\",\"type\":\"uint256\"}],\"name\":\"validateUserOp\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"validationData\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"Account module contract that provides the account features and initialization of signer compatible with EIP-1271 & EIP-4337\",\"kind\":\"dev\",\"methods\":{\"execute(address,uint256,bytes)\":{\"details\":\"This method executes the calldata coming from the EntryPoint. Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\",\"params\":{\"_dest\":\"Address of destination where the call will be forwarded to\",\"_func\":\"Bytes of calldata to execute in the destination address\",\"_value\":\"Amount of native coin the owner is willing to send(e.g. ETH, BNB)\"}},\"executeBatch(address[],uint256[],bytes[])\":{\"details\":\"This method batch executes the calldata coming from the EntryPoint. Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\",\"params\":{\"_dest\":\"Array of addresses of destination where the call will be forwarded to\",\"_func\":\"Array of bytes of calldata to execute in the destination address\",\"_value\":\"Array of amount of native coin the owner is willing to send(e.g. ETH, BNB)\"}},\"initialize(address,address,address,address,bytes)\":{\"details\":\"This method can only be called during the initialization or signature migration. If the proxy contract was created without initialization, anyone can call initialize. Barz calls initialize in constructor in an atomic transaction during deployment\",\"params\":{\"_anEntryPoint\":\"Entrypoint contract defined in EIP-4337 handling the flow of UserOp\",\"_defaultFallBackHandler\":\"Middleware contract for default facets\",\"_facetRegistry\":\"Registry of Facets that hold all facet information\",\"_ownerPublicKey\":\"Bytes of owner public key\",\"_verificationFacet\":\"Facet contract handling the verificationi\"}}},\"title\":\"Account Facet\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"This constructor ensures that this contract can only be used as singleton for Proxy contracts\"},\"entryPoint()\":{\"notice\":\"Returns the address of EntryPoint contract registered to Barz account\"},\"execute(address,uint256,bytes)\":{\"notice\":\"Calls the destination with inputted calldata and value from EntryPoint\"},\"executeBatch(address[],uint256[],bytes[])\":{\"notice\":\"Batch calls the destination with inputted calldata and value from EntryPoint\"},\"getNonce()\":{\"notice\":\"Return the account nonce. This method returns the next sequential nonce. For a nonce of a specific key, use `entrypoint.getNonce(account, key)`\"},\"initialize(address,address,address,address,bytes)\":{\"notice\":\"Initializes the initial storage of the Barz contract.\"},\"validateUserOp((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256)\":{\"notice\":\"Validate user's signature and nonce. subclass doesn't need to override this method. Instead, it should override the specific internal validation methods.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/AccountFacet.sol\":\"AccountFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./math/Math.sol\\\";\\nimport \\\"./math/SignedMath.sol\\\";\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n uint256 length = Math.log10(value) + 1;\\n string memory buffer = new string(length);\\n uint256 ptr;\\n /// @solidity memory-safe-assembly\\n assembly {\\n ptr := add(buffer, add(32, length))\\n }\\n while (true) {\\n ptr--;\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\\n }\\n value /= 10;\\n if (value == 0) break;\\n }\\n return buffer;\\n }\\n }\\n\\n /**\\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\\n */\\n function toString(int256 value) internal pure returns (string memory) {\\n return string(abi.encodePacked(value < 0 ? \\\"-\\\" : \\\"\\\", toString(SignedMath.abs(value))));\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n return toHexString(value, Math.log256(value) + 1);\\n }\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n\\n /**\\n * @dev Returns true if the two strings are equal.\\n */\\n function equal(string memory a, string memory b) internal pure returns (bool) {\\n return keccak256(bytes(a)) == keccak256(bytes(b));\\n }\\n}\\n\",\"keccak256\":\"0x3088eb2868e8d13d89d16670b5f8612c4ab9ff8956272837d8e90106c59c14a0\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Strings.sol\\\";\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSA {\\n enum RecoverError {\\n NoError,\\n InvalidSignature,\\n InvalidSignatureLength,\\n InvalidSignatureS,\\n InvalidSignatureV // Deprecated in v4.8\\n }\\n\\n function _throwError(RecoverError error) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert(\\\"ECDSA: invalid signature\\\");\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert(\\\"ECDSA: invalid signature length\\\");\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert(\\\"ECDSA: invalid signature 's' value\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature` or error string. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n *\\n * Documentation for signature generation:\\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n return tryRecover(hash, v, r, s);\\n } else {\\n return (address(0), RecoverError.InvalidSignatureLength);\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature`. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, signature);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\\n uint8 v = uint8((uint256(vs) >> 255) + 27);\\n return tryRecover(hash, v, r, s);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n *\\n * _Available since v4.2._\\n */\\n function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\\n // the valid range for s in (301): 0 < s < secp256k1n \\u00f7 2 + 1, and for v in (302): v \\u2208 {27, 28}. Most\\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\\n //\\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\\n // these malleable signatures as well.\\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n return (address(0), RecoverError.InvalidSignatureS);\\n }\\n\\n // If the signature is valid (and not malleable), return the signer address\\n address signer = ecrecover(hash, v, r, s);\\n if (signer == address(0)) {\\n return (address(0), RecoverError.InvalidSignature);\\n }\\n\\n return (signer, RecoverError.NoError);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore(0x00, \\\"\\\\x19Ethereum Signed Message:\\\\n32\\\")\\n mstore(0x1c, hash)\\n message := keccak256(0x00, 0x3c)\\n }\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from `s`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n\\\", Strings.toString(s.length), s));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Typed Data, created from a\\n * `domainSeparator` and a `structHash`. This produces hash corresponding\\n * to the one signed with the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n * JSON-RPC method as part of EIP-712.\\n *\\n * See {recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n let ptr := mload(0x40)\\n mstore(ptr, \\\"\\\\x19\\\\x01\\\")\\n mstore(add(ptr, 0x02), domainSeparator)\\n mstore(add(ptr, 0x22), structHash)\\n data := keccak256(ptr, 0x42)\\n }\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Data with intended validator, created from a\\n * `validator` and `data` according to the version 0 of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x00\\\", validator, data));\\n }\\n}\\n\",\"keccak256\":\"0x809bc3edb4bcbef8263fa616c1b60ee0004b50a8a1bfa164d8f57fd31f520c58\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n enum Rounding {\\n Down, // Toward negative infinity\\n Up, // Toward infinity\\n Zero // Toward zero\\n }\\n\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow.\\n return (a & b) + (a ^ b) / 2;\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a == 0 ? 0 : (a - 1) / b + 1;\\n }\\n\\n /**\\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\\n * with further edits by Uniswap Labs also under MIT license.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\\n unchecked {\\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2^256 + prod0.\\n uint256 prod0; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division.\\n if (prod1 == 0) {\\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\\n // The surrounding unchecked block does not change this fact.\\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\\n return prod0 / denominator;\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n require(denominator > prod1, \\\"Math: mulDiv overflow\\\");\\n\\n ///////////////////////////////////////////////\\n // 512 by 256 division.\\n ///////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0].\\n uint256 remainder;\\n assembly {\\n // Compute remainder using mulmod.\\n remainder := mulmod(x, y, denominator)\\n\\n // Subtract 256 bit number from 512 bit number.\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\\n // See https://cs.stackexchange.com/q/138556/92363.\\n\\n // Does not overflow because the denominator cannot be zero at this stage in the function.\\n uint256 twos = denominator & (~denominator + 1);\\n assembly {\\n // Divide denominator by twos.\\n denominator := div(denominator, twos)\\n\\n // Divide [prod1 prod0] by twos.\\n prod0 := div(prod0, twos)\\n\\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\\n twos := add(div(sub(0, twos), twos), 1)\\n }\\n\\n // Shift in bits from prod1 into prod0.\\n prod0 |= prod1 * twos;\\n\\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\\n // four bits. That is, denominator * inv = 1 mod 2^4.\\n uint256 inverse = (3 * denominator) ^ 2;\\n\\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\\n // in modular arithmetic, doubling the correct bits in each step.\\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\\n\\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inverse;\\n return result;\\n }\\n }\\n\\n /**\\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\\n uint256 result = mulDiv(x, y, denominator);\\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\\n result += 1;\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\\n *\\n * Inspired by Henry S. Warren, Jr.'s \\\"Hacker's Delight\\\" (Chapter 11).\\n */\\n function sqrt(uint256 a) internal pure returns (uint256) {\\n if (a == 0) {\\n return 0;\\n }\\n\\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\\n //\\n // We know that the \\\"msb\\\" (most significant bit) of our target number `a` is a power of 2 such that we have\\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\\n //\\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\\n // \\u2192 `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\\n // \\u2192 `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\\n //\\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\\n uint256 result = 1 << (log2(a) >> 1);\\n\\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\\n // into the expected uint128 result.\\n unchecked {\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n return min(result, a / result);\\n }\\n }\\n\\n /**\\n * @notice Calculates sqrt(a), following the selected rounding direction.\\n */\\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = sqrt(a);\\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 2, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 128;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 64;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 32;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 16;\\n }\\n if (value >> 8 > 0) {\\n value >>= 8;\\n result += 8;\\n }\\n if (value >> 4 > 0) {\\n value >>= 4;\\n result += 4;\\n }\\n if (value >> 2 > 0) {\\n value >>= 2;\\n result += 2;\\n }\\n if (value >> 1 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log2(value);\\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 10, rounded down, of a positive value.\\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 + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 256, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n *\\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\\n */\\n function log256(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 16;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 8;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 4;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 2;\\n }\\n if (value >> 8 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log256(value);\\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe4455ac1eb7fc497bb7402579e7b4d64d928b846fce7d2b6fde06d366f21c2b3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\\n * checks.\\n *\\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\\n * easily result in undesired exploitation or bugs, since developers usually\\n * assume that overflows raise errors. `SafeCast` restores this intuition by\\n * reverting the transaction when such an operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n *\\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\\n * all math on `uint256` and `int256` and then downcasting.\\n */\\nlibrary SafeCast {\\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 * _Available since v4.7._\\n */\\n function toUint248(uint256 value) internal pure returns (uint248) {\\n require(value <= type(uint248).max, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint240(uint256 value) internal pure returns (uint240) {\\n require(value <= type(uint240).max, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint232(uint256 value) internal pure returns (uint232) {\\n require(value <= type(uint232).max, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint224(uint256 value) internal pure returns (uint224) {\\n require(value <= type(uint224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint216(uint256 value) internal pure returns (uint216) {\\n require(value <= type(uint216).max, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint208(uint256 value) internal pure returns (uint208) {\\n require(value <= type(uint208).max, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint200(uint256 value) internal pure returns (uint200) {\\n require(value <= type(uint200).max, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint192(uint256 value) internal pure returns (uint192) {\\n require(value <= type(uint192).max, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint184(uint256 value) internal pure returns (uint184) {\\n require(value <= type(uint184).max, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint176(uint256 value) internal pure returns (uint176) {\\n require(value <= type(uint176).max, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint168(uint256 value) internal pure returns (uint168) {\\n require(value <= type(uint168).max, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint160(uint256 value) internal pure returns (uint160) {\\n require(value <= type(uint160).max, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint152(uint256 value) internal pure returns (uint152) {\\n require(value <= type(uint152).max, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint144(uint256 value) internal pure returns (uint144) {\\n require(value <= type(uint144).max, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint136(uint256 value) internal pure returns (uint136) {\\n require(value <= type(uint136).max, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint128(uint256 value) internal pure returns (uint128) {\\n require(value <= type(uint128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint120(uint256 value) internal pure returns (uint120) {\\n require(value <= type(uint120).max, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint112(uint256 value) internal pure returns (uint112) {\\n require(value <= type(uint112).max, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint104(uint256 value) internal pure returns (uint104) {\\n require(value <= type(uint104).max, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint96(uint256 value) internal pure returns (uint96) {\\n require(value <= type(uint96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint88(uint256 value) internal pure returns (uint88) {\\n require(value <= type(uint88).max, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint80(uint256 value) internal pure returns (uint80) {\\n require(value <= type(uint80).max, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint72(uint256 value) internal pure returns (uint72) {\\n require(value <= type(uint72).max, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint64(uint256 value) internal pure returns (uint64) {\\n require(value <= type(uint64).max, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint56(uint256 value) internal pure returns (uint56) {\\n require(value <= type(uint56).max, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint48(uint256 value) internal pure returns (uint48) {\\n require(value <= type(uint48).max, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint40(uint256 value) internal pure returns (uint40) {\\n require(value <= type(uint40).max, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint32(uint256 value) internal pure returns (uint32) {\\n require(value <= type(uint32).max, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint24(uint256 value) internal pure returns (uint24) {\\n require(value <= type(uint24).max, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint16(uint256 value) internal pure returns (uint16) {\\n require(value <= type(uint16).max, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint8(uint256 value) internal pure returns (uint8) {\\n require(value <= type(uint8).max, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\n */\\n function toUint256(int256 value) internal pure returns (uint256) {\\n require(value >= 0, \\\"SafeCast: value must be positive\\\");\\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 * _Available since v4.7._\\n */\\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\\n downcasted = int248(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\\n downcasted = int240(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\\n downcasted = int232(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\\n downcasted = int224(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\\n downcasted = int216(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\\n downcasted = int208(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\\n downcasted = int200(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\\n downcasted = int192(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\\n downcasted = int184(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\\n downcasted = int176(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\\n downcasted = int168(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\\n downcasted = int160(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\\n downcasted = int152(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\\n downcasted = int144(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\\n downcasted = int136(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\\n downcasted = int128(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\\n downcasted = int120(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\\n downcasted = int112(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\\n downcasted = int104(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\\n downcasted = int96(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\\n downcasted = int88(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\\n downcasted = int80(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\\n downcasted = int72(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\\n downcasted = int64(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\\n downcasted = int56(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\\n downcasted = int48(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\\n downcasted = int40(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\\n downcasted = int32(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\\n downcasted = int24(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\\n downcasted = int16(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\\n downcasted = int8(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\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 require(value <= uint256(type(int256).max), \\\"SafeCast: value doesn't fit in an int256\\\");\\n return int256(value);\\n }\\n}\\n\",\"keccak256\":\"0x52a8cfb0f5239d11b457dcdd1b326992ef672714ca8da71a157255bddd13f3ad\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SignedMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard signed math utilities missing in the Solidity language.\\n */\\nlibrary SignedMath {\\n /**\\n * @dev Returns the largest of two signed numbers.\\n */\\n function max(int256 a, int256 b) internal pure returns (int256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two signed numbers.\\n */\\n function min(int256 a, int256 b) internal pure returns (int256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two signed numbers without overflow.\\n * The result is rounded towards zero.\\n */\\n function average(int256 a, int256 b) internal pure returns (int256) {\\n // Formula from the book \\\"Hacker's Delight\\\"\\n int256 x = (a & b) + ((a ^ b) >> 1);\\n return x + (int256(uint256(x) >> 255) & (a ^ b));\\n }\\n\\n /**\\n * @dev Returns the absolute unsigned value of a signed value.\\n */\\n function abs(int256 n) internal pure returns (uint256) {\\n unchecked {\\n // must be unchecked in order to support `n = type(int256).min`\\n return uint256(n >= 0 ? n : -n);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf92515413956f529d95977adc9b0567d583c6203fc31ab1c23824c35187e3ddc\",\"license\":\"MIT\"},\"contracts/aa-4337/core/BaseAccount.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-empty-blocks */\\n\\nimport \\\"../interfaces/IAccount.sol\\\";\\nimport \\\"../interfaces/IEntryPoint.sol\\\";\\nimport \\\"./Helpers.sol\\\";\\n\\n/**\\n * Basic account implementation.\\n * this contract provides the basic logic for implementing the IAccount interface - validateUserOp\\n * specific account implementation should inherit it and provide the account-specific logic\\n */\\nabstract contract BaseAccount is IAccount {\\n using UserOperationLib for UserOperation;\\n\\n //return value in case of signature failure, with no time-range.\\n // equivalent to _packValidationData(true,0,0);\\n uint256 internal constant SIG_VALIDATION_FAILED = 1;\\n\\n /**\\n * Return the account nonce.\\n * This method returns the next sequential nonce.\\n * For a nonce of a specific key, use `entrypoint.getNonce(account, key)`\\n */\\n function getNonce() public view virtual returns (uint256) {\\n return entryPoint().getNonce(address(this), 0);\\n }\\n\\n /**\\n * return the entryPoint used by this account.\\n * subclass should return the current entryPoint used by this account.\\n */\\n function entryPoint() public view virtual returns (IEntryPoint);\\n\\n /**\\n * Validate user's signature and nonce.\\n * subclass doesn't need to override this method. Instead, it should override the specific internal validation methods.\\n */\\n function validateUserOp(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n uint256 missingAccountFunds\\n ) external virtual override returns (uint256 validationData) {\\n _requireFromEntryPoint();\\n validationData = _validateSignature(userOp, userOpHash);\\n _validateNonce(userOp.nonce);\\n _payPrefund(missingAccountFunds);\\n }\\n\\n /**\\n * ensure the request comes from the known entrypoint.\\n */\\n function _requireFromEntryPoint() internal view virtual {\\n require(\\n msg.sender == address(entryPoint()),\\n \\\"account: not from EntryPoint\\\"\\n );\\n }\\n\\n /**\\n * validate the signature is valid for this message.\\n * @param userOp validate the userOp.signature field\\n * @param userOpHash convenient field: the hash of the request, to check the signature against\\n * (also hashes the entrypoint and chain id)\\n * @return validationData signature and time-range of this operation\\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\\n * otherwise, an address of an \\\"authorizer\\\" contract.\\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \\\"indefinite\\\"\\n * <6-byte> validAfter - first timestamp this operation is valid\\n * If the account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\\n */\\n function _validateSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) internal virtual returns (uint256 validationData);\\n\\n /**\\n * Validate the nonce of the UserOperation.\\n * This method may validate the nonce requirement of this account.\\n * e.g.\\n * To limit the nonce to use sequenced UserOps only (no \\\"out of order\\\" UserOps):\\n * `require(nonce < type(uint64).max)`\\n * For a hypothetical account that *requires* the nonce to be out-of-order:\\n * `require(nonce & type(uint64).max == 0)`\\n *\\n * The actual nonce uniqueness is managed by the EntryPoint, and thus no other\\n * action is needed by the account itself.\\n *\\n * @param nonce to validate\\n *\\n * solhint-disable-next-line no-empty-blocks\\n */\\n function _validateNonce(uint256 nonce) internal view virtual {}\\n\\n /**\\n * sends to the entrypoint (msg.sender) the missing funds for this transaction.\\n * subclass MAY override this method for better funds management\\n * (e.g. send to the entryPoint more than the minimum required, so that in future transactions\\n * it will not be required to send again)\\n * @param missingAccountFunds the minimum value this method should send the entrypoint.\\n * this value MAY be zero, in case there is enough deposit, or the userOp has a paymaster.\\n */\\n function _payPrefund(uint256 missingAccountFunds) internal virtual {\\n if (missingAccountFunds != 0) {\\n (bool success, ) = payable(msg.sender).call{\\n value: missingAccountFunds,\\n gas: type(uint256).max\\n }(\\\"\\\");\\n (success);\\n //ignore failure (its EntryPoint's job to verify, not account.)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa0dcc386b0f04711db3e394fb50e55a3b3b1a4d19fac1f10895844e1aa4e3d5c\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/core/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable no-inline-assembly */\\n\\n/**\\n * returned data from validateUserOp.\\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\\n * @param aggregator - address(0) - the account validated the signature by itself.\\n * address(1) - the account failed to validate the signature.\\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\\n * @param validAfter - this UserOp is valid only after this timestamp.\\n * @param validaUntil - this UserOp is valid only up to this timestamp.\\n */\\nstruct ValidationData {\\n address aggregator;\\n uint48 validAfter;\\n uint48 validUntil;\\n}\\n\\n//extract sigFailed, validAfter, validUntil.\\n// also convert zero validUntil to type(uint48).max\\nfunction _parseValidationData(\\n uint validationData\\n) pure returns (ValidationData memory data) {\\n address aggregator = address(uint160(validationData));\\n uint48 validUntil = uint48(validationData >> 160);\\n if (validUntil == 0) {\\n validUntil = type(uint48).max;\\n }\\n uint48 validAfter = uint48(validationData >> (48 + 160));\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n// intersect account and paymaster ranges.\\nfunction _intersectTimeRange(\\n uint256 validationData,\\n uint256 paymasterValidationData\\n) pure returns (ValidationData memory) {\\n ValidationData memory accountValidationData = _parseValidationData(\\n validationData\\n );\\n ValidationData memory pmValidationData = _parseValidationData(\\n paymasterValidationData\\n );\\n address aggregator = accountValidationData.aggregator;\\n if (aggregator == address(0)) {\\n aggregator = pmValidationData.aggregator;\\n }\\n uint48 validAfter = accountValidationData.validAfter;\\n uint48 validUntil = accountValidationData.validUntil;\\n uint48 pmValidAfter = pmValidationData.validAfter;\\n uint48 pmValidUntil = pmValidationData.validUntil;\\n\\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp\\n * @param data - the ValidationData to pack\\n */\\nfunction _packValidationData(\\n ValidationData memory data\\n) pure returns (uint256) {\\n return\\n uint160(data.aggregator) |\\n (uint256(data.validUntil) << 160) |\\n (uint256(data.validAfter) << (160 + 48));\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp, when not using an aggregator\\n * @param sigFailed - true for signature failure, false for success\\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\\n * @param validAfter first timestamp this UserOperation is valid\\n */\\nfunction _packValidationData(\\n bool sigFailed,\\n uint48 validUntil,\\n uint48 validAfter\\n) pure returns (uint256) {\\n return\\n (sigFailed ? 1 : 0) |\\n (uint256(validUntil) << 160) |\\n (uint256(validAfter) << (160 + 48));\\n}\\n\\n/**\\n * keccak function over calldata.\\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\\n */\\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\\n assembly {\\n let mem := mload(0x40)\\n let len := data.length\\n calldatacopy(mem, data.offset, len)\\n ret := keccak256(mem, len)\\n }\\n}\\n\",\"keccak256\":\"0xa79f06cd158ecb8c0da95493a2f348933b8627a63e228b99738bff3aa107942d\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAccount.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\ninterface IAccount {\\n /**\\n * Validate user's signature and nonce\\n * the entryPoint will make the call to the recipient only if this validation call returns successfully.\\n * signature failure should be reported by returning SIG_VALIDATION_FAILED (1).\\n * This allows making a \\\"simulation call\\\" without a valid signature\\n * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure.\\n *\\n * @dev Must validate caller is the entryPoint.\\n * Must validate the signature and nonce\\n * @param userOp the operation that is about to be executed.\\n * @param userOpHash hash of the user's request data. can be used as the basis for signature.\\n * @param missingAccountFunds missing funds on the account's deposit in the entrypoint.\\n * This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call.\\n * The excess is left as a deposit in the entrypoint, for future calls.\\n * can be withdrawn anytime using \\\"entryPoint.withdrawTo()\\\"\\n * In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero.\\n * @return validationData packaged ValidationData structure. use `_packValidationData` and `_unpackValidationData` to encode and decode\\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\\n * otherwise, an address of an \\\"authorizer\\\" contract.\\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \\\"indefinite\\\"\\n * <6-byte> validAfter - first timestamp this operation is valid\\n * If an account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\\n */\\n function validateUserOp(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n uint256 missingAccountFunds\\n ) external returns (uint256 validationData);\\n}\\n\",\"keccak256\":\"0xcbc4b0973cf954c5895b7796335f651fbfcfb55f67dfa789a3d354f8e23c4f2b\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAggregator.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\n/**\\n * Aggregated Signatures validator.\\n */\\ninterface IAggregator {\\n /**\\n * validate aggregated signature.\\n * revert if the aggregated signature does not match the given list of operations.\\n */\\n function validateSignatures(\\n UserOperation[] calldata userOps,\\n bytes calldata signature\\n ) external view;\\n\\n /**\\n * validate signature of a single userOp\\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\\n * @param userOp the userOperation received from the user.\\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\\n * (usually empty, unless account and aggregator support some kind of \\\"multisig\\\"\\n */\\n function validateUserOpSignature(\\n UserOperation calldata userOp\\n ) external view returns (bytes memory sigForUserOp);\\n\\n /**\\n * aggregate multiple signatures into a single value.\\n * This method is called off-chain to calculate the signature to pass with handleOps()\\n * bundler MAY use optimized custom code perform this aggregation\\n * @param userOps array of UserOperations to collect the signatures from.\\n * @return aggregatedSignature the aggregated signature\\n */\\n function aggregateSignatures(\\n UserOperation[] calldata userOps\\n ) external view returns (bytes memory aggregatedSignature);\\n}\\n\",\"keccak256\":\"0xdfdcd80568f037716674619b31be630fcd8316262f05a815b41d1e81782c966a\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IEntryPoint.sol\":{\"content\":\"/**\\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\\n ** Only one instance required on each chain.\\n **/\\n// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-inline-assembly */\\n/* solhint-disable reason-string */\\n\\nimport \\\"./UserOperation.sol\\\";\\nimport \\\"./IStakeManager.sol\\\";\\nimport \\\"./IAggregator.sol\\\";\\nimport \\\"./INonceManager.sol\\\";\\n\\ninterface IEntryPoint is IStakeManager, INonceManager {\\n /***\\n * An event emitted after each successful request\\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\\n * @param sender - the account that generates this request.\\n * @param paymaster - if non-null, the paymaster that pays for this request.\\n * @param nonce - the nonce value from the request.\\n * @param success - true if the sender transaction succeeded, false if reverted.\\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\\n */\\n event UserOperationEvent(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address indexed paymaster,\\n uint256 nonce,\\n bool success,\\n uint256 actualGasCost,\\n uint256 actualGasUsed\\n );\\n\\n /**\\n * account \\\"sender\\\" was deployed.\\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\\n * @param sender the account that is deployed\\n * @param factory the factory used to deploy this account (in the initCode)\\n * @param paymaster the paymaster used by this UserOp\\n */\\n event AccountDeployed(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address factory,\\n address paymaster\\n );\\n\\n /**\\n * An event emitted if the UserOperation \\\"callData\\\" reverted with non-zero length\\n * @param userOpHash the request unique identifier.\\n * @param sender the sender of this request\\n * @param nonce the nonce used in the request\\n * @param revertReason - the return bytes from the (reverted) call to \\\"callData\\\".\\n */\\n event UserOperationRevertReason(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n uint256 nonce,\\n bytes revertReason\\n );\\n\\n /**\\n * an event emitted by handleOps(), before starting the execution loop.\\n * any event emitted before this event, is part of the validation.\\n */\\n event BeforeExecution();\\n\\n /**\\n * signature aggregator used by the following UserOperationEvents within this bundle.\\n */\\n event SignatureAggregatorChanged(address indexed aggregator);\\n\\n /**\\n * a custom revert error of handleOps, to identify the offending op.\\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\\n * @param reason - revert reason\\n * The string starts with a unique code \\\"AAmn\\\", where \\\"m\\\" is \\\"1\\\" for factory, \\\"2\\\" for account and \\\"3\\\" for paymaster issues,\\n * so a failure can be attributed to the correct entity.\\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\\n */\\n error FailedOp(uint256 opIndex, string reason);\\n\\n /**\\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\\n */\\n error SignatureValidationFailed(address aggregator);\\n\\n /**\\n * Successful result from simulateValidation.\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n */\\n error ValidationResult(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo\\n );\\n\\n /**\\n * Successful result from simulateValidation, if the account returns a signature aggregator\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\\n * bundler MUST use it to verify the signature, or reject the UserOperation\\n */\\n error ValidationResultWithAggregation(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo,\\n AggregatorStakeInfo aggregatorInfo\\n );\\n\\n /**\\n * return value of getSenderAddress\\n */\\n error SenderAddressResult(address sender);\\n\\n /**\\n * return value of simulateHandleOp\\n */\\n error ExecutionResult(\\n uint256 preOpGas,\\n uint256 paid,\\n uint48 validAfter,\\n uint48 validUntil,\\n bool targetSuccess,\\n bytes targetResult\\n );\\n\\n //UserOps handled, per aggregator\\n struct UserOpsPerAggregator {\\n UserOperation[] userOps;\\n // aggregator address\\n IAggregator aggregator;\\n // aggregated signature\\n bytes signature;\\n }\\n\\n /**\\n * Execute a batch of UserOperation.\\n * no signature aggregator is used.\\n * if any account requires an aggregator (that is, it returned an aggregator when\\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\\n * @param ops the operations to execute\\n * @param beneficiary the address to receive the fees\\n */\\n function handleOps(\\n UserOperation[] calldata ops,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * Execute a batch of UserOperation with Aggregators\\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\\n * @param beneficiary the address to receive the fees\\n */\\n function handleAggregatedOps(\\n UserOpsPerAggregator[] calldata opsPerAggregator,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * generate a request Id - unique identifier for this request.\\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\\n */\\n function getUserOpHash(\\n UserOperation calldata userOp\\n ) external view returns (bytes32);\\n\\n /**\\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\\n * @param userOp the user operation to validate.\\n */\\n function simulateValidation(UserOperation calldata userOp) external;\\n\\n /**\\n * gas and return values during simulation\\n * @param preOpGas the gas used for validation (including preValidationGas)\\n * @param prefund the required prefund for this operation\\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\\n */\\n struct ReturnInfo {\\n uint256 preOpGas;\\n uint256 prefund;\\n bool sigFailed;\\n uint48 validAfter;\\n uint48 validUntil;\\n bytes paymasterContext;\\n }\\n\\n /**\\n * returned aggregated signature info.\\n * the aggregator returned by the account, and its current stake.\\n */\\n struct AggregatorStakeInfo {\\n address aggregator;\\n StakeInfo stakeInfo;\\n }\\n\\n /**\\n * Get counterfactual sender address.\\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\\n * this method always revert, and returns the address in SenderAddressResult error\\n * @param initCode the constructor code to be passed into the UserOperation.\\n */\\n function getSenderAddress(bytes memory initCode) external;\\n\\n /**\\n * simulate full execution of a UserOperation (including both validation and target execution)\\n * this method will always revert with \\\"ExecutionResult\\\".\\n * it performs full validation of the UserOperation, but ignores signature error.\\n * an optional target address is called after the userop succeeds, and its value is returned\\n * (before the entire call is reverted)\\n * Note that in order to collect the the success/failure of the target call, it must be executed\\n * with trace enabled to track the emitted events.\\n * @param op the UserOperation to simulate\\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\\n * are set to the return from that call.\\n * @param targetCallData callData to pass to target address\\n */\\n function simulateHandleOp(\\n UserOperation calldata op,\\n address target,\\n bytes calldata targetCallData\\n ) external;\\n}\\n\",\"keccak256\":\"0x9ccb1b188eda8bbf5f6c2d01bd83c3d8b2b04fcf745283051d31fe96d1d8e40f\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/INonceManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\ninterface INonceManager {\\n /**\\n * Return the next nonce for this sender.\\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\\n * But UserOp with different keys can come with arbitrary order.\\n *\\n * @param sender the account address\\n * @param key the high 192 bit of the nonce\\n * @return nonce a full nonce to pass for next UserOp with this sender.\\n */\\n function getNonce(\\n address sender,\\n uint192 key\\n ) external view returns (uint256 nonce);\\n\\n /**\\n * Manually increment the nonce of the sender.\\n * This method is exposed just for completeness..\\n * Account does NOT need to call it, neither during validation, nor elsewhere,\\n * as the EntryPoint will update the nonce regardless.\\n * Possible use-case is call it with various keys to \\\"initialize\\\" their nonces to one, so that future\\n * UserOperations will not pay extra for the first transaction with a given key.\\n */\\n function incrementNonce(uint192 key) external;\\n}\\n\",\"keccak256\":\"0xce478ad0fa0d18a3b785ac854623029e7ab463d05873dfaa365abfa1bf100912\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IStakeManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8.12;\\n\\n/**\\n * manage deposits and stakes.\\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\\n * stake is value locked for at least \\\"unstakeDelay\\\" by the staked entity.\\n */\\ninterface IStakeManager {\\n event Deposited(address indexed account, uint256 totalDeposit);\\n\\n event Withdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /// Emitted when stake or unstake delay are modified\\n event StakeLocked(\\n address indexed account,\\n uint256 totalStaked,\\n uint256 unstakeDelaySec\\n );\\n\\n /// Emitted once a stake is scheduled for withdrawal\\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\\n\\n event StakeWithdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /**\\n * @param deposit the entity's deposit\\n * @param staked true if this entity is staked.\\n * @param stake actual amount of ether staked for this entity.\\n * @param unstakeDelaySec minimum delay to withdraw the stake.\\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\\n * and the rest fit into a 2nd cell.\\n * 112 bit allows for 10^15 eth\\n * 48 bit for full timestamp\\n * 32 bit allows 150 years for unstake delay\\n */\\n struct DepositInfo {\\n uint112 deposit;\\n bool staked;\\n uint112 stake;\\n uint32 unstakeDelaySec;\\n uint48 withdrawTime;\\n }\\n\\n //API struct used by getStakeInfo and simulateValidation\\n struct StakeInfo {\\n uint256 stake;\\n uint256 unstakeDelaySec;\\n }\\n\\n /// @return info - full deposit information of given account\\n function getDepositInfo(\\n address account\\n ) external view returns (DepositInfo memory info);\\n\\n /// @return the deposit (for gas payment) of the account\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * add to the deposit of the given account\\n */\\n function depositTo(address account) external payable;\\n\\n /**\\n * add to the account's stake - amount and delay\\n * any pending unstake is first cancelled.\\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\\n */\\n function addStake(uint32 _unstakeDelaySec) external payable;\\n\\n /**\\n * attempt to unlock the stake.\\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\\n */\\n function unlockStake() external;\\n\\n /**\\n * withdraw from the (unlocked) stake.\\n * must first call unlockStake and wait for the unstakeDelay to pass\\n * @param withdrawAddress the address to send withdrawn value.\\n */\\n function withdrawStake(address payable withdrawAddress) external;\\n\\n /**\\n * withdraw from the deposit.\\n * @param withdrawAddress the address to send withdrawn value.\\n * @param withdrawAmount the amount to withdraw.\\n */\\n function withdrawTo(\\n address payable withdrawAddress,\\n uint256 withdrawAmount\\n ) external;\\n}\\n\",\"keccak256\":\"0xadcea606c9b7aafe6645441f2154a60f271330b0eee5292a632aa71c1672d546\",\"license\":\"GPL-3.0-only\"},\"contracts/aa-4337/interfaces/UserOperation.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable no-inline-assembly */\\n\\nimport {calldataKeccak} from \\\"../core/Helpers.sol\\\";\\n\\n/**\\n * User Operation struct\\n * @param sender the sender account of this request.\\n * @param nonce unique value the sender uses to verify it is not a replay.\\n * @param initCode if set, the account contract will be created by this constructor/\\n * @param callData the method call to execute on this account.\\n * @param callGasLimit the gas limit passed to the callData method call.\\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\\n * @param maxFeePerGas same as EIP-1559 gas parameter.\\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\\n */\\nstruct UserOperation {\\n address sender;\\n uint256 nonce;\\n bytes initCode;\\n bytes callData;\\n uint256 callGasLimit;\\n uint256 verificationGasLimit;\\n uint256 preVerificationGas;\\n uint256 maxFeePerGas;\\n uint256 maxPriorityFeePerGas;\\n bytes paymasterAndData;\\n bytes signature;\\n}\\n\\n/**\\n * Utility functions helpful when working with UserOperation structs.\\n */\\nlibrary UserOperationLib {\\n function getSender(\\n UserOperation calldata userOp\\n ) internal pure returns (address) {\\n address data;\\n //read sender from userOp, which is first userOp member (saves 800 gas...)\\n assembly {\\n data := calldataload(userOp)\\n }\\n return address(uint160(data));\\n }\\n\\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\\n // pay above what he signed for.\\n function gasPrice(\\n UserOperation calldata userOp\\n ) internal view returns (uint256) {\\n unchecked {\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n if (maxFeePerGas == maxPriorityFeePerGas) {\\n //legacy mode (for networks that don't support basefee opcode)\\n return maxFeePerGas;\\n }\\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\\n }\\n }\\n\\n function pack(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes memory ret) {\\n address sender = getSender(userOp);\\n uint256 nonce = userOp.nonce;\\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\\n bytes32 hashCallData = calldataKeccak(userOp.callData);\\n uint256 callGasLimit = userOp.callGasLimit;\\n uint256 verificationGasLimit = userOp.verificationGasLimit;\\n uint256 preVerificationGas = userOp.preVerificationGas;\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\\n\\n return\\n abi.encode(\\n sender,\\n nonce,\\n hashInitCode,\\n hashCallData,\\n callGasLimit,\\n verificationGasLimit,\\n preVerificationGas,\\n maxFeePerGas,\\n maxPriorityFeePerGas,\\n hashPaymasterAndData\\n );\\n }\\n\\n function hash(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes32) {\\n return keccak256(pack(userOp));\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n}\\n\",\"keccak256\":\"0x2429f5cc546bdee08c7e63858d0dda8491eaa3ab5194df884dc948c1154d2834\",\"license\":\"GPL-3.0\"},\"contracts/facets/AccountFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {ECDSA} from \\\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\\\";\\nimport {UserOperation} from \\\"../aa-4337/interfaces/UserOperation.sol\\\";\\nimport {IEntryPoint} from \\\"../aa-4337/interfaces/IEntryPoint.sol\\\";\\nimport {BaseAccount} from \\\"../aa-4337/core/BaseAccount.sol\\\";\\nimport {LibAppStorage, BarzStorage} from \\\"../libraries/LibAppStorage.sol\\\";\\nimport {LibDiamond} from \\\"../libraries/LibDiamond.sol\\\";\\nimport {LibLoupe} from \\\"../libraries/LibLoupe.sol\\\";\\nimport {IFacetRegistry} from \\\"../infrastructure/interfaces/IFacetRegistry.sol\\\";\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\nimport {IVerificationFacet} from \\\"./interfaces/IVerificationFacet.sol\\\";\\nimport {IERC1271} from \\\"../interfaces/ERC/IERC1271.sol\\\";\\nimport {IAccountFacet} from \\\"./interfaces/IAccountFacet.sol\\\";\\n\\n/**\\n * @title Account Facet\\n * @dev Account module contract that provides the account features and initialization of signer\\n * compatible with EIP-1271 & EIP-4337\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract AccountFacet is IAccountFacet, BarzStorage, BaseAccount {\\n using ECDSA for bytes32;\\n\\n /**\\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\\n */\\n constructor() {\\n LibAppStorage.enforceAccountInitialize();\\n }\\n\\n /**\\n * @notice Returns the address of EntryPoint contract registered to Barz account\\n */\\n function entryPoint() public view override returns (IEntryPoint) {\\n return s.entryPoint;\\n }\\n\\n /**\\n * @notice Initializes the initial storage of the Barz contract.\\n * @dev This method can only be called during the initialization or signature migration.\\n * If the proxy contract was created without initialization, anyone can call initialize.\\n * Barz calls initialize in constructor in an atomic transaction during deployment\\n * @param _verificationFacet Facet contract handling the verificationi\\n * @param _anEntryPoint Entrypoint contract defined in EIP-4337 handling the flow of UserOp\\n * @param _facetRegistry Registry of Facets that hold all facet information\\n * @param _defaultFallBackHandler Middleware contract for default facets\\n * @param _ownerPublicKey Bytes of owner public key\\n */\\n function initialize(\\n address _verificationFacet,\\n address _anEntryPoint,\\n address _facetRegistry,\\n address _defaultFallBackHandler,\\n bytes calldata _ownerPublicKey\\n ) public override returns (uint256 initSuccess) {\\n LibAppStorage.enforceAccountInitialize();\\n s.entryPoint = IEntryPoint(_anEntryPoint);\\n s.facetRegistry = IFacetRegistry(_facetRegistry);\\n LibDiamond.diamondStorage().defaultFallbackHandler = IDiamondLoupe(\\n _defaultFallBackHandler\\n );\\n\\n _cutDiamondAccountFacet(_verificationFacet);\\n\\n bytes memory initCall = abi.encodeWithSignature(\\n \\\"initializeSigner(bytes)\\\",\\n _ownerPublicKey\\n );\\n // Every Verification Facet should comply with initializeSigner(bytes)\\n // to be compatible with the Barz contract(for initialization)\\n (bool success, bytes memory result) = _verificationFacet.delegatecall(\\n initCall\\n );\\n if (!success || uint256(bytes32(result)) != 1) {\\n revert AccountFacet__InitializationFailure();\\n }\\n\\n initSuccess = 1;\\n emit AccountInitialized(s.entryPoint, _ownerPublicKey);\\n }\\n\\n function _cutDiamondAccountFacet(address _verificationFacet) internal {\\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](1);\\n\\n bytes4 ownerVerificationFuncSelector = IVerificationFacet(\\n _verificationFacet\\n ).validateOwnerSignatureSelector();\\n\\n bytes4[] memory verificationFunctionSelectors = new bytes4[](3);\\n verificationFunctionSelectors[0] = IERC1271.isValidSignature.selector;\\n verificationFunctionSelectors[1] = ownerVerificationFuncSelector;\\n verificationFunctionSelectors[2] = IVerificationFacet.owner.selector;\\n cut[0] = IDiamondCut.FacetCut({\\n facetAddress: _verificationFacet,\\n action: IDiamondCut.FacetCutAction.Add,\\n functionSelectors: verificationFunctionSelectors\\n });\\n\\n LibDiamond.diamondCut(cut, address(0), \\\"\\\");\\n }\\n\\n /**\\n * @notice Calls the destination with inputted calldata and value from EntryPoint\\n * @dev This method executes the calldata coming from the EntryPoint.\\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\\n * @param _dest Address of destination where the call will be forwarded to\\n * @param _value Amount of native coin the owner is willing to send(e.g. ETH, BNB)\\n * @param _func Bytes of calldata to execute in the destination address\\n */\\n function execute(\\n address _dest,\\n uint256 _value,\\n bytes calldata _func\\n ) external override onlyWhenUnlocked {\\n _requireFromEntryPoint();\\n address restrictionsFacet = LibDiamond.restrictionsFacet();\\n if (restrictionsFacet == address(0)) _call(_dest, _value, _func);\\n else _callWithRestrictions(_dest, _value, _func, restrictionsFacet);\\n }\\n\\n /**\\n * @notice Batch calls the destination with inputted calldata and value from EntryPoint\\n * @dev This method batch executes the calldata coming from the EntryPoint.\\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\\n * @param _dest Array of addresses of destination where the call will be forwarded to\\n * @param _value Array of amount of native coin the owner is willing to send(e.g. ETH, BNB)\\n * @param _func Array of bytes of calldata to execute in the destination address\\n */\\n function executeBatch(\\n address[] calldata _dest,\\n uint256[] calldata _value,\\n bytes[] calldata _func\\n ) external override onlyWhenUnlocked {\\n _requireFromEntryPoint();\\n if (_dest.length != _func.length || _dest.length != _value.length)\\n revert AccountFacet__InvalidArrayLength();\\n address restrictionsFacet = LibDiamond.restrictionsFacet();\\n if (restrictionsFacet == address(0)) {\\n for (uint256 i; i < _dest.length; ) {\\n _call(_dest[i], _value[i], _func[i]);\\n unchecked {\\n ++i;\\n }\\n }\\n } else {\\n for (uint256 i; i < _dest.length; ) {\\n _callWithRestrictions(\\n _dest[i],\\n _value[i],\\n _func[i],\\n restrictionsFacet\\n );\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n }\\n\\n /**\\n * @notice Validates the signature field of UserOperation\\n * @dev This method validates if the signature of UserOp is indeed valid by delegating the call to Verification Facet\\n * Barz makes a call to the pre-registered Verification Facet address in App Storage\\n * @param _userOp UserOperation from owner to be validated\\n * @param _userOpHash Hash of UserOperation given from the EntryPoint contract\\n */\\n function _validateSignature(\\n UserOperation calldata _userOp,\\n bytes32 _userOpHash\\n ) internal override returns (uint256 validationData) {\\n // Get Facet with Function Selector\\n address facet = LibLoupe.facetAddress(s.validateOwnerSignatureSelector);\\n if (facet == address(0))\\n revert AccountFacet__NonExistentVerificationFacet();\\n\\n // Make function call to VerificationFacet\\n bytes memory validateCall = abi.encodeWithSelector(\\n s.validateOwnerSignatureSelector,\\n _userOp,\\n _userOpHash\\n );\\n (bool success, bytes memory result) = facet.delegatecall(validateCall);\\n if (!success) revert AccountFacet__CallNotSuccessful();\\n validationData = uint256(bytes32(result));\\n if (validationData == 0) emit VerificationSuccess(_userOpHash);\\n else emit VerificationFailure(_userOpHash);\\n }\\n\\n /**\\n * @notice Calls the target with the inputted value and calldata\\n * @dev This method is the actual function in Barz that makes a call with an arbitrary owner-given data\\n * @param _target Address of the destination contract which the call is getting forwarded to\\n * @param _value Amount of Native coin the owner is wanting to make in this call\\n * @param _data Calldata the owner is forwarding together in the call e.g. Swap/Token Transfer\\n */\\n function _call(\\n address _target,\\n uint256 _value,\\n bytes memory _data\\n ) internal {\\n (bool success, bytes memory result) = _target.call{value: _value}(\\n _data\\n );\\n if (!success) {\\n assembly {\\n revert(add(result, 32), mload(result))\\n }\\n }\\n }\\n\\n /**\\n * @notice Calls the target with the inputted value and calldata together with restrictions check\\n * @dev This method is the actual function in Barz that makes a call with an arbitrary owner-given data\\n * @param _target Address of the destination contract which the call is getting forwarded to\\n * @param _value Amount of Native coin the owner is wanting to make in this call\\n * @param _data Calldata the owner is forwarding together in the call e.g. Swap/Token Transfer\\n * @param _restrictionsFacet Address of Facet to validate restrictions\\n */\\n function _callWithRestrictions(\\n address _target,\\n uint256 _value,\\n bytes memory _data,\\n address _restrictionsFacet\\n ) internal {\\n // NOTE: No restrictions facet, so restriction validation passes\\n if (_checkRestrictions(_restrictionsFacet, _target, _value, _data) != 0)\\n revert AccountFacet__RestrictionsFailure();\\n\\n (bool success, bytes memory result) = _target.call{value: _value}(\\n _data\\n );\\n if (!success) {\\n assembly {\\n revert(add(result, 32), mload(result))\\n }\\n }\\n }\\n\\n /**\\n * @notice Checks restrictions if the restrictions facet exists\\n * @dev This method checks if the restrictions facet exists and makes a verification call to an array of restrictions facet\\n * @param _facet Address that holds the restrictions logic\\n * @param _target Address the call is getting forwarded to\\n * @param _value Amount of native coin the call is sending together with the call\\n * @param _data Calldata to trigger execution in target address\\n */\\n function _checkRestrictions(\\n address _facet,\\n address _target,\\n uint256 _value,\\n bytes memory _data\\n ) internal returns (uint256 result) {\\n bytes memory call = abi.encodeWithSignature(\\n \\\"verifyRestrictions(address,address,uint256,bytes)\\\",\\n address(this),\\n _target,\\n _value,\\n _data\\n );\\n (bool success, bytes memory response) = _facet.delegatecall(call);\\n if (!success) revert AccountFacet__RestrictionsFailure();\\n result = uint256(bytes32(response));\\n }\\n}\\n\",\"keccak256\":\"0xcd92bcdd447010880f78e57e213123269c9e023adfc0a540608daa127d8649ca\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/facets/interfaces/IAccountFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IEntryPoint} from \\\"../../aa-4337/interfaces/IEntryPoint.sol\\\";\\n\\n/**\\n * @title Account Facet Interface\\n * @dev Interface of module contract that provides the account features and init/unitialization of signer\\n * compatible with EIP-1271 & EIP-4337\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IAccountFacet {\\n event AccountInitialized(\\n IEntryPoint indexed entryPoint,\\n bytes indexed ownerPublicKey\\n );\\n // NOTE: Added Below Event\\n event VerificationSuccess(bytes32);\\n event VerificationFailure(bytes32);\\n\\n error AccountFacet__InitializationFailure();\\n error AccountFacet__RestrictionsFailure();\\n error AccountFacet__NonExistentVerificationFacet();\\n error AccountFacet__CallNotSuccessful();\\n error AccountFacet__InvalidArrayLength();\\n\\n function initialize(\\n address verificationFacet,\\n address anEntryPoint,\\n address facetRegistry,\\n address _defaultFallBack,\\n bytes calldata _ownerPublicKey\\n ) external returns (uint256);\\n\\n function execute(address dest, uint256 value, bytes calldata func) external;\\n\\n function executeBatch(\\n address[] calldata dest,\\n uint256[] calldata value,\\n bytes[] calldata func\\n ) external;\\n}\\n\",\"keccak256\":\"0x74a9cb0b8f2f4a5148e366a401a0354426c536c012c025025d07cc25a4cd5382\",\"license\":\"Apache-2.0\"},\"contracts/facets/interfaces/IVerificationFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {UserOperation} from \\\"../../aa-4337/interfaces/UserOperation.sol\\\";\\n\\n/**\\n * @title Verification Facet Interface\\n * @dev Implements logic for user ops signature verification\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\ninterface IVerificationFacet {\\n event SignerInitialized(bytes);\\n event SignerUninitialized();\\n\\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\\n error VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\\n error VerificationFacet__InitializationFailure();\\n error VerificationFacet__InvalidFacetMapping();\\n\\n function initializeSigner(bytes memory) external returns (uint256);\\n\\n function uninitializeSigner() external returns (uint256);\\n\\n function validateOwnerSignatureSelector() external view returns (bytes4);\\n\\n function owner() external view returns (bytes memory);\\n\\n function isValidKeyType(bytes calldata) external view returns (bool);\\n\\n function validateOwnerSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x72bc370a1d1b5a6d6bde67f5026733fd8f6ba434bb90e73b0bd8627fb1579928\",\"license\":\"Apache-2.0\"},\"contracts/infrastructure/interfaces/IFacetRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Registry Interface\\n * @dev Interface for Facet Registry contract to keep track of facets & function selectors addable to user wallets\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IFacetRegistry {\\n struct FacetRegistryConfig {\\n bytes4[] selectors;\\n mapping(bytes4 => FacetInfo) info;\\n }\\n struct FacetInfo {\\n bool exists;\\n uint128 index;\\n }\\n\\n event FacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] facetSelectors\\n );\\n event FacetFunctionSelectorsRemoved(address facet, bytes4[] facetSelectors);\\n\\n error FacetRegistry__FacetSelectorAlreadyRegistered();\\n error FacetRegistry__UnregisteredFacetSelector();\\n\\n function registerFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function removeFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function areFacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external view returns (bool);\\n\\n function isFacetFunctionSelectorRegistered(\\n address facet,\\n bytes4 facetSelector\\n ) external view returns (bool);\\n\\n function getFacetFunctionSelectors(\\n address facet\\n ) external view returns (bytes4[] memory);\\n}\\n\",\"keccak256\":\"0x6e6dd2cab346ef7c31230740ec48d2925e4a9ab24c2f2fb268baaf408dcf02ef\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC1271 {\\n function isValidSignature(\\n bytes32 hash,\\n bytes memory signature\\n ) external view returns (bytes4);\\n}\\n\",\"keccak256\":\"0xcdddb7d5641c9d3f2432dec7fd13fddb9ae1480f25c76c21511e2fa16b8bd422\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibAppStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {SafeCast} from \\\"@openzeppelin/contracts/utils/math/SafeCast.sol\\\";\\nimport {IEntryPoint} from \\\"../aa-4337/interfaces/IEntryPoint.sol\\\";\\nimport {IFacetRegistry} from \\\"../infrastructure/interfaces/IFacetRegistry.sol\\\";\\n\\n/*\\n * @title App Storage\\n * @dev App storage for Barz contract to prevent storage collision\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Lock {\\n uint64 release;\\n bytes4 locker;\\n}\\n\\nstruct InitializersStorage {\\n // NOTE: initialized is a variable to make sure the initialization is only done once.\\n uint8 signerInitialized;\\n uint8 accountInitialized;\\n uint8 restrictionsInitialized;\\n}\\n\\nstruct AppStorage {\\n mapping(uint256 => InitializersStorage) initStorage;\\n uint8 signerMigration;\\n bytes4 validateOwnerSignatureSelector;\\n IEntryPoint entryPoint;\\n IFacetRegistry facetRegistry;\\n mapping(uint256 => Lock) locks;\\n}\\n\\nlibrary LibAppStorage {\\n error LibAppStorage__AccountAlreadyUninitialized();\\n error LibAppStorage__AccountMustBeUninitialized();\\n error LibAppStorage__SignerAlreadyUninitialized();\\n error LibAppStorage__SignerMustBeUninitialized();\\n\\n function appStorage() internal pure returns (AppStorage storage ds) {\\n assembly {\\n ds.slot := 0\\n }\\n }\\n\\n function setSignerUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerAlreadyUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 0;\\n }\\n\\n function getValidateOwnerSignatureSelector()\\n internal\\n view\\n returns (bytes4 selector)\\n {\\n selector = appStorage().validateOwnerSignatureSelector;\\n }\\n\\n function setValidateOwnerSignatureSelector(\\n bytes4 _validateOwnerSignatureSelector\\n ) internal {\\n appStorage()\\n .validateOwnerSignatureSelector = _validateOwnerSignatureSelector;\\n }\\n\\n function enforceSignerInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerMustBeUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 1;\\n }\\n\\n function enforceAccountInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].accountInitialized) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n s.initStorage[0].accountInitialized = 1;\\n }\\n\\n function initiateSignerMigration() internal {\\n appStorage().signerMigration = 1;\\n }\\n\\n function enforceSignerMigration() internal view {\\n if (1 != appStorage().signerMigration) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n }\\n\\n function finalizeSignerMigration() internal {\\n appStorage().signerMigration = 0;\\n }\\n\\n function setLock(uint256 _releaseAfter, bytes4 _locker) internal {\\n appStorage().locks[0] = Lock(SafeCast.toUint64(_releaseAfter), _locker);\\n }\\n\\n function enforceRestrictionsInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__SignerMustBeUninitialized();\\n s.initStorage[0].restrictionsInitialized = 1;\\n }\\n\\n function setRestrictionsUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__AccountAlreadyUninitialized();\\n s.initStorage[0].restrictionsInitialized = 0;\\n }\\n}\\n\\ncontract BarzStorage {\\n AppStorage internal s;\\n modifier onlyWhenUnlocked() {\\n require(\\n uint64(block.timestamp) >= s.locks[0].release,\\n \\\"Account Locked\\\"\\n );\\n _;\\n }\\n modifier onlyWhenLocked() {\\n require(\\n uint64(block.timestamp) < s.locks[0].release,\\n \\\"Account Unlocked\\\"\\n );\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x48524007862a6ce0e07f645950613ce6513ce073c37a109c75019683d42bae27\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\\n bytes4(keccak256(\\\"verifyRestrictions(address,address,uint256,bytes)\\\"));\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // Default Fallback Handler of the barz.\\n IDiamondLoupe defaultFallbackHandler;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function enforceIsSelf() internal view {\\n require(msg.sender == address(this), \\\"LibDiamond: Caller not self\\\");\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n\\n unchecked {\\n facetIndex++;\\n }\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n\\n function restrictionsFacet() internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(\\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2cabdc00de859c3a3170ce3bda5d0e5fd3933d47ce904fd1585f9818b02572f8\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\nimport {LibDiamond} from \\\"./LibDiamond.sol\\\";\\n\\n/**\\n * @title LibLoupe\\n * @dev Internal Library to provide utility feature for reading the state of diamond facets\\n * Originally from Diamond's implementation of Mudgen(author of EIP-2535)\\n */\\nlibrary LibLoupe {\\n /// @notice Gets all facets and their selectors.\\n /// @return facets_ Facet\\n function facets()\\n internal\\n view\\n returns (IDiamondLoupe.Facet[] memory facets_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facets_ = new IDiamondLoupe.Facet[](ds.selectorCount);\\n uint16[] memory numFacetSelectors = new uint16[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facets_[facetIndex].facetAddress == facetAddress_) {\\n facets_[facetIndex].functionSelectors[\\n numFacetSelectors[facetIndex]\\n ] = selector;\\n // probably will never have more than 256 functions from one facet contract\\n require(numFacetSelectors[facetIndex] < 255);\\n numFacetSelectors[facetIndex]++;\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facets_[numFacets].facetAddress = facetAddress_;\\n facets_[numFacets].functionSelectors = new bytes4[](\\n ds.selectorCount\\n );\\n facets_[numFacets].functionSelectors[0] = selector;\\n numFacetSelectors[numFacets] = 1;\\n numFacets++;\\n }\\n }\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n uint256 numSelectors = numFacetSelectors[facetIndex];\\n bytes4[] memory selectors = facets_[facetIndex].functionSelectors;\\n // setting the number of selectors\\n assembly {\\n mstore(selectors, numSelectors)\\n }\\n }\\n // setting the number of facets\\n assembly {\\n mstore(facets_, numFacets)\\n }\\n }\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return _facetFunctionSelectors The selectors associated with a facet address.\\n function facetFunctionSelectors(\\n address _facet\\n ) internal view returns (bytes4[] memory _facetFunctionSelectors) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n uint256 numSelectors;\\n _facetFunctionSelectors = new bytes4[](ds.selectorCount);\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facet = address(bytes20(ds.facets[selector]));\\n if (_facet == facet) {\\n _facetFunctionSelectors[numSelectors] = selector;\\n numSelectors++;\\n }\\n }\\n }\\n // Set the number of selectors in the array\\n assembly {\\n mstore(_facetFunctionSelectors, numSelectors)\\n }\\n }\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n internal\\n view\\n returns (address[] memory facetAddresses_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetAddresses_ = new address[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facetAddress_ == facetAddresses_[facetIndex]) {\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facetAddresses_[numFacets] = facetAddress_;\\n numFacets++;\\n }\\n }\\n // Set the number of facet addresses in the array\\n assembly {\\n mstore(facetAddresses_, numFacets)\\n }\\n }\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(LibDiamond.diamondStorage().facets[_functionSelector])\\n );\\n }\\n}\\n\",\"keccak256\":\"0x0b11439c3cc657095e15ec2241fdcf67204b14001357b612fc5db4ff9e760a5a\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5061001961001e565b61008e565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb554610100900460ff1615610070576040516338fc28cb60e01b815260040160405180910390fd5b600080805260209190915260409020805461ff001916610100179055565b6129b6806200009e6000396000f3fe608060405234801561001057600080fd5b50600436106100725760003560e01c8063b0d691fe11610050578063b0d691fe146100c5578063b61d27f61461010c578063d087d2881461011f57600080fd5b80633a871cdd1461007757806347e1da2a1461009d5780634a936417146100b2575b600080fd5b61008a610085366004611fb5565b610127565b6040519081526020015b60405180910390f35b6100b06100ab366004612055565b61014d565b005b61008a6100c036600461215a565b610450565b60015465010000000000900473ffffffffffffffffffffffffffffffffffffffff1660405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610094565b6100b061011a3660046121ce565b6106d0565b61008a61089d565b600061013161095e565b61013b8484610a16565b905061014682610c5d565b9392505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff9081164290911610156101f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064015b60405180910390fd5b6101fd61095e565b848114158061020c5750848314155b15610243576040517fdde5716100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006102b87fac87185d000000000000000000000000000000000000000000000000000000006000527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020527f6d9f2463c8c0d8cb8be556a773ab21d4321328909a1725f2ef7cae0c320e95da5460601c90565b905073ffffffffffffffffffffffffffffffffffffffff811661038f5760005b86811015610389576103818888838181106102f5576102f5612228565b905060200201602081019061030a9190612257565b87878481811061031c5761031c612228565b9050602002013586868581811061033557610335612228565b90506020028101906103479190612272565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610cc892505050565b6001016102d8565b50610447565b60005b868110156104455761043d8888838181106103af576103af612228565b90506020020160208101906103c49190612257565b8787848181106103d6576103d6612228565b905060200201358686858181106103ef576103ef612228565b90506020028101906104019190612272565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250889250610d45915050565b600101610392565b505b50505050505050565b600061045a610e0d565b6001805473ffffffffffffffffffffffffffffffffffffffff88811665010000000000027fffffffffffffff0000000000000000000000000000000000000000ffffffffff90921691909117909155600280548783167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216179091557f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd492380549287169290911691909117905561051187610eb3565b60008383604051602401610526929190612320565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fcd9b47e40000000000000000000000000000000000000000000000000000000017905251909150600090819073ffffffffffffffffffffffffffffffffffffffff8b16906105c8908590612360565b600060405180830381855af49150503d8060008114610603576040519150601f19603f3d011682016040523d82523d6000602084013e610608565b606091505b5091509150811580610623575061061e8161237c565b600114155b1561065a576040517f1602372100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60019350858560405161066e9291906123c1565b60405190819003812060015490916501000000000090910473ffffffffffffffffffffffffffffffffffffffff16907fd429ff0b972be4ae725700a373d05007287994e4c86cb83315b43ffa85b595fd90600090a35050509695505050505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610773576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064016101ec565b61077b61095e565b60006107f07fac87185d000000000000000000000000000000000000000000000000000000006000527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020527f6d9f2463c8c0d8cb8be556a773ab21d4321328909a1725f2ef7cae0c320e95da5460601c90565b905073ffffffffffffffffffffffffffffffffffffffff81166108535761084e858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610cc892505050565b610896565b610896858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250879250610d45915050565b5050505050565b60015460009065010000000000900473ffffffffffffffffffffffffffffffffffffffff166040517f35567e1a0000000000000000000000000000000000000000000000000000000081523060048201526000602482015273ffffffffffffffffffffffffffffffffffffffff91909116906335567e1a90604401602060405180830381865afa158015610935573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061095991906123d1565b905090565b60015465010000000000900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a14576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f6163636f756e743a206e6f742066726f6d20456e747279506f696e740000000060448201526064016101ec565b565b600154610100900460e01b7fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604081205460601c80610aab576040517f6eb2360200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600154604051600091610100900460e01b90610acd908790879060240161244e565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090506000808373ffffffffffffffffffffffffffffffffffffffff1683604051610b549190612360565b600060405180830381855af49150503d8060008114610b8f576040519150601f19603f3d011682016040523d82523d6000602084013e610b94565b606091505b509150915081610bd0576040517f3cbbb65000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610bd98161237c565b94506000859003610c1c576040518681527f19e781916118c373dadcb7776fae0a2dbb6bbdeedae143ce68031e22801ef8659060200160405180910390a1610c50565b6040518681527fbbfee2df7f28b899771f1015dc85d7840ff9f6162f23f6aa99686e8fbd2ce1319060200160405180910390a15b5050505092915050565b50565b8015610c5a5760405160009033907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90849084818181858888f193505050503d8060008114610896576040519150601f19603f3d011682016040523d82523d6000602084013e610896565b6000808473ffffffffffffffffffffffffffffffffffffffff168484604051610cf19190612360565b60006040518083038185875af1925050503d8060008114610d2e576040519150601f19603f3d011682016040523d82523d6000602084013e610d33565b606091505b50915091508161089657805160208201fd5b610d5181858585611117565b15610d88576040517f01f595e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000808573ffffffffffffffffffffffffffffffffffffffff168585604051610db19190612360565b60006040518083038185875af1925050503d8060008114610dee576040519150601f19603f3d011682016040523d82523d6000602084013e610df3565b606091505b509150915081610e0557805160208201fd5b505050505050565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb554610100900460ff1615610e78576040517f38fc28cb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100179055565b604080516001808252818301909252600091816020015b60408051606080820183526000808352602083015291810191909152815260200190600190039081610eca57905050905060008273ffffffffffffffffffffffffffffffffffffffff16633253960f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f6c9190612592565b604080516003808252608082019092529192506000919060208201606080368337019050509050631626ba7e60e01b81600081518110610fae57610fae612228565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681525050818160018151811061100e5761100e612228565b7fffffffff000000000000000000000000000000000000000000000000000000009092166020928302919091019091015280517f8da5cb5b00000000000000000000000000000000000000000000000000000000908290600290811061107657611076612228565b7fffffffff00000000000000000000000000000000000000000000000000000000909216602092830291909101820152604080516060810190915273ffffffffffffffffffffffffffffffffffffffff861681529081016000815260200182815250836000815181106110eb576110eb612228565b602002602001018190525061111183600060405180602001604052806000815250611264565b50505050565b60008030858585604051602401611131949392919061264d565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fac87185d0000000000000000000000000000000000000000000000000000000017905251909150600090819073ffffffffffffffffffffffffffffffffffffffff8916906111d3908590612360565b600060405180830381855af49150503d806000811461120e576040519150601f19603f3d011682016040523d82523d6000602084013e611213565b606091505b50915091508161124f576040517f01f595e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6112588161237c565b98975050505050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921547f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff8116908190600090600716156112d35750600381901c60009081526001840160205260409020545b60005b87518110156113505761134383838a84815181106112f6576112f6612228565b6020026020010151600001518b858151811061131457611314612228565b6020026020010151602001518c868151811061133257611332612228565b6020026020010151604001516113f0565b90935091506001016112d6565b50828214611389576002840180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff84161790555b60078216156113ab57600382901c600090815260018501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb6738787876040516113de93929190612696565b60405180910390a16104478686611e81565b600080807f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f905060008451116114a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f2063757400000000000000000000000000000000000000000060648201526084016101ec565b60008560028111156114bc576114bc6125d4565b0361168c576114e38660405180606001604052806024815260200161290d60249139611f7a565b60005b845181101561168657600085828151811061150357611503612228565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c156115d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c726561647920657869737473000000000000000000000060648201526084016101ec565b7fffffffff0000000000000000000000000000000000000000000000000000000080831660008181526020879052604090207fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608d901b168e17905560e060058e901b811692831c199c909c1690821c179a81900361166a5760038c901c600090815260018601602052604081209b909b555b8b6116748161282d565b9c5050600190930192506114e6915050565b50611e75565b60018560028111156116a0576116a06125d4565b03611990576116c78660405180606001604052806028815260200161295960289139611f7a565b60005b84518110156116865760008582815181106116e7576116e7612228565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c3081036117bc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4c69624469616d6f6e644375743a2043616e2774207265706c61636520696d6d60448201527f757461626c652066756e6374696f6e000000000000000000000000000000000060648201526084016101ec565b8973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611877576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e000000000000000060648201526084016101ec565b73ffffffffffffffffffffffffffffffffffffffff811661191a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e207468617420646f65736e2774206578697374000000000000000060648201526084016101ec565b507fffffffff0000000000000000000000000000000000000000000000000000000090911660009081526020849052604090206bffffffffffffffffffffffff919091167fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608a901b161790556001016116ca565b60028560028111156119a4576119a46125d4565b03611ded5773ffffffffffffffffffffffffffffffffffffffff861615611a4d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d75737420626520616464726573732830290000000000000000000060648201526084016101ec565b600388901c6007891660005b8651811015611dcd5760008a9003611a955782611a7581612865565b60008181526001870160205260409020549b50935060079250611aa39050565b81611a9f81612865565b9250505b6000806000808a8581518110611abb57611abb612228565b6020908102919091018101517fffffffff0000000000000000000000000000000000000000000000000000000081166000908152918a9052604090912054909150606081901c611b8d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e277420657869737400000000000000000060648201526084016101ec565b30606082901c03611c20576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e00000000000000000000000000000000000060648201526084016101ec565b600587901b8f901b94507fffffffff0000000000000000000000000000000000000000000000000000000080861690831614611cbe577fffffffff000000000000000000000000000000000000000000000000000000008516600090815260208a90526040902080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff83161790555b7fffffffff0000000000000000000000000000000000000000000000000000000091909116600090815260208990526040812055600381901c611fff16925060051b60e0169050858214611d53576000828152600188016020526040902080547fffffffff0000000000000000000000000000000000000000000000000000000080841c19909116908516831c179055611da4565b80837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c817fffffffff0000000000000000000000000000000000000000000000000000000060001b901c198e16179c505b84600003611dc257600086815260018801602052604081208190559c505b505050600101611a59565b5080611dda83600861289a565b611de491906128b7565b99505050611e75565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560448201527f74416374696f6e0000000000000000000000000000000000000000000000000060648201526084016101ec565b50959694955050505050565b73ffffffffffffffffffffffffffffffffffffffff8216611ea0575050565b611ec28260405180606001604052806028815260200161293160289139611f7a565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051611eea9190612360565b600060405180830381855af49150503d8060008114611f25576040519150601f19603f3d011682016040523d82523d6000602084013e611f2a565b606091505b50915091508161111157805115611f445780518082602001fd5b83836040517f192105d70000000000000000000000000000000000000000000000000000000081526004016101ec9291906128ca565b813b8181611111576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101ec91906128f9565b600080600060608486031215611fca57600080fd5b833567ffffffffffffffff811115611fe157600080fd5b84016101608187031215611ff457600080fd5b95602085013595506040909401359392505050565b60008083601f84011261201b57600080fd5b50813567ffffffffffffffff81111561203357600080fd5b6020830191508360208260051b850101111561204e57600080fd5b9250929050565b6000806000806000806060878903121561206e57600080fd5b863567ffffffffffffffff8082111561208657600080fd5b6120928a838b01612009565b909850965060208901359150808211156120ab57600080fd5b6120b78a838b01612009565b909650945060408901359150808211156120d057600080fd5b506120dd89828a01612009565b979a9699509497509295939492505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461211357600080fd5b919050565b60008083601f84011261212a57600080fd5b50813567ffffffffffffffff81111561214257600080fd5b60208301915083602082850101111561204e57600080fd5b60008060008060008060a0878903121561217357600080fd5b61217c876120ef565b955061218a602088016120ef565b9450612198604088016120ef565b93506121a6606088016120ef565b9250608087013567ffffffffffffffff8111156121c257600080fd5b6120dd89828a01612118565b600080600080606085870312156121e457600080fd5b6121ed856120ef565b935060208501359250604085013567ffffffffffffffff81111561221057600080fd5b61221c87828801612118565b95989497509550505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561226957600080fd5b610146826120ef565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126122a757600080fd5b83018035915067ffffffffffffffff8211156122c257600080fd5b60200191503681900382131561204e57600080fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b6020815260006123346020830184866122d7565b949350505050565b60005b8381101561235757818101518382015260200161233f565b50506000910152565b6000825161237281846020870161233c565b9190910192915050565b805160208083015191908110156123bb577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8160200360031b1b821691505b50919050565b8183823760009101908152919050565b6000602082840312156123e357600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261241f57600080fd5b830160208101925035905067ffffffffffffffff81111561243f57600080fd5b80360382131561204e57600080fd5b6040815261247c60408201612462856120ef565b73ffffffffffffffffffffffffffffffffffffffff169052565b60208301356060820152600061249560408501856123ea565b6101608060808601526124ad6101a0860183856122d7565b92506124bc60608801886123ea565b92507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0808786030160a08801526124f48585846122d7565b9450608089013560c088015260a089013560e0880152610100935060c089013584880152610120915060e089013582880152610140848a01358189015261253d838b018b6123ea565b955092508188870301848901526125558686856122d7565b9550612563818b018b6123ea565b9550935050808786030161018088015250506125808383836122d7565b93505050508260208301529392505050565b6000602082840312156125a457600080fd5b81517fffffffff000000000000000000000000000000000000000000000000000000008116811461014657600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6000815180845261261b81602086016020860161233c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600073ffffffffffffffffffffffffffffffffffffffff80871683528086166020840152508360408301526080606083015261268c6080830184612603565b9695505050505050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b848110156127c1577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808a8503018652815188850173ffffffffffffffffffffffffffffffffffffffff82511686528482015160038110612748577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b808310156127ac5783517fffffffff0000000000000000000000000000000000000000000000000000000016825292860192600192909201919086019061276a565b509785019795505050908201906001016126bf565b505073ffffffffffffffffffffffffffffffffffffffff8a169088015286810360408801526127f08189612603565b9a9950505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361285e5761285e6127fe565b5060010190565b600081612874576128746127fe565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b80820281158282048414176128b1576128b16127fe565b92915050565b808201808211156128b1576128b16127fe565b73ffffffffffffffffffffffffffffffffffffffff831681526040602082015260006123346040830184612603565b602081526000610146602083018461260356fe4c69624469616d6f6e644375743a2041646420666163657420686173206e6f20636f64654c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a205265706c61636520666163657420686173206e6f20636f6465a2646970667358221220a952f19990a20474450919a2df9ddff4430a71350892e0954f2bb073575ad64864736f6c63430008150033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100725760003560e01c8063b0d691fe11610050578063b0d691fe146100c5578063b61d27f61461010c578063d087d2881461011f57600080fd5b80633a871cdd1461007757806347e1da2a1461009d5780634a936417146100b2575b600080fd5b61008a610085366004611fb5565b610127565b6040519081526020015b60405180910390f35b6100b06100ab366004612055565b61014d565b005b61008a6100c036600461215a565b610450565b60015465010000000000900473ffffffffffffffffffffffffffffffffffffffff1660405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610094565b6100b061011a3660046121ce565b6106d0565b61008a61089d565b600061013161095e565b61013b8484610a16565b905061014682610c5d565b9392505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff9081164290911610156101f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064015b60405180910390fd5b6101fd61095e565b848114158061020c5750848314155b15610243576040517fdde5716100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006102b87fac87185d000000000000000000000000000000000000000000000000000000006000527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020527f6d9f2463c8c0d8cb8be556a773ab21d4321328909a1725f2ef7cae0c320e95da5460601c90565b905073ffffffffffffffffffffffffffffffffffffffff811661038f5760005b86811015610389576103818888838181106102f5576102f5612228565b905060200201602081019061030a9190612257565b87878481811061031c5761031c612228565b9050602002013586868581811061033557610335612228565b90506020028101906103479190612272565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610cc892505050565b6001016102d8565b50610447565b60005b868110156104455761043d8888838181106103af576103af612228565b90506020020160208101906103c49190612257565b8787848181106103d6576103d6612228565b905060200201358686858181106103ef576103ef612228565b90506020028101906104019190612272565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250889250610d45915050565b600101610392565b505b50505050505050565b600061045a610e0d565b6001805473ffffffffffffffffffffffffffffffffffffffff88811665010000000000027fffffffffffffff0000000000000000000000000000000000000000ffffffffff90921691909117909155600280548783167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216179091557f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd492380549287169290911691909117905561051187610eb3565b60008383604051602401610526929190612320565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fcd9b47e40000000000000000000000000000000000000000000000000000000017905251909150600090819073ffffffffffffffffffffffffffffffffffffffff8b16906105c8908590612360565b600060405180830381855af49150503d8060008114610603576040519150601f19603f3d011682016040523d82523d6000602084013e610608565b606091505b5091509150811580610623575061061e8161237c565b600114155b1561065a576040517f1602372100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60019350858560405161066e9291906123c1565b60405190819003812060015490916501000000000090910473ffffffffffffffffffffffffffffffffffffffff16907fd429ff0b972be4ae725700a373d05007287994e4c86cb83315b43ffa85b595fd90600090a35050509695505050505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610773576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064016101ec565b61077b61095e565b60006107f07fac87185d000000000000000000000000000000000000000000000000000000006000527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020527f6d9f2463c8c0d8cb8be556a773ab21d4321328909a1725f2ef7cae0c320e95da5460601c90565b905073ffffffffffffffffffffffffffffffffffffffff81166108535761084e858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610cc892505050565b610896565b610896858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250879250610d45915050565b5050505050565b60015460009065010000000000900473ffffffffffffffffffffffffffffffffffffffff166040517f35567e1a0000000000000000000000000000000000000000000000000000000081523060048201526000602482015273ffffffffffffffffffffffffffffffffffffffff91909116906335567e1a90604401602060405180830381865afa158015610935573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061095991906123d1565b905090565b60015465010000000000900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a14576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f6163636f756e743a206e6f742066726f6d20456e747279506f696e740000000060448201526064016101ec565b565b600154610100900460e01b7fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604081205460601c80610aab576040517f6eb2360200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600154604051600091610100900460e01b90610acd908790879060240161244e565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090506000808373ffffffffffffffffffffffffffffffffffffffff1683604051610b549190612360565b600060405180830381855af49150503d8060008114610b8f576040519150601f19603f3d011682016040523d82523d6000602084013e610b94565b606091505b509150915081610bd0576040517f3cbbb65000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610bd98161237c565b94506000859003610c1c576040518681527f19e781916118c373dadcb7776fae0a2dbb6bbdeedae143ce68031e22801ef8659060200160405180910390a1610c50565b6040518681527fbbfee2df7f28b899771f1015dc85d7840ff9f6162f23f6aa99686e8fbd2ce1319060200160405180910390a15b5050505092915050565b50565b8015610c5a5760405160009033907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90849084818181858888f193505050503d8060008114610896576040519150601f19603f3d011682016040523d82523d6000602084013e610896565b6000808473ffffffffffffffffffffffffffffffffffffffff168484604051610cf19190612360565b60006040518083038185875af1925050503d8060008114610d2e576040519150601f19603f3d011682016040523d82523d6000602084013e610d33565b606091505b50915091508161089657805160208201fd5b610d5181858585611117565b15610d88576040517f01f595e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000808573ffffffffffffffffffffffffffffffffffffffff168585604051610db19190612360565b60006040518083038185875af1925050503d8060008114610dee576040519150601f19603f3d011682016040523d82523d6000602084013e610df3565b606091505b509150915081610e0557805160208201fd5b505050505050565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb554610100900460ff1615610e78576040517f38fc28cb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100179055565b604080516001808252818301909252600091816020015b60408051606080820183526000808352602083015291810191909152815260200190600190039081610eca57905050905060008273ffffffffffffffffffffffffffffffffffffffff16633253960f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f6c9190612592565b604080516003808252608082019092529192506000919060208201606080368337019050509050631626ba7e60e01b81600081518110610fae57610fae612228565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681525050818160018151811061100e5761100e612228565b7fffffffff000000000000000000000000000000000000000000000000000000009092166020928302919091019091015280517f8da5cb5b00000000000000000000000000000000000000000000000000000000908290600290811061107657611076612228565b7fffffffff00000000000000000000000000000000000000000000000000000000909216602092830291909101820152604080516060810190915273ffffffffffffffffffffffffffffffffffffffff861681529081016000815260200182815250836000815181106110eb576110eb612228565b602002602001018190525061111183600060405180602001604052806000815250611264565b50505050565b60008030858585604051602401611131949392919061264d565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fac87185d0000000000000000000000000000000000000000000000000000000017905251909150600090819073ffffffffffffffffffffffffffffffffffffffff8916906111d3908590612360565b600060405180830381855af49150503d806000811461120e576040519150601f19603f3d011682016040523d82523d6000602084013e611213565b606091505b50915091508161124f576040517f01f595e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6112588161237c565b98975050505050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921547f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff8116908190600090600716156112d35750600381901c60009081526001840160205260409020545b60005b87518110156113505761134383838a84815181106112f6576112f6612228565b6020026020010151600001518b858151811061131457611314612228565b6020026020010151602001518c868151811061133257611332612228565b6020026020010151604001516113f0565b90935091506001016112d6565b50828214611389576002840180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff84161790555b60078216156113ab57600382901c600090815260018501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb6738787876040516113de93929190612696565b60405180910390a16104478686611e81565b600080807f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f905060008451116114a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f2063757400000000000000000000000000000000000000000060648201526084016101ec565b60008560028111156114bc576114bc6125d4565b0361168c576114e38660405180606001604052806024815260200161290d60249139611f7a565b60005b845181101561168657600085828151811061150357611503612228565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c156115d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c726561647920657869737473000000000000000000000060648201526084016101ec565b7fffffffff0000000000000000000000000000000000000000000000000000000080831660008181526020879052604090207fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608d901b168e17905560e060058e901b811692831c199c909c1690821c179a81900361166a5760038c901c600090815260018601602052604081209b909b555b8b6116748161282d565b9c5050600190930192506114e6915050565b50611e75565b60018560028111156116a0576116a06125d4565b03611990576116c78660405180606001604052806028815260200161295960289139611f7a565b60005b84518110156116865760008582815181106116e7576116e7612228565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c3081036117bc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4c69624469616d6f6e644375743a2043616e2774207265706c61636520696d6d60448201527f757461626c652066756e6374696f6e000000000000000000000000000000000060648201526084016101ec565b8973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611877576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e000000000000000060648201526084016101ec565b73ffffffffffffffffffffffffffffffffffffffff811661191a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e207468617420646f65736e2774206578697374000000000000000060648201526084016101ec565b507fffffffff0000000000000000000000000000000000000000000000000000000090911660009081526020849052604090206bffffffffffffffffffffffff919091167fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608a901b161790556001016116ca565b60028560028111156119a4576119a46125d4565b03611ded5773ffffffffffffffffffffffffffffffffffffffff861615611a4d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d75737420626520616464726573732830290000000000000000000060648201526084016101ec565b600388901c6007891660005b8651811015611dcd5760008a9003611a955782611a7581612865565b60008181526001870160205260409020549b50935060079250611aa39050565b81611a9f81612865565b9250505b6000806000808a8581518110611abb57611abb612228565b6020908102919091018101517fffffffff0000000000000000000000000000000000000000000000000000000081166000908152918a9052604090912054909150606081901c611b8d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e277420657869737400000000000000000060648201526084016101ec565b30606082901c03611c20576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e00000000000000000000000000000000000060648201526084016101ec565b600587901b8f901b94507fffffffff0000000000000000000000000000000000000000000000000000000080861690831614611cbe577fffffffff000000000000000000000000000000000000000000000000000000008516600090815260208a90526040902080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff83161790555b7fffffffff0000000000000000000000000000000000000000000000000000000091909116600090815260208990526040812055600381901c611fff16925060051b60e0169050858214611d53576000828152600188016020526040902080547fffffffff0000000000000000000000000000000000000000000000000000000080841c19909116908516831c179055611da4565b80837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c817fffffffff0000000000000000000000000000000000000000000000000000000060001b901c198e16179c505b84600003611dc257600086815260018801602052604081208190559c505b505050600101611a59565b5080611dda83600861289a565b611de491906128b7565b99505050611e75565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560448201527f74416374696f6e0000000000000000000000000000000000000000000000000060648201526084016101ec565b50959694955050505050565b73ffffffffffffffffffffffffffffffffffffffff8216611ea0575050565b611ec28260405180606001604052806028815260200161293160289139611f7a565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051611eea9190612360565b600060405180830381855af49150503d8060008114611f25576040519150601f19603f3d011682016040523d82523d6000602084013e611f2a565b606091505b50915091508161111157805115611f445780518082602001fd5b83836040517f192105d70000000000000000000000000000000000000000000000000000000081526004016101ec9291906128ca565b813b8181611111576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101ec91906128f9565b600080600060608486031215611fca57600080fd5b833567ffffffffffffffff811115611fe157600080fd5b84016101608187031215611ff457600080fd5b95602085013595506040909401359392505050565b60008083601f84011261201b57600080fd5b50813567ffffffffffffffff81111561203357600080fd5b6020830191508360208260051b850101111561204e57600080fd5b9250929050565b6000806000806000806060878903121561206e57600080fd5b863567ffffffffffffffff8082111561208657600080fd5b6120928a838b01612009565b909850965060208901359150808211156120ab57600080fd5b6120b78a838b01612009565b909650945060408901359150808211156120d057600080fd5b506120dd89828a01612009565b979a9699509497509295939492505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461211357600080fd5b919050565b60008083601f84011261212a57600080fd5b50813567ffffffffffffffff81111561214257600080fd5b60208301915083602082850101111561204e57600080fd5b60008060008060008060a0878903121561217357600080fd5b61217c876120ef565b955061218a602088016120ef565b9450612198604088016120ef565b93506121a6606088016120ef565b9250608087013567ffffffffffffffff8111156121c257600080fd5b6120dd89828a01612118565b600080600080606085870312156121e457600080fd5b6121ed856120ef565b935060208501359250604085013567ffffffffffffffff81111561221057600080fd5b61221c87828801612118565b95989497509550505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561226957600080fd5b610146826120ef565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126122a757600080fd5b83018035915067ffffffffffffffff8211156122c257600080fd5b60200191503681900382131561204e57600080fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b6020815260006123346020830184866122d7565b949350505050565b60005b8381101561235757818101518382015260200161233f565b50506000910152565b6000825161237281846020870161233c565b9190910192915050565b805160208083015191908110156123bb577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8160200360031b1b821691505b50919050565b8183823760009101908152919050565b6000602082840312156123e357600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261241f57600080fd5b830160208101925035905067ffffffffffffffff81111561243f57600080fd5b80360382131561204e57600080fd5b6040815261247c60408201612462856120ef565b73ffffffffffffffffffffffffffffffffffffffff169052565b60208301356060820152600061249560408501856123ea565b6101608060808601526124ad6101a0860183856122d7565b92506124bc60608801886123ea565b92507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0808786030160a08801526124f48585846122d7565b9450608089013560c088015260a089013560e0880152610100935060c089013584880152610120915060e089013582880152610140848a01358189015261253d838b018b6123ea565b955092508188870301848901526125558686856122d7565b9550612563818b018b6123ea565b9550935050808786030161018088015250506125808383836122d7565b93505050508260208301529392505050565b6000602082840312156125a457600080fd5b81517fffffffff000000000000000000000000000000000000000000000000000000008116811461014657600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6000815180845261261b81602086016020860161233c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600073ffffffffffffffffffffffffffffffffffffffff80871683528086166020840152508360408301526080606083015261268c6080830184612603565b9695505050505050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b848110156127c1577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808a8503018652815188850173ffffffffffffffffffffffffffffffffffffffff82511686528482015160038110612748577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b808310156127ac5783517fffffffff0000000000000000000000000000000000000000000000000000000016825292860192600192909201919086019061276a565b509785019795505050908201906001016126bf565b505073ffffffffffffffffffffffffffffffffffffffff8a169088015286810360408801526127f08189612603565b9a9950505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361285e5761285e6127fe565b5060010190565b600081612874576128746127fe565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b80820281158282048414176128b1576128b16127fe565b92915050565b808201808211156128b1576128b16127fe565b73ffffffffffffffffffffffffffffffffffffffff831681526040602082015260006123346040830184612603565b602081526000610146602083018461260356fe4c69624469616d6f6e644375743a2041646420666163657420686173206e6f20636f64654c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a205265706c61636520666163657420686173206e6f20636f6465a2646970667358221220a952f19990a20474450919a2df9ddff4430a71350892e0954f2bb073575ad64864736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "Account module contract that provides the account features and initialization of signer compatible with EIP-1271 & EIP-4337", + "kind": "dev", + "methods": { + "execute(address,uint256,bytes)": { + "details": "This method executes the calldata coming from the EntryPoint. Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)", + "params": { + "_dest": "Address of destination where the call will be forwarded to", + "_func": "Bytes of calldata to execute in the destination address", + "_value": "Amount of native coin the owner is willing to send(e.g. ETH, BNB)" + } + }, + "executeBatch(address[],uint256[],bytes[])": { + "details": "This method batch executes the calldata coming from the EntryPoint. Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)", + "params": { + "_dest": "Array of addresses of destination where the call will be forwarded to", + "_func": "Array of bytes of calldata to execute in the destination address", + "_value": "Array of amount of native coin the owner is willing to send(e.g. ETH, BNB)" + } + }, + "initialize(address,address,address,address,bytes)": { + "details": "This method can only be called during the initialization or signature migration. If the proxy contract was created without initialization, anyone can call initialize. Barz calls initialize in constructor in an atomic transaction during deployment", + "params": { + "_anEntryPoint": "Entrypoint contract defined in EIP-4337 handling the flow of UserOp", + "_defaultFallBackHandler": "Middleware contract for default facets", + "_facetRegistry": "Registry of Facets that hold all facet information", + "_ownerPublicKey": "Bytes of owner public key", + "_verificationFacet": "Facet contract handling the verificationi" + } + } + }, + "title": "Account Facet", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "constructor": { + "notice": "This constructor ensures that this contract can only be used as singleton for Proxy contracts" + }, + "entryPoint()": { + "notice": "Returns the address of EntryPoint contract registered to Barz account" + }, + "execute(address,uint256,bytes)": { + "notice": "Calls the destination with inputted calldata and value from EntryPoint" + }, + "executeBatch(address[],uint256[],bytes[])": { + "notice": "Batch calls the destination with inputted calldata and value from EntryPoint" + }, + "getNonce()": { + "notice": "Return the account nonce. This method returns the next sequential nonce. For a nonce of a specific key, use `entrypoint.getNonce(account, key)`" + }, + "initialize(address,address,address,address,bytes)": { + "notice": "Initializes the initial storage of the Barz contract." + }, + "validateUserOp((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256)": { + "notice": "Validate user's signature and nonce. subclass doesn't need to override this method. Instead, it should override the specific internal validation methods." + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 27823, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "s", + "offset": 0, + "slot": "0", + "type": "t_struct(AppStorage)27570_storage" + } + ], + "types": { + "t_bytes4": { + "encoding": "inplace", + "label": "bytes4", + "numberOfBytes": "4" + }, + "t_contract(IEntryPoint)12286": { + "encoding": "inplace", + "label": "contract IEntryPoint", + "numberOfBytes": "20" + }, + "t_contract(IFacetRegistry)26105": { + "encoding": "inplace", + "label": "contract IFacetRegistry", + "numberOfBytes": "20" + }, + "t_mapping(t_uint256,t_struct(InitializersStorage)27549_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => struct InitializersStorage)", + "numberOfBytes": "32", + "value": "t_struct(InitializersStorage)27549_storage" + }, + "t_mapping(t_uint256,t_struct(Lock)27542_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => struct Lock)", + "numberOfBytes": "32", + "value": "t_struct(Lock)27542_storage" + }, + "t_struct(AppStorage)27570_storage": { + "encoding": "inplace", + "label": "struct AppStorage", + "members": [ + { + "astId": 27554, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "initStorage", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_uint256,t_struct(InitializersStorage)27549_storage)" + }, + { + "astId": 27556, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "signerMigration", + "offset": 0, + "slot": "1", + "type": "t_uint8" + }, + { + "astId": 27558, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "validateOwnerSignatureSelector", + "offset": 1, + "slot": "1", + "type": "t_bytes4" + }, + { + "astId": 27561, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "entryPoint", + "offset": 5, + "slot": "1", + "type": "t_contract(IEntryPoint)12286" + }, + { + "astId": 27564, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "facetRegistry", + "offset": 0, + "slot": "2", + "type": "t_contract(IFacetRegistry)26105" + }, + { + "astId": 27569, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "locks", + "offset": 0, + "slot": "3", + "type": "t_mapping(t_uint256,t_struct(Lock)27542_storage)" + } + ], + "numberOfBytes": "128" + }, + "t_struct(InitializersStorage)27549_storage": { + "encoding": "inplace", + "label": "struct InitializersStorage", + "members": [ + { + "astId": 27544, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "signerInitialized", + "offset": 0, + "slot": "0", + "type": "t_uint8" + }, + { + "astId": 27546, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "accountInitialized", + "offset": 1, + "slot": "0", + "type": "t_uint8" + }, + { + "astId": 27548, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "restrictionsInitialized", + "offset": 2, + "slot": "0", + "type": "t_uint8" + } + ], + "numberOfBytes": "32" + }, + "t_struct(Lock)27542_storage": { + "encoding": "inplace", + "label": "struct Lock", + "members": [ + { + "astId": 27539, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "release", + "offset": 0, + "slot": "0", + "type": "t_uint64" + }, + { + "astId": 27541, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "locker", + "offset": 8, + "slot": "0", + "type": "t_bytes4" + } + ], + "numberOfBytes": "32" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint64": { + "encoding": "inplace", + "label": "uint64", + "numberOfBytes": "8" + }, + "t_uint8": { + "encoding": "inplace", + "label": "uint8", + "numberOfBytes": "1" + } + } + } +} \ No newline at end of file diff --git a/deployments/arbitrum/BarzFactory.json b/deployments/arbitrum/BarzFactory.json new file mode 100644 index 0000000..72aa80c --- /dev/null +++ b/deployments/arbitrum/BarzFactory.json @@ -0,0 +1,318 @@ +{ + "address": "0x729c310186a57833f622630a16d13f710b83272a", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_accountFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_entryPoint", + "type": "address" + }, + { + "internalType": "address", + "name": "_facetRegistry", + "type": "address" + }, + { + "internalType": "address", + "name": "_defaultFallback", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "BarzDeployed", + "type": "event" + }, + { + "inputs": [], + "name": "accountFacet", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_verificationFacet", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_owner", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "_salt", + "type": "uint256" + } + ], + "name": "createAccount", + "outputs": [ + { + "internalType": "contract Barz", + "name": "barz", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "defaultFallback", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "entryPoint", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetRegistry", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_verificationFacet", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_owner", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "_salt", + "type": "uint256" + } + ], + "name": "getAddress", + "outputs": [ + { + "internalType": "address", + "name": "barzAddress", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_accountFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_verificationFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_entryPoint", + "type": "address" + }, + { + "internalType": "address", + "name": "_facetRegistry", + "type": "address" + }, + { + "internalType": "address", + "name": "_defaultFallback", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_ownerPublicKey", + "type": "bytes" + } + ], + "name": "getBytecode", + "outputs": [ + { + "internalType": "bytes", + "name": "barzBytecode", + "type": "bytes" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "getCreationCode", + "outputs": [ + { + "internalType": "bytes", + "name": "creationCode", + "type": "bytes" + } + ], + "stateMutability": "pure", + "type": "function" + } + ], + "transactionHash": "0x8df632973483f038de544ede95d2370d5f2f8aa8baa10918c2021c37afd7928a", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 1, + "gasUsed": "7660991", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0xa4c3a85d55cbbc97243fc3d612cd90eea8fe9bdcdf7c3b2b6f06fc19ef26cb2b", + "transactionHash": "0x8df632973483f038de544ede95d2370d5f2f8aa8baa10918c2021c37afd7928a", + "logs": [], + "blockNumber": 152284179, + "cumulativeGasUsed": "7660991", + "status": 1, + "byzantium": true + }, + "args": [ + "0xFde53272dcd7938d16E031A6989753c321728332", + "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789", + "0xAfCb70e6e9514E2A15B23A01d2a9b9f7A34f2c33", + "0x2e7f1dAe1F3799d20f5c31bEFdc7A620f664728D" + ], + "numDeployments": 3, + "solcInputHash": "4356503edd8ae34e73cb6dd1c8e2fc8a", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_accountFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_entryPoint\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_facetRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_defaultFallback\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"BarzDeployed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"accountFacet\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_verificationFacet\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_owner\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_salt\",\"type\":\"uint256\"}],\"name\":\"createAccount\",\"outputs\":[{\"internalType\":\"contract Barz\",\"name\":\"barz\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"defaultFallback\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"entryPoint\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetRegistry\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_verificationFacet\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_owner\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_salt\",\"type\":\"uint256\"}],\"name\":\"getAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"barzAddress\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_accountFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_verificationFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_entryPoint\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_facetRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_defaultFallback\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_ownerPublicKey\",\"type\":\"bytes\"}],\"name\":\"getBytecode\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"barzBytecode\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCreationCode\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"creationCode\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"Contract to easily deploy Barz to a pre-computed address with a single call\",\"kind\":\"dev\",\"methods\":{\"constructor\":{\"params\":{\"_accountFacet\":\"Account Facet to be used to create Barz\",\"_defaultFallback\":\"Default Fallback Handler to be used to create Barz\",\"_entryPoint\":\"Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\",\"_facetRegistry\":\"Facet Registry to be used to create Barz\"}},\"createAccount(address,bytes,uint256)\":{\"params\":{\"_owner\":\"Public Key of the owner to initialize barz account\",\"_salt\":\"Salt used for deploying barz with create2\",\"_verificationFacet\":\"Address of verification facet used for creating the barz account\"},\"returns\":{\"barz\":\"Instance of Barz contract deployed with the given parameters\"}},\"getAddress(address,bytes,uint256)\":{\"params\":{\"_owner\":\"Public Key of the owner to initialize barz account\",\"_salt\":\"Salt used for deploying barz with create2\",\"_verificationFacet\":\"Address of verification facet used for creating the barz account\"},\"returns\":{\"barzAddress\":\"Precalculated Barz address\"}},\"getBytecode(address,address,address,address,address,bytes)\":{\"params\":{\"_accountFacet\":\"Account Facet to be used to create Barz\",\"_defaultFallback\":\"Default Fallback Handler to be used to create Barz\",\"_entryPoint\":\"Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\",\"_facetRegistry\":\"Facet Registry to be used to create Barz\",\"_ownerPublicKey\":\"Public Key of owner to be used to initialize Barz ownership\",\"_verificationFacet\":\"Verification Facet to be used to create Barz\"},\"returns\":{\"barzBytecode\":\"Bytecode of Barz\"}},\"getCreationCode()\":{\"returns\":{\"creationCode\":\"Creation code of Barz\"}}},\"title\":\"Barz Factory\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"Sets the initialization data for Barz contract initialization\"},\"createAccount(address,bytes,uint256)\":{\"notice\":\"Creates the Barz with a single call. It creates the Barz contract with the givent verification facet\"},\"getAddress(address,bytes,uint256)\":{\"notice\":\"Calculates the address of Barz with the given parameters\"},\"getBytecode(address,address,address,address,address,bytes)\":{\"notice\":\"Returns the bytecode of Barz with the given parameter\"},\"getCreationCode()\":{\"notice\":\"Returns the creation code of the Barz contract\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/BarzFactory.sol\":\"BarzFactory\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"contracts/Barz.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {LibDiamond} from \\\"./libraries/LibDiamond.sol\\\";\\nimport {IBarz} from \\\"./interfaces/IBarz.sol\\\";\\n\\n/**\\n * @title Barz\\n * @dev A diamond proxy wallet with a modular & upgradeable architecture\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract Barz is IBarz {\\n /**\\n * @notice Initializes Barz with the given parameters. Barz account is intended to be created from Barz Factory for stable deployment.\\n * @dev This method makes a delegate call to account facet and account facet handles the initialization.\\n * With modular architecture, Barz encompasses wide spectrum of architecture and logic.\\n * The only requirement is account facet to comply with initialize() interface.\\n * Barz doesn't include built-in functions and is a full proxy, for maximum extensibility and modularity.\\n * @param _accountFacet Address of Account Facet in charge of the Barz initialization\\n * @param _verificationFacet Address of Verification Facet for verifying the signature. Could be any signature scheme\\n * @param _entryPoint Address of Entry Point contract\\n * @param _facetRegistry Address of Facet Registry. Facet Registry is a registry holding trusted facets that could be added to user's wallet\\n * @param _defaultFallBack Address of Default FallBack Handler. Middleware contract for more efficient deployment\\n * @param _ownerPublicKey Bytes of Owner Public Key using for initialization\\n */\\n constructor(\\n address _accountFacet,\\n address _verificationFacet,\\n address _entryPoint,\\n address _facetRegistry,\\n address _defaultFallBack,\\n bytes memory _ownerPublicKey\\n ) payable {\\n bytes memory initCall = abi.encodeWithSignature(\\n \\\"initialize(address,address,address,address,bytes)\\\",\\n _verificationFacet,\\n _entryPoint,\\n _facetRegistry,\\n _defaultFallBack,\\n _ownerPublicKey\\n );\\n (bool success, bytes memory result) = _accountFacet.delegatecall(\\n initCall\\n );\\n if (!success || uint256(bytes32(result)) != 1) {\\n revert Barz__InitializationFailure();\\n }\\n }\\n\\n /**\\n * @notice Fallback function for Barz complying with Diamond Standard with customization of adding Default Fallback Handler\\n * @dev Find facet for function that is called and execute the function if a facet is found and return any value.\\n */\\n fallback() external payable {\\n LibDiamond.DiamondStorage storage ds;\\n bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION;\\n // get diamond storage\\n assembly {\\n ds.slot := position\\n }\\n // get facet from function selector\\n address facet = address(bytes20(ds.facets[msg.sig]));\\n if (facet == address(0))\\n facet = ds.defaultFallbackHandler.facetAddress(msg.sig);\\n require(facet != address(0), \\\"Barz: Function does not exist\\\");\\n // Execute external function from facet using delegatecall and return any value.\\n assembly {\\n // copy function selector and any arguments\\n calldatacopy(0, 0, calldatasize())\\n // execute function call using the facet\\n let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)\\n // get any return value\\n returndatacopy(0, 0, returndatasize())\\n // return any return value or error back to the caller\\n switch result\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @notice Receive function to receive native token without data\\n */\\n receive() external payable {}\\n}\\n\",\"keccak256\":\"0xd1c773409a4b3d1ca0316445d9ea1d686bab9cd5f6731fbdb0766a93edfd7bdb\",\"license\":\"Apache-2.0\"},\"contracts/BarzFactory.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {Barz} from \\\"./Barz.sol\\\";\\nimport {IBarzFactory} from \\\"./interfaces/IBarzFactory.sol\\\";\\n\\n/**\\n * @title Barz Factory\\n * @dev Contract to easily deploy Barz to a pre-computed address with a single call\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract BarzFactory is IBarzFactory {\\n address public immutable accountFacet;\\n address public immutable entryPoint;\\n address public immutable facetRegistry;\\n address public immutable defaultFallback;\\n\\n /**\\n * @notice Sets the initialization data for Barz contract initialization\\n * @param _accountFacet Account Facet to be used to create Barz\\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\\n * @param _facetRegistry Facet Registry to be used to create Barz\\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\\n */\\n constructor(\\n address _accountFacet,\\n address _entryPoint,\\n address _facetRegistry,\\n address _defaultFallback\\n ) {\\n accountFacet = _accountFacet;\\n entryPoint = _entryPoint;\\n facetRegistry = _facetRegistry;\\n defaultFallback = _defaultFallback;\\n }\\n\\n /**\\n * @notice Creates the Barz with a single call. It creates the Barz contract with the givent verification facet\\n * @param _verificationFacet Address of verification facet used for creating the barz account\\n * @param _owner Public Key of the owner to initialize barz account\\n * @param _salt Salt used for deploying barz with create2\\n * @return barz Instance of Barz contract deployed with the given parameters\\n */\\n function createAccount(\\n address _verificationFacet,\\n bytes calldata _owner,\\n uint256 _salt\\n ) external override returns (Barz barz) {\\n address addr = getAddress(_verificationFacet, _owner, _salt);\\n uint codeSize = addr.code.length;\\n if (codeSize > 0) {\\n return Barz(payable(addr));\\n }\\n barz = new Barz{salt: bytes32(_salt)}(\\n accountFacet,\\n _verificationFacet,\\n entryPoint,\\n facetRegistry,\\n defaultFallback,\\n _owner\\n );\\n emit BarzDeployed(address(barz));\\n }\\n\\n /**\\n * @notice Calculates the address of Barz with the given parameters\\n * @param _verificationFacet Address of verification facet used for creating the barz account\\n * @param _owner Public Key of the owner to initialize barz account\\n * @param _salt Salt used for deploying barz with create2\\n * @return barzAddress Precalculated Barz address\\n */\\n function getAddress(\\n address _verificationFacet,\\n bytes calldata _owner,\\n uint256 _salt\\n ) public view override returns (address barzAddress) {\\n bytes memory bytecode = getBytecode(\\n accountFacet,\\n _verificationFacet,\\n entryPoint,\\n facetRegistry,\\n defaultFallback,\\n _owner\\n );\\n bytes32 hash = keccak256(\\n abi.encodePacked(\\n bytes1(0xff),\\n address(this),\\n _salt,\\n keccak256(bytecode)\\n )\\n );\\n barzAddress = address(uint160(uint256(hash)));\\n }\\n\\n /**\\n * @notice Returns the bytecode of Barz with the given parameter\\n * @param _accountFacet Account Facet to be used to create Barz\\n * @param _verificationFacet Verification Facet to be used to create Barz\\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\\n * @param _facetRegistry Facet Registry to be used to create Barz\\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\\n * @param _ownerPublicKey Public Key of owner to be used to initialize Barz ownership\\n * @return barzBytecode Bytecode of Barz\\n */\\n function getBytecode(\\n address _accountFacet,\\n address _verificationFacet,\\n address _entryPoint,\\n address _facetRegistry,\\n address _defaultFallback,\\n bytes calldata _ownerPublicKey\\n ) public pure override returns (bytes memory barzBytecode) {\\n bytes memory bytecode = type(Barz).creationCode;\\n barzBytecode = abi.encodePacked(\\n bytecode,\\n abi.encode(\\n _accountFacet,\\n _verificationFacet,\\n _entryPoint,\\n _facetRegistry,\\n _defaultFallback,\\n _ownerPublicKey\\n )\\n );\\n }\\n\\n /**\\n * @notice Returns the creation code of the Barz contract\\n * @return creationCode Creation code of Barz\\n */\\n function getCreationCode()\\n public\\n pure\\n override\\n returns (bytes memory creationCode)\\n {\\n creationCode = type(Barz).creationCode;\\n }\\n}\\n\",\"keccak256\":\"0x76d6058fa4714f5ef87b876e49ce7e21f581164901eea906ec743e82362b1df6\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IBarz.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Barz Interface\\n * @dev Interface of Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IBarz {\\n error Barz__InitializationFailure();\\n}\\n\",\"keccak256\":\"0xca9f0c2c1ad7d06088fa16ae92d587416f2d10d8f999d7afe8ca5c4d73410aba\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IBarzFactory.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {Barz} from \\\"../Barz.sol\\\";\\n\\n/**\\n * @title Barz Factory Interface\\n * @dev Interface of contract to easily deploy Barz to a pre-computed address with a single call\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IBarzFactory {\\n event BarzDeployed(address);\\n\\n function createAccount(\\n address verificationFacet,\\n bytes calldata owner,\\n uint256 salt\\n ) external returns (Barz);\\n\\n function getAddress(\\n address verificationFacet,\\n bytes calldata owner,\\n uint256 salt\\n ) external view returns (address);\\n\\n function getBytecode(\\n address accountFacet,\\n address verificationFacet,\\n address entryPoint,\\n address facetRegistry,\\n address defaultFallback,\\n bytes memory ownerPublicKey\\n ) external pure returns (bytes memory);\\n\\n function getCreationCode() external pure returns (bytes memory);\\n}\\n\",\"keccak256\":\"0xadb48a6f3025f6395e26ffd5f9319da73ad2383906c8223e8455f41f420fba26\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\\n bytes4(keccak256(\\\"verifyRestrictions(address,address,uint256,bytes)\\\"));\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // Default Fallback Handler of the barz.\\n IDiamondLoupe defaultFallbackHandler;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function enforceIsSelf() internal view {\\n require(msg.sender == address(this), \\\"LibDiamond: Caller not self\\\");\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n\\n unchecked {\\n facetIndex++;\\n }\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n\\n function restrictionsFacet() internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(\\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2cabdc00de859c3a3170ce3bda5d0e5fd3933d47ce904fd1585f9818b02572f8\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x61010060405234801561001157600080fd5b50604051610eba380380610eba8339810160408190526100309161006e565b6001600160a01b0393841660805291831660a052821660c0521660e0526100c2565b80516001600160a01b038116811461006957600080fd5b919050565b6000806000806080858703121561008457600080fd5b61008d85610052565b935061009b60208601610052565b92506100a960408601610052565b91506100b760608601610052565b905092959194509250565b60805160a05160c05160e051610d886101326000396000818161013b015281816102b3015261048101526000818160bf01528181610292015261046001526000818161016301528181610271015261043f01526000818161018b0152818161024f015261041d0152610d886000f3fe60806040523480156200001157600080fd5b5060043610620000925760003560e01c806344409a82116200006257806344409a821462000135578063b0d691fe146200015d578063b0f5d4641462000185578063c8a7adf514620001ad57600080fd5b8062c194db14620000975780630a1acd7314620000b9578063296601cd146200010757806333bb64a7146200011e575b600080fd5b620000a1620001c4565b604051620000b091906200056c565b60405180910390f35b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001620000b0565b620000e16200011836600462000635565b6200020e565b620000a16200012f36600462000695565b6200036d565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e1620001be36600462000635565b62000414565b606060405180602001620001d89062000538565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082820381018352601f90910116604052919050565b6000806200021f8686868662000414565b905073ffffffffffffffffffffffffffffffffffffffff81163b8015620002495750905062000365565b8360001b7f0000000000000000000000000000000000000000000000000000000000000000887f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008b8b604051620002e29062000538565b620002f497969594939291906200073a565b8190604051809103906000f590508015801562000315573d6000803e3d6000fd5b5060405173ffffffffffffffffffffffffffffffffffffffff821681529093507f9e6e326008e68f57877e2bae766a5745c162e42359e34834a7f0661fa82d31b19060200160405180910390a150505b949350505050565b6060600060405180602001620003839062000538565b6020820181038252601f19601f8201166040525090508089898989898989604051602001620003b997969594939291906200073a565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052620003f79291602001620007cd565b604051602081830303815290604052915050979650505050505050565b600080620004a87f0000000000000000000000000000000000000000000000000000000000000000877f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008a8a6200036d565b8051602091820120604080517fff00000000000000000000000000000000000000000000000000000000000000818501523060601b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001660218201526035810196909652605580870192909252805180870390920182526075909501909452835193019290922095945050505050565b610552806200080183390190565b60005b838110156200056357818101518382015260200162000549565b50506000910152565b60208152600082518060208401526200058d81604085016020870162000546565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b803573ffffffffffffffffffffffffffffffffffffffff81168114620005e457600080fd5b919050565b60008083601f840112620005fc57600080fd5b50813567ffffffffffffffff8111156200061557600080fd5b6020830191508360208285010111156200062e57600080fd5b9250929050565b600080600080606085870312156200064c57600080fd5b6200065785620005bf565b9350602085013567ffffffffffffffff8111156200067457600080fd5b6200068287828801620005e9565b9598909750949560400135949350505050565b600080600080600080600060c0888a031215620006b157600080fd5b620006bc88620005bf565b9650620006cc60208901620005bf565b9550620006dc60408901620005bf565b9450620006ec60608901620005bf565b9350620006fc60808901620005bf565b925060a088013567ffffffffffffffff8111156200071957600080fd5b620007278a828b01620005e9565b989b979a50959850939692959293505050565b600073ffffffffffffffffffffffffffffffffffffffff808a16835280891660208401528088166040840152808716606084015280861660808401525060c060a08301528260c0830152828460e0840137600060e0848401015260e07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f850116830101905098975050505050505050565b60008351620007e181846020880162000546565b835190830190620007f781836020880162000546565b0194935050505056fe608060405260405161055238038061055283398101604081905261002291610163565b6000858585858560405160240161003d959493929190610264565b60408051601f198184030181529181526020820180516001600160e01b0316634a93641760e01b1790525190915060009081906001600160a01b038a16906100869085906102c3565b600060405180830381855af49150503d80600081146100c1576040519150601f19603f3d011682016040523d82523d6000602084013e6100c6565b606091505b50915091508115806100e157506100dc816102df565b600114155b156100ff57604051636ff35f8960e01b815260040160405180910390fd5b505050505050505050610306565b80516001600160a01b038116811461012457600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101561015a578181015183820152602001610142565b50506000910152565b60008060008060008060c0878903121561017c57600080fd5b6101858761010d565b95506101936020880161010d565b94506101a16040880161010d565b93506101af6060880161010d565b92506101bd6080880161010d565b60a08801519092506001600160401b03808211156101da57600080fd5b818901915089601f8301126101ee57600080fd5b81518181111561020057610200610129565b604051601f8201601f19908116603f0116810190838211818310171561022857610228610129565b816040528281528c602084870101111561024157600080fd5b61025283602083016020880161013f565b80955050505050509295509295509295565b600060018060a01b0380881683528087166020840152808616604084015280851660608401525060a0608083015282518060a08401526102ab8160c085016020870161013f565b601f01601f19169190910160c0019695505050505050565b600082516102d581846020870161013f565b9190910192915050565b80516020808301519190811015610300576000198160200360031b1b821691505b50919050565b61023d806103156000396000f3fe60806040523661000b57005b600080357fffffffff000000000000000000000000000000000000000000000000000000001681527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020819052604090912054819060601c80610125576004838101546040517fcdffacc60000000000000000000000000000000000000000000000000000000081526000357fffffffff00000000000000000000000000000000000000000000000000000000169281019290925273ffffffffffffffffffffffffffffffffffffffff169063cdffacc690602401602060405180830381865afa1580156100fe573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061012291906101ca565b90505b73ffffffffffffffffffffffffffffffffffffffff81166101a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4261727a3a2046756e6374696f6e20646f6573206e6f74206578697374000000604482015260640160405180910390fd5b3660008037600080366000845af43d6000803e8080156101c5573d6000f35b3d6000fd5b6000602082840312156101dc57600080fd5b815173ffffffffffffffffffffffffffffffffffffffff8116811461020057600080fd5b939250505056fea26469706673582212200f3fa76ace3be8675d8b4c0d6c210a922fff2c2f1444023b817d1f6c908cd56a64736f6c63430008150033a2646970667358221220329ad45a4ef4915180001cb1fc90a5f97ad94a0b280426a580cba65fce28c0f164736f6c63430008150033", + "deployedBytecode": "0x60806040523480156200001157600080fd5b5060043610620000925760003560e01c806344409a82116200006257806344409a821462000135578063b0d691fe146200015d578063b0f5d4641462000185578063c8a7adf514620001ad57600080fd5b8062c194db14620000975780630a1acd7314620000b9578063296601cd146200010757806333bb64a7146200011e575b600080fd5b620000a1620001c4565b604051620000b091906200056c565b60405180910390f35b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001620000b0565b620000e16200011836600462000635565b6200020e565b620000a16200012f36600462000695565b6200036d565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e1620001be36600462000635565b62000414565b606060405180602001620001d89062000538565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082820381018352601f90910116604052919050565b6000806200021f8686868662000414565b905073ffffffffffffffffffffffffffffffffffffffff81163b8015620002495750905062000365565b8360001b7f0000000000000000000000000000000000000000000000000000000000000000887f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008b8b604051620002e29062000538565b620002f497969594939291906200073a565b8190604051809103906000f590508015801562000315573d6000803e3d6000fd5b5060405173ffffffffffffffffffffffffffffffffffffffff821681529093507f9e6e326008e68f57877e2bae766a5745c162e42359e34834a7f0661fa82d31b19060200160405180910390a150505b949350505050565b6060600060405180602001620003839062000538565b6020820181038252601f19601f8201166040525090508089898989898989604051602001620003b997969594939291906200073a565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052620003f79291602001620007cd565b604051602081830303815290604052915050979650505050505050565b600080620004a87f0000000000000000000000000000000000000000000000000000000000000000877f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008a8a6200036d565b8051602091820120604080517fff00000000000000000000000000000000000000000000000000000000000000818501523060601b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001660218201526035810196909652605580870192909252805180870390920182526075909501909452835193019290922095945050505050565b610552806200080183390190565b60005b838110156200056357818101518382015260200162000549565b50506000910152565b60208152600082518060208401526200058d81604085016020870162000546565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b803573ffffffffffffffffffffffffffffffffffffffff81168114620005e457600080fd5b919050565b60008083601f840112620005fc57600080fd5b50813567ffffffffffffffff8111156200061557600080fd5b6020830191508360208285010111156200062e57600080fd5b9250929050565b600080600080606085870312156200064c57600080fd5b6200065785620005bf565b9350602085013567ffffffffffffffff8111156200067457600080fd5b6200068287828801620005e9565b9598909750949560400135949350505050565b600080600080600080600060c0888a031215620006b157600080fd5b620006bc88620005bf565b9650620006cc60208901620005bf565b9550620006dc60408901620005bf565b9450620006ec60608901620005bf565b9350620006fc60808901620005bf565b925060a088013567ffffffffffffffff8111156200071957600080fd5b620007278a828b01620005e9565b989b979a50959850939692959293505050565b600073ffffffffffffffffffffffffffffffffffffffff808a16835280891660208401528088166040840152808716606084015280861660808401525060c060a08301528260c0830152828460e0840137600060e0848401015260e07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f850116830101905098975050505050505050565b60008351620007e181846020880162000546565b835190830190620007f781836020880162000546565b0194935050505056fe608060405260405161055238038061055283398101604081905261002291610163565b6000858585858560405160240161003d959493929190610264565b60408051601f198184030181529181526020820180516001600160e01b0316634a93641760e01b1790525190915060009081906001600160a01b038a16906100869085906102c3565b600060405180830381855af49150503d80600081146100c1576040519150601f19603f3d011682016040523d82523d6000602084013e6100c6565b606091505b50915091508115806100e157506100dc816102df565b600114155b156100ff57604051636ff35f8960e01b815260040160405180910390fd5b505050505050505050610306565b80516001600160a01b038116811461012457600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101561015a578181015183820152602001610142565b50506000910152565b60008060008060008060c0878903121561017c57600080fd5b6101858761010d565b95506101936020880161010d565b94506101a16040880161010d565b93506101af6060880161010d565b92506101bd6080880161010d565b60a08801519092506001600160401b03808211156101da57600080fd5b818901915089601f8301126101ee57600080fd5b81518181111561020057610200610129565b604051601f8201601f19908116603f0116810190838211818310171561022857610228610129565b816040528281528c602084870101111561024157600080fd5b61025283602083016020880161013f565b80955050505050509295509295509295565b600060018060a01b0380881683528087166020840152808616604084015280851660608401525060a0608083015282518060a08401526102ab8160c085016020870161013f565b601f01601f19169190910160c0019695505050505050565b600082516102d581846020870161013f565b9190910192915050565b80516020808301519190811015610300576000198160200360031b1b821691505b50919050565b61023d806103156000396000f3fe60806040523661000b57005b600080357fffffffff000000000000000000000000000000000000000000000000000000001681527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020819052604090912054819060601c80610125576004838101546040517fcdffacc60000000000000000000000000000000000000000000000000000000081526000357fffffffff00000000000000000000000000000000000000000000000000000000169281019290925273ffffffffffffffffffffffffffffffffffffffff169063cdffacc690602401602060405180830381865afa1580156100fe573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061012291906101ca565b90505b73ffffffffffffffffffffffffffffffffffffffff81166101a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4261727a3a2046756e6374696f6e20646f6573206e6f74206578697374000000604482015260640160405180910390fd5b3660008037600080366000845af43d6000803e8080156101c5573d6000f35b3d6000fd5b6000602082840312156101dc57600080fd5b815173ffffffffffffffffffffffffffffffffffffffff8116811461020057600080fd5b939250505056fea26469706673582212200f3fa76ace3be8675d8b4c0d6c210a922fff2c2f1444023b817d1f6c908cd56a64736f6c63430008150033a2646970667358221220329ad45a4ef4915180001cb1fc90a5f97ad94a0b280426a580cba65fce28c0f164736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "Contract to easily deploy Barz to a pre-computed address with a single call", + "kind": "dev", + "methods": { + "constructor": { + "params": { + "_accountFacet": "Account Facet to be used to create Barz", + "_defaultFallback": "Default Fallback Handler to be used to create Barz", + "_entryPoint": "Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF", + "_facetRegistry": "Facet Registry to be used to create Barz" + } + }, + "createAccount(address,bytes,uint256)": { + "params": { + "_owner": "Public Key of the owner to initialize barz account", + "_salt": "Salt used for deploying barz with create2", + "_verificationFacet": "Address of verification facet used for creating the barz account" + }, + "returns": { + "barz": "Instance of Barz contract deployed with the given parameters" + } + }, + "getAddress(address,bytes,uint256)": { + "params": { + "_owner": "Public Key of the owner to initialize barz account", + "_salt": "Salt used for deploying barz with create2", + "_verificationFacet": "Address of verification facet used for creating the barz account" + }, + "returns": { + "barzAddress": "Precalculated Barz address" + } + }, + "getBytecode(address,address,address,address,address,bytes)": { + "params": { + "_accountFacet": "Account Facet to be used to create Barz", + "_defaultFallback": "Default Fallback Handler to be used to create Barz", + "_entryPoint": "Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF", + "_facetRegistry": "Facet Registry to be used to create Barz", + "_ownerPublicKey": "Public Key of owner to be used to initialize Barz ownership", + "_verificationFacet": "Verification Facet to be used to create Barz" + }, + "returns": { + "barzBytecode": "Bytecode of Barz" + } + }, + "getCreationCode()": { + "returns": { + "creationCode": "Creation code of Barz" + } + } + }, + "title": "Barz Factory", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "constructor": { + "notice": "Sets the initialization data for Barz contract initialization" + }, + "createAccount(address,bytes,uint256)": { + "notice": "Creates the Barz with a single call. It creates the Barz contract with the givent verification facet" + }, + "getAddress(address,bytes,uint256)": { + "notice": "Calculates the address of Barz with the given parameters" + }, + "getBytecode(address,address,address,address,address,bytes)": { + "notice": "Returns the bytecode of Barz with the given parameter" + }, + "getCreationCode()": { + "notice": "Returns the creation code of the Barz contract" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/arbitrum/DefaultFallbackHandler.json b/deployments/arbitrum/DefaultFallbackHandler.json new file mode 100644 index 0000000..5a55b1b --- /dev/null +++ b/deployments/arbitrum/DefaultFallbackHandler.json @@ -0,0 +1,275 @@ +{ + "address": "0x2e7f1dAe1F3799d20f5c31bEFdc7A620f664728D", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_diamondCutFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_accountFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_tokenReceiverFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_diamondLoupeFacet", + "type": "address" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_initializationContractAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "InitializationFunctionReverted", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "indexed": false, + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "DiamondCut", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_functionSelector", + "type": "bytes4" + } + ], + "name": "facetAddress", + "outputs": [ + { + "internalType": "address", + "name": "facetAddress_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetAddresses", + "outputs": [ + { + "internalType": "address[]", + "name": "facetAddresses_", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_facet", + "type": "address" + } + ], + "name": "facetFunctionSelectors", + "outputs": [ + { + "internalType": "bytes4[]", + "name": "facetFunctionSelectors_", + "type": "bytes4[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facets", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondLoupe.Facet[]", + "name": "facets_", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0xd9a6670101c0cd5e8237a725152d98fe4934af95ed268e0b36640960c4f1dca4", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 1, + "gasUsed": "13001879", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000001000000000800002000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000", + "blockHash": "0xf665d937e5214e7ae303da96390e8eb5755deea6ddf5695ae4f0ac6694f0acf4", + "transactionHash": "0xd9a6670101c0cd5e8237a725152d98fe4934af95ed268e0b36640960c4f1dca4", + "logs": [ + { + "transactionIndex": 1, + "blockNumber": 152284164, + "transactionHash": "0xd9a6670101c0cd5e8237a725152d98fe4934af95ed268e0b36640960c4f1dca4", + "address": "0x2e7f1dAe1F3799d20f5c31bEFdc7A620f664728D", + "topics": [ + "0x8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb673" + ], + "data": "0x000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000580000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000000000000000000000000000000000003600000000000000000000000000b9504140771c3688ff041917192277d2f52e1e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000011f931c1c00000000000000000000000000000000000000000000000000000000000000000000000000000000fde53272dcd7938d16e031a6989753c321728332000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000005b61d27f60000000000000000000000000000000000000000000000000000000047e1da2a000000000000000000000000000000000000000000000000000000003a871cdd00000000000000000000000000000000000000000000000000000000d087d28800000000000000000000000000000000000000000000000000000000b0d691fe000000000000000000000000000000000000000000000000000000000000000000000000000000003143e1c0af0cdc153423863923cf4e3818e34daa000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000005150b7a0200000000000000000000000000000000000000000000000000000000f23a6e6100000000000000000000000000000000000000000000000000000000bc197c81000000000000000000000000000000000000000000000000000000000023de2900000000000000000000000000000000000000000000000000000000a4c0ed3600000000000000000000000000000000000000000000000000000000000000000000000000000000ce36b85d12d81cd619c745c7717f3396e184ac7c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000097a0ed62700000000000000000000000000000000000000000000000000000000adfca15e0000000000000000000000000000000000000000000000000000000052ef6b2c00000000000000000000000000000000000000000000000000000000cdffacc60000000000000000000000000000000000000000000000000000000001ffc9a700000000000000000000000000000000000000000000000000000000f9796ccf0000000000000000000000000000000000000000000000000000000001a5502200000000000000000000000000000000000000000000000000000000d42139a900000000000000000000000000000000000000000000000000000000e3a2f6fe000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "logIndex": 0, + "blockHash": "0xf665d937e5214e7ae303da96390e8eb5755deea6ddf5695ae4f0ac6694f0acf4" + } + ], + "blockNumber": 152284164, + "cumulativeGasUsed": "13001879", + "status": 1, + "byzantium": true + }, + "args": [ + "0x0B9504140771C3688Ff041917192277D2f52E1e0", + "0xFde53272dcd7938d16E031A6989753c321728332", + "0x3143E1C0Af0Cdc153423863923Cf4e3818e34Daa", + "0xCe36b85d12D81cd619C745c7717f3396E184Ac7C" + ], + "numDeployments": 3, + "solcInputHash": "4356503edd8ae34e73cb6dd1c8e2fc8a", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_diamondCutFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_accountFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_tokenReceiverFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_diamondLoupeFacet\",\"type\":\"address\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_initializationContractAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"InitializationFunctionReverted\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"DiamondCut\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_functionSelector\",\"type\":\"bytes4\"}],\"name\":\"facetAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"facetAddress_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetAddresses\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"facetAddresses_\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_facet\",\"type\":\"address\"}],\"name\":\"facetFunctionSelectors\",\"outputs\":[{\"internalType\":\"bytes4[]\",\"name\":\"facetFunctionSelectors_\",\"type\":\"bytes4[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facets\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondLoupe.Facet[]\",\"name\":\"facets_\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"A default fallback handler for Barz\",\"kind\":\"dev\",\"methods\":{\"constructor\":{\"details\":\"This contract is also a diamond that holds the default facets to reduce gas cost for wallet activation. Within the constructor this conducts diamond cut to initially setup the diamond. This is a non-upgradeable contract\",\"params\":{\"_accountFacet\":\"Address account facet\",\"_diamondCutFacet\":\"Address if diamond cut facet\",\"_diamondLoupeFacet\":\"Address of diamond loupe facet\",\"_tokenReceiverFacet\":\"Address of token receiver facet\"}},\"facetAddress(bytes4)\":{\"details\":\"If facet is not found return address(0).\",\"params\":{\"_functionSelector\":\"The function selector.\"},\"returns\":{\"facetAddress_\":\"The facet address.\"}},\"facetAddresses()\":{\"returns\":{\"facetAddresses_\":\"facetAddresses_\"}},\"facetFunctionSelectors(address)\":{\"params\":{\"_facet\":\"The facet address.\"},\"returns\":{\"facetFunctionSelectors_\":\"facetFunctionSelectors_\"}},\"facets()\":{\"returns\":{\"facets_\":\"The facet struct array including all facet information\"}}},\"title\":\"DefaultFallbackHandler\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"Sets the middleware diamond for Barz wallet as a fallback handler\"},\"facetAddress(bytes4)\":{\"notice\":\"Gets the facet that supports the given selector.\"},\"facetAddresses()\":{\"notice\":\"Get all the facet addresses used by a diamond.\"},\"facetFunctionSelectors(address)\":{\"notice\":\"Gets all the function selectors provided by a facet.\"},\"facets()\":{\"notice\":\"Returns the facet information of call facets registered to this diamond.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/infrastructure/DefaultFallbackHandler.sol\":\"DefaultFallbackHandler\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/introspection/IERC165.sol\\\";\\n\\n/**\\n * @dev _Available since v3.1._\\n */\\ninterface IERC1155Receiver is IERC165 {\\n /**\\n * @dev Handles the receipt of a single ERC1155 token type. This function is\\n * called at the end of a `safeTransferFrom` after the balance has been updated.\\n *\\n * NOTE: To accept the transfer, this must return\\n * `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))`\\n * (i.e. 0xf23a6e61, or its own function selector).\\n *\\n * @param operator The address which initiated the transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param id The ID of the token being transferred\\n * @param value The amount of tokens being transferred\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155Received(\\n address operator,\\n address from,\\n uint256 id,\\n uint256 value,\\n bytes calldata data\\n ) external returns (bytes4);\\n\\n /**\\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\\n * is called at the end of a `safeBatchTransferFrom` after the balances have\\n * been updated.\\n *\\n * NOTE: To accept the transfer(s), this must return\\n * `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))`\\n * (i.e. 0xbc197c81, or its own function selector).\\n *\\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155BatchReceived(\\n address operator,\\n address from,\\n uint256[] calldata ids,\\n uint256[] calldata values,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xeb373f1fdc7b755c6a750123a9b9e3a8a02c1470042fd6505d875000a80bde0b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title ERC721 token receiver interface\\n * @dev Interface for any contract that wants to support safeTransfers\\n * from ERC721 asset contracts.\\n */\\ninterface IERC721Receiver {\\n /**\\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\\n * by `operator` from `from`, this function is called.\\n *\\n * It must return its Solidity selector to confirm the token transfer.\\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\\n *\\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\\n */\\n function onERC721Received(\\n address operator,\\n address from,\\n uint256 tokenId,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\\n *\\n * Accounts can be notified of {IERC777} tokens being sent to them by having a\\n * contract implement this interface (contract holders can be their own\\n * implementer) and registering it on the\\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\\n *\\n * See {IERC1820Registry} and {ERC1820Implementer}.\\n */\\ninterface IERC777Recipient {\\n /**\\n * @dev Called by an {IERC777} token contract whenever tokens are being\\n * moved or created into a registered account (`to`). The type of operation\\n * is conveyed by `from` being the zero address or not.\\n *\\n * This call occurs _after_ the token contract's state is updated, so\\n * {IERC777-balanceOf}, etc., can be used to query the post-operation state.\\n *\\n * This function may revert to prevent the operation from being executed.\\n */\\n function tokensReceived(\\n address operator,\\n address from,\\n address to,\\n uint256 amount,\\n bytes calldata userData,\\n bytes calldata operatorData\\n ) external;\\n}\\n\",\"keccak256\":\"0x1a5d61db2733202ba361e6d6741cd2e662380e22b80e987eacfc91973f2267dc\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"contracts/aa-4337/core/BaseAccount.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-empty-blocks */\\n\\nimport \\\"../interfaces/IAccount.sol\\\";\\nimport \\\"../interfaces/IEntryPoint.sol\\\";\\nimport \\\"./Helpers.sol\\\";\\n\\n/**\\n * Basic account implementation.\\n * this contract provides the basic logic for implementing the IAccount interface - validateUserOp\\n * specific account implementation should inherit it and provide the account-specific logic\\n */\\nabstract contract BaseAccount is IAccount {\\n using UserOperationLib for UserOperation;\\n\\n //return value in case of signature failure, with no time-range.\\n // equivalent to _packValidationData(true,0,0);\\n uint256 internal constant SIG_VALIDATION_FAILED = 1;\\n\\n /**\\n * Return the account nonce.\\n * This method returns the next sequential nonce.\\n * For a nonce of a specific key, use `entrypoint.getNonce(account, key)`\\n */\\n function getNonce() public view virtual returns (uint256) {\\n return entryPoint().getNonce(address(this), 0);\\n }\\n\\n /**\\n * return the entryPoint used by this account.\\n * subclass should return the current entryPoint used by this account.\\n */\\n function entryPoint() public view virtual returns (IEntryPoint);\\n\\n /**\\n * Validate user's signature and nonce.\\n * subclass doesn't need to override this method. Instead, it should override the specific internal validation methods.\\n */\\n function validateUserOp(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n uint256 missingAccountFunds\\n ) external virtual override returns (uint256 validationData) {\\n _requireFromEntryPoint();\\n validationData = _validateSignature(userOp, userOpHash);\\n _validateNonce(userOp.nonce);\\n _payPrefund(missingAccountFunds);\\n }\\n\\n /**\\n * ensure the request comes from the known entrypoint.\\n */\\n function _requireFromEntryPoint() internal view virtual {\\n require(\\n msg.sender == address(entryPoint()),\\n \\\"account: not from EntryPoint\\\"\\n );\\n }\\n\\n /**\\n * validate the signature is valid for this message.\\n * @param userOp validate the userOp.signature field\\n * @param userOpHash convenient field: the hash of the request, to check the signature against\\n * (also hashes the entrypoint and chain id)\\n * @return validationData signature and time-range of this operation\\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\\n * otherwise, an address of an \\\"authorizer\\\" contract.\\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \\\"indefinite\\\"\\n * <6-byte> validAfter - first timestamp this operation is valid\\n * If the account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\\n */\\n function _validateSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) internal virtual returns (uint256 validationData);\\n\\n /**\\n * Validate the nonce of the UserOperation.\\n * This method may validate the nonce requirement of this account.\\n * e.g.\\n * To limit the nonce to use sequenced UserOps only (no \\\"out of order\\\" UserOps):\\n * `require(nonce < type(uint64).max)`\\n * For a hypothetical account that *requires* the nonce to be out-of-order:\\n * `require(nonce & type(uint64).max == 0)`\\n *\\n * The actual nonce uniqueness is managed by the EntryPoint, and thus no other\\n * action is needed by the account itself.\\n *\\n * @param nonce to validate\\n *\\n * solhint-disable-next-line no-empty-blocks\\n */\\n function _validateNonce(uint256 nonce) internal view virtual {}\\n\\n /**\\n * sends to the entrypoint (msg.sender) the missing funds for this transaction.\\n * subclass MAY override this method for better funds management\\n * (e.g. send to the entryPoint more than the minimum required, so that in future transactions\\n * it will not be required to send again)\\n * @param missingAccountFunds the minimum value this method should send the entrypoint.\\n * this value MAY be zero, in case there is enough deposit, or the userOp has a paymaster.\\n */\\n function _payPrefund(uint256 missingAccountFunds) internal virtual {\\n if (missingAccountFunds != 0) {\\n (bool success, ) = payable(msg.sender).call{\\n value: missingAccountFunds,\\n gas: type(uint256).max\\n }(\\\"\\\");\\n (success);\\n //ignore failure (its EntryPoint's job to verify, not account.)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa0dcc386b0f04711db3e394fb50e55a3b3b1a4d19fac1f10895844e1aa4e3d5c\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/core/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable no-inline-assembly */\\n\\n/**\\n * returned data from validateUserOp.\\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\\n * @param aggregator - address(0) - the account validated the signature by itself.\\n * address(1) - the account failed to validate the signature.\\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\\n * @param validAfter - this UserOp is valid only after this timestamp.\\n * @param validaUntil - this UserOp is valid only up to this timestamp.\\n */\\nstruct ValidationData {\\n address aggregator;\\n uint48 validAfter;\\n uint48 validUntil;\\n}\\n\\n//extract sigFailed, validAfter, validUntil.\\n// also convert zero validUntil to type(uint48).max\\nfunction _parseValidationData(\\n uint validationData\\n) pure returns (ValidationData memory data) {\\n address aggregator = address(uint160(validationData));\\n uint48 validUntil = uint48(validationData >> 160);\\n if (validUntil == 0) {\\n validUntil = type(uint48).max;\\n }\\n uint48 validAfter = uint48(validationData >> (48 + 160));\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n// intersect account and paymaster ranges.\\nfunction _intersectTimeRange(\\n uint256 validationData,\\n uint256 paymasterValidationData\\n) pure returns (ValidationData memory) {\\n ValidationData memory accountValidationData = _parseValidationData(\\n validationData\\n );\\n ValidationData memory pmValidationData = _parseValidationData(\\n paymasterValidationData\\n );\\n address aggregator = accountValidationData.aggregator;\\n if (aggregator == address(0)) {\\n aggregator = pmValidationData.aggregator;\\n }\\n uint48 validAfter = accountValidationData.validAfter;\\n uint48 validUntil = accountValidationData.validUntil;\\n uint48 pmValidAfter = pmValidationData.validAfter;\\n uint48 pmValidUntil = pmValidationData.validUntil;\\n\\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp\\n * @param data - the ValidationData to pack\\n */\\nfunction _packValidationData(\\n ValidationData memory data\\n) pure returns (uint256) {\\n return\\n uint160(data.aggregator) |\\n (uint256(data.validUntil) << 160) |\\n (uint256(data.validAfter) << (160 + 48));\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp, when not using an aggregator\\n * @param sigFailed - true for signature failure, false for success\\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\\n * @param validAfter first timestamp this UserOperation is valid\\n */\\nfunction _packValidationData(\\n bool sigFailed,\\n uint48 validUntil,\\n uint48 validAfter\\n) pure returns (uint256) {\\n return\\n (sigFailed ? 1 : 0) |\\n (uint256(validUntil) << 160) |\\n (uint256(validAfter) << (160 + 48));\\n}\\n\\n/**\\n * keccak function over calldata.\\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\\n */\\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\\n assembly {\\n let mem := mload(0x40)\\n let len := data.length\\n calldatacopy(mem, data.offset, len)\\n ret := keccak256(mem, len)\\n }\\n}\\n\",\"keccak256\":\"0xa79f06cd158ecb8c0da95493a2f348933b8627a63e228b99738bff3aa107942d\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAccount.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\ninterface IAccount {\\n /**\\n * Validate user's signature and nonce\\n * the entryPoint will make the call to the recipient only if this validation call returns successfully.\\n * signature failure should be reported by returning SIG_VALIDATION_FAILED (1).\\n * This allows making a \\\"simulation call\\\" without a valid signature\\n * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure.\\n *\\n * @dev Must validate caller is the entryPoint.\\n * Must validate the signature and nonce\\n * @param userOp the operation that is about to be executed.\\n * @param userOpHash hash of the user's request data. can be used as the basis for signature.\\n * @param missingAccountFunds missing funds on the account's deposit in the entrypoint.\\n * This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call.\\n * The excess is left as a deposit in the entrypoint, for future calls.\\n * can be withdrawn anytime using \\\"entryPoint.withdrawTo()\\\"\\n * In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero.\\n * @return validationData packaged ValidationData structure. use `_packValidationData` and `_unpackValidationData` to encode and decode\\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\\n * otherwise, an address of an \\\"authorizer\\\" contract.\\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \\\"indefinite\\\"\\n * <6-byte> validAfter - first timestamp this operation is valid\\n * If an account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\\n */\\n function validateUserOp(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n uint256 missingAccountFunds\\n ) external returns (uint256 validationData);\\n}\\n\",\"keccak256\":\"0xcbc4b0973cf954c5895b7796335f651fbfcfb55f67dfa789a3d354f8e23c4f2b\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAggregator.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\n/**\\n * Aggregated Signatures validator.\\n */\\ninterface IAggregator {\\n /**\\n * validate aggregated signature.\\n * revert if the aggregated signature does not match the given list of operations.\\n */\\n function validateSignatures(\\n UserOperation[] calldata userOps,\\n bytes calldata signature\\n ) external view;\\n\\n /**\\n * validate signature of a single userOp\\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\\n * @param userOp the userOperation received from the user.\\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\\n * (usually empty, unless account and aggregator support some kind of \\\"multisig\\\"\\n */\\n function validateUserOpSignature(\\n UserOperation calldata userOp\\n ) external view returns (bytes memory sigForUserOp);\\n\\n /**\\n * aggregate multiple signatures into a single value.\\n * This method is called off-chain to calculate the signature to pass with handleOps()\\n * bundler MAY use optimized custom code perform this aggregation\\n * @param userOps array of UserOperations to collect the signatures from.\\n * @return aggregatedSignature the aggregated signature\\n */\\n function aggregateSignatures(\\n UserOperation[] calldata userOps\\n ) external view returns (bytes memory aggregatedSignature);\\n}\\n\",\"keccak256\":\"0xdfdcd80568f037716674619b31be630fcd8316262f05a815b41d1e81782c966a\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IEntryPoint.sol\":{\"content\":\"/**\\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\\n ** Only one instance required on each chain.\\n **/\\n// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-inline-assembly */\\n/* solhint-disable reason-string */\\n\\nimport \\\"./UserOperation.sol\\\";\\nimport \\\"./IStakeManager.sol\\\";\\nimport \\\"./IAggregator.sol\\\";\\nimport \\\"./INonceManager.sol\\\";\\n\\ninterface IEntryPoint is IStakeManager, INonceManager {\\n /***\\n * An event emitted after each successful request\\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\\n * @param sender - the account that generates this request.\\n * @param paymaster - if non-null, the paymaster that pays for this request.\\n * @param nonce - the nonce value from the request.\\n * @param success - true if the sender transaction succeeded, false if reverted.\\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\\n */\\n event UserOperationEvent(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address indexed paymaster,\\n uint256 nonce,\\n bool success,\\n uint256 actualGasCost,\\n uint256 actualGasUsed\\n );\\n\\n /**\\n * account \\\"sender\\\" was deployed.\\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\\n * @param sender the account that is deployed\\n * @param factory the factory used to deploy this account (in the initCode)\\n * @param paymaster the paymaster used by this UserOp\\n */\\n event AccountDeployed(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address factory,\\n address paymaster\\n );\\n\\n /**\\n * An event emitted if the UserOperation \\\"callData\\\" reverted with non-zero length\\n * @param userOpHash the request unique identifier.\\n * @param sender the sender of this request\\n * @param nonce the nonce used in the request\\n * @param revertReason - the return bytes from the (reverted) call to \\\"callData\\\".\\n */\\n event UserOperationRevertReason(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n uint256 nonce,\\n bytes revertReason\\n );\\n\\n /**\\n * an event emitted by handleOps(), before starting the execution loop.\\n * any event emitted before this event, is part of the validation.\\n */\\n event BeforeExecution();\\n\\n /**\\n * signature aggregator used by the following UserOperationEvents within this bundle.\\n */\\n event SignatureAggregatorChanged(address indexed aggregator);\\n\\n /**\\n * a custom revert error of handleOps, to identify the offending op.\\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\\n * @param reason - revert reason\\n * The string starts with a unique code \\\"AAmn\\\", where \\\"m\\\" is \\\"1\\\" for factory, \\\"2\\\" for account and \\\"3\\\" for paymaster issues,\\n * so a failure can be attributed to the correct entity.\\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\\n */\\n error FailedOp(uint256 opIndex, string reason);\\n\\n /**\\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\\n */\\n error SignatureValidationFailed(address aggregator);\\n\\n /**\\n * Successful result from simulateValidation.\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n */\\n error ValidationResult(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo\\n );\\n\\n /**\\n * Successful result from simulateValidation, if the account returns a signature aggregator\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\\n * bundler MUST use it to verify the signature, or reject the UserOperation\\n */\\n error ValidationResultWithAggregation(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo,\\n AggregatorStakeInfo aggregatorInfo\\n );\\n\\n /**\\n * return value of getSenderAddress\\n */\\n error SenderAddressResult(address sender);\\n\\n /**\\n * return value of simulateHandleOp\\n */\\n error ExecutionResult(\\n uint256 preOpGas,\\n uint256 paid,\\n uint48 validAfter,\\n uint48 validUntil,\\n bool targetSuccess,\\n bytes targetResult\\n );\\n\\n //UserOps handled, per aggregator\\n struct UserOpsPerAggregator {\\n UserOperation[] userOps;\\n // aggregator address\\n IAggregator aggregator;\\n // aggregated signature\\n bytes signature;\\n }\\n\\n /**\\n * Execute a batch of UserOperation.\\n * no signature aggregator is used.\\n * if any account requires an aggregator (that is, it returned an aggregator when\\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\\n * @param ops the operations to execute\\n * @param beneficiary the address to receive the fees\\n */\\n function handleOps(\\n UserOperation[] calldata ops,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * Execute a batch of UserOperation with Aggregators\\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\\n * @param beneficiary the address to receive the fees\\n */\\n function handleAggregatedOps(\\n UserOpsPerAggregator[] calldata opsPerAggregator,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * generate a request Id - unique identifier for this request.\\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\\n */\\n function getUserOpHash(\\n UserOperation calldata userOp\\n ) external view returns (bytes32);\\n\\n /**\\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\\n * @param userOp the user operation to validate.\\n */\\n function simulateValidation(UserOperation calldata userOp) external;\\n\\n /**\\n * gas and return values during simulation\\n * @param preOpGas the gas used for validation (including preValidationGas)\\n * @param prefund the required prefund for this operation\\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\\n */\\n struct ReturnInfo {\\n uint256 preOpGas;\\n uint256 prefund;\\n bool sigFailed;\\n uint48 validAfter;\\n uint48 validUntil;\\n bytes paymasterContext;\\n }\\n\\n /**\\n * returned aggregated signature info.\\n * the aggregator returned by the account, and its current stake.\\n */\\n struct AggregatorStakeInfo {\\n address aggregator;\\n StakeInfo stakeInfo;\\n }\\n\\n /**\\n * Get counterfactual sender address.\\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\\n * this method always revert, and returns the address in SenderAddressResult error\\n * @param initCode the constructor code to be passed into the UserOperation.\\n */\\n function getSenderAddress(bytes memory initCode) external;\\n\\n /**\\n * simulate full execution of a UserOperation (including both validation and target execution)\\n * this method will always revert with \\\"ExecutionResult\\\".\\n * it performs full validation of the UserOperation, but ignores signature error.\\n * an optional target address is called after the userop succeeds, and its value is returned\\n * (before the entire call is reverted)\\n * Note that in order to collect the the success/failure of the target call, it must be executed\\n * with trace enabled to track the emitted events.\\n * @param op the UserOperation to simulate\\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\\n * are set to the return from that call.\\n * @param targetCallData callData to pass to target address\\n */\\n function simulateHandleOp(\\n UserOperation calldata op,\\n address target,\\n bytes calldata targetCallData\\n ) external;\\n}\\n\",\"keccak256\":\"0x9ccb1b188eda8bbf5f6c2d01bd83c3d8b2b04fcf745283051d31fe96d1d8e40f\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/INonceManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\ninterface INonceManager {\\n /**\\n * Return the next nonce for this sender.\\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\\n * But UserOp with different keys can come with arbitrary order.\\n *\\n * @param sender the account address\\n * @param key the high 192 bit of the nonce\\n * @return nonce a full nonce to pass for next UserOp with this sender.\\n */\\n function getNonce(\\n address sender,\\n uint192 key\\n ) external view returns (uint256 nonce);\\n\\n /**\\n * Manually increment the nonce of the sender.\\n * This method is exposed just for completeness..\\n * Account does NOT need to call it, neither during validation, nor elsewhere,\\n * as the EntryPoint will update the nonce regardless.\\n * Possible use-case is call it with various keys to \\\"initialize\\\" their nonces to one, so that future\\n * UserOperations will not pay extra for the first transaction with a given key.\\n */\\n function incrementNonce(uint192 key) external;\\n}\\n\",\"keccak256\":\"0xce478ad0fa0d18a3b785ac854623029e7ab463d05873dfaa365abfa1bf100912\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IStakeManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8.12;\\n\\n/**\\n * manage deposits and stakes.\\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\\n * stake is value locked for at least \\\"unstakeDelay\\\" by the staked entity.\\n */\\ninterface IStakeManager {\\n event Deposited(address indexed account, uint256 totalDeposit);\\n\\n event Withdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /// Emitted when stake or unstake delay are modified\\n event StakeLocked(\\n address indexed account,\\n uint256 totalStaked,\\n uint256 unstakeDelaySec\\n );\\n\\n /// Emitted once a stake is scheduled for withdrawal\\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\\n\\n event StakeWithdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /**\\n * @param deposit the entity's deposit\\n * @param staked true if this entity is staked.\\n * @param stake actual amount of ether staked for this entity.\\n * @param unstakeDelaySec minimum delay to withdraw the stake.\\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\\n * and the rest fit into a 2nd cell.\\n * 112 bit allows for 10^15 eth\\n * 48 bit for full timestamp\\n * 32 bit allows 150 years for unstake delay\\n */\\n struct DepositInfo {\\n uint112 deposit;\\n bool staked;\\n uint112 stake;\\n uint32 unstakeDelaySec;\\n uint48 withdrawTime;\\n }\\n\\n //API struct used by getStakeInfo and simulateValidation\\n struct StakeInfo {\\n uint256 stake;\\n uint256 unstakeDelaySec;\\n }\\n\\n /// @return info - full deposit information of given account\\n function getDepositInfo(\\n address account\\n ) external view returns (DepositInfo memory info);\\n\\n /// @return the deposit (for gas payment) of the account\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * add to the deposit of the given account\\n */\\n function depositTo(address account) external payable;\\n\\n /**\\n * add to the account's stake - amount and delay\\n * any pending unstake is first cancelled.\\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\\n */\\n function addStake(uint32 _unstakeDelaySec) external payable;\\n\\n /**\\n * attempt to unlock the stake.\\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\\n */\\n function unlockStake() external;\\n\\n /**\\n * withdraw from the (unlocked) stake.\\n * must first call unlockStake and wait for the unstakeDelay to pass\\n * @param withdrawAddress the address to send withdrawn value.\\n */\\n function withdrawStake(address payable withdrawAddress) external;\\n\\n /**\\n * withdraw from the deposit.\\n * @param withdrawAddress the address to send withdrawn value.\\n * @param withdrawAmount the amount to withdraw.\\n */\\n function withdrawTo(\\n address payable withdrawAddress,\\n uint256 withdrawAmount\\n ) external;\\n}\\n\",\"keccak256\":\"0xadcea606c9b7aafe6645441f2154a60f271330b0eee5292a632aa71c1672d546\",\"license\":\"GPL-3.0-only\"},\"contracts/aa-4337/interfaces/UserOperation.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable no-inline-assembly */\\n\\nimport {calldataKeccak} from \\\"../core/Helpers.sol\\\";\\n\\n/**\\n * User Operation struct\\n * @param sender the sender account of this request.\\n * @param nonce unique value the sender uses to verify it is not a replay.\\n * @param initCode if set, the account contract will be created by this constructor/\\n * @param callData the method call to execute on this account.\\n * @param callGasLimit the gas limit passed to the callData method call.\\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\\n * @param maxFeePerGas same as EIP-1559 gas parameter.\\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\\n */\\nstruct UserOperation {\\n address sender;\\n uint256 nonce;\\n bytes initCode;\\n bytes callData;\\n uint256 callGasLimit;\\n uint256 verificationGasLimit;\\n uint256 preVerificationGas;\\n uint256 maxFeePerGas;\\n uint256 maxPriorityFeePerGas;\\n bytes paymasterAndData;\\n bytes signature;\\n}\\n\\n/**\\n * Utility functions helpful when working with UserOperation structs.\\n */\\nlibrary UserOperationLib {\\n function getSender(\\n UserOperation calldata userOp\\n ) internal pure returns (address) {\\n address data;\\n //read sender from userOp, which is first userOp member (saves 800 gas...)\\n assembly {\\n data := calldataload(userOp)\\n }\\n return address(uint160(data));\\n }\\n\\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\\n // pay above what he signed for.\\n function gasPrice(\\n UserOperation calldata userOp\\n ) internal view returns (uint256) {\\n unchecked {\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n if (maxFeePerGas == maxPriorityFeePerGas) {\\n //legacy mode (for networks that don't support basefee opcode)\\n return maxFeePerGas;\\n }\\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\\n }\\n }\\n\\n function pack(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes memory ret) {\\n address sender = getSender(userOp);\\n uint256 nonce = userOp.nonce;\\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\\n bytes32 hashCallData = calldataKeccak(userOp.callData);\\n uint256 callGasLimit = userOp.callGasLimit;\\n uint256 verificationGasLimit = userOp.verificationGasLimit;\\n uint256 preVerificationGas = userOp.preVerificationGas;\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\\n\\n return\\n abi.encode(\\n sender,\\n nonce,\\n hashInitCode,\\n hashCallData,\\n callGasLimit,\\n verificationGasLimit,\\n preVerificationGas,\\n maxFeePerGas,\\n maxPriorityFeePerGas,\\n hashPaymasterAndData\\n );\\n }\\n\\n function hash(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes32) {\\n return keccak256(pack(userOp));\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n}\\n\",\"keccak256\":\"0x2429f5cc546bdee08c7e63858d0dda8491eaa3ab5194df884dc948c1154d2834\",\"license\":\"GPL-3.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IStorageLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"./IDiamondLoupe.sol\\\";\\n\\n/**\\n * @title LoupeFromStorage Interface\\n * @dev Interface contract to function as a loupe facet directly attached to diamond storage of Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IStorageLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facetsFromStorage()\\n external\\n view\\n returns (IDiamondLoupe.Facet[] memory);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n function facetFunctionSelectorsFromStorage(\\n address _facet\\n ) external view returns (bytes4[] memory);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n function facetAddressesFromStorage()\\n external\\n view\\n returns (address[] memory);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n function facetAddressFromStorage(\\n bytes4 _functionSelector\\n ) external view returns (address);\\n}\\n\",\"keccak256\":\"0xdf5dc9c57319e9087628c9cf9404b4f75585b76d1c2f4f59ee796c933967ea5c\",\"license\":\"Apache-2.0\"},\"contracts/facets/interfaces/IAccountFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IEntryPoint} from \\\"../../aa-4337/interfaces/IEntryPoint.sol\\\";\\n\\n/**\\n * @title Account Facet Interface\\n * @dev Interface of module contract that provides the account features and init/unitialization of signer\\n * compatible with EIP-1271 & EIP-4337\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IAccountFacet {\\n event AccountInitialized(\\n IEntryPoint indexed entryPoint,\\n bytes indexed ownerPublicKey\\n );\\n // NOTE: Added Below Event\\n event VerificationSuccess(bytes32);\\n event VerificationFailure(bytes32);\\n\\n error AccountFacet__InitializationFailure();\\n error AccountFacet__RestrictionsFailure();\\n error AccountFacet__NonExistentVerificationFacet();\\n error AccountFacet__CallNotSuccessful();\\n error AccountFacet__InvalidArrayLength();\\n\\n function initialize(\\n address verificationFacet,\\n address anEntryPoint,\\n address facetRegistry,\\n address _defaultFallBack,\\n bytes calldata _ownerPublicKey\\n ) external returns (uint256);\\n\\n function execute(address dest, uint256 value, bytes calldata func) external;\\n\\n function executeBatch(\\n address[] calldata dest,\\n uint256[] calldata value,\\n bytes[] calldata func\\n ) external;\\n}\\n\",\"keccak256\":\"0x74a9cb0b8f2f4a5148e366a401a0354426c536c012c025025d07cc25a4cd5382\",\"license\":\"Apache-2.0\"},\"contracts/infrastructure/DefaultFallbackHandler.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IERC721Receiver} from \\\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\\\";\\nimport {IERC1155Receiver} from \\\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\\\";\\nimport {IERC777Recipient} from \\\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\\\";\\nimport {BaseAccount} from \\\"../aa-4337/core/BaseAccount.sol\\\";\\nimport {DefaultLibDiamond} from \\\"../libraries/DefaultLibDiamond.sol\\\";\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IAccountFacet} from \\\"../facets/interfaces/IAccountFacet.sol\\\";\\nimport {IStorageLoupe} from \\\"../facets/base/interfaces/IStorageLoupe.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\nimport {IERC677Receiver} from \\\"../interfaces/ERC/IERC677Receiver.sol\\\";\\nimport {IERC165} from \\\"../interfaces/ERC/IERC165.sol\\\";\\n\\n/**\\n * @title DefaultFallbackHandler\\n * @dev A default fallback handler for Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract DefaultFallbackHandler is IDiamondLoupe {\\n /**\\n * @notice Sets the middleware diamond for Barz wallet as a fallback handler\\n * @dev This contract is also a diamond that holds the default facets to reduce gas cost for wallet activation.\\n * Within the constructor this conducts diamond cut to initially setup the diamond. This is a non-upgradeable contract\\n * @param _diamondCutFacet Address if diamond cut facet\\n * @param _accountFacet Address account facet\\n * @param _tokenReceiverFacet Address of token receiver facet\\n * @param _diamondLoupeFacet Address of diamond loupe facet\\n */\\n constructor(\\n address _diamondCutFacet,\\n address _accountFacet,\\n address _tokenReceiverFacet,\\n address _diamondLoupeFacet\\n ) payable {\\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](4);\\n bytes4[] memory functionSelectors = new bytes4[](1);\\n functionSelectors[0] = IDiamondCut.diamondCut.selector;\\n\\n bytes4[] memory accountFunctionSelectors = new bytes4[](5);\\n accountFunctionSelectors[0] = IAccountFacet.execute.selector;\\n accountFunctionSelectors[1] = IAccountFacet.executeBatch.selector;\\n accountFunctionSelectors[2] = BaseAccount.validateUserOp.selector;\\n accountFunctionSelectors[3] = BaseAccount.getNonce.selector;\\n accountFunctionSelectors[4] = BaseAccount.entryPoint.selector;\\n\\n bytes4[] memory receiverFacetSelectors = new bytes4[](5);\\n receiverFacetSelectors[0] = IERC721Receiver.onERC721Received.selector;\\n receiverFacetSelectors[1] = IERC1155Receiver.onERC1155Received.selector;\\n receiverFacetSelectors[2] = IERC1155Receiver\\n .onERC1155BatchReceived\\n .selector;\\n receiverFacetSelectors[3] = IERC777Recipient.tokensReceived.selector;\\n receiverFacetSelectors[4] = IERC677Receiver.onTokenTransfer.selector;\\n\\n bytes4[] memory loupeFacetSelectors = new bytes4[](9);\\n loupeFacetSelectors[0] = IDiamondLoupe.facets.selector;\\n loupeFacetSelectors[1] = IDiamondLoupe.facetFunctionSelectors.selector;\\n loupeFacetSelectors[2] = IDiamondLoupe.facetAddresses.selector;\\n loupeFacetSelectors[3] = IDiamondLoupe.facetAddress.selector;\\n loupeFacetSelectors[4] = IERC165.supportsInterface.selector;\\n loupeFacetSelectors[5] = IStorageLoupe.facetsFromStorage.selector;\\n loupeFacetSelectors[6] = IStorageLoupe\\n .facetFunctionSelectorsFromStorage\\n .selector;\\n loupeFacetSelectors[7] = IStorageLoupe\\n .facetAddressesFromStorage\\n .selector;\\n loupeFacetSelectors[8] = IStorageLoupe.facetAddressFromStorage.selector;\\n\\n {\\n cut[0] = IDiamondCut.FacetCut({\\n facetAddress: _diamondCutFacet,\\n action: IDiamondCut.FacetCutAction.Add,\\n functionSelectors: functionSelectors\\n });\\n cut[1] = IDiamondCut.FacetCut({\\n facetAddress: _accountFacet,\\n action: IDiamondCut.FacetCutAction.Add,\\n functionSelectors: accountFunctionSelectors\\n });\\n cut[2] = IDiamondCut.FacetCut({\\n facetAddress: _tokenReceiverFacet,\\n action: IDiamondCut.FacetCutAction.Add,\\n functionSelectors: receiverFacetSelectors\\n });\\n cut[3] = IDiamondCut.FacetCut({\\n facetAddress: _diamondLoupeFacet,\\n action: IDiamondCut.FacetCutAction.Add,\\n functionSelectors: loupeFacetSelectors\\n });\\n\\n DefaultLibDiamond.diamondCut(cut, address(0), \\\"\\\");\\n }\\n }\\n\\n /**\\n * @notice Returns the facet information of call facets registered to this diamond.\\n * @return facets_ The facet struct array including all facet information\\n */\\n function facets() external view override returns (Facet[] memory facets_) {\\n DefaultLibDiamond.DiamondStorage storage ds = DefaultLibDiamond\\n .diamondStorage();\\n uint256 numFacets = ds.facetAddresses.length;\\n facets_ = new Facet[](numFacets);\\n for (uint256 i; i < numFacets; ) {\\n address facetAddress_ = ds.facetAddresses[i];\\n facets_[i].facetAddress = facetAddress_;\\n facets_[i].functionSelectors = ds\\n .facetFunctionSelectors[facetAddress_]\\n .functionSelectors;\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * @notice Gets all the function selectors provided by a facet.\\n * @param _facet The facet address.\\n * @return facetFunctionSelectors_\\n */\\n function facetFunctionSelectors(\\n address _facet\\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\\n facetFunctionSelectors_ = DefaultLibDiamond\\n .diamondStorage()\\n .facetFunctionSelectors[_facet]\\n .functionSelectors;\\n }\\n\\n /**\\n * @notice Get all the facet addresses used by a diamond.\\n * @return facetAddresses_\\n */\\n function facetAddresses()\\n external\\n view\\n override\\n returns (address[] memory facetAddresses_)\\n {\\n facetAddresses_ = DefaultLibDiamond.diamondStorage().facetAddresses;\\n }\\n\\n /** @notice Gets the facet that supports the given selector.\\n * @dev If facet is not found return address(0).\\n * @param _functionSelector The function selector.\\n * @return facetAddress_ The facet address.\\n */\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view override returns (address facetAddress_) {\\n facetAddress_ = DefaultLibDiamond\\n .diamondStorage()\\n .selectorToFacetAndPosition[_functionSelector]\\n .facetAddress;\\n }\\n}\\n\",\"keccak256\":\"0xa482fe778481e34e9fb3c4074231f8048437e934c0ca9a0c78e8e61d3a24470a\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.21;\\n\\ninterface IERC165 {\\n /// @notice Query if a contract implements an interface\\n /// @param interfaceId The interface identifier, as specified in ERC-165\\n /// @dev Interface identification is specified in ERC-165. This function\\n /// uses less than 30,000 gas.\\n /// @return `true` if the contract implements `interfaceID` and\\n /// `interfaceID` is not 0xffffffff, `false` otherwise\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xbb7f07e170898793c5535cc4b7e8944c4b990a631ac806d0b788e794abc788a3\",\"license\":\"MIT\"},\"contracts/interfaces/ERC/IERC677Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC677Receiver {\\n function onTokenTransfer(\\n address sender,\\n uint value,\\n bytes calldata data\\n ) external pure returns (bool);\\n}\\n\",\"keccak256\":\"0x4c1631cf45ea6daac0ec158c3edb9453099130b6b64f697004b83f95aa1f7350\",\"license\":\"Apache-2.0\"},\"contracts/libraries/DefaultLibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary DefaultLibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (\\n uint256 facetIndex;\\n facetIndex < _diamondCut.length;\\n facetIndex++\\n ) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(\\n address _facetAddress,\\n bytes4[] memory _functionSelectors\\n ) internal {\\n uint256 funcSelectorsLength = _functionSelectors.length;\\n require(\\n funcSelectorsLength > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _facetAddress != address(0),\\n \\\"LibDiamondCut: Add facet can't be address(0)\\\"\\n );\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (\\n uint256 selectorIndex;\\n selectorIndex < funcSelectorsLength;\\n selectorIndex++\\n ) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds\\n .selectorToFacetAndPosition[selector]\\n .facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(\\n address _facetAddress,\\n bytes4[] memory _functionSelectors\\n ) internal {\\n uint256 funcSelectorsLength = _functionSelectors.length;\\n require(\\n funcSelectorsLength > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _facetAddress != address(0),\\n \\\"LibDiamondCut: Replace facet can't be address(0)\\\"\\n );\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (\\n uint256 selectorIndex;\\n selectorIndex < funcSelectorsLength;\\n selectorIndex++\\n ) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds\\n .selectorToFacetAndPosition[selector]\\n .facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same facet\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(\\n address _facetAddress,\\n bytes4[] memory _functionSelectors\\n ) internal {\\n uint256 funcSelectorsLength = _functionSelectors.length;\\n require(\\n funcSelectorsLength > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(\\n _facetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n for (\\n uint256 selectorIndex;\\n selectorIndex < funcSelectorsLength;\\n selectorIndex++\\n ) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds\\n .selectorToFacetAndPosition[selector]\\n .facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(\\n DiamondStorage storage ds,\\n address _facetAddress\\n ) internal {\\n enforceHasContractCode(\\n _facetAddress,\\n \\\"LibDiamondCut: New facet has no code\\\"\\n );\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds\\n .facetAddresses\\n .length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds\\n .selectorToFacetAndPosition[_selector]\\n .functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(\\n _selector\\n );\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(\\n _facetAddress != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // an immutable function is a function defined directly in a diamond\\n require(\\n _facetAddress != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds\\n .selectorToFacetAndPosition[_selector]\\n .functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors[lastSelectorPosition];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n selectorPosition\\n ] = lastSelector;\\n ds\\n .selectorToFacetAndPosition[lastSelector]\\n .functionSelectorPosition = uint96(selectorPosition);\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[\\n lastFacetAddressPosition\\n ];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds\\n .facetFunctionSelectors[lastFacetAddress]\\n .facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds\\n .facetFunctionSelectors[_facetAddress]\\n .facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x1b08f332d62919288bb1f0d154ca4b85f4e167d2a06e680f8ec93dba65be3be1\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x6080604052604051620020183803806200201883398101604081905262000026916200156b565b60408051600480825260a08201909252600091816020015b604080516060808201835260008083526020830152918101919091528152602001906001900390816200003e5750506040805160018082528183019092529192506000919060208083019080368337019050509050631f931c1c60e01b81600081518110620000b157620000b1620015c8565b6001600160e01b03199290921660209283029190910182015260408051600580825260c08201909252600092909190820160a08036833701905050905063b61d27f660e01b816000815181106200010c576200010c620015c8565b6001600160e01b03199092166020928302919091019091015280516323f0ed1560e11b9082906001908110620001465762000146620015c8565b6001600160e01b0319909216602092830291909101909101528051633a871cdd60e01b9082906002908110620001805762000180620015c8565b6001600160e01b0319909216602092830291909101909101528051631a10fa5160e31b9082906003908110620001ba57620001ba620015c8565b6001600160e01b031990921660209283029190910190910152805163586b48ff60e11b9082906004908110620001f457620001f4620015c8565b6001600160e01b03199290921660209283029190910182015260408051600580825260c08201909252600092909190820160a08036833701905050905063150b7a0260e01b816000815181106200024f576200024f620015c8565b6001600160e01b031990921660209283029190910190910152805163f23a6e6160e01b9082906001908110620002895762000289620015c8565b6001600160e01b031990921660209283029190910190910152805163bc197c8160e01b9082906002908110620002c357620002c3620015c8565b6001600160e01b03199092166020928302919091019091015280516223de2960e01b9082906003908110620002fc57620002fc620015c8565b6001600160e01b0319909216602092830291909101909101528051635260769b60e11b9082906004908110620003365762000336620015c8565b6001600160e01b0319929092166020928302919091018201526040805160098082526101408201909252600092909190820161012080368337019050509050637a0ed62760e01b81600081518110620003935762000393620015c8565b6001600160e01b03199092166020928302919091019091015280516356fe50af60e11b9082906001908110620003cd57620003cd620015c8565b6001600160e01b03199092166020928302919091019091015280516314bbdacb60e21b9082906002908110620004075762000407620015c8565b6001600160e01b03199092166020928302919091019091015280516366ffd66360e11b9082906003908110620004415762000441620015c8565b6001600160e01b03199092166020928302919091019091015280516301ffc9a760e01b90829060049081106200047b576200047b620015c8565b6001600160e01b031990921660209283029190910190910152805163f9796ccf60e01b9082906005908110620004b557620004b5620015c8565b6001600160e01b031990921660209283029190910190910152805162d2a81160e11b9082906006908110620004ee57620004ee620015c8565b6001600160e01b031990921660209283029190910190910152805163d42139a960e01b9082906007908110620005285762000528620015c8565b6001600160e01b03199092166020928302919091019091015280516371d17b7f60e11b9082906008908110620005625762000562620015c8565b6001600160e01b031990921660209283029190910182015260408051606081019091526001600160a01b038b168152908101600081526020018581525085600081518110620005b557620005b5620015c8565b60200260200101819052506040518060600160405280896001600160a01b0316815260200160006002811115620005f057620005f0620015de565b815260200184815250856001815181106200060f576200060f620015c8565b60200260200101819052506040518060600160405280886001600160a01b03168152602001600060028111156200064a576200064a620015de565b81526020018381525085600281518110620006695762000669620015c8565b60200260200101819052506040518060600160405280876001600160a01b0316815260200160006002811115620006a457620006a4620015de565b81526020018281525085600381518110620006c357620006c3620015c8565b6020026020010181905250620006f1856000604051806020016040528060008152506200070060201b60201c565b5050505050505050506200184c565b60005b83518110156200090c576000848281518110620007245762000724620015c8565b602002602001015160200151905060006002811115620007485762000748620015de565b8160028111156200075d576200075d620015de565b03620007bb57620007b58583815181106200077c576200077c620015c8565b6020026020010151600001518684815181106200079d576200079d620015c8565b6020026020010151604001516200095b60201b60201c565b620008f6565b6001816002811115620007d257620007d2620015de565b036200082a57620007b5858381518110620007f157620007f1620015c8565b602002602001015160000151868481518110620008125762000812620015c8565b60200260200101516040015162000bf760201b60201c565b6002816002811115620008415762000841620015de565b036200089957620007b5858381518110620008605762000860620015c8565b602002602001015160000151868481518110620008815762000881620015c8565b60200260200101516040015162000ea160201b60201c565b60405162461bcd60e51b815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f727265637420466163657443756044820152663a20b1ba34b7b760c91b60648201526084015b60405180910390fd5b508062000903816200160a565b91505062000703565b507f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb67383838360405162000942939291906200167a565b60405180910390a162000956828262001005565b505050565b805180620009af5760405162461bcd60e51b815260206004820152602b602482015260008051602062001ff883398151915260448201526a1858d95d081d1bc818dd5d60aa1b6064820152608401620008ed565b60008051602062001f8c8339815191526001600160a01b03841662000a2c5760405162461bcd60e51b815260206004820152602c60248201527f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260448201526b65206164647265737328302960a01b6064820152608401620008ed565b6001600160a01b0384166000908152600182016020526040812054906001600160601b038216900362000a655762000a658286620010dd565b60005b8381101562000bef57600085828151811062000a885762000a88620015c8565b6020908102919091018101516001600160e01b031981166000908152918690526040909120549091506001600160a01b0316801562000b305760405162461bcd60e51b815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c72656164792065786973747300000000000000000000006064820152608401620008ed565b6001600160e01b0319821660008181526020878152604080832080546001600160a01b03908116600160a01b6001600160601b038c16021782558d168085526001808c0185529285208054938401815585528385206008840401805463ffffffff60079095166004026101000a948502191660e08a901c94909402939093179092559390925287905281546001600160a01b0319161790558362000bd48162001781565b9450505050808062000be6906200160a565b91505062000a68565b505050505050565b80518062000c4b5760405162461bcd60e51b815260206004820152602b602482015260008051602062001ff883398151915260448201526a1858d95d081d1bc818dd5d60aa1b6064820152608401620008ed565b60008051602062001f8c8339815191526001600160a01b03841662000ccc5760405162461bcd60e51b815260206004820152603060248201527f4c69624469616d6f6e644375743a205265706c6163652066616365742063616e60448201526f2774206265206164647265737328302960801b6064820152608401620008ed565b6001600160a01b0384166000908152600182016020526040812054906001600160601b038216900362000d055762000d058286620010dd565b60005b8381101562000bef57600085828151811062000d285762000d28620015c8565b6020908102919091018101516001600160e01b031981166000908152918690526040909120549091506001600160a01b03908116908816810362000dd55760405162461bcd60e51b815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d6520666163657400000000000000000000006064820152608401620008ed565b62000de28582846200114a565b6001600160e01b0319821660008181526020878152604080832080546001600160a01b03908116600160a01b6001600160601b038c16021782558d168085526001808c0185529285208054938401815585528385206008840401805463ffffffff60079095166004026101000a948502191660e08a901c94909402939093179092559390925287905281546001600160a01b0319161790558362000e868162001781565b9450505050808062000e98906200160a565b91505062000d08565b80518062000ef55760405162461bcd60e51b815260206004820152602b602482015260008051602062001ff883398151915260448201526a1858d95d081d1bc818dd5d60aa1b6064820152608401620008ed565b60008051602062001f8c8339815191526001600160a01b0384161562000f845760405162461bcd60e51b815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d7573742062652061646472657373283029000000000000000000006064820152608401620008ed565b60005b8281101562000ffe57600084828151811062000fa75762000fa7620015c8565b6020908102919091018101516001600160e01b031981166000908152918590526040909120549091506001600160a01b031662000fe68482846200114a565b5050808062000ff5906200160a565b91505062000f87565b5050505050565b6001600160a01b03821662001018575050565b6200103d8260405180606001604052806028815260200162001fac602891396200152a565b600080836001600160a01b0316836040516200105a9190620017b2565b600060405180830381855af49150503d806000811462001097576040519150601f19603f3d011682016040523d82523d6000602084013e6200109c565b606091505b509150915081620010d757805115620010b85780518082602001fd5b838360405163192105d760e01b8152600401620008ed929190620017d0565b50505050565b620011028160405180606001604052806024815260200162001fd4602491396200152a565b6002820180546001600160a01b0390921660008181526001948501602090815260408220860185905594840183559182529290200180546001600160a01b0319169091179055565b6001600160a01b038216620011c85760405162461bcd60e51b815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608401620008ed565b306001600160a01b03831603620012395760405162461bcd60e51b815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201526d3a30b1363290333ab731ba34b7b760911b6064820152608401620008ed565b6001600160e01b03198116600090815260208481526040808320546001600160a01b0386168452600180880190935290832054600160a01b9091046001600160601b031692916200128a91620017fe565b905080821462001383576001600160a01b03841660009081526001860160205260408120805483908110620012c357620012c3620015c8565b600091825260208083206008830401546001600160a01b038916845260018a019091526040909220805460079092166004026101000a90920460e01b925082919085908110620013175762001317620015c8565b600091825260208083206008830401805463ffffffff60079094166004026101000a938402191660e09590951c929092029390931790556001600160e01b03199290921682528690526040902080546001600160a01b0316600160a01b6001600160601b038516021790555b6001600160a01b03841660009081526001860160205260409020805480620013af57620013af6200181a565b60008281526020808220600860001990940193840401805463ffffffff600460078716026101000a0219169055919092556001600160e01b0319851682528690526040812081905581900362000ffe5760028501546000906200141590600190620017fe565b6001600160a01b0386166000908152600180890160205260409091200154909150808214620014cb576000876002018381548110620014585762001458620015c8565b6000918252602090912001546002890180546001600160a01b0390921692508291849081106200148c576200148c620015c8565b600091825260208083209190910180546001600160a01b0319166001600160a01b03948516179055929091168152600189810190925260409020018190555b86600201805480620014e157620014e16200181a565b60008281526020808220830160001990810180546001600160a01b03191690559092019092556001600160a01b0388168252600189810190915260408220015550505050505050565b813b8181620010d75760405162461bcd60e51b8152600401620008ed919062001830565b80516001600160a01b03811681146200156657600080fd5b919050565b600080600080608085870312156200158257600080fd5b6200158d856200154e565b93506200159d602086016200154e565b9250620015ad604086016200154e565b9150620015bd606086016200154e565b905092959194509250565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016200161f576200161f620015f4565b5060010190565b60005b838110156200164357818101518382015260200162001629565b50506000910152565b600081518084526200166681602086016020860162001626565b601f01601f19169290920160200192915050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b848110156200174f57898403607f19018652815180516001600160a01b03168552838101518986019060038110620016eb57634e487b7160e01b600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b80831015620017395783516001600160e01b03191682529286019260019290920191908601906200170d565b50978501979550505090820190600101620016a3565b50506001600160a01b038a169088015286810360408801526200177381896200164c565b9a9950505050505050505050565b60006001600160601b038281166002600160601b03198101620017a857620017a8620015f4565b6001019392505050565b60008251620017c681846020870162001626565b9190910192915050565b6001600160a01b0383168152604060208201819052600090620017f6908301846200164c565b949350505050565b81810381811115620018145762001814620015f4565b92915050565b634e487b7160e01b600052603160045260246000fd5b6020815260006200184560208301846200164c565b9392505050565b610730806200185c6000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806352ef6b2c146100515780637a0ed6271461006f578063adfca15e14610084578063cdffacc6146100a4575b600080fd5b610059610140565b60405161006691906104ab565b60405180910390f35b6100776101d1565b6040516100669190610562565b61009761009236600461060a565b6103d1565b6040516100669190610647565b61011b6100b236600461065a565b7fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610066565b60607f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6002018054806020026020016040519081016040528092919081815260200182805480156101c757602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161019c575b5050505050905090565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f908067ffffffffffffffff8111156102315761023161069c565b60405190808252806020026020018201604052801561027757816020015b60408051808201909152600081526060602082015281526020019060019003908161024f5790505b50925060005b818110156103cb57600083600201828154811061029c5761029c6106cb565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050808583815181106102dc576102dc6106cb565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff928316905290821660009081526001860182526040908190208054825181850281018501909352808352919290919083018282801561039d57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161034a5790505b50505050508583815181106103b4576103b46106cb565b60209081029190910181015101525060010161027d565b50505090565b73ffffffffffffffffffffffffffffffffffffffff811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4920602090815260409182902080548351818402810184019094528084526060939283018282801561049f57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161044c5790505b50505050509050919050565b6020808252825182820181905260009190848201906040850190845b818110156104f957835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016104c7565b50909695505050505050565b600081518084526020808501945080840160005b838110156105575781517fffffffff000000000000000000000000000000000000000000000000000000001687529582019590820190600101610519565b509495945050505050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b838110156105fc578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00185528151805173ffffffffffffffffffffffffffffffffffffffff1684528701518784018790526105e987850182610505565b9588019593505090860190600101610589565b509098975050505050505050565b60006020828403121561061c57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461064057600080fd5b9392505050565b6020815260006106406020830184610505565b60006020828403121561066c57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461064057600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea264697066735822122024a872696a5ad50024326567061c50adea63ff0d49edf0ac60339459d33d571664736f6c63430008150033183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f4c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a204e657720666163657420686173206e6f20636f64654c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e2066", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806352ef6b2c146100515780637a0ed6271461006f578063adfca15e14610084578063cdffacc6146100a4575b600080fd5b610059610140565b60405161006691906104ab565b60405180910390f35b6100776101d1565b6040516100669190610562565b61009761009236600461060a565b6103d1565b6040516100669190610647565b61011b6100b236600461065a565b7fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610066565b60607f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6002018054806020026020016040519081016040528092919081815260200182805480156101c757602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161019c575b5050505050905090565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f908067ffffffffffffffff8111156102315761023161069c565b60405190808252806020026020018201604052801561027757816020015b60408051808201909152600081526060602082015281526020019060019003908161024f5790505b50925060005b818110156103cb57600083600201828154811061029c5761029c6106cb565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050808583815181106102dc576102dc6106cb565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff928316905290821660009081526001860182526040908190208054825181850281018501909352808352919290919083018282801561039d57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161034a5790505b50505050508583815181106103b4576103b46106cb565b60209081029190910181015101525060010161027d565b50505090565b73ffffffffffffffffffffffffffffffffffffffff811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4920602090815260409182902080548351818402810184019094528084526060939283018282801561049f57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161044c5790505b50505050509050919050565b6020808252825182820181905260009190848201906040850190845b818110156104f957835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016104c7565b50909695505050505050565b600081518084526020808501945080840160005b838110156105575781517fffffffff000000000000000000000000000000000000000000000000000000001687529582019590820190600101610519565b509495945050505050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b838110156105fc578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00185528151805173ffffffffffffffffffffffffffffffffffffffff1684528701518784018790526105e987850182610505565b9588019593505090860190600101610589565b509098975050505050505050565b60006020828403121561061c57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461064057600080fd5b9392505050565b6020815260006106406020830184610505565b60006020828403121561066c57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461064057600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea264697066735822122024a872696a5ad50024326567061c50adea63ff0d49edf0ac60339459d33d571664736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "A default fallback handler for Barz", + "kind": "dev", + "methods": { + "constructor": { + "details": "This contract is also a diamond that holds the default facets to reduce gas cost for wallet activation. Within the constructor this conducts diamond cut to initially setup the diamond. This is a non-upgradeable contract", + "params": { + "_accountFacet": "Address account facet", + "_diamondCutFacet": "Address if diamond cut facet", + "_diamondLoupeFacet": "Address of diamond loupe facet", + "_tokenReceiverFacet": "Address of token receiver facet" + } + }, + "facetAddress(bytes4)": { + "details": "If facet is not found return address(0).", + "params": { + "_functionSelector": "The function selector." + }, + "returns": { + "facetAddress_": "The facet address." + } + }, + "facetAddresses()": { + "returns": { + "facetAddresses_": "facetAddresses_" + } + }, + "facetFunctionSelectors(address)": { + "params": { + "_facet": "The facet address." + }, + "returns": { + "facetFunctionSelectors_": "facetFunctionSelectors_" + } + }, + "facets()": { + "returns": { + "facets_": "The facet struct array including all facet information" + } + } + }, + "title": "DefaultFallbackHandler", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "constructor": { + "notice": "Sets the middleware diamond for Barz wallet as a fallback handler" + }, + "facetAddress(bytes4)": { + "notice": "Gets the facet that supports the given selector." + }, + "facetAddresses()": { + "notice": "Get all the facet addresses used by a diamond." + }, + "facetFunctionSelectors(address)": { + "notice": "Gets all the function selectors provided by a facet." + }, + "facets()": { + "notice": "Returns the facet information of call facets registered to this diamond." + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/arbitrum/DiamondCutFacet.json b/deployments/arbitrum/DiamondCutFacet.json new file mode 100644 index 0000000..42320c9 --- /dev/null +++ b/deployments/arbitrum/DiamondCutFacet.json @@ -0,0 +1,856 @@ +{ + "address": "0x0B9504140771C3688Ff041917192277D2f52E1e0", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_securityManager", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "CallerNotGuardian", + "type": "error" + }, + { + "inputs": [], + "name": "CallerNotGuardianOrOwner", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__CannotRevokeUnapproved", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__DuplicateApproval", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InsufficientApprovers", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidApprovalValidationPeriod", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidApprover", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidApproverSignature", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidArrayLength", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidInitAddress", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidRouteWithGuardian", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidRouteWithoutGuardian", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__LackOfOwnerApproval", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__OwnerAlreadyApproved", + "type": "error" + }, + { + "inputs": [], + "name": "DuplicateApprover", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_initializationContractAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "InitializationFunctionReverted", + "type": "error" + }, + { + "inputs": [], + "name": "UnregisteredFacetAndSelectors", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroApproverLength", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "indexed": false, + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "DiamondCut", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "diamondCut", + "type": "tuple[]" + } + ], + "name": "DiamondCutApprovalRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "diamondCut", + "type": "tuple[]" + } + ], + "name": "DiamondCutApproved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + }, + { + "indexed": false, + "internalType": "bool", + "name": "_lag", + "type": "bool" + } + ], + "name": "SupportsInterfaceUpdated", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_diamondCutHash", + "type": "bytes32" + }, + { + "internalType": "address[]", + "name": "_approvers", + "type": "address[]" + } + ], + "name": "_checkDuplicateOnChainApprover", + "outputs": [], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + } + ], + "name": "approveDiamondCut", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "diamondCut", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "internalType": "address[]", + "name": "_approvers", + "type": "address[]" + }, + { + "internalType": "bytes[]", + "name": "_signatures", + "type": "bytes[]" + } + ], + "name": "diamondCutWithGuardian", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_diamondCutHash", + "type": "bytes32" + } + ], + "name": "getDiamondCutApprovalCountWithTimeValidity", + "outputs": [ + { + "internalType": "uint256", + "name": "approvalCount", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + } + ], + "name": "getDiamondCutHash", + "outputs": [ + { + "internalType": "bytes32", + "name": "cutHash", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getDiamondCutNonce", + "outputs": [ + { + "internalType": "uint128", + "name": "cutNonce", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_diamondCutHash", + "type": "bytes32" + } + ], + "name": "getOwnerCutApprovalWithTimeValidity", + "outputs": [ + { + "internalType": "bool", + "name": "isApprovedByOwner", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_diamondCutHash", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "_approver", + "type": "address" + } + ], + "name": "isCutApproved", + "outputs": [ + { + "internalType": "bool", + "name": "isApproved", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + } + ], + "name": "revokeDiamondCutApproval", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "securityManager", + "outputs": [ + { + "internalType": "contract ISecurityManager", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_interfaceId", + "type": "bytes4" + }, + { + "internalType": "bool", + "name": "_flag", + "type": "bool" + } + ], + "name": "updateSupportsInterface", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0xfd748c6c258a06361d930ce50714074b4a080876ef4c4fecc3a3cd0abea79d3b", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 1, + "gasUsed": "21332374", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x22320c8bc2aa37275c3997c1d67fecaa965e7abe2f0f9804c4a83d8ead1d2b0a", + "transactionHash": "0xfd748c6c258a06361d930ce50714074b4a080876ef4c4fecc3a3cd0abea79d3b", + "logs": [], + "blockNumber": 152284098, + "cumulativeGasUsed": "21332374", + "status": 1, + "byzantium": true + }, + "args": [ + "0xcBe266adbfd7CB32988128e7f37b7c8b3C5521A8" + ], + "numDeployments": 3, + "solcInputHash": "4356503edd8ae34e73cb6dd1c8e2fc8a", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_securityManager\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"CallerNotGuardian\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallerNotGuardianOrOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__CannotRevokeUnapproved\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__DuplicateApproval\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InsufficientApprovers\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidApprovalValidationPeriod\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidApprover\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidApproverSignature\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidArrayLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidInitAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidRouteWithGuardian\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidRouteWithoutGuardian\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__LackOfOwnerApproval\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__OwnerAlreadyApproved\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateApprover\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_initializationContractAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"InitializationFunctionReverted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnregisteredFacetAndSelectors\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroApproverLength\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"DiamondCut\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"diamondCut\",\"type\":\"tuple[]\"}],\"name\":\"DiamondCutApprovalRevoked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"diamondCut\",\"type\":\"tuple[]\"}],\"name\":\"DiamondCutApproved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"_lag\",\"type\":\"bool\"}],\"name\":\"SupportsInterfaceUpdated\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_diamondCutHash\",\"type\":\"bytes32\"},{\"internalType\":\"address[]\",\"name\":\"_approvers\",\"type\":\"address[]\"}],\"name\":\"_checkDuplicateOnChainApprover\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"}],\"name\":\"approveDiamondCut\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"diamondCut\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"internalType\":\"address[]\",\"name\":\"_approvers\",\"type\":\"address[]\"},{\"internalType\":\"bytes[]\",\"name\":\"_signatures\",\"type\":\"bytes[]\"}],\"name\":\"diamondCutWithGuardian\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_diamondCutHash\",\"type\":\"bytes32\"}],\"name\":\"getDiamondCutApprovalCountWithTimeValidity\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"approvalCount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"}],\"name\":\"getDiamondCutHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"cutHash\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDiamondCutNonce\",\"outputs\":[{\"internalType\":\"uint128\",\"name\":\"cutNonce\",\"type\":\"uint128\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_diamondCutHash\",\"type\":\"bytes32\"}],\"name\":\"getOwnerCutApprovalWithTimeValidity\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isApprovedByOwner\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_diamondCutHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"_approver\",\"type\":\"address\"}],\"name\":\"isCutApproved\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isApproved\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"}],\"name\":\"revokeDiamondCutApproval\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"securityManager\",\"outputs\":[{\"internalType\":\"contract ISecurityManager\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_interfaceId\",\"type\":\"bytes4\"},{\"internalType\":\"bool\",\"name\":\"_flag\",\"type\":\"bool\"}],\"name\":\"updateSupportsInterface\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"Responsible for adding/removing/replace facets in Barz\",\"kind\":\"dev\",\"methods\":{\"_checkDuplicateOnChainApprover(bytes32,address[])\":{\"params\":{\"_approvers\":\"List of approver addresses\",\"_diamondCutHash\":\"Hash of diamondCut information including the facet addresses and function selectors\"}},\"approveDiamondCut((address,uint8,bytes4[])[])\":{\"params\":{\"_diamondCut\":\"Contains the facet addresses and function selectors\"}},\"constructor\":{\"params\":{\"_securityManager\":\"Security Manager contract that holds the security related variables for all wallets\"}},\"diamondCut((address,uint8,bytes4[])[],address,bytes)\":{\"params\":{\"_diamondCut\":\"Contains the facet addresses and function selectors\",\"_init\":\"The address of the contract or facet to execute _calldata. It's prohibited in Barz\"}},\"diamondCutWithGuardian((address,uint8,bytes4[])[],address[],bytes[])\":{\"params\":{\"_approvers\":\"Guardian or owner address that approves the diamond cut\",\"_diamondCut\":\"Contains the facet addresses and function selectors\",\"_signatures\":\"Signature of Guardians or owner that approves the diamond cut\"}},\"getDiamondCutApprovalCountWithTimeValidity(bytes32)\":{\"params\":{\"_diamondCutHash\":\"Hash of diamondCut information including the facet addresses and function selectors\"}},\"getDiamondCutHash((address,uint8,bytes4[])[])\":{\"params\":{\"_diamondCut\":\"Contains the facet addresses and function selectors\"},\"returns\":{\"cutHash\":\"Diamond Cut Hash\"}},\"getDiamondCutNonce()\":{\"details\":\"This method fetches the nonce from diamond cut storage\",\"returns\":{\"cutNonce\":\"Nonce of diamond cut to protect from reply attacks\"}},\"getOwnerCutApprovalWithTimeValidity(bytes32)\":{\"params\":{\"_diamondCutHash\":\"Hash of diamondCut information including the facet addresses and function selectors\"},\"returns\":{\"isApprovedByOwner\":\"Bool value showing if the owner approved the cut\"}},\"isCutApproved(bytes32,address)\":{\"params\":{\"_approver\":\"Address of approver\",\"_diamondCutHash\":\"Hash of diamondCut information including the facet addresses and function selectors\"},\"returns\":{\"isApproved\":\"Bool value showing if the approver approved the cut\"}},\"revokeDiamondCutApproval((address,uint8,bytes4[])[])\":{\"params\":{\"_diamondCut\":\"Contains the facet addresses and function selectors\"}},\"updateSupportsInterface(bytes4,bool)\":{\"params\":{\"_flag\":\"Bool value to update the mapping of the given interface ID\",\"_interfaceId\":\"InterfaceID to update the mapping\"}}},\"title\":\"DiamondCut Facet\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"_checkDuplicateOnChainApprover(bytes32,address[])\":{\"notice\":\"Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval Approvers who approved on-chain should not be included in the off-chain approval\"},\"approveDiamondCut((address,uint8,bytes4[])[])\":{\"notice\":\"Approves diamond cut. This can only be called directly from guardian or owner\"},\"constructor\":{\"notice\":\"This constructor sets the Security Manager address which is an immutable variable. Immutable variables do not impact the storage of diamond\"},\"diamondCut((address,uint8,bytes4[])[],address,bytes)\":{\"notice\":\"Add/replace/remove any number of functions and optionally execute a function with delegatecall when guardians don't exist\"},\"diamondCutWithGuardian((address,uint8,bytes4[])[],address[],bytes[])\":{\"notice\":\"Add/replace/remove any number of functions and optionally execute a function with delegatecall when guardians exist\"},\"getDiamondCutApprovalCountWithTimeValidity(bytes32)\":{\"notice\":\"Gets the number of approvals of diamond cut from guardians\"},\"getDiamondCutHash((address,uint8,bytes4[])[])\":{\"notice\":\"Returns the diamond cut hash. This function ensures that this hash is safe from replay attack by including salt, address, chainId, and nonce, etc.\"},\"getDiamondCutNonce()\":{\"notice\":\"Returns the diamond cut nonce of this wallet\"},\"getOwnerCutApprovalWithTimeValidity(bytes32)\":{\"notice\":\"Returns if the owner has approved the diamond cut\"},\"isCutApproved(bytes32,address)\":{\"notice\":\"Returns if the given approver has approved the diamond cut\"},\"revokeDiamondCutApproval((address,uint8,bytes4[])[])\":{\"notice\":\"Revokes the approval of diamond cut. This can only be called directly from guardian or owner\"},\"updateSupportsInterface(bytes4,bool)\":{\"notice\":\"Updates the flag for the interfaceId\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/base/DiamondCutFacet.sol\":\"DiamondCutFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/interfaces/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC1271 standard signature validation method for\\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC1271 {\\n /**\\n * @dev Should return whether the signature provided is valid for the provided data\\n * @param hash Hash of the data to be signed\\n * @param signature Signature byte array associated with _data\\n */\\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\\n}\\n\",\"keccak256\":\"0x0705a4b1b86d7b0bd8432118f226ba139c44b9dcaba0a6eafba2dd7d0639c544\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./math/Math.sol\\\";\\nimport \\\"./math/SignedMath.sol\\\";\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n uint256 length = Math.log10(value) + 1;\\n string memory buffer = new string(length);\\n uint256 ptr;\\n /// @solidity memory-safe-assembly\\n assembly {\\n ptr := add(buffer, add(32, length))\\n }\\n while (true) {\\n ptr--;\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\\n }\\n value /= 10;\\n if (value == 0) break;\\n }\\n return buffer;\\n }\\n }\\n\\n /**\\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\\n */\\n function toString(int256 value) internal pure returns (string memory) {\\n return string(abi.encodePacked(value < 0 ? \\\"-\\\" : \\\"\\\", toString(SignedMath.abs(value))));\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n return toHexString(value, Math.log256(value) + 1);\\n }\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n\\n /**\\n * @dev Returns true if the two strings are equal.\\n */\\n function equal(string memory a, string memory b) internal pure returns (bool) {\\n return keccak256(bytes(a)) == keccak256(bytes(b));\\n }\\n}\\n\",\"keccak256\":\"0x3088eb2868e8d13d89d16670b5f8612c4ab9ff8956272837d8e90106c59c14a0\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Strings.sol\\\";\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSA {\\n enum RecoverError {\\n NoError,\\n InvalidSignature,\\n InvalidSignatureLength,\\n InvalidSignatureS,\\n InvalidSignatureV // Deprecated in v4.8\\n }\\n\\n function _throwError(RecoverError error) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert(\\\"ECDSA: invalid signature\\\");\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert(\\\"ECDSA: invalid signature length\\\");\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert(\\\"ECDSA: invalid signature 's' value\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature` or error string. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n *\\n * Documentation for signature generation:\\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n return tryRecover(hash, v, r, s);\\n } else {\\n return (address(0), RecoverError.InvalidSignatureLength);\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature`. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, signature);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\\n uint8 v = uint8((uint256(vs) >> 255) + 27);\\n return tryRecover(hash, v, r, s);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n *\\n * _Available since v4.2._\\n */\\n function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\\n // the valid range for s in (301): 0 < s < secp256k1n \\u00f7 2 + 1, and for v in (302): v \\u2208 {27, 28}. Most\\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\\n //\\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\\n // these malleable signatures as well.\\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n return (address(0), RecoverError.InvalidSignatureS);\\n }\\n\\n // If the signature is valid (and not malleable), return the signer address\\n address signer = ecrecover(hash, v, r, s);\\n if (signer == address(0)) {\\n return (address(0), RecoverError.InvalidSignature);\\n }\\n\\n return (signer, RecoverError.NoError);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore(0x00, \\\"\\\\x19Ethereum Signed Message:\\\\n32\\\")\\n mstore(0x1c, hash)\\n message := keccak256(0x00, 0x3c)\\n }\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from `s`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n\\\", Strings.toString(s.length), s));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Typed Data, created from a\\n * `domainSeparator` and a `structHash`. This produces hash corresponding\\n * to the one signed with the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n * JSON-RPC method as part of EIP-712.\\n *\\n * See {recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n let ptr := mload(0x40)\\n mstore(ptr, \\\"\\\\x19\\\\x01\\\")\\n mstore(add(ptr, 0x02), domainSeparator)\\n mstore(add(ptr, 0x22), structHash)\\n data := keccak256(ptr, 0x42)\\n }\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Data with intended validator, created from a\\n * `validator` and `data` according to the version 0 of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x00\\\", validator, data));\\n }\\n}\\n\",\"keccak256\":\"0x809bc3edb4bcbef8263fa616c1b60ee0004b50a8a1bfa164d8f57fd31f520c58\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/SignatureChecker.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./ECDSA.sol\\\";\\nimport \\\"../../interfaces/IERC1271.sol\\\";\\n\\n/**\\n * @dev Signature verification helper that can be used instead of `ECDSA.recover` to seamlessly support both ECDSA\\n * signatures from externally owned accounts (EOAs) as well as ERC1271 signatures from smart contract wallets like\\n * Argent and Gnosis Safe.\\n *\\n * _Available since v4.1._\\n */\\nlibrary SignatureChecker {\\n /**\\n * @dev Checks if a signature is valid for a given signer and data hash. If the signer is a smart contract, the\\n * signature is validated against that smart contract using ERC1271, otherwise it's validated using `ECDSA.recover`.\\n *\\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\\n */\\n function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature) internal view returns (bool) {\\n (address recovered, ECDSA.RecoverError error) = ECDSA.tryRecover(hash, signature);\\n return\\n (error == ECDSA.RecoverError.NoError && recovered == signer) ||\\n isValidERC1271SignatureNow(signer, hash, signature);\\n }\\n\\n /**\\n * @dev Checks if a signature is valid for a given signer and data hash. The signature is validated\\n * against the signer smart contract using ERC1271.\\n *\\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\\n */\\n function isValidERC1271SignatureNow(\\n address signer,\\n bytes32 hash,\\n bytes memory signature\\n ) internal view returns (bool) {\\n (bool success, bytes memory result) = signer.staticcall(\\n abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, signature)\\n );\\n return (success &&\\n result.length >= 32 &&\\n abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector));\\n }\\n}\\n\",\"keccak256\":\"0x3af3ca86df39aac39a0514c84459d691434a108d2151c8ce9d69f32e315cab80\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n enum Rounding {\\n Down, // Toward negative infinity\\n Up, // Toward infinity\\n Zero // Toward zero\\n }\\n\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow.\\n return (a & b) + (a ^ b) / 2;\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a == 0 ? 0 : (a - 1) / b + 1;\\n }\\n\\n /**\\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\\n * with further edits by Uniswap Labs also under MIT license.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\\n unchecked {\\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2^256 + prod0.\\n uint256 prod0; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division.\\n if (prod1 == 0) {\\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\\n // The surrounding unchecked block does not change this fact.\\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\\n return prod0 / denominator;\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n require(denominator > prod1, \\\"Math: mulDiv overflow\\\");\\n\\n ///////////////////////////////////////////////\\n // 512 by 256 division.\\n ///////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0].\\n uint256 remainder;\\n assembly {\\n // Compute remainder using mulmod.\\n remainder := mulmod(x, y, denominator)\\n\\n // Subtract 256 bit number from 512 bit number.\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\\n // See https://cs.stackexchange.com/q/138556/92363.\\n\\n // Does not overflow because the denominator cannot be zero at this stage in the function.\\n uint256 twos = denominator & (~denominator + 1);\\n assembly {\\n // Divide denominator by twos.\\n denominator := div(denominator, twos)\\n\\n // Divide [prod1 prod0] by twos.\\n prod0 := div(prod0, twos)\\n\\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\\n twos := add(div(sub(0, twos), twos), 1)\\n }\\n\\n // Shift in bits from prod1 into prod0.\\n prod0 |= prod1 * twos;\\n\\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\\n // four bits. That is, denominator * inv = 1 mod 2^4.\\n uint256 inverse = (3 * denominator) ^ 2;\\n\\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\\n // in modular arithmetic, doubling the correct bits in each step.\\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\\n\\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inverse;\\n return result;\\n }\\n }\\n\\n /**\\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\\n uint256 result = mulDiv(x, y, denominator);\\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\\n result += 1;\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\\n *\\n * Inspired by Henry S. Warren, Jr.'s \\\"Hacker's Delight\\\" (Chapter 11).\\n */\\n function sqrt(uint256 a) internal pure returns (uint256) {\\n if (a == 0) {\\n return 0;\\n }\\n\\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\\n //\\n // We know that the \\\"msb\\\" (most significant bit) of our target number `a` is a power of 2 such that we have\\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\\n //\\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\\n // \\u2192 `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\\n // \\u2192 `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\\n //\\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\\n uint256 result = 1 << (log2(a) >> 1);\\n\\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\\n // into the expected uint128 result.\\n unchecked {\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n return min(result, a / result);\\n }\\n }\\n\\n /**\\n * @notice Calculates sqrt(a), following the selected rounding direction.\\n */\\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = sqrt(a);\\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 2, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 128;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 64;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 32;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 16;\\n }\\n if (value >> 8 > 0) {\\n value >>= 8;\\n result += 8;\\n }\\n if (value >> 4 > 0) {\\n value >>= 4;\\n result += 4;\\n }\\n if (value >> 2 > 0) {\\n value >>= 2;\\n result += 2;\\n }\\n if (value >> 1 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log2(value);\\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 10, rounded down, of a positive value.\\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 + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 256, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n *\\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\\n */\\n function log256(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 16;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 8;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 4;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 2;\\n }\\n if (value >> 8 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log256(value);\\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe4455ac1eb7fc497bb7402579e7b4d64d928b846fce7d2b6fde06d366f21c2b3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\\n * checks.\\n *\\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\\n * easily result in undesired exploitation or bugs, since developers usually\\n * assume that overflows raise errors. `SafeCast` restores this intuition by\\n * reverting the transaction when such an operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n *\\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\\n * all math on `uint256` and `int256` and then downcasting.\\n */\\nlibrary SafeCast {\\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 * _Available since v4.7._\\n */\\n function toUint248(uint256 value) internal pure returns (uint248) {\\n require(value <= type(uint248).max, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint240(uint256 value) internal pure returns (uint240) {\\n require(value <= type(uint240).max, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint232(uint256 value) internal pure returns (uint232) {\\n require(value <= type(uint232).max, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint224(uint256 value) internal pure returns (uint224) {\\n require(value <= type(uint224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint216(uint256 value) internal pure returns (uint216) {\\n require(value <= type(uint216).max, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint208(uint256 value) internal pure returns (uint208) {\\n require(value <= type(uint208).max, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint200(uint256 value) internal pure returns (uint200) {\\n require(value <= type(uint200).max, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint192(uint256 value) internal pure returns (uint192) {\\n require(value <= type(uint192).max, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint184(uint256 value) internal pure returns (uint184) {\\n require(value <= type(uint184).max, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint176(uint256 value) internal pure returns (uint176) {\\n require(value <= type(uint176).max, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint168(uint256 value) internal pure returns (uint168) {\\n require(value <= type(uint168).max, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint160(uint256 value) internal pure returns (uint160) {\\n require(value <= type(uint160).max, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint152(uint256 value) internal pure returns (uint152) {\\n require(value <= type(uint152).max, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint144(uint256 value) internal pure returns (uint144) {\\n require(value <= type(uint144).max, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint136(uint256 value) internal pure returns (uint136) {\\n require(value <= type(uint136).max, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint128(uint256 value) internal pure returns (uint128) {\\n require(value <= type(uint128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint120(uint256 value) internal pure returns (uint120) {\\n require(value <= type(uint120).max, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint112(uint256 value) internal pure returns (uint112) {\\n require(value <= type(uint112).max, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint104(uint256 value) internal pure returns (uint104) {\\n require(value <= type(uint104).max, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint96(uint256 value) internal pure returns (uint96) {\\n require(value <= type(uint96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint88(uint256 value) internal pure returns (uint88) {\\n require(value <= type(uint88).max, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint80(uint256 value) internal pure returns (uint80) {\\n require(value <= type(uint80).max, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint72(uint256 value) internal pure returns (uint72) {\\n require(value <= type(uint72).max, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint64(uint256 value) internal pure returns (uint64) {\\n require(value <= type(uint64).max, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint56(uint256 value) internal pure returns (uint56) {\\n require(value <= type(uint56).max, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint48(uint256 value) internal pure returns (uint48) {\\n require(value <= type(uint48).max, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint40(uint256 value) internal pure returns (uint40) {\\n require(value <= type(uint40).max, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint32(uint256 value) internal pure returns (uint32) {\\n require(value <= type(uint32).max, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint24(uint256 value) internal pure returns (uint24) {\\n require(value <= type(uint24).max, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint16(uint256 value) internal pure returns (uint16) {\\n require(value <= type(uint16).max, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint8(uint256 value) internal pure returns (uint8) {\\n require(value <= type(uint8).max, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\n */\\n function toUint256(int256 value) internal pure returns (uint256) {\\n require(value >= 0, \\\"SafeCast: value must be positive\\\");\\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 * _Available since v4.7._\\n */\\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\\n downcasted = int248(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\\n downcasted = int240(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\\n downcasted = int232(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\\n downcasted = int224(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\\n downcasted = int216(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\\n downcasted = int208(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\\n downcasted = int200(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\\n downcasted = int192(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\\n downcasted = int184(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\\n downcasted = int176(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\\n downcasted = int168(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\\n downcasted = int160(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\\n downcasted = int152(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\\n downcasted = int144(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\\n downcasted = int136(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\\n downcasted = int128(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\\n downcasted = int120(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\\n downcasted = int112(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\\n downcasted = int104(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\\n downcasted = int96(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\\n downcasted = int88(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\\n downcasted = int80(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\\n downcasted = int72(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\\n downcasted = int64(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\\n downcasted = int56(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\\n downcasted = int48(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\\n downcasted = int40(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\\n downcasted = int32(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\\n downcasted = int24(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\\n downcasted = int16(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\\n downcasted = int8(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\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 require(value <= uint256(type(int256).max), \\\"SafeCast: value doesn't fit in an int256\\\");\\n return int256(value);\\n }\\n}\\n\",\"keccak256\":\"0x52a8cfb0f5239d11b457dcdd1b326992ef672714ca8da71a157255bddd13f3ad\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SignedMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard signed math utilities missing in the Solidity language.\\n */\\nlibrary SignedMath {\\n /**\\n * @dev Returns the largest of two signed numbers.\\n */\\n function max(int256 a, int256 b) internal pure returns (int256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two signed numbers.\\n */\\n function min(int256 a, int256 b) internal pure returns (int256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two signed numbers without overflow.\\n * The result is rounded towards zero.\\n */\\n function average(int256 a, int256 b) internal pure returns (int256) {\\n // Formula from the book \\\"Hacker's Delight\\\"\\n int256 x = (a & b) + ((a ^ b) >> 1);\\n return x + (int256(uint256(x) >> 255) & (a ^ b));\\n }\\n\\n /**\\n * @dev Returns the absolute unsigned value of a signed value.\\n */\\n function abs(int256 n) internal pure returns (uint256) {\\n unchecked {\\n // must be unchecked in order to support `n = type(int256).min`\\n return uint256(n >= 0 ? n : -n);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf92515413956f529d95977adc9b0567d583c6203fc31ab1c23824c35187e3ddc\",\"license\":\"MIT\"},\"contracts/aa-4337/core/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable no-inline-assembly */\\n\\n/**\\n * returned data from validateUserOp.\\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\\n * @param aggregator - address(0) - the account validated the signature by itself.\\n * address(1) - the account failed to validate the signature.\\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\\n * @param validAfter - this UserOp is valid only after this timestamp.\\n * @param validaUntil - this UserOp is valid only up to this timestamp.\\n */\\nstruct ValidationData {\\n address aggregator;\\n uint48 validAfter;\\n uint48 validUntil;\\n}\\n\\n//extract sigFailed, validAfter, validUntil.\\n// also convert zero validUntil to type(uint48).max\\nfunction _parseValidationData(\\n uint validationData\\n) pure returns (ValidationData memory data) {\\n address aggregator = address(uint160(validationData));\\n uint48 validUntil = uint48(validationData >> 160);\\n if (validUntil == 0) {\\n validUntil = type(uint48).max;\\n }\\n uint48 validAfter = uint48(validationData >> (48 + 160));\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n// intersect account and paymaster ranges.\\nfunction _intersectTimeRange(\\n uint256 validationData,\\n uint256 paymasterValidationData\\n) pure returns (ValidationData memory) {\\n ValidationData memory accountValidationData = _parseValidationData(\\n validationData\\n );\\n ValidationData memory pmValidationData = _parseValidationData(\\n paymasterValidationData\\n );\\n address aggregator = accountValidationData.aggregator;\\n if (aggregator == address(0)) {\\n aggregator = pmValidationData.aggregator;\\n }\\n uint48 validAfter = accountValidationData.validAfter;\\n uint48 validUntil = accountValidationData.validUntil;\\n uint48 pmValidAfter = pmValidationData.validAfter;\\n uint48 pmValidUntil = pmValidationData.validUntil;\\n\\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp\\n * @param data - the ValidationData to pack\\n */\\nfunction _packValidationData(\\n ValidationData memory data\\n) pure returns (uint256) {\\n return\\n uint160(data.aggregator) |\\n (uint256(data.validUntil) << 160) |\\n (uint256(data.validAfter) << (160 + 48));\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp, when not using an aggregator\\n * @param sigFailed - true for signature failure, false for success\\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\\n * @param validAfter first timestamp this UserOperation is valid\\n */\\nfunction _packValidationData(\\n bool sigFailed,\\n uint48 validUntil,\\n uint48 validAfter\\n) pure returns (uint256) {\\n return\\n (sigFailed ? 1 : 0) |\\n (uint256(validUntil) << 160) |\\n (uint256(validAfter) << (160 + 48));\\n}\\n\\n/**\\n * keccak function over calldata.\\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\\n */\\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\\n assembly {\\n let mem := mload(0x40)\\n let len := data.length\\n calldatacopy(mem, data.offset, len)\\n ret := keccak256(mem, len)\\n }\\n}\\n\",\"keccak256\":\"0xa79f06cd158ecb8c0da95493a2f348933b8627a63e228b99738bff3aa107942d\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAggregator.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\n/**\\n * Aggregated Signatures validator.\\n */\\ninterface IAggregator {\\n /**\\n * validate aggregated signature.\\n * revert if the aggregated signature does not match the given list of operations.\\n */\\n function validateSignatures(\\n UserOperation[] calldata userOps,\\n bytes calldata signature\\n ) external view;\\n\\n /**\\n * validate signature of a single userOp\\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\\n * @param userOp the userOperation received from the user.\\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\\n * (usually empty, unless account and aggregator support some kind of \\\"multisig\\\"\\n */\\n function validateUserOpSignature(\\n UserOperation calldata userOp\\n ) external view returns (bytes memory sigForUserOp);\\n\\n /**\\n * aggregate multiple signatures into a single value.\\n * This method is called off-chain to calculate the signature to pass with handleOps()\\n * bundler MAY use optimized custom code perform this aggregation\\n * @param userOps array of UserOperations to collect the signatures from.\\n * @return aggregatedSignature the aggregated signature\\n */\\n function aggregateSignatures(\\n UserOperation[] calldata userOps\\n ) external view returns (bytes memory aggregatedSignature);\\n}\\n\",\"keccak256\":\"0xdfdcd80568f037716674619b31be630fcd8316262f05a815b41d1e81782c966a\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IEntryPoint.sol\":{\"content\":\"/**\\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\\n ** Only one instance required on each chain.\\n **/\\n// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-inline-assembly */\\n/* solhint-disable reason-string */\\n\\nimport \\\"./UserOperation.sol\\\";\\nimport \\\"./IStakeManager.sol\\\";\\nimport \\\"./IAggregator.sol\\\";\\nimport \\\"./INonceManager.sol\\\";\\n\\ninterface IEntryPoint is IStakeManager, INonceManager {\\n /***\\n * An event emitted after each successful request\\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\\n * @param sender - the account that generates this request.\\n * @param paymaster - if non-null, the paymaster that pays for this request.\\n * @param nonce - the nonce value from the request.\\n * @param success - true if the sender transaction succeeded, false if reverted.\\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\\n */\\n event UserOperationEvent(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address indexed paymaster,\\n uint256 nonce,\\n bool success,\\n uint256 actualGasCost,\\n uint256 actualGasUsed\\n );\\n\\n /**\\n * account \\\"sender\\\" was deployed.\\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\\n * @param sender the account that is deployed\\n * @param factory the factory used to deploy this account (in the initCode)\\n * @param paymaster the paymaster used by this UserOp\\n */\\n event AccountDeployed(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address factory,\\n address paymaster\\n );\\n\\n /**\\n * An event emitted if the UserOperation \\\"callData\\\" reverted with non-zero length\\n * @param userOpHash the request unique identifier.\\n * @param sender the sender of this request\\n * @param nonce the nonce used in the request\\n * @param revertReason - the return bytes from the (reverted) call to \\\"callData\\\".\\n */\\n event UserOperationRevertReason(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n uint256 nonce,\\n bytes revertReason\\n );\\n\\n /**\\n * an event emitted by handleOps(), before starting the execution loop.\\n * any event emitted before this event, is part of the validation.\\n */\\n event BeforeExecution();\\n\\n /**\\n * signature aggregator used by the following UserOperationEvents within this bundle.\\n */\\n event SignatureAggregatorChanged(address indexed aggregator);\\n\\n /**\\n * a custom revert error of handleOps, to identify the offending op.\\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\\n * @param reason - revert reason\\n * The string starts with a unique code \\\"AAmn\\\", where \\\"m\\\" is \\\"1\\\" for factory, \\\"2\\\" for account and \\\"3\\\" for paymaster issues,\\n * so a failure can be attributed to the correct entity.\\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\\n */\\n error FailedOp(uint256 opIndex, string reason);\\n\\n /**\\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\\n */\\n error SignatureValidationFailed(address aggregator);\\n\\n /**\\n * Successful result from simulateValidation.\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n */\\n error ValidationResult(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo\\n );\\n\\n /**\\n * Successful result from simulateValidation, if the account returns a signature aggregator\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\\n * bundler MUST use it to verify the signature, or reject the UserOperation\\n */\\n error ValidationResultWithAggregation(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo,\\n AggregatorStakeInfo aggregatorInfo\\n );\\n\\n /**\\n * return value of getSenderAddress\\n */\\n error SenderAddressResult(address sender);\\n\\n /**\\n * return value of simulateHandleOp\\n */\\n error ExecutionResult(\\n uint256 preOpGas,\\n uint256 paid,\\n uint48 validAfter,\\n uint48 validUntil,\\n bool targetSuccess,\\n bytes targetResult\\n );\\n\\n //UserOps handled, per aggregator\\n struct UserOpsPerAggregator {\\n UserOperation[] userOps;\\n // aggregator address\\n IAggregator aggregator;\\n // aggregated signature\\n bytes signature;\\n }\\n\\n /**\\n * Execute a batch of UserOperation.\\n * no signature aggregator is used.\\n * if any account requires an aggregator (that is, it returned an aggregator when\\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\\n * @param ops the operations to execute\\n * @param beneficiary the address to receive the fees\\n */\\n function handleOps(\\n UserOperation[] calldata ops,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * Execute a batch of UserOperation with Aggregators\\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\\n * @param beneficiary the address to receive the fees\\n */\\n function handleAggregatedOps(\\n UserOpsPerAggregator[] calldata opsPerAggregator,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * generate a request Id - unique identifier for this request.\\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\\n */\\n function getUserOpHash(\\n UserOperation calldata userOp\\n ) external view returns (bytes32);\\n\\n /**\\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\\n * @param userOp the user operation to validate.\\n */\\n function simulateValidation(UserOperation calldata userOp) external;\\n\\n /**\\n * gas and return values during simulation\\n * @param preOpGas the gas used for validation (including preValidationGas)\\n * @param prefund the required prefund for this operation\\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\\n */\\n struct ReturnInfo {\\n uint256 preOpGas;\\n uint256 prefund;\\n bool sigFailed;\\n uint48 validAfter;\\n uint48 validUntil;\\n bytes paymasterContext;\\n }\\n\\n /**\\n * returned aggregated signature info.\\n * the aggregator returned by the account, and its current stake.\\n */\\n struct AggregatorStakeInfo {\\n address aggregator;\\n StakeInfo stakeInfo;\\n }\\n\\n /**\\n * Get counterfactual sender address.\\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\\n * this method always revert, and returns the address in SenderAddressResult error\\n * @param initCode the constructor code to be passed into the UserOperation.\\n */\\n function getSenderAddress(bytes memory initCode) external;\\n\\n /**\\n * simulate full execution of a UserOperation (including both validation and target execution)\\n * this method will always revert with \\\"ExecutionResult\\\".\\n * it performs full validation of the UserOperation, but ignores signature error.\\n * an optional target address is called after the userop succeeds, and its value is returned\\n * (before the entire call is reverted)\\n * Note that in order to collect the the success/failure of the target call, it must be executed\\n * with trace enabled to track the emitted events.\\n * @param op the UserOperation to simulate\\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\\n * are set to the return from that call.\\n * @param targetCallData callData to pass to target address\\n */\\n function simulateHandleOp(\\n UserOperation calldata op,\\n address target,\\n bytes calldata targetCallData\\n ) external;\\n}\\n\",\"keccak256\":\"0x9ccb1b188eda8bbf5f6c2d01bd83c3d8b2b04fcf745283051d31fe96d1d8e40f\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/INonceManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\ninterface INonceManager {\\n /**\\n * Return the next nonce for this sender.\\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\\n * But UserOp with different keys can come with arbitrary order.\\n *\\n * @param sender the account address\\n * @param key the high 192 bit of the nonce\\n * @return nonce a full nonce to pass for next UserOp with this sender.\\n */\\n function getNonce(\\n address sender,\\n uint192 key\\n ) external view returns (uint256 nonce);\\n\\n /**\\n * Manually increment the nonce of the sender.\\n * This method is exposed just for completeness..\\n * Account does NOT need to call it, neither during validation, nor elsewhere,\\n * as the EntryPoint will update the nonce regardless.\\n * Possible use-case is call it with various keys to \\\"initialize\\\" their nonces to one, so that future\\n * UserOperations will not pay extra for the first transaction with a given key.\\n */\\n function incrementNonce(uint192 key) external;\\n}\\n\",\"keccak256\":\"0xce478ad0fa0d18a3b785ac854623029e7ab463d05873dfaa365abfa1bf100912\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IStakeManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8.12;\\n\\n/**\\n * manage deposits and stakes.\\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\\n * stake is value locked for at least \\\"unstakeDelay\\\" by the staked entity.\\n */\\ninterface IStakeManager {\\n event Deposited(address indexed account, uint256 totalDeposit);\\n\\n event Withdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /// Emitted when stake or unstake delay are modified\\n event StakeLocked(\\n address indexed account,\\n uint256 totalStaked,\\n uint256 unstakeDelaySec\\n );\\n\\n /// Emitted once a stake is scheduled for withdrawal\\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\\n\\n event StakeWithdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /**\\n * @param deposit the entity's deposit\\n * @param staked true if this entity is staked.\\n * @param stake actual amount of ether staked for this entity.\\n * @param unstakeDelaySec minimum delay to withdraw the stake.\\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\\n * and the rest fit into a 2nd cell.\\n * 112 bit allows for 10^15 eth\\n * 48 bit for full timestamp\\n * 32 bit allows 150 years for unstake delay\\n */\\n struct DepositInfo {\\n uint112 deposit;\\n bool staked;\\n uint112 stake;\\n uint32 unstakeDelaySec;\\n uint48 withdrawTime;\\n }\\n\\n //API struct used by getStakeInfo and simulateValidation\\n struct StakeInfo {\\n uint256 stake;\\n uint256 unstakeDelaySec;\\n }\\n\\n /// @return info - full deposit information of given account\\n function getDepositInfo(\\n address account\\n ) external view returns (DepositInfo memory info);\\n\\n /// @return the deposit (for gas payment) of the account\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * add to the deposit of the given account\\n */\\n function depositTo(address account) external payable;\\n\\n /**\\n * add to the account's stake - amount and delay\\n * any pending unstake is first cancelled.\\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\\n */\\n function addStake(uint32 _unstakeDelaySec) external payable;\\n\\n /**\\n * attempt to unlock the stake.\\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\\n */\\n function unlockStake() external;\\n\\n /**\\n * withdraw from the (unlocked) stake.\\n * must first call unlockStake and wait for the unstakeDelay to pass\\n * @param withdrawAddress the address to send withdrawn value.\\n */\\n function withdrawStake(address payable withdrawAddress) external;\\n\\n /**\\n * withdraw from the deposit.\\n * @param withdrawAddress the address to send withdrawn value.\\n * @param withdrawAmount the amount to withdraw.\\n */\\n function withdrawTo(\\n address payable withdrawAddress,\\n uint256 withdrawAmount\\n ) external;\\n}\\n\",\"keccak256\":\"0xadcea606c9b7aafe6645441f2154a60f271330b0eee5292a632aa71c1672d546\",\"license\":\"GPL-3.0-only\"},\"contracts/aa-4337/interfaces/UserOperation.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable no-inline-assembly */\\n\\nimport {calldataKeccak} from \\\"../core/Helpers.sol\\\";\\n\\n/**\\n * User Operation struct\\n * @param sender the sender account of this request.\\n * @param nonce unique value the sender uses to verify it is not a replay.\\n * @param initCode if set, the account contract will be created by this constructor/\\n * @param callData the method call to execute on this account.\\n * @param callGasLimit the gas limit passed to the callData method call.\\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\\n * @param maxFeePerGas same as EIP-1559 gas parameter.\\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\\n */\\nstruct UserOperation {\\n address sender;\\n uint256 nonce;\\n bytes initCode;\\n bytes callData;\\n uint256 callGasLimit;\\n uint256 verificationGasLimit;\\n uint256 preVerificationGas;\\n uint256 maxFeePerGas;\\n uint256 maxPriorityFeePerGas;\\n bytes paymasterAndData;\\n bytes signature;\\n}\\n\\n/**\\n * Utility functions helpful when working with UserOperation structs.\\n */\\nlibrary UserOperationLib {\\n function getSender(\\n UserOperation calldata userOp\\n ) internal pure returns (address) {\\n address data;\\n //read sender from userOp, which is first userOp member (saves 800 gas...)\\n assembly {\\n data := calldataload(userOp)\\n }\\n return address(uint160(data));\\n }\\n\\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\\n // pay above what he signed for.\\n function gasPrice(\\n UserOperation calldata userOp\\n ) internal view returns (uint256) {\\n unchecked {\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n if (maxFeePerGas == maxPriorityFeePerGas) {\\n //legacy mode (for networks that don't support basefee opcode)\\n return maxFeePerGas;\\n }\\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\\n }\\n }\\n\\n function pack(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes memory ret) {\\n address sender = getSender(userOp);\\n uint256 nonce = userOp.nonce;\\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\\n bytes32 hashCallData = calldataKeccak(userOp.callData);\\n uint256 callGasLimit = userOp.callGasLimit;\\n uint256 verificationGasLimit = userOp.verificationGasLimit;\\n uint256 preVerificationGas = userOp.preVerificationGas;\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\\n\\n return\\n abi.encode(\\n sender,\\n nonce,\\n hashInitCode,\\n hashCallData,\\n callGasLimit,\\n verificationGasLimit,\\n preVerificationGas,\\n maxFeePerGas,\\n maxPriorityFeePerGas,\\n hashPaymasterAndData\\n );\\n }\\n\\n function hash(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes32) {\\n return keccak256(pack(userOp));\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n}\\n\",\"keccak256\":\"0x2429f5cc546bdee08c7e63858d0dda8491eaa3ab5194df884dc948c1154d2834\",\"license\":\"GPL-3.0\"},\"contracts/facets/Modifiers.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {LibGuardian} from \\\"../libraries/LibGuardian.sol\\\";\\nimport {BarzStorage} from \\\"../libraries/LibAppStorage.sol\\\";\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\n\\n/**\\n * @title Modifiers\\n * @dev Responsible for providing modifiers/util functions to Facet contracts\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\nabstract contract Modifiers is BarzStorage {\\n uint8 constant INNER_STRUCT = 0;\\n\\n error CallerNotGuardian();\\n error CallerNotGuardianOrOwner();\\n error DuplicateApprover();\\n error ZeroApproverLength();\\n error UnregisteredFacetAndSelectors();\\n\\n /**\\n * @notice Modifier to only allow guardian to make a call, reverts if any other entity is the caller\\n */\\n modifier onlyGuardian() {\\n if (!LibGuardian.isGuardian(msg.sender)) revert CallerNotGuardian();\\n _;\\n }\\n\\n /**\\n * @notice Modifier to only allow guardian or owner to make a call, reverts if any other entity is the caller\\n */\\n modifier onlyGuardianOrOwner() {\\n if (!LibGuardian.isGuardian(msg.sender) && address(this) != msg.sender)\\n revert CallerNotGuardianOrOwner();\\n _;\\n }\\n\\n /**\\n * @notice Checks if the approver address is the array is unique with no duplicate\\n * @dev This method loops through the array and checks if a duplicate address exists, it reverts if duplicate address exists\\n * @param approvers Array of address\\n */\\n function _checkApprover(\\n address[] memory approvers\\n ) internal pure returns (bool) {\\n uint256 approverLength = approvers.length;\\n if (0 == approverLength) revert ZeroApproverLength();\\n for (uint256 i; i < approverLength - 1; ) {\\n for (uint256 j = i + 1; j < approverLength; ) {\\n if (approvers[i] == approvers[j]) {\\n revert DuplicateApprover(); // Found a duplicate\\n }\\n unchecked {\\n ++j;\\n }\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n return false; // No duplicates found\\n }\\n\\n /**\\n * @notice Checks if the facet getting added or replaced is registered to facet registry\\n * @dev This method loops through the cut and checks if the facet getting added/replaced is registered to facet registry\\n * @param _diamondCut Array of FacetCut, data for diamondCut defined in EIP-2535\\n */\\n function _checkFacetCutValidity(\\n IDiamondCut.FacetCut[] memory _diamondCut\\n ) internal view {\\n uint256 diamondCutLength = _diamondCut.length;\\n for (uint256 i; i < diamondCutLength; ) {\\n if (\\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Add ||\\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Replace\\n ) {\\n if (\\n !s.facetRegistry.areFacetFunctionSelectorsRegistered(\\n _diamondCut[i].facetAddress,\\n _diamondCut[i].functionSelectors\\n )\\n ) revert UnregisteredFacetAndSelectors();\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb42956323d199bdec243a5f9859439aae057fbfdd1d79e3a96afc857ecb3115f\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/DiamondCutFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {LibDiamond} from \\\"../../libraries/LibDiamond.sol\\\";\\nimport {LibGuardian} from \\\"../../libraries/LibGuardian.sol\\\";\\nimport {ISecurityManager} from \\\"../../infrastructure/interfaces/ISecurityManager.sol\\\";\\nimport {SignatureChecker} from \\\"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\\\";\\nimport {LibFacetStorage, DiamondCutApprovalConfig, ApprovalConfig} from \\\"../../libraries/LibFacetStorage.sol\\\";\\nimport {Modifiers} from \\\"../Modifiers.sol\\\";\\nimport {IDiamondCut} from \\\"./interfaces/IDiamondCut.sol\\\";\\n\\n/**\\n * @title DiamondCut Facet\\n * @dev Responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract DiamondCutFacet is Modifiers, IDiamondCut {\\n ISecurityManager public immutable securityManager;\\n\\n /**\\n * @notice This constructor sets the Security Manager address which is an immutable variable.\\n * Immutable variables do not impact the storage of diamond\\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\\n */\\n constructor(address _securityManager) {\\n securityManager = ISecurityManager(_securityManager);\\n }\\n\\n /**\\n * @notice Updates the flag for the interfaceId\\n * @param _interfaceId InterfaceID to update the mapping\\n * @param _flag Bool value to update the mapping of the given interface ID\\n */\\n function updateSupportsInterface(\\n bytes4 _interfaceId,\\n bool _flag\\n ) external override onlyWhenUnlocked {\\n LibDiamond.enforceIsSelf();\\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId] = _flag;\\n emit SupportsInterfaceUpdated(_interfaceId, _flag);\\n }\\n\\n /**\\n * @notice Add/replace/remove any number of functions and optionally execute\\n * a function with delegatecall when guardians don't exist\\n * @param _diamondCut Contains the facet addresses and function selectors\\n * @param _init The address of the contract or facet to execute _calldata. It's prohibited in Barz\\n */\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata\\n ) external override onlyWhenUnlocked {\\n LibDiamond.enforceIsSelf();\\n\\n _checkFacetCutValidity(_diamondCut);\\n // require approval from guardian if guardian exists\\n if (0 != LibGuardian.guardianCount())\\n revert DiamondCutFacet__InvalidRouteWithGuardian();\\n if (address(0) != _init) revert DiamondCutFacet__InvalidInitAddress();\\n\\n unchecked {\\n ++LibFacetStorage.diamondCutStorage().nonce;\\n }\\n LibDiamond.diamondCut(_diamondCut, address(0), \\\"\\\");\\n }\\n\\n /**\\n * @notice Add/replace/remove any number of functions and optionally execute\\n * a function with delegatecall when guardians exist\\n * @param _diamondCut Contains the facet addresses and function selectors\\n * @param _approvers Guardian or owner address that approves the diamond cut\\n * @param _signatures Signature of Guardians or owner that approves the diamond cut\\n */\\n function diamondCutWithGuardian(\\n FacetCut[] calldata _diamondCut,\\n address[] calldata _approvers,\\n bytes[] calldata _signatures\\n ) external override onlyWhenUnlocked {\\n if (_approvers.length != _signatures.length)\\n revert DiamondCutFacet__InvalidArrayLength();\\n _checkFacetCutValidity(_diamondCut);\\n if (0 == LibGuardian.guardianCount())\\n revert DiamondCutFacet__InvalidRouteWithGuardian();\\n\\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\\n\\n _checkApprover(_approvers);\\n _checkDuplicateOnChainApprover(cutHash, _approvers);\\n\\n bool onChainOwnerApproval = getOwnerCutApprovalWithTimeValidity(\\n cutHash\\n );\\n\\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\\n if (\\n _approvers.length +\\n getDiamondCutApprovalCountWithTimeValidity(cutHash) <\\n LibGuardian.majorityOfGuardians() + threshold\\n ) revert DiamondCutFacet__InsufficientApprovers();\\n\\n bool ownerApproved;\\n for (uint256 i; i < _approvers.length; ) {\\n if (\\n !LibGuardian.isGuardian(_approvers[i]) &&\\n _approvers[i] != address(this)\\n ) revert DiamondCutFacet__InvalidApprover();\\n if (_approvers[i] == address(this)) {\\n if (onChainOwnerApproval)\\n revert DiamondCutFacet__OwnerAlreadyApproved();\\n ownerApproved = true;\\n }\\n if (\\n !SignatureChecker.isValidSignatureNow(\\n _approvers[i],\\n cutHash,\\n _signatures[i]\\n )\\n ) revert DiamondCutFacet__InvalidApproverSignature();\\n unchecked {\\n ++i;\\n }\\n }\\n if (!ownerApproved && !onChainOwnerApproval)\\n revert DiamondCutFacet__LackOfOwnerApproval();\\n\\n unchecked {\\n ++LibFacetStorage.diamondCutStorage().nonce;\\n }\\n LibDiamond.diamondCut(_diamondCut, address(0), \\\"\\\");\\n }\\n\\n /**\\n * @notice Approves diamond cut. This can only be called directly from guardian or owner\\n * @param _diamondCut Contains the facet addresses and function selectors\\n */\\n function approveDiamondCut(\\n FacetCut[] calldata _diamondCut\\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\\n if (LibGuardian.guardianCount() == 0)\\n revert DiamondCutFacet__InvalidRouteWithoutGuardian();\\n DiamondCutApprovalConfig storage ds = LibFacetStorage\\n .diamondCutStorage()\\n .diamondCutApprovalConfigs[INNER_STRUCT];\\n _checkFacetCutValidity(_diamondCut);\\n\\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\\n uint64 approvalValidUntil = uint64(\\n block.timestamp + getApprovalValidationPeriod()\\n );\\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(\\n true,\\n approvalValidUntil\\n );\\n emit DiamondCutApproved(_diamondCut);\\n if (\\n (getDiamondCutApprovalCountWithTimeValidity(cutHash) >=\\n LibGuardian.majorityOfGuardians()) &&\\n getOwnerCutApprovalWithTimeValidity(cutHash)\\n ) {\\n unchecked {\\n ++LibFacetStorage.diamondCutStorage().nonce;\\n }\\n LibDiamond.diamondCut(_diamondCut, address(0), \\\"\\\");\\n }\\n }\\n\\n /**\\n * @notice Revokes the approval of diamond cut. This can only be called directly from guardian or owner\\n * @param _diamondCut Contains the facet addresses and function selectors\\n */\\n function revokeDiamondCutApproval(\\n FacetCut[] calldata _diamondCut\\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\\n DiamondCutApprovalConfig storage ds = LibFacetStorage\\n .diamondCutStorage()\\n .diamondCutApprovalConfigs[INNER_STRUCT];\\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\\n if (!ds.isDiamondCutApproved[cutHash][msg.sender].isApproved)\\n revert DiamondCutFacet__CannotRevokeUnapproved();\\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(false, 0);\\n emit DiamondCutApprovalRevoked(_diamondCut);\\n }\\n\\n /**\\n * @notice Gets the number of approvals of diamond cut from guardians\\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\\n */\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 _diamondCutHash\\n ) public view override returns (uint256 approvalCount) {\\n address[] memory guardians = LibGuardian.getGuardians();\\n uint256 guardiansLength = guardians.length;\\n for (uint256 i; i < guardiansLength; ) {\\n if (isCutApproved(_diamondCutHash, guardians[i])) {\\n unchecked {\\n ++approvalCount;\\n }\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n return approvalCount;\\n }\\n\\n /**\\n * @notice Returns if the owner has approved the diamond cut\\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\\n * @return isApprovedByOwner Bool value showing if the owner approved the cut\\n */\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 _diamondCutHash\\n ) public view override returns (bool isApprovedByOwner) {\\n isApprovedByOwner = isCutApproved(_diamondCutHash, address(this));\\n }\\n\\n /**\\n * @notice Returns if the given approver has approved the diamond cut\\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\\n * @param _approver Address of approver\\n * @return isApproved Bool value showing if the approver approved the cut\\n */\\n function isCutApproved(\\n bytes32 _diamondCutHash,\\n address _approver\\n ) public view override returns (bool isApproved) {\\n DiamondCutApprovalConfig storage ds = LibFacetStorage\\n .diamondCutStorage()\\n .diamondCutApprovalConfigs[INNER_STRUCT];\\n isApproved = (ds\\n .isDiamondCutApproved[_diamondCutHash][_approver].isApproved &&\\n block.timestamp <\\n ds.isDiamondCutApproved[_diamondCutHash][_approver].validUntil);\\n }\\n\\n /**\\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\\n * Approvers who approved on-chain should not be included in the off-chain approval\\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\\n * @param _approvers List of approver addresses\\n */\\n function _checkDuplicateOnChainApprover(\\n bytes32 _diamondCutHash,\\n address[] memory _approvers\\n ) public view {\\n address[] memory guardians = LibGuardian.getGuardians();\\n uint256 guardianLength = guardians.length;\\n uint256 approversLength = _approvers.length;\\n for (uint256 i; i < guardianLength; ) {\\n if (isCutApproved(_diamondCutHash, guardians[i])) {\\n for (uint256 j; j < approversLength; ) {\\n if (_approvers[j] == guardians[i])\\n revert DiamondCutFacet__DuplicateApproval();\\n unchecked {\\n ++j;\\n }\\n }\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * @notice Returns the diamond cut hash. This function ensures that this hash is safe from replay attack by including\\n * salt, address, chainId, and nonce, etc.\\n * @param _diamondCut Contains the facet addresses and function selectors\\n * @return cutHash Diamond Cut Hash\\n */\\n function getDiamondCutHash(\\n FacetCut[] calldata _diamondCut\\n ) public view override returns (bytes32 cutHash) {\\n cutHash = keccak256(\\n abi.encodePacked(\\n \\\"\\\\x19Ethereum Signed Message:\\\\n32\\\",\\n keccak256(\\n abi.encode(\\n keccak256(abi.encode(_diamondCut)),\\n address(this),\\n block.chainid,\\n LibFacetStorage.diamondCutStorage().nonce\\n )\\n )\\n )\\n );\\n }\\n\\n /**\\n * @notice Returns the approval validation Period\\n * @dev This method fetches the validation period from the security manager\\n * @return approvalValidationPeriod Approval validation period of Barz contract fetched from security manager\\n */\\n function getApprovalValidationPeriod()\\n internal\\n view\\n returns (uint256 approvalValidationPeriod)\\n {\\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\\n address(this)\\n );\\n if (approvalValidationPeriod <= 0)\\n revert DiamondCutFacet__InvalidApprovalValidationPeriod();\\n }\\n\\n /**\\n * @notice Returns the diamond cut nonce of this wallet\\n * @dev This method fetches the nonce from diamond cut storage\\n * @return cutNonce Nonce of diamond cut to protect from reply attacks\\n */\\n function getDiamondCutNonce()\\n public\\n view\\n override\\n returns (uint128 cutNonce)\\n {\\n cutNonce = LibFacetStorage.diamondCutStorage().nonce;\\n }\\n}\\n\",\"keccak256\":\"0xe91a7dd2daabf2e989c94089f4f1eb0da94276c3070559ac8988838e10dd1f5d\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/infrastructure/interfaces/IFacetRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Registry Interface\\n * @dev Interface for Facet Registry contract to keep track of facets & function selectors addable to user wallets\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IFacetRegistry {\\n struct FacetRegistryConfig {\\n bytes4[] selectors;\\n mapping(bytes4 => FacetInfo) info;\\n }\\n struct FacetInfo {\\n bool exists;\\n uint128 index;\\n }\\n\\n event FacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] facetSelectors\\n );\\n event FacetFunctionSelectorsRemoved(address facet, bytes4[] facetSelectors);\\n\\n error FacetRegistry__FacetSelectorAlreadyRegistered();\\n error FacetRegistry__UnregisteredFacetSelector();\\n\\n function registerFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function removeFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function areFacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external view returns (bool);\\n\\n function isFacetFunctionSelectorRegistered(\\n address facet,\\n bytes4 facetSelector\\n ) external view returns (bool);\\n\\n function getFacetFunctionSelectors(\\n address facet\\n ) external view returns (bytes4[] memory);\\n}\\n\",\"keccak256\":\"0x6e6dd2cab346ef7c31230740ec48d2925e4a9ab24c2f2fb268baaf408dcf02ef\",\"license\":\"Apache-2.0\"},\"contracts/infrastructure/interfaces/ISecurityManager.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Registry Interface\\n * @dev Infrastructure contract to manage security parameters of users\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\ninterface ISecurityManager {\\n error SecurityManager__OutOfBoundary();\\n error SecurityManager__CallerNotWallet();\\n error SecurityManager__AlreadyIntialized();\\n\\n function initializeAdditionSecurityPeriod(\\n uint128 defaultAdditionSecurityPeriod,\\n uint128 minAdditionSecurityPeriod,\\n uint128 maxAdditionSecurityPeriod\\n ) external;\\n\\n function initializeRemovalSecurityPeriod(\\n uint128 defaultRemovalSecurityPeriod,\\n uint128 minRemovalSecurityPeriod,\\n uint128 maxRemovalSecurityPeriod\\n ) external;\\n\\n function initializeApprovalValidationPeriod(\\n uint128 defaultApprovalValidationPeriod,\\n uint128 minApprovalValidationPeriod,\\n uint128 maxApprovalValidationPeriod\\n ) external;\\n\\n function initializeMigrationPeriod(\\n uint128 defaultMigrationPeriod,\\n uint128 minMigrationPeriod,\\n uint128 maxMigrationPeriod\\n ) external;\\n\\n function initializeLockPeriod(\\n uint128 defaultLockPeriod,\\n uint128 minLockPeriod,\\n uint128 maxLockPeriod\\n ) external;\\n\\n function initializeRecoveryPeriod(\\n uint128 defaultRecoveryPeriod,\\n uint128 minRecoveryPeriod,\\n uint128 maxRecoveryPeriod\\n ) external;\\n\\n function initializeSecurityWindow(\\n uint128 defaultSecurityWindow,\\n uint128 minSecurityWindow,\\n uint128 maxSecurityWindow\\n ) external;\\n\\n function setAdditionSecurityPeriod(\\n address wallet,\\n uint128 additionSecurityPeriod\\n ) external;\\n\\n function setRemovalSecurityPeriod(\\n address wallet,\\n uint128 removalSecurityPeriod\\n ) external;\\n\\n function setSecurityWindow(address wallet, uint128 securityWindow) external;\\n\\n function setRecoveryPeriod(address wallet, uint128 recoveryPeriod) external;\\n\\n function setLockPeriod(address wallet, uint128 lockPeriod) external;\\n\\n function setApprovalValidationPeriod(\\n address wallet,\\n uint128 approvalValidationPeriod\\n ) external;\\n\\n function setMigrationPeriod(\\n address wallet,\\n uint128 migrationPeriod\\n ) external;\\n\\n function additionSecurityPeriodOf(\\n address wallet\\n ) external view returns (uint128);\\n\\n function removalSecurityPeriodOf(\\n address wallet\\n ) external view returns (uint128);\\n\\n function securityWindowOf(address wallet) external view returns (uint128);\\n\\n function recoveryPeriodOf(address wallet) external view returns (uint128);\\n\\n function lockPeriodOf(address wallet) external view returns (uint128);\\n\\n function migrationPeriodOf(address wallet) external view returns (uint128);\\n\\n function approvalValidationPeriodOf(\\n address wallet\\n ) external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x9ac6566033ef81ba5744c8ed2b08f130b781b498ab9245bcca87567669549552\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibAppStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {SafeCast} from \\\"@openzeppelin/contracts/utils/math/SafeCast.sol\\\";\\nimport {IEntryPoint} from \\\"../aa-4337/interfaces/IEntryPoint.sol\\\";\\nimport {IFacetRegistry} from \\\"../infrastructure/interfaces/IFacetRegistry.sol\\\";\\n\\n/*\\n * @title App Storage\\n * @dev App storage for Barz contract to prevent storage collision\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Lock {\\n uint64 release;\\n bytes4 locker;\\n}\\n\\nstruct InitializersStorage {\\n // NOTE: initialized is a variable to make sure the initialization is only done once.\\n uint8 signerInitialized;\\n uint8 accountInitialized;\\n uint8 restrictionsInitialized;\\n}\\n\\nstruct AppStorage {\\n mapping(uint256 => InitializersStorage) initStorage;\\n uint8 signerMigration;\\n bytes4 validateOwnerSignatureSelector;\\n IEntryPoint entryPoint;\\n IFacetRegistry facetRegistry;\\n mapping(uint256 => Lock) locks;\\n}\\n\\nlibrary LibAppStorage {\\n error LibAppStorage__AccountAlreadyUninitialized();\\n error LibAppStorage__AccountMustBeUninitialized();\\n error LibAppStorage__SignerAlreadyUninitialized();\\n error LibAppStorage__SignerMustBeUninitialized();\\n\\n function appStorage() internal pure returns (AppStorage storage ds) {\\n assembly {\\n ds.slot := 0\\n }\\n }\\n\\n function setSignerUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerAlreadyUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 0;\\n }\\n\\n function getValidateOwnerSignatureSelector()\\n internal\\n view\\n returns (bytes4 selector)\\n {\\n selector = appStorage().validateOwnerSignatureSelector;\\n }\\n\\n function setValidateOwnerSignatureSelector(\\n bytes4 _validateOwnerSignatureSelector\\n ) internal {\\n appStorage()\\n .validateOwnerSignatureSelector = _validateOwnerSignatureSelector;\\n }\\n\\n function enforceSignerInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerMustBeUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 1;\\n }\\n\\n function enforceAccountInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].accountInitialized) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n s.initStorage[0].accountInitialized = 1;\\n }\\n\\n function initiateSignerMigration() internal {\\n appStorage().signerMigration = 1;\\n }\\n\\n function enforceSignerMigration() internal view {\\n if (1 != appStorage().signerMigration) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n }\\n\\n function finalizeSignerMigration() internal {\\n appStorage().signerMigration = 0;\\n }\\n\\n function setLock(uint256 _releaseAfter, bytes4 _locker) internal {\\n appStorage().locks[0] = Lock(SafeCast.toUint64(_releaseAfter), _locker);\\n }\\n\\n function enforceRestrictionsInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__SignerMustBeUninitialized();\\n s.initStorage[0].restrictionsInitialized = 1;\\n }\\n\\n function setRestrictionsUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__AccountAlreadyUninitialized();\\n s.initStorage[0].restrictionsInitialized = 0;\\n }\\n}\\n\\ncontract BarzStorage {\\n AppStorage internal s;\\n modifier onlyWhenUnlocked() {\\n require(\\n uint64(block.timestamp) >= s.locks[0].release,\\n \\\"Account Locked\\\"\\n );\\n _;\\n }\\n modifier onlyWhenLocked() {\\n require(\\n uint64(block.timestamp) < s.locks[0].release,\\n \\\"Account Unlocked\\\"\\n );\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x48524007862a6ce0e07f645950613ce6513ce073c37a109c75019683d42bae27\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\\n bytes4(keccak256(\\\"verifyRestrictions(address,address,uint256,bytes)\\\"));\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // Default Fallback Handler of the barz.\\n IDiamondLoupe defaultFallbackHandler;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function enforceIsSelf() internal view {\\n require(msg.sender == address(this), \\\"LibDiamond: Caller not self\\\");\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n\\n unchecked {\\n facetIndex++;\\n }\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n\\n function restrictionsFacet() internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(\\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2cabdc00de859c3a3170ce3bda5d0e5fd3933d47ce904fd1585f9818b02572f8\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibFacetStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Storage\\n * @dev Storage contract to store each facets variables with diamond storage\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Secp256k1VerificationStorage {\\n address signer;\\n}\\n\\nstruct Secp256r1VerificationStorage {\\n uint256[2] q;\\n}\\n\\nstruct GuardianStorage {\\n mapping(bytes32 => uint256) pending;\\n mapping(uint8 => StorageConfig) configs;\\n}\\n\\nstruct Info {\\n bool exists;\\n uint128 index;\\n}\\n\\nstruct StorageConfig {\\n address[] addresses;\\n mapping(address => Info) info;\\n}\\n\\nstruct RecoveryConfig {\\n bytes recoveryPublicKey;\\n uint64 executeAfter;\\n}\\n\\nstruct ApprovalConfig {\\n bool isApproved;\\n uint64 validUntil;\\n}\\n\\nstruct RecoveryApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isNewOwnerApproved;\\n}\\n\\nstruct RecoveryStorage {\\n mapping(uint8 => RecoveryConfig) recoveryConfigs;\\n mapping(uint8 => RecoveryApprovalConfig) recoveryApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct RestrictionsStorage {\\n address[] restrictions;\\n mapping(address => bool) exists;\\n}\\n\\nstruct SignatureMigrationConfig {\\n bytes migrationPublicKey;\\n address migrationVerificationFacet;\\n bytes4[] migrationSelectors;\\n uint64 migrateAfter;\\n}\\n\\nstruct SignatureMigrationApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isMigrationApproved;\\n}\\n\\nstruct SignatureMigrationStorage {\\n mapping(uint8 => SignatureMigrationConfig) migrationConfigs;\\n mapping(uint8 => SignatureMigrationApprovalConfig) migrationApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct DiamondCutApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isDiamondCutApproved;\\n}\\n\\nstruct DiamondCutStorage {\\n mapping(uint8 => DiamondCutApprovalConfig) diamondCutApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct LockStorage {\\n uint128 nonce;\\n}\\n\\nlibrary LibFacetStorage {\\n bytes32 constant K1_STORAGE_POSITION =\\n keccak256(\\n \\\"v0.trustwallet.diamond.storage.Secp256k1VerificationStorage\\\"\\n );\\n bytes32 constant R1_STORAGE_POSITION =\\n keccak256(\\n \\\"v0.trustwallet.diamond.storage.Secp256r1VerificationStorage\\\"\\n );\\n bytes32 constant GUARDIAN_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.GuardianStorage\\\");\\n bytes32 constant RECOVERY_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.RecoveryStorage\\\");\\n bytes32 constant RESTRICTION_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.RestrictionsStorage\\\");\\n bytes32 constant MIGRATION_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.SignatureMigrationStorage\\\");\\n bytes32 constant DIAMONDCUT_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.DiamondCutStorage\\\");\\n bytes32 constant LOCK_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.LockStorage\\\");\\n\\n function k1Storage()\\n internal\\n pure\\n returns (Secp256k1VerificationStorage storage ds)\\n {\\n bytes32 storagePosition = K1_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function r1Storage()\\n internal\\n pure\\n returns (Secp256r1VerificationStorage storage ds)\\n {\\n bytes32 storagePosition = R1_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function guardianStorage()\\n internal\\n pure\\n returns (GuardianStorage storage ds)\\n {\\n bytes32 storagePosition = GUARDIAN_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function recoveryStorage()\\n internal\\n pure\\n returns (RecoveryStorage storage ds)\\n {\\n bytes32 storagePosition = RECOVERY_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function restrictionsStorage()\\n internal\\n pure\\n returns (RestrictionsStorage storage ds)\\n {\\n bytes32 storagePosition = RESTRICTION_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function migrationStorage()\\n internal\\n pure\\n returns (SignatureMigrationStorage storage ds)\\n {\\n bytes32 storagePosition = MIGRATION_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function diamondCutStorage()\\n internal\\n pure\\n returns (DiamondCutStorage storage ds)\\n {\\n bytes32 storagePosition = DIAMONDCUT_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function lockStorage() internal pure returns (LockStorage storage ds) {\\n bytes32 storagePosition = LOCK_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n}\\n\",\"keccak256\":\"0x87c85decfd943deda9540733e464cb1a92eba735a301e89ce6f798016e359761\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibGuardian.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {LibFacetStorage, StorageConfig} from \\\"./LibFacetStorage.sol\\\";\\n\\n/**\\n * @title LibGuardian\\n * @dev Internal Library to provide utility feature for Guardians stored in Guardian Facet Storage\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\nlibrary LibGuardian {\\n function majorityOfGuardians()\\n internal\\n view\\n returns (uint256 guardianNumber)\\n {\\n uint256 guardianLength = guardianCount();\\n guardianNumber = (guardianLength == 0) ? 0 : guardianLength / 2 + 1;\\n }\\n\\n function isGuardian(address _guardian) internal view returns (bool) {\\n StorageConfig storage config = LibFacetStorage\\n .guardianStorage()\\n .configs[0];\\n return config.info[_guardian].exists;\\n }\\n\\n function guardianCount() internal view returns (uint256) {\\n StorageConfig storage config = LibFacetStorage\\n .guardianStorage()\\n .configs[0];\\n return config.addresses.length;\\n }\\n\\n function getGuardians() internal view returns (address[] memory) {\\n StorageConfig storage config = LibFacetStorage\\n .guardianStorage()\\n .configs[0];\\n address[] memory addresses = new address[](config.addresses.length);\\n uint256 addressesLen = config.addresses.length;\\n for (uint256 i; i < addressesLen; ) {\\n addresses[i] = config.addresses[i];\\n unchecked {\\n ++i;\\n }\\n }\\n return addresses;\\n }\\n}\\n\",\"keccak256\":\"0x6a620992d5535878fc03d1a27a6675f4c1509adfb3ddbbca1c52b546c25392dc\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x60a06040523480156200001157600080fd5b506040516200379b3803806200379b833981016040819052620000349162000046565b6001600160a01b031660805262000078565b6000602082840312156200005957600080fd5b81516001600160a01b03811681146200007157600080fd5b9392505050565b6080516137006200009b600039600081816101f10152611b2501526137006000f3fe608060405234801561001057600080fd5b50600436106100d45760003560e01c806379c0d58d11610081578063afb877bb1161005b578063afb877bb146101d9578063de675a6d146101ec578063e33ecf0a1461023857600080fd5b806379c0d58d14610192578063836d6bfb146101b35780638824a0bb146101c657600080fd5b806326fc3ef4116100b257806326fc3ef4146101145780632f4d98ea1461015c5780633c0985681461017f57600080fd5b806313c34f4b146100d95780631c776dd5146100ee5780631f931c1c14610101575b600080fd5b6100ec6100e7366004612a97565b61024b565b005b6100ec6100fc366004612ad9565b6104df565b6100ec61010f366004612b9c565b610a76565b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9bf546040516fffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b61016f61016a366004612c4a565b610c7b565b6040519015158152602001610153565b6100ec61018d366004612ca4565b610c8d565b6101a56101a0366004612c4a565b610df2565b604051908152602001610153565b61016f6101c1366004612cdb565b610e4c565b6100ec6101d4366004612dd2565b610eed565b6100ec6101e7366004612a97565b610fe1565b6102137f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610153565b6101a5610246366004612a97565b61130e565b3360009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff1615801561028a5750303314155b156102c1576040517f6238ee3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610369576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064015b60405180910390fd5b60008080527f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be6020527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d3906103be848461130e565b60008181526020848152604080832033845290915290205490915060ff16610412576040517fedc5708300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051808201825260008082526020808301828152858352868252848320338452909152908390209151825491517fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000009092169015157fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff161761010067ffffffffffffffff90921691909102179055517f3c3d8c1f0b0faff6fe0ace6b485d0595a0106dce9e303f956fd941ebdbe9a98e906104d19086908690612f54565b60405180910390a150505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610582576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b8281146105bb576040517fe854148500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6105cd6105c886886130aa565b611435565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b754600003610650576040517fa788861700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061065c878761130e565b905061069a8585808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506115b392505050565b506106d881868680806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250610eed92505050565b60006106e382610c7b565b90506000816106f35760016106f6565b60005b60ff169050806107046116d0565b61070e9190613201565b61071784610df2565b6107219088613201565b1015610759576040517f709fb08000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805b878110156109a0576107d989898381811061077a5761077a613214565b905060200201602081019061078f9190613243565b73ffffffffffffffffffffffffffffffffffffffff1660009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff1690565b1580156108225750308989838181106107f4576107f4613214565b90506020020160208101906108099190613243565b73ffffffffffffffffffffffffffffffffffffffff1614155b15610859576040517f7b2cbbb400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3089898381811061086c5761086c613214565b90506020020160208101906108819190613243565b73ffffffffffffffffffffffffffffffffffffffff16036108d95783156108d4576040517fee21708000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600191505b6109628989838181106108ee576108ee613214565b90506020020160208101906109039190613243565b8689898581811061091657610916613214565b90506020028101906109289190613265565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061174f92505050565b610998576040517fac3d341600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60010161075d565b50801580156109ad575082155b156109e4576040517f6d21730400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9bf80546fffffffffffffffffffffffffffffffff808216600101167fffffffffffffffffffffffffffffffff00000000000000000000000000000000909116179055610a6a610a538a8c6130aa565b6000604051806020016040528060008152506117ca565b50505050505050505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610b19576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b610b2161195f565b610b2e6105c885876130aa565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75415610baf576040517fa788861700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff831615610bfd576040517f871cb76100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be5b600190810180547fffffffffffffffffffffffffffffffff0000000000000000000000000000000081166fffffffffffffffffffffffffffffffff91821690930116919091179055610c74610a5385876130aa565b5050505050565b6000610c878230610e4c565b92915050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610d30576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b610d3861195f565b7fffffffff00000000000000000000000000000000000000000000000000000000821660008181527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4922602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001685151590811790915582519384529083015280517f4e6bd17989efa6d6a9607ccaac1bba27b29f99622bc830d99a3a9883b21a19c79281900390910190a15050565b600080610dfd6119ca565b805190915060005b81811015610e4457610e3085848381518110610e2357610e23613214565b6020026020010151610e4c565b15610e3c578360010193505b600101610e05565b505050919050565b60008281527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d36020818152604080842073ffffffffffffffffffffffffffffffffffffffff8616855290915282205460ff168015610ee5575060008481526020828152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152902054610100900467ffffffffffffffff1642105b949350505050565b6000610ef76119ca565b805183519192509060005b82811015610fd957610f2086858381518110610e2357610e23613214565b15610fd15760005b82811015610fcf57848281518110610f4257610f42613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16868281518110610f7257610f72613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603610fc7576040517f50f5729f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600101610f28565b505b600101610f02565b505050505050565b3360009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff161580156110205750303314155b15611057576040517f6238ee3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff9081164290911610156110fa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75460000361117d576040517f3a76e1f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080527f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be6020527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d36111d36105c883856130aa565b60006111df848461130e565b905060006111eb611af4565b6111f59042613201565b6040805180820182526001815267ffffffffffffffff838116602080840191825260008881528982528581203382529091528490209251835491517fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000009092169015157fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff16176101009190921602179055519091507f6248ff757895beed7d43d135bccf59a26b7fbdf0fe8233487c44e82c0f266ba3906112b89087908790612f54565b60405180910390a16112c86116d0565b6112d183610df2565b101580156112e357506112e382610c7b565b15610c74577f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be610c1f565b60008282604051602001611323929190612f54565b6040516020818303038152906040528051906020012030466113627f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be90565b6001015460408051602081019590955273ffffffffffffffffffffffffffffffffffffffff9093169284019290925260608301526fffffffffffffffffffffffffffffffff16608082015260a001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905280516020918201207f19457468657265756d205369676e6564204d6573736167653a0a33320000000091830191909152603c820152605c0160405160208183030381529060405280519060200120905092915050565b805160005b818110156115ae57600083828151811061145657611456613214565b602002602001015160200151600281111561147357611473612e8a565b14806114ad5750600183828151811061148e5761148e613214565b60200260200101516020015160028111156114ab576114ab612e8a565b145b156115a657600254835173ffffffffffffffffffffffffffffffffffffffff9091169063df871f72908590849081106114e8576114e8613214565b60200260200101516000015185848151811061150657611506613214565b6020026020010151604001516040518363ffffffff1660e01b815260040161152f92919061331c565b602060405180830381865afa15801561154c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611570919061334b565b6115a6576040517ff41a931c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60010161143a565b505050565b80516000908082036115f1576040517f3aee2eec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b6115ff600183613368565b8110156116c6576000611613826001613201565b90505b828110156116bd5784818151811061163057611630613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1685838151811061166057611660613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16036116b5576040517f8dd19e7d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600101611616565b506001016115f4565b5060009392505050565b600080611723600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75490565b905080156117465761173660028261337b565b611741906001613201565b611749565b60005b91505090565b600080600061175e8585611bf6565b9092509050600081600481111561177757611777612e8a565b1480156117af57508573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b806117c057506117c0868686611c3b565b9695505050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921547f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff8116908190600090600716156118395750600381901c60009081526001840160205260409020545b60005b87518110156118b6576118a983838a848151811061185c5761185c613214565b6020026020010151600001518b858151811061187a5761187a613214565b6020026020010151602001518c868151811061189857611898613214565b602002602001015160400151611d98565b909350915060010161183c565b508282146118ef576002840180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff84161790555b600782161561191157600382901c600090815260018501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb67387878760405161194493929190613424565b60405180910390a16119568686612829565b50505050505050565b3330146119c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4c69624469616d6f6e643a2043616c6c6572206e6f742073656c6600000000006044820152606401610360565b565b60008080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b780546060929067ffffffffffffffff811115611a3257611a32612d07565b604051908082528060200260200182016040528015611a5b578160200160208202803683370190505b50825490915060005b81811015611aeb57836000018181548110611a8157611a81613214565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16838281518110611abe57611abe613214565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101611a64565b50909392505050565b6040517f52430c8d0000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906352430c8d90602401602060405180830381865afa158015611b81573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ba59190613510565b6fffffffffffffffffffffffffffffffff16905060008111611bf3576040517fdac5ec8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b90565b6000808251604103611c2c5760208301516040840151606085015160001a611c2087828585612928565b94509450505050611c34565b506000905060025b9250929050565b60008060008573ffffffffffffffffffffffffffffffffffffffff16631626ba7e60e01b8686604051602401611c72929190613542565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909416939093179092529051611cfb919061355b565b600060405180830381855afa9150503d8060008114611d36576040519150601f19603f3d011682016040523d82523d6000602084013e611d3b565b606091505b5091509150818015611d4f57506020815110155b80156117c0575080517f1626ba7e0000000000000000000000000000000000000000000000000000000090611d8d9083016020908101908401613577565b149695505050505050565b600080807f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f90506000845111611e50576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610360565b6000856002811115611e6457611e64612e8a565b0361203457611e8b8660405180606001604052806024815260200161365760249139612a17565b60005b845181101561202e576000858281518110611eab57611eab613214565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c15611f7e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c72656164792065786973747300000000000000000000006064820152608401610360565b7fffffffff0000000000000000000000000000000000000000000000000000000080831660008181526020879052604090207fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608d901b168e17905560e060058e901b811692831c199c909c1690821c179a8190036120125760038c901c600090815260018601602052604081209b909b555b8b61201c81613590565b9c505060019093019250611e8e915050565b5061281d565b600185600281111561204857612048612e8a565b036123385761206f866040518060600160405280602881526020016136a360289139612a17565b60005b845181101561202e57600085828151811061208f5761208f613214565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c308103612164576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4c69624469616d6f6e644375743a2043616e2774207265706c61636520696d6d60448201527f757461626c652066756e6374696f6e00000000000000000000000000000000006064820152608401610360565b8973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361221f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e00000000000000006064820152608401610360565b73ffffffffffffffffffffffffffffffffffffffff81166122c2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e207468617420646f65736e277420657869737400000000000000006064820152608401610360565b507fffffffff0000000000000000000000000000000000000000000000000000000090911660009081526020849052604090206bffffffffffffffffffffffff919091167fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608a901b16179055600101612072565b600285600281111561234c5761234c612e8a565b036127955773ffffffffffffffffffffffffffffffffffffffff8616156123f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d7573742062652061646472657373283029000000000000000000006064820152608401610360565b600388901c6007891660005b86518110156127755760008a900361243d578261241d816135c8565b60008181526001870160205260409020549b5093506007925061244b9050565b81612447816135c8565b9250505b6000806000808a858151811061246357612463613214565b6020908102919091018101517fffffffff0000000000000000000000000000000000000000000000000000000081166000908152918a9052604090912054909150606081901c612535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608401610360565b30606082901c036125c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e0000000000000000000000000000000000006064820152608401610360565b600587901b8f901b94507fffffffff0000000000000000000000000000000000000000000000000000000080861690831614612666577fffffffff000000000000000000000000000000000000000000000000000000008516600090815260208a90526040902080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff83161790555b7fffffffff0000000000000000000000000000000000000000000000000000000091909116600090815260208990526040812055600381901c611fff16925060051b60e01690508582146126fb576000828152600188016020526040902080547fffffffff0000000000000000000000000000000000000000000000000000000080841c19909116908516831c17905561274c565b80837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c817fffffffff0000000000000000000000000000000000000000000000000000000060001b901c198e16179c505b8460000361276a57600086815260018801602052604081208190559c505b505050600101612401565b50806127828360086135fd565b61278c9190613201565b9950505061281d565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560448201527f74416374696f6e000000000000000000000000000000000000000000000000006064820152608401610360565b50959694955050505050565b73ffffffffffffffffffffffffffffffffffffffff8216612848575050565b61286a8260405180606001604052806028815260200161367b60289139612a17565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051612892919061355b565b600060405180830381855af49150503d80600081146128cd576040519150601f19603f3d011682016040523d82523d6000602084013e6128d2565b606091505b509150915081612922578051156128ec5780518082602001fd5b83836040517f192105d7000000000000000000000000000000000000000000000000000000008152600401610360929190613614565b50505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561295f5750600090506003612a0e565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156129b3573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116612a0757600060019250925050612a0e565b9150600090505b94509492505050565b813b8181612922576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103609190613643565b60008083601f840112612a6457600080fd5b50813567ffffffffffffffff811115612a7c57600080fd5b6020830191508360208260051b8501011115611c3457600080fd5b60008060208385031215612aaa57600080fd5b823567ffffffffffffffff811115612ac157600080fd5b612acd85828601612a52565b90969095509350505050565b60008060008060008060608789031215612af257600080fd5b863567ffffffffffffffff80821115612b0a57600080fd5b612b168a838b01612a52565b90985096506020890135915080821115612b2f57600080fd5b612b3b8a838b01612a52565b90965094506040890135915080821115612b5457600080fd5b50612b6189828a01612a52565b979a9699509497509295939492505050565b803573ffffffffffffffffffffffffffffffffffffffff81168114612b9757600080fd5b919050565b600080600080600060608688031215612bb457600080fd5b853567ffffffffffffffff80821115612bcc57600080fd5b612bd889838a01612a52565b9097509550859150612bec60208901612b73565b94506040880135915080821115612c0257600080fd5b818801915088601f830112612c1657600080fd5b813581811115612c2557600080fd5b896020828501011115612c3757600080fd5b9699959850939650602001949392505050565b600060208284031215612c5c57600080fd5b5035919050565b80357fffffffff0000000000000000000000000000000000000000000000000000000081168114612b9757600080fd5b8015158114612ca157600080fd5b50565b60008060408385031215612cb757600080fd5b612cc083612c63565b91506020830135612cd081612c93565b809150509250929050565b60008060408385031215612cee57600080fd5b82359150612cfe60208401612b73565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff81118282101715612d5957612d59612d07565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715612da657612da6612d07565b604052919050565b600067ffffffffffffffff821115612dc857612dc8612d07565b5060051b60200190565b60008060408385031215612de557600080fd5b8235915060208084013567ffffffffffffffff811115612e0457600080fd5b8401601f81018613612e1557600080fd5b8035612e28612e2382612dae565b612d5f565b81815260059190911b82018301908381019088831115612e4757600080fd5b928401925b82841015612e6c57612e5d84612b73565b82529284019290840190612e4c565b80955050505050509250929050565b803560038110612b9757600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60038110612ef0577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b8183526000602080850194508260005b85811015612f49577fffffffff00000000000000000000000000000000000000000000000000000000612f3683612c63565b1687529582019590820190600101612f04565b509495945050505050565b60208082528181018390526000906040808401600586811b8601830188865b8981101561309b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc089840301855281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa18c3603018112612fd457600080fd5b8b01606073ffffffffffffffffffffffffffffffffffffffff612ff683612b73565b168552613004898301612e7b565b6130108a870182612eb9565b50878201357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe183360301811261304557600080fd5b90910188810191903567ffffffffffffffff81111561306357600080fd5b80871b360383131561307457600080fd5b81898701526130868287018285612ef4565b978a0197955050509187019150600101612f73565b50909998505050505050505050565b60006130b8612e2384612dae565b83815260208082019190600586811b8601368111156130d657600080fd5b865b818110156131c557803567ffffffffffffffff808211156130f95760008081fd5b818a0191506060823603121561310f5760008081fd5b613117612d36565b61312083612b73565b815261312d878401612e7b565b87820152604080840135838111156131455760008081fd5b939093019236601f85011261315c57600092508283fd5b8335925061316c612e2384612dae565b83815292871b840188019288810190368511156131895760008081fd5b948901945b848610156131ae5761319f86612c63565b8252948901949089019061318e565b9183019190915250885250509483019483016130d8565b5092979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610c8757610c876131d2565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561325557600080fd5b61325e82612b73565b9392505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261329a57600080fd5b83018035915067ffffffffffffffff8211156132b557600080fd5b602001915036819003821315611c3457600080fd5b600081518084526020808501945080840160005b83811015612f495781517fffffffff0000000000000000000000000000000000000000000000000000000016875295820195908201906001016132de565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000610ee560408301846132ca565b60006020828403121561335d57600080fd5b815161325e81612c93565b81810381811115610c8757610c876131d2565b6000826133b1577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60005b838110156133d15781810151838201526020016133b9565b50506000910152565b600081518084526133f28160208601602086016133b6565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6000606080830181845280875180835260808601915060808160051b87010192506020808a0160005b838110156134d4577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80898703018552815173ffffffffffffffffffffffffffffffffffffffff8151168752838101516134a885890182612eb9565b506040908101519087018890526134c1878901826132ca565b965050938201939082019060010161344d565b505073ffffffffffffffffffffffffffffffffffffffff8916908701525050838103604085015261350581866133da565b979650505050505050565b60006020828403121561352257600080fd5b81516fffffffffffffffffffffffffffffffff8116811461325e57600080fd5b828152604060208201526000610ee560408301846133da565b6000825161356d8184602087016133b6565b9190910192915050565b60006020828403121561358957600080fd5b5051919050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036135c1576135c16131d2565b5060010190565b6000816135d7576135d76131d2565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b8082028115828204841417610c8757610c876131d2565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000610ee560408301846133da565b60208152600061325e60208301846133da56fe4c69624469616d6f6e644375743a2041646420666163657420686173206e6f20636f64654c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a205265706c61636520666163657420686173206e6f20636f6465a2646970667358221220c5a8c10b22f20cde3fe0431ff57305237423677a60888f5b349fc6751336ae1464736f6c63430008150033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100d45760003560e01c806379c0d58d11610081578063afb877bb1161005b578063afb877bb146101d9578063de675a6d146101ec578063e33ecf0a1461023857600080fd5b806379c0d58d14610192578063836d6bfb146101b35780638824a0bb146101c657600080fd5b806326fc3ef4116100b257806326fc3ef4146101145780632f4d98ea1461015c5780633c0985681461017f57600080fd5b806313c34f4b146100d95780631c776dd5146100ee5780631f931c1c14610101575b600080fd5b6100ec6100e7366004612a97565b61024b565b005b6100ec6100fc366004612ad9565b6104df565b6100ec61010f366004612b9c565b610a76565b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9bf546040516fffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b61016f61016a366004612c4a565b610c7b565b6040519015158152602001610153565b6100ec61018d366004612ca4565b610c8d565b6101a56101a0366004612c4a565b610df2565b604051908152602001610153565b61016f6101c1366004612cdb565b610e4c565b6100ec6101d4366004612dd2565b610eed565b6100ec6101e7366004612a97565b610fe1565b6102137f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610153565b6101a5610246366004612a97565b61130e565b3360009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff1615801561028a5750303314155b156102c1576040517f6238ee3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610369576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064015b60405180910390fd5b60008080527f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be6020527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d3906103be848461130e565b60008181526020848152604080832033845290915290205490915060ff16610412576040517fedc5708300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051808201825260008082526020808301828152858352868252848320338452909152908390209151825491517fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000009092169015157fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff161761010067ffffffffffffffff90921691909102179055517f3c3d8c1f0b0faff6fe0ace6b485d0595a0106dce9e303f956fd941ebdbe9a98e906104d19086908690612f54565b60405180910390a150505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610582576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b8281146105bb576040517fe854148500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6105cd6105c886886130aa565b611435565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b754600003610650576040517fa788861700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061065c878761130e565b905061069a8585808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506115b392505050565b506106d881868680806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250610eed92505050565b60006106e382610c7b565b90506000816106f35760016106f6565b60005b60ff169050806107046116d0565b61070e9190613201565b61071784610df2565b6107219088613201565b1015610759576040517f709fb08000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805b878110156109a0576107d989898381811061077a5761077a613214565b905060200201602081019061078f9190613243565b73ffffffffffffffffffffffffffffffffffffffff1660009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff1690565b1580156108225750308989838181106107f4576107f4613214565b90506020020160208101906108099190613243565b73ffffffffffffffffffffffffffffffffffffffff1614155b15610859576040517f7b2cbbb400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3089898381811061086c5761086c613214565b90506020020160208101906108819190613243565b73ffffffffffffffffffffffffffffffffffffffff16036108d95783156108d4576040517fee21708000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600191505b6109628989838181106108ee576108ee613214565b90506020020160208101906109039190613243565b8689898581811061091657610916613214565b90506020028101906109289190613265565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061174f92505050565b610998576040517fac3d341600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60010161075d565b50801580156109ad575082155b156109e4576040517f6d21730400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9bf80546fffffffffffffffffffffffffffffffff808216600101167fffffffffffffffffffffffffffffffff00000000000000000000000000000000909116179055610a6a610a538a8c6130aa565b6000604051806020016040528060008152506117ca565b50505050505050505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610b19576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b610b2161195f565b610b2e6105c885876130aa565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75415610baf576040517fa788861700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff831615610bfd576040517f871cb76100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be5b600190810180547fffffffffffffffffffffffffffffffff0000000000000000000000000000000081166fffffffffffffffffffffffffffffffff91821690930116919091179055610c74610a5385876130aa565b5050505050565b6000610c878230610e4c565b92915050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610d30576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b610d3861195f565b7fffffffff00000000000000000000000000000000000000000000000000000000821660008181527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4922602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001685151590811790915582519384529083015280517f4e6bd17989efa6d6a9607ccaac1bba27b29f99622bc830d99a3a9883b21a19c79281900390910190a15050565b600080610dfd6119ca565b805190915060005b81811015610e4457610e3085848381518110610e2357610e23613214565b6020026020010151610e4c565b15610e3c578360010193505b600101610e05565b505050919050565b60008281527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d36020818152604080842073ffffffffffffffffffffffffffffffffffffffff8616855290915282205460ff168015610ee5575060008481526020828152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152902054610100900467ffffffffffffffff1642105b949350505050565b6000610ef76119ca565b805183519192509060005b82811015610fd957610f2086858381518110610e2357610e23613214565b15610fd15760005b82811015610fcf57848281518110610f4257610f42613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16868281518110610f7257610f72613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603610fc7576040517f50f5729f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600101610f28565b505b600101610f02565b505050505050565b3360009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff161580156110205750303314155b15611057576040517f6238ee3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff9081164290911610156110fa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75460000361117d576040517f3a76e1f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080527f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be6020527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d36111d36105c883856130aa565b60006111df848461130e565b905060006111eb611af4565b6111f59042613201565b6040805180820182526001815267ffffffffffffffff838116602080840191825260008881528982528581203382529091528490209251835491517fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000009092169015157fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff16176101009190921602179055519091507f6248ff757895beed7d43d135bccf59a26b7fbdf0fe8233487c44e82c0f266ba3906112b89087908790612f54565b60405180910390a16112c86116d0565b6112d183610df2565b101580156112e357506112e382610c7b565b15610c74577f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be610c1f565b60008282604051602001611323929190612f54565b6040516020818303038152906040528051906020012030466113627f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be90565b6001015460408051602081019590955273ffffffffffffffffffffffffffffffffffffffff9093169284019290925260608301526fffffffffffffffffffffffffffffffff16608082015260a001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905280516020918201207f19457468657265756d205369676e6564204d6573736167653a0a33320000000091830191909152603c820152605c0160405160208183030381529060405280519060200120905092915050565b805160005b818110156115ae57600083828151811061145657611456613214565b602002602001015160200151600281111561147357611473612e8a565b14806114ad5750600183828151811061148e5761148e613214565b60200260200101516020015160028111156114ab576114ab612e8a565b145b156115a657600254835173ffffffffffffffffffffffffffffffffffffffff9091169063df871f72908590849081106114e8576114e8613214565b60200260200101516000015185848151811061150657611506613214565b6020026020010151604001516040518363ffffffff1660e01b815260040161152f92919061331c565b602060405180830381865afa15801561154c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611570919061334b565b6115a6576040517ff41a931c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60010161143a565b505050565b80516000908082036115f1576040517f3aee2eec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b6115ff600183613368565b8110156116c6576000611613826001613201565b90505b828110156116bd5784818151811061163057611630613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1685838151811061166057611660613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16036116b5576040517f8dd19e7d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600101611616565b506001016115f4565b5060009392505050565b600080611723600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75490565b905080156117465761173660028261337b565b611741906001613201565b611749565b60005b91505090565b600080600061175e8585611bf6565b9092509050600081600481111561177757611777612e8a565b1480156117af57508573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b806117c057506117c0868686611c3b565b9695505050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921547f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff8116908190600090600716156118395750600381901c60009081526001840160205260409020545b60005b87518110156118b6576118a983838a848151811061185c5761185c613214565b6020026020010151600001518b858151811061187a5761187a613214565b6020026020010151602001518c868151811061189857611898613214565b602002602001015160400151611d98565b909350915060010161183c565b508282146118ef576002840180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff84161790555b600782161561191157600382901c600090815260018501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb67387878760405161194493929190613424565b60405180910390a16119568686612829565b50505050505050565b3330146119c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4c69624469616d6f6e643a2043616c6c6572206e6f742073656c6600000000006044820152606401610360565b565b60008080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b780546060929067ffffffffffffffff811115611a3257611a32612d07565b604051908082528060200260200182016040528015611a5b578160200160208202803683370190505b50825490915060005b81811015611aeb57836000018181548110611a8157611a81613214565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16838281518110611abe57611abe613214565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101611a64565b50909392505050565b6040517f52430c8d0000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906352430c8d90602401602060405180830381865afa158015611b81573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ba59190613510565b6fffffffffffffffffffffffffffffffff16905060008111611bf3576040517fdac5ec8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b90565b6000808251604103611c2c5760208301516040840151606085015160001a611c2087828585612928565b94509450505050611c34565b506000905060025b9250929050565b60008060008573ffffffffffffffffffffffffffffffffffffffff16631626ba7e60e01b8686604051602401611c72929190613542565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909416939093179092529051611cfb919061355b565b600060405180830381855afa9150503d8060008114611d36576040519150601f19603f3d011682016040523d82523d6000602084013e611d3b565b606091505b5091509150818015611d4f57506020815110155b80156117c0575080517f1626ba7e0000000000000000000000000000000000000000000000000000000090611d8d9083016020908101908401613577565b149695505050505050565b600080807f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f90506000845111611e50576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610360565b6000856002811115611e6457611e64612e8a565b0361203457611e8b8660405180606001604052806024815260200161365760249139612a17565b60005b845181101561202e576000858281518110611eab57611eab613214565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c15611f7e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c72656164792065786973747300000000000000000000006064820152608401610360565b7fffffffff0000000000000000000000000000000000000000000000000000000080831660008181526020879052604090207fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608d901b168e17905560e060058e901b811692831c199c909c1690821c179a8190036120125760038c901c600090815260018601602052604081209b909b555b8b61201c81613590565b9c505060019093019250611e8e915050565b5061281d565b600185600281111561204857612048612e8a565b036123385761206f866040518060600160405280602881526020016136a360289139612a17565b60005b845181101561202e57600085828151811061208f5761208f613214565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c308103612164576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4c69624469616d6f6e644375743a2043616e2774207265706c61636520696d6d60448201527f757461626c652066756e6374696f6e00000000000000000000000000000000006064820152608401610360565b8973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361221f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e00000000000000006064820152608401610360565b73ffffffffffffffffffffffffffffffffffffffff81166122c2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e207468617420646f65736e277420657869737400000000000000006064820152608401610360565b507fffffffff0000000000000000000000000000000000000000000000000000000090911660009081526020849052604090206bffffffffffffffffffffffff919091167fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608a901b16179055600101612072565b600285600281111561234c5761234c612e8a565b036127955773ffffffffffffffffffffffffffffffffffffffff8616156123f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d7573742062652061646472657373283029000000000000000000006064820152608401610360565b600388901c6007891660005b86518110156127755760008a900361243d578261241d816135c8565b60008181526001870160205260409020549b5093506007925061244b9050565b81612447816135c8565b9250505b6000806000808a858151811061246357612463613214565b6020908102919091018101517fffffffff0000000000000000000000000000000000000000000000000000000081166000908152918a9052604090912054909150606081901c612535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608401610360565b30606082901c036125c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e0000000000000000000000000000000000006064820152608401610360565b600587901b8f901b94507fffffffff0000000000000000000000000000000000000000000000000000000080861690831614612666577fffffffff000000000000000000000000000000000000000000000000000000008516600090815260208a90526040902080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff83161790555b7fffffffff0000000000000000000000000000000000000000000000000000000091909116600090815260208990526040812055600381901c611fff16925060051b60e01690508582146126fb576000828152600188016020526040902080547fffffffff0000000000000000000000000000000000000000000000000000000080841c19909116908516831c17905561274c565b80837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c817fffffffff0000000000000000000000000000000000000000000000000000000060001b901c198e16179c505b8460000361276a57600086815260018801602052604081208190559c505b505050600101612401565b50806127828360086135fd565b61278c9190613201565b9950505061281d565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560448201527f74416374696f6e000000000000000000000000000000000000000000000000006064820152608401610360565b50959694955050505050565b73ffffffffffffffffffffffffffffffffffffffff8216612848575050565b61286a8260405180606001604052806028815260200161367b60289139612a17565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051612892919061355b565b600060405180830381855af49150503d80600081146128cd576040519150601f19603f3d011682016040523d82523d6000602084013e6128d2565b606091505b509150915081612922578051156128ec5780518082602001fd5b83836040517f192105d7000000000000000000000000000000000000000000000000000000008152600401610360929190613614565b50505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561295f5750600090506003612a0e565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156129b3573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116612a0757600060019250925050612a0e565b9150600090505b94509492505050565b813b8181612922576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103609190613643565b60008083601f840112612a6457600080fd5b50813567ffffffffffffffff811115612a7c57600080fd5b6020830191508360208260051b8501011115611c3457600080fd5b60008060208385031215612aaa57600080fd5b823567ffffffffffffffff811115612ac157600080fd5b612acd85828601612a52565b90969095509350505050565b60008060008060008060608789031215612af257600080fd5b863567ffffffffffffffff80821115612b0a57600080fd5b612b168a838b01612a52565b90985096506020890135915080821115612b2f57600080fd5b612b3b8a838b01612a52565b90965094506040890135915080821115612b5457600080fd5b50612b6189828a01612a52565b979a9699509497509295939492505050565b803573ffffffffffffffffffffffffffffffffffffffff81168114612b9757600080fd5b919050565b600080600080600060608688031215612bb457600080fd5b853567ffffffffffffffff80821115612bcc57600080fd5b612bd889838a01612a52565b9097509550859150612bec60208901612b73565b94506040880135915080821115612c0257600080fd5b818801915088601f830112612c1657600080fd5b813581811115612c2557600080fd5b896020828501011115612c3757600080fd5b9699959850939650602001949392505050565b600060208284031215612c5c57600080fd5b5035919050565b80357fffffffff0000000000000000000000000000000000000000000000000000000081168114612b9757600080fd5b8015158114612ca157600080fd5b50565b60008060408385031215612cb757600080fd5b612cc083612c63565b91506020830135612cd081612c93565b809150509250929050565b60008060408385031215612cee57600080fd5b82359150612cfe60208401612b73565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff81118282101715612d5957612d59612d07565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715612da657612da6612d07565b604052919050565b600067ffffffffffffffff821115612dc857612dc8612d07565b5060051b60200190565b60008060408385031215612de557600080fd5b8235915060208084013567ffffffffffffffff811115612e0457600080fd5b8401601f81018613612e1557600080fd5b8035612e28612e2382612dae565b612d5f565b81815260059190911b82018301908381019088831115612e4757600080fd5b928401925b82841015612e6c57612e5d84612b73565b82529284019290840190612e4c565b80955050505050509250929050565b803560038110612b9757600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60038110612ef0577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b8183526000602080850194508260005b85811015612f49577fffffffff00000000000000000000000000000000000000000000000000000000612f3683612c63565b1687529582019590820190600101612f04565b509495945050505050565b60208082528181018390526000906040808401600586811b8601830188865b8981101561309b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc089840301855281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa18c3603018112612fd457600080fd5b8b01606073ffffffffffffffffffffffffffffffffffffffff612ff683612b73565b168552613004898301612e7b565b6130108a870182612eb9565b50878201357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe183360301811261304557600080fd5b90910188810191903567ffffffffffffffff81111561306357600080fd5b80871b360383131561307457600080fd5b81898701526130868287018285612ef4565b978a0197955050509187019150600101612f73565b50909998505050505050505050565b60006130b8612e2384612dae565b83815260208082019190600586811b8601368111156130d657600080fd5b865b818110156131c557803567ffffffffffffffff808211156130f95760008081fd5b818a0191506060823603121561310f5760008081fd5b613117612d36565b61312083612b73565b815261312d878401612e7b565b87820152604080840135838111156131455760008081fd5b939093019236601f85011261315c57600092508283fd5b8335925061316c612e2384612dae565b83815292871b840188019288810190368511156131895760008081fd5b948901945b848610156131ae5761319f86612c63565b8252948901949089019061318e565b9183019190915250885250509483019483016130d8565b5092979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610c8757610c876131d2565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561325557600080fd5b61325e82612b73565b9392505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261329a57600080fd5b83018035915067ffffffffffffffff8211156132b557600080fd5b602001915036819003821315611c3457600080fd5b600081518084526020808501945080840160005b83811015612f495781517fffffffff0000000000000000000000000000000000000000000000000000000016875295820195908201906001016132de565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000610ee560408301846132ca565b60006020828403121561335d57600080fd5b815161325e81612c93565b81810381811115610c8757610c876131d2565b6000826133b1577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60005b838110156133d15781810151838201526020016133b9565b50506000910152565b600081518084526133f28160208601602086016133b6565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6000606080830181845280875180835260808601915060808160051b87010192506020808a0160005b838110156134d4577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80898703018552815173ffffffffffffffffffffffffffffffffffffffff8151168752838101516134a885890182612eb9565b506040908101519087018890526134c1878901826132ca565b965050938201939082019060010161344d565b505073ffffffffffffffffffffffffffffffffffffffff8916908701525050838103604085015261350581866133da565b979650505050505050565b60006020828403121561352257600080fd5b81516fffffffffffffffffffffffffffffffff8116811461325e57600080fd5b828152604060208201526000610ee560408301846133da565b6000825161356d8184602087016133b6565b9190910192915050565b60006020828403121561358957600080fd5b5051919050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036135c1576135c16131d2565b5060010190565b6000816135d7576135d76131d2565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b8082028115828204841417610c8757610c876131d2565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000610ee560408301846133da565b60208152600061325e60208301846133da56fe4c69624469616d6f6e644375743a2041646420666163657420686173206e6f20636f64654c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a205265706c61636520666163657420686173206e6f20636f6465a2646970667358221220c5a8c10b22f20cde3fe0431ff57305237423677a60888f5b349fc6751336ae1464736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "Responsible for adding/removing/replace facets in Barz", + "kind": "dev", + "methods": { + "_checkDuplicateOnChainApprover(bytes32,address[])": { + "params": { + "_approvers": "List of approver addresses", + "_diamondCutHash": "Hash of diamondCut information including the facet addresses and function selectors" + } + }, + "approveDiamondCut((address,uint8,bytes4[])[])": { + "params": { + "_diamondCut": "Contains the facet addresses and function selectors" + } + }, + "constructor": { + "params": { + "_securityManager": "Security Manager contract that holds the security related variables for all wallets" + } + }, + "diamondCut((address,uint8,bytes4[])[],address,bytes)": { + "params": { + "_diamondCut": "Contains the facet addresses and function selectors", + "_init": "The address of the contract or facet to execute _calldata. It's prohibited in Barz" + } + }, + "diamondCutWithGuardian((address,uint8,bytes4[])[],address[],bytes[])": { + "params": { + "_approvers": "Guardian or owner address that approves the diamond cut", + "_diamondCut": "Contains the facet addresses and function selectors", + "_signatures": "Signature of Guardians or owner that approves the diamond cut" + } + }, + "getDiamondCutApprovalCountWithTimeValidity(bytes32)": { + "params": { + "_diamondCutHash": "Hash of diamondCut information including the facet addresses and function selectors" + } + }, + "getDiamondCutHash((address,uint8,bytes4[])[])": { + "params": { + "_diamondCut": "Contains the facet addresses and function selectors" + }, + "returns": { + "cutHash": "Diamond Cut Hash" + } + }, + "getDiamondCutNonce()": { + "details": "This method fetches the nonce from diamond cut storage", + "returns": { + "cutNonce": "Nonce of diamond cut to protect from reply attacks" + } + }, + "getOwnerCutApprovalWithTimeValidity(bytes32)": { + "params": { + "_diamondCutHash": "Hash of diamondCut information including the facet addresses and function selectors" + }, + "returns": { + "isApprovedByOwner": "Bool value showing if the owner approved the cut" + } + }, + "isCutApproved(bytes32,address)": { + "params": { + "_approver": "Address of approver", + "_diamondCutHash": "Hash of diamondCut information including the facet addresses and function selectors" + }, + "returns": { + "isApproved": "Bool value showing if the approver approved the cut" + } + }, + "revokeDiamondCutApproval((address,uint8,bytes4[])[])": { + "params": { + "_diamondCut": "Contains the facet addresses and function selectors" + } + }, + "updateSupportsInterface(bytes4,bool)": { + "params": { + "_flag": "Bool value to update the mapping of the given interface ID", + "_interfaceId": "InterfaceID to update the mapping" + } + } + }, + "title": "DiamondCut Facet", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "_checkDuplicateOnChainApprover(bytes32,address[])": { + "notice": "Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval Approvers who approved on-chain should not be included in the off-chain approval" + }, + "approveDiamondCut((address,uint8,bytes4[])[])": { + "notice": "Approves diamond cut. This can only be called directly from guardian or owner" + }, + "constructor": { + "notice": "This constructor sets the Security Manager address which is an immutable variable. Immutable variables do not impact the storage of diamond" + }, + "diamondCut((address,uint8,bytes4[])[],address,bytes)": { + "notice": "Add/replace/remove any number of functions and optionally execute a function with delegatecall when guardians don't exist" + }, + "diamondCutWithGuardian((address,uint8,bytes4[])[],address[],bytes[])": { + "notice": "Add/replace/remove any number of functions and optionally execute a function with delegatecall when guardians exist" + }, + "getDiamondCutApprovalCountWithTimeValidity(bytes32)": { + "notice": "Gets the number of approvals of diamond cut from guardians" + }, + "getDiamondCutHash((address,uint8,bytes4[])[])": { + "notice": "Returns the diamond cut hash. This function ensures that this hash is safe from replay attack by including salt, address, chainId, and nonce, etc." + }, + "getDiamondCutNonce()": { + "notice": "Returns the diamond cut nonce of this wallet" + }, + "getOwnerCutApprovalWithTimeValidity(bytes32)": { + "notice": "Returns if the owner has approved the diamond cut" + }, + "isCutApproved(bytes32,address)": { + "notice": "Returns if the given approver has approved the diamond cut" + }, + "revokeDiamondCutApproval((address,uint8,bytes4[])[])": { + "notice": "Revokes the approval of diamond cut. This can only be called directly from guardian or owner" + }, + "updateSupportsInterface(bytes4,bool)": { + "notice": "Updates the flag for the interfaceId" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 27823, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "s", + "offset": 0, + "slot": "0", + "type": "t_struct(AppStorage)27570_storage" + } + ], + "types": { + "t_bytes4": { + "encoding": "inplace", + "label": "bytes4", + "numberOfBytes": "4" + }, + "t_contract(IEntryPoint)12286": { + "encoding": "inplace", + "label": "contract IEntryPoint", + "numberOfBytes": "20" + }, + "t_contract(IFacetRegistry)26105": { + "encoding": "inplace", + "label": "contract IFacetRegistry", + "numberOfBytes": "20" + }, + "t_mapping(t_uint256,t_struct(InitializersStorage)27549_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => struct InitializersStorage)", + "numberOfBytes": "32", + "value": "t_struct(InitializersStorage)27549_storage" + }, + "t_mapping(t_uint256,t_struct(Lock)27542_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => struct Lock)", + "numberOfBytes": "32", + "value": "t_struct(Lock)27542_storage" + }, + "t_struct(AppStorage)27570_storage": { + "encoding": "inplace", + "label": "struct AppStorage", + "members": [ + { + "astId": 27554, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "initStorage", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_uint256,t_struct(InitializersStorage)27549_storage)" + }, + { + "astId": 27556, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "signerMigration", + "offset": 0, + "slot": "1", + "type": "t_uint8" + }, + { + "astId": 27558, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "validateOwnerSignatureSelector", + "offset": 1, + "slot": "1", + "type": "t_bytes4" + }, + { + "astId": 27561, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "entryPoint", + "offset": 5, + "slot": "1", + "type": "t_contract(IEntryPoint)12286" + }, + { + "astId": 27564, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "facetRegistry", + "offset": 0, + "slot": "2", + "type": "t_contract(IFacetRegistry)26105" + }, + { + "astId": 27569, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "locks", + "offset": 0, + "slot": "3", + "type": "t_mapping(t_uint256,t_struct(Lock)27542_storage)" + } + ], + "numberOfBytes": "128" + }, + "t_struct(InitializersStorage)27549_storage": { + "encoding": "inplace", + "label": "struct InitializersStorage", + "members": [ + { + "astId": 27544, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "signerInitialized", + "offset": 0, + "slot": "0", + "type": "t_uint8" + }, + { + "astId": 27546, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "accountInitialized", + "offset": 1, + "slot": "0", + "type": "t_uint8" + }, + { + "astId": 27548, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "restrictionsInitialized", + "offset": 2, + "slot": "0", + "type": "t_uint8" + } + ], + "numberOfBytes": "32" + }, + "t_struct(Lock)27542_storage": { + "encoding": "inplace", + "label": "struct Lock", + "members": [ + { + "astId": 27539, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "release", + "offset": 0, + "slot": "0", + "type": "t_uint64" + }, + { + "astId": 27541, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "locker", + "offset": 8, + "slot": "0", + "type": "t_bytes4" + } + ], + "numberOfBytes": "32" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint64": { + "encoding": "inplace", + "label": "uint64", + "numberOfBytes": "8" + }, + "t_uint8": { + "encoding": "inplace", + "label": "uint8", + "numberOfBytes": "1" + } + } + } +} \ No newline at end of file diff --git a/deployments/arbitrum/DiamondLoupeFacet.json b/deployments/arbitrum/DiamondLoupeFacet.json new file mode 100644 index 0000000..25688b3 --- /dev/null +++ b/deployments/arbitrum/DiamondLoupeFacet.json @@ -0,0 +1,306 @@ +{ + "address": "0xCe36b85d12D81cd619C745c7717f3396E184Ac7C", + "abi": [ + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_functionSelector", + "type": "bytes4" + } + ], + "name": "facetAddress", + "outputs": [ + { + "internalType": "address", + "name": "facetAddress_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_functionSelector", + "type": "bytes4" + } + ], + "name": "facetAddressFromStorage", + "outputs": [ + { + "internalType": "address", + "name": "facetAddress_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetAddresses", + "outputs": [ + { + "internalType": "address[]", + "name": "facetAddresses_", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetAddressesFromStorage", + "outputs": [ + { + "internalType": "address[]", + "name": "facetAddresses_", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_facet", + "type": "address" + } + ], + "name": "facetFunctionSelectors", + "outputs": [ + { + "internalType": "bytes4[]", + "name": "facetFunctionSelectors_", + "type": "bytes4[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_facet", + "type": "address" + } + ], + "name": "facetFunctionSelectorsFromStorage", + "outputs": [ + { + "internalType": "bytes4[]", + "name": "facetFunctionSelectors_", + "type": "bytes4[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facets", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondLoupe.Facet[]", + "name": "facets_", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetsFromStorage", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondLoupe.Facet[]", + "name": "facets_", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "isSupported", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0x49ce7cd40bd71414247dabc5c81c43696ca7634274088d8b1ab8159b331869f0", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 1, + "gasUsed": "13094913", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x43907f558b193e08683a031a8497797b98cf04cbd62a53009dff623000217d45", + "transactionHash": "0x49ce7cd40bd71414247dabc5c81c43696ca7634274088d8b1ab8159b331869f0", + "logs": [], + "blockNumber": 152284114, + "cumulativeGasUsed": "13094913", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 3, + "solcInputHash": "4356503edd8ae34e73cb6dd1c8e2fc8a", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_functionSelector\",\"type\":\"bytes4\"}],\"name\":\"facetAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"facetAddress_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_functionSelector\",\"type\":\"bytes4\"}],\"name\":\"facetAddressFromStorage\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"facetAddress_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetAddresses\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"facetAddresses_\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetAddressesFromStorage\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"facetAddresses_\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_facet\",\"type\":\"address\"}],\"name\":\"facetFunctionSelectors\",\"outputs\":[{\"internalType\":\"bytes4[]\",\"name\":\"facetFunctionSelectors_\",\"type\":\"bytes4[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_facet\",\"type\":\"address\"}],\"name\":\"facetFunctionSelectorsFromStorage\",\"outputs\":[{\"internalType\":\"bytes4[]\",\"name\":\"facetFunctionSelectors_\",\"type\":\"bytes4[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facets\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondLoupe.Facet[]\",\"name\":\"facets_\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetsFromStorage\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondLoupe.Facet[]\",\"name\":\"facets_\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isSupported\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"DiamondLoupe contract compatible with EIP-2535\",\"kind\":\"dev\",\"methods\":{\"facetAddress(bytes4)\":{\"details\":\"If facet is not found return address(0).\",\"params\":{\"_functionSelector\":\"The function selector.\"},\"returns\":{\"facetAddress_\":\"The facet address.\"}},\"facetAddressFromStorage(bytes4)\":{\"params\":{\"_functionSelector\":\"Function selector to fetch the facet address from diamond storage\"},\"returns\":{\"facetAddress_\":\"Facet address mapped with the function selector\"}},\"facetAddresses()\":{\"returns\":{\"facetAddresses_\":\"facetAddresses_\"}},\"facetAddressesFromStorage()\":{\"returns\":{\"facetAddresses_\":\"All facet addresses attached directly to diamond storage\"}},\"facetFunctionSelectors(address)\":{\"params\":{\"_facet\":\"The facet address.\"},\"returns\":{\"facetFunctionSelectors_\":\"facetFunctionSelectors_\"}},\"facetFunctionSelectorsFromStorage(address)\":{\"params\":{\"_facet\":\"Facet address to fetch the facet function selectors from diamond storage\"},\"returns\":{\"facetFunctionSelectors_\":\"Facet function selectors of the given facet address\"}},\"facets()\":{\"details\":\"Barz uses a special architecture called default fallback handler. Default Fallback handler is used as a middleware that holds the mapping of facet function selector and facet address that Barz uses. This helps Barz to reduce significant amount of gas during the initialization process. Hence, this method aggregates both the facet information from DefaulFallbackHandler and in diamond storage and shows the data to users.\",\"returns\":{\"facets_\":\"Facet\"}},\"facetsFromStorage()\":{\"returns\":{\"facets_\":\"Facet information attached directly to diamond storage\"}},\"supportsInterface(bytes4)\":{\"params\":{\"_interfaceId\":\"Interface ID for detecting the interface\"},\"returns\":{\"isSupported\":\"Bool value showing if the standard is supported in the contract\"}}},\"title\":\"DiamondLoupe Facet\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"facetAddress(bytes4)\":{\"notice\":\"Gets the facet that supports the given selector.\"},\"facetAddressFromStorage(bytes4)\":{\"notice\":\"Returns the facet address attached to the given function selector. This excludes the facets from the default fallback handler\"},\"facetAddresses()\":{\"notice\":\"Get all the facet addresses used by Barz.\"},\"facetAddressesFromStorage()\":{\"notice\":\"Returns all facet addresses attached directly to diamond storage. This excludes the facets from the default fallback handler\"},\"facetFunctionSelectors(address)\":{\"notice\":\"Gets all the function selectors provided by a facet.\"},\"facetFunctionSelectorsFromStorage(address)\":{\"notice\":\"Returns function selectors of given facet address attached directly to diamond storage. This excludes the facets from the default fallback handler\"},\"facets()\":{\"notice\":\"Gets all facets and their selectors.\"},\"facetsFromStorage()\":{\"notice\":\"Returns the facet from the diamond storage. This excludes the facets from the default fallback handler\"},\"supportsInterface(bytes4)\":{\"notice\":\"SupportInterface to be compatible with EIP 165\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/base/DiamondLoupeFacet.sol\":\"DiamondLoupeFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/introspection/IERC165.sol\\\";\\n\\n/**\\n * @dev _Available since v3.1._\\n */\\ninterface IERC1155Receiver is IERC165 {\\n /**\\n * @dev Handles the receipt of a single ERC1155 token type. This function is\\n * called at the end of a `safeTransferFrom` after the balance has been updated.\\n *\\n * NOTE: To accept the transfer, this must return\\n * `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))`\\n * (i.e. 0xf23a6e61, or its own function selector).\\n *\\n * @param operator The address which initiated the transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param id The ID of the token being transferred\\n * @param value The amount of tokens being transferred\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155Received(\\n address operator,\\n address from,\\n uint256 id,\\n uint256 value,\\n bytes calldata data\\n ) external returns (bytes4);\\n\\n /**\\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\\n * is called at the end of a `safeBatchTransferFrom` after the balances have\\n * been updated.\\n *\\n * NOTE: To accept the transfer(s), this must return\\n * `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))`\\n * (i.e. 0xbc197c81, or its own function selector).\\n *\\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155BatchReceived(\\n address operator,\\n address from,\\n uint256[] calldata ids,\\n uint256[] calldata values,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xeb373f1fdc7b755c6a750123a9b9e3a8a02c1470042fd6505d875000a80bde0b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title ERC721 token receiver interface\\n * @dev Interface for any contract that wants to support safeTransfers\\n * from ERC721 asset contracts.\\n */\\ninterface IERC721Receiver {\\n /**\\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\\n * by `operator` from `from`, this function is called.\\n *\\n * It must return its Solidity selector to confirm the token transfer.\\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\\n *\\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\\n */\\n function onERC721Received(\\n address operator,\\n address from,\\n uint256 tokenId,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\\n *\\n * Accounts can be notified of {IERC777} tokens being sent to them by having a\\n * contract implement this interface (contract holders can be their own\\n * implementer) and registering it on the\\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\\n *\\n * See {IERC1820Registry} and {ERC1820Implementer}.\\n */\\ninterface IERC777Recipient {\\n /**\\n * @dev Called by an {IERC777} token contract whenever tokens are being\\n * moved or created into a registered account (`to`). The type of operation\\n * is conveyed by `from` being the zero address or not.\\n *\\n * This call occurs _after_ the token contract's state is updated, so\\n * {IERC777-balanceOf}, etc., can be used to query the post-operation state.\\n *\\n * This function may revert to prevent the operation from being executed.\\n */\\n function tokensReceived(\\n address operator,\\n address from,\\n address to,\\n uint256 amount,\\n bytes calldata userData,\\n bytes calldata operatorData\\n ) external;\\n}\\n\",\"keccak256\":\"0x1a5d61db2733202ba361e6d6741cd2e662380e22b80e987eacfc91973f2267dc\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"contracts/facets/base/DiamondLoupeFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IERC777Recipient} from \\\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\\\";\\nimport {IERC165} from \\\"../../interfaces/ERC/IERC165.sol\\\";\\nimport {IERC1271} from \\\"../../interfaces/ERC/IERC1271.sol\\\";\\nimport {IERC677Receiver} from \\\"../../interfaces/ERC/IERC677Receiver.sol\\\";\\nimport {IERC721Receiver} from \\\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\\\";\\nimport {IERC1155Receiver} from \\\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\\\";\\nimport {LibDiamond} from \\\"../../libraries/LibDiamond.sol\\\";\\nimport {LibLoupe} from \\\"../../libraries/LibLoupe.sol\\\";\\nimport {LibUtils} from \\\"../../libraries/LibUtils.sol\\\";\\nimport {IDiamondCut} from \\\"../../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IStorageLoupe} from \\\"./interfaces/IStorageLoupe.sol\\\";\\nimport {IDiamondLoupe} from \\\"./interfaces/IDiamondLoupe.sol\\\";\\n\\n/**\\n * @title DiamondLoupe Facet\\n * @dev DiamondLoupe contract compatible with EIP-2535\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract DiamondLoupeFacet is IDiamondLoupe, IStorageLoupe, IERC165 {\\n // Diamond Loupe Functions\\n ////////////////////////////////////////////////////////////////////\\n /// These functions are expected to be called frequently by tools off-chain.\\n\\n /**\\n * @notice Gets all facets and their selectors.\\n * @dev Barz uses a special architecture called default fallback handler. Default Fallback handler is used as a middleware\\n * that holds the mapping of facet function selector and facet address that Barz uses. This helps Barz to reduce\\n * significant amount of gas during the initialization process.\\n * Hence, this method aggregates both the facet information from DefaulFallbackHandler and in diamond storage and shows the data to users.\\n * @return facets_ Facet\\n */\\n function facets() public view override returns (Facet[] memory facets_) {\\n Facet[] memory defaultFacet = LibDiamond\\n .diamondStorage()\\n .defaultFallbackHandler\\n .facets();\\n Facet[] memory _facets = LibLoupe.facets();\\n uint256 numFacets = _facets.length;\\n bytes4[] memory keys;\\n address[] memory values;\\n for (uint256 i; i < numFacets; ) {\\n uint256 selectorsLength = _facets[i].functionSelectors.length;\\n for (uint256 j; j < selectorsLength; ) {\\n (keys, values) = LibUtils.setValue(\\n keys,\\n values,\\n _facets[i].functionSelectors[j],\\n _facets[i].facetAddress\\n );\\n unchecked {\\n ++j;\\n }\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n {\\n bool iIncrement;\\n for (uint256 i; i < defaultFacet.length; ) {\\n bool jIncrement;\\n for (\\n uint256 j;\\n j < defaultFacet[i].functionSelectors.length;\\n\\n ) {\\n if (\\n LibUtils.getValue(\\n keys,\\n values,\\n defaultFacet[i].functionSelectors[j]\\n ) != address(0)\\n ) {\\n if (defaultFacet[i].functionSelectors.length == 1) {\\n defaultFacet = LibUtils.removeFacetElement(\\n defaultFacet,\\n i\\n );\\n iIncrement = true;\\n break;\\n }\\n defaultFacet[i].functionSelectors = LibUtils\\n .removeElement(\\n defaultFacet[i].functionSelectors,\\n j\\n );\\n jIncrement = true;\\n }\\n if (!jIncrement) {\\n unchecked {\\n ++j;\\n }\\n } else {\\n jIncrement = false;\\n }\\n }\\n if (!iIncrement) {\\n unchecked {\\n ++i;\\n }\\n } else {\\n iIncrement = false;\\n }\\n }\\n }\\n {\\n uint256 facetLength = numFacets + defaultFacet.length;\\n facets_ = new Facet[](facetLength);\\n uint256 defaultFacetIndex;\\n for (uint256 i; i < facetLength; ) {\\n if (i < numFacets) {\\n facets_[i] = _facets[i];\\n bool jIncrementor;\\n for (uint256 j; j < defaultFacet.length; ) {\\n if (\\n facets_[i].facetAddress ==\\n defaultFacet[j].facetAddress\\n ) {\\n facets_[i].functionSelectors = LibUtils.mergeArrays(\\n _facets[i].functionSelectors,\\n defaultFacet[j].functionSelectors\\n );\\n defaultFacet = LibUtils.removeFacetElement(\\n defaultFacet,\\n j\\n );\\n jIncrementor = true;\\n {\\n facets_ = LibUtils.removeFacetElement(\\n facets_,\\n facets_.length - 1\\n );\\n }\\n --facetLength;\\n }\\n if (!jIncrementor) {\\n unchecked {\\n ++j;\\n }\\n } else {\\n jIncrementor = false;\\n }\\n }\\n } else {\\n facets_[i] = defaultFacet[defaultFacetIndex];\\n ++defaultFacetIndex;\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n }\\n\\n /**\\n * @notice Gets all the function selectors provided by a facet.\\n * @param _facet The facet address.\\n * @return facetFunctionSelectors_\\n */\\n function facetFunctionSelectors(\\n address _facet\\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\\n Facet[] memory facet = facets();\\n uint256 facetLength = facet.length;\\n for (uint256 i; i < facetLength; ) {\\n if (facet[i].facetAddress == _facet)\\n return facet[i].functionSelectors;\\n unchecked {\\n ++i;\\n }\\n }\\n return facetFunctionSelectors_;\\n }\\n\\n /**\\n * @notice Get all the facet addresses used by Barz.\\n * @return facetAddresses_\\n */\\n function facetAddresses()\\n external\\n view\\n override\\n returns (address[] memory facetAddresses_)\\n {\\n Facet[] memory facet = facets();\\n uint256 facetLength = facet.length;\\n facetAddresses_ = new address[](facetLength);\\n for (uint256 i; i < facetLength; ) {\\n facetAddresses_[i] = facet[i].facetAddress;\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * @notice Gets the facet that supports the given selector.\\n * @dev If facet is not found return address(0).\\n * @param _functionSelector The function selector.\\n * @return facetAddress_ The facet address.\\n */\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view override returns (address facetAddress_) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n\\n facetAddress_ = address(bytes20(ds.facets[_functionSelector]));\\n if (facetAddress_ == address(0)) {\\n facetAddress_ = IDiamondLoupe(ds.defaultFallbackHandler)\\n .facetAddress(_functionSelector);\\n }\\n }\\n\\n /**\\n * @notice SupportInterface to be compatible with EIP 165\\n * @param _interfaceId Interface ID for detecting the interface\\n * @return isSupported Bool value showing if the standard is supported in the contract\\n */\\n function supportsInterface(\\n bytes4 _interfaceId\\n ) external view override returns (bool isSupported) {\\n isSupported =\\n _interfaceId == type(IERC165).interfaceId ||\\n _interfaceId == IDiamondCut.diamondCut.selector ||\\n _interfaceId == type(IDiamondLoupe).interfaceId ||\\n _interfaceId == type(IERC1155Receiver).interfaceId ||\\n _interfaceId == type(IERC721Receiver).interfaceId ||\\n _interfaceId == type(IERC777Recipient).interfaceId ||\\n _interfaceId == IERC1271.isValidSignature.selector ||\\n _interfaceId == type(IERC677Receiver).interfaceId ||\\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId];\\n }\\n\\n /**\\n * @notice Returns the facet from the diamond storage. This excludes the facets from the default fallback handler\\n * @return facets_ Facet information attached directly to diamond storage\\n */\\n function facetsFromStorage()\\n external\\n view\\n override\\n returns (Facet[] memory facets_)\\n {\\n facets_ = LibLoupe.facets();\\n }\\n\\n /**\\n * @notice Returns the facet address attached to the given function selector. This excludes the facets from the default fallback handler\\n * @param _functionSelector Function selector to fetch the facet address from diamond storage\\n * @return facetAddress_ Facet address mapped with the function selector\\n */\\n function facetAddressFromStorage(\\n bytes4 _functionSelector\\n ) external view override returns (address facetAddress_) {\\n facetAddress_ = LibLoupe.facetAddress(_functionSelector);\\n }\\n\\n /**\\n * @notice Returns all facet addresses attached directly to diamond storage. This excludes the facets from the default fallback handler\\n * @return facetAddresses_ All facet addresses attached directly to diamond storage\\n */\\n function facetAddressesFromStorage()\\n external\\n view\\n override\\n returns (address[] memory facetAddresses_)\\n {\\n facetAddresses_ = LibLoupe.facetAddresses();\\n }\\n\\n /**\\n * @notice Returns function selectors of given facet address attached directly to diamond storage. This excludes the facets from the default fallback handler\\n * @param _facet Facet address to fetch the facet function selectors from diamond storage\\n * @return facetFunctionSelectors_ Facet function selectors of the given facet address\\n */\\n function facetFunctionSelectorsFromStorage(\\n address _facet\\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\\n facetFunctionSelectors_ = LibLoupe.facetFunctionSelectors(_facet);\\n }\\n}\\n\",\"keccak256\":\"0xf392fde159eec6483fc15fa323ecd6d764028f5b8734a66662c4116292363794\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IStorageLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"./IDiamondLoupe.sol\\\";\\n\\n/**\\n * @title LoupeFromStorage Interface\\n * @dev Interface contract to function as a loupe facet directly attached to diamond storage of Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IStorageLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facetsFromStorage()\\n external\\n view\\n returns (IDiamondLoupe.Facet[] memory);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n function facetFunctionSelectorsFromStorage(\\n address _facet\\n ) external view returns (bytes4[] memory);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n function facetAddressesFromStorage()\\n external\\n view\\n returns (address[] memory);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n function facetAddressFromStorage(\\n bytes4 _functionSelector\\n ) external view returns (address);\\n}\\n\",\"keccak256\":\"0xdf5dc9c57319e9087628c9cf9404b4f75585b76d1c2f4f59ee796c933967ea5c\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC1271 {\\n function isValidSignature(\\n bytes32 hash,\\n bytes memory signature\\n ) external view returns (bytes4);\\n}\\n\",\"keccak256\":\"0xcdddb7d5641c9d3f2432dec7fd13fddb9ae1480f25c76c21511e2fa16b8bd422\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.21;\\n\\ninterface IERC165 {\\n /// @notice Query if a contract implements an interface\\n /// @param interfaceId The interface identifier, as specified in ERC-165\\n /// @dev Interface identification is specified in ERC-165. This function\\n /// uses less than 30,000 gas.\\n /// @return `true` if the contract implements `interfaceID` and\\n /// `interfaceID` is not 0xffffffff, `false` otherwise\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xbb7f07e170898793c5535cc4b7e8944c4b990a631ac806d0b788e794abc788a3\",\"license\":\"MIT\"},\"contracts/interfaces/ERC/IERC677Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC677Receiver {\\n function onTokenTransfer(\\n address sender,\\n uint value,\\n bytes calldata data\\n ) external pure returns (bool);\\n}\\n\",\"keccak256\":\"0x4c1631cf45ea6daac0ec158c3edb9453099130b6b64f697004b83f95aa1f7350\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\\n bytes4(keccak256(\\\"verifyRestrictions(address,address,uint256,bytes)\\\"));\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // Default Fallback Handler of the barz.\\n IDiamondLoupe defaultFallbackHandler;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function enforceIsSelf() internal view {\\n require(msg.sender == address(this), \\\"LibDiamond: Caller not self\\\");\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n\\n unchecked {\\n facetIndex++;\\n }\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n\\n function restrictionsFacet() internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(\\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2cabdc00de859c3a3170ce3bda5d0e5fd3933d47ce904fd1585f9818b02572f8\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\nimport {LibDiamond} from \\\"./LibDiamond.sol\\\";\\n\\n/**\\n * @title LibLoupe\\n * @dev Internal Library to provide utility feature for reading the state of diamond facets\\n * Originally from Diamond's implementation of Mudgen(author of EIP-2535)\\n */\\nlibrary LibLoupe {\\n /// @notice Gets all facets and their selectors.\\n /// @return facets_ Facet\\n function facets()\\n internal\\n view\\n returns (IDiamondLoupe.Facet[] memory facets_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facets_ = new IDiamondLoupe.Facet[](ds.selectorCount);\\n uint16[] memory numFacetSelectors = new uint16[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facets_[facetIndex].facetAddress == facetAddress_) {\\n facets_[facetIndex].functionSelectors[\\n numFacetSelectors[facetIndex]\\n ] = selector;\\n // probably will never have more than 256 functions from one facet contract\\n require(numFacetSelectors[facetIndex] < 255);\\n numFacetSelectors[facetIndex]++;\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facets_[numFacets].facetAddress = facetAddress_;\\n facets_[numFacets].functionSelectors = new bytes4[](\\n ds.selectorCount\\n );\\n facets_[numFacets].functionSelectors[0] = selector;\\n numFacetSelectors[numFacets] = 1;\\n numFacets++;\\n }\\n }\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n uint256 numSelectors = numFacetSelectors[facetIndex];\\n bytes4[] memory selectors = facets_[facetIndex].functionSelectors;\\n // setting the number of selectors\\n assembly {\\n mstore(selectors, numSelectors)\\n }\\n }\\n // setting the number of facets\\n assembly {\\n mstore(facets_, numFacets)\\n }\\n }\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return _facetFunctionSelectors The selectors associated with a facet address.\\n function facetFunctionSelectors(\\n address _facet\\n ) internal view returns (bytes4[] memory _facetFunctionSelectors) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n uint256 numSelectors;\\n _facetFunctionSelectors = new bytes4[](ds.selectorCount);\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facet = address(bytes20(ds.facets[selector]));\\n if (_facet == facet) {\\n _facetFunctionSelectors[numSelectors] = selector;\\n numSelectors++;\\n }\\n }\\n }\\n // Set the number of selectors in the array\\n assembly {\\n mstore(_facetFunctionSelectors, numSelectors)\\n }\\n }\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n internal\\n view\\n returns (address[] memory facetAddresses_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetAddresses_ = new address[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facetAddress_ == facetAddresses_[facetIndex]) {\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facetAddresses_[numFacets] = facetAddress_;\\n numFacets++;\\n }\\n }\\n // Set the number of facet addresses in the array\\n assembly {\\n mstore(facetAddresses_, numFacets)\\n }\\n }\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(LibDiamond.diamondStorage().facets[_functionSelector])\\n );\\n }\\n}\\n\",\"keccak256\":\"0x0b11439c3cc657095e15ec2241fdcf67204b14001357b612fc5db4ff9e760a5a\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibUtils.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nlibrary LibUtils {\\n // Internal utility functions\\n function mergeArrays(\\n bytes4[] memory _array1,\\n bytes4[] memory _array2\\n ) internal pure returns (bytes4[] memory) {\\n uint256 length1 = _array1.length;\\n uint256 length2 = _array2.length;\\n bytes4[] memory mergedArray = new bytes4[](length1 + length2);\\n\\n for (uint256 i; i < length1; ) {\\n mergedArray[i] = _array1[i];\\n unchecked {\\n ++i;\\n }\\n }\\n\\n for (uint256 i; i < length2; ) {\\n mergedArray[length1 + i] = _array2[i];\\n unchecked {\\n ++i;\\n }\\n }\\n\\n return mergedArray;\\n }\\n\\n function removeFacetElement(\\n IDiamondLoupe.Facet[] memory _facets,\\n uint256 _index\\n ) internal pure returns (IDiamondLoupe.Facet[] memory) {\\n require(_index < _facets.length, \\\"Invalid index\\\");\\n require(_facets.length != 0, \\\"Invalid array\\\");\\n\\n // Create a new array with a length of `_facets.length - 1`\\n IDiamondLoupe.Facet[] memory newArray = new IDiamondLoupe.Facet[](\\n _facets.length - 1\\n );\\n uint256 newArrayLength = newArray.length;\\n // Iterate over the original array, skipping the element at the specified `index`\\n for (uint256 i; i < newArrayLength; ) {\\n if (i < _index) {\\n newArray[i] = _facets[i];\\n } else {\\n newArray[i] = _facets[i + 1];\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n\\n return newArray;\\n }\\n\\n function removeElement(\\n bytes4[] memory _array,\\n uint256 _index\\n ) internal pure returns (bytes4[] memory) {\\n require(_index < _array.length, \\\"Invalid index\\\");\\n require(_array.length != 0, \\\"Invalid array\\\");\\n\\n bytes4[] memory newArray = new bytes4[](_array.length - 1);\\n uint256 newArrayLength = newArray.length;\\n for (uint256 i; i < newArrayLength; ) {\\n if (i < _index) {\\n newArray[i] = _array[i];\\n } else {\\n newArray[i] = _array[i + 1];\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n\\n return newArray;\\n }\\n\\n function setValue(\\n bytes4[] memory _keys,\\n address[] memory _values,\\n bytes4 _key,\\n address _value\\n ) internal pure returns (bytes4[] memory, address[] memory) {\\n uint256 index = findIndex(_keys, _key);\\n uint256 keysLength = _keys.length;\\n if (index < keysLength) {\\n _values[index] = _value;\\n } else {\\n // Create new storage arrays\\n bytes4[] memory newKeys = new bytes4[](keysLength + 1);\\n address[] memory newValues = new address[](_values.length + 1);\\n\\n // Copy values to the new storage arrays\\n for (uint256 i; i < keysLength; ) {\\n newKeys[i] = _keys[i];\\n newValues[i] = _values[i];\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n // Add the new key-value pair\\n newKeys[keysLength] = _key;\\n newValues[_values.length] = _value;\\n\\n return (newKeys, newValues);\\n }\\n\\n // If the key already exists, return the original arrays\\n return (_keys, _values);\\n }\\n\\n function getValue(\\n bytes4[] memory _keys,\\n address[] memory _values,\\n bytes4 _key\\n ) internal pure returns (address) {\\n uint256 index = findIndex(_keys, _key);\\n if (index >= _keys.length) return address(0);\\n\\n return _values[index];\\n }\\n\\n function findIndex(\\n bytes4[] memory _keys,\\n bytes4 _key\\n ) internal pure returns (uint256) {\\n uint256 keysLength = _keys.length;\\n for (uint256 i; i < keysLength; ) {\\n if (_keys[i] == _key) {\\n return i;\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n return keysLength;\\n }\\n}\\n\",\"keccak256\":\"0xde8aeefe54c4be483f2b2c055aca11e2830f7094c0586a82e10ec544933b5714\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5061240b806100206000396000f3fe608060405234801561001057600080fd5b50600436106100a35760003560e01c8063adfca15e11610076578063d42139a91161005b578063d42139a914610169578063e3a2f6fe14610171578063f9796ccf1461018457600080fd5b8063adfca15e1461011e578063cdffacc61461013157600080fd5b806301a55022146100a857806301ffc9a7146100d157806352ef6b2c146100f45780637a0ed62714610109575b600080fd5b6100bb6100b6366004611e4b565b61018c565b6040516100c89190611e68565b60405180910390f35b6100e46100df366004611efc565b61019d565b60405190151581526020016100c8565b6100fc610454565b6040516100c89190611f19565b610111610518565b6040516100c89190611f67565b6100bb61012c366004611e4b565b610a63565b61014461013f366004611efc565b610b07565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100c8565b6100fc610c24565b61014461017f366004611efc565b610c33565b610111610c8c565b606061019782610c96565b92915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000148061023057507fffffffff0000000000000000000000000000000000000000000000000000000082167f1f931c1c00000000000000000000000000000000000000000000000000000000145b8061027c57507fffffffff0000000000000000000000000000000000000000000000000000000082167f48e2b09300000000000000000000000000000000000000000000000000000000145b806102c857507fffffffff0000000000000000000000000000000000000000000000000000000082167f4e2312e000000000000000000000000000000000000000000000000000000000145b8061031457507fffffffff0000000000000000000000000000000000000000000000000000000082167f150b7a0200000000000000000000000000000000000000000000000000000000145b8061035f57507fffffffff0000000000000000000000000000000000000000000000000000000082167e23de2900000000000000000000000000000000000000000000000000000000145b806103ab57507fffffffff0000000000000000000000000000000000000000000000000000000082167f1626ba7e00000000000000000000000000000000000000000000000000000000145b806103f757507fffffffff0000000000000000000000000000000000000000000000000000000082167fa4c0ed3600000000000000000000000000000000000000000000000000000000145b806101975750507fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4922602052604090205460ff1690565b60606000610460610518565b80519091508067ffffffffffffffff81111561047e5761047e61205d565b6040519080825280602002602001820160405280156104a7578160200160208202803683370190505b50925060005b81811015610512578281815181106104c7576104c761208c565b6020026020010151600001518482815181106104e5576104e561208c565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526001016104ad565b50505090565b606060007f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f600490810154604080517f7a0ed627000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff90921692637a0ed6279282820192600092908290030181865afa1580156105ac573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526105f29190810190612157565b905060006105fe610e57565b805190915060608060005b838110156106b55760008582815181106106255761062561208c565b60200260200101516020015151905060005b818110156106ab5761069e85858986815181106106565761065661208c565b60200260200101516020015184815181106106735761067361208c565b60200260200101518a878151811061068d5761068d61208c565b60200260200101516000015161134a565b9095509350600101610637565b5050600101610609565b506000805b865181101561081b576000805b8883815181106106d9576106d961208c565b602002602001015160200151518110156107ff57600073ffffffffffffffffffffffffffffffffffffffff1661074687878c878151811061071c5761071c61208c565b60200260200101516020015185815181106107395761073961208c565b60200260200101516115f1565b73ffffffffffffffffffffffffffffffffffffffff16146107e9578883815181106107735761077361208c565b6020026020010151602001515160010361079c576107918984611637565b9850600193506107ff565b6107c38984815181106107b1576107b161208c565b6020026020010151602001518261182a565b8984815181106107d5576107d561208c565b602002602001015160200181905250600191505b816107f6576001016106c7565b600091506106c7565b508261081057816001019150610815565b600092505b506106ba565b5050600085518461082c9190612304565b90508067ffffffffffffffff8111156108475761084761205d565b60405190808252806020026020018201604052801561088d57816020015b6040805180820190915260008152606060208201528152602001906001900390816108655790505b5096506000805b82811015610a585785811015610a0c578681815181106108b6576108b661208c565b60200260200101518982815181106108d0576108d061208c565b60200260200101819052506000805b8951811015610a05578981815181106108fa576108fa61208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff168b848151811061092e5761092e61208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff16036109ef5761099989848151811061096a5761096a61208c565b6020026020010151602001518b83815181106109885761098861208c565b602002602001015160200151611a3d565b8b84815181106109ab576109ab61208c565b6020026020010151602001819052506109c48a82611637565b9950600191506109e18b60018d516109dc9190612317565b611637565b9a506109ec8561232a565b94505b816109fc576001016108df565b600091506108df565b5050610a50565b878281518110610a1e57610a1e61208c565b6020026020010151898281518110610a3857610a3861208c565b602002602001018190525081610a4d9061235f565b91505b600101610894565b505050505050505090565b60606000610a6f610518565b805190915060005b81811015610aff578473ffffffffffffffffffffffffffffffffffffffff16838281518110610aa857610aa861208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1603610af757828181518110610ae157610ae161208c565b6020026020010151602001519350505050919050565b600101610a77565b505050919050565b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602081905260409091205460601c9081610c1e576004818101546040517fcdffacc60000000000000000000000000000000000000000000000000000000081527fffffffff0000000000000000000000000000000000000000000000000000000086169281019290925273ffffffffffffffffffffffffffffffffffffffff169063cdffacc690602401602060405180830381865afa158015610bf7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c1b9190612397565b91505b50919050565b6060610c2e611b8b565b905090565b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604081205460601c610197565b6060610c2e610e57565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9060009061ffff1667ffffffffffffffff811115610cfc57610cfc61205d565b604051908082528060200260200182016040528015610d25578160200160208202803683370190505b5092506000805b600284015461ffff16821015610e4d576000818152600185016020526040812054905b6008811015610e385783610d628161235f565b600288015490955061ffff1685119050610e3857600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020889052604090205460601c73ffffffffffffffffffffffffffffffffffffffff8a16819003610e235781898881518110610de457610de461208c565b7fffffffff000000000000000000000000000000000000000000000000000000009092166020928302919091019091015286610e1f8161235f565b9750505b50508080610e309061235f565b915050610d4f565b50508080610e459061235f565b915050610d2c565b5050825250919050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff1667ffffffffffffffff811115610eba57610eba61205d565b604051908082528060200260200182016040528015610f0057816020015b604080518082019091526000815260606020820152815260200190600190039081610ed85790505b50600282015490925060009061ffff1667ffffffffffffffff811115610f2857610f2861205d565b604051908082528060200260200182016040528015610f51578160200160208202803683370190505b50905060008060005b600285015461ffff168210156112d7576000818152600186016020526040812054905b60088110156112c25783610f908161235f565b600289015490955061ffff16851190506112c257600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020899052604081205460601c90805b88811015611148578273ffffffffffffffffffffffffffffffffffffffff168c82815181106110155761101561208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff160361113657838c828151811061104f5761104f61208c565b6020026020010151602001518b838151811061106d5761106d61208c565b602002602001015161ffff16815181106110895761108961208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152505060ff8a82815181106110e9576110e961208c565b602002602001015161ffff16106110ff57600080fd5b8981815181106111115761111161208c565b602002602001018051809190611126906123b4565b61ffff1690525060019150611148565b806111408161235f565b915050610fe4565b508015611157575050506112b0565b818b898151811061116a5761116a61208c565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff909116905260028a015461ffff1667ffffffffffffffff8111156111b0576111b061205d565b6040519080825280602002602001820160405280156111d9578160200160208202803683370190505b508b89815181106111ec576111ec61208c565b602002602001015160200181905250828b898151811061120e5761120e61208c565b60200260200101516020015160008151811061122c5761122c61208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681525050600189898151811061128c5761128c61208c565b61ffff90921660209283029190910190910152876112a98161235f565b9850505050505b806112ba8161235f565b915050610f7d565b505080806112cf9061235f565b915050610f5a565b5060005b8281101561133f5760008482815181106112f7576112f761208c565b602002602001015161ffff16905060008783815181106113195761131961208c565b6020026020010151602001519050818152505080806113379061235f565b9150506112db565b508185525050505090565b60608060006113598786611da0565b8751909150808210156113b857848783815181106113795761137961208c565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250506115df565b60006113c5826001612304565b67ffffffffffffffff8111156113dd576113dd61205d565b604051908082528060200260200182016040528015611406578160200160208202803683370190505b5090506000885160016114199190612304565b67ffffffffffffffff8111156114315761143161205d565b60405190808252806020026020018201604052801561145a578160200160208202803683370190505b50905060005b83811015611539578a818151811061147a5761147a61208c565b60200260200101518382815181106114945761149461208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815250508981815181106114f2576114f261208c565b602002602001015182828151811061150c5761150c61208c565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101611460565b508782848151811061154d5761154d61208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152505086818a51815181106115ad576115ad61208c565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015290945092506115e8915050565b87879350935050505b94509492505050565b6000806115fe8584611da0565b905084518110611612576000915050611630565b8381815181106116245761162461208c565b60200260200101519150505b9392505050565b6060825182106116a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420696e6465780000000000000000000000000000000000000060448201526064015b60405180910390fd5b8251600003611713576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420617272617900000000000000000000000000000000000000604482015260640161169f565b6000600184516117239190612317565b67ffffffffffffffff81111561173b5761173b61205d565b60405190808252806020026020018201604052801561178157816020015b6040805180820190915260008152606060208201528152602001906001900390816117595790505b50805190915060005b8181101561182057848110156117d6578581815181106117ac576117ac61208c565b60200260200101518382815181106117c6576117c661208c565b6020026020010181905250611818565b856117e2826001612304565b815181106117f2576117f261208c565b602002602001015183828151811061180c5761180c61208c565b60200260200101819052505b60010161178a565b5090949350505050565b606082518210611896576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420696e64657800000000000000000000000000000000000000604482015260640161169f565b8251600003611901576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420617272617900000000000000000000000000000000000000604482015260640161169f565b6000600184516119119190612317565b67ffffffffffffffff8111156119295761192961205d565b604051908082528060200260200182016040528015611952578160200160208202803683370190505b50805190915060005b8181101561182057848110156119cd5785818151811061197d5761197d61208c565b60200260200101518382815181106119975761199761208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152611a35565b856119d9826001612304565b815181106119e9576119e961208c565b6020026020010151838281518110611a0357611a0361208c565b7fffffffff00000000000000000000000000000000000000000000000000000000909216602092830291909101909101525b60010161195b565b81518151606091906000611a518284612304565b67ffffffffffffffff811115611a6957611a6961205d565b604051908082528060200260200182016040528015611a92578160200160208202803683370190505b50905060005b83811015611b0557868181518110611ab257611ab261208c565b6020026020010151828281518110611acc57611acc61208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152600101611a98565b5060005b82811015611b8157858181518110611b2357611b2361208c565b6020026020010151828286611b389190612304565b81518110611b4857611b4861208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152600101611b09565b5095945050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff1667ffffffffffffffff811115611bee57611bee61205d565b604051908082528060200260200182016040528015611c17578160200160208202803683370190505b50915060008060005b600284015461ffff16821015611d98576000818152600185016020526040812054905b6008811015611d835783611c568161235f565b600288015490955061ffff1685119050611d8357600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020889052604081205460601c90805b88811015611d19578a8181518110611cc457611cc461208c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611d075760019150611d19565b80611d118161235f565b915050611caa565b508015611d2857505050611d71565b818a8981518110611d3b57611d3b61208c565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015287611d6a8161235f565b9850505050505b80611d7b8161235f565b915050611c43565b50508080611d909061235f565b915050611c20565b505082525090565b8151600090815b81811015611e1e57837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916858281518110611de157611de161208c565b60200260200101517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603611e165791506101979050565b600101611da7565b509392505050565b73ffffffffffffffffffffffffffffffffffffffff81168114611e4857600080fd5b50565b600060208284031215611e5d57600080fd5b813561163081611e26565b6020808252825182820181905260009190848201906040850190845b81811015611ec25783517fffffffff000000000000000000000000000000000000000000000000000000001683529284019291840191600101611e84565b50909695505050505050565b7fffffffff0000000000000000000000000000000000000000000000000000000081168114611e4857600080fd5b600060208284031215611f0e57600080fd5b813561163081611ece565b6020808252825182820181905260009190848201906040850190845b81811015611ec257835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101611f35565b60006020808301818452808551808352604092508286019150828160051b8701018488016000805b8481101561204e578984037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00186528251805173ffffffffffffffffffffffffffffffffffffffff168552880151888501889052805188860181905290890190839060608701905b808310156120395783517fffffffff00000000000000000000000000000000000000000000000000000000168252928b019260019290920191908b0190611ff7565b50978a01979550505091870191600101611f8f565b50919998505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6040805190810167ffffffffffffffff811182821017156120de576120de61205d565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561212b5761212b61205d565b604052919050565b600067ffffffffffffffff82111561214d5761214d61205d565b5060051b60200190565b6000602080838503121561216a57600080fd5b825167ffffffffffffffff8082111561218257600080fd5b818501915085601f83011261219657600080fd5b81516121a96121a482612133565b6120e4565b81815260059190911b830184019084810190888311156121c857600080fd5b8585015b838110156122c8578051858111156121e45760008081fd5b86016040818c037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00181131561221a5760008081fd5b6122226120bb565b8983015161222f81611e26565b815282820151888111156122435760008081fd5b8084019350508c603f8401126122595760008081fd5b898301516122696121a482612133565b81815260059190911b84018301908b8101908f8311156122895760008081fd5b948401945b828610156122b357855194506122a385611ece565b848252948c0194908c019061228e565b838d01525050855250509186019186016121cc565b5098975050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610197576101976122d5565b81810381811115610197576101976122d5565b600081612339576123396122d5565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612390576123906122d5565b5060010190565b6000602082840312156123a957600080fd5b815161163081611e26565b600061ffff8083168181036123cb576123cb6122d5565b600101939250505056fea26469706673582212205959d8d85aad6f29d5fc37d5a52c404c25392cec49195c3b761da0e863e99b0f64736f6c63430008150033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100a35760003560e01c8063adfca15e11610076578063d42139a91161005b578063d42139a914610169578063e3a2f6fe14610171578063f9796ccf1461018457600080fd5b8063adfca15e1461011e578063cdffacc61461013157600080fd5b806301a55022146100a857806301ffc9a7146100d157806352ef6b2c146100f45780637a0ed62714610109575b600080fd5b6100bb6100b6366004611e4b565b61018c565b6040516100c89190611e68565b60405180910390f35b6100e46100df366004611efc565b61019d565b60405190151581526020016100c8565b6100fc610454565b6040516100c89190611f19565b610111610518565b6040516100c89190611f67565b6100bb61012c366004611e4b565b610a63565b61014461013f366004611efc565b610b07565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100c8565b6100fc610c24565b61014461017f366004611efc565b610c33565b610111610c8c565b606061019782610c96565b92915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000148061023057507fffffffff0000000000000000000000000000000000000000000000000000000082167f1f931c1c00000000000000000000000000000000000000000000000000000000145b8061027c57507fffffffff0000000000000000000000000000000000000000000000000000000082167f48e2b09300000000000000000000000000000000000000000000000000000000145b806102c857507fffffffff0000000000000000000000000000000000000000000000000000000082167f4e2312e000000000000000000000000000000000000000000000000000000000145b8061031457507fffffffff0000000000000000000000000000000000000000000000000000000082167f150b7a0200000000000000000000000000000000000000000000000000000000145b8061035f57507fffffffff0000000000000000000000000000000000000000000000000000000082167e23de2900000000000000000000000000000000000000000000000000000000145b806103ab57507fffffffff0000000000000000000000000000000000000000000000000000000082167f1626ba7e00000000000000000000000000000000000000000000000000000000145b806103f757507fffffffff0000000000000000000000000000000000000000000000000000000082167fa4c0ed3600000000000000000000000000000000000000000000000000000000145b806101975750507fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4922602052604090205460ff1690565b60606000610460610518565b80519091508067ffffffffffffffff81111561047e5761047e61205d565b6040519080825280602002602001820160405280156104a7578160200160208202803683370190505b50925060005b81811015610512578281815181106104c7576104c761208c565b6020026020010151600001518482815181106104e5576104e561208c565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526001016104ad565b50505090565b606060007f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f600490810154604080517f7a0ed627000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff90921692637a0ed6279282820192600092908290030181865afa1580156105ac573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526105f29190810190612157565b905060006105fe610e57565b805190915060608060005b838110156106b55760008582815181106106255761062561208c565b60200260200101516020015151905060005b818110156106ab5761069e85858986815181106106565761065661208c565b60200260200101516020015184815181106106735761067361208c565b60200260200101518a878151811061068d5761068d61208c565b60200260200101516000015161134a565b9095509350600101610637565b5050600101610609565b506000805b865181101561081b576000805b8883815181106106d9576106d961208c565b602002602001015160200151518110156107ff57600073ffffffffffffffffffffffffffffffffffffffff1661074687878c878151811061071c5761071c61208c565b60200260200101516020015185815181106107395761073961208c565b60200260200101516115f1565b73ffffffffffffffffffffffffffffffffffffffff16146107e9578883815181106107735761077361208c565b6020026020010151602001515160010361079c576107918984611637565b9850600193506107ff565b6107c38984815181106107b1576107b161208c565b6020026020010151602001518261182a565b8984815181106107d5576107d561208c565b602002602001015160200181905250600191505b816107f6576001016106c7565b600091506106c7565b508261081057816001019150610815565b600092505b506106ba565b5050600085518461082c9190612304565b90508067ffffffffffffffff8111156108475761084761205d565b60405190808252806020026020018201604052801561088d57816020015b6040805180820190915260008152606060208201528152602001906001900390816108655790505b5096506000805b82811015610a585785811015610a0c578681815181106108b6576108b661208c565b60200260200101518982815181106108d0576108d061208c565b60200260200101819052506000805b8951811015610a05578981815181106108fa576108fa61208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff168b848151811061092e5761092e61208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff16036109ef5761099989848151811061096a5761096a61208c565b6020026020010151602001518b83815181106109885761098861208c565b602002602001015160200151611a3d565b8b84815181106109ab576109ab61208c565b6020026020010151602001819052506109c48a82611637565b9950600191506109e18b60018d516109dc9190612317565b611637565b9a506109ec8561232a565b94505b816109fc576001016108df565b600091506108df565b5050610a50565b878281518110610a1e57610a1e61208c565b6020026020010151898281518110610a3857610a3861208c565b602002602001018190525081610a4d9061235f565b91505b600101610894565b505050505050505090565b60606000610a6f610518565b805190915060005b81811015610aff578473ffffffffffffffffffffffffffffffffffffffff16838281518110610aa857610aa861208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1603610af757828181518110610ae157610ae161208c565b6020026020010151602001519350505050919050565b600101610a77565b505050919050565b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602081905260409091205460601c9081610c1e576004818101546040517fcdffacc60000000000000000000000000000000000000000000000000000000081527fffffffff0000000000000000000000000000000000000000000000000000000086169281019290925273ffffffffffffffffffffffffffffffffffffffff169063cdffacc690602401602060405180830381865afa158015610bf7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c1b9190612397565b91505b50919050565b6060610c2e611b8b565b905090565b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604081205460601c610197565b6060610c2e610e57565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9060009061ffff1667ffffffffffffffff811115610cfc57610cfc61205d565b604051908082528060200260200182016040528015610d25578160200160208202803683370190505b5092506000805b600284015461ffff16821015610e4d576000818152600185016020526040812054905b6008811015610e385783610d628161235f565b600288015490955061ffff1685119050610e3857600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020889052604090205460601c73ffffffffffffffffffffffffffffffffffffffff8a16819003610e235781898881518110610de457610de461208c565b7fffffffff000000000000000000000000000000000000000000000000000000009092166020928302919091019091015286610e1f8161235f565b9750505b50508080610e309061235f565b915050610d4f565b50508080610e459061235f565b915050610d2c565b5050825250919050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff1667ffffffffffffffff811115610eba57610eba61205d565b604051908082528060200260200182016040528015610f0057816020015b604080518082019091526000815260606020820152815260200190600190039081610ed85790505b50600282015490925060009061ffff1667ffffffffffffffff811115610f2857610f2861205d565b604051908082528060200260200182016040528015610f51578160200160208202803683370190505b50905060008060005b600285015461ffff168210156112d7576000818152600186016020526040812054905b60088110156112c25783610f908161235f565b600289015490955061ffff16851190506112c257600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020899052604081205460601c90805b88811015611148578273ffffffffffffffffffffffffffffffffffffffff168c82815181106110155761101561208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff160361113657838c828151811061104f5761104f61208c565b6020026020010151602001518b838151811061106d5761106d61208c565b602002602001015161ffff16815181106110895761108961208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152505060ff8a82815181106110e9576110e961208c565b602002602001015161ffff16106110ff57600080fd5b8981815181106111115761111161208c565b602002602001018051809190611126906123b4565b61ffff1690525060019150611148565b806111408161235f565b915050610fe4565b508015611157575050506112b0565b818b898151811061116a5761116a61208c565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff909116905260028a015461ffff1667ffffffffffffffff8111156111b0576111b061205d565b6040519080825280602002602001820160405280156111d9578160200160208202803683370190505b508b89815181106111ec576111ec61208c565b602002602001015160200181905250828b898151811061120e5761120e61208c565b60200260200101516020015160008151811061122c5761122c61208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681525050600189898151811061128c5761128c61208c565b61ffff90921660209283029190910190910152876112a98161235f565b9850505050505b806112ba8161235f565b915050610f7d565b505080806112cf9061235f565b915050610f5a565b5060005b8281101561133f5760008482815181106112f7576112f761208c565b602002602001015161ffff16905060008783815181106113195761131961208c565b6020026020010151602001519050818152505080806113379061235f565b9150506112db565b508185525050505090565b60608060006113598786611da0565b8751909150808210156113b857848783815181106113795761137961208c565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250506115df565b60006113c5826001612304565b67ffffffffffffffff8111156113dd576113dd61205d565b604051908082528060200260200182016040528015611406578160200160208202803683370190505b5090506000885160016114199190612304565b67ffffffffffffffff8111156114315761143161205d565b60405190808252806020026020018201604052801561145a578160200160208202803683370190505b50905060005b83811015611539578a818151811061147a5761147a61208c565b60200260200101518382815181106114945761149461208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815250508981815181106114f2576114f261208c565b602002602001015182828151811061150c5761150c61208c565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101611460565b508782848151811061154d5761154d61208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152505086818a51815181106115ad576115ad61208c565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015290945092506115e8915050565b87879350935050505b94509492505050565b6000806115fe8584611da0565b905084518110611612576000915050611630565b8381815181106116245761162461208c565b60200260200101519150505b9392505050565b6060825182106116a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420696e6465780000000000000000000000000000000000000060448201526064015b60405180910390fd5b8251600003611713576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420617272617900000000000000000000000000000000000000604482015260640161169f565b6000600184516117239190612317565b67ffffffffffffffff81111561173b5761173b61205d565b60405190808252806020026020018201604052801561178157816020015b6040805180820190915260008152606060208201528152602001906001900390816117595790505b50805190915060005b8181101561182057848110156117d6578581815181106117ac576117ac61208c565b60200260200101518382815181106117c6576117c661208c565b6020026020010181905250611818565b856117e2826001612304565b815181106117f2576117f261208c565b602002602001015183828151811061180c5761180c61208c565b60200260200101819052505b60010161178a565b5090949350505050565b606082518210611896576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420696e64657800000000000000000000000000000000000000604482015260640161169f565b8251600003611901576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420617272617900000000000000000000000000000000000000604482015260640161169f565b6000600184516119119190612317565b67ffffffffffffffff8111156119295761192961205d565b604051908082528060200260200182016040528015611952578160200160208202803683370190505b50805190915060005b8181101561182057848110156119cd5785818151811061197d5761197d61208c565b60200260200101518382815181106119975761199761208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152611a35565b856119d9826001612304565b815181106119e9576119e961208c565b6020026020010151838281518110611a0357611a0361208c565b7fffffffff00000000000000000000000000000000000000000000000000000000909216602092830291909101909101525b60010161195b565b81518151606091906000611a518284612304565b67ffffffffffffffff811115611a6957611a6961205d565b604051908082528060200260200182016040528015611a92578160200160208202803683370190505b50905060005b83811015611b0557868181518110611ab257611ab261208c565b6020026020010151828281518110611acc57611acc61208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152600101611a98565b5060005b82811015611b8157858181518110611b2357611b2361208c565b6020026020010151828286611b389190612304565b81518110611b4857611b4861208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152600101611b09565b5095945050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff1667ffffffffffffffff811115611bee57611bee61205d565b604051908082528060200260200182016040528015611c17578160200160208202803683370190505b50915060008060005b600284015461ffff16821015611d98576000818152600185016020526040812054905b6008811015611d835783611c568161235f565b600288015490955061ffff1685119050611d8357600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020889052604081205460601c90805b88811015611d19578a8181518110611cc457611cc461208c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611d075760019150611d19565b80611d118161235f565b915050611caa565b508015611d2857505050611d71565b818a8981518110611d3b57611d3b61208c565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015287611d6a8161235f565b9850505050505b80611d7b8161235f565b915050611c43565b50508080611d909061235f565b915050611c20565b505082525090565b8151600090815b81811015611e1e57837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916858281518110611de157611de161208c565b60200260200101517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603611e165791506101979050565b600101611da7565b509392505050565b73ffffffffffffffffffffffffffffffffffffffff81168114611e4857600080fd5b50565b600060208284031215611e5d57600080fd5b813561163081611e26565b6020808252825182820181905260009190848201906040850190845b81811015611ec25783517fffffffff000000000000000000000000000000000000000000000000000000001683529284019291840191600101611e84565b50909695505050505050565b7fffffffff0000000000000000000000000000000000000000000000000000000081168114611e4857600080fd5b600060208284031215611f0e57600080fd5b813561163081611ece565b6020808252825182820181905260009190848201906040850190845b81811015611ec257835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101611f35565b60006020808301818452808551808352604092508286019150828160051b8701018488016000805b8481101561204e578984037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00186528251805173ffffffffffffffffffffffffffffffffffffffff168552880151888501889052805188860181905290890190839060608701905b808310156120395783517fffffffff00000000000000000000000000000000000000000000000000000000168252928b019260019290920191908b0190611ff7565b50978a01979550505091870191600101611f8f565b50919998505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6040805190810167ffffffffffffffff811182821017156120de576120de61205d565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561212b5761212b61205d565b604052919050565b600067ffffffffffffffff82111561214d5761214d61205d565b5060051b60200190565b6000602080838503121561216a57600080fd5b825167ffffffffffffffff8082111561218257600080fd5b818501915085601f83011261219657600080fd5b81516121a96121a482612133565b6120e4565b81815260059190911b830184019084810190888311156121c857600080fd5b8585015b838110156122c8578051858111156121e45760008081fd5b86016040818c037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00181131561221a5760008081fd5b6122226120bb565b8983015161222f81611e26565b815282820151888111156122435760008081fd5b8084019350508c603f8401126122595760008081fd5b898301516122696121a482612133565b81815260059190911b84018301908b8101908f8311156122895760008081fd5b948401945b828610156122b357855194506122a385611ece565b848252948c0194908c019061228e565b838d01525050855250509186019186016121cc565b5098975050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610197576101976122d5565b81810381811115610197576101976122d5565b600081612339576123396122d5565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612390576123906122d5565b5060010190565b6000602082840312156123a957600080fd5b815161163081611e26565b600061ffff8083168181036123cb576123cb6122d5565b600101939250505056fea26469706673582212205959d8d85aad6f29d5fc37d5a52c404c25392cec49195c3b761da0e863e99b0f64736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "DiamondLoupe contract compatible with EIP-2535", + "kind": "dev", + "methods": { + "facetAddress(bytes4)": { + "details": "If facet is not found return address(0).", + "params": { + "_functionSelector": "The function selector." + }, + "returns": { + "facetAddress_": "The facet address." + } + }, + "facetAddressFromStorage(bytes4)": { + "params": { + "_functionSelector": "Function selector to fetch the facet address from diamond storage" + }, + "returns": { + "facetAddress_": "Facet address mapped with the function selector" + } + }, + "facetAddresses()": { + "returns": { + "facetAddresses_": "facetAddresses_" + } + }, + "facetAddressesFromStorage()": { + "returns": { + "facetAddresses_": "All facet addresses attached directly to diamond storage" + } + }, + "facetFunctionSelectors(address)": { + "params": { + "_facet": "The facet address." + }, + "returns": { + "facetFunctionSelectors_": "facetFunctionSelectors_" + } + }, + "facetFunctionSelectorsFromStorage(address)": { + "params": { + "_facet": "Facet address to fetch the facet function selectors from diamond storage" + }, + "returns": { + "facetFunctionSelectors_": "Facet function selectors of the given facet address" + } + }, + "facets()": { + "details": "Barz uses a special architecture called default fallback handler. Default Fallback handler is used as a middleware that holds the mapping of facet function selector and facet address that Barz uses. This helps Barz to reduce significant amount of gas during the initialization process. Hence, this method aggregates both the facet information from DefaulFallbackHandler and in diamond storage and shows the data to users.", + "returns": { + "facets_": "Facet" + } + }, + "facetsFromStorage()": { + "returns": { + "facets_": "Facet information attached directly to diamond storage" + } + }, + "supportsInterface(bytes4)": { + "params": { + "_interfaceId": "Interface ID for detecting the interface" + }, + "returns": { + "isSupported": "Bool value showing if the standard is supported in the contract" + } + } + }, + "title": "DiamondLoupe Facet", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "facetAddress(bytes4)": { + "notice": "Gets the facet that supports the given selector." + }, + "facetAddressFromStorage(bytes4)": { + "notice": "Returns the facet address attached to the given function selector. This excludes the facets from the default fallback handler" + }, + "facetAddresses()": { + "notice": "Get all the facet addresses used by Barz." + }, + "facetAddressesFromStorage()": { + "notice": "Returns all facet addresses attached directly to diamond storage. This excludes the facets from the default fallback handler" + }, + "facetFunctionSelectors(address)": { + "notice": "Gets all the function selectors provided by a facet." + }, + "facetFunctionSelectorsFromStorage(address)": { + "notice": "Returns function selectors of given facet address attached directly to diamond storage. This excludes the facets from the default fallback handler" + }, + "facets()": { + "notice": "Gets all facets and their selectors." + }, + "facetsFromStorage()": { + "notice": "Returns the facet from the diamond storage. This excludes the facets from the default fallback handler" + }, + "supportsInterface(bytes4)": { + "notice": "SupportInterface to be compatible with EIP 165" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/arbitrum/Secp256r1VerificationFacet.json b/deployments/arbitrum/Secp256r1VerificationFacet.json new file mode 100644 index 0000000..9828123 --- /dev/null +++ b/deployments/arbitrum/Secp256r1VerificationFacet.json @@ -0,0 +1,483 @@ +{ + "address": "0xeE1AF8E967eC04C84711842796A5E714D2FD33e6", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "LibAppStorage__AccountMustBeUninitialized", + "type": "error" + }, + { + "inputs": [], + "name": "LibAppStorage__SignerAlreadyUninitialized", + "type": "error" + }, + { + "inputs": [], + "name": "LibAppStorage__SignerMustBeUninitialized", + "type": "error" + }, + { + "inputs": [], + "name": "Secp256r1VerificationFacet__InvalidSignerLength", + "type": "error" + }, + { + "inputs": [], + "name": "VerificationFacet__InitializationFailure", + "type": "error" + }, + { + "inputs": [], + "name": "VerificationFacet__InvalidFacetMapping", + "type": "error" + }, + { + "inputs": [], + "name": "VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet", + "type": "error" + }, + { + "inputs": [], + "name": "VerificationFacet__ValidateOwnerSignatureSelectorNotSet", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "SignerInitialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "SignerUninitialized", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_publicKey", + "type": "bytes" + } + ], + "name": "initializeSigner", + "outputs": [ + { + "internalType": "uint256", + "name": "initSuccess", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_publicKey", + "type": "bytes" + } + ], + "name": "isValidKeyType", + "outputs": [ + { + "internalType": "bool", + "name": "isValid", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_hash", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "_signature", + "type": "bytes" + } + ], + "name": "isValidSignature", + "outputs": [ + { + "internalType": "bytes4", + "name": "magicValue", + "type": "bytes4" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "bytes", + "name": "signer", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "self", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "uninitializeSigner", + "outputs": [ + { + "internalType": "uint256", + "name": "uninitSuccess", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "initCode", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "callGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "verificationGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "preVerificationGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxFeePerGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPriorityFeePerGas", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "paymasterAndData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "internalType": "struct UserOperation", + "name": "userOp", + "type": "tuple" + }, + { + "internalType": "bytes32", + "name": "userOpHash", + "type": "bytes32" + } + ], + "name": "validateOwnerSignature", + "outputs": [ + { + "internalType": "uint256", + "name": "validationData", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "validateOwnerSignatureSelector", + "outputs": [ + { + "internalType": "bytes4", + "name": "ownerSignatureValidatorSelector", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "initCode", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "callGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "verificationGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "preVerificationGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxFeePerGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPriorityFeePerGas", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "paymasterAndData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "internalType": "struct UserOperation", + "name": "userOp", + "type": "tuple" + }, + { + "internalType": "bytes32", + "name": "userOpHash", + "type": "bytes32" + }, + { + "internalType": "uint256[2]", + "name": "q", + "type": "uint256[2]" + } + ], + "name": "validateSignature", + "outputs": [ + { + "internalType": "uint256", + "name": "isValid", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0x8b8150c0d371417936b7d9a66997227dcb3821df57c91574a9da986a3d5c448b", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 1, + "gasUsed": "14326705", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0xf36877f12071022ce4a6640bfd18bc66021763c04bbc702168d3be95792ea767", + "transactionHash": "0x8b8150c0d371417936b7d9a66997227dcb3821df57c91574a9da986a3d5c448b", + "logs": [], + "blockNumber": 152284131, + "cumulativeGasUsed": "14326705", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 3, + "solcInputHash": "4356503edd8ae34e73cb6dd1c8e2fc8a", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"LibAppStorage__AccountMustBeUninitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LibAppStorage__SignerAlreadyUninitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LibAppStorage__SignerMustBeUninitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Secp256r1VerificationFacet__InvalidSignerLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerificationFacet__InitializationFailure\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerificationFacet__InvalidFacetMapping\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerificationFacet__ValidateOwnerSignatureSelectorNotSet\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"SignerInitialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"SignerUninitialized\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_publicKey\",\"type\":\"bytes\"}],\"name\":\"initializeSigner\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"initSuccess\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_publicKey\",\"type\":\"bytes\"}],\"name\":\"isValidKeyType\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isValid\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_hash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"_signature\",\"type\":\"bytes\"}],\"name\":\"isValidSignature\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"magicValue\",\"type\":\"bytes4\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"signer\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"self\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"uninitializeSigner\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"uninitSuccess\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"userOp\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"}],\"name\":\"validateOwnerSignature\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"validationData\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"validateOwnerSignatureSelector\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"ownerSignatureValidatorSelector\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"userOp\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256[2]\",\"name\":\"q\",\"type\":\"uint256[2]\"}],\"name\":\"validateSignature\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"isValid\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Ruslan Serebriakov (@rsrbk)David Yongjun Kim (@Powerstream3604)\",\"details\":\"Primarily used to verify user ops signed with passkeys\",\"kind\":\"dev\",\"methods\":{\"initializeSigner(bytes)\":{\"details\":\"This method checks if the signer has already been initialized. If already initialized, it reverts. It checks if the public key is in the light format and initializes signer storage in k1 storage.\",\"params\":{\"_publicKey\":\"Bytes of owner public key\"},\"returns\":{\"initSuccess\":\"Uint value representing the success of init operation\"}},\"isValidKeyType(bytes)\":{\"details\":\"For this Secp256k1Verification Facet, the public key should in an uncompressed public key format\",\"params\":{\"_publicKey\":\"Bytes of public key for format check\"},\"returns\":{\"isValid\":\"Boolean variable representing if the format of public key is valid\"}},\"isValidSignature(bytes32,bytes)\":{\"details\":\"This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\",\"params\":{\"_hash\":\"Hash value the owner signed\",\"_signature\":\"Signature that signed the above hash\"},\"returns\":{\"magicValue\":\"Bytes4 value representing the success/failure of validation\"}},\"owner()\":{\"returns\":{\"signer\":\"Bytes of owner address\"}},\"uninitializeSigner()\":{\"details\":\"This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\",\"returns\":{\"uninitSuccess\":\"Uint value representing the success of uninit operation\"}},\"validateOwnerSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32)\":{\"details\":\"This method validates if the user operation is signed by the owner. It internally calls validateSignature with signer public key.\",\"params\":{\"userOp\":\"UserOperation including all information for execution\",\"userOpHash\":\"Hash of UserOperation given from EntryPoint. This hash is used for signature validation\"},\"returns\":{\"validationData\":\"Uint value representing whether the validation is successful. 0 for success, 1 for failure\"}},\"validateOwnerSignatureSelector()\":{\"returns\":{\"ownerSignatureValidatorSelector\":\"Bytes4 selector of function signature to validate account owner's UserOperation signature\"}},\"validateSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256[2])\":{\"details\":\"This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\",\"params\":{\"q\":\"Public Key of signer who signed the contract, to be validated\",\"userOp\":\"UserOperation including all information for execution\",\"userOpHash\":\"Hash of UserOperation given from EntryPoint. This hash is used for signature validation\"},\"returns\":{\"isValid\":\"Uint value representing whether the validation is successful. 0 for success, 1 for failure\"}}},\"title\":\"Secp256r1 verification facet\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"This constructor ensures that this contract can only be used as singleton for Proxy contracts\"},\"initializeSigner(bytes)\":{\"notice\":\"Initializes the signer in R1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\"},\"isValidKeyType(bytes)\":{\"notice\":\"Validates if the format of public key is valid for this verification facet\"},\"isValidSignature(bytes32,bytes)\":{\"notice\":\"Validates if the signature is valid. Function to be compatible with EIP-1271\"},\"owner()\":{\"notice\":\"Returns the owner of the account\"},\"uninitializeSigner()\":{\"notice\":\"Uninitialize signer in R1 Facet Storage. This can only be called when the account is undergoing signature migration and has already been initialized.\"},\"validateOwnerSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32)\":{\"notice\":\"Validates if the user operation is signed by the owner.\"},\"validateOwnerSignatureSelector()\":{\"notice\":\"Returns the selector of function to validate the signature of UserOperation\"},\"validateSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256[2])\":{\"notice\":\"Validates if the signature of UserOperation is signed by the given signer\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/verification/secp256r1/Secp256r1VerificationFacet.sol\":\"Secp256r1VerificationFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/utils/math/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\\n * checks.\\n *\\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\\n * easily result in undesired exploitation or bugs, since developers usually\\n * assume that overflows raise errors. `SafeCast` restores this intuition by\\n * reverting the transaction when such an operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n *\\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\\n * all math on `uint256` and `int256` and then downcasting.\\n */\\nlibrary SafeCast {\\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 * _Available since v4.7._\\n */\\n function toUint248(uint256 value) internal pure returns (uint248) {\\n require(value <= type(uint248).max, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint240(uint256 value) internal pure returns (uint240) {\\n require(value <= type(uint240).max, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint232(uint256 value) internal pure returns (uint232) {\\n require(value <= type(uint232).max, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint224(uint256 value) internal pure returns (uint224) {\\n require(value <= type(uint224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint216(uint256 value) internal pure returns (uint216) {\\n require(value <= type(uint216).max, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint208(uint256 value) internal pure returns (uint208) {\\n require(value <= type(uint208).max, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint200(uint256 value) internal pure returns (uint200) {\\n require(value <= type(uint200).max, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint192(uint256 value) internal pure returns (uint192) {\\n require(value <= type(uint192).max, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint184(uint256 value) internal pure returns (uint184) {\\n require(value <= type(uint184).max, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint176(uint256 value) internal pure returns (uint176) {\\n require(value <= type(uint176).max, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint168(uint256 value) internal pure returns (uint168) {\\n require(value <= type(uint168).max, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint160(uint256 value) internal pure returns (uint160) {\\n require(value <= type(uint160).max, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint152(uint256 value) internal pure returns (uint152) {\\n require(value <= type(uint152).max, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint144(uint256 value) internal pure returns (uint144) {\\n require(value <= type(uint144).max, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint136(uint256 value) internal pure returns (uint136) {\\n require(value <= type(uint136).max, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint128(uint256 value) internal pure returns (uint128) {\\n require(value <= type(uint128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint120(uint256 value) internal pure returns (uint120) {\\n require(value <= type(uint120).max, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint112(uint256 value) internal pure returns (uint112) {\\n require(value <= type(uint112).max, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint104(uint256 value) internal pure returns (uint104) {\\n require(value <= type(uint104).max, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint96(uint256 value) internal pure returns (uint96) {\\n require(value <= type(uint96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint88(uint256 value) internal pure returns (uint88) {\\n require(value <= type(uint88).max, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint80(uint256 value) internal pure returns (uint80) {\\n require(value <= type(uint80).max, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint72(uint256 value) internal pure returns (uint72) {\\n require(value <= type(uint72).max, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint64(uint256 value) internal pure returns (uint64) {\\n require(value <= type(uint64).max, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint56(uint256 value) internal pure returns (uint56) {\\n require(value <= type(uint56).max, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint48(uint256 value) internal pure returns (uint48) {\\n require(value <= type(uint48).max, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint40(uint256 value) internal pure returns (uint40) {\\n require(value <= type(uint40).max, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint32(uint256 value) internal pure returns (uint32) {\\n require(value <= type(uint32).max, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint24(uint256 value) internal pure returns (uint24) {\\n require(value <= type(uint24).max, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint16(uint256 value) internal pure returns (uint16) {\\n require(value <= type(uint16).max, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint8(uint256 value) internal pure returns (uint8) {\\n require(value <= type(uint8).max, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\n */\\n function toUint256(int256 value) internal pure returns (uint256) {\\n require(value >= 0, \\\"SafeCast: value must be positive\\\");\\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 * _Available since v4.7._\\n */\\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\\n downcasted = int248(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\\n downcasted = int240(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\\n downcasted = int232(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\\n downcasted = int224(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\\n downcasted = int216(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\\n downcasted = int208(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\\n downcasted = int200(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\\n downcasted = int192(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\\n downcasted = int184(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\\n downcasted = int176(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\\n downcasted = int168(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\\n downcasted = int160(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\\n downcasted = int152(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\\n downcasted = int144(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\\n downcasted = int136(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\\n downcasted = int128(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\\n downcasted = int120(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\\n downcasted = int112(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\\n downcasted = int104(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\\n downcasted = int96(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\\n downcasted = int88(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\\n downcasted = int80(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\\n downcasted = int72(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\\n downcasted = int64(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\\n downcasted = int56(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\\n downcasted = int48(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\\n downcasted = int40(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\\n downcasted = int32(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\\n downcasted = int24(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\\n downcasted = int16(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\\n downcasted = int8(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\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 require(value <= uint256(type(int256).max), \\\"SafeCast: value doesn't fit in an int256\\\");\\n return int256(value);\\n }\\n}\\n\",\"keccak256\":\"0x52a8cfb0f5239d11b457dcdd1b326992ef672714ca8da71a157255bddd13f3ad\",\"license\":\"MIT\"},\"contracts/aa-4337/core/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable no-inline-assembly */\\n\\n/**\\n * returned data from validateUserOp.\\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\\n * @param aggregator - address(0) - the account validated the signature by itself.\\n * address(1) - the account failed to validate the signature.\\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\\n * @param validAfter - this UserOp is valid only after this timestamp.\\n * @param validaUntil - this UserOp is valid only up to this timestamp.\\n */\\nstruct ValidationData {\\n address aggregator;\\n uint48 validAfter;\\n uint48 validUntil;\\n}\\n\\n//extract sigFailed, validAfter, validUntil.\\n// also convert zero validUntil to type(uint48).max\\nfunction _parseValidationData(\\n uint validationData\\n) pure returns (ValidationData memory data) {\\n address aggregator = address(uint160(validationData));\\n uint48 validUntil = uint48(validationData >> 160);\\n if (validUntil == 0) {\\n validUntil = type(uint48).max;\\n }\\n uint48 validAfter = uint48(validationData >> (48 + 160));\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n// intersect account and paymaster ranges.\\nfunction _intersectTimeRange(\\n uint256 validationData,\\n uint256 paymasterValidationData\\n) pure returns (ValidationData memory) {\\n ValidationData memory accountValidationData = _parseValidationData(\\n validationData\\n );\\n ValidationData memory pmValidationData = _parseValidationData(\\n paymasterValidationData\\n );\\n address aggregator = accountValidationData.aggregator;\\n if (aggregator == address(0)) {\\n aggregator = pmValidationData.aggregator;\\n }\\n uint48 validAfter = accountValidationData.validAfter;\\n uint48 validUntil = accountValidationData.validUntil;\\n uint48 pmValidAfter = pmValidationData.validAfter;\\n uint48 pmValidUntil = pmValidationData.validUntil;\\n\\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp\\n * @param data - the ValidationData to pack\\n */\\nfunction _packValidationData(\\n ValidationData memory data\\n) pure returns (uint256) {\\n return\\n uint160(data.aggregator) |\\n (uint256(data.validUntil) << 160) |\\n (uint256(data.validAfter) << (160 + 48));\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp, when not using an aggregator\\n * @param sigFailed - true for signature failure, false for success\\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\\n * @param validAfter first timestamp this UserOperation is valid\\n */\\nfunction _packValidationData(\\n bool sigFailed,\\n uint48 validUntil,\\n uint48 validAfter\\n) pure returns (uint256) {\\n return\\n (sigFailed ? 1 : 0) |\\n (uint256(validUntil) << 160) |\\n (uint256(validAfter) << (160 + 48));\\n}\\n\\n/**\\n * keccak function over calldata.\\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\\n */\\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\\n assembly {\\n let mem := mload(0x40)\\n let len := data.length\\n calldatacopy(mem, data.offset, len)\\n ret := keccak256(mem, len)\\n }\\n}\\n\",\"keccak256\":\"0xa79f06cd158ecb8c0da95493a2f348933b8627a63e228b99738bff3aa107942d\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAggregator.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\n/**\\n * Aggregated Signatures validator.\\n */\\ninterface IAggregator {\\n /**\\n * validate aggregated signature.\\n * revert if the aggregated signature does not match the given list of operations.\\n */\\n function validateSignatures(\\n UserOperation[] calldata userOps,\\n bytes calldata signature\\n ) external view;\\n\\n /**\\n * validate signature of a single userOp\\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\\n * @param userOp the userOperation received from the user.\\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\\n * (usually empty, unless account and aggregator support some kind of \\\"multisig\\\"\\n */\\n function validateUserOpSignature(\\n UserOperation calldata userOp\\n ) external view returns (bytes memory sigForUserOp);\\n\\n /**\\n * aggregate multiple signatures into a single value.\\n * This method is called off-chain to calculate the signature to pass with handleOps()\\n * bundler MAY use optimized custom code perform this aggregation\\n * @param userOps array of UserOperations to collect the signatures from.\\n * @return aggregatedSignature the aggregated signature\\n */\\n function aggregateSignatures(\\n UserOperation[] calldata userOps\\n ) external view returns (bytes memory aggregatedSignature);\\n}\\n\",\"keccak256\":\"0xdfdcd80568f037716674619b31be630fcd8316262f05a815b41d1e81782c966a\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IEntryPoint.sol\":{\"content\":\"/**\\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\\n ** Only one instance required on each chain.\\n **/\\n// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-inline-assembly */\\n/* solhint-disable reason-string */\\n\\nimport \\\"./UserOperation.sol\\\";\\nimport \\\"./IStakeManager.sol\\\";\\nimport \\\"./IAggregator.sol\\\";\\nimport \\\"./INonceManager.sol\\\";\\n\\ninterface IEntryPoint is IStakeManager, INonceManager {\\n /***\\n * An event emitted after each successful request\\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\\n * @param sender - the account that generates this request.\\n * @param paymaster - if non-null, the paymaster that pays for this request.\\n * @param nonce - the nonce value from the request.\\n * @param success - true if the sender transaction succeeded, false if reverted.\\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\\n */\\n event UserOperationEvent(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address indexed paymaster,\\n uint256 nonce,\\n bool success,\\n uint256 actualGasCost,\\n uint256 actualGasUsed\\n );\\n\\n /**\\n * account \\\"sender\\\" was deployed.\\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\\n * @param sender the account that is deployed\\n * @param factory the factory used to deploy this account (in the initCode)\\n * @param paymaster the paymaster used by this UserOp\\n */\\n event AccountDeployed(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address factory,\\n address paymaster\\n );\\n\\n /**\\n * An event emitted if the UserOperation \\\"callData\\\" reverted with non-zero length\\n * @param userOpHash the request unique identifier.\\n * @param sender the sender of this request\\n * @param nonce the nonce used in the request\\n * @param revertReason - the return bytes from the (reverted) call to \\\"callData\\\".\\n */\\n event UserOperationRevertReason(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n uint256 nonce,\\n bytes revertReason\\n );\\n\\n /**\\n * an event emitted by handleOps(), before starting the execution loop.\\n * any event emitted before this event, is part of the validation.\\n */\\n event BeforeExecution();\\n\\n /**\\n * signature aggregator used by the following UserOperationEvents within this bundle.\\n */\\n event SignatureAggregatorChanged(address indexed aggregator);\\n\\n /**\\n * a custom revert error of handleOps, to identify the offending op.\\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\\n * @param reason - revert reason\\n * The string starts with a unique code \\\"AAmn\\\", where \\\"m\\\" is \\\"1\\\" for factory, \\\"2\\\" for account and \\\"3\\\" for paymaster issues,\\n * so a failure can be attributed to the correct entity.\\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\\n */\\n error FailedOp(uint256 opIndex, string reason);\\n\\n /**\\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\\n */\\n error SignatureValidationFailed(address aggregator);\\n\\n /**\\n * Successful result from simulateValidation.\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n */\\n error ValidationResult(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo\\n );\\n\\n /**\\n * Successful result from simulateValidation, if the account returns a signature aggregator\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\\n * bundler MUST use it to verify the signature, or reject the UserOperation\\n */\\n error ValidationResultWithAggregation(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo,\\n AggregatorStakeInfo aggregatorInfo\\n );\\n\\n /**\\n * return value of getSenderAddress\\n */\\n error SenderAddressResult(address sender);\\n\\n /**\\n * return value of simulateHandleOp\\n */\\n error ExecutionResult(\\n uint256 preOpGas,\\n uint256 paid,\\n uint48 validAfter,\\n uint48 validUntil,\\n bool targetSuccess,\\n bytes targetResult\\n );\\n\\n //UserOps handled, per aggregator\\n struct UserOpsPerAggregator {\\n UserOperation[] userOps;\\n // aggregator address\\n IAggregator aggregator;\\n // aggregated signature\\n bytes signature;\\n }\\n\\n /**\\n * Execute a batch of UserOperation.\\n * no signature aggregator is used.\\n * if any account requires an aggregator (that is, it returned an aggregator when\\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\\n * @param ops the operations to execute\\n * @param beneficiary the address to receive the fees\\n */\\n function handleOps(\\n UserOperation[] calldata ops,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * Execute a batch of UserOperation with Aggregators\\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\\n * @param beneficiary the address to receive the fees\\n */\\n function handleAggregatedOps(\\n UserOpsPerAggregator[] calldata opsPerAggregator,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * generate a request Id - unique identifier for this request.\\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\\n */\\n function getUserOpHash(\\n UserOperation calldata userOp\\n ) external view returns (bytes32);\\n\\n /**\\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\\n * @param userOp the user operation to validate.\\n */\\n function simulateValidation(UserOperation calldata userOp) external;\\n\\n /**\\n * gas and return values during simulation\\n * @param preOpGas the gas used for validation (including preValidationGas)\\n * @param prefund the required prefund for this operation\\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\\n */\\n struct ReturnInfo {\\n uint256 preOpGas;\\n uint256 prefund;\\n bool sigFailed;\\n uint48 validAfter;\\n uint48 validUntil;\\n bytes paymasterContext;\\n }\\n\\n /**\\n * returned aggregated signature info.\\n * the aggregator returned by the account, and its current stake.\\n */\\n struct AggregatorStakeInfo {\\n address aggregator;\\n StakeInfo stakeInfo;\\n }\\n\\n /**\\n * Get counterfactual sender address.\\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\\n * this method always revert, and returns the address in SenderAddressResult error\\n * @param initCode the constructor code to be passed into the UserOperation.\\n */\\n function getSenderAddress(bytes memory initCode) external;\\n\\n /**\\n * simulate full execution of a UserOperation (including both validation and target execution)\\n * this method will always revert with \\\"ExecutionResult\\\".\\n * it performs full validation of the UserOperation, but ignores signature error.\\n * an optional target address is called after the userop succeeds, and its value is returned\\n * (before the entire call is reverted)\\n * Note that in order to collect the the success/failure of the target call, it must be executed\\n * with trace enabled to track the emitted events.\\n * @param op the UserOperation to simulate\\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\\n * are set to the return from that call.\\n * @param targetCallData callData to pass to target address\\n */\\n function simulateHandleOp(\\n UserOperation calldata op,\\n address target,\\n bytes calldata targetCallData\\n ) external;\\n}\\n\",\"keccak256\":\"0x9ccb1b188eda8bbf5f6c2d01bd83c3d8b2b04fcf745283051d31fe96d1d8e40f\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/INonceManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\ninterface INonceManager {\\n /**\\n * Return the next nonce for this sender.\\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\\n * But UserOp with different keys can come with arbitrary order.\\n *\\n * @param sender the account address\\n * @param key the high 192 bit of the nonce\\n * @return nonce a full nonce to pass for next UserOp with this sender.\\n */\\n function getNonce(\\n address sender,\\n uint192 key\\n ) external view returns (uint256 nonce);\\n\\n /**\\n * Manually increment the nonce of the sender.\\n * This method is exposed just for completeness..\\n * Account does NOT need to call it, neither during validation, nor elsewhere,\\n * as the EntryPoint will update the nonce regardless.\\n * Possible use-case is call it with various keys to \\\"initialize\\\" their nonces to one, so that future\\n * UserOperations will not pay extra for the first transaction with a given key.\\n */\\n function incrementNonce(uint192 key) external;\\n}\\n\",\"keccak256\":\"0xce478ad0fa0d18a3b785ac854623029e7ab463d05873dfaa365abfa1bf100912\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IStakeManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8.12;\\n\\n/**\\n * manage deposits and stakes.\\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\\n * stake is value locked for at least \\\"unstakeDelay\\\" by the staked entity.\\n */\\ninterface IStakeManager {\\n event Deposited(address indexed account, uint256 totalDeposit);\\n\\n event Withdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /// Emitted when stake or unstake delay are modified\\n event StakeLocked(\\n address indexed account,\\n uint256 totalStaked,\\n uint256 unstakeDelaySec\\n );\\n\\n /// Emitted once a stake is scheduled for withdrawal\\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\\n\\n event StakeWithdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /**\\n * @param deposit the entity's deposit\\n * @param staked true if this entity is staked.\\n * @param stake actual amount of ether staked for this entity.\\n * @param unstakeDelaySec minimum delay to withdraw the stake.\\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\\n * and the rest fit into a 2nd cell.\\n * 112 bit allows for 10^15 eth\\n * 48 bit for full timestamp\\n * 32 bit allows 150 years for unstake delay\\n */\\n struct DepositInfo {\\n uint112 deposit;\\n bool staked;\\n uint112 stake;\\n uint32 unstakeDelaySec;\\n uint48 withdrawTime;\\n }\\n\\n //API struct used by getStakeInfo and simulateValidation\\n struct StakeInfo {\\n uint256 stake;\\n uint256 unstakeDelaySec;\\n }\\n\\n /// @return info - full deposit information of given account\\n function getDepositInfo(\\n address account\\n ) external view returns (DepositInfo memory info);\\n\\n /// @return the deposit (for gas payment) of the account\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * add to the deposit of the given account\\n */\\n function depositTo(address account) external payable;\\n\\n /**\\n * add to the account's stake - amount and delay\\n * any pending unstake is first cancelled.\\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\\n */\\n function addStake(uint32 _unstakeDelaySec) external payable;\\n\\n /**\\n * attempt to unlock the stake.\\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\\n */\\n function unlockStake() external;\\n\\n /**\\n * withdraw from the (unlocked) stake.\\n * must first call unlockStake and wait for the unstakeDelay to pass\\n * @param withdrawAddress the address to send withdrawn value.\\n */\\n function withdrawStake(address payable withdrawAddress) external;\\n\\n /**\\n * withdraw from the deposit.\\n * @param withdrawAddress the address to send withdrawn value.\\n * @param withdrawAmount the amount to withdraw.\\n */\\n function withdrawTo(\\n address payable withdrawAddress,\\n uint256 withdrawAmount\\n ) external;\\n}\\n\",\"keccak256\":\"0xadcea606c9b7aafe6645441f2154a60f271330b0eee5292a632aa71c1672d546\",\"license\":\"GPL-3.0-only\"},\"contracts/aa-4337/interfaces/UserOperation.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable no-inline-assembly */\\n\\nimport {calldataKeccak} from \\\"../core/Helpers.sol\\\";\\n\\n/**\\n * User Operation struct\\n * @param sender the sender account of this request.\\n * @param nonce unique value the sender uses to verify it is not a replay.\\n * @param initCode if set, the account contract will be created by this constructor/\\n * @param callData the method call to execute on this account.\\n * @param callGasLimit the gas limit passed to the callData method call.\\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\\n * @param maxFeePerGas same as EIP-1559 gas parameter.\\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\\n */\\nstruct UserOperation {\\n address sender;\\n uint256 nonce;\\n bytes initCode;\\n bytes callData;\\n uint256 callGasLimit;\\n uint256 verificationGasLimit;\\n uint256 preVerificationGas;\\n uint256 maxFeePerGas;\\n uint256 maxPriorityFeePerGas;\\n bytes paymasterAndData;\\n bytes signature;\\n}\\n\\n/**\\n * Utility functions helpful when working with UserOperation structs.\\n */\\nlibrary UserOperationLib {\\n function getSender(\\n UserOperation calldata userOp\\n ) internal pure returns (address) {\\n address data;\\n //read sender from userOp, which is first userOp member (saves 800 gas...)\\n assembly {\\n data := calldataload(userOp)\\n }\\n return address(uint160(data));\\n }\\n\\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\\n // pay above what he signed for.\\n function gasPrice(\\n UserOperation calldata userOp\\n ) internal view returns (uint256) {\\n unchecked {\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n if (maxFeePerGas == maxPriorityFeePerGas) {\\n //legacy mode (for networks that don't support basefee opcode)\\n return maxFeePerGas;\\n }\\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\\n }\\n }\\n\\n function pack(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes memory ret) {\\n address sender = getSender(userOp);\\n uint256 nonce = userOp.nonce;\\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\\n bytes32 hashCallData = calldataKeccak(userOp.callData);\\n uint256 callGasLimit = userOp.callGasLimit;\\n uint256 verificationGasLimit = userOp.verificationGasLimit;\\n uint256 preVerificationGas = userOp.preVerificationGas;\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\\n\\n return\\n abi.encode(\\n sender,\\n nonce,\\n hashInitCode,\\n hashCallData,\\n callGasLimit,\\n verificationGasLimit,\\n preVerificationGas,\\n maxFeePerGas,\\n maxPriorityFeePerGas,\\n hashPaymasterAndData\\n );\\n }\\n\\n function hash(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes32) {\\n return keccak256(pack(userOp));\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n}\\n\",\"keccak256\":\"0x2429f5cc546bdee08c7e63858d0dda8491eaa3ab5194df884dc948c1154d2834\",\"license\":\"GPL-3.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/facets/interfaces/IVerificationFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {UserOperation} from \\\"../../aa-4337/interfaces/UserOperation.sol\\\";\\n\\n/**\\n * @title Verification Facet Interface\\n * @dev Implements logic for user ops signature verification\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\ninterface IVerificationFacet {\\n event SignerInitialized(bytes);\\n event SignerUninitialized();\\n\\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\\n error VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\\n error VerificationFacet__InitializationFailure();\\n error VerificationFacet__InvalidFacetMapping();\\n\\n function initializeSigner(bytes memory) external returns (uint256);\\n\\n function uninitializeSigner() external returns (uint256);\\n\\n function validateOwnerSignatureSelector() external view returns (bytes4);\\n\\n function owner() external view returns (bytes memory);\\n\\n function isValidKeyType(bytes calldata) external view returns (bool);\\n\\n function validateOwnerSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x72bc370a1d1b5a6d6bde67f5026733fd8f6ba434bb90e73b0bd8627fb1579928\",\"license\":\"Apache-2.0\"},\"contracts/facets/verification/secp256r1/Secp256r1VerificationFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {UserOperation} from \\\"../../../aa-4337/interfaces/UserOperation.sol\\\";\\nimport {LibAppStorage} from \\\"../../../libraries/LibAppStorage.sol\\\";\\nimport {LibLoupe} from \\\"../../../libraries/LibLoupe.sol\\\";\\nimport {LibFacetStorage, Secp256r1VerificationStorage} from \\\"../../../libraries/LibFacetStorage.sol\\\";\\nimport {Base64} from \\\"./utils/Base64.sol\\\";\\nimport {LibSecp256r1} from \\\"./utils/LibSecp256r1.sol\\\";\\nimport {IERC1271} from \\\"../../../interfaces/ERC/IERC1271.sol\\\";\\nimport {IVerificationFacet} from \\\"../../interfaces/IVerificationFacet.sol\\\";\\n\\n/**\\n * @title Secp256r1 verification facet\\n * @dev Primarily used to verify user ops signed with passkeys\\n * @author Ruslan Serebriakov (@rsrbk)\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract Secp256r1VerificationFacet is IVerificationFacet, IERC1271 {\\n error Secp256r1VerificationFacet__InvalidSignerLength();\\n address public immutable self;\\n\\n /**\\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\\n */\\n constructor() {\\n LibAppStorage.enforceSignerInitialize();\\n self = address(this);\\n }\\n\\n /**\\n * @notice Initializes the signer in R1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\\n * @param _publicKey Bytes of owner public key\\n * @return initSuccess Uint value representing the success of init operation\\n */\\n function initializeSigner(\\n bytes calldata _publicKey\\n ) public override returns (uint256 initSuccess) {\\n LibAppStorage.enforceSignerInitialize();\\n\\n if (!isValidKeyType(_publicKey))\\n revert Secp256r1VerificationFacet__InvalidSignerLength();\\n\\n bytes memory publicKeyCoordinates = _publicKey[1:];\\n uint256[2] memory q;\\n assembly {\\n // Copy the bytes from the input data into the uint256 array\\n mstore(q, mload(add(publicKeyCoordinates, 32)))\\n mstore(add(q, 32), mload(add(publicKeyCoordinates, 64)))\\n }\\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\\n .r1Storage();\\n r1Storage.q = q;\\n\\n bytes4 validateSelector = validateOwnerSignatureSelector();\\n\\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\\n if (LibLoupe.facetAddress(validateSelector) != self)\\n revert VerificationFacet__InvalidFacetMapping();\\n\\n // initialize verification function selector\\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\\n\\n initSuccess = 1;\\n\\n emit SignerInitialized(_publicKey);\\n }\\n\\n /**\\n * @notice Uninitialize signer in R1 Facet Storage. This can only be called when the account is undergoing signature migration\\n * and has already been initialized.\\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\\n * @return uninitSuccess Uint value representing the success of uninit operation\\n */\\n function uninitializeSigner()\\n external\\n override\\n returns (uint256 uninitSuccess)\\n {\\n LibAppStorage.enforceSignerMigration();\\n LibAppStorage.setSignerUninitialized();\\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\\n .r1Storage();\\n r1Storage.q = [0, 0];\\n\\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\\n\\n uninitSuccess = 1;\\n\\n emit SignerUninitialized();\\n }\\n\\n /**\\n * @notice Validates if the user operation is signed by the owner.\\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\\n * signer public key.\\n * @param userOp UserOperation including all information for execution\\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\\n */\\n function validateOwnerSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) public view override returns (uint256 validationData) {\\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\\n .r1Storage();\\n validationData = validateSignature(userOp, userOpHash, r1Storage.q);\\n }\\n\\n /**\\n * @notice Validates if the signature of UserOperation is signed by the given signer\\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\\n * @param userOp UserOperation including all information for execution\\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\\n * @param q Public Key of signer who signed the contract, to be validated\\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\\n */\\n function validateSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n uint256[2] memory q\\n ) public view returns (uint256 isValid) {\\n isValid = (_validateSignature(q, userOpHash, userOp.signature)) ? 0 : 1;\\n }\\n\\n /**\\n * @notice Returns the selector of function to validate the signature of UserOperation\\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\\n */\\n function validateOwnerSignatureSelector()\\n public\\n pure\\n override\\n returns (bytes4 ownerSignatureValidatorSelector)\\n {\\n return this.validateOwnerSignature.selector; // validateOwnerSignature(UserOperation calldata userOp,bytes32 userOpHash)\\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\\n }\\n\\n /**\\n * @notice Returns the owner of the account\\n * @return signer Bytes of owner address\\n */\\n function owner() public view override returns (bytes memory signer) {\\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\\n .r1Storage();\\n signer = abi.encodePacked(r1Storage.q);\\n }\\n\\n /**\\n * @notice Validates if the format of public key is valid for this verification facet\\n * @dev For this Secp256k1Verification Facet, the public key should in an uncompressed public key format\\n * @param _publicKey Bytes of public key for format check\\n * @return isValid Boolean variable representing if the format of public key is valid\\n */\\n function isValidKeyType(\\n bytes memory _publicKey\\n ) public pure override returns (bool isValid) {\\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\\n }\\n\\n /**\\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\\n * @param _hash Hash value the owner signed\\n * @param _signature Signature that signed the above hash\\n * @return magicValue Bytes4 value representing the success/failure of validation\\n */\\n function isValidSignature(\\n bytes32 _hash,\\n bytes memory _signature\\n ) public view override returns (bytes4 magicValue) {\\n magicValue = _validateSignature(\\n LibFacetStorage.r1Storage().q,\\n _hash,\\n _signature\\n )\\n ? this.isValidSignature.selector\\n : bytes4(0xffffffff);\\n }\\n\\n function _validateSignature(\\n uint256[2] memory q,\\n bytes32 _hash,\\n bytes memory _signature\\n ) internal view returns (bool) {\\n (\\n uint256 rValue,\\n uint256 sValue,\\n bytes memory authenticatorData,\\n string memory clientDataJSONPre,\\n string memory clientDataJSONPost\\n ) = abi.decode(_signature, (uint256, uint256, bytes, string, string));\\n bytes32 clientHash;\\n {\\n string memory opHashBase64 = Base64.encode(bytes.concat(_hash));\\n string memory clientDataJSON = string.concat(\\n clientDataJSONPre,\\n opHashBase64,\\n clientDataJSONPost\\n );\\n clientHash = sha256(bytes(clientDataJSON));\\n }\\n bytes32 sigHash = sha256(bytes.concat(authenticatorData, clientHash));\\n return LibSecp256r1.Verify(q, rValue, sValue, uint256(sigHash));\\n }\\n}\\n\",\"keccak256\":\"0xdb3bae77323eef4e16ef5a5342f548527c9e82b44e8e9dab90906dc2c00082ff\",\"license\":\"Apache-2.0\"},\"contracts/facets/verification/secp256r1/utils/Base64.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @dev Provides a set of functions to operate with Base64 strings.\\n * modified for base64url https://datatracker.ietf.org/doc/html/rfc4648#section-5\\n * _Available since v4.5._\\n */\\nlibrary Base64 {\\n /**\\n * @dev Base64 Encoding/Decoding Table\\n */\\n string internal constant _TABLE =\\n \\\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_\\\";\\n\\n /**\\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\\n */\\n function encode(bytes memory data) internal pure returns (string memory) {\\n /**\\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\\n */\\n if (data.length == 0) return \\\"\\\";\\n\\n // Loads the table into memory\\n string memory table = _TABLE;\\n\\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\\n // and split into 4 numbers of 6 bits.\\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\\n // - `data.length + 2` -> Round up\\n // - `/ 3` -> Number of 3-bytes chunks\\n // - `4 *` -> 4 characters for each chunk\\n uint256 newlength = (data.length * 8) / 6;\\n if (data.length % 6 > 0) {\\n newlength++;\\n }\\n string memory result = new string(newlength);\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n // Prepare the lookup table (skip the first \\\"length\\\" byte)\\n let tablePtr := add(table, 1)\\n\\n // Prepare result pointer, jump over length\\n let resultPtr := add(result, 32)\\n\\n // Run over the input, 3 bytes at a time\\n for {\\n let dataPtr := data\\n let endPtr := add(data, mload(data))\\n } lt(dataPtr, endPtr) {\\n\\n } {\\n // Advance 3 bytes\\n dataPtr := add(dataPtr, 3)\\n let input := mload(dataPtr)\\n\\n // To write each character, shift the 3 bytes (18 bits) chunk\\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\\n // and apply logical AND with 0x3F which is the number of\\n // the previous character in the ASCII table prior to the Base64 Table\\n // The result is then added to the table to get the character to write,\\n // and finally write it in the result pointer but with a left shift\\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\\n\\n mstore8(\\n resultPtr,\\n mload(add(tablePtr, and(shr(18, input), 0x3F)))\\n )\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(\\n resultPtr,\\n mload(add(tablePtr, and(shr(12, input), 0x3F)))\\n )\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(\\n resultPtr,\\n mload(add(tablePtr, and(shr(6, input), 0x3F)))\\n )\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n }\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0xbf0afa21e5a128f260c1a8d4333dc0b0e8755a50d37dfa9b5d362d36ef9cdc14\",\"license\":\"Apache-2.0\"},\"contracts/facets/verification/secp256r1/utils/LibSecp256r1.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n// Heavily inspired from\\n// https://github.com/maxrobot/elliptic-solidity/blob/master/contracts/Secp256r1.sol\\n// https://github.com/tdrerup/elliptic-curve-solidity/blob/master/contracts/curves/EllipticCurve.sol\\n// modified to use precompile 0x05 modexp\\n// and modified jacobian double\\n// optimisations to avoid to an from from affine and jacobian coordinates\\n\\n// Additional Elliptic curve Public key / Signature validation added by\\n// David Yonjun Kim (@Powerstream3604)\\n\\nstruct JPoint {\\n uint256 x;\\n uint256 y;\\n uint256 z;\\n}\\n\\nlibrary LibSecp256r1 {\\n uint256 constant gx =\\n 0x6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296;\\n uint256 constant gy =\\n 0x4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5;\\n uint256 public constant pp =\\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF;\\n\\n uint256 public constant nn =\\n 0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551;\\n uint256 constant a =\\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC;\\n uint256 constant b =\\n 0x5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B;\\n uint256 constant MOST_SIGNIFICANT =\\n 0xc000000000000000000000000000000000000000000000000000000000000000;\\n\\n /*\\n * Verify\\n * @description - verifies that a public key has signed a given message\\n * @param Q - public key coordinates X & Y\\n * @param R - signature half R\\n * @param S - signature half S\\n * @param input - hashed message\\n */\\n function Verify(\\n uint256[2] memory q,\\n uint r,\\n uint s,\\n uint e\\n ) internal view returns (bool) {\\n if (q[0] > pp - 1 || q[1] > pp - 1) {\\n return false;\\n }\\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\\n return false;\\n }\\n if (\\n mulmod(q[1], q[1], pp) !=\\n addmod(\\n addmod(\\n mulmod(q[0], mulmod(q[0], q[0], pp), pp),\\n mulmod(a, q[0], pp),\\n pp\\n ),\\n b,\\n pp\\n )\\n ) {\\n return false;\\n }\\n\\n JPoint[16] memory points = _preComputeJacobianPoints(q);\\n return VerifyWithPrecompute(points, r, s, e);\\n }\\n\\n function VerifyWithPrecompute(\\n JPoint[16] memory points,\\n uint r,\\n uint s,\\n uint e\\n ) internal view returns (bool) {\\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\\n return false;\\n }\\n\\n uint w = _primemod(s, nn);\\n\\n uint u1 = mulmod(e, w, nn);\\n uint u2 = mulmod(r, w, nn);\\n\\n uint x;\\n uint y;\\n\\n (x, y) = ShamirMultJacobian(points, u1, u2);\\n return (x == r);\\n }\\n\\n /*\\n * Strauss Shamir trick for EC multiplication\\n * https://stackoverflow.com/questions/50993471/ec-scalar-multiplication-with-strauss-shamir-method\\n * we optimise on this a bit to do with 2 bits at a time rather than a single bit\\n * the individual points for a single pass are precomputed\\n * overall this reduces the number of additions while keeping the same number of doublings\\n */\\n function ShamirMultJacobian(\\n JPoint[16] memory points,\\n uint u1,\\n uint u2\\n ) internal view returns (uint, uint) {\\n uint x = 0;\\n uint y = 0;\\n uint z = 0;\\n uint bits = 128;\\n uint index = 0;\\n\\n while (bits > 0) {\\n if (z > 0) {\\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\\n }\\n index =\\n ((u1 & MOST_SIGNIFICANT) >> 252) |\\n ((u2 & MOST_SIGNIFICANT) >> 254);\\n if (index > 0) {\\n (x, y, z) = _jAdd(\\n x,\\n y,\\n z,\\n points[index].x,\\n points[index].y,\\n points[index].z\\n );\\n }\\n u1 <<= 2;\\n u2 <<= 2;\\n bits--;\\n }\\n (x, y) = _affineFromJacobian(x, y, z);\\n return (x, y);\\n }\\n\\n function _preComputeJacobianPoints(\\n uint256[2] memory q\\n ) internal pure returns (JPoint[16] memory points) {\\n points[0] = JPoint(0, 0, 0);\\n points[1] = JPoint(q[0], q[1], 1); // u2\\n points[2] = _jPointDouble(points[1]);\\n points[3] = _jPointAdd(points[1], points[2]);\\n\\n points[4] = JPoint(gx, gy, 1); // u1Points[1]\\n points[5] = _jPointAdd(points[4], points[1]);\\n points[6] = _jPointAdd(points[4], points[2]);\\n points[7] = _jPointAdd(points[4], points[3]);\\n\\n points[8] = _jPointDouble(points[4]); // u1Points[2]\\n points[9] = _jPointAdd(points[8], points[1]);\\n points[10] = _jPointAdd(points[8], points[2]);\\n points[11] = _jPointAdd(points[8], points[3]);\\n\\n points[12] = _jPointAdd(points[4], points[8]); // u1Points[3]\\n points[13] = _jPointAdd(points[12], points[1]);\\n points[14] = _jPointAdd(points[12], points[2]);\\n points[15] = _jPointAdd(points[12], points[3]);\\n }\\n\\n function _jPointAdd(\\n JPoint memory p1,\\n JPoint memory p2\\n ) internal pure returns (JPoint memory) {\\n uint x;\\n uint y;\\n uint z;\\n (x, y, z) = _jAdd(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z);\\n return JPoint(x, y, z);\\n }\\n\\n function _jPointDouble(\\n JPoint memory p\\n ) internal pure returns (JPoint memory) {\\n uint x;\\n uint y;\\n uint z;\\n (x, y, z) = _modifiedJacobianDouble(p.x, p.y, p.z);\\n return JPoint(x, y, z);\\n }\\n\\n /* _affineFromJacobian\\n * @desription returns affine coordinates from a jacobian input follows\\n * golang elliptic/crypto library\\n */\\n function _affineFromJacobian(\\n uint x,\\n uint y,\\n uint z\\n ) internal view returns (uint ax, uint ay) {\\n if (z == 0) {\\n return (0, 0);\\n }\\n\\n uint zinv = _primemod(z, pp);\\n uint zinvsq = mulmod(zinv, zinv, pp);\\n\\n ax = mulmod(x, zinvsq, pp);\\n ay = mulmod(y, mulmod(zinvsq, zinv, pp), pp);\\n }\\n\\n /*\\n * _jAdd\\n * @description performs Jacobian addition as defined below:\\n * http://www.hyperelliptic.org/EFD/g1p/data/shortw/jacobian/addition/add-2007-bl\\n */\\n function _jAdd(\\n uint p1,\\n uint p2,\\n uint p3,\\n uint q1,\\n uint q2,\\n uint q3\\n ) internal pure returns (uint r1, uint r2, uint r3) {\\n if (p3 == 0) {\\n r1 = q1;\\n r2 = q2;\\n r3 = q3;\\n\\n return (r1, r2, r3);\\n } else if (q3 == 0) {\\n r1 = p1;\\n r2 = p2;\\n r3 = p3;\\n\\n return (r1, r2, r3);\\n }\\n\\n assembly {\\n let\\n pd\\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\\n let z1z1 := mulmod(p3, p3, pd) // Z1Z1 = Z1^2\\n let z2z2 := mulmod(q3, q3, pd) // Z2Z2 = Z2^2\\n\\n let u1 := mulmod(p1, z2z2, pd) // U1 = X1*Z2Z2\\n let u2 := mulmod(q1, z1z1, pd) // U2 = X2*Z1Z1\\n\\n let s1 := mulmod(p2, mulmod(z2z2, q3, pd), pd) // S1 = Y1*Z2*Z2Z2\\n let s2 := mulmod(q2, mulmod(z1z1, p3, pd), pd) // S2 = Y2*Z1*Z1Z1\\n\\n let p3q3 := addmod(p3, q3, pd)\\n\\n if lt(u2, u1) {\\n u2 := add(pd, u2) // u2 = u2+pd\\n }\\n let h := sub(u2, u1) // H = U2-U1\\n\\n let i := mulmod(0x02, h, pd)\\n i := mulmod(i, i, pd) // I = (2*H)^2\\n\\n let j := mulmod(h, i, pd) // J = H*I\\n if lt(s2, s1) {\\n s2 := add(pd, s2) // u2 = u2+pd\\n }\\n let rr := mulmod(0x02, sub(s2, s1), pd) // r = 2*(S2-S1)\\n r1 := mulmod(rr, rr, pd) // X3 = R^2\\n\\n let v := mulmod(u1, i, pd) // V = U1*I\\n let j2v := addmod(j, mulmod(0x02, v, pd), pd)\\n if lt(r1, j2v) {\\n r1 := add(pd, r1) // X3 = X3+pd\\n }\\n r1 := sub(r1, j2v)\\n\\n // Y3 = r*(V-X3)-2*S1*J\\n let s12j := mulmod(mulmod(0x02, s1, pd), j, pd)\\n\\n if lt(v, r1) {\\n v := add(pd, v)\\n }\\n r2 := mulmod(rr, sub(v, r1), pd)\\n\\n if lt(r2, s12j) {\\n r2 := add(pd, r2)\\n }\\n r2 := sub(r2, s12j)\\n\\n // Z3 = ((Z1+Z2)^2-Z1Z1-Z2Z2)*H\\n z1z1 := addmod(z1z1, z2z2, pd)\\n j2v := mulmod(p3q3, p3q3, pd)\\n if lt(j2v, z1z1) {\\n j2v := add(pd, j2v)\\n }\\n r3 := mulmod(sub(j2v, z1z1), h, pd)\\n }\\n return (r1, r2, r3);\\n }\\n\\n // Point doubling on the modified jacobian coordinates\\n // http://point-at-infinity.org/ecc/Prime_Curve_Modified_Jacobian_Coordinates.html\\n function _modifiedJacobianDouble(\\n uint x,\\n uint y,\\n uint z\\n ) internal pure returns (uint x3, uint y3, uint z3) {\\n if (y == 0) return (0, 0, 0);\\n assembly {\\n let\\n pd\\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\\n let z2 := mulmod(z, z, pd)\\n let az4 := mulmod(\\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC,\\n mulmod(z2, z2, pd),\\n pd\\n )\\n let y2 := mulmod(y, y, pd)\\n let s := mulmod(0x04, mulmod(x, y2, pd), pd)\\n let u := mulmod(0x08, mulmod(y2, y2, pd), pd)\\n let m := addmod(mulmod(0x03, mulmod(x, x, pd), pd), az4, pd)\\n let twos := mulmod(0x02, s, pd)\\n let m2 := mulmod(m, m, pd)\\n if lt(m2, twos) {\\n m2 := add(pd, m2)\\n }\\n x3 := sub(m2, twos)\\n if lt(s, x3) {\\n s := add(pd, s)\\n }\\n y3 := mulmod(m, sub(s, x3), pd)\\n if lt(y3, u) {\\n y3 := add(pd, y3)\\n }\\n y3 := sub(y3, u)\\n z3 := mulmod(0x02, mulmod(y, z, pd), pd)\\n }\\n }\\n\\n // Fermats little theorem https://en.wikipedia.org/wiki/Fermat%27s_little_theorem\\n // a^(p-1) = 1 mod p\\n // a^(-1) \\u2245 a^(p-2) (mod p)\\n // we then use the precompile bigModExp to compute a^(-1)\\n function _primemod(uint value, uint p) internal view returns (uint ret) {\\n ret = modexp(value, p - 2, p);\\n return ret;\\n }\\n\\n // Wrapper for built-in BigNumber_modexp (contract 0x5) as described here. https://github.com/ethereum/EIPs/pull/198\\n function modexp(\\n uint _base,\\n uint _exp,\\n uint _mod\\n ) internal view returns (uint ret) {\\n // bigModExp(_base, _exp, _mod);\\n assembly {\\n if gt(_base, _mod) {\\n _base := mod(_base, _mod)\\n }\\n // Free memory pointer is always stored at 0x40\\n let freemem := mload(0x40)\\n\\n mstore(freemem, 0x20)\\n mstore(add(freemem, 0x20), 0x20)\\n mstore(add(freemem, 0x40), 0x20)\\n\\n mstore(add(freemem, 0x60), _base)\\n mstore(add(freemem, 0x80), _exp)\\n mstore(add(freemem, 0xa0), _mod)\\n\\n let success := staticcall(14000, 0x5, freemem, 0xc0, freemem, 0x20)\\n switch success\\n case 0 {\\n revert(0x0, 0x0)\\n }\\n default {\\n ret := mload(freemem)\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb53714ba63cddb379ba312c1e7f6a423f4d7a7e34fa1364ec8295cd57d544024\",\"license\":\"GPL-3.0\"},\"contracts/infrastructure/interfaces/IFacetRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Registry Interface\\n * @dev Interface for Facet Registry contract to keep track of facets & function selectors addable to user wallets\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IFacetRegistry {\\n struct FacetRegistryConfig {\\n bytes4[] selectors;\\n mapping(bytes4 => FacetInfo) info;\\n }\\n struct FacetInfo {\\n bool exists;\\n uint128 index;\\n }\\n\\n event FacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] facetSelectors\\n );\\n event FacetFunctionSelectorsRemoved(address facet, bytes4[] facetSelectors);\\n\\n error FacetRegistry__FacetSelectorAlreadyRegistered();\\n error FacetRegistry__UnregisteredFacetSelector();\\n\\n function registerFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function removeFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function areFacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external view returns (bool);\\n\\n function isFacetFunctionSelectorRegistered(\\n address facet,\\n bytes4 facetSelector\\n ) external view returns (bool);\\n\\n function getFacetFunctionSelectors(\\n address facet\\n ) external view returns (bytes4[] memory);\\n}\\n\",\"keccak256\":\"0x6e6dd2cab346ef7c31230740ec48d2925e4a9ab24c2f2fb268baaf408dcf02ef\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC1271 {\\n function isValidSignature(\\n bytes32 hash,\\n bytes memory signature\\n ) external view returns (bytes4);\\n}\\n\",\"keccak256\":\"0xcdddb7d5641c9d3f2432dec7fd13fddb9ae1480f25c76c21511e2fa16b8bd422\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibAppStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {SafeCast} from \\\"@openzeppelin/contracts/utils/math/SafeCast.sol\\\";\\nimport {IEntryPoint} from \\\"../aa-4337/interfaces/IEntryPoint.sol\\\";\\nimport {IFacetRegistry} from \\\"../infrastructure/interfaces/IFacetRegistry.sol\\\";\\n\\n/*\\n * @title App Storage\\n * @dev App storage for Barz contract to prevent storage collision\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Lock {\\n uint64 release;\\n bytes4 locker;\\n}\\n\\nstruct InitializersStorage {\\n // NOTE: initialized is a variable to make sure the initialization is only done once.\\n uint8 signerInitialized;\\n uint8 accountInitialized;\\n uint8 restrictionsInitialized;\\n}\\n\\nstruct AppStorage {\\n mapping(uint256 => InitializersStorage) initStorage;\\n uint8 signerMigration;\\n bytes4 validateOwnerSignatureSelector;\\n IEntryPoint entryPoint;\\n IFacetRegistry facetRegistry;\\n mapping(uint256 => Lock) locks;\\n}\\n\\nlibrary LibAppStorage {\\n error LibAppStorage__AccountAlreadyUninitialized();\\n error LibAppStorage__AccountMustBeUninitialized();\\n error LibAppStorage__SignerAlreadyUninitialized();\\n error LibAppStorage__SignerMustBeUninitialized();\\n\\n function appStorage() internal pure returns (AppStorage storage ds) {\\n assembly {\\n ds.slot := 0\\n }\\n }\\n\\n function setSignerUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerAlreadyUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 0;\\n }\\n\\n function getValidateOwnerSignatureSelector()\\n internal\\n view\\n returns (bytes4 selector)\\n {\\n selector = appStorage().validateOwnerSignatureSelector;\\n }\\n\\n function setValidateOwnerSignatureSelector(\\n bytes4 _validateOwnerSignatureSelector\\n ) internal {\\n appStorage()\\n .validateOwnerSignatureSelector = _validateOwnerSignatureSelector;\\n }\\n\\n function enforceSignerInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerMustBeUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 1;\\n }\\n\\n function enforceAccountInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].accountInitialized) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n s.initStorage[0].accountInitialized = 1;\\n }\\n\\n function initiateSignerMigration() internal {\\n appStorage().signerMigration = 1;\\n }\\n\\n function enforceSignerMigration() internal view {\\n if (1 != appStorage().signerMigration) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n }\\n\\n function finalizeSignerMigration() internal {\\n appStorage().signerMigration = 0;\\n }\\n\\n function setLock(uint256 _releaseAfter, bytes4 _locker) internal {\\n appStorage().locks[0] = Lock(SafeCast.toUint64(_releaseAfter), _locker);\\n }\\n\\n function enforceRestrictionsInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__SignerMustBeUninitialized();\\n s.initStorage[0].restrictionsInitialized = 1;\\n }\\n\\n function setRestrictionsUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__AccountAlreadyUninitialized();\\n s.initStorage[0].restrictionsInitialized = 0;\\n }\\n}\\n\\ncontract BarzStorage {\\n AppStorage internal s;\\n modifier onlyWhenUnlocked() {\\n require(\\n uint64(block.timestamp) >= s.locks[0].release,\\n \\\"Account Locked\\\"\\n );\\n _;\\n }\\n modifier onlyWhenLocked() {\\n require(\\n uint64(block.timestamp) < s.locks[0].release,\\n \\\"Account Unlocked\\\"\\n );\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x48524007862a6ce0e07f645950613ce6513ce073c37a109c75019683d42bae27\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\\n bytes4(keccak256(\\\"verifyRestrictions(address,address,uint256,bytes)\\\"));\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // Default Fallback Handler of the barz.\\n IDiamondLoupe defaultFallbackHandler;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function enforceIsSelf() internal view {\\n require(msg.sender == address(this), \\\"LibDiamond: Caller not self\\\");\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n\\n unchecked {\\n facetIndex++;\\n }\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n\\n function restrictionsFacet() internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(\\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2cabdc00de859c3a3170ce3bda5d0e5fd3933d47ce904fd1585f9818b02572f8\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibFacetStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Storage\\n * @dev Storage contract to store each facets variables with diamond storage\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Secp256k1VerificationStorage {\\n address signer;\\n}\\n\\nstruct Secp256r1VerificationStorage {\\n uint256[2] q;\\n}\\n\\nstruct GuardianStorage {\\n mapping(bytes32 => uint256) pending;\\n mapping(uint8 => StorageConfig) configs;\\n}\\n\\nstruct Info {\\n bool exists;\\n uint128 index;\\n}\\n\\nstruct StorageConfig {\\n address[] addresses;\\n mapping(address => Info) info;\\n}\\n\\nstruct RecoveryConfig {\\n bytes recoveryPublicKey;\\n uint64 executeAfter;\\n}\\n\\nstruct ApprovalConfig {\\n bool isApproved;\\n uint64 validUntil;\\n}\\n\\nstruct RecoveryApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isNewOwnerApproved;\\n}\\n\\nstruct RecoveryStorage {\\n mapping(uint8 => RecoveryConfig) recoveryConfigs;\\n mapping(uint8 => RecoveryApprovalConfig) recoveryApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct RestrictionsStorage {\\n address[] restrictions;\\n mapping(address => bool) exists;\\n}\\n\\nstruct SignatureMigrationConfig {\\n bytes migrationPublicKey;\\n address migrationVerificationFacet;\\n bytes4[] migrationSelectors;\\n uint64 migrateAfter;\\n}\\n\\nstruct SignatureMigrationApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isMigrationApproved;\\n}\\n\\nstruct SignatureMigrationStorage {\\n mapping(uint8 => SignatureMigrationConfig) migrationConfigs;\\n mapping(uint8 => SignatureMigrationApprovalConfig) migrationApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct DiamondCutApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isDiamondCutApproved;\\n}\\n\\nstruct DiamondCutStorage {\\n mapping(uint8 => DiamondCutApprovalConfig) diamondCutApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct LockStorage {\\n uint128 nonce;\\n}\\n\\nlibrary LibFacetStorage {\\n bytes32 constant K1_STORAGE_POSITION =\\n keccak256(\\n \\\"v0.trustwallet.diamond.storage.Secp256k1VerificationStorage\\\"\\n );\\n bytes32 constant R1_STORAGE_POSITION =\\n keccak256(\\n \\\"v0.trustwallet.diamond.storage.Secp256r1VerificationStorage\\\"\\n );\\n bytes32 constant GUARDIAN_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.GuardianStorage\\\");\\n bytes32 constant RECOVERY_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.RecoveryStorage\\\");\\n bytes32 constant RESTRICTION_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.RestrictionsStorage\\\");\\n bytes32 constant MIGRATION_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.SignatureMigrationStorage\\\");\\n bytes32 constant DIAMONDCUT_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.DiamondCutStorage\\\");\\n bytes32 constant LOCK_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.LockStorage\\\");\\n\\n function k1Storage()\\n internal\\n pure\\n returns (Secp256k1VerificationStorage storage ds)\\n {\\n bytes32 storagePosition = K1_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function r1Storage()\\n internal\\n pure\\n returns (Secp256r1VerificationStorage storage ds)\\n {\\n bytes32 storagePosition = R1_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function guardianStorage()\\n internal\\n pure\\n returns (GuardianStorage storage ds)\\n {\\n bytes32 storagePosition = GUARDIAN_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function recoveryStorage()\\n internal\\n pure\\n returns (RecoveryStorage storage ds)\\n {\\n bytes32 storagePosition = RECOVERY_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function restrictionsStorage()\\n internal\\n pure\\n returns (RestrictionsStorage storage ds)\\n {\\n bytes32 storagePosition = RESTRICTION_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function migrationStorage()\\n internal\\n pure\\n returns (SignatureMigrationStorage storage ds)\\n {\\n bytes32 storagePosition = MIGRATION_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function diamondCutStorage()\\n internal\\n pure\\n returns (DiamondCutStorage storage ds)\\n {\\n bytes32 storagePosition = DIAMONDCUT_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function lockStorage() internal pure returns (LockStorage storage ds) {\\n bytes32 storagePosition = LOCK_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n}\\n\",\"keccak256\":\"0x87c85decfd943deda9540733e464cb1a92eba735a301e89ce6f798016e359761\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\nimport {LibDiamond} from \\\"./LibDiamond.sol\\\";\\n\\n/**\\n * @title LibLoupe\\n * @dev Internal Library to provide utility feature for reading the state of diamond facets\\n * Originally from Diamond's implementation of Mudgen(author of EIP-2535)\\n */\\nlibrary LibLoupe {\\n /// @notice Gets all facets and their selectors.\\n /// @return facets_ Facet\\n function facets()\\n internal\\n view\\n returns (IDiamondLoupe.Facet[] memory facets_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facets_ = new IDiamondLoupe.Facet[](ds.selectorCount);\\n uint16[] memory numFacetSelectors = new uint16[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facets_[facetIndex].facetAddress == facetAddress_) {\\n facets_[facetIndex].functionSelectors[\\n numFacetSelectors[facetIndex]\\n ] = selector;\\n // probably will never have more than 256 functions from one facet contract\\n require(numFacetSelectors[facetIndex] < 255);\\n numFacetSelectors[facetIndex]++;\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facets_[numFacets].facetAddress = facetAddress_;\\n facets_[numFacets].functionSelectors = new bytes4[](\\n ds.selectorCount\\n );\\n facets_[numFacets].functionSelectors[0] = selector;\\n numFacetSelectors[numFacets] = 1;\\n numFacets++;\\n }\\n }\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n uint256 numSelectors = numFacetSelectors[facetIndex];\\n bytes4[] memory selectors = facets_[facetIndex].functionSelectors;\\n // setting the number of selectors\\n assembly {\\n mstore(selectors, numSelectors)\\n }\\n }\\n // setting the number of facets\\n assembly {\\n mstore(facets_, numFacets)\\n }\\n }\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return _facetFunctionSelectors The selectors associated with a facet address.\\n function facetFunctionSelectors(\\n address _facet\\n ) internal view returns (bytes4[] memory _facetFunctionSelectors) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n uint256 numSelectors;\\n _facetFunctionSelectors = new bytes4[](ds.selectorCount);\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facet = address(bytes20(ds.facets[selector]));\\n if (_facet == facet) {\\n _facetFunctionSelectors[numSelectors] = selector;\\n numSelectors++;\\n }\\n }\\n }\\n // Set the number of selectors in the array\\n assembly {\\n mstore(_facetFunctionSelectors, numSelectors)\\n }\\n }\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n internal\\n view\\n returns (address[] memory facetAddresses_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetAddresses_ = new address[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facetAddress_ == facetAddresses_[facetIndex]) {\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facetAddresses_[numFacets] = facetAddress_;\\n numFacets++;\\n }\\n }\\n // Set the number of facet addresses in the array\\n assembly {\\n mstore(facetAddresses_, numFacets)\\n }\\n }\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(LibDiamond.diamondStorage().facets[_functionSelector])\\n );\\n }\\n}\\n\",\"keccak256\":\"0x0b11439c3cc657095e15ec2241fdcf67204b14001357b612fc5db4ff9e760a5a\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x60a060405234801561001057600080fd5b50610019610022565b3060805261008b565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff161561006f57604051637c2cde8b60e01b815260040160405180910390fd5b600080805260209190915260409020805460ff19166001179055565b608051611f746100ad6000396000818161016001526106e10152611f746000f3fe608060405234801561001057600080fd5b50600436106100a35760003560e01c80637104ddb2116100765780638dd501211161005b5780638dd50121146101bc578063cd00e50a146101cf578063cd9b47e4146101d757600080fd5b80637104ddb21461015b5780638da5cb5b146101a757600080fd5b806311cfe388146100a85780631626ba7e146100ce5780633253960f14610112578063392dd6d914610138575b600080fd5b6100bb6100b6366004611823565b6101ea565b6040519081526020015b60405180910390f35b6100e16100dc366004611956565b610252565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020016100c5565b7f8dd50121000000000000000000000000000000000000000000000000000000006100e1565b61014b61014636600461199d565b6102fd565b60405190151581526020016100c5565b6101827f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100c5565b6101af61036f565b6040516100c591906119f6565b6100bb6101ca366004611a47565b6103ba565b6100bb61041f565b6100bb6101e5366004611a8c565b61053a565b600061023982846101ff610140880188611afe565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061083692505050565b610244576001610247565b60005b60ff16949350505050565b60006102aa7f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b1653646040805180820191829052919060029082845b81548152602001906001019080831161028b5750505050508484610836565b6102d4577fffffffff000000000000000000000000000000000000000000000000000000006102f6565b7f1626ba7e000000000000000000000000000000000000000000000000000000005b9392505050565b60008151604114801561036957508160008151811061031e5761031e611b6a565b6020910101517fff00000000000000000000000000000000000000000000000000000000000000167f0400000000000000000000000000000000000000000000000000000000000000145b92915050565b6040516060907f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364906103a5908290602001611b99565b60405160208183030381529060405291505090565b60408051808201918290526000917f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364916104179186918691859060029082845b8154815260200190600101908083116103fa5750505050506101ea565b949350505050565b60006104296109b4565b6104316109f4565b60408051808201909152600080825260208201527f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364906104749082906002611675565b506000610488600154610100900460e01b90565b7fffffffff0000000000000000000000000000000000000000000000000000000016036104e1576040517f127c609a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff169055604051600192507fcccd30db6bc000b8bb8d11162228d2d69e3c361983ca3ae8c1365ce64b0fae9e90600090a15090565b6000610544610a93565b61058383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102fd92505050565b6105b9576040517f6c334d2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006105c88360018187611bcd565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092935061060992506116b8915050565b602082015181526040820151602082015260006106437f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b16536490565b9050610651818360026116d6565b507f8dd50121000000000000000000000000000000000000000000000000000000006000610686600154610100900460e01b90565b7fffffffff0000000000000000000000000000000000000000000000000000000016146106df576040517f5f95a63c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16610770827fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604090205460601c90565b73ffffffffffffffffffffffffffffffffffffffff16146107bd576040517fbb4752b700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff1661010060e084901c02179055600194507f6d54821a69ec281ed7ba1bf2729c700768c47df1d80fad646b0a14cc1d5c39ed8787604051610824929190611bf7565b60405180910390a15050505092915050565b600080600080600080868060200190518101906108539190611c94565b9450945094509450945060008061088a8a60405160200161087691815260200190565b604051602081830303815290604052610b33565b905060008482856040516020016108a393929190611d47565b60405160208183030381529060405290506002816040516108c49190611d8a565b602060405180830381855afa1580156108e1573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906109049190611da6565b9250505060006002858360405160200161091f929190611dbf565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905261095791611d8a565b602060405180830381855afa158015610974573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906109979190611da6565b90506109a58b888884610c6f565b9b9a5050505050505050505050565b6001805460ff16146109f2576040517f38fc28cb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff16600114610a5c576040517fe00d7c7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff1615610af9576040517f7c2cde8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b60608151600003610b5257505060408051602081019091526000815290565b6000604051806060016040528060408152602001611eff6040913990506000600684516008610b819190611e10565b610b8b9190611e56565b9050600060068551610b9d9190611e6a565b1115610bb15780610bad81611e7e565b9150505b60008167ffffffffffffffff811115610bcc57610bcc61177c565b6040519080825280601f01601f191660200182016040528015610bf6576020820181803683370190505b509050600183016020820186875188015b80821015610c62576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f8116850151845350600183019250610c07565b5092979650505050505050565b6000610c9c60017fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611eb6565b85511180610cd75750610cd060017fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611eb6565b6020860151115b15610ce457506000610417565b831580610cef575082155b80610d1a57507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518410155b80610d4557507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518310155b15610d5257506000610417565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff7f5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff8088600060200201517fffffffff00000001000000000000000000000000fffffffffffffffffffffffc0988517fffffffff00000001000000000000000000000000ffffffffffffffffffffffff90819080098a5109080860208601517fffffffff00000001000000000000000000000000ffffffffffffffffffffffff90800914610e4357506000610417565b6000610e4e86610e66565b9050610e5c81868686611062565b9695505050505050565b610e6e611704565b60405180606001604052806000815260200160008152602001600081525081600060108110610e9f57610e9f611b6a565b60200201526040805160608101909152808360006020020151815260200183600160028110610ed057610ed0611b6a565b60200201518152602001600181525081600160108110610ef257610ef2611b6a565b6020020152610f088160015b602002015161116f565b6040820152610f278160015b60200201518260025b60200201516111d1565b6060828101919091526040805191820181527f6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c29682527f4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f560208301526001908201526080820152610fa18160045b6020020151826001610f1d565b60a0820152610fb1816004610f14565b60c0820152610fca8160045b6020020151826003610f1d565b60e0820152610fda816004610efe565b610100820152610feb816008610f94565b610120820152610ffc816008610f14565b61014082015261100d816008610fbd565b610160820152608081015161102490826008610f1d565b61018082015261103581600c610f94565b6101a082015261104681600c610f14565b6101c082015261105781600c610fbd565b6101e0820152919050565b600083158061106f575082155b8061109a57507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518410155b806110c557507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518310155b156110d257506000610417565b60006110fe847fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551611243565b905060007fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551828509905060007fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551838809905060008061115e8a858561125a565b509098149998505050505050505050565b61119360405180606001604052806000815260200160008152602001600081525090565b60008060006111af856000015186602001518760400151611346565b6040805160608101825293845260208401929092529082015295945050505050565b6111f560405180606001604052806000815260200160008152602001600081525090565b6000806000611220866000015187602001518860400151886000015189602001518a60400151611424565b604080516060810182529384526020840192909252908201529695505050505050565b60006102f683611254600285611eb6565b8461155c565b6000808080806080815b81156113285782156112955761127b858585611346565b9196509450925061128d858585611346565b919650945092505b50600c60fc89901c1660fe88901c17801561130b576113038585858d85601081106112c2576112c2611b6a565b6020020151518e86601081106112da576112da611b6a565b6020020151602001518f87601081106112f5576112f5611b6a565b602002015160400151611424565b919650945092505b600298891b989790971b968161132081611ec9565b925050611264565b6113338585856115b0565b909750955050505050505b935093915050565b6000806000846000036113615750600091508190508061141b565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff8085860981828283097fffffffff00000001000000000000000000000000fffffffffffffffffffffffc099050818788098283828b0960040983848384096008099150838385868d8e09600309089250838160020984848509818110156113e65785015b039650868110156113f45783015b8387820384099550508085101561140a57938201935b909303925080808688096002099150505b93509350939050565b60008060008660000361143e575084915083905082611550565b83600003611453575087915086905085611550565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff808889098186870982818d0983838b0984858a85098e0985868e87098c09868b8f08848410156114a357928701925b8484039350878460020988818209905088818609848410156114c457928901925b898585036002099350898485099c50898288099650898a8860020982089150818d10156114f0579b89019b5b818d039c5089818b87600209099450508b86101561150d57948801945b888c870384099a50838b101561152257998801995b838b039a508887890897508882830990508781101561153e5788015b88858983030999505050505050505050505b96509650969350505050565b60008184111561156c5781840693505b60405160208152602080820152602060408201528460608201528360808201528260a082015260208160c08360056136b0fa8080156100a357505051949350505050565b600080826000036115c65750600090508061133e565b60006115f2847fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611243565b905060007fffffffff00000001000000000000000000000000ffffffffffffffffffffffff82830990507fffffffff00000001000000000000000000000000ffffffffffffffffffffffff81880993507fffffffff00000001000000000000000000000000ffffffffffffffffffffffff80838309870992505050935093915050565b82600281019282156116a8579160200282015b828111156116a8578251829060ff16905591602001919060010190611688565b506116b492915061174e565b5090565b60405180604001604052806002906020820280368337509192915050565b82600281019282156116a8579160200282015b828111156116a85782518255916020019190600101906116e9565b6040518061020001604052806010905b61173860405180606001604052806000815260200160008152602001600081525090565b8152602001906001900390816117145790505090565b5b808211156116b4576000815560010161174f565b6000610160828403121561177657600080fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156117ce576117ce61177c565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561181b5761181b61177c565b604052919050565b60008060006080848603121561183857600080fd5b833567ffffffffffffffff81111561184f57600080fd5b61185b86828701611763565b935050602080850135925085605f86011261187557600080fd5b61187d6117ab565b80608087018881111561188f57600080fd5b604088015b818110156118ab5780358452928401928401611894565b50508093505050509250925092565b600067ffffffffffffffff8211156118d4576118d461177c565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261191157600080fd5b813561192461191f826118ba565b6117d4565b81815284602083860101111561193957600080fd5b816020850160208301376000918101602001919091529392505050565b6000806040838503121561196957600080fd5b82359150602083013567ffffffffffffffff81111561198757600080fd5b61199385828601611900565b9150509250929050565b6000602082840312156119af57600080fd5b813567ffffffffffffffff8111156119c657600080fd5b61041784828501611900565b60005b838110156119ed5781810151838201526020016119d5565b50506000910152565b6020815260008251806020840152611a158160408501602087016119d2565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b60008060408385031215611a5a57600080fd5b823567ffffffffffffffff811115611a7157600080fd5b611a7d85828601611763565b95602094909401359450505050565b60008060208385031215611a9f57600080fd5b823567ffffffffffffffff80821115611ab757600080fd5b818501915085601f830112611acb57600080fd5b813581811115611ada57600080fd5b866020828501011115611aec57600080fd5b60209290920196919550909350505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112611b3357600080fd5b83018035915067ffffffffffffffff821115611b4e57600080fd5b602001915036819003821315611b6357600080fd5b9250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008183825b6002811015611bbe578154835260209092019160019182019101611b9f565b50505060408201905092915050565b60008085851115611bdd57600080fd5b83861115611bea57600080fd5b5050820193919092039150565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b6000611c5261191f846118ba565b9050828152838383011115611c6657600080fd5b6102f68360208301846119d2565b600082601f830112611c8557600080fd5b6102f683835160208501611c44565b600080600080600060a08688031215611cac57600080fd5b8551945060208601519350604086015167ffffffffffffffff80821115611cd257600080fd5b818801915088601f830112611ce657600080fd5b611cf589835160208501611c44565b94506060880151915080821115611d0b57600080fd5b611d1789838a01611c74565b93506080880151915080821115611d2d57600080fd5b50611d3a88828901611c74565b9150509295509295909350565b60008451611d598184602089016119d2565b845190830190611d6d8183602089016119d2565b8451910190611d808183602088016119d2565b0195945050505050565b60008251611d9c8184602087016119d2565b9190910192915050565b600060208284031215611db857600080fd5b5051919050565b60008351611dd18184602088016119d2565b9190910191825250602001919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808202811582820484141761036957610369611de1565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082611e6557611e65611e27565b500490565b600082611e7957611e79611e27565b500690565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611eaf57611eaf611de1565b5060010190565b8181038181111561036957610369611de1565b600081611ed857611ed8611de1565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392d5fa2646970667358221220d4142da7b16effb6b95f41adeff2bc8ce0d59d3b70ca8d55e6e83224bbfbec0a64736f6c63430008150033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100a35760003560e01c80637104ddb2116100765780638dd501211161005b5780638dd50121146101bc578063cd00e50a146101cf578063cd9b47e4146101d757600080fd5b80637104ddb21461015b5780638da5cb5b146101a757600080fd5b806311cfe388146100a85780631626ba7e146100ce5780633253960f14610112578063392dd6d914610138575b600080fd5b6100bb6100b6366004611823565b6101ea565b6040519081526020015b60405180910390f35b6100e16100dc366004611956565b610252565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020016100c5565b7f8dd50121000000000000000000000000000000000000000000000000000000006100e1565b61014b61014636600461199d565b6102fd565b60405190151581526020016100c5565b6101827f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100c5565b6101af61036f565b6040516100c591906119f6565b6100bb6101ca366004611a47565b6103ba565b6100bb61041f565b6100bb6101e5366004611a8c565b61053a565b600061023982846101ff610140880188611afe565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061083692505050565b610244576001610247565b60005b60ff16949350505050565b60006102aa7f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b1653646040805180820191829052919060029082845b81548152602001906001019080831161028b5750505050508484610836565b6102d4577fffffffff000000000000000000000000000000000000000000000000000000006102f6565b7f1626ba7e000000000000000000000000000000000000000000000000000000005b9392505050565b60008151604114801561036957508160008151811061031e5761031e611b6a565b6020910101517fff00000000000000000000000000000000000000000000000000000000000000167f0400000000000000000000000000000000000000000000000000000000000000145b92915050565b6040516060907f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364906103a5908290602001611b99565b60405160208183030381529060405291505090565b60408051808201918290526000917f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364916104179186918691859060029082845b8154815260200190600101908083116103fa5750505050506101ea565b949350505050565b60006104296109b4565b6104316109f4565b60408051808201909152600080825260208201527f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364906104749082906002611675565b506000610488600154610100900460e01b90565b7fffffffff0000000000000000000000000000000000000000000000000000000016036104e1576040517f127c609a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff169055604051600192507fcccd30db6bc000b8bb8d11162228d2d69e3c361983ca3ae8c1365ce64b0fae9e90600090a15090565b6000610544610a93565b61058383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102fd92505050565b6105b9576040517f6c334d2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006105c88360018187611bcd565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092935061060992506116b8915050565b602082015181526040820151602082015260006106437f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b16536490565b9050610651818360026116d6565b507f8dd50121000000000000000000000000000000000000000000000000000000006000610686600154610100900460e01b90565b7fffffffff0000000000000000000000000000000000000000000000000000000016146106df576040517f5f95a63c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16610770827fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604090205460601c90565b73ffffffffffffffffffffffffffffffffffffffff16146107bd576040517fbb4752b700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff1661010060e084901c02179055600194507f6d54821a69ec281ed7ba1bf2729c700768c47df1d80fad646b0a14cc1d5c39ed8787604051610824929190611bf7565b60405180910390a15050505092915050565b600080600080600080868060200190518101906108539190611c94565b9450945094509450945060008061088a8a60405160200161087691815260200190565b604051602081830303815290604052610b33565b905060008482856040516020016108a393929190611d47565b60405160208183030381529060405290506002816040516108c49190611d8a565b602060405180830381855afa1580156108e1573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906109049190611da6565b9250505060006002858360405160200161091f929190611dbf565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905261095791611d8a565b602060405180830381855afa158015610974573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906109979190611da6565b90506109a58b888884610c6f565b9b9a5050505050505050505050565b6001805460ff16146109f2576040517f38fc28cb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff16600114610a5c576040517fe00d7c7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff1615610af9576040517f7c2cde8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b60608151600003610b5257505060408051602081019091526000815290565b6000604051806060016040528060408152602001611eff6040913990506000600684516008610b819190611e10565b610b8b9190611e56565b9050600060068551610b9d9190611e6a565b1115610bb15780610bad81611e7e565b9150505b60008167ffffffffffffffff811115610bcc57610bcc61177c565b6040519080825280601f01601f191660200182016040528015610bf6576020820181803683370190505b509050600183016020820186875188015b80821015610c62576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f8116850151845350600183019250610c07565b5092979650505050505050565b6000610c9c60017fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611eb6565b85511180610cd75750610cd060017fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611eb6565b6020860151115b15610ce457506000610417565b831580610cef575082155b80610d1a57507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518410155b80610d4557507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518310155b15610d5257506000610417565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff7f5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff8088600060200201517fffffffff00000001000000000000000000000000fffffffffffffffffffffffc0988517fffffffff00000001000000000000000000000000ffffffffffffffffffffffff90819080098a5109080860208601517fffffffff00000001000000000000000000000000ffffffffffffffffffffffff90800914610e4357506000610417565b6000610e4e86610e66565b9050610e5c81868686611062565b9695505050505050565b610e6e611704565b60405180606001604052806000815260200160008152602001600081525081600060108110610e9f57610e9f611b6a565b60200201526040805160608101909152808360006020020151815260200183600160028110610ed057610ed0611b6a565b60200201518152602001600181525081600160108110610ef257610ef2611b6a565b6020020152610f088160015b602002015161116f565b6040820152610f278160015b60200201518260025b60200201516111d1565b6060828101919091526040805191820181527f6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c29682527f4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f560208301526001908201526080820152610fa18160045b6020020151826001610f1d565b60a0820152610fb1816004610f14565b60c0820152610fca8160045b6020020151826003610f1d565b60e0820152610fda816004610efe565b610100820152610feb816008610f94565b610120820152610ffc816008610f14565b61014082015261100d816008610fbd565b610160820152608081015161102490826008610f1d565b61018082015261103581600c610f94565b6101a082015261104681600c610f14565b6101c082015261105781600c610fbd565b6101e0820152919050565b600083158061106f575082155b8061109a57507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518410155b806110c557507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518310155b156110d257506000610417565b60006110fe847fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551611243565b905060007fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551828509905060007fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551838809905060008061115e8a858561125a565b509098149998505050505050505050565b61119360405180606001604052806000815260200160008152602001600081525090565b60008060006111af856000015186602001518760400151611346565b6040805160608101825293845260208401929092529082015295945050505050565b6111f560405180606001604052806000815260200160008152602001600081525090565b6000806000611220866000015187602001518860400151886000015189602001518a60400151611424565b604080516060810182529384526020840192909252908201529695505050505050565b60006102f683611254600285611eb6565b8461155c565b6000808080806080815b81156113285782156112955761127b858585611346565b9196509450925061128d858585611346565b919650945092505b50600c60fc89901c1660fe88901c17801561130b576113038585858d85601081106112c2576112c2611b6a565b6020020151518e86601081106112da576112da611b6a565b6020020151602001518f87601081106112f5576112f5611b6a565b602002015160400151611424565b919650945092505b600298891b989790971b968161132081611ec9565b925050611264565b6113338585856115b0565b909750955050505050505b935093915050565b6000806000846000036113615750600091508190508061141b565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff8085860981828283097fffffffff00000001000000000000000000000000fffffffffffffffffffffffc099050818788098283828b0960040983848384096008099150838385868d8e09600309089250838160020984848509818110156113e65785015b039650868110156113f45783015b8387820384099550508085101561140a57938201935b909303925080808688096002099150505b93509350939050565b60008060008660000361143e575084915083905082611550565b83600003611453575087915086905085611550565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff808889098186870982818d0983838b0984858a85098e0985868e87098c09868b8f08848410156114a357928701925b8484039350878460020988818209905088818609848410156114c457928901925b898585036002099350898485099c50898288099650898a8860020982089150818d10156114f0579b89019b5b818d039c5089818b87600209099450508b86101561150d57948801945b888c870384099a50838b101561152257998801995b838b039a508887890897508882830990508781101561153e5788015b88858983030999505050505050505050505b96509650969350505050565b60008184111561156c5781840693505b60405160208152602080820152602060408201528460608201528360808201528260a082015260208160c08360056136b0fa8080156100a357505051949350505050565b600080826000036115c65750600090508061133e565b60006115f2847fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611243565b905060007fffffffff00000001000000000000000000000000ffffffffffffffffffffffff82830990507fffffffff00000001000000000000000000000000ffffffffffffffffffffffff81880993507fffffffff00000001000000000000000000000000ffffffffffffffffffffffff80838309870992505050935093915050565b82600281019282156116a8579160200282015b828111156116a8578251829060ff16905591602001919060010190611688565b506116b492915061174e565b5090565b60405180604001604052806002906020820280368337509192915050565b82600281019282156116a8579160200282015b828111156116a85782518255916020019190600101906116e9565b6040518061020001604052806010905b61173860405180606001604052806000815260200160008152602001600081525090565b8152602001906001900390816117145790505090565b5b808211156116b4576000815560010161174f565b6000610160828403121561177657600080fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156117ce576117ce61177c565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561181b5761181b61177c565b604052919050565b60008060006080848603121561183857600080fd5b833567ffffffffffffffff81111561184f57600080fd5b61185b86828701611763565b935050602080850135925085605f86011261187557600080fd5b61187d6117ab565b80608087018881111561188f57600080fd5b604088015b818110156118ab5780358452928401928401611894565b50508093505050509250925092565b600067ffffffffffffffff8211156118d4576118d461177c565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261191157600080fd5b813561192461191f826118ba565b6117d4565b81815284602083860101111561193957600080fd5b816020850160208301376000918101602001919091529392505050565b6000806040838503121561196957600080fd5b82359150602083013567ffffffffffffffff81111561198757600080fd5b61199385828601611900565b9150509250929050565b6000602082840312156119af57600080fd5b813567ffffffffffffffff8111156119c657600080fd5b61041784828501611900565b60005b838110156119ed5781810151838201526020016119d5565b50506000910152565b6020815260008251806020840152611a158160408501602087016119d2565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b60008060408385031215611a5a57600080fd5b823567ffffffffffffffff811115611a7157600080fd5b611a7d85828601611763565b95602094909401359450505050565b60008060208385031215611a9f57600080fd5b823567ffffffffffffffff80821115611ab757600080fd5b818501915085601f830112611acb57600080fd5b813581811115611ada57600080fd5b866020828501011115611aec57600080fd5b60209290920196919550909350505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112611b3357600080fd5b83018035915067ffffffffffffffff821115611b4e57600080fd5b602001915036819003821315611b6357600080fd5b9250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008183825b6002811015611bbe578154835260209092019160019182019101611b9f565b50505060408201905092915050565b60008085851115611bdd57600080fd5b83861115611bea57600080fd5b5050820193919092039150565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b6000611c5261191f846118ba565b9050828152838383011115611c6657600080fd5b6102f68360208301846119d2565b600082601f830112611c8557600080fd5b6102f683835160208501611c44565b600080600080600060a08688031215611cac57600080fd5b8551945060208601519350604086015167ffffffffffffffff80821115611cd257600080fd5b818801915088601f830112611ce657600080fd5b611cf589835160208501611c44565b94506060880151915080821115611d0b57600080fd5b611d1789838a01611c74565b93506080880151915080821115611d2d57600080fd5b50611d3a88828901611c74565b9150509295509295909350565b60008451611d598184602089016119d2565b845190830190611d6d8183602089016119d2565b8451910190611d808183602088016119d2565b0195945050505050565b60008251611d9c8184602087016119d2565b9190910192915050565b600060208284031215611db857600080fd5b5051919050565b60008351611dd18184602088016119d2565b9190910191825250602001919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808202811582820484141761036957610369611de1565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082611e6557611e65611e27565b500490565b600082611e7957611e79611e27565b500690565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611eaf57611eaf611de1565b5060010190565b8181038181111561036957610369611de1565b600081611ed857611ed8611de1565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392d5fa2646970667358221220d4142da7b16effb6b95f41adeff2bc8ce0d59d3b70ca8d55e6e83224bbfbec0a64736f6c63430008150033", + "devdoc": { + "author": "Ruslan Serebriakov (@rsrbk)David Yongjun Kim (@Powerstream3604)", + "details": "Primarily used to verify user ops signed with passkeys", + "kind": "dev", + "methods": { + "initializeSigner(bytes)": { + "details": "This method checks if the signer has already been initialized. If already initialized, it reverts. It checks if the public key is in the light format and initializes signer storage in k1 storage.", + "params": { + "_publicKey": "Bytes of owner public key" + }, + "returns": { + "initSuccess": "Uint value representing the success of init operation" + } + }, + "isValidKeyType(bytes)": { + "details": "For this Secp256k1Verification Facet, the public key should in an uncompressed public key format", + "params": { + "_publicKey": "Bytes of public key for format check" + }, + "returns": { + "isValid": "Boolean variable representing if the format of public key is valid" + } + }, + "isValidSignature(bytes32,bytes)": { + "details": "This method verifies the signature if the owner indeed signed the hash. Returns magic value if true", + "params": { + "_hash": "Hash value the owner signed", + "_signature": "Signature that signed the above hash" + }, + "returns": { + "magicValue": "Bytes4 value representing the success/failure of validation" + } + }, + "owner()": { + "returns": { + "signer": "Bytes of owner address" + } + }, + "uninitializeSigner()": { + "details": "This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.", + "returns": { + "uninitSuccess": "Uint value representing the success of uninit operation" + } + }, + "validateOwnerSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32)": { + "details": "This method validates if the user operation is signed by the owner. It internally calls validateSignature with signer public key.", + "params": { + "userOp": "UserOperation including all information for execution", + "userOpHash": "Hash of UserOperation given from EntryPoint. This hash is used for signature validation" + }, + "returns": { + "validationData": "Uint value representing whether the validation is successful. 0 for success, 1 for failure" + } + }, + "validateOwnerSignatureSelector()": { + "returns": { + "ownerSignatureValidatorSelector": "Bytes4 selector of function signature to validate account owner's UserOperation signature" + } + }, + "validateSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256[2])": { + "details": "This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address", + "params": { + "q": "Public Key of signer who signed the contract, to be validated", + "userOp": "UserOperation including all information for execution", + "userOpHash": "Hash of UserOperation given from EntryPoint. This hash is used for signature validation" + }, + "returns": { + "isValid": "Uint value representing whether the validation is successful. 0 for success, 1 for failure" + } + } + }, + "title": "Secp256r1 verification facet", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "constructor": { + "notice": "This constructor ensures that this contract can only be used as singleton for Proxy contracts" + }, + "initializeSigner(bytes)": { + "notice": "Initializes the signer in R1 Facet Storage. This can only be called when the account is uninitialized or during signature migration." + }, + "isValidKeyType(bytes)": { + "notice": "Validates if the format of public key is valid for this verification facet" + }, + "isValidSignature(bytes32,bytes)": { + "notice": "Validates if the signature is valid. Function to be compatible with EIP-1271" + }, + "owner()": { + "notice": "Returns the owner of the account" + }, + "uninitializeSigner()": { + "notice": "Uninitialize signer in R1 Facet Storage. This can only be called when the account is undergoing signature migration and has already been initialized." + }, + "validateOwnerSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32)": { + "notice": "Validates if the user operation is signed by the owner." + }, + "validateOwnerSignatureSelector()": { + "notice": "Returns the selector of function to validate the signature of UserOperation" + }, + "validateSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256[2])": { + "notice": "Validates if the signature of UserOperation is signed by the given signer" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/arbitrum/TokenReceiverFacet.json b/deployments/arbitrum/TokenReceiverFacet.json new file mode 100644 index 0000000..e1a20bc --- /dev/null +++ b/deployments/arbitrum/TokenReceiverFacet.json @@ -0,0 +1,239 @@ +{ + "address": "0x3143E1C0Af0Cdc153423863923Cf4e3818e34Daa", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onERC1155BatchReceived", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onERC1155Received", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onERC721Received", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onTokenTransfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "tokensReceived", + "outputs": [], + "stateMutability": "pure", + "type": "function" + } + ], + "transactionHash": "0x2dc0041c9b9820a23a8cf7107d7e18aa05986d051d4c1247df7d5bbf6d014c89", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 1, + "gasUsed": "5244382", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0xe4b89967734470ea7396b10eac6352d4c994584c14d4ef3a27e9874f8fd96502", + "transactionHash": "0x2dc0041c9b9820a23a8cf7107d7e18aa05986d051d4c1247df7d5bbf6d014c89", + "logs": [], + "blockNumber": 144547138, + "cumulativeGasUsed": "5244382", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "0c861e53801b64e5ccc05669ea62a977", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onERC1155BatchReceived\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onERC1155Received\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onERC721Received\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"tokensReceived\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"Contract that enables receiving ERC721/ERC1155/ERC777/ERC677 Tokens with safe transfer\",\"kind\":\"dev\",\"methods\":{},\"title\":\"TokenReceiver Facet\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\":{\"notice\":\"Handles ERC1155 Token batch callback. return Standardized onERC1155BatchReceived return value.\"},\"onERC1155Received(address,address,uint256,uint256,bytes)\":{\"notice\":\"Handles ERC1155 Token callback. return Standardized onERC1155Received return value.\"},\"onERC721Received(address,address,uint256,bytes)\":{\"notice\":\"Handles ERC721 Token callback. return Standardized onERC721Received return value.\"},\"onTokenTransfer(address,uint256,bytes)\":{\"notice\":\"Handles ERC677 Token callback. return true.\"},\"tokensReceived(address,address,address,uint256,bytes,bytes)\":{\"notice\":\"Handles ERC777 Token callback. Does not return value, empty implementation.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/TokenReceiverFacet.sol\":\"TokenReceiverFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title ERC721 token receiver interface\\n * @dev Interface for any contract that wants to support safeTransfers\\n * from ERC721 asset contracts.\\n */\\ninterface IERC721Receiver {\\n /**\\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\\n * by `operator` from `from`, this function is called.\\n *\\n * It must return its Solidity selector to confirm the token transfer.\\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\\n *\\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\\n */\\n function onERC721Received(\\n address operator,\\n address from,\\n uint256 tokenId,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\\n *\\n * Accounts can be notified of {IERC777} tokens being sent to them by having a\\n * contract implement this interface (contract holders can be their own\\n * implementer) and registering it on the\\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\\n *\\n * See {IERC1820Registry} and {ERC1820Implementer}.\\n */\\ninterface IERC777Recipient {\\n /**\\n * @dev Called by an {IERC777} token contract whenever tokens are being\\n * moved or created into a registered account (`to`). The type of operation\\n * is conveyed by `from` being the zero address or not.\\n *\\n * This call occurs _after_ the token contract's state is updated, so\\n * {IERC777-balanceOf}, etc., can be used to query the post-operation state.\\n *\\n * This function may revert to prevent the operation from being executed.\\n */\\n function tokensReceived(\\n address operator,\\n address from,\\n address to,\\n uint256 amount,\\n bytes calldata userData,\\n bytes calldata operatorData\\n ) external;\\n}\\n\",\"keccak256\":\"0x1a5d61db2733202ba361e6d6741cd2e662380e22b80e987eacfc91973f2267dc\",\"license\":\"MIT\"},\"contracts/facets/TokenReceiverFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IERC721Receiver} from \\\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\\\";\\nimport {IERC777Recipient} from \\\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\\\";\\nimport {IERC1155Receiver} from \\\"../interfaces/ERC/IERC1155Receiver.sol\\\";\\nimport {IERC677Receiver} from \\\"../interfaces/ERC/IERC677Receiver.sol\\\";\\n\\n/**\\n * @title TokenReceiver Facet\\n * @dev Contract that enables receiving ERC721/ERC1155/ERC777/ERC677 Tokens with safe transfer\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract TokenReceiverFacet is\\n IERC721Receiver,\\n IERC1155Receiver,\\n IERC777Recipient,\\n IERC677Receiver\\n{\\n /**\\n * @notice Handles ERC721 Token callback.\\n * return Standardized onERC721Received return value.\\n */\\n function onERC721Received(\\n address,\\n address,\\n uint256,\\n bytes calldata\\n ) external pure override returns (bytes4) {\\n return IERC721Receiver.onERC721Received.selector;\\n }\\n\\n /**\\n * @notice Handles ERC1155 Token callback.\\n * return Standardized onERC1155Received return value.\\n */\\n function onERC1155Received(\\n address,\\n address,\\n uint256,\\n uint256,\\n bytes calldata\\n ) external pure override returns (bytes4) {\\n return IERC1155Receiver.onERC1155Received.selector;\\n }\\n\\n /**\\n * @notice Handles ERC1155 Token batch callback.\\n * return Standardized onERC1155BatchReceived return value.\\n */\\n function onERC1155BatchReceived(\\n address,\\n address,\\n uint256[] calldata,\\n uint256[] calldata,\\n bytes calldata\\n ) external pure override returns (bytes4) {\\n return IERC1155Receiver.onERC1155BatchReceived.selector;\\n }\\n\\n /**\\n * @notice Handles ERC777 Token callback.\\n * Does not return value, empty implementation.\\n */\\n function tokensReceived(\\n address,\\n address,\\n address,\\n uint256,\\n bytes calldata,\\n bytes calldata\\n ) external pure override {}\\n\\n /**\\n * @notice Handles ERC677 Token callback.\\n * return true.\\n */\\n function onTokenTransfer(\\n address,\\n uint256,\\n bytes calldata\\n ) external pure override returns (bool) {\\n return true;\\n }\\n}\\n\",\"keccak256\":\"0xdfe483d05ef4056bb464c34ade19ab527687aff3ed0b6303b447a68b5ff7abb4\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC1155Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\n\\npragma solidity 0.8.21;\\n\\n/**\\n * @dev _Available since v3.1._\\n */\\ninterface IERC1155Receiver {\\n /**\\n * @dev Handles the receipt of a single ERC1155 token type. This function is\\n * called at the end of a `safeTransferFrom` after the balance has been updated.\\n *\\n * NOTE: To accept the transfer, this must return\\n * `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))`\\n * (i.e. 0xf23a6e61, or its own function selector).\\n *\\n * @param operator The address which initiated the transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param id The ID of the token being transferred\\n * @param value The amount of tokens being transferred\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155Received(\\n address operator,\\n address from,\\n uint256 id,\\n uint256 value,\\n bytes calldata data\\n ) external returns (bytes4);\\n\\n /**\\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\\n * is called at the end of a `safeBatchTransferFrom` after the balances have\\n * been updated.\\n *\\n * NOTE: To accept the transfer(s), this must return\\n * `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))`\\n * (i.e. 0xbc197c81, or its own function selector).\\n *\\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155BatchReceived(\\n address operator,\\n address from,\\n uint256[] calldata ids,\\n uint256[] calldata values,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0x3729c6757bae3aba03ac1c5064d67ad13b94e2a9428bf44b9be510373406da0c\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC677Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC677Receiver {\\n function onTokenTransfer(\\n address sender,\\n uint value,\\n bytes calldata data\\n ) external pure returns (bool);\\n}\\n\",\"keccak256\":\"0x4c1631cf45ea6daac0ec158c3edb9453099130b6b64f697004b83f95aa1f7350\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50610502806100206000396000f3fe608060405234801561001057600080fd5b50600436106100665760003560e01c8063a4c0ed3611610050578063a4c0ed36146100f3578063bc197c811461011b578063f23a6e611461015657600080fd5b806223de291461006b578063150b7a0214610085575b600080fd5b610083610079366004610201565b5050505050505050565b005b6100bd6100933660046102ac565b7f150b7a020000000000000000000000000000000000000000000000000000000095945050505050565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020015b60405180910390f35b61010b61010136600461031b565b6001949350505050565b60405190151581526020016100ea565b6100bd6101293660046103ba565b7fbc197c810000000000000000000000000000000000000000000000000000000098975050505050505050565b6100bd610164366004610454565b7ff23a6e61000000000000000000000000000000000000000000000000000000009695505050505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146101b357600080fd5b919050565b60008083601f8401126101ca57600080fd5b50813567ffffffffffffffff8111156101e257600080fd5b6020830191508360208285010111156101fa57600080fd5b9250929050565b60008060008060008060008060c0898b03121561021d57600080fd5b6102268961018f565b975061023460208a0161018f565b965061024260408a0161018f565b955060608901359450608089013567ffffffffffffffff8082111561026657600080fd5b6102728c838d016101b8565b909650945060a08b013591508082111561028b57600080fd5b506102988b828c016101b8565b999c989b5096995094979396929594505050565b6000806000806000608086880312156102c457600080fd5b6102cd8661018f565b94506102db6020870161018f565b935060408601359250606086013567ffffffffffffffff8111156102fe57600080fd5b61030a888289016101b8565b969995985093965092949392505050565b6000806000806060858703121561033157600080fd5b61033a8561018f565b935060208501359250604085013567ffffffffffffffff81111561035d57600080fd5b610369878288016101b8565b95989497509550505050565b60008083601f84011261038757600080fd5b50813567ffffffffffffffff81111561039f57600080fd5b6020830191508360208260051b85010111156101fa57600080fd5b60008060008060008060008060a0898b0312156103d657600080fd5b6103df8961018f565b97506103ed60208a0161018f565b9650604089013567ffffffffffffffff8082111561040a57600080fd5b6104168c838d01610375565b909850965060608b013591508082111561042f57600080fd5b61043b8c838d01610375565b909650945060808b013591508082111561028b57600080fd5b60008060008060008060a0878903121561046d57600080fd5b6104768761018f565b95506104846020880161018f565b94506040870135935060608701359250608087013567ffffffffffffffff8111156104ae57600080fd5b6104ba89828a016101b8565b979a969950949750929593949250505056fea2646970667358221220ae9a97061ae9e1485161ca9c8d3228a23e47b18755fa935f51b40e927816ca2964736f6c63430008150033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100665760003560e01c8063a4c0ed3611610050578063a4c0ed36146100f3578063bc197c811461011b578063f23a6e611461015657600080fd5b806223de291461006b578063150b7a0214610085575b600080fd5b610083610079366004610201565b5050505050505050565b005b6100bd6100933660046102ac565b7f150b7a020000000000000000000000000000000000000000000000000000000095945050505050565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020015b60405180910390f35b61010b61010136600461031b565b6001949350505050565b60405190151581526020016100ea565b6100bd6101293660046103ba565b7fbc197c810000000000000000000000000000000000000000000000000000000098975050505050505050565b6100bd610164366004610454565b7ff23a6e61000000000000000000000000000000000000000000000000000000009695505050505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146101b357600080fd5b919050565b60008083601f8401126101ca57600080fd5b50813567ffffffffffffffff8111156101e257600080fd5b6020830191508360208285010111156101fa57600080fd5b9250929050565b60008060008060008060008060c0898b03121561021d57600080fd5b6102268961018f565b975061023460208a0161018f565b965061024260408a0161018f565b955060608901359450608089013567ffffffffffffffff8082111561026657600080fd5b6102728c838d016101b8565b909650945060a08b013591508082111561028b57600080fd5b506102988b828c016101b8565b999c989b5096995094979396929594505050565b6000806000806000608086880312156102c457600080fd5b6102cd8661018f565b94506102db6020870161018f565b935060408601359250606086013567ffffffffffffffff8111156102fe57600080fd5b61030a888289016101b8565b969995985093965092949392505050565b6000806000806060858703121561033157600080fd5b61033a8561018f565b935060208501359250604085013567ffffffffffffffff81111561035d57600080fd5b610369878288016101b8565b95989497509550505050565b60008083601f84011261038757600080fd5b50813567ffffffffffffffff81111561039f57600080fd5b6020830191508360208260051b85010111156101fa57600080fd5b60008060008060008060008060a0898b0312156103d657600080fd5b6103df8961018f565b97506103ed60208a0161018f565b9650604089013567ffffffffffffffff8082111561040a57600080fd5b6104168c838d01610375565b909850965060608b013591508082111561042f57600080fd5b61043b8c838d01610375565b909650945060808b013591508082111561028b57600080fd5b60008060008060008060a0878903121561046d57600080fd5b6104768761018f565b95506104846020880161018f565b94506040870135935060608701359250608087013567ffffffffffffffff8111156104ae57600080fd5b6104ba89828a016101b8565b979a969950949750929593949250505056fea2646970667358221220ae9a97061ae9e1485161ca9c8d3228a23e47b18755fa935f51b40e927816ca2964736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "Contract that enables receiving ERC721/ERC1155/ERC777/ERC677 Tokens with safe transfer", + "kind": "dev", + "methods": {}, + "title": "TokenReceiver Facet", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)": { + "notice": "Handles ERC1155 Token batch callback. return Standardized onERC1155BatchReceived return value." + }, + "onERC1155Received(address,address,uint256,uint256,bytes)": { + "notice": "Handles ERC1155 Token callback. return Standardized onERC1155Received return value." + }, + "onERC721Received(address,address,uint256,bytes)": { + "notice": "Handles ERC721 Token callback. return Standardized onERC721Received return value." + }, + "onTokenTransfer(address,uint256,bytes)": { + "notice": "Handles ERC677 Token callback. return true." + }, + "tokensReceived(address,address,address,uint256,bytes,bytes)": { + "notice": "Handles ERC777 Token callback. Does not return value, empty implementation." + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/arbitrum/solcInputs/0c861e53801b64e5ccc05669ea62a977.json b/deployments/arbitrum/solcInputs/0c861e53801b64e5ccc05669ea62a977.json new file mode 100644 index 0000000..47e9456 --- /dev/null +++ b/deployments/arbitrum/solcInputs/0c861e53801b64e5ccc05669ea62a977.json @@ -0,0 +1,354 @@ +{ + "language": "Solidity", + "sources": { + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby disabling any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable2Step.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./Ownable.sol\";\n\n/**\n * @dev Contract module which provides access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership} and {acceptOwnership}.\n *\n * This module is used through inheritance. It will make available all functions\n * from parent (Ownable).\n */\nabstract contract Ownable2Step is Ownable {\n address private _pendingOwner;\n\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Returns the address of the pending owner.\n */\n function pendingOwner() public view virtual returns (address) {\n return _pendingOwner;\n }\n\n /**\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual override onlyOwner {\n _pendingOwner = newOwner;\n emit OwnershipTransferStarted(owner(), newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual override {\n delete _pendingOwner;\n super._transferOwnership(newOwner);\n }\n\n /**\n * @dev The new owner accepts the ownership transfer.\n */\n function acceptOwnership() public virtual {\n address sender = _msgSender();\n require(pendingOwner() == sender, \"Ownable2Step: caller is not the new owner\");\n _transferOwnership(sender);\n }\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC1271.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC1271 standard signature validation method for\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\n *\n * _Available since v4.1._\n */\ninterface IERC1271 {\n /**\n * @dev Should return whether the signature provided is valid for the provided data\n * @param hash Hash of the data to be signed\n * @param signature Signature byte array associated with _data\n */\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\n}\n" + }, + "@openzeppelin/contracts/security/ReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor() {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n _nonReentrantBefore();\n _;\n _nonReentrantAfter();\n }\n\n function _nonReentrantBefore() private {\n // On the first call to nonReentrant, _status will be _NOT_ENTERED\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n }\n\n function _nonReentrantAfter() private {\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Returns true if the reentrancy guard is currently set to \"entered\", which indicates there is a\n * `nonReentrant` function in the call stack.\n */\n function _reentrancyGuardEntered() internal view returns (bool) {\n return _status == _ENTERED;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/ERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/ERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC1155.sol\";\nimport \"./IERC1155Receiver.sol\";\nimport \"./extensions/IERC1155MetadataURI.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of the basic standard multi-token.\n * See https://eips.ethereum.org/EIPS/eip-1155\n * Originally based on code by Enjin: https://github.com/enjin/erc-1155\n *\n * _Available since v3.1._\n */\ncontract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {\n using Address for address;\n\n // Mapping from token ID to account balances\n mapping(uint256 => mapping(address => uint256)) private _balances;\n\n // Mapping from account to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json\n string private _uri;\n\n /**\n * @dev See {_setURI}.\n */\n constructor(string memory uri_) {\n _setURI(uri_);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return\n interfaceId == type(IERC1155).interfaceId ||\n interfaceId == type(IERC1155MetadataURI).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC1155MetadataURI-uri}.\n *\n * This implementation returns the same URI for *all* token types. It relies\n * on the token type ID substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * Clients calling this function must replace the `\\{id\\}` substring with the\n * actual token type ID.\n */\n function uri(uint256) public view virtual override returns (string memory) {\n return _uri;\n }\n\n /**\n * @dev See {IERC1155-balanceOf}.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {\n require(account != address(0), \"ERC1155: address zero is not a valid owner\");\n return _balances[id][account];\n }\n\n /**\n * @dev See {IERC1155-balanceOfBatch}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] memory accounts,\n uint256[] memory ids\n ) public view virtual override returns (uint256[] memory) {\n require(accounts.length == ids.length, \"ERC1155: accounts and ids length mismatch\");\n\n uint256[] memory batchBalances = new uint256[](accounts.length);\n\n for (uint256 i = 0; i < accounts.length; ++i) {\n batchBalances[i] = balanceOf(accounts[i], ids[i]);\n }\n\n return batchBalances;\n }\n\n /**\n * @dev See {IERC1155-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC1155-isApprovedForAll}.\n */\n function isApprovedForAll(address account, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[account][operator];\n }\n\n /**\n * @dev See {IERC1155-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n _safeTransferFrom(from, to, id, amount, data);\n }\n\n /**\n * @dev See {IERC1155-safeBatchTransferFrom}.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n _safeBatchTransferFrom(from, to, ids, amounts, data);\n }\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n\n emit TransferSingle(operator, from, to, id, amount);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n for (uint256 i = 0; i < ids.length; ++i) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n }\n\n emit TransferBatch(operator, from, to, ids, amounts);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\n\n _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);\n }\n\n /**\n * @dev Sets a new URI for all token types, by relying on the token type ID\n * substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * By this mechanism, any occurrence of the `\\{id\\}` substring in either the\n * URI or any of the amounts in the JSON file at said URI will be replaced by\n * clients with the token type ID.\n *\n * For example, the `https://token-cdn-domain/\\{id\\}.json` URI would be\n * interpreted by clients as\n * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`\n * for token type ID 0x4cce0.\n *\n * See {uri}.\n *\n * Because these URIs cannot be meaningfully represented by the {URI} event,\n * this function emits no events.\n */\n function _setURI(string memory newuri) internal virtual {\n _uri = newuri;\n }\n\n /**\n * @dev Creates `amount` tokens of token type `id`, and assigns them to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _mint(address to, uint256 id, uint256 amount, bytes memory data) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _balances[id][to] += amount;\n emit TransferSingle(operator, address(0), to, id, amount);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n for (uint256 i = 0; i < ids.length; i++) {\n _balances[ids[i]][to] += amounts[i];\n }\n\n emit TransferBatch(operator, address(0), to, ids, amounts);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);\n }\n\n /**\n * @dev Destroys `amount` tokens of token type `id` from `from`\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `from` must have at least `amount` tokens of token type `id`.\n */\n function _burn(address from, uint256 id, uint256 amount) internal virtual {\n require(from != address(0), \"ERC1155: burn from the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n\n emit TransferSingle(operator, from, address(0), id, amount);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n */\n function _burnBatch(address from, uint256[] memory ids, uint256[] memory amounts) internal virtual {\n require(from != address(0), \"ERC1155: burn from the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n\n for (uint256 i = 0; i < ids.length; i++) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n }\n\n emit TransferBatch(operator, from, address(0), ids, amounts);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {\n require(owner != operator, \"ERC1155: setting approval status for self\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning, as well as batched variants.\n *\n * The same hook is called on both single and batched variants. For single\n * transfers, the length of the `ids` and `amounts` arrays will be 1.\n *\n * Calling conditions (for each `id` and `amount` pair):\n *\n * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * of token type `id` will be transferred to `to`.\n * - When `from` is zero, `amount` tokens of token type `id` will be minted\n * for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n * will be burned.\n * - `from` and `to` are never both zero.\n * - `ids` and `amounts` have the same, non-zero length.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any token transfer. This includes minting\n * and burning, as well as batched variants.\n *\n * The same hook is called on both single and batched variants. For single\n * transfers, the length of the `id` and `amount` arrays will be 1.\n *\n * Calling conditions (for each `id` and `amount` pair):\n *\n * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * of token type `id` will be transferred to `to`.\n * - When `from` is zero, `amount` tokens of token type `id` will be minted\n * for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n * will be burned.\n * - `from` and `to` are never both zero.\n * - `ids` and `amounts` have the same, non-zero length.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {}\n\n function _doSafeTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155Receiver.onERC1155Received.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non-ERC1155Receiver implementer\");\n }\n }\n }\n\n function _doSafeBatchTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (\n bytes4 response\n ) {\n if (response != IERC1155Receiver.onERC1155BatchReceived.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non-ERC1155Receiver implementer\");\n }\n }\n }\n\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {\n uint256[] memory array = new uint256[](1);\n array[0] = element;\n\n return array;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC1155.sol\";\n\n/**\n * @dev Interface of the optional ERC1155MetadataExtension interface, as defined\n * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155MetadataURI is IERC1155 {\n /**\n * @dev Returns the URI for token type `id`.\n *\n * If the `\\{id\\}` substring is present in the URI, it must be replaced by\n * clients with the actual token type ID.\n */\n function uri(uint256 id) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155 is IERC165 {\n /**\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n */\n event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);\n\n /**\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n * transfers.\n */\n event TransferBatch(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\n\n /**\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n * `approved`.\n */\n event ApprovalForAll(address indexed account, address indexed operator, bool approved);\n\n /**\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n *\n * If an {URI} event was emitted for `id`, the standard\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n * returned by {IERC1155MetadataURI-uri}.\n */\n event URI(string value, uint256 indexed id);\n\n /**\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) external view returns (uint256);\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] calldata accounts,\n uint256[] calldata ids\n ) external view returns (uint256[] memory);\n\n /**\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n *\n * Emits an {ApprovalForAll} event.\n *\n * Requirements:\n *\n * - `operator` cannot be the caller.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n *\n * See {setApprovalForAll}.\n */\n function isApprovedForAll(address account, address operator) external view returns (bool);\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155Receiver is IERC165 {\n /**\n * @dev Handles the receipt of a single ERC1155 token type. This function is\n * called at the end of a `safeTransferFrom` after the balance has been updated.\n *\n * NOTE: To accept the transfer, this must return\n * `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n * (i.e. 0xf23a6e61, or its own function selector).\n *\n * @param operator The address which initiated the transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param id The ID of the token being transferred\n * @param value The amount of tokens being transferred\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n ) external returns (bytes4);\n\n /**\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\n * is called at the end of a `safeBatchTransferFrom` after the balances have\n * been updated.\n *\n * NOTE: To accept the transfer(s), this must return\n * `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n * (i.e. 0xbc197c81, or its own function selector).\n *\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the default value returned by this function, unless\n * it's overridden.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(address from, address to, uint256 amount) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\n // decrementing then incrementing.\n _balances[to] += amount;\n }\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n unchecked {\n // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\n _balances[account] += amount;\n }\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n // Overflow not possible: amount <= accountBalance <= totalSupply.\n _totalSupply -= amount;\n }\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\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" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` 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 amount) 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 `amount` as the allowance of `spender` over the 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 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` 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 amount) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/ERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721.sol\";\nimport \"./IERC721Receiver.sol\";\nimport \"./extensions/IERC721Metadata.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/Strings.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\n using Address for address;\n using Strings for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\n\n // Mapping from token ID to approved address\n mapping(uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return\n interfaceId == type(IERC721).interfaceId ||\n interfaceId == type(IERC721Metadata).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _ownerOf(tokenId);\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token owner or approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n _requireMinted(tokenId);\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n _safeTransfer(from, to, tokenId, data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(address from, address to, uint256 tokenId, bytes memory data) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist\n */\n function _ownerOf(uint256 tokenId) internal view virtual returns (address) {\n return _owners[tokenId];\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _ownerOf(tokenId) != address(0);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n address owner = ERC721.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(address to, uint256 tokenId, bytes memory data) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId, 1);\n\n // Check that tokenId was not minted by `_beforeTokenTransfer` hook\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n unchecked {\n // Will not overflow unless all 2**256 token ids are minted to the same owner.\n // Given that tokens are minted one by one, it is impossible in practice that\n // this ever happens. Might change if we allow batch minting.\n // The ERC fails to describe this case.\n _balances[to] += 1;\n }\n\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(address(0), to, tokenId, 1);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n * This is an internal function that does not check if the sender is authorized to operate on the token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId, 1);\n\n // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook\n owner = ERC721.ownerOf(tokenId);\n\n // Clear approvals\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // Cannot overflow, as that would require more tokens to be burned/transferred\n // out than the owner initially received through minting and transferring in.\n _balances[owner] -= 1;\n }\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(owner, address(0), tokenId, 1);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(address from, address to, uint256 tokenId) internal virtual {\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId, 1);\n\n // Check that tokenId was not transferred by `_beforeTokenTransfer` hook\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n\n // Clear approvals from the previous owner\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // `_balances[from]` cannot overflow for the same reason as described in `_burn`:\n // `from`'s balance is the number of token held, which is at least one before the current\n // transfer.\n // `_balances[to]` could overflow in the conditions described in `_mint`. That would require\n // all 2**256 token ids to be minted, which in practice is impossible.\n _balances[from] -= 1;\n _balances[to] += 1;\n }\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId, 1);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721Receiver.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`.\n * - When `from` is zero, the tokens will be minted for `to`.\n * - When `to` is zero, ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}\n\n /**\n * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`.\n * - When `from` is zero, the tokens were minted for `to`.\n * - When `to` is zero, ``from``'s tokens were burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}\n\n /**\n * @dev Unsafe write access to the balances, used by extensions that \"mint\" tokens using an {ownerOf} override.\n *\n * WARNING: Anyone calling this MUST ensure that the balances remain consistent with the ownership. The invariant\n * being that for any address `a` the value returned by `balanceOf(a)` must be equal to the number of tokens such\n * that `ownerOf(tokenId)` is `a`.\n */\n // solhint-disable-next-line func-name-mixedcase\n function __unsafe_increaseBalance(address account, uint256 amount) internal {\n _balances[account] += amount;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721Receiver {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/ERC777.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC777/ERC777.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC777.sol\";\nimport \"./IERC777Recipient.sol\";\nimport \"./IERC777Sender.sol\";\nimport \"../ERC20/IERC20.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/introspection/IERC1820Registry.sol\";\n\n/**\n * @dev Implementation of the {IERC777} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n *\n * Support for ERC20 is included in this contract, as specified by the EIP: both\n * the ERC777 and ERC20 interfaces can be safely used when interacting with it.\n * Both {IERC777-Sent} and {IERC20-Transfer} events are emitted on token\n * movements.\n *\n * Additionally, the {IERC777-granularity} value is hard-coded to `1`, meaning that there\n * are no special restrictions in the amount of tokens that created, moved, or\n * destroyed. This makes integration with ERC20 applications seamless.\n *\n * CAUTION: This file is deprecated as of v4.9 and will be removed in the next major release.\n */\ncontract ERC777 is Context, IERC777, IERC20 {\n using Address for address;\n\n IERC1820Registry internal constant _ERC1820_REGISTRY = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n mapping(address => uint256) private _balances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n bytes32 private constant _TOKENS_SENDER_INTERFACE_HASH = keccak256(\"ERC777TokensSender\");\n bytes32 private constant _TOKENS_RECIPIENT_INTERFACE_HASH = keccak256(\"ERC777TokensRecipient\");\n\n // This isn't ever read from - it's only used to respond to the defaultOperators query.\n address[] private _defaultOperatorsArray;\n\n // Immutable, but accounts may revoke them (tracked in __revokedDefaultOperators).\n mapping(address => bool) private _defaultOperators;\n\n // For each account, a mapping of its operators and revoked default operators.\n mapping(address => mapping(address => bool)) private _operators;\n mapping(address => mapping(address => bool)) private _revokedDefaultOperators;\n\n // ERC20-allowances\n mapping(address => mapping(address => uint256)) private _allowances;\n\n /**\n * @dev `defaultOperators` may be an empty array.\n */\n constructor(string memory name_, string memory symbol_, address[] memory defaultOperators_) {\n _name = name_;\n _symbol = symbol_;\n\n _defaultOperatorsArray = defaultOperators_;\n for (uint256 i = 0; i < defaultOperators_.length; i++) {\n _defaultOperators[defaultOperators_[i]] = true;\n }\n\n // register interfaces\n _ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256(\"ERC777Token\"), address(this));\n _ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256(\"ERC20Token\"), address(this));\n }\n\n /**\n * @dev See {IERC777-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC777-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {ERC20-decimals}.\n *\n * Always returns 18, as per the\n * [ERC777 EIP](https://eips.ethereum.org/EIPS/eip-777#backward-compatibility).\n */\n function decimals() public pure virtual returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC777-granularity}.\n *\n * This implementation always returns `1`.\n */\n function granularity() public view virtual override returns (uint256) {\n return 1;\n }\n\n /**\n * @dev See {IERC777-totalSupply}.\n */\n function totalSupply() public view virtual override(IERC20, IERC777) returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev Returns the amount of tokens owned by an account (`tokenHolder`).\n */\n function balanceOf(address tokenHolder) public view virtual override(IERC20, IERC777) returns (uint256) {\n return _balances[tokenHolder];\n }\n\n /**\n * @dev See {IERC777-send}.\n *\n * Also emits a {IERC20-Transfer} event for ERC20 compatibility.\n */\n function send(address recipient, uint256 amount, bytes memory data) public virtual override {\n _send(_msgSender(), recipient, amount, data, \"\", true);\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Unlike `send`, `recipient` is _not_ required to implement the {IERC777Recipient}\n * interface if it is a contract.\n *\n * Also emits a {Sent} event.\n */\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n _send(_msgSender(), recipient, amount, \"\", \"\", false);\n return true;\n }\n\n /**\n * @dev See {IERC777-burn}.\n *\n * Also emits a {IERC20-Transfer} event for ERC20 compatibility.\n */\n function burn(uint256 amount, bytes memory data) public virtual override {\n _burn(_msgSender(), amount, data, \"\");\n }\n\n /**\n * @dev See {IERC777-isOperatorFor}.\n */\n function isOperatorFor(address operator, address tokenHolder) public view virtual override returns (bool) {\n return\n operator == tokenHolder ||\n (_defaultOperators[operator] && !_revokedDefaultOperators[tokenHolder][operator]) ||\n _operators[tokenHolder][operator];\n }\n\n /**\n * @dev See {IERC777-authorizeOperator}.\n */\n function authorizeOperator(address operator) public virtual override {\n require(_msgSender() != operator, \"ERC777: authorizing self as operator\");\n\n if (_defaultOperators[operator]) {\n delete _revokedDefaultOperators[_msgSender()][operator];\n } else {\n _operators[_msgSender()][operator] = true;\n }\n\n emit AuthorizedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-revokeOperator}.\n */\n function revokeOperator(address operator) public virtual override {\n require(operator != _msgSender(), \"ERC777: revoking self as operator\");\n\n if (_defaultOperators[operator]) {\n _revokedDefaultOperators[_msgSender()][operator] = true;\n } else {\n delete _operators[_msgSender()][operator];\n }\n\n emit RevokedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-defaultOperators}.\n */\n function defaultOperators() public view virtual override returns (address[] memory) {\n return _defaultOperatorsArray;\n }\n\n /**\n * @dev See {IERC777-operatorSend}.\n *\n * Emits {Sent} and {IERC20-Transfer} events.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes memory data,\n bytes memory operatorData\n ) public virtual override {\n require(isOperatorFor(_msgSender(), sender), \"ERC777: caller is not an operator for holder\");\n _send(sender, recipient, amount, data, operatorData, true);\n }\n\n /**\n * @dev See {IERC777-operatorBurn}.\n *\n * Emits {Burned} and {IERC20-Transfer} events.\n */\n function operatorBurn(\n address account,\n uint256 amount,\n bytes memory data,\n bytes memory operatorData\n ) public virtual override {\n require(isOperatorFor(_msgSender(), account), \"ERC777: caller is not an operator for holder\");\n _burn(account, amount, data, operatorData);\n }\n\n /**\n * @dev See {IERC20-allowance}.\n *\n * Note that operator and allowance concepts are orthogonal: operators may\n * not have allowance, and accounts with allowance may not be operators\n * themselves.\n */\n function allowance(address holder, address spender) public view virtual override returns (uint256) {\n return _allowances[holder][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Note that accounts cannot have allowance issued by their operators.\n */\n function approve(address spender, uint256 value) public virtual override returns (bool) {\n address holder = _msgSender();\n _approve(holder, spender, value);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Note that operator and allowance concepts are orthogonal: operators cannot\n * call `transferFrom` (unless they have allowance), and accounts with\n * allowance cannot call `operatorSend` (unless they are operators).\n *\n * Emits {Sent}, {IERC20-Transfer} and {IERC20-Approval} events.\n */\n function transferFrom(address holder, address recipient, uint256 amount) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(holder, spender, amount);\n _send(holder, recipient, amount, \"\", \"\", false);\n return true;\n }\n\n /**\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with the caller address as the `operator` and with\n * `userData` and `operatorData`.\n *\n * See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits {Minted} and {IERC20-Transfer} events.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - if `account` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function _mint(address account, uint256 amount, bytes memory userData, bytes memory operatorData) internal virtual {\n _mint(account, amount, userData, operatorData, true);\n }\n\n /**\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * If `requireReceptionAck` is set to true, and if a send hook is\n * registered for `account`, the corresponding function will be called with\n * `operator`, `data` and `operatorData`.\n *\n * See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits {Minted} and {IERC20-Transfer} events.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - if `account` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function _mint(\n address account,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) internal virtual {\n require(account != address(0), \"ERC777: mint to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), account, amount);\n\n // Update state variables\n _totalSupply += amount;\n _balances[account] += amount;\n\n _callTokensReceived(operator, address(0), account, amount, userData, operatorData, requireReceptionAck);\n\n emit Minted(operator, account, amount, userData, operatorData);\n emit Transfer(address(0), account, amount);\n }\n\n /**\n * @dev Send tokens\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _send(\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) internal virtual {\n require(from != address(0), \"ERC777: transfer from the zero address\");\n require(to != address(0), \"ERC777: transfer to the zero address\");\n\n address operator = _msgSender();\n\n _callTokensToSend(operator, from, to, amount, userData, operatorData);\n\n _move(operator, from, to, amount, userData, operatorData);\n\n _callTokensReceived(operator, from, to, amount, userData, operatorData, requireReceptionAck);\n }\n\n /**\n * @dev Burn tokens\n * @param from address token holder address\n * @param amount uint256 amount of tokens to burn\n * @param data bytes extra information provided by the token holder\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _burn(address from, uint256 amount, bytes memory data, bytes memory operatorData) internal virtual {\n require(from != address(0), \"ERC777: burn from the zero address\");\n\n address operator = _msgSender();\n\n _callTokensToSend(operator, from, address(0), amount, data, operatorData);\n\n _beforeTokenTransfer(operator, from, address(0), amount);\n\n // Update state variables\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC777: burn amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Burned(operator, from, amount, data, operatorData);\n emit Transfer(from, address(0), amount);\n }\n\n function _move(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n ) private {\n _beforeTokenTransfer(operator, from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC777: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Sent(operator, from, to, amount, userData, operatorData);\n emit Transfer(from, to, amount);\n }\n\n /**\n * @dev See {ERC20-_approve}.\n *\n * Note that accounts cannot have allowance issued by their operators.\n */\n function _approve(address holder, address spender, uint256 value) internal virtual {\n require(holder != address(0), \"ERC777: approve from the zero address\");\n require(spender != address(0), \"ERC777: approve to the zero address\");\n\n _allowances[holder][spender] = value;\n emit Approval(holder, spender, value);\n }\n\n /**\n * @dev Call from.tokensToSend() if the interface is registered\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _callTokensToSend(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n ) private {\n address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(from, _TOKENS_SENDER_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Sender(implementer).tokensToSend(operator, from, to, amount, userData, operatorData);\n }\n }\n\n /**\n * @dev Call to.tokensReceived() if the interface is registered. Reverts if the recipient is a contract but\n * tokensReceived() was not registered for the recipient\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _callTokensReceived(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) private {\n address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(to, _TOKENS_RECIPIENT_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Recipient(implementer).tokensReceived(operator, from, to, amount, userData, operatorData);\n } else if (requireReceptionAck) {\n require(!to.isContract(), \"ERC777: token recipient contract has no implementer for ERC777TokensRecipient\");\n }\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {IERC20-Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC777: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes\n * calls to {send}, {transfer}, {operatorSend}, {transferFrom}, minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be to transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address operator, address from, address to, uint256 amount) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC777/IERC777.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777Token standard as defined in the EIP.\n *\n * This contract uses the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 registry standard] to let\n * token holders and recipients react to token movements by using setting implementers\n * for the associated interfaces in said registry. See {IERC1820Registry} and\n * {ERC1820Implementer}.\n */\ninterface IERC777 {\n /**\n * @dev Emitted when `amount` tokens are created by `operator` and assigned to `to`.\n *\n * Note that some additional user `data` and `operatorData` can be logged in the event.\n */\n event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);\n\n /**\n * @dev Emitted when `operator` destroys `amount` tokens from `account`.\n *\n * Note that some additional user `data` and `operatorData` can be logged in the event.\n */\n event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);\n\n /**\n * @dev Emitted when `operator` is made operator for `tokenHolder`.\n */\n event AuthorizedOperator(address indexed operator, address indexed tokenHolder);\n\n /**\n * @dev Emitted when `operator` is revoked its operator status for `tokenHolder`.\n */\n event RevokedOperator(address indexed operator, address indexed tokenHolder);\n\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, usually a shorter version of the\n * name.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the smallest part of the token that is not divisible. This\n * means all token operations (creation, movement and destruction) must have\n * amounts that are a multiple of this number.\n *\n * For most token contracts, this value will equal 1.\n */\n function granularity() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by an account (`owner`).\n */\n function balanceOf(address owner) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * If send or receive hooks are registered for the caller and `recipient`,\n * the corresponding functions will be called with `data` and empty\n * `operatorData`. See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits a {Sent} event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function send(address recipient, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Destroys `amount` tokens from the caller's account, reducing the\n * total supply.\n *\n * If a send hook is registered for the caller, the corresponding function\n * will be called with `data` and empty `operatorData`. See {IERC777Sender}.\n *\n * Emits a {Burned} event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n */\n function burn(uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Returns true if an account is an operator of `tokenHolder`.\n * Operators can send and burn tokens on behalf of their owners. All\n * accounts are their own operator.\n *\n * See {operatorSend} and {operatorBurn}.\n */\n function isOperatorFor(address operator, address tokenHolder) external view returns (bool);\n\n /**\n * @dev Make an account an operator of the caller.\n *\n * See {isOperatorFor}.\n *\n * Emits an {AuthorizedOperator} event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function authorizeOperator(address operator) external;\n\n /**\n * @dev Revoke an account's operator status for the caller.\n *\n * See {isOperatorFor} and {defaultOperators}.\n *\n * Emits a {RevokedOperator} event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function revokeOperator(address operator) external;\n\n /**\n * @dev Returns the list of default operators. These accounts are operators\n * for all token holders, even if {authorizeOperator} was never called on\n * them.\n *\n * This list is immutable, but individual holders may revoke these via\n * {revokeOperator}, in which case {isOperatorFor} will return false.\n */\n function defaultOperators() external view returns (address[] memory);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must\n * be an operator of `sender`.\n *\n * If send or receive hooks are registered for `sender` and `recipient`,\n * the corresponding functions will be called with `data` and\n * `operatorData`. See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits a {Sent} event.\n *\n * Requirements\n *\n * - `sender` cannot be the zero address.\n * - `sender` must have at least `amount` tokens.\n * - the caller must be an operator for `sender`.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes calldata data,\n bytes calldata operatorData\n ) external;\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the total supply.\n * The caller must be an operator of `account`.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with `data` and `operatorData`. See {IERC777Sender}.\n *\n * Emits a {Burned} event.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n * - the caller must be an operator for `account`.\n */\n function operatorBurn(address account, uint256 amount, bytes calldata data, bytes calldata operatorData) external;\n\n event Sent(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes data,\n bytes operatorData\n );\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\n *\n * Accounts can be notified of {IERC777} tokens being sent to them by having a\n * contract implement this interface (contract holders can be their own\n * implementer) and registering it on the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\n *\n * See {IERC1820Registry} and {ERC1820Implementer}.\n */\ninterface IERC777Recipient {\n /**\n * @dev Called by an {IERC777} token contract whenever tokens are being\n * moved or created into a registered account (`to`). The type of operation\n * is conveyed by `from` being the zero address or not.\n *\n * This call occurs _after_ the token contract's state is updated, so\n * {IERC777-balanceOf}, etc., can be used to query the post-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensReceived(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777Sender.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Sender.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777TokensSender standard as defined in the EIP.\n *\n * {IERC777} Token holders can be notified of operations performed on their\n * tokens by having a contract implement this interface (contract holders can be\n * their own implementer) and registering it on the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\n *\n * See {IERC1820Registry} and {ERC1820Implementer}.\n */\ninterface IERC777Sender {\n /**\n * @dev Called by an {IERC777} token contract whenever a registered holder's\n * (`from`) tokens are about to be moved or destroyed. The type of operation\n * is conveyed by `to` being the zero address or not.\n *\n * This call occurs _before_ the token contract's state is updated, so\n * {IERC777-balanceOf}, etc., can be used to query the pre-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensToSend(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n *\n * Furthermore, `isContract` will also return true if the target contract within\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n * which only has an effect at the end of a transaction.\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Counters.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary Counters {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/ECDSA.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Strings.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV // Deprecated in v4.8\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n /// @solidity memory-safe-assembly\n assembly {\n mstore(0x00, \"\\x19Ethereum Signed Message:\\n32\")\n mstore(0x1c, hash)\n message := keccak256(0x00, 0x3c)\n }\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\n /// @solidity memory-safe-assembly\n assembly {\n let ptr := mload(0x40)\n mstore(ptr, \"\\x19\\x01\")\n mstore(add(ptr, 0x02), domainSeparator)\n mstore(add(ptr, 0x22), structHash)\n data := keccak256(ptr, 0x42)\n }\n }\n\n /**\n * @dev Returns an Ethereum Signed Data with intended validator, created from a\n * `validator` and `data` according to the version 0 of EIP-191.\n *\n * See {recover}.\n */\n function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x00\", validator, data));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/SignatureChecker.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSA.sol\";\nimport \"../../interfaces/IERC1271.sol\";\n\n/**\n * @dev Signature verification helper that can be used instead of `ECDSA.recover` to seamlessly support both ECDSA\n * signatures from externally owned accounts (EOAs) as well as ERC1271 signatures from smart contract wallets like\n * Argent and Gnosis Safe.\n *\n * _Available since v4.1._\n */\nlibrary SignatureChecker {\n /**\n * @dev Checks if a signature is valid for a given signer and data hash. If the signer is a smart contract, the\n * signature is validated against that smart contract using ERC1271, otherwise it's validated using `ECDSA.recover`.\n *\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\n */\n function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature) internal view returns (bool) {\n (address recovered, ECDSA.RecoverError error) = ECDSA.tryRecover(hash, signature);\n return\n (error == ECDSA.RecoverError.NoError && recovered == signer) ||\n isValidERC1271SignatureNow(signer, hash, signature);\n }\n\n /**\n * @dev Checks if a signature is valid for a given signer and data hash. The signature is validated\n * against the signer smart contract using ERC1271.\n *\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\n */\n function isValidERC1271SignatureNow(\n address signer,\n bytes32 hash,\n bytes memory signature\n ) internal view returns (bool) {\n (bool success, bytes memory result) = signer.staticcall(\n abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, signature)\n );\n return (success &&\n result.length >= 32 &&\n abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/ERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165 is IERC165 {\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165).interfaceId;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC1820Registry.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/introspection/IERC1820Registry.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the global ERC1820 Registry, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register\n * implementers for interfaces in this registry, as well as query support.\n *\n * Implementers may be shared by multiple accounts, and can also implement more\n * than a single interface for each account. Contracts can implement interfaces\n * for themselves, but externally-owned accounts (EOA) must delegate this to a\n * contract.\n *\n * {IERC165} interfaces can also be queried via the registry.\n *\n * For an in-depth explanation and source code analysis, see the EIP text.\n */\ninterface IERC1820Registry {\n event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer);\n\n event ManagerChanged(address indexed account, address indexed newManager);\n\n /**\n * @dev Sets `newManager` as the manager for `account`. A manager of an\n * account is able to set interface implementers for it.\n *\n * By default, each account is its own manager. Passing a value of `0x0` in\n * `newManager` will reset the manager to this initial state.\n *\n * Emits a {ManagerChanged} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `account`.\n */\n function setManager(address account, address newManager) external;\n\n /**\n * @dev Returns the manager for `account`.\n *\n * See {setManager}.\n */\n function getManager(address account) external view returns (address);\n\n /**\n * @dev Sets the `implementer` contract as ``account``'s implementer for\n * `interfaceHash`.\n *\n * `account` being the zero address is an alias for the caller's address.\n * The zero address can also be used in `implementer` to remove an old one.\n *\n * See {interfaceHash} to learn how these are created.\n *\n * Emits an {InterfaceImplementerSet} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `account`.\n * - `interfaceHash` must not be an {IERC165} interface id (i.e. it must not\n * end in 28 zeroes).\n * - `implementer` must implement {IERC1820Implementer} and return true when\n * queried for support, unless `implementer` is the caller. See\n * {IERC1820Implementer-canImplementInterfaceForAddress}.\n */\n function setInterfaceImplementer(address account, bytes32 _interfaceHash, address implementer) external;\n\n /**\n * @dev Returns the implementer of `interfaceHash` for `account`. If no such\n * implementer is registered, returns the zero address.\n *\n * If `interfaceHash` is an {IERC165} interface id (i.e. it ends with 28\n * zeroes), `account` will be queried for support of it.\n *\n * `account` being the zero address is an alias for the caller's address.\n */\n function getInterfaceImplementer(address account, bytes32 _interfaceHash) external view returns (address);\n\n /**\n * @dev Returns the interface hash for an `interfaceName`, as defined in the\n * corresponding\n * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP].\n */\n function interfaceHash(string calldata interfaceName) external pure returns (bytes32);\n\n /**\n * @notice Updates the cache with whether the contract implements an ERC165 interface or not.\n * @param account Address of the contract for which to update the cache.\n * @param interfaceId ERC165 interface for which to update the cache.\n */\n function updateERC165Cache(address account, bytes4 interfaceId) external;\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not.\n * If the result is not cached a direct lookup on the contract address is performed.\n * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling\n * {updateERC165Cache} with the contract address.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool);\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not without using or updating the cache.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/math/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\n // The surrounding unchecked block does not change this fact.\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1, \"Math: mulDiv overflow\");\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n //\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n //\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n //\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1 << (log2(a) >> 1);\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = sqrt(a);\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 2, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 128;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 64;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 32;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 16;\n }\n if (value >> 8 > 0) {\n value >>= 8;\n result += 8;\n }\n if (value >> 4 > 0) {\n value >>= 4;\n result += 4;\n }\n if (value >> 2 > 0) {\n value >>= 2;\n result += 2;\n }\n if (value >> 1 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log2(value);\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 10, rounded down, of a positive value.\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 + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 256, rounded down, of a positive value.\n * Returns 0 if given 0.\n *\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n */\n function log256(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 16;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 8;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 4;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 2;\n }\n if (value >> 8 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log256(value);\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/SafeCast.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCast {\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 * _Available since v4.7._\n */\n function toUint248(uint256 value) internal pure returns (uint248) {\n require(value <= type(uint248).max, \"SafeCast: value doesn't fit in 248 bits\");\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 * _Available since v4.7._\n */\n function toUint240(uint256 value) internal pure returns (uint240) {\n require(value <= type(uint240).max, \"SafeCast: value doesn't fit in 240 bits\");\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 * _Available since v4.7._\n */\n function toUint232(uint256 value) internal pure returns (uint232) {\n require(value <= type(uint232).max, \"SafeCast: value doesn't fit in 232 bits\");\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 * _Available since v4.2._\n */\n function toUint224(uint256 value) internal pure returns (uint224) {\n require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\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 * _Available since v4.7._\n */\n function toUint216(uint256 value) internal pure returns (uint216) {\n require(value <= type(uint216).max, \"SafeCast: value doesn't fit in 216 bits\");\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 * _Available since v4.7._\n */\n function toUint208(uint256 value) internal pure returns (uint208) {\n require(value <= type(uint208).max, \"SafeCast: value doesn't fit in 208 bits\");\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 * _Available since v4.7._\n */\n function toUint200(uint256 value) internal pure returns (uint200) {\n require(value <= type(uint200).max, \"SafeCast: value doesn't fit in 200 bits\");\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 * _Available since v4.7._\n */\n function toUint192(uint256 value) internal pure returns (uint192) {\n require(value <= type(uint192).max, \"SafeCast: value doesn't fit in 192 bits\");\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 * _Available since v4.7._\n */\n function toUint184(uint256 value) internal pure returns (uint184) {\n require(value <= type(uint184).max, \"SafeCast: value doesn't fit in 184 bits\");\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 * _Available since v4.7._\n */\n function toUint176(uint256 value) internal pure returns (uint176) {\n require(value <= type(uint176).max, \"SafeCast: value doesn't fit in 176 bits\");\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 * _Available since v4.7._\n */\n function toUint168(uint256 value) internal pure returns (uint168) {\n require(value <= type(uint168).max, \"SafeCast: value doesn't fit in 168 bits\");\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 * _Available since v4.7._\n */\n function toUint160(uint256 value) internal pure returns (uint160) {\n require(value <= type(uint160).max, \"SafeCast: value doesn't fit in 160 bits\");\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 * _Available since v4.7._\n */\n function toUint152(uint256 value) internal pure returns (uint152) {\n require(value <= type(uint152).max, \"SafeCast: value doesn't fit in 152 bits\");\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 * _Available since v4.7._\n */\n function toUint144(uint256 value) internal pure returns (uint144) {\n require(value <= type(uint144).max, \"SafeCast: value doesn't fit in 144 bits\");\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 * _Available since v4.7._\n */\n function toUint136(uint256 value) internal pure returns (uint136) {\n require(value <= type(uint136).max, \"SafeCast: value doesn't fit in 136 bits\");\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 * _Available since v2.5._\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\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 * _Available since v4.7._\n */\n function toUint120(uint256 value) internal pure returns (uint120) {\n require(value <= type(uint120).max, \"SafeCast: value doesn't fit in 120 bits\");\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 * _Available since v4.7._\n */\n function toUint112(uint256 value) internal pure returns (uint112) {\n require(value <= type(uint112).max, \"SafeCast: value doesn't fit in 112 bits\");\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 * _Available since v4.7._\n */\n function toUint104(uint256 value) internal pure returns (uint104) {\n require(value <= type(uint104).max, \"SafeCast: value doesn't fit in 104 bits\");\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 * _Available since v4.2._\n */\n function toUint96(uint256 value) internal pure returns (uint96) {\n require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\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 * _Available since v4.7._\n */\n function toUint88(uint256 value) internal pure returns (uint88) {\n require(value <= type(uint88).max, \"SafeCast: value doesn't fit in 88 bits\");\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 * _Available since v4.7._\n */\n function toUint80(uint256 value) internal pure returns (uint80) {\n require(value <= type(uint80).max, \"SafeCast: value doesn't fit in 80 bits\");\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 * _Available since v4.7._\n */\n function toUint72(uint256 value) internal pure returns (uint72) {\n require(value <= type(uint72).max, \"SafeCast: value doesn't fit in 72 bits\");\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 * _Available since v2.5._\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\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 * _Available since v4.7._\n */\n function toUint56(uint256 value) internal pure returns (uint56) {\n require(value <= type(uint56).max, \"SafeCast: value doesn't fit in 56 bits\");\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 * _Available since v4.7._\n */\n function toUint48(uint256 value) internal pure returns (uint48) {\n require(value <= type(uint48).max, \"SafeCast: value doesn't fit in 48 bits\");\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 * _Available since v4.7._\n */\n function toUint40(uint256 value) internal pure returns (uint40) {\n require(value <= type(uint40).max, \"SafeCast: value doesn't fit in 40 bits\");\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 * _Available since v2.5._\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\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 * _Available since v4.7._\n */\n function toUint24(uint256 value) internal pure returns (uint24) {\n require(value <= type(uint24).max, \"SafeCast: value doesn't fit in 24 bits\");\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 * _Available since v2.5._\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\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 * _Available since v2.5._\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\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 * _Available since v3.0._\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\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 * _Available since v4.7._\n */\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\n downcasted = int248(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 248 bits\");\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 * _Available since v4.7._\n */\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\n downcasted = int240(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 240 bits\");\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 * _Available since v4.7._\n */\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\n downcasted = int232(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 232 bits\");\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 * _Available since v4.7._\n */\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\n downcasted = int224(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 224 bits\");\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 * _Available since v4.7._\n */\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\n downcasted = int216(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 216 bits\");\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 * _Available since v4.7._\n */\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\n downcasted = int208(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 208 bits\");\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 * _Available since v4.7._\n */\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\n downcasted = int200(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 200 bits\");\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 * _Available since v4.7._\n */\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\n downcasted = int192(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 192 bits\");\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 * _Available since v4.7._\n */\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\n downcasted = int184(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 184 bits\");\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 * _Available since v4.7._\n */\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\n downcasted = int176(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 176 bits\");\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 * _Available since v4.7._\n */\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\n downcasted = int168(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 168 bits\");\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 * _Available since v4.7._\n */\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\n downcasted = int160(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 160 bits\");\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 * _Available since v4.7._\n */\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\n downcasted = int152(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 152 bits\");\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 * _Available since v4.7._\n */\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\n downcasted = int144(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 144 bits\");\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 * _Available since v4.7._\n */\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\n downcasted = int136(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 136 bits\");\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 * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\n downcasted = int128(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 128 bits\");\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 * _Available since v4.7._\n */\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\n downcasted = int120(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 120 bits\");\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 * _Available since v4.7._\n */\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\n downcasted = int112(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 112 bits\");\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 * _Available since v4.7._\n */\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\n downcasted = int104(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 104 bits\");\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 * _Available since v4.7._\n */\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\n downcasted = int96(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 96 bits\");\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 * _Available since v4.7._\n */\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\n downcasted = int88(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 88 bits\");\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 * _Available since v4.7._\n */\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\n downcasted = int80(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 80 bits\");\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 * _Available since v4.7._\n */\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\n downcasted = int72(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 72 bits\");\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 * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\n downcasted = int64(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 64 bits\");\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 * _Available since v4.7._\n */\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\n downcasted = int56(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 56 bits\");\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 * _Available since v4.7._\n */\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\n downcasted = int48(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 48 bits\");\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 * _Available since v4.7._\n */\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\n downcasted = int40(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 40 bits\");\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 * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\n downcasted = int32(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 32 bits\");\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 * _Available since v4.7._\n */\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\n downcasted = int24(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 24 bits\");\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 * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\n downcasted = int16(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 16 bits\");\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 * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\n downcasted = int8(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 8 bits\");\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 * _Available since v3.0._\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 require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/SignedMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard signed math utilities missing in the Solidity language.\n */\nlibrary SignedMath {\n /**\n * @dev Returns the largest of two signed numbers.\n */\n function max(int256 a, int256 b) internal pure returns (int256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two signed numbers.\n */\n function min(int256 a, int256 b) internal pure returns (int256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two signed numbers without overflow.\n * The result is rounded towards zero.\n */\n function average(int256 a, int256 b) internal pure returns (int256) {\n // Formula from the book \"Hacker's Delight\"\n int256 x = (a & b) + ((a ^ b) >> 1);\n return x + (int256(uint256(x) >> 255) & (a ^ b));\n }\n\n /**\n * @dev Returns the absolute unsigned value of a signed value.\n */\n function abs(int256 n) internal pure returns (uint256) {\n unchecked {\n // must be unchecked in order to support `n = type(int256).min`\n return uint256(n >= 0 ? n : -n);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/Math.sol\";\nimport \"./math/SignedMath.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n unchecked {\n uint256 length = Math.log10(value) + 1;\n string memory buffer = new string(length);\n uint256 ptr;\n /// @solidity memory-safe-assembly\n assembly {\n ptr := add(buffer, add(32, length))\n }\n while (true) {\n ptr--;\n /// @solidity memory-safe-assembly\n assembly {\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n }\n value /= 10;\n if (value == 0) break;\n }\n return buffer;\n }\n }\n\n /**\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\n */\n function toString(int256 value) internal pure returns (string memory) {\n return string(abi.encodePacked(value < 0 ? \"-\" : \"\", toString(SignedMath.abs(value))));\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n unchecked {\n return toHexString(value, Math.log256(value) + 1);\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n\n /**\n * @dev Returns true if the two strings are equal.\n */\n function equal(string memory a, string memory b) internal pure returns (bool) {\n return keccak256(bytes(a)) == keccak256(bytes(b));\n }\n}\n" + }, + "contracts/aa-4337/core/BaseAccount.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-empty-blocks */\n\nimport \"../interfaces/IAccount.sol\";\nimport \"../interfaces/IEntryPoint.sol\";\nimport \"./Helpers.sol\";\n\n/**\n * Basic account implementation.\n * this contract provides the basic logic for implementing the IAccount interface - validateUserOp\n * specific account implementation should inherit it and provide the account-specific logic\n */\nabstract contract BaseAccount is IAccount {\n using UserOperationLib for UserOperation;\n\n //return value in case of signature failure, with no time-range.\n // equivalent to _packValidationData(true,0,0);\n uint256 internal constant SIG_VALIDATION_FAILED = 1;\n\n /**\n * Return the account nonce.\n * This method returns the next sequential nonce.\n * For a nonce of a specific key, use `entrypoint.getNonce(account, key)`\n */\n function getNonce() public view virtual returns (uint256) {\n return entryPoint().getNonce(address(this), 0);\n }\n\n /**\n * return the entryPoint used by this account.\n * subclass should return the current entryPoint used by this account.\n */\n function entryPoint() public view virtual returns (IEntryPoint);\n\n /**\n * Validate user's signature and nonce.\n * subclass doesn't need to override this method. Instead, it should override the specific internal validation methods.\n */\n function validateUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 missingAccountFunds\n ) external virtual override returns (uint256 validationData) {\n _requireFromEntryPoint();\n validationData = _validateSignature(userOp, userOpHash);\n _validateNonce(userOp.nonce);\n _payPrefund(missingAccountFunds);\n }\n\n /**\n * ensure the request comes from the known entrypoint.\n */\n function _requireFromEntryPoint() internal view virtual {\n require(\n msg.sender == address(entryPoint()),\n \"account: not from EntryPoint\"\n );\n }\n\n /**\n * validate the signature is valid for this message.\n * @param userOp validate the userOp.signature field\n * @param userOpHash convenient field: the hash of the request, to check the signature against\n * (also hashes the entrypoint and chain id)\n * @return validationData signature and time-range of this operation\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * If the account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function _validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) internal virtual returns (uint256 validationData);\n\n /**\n * Validate the nonce of the UserOperation.\n * This method may validate the nonce requirement of this account.\n * e.g.\n * To limit the nonce to use sequenced UserOps only (no \"out of order\" UserOps):\n * `require(nonce < type(uint64).max)`\n * For a hypothetical account that *requires* the nonce to be out-of-order:\n * `require(nonce & type(uint64).max == 0)`\n *\n * The actual nonce uniqueness is managed by the EntryPoint, and thus no other\n * action is needed by the account itself.\n *\n * @param nonce to validate\n *\n * solhint-disable-next-line no-empty-blocks\n */\n function _validateNonce(uint256 nonce) internal view virtual {}\n\n /**\n * sends to the entrypoint (msg.sender) the missing funds for this transaction.\n * subclass MAY override this method for better funds management\n * (e.g. send to the entryPoint more than the minimum required, so that in future transactions\n * it will not be required to send again)\n * @param missingAccountFunds the minimum value this method should send the entrypoint.\n * this value MAY be zero, in case there is enough deposit, or the userOp has a paymaster.\n */\n function _payPrefund(uint256 missingAccountFunds) internal virtual {\n if (missingAccountFunds != 0) {\n (bool success, ) = payable(msg.sender).call{\n value: missingAccountFunds,\n gas: type(uint256).max\n }(\"\");\n (success);\n //ignore failure (its EntryPoint's job to verify, not account.)\n }\n }\n}\n" + }, + "contracts/aa-4337/core/EntryPoint.sol": { + "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n\nimport \"../interfaces/IAccount.sol\";\nimport \"../interfaces/IPaymaster.sol\";\nimport \"../interfaces/IEntryPoint.sol\";\n\nimport \"../utils/Exec.sol\";\nimport \"./StakeManager.sol\";\nimport \"./SenderCreator.sol\";\nimport \"./Helpers.sol\";\nimport \"./NonceManager.sol\";\nimport \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\n\ncontract EntryPoint is\n IEntryPoint,\n StakeManager,\n NonceManager,\n ReentrancyGuard\n{\n using UserOperationLib for UserOperation;\n\n SenderCreator private immutable senderCreator = new SenderCreator();\n\n // internal value used during simulation: need to query aggregator.\n address private constant SIMULATE_FIND_AGGREGATOR = address(1);\n\n // marker for inner call revert on out of gas\n bytes32 private constant INNER_OUT_OF_GAS = hex\"deaddead\";\n\n uint256 private constant REVERT_REASON_MAX_LEN = 2048;\n\n /**\n * for simulation purposes, validateUserOp (and validatePaymasterUserOp) must return this value\n * in case of signature failure, instead of revert.\n */\n uint256 public constant SIG_VALIDATION_FAILED = 1;\n\n /**\n * compensate the caller's beneficiary address with the collected fees of all UserOperations.\n * @param beneficiary the address to receive the fees\n * @param amount amount to transfer.\n */\n function _compensate(address payable beneficiary, uint256 amount) internal {\n require(beneficiary != address(0), \"AA90 invalid beneficiary\");\n (bool success, ) = beneficiary.call{value: amount}(\"\");\n require(success, \"AA91 failed send to beneficiary\");\n }\n\n /**\n * execute a user op\n * @param opIndex index into the opInfo array\n * @param userOp the userOp to execute\n * @param opInfo the opInfo filled by validatePrepayment for this userOp.\n * @return collected the total amount this userOp paid.\n */\n function _executeUserOp(\n uint256 opIndex,\n UserOperation calldata userOp,\n UserOpInfo memory opInfo\n ) private returns (uint256 collected) {\n uint256 preGas = gasleft();\n bytes memory context = getMemoryBytesFromOffset(opInfo.contextOffset);\n\n try this.innerHandleOp(userOp.callData, opInfo, context) returns (\n uint256 _actualGasCost\n ) {\n collected = _actualGasCost;\n } catch {\n bytes32 innerRevertCode;\n assembly {\n returndatacopy(0, 0, 32)\n innerRevertCode := mload(0)\n }\n // handleOps was called with gas limit too low. abort entire bundle.\n if (innerRevertCode == INNER_OUT_OF_GAS) {\n //report paymaster, since if it is not deliberately caused by the bundler,\n // it must be a revert caused by paymaster.\n revert FailedOp(opIndex, \"AA95 out of gas\");\n }\n\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n collected = _handlePostOp(\n opIndex,\n IPaymaster.PostOpMode.postOpReverted,\n opInfo,\n context,\n actualGas\n );\n }\n }\n\n /**\n * Execute a batch of UserOperations.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(\n UserOperation[] calldata ops,\n address payable beneficiary\n ) public nonReentrant {\n uint256 opslen = ops.length;\n UserOpInfo[] memory opInfos = new UserOpInfo[](opslen);\n\n unchecked {\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[i];\n (\n uint256 validationData,\n uint256 pmValidationData\n ) = _validatePrepayment(i, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(\n i,\n validationData,\n pmValidationData,\n address(0)\n );\n }\n\n uint256 collected = 0;\n emit BeforeExecution();\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(i, ops[i], opInfos[i]);\n }\n\n _compensate(beneficiary, collected);\n } //unchecked\n }\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) public nonReentrant {\n uint256 opasLen = opsPerAggregator.length;\n uint256 totalOps = 0;\n for (uint256 i = 0; i < opasLen; i++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[i];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n //address(1) is special marker of \"signature error\"\n require(\n address(aggregator) != address(1),\n \"AA96 invalid aggregator\"\n );\n\n if (address(aggregator) != address(0)) {\n // solhint-disable-next-line no-empty-blocks\n try aggregator.validateSignatures(ops, opa.signature) {} catch {\n revert SignatureValidationFailed(address(aggregator));\n }\n }\n\n totalOps += ops.length;\n }\n\n UserOpInfo[] memory opInfos = new UserOpInfo[](totalOps);\n\n emit BeforeExecution();\n\n uint256 opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n uint256 opslen = ops.length;\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[opIndex];\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(opIndex, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(\n i,\n validationData,\n paymasterValidationData,\n address(aggregator)\n );\n opIndex++;\n }\n }\n\n uint256 collected = 0;\n opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n emit SignatureAggregatorChanged(address(opa.aggregator));\n UserOperation[] calldata ops = opa.userOps;\n uint256 opslen = ops.length;\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(opIndex, ops[i], opInfos[opIndex]);\n opIndex++;\n }\n }\n emit SignatureAggregatorChanged(address(0));\n\n _compensate(beneficiary, collected);\n }\n\n /// @inheritdoc IEntryPoint\n function simulateHandleOp(\n UserOperation calldata op,\n address target,\n bytes calldata targetCallData\n ) external override {\n UserOpInfo memory opInfo;\n _simulationOnlyValidations(op);\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(0, op, opInfo);\n ValidationData memory data = _intersectTimeRange(\n validationData,\n paymasterValidationData\n );\n\n numberMarker();\n uint256 paid = _executeUserOp(0, op, opInfo);\n numberMarker();\n bool targetSuccess;\n bytes memory targetResult;\n if (target != address(0)) {\n (targetSuccess, targetResult) = target.call(targetCallData);\n }\n revert ExecutionResult(\n opInfo.preOpGas,\n paid,\n data.validAfter,\n data.validUntil,\n targetSuccess,\n targetResult\n );\n }\n\n // A memory copy of UserOp static fields only.\n // Excluding: callData, initCode and signature. Replacing paymasterAndData with paymaster.\n struct MemoryUserOp {\n address sender;\n uint256 nonce;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n address paymaster;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n }\n\n struct UserOpInfo {\n MemoryUserOp mUserOp;\n bytes32 userOpHash;\n uint256 prefund;\n uint256 contextOffset;\n uint256 preOpGas;\n }\n\n /**\n * inner function to handle a UserOperation.\n * Must be declared \"external\" to open a call context, but it can only be called by handleOps.\n */\n function innerHandleOp(\n bytes memory callData,\n UserOpInfo memory opInfo,\n bytes calldata context\n ) external returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n require(msg.sender == address(this), \"AA92 internal call only\");\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n\n uint callGasLimit = mUserOp.callGasLimit;\n unchecked {\n // handleOps was called with gas limit too low. abort entire bundle.\n if (\n gasleft() < callGasLimit + mUserOp.verificationGasLimit + 5000\n ) {\n assembly {\n mstore(0, INNER_OUT_OF_GAS)\n revert(0, 32)\n }\n }\n }\n\n IPaymaster.PostOpMode mode = IPaymaster.PostOpMode.opSucceeded;\n if (callData.length > 0) {\n bool success = Exec.call(mUserOp.sender, 0, callData, callGasLimit);\n if (!success) {\n bytes memory result = Exec.getReturnData(REVERT_REASON_MAX_LEN);\n if (result.length > 0) {\n emit UserOperationRevertReason(\n opInfo.userOpHash,\n mUserOp.sender,\n mUserOp.nonce,\n result\n );\n }\n mode = IPaymaster.PostOpMode.opReverted;\n }\n }\n\n unchecked {\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n //note: opIndex is ignored (relevant only if mode==postOpReverted, which is only possible outside of innerHandleOp)\n return _handlePostOp(0, mode, opInfo, context, actualGas);\n }\n }\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(\n UserOperation calldata userOp\n ) public view returns (bytes32) {\n return\n keccak256(abi.encode(userOp.hash(), address(this), block.chainid));\n }\n\n /**\n * copy general fields from userOp into the memory opInfo structure.\n */\n function _copyUserOpToMemory(\n UserOperation calldata userOp,\n MemoryUserOp memory mUserOp\n ) internal pure {\n mUserOp.sender = userOp.sender;\n mUserOp.nonce = userOp.nonce;\n mUserOp.callGasLimit = userOp.callGasLimit;\n mUserOp.verificationGasLimit = userOp.verificationGasLimit;\n mUserOp.preVerificationGas = userOp.preVerificationGas;\n mUserOp.maxFeePerGas = userOp.maxFeePerGas;\n mUserOp.maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes calldata paymasterAndData = userOp.paymasterAndData;\n if (paymasterAndData.length > 0) {\n require(\n paymasterAndData.length >= 20,\n \"AA93 invalid paymasterAndData\"\n );\n mUserOp.paymaster = address(bytes20(paymasterAndData[:20]));\n } else {\n mUserOp.paymaster = address(0);\n }\n }\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external {\n UserOpInfo memory outOpInfo;\n\n _simulationOnlyValidations(userOp);\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(0, userOp, outOpInfo);\n StakeInfo memory paymasterInfo = _getStakeInfo(\n outOpInfo.mUserOp.paymaster\n );\n StakeInfo memory senderInfo = _getStakeInfo(outOpInfo.mUserOp.sender);\n StakeInfo memory factoryInfo;\n {\n bytes calldata initCode = userOp.initCode;\n address factory = initCode.length >= 20\n ? address(bytes20(initCode[0:20]))\n : address(0);\n factoryInfo = _getStakeInfo(factory);\n }\n\n ValidationData memory data = _intersectTimeRange(\n validationData,\n paymasterValidationData\n );\n address aggregator = data.aggregator;\n bool sigFailed = aggregator == address(1);\n ReturnInfo memory returnInfo = ReturnInfo(\n outOpInfo.preOpGas,\n outOpInfo.prefund,\n sigFailed,\n data.validAfter,\n data.validUntil,\n getMemoryBytesFromOffset(outOpInfo.contextOffset)\n );\n\n if (aggregator != address(0) && aggregator != address(1)) {\n AggregatorStakeInfo memory aggregatorInfo = AggregatorStakeInfo(\n aggregator,\n _getStakeInfo(aggregator)\n );\n revert ValidationResultWithAggregation(\n returnInfo,\n senderInfo,\n factoryInfo,\n paymasterInfo,\n aggregatorInfo\n );\n }\n revert ValidationResult(\n returnInfo,\n senderInfo,\n factoryInfo,\n paymasterInfo\n );\n }\n\n function _getRequiredPrefund(\n MemoryUserOp memory mUserOp\n ) internal pure returns (uint256 requiredPrefund) {\n unchecked {\n //when using a Paymaster, the verificationGasLimit is used also to as a limit for the postOp call.\n // our security model might call postOp eventually twice\n uint256 mul = mUserOp.paymaster != address(0) ? 3 : 1;\n uint256 requiredGas = mUserOp.callGasLimit +\n mUserOp.verificationGasLimit *\n mul +\n mUserOp.preVerificationGas;\n\n requiredPrefund = requiredGas * mUserOp.maxFeePerGas;\n }\n }\n\n // create the sender's contract if needed.\n function _createSenderIfNeeded(\n uint256 opIndex,\n UserOpInfo memory opInfo,\n bytes calldata initCode\n ) internal {\n if (initCode.length != 0) {\n address sender = opInfo.mUserOp.sender;\n if (sender.code.length != 0)\n revert FailedOp(opIndex, \"AA10 sender already constructed\");\n address sender1 = senderCreator.createSender{\n gas: opInfo.mUserOp.verificationGasLimit\n }(initCode);\n if (sender1 == address(0))\n revert FailedOp(opIndex, \"AA13 initCode failed or OOG\");\n if (sender1 != sender)\n revert FailedOp(opIndex, \"AA14 initCode must return sender\");\n if (sender1.code.length == 0)\n revert FailedOp(opIndex, \"AA15 initCode must create sender\");\n address factory = address(bytes20(initCode[0:20]));\n emit AccountDeployed(\n opInfo.userOpHash,\n sender,\n factory,\n opInfo.mUserOp.paymaster\n );\n }\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes calldata initCode) public {\n address sender = senderCreator.createSender(initCode);\n revert SenderAddressResult(sender);\n }\n\n function _simulationOnlyValidations(\n UserOperation calldata userOp\n ) internal view {\n // solhint-disable-next-line no-empty-blocks\n try\n this._validateSenderAndPaymaster(\n userOp.initCode,\n userOp.sender,\n userOp.paymasterAndData\n )\n {} catch Error(string memory revertReason) {\n if (bytes(revertReason).length != 0) {\n revert FailedOp(0, revertReason);\n }\n }\n }\n\n /**\n * Called only during simulation.\n * This function always reverts to prevent warm/cold storage differentiation in simulation vs execution.\n */\n function _validateSenderAndPaymaster(\n bytes calldata initCode,\n address sender,\n bytes calldata paymasterAndData\n ) external view {\n if (initCode.length == 0 && sender.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA20 account not deployed\");\n }\n if (paymasterAndData.length >= 20) {\n address paymaster = address(bytes20(paymasterAndData[0:20]));\n if (paymaster.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA30 paymaster not deployed\");\n }\n }\n // always revert\n revert(\"\");\n }\n\n /**\n * call account.validateUserOp.\n * revert (with FailedOp) in case validateUserOp reverts, or account didn't send required prefund.\n * decrement account's deposit if needed\n */\n function _validateAccountPrepayment(\n uint256 opIndex,\n UserOperation calldata op,\n UserOpInfo memory opInfo,\n uint256 requiredPrefund\n )\n internal\n returns (\n uint256 gasUsedByValidateAccountPrepayment,\n uint256 validationData\n )\n {\n unchecked {\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n address sender = mUserOp.sender;\n _createSenderIfNeeded(opIndex, opInfo, op.initCode);\n address paymaster = mUserOp.paymaster;\n numberMarker();\n uint256 missingAccountFunds = 0;\n if (paymaster == address(0)) {\n uint256 bal = balanceOf(sender);\n missingAccountFunds = bal > requiredPrefund\n ? 0\n : requiredPrefund - bal;\n }\n try\n IAccount(sender).validateUserOp{\n gas: mUserOp.verificationGasLimit\n }(op, opInfo.userOpHash, missingAccountFunds)\n returns (uint256 _validationData) {\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA23 reverted: \", revertReason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA23 reverted (or OOG)\");\n }\n if (paymaster == address(0)) {\n DepositInfo storage senderInfo = deposits[sender];\n uint256 deposit = senderInfo.deposit;\n if (requiredPrefund > deposit) {\n revert FailedOp(opIndex, \"AA21 didn't pay prefund\");\n }\n senderInfo.deposit = uint112(deposit - requiredPrefund);\n }\n gasUsedByValidateAccountPrepayment = preGas - gasleft();\n }\n }\n\n /**\n * In case the request has a paymaster:\n * Validate paymaster has enough deposit.\n * Call paymaster.validatePaymasterUserOp.\n * Revert with proper FailedOp in case paymaster reverts.\n * Decrement paymaster's deposit\n */\n function _validatePaymasterPrepayment(\n uint256 opIndex,\n UserOperation calldata op,\n UserOpInfo memory opInfo,\n uint256 requiredPreFund,\n uint256 gasUsedByValidateAccountPrepayment\n ) internal returns (bytes memory context, uint256 validationData) {\n unchecked {\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 verificationGasLimit = mUserOp.verificationGasLimit;\n require(\n verificationGasLimit > gasUsedByValidateAccountPrepayment,\n \"AA41 too little verificationGas\"\n );\n uint256 gas = verificationGasLimit -\n gasUsedByValidateAccountPrepayment;\n\n address paymaster = mUserOp.paymaster;\n DepositInfo storage paymasterInfo = deposits[paymaster];\n uint256 deposit = paymasterInfo.deposit;\n if (deposit < requiredPreFund) {\n revert FailedOp(opIndex, \"AA31 paymaster deposit too low\");\n }\n paymasterInfo.deposit = uint112(deposit - requiredPreFund);\n try\n IPaymaster(paymaster).validatePaymasterUserOp{gas: gas}(\n op,\n opInfo.userOpHash,\n requiredPreFund\n )\n returns (bytes memory _context, uint256 _validationData) {\n context = _context;\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA33 reverted: \", revertReason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA33 reverted (or OOG)\");\n }\n }\n }\n\n /**\n * revert if either account validationData or paymaster validationData is expired\n */\n function _validateAccountAndPaymasterValidationData(\n uint256 opIndex,\n uint256 validationData,\n uint256 paymasterValidationData,\n address expectedAggregator\n ) internal view {\n (address aggregator, bool outOfTimeRange) = _getValidationData(\n validationData\n );\n if (expectedAggregator != aggregator) {\n revert FailedOp(opIndex, \"AA24 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA22 expired or not due\");\n }\n //pmAggregator is not a real signature aggregator: we don't have logic to handle it as address.\n // non-zero address means that the paymaster fails due to some signature check (which is ok only during estimation)\n address pmAggregator;\n (pmAggregator, outOfTimeRange) = _getValidationData(\n paymasterValidationData\n );\n if (pmAggregator != address(0)) {\n revert FailedOp(opIndex, \"AA34 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA32 paymaster expired or not due\");\n }\n }\n\n function _getValidationData(\n uint256 validationData\n ) internal view returns (address aggregator, bool outOfTimeRange) {\n if (validationData == 0) {\n return (address(0), false);\n }\n ValidationData memory data = _parseValidationData(validationData);\n // solhint-disable-next-line not-rely-on-time\n outOfTimeRange =\n block.timestamp > data.validUntil ||\n block.timestamp < data.validAfter;\n aggregator = data.aggregator;\n }\n\n /**\n * validate account and paymaster (if defined).\n * also make sure total validation doesn't exceed verificationGasLimit\n * this method is called off-chain (simulateValidation()) and on-chain (from handleOps)\n * @param opIndex the index of this userOp into the \"opInfos\" array\n * @param userOp the userOp to validate\n */\n function _validatePrepayment(\n uint256 opIndex,\n UserOperation calldata userOp,\n UserOpInfo memory outOpInfo\n )\n private\n returns (uint256 validationData, uint256 paymasterValidationData)\n {\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = outOpInfo.mUserOp;\n _copyUserOpToMemory(userOp, mUserOp);\n outOpInfo.userOpHash = getUserOpHash(userOp);\n\n // validate all numeric values in userOp are well below 128 bit, so they can safely be added\n // and multiplied without causing overflow\n uint256 maxGasValues = mUserOp.preVerificationGas |\n mUserOp.verificationGasLimit |\n mUserOp.callGasLimit |\n userOp.maxFeePerGas |\n userOp.maxPriorityFeePerGas;\n require(maxGasValues <= type(uint120).max, \"AA94 gas values overflow\");\n\n uint256 gasUsedByValidateAccountPrepayment;\n uint256 requiredPreFund = _getRequiredPrefund(mUserOp);\n (\n gasUsedByValidateAccountPrepayment,\n validationData\n ) = _validateAccountPrepayment(\n opIndex,\n userOp,\n outOpInfo,\n requiredPreFund\n );\n\n if (!_validateAndUpdateNonce(mUserOp.sender, mUserOp.nonce)) {\n revert FailedOp(opIndex, \"AA25 invalid account nonce\");\n }\n\n //a \"marker\" where account opcode validation is done and paymaster opcode validation is about to start\n // (used only by off-chain simulateValidation)\n numberMarker();\n\n bytes memory context;\n if (mUserOp.paymaster != address(0)) {\n (context, paymasterValidationData) = _validatePaymasterPrepayment(\n opIndex,\n userOp,\n outOpInfo,\n requiredPreFund,\n gasUsedByValidateAccountPrepayment\n );\n }\n unchecked {\n uint256 gasUsed = preGas - gasleft();\n\n if (userOp.verificationGasLimit < gasUsed) {\n revert FailedOp(opIndex, \"AA40 over verificationGasLimit\");\n }\n outOpInfo.prefund = requiredPreFund;\n outOpInfo.contextOffset = getOffsetOfMemoryBytes(context);\n outOpInfo.preOpGas = preGas - gasleft() + userOp.preVerificationGas;\n }\n }\n\n /**\n * process post-operation.\n * called just after the callData is executed.\n * if a paymaster is defined and its validation returned a non-empty context, its postOp is called.\n * the excess amount is refunded to the account (or paymaster - if it was used in the request)\n * @param opIndex index in the batch\n * @param mode - whether is called from innerHandleOp, or outside (postOpReverted)\n * @param opInfo userOp fields and info collected during validation\n * @param context the context returned in validatePaymasterUserOp\n * @param actualGas the gas used so far by this user operation\n */\n function _handlePostOp(\n uint256 opIndex,\n IPaymaster.PostOpMode mode,\n UserOpInfo memory opInfo,\n bytes memory context,\n uint256 actualGas\n ) private returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n unchecked {\n address refundAddress;\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 gasPrice = getUserOpGasPrice(mUserOp);\n\n address paymaster = mUserOp.paymaster;\n if (paymaster == address(0)) {\n refundAddress = mUserOp.sender;\n } else {\n refundAddress = paymaster;\n if (context.length > 0) {\n actualGasCost = actualGas * gasPrice;\n if (mode != IPaymaster.PostOpMode.postOpReverted) {\n IPaymaster(paymaster).postOp{\n gas: mUserOp.verificationGasLimit\n }(mode, context, actualGasCost);\n } else {\n // solhint-disable-next-line no-empty-blocks\n try\n IPaymaster(paymaster).postOp{\n gas: mUserOp.verificationGasLimit\n }(mode, context, actualGasCost)\n {} catch Error(string memory reason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA50 postOp reverted: \", reason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA50 postOp revert\");\n }\n }\n }\n }\n actualGas += preGas - gasleft();\n actualGasCost = actualGas * gasPrice;\n if (opInfo.prefund < actualGasCost) {\n revert FailedOp(opIndex, \"AA51 prefund below actualGasCost\");\n }\n uint256 refund = opInfo.prefund - actualGasCost;\n _incrementDeposit(refundAddress, refund);\n bool success = mode == IPaymaster.PostOpMode.opSucceeded;\n emit UserOperationEvent(\n opInfo.userOpHash,\n mUserOp.sender,\n mUserOp.paymaster,\n mUserOp.nonce,\n success,\n actualGasCost,\n actualGas\n );\n } // unchecked\n }\n\n /**\n * the gas price this UserOp agrees to pay.\n * relayer/block builder might submit the TX with higher priorityFee, but the user should not\n */\n function getUserOpGasPrice(\n MemoryUserOp memory mUserOp\n ) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = mUserOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = mUserOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n function getOffsetOfMemoryBytes(\n bytes memory data\n ) internal pure returns (uint256 offset) {\n assembly {\n offset := data\n }\n }\n\n function getMemoryBytesFromOffset(\n uint256 offset\n ) internal pure returns (bytes memory data) {\n assembly {\n data := offset\n }\n }\n\n //place the NUMBER opcode in the code.\n // this is used as a marker during simulation, as this OP is completely banned from the simulated code of the\n // account and paymaster.\n function numberMarker() internal view {\n assembly {\n mstore(0, number())\n }\n }\n}\n" + }, + "contracts/aa-4337/core/Helpers.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable no-inline-assembly */\n\n/**\n * returned data from validateUserOp.\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\n * @param aggregator - address(0) - the account validated the signature by itself.\n * address(1) - the account failed to validate the signature.\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\n * @param validAfter - this UserOp is valid only after this timestamp.\n * @param validaUntil - this UserOp is valid only up to this timestamp.\n */\nstruct ValidationData {\n address aggregator;\n uint48 validAfter;\n uint48 validUntil;\n}\n\n//extract sigFailed, validAfter, validUntil.\n// also convert zero validUntil to type(uint48).max\nfunction _parseValidationData(\n uint validationData\n) pure returns (ValidationData memory data) {\n address aggregator = address(uint160(validationData));\n uint48 validUntil = uint48(validationData >> 160);\n if (validUntil == 0) {\n validUntil = type(uint48).max;\n }\n uint48 validAfter = uint48(validationData >> (48 + 160));\n return ValidationData(aggregator, validAfter, validUntil);\n}\n\n// intersect account and paymaster ranges.\nfunction _intersectTimeRange(\n uint256 validationData,\n uint256 paymasterValidationData\n) pure returns (ValidationData memory) {\n ValidationData memory accountValidationData = _parseValidationData(\n validationData\n );\n ValidationData memory pmValidationData = _parseValidationData(\n paymasterValidationData\n );\n address aggregator = accountValidationData.aggregator;\n if (aggregator == address(0)) {\n aggregator = pmValidationData.aggregator;\n }\n uint48 validAfter = accountValidationData.validAfter;\n uint48 validUntil = accountValidationData.validUntil;\n uint48 pmValidAfter = pmValidationData.validAfter;\n uint48 pmValidUntil = pmValidationData.validUntil;\n\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\n return ValidationData(aggregator, validAfter, validUntil);\n}\n\n/**\n * helper to pack the return value for validateUserOp\n * @param data - the ValidationData to pack\n */\nfunction _packValidationData(\n ValidationData memory data\n) pure returns (uint256) {\n return\n uint160(data.aggregator) |\n (uint256(data.validUntil) << 160) |\n (uint256(data.validAfter) << (160 + 48));\n}\n\n/**\n * helper to pack the return value for validateUserOp, when not using an aggregator\n * @param sigFailed - true for signature failure, false for success\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\n * @param validAfter first timestamp this UserOperation is valid\n */\nfunction _packValidationData(\n bool sigFailed,\n uint48 validUntil,\n uint48 validAfter\n) pure returns (uint256) {\n return\n (sigFailed ? 1 : 0) |\n (uint256(validUntil) << 160) |\n (uint256(validAfter) << (160 + 48));\n}\n\n/**\n * keccak function over calldata.\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\n */\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\n assembly {\n let mem := mload(0x40)\n let len := data.length\n calldatacopy(mem, data.offset, len)\n ret := keccak256(mem, len)\n }\n}\n" + }, + "contracts/aa-4337/core/NonceManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\nimport \"../interfaces/IEntryPoint.sol\";\n\n/**\n * nonce management functionality\n */\ncontract NonceManager is INonceManager {\n /**\n * The next valid sequence number for a given nonce key.\n */\n mapping(address => mapping(uint192 => uint256)) public nonceSequenceNumber;\n\n function getNonce(\n address sender,\n uint192 key\n ) public view override returns (uint256 nonce) {\n return nonceSequenceNumber[sender][key] | (uint256(key) << 64);\n }\n\n // allow an account to manually increment its own nonce.\n // (mainly so that during construction nonce can be made non-zero,\n // to \"absorb\" the gas cost of first nonce increment to 1st transaction (construction),\n // not to 2nd transaction)\n function incrementNonce(uint192 key) public override {\n nonceSequenceNumber[msg.sender][key]++;\n }\n\n /**\n * validate nonce uniqueness for this account.\n * called just after validateUserOp()\n */\n function _validateAndUpdateNonce(\n address sender,\n uint256 nonce\n ) internal returns (bool) {\n uint192 key = uint192(nonce >> 64);\n uint64 seq = uint64(nonce);\n return nonceSequenceNumber[sender][key]++ == seq;\n }\n}\n" + }, + "contracts/aa-4337/core/SenderCreator.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/**\n * helper contract for EntryPoint, to call userOp.initCode from a \"neutral\" address,\n * which is explicitly not the entryPoint itself.\n */\ncontract SenderCreator {\n /**\n * call the \"initCode\" factory to create and return the sender account address\n * @param initCode the initCode value from a UserOp. contains 20 bytes of factory address, followed by calldata\n * @return sender the returned address of the created account, or zero address on failure.\n */\n function createSender(\n bytes calldata initCode\n ) external returns (address sender) {\n address factory = address(bytes20(initCode[0:20]));\n bytes memory initCallData = initCode[20:];\n bool success;\n /* solhint-disable no-inline-assembly */\n assembly {\n success := call(\n gas(),\n factory,\n 0,\n add(initCallData, 0x20),\n mload(initCallData),\n 0,\n 32\n )\n sender := mload(0)\n }\n if (!success) {\n sender = address(0);\n }\n }\n}\n" + }, + "contracts/aa-4337/core/StakeManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity 0.8.21;\n\nimport \"../interfaces/IStakeManager.sol\";\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable not-rely-on-time */\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by a paymaster.\n */\nabstract contract StakeManager is IStakeManager {\n /// maps paymaster to their deposits and stakes\n mapping(address => DepositInfo) public deposits;\n\n /// @inheritdoc IStakeManager\n function getDepositInfo(\n address account\n ) public view returns (DepositInfo memory info) {\n return deposits[account];\n }\n\n // internal method to return just the stake info\n function _getStakeInfo(\n address addr\n ) internal view returns (StakeInfo memory info) {\n DepositInfo storage depositInfo = deposits[addr];\n info.stake = depositInfo.stake;\n info.unstakeDelaySec = depositInfo.unstakeDelaySec;\n }\n\n /// return the deposit (for gas payment) of the account\n function balanceOf(address account) public view returns (uint256) {\n return deposits[account].deposit;\n }\n\n receive() external payable {\n depositTo(msg.sender);\n }\n\n function _incrementDeposit(address account, uint256 amount) internal {\n DepositInfo storage info = deposits[account];\n uint256 newAmount = info.deposit + amount;\n require(newAmount <= type(uint112).max, \"deposit overflow\");\n info.deposit = uint112(newAmount);\n }\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) public payable {\n _incrementDeposit(account, msg.value);\n DepositInfo storage info = deposits[account];\n emit Deposited(account, info.deposit);\n }\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 unstakeDelaySec) public payable {\n DepositInfo storage info = deposits[msg.sender];\n require(unstakeDelaySec > 0, \"must specify unstake delay\");\n require(\n unstakeDelaySec >= info.unstakeDelaySec,\n \"cannot decrease unstake time\"\n );\n uint256 stake = info.stake + msg.value;\n require(stake > 0, \"no stake specified\");\n require(stake <= type(uint112).max, \"stake overflow\");\n deposits[msg.sender] = DepositInfo(\n info.deposit,\n true,\n uint112(stake),\n unstakeDelaySec,\n 0\n );\n emit StakeLocked(msg.sender, stake, unstakeDelaySec);\n }\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external {\n DepositInfo storage info = deposits[msg.sender];\n require(info.unstakeDelaySec != 0, \"not staked\");\n require(info.staked, \"already unstaking\");\n uint48 withdrawTime = uint48(block.timestamp) + info.unstakeDelaySec;\n info.withdrawTime = withdrawTime;\n info.staked = false;\n emit StakeUnlocked(msg.sender, withdrawTime);\n }\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external {\n DepositInfo storage info = deposits[msg.sender];\n uint256 stake = info.stake;\n require(stake > 0, \"No stake to withdraw\");\n require(info.withdrawTime > 0, \"must call unlockStake() first\");\n require(\n info.withdrawTime <= block.timestamp,\n \"Stake withdrawal is not due\"\n );\n info.unstakeDelaySec = 0;\n info.withdrawTime = 0;\n info.stake = 0;\n emit StakeWithdrawn(msg.sender, withdrawAddress, stake);\n (bool success, ) = withdrawAddress.call{value: stake}(\"\");\n require(success, \"failed to withdraw stake\");\n }\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(\n address payable withdrawAddress,\n uint256 withdrawAmount\n ) external {\n DepositInfo storage info = deposits[msg.sender];\n require(withdrawAmount <= info.deposit, \"Withdraw amount too large\");\n info.deposit = uint112(info.deposit - withdrawAmount);\n emit Withdrawn(msg.sender, withdrawAddress, withdrawAmount);\n (bool success, ) = withdrawAddress.call{value: withdrawAmount}(\"\");\n require(success, \"failed to withdraw\");\n }\n}\n" + }, + "contracts/aa-4337/interfaces/IAccount.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\ninterface IAccount {\n /**\n * Validate user's signature and nonce\n * the entryPoint will make the call to the recipient only if this validation call returns successfully.\n * signature failure should be reported by returning SIG_VALIDATION_FAILED (1).\n * This allows making a \"simulation call\" without a valid signature\n * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure.\n *\n * @dev Must validate caller is the entryPoint.\n * Must validate the signature and nonce\n * @param userOp the operation that is about to be executed.\n * @param userOpHash hash of the user's request data. can be used as the basis for signature.\n * @param missingAccountFunds missing funds on the account's deposit in the entrypoint.\n * This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call.\n * The excess is left as a deposit in the entrypoint, for future calls.\n * can be withdrawn anytime using \"entryPoint.withdrawTo()\"\n * In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero.\n * @return validationData packaged ValidationData structure. use `_packValidationData` and `_unpackValidationData` to encode and decode\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * If an account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validateUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 missingAccountFunds\n ) external returns (uint256 validationData);\n}\n" + }, + "contracts/aa-4337/interfaces/IAggregator.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * Aggregated Signatures validator.\n */\ninterface IAggregator {\n /**\n * validate aggregated signature.\n * revert if the aggregated signature does not match the given list of operations.\n */\n function validateSignatures(\n UserOperation[] calldata userOps,\n bytes calldata signature\n ) external view;\n\n /**\n * validate signature of a single userOp\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\n * @param userOp the userOperation received from the user.\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\n * (usually empty, unless account and aggregator support some kind of \"multisig\"\n */\n function validateUserOpSignature(\n UserOperation calldata userOp\n ) external view returns (bytes memory sigForUserOp);\n\n /**\n * aggregate multiple signatures into a single value.\n * This method is called off-chain to calculate the signature to pass with handleOps()\n * bundler MAY use optimized custom code perform this aggregation\n * @param userOps array of UserOperations to collect the signatures from.\n * @return aggregatedSignature the aggregated signature\n */\n function aggregateSignatures(\n UserOperation[] calldata userOps\n ) external view returns (bytes memory aggregatedSignature);\n}\n" + }, + "contracts/aa-4337/interfaces/IEntryPoint.sol": { + "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n/* solhint-disable reason-string */\n\nimport \"./UserOperation.sol\";\nimport \"./IStakeManager.sol\";\nimport \"./IAggregator.sol\";\nimport \"./INonceManager.sol\";\n\ninterface IEntryPoint is IStakeManager, INonceManager {\n /***\n * An event emitted after each successful request\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\n * @param sender - the account that generates this request.\n * @param paymaster - if non-null, the paymaster that pays for this request.\n * @param nonce - the nonce value from the request.\n * @param success - true if the sender transaction succeeded, false if reverted.\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\n */\n event UserOperationEvent(\n bytes32 indexed userOpHash,\n address indexed sender,\n address indexed paymaster,\n uint256 nonce,\n bool success,\n uint256 actualGasCost,\n uint256 actualGasUsed\n );\n\n /**\n * account \"sender\" was deployed.\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\n * @param sender the account that is deployed\n * @param factory the factory used to deploy this account (in the initCode)\n * @param paymaster the paymaster used by this UserOp\n */\n event AccountDeployed(\n bytes32 indexed userOpHash,\n address indexed sender,\n address factory,\n address paymaster\n );\n\n /**\n * An event emitted if the UserOperation \"callData\" reverted with non-zero length\n * @param userOpHash the request unique identifier.\n * @param sender the sender of this request\n * @param nonce the nonce used in the request\n * @param revertReason - the return bytes from the (reverted) call to \"callData\".\n */\n event UserOperationRevertReason(\n bytes32 indexed userOpHash,\n address indexed sender,\n uint256 nonce,\n bytes revertReason\n );\n\n /**\n * an event emitted by handleOps(), before starting the execution loop.\n * any event emitted before this event, is part of the validation.\n */\n event BeforeExecution();\n\n /**\n * signature aggregator used by the following UserOperationEvents within this bundle.\n */\n event SignatureAggregatorChanged(address indexed aggregator);\n\n /**\n * a custom revert error of handleOps, to identify the offending op.\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\n * @param reason - revert reason\n * The string starts with a unique code \"AAmn\", where \"m\" is \"1\" for factory, \"2\" for account and \"3\" for paymaster issues,\n * so a failure can be attributed to the correct entity.\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\n */\n error FailedOp(uint256 opIndex, string reason);\n\n /**\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\n */\n error SignatureValidationFailed(address aggregator);\n\n /**\n * Successful result from simulateValidation.\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n */\n error ValidationResult(\n ReturnInfo returnInfo,\n StakeInfo senderInfo,\n StakeInfo factoryInfo,\n StakeInfo paymasterInfo\n );\n\n /**\n * Successful result from simulateValidation, if the account returns a signature aggregator\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\n * bundler MUST use it to verify the signature, or reject the UserOperation\n */\n error ValidationResultWithAggregation(\n ReturnInfo returnInfo,\n StakeInfo senderInfo,\n StakeInfo factoryInfo,\n StakeInfo paymasterInfo,\n AggregatorStakeInfo aggregatorInfo\n );\n\n /**\n * return value of getSenderAddress\n */\n error SenderAddressResult(address sender);\n\n /**\n * return value of simulateHandleOp\n */\n error ExecutionResult(\n uint256 preOpGas,\n uint256 paid,\n uint48 validAfter,\n uint48 validUntil,\n bool targetSuccess,\n bytes targetResult\n );\n\n //UserOps handled, per aggregator\n struct UserOpsPerAggregator {\n UserOperation[] userOps;\n // aggregator address\n IAggregator aggregator;\n // aggregated signature\n bytes signature;\n }\n\n /**\n * Execute a batch of UserOperation.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(\n UserOperation[] calldata ops,\n address payable beneficiary\n ) external;\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) external;\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(\n UserOperation calldata userOp\n ) external view returns (bytes32);\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external;\n\n /**\n * gas and return values during simulation\n * @param preOpGas the gas used for validation (including preValidationGas)\n * @param prefund the required prefund for this operation\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\n */\n struct ReturnInfo {\n uint256 preOpGas;\n uint256 prefund;\n bool sigFailed;\n uint48 validAfter;\n uint48 validUntil;\n bytes paymasterContext;\n }\n\n /**\n * returned aggregated signature info.\n * the aggregator returned by the account, and its current stake.\n */\n struct AggregatorStakeInfo {\n address aggregator;\n StakeInfo stakeInfo;\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes memory initCode) external;\n\n /**\n * simulate full execution of a UserOperation (including both validation and target execution)\n * this method will always revert with \"ExecutionResult\".\n * it performs full validation of the UserOperation, but ignores signature error.\n * an optional target address is called after the userop succeeds, and its value is returned\n * (before the entire call is reverted)\n * Note that in order to collect the the success/failure of the target call, it must be executed\n * with trace enabled to track the emitted events.\n * @param op the UserOperation to simulate\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\n * are set to the return from that call.\n * @param targetCallData callData to pass to target address\n */\n function simulateHandleOp(\n UserOperation calldata op,\n address target,\n bytes calldata targetCallData\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/INonceManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\ninterface INonceManager {\n /**\n * Return the next nonce for this sender.\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\n * But UserOp with different keys can come with arbitrary order.\n *\n * @param sender the account address\n * @param key the high 192 bit of the nonce\n * @return nonce a full nonce to pass for next UserOp with this sender.\n */\n function getNonce(\n address sender,\n uint192 key\n ) external view returns (uint256 nonce);\n\n /**\n * Manually increment the nonce of the sender.\n * This method is exposed just for completeness..\n * Account does NOT need to call it, neither during validation, nor elsewhere,\n * as the EntryPoint will update the nonce regardless.\n * Possible use-case is call it with various keys to \"initialize\" their nonces to one, so that future\n * UserOperations will not pay extra for the first transaction with a given key.\n */\n function incrementNonce(uint192 key) external;\n}\n" + }, + "contracts/aa-4337/interfaces/IPaymaster.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * the interface exposed by a paymaster contract, who agrees to pay the gas for user's operations.\n * a paymaster must hold a stake to cover the required entrypoint stake and also the gas for the transaction.\n */\ninterface IPaymaster {\n enum PostOpMode {\n opSucceeded, // user op succeeded\n opReverted, // user op reverted. still has to pay for gas.\n postOpReverted //user op succeeded, but caused postOp to revert. Now it's a 2nd call, after user's op was deliberately reverted.\n }\n\n /**\n * payment validation: check if paymaster agrees to pay.\n * Must verify sender is the entryPoint.\n * Revert to reject this request.\n * Note that bundlers will reject this method if it changes the state, unless the paymaster is trusted (whitelisted)\n * The paymaster pre-pays using its deposit, and receive back a refund after the postOp method returns.\n * @param userOp the user operation\n * @param userOpHash hash of the user's request data.\n * @param maxCost the maximum cost of this transaction (based on maximum gas and gas price from userOp)\n * @return context value to send to a postOp\n * zero length to signify postOp is not required.\n * @return validationData signature and time-range of this operation, encoded the same as the return value of validateUserOperation\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validatePaymasterUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 maxCost\n ) external returns (bytes memory context, uint256 validationData);\n\n /**\n * post-operation handler.\n * Must verify sender is the entryPoint\n * @param mode enum with the following options:\n * opSucceeded - user operation succeeded.\n * opReverted - user op reverted. still has to pay for gas.\n * postOpReverted - user op succeeded, but caused postOp (in mode=opSucceeded) to revert.\n * Now this is the 2nd call, after user's op was deliberately reverted.\n * @param context - the context value returned by validatePaymasterUserOp\n * @param actualGasCost - actual gas used so far (without this postOp call).\n */\n function postOp(\n PostOpMode mode,\n bytes calldata context,\n uint256 actualGasCost\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/IStakeManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.12;\n\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by the staked entity.\n */\ninterface IStakeManager {\n event Deposited(address indexed account, uint256 totalDeposit);\n\n event Withdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /// Emitted when stake or unstake delay are modified\n event StakeLocked(\n address indexed account,\n uint256 totalStaked,\n uint256 unstakeDelaySec\n );\n\n /// Emitted once a stake is scheduled for withdrawal\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\n\n event StakeWithdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /**\n * @param deposit the entity's deposit\n * @param staked true if this entity is staked.\n * @param stake actual amount of ether staked for this entity.\n * @param unstakeDelaySec minimum delay to withdraw the stake.\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\n * and the rest fit into a 2nd cell.\n * 112 bit allows for 10^15 eth\n * 48 bit for full timestamp\n * 32 bit allows 150 years for unstake delay\n */\n struct DepositInfo {\n uint112 deposit;\n bool staked;\n uint112 stake;\n uint32 unstakeDelaySec;\n uint48 withdrawTime;\n }\n\n //API struct used by getStakeInfo and simulateValidation\n struct StakeInfo {\n uint256 stake;\n uint256 unstakeDelaySec;\n }\n\n /// @return info - full deposit information of given account\n function getDepositInfo(\n address account\n ) external view returns (DepositInfo memory info);\n\n /// @return the deposit (for gas payment) of the account\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) external payable;\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 _unstakeDelaySec) external payable;\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external;\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external;\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(\n address payable withdrawAddress,\n uint256 withdrawAmount\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/UserOperation.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable no-inline-assembly */\n\nimport {calldataKeccak} from \"../core/Helpers.sol\";\n\n/**\n * User Operation struct\n * @param sender the sender account of this request.\n * @param nonce unique value the sender uses to verify it is not a replay.\n * @param initCode if set, the account contract will be created by this constructor/\n * @param callData the method call to execute on this account.\n * @param callGasLimit the gas limit passed to the callData method call.\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\n * @param maxFeePerGas same as EIP-1559 gas parameter.\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\n */\nstruct UserOperation {\n address sender;\n uint256 nonce;\n bytes initCode;\n bytes callData;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n bytes paymasterAndData;\n bytes signature;\n}\n\n/**\n * Utility functions helpful when working with UserOperation structs.\n */\nlibrary UserOperationLib {\n function getSender(\n UserOperation calldata userOp\n ) internal pure returns (address) {\n address data;\n //read sender from userOp, which is first userOp member (saves 800 gas...)\n assembly {\n data := calldataload(userOp)\n }\n return address(uint160(data));\n }\n\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\n // pay above what he signed for.\n function gasPrice(\n UserOperation calldata userOp\n ) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function pack(\n UserOperation calldata userOp\n ) internal pure returns (bytes memory ret) {\n address sender = getSender(userOp);\n uint256 nonce = userOp.nonce;\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\n bytes32 hashCallData = calldataKeccak(userOp.callData);\n uint256 callGasLimit = userOp.callGasLimit;\n uint256 verificationGasLimit = userOp.verificationGasLimit;\n uint256 preVerificationGas = userOp.preVerificationGas;\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\n\n return\n abi.encode(\n sender,\n nonce,\n hashInitCode,\n hashCallData,\n callGasLimit,\n verificationGasLimit,\n preVerificationGas,\n maxFeePerGas,\n maxPriorityFeePerGas,\n hashPaymasterAndData\n );\n }\n\n function hash(\n UserOperation calldata userOp\n ) internal pure returns (bytes32) {\n return keccak256(pack(userOp));\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n}\n" + }, + "contracts/aa-4337/utils/Exec.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.5 <0.9.0;\n\n// solhint-disable no-inline-assembly\n\n/**\n * Utility functions helpful when making different kinds of contract calls in Solidity.\n */\nlibrary Exec {\n function call(\n address to,\n uint256 value,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := call(\n txGas,\n to,\n value,\n add(data, 0x20),\n mload(data),\n 0,\n 0\n )\n }\n }\n\n function staticcall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal view returns (bool success) {\n assembly {\n success := staticcall(txGas, to, add(data, 0x20), mload(data), 0, 0)\n }\n }\n\n function delegateCall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := delegatecall(\n txGas,\n to,\n add(data, 0x20),\n mload(data),\n 0,\n 0\n )\n }\n }\n\n // get returned data from last call or calldelegate\n function getReturnData(\n uint256 maxLen\n ) internal pure returns (bytes memory returnData) {\n assembly {\n let len := returndatasize()\n if gt(len, maxLen) {\n len := maxLen\n }\n let ptr := mload(0x40)\n mstore(0x40, add(ptr, add(len, 0x20)))\n mstore(ptr, len)\n returndatacopy(add(ptr, 0x20), 0, len)\n returnData := ptr\n }\n }\n\n // revert with explicit byte array (probably reverted info from call)\n function revertWithData(bytes memory returnData) internal pure {\n assembly {\n revert(add(returnData, 32), mload(returnData))\n }\n }\n\n function callAndRevert(\n address to,\n bytes memory data,\n uint256 maxLen\n ) internal {\n bool success = call(to, 0, data, gasleft());\n if (!success) {\n revertWithData(getReturnData(maxLen));\n }\n }\n}\n" + }, + "contracts/Barz.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"./libraries/LibDiamond.sol\";\nimport {IBarz} from \"./interfaces/IBarz.sol\";\n\n/**\n * @title Barz\n * @dev A diamond proxy wallet with a modular & upgradeable architecture\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract Barz is IBarz {\n /**\n * @notice Initializes Barz with the given parameters. Barz account is intended to be created from Barz Factory for stable deployment.\n * @dev This method makes a delegate call to account facet and account facet handles the initialization.\n * With modular architecture, Barz encompasses wide spectrum of architecture and logic.\n * The only requirement is account facet to comply with initialize() interface.\n * Barz doesn't include built-in functions and is a full proxy, for maximum extensibility and modularity.\n * @param _accountFacet Address of Account Facet in charge of the Barz initialization\n * @param _verificationFacet Address of Verification Facet for verifying the signature. Could be any signature scheme\n * @param _entryPoint Address of Entry Point contract\n * @param _facetRegistry Address of Facet Registry. Facet Registry is a registry holding trusted facets that could be added to user's wallet\n * @param _defaultFallBack Address of Default FallBack Handler. Middleware contract for more efficient deployment\n * @param _ownerPublicKey Bytes of Owner Public Key using for initialization\n */\n constructor(\n address _accountFacet,\n address _verificationFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallBack,\n bytes memory _ownerPublicKey\n ) payable {\n bytes memory initCall = abi.encodeWithSignature(\n \"initialize(address,address,address,address,bytes)\",\n _verificationFacet,\n _entryPoint,\n _facetRegistry,\n _defaultFallBack,\n _ownerPublicKey\n );\n (bool success, bytes memory result) = _accountFacet.delegatecall(\n initCall\n );\n if (!success || uint256(bytes32(result)) != 1) {\n revert Barz__InitializationFailure();\n }\n }\n\n /**\n * @notice Fallback function for Barz complying with Diamond Standard with customization of adding Default Fallback Handler\n * @dev Find facet for function that is called and execute the function if a facet is found and return any value.\n */\n fallback() external payable {\n LibDiamond.DiamondStorage storage ds;\n bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION;\n // get diamond storage\n assembly {\n ds.slot := position\n }\n // get facet from function selector\n address facet = address(bytes20(ds.facets[msg.sig]));\n if (facet == address(0))\n facet = ds.defaultFallbackHandler.facetAddress(msg.sig);\n require(facet != address(0), \"Barz: Function does not exist\");\n // Execute external function from facet using delegatecall and return any value.\n assembly {\n // copy function selector and any arguments\n calldatacopy(0, 0, calldatasize())\n // execute function call using the facet\n let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)\n // get any return value\n returndatacopy(0, 0, returndatasize())\n // return any return value or error back to the caller\n switch result\n case 0 {\n revert(0, returndatasize())\n }\n default {\n return(0, returndatasize())\n }\n }\n }\n\n /**\n * @notice Receive function to receive native token without data\n */\n receive() external payable {}\n}\n" + }, + "contracts/BarzFactory.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Barz} from \"./Barz.sol\";\nimport {IBarzFactory} from \"./interfaces/IBarzFactory.sol\";\n\n/**\n * @title Barz Factory\n * @dev Contract to easily deploy Barz to a pre-computed address with a single call\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract BarzFactory is IBarzFactory {\n event BarzDeployed(address);\n\n address public immutable accountFacet;\n address public immutable entryPoint;\n address public immutable facetRegistry;\n address public immutable defaultFallback;\n\n /**\n * @notice Sets the initialization data for Barz contract initialization\n * @param _accountFacet Account Facet to be used to create Barz\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\n * @param _facetRegistry Facet Registry to be used to create Barz\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\n */\n constructor(\n address _accountFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallback\n ) {\n accountFacet = _accountFacet;\n entryPoint = _entryPoint;\n facetRegistry = _facetRegistry;\n defaultFallback = _defaultFallback;\n }\n\n /**\n * @notice Creates the Barz with a single call. It creates the Barz contract with the givent verification facet\n * @param _verificationFacet Address of verification facet used for creating the barz account\n * @param _owner Public Key of the owner to initialize barz account\n * @param _salt Salt used for deploying barz with create2\n * @return barz Instance of Barz contract deployed with the given parameters\n */\n function createAccount(\n address _verificationFacet,\n bytes calldata _owner,\n uint256 _salt\n ) external override returns (Barz barz) {\n address addr = getAddress(_verificationFacet, _owner, _salt);\n uint codeSize = addr.code.length;\n if (codeSize > 0) {\n return Barz(payable(addr));\n }\n barz = new Barz{salt: bytes32(_salt)}(\n accountFacet,\n _verificationFacet,\n entryPoint,\n facetRegistry,\n defaultFallback,\n _owner\n );\n emit BarzDeployed(address(barz));\n }\n\n /**\n * @notice Calculates the address of Barz with the given parameters\n * @param _verificationFacet Address of verification facet used for creating the barz account\n * @param _owner Public Key of the owner to initialize barz account\n * @param _salt Salt used for deploying barz with create2\n * @return barzAddress Precalculated Barz address\n */\n function getAddress(\n address _verificationFacet,\n bytes calldata _owner,\n uint256 _salt\n ) public view override returns (address barzAddress) {\n bytes memory bytecode = getBytecode(\n accountFacet,\n _verificationFacet,\n entryPoint,\n facetRegistry,\n defaultFallback,\n _owner\n );\n bytes32 hash = keccak256(\n abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(bytecode)\n )\n );\n barzAddress = address(uint160(uint256(hash)));\n }\n\n /**\n * @notice Returns the bytecode of Barz with the given parameter\n * @param _accountFacet Account Facet to be used to create Barz\n * @param _verificationFacet Verification Facet to be used to create Barz\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\n * @param _facetRegistry Facet Registry to be used to create Barz\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\n * @param _ownerPublicKey Public Key of owner to be used to initialize Barz ownership\n * @return barzBytecode Bytecode of Barz\n */\n function getBytecode(\n address _accountFacet,\n address _verificationFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallback,\n bytes calldata _ownerPublicKey\n ) public pure override returns (bytes memory barzBytecode) {\n bytes memory bytecode = type(Barz).creationCode;\n barzBytecode = abi.encodePacked(\n bytecode,\n abi.encode(\n _accountFacet,\n _verificationFacet,\n _entryPoint,\n _facetRegistry,\n _defaultFallback,\n _ownerPublicKey\n )\n );\n }\n\n /**\n * @notice Returns the creation code of the Barz contract\n * @return creationCode Creation code of Barz\n */\n function getCreationCode()\n public\n pure\n override\n returns (bytes memory creationCode)\n {\n creationCode = type(Barz).creationCode;\n }\n}\n" + }, + "contracts/facets/AccountFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {UserOperation} from \"../aa-4337/interfaces/UserOperation.sol\";\nimport {IEntryPoint} from \"../aa-4337/interfaces/IEntryPoint.sol\";\nimport {BaseAccount} from \"../aa-4337/core/BaseAccount.sol\";\nimport {LibAppStorage, BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {IFacetRegistry} from \"../infrastructure/interfaces/IFacetRegistry.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {IERC1271} from \"../interfaces/ERC/IERC1271.sol\";\nimport {IAccountFacet} from \"./interfaces/IAccountFacet.sol\";\n\n/**\n * @title Account Facet\n * @dev Account module contract that provides the account features and initialization of signer\n * compatible with EIP-1271 & EIP-4337\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract AccountFacet is BarzStorage, BaseAccount, IAccountFacet {\n using ECDSA for bytes32;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceAccountInitialize();\n }\n\n /**\n * @notice Returns the address of EntryPoint contract registered to Barz account\n */\n function entryPoint() public view override returns (IEntryPoint) {\n return s.entryPoint;\n }\n\n /**\n * @notice Initializes the initial storage of the Barz contract.\n * @dev This method can only be called during the initialization or signature migration.\n * If the proxy contract was created without initialization, anyone can call initialize.\n * Barz calls initialize in constructor in an atomic transaction during deployment\n * @param _verificationFacet Facet contract handling the verificationi\n * @param _anEntryPoint Entrypoint contract defined in EIP-4337 handling the flow of UserOp\n * @param _facetRegistry Registry of Facets that hold all facet information\n * @param _defaultFallBackHandler Middleware contract for default facets\n * @param _ownerPublicKey Bytes of owner public key\n */\n function initialize(\n address _verificationFacet,\n address _anEntryPoint,\n address _facetRegistry,\n address _defaultFallBackHandler,\n bytes calldata _ownerPublicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceAccountInitialize();\n s.entryPoint = IEntryPoint(_anEntryPoint);\n s.facetRegistry = IFacetRegistry(_facetRegistry);\n LibDiamond.diamondStorage().defaultFallbackHandler = IDiamondLoupe(\n _defaultFallBackHandler\n );\n\n _cutDiamondAccountFacet(_verificationFacet);\n\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n _ownerPublicKey\n );\n // Every Verification Facet should comply with initializeSigner(bytes)\n // to be compatible with the Barz contract(for initialization)\n (bool success, bytes memory result) = _verificationFacet.delegatecall(\n initCall\n );\n if (!success || uint256(bytes32(result)) != 1) {\n revert AccountFacet__InitializationFailure();\n }\n\n initSuccess = 1;\n emit AccountInitialized(s.entryPoint, _ownerPublicKey);\n }\n\n function _cutDiamondAccountFacet(address _verificationFacet) internal {\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](1);\n\n bytes4 ownerVerificationFuncSelector = IVerificationFacet(\n _verificationFacet\n ).validateOwnerSignatureSelector();\n\n bytes4[] memory verificationFunctionSelectors = new bytes4[](3);\n verificationFunctionSelectors[0] = IERC1271.isValidSignature.selector;\n verificationFunctionSelectors[1] = ownerVerificationFuncSelector;\n verificationFunctionSelectors[2] = IVerificationFacet.owner.selector;\n cut[0] = IDiamondCut.FacetCut({\n facetAddress: _verificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: verificationFunctionSelectors\n });\n\n LibDiamond.diamondCut(cut, address(0), \"\");\n }\n\n /**\n * @notice Calls the destination with inputted calldata and value from EntryPoint\n * @dev This method executes the calldata coming from the EntryPoint.\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\n * @param _dest Address of destination where the call will be forwarded to\n * @param _value Amount of native coin the owner is willing to send(e.g. ETH, BNB)\n * @param _func Bytes of calldata to execute in the destination address\n */\n function execute(\n address _dest,\n uint256 _value,\n bytes calldata _func\n ) external override onlyWhenUnlocked {\n _requireFromEntryPoint();\n _call(_dest, _value, _func);\n }\n\n /**\n * @notice Batch calls the destination with inputted calldata and value from EntryPoint\n * @dev This method batch executes the calldata coming from the EntryPoint.\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\n * @param _dest Array of addresses of destination where the call will be forwarded to\n * @param _value Array of amount of native coin the owner is willing to send(e.g. ETH, BNB)\n * @param _func Array of bytes of calldata to execute in the destination address\n */\n function executeBatch(\n address[] calldata _dest,\n uint256[] calldata _value,\n bytes[] calldata _func\n ) external override onlyWhenUnlocked {\n _requireFromEntryPoint();\n uint256 destLength = _dest.length;\n require(\n destLength == _func.length && destLength == _value.length,\n \"wrong array lengths\"\n );\n for (uint256 i; i < destLength; ) {\n _call(_dest[i], _value[i], _func[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Validates the signature field of UserOperation\n * @dev This method validates if the signature of UserOp is indeed valid by delegating the call to Verification Facet\n * Barz makes a call to the pre-registered Verification Facet address in App Storage\n * @param _userOp UserOperation from owner to be validated\n * @param _userOpHash Hash of UserOperation given from the EntryPoint contract\n */\n function _validateSignature(\n UserOperation calldata _userOp,\n bytes32 _userOpHash\n ) internal override returns (uint256 validationData) {\n // Get Facet with Function Selector\n address facet = LibLoupe.facetAddress(s.validateOwnerSignatureSelector);\n if (facet == address(0))\n revert AccountFacet__NonExistentVerificationFacet();\n\n // Make function call to VerificationFacet\n bytes memory validateCall = abi.encodeWithSelector(\n s.validateOwnerSignatureSelector,\n _userOp,\n _userOpHash\n );\n (bool success, bytes memory result) = facet.delegatecall(validateCall);\n if (!success) revert AccountFacet__CallNotSuccessful();\n validationData = uint256(bytes32(result));\n if (validationData == 0) emit VerificationSuccess(_userOpHash);\n else emit VerificationFailure(_userOpHash);\n }\n\n /**\n * @notice Calls the target with the inputted value and calldata\n * @dev This method is the actual function in Barz that makes a call with an arbitrary owner-given data\n * @param _target Address of the destination contract which the call is getting forwarded to\n * @param _value Amount of Native coin the owner is wanting to make in this call\n * @param _data Calldata the owner is forwarding together in the call e.g. Swap/Token Transfer\n */\n function _call(\n address _target,\n uint256 _value,\n bytes memory _data\n ) internal {\n if (_checkRestrictions(_target, _value, _data) == 1)\n revert AccountFacet__RestrictionsFailure();\n\n (bool success, bytes memory result) = _target.call{value: _value}(\n _data\n );\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n }\n\n /**\n * @notice Checks restrictions if the restrictions facet exists\n * @dev This method checks if the restrictions facet exists and makes a verification call to an array of restrictions facet\n * @param _target Address the call is getting forwarded to\n * @param _value Amount of native coin the call is sending together with the call\n * @param _data Calldata to trigger execution in target address\n */\n function _checkRestrictions(\n address _target,\n uint256 _value,\n bytes memory _data\n ) internal returns (uint256 result) {\n address facet = LibDiamond.restrictionsFacet();\n // NOTE: No restrictions facet, so restriction validation passes\n if (facet == address(0)) return 0;\n bytes memory call = abi.encodeWithSignature(\n \"verifyRestrictions(address,address,uint256,bytes)\",\n address(this),\n _target,\n _value,\n _data\n );\n (bool success, bytes memory response) = facet.delegatecall(call);\n if (!success) revert AccountFacet__RestrictionsFailure();\n result = uint256(bytes32(response));\n }\n}\n" + }, + "contracts/facets/AccountRecoveryFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibFacetStorage, RecoveryStorage, RecoveryConfig, RecoveryApprovalConfig, ApprovalConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {IAccountRecoveryFacet} from \"./interfaces/IAccountRecoveryFacet.sol\";\n\n/**\n * @title Account Recovery Facet\n * @dev Contract that enables recovery of accounts when owner key is unavailable\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract AccountRecoveryFacet is IAccountRecoveryFacet, Modifiers {\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Approve recovery of account as guardian\n * @dev This method can only be called by guardian and guardian inputs the public key of the new owner\n * When the threshold(majority of guardians) passes, it automatically executes account recovery\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function approveAccountRecovery(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + _getApprovalValidationPeriod()\n );\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit RecoveryApproved(\n _recoveryPublicKey,\n msg.sender,\n approvalValidUntil\n );\n if (\n getRecoveryApprovalCountWithTimeValidity(recoveryPublicKeyHash) >=\n LibGuardian.majorityOfGuardians()\n ) _executeRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Revoke recovery of account as guardian\n * @dev This method can only be called by guardian and guardian inputs the public key of the new owner\n When the threshold(majority of guardians) passes, it automatically revokes account recovery when recovery is pending\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function revokeAccountRecoveryApproval(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n if (\n !rs\n .isNewOwnerApproved[recoveryPublicKeyHash][msg.sender].isApproved ||\n !(block.timestamp <\n rs\n .isNewOwnerApproved[recoveryPublicKeyHash][msg.sender]\n .validUntil)\n ) revert AccountRecoveryFacet__NonExistentApproval();\n\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(false, 0);\n emit RecoveryApprovalRevoked(_recoveryPublicKey, msg.sender);\n }\n\n /**\n * @notice Executes recovery with signatures or on-chain pre-approvals\n * @dev This method validates the signatures of guardians or checks the on-chain pre-approved calls to check if the threshold passes\n * When the threshold passes, account recovery is executed and revert otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _guardians Array of guardians address that are approving the recovery of Account\n * @param _signatures Array of signature bytes that signed the approval hash\n */\n function executeRecovery(\n bytes calldata _recoveryPublicKey,\n address[] calldata _guardians,\n bytes[] calldata _signatures\n ) external override {\n if (_isRecoveryPending())\n revert AccountRecoveryFacet__RecoveryAlreadyOngoing();\n uint256 guardiansLength = _guardians.length;\n if (guardiansLength != _signatures.length)\n revert AccountRecoveryFacet__InvalidArrayLength();\n validateNewOwner(_recoveryPublicKey);\n\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n\n _checkApprover(_guardians);\n _checkDuplicateOnChainApprover(recoveryPublicKeyHash, _guardians);\n\n if (\n guardiansLength +\n getRecoveryApprovalCountWithTimeValidity(\n recoveryPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians()\n ) revert AccountRecoveryFacet__InsufficientGuardians();\n for (uint256 i; i < guardiansLength; ) {\n if (!LibGuardian.isGuardian(_guardians[i]))\n revert AccountRecoveryFacet__InvalidGuardian();\n if (\n !SignatureChecker.isValidSignatureNow(\n _guardians[i],\n recoveryPublicKeyHash,\n _signatures[i]\n )\n ) revert AccountRecoveryFacet__InvalidGuardianSignature();\n unchecked {\n ++i;\n }\n }\n _executeRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Executes recovery of the account. Note that execution and finalization is a different process\n * @dev Executes the recovery and adds recovery data to recovery configuration. Locks the account\n * @param _recoveryPublicKey Public Key of the account for recovery\n */\n function _executeRecovery(bytes memory _recoveryPublicKey) internal {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n ++rs.nonce;\n uint64 executeAfter = uint64(block.timestamp + _getRecoveryPeriod());\n rs.recoveryConfigs[INNER_STRUCT] = RecoveryConfig(\n _recoveryPublicKey,\n executeAfter // NOTE: Remove guardian Count\n );\n LibAppStorage.setLock(\n block.timestamp + _getLockPeriod(),\n AccountRecoveryFacet.executeRecovery.selector\n );\n emit RecoveryExecuted(_recoveryPublicKey, executeAfter);\n }\n\n /**\n * @notice Finalize recovery after recovery pending period. Recovery pending period can be set by user beforehand in SecurityManager\n * @dev This method finalizes recovery and fully changes the ownership of the account to the newly inputted recovery public key\n */\n function finalizeRecovery() external override {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n if (\n uint64(block.timestamp) <=\n rs.recoveryConfigs[INNER_STRUCT].executeAfter\n ) revert AccountRecoveryFacet__RecoveryPeriodNotOver();\n bytes memory recoveryOwner = rs\n .recoveryConfigs[INNER_STRUCT]\n .recoveryPublicKey;\n\n delete rs.recoveryConfigs[INNER_STRUCT];\n\n LibAppStorage.setLock(0, bytes4(0));\n\n LibAppStorage.initiateSignerMigration();\n address verificationFacet = address(\n bytes20(\n LibDiamond.diamondStorage().facets[\n s.validateOwnerSignatureSelector\n ]\n )\n );\n bytes memory uninitCall = abi.encodeWithSignature(\n \"uninitializeSigner()\"\n );\n (bool success, bytes memory result) = verificationFacet.delegatecall(\n uninitCall\n );\n if (!success) revert AccountRecoveryFacet__CallNotSuccesful();\n uint256 validationData = uint256(bytes32(result));\n if (validationData != 1)\n revert AccountRecoveryFacet__SignerUninitializationFailure();\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n recoveryOwner\n );\n (success, result) = verificationFacet.delegatecall(initCall);\n if (!success) revert AccountRecoveryFacet__CallNotSuccesful();\n validationData = uint256(bytes32(result));\n if (validationData != 1)\n revert AccountRecoveryFacet__SignerInitializationFailure();\n LibAppStorage.finalizeSignerMigration();\n emit RecoveryFinalized(recoveryOwner);\n }\n\n /**\n * @notice Approves the cancellation of recovery\n * @dev This method approves the cancellation of recovery when recovery is still pending - waiting for finalization\n * @param _recoveryPublicKey Bytes of public key which is pending for recovery\n */\n function approveCancelRecovery(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"CancelRecovery\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + _getApprovalValidationPeriod()\n );\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit RecoveryCancellationApproved(_recoveryPublicKey, msg.sender);\n if (\n getRecoveryApprovalCountWithTimeValidity(recoveryPublicKeyHash) >=\n LibGuardian.majorityOfGuardians()\n ) {\n _cancelRecovery(_recoveryPublicKey);\n }\n }\n\n /**\n * @notice Hardstops an ongoing recovery\n * @dev This method provides a safety mechanism to protect owners of malicious guardians.\n * Owners can hardstop recovery when an malicious guardians starts the recovery process.\n * @param _signature Signature of the owner that signs the hash to hardstop recovery\n */\n function hardstopRecovery(bytes calldata _signature) external override {\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n \"0\",\n \"HardstopRecovery\"\n );\n if (\n !SignatureChecker.isValidSignatureNow(\n address(this),\n recoveryPublicKeyHash,\n _signature\n )\n ) revert AccountRecoveryFacet__InvalidOwnerSignature();\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n ++rs.nonce;\n delete rs.recoveryConfigs[INNER_STRUCT];\n LibAppStorage.setLock(0, bytes4(0));\n emit RecoveryHardstopped();\n }\n\n /**\n * @notice Cancels recovery with signatures or on-chain pre-approvals\n * @dev This method validates the signatures of guardians or checks the on-chain pre-approved calls to check if the threshold passes\n * When the threshold passes, account recovery is canceled and revert otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _guardians Array of guardians address that are approving the recovery of Account\n * @param _signatures Array of signature bytes that signed the cancellation approval hash\n */\n function cancelRecovery(\n bytes calldata _recoveryPublicKey,\n address[] calldata _guardians,\n bytes[] calldata _signatures\n ) external override {\n uint256 guardiansLength = _guardians.length;\n if (guardiansLength != _signatures.length)\n revert AccountRecoveryFacet__InvalidArrayLength();\n validateNewOwner(_recoveryPublicKey);\n\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"CancelRecovery\"\n );\n\n _checkApprover(_guardians);\n _checkDuplicateOnChainApprover(recoveryPublicKeyHash, _guardians);\n\n if (\n guardiansLength +\n getRecoveryApprovalCountWithTimeValidity(\n recoveryPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians()\n ) revert AccountRecoveryFacet__InsufficientGuardians();\n for (uint256 i; i < guardiansLength; ) {\n if (!LibGuardian.isGuardian(_guardians[i]))\n revert AccountRecoveryFacet__CallerNotGuardian();\n if (\n !SignatureChecker.isValidSignatureNow(\n _guardians[i],\n recoveryPublicKeyHash,\n _signatures[i]\n )\n ) revert AccountRecoveryFacet__InvalidGuardianSignature();\n unchecked {\n ++i;\n }\n }\n _cancelRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Cancel recovery when the recovery is pending. Unlock the account as well\n * @dev This method checks if the recovery is pending and reverts if not pending.\n * It increases the recovery nonce and deletes the recovery information and gets a small portion of gas in return\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function _cancelRecovery(bytes memory _recoveryPublicKey) internal {\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n LibAppStorage.setLock(0, bytes4(0));\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n ++rs.nonce;\n delete rs.recoveryConfigs[INNER_STRUCT];\n emit RecoveryCanceled(_recoveryPublicKey);\n }\n\n /**\n * @notice Validates the format of public key to be used for recovery\n * @dev This method checks if the public key format is correct and reverts otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function validateNewOwner(bytes memory _recoveryPublicKey) public view {\n if (\n !IVerificationFacet(\n LibLoupe.facetAddress(s.validateOwnerSignatureSelector)\n ).isValidKeyType(_recoveryPublicKey)\n ) revert AccountRecoveryFacet__InvalidRecoveryPublicKey();\n }\n\n /**\n * @notice Checks if recovery is currently pending\n * @return isPending Boolean indicating if recovery is pending\n */\n function _isRecoveryPending() internal view returns (bool isPending) {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n isPending = (rs.recoveryConfigs[INNER_STRUCT].executeAfter > 0);\n }\n\n /**\n * @notice Calculate the recovery hash dependent on chain, wallet address, nonce with EIP-191 prefix for safety\n * @dev Returns the keccak256 hash of EIP-191 msg hash packed with public key, salt, nonce, wallet address, etc\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _saltString Salt string to uniquely identify each recovery hash and for security\n * @return recoveryKeyHash Bytes32 string of the recovery hash\n */\n function getApprovalRecoveryKeyHash(\n bytes memory _recoveryPublicKey,\n string memory _saltString\n ) public view override returns (bytes32 recoveryKeyHash) {\n recoveryKeyHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n _recoveryPublicKey,\n _saltString,\n address(this),\n block.chainid,\n LibFacetStorage.recoveryStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Check the onchain approval of guardians and returns the number of guardians that approved\n * @dev Loop through the guardian addresses and returns the number of guardians that approved this recovery hash\n * @param _recoveryPublicKeyHash Bytes hash of newly recovered public key and recovery value of the account\n * @return approvalCount Number of guardians that approved\n */\n function getRecoveryApprovalCountWithTimeValidity(\n bytes32 _recoveryPublicKeyHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n for (uint256 i; i < guardianLength; ) {\n if (isRecoveryApproved(_recoveryPublicKeyHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Checks if the recovery is approved by the given approver\n * @param _recoveryPublicKeyHash Hash of the public key and configuration for recovery\n * @param _approver Address of approver\n * @return isApproved Bool value if recovery hash is approved\n */\n function isRecoveryApproved(\n bytes32 _recoveryPublicKeyHash,\n address _approver\n ) public view override returns (bool isApproved) {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n if (\n rs\n .isNewOwnerApproved[_recoveryPublicKeyHash][_approver].isApproved &&\n block.timestamp <\n rs.isNewOwnerApproved[_recoveryPublicKeyHash][_approver].validUntil\n ) {\n isApproved = true;\n }\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _recoveryPublicKeyHash Hash of recovery information\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _recoveryPublicKeyHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isRecoveryApproved(_recoveryPublicKeyHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert AccountRecoveryFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the lock period of this wallet address from security manager\n * @return lockPeriod value of lock period\n */\n function _getLockPeriod() internal view returns (uint256 lockPeriod) {\n lockPeriod = securityManager.lockPeriodOf(address(this));\n if (lockPeriod == 0) revert AccountRecoveryFacet__InvalidLockPeriod();\n }\n\n /**\n * @notice Returns the lock period of this wallet address from security manager\n * @return recoveryPeriod value of recovery period\n */\n function _getRecoveryPeriod()\n internal\n view\n returns (uint256 recoveryPeriod)\n {\n recoveryPeriod = securityManager.recoveryPeriodOf(address(this));\n if (recoveryPeriod == 0)\n revert AccountRecoveryFacet__InvalidRecoveryPeriod();\n }\n\n /**\n * @notice Returns the approval validation period of this wallet address from security manager\n * @return approvalValidationPeriod value of approval validation period\n */\n function _getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod == 0)\n revert AccountRecoveryFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the recovery nonce of this wallet address from security manager\n * @return nonce value of recovery nonce\n */\n function getRecoveryNonce() public view override returns (uint128 nonce) {\n nonce = LibFacetStorage.recoveryStorage().nonce;\n }\n\n /**\n * @notice Returns the recovery information of the pending recovery\n * @return recoveryConfig value struct of pending recovery\n */\n function getPendingRecovery()\n public\n view\n override\n returns (RecoveryConfig memory recoveryConfig)\n {\n recoveryConfig = LibFacetStorage.recoveryStorage().recoveryConfigs[\n INNER_STRUCT\n ];\n }\n}\n" + }, + "contracts/facets/base/DiamondCutFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibGuardian} from \"../../libraries/LibGuardian.sol\";\nimport {ISecurityManager} from \"../../infrastructure/interfaces/ISecurityManager.sol\";\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibFacetStorage, DiamondCutApprovalConfig, ApprovalConfig} from \"../../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"../Modifiers.sol\";\nimport {IDiamondCut} from \"./interfaces/IDiamondCut.sol\";\n\n/**\n * @title DiamondCut Facet\n * @dev Responsible for adding/removing/replace facets in Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DiamondCutFacet is Modifiers, IDiamondCut {\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Updates the flag for the interfaceId\n * @param _interfaceId InterfaceID to update the mapping\n * @param _flag Bool value to update the mapping of the given interface ID\n */\n function updateSupportsInterface(\n bytes4 _interfaceId,\n bool _flag\n ) external override onlyWhenUnlocked {\n LibDiamond.enforceIsSelf();\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId] = _flag;\n emit SupportsInterfaceUpdated(_interfaceId, _flag);\n }\n\n /**\n * @notice Add/replace/remove any number of functions and optionally execute\n * a function with delegatecall when guardians don't exist\n * @param _diamondCut Contains the facet addresses and function selectors\n * @param _init The address of the contract or facet to execute _calldata\n * @param _calldata A function call, including function selector and arguments\n * _calldata is executed with delegatecall on _init\n */\n function diamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) external override onlyWhenUnlocked {\n LibDiamond.enforceIsSelf();\n\n _checkFacetCutValidity(_diamondCut);\n // require approval from guardian if guardian exists\n if (0 != LibGuardian.guardianCount())\n revert DiamondCutFacet__InvalidRouteWithGuardian();\n\n ++LibFacetStorage.diamondCutStorage().nonce;\n LibDiamond.diamondCut(_diamondCut, _init, _calldata);\n }\n\n /**\n * @notice Add/replace/remove any number of functions and optionally execute\n * a function with delegatecall when guardians exist\n * @param _diamondCut Contains the facet addresses and function selectors\n * @param _init The address of the contract or facet to execute _calldata\n * @param _calldata A function call, including function selector and arguments\n * _calldata is executed with delegatecall on _init\n * @param _approvers Guardian or owner address that approves the diamond cut\n * @param _signatures Signature of Guardians or owner that approves the diamond cut\n */\n function diamondCutWithGuardian(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n ) external override onlyWhenUnlocked {\n uint256 approverLength = _approvers.length;\n if (approverLength != _signatures.length)\n revert DiamondCutFacet__InvalidArrayLength();\n _checkFacetCutValidity(_diamondCut);\n if (0 == LibGuardian.guardianCount())\n revert DiamondCutFacet__InvalidRouteWithGuardian();\n\n bytes32 cutHash = getDiamondCutHash(_diamondCut, _init, _calldata);\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(cutHash, _approvers);\n\n bool onChainOwnerApproval = getOwnerCutApprovalWithTimeValidity(\n cutHash\n );\n\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n if (\n approverLength +\n getDiamondCutApprovalCountWithTimeValidity(cutHash) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert DiamondCutFacet__InsufficientApprovers();\n\n bool ownerApproved;\n for (uint256 i; i < approverLength; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n _approvers[i] != address(this)\n ) revert DiamondCutFacet__InvalidApprover();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert DiamondCutFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n cutHash,\n _signatures[i]\n )\n ) revert DiamondCutFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n if (!ownerApproved && !onChainOwnerApproval)\n revert DiamondCutFacet__LackOfOwnerApproval();\n\n ++LibFacetStorage.diamondCutStorage().nonce;\n LibDiamond.diamondCut(_diamondCut, _init, _calldata);\n }\n\n /**\n * @notice Approves diamond cut. This can only be called directly from guardian or owner\n * @param _diamondCut Contains the facet addresses and function selectors\n * @param _init The address of the contract or facet to execute _calldata\n * @param _calldata A function call, including function selector and arguments\n * _calldata is executed with delegatecall on _init\n */\n function approveDiamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\n if (LibGuardian.guardianCount() == 0)\n revert DiamondCutFacet__InvalidRouteWithoutGuardian();\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n _checkFacetCutValidity(_diamondCut);\n\n bytes32 cutHash = getDiamondCutHash(_diamondCut, _init, _calldata);\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(\n true,\n approvalValidUntil\n );\n emit DiamondCutApproved(_diamondCut, _init, _calldata);\n if (\n (getDiamondCutApprovalCountWithTimeValidity(cutHash) >=\n LibGuardian.majorityOfGuardians()) &&\n getOwnerCutApprovalWithTimeValidity(cutHash)\n ) {\n ++LibFacetStorage.diamondCutStorage().nonce;\n LibDiamond.diamondCut(_diamondCut, _init, _calldata);\n }\n }\n\n /**\n * @notice Revokes the approval of diamond cut. This can only be called directly from guardian or owner\n * @param _diamondCut Contains the facet addresses and function selectors\n * @param _init The address of the contract or facet to execute _calldata\n * @param _calldata A function call, including function selector and arguments\n * _calldata is executed with delegatecall on _init\n */\n function revokeDiamondCutApproval(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n bytes32 cutHash = getDiamondCutHash(_diamondCut, _init, _calldata);\n if (!ds.isDiamondCutApproved[cutHash][msg.sender].isApproved)\n revert DiamondCutFacet__CannotRevokeUnapproved();\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(false, 0);\n emit DiamondCutApprovalRevoked(_diamondCut, _init, _calldata);\n }\n\n /**\n * @notice Gets the number of approvals of diamond cut from guardians\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n */\n function getDiamondCutApprovalCountWithTimeValidity(\n bytes32 _diamondCutHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardiansLength = guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n if (isCutApproved(_diamondCutHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n return approvalCount;\n }\n\n /**\n * @notice Returns if the owner has approved the diamond cut\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @return isApprovedByOwner Bool value showing if the owner approved the cut\n */\n function getOwnerCutApprovalWithTimeValidity(\n bytes32 _diamondCutHash\n ) public view override returns (bool isApprovedByOwner) {\n isApprovedByOwner = isCutApproved(_diamondCutHash, address(this));\n }\n\n /**\n * @notice Returns if the given approver has approved the diamond cut\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @param _approver Address of approver\n * @return isApproved Bool value showing if the approver approved the cut\n */\n function isCutApproved(\n bytes32 _diamondCutHash,\n address _approver\n ) public view override returns (bool isApproved) {\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n isApproved = (ds\n .isDiamondCutApproved[_diamondCutHash][_approver].isApproved &&\n block.timestamp <\n ds.isDiamondCutApproved[_diamondCutHash][_approver].validUntil);\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _diamondCutHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isCutApproved(_diamondCutHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert DiamondCutFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the diamond cut hash. This function ensures that this hash is safe from replay attack by including\n * salt, address, chainId, and nonce, etc.\n * @param _diamondCut Contains the facet addresses and function selectors\n * @param _init The address of the contract or facet to execute _calldata\n * @param _calldata A function call, including function selector and arguments\n * _calldata is executed with delegatecall on _init\n * @return cutHash Diamond Cut Hash\n */\n function getDiamondCutHash(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) public view override returns (bytes32 cutHash) {\n cutHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n keccak256(abi.encode(_diamondCut)),\n _init,\n _calldata,\n address(this),\n block.chainid,\n LibFacetStorage.diamondCutStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Returns the approval validation Period\n * @dev This method fetches the validation period from the security manager\n * @return approvalValidationPeriod Approval validation period of Barz contract fetched from security manager\n */\n function getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod <= 0)\n revert DiamondCutFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the diamond cut nonce of this wallet\n * @dev This method fetches the nonce from diamond cut storage\n * @return cutNonce Nonce of diamond cut to protect from reply attacks\n */\n function getDiamondCutNonce()\n public\n view\n override\n returns (uint128 cutNonce)\n {\n cutNonce = LibFacetStorage.diamondCutStorage().nonce;\n }\n}\n" + }, + "contracts/facets/base/DiamondLoupeFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {IERC165} from \"../../interfaces/ERC/IERC165.sol\";\nimport {IERC1271} from \"../../interfaces/ERC/IERC1271.sol\";\nimport {IERC677Receiver} from \"../../interfaces/ERC/IERC677Receiver.sol\";\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC1155Receiver} from \"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\";\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../../libraries/LibLoupe.sol\";\nimport {LibUtils} from \"../../libraries/LibUtils.sol\";\nimport {IDiamondCut} from \"../../facets/base/interfaces/IDiamondCut.sol\";\nimport {IStorageLoupe} from \"./interfaces/IStorageLoupe.sol\";\nimport {IDiamondLoupe} from \"./interfaces/IDiamondLoupe.sol\";\n\n/**\n * @title DiamondLoupe Facet\n * @dev DiamondLoupe contract compatible with EIP-2535\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DiamondLoupeFacet is IDiamondLoupe, IStorageLoupe, IERC165 {\n // Diamond Loupe Functions\n ////////////////////////////////////////////////////////////////////\n /// These functions are expected to be called frequently by tools off-chain.\n\n /**\n * @notice Gets all facets and their selectors.\n * @dev Barz uses a special architecture called default fallback handler. Default Fallback handler is used as a middleware\n * that holds the mapping of facet function selector and facet address that Barz uses. This helps Barz to reduce\n * significant amount of gas during the initialization process.\n * Hence, this method aggregates both the facet information from DefaulFallbackHandler and in diamond storage and shows the data to users.\n * @return facets_ Facet\n */\n function facets() public view override returns (Facet[] memory facets_) {\n Facet[] memory defaultFacet = LibDiamond\n .diamondStorage()\n .defaultFallbackHandler\n .facets();\n Facet[] memory _facets = LibLoupe.facets();\n uint256 numFacets = _facets.length;\n bytes4[] memory keys;\n address[] memory values;\n for (uint256 i; i < numFacets; ) {\n uint256 selectorsLength = _facets[i].functionSelectors.length;\n for (uint256 j; j < selectorsLength; ) {\n (keys, values) = LibUtils.setValue(\n keys,\n values,\n _facets[i].functionSelectors[j],\n _facets[i].facetAddress\n );\n unchecked {\n ++j;\n }\n }\n unchecked {\n ++i;\n }\n }\n {\n bool iIncrement;\n for (uint256 i; i < defaultFacet.length; ) {\n bool jIncrement;\n for (\n uint256 j;\n j < defaultFacet[i].functionSelectors.length;\n\n ) {\n if (\n LibUtils.getValue(\n keys,\n values,\n defaultFacet[i].functionSelectors[j]\n ) != address(0)\n ) {\n if (defaultFacet[i].functionSelectors.length == 1) {\n defaultFacet = LibUtils.removeFacetElement(\n defaultFacet,\n i\n );\n iIncrement = true;\n break;\n }\n defaultFacet[i].functionSelectors = LibUtils\n .removeElement(\n defaultFacet[i].functionSelectors,\n j\n );\n jIncrement = true;\n }\n if (!jIncrement) {\n unchecked {\n ++j;\n }\n } else {\n jIncrement = false;\n }\n }\n if (!iIncrement) {\n unchecked {\n ++i;\n }\n } else {\n iIncrement = false;\n }\n }\n }\n {\n uint256 facetLength = numFacets + defaultFacet.length;\n facets_ = new Facet[](facetLength);\n uint256 defaultFacetIndex;\n for (uint256 i; i < facetLength; ) {\n if (i < numFacets) {\n facets_[i] = _facets[i];\n bool jIncrementor;\n for (uint256 j; j < defaultFacet.length; ) {\n if (\n facets_[i].facetAddress ==\n defaultFacet[j].facetAddress\n ) {\n facets_[i].functionSelectors = LibUtils.mergeArrays(\n _facets[i].functionSelectors,\n defaultFacet[j].functionSelectors\n );\n defaultFacet = LibUtils.removeFacetElement(\n defaultFacet,\n j\n );\n jIncrementor = true;\n {\n facets_ = LibUtils.removeFacetElement(\n facets_,\n facets_.length - 1\n );\n }\n --facetLength;\n }\n if (!jIncrementor) {\n unchecked {\n ++j;\n }\n } else {\n jIncrementor = false;\n }\n }\n } else {\n facets_[i] = defaultFacet[defaultFacetIndex];\n ++defaultFacetIndex;\n }\n unchecked {\n ++i;\n }\n }\n }\n }\n\n /**\n * @notice Gets all the function selectors provided by a facet.\n * @param _facet The facet address.\n * @return facetFunctionSelectors_\n */\n function facetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n Facet[] memory facet = facets();\n uint256 facetLength = facet.length;\n for (uint256 i; i < facetLength; ) {\n if (facet[i].facetAddress == _facet)\n return facet[i].functionSelectors;\n unchecked {\n ++i;\n }\n }\n return facetFunctionSelectors_;\n }\n\n /**\n * @notice Get all the facet addresses used by Barz.\n * @return facetAddresses_\n */\n function facetAddresses()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n Facet[] memory facet = facets();\n uint256 facetLength = facet.length;\n facetAddresses_ = new address[](facetLength);\n for (uint256 i; i < facetLength; ) {\n facetAddresses_[i] = facet[i].facetAddress;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Gets the facet that supports the given selector.\n * @dev If facet is not found return address(0).\n * @param _functionSelector The function selector.\n * @return facetAddress_ The facet address.\n */\n function facetAddress(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n\n facetAddress_ = address(bytes20(ds.facets[_functionSelector]));\n if (facetAddress_ == address(0)) {\n facetAddress_ = IDiamondLoupe(ds.defaultFallbackHandler)\n .facetAddress(_functionSelector);\n }\n }\n\n /**\n * @notice SupportInterface to be compatible with EIP 165\n * @param _interfaceId Interface ID for detecting the interface\n * @return isSupported Bool value showing if the standard is supported in the contract\n */\n function supportsInterface(\n bytes4 _interfaceId\n ) external view override returns (bool isSupported) {\n isSupported =\n _interfaceId == type(IERC165).interfaceId ||\n _interfaceId == IDiamondCut.diamondCut.selector ||\n _interfaceId == type(IDiamondLoupe).interfaceId ||\n _interfaceId == type(IERC1155Receiver).interfaceId ||\n _interfaceId == type(IERC721Receiver).interfaceId ||\n _interfaceId == type(IERC777Recipient).interfaceId ||\n _interfaceId == IERC1271.isValidSignature.selector ||\n _interfaceId == type(IERC677Receiver).interfaceId ||\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId];\n }\n\n /**\n * @notice Returns the facet from the diamond storage. This excludes the facets from the default fallback handler\n * @return facets_ Facet information attached directly to diamond storage\n */\n function facetsFromStorage()\n external\n view\n override\n returns (Facet[] memory facets_)\n {\n facets_ = LibLoupe.facets();\n }\n\n /**\n * @notice Returns the facet address attached to the given function selector. This excludes the facets from the default fallback handler\n * @param _functionSelector Function selector to fetch the facet address from diamond storage\n * @return facetAddress_ Facet address mapped with the function selector\n */\n function facetAddressFromStorage(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n facetAddress_ = LibLoupe.facetAddress(_functionSelector);\n }\n\n /**\n * @notice Returns all facet addresses attached directly to diamond storage. This excludes the facets from the default fallback handler\n * @return facetAddresses_ All facet addresses attached directly to diamond storage\n */\n function facetAddressesFromStorage()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n facetAddresses_ = LibLoupe.facetAddresses();\n }\n\n /**\n * @notice Returns function selectors of given facet address attached directly to diamond storage. This excludes the facets from the default fallback handler\n * @param _facet Facet address to fetch the facet function selectors from diamond storage\n * @return facetFunctionSelectors_ Facet function selectors of the given facet address\n */\n function facetFunctionSelectorsFromStorage(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n facetFunctionSelectors_ = LibLoupe.facetFunctionSelectors(_facet);\n }\n}\n" + }, + "contracts/facets/base/interfaces/IDiamondCut.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title DiamondCut Facet Interface\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IDiamondCut {\n error DiamondCutFacet__InvalidRouteWithGuardian();\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\n error DiamondCutFacet__InvalidArrayLength();\n error DiamondCutFacet__InsufficientApprovers();\n error DiamondCutFacet__InvalidApprover();\n error DiamondCutFacet__InvalidApproverSignature();\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\n error DiamondCutFacet__CannotRevokeUnapproved();\n error DiamondCutFacet__GuardianApprovalNotRequired();\n error DiamondCutFacet__LackOfOwnerApproval();\n error DiamondCutFacet__OwnerAlreadyApproved();\n error DiamondCutFacet__DuplicateApproval();\n\n event DiamondCutApproved(\n FacetCut[] diamondCut,\n address init,\n bytes initCalldata\n );\n event DiamondCutApprovalRevoked(\n FacetCut[] diamondCut,\n address init,\n bytes initCalldata\n );\n\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\n\n enum FacetCutAction {\n Add,\n Replace,\n Remove\n }\n // Add=0, Replace=1, Remove=2\n\n struct FacetCut {\n address facetAddress;\n FacetCutAction action;\n bytes4[] functionSelectors;\n }\n\n /// @notice Add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param diamondCut Contains the facet addresses and function selectors\n /// @param init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function diamondCut(\n FacetCut[] calldata diamondCut,\n address init,\n bytes calldata _calldata\n ) external;\n\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\n\n function diamondCutWithGuardian(\n FacetCut[] calldata diamondCut,\n address init,\n bytes calldata _calldata,\n address[] calldata approvers,\n bytes[] calldata signatures\n ) external;\n\n function approveDiamondCut(\n FacetCut[] calldata diamondCut,\n address init,\n bytes calldata _calldata\n ) external;\n\n function revokeDiamondCutApproval(\n FacetCut[] calldata diamondCut,\n address init,\n bytes calldata _calldata\n ) external;\n\n function getDiamondCutApprovalCountWithTimeValidity(\n bytes32 diamondCutHash\n ) external view returns (uint256);\n\n function getOwnerCutApprovalWithTimeValidity(\n bytes32 diamondCutHash\n ) external view returns (bool);\n\n function isCutApproved(\n bytes32 diamondCutHash,\n address approver\n ) external view returns (bool);\n\n function getDiamondCutHash(\n FacetCut[] calldata diamondCut,\n address init,\n bytes calldata _calldata\n ) external view returns (bytes32);\n\n function getDiamondCutNonce() external view returns (uint128);\n}\n" + }, + "contracts/facets/base/interfaces/IDiamondLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n// A loupe is a small magnifying glass used to look at diamonds.\n// These functions look at diamonds\ninterface IDiamondLoupe {\n /// These functions are expected to be called frequently\n /// by tools.\n\n struct Facet {\n address facetAddress;\n bytes4[] functionSelectors;\n }\n\n /// @notice Gets all facet addresses and their four byte function selectors.\n /// @return facets_ Facet\n function facets() external view returns (Facet[] memory facets_);\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n /// @return facetFunctionSelectors_\n function facetFunctionSelectors(\n address _facet\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses()\n external\n view\n returns (address[] memory facetAddresses_);\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(\n bytes4 _functionSelector\n ) external view returns (address facetAddress_);\n}\n" + }, + "contracts/facets/base/interfaces/IStorageLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"./IDiamondLoupe.sol\";\n\n/**\n * @title LoupeFromStorage Interface\n * @dev Interface contract to function as a loupe facet directly attached to diamond storage of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IStorageLoupe {\n /// These functions are expected to be called frequently\n /// by tools.\n\n /// @notice Gets all facet addresses and their four byte function selectors.\n /// @return facets_ Facet\n function facetsFromStorage()\n external\n view\n returns (IDiamondLoupe.Facet[] memory);\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n function facetFunctionSelectorsFromStorage(\n address _facet\n ) external view returns (bytes4[] memory);\n\n /// @notice Get all the facet addresses used by a diamond.\n function facetAddressesFromStorage()\n external\n view\n returns (address[] memory);\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n function facetAddressFromStorage(\n bytes4 _functionSelector\n ) external view returns (address);\n}\n" + }, + "contracts/facets/GuardianFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibFacetStorage, GuardianStorage, StorageConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IGuardianFacet} from \"./interfaces/IGuardianFacet.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Guardian Facet\n * @dev Contract that enables addition/removal of guardians from Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract GuardianFacet is IGuardianFacet {\n ISecurityManager public immutable securityManager;\n uint8 public constant INNER_STRUCT = 0;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Add guardians to Barz.\n * @dev This method internally calls addGuardian which checks the validity of guardian address and adds\n * as guardian if valid\n * @param _guardians Array of addresses to add as guardian\n */\n function addGuardians(address[] calldata _guardians) external override {\n LibDiamond.enforceIsSelf();\n uint256 guardiansLength = _guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n addGuardian(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Add a guardian to Barz.\n * @dev This method checks if the function is called by the owner and validates the address of guardian\n * When the validation passes, guardian address is added to the pending state waiting for confirmation\n * @param _guardian Address to add as guardian\n */\n function addGuardian(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (_guardian == address(this))\n revert GuardianFacet__GuardianCannotBeSelf();\n if (isGuardian(_guardian)) revert GuardianFacet__DuplicateGuardian();\n if (_guardian == address(0))\n revert GuardianFacet__ZeroAddressGuardian();\n if (\n keccak256(abi.encodePacked(_guardian)) ==\n keccak256(IVerificationFacet(address(this)).owner())\n ) revert GuardianFacet__OwnerCannotBeGuardian();\n\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n if (\n gs.pending[id] != 0 ||\n block.timestamp <= gs.pending[id] + getSecurityWindow()\n ) revert GuardianFacet__DuplicateGuardianAddition();\n\n uint256 securityPeriod = getAdditionSecurityPeriod();\n gs.pending[id] = block.timestamp + securityPeriod;\n emit GuardianAdditionRequested(\n _guardian,\n block.timestamp + securityPeriod\n );\n }\n\n /**\n * @notice Remove guardians from Barz.\n * @dev This method internally calls removeGuardian which checks the validity of guardian and removes\n * guardian when the request is valid\n * @param _guardians Array of addresses to be removed\n */\n function removeGuardians(address[] calldata _guardians) external override {\n LibDiamond.enforceIsSelf();\n uint256 guardiansLength = _guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n removeGuardian(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Remove a guardian from Barz.\n * @dev This method validates if the guardian to be removed is a guardian and puts the guardian removal\n * to a pending state waiting to be confirmed.\n * @param _guardian Address of guardian to be removed\n */\n function removeGuardian(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n if (!isGuardian(_guardian)) revert GuardianFacet__NonExistentGuardian();\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n if (\n gs.pending[id] != 0 ||\n block.timestamp <= gs.pending[id] + getSecurityWindow()\n ) revert GuardianFacet__DuplicateGuardianRemoval();\n\n uint256 securityPeriod = getRemovalSecurityPeriod();\n gs.pending[id] = block.timestamp + securityPeriod;\n emit GuardianRemovalRequested(\n _guardian,\n block.timestamp + securityPeriod\n );\n }\n\n /**\n * @notice Confirm addition of guardians\n * @dev This method internally calls confirmGuardianAddition which checks the validity of pending request.\n * Guardians are fully added when they pass the validation. Anyone can call this function.\n * @param _guardians Array of guardian addresses to be added\n */\n function confirmGuardianAdditions(\n address[] calldata _guardians\n ) external override {\n uint256 guardiansLength = _guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n confirmGuardianAddition(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Confirm addition of a guardian\n * @dev This method checks the validity of pending request.\n * Guardians are fully added when they pass the validation. Anyone can call this function.\n * @param _guardian Guardian address to be added\n */\n function confirmGuardianAddition(address _guardian) public override {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingAddition();\n if (gs.pending[id] >= block.timestamp)\n revert GuardianFacet__PendingAdditionNotOver();\n if (block.timestamp >= gs.pending[id] + getSecurityWindow())\n revert GuardianFacet__PendingAdditionExpired();\n\n _addGuardian(_guardian);\n\n delete gs.pending[id];\n emit GuardianAdded(_guardian);\n }\n\n /**\n * @notice Confirm removal of guardians\n * @dev This method internally calls confirmGuardianRemoval to check the validity guardian removal confirmation.\n * Guardians are fully removed when they pass the validation. Anyone can call this function.\n * @param _guardians Array of guardian addresses to be removed\n */\n function confirmGuardianRemovals(\n address[] calldata _guardians\n ) external override {\n uint256 guardiansLength = _guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n confirmGuardianRemoval(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Confirm removal of a guardian\n * @dev This method checks the validity guardian removal confirmation.\n * Guardian is fully removed when they pass the validation. Anyone can call this function.\n * @param _guardian Guardian address to be removed\n */\n function confirmGuardianRemoval(address _guardian) public override {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingRemoval();\n if (gs.pending[id] >= block.timestamp)\n revert GuardianFacet__PendingRemovalNotOver();\n if (block.timestamp >= gs.pending[id] + getSecurityWindow())\n revert GuardianFacet__PendingAdditionExpired();\n\n _removeGuardian(_guardian);\n delete gs.pending[id];\n emit GuardianRemoved(_guardian);\n }\n\n /**\n * @notice Cancel pending guardian addition\n * @dev This method checks if the previous request for guardian request exists.\n * It reverts if previous request is not pending and cancels the addition otherwise.\n * @param _guardian Guardian address to be canceled from addition\n */\n function cancelGuardianAddition(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingAddition();\n delete gs.pending[id];\n emit GuardianAdditionCancelled(_guardian);\n }\n\n /**\n * @notice Cancel pending guardian removal\n * @dev This method checks if the previous request for guardian request exists.\n * It reverts if previous request is not pending and cancels the removal otherwise.\n * @param _guardian Guardian address to be canceled from removal\n */\n function cancelGuardianRemoval(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingRemoval();\n delete gs.pending[id];\n emit GuardianRemovalCancelled(_guardian);\n }\n\n /**\n * @notice Get the addition security period of current account from security manager\n * @dev This method returns the uint value if addition security period\n * @return additionSecurityPeriod Uint256 value of addition security period\n */\n function getAdditionSecurityPeriod()\n public\n view\n override\n returns (uint256 additionSecurityPeriod)\n {\n additionSecurityPeriod = securityManager.additionSecurityPeriodOf(\n address(this)\n );\n if (additionSecurityPeriod == 0)\n revert GuardianFacet__InvalidAdditionSecurityPeriod();\n }\n\n /**\n * @notice Get the removal security period of current account from security manager\n * @dev This method returns the uint value if removal security period\n * @return removalSecurityPeriod Uint256 value of removal security period\n */\n function getRemovalSecurityPeriod()\n public\n view\n override\n returns (uint256 removalSecurityPeriod)\n {\n removalSecurityPeriod = securityManager.removalSecurityPeriodOf(\n address(this)\n );\n if (removalSecurityPeriod == 0)\n revert GuardianFacet__InvalidRemovalSecurityPeriod();\n }\n\n /**\n * @notice Get the security window of current account from security manager\n * @dev This method returns the uint value if security window\n * @return securityWindow Uint256 value of removal security period\n */\n function getSecurityWindow()\n public\n view\n override\n returns (uint256 securityWindow)\n {\n securityWindow = securityManager.securityWindowOf(address(this));\n if (securityWindow == 0) revert GuardianFacet__InvalidSecurityWindow();\n }\n\n /**\n * @notice Checks if the addition of the given guardian address is pending\n * @dev This method returns the bool value of whether the guardian address is pending addition\n * @return isPending Bool value of representing the pending of guardian addition\n */\n function isAdditionPending(\n address _guardian\n ) public view override returns (bool isPending) {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n isPending = _isPending(id);\n }\n\n /**\n * @notice Checks if the removal of the given guardian address is pending\n * @dev This method returns the bool value of whether the guardian address is pending removal\n * @return isPending Bool value of representing the pending of guardian removal\n */\n function isRemovalPending(\n address _guardian\n ) public view override returns (bool isPending) {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n isPending = _isPending(id);\n }\n\n /**\n * @notice Checks if the given hash is pending\n * @dev This method returns the bool value whether the hash is pending\n * @return isPending Bool value of representing the pending of guardian operation\n */\n function _isPending(\n bytes32 _idHash\n ) internal view returns (bool isPending) {\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n isPending = ((gs.pending[_idHash] > 0 &&\n gs.pending[_idHash] < block.timestamp) &&\n block.timestamp < gs.pending[_idHash] + getSecurityWindow());\n }\n\n /**\n * @notice Adds guardian to storage config. This is called when guardian is fully added.\n * @dev This method add guardian address and config information to Facet Storage dedicated for guardian\n * When this function is called, guardian is fully added to this Barz Smart Account\n * @param _guardian Address of guardian to be added\n */\n function _addGuardian(address _guardian) internal {\n if (!isAdditionPending(_guardian))\n revert GuardianFacet__InvalidGuardianAddition();\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n if (config.info[_guardian].exists)\n revert GuardianFacet__AlreadyExists();\n\n config.info[_guardian].exists = true;\n config.info[_guardian].index = uint128(config.addresses.length);\n config.addresses.push(_guardian);\n }\n\n /**\n * @notice Removes guardian to storage config. This is called when guardian is fully removed.\n * @dev This method remove guardian address and config information to Facet Storage dedicated for guardian\n * When this function is called, guardian is fully removed from this Barz Smart Account\n * @param _guardian Address of guardian to be removed\n */\n function _removeGuardian(address _guardian) internal {\n if (!isRemovalPending(_guardian))\n revert GuardianFacet__InvalidGuardianRemoval();\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n if (!config.info[_guardian].exists)\n revert GuardianFacet__NonExistentGuardian();\n\n address lastAddress = config.addresses[config.addresses.length - 1];\n if (_guardian != lastAddress) {\n uint128 targetIndex = config.info[_guardian].index;\n config.addresses[targetIndex] = lastAddress;\n config.info[lastAddress].index = targetIndex;\n }\n config.addresses.pop();\n delete config.info[_guardian];\n\n emit GuardianRemoved(_guardian);\n }\n\n /**\n * @notice Reads guardian storage and fetches the addresses into an array from the storage\n * @dev This method fetches the guardian storage and returns the list of guardian addresses\n * @return addresses Array of addresses comprised of guardian\n */\n function getGuardians()\n public\n view\n override\n returns (address[] memory addresses)\n {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n addresses = new address[](config.addresses.length);\n uint256 addressesLen = config.addresses.length;\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the number of majority of guardians\n * @return majorityOfGuardians_ Number of majority of guardians e.g., 2 if 3 guardians / 3 if 5 guardians\n */\n function majorityOfGuardians()\n public\n view\n override\n returns (uint256 majorityOfGuardians_)\n {\n majorityOfGuardians_ = LibGuardian.majorityOfGuardians();\n }\n\n /**\n * @notice Reads guardian storage and fetches the addresses into an array from the storage\n * @dev This method fetches the guardian storage and returns the list of guardian addresses\n * @return guardianNumber Array of guardians in the account\n */\n function guardianCount()\n public\n view\n override\n returns (uint256 guardianNumber)\n {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n guardianNumber = config.addresses.length;\n }\n\n /**\n * @notice Reads guardian storage and checks if the given address is a guardian\n * @return isGuardian_ Bool value representing if the given address is guardian\n */\n function isGuardian(\n address _guardian\n ) public view override returns (bool isGuardian_) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n isGuardian_ = config.info[_guardian].exists;\n }\n\n /**\n * @notice Checks if the guardian number is zero and returns of guardian facet is okay to be removed\n * @return isRemovable Bool value representing if guardian facet is removable\n */\n function isGuardianFacetRemovable()\n external\n view\n override\n returns (bool isRemovable)\n {\n isRemovable = (0 == guardianCount());\n }\n}\n" + }, + "contracts/facets/interfaces/IAccountFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IEntryPoint} from \"../../aa-4337/interfaces/IEntryPoint.sol\";\n\n/**\n * @title Account Facet Interface\n * @dev Interface of module contract that provides the account features and init/unitialization of signer\n * compatible with EIP-1271 & EIP-4337\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IAccountFacet {\n event AccountInitialized(\n IEntryPoint indexed entryPoint,\n bytes indexed ownerPublicKey\n );\n // NOTE: Added Below Event\n event VerificationSuccess(bytes32);\n event VerificationFailure(bytes32);\n\n error AccountFacet__InitializationFailure();\n error AccountFacet__RestrictionsFailure();\n error AccountFacet__NonExistentVerificationFacet();\n error AccountFacet__CallNotSuccessful();\n\n function initialize(\n address verificationFacet,\n address anEntryPoint,\n address facetRegistry,\n address _defaultFallBack,\n bytes calldata _ownerPublicKey\n ) external returns (uint256);\n\n function execute(address dest, uint256 value, bytes calldata func) external;\n\n function executeBatch(\n address[] calldata dest,\n uint256[] calldata value,\n bytes[] calldata func\n ) external;\n}\n" + }, + "contracts/facets/interfaces/IAccountRecoveryFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {RecoveryConfig} from \"../../libraries/LibFacetStorage.sol\";\n\n/**\n * @title Account Recovery Facet Interface\n * @dev Interface of contract that enables recovery of accounts when owner key is unavailable\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IAccountRecoveryFacet {\n event RecoveryExecuted(\n bytes indexed recoveryPublicKey,\n uint64 executeAfter\n );\n event RecoveryFinalized(bytes indexed recoveryPublicKey);\n event RecoveryCanceled(bytes indexed recoveryPublicKey);\n event RecoveryApproved(\n bytes indexed recoveryPublicKey,\n address indexed guardian,\n uint64 validUntil\n );\n event RecoveryApprovalRevoked(\n bytes indexed recoveryPublicKey,\n address indexed guardian\n );\n event RecoveryCancellationApproved(\n bytes indexed recoveryPublicKey,\n address indexed guardian\n );\n event RecoveryHardstopped();\n\n error AccountRecoveryFacet__CallerNotGuardian();\n error AccountRecoveryFacet__InvalidRecoveryPublicKey();\n error AccountRecoveryFacet__SignerInitializationFailure();\n error AccountRecoveryFacet__SignerUninitializationFailure();\n error AccountRecoveryFacet__InvalidArrayLength();\n error AccountRecoveryFacet__InsufficientGuardians();\n error AccountRecoveryFacet__RecoveryAlreadyOngoing();\n error AccountRecoveryFacet__NonexistentRecovery();\n error AccountRecoveryFacet__NonExistentApproval();\n error AccountRecoveryFacet__RecoveryPeriodNotOver();\n error AccountRecoveryFacet__InvalidLockPeriod();\n error AccountRecoveryFacet__InvalidRecoveryPeriod();\n error AccountRecoveryFacet__InvalidApprovalValidationPeriod();\n error AccountRecoveryFacet__InvalidGuardian();\n error AccountRecoveryFacet__InvalidGuardianSignature();\n error AccountRecoveryFacet__InvalidOwnerSignature();\n error AccountRecoveryFacet__CallNotSuccesful();\n error AccountRecoveryFacet__DuplicateApproval();\n\n function approveAccountRecovery(bytes calldata recoveryPublicKey) external;\n\n function revokeAccountRecoveryApproval(\n bytes calldata recoveryPublicKey\n ) external;\n\n function executeRecovery(\n bytes calldata recoveryPublicKey,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function finalizeRecovery() external;\n\n function approveCancelRecovery(bytes calldata recoveryPublicKey) external;\n\n function cancelRecovery(\n bytes calldata recoveryPublicKey,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function hardstopRecovery(bytes calldata signature) external;\n\n function getApprovalRecoveryKeyHash(\n bytes memory recoveryPublicKey,\n string memory saltString\n ) external view returns (bytes32);\n\n function getRecoveryApprovalCountWithTimeValidity(\n bytes32 recoveryPublicKeyHash\n ) external view returns (uint256);\n\n function isRecoveryApproved(\n bytes32 recoveryPublicKeyHash,\n address approver\n ) external view returns (bool);\n\n function getRecoveryNonce() external view returns (uint128);\n\n function getPendingRecovery() external view returns (RecoveryConfig memory);\n}\n" + }, + "contracts/facets/interfaces/IGuardianFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Guardian Facet Interface\n * @dev Interface of guaridna contract that enables addition/removal of guardians from Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IGuardianFacet {\n event GuardianAdditionRequested(\n address indexed guardian,\n uint256 executeAfter\n );\n event GuardianRemovalRequested(\n address indexed guardian,\n uint256 executeAfter\n );\n event GuardianAdditionCancelled(address indexed guardian);\n event GuardianRemovalCancelled(address indexed guardian);\n event GuardianAdded(address indexed guardian);\n event GuardianRemoved(address indexed guardian);\n\n error GuardianFacet__GuardianCannotBeSelf();\n error GuardianFacet__DuplicateGuardian();\n error GuardianFacet__OwnerCannotBeGuardian();\n error GuardianFacet__DuplicateGuardianAddition();\n error GuardianFacet__DuplicateGuardianRemoval();\n error GuardianFacet__UnknownPendingAddition();\n error GuardianFacet__PendingAdditionNotOver();\n error GuardianFacet__UnknownPendingRemoval();\n error GuardianFacet__PendingRemovalNotOver();\n error GuardianFacet__PendingAdditionExpired();\n error GuardianFacet__InvalidAdditionSecurityPeriod();\n error GuardianFacet__InvalidRemovalSecurityPeriod();\n error GuardianFacet__InvalidSecurityWindow();\n error GuardianFacet__NonExistentGuardian();\n error GuardianFacet__AlreadyExists();\n error GuardianFacet__InvalidGuardianAddition();\n error GuardianFacet__InvalidGuardianRemoval();\n error GuardianFacet__ZeroAddressGuardian();\n\n function addGuardian(address guardian) external;\n\n function addGuardians(address[] calldata guardians) external;\n\n function removeGuardian(address guardian) external;\n\n function removeGuardians(address[] calldata guardians) external;\n\n function confirmGuardianAddition(address guardian) external;\n\n function confirmGuardianAdditions(address[] calldata guardian) external;\n\n function confirmGuardianRemoval(address guardian) external;\n\n function confirmGuardianRemovals(address[] calldata guardian) external;\n\n function cancelGuardianAddition(address guardian) external;\n\n function cancelGuardianRemoval(address guardian) external;\n\n function isGuardian(address guardian) external view returns (bool);\n\n function isAdditionPending(address guardian) external view returns (bool);\n\n function isRemovalPending(address guardian) external view returns (bool);\n\n function isGuardianFacetRemovable() external view returns (bool);\n\n function getAdditionSecurityPeriod() external view returns (uint256);\n\n function getRemovalSecurityPeriod() external view returns (uint256);\n\n function getSecurityWindow() external view returns (uint256);\n\n function getGuardians() external view returns (address[] memory);\n\n function majorityOfGuardians() external view returns (uint256);\n\n function guardianCount() external view returns (uint256);\n}\n" + }, + "contracts/facets/interfaces/ILockFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Lock} from \"../../libraries/LibAppStorage.sol\";\n\n/**\n * @title Lock Facet Interface\n * @dev Interface of Lock contract that enables full lock/unlock of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface ILockFacet {\n event Locked(uint64 releaseAfter);\n event Unlocked();\n\n error LockFacet__InvalidRecoveryPeriod();\n error LockFacet__CannotUnlock();\n error LockFacet__InvalidSignature();\n error LockFacet__InvalidApprover();\n\n function lock() external;\n\n function unlock(address approver, bytes calldata signature) external;\n\n function getLockPeriod() external view returns (uint256);\n\n function isLocked() external view returns (bool);\n\n function getUnlockHash() external view returns (bytes32);\n\n function lockNonce() external view returns (uint128);\n\n function getPendingLock() external view returns (Lock memory);\n}\n" + }, + "contracts/facets/interfaces/IMultiSigFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Multi-sig facet Interface\n * @dev Interface of Multi-signature Facet with custom threshold.\n Wallet that adds this facet becomes a multi-sig wallet\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IMultiSigFacet {\n event ThresholdChanged(uint256 threshold);\n event OwnerAdded(address indexed newOwner);\n event OwnerRemoved(address indexed prevOwner);\n event HashApproved(bytes32 hashToApprove, address indexed owner);\n\n error MultiSigFacet__InvalidThreshold();\n error MultisigFacet__InvalidOwnerCount();\n error MultiSigFacet__InvalidRoute();\n error MultiSigFacet__InsufficientSignerLength();\n error MultiSigFacet__InvalidInitData();\n error MultiSigFacet__InvalidOwnerAddress();\n error MultiSigFacet__InvalidOwnerPair();\n error MultiSigFacet__InvalidSignatureLength();\n error MultiSigFacet__InvalidSignatureType();\n error MultiSigFacet__DuplicateOwner();\n error MultiSigFacet__OnlyOwner();\n\n function checkSignatures(\n bytes32 _dataHash,\n bytes calldata _signatures,\n uint256 _threshold\n ) external view returns (uint256);\n\n function splitSignatures(\n bytes calldata _signatures,\n uint256 _nextOffset\n )\n external\n pure\n returns (\n address owner,\n bytes memory signature,\n uint256 signatureType,\n uint256 nextOffset\n );\n\n function approveHash(bytes32 hashToApprove) external;\n\n function addOwner(address newOwner, uint256 threshold) external;\n\n function removeOwner(\n address prevOwner,\n address removedOwner,\n uint256 threshold\n ) external;\n\n function swapOwner(\n address prevOwner,\n address oldOwner,\n address newOwner\n ) external;\n\n function changeThreshold(uint256 _threshold) external;\n\n function isOwner(address owner) external view returns (bool);\n\n function getThreshold() external view returns (uint256);\n\n function getOwners() external view returns (address[] memory);\n}\n" + }, + "contracts/facets/interfaces/IRestrictionsFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Restrictions Facet Interface\n * @dev Interface of Restrictions contract that enables modular restrictions in Barz\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IRestrictionsFacet {\n event RestrictionAdded(address indexed restriction);\n event RestrictionRemoved(address indexed restriction);\n\n error RestrictionsFacet__EmptyRestrictionsList();\n error RestrictionsFacet__RestrictionNotFound();\n error RestrictionsFacet__RestrictionAlreadyExists();\n error RestrictionsFacet__ZeroAddressRestrictions();\n error RestrictionsFacet__ZeroAddressRestrictionsFacet();\n error RestrictionsFacet__RemainingRestrictionsCantBeEmpty();\n\n function initializeRestrictions(\n address[] memory _restrictions\n ) external returns (uint256);\n\n function uninitializeRestrictions() external returns (uint256);\n\n function getRestrictions() external view returns (address[] memory);\n\n function addRestriction(address restriction) external;\n\n function removeRestriction(address restriction) external;\n\n function verifyRestrictions(\n address from,\n address to,\n uint256 value,\n bytes calldata _calldata\n ) external returns (uint256);\n}\n" + }, + "contracts/facets/interfaces/ISignatureMigrationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureMigrationConfig} from \"../../libraries/LibFacetStorage.sol\";\n\n/**\n * @title Signature Migration Facet Interface\n * @dev Interface of Signature Migration contract for migrating user signature scheme to a new scheme user sets\n * Which could include\n * - ECDSA on Secp256K1 Curve\n * - ECDSA on Secp256R1 Curve\n * - BLS, Schnorr, etc\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface ISignatureMigrationFacet {\n event SignatureSchemeMigration(\n address indexed prevVerificationFacet,\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n event SignatureMigrationApproved(\n bytes newPublicKey,\n address indexed newVerificationFacet,\n bytes4[] verificationFuncSelectors,\n address indexed guardian,\n uint128 approvalValidUntil\n );\n event SignatureMigrationApprovalRevoked(\n bytes newPublicKey,\n address indexed newVerificationFacet,\n bytes4[] verificationFuncSelectors,\n address indexed guardian\n );\n event SignatureMigrationExecuted(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors,\n uint128 migrateAfter\n );\n event SignatureMigrationCanceled(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n event SignatureMigrationCancellationApproved(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n\n error SignatureMigrationFacet__SignerUninitializationFailure();\n error SignatureMigrationFacet__InvalidRouteWithGuardian();\n error SignatureMigrationFacet__InvalidKeyType();\n error SignatureMigrationFacet__InsufficientApprovers();\n error SignatureMigrationFacet__InvalidApproverSignature();\n error SignatureMigrationFacet__InvalidGuardian();\n error SignatureMigrationFacet__NonExistentApprover();\n error SignatureMigrationFacet__InvalidMigrationPeriod();\n error SignatureMigrationFacet__NonexistentMigration();\n error SignatureMigrationFacet__MigrationPeriodNotOver();\n error SignatureMigrationFacet__InvalidArrayLength();\n error SignatureMigrationFacet__InvalidApprovalValidationPeriod();\n error SignatureMigrationFacet__CannotRevokeUnapproved();\n error SignatureMigrationFacet__LackOfOwnerApproval();\n error SignatureMigrationFacet__OwnerAlreadyApproved();\n error SignatureMigrationFacet__NonExistentVerificationFacet();\n error SignatureMigrationFacet__DuplicateApproval();\n\n function migrateSignatureScheme(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function migrateSignatureSchemeWithGuardian(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors,\n address[] calldata approvers,\n bytes[] calldata signatures\n ) external;\n\n function approveSignatureSchemeMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function revokeSignatureMigrationApproval(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function finalizeSignatureMigration() external;\n\n function approveCancelSignatureMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function cancelSignatureMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function getApprovalMigrationKeyHash(\n bytes memory recoveryPublicKey,\n address newVerificationFacet,\n bytes4[] memory newVerificationFuncSelectors,\n string memory saltString\n ) external view returns (bytes32);\n\n function getMigrationOwnerApprovalWithTimeValidity(\n bytes32 publicKeyHash\n ) external view returns (bool);\n\n function getMigrationApprovalCountWithTimeValidity(\n bytes32 publicKeyHash\n ) external view returns (uint256);\n\n function isMigrationApproved(\n bytes32 migrationPublicKeyHash,\n address approver\n ) external view returns (bool);\n\n function getMigrationNonce() external view returns (uint128);\n\n function isMigrationPending() external view returns (bool);\n\n function getPendingMigration()\n external\n view\n returns (SignatureMigrationConfig memory);\n}\n" + }, + "contracts/facets/interfaces/IVerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {UserOperation} from \"../../aa-4337/interfaces/UserOperation.sol\";\n\n/**\n * @title Verification Facet Interface\n * @dev Implements logic for user ops signature verification\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface IVerificationFacet {\n event SignerInitialized(bytes);\n event SignerUninitialized();\n\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n error VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n error VerificationFacet__InitializationFailure();\n error VerificationFacet__InvalidFacetMapping();\n\n function initializeSigner(bytes memory) external returns (uint256);\n\n function uninitializeSigner() external returns (uint256);\n\n function validateOwnerSignatureSelector() external view returns (bytes4);\n\n function owner() external view returns (bytes memory);\n\n function isValidKeyType(bytes calldata) external view returns (bool);\n\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) external view returns (uint256);\n}\n" + }, + "contracts/facets/LockFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage, Lock} from \"../libraries/LibAppStorage.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibFacetStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {ILockFacet} from \"./interfaces/ILockFacet.sol\";\n\n/**\n * @title Lock Facet\n * @dev Contract that enables full lock/unlock of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract LockFacet is ILockFacet, Modifiers {\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Locks the account for the lock period. Lock period is defined in the security manager and it's customizable\n * This function can only be called when account is unlocked by owner or guardians\n * @dev This method checks the caller and if the account is currently locked and locks the account after fetching the\n * Lock period from the owner.\n */\n function lock() external override onlyGuardianOrOwner onlyWhenUnlocked {\n uint256 unlockTime = block.timestamp + getLockPeriod();\n ++LibFacetStorage.lockStorage().nonce;\n LibAppStorage.setLock(unlockTime, LockFacet.lock.selector);\n emit Locked(uint64(unlockTime));\n }\n\n /**\n * @notice Locks the account when the account is locked. This function can be called by anyone but must provide the approver address and signature.\n * The approver should be one of the guardians or owner.\n * @dev This method takes the approver address and the signature. After validating the address and the signature, it unlocks the account immediately.\n * Only one of the guardian or owner is required to lock and unlock the account.\n * @param _approver Address of approver approving the unlock of Barz account\n * @param _signature Signature of the approver that signed the msg hash for unlocking the account\n */\n function unlock(\n address _approver,\n bytes calldata _signature\n ) external override onlyWhenLocked {\n if (_approver != address(this) && !LibGuardian.isGuardian(_approver))\n revert LockFacet__InvalidApprover();\n if (\n !SignatureChecker.isValidSignatureNow(\n _approver,\n getUnlockHash(),\n _signature\n )\n ) revert LockFacet__InvalidSignature();\n _unlock();\n }\n\n /**\n * @notice Unlocks the account and increments the lock nonce\n */\n function _unlock() private {\n if (s.locks[INNER_STRUCT].locker != LockFacet.lock.selector)\n revert LockFacet__CannotUnlock();\n ++LibFacetStorage.lockStorage().nonce;\n LibAppStorage.setLock(0, bytes4(0));\n emit Unlocked();\n }\n\n /**\n * @notice Returns the lock period of current Barz account. Lock period information is held by Security Manager\n * @return lockPeriod Uint value of lock period in seconds\n */\n function getLockPeriod() public view override returns (uint256 lockPeriod) {\n lockPeriod = securityManager.lockPeriodOf(address(this));\n if (lockPeriod == 0) revert LockFacet__InvalidRecoveryPeriod();\n }\n\n /**\n * @notice Returns if the account is locked or not\n * @dev This method fetches the current block timestamp and compares that with release time.\n * After checking the timestamp and release time, it returns if the account is still locked or not.\n * @return isLocked_ Uint value of lock period in seconds\n */\n function isLocked() public view override returns (bool isLocked_) {\n isLocked_ = uint64(block.timestamp) < s.locks[INNER_STRUCT].release;\n }\n\n /**\n * @notice Calculates the unlock hash and returns the unlock hash safe from signature reply attack\n * @dev This method calculates the unlock hash with EIP-191 prefix, wallet address, chainID, and nonce\n * It packs the result and packs them and hashes it.\n * @return unlockHash Bytes32 unlock hash\n */\n function getUnlockHash() public view override returns (bytes32 unlockHash) {\n unlockHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n \"Unlock\",\n address(this),\n block.chainid,\n lockNonce()\n )\n )\n )\n );\n }\n\n /**\n * @notice Returns lock nonce of account. Reads nonce from lock storage within facet storage\n * @return lockNonce_ Uint128 value of lock nonce. This is incremented whenever the account is lock/unlocked\n */\n function lockNonce() public view override returns (uint128 lockNonce_) {\n lockNonce_ = LibFacetStorage.lockStorage().nonce;\n }\n\n /**\n * @notice Returns the overall information of current lock\n * @return pendingLock Struct value including all information of pending lock\n */\n function getPendingLock()\n public\n view\n override\n returns (Lock memory pendingLock)\n {\n pendingLock = s.locks[INNER_STRUCT];\n }\n}\n" + }, + "contracts/facets/Modifiers.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {IFacetRegistry} from \"../infrastructure/interfaces/IFacetRegistry.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\n\n/**\n * @title Modifiers\n * @dev Responsible for providing modifiers/util functions to Facet contracts\n * @author David Yongjun Kim (@Powerstream3604)\n */\nabstract contract Modifiers is BarzStorage {\n uint8 constant INNER_STRUCT = 0;\n\n error CallerNotGuardian();\n error CallerNotGuardianOrOwner();\n error DuplicateApprover();\n error ZeroApproverLength();\n error UnregisteredFacetAndSelectors();\n\n /**\n * @notice Modifier to only allow guardian to make a call, reverts if any other entity is the caller\n */\n modifier onlyGuardian() {\n if (!LibGuardian.isGuardian(msg.sender)) revert CallerNotGuardian();\n _;\n }\n\n /**\n * @notice Modifier to only allow guardian or owner to make a call, reverts if any other entity is the caller\n */\n modifier onlyGuardianOrOwner() {\n if (!LibGuardian.isGuardian(msg.sender) && address(this) != msg.sender)\n revert CallerNotGuardianOrOwner();\n _;\n }\n\n /**\n * @notice Checks if the approver address is the array is unique with no duplicate\n * @dev This method loops through the array and checks if a duplicate address exists, it reverts if duplicate address exists\n * @param approvers Array of address\n */\n function _checkApprover(\n address[] memory approvers\n ) internal pure returns (bool) {\n uint256 approverLength = approvers.length;\n if (0 == approverLength) revert ZeroApproverLength();\n for (uint256 i; i < approverLength - 1; ) {\n for (uint256 j = i + 1; j < approverLength; ) {\n if (approvers[i] == approvers[j]) {\n revert DuplicateApprover(); // Found a duplicate\n }\n unchecked {\n ++j;\n }\n }\n unchecked {\n ++i;\n }\n }\n return false; // No duplicates found\n }\n\n /**\n * @notice Checks if the facet getting added or replaced is registered to facet registry\n * @dev This method loops through the cut and checks if the facet getting added/replaced is registered to facet registry\n * @param _diamondCut Array of FacetCut, data for diamondCut defined in EIP-2535\n */\n function _checkFacetCutValidity(\n IDiamondCut.FacetCut[] memory _diamondCut\n ) internal view {\n uint256 diamondCutLength = _diamondCut.length;\n for (uint256 i; i < diamondCutLength; ) {\n if (\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Add ||\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Replace\n ) {\n if (\n !s.facetRegistry.areFacetFunctionSelectorsRegistered(\n _diamondCut[i].facetAddress,\n _diamondCut[i].functionSelectors\n )\n ) revert UnregisteredFacetAndSelectors();\n }\n unchecked {\n ++i;\n }\n }\n }\n}\n" + }, + "contracts/facets/RestrictionsFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, RestrictionsStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {IRestriction} from \"../restrictions/IRestriction.sol\";\nimport {IRestrictionsFacet} from \"./interfaces/IRestrictionsFacet.sol\";\n\n/**\n * @title Restrictions facet\n * @dev Responsible for storing and verifying different kinds of restrictions, for example:\n * - Whitelist / Blacklist\n * - Daily limits\n * - Trading time restrictions\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract RestrictionsFacet is IRestrictionsFacet {\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceRestrictionsInitialize();\n }\n\n /**\n * @notice Intialize restrictions of Barz. Restrictions facet call restriction contracts for restriction validation\n * before each call\n * @param _restrictions The initial array of restrictions.\n * @return initSuccess Int value showing if the initialization of restriction is successful\n */\n function initializeRestrictions(\n address[] calldata _restrictions\n ) public override returns (uint256 initSuccess) {\n LibDiamond.enforceIsSelf();\n LibAppStorage.enforceRestrictionsInitialize();\n\n uint256 restrictionsLength = _restrictions.length;\n if (restrictionsLength == 0) {\n // You can't initialize RestrictionsFacet with an empty list of restrictions\n revert RestrictionsFacet__EmptyRestrictionsList();\n }\n for (uint256 i; i < restrictionsLength; ) {\n if (_restrictions[i] == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictions();\n unchecked {\n ++i;\n }\n }\n\n LibFacetStorage.restrictionsStorage().restrictions = _restrictions;\n _updateRestrictionsMap(_restrictions, true);\n initSuccess = 1;\n }\n\n /**\n * @notice Unitialize restrictions of Barz\n * @return uninitSuccess Int value showing if the initialization of restriction is successful\n */\n function uninitializeRestrictions()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibDiamond.enforceIsSelf();\n LibAppStorage.setRestrictionsUninitialized();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n _updateRestrictionsMap(restrictionsStorage.restrictions, false);\n restrictionsStorage.restrictions = new address[](0);\n uninitSuccess = 1;\n }\n\n /**\n * @notice Returns the list of Restrictions contract address\n * @return restrictions Addresses of IRestriction which are currently active\n */\n function getRestrictions()\n public\n view\n override\n returns (address[] memory restrictions)\n {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n restrictions = restrictionsStorage.restrictions;\n }\n\n /**\n * @notice Adds restrictions to Barz with validation on the restriction contract address.\n * This method is only callable by the owner(self).\n * @param _restriction The address of the restriction to be added.\n */\n function addRestriction(address _restriction) external override {\n LibDiamond.enforceIsSelf();\n if (LibDiamond.restrictionsFacet() == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictionsFacet();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n if (_restriction == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictions();\n if (restrictionsStorage.exists[_restriction])\n revert RestrictionsFacet__RestrictionAlreadyExists();\n\n restrictionsStorage.restrictions.push(_restriction);\n restrictionsStorage.exists[_restriction] = true;\n\n emit RestrictionAdded(_restriction);\n }\n\n /**\n * @notice Remove restrictions from Barz if it existed. This method is only callable by the owner(self).\n * @param _restriction The address of the restriction to be removed.\n */\n function removeRestriction(address _restriction) external override {\n LibDiamond.enforceIsSelf();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n if (!restrictionsStorage.exists[_restriction])\n revert RestrictionsFacet__RestrictionNotFound();\n\n address[] storage restrictions = restrictionsStorage.restrictions;\n\n uint256 indexToDelete = restrictions.length;\n uint256 restrictionsLen = restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n if (restrictions[i] == _restriction) {\n indexToDelete = i;\n break;\n }\n unchecked {\n ++i;\n }\n }\n\n if (indexToDelete == 0 && restrictionsLen == 1) {\n revert RestrictionsFacet__RemainingRestrictionsCantBeEmpty();\n } else if (indexToDelete == restrictionsLen) {\n revert RestrictionsFacet__RestrictionNotFound();\n } else {\n restrictions[indexToDelete] = restrictions[restrictionsLen - 1];\n restrictions.pop();\n }\n\n restrictionsStorage.exists[_restriction] = false;\n emit RestrictionRemoved(_restriction);\n }\n\n /**\n * @notice Sets the restrictions address value mapping to true or false when adding/removing restriction contracts\n * @param _restrictions List of restriction contracts address\n * @param _newValue Bool value to flag to the list of restrictions contracts\n */\n function _updateRestrictionsMap(\n address[] memory _restrictions,\n bool _newValue\n ) internal {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n uint restrictionsLen = _restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n restrictionsStorage.exists[_restrictions[i]] = _newValue;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @dev Iterates over all restrictions and verifies each of them with the transaction parameters.\n * @param _from The address of the sender, that will be signing the transaction.\n * @param _to The receiving address.\n * @param _value Amount of ETH to transfer from sender to recipient.\n * @param _calldata Optional field to include arbitrary data.\n * @return 0 if all the checks passed, 1 otherwise.\n */\n function verifyRestrictions(\n address _from,\n address _to,\n uint256 _value,\n bytes calldata _calldata\n ) external returns (uint256) {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n uint restrictionsLen = restrictionsStorage.restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n IRestriction restriction = IRestriction(\n restrictionsStorage.restrictions[i]\n );\n bool checkPassed = restriction.check(_from, _to, _value, _calldata);\n if (!checkPassed) {\n return 1;\n }\n unchecked {\n ++i;\n }\n }\n\n return 0;\n }\n}\n" + }, + "contracts/facets/SignatureMigrationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, SignatureMigrationStorage, SignatureMigrationConfig, SignatureMigrationApprovalConfig, ApprovalConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IDiamondCut} from \"./base/interfaces/IDiamondCut.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {ISignatureMigrationFacet} from \"./interfaces/ISignatureMigrationFacet.sol\";\n\n/**\n * @title Signature Migration Facet\n * @dev Responsible for migrating user signature scheme to a new scheme user sets\n * Which could include\n * - ECDSA on Secp256K1 Curve\n * - ECDSA on Secp256R1 Curve\n * - BLS, Schnorr, etc\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract SignatureMigrationFacet is ISignatureMigrationFacet, Modifiers {\n /**\n * @notice This modifier verifies if the public key format matches with the new verification facet\n * @param _publicKey Bytes of public key to be validated for the new verification facet\n * @param _newVerificationFacet Address of new verification facet\n */\n modifier validateKeyType(\n bytes memory _publicKey,\n address _newVerificationFacet\n ) {\n if (\n !IVerificationFacet(_newVerificationFacet).isValidKeyType(\n _publicKey\n )\n ) revert SignatureMigrationFacet__InvalidKeyType();\n _;\n }\n\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n // IMPORTANT NOTE: In the client side when they call this function, the func selectors should be sorted in ascending order\n // to prevent different hash with same items in the array\n /**\n * @notice Moves the state of migration to a pending state. When pending state is over after pending period time,\n * Migration can be finalized. This function can only be called by self and when the account is unlocked.\n * @dev This method checks if the caller is self and if guardians exists. It migrates signature request to a pending state\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function migrateSignatureScheme(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n public\n override\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n // Only self contract can call this function\n LibDiamond.enforceIsSelf();\n // Should revert if guardian exist\n if (0 != LibGuardian.guardianCount())\n revert SignatureMigrationFacet__InvalidRouteWithGuardian();\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n // NOTE: Migration requires a pending period & confirmation from owner to prevent a\n // single call changing the ownership of the wallet\n /**\n * @notice Migrate signature scheme when guardians exists. Verifies the signature of guardians and moves migration to pending state.\n * Which can then be finalized when pending period is over. Owner's approval is mandatory for migration to happen\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _approvers List of approvers. This could include owner\n */\n function migrateSignatureSchemeWithGuardian(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n )\n public\n override\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n // Should revert if does not guardian exist\n if (0 == LibGuardian.guardianCount())\n revert SignatureMigrationFacet__InvalidRouteWithGuardian();\n uint256 approversLength = _approvers.length;\n if (approversLength != _signatures.length)\n revert SignatureMigrationFacet__InvalidArrayLength();\n\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(migrationPublicKeyHash, _approvers);\n\n bool onChainOwnerApproval = getMigrationOwnerApprovalWithTimeValidity(\n migrationPublicKeyHash\n );\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n\n if (\n approversLength +\n getMigrationApprovalCountWithTimeValidity(\n migrationPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert SignatureMigrationFacet__InsufficientApprovers();\n {\n // To prevent Stack too deep\n bool ownerApproved;\n for (uint256 i; i < approversLength; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n address(this) != _approvers[i]\n ) revert SignatureMigrationFacet__InvalidGuardian();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert SignatureMigrationFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n migrationPublicKeyHash,\n _signatures[i]\n )\n ) revert SignatureMigrationFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n\n if (!ownerApproved && !onChainOwnerApproval)\n revert SignatureMigrationFacet__LackOfOwnerApproval();\n }\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Internal function that moves signature mgiration to a pending state.\n * @dev This method increments migration nonce and sets the migration in the migration config. Emits events for migration execution\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _migrateSignatureScheme(\n address _newVerificationFacet,\n bytes memory _newPublicKey,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal {\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n\n ++ms.nonce;\n uint64 migrateAfter = uint64(block.timestamp + getMigrationPeriod());\n\n ms.migrationConfigs[INNER_STRUCT] = SignatureMigrationConfig(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n migrateAfter\n );\n\n emit SignatureMigrationExecuted(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors,\n migrateAfter\n );\n }\n\n /**\n * @notice Approves signature scheme migration on-chain. This can be called by owner or guardian only when the account is unlocked.\n * When the threshold of the migration approval passed and owner approval is granted, it automatically moves migration to a pending state\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function approveSignatureSchemeMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n public\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit SignatureMigrationApproved(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n msg.sender,\n approvalValidUntil\n );\n if (\n getMigrationApprovalCountWithTimeValidity(migrationPublicKeyHash) >=\n LibGuardian.majorityOfGuardians() &&\n getMigrationOwnerApprovalWithTimeValidity(migrationPublicKeyHash)\n )\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Revokes the approval of signature migration done on-chain. Emits revoke event when revoked.\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function revokeSignatureMigrationApproval(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n external\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n if (!isMigrationApproved(migrationPublicKeyHash, msg.sender))\n revert SignatureMigrationFacet__CannotRevokeUnapproved();\n\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(false, 0);\n emit SignatureMigrationApprovalRevoked(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n msg.sender\n );\n }\n\n /**\n * @notice Finalizes the pending signature scheme migration. This function can only be called by owner.\n * It removes the facets of the previous verification facet and adds the new verification facet.\n * After finalizing migration, it emits migration event which shows the change of the verification facet\n */\n function finalizeSignatureMigration() external override {\n // NOTE: Only owner can call this function\n LibDiamond.enforceIsSelf();\n\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n\n if (!isMigrationPending())\n revert SignatureMigrationFacet__NonexistentMigration();\n\n if (\n uint64(block.timestamp) <=\n ms.migrationConfigs[INNER_STRUCT].migrateAfter\n ) revert SignatureMigrationFacet__MigrationPeriodNotOver();\n address newVerificationFacet = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationVerificationFacet;\n bytes4[] memory newVerificationFuncSelectors = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationSelectors;\n bytes memory newPublicKey = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationPublicKey;\n\n address prevVerificationFacet = LibLoupe.facetAddress(\n s.validateOwnerSignatureSelector\n );\n if (prevVerificationFacet == address(0))\n revert SignatureMigrationFacet__NonExistentVerificationFacet();\n\n IDiamondCut.FacetCut[] memory UninitCut;\n IDiamondCut.FacetCut[] memory InitCut;\n {\n bytes4[] memory prevVerificationFuncSelectors = LibLoupe\n .facetFunctionSelectors(prevVerificationFacet);\n\n UninitCut = new IDiamondCut.FacetCut[](1);\n InitCut = new IDiamondCut.FacetCut[](1);\n UninitCut[0] = IDiamondCut.FacetCut({\n facetAddress: address(0),\n action: IDiamondCut.FacetCutAction.Remove,\n functionSelectors: prevVerificationFuncSelectors\n });\n InitCut[0] = IDiamondCut.FacetCut({\n facetAddress: newVerificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: newVerificationFuncSelectors\n });\n {\n IDiamondCut.FacetCut[]\n memory facetCuts = new IDiamondCut.FacetCut[](2);\n facetCuts[0] = UninitCut[0];\n facetCuts[1] = InitCut[0];\n _checkFacetCutValidity(facetCuts);\n }\n LibAppStorage.initiateSignerMigration();\n address verificationFacet = address(\n bytes20(\n LibDiamond.diamondStorage().facets[\n s.validateOwnerSignatureSelector\n ]\n )\n );\n bytes memory uninitCall = abi.encodeWithSignature(\n \"uninitializeSigner()\"\n );\n (bool success, bytes memory result) = verificationFacet\n .delegatecall(uninitCall);\n require(success, \"MigrationFacet: uninitialize not successful\");\n uint256 validationData = uint256(bytes32(result));\n if (validationData == 0)\n revert SignatureMigrationFacet__SignerUninitializationFailure();\n\n LibDiamond.diamondCut(UninitCut, address(0), \"\");\n }\n {\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n newPublicKey\n );\n\n // Every Verification Facet should comply with initializeSigner(bytes)\n // to be compatible with the Barz contract(for initialization)\n LibDiamond.diamondCut(InitCut, newVerificationFacet, initCall);\n LibAppStorage.finalizeSignerMigration();\n emit SignatureSchemeMigration(\n prevVerificationFacet,\n newVerificationFacet,\n newPublicKey,\n newVerificationFuncSelectors\n );\n }\n }\n\n /**\n * @notice Approve cancellation of signature migration. If cancellation approval passes guardian threshold with owner approval\n * it automatically cancels the migration.\n * @dev This method checks if the caller is one of guardian or owner and sets true for the cancellation hash in the approval config.\n * It internally calls _cancelSignatureMigration for canceling the migration\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function approveCancelSignatureMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n external\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"CancelSignatureMigration\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit SignatureMigrationCancellationApproved(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n if (\n getMigrationApprovalCountWithTimeValidity(migrationPublicKeyHash) >=\n LibGuardian.majorityOfGuardians() &&\n getMigrationOwnerApprovalWithTimeValidity(migrationPublicKeyHash)\n )\n _cancelSignatureMigration(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Verifies the signature of guardians/owner and cancels the signature migration.\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _approvers List of approvers. This could include owner\n */\n function cancelSignatureMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n )\n external\n override\n validateKeyType(_newPublicKey, _newVerificationFacet)\n onlyWhenUnlocked\n {\n uint256 approversLength = _approvers.length;\n if (approversLength != _signatures.length)\n revert SignatureMigrationFacet__InvalidArrayLength();\n\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"CancelSignatureMigration\"\n );\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(migrationPublicKeyHash, _approvers);\n\n bool onChainOwnerApproval = getMigrationOwnerApprovalWithTimeValidity(\n migrationPublicKeyHash\n );\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n if (\n approversLength +\n getMigrationApprovalCountWithTimeValidity(\n migrationPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert SignatureMigrationFacet__InsufficientApprovers();\n {\n // To prevent stack too deep\n bool ownerApproved;\n for (uint256 i; i < approversLength; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n address(this) != _approvers[i]\n ) revert SignatureMigrationFacet__NonExistentApprover();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert SignatureMigrationFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n migrationPublicKeyHash,\n _signatures[i]\n )\n ) revert SignatureMigrationFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n if (!ownerApproved && !onChainOwnerApproval)\n revert SignatureMigrationFacet__LackOfOwnerApproval();\n }\n _cancelSignatureMigration(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Internal function that cancels signature migration.\n * @dev This method increments migration nonce and deletes the migration from the migration config. Emits events for migration cancellation\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _cancelSignatureMigration(\n address _newVerificationFacet,\n bytes memory _newPublicKey,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal {\n if (!isMigrationPending())\n revert SignatureMigrationFacet__NonexistentMigration();\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n ++ms.nonce;\n delete ms.migrationConfigs[INNER_STRUCT];\n emit SignatureMigrationCanceled(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Checks if the facets to be added from new verification facet is registered to facet registry\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _checkMigrationCutValidity(\n address _newVerificationFacet,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal view {\n IDiamondCut.FacetCut[] memory facetCuts = new IDiamondCut.FacetCut[](1);\n facetCuts[0] = IDiamondCut.FacetCut({\n facetAddress: _newVerificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: _newVerificationFuncSelectors\n });\n _checkFacetCutValidity(facetCuts);\n }\n\n /**\n * @notice Returns if the migration is pending of not\n * @dev This method fetches the migration storage and checks if the migrate after is above 0 value\n * @return isPending Bool value that shows if the migration is pending\n */\n function isMigrationPending()\n public\n view\n override\n returns (bool isPending)\n {\n SignatureMigrationStorage storage rs = LibFacetStorage\n .migrationStorage();\n isPending = rs.migrationConfigs[INNER_STRUCT].migrateAfter > 0;\n }\n\n /**\n * @notice Returns the migration hash. This function ensures that this hash is safe from replay attack by including\n * public key, verification facet, function selectors, salt, address, chainId, and nonce.\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _saltString Salt value for generating the migration hash\n * @return migrationKeyHash Bytes32 string of the migration key hash\n */\n function getApprovalMigrationKeyHash(\n bytes memory _newPublicKey,\n address _newVerificationFacet,\n bytes4[] memory _newVerificationFuncSelectors,\n string memory _saltString\n ) public view override returns (bytes32 migrationKeyHash) {\n migrationKeyHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n _newPublicKey,\n _newVerificationFacet,\n keccak256(abi.encode(_newVerificationFuncSelectors)),\n _saltString,\n address(this),\n block.chainid,\n LibFacetStorage.migrationStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Checks if the owner approved the hash for migration\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @return isApprovedByOwner Bool value of showing if the owner approved it or not\n */\n function getMigrationOwnerApprovalWithTimeValidity(\n bytes32 _migrationPublicKeyHash\n ) public view override returns (bool isApprovedByOwner) {\n isApprovedByOwner = isMigrationApproved(\n _migrationPublicKeyHash,\n address(this)\n );\n }\n\n /**\n * @notice Checks how many of the guardians approved the migration hash\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @return approvalCount Number of approvals\n */\n function getMigrationApprovalCountWithTimeValidity(\n bytes32 _migrationPublicKeyHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardiansLength = guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n if (isMigrationApproved(_migrationPublicKeyHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n return approvalCount;\n }\n\n /**\n * @notice Checks if the migration is approved by the given approver\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @param _approver Address of approver\n * @return isApproved Bool value if migration hash is approved\n */\n function isMigrationApproved(\n bytes32 _migrationPublicKeyHash,\n address _approver\n ) public view override returns (bool isApproved) {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n isApproved = (ms\n .isMigrationApproved[_migrationPublicKeyHash][_approver].isApproved &&\n block.timestamp <\n ms\n .isMigrationApproved[_migrationPublicKeyHash][_approver]\n .validUntil);\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _migrationPublicKeyHash Hash of migration information\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _migrationPublicKeyHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isMigrationApproved(_migrationPublicKeyHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert SignatureMigrationFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the migration period of this wallet\n * @dev This method fetches the migration period from the security manager\n * @return migrationPeriod Migration period of Barz contract fetched from security manager\n */\n function getMigrationPeriod()\n internal\n view\n returns (uint128 migrationPeriod)\n {\n migrationPeriod = securityManager.migrationPeriodOf(address(this));\n if (migrationPeriod == 0)\n revert SignatureMigrationFacet__InvalidMigrationPeriod();\n }\n\n /**\n * @notice Returns the validation period of this wallet\n * @dev This method fetches the validation period from the security manager\n * @return approvalValidationPeriod Validation period of Barz contract fetched from security manager\n */\n function getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod == 0)\n revert SignatureMigrationFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the migration nonce of this wallet\n * @dev This method fetches the nonce from migration storage\n * @return migrationNonce Nonce of migration to protect from reply attacks\n */\n function getMigrationNonce()\n public\n view\n override\n returns (uint128 migrationNonce)\n {\n migrationNonce = LibFacetStorage.migrationStorage().nonce;\n }\n\n /**\n * @notice Returns the migration configuration of this wallet\n * @dev This method fetches the migration config from the migration storage\n * @return pendingMigrationConfig Migration config currently pending for signature migration\n */\n function getPendingMigration()\n external\n view\n override\n returns (SignatureMigrationConfig memory pendingMigrationConfig)\n {\n pendingMigrationConfig = LibFacetStorage\n .migrationStorage()\n .migrationConfigs[INNER_STRUCT];\n }\n}\n" + }, + "contracts/facets/TokenReceiverFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {IERC1155Receiver} from \"../interfaces/ERC/IERC1155Receiver.sol\";\nimport {IERC677Receiver} from \"../interfaces/ERC/IERC677Receiver.sol\";\n\n/**\n * @title TokenReceiver Facet\n * @dev Contract that enables receiving ERC721/ERC1155/ERC777/ERC677 Tokens with safe transfer\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract TokenReceiverFacet is\n IERC721Receiver,\n IERC1155Receiver,\n IERC777Recipient,\n IERC677Receiver\n{\n /**\n * @notice Handles ERC721 Token callback.\n * return Standardized onERC721Received return value.\n */\n function onERC721Received(\n address,\n address,\n uint256,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC721Receiver.onERC721Received.selector;\n }\n\n /**\n * @notice Handles ERC1155 Token callback.\n * return Standardized onERC1155Received return value.\n */\n function onERC1155Received(\n address,\n address,\n uint256,\n uint256,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC1155Receiver.onERC1155Received.selector;\n }\n\n /**\n * @notice Handles ERC1155 Token batch callback.\n * return Standardized onERC1155BatchReceived return value.\n */\n function onERC1155BatchReceived(\n address,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC1155Receiver.onERC1155BatchReceived.selector;\n }\n\n /**\n * @notice Handles ERC777 Token callback.\n * Does not return value, empty implementation.\n */\n function tokensReceived(\n address,\n address,\n address,\n uint256,\n bytes calldata,\n bytes calldata\n ) external pure override {}\n\n /**\n * @notice Handles ERC677 Token callback.\n * return true.\n */\n function onTokenTransfer(\n address,\n uint256,\n bytes calldata\n ) external pure override returns (bool) {\n return true;\n }\n}\n" + }, + "contracts/facets/verification/MultiSigFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {UserOperation} from \"../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../../libraries/LibLoupe.sol\";\nimport {LibAppStorage} from \"../../libraries/LibAppStorage.sol\";\nimport {LibMultiSigStorage, MultiSigStorage} from \"../../libraries/LibMultiSigStorage.sol\";\nimport {IERC1271} from \"../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../interfaces/IVerificationFacet.sol\";\nimport {IMultiSigFacet} from \"../interfaces/IMultiSigFacet.sol\";\n\n/**\n * @title Multi-sig facet\n * @dev Multi-signature Facet with custom threshold.\n * Wallet that adds this facet becomes a multi-sig wallet.\n * Reference signature_format.md documentation for Multi-sig facet details\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract MultiSigFacet is IMultiSigFacet, IVerificationFacet, IERC1271 {\n using ECDSA for bytes32;\n\n address public immutable self;\n\n address internal constant SENTINEL_OWNERS = address(0x1);\n uint256 internal constant ADDRESS = 20;\n uint256 internal constant SIG_TYPE = 1;\n uint256 internal constant SIG_LEN = 4;\n uint256 internal constant THRESHOLD = 4;\n uint256 internal constant INVALID_SIG = 1;\n uint256 internal constant VALID_SIG = 0;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in Multisig Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the right format and initializes signer storage in k1 storage.\n * @param _owners Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _owners\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n\n if (!isValidKeyType(_owners)) revert MultiSigFacet__InvalidInitData();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n uint256 threshold = uint256(uint32(bytes4(_owners)));\n uint256 ownerCount = (_owners.length - THRESHOLD) / ADDRESS;\n\n if (threshold == 0) revert MultiSigFacet__InvalidThreshold();\n if (ownerCount == 0) revert MultisigFacet__InvalidOwnerCount();\n\n address currentOwner = SENTINEL_OWNERS;\n uint256 ptr = THRESHOLD;\n address owner_;\n for (uint256 i; i < ownerCount; ) {\n owner_ = address(bytes20(_owners[ptr:ptr + ADDRESS]));\n ptr += ADDRESS;\n if (\n owner_ == address(0) ||\n owner_ == SENTINEL_OWNERS ||\n owner_ == address(this) ||\n owner_ == currentOwner\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[owner_] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n\n ms.owners[currentOwner] = owner_;\n currentOwner = owner_;\n\n unchecked {\n ++i;\n }\n }\n ms.owners[currentOwner] = SENTINEL_OWNERS;\n ms.ownerCount = ownerCount;\n ms.threshold = threshold;\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_owners);\n }\n\n /**\n * @notice Uninitialize signer in K1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n ++ms.counter;\n address[] memory ownerlist = getOwners();\n uint256 ownerlistLength = ownerlist.length;\n for (uint256 i; i < ownerlistLength; ) {\n ms.owners[ownerlist[i]] = address(0);\n unchecked {\n ++i;\n }\n }\n ms.owners[SENTINEL_OWNERS] = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls checkSignatures with\n * user operation hash and signature together with the threshold.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n // Data 1 is invalid, Data 0 is valid\n validationData = checkSignatures(\n userOpHash,\n userOp.signature,\n LibMultiSigStorage.multisigStorage().threshold\n );\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n return this.validateOwnerSignature.selector;\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n uint totalLength = ms.ownerCount * ADDRESS;\n bytes memory result = new bytes(totalLength);\n\n // populate return array\n uint256 index;\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n while (currentOwner != SENTINEL_OWNERS) {\n assembly {\n mstore(\n add(result, add(32, mul(index, ADDRESS))),\n shl(96, currentOwner)\n )\n }\n currentOwner = ms.owners[currentOwner];\n index++;\n }\n\n return result;\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key should comply with the format in the signature_format.md doc\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n uint256 publicKeyLength = _publicKey.length;\n if (\n publicKeyLength < ADDRESS + THRESHOLD ||\n (publicKeyLength - THRESHOLD) % ADDRESS != 0\n ) return false;\n\n uint256 threshold = uint256(uint32(bytes4(_publicKey)));\n uint256 ownerCount = (publicKeyLength - THRESHOLD) / ADDRESS;\n\n isValid = !(ownerCount < threshold || threshold == 0);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes calldata _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (checkSignatures(\n _hash,\n _signature,\n LibMultiSigStorage.multisigStorage().threshold\n ) == VALID_SIG)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n\n /**\n * @notice Validates the format of the signature and verifies if the signature is signed by the expected key.\n * Reference signature_format.md doc for details about signature format and signature types\n * @param _dataHash Bytes value of data hash signed by the owners\n * @param _signatures Bytes value of signature which should comply with signature format\n * @param _threshold Uint256 value of current Multi-sig Barz's threshold\n */\n function checkSignatures(\n bytes32 _dataHash,\n bytes calldata _signatures,\n uint256 _threshold\n ) public view returns (uint256) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n address lastOwner = address(0);\n address currentOwner;\n bytes memory signature;\n uint256 signatureType;\n uint256 nextOffset;\n uint256 i;\n for (i; i < _threshold; ) {\n (\n currentOwner,\n signature,\n signatureType,\n nextOffset\n ) = splitSignatures(_signatures, nextOffset);\n if (nextOffset == 0 && i + 1 < _threshold) return INVALID_SIG;\n if (signatureType == 1) {\n // If signatureType is 1 then it is default dataHash signed.\n // This also includes the contract signature\n if (\n !SignatureChecker.isValidSignatureNow(\n currentOwner,\n _dataHash,\n signature\n )\n ) return INVALID_SIG;\n } else if (signatureType == 2) {\n // If signatureType is 2 then it is an approved hash\n if (ms.approvedHashes[ms.counter][currentOwner][_dataHash] == 0)\n return INVALID_SIG;\n } else if (signatureType == 3) {\n // If signatureType is 3 then it is a signed message hash\n // This also includes the contract signature\n bytes32 msgHash = _dataHash.toEthSignedMessageHash();\n if (\n !SignatureChecker.isValidSignatureNow(\n currentOwner,\n msgHash,\n signature\n )\n ) return INVALID_SIG;\n } else revert MultiSigFacet__InvalidRoute();\n if (\n currentOwner <= lastOwner ||\n ms.owners[currentOwner] == address(0) ||\n currentOwner == SENTINEL_OWNERS\n ) return INVALID_SIG;\n lastOwner = currentOwner;\n\n unchecked {\n ++i;\n }\n }\n return VALID_SIG;\n }\n\n /**\n * @notice Split signatures into each individual signatures. Should comply with signature format to be split\n * @param _signatures Bytes value of signature\n * @param _nextOffset Uint256 value of next offset to start splitting the signature\n */\n function splitSignatures(\n bytes calldata _signatures,\n uint256 _nextOffset\n )\n public\n pure\n returns (\n address owner_,\n bytes memory signature,\n uint256 signatureType,\n uint256 nextOffset\n )\n {\n uint256 signaturesLength = _signatures.length;\n\n if (signaturesLength <= _nextOffset + ADDRESS + SIG_LEN)\n revert MultiSigFacet__InsufficientSignerLength();\n\n owner_ = address(\n bytes20(_signatures[_nextOffset:_nextOffset + ADDRESS])\n );\n\n signatureType = uint256(\n uint8(\n bytes1(\n _signatures[_nextOffset + ADDRESS:_nextOffset +\n ADDRESS +\n SIG_TYPE]\n )\n )\n );\n\n if (signatureType > 3 || signatureType == 0)\n revert MultiSigFacet__InvalidSignatureType();\n uint256 offSet = _nextOffset + ADDRESS + SIG_TYPE;\n uint256 siglen = uint256(\n uint32(bytes4(_signatures[offSet:offSet + SIG_LEN]))\n );\n if (offSet + siglen > signaturesLength)\n revert MultiSigFacet__InvalidSignatureLength();\n\n offSet += SIG_LEN;\n if (offSet + siglen == signaturesLength) nextOffset = 0;\n else nextOffset = offSet + siglen;\n\n signature = _signatures[offSet:offSet + siglen];\n }\n\n /**\n * @notice Approves the hash of userOperation on-chain. This can only be called by owners.\n * @param _hashToApprove Bytes value of UserOperation hash to approve\n */\n function approveHash(bytes32 _hashToApprove) external {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (ms.owners[msg.sender] == address(0))\n revert MultiSigFacet__OnlyOwner();\n\n ms.approvedHashes[ms.counter][msg.sender][_hashToApprove] = 1;\n emit HashApproved(_hashToApprove, msg.sender);\n }\n\n /**\n * @notice Add owner to Barz. Update thresold if threshold is given different from current threshold\n * @dev This can only be done via a Self call.\n * @param _newOwner Address of new owner to be added\n * @param _threshold Uint256 value of threshold\n */\n function addOwner(address _newOwner, uint256 _threshold) external {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (\n _newOwner == address(0) ||\n _newOwner == SENTINEL_OWNERS ||\n _newOwner == address(this)\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_newOwner] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n\n ms.owners[_newOwner] = ms.owners[SENTINEL_OWNERS];\n ms.owners[SENTINEL_OWNERS] = _newOwner;\n ++ms.ownerCount;\n emit OwnerAdded(_newOwner);\n\n if (ms.threshold != _threshold) changeThreshold(_threshold);\n }\n\n /**\n * @notice Remove owner from Barz. Update thresold if threshold is given different from current threshold\n * @dev This can only be done via a Self call.\n * @param _prevOwner Address of owner located right behind the removed owner address in the linked list\n * @param _removedOwner Address of owner to be removed\n * @param _threshold Uint256 value of threshold\n */\n function removeOwner(\n address _prevOwner,\n address _removedOwner,\n uint256 _threshold\n ) external {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (ms.ownerCount - 1 < _threshold)\n revert MultiSigFacet__InvalidThreshold();\n if (_removedOwner == address(0) || _removedOwner == SENTINEL_OWNERS)\n revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_prevOwner] != _removedOwner)\n revert MultiSigFacet__InvalidOwnerPair();\n\n ms.owners[_prevOwner] = ms.owners[_removedOwner];\n ms.owners[_removedOwner] = address(0);\n --ms.ownerCount;\n emit OwnerRemoved(_removedOwner);\n\n if (ms.threshold != _threshold) changeThreshold(_threshold);\n }\n\n /**\n * @notice Swap owner in Barz.\n * @dev This can only be done via a Self call.\n * @param _prevOwner Address of owner located right behind the removed owner address in the linked list\n * @param _oldOwner Address of owner to be removed\n * @param _newOwner Address of owner to be added\n */\n function swapOwner(\n address _prevOwner,\n address _oldOwner,\n address _newOwner\n ) public {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (\n _newOwner == address(0) ||\n _newOwner == SENTINEL_OWNERS ||\n _newOwner == address(this)\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_newOwner] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n if (_oldOwner == address(0) || _oldOwner == SENTINEL_OWNERS)\n revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_prevOwner] != _oldOwner)\n revert MultiSigFacet__InvalidOwnerPair();\n\n ms.owners[_newOwner] = ms.owners[_oldOwner];\n ms.owners[_prevOwner] = _newOwner;\n ms.owners[_oldOwner] = address(0);\n emit OwnerRemoved(_oldOwner);\n emit OwnerAdded(_newOwner);\n }\n\n /**\n * @notice Changes the threshold of the Barz to `_threshold`.\n * @dev This can only be done via a Self call.\n * @param _threshold New threshold\n */\n function changeThreshold(uint256 _threshold) public {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (_threshold > ms.ownerCount || _threshold == 0)\n revert MultiSigFacet__InvalidThreshold();\n\n ms.threshold = _threshold;\n emit ThresholdChanged(_threshold);\n }\n\n /**\n * @notice Checks if the given address is owner\n * @param _owner Address to be checked if it's owner\n * @return isOwner_ Bool value showing if it's owner address\n */\n function isOwner(address _owner) public view returns (bool isOwner_) {\n isOwner_ = (_owner != SENTINEL_OWNERS &&\n LibMultiSigStorage.multisigStorage().owners[_owner] != address(0));\n }\n\n /**\n * @notice Returns the threshold of Barz\n * @return threshold Threshold of the Barz account\n */\n function getThreshold() public view returns (uint256 threshold) {\n threshold = LibMultiSigStorage.multisigStorage().threshold;\n }\n\n /**\n * @notice Returns the list of owner addresses\n * @return owners List of owners\n */\n function getOwners() public view returns (address[] memory owners) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n owners = new address[](ms.ownerCount);\n\n uint256 index;\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n while (currentOwner != SENTINEL_OWNERS) {\n owners[index] = currentOwner;\n currentOwner = ms.owners[currentOwner];\n index++;\n }\n }\n\n /**\n * @notice Returns the previous owner in the linked list\n * @param _owner Address of owner\n * @return prevOwner Address of previous owner\n */\n function getPrevOwner(\n address _owner\n ) public view returns (address prevOwner) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n if (currentOwner == _owner) return SENTINEL_OWNERS;\n while (currentOwner != SENTINEL_OWNERS) {\n if (ms.owners[currentOwner] == _owner) return currentOwner;\n\n currentOwner = ms.owners[currentOwner];\n }\n return address(0);\n }\n\n /**\n * @notice Returns of the owner is approved by given owner address\n * @param _owner Address of owner\n * @param _hash Hash of UserOperation\n * @return isApproved Bool value showing if the hash is approved by owner\n */\n function isApprovedHash(\n address _owner,\n bytes32 _hash\n ) public view returns (bool isApproved) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n isApproved = (ms.approvedHashes[ms.counter][_owner][_hash] == 1);\n }\n}\n" + }, + "contracts/facets/verification/secp256k1/Secp256k1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {UserOperation} from \"../../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibAppStorage} from \"../../../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, Secp256k1VerificationStorage} from \"../../../libraries/LibFacetStorage.sol\";\nimport {LibLoupe} from \"../../../libraries/LibLoupe.sol\";\nimport {IERC1271} from \"../../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../../interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Secp256k1 verification facet\n * @dev Default Ethereum's elliptic curve\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract Secp256k1VerificationFacet is IVerificationFacet, IERC1271 {\n using ECDSA for bytes32;\n error Secp256k1VerificationFacet__InvalidSignerLength();\n address public immutable self;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in K1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\n * @param _publicKey Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _publicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n if (!isValidKeyType(_publicKey))\n revert Secp256k1VerificationFacet__InvalidSignerLength();\n\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(uint160(uint256(keccak256(_publicKey[1:]))));\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_publicKey);\n }\n\n /**\n * @notice Uninitialize signer in K1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\n * signer public key.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n validationData = validateSignature(\n userOp,\n userOpHash,\n k1Storage.signer\n );\n }\n\n /**\n * @notice Validates if the signature of UserOperation is signed by the given signer\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @param signer Address of signer who signed the contract, to be validated\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n address signer\n ) public pure returns (uint256 isValid) {\n bytes32 hash = userOpHash.toEthSignedMessageHash();\n isValid = (signer != hash.recover(userOp.signature)) ? 1 : 0;\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n ownerSignatureValidatorSelector = this.validateOwnerSignature.selector;\n // NOTE: The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory signer) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n signer = abi.encodePacked(k1Storage.signer);\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key length should be 65 in an uncompressed public key format\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (_hash.recover(_signature) ==\n LibFacetStorage.k1Storage().signer)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/Secp256r1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {UserOperation} from \"../../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibAppStorage} from \"../../../libraries/LibAppStorage.sol\";\nimport {LibLoupe} from \"../../../libraries/LibLoupe.sol\";\nimport {LibFacetStorage, Secp256r1VerificationStorage} from \"../../../libraries/LibFacetStorage.sol\";\nimport {Base64} from \"./utils/Base64.sol\";\nimport {LibSecp256r1} from \"./utils/LibSecp256r1.sol\";\nimport {IERC1271} from \"../../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../../interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Secp256r1 verification facet\n * @dev Primarily used to verify user ops signed with passkeys\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract Secp256r1VerificationFacet is IVerificationFacet, IERC1271 {\n error Secp256r1VerificationFacet__InvalidSignerLength();\n address public immutable self;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in R1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\n * @param _publicKey Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _publicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n\n if (!isValidKeyType(_publicKey))\n revert Secp256r1VerificationFacet__InvalidSignerLength();\n\n bytes memory publicKeyCoordinates = _publicKey[1:];\n uint256[2] memory q;\n assembly {\n // Copy the bytes from the input data into the uint256 array\n mstore(q, mload(add(publicKeyCoordinates, 32)))\n mstore(add(q, 32), mload(add(publicKeyCoordinates, 64)))\n }\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n r1Storage.q = q;\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_publicKey);\n }\n\n /**\n * @notice Uninitialize signer in R1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n r1Storage.q = [0, 0];\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\n * signer public key.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n validationData = validateSignature(userOp, userOpHash, r1Storage.q);\n }\n\n /**\n * @notice Validates if the signature of UserOperation is signed by the given signer\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @param q Public Key of signer who signed the contract, to be validated\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256[2] memory q\n ) public view returns (uint256 isValid) {\n isValid = (_validateSignature(q, userOpHash, userOp.signature)) ? 0 : 1;\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n return this.validateOwnerSignature.selector; // validateOwnerSignature(UserOperation calldata userOp,bytes32 userOpHash)\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory signer) {\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n signer = abi.encodePacked(r1Storage.q);\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key should in an uncompressed public key format\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = _validateSignature(\n LibFacetStorage.r1Storage().q,\n _hash,\n _signature\n )\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n\n function _validateSignature(\n uint256[2] memory q,\n bytes32 _hash,\n bytes memory _signature\n ) internal view returns (bool) {\n (\n uint256 rValue,\n uint256 sValue,\n bytes memory authenticatorData,\n string memory clientDataJSONPre,\n string memory clientDataJSONPost\n ) = abi.decode(_signature, (uint256, uint256, bytes, string, string));\n bytes32 clientHash;\n {\n string memory opHashBase64 = Base64.encode(bytes.concat(_hash));\n string memory clientDataJSON = string.concat(\n clientDataJSONPre,\n opHashBase64,\n clientDataJSONPost\n );\n clientHash = sha256(bytes(clientDataJSON));\n }\n bytes32 sigHash = sha256(bytes.concat(authenticatorData, clientHash));\n return LibSecp256r1.Verify(q, rValue, sValue, uint256(sigHash));\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/utils/Base64.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @dev Provides a set of functions to operate with Base64 strings.\n * modified for base64url https://datatracker.ietf.org/doc/html/rfc4648#section-5\n * _Available since v4.5._\n */\nlibrary Base64 {\n /**\n * @dev Base64 Encoding/Decoding Table\n */\n string internal constant _TABLE =\n \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_\";\n\n /**\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\n */\n function encode(bytes memory data) internal pure returns (string memory) {\n /**\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\n */\n if (data.length == 0) return \"\";\n\n // Loads the table into memory\n string memory table = _TABLE;\n\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\n // and split into 4 numbers of 6 bits.\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\n // - `data.length + 2` -> Round up\n // - `/ 3` -> Number of 3-bytes chunks\n // - `4 *` -> 4 characters for each chunk\n uint256 newlength = (data.length * 8) / 6;\n if (data.length % 6 > 0) {\n newlength++;\n }\n string memory result = new string(newlength);\n\n /// @solidity memory-safe-assembly\n assembly {\n // Prepare the lookup table (skip the first \"length\" byte)\n let tablePtr := add(table, 1)\n\n // Prepare result pointer, jump over length\n let resultPtr := add(result, 32)\n\n // Run over the input, 3 bytes at a time\n for {\n let dataPtr := data\n let endPtr := add(data, mload(data))\n } lt(dataPtr, endPtr) {\n\n } {\n // Advance 3 bytes\n dataPtr := add(dataPtr, 3)\n let input := mload(dataPtr)\n\n // To write each character, shift the 3 bytes (18 bits) chunk\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\n // and apply logical AND with 0x3F which is the number of\n // the previous character in the ASCII table prior to the Base64 Table\n // The result is then added to the table to get the character to write,\n // and finally write it in the result pointer but with a left shift\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(18, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(12, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(6, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n }\n }\n\n return result;\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/utils/LibSecp256r1.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n// Heavily inspired from\n// https://github.com/maxrobot/elliptic-solidity/blob/master/contracts/Secp256r1.sol\n// https://github.com/tdrerup/elliptic-curve-solidity/blob/master/contracts/curves/EllipticCurve.sol\n// modified to use precompile 0x05 modexp\n// and modified jacobian double\n// optimisations to avoid to an from from affine and jacobian coordinates\n\n// Additional Elliptic curve Public key / Signature validation added by\n// David Yonjun Kim (@Powerstream3604)\n\nstruct JPoint {\n uint256 x;\n uint256 y;\n uint256 z;\n}\n\nlibrary LibSecp256r1 {\n uint256 constant gx =\n 0x6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296;\n uint256 constant gy =\n 0x4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5;\n uint256 public constant pp =\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF;\n\n uint256 public constant nn =\n 0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551;\n uint256 constant a =\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC;\n uint256 constant b =\n 0x5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B;\n uint256 constant MOST_SIGNIFICANT =\n 0xc000000000000000000000000000000000000000000000000000000000000000;\n\n /*\n * Verify\n * @description - verifies that a public key has signed a given message\n * @param Q - public key coordinates X & Y\n * @param R - signature half R\n * @param S - signature half S\n * @param input - hashed message\n */\n function Verify(\n uint256[2] memory q,\n uint r,\n uint s,\n uint e\n ) internal view returns (bool) {\n if (q[0] > pp - 1 || q[1] > pp - 1) {\n return false;\n }\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\n return false;\n }\n if (\n mulmod(q[1], q[1], pp) !=\n addmod(\n addmod(\n mulmod(q[0], mulmod(q[0], q[0], pp), pp),\n mulmod(a, q[0], pp),\n pp\n ),\n b,\n pp\n )\n ) {\n return false;\n }\n\n JPoint[16] memory points = _preComputeJacobianPoints(q);\n return VerifyWithPrecompute(points, r, s, e);\n }\n\n function VerifyWithPrecompute(\n JPoint[16] memory points,\n uint r,\n uint s,\n uint e\n ) internal view returns (bool) {\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\n return false;\n }\n\n uint w = _primemod(s, nn);\n\n uint u1 = mulmod(e, w, nn);\n uint u2 = mulmod(r, w, nn);\n\n uint x;\n uint y;\n\n (x, y) = ShamirMultJacobian(points, u1, u2);\n return (x == r);\n }\n\n /*\n * Strauss Shamir trick for EC multiplication\n * https://stackoverflow.com/questions/50993471/ec-scalar-multiplication-with-strauss-shamir-method\n * we optimise on this a bit to do with 2 bits at a time rather than a single bit\n * the individual points for a single pass are precomputed\n * overall this reduces the number of additions while keeping the same number of doublings\n */\n function ShamirMultJacobian(\n JPoint[16] memory points,\n uint u1,\n uint u2\n ) internal view returns (uint, uint) {\n uint x = 0;\n uint y = 0;\n uint z = 0;\n uint bits = 128;\n uint index = 0;\n\n while (bits > 0) {\n if (z > 0) {\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\n }\n index =\n ((u1 & MOST_SIGNIFICANT) >> 252) |\n ((u2 & MOST_SIGNIFICANT) >> 254);\n if (index > 0) {\n (x, y, z) = _jAdd(\n x,\n y,\n z,\n points[index].x,\n points[index].y,\n points[index].z\n );\n }\n u1 <<= 2;\n u2 <<= 2;\n bits--;\n }\n (x, y) = _affineFromJacobian(x, y, z);\n return (x, y);\n }\n\n function _preComputeJacobianPoints(\n uint256[2] memory q\n ) internal pure returns (JPoint[16] memory points) {\n points[0] = JPoint(0, 0, 0);\n points[1] = JPoint(q[0], q[1], 1); // u2\n points[2] = _jPointDouble(points[1]);\n points[3] = _jPointAdd(points[1], points[2]);\n\n points[4] = JPoint(gx, gy, 1); // u1Points[1]\n points[5] = _jPointAdd(points[4], points[1]);\n points[6] = _jPointAdd(points[4], points[2]);\n points[7] = _jPointAdd(points[4], points[3]);\n\n points[8] = _jPointDouble(points[4]); // u1Points[2]\n points[9] = _jPointAdd(points[8], points[1]);\n points[10] = _jPointAdd(points[8], points[2]);\n points[11] = _jPointAdd(points[8], points[3]);\n\n points[12] = _jPointAdd(points[4], points[8]); // u1Points[3]\n points[13] = _jPointAdd(points[12], points[1]);\n points[14] = _jPointAdd(points[12], points[2]);\n points[15] = _jPointAdd(points[12], points[3]);\n }\n\n function _jPointAdd(\n JPoint memory p1,\n JPoint memory p2\n ) internal pure returns (JPoint memory) {\n uint x;\n uint y;\n uint z;\n (x, y, z) = _jAdd(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z);\n return JPoint(x, y, z);\n }\n\n function _jPointDouble(\n JPoint memory p\n ) internal pure returns (JPoint memory) {\n uint x;\n uint y;\n uint z;\n (x, y, z) = _modifiedJacobianDouble(p.x, p.y, p.z);\n return JPoint(x, y, z);\n }\n\n /* _affineFromJacobian\n * @desription returns affine coordinates from a jacobian input follows\n * golang elliptic/crypto library\n */\n function _affineFromJacobian(\n uint x,\n uint y,\n uint z\n ) internal view returns (uint ax, uint ay) {\n if (z == 0) {\n return (0, 0);\n }\n\n uint zinv = _primemod(z, pp);\n uint zinvsq = mulmod(zinv, zinv, pp);\n\n ax = mulmod(x, zinvsq, pp);\n ay = mulmod(y, mulmod(zinvsq, zinv, pp), pp);\n }\n\n /*\n * _jAdd\n * @description performs Jacobian addition as defined below:\n * http://www.hyperelliptic.org/EFD/g1p/data/shortw/jacobian/addition/add-2007-bl\n */\n function _jAdd(\n uint p1,\n uint p2,\n uint p3,\n uint q1,\n uint q2,\n uint q3\n ) internal pure returns (uint r1, uint r2, uint r3) {\n if (p3 == 0) {\n r1 = q1;\n r2 = q2;\n r3 = q3;\n\n return (r1, r2, r3);\n } else if (q3 == 0) {\n r1 = p1;\n r2 = p2;\n r3 = p3;\n\n return (r1, r2, r3);\n }\n\n assembly {\n let\n pd\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\n let z1z1 := mulmod(p3, p3, pd) // Z1Z1 = Z1^2\n let z2z2 := mulmod(q3, q3, pd) // Z2Z2 = Z2^2\n\n let u1 := mulmod(p1, z2z2, pd) // U1 = X1*Z2Z2\n let u2 := mulmod(q1, z1z1, pd) // U2 = X2*Z1Z1\n\n let s1 := mulmod(p2, mulmod(z2z2, q3, pd), pd) // S1 = Y1*Z2*Z2Z2\n let s2 := mulmod(q2, mulmod(z1z1, p3, pd), pd) // S2 = Y2*Z1*Z1Z1\n\n let p3q3 := addmod(p3, q3, pd)\n\n if lt(u2, u1) {\n u2 := add(pd, u2) // u2 = u2+pd\n }\n let h := sub(u2, u1) // H = U2-U1\n\n let i := mulmod(0x02, h, pd)\n i := mulmod(i, i, pd) // I = (2*H)^2\n\n let j := mulmod(h, i, pd) // J = H*I\n if lt(s2, s1) {\n s2 := add(pd, s2) // u2 = u2+pd\n }\n let rr := mulmod(0x02, sub(s2, s1), pd) // r = 2*(S2-S1)\n r1 := mulmod(rr, rr, pd) // X3 = R^2\n\n let v := mulmod(u1, i, pd) // V = U1*I\n let j2v := addmod(j, mulmod(0x02, v, pd), pd)\n if lt(r1, j2v) {\n r1 := add(pd, r1) // X3 = X3+pd\n }\n r1 := sub(r1, j2v)\n\n // Y3 = r*(V-X3)-2*S1*J\n let s12j := mulmod(mulmod(0x02, s1, pd), j, pd)\n\n if lt(v, r1) {\n v := add(pd, v)\n }\n r2 := mulmod(rr, sub(v, r1), pd)\n\n if lt(r2, s12j) {\n r2 := add(pd, r2)\n }\n r2 := sub(r2, s12j)\n\n // Z3 = ((Z1+Z2)^2-Z1Z1-Z2Z2)*H\n z1z1 := addmod(z1z1, z2z2, pd)\n j2v := mulmod(p3q3, p3q3, pd)\n if lt(j2v, z1z1) {\n j2v := add(pd, j2v)\n }\n r3 := mulmod(sub(j2v, z1z1), h, pd)\n }\n return (r1, r2, r3);\n }\n\n // Point doubling on the modified jacobian coordinates\n // http://point-at-infinity.org/ecc/Prime_Curve_Modified_Jacobian_Coordinates.html\n function _modifiedJacobianDouble(\n uint x,\n uint y,\n uint z\n ) internal pure returns (uint x3, uint y3, uint z3) {\n if (y == 0) return (0, 0, 0);\n assembly {\n let\n pd\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\n let z2 := mulmod(z, z, pd)\n let az4 := mulmod(\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC,\n mulmod(z2, z2, pd),\n pd\n )\n let y2 := mulmod(y, y, pd)\n let s := mulmod(0x04, mulmod(x, y2, pd), pd)\n let u := mulmod(0x08, mulmod(y2, y2, pd), pd)\n let m := addmod(mulmod(0x03, mulmod(x, x, pd), pd), az4, pd)\n let twos := mulmod(0x02, s, pd)\n let m2 := mulmod(m, m, pd)\n if lt(m2, twos) {\n m2 := add(pd, m2)\n }\n x3 := sub(m2, twos)\n if lt(s, x3) {\n s := add(pd, s)\n }\n y3 := mulmod(m, sub(s, x3), pd)\n if lt(y3, u) {\n y3 := add(pd, y3)\n }\n y3 := sub(y3, u)\n z3 := mulmod(0x02, mulmod(y, z, pd), pd)\n }\n }\n\n // Fermats little theorem https://en.wikipedia.org/wiki/Fermat%27s_little_theorem\n // a^(p-1) = 1 mod p\n // a^(-1) ≅ a^(p-2) (mod p)\n // we then use the precompile bigModExp to compute a^(-1)\n function _primemod(uint value, uint p) internal view returns (uint ret) {\n ret = modexp(value, p - 2, p);\n return ret;\n }\n\n // Wrapper for built-in BigNumber_modexp (contract 0x5) as described here. https://github.com/ethereum/EIPs/pull/198\n function modexp(\n uint _base,\n uint _exp,\n uint _mod\n ) internal view returns (uint ret) {\n // bigModExp(_base, _exp, _mod);\n assembly {\n if gt(_base, _mod) {\n _base := mod(_base, _mod)\n }\n // Free memory pointer is always stored at 0x40\n let freemem := mload(0x40)\n\n mstore(freemem, 0x20)\n mstore(add(freemem, 0x20), 0x20)\n mstore(add(freemem, 0x40), 0x20)\n\n mstore(add(freemem, 0x60), _base)\n mstore(add(freemem, 0x80), _exp)\n mstore(add(freemem, 0xa0), _mod)\n\n let success := staticcall(14000, 0x5, freemem, 0xc0, freemem, 0x20)\n switch success\n case 0 {\n revert(0x0, 0x0)\n }\n default {\n ret := mload(freemem)\n }\n }\n }\n}\n" + }, + "contracts/infrastructure/DefaultFallbackHandler.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC1155Receiver} from \"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\";\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {BaseAccount} from \"../aa-4337/core/BaseAccount.sol\";\nimport {DefaultLibDiamond} from \"../libraries/DefaultLibDiamond.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IAccountFacet} from \"../facets/interfaces/IAccountFacet.sol\";\nimport {IStorageLoupe} from \"../facets/base/interfaces/IStorageLoupe.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IERC677Receiver} from \"../interfaces/ERC/IERC677Receiver.sol\";\nimport {IERC165} from \"../interfaces/ERC/IERC165.sol\";\n\n/**\n * @title DefaultFallbackHandler\n * @dev A default fallback handler for Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DefaultFallbackHandler is IDiamondLoupe {\n /**\n * @notice Sets the middleware diamond for Barz wallet as a fallback handler\n * @dev This contract is also a diamond that holds the default facets to reduce gas cost for wallet activation.\n * Within the constructor this conducts diamond cut to initially setup the diamond. This is a non-upgradeable contract\n * @param _diamondCutFacet Address if diamond cut facet\n * @param _accountFacet Address account facet\n * @param _tokenReceiverFacet Address of token receiver facet\n * @param _diamondLoupeFacet Address of diamond loupe facet\n */\n constructor(\n address _diamondCutFacet,\n address _accountFacet,\n address _tokenReceiverFacet,\n address _diamondLoupeFacet\n ) payable {\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](4);\n bytes4[] memory functionSelectors = new bytes4[](1);\n functionSelectors[0] = IDiamondCut.diamondCut.selector;\n\n bytes4[] memory accountFunctionSelectors = new bytes4[](5);\n accountFunctionSelectors[0] = IAccountFacet.execute.selector;\n accountFunctionSelectors[1] = IAccountFacet.executeBatch.selector;\n accountFunctionSelectors[2] = BaseAccount.validateUserOp.selector;\n accountFunctionSelectors[3] = BaseAccount.getNonce.selector;\n accountFunctionSelectors[4] = BaseAccount.entryPoint.selector;\n\n bytes4[] memory receiverFacetSelectors = new bytes4[](5);\n receiverFacetSelectors[0] = IERC721Receiver.onERC721Received.selector;\n receiverFacetSelectors[1] = IERC1155Receiver.onERC1155Received.selector;\n receiverFacetSelectors[2] = IERC1155Receiver\n .onERC1155BatchReceived\n .selector;\n receiverFacetSelectors[3] = IERC777Recipient.tokensReceived.selector;\n receiverFacetSelectors[4] = IERC677Receiver.onTokenTransfer.selector;\n\n bytes4[] memory loupeFacetSelectors = new bytes4[](9);\n loupeFacetSelectors[0] = IDiamondLoupe.facets.selector;\n loupeFacetSelectors[1] = IDiamondLoupe.facetFunctionSelectors.selector;\n loupeFacetSelectors[2] = IDiamondLoupe.facetAddresses.selector;\n loupeFacetSelectors[3] = IDiamondLoupe.facetAddress.selector;\n loupeFacetSelectors[4] = IERC165.supportsInterface.selector;\n loupeFacetSelectors[5] = IStorageLoupe.facetsFromStorage.selector;\n loupeFacetSelectors[6] = IStorageLoupe\n .facetFunctionSelectorsFromStorage\n .selector;\n loupeFacetSelectors[7] = IStorageLoupe\n .facetAddressesFromStorage\n .selector;\n loupeFacetSelectors[8] = IStorageLoupe.facetAddressFromStorage.selector;\n\n {\n cut[0] = IDiamondCut.FacetCut({\n facetAddress: _diamondCutFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: functionSelectors\n });\n cut[1] = IDiamondCut.FacetCut({\n facetAddress: _accountFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: accountFunctionSelectors\n });\n cut[2] = IDiamondCut.FacetCut({\n facetAddress: _tokenReceiverFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: receiverFacetSelectors\n });\n cut[3] = IDiamondCut.FacetCut({\n facetAddress: _diamondLoupeFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: loupeFacetSelectors\n });\n\n DefaultLibDiamond.diamondCut(cut, address(0), \"\");\n }\n }\n\n /**\n * @notice Returns the facet information of call facets registered to this diamond.\n * @return facets_ The facet struct array including all facet information\n */\n function facets() external view override returns (Facet[] memory facets_) {\n DefaultLibDiamond.DiamondStorage storage ds = DefaultLibDiamond\n .diamondStorage();\n uint256 numFacets = ds.facetAddresses.length;\n facets_ = new Facet[](numFacets);\n for (uint256 i; i < numFacets; ) {\n address facetAddress_ = ds.facetAddresses[i];\n facets_[i].facetAddress = facetAddress_;\n facets_[i].functionSelectors = ds\n .facetFunctionSelectors[facetAddress_]\n .functionSelectors;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Gets all the function selectors provided by a facet.\n * @param _facet The facet address.\n * @return facetFunctionSelectors_\n */\n function facetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n facetFunctionSelectors_ = DefaultLibDiamond\n .diamondStorage()\n .facetFunctionSelectors[_facet]\n .functionSelectors;\n }\n\n /**\n * @notice Get all the facet addresses used by a diamond.\n * @return facetAddresses_\n */\n function facetAddresses()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n facetAddresses_ = DefaultLibDiamond.diamondStorage().facetAddresses;\n }\n\n /** @notice Gets the facet that supports the given selector.\n * @dev If facet is not found return address(0).\n * @param _functionSelector The function selector.\n * @return facetAddress_ The facet address.\n */\n function facetAddress(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n facetAddress_ = DefaultLibDiamond\n .diamondStorage()\n .selectorToFacetAndPosition[_functionSelector]\n .facetAddress;\n }\n}\n" + }, + "contracts/infrastructure/FacetRegistry.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport {IFacetRegistry} from \"./interfaces/IFacetRegistry.sol\";\n\n/**\n * @title Facet Registry\n * @dev Contract to keep track of facets & function selectors addable to user wallets\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract FacetRegistry is IFacetRegistry, Ownable2Step {\n mapping(address => FacetRegistryConfig) private facets;\n\n /**\n * @notice Transfers the ownership of the contract to the given owner\n * @param _owner Address of owner who has access to initialize the default security variables for security manager\n */\n constructor(address _owner) {\n transferOwnership(_owner);\n _transferOwnership(_owner);\n }\n\n /**\n * @dev Registers a facet and it's function selectors to registry\n * @param _facet address of facet\n * @param _facetSelectors list of function selectors of the facet\n */\n function registerFacetFunctionSelectors(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external override onlyOwner {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n uint256 facetSelectorsLength = _facetSelectors.length;\n for (uint256 i; i < facetSelectorsLength; ) {\n if (facetConfig.info[_facetSelectors[i]].exists)\n revert FacetRegistry__FacetSelectorAlreadyRegistered();\n\n facetConfig.info[_facetSelectors[i]].exists = true;\n facetConfig.info[_facetSelectors[i]].index = uint128(\n facetConfig.selectors.length\n );\n facetConfig.selectors.push(_facetSelectors[i]);\n unchecked {\n ++i;\n }\n }\n emit FacetFunctionSelectorsRegistered(_facet, _facetSelectors);\n }\n\n /**\n * @dev Removes a registered facet and it's corresponding selectors from registry\n * @param _facet address of facet\n * @param _facetSelectors list of function selectors of the facet\n */\n function removeFacetFunctionSelectors(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external override onlyOwner {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n uint256 facetSelectorsLength = _facetSelectors.length;\n for (uint256 i; i < facetSelectorsLength; ) {\n if (!facetConfig.info[_facetSelectors[i]].exists)\n revert FacetRegistry__UnregisteredFacetSelector();\n\n bytes4 lastSelector = facetConfig.selectors[\n facetConfig.selectors.length - 1\n ];\n if (_facetSelectors[i] != lastSelector) {\n uint128 targetIndex = facetConfig\n .info[_facetSelectors[i]]\n .index;\n facetConfig.selectors[targetIndex] = lastSelector;\n facetConfig.info[lastSelector].index = targetIndex;\n }\n facetConfig.selectors.pop();\n delete facetConfig.info[_facetSelectors[i]];\n\n unchecked {\n ++i;\n }\n }\n emit FacetFunctionSelectorsRemoved(_facet, _facetSelectors);\n }\n\n /**\n * @dev Checks if a facet and it's selectors given is registered to facet registry\n * @param _facet Address of facet\n * @param _facetSelectors List of function selectors of the facet\n */\n function areFacetFunctionSelectorsRegistered(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external view override returns (bool) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n uint256 facetSelectorsLength = _facetSelectors.length;\n if (facetSelectorsLength == 0) return false;\n for (uint256 i; i < facetSelectorsLength; ) {\n if (!facetConfig.info[_facetSelectors[i]].exists) return false;\n unchecked {\n ++i;\n }\n }\n return true;\n }\n\n /**\n * @dev Checks if a facet and it's selector given is registered to facet registry\n * @param _facet Address of facet\n * @param _facetSelector List of function selectors of the facet\n * @return isRegistered Bool value showing if the selector is registered\n */\n function isFacetFunctionSelectorRegistered(\n address _facet,\n bytes4 _facetSelector\n ) external view override returns (bool isRegistered) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n isRegistered = facetConfig.info[_facetSelector].exists;\n }\n\n /**\n * @dev Get the registered selectors of facet from registry\n * @param _facet Address of facet\n * @return selectors Selectors registered to facet\n */\n function getFacetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory selectors) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n selectors = facetConfig.selectors;\n }\n}\n" + }, + "contracts/infrastructure/interfaces/IFacetRegistry.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Registry Interface\n * @dev Interface for Facet Registry contract to keep track of facets & function selectors addable to user wallets\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IFacetRegistry {\n struct FacetRegistryConfig {\n bytes4[] selectors;\n mapping(bytes4 => FacetInfo) info;\n }\n struct FacetInfo {\n bool exists;\n uint128 index;\n }\n\n event FacetFunctionSelectorsRegistered(\n address facet,\n bytes4[] facetSelectors\n );\n event FacetFunctionSelectorsRemoved(address facet, bytes4[] facetSelectors);\n\n error FacetRegistry__FacetSelectorAlreadyRegistered();\n error FacetRegistry__UnregisteredFacetSelector();\n\n function registerFacetFunctionSelectors(\n address facet,\n bytes4[] calldata facetSelectors\n ) external;\n\n function removeFacetFunctionSelectors(\n address facet,\n bytes4[] calldata facetSelectors\n ) external;\n\n function areFacetFunctionSelectorsRegistered(\n address facet,\n bytes4[] calldata facetSelectors\n ) external view returns (bool);\n\n function isFacetFunctionSelectorRegistered(\n address facet,\n bytes4 facetSelector\n ) external view returns (bool);\n\n function getFacetFunctionSelectors(\n address facet\n ) external view returns (bytes4[] memory);\n}\n" + }, + "contracts/infrastructure/interfaces/ISecurityManager.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Registry Interface\n * @dev Infrastructure contract to manage security parameters of users\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface ISecurityManager {\n error SecurityManager__OutOfBoundary();\n error SecurityManager__CallerNotWallet();\n error SecurityManager__AlreadyIntialized();\n\n function initializeAdditionSecurityPeriod(\n uint128 defaultAdditionSecurityPeriod,\n uint128 minAdditionSecurityPeriod,\n uint128 maxAdditionSecurityPeriod\n ) external;\n\n function initializeRemovalSecurityPeriod(\n uint128 defaultRemovalSecurityPeriod,\n uint128 minRemovalSecurityPeriod,\n uint128 maxRemovalSecurityPeriod\n ) external;\n\n function initializeApprovalValidationPeriod(\n uint128 defaultApprovalValidationPeriod,\n uint128 minApprovalValidationPeriod,\n uint128 maxApprovalValidationPeriod\n ) external;\n\n function initializeMigrationPeriod(\n uint128 defaultMigrationPeriod,\n uint128 minMigrationPeriod,\n uint128 maxMigrationPeriod\n ) external;\n\n function initializeLockPeriod(\n uint128 defaultLockPeriod,\n uint128 minLockPeriod,\n uint128 maxLockPeriod\n ) external;\n\n function initializeRecoveryPeriod(\n uint128 defaultRecoveryPeriod,\n uint128 minRecoveryPeriod,\n uint128 maxRecoveryPeriod\n ) external;\n\n function initializeSecurityWindow(\n uint128 defaultSecurityWindow,\n uint128 minSecurityWindow,\n uint128 maxSecurityWindow\n ) external;\n\n function setAdditionSecurityPeriod(\n address wallet,\n uint128 additionSecurityPeriod\n ) external;\n\n function setRemovalSecurityPeriod(\n address wallet,\n uint128 removalSecurityPeriod\n ) external;\n\n function setSecurityWindow(address wallet, uint128 securityWindow) external;\n\n function setRecoveryPeriod(address wallet, uint128 recoveryPeriod) external;\n\n function setLockPeriod(address wallet, uint128 lockPeriod) external;\n\n function setApprovalValidationPeriod(\n address wallet,\n uint128 approvalValidationPeriod\n ) external;\n\n function setMigrationPeriod(\n address wallet,\n uint128 migrationPeriod\n ) external;\n\n function additionSecurityPeriodOf(\n address wallet\n ) external view returns (uint128);\n\n function removalSecurityPeriodOf(\n address wallet\n ) external view returns (uint128);\n\n function securityWindowOf(address wallet) external view returns (uint128);\n\n function recoveryPeriodOf(address wallet) external view returns (uint128);\n\n function lockPeriodOf(address wallet) external view returns (uint128);\n\n function migrationPeriodOf(address wallet) external view returns (uint128);\n\n function approvalValidationPeriodOf(\n address wallet\n ) external view returns (uint128);\n}\n" + }, + "contracts/infrastructure/RemoteStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IGuardianFacet} from \"../facets/interfaces/IGuardianFacet.sol\";\n\n/**\n * @title Remote Storage\n * @dev Remote storage allows you to associate addresses with an array of addresses on a standalone smart contract.\n * This could be useful when you don't want to use the local diamond storage for some purpose.\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\nabstract contract RemoteStorage {\n struct StorageConfig {\n address[] addresses;\n mapping(address => Info) info;\n }\n\n struct Info {\n bool exists;\n uint128 index;\n }\n\n mapping(address => StorageConfig) internal configs;\n\n event Added(address _address);\n event Removed(address _address);\n\n error RemoteStorage__CallerNotOwner();\n error RemoteStorage__CallerNotGuardianOrOwner();\n error RemoteStorage__AlreadyExists();\n error RemoteStorage__NotFound();\n error RemoteStorage__CallerNotGuardian();\n\n bytes4 constant IS_GUARDIAN_SELECTOR =\n bytes4(keccak256(\"isGuardian(address)\"));\n bytes4 constant GUARDIAN_COUNT = bytes4(keccak256(\"guardianCount()\"));\n\n /**\n * @notice Modifier to only allow the self to call. Reverts otherwise\n */\n modifier onlyWallet(address _wallet) {\n if (msg.sender != _wallet) revert RemoteStorage__CallerNotOwner();\n _;\n }\n\n /**\n * @notice Enfore the callet to be wallet of guardian of the wallet\n * @param _wallet Address of wallet\n */\n function enforceGuardianOrWallet(address _wallet) internal view {\n if (msg.sender == _wallet) return;\n address facetAddress = IDiamondLoupe(_wallet).facetAddress(\n IS_GUARDIAN_SELECTOR\n );\n if (facetAddress != address(0))\n if (IGuardianFacet(_wallet).isGuardian(msg.sender)) return;\n revert RemoteStorage__CallerNotGuardianOrOwner();\n }\n\n /**\n * @notice Enforce the caller to be wallet IF guardians doesn't exists and only guardian when guardians exists\n * @param _wallet Target wallet address to be handled by infrastructure contracts\n */\n function enforceWalletOrGuardianIfExists(address _wallet) internal view {\n address facetAddress;\n if (msg.sender == _wallet) {\n facetAddress = IDiamondLoupe(_wallet).facetAddress(GUARDIAN_COUNT);\n if (facetAddress == address(0)) return;\n uint256 guardianCount = IGuardianFacet(_wallet).guardianCount();\n if (guardianCount != 0) revert RemoteStorage__CallerNotGuardian();\n return;\n }\n facetAddress = IDiamondLoupe(_wallet).facetAddress(\n IS_GUARDIAN_SELECTOR\n );\n if (facetAddress != address(0))\n if (IGuardianFacet(_wallet).isGuardian(msg.sender)) return;\n\n revert RemoteStorage__CallerNotGuardianOrOwner();\n }\n\n /**\n * @notice Add address to storage and reverts if the address already exists.\n * This is an internal function callable from contracts that inherit this abstract contract\n * @param _wallet Address of wallet to add the address\n * @param _address Address to be added to wallet\n */\n function addAddress(address _wallet, address _address) internal {\n StorageConfig storage config = configs[_wallet];\n if (config.info[_address].exists) revert RemoteStorage__AlreadyExists();\n\n config.info[_address].exists = true;\n config.info[_address].index = uint128(config.addresses.length);\n config.addresses.push(_address);\n\n emit Added(_address);\n }\n\n /**\n * @notice Remove address from storage and reverts if the address already exists.\n * This is an internal function callable from contracts that inherit this abstract contract\n * @param _wallet Address of wallet to remove the address\n * @param _address Address to be removed from wallet\n */\n function removeAddress(address _wallet, address _address) internal {\n StorageConfig storage config = configs[_wallet];\n if (!config.info[_address].exists) revert RemoteStorage__NotFound();\n\n address lastAddress = config.addresses[config.addresses.length - 1];\n if (_address != lastAddress) {\n uint128 targetIndex = config.info[_address].index;\n config.addresses[targetIndex] = lastAddress;\n config.info[lastAddress].index = targetIndex;\n }\n config.addresses.pop();\n delete config.info[_address];\n\n emit Removed(_address);\n }\n\n /**\n * @notice Returns the address added to the given wallet\n * @param _wallet Address of wallet to fetch the addresses added to it\n * @return addresses List of addresses added to the wallet\n */\n function getAddresses(\n address _wallet\n ) internal view returns (address[] memory addresses) {\n StorageConfig storage config = configs[_wallet];\n addresses = new address[](config.addresses.length);\n uint addressesLen = config.addresses.length;\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns bool value checking if the address exists in the given wallet address\n * @param _wallet Wallet address to check\n * @param _address Address to fetch if the address if added to given wallet\n * @return exists_ Bool value showing if the address exists in wallet\n */\n function exists(\n address _wallet,\n address _address\n ) internal view returns (bool exists_) {\n exists_ = configs[_wallet].info[_address].exists;\n }\n\n /**\n * @notice Returns the number of addresses added to the wallet\n * @param _wallet Address of wallet to check\n * @return count_ Number of addresses added to wallet\n */\n function count(address _wallet) internal view returns (uint256 count_) {\n count_ = configs[_wallet].addresses.length;\n }\n}\n" + }, + "contracts/infrastructure/SecurityManager.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport {ISecurityManager} from \"./interfaces/ISecurityManager.sol\";\n\n/**\n * @title Security Manager\n * @dev Infrastructure contract to manage security parameters of users\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract SecurityManager is ISecurityManager, Ownable2Step {\n uint128 public minAdditionSecurityPeriod;\n uint128 public maxAdditionSecurityPeriod;\n uint128 private defaultAdditionSecurityPeriod;\n\n uint128 public minRemovalSecurityPeriod;\n uint128 public maxRemovalSecurityPeriod;\n uint128 private defaultRemovalSecurityPeriod;\n\n uint128 public minSecurityWindow;\n uint128 public maxSecurityWindow;\n uint128 private defaultSecurityWindow;\n\n uint128 public minRecoveryPeriod;\n uint128 public maxRecoveryPeriod;\n uint128 private defaultRecoveryPeriod;\n\n uint128 public minLockPeriod;\n uint128 public maxLockPeriod;\n uint128 private defaultLockPeriod;\n\n uint128 public minApprovalValidationPeriod;\n uint128 public maxApprovalValidationPeriod;\n uint128 private defaultApprovalValidationPeriod;\n\n uint128 public minMigrationPeriod;\n uint128 public maxMigrationPeriod;\n uint128 private defaultMigrationPeriod;\n\n bool public _isAdditionSecurityPeriodInitialized;\n bool public _isRemovalSecurityPeriodInitialized;\n bool public _isSecurityWindowInitialized;\n bool public _isRecoveryPeriodInitialized;\n bool public _isLockPeriodInitialized;\n bool public _isApprovalValidationPeriodInitialized;\n bool public _isMigrationPeriodInitialized;\n\n mapping(address => CustomSecurityConfig) securityConfigs;\n\n struct CustomSecurityConfig {\n uint128 additionSecurityPeriod;\n uint128 removalSecurityPeriod;\n uint128 securityWindow;\n uint128 recoveryPeriod;\n uint128 lockPeriod;\n uint128 approvalValidationPeriod;\n uint128 migrationPeriod;\n }\n\n /**\n * @notice Modifier to only allow wallet itself to make a call to wallet\n */\n modifier onlyWallet(address _wallet) {\n if (msg.sender != _wallet) revert SecurityManager__CallerNotWallet();\n _;\n }\n\n /**\n * @notice Modifier to revert if the variable is already initialized\n */\n modifier initializer(bool _isInitialized) {\n if (_isInitialized) revert SecurityManager__AlreadyIntialized();\n _;\n }\n\n /**\n * @notice Transfers the ownership of the contract to the given owner\n * @param _owner Address of owner who has access to initialize the default security variables for security manager\n */\n constructor(address _owner) {\n transferOwnership(_owner);\n _transferOwnership(_owner);\n }\n\n /**\n * @notice Sets the initial default/min/max addition security period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultAdditionSecurityPeriod Default Addition Security Period for all Barz contracts\n * @param _minAdditionSecurityPeriod Minimum Addition Security Period for all Barz contracts\n * @param _maxAdditionSecurityPeriod Maximum Addition Security Period for all Barz contracts\n */\n function initializeAdditionSecurityPeriod(\n uint128 _defaultAdditionSecurityPeriod,\n uint128 _minAdditionSecurityPeriod,\n uint128 _maxAdditionSecurityPeriod\n )\n external\n override\n onlyOwner\n initializer(_isAdditionSecurityPeriodInitialized)\n {\n _isAdditionSecurityPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultAdditionSecurityPeriod,\n _minAdditionSecurityPeriod,\n _maxAdditionSecurityPeriod\n );\n defaultAdditionSecurityPeriod = _defaultAdditionSecurityPeriod;\n minAdditionSecurityPeriod = _minAdditionSecurityPeriod;\n maxAdditionSecurityPeriod = _maxAdditionSecurityPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max removal security period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultRemovalSecurityPeriod Default Removal Security Period for all Barz contracts\n * @param _minRemovalSecurityPeriod Minimum Removal Security Period for all Barz contracts\n * @param _maxRemovalSecurityPeriod Maximum Removal Security Period for all Barz contracts\n */\n function initializeRemovalSecurityPeriod(\n uint128 _defaultRemovalSecurityPeriod,\n uint128 _minRemovalSecurityPeriod,\n uint128 _maxRemovalSecurityPeriod\n )\n external\n override\n onlyOwner\n initializer(_isRemovalSecurityPeriodInitialized)\n {\n _isRemovalSecurityPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultRemovalSecurityPeriod,\n _minRemovalSecurityPeriod,\n _maxRemovalSecurityPeriod\n );\n defaultRemovalSecurityPeriod = _defaultRemovalSecurityPeriod;\n minRemovalSecurityPeriod = _minRemovalSecurityPeriod;\n maxRemovalSecurityPeriod = _maxRemovalSecurityPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/maxd security window for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultSecurityWindow Default Security Window for all Barz contracts\n * @param _minSecurityWindow Minimum Security Window for all Barz contracts\n * @param _maxSecurityWindow Maximum Security Window for all Barz contracts\n */\n function initializeSecurityWindow(\n uint128 _defaultSecurityWindow,\n uint128 _minSecurityWindow,\n uint128 _maxSecurityWindow\n ) external override onlyOwner initializer(_isSecurityWindowInitialized) {\n _isSecurityWindowInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultSecurityWindow,\n _minSecurityWindow,\n _maxSecurityWindow\n );\n defaultSecurityWindow = _defaultSecurityWindow;\n minSecurityWindow = _minSecurityWindow;\n maxSecurityWindow = _maxSecurityWindow;\n }\n\n /**\n * @notice Sets the initial default/min/max recovery period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultRecoveryPeriod Default Recovery Period for all Barz contracts\n * @param _minRecoveryPeriod Minimum Recovery Period for all Barz contracts\n * @param _maxRecoveryPeriod Maximum Recovery Period for all Barz contracts\n */\n function initializeRecoveryPeriod(\n uint128 _defaultRecoveryPeriod,\n uint128 _minRecoveryPeriod,\n uint128 _maxRecoveryPeriod\n ) external override onlyOwner initializer(_isRecoveryPeriodInitialized) {\n _isRecoveryPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultRecoveryPeriod,\n _minRecoveryPeriod,\n _maxRecoveryPeriod\n );\n defaultRecoveryPeriod = _defaultRecoveryPeriod;\n minRecoveryPeriod = _minRecoveryPeriod;\n maxRecoveryPeriod = _maxRecoveryPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max lock period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultLockPeriod Default Lock Period for all Barz contracts\n * @param _minLockPeriod Minimum Lock Period for all Barz contracts\n * @param _maxLockPeriod Maximum Lock Period for all Barz contracts\n */\n function initializeLockPeriod(\n uint128 _defaultLockPeriod,\n uint128 _minLockPeriod,\n uint128 _maxLockPeriod\n ) external override onlyOwner initializer(_isLockPeriodInitialized) {\n _isLockPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultLockPeriod,\n _minLockPeriod,\n _maxLockPeriod\n );\n defaultLockPeriod = _defaultLockPeriod;\n minLockPeriod = _minLockPeriod;\n maxLockPeriod = _maxLockPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max approval validation period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultApprovalValidationPeriod Default Approval Validation Period for all Barz contracts\n * @param _minApprovalValidationPeriod Minimum Approval Validation Period for all Barz contracts\n * @param _maxApprovalValidationPeriod Maximum Approval Validation Period for all Barz contracts\n */\n function initializeApprovalValidationPeriod(\n uint128 _defaultApprovalValidationPeriod,\n uint128 _minApprovalValidationPeriod,\n uint128 _maxApprovalValidationPeriod\n )\n external\n override\n onlyOwner\n initializer(_isApprovalValidationPeriodInitialized)\n {\n _isApprovalValidationPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultApprovalValidationPeriod,\n _minApprovalValidationPeriod,\n _maxApprovalValidationPeriod\n );\n defaultApprovalValidationPeriod = _defaultApprovalValidationPeriod;\n minApprovalValidationPeriod = _minApprovalValidationPeriod;\n maxApprovalValidationPeriod = _maxApprovalValidationPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max migration period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultMigrationPeriod Default Migration Period for all Barz contracts\n * @param _minMigrationPeriod Minimum Migration Period for all Barz contracts\n * @param _maxMigrationPeriod Maximum Migration Period for all Barz contracts\n */\n function initializeMigrationPeriod(\n uint128 _defaultMigrationPeriod,\n uint128 _minMigrationPeriod,\n uint128 _maxMigrationPeriod\n ) external override onlyOwner initializer(_isMigrationPeriodInitialized) {\n _isMigrationPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultMigrationPeriod,\n _minMigrationPeriod,\n _maxMigrationPeriod\n );\n defaultMigrationPeriod = _defaultMigrationPeriod;\n minMigrationPeriod = _minMigrationPeriod;\n maxMigrationPeriod = _maxMigrationPeriod;\n }\n\n /**\n * @notice Wallet owner sets the addition security period for the wallet. Only the owner of wallet can call this function.\n * The addition security period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _additionSecurityPeriod Custom Addition Security Period for the wallet\n */\n function setAdditionSecurityPeriod(\n address _wallet,\n uint128 _additionSecurityPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _additionSecurityPeriod,\n minAdditionSecurityPeriod,\n maxAdditionSecurityPeriod\n );\n securityConfigs[_wallet]\n .additionSecurityPeriod = _additionSecurityPeriod;\n }\n\n /**\n * @notice Wallet owner sets the removal security period for the wallet. Only the owner of wallet can call this function.\n * The removal security period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _removalSecurityPeriod Custom Removal Security Period for the wallet\n */\n function setRemovalSecurityPeriod(\n address _wallet,\n uint128 _removalSecurityPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _removalSecurityPeriod,\n minRemovalSecurityPeriod,\n maxRemovalSecurityPeriod\n );\n securityConfigs[_wallet].removalSecurityPeriod = _removalSecurityPeriod;\n }\n\n /**\n * @notice Wallet owner sets the security window for the wallet. Only the owner of wallet can call this function.\n * The security window should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _securityWindow Custom Security Window for the wallet\n */\n function setSecurityWindow(\n address _wallet,\n uint128 _securityWindow\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _securityWindow,\n minSecurityWindow,\n maxSecurityWindow\n );\n securityConfigs[_wallet].securityWindow = _securityWindow;\n }\n\n /**\n * @notice Wallet owner sets the recovery period for the wallet. Only the owner of wallet can call this function.\n * The recovery period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _recoveryPeriod Custom recovery period for the wallet\n */\n function setRecoveryPeriod(\n address _wallet,\n uint128 _recoveryPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _recoveryPeriod,\n minRecoveryPeriod,\n maxRecoveryPeriod\n );\n securityConfigs[_wallet].recoveryPeriod = _recoveryPeriod;\n }\n\n /**\n * @notice Wallet owner sets the lock period for the wallet. Only the owner of wallet can call this function.\n * The lock period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _lockPeriod Custom Lock period for the wallet\n */\n function setLockPeriod(\n address _wallet,\n uint128 _lockPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(_lockPeriod, minLockPeriod, maxLockPeriod);\n securityConfigs[_wallet].lockPeriod = _lockPeriod;\n }\n\n /**\n * @notice Wallet owner sets the approval validation period for the wallet. Only the owner of wallet can call this function.\n * The approval validation period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _approvalValidationPeriod Custom approval validation period for the wallet\n */\n function setApprovalValidationPeriod(\n address _wallet,\n uint128 _approvalValidationPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _approvalValidationPeriod,\n minApprovalValidationPeriod,\n maxApprovalValidationPeriod\n );\n securityConfigs[_wallet]\n .approvalValidationPeriod = _approvalValidationPeriod;\n }\n\n /**\n * @notice Wallet owner sets the migration period for the wallet. Only the owner of wallet can call this function.\n * The migration period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _migrationPeriod Custom migration period for the wallet\n */\n\n function setMigrationPeriod(\n address _wallet,\n uint128 _migrationPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _migrationPeriod,\n minMigrationPeriod,\n maxMigrationPeriod\n );\n securityConfigs[_wallet].migrationPeriod = _migrationPeriod;\n }\n\n /**\n * @notice Returns the addition security period. Returns default value when custom addition security period is not set\n * @param _wallet Address of wallet\n * @return additionSecurityPeriod Addition Security Period of the given Barz account or wallet\n */\n function additionSecurityPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 additionSecurityPeriod)\n {\n additionSecurityPeriod = securityConfigs[_wallet]\n .additionSecurityPeriod;\n additionSecurityPeriod = (additionSecurityPeriod == 0)\n ? defaultAdditionSecurityPeriod\n : additionSecurityPeriod;\n }\n\n /**\n * @notice Returns the removal security period. Returns default value when custom removal security period is not set\n * @param _wallet Address of wallet\n * @return removalSecurityPeriod Removal Security Period of the given Barz account or wallet\n */\n function removalSecurityPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 removalSecurityPeriod)\n {\n removalSecurityPeriod = securityConfigs[_wallet].removalSecurityPeriod;\n removalSecurityPeriod = (removalSecurityPeriod == 0)\n ? defaultRemovalSecurityPeriod\n : removalSecurityPeriod;\n }\n\n /**\n * @notice Returns the security window. Returns default value when custom security window is not set\n * @param _wallet Address of wallet\n * @return securityWindow Security window of the given Barz account or wallet\n */\n function securityWindowOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 securityWindow)\n {\n securityWindow = securityConfigs[_wallet].securityWindow;\n securityWindow = (securityWindow == 0)\n ? defaultSecurityWindow\n : securityWindow;\n }\n\n /**\n * @notice Returns the recovery period. Returns default value when custom recovery period is not set\n * @param _wallet Address of wallet\n * @return recoveryPeriod Recovery Period of the given Barz account or wallet\n */\n function recoveryPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 recoveryPeriod)\n {\n recoveryPeriod = securityConfigs[_wallet].recoveryPeriod;\n recoveryPeriod = (recoveryPeriod == 0)\n ? defaultRecoveryPeriod\n : recoveryPeriod;\n }\n\n /**\n * @notice Returns the lock period. Returns default value when custom lock period is not set\n * @param _wallet Address of wallet\n * @return lockPeriod Lock Period of the given Barz account or wallet\n */\n function lockPeriodOf(\n address _wallet\n ) public view override onlyWallet(_wallet) returns (uint128 lockPeriod) {\n lockPeriod = securityConfigs[_wallet].lockPeriod;\n lockPeriod = (lockPeriod == 0) ? defaultLockPeriod : lockPeriod;\n }\n\n /**\n * @notice Returns the approval validation period. Returns default value when custom approval validation period is not set\n * @param _wallet Address of wallet\n * @return approvalValidationPeriod Approval Validation Period of the given Barz account or wallet\n */\n function approvalValidationPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityConfigs[_wallet]\n .approvalValidationPeriod;\n approvalValidationPeriod = (approvalValidationPeriod == 0)\n ? defaultApprovalValidationPeriod\n : approvalValidationPeriod;\n }\n\n /**\n * @notice Returns the migration period. Returns default value when custom migration period is not set\n * @param _wallet Address of wallet\n * @return migrationPeriod Migration Period of the given Barz account or wallet\n */\n function migrationPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 migrationPeriod)\n {\n migrationPeriod = securityConfigs[_wallet].migrationPeriod;\n migrationPeriod = (migrationPeriod == 0)\n ? defaultMigrationPeriod\n : migrationPeriod;\n }\n\n /**\n * @notice Validates if the period is smaller than the max period or bigger than the min period\n * @param _period Period to be checked\n * @param _minPeriod Minimum period\n * @param _maxPeriod Maximum period\n */\n function _validatePeriodBoundaries(\n uint128 _period,\n uint128 _minPeriod,\n uint128 _maxPeriod\n ) internal pure {\n if (_period >= _maxPeriod || _period <= _minPeriod)\n revert SecurityManager__OutOfBoundary();\n }\n}\n" + }, + "contracts/infrastructure/WhitelistStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {RemoteStorage} from \"./RemoteStorage.sol\";\n\n/**\n * @title Whitelist storage\n * @dev Maps addresses to the corresponsing array of whitelisted addresses for each of them.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract WhitelistStorage is RemoteStorage {\n /**\n * @dev Add the address to the whitelist storage\n * @param _wallet User wallet\n * @param _address Address to be whitelisted\n */\n function whitelistAddress(address _wallet, address _address) external {\n enforceWalletOrGuardianIfExists(_wallet);\n addAddress(_wallet, _address);\n }\n\n /**\n * @dev Removes the address from the whitelist storage\n * @param _wallet User wallet\n * @param _address Address to be removed from the whitelist\n */\n function blacklistAddress(address _wallet, address _address) external {\n enforceGuardianOrWallet(_wallet);\n removeAddress(_wallet, _address);\n }\n\n /**\n * @dev Returns whether the address exists in the whitelist storage, associated with the wallet\n * @param _wallet User wallet\n * @param _address Address to be whitelisted\n */\n function isWhitelisted(\n address _wallet,\n address _address\n ) external view returns (bool) {\n return exists(_wallet, _address);\n }\n\n /**\n * @dev Returns all whitelisted addresses associated with the wallet\n * @param _wallet User wallet\n */\n function getWhitelistedAddresses(\n address _wallet\n ) external view returns (address[] memory) {\n return getAddresses(_wallet);\n }\n}\n" + }, + "contracts/interfaces/ERC/IERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\n\npragma solidity 0.8.21;\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155Receiver {\n /**\n * @dev Handles the receipt of a single ERC1155 token type. This function is\n * called at the end of a `safeTransferFrom` after the balance has been updated.\n *\n * NOTE: To accept the transfer, this must return\n * `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n * (i.e. 0xf23a6e61, or its own function selector).\n *\n * @param operator The address which initiated the transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param id The ID of the token being transferred\n * @param value The amount of tokens being transferred\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n ) external returns (bytes4);\n\n /**\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\n * is called at the end of a `safeBatchTransferFrom` after the balances have\n * been updated.\n *\n * NOTE: To accept the transfer(s), this must return\n * `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n * (i.e. 0xbc197c81, or its own function selector).\n *\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "contracts/interfaces/ERC/IERC1271.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\ninterface IERC1271 {\n function isValidSignature(\n bytes32 hash,\n bytes memory signature\n ) external view returns (bytes4);\n}\n" + }, + "contracts/interfaces/ERC/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\ninterface IERC165 {\n /// @notice Query if a contract implements an interface\n /// @param interfaceId The interface identifier, as specified in ERC-165\n /// @dev Interface identification is specified in ERC-165. This function\n /// uses less than 30,000 gas.\n /// @return `true` if the contract implements `interfaceID` and\n /// `interfaceID` is not 0xffffffff, `false` otherwise\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/IERC173.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\n/// @title ERC-173 Contract Ownership Standard\n/// Note: the ERC-165 identifier for this interface is 0x7f5828d0\n/* is ERC165 */\ninterface IERC173 {\n /// @dev This emits when ownership of a contract changes.\n event OwnershipTransferred(\n address indexed previousOwner,\n address indexed newOwner\n );\n\n /// @notice Get the address of the owner\n /// @return owner_ The address of the owner.\n function owner() external view returns (address owner_);\n\n /// @notice Set the address of the new owner of the contract\n /// @dev Set _newOwner to address(0) to renounce any ownership.\n /// @param _newOwner The address of the new owner of the contract\n function transferOwnership(address _newOwner) external;\n}\n" + }, + "contracts/interfaces/ERC/IERC677Receiver.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\ninterface IERC677Receiver {\n function onTokenTransfer(\n address sender,\n uint value,\n bytes calldata data\n ) external pure returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155 is IERC165 {\n /**\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n */\n event TransferSingle(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256 id,\n uint256 value\n );\n\n /**\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n * transfers.\n */\n event TransferBatch(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\n\n /**\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n * `approved`.\n */\n event ApprovalForAll(\n address indexed account,\n address indexed operator,\n bool approved\n );\n\n /**\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n *\n * If an {URI} event was emitted for `id`, the standard\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n * returned by {IERC1155MetadataURI-uri}.\n */\n event URI(string value, uint256 indexed id);\n\n /**\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(\n address account,\n uint256 id\n ) external view returns (uint256);\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] calldata accounts,\n uint256[] calldata ids\n ) external view returns (uint256[] memory);\n\n /**\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n *\n * Emits an {ApprovalForAll} event.\n *\n * Requirements:\n *\n * - `operator` cannot be the caller.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n *\n * See {setApprovalForAll}.\n */\n function isApprovedForAll(\n address account,\n address operator\n ) external view returns (bool);\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes calldata data\n ) external;\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(\n address indexed owner,\n address indexed spender,\n uint256 value\n );\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` 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 amount) 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(\n address owner,\n address spender\n ) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the 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 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` 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(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(\n address spender,\n uint256 addedValue\n ) external returns (bool);\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(\n address spender,\n uint256 subtractedValue\n ) external returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(\n address indexed from,\n address indexed to,\n uint256 indexed tokenId\n );\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(\n address indexed owner,\n address indexed approved,\n uint256 indexed tokenId\n );\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(\n address indexed owner,\n address indexed operator,\n bool approved\n );\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(\n uint256 tokenId\n ) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(\n address owner,\n address operator\n ) external view returns (bool);\n}\n" + }, + "contracts/interfaces/IBarz.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Barz Interface\n * @dev Interface of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IBarz {\n error Barz__InitializationFailure();\n}\n" + }, + "contracts/interfaces/IBarzFactory.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Barz} from \"../Barz.sol\";\n\n/**\n * @title Barz Factory Interface\n * @dev Interface of contract to easily deploy Barz to a pre-computed address with a single call\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IBarzFactory {\n function createAccount(\n address verificationFacet,\n bytes calldata owner,\n uint256 salt\n ) external returns (Barz);\n\n function getAddress(\n address verificationFacet,\n bytes calldata owner,\n uint256 salt\n ) external view returns (address);\n\n function getBytecode(\n address accountFacet,\n address verificationFacet,\n address entryPoint,\n address facetRegistry,\n address defaultFallback,\n bytes memory ownerPublicKey\n ) external pure returns (bytes memory);\n\n function getCreationCode() external pure returns (bytes memory);\n}\n" + }, + "contracts/libraries/DefaultLibDiamond.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\n\nerror InitializationFunctionReverted(\n address _initializationContractAddress,\n bytes _calldata\n);\n\nlibrary DefaultLibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION =\n keccak256(\"trustwallet.barz.diamond.storage\");\n\n struct FacetAddressAndPosition {\n address facetAddress;\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\n }\n\n struct FacetFunctionSelectors {\n bytes4[] functionSelectors;\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\n }\n\n struct DiamondStorage {\n // maps function selector to the facet address and\n // the position of the selector in the facetFunctionSelectors.selectors array\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\n // maps facet addresses to function selectors\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\n // facet addresses\n address[] facetAddresses;\n // Used to query if a contract implements an interface.\n // Used to implement ERC-165.\n mapping(bytes4 => bool) supportedInterfaces;\n }\n\n function diamondStorage()\n internal\n pure\n returns (DiamondStorage storage ds)\n {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n event DiamondCut(\n IDiamondCut.FacetCut[] _diamondCut,\n address _init,\n bytes _calldata\n );\n\n // Internal function version of diamondCut\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n for (\n uint256 facetIndex;\n facetIndex < _diamondCut.length;\n facetIndex++\n ) {\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\n if (action == IDiamondCut.FacetCutAction.Add) {\n addFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\n replaceFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\n removeFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else {\n revert(\"LibDiamondCut: Incorrect FacetCutAction\");\n }\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Add facet can't be address(0)\"\n );\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n require(\n oldFacetAddress == address(0),\n \"LibDiamondCut: Can't add function that already exists\"\n );\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function replaceFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Replace facet can't be address(0)\"\n );\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n require(\n oldFacetAddress != _facetAddress,\n \"LibDiamondCut: Can't replace function with same facet\"\n );\n removeFunction(ds, oldFacetAddress, selector);\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function removeFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n // if function does not exist then do nothing and return\n require(\n _facetAddress == address(0),\n \"LibDiamondCut: Remove facet address must be address(0)\"\n );\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n removeFunction(ds, oldFacetAddress, selector);\n }\n }\n\n function addFacet(\n DiamondStorage storage ds,\n address _facetAddress\n ) internal {\n enforceHasContractCode(\n _facetAddress,\n \"LibDiamondCut: New facet has no code\"\n );\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds\n .facetAddresses\n .length;\n ds.facetAddresses.push(_facetAddress);\n }\n\n function addFunction(\n DiamondStorage storage ds,\n bytes4 _selector,\n uint96 _selectorPosition,\n address _facetAddress\n ) internal {\n ds\n .selectorToFacetAndPosition[_selector]\n .functionSelectorPosition = _selectorPosition;\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(\n _selector\n );\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\n }\n\n function removeFunction(\n DiamondStorage storage ds,\n address _facetAddress,\n bytes4 _selector\n ) internal {\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Can't remove function that doesn't exist\"\n );\n // an immutable function is a function defined directly in a diamond\n require(\n _facetAddress != address(this),\n \"LibDiamondCut: Can't remove immutable function\"\n );\n // replace selector with last selector, then delete last selector\n uint256 selectorPosition = ds\n .selectorToFacetAndPosition[_selector]\n .functionSelectorPosition;\n uint256 lastSelectorPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors\n .length - 1;\n // if not the same then replace _selector with lastSelector\n if (selectorPosition != lastSelectorPosition) {\n bytes4 lastSelector = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors[lastSelectorPosition];\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[\n selectorPosition\n ] = lastSelector;\n ds\n .selectorToFacetAndPosition[lastSelector]\n .functionSelectorPosition = uint96(selectorPosition);\n }\n // delete the last selector\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\n delete ds.selectorToFacetAndPosition[_selector];\n\n // if no more selectors for facet address then delete the facet address\n if (lastSelectorPosition == 0) {\n // replace facet address with last facet address and delete last facet address\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\n uint256 facetAddressPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .facetAddressPosition;\n if (facetAddressPosition != lastFacetAddressPosition) {\n address lastFacetAddress = ds.facetAddresses[\n lastFacetAddressPosition\n ];\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\n ds\n .facetFunctionSelectors[lastFacetAddress]\n .facetAddressPosition = facetAddressPosition;\n }\n ds.facetAddresses.pop();\n delete ds\n .facetFunctionSelectors[_facetAddress]\n .facetAddressPosition;\n }\n }\n\n function initializeDiamondCut(\n address _init,\n bytes memory _calldata\n ) internal {\n if (_init == address(0)) {\n return;\n }\n enforceHasContractCode(\n _init,\n \"LibDiamondCut: _init address has no code\"\n );\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length > 0) {\n // bubble up error\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(error)\n revert(add(32, error), returndata_size)\n }\n } else {\n revert InitializationFunctionReverted(_init, _calldata);\n }\n }\n }\n\n function enforceHasContractCode(\n address _contract,\n string memory _errorMessage\n ) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize > 0, _errorMessage);\n }\n}\n" + }, + "contracts/libraries/LibAppStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SafeCast} from \"@openzeppelin/contracts/utils/math/SafeCast.sol\";\nimport {IEntryPoint} from \"../aa-4337/interfaces/IEntryPoint.sol\";\nimport {IFacetRegistry} from \"../infrastructure/interfaces/IFacetRegistry.sol\";\n\n/*\n * @title App Storage\n * @dev App storage for Barz contract to prevent storage collision\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\n\nstruct Lock {\n uint64 release;\n bytes4 locker;\n}\n\nstruct InitializersStorage {\n // NOTE: initialized is a variable to make sure the initialization is only done once.\n uint8 signerInitialized;\n uint8 accountInitialized;\n uint8 restrictionsInitialized;\n}\n\nstruct AppStorage {\n mapping(uint256 => InitializersStorage) initStorage;\n uint8 signerMigration;\n bytes4 validateOwnerSignatureSelector;\n IEntryPoint entryPoint;\n IFacetRegistry facetRegistry;\n mapping(uint256 => Lock) locks;\n}\n\nlibrary LibAppStorage {\n error LibAppStorage__AccountAlreadyUninitialized();\n error LibAppStorage__AccountMustBeUninitialized();\n error LibAppStorage__SignerAlreadyUninitialized();\n error LibAppStorage__SignerMustBeUninitialized();\n\n function appStorage() internal pure returns (AppStorage storage ds) {\n assembly {\n ds.slot := 0\n }\n }\n\n function setSignerUninitialized() internal {\n AppStorage storage s = appStorage();\n if (1 != s.initStorage[0].signerInitialized) {\n revert LibAppStorage__SignerAlreadyUninitialized();\n }\n s.initStorage[0].signerInitialized = 0;\n }\n\n function getValidateOwnerSignatureSelector()\n internal\n view\n returns (bytes4 selector)\n {\n selector = appStorage().validateOwnerSignatureSelector;\n }\n\n function setValidateOwnerSignatureSelector(\n bytes4 _validateOwnerSignatureSelector\n ) internal {\n appStorage()\n .validateOwnerSignatureSelector = _validateOwnerSignatureSelector;\n }\n\n function enforceSignerInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].signerInitialized) {\n revert LibAppStorage__SignerMustBeUninitialized();\n }\n s.initStorage[0].signerInitialized = 1;\n }\n\n function enforceAccountInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].accountInitialized) {\n revert LibAppStorage__AccountMustBeUninitialized();\n }\n s.initStorage[0].accountInitialized = 1;\n }\n\n function initiateSignerMigration() internal {\n appStorage().signerMigration = 1;\n }\n\n function enforceSignerMigration() internal view {\n if (1 != appStorage().signerMigration) {\n revert LibAppStorage__AccountMustBeUninitialized();\n }\n }\n\n function finalizeSignerMigration() internal {\n appStorage().signerMigration = 0;\n }\n\n function setLock(uint256 _releaseAfter, bytes4 _locker) internal {\n appStorage().locks[0] = Lock(SafeCast.toUint64(_releaseAfter), _locker);\n }\n\n function enforceRestrictionsInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].restrictionsInitialized)\n revert LibAppStorage__SignerMustBeUninitialized();\n s.initStorage[0].restrictionsInitialized = 1;\n }\n\n function setRestrictionsUninitialized() internal {\n AppStorage storage s = appStorage();\n if (1 != s.initStorage[0].restrictionsInitialized)\n revert LibAppStorage__AccountAlreadyUninitialized();\n s.initStorage[0].restrictionsInitialized = 0;\n }\n}\n\ncontract BarzStorage {\n AppStorage internal s;\n modifier onlyWhenUnlocked() {\n require(\n uint64(block.timestamp) >= s.locks[0].release,\n \"Account Locked\"\n );\n _;\n }\n modifier onlyWhenLocked() {\n require(\n uint64(block.timestamp) < s.locks[0].release,\n \"Account Unlocked\"\n );\n _;\n }\n}\n" + }, + "contracts/libraries/LibDiamond.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\n\nerror InitializationFunctionReverted(\n address _initializationContractAddress,\n bytes _calldata\n);\n\nlibrary LibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION =\n keccak256(\"trustwallet.barz.diamond.storage\");\n\n struct DiamondStorage {\n // maps function selectors to the facets that execute the functions.\n // and maps the selectors to their position in the selectorSlots array.\n // func selector => address facet, selector position\n mapping(bytes4 => bytes32) facets;\n // array of slots of function selectors.\n // each slot holds 8 function selectors.\n mapping(uint256 => bytes32) selectorSlots;\n // The number of function selectors in selectorSlots\n uint16 selectorCount;\n // Used to query if a contract implements an interface.\n // Used to implement ERC-165.\n mapping(bytes4 => bool) supportedInterfaces;\n // Default Fallback Handler of the barz.\n IDiamondLoupe defaultFallbackHandler;\n }\n\n function diamondStorage()\n internal\n pure\n returns (DiamondStorage storage ds)\n {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n function enforceIsSelf() internal view {\n require(msg.sender == address(this), \"LibDiamond: Caller not self\");\n }\n\n event DiamondCut(\n IDiamondCut.FacetCut[] _diamondCut,\n address _init,\n bytes _calldata\n );\n\n bytes32 constant CLEAR_ADDRESS_MASK =\n bytes32(uint256(0xffffffffffffffffffffffff));\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\n\n // Internal function version of diamondCut\n // This code is almost the same as the external diamondCut,\n // except it is using 'Facet[] memory _diamondCut' instead of\n // 'Facet[] calldata _diamondCut'.\n // The code is duplicated to prevent copying calldata to memory which\n // causes an error for a two dimensional array.\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n DiamondStorage storage ds = diamondStorage();\n uint256 originalSelectorCount = ds.selectorCount;\n uint256 selectorCount = originalSelectorCount;\n bytes32 selectorSlot;\n // Check if last selector slot is not full\n // \"selectorCount & 7\" is a gas efficient modulo by eight \"selectorCount % 8\"\n if (selectorCount & 7 > 0) {\n // get last selectorSlot\n // \"selectorSlot >> 3\" is a gas efficient division by 8 \"selectorSlot / 8\"\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\n }\n // loop through diamond cut\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\n selectorCount,\n selectorSlot,\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].action,\n _diamondCut[facetIndex].functionSelectors\n );\n\n unchecked {\n facetIndex++;\n }\n }\n if (selectorCount != originalSelectorCount) {\n ds.selectorCount = uint16(selectorCount);\n }\n // If last selector slot is not full\n // \"selectorCount & 7\" is a gas efficient modulo by eight \"selectorCount % 8\"\n if (selectorCount & 7 > 0) {\n // \"selectorSlot >> 3\" is a gas efficient division by 8 \"selectorSlot / 8\"\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addReplaceRemoveFacetSelectors(\n uint256 _selectorCount,\n bytes32 _selectorSlot,\n address _newFacetAddress,\n IDiamondCut.FacetCutAction _action,\n bytes4[] memory _selectors\n ) internal returns (uint256, bytes32) {\n DiamondStorage storage ds = diamondStorage();\n require(\n _selectors.length > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n if (_action == IDiamondCut.FacetCutAction.Add) {\n enforceHasContractCode(\n _newFacetAddress,\n \"LibDiamondCut: Add facet has no code\"\n );\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n require(\n address(bytes20(oldFacet)) == address(0),\n \"LibDiamondCut: Can't add function that already exists\"\n );\n // add facet for selector\n ds.facets[selector] =\n bytes20(_newFacetAddress) |\n bytes32(_selectorCount);\n // \"_selectorCount & 7\" is a gas efficient modulo by eight \"_selectorCount % 8\"\n // \" << 5 is the same as multiplying by 32 ( * 32)\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\n // clear selector position in slot and add selector\n _selectorSlot =\n (_selectorSlot &\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\n (bytes32(selector) >> selectorInSlotPosition);\n // if slot is full then write it to storage\n if (selectorInSlotPosition == 224) {\n // \"_selectorSlot >> 3\" is a gas efficient division by 8 \"_selectorSlot / 8\"\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\n _selectorSlot = 0;\n }\n _selectorCount++;\n\n unchecked {\n selectorIndex++;\n }\n }\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\n enforceHasContractCode(\n _newFacetAddress,\n \"LibDiamondCut: Replace facet has no code\"\n );\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n address oldFacetAddress = address(bytes20(oldFacet));\n // only useful if immutable functions exist\n require(\n oldFacetAddress != address(this),\n \"LibDiamondCut: Can't replace immutable function\"\n );\n require(\n oldFacetAddress != _newFacetAddress,\n \"LibDiamondCut: Can't replace function with same function\"\n );\n require(\n oldFacetAddress != address(0),\n \"LibDiamondCut: Can't replace function that doesn't exist\"\n );\n // replace old facet address\n ds.facets[selector] =\n (oldFacet & CLEAR_ADDRESS_MASK) |\n bytes20(_newFacetAddress);\n\n unchecked {\n selectorIndex++;\n }\n }\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\n require(\n _newFacetAddress == address(0),\n \"LibDiamondCut: Remove facet address must be address(0)\"\n );\n // \"_selectorCount >> 3\" is a gas efficient division by 8 \"_selectorCount / 8\"\n uint256 selectorSlotCount = _selectorCount >> 3;\n // \"_selectorCount & 7\" is a gas efficient modulo by eight \"_selectorCount % 8\"\n uint256 selectorInSlotIndex = _selectorCount & 7;\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n if (_selectorSlot == 0) {\n // get last selectorSlot\n selectorSlotCount--;\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\n selectorInSlotIndex = 7;\n } else {\n selectorInSlotIndex--;\n }\n bytes4 lastSelector;\n uint256 oldSelectorsSlotCount;\n uint256 oldSelectorInSlotPosition;\n // adding a block here prevents stack too deep error\n {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n require(\n address(bytes20(oldFacet)) != address(0),\n \"LibDiamondCut: Can't remove function that doesn't exist\"\n );\n // only useful if immutable functions exist\n require(\n address(bytes20(oldFacet)) != address(this),\n \"LibDiamondCut: Can't remove immutable function\"\n );\n // replace selector with last selector in ds.facets\n // gets the last selector\n // \" << 5 is the same as multiplying by 32 ( * 32)\n lastSelector = bytes4(\n _selectorSlot << (selectorInSlotIndex << 5)\n );\n if (lastSelector != selector) {\n // update last selector slot position info\n ds.facets[lastSelector] =\n (oldFacet & CLEAR_ADDRESS_MASK) |\n bytes20(ds.facets[lastSelector]);\n }\n delete ds.facets[selector];\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\n // \"oldSelectorCount >> 3\" is a gas efficient division by 8 \"oldSelectorCount / 8\"\n oldSelectorsSlotCount = oldSelectorCount >> 3;\n // \"oldSelectorCount & 7\" is a gas efficient modulo by eight \"oldSelectorCount % 8\"\n // \" << 5 is the same as multiplying by 32 ( * 32)\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\n }\n if (oldSelectorsSlotCount != selectorSlotCount) {\n bytes32 oldSelectorSlot = ds.selectorSlots[\n oldSelectorsSlotCount\n ];\n // clears the selector we are deleting and puts the last selector in its place.\n oldSelectorSlot =\n (oldSelectorSlot &\n ~(CLEAR_SELECTOR_MASK >>\n oldSelectorInSlotPosition)) |\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\n // update storage with the modified slot\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\n } else {\n // clears the selector we are deleting and puts the last selector in its place.\n _selectorSlot =\n (_selectorSlot &\n ~(CLEAR_SELECTOR_MASK >>\n oldSelectorInSlotPosition)) |\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\n }\n if (selectorInSlotIndex == 0) {\n delete ds.selectorSlots[selectorSlotCount];\n _selectorSlot = 0;\n }\n\n unchecked {\n selectorIndex++;\n }\n }\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\n } else {\n revert(\"LibDiamondCut: Incorrect FacetCutAction\");\n }\n return (_selectorCount, _selectorSlot);\n }\n\n function initializeDiamondCut(\n address _init,\n bytes memory _calldata\n ) internal {\n if (_init == address(0)) {\n return;\n }\n enforceHasContractCode(\n _init,\n \"LibDiamondCut: _init address has no code\"\n );\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length > 0) {\n // bubble up error\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(error)\n revert(add(32, error), returndata_size)\n }\n } else {\n revert InitializationFunctionReverted(_init, _calldata);\n }\n }\n }\n\n function enforceHasContractCode(\n address _contract,\n string memory _errorMessage\n ) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize > 0, _errorMessage);\n }\n\n function restrictionsFacet() internal view returns (address facetAddress_) {\n bytes4 selector = bytes4(\n keccak256(\"verifyRestrictions(address,address,uint256,bytes)\")\n );\n facetAddress_ = address(\n bytes20(LibDiamond.diamondStorage().facets[selector])\n );\n }\n}\n" + }, + "contracts/libraries/LibFacetStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Storage\n * @dev Storage contract to store each facets variables with diamond storage\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\n\nstruct Secp256k1VerificationStorage {\n address signer;\n}\n\nstruct Secp256r1VerificationStorage {\n uint256[2] q;\n}\n\nstruct GuardianStorage {\n mapping(bytes32 => uint256) pending;\n mapping(uint8 => StorageConfig) configs;\n}\n\nstruct Info {\n bool exists;\n uint128 index;\n}\n\nstruct StorageConfig {\n address[] addresses;\n mapping(address => Info) info;\n}\n\nstruct RecoveryConfig {\n bytes recoveryPublicKey;\n uint64 executeAfter;\n}\n\nstruct ApprovalConfig {\n bool isApproved;\n uint64 validUntil;\n}\n\nstruct RecoveryApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isNewOwnerApproved;\n}\n\nstruct RecoveryStorage {\n mapping(uint8 => RecoveryConfig) recoveryConfigs;\n mapping(uint8 => RecoveryApprovalConfig) recoveryApprovalConfigs;\n uint128 nonce;\n}\n\nstruct RestrictionsStorage {\n address[] restrictions;\n mapping(address => bool) exists;\n}\n\nstruct SignatureMigrationConfig {\n bytes migrationPublicKey;\n address migrationVerificationFacet;\n bytes4[] migrationSelectors;\n uint64 migrateAfter;\n}\n\nstruct SignatureMigrationApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isMigrationApproved;\n}\n\nstruct SignatureMigrationStorage {\n mapping(uint8 => SignatureMigrationConfig) migrationConfigs;\n mapping(uint8 => SignatureMigrationApprovalConfig) migrationApprovalConfigs;\n uint128 nonce;\n}\n\nstruct DiamondCutApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isDiamondCutApproved;\n}\n\nstruct DiamondCutStorage {\n mapping(uint8 => DiamondCutApprovalConfig) diamondCutApprovalConfigs;\n uint128 nonce;\n}\n\nstruct LockStorage {\n uint128 nonce;\n}\n\nlibrary LibFacetStorage {\n function k1Storage()\n internal\n pure\n returns (Secp256k1VerificationStorage storage ds)\n {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.Secp256k1VerificationStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function r1Storage()\n internal\n pure\n returns (Secp256r1VerificationStorage storage ds)\n {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.Secp256r1VerificationStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function guardianStorage()\n internal\n pure\n returns (GuardianStorage storage ds)\n {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.GuardianStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function recoveryStorage()\n internal\n pure\n returns (RecoveryStorage storage ds)\n {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.RecoveryStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function restrictionsStorage()\n internal\n pure\n returns (RestrictionsStorage storage ds)\n {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.RestrictionsStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function migrationStorage()\n internal\n pure\n returns (SignatureMigrationStorage storage ds)\n {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.SignatureMigrationStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function diamondCutStorage()\n internal\n pure\n returns (DiamondCutStorage storage ds)\n {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.DiamondCutStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function lockStorage() internal pure returns (LockStorage storage ds) {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.LockStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n}\n" + }, + "contracts/libraries/LibGuardian.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibFacetStorage, StorageConfig} from \"./LibFacetStorage.sol\";\n\n/**\n * @title LibGuardian\n * @dev Internal Library to provide utility feature for Guardians stored in Guardian Facet Storage\n * @author David Yongjun Kim (@Powerstream3604)\n */\nlibrary LibGuardian {\n function majorityOfGuardians()\n internal\n view\n returns (uint256 guardianNumber)\n {\n uint256 guardianLength = guardianCount();\n guardianNumber = (guardianLength == 0) ? 0 : guardianLength / 2 + 1;\n }\n\n function isGuardian(address _guardian) internal view returns (bool) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n return config.info[_guardian].exists;\n }\n\n function guardianCount() internal view returns (uint256) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n return config.addresses.length;\n }\n\n function getGuardians() internal view returns (address[] memory) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n address[] memory addresses = new address[](config.addresses.length);\n uint256 addressesLen = config.addresses.length;\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n return addresses;\n }\n}\n" + }, + "contracts/libraries/LibLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {LibDiamond} from \"./LibDiamond.sol\";\n\n/**\n * @title LibLoupe\n * @dev Internal Library to provide utility feature for reading the state of diamond facets\n * @author David Yongjun Kim (@Powerstream3604)\n */\nlibrary LibLoupe {\n /// @notice Gets all facets and their selectors.\n /// @return facets_ Facet\n function facets()\n internal\n view\n returns (IDiamondLoupe.Facet[] memory facets_)\n {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facets_ = new IDiamondLoupe.Facet[](ds.selectorCount);\n uint16[] memory numFacetSelectors = new uint16[](ds.selectorCount);\n uint256 numFacets;\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facetAddress_ = address(bytes20(ds.facets[selector]));\n bool continueLoop;\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n if (facets_[facetIndex].facetAddress == facetAddress_) {\n facets_[facetIndex].functionSelectors[\n numFacetSelectors[facetIndex]\n ] = selector;\n // probably will never have more than 256 functions from one facet contract\n require(numFacetSelectors[facetIndex] < 255);\n numFacetSelectors[facetIndex]++;\n continueLoop = true;\n break;\n }\n }\n if (continueLoop) {\n continue;\n }\n facets_[numFacets].facetAddress = facetAddress_;\n facets_[numFacets].functionSelectors = new bytes4[](\n ds.selectorCount\n );\n facets_[numFacets].functionSelectors[0] = selector;\n numFacetSelectors[numFacets] = 1;\n numFacets++;\n }\n }\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n uint256 numSelectors = numFacetSelectors[facetIndex];\n bytes4[] memory selectors = facets_[facetIndex].functionSelectors;\n // setting the number of selectors\n assembly {\n mstore(selectors, numSelectors)\n }\n }\n // setting the number of facets\n assembly {\n mstore(facets_, numFacets)\n }\n }\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n /// @return _facetFunctionSelectors The selectors associated with a facet address.\n function facetFunctionSelectors(\n address _facet\n ) internal view returns (bytes4[] memory _facetFunctionSelectors) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n uint256 numSelectors;\n _facetFunctionSelectors = new bytes4[](ds.selectorCount);\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facet = address(bytes20(ds.facets[selector]));\n if (_facet == facet) {\n _facetFunctionSelectors[numSelectors] = selector;\n numSelectors++;\n }\n }\n }\n // Set the number of selectors in the array\n assembly {\n mstore(_facetFunctionSelectors, numSelectors)\n }\n }\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses()\n internal\n view\n returns (address[] memory facetAddresses_)\n {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facetAddresses_ = new address[](ds.selectorCount);\n uint256 numFacets;\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facetAddress_ = address(bytes20(ds.facets[selector]));\n bool continueLoop;\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n if (facetAddress_ == facetAddresses_[facetIndex]) {\n continueLoop = true;\n break;\n }\n }\n if (continueLoop) {\n continue;\n }\n facetAddresses_[numFacets] = facetAddress_;\n numFacets++;\n }\n }\n // Set the number of facet addresses in the array\n assembly {\n mstore(facetAddresses_, numFacets)\n }\n }\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(\n bytes4 _functionSelector\n ) internal view returns (address facetAddress_) {\n facetAddress_ = address(\n bytes20(LibDiamond.diamondStorage().facets[_functionSelector])\n );\n }\n}\n" + }, + "contracts/libraries/LibMultiSigStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Multi-sig Storage\n * @dev Storage contract for storing Multi-sig Facet variables in diamond storage pattern\n * @author David Yongjun Kim (@Powerstream3604)\n */\n\nstruct MultiSigStorage {\n mapping(address => address) owners;\n mapping(uint256 => mapping(address => mapping(bytes32 => uint256))) approvedHashes;\n uint256 ownerCount;\n uint256 threshold;\n uint256 counter;\n}\n\nlibrary LibMultiSigStorage {\n function multisigStorage()\n internal\n pure\n returns (MultiSigStorage storage ds)\n {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.MultiSigStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n}\n" + }, + "contracts/libraries/LibRecoverSpender.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title RecoverSpender\n * @dev Library to determine the action and spender of calldata\n * @author Ruslan Serebriakov (@rsrbk)\n */\nlibrary LibRecoverSpender {\n // ERC20, ERC721 & ERC1155 transfers & approvals\n bytes4 private constant ERC20_TRANSFER =\n bytes4(keccak256(\"transfer(address,uint256)\"));\n bytes4 private constant ERC20_APPROVE =\n bytes4(keccak256(\"approve(address,uint256)\"));\n bytes4 private constant ERC20_INCREASE_ALLOWANCE =\n bytes4(keccak256(\"increaseAllowance(address,uint256)\"));\n bytes4 private constant ERC20_DECREASE_ALLOWANCE =\n bytes4(keccak256(\"decreaseAllowance(address,uint256)\"));\n bytes4 private constant ERC721_SET_APPROVAL_FOR_ALL =\n bytes4(keccak256(\"setApprovalForAll(address,bool)\"));\n bytes4 private constant ERC721_TRANSFER_FROM =\n bytes4(keccak256(\"transferFrom(address,address,uint256)\"));\n bytes4 private constant ERC721_SAFE_TRANSFER_FROM =\n bytes4(keccak256(\"safeTransferFrom(address,address,uint256)\"));\n bytes4 private constant ERC721_SAFE_TRANSFER_FROM_BYTES =\n bytes4(keccak256(\"safeTransferFrom(address,address,uint256,bytes)\"));\n bytes4 private constant ERC1155_SAFE_TRANSFER_FROM =\n bytes4(\n keccak256(\"safeTransferFrom(address,address,uint256,uint256,bytes)\")\n );\n bytes4 private constant ERC1155_SAFE_BATCH_TRANSFER_FROM =\n bytes4(\n keccak256(\n \"safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)\"\n )\n );\n\n /**\n * @notice Helper method to recover the spender from a contract call.\n * The method returns the contract unless the call is to a standard method of a ERC20/ERC721/ERC1155 token\n * in which case the spender is recovered from the data.\n * @param _to The target contract.\n * @param _data The data payload.\n */\n function _recover(\n address _to,\n bytes memory _data\n ) internal pure returns (address spender) {\n if (_data.length >= 68) {\n bytes4 methodId;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n methodId := mload(add(_data, 0x20))\n }\n if (\n methodId == ERC20_TRANSFER ||\n methodId == ERC20_APPROVE ||\n methodId == ERC20_INCREASE_ALLOWANCE ||\n methodId == ERC20_DECREASE_ALLOWANCE ||\n methodId == ERC721_SET_APPROVAL_FOR_ALL\n ) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n spender := mload(add(_data, 0x24))\n }\n return spender;\n }\n if (\n methodId == ERC721_TRANSFER_FROM ||\n methodId == ERC721_SAFE_TRANSFER_FROM ||\n methodId == ERC721_SAFE_TRANSFER_FROM_BYTES ||\n methodId == ERC1155_SAFE_TRANSFER_FROM ||\n methodId == ERC1155_SAFE_BATCH_TRANSFER_FROM\n ) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n spender := mload(add(_data, 0x44))\n }\n return spender;\n }\n }\n\n spender = _to;\n }\n}\n" + }, + "contracts/libraries/LibUtils.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\n\nlibrary LibUtils {\n // Internal utility functions\n function mergeArrays(\n bytes4[] memory _array1,\n bytes4[] memory _array2\n ) internal pure returns (bytes4[] memory) {\n uint256 length1 = _array1.length;\n uint256 length2 = _array2.length;\n bytes4[] memory mergedArray = new bytes4[](length1 + length2);\n\n for (uint256 i; i < length1; ) {\n mergedArray[i] = _array1[i];\n unchecked {\n ++i;\n }\n }\n\n for (uint256 i; i < length2; ) {\n mergedArray[length1 + i] = _array2[i];\n unchecked {\n ++i;\n }\n }\n\n return mergedArray;\n }\n\n function removeFacetElement(\n IDiamondLoupe.Facet[] memory _facets,\n uint256 _index\n ) internal pure returns (IDiamondLoupe.Facet[] memory) {\n require(_index < _facets.length, \"Invalid index\");\n require(_facets.length != 0, \"Invalid array\");\n\n // Create a new array with a length of `_facets.length - 1`\n IDiamondLoupe.Facet[] memory newArray = new IDiamondLoupe.Facet[](\n _facets.length - 1\n );\n uint256 newArrayLength = newArray.length;\n // Iterate over the original array, skipping the element at the specified `index`\n for (uint256 i; i < newArrayLength; ) {\n if (i < _index) {\n newArray[i] = _facets[i];\n } else {\n newArray[i] = _facets[i + 1];\n }\n unchecked {\n ++i;\n }\n }\n\n return newArray;\n }\n\n function removeElement(\n bytes4[] memory _array,\n uint256 _index\n ) internal pure returns (bytes4[] memory) {\n require(_index < _array.length, \"Invalid index\");\n require(_array.length != 0, \"Invalid array\");\n\n bytes4[] memory newArray = new bytes4[](_array.length - 1);\n uint256 newArrayLength = newArray.length;\n for (uint256 i; i < newArrayLength; ) {\n if (i < _index) {\n newArray[i] = _array[i];\n } else {\n newArray[i] = _array[i + 1];\n }\n unchecked {\n ++i;\n }\n }\n\n return newArray;\n }\n\n function setValue(\n bytes4[] memory _keys,\n address[] memory _values,\n bytes4 _key,\n address _value\n ) internal pure returns (bytes4[] memory, address[] memory) {\n uint256 index = findIndex(_keys, _key);\n uint256 keysLength = _keys.length;\n if (index < keysLength) {\n _values[index] = _value;\n } else {\n // Create new storage arrays\n bytes4[] memory newKeys = new bytes4[](keysLength + 1);\n address[] memory newValues = new address[](_values.length + 1);\n\n // Copy values to the new storage arrays\n for (uint256 i; i < keysLength; ) {\n newKeys[i] = _keys[i];\n newValues[i] = _values[i];\n\n unchecked {\n ++i;\n }\n }\n\n // Add the new key-value pair\n newKeys[keysLength] = _key;\n newValues[_values.length] = _value;\n\n return (newKeys, newValues);\n }\n\n // If the key already exists, return the original arrays\n return (_keys, _values);\n }\n\n function getValue(\n bytes4[] memory _keys,\n address[] memory _values,\n bytes4 _key\n ) internal pure returns (address) {\n uint256 index = findIndex(_keys, _key);\n if (index >= _keys.length) return address(0);\n\n return _values[index];\n }\n\n function findIndex(\n bytes4[] memory _keys,\n bytes4 _key\n ) internal pure returns (uint256) {\n uint256 keysLength = _keys.length;\n for (uint256 i; i < keysLength; ) {\n if (_keys[i] == _key) {\n return i;\n }\n unchecked {\n ++i;\n }\n }\n return keysLength;\n }\n}\n" + }, + "contracts/restrictions/IRestriction.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Interface for restrictions\n * @dev Restriction is a contract which decides whether to approve a certain kind of transaction, based on its internal logic.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface IRestriction {\n /**\n * @dev Based on restriction's internal logic, it should accept or reject a certain transaction.\n * @param from The address of the sender, that will be signing the transaction.\n * @param to The receiving address.\n * @param value Amount of ETH to transfer from sender to recipient.\n * @param _calldata Optional field to include arbitrary data.\n * @return bool value for whether the check is passed\n */\n function check(\n address from,\n address to,\n uint256 value,\n bytes calldata _calldata\n ) external returns (bool);\n}\n" + }, + "contracts/restrictions/WhitelistRestriction.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibRecoverSpender} from \"../libraries/LibRecoverSpender.sol\";\nimport {WhitelistStorage} from \"../infrastructure/WhitelistStorage.sol\";\nimport {IRestriction} from \"./IRestriction.sol\";\n\n/**\n * @title Whitelist Restriction\n * @dev This restriction defines a list of accepted addresses and denies any interaction with addresses outside of it.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract WhitelistRestriction is IRestriction {\n WhitelistStorage public immutable whitelistStorage;\n\n constructor(WhitelistStorage _whitelistStorage) {\n whitelistStorage = _whitelistStorage;\n }\n\n /**\n * @notice Helper method to recover the spender from a contract call.\n * The method returns the contract unless the call is to a standard method of a ERC20/ERC721/ERC1155 token\n * in which case the spender is recovered from the data.\n * @param _to The target contract.\n * @param _data The data payload.\n */\n function recoverSpender(\n address _to,\n bytes memory _data\n ) public pure returns (address spender) {\n return LibRecoverSpender._recover(_to, _data);\n }\n\n /*\n * @dev IRestriction's implementation. It will allow transaction if the sender is whitelisted, or user, or the whitelist storage.\n * @param _from The address of the sender, that will be signing the transaction.\n * @param _to The receiving address.\n * @param _calldata Optional field to include arbitrary data.\n * @return result value for whether the check is passed\n */\n function check(\n address _from,\n address _to,\n uint256 /*_value*/,\n bytes calldata _calldata\n ) external view override returns (bool result) {\n return\n whitelistStorage.isWhitelisted(\n _from,\n LibRecoverSpender._recover(_to, _calldata)\n ) ||\n _to == address(whitelistStorage) ||\n _to == msg.sender;\n }\n}\n" + }, + "contracts/test/Counter.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\ncontract TestCounter {\n int private count = 0;\n\n function incrementCounter() public {\n count += 1;\n }\n\n function decrementCounter() public {\n count -= 1;\n }\n\n function getCount() public view returns (int) {\n return count;\n }\n}\n" + }, + "contracts/test/TestERC1155.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC1155/ERC1155.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\n\ncontract TestERC1155 is ERC1155 {\n using Counters for Counters.Counter;\n\n Counters.Counter private _tokenIds;\n\n constructor() ERC1155(\"\") {}\n\n function mint(address account, uint256 amount) external {\n uint256 tokenId = _getNextTokenId();\n _mint(account, tokenId, amount, \"\");\n }\n\n function mintBatch(\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes memory data\n ) external {\n require(\n ids.length == amounts.length,\n \"TestERC1155: arrays length mismatch\"\n );\n\n _mintBatch(to, ids, amounts, data);\n }\n\n function _getNextTokenId() private returns (uint256) {\n _tokenIds.increment();\n return _tokenIds.current();\n }\n}\n" + }, + "contracts/test/TestERC777.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC777/ERC777.sol\";\n\ncontract TestERC777 is ERC777 {\n constructor(\n address[] memory _operators\n ) ERC777(\"TestERC777\", \"TERC777\", _operators) {}\n\n function mint(address account, uint256 amount) external {\n _mint(account, amount, \"\", \"\");\n }\n}\n" + }, + "contracts/test/TestInvalidSecp256k1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IVerificationFacet} from \"../facets/interfaces/IVerificationFacet.sol\";\nimport {IERC1271} from \"../interfaces/ERC/IERC1271.sol\";\nimport {AppStorage, LibAppStorage, BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {LibFacetStorage, Secp256k1VerificationStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {UserOperation} from \"../aa-4337/interfaces/UserOperation.sol\";\n\n/**\n * @title Test Secp256k1 verification facet\n * @dev Default Ethereum's elliptic curve\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract TestInvalidSecp256k1VerificationFacet is BarzStorage, IERC1271 {\n using ECDSA for bytes32;\n error Secp256k1VerificationFacet__InvalidSignerLength();\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n\n event SignerUninitialized();\n\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n }\n\n // THIS INVALID FACET DOES NOT INCLUDE initializeSigner()\n // THIS FACET IS USED TO TEST WHEN initializeSigner() DOESN'T EXIST IN FACET\n\n function uninitializeSigner() external returns (uint256 uninitSuccess) {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view returns (uint256 validationData) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n return validateSignature(userOp, userOpHash, k1Storage.signer);\n }\n\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n address signer\n ) public pure returns (uint256) {\n bytes32 hash = userOpHash.toEthSignedMessageHash();\n if (signer != hash.recover(userOp.signature)) return 1;\n return 0;\n }\n\n // This is REMOVED for testing purpose\n function validateOwnerSignatureSelector() public pure returns (bytes4) {\n // return this.validateOwnerSignature.selector;\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n function owner() public view returns (bytes memory) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n return abi.encodePacked(k1Storage.signer);\n }\n\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure returns (bool) {\n return (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (_hash.recover(_signature) ==\n LibFacetStorage.k1Storage().signer)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n}\n" + }, + "contracts/test/TestNFT.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\n\ncontract TestNFT is ERC721 {\n using Counters for Counters.Counter;\n Counters.Counter private currentTokenId;\n\n constructor() ERC721(\"TestNFT\", \"TNFT\") {}\n\n function mint(address recipient) public returns (uint256) {\n currentTokenId.increment();\n uint256 newItemId = currentTokenId.current();\n _safeMint(recipient, newItemId);\n return newItemId;\n }\n}\n" + }, + "contracts/test/TestToken.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract TestToken is ERC20 {\n constructor()\n // solhint-disable-next-line no-empty-blocks\n ERC20(\"TST\", \"TestToken\")\n {}\n\n function mint(address sender, uint256 amount) external {\n _mint(sender, amount);\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 999999 + }, + "evmVersion": "paris", + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/deployments/arbitrum/solcInputs/167a830377988095f5f829bf03425fb0.json b/deployments/arbitrum/solcInputs/167a830377988095f5f829bf03425fb0.json new file mode 100644 index 0000000..2833a16 --- /dev/null +++ b/deployments/arbitrum/solcInputs/167a830377988095f5f829bf03425fb0.json @@ -0,0 +1,354 @@ +{ + "language": "Solidity", + "sources": { + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby disabling any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable2Step.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./Ownable.sol\";\n\n/**\n * @dev Contract module which provides access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership} and {acceptOwnership}.\n *\n * This module is used through inheritance. It will make available all functions\n * from parent (Ownable).\n */\nabstract contract Ownable2Step is Ownable {\n address private _pendingOwner;\n\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Returns the address of the pending owner.\n */\n function pendingOwner() public view virtual returns (address) {\n return _pendingOwner;\n }\n\n /**\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual override onlyOwner {\n _pendingOwner = newOwner;\n emit OwnershipTransferStarted(owner(), newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual override {\n delete _pendingOwner;\n super._transferOwnership(newOwner);\n }\n\n /**\n * @dev The new owner accepts the ownership transfer.\n */\n function acceptOwnership() public virtual {\n address sender = _msgSender();\n require(pendingOwner() == sender, \"Ownable2Step: caller is not the new owner\");\n _transferOwnership(sender);\n }\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC1271.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC1271 standard signature validation method for\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\n *\n * _Available since v4.1._\n */\ninterface IERC1271 {\n /**\n * @dev Should return whether the signature provided is valid for the provided data\n * @param hash Hash of the data to be signed\n * @param signature Signature byte array associated with _data\n */\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\n}\n" + }, + "@openzeppelin/contracts/security/ReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor() {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n _nonReentrantBefore();\n _;\n _nonReentrantAfter();\n }\n\n function _nonReentrantBefore() private {\n // On the first call to nonReentrant, _status will be _NOT_ENTERED\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n }\n\n function _nonReentrantAfter() private {\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Returns true if the reentrancy guard is currently set to \"entered\", which indicates there is a\n * `nonReentrant` function in the call stack.\n */\n function _reentrancyGuardEntered() internal view returns (bool) {\n return _status == _ENTERED;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/ERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/ERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC1155.sol\";\nimport \"./IERC1155Receiver.sol\";\nimport \"./extensions/IERC1155MetadataURI.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of the basic standard multi-token.\n * See https://eips.ethereum.org/EIPS/eip-1155\n * Originally based on code by Enjin: https://github.com/enjin/erc-1155\n *\n * _Available since v3.1._\n */\ncontract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {\n using Address for address;\n\n // Mapping from token ID to account balances\n mapping(uint256 => mapping(address => uint256)) private _balances;\n\n // Mapping from account to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json\n string private _uri;\n\n /**\n * @dev See {_setURI}.\n */\n constructor(string memory uri_) {\n _setURI(uri_);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return\n interfaceId == type(IERC1155).interfaceId ||\n interfaceId == type(IERC1155MetadataURI).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC1155MetadataURI-uri}.\n *\n * This implementation returns the same URI for *all* token types. It relies\n * on the token type ID substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * Clients calling this function must replace the `\\{id\\}` substring with the\n * actual token type ID.\n */\n function uri(uint256) public view virtual override returns (string memory) {\n return _uri;\n }\n\n /**\n * @dev See {IERC1155-balanceOf}.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {\n require(account != address(0), \"ERC1155: address zero is not a valid owner\");\n return _balances[id][account];\n }\n\n /**\n * @dev See {IERC1155-balanceOfBatch}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] memory accounts,\n uint256[] memory ids\n ) public view virtual override returns (uint256[] memory) {\n require(accounts.length == ids.length, \"ERC1155: accounts and ids length mismatch\");\n\n uint256[] memory batchBalances = new uint256[](accounts.length);\n\n for (uint256 i = 0; i < accounts.length; ++i) {\n batchBalances[i] = balanceOf(accounts[i], ids[i]);\n }\n\n return batchBalances;\n }\n\n /**\n * @dev See {IERC1155-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC1155-isApprovedForAll}.\n */\n function isApprovedForAll(address account, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[account][operator];\n }\n\n /**\n * @dev See {IERC1155-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n _safeTransferFrom(from, to, id, amount, data);\n }\n\n /**\n * @dev See {IERC1155-safeBatchTransferFrom}.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n _safeBatchTransferFrom(from, to, ids, amounts, data);\n }\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n\n emit TransferSingle(operator, from, to, id, amount);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n for (uint256 i = 0; i < ids.length; ++i) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n }\n\n emit TransferBatch(operator, from, to, ids, amounts);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\n\n _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);\n }\n\n /**\n * @dev Sets a new URI for all token types, by relying on the token type ID\n * substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * By this mechanism, any occurrence of the `\\{id\\}` substring in either the\n * URI or any of the amounts in the JSON file at said URI will be replaced by\n * clients with the token type ID.\n *\n * For example, the `https://token-cdn-domain/\\{id\\}.json` URI would be\n * interpreted by clients as\n * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`\n * for token type ID 0x4cce0.\n *\n * See {uri}.\n *\n * Because these URIs cannot be meaningfully represented by the {URI} event,\n * this function emits no events.\n */\n function _setURI(string memory newuri) internal virtual {\n _uri = newuri;\n }\n\n /**\n * @dev Creates `amount` tokens of token type `id`, and assigns them to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _mint(address to, uint256 id, uint256 amount, bytes memory data) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _balances[id][to] += amount;\n emit TransferSingle(operator, address(0), to, id, amount);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n for (uint256 i = 0; i < ids.length; i++) {\n _balances[ids[i]][to] += amounts[i];\n }\n\n emit TransferBatch(operator, address(0), to, ids, amounts);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);\n }\n\n /**\n * @dev Destroys `amount` tokens of token type `id` from `from`\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `from` must have at least `amount` tokens of token type `id`.\n */\n function _burn(address from, uint256 id, uint256 amount) internal virtual {\n require(from != address(0), \"ERC1155: burn from the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n\n emit TransferSingle(operator, from, address(0), id, amount);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n */\n function _burnBatch(address from, uint256[] memory ids, uint256[] memory amounts) internal virtual {\n require(from != address(0), \"ERC1155: burn from the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n\n for (uint256 i = 0; i < ids.length; i++) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n }\n\n emit TransferBatch(operator, from, address(0), ids, amounts);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {\n require(owner != operator, \"ERC1155: setting approval status for self\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning, as well as batched variants.\n *\n * The same hook is called on both single and batched variants. For single\n * transfers, the length of the `ids` and `amounts` arrays will be 1.\n *\n * Calling conditions (for each `id` and `amount` pair):\n *\n * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * of token type `id` will be transferred to `to`.\n * - When `from` is zero, `amount` tokens of token type `id` will be minted\n * for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n * will be burned.\n * - `from` and `to` are never both zero.\n * - `ids` and `amounts` have the same, non-zero length.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any token transfer. This includes minting\n * and burning, as well as batched variants.\n *\n * The same hook is called on both single and batched variants. For single\n * transfers, the length of the `id` and `amount` arrays will be 1.\n *\n * Calling conditions (for each `id` and `amount` pair):\n *\n * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * of token type `id` will be transferred to `to`.\n * - When `from` is zero, `amount` tokens of token type `id` will be minted\n * for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n * will be burned.\n * - `from` and `to` are never both zero.\n * - `ids` and `amounts` have the same, non-zero length.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {}\n\n function _doSafeTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155Receiver.onERC1155Received.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non-ERC1155Receiver implementer\");\n }\n }\n }\n\n function _doSafeBatchTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (\n bytes4 response\n ) {\n if (response != IERC1155Receiver.onERC1155BatchReceived.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non-ERC1155Receiver implementer\");\n }\n }\n }\n\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {\n uint256[] memory array = new uint256[](1);\n array[0] = element;\n\n return array;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC1155.sol\";\n\n/**\n * @dev Interface of the optional ERC1155MetadataExtension interface, as defined\n * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155MetadataURI is IERC1155 {\n /**\n * @dev Returns the URI for token type `id`.\n *\n * If the `\\{id\\}` substring is present in the URI, it must be replaced by\n * clients with the actual token type ID.\n */\n function uri(uint256 id) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155 is IERC165 {\n /**\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n */\n event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);\n\n /**\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n * transfers.\n */\n event TransferBatch(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\n\n /**\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n * `approved`.\n */\n event ApprovalForAll(address indexed account, address indexed operator, bool approved);\n\n /**\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n *\n * If an {URI} event was emitted for `id`, the standard\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n * returned by {IERC1155MetadataURI-uri}.\n */\n event URI(string value, uint256 indexed id);\n\n /**\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) external view returns (uint256);\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] calldata accounts,\n uint256[] calldata ids\n ) external view returns (uint256[] memory);\n\n /**\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n *\n * Emits an {ApprovalForAll} event.\n *\n * Requirements:\n *\n * - `operator` cannot be the caller.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n *\n * See {setApprovalForAll}.\n */\n function isApprovedForAll(address account, address operator) external view returns (bool);\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155Receiver is IERC165 {\n /**\n * @dev Handles the receipt of a single ERC1155 token type. This function is\n * called at the end of a `safeTransferFrom` after the balance has been updated.\n *\n * NOTE: To accept the transfer, this must return\n * `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n * (i.e. 0xf23a6e61, or its own function selector).\n *\n * @param operator The address which initiated the transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param id The ID of the token being transferred\n * @param value The amount of tokens being transferred\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n ) external returns (bytes4);\n\n /**\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\n * is called at the end of a `safeBatchTransferFrom` after the balances have\n * been updated.\n *\n * NOTE: To accept the transfer(s), this must return\n * `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n * (i.e. 0xbc197c81, or its own function selector).\n *\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the default value returned by this function, unless\n * it's overridden.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(address from, address to, uint256 amount) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\n // decrementing then incrementing.\n _balances[to] += amount;\n }\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n unchecked {\n // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\n _balances[account] += amount;\n }\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n // Overflow not possible: amount <= accountBalance <= totalSupply.\n _totalSupply -= amount;\n }\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\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" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` 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 amount) 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 `amount` as the allowance of `spender` over the 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 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` 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 amount) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/ERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721.sol\";\nimport \"./IERC721Receiver.sol\";\nimport \"./extensions/IERC721Metadata.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/Strings.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\n using Address for address;\n using Strings for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\n\n // Mapping from token ID to approved address\n mapping(uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return\n interfaceId == type(IERC721).interfaceId ||\n interfaceId == type(IERC721Metadata).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _ownerOf(tokenId);\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token owner or approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n _requireMinted(tokenId);\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n _safeTransfer(from, to, tokenId, data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(address from, address to, uint256 tokenId, bytes memory data) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist\n */\n function _ownerOf(uint256 tokenId) internal view virtual returns (address) {\n return _owners[tokenId];\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _ownerOf(tokenId) != address(0);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n address owner = ERC721.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(address to, uint256 tokenId, bytes memory data) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId, 1);\n\n // Check that tokenId was not minted by `_beforeTokenTransfer` hook\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n unchecked {\n // Will not overflow unless all 2**256 token ids are minted to the same owner.\n // Given that tokens are minted one by one, it is impossible in practice that\n // this ever happens. Might change if we allow batch minting.\n // The ERC fails to describe this case.\n _balances[to] += 1;\n }\n\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(address(0), to, tokenId, 1);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n * This is an internal function that does not check if the sender is authorized to operate on the token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId, 1);\n\n // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook\n owner = ERC721.ownerOf(tokenId);\n\n // Clear approvals\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // Cannot overflow, as that would require more tokens to be burned/transferred\n // out than the owner initially received through minting and transferring in.\n _balances[owner] -= 1;\n }\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(owner, address(0), tokenId, 1);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(address from, address to, uint256 tokenId) internal virtual {\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId, 1);\n\n // Check that tokenId was not transferred by `_beforeTokenTransfer` hook\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n\n // Clear approvals from the previous owner\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // `_balances[from]` cannot overflow for the same reason as described in `_burn`:\n // `from`'s balance is the number of token held, which is at least one before the current\n // transfer.\n // `_balances[to]` could overflow in the conditions described in `_mint`. That would require\n // all 2**256 token ids to be minted, which in practice is impossible.\n _balances[from] -= 1;\n _balances[to] += 1;\n }\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId, 1);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721Receiver.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`.\n * - When `from` is zero, the tokens will be minted for `to`.\n * - When `to` is zero, ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}\n\n /**\n * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`.\n * - When `from` is zero, the tokens were minted for `to`.\n * - When `to` is zero, ``from``'s tokens were burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}\n\n /**\n * @dev Unsafe write access to the balances, used by extensions that \"mint\" tokens using an {ownerOf} override.\n *\n * WARNING: Anyone calling this MUST ensure that the balances remain consistent with the ownership. The invariant\n * being that for any address `a` the value returned by `balanceOf(a)` must be equal to the number of tokens such\n * that `ownerOf(tokenId)` is `a`.\n */\n // solhint-disable-next-line func-name-mixedcase\n function __unsafe_increaseBalance(address account, uint256 amount) internal {\n _balances[account] += amount;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721Receiver {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/ERC777.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC777/ERC777.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC777.sol\";\nimport \"./IERC777Recipient.sol\";\nimport \"./IERC777Sender.sol\";\nimport \"../ERC20/IERC20.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/introspection/IERC1820Registry.sol\";\n\n/**\n * @dev Implementation of the {IERC777} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n *\n * Support for ERC20 is included in this contract, as specified by the EIP: both\n * the ERC777 and ERC20 interfaces can be safely used when interacting with it.\n * Both {IERC777-Sent} and {IERC20-Transfer} events are emitted on token\n * movements.\n *\n * Additionally, the {IERC777-granularity} value is hard-coded to `1`, meaning that there\n * are no special restrictions in the amount of tokens that created, moved, or\n * destroyed. This makes integration with ERC20 applications seamless.\n *\n * CAUTION: This file is deprecated as of v4.9 and will be removed in the next major release.\n */\ncontract ERC777 is Context, IERC777, IERC20 {\n using Address for address;\n\n IERC1820Registry internal constant _ERC1820_REGISTRY = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n mapping(address => uint256) private _balances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n bytes32 private constant _TOKENS_SENDER_INTERFACE_HASH = keccak256(\"ERC777TokensSender\");\n bytes32 private constant _TOKENS_RECIPIENT_INTERFACE_HASH = keccak256(\"ERC777TokensRecipient\");\n\n // This isn't ever read from - it's only used to respond to the defaultOperators query.\n address[] private _defaultOperatorsArray;\n\n // Immutable, but accounts may revoke them (tracked in __revokedDefaultOperators).\n mapping(address => bool) private _defaultOperators;\n\n // For each account, a mapping of its operators and revoked default operators.\n mapping(address => mapping(address => bool)) private _operators;\n mapping(address => mapping(address => bool)) private _revokedDefaultOperators;\n\n // ERC20-allowances\n mapping(address => mapping(address => uint256)) private _allowances;\n\n /**\n * @dev `defaultOperators` may be an empty array.\n */\n constructor(string memory name_, string memory symbol_, address[] memory defaultOperators_) {\n _name = name_;\n _symbol = symbol_;\n\n _defaultOperatorsArray = defaultOperators_;\n for (uint256 i = 0; i < defaultOperators_.length; i++) {\n _defaultOperators[defaultOperators_[i]] = true;\n }\n\n // register interfaces\n _ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256(\"ERC777Token\"), address(this));\n _ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256(\"ERC20Token\"), address(this));\n }\n\n /**\n * @dev See {IERC777-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC777-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {ERC20-decimals}.\n *\n * Always returns 18, as per the\n * [ERC777 EIP](https://eips.ethereum.org/EIPS/eip-777#backward-compatibility).\n */\n function decimals() public pure virtual returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC777-granularity}.\n *\n * This implementation always returns `1`.\n */\n function granularity() public view virtual override returns (uint256) {\n return 1;\n }\n\n /**\n * @dev See {IERC777-totalSupply}.\n */\n function totalSupply() public view virtual override(IERC20, IERC777) returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev Returns the amount of tokens owned by an account (`tokenHolder`).\n */\n function balanceOf(address tokenHolder) public view virtual override(IERC20, IERC777) returns (uint256) {\n return _balances[tokenHolder];\n }\n\n /**\n * @dev See {IERC777-send}.\n *\n * Also emits a {IERC20-Transfer} event for ERC20 compatibility.\n */\n function send(address recipient, uint256 amount, bytes memory data) public virtual override {\n _send(_msgSender(), recipient, amount, data, \"\", true);\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Unlike `send`, `recipient` is _not_ required to implement the {IERC777Recipient}\n * interface if it is a contract.\n *\n * Also emits a {Sent} event.\n */\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n _send(_msgSender(), recipient, amount, \"\", \"\", false);\n return true;\n }\n\n /**\n * @dev See {IERC777-burn}.\n *\n * Also emits a {IERC20-Transfer} event for ERC20 compatibility.\n */\n function burn(uint256 amount, bytes memory data) public virtual override {\n _burn(_msgSender(), amount, data, \"\");\n }\n\n /**\n * @dev See {IERC777-isOperatorFor}.\n */\n function isOperatorFor(address operator, address tokenHolder) public view virtual override returns (bool) {\n return\n operator == tokenHolder ||\n (_defaultOperators[operator] && !_revokedDefaultOperators[tokenHolder][operator]) ||\n _operators[tokenHolder][operator];\n }\n\n /**\n * @dev See {IERC777-authorizeOperator}.\n */\n function authorizeOperator(address operator) public virtual override {\n require(_msgSender() != operator, \"ERC777: authorizing self as operator\");\n\n if (_defaultOperators[operator]) {\n delete _revokedDefaultOperators[_msgSender()][operator];\n } else {\n _operators[_msgSender()][operator] = true;\n }\n\n emit AuthorizedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-revokeOperator}.\n */\n function revokeOperator(address operator) public virtual override {\n require(operator != _msgSender(), \"ERC777: revoking self as operator\");\n\n if (_defaultOperators[operator]) {\n _revokedDefaultOperators[_msgSender()][operator] = true;\n } else {\n delete _operators[_msgSender()][operator];\n }\n\n emit RevokedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-defaultOperators}.\n */\n function defaultOperators() public view virtual override returns (address[] memory) {\n return _defaultOperatorsArray;\n }\n\n /**\n * @dev See {IERC777-operatorSend}.\n *\n * Emits {Sent} and {IERC20-Transfer} events.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes memory data,\n bytes memory operatorData\n ) public virtual override {\n require(isOperatorFor(_msgSender(), sender), \"ERC777: caller is not an operator for holder\");\n _send(sender, recipient, amount, data, operatorData, true);\n }\n\n /**\n * @dev See {IERC777-operatorBurn}.\n *\n * Emits {Burned} and {IERC20-Transfer} events.\n */\n function operatorBurn(\n address account,\n uint256 amount,\n bytes memory data,\n bytes memory operatorData\n ) public virtual override {\n require(isOperatorFor(_msgSender(), account), \"ERC777: caller is not an operator for holder\");\n _burn(account, amount, data, operatorData);\n }\n\n /**\n * @dev See {IERC20-allowance}.\n *\n * Note that operator and allowance concepts are orthogonal: operators may\n * not have allowance, and accounts with allowance may not be operators\n * themselves.\n */\n function allowance(address holder, address spender) public view virtual override returns (uint256) {\n return _allowances[holder][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Note that accounts cannot have allowance issued by their operators.\n */\n function approve(address spender, uint256 value) public virtual override returns (bool) {\n address holder = _msgSender();\n _approve(holder, spender, value);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Note that operator and allowance concepts are orthogonal: operators cannot\n * call `transferFrom` (unless they have allowance), and accounts with\n * allowance cannot call `operatorSend` (unless they are operators).\n *\n * Emits {Sent}, {IERC20-Transfer} and {IERC20-Approval} events.\n */\n function transferFrom(address holder, address recipient, uint256 amount) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(holder, spender, amount);\n _send(holder, recipient, amount, \"\", \"\", false);\n return true;\n }\n\n /**\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with the caller address as the `operator` and with\n * `userData` and `operatorData`.\n *\n * See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits {Minted} and {IERC20-Transfer} events.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - if `account` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function _mint(address account, uint256 amount, bytes memory userData, bytes memory operatorData) internal virtual {\n _mint(account, amount, userData, operatorData, true);\n }\n\n /**\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * If `requireReceptionAck` is set to true, and if a send hook is\n * registered for `account`, the corresponding function will be called with\n * `operator`, `data` and `operatorData`.\n *\n * See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits {Minted} and {IERC20-Transfer} events.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - if `account` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function _mint(\n address account,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) internal virtual {\n require(account != address(0), \"ERC777: mint to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), account, amount);\n\n // Update state variables\n _totalSupply += amount;\n _balances[account] += amount;\n\n _callTokensReceived(operator, address(0), account, amount, userData, operatorData, requireReceptionAck);\n\n emit Minted(operator, account, amount, userData, operatorData);\n emit Transfer(address(0), account, amount);\n }\n\n /**\n * @dev Send tokens\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _send(\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) internal virtual {\n require(from != address(0), \"ERC777: transfer from the zero address\");\n require(to != address(0), \"ERC777: transfer to the zero address\");\n\n address operator = _msgSender();\n\n _callTokensToSend(operator, from, to, amount, userData, operatorData);\n\n _move(operator, from, to, amount, userData, operatorData);\n\n _callTokensReceived(operator, from, to, amount, userData, operatorData, requireReceptionAck);\n }\n\n /**\n * @dev Burn tokens\n * @param from address token holder address\n * @param amount uint256 amount of tokens to burn\n * @param data bytes extra information provided by the token holder\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _burn(address from, uint256 amount, bytes memory data, bytes memory operatorData) internal virtual {\n require(from != address(0), \"ERC777: burn from the zero address\");\n\n address operator = _msgSender();\n\n _callTokensToSend(operator, from, address(0), amount, data, operatorData);\n\n _beforeTokenTransfer(operator, from, address(0), amount);\n\n // Update state variables\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC777: burn amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Burned(operator, from, amount, data, operatorData);\n emit Transfer(from, address(0), amount);\n }\n\n function _move(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n ) private {\n _beforeTokenTransfer(operator, from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC777: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Sent(operator, from, to, amount, userData, operatorData);\n emit Transfer(from, to, amount);\n }\n\n /**\n * @dev See {ERC20-_approve}.\n *\n * Note that accounts cannot have allowance issued by their operators.\n */\n function _approve(address holder, address spender, uint256 value) internal virtual {\n require(holder != address(0), \"ERC777: approve from the zero address\");\n require(spender != address(0), \"ERC777: approve to the zero address\");\n\n _allowances[holder][spender] = value;\n emit Approval(holder, spender, value);\n }\n\n /**\n * @dev Call from.tokensToSend() if the interface is registered\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _callTokensToSend(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n ) private {\n address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(from, _TOKENS_SENDER_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Sender(implementer).tokensToSend(operator, from, to, amount, userData, operatorData);\n }\n }\n\n /**\n * @dev Call to.tokensReceived() if the interface is registered. Reverts if the recipient is a contract but\n * tokensReceived() was not registered for the recipient\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _callTokensReceived(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) private {\n address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(to, _TOKENS_RECIPIENT_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Recipient(implementer).tokensReceived(operator, from, to, amount, userData, operatorData);\n } else if (requireReceptionAck) {\n require(!to.isContract(), \"ERC777: token recipient contract has no implementer for ERC777TokensRecipient\");\n }\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {IERC20-Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC777: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes\n * calls to {send}, {transfer}, {operatorSend}, {transferFrom}, minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be to transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address operator, address from, address to, uint256 amount) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC777/IERC777.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777Token standard as defined in the EIP.\n *\n * This contract uses the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 registry standard] to let\n * token holders and recipients react to token movements by using setting implementers\n * for the associated interfaces in said registry. See {IERC1820Registry} and\n * {ERC1820Implementer}.\n */\ninterface IERC777 {\n /**\n * @dev Emitted when `amount` tokens are created by `operator` and assigned to `to`.\n *\n * Note that some additional user `data` and `operatorData` can be logged in the event.\n */\n event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);\n\n /**\n * @dev Emitted when `operator` destroys `amount` tokens from `account`.\n *\n * Note that some additional user `data` and `operatorData` can be logged in the event.\n */\n event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);\n\n /**\n * @dev Emitted when `operator` is made operator for `tokenHolder`.\n */\n event AuthorizedOperator(address indexed operator, address indexed tokenHolder);\n\n /**\n * @dev Emitted when `operator` is revoked its operator status for `tokenHolder`.\n */\n event RevokedOperator(address indexed operator, address indexed tokenHolder);\n\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, usually a shorter version of the\n * name.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the smallest part of the token that is not divisible. This\n * means all token operations (creation, movement and destruction) must have\n * amounts that are a multiple of this number.\n *\n * For most token contracts, this value will equal 1.\n */\n function granularity() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by an account (`owner`).\n */\n function balanceOf(address owner) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * If send or receive hooks are registered for the caller and `recipient`,\n * the corresponding functions will be called with `data` and empty\n * `operatorData`. See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits a {Sent} event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function send(address recipient, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Destroys `amount` tokens from the caller's account, reducing the\n * total supply.\n *\n * If a send hook is registered for the caller, the corresponding function\n * will be called with `data` and empty `operatorData`. See {IERC777Sender}.\n *\n * Emits a {Burned} event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n */\n function burn(uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Returns true if an account is an operator of `tokenHolder`.\n * Operators can send and burn tokens on behalf of their owners. All\n * accounts are their own operator.\n *\n * See {operatorSend} and {operatorBurn}.\n */\n function isOperatorFor(address operator, address tokenHolder) external view returns (bool);\n\n /**\n * @dev Make an account an operator of the caller.\n *\n * See {isOperatorFor}.\n *\n * Emits an {AuthorizedOperator} event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function authorizeOperator(address operator) external;\n\n /**\n * @dev Revoke an account's operator status for the caller.\n *\n * See {isOperatorFor} and {defaultOperators}.\n *\n * Emits a {RevokedOperator} event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function revokeOperator(address operator) external;\n\n /**\n * @dev Returns the list of default operators. These accounts are operators\n * for all token holders, even if {authorizeOperator} was never called on\n * them.\n *\n * This list is immutable, but individual holders may revoke these via\n * {revokeOperator}, in which case {isOperatorFor} will return false.\n */\n function defaultOperators() external view returns (address[] memory);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must\n * be an operator of `sender`.\n *\n * If send or receive hooks are registered for `sender` and `recipient`,\n * the corresponding functions will be called with `data` and\n * `operatorData`. See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits a {Sent} event.\n *\n * Requirements\n *\n * - `sender` cannot be the zero address.\n * - `sender` must have at least `amount` tokens.\n * - the caller must be an operator for `sender`.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes calldata data,\n bytes calldata operatorData\n ) external;\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the total supply.\n * The caller must be an operator of `account`.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with `data` and `operatorData`. See {IERC777Sender}.\n *\n * Emits a {Burned} event.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n * - the caller must be an operator for `account`.\n */\n function operatorBurn(address account, uint256 amount, bytes calldata data, bytes calldata operatorData) external;\n\n event Sent(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes data,\n bytes operatorData\n );\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\n *\n * Accounts can be notified of {IERC777} tokens being sent to them by having a\n * contract implement this interface (contract holders can be their own\n * implementer) and registering it on the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\n *\n * See {IERC1820Registry} and {ERC1820Implementer}.\n */\ninterface IERC777Recipient {\n /**\n * @dev Called by an {IERC777} token contract whenever tokens are being\n * moved or created into a registered account (`to`). The type of operation\n * is conveyed by `from` being the zero address or not.\n *\n * This call occurs _after_ the token contract's state is updated, so\n * {IERC777-balanceOf}, etc., can be used to query the post-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensReceived(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777Sender.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Sender.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777TokensSender standard as defined in the EIP.\n *\n * {IERC777} Token holders can be notified of operations performed on their\n * tokens by having a contract implement this interface (contract holders can be\n * their own implementer) and registering it on the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\n *\n * See {IERC1820Registry} and {ERC1820Implementer}.\n */\ninterface IERC777Sender {\n /**\n * @dev Called by an {IERC777} token contract whenever a registered holder's\n * (`from`) tokens are about to be moved or destroyed. The type of operation\n * is conveyed by `to` being the zero address or not.\n *\n * This call occurs _before_ the token contract's state is updated, so\n * {IERC777-balanceOf}, etc., can be used to query the pre-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensToSend(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n *\n * Furthermore, `isContract` will also return true if the target contract within\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n * which only has an effect at the end of a transaction.\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Counters.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary Counters {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/ECDSA.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Strings.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV // Deprecated in v4.8\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n /// @solidity memory-safe-assembly\n assembly {\n mstore(0x00, \"\\x19Ethereum Signed Message:\\n32\")\n mstore(0x1c, hash)\n message := keccak256(0x00, 0x3c)\n }\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\n /// @solidity memory-safe-assembly\n assembly {\n let ptr := mload(0x40)\n mstore(ptr, \"\\x19\\x01\")\n mstore(add(ptr, 0x02), domainSeparator)\n mstore(add(ptr, 0x22), structHash)\n data := keccak256(ptr, 0x42)\n }\n }\n\n /**\n * @dev Returns an Ethereum Signed Data with intended validator, created from a\n * `validator` and `data` according to the version 0 of EIP-191.\n *\n * See {recover}.\n */\n function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x00\", validator, data));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/SignatureChecker.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSA.sol\";\nimport \"../../interfaces/IERC1271.sol\";\n\n/**\n * @dev Signature verification helper that can be used instead of `ECDSA.recover` to seamlessly support both ECDSA\n * signatures from externally owned accounts (EOAs) as well as ERC1271 signatures from smart contract wallets like\n * Argent and Gnosis Safe.\n *\n * _Available since v4.1._\n */\nlibrary SignatureChecker {\n /**\n * @dev Checks if a signature is valid for a given signer and data hash. If the signer is a smart contract, the\n * signature is validated against that smart contract using ERC1271, otherwise it's validated using `ECDSA.recover`.\n *\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\n */\n function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature) internal view returns (bool) {\n (address recovered, ECDSA.RecoverError error) = ECDSA.tryRecover(hash, signature);\n return\n (error == ECDSA.RecoverError.NoError && recovered == signer) ||\n isValidERC1271SignatureNow(signer, hash, signature);\n }\n\n /**\n * @dev Checks if a signature is valid for a given signer and data hash. The signature is validated\n * against the signer smart contract using ERC1271.\n *\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\n */\n function isValidERC1271SignatureNow(\n address signer,\n bytes32 hash,\n bytes memory signature\n ) internal view returns (bool) {\n (bool success, bytes memory result) = signer.staticcall(\n abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, signature)\n );\n return (success &&\n result.length >= 32 &&\n abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/ERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165 is IERC165 {\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165).interfaceId;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC1820Registry.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/introspection/IERC1820Registry.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the global ERC1820 Registry, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register\n * implementers for interfaces in this registry, as well as query support.\n *\n * Implementers may be shared by multiple accounts, and can also implement more\n * than a single interface for each account. Contracts can implement interfaces\n * for themselves, but externally-owned accounts (EOA) must delegate this to a\n * contract.\n *\n * {IERC165} interfaces can also be queried via the registry.\n *\n * For an in-depth explanation and source code analysis, see the EIP text.\n */\ninterface IERC1820Registry {\n event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer);\n\n event ManagerChanged(address indexed account, address indexed newManager);\n\n /**\n * @dev Sets `newManager` as the manager for `account`. A manager of an\n * account is able to set interface implementers for it.\n *\n * By default, each account is its own manager. Passing a value of `0x0` in\n * `newManager` will reset the manager to this initial state.\n *\n * Emits a {ManagerChanged} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `account`.\n */\n function setManager(address account, address newManager) external;\n\n /**\n * @dev Returns the manager for `account`.\n *\n * See {setManager}.\n */\n function getManager(address account) external view returns (address);\n\n /**\n * @dev Sets the `implementer` contract as ``account``'s implementer for\n * `interfaceHash`.\n *\n * `account` being the zero address is an alias for the caller's address.\n * The zero address can also be used in `implementer` to remove an old one.\n *\n * See {interfaceHash} to learn how these are created.\n *\n * Emits an {InterfaceImplementerSet} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `account`.\n * - `interfaceHash` must not be an {IERC165} interface id (i.e. it must not\n * end in 28 zeroes).\n * - `implementer` must implement {IERC1820Implementer} and return true when\n * queried for support, unless `implementer` is the caller. See\n * {IERC1820Implementer-canImplementInterfaceForAddress}.\n */\n function setInterfaceImplementer(address account, bytes32 _interfaceHash, address implementer) external;\n\n /**\n * @dev Returns the implementer of `interfaceHash` for `account`. If no such\n * implementer is registered, returns the zero address.\n *\n * If `interfaceHash` is an {IERC165} interface id (i.e. it ends with 28\n * zeroes), `account` will be queried for support of it.\n *\n * `account` being the zero address is an alias for the caller's address.\n */\n function getInterfaceImplementer(address account, bytes32 _interfaceHash) external view returns (address);\n\n /**\n * @dev Returns the interface hash for an `interfaceName`, as defined in the\n * corresponding\n * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP].\n */\n function interfaceHash(string calldata interfaceName) external pure returns (bytes32);\n\n /**\n * @notice Updates the cache with whether the contract implements an ERC165 interface or not.\n * @param account Address of the contract for which to update the cache.\n * @param interfaceId ERC165 interface for which to update the cache.\n */\n function updateERC165Cache(address account, bytes4 interfaceId) external;\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not.\n * If the result is not cached a direct lookup on the contract address is performed.\n * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling\n * {updateERC165Cache} with the contract address.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool);\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not without using or updating the cache.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/math/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\n // The surrounding unchecked block does not change this fact.\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1, \"Math: mulDiv overflow\");\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n //\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n //\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n //\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1 << (log2(a) >> 1);\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = sqrt(a);\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 2, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 128;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 64;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 32;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 16;\n }\n if (value >> 8 > 0) {\n value >>= 8;\n result += 8;\n }\n if (value >> 4 > 0) {\n value >>= 4;\n result += 4;\n }\n if (value >> 2 > 0) {\n value >>= 2;\n result += 2;\n }\n if (value >> 1 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log2(value);\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 10, rounded down, of a positive value.\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 + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 256, rounded down, of a positive value.\n * Returns 0 if given 0.\n *\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n */\n function log256(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 16;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 8;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 4;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 2;\n }\n if (value >> 8 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log256(value);\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/SafeCast.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCast {\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 * _Available since v4.7._\n */\n function toUint248(uint256 value) internal pure returns (uint248) {\n require(value <= type(uint248).max, \"SafeCast: value doesn't fit in 248 bits\");\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 * _Available since v4.7._\n */\n function toUint240(uint256 value) internal pure returns (uint240) {\n require(value <= type(uint240).max, \"SafeCast: value doesn't fit in 240 bits\");\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 * _Available since v4.7._\n */\n function toUint232(uint256 value) internal pure returns (uint232) {\n require(value <= type(uint232).max, \"SafeCast: value doesn't fit in 232 bits\");\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 * _Available since v4.2._\n */\n function toUint224(uint256 value) internal pure returns (uint224) {\n require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\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 * _Available since v4.7._\n */\n function toUint216(uint256 value) internal pure returns (uint216) {\n require(value <= type(uint216).max, \"SafeCast: value doesn't fit in 216 bits\");\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 * _Available since v4.7._\n */\n function toUint208(uint256 value) internal pure returns (uint208) {\n require(value <= type(uint208).max, \"SafeCast: value doesn't fit in 208 bits\");\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 * _Available since v4.7._\n */\n function toUint200(uint256 value) internal pure returns (uint200) {\n require(value <= type(uint200).max, \"SafeCast: value doesn't fit in 200 bits\");\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 * _Available since v4.7._\n */\n function toUint192(uint256 value) internal pure returns (uint192) {\n require(value <= type(uint192).max, \"SafeCast: value doesn't fit in 192 bits\");\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 * _Available since v4.7._\n */\n function toUint184(uint256 value) internal pure returns (uint184) {\n require(value <= type(uint184).max, \"SafeCast: value doesn't fit in 184 bits\");\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 * _Available since v4.7._\n */\n function toUint176(uint256 value) internal pure returns (uint176) {\n require(value <= type(uint176).max, \"SafeCast: value doesn't fit in 176 bits\");\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 * _Available since v4.7._\n */\n function toUint168(uint256 value) internal pure returns (uint168) {\n require(value <= type(uint168).max, \"SafeCast: value doesn't fit in 168 bits\");\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 * _Available since v4.7._\n */\n function toUint160(uint256 value) internal pure returns (uint160) {\n require(value <= type(uint160).max, \"SafeCast: value doesn't fit in 160 bits\");\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 * _Available since v4.7._\n */\n function toUint152(uint256 value) internal pure returns (uint152) {\n require(value <= type(uint152).max, \"SafeCast: value doesn't fit in 152 bits\");\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 * _Available since v4.7._\n */\n function toUint144(uint256 value) internal pure returns (uint144) {\n require(value <= type(uint144).max, \"SafeCast: value doesn't fit in 144 bits\");\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 * _Available since v4.7._\n */\n function toUint136(uint256 value) internal pure returns (uint136) {\n require(value <= type(uint136).max, \"SafeCast: value doesn't fit in 136 bits\");\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 * _Available since v2.5._\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\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 * _Available since v4.7._\n */\n function toUint120(uint256 value) internal pure returns (uint120) {\n require(value <= type(uint120).max, \"SafeCast: value doesn't fit in 120 bits\");\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 * _Available since v4.7._\n */\n function toUint112(uint256 value) internal pure returns (uint112) {\n require(value <= type(uint112).max, \"SafeCast: value doesn't fit in 112 bits\");\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 * _Available since v4.7._\n */\n function toUint104(uint256 value) internal pure returns (uint104) {\n require(value <= type(uint104).max, \"SafeCast: value doesn't fit in 104 bits\");\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 * _Available since v4.2._\n */\n function toUint96(uint256 value) internal pure returns (uint96) {\n require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\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 * _Available since v4.7._\n */\n function toUint88(uint256 value) internal pure returns (uint88) {\n require(value <= type(uint88).max, \"SafeCast: value doesn't fit in 88 bits\");\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 * _Available since v4.7._\n */\n function toUint80(uint256 value) internal pure returns (uint80) {\n require(value <= type(uint80).max, \"SafeCast: value doesn't fit in 80 bits\");\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 * _Available since v4.7._\n */\n function toUint72(uint256 value) internal pure returns (uint72) {\n require(value <= type(uint72).max, \"SafeCast: value doesn't fit in 72 bits\");\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 * _Available since v2.5._\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\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 * _Available since v4.7._\n */\n function toUint56(uint256 value) internal pure returns (uint56) {\n require(value <= type(uint56).max, \"SafeCast: value doesn't fit in 56 bits\");\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 * _Available since v4.7._\n */\n function toUint48(uint256 value) internal pure returns (uint48) {\n require(value <= type(uint48).max, \"SafeCast: value doesn't fit in 48 bits\");\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 * _Available since v4.7._\n */\n function toUint40(uint256 value) internal pure returns (uint40) {\n require(value <= type(uint40).max, \"SafeCast: value doesn't fit in 40 bits\");\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 * _Available since v2.5._\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\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 * _Available since v4.7._\n */\n function toUint24(uint256 value) internal pure returns (uint24) {\n require(value <= type(uint24).max, \"SafeCast: value doesn't fit in 24 bits\");\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 * _Available since v2.5._\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\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 * _Available since v2.5._\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\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 * _Available since v3.0._\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\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 * _Available since v4.7._\n */\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\n downcasted = int248(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 248 bits\");\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 * _Available since v4.7._\n */\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\n downcasted = int240(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 240 bits\");\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 * _Available since v4.7._\n */\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\n downcasted = int232(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 232 bits\");\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 * _Available since v4.7._\n */\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\n downcasted = int224(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 224 bits\");\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 * _Available since v4.7._\n */\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\n downcasted = int216(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 216 bits\");\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 * _Available since v4.7._\n */\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\n downcasted = int208(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 208 bits\");\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 * _Available since v4.7._\n */\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\n downcasted = int200(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 200 bits\");\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 * _Available since v4.7._\n */\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\n downcasted = int192(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 192 bits\");\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 * _Available since v4.7._\n */\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\n downcasted = int184(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 184 bits\");\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 * _Available since v4.7._\n */\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\n downcasted = int176(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 176 bits\");\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 * _Available since v4.7._\n */\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\n downcasted = int168(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 168 bits\");\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 * _Available since v4.7._\n */\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\n downcasted = int160(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 160 bits\");\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 * _Available since v4.7._\n */\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\n downcasted = int152(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 152 bits\");\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 * _Available since v4.7._\n */\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\n downcasted = int144(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 144 bits\");\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 * _Available since v4.7._\n */\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\n downcasted = int136(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 136 bits\");\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 * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\n downcasted = int128(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 128 bits\");\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 * _Available since v4.7._\n */\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\n downcasted = int120(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 120 bits\");\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 * _Available since v4.7._\n */\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\n downcasted = int112(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 112 bits\");\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 * _Available since v4.7._\n */\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\n downcasted = int104(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 104 bits\");\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 * _Available since v4.7._\n */\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\n downcasted = int96(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 96 bits\");\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 * _Available since v4.7._\n */\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\n downcasted = int88(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 88 bits\");\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 * _Available since v4.7._\n */\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\n downcasted = int80(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 80 bits\");\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 * _Available since v4.7._\n */\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\n downcasted = int72(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 72 bits\");\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 * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\n downcasted = int64(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 64 bits\");\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 * _Available since v4.7._\n */\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\n downcasted = int56(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 56 bits\");\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 * _Available since v4.7._\n */\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\n downcasted = int48(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 48 bits\");\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 * _Available since v4.7._\n */\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\n downcasted = int40(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 40 bits\");\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 * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\n downcasted = int32(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 32 bits\");\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 * _Available since v4.7._\n */\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\n downcasted = int24(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 24 bits\");\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 * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\n downcasted = int16(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 16 bits\");\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 * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\n downcasted = int8(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 8 bits\");\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 * _Available since v3.0._\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 require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/SignedMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard signed math utilities missing in the Solidity language.\n */\nlibrary SignedMath {\n /**\n * @dev Returns the largest of two signed numbers.\n */\n function max(int256 a, int256 b) internal pure returns (int256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two signed numbers.\n */\n function min(int256 a, int256 b) internal pure returns (int256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two signed numbers without overflow.\n * The result is rounded towards zero.\n */\n function average(int256 a, int256 b) internal pure returns (int256) {\n // Formula from the book \"Hacker's Delight\"\n int256 x = (a & b) + ((a ^ b) >> 1);\n return x + (int256(uint256(x) >> 255) & (a ^ b));\n }\n\n /**\n * @dev Returns the absolute unsigned value of a signed value.\n */\n function abs(int256 n) internal pure returns (uint256) {\n unchecked {\n // must be unchecked in order to support `n = type(int256).min`\n return uint256(n >= 0 ? n : -n);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/Math.sol\";\nimport \"./math/SignedMath.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n unchecked {\n uint256 length = Math.log10(value) + 1;\n string memory buffer = new string(length);\n uint256 ptr;\n /// @solidity memory-safe-assembly\n assembly {\n ptr := add(buffer, add(32, length))\n }\n while (true) {\n ptr--;\n /// @solidity memory-safe-assembly\n assembly {\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n }\n value /= 10;\n if (value == 0) break;\n }\n return buffer;\n }\n }\n\n /**\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\n */\n function toString(int256 value) internal pure returns (string memory) {\n return string(abi.encodePacked(value < 0 ? \"-\" : \"\", toString(SignedMath.abs(value))));\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n unchecked {\n return toHexString(value, Math.log256(value) + 1);\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n\n /**\n * @dev Returns true if the two strings are equal.\n */\n function equal(string memory a, string memory b) internal pure returns (bool) {\n return keccak256(bytes(a)) == keccak256(bytes(b));\n }\n}\n" + }, + "contracts/aa-4337/core/BaseAccount.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-empty-blocks */\n\nimport \"../interfaces/IAccount.sol\";\nimport \"../interfaces/IEntryPoint.sol\";\nimport \"./Helpers.sol\";\n\n/**\n * Basic account implementation.\n * this contract provides the basic logic for implementing the IAccount interface - validateUserOp\n * specific account implementation should inherit it and provide the account-specific logic\n */\nabstract contract BaseAccount is IAccount {\n using UserOperationLib for UserOperation;\n\n //return value in case of signature failure, with no time-range.\n // equivalent to _packValidationData(true,0,0);\n uint256 internal constant SIG_VALIDATION_FAILED = 1;\n\n /**\n * Return the account nonce.\n * This method returns the next sequential nonce.\n * For a nonce of a specific key, use `entrypoint.getNonce(account, key)`\n */\n function getNonce() public view virtual returns (uint256) {\n return entryPoint().getNonce(address(this), 0);\n }\n\n /**\n * return the entryPoint used by this account.\n * subclass should return the current entryPoint used by this account.\n */\n function entryPoint() public view virtual returns (IEntryPoint);\n\n /**\n * Validate user's signature and nonce.\n * subclass doesn't need to override this method. Instead, it should override the specific internal validation methods.\n */\n function validateUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 missingAccountFunds\n ) external virtual override returns (uint256 validationData) {\n _requireFromEntryPoint();\n validationData = _validateSignature(userOp, userOpHash);\n _validateNonce(userOp.nonce);\n _payPrefund(missingAccountFunds);\n }\n\n /**\n * ensure the request comes from the known entrypoint.\n */\n function _requireFromEntryPoint() internal view virtual {\n require(\n msg.sender == address(entryPoint()),\n \"account: not from EntryPoint\"\n );\n }\n\n /**\n * validate the signature is valid for this message.\n * @param userOp validate the userOp.signature field\n * @param userOpHash convenient field: the hash of the request, to check the signature against\n * (also hashes the entrypoint and chain id)\n * @return validationData signature and time-range of this operation\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * If the account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function _validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) internal virtual returns (uint256 validationData);\n\n /**\n * Validate the nonce of the UserOperation.\n * This method may validate the nonce requirement of this account.\n * e.g.\n * To limit the nonce to use sequenced UserOps only (no \"out of order\" UserOps):\n * `require(nonce < type(uint64).max)`\n * For a hypothetical account that *requires* the nonce to be out-of-order:\n * `require(nonce & type(uint64).max == 0)`\n *\n * The actual nonce uniqueness is managed by the EntryPoint, and thus no other\n * action is needed by the account itself.\n *\n * @param nonce to validate\n *\n * solhint-disable-next-line no-empty-blocks\n */\n function _validateNonce(uint256 nonce) internal view virtual {}\n\n /**\n * sends to the entrypoint (msg.sender) the missing funds for this transaction.\n * subclass MAY override this method for better funds management\n * (e.g. send to the entryPoint more than the minimum required, so that in future transactions\n * it will not be required to send again)\n * @param missingAccountFunds the minimum value this method should send the entrypoint.\n * this value MAY be zero, in case there is enough deposit, or the userOp has a paymaster.\n */\n function _payPrefund(uint256 missingAccountFunds) internal virtual {\n if (missingAccountFunds != 0) {\n (bool success, ) = payable(msg.sender).call{\n value: missingAccountFunds,\n gas: type(uint256).max\n }(\"\");\n (success);\n //ignore failure (its EntryPoint's job to verify, not account.)\n }\n }\n}\n" + }, + "contracts/aa-4337/core/EntryPoint.sol": { + "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n\nimport \"../interfaces/IAccount.sol\";\nimport \"../interfaces/IPaymaster.sol\";\nimport \"../interfaces/IEntryPoint.sol\";\n\nimport \"../utils/Exec.sol\";\nimport \"./StakeManager.sol\";\nimport \"./SenderCreator.sol\";\nimport \"./Helpers.sol\";\nimport \"./NonceManager.sol\";\nimport \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\n\ncontract EntryPoint is\n IEntryPoint,\n StakeManager,\n NonceManager,\n ReentrancyGuard\n{\n using UserOperationLib for UserOperation;\n\n SenderCreator private immutable senderCreator = new SenderCreator();\n\n // internal value used during simulation: need to query aggregator.\n address private constant SIMULATE_FIND_AGGREGATOR = address(1);\n\n // marker for inner call revert on out of gas\n bytes32 private constant INNER_OUT_OF_GAS = hex\"deaddead\";\n\n uint256 private constant REVERT_REASON_MAX_LEN = 2048;\n\n /**\n * for simulation purposes, validateUserOp (and validatePaymasterUserOp) must return this value\n * in case of signature failure, instead of revert.\n */\n uint256 public constant SIG_VALIDATION_FAILED = 1;\n\n /**\n * compensate the caller's beneficiary address with the collected fees of all UserOperations.\n * @param beneficiary the address to receive the fees\n * @param amount amount to transfer.\n */\n function _compensate(address payable beneficiary, uint256 amount) internal {\n require(beneficiary != address(0), \"AA90 invalid beneficiary\");\n (bool success, ) = beneficiary.call{value: amount}(\"\");\n require(success, \"AA91 failed send to beneficiary\");\n }\n\n /**\n * execute a user op\n * @param opIndex index into the opInfo array\n * @param userOp the userOp to execute\n * @param opInfo the opInfo filled by validatePrepayment for this userOp.\n * @return collected the total amount this userOp paid.\n */\n function _executeUserOp(\n uint256 opIndex,\n UserOperation calldata userOp,\n UserOpInfo memory opInfo\n ) private returns (uint256 collected) {\n uint256 preGas = gasleft();\n bytes memory context = getMemoryBytesFromOffset(opInfo.contextOffset);\n\n try this.innerHandleOp(userOp.callData, opInfo, context) returns (\n uint256 _actualGasCost\n ) {\n collected = _actualGasCost;\n } catch {\n bytes32 innerRevertCode;\n assembly {\n returndatacopy(0, 0, 32)\n innerRevertCode := mload(0)\n }\n // handleOps was called with gas limit too low. abort entire bundle.\n if (innerRevertCode == INNER_OUT_OF_GAS) {\n //report paymaster, since if it is not deliberately caused by the bundler,\n // it must be a revert caused by paymaster.\n revert FailedOp(opIndex, \"AA95 out of gas\");\n }\n\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n collected = _handlePostOp(\n opIndex,\n IPaymaster.PostOpMode.postOpReverted,\n opInfo,\n context,\n actualGas\n );\n }\n }\n\n /**\n * Execute a batch of UserOperations.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(\n UserOperation[] calldata ops,\n address payable beneficiary\n ) public nonReentrant {\n uint256 opslen = ops.length;\n UserOpInfo[] memory opInfos = new UserOpInfo[](opslen);\n\n unchecked {\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[i];\n (\n uint256 validationData,\n uint256 pmValidationData\n ) = _validatePrepayment(i, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(\n i,\n validationData,\n pmValidationData,\n address(0)\n );\n }\n\n uint256 collected = 0;\n emit BeforeExecution();\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(i, ops[i], opInfos[i]);\n }\n\n _compensate(beneficiary, collected);\n } //unchecked\n }\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) public nonReentrant {\n uint256 opasLen = opsPerAggregator.length;\n uint256 totalOps = 0;\n for (uint256 i = 0; i < opasLen; i++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[i];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n //address(1) is special marker of \"signature error\"\n require(\n address(aggregator) != address(1),\n \"AA96 invalid aggregator\"\n );\n\n if (address(aggregator) != address(0)) {\n // solhint-disable-next-line no-empty-blocks\n try aggregator.validateSignatures(ops, opa.signature) {} catch {\n revert SignatureValidationFailed(address(aggregator));\n }\n }\n\n totalOps += ops.length;\n }\n\n UserOpInfo[] memory opInfos = new UserOpInfo[](totalOps);\n\n emit BeforeExecution();\n\n uint256 opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n uint256 opslen = ops.length;\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[opIndex];\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(opIndex, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(\n i,\n validationData,\n paymasterValidationData,\n address(aggregator)\n );\n opIndex++;\n }\n }\n\n uint256 collected = 0;\n opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n emit SignatureAggregatorChanged(address(opa.aggregator));\n UserOperation[] calldata ops = opa.userOps;\n uint256 opslen = ops.length;\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(opIndex, ops[i], opInfos[opIndex]);\n opIndex++;\n }\n }\n emit SignatureAggregatorChanged(address(0));\n\n _compensate(beneficiary, collected);\n }\n\n /// @inheritdoc IEntryPoint\n function simulateHandleOp(\n UserOperation calldata op,\n address target,\n bytes calldata targetCallData\n ) external override {\n UserOpInfo memory opInfo;\n _simulationOnlyValidations(op);\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(0, op, opInfo);\n ValidationData memory data = _intersectTimeRange(\n validationData,\n paymasterValidationData\n );\n\n numberMarker();\n uint256 paid = _executeUserOp(0, op, opInfo);\n numberMarker();\n bool targetSuccess;\n bytes memory targetResult;\n if (target != address(0)) {\n (targetSuccess, targetResult) = target.call(targetCallData);\n }\n revert ExecutionResult(\n opInfo.preOpGas,\n paid,\n data.validAfter,\n data.validUntil,\n targetSuccess,\n targetResult\n );\n }\n\n // A memory copy of UserOp static fields only.\n // Excluding: callData, initCode and signature. Replacing paymasterAndData with paymaster.\n struct MemoryUserOp {\n address sender;\n uint256 nonce;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n address paymaster;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n }\n\n struct UserOpInfo {\n MemoryUserOp mUserOp;\n bytes32 userOpHash;\n uint256 prefund;\n uint256 contextOffset;\n uint256 preOpGas;\n }\n\n /**\n * inner function to handle a UserOperation.\n * Must be declared \"external\" to open a call context, but it can only be called by handleOps.\n */\n function innerHandleOp(\n bytes memory callData,\n UserOpInfo memory opInfo,\n bytes calldata context\n ) external returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n require(msg.sender == address(this), \"AA92 internal call only\");\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n\n uint callGasLimit = mUserOp.callGasLimit;\n unchecked {\n // handleOps was called with gas limit too low. abort entire bundle.\n if (\n gasleft() < callGasLimit + mUserOp.verificationGasLimit + 5000\n ) {\n assembly {\n mstore(0, INNER_OUT_OF_GAS)\n revert(0, 32)\n }\n }\n }\n\n IPaymaster.PostOpMode mode = IPaymaster.PostOpMode.opSucceeded;\n if (callData.length > 0) {\n bool success = Exec.call(mUserOp.sender, 0, callData, callGasLimit);\n if (!success) {\n bytes memory result = Exec.getReturnData(REVERT_REASON_MAX_LEN);\n if (result.length > 0) {\n emit UserOperationRevertReason(\n opInfo.userOpHash,\n mUserOp.sender,\n mUserOp.nonce,\n result\n );\n }\n mode = IPaymaster.PostOpMode.opReverted;\n }\n }\n\n unchecked {\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n //note: opIndex is ignored (relevant only if mode==postOpReverted, which is only possible outside of innerHandleOp)\n return _handlePostOp(0, mode, opInfo, context, actualGas);\n }\n }\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(\n UserOperation calldata userOp\n ) public view returns (bytes32) {\n return\n keccak256(abi.encode(userOp.hash(), address(this), block.chainid));\n }\n\n /**\n * copy general fields from userOp into the memory opInfo structure.\n */\n function _copyUserOpToMemory(\n UserOperation calldata userOp,\n MemoryUserOp memory mUserOp\n ) internal pure {\n mUserOp.sender = userOp.sender;\n mUserOp.nonce = userOp.nonce;\n mUserOp.callGasLimit = userOp.callGasLimit;\n mUserOp.verificationGasLimit = userOp.verificationGasLimit;\n mUserOp.preVerificationGas = userOp.preVerificationGas;\n mUserOp.maxFeePerGas = userOp.maxFeePerGas;\n mUserOp.maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes calldata paymasterAndData = userOp.paymasterAndData;\n if (paymasterAndData.length > 0) {\n require(\n paymasterAndData.length >= 20,\n \"AA93 invalid paymasterAndData\"\n );\n mUserOp.paymaster = address(bytes20(paymasterAndData[:20]));\n } else {\n mUserOp.paymaster = address(0);\n }\n }\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external {\n UserOpInfo memory outOpInfo;\n\n _simulationOnlyValidations(userOp);\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(0, userOp, outOpInfo);\n StakeInfo memory paymasterInfo = _getStakeInfo(\n outOpInfo.mUserOp.paymaster\n );\n StakeInfo memory senderInfo = _getStakeInfo(outOpInfo.mUserOp.sender);\n StakeInfo memory factoryInfo;\n {\n bytes calldata initCode = userOp.initCode;\n address factory = initCode.length >= 20\n ? address(bytes20(initCode[0:20]))\n : address(0);\n factoryInfo = _getStakeInfo(factory);\n }\n\n ValidationData memory data = _intersectTimeRange(\n validationData,\n paymasterValidationData\n );\n address aggregator = data.aggregator;\n bool sigFailed = aggregator == address(1);\n ReturnInfo memory returnInfo = ReturnInfo(\n outOpInfo.preOpGas,\n outOpInfo.prefund,\n sigFailed,\n data.validAfter,\n data.validUntil,\n getMemoryBytesFromOffset(outOpInfo.contextOffset)\n );\n\n if (aggregator != address(0) && aggregator != address(1)) {\n AggregatorStakeInfo memory aggregatorInfo = AggregatorStakeInfo(\n aggregator,\n _getStakeInfo(aggregator)\n );\n revert ValidationResultWithAggregation(\n returnInfo,\n senderInfo,\n factoryInfo,\n paymasterInfo,\n aggregatorInfo\n );\n }\n revert ValidationResult(\n returnInfo,\n senderInfo,\n factoryInfo,\n paymasterInfo\n );\n }\n\n function _getRequiredPrefund(\n MemoryUserOp memory mUserOp\n ) internal pure returns (uint256 requiredPrefund) {\n unchecked {\n //when using a Paymaster, the verificationGasLimit is used also to as a limit for the postOp call.\n // our security model might call postOp eventually twice\n uint256 mul = mUserOp.paymaster != address(0) ? 3 : 1;\n uint256 requiredGas = mUserOp.callGasLimit +\n mUserOp.verificationGasLimit *\n mul +\n mUserOp.preVerificationGas;\n\n requiredPrefund = requiredGas * mUserOp.maxFeePerGas;\n }\n }\n\n // create the sender's contract if needed.\n function _createSenderIfNeeded(\n uint256 opIndex,\n UserOpInfo memory opInfo,\n bytes calldata initCode\n ) internal {\n if (initCode.length != 0) {\n address sender = opInfo.mUserOp.sender;\n if (sender.code.length != 0)\n revert FailedOp(opIndex, \"AA10 sender already constructed\");\n address sender1 = senderCreator.createSender{\n gas: opInfo.mUserOp.verificationGasLimit\n }(initCode);\n if (sender1 == address(0))\n revert FailedOp(opIndex, \"AA13 initCode failed or OOG\");\n if (sender1 != sender)\n revert FailedOp(opIndex, \"AA14 initCode must return sender\");\n if (sender1.code.length == 0)\n revert FailedOp(opIndex, \"AA15 initCode must create sender\");\n address factory = address(bytes20(initCode[0:20]));\n emit AccountDeployed(\n opInfo.userOpHash,\n sender,\n factory,\n opInfo.mUserOp.paymaster\n );\n }\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes calldata initCode) public {\n address sender = senderCreator.createSender(initCode);\n revert SenderAddressResult(sender);\n }\n\n function _simulationOnlyValidations(\n UserOperation calldata userOp\n ) internal view {\n // solhint-disable-next-line no-empty-blocks\n try\n this._validateSenderAndPaymaster(\n userOp.initCode,\n userOp.sender,\n userOp.paymasterAndData\n )\n {} catch Error(string memory revertReason) {\n if (bytes(revertReason).length != 0) {\n revert FailedOp(0, revertReason);\n }\n }\n }\n\n /**\n * Called only during simulation.\n * This function always reverts to prevent warm/cold storage differentiation in simulation vs execution.\n */\n function _validateSenderAndPaymaster(\n bytes calldata initCode,\n address sender,\n bytes calldata paymasterAndData\n ) external view {\n if (initCode.length == 0 && sender.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA20 account not deployed\");\n }\n if (paymasterAndData.length >= 20) {\n address paymaster = address(bytes20(paymasterAndData[0:20]));\n if (paymaster.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA30 paymaster not deployed\");\n }\n }\n // always revert\n revert(\"\");\n }\n\n /**\n * call account.validateUserOp.\n * revert (with FailedOp) in case validateUserOp reverts, or account didn't send required prefund.\n * decrement account's deposit if needed\n */\n function _validateAccountPrepayment(\n uint256 opIndex,\n UserOperation calldata op,\n UserOpInfo memory opInfo,\n uint256 requiredPrefund\n )\n internal\n returns (\n uint256 gasUsedByValidateAccountPrepayment,\n uint256 validationData\n )\n {\n unchecked {\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n address sender = mUserOp.sender;\n _createSenderIfNeeded(opIndex, opInfo, op.initCode);\n address paymaster = mUserOp.paymaster;\n numberMarker();\n uint256 missingAccountFunds = 0;\n if (paymaster == address(0)) {\n uint256 bal = balanceOf(sender);\n missingAccountFunds = bal > requiredPrefund\n ? 0\n : requiredPrefund - bal;\n }\n try\n IAccount(sender).validateUserOp{\n gas: mUserOp.verificationGasLimit\n }(op, opInfo.userOpHash, missingAccountFunds)\n returns (uint256 _validationData) {\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA23 reverted: \", revertReason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA23 reverted (or OOG)\");\n }\n if (paymaster == address(0)) {\n DepositInfo storage senderInfo = deposits[sender];\n uint256 deposit = senderInfo.deposit;\n if (requiredPrefund > deposit) {\n revert FailedOp(opIndex, \"AA21 didn't pay prefund\");\n }\n senderInfo.deposit = uint112(deposit - requiredPrefund);\n }\n gasUsedByValidateAccountPrepayment = preGas - gasleft();\n }\n }\n\n /**\n * In case the request has a paymaster:\n * Validate paymaster has enough deposit.\n * Call paymaster.validatePaymasterUserOp.\n * Revert with proper FailedOp in case paymaster reverts.\n * Decrement paymaster's deposit\n */\n function _validatePaymasterPrepayment(\n uint256 opIndex,\n UserOperation calldata op,\n UserOpInfo memory opInfo,\n uint256 requiredPreFund,\n uint256 gasUsedByValidateAccountPrepayment\n ) internal returns (bytes memory context, uint256 validationData) {\n unchecked {\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 verificationGasLimit = mUserOp.verificationGasLimit;\n require(\n verificationGasLimit > gasUsedByValidateAccountPrepayment,\n \"AA41 too little verificationGas\"\n );\n uint256 gas = verificationGasLimit -\n gasUsedByValidateAccountPrepayment;\n\n address paymaster = mUserOp.paymaster;\n DepositInfo storage paymasterInfo = deposits[paymaster];\n uint256 deposit = paymasterInfo.deposit;\n if (deposit < requiredPreFund) {\n revert FailedOp(opIndex, \"AA31 paymaster deposit too low\");\n }\n paymasterInfo.deposit = uint112(deposit - requiredPreFund);\n try\n IPaymaster(paymaster).validatePaymasterUserOp{gas: gas}(\n op,\n opInfo.userOpHash,\n requiredPreFund\n )\n returns (bytes memory _context, uint256 _validationData) {\n context = _context;\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA33 reverted: \", revertReason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA33 reverted (or OOG)\");\n }\n }\n }\n\n /**\n * revert if either account validationData or paymaster validationData is expired\n */\n function _validateAccountAndPaymasterValidationData(\n uint256 opIndex,\n uint256 validationData,\n uint256 paymasterValidationData,\n address expectedAggregator\n ) internal view {\n (address aggregator, bool outOfTimeRange) = _getValidationData(\n validationData\n );\n if (expectedAggregator != aggregator) {\n revert FailedOp(opIndex, \"AA24 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA22 expired or not due\");\n }\n //pmAggregator is not a real signature aggregator: we don't have logic to handle it as address.\n // non-zero address means that the paymaster fails due to some signature check (which is ok only during estimation)\n address pmAggregator;\n (pmAggregator, outOfTimeRange) = _getValidationData(\n paymasterValidationData\n );\n if (pmAggregator != address(0)) {\n revert FailedOp(opIndex, \"AA34 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA32 paymaster expired or not due\");\n }\n }\n\n function _getValidationData(\n uint256 validationData\n ) internal view returns (address aggregator, bool outOfTimeRange) {\n if (validationData == 0) {\n return (address(0), false);\n }\n ValidationData memory data = _parseValidationData(validationData);\n // solhint-disable-next-line not-rely-on-time\n outOfTimeRange =\n block.timestamp > data.validUntil ||\n block.timestamp < data.validAfter;\n aggregator = data.aggregator;\n }\n\n /**\n * validate account and paymaster (if defined).\n * also make sure total validation doesn't exceed verificationGasLimit\n * this method is called off-chain (simulateValidation()) and on-chain (from handleOps)\n * @param opIndex the index of this userOp into the \"opInfos\" array\n * @param userOp the userOp to validate\n */\n function _validatePrepayment(\n uint256 opIndex,\n UserOperation calldata userOp,\n UserOpInfo memory outOpInfo\n )\n private\n returns (uint256 validationData, uint256 paymasterValidationData)\n {\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = outOpInfo.mUserOp;\n _copyUserOpToMemory(userOp, mUserOp);\n outOpInfo.userOpHash = getUserOpHash(userOp);\n\n // validate all numeric values in userOp are well below 128 bit, so they can safely be added\n // and multiplied without causing overflow\n uint256 maxGasValues = mUserOp.preVerificationGas |\n mUserOp.verificationGasLimit |\n mUserOp.callGasLimit |\n userOp.maxFeePerGas |\n userOp.maxPriorityFeePerGas;\n require(maxGasValues <= type(uint120).max, \"AA94 gas values overflow\");\n\n uint256 gasUsedByValidateAccountPrepayment;\n uint256 requiredPreFund = _getRequiredPrefund(mUserOp);\n (\n gasUsedByValidateAccountPrepayment,\n validationData\n ) = _validateAccountPrepayment(\n opIndex,\n userOp,\n outOpInfo,\n requiredPreFund\n );\n\n if (!_validateAndUpdateNonce(mUserOp.sender, mUserOp.nonce)) {\n revert FailedOp(opIndex, \"AA25 invalid account nonce\");\n }\n\n //a \"marker\" where account opcode validation is done and paymaster opcode validation is about to start\n // (used only by off-chain simulateValidation)\n numberMarker();\n\n bytes memory context;\n if (mUserOp.paymaster != address(0)) {\n (context, paymasterValidationData) = _validatePaymasterPrepayment(\n opIndex,\n userOp,\n outOpInfo,\n requiredPreFund,\n gasUsedByValidateAccountPrepayment\n );\n }\n unchecked {\n uint256 gasUsed = preGas - gasleft();\n\n if (userOp.verificationGasLimit < gasUsed) {\n revert FailedOp(opIndex, \"AA40 over verificationGasLimit\");\n }\n outOpInfo.prefund = requiredPreFund;\n outOpInfo.contextOffset = getOffsetOfMemoryBytes(context);\n outOpInfo.preOpGas = preGas - gasleft() + userOp.preVerificationGas;\n }\n }\n\n /**\n * process post-operation.\n * called just after the callData is executed.\n * if a paymaster is defined and its validation returned a non-empty context, its postOp is called.\n * the excess amount is refunded to the account (or paymaster - if it was used in the request)\n * @param opIndex index in the batch\n * @param mode - whether is called from innerHandleOp, or outside (postOpReverted)\n * @param opInfo userOp fields and info collected during validation\n * @param context the context returned in validatePaymasterUserOp\n * @param actualGas the gas used so far by this user operation\n */\n function _handlePostOp(\n uint256 opIndex,\n IPaymaster.PostOpMode mode,\n UserOpInfo memory opInfo,\n bytes memory context,\n uint256 actualGas\n ) private returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n unchecked {\n address refundAddress;\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 gasPrice = getUserOpGasPrice(mUserOp);\n\n address paymaster = mUserOp.paymaster;\n if (paymaster == address(0)) {\n refundAddress = mUserOp.sender;\n } else {\n refundAddress = paymaster;\n if (context.length > 0) {\n actualGasCost = actualGas * gasPrice;\n if (mode != IPaymaster.PostOpMode.postOpReverted) {\n IPaymaster(paymaster).postOp{\n gas: mUserOp.verificationGasLimit\n }(mode, context, actualGasCost);\n } else {\n // solhint-disable-next-line no-empty-blocks\n try\n IPaymaster(paymaster).postOp{\n gas: mUserOp.verificationGasLimit\n }(mode, context, actualGasCost)\n {} catch Error(string memory reason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA50 postOp reverted: \", reason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA50 postOp revert\");\n }\n }\n }\n }\n actualGas += preGas - gasleft();\n actualGasCost = actualGas * gasPrice;\n if (opInfo.prefund < actualGasCost) {\n revert FailedOp(opIndex, \"AA51 prefund below actualGasCost\");\n }\n uint256 refund = opInfo.prefund - actualGasCost;\n _incrementDeposit(refundAddress, refund);\n bool success = mode == IPaymaster.PostOpMode.opSucceeded;\n emit UserOperationEvent(\n opInfo.userOpHash,\n mUserOp.sender,\n mUserOp.paymaster,\n mUserOp.nonce,\n success,\n actualGasCost,\n actualGas\n );\n } // unchecked\n }\n\n /**\n * the gas price this UserOp agrees to pay.\n * relayer/block builder might submit the TX with higher priorityFee, but the user should not\n */\n function getUserOpGasPrice(\n MemoryUserOp memory mUserOp\n ) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = mUserOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = mUserOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n function getOffsetOfMemoryBytes(\n bytes memory data\n ) internal pure returns (uint256 offset) {\n assembly {\n offset := data\n }\n }\n\n function getMemoryBytesFromOffset(\n uint256 offset\n ) internal pure returns (bytes memory data) {\n assembly {\n data := offset\n }\n }\n\n //place the NUMBER opcode in the code.\n // this is used as a marker during simulation, as this OP is completely banned from the simulated code of the\n // account and paymaster.\n function numberMarker() internal view {\n assembly {\n mstore(0, number())\n }\n }\n}\n" + }, + "contracts/aa-4337/core/Helpers.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable no-inline-assembly */\n\n/**\n * returned data from validateUserOp.\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\n * @param aggregator - address(0) - the account validated the signature by itself.\n * address(1) - the account failed to validate the signature.\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\n * @param validAfter - this UserOp is valid only after this timestamp.\n * @param validaUntil - this UserOp is valid only up to this timestamp.\n */\nstruct ValidationData {\n address aggregator;\n uint48 validAfter;\n uint48 validUntil;\n}\n\n//extract sigFailed, validAfter, validUntil.\n// also convert zero validUntil to type(uint48).max\nfunction _parseValidationData(\n uint validationData\n) pure returns (ValidationData memory data) {\n address aggregator = address(uint160(validationData));\n uint48 validUntil = uint48(validationData >> 160);\n if (validUntil == 0) {\n validUntil = type(uint48).max;\n }\n uint48 validAfter = uint48(validationData >> (48 + 160));\n return ValidationData(aggregator, validAfter, validUntil);\n}\n\n// intersect account and paymaster ranges.\nfunction _intersectTimeRange(\n uint256 validationData,\n uint256 paymasterValidationData\n) pure returns (ValidationData memory) {\n ValidationData memory accountValidationData = _parseValidationData(\n validationData\n );\n ValidationData memory pmValidationData = _parseValidationData(\n paymasterValidationData\n );\n address aggregator = accountValidationData.aggregator;\n if (aggregator == address(0)) {\n aggregator = pmValidationData.aggregator;\n }\n uint48 validAfter = accountValidationData.validAfter;\n uint48 validUntil = accountValidationData.validUntil;\n uint48 pmValidAfter = pmValidationData.validAfter;\n uint48 pmValidUntil = pmValidationData.validUntil;\n\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\n return ValidationData(aggregator, validAfter, validUntil);\n}\n\n/**\n * helper to pack the return value for validateUserOp\n * @param data - the ValidationData to pack\n */\nfunction _packValidationData(\n ValidationData memory data\n) pure returns (uint256) {\n return\n uint160(data.aggregator) |\n (uint256(data.validUntil) << 160) |\n (uint256(data.validAfter) << (160 + 48));\n}\n\n/**\n * helper to pack the return value for validateUserOp, when not using an aggregator\n * @param sigFailed - true for signature failure, false for success\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\n * @param validAfter first timestamp this UserOperation is valid\n */\nfunction _packValidationData(\n bool sigFailed,\n uint48 validUntil,\n uint48 validAfter\n) pure returns (uint256) {\n return\n (sigFailed ? 1 : 0) |\n (uint256(validUntil) << 160) |\n (uint256(validAfter) << (160 + 48));\n}\n\n/**\n * keccak function over calldata.\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\n */\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\n assembly {\n let mem := mload(0x40)\n let len := data.length\n calldatacopy(mem, data.offset, len)\n ret := keccak256(mem, len)\n }\n}\n" + }, + "contracts/aa-4337/core/NonceManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\nimport \"../interfaces/IEntryPoint.sol\";\n\n/**\n * nonce management functionality\n */\ncontract NonceManager is INonceManager {\n /**\n * The next valid sequence number for a given nonce key.\n */\n mapping(address => mapping(uint192 => uint256)) public nonceSequenceNumber;\n\n function getNonce(\n address sender,\n uint192 key\n ) public view override returns (uint256 nonce) {\n return nonceSequenceNumber[sender][key] | (uint256(key) << 64);\n }\n\n // allow an account to manually increment its own nonce.\n // (mainly so that during construction nonce can be made non-zero,\n // to \"absorb\" the gas cost of first nonce increment to 1st transaction (construction),\n // not to 2nd transaction)\n function incrementNonce(uint192 key) public override {\n nonceSequenceNumber[msg.sender][key]++;\n }\n\n /**\n * validate nonce uniqueness for this account.\n * called just after validateUserOp()\n */\n function _validateAndUpdateNonce(\n address sender,\n uint256 nonce\n ) internal returns (bool) {\n uint192 key = uint192(nonce >> 64);\n uint64 seq = uint64(nonce);\n return nonceSequenceNumber[sender][key]++ == seq;\n }\n}\n" + }, + "contracts/aa-4337/core/SenderCreator.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/**\n * helper contract for EntryPoint, to call userOp.initCode from a \"neutral\" address,\n * which is explicitly not the entryPoint itself.\n */\ncontract SenderCreator {\n /**\n * call the \"initCode\" factory to create and return the sender account address\n * @param initCode the initCode value from a UserOp. contains 20 bytes of factory address, followed by calldata\n * @return sender the returned address of the created account, or zero address on failure.\n */\n function createSender(\n bytes calldata initCode\n ) external returns (address sender) {\n address factory = address(bytes20(initCode[0:20]));\n bytes memory initCallData = initCode[20:];\n bool success;\n /* solhint-disable no-inline-assembly */\n assembly {\n success := call(\n gas(),\n factory,\n 0,\n add(initCallData, 0x20),\n mload(initCallData),\n 0,\n 32\n )\n sender := mload(0)\n }\n if (!success) {\n sender = address(0);\n }\n }\n}\n" + }, + "contracts/aa-4337/core/StakeManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity 0.8.21;\n\nimport \"../interfaces/IStakeManager.sol\";\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable not-rely-on-time */\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by a paymaster.\n */\nabstract contract StakeManager is IStakeManager {\n /// maps paymaster to their deposits and stakes\n mapping(address => DepositInfo) public deposits;\n\n /// @inheritdoc IStakeManager\n function getDepositInfo(\n address account\n ) public view returns (DepositInfo memory info) {\n return deposits[account];\n }\n\n // internal method to return just the stake info\n function _getStakeInfo(\n address addr\n ) internal view returns (StakeInfo memory info) {\n DepositInfo storage depositInfo = deposits[addr];\n info.stake = depositInfo.stake;\n info.unstakeDelaySec = depositInfo.unstakeDelaySec;\n }\n\n /// return the deposit (for gas payment) of the account\n function balanceOf(address account) public view returns (uint256) {\n return deposits[account].deposit;\n }\n\n receive() external payable {\n depositTo(msg.sender);\n }\n\n function _incrementDeposit(address account, uint256 amount) internal {\n DepositInfo storage info = deposits[account];\n uint256 newAmount = info.deposit + amount;\n require(newAmount <= type(uint112).max, \"deposit overflow\");\n info.deposit = uint112(newAmount);\n }\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) public payable {\n _incrementDeposit(account, msg.value);\n DepositInfo storage info = deposits[account];\n emit Deposited(account, info.deposit);\n }\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 unstakeDelaySec) public payable {\n DepositInfo storage info = deposits[msg.sender];\n require(unstakeDelaySec > 0, \"must specify unstake delay\");\n require(\n unstakeDelaySec >= info.unstakeDelaySec,\n \"cannot decrease unstake time\"\n );\n uint256 stake = info.stake + msg.value;\n require(stake > 0, \"no stake specified\");\n require(stake <= type(uint112).max, \"stake overflow\");\n deposits[msg.sender] = DepositInfo(\n info.deposit,\n true,\n uint112(stake),\n unstakeDelaySec,\n 0\n );\n emit StakeLocked(msg.sender, stake, unstakeDelaySec);\n }\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external {\n DepositInfo storage info = deposits[msg.sender];\n require(info.unstakeDelaySec != 0, \"not staked\");\n require(info.staked, \"already unstaking\");\n uint48 withdrawTime = uint48(block.timestamp) + info.unstakeDelaySec;\n info.withdrawTime = withdrawTime;\n info.staked = false;\n emit StakeUnlocked(msg.sender, withdrawTime);\n }\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external {\n DepositInfo storage info = deposits[msg.sender];\n uint256 stake = info.stake;\n require(stake > 0, \"No stake to withdraw\");\n require(info.withdrawTime > 0, \"must call unlockStake() first\");\n require(\n info.withdrawTime <= block.timestamp,\n \"Stake withdrawal is not due\"\n );\n info.unstakeDelaySec = 0;\n info.withdrawTime = 0;\n info.stake = 0;\n emit StakeWithdrawn(msg.sender, withdrawAddress, stake);\n (bool success, ) = withdrawAddress.call{value: stake}(\"\");\n require(success, \"failed to withdraw stake\");\n }\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(\n address payable withdrawAddress,\n uint256 withdrawAmount\n ) external {\n DepositInfo storage info = deposits[msg.sender];\n require(withdrawAmount <= info.deposit, \"Withdraw amount too large\");\n info.deposit = uint112(info.deposit - withdrawAmount);\n emit Withdrawn(msg.sender, withdrawAddress, withdrawAmount);\n (bool success, ) = withdrawAddress.call{value: withdrawAmount}(\"\");\n require(success, \"failed to withdraw\");\n }\n}\n" + }, + "contracts/aa-4337/interfaces/IAccount.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\ninterface IAccount {\n /**\n * Validate user's signature and nonce\n * the entryPoint will make the call to the recipient only if this validation call returns successfully.\n * signature failure should be reported by returning SIG_VALIDATION_FAILED (1).\n * This allows making a \"simulation call\" without a valid signature\n * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure.\n *\n * @dev Must validate caller is the entryPoint.\n * Must validate the signature and nonce\n * @param userOp the operation that is about to be executed.\n * @param userOpHash hash of the user's request data. can be used as the basis for signature.\n * @param missingAccountFunds missing funds on the account's deposit in the entrypoint.\n * This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call.\n * The excess is left as a deposit in the entrypoint, for future calls.\n * can be withdrawn anytime using \"entryPoint.withdrawTo()\"\n * In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero.\n * @return validationData packaged ValidationData structure. use `_packValidationData` and `_unpackValidationData` to encode and decode\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * If an account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validateUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 missingAccountFunds\n ) external returns (uint256 validationData);\n}\n" + }, + "contracts/aa-4337/interfaces/IAggregator.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * Aggregated Signatures validator.\n */\ninterface IAggregator {\n /**\n * validate aggregated signature.\n * revert if the aggregated signature does not match the given list of operations.\n */\n function validateSignatures(\n UserOperation[] calldata userOps,\n bytes calldata signature\n ) external view;\n\n /**\n * validate signature of a single userOp\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\n * @param userOp the userOperation received from the user.\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\n * (usually empty, unless account and aggregator support some kind of \"multisig\"\n */\n function validateUserOpSignature(\n UserOperation calldata userOp\n ) external view returns (bytes memory sigForUserOp);\n\n /**\n * aggregate multiple signatures into a single value.\n * This method is called off-chain to calculate the signature to pass with handleOps()\n * bundler MAY use optimized custom code perform this aggregation\n * @param userOps array of UserOperations to collect the signatures from.\n * @return aggregatedSignature the aggregated signature\n */\n function aggregateSignatures(\n UserOperation[] calldata userOps\n ) external view returns (bytes memory aggregatedSignature);\n}\n" + }, + "contracts/aa-4337/interfaces/IEntryPoint.sol": { + "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n/* solhint-disable reason-string */\n\nimport \"./UserOperation.sol\";\nimport \"./IStakeManager.sol\";\nimport \"./IAggregator.sol\";\nimport \"./INonceManager.sol\";\n\ninterface IEntryPoint is IStakeManager, INonceManager {\n /***\n * An event emitted after each successful request\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\n * @param sender - the account that generates this request.\n * @param paymaster - if non-null, the paymaster that pays for this request.\n * @param nonce - the nonce value from the request.\n * @param success - true if the sender transaction succeeded, false if reverted.\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\n */\n event UserOperationEvent(\n bytes32 indexed userOpHash,\n address indexed sender,\n address indexed paymaster,\n uint256 nonce,\n bool success,\n uint256 actualGasCost,\n uint256 actualGasUsed\n );\n\n /**\n * account \"sender\" was deployed.\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\n * @param sender the account that is deployed\n * @param factory the factory used to deploy this account (in the initCode)\n * @param paymaster the paymaster used by this UserOp\n */\n event AccountDeployed(\n bytes32 indexed userOpHash,\n address indexed sender,\n address factory,\n address paymaster\n );\n\n /**\n * An event emitted if the UserOperation \"callData\" reverted with non-zero length\n * @param userOpHash the request unique identifier.\n * @param sender the sender of this request\n * @param nonce the nonce used in the request\n * @param revertReason - the return bytes from the (reverted) call to \"callData\".\n */\n event UserOperationRevertReason(\n bytes32 indexed userOpHash,\n address indexed sender,\n uint256 nonce,\n bytes revertReason\n );\n\n /**\n * an event emitted by handleOps(), before starting the execution loop.\n * any event emitted before this event, is part of the validation.\n */\n event BeforeExecution();\n\n /**\n * signature aggregator used by the following UserOperationEvents within this bundle.\n */\n event SignatureAggregatorChanged(address indexed aggregator);\n\n /**\n * a custom revert error of handleOps, to identify the offending op.\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\n * @param reason - revert reason\n * The string starts with a unique code \"AAmn\", where \"m\" is \"1\" for factory, \"2\" for account and \"3\" for paymaster issues,\n * so a failure can be attributed to the correct entity.\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\n */\n error FailedOp(uint256 opIndex, string reason);\n\n /**\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\n */\n error SignatureValidationFailed(address aggregator);\n\n /**\n * Successful result from simulateValidation.\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n */\n error ValidationResult(\n ReturnInfo returnInfo,\n StakeInfo senderInfo,\n StakeInfo factoryInfo,\n StakeInfo paymasterInfo\n );\n\n /**\n * Successful result from simulateValidation, if the account returns a signature aggregator\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\n * bundler MUST use it to verify the signature, or reject the UserOperation\n */\n error ValidationResultWithAggregation(\n ReturnInfo returnInfo,\n StakeInfo senderInfo,\n StakeInfo factoryInfo,\n StakeInfo paymasterInfo,\n AggregatorStakeInfo aggregatorInfo\n );\n\n /**\n * return value of getSenderAddress\n */\n error SenderAddressResult(address sender);\n\n /**\n * return value of simulateHandleOp\n */\n error ExecutionResult(\n uint256 preOpGas,\n uint256 paid,\n uint48 validAfter,\n uint48 validUntil,\n bool targetSuccess,\n bytes targetResult\n );\n\n //UserOps handled, per aggregator\n struct UserOpsPerAggregator {\n UserOperation[] userOps;\n // aggregator address\n IAggregator aggregator;\n // aggregated signature\n bytes signature;\n }\n\n /**\n * Execute a batch of UserOperation.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(\n UserOperation[] calldata ops,\n address payable beneficiary\n ) external;\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) external;\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(\n UserOperation calldata userOp\n ) external view returns (bytes32);\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external;\n\n /**\n * gas and return values during simulation\n * @param preOpGas the gas used for validation (including preValidationGas)\n * @param prefund the required prefund for this operation\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\n */\n struct ReturnInfo {\n uint256 preOpGas;\n uint256 prefund;\n bool sigFailed;\n uint48 validAfter;\n uint48 validUntil;\n bytes paymasterContext;\n }\n\n /**\n * returned aggregated signature info.\n * the aggregator returned by the account, and its current stake.\n */\n struct AggregatorStakeInfo {\n address aggregator;\n StakeInfo stakeInfo;\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes memory initCode) external;\n\n /**\n * simulate full execution of a UserOperation (including both validation and target execution)\n * this method will always revert with \"ExecutionResult\".\n * it performs full validation of the UserOperation, but ignores signature error.\n * an optional target address is called after the userop succeeds, and its value is returned\n * (before the entire call is reverted)\n * Note that in order to collect the the success/failure of the target call, it must be executed\n * with trace enabled to track the emitted events.\n * @param op the UserOperation to simulate\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\n * are set to the return from that call.\n * @param targetCallData callData to pass to target address\n */\n function simulateHandleOp(\n UserOperation calldata op,\n address target,\n bytes calldata targetCallData\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/INonceManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\ninterface INonceManager {\n /**\n * Return the next nonce for this sender.\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\n * But UserOp with different keys can come with arbitrary order.\n *\n * @param sender the account address\n * @param key the high 192 bit of the nonce\n * @return nonce a full nonce to pass for next UserOp with this sender.\n */\n function getNonce(\n address sender,\n uint192 key\n ) external view returns (uint256 nonce);\n\n /**\n * Manually increment the nonce of the sender.\n * This method is exposed just for completeness..\n * Account does NOT need to call it, neither during validation, nor elsewhere,\n * as the EntryPoint will update the nonce regardless.\n * Possible use-case is call it with various keys to \"initialize\" their nonces to one, so that future\n * UserOperations will not pay extra for the first transaction with a given key.\n */\n function incrementNonce(uint192 key) external;\n}\n" + }, + "contracts/aa-4337/interfaces/IPaymaster.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * the interface exposed by a paymaster contract, who agrees to pay the gas for user's operations.\n * a paymaster must hold a stake to cover the required entrypoint stake and also the gas for the transaction.\n */\ninterface IPaymaster {\n enum PostOpMode {\n opSucceeded, // user op succeeded\n opReverted, // user op reverted. still has to pay for gas.\n postOpReverted //user op succeeded, but caused postOp to revert. Now it's a 2nd call, after user's op was deliberately reverted.\n }\n\n /**\n * payment validation: check if paymaster agrees to pay.\n * Must verify sender is the entryPoint.\n * Revert to reject this request.\n * Note that bundlers will reject this method if it changes the state, unless the paymaster is trusted (whitelisted)\n * The paymaster pre-pays using its deposit, and receive back a refund after the postOp method returns.\n * @param userOp the user operation\n * @param userOpHash hash of the user's request data.\n * @param maxCost the maximum cost of this transaction (based on maximum gas and gas price from userOp)\n * @return context value to send to a postOp\n * zero length to signify postOp is not required.\n * @return validationData signature and time-range of this operation, encoded the same as the return value of validateUserOperation\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validatePaymasterUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 maxCost\n ) external returns (bytes memory context, uint256 validationData);\n\n /**\n * post-operation handler.\n * Must verify sender is the entryPoint\n * @param mode enum with the following options:\n * opSucceeded - user operation succeeded.\n * opReverted - user op reverted. still has to pay for gas.\n * postOpReverted - user op succeeded, but caused postOp (in mode=opSucceeded) to revert.\n * Now this is the 2nd call, after user's op was deliberately reverted.\n * @param context - the context value returned by validatePaymasterUserOp\n * @param actualGasCost - actual gas used so far (without this postOp call).\n */\n function postOp(\n PostOpMode mode,\n bytes calldata context,\n uint256 actualGasCost\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/IStakeManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.12;\n\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by the staked entity.\n */\ninterface IStakeManager {\n event Deposited(address indexed account, uint256 totalDeposit);\n\n event Withdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /// Emitted when stake or unstake delay are modified\n event StakeLocked(\n address indexed account,\n uint256 totalStaked,\n uint256 unstakeDelaySec\n );\n\n /// Emitted once a stake is scheduled for withdrawal\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\n\n event StakeWithdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /**\n * @param deposit the entity's deposit\n * @param staked true if this entity is staked.\n * @param stake actual amount of ether staked for this entity.\n * @param unstakeDelaySec minimum delay to withdraw the stake.\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\n * and the rest fit into a 2nd cell.\n * 112 bit allows for 10^15 eth\n * 48 bit for full timestamp\n * 32 bit allows 150 years for unstake delay\n */\n struct DepositInfo {\n uint112 deposit;\n bool staked;\n uint112 stake;\n uint32 unstakeDelaySec;\n uint48 withdrawTime;\n }\n\n //API struct used by getStakeInfo and simulateValidation\n struct StakeInfo {\n uint256 stake;\n uint256 unstakeDelaySec;\n }\n\n /// @return info - full deposit information of given account\n function getDepositInfo(\n address account\n ) external view returns (DepositInfo memory info);\n\n /// @return the deposit (for gas payment) of the account\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) external payable;\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 _unstakeDelaySec) external payable;\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external;\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external;\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(\n address payable withdrawAddress,\n uint256 withdrawAmount\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/UserOperation.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable no-inline-assembly */\n\nimport {calldataKeccak} from \"../core/Helpers.sol\";\n\n/**\n * User Operation struct\n * @param sender the sender account of this request.\n * @param nonce unique value the sender uses to verify it is not a replay.\n * @param initCode if set, the account contract will be created by this constructor/\n * @param callData the method call to execute on this account.\n * @param callGasLimit the gas limit passed to the callData method call.\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\n * @param maxFeePerGas same as EIP-1559 gas parameter.\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\n */\nstruct UserOperation {\n address sender;\n uint256 nonce;\n bytes initCode;\n bytes callData;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n bytes paymasterAndData;\n bytes signature;\n}\n\n/**\n * Utility functions helpful when working with UserOperation structs.\n */\nlibrary UserOperationLib {\n function getSender(\n UserOperation calldata userOp\n ) internal pure returns (address) {\n address data;\n //read sender from userOp, which is first userOp member (saves 800 gas...)\n assembly {\n data := calldataload(userOp)\n }\n return address(uint160(data));\n }\n\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\n // pay above what he signed for.\n function gasPrice(\n UserOperation calldata userOp\n ) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function pack(\n UserOperation calldata userOp\n ) internal pure returns (bytes memory ret) {\n address sender = getSender(userOp);\n uint256 nonce = userOp.nonce;\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\n bytes32 hashCallData = calldataKeccak(userOp.callData);\n uint256 callGasLimit = userOp.callGasLimit;\n uint256 verificationGasLimit = userOp.verificationGasLimit;\n uint256 preVerificationGas = userOp.preVerificationGas;\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\n\n return\n abi.encode(\n sender,\n nonce,\n hashInitCode,\n hashCallData,\n callGasLimit,\n verificationGasLimit,\n preVerificationGas,\n maxFeePerGas,\n maxPriorityFeePerGas,\n hashPaymasterAndData\n );\n }\n\n function hash(\n UserOperation calldata userOp\n ) internal pure returns (bytes32) {\n return keccak256(pack(userOp));\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n}\n" + }, + "contracts/aa-4337/utils/Exec.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.5 <0.9.0;\n\n// solhint-disable no-inline-assembly\n\n/**\n * Utility functions helpful when making different kinds of contract calls in Solidity.\n */\nlibrary Exec {\n function call(\n address to,\n uint256 value,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := call(\n txGas,\n to,\n value,\n add(data, 0x20),\n mload(data),\n 0,\n 0\n )\n }\n }\n\n function staticcall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal view returns (bool success) {\n assembly {\n success := staticcall(txGas, to, add(data, 0x20), mload(data), 0, 0)\n }\n }\n\n function delegateCall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := delegatecall(\n txGas,\n to,\n add(data, 0x20),\n mload(data),\n 0,\n 0\n )\n }\n }\n\n // get returned data from last call or calldelegate\n function getReturnData(\n uint256 maxLen\n ) internal pure returns (bytes memory returnData) {\n assembly {\n let len := returndatasize()\n if gt(len, maxLen) {\n len := maxLen\n }\n let ptr := mload(0x40)\n mstore(0x40, add(ptr, add(len, 0x20)))\n mstore(ptr, len)\n returndatacopy(add(ptr, 0x20), 0, len)\n returnData := ptr\n }\n }\n\n // revert with explicit byte array (probably reverted info from call)\n function revertWithData(bytes memory returnData) internal pure {\n assembly {\n revert(add(returnData, 32), mload(returnData))\n }\n }\n\n function callAndRevert(\n address to,\n bytes memory data,\n uint256 maxLen\n ) internal {\n bool success = call(to, 0, data, gasleft());\n if (!success) {\n revertWithData(getReturnData(maxLen));\n }\n }\n}\n" + }, + "contracts/Barz.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"./libraries/LibDiamond.sol\";\nimport {IBarz} from \"./interfaces/IBarz.sol\";\n\n/**\n * @title Barz\n * @dev A diamond proxy wallet with a modular & upgradeable architecture\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract Barz is IBarz {\n /**\n * @notice Initializes Barz with the given parameters. Barz account is intended to be created from Barz Factory for stable deployment.\n * @dev This method makes a delegate call to account facet and account facet handles the initialization.\n * With modular architecture, Barz encompasses wide spectrum of architecture and logic.\n * The only requirement is account facet to comply with initialize() interface.\n * Barz doesn't include built-in functions and is a full proxy, for maximum extensibility and modularity.\n * @param _accountFacet Address of Account Facet in charge of the Barz initialization\n * @param _verificationFacet Address of Verification Facet for verifying the signature. Could be any signature scheme\n * @param _entryPoint Address of Entry Point contract\n * @param _facetRegistry Address of Facet Registry. Facet Registry is a registry holding trusted facets that could be added to user's wallet\n * @param _defaultFallBack Address of Default FallBack Handler. Middleware contract for more efficient deployment\n * @param _ownerPublicKey Bytes of Owner Public Key using for initialization\n */\n constructor(\n address _accountFacet,\n address _verificationFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallBack,\n bytes memory _ownerPublicKey\n ) payable {\n bytes memory initCall = abi.encodeWithSignature(\n \"initialize(address,address,address,address,bytes)\",\n _verificationFacet,\n _entryPoint,\n _facetRegistry,\n _defaultFallBack,\n _ownerPublicKey\n );\n (bool success, bytes memory result) = _accountFacet.delegatecall(\n initCall\n );\n if (!success || uint256(bytes32(result)) != 1) {\n revert Barz__InitializationFailure();\n }\n }\n\n /**\n * @notice Fallback function for Barz complying with Diamond Standard with customization of adding Default Fallback Handler\n * @dev Find facet for function that is called and execute the function if a facet is found and return any value.\n */\n fallback() external payable {\n LibDiamond.DiamondStorage storage ds;\n bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION;\n // get diamond storage\n assembly {\n ds.slot := position\n }\n // get facet from function selector\n address facet = address(bytes20(ds.facets[msg.sig]));\n if (facet == address(0))\n facet = ds.defaultFallbackHandler.facetAddress(msg.sig);\n require(facet != address(0), \"Barz: Function does not exist\");\n // Execute external function from facet using delegatecall and return any value.\n assembly {\n // copy function selector and any arguments\n calldatacopy(0, 0, calldatasize())\n // execute function call using the facet\n let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)\n // get any return value\n returndatacopy(0, 0, returndatasize())\n // return any return value or error back to the caller\n switch result\n case 0 {\n revert(0, returndatasize())\n }\n default {\n return(0, returndatasize())\n }\n }\n }\n\n /**\n * @notice Receive function to receive native token without data\n */\n receive() external payable {}\n}\n" + }, + "contracts/BarzFactory.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Barz} from \"./Barz.sol\";\nimport {IBarzFactory} from \"./interfaces/IBarzFactory.sol\";\n\n/**\n * @title Barz Factory\n * @dev Contract to easily deploy Barz to a pre-computed address with a single call\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract BarzFactory is IBarzFactory {\n event BarzDeployed(address);\n\n address public immutable accountFacet;\n address public immutable entryPoint;\n address public immutable facetRegistry;\n address public immutable defaultFallback;\n\n /**\n * @notice Sets the initialization data for Barz contract initialization\n * @param _accountFacet Account Facet to be used to create Barz\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\n * @param _facetRegistry Facet Registry to be used to create Barz\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\n */\n constructor(\n address _accountFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallback\n ) {\n accountFacet = _accountFacet;\n entryPoint = _entryPoint;\n facetRegistry = _facetRegistry;\n defaultFallback = _defaultFallback;\n }\n\n /**\n * @notice Creates the Barz with a single call. It creates the Barz contract with the givent verification facet\n * @param _verificationFacet Address of verification facet used for creating the barz account\n * @param _owner Public Key of the owner to initialize barz account\n * @param _salt Salt used for deploying barz with create2\n * @return barz Instance of Barz contract deployed with the given parameters\n */\n function createAccount(\n address _verificationFacet,\n bytes calldata _owner,\n uint256 _salt\n ) external override returns (Barz barz) {\n address addr = getAddress(_verificationFacet, _owner, _salt);\n uint codeSize = addr.code.length;\n if (codeSize > 0) {\n return Barz(payable(addr));\n }\n barz = new Barz{salt: bytes32(_salt)}(\n accountFacet,\n _verificationFacet,\n entryPoint,\n facetRegistry,\n defaultFallback,\n _owner\n );\n emit BarzDeployed(address(barz));\n }\n\n /**\n * @notice Calculates the address of Barz with the given parameters\n * @param _verificationFacet Address of verification facet used for creating the barz account\n * @param _owner Public Key of the owner to initialize barz account\n * @param _salt Salt used for deploying barz with create2\n * @return barzAddress Precalculated Barz address\n */\n function getAddress(\n address _verificationFacet,\n bytes calldata _owner,\n uint256 _salt\n ) public view override returns (address barzAddress) {\n bytes memory bytecode = getBytecode(\n accountFacet,\n _verificationFacet,\n entryPoint,\n facetRegistry,\n defaultFallback,\n _owner\n );\n bytes32 hash = keccak256(\n abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(bytecode)\n )\n );\n barzAddress = address(uint160(uint256(hash)));\n }\n\n /**\n * @notice Returns the bytecode of Barz with the given parameter\n * @param _accountFacet Account Facet to be used to create Barz\n * @param _verificationFacet Verification Facet to be used to create Barz\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\n * @param _facetRegistry Facet Registry to be used to create Barz\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\n * @param _ownerPublicKey Public Key of owner to be used to initialize Barz ownership\n * @return barzBytecode Bytecode of Barz\n */\n function getBytecode(\n address _accountFacet,\n address _verificationFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallback,\n bytes calldata _ownerPublicKey\n ) public pure override returns (bytes memory barzBytecode) {\n bytes memory bytecode = type(Barz).creationCode;\n barzBytecode = abi.encodePacked(\n bytecode,\n abi.encode(\n _accountFacet,\n _verificationFacet,\n _entryPoint,\n _facetRegistry,\n _defaultFallback,\n _ownerPublicKey\n )\n );\n }\n\n /**\n * @notice Returns the creation code of the Barz contract\n * @return creationCode Creation code of Barz\n */\n function getCreationCode()\n public\n pure\n override\n returns (bytes memory creationCode)\n {\n creationCode = type(Barz).creationCode;\n }\n}\n" + }, + "contracts/facets/AccountFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {UserOperation} from \"../aa-4337/interfaces/UserOperation.sol\";\nimport {IEntryPoint} from \"../aa-4337/interfaces/IEntryPoint.sol\";\nimport {BaseAccount} from \"../aa-4337/core/BaseAccount.sol\";\nimport {LibAppStorage, BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {IFacetRegistry} from \"../infrastructure/interfaces/IFacetRegistry.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {IERC1271} from \"../interfaces/ERC/IERC1271.sol\";\nimport {IAccountFacet} from \"./interfaces/IAccountFacet.sol\";\n\n/**\n * @title Account Facet\n * @dev Account module contract that provides the account features and initialization of signer\n * compatible with EIP-1271 & EIP-4337\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract AccountFacet is BarzStorage, BaseAccount, IAccountFacet {\n using ECDSA for bytes32;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceAccountInitialize();\n }\n\n /**\n * @notice Returns the address of EntryPoint contract registered to Barz account\n */\n function entryPoint() public view override returns (IEntryPoint) {\n return s.entryPoint;\n }\n\n /**\n * @notice Initializes the initial storage of the Barz contract.\n * @dev This method can only be called during the initialization or signature migration.\n * If the proxy contract was created without initialization, anyone can call initialize.\n * Barz calls initialize in constructor in an atomic transaction during deployment\n * @param _verificationFacet Facet contract handling the verificationi\n * @param _anEntryPoint Entrypoint contract defined in EIP-4337 handling the flow of UserOp\n * @param _facetRegistry Registry of Facets that hold all facet information\n * @param _defaultFallBackHandler Middleware contract for default facets\n * @param _ownerPublicKey Bytes of owner public key\n */\n function initialize(\n address _verificationFacet,\n address _anEntryPoint,\n address _facetRegistry,\n address _defaultFallBackHandler,\n bytes calldata _ownerPublicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceAccountInitialize();\n s.entryPoint = IEntryPoint(_anEntryPoint);\n s.facetRegistry = IFacetRegistry(_facetRegistry);\n LibDiamond.diamondStorage().defaultFallbackHandler = IDiamondLoupe(\n _defaultFallBackHandler\n );\n\n _cutDiamondAccountFacet(_verificationFacet);\n\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n _ownerPublicKey\n );\n // Every Verification Facet should comply with initializeSigner(bytes)\n // to be compatible with the Barz contract(for initialization)\n (bool success, bytes memory result) = _verificationFacet.delegatecall(\n initCall\n );\n if (!success || uint256(bytes32(result)) != 1) {\n revert AccountFacet__InitializationFailure();\n }\n\n initSuccess = 1;\n emit AccountInitialized(s.entryPoint, _ownerPublicKey);\n }\n\n function _cutDiamondAccountFacet(address _verificationFacet) internal {\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](1);\n\n bytes4 ownerVerificationFuncSelector = IVerificationFacet(\n _verificationFacet\n ).validateOwnerSignatureSelector();\n\n bytes4[] memory verificationFunctionSelectors = new bytes4[](3);\n verificationFunctionSelectors[0] = IERC1271.isValidSignature.selector;\n verificationFunctionSelectors[1] = ownerVerificationFuncSelector;\n verificationFunctionSelectors[2] = IVerificationFacet.owner.selector;\n cut[0] = IDiamondCut.FacetCut({\n facetAddress: _verificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: verificationFunctionSelectors\n });\n\n LibDiamond.diamondCut(cut, address(0), \"\");\n }\n\n /**\n * @notice Calls the destination with inputted calldata and value from EntryPoint\n * @dev This method executes the calldata coming from the EntryPoint.\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\n * @param _dest Address of destination where the call will be forwarded to\n * @param _value Amount of native coin the owner is willing to send(e.g. ETH, BNB)\n * @param _func Bytes of calldata to execute in the destination address\n */\n function execute(\n address _dest,\n uint256 _value,\n bytes calldata _func\n ) external override onlyWhenUnlocked {\n _requireFromEntryPoint();\n _call(_dest, _value, _func);\n }\n\n /**\n * @notice Batch calls the destination with inputted calldata and value from EntryPoint\n * @dev This method batch executes the calldata coming from the EntryPoint.\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\n * @param _dest Array of addresses of destination where the call will be forwarded to\n * @param _value Array of amount of native coin the owner is willing to send(e.g. ETH, BNB)\n * @param _func Array of bytes of calldata to execute in the destination address\n */\n function executeBatch(\n address[] calldata _dest,\n uint256[] calldata _value,\n bytes[] calldata _func\n ) external override onlyWhenUnlocked {\n _requireFromEntryPoint();\n require(\n _dest.length == _func.length && _dest.length == _value.length,\n \"wrong array lengths\"\n );\n for (uint256 i; i < _dest.length; ) {\n _call(_dest[i], _value[i], _func[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Validates the signature field of UserOperation\n * @dev This method validates if the signature of UserOp is indeed valid by delegating the call to Verification Facet\n * Barz makes a call to the pre-registered Verification Facet address in App Storage\n * @param _userOp UserOperation from owner to be validated\n * @param _userOpHash Hash of UserOperation given from the EntryPoint contract\n */\n function _validateSignature(\n UserOperation calldata _userOp,\n bytes32 _userOpHash\n ) internal override returns (uint256 validationData) {\n // Get Facet with Function Selector\n address facet = LibLoupe.facetAddress(s.validateOwnerSignatureSelector);\n if (facet == address(0))\n revert AccountFacet__NonExistentVerificationFacet();\n\n // Make function call to VerificationFacet\n bytes memory validateCall = abi.encodeWithSelector(\n s.validateOwnerSignatureSelector,\n _userOp,\n _userOpHash\n );\n (bool success, bytes memory result) = facet.delegatecall(validateCall);\n if (!success) revert AccountFacet__CallNotSuccessful();\n validationData = uint256(bytes32(result));\n if (validationData == 0) emit VerificationSuccess(_userOpHash);\n else emit VerificationFailure(_userOpHash);\n }\n\n /**\n * @notice Calls the target with the inputted value and calldata\n * @dev This method is the actual function in Barz that makes a call with an arbitrary owner-given data\n * @param _target Address of the destination contract which the call is getting forwarded to\n * @param _value Amount of Native coin the owner is wanting to make in this call\n * @param _data Calldata the owner is forwarding together in the call e.g. Swap/Token Transfer\n */\n function _call(\n address _target,\n uint256 _value,\n bytes memory _data\n ) internal {\n address facet = LibDiamond.restrictionsFacet();\n // NOTE: No restrictions facet, so restriction validation passes\n if (facet != address(0)) {\n if (_checkRestrictions(facet, _target, _value, _data) == 1)\n revert AccountFacet__RestrictionsFailure();\n }\n\n (bool success, bytes memory result) = _target.call{value: _value}(\n _data\n );\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n }\n\n /**\n * @notice Checks restrictions if the restrictions facet exists\n * @dev This method checks if the restrictions facet exists and makes a verification call to an array of restrictions facet\n * @param _facet Address that holds the restrictions logic\n * @param _target Address the call is getting forwarded to\n * @param _value Amount of native coin the call is sending together with the call\n * @param _data Calldata to trigger execution in target address\n */\n function _checkRestrictions(\n address _facet,\n address _target,\n uint256 _value,\n bytes memory _data\n ) internal returns (uint256 result) {\n bytes memory call = abi.encodeWithSignature(\n \"verifyRestrictions(address,address,uint256,bytes)\",\n address(this),\n _target,\n _value,\n _data\n );\n (bool success, bytes memory response) = _facet.delegatecall(call);\n if (!success) revert AccountFacet__RestrictionsFailure();\n result = uint256(bytes32(response));\n }\n}\n" + }, + "contracts/facets/AccountRecoveryFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibFacetStorage, RecoveryStorage, RecoveryConfig, RecoveryApprovalConfig, ApprovalConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {IAccountRecoveryFacet} from \"./interfaces/IAccountRecoveryFacet.sol\";\n\n/**\n * @title Account Recovery Facet\n * @dev Contract that enables recovery of accounts when owner key is unavailable\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract AccountRecoveryFacet is IAccountRecoveryFacet, Modifiers {\n bytes constant UNINIT_CALL =\n abi.encodeWithSignature(\"uninitializeSigner()\");\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Approve recovery of account as guardian\n * @dev This method can only be called by guardian and guardian inputs the public key of the new owner\n * When the threshold(majority of guardians) passes, it automatically executes account recovery\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function approveAccountRecovery(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + _getApprovalValidationPeriod()\n );\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit RecoveryApproved(\n _recoveryPublicKey,\n msg.sender,\n approvalValidUntil\n );\n if (\n getRecoveryApprovalCountWithTimeValidity(recoveryPublicKeyHash) >=\n LibGuardian.majorityOfGuardians()\n ) _executeRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Revoke recovery of account as guardian\n * @dev This method can only be called by guardian and guardian inputs the public key of the new owner\n When the threshold(majority of guardians) passes, it automatically revokes account recovery when recovery is pending\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function revokeAccountRecoveryApproval(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n if (\n !rs\n .isNewOwnerApproved[recoveryPublicKeyHash][msg.sender].isApproved ||\n !(block.timestamp <\n rs\n .isNewOwnerApproved[recoveryPublicKeyHash][msg.sender]\n .validUntil)\n ) revert AccountRecoveryFacet__NonExistentApproval();\n\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(false, 0);\n emit RecoveryApprovalRevoked(_recoveryPublicKey, msg.sender);\n }\n\n /**\n * @notice Executes recovery with signatures or on-chain pre-approvals\n * @dev This method validates the signatures of guardians or checks the on-chain pre-approved calls to check if the threshold passes\n * When the threshold passes, account recovery is executed and revert otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _guardians Array of guardians address that are approving the recovery of Account\n * @param _signatures Array of signature bytes that signed the approval hash\n */\n function executeRecovery(\n bytes calldata _recoveryPublicKey,\n address[] calldata _guardians,\n bytes[] calldata _signatures\n ) external override {\n if (_isRecoveryPending())\n revert AccountRecoveryFacet__RecoveryAlreadyOngoing();\n if (_guardians.length != _signatures.length)\n revert AccountRecoveryFacet__InvalidArrayLength();\n validateNewOwner(_recoveryPublicKey);\n\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n\n _checkApprover(_guardians);\n _checkDuplicateOnChainApprover(recoveryPublicKeyHash, _guardians);\n\n if (\n _guardians.length +\n getRecoveryApprovalCountWithTimeValidity(\n recoveryPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians()\n ) revert AccountRecoveryFacet__InsufficientGuardians();\n for (uint256 i; i < _guardians.length; ) {\n if (!LibGuardian.isGuardian(_guardians[i]))\n revert AccountRecoveryFacet__InvalidGuardian();\n if (\n !SignatureChecker.isValidSignatureNow(\n _guardians[i],\n recoveryPublicKeyHash,\n _signatures[i]\n )\n ) revert AccountRecoveryFacet__InvalidGuardianSignature();\n unchecked {\n ++i;\n }\n }\n _executeRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Executes recovery of the account. Note that execution and finalization is a different process\n * @dev Executes the recovery and adds recovery data to recovery configuration. Locks the account\n * @param _recoveryPublicKey Public Key of the account for recovery\n */\n function _executeRecovery(bytes memory _recoveryPublicKey) internal {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n ++rs.nonce;\n uint64 executeAfter = uint64(block.timestamp + _getRecoveryPeriod());\n rs.recoveryConfigs[INNER_STRUCT] = RecoveryConfig(\n _recoveryPublicKey,\n executeAfter // NOTE: Remove guardian Count\n );\n LibAppStorage.setLock(\n block.timestamp + _getLockPeriod(),\n AccountRecoveryFacet.executeRecovery.selector\n );\n emit RecoveryExecuted(_recoveryPublicKey, executeAfter);\n }\n\n /**\n * @notice Finalize recovery after recovery pending period. Recovery pending period can be set by user beforehand in SecurityManager\n * @dev This method finalizes recovery and fully changes the ownership of the account to the newly inputted recovery public key\n */\n function finalizeRecovery() external override {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n if (\n uint64(block.timestamp) <=\n rs.recoveryConfigs[INNER_STRUCT].executeAfter\n ) revert AccountRecoveryFacet__RecoveryPeriodNotOver();\n bytes memory recoveryOwner = rs\n .recoveryConfigs[INNER_STRUCT]\n .recoveryPublicKey;\n\n delete rs.recoveryConfigs[INNER_STRUCT];\n\n LibAppStorage.setLock(0, bytes4(0));\n\n LibAppStorage.initiateSignerMigration();\n address verificationFacet = address(\n bytes20(\n LibDiamond.diamondStorage().facets[\n s.validateOwnerSignatureSelector\n ]\n )\n );\n (bool success, bytes memory result) = verificationFacet.delegatecall(\n UNINIT_CALL\n );\n if (!success) revert AccountRecoveryFacet__CallNotSuccesful();\n uint256 validationData = uint256(bytes32(result));\n if (validationData != 1)\n revert AccountRecoveryFacet__SignerUninitializationFailure();\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n recoveryOwner\n );\n (success, result) = verificationFacet.delegatecall(initCall);\n if (!success) revert AccountRecoveryFacet__CallNotSuccesful();\n validationData = uint256(bytes32(result));\n if (validationData != 1)\n revert AccountRecoveryFacet__SignerInitializationFailure();\n LibAppStorage.finalizeSignerMigration();\n emit RecoveryFinalized(recoveryOwner);\n }\n\n /**\n * @notice Approves the cancellation of recovery\n * @dev This method approves the cancellation of recovery when recovery is still pending - waiting for finalization\n * @param _recoveryPublicKey Bytes of public key which is pending for recovery\n */\n function approveCancelRecovery(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"CancelRecovery\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + _getApprovalValidationPeriod()\n );\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit RecoveryCancellationApproved(_recoveryPublicKey, msg.sender);\n if (\n getRecoveryApprovalCountWithTimeValidity(recoveryPublicKeyHash) >=\n LibGuardian.majorityOfGuardians()\n ) {\n _cancelRecovery(_recoveryPublicKey);\n }\n }\n\n /**\n * @notice Hardstops an ongoing recovery\n * @dev This method provides a safety mechanism to protect owners of malicious guardians.\n * Owners can hardstop recovery when an malicious guardians starts the recovery process.\n * @param _signature Signature of the owner that signs the hash to hardstop recovery\n */\n function hardstopRecovery(bytes calldata _signature) external override {\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n \"0\",\n \"HardstopRecovery\"\n );\n if (\n !SignatureChecker.isValidSignatureNow(\n address(this),\n recoveryPublicKeyHash,\n _signature\n )\n ) revert AccountRecoveryFacet__InvalidOwnerSignature();\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n ++rs.nonce;\n delete rs.recoveryConfigs[INNER_STRUCT];\n LibAppStorage.setLock(0, bytes4(0));\n emit RecoveryHardstopped();\n }\n\n /**\n * @notice Cancels recovery with signatures or on-chain pre-approvals\n * @dev This method validates the signatures of guardians or checks the on-chain pre-approved calls to check if the threshold passes\n * When the threshold passes, account recovery is canceled and revert otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _guardians Array of guardians address that are approving the recovery of Account\n * @param _signatures Array of signature bytes that signed the cancellation approval hash\n */\n function cancelRecovery(\n bytes calldata _recoveryPublicKey,\n address[] calldata _guardians,\n bytes[] calldata _signatures\n ) external override {\n if (_guardians.length != _signatures.length)\n revert AccountRecoveryFacet__InvalidArrayLength();\n validateNewOwner(_recoveryPublicKey);\n\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"CancelRecovery\"\n );\n\n _checkApprover(_guardians);\n _checkDuplicateOnChainApprover(recoveryPublicKeyHash, _guardians);\n\n if (\n _guardians.length +\n getRecoveryApprovalCountWithTimeValidity(\n recoveryPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians()\n ) revert AccountRecoveryFacet__InsufficientGuardians();\n for (uint256 i; i < _guardians.length; ) {\n if (!LibGuardian.isGuardian(_guardians[i]))\n revert AccountRecoveryFacet__CallerNotGuardian();\n if (\n !SignatureChecker.isValidSignatureNow(\n _guardians[i],\n recoveryPublicKeyHash,\n _signatures[i]\n )\n ) revert AccountRecoveryFacet__InvalidGuardianSignature();\n unchecked {\n ++i;\n }\n }\n _cancelRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Cancel recovery when the recovery is pending. Unlock the account as well\n * @dev This method checks if the recovery is pending and reverts if not pending.\n * It increases the recovery nonce and deletes the recovery information and gets a small portion of gas in return\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function _cancelRecovery(bytes memory _recoveryPublicKey) internal {\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n LibAppStorage.setLock(0, bytes4(0));\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n ++rs.nonce;\n delete rs.recoveryConfigs[INNER_STRUCT];\n emit RecoveryCanceled(_recoveryPublicKey);\n }\n\n /**\n * @notice Validates the format of public key to be used for recovery\n * @dev This method checks if the public key format is correct and reverts otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function validateNewOwner(bytes memory _recoveryPublicKey) public view {\n if (\n !IVerificationFacet(\n LibLoupe.facetAddress(s.validateOwnerSignatureSelector)\n ).isValidKeyType(_recoveryPublicKey)\n ) revert AccountRecoveryFacet__InvalidRecoveryPublicKey();\n }\n\n /**\n * @notice Checks if recovery is currently pending\n * @return isPending Boolean indicating if recovery is pending\n */\n function _isRecoveryPending() internal view returns (bool isPending) {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n isPending = (rs.recoveryConfigs[INNER_STRUCT].executeAfter > 0);\n }\n\n /**\n * @notice Calculate the recovery hash dependent on chain, wallet address, nonce with EIP-191 prefix for safety\n * @dev Returns the keccak256 hash of EIP-191 msg hash packed with public key, salt, nonce, wallet address, etc\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _saltString Salt string to uniquely identify each recovery hash and for security\n * @return recoveryKeyHash Bytes32 string of the recovery hash\n */\n function getApprovalRecoveryKeyHash(\n bytes memory _recoveryPublicKey,\n string memory _saltString\n ) public view override returns (bytes32 recoveryKeyHash) {\n recoveryKeyHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n _recoveryPublicKey,\n _saltString,\n address(this),\n block.chainid,\n LibFacetStorage.recoveryStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Check the onchain approval of guardians and returns the number of guardians that approved\n * @dev Loop through the guardian addresses and returns the number of guardians that approved this recovery hash\n * @param _recoveryPublicKeyHash Bytes hash of newly recovered public key and recovery value of the account\n * @return approvalCount Number of guardians that approved\n */\n function getRecoveryApprovalCountWithTimeValidity(\n bytes32 _recoveryPublicKeyHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n for (uint256 i; i < guardianLength; ) {\n if (isRecoveryApproved(_recoveryPublicKeyHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Checks if the recovery is approved by the given approver\n * @param _recoveryPublicKeyHash Hash of the public key and configuration for recovery\n * @param _approver Address of approver\n * @return isApproved Bool value if recovery hash is approved\n */\n function isRecoveryApproved(\n bytes32 _recoveryPublicKeyHash,\n address _approver\n ) public view override returns (bool isApproved) {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n if (\n rs\n .isNewOwnerApproved[_recoveryPublicKeyHash][_approver].isApproved &&\n block.timestamp <\n rs.isNewOwnerApproved[_recoveryPublicKeyHash][_approver].validUntil\n ) {\n isApproved = true;\n }\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _recoveryPublicKeyHash Hash of recovery information\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _recoveryPublicKeyHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isRecoveryApproved(_recoveryPublicKeyHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert AccountRecoveryFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the lock period of this wallet address from security manager\n * @return lockPeriod value of lock period\n */\n function _getLockPeriod() internal view returns (uint256 lockPeriod) {\n lockPeriod = securityManager.lockPeriodOf(address(this));\n if (lockPeriod == 0) revert AccountRecoveryFacet__InvalidLockPeriod();\n }\n\n /**\n * @notice Returns the lock period of this wallet address from security manager\n * @return recoveryPeriod value of recovery period\n */\n function _getRecoveryPeriod()\n internal\n view\n returns (uint256 recoveryPeriod)\n {\n recoveryPeriod = securityManager.recoveryPeriodOf(address(this));\n if (recoveryPeriod == 0)\n revert AccountRecoveryFacet__InvalidRecoveryPeriod();\n }\n\n /**\n * @notice Returns the approval validation period of this wallet address from security manager\n * @return approvalValidationPeriod value of approval validation period\n */\n function _getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod == 0)\n revert AccountRecoveryFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the recovery nonce of this wallet address from security manager\n * @return nonce value of recovery nonce\n */\n function getRecoveryNonce() public view override returns (uint128 nonce) {\n nonce = LibFacetStorage.recoveryStorage().nonce;\n }\n\n /**\n * @notice Returns the recovery information of the pending recovery\n * @return recoveryConfig value struct of pending recovery\n */\n function getPendingRecovery()\n public\n view\n override\n returns (RecoveryConfig memory recoveryConfig)\n {\n recoveryConfig = LibFacetStorage.recoveryStorage().recoveryConfigs[\n INNER_STRUCT\n ];\n }\n}\n" + }, + "contracts/facets/base/DiamondCutFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibGuardian} from \"../../libraries/LibGuardian.sol\";\nimport {ISecurityManager} from \"../../infrastructure/interfaces/ISecurityManager.sol\";\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibFacetStorage, DiamondCutApprovalConfig, ApprovalConfig} from \"../../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"../Modifiers.sol\";\nimport {IDiamondCut} from \"./interfaces/IDiamondCut.sol\";\n\n/**\n * @title DiamondCut Facet\n * @dev Responsible for adding/removing/replace facets in Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DiamondCutFacet is Modifiers, IDiamondCut {\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Updates the flag for the interfaceId\n * @param _interfaceId InterfaceID to update the mapping\n * @param _flag Bool value to update the mapping of the given interface ID\n */\n function updateSupportsInterface(\n bytes4 _interfaceId,\n bool _flag\n ) external override onlyWhenUnlocked {\n LibDiamond.enforceIsSelf();\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId] = _flag;\n emit SupportsInterfaceUpdated(_interfaceId, _flag);\n }\n\n /**\n * @notice Add/replace/remove any number of functions and optionally execute\n * a function with delegatecall when guardians don't exist\n * @param _diamondCut Contains the facet addresses and function selectors\n * @param _init The address of the contract or facet to execute _calldata. It's prohibited in Barz\n */\n function diamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata\n ) external override onlyWhenUnlocked {\n LibDiamond.enforceIsSelf();\n\n _checkFacetCutValidity(_diamondCut);\n // require approval from guardian if guardian exists\n if (0 != LibGuardian.guardianCount())\n revert DiamondCutFacet__InvalidRouteWithGuardian();\n if (address(0) != _init) revert DiamondCutFacet__InvalidInitAddress();\n\n ++LibFacetStorage.diamondCutStorage().nonce;\n LibDiamond.diamondCut(_diamondCut, address(0), \"\");\n }\n\n /**\n * @notice Add/replace/remove any number of functions and optionally execute\n * a function with delegatecall when guardians exist\n * @param _diamondCut Contains the facet addresses and function selectors\n * @param _approvers Guardian or owner address that approves the diamond cut\n * @param _signatures Signature of Guardians or owner that approves the diamond cut\n */\n function diamondCutWithGuardian(\n FacetCut[] calldata _diamondCut,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n ) external override onlyWhenUnlocked {\n if (_approvers.length != _signatures.length)\n revert DiamondCutFacet__InvalidArrayLength();\n _checkFacetCutValidity(_diamondCut);\n if (0 == LibGuardian.guardianCount())\n revert DiamondCutFacet__InvalidRouteWithGuardian();\n\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(cutHash, _approvers);\n\n bool onChainOwnerApproval = getOwnerCutApprovalWithTimeValidity(\n cutHash\n );\n\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n if (\n _approvers.length +\n getDiamondCutApprovalCountWithTimeValidity(cutHash) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert DiamondCutFacet__InsufficientApprovers();\n\n bool ownerApproved;\n for (uint256 i; i < _approvers.length; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n _approvers[i] != address(this)\n ) revert DiamondCutFacet__InvalidApprover();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert DiamondCutFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n cutHash,\n _signatures[i]\n )\n ) revert DiamondCutFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n if (!ownerApproved && !onChainOwnerApproval)\n revert DiamondCutFacet__LackOfOwnerApproval();\n\n ++LibFacetStorage.diamondCutStorage().nonce;\n LibDiamond.diamondCut(_diamondCut, address(0), \"\");\n }\n\n /**\n * @notice Approves diamond cut. This can only be called directly from guardian or owner\n * @param _diamondCut Contains the facet addresses and function selectors\n */\n function approveDiamondCut(\n FacetCut[] calldata _diamondCut\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\n if (LibGuardian.guardianCount() == 0)\n revert DiamondCutFacet__InvalidRouteWithoutGuardian();\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n _checkFacetCutValidity(_diamondCut);\n\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(\n true,\n approvalValidUntil\n );\n emit DiamondCutApproved(_diamondCut);\n if (\n (getDiamondCutApprovalCountWithTimeValidity(cutHash) >=\n LibGuardian.majorityOfGuardians()) &&\n getOwnerCutApprovalWithTimeValidity(cutHash)\n ) {\n ++LibFacetStorage.diamondCutStorage().nonce;\n LibDiamond.diamondCut(_diamondCut, address(0), \"\");\n }\n }\n\n /**\n * @notice Revokes the approval of diamond cut. This can only be called directly from guardian or owner\n * @param _diamondCut Contains the facet addresses and function selectors\n */\n function revokeDiamondCutApproval(\n FacetCut[] calldata _diamondCut\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\n if (!ds.isDiamondCutApproved[cutHash][msg.sender].isApproved)\n revert DiamondCutFacet__CannotRevokeUnapproved();\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(false, 0);\n emit DiamondCutApprovalRevoked(_diamondCut);\n }\n\n /**\n * @notice Gets the number of approvals of diamond cut from guardians\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n */\n function getDiamondCutApprovalCountWithTimeValidity(\n bytes32 _diamondCutHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardiansLength = guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n if (isCutApproved(_diamondCutHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n return approvalCount;\n }\n\n /**\n * @notice Returns if the owner has approved the diamond cut\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @return isApprovedByOwner Bool value showing if the owner approved the cut\n */\n function getOwnerCutApprovalWithTimeValidity(\n bytes32 _diamondCutHash\n ) public view override returns (bool isApprovedByOwner) {\n isApprovedByOwner = isCutApproved(_diamondCutHash, address(this));\n }\n\n /**\n * @notice Returns if the given approver has approved the diamond cut\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @param _approver Address of approver\n * @return isApproved Bool value showing if the approver approved the cut\n */\n function isCutApproved(\n bytes32 _diamondCutHash,\n address _approver\n ) public view override returns (bool isApproved) {\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n isApproved = (ds\n .isDiamondCutApproved[_diamondCutHash][_approver].isApproved &&\n block.timestamp <\n ds.isDiamondCutApproved[_diamondCutHash][_approver].validUntil);\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _diamondCutHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isCutApproved(_diamondCutHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert DiamondCutFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the diamond cut hash. This function ensures that this hash is safe from replay attack by including\n * salt, address, chainId, and nonce, etc.\n * @param _diamondCut Contains the facet addresses and function selectors\n * @return cutHash Diamond Cut Hash\n */\n function getDiamondCutHash(\n FacetCut[] calldata _diamondCut\n ) public view override returns (bytes32 cutHash) {\n cutHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n keccak256(abi.encode(_diamondCut)),\n address(this),\n block.chainid,\n LibFacetStorage.diamondCutStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Returns the approval validation Period\n * @dev This method fetches the validation period from the security manager\n * @return approvalValidationPeriod Approval validation period of Barz contract fetched from security manager\n */\n function getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod <= 0)\n revert DiamondCutFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the diamond cut nonce of this wallet\n * @dev This method fetches the nonce from diamond cut storage\n * @return cutNonce Nonce of diamond cut to protect from reply attacks\n */\n function getDiamondCutNonce()\n public\n view\n override\n returns (uint128 cutNonce)\n {\n cutNonce = LibFacetStorage.diamondCutStorage().nonce;\n }\n}\n" + }, + "contracts/facets/base/DiamondLoupeFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {IERC165} from \"../../interfaces/ERC/IERC165.sol\";\nimport {IERC1271} from \"../../interfaces/ERC/IERC1271.sol\";\nimport {IERC677Receiver} from \"../../interfaces/ERC/IERC677Receiver.sol\";\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC1155Receiver} from \"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\";\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../../libraries/LibLoupe.sol\";\nimport {LibUtils} from \"../../libraries/LibUtils.sol\";\nimport {IDiamondCut} from \"../../facets/base/interfaces/IDiamondCut.sol\";\nimport {IStorageLoupe} from \"./interfaces/IStorageLoupe.sol\";\nimport {IDiamondLoupe} from \"./interfaces/IDiamondLoupe.sol\";\n\n/**\n * @title DiamondLoupe Facet\n * @dev DiamondLoupe contract compatible with EIP-2535\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DiamondLoupeFacet is IDiamondLoupe, IStorageLoupe, IERC165 {\n // Diamond Loupe Functions\n ////////////////////////////////////////////////////////////////////\n /// These functions are expected to be called frequently by tools off-chain.\n\n /**\n * @notice Gets all facets and their selectors.\n * @dev Barz uses a special architecture called default fallback handler. Default Fallback handler is used as a middleware\n * that holds the mapping of facet function selector and facet address that Barz uses. This helps Barz to reduce\n * significant amount of gas during the initialization process.\n * Hence, this method aggregates both the facet information from DefaulFallbackHandler and in diamond storage and shows the data to users.\n * @return facets_ Facet\n */\n function facets() public view override returns (Facet[] memory facets_) {\n Facet[] memory defaultFacet = LibDiamond\n .diamondStorage()\n .defaultFallbackHandler\n .facets();\n Facet[] memory _facets = LibLoupe.facets();\n uint256 numFacets = _facets.length;\n bytes4[] memory keys;\n address[] memory values;\n for (uint256 i; i < numFacets; ) {\n uint256 selectorsLength = _facets[i].functionSelectors.length;\n for (uint256 j; j < selectorsLength; ) {\n (keys, values) = LibUtils.setValue(\n keys,\n values,\n _facets[i].functionSelectors[j],\n _facets[i].facetAddress\n );\n unchecked {\n ++j;\n }\n }\n unchecked {\n ++i;\n }\n }\n {\n bool iIncrement;\n for (uint256 i; i < defaultFacet.length; ) {\n bool jIncrement;\n for (\n uint256 j;\n j < defaultFacet[i].functionSelectors.length;\n\n ) {\n if (\n LibUtils.getValue(\n keys,\n values,\n defaultFacet[i].functionSelectors[j]\n ) != address(0)\n ) {\n if (defaultFacet[i].functionSelectors.length == 1) {\n defaultFacet = LibUtils.removeFacetElement(\n defaultFacet,\n i\n );\n iIncrement = true;\n break;\n }\n defaultFacet[i].functionSelectors = LibUtils\n .removeElement(\n defaultFacet[i].functionSelectors,\n j\n );\n jIncrement = true;\n }\n if (!jIncrement) {\n unchecked {\n ++j;\n }\n } else {\n jIncrement = false;\n }\n }\n if (!iIncrement) {\n unchecked {\n ++i;\n }\n } else {\n iIncrement = false;\n }\n }\n }\n {\n uint256 facetLength = numFacets + defaultFacet.length;\n facets_ = new Facet[](facetLength);\n uint256 defaultFacetIndex;\n for (uint256 i; i < facetLength; ) {\n if (i < numFacets) {\n facets_[i] = _facets[i];\n bool jIncrementor;\n for (uint256 j; j < defaultFacet.length; ) {\n if (\n facets_[i].facetAddress ==\n defaultFacet[j].facetAddress\n ) {\n facets_[i].functionSelectors = LibUtils.mergeArrays(\n _facets[i].functionSelectors,\n defaultFacet[j].functionSelectors\n );\n defaultFacet = LibUtils.removeFacetElement(\n defaultFacet,\n j\n );\n jIncrementor = true;\n {\n facets_ = LibUtils.removeFacetElement(\n facets_,\n facets_.length - 1\n );\n }\n --facetLength;\n }\n if (!jIncrementor) {\n unchecked {\n ++j;\n }\n } else {\n jIncrementor = false;\n }\n }\n } else {\n facets_[i] = defaultFacet[defaultFacetIndex];\n ++defaultFacetIndex;\n }\n unchecked {\n ++i;\n }\n }\n }\n }\n\n /**\n * @notice Gets all the function selectors provided by a facet.\n * @param _facet The facet address.\n * @return facetFunctionSelectors_\n */\n function facetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n Facet[] memory facet = facets();\n uint256 facetLength = facet.length;\n for (uint256 i; i < facetLength; ) {\n if (facet[i].facetAddress == _facet)\n return facet[i].functionSelectors;\n unchecked {\n ++i;\n }\n }\n return facetFunctionSelectors_;\n }\n\n /**\n * @notice Get all the facet addresses used by Barz.\n * @return facetAddresses_\n */\n function facetAddresses()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n Facet[] memory facet = facets();\n uint256 facetLength = facet.length;\n facetAddresses_ = new address[](facetLength);\n for (uint256 i; i < facetLength; ) {\n facetAddresses_[i] = facet[i].facetAddress;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Gets the facet that supports the given selector.\n * @dev If facet is not found return address(0).\n * @param _functionSelector The function selector.\n * @return facetAddress_ The facet address.\n */\n function facetAddress(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n\n facetAddress_ = address(bytes20(ds.facets[_functionSelector]));\n if (facetAddress_ == address(0)) {\n facetAddress_ = IDiamondLoupe(ds.defaultFallbackHandler)\n .facetAddress(_functionSelector);\n }\n }\n\n /**\n * @notice SupportInterface to be compatible with EIP 165\n * @param _interfaceId Interface ID for detecting the interface\n * @return isSupported Bool value showing if the standard is supported in the contract\n */\n function supportsInterface(\n bytes4 _interfaceId\n ) external view override returns (bool isSupported) {\n isSupported =\n _interfaceId == type(IERC165).interfaceId ||\n _interfaceId == IDiamondCut.diamondCut.selector ||\n _interfaceId == type(IDiamondLoupe).interfaceId ||\n _interfaceId == type(IERC1155Receiver).interfaceId ||\n _interfaceId == type(IERC721Receiver).interfaceId ||\n _interfaceId == type(IERC777Recipient).interfaceId ||\n _interfaceId == IERC1271.isValidSignature.selector ||\n _interfaceId == type(IERC677Receiver).interfaceId ||\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId];\n }\n\n /**\n * @notice Returns the facet from the diamond storage. This excludes the facets from the default fallback handler\n * @return facets_ Facet information attached directly to diamond storage\n */\n function facetsFromStorage()\n external\n view\n override\n returns (Facet[] memory facets_)\n {\n facets_ = LibLoupe.facets();\n }\n\n /**\n * @notice Returns the facet address attached to the given function selector. This excludes the facets from the default fallback handler\n * @param _functionSelector Function selector to fetch the facet address from diamond storage\n * @return facetAddress_ Facet address mapped with the function selector\n */\n function facetAddressFromStorage(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n facetAddress_ = LibLoupe.facetAddress(_functionSelector);\n }\n\n /**\n * @notice Returns all facet addresses attached directly to diamond storage. This excludes the facets from the default fallback handler\n * @return facetAddresses_ All facet addresses attached directly to diamond storage\n */\n function facetAddressesFromStorage()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n facetAddresses_ = LibLoupe.facetAddresses();\n }\n\n /**\n * @notice Returns function selectors of given facet address attached directly to diamond storage. This excludes the facets from the default fallback handler\n * @param _facet Facet address to fetch the facet function selectors from diamond storage\n * @return facetFunctionSelectors_ Facet function selectors of the given facet address\n */\n function facetFunctionSelectorsFromStorage(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n facetFunctionSelectors_ = LibLoupe.facetFunctionSelectors(_facet);\n }\n}\n" + }, + "contracts/facets/base/interfaces/IDiamondCut.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title DiamondCut Facet Interface\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IDiamondCut {\n error DiamondCutFacet__InvalidRouteWithGuardian();\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\n error DiamondCutFacet__InvalidArrayLength();\n error DiamondCutFacet__InsufficientApprovers();\n error DiamondCutFacet__InvalidApprover();\n error DiamondCutFacet__InvalidApproverSignature();\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\n error DiamondCutFacet__CannotRevokeUnapproved();\n error DiamondCutFacet__LackOfOwnerApproval();\n error DiamondCutFacet__OwnerAlreadyApproved();\n error DiamondCutFacet__DuplicateApproval();\n error DiamondCutFacet__InvalidInitAddress();\n\n event DiamondCutApproved(FacetCut[] diamondCut);\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\n\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\n\n enum FacetCutAction {\n Add,\n Replace,\n Remove\n }\n // Add=0, Replace=1, Remove=2\n\n struct FacetCut {\n address facetAddress;\n FacetCutAction action;\n bytes4[] functionSelectors;\n }\n\n /// @notice Add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param diamondCut Contains the facet addresses and function selectors\n /// @param init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function diamondCut(\n FacetCut[] calldata diamondCut,\n address init,\n bytes calldata _calldata\n ) external;\n\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\n\n function diamondCutWithGuardian(\n FacetCut[] calldata diamondCut,\n address[] calldata approvers,\n bytes[] calldata signatures\n ) external;\n\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\n\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\n\n function getDiamondCutApprovalCountWithTimeValidity(\n bytes32 diamondCutHash\n ) external view returns (uint256);\n\n function getOwnerCutApprovalWithTimeValidity(\n bytes32 diamondCutHash\n ) external view returns (bool);\n\n function isCutApproved(\n bytes32 diamondCutHash,\n address approver\n ) external view returns (bool);\n\n function getDiamondCutHash(\n FacetCut[] calldata diamondCut\n ) external view returns (bytes32);\n\n function getDiamondCutNonce() external view returns (uint128);\n}\n" + }, + "contracts/facets/base/interfaces/IDiamondLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n// A loupe is a small magnifying glass used to look at diamonds.\n// These functions look at diamonds\ninterface IDiamondLoupe {\n /// These functions are expected to be called frequently\n /// by tools.\n\n struct Facet {\n address facetAddress;\n bytes4[] functionSelectors;\n }\n\n /// @notice Gets all facet addresses and their four byte function selectors.\n /// @return facets_ Facet\n function facets() external view returns (Facet[] memory facets_);\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n /// @return facetFunctionSelectors_\n function facetFunctionSelectors(\n address _facet\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses()\n external\n view\n returns (address[] memory facetAddresses_);\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(\n bytes4 _functionSelector\n ) external view returns (address facetAddress_);\n}\n" + }, + "contracts/facets/base/interfaces/IStorageLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"./IDiamondLoupe.sol\";\n\n/**\n * @title LoupeFromStorage Interface\n * @dev Interface contract to function as a loupe facet directly attached to diamond storage of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IStorageLoupe {\n /// These functions are expected to be called frequently\n /// by tools.\n\n /// @notice Gets all facet addresses and their four byte function selectors.\n /// @return facets_ Facet\n function facetsFromStorage()\n external\n view\n returns (IDiamondLoupe.Facet[] memory);\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n function facetFunctionSelectorsFromStorage(\n address _facet\n ) external view returns (bytes4[] memory);\n\n /// @notice Get all the facet addresses used by a diamond.\n function facetAddressesFromStorage()\n external\n view\n returns (address[] memory);\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n function facetAddressFromStorage(\n bytes4 _functionSelector\n ) external view returns (address);\n}\n" + }, + "contracts/facets/GuardianFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibFacetStorage, GuardianStorage, StorageConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IGuardianFacet} from \"./interfaces/IGuardianFacet.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Guardian Facet\n * @dev Contract that enables addition/removal of guardians from Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract GuardianFacet is IGuardianFacet {\n ISecurityManager public immutable securityManager;\n uint8 public constant INNER_STRUCT = 0;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Add guardians to Barz.\n * @dev This method internally calls addGuardian which checks the validity of guardian address and adds\n * as guardian if valid\n * @param _guardians Array of addresses to add as guardian\n */\n function addGuardians(address[] calldata _guardians) external override {\n LibDiamond.enforceIsSelf();\n for (uint256 i; i < _guardians.length; ) {\n addGuardian(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Add a guardian to Barz.\n * @dev This method checks if the function is called by the owner and validates the address of guardian\n * When the validation passes, guardian address is added to the pending state waiting for confirmation\n * @param _guardian Address to add as guardian\n */\n function addGuardian(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (_guardian == address(this))\n revert GuardianFacet__GuardianCannotBeSelf();\n if (isGuardian(_guardian)) revert GuardianFacet__DuplicateGuardian();\n if (_guardian == address(0))\n revert GuardianFacet__ZeroAddressGuardian();\n if (\n keccak256(abi.encodePacked(_guardian)) ==\n keccak256(IVerificationFacet(address(this)).owner())\n ) revert GuardianFacet__OwnerCannotBeGuardian();\n\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n if (\n gs.pending[id] != 0 ||\n block.timestamp <= gs.pending[id] + getSecurityWindow()\n ) revert GuardianFacet__DuplicateGuardianAddition();\n\n uint256 securityPeriod = getAdditionSecurityPeriod();\n gs.pending[id] = block.timestamp + securityPeriod;\n emit GuardianAdditionRequested(\n _guardian,\n block.timestamp + securityPeriod\n );\n }\n\n /**\n * @notice Remove guardians from Barz.\n * @dev This method internally calls removeGuardian which checks the validity of guardian and removes\n * guardian when the request is valid\n * @param _guardians Array of addresses to be removed\n */\n function removeGuardians(address[] calldata _guardians) external override {\n LibDiamond.enforceIsSelf();\n for (uint256 i; i < _guardians.length; ) {\n removeGuardian(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Remove a guardian from Barz.\n * @dev This method validates if the guardian to be removed is a guardian and puts the guardian removal\n * to a pending state waiting to be confirmed.\n * @param _guardian Address of guardian to be removed\n */\n function removeGuardian(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n if (!isGuardian(_guardian)) revert GuardianFacet__NonExistentGuardian();\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n if (\n gs.pending[id] != 0 ||\n block.timestamp <= gs.pending[id] + getSecurityWindow()\n ) revert GuardianFacet__DuplicateGuardianRemoval();\n\n uint256 securityPeriod = getRemovalSecurityPeriod();\n gs.pending[id] = block.timestamp + securityPeriod;\n emit GuardianRemovalRequested(\n _guardian,\n block.timestamp + securityPeriod\n );\n }\n\n /**\n * @notice Confirm addition of guardians\n * @dev This method internally calls confirmGuardianAddition which checks the validity of pending request.\n * Guardians are fully added when they pass the validation. Anyone can call this function.\n * @param _guardians Array of guardian addresses to be added\n */\n function confirmGuardianAdditions(\n address[] calldata _guardians\n ) external override {\n for (uint256 i; i < _guardians.length; ) {\n confirmGuardianAddition(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Confirm addition of a guardian\n * @dev This method checks the validity of pending request.\n * Guardians are fully added when they pass the validation. Anyone can call this function.\n * @param _guardian Guardian address to be added\n */\n function confirmGuardianAddition(address _guardian) public override {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingAddition();\n if (gs.pending[id] >= block.timestamp)\n revert GuardianFacet__PendingAdditionNotOver();\n if (block.timestamp >= gs.pending[id] + getSecurityWindow())\n revert GuardianFacet__PendingAdditionExpired();\n\n _addGuardian(_guardian);\n\n delete gs.pending[id];\n emit GuardianAdded(_guardian);\n }\n\n /**\n * @notice Confirm removal of guardians\n * @dev This method internally calls confirmGuardianRemoval to check the validity guardian removal confirmation.\n * Guardians are fully removed when they pass the validation. Anyone can call this function.\n * @param _guardians Array of guardian addresses to be removed\n */\n function confirmGuardianRemovals(\n address[] calldata _guardians\n ) external override {\n for (uint256 i; i < _guardians.length; ) {\n confirmGuardianRemoval(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Confirm removal of a guardian\n * @dev This method checks the validity guardian removal confirmation.\n * Guardian is fully removed when they pass the validation. Anyone can call this function.\n * @param _guardian Guardian address to be removed\n */\n function confirmGuardianRemoval(address _guardian) public override {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingRemoval();\n if (gs.pending[id] >= block.timestamp)\n revert GuardianFacet__PendingRemovalNotOver();\n if (block.timestamp >= gs.pending[id] + getSecurityWindow())\n revert GuardianFacet__PendingAdditionExpired();\n\n _removeGuardian(_guardian);\n delete gs.pending[id];\n emit GuardianRemoved(_guardian);\n }\n\n /**\n * @notice Cancel pending guardian addition\n * @dev This method checks if the previous request for guardian request exists.\n * It reverts if previous request is not pending and cancels the addition otherwise.\n * @param _guardian Guardian address to be canceled from addition\n */\n function cancelGuardianAddition(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingAddition();\n delete gs.pending[id];\n emit GuardianAdditionCancelled(_guardian);\n }\n\n /**\n * @notice Cancel pending guardian removal\n * @dev This method checks if the previous request for guardian request exists.\n * It reverts if previous request is not pending and cancels the removal otherwise.\n * @param _guardian Guardian address to be canceled from removal\n */\n function cancelGuardianRemoval(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingRemoval();\n delete gs.pending[id];\n emit GuardianRemovalCancelled(_guardian);\n }\n\n /**\n * @notice Get the addition security period of current account from security manager\n * @dev This method returns the uint value if addition security period\n * @return additionSecurityPeriod Uint256 value of addition security period\n */\n function getAdditionSecurityPeriod()\n public\n view\n override\n returns (uint256 additionSecurityPeriod)\n {\n additionSecurityPeriod = securityManager.additionSecurityPeriodOf(\n address(this)\n );\n if (additionSecurityPeriod == 0)\n revert GuardianFacet__InvalidAdditionSecurityPeriod();\n }\n\n /**\n * @notice Get the removal security period of current account from security manager\n * @dev This method returns the uint value if removal security period\n * @return removalSecurityPeriod Uint256 value of removal security period\n */\n function getRemovalSecurityPeriod()\n public\n view\n override\n returns (uint256 removalSecurityPeriod)\n {\n removalSecurityPeriod = securityManager.removalSecurityPeriodOf(\n address(this)\n );\n if (removalSecurityPeriod == 0)\n revert GuardianFacet__InvalidRemovalSecurityPeriod();\n }\n\n /**\n * @notice Get the security window of current account from security manager\n * @dev This method returns the uint value if security window\n * @return securityWindow Uint256 value of removal security period\n */\n function getSecurityWindow()\n public\n view\n override\n returns (uint256 securityWindow)\n {\n securityWindow = securityManager.securityWindowOf(address(this));\n if (securityWindow == 0) revert GuardianFacet__InvalidSecurityWindow();\n }\n\n /**\n * @notice Checks if the addition of the given guardian address is pending\n * @dev This method returns the bool value of whether the guardian address is pending addition\n * @return isPending Bool value of representing the pending of guardian addition\n */\n function isAdditionPending(\n address _guardian\n ) public view override returns (bool isPending) {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n isPending = _isPending(id);\n }\n\n /**\n * @notice Checks if the removal of the given guardian address is pending\n * @dev This method returns the bool value of whether the guardian address is pending removal\n * @return isPending Bool value of representing the pending of guardian removal\n */\n function isRemovalPending(\n address _guardian\n ) public view override returns (bool isPending) {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n isPending = _isPending(id);\n }\n\n /**\n * @notice Checks if the given hash is pending\n * @dev This method returns the bool value whether the hash is pending\n * @return isPending Bool value of representing the pending of guardian operation\n */\n function _isPending(\n bytes32 _idHash\n ) internal view returns (bool isPending) {\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n isPending = ((gs.pending[_idHash] > 0 &&\n gs.pending[_idHash] < block.timestamp) &&\n block.timestamp < gs.pending[_idHash] + getSecurityWindow());\n }\n\n /**\n * @notice Adds guardian to storage config. This is called when guardian is fully added.\n * @dev This method add guardian address and config information to Facet Storage dedicated for guardian\n * When this function is called, guardian is fully added to this Barz Smart Account\n * @param _guardian Address of guardian to be added\n */\n function _addGuardian(address _guardian) internal {\n if (!isAdditionPending(_guardian))\n revert GuardianFacet__InvalidGuardianAddition();\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n if (config.info[_guardian].exists)\n revert GuardianFacet__AlreadyExists();\n\n config.info[_guardian].exists = true;\n config.info[_guardian].index = uint128(config.addresses.length);\n config.addresses.push(_guardian);\n }\n\n /**\n * @notice Removes guardian to storage config. This is called when guardian is fully removed.\n * @dev This method remove guardian address and config information to Facet Storage dedicated for guardian\n * When this function is called, guardian is fully removed from this Barz Smart Account\n * @param _guardian Address of guardian to be removed\n */\n function _removeGuardian(address _guardian) internal {\n if (!isRemovalPending(_guardian))\n revert GuardianFacet__InvalidGuardianRemoval();\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n if (!config.info[_guardian].exists)\n revert GuardianFacet__NonExistentGuardian();\n\n address lastAddress = config.addresses[config.addresses.length - 1];\n if (_guardian != lastAddress) {\n uint128 targetIndex = config.info[_guardian].index;\n config.addresses[targetIndex] = lastAddress;\n config.info[lastAddress].index = targetIndex;\n }\n config.addresses.pop();\n delete config.info[_guardian];\n\n emit GuardianRemoved(_guardian);\n }\n\n /**\n * @notice Reads guardian storage and fetches the addresses into an array from the storage\n * @dev This method fetches the guardian storage and returns the list of guardian addresses\n * @return addresses Array of addresses comprised of guardian\n */\n function getGuardians()\n public\n view\n override\n returns (address[] memory addresses)\n {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n addresses = new address[](config.addresses.length);\n uint256 addressesLen = config.addresses.length;\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the number of majority of guardians\n * @return majorityOfGuardians_ Number of majority of guardians e.g., 2 if 3 guardians / 3 if 5 guardians\n */\n function majorityOfGuardians()\n public\n view\n override\n returns (uint256 majorityOfGuardians_)\n {\n majorityOfGuardians_ = LibGuardian.majorityOfGuardians();\n }\n\n /**\n * @notice Reads guardian storage and fetches the addresses into an array from the storage\n * @dev This method fetches the guardian storage and returns the list of guardian addresses\n * @return guardianNumber Array of guardians in the account\n */\n function guardianCount()\n public\n view\n override\n returns (uint256 guardianNumber)\n {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n guardianNumber = config.addresses.length;\n }\n\n /**\n * @notice Reads guardian storage and checks if the given address is a guardian\n * @return isGuardian_ Bool value representing if the given address is guardian\n */\n function isGuardian(\n address _guardian\n ) public view override returns (bool isGuardian_) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n isGuardian_ = config.info[_guardian].exists;\n }\n\n /**\n * @notice Checks if the guardian number is zero and returns of guardian facet is okay to be removed\n * @return isRemovable Bool value representing if guardian facet is removable\n */\n function isGuardianFacetRemovable()\n external\n view\n override\n returns (bool isRemovable)\n {\n isRemovable = (0 == guardianCount());\n }\n}\n" + }, + "contracts/facets/interfaces/IAccountFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IEntryPoint} from \"../../aa-4337/interfaces/IEntryPoint.sol\";\n\n/**\n * @title Account Facet Interface\n * @dev Interface of module contract that provides the account features and init/unitialization of signer\n * compatible with EIP-1271 & EIP-4337\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IAccountFacet {\n event AccountInitialized(\n IEntryPoint indexed entryPoint,\n bytes indexed ownerPublicKey\n );\n // NOTE: Added Below Event\n event VerificationSuccess(bytes32);\n event VerificationFailure(bytes32);\n\n error AccountFacet__InitializationFailure();\n error AccountFacet__RestrictionsFailure();\n error AccountFacet__NonExistentVerificationFacet();\n error AccountFacet__CallNotSuccessful();\n\n function initialize(\n address verificationFacet,\n address anEntryPoint,\n address facetRegistry,\n address _defaultFallBack,\n bytes calldata _ownerPublicKey\n ) external returns (uint256);\n\n function execute(address dest, uint256 value, bytes calldata func) external;\n\n function executeBatch(\n address[] calldata dest,\n uint256[] calldata value,\n bytes[] calldata func\n ) external;\n}\n" + }, + "contracts/facets/interfaces/IAccountRecoveryFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {RecoveryConfig} from \"../../libraries/LibFacetStorage.sol\";\n\n/**\n * @title Account Recovery Facet Interface\n * @dev Interface of contract that enables recovery of accounts when owner key is unavailable\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IAccountRecoveryFacet {\n event RecoveryExecuted(\n bytes indexed recoveryPublicKey,\n uint64 executeAfter\n );\n event RecoveryFinalized(bytes indexed recoveryPublicKey);\n event RecoveryCanceled(bytes indexed recoveryPublicKey);\n event RecoveryApproved(\n bytes indexed recoveryPublicKey,\n address indexed guardian,\n uint64 validUntil\n );\n event RecoveryApprovalRevoked(\n bytes indexed recoveryPublicKey,\n address indexed guardian\n );\n event RecoveryCancellationApproved(\n bytes indexed recoveryPublicKey,\n address indexed guardian\n );\n event RecoveryHardstopped();\n\n error AccountRecoveryFacet__CallerNotGuardian();\n error AccountRecoveryFacet__InvalidRecoveryPublicKey();\n error AccountRecoveryFacet__SignerInitializationFailure();\n error AccountRecoveryFacet__SignerUninitializationFailure();\n error AccountRecoveryFacet__InvalidArrayLength();\n error AccountRecoveryFacet__InsufficientGuardians();\n error AccountRecoveryFacet__RecoveryAlreadyOngoing();\n error AccountRecoveryFacet__NonexistentRecovery();\n error AccountRecoveryFacet__NonExistentApproval();\n error AccountRecoveryFacet__RecoveryPeriodNotOver();\n error AccountRecoveryFacet__InvalidLockPeriod();\n error AccountRecoveryFacet__InvalidRecoveryPeriod();\n error AccountRecoveryFacet__InvalidApprovalValidationPeriod();\n error AccountRecoveryFacet__InvalidGuardian();\n error AccountRecoveryFacet__InvalidGuardianSignature();\n error AccountRecoveryFacet__InvalidOwnerSignature();\n error AccountRecoveryFacet__CallNotSuccesful();\n error AccountRecoveryFacet__DuplicateApproval();\n\n function approveAccountRecovery(bytes calldata recoveryPublicKey) external;\n\n function revokeAccountRecoveryApproval(\n bytes calldata recoveryPublicKey\n ) external;\n\n function executeRecovery(\n bytes calldata recoveryPublicKey,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function finalizeRecovery() external;\n\n function approveCancelRecovery(bytes calldata recoveryPublicKey) external;\n\n function cancelRecovery(\n bytes calldata recoveryPublicKey,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function hardstopRecovery(bytes calldata signature) external;\n\n function getApprovalRecoveryKeyHash(\n bytes memory recoveryPublicKey,\n string memory saltString\n ) external view returns (bytes32);\n\n function getRecoveryApprovalCountWithTimeValidity(\n bytes32 recoveryPublicKeyHash\n ) external view returns (uint256);\n\n function isRecoveryApproved(\n bytes32 recoveryPublicKeyHash,\n address approver\n ) external view returns (bool);\n\n function getRecoveryNonce() external view returns (uint128);\n\n function getPendingRecovery() external view returns (RecoveryConfig memory);\n}\n" + }, + "contracts/facets/interfaces/IGuardianFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Guardian Facet Interface\n * @dev Interface of guaridna contract that enables addition/removal of guardians from Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IGuardianFacet {\n event GuardianAdditionRequested(\n address indexed guardian,\n uint256 executeAfter\n );\n event GuardianRemovalRequested(\n address indexed guardian,\n uint256 executeAfter\n );\n event GuardianAdditionCancelled(address indexed guardian);\n event GuardianRemovalCancelled(address indexed guardian);\n event GuardianAdded(address indexed guardian);\n event GuardianRemoved(address indexed guardian);\n\n error GuardianFacet__GuardianCannotBeSelf();\n error GuardianFacet__DuplicateGuardian();\n error GuardianFacet__OwnerCannotBeGuardian();\n error GuardianFacet__DuplicateGuardianAddition();\n error GuardianFacet__DuplicateGuardianRemoval();\n error GuardianFacet__UnknownPendingAddition();\n error GuardianFacet__PendingAdditionNotOver();\n error GuardianFacet__UnknownPendingRemoval();\n error GuardianFacet__PendingRemovalNotOver();\n error GuardianFacet__PendingAdditionExpired();\n error GuardianFacet__InvalidAdditionSecurityPeriod();\n error GuardianFacet__InvalidRemovalSecurityPeriod();\n error GuardianFacet__InvalidSecurityWindow();\n error GuardianFacet__NonExistentGuardian();\n error GuardianFacet__AlreadyExists();\n error GuardianFacet__InvalidGuardianAddition();\n error GuardianFacet__InvalidGuardianRemoval();\n error GuardianFacet__ZeroAddressGuardian();\n\n function addGuardian(address guardian) external;\n\n function addGuardians(address[] calldata guardians) external;\n\n function removeGuardian(address guardian) external;\n\n function removeGuardians(address[] calldata guardians) external;\n\n function confirmGuardianAddition(address guardian) external;\n\n function confirmGuardianAdditions(address[] calldata guardian) external;\n\n function confirmGuardianRemoval(address guardian) external;\n\n function confirmGuardianRemovals(address[] calldata guardian) external;\n\n function cancelGuardianAddition(address guardian) external;\n\n function cancelGuardianRemoval(address guardian) external;\n\n function isGuardian(address guardian) external view returns (bool);\n\n function isAdditionPending(address guardian) external view returns (bool);\n\n function isRemovalPending(address guardian) external view returns (bool);\n\n function isGuardianFacetRemovable() external view returns (bool);\n\n function getAdditionSecurityPeriod() external view returns (uint256);\n\n function getRemovalSecurityPeriod() external view returns (uint256);\n\n function getSecurityWindow() external view returns (uint256);\n\n function getGuardians() external view returns (address[] memory);\n\n function majorityOfGuardians() external view returns (uint256);\n\n function guardianCount() external view returns (uint256);\n}\n" + }, + "contracts/facets/interfaces/ILockFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Lock} from \"../../libraries/LibAppStorage.sol\";\n\n/**\n * @title Lock Facet Interface\n * @dev Interface of Lock contract that enables full lock/unlock of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface ILockFacet {\n event Locked(uint64 releaseAfter);\n event Unlocked();\n\n error LockFacet__InvalidRecoveryPeriod();\n error LockFacet__CannotUnlock();\n error LockFacet__InvalidSignature();\n error LockFacet__InvalidApprover();\n\n function lock() external;\n\n function unlock(address approver, bytes calldata signature) external;\n\n function getLockPeriod() external view returns (uint256);\n\n function isLocked() external view returns (bool);\n\n function getUnlockHash() external view returns (bytes32);\n\n function lockNonce() external view returns (uint128);\n\n function getPendingLock() external view returns (Lock memory);\n}\n" + }, + "contracts/facets/interfaces/IMultiSigFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Multi-sig facet Interface\n * @dev Interface of Multi-signature Facet with custom threshold.\n Wallet that adds this facet becomes a multi-sig wallet\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IMultiSigFacet {\n event ThresholdChanged(uint256 threshold);\n event OwnerAdded(address indexed newOwner);\n event OwnerRemoved(address indexed prevOwner);\n event HashApproved(bytes32 hashToApprove, address indexed owner);\n\n error MultiSigFacet__InvalidThreshold();\n error MultisigFacet__InvalidOwnerCount();\n error MultiSigFacet__InvalidRoute();\n error MultiSigFacet__InsufficientSignerLength();\n error MultiSigFacet__InvalidInitData();\n error MultiSigFacet__InvalidOwnerAddress();\n error MultiSigFacet__InvalidOwnerPair();\n error MultiSigFacet__InvalidSignatureLength();\n error MultiSigFacet__InvalidSignatureType();\n error MultiSigFacet__DuplicateOwner();\n error MultiSigFacet__OnlyOwner();\n\n function checkSignatures(\n bytes32 _dataHash,\n bytes calldata _signatures,\n uint256 _threshold\n ) external view returns (uint256);\n\n function splitSignatures(\n bytes calldata _signatures,\n uint256 _nextOffset\n )\n external\n pure\n returns (\n address owner,\n bytes memory signature,\n uint256 signatureType,\n uint256 nextOffset\n );\n\n function approveHash(bytes32 hashToApprove) external;\n\n function addOwner(address newOwner, uint256 threshold) external;\n\n function removeOwner(\n address prevOwner,\n address removedOwner,\n uint256 threshold\n ) external;\n\n function swapOwner(\n address prevOwner,\n address oldOwner,\n address newOwner\n ) external;\n\n function changeThreshold(uint256 _threshold) external;\n\n function isOwner(address owner) external view returns (bool);\n\n function getThreshold() external view returns (uint256);\n\n function getOwners() external view returns (address[] memory);\n}\n" + }, + "contracts/facets/interfaces/IRestrictionsFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Restrictions Facet Interface\n * @dev Interface of Restrictions contract that enables modular restrictions in Barz\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IRestrictionsFacet {\n event RestrictionAdded(address indexed restriction);\n event RestrictionRemoved(address indexed restriction);\n\n error RestrictionsFacet__EmptyRestrictionsList();\n error RestrictionsFacet__RestrictionNotFound();\n error RestrictionsFacet__RestrictionAlreadyExists();\n error RestrictionsFacet__ZeroAddressRestrictions();\n error RestrictionsFacet__ZeroAddressRestrictionsFacet();\n error RestrictionsFacet__RemainingRestrictionsCantBeEmpty();\n\n function initializeRestrictions(\n address[] memory _restrictions\n ) external returns (uint256);\n\n function uninitializeRestrictions() external returns (uint256);\n\n function getRestrictions() external view returns (address[] memory);\n\n function addRestriction(address restriction) external;\n\n function removeRestriction(address restriction) external;\n\n function verifyRestrictions(\n address from,\n address to,\n uint256 value,\n bytes calldata _calldata\n ) external returns (uint256);\n}\n" + }, + "contracts/facets/interfaces/ISignatureMigrationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureMigrationConfig} from \"../../libraries/LibFacetStorage.sol\";\n\n/**\n * @title Signature Migration Facet Interface\n * @dev Interface of Signature Migration contract for migrating user signature scheme to a new scheme user sets\n * Which could include\n * - ECDSA on Secp256K1 Curve\n * - ECDSA on Secp256R1 Curve\n * - BLS, Schnorr, etc\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface ISignatureMigrationFacet {\n event SignatureSchemeMigration(\n address indexed prevVerificationFacet,\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n event SignatureMigrationApproved(\n bytes newPublicKey,\n address indexed newVerificationFacet,\n bytes4[] verificationFuncSelectors,\n address indexed guardian,\n uint128 approvalValidUntil\n );\n event SignatureMigrationApprovalRevoked(\n bytes newPublicKey,\n address indexed newVerificationFacet,\n bytes4[] verificationFuncSelectors,\n address indexed guardian\n );\n event SignatureMigrationExecuted(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors,\n uint128 migrateAfter\n );\n event SignatureMigrationCanceled(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n event SignatureMigrationCancellationApproved(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n\n error SignatureMigrationFacet__SignerUninitializationFailure();\n error SignatureMigrationFacet__InvalidRouteWithGuardian();\n error SignatureMigrationFacet__InvalidKeyType();\n error SignatureMigrationFacet__InsufficientApprovers();\n error SignatureMigrationFacet__InvalidApproverSignature();\n error SignatureMigrationFacet__InvalidGuardian();\n error SignatureMigrationFacet__NonExistentApprover();\n error SignatureMigrationFacet__InvalidMigrationPeriod();\n error SignatureMigrationFacet__NonexistentMigration();\n error SignatureMigrationFacet__MigrationPeriodNotOver();\n error SignatureMigrationFacet__InvalidArrayLength();\n error SignatureMigrationFacet__InvalidApprovalValidationPeriod();\n error SignatureMigrationFacet__CannotRevokeUnapproved();\n error SignatureMigrationFacet__LackOfOwnerApproval();\n error SignatureMigrationFacet__OwnerAlreadyApproved();\n error SignatureMigrationFacet__NonExistentVerificationFacet();\n error SignatureMigrationFacet__DuplicateApproval();\n\n function migrateSignatureScheme(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function migrateSignatureSchemeWithGuardian(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors,\n address[] calldata approvers,\n bytes[] calldata signatures\n ) external;\n\n function approveSignatureSchemeMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function revokeSignatureMigrationApproval(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function finalizeSignatureMigration() external;\n\n function approveCancelSignatureMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function cancelSignatureMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function getApprovalMigrationKeyHash(\n bytes memory recoveryPublicKey,\n address newVerificationFacet,\n bytes4[] memory newVerificationFuncSelectors,\n string memory saltString\n ) external view returns (bytes32);\n\n function getMigrationOwnerApprovalWithTimeValidity(\n bytes32 publicKeyHash\n ) external view returns (bool);\n\n function getMigrationApprovalCountWithTimeValidity(\n bytes32 publicKeyHash\n ) external view returns (uint256);\n\n function isMigrationApproved(\n bytes32 migrationPublicKeyHash,\n address approver\n ) external view returns (bool);\n\n function getMigrationNonce() external view returns (uint128);\n\n function isMigrationPending() external view returns (bool);\n\n function getPendingMigration()\n external\n view\n returns (SignatureMigrationConfig memory);\n}\n" + }, + "contracts/facets/interfaces/IVerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {UserOperation} from \"../../aa-4337/interfaces/UserOperation.sol\";\n\n/**\n * @title Verification Facet Interface\n * @dev Implements logic for user ops signature verification\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface IVerificationFacet {\n event SignerInitialized(bytes);\n event SignerUninitialized();\n\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n error VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n error VerificationFacet__InitializationFailure();\n error VerificationFacet__InvalidFacetMapping();\n\n function initializeSigner(bytes memory) external returns (uint256);\n\n function uninitializeSigner() external returns (uint256);\n\n function validateOwnerSignatureSelector() external view returns (bytes4);\n\n function owner() external view returns (bytes memory);\n\n function isValidKeyType(bytes calldata) external view returns (bool);\n\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) external view returns (uint256);\n}\n" + }, + "contracts/facets/LockFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage, Lock} from \"../libraries/LibAppStorage.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibFacetStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {ILockFacet} from \"./interfaces/ILockFacet.sol\";\n\n/**\n * @title Lock Facet\n * @dev Contract that enables full lock/unlock of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract LockFacet is ILockFacet, Modifiers {\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Locks the account for the lock period. Lock period is defined in the security manager and it's customizable\n * This function can only be called when account is unlocked by owner or guardians\n * @dev This method checks the caller and if the account is currently locked and locks the account after fetching the\n * Lock period from the owner.\n */\n function lock() external override onlyGuardianOrOwner onlyWhenUnlocked {\n uint256 unlockTime = block.timestamp + getLockPeriod();\n ++LibFacetStorage.lockStorage().nonce;\n LibAppStorage.setLock(unlockTime, LockFacet.lock.selector);\n emit Locked(uint64(unlockTime));\n }\n\n /**\n * @notice Locks the account when the account is locked. This function can be called by anyone but must provide the approver address and signature.\n * The approver should be one of the guardians or owner.\n * @dev This method takes the approver address and the signature. After validating the address and the signature, it unlocks the account immediately.\n * Only one of the guardian or owner is required to lock and unlock the account.\n * @param _approver Address of approver approving the unlock of Barz account\n * @param _signature Signature of the approver that signed the msg hash for unlocking the account\n */\n function unlock(\n address _approver,\n bytes calldata _signature\n ) external override onlyWhenLocked {\n if (_approver != address(this) && !LibGuardian.isGuardian(_approver))\n revert LockFacet__InvalidApprover();\n if (\n !SignatureChecker.isValidSignatureNow(\n _approver,\n getUnlockHash(),\n _signature\n )\n ) revert LockFacet__InvalidSignature();\n _unlock();\n }\n\n /**\n * @notice Unlocks the account and increments the lock nonce\n */\n function _unlock() private {\n if (s.locks[INNER_STRUCT].locker != LockFacet.lock.selector)\n revert LockFacet__CannotUnlock();\n ++LibFacetStorage.lockStorage().nonce;\n LibAppStorage.setLock(0, bytes4(0));\n emit Unlocked();\n }\n\n /**\n * @notice Returns the lock period of current Barz account. Lock period information is held by Security Manager\n * @return lockPeriod Uint value of lock period in seconds\n */\n function getLockPeriod() public view override returns (uint256 lockPeriod) {\n lockPeriod = securityManager.lockPeriodOf(address(this));\n if (lockPeriod == 0) revert LockFacet__InvalidRecoveryPeriod();\n }\n\n /**\n * @notice Returns if the account is locked or not\n * @dev This method fetches the current block timestamp and compares that with release time.\n * After checking the timestamp and release time, it returns if the account is still locked or not.\n * @return isLocked_ Uint value of lock period in seconds\n */\n function isLocked() public view override returns (bool isLocked_) {\n isLocked_ = uint64(block.timestamp) < s.locks[INNER_STRUCT].release;\n }\n\n /**\n * @notice Calculates the unlock hash and returns the unlock hash safe from signature reply attack\n * @dev This method calculates the unlock hash with EIP-191 prefix, wallet address, chainID, and nonce\n * It packs the result and packs them and hashes it.\n * @return unlockHash Bytes32 unlock hash\n */\n function getUnlockHash() public view override returns (bytes32 unlockHash) {\n unlockHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n \"Unlock\",\n address(this),\n block.chainid,\n lockNonce()\n )\n )\n )\n );\n }\n\n /**\n * @notice Returns lock nonce of account. Reads nonce from lock storage within facet storage\n * @return lockNonce_ Uint128 value of lock nonce. This is incremented whenever the account is lock/unlocked\n */\n function lockNonce() public view override returns (uint128 lockNonce_) {\n lockNonce_ = LibFacetStorage.lockStorage().nonce;\n }\n\n /**\n * @notice Returns the overall information of current lock\n * @return pendingLock Struct value including all information of pending lock\n */\n function getPendingLock()\n public\n view\n override\n returns (Lock memory pendingLock)\n {\n pendingLock = s.locks[INNER_STRUCT];\n }\n}\n" + }, + "contracts/facets/Modifiers.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {IFacetRegistry} from \"../infrastructure/interfaces/IFacetRegistry.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\n\n/**\n * @title Modifiers\n * @dev Responsible for providing modifiers/util functions to Facet contracts\n * @author David Yongjun Kim (@Powerstream3604)\n */\nabstract contract Modifiers is BarzStorage {\n uint8 constant INNER_STRUCT = 0;\n\n error CallerNotGuardian();\n error CallerNotGuardianOrOwner();\n error DuplicateApprover();\n error ZeroApproverLength();\n error UnregisteredFacetAndSelectors();\n\n /**\n * @notice Modifier to only allow guardian to make a call, reverts if any other entity is the caller\n */\n modifier onlyGuardian() {\n if (!LibGuardian.isGuardian(msg.sender)) revert CallerNotGuardian();\n _;\n }\n\n /**\n * @notice Modifier to only allow guardian or owner to make a call, reverts if any other entity is the caller\n */\n modifier onlyGuardianOrOwner() {\n if (!LibGuardian.isGuardian(msg.sender) && address(this) != msg.sender)\n revert CallerNotGuardianOrOwner();\n _;\n }\n\n /**\n * @notice Checks if the approver address is the array is unique with no duplicate\n * @dev This method loops through the array and checks if a duplicate address exists, it reverts if duplicate address exists\n * @param approvers Array of address\n */\n function _checkApprover(\n address[] memory approvers\n ) internal pure returns (bool) {\n uint256 approverLength = approvers.length;\n if (0 == approverLength) revert ZeroApproverLength();\n for (uint256 i; i < approverLength - 1; ) {\n for (uint256 j = i + 1; j < approverLength; ) {\n if (approvers[i] == approvers[j]) {\n revert DuplicateApprover(); // Found a duplicate\n }\n unchecked {\n ++j;\n }\n }\n unchecked {\n ++i;\n }\n }\n return false; // No duplicates found\n }\n\n /**\n * @notice Checks if the facet getting added or replaced is registered to facet registry\n * @dev This method loops through the cut and checks if the facet getting added/replaced is registered to facet registry\n * @param _diamondCut Array of FacetCut, data for diamondCut defined in EIP-2535\n */\n function _checkFacetCutValidity(\n IDiamondCut.FacetCut[] memory _diamondCut\n ) internal view {\n uint256 diamondCutLength = _diamondCut.length;\n for (uint256 i; i < diamondCutLength; ) {\n if (\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Add ||\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Replace\n ) {\n if (\n !s.facetRegistry.areFacetFunctionSelectorsRegistered(\n _diamondCut[i].facetAddress,\n _diamondCut[i].functionSelectors\n )\n ) revert UnregisteredFacetAndSelectors();\n }\n unchecked {\n ++i;\n }\n }\n }\n}\n" + }, + "contracts/facets/RestrictionsFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, RestrictionsStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {IRestriction} from \"../restrictions/IRestriction.sol\";\nimport {IRestrictionsFacet} from \"./interfaces/IRestrictionsFacet.sol\";\n\n/**\n * @title Restrictions facet\n * @dev Responsible for storing and verifying different kinds of restrictions, for example:\n * - Whitelist / Blacklist\n * - Daily limits\n * - Trading time restrictions\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract RestrictionsFacet is IRestrictionsFacet {\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceRestrictionsInitialize();\n }\n\n /**\n * @notice Intialize restrictions of Barz. Restrictions facet call restriction contracts for restriction validation\n * before each call\n * @param _restrictions The initial array of restrictions.\n * @return initSuccess Int value showing if the initialization of restriction is successful\n */\n function initializeRestrictions(\n address[] calldata _restrictions\n ) public override returns (uint256 initSuccess) {\n LibDiamond.enforceIsSelf();\n LibAppStorage.enforceRestrictionsInitialize();\n\n if (_restrictions.length == 0) {\n // You can't initialize RestrictionsFacet with an empty list of restrictions\n revert RestrictionsFacet__EmptyRestrictionsList();\n }\n for (uint256 i; i < _restrictions.length; ) {\n if (_restrictions[i] == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictions();\n unchecked {\n ++i;\n }\n }\n\n LibFacetStorage.restrictionsStorage().restrictions = _restrictions;\n _updateRestrictionsMap(_restrictions, true);\n initSuccess = 1;\n }\n\n /**\n * @notice Unitialize restrictions of Barz\n * @return uninitSuccess Int value showing if the initialization of restriction is successful\n */\n function uninitializeRestrictions()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibDiamond.enforceIsSelf();\n LibAppStorage.setRestrictionsUninitialized();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n _updateRestrictionsMap(restrictionsStorage.restrictions, false);\n restrictionsStorage.restrictions = new address[](0);\n uninitSuccess = 1;\n }\n\n /**\n * @notice Returns the list of Restrictions contract address\n * @return restrictions Addresses of IRestriction which are currently active\n */\n function getRestrictions()\n public\n view\n override\n returns (address[] memory restrictions)\n {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n restrictions = restrictionsStorage.restrictions;\n }\n\n /**\n * @notice Adds restrictions to Barz with validation on the restriction contract address.\n * This method is only callable by the owner(self).\n * @param _restriction The address of the restriction to be added.\n */\n function addRestriction(address _restriction) external override {\n LibDiamond.enforceIsSelf();\n if (LibDiamond.restrictionsFacet() == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictionsFacet();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n if (_restriction == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictions();\n if (restrictionsStorage.exists[_restriction])\n revert RestrictionsFacet__RestrictionAlreadyExists();\n\n restrictionsStorage.restrictions.push(_restriction);\n restrictionsStorage.exists[_restriction] = true;\n\n emit RestrictionAdded(_restriction);\n }\n\n /**\n * @notice Remove restrictions from Barz if it existed. This method is only callable by the owner(self).\n * @param _restriction The address of the restriction to be removed.\n */\n function removeRestriction(address _restriction) external override {\n LibDiamond.enforceIsSelf();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n if (!restrictionsStorage.exists[_restriction])\n revert RestrictionsFacet__RestrictionNotFound();\n\n address[] storage restrictions = restrictionsStorage.restrictions;\n\n uint256 indexToDelete = restrictions.length;\n uint256 restrictionsLen = restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n if (restrictions[i] == _restriction) {\n indexToDelete = i;\n break;\n }\n unchecked {\n ++i;\n }\n }\n\n if (indexToDelete == 0 && restrictionsLen == 1) {\n revert RestrictionsFacet__RemainingRestrictionsCantBeEmpty();\n } else if (indexToDelete == restrictionsLen) {\n revert RestrictionsFacet__RestrictionNotFound();\n } else {\n restrictions[indexToDelete] = restrictions[restrictionsLen - 1];\n restrictions.pop();\n }\n\n restrictionsStorage.exists[_restriction] = false;\n emit RestrictionRemoved(_restriction);\n }\n\n /**\n * @notice Sets the restrictions address value mapping to true or false when adding/removing restriction contracts\n * @param _restrictions List of restriction contracts address\n * @param _newValue Bool value to flag to the list of restrictions contracts\n */\n function _updateRestrictionsMap(\n address[] memory _restrictions,\n bool _newValue\n ) internal {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n uint restrictionsLen = _restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n restrictionsStorage.exists[_restrictions[i]] = _newValue;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @dev Iterates over all restrictions and verifies each of them with the transaction parameters.\n * @param _from The address of the sender, that will be signing the transaction.\n * @param _to The receiving address.\n * @param _value Amount of ETH to transfer from sender to recipient.\n * @param _calldata Optional field to include arbitrary data.\n * @return 0 if all the checks passed, 1 otherwise.\n */\n function verifyRestrictions(\n address _from,\n address _to,\n uint256 _value,\n bytes calldata _calldata\n ) external returns (uint256) {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n uint restrictionsLen = restrictionsStorage.restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n IRestriction restriction = IRestriction(\n restrictionsStorage.restrictions[i]\n );\n bool checkPassed = restriction.check(_from, _to, _value, _calldata);\n if (!checkPassed) {\n return 1;\n }\n unchecked {\n ++i;\n }\n }\n\n return 0;\n }\n}\n" + }, + "contracts/facets/SignatureMigrationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, SignatureMigrationStorage, SignatureMigrationConfig, SignatureMigrationApprovalConfig, ApprovalConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IDiamondCut} from \"./base/interfaces/IDiamondCut.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {ISignatureMigrationFacet} from \"./interfaces/ISignatureMigrationFacet.sol\";\n\n/**\n * @title Signature Migration Facet\n * @dev Responsible for migrating user signature scheme to a new scheme user sets\n * Which could include\n * - ECDSA on Secp256K1 Curve\n * - ECDSA on Secp256R1 Curve\n * - BLS, Schnorr, etc\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract SignatureMigrationFacet is ISignatureMigrationFacet, Modifiers {\n bytes constant UNINIT_CALL =\n abi.encodeWithSignature(\"uninitializeSigner()\");\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This modifier verifies if the public key format matches with the new verification facet\n * @param _publicKey Bytes of public key to be validated for the new verification facet\n * @param _newVerificationFacet Address of new verification facet\n */\n modifier validateKeyType(\n bytes memory _publicKey,\n address _newVerificationFacet\n ) {\n if (\n !IVerificationFacet(_newVerificationFacet).isValidKeyType(\n _publicKey\n )\n ) revert SignatureMigrationFacet__InvalidKeyType();\n _;\n }\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n // IMPORTANT NOTE: In the client side when they call this function, the func selectors should be sorted in ascending order\n // to prevent different hash with same items in the array\n /**\n * @notice Moves the state of migration to a pending state. When pending state is over after pending period time,\n * Migration can be finalized. This function can only be called by self and when the account is unlocked.\n * @dev This method checks if the caller is self and if guardians exists. It migrates signature request to a pending state\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function migrateSignatureScheme(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n public\n override\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n // Only self contract can call this function\n LibDiamond.enforceIsSelf();\n // Should revert if guardian exist\n if (0 != LibGuardian.guardianCount())\n revert SignatureMigrationFacet__InvalidRouteWithGuardian();\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n // NOTE: Migration requires a pending period & confirmation from owner to prevent a\n // single call changing the ownership of the wallet\n /**\n * @notice Migrate signature scheme when guardians exists. Verifies the signature of guardians and moves migration to pending state.\n * Which can then be finalized when pending period is over. Owner's approval is mandatory for migration to happen\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _approvers List of approvers. This could include owner\n */\n function migrateSignatureSchemeWithGuardian(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n )\n public\n override\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n // Should revert if does not guardian exist\n if (0 == LibGuardian.guardianCount())\n revert SignatureMigrationFacet__InvalidRouteWithGuardian();\n if (_approvers.length != _signatures.length)\n revert SignatureMigrationFacet__InvalidArrayLength();\n\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(migrationPublicKeyHash, _approvers);\n\n bool onChainOwnerApproval = getMigrationOwnerApprovalWithTimeValidity(\n migrationPublicKeyHash\n );\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n\n if (\n _approvers.length +\n getMigrationApprovalCountWithTimeValidity(\n migrationPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert SignatureMigrationFacet__InsufficientApprovers();\n {\n // To prevent Stack too deep\n bool ownerApproved;\n for (uint256 i; i < _approvers.length; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n address(this) != _approvers[i]\n ) revert SignatureMigrationFacet__InvalidGuardian();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert SignatureMigrationFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n migrationPublicKeyHash,\n _signatures[i]\n )\n ) revert SignatureMigrationFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n\n if (!ownerApproved && !onChainOwnerApproval)\n revert SignatureMigrationFacet__LackOfOwnerApproval();\n }\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Internal function that moves signature mgiration to a pending state.\n * @dev This method increments migration nonce and sets the migration in the migration config. Emits events for migration execution\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _migrateSignatureScheme(\n address _newVerificationFacet,\n bytes memory _newPublicKey,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal {\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n\n ++ms.nonce;\n uint64 migrateAfter = uint64(block.timestamp + getMigrationPeriod());\n\n ms.migrationConfigs[INNER_STRUCT] = SignatureMigrationConfig(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n migrateAfter\n );\n\n emit SignatureMigrationExecuted(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors,\n migrateAfter\n );\n }\n\n /**\n * @notice Approves signature scheme migration on-chain. This can be called by owner or guardian only when the account is unlocked.\n * When the threshold of the migration approval passed and owner approval is granted, it automatically moves migration to a pending state\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function approveSignatureSchemeMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n public\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit SignatureMigrationApproved(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n msg.sender,\n approvalValidUntil\n );\n if (\n getMigrationApprovalCountWithTimeValidity(migrationPublicKeyHash) >=\n LibGuardian.majorityOfGuardians() &&\n getMigrationOwnerApprovalWithTimeValidity(migrationPublicKeyHash)\n )\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Revokes the approval of signature migration done on-chain. Emits revoke event when revoked.\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function revokeSignatureMigrationApproval(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n external\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n if (!isMigrationApproved(migrationPublicKeyHash, msg.sender))\n revert SignatureMigrationFacet__CannotRevokeUnapproved();\n\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(false, 0);\n emit SignatureMigrationApprovalRevoked(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n msg.sender\n );\n }\n\n /**\n * @notice Finalizes the pending signature scheme migration. This function can only be called by owner.\n * It removes the facets of the previous verification facet and adds the new verification facet.\n * After finalizing migration, it emits migration event which shows the change of the verification facet\n */\n function finalizeSignatureMigration() external override {\n // NOTE: Only owner can call this function\n LibDiamond.enforceIsSelf();\n\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n\n if (!isMigrationPending())\n revert SignatureMigrationFacet__NonexistentMigration();\n\n if (\n uint64(block.timestamp) <=\n ms.migrationConfigs[INNER_STRUCT].migrateAfter\n ) revert SignatureMigrationFacet__MigrationPeriodNotOver();\n address newVerificationFacet = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationVerificationFacet;\n bytes4[] memory newVerificationFuncSelectors = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationSelectors;\n bytes memory newPublicKey = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationPublicKey;\n\n address prevVerificationFacet = LibLoupe.facetAddress(\n s.validateOwnerSignatureSelector\n );\n if (prevVerificationFacet == address(0))\n revert SignatureMigrationFacet__NonExistentVerificationFacet();\n\n IDiamondCut.FacetCut[] memory UninitCut;\n IDiamondCut.FacetCut[] memory InitCut;\n {\n bytes4[] memory prevVerificationFuncSelectors = LibLoupe\n .facetFunctionSelectors(prevVerificationFacet);\n\n UninitCut = new IDiamondCut.FacetCut[](1);\n InitCut = new IDiamondCut.FacetCut[](1);\n UninitCut[0] = IDiamondCut.FacetCut({\n facetAddress: address(0),\n action: IDiamondCut.FacetCutAction.Remove,\n functionSelectors: prevVerificationFuncSelectors\n });\n InitCut[0] = IDiamondCut.FacetCut({\n facetAddress: newVerificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: newVerificationFuncSelectors\n });\n {\n IDiamondCut.FacetCut[]\n memory facetCuts = new IDiamondCut.FacetCut[](2);\n facetCuts[0] = UninitCut[0];\n facetCuts[1] = InitCut[0];\n _checkFacetCutValidity(facetCuts);\n }\n LibAppStorage.initiateSignerMigration();\n address verificationFacet = address(\n bytes20(\n LibDiamond.diamondStorage().facets[\n s.validateOwnerSignatureSelector\n ]\n )\n );\n\n (bool success, bytes memory result) = verificationFacet\n .delegatecall(UNINIT_CALL);\n require(success, \"MigrationFacet: uninitialize not successful\");\n uint256 validationData = uint256(bytes32(result));\n if (validationData == 0)\n revert SignatureMigrationFacet__SignerUninitializationFailure();\n\n LibDiamond.diamondCut(UninitCut, address(0), \"\");\n }\n {\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n newPublicKey\n );\n\n // Every Verification Facet should comply with initializeSigner(bytes)\n // to be compatible with the Barz contract(for initialization)\n LibDiamond.diamondCut(InitCut, newVerificationFacet, initCall);\n LibAppStorage.finalizeSignerMigration();\n emit SignatureSchemeMigration(\n prevVerificationFacet,\n newVerificationFacet,\n newPublicKey,\n newVerificationFuncSelectors\n );\n }\n }\n\n /**\n * @notice Approve cancellation of signature migration. If cancellation approval passes guardian threshold with owner approval\n * it automatically cancels the migration.\n * @dev This method checks if the caller is one of guardian or owner and sets true for the cancellation hash in the approval config.\n * It internally calls _cancelSignatureMigration for canceling the migration\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function approveCancelSignatureMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n external\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"CancelSignatureMigration\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit SignatureMigrationCancellationApproved(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n if (\n getMigrationApprovalCountWithTimeValidity(migrationPublicKeyHash) >=\n LibGuardian.majorityOfGuardians() &&\n getMigrationOwnerApprovalWithTimeValidity(migrationPublicKeyHash)\n )\n _cancelSignatureMigration(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Verifies the signature of guardians/owner and cancels the signature migration.\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _approvers List of approvers. This could include owner\n */\n function cancelSignatureMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n )\n external\n override\n validateKeyType(_newPublicKey, _newVerificationFacet)\n onlyWhenUnlocked\n {\n if (_approvers.length != _signatures.length)\n revert SignatureMigrationFacet__InvalidArrayLength();\n\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"CancelSignatureMigration\"\n );\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(migrationPublicKeyHash, _approvers);\n\n bool onChainOwnerApproval = getMigrationOwnerApprovalWithTimeValidity(\n migrationPublicKeyHash\n );\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n if (\n _approvers.length +\n getMigrationApprovalCountWithTimeValidity(\n migrationPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert SignatureMigrationFacet__InsufficientApprovers();\n {\n // To prevent stack too deep\n bool ownerApproved;\n for (uint256 i; i < _approvers.length; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n address(this) != _approvers[i]\n ) revert SignatureMigrationFacet__NonExistentApprover();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert SignatureMigrationFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n migrationPublicKeyHash,\n _signatures[i]\n )\n ) revert SignatureMigrationFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n if (!ownerApproved && !onChainOwnerApproval)\n revert SignatureMigrationFacet__LackOfOwnerApproval();\n }\n _cancelSignatureMigration(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Internal function that cancels signature migration.\n * @dev This method increments migration nonce and deletes the migration from the migration config. Emits events for migration cancellation\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _cancelSignatureMigration(\n address _newVerificationFacet,\n bytes memory _newPublicKey,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal {\n if (!isMigrationPending())\n revert SignatureMigrationFacet__NonexistentMigration();\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n ++ms.nonce;\n delete ms.migrationConfigs[INNER_STRUCT];\n emit SignatureMigrationCanceled(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Checks if the facets to be added from new verification facet is registered to facet registry\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _checkMigrationCutValidity(\n address _newVerificationFacet,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal view {\n IDiamondCut.FacetCut[] memory facetCuts = new IDiamondCut.FacetCut[](1);\n facetCuts[0] = IDiamondCut.FacetCut({\n facetAddress: _newVerificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: _newVerificationFuncSelectors\n });\n _checkFacetCutValidity(facetCuts);\n }\n\n /**\n * @notice Returns if the migration is pending of not\n * @dev This method fetches the migration storage and checks if the migrate after is above 0 value\n * @return isPending Bool value that shows if the migration is pending\n */\n function isMigrationPending()\n public\n view\n override\n returns (bool isPending)\n {\n SignatureMigrationStorage storage rs = LibFacetStorage\n .migrationStorage();\n isPending = rs.migrationConfigs[INNER_STRUCT].migrateAfter > 0;\n }\n\n /**\n * @notice Returns the migration hash. This function ensures that this hash is safe from replay attack by including\n * public key, verification facet, function selectors, salt, address, chainId, and nonce.\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _saltString Salt value for generating the migration hash\n * @return migrationKeyHash Bytes32 string of the migration key hash\n */\n function getApprovalMigrationKeyHash(\n bytes memory _newPublicKey,\n address _newVerificationFacet,\n bytes4[] memory _newVerificationFuncSelectors,\n string memory _saltString\n ) public view override returns (bytes32 migrationKeyHash) {\n migrationKeyHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n _newPublicKey,\n _newVerificationFacet,\n keccak256(abi.encode(_newVerificationFuncSelectors)),\n _saltString,\n address(this),\n block.chainid,\n LibFacetStorage.migrationStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Checks if the owner approved the hash for migration\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @return isApprovedByOwner Bool value of showing if the owner approved it or not\n */\n function getMigrationOwnerApprovalWithTimeValidity(\n bytes32 _migrationPublicKeyHash\n ) public view override returns (bool isApprovedByOwner) {\n isApprovedByOwner = isMigrationApproved(\n _migrationPublicKeyHash,\n address(this)\n );\n }\n\n /**\n * @notice Checks how many of the guardians approved the migration hash\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @return approvalCount Number of approvals\n */\n function getMigrationApprovalCountWithTimeValidity(\n bytes32 _migrationPublicKeyHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardiansLength = guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n if (isMigrationApproved(_migrationPublicKeyHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n return approvalCount;\n }\n\n /**\n * @notice Checks if the migration is approved by the given approver\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @param _approver Address of approver\n * @return isApproved Bool value if migration hash is approved\n */\n function isMigrationApproved(\n bytes32 _migrationPublicKeyHash,\n address _approver\n ) public view override returns (bool isApproved) {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n isApproved = (ms\n .isMigrationApproved[_migrationPublicKeyHash][_approver].isApproved &&\n block.timestamp <\n ms\n .isMigrationApproved[_migrationPublicKeyHash][_approver]\n .validUntil);\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _migrationPublicKeyHash Hash of migration information\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _migrationPublicKeyHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isMigrationApproved(_migrationPublicKeyHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert SignatureMigrationFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the migration period of this wallet\n * @dev This method fetches the migration period from the security manager\n * @return migrationPeriod Migration period of Barz contract fetched from security manager\n */\n function getMigrationPeriod()\n internal\n view\n returns (uint128 migrationPeriod)\n {\n migrationPeriod = securityManager.migrationPeriodOf(address(this));\n if (migrationPeriod == 0)\n revert SignatureMigrationFacet__InvalidMigrationPeriod();\n }\n\n /**\n * @notice Returns the validation period of this wallet\n * @dev This method fetches the validation period from the security manager\n * @return approvalValidationPeriod Validation period of Barz contract fetched from security manager\n */\n function getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod == 0)\n revert SignatureMigrationFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the migration nonce of this wallet\n * @dev This method fetches the nonce from migration storage\n * @return migrationNonce Nonce of migration to protect from reply attacks\n */\n function getMigrationNonce()\n public\n view\n override\n returns (uint128 migrationNonce)\n {\n migrationNonce = LibFacetStorage.migrationStorage().nonce;\n }\n\n /**\n * @notice Returns the migration configuration of this wallet\n * @dev This method fetches the migration config from the migration storage\n * @return pendingMigrationConfig Migration config currently pending for signature migration\n */\n function getPendingMigration()\n external\n view\n override\n returns (SignatureMigrationConfig memory pendingMigrationConfig)\n {\n pendingMigrationConfig = LibFacetStorage\n .migrationStorage()\n .migrationConfigs[INNER_STRUCT];\n }\n}\n" + }, + "contracts/facets/TokenReceiverFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {IERC1155Receiver} from \"../interfaces/ERC/IERC1155Receiver.sol\";\nimport {IERC677Receiver} from \"../interfaces/ERC/IERC677Receiver.sol\";\n\n/**\n * @title TokenReceiver Facet\n * @dev Contract that enables receiving ERC721/ERC1155/ERC777/ERC677 Tokens with safe transfer\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract TokenReceiverFacet is\n IERC721Receiver,\n IERC1155Receiver,\n IERC777Recipient,\n IERC677Receiver\n{\n /**\n * @notice Handles ERC721 Token callback.\n * return Standardized onERC721Received return value.\n */\n function onERC721Received(\n address,\n address,\n uint256,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC721Receiver.onERC721Received.selector;\n }\n\n /**\n * @notice Handles ERC1155 Token callback.\n * return Standardized onERC1155Received return value.\n */\n function onERC1155Received(\n address,\n address,\n uint256,\n uint256,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC1155Receiver.onERC1155Received.selector;\n }\n\n /**\n * @notice Handles ERC1155 Token batch callback.\n * return Standardized onERC1155BatchReceived return value.\n */\n function onERC1155BatchReceived(\n address,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC1155Receiver.onERC1155BatchReceived.selector;\n }\n\n /**\n * @notice Handles ERC777 Token callback.\n * Does not return value, empty implementation.\n */\n function tokensReceived(\n address,\n address,\n address,\n uint256,\n bytes calldata,\n bytes calldata\n ) external pure override {}\n\n /**\n * @notice Handles ERC677 Token callback.\n * return true.\n */\n function onTokenTransfer(\n address,\n uint256,\n bytes calldata\n ) external pure override returns (bool) {\n return true;\n }\n}\n" + }, + "contracts/facets/verification/MultiSigFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {UserOperation} from \"../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../../libraries/LibLoupe.sol\";\nimport {LibAppStorage} from \"../../libraries/LibAppStorage.sol\";\nimport {LibMultiSigStorage, MultiSigStorage} from \"../../libraries/LibMultiSigStorage.sol\";\nimport {IERC1271} from \"../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../interfaces/IVerificationFacet.sol\";\nimport {IMultiSigFacet} from \"../interfaces/IMultiSigFacet.sol\";\n\n/**\n * @title Multi-sig facet\n * @dev Multi-signature Facet with custom threshold.\n * Wallet that adds this facet becomes a multi-sig wallet.\n * Reference signature_format.md documentation for Multi-sig facet details\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract MultiSigFacet is IMultiSigFacet, IVerificationFacet, IERC1271 {\n using ECDSA for bytes32;\n\n address public immutable self;\n\n address internal constant SENTINEL_OWNERS = address(0x1);\n uint256 internal constant ADDRESS = 20;\n uint256 internal constant SIG_TYPE = 1;\n uint256 internal constant SIG_LEN = 4;\n uint256 internal constant THRESHOLD = 4;\n uint256 internal constant INVALID_SIG = 1;\n uint256 internal constant VALID_SIG = 0;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in Multisig Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the right format and initializes signer storage in k1 storage.\n * @param _owners Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _owners\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n\n if (!isValidKeyType(_owners)) revert MultiSigFacet__InvalidInitData();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n uint256 threshold = uint256(uint32(bytes4(_owners)));\n uint256 ownerCount = (_owners.length - THRESHOLD) / ADDRESS;\n\n if (threshold == 0) revert MultiSigFacet__InvalidThreshold();\n if (ownerCount == 0) revert MultisigFacet__InvalidOwnerCount();\n\n address currentOwner = SENTINEL_OWNERS;\n uint256 ptr = THRESHOLD;\n address owner_;\n for (uint256 i; i < ownerCount; ) {\n owner_ = address(bytes20(_owners[ptr:ptr + ADDRESS]));\n ptr += ADDRESS;\n if (\n owner_ == address(0) ||\n owner_ == SENTINEL_OWNERS ||\n owner_ == address(this) ||\n owner_ == currentOwner\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[owner_] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n\n ms.owners[currentOwner] = owner_;\n currentOwner = owner_;\n\n unchecked {\n ++i;\n }\n }\n ms.owners[currentOwner] = SENTINEL_OWNERS;\n ms.ownerCount = ownerCount;\n ms.threshold = threshold;\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_owners);\n }\n\n /**\n * @notice Uninitialize signer in K1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n ++ms.counter;\n address[] memory ownerlist = getOwners();\n uint256 ownerlistLength = ownerlist.length;\n for (uint256 i; i < ownerlistLength; ) {\n ms.owners[ownerlist[i]] = address(0);\n unchecked {\n ++i;\n }\n }\n ms.owners[SENTINEL_OWNERS] = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls checkSignatures with\n * user operation hash and signature together with the threshold.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n // Data 1 is invalid, Data 0 is valid\n validationData = checkSignatures(\n userOpHash,\n userOp.signature,\n LibMultiSigStorage.multisigStorage().threshold\n );\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n return this.validateOwnerSignature.selector;\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n uint totalLength = ms.ownerCount * ADDRESS;\n bytes memory result = new bytes(totalLength);\n\n // populate return array\n uint256 index;\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n while (currentOwner != SENTINEL_OWNERS) {\n assembly {\n mstore(\n add(result, add(32, mul(index, ADDRESS))),\n shl(96, currentOwner)\n )\n }\n currentOwner = ms.owners[currentOwner];\n index++;\n }\n\n return result;\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key should comply with the format in the signature_format.md doc\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n uint256 publicKeyLength = _publicKey.length;\n if (\n publicKeyLength < ADDRESS + THRESHOLD ||\n (publicKeyLength - THRESHOLD) % ADDRESS != 0\n ) return false;\n\n uint256 threshold = uint256(uint32(bytes4(_publicKey)));\n uint256 ownerCount = (publicKeyLength - THRESHOLD) / ADDRESS;\n\n isValid = !(ownerCount < threshold || threshold == 0);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes calldata _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (checkSignatures(\n _hash,\n _signature,\n LibMultiSigStorage.multisigStorage().threshold\n ) == VALID_SIG)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n\n /**\n * @notice Validates the format of the signature and verifies if the signature is signed by the expected key.\n * Reference signature_format.md doc for details about signature format and signature types\n * @param _dataHash Bytes value of data hash signed by the owners\n * @param _signatures Bytes value of signature which should comply with signature format\n * @param _threshold Uint256 value of current Multi-sig Barz's threshold\n */\n function checkSignatures(\n bytes32 _dataHash,\n bytes calldata _signatures,\n uint256 _threshold\n ) public view returns (uint256) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n address lastOwner = address(0);\n address currentOwner;\n bytes memory signature;\n uint256 signatureType;\n uint256 nextOffset;\n uint256 i;\n for (i; i < _threshold; ) {\n (\n currentOwner,\n signature,\n signatureType,\n nextOffset\n ) = splitSignatures(_signatures, nextOffset);\n if (nextOffset == 0 && i + 1 < _threshold) return INVALID_SIG;\n if (signatureType == 1) {\n // If signatureType is 1 then it is default dataHash signed.\n // This also includes the contract signature\n if (\n !SignatureChecker.isValidSignatureNow(\n currentOwner,\n _dataHash,\n signature\n )\n ) return INVALID_SIG;\n } else if (signatureType == 2) {\n // If signatureType is 2 then it is an approved hash\n if (ms.approvedHashes[ms.counter][currentOwner][_dataHash] == 0)\n return INVALID_SIG;\n } else if (signatureType == 3) {\n // If signatureType is 3 then it is a signed message hash\n // This also includes the contract signature\n bytes32 msgHash = _dataHash.toEthSignedMessageHash();\n if (\n !SignatureChecker.isValidSignatureNow(\n currentOwner,\n msgHash,\n signature\n )\n ) return INVALID_SIG;\n } else revert MultiSigFacet__InvalidRoute();\n if (\n currentOwner <= lastOwner ||\n ms.owners[currentOwner] == address(0) ||\n currentOwner == SENTINEL_OWNERS\n ) return INVALID_SIG;\n lastOwner = currentOwner;\n\n unchecked {\n ++i;\n }\n }\n return VALID_SIG;\n }\n\n /**\n * @notice Split signatures into each individual signatures. Should comply with signature format to be split\n * @param _signatures Bytes value of signature\n * @param _nextOffset Uint256 value of next offset to start splitting the signature\n */\n function splitSignatures(\n bytes calldata _signatures,\n uint256 _nextOffset\n )\n public\n pure\n returns (\n address owner_,\n bytes memory signature,\n uint256 signatureType,\n uint256 nextOffset\n )\n {\n uint256 signaturesLength = _signatures.length;\n\n if (signaturesLength <= _nextOffset + ADDRESS + SIG_LEN)\n revert MultiSigFacet__InsufficientSignerLength();\n\n owner_ = address(\n bytes20(_signatures[_nextOffset:_nextOffset + ADDRESS])\n );\n\n signatureType = uint256(\n uint8(\n bytes1(\n _signatures[_nextOffset + ADDRESS:_nextOffset +\n ADDRESS +\n SIG_TYPE]\n )\n )\n );\n\n if (signatureType > 3 || signatureType == 0)\n revert MultiSigFacet__InvalidSignatureType();\n uint256 offSet = _nextOffset + ADDRESS + SIG_TYPE;\n uint256 siglen = uint256(\n uint32(bytes4(_signatures[offSet:offSet + SIG_LEN]))\n );\n if (offSet + siglen > signaturesLength)\n revert MultiSigFacet__InvalidSignatureLength();\n\n offSet += SIG_LEN;\n if (offSet + siglen == signaturesLength) nextOffset = 0;\n else nextOffset = offSet + siglen;\n\n signature = _signatures[offSet:offSet + siglen];\n }\n\n /**\n * @notice Approves the hash of userOperation on-chain. This can only be called by owners.\n * @param _hashToApprove Bytes value of UserOperation hash to approve\n */\n function approveHash(bytes32 _hashToApprove) external {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (ms.owners[msg.sender] == address(0))\n revert MultiSigFacet__OnlyOwner();\n\n ms.approvedHashes[ms.counter][msg.sender][_hashToApprove] = 1;\n emit HashApproved(_hashToApprove, msg.sender);\n }\n\n /**\n * @notice Add owner to Barz. Update thresold if threshold is given different from current threshold\n * @dev This can only be done via a Self call.\n * @param _newOwner Address of new owner to be added\n * @param _threshold Uint256 value of threshold\n */\n function addOwner(address _newOwner, uint256 _threshold) external {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (\n _newOwner == address(0) ||\n _newOwner == SENTINEL_OWNERS ||\n _newOwner == address(this)\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_newOwner] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n\n ms.owners[_newOwner] = ms.owners[SENTINEL_OWNERS];\n ms.owners[SENTINEL_OWNERS] = _newOwner;\n ++ms.ownerCount;\n emit OwnerAdded(_newOwner);\n\n if (ms.threshold != _threshold) changeThreshold(_threshold);\n }\n\n /**\n * @notice Remove owner from Barz. Update thresold if threshold is given different from current threshold\n * @dev This can only be done via a Self call.\n * @param _prevOwner Address of owner located right behind the removed owner address in the linked list\n * @param _removedOwner Address of owner to be removed\n * @param _threshold Uint256 value of threshold\n */\n function removeOwner(\n address _prevOwner,\n address _removedOwner,\n uint256 _threshold\n ) external {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (ms.ownerCount - 1 < _threshold)\n revert MultiSigFacet__InvalidThreshold();\n if (_removedOwner == address(0) || _removedOwner == SENTINEL_OWNERS)\n revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_prevOwner] != _removedOwner)\n revert MultiSigFacet__InvalidOwnerPair();\n\n ms.owners[_prevOwner] = ms.owners[_removedOwner];\n ms.owners[_removedOwner] = address(0);\n --ms.ownerCount;\n emit OwnerRemoved(_removedOwner);\n\n if (ms.threshold != _threshold) changeThreshold(_threshold);\n }\n\n /**\n * @notice Swap owner in Barz.\n * @dev This can only be done via a Self call.\n * @param _prevOwner Address of owner located right behind the removed owner address in the linked list\n * @param _oldOwner Address of owner to be removed\n * @param _newOwner Address of owner to be added\n */\n function swapOwner(\n address _prevOwner,\n address _oldOwner,\n address _newOwner\n ) public {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (\n _newOwner == address(0) ||\n _newOwner == SENTINEL_OWNERS ||\n _newOwner == address(this)\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_newOwner] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n if (_oldOwner == address(0) || _oldOwner == SENTINEL_OWNERS)\n revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_prevOwner] != _oldOwner)\n revert MultiSigFacet__InvalidOwnerPair();\n\n ms.owners[_newOwner] = ms.owners[_oldOwner];\n ms.owners[_prevOwner] = _newOwner;\n ms.owners[_oldOwner] = address(0);\n emit OwnerRemoved(_oldOwner);\n emit OwnerAdded(_newOwner);\n }\n\n /**\n * @notice Changes the threshold of the Barz to `_threshold`.\n * @dev This can only be done via a Self call.\n * @param _threshold New threshold\n */\n function changeThreshold(uint256 _threshold) public {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (_threshold > ms.ownerCount || _threshold == 0)\n revert MultiSigFacet__InvalidThreshold();\n\n ms.threshold = _threshold;\n emit ThresholdChanged(_threshold);\n }\n\n /**\n * @notice Checks if the given address is owner\n * @param _owner Address to be checked if it's owner\n * @return isOwner_ Bool value showing if it's owner address\n */\n function isOwner(address _owner) public view returns (bool isOwner_) {\n isOwner_ = (_owner != SENTINEL_OWNERS &&\n LibMultiSigStorage.multisigStorage().owners[_owner] != address(0));\n }\n\n /**\n * @notice Returns the threshold of Barz\n * @return threshold Threshold of the Barz account\n */\n function getThreshold() public view returns (uint256 threshold) {\n threshold = LibMultiSigStorage.multisigStorage().threshold;\n }\n\n /**\n * @notice Returns the list of owner addresses\n * @return owners List of owners\n */\n function getOwners() public view returns (address[] memory owners) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n owners = new address[](ms.ownerCount);\n\n uint256 index;\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n while (currentOwner != SENTINEL_OWNERS) {\n owners[index] = currentOwner;\n currentOwner = ms.owners[currentOwner];\n index++;\n }\n }\n\n /**\n * @notice Returns the previous owner in the linked list\n * @param _owner Address of owner\n * @return prevOwner Address of previous owner\n */\n function getPrevOwner(\n address _owner\n ) public view returns (address prevOwner) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n if (currentOwner == _owner) return SENTINEL_OWNERS;\n while (currentOwner != SENTINEL_OWNERS) {\n if (ms.owners[currentOwner] == _owner) return currentOwner;\n\n currentOwner = ms.owners[currentOwner];\n }\n return address(0);\n }\n\n /**\n * @notice Returns of the owner is approved by given owner address\n * @param _owner Address of owner\n * @param _hash Hash of UserOperation\n * @return isApproved Bool value showing if the hash is approved by owner\n */\n function isApprovedHash(\n address _owner,\n bytes32 _hash\n ) public view returns (bool isApproved) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n isApproved = (ms.approvedHashes[ms.counter][_owner][_hash] == 1);\n }\n}\n" + }, + "contracts/facets/verification/secp256k1/Secp256k1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {UserOperation} from \"../../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibAppStorage} from \"../../../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, Secp256k1VerificationStorage} from \"../../../libraries/LibFacetStorage.sol\";\nimport {LibLoupe} from \"../../../libraries/LibLoupe.sol\";\nimport {IERC1271} from \"../../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../../interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Secp256k1 verification facet\n * @dev Default Ethereum's elliptic curve\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract Secp256k1VerificationFacet is IVerificationFacet, IERC1271 {\n using ECDSA for bytes32;\n error Secp256k1VerificationFacet__InvalidSignerLength();\n address public immutable self;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in K1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\n * @param _publicKey Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _publicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n if (!isValidKeyType(_publicKey))\n revert Secp256k1VerificationFacet__InvalidSignerLength();\n\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(uint160(uint256(keccak256(_publicKey[1:]))));\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_publicKey);\n }\n\n /**\n * @notice Uninitialize signer in K1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\n * signer public key.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n validationData = validateSignature(\n userOp,\n userOpHash,\n k1Storage.signer\n );\n }\n\n /**\n * @notice Validates if the signature of UserOperation is signed by the given signer\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @param signer Address of signer who signed the contract, to be validated\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n address signer\n ) public pure returns (uint256 isValid) {\n bytes32 hash = userOpHash.toEthSignedMessageHash();\n isValid = (signer != hash.recover(userOp.signature)) ? 1 : 0;\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n ownerSignatureValidatorSelector = this.validateOwnerSignature.selector;\n // NOTE: The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory signer) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n signer = abi.encodePacked(k1Storage.signer);\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key length should be 65 in an uncompressed public key format\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (_hash.recover(_signature) ==\n LibFacetStorage.k1Storage().signer)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/Secp256r1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {UserOperation} from \"../../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibAppStorage} from \"../../../libraries/LibAppStorage.sol\";\nimport {LibLoupe} from \"../../../libraries/LibLoupe.sol\";\nimport {LibFacetStorage, Secp256r1VerificationStorage} from \"../../../libraries/LibFacetStorage.sol\";\nimport {Base64} from \"./utils/Base64.sol\";\nimport {LibSecp256r1} from \"./utils/LibSecp256r1.sol\";\nimport {IERC1271} from \"../../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../../interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Secp256r1 verification facet\n * @dev Primarily used to verify user ops signed with passkeys\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract Secp256r1VerificationFacet is IVerificationFacet, IERC1271 {\n error Secp256r1VerificationFacet__InvalidSignerLength();\n address public immutable self;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in R1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\n * @param _publicKey Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _publicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n\n if (!isValidKeyType(_publicKey))\n revert Secp256r1VerificationFacet__InvalidSignerLength();\n\n bytes memory publicKeyCoordinates = _publicKey[1:];\n uint256[2] memory q;\n assembly {\n // Copy the bytes from the input data into the uint256 array\n mstore(q, mload(add(publicKeyCoordinates, 32)))\n mstore(add(q, 32), mload(add(publicKeyCoordinates, 64)))\n }\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n r1Storage.q = q;\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_publicKey);\n }\n\n /**\n * @notice Uninitialize signer in R1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n r1Storage.q = [0, 0];\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\n * signer public key.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n validationData = validateSignature(userOp, userOpHash, r1Storage.q);\n }\n\n /**\n * @notice Validates if the signature of UserOperation is signed by the given signer\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @param q Public Key of signer who signed the contract, to be validated\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256[2] memory q\n ) public view returns (uint256 isValid) {\n isValid = (_validateSignature(q, userOpHash, userOp.signature)) ? 0 : 1;\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n return this.validateOwnerSignature.selector; // validateOwnerSignature(UserOperation calldata userOp,bytes32 userOpHash)\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory signer) {\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n signer = abi.encodePacked(r1Storage.q);\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key should in an uncompressed public key format\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = _validateSignature(\n LibFacetStorage.r1Storage().q,\n _hash,\n _signature\n )\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n\n function _validateSignature(\n uint256[2] memory q,\n bytes32 _hash,\n bytes memory _signature\n ) internal view returns (bool) {\n (\n uint256 rValue,\n uint256 sValue,\n bytes memory authenticatorData,\n string memory clientDataJSONPre,\n string memory clientDataJSONPost\n ) = abi.decode(_signature, (uint256, uint256, bytes, string, string));\n bytes32 clientHash;\n {\n string memory opHashBase64 = Base64.encode(bytes.concat(_hash));\n string memory clientDataJSON = string.concat(\n clientDataJSONPre,\n opHashBase64,\n clientDataJSONPost\n );\n clientHash = sha256(bytes(clientDataJSON));\n }\n bytes32 sigHash = sha256(bytes.concat(authenticatorData, clientHash));\n return LibSecp256r1.Verify(q, rValue, sValue, uint256(sigHash));\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/utils/Base64.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @dev Provides a set of functions to operate with Base64 strings.\n * modified for base64url https://datatracker.ietf.org/doc/html/rfc4648#section-5\n * _Available since v4.5._\n */\nlibrary Base64 {\n /**\n * @dev Base64 Encoding/Decoding Table\n */\n string internal constant _TABLE =\n \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_\";\n\n /**\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\n */\n function encode(bytes memory data) internal pure returns (string memory) {\n /**\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\n */\n if (data.length == 0) return \"\";\n\n // Loads the table into memory\n string memory table = _TABLE;\n\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\n // and split into 4 numbers of 6 bits.\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\n // - `data.length + 2` -> Round up\n // - `/ 3` -> Number of 3-bytes chunks\n // - `4 *` -> 4 characters for each chunk\n uint256 newlength = (data.length * 8) / 6;\n if (data.length % 6 > 0) {\n newlength++;\n }\n string memory result = new string(newlength);\n\n /// @solidity memory-safe-assembly\n assembly {\n // Prepare the lookup table (skip the first \"length\" byte)\n let tablePtr := add(table, 1)\n\n // Prepare result pointer, jump over length\n let resultPtr := add(result, 32)\n\n // Run over the input, 3 bytes at a time\n for {\n let dataPtr := data\n let endPtr := add(data, mload(data))\n } lt(dataPtr, endPtr) {\n\n } {\n // Advance 3 bytes\n dataPtr := add(dataPtr, 3)\n let input := mload(dataPtr)\n\n // To write each character, shift the 3 bytes (18 bits) chunk\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\n // and apply logical AND with 0x3F which is the number of\n // the previous character in the ASCII table prior to the Base64 Table\n // The result is then added to the table to get the character to write,\n // and finally write it in the result pointer but with a left shift\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(18, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(12, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(6, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n }\n }\n\n return result;\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/utils/LibSecp256r1.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n// Heavily inspired from\n// https://github.com/maxrobot/elliptic-solidity/blob/master/contracts/Secp256r1.sol\n// https://github.com/tdrerup/elliptic-curve-solidity/blob/master/contracts/curves/EllipticCurve.sol\n// modified to use precompile 0x05 modexp\n// and modified jacobian double\n// optimisations to avoid to an from from affine and jacobian coordinates\n\n// Additional Elliptic curve Public key / Signature validation added by\n// David Yonjun Kim (@Powerstream3604)\n\nstruct JPoint {\n uint256 x;\n uint256 y;\n uint256 z;\n}\n\nlibrary LibSecp256r1 {\n uint256 constant gx =\n 0x6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296;\n uint256 constant gy =\n 0x4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5;\n uint256 public constant pp =\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF;\n\n uint256 public constant nn =\n 0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551;\n uint256 constant a =\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC;\n uint256 constant b =\n 0x5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B;\n uint256 constant MOST_SIGNIFICANT =\n 0xc000000000000000000000000000000000000000000000000000000000000000;\n\n /*\n * Verify\n * @description - verifies that a public key has signed a given message\n * @param Q - public key coordinates X & Y\n * @param R - signature half R\n * @param S - signature half S\n * @param input - hashed message\n */\n function Verify(\n uint256[2] memory q,\n uint r,\n uint s,\n uint e\n ) internal view returns (bool) {\n if (q[0] > pp - 1 || q[1] > pp - 1) {\n return false;\n }\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\n return false;\n }\n if (\n mulmod(q[1], q[1], pp) !=\n addmod(\n addmod(\n mulmod(q[0], mulmod(q[0], q[0], pp), pp),\n mulmod(a, q[0], pp),\n pp\n ),\n b,\n pp\n )\n ) {\n return false;\n }\n\n JPoint[16] memory points = _preComputeJacobianPoints(q);\n return VerifyWithPrecompute(points, r, s, e);\n }\n\n function VerifyWithPrecompute(\n JPoint[16] memory points,\n uint r,\n uint s,\n uint e\n ) internal view returns (bool) {\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\n return false;\n }\n\n uint w = _primemod(s, nn);\n\n uint u1 = mulmod(e, w, nn);\n uint u2 = mulmod(r, w, nn);\n\n uint x;\n uint y;\n\n (x, y) = ShamirMultJacobian(points, u1, u2);\n return (x == r);\n }\n\n /*\n * Strauss Shamir trick for EC multiplication\n * https://stackoverflow.com/questions/50993471/ec-scalar-multiplication-with-strauss-shamir-method\n * we optimise on this a bit to do with 2 bits at a time rather than a single bit\n * the individual points for a single pass are precomputed\n * overall this reduces the number of additions while keeping the same number of doublings\n */\n function ShamirMultJacobian(\n JPoint[16] memory points,\n uint u1,\n uint u2\n ) internal view returns (uint, uint) {\n uint x = 0;\n uint y = 0;\n uint z = 0;\n uint bits = 128;\n uint index = 0;\n\n while (bits > 0) {\n if (z > 0) {\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\n }\n index =\n ((u1 & MOST_SIGNIFICANT) >> 252) |\n ((u2 & MOST_SIGNIFICANT) >> 254);\n if (index > 0) {\n (x, y, z) = _jAdd(\n x,\n y,\n z,\n points[index].x,\n points[index].y,\n points[index].z\n );\n }\n u1 <<= 2;\n u2 <<= 2;\n bits--;\n }\n (x, y) = _affineFromJacobian(x, y, z);\n return (x, y);\n }\n\n function _preComputeJacobianPoints(\n uint256[2] memory q\n ) internal pure returns (JPoint[16] memory points) {\n points[0] = JPoint(0, 0, 0);\n points[1] = JPoint(q[0], q[1], 1); // u2\n points[2] = _jPointDouble(points[1]);\n points[3] = _jPointAdd(points[1], points[2]);\n\n points[4] = JPoint(gx, gy, 1); // u1Points[1]\n points[5] = _jPointAdd(points[4], points[1]);\n points[6] = _jPointAdd(points[4], points[2]);\n points[7] = _jPointAdd(points[4], points[3]);\n\n points[8] = _jPointDouble(points[4]); // u1Points[2]\n points[9] = _jPointAdd(points[8], points[1]);\n points[10] = _jPointAdd(points[8], points[2]);\n points[11] = _jPointAdd(points[8], points[3]);\n\n points[12] = _jPointAdd(points[4], points[8]); // u1Points[3]\n points[13] = _jPointAdd(points[12], points[1]);\n points[14] = _jPointAdd(points[12], points[2]);\n points[15] = _jPointAdd(points[12], points[3]);\n }\n\n function _jPointAdd(\n JPoint memory p1,\n JPoint memory p2\n ) internal pure returns (JPoint memory) {\n uint x;\n uint y;\n uint z;\n (x, y, z) = _jAdd(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z);\n return JPoint(x, y, z);\n }\n\n function _jPointDouble(\n JPoint memory p\n ) internal pure returns (JPoint memory) {\n uint x;\n uint y;\n uint z;\n (x, y, z) = _modifiedJacobianDouble(p.x, p.y, p.z);\n return JPoint(x, y, z);\n }\n\n /* _affineFromJacobian\n * @desription returns affine coordinates from a jacobian input follows\n * golang elliptic/crypto library\n */\n function _affineFromJacobian(\n uint x,\n uint y,\n uint z\n ) internal view returns (uint ax, uint ay) {\n if (z == 0) {\n return (0, 0);\n }\n\n uint zinv = _primemod(z, pp);\n uint zinvsq = mulmod(zinv, zinv, pp);\n\n ax = mulmod(x, zinvsq, pp);\n ay = mulmod(y, mulmod(zinvsq, zinv, pp), pp);\n }\n\n /*\n * _jAdd\n * @description performs Jacobian addition as defined below:\n * http://www.hyperelliptic.org/EFD/g1p/data/shortw/jacobian/addition/add-2007-bl\n */\n function _jAdd(\n uint p1,\n uint p2,\n uint p3,\n uint q1,\n uint q2,\n uint q3\n ) internal pure returns (uint r1, uint r2, uint r3) {\n if (p3 == 0) {\n r1 = q1;\n r2 = q2;\n r3 = q3;\n\n return (r1, r2, r3);\n } else if (q3 == 0) {\n r1 = p1;\n r2 = p2;\n r3 = p3;\n\n return (r1, r2, r3);\n }\n\n assembly {\n let\n pd\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\n let z1z1 := mulmod(p3, p3, pd) // Z1Z1 = Z1^2\n let z2z2 := mulmod(q3, q3, pd) // Z2Z2 = Z2^2\n\n let u1 := mulmod(p1, z2z2, pd) // U1 = X1*Z2Z2\n let u2 := mulmod(q1, z1z1, pd) // U2 = X2*Z1Z1\n\n let s1 := mulmod(p2, mulmod(z2z2, q3, pd), pd) // S1 = Y1*Z2*Z2Z2\n let s2 := mulmod(q2, mulmod(z1z1, p3, pd), pd) // S2 = Y2*Z1*Z1Z1\n\n let p3q3 := addmod(p3, q3, pd)\n\n if lt(u2, u1) {\n u2 := add(pd, u2) // u2 = u2+pd\n }\n let h := sub(u2, u1) // H = U2-U1\n\n let i := mulmod(0x02, h, pd)\n i := mulmod(i, i, pd) // I = (2*H)^2\n\n let j := mulmod(h, i, pd) // J = H*I\n if lt(s2, s1) {\n s2 := add(pd, s2) // u2 = u2+pd\n }\n let rr := mulmod(0x02, sub(s2, s1), pd) // r = 2*(S2-S1)\n r1 := mulmod(rr, rr, pd) // X3 = R^2\n\n let v := mulmod(u1, i, pd) // V = U1*I\n let j2v := addmod(j, mulmod(0x02, v, pd), pd)\n if lt(r1, j2v) {\n r1 := add(pd, r1) // X3 = X3+pd\n }\n r1 := sub(r1, j2v)\n\n // Y3 = r*(V-X3)-2*S1*J\n let s12j := mulmod(mulmod(0x02, s1, pd), j, pd)\n\n if lt(v, r1) {\n v := add(pd, v)\n }\n r2 := mulmod(rr, sub(v, r1), pd)\n\n if lt(r2, s12j) {\n r2 := add(pd, r2)\n }\n r2 := sub(r2, s12j)\n\n // Z3 = ((Z1+Z2)^2-Z1Z1-Z2Z2)*H\n z1z1 := addmod(z1z1, z2z2, pd)\n j2v := mulmod(p3q3, p3q3, pd)\n if lt(j2v, z1z1) {\n j2v := add(pd, j2v)\n }\n r3 := mulmod(sub(j2v, z1z1), h, pd)\n }\n return (r1, r2, r3);\n }\n\n // Point doubling on the modified jacobian coordinates\n // http://point-at-infinity.org/ecc/Prime_Curve_Modified_Jacobian_Coordinates.html\n function _modifiedJacobianDouble(\n uint x,\n uint y,\n uint z\n ) internal pure returns (uint x3, uint y3, uint z3) {\n if (y == 0) return (0, 0, 0);\n assembly {\n let\n pd\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\n let z2 := mulmod(z, z, pd)\n let az4 := mulmod(\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC,\n mulmod(z2, z2, pd),\n pd\n )\n let y2 := mulmod(y, y, pd)\n let s := mulmod(0x04, mulmod(x, y2, pd), pd)\n let u := mulmod(0x08, mulmod(y2, y2, pd), pd)\n let m := addmod(mulmod(0x03, mulmod(x, x, pd), pd), az4, pd)\n let twos := mulmod(0x02, s, pd)\n let m2 := mulmod(m, m, pd)\n if lt(m2, twos) {\n m2 := add(pd, m2)\n }\n x3 := sub(m2, twos)\n if lt(s, x3) {\n s := add(pd, s)\n }\n y3 := mulmod(m, sub(s, x3), pd)\n if lt(y3, u) {\n y3 := add(pd, y3)\n }\n y3 := sub(y3, u)\n z3 := mulmod(0x02, mulmod(y, z, pd), pd)\n }\n }\n\n // Fermats little theorem https://en.wikipedia.org/wiki/Fermat%27s_little_theorem\n // a^(p-1) = 1 mod p\n // a^(-1) ≅ a^(p-2) (mod p)\n // we then use the precompile bigModExp to compute a^(-1)\n function _primemod(uint value, uint p) internal view returns (uint ret) {\n ret = modexp(value, p - 2, p);\n return ret;\n }\n\n // Wrapper for built-in BigNumber_modexp (contract 0x5) as described here. https://github.com/ethereum/EIPs/pull/198\n function modexp(\n uint _base,\n uint _exp,\n uint _mod\n ) internal view returns (uint ret) {\n // bigModExp(_base, _exp, _mod);\n assembly {\n if gt(_base, _mod) {\n _base := mod(_base, _mod)\n }\n // Free memory pointer is always stored at 0x40\n let freemem := mload(0x40)\n\n mstore(freemem, 0x20)\n mstore(add(freemem, 0x20), 0x20)\n mstore(add(freemem, 0x40), 0x20)\n\n mstore(add(freemem, 0x60), _base)\n mstore(add(freemem, 0x80), _exp)\n mstore(add(freemem, 0xa0), _mod)\n\n let success := staticcall(14000, 0x5, freemem, 0xc0, freemem, 0x20)\n switch success\n case 0 {\n revert(0x0, 0x0)\n }\n default {\n ret := mload(freemem)\n }\n }\n }\n}\n" + }, + "contracts/infrastructure/DefaultFallbackHandler.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC1155Receiver} from \"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\";\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {BaseAccount} from \"../aa-4337/core/BaseAccount.sol\";\nimport {DefaultLibDiamond} from \"../libraries/DefaultLibDiamond.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IAccountFacet} from \"../facets/interfaces/IAccountFacet.sol\";\nimport {IStorageLoupe} from \"../facets/base/interfaces/IStorageLoupe.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IERC677Receiver} from \"../interfaces/ERC/IERC677Receiver.sol\";\nimport {IERC165} from \"../interfaces/ERC/IERC165.sol\";\n\n/**\n * @title DefaultFallbackHandler\n * @dev A default fallback handler for Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DefaultFallbackHandler is IDiamondLoupe {\n /**\n * @notice Sets the middleware diamond for Barz wallet as a fallback handler\n * @dev This contract is also a diamond that holds the default facets to reduce gas cost for wallet activation.\n * Within the constructor this conducts diamond cut to initially setup the diamond. This is a non-upgradeable contract\n * @param _diamondCutFacet Address if diamond cut facet\n * @param _accountFacet Address account facet\n * @param _tokenReceiverFacet Address of token receiver facet\n * @param _diamondLoupeFacet Address of diamond loupe facet\n */\n constructor(\n address _diamondCutFacet,\n address _accountFacet,\n address _tokenReceiverFacet,\n address _diamondLoupeFacet\n ) payable {\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](4);\n bytes4[] memory functionSelectors = new bytes4[](1);\n functionSelectors[0] = IDiamondCut.diamondCut.selector;\n\n bytes4[] memory accountFunctionSelectors = new bytes4[](5);\n accountFunctionSelectors[0] = IAccountFacet.execute.selector;\n accountFunctionSelectors[1] = IAccountFacet.executeBatch.selector;\n accountFunctionSelectors[2] = BaseAccount.validateUserOp.selector;\n accountFunctionSelectors[3] = BaseAccount.getNonce.selector;\n accountFunctionSelectors[4] = BaseAccount.entryPoint.selector;\n\n bytes4[] memory receiverFacetSelectors = new bytes4[](5);\n receiverFacetSelectors[0] = IERC721Receiver.onERC721Received.selector;\n receiverFacetSelectors[1] = IERC1155Receiver.onERC1155Received.selector;\n receiverFacetSelectors[2] = IERC1155Receiver\n .onERC1155BatchReceived\n .selector;\n receiverFacetSelectors[3] = IERC777Recipient.tokensReceived.selector;\n receiverFacetSelectors[4] = IERC677Receiver.onTokenTransfer.selector;\n\n bytes4[] memory loupeFacetSelectors = new bytes4[](9);\n loupeFacetSelectors[0] = IDiamondLoupe.facets.selector;\n loupeFacetSelectors[1] = IDiamondLoupe.facetFunctionSelectors.selector;\n loupeFacetSelectors[2] = IDiamondLoupe.facetAddresses.selector;\n loupeFacetSelectors[3] = IDiamondLoupe.facetAddress.selector;\n loupeFacetSelectors[4] = IERC165.supportsInterface.selector;\n loupeFacetSelectors[5] = IStorageLoupe.facetsFromStorage.selector;\n loupeFacetSelectors[6] = IStorageLoupe\n .facetFunctionSelectorsFromStorage\n .selector;\n loupeFacetSelectors[7] = IStorageLoupe\n .facetAddressesFromStorage\n .selector;\n loupeFacetSelectors[8] = IStorageLoupe.facetAddressFromStorage.selector;\n\n {\n cut[0] = IDiamondCut.FacetCut({\n facetAddress: _diamondCutFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: functionSelectors\n });\n cut[1] = IDiamondCut.FacetCut({\n facetAddress: _accountFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: accountFunctionSelectors\n });\n cut[2] = IDiamondCut.FacetCut({\n facetAddress: _tokenReceiverFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: receiverFacetSelectors\n });\n cut[3] = IDiamondCut.FacetCut({\n facetAddress: _diamondLoupeFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: loupeFacetSelectors\n });\n\n DefaultLibDiamond.diamondCut(cut, address(0), \"\");\n }\n }\n\n /**\n * @notice Returns the facet information of call facets registered to this diamond.\n * @return facets_ The facet struct array including all facet information\n */\n function facets() external view override returns (Facet[] memory facets_) {\n DefaultLibDiamond.DiamondStorage storage ds = DefaultLibDiamond\n .diamondStorage();\n uint256 numFacets = ds.facetAddresses.length;\n facets_ = new Facet[](numFacets);\n for (uint256 i; i < numFacets; ) {\n address facetAddress_ = ds.facetAddresses[i];\n facets_[i].facetAddress = facetAddress_;\n facets_[i].functionSelectors = ds\n .facetFunctionSelectors[facetAddress_]\n .functionSelectors;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Gets all the function selectors provided by a facet.\n * @param _facet The facet address.\n * @return facetFunctionSelectors_\n */\n function facetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n facetFunctionSelectors_ = DefaultLibDiamond\n .diamondStorage()\n .facetFunctionSelectors[_facet]\n .functionSelectors;\n }\n\n /**\n * @notice Get all the facet addresses used by a diamond.\n * @return facetAddresses_\n */\n function facetAddresses()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n facetAddresses_ = DefaultLibDiamond.diamondStorage().facetAddresses;\n }\n\n /** @notice Gets the facet that supports the given selector.\n * @dev If facet is not found return address(0).\n * @param _functionSelector The function selector.\n * @return facetAddress_ The facet address.\n */\n function facetAddress(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n facetAddress_ = DefaultLibDiamond\n .diamondStorage()\n .selectorToFacetAndPosition[_functionSelector]\n .facetAddress;\n }\n}\n" + }, + "contracts/infrastructure/FacetRegistry.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport {IFacetRegistry} from \"./interfaces/IFacetRegistry.sol\";\n\n/**\n * @title Facet Registry\n * @dev Contract to keep track of facets & function selectors addable to user wallets\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract FacetRegistry is IFacetRegistry, Ownable2Step {\n mapping(address => FacetRegistryConfig) private facets;\n\n /**\n * @notice Transfers the ownership of the contract to the given owner\n * @param _owner Address of owner who has access to initialize the default security variables for security manager\n */\n constructor(address _owner) {\n transferOwnership(_owner);\n _transferOwnership(_owner);\n }\n\n /**\n * @dev Registers a facet and it's function selectors to registry\n * @param _facet address of facet\n * @param _facetSelectors list of function selectors of the facet\n */\n function registerFacetFunctionSelectors(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external override onlyOwner {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n for (uint256 i; i < _facetSelectors.length; ) {\n if (facetConfig.info[_facetSelectors[i]].exists)\n revert FacetRegistry__FacetSelectorAlreadyRegistered();\n\n facetConfig.info[_facetSelectors[i]].exists = true;\n facetConfig.info[_facetSelectors[i]].index = uint128(\n facetConfig.selectors.length\n );\n facetConfig.selectors.push(_facetSelectors[i]);\n unchecked {\n ++i;\n }\n }\n emit FacetFunctionSelectorsRegistered(_facet, _facetSelectors);\n }\n\n /**\n * @dev Removes a registered facet and it's corresponding selectors from registry\n * @param _facet address of facet\n * @param _facetSelectors list of function selectors of the facet\n */\n function removeFacetFunctionSelectors(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external override onlyOwner {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n for (uint256 i; i < _facetSelectors.length; ) {\n if (!facetConfig.info[_facetSelectors[i]].exists)\n revert FacetRegistry__UnregisteredFacetSelector();\n\n bytes4 lastSelector = facetConfig.selectors[\n facetConfig.selectors.length - 1\n ];\n if (_facetSelectors[i] != lastSelector) {\n uint128 targetIndex = facetConfig\n .info[_facetSelectors[i]]\n .index;\n facetConfig.selectors[targetIndex] = lastSelector;\n facetConfig.info[lastSelector].index = targetIndex;\n }\n facetConfig.selectors.pop();\n delete facetConfig.info[_facetSelectors[i]];\n\n unchecked {\n ++i;\n }\n }\n emit FacetFunctionSelectorsRemoved(_facet, _facetSelectors);\n }\n\n /**\n * @dev Checks if a facet and it's selectors given is registered to facet registry\n * @param _facet Address of facet\n * @param _facetSelectors List of function selectors of the facet\n */\n function areFacetFunctionSelectorsRegistered(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external view override returns (bool) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n if (_facetSelectors.length == 0) return false;\n for (uint256 i; i < _facetSelectors.length; ) {\n if (!facetConfig.info[_facetSelectors[i]].exists) return false;\n unchecked {\n ++i;\n }\n }\n return true;\n }\n\n /**\n * @dev Checks if a facet and it's selector given is registered to facet registry\n * @param _facet Address of facet\n * @param _facetSelector List of function selectors of the facet\n * @return isRegistered Bool value showing if the selector is registered\n */\n function isFacetFunctionSelectorRegistered(\n address _facet,\n bytes4 _facetSelector\n ) external view override returns (bool isRegistered) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n isRegistered = facetConfig.info[_facetSelector].exists;\n }\n\n /**\n * @dev Get the registered selectors of facet from registry\n * @param _facet Address of facet\n * @return selectors Selectors registered to facet\n */\n function getFacetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory selectors) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n selectors = facetConfig.selectors;\n }\n}\n" + }, + "contracts/infrastructure/interfaces/IFacetRegistry.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Registry Interface\n * @dev Interface for Facet Registry contract to keep track of facets & function selectors addable to user wallets\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IFacetRegistry {\n struct FacetRegistryConfig {\n bytes4[] selectors;\n mapping(bytes4 => FacetInfo) info;\n }\n struct FacetInfo {\n bool exists;\n uint128 index;\n }\n\n event FacetFunctionSelectorsRegistered(\n address facet,\n bytes4[] facetSelectors\n );\n event FacetFunctionSelectorsRemoved(address facet, bytes4[] facetSelectors);\n\n error FacetRegistry__FacetSelectorAlreadyRegistered();\n error FacetRegistry__UnregisteredFacetSelector();\n\n function registerFacetFunctionSelectors(\n address facet,\n bytes4[] calldata facetSelectors\n ) external;\n\n function removeFacetFunctionSelectors(\n address facet,\n bytes4[] calldata facetSelectors\n ) external;\n\n function areFacetFunctionSelectorsRegistered(\n address facet,\n bytes4[] calldata facetSelectors\n ) external view returns (bool);\n\n function isFacetFunctionSelectorRegistered(\n address facet,\n bytes4 facetSelector\n ) external view returns (bool);\n\n function getFacetFunctionSelectors(\n address facet\n ) external view returns (bytes4[] memory);\n}\n" + }, + "contracts/infrastructure/interfaces/ISecurityManager.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Registry Interface\n * @dev Infrastructure contract to manage security parameters of users\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface ISecurityManager {\n error SecurityManager__OutOfBoundary();\n error SecurityManager__CallerNotWallet();\n error SecurityManager__AlreadyIntialized();\n\n function initializeAdditionSecurityPeriod(\n uint128 defaultAdditionSecurityPeriod,\n uint128 minAdditionSecurityPeriod,\n uint128 maxAdditionSecurityPeriod\n ) external;\n\n function initializeRemovalSecurityPeriod(\n uint128 defaultRemovalSecurityPeriod,\n uint128 minRemovalSecurityPeriod,\n uint128 maxRemovalSecurityPeriod\n ) external;\n\n function initializeApprovalValidationPeriod(\n uint128 defaultApprovalValidationPeriod,\n uint128 minApprovalValidationPeriod,\n uint128 maxApprovalValidationPeriod\n ) external;\n\n function initializeMigrationPeriod(\n uint128 defaultMigrationPeriod,\n uint128 minMigrationPeriod,\n uint128 maxMigrationPeriod\n ) external;\n\n function initializeLockPeriod(\n uint128 defaultLockPeriod,\n uint128 minLockPeriod,\n uint128 maxLockPeriod\n ) external;\n\n function initializeRecoveryPeriod(\n uint128 defaultRecoveryPeriod,\n uint128 minRecoveryPeriod,\n uint128 maxRecoveryPeriod\n ) external;\n\n function initializeSecurityWindow(\n uint128 defaultSecurityWindow,\n uint128 minSecurityWindow,\n uint128 maxSecurityWindow\n ) external;\n\n function setAdditionSecurityPeriod(\n address wallet,\n uint128 additionSecurityPeriod\n ) external;\n\n function setRemovalSecurityPeriod(\n address wallet,\n uint128 removalSecurityPeriod\n ) external;\n\n function setSecurityWindow(address wallet, uint128 securityWindow) external;\n\n function setRecoveryPeriod(address wallet, uint128 recoveryPeriod) external;\n\n function setLockPeriod(address wallet, uint128 lockPeriod) external;\n\n function setApprovalValidationPeriod(\n address wallet,\n uint128 approvalValidationPeriod\n ) external;\n\n function setMigrationPeriod(\n address wallet,\n uint128 migrationPeriod\n ) external;\n\n function additionSecurityPeriodOf(\n address wallet\n ) external view returns (uint128);\n\n function removalSecurityPeriodOf(\n address wallet\n ) external view returns (uint128);\n\n function securityWindowOf(address wallet) external view returns (uint128);\n\n function recoveryPeriodOf(address wallet) external view returns (uint128);\n\n function lockPeriodOf(address wallet) external view returns (uint128);\n\n function migrationPeriodOf(address wallet) external view returns (uint128);\n\n function approvalValidationPeriodOf(\n address wallet\n ) external view returns (uint128);\n}\n" + }, + "contracts/infrastructure/RemoteStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IGuardianFacet} from \"../facets/interfaces/IGuardianFacet.sol\";\n\n/**\n * @title Remote Storage\n * @dev Remote storage allows you to associate addresses with an array of addresses on a standalone smart contract.\n * This could be useful when you don't want to use the local diamond storage for some purpose.\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\nabstract contract RemoteStorage {\n struct StorageConfig {\n address[] addresses;\n mapping(address => Info) info;\n }\n\n struct Info {\n bool exists;\n uint128 index;\n }\n\n mapping(address => StorageConfig) internal configs;\n\n event Added(address _address);\n event Removed(address _address);\n\n error RemoteStorage__CallerNotOwner();\n error RemoteStorage__CallerNotGuardianOrOwner();\n error RemoteStorage__AlreadyExists();\n error RemoteStorage__NotFound();\n error RemoteStorage__CallerNotGuardian();\n\n bytes4 constant IS_GUARDIAN_SELECTOR =\n bytes4(keccak256(\"isGuardian(address)\"));\n bytes4 constant GUARDIAN_COUNT = bytes4(keccak256(\"guardianCount()\"));\n\n /**\n * @notice Modifier to only allow the self to call. Reverts otherwise\n */\n modifier onlyWallet(address _wallet) {\n if (msg.sender != _wallet) revert RemoteStorage__CallerNotOwner();\n _;\n }\n\n /**\n * @notice Enfore the callet to be wallet of guardian of the wallet\n * @param _wallet Address of wallet\n */\n function enforceGuardianOrWallet(address _wallet) internal view {\n if (msg.sender == _wallet) return;\n address facetAddress = IDiamondLoupe(_wallet).facetAddress(\n IS_GUARDIAN_SELECTOR\n );\n if (facetAddress != address(0))\n if (IGuardianFacet(_wallet).isGuardian(msg.sender)) return;\n revert RemoteStorage__CallerNotGuardianOrOwner();\n }\n\n /**\n * @notice Enforce the caller to be wallet IF guardians doesn't exists and only guardian when guardians exists\n * @param _wallet Target wallet address to be handled by infrastructure contracts\n */\n function enforceWalletOrGuardianIfExists(address _wallet) internal view {\n address facetAddress;\n if (msg.sender == _wallet) {\n facetAddress = IDiamondLoupe(_wallet).facetAddress(GUARDIAN_COUNT);\n if (facetAddress == address(0)) return;\n uint256 guardianCount = IGuardianFacet(_wallet).guardianCount();\n if (guardianCount != 0) revert RemoteStorage__CallerNotGuardian();\n return;\n }\n facetAddress = IDiamondLoupe(_wallet).facetAddress(\n IS_GUARDIAN_SELECTOR\n );\n if (facetAddress != address(0))\n if (IGuardianFacet(_wallet).isGuardian(msg.sender)) return;\n\n revert RemoteStorage__CallerNotGuardianOrOwner();\n }\n\n /**\n * @notice Add address to storage and reverts if the address already exists.\n * This is an internal function callable from contracts that inherit this abstract contract\n * @param _wallet Address of wallet to add the address\n * @param _address Address to be added to wallet\n */\n function addAddress(address _wallet, address _address) internal {\n StorageConfig storage config = configs[_wallet];\n if (config.info[_address].exists) revert RemoteStorage__AlreadyExists();\n\n config.info[_address].exists = true;\n config.info[_address].index = uint128(config.addresses.length);\n config.addresses.push(_address);\n\n emit Added(_address);\n }\n\n /**\n * @notice Remove address from storage and reverts if the address already exists.\n * This is an internal function callable from contracts that inherit this abstract contract\n * @param _wallet Address of wallet to remove the address\n * @param _address Address to be removed from wallet\n */\n function removeAddress(address _wallet, address _address) internal {\n StorageConfig storage config = configs[_wallet];\n if (!config.info[_address].exists) revert RemoteStorage__NotFound();\n\n address lastAddress = config.addresses[config.addresses.length - 1];\n if (_address != lastAddress) {\n uint128 targetIndex = config.info[_address].index;\n config.addresses[targetIndex] = lastAddress;\n config.info[lastAddress].index = targetIndex;\n }\n config.addresses.pop();\n delete config.info[_address];\n\n emit Removed(_address);\n }\n\n /**\n * @notice Returns the address added to the given wallet\n * @param _wallet Address of wallet to fetch the addresses added to it\n * @return addresses List of addresses added to the wallet\n */\n function getAddresses(\n address _wallet\n ) internal view returns (address[] memory addresses) {\n StorageConfig storage config = configs[_wallet];\n addresses = new address[](config.addresses.length);\n uint addressesLen = config.addresses.length;\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns bool value checking if the address exists in the given wallet address\n * @param _wallet Wallet address to check\n * @param _address Address to fetch if the address if added to given wallet\n * @return exists_ Bool value showing if the address exists in wallet\n */\n function exists(\n address _wallet,\n address _address\n ) internal view returns (bool exists_) {\n exists_ = configs[_wallet].info[_address].exists;\n }\n\n /**\n * @notice Returns the number of addresses added to the wallet\n * @param _wallet Address of wallet to check\n * @return count_ Number of addresses added to wallet\n */\n function count(address _wallet) internal view returns (uint256 count_) {\n count_ = configs[_wallet].addresses.length;\n }\n}\n" + }, + "contracts/infrastructure/SecurityManager.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport {ISecurityManager} from \"./interfaces/ISecurityManager.sol\";\n\n/**\n * @title Security Manager\n * @dev Infrastructure contract to manage security parameters of users\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract SecurityManager is ISecurityManager, Ownable2Step {\n uint128 public minAdditionSecurityPeriod;\n uint128 public maxAdditionSecurityPeriod;\n uint128 private defaultAdditionSecurityPeriod;\n\n uint128 public minRemovalSecurityPeriod;\n uint128 public maxRemovalSecurityPeriod;\n uint128 private defaultRemovalSecurityPeriod;\n\n uint128 public minSecurityWindow;\n uint128 public maxSecurityWindow;\n uint128 private defaultSecurityWindow;\n\n uint128 public minRecoveryPeriod;\n uint128 public maxRecoveryPeriod;\n uint128 private defaultRecoveryPeriod;\n\n uint128 public minLockPeriod;\n uint128 public maxLockPeriod;\n uint128 private defaultLockPeriod;\n\n uint128 public minApprovalValidationPeriod;\n uint128 public maxApprovalValidationPeriod;\n uint128 private defaultApprovalValidationPeriod;\n\n uint128 public minMigrationPeriod;\n uint128 public maxMigrationPeriod;\n uint128 private defaultMigrationPeriod;\n\n bool public _isAdditionSecurityPeriodInitialized;\n bool public _isRemovalSecurityPeriodInitialized;\n bool public _isSecurityWindowInitialized;\n bool public _isRecoveryPeriodInitialized;\n bool public _isLockPeriodInitialized;\n bool public _isApprovalValidationPeriodInitialized;\n bool public _isMigrationPeriodInitialized;\n\n mapping(address => CustomSecurityConfig) securityConfigs;\n\n struct CustomSecurityConfig {\n uint128 additionSecurityPeriod;\n uint128 removalSecurityPeriod;\n uint128 securityWindow;\n uint128 recoveryPeriod;\n uint128 lockPeriod;\n uint128 approvalValidationPeriod;\n uint128 migrationPeriod;\n }\n\n /**\n * @notice Modifier to only allow wallet itself to make a call to wallet\n */\n modifier onlyWallet(address _wallet) {\n if (msg.sender != _wallet) revert SecurityManager__CallerNotWallet();\n _;\n }\n\n /**\n * @notice Modifier to revert if the variable is already initialized\n */\n modifier initializer(bool _isInitialized) {\n if (_isInitialized) revert SecurityManager__AlreadyIntialized();\n _;\n }\n\n /**\n * @notice Transfers the ownership of the contract to the given owner\n * @param _owner Address of owner who has access to initialize the default security variables for security manager\n */\n constructor(address _owner) {\n transferOwnership(_owner);\n _transferOwnership(_owner);\n }\n\n /**\n * @notice Sets the initial default/min/max addition security period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultAdditionSecurityPeriod Default Addition Security Period for all Barz contracts\n * @param _minAdditionSecurityPeriod Minimum Addition Security Period for all Barz contracts\n * @param _maxAdditionSecurityPeriod Maximum Addition Security Period for all Barz contracts\n */\n function initializeAdditionSecurityPeriod(\n uint128 _defaultAdditionSecurityPeriod,\n uint128 _minAdditionSecurityPeriod,\n uint128 _maxAdditionSecurityPeriod\n )\n external\n override\n onlyOwner\n initializer(_isAdditionSecurityPeriodInitialized)\n {\n _isAdditionSecurityPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultAdditionSecurityPeriod,\n _minAdditionSecurityPeriod,\n _maxAdditionSecurityPeriod\n );\n defaultAdditionSecurityPeriod = _defaultAdditionSecurityPeriod;\n minAdditionSecurityPeriod = _minAdditionSecurityPeriod;\n maxAdditionSecurityPeriod = _maxAdditionSecurityPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max removal security period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultRemovalSecurityPeriod Default Removal Security Period for all Barz contracts\n * @param _minRemovalSecurityPeriod Minimum Removal Security Period for all Barz contracts\n * @param _maxRemovalSecurityPeriod Maximum Removal Security Period for all Barz contracts\n */\n function initializeRemovalSecurityPeriod(\n uint128 _defaultRemovalSecurityPeriod,\n uint128 _minRemovalSecurityPeriod,\n uint128 _maxRemovalSecurityPeriod\n )\n external\n override\n onlyOwner\n initializer(_isRemovalSecurityPeriodInitialized)\n {\n _isRemovalSecurityPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultRemovalSecurityPeriod,\n _minRemovalSecurityPeriod,\n _maxRemovalSecurityPeriod\n );\n defaultRemovalSecurityPeriod = _defaultRemovalSecurityPeriod;\n minRemovalSecurityPeriod = _minRemovalSecurityPeriod;\n maxRemovalSecurityPeriod = _maxRemovalSecurityPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/maxd security window for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultSecurityWindow Default Security Window for all Barz contracts\n * @param _minSecurityWindow Minimum Security Window for all Barz contracts\n * @param _maxSecurityWindow Maximum Security Window for all Barz contracts\n */\n function initializeSecurityWindow(\n uint128 _defaultSecurityWindow,\n uint128 _minSecurityWindow,\n uint128 _maxSecurityWindow\n ) external override onlyOwner initializer(_isSecurityWindowInitialized) {\n _isSecurityWindowInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultSecurityWindow,\n _minSecurityWindow,\n _maxSecurityWindow\n );\n defaultSecurityWindow = _defaultSecurityWindow;\n minSecurityWindow = _minSecurityWindow;\n maxSecurityWindow = _maxSecurityWindow;\n }\n\n /**\n * @notice Sets the initial default/min/max recovery period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultRecoveryPeriod Default Recovery Period for all Barz contracts\n * @param _minRecoveryPeriod Minimum Recovery Period for all Barz contracts\n * @param _maxRecoveryPeriod Maximum Recovery Period for all Barz contracts\n */\n function initializeRecoveryPeriod(\n uint128 _defaultRecoveryPeriod,\n uint128 _minRecoveryPeriod,\n uint128 _maxRecoveryPeriod\n ) external override onlyOwner initializer(_isRecoveryPeriodInitialized) {\n _isRecoveryPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultRecoveryPeriod,\n _minRecoveryPeriod,\n _maxRecoveryPeriod\n );\n defaultRecoveryPeriod = _defaultRecoveryPeriod;\n minRecoveryPeriod = _minRecoveryPeriod;\n maxRecoveryPeriod = _maxRecoveryPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max lock period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultLockPeriod Default Lock Period for all Barz contracts\n * @param _minLockPeriod Minimum Lock Period for all Barz contracts\n * @param _maxLockPeriod Maximum Lock Period for all Barz contracts\n */\n function initializeLockPeriod(\n uint128 _defaultLockPeriod,\n uint128 _minLockPeriod,\n uint128 _maxLockPeriod\n ) external override onlyOwner initializer(_isLockPeriodInitialized) {\n _isLockPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultLockPeriod,\n _minLockPeriod,\n _maxLockPeriod\n );\n defaultLockPeriod = _defaultLockPeriod;\n minLockPeriod = _minLockPeriod;\n maxLockPeriod = _maxLockPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max approval validation period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultApprovalValidationPeriod Default Approval Validation Period for all Barz contracts\n * @param _minApprovalValidationPeriod Minimum Approval Validation Period for all Barz contracts\n * @param _maxApprovalValidationPeriod Maximum Approval Validation Period for all Barz contracts\n */\n function initializeApprovalValidationPeriod(\n uint128 _defaultApprovalValidationPeriod,\n uint128 _minApprovalValidationPeriod,\n uint128 _maxApprovalValidationPeriod\n )\n external\n override\n onlyOwner\n initializer(_isApprovalValidationPeriodInitialized)\n {\n _isApprovalValidationPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultApprovalValidationPeriod,\n _minApprovalValidationPeriod,\n _maxApprovalValidationPeriod\n );\n defaultApprovalValidationPeriod = _defaultApprovalValidationPeriod;\n minApprovalValidationPeriod = _minApprovalValidationPeriod;\n maxApprovalValidationPeriod = _maxApprovalValidationPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max migration period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultMigrationPeriod Default Migration Period for all Barz contracts\n * @param _minMigrationPeriod Minimum Migration Period for all Barz contracts\n * @param _maxMigrationPeriod Maximum Migration Period for all Barz contracts\n */\n function initializeMigrationPeriod(\n uint128 _defaultMigrationPeriod,\n uint128 _minMigrationPeriod,\n uint128 _maxMigrationPeriod\n ) external override onlyOwner initializer(_isMigrationPeriodInitialized) {\n _isMigrationPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultMigrationPeriod,\n _minMigrationPeriod,\n _maxMigrationPeriod\n );\n defaultMigrationPeriod = _defaultMigrationPeriod;\n minMigrationPeriod = _minMigrationPeriod;\n maxMigrationPeriod = _maxMigrationPeriod;\n }\n\n /**\n * @notice Wallet owner sets the addition security period for the wallet. Only the owner of wallet can call this function.\n * The addition security period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _additionSecurityPeriod Custom Addition Security Period for the wallet\n */\n function setAdditionSecurityPeriod(\n address _wallet,\n uint128 _additionSecurityPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _additionSecurityPeriod,\n minAdditionSecurityPeriod,\n maxAdditionSecurityPeriod\n );\n securityConfigs[_wallet]\n .additionSecurityPeriod = _additionSecurityPeriod;\n }\n\n /**\n * @notice Wallet owner sets the removal security period for the wallet. Only the owner of wallet can call this function.\n * The removal security period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _removalSecurityPeriod Custom Removal Security Period for the wallet\n */\n function setRemovalSecurityPeriod(\n address _wallet,\n uint128 _removalSecurityPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _removalSecurityPeriod,\n minRemovalSecurityPeriod,\n maxRemovalSecurityPeriod\n );\n securityConfigs[_wallet].removalSecurityPeriod = _removalSecurityPeriod;\n }\n\n /**\n * @notice Wallet owner sets the security window for the wallet. Only the owner of wallet can call this function.\n * The security window should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _securityWindow Custom Security Window for the wallet\n */\n function setSecurityWindow(\n address _wallet,\n uint128 _securityWindow\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _securityWindow,\n minSecurityWindow,\n maxSecurityWindow\n );\n securityConfigs[_wallet].securityWindow = _securityWindow;\n }\n\n /**\n * @notice Wallet owner sets the recovery period for the wallet. Only the owner of wallet can call this function.\n * The recovery period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _recoveryPeriod Custom recovery period for the wallet\n */\n function setRecoveryPeriod(\n address _wallet,\n uint128 _recoveryPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _recoveryPeriod,\n minRecoveryPeriod,\n maxRecoveryPeriod\n );\n securityConfigs[_wallet].recoveryPeriod = _recoveryPeriod;\n }\n\n /**\n * @notice Wallet owner sets the lock period for the wallet. Only the owner of wallet can call this function.\n * The lock period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _lockPeriod Custom Lock period for the wallet\n */\n function setLockPeriod(\n address _wallet,\n uint128 _lockPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(_lockPeriod, minLockPeriod, maxLockPeriod);\n securityConfigs[_wallet].lockPeriod = _lockPeriod;\n }\n\n /**\n * @notice Wallet owner sets the approval validation period for the wallet. Only the owner of wallet can call this function.\n * The approval validation period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _approvalValidationPeriod Custom approval validation period for the wallet\n */\n function setApprovalValidationPeriod(\n address _wallet,\n uint128 _approvalValidationPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _approvalValidationPeriod,\n minApprovalValidationPeriod,\n maxApprovalValidationPeriod\n );\n securityConfigs[_wallet]\n .approvalValidationPeriod = _approvalValidationPeriod;\n }\n\n /**\n * @notice Wallet owner sets the migration period for the wallet. Only the owner of wallet can call this function.\n * The migration period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _migrationPeriod Custom migration period for the wallet\n */\n\n function setMigrationPeriod(\n address _wallet,\n uint128 _migrationPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _migrationPeriod,\n minMigrationPeriod,\n maxMigrationPeriod\n );\n securityConfigs[_wallet].migrationPeriod = _migrationPeriod;\n }\n\n /**\n * @notice Returns the addition security period. Returns default value when custom addition security period is not set\n * @param _wallet Address of wallet\n * @return additionSecurityPeriod Addition Security Period of the given Barz account or wallet\n */\n function additionSecurityPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 additionSecurityPeriod)\n {\n additionSecurityPeriod = securityConfigs[_wallet]\n .additionSecurityPeriod;\n additionSecurityPeriod = (additionSecurityPeriod == 0)\n ? defaultAdditionSecurityPeriod\n : additionSecurityPeriod;\n }\n\n /**\n * @notice Returns the removal security period. Returns default value when custom removal security period is not set\n * @param _wallet Address of wallet\n * @return removalSecurityPeriod Removal Security Period of the given Barz account or wallet\n */\n function removalSecurityPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 removalSecurityPeriod)\n {\n removalSecurityPeriod = securityConfigs[_wallet].removalSecurityPeriod;\n removalSecurityPeriod = (removalSecurityPeriod == 0)\n ? defaultRemovalSecurityPeriod\n : removalSecurityPeriod;\n }\n\n /**\n * @notice Returns the security window. Returns default value when custom security window is not set\n * @param _wallet Address of wallet\n * @return securityWindow Security window of the given Barz account or wallet\n */\n function securityWindowOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 securityWindow)\n {\n securityWindow = securityConfigs[_wallet].securityWindow;\n securityWindow = (securityWindow == 0)\n ? defaultSecurityWindow\n : securityWindow;\n }\n\n /**\n * @notice Returns the recovery period. Returns default value when custom recovery period is not set\n * @param _wallet Address of wallet\n * @return recoveryPeriod Recovery Period of the given Barz account or wallet\n */\n function recoveryPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 recoveryPeriod)\n {\n recoveryPeriod = securityConfigs[_wallet].recoveryPeriod;\n recoveryPeriod = (recoveryPeriod == 0)\n ? defaultRecoveryPeriod\n : recoveryPeriod;\n }\n\n /**\n * @notice Returns the lock period. Returns default value when custom lock period is not set\n * @param _wallet Address of wallet\n * @return lockPeriod Lock Period of the given Barz account or wallet\n */\n function lockPeriodOf(\n address _wallet\n ) public view override onlyWallet(_wallet) returns (uint128 lockPeriod) {\n lockPeriod = securityConfigs[_wallet].lockPeriod;\n lockPeriod = (lockPeriod == 0) ? defaultLockPeriod : lockPeriod;\n }\n\n /**\n * @notice Returns the approval validation period. Returns default value when custom approval validation period is not set\n * @param _wallet Address of wallet\n * @return approvalValidationPeriod Approval Validation Period of the given Barz account or wallet\n */\n function approvalValidationPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityConfigs[_wallet]\n .approvalValidationPeriod;\n approvalValidationPeriod = (approvalValidationPeriod == 0)\n ? defaultApprovalValidationPeriod\n : approvalValidationPeriod;\n }\n\n /**\n * @notice Returns the migration period. Returns default value when custom migration period is not set\n * @param _wallet Address of wallet\n * @return migrationPeriod Migration Period of the given Barz account or wallet\n */\n function migrationPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 migrationPeriod)\n {\n migrationPeriod = securityConfigs[_wallet].migrationPeriod;\n migrationPeriod = (migrationPeriod == 0)\n ? defaultMigrationPeriod\n : migrationPeriod;\n }\n\n /**\n * @notice Validates if the period is smaller than the max period or bigger than the min period\n * @param _period Period to be checked\n * @param _minPeriod Minimum period\n * @param _maxPeriod Maximum period\n */\n function _validatePeriodBoundaries(\n uint128 _period,\n uint128 _minPeriod,\n uint128 _maxPeriod\n ) internal pure {\n if (_period >= _maxPeriod || _period <= _minPeriod)\n revert SecurityManager__OutOfBoundary();\n }\n}\n" + }, + "contracts/infrastructure/WhitelistStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {RemoteStorage} from \"./RemoteStorage.sol\";\n\n/**\n * @title Whitelist storage\n * @dev Maps addresses to the corresponsing array of whitelisted addresses for each of them.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract WhitelistStorage is RemoteStorage {\n /**\n * @dev Add the address to the whitelist storage\n * @param _wallet User wallet\n * @param _address Address to be whitelisted\n */\n function whitelistAddress(address _wallet, address _address) external {\n enforceWalletOrGuardianIfExists(_wallet);\n addAddress(_wallet, _address);\n }\n\n /**\n * @dev Removes the address from the whitelist storage\n * @param _wallet User wallet\n * @param _address Address to be removed from the whitelist\n */\n function blacklistAddress(address _wallet, address _address) external {\n enforceGuardianOrWallet(_wallet);\n removeAddress(_wallet, _address);\n }\n\n /**\n * @dev Returns whether the address exists in the whitelist storage, associated with the wallet\n * @param _wallet User wallet\n * @param _address Address to be whitelisted\n */\n function isWhitelisted(\n address _wallet,\n address _address\n ) external view returns (bool) {\n return exists(_wallet, _address);\n }\n\n /**\n * @dev Returns all whitelisted addresses associated with the wallet\n * @param _wallet User wallet\n */\n function getWhitelistedAddresses(\n address _wallet\n ) external view returns (address[] memory) {\n return getAddresses(_wallet);\n }\n}\n" + }, + "contracts/interfaces/ERC/IERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\n\npragma solidity 0.8.21;\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155Receiver {\n /**\n * @dev Handles the receipt of a single ERC1155 token type. This function is\n * called at the end of a `safeTransferFrom` after the balance has been updated.\n *\n * NOTE: To accept the transfer, this must return\n * `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n * (i.e. 0xf23a6e61, or its own function selector).\n *\n * @param operator The address which initiated the transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param id The ID of the token being transferred\n * @param value The amount of tokens being transferred\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n ) external returns (bytes4);\n\n /**\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\n * is called at the end of a `safeBatchTransferFrom` after the balances have\n * been updated.\n *\n * NOTE: To accept the transfer(s), this must return\n * `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n * (i.e. 0xbc197c81, or its own function selector).\n *\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "contracts/interfaces/ERC/IERC1271.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\ninterface IERC1271 {\n function isValidSignature(\n bytes32 hash,\n bytes memory signature\n ) external view returns (bytes4);\n}\n" + }, + "contracts/interfaces/ERC/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\ninterface IERC165 {\n /// @notice Query if a contract implements an interface\n /// @param interfaceId The interface identifier, as specified in ERC-165\n /// @dev Interface identification is specified in ERC-165. This function\n /// uses less than 30,000 gas.\n /// @return `true` if the contract implements `interfaceID` and\n /// `interfaceID` is not 0xffffffff, `false` otherwise\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/IERC173.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\n/// @title ERC-173 Contract Ownership Standard\n/// Note: the ERC-165 identifier for this interface is 0x7f5828d0\n/* is ERC165 */\ninterface IERC173 {\n /// @dev This emits when ownership of a contract changes.\n event OwnershipTransferred(\n address indexed previousOwner,\n address indexed newOwner\n );\n\n /// @notice Get the address of the owner\n /// @return owner_ The address of the owner.\n function owner() external view returns (address owner_);\n\n /// @notice Set the address of the new owner of the contract\n /// @dev Set _newOwner to address(0) to renounce any ownership.\n /// @param _newOwner The address of the new owner of the contract\n function transferOwnership(address _newOwner) external;\n}\n" + }, + "contracts/interfaces/ERC/IERC677Receiver.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\ninterface IERC677Receiver {\n function onTokenTransfer(\n address sender,\n uint value,\n bytes calldata data\n ) external pure returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155 is IERC165 {\n /**\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n */\n event TransferSingle(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256 id,\n uint256 value\n );\n\n /**\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n * transfers.\n */\n event TransferBatch(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\n\n /**\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n * `approved`.\n */\n event ApprovalForAll(\n address indexed account,\n address indexed operator,\n bool approved\n );\n\n /**\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n *\n * If an {URI} event was emitted for `id`, the standard\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n * returned by {IERC1155MetadataURI-uri}.\n */\n event URI(string value, uint256 indexed id);\n\n /**\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(\n address account,\n uint256 id\n ) external view returns (uint256);\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] calldata accounts,\n uint256[] calldata ids\n ) external view returns (uint256[] memory);\n\n /**\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n *\n * Emits an {ApprovalForAll} event.\n *\n * Requirements:\n *\n * - `operator` cannot be the caller.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n *\n * See {setApprovalForAll}.\n */\n function isApprovedForAll(\n address account,\n address operator\n ) external view returns (bool);\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes calldata data\n ) external;\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(\n address indexed owner,\n address indexed spender,\n uint256 value\n );\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` 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 amount) 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(\n address owner,\n address spender\n ) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the 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 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` 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(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(\n address spender,\n uint256 addedValue\n ) external returns (bool);\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(\n address spender,\n uint256 subtractedValue\n ) external returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(\n address indexed from,\n address indexed to,\n uint256 indexed tokenId\n );\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(\n address indexed owner,\n address indexed approved,\n uint256 indexed tokenId\n );\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(\n address indexed owner,\n address indexed operator,\n bool approved\n );\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(\n uint256 tokenId\n ) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(\n address owner,\n address operator\n ) external view returns (bool);\n}\n" + }, + "contracts/interfaces/IBarz.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Barz Interface\n * @dev Interface of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IBarz {\n error Barz__InitializationFailure();\n}\n" + }, + "contracts/interfaces/IBarzFactory.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Barz} from \"../Barz.sol\";\n\n/**\n * @title Barz Factory Interface\n * @dev Interface of contract to easily deploy Barz to a pre-computed address with a single call\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IBarzFactory {\n function createAccount(\n address verificationFacet,\n bytes calldata owner,\n uint256 salt\n ) external returns (Barz);\n\n function getAddress(\n address verificationFacet,\n bytes calldata owner,\n uint256 salt\n ) external view returns (address);\n\n function getBytecode(\n address accountFacet,\n address verificationFacet,\n address entryPoint,\n address facetRegistry,\n address defaultFallback,\n bytes memory ownerPublicKey\n ) external pure returns (bytes memory);\n\n function getCreationCode() external pure returns (bytes memory);\n}\n" + }, + "contracts/libraries/DefaultLibDiamond.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\n\nerror InitializationFunctionReverted(\n address _initializationContractAddress,\n bytes _calldata\n);\n\nlibrary DefaultLibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION =\n keccak256(\"trustwallet.barz.diamond.storage\");\n\n struct FacetAddressAndPosition {\n address facetAddress;\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\n }\n\n struct FacetFunctionSelectors {\n bytes4[] functionSelectors;\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\n }\n\n struct DiamondStorage {\n // maps function selector to the facet address and\n // the position of the selector in the facetFunctionSelectors.selectors array\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\n // maps facet addresses to function selectors\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\n // facet addresses\n address[] facetAddresses;\n // Used to query if a contract implements an interface.\n // Used to implement ERC-165.\n mapping(bytes4 => bool) supportedInterfaces;\n }\n\n function diamondStorage()\n internal\n pure\n returns (DiamondStorage storage ds)\n {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n event DiamondCut(\n IDiamondCut.FacetCut[] _diamondCut,\n address _init,\n bytes _calldata\n );\n\n // Internal function version of diamondCut\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n for (\n uint256 facetIndex;\n facetIndex < _diamondCut.length;\n facetIndex++\n ) {\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\n if (action == IDiamondCut.FacetCutAction.Add) {\n addFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\n replaceFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\n removeFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else {\n revert(\"LibDiamondCut: Incorrect FacetCutAction\");\n }\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Add facet can't be address(0)\"\n );\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n require(\n oldFacetAddress == address(0),\n \"LibDiamondCut: Can't add function that already exists\"\n );\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function replaceFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Replace facet can't be address(0)\"\n );\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n require(\n oldFacetAddress != _facetAddress,\n \"LibDiamondCut: Can't replace function with same facet\"\n );\n removeFunction(ds, oldFacetAddress, selector);\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function removeFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n // if function does not exist then do nothing and return\n require(\n _facetAddress == address(0),\n \"LibDiamondCut: Remove facet address must be address(0)\"\n );\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n removeFunction(ds, oldFacetAddress, selector);\n }\n }\n\n function addFacet(\n DiamondStorage storage ds,\n address _facetAddress\n ) internal {\n enforceHasContractCode(\n _facetAddress,\n \"LibDiamondCut: New facet has no code\"\n );\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds\n .facetAddresses\n .length;\n ds.facetAddresses.push(_facetAddress);\n }\n\n function addFunction(\n DiamondStorage storage ds,\n bytes4 _selector,\n uint96 _selectorPosition,\n address _facetAddress\n ) internal {\n ds\n .selectorToFacetAndPosition[_selector]\n .functionSelectorPosition = _selectorPosition;\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(\n _selector\n );\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\n }\n\n function removeFunction(\n DiamondStorage storage ds,\n address _facetAddress,\n bytes4 _selector\n ) internal {\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Can't remove function that doesn't exist\"\n );\n // an immutable function is a function defined directly in a diamond\n require(\n _facetAddress != address(this),\n \"LibDiamondCut: Can't remove immutable function\"\n );\n // replace selector with last selector, then delete last selector\n uint256 selectorPosition = ds\n .selectorToFacetAndPosition[_selector]\n .functionSelectorPosition;\n uint256 lastSelectorPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors\n .length - 1;\n // if not the same then replace _selector with lastSelector\n if (selectorPosition != lastSelectorPosition) {\n bytes4 lastSelector = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors[lastSelectorPosition];\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[\n selectorPosition\n ] = lastSelector;\n ds\n .selectorToFacetAndPosition[lastSelector]\n .functionSelectorPosition = uint96(selectorPosition);\n }\n // delete the last selector\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\n delete ds.selectorToFacetAndPosition[_selector];\n\n // if no more selectors for facet address then delete the facet address\n if (lastSelectorPosition == 0) {\n // replace facet address with last facet address and delete last facet address\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\n uint256 facetAddressPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .facetAddressPosition;\n if (facetAddressPosition != lastFacetAddressPosition) {\n address lastFacetAddress = ds.facetAddresses[\n lastFacetAddressPosition\n ];\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\n ds\n .facetFunctionSelectors[lastFacetAddress]\n .facetAddressPosition = facetAddressPosition;\n }\n ds.facetAddresses.pop();\n delete ds\n .facetFunctionSelectors[_facetAddress]\n .facetAddressPosition;\n }\n }\n\n function initializeDiamondCut(\n address _init,\n bytes memory _calldata\n ) internal {\n if (_init == address(0)) {\n return;\n }\n enforceHasContractCode(\n _init,\n \"LibDiamondCut: _init address has no code\"\n );\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length > 0) {\n // bubble up error\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(error)\n revert(add(32, error), returndata_size)\n }\n } else {\n revert InitializationFunctionReverted(_init, _calldata);\n }\n }\n }\n\n function enforceHasContractCode(\n address _contract,\n string memory _errorMessage\n ) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize > 0, _errorMessage);\n }\n}\n" + }, + "contracts/libraries/LibAppStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SafeCast} from \"@openzeppelin/contracts/utils/math/SafeCast.sol\";\nimport {IEntryPoint} from \"../aa-4337/interfaces/IEntryPoint.sol\";\nimport {IFacetRegistry} from \"../infrastructure/interfaces/IFacetRegistry.sol\";\n\n/*\n * @title App Storage\n * @dev App storage for Barz contract to prevent storage collision\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\n\nstruct Lock {\n uint64 release;\n bytes4 locker;\n}\n\nstruct InitializersStorage {\n // NOTE: initialized is a variable to make sure the initialization is only done once.\n uint8 signerInitialized;\n uint8 accountInitialized;\n uint8 restrictionsInitialized;\n}\n\nstruct AppStorage {\n mapping(uint256 => InitializersStorage) initStorage;\n uint8 signerMigration;\n bytes4 validateOwnerSignatureSelector;\n IEntryPoint entryPoint;\n IFacetRegistry facetRegistry;\n mapping(uint256 => Lock) locks;\n}\n\nlibrary LibAppStorage {\n error LibAppStorage__AccountAlreadyUninitialized();\n error LibAppStorage__AccountMustBeUninitialized();\n error LibAppStorage__SignerAlreadyUninitialized();\n error LibAppStorage__SignerMustBeUninitialized();\n\n function appStorage() internal pure returns (AppStorage storage ds) {\n assembly {\n ds.slot := 0\n }\n }\n\n function setSignerUninitialized() internal {\n AppStorage storage s = appStorage();\n if (1 != s.initStorage[0].signerInitialized) {\n revert LibAppStorage__SignerAlreadyUninitialized();\n }\n s.initStorage[0].signerInitialized = 0;\n }\n\n function getValidateOwnerSignatureSelector()\n internal\n view\n returns (bytes4 selector)\n {\n selector = appStorage().validateOwnerSignatureSelector;\n }\n\n function setValidateOwnerSignatureSelector(\n bytes4 _validateOwnerSignatureSelector\n ) internal {\n appStorage()\n .validateOwnerSignatureSelector = _validateOwnerSignatureSelector;\n }\n\n function enforceSignerInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].signerInitialized) {\n revert LibAppStorage__SignerMustBeUninitialized();\n }\n s.initStorage[0].signerInitialized = 1;\n }\n\n function enforceAccountInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].accountInitialized) {\n revert LibAppStorage__AccountMustBeUninitialized();\n }\n s.initStorage[0].accountInitialized = 1;\n }\n\n function initiateSignerMigration() internal {\n appStorage().signerMigration = 1;\n }\n\n function enforceSignerMigration() internal view {\n if (1 != appStorage().signerMigration) {\n revert LibAppStorage__AccountMustBeUninitialized();\n }\n }\n\n function finalizeSignerMigration() internal {\n appStorage().signerMigration = 0;\n }\n\n function setLock(uint256 _releaseAfter, bytes4 _locker) internal {\n appStorage().locks[0] = Lock(SafeCast.toUint64(_releaseAfter), _locker);\n }\n\n function enforceRestrictionsInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].restrictionsInitialized)\n revert LibAppStorage__SignerMustBeUninitialized();\n s.initStorage[0].restrictionsInitialized = 1;\n }\n\n function setRestrictionsUninitialized() internal {\n AppStorage storage s = appStorage();\n if (1 != s.initStorage[0].restrictionsInitialized)\n revert LibAppStorage__AccountAlreadyUninitialized();\n s.initStorage[0].restrictionsInitialized = 0;\n }\n}\n\ncontract BarzStorage {\n AppStorage internal s;\n modifier onlyWhenUnlocked() {\n require(\n uint64(block.timestamp) >= s.locks[0].release,\n \"Account Locked\"\n );\n _;\n }\n modifier onlyWhenLocked() {\n require(\n uint64(block.timestamp) < s.locks[0].release,\n \"Account Unlocked\"\n );\n _;\n }\n}\n" + }, + "contracts/libraries/LibDiamond.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\n\nerror InitializationFunctionReverted(\n address _initializationContractAddress,\n bytes _calldata\n);\n\nlibrary LibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION =\n keccak256(\"trustwallet.barz.diamond.storage\");\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\n bytes4(keccak256(\"verifyRestrictions(address,address,uint256,bytes)\"));\n struct DiamondStorage {\n // maps function selectors to the facets that execute the functions.\n // and maps the selectors to their position in the selectorSlots array.\n // func selector => address facet, selector position\n mapping(bytes4 => bytes32) facets;\n // array of slots of function selectors.\n // each slot holds 8 function selectors.\n mapping(uint256 => bytes32) selectorSlots;\n // The number of function selectors in selectorSlots\n uint16 selectorCount;\n // Used to query if a contract implements an interface.\n // Used to implement ERC-165.\n mapping(bytes4 => bool) supportedInterfaces;\n // Default Fallback Handler of the barz.\n IDiamondLoupe defaultFallbackHandler;\n }\n\n function diamondStorage()\n internal\n pure\n returns (DiamondStorage storage ds)\n {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n function enforceIsSelf() internal view {\n require(msg.sender == address(this), \"LibDiamond: Caller not self\");\n }\n\n event DiamondCut(\n IDiamondCut.FacetCut[] _diamondCut,\n address _init,\n bytes _calldata\n );\n\n bytes32 constant CLEAR_ADDRESS_MASK =\n bytes32(uint256(0xffffffffffffffffffffffff));\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\n\n // Internal function version of diamondCut\n // This code is almost the same as the external diamondCut,\n // except it is using 'Facet[] memory _diamondCut' instead of\n // 'Facet[] calldata _diamondCut'.\n // The code is duplicated to prevent copying calldata to memory which\n // causes an error for a two dimensional array.\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n DiamondStorage storage ds = diamondStorage();\n uint256 originalSelectorCount = ds.selectorCount;\n uint256 selectorCount = originalSelectorCount;\n bytes32 selectorSlot;\n // Check if last selector slot is not full\n // \"selectorCount & 7\" is a gas efficient modulo by eight \"selectorCount % 8\"\n if (selectorCount & 7 > 0) {\n // get last selectorSlot\n // \"selectorSlot >> 3\" is a gas efficient division by 8 \"selectorSlot / 8\"\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\n }\n // loop through diamond cut\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\n selectorCount,\n selectorSlot,\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].action,\n _diamondCut[facetIndex].functionSelectors\n );\n\n unchecked {\n facetIndex++;\n }\n }\n if (selectorCount != originalSelectorCount) {\n ds.selectorCount = uint16(selectorCount);\n }\n // If last selector slot is not full\n // \"selectorCount & 7\" is a gas efficient modulo by eight \"selectorCount % 8\"\n if (selectorCount & 7 > 0) {\n // \"selectorSlot >> 3\" is a gas efficient division by 8 \"selectorSlot / 8\"\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addReplaceRemoveFacetSelectors(\n uint256 _selectorCount,\n bytes32 _selectorSlot,\n address _newFacetAddress,\n IDiamondCut.FacetCutAction _action,\n bytes4[] memory _selectors\n ) internal returns (uint256, bytes32) {\n DiamondStorage storage ds = diamondStorage();\n require(\n _selectors.length > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n if (_action == IDiamondCut.FacetCutAction.Add) {\n enforceHasContractCode(\n _newFacetAddress,\n \"LibDiamondCut: Add facet has no code\"\n );\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n require(\n address(bytes20(oldFacet)) == address(0),\n \"LibDiamondCut: Can't add function that already exists\"\n );\n // add facet for selector\n ds.facets[selector] =\n bytes20(_newFacetAddress) |\n bytes32(_selectorCount);\n // \"_selectorCount & 7\" is a gas efficient modulo by eight \"_selectorCount % 8\"\n // \" << 5 is the same as multiplying by 32 ( * 32)\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\n // clear selector position in slot and add selector\n _selectorSlot =\n (_selectorSlot &\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\n (bytes32(selector) >> selectorInSlotPosition);\n // if slot is full then write it to storage\n if (selectorInSlotPosition == 224) {\n // \"_selectorSlot >> 3\" is a gas efficient division by 8 \"_selectorSlot / 8\"\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\n _selectorSlot = 0;\n }\n _selectorCount++;\n\n unchecked {\n selectorIndex++;\n }\n }\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\n enforceHasContractCode(\n _newFacetAddress,\n \"LibDiamondCut: Replace facet has no code\"\n );\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n address oldFacetAddress = address(bytes20(oldFacet));\n // only useful if immutable functions exist\n require(\n oldFacetAddress != address(this),\n \"LibDiamondCut: Can't replace immutable function\"\n );\n require(\n oldFacetAddress != _newFacetAddress,\n \"LibDiamondCut: Can't replace function with same function\"\n );\n require(\n oldFacetAddress != address(0),\n \"LibDiamondCut: Can't replace function that doesn't exist\"\n );\n // replace old facet address\n ds.facets[selector] =\n (oldFacet & CLEAR_ADDRESS_MASK) |\n bytes20(_newFacetAddress);\n\n unchecked {\n selectorIndex++;\n }\n }\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\n require(\n _newFacetAddress == address(0),\n \"LibDiamondCut: Remove facet address must be address(0)\"\n );\n // \"_selectorCount >> 3\" is a gas efficient division by 8 \"_selectorCount / 8\"\n uint256 selectorSlotCount = _selectorCount >> 3;\n // \"_selectorCount & 7\" is a gas efficient modulo by eight \"_selectorCount % 8\"\n uint256 selectorInSlotIndex = _selectorCount & 7;\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n if (_selectorSlot == 0) {\n // get last selectorSlot\n selectorSlotCount--;\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\n selectorInSlotIndex = 7;\n } else {\n selectorInSlotIndex--;\n }\n bytes4 lastSelector;\n uint256 oldSelectorsSlotCount;\n uint256 oldSelectorInSlotPosition;\n // adding a block here prevents stack too deep error\n {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n require(\n address(bytes20(oldFacet)) != address(0),\n \"LibDiamondCut: Can't remove function that doesn't exist\"\n );\n // only useful if immutable functions exist\n require(\n address(bytes20(oldFacet)) != address(this),\n \"LibDiamondCut: Can't remove immutable function\"\n );\n // replace selector with last selector in ds.facets\n // gets the last selector\n // \" << 5 is the same as multiplying by 32 ( * 32)\n lastSelector = bytes4(\n _selectorSlot << (selectorInSlotIndex << 5)\n );\n if (lastSelector != selector) {\n // update last selector slot position info\n ds.facets[lastSelector] =\n (oldFacet & CLEAR_ADDRESS_MASK) |\n bytes20(ds.facets[lastSelector]);\n }\n delete ds.facets[selector];\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\n // \"oldSelectorCount >> 3\" is a gas efficient division by 8 \"oldSelectorCount / 8\"\n oldSelectorsSlotCount = oldSelectorCount >> 3;\n // \"oldSelectorCount & 7\" is a gas efficient modulo by eight \"oldSelectorCount % 8\"\n // \" << 5 is the same as multiplying by 32 ( * 32)\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\n }\n if (oldSelectorsSlotCount != selectorSlotCount) {\n bytes32 oldSelectorSlot = ds.selectorSlots[\n oldSelectorsSlotCount\n ];\n // clears the selector we are deleting and puts the last selector in its place.\n oldSelectorSlot =\n (oldSelectorSlot &\n ~(CLEAR_SELECTOR_MASK >>\n oldSelectorInSlotPosition)) |\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\n // update storage with the modified slot\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\n } else {\n // clears the selector we are deleting and puts the last selector in its place.\n _selectorSlot =\n (_selectorSlot &\n ~(CLEAR_SELECTOR_MASK >>\n oldSelectorInSlotPosition)) |\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\n }\n if (selectorInSlotIndex == 0) {\n delete ds.selectorSlots[selectorSlotCount];\n _selectorSlot = 0;\n }\n\n unchecked {\n selectorIndex++;\n }\n }\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\n } else {\n revert(\"LibDiamondCut: Incorrect FacetCutAction\");\n }\n return (_selectorCount, _selectorSlot);\n }\n\n function initializeDiamondCut(\n address _init,\n bytes memory _calldata\n ) internal {\n if (_init == address(0)) {\n return;\n }\n enforceHasContractCode(\n _init,\n \"LibDiamondCut: _init address has no code\"\n );\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length > 0) {\n // bubble up error\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(error)\n revert(add(32, error), returndata_size)\n }\n } else {\n revert InitializationFunctionReverted(_init, _calldata);\n }\n }\n }\n\n function enforceHasContractCode(\n address _contract,\n string memory _errorMessage\n ) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize > 0, _errorMessage);\n }\n\n function restrictionsFacet() internal view returns (address facetAddress_) {\n facetAddress_ = address(\n bytes20(\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\n )\n );\n }\n}\n" + }, + "contracts/libraries/LibFacetStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Storage\n * @dev Storage contract to store each facets variables with diamond storage\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\n\nstruct Secp256k1VerificationStorage {\n address signer;\n}\n\nstruct Secp256r1VerificationStorage {\n uint256[2] q;\n}\n\nstruct GuardianStorage {\n mapping(bytes32 => uint256) pending;\n mapping(uint8 => StorageConfig) configs;\n}\n\nstruct Info {\n bool exists;\n uint128 index;\n}\n\nstruct StorageConfig {\n address[] addresses;\n mapping(address => Info) info;\n}\n\nstruct RecoveryConfig {\n bytes recoveryPublicKey;\n uint64 executeAfter;\n}\n\nstruct ApprovalConfig {\n bool isApproved;\n uint64 validUntil;\n}\n\nstruct RecoveryApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isNewOwnerApproved;\n}\n\nstruct RecoveryStorage {\n mapping(uint8 => RecoveryConfig) recoveryConfigs;\n mapping(uint8 => RecoveryApprovalConfig) recoveryApprovalConfigs;\n uint128 nonce;\n}\n\nstruct RestrictionsStorage {\n address[] restrictions;\n mapping(address => bool) exists;\n}\n\nstruct SignatureMigrationConfig {\n bytes migrationPublicKey;\n address migrationVerificationFacet;\n bytes4[] migrationSelectors;\n uint64 migrateAfter;\n}\n\nstruct SignatureMigrationApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isMigrationApproved;\n}\n\nstruct SignatureMigrationStorage {\n mapping(uint8 => SignatureMigrationConfig) migrationConfigs;\n mapping(uint8 => SignatureMigrationApprovalConfig) migrationApprovalConfigs;\n uint128 nonce;\n}\n\nstruct DiamondCutApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isDiamondCutApproved;\n}\n\nstruct DiamondCutStorage {\n mapping(uint8 => DiamondCutApprovalConfig) diamondCutApprovalConfigs;\n uint128 nonce;\n}\n\nstruct LockStorage {\n uint128 nonce;\n}\n\nlibrary LibFacetStorage {\n bytes32 constant K1_STORAGE_POSITION =\n keccak256(\n \"v0.trustwallet.diamond.storage.Secp256k1VerificationStorage\"\n );\n bytes32 constant R1_STORAGE_POSITION =\n keccak256(\n \"v0.trustwallet.diamond.storage.Secp256r1VerificationStorage\"\n );\n bytes32 constant GUARDIAN_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.GuardianStorage\");\n bytes32 constant RECOVERY_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.RecoveryStorage\");\n bytes32 constant RESTRICTION_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.RestrictionsStorage\");\n bytes32 constant MIGRATION_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.SignatureMigrationStorage\");\n bytes32 constant DIAMONDCUT_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.DiamondCutStorage\");\n bytes32 constant LOCK_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.LockStorage\");\n\n function k1Storage()\n internal\n pure\n returns (Secp256k1VerificationStorage storage ds)\n {\n bytes32 storagePosition = K1_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function r1Storage()\n internal\n pure\n returns (Secp256r1VerificationStorage storage ds)\n {\n bytes32 storagePosition = R1_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function guardianStorage()\n internal\n pure\n returns (GuardianStorage storage ds)\n {\n bytes32 storagePosition = GUARDIAN_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function recoveryStorage()\n internal\n pure\n returns (RecoveryStorage storage ds)\n {\n bytes32 storagePosition = RECOVERY_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function restrictionsStorage()\n internal\n pure\n returns (RestrictionsStorage storage ds)\n {\n bytes32 storagePosition = RESTRICTION_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function migrationStorage()\n internal\n pure\n returns (SignatureMigrationStorage storage ds)\n {\n bytes32 storagePosition = MIGRATION_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function diamondCutStorage()\n internal\n pure\n returns (DiamondCutStorage storage ds)\n {\n bytes32 storagePosition = DIAMONDCUT_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function lockStorage() internal pure returns (LockStorage storage ds) {\n bytes32 storagePosition = LOCK_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n}\n" + }, + "contracts/libraries/LibGuardian.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibFacetStorage, StorageConfig} from \"./LibFacetStorage.sol\";\n\n/**\n * @title LibGuardian\n * @dev Internal Library to provide utility feature for Guardians stored in Guardian Facet Storage\n * @author David Yongjun Kim (@Powerstream3604)\n */\nlibrary LibGuardian {\n function majorityOfGuardians()\n internal\n view\n returns (uint256 guardianNumber)\n {\n uint256 guardianLength = guardianCount();\n guardianNumber = (guardianLength == 0) ? 0 : guardianLength / 2 + 1;\n }\n\n function isGuardian(address _guardian) internal view returns (bool) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n return config.info[_guardian].exists;\n }\n\n function guardianCount() internal view returns (uint256) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n return config.addresses.length;\n }\n\n function getGuardians() internal view returns (address[] memory) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n address[] memory addresses = new address[](config.addresses.length);\n uint256 addressesLen = config.addresses.length;\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n return addresses;\n }\n}\n" + }, + "contracts/libraries/LibLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {LibDiamond} from \"./LibDiamond.sol\";\n\n/**\n * @title LibLoupe\n * @dev Internal Library to provide utility feature for reading the state of diamond facets\n * @author David Yongjun Kim (@Powerstream3604)\n */\nlibrary LibLoupe {\n /// @notice Gets all facets and their selectors.\n /// @return facets_ Facet\n function facets()\n internal\n view\n returns (IDiamondLoupe.Facet[] memory facets_)\n {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facets_ = new IDiamondLoupe.Facet[](ds.selectorCount);\n uint16[] memory numFacetSelectors = new uint16[](ds.selectorCount);\n uint256 numFacets;\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facetAddress_ = address(bytes20(ds.facets[selector]));\n bool continueLoop;\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n if (facets_[facetIndex].facetAddress == facetAddress_) {\n facets_[facetIndex].functionSelectors[\n numFacetSelectors[facetIndex]\n ] = selector;\n // probably will never have more than 256 functions from one facet contract\n require(numFacetSelectors[facetIndex] < 255);\n numFacetSelectors[facetIndex]++;\n continueLoop = true;\n break;\n }\n }\n if (continueLoop) {\n continue;\n }\n facets_[numFacets].facetAddress = facetAddress_;\n facets_[numFacets].functionSelectors = new bytes4[](\n ds.selectorCount\n );\n facets_[numFacets].functionSelectors[0] = selector;\n numFacetSelectors[numFacets] = 1;\n numFacets++;\n }\n }\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n uint256 numSelectors = numFacetSelectors[facetIndex];\n bytes4[] memory selectors = facets_[facetIndex].functionSelectors;\n // setting the number of selectors\n assembly {\n mstore(selectors, numSelectors)\n }\n }\n // setting the number of facets\n assembly {\n mstore(facets_, numFacets)\n }\n }\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n /// @return _facetFunctionSelectors The selectors associated with a facet address.\n function facetFunctionSelectors(\n address _facet\n ) internal view returns (bytes4[] memory _facetFunctionSelectors) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n uint256 numSelectors;\n _facetFunctionSelectors = new bytes4[](ds.selectorCount);\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facet = address(bytes20(ds.facets[selector]));\n if (_facet == facet) {\n _facetFunctionSelectors[numSelectors] = selector;\n numSelectors++;\n }\n }\n }\n // Set the number of selectors in the array\n assembly {\n mstore(_facetFunctionSelectors, numSelectors)\n }\n }\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses()\n internal\n view\n returns (address[] memory facetAddresses_)\n {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facetAddresses_ = new address[](ds.selectorCount);\n uint256 numFacets;\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facetAddress_ = address(bytes20(ds.facets[selector]));\n bool continueLoop;\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n if (facetAddress_ == facetAddresses_[facetIndex]) {\n continueLoop = true;\n break;\n }\n }\n if (continueLoop) {\n continue;\n }\n facetAddresses_[numFacets] = facetAddress_;\n numFacets++;\n }\n }\n // Set the number of facet addresses in the array\n assembly {\n mstore(facetAddresses_, numFacets)\n }\n }\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(\n bytes4 _functionSelector\n ) internal view returns (address facetAddress_) {\n facetAddress_ = address(\n bytes20(LibDiamond.diamondStorage().facets[_functionSelector])\n );\n }\n}\n" + }, + "contracts/libraries/LibMultiSigStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Multi-sig Storage\n * @dev Storage contract for storing Multi-sig Facet variables in diamond storage pattern\n * @author David Yongjun Kim (@Powerstream3604)\n */\n\nstruct MultiSigStorage {\n mapping(address => address) owners;\n mapping(uint256 => mapping(address => mapping(bytes32 => uint256))) approvedHashes;\n uint256 ownerCount;\n uint256 threshold;\n uint256 counter;\n}\n\nlibrary LibMultiSigStorage {\n function multisigStorage()\n internal\n pure\n returns (MultiSigStorage storage ds)\n {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.MultiSigStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n}\n" + }, + "contracts/libraries/LibRecoverSpender.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title RecoverSpender\n * @dev Library to determine the action and spender of calldata\n * @author Ruslan Serebriakov (@rsrbk)\n */\nlibrary LibRecoverSpender {\n // ERC20, ERC721 & ERC1155 transfers & approvals\n bytes4 private constant ERC20_TRANSFER =\n bytes4(keccak256(\"transfer(address,uint256)\"));\n bytes4 private constant ERC20_APPROVE =\n bytes4(keccak256(\"approve(address,uint256)\"));\n bytes4 private constant ERC20_INCREASE_ALLOWANCE =\n bytes4(keccak256(\"increaseAllowance(address,uint256)\"));\n bytes4 private constant ERC20_DECREASE_ALLOWANCE =\n bytes4(keccak256(\"decreaseAllowance(address,uint256)\"));\n bytes4 private constant ERC721_SET_APPROVAL_FOR_ALL =\n bytes4(keccak256(\"setApprovalForAll(address,bool)\"));\n bytes4 private constant ERC721_TRANSFER_FROM =\n bytes4(keccak256(\"transferFrom(address,address,uint256)\"));\n bytes4 private constant ERC721_SAFE_TRANSFER_FROM =\n bytes4(keccak256(\"safeTransferFrom(address,address,uint256)\"));\n bytes4 private constant ERC721_SAFE_TRANSFER_FROM_BYTES =\n bytes4(keccak256(\"safeTransferFrom(address,address,uint256,bytes)\"));\n bytes4 private constant ERC1155_SAFE_TRANSFER_FROM =\n bytes4(\n keccak256(\"safeTransferFrom(address,address,uint256,uint256,bytes)\")\n );\n bytes4 private constant ERC1155_SAFE_BATCH_TRANSFER_FROM =\n bytes4(\n keccak256(\n \"safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)\"\n )\n );\n\n /**\n * @notice Helper method to recover the spender from a contract call.\n * The method returns the contract unless the call is to a standard method of a ERC20/ERC721/ERC1155 token\n * in which case the spender is recovered from the data.\n * @param _to The target contract.\n * @param _data The data payload.\n */\n function _recover(\n address _to,\n bytes memory _data\n ) internal pure returns (address spender) {\n if (_data.length >= 68) {\n bytes4 methodId;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n methodId := mload(add(_data, 0x20))\n }\n if (\n methodId == ERC20_TRANSFER ||\n methodId == ERC20_APPROVE ||\n methodId == ERC20_INCREASE_ALLOWANCE ||\n methodId == ERC20_DECREASE_ALLOWANCE ||\n methodId == ERC721_SET_APPROVAL_FOR_ALL\n ) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n spender := mload(add(_data, 0x24))\n }\n return spender;\n }\n if (\n methodId == ERC721_TRANSFER_FROM ||\n methodId == ERC721_SAFE_TRANSFER_FROM ||\n methodId == ERC721_SAFE_TRANSFER_FROM_BYTES ||\n methodId == ERC1155_SAFE_TRANSFER_FROM ||\n methodId == ERC1155_SAFE_BATCH_TRANSFER_FROM\n ) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n spender := mload(add(_data, 0x44))\n }\n return spender;\n }\n }\n\n spender = _to;\n }\n}\n" + }, + "contracts/libraries/LibUtils.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\n\nlibrary LibUtils {\n // Internal utility functions\n function mergeArrays(\n bytes4[] memory _array1,\n bytes4[] memory _array2\n ) internal pure returns (bytes4[] memory) {\n uint256 length1 = _array1.length;\n uint256 length2 = _array2.length;\n bytes4[] memory mergedArray = new bytes4[](length1 + length2);\n\n for (uint256 i; i < length1; ) {\n mergedArray[i] = _array1[i];\n unchecked {\n ++i;\n }\n }\n\n for (uint256 i; i < length2; ) {\n mergedArray[length1 + i] = _array2[i];\n unchecked {\n ++i;\n }\n }\n\n return mergedArray;\n }\n\n function removeFacetElement(\n IDiamondLoupe.Facet[] memory _facets,\n uint256 _index\n ) internal pure returns (IDiamondLoupe.Facet[] memory) {\n require(_index < _facets.length, \"Invalid index\");\n require(_facets.length != 0, \"Invalid array\");\n\n // Create a new array with a length of `_facets.length - 1`\n IDiamondLoupe.Facet[] memory newArray = new IDiamondLoupe.Facet[](\n _facets.length - 1\n );\n uint256 newArrayLength = newArray.length;\n // Iterate over the original array, skipping the element at the specified `index`\n for (uint256 i; i < newArrayLength; ) {\n if (i < _index) {\n newArray[i] = _facets[i];\n } else {\n newArray[i] = _facets[i + 1];\n }\n unchecked {\n ++i;\n }\n }\n\n return newArray;\n }\n\n function removeElement(\n bytes4[] memory _array,\n uint256 _index\n ) internal pure returns (bytes4[] memory) {\n require(_index < _array.length, \"Invalid index\");\n require(_array.length != 0, \"Invalid array\");\n\n bytes4[] memory newArray = new bytes4[](_array.length - 1);\n uint256 newArrayLength = newArray.length;\n for (uint256 i; i < newArrayLength; ) {\n if (i < _index) {\n newArray[i] = _array[i];\n } else {\n newArray[i] = _array[i + 1];\n }\n unchecked {\n ++i;\n }\n }\n\n return newArray;\n }\n\n function setValue(\n bytes4[] memory _keys,\n address[] memory _values,\n bytes4 _key,\n address _value\n ) internal pure returns (bytes4[] memory, address[] memory) {\n uint256 index = findIndex(_keys, _key);\n uint256 keysLength = _keys.length;\n if (index < keysLength) {\n _values[index] = _value;\n } else {\n // Create new storage arrays\n bytes4[] memory newKeys = new bytes4[](keysLength + 1);\n address[] memory newValues = new address[](_values.length + 1);\n\n // Copy values to the new storage arrays\n for (uint256 i; i < keysLength; ) {\n newKeys[i] = _keys[i];\n newValues[i] = _values[i];\n\n unchecked {\n ++i;\n }\n }\n\n // Add the new key-value pair\n newKeys[keysLength] = _key;\n newValues[_values.length] = _value;\n\n return (newKeys, newValues);\n }\n\n // If the key already exists, return the original arrays\n return (_keys, _values);\n }\n\n function getValue(\n bytes4[] memory _keys,\n address[] memory _values,\n bytes4 _key\n ) internal pure returns (address) {\n uint256 index = findIndex(_keys, _key);\n if (index >= _keys.length) return address(0);\n\n return _values[index];\n }\n\n function findIndex(\n bytes4[] memory _keys,\n bytes4 _key\n ) internal pure returns (uint256) {\n uint256 keysLength = _keys.length;\n for (uint256 i; i < keysLength; ) {\n if (_keys[i] == _key) {\n return i;\n }\n unchecked {\n ++i;\n }\n }\n return keysLength;\n }\n}\n" + }, + "contracts/restrictions/IRestriction.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Interface for restrictions\n * @dev Restriction is a contract which decides whether to approve a certain kind of transaction, based on its internal logic.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface IRestriction {\n /**\n * @dev Based on restriction's internal logic, it should accept or reject a certain transaction.\n * @param from The address of the sender, that will be signing the transaction.\n * @param to The receiving address.\n * @param value Amount of ETH to transfer from sender to recipient.\n * @param _calldata Optional field to include arbitrary data.\n * @return bool value for whether the check is passed\n */\n function check(\n address from,\n address to,\n uint256 value,\n bytes calldata _calldata\n ) external returns (bool);\n}\n" + }, + "contracts/restrictions/WhitelistRestriction.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibRecoverSpender} from \"../libraries/LibRecoverSpender.sol\";\nimport {WhitelistStorage} from \"../infrastructure/WhitelistStorage.sol\";\nimport {IRestriction} from \"./IRestriction.sol\";\n\n/**\n * @title Whitelist Restriction\n * @dev This restriction defines a list of accepted addresses and denies any interaction with addresses outside of it.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract WhitelistRestriction is IRestriction {\n WhitelistStorage public immutable whitelistStorage;\n\n constructor(WhitelistStorage _whitelistStorage) {\n whitelistStorage = _whitelistStorage;\n }\n\n /**\n * @notice Helper method to recover the spender from a contract call.\n * The method returns the contract unless the call is to a standard method of a ERC20/ERC721/ERC1155 token\n * in which case the spender is recovered from the data.\n * @param _to The target contract.\n * @param _data The data payload.\n */\n function recoverSpender(\n address _to,\n bytes memory _data\n ) public pure returns (address spender) {\n return LibRecoverSpender._recover(_to, _data);\n }\n\n /*\n * @dev IRestriction's implementation. It will allow transaction if the sender is whitelisted, or user, or the whitelist storage.\n * @param _from The address of the sender, that will be signing the transaction.\n * @param _to The receiving address.\n * @param _calldata Optional field to include arbitrary data.\n * @return result value for whether the check is passed\n */\n function check(\n address _from,\n address _to,\n uint256 /*_value*/,\n bytes calldata _calldata\n ) external view override returns (bool result) {\n return\n whitelistStorage.isWhitelisted(\n _from,\n LibRecoverSpender._recover(_to, _calldata)\n ) ||\n _to == address(whitelistStorage) ||\n _to == msg.sender;\n }\n}\n" + }, + "contracts/test/Counter.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\ncontract TestCounter {\n int private count = 0;\n\n function incrementCounter() public {\n count += 1;\n }\n\n function decrementCounter() public {\n count -= 1;\n }\n\n function getCount() public view returns (int) {\n return count;\n }\n}\n" + }, + "contracts/test/TestERC1155.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC1155/ERC1155.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\n\ncontract TestERC1155 is ERC1155 {\n using Counters for Counters.Counter;\n\n Counters.Counter private _tokenIds;\n\n constructor() ERC1155(\"\") {}\n\n function mint(address account, uint256 amount) external {\n uint256 tokenId = _getNextTokenId();\n _mint(account, tokenId, amount, \"\");\n }\n\n function mintBatch(\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes memory data\n ) external {\n require(\n ids.length == amounts.length,\n \"TestERC1155: arrays length mismatch\"\n );\n\n _mintBatch(to, ids, amounts, data);\n }\n\n function _getNextTokenId() private returns (uint256) {\n _tokenIds.increment();\n return _tokenIds.current();\n }\n}\n" + }, + "contracts/test/TestERC777.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC777/ERC777.sol\";\n\ncontract TestERC777 is ERC777 {\n constructor(\n address[] memory _operators\n ) ERC777(\"TestERC777\", \"TERC777\", _operators) {}\n\n function mint(address account, uint256 amount) external {\n _mint(account, amount, \"\", \"\");\n }\n}\n" + }, + "contracts/test/TestInvalidSecp256k1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IVerificationFacet} from \"../facets/interfaces/IVerificationFacet.sol\";\nimport {IERC1271} from \"../interfaces/ERC/IERC1271.sol\";\nimport {AppStorage, LibAppStorage, BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {LibFacetStorage, Secp256k1VerificationStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {UserOperation} from \"../aa-4337/interfaces/UserOperation.sol\";\n\n/**\n * @title Test Secp256k1 verification facet\n * @dev Default Ethereum's elliptic curve\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract TestInvalidSecp256k1VerificationFacet is BarzStorage, IERC1271 {\n using ECDSA for bytes32;\n error Secp256k1VerificationFacet__InvalidSignerLength();\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n\n event SignerUninitialized();\n\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n }\n\n // THIS INVALID FACET DOES NOT INCLUDE initializeSigner()\n // THIS FACET IS USED TO TEST WHEN initializeSigner() DOESN'T EXIST IN FACET\n\n function uninitializeSigner() external returns (uint256 uninitSuccess) {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view returns (uint256 validationData) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n return validateSignature(userOp, userOpHash, k1Storage.signer);\n }\n\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n address signer\n ) public pure returns (uint256) {\n bytes32 hash = userOpHash.toEthSignedMessageHash();\n if (signer != hash.recover(userOp.signature)) return 1;\n return 0;\n }\n\n // This is REMOVED for testing purpose\n function validateOwnerSignatureSelector() public pure returns (bytes4) {\n // return this.validateOwnerSignature.selector;\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n function owner() public view returns (bytes memory) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n return abi.encodePacked(k1Storage.signer);\n }\n\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure returns (bool) {\n return (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (_hash.recover(_signature) ==\n LibFacetStorage.k1Storage().signer)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n}\n" + }, + "contracts/test/TestNFT.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\n\ncontract TestNFT is ERC721 {\n using Counters for Counters.Counter;\n Counters.Counter private currentTokenId;\n\n constructor() ERC721(\"TestNFT\", \"TNFT\") {}\n\n function mint(address recipient) public returns (uint256) {\n currentTokenId.increment();\n uint256 newItemId = currentTokenId.current();\n _safeMint(recipient, newItemId);\n return newItemId;\n }\n}\n" + }, + "contracts/test/TestToken.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract TestToken is ERC20 {\n constructor()\n // solhint-disable-next-line no-empty-blocks\n ERC20(\"TST\", \"TestToken\")\n {}\n\n function mint(address sender, uint256 amount) external {\n _mint(sender, amount);\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 999999 + }, + "evmVersion": "paris", + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/deployments/arbitrum/solcInputs/4356503edd8ae34e73cb6dd1c8e2fc8a.json b/deployments/arbitrum/solcInputs/4356503edd8ae34e73cb6dd1c8e2fc8a.json new file mode 100644 index 0000000..db88715 --- /dev/null +++ b/deployments/arbitrum/solcInputs/4356503edd8ae34e73cb6dd1c8e2fc8a.json @@ -0,0 +1,354 @@ +{ + "language": "Solidity", + "sources": { + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby disabling any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable2Step.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./Ownable.sol\";\n\n/**\n * @dev Contract module which provides access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership} and {acceptOwnership}.\n *\n * This module is used through inheritance. It will make available all functions\n * from parent (Ownable).\n */\nabstract contract Ownable2Step is Ownable {\n address private _pendingOwner;\n\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Returns the address of the pending owner.\n */\n function pendingOwner() public view virtual returns (address) {\n return _pendingOwner;\n }\n\n /**\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual override onlyOwner {\n _pendingOwner = newOwner;\n emit OwnershipTransferStarted(owner(), newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual override {\n delete _pendingOwner;\n super._transferOwnership(newOwner);\n }\n\n /**\n * @dev The new owner accepts the ownership transfer.\n */\n function acceptOwnership() public virtual {\n address sender = _msgSender();\n require(pendingOwner() == sender, \"Ownable2Step: caller is not the new owner\");\n _transferOwnership(sender);\n }\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC1271.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC1271 standard signature validation method for\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\n *\n * _Available since v4.1._\n */\ninterface IERC1271 {\n /**\n * @dev Should return whether the signature provided is valid for the provided data\n * @param hash Hash of the data to be signed\n * @param signature Signature byte array associated with _data\n */\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\n}\n" + }, + "@openzeppelin/contracts/security/ReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor() {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n _nonReentrantBefore();\n _;\n _nonReentrantAfter();\n }\n\n function _nonReentrantBefore() private {\n // On the first call to nonReentrant, _status will be _NOT_ENTERED\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n }\n\n function _nonReentrantAfter() private {\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Returns true if the reentrancy guard is currently set to \"entered\", which indicates there is a\n * `nonReentrant` function in the call stack.\n */\n function _reentrancyGuardEntered() internal view returns (bool) {\n return _status == _ENTERED;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/ERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/ERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC1155.sol\";\nimport \"./IERC1155Receiver.sol\";\nimport \"./extensions/IERC1155MetadataURI.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of the basic standard multi-token.\n * See https://eips.ethereum.org/EIPS/eip-1155\n * Originally based on code by Enjin: https://github.com/enjin/erc-1155\n *\n * _Available since v3.1._\n */\ncontract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {\n using Address for address;\n\n // Mapping from token ID to account balances\n mapping(uint256 => mapping(address => uint256)) private _balances;\n\n // Mapping from account to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json\n string private _uri;\n\n /**\n * @dev See {_setURI}.\n */\n constructor(string memory uri_) {\n _setURI(uri_);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return\n interfaceId == type(IERC1155).interfaceId ||\n interfaceId == type(IERC1155MetadataURI).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC1155MetadataURI-uri}.\n *\n * This implementation returns the same URI for *all* token types. It relies\n * on the token type ID substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * Clients calling this function must replace the `\\{id\\}` substring with the\n * actual token type ID.\n */\n function uri(uint256) public view virtual override returns (string memory) {\n return _uri;\n }\n\n /**\n * @dev See {IERC1155-balanceOf}.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {\n require(account != address(0), \"ERC1155: address zero is not a valid owner\");\n return _balances[id][account];\n }\n\n /**\n * @dev See {IERC1155-balanceOfBatch}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] memory accounts,\n uint256[] memory ids\n ) public view virtual override returns (uint256[] memory) {\n require(accounts.length == ids.length, \"ERC1155: accounts and ids length mismatch\");\n\n uint256[] memory batchBalances = new uint256[](accounts.length);\n\n for (uint256 i = 0; i < accounts.length; ++i) {\n batchBalances[i] = balanceOf(accounts[i], ids[i]);\n }\n\n return batchBalances;\n }\n\n /**\n * @dev See {IERC1155-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC1155-isApprovedForAll}.\n */\n function isApprovedForAll(address account, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[account][operator];\n }\n\n /**\n * @dev See {IERC1155-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n _safeTransferFrom(from, to, id, amount, data);\n }\n\n /**\n * @dev See {IERC1155-safeBatchTransferFrom}.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n _safeBatchTransferFrom(from, to, ids, amounts, data);\n }\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n\n emit TransferSingle(operator, from, to, id, amount);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n for (uint256 i = 0; i < ids.length; ++i) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n }\n\n emit TransferBatch(operator, from, to, ids, amounts);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\n\n _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);\n }\n\n /**\n * @dev Sets a new URI for all token types, by relying on the token type ID\n * substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * By this mechanism, any occurrence of the `\\{id\\}` substring in either the\n * URI or any of the amounts in the JSON file at said URI will be replaced by\n * clients with the token type ID.\n *\n * For example, the `https://token-cdn-domain/\\{id\\}.json` URI would be\n * interpreted by clients as\n * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`\n * for token type ID 0x4cce0.\n *\n * See {uri}.\n *\n * Because these URIs cannot be meaningfully represented by the {URI} event,\n * this function emits no events.\n */\n function _setURI(string memory newuri) internal virtual {\n _uri = newuri;\n }\n\n /**\n * @dev Creates `amount` tokens of token type `id`, and assigns them to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _mint(address to, uint256 id, uint256 amount, bytes memory data) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _balances[id][to] += amount;\n emit TransferSingle(operator, address(0), to, id, amount);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n for (uint256 i = 0; i < ids.length; i++) {\n _balances[ids[i]][to] += amounts[i];\n }\n\n emit TransferBatch(operator, address(0), to, ids, amounts);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);\n }\n\n /**\n * @dev Destroys `amount` tokens of token type `id` from `from`\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `from` must have at least `amount` tokens of token type `id`.\n */\n function _burn(address from, uint256 id, uint256 amount) internal virtual {\n require(from != address(0), \"ERC1155: burn from the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n\n emit TransferSingle(operator, from, address(0), id, amount);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n */\n function _burnBatch(address from, uint256[] memory ids, uint256[] memory amounts) internal virtual {\n require(from != address(0), \"ERC1155: burn from the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n\n for (uint256 i = 0; i < ids.length; i++) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n }\n\n emit TransferBatch(operator, from, address(0), ids, amounts);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {\n require(owner != operator, \"ERC1155: setting approval status for self\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning, as well as batched variants.\n *\n * The same hook is called on both single and batched variants. For single\n * transfers, the length of the `ids` and `amounts` arrays will be 1.\n *\n * Calling conditions (for each `id` and `amount` pair):\n *\n * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * of token type `id` will be transferred to `to`.\n * - When `from` is zero, `amount` tokens of token type `id` will be minted\n * for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n * will be burned.\n * - `from` and `to` are never both zero.\n * - `ids` and `amounts` have the same, non-zero length.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any token transfer. This includes minting\n * and burning, as well as batched variants.\n *\n * The same hook is called on both single and batched variants. For single\n * transfers, the length of the `id` and `amount` arrays will be 1.\n *\n * Calling conditions (for each `id` and `amount` pair):\n *\n * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * of token type `id` will be transferred to `to`.\n * - When `from` is zero, `amount` tokens of token type `id` will be minted\n * for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n * will be burned.\n * - `from` and `to` are never both zero.\n * - `ids` and `amounts` have the same, non-zero length.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {}\n\n function _doSafeTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155Receiver.onERC1155Received.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non-ERC1155Receiver implementer\");\n }\n }\n }\n\n function _doSafeBatchTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (\n bytes4 response\n ) {\n if (response != IERC1155Receiver.onERC1155BatchReceived.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non-ERC1155Receiver implementer\");\n }\n }\n }\n\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {\n uint256[] memory array = new uint256[](1);\n array[0] = element;\n\n return array;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC1155.sol\";\n\n/**\n * @dev Interface of the optional ERC1155MetadataExtension interface, as defined\n * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155MetadataURI is IERC1155 {\n /**\n * @dev Returns the URI for token type `id`.\n *\n * If the `\\{id\\}` substring is present in the URI, it must be replaced by\n * clients with the actual token type ID.\n */\n function uri(uint256 id) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155 is IERC165 {\n /**\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n */\n event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);\n\n /**\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n * transfers.\n */\n event TransferBatch(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\n\n /**\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n * `approved`.\n */\n event ApprovalForAll(address indexed account, address indexed operator, bool approved);\n\n /**\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n *\n * If an {URI} event was emitted for `id`, the standard\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n * returned by {IERC1155MetadataURI-uri}.\n */\n event URI(string value, uint256 indexed id);\n\n /**\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) external view returns (uint256);\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] calldata accounts,\n uint256[] calldata ids\n ) external view returns (uint256[] memory);\n\n /**\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n *\n * Emits an {ApprovalForAll} event.\n *\n * Requirements:\n *\n * - `operator` cannot be the caller.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n *\n * See {setApprovalForAll}.\n */\n function isApprovedForAll(address account, address operator) external view returns (bool);\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155Receiver is IERC165 {\n /**\n * @dev Handles the receipt of a single ERC1155 token type. This function is\n * called at the end of a `safeTransferFrom` after the balance has been updated.\n *\n * NOTE: To accept the transfer, this must return\n * `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n * (i.e. 0xf23a6e61, or its own function selector).\n *\n * @param operator The address which initiated the transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param id The ID of the token being transferred\n * @param value The amount of tokens being transferred\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n ) external returns (bytes4);\n\n /**\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\n * is called at the end of a `safeBatchTransferFrom` after the balances have\n * been updated.\n *\n * NOTE: To accept the transfer(s), this must return\n * `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n * (i.e. 0xbc197c81, or its own function selector).\n *\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the default value returned by this function, unless\n * it's overridden.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(address from, address to, uint256 amount) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\n // decrementing then incrementing.\n _balances[to] += amount;\n }\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n unchecked {\n // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\n _balances[account] += amount;\n }\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n // Overflow not possible: amount <= accountBalance <= totalSupply.\n _totalSupply -= amount;\n }\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\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" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` 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 amount) 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 `amount` as the allowance of `spender` over the 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 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` 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 amount) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/ERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721.sol\";\nimport \"./IERC721Receiver.sol\";\nimport \"./extensions/IERC721Metadata.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/Strings.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\n using Address for address;\n using Strings for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\n\n // Mapping from token ID to approved address\n mapping(uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return\n interfaceId == type(IERC721).interfaceId ||\n interfaceId == type(IERC721Metadata).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _ownerOf(tokenId);\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token owner or approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n _requireMinted(tokenId);\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n _safeTransfer(from, to, tokenId, data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(address from, address to, uint256 tokenId, bytes memory data) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist\n */\n function _ownerOf(uint256 tokenId) internal view virtual returns (address) {\n return _owners[tokenId];\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _ownerOf(tokenId) != address(0);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n address owner = ERC721.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(address to, uint256 tokenId, bytes memory data) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId, 1);\n\n // Check that tokenId was not minted by `_beforeTokenTransfer` hook\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n unchecked {\n // Will not overflow unless all 2**256 token ids are minted to the same owner.\n // Given that tokens are minted one by one, it is impossible in practice that\n // this ever happens. Might change if we allow batch minting.\n // The ERC fails to describe this case.\n _balances[to] += 1;\n }\n\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(address(0), to, tokenId, 1);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n * This is an internal function that does not check if the sender is authorized to operate on the token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId, 1);\n\n // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook\n owner = ERC721.ownerOf(tokenId);\n\n // Clear approvals\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // Cannot overflow, as that would require more tokens to be burned/transferred\n // out than the owner initially received through minting and transferring in.\n _balances[owner] -= 1;\n }\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(owner, address(0), tokenId, 1);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(address from, address to, uint256 tokenId) internal virtual {\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId, 1);\n\n // Check that tokenId was not transferred by `_beforeTokenTransfer` hook\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n\n // Clear approvals from the previous owner\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // `_balances[from]` cannot overflow for the same reason as described in `_burn`:\n // `from`'s balance is the number of token held, which is at least one before the current\n // transfer.\n // `_balances[to]` could overflow in the conditions described in `_mint`. That would require\n // all 2**256 token ids to be minted, which in practice is impossible.\n _balances[from] -= 1;\n _balances[to] += 1;\n }\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId, 1);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721Receiver.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`.\n * - When `from` is zero, the tokens will be minted for `to`.\n * - When `to` is zero, ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}\n\n /**\n * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`.\n * - When `from` is zero, the tokens were minted for `to`.\n * - When `to` is zero, ``from``'s tokens were burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}\n\n /**\n * @dev Unsafe write access to the balances, used by extensions that \"mint\" tokens using an {ownerOf} override.\n *\n * WARNING: Anyone calling this MUST ensure that the balances remain consistent with the ownership. The invariant\n * being that for any address `a` the value returned by `balanceOf(a)` must be equal to the number of tokens such\n * that `ownerOf(tokenId)` is `a`.\n */\n // solhint-disable-next-line func-name-mixedcase\n function __unsafe_increaseBalance(address account, uint256 amount) internal {\n _balances[account] += amount;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721Receiver {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/ERC777.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC777/ERC777.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC777.sol\";\nimport \"./IERC777Recipient.sol\";\nimport \"./IERC777Sender.sol\";\nimport \"../ERC20/IERC20.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/introspection/IERC1820Registry.sol\";\n\n/**\n * @dev Implementation of the {IERC777} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n *\n * Support for ERC20 is included in this contract, as specified by the EIP: both\n * the ERC777 and ERC20 interfaces can be safely used when interacting with it.\n * Both {IERC777-Sent} and {IERC20-Transfer} events are emitted on token\n * movements.\n *\n * Additionally, the {IERC777-granularity} value is hard-coded to `1`, meaning that there\n * are no special restrictions in the amount of tokens that created, moved, or\n * destroyed. This makes integration with ERC20 applications seamless.\n *\n * CAUTION: This file is deprecated as of v4.9 and will be removed in the next major release.\n */\ncontract ERC777 is Context, IERC777, IERC20 {\n using Address for address;\n\n IERC1820Registry internal constant _ERC1820_REGISTRY = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n mapping(address => uint256) private _balances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n bytes32 private constant _TOKENS_SENDER_INTERFACE_HASH = keccak256(\"ERC777TokensSender\");\n bytes32 private constant _TOKENS_RECIPIENT_INTERFACE_HASH = keccak256(\"ERC777TokensRecipient\");\n\n // This isn't ever read from - it's only used to respond to the defaultOperators query.\n address[] private _defaultOperatorsArray;\n\n // Immutable, but accounts may revoke them (tracked in __revokedDefaultOperators).\n mapping(address => bool) private _defaultOperators;\n\n // For each account, a mapping of its operators and revoked default operators.\n mapping(address => mapping(address => bool)) private _operators;\n mapping(address => mapping(address => bool)) private _revokedDefaultOperators;\n\n // ERC20-allowances\n mapping(address => mapping(address => uint256)) private _allowances;\n\n /**\n * @dev `defaultOperators` may be an empty array.\n */\n constructor(string memory name_, string memory symbol_, address[] memory defaultOperators_) {\n _name = name_;\n _symbol = symbol_;\n\n _defaultOperatorsArray = defaultOperators_;\n for (uint256 i = 0; i < defaultOperators_.length; i++) {\n _defaultOperators[defaultOperators_[i]] = true;\n }\n\n // register interfaces\n _ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256(\"ERC777Token\"), address(this));\n _ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256(\"ERC20Token\"), address(this));\n }\n\n /**\n * @dev See {IERC777-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC777-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {ERC20-decimals}.\n *\n * Always returns 18, as per the\n * [ERC777 EIP](https://eips.ethereum.org/EIPS/eip-777#backward-compatibility).\n */\n function decimals() public pure virtual returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC777-granularity}.\n *\n * This implementation always returns `1`.\n */\n function granularity() public view virtual override returns (uint256) {\n return 1;\n }\n\n /**\n * @dev See {IERC777-totalSupply}.\n */\n function totalSupply() public view virtual override(IERC20, IERC777) returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev Returns the amount of tokens owned by an account (`tokenHolder`).\n */\n function balanceOf(address tokenHolder) public view virtual override(IERC20, IERC777) returns (uint256) {\n return _balances[tokenHolder];\n }\n\n /**\n * @dev See {IERC777-send}.\n *\n * Also emits a {IERC20-Transfer} event for ERC20 compatibility.\n */\n function send(address recipient, uint256 amount, bytes memory data) public virtual override {\n _send(_msgSender(), recipient, amount, data, \"\", true);\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Unlike `send`, `recipient` is _not_ required to implement the {IERC777Recipient}\n * interface if it is a contract.\n *\n * Also emits a {Sent} event.\n */\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n _send(_msgSender(), recipient, amount, \"\", \"\", false);\n return true;\n }\n\n /**\n * @dev See {IERC777-burn}.\n *\n * Also emits a {IERC20-Transfer} event for ERC20 compatibility.\n */\n function burn(uint256 amount, bytes memory data) public virtual override {\n _burn(_msgSender(), amount, data, \"\");\n }\n\n /**\n * @dev See {IERC777-isOperatorFor}.\n */\n function isOperatorFor(address operator, address tokenHolder) public view virtual override returns (bool) {\n return\n operator == tokenHolder ||\n (_defaultOperators[operator] && !_revokedDefaultOperators[tokenHolder][operator]) ||\n _operators[tokenHolder][operator];\n }\n\n /**\n * @dev See {IERC777-authorizeOperator}.\n */\n function authorizeOperator(address operator) public virtual override {\n require(_msgSender() != operator, \"ERC777: authorizing self as operator\");\n\n if (_defaultOperators[operator]) {\n delete _revokedDefaultOperators[_msgSender()][operator];\n } else {\n _operators[_msgSender()][operator] = true;\n }\n\n emit AuthorizedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-revokeOperator}.\n */\n function revokeOperator(address operator) public virtual override {\n require(operator != _msgSender(), \"ERC777: revoking self as operator\");\n\n if (_defaultOperators[operator]) {\n _revokedDefaultOperators[_msgSender()][operator] = true;\n } else {\n delete _operators[_msgSender()][operator];\n }\n\n emit RevokedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-defaultOperators}.\n */\n function defaultOperators() public view virtual override returns (address[] memory) {\n return _defaultOperatorsArray;\n }\n\n /**\n * @dev See {IERC777-operatorSend}.\n *\n * Emits {Sent} and {IERC20-Transfer} events.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes memory data,\n bytes memory operatorData\n ) public virtual override {\n require(isOperatorFor(_msgSender(), sender), \"ERC777: caller is not an operator for holder\");\n _send(sender, recipient, amount, data, operatorData, true);\n }\n\n /**\n * @dev See {IERC777-operatorBurn}.\n *\n * Emits {Burned} and {IERC20-Transfer} events.\n */\n function operatorBurn(\n address account,\n uint256 amount,\n bytes memory data,\n bytes memory operatorData\n ) public virtual override {\n require(isOperatorFor(_msgSender(), account), \"ERC777: caller is not an operator for holder\");\n _burn(account, amount, data, operatorData);\n }\n\n /**\n * @dev See {IERC20-allowance}.\n *\n * Note that operator and allowance concepts are orthogonal: operators may\n * not have allowance, and accounts with allowance may not be operators\n * themselves.\n */\n function allowance(address holder, address spender) public view virtual override returns (uint256) {\n return _allowances[holder][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Note that accounts cannot have allowance issued by their operators.\n */\n function approve(address spender, uint256 value) public virtual override returns (bool) {\n address holder = _msgSender();\n _approve(holder, spender, value);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Note that operator and allowance concepts are orthogonal: operators cannot\n * call `transferFrom` (unless they have allowance), and accounts with\n * allowance cannot call `operatorSend` (unless they are operators).\n *\n * Emits {Sent}, {IERC20-Transfer} and {IERC20-Approval} events.\n */\n function transferFrom(address holder, address recipient, uint256 amount) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(holder, spender, amount);\n _send(holder, recipient, amount, \"\", \"\", false);\n return true;\n }\n\n /**\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with the caller address as the `operator` and with\n * `userData` and `operatorData`.\n *\n * See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits {Minted} and {IERC20-Transfer} events.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - if `account` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function _mint(address account, uint256 amount, bytes memory userData, bytes memory operatorData) internal virtual {\n _mint(account, amount, userData, operatorData, true);\n }\n\n /**\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * If `requireReceptionAck` is set to true, and if a send hook is\n * registered for `account`, the corresponding function will be called with\n * `operator`, `data` and `operatorData`.\n *\n * See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits {Minted} and {IERC20-Transfer} events.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - if `account` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function _mint(\n address account,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) internal virtual {\n require(account != address(0), \"ERC777: mint to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), account, amount);\n\n // Update state variables\n _totalSupply += amount;\n _balances[account] += amount;\n\n _callTokensReceived(operator, address(0), account, amount, userData, operatorData, requireReceptionAck);\n\n emit Minted(operator, account, amount, userData, operatorData);\n emit Transfer(address(0), account, amount);\n }\n\n /**\n * @dev Send tokens\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _send(\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) internal virtual {\n require(from != address(0), \"ERC777: transfer from the zero address\");\n require(to != address(0), \"ERC777: transfer to the zero address\");\n\n address operator = _msgSender();\n\n _callTokensToSend(operator, from, to, amount, userData, operatorData);\n\n _move(operator, from, to, amount, userData, operatorData);\n\n _callTokensReceived(operator, from, to, amount, userData, operatorData, requireReceptionAck);\n }\n\n /**\n * @dev Burn tokens\n * @param from address token holder address\n * @param amount uint256 amount of tokens to burn\n * @param data bytes extra information provided by the token holder\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _burn(address from, uint256 amount, bytes memory data, bytes memory operatorData) internal virtual {\n require(from != address(0), \"ERC777: burn from the zero address\");\n\n address operator = _msgSender();\n\n _callTokensToSend(operator, from, address(0), amount, data, operatorData);\n\n _beforeTokenTransfer(operator, from, address(0), amount);\n\n // Update state variables\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC777: burn amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Burned(operator, from, amount, data, operatorData);\n emit Transfer(from, address(0), amount);\n }\n\n function _move(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n ) private {\n _beforeTokenTransfer(operator, from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC777: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Sent(operator, from, to, amount, userData, operatorData);\n emit Transfer(from, to, amount);\n }\n\n /**\n * @dev See {ERC20-_approve}.\n *\n * Note that accounts cannot have allowance issued by their operators.\n */\n function _approve(address holder, address spender, uint256 value) internal virtual {\n require(holder != address(0), \"ERC777: approve from the zero address\");\n require(spender != address(0), \"ERC777: approve to the zero address\");\n\n _allowances[holder][spender] = value;\n emit Approval(holder, spender, value);\n }\n\n /**\n * @dev Call from.tokensToSend() if the interface is registered\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _callTokensToSend(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n ) private {\n address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(from, _TOKENS_SENDER_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Sender(implementer).tokensToSend(operator, from, to, amount, userData, operatorData);\n }\n }\n\n /**\n * @dev Call to.tokensReceived() if the interface is registered. Reverts if the recipient is a contract but\n * tokensReceived() was not registered for the recipient\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _callTokensReceived(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) private {\n address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(to, _TOKENS_RECIPIENT_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Recipient(implementer).tokensReceived(operator, from, to, amount, userData, operatorData);\n } else if (requireReceptionAck) {\n require(!to.isContract(), \"ERC777: token recipient contract has no implementer for ERC777TokensRecipient\");\n }\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {IERC20-Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC777: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes\n * calls to {send}, {transfer}, {operatorSend}, {transferFrom}, minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be to transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address operator, address from, address to, uint256 amount) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC777/IERC777.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777Token standard as defined in the EIP.\n *\n * This contract uses the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 registry standard] to let\n * token holders and recipients react to token movements by using setting implementers\n * for the associated interfaces in said registry. See {IERC1820Registry} and\n * {ERC1820Implementer}.\n */\ninterface IERC777 {\n /**\n * @dev Emitted when `amount` tokens are created by `operator` and assigned to `to`.\n *\n * Note that some additional user `data` and `operatorData` can be logged in the event.\n */\n event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);\n\n /**\n * @dev Emitted when `operator` destroys `amount` tokens from `account`.\n *\n * Note that some additional user `data` and `operatorData` can be logged in the event.\n */\n event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);\n\n /**\n * @dev Emitted when `operator` is made operator for `tokenHolder`.\n */\n event AuthorizedOperator(address indexed operator, address indexed tokenHolder);\n\n /**\n * @dev Emitted when `operator` is revoked its operator status for `tokenHolder`.\n */\n event RevokedOperator(address indexed operator, address indexed tokenHolder);\n\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, usually a shorter version of the\n * name.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the smallest part of the token that is not divisible. This\n * means all token operations (creation, movement and destruction) must have\n * amounts that are a multiple of this number.\n *\n * For most token contracts, this value will equal 1.\n */\n function granularity() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by an account (`owner`).\n */\n function balanceOf(address owner) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * If send or receive hooks are registered for the caller and `recipient`,\n * the corresponding functions will be called with `data` and empty\n * `operatorData`. See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits a {Sent} event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function send(address recipient, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Destroys `amount` tokens from the caller's account, reducing the\n * total supply.\n *\n * If a send hook is registered for the caller, the corresponding function\n * will be called with `data` and empty `operatorData`. See {IERC777Sender}.\n *\n * Emits a {Burned} event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n */\n function burn(uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Returns true if an account is an operator of `tokenHolder`.\n * Operators can send and burn tokens on behalf of their owners. All\n * accounts are their own operator.\n *\n * See {operatorSend} and {operatorBurn}.\n */\n function isOperatorFor(address operator, address tokenHolder) external view returns (bool);\n\n /**\n * @dev Make an account an operator of the caller.\n *\n * See {isOperatorFor}.\n *\n * Emits an {AuthorizedOperator} event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function authorizeOperator(address operator) external;\n\n /**\n * @dev Revoke an account's operator status for the caller.\n *\n * See {isOperatorFor} and {defaultOperators}.\n *\n * Emits a {RevokedOperator} event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function revokeOperator(address operator) external;\n\n /**\n * @dev Returns the list of default operators. These accounts are operators\n * for all token holders, even if {authorizeOperator} was never called on\n * them.\n *\n * This list is immutable, but individual holders may revoke these via\n * {revokeOperator}, in which case {isOperatorFor} will return false.\n */\n function defaultOperators() external view returns (address[] memory);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must\n * be an operator of `sender`.\n *\n * If send or receive hooks are registered for `sender` and `recipient`,\n * the corresponding functions will be called with `data` and\n * `operatorData`. See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits a {Sent} event.\n *\n * Requirements\n *\n * - `sender` cannot be the zero address.\n * - `sender` must have at least `amount` tokens.\n * - the caller must be an operator for `sender`.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes calldata data,\n bytes calldata operatorData\n ) external;\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the total supply.\n * The caller must be an operator of `account`.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with `data` and `operatorData`. See {IERC777Sender}.\n *\n * Emits a {Burned} event.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n * - the caller must be an operator for `account`.\n */\n function operatorBurn(address account, uint256 amount, bytes calldata data, bytes calldata operatorData) external;\n\n event Sent(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes data,\n bytes operatorData\n );\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\n *\n * Accounts can be notified of {IERC777} tokens being sent to them by having a\n * contract implement this interface (contract holders can be their own\n * implementer) and registering it on the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\n *\n * See {IERC1820Registry} and {ERC1820Implementer}.\n */\ninterface IERC777Recipient {\n /**\n * @dev Called by an {IERC777} token contract whenever tokens are being\n * moved or created into a registered account (`to`). The type of operation\n * is conveyed by `from` being the zero address or not.\n *\n * This call occurs _after_ the token contract's state is updated, so\n * {IERC777-balanceOf}, etc., can be used to query the post-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensReceived(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777Sender.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Sender.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777TokensSender standard as defined in the EIP.\n *\n * {IERC777} Token holders can be notified of operations performed on their\n * tokens by having a contract implement this interface (contract holders can be\n * their own implementer) and registering it on the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\n *\n * See {IERC1820Registry} and {ERC1820Implementer}.\n */\ninterface IERC777Sender {\n /**\n * @dev Called by an {IERC777} token contract whenever a registered holder's\n * (`from`) tokens are about to be moved or destroyed. The type of operation\n * is conveyed by `to` being the zero address or not.\n *\n * This call occurs _before_ the token contract's state is updated, so\n * {IERC777-balanceOf}, etc., can be used to query the pre-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensToSend(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n *\n * Furthermore, `isContract` will also return true if the target contract within\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n * which only has an effect at the end of a transaction.\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Counters.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary Counters {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/ECDSA.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Strings.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV // Deprecated in v4.8\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n /// @solidity memory-safe-assembly\n assembly {\n mstore(0x00, \"\\x19Ethereum Signed Message:\\n32\")\n mstore(0x1c, hash)\n message := keccak256(0x00, 0x3c)\n }\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\n /// @solidity memory-safe-assembly\n assembly {\n let ptr := mload(0x40)\n mstore(ptr, \"\\x19\\x01\")\n mstore(add(ptr, 0x02), domainSeparator)\n mstore(add(ptr, 0x22), structHash)\n data := keccak256(ptr, 0x42)\n }\n }\n\n /**\n * @dev Returns an Ethereum Signed Data with intended validator, created from a\n * `validator` and `data` according to the version 0 of EIP-191.\n *\n * See {recover}.\n */\n function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x00\", validator, data));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/SignatureChecker.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSA.sol\";\nimport \"../../interfaces/IERC1271.sol\";\n\n/**\n * @dev Signature verification helper that can be used instead of `ECDSA.recover` to seamlessly support both ECDSA\n * signatures from externally owned accounts (EOAs) as well as ERC1271 signatures from smart contract wallets like\n * Argent and Gnosis Safe.\n *\n * _Available since v4.1._\n */\nlibrary SignatureChecker {\n /**\n * @dev Checks if a signature is valid for a given signer and data hash. If the signer is a smart contract, the\n * signature is validated against that smart contract using ERC1271, otherwise it's validated using `ECDSA.recover`.\n *\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\n */\n function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature) internal view returns (bool) {\n (address recovered, ECDSA.RecoverError error) = ECDSA.tryRecover(hash, signature);\n return\n (error == ECDSA.RecoverError.NoError && recovered == signer) ||\n isValidERC1271SignatureNow(signer, hash, signature);\n }\n\n /**\n * @dev Checks if a signature is valid for a given signer and data hash. The signature is validated\n * against the signer smart contract using ERC1271.\n *\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\n */\n function isValidERC1271SignatureNow(\n address signer,\n bytes32 hash,\n bytes memory signature\n ) internal view returns (bool) {\n (bool success, bytes memory result) = signer.staticcall(\n abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, signature)\n );\n return (success &&\n result.length >= 32 &&\n abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/ERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165 is IERC165 {\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165).interfaceId;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC1820Registry.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/introspection/IERC1820Registry.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the global ERC1820 Registry, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register\n * implementers for interfaces in this registry, as well as query support.\n *\n * Implementers may be shared by multiple accounts, and can also implement more\n * than a single interface for each account. Contracts can implement interfaces\n * for themselves, but externally-owned accounts (EOA) must delegate this to a\n * contract.\n *\n * {IERC165} interfaces can also be queried via the registry.\n *\n * For an in-depth explanation and source code analysis, see the EIP text.\n */\ninterface IERC1820Registry {\n event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer);\n\n event ManagerChanged(address indexed account, address indexed newManager);\n\n /**\n * @dev Sets `newManager` as the manager for `account`. A manager of an\n * account is able to set interface implementers for it.\n *\n * By default, each account is its own manager. Passing a value of `0x0` in\n * `newManager` will reset the manager to this initial state.\n *\n * Emits a {ManagerChanged} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `account`.\n */\n function setManager(address account, address newManager) external;\n\n /**\n * @dev Returns the manager for `account`.\n *\n * See {setManager}.\n */\n function getManager(address account) external view returns (address);\n\n /**\n * @dev Sets the `implementer` contract as ``account``'s implementer for\n * `interfaceHash`.\n *\n * `account` being the zero address is an alias for the caller's address.\n * The zero address can also be used in `implementer` to remove an old one.\n *\n * See {interfaceHash} to learn how these are created.\n *\n * Emits an {InterfaceImplementerSet} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `account`.\n * - `interfaceHash` must not be an {IERC165} interface id (i.e. it must not\n * end in 28 zeroes).\n * - `implementer` must implement {IERC1820Implementer} and return true when\n * queried for support, unless `implementer` is the caller. See\n * {IERC1820Implementer-canImplementInterfaceForAddress}.\n */\n function setInterfaceImplementer(address account, bytes32 _interfaceHash, address implementer) external;\n\n /**\n * @dev Returns the implementer of `interfaceHash` for `account`. If no such\n * implementer is registered, returns the zero address.\n *\n * If `interfaceHash` is an {IERC165} interface id (i.e. it ends with 28\n * zeroes), `account` will be queried for support of it.\n *\n * `account` being the zero address is an alias for the caller's address.\n */\n function getInterfaceImplementer(address account, bytes32 _interfaceHash) external view returns (address);\n\n /**\n * @dev Returns the interface hash for an `interfaceName`, as defined in the\n * corresponding\n * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP].\n */\n function interfaceHash(string calldata interfaceName) external pure returns (bytes32);\n\n /**\n * @notice Updates the cache with whether the contract implements an ERC165 interface or not.\n * @param account Address of the contract for which to update the cache.\n * @param interfaceId ERC165 interface for which to update the cache.\n */\n function updateERC165Cache(address account, bytes4 interfaceId) external;\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not.\n * If the result is not cached a direct lookup on the contract address is performed.\n * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling\n * {updateERC165Cache} with the contract address.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool);\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not without using or updating the cache.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/math/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\n // The surrounding unchecked block does not change this fact.\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1, \"Math: mulDiv overflow\");\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n //\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n //\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n //\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1 << (log2(a) >> 1);\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = sqrt(a);\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 2, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 128;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 64;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 32;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 16;\n }\n if (value >> 8 > 0) {\n value >>= 8;\n result += 8;\n }\n if (value >> 4 > 0) {\n value >>= 4;\n result += 4;\n }\n if (value >> 2 > 0) {\n value >>= 2;\n result += 2;\n }\n if (value >> 1 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log2(value);\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 10, rounded down, of a positive value.\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 + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 256, rounded down, of a positive value.\n * Returns 0 if given 0.\n *\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n */\n function log256(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 16;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 8;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 4;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 2;\n }\n if (value >> 8 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log256(value);\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/SafeCast.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCast {\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 * _Available since v4.7._\n */\n function toUint248(uint256 value) internal pure returns (uint248) {\n require(value <= type(uint248).max, \"SafeCast: value doesn't fit in 248 bits\");\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 * _Available since v4.7._\n */\n function toUint240(uint256 value) internal pure returns (uint240) {\n require(value <= type(uint240).max, \"SafeCast: value doesn't fit in 240 bits\");\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 * _Available since v4.7._\n */\n function toUint232(uint256 value) internal pure returns (uint232) {\n require(value <= type(uint232).max, \"SafeCast: value doesn't fit in 232 bits\");\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 * _Available since v4.2._\n */\n function toUint224(uint256 value) internal pure returns (uint224) {\n require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\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 * _Available since v4.7._\n */\n function toUint216(uint256 value) internal pure returns (uint216) {\n require(value <= type(uint216).max, \"SafeCast: value doesn't fit in 216 bits\");\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 * _Available since v4.7._\n */\n function toUint208(uint256 value) internal pure returns (uint208) {\n require(value <= type(uint208).max, \"SafeCast: value doesn't fit in 208 bits\");\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 * _Available since v4.7._\n */\n function toUint200(uint256 value) internal pure returns (uint200) {\n require(value <= type(uint200).max, \"SafeCast: value doesn't fit in 200 bits\");\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 * _Available since v4.7._\n */\n function toUint192(uint256 value) internal pure returns (uint192) {\n require(value <= type(uint192).max, \"SafeCast: value doesn't fit in 192 bits\");\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 * _Available since v4.7._\n */\n function toUint184(uint256 value) internal pure returns (uint184) {\n require(value <= type(uint184).max, \"SafeCast: value doesn't fit in 184 bits\");\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 * _Available since v4.7._\n */\n function toUint176(uint256 value) internal pure returns (uint176) {\n require(value <= type(uint176).max, \"SafeCast: value doesn't fit in 176 bits\");\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 * _Available since v4.7._\n */\n function toUint168(uint256 value) internal pure returns (uint168) {\n require(value <= type(uint168).max, \"SafeCast: value doesn't fit in 168 bits\");\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 * _Available since v4.7._\n */\n function toUint160(uint256 value) internal pure returns (uint160) {\n require(value <= type(uint160).max, \"SafeCast: value doesn't fit in 160 bits\");\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 * _Available since v4.7._\n */\n function toUint152(uint256 value) internal pure returns (uint152) {\n require(value <= type(uint152).max, \"SafeCast: value doesn't fit in 152 bits\");\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 * _Available since v4.7._\n */\n function toUint144(uint256 value) internal pure returns (uint144) {\n require(value <= type(uint144).max, \"SafeCast: value doesn't fit in 144 bits\");\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 * _Available since v4.7._\n */\n function toUint136(uint256 value) internal pure returns (uint136) {\n require(value <= type(uint136).max, \"SafeCast: value doesn't fit in 136 bits\");\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 * _Available since v2.5._\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\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 * _Available since v4.7._\n */\n function toUint120(uint256 value) internal pure returns (uint120) {\n require(value <= type(uint120).max, \"SafeCast: value doesn't fit in 120 bits\");\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 * _Available since v4.7._\n */\n function toUint112(uint256 value) internal pure returns (uint112) {\n require(value <= type(uint112).max, \"SafeCast: value doesn't fit in 112 bits\");\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 * _Available since v4.7._\n */\n function toUint104(uint256 value) internal pure returns (uint104) {\n require(value <= type(uint104).max, \"SafeCast: value doesn't fit in 104 bits\");\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 * _Available since v4.2._\n */\n function toUint96(uint256 value) internal pure returns (uint96) {\n require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\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 * _Available since v4.7._\n */\n function toUint88(uint256 value) internal pure returns (uint88) {\n require(value <= type(uint88).max, \"SafeCast: value doesn't fit in 88 bits\");\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 * _Available since v4.7._\n */\n function toUint80(uint256 value) internal pure returns (uint80) {\n require(value <= type(uint80).max, \"SafeCast: value doesn't fit in 80 bits\");\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 * _Available since v4.7._\n */\n function toUint72(uint256 value) internal pure returns (uint72) {\n require(value <= type(uint72).max, \"SafeCast: value doesn't fit in 72 bits\");\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 * _Available since v2.5._\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\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 * _Available since v4.7._\n */\n function toUint56(uint256 value) internal pure returns (uint56) {\n require(value <= type(uint56).max, \"SafeCast: value doesn't fit in 56 bits\");\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 * _Available since v4.7._\n */\n function toUint48(uint256 value) internal pure returns (uint48) {\n require(value <= type(uint48).max, \"SafeCast: value doesn't fit in 48 bits\");\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 * _Available since v4.7._\n */\n function toUint40(uint256 value) internal pure returns (uint40) {\n require(value <= type(uint40).max, \"SafeCast: value doesn't fit in 40 bits\");\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 * _Available since v2.5._\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\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 * _Available since v4.7._\n */\n function toUint24(uint256 value) internal pure returns (uint24) {\n require(value <= type(uint24).max, \"SafeCast: value doesn't fit in 24 bits\");\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 * _Available since v2.5._\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\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 * _Available since v2.5._\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\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 * _Available since v3.0._\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\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 * _Available since v4.7._\n */\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\n downcasted = int248(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 248 bits\");\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 * _Available since v4.7._\n */\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\n downcasted = int240(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 240 bits\");\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 * _Available since v4.7._\n */\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\n downcasted = int232(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 232 bits\");\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 * _Available since v4.7._\n */\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\n downcasted = int224(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 224 bits\");\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 * _Available since v4.7._\n */\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\n downcasted = int216(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 216 bits\");\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 * _Available since v4.7._\n */\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\n downcasted = int208(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 208 bits\");\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 * _Available since v4.7._\n */\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\n downcasted = int200(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 200 bits\");\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 * _Available since v4.7._\n */\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\n downcasted = int192(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 192 bits\");\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 * _Available since v4.7._\n */\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\n downcasted = int184(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 184 bits\");\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 * _Available since v4.7._\n */\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\n downcasted = int176(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 176 bits\");\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 * _Available since v4.7._\n */\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\n downcasted = int168(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 168 bits\");\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 * _Available since v4.7._\n */\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\n downcasted = int160(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 160 bits\");\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 * _Available since v4.7._\n */\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\n downcasted = int152(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 152 bits\");\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 * _Available since v4.7._\n */\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\n downcasted = int144(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 144 bits\");\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 * _Available since v4.7._\n */\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\n downcasted = int136(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 136 bits\");\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 * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\n downcasted = int128(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 128 bits\");\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 * _Available since v4.7._\n */\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\n downcasted = int120(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 120 bits\");\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 * _Available since v4.7._\n */\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\n downcasted = int112(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 112 bits\");\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 * _Available since v4.7._\n */\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\n downcasted = int104(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 104 bits\");\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 * _Available since v4.7._\n */\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\n downcasted = int96(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 96 bits\");\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 * _Available since v4.7._\n */\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\n downcasted = int88(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 88 bits\");\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 * _Available since v4.7._\n */\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\n downcasted = int80(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 80 bits\");\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 * _Available since v4.7._\n */\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\n downcasted = int72(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 72 bits\");\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 * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\n downcasted = int64(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 64 bits\");\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 * _Available since v4.7._\n */\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\n downcasted = int56(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 56 bits\");\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 * _Available since v4.7._\n */\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\n downcasted = int48(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 48 bits\");\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 * _Available since v4.7._\n */\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\n downcasted = int40(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 40 bits\");\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 * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\n downcasted = int32(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 32 bits\");\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 * _Available since v4.7._\n */\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\n downcasted = int24(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 24 bits\");\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 * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\n downcasted = int16(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 16 bits\");\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 * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\n downcasted = int8(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 8 bits\");\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 * _Available since v3.0._\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 require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/SignedMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard signed math utilities missing in the Solidity language.\n */\nlibrary SignedMath {\n /**\n * @dev Returns the largest of two signed numbers.\n */\n function max(int256 a, int256 b) internal pure returns (int256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two signed numbers.\n */\n function min(int256 a, int256 b) internal pure returns (int256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two signed numbers without overflow.\n * The result is rounded towards zero.\n */\n function average(int256 a, int256 b) internal pure returns (int256) {\n // Formula from the book \"Hacker's Delight\"\n int256 x = (a & b) + ((a ^ b) >> 1);\n return x + (int256(uint256(x) >> 255) & (a ^ b));\n }\n\n /**\n * @dev Returns the absolute unsigned value of a signed value.\n */\n function abs(int256 n) internal pure returns (uint256) {\n unchecked {\n // must be unchecked in order to support `n = type(int256).min`\n return uint256(n >= 0 ? n : -n);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/Math.sol\";\nimport \"./math/SignedMath.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n unchecked {\n uint256 length = Math.log10(value) + 1;\n string memory buffer = new string(length);\n uint256 ptr;\n /// @solidity memory-safe-assembly\n assembly {\n ptr := add(buffer, add(32, length))\n }\n while (true) {\n ptr--;\n /// @solidity memory-safe-assembly\n assembly {\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n }\n value /= 10;\n if (value == 0) break;\n }\n return buffer;\n }\n }\n\n /**\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\n */\n function toString(int256 value) internal pure returns (string memory) {\n return string(abi.encodePacked(value < 0 ? \"-\" : \"\", toString(SignedMath.abs(value))));\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n unchecked {\n return toHexString(value, Math.log256(value) + 1);\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n\n /**\n * @dev Returns true if the two strings are equal.\n */\n function equal(string memory a, string memory b) internal pure returns (bool) {\n return keccak256(bytes(a)) == keccak256(bytes(b));\n }\n}\n" + }, + "contracts/aa-4337/core/BaseAccount.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-empty-blocks */\n\nimport \"../interfaces/IAccount.sol\";\nimport \"../interfaces/IEntryPoint.sol\";\nimport \"./Helpers.sol\";\n\n/**\n * Basic account implementation.\n * this contract provides the basic logic for implementing the IAccount interface - validateUserOp\n * specific account implementation should inherit it and provide the account-specific logic\n */\nabstract contract BaseAccount is IAccount {\n using UserOperationLib for UserOperation;\n\n //return value in case of signature failure, with no time-range.\n // equivalent to _packValidationData(true,0,0);\n uint256 internal constant SIG_VALIDATION_FAILED = 1;\n\n /**\n * Return the account nonce.\n * This method returns the next sequential nonce.\n * For a nonce of a specific key, use `entrypoint.getNonce(account, key)`\n */\n function getNonce() public view virtual returns (uint256) {\n return entryPoint().getNonce(address(this), 0);\n }\n\n /**\n * return the entryPoint used by this account.\n * subclass should return the current entryPoint used by this account.\n */\n function entryPoint() public view virtual returns (IEntryPoint);\n\n /**\n * Validate user's signature and nonce.\n * subclass doesn't need to override this method. Instead, it should override the specific internal validation methods.\n */\n function validateUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 missingAccountFunds\n ) external virtual override returns (uint256 validationData) {\n _requireFromEntryPoint();\n validationData = _validateSignature(userOp, userOpHash);\n _validateNonce(userOp.nonce);\n _payPrefund(missingAccountFunds);\n }\n\n /**\n * ensure the request comes from the known entrypoint.\n */\n function _requireFromEntryPoint() internal view virtual {\n require(\n msg.sender == address(entryPoint()),\n \"account: not from EntryPoint\"\n );\n }\n\n /**\n * validate the signature is valid for this message.\n * @param userOp validate the userOp.signature field\n * @param userOpHash convenient field: the hash of the request, to check the signature against\n * (also hashes the entrypoint and chain id)\n * @return validationData signature and time-range of this operation\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * If the account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function _validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) internal virtual returns (uint256 validationData);\n\n /**\n * Validate the nonce of the UserOperation.\n * This method may validate the nonce requirement of this account.\n * e.g.\n * To limit the nonce to use sequenced UserOps only (no \"out of order\" UserOps):\n * `require(nonce < type(uint64).max)`\n * For a hypothetical account that *requires* the nonce to be out-of-order:\n * `require(nonce & type(uint64).max == 0)`\n *\n * The actual nonce uniqueness is managed by the EntryPoint, and thus no other\n * action is needed by the account itself.\n *\n * @param nonce to validate\n *\n * solhint-disable-next-line no-empty-blocks\n */\n function _validateNonce(uint256 nonce) internal view virtual {}\n\n /**\n * sends to the entrypoint (msg.sender) the missing funds for this transaction.\n * subclass MAY override this method for better funds management\n * (e.g. send to the entryPoint more than the minimum required, so that in future transactions\n * it will not be required to send again)\n * @param missingAccountFunds the minimum value this method should send the entrypoint.\n * this value MAY be zero, in case there is enough deposit, or the userOp has a paymaster.\n */\n function _payPrefund(uint256 missingAccountFunds) internal virtual {\n if (missingAccountFunds != 0) {\n (bool success, ) = payable(msg.sender).call{\n value: missingAccountFunds,\n gas: type(uint256).max\n }(\"\");\n (success);\n //ignore failure (its EntryPoint's job to verify, not account.)\n }\n }\n}\n" + }, + "contracts/aa-4337/core/EntryPoint.sol": { + "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n\nimport \"../interfaces/IAccount.sol\";\nimport \"../interfaces/IPaymaster.sol\";\nimport \"../interfaces/IEntryPoint.sol\";\n\nimport \"../utils/Exec.sol\";\nimport \"./StakeManager.sol\";\nimport \"./SenderCreator.sol\";\nimport \"./Helpers.sol\";\nimport \"./NonceManager.sol\";\nimport \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\n\ncontract EntryPoint is\n IEntryPoint,\n StakeManager,\n NonceManager,\n ReentrancyGuard\n{\n using UserOperationLib for UserOperation;\n\n SenderCreator private immutable senderCreator = new SenderCreator();\n\n // internal value used during simulation: need to query aggregator.\n address private constant SIMULATE_FIND_AGGREGATOR = address(1);\n\n // marker for inner call revert on out of gas\n bytes32 private constant INNER_OUT_OF_GAS = hex\"deaddead\";\n\n uint256 private constant REVERT_REASON_MAX_LEN = 2048;\n\n /**\n * for simulation purposes, validateUserOp (and validatePaymasterUserOp) must return this value\n * in case of signature failure, instead of revert.\n */\n uint256 public constant SIG_VALIDATION_FAILED = 1;\n\n /**\n * compensate the caller's beneficiary address with the collected fees of all UserOperations.\n * @param beneficiary the address to receive the fees\n * @param amount amount to transfer.\n */\n function _compensate(address payable beneficiary, uint256 amount) internal {\n require(beneficiary != address(0), \"AA90 invalid beneficiary\");\n (bool success, ) = beneficiary.call{value: amount}(\"\");\n require(success, \"AA91 failed send to beneficiary\");\n }\n\n /**\n * execute a user op\n * @param opIndex index into the opInfo array\n * @param userOp the userOp to execute\n * @param opInfo the opInfo filled by validatePrepayment for this userOp.\n * @return collected the total amount this userOp paid.\n */\n function _executeUserOp(\n uint256 opIndex,\n UserOperation calldata userOp,\n UserOpInfo memory opInfo\n ) private returns (uint256 collected) {\n uint256 preGas = gasleft();\n bytes memory context = getMemoryBytesFromOffset(opInfo.contextOffset);\n\n try this.innerHandleOp(userOp.callData, opInfo, context) returns (\n uint256 _actualGasCost\n ) {\n collected = _actualGasCost;\n } catch {\n bytes32 innerRevertCode;\n assembly {\n returndatacopy(0, 0, 32)\n innerRevertCode := mload(0)\n }\n // handleOps was called with gas limit too low. abort entire bundle.\n if (innerRevertCode == INNER_OUT_OF_GAS) {\n //report paymaster, since if it is not deliberately caused by the bundler,\n // it must be a revert caused by paymaster.\n revert FailedOp(opIndex, \"AA95 out of gas\");\n }\n\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n collected = _handlePostOp(\n opIndex,\n IPaymaster.PostOpMode.postOpReverted,\n opInfo,\n context,\n actualGas\n );\n }\n }\n\n /**\n * Execute a batch of UserOperations.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(\n UserOperation[] calldata ops,\n address payable beneficiary\n ) public nonReentrant {\n uint256 opslen = ops.length;\n UserOpInfo[] memory opInfos = new UserOpInfo[](opslen);\n\n unchecked {\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[i];\n (\n uint256 validationData,\n uint256 pmValidationData\n ) = _validatePrepayment(i, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(\n i,\n validationData,\n pmValidationData,\n address(0)\n );\n }\n\n uint256 collected = 0;\n emit BeforeExecution();\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(i, ops[i], opInfos[i]);\n }\n\n _compensate(beneficiary, collected);\n } //unchecked\n }\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) public nonReentrant {\n uint256 opasLen = opsPerAggregator.length;\n uint256 totalOps = 0;\n for (uint256 i = 0; i < opasLen; i++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[i];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n //address(1) is special marker of \"signature error\"\n require(\n address(aggregator) != address(1),\n \"AA96 invalid aggregator\"\n );\n\n if (address(aggregator) != address(0)) {\n // solhint-disable-next-line no-empty-blocks\n try aggregator.validateSignatures(ops, opa.signature) {} catch {\n revert SignatureValidationFailed(address(aggregator));\n }\n }\n\n totalOps += ops.length;\n }\n\n UserOpInfo[] memory opInfos = new UserOpInfo[](totalOps);\n\n emit BeforeExecution();\n\n uint256 opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n uint256 opslen = ops.length;\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[opIndex];\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(opIndex, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(\n i,\n validationData,\n paymasterValidationData,\n address(aggregator)\n );\n opIndex++;\n }\n }\n\n uint256 collected = 0;\n opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n emit SignatureAggregatorChanged(address(opa.aggregator));\n UserOperation[] calldata ops = opa.userOps;\n uint256 opslen = ops.length;\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(opIndex, ops[i], opInfos[opIndex]);\n opIndex++;\n }\n }\n emit SignatureAggregatorChanged(address(0));\n\n _compensate(beneficiary, collected);\n }\n\n /// @inheritdoc IEntryPoint\n function simulateHandleOp(\n UserOperation calldata op,\n address target,\n bytes calldata targetCallData\n ) external override {\n UserOpInfo memory opInfo;\n _simulationOnlyValidations(op);\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(0, op, opInfo);\n ValidationData memory data = _intersectTimeRange(\n validationData,\n paymasterValidationData\n );\n\n numberMarker();\n uint256 paid = _executeUserOp(0, op, opInfo);\n numberMarker();\n bool targetSuccess;\n bytes memory targetResult;\n if (target != address(0)) {\n (targetSuccess, targetResult) = target.call(targetCallData);\n }\n revert ExecutionResult(\n opInfo.preOpGas,\n paid,\n data.validAfter,\n data.validUntil,\n targetSuccess,\n targetResult\n );\n }\n\n // A memory copy of UserOp static fields only.\n // Excluding: callData, initCode and signature. Replacing paymasterAndData with paymaster.\n struct MemoryUserOp {\n address sender;\n uint256 nonce;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n address paymaster;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n }\n\n struct UserOpInfo {\n MemoryUserOp mUserOp;\n bytes32 userOpHash;\n uint256 prefund;\n uint256 contextOffset;\n uint256 preOpGas;\n }\n\n /**\n * inner function to handle a UserOperation.\n * Must be declared \"external\" to open a call context, but it can only be called by handleOps.\n */\n function innerHandleOp(\n bytes memory callData,\n UserOpInfo memory opInfo,\n bytes calldata context\n ) external returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n require(msg.sender == address(this), \"AA92 internal call only\");\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n\n uint callGasLimit = mUserOp.callGasLimit;\n unchecked {\n // handleOps was called with gas limit too low. abort entire bundle.\n if (\n gasleft() < callGasLimit + mUserOp.verificationGasLimit + 5000\n ) {\n assembly {\n mstore(0, INNER_OUT_OF_GAS)\n revert(0, 32)\n }\n }\n }\n\n IPaymaster.PostOpMode mode = IPaymaster.PostOpMode.opSucceeded;\n if (callData.length > 0) {\n bool success = Exec.call(mUserOp.sender, 0, callData, callGasLimit);\n if (!success) {\n bytes memory result = Exec.getReturnData(REVERT_REASON_MAX_LEN);\n if (result.length > 0) {\n emit UserOperationRevertReason(\n opInfo.userOpHash,\n mUserOp.sender,\n mUserOp.nonce,\n result\n );\n }\n mode = IPaymaster.PostOpMode.opReverted;\n }\n }\n\n unchecked {\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n //note: opIndex is ignored (relevant only if mode==postOpReverted, which is only possible outside of innerHandleOp)\n return _handlePostOp(0, mode, opInfo, context, actualGas);\n }\n }\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(\n UserOperation calldata userOp\n ) public view returns (bytes32) {\n return\n keccak256(abi.encode(userOp.hash(), address(this), block.chainid));\n }\n\n /**\n * copy general fields from userOp into the memory opInfo structure.\n */\n function _copyUserOpToMemory(\n UserOperation calldata userOp,\n MemoryUserOp memory mUserOp\n ) internal pure {\n mUserOp.sender = userOp.sender;\n mUserOp.nonce = userOp.nonce;\n mUserOp.callGasLimit = userOp.callGasLimit;\n mUserOp.verificationGasLimit = userOp.verificationGasLimit;\n mUserOp.preVerificationGas = userOp.preVerificationGas;\n mUserOp.maxFeePerGas = userOp.maxFeePerGas;\n mUserOp.maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes calldata paymasterAndData = userOp.paymasterAndData;\n if (paymasterAndData.length > 0) {\n require(\n paymasterAndData.length >= 20,\n \"AA93 invalid paymasterAndData\"\n );\n mUserOp.paymaster = address(bytes20(paymasterAndData[:20]));\n } else {\n mUserOp.paymaster = address(0);\n }\n }\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external {\n UserOpInfo memory outOpInfo;\n\n _simulationOnlyValidations(userOp);\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(0, userOp, outOpInfo);\n StakeInfo memory paymasterInfo = _getStakeInfo(\n outOpInfo.mUserOp.paymaster\n );\n StakeInfo memory senderInfo = _getStakeInfo(outOpInfo.mUserOp.sender);\n StakeInfo memory factoryInfo;\n {\n bytes calldata initCode = userOp.initCode;\n address factory = initCode.length >= 20\n ? address(bytes20(initCode[0:20]))\n : address(0);\n factoryInfo = _getStakeInfo(factory);\n }\n\n ValidationData memory data = _intersectTimeRange(\n validationData,\n paymasterValidationData\n );\n address aggregator = data.aggregator;\n bool sigFailed = aggregator == address(1);\n ReturnInfo memory returnInfo = ReturnInfo(\n outOpInfo.preOpGas,\n outOpInfo.prefund,\n sigFailed,\n data.validAfter,\n data.validUntil,\n getMemoryBytesFromOffset(outOpInfo.contextOffset)\n );\n\n if (aggregator != address(0) && aggregator != address(1)) {\n AggregatorStakeInfo memory aggregatorInfo = AggregatorStakeInfo(\n aggregator,\n _getStakeInfo(aggregator)\n );\n revert ValidationResultWithAggregation(\n returnInfo,\n senderInfo,\n factoryInfo,\n paymasterInfo,\n aggregatorInfo\n );\n }\n revert ValidationResult(\n returnInfo,\n senderInfo,\n factoryInfo,\n paymasterInfo\n );\n }\n\n function _getRequiredPrefund(\n MemoryUserOp memory mUserOp\n ) internal pure returns (uint256 requiredPrefund) {\n unchecked {\n //when using a Paymaster, the verificationGasLimit is used also to as a limit for the postOp call.\n // our security model might call postOp eventually twice\n uint256 mul = mUserOp.paymaster != address(0) ? 3 : 1;\n uint256 requiredGas = mUserOp.callGasLimit +\n mUserOp.verificationGasLimit *\n mul +\n mUserOp.preVerificationGas;\n\n requiredPrefund = requiredGas * mUserOp.maxFeePerGas;\n }\n }\n\n // create the sender's contract if needed.\n function _createSenderIfNeeded(\n uint256 opIndex,\n UserOpInfo memory opInfo,\n bytes calldata initCode\n ) internal {\n if (initCode.length != 0) {\n address sender = opInfo.mUserOp.sender;\n if (sender.code.length != 0)\n revert FailedOp(opIndex, \"AA10 sender already constructed\");\n address sender1 = senderCreator.createSender{\n gas: opInfo.mUserOp.verificationGasLimit\n }(initCode);\n if (sender1 == address(0))\n revert FailedOp(opIndex, \"AA13 initCode failed or OOG\");\n if (sender1 != sender)\n revert FailedOp(opIndex, \"AA14 initCode must return sender\");\n if (sender1.code.length == 0)\n revert FailedOp(opIndex, \"AA15 initCode must create sender\");\n address factory = address(bytes20(initCode[0:20]));\n emit AccountDeployed(\n opInfo.userOpHash,\n sender,\n factory,\n opInfo.mUserOp.paymaster\n );\n }\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes calldata initCode) public {\n address sender = senderCreator.createSender(initCode);\n revert SenderAddressResult(sender);\n }\n\n function _simulationOnlyValidations(\n UserOperation calldata userOp\n ) internal view {\n // solhint-disable-next-line no-empty-blocks\n try\n this._validateSenderAndPaymaster(\n userOp.initCode,\n userOp.sender,\n userOp.paymasterAndData\n )\n {} catch Error(string memory revertReason) {\n if (bytes(revertReason).length != 0) {\n revert FailedOp(0, revertReason);\n }\n }\n }\n\n /**\n * Called only during simulation.\n * This function always reverts to prevent warm/cold storage differentiation in simulation vs execution.\n */\n function _validateSenderAndPaymaster(\n bytes calldata initCode,\n address sender,\n bytes calldata paymasterAndData\n ) external view {\n if (initCode.length == 0 && sender.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA20 account not deployed\");\n }\n if (paymasterAndData.length >= 20) {\n address paymaster = address(bytes20(paymasterAndData[0:20]));\n if (paymaster.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA30 paymaster not deployed\");\n }\n }\n // always revert\n revert(\"\");\n }\n\n /**\n * call account.validateUserOp.\n * revert (with FailedOp) in case validateUserOp reverts, or account didn't send required prefund.\n * decrement account's deposit if needed\n */\n function _validateAccountPrepayment(\n uint256 opIndex,\n UserOperation calldata op,\n UserOpInfo memory opInfo,\n uint256 requiredPrefund\n )\n internal\n returns (\n uint256 gasUsedByValidateAccountPrepayment,\n uint256 validationData\n )\n {\n unchecked {\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n address sender = mUserOp.sender;\n _createSenderIfNeeded(opIndex, opInfo, op.initCode);\n address paymaster = mUserOp.paymaster;\n numberMarker();\n uint256 missingAccountFunds = 0;\n if (paymaster == address(0)) {\n uint256 bal = balanceOf(sender);\n missingAccountFunds = bal > requiredPrefund\n ? 0\n : requiredPrefund - bal;\n }\n try\n IAccount(sender).validateUserOp{\n gas: mUserOp.verificationGasLimit\n }(op, opInfo.userOpHash, missingAccountFunds)\n returns (uint256 _validationData) {\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA23 reverted: \", revertReason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA23 reverted (or OOG)\");\n }\n if (paymaster == address(0)) {\n DepositInfo storage senderInfo = deposits[sender];\n uint256 deposit = senderInfo.deposit;\n if (requiredPrefund > deposit) {\n revert FailedOp(opIndex, \"AA21 didn't pay prefund\");\n }\n senderInfo.deposit = uint112(deposit - requiredPrefund);\n }\n gasUsedByValidateAccountPrepayment = preGas - gasleft();\n }\n }\n\n /**\n * In case the request has a paymaster:\n * Validate paymaster has enough deposit.\n * Call paymaster.validatePaymasterUserOp.\n * Revert with proper FailedOp in case paymaster reverts.\n * Decrement paymaster's deposit\n */\n function _validatePaymasterPrepayment(\n uint256 opIndex,\n UserOperation calldata op,\n UserOpInfo memory opInfo,\n uint256 requiredPreFund,\n uint256 gasUsedByValidateAccountPrepayment\n ) internal returns (bytes memory context, uint256 validationData) {\n unchecked {\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 verificationGasLimit = mUserOp.verificationGasLimit;\n require(\n verificationGasLimit > gasUsedByValidateAccountPrepayment,\n \"AA41 too little verificationGas\"\n );\n uint256 gas = verificationGasLimit -\n gasUsedByValidateAccountPrepayment;\n\n address paymaster = mUserOp.paymaster;\n DepositInfo storage paymasterInfo = deposits[paymaster];\n uint256 deposit = paymasterInfo.deposit;\n if (deposit < requiredPreFund) {\n revert FailedOp(opIndex, \"AA31 paymaster deposit too low\");\n }\n paymasterInfo.deposit = uint112(deposit - requiredPreFund);\n try\n IPaymaster(paymaster).validatePaymasterUserOp{gas: gas}(\n op,\n opInfo.userOpHash,\n requiredPreFund\n )\n returns (bytes memory _context, uint256 _validationData) {\n context = _context;\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA33 reverted: \", revertReason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA33 reverted (or OOG)\");\n }\n }\n }\n\n /**\n * revert if either account validationData or paymaster validationData is expired\n */\n function _validateAccountAndPaymasterValidationData(\n uint256 opIndex,\n uint256 validationData,\n uint256 paymasterValidationData,\n address expectedAggregator\n ) internal view {\n (address aggregator, bool outOfTimeRange) = _getValidationData(\n validationData\n );\n if (expectedAggregator != aggregator) {\n revert FailedOp(opIndex, \"AA24 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA22 expired or not due\");\n }\n //pmAggregator is not a real signature aggregator: we don't have logic to handle it as address.\n // non-zero address means that the paymaster fails due to some signature check (which is ok only during estimation)\n address pmAggregator;\n (pmAggregator, outOfTimeRange) = _getValidationData(\n paymasterValidationData\n );\n if (pmAggregator != address(0)) {\n revert FailedOp(opIndex, \"AA34 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA32 paymaster expired or not due\");\n }\n }\n\n function _getValidationData(\n uint256 validationData\n ) internal view returns (address aggregator, bool outOfTimeRange) {\n if (validationData == 0) {\n return (address(0), false);\n }\n ValidationData memory data = _parseValidationData(validationData);\n // solhint-disable-next-line not-rely-on-time\n outOfTimeRange =\n block.timestamp > data.validUntil ||\n block.timestamp < data.validAfter;\n aggregator = data.aggregator;\n }\n\n /**\n * validate account and paymaster (if defined).\n * also make sure total validation doesn't exceed verificationGasLimit\n * this method is called off-chain (simulateValidation()) and on-chain (from handleOps)\n * @param opIndex the index of this userOp into the \"opInfos\" array\n * @param userOp the userOp to validate\n */\n function _validatePrepayment(\n uint256 opIndex,\n UserOperation calldata userOp,\n UserOpInfo memory outOpInfo\n )\n private\n returns (uint256 validationData, uint256 paymasterValidationData)\n {\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = outOpInfo.mUserOp;\n _copyUserOpToMemory(userOp, mUserOp);\n outOpInfo.userOpHash = getUserOpHash(userOp);\n\n // validate all numeric values in userOp are well below 128 bit, so they can safely be added\n // and multiplied without causing overflow\n uint256 maxGasValues = mUserOp.preVerificationGas |\n mUserOp.verificationGasLimit |\n mUserOp.callGasLimit |\n userOp.maxFeePerGas |\n userOp.maxPriorityFeePerGas;\n require(maxGasValues <= type(uint120).max, \"AA94 gas values overflow\");\n\n uint256 gasUsedByValidateAccountPrepayment;\n uint256 requiredPreFund = _getRequiredPrefund(mUserOp);\n (\n gasUsedByValidateAccountPrepayment,\n validationData\n ) = _validateAccountPrepayment(\n opIndex,\n userOp,\n outOpInfo,\n requiredPreFund\n );\n\n if (!_validateAndUpdateNonce(mUserOp.sender, mUserOp.nonce)) {\n revert FailedOp(opIndex, \"AA25 invalid account nonce\");\n }\n\n //a \"marker\" where account opcode validation is done and paymaster opcode validation is about to start\n // (used only by off-chain simulateValidation)\n numberMarker();\n\n bytes memory context;\n if (mUserOp.paymaster != address(0)) {\n (context, paymasterValidationData) = _validatePaymasterPrepayment(\n opIndex,\n userOp,\n outOpInfo,\n requiredPreFund,\n gasUsedByValidateAccountPrepayment\n );\n }\n unchecked {\n uint256 gasUsed = preGas - gasleft();\n\n if (userOp.verificationGasLimit < gasUsed) {\n revert FailedOp(opIndex, \"AA40 over verificationGasLimit\");\n }\n outOpInfo.prefund = requiredPreFund;\n outOpInfo.contextOffset = getOffsetOfMemoryBytes(context);\n outOpInfo.preOpGas = preGas - gasleft() + userOp.preVerificationGas;\n }\n }\n\n /**\n * process post-operation.\n * called just after the callData is executed.\n * if a paymaster is defined and its validation returned a non-empty context, its postOp is called.\n * the excess amount is refunded to the account (or paymaster - if it was used in the request)\n * @param opIndex index in the batch\n * @param mode - whether is called from innerHandleOp, or outside (postOpReverted)\n * @param opInfo userOp fields and info collected during validation\n * @param context the context returned in validatePaymasterUserOp\n * @param actualGas the gas used so far by this user operation\n */\n function _handlePostOp(\n uint256 opIndex,\n IPaymaster.PostOpMode mode,\n UserOpInfo memory opInfo,\n bytes memory context,\n uint256 actualGas\n ) private returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n unchecked {\n address refundAddress;\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 gasPrice = getUserOpGasPrice(mUserOp);\n\n address paymaster = mUserOp.paymaster;\n if (paymaster == address(0)) {\n refundAddress = mUserOp.sender;\n } else {\n refundAddress = paymaster;\n if (context.length > 0) {\n actualGasCost = actualGas * gasPrice;\n if (mode != IPaymaster.PostOpMode.postOpReverted) {\n IPaymaster(paymaster).postOp{\n gas: mUserOp.verificationGasLimit\n }(mode, context, actualGasCost);\n } else {\n // solhint-disable-next-line no-empty-blocks\n try\n IPaymaster(paymaster).postOp{\n gas: mUserOp.verificationGasLimit\n }(mode, context, actualGasCost)\n {} catch Error(string memory reason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA50 postOp reverted: \", reason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA50 postOp revert\");\n }\n }\n }\n }\n actualGas += preGas - gasleft();\n actualGasCost = actualGas * gasPrice;\n if (opInfo.prefund < actualGasCost) {\n revert FailedOp(opIndex, \"AA51 prefund below actualGasCost\");\n }\n uint256 refund = opInfo.prefund - actualGasCost;\n _incrementDeposit(refundAddress, refund);\n bool success = mode == IPaymaster.PostOpMode.opSucceeded;\n emit UserOperationEvent(\n opInfo.userOpHash,\n mUserOp.sender,\n mUserOp.paymaster,\n mUserOp.nonce,\n success,\n actualGasCost,\n actualGas\n );\n } // unchecked\n }\n\n /**\n * the gas price this UserOp agrees to pay.\n * relayer/block builder might submit the TX with higher priorityFee, but the user should not\n */\n function getUserOpGasPrice(\n MemoryUserOp memory mUserOp\n ) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = mUserOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = mUserOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n function getOffsetOfMemoryBytes(\n bytes memory data\n ) internal pure returns (uint256 offset) {\n assembly {\n offset := data\n }\n }\n\n function getMemoryBytesFromOffset(\n uint256 offset\n ) internal pure returns (bytes memory data) {\n assembly {\n data := offset\n }\n }\n\n //place the NUMBER opcode in the code.\n // this is used as a marker during simulation, as this OP is completely banned from the simulated code of the\n // account and paymaster.\n function numberMarker() internal view {\n assembly {\n mstore(0, number())\n }\n }\n}\n" + }, + "contracts/aa-4337/core/Helpers.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable no-inline-assembly */\n\n/**\n * returned data from validateUserOp.\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\n * @param aggregator - address(0) - the account validated the signature by itself.\n * address(1) - the account failed to validate the signature.\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\n * @param validAfter - this UserOp is valid only after this timestamp.\n * @param validaUntil - this UserOp is valid only up to this timestamp.\n */\nstruct ValidationData {\n address aggregator;\n uint48 validAfter;\n uint48 validUntil;\n}\n\n//extract sigFailed, validAfter, validUntil.\n// also convert zero validUntil to type(uint48).max\nfunction _parseValidationData(\n uint validationData\n) pure returns (ValidationData memory data) {\n address aggregator = address(uint160(validationData));\n uint48 validUntil = uint48(validationData >> 160);\n if (validUntil == 0) {\n validUntil = type(uint48).max;\n }\n uint48 validAfter = uint48(validationData >> (48 + 160));\n return ValidationData(aggregator, validAfter, validUntil);\n}\n\n// intersect account and paymaster ranges.\nfunction _intersectTimeRange(\n uint256 validationData,\n uint256 paymasterValidationData\n) pure returns (ValidationData memory) {\n ValidationData memory accountValidationData = _parseValidationData(\n validationData\n );\n ValidationData memory pmValidationData = _parseValidationData(\n paymasterValidationData\n );\n address aggregator = accountValidationData.aggregator;\n if (aggregator == address(0)) {\n aggregator = pmValidationData.aggregator;\n }\n uint48 validAfter = accountValidationData.validAfter;\n uint48 validUntil = accountValidationData.validUntil;\n uint48 pmValidAfter = pmValidationData.validAfter;\n uint48 pmValidUntil = pmValidationData.validUntil;\n\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\n return ValidationData(aggregator, validAfter, validUntil);\n}\n\n/**\n * helper to pack the return value for validateUserOp\n * @param data - the ValidationData to pack\n */\nfunction _packValidationData(\n ValidationData memory data\n) pure returns (uint256) {\n return\n uint160(data.aggregator) |\n (uint256(data.validUntil) << 160) |\n (uint256(data.validAfter) << (160 + 48));\n}\n\n/**\n * helper to pack the return value for validateUserOp, when not using an aggregator\n * @param sigFailed - true for signature failure, false for success\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\n * @param validAfter first timestamp this UserOperation is valid\n */\nfunction _packValidationData(\n bool sigFailed,\n uint48 validUntil,\n uint48 validAfter\n) pure returns (uint256) {\n return\n (sigFailed ? 1 : 0) |\n (uint256(validUntil) << 160) |\n (uint256(validAfter) << (160 + 48));\n}\n\n/**\n * keccak function over calldata.\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\n */\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\n assembly {\n let mem := mload(0x40)\n let len := data.length\n calldatacopy(mem, data.offset, len)\n ret := keccak256(mem, len)\n }\n}\n" + }, + "contracts/aa-4337/core/NonceManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\nimport \"../interfaces/IEntryPoint.sol\";\n\n/**\n * nonce management functionality\n */\ncontract NonceManager is INonceManager {\n /**\n * The next valid sequence number for a given nonce key.\n */\n mapping(address => mapping(uint192 => uint256)) public nonceSequenceNumber;\n\n function getNonce(\n address sender,\n uint192 key\n ) public view override returns (uint256 nonce) {\n return nonceSequenceNumber[sender][key] | (uint256(key) << 64);\n }\n\n // allow an account to manually increment its own nonce.\n // (mainly so that during construction nonce can be made non-zero,\n // to \"absorb\" the gas cost of first nonce increment to 1st transaction (construction),\n // not to 2nd transaction)\n function incrementNonce(uint192 key) public override {\n nonceSequenceNumber[msg.sender][key]++;\n }\n\n /**\n * validate nonce uniqueness for this account.\n * called just after validateUserOp()\n */\n function _validateAndUpdateNonce(\n address sender,\n uint256 nonce\n ) internal returns (bool) {\n uint192 key = uint192(nonce >> 64);\n uint64 seq = uint64(nonce);\n return nonceSequenceNumber[sender][key]++ == seq;\n }\n}\n" + }, + "contracts/aa-4337/core/SenderCreator.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/**\n * helper contract for EntryPoint, to call userOp.initCode from a \"neutral\" address,\n * which is explicitly not the entryPoint itself.\n */\ncontract SenderCreator {\n /**\n * call the \"initCode\" factory to create and return the sender account address\n * @param initCode the initCode value from a UserOp. contains 20 bytes of factory address, followed by calldata\n * @return sender the returned address of the created account, or zero address on failure.\n */\n function createSender(\n bytes calldata initCode\n ) external returns (address sender) {\n address factory = address(bytes20(initCode[0:20]));\n bytes memory initCallData = initCode[20:];\n bool success;\n /* solhint-disable no-inline-assembly */\n assembly {\n success := call(\n gas(),\n factory,\n 0,\n add(initCallData, 0x20),\n mload(initCallData),\n 0,\n 32\n )\n sender := mload(0)\n }\n if (!success) {\n sender = address(0);\n }\n }\n}\n" + }, + "contracts/aa-4337/core/StakeManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity 0.8.21;\n\nimport \"../interfaces/IStakeManager.sol\";\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable not-rely-on-time */\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by a paymaster.\n */\nabstract contract StakeManager is IStakeManager {\n /// maps paymaster to their deposits and stakes\n mapping(address => DepositInfo) public deposits;\n\n /// @inheritdoc IStakeManager\n function getDepositInfo(\n address account\n ) public view returns (DepositInfo memory info) {\n return deposits[account];\n }\n\n // internal method to return just the stake info\n function _getStakeInfo(\n address addr\n ) internal view returns (StakeInfo memory info) {\n DepositInfo storage depositInfo = deposits[addr];\n info.stake = depositInfo.stake;\n info.unstakeDelaySec = depositInfo.unstakeDelaySec;\n }\n\n /// return the deposit (for gas payment) of the account\n function balanceOf(address account) public view returns (uint256) {\n return deposits[account].deposit;\n }\n\n receive() external payable {\n depositTo(msg.sender);\n }\n\n function _incrementDeposit(address account, uint256 amount) internal {\n DepositInfo storage info = deposits[account];\n uint256 newAmount = info.deposit + amount;\n require(newAmount <= type(uint112).max, \"deposit overflow\");\n info.deposit = uint112(newAmount);\n }\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) public payable {\n _incrementDeposit(account, msg.value);\n DepositInfo storage info = deposits[account];\n emit Deposited(account, info.deposit);\n }\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 unstakeDelaySec) public payable {\n DepositInfo storage info = deposits[msg.sender];\n require(unstakeDelaySec > 0, \"must specify unstake delay\");\n require(\n unstakeDelaySec >= info.unstakeDelaySec,\n \"cannot decrease unstake time\"\n );\n uint256 stake = info.stake + msg.value;\n require(stake > 0, \"no stake specified\");\n require(stake <= type(uint112).max, \"stake overflow\");\n deposits[msg.sender] = DepositInfo(\n info.deposit,\n true,\n uint112(stake),\n unstakeDelaySec,\n 0\n );\n emit StakeLocked(msg.sender, stake, unstakeDelaySec);\n }\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external {\n DepositInfo storage info = deposits[msg.sender];\n require(info.unstakeDelaySec != 0, \"not staked\");\n require(info.staked, \"already unstaking\");\n uint48 withdrawTime = uint48(block.timestamp) + info.unstakeDelaySec;\n info.withdrawTime = withdrawTime;\n info.staked = false;\n emit StakeUnlocked(msg.sender, withdrawTime);\n }\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external {\n DepositInfo storage info = deposits[msg.sender];\n uint256 stake = info.stake;\n require(stake > 0, \"No stake to withdraw\");\n require(info.withdrawTime > 0, \"must call unlockStake() first\");\n require(\n info.withdrawTime <= block.timestamp,\n \"Stake withdrawal is not due\"\n );\n info.unstakeDelaySec = 0;\n info.withdrawTime = 0;\n info.stake = 0;\n emit StakeWithdrawn(msg.sender, withdrawAddress, stake);\n (bool success, ) = withdrawAddress.call{value: stake}(\"\");\n require(success, \"failed to withdraw stake\");\n }\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(\n address payable withdrawAddress,\n uint256 withdrawAmount\n ) external {\n DepositInfo storage info = deposits[msg.sender];\n require(withdrawAmount <= info.deposit, \"Withdraw amount too large\");\n info.deposit = uint112(info.deposit - withdrawAmount);\n emit Withdrawn(msg.sender, withdrawAddress, withdrawAmount);\n (bool success, ) = withdrawAddress.call{value: withdrawAmount}(\"\");\n require(success, \"failed to withdraw\");\n }\n}\n" + }, + "contracts/aa-4337/interfaces/IAccount.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\ninterface IAccount {\n /**\n * Validate user's signature and nonce\n * the entryPoint will make the call to the recipient only if this validation call returns successfully.\n * signature failure should be reported by returning SIG_VALIDATION_FAILED (1).\n * This allows making a \"simulation call\" without a valid signature\n * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure.\n *\n * @dev Must validate caller is the entryPoint.\n * Must validate the signature and nonce\n * @param userOp the operation that is about to be executed.\n * @param userOpHash hash of the user's request data. can be used as the basis for signature.\n * @param missingAccountFunds missing funds on the account's deposit in the entrypoint.\n * This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call.\n * The excess is left as a deposit in the entrypoint, for future calls.\n * can be withdrawn anytime using \"entryPoint.withdrawTo()\"\n * In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero.\n * @return validationData packaged ValidationData structure. use `_packValidationData` and `_unpackValidationData` to encode and decode\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * If an account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validateUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 missingAccountFunds\n ) external returns (uint256 validationData);\n}\n" + }, + "contracts/aa-4337/interfaces/IAggregator.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * Aggregated Signatures validator.\n */\ninterface IAggregator {\n /**\n * validate aggregated signature.\n * revert if the aggregated signature does not match the given list of operations.\n */\n function validateSignatures(\n UserOperation[] calldata userOps,\n bytes calldata signature\n ) external view;\n\n /**\n * validate signature of a single userOp\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\n * @param userOp the userOperation received from the user.\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\n * (usually empty, unless account and aggregator support some kind of \"multisig\"\n */\n function validateUserOpSignature(\n UserOperation calldata userOp\n ) external view returns (bytes memory sigForUserOp);\n\n /**\n * aggregate multiple signatures into a single value.\n * This method is called off-chain to calculate the signature to pass with handleOps()\n * bundler MAY use optimized custom code perform this aggregation\n * @param userOps array of UserOperations to collect the signatures from.\n * @return aggregatedSignature the aggregated signature\n */\n function aggregateSignatures(\n UserOperation[] calldata userOps\n ) external view returns (bytes memory aggregatedSignature);\n}\n" + }, + "contracts/aa-4337/interfaces/IEntryPoint.sol": { + "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n/* solhint-disable reason-string */\n\nimport \"./UserOperation.sol\";\nimport \"./IStakeManager.sol\";\nimport \"./IAggregator.sol\";\nimport \"./INonceManager.sol\";\n\ninterface IEntryPoint is IStakeManager, INonceManager {\n /***\n * An event emitted after each successful request\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\n * @param sender - the account that generates this request.\n * @param paymaster - if non-null, the paymaster that pays for this request.\n * @param nonce - the nonce value from the request.\n * @param success - true if the sender transaction succeeded, false if reverted.\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\n */\n event UserOperationEvent(\n bytes32 indexed userOpHash,\n address indexed sender,\n address indexed paymaster,\n uint256 nonce,\n bool success,\n uint256 actualGasCost,\n uint256 actualGasUsed\n );\n\n /**\n * account \"sender\" was deployed.\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\n * @param sender the account that is deployed\n * @param factory the factory used to deploy this account (in the initCode)\n * @param paymaster the paymaster used by this UserOp\n */\n event AccountDeployed(\n bytes32 indexed userOpHash,\n address indexed sender,\n address factory,\n address paymaster\n );\n\n /**\n * An event emitted if the UserOperation \"callData\" reverted with non-zero length\n * @param userOpHash the request unique identifier.\n * @param sender the sender of this request\n * @param nonce the nonce used in the request\n * @param revertReason - the return bytes from the (reverted) call to \"callData\".\n */\n event UserOperationRevertReason(\n bytes32 indexed userOpHash,\n address indexed sender,\n uint256 nonce,\n bytes revertReason\n );\n\n /**\n * an event emitted by handleOps(), before starting the execution loop.\n * any event emitted before this event, is part of the validation.\n */\n event BeforeExecution();\n\n /**\n * signature aggregator used by the following UserOperationEvents within this bundle.\n */\n event SignatureAggregatorChanged(address indexed aggregator);\n\n /**\n * a custom revert error of handleOps, to identify the offending op.\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\n * @param reason - revert reason\n * The string starts with a unique code \"AAmn\", where \"m\" is \"1\" for factory, \"2\" for account and \"3\" for paymaster issues,\n * so a failure can be attributed to the correct entity.\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\n */\n error FailedOp(uint256 opIndex, string reason);\n\n /**\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\n */\n error SignatureValidationFailed(address aggregator);\n\n /**\n * Successful result from simulateValidation.\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n */\n error ValidationResult(\n ReturnInfo returnInfo,\n StakeInfo senderInfo,\n StakeInfo factoryInfo,\n StakeInfo paymasterInfo\n );\n\n /**\n * Successful result from simulateValidation, if the account returns a signature aggregator\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\n * bundler MUST use it to verify the signature, or reject the UserOperation\n */\n error ValidationResultWithAggregation(\n ReturnInfo returnInfo,\n StakeInfo senderInfo,\n StakeInfo factoryInfo,\n StakeInfo paymasterInfo,\n AggregatorStakeInfo aggregatorInfo\n );\n\n /**\n * return value of getSenderAddress\n */\n error SenderAddressResult(address sender);\n\n /**\n * return value of simulateHandleOp\n */\n error ExecutionResult(\n uint256 preOpGas,\n uint256 paid,\n uint48 validAfter,\n uint48 validUntil,\n bool targetSuccess,\n bytes targetResult\n );\n\n //UserOps handled, per aggregator\n struct UserOpsPerAggregator {\n UserOperation[] userOps;\n // aggregator address\n IAggregator aggregator;\n // aggregated signature\n bytes signature;\n }\n\n /**\n * Execute a batch of UserOperation.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(\n UserOperation[] calldata ops,\n address payable beneficiary\n ) external;\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) external;\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(\n UserOperation calldata userOp\n ) external view returns (bytes32);\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external;\n\n /**\n * gas and return values during simulation\n * @param preOpGas the gas used for validation (including preValidationGas)\n * @param prefund the required prefund for this operation\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\n */\n struct ReturnInfo {\n uint256 preOpGas;\n uint256 prefund;\n bool sigFailed;\n uint48 validAfter;\n uint48 validUntil;\n bytes paymasterContext;\n }\n\n /**\n * returned aggregated signature info.\n * the aggregator returned by the account, and its current stake.\n */\n struct AggregatorStakeInfo {\n address aggregator;\n StakeInfo stakeInfo;\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes memory initCode) external;\n\n /**\n * simulate full execution of a UserOperation (including both validation and target execution)\n * this method will always revert with \"ExecutionResult\".\n * it performs full validation of the UserOperation, but ignores signature error.\n * an optional target address is called after the userop succeeds, and its value is returned\n * (before the entire call is reverted)\n * Note that in order to collect the the success/failure of the target call, it must be executed\n * with trace enabled to track the emitted events.\n * @param op the UserOperation to simulate\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\n * are set to the return from that call.\n * @param targetCallData callData to pass to target address\n */\n function simulateHandleOp(\n UserOperation calldata op,\n address target,\n bytes calldata targetCallData\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/INonceManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\ninterface INonceManager {\n /**\n * Return the next nonce for this sender.\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\n * But UserOp with different keys can come with arbitrary order.\n *\n * @param sender the account address\n * @param key the high 192 bit of the nonce\n * @return nonce a full nonce to pass for next UserOp with this sender.\n */\n function getNonce(\n address sender,\n uint192 key\n ) external view returns (uint256 nonce);\n\n /**\n * Manually increment the nonce of the sender.\n * This method is exposed just for completeness..\n * Account does NOT need to call it, neither during validation, nor elsewhere,\n * as the EntryPoint will update the nonce regardless.\n * Possible use-case is call it with various keys to \"initialize\" their nonces to one, so that future\n * UserOperations will not pay extra for the first transaction with a given key.\n */\n function incrementNonce(uint192 key) external;\n}\n" + }, + "contracts/aa-4337/interfaces/IPaymaster.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * the interface exposed by a paymaster contract, who agrees to pay the gas for user's operations.\n * a paymaster must hold a stake to cover the required entrypoint stake and also the gas for the transaction.\n */\ninterface IPaymaster {\n enum PostOpMode {\n opSucceeded, // user op succeeded\n opReverted, // user op reverted. still has to pay for gas.\n postOpReverted //user op succeeded, but caused postOp to revert. Now it's a 2nd call, after user's op was deliberately reverted.\n }\n\n /**\n * payment validation: check if paymaster agrees to pay.\n * Must verify sender is the entryPoint.\n * Revert to reject this request.\n * Note that bundlers will reject this method if it changes the state, unless the paymaster is trusted (whitelisted)\n * The paymaster pre-pays using its deposit, and receive back a refund after the postOp method returns.\n * @param userOp the user operation\n * @param userOpHash hash of the user's request data.\n * @param maxCost the maximum cost of this transaction (based on maximum gas and gas price from userOp)\n * @return context value to send to a postOp\n * zero length to signify postOp is not required.\n * @return validationData signature and time-range of this operation, encoded the same as the return value of validateUserOperation\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validatePaymasterUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 maxCost\n ) external returns (bytes memory context, uint256 validationData);\n\n /**\n * post-operation handler.\n * Must verify sender is the entryPoint\n * @param mode enum with the following options:\n * opSucceeded - user operation succeeded.\n * opReverted - user op reverted. still has to pay for gas.\n * postOpReverted - user op succeeded, but caused postOp (in mode=opSucceeded) to revert.\n * Now this is the 2nd call, after user's op was deliberately reverted.\n * @param context - the context value returned by validatePaymasterUserOp\n * @param actualGasCost - actual gas used so far (without this postOp call).\n */\n function postOp(\n PostOpMode mode,\n bytes calldata context,\n uint256 actualGasCost\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/IStakeManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.12;\n\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by the staked entity.\n */\ninterface IStakeManager {\n event Deposited(address indexed account, uint256 totalDeposit);\n\n event Withdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /// Emitted when stake or unstake delay are modified\n event StakeLocked(\n address indexed account,\n uint256 totalStaked,\n uint256 unstakeDelaySec\n );\n\n /// Emitted once a stake is scheduled for withdrawal\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\n\n event StakeWithdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /**\n * @param deposit the entity's deposit\n * @param staked true if this entity is staked.\n * @param stake actual amount of ether staked for this entity.\n * @param unstakeDelaySec minimum delay to withdraw the stake.\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\n * and the rest fit into a 2nd cell.\n * 112 bit allows for 10^15 eth\n * 48 bit for full timestamp\n * 32 bit allows 150 years for unstake delay\n */\n struct DepositInfo {\n uint112 deposit;\n bool staked;\n uint112 stake;\n uint32 unstakeDelaySec;\n uint48 withdrawTime;\n }\n\n //API struct used by getStakeInfo and simulateValidation\n struct StakeInfo {\n uint256 stake;\n uint256 unstakeDelaySec;\n }\n\n /// @return info - full deposit information of given account\n function getDepositInfo(\n address account\n ) external view returns (DepositInfo memory info);\n\n /// @return the deposit (for gas payment) of the account\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) external payable;\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 _unstakeDelaySec) external payable;\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external;\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external;\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(\n address payable withdrawAddress,\n uint256 withdrawAmount\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/UserOperation.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable no-inline-assembly */\n\nimport {calldataKeccak} from \"../core/Helpers.sol\";\n\n/**\n * User Operation struct\n * @param sender the sender account of this request.\n * @param nonce unique value the sender uses to verify it is not a replay.\n * @param initCode if set, the account contract will be created by this constructor/\n * @param callData the method call to execute on this account.\n * @param callGasLimit the gas limit passed to the callData method call.\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\n * @param maxFeePerGas same as EIP-1559 gas parameter.\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\n */\nstruct UserOperation {\n address sender;\n uint256 nonce;\n bytes initCode;\n bytes callData;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n bytes paymasterAndData;\n bytes signature;\n}\n\n/**\n * Utility functions helpful when working with UserOperation structs.\n */\nlibrary UserOperationLib {\n function getSender(\n UserOperation calldata userOp\n ) internal pure returns (address) {\n address data;\n //read sender from userOp, which is first userOp member (saves 800 gas...)\n assembly {\n data := calldataload(userOp)\n }\n return address(uint160(data));\n }\n\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\n // pay above what he signed for.\n function gasPrice(\n UserOperation calldata userOp\n ) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function pack(\n UserOperation calldata userOp\n ) internal pure returns (bytes memory ret) {\n address sender = getSender(userOp);\n uint256 nonce = userOp.nonce;\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\n bytes32 hashCallData = calldataKeccak(userOp.callData);\n uint256 callGasLimit = userOp.callGasLimit;\n uint256 verificationGasLimit = userOp.verificationGasLimit;\n uint256 preVerificationGas = userOp.preVerificationGas;\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\n\n return\n abi.encode(\n sender,\n nonce,\n hashInitCode,\n hashCallData,\n callGasLimit,\n verificationGasLimit,\n preVerificationGas,\n maxFeePerGas,\n maxPriorityFeePerGas,\n hashPaymasterAndData\n );\n }\n\n function hash(\n UserOperation calldata userOp\n ) internal pure returns (bytes32) {\n return keccak256(pack(userOp));\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n}\n" + }, + "contracts/aa-4337/utils/Exec.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.5 <0.9.0;\n\n// solhint-disable no-inline-assembly\n\n/**\n * Utility functions helpful when making different kinds of contract calls in Solidity.\n */\nlibrary Exec {\n function call(\n address to,\n uint256 value,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := call(\n txGas,\n to,\n value,\n add(data, 0x20),\n mload(data),\n 0,\n 0\n )\n }\n }\n\n function staticcall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal view returns (bool success) {\n assembly {\n success := staticcall(txGas, to, add(data, 0x20), mload(data), 0, 0)\n }\n }\n\n function delegateCall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := delegatecall(\n txGas,\n to,\n add(data, 0x20),\n mload(data),\n 0,\n 0\n )\n }\n }\n\n // get returned data from last call or calldelegate\n function getReturnData(\n uint256 maxLen\n ) internal pure returns (bytes memory returnData) {\n assembly {\n let len := returndatasize()\n if gt(len, maxLen) {\n len := maxLen\n }\n let ptr := mload(0x40)\n mstore(0x40, add(ptr, add(len, 0x20)))\n mstore(ptr, len)\n returndatacopy(add(ptr, 0x20), 0, len)\n returnData := ptr\n }\n }\n\n // revert with explicit byte array (probably reverted info from call)\n function revertWithData(bytes memory returnData) internal pure {\n assembly {\n revert(add(returnData, 32), mload(returnData))\n }\n }\n\n function callAndRevert(\n address to,\n bytes memory data,\n uint256 maxLen\n ) internal {\n bool success = call(to, 0, data, gasleft());\n if (!success) {\n revertWithData(getReturnData(maxLen));\n }\n }\n}\n" + }, + "contracts/Barz.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"./libraries/LibDiamond.sol\";\nimport {IBarz} from \"./interfaces/IBarz.sol\";\n\n/**\n * @title Barz\n * @dev A diamond proxy wallet with a modular & upgradeable architecture\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract Barz is IBarz {\n /**\n * @notice Initializes Barz with the given parameters. Barz account is intended to be created from Barz Factory for stable deployment.\n * @dev This method makes a delegate call to account facet and account facet handles the initialization.\n * With modular architecture, Barz encompasses wide spectrum of architecture and logic.\n * The only requirement is account facet to comply with initialize() interface.\n * Barz doesn't include built-in functions and is a full proxy, for maximum extensibility and modularity.\n * @param _accountFacet Address of Account Facet in charge of the Barz initialization\n * @param _verificationFacet Address of Verification Facet for verifying the signature. Could be any signature scheme\n * @param _entryPoint Address of Entry Point contract\n * @param _facetRegistry Address of Facet Registry. Facet Registry is a registry holding trusted facets that could be added to user's wallet\n * @param _defaultFallBack Address of Default FallBack Handler. Middleware contract for more efficient deployment\n * @param _ownerPublicKey Bytes of Owner Public Key using for initialization\n */\n constructor(\n address _accountFacet,\n address _verificationFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallBack,\n bytes memory _ownerPublicKey\n ) payable {\n bytes memory initCall = abi.encodeWithSignature(\n \"initialize(address,address,address,address,bytes)\",\n _verificationFacet,\n _entryPoint,\n _facetRegistry,\n _defaultFallBack,\n _ownerPublicKey\n );\n (bool success, bytes memory result) = _accountFacet.delegatecall(\n initCall\n );\n if (!success || uint256(bytes32(result)) != 1) {\n revert Barz__InitializationFailure();\n }\n }\n\n /**\n * @notice Fallback function for Barz complying with Diamond Standard with customization of adding Default Fallback Handler\n * @dev Find facet for function that is called and execute the function if a facet is found and return any value.\n */\n fallback() external payable {\n LibDiamond.DiamondStorage storage ds;\n bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION;\n // get diamond storage\n assembly {\n ds.slot := position\n }\n // get facet from function selector\n address facet = address(bytes20(ds.facets[msg.sig]));\n if (facet == address(0))\n facet = ds.defaultFallbackHandler.facetAddress(msg.sig);\n require(facet != address(0), \"Barz: Function does not exist\");\n // Execute external function from facet using delegatecall and return any value.\n assembly {\n // copy function selector and any arguments\n calldatacopy(0, 0, calldatasize())\n // execute function call using the facet\n let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)\n // get any return value\n returndatacopy(0, 0, returndatasize())\n // return any return value or error back to the caller\n switch result\n case 0 {\n revert(0, returndatasize())\n }\n default {\n return(0, returndatasize())\n }\n }\n }\n\n /**\n * @notice Receive function to receive native token without data\n */\n receive() external payable {}\n}\n" + }, + "contracts/BarzFactory.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Barz} from \"./Barz.sol\";\nimport {IBarzFactory} from \"./interfaces/IBarzFactory.sol\";\n\n/**\n * @title Barz Factory\n * @dev Contract to easily deploy Barz to a pre-computed address with a single call\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract BarzFactory is IBarzFactory {\n address public immutable accountFacet;\n address public immutable entryPoint;\n address public immutable facetRegistry;\n address public immutable defaultFallback;\n\n /**\n * @notice Sets the initialization data for Barz contract initialization\n * @param _accountFacet Account Facet to be used to create Barz\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\n * @param _facetRegistry Facet Registry to be used to create Barz\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\n */\n constructor(\n address _accountFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallback\n ) {\n accountFacet = _accountFacet;\n entryPoint = _entryPoint;\n facetRegistry = _facetRegistry;\n defaultFallback = _defaultFallback;\n }\n\n /**\n * @notice Creates the Barz with a single call. It creates the Barz contract with the givent verification facet\n * @param _verificationFacet Address of verification facet used for creating the barz account\n * @param _owner Public Key of the owner to initialize barz account\n * @param _salt Salt used for deploying barz with create2\n * @return barz Instance of Barz contract deployed with the given parameters\n */\n function createAccount(\n address _verificationFacet,\n bytes calldata _owner,\n uint256 _salt\n ) external override returns (Barz barz) {\n address addr = getAddress(_verificationFacet, _owner, _salt);\n uint codeSize = addr.code.length;\n if (codeSize > 0) {\n return Barz(payable(addr));\n }\n barz = new Barz{salt: bytes32(_salt)}(\n accountFacet,\n _verificationFacet,\n entryPoint,\n facetRegistry,\n defaultFallback,\n _owner\n );\n emit BarzDeployed(address(barz));\n }\n\n /**\n * @notice Calculates the address of Barz with the given parameters\n * @param _verificationFacet Address of verification facet used for creating the barz account\n * @param _owner Public Key of the owner to initialize barz account\n * @param _salt Salt used for deploying barz with create2\n * @return barzAddress Precalculated Barz address\n */\n function getAddress(\n address _verificationFacet,\n bytes calldata _owner,\n uint256 _salt\n ) public view override returns (address barzAddress) {\n bytes memory bytecode = getBytecode(\n accountFacet,\n _verificationFacet,\n entryPoint,\n facetRegistry,\n defaultFallback,\n _owner\n );\n bytes32 hash = keccak256(\n abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(bytecode)\n )\n );\n barzAddress = address(uint160(uint256(hash)));\n }\n\n /**\n * @notice Returns the bytecode of Barz with the given parameter\n * @param _accountFacet Account Facet to be used to create Barz\n * @param _verificationFacet Verification Facet to be used to create Barz\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\n * @param _facetRegistry Facet Registry to be used to create Barz\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\n * @param _ownerPublicKey Public Key of owner to be used to initialize Barz ownership\n * @return barzBytecode Bytecode of Barz\n */\n function getBytecode(\n address _accountFacet,\n address _verificationFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallback,\n bytes calldata _ownerPublicKey\n ) public pure override returns (bytes memory barzBytecode) {\n bytes memory bytecode = type(Barz).creationCode;\n barzBytecode = abi.encodePacked(\n bytecode,\n abi.encode(\n _accountFacet,\n _verificationFacet,\n _entryPoint,\n _facetRegistry,\n _defaultFallback,\n _ownerPublicKey\n )\n );\n }\n\n /**\n * @notice Returns the creation code of the Barz contract\n * @return creationCode Creation code of Barz\n */\n function getCreationCode()\n public\n pure\n override\n returns (bytes memory creationCode)\n {\n creationCode = type(Barz).creationCode;\n }\n}\n" + }, + "contracts/facets/AccountFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {UserOperation} from \"../aa-4337/interfaces/UserOperation.sol\";\nimport {IEntryPoint} from \"../aa-4337/interfaces/IEntryPoint.sol\";\nimport {BaseAccount} from \"../aa-4337/core/BaseAccount.sol\";\nimport {LibAppStorage, BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {IFacetRegistry} from \"../infrastructure/interfaces/IFacetRegistry.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {IERC1271} from \"../interfaces/ERC/IERC1271.sol\";\nimport {IAccountFacet} from \"./interfaces/IAccountFacet.sol\";\n\n/**\n * @title Account Facet\n * @dev Account module contract that provides the account features and initialization of signer\n * compatible with EIP-1271 & EIP-4337\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract AccountFacet is IAccountFacet, BarzStorage, BaseAccount {\n using ECDSA for bytes32;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceAccountInitialize();\n }\n\n /**\n * @notice Returns the address of EntryPoint contract registered to Barz account\n */\n function entryPoint() public view override returns (IEntryPoint) {\n return s.entryPoint;\n }\n\n /**\n * @notice Initializes the initial storage of the Barz contract.\n * @dev This method can only be called during the initialization or signature migration.\n * If the proxy contract was created without initialization, anyone can call initialize.\n * Barz calls initialize in constructor in an atomic transaction during deployment\n * @param _verificationFacet Facet contract handling the verificationi\n * @param _anEntryPoint Entrypoint contract defined in EIP-4337 handling the flow of UserOp\n * @param _facetRegistry Registry of Facets that hold all facet information\n * @param _defaultFallBackHandler Middleware contract for default facets\n * @param _ownerPublicKey Bytes of owner public key\n */\n function initialize(\n address _verificationFacet,\n address _anEntryPoint,\n address _facetRegistry,\n address _defaultFallBackHandler,\n bytes calldata _ownerPublicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceAccountInitialize();\n s.entryPoint = IEntryPoint(_anEntryPoint);\n s.facetRegistry = IFacetRegistry(_facetRegistry);\n LibDiamond.diamondStorage().defaultFallbackHandler = IDiamondLoupe(\n _defaultFallBackHandler\n );\n\n _cutDiamondAccountFacet(_verificationFacet);\n\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n _ownerPublicKey\n );\n // Every Verification Facet should comply with initializeSigner(bytes)\n // to be compatible with the Barz contract(for initialization)\n (bool success, bytes memory result) = _verificationFacet.delegatecall(\n initCall\n );\n if (!success || uint256(bytes32(result)) != 1) {\n revert AccountFacet__InitializationFailure();\n }\n\n initSuccess = 1;\n emit AccountInitialized(s.entryPoint, _ownerPublicKey);\n }\n\n function _cutDiamondAccountFacet(address _verificationFacet) internal {\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](1);\n\n bytes4 ownerVerificationFuncSelector = IVerificationFacet(\n _verificationFacet\n ).validateOwnerSignatureSelector();\n\n bytes4[] memory verificationFunctionSelectors = new bytes4[](3);\n verificationFunctionSelectors[0] = IERC1271.isValidSignature.selector;\n verificationFunctionSelectors[1] = ownerVerificationFuncSelector;\n verificationFunctionSelectors[2] = IVerificationFacet.owner.selector;\n cut[0] = IDiamondCut.FacetCut({\n facetAddress: _verificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: verificationFunctionSelectors\n });\n\n LibDiamond.diamondCut(cut, address(0), \"\");\n }\n\n /**\n * @notice Calls the destination with inputted calldata and value from EntryPoint\n * @dev This method executes the calldata coming from the EntryPoint.\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\n * @param _dest Address of destination where the call will be forwarded to\n * @param _value Amount of native coin the owner is willing to send(e.g. ETH, BNB)\n * @param _func Bytes of calldata to execute in the destination address\n */\n function execute(\n address _dest,\n uint256 _value,\n bytes calldata _func\n ) external override onlyWhenUnlocked {\n _requireFromEntryPoint();\n address restrictionsFacet = LibDiamond.restrictionsFacet();\n if (restrictionsFacet == address(0)) _call(_dest, _value, _func);\n else _callWithRestrictions(_dest, _value, _func, restrictionsFacet);\n }\n\n /**\n * @notice Batch calls the destination with inputted calldata and value from EntryPoint\n * @dev This method batch executes the calldata coming from the EntryPoint.\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\n * @param _dest Array of addresses of destination where the call will be forwarded to\n * @param _value Array of amount of native coin the owner is willing to send(e.g. ETH, BNB)\n * @param _func Array of bytes of calldata to execute in the destination address\n */\n function executeBatch(\n address[] calldata _dest,\n uint256[] calldata _value,\n bytes[] calldata _func\n ) external override onlyWhenUnlocked {\n _requireFromEntryPoint();\n if (_dest.length != _func.length || _dest.length != _value.length)\n revert AccountFacet__InvalidArrayLength();\n address restrictionsFacet = LibDiamond.restrictionsFacet();\n if (restrictionsFacet == address(0)) {\n for (uint256 i; i < _dest.length; ) {\n _call(_dest[i], _value[i], _func[i]);\n unchecked {\n ++i;\n }\n }\n } else {\n for (uint256 i; i < _dest.length; ) {\n _callWithRestrictions(\n _dest[i],\n _value[i],\n _func[i],\n restrictionsFacet\n );\n unchecked {\n ++i;\n }\n }\n }\n }\n\n /**\n * @notice Validates the signature field of UserOperation\n * @dev This method validates if the signature of UserOp is indeed valid by delegating the call to Verification Facet\n * Barz makes a call to the pre-registered Verification Facet address in App Storage\n * @param _userOp UserOperation from owner to be validated\n * @param _userOpHash Hash of UserOperation given from the EntryPoint contract\n */\n function _validateSignature(\n UserOperation calldata _userOp,\n bytes32 _userOpHash\n ) internal override returns (uint256 validationData) {\n // Get Facet with Function Selector\n address facet = LibLoupe.facetAddress(s.validateOwnerSignatureSelector);\n if (facet == address(0))\n revert AccountFacet__NonExistentVerificationFacet();\n\n // Make function call to VerificationFacet\n bytes memory validateCall = abi.encodeWithSelector(\n s.validateOwnerSignatureSelector,\n _userOp,\n _userOpHash\n );\n (bool success, bytes memory result) = facet.delegatecall(validateCall);\n if (!success) revert AccountFacet__CallNotSuccessful();\n validationData = uint256(bytes32(result));\n if (validationData == 0) emit VerificationSuccess(_userOpHash);\n else emit VerificationFailure(_userOpHash);\n }\n\n /**\n * @notice Calls the target with the inputted value and calldata\n * @dev This method is the actual function in Barz that makes a call with an arbitrary owner-given data\n * @param _target Address of the destination contract which the call is getting forwarded to\n * @param _value Amount of Native coin the owner is wanting to make in this call\n * @param _data Calldata the owner is forwarding together in the call e.g. Swap/Token Transfer\n */\n function _call(\n address _target,\n uint256 _value,\n bytes memory _data\n ) internal {\n (bool success, bytes memory result) = _target.call{value: _value}(\n _data\n );\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n }\n\n /**\n * @notice Calls the target with the inputted value and calldata together with restrictions check\n * @dev This method is the actual function in Barz that makes a call with an arbitrary owner-given data\n * @param _target Address of the destination contract which the call is getting forwarded to\n * @param _value Amount of Native coin the owner is wanting to make in this call\n * @param _data Calldata the owner is forwarding together in the call e.g. Swap/Token Transfer\n * @param _restrictionsFacet Address of Facet to validate restrictions\n */\n function _callWithRestrictions(\n address _target,\n uint256 _value,\n bytes memory _data,\n address _restrictionsFacet\n ) internal {\n // NOTE: No restrictions facet, so restriction validation passes\n if (_checkRestrictions(_restrictionsFacet, _target, _value, _data) != 0)\n revert AccountFacet__RestrictionsFailure();\n\n (bool success, bytes memory result) = _target.call{value: _value}(\n _data\n );\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n }\n\n /**\n * @notice Checks restrictions if the restrictions facet exists\n * @dev This method checks if the restrictions facet exists and makes a verification call to an array of restrictions facet\n * @param _facet Address that holds the restrictions logic\n * @param _target Address the call is getting forwarded to\n * @param _value Amount of native coin the call is sending together with the call\n * @param _data Calldata to trigger execution in target address\n */\n function _checkRestrictions(\n address _facet,\n address _target,\n uint256 _value,\n bytes memory _data\n ) internal returns (uint256 result) {\n bytes memory call = abi.encodeWithSignature(\n \"verifyRestrictions(address,address,uint256,bytes)\",\n address(this),\n _target,\n _value,\n _data\n );\n (bool success, bytes memory response) = _facet.delegatecall(call);\n if (!success) revert AccountFacet__RestrictionsFailure();\n result = uint256(bytes32(response));\n }\n}\n" + }, + "contracts/facets/AccountRecoveryFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibFacetStorage, RecoveryStorage, RecoveryConfig, RecoveryApprovalConfig, ApprovalConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {IAccountRecoveryFacet} from \"./interfaces/IAccountRecoveryFacet.sol\";\n\n/**\n * @title Account Recovery Facet\n * @dev Contract that enables recovery of accounts when owner key is unavailable\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract AccountRecoveryFacet is IAccountRecoveryFacet, Modifiers {\n bytes constant UNINIT_CALL =\n abi.encodeWithSignature(\"uninitializeSigner()\");\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Approve recovery of account as guardian\n * @dev This method can only be called by guardian and guardian inputs the public key of the new owner\n * When the threshold(majority of guardians) passes, it automatically executes account recovery\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function approveAccountRecovery(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + _getApprovalValidationPeriod()\n );\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit RecoveryApproved(\n _recoveryPublicKey,\n msg.sender,\n approvalValidUntil\n );\n if (\n getRecoveryApprovalCountWithTimeValidity(recoveryPublicKeyHash) >=\n LibGuardian.majorityOfGuardians()\n ) _executeRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Revoke recovery of account as guardian\n * @dev This method can only be called by guardian and guardian inputs the public key of the new owner\n When the threshold(majority of guardians) passes, it automatically revokes account recovery when recovery is pending\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function revokeAccountRecoveryApproval(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n if (\n !rs\n .isNewOwnerApproved[recoveryPublicKeyHash][msg.sender].isApproved ||\n !(block.timestamp <\n rs\n .isNewOwnerApproved[recoveryPublicKeyHash][msg.sender]\n .validUntil)\n ) revert AccountRecoveryFacet__NonExistentApproval();\n\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(false, 0);\n emit RecoveryApprovalRevoked(_recoveryPublicKey, msg.sender);\n }\n\n /**\n * @notice Executes recovery with signatures or on-chain pre-approvals\n * @dev This method validates the signatures of guardians or checks the on-chain pre-approved calls to check if the threshold passes\n * When the threshold passes, account recovery is executed and revert otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _guardians Array of guardians address that are approving the recovery of Account\n * @param _signatures Array of signature bytes that signed the approval hash\n */\n function executeRecovery(\n bytes calldata _recoveryPublicKey,\n address[] calldata _guardians,\n bytes[] calldata _signatures\n ) external override {\n if (_isRecoveryPending())\n revert AccountRecoveryFacet__RecoveryAlreadyOngoing();\n if (_guardians.length != _signatures.length)\n revert AccountRecoveryFacet__InvalidArrayLength();\n validateNewOwner(_recoveryPublicKey);\n\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n\n _checkApprover(_guardians);\n _checkDuplicateOnChainApprover(recoveryPublicKeyHash, _guardians);\n\n if (\n _guardians.length +\n getRecoveryApprovalCountWithTimeValidity(\n recoveryPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians()\n ) revert AccountRecoveryFacet__InsufficientGuardians();\n for (uint256 i; i < _guardians.length; ) {\n if (!LibGuardian.isGuardian(_guardians[i]))\n revert AccountRecoveryFacet__InvalidGuardian();\n if (\n !SignatureChecker.isValidSignatureNow(\n _guardians[i],\n recoveryPublicKeyHash,\n _signatures[i]\n )\n ) revert AccountRecoveryFacet__InvalidGuardianSignature();\n unchecked {\n ++i;\n }\n }\n _executeRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Executes recovery of the account. Note that execution and finalization is a different process\n * @dev Executes the recovery and adds recovery data to recovery configuration. Locks the account\n * @param _recoveryPublicKey Public Key of the account for recovery\n */\n function _executeRecovery(bytes memory _recoveryPublicKey) internal {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n unchecked {\n ++rs.nonce;\n }\n uint64 executeAfter = uint64(block.timestamp + _getRecoveryPeriod());\n rs.recoveryConfigs[INNER_STRUCT] = RecoveryConfig(\n _recoveryPublicKey,\n executeAfter // NOTE: Remove guardian Count\n );\n LibAppStorage.setLock(\n block.timestamp + _getLockPeriod(),\n AccountRecoveryFacet.executeRecovery.selector\n );\n emit RecoveryExecuted(_recoveryPublicKey, executeAfter);\n }\n\n /**\n * @notice Finalize recovery after recovery pending period. Recovery pending period can be set by user beforehand in SecurityManager\n * @dev This method finalizes recovery and fully changes the ownership of the account to the newly inputted recovery public key\n */\n function finalizeRecovery() external override {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n if (\n uint64(block.timestamp) <=\n rs.recoveryConfigs[INNER_STRUCT].executeAfter\n ) revert AccountRecoveryFacet__RecoveryPeriodNotOver();\n bytes memory recoveryOwner = rs\n .recoveryConfigs[INNER_STRUCT]\n .recoveryPublicKey;\n\n delete rs.recoveryConfigs[INNER_STRUCT];\n\n LibAppStorage.setLock(0, bytes4(0));\n\n LibAppStorage.initiateSignerMigration();\n address verificationFacet = address(\n bytes20(\n LibDiamond.diamondStorage().facets[\n s.validateOwnerSignatureSelector\n ]\n )\n );\n (bool success, bytes memory result) = verificationFacet.delegatecall(\n UNINIT_CALL\n );\n if (!success) revert AccountRecoveryFacet__CallNotSuccesful();\n uint256 validationData = uint256(bytes32(result));\n if (validationData != 1)\n revert AccountRecoveryFacet__SignerUninitializationFailure();\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n recoveryOwner\n );\n (success, result) = verificationFacet.delegatecall(initCall);\n if (!success) revert AccountRecoveryFacet__CallNotSuccesful();\n validationData = uint256(bytes32(result));\n if (validationData != 1)\n revert AccountRecoveryFacet__SignerInitializationFailure();\n LibAppStorage.finalizeSignerMigration();\n emit RecoveryFinalized(recoveryOwner);\n }\n\n /**\n * @notice Approves the cancellation of recovery\n * @dev This method approves the cancellation of recovery when recovery is still pending - waiting for finalization\n * @param _recoveryPublicKey Bytes of public key which is pending for recovery\n */\n function approveCancelRecovery(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"CancelRecovery\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + _getApprovalValidationPeriod()\n );\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit RecoveryCancellationApproved(_recoveryPublicKey, msg.sender);\n if (\n getRecoveryApprovalCountWithTimeValidity(recoveryPublicKeyHash) >=\n LibGuardian.majorityOfGuardians()\n ) {\n _cancelRecovery(_recoveryPublicKey);\n }\n }\n\n /**\n * @notice Hardstops an ongoing recovery\n * @dev This method provides a safety mechanism to protect owners of malicious guardians.\n * Owners can hardstop recovery when an malicious guardians starts the recovery process.\n * @param _signature Signature of the owner that signs the hash to hardstop recovery\n */\n function hardstopRecovery(bytes calldata _signature) external override {\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n \"0\",\n \"HardstopRecovery\"\n );\n if (\n !SignatureChecker.isValidSignatureNow(\n address(this),\n recoveryPublicKeyHash,\n _signature\n )\n ) revert AccountRecoveryFacet__InvalidOwnerSignature();\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n unchecked {\n ++rs.nonce;\n }\n delete rs.recoveryConfigs[INNER_STRUCT];\n LibAppStorage.setLock(0, bytes4(0));\n emit RecoveryHardstopped();\n }\n\n /**\n * @notice Cancels recovery with signatures or on-chain pre-approvals\n * @dev This method validates the signatures of guardians or checks the on-chain pre-approved calls to check if the threshold passes\n * When the threshold passes, account recovery is canceled and revert otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _guardians Array of guardians address that are approving the recovery of Account\n * @param _signatures Array of signature bytes that signed the cancellation approval hash\n */\n function cancelRecovery(\n bytes calldata _recoveryPublicKey,\n address[] calldata _guardians,\n bytes[] calldata _signatures\n ) external override {\n if (_guardians.length != _signatures.length)\n revert AccountRecoveryFacet__InvalidArrayLength();\n validateNewOwner(_recoveryPublicKey);\n\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"CancelRecovery\"\n );\n\n _checkApprover(_guardians);\n _checkDuplicateOnChainApprover(recoveryPublicKeyHash, _guardians);\n\n if (\n _guardians.length +\n getRecoveryApprovalCountWithTimeValidity(\n recoveryPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians()\n ) revert AccountRecoveryFacet__InsufficientGuardians();\n for (uint256 i; i < _guardians.length; ) {\n if (!LibGuardian.isGuardian(_guardians[i]))\n revert AccountRecoveryFacet__CallerNotGuardian();\n if (\n !SignatureChecker.isValidSignatureNow(\n _guardians[i],\n recoveryPublicKeyHash,\n _signatures[i]\n )\n ) revert AccountRecoveryFacet__InvalidGuardianSignature();\n unchecked {\n ++i;\n }\n }\n _cancelRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Cancel recovery when the recovery is pending. Unlock the account as well\n * @dev This method checks if the recovery is pending and reverts if not pending.\n * It increases the recovery nonce and deletes the recovery information and gets a small portion of gas in return\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function _cancelRecovery(bytes memory _recoveryPublicKey) internal {\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n LibAppStorage.setLock(0, bytes4(0));\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n unchecked {\n ++rs.nonce;\n }\n delete rs.recoveryConfigs[INNER_STRUCT];\n emit RecoveryCanceled(_recoveryPublicKey);\n }\n\n /**\n * @notice Validates the format of public key to be used for recovery\n * @dev This method checks if the public key format is correct and reverts otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function validateNewOwner(bytes memory _recoveryPublicKey) public view {\n if (\n !IVerificationFacet(\n LibLoupe.facetAddress(s.validateOwnerSignatureSelector)\n ).isValidKeyType(_recoveryPublicKey)\n ) revert AccountRecoveryFacet__InvalidRecoveryPublicKey();\n }\n\n /**\n * @notice Checks if recovery is currently pending\n * @return isPending Boolean indicating if recovery is pending\n */\n function _isRecoveryPending() internal view returns (bool isPending) {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n isPending = (rs.recoveryConfigs[INNER_STRUCT].executeAfter > 0);\n }\n\n /**\n * @notice Calculate the recovery hash dependent on chain, wallet address, nonce with EIP-191 prefix for safety\n * @dev Returns the keccak256 hash of EIP-191 msg hash packed with public key, salt, nonce, wallet address, etc\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _saltString Salt string to uniquely identify each recovery hash and for security\n * @return recoveryKeyHash Bytes32 string of the recovery hash\n */\n function getApprovalRecoveryKeyHash(\n bytes memory _recoveryPublicKey,\n string memory _saltString\n ) public view override returns (bytes32 recoveryKeyHash) {\n recoveryKeyHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n _recoveryPublicKey,\n _saltString,\n address(this),\n block.chainid,\n LibFacetStorage.recoveryStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Check the onchain approval of guardians and returns the number of guardians that approved\n * @dev Loop through the guardian addresses and returns the number of guardians that approved this recovery hash\n * @param _recoveryPublicKeyHash Bytes hash of newly recovered public key and recovery value of the account\n * @return approvalCount Number of guardians that approved\n */\n function getRecoveryApprovalCountWithTimeValidity(\n bytes32 _recoveryPublicKeyHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n for (uint256 i; i < guardianLength; ) {\n if (isRecoveryApproved(_recoveryPublicKeyHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Checks if the recovery is approved by the given approver\n * @param _recoveryPublicKeyHash Hash of the public key and configuration for recovery\n * @param _approver Address of approver\n * @return isApproved Bool value if recovery hash is approved\n */\n function isRecoveryApproved(\n bytes32 _recoveryPublicKeyHash,\n address _approver\n ) public view override returns (bool isApproved) {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n if (\n rs\n .isNewOwnerApproved[_recoveryPublicKeyHash][_approver].isApproved &&\n block.timestamp <\n rs.isNewOwnerApproved[_recoveryPublicKeyHash][_approver].validUntil\n ) {\n isApproved = true;\n }\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _recoveryPublicKeyHash Hash of recovery information\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _recoveryPublicKeyHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isRecoveryApproved(_recoveryPublicKeyHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert AccountRecoveryFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the lock period of this wallet address from security manager\n * @return lockPeriod value of lock period\n */\n function _getLockPeriod() internal view returns (uint256 lockPeriod) {\n lockPeriod = securityManager.lockPeriodOf(address(this));\n if (lockPeriod == 0) revert AccountRecoveryFacet__InvalidLockPeriod();\n }\n\n /**\n * @notice Returns the lock period of this wallet address from security manager\n * @return recoveryPeriod value of recovery period\n */\n function _getRecoveryPeriod()\n internal\n view\n returns (uint256 recoveryPeriod)\n {\n recoveryPeriod = securityManager.recoveryPeriodOf(address(this));\n if (recoveryPeriod == 0)\n revert AccountRecoveryFacet__InvalidRecoveryPeriod();\n }\n\n /**\n * @notice Returns the approval validation period of this wallet address from security manager\n * @return approvalValidationPeriod value of approval validation period\n */\n function _getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod == 0)\n revert AccountRecoveryFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the recovery nonce of this wallet address from security manager\n * @return nonce value of recovery nonce\n */\n function getRecoveryNonce() public view override returns (uint128 nonce) {\n nonce = LibFacetStorage.recoveryStorage().nonce;\n }\n\n /**\n * @notice Returns the recovery information of the pending recovery\n * @return recoveryConfig value struct of pending recovery\n */\n function getPendingRecovery()\n public\n view\n override\n returns (RecoveryConfig memory recoveryConfig)\n {\n recoveryConfig = LibFacetStorage.recoveryStorage().recoveryConfigs[\n INNER_STRUCT\n ];\n }\n}\n" + }, + "contracts/facets/base/DiamondCutFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibGuardian} from \"../../libraries/LibGuardian.sol\";\nimport {ISecurityManager} from \"../../infrastructure/interfaces/ISecurityManager.sol\";\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibFacetStorage, DiamondCutApprovalConfig, ApprovalConfig} from \"../../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"../Modifiers.sol\";\nimport {IDiamondCut} from \"./interfaces/IDiamondCut.sol\";\n\n/**\n * @title DiamondCut Facet\n * @dev Responsible for adding/removing/replace facets in Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DiamondCutFacet is Modifiers, IDiamondCut {\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Updates the flag for the interfaceId\n * @param _interfaceId InterfaceID to update the mapping\n * @param _flag Bool value to update the mapping of the given interface ID\n */\n function updateSupportsInterface(\n bytes4 _interfaceId,\n bool _flag\n ) external override onlyWhenUnlocked {\n LibDiamond.enforceIsSelf();\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId] = _flag;\n emit SupportsInterfaceUpdated(_interfaceId, _flag);\n }\n\n /**\n * @notice Add/replace/remove any number of functions and optionally execute\n * a function with delegatecall when guardians don't exist\n * @param _diamondCut Contains the facet addresses and function selectors\n * @param _init The address of the contract or facet to execute _calldata. It's prohibited in Barz\n */\n function diamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata\n ) external override onlyWhenUnlocked {\n LibDiamond.enforceIsSelf();\n\n _checkFacetCutValidity(_diamondCut);\n // require approval from guardian if guardian exists\n if (0 != LibGuardian.guardianCount())\n revert DiamondCutFacet__InvalidRouteWithGuardian();\n if (address(0) != _init) revert DiamondCutFacet__InvalidInitAddress();\n\n unchecked {\n ++LibFacetStorage.diamondCutStorage().nonce;\n }\n LibDiamond.diamondCut(_diamondCut, address(0), \"\");\n }\n\n /**\n * @notice Add/replace/remove any number of functions and optionally execute\n * a function with delegatecall when guardians exist\n * @param _diamondCut Contains the facet addresses and function selectors\n * @param _approvers Guardian or owner address that approves the diamond cut\n * @param _signatures Signature of Guardians or owner that approves the diamond cut\n */\n function diamondCutWithGuardian(\n FacetCut[] calldata _diamondCut,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n ) external override onlyWhenUnlocked {\n if (_approvers.length != _signatures.length)\n revert DiamondCutFacet__InvalidArrayLength();\n _checkFacetCutValidity(_diamondCut);\n if (0 == LibGuardian.guardianCount())\n revert DiamondCutFacet__InvalidRouteWithGuardian();\n\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(cutHash, _approvers);\n\n bool onChainOwnerApproval = getOwnerCutApprovalWithTimeValidity(\n cutHash\n );\n\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n if (\n _approvers.length +\n getDiamondCutApprovalCountWithTimeValidity(cutHash) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert DiamondCutFacet__InsufficientApprovers();\n\n bool ownerApproved;\n for (uint256 i; i < _approvers.length; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n _approvers[i] != address(this)\n ) revert DiamondCutFacet__InvalidApprover();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert DiamondCutFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n cutHash,\n _signatures[i]\n )\n ) revert DiamondCutFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n if (!ownerApproved && !onChainOwnerApproval)\n revert DiamondCutFacet__LackOfOwnerApproval();\n\n unchecked {\n ++LibFacetStorage.diamondCutStorage().nonce;\n }\n LibDiamond.diamondCut(_diamondCut, address(0), \"\");\n }\n\n /**\n * @notice Approves diamond cut. This can only be called directly from guardian or owner\n * @param _diamondCut Contains the facet addresses and function selectors\n */\n function approveDiamondCut(\n FacetCut[] calldata _diamondCut\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\n if (LibGuardian.guardianCount() == 0)\n revert DiamondCutFacet__InvalidRouteWithoutGuardian();\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n _checkFacetCutValidity(_diamondCut);\n\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(\n true,\n approvalValidUntil\n );\n emit DiamondCutApproved(_diamondCut);\n if (\n (getDiamondCutApprovalCountWithTimeValidity(cutHash) >=\n LibGuardian.majorityOfGuardians()) &&\n getOwnerCutApprovalWithTimeValidity(cutHash)\n ) {\n unchecked {\n ++LibFacetStorage.diamondCutStorage().nonce;\n }\n LibDiamond.diamondCut(_diamondCut, address(0), \"\");\n }\n }\n\n /**\n * @notice Revokes the approval of diamond cut. This can only be called directly from guardian or owner\n * @param _diamondCut Contains the facet addresses and function selectors\n */\n function revokeDiamondCutApproval(\n FacetCut[] calldata _diamondCut\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\n if (!ds.isDiamondCutApproved[cutHash][msg.sender].isApproved)\n revert DiamondCutFacet__CannotRevokeUnapproved();\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(false, 0);\n emit DiamondCutApprovalRevoked(_diamondCut);\n }\n\n /**\n * @notice Gets the number of approvals of diamond cut from guardians\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n */\n function getDiamondCutApprovalCountWithTimeValidity(\n bytes32 _diamondCutHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardiansLength = guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n if (isCutApproved(_diamondCutHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n return approvalCount;\n }\n\n /**\n * @notice Returns if the owner has approved the diamond cut\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @return isApprovedByOwner Bool value showing if the owner approved the cut\n */\n function getOwnerCutApprovalWithTimeValidity(\n bytes32 _diamondCutHash\n ) public view override returns (bool isApprovedByOwner) {\n isApprovedByOwner = isCutApproved(_diamondCutHash, address(this));\n }\n\n /**\n * @notice Returns if the given approver has approved the diamond cut\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @param _approver Address of approver\n * @return isApproved Bool value showing if the approver approved the cut\n */\n function isCutApproved(\n bytes32 _diamondCutHash,\n address _approver\n ) public view override returns (bool isApproved) {\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n isApproved = (ds\n .isDiamondCutApproved[_diamondCutHash][_approver].isApproved &&\n block.timestamp <\n ds.isDiamondCutApproved[_diamondCutHash][_approver].validUntil);\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _diamondCutHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isCutApproved(_diamondCutHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert DiamondCutFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the diamond cut hash. This function ensures that this hash is safe from replay attack by including\n * salt, address, chainId, and nonce, etc.\n * @param _diamondCut Contains the facet addresses and function selectors\n * @return cutHash Diamond Cut Hash\n */\n function getDiamondCutHash(\n FacetCut[] calldata _diamondCut\n ) public view override returns (bytes32 cutHash) {\n cutHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n keccak256(abi.encode(_diamondCut)),\n address(this),\n block.chainid,\n LibFacetStorage.diamondCutStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Returns the approval validation Period\n * @dev This method fetches the validation period from the security manager\n * @return approvalValidationPeriod Approval validation period of Barz contract fetched from security manager\n */\n function getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod <= 0)\n revert DiamondCutFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the diamond cut nonce of this wallet\n * @dev This method fetches the nonce from diamond cut storage\n * @return cutNonce Nonce of diamond cut to protect from reply attacks\n */\n function getDiamondCutNonce()\n public\n view\n override\n returns (uint128 cutNonce)\n {\n cutNonce = LibFacetStorage.diamondCutStorage().nonce;\n }\n}\n" + }, + "contracts/facets/base/DiamondLoupeFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {IERC165} from \"../../interfaces/ERC/IERC165.sol\";\nimport {IERC1271} from \"../../interfaces/ERC/IERC1271.sol\";\nimport {IERC677Receiver} from \"../../interfaces/ERC/IERC677Receiver.sol\";\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC1155Receiver} from \"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\";\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../../libraries/LibLoupe.sol\";\nimport {LibUtils} from \"../../libraries/LibUtils.sol\";\nimport {IDiamondCut} from \"../../facets/base/interfaces/IDiamondCut.sol\";\nimport {IStorageLoupe} from \"./interfaces/IStorageLoupe.sol\";\nimport {IDiamondLoupe} from \"./interfaces/IDiamondLoupe.sol\";\n\n/**\n * @title DiamondLoupe Facet\n * @dev DiamondLoupe contract compatible with EIP-2535\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DiamondLoupeFacet is IDiamondLoupe, IStorageLoupe, IERC165 {\n // Diamond Loupe Functions\n ////////////////////////////////////////////////////////////////////\n /// These functions are expected to be called frequently by tools off-chain.\n\n /**\n * @notice Gets all facets and their selectors.\n * @dev Barz uses a special architecture called default fallback handler. Default Fallback handler is used as a middleware\n * that holds the mapping of facet function selector and facet address that Barz uses. This helps Barz to reduce\n * significant amount of gas during the initialization process.\n * Hence, this method aggregates both the facet information from DefaulFallbackHandler and in diamond storage and shows the data to users.\n * @return facets_ Facet\n */\n function facets() public view override returns (Facet[] memory facets_) {\n Facet[] memory defaultFacet = LibDiamond\n .diamondStorage()\n .defaultFallbackHandler\n .facets();\n Facet[] memory _facets = LibLoupe.facets();\n uint256 numFacets = _facets.length;\n bytes4[] memory keys;\n address[] memory values;\n for (uint256 i; i < numFacets; ) {\n uint256 selectorsLength = _facets[i].functionSelectors.length;\n for (uint256 j; j < selectorsLength; ) {\n (keys, values) = LibUtils.setValue(\n keys,\n values,\n _facets[i].functionSelectors[j],\n _facets[i].facetAddress\n );\n unchecked {\n ++j;\n }\n }\n unchecked {\n ++i;\n }\n }\n {\n bool iIncrement;\n for (uint256 i; i < defaultFacet.length; ) {\n bool jIncrement;\n for (\n uint256 j;\n j < defaultFacet[i].functionSelectors.length;\n\n ) {\n if (\n LibUtils.getValue(\n keys,\n values,\n defaultFacet[i].functionSelectors[j]\n ) != address(0)\n ) {\n if (defaultFacet[i].functionSelectors.length == 1) {\n defaultFacet = LibUtils.removeFacetElement(\n defaultFacet,\n i\n );\n iIncrement = true;\n break;\n }\n defaultFacet[i].functionSelectors = LibUtils\n .removeElement(\n defaultFacet[i].functionSelectors,\n j\n );\n jIncrement = true;\n }\n if (!jIncrement) {\n unchecked {\n ++j;\n }\n } else {\n jIncrement = false;\n }\n }\n if (!iIncrement) {\n unchecked {\n ++i;\n }\n } else {\n iIncrement = false;\n }\n }\n }\n {\n uint256 facetLength = numFacets + defaultFacet.length;\n facets_ = new Facet[](facetLength);\n uint256 defaultFacetIndex;\n for (uint256 i; i < facetLength; ) {\n if (i < numFacets) {\n facets_[i] = _facets[i];\n bool jIncrementor;\n for (uint256 j; j < defaultFacet.length; ) {\n if (\n facets_[i].facetAddress ==\n defaultFacet[j].facetAddress\n ) {\n facets_[i].functionSelectors = LibUtils.mergeArrays(\n _facets[i].functionSelectors,\n defaultFacet[j].functionSelectors\n );\n defaultFacet = LibUtils.removeFacetElement(\n defaultFacet,\n j\n );\n jIncrementor = true;\n {\n facets_ = LibUtils.removeFacetElement(\n facets_,\n facets_.length - 1\n );\n }\n --facetLength;\n }\n if (!jIncrementor) {\n unchecked {\n ++j;\n }\n } else {\n jIncrementor = false;\n }\n }\n } else {\n facets_[i] = defaultFacet[defaultFacetIndex];\n ++defaultFacetIndex;\n }\n unchecked {\n ++i;\n }\n }\n }\n }\n\n /**\n * @notice Gets all the function selectors provided by a facet.\n * @param _facet The facet address.\n * @return facetFunctionSelectors_\n */\n function facetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n Facet[] memory facet = facets();\n uint256 facetLength = facet.length;\n for (uint256 i; i < facetLength; ) {\n if (facet[i].facetAddress == _facet)\n return facet[i].functionSelectors;\n unchecked {\n ++i;\n }\n }\n return facetFunctionSelectors_;\n }\n\n /**\n * @notice Get all the facet addresses used by Barz.\n * @return facetAddresses_\n */\n function facetAddresses()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n Facet[] memory facet = facets();\n uint256 facetLength = facet.length;\n facetAddresses_ = new address[](facetLength);\n for (uint256 i; i < facetLength; ) {\n facetAddresses_[i] = facet[i].facetAddress;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Gets the facet that supports the given selector.\n * @dev If facet is not found return address(0).\n * @param _functionSelector The function selector.\n * @return facetAddress_ The facet address.\n */\n function facetAddress(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n\n facetAddress_ = address(bytes20(ds.facets[_functionSelector]));\n if (facetAddress_ == address(0)) {\n facetAddress_ = IDiamondLoupe(ds.defaultFallbackHandler)\n .facetAddress(_functionSelector);\n }\n }\n\n /**\n * @notice SupportInterface to be compatible with EIP 165\n * @param _interfaceId Interface ID for detecting the interface\n * @return isSupported Bool value showing if the standard is supported in the contract\n */\n function supportsInterface(\n bytes4 _interfaceId\n ) external view override returns (bool isSupported) {\n isSupported =\n _interfaceId == type(IERC165).interfaceId ||\n _interfaceId == IDiamondCut.diamondCut.selector ||\n _interfaceId == type(IDiamondLoupe).interfaceId ||\n _interfaceId == type(IERC1155Receiver).interfaceId ||\n _interfaceId == type(IERC721Receiver).interfaceId ||\n _interfaceId == type(IERC777Recipient).interfaceId ||\n _interfaceId == IERC1271.isValidSignature.selector ||\n _interfaceId == type(IERC677Receiver).interfaceId ||\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId];\n }\n\n /**\n * @notice Returns the facet from the diamond storage. This excludes the facets from the default fallback handler\n * @return facets_ Facet information attached directly to diamond storage\n */\n function facetsFromStorage()\n external\n view\n override\n returns (Facet[] memory facets_)\n {\n facets_ = LibLoupe.facets();\n }\n\n /**\n * @notice Returns the facet address attached to the given function selector. This excludes the facets from the default fallback handler\n * @param _functionSelector Function selector to fetch the facet address from diamond storage\n * @return facetAddress_ Facet address mapped with the function selector\n */\n function facetAddressFromStorage(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n facetAddress_ = LibLoupe.facetAddress(_functionSelector);\n }\n\n /**\n * @notice Returns all facet addresses attached directly to diamond storage. This excludes the facets from the default fallback handler\n * @return facetAddresses_ All facet addresses attached directly to diamond storage\n */\n function facetAddressesFromStorage()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n facetAddresses_ = LibLoupe.facetAddresses();\n }\n\n /**\n * @notice Returns function selectors of given facet address attached directly to diamond storage. This excludes the facets from the default fallback handler\n * @param _facet Facet address to fetch the facet function selectors from diamond storage\n * @return facetFunctionSelectors_ Facet function selectors of the given facet address\n */\n function facetFunctionSelectorsFromStorage(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n facetFunctionSelectors_ = LibLoupe.facetFunctionSelectors(_facet);\n }\n}\n" + }, + "contracts/facets/base/interfaces/IDiamondCut.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title DiamondCut Facet Interface\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IDiamondCut {\n error DiamondCutFacet__InvalidRouteWithGuardian();\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\n error DiamondCutFacet__InvalidArrayLength();\n error DiamondCutFacet__InsufficientApprovers();\n error DiamondCutFacet__InvalidApprover();\n error DiamondCutFacet__InvalidApproverSignature();\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\n error DiamondCutFacet__CannotRevokeUnapproved();\n error DiamondCutFacet__LackOfOwnerApproval();\n error DiamondCutFacet__OwnerAlreadyApproved();\n error DiamondCutFacet__DuplicateApproval();\n error DiamondCutFacet__InvalidInitAddress();\n\n event DiamondCutApproved(FacetCut[] diamondCut);\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\n\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\n\n enum FacetCutAction {\n Add,\n Replace,\n Remove\n }\n // Add=0, Replace=1, Remove=2\n\n struct FacetCut {\n address facetAddress;\n FacetCutAction action;\n bytes4[] functionSelectors;\n }\n\n /// @notice Add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param diamondCut Contains the facet addresses and function selectors\n /// @param init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function diamondCut(\n FacetCut[] calldata diamondCut,\n address init,\n bytes calldata _calldata\n ) external;\n\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\n\n function diamondCutWithGuardian(\n FacetCut[] calldata diamondCut,\n address[] calldata approvers,\n bytes[] calldata signatures\n ) external;\n\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\n\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\n\n function getDiamondCutApprovalCountWithTimeValidity(\n bytes32 diamondCutHash\n ) external view returns (uint256);\n\n function getOwnerCutApprovalWithTimeValidity(\n bytes32 diamondCutHash\n ) external view returns (bool);\n\n function isCutApproved(\n bytes32 diamondCutHash,\n address approver\n ) external view returns (bool);\n\n function getDiamondCutHash(\n FacetCut[] calldata diamondCut\n ) external view returns (bytes32);\n\n function getDiamondCutNonce() external view returns (uint128);\n}\n" + }, + "contracts/facets/base/interfaces/IDiamondLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n// A loupe is a small magnifying glass used to look at diamonds.\n// These functions look at diamonds\ninterface IDiamondLoupe {\n /// These functions are expected to be called frequently\n /// by tools.\n\n struct Facet {\n address facetAddress;\n bytes4[] functionSelectors;\n }\n\n /// @notice Gets all facet addresses and their four byte function selectors.\n /// @return facets_ Facet\n function facets() external view returns (Facet[] memory facets_);\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n /// @return facetFunctionSelectors_\n function facetFunctionSelectors(\n address _facet\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses()\n external\n view\n returns (address[] memory facetAddresses_);\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(\n bytes4 _functionSelector\n ) external view returns (address facetAddress_);\n}\n" + }, + "contracts/facets/base/interfaces/IStorageLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"./IDiamondLoupe.sol\";\n\n/**\n * @title LoupeFromStorage Interface\n * @dev Interface contract to function as a loupe facet directly attached to diamond storage of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IStorageLoupe {\n /// These functions are expected to be called frequently\n /// by tools.\n\n /// @notice Gets all facet addresses and their four byte function selectors.\n /// @return facets_ Facet\n function facetsFromStorage()\n external\n view\n returns (IDiamondLoupe.Facet[] memory);\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n function facetFunctionSelectorsFromStorage(\n address _facet\n ) external view returns (bytes4[] memory);\n\n /// @notice Get all the facet addresses used by a diamond.\n function facetAddressesFromStorage()\n external\n view\n returns (address[] memory);\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n function facetAddressFromStorage(\n bytes4 _functionSelector\n ) external view returns (address);\n}\n" + }, + "contracts/facets/GuardianFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibFacetStorage, GuardianStorage, StorageConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IGuardianFacet} from \"./interfaces/IGuardianFacet.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Guardian Facet\n * @dev Contract that enables addition/removal of guardians from Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract GuardianFacet is IGuardianFacet {\n ISecurityManager public immutable securityManager;\n uint8 public constant INNER_STRUCT = 0;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Add guardians to Barz.\n * @dev This method internally calls addGuardian which checks the validity of guardian address and adds\n * as guardian if valid\n * @param _guardians Array of addresses to add as guardian\n */\n function addGuardians(address[] calldata _guardians) external override {\n LibDiamond.enforceIsSelf();\n for (uint256 i; i < _guardians.length; ) {\n addGuardian(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Add a guardian to Barz.\n * @dev This method checks if the function is called by the owner and validates the address of guardian\n * When the validation passes, guardian address is added to the pending state waiting for confirmation\n * @param _guardian Address to add as guardian\n */\n function addGuardian(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (_guardian == address(this))\n revert GuardianFacet__GuardianCannotBeSelf();\n if (isGuardian(_guardian)) revert GuardianFacet__DuplicateGuardian();\n if (_guardian == address(0))\n revert GuardianFacet__ZeroAddressGuardian();\n if (\n keccak256(abi.encodePacked(_guardian)) ==\n keccak256(IVerificationFacet(address(this)).owner())\n ) revert GuardianFacet__OwnerCannotBeGuardian();\n\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n if (\n gs.pending[id] != 0 ||\n block.timestamp <= gs.pending[id] + getSecurityWindow()\n ) revert GuardianFacet__DuplicateGuardianAddition();\n\n uint256 securityPeriod = getAdditionSecurityPeriod();\n gs.pending[id] = block.timestamp + securityPeriod;\n emit GuardianAdditionRequested(\n _guardian,\n block.timestamp + securityPeriod\n );\n }\n\n /**\n * @notice Remove guardians from Barz.\n * @dev This method internally calls removeGuardian which checks the validity of guardian and removes\n * guardian when the request is valid\n * @param _guardians Array of addresses to be removed\n */\n function removeGuardians(address[] calldata _guardians) external override {\n LibDiamond.enforceIsSelf();\n for (uint256 i; i < _guardians.length; ) {\n removeGuardian(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Remove a guardian from Barz.\n * @dev This method validates if the guardian to be removed is a guardian and puts the guardian removal\n * to a pending state waiting to be confirmed.\n * @param _guardian Address of guardian to be removed\n */\n function removeGuardian(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n if (!isGuardian(_guardian)) revert GuardianFacet__NonExistentGuardian();\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n if (\n gs.pending[id] != 0 ||\n block.timestamp <= gs.pending[id] + getSecurityWindow()\n ) revert GuardianFacet__DuplicateGuardianRemoval();\n\n uint256 securityPeriod = getRemovalSecurityPeriod();\n gs.pending[id] = block.timestamp + securityPeriod;\n emit GuardianRemovalRequested(\n _guardian,\n block.timestamp + securityPeriod\n );\n }\n\n /**\n * @notice Confirm addition of guardians\n * @dev This method internally calls confirmGuardianAddition which checks the validity of pending request.\n * Guardians are fully added when they pass the validation. Anyone can call this function.\n * @param _guardians Array of guardian addresses to be added\n */\n function confirmGuardianAdditions(\n address[] calldata _guardians\n ) external override {\n for (uint256 i; i < _guardians.length; ) {\n confirmGuardianAddition(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Confirm addition of a guardian\n * @dev This method checks the validity of pending request.\n * Guardians are fully added when they pass the validation. Anyone can call this function.\n * @param _guardian Guardian address to be added\n */\n function confirmGuardianAddition(address _guardian) public override {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingAddition();\n if (gs.pending[id] >= block.timestamp)\n revert GuardianFacet__PendingAdditionNotOver();\n if (block.timestamp >= gs.pending[id] + getSecurityWindow())\n revert GuardianFacet__PendingAdditionExpired();\n\n _addGuardian(_guardian);\n\n delete gs.pending[id];\n emit GuardianAdded(_guardian);\n }\n\n /**\n * @notice Confirm removal of guardians\n * @dev This method internally calls confirmGuardianRemoval to check the validity guardian removal confirmation.\n * Guardians are fully removed when they pass the validation. Anyone can call this function.\n * @param _guardians Array of guardian addresses to be removed\n */\n function confirmGuardianRemovals(\n address[] calldata _guardians\n ) external override {\n for (uint256 i; i < _guardians.length; ) {\n confirmGuardianRemoval(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Confirm removal of a guardian\n * @dev This method checks the validity guardian removal confirmation.\n * Guardian is fully removed when they pass the validation. Anyone can call this function.\n * @param _guardian Guardian address to be removed\n */\n function confirmGuardianRemoval(address _guardian) public override {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingRemoval();\n if (gs.pending[id] >= block.timestamp)\n revert GuardianFacet__PendingRemovalNotOver();\n if (block.timestamp >= gs.pending[id] + getSecurityWindow())\n revert GuardianFacet__PendingAdditionExpired();\n\n _removeGuardian(_guardian);\n delete gs.pending[id];\n emit GuardianRemoved(_guardian);\n }\n\n /**\n * @notice Cancel pending guardian addition\n * @dev This method checks if the previous request for guardian request exists.\n * It reverts if previous request is not pending and cancels the addition otherwise.\n * @param _guardian Guardian address to be canceled from addition\n */\n function cancelGuardianAddition(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingAddition();\n delete gs.pending[id];\n emit GuardianAdditionCancelled(_guardian);\n }\n\n /**\n * @notice Cancel pending guardian removal\n * @dev This method checks if the previous request for guardian request exists.\n * It reverts if previous request is not pending and cancels the removal otherwise.\n * @param _guardian Guardian address to be canceled from removal\n */\n function cancelGuardianRemoval(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingRemoval();\n delete gs.pending[id];\n emit GuardianRemovalCancelled(_guardian);\n }\n\n /**\n * @notice Get the addition security period of current account from security manager\n * @dev This method returns the uint value if addition security period\n * @return additionSecurityPeriod Uint256 value of addition security period\n */\n function getAdditionSecurityPeriod()\n public\n view\n override\n returns (uint256 additionSecurityPeriod)\n {\n additionSecurityPeriod = securityManager.additionSecurityPeriodOf(\n address(this)\n );\n if (additionSecurityPeriod == 0)\n revert GuardianFacet__InvalidAdditionSecurityPeriod();\n }\n\n /**\n * @notice Get the removal security period of current account from security manager\n * @dev This method returns the uint value if removal security period\n * @return removalSecurityPeriod Uint256 value of removal security period\n */\n function getRemovalSecurityPeriod()\n public\n view\n override\n returns (uint256 removalSecurityPeriod)\n {\n removalSecurityPeriod = securityManager.removalSecurityPeriodOf(\n address(this)\n );\n if (removalSecurityPeriod == 0)\n revert GuardianFacet__InvalidRemovalSecurityPeriod();\n }\n\n /**\n * @notice Get the security window of current account from security manager\n * @dev This method returns the uint value if security window\n * @return securityWindow Uint256 value of removal security period\n */\n function getSecurityWindow()\n public\n view\n override\n returns (uint256 securityWindow)\n {\n securityWindow = securityManager.securityWindowOf(address(this));\n if (securityWindow == 0) revert GuardianFacet__InvalidSecurityWindow();\n }\n\n /**\n * @notice Checks if the addition of the given guardian address is pending\n * @dev This method returns the bool value of whether the guardian address is pending addition\n * @return isPending Bool value of representing the pending of guardian addition\n */\n function isAdditionPending(\n address _guardian\n ) public view override returns (bool isPending) {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n isPending = _isPending(id);\n }\n\n /**\n * @notice Checks if the removal of the given guardian address is pending\n * @dev This method returns the bool value of whether the guardian address is pending removal\n * @return isPending Bool value of representing the pending of guardian removal\n */\n function isRemovalPending(\n address _guardian\n ) public view override returns (bool isPending) {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n isPending = _isPending(id);\n }\n\n /**\n * @notice Checks if the given hash is pending\n * @dev This method returns the bool value whether the hash is pending\n * @return isPending Bool value of representing the pending of guardian operation\n */\n function _isPending(\n bytes32 _idHash\n ) internal view returns (bool isPending) {\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n isPending = ((gs.pending[_idHash] > 0 &&\n gs.pending[_idHash] < block.timestamp) &&\n block.timestamp < gs.pending[_idHash] + getSecurityWindow());\n }\n\n /**\n * @notice Adds guardian to storage config. This is called when guardian is fully added.\n * @dev This method add guardian address and config information to Facet Storage dedicated for guardian\n * When this function is called, guardian is fully added to this Barz Smart Account\n * @param _guardian Address of guardian to be added\n */\n function _addGuardian(address _guardian) internal {\n if (!isAdditionPending(_guardian))\n revert GuardianFacet__InvalidGuardianAddition();\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n if (config.info[_guardian].exists)\n revert GuardianFacet__AlreadyExists();\n\n config.info[_guardian].exists = true;\n config.info[_guardian].index = uint128(config.addresses.length);\n config.addresses.push(_guardian);\n }\n\n /**\n * @notice Removes guardian to storage config. This is called when guardian is fully removed.\n * @dev This method remove guardian address and config information to Facet Storage dedicated for guardian\n * When this function is called, guardian is fully removed from this Barz Smart Account\n * @param _guardian Address of guardian to be removed\n */\n function _removeGuardian(address _guardian) internal {\n if (!isRemovalPending(_guardian))\n revert GuardianFacet__InvalidGuardianRemoval();\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n if (!config.info[_guardian].exists)\n revert GuardianFacet__NonExistentGuardian();\n\n address lastAddress = config.addresses[config.addresses.length - 1];\n if (_guardian != lastAddress) {\n uint128 targetIndex = config.info[_guardian].index;\n config.addresses[targetIndex] = lastAddress;\n config.info[lastAddress].index = targetIndex;\n }\n config.addresses.pop();\n delete config.info[_guardian];\n\n emit GuardianRemoved(_guardian);\n }\n\n /**\n * @notice Reads guardian storage and fetches the addresses into an array from the storage\n * @dev This method fetches the guardian storage and returns the list of guardian addresses\n * @return addresses Array of addresses comprised of guardian\n */\n function getGuardians()\n public\n view\n override\n returns (address[] memory addresses)\n {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n uint256 addressesLen = config.addresses.length;\n addresses = new address[](addressesLen);\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the number of majority of guardians\n * @return majorityOfGuardians_ Number of majority of guardians e.g., 2 if 3 guardians / 3 if 5 guardians\n */\n function majorityOfGuardians()\n public\n view\n override\n returns (uint256 majorityOfGuardians_)\n {\n majorityOfGuardians_ = LibGuardian.majorityOfGuardians();\n }\n\n /**\n * @notice Reads guardian storage and fetches the addresses into an array from the storage\n * @dev This method fetches the guardian storage and returns the list of guardian addresses\n * @return guardianNumber Array of guardians in the account\n */\n function guardianCount()\n public\n view\n override\n returns (uint256 guardianNumber)\n {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n guardianNumber = config.addresses.length;\n }\n\n /**\n * @notice Reads guardian storage and checks if the given address is a guardian\n * @return isGuardian_ Bool value representing if the given address is guardian\n */\n function isGuardian(\n address _guardian\n ) public view override returns (bool isGuardian_) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n isGuardian_ = config.info[_guardian].exists;\n }\n\n /**\n * @notice Checks if the guardian number is zero and returns of guardian facet is okay to be removed\n * @return isRemovable Bool value representing if guardian facet is removable\n */\n function isGuardianFacetRemovable()\n external\n view\n override\n returns (bool isRemovable)\n {\n isRemovable = (0 == guardianCount());\n }\n}\n" + }, + "contracts/facets/interfaces/IAccountFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IEntryPoint} from \"../../aa-4337/interfaces/IEntryPoint.sol\";\n\n/**\n * @title Account Facet Interface\n * @dev Interface of module contract that provides the account features and init/unitialization of signer\n * compatible with EIP-1271 & EIP-4337\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IAccountFacet {\n event AccountInitialized(\n IEntryPoint indexed entryPoint,\n bytes indexed ownerPublicKey\n );\n // NOTE: Added Below Event\n event VerificationSuccess(bytes32);\n event VerificationFailure(bytes32);\n\n error AccountFacet__InitializationFailure();\n error AccountFacet__RestrictionsFailure();\n error AccountFacet__NonExistentVerificationFacet();\n error AccountFacet__CallNotSuccessful();\n error AccountFacet__InvalidArrayLength();\n\n function initialize(\n address verificationFacet,\n address anEntryPoint,\n address facetRegistry,\n address _defaultFallBack,\n bytes calldata _ownerPublicKey\n ) external returns (uint256);\n\n function execute(address dest, uint256 value, bytes calldata func) external;\n\n function executeBatch(\n address[] calldata dest,\n uint256[] calldata value,\n bytes[] calldata func\n ) external;\n}\n" + }, + "contracts/facets/interfaces/IAccountRecoveryFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {RecoveryConfig} from \"../../libraries/LibFacetStorage.sol\";\n\n/**\n * @title Account Recovery Facet Interface\n * @dev Interface of contract that enables recovery of accounts when owner key is unavailable\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IAccountRecoveryFacet {\n event RecoveryExecuted(\n bytes indexed recoveryPublicKey,\n uint64 executeAfter\n );\n event RecoveryFinalized(bytes indexed recoveryPublicKey);\n event RecoveryCanceled(bytes indexed recoveryPublicKey);\n event RecoveryApproved(\n bytes indexed recoveryPublicKey,\n address indexed guardian,\n uint64 validUntil\n );\n event RecoveryApprovalRevoked(\n bytes indexed recoveryPublicKey,\n address indexed guardian\n );\n event RecoveryCancellationApproved(\n bytes indexed recoveryPublicKey,\n address indexed guardian\n );\n event RecoveryHardstopped();\n\n error AccountRecoveryFacet__CallerNotGuardian();\n error AccountRecoveryFacet__InvalidRecoveryPublicKey();\n error AccountRecoveryFacet__SignerInitializationFailure();\n error AccountRecoveryFacet__SignerUninitializationFailure();\n error AccountRecoveryFacet__InvalidArrayLength();\n error AccountRecoveryFacet__InsufficientGuardians();\n error AccountRecoveryFacet__RecoveryAlreadyOngoing();\n error AccountRecoveryFacet__NonexistentRecovery();\n error AccountRecoveryFacet__NonExistentApproval();\n error AccountRecoveryFacet__RecoveryPeriodNotOver();\n error AccountRecoveryFacet__InvalidLockPeriod();\n error AccountRecoveryFacet__InvalidRecoveryPeriod();\n error AccountRecoveryFacet__InvalidApprovalValidationPeriod();\n error AccountRecoveryFacet__InvalidGuardian();\n error AccountRecoveryFacet__InvalidGuardianSignature();\n error AccountRecoveryFacet__InvalidOwnerSignature();\n error AccountRecoveryFacet__CallNotSuccesful();\n error AccountRecoveryFacet__DuplicateApproval();\n\n function approveAccountRecovery(bytes calldata recoveryPublicKey) external;\n\n function revokeAccountRecoveryApproval(\n bytes calldata recoveryPublicKey\n ) external;\n\n function executeRecovery(\n bytes calldata recoveryPublicKey,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function finalizeRecovery() external;\n\n function approveCancelRecovery(bytes calldata recoveryPublicKey) external;\n\n function cancelRecovery(\n bytes calldata recoveryPublicKey,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function hardstopRecovery(bytes calldata signature) external;\n\n function getApprovalRecoveryKeyHash(\n bytes memory recoveryPublicKey,\n string memory saltString\n ) external view returns (bytes32);\n\n function getRecoveryApprovalCountWithTimeValidity(\n bytes32 recoveryPublicKeyHash\n ) external view returns (uint256);\n\n function isRecoveryApproved(\n bytes32 recoveryPublicKeyHash,\n address approver\n ) external view returns (bool);\n\n function getRecoveryNonce() external view returns (uint128);\n\n function getPendingRecovery() external view returns (RecoveryConfig memory);\n}\n" + }, + "contracts/facets/interfaces/IGuardianFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Guardian Facet Interface\n * @dev Interface of guaridna contract that enables addition/removal of guardians from Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IGuardianFacet {\n event GuardianAdditionRequested(\n address indexed guardian,\n uint256 executeAfter\n );\n event GuardianRemovalRequested(\n address indexed guardian,\n uint256 executeAfter\n );\n event GuardianAdditionCancelled(address indexed guardian);\n event GuardianRemovalCancelled(address indexed guardian);\n event GuardianAdded(address indexed guardian);\n event GuardianRemoved(address indexed guardian);\n\n error GuardianFacet__GuardianCannotBeSelf();\n error GuardianFacet__DuplicateGuardian();\n error GuardianFacet__OwnerCannotBeGuardian();\n error GuardianFacet__DuplicateGuardianAddition();\n error GuardianFacet__DuplicateGuardianRemoval();\n error GuardianFacet__UnknownPendingAddition();\n error GuardianFacet__PendingAdditionNotOver();\n error GuardianFacet__UnknownPendingRemoval();\n error GuardianFacet__PendingRemovalNotOver();\n error GuardianFacet__PendingAdditionExpired();\n error GuardianFacet__InvalidAdditionSecurityPeriod();\n error GuardianFacet__InvalidRemovalSecurityPeriod();\n error GuardianFacet__InvalidSecurityWindow();\n error GuardianFacet__NonExistentGuardian();\n error GuardianFacet__AlreadyExists();\n error GuardianFacet__InvalidGuardianAddition();\n error GuardianFacet__InvalidGuardianRemoval();\n error GuardianFacet__ZeroAddressGuardian();\n\n function addGuardian(address guardian) external;\n\n function addGuardians(address[] calldata guardians) external;\n\n function removeGuardian(address guardian) external;\n\n function removeGuardians(address[] calldata guardians) external;\n\n function confirmGuardianAddition(address guardian) external;\n\n function confirmGuardianAdditions(address[] calldata guardian) external;\n\n function confirmGuardianRemoval(address guardian) external;\n\n function confirmGuardianRemovals(address[] calldata guardian) external;\n\n function cancelGuardianAddition(address guardian) external;\n\n function cancelGuardianRemoval(address guardian) external;\n\n function isGuardian(address guardian) external view returns (bool);\n\n function isAdditionPending(address guardian) external view returns (bool);\n\n function isRemovalPending(address guardian) external view returns (bool);\n\n function isGuardianFacetRemovable() external view returns (bool);\n\n function getAdditionSecurityPeriod() external view returns (uint256);\n\n function getRemovalSecurityPeriod() external view returns (uint256);\n\n function getSecurityWindow() external view returns (uint256);\n\n function getGuardians() external view returns (address[] memory);\n\n function majorityOfGuardians() external view returns (uint256);\n\n function guardianCount() external view returns (uint256);\n}\n" + }, + "contracts/facets/interfaces/ILockFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Lock} from \"../../libraries/LibAppStorage.sol\";\n\n/**\n * @title Lock Facet Interface\n * @dev Interface of Lock contract that enables full lock/unlock of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface ILockFacet {\n event Locked(uint64 releaseAfter);\n event Unlocked();\n\n error LockFacet__InvalidRecoveryPeriod();\n error LockFacet__CannotUnlock();\n error LockFacet__InvalidSignature();\n error LockFacet__InvalidApprover();\n\n function lock() external;\n\n function unlock(address approver, bytes calldata signature) external;\n\n function getLockPeriod() external view returns (uint256);\n\n function isLocked() external view returns (bool);\n\n function getUnlockHash() external view returns (bytes32);\n\n function lockNonce() external view returns (uint128);\n\n function getPendingLock() external view returns (Lock memory);\n}\n" + }, + "contracts/facets/interfaces/IMultiSigFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Multi-sig facet Interface\n * @dev Interface of Multi-signature Facet with custom threshold.\n Wallet that adds this facet becomes a multi-sig wallet\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IMultiSigFacet {\n event ThresholdChanged(uint256 threshold);\n event OwnerAdded(address indexed newOwner);\n event OwnerRemoved(address indexed prevOwner);\n event HashApproved(bytes32 hashToApprove, address indexed owner);\n\n error MultiSigFacet__InvalidThreshold();\n error MultisigFacet__InvalidOwnerCount();\n error MultiSigFacet__InvalidRoute();\n error MultiSigFacet__InsufficientSignerLength();\n error MultiSigFacet__InvalidInitData();\n error MultiSigFacet__InvalidOwnerAddress();\n error MultiSigFacet__InvalidOwnerPair();\n error MultiSigFacet__InvalidSignatureLength();\n error MultiSigFacet__InvalidSignatureType();\n error MultiSigFacet__DuplicateOwner();\n error MultiSigFacet__OnlyOwner();\n\n function checkSignatures(\n bytes32 _dataHash,\n bytes calldata _signatures,\n uint256 _threshold\n ) external view returns (uint256);\n\n function splitSignatures(\n bytes calldata _signatures,\n uint256 _nextOffset\n )\n external\n pure\n returns (\n address owner,\n bytes memory signature,\n uint256 signatureType,\n uint256 nextOffset\n );\n\n function approveHash(bytes32 hashToApprove) external;\n\n function addOwner(address newOwner, uint256 threshold) external;\n\n function removeOwner(\n address prevOwner,\n address removedOwner,\n uint256 threshold\n ) external;\n\n function swapOwner(\n address prevOwner,\n address oldOwner,\n address newOwner\n ) external;\n\n function changeThreshold(uint256 _threshold) external;\n\n function isOwner(address owner) external view returns (bool);\n\n function getThreshold() external view returns (uint256);\n\n function getOwners() external view returns (address[] memory);\n}\n" + }, + "contracts/facets/interfaces/IRestrictionsFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Restrictions Facet Interface\n * @dev Interface of Restrictions contract that enables modular restrictions in Barz\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IRestrictionsFacet {\n event RestrictionAdded(address indexed restriction);\n event RestrictionRemoved(address indexed restriction);\n\n error RestrictionsFacet__EmptyRestrictionsList();\n error RestrictionsFacet__RestrictionNotFound();\n error RestrictionsFacet__RestrictionAlreadyExists();\n error RestrictionsFacet__ZeroAddressRestrictions();\n error RestrictionsFacet__ZeroAddressRestrictionsFacet();\n error RestrictionsFacet__RemainingRestrictionsCantBeEmpty();\n\n function initializeRestrictions(\n address[] memory _restrictions\n ) external returns (uint256);\n\n function uninitializeRestrictions() external returns (uint256);\n\n function getRestrictions() external view returns (address[] memory);\n\n function addRestriction(address restriction) external;\n\n function removeRestriction(address restriction) external;\n\n function verifyRestrictions(\n address from,\n address to,\n uint256 value,\n bytes calldata _calldata\n ) external returns (uint256);\n}\n" + }, + "contracts/facets/interfaces/ISignatureMigrationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureMigrationConfig} from \"../../libraries/LibFacetStorage.sol\";\n\n/**\n * @title Signature Migration Facet Interface\n * @dev Interface of Signature Migration contract for migrating user signature scheme to a new scheme user sets\n * Which could include\n * - ECDSA on Secp256K1 Curve\n * - ECDSA on Secp256R1 Curve\n * - BLS, Schnorr, etc\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface ISignatureMigrationFacet {\n event SignatureSchemeMigration(\n address indexed prevVerificationFacet,\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n event SignatureMigrationApproved(\n bytes newPublicKey,\n address indexed newVerificationFacet,\n bytes4[] verificationFuncSelectors,\n address indexed guardian,\n uint128 approvalValidUntil\n );\n event SignatureMigrationApprovalRevoked(\n bytes newPublicKey,\n address indexed newVerificationFacet,\n bytes4[] verificationFuncSelectors,\n address indexed guardian\n );\n event SignatureMigrationExecuted(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors,\n uint128 migrateAfter\n );\n event SignatureMigrationCanceled(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n event SignatureMigrationCancellationApproved(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n\n error SignatureMigrationFacet__SignerUninitializationFailure();\n error SignatureMigrationFacet__SignerInitializationFailure();\n error SignatureMigrationFacet__InvalidRouteWithGuardian();\n error SignatureMigrationFacet__InvalidKeyType();\n error SignatureMigrationFacet__InsufficientApprovers();\n error SignatureMigrationFacet__InvalidApproverSignature();\n error SignatureMigrationFacet__InvalidGuardian();\n error SignatureMigrationFacet__NonExistentApprover();\n error SignatureMigrationFacet__InvalidMigrationPeriod();\n error SignatureMigrationFacet__NonexistentMigration();\n error SignatureMigrationFacet__MigrationPeriodNotOver();\n error SignatureMigrationFacet__InvalidArrayLength();\n error SignatureMigrationFacet__InvalidApprovalValidationPeriod();\n error SignatureMigrationFacet__CannotRevokeUnapproved();\n error SignatureMigrationFacet__LackOfOwnerApproval();\n error SignatureMigrationFacet__OwnerAlreadyApproved();\n error SignatureMigrationFacet__NonExistentVerificationFacet();\n error SignatureMigrationFacet__DuplicateApproval();\n\n function migrateSignatureScheme(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function migrateSignatureSchemeWithGuardian(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors,\n address[] calldata approvers,\n bytes[] calldata signatures\n ) external;\n\n function approveSignatureSchemeMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function revokeSignatureMigrationApproval(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function finalizeSignatureMigration() external;\n\n function approveCancelSignatureMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function cancelSignatureMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function getApprovalMigrationKeyHash(\n bytes memory recoveryPublicKey,\n address newVerificationFacet,\n bytes4[] memory newVerificationFuncSelectors,\n string memory saltString\n ) external view returns (bytes32);\n\n function getMigrationOwnerApprovalWithTimeValidity(\n bytes32 publicKeyHash\n ) external view returns (bool);\n\n function getMigrationApprovalCountWithTimeValidity(\n bytes32 publicKeyHash\n ) external view returns (uint256);\n\n function isMigrationApproved(\n bytes32 migrationPublicKeyHash,\n address approver\n ) external view returns (bool);\n\n function getMigrationNonce() external view returns (uint128);\n\n function isMigrationPending() external view returns (bool);\n\n function getPendingMigration()\n external\n view\n returns (SignatureMigrationConfig memory);\n}\n" + }, + "contracts/facets/interfaces/IVerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {UserOperation} from \"../../aa-4337/interfaces/UserOperation.sol\";\n\n/**\n * @title Verification Facet Interface\n * @dev Implements logic for user ops signature verification\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface IVerificationFacet {\n event SignerInitialized(bytes);\n event SignerUninitialized();\n\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n error VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n error VerificationFacet__InitializationFailure();\n error VerificationFacet__InvalidFacetMapping();\n\n function initializeSigner(bytes memory) external returns (uint256);\n\n function uninitializeSigner() external returns (uint256);\n\n function validateOwnerSignatureSelector() external view returns (bytes4);\n\n function owner() external view returns (bytes memory);\n\n function isValidKeyType(bytes calldata) external view returns (bool);\n\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) external view returns (uint256);\n}\n" + }, + "contracts/facets/LockFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage, Lock} from \"../libraries/LibAppStorage.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibFacetStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {ILockFacet} from \"./interfaces/ILockFacet.sol\";\n\n/**\n * @title Lock Facet\n * @dev Contract that enables full lock/unlock of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract LockFacet is ILockFacet, Modifiers {\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Locks the account for the lock period. Lock period is defined in the security manager and it's customizable\n * This function can only be called when account is unlocked by owner or guardians\n * @dev This method checks the caller and if the account is currently locked and locks the account after fetching the\n * Lock period from the owner.\n */\n function lock() external override onlyGuardianOrOwner onlyWhenUnlocked {\n uint256 unlockTime = block.timestamp + getLockPeriod();\n unchecked {\n ++LibFacetStorage.lockStorage().nonce;\n }\n LibAppStorage.setLock(unlockTime, LockFacet.lock.selector);\n emit Locked(uint64(unlockTime));\n }\n\n /**\n * @notice Locks the account when the account is locked. This function can be called by anyone but must provide the approver address and signature.\n * The approver should be one of the guardians or owner.\n * @dev This method takes the approver address and the signature. After validating the address and the signature, it unlocks the account immediately.\n * Only one of the guardian or owner is required to lock and unlock the account.\n * @param _approver Address of approver approving the unlock of Barz account\n * @param _signature Signature of the approver that signed the msg hash for unlocking the account\n */\n function unlock(\n address _approver,\n bytes calldata _signature\n ) external override onlyWhenLocked {\n if (_approver != address(this) && !LibGuardian.isGuardian(_approver))\n revert LockFacet__InvalidApprover();\n if (\n !SignatureChecker.isValidSignatureNow(\n _approver,\n getUnlockHash(),\n _signature\n )\n ) revert LockFacet__InvalidSignature();\n _unlock();\n }\n\n /**\n * @notice Unlocks the account and increments the lock nonce\n */\n function _unlock() private {\n if (s.locks[INNER_STRUCT].locker != LockFacet.lock.selector)\n revert LockFacet__CannotUnlock();\n unchecked {\n ++LibFacetStorage.lockStorage().nonce;\n }\n LibAppStorage.setLock(0, bytes4(0));\n emit Unlocked();\n }\n\n /**\n * @notice Returns the lock period of current Barz account. Lock period information is held by Security Manager\n * @return lockPeriod Uint value of lock period in seconds\n */\n function getLockPeriod() public view override returns (uint256 lockPeriod) {\n lockPeriod = securityManager.lockPeriodOf(address(this));\n if (lockPeriod == 0) revert LockFacet__InvalidRecoveryPeriod();\n }\n\n /**\n * @notice Returns if the account is locked or not\n * @dev This method fetches the current block timestamp and compares that with release time.\n * After checking the timestamp and release time, it returns if the account is still locked or not.\n * @return isLocked_ Uint value of lock period in seconds\n */\n function isLocked() public view override returns (bool isLocked_) {\n isLocked_ = uint64(block.timestamp) < s.locks[INNER_STRUCT].release;\n }\n\n /**\n * @notice Calculates the unlock hash and returns the unlock hash safe from signature reply attack\n * @dev This method calculates the unlock hash with EIP-191 prefix, wallet address, chainID, and nonce\n * It packs the result and packs them and hashes it.\n * @return unlockHash Bytes32 unlock hash\n */\n function getUnlockHash() public view override returns (bytes32 unlockHash) {\n unlockHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n \"Unlock\",\n address(this),\n block.chainid,\n lockNonce()\n )\n )\n )\n );\n }\n\n /**\n * @notice Returns lock nonce of account. Reads nonce from lock storage within facet storage\n * @return lockNonce_ Uint128 value of lock nonce. This is incremented whenever the account is lock/unlocked\n */\n function lockNonce() public view override returns (uint128 lockNonce_) {\n lockNonce_ = LibFacetStorage.lockStorage().nonce;\n }\n\n /**\n * @notice Returns the overall information of current lock\n * @return pendingLock Struct value including all information of pending lock\n */\n function getPendingLock()\n public\n view\n override\n returns (Lock memory pendingLock)\n {\n pendingLock = s.locks[INNER_STRUCT];\n }\n}\n" + }, + "contracts/facets/Modifiers.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\n\n/**\n * @title Modifiers\n * @dev Responsible for providing modifiers/util functions to Facet contracts\n * @author David Yongjun Kim (@Powerstream3604)\n */\nabstract contract Modifiers is BarzStorage {\n uint8 constant INNER_STRUCT = 0;\n\n error CallerNotGuardian();\n error CallerNotGuardianOrOwner();\n error DuplicateApprover();\n error ZeroApproverLength();\n error UnregisteredFacetAndSelectors();\n\n /**\n * @notice Modifier to only allow guardian to make a call, reverts if any other entity is the caller\n */\n modifier onlyGuardian() {\n if (!LibGuardian.isGuardian(msg.sender)) revert CallerNotGuardian();\n _;\n }\n\n /**\n * @notice Modifier to only allow guardian or owner to make a call, reverts if any other entity is the caller\n */\n modifier onlyGuardianOrOwner() {\n if (!LibGuardian.isGuardian(msg.sender) && address(this) != msg.sender)\n revert CallerNotGuardianOrOwner();\n _;\n }\n\n /**\n * @notice Checks if the approver address is the array is unique with no duplicate\n * @dev This method loops through the array and checks if a duplicate address exists, it reverts if duplicate address exists\n * @param approvers Array of address\n */\n function _checkApprover(\n address[] memory approvers\n ) internal pure returns (bool) {\n uint256 approverLength = approvers.length;\n if (0 == approverLength) revert ZeroApproverLength();\n for (uint256 i; i < approverLength - 1; ) {\n for (uint256 j = i + 1; j < approverLength; ) {\n if (approvers[i] == approvers[j]) {\n revert DuplicateApprover(); // Found a duplicate\n }\n unchecked {\n ++j;\n }\n }\n unchecked {\n ++i;\n }\n }\n return false; // No duplicates found\n }\n\n /**\n * @notice Checks if the facet getting added or replaced is registered to facet registry\n * @dev This method loops through the cut and checks if the facet getting added/replaced is registered to facet registry\n * @param _diamondCut Array of FacetCut, data for diamondCut defined in EIP-2535\n */\n function _checkFacetCutValidity(\n IDiamondCut.FacetCut[] memory _diamondCut\n ) internal view {\n uint256 diamondCutLength = _diamondCut.length;\n for (uint256 i; i < diamondCutLength; ) {\n if (\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Add ||\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Replace\n ) {\n if (\n !s.facetRegistry.areFacetFunctionSelectorsRegistered(\n _diamondCut[i].facetAddress,\n _diamondCut[i].functionSelectors\n )\n ) revert UnregisteredFacetAndSelectors();\n }\n unchecked {\n ++i;\n }\n }\n }\n}\n" + }, + "contracts/facets/RestrictionsFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ReentrancyGuard} from \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, RestrictionsStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {IRestriction} from \"../restrictions/IRestriction.sol\";\nimport {IRestrictionsFacet} from \"./interfaces/IRestrictionsFacet.sol\";\n\n/**\n * @title Restrictions facet\n * @dev Responsible for storing and verifying different kinds of restrictions, for example:\n * - Whitelist / Blacklist\n * - Daily limits\n * - Trading time restrictions\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract RestrictionsFacet is IRestrictionsFacet, ReentrancyGuard {\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceRestrictionsInitialize();\n }\n\n /**\n * @notice Intialize restrictions of Barz. Restrictions facet call restriction contracts for restriction validation\n * before each call\n * @param _restrictions The initial array of restrictions.\n * @return initSuccess Int value showing if the initialization of restriction is successful\n */\n function initializeRestrictions(\n address[] calldata _restrictions\n ) public override returns (uint256 initSuccess) {\n LibDiamond.enforceIsSelf();\n LibAppStorage.enforceRestrictionsInitialize();\n\n if (_restrictions.length == 0) {\n // You can't initialize RestrictionsFacet with an empty list of restrictions\n revert RestrictionsFacet__EmptyRestrictionsList();\n }\n for (uint256 i; i < _restrictions.length; ) {\n if (_restrictions[i] == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictions();\n unchecked {\n ++i;\n }\n }\n\n LibFacetStorage.restrictionsStorage().restrictions = _restrictions;\n _updateRestrictionsMap(_restrictions, true);\n initSuccess = 1;\n }\n\n /**\n * @notice Unitialize restrictions of Barz\n * @return uninitSuccess Int value showing if the initialization of restriction is successful\n */\n function uninitializeRestrictions()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibDiamond.enforceIsSelf();\n LibAppStorage.setRestrictionsUninitialized();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n _updateRestrictionsMap(restrictionsStorage.restrictions, false);\n restrictionsStorage.restrictions = new address[](0);\n uninitSuccess = 1;\n }\n\n /**\n * @notice Returns the list of Restrictions contract address\n * @return restrictions Addresses of IRestriction which are currently active\n */\n function getRestrictions()\n public\n view\n override\n returns (address[] memory restrictions)\n {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n restrictions = restrictionsStorage.restrictions;\n }\n\n /**\n * @notice Adds restrictions to Barz with validation on the restriction contract address.\n * This method is only callable by the owner(self).\n * @param _restriction The address of the restriction to be added.\n */\n function addRestriction(address _restriction) external override {\n LibDiamond.enforceIsSelf();\n if (LibDiamond.restrictionsFacet() == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictionsFacet();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n if (_restriction == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictions();\n if (restrictionsStorage.exists[_restriction])\n revert RestrictionsFacet__RestrictionAlreadyExists();\n\n restrictionsStorage.restrictions.push(_restriction);\n restrictionsStorage.exists[_restriction] = true;\n\n emit RestrictionAdded(_restriction);\n }\n\n /**\n * @notice Remove restrictions from Barz if it existed. This method is only callable by the owner(self).\n * @param _restriction The address of the restriction to be removed.\n */\n function removeRestriction(address _restriction) external override {\n LibDiamond.enforceIsSelf();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n if (!restrictionsStorage.exists[_restriction])\n revert RestrictionsFacet__RestrictionNotFound();\n\n address[] storage restrictions = restrictionsStorage.restrictions;\n\n uint256 indexToDelete = restrictions.length;\n uint256 restrictionsLen = restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n if (restrictions[i] == _restriction) {\n indexToDelete = i;\n break;\n }\n unchecked {\n ++i;\n }\n }\n\n if (indexToDelete == 0 && restrictionsLen == 1) {\n revert RestrictionsFacet__RemainingRestrictionsCantBeEmpty();\n } else if (indexToDelete == restrictionsLen) {\n revert RestrictionsFacet__RestrictionNotFound();\n } else {\n restrictions[indexToDelete] = restrictions[restrictionsLen - 1];\n restrictions.pop();\n }\n\n restrictionsStorage.exists[_restriction] = false;\n emit RestrictionRemoved(_restriction);\n }\n\n /**\n * @notice Sets the restrictions address value mapping to true or false when adding/removing restriction contracts\n * @param _restrictions List of restriction contracts address\n * @param _newValue Bool value to flag to the list of restrictions contracts\n */\n function _updateRestrictionsMap(\n address[] memory _restrictions,\n bool _newValue\n ) internal {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n uint restrictionsLen = _restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n restrictionsStorage.exists[_restrictions[i]] = _newValue;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @dev Iterates over all restrictions and verifies each of them with the transaction parameters.\n * @param _from The address of the sender, that will be signing the transaction.\n * @param _to The receiving address.\n * @param _value Amount of ETH to transfer from sender to recipient.\n * @param _calldata Optional field to include arbitrary data.\n * @return 0 if all the checks passed, 1 otherwise.\n */\n function verifyRestrictions(\n address _from,\n address _to,\n uint256 _value,\n bytes calldata _calldata\n ) external nonReentrant returns (uint256) {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n uint restrictionsLen = restrictionsStorage.restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n IRestriction restriction = IRestriction(\n restrictionsStorage.restrictions[i]\n );\n bool checkPassed = restriction.check(_from, _to, _value, _calldata);\n if (!checkPassed) {\n return 1;\n }\n unchecked {\n ++i;\n }\n }\n\n return 0;\n }\n}\n" + }, + "contracts/facets/SignatureMigrationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, SignatureMigrationStorage, SignatureMigrationConfig, SignatureMigrationApprovalConfig, ApprovalConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IDiamondCut} from \"./base/interfaces/IDiamondCut.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {ISignatureMigrationFacet} from \"./interfaces/ISignatureMigrationFacet.sol\";\n\n/**\n * @title Signature Migration Facet\n * @dev Responsible for migrating user signature scheme to a new scheme user sets\n * Which could include\n * - ECDSA on Secp256K1 Curve\n * - ECDSA on Secp256R1 Curve\n * - BLS, Schnorr, etc\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract SignatureMigrationFacet is ISignatureMigrationFacet, Modifiers {\n bytes constant UNINIT_CALL =\n abi.encodeWithSignature(\"uninitializeSigner()\");\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This modifier verifies if the public key format matches with the new verification facet\n * @param _publicKey Bytes of public key to be validated for the new verification facet\n * @param _newVerificationFacet Address of new verification facet\n */\n modifier validateKeyType(\n bytes memory _publicKey,\n address _newVerificationFacet\n ) {\n if (\n !IVerificationFacet(_newVerificationFacet).isValidKeyType(\n _publicKey\n )\n ) revert SignatureMigrationFacet__InvalidKeyType();\n _;\n }\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n // IMPORTANT NOTE: In the client side when they call this function, the func selectors should be sorted in ascending order\n // to prevent different hash with same items in the array\n /**\n * @notice Moves the state of migration to a pending state. When pending state is over after pending period time,\n * Migration can be finalized. This function can only be called by self and when the account is unlocked.\n * @dev This method checks if the caller is self and if guardians exists. It migrates signature request to a pending state\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function migrateSignatureScheme(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n public\n override\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n // Only self contract can call this function\n LibDiamond.enforceIsSelf();\n // Should revert if guardian exist\n if (0 != LibGuardian.guardianCount())\n revert SignatureMigrationFacet__InvalidRouteWithGuardian();\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n // NOTE: Migration requires a pending period & confirmation from owner to prevent a\n // single call changing the ownership of the wallet\n /**\n * @notice Migrate signature scheme when guardians exists. Verifies the signature of guardians and moves migration to pending state.\n * Which can then be finalized when pending period is over. Owner's approval is mandatory for migration to happen\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _approvers List of approvers. This could include owner\n */\n function migrateSignatureSchemeWithGuardian(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n )\n public\n override\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n // Should revert if does not guardian exist\n if (0 == LibGuardian.guardianCount())\n revert SignatureMigrationFacet__InvalidRouteWithGuardian();\n if (_approvers.length != _signatures.length)\n revert SignatureMigrationFacet__InvalidArrayLength();\n\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(migrationPublicKeyHash, _approvers);\n\n bool onChainOwnerApproval = getMigrationOwnerApprovalWithTimeValidity(\n migrationPublicKeyHash\n );\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n\n if (\n _approvers.length +\n getMigrationApprovalCountWithTimeValidity(\n migrationPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert SignatureMigrationFacet__InsufficientApprovers();\n {\n // To prevent Stack too deep\n bool ownerApproved;\n for (uint256 i; i < _approvers.length; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n address(this) != _approvers[i]\n ) revert SignatureMigrationFacet__InvalidGuardian();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert SignatureMigrationFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n migrationPublicKeyHash,\n _signatures[i]\n )\n ) revert SignatureMigrationFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n\n if (!ownerApproved && !onChainOwnerApproval)\n revert SignatureMigrationFacet__LackOfOwnerApproval();\n }\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Internal function that moves signature mgiration to a pending state.\n * @dev This method increments migration nonce and sets the migration in the migration config. Emits events for migration execution\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _migrateSignatureScheme(\n address _newVerificationFacet,\n bytes memory _newPublicKey,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal {\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n unchecked {\n ++ms.nonce;\n }\n uint64 migrateAfter = uint64(block.timestamp + getMigrationPeriod());\n\n ms.migrationConfigs[INNER_STRUCT] = SignatureMigrationConfig(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n migrateAfter\n );\n\n emit SignatureMigrationExecuted(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors,\n migrateAfter\n );\n }\n\n /**\n * @notice Approves signature scheme migration on-chain. This can be called by owner or guardian only when the account is unlocked.\n * When the threshold of the migration approval passed and owner approval is granted, it automatically moves migration to a pending state\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function approveSignatureSchemeMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n public\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit SignatureMigrationApproved(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n msg.sender,\n approvalValidUntil\n );\n if (\n getMigrationApprovalCountWithTimeValidity(migrationPublicKeyHash) >=\n LibGuardian.majorityOfGuardians() &&\n getMigrationOwnerApprovalWithTimeValidity(migrationPublicKeyHash)\n )\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Revokes the approval of signature migration done on-chain. Emits revoke event when revoked.\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function revokeSignatureMigrationApproval(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n external\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n if (!isMigrationApproved(migrationPublicKeyHash, msg.sender))\n revert SignatureMigrationFacet__CannotRevokeUnapproved();\n\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(false, 0);\n emit SignatureMigrationApprovalRevoked(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n msg.sender\n );\n }\n\n /**\n * @notice Finalizes the pending signature scheme migration. This function can only be called by owner.\n * It removes the facets of the previous verification facet and adds the new verification facet.\n * After finalizing migration, it emits migration event which shows the change of the verification facet\n */\n function finalizeSignatureMigration() external override {\n // NOTE: Only owner can call this function\n LibDiamond.enforceIsSelf();\n\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n\n if (!isMigrationPending())\n revert SignatureMigrationFacet__NonexistentMigration();\n\n if (\n uint64(block.timestamp) <=\n ms.migrationConfigs[INNER_STRUCT].migrateAfter\n ) revert SignatureMigrationFacet__MigrationPeriodNotOver();\n address newVerificationFacet = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationVerificationFacet;\n bytes4[] memory newVerificationFuncSelectors = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationSelectors;\n bytes memory newPublicKey = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationPublicKey;\n\n address prevVerificationFacet = LibLoupe.facetAddress(\n s.validateOwnerSignatureSelector\n );\n if (prevVerificationFacet == address(0))\n revert SignatureMigrationFacet__NonExistentVerificationFacet();\n\n IDiamondCut.FacetCut[] memory UninitCut;\n IDiamondCut.FacetCut[] memory InitCut;\n {\n bytes4[] memory prevVerificationFuncSelectors = LibLoupe\n .facetFunctionSelectors(prevVerificationFacet);\n\n UninitCut = new IDiamondCut.FacetCut[](1);\n InitCut = new IDiamondCut.FacetCut[](1);\n UninitCut[0] = IDiamondCut.FacetCut({\n facetAddress: address(0),\n action: IDiamondCut.FacetCutAction.Remove,\n functionSelectors: prevVerificationFuncSelectors\n });\n InitCut[0] = IDiamondCut.FacetCut({\n facetAddress: newVerificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: newVerificationFuncSelectors\n });\n {\n IDiamondCut.FacetCut[]\n memory facetCuts = new IDiamondCut.FacetCut[](2);\n facetCuts[0] = UninitCut[0];\n facetCuts[1] = InitCut[0];\n _checkFacetCutValidity(facetCuts);\n }\n LibAppStorage.initiateSignerMigration();\n address verificationFacet = address(\n bytes20(\n LibDiamond.diamondStorage().facets[\n s.validateOwnerSignatureSelector\n ]\n )\n );\n\n (bool uninitSuccess, bytes memory uninitResult) = verificationFacet\n .delegatecall(UNINIT_CALL);\n if (!uninitSuccess || uint256(bytes32(uninitResult)) != 1)\n revert SignatureMigrationFacet__SignerUninitializationFailure();\n LibAppStorage.finalizeSignerMigration();\n\n LibDiamond.diamondCut(UninitCut, address(0), \"\");\n }\n {\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n newPublicKey\n );\n\n // Every Verification Facet should comply with initializeSigner(bytes)\n // to be compatible with the Barz contract(for initialization)\n LibDiamond.diamondCut(InitCut, address(0), \"\");\n (bool initSuccess, bytes memory initResult) = newVerificationFacet\n .delegatecall(initCall);\n if (!initSuccess || uint256(bytes32(initResult)) != 1)\n revert SignatureMigrationFacet__SignerInitializationFailure();\n\n emit SignatureSchemeMigration(\n prevVerificationFacet,\n newVerificationFacet,\n newPublicKey,\n newVerificationFuncSelectors\n );\n }\n }\n\n /**\n * @notice Approve cancellation of signature migration. If cancellation approval passes guardian threshold with owner approval\n * it automatically cancels the migration.\n * @dev This method checks if the caller is one of guardian or owner and sets true for the cancellation hash in the approval config.\n * It internally calls _cancelSignatureMigration for canceling the migration\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function approveCancelSignatureMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n external\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"CancelSignatureMigration\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit SignatureMigrationCancellationApproved(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n if (\n getMigrationApprovalCountWithTimeValidity(migrationPublicKeyHash) >=\n LibGuardian.majorityOfGuardians() &&\n getMigrationOwnerApprovalWithTimeValidity(migrationPublicKeyHash)\n )\n _cancelSignatureMigration(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Verifies the signature of guardians/owner and cancels the signature migration.\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _approvers List of approvers. This could include owner\n */\n function cancelSignatureMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n )\n external\n override\n validateKeyType(_newPublicKey, _newVerificationFacet)\n onlyWhenUnlocked\n {\n if (_approvers.length != _signatures.length)\n revert SignatureMigrationFacet__InvalidArrayLength();\n\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"CancelSignatureMigration\"\n );\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(migrationPublicKeyHash, _approvers);\n\n bool onChainOwnerApproval = getMigrationOwnerApprovalWithTimeValidity(\n migrationPublicKeyHash\n );\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n if (\n _approvers.length +\n getMigrationApprovalCountWithTimeValidity(\n migrationPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert SignatureMigrationFacet__InsufficientApprovers();\n {\n // To prevent stack too deep\n bool ownerApproved;\n for (uint256 i; i < _approvers.length; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n address(this) != _approvers[i]\n ) revert SignatureMigrationFacet__NonExistentApprover();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert SignatureMigrationFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n migrationPublicKeyHash,\n _signatures[i]\n )\n ) revert SignatureMigrationFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n if (!ownerApproved && !onChainOwnerApproval)\n revert SignatureMigrationFacet__LackOfOwnerApproval();\n }\n _cancelSignatureMigration(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Internal function that cancels signature migration.\n * @dev This method increments migration nonce and deletes the migration from the migration config. Emits events for migration cancellation\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _cancelSignatureMigration(\n address _newVerificationFacet,\n bytes memory _newPublicKey,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal {\n if (!isMigrationPending())\n revert SignatureMigrationFacet__NonexistentMigration();\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n unchecked {\n ++ms.nonce;\n }\n delete ms.migrationConfigs[INNER_STRUCT];\n emit SignatureMigrationCanceled(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Checks if the facets to be added from new verification facet is registered to facet registry\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _checkMigrationCutValidity(\n address _newVerificationFacet,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal view {\n IDiamondCut.FacetCut[] memory facetCuts = new IDiamondCut.FacetCut[](1);\n facetCuts[0] = IDiamondCut.FacetCut({\n facetAddress: _newVerificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: _newVerificationFuncSelectors\n });\n _checkFacetCutValidity(facetCuts);\n }\n\n /**\n * @notice Returns if the migration is pending of not\n * @dev This method fetches the migration storage and checks if the migrate after is above 0 value\n * @return isPending Bool value that shows if the migration is pending\n */\n function isMigrationPending()\n public\n view\n override\n returns (bool isPending)\n {\n SignatureMigrationStorage storage rs = LibFacetStorage\n .migrationStorage();\n isPending = rs.migrationConfigs[INNER_STRUCT].migrateAfter > 0;\n }\n\n /**\n * @notice Returns the migration hash. This function ensures that this hash is safe from replay attack by including\n * public key, verification facet, function selectors, salt, address, chainId, and nonce.\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _saltString Salt value for generating the migration hash\n * @return migrationKeyHash Bytes32 string of the migration key hash\n */\n function getApprovalMigrationKeyHash(\n bytes memory _newPublicKey,\n address _newVerificationFacet,\n bytes4[] memory _newVerificationFuncSelectors,\n string memory _saltString\n ) public view override returns (bytes32 migrationKeyHash) {\n migrationKeyHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n _newPublicKey,\n _newVerificationFacet,\n keccak256(abi.encode(_newVerificationFuncSelectors)),\n _saltString,\n address(this),\n block.chainid,\n LibFacetStorage.migrationStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Checks if the owner approved the hash for migration\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @return isApprovedByOwner Bool value of showing if the owner approved it or not\n */\n function getMigrationOwnerApprovalWithTimeValidity(\n bytes32 _migrationPublicKeyHash\n ) public view override returns (bool isApprovedByOwner) {\n isApprovedByOwner = isMigrationApproved(\n _migrationPublicKeyHash,\n address(this)\n );\n }\n\n /**\n * @notice Checks how many of the guardians approved the migration hash\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @return approvalCount Number of approvals\n */\n function getMigrationApprovalCountWithTimeValidity(\n bytes32 _migrationPublicKeyHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardiansLength = guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n if (isMigrationApproved(_migrationPublicKeyHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n return approvalCount;\n }\n\n /**\n * @notice Checks if the migration is approved by the given approver\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @param _approver Address of approver\n * @return isApproved Bool value if migration hash is approved\n */\n function isMigrationApproved(\n bytes32 _migrationPublicKeyHash,\n address _approver\n ) public view override returns (bool isApproved) {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n isApproved = (ms\n .isMigrationApproved[_migrationPublicKeyHash][_approver].isApproved &&\n block.timestamp <\n ms\n .isMigrationApproved[_migrationPublicKeyHash][_approver]\n .validUntil);\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _migrationPublicKeyHash Hash of migration information\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _migrationPublicKeyHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isMigrationApproved(_migrationPublicKeyHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert SignatureMigrationFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the migration period of this wallet\n * @dev This method fetches the migration period from the security manager\n * @return migrationPeriod Migration period of Barz contract fetched from security manager\n */\n function getMigrationPeriod()\n internal\n view\n returns (uint128 migrationPeriod)\n {\n migrationPeriod = securityManager.migrationPeriodOf(address(this));\n if (migrationPeriod == 0)\n revert SignatureMigrationFacet__InvalidMigrationPeriod();\n }\n\n /**\n * @notice Returns the validation period of this wallet\n * @dev This method fetches the validation period from the security manager\n * @return approvalValidationPeriod Validation period of Barz contract fetched from security manager\n */\n function getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod == 0)\n revert SignatureMigrationFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the migration nonce of this wallet\n * @dev This method fetches the nonce from migration storage\n * @return migrationNonce Nonce of migration to protect from reply attacks\n */\n function getMigrationNonce()\n public\n view\n override\n returns (uint128 migrationNonce)\n {\n migrationNonce = LibFacetStorage.migrationStorage().nonce;\n }\n\n /**\n * @notice Returns the migration configuration of this wallet\n * @dev This method fetches the migration config from the migration storage\n * @return pendingMigrationConfig Migration config currently pending for signature migration\n */\n function getPendingMigration()\n external\n view\n override\n returns (SignatureMigrationConfig memory pendingMigrationConfig)\n {\n pendingMigrationConfig = LibFacetStorage\n .migrationStorage()\n .migrationConfigs[INNER_STRUCT];\n }\n}\n" + }, + "contracts/facets/TokenReceiverFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {IERC1155Receiver} from \"../interfaces/ERC/IERC1155Receiver.sol\";\nimport {IERC677Receiver} from \"../interfaces/ERC/IERC677Receiver.sol\";\n\n/**\n * @title TokenReceiver Facet\n * @dev Contract that enables receiving ERC721/ERC1155/ERC777/ERC677 Tokens with safe transfer\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract TokenReceiverFacet is\n IERC721Receiver,\n IERC1155Receiver,\n IERC777Recipient,\n IERC677Receiver\n{\n /**\n * @notice Handles ERC721 Token callback.\n * return Standardized onERC721Received return value.\n */\n function onERC721Received(\n address,\n address,\n uint256,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC721Receiver.onERC721Received.selector;\n }\n\n /**\n * @notice Handles ERC1155 Token callback.\n * return Standardized onERC1155Received return value.\n */\n function onERC1155Received(\n address,\n address,\n uint256,\n uint256,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC1155Receiver.onERC1155Received.selector;\n }\n\n /**\n * @notice Handles ERC1155 Token batch callback.\n * return Standardized onERC1155BatchReceived return value.\n */\n function onERC1155BatchReceived(\n address,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC1155Receiver.onERC1155BatchReceived.selector;\n }\n\n /**\n * @notice Handles ERC777 Token callback.\n * Does not return value, empty implementation.\n */\n function tokensReceived(\n address,\n address,\n address,\n uint256,\n bytes calldata,\n bytes calldata\n ) external pure override {}\n\n /**\n * @notice Handles ERC677 Token callback.\n * return true.\n */\n function onTokenTransfer(\n address,\n uint256,\n bytes calldata\n ) external pure override returns (bool) {\n return true;\n }\n}\n" + }, + "contracts/facets/verification/MultiSigFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {UserOperation} from \"../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../../libraries/LibLoupe.sol\";\nimport {LibAppStorage} from \"../../libraries/LibAppStorage.sol\";\nimport {LibMultiSigStorage, MultiSigStorage} from \"../../libraries/LibMultiSigStorage.sol\";\nimport {IERC1271} from \"../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../interfaces/IVerificationFacet.sol\";\nimport {IMultiSigFacet} from \"../interfaces/IMultiSigFacet.sol\";\n\n/**\n * @title Multi-sig facet\n * @dev Multi-signature Facet with custom threshold.\n * Wallet that adds this facet becomes a multi-sig wallet.\n * Reference signature_format.md documentation for Multi-sig facet details\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract MultiSigFacet is IMultiSigFacet, IVerificationFacet, IERC1271 {\n using ECDSA for bytes32;\n\n address public immutable self;\n\n address internal constant SENTINEL_OWNERS = address(0x1);\n uint256 internal constant ADDRESS = 20;\n uint256 internal constant SIG_TYPE = 1;\n uint256 internal constant SIG_LEN = 4;\n uint256 internal constant THRESHOLD = 4;\n uint256 internal constant INVALID_SIG = 1;\n uint256 internal constant VALID_SIG = 0;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in Multisig Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the right format and initializes signer storage in k1 storage.\n * @param _owners Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _owners\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n\n if (!isValidKeyType(_owners)) revert MultiSigFacet__InvalidInitData();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n uint256 threshold = uint256(uint32(bytes4(_owners)));\n uint256 ownerCount = (_owners.length - THRESHOLD) / ADDRESS;\n\n if (threshold == 0) revert MultiSigFacet__InvalidThreshold();\n if (ownerCount == 0) revert MultisigFacet__InvalidOwnerCount();\n\n address currentOwner = SENTINEL_OWNERS;\n uint256 ptr = THRESHOLD;\n address owner_;\n for (uint256 i; i < ownerCount; ) {\n owner_ = address(bytes20(_owners[ptr:ptr + ADDRESS]));\n ptr += ADDRESS;\n if (\n owner_ == address(0) ||\n owner_ == SENTINEL_OWNERS ||\n owner_ == address(this) ||\n owner_ == currentOwner\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[owner_] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n\n ms.owners[currentOwner] = owner_;\n currentOwner = owner_;\n\n unchecked {\n ++i;\n }\n }\n ms.owners[currentOwner] = SENTINEL_OWNERS;\n ms.ownerCount = ownerCount;\n ms.threshold = threshold;\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_owners);\n }\n\n /**\n * @notice Uninitialize signer in K1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n ++ms.counter;\n address[] memory ownerlist = getOwners();\n uint256 ownerlistLength = ownerlist.length;\n for (uint256 i; i < ownerlistLength; ) {\n ms.owners[ownerlist[i]] = address(0);\n unchecked {\n ++i;\n }\n }\n ms.owners[SENTINEL_OWNERS] = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls checkSignatures with\n * user operation hash and signature together with the threshold.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n // Data 1 is invalid, Data 0 is valid\n validationData = checkSignatures(\n userOpHash,\n userOp.signature,\n LibMultiSigStorage.multisigStorage().threshold\n );\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n return this.validateOwnerSignature.selector;\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n uint totalLength = ms.ownerCount * ADDRESS;\n bytes memory result = new bytes(totalLength);\n\n // populate return array\n uint256 index;\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n while (currentOwner != SENTINEL_OWNERS) {\n assembly {\n mstore(\n add(result, add(32, mul(index, ADDRESS))),\n shl(96, currentOwner)\n )\n }\n currentOwner = ms.owners[currentOwner];\n index++;\n }\n\n return result;\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key should comply with the format in the signature_format.md doc\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n uint256 publicKeyLength = _publicKey.length;\n if (\n publicKeyLength < ADDRESS + THRESHOLD ||\n (publicKeyLength - THRESHOLD) % ADDRESS != 0\n ) return false;\n\n uint256 threshold = uint256(uint32(bytes4(_publicKey)));\n uint256 ownerCount = (publicKeyLength - THRESHOLD) / ADDRESS;\n\n isValid = !(ownerCount < threshold || threshold == 0);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes calldata _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (checkSignatures(\n _hash,\n _signature,\n LibMultiSigStorage.multisigStorage().threshold\n ) == VALID_SIG)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n\n /**\n * @notice Validates the format of the signature and verifies if the signature is signed by the expected key.\n * Reference signature_format.md doc for details about signature format and signature types\n * @param _dataHash Bytes value of data hash signed by the owners\n * @param _signatures Bytes value of signature which should comply with signature format\n * @param _threshold Uint256 value of current Multi-sig Barz's threshold\n */\n function checkSignatures(\n bytes32 _dataHash,\n bytes calldata _signatures,\n uint256 _threshold\n ) public view returns (uint256) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n address lastOwner = address(0);\n address currentOwner;\n bytes memory signature;\n uint256 signatureType;\n uint256 nextOffset;\n uint256 i;\n for (i; i < _threshold; ) {\n (\n currentOwner,\n signature,\n signatureType,\n nextOffset\n ) = splitSignatures(_signatures, nextOffset);\n if (nextOffset == 0 && i + 1 < _threshold) return INVALID_SIG;\n if (signatureType == 1) {\n // If signatureType is 1 then it is default dataHash signed.\n // This also includes the contract signature\n if (\n !SignatureChecker.isValidSignatureNow(\n currentOwner,\n _dataHash,\n signature\n )\n ) return INVALID_SIG;\n } else if (signatureType == 2) {\n // If signatureType is 2 then it is an approved hash\n if (ms.approvedHashes[ms.counter][currentOwner][_dataHash] == 0)\n return INVALID_SIG;\n } else if (signatureType == 3) {\n // If signatureType is 3 then it is a signed message hash\n // This also includes the contract signature\n bytes32 msgHash = _dataHash.toEthSignedMessageHash();\n if (\n !SignatureChecker.isValidSignatureNow(\n currentOwner,\n msgHash,\n signature\n )\n ) return INVALID_SIG;\n } else revert MultiSigFacet__InvalidRoute();\n if (\n currentOwner <= lastOwner ||\n ms.owners[currentOwner] == address(0) ||\n currentOwner == SENTINEL_OWNERS\n ) return INVALID_SIG;\n lastOwner = currentOwner;\n\n unchecked {\n ++i;\n }\n }\n return VALID_SIG;\n }\n\n /**\n * @notice Split signatures into each individual signatures. Should comply with signature format to be split\n * @param _signatures Bytes value of signature\n * @param _nextOffset Uint256 value of next offset to start splitting the signature\n */\n function splitSignatures(\n bytes calldata _signatures,\n uint256 _nextOffset\n )\n public\n pure\n returns (\n address owner_,\n bytes memory signature,\n uint256 signatureType,\n uint256 nextOffset\n )\n {\n uint256 signaturesLength = _signatures.length;\n\n if (signaturesLength <= _nextOffset + ADDRESS + SIG_LEN)\n revert MultiSigFacet__InsufficientSignerLength();\n\n owner_ = address(\n bytes20(_signatures[_nextOffset:_nextOffset + ADDRESS])\n );\n\n signatureType = uint256(\n uint8(\n bytes1(\n _signatures[_nextOffset + ADDRESS:_nextOffset +\n ADDRESS +\n SIG_TYPE]\n )\n )\n );\n\n if (signatureType > 3 || signatureType == 0)\n revert MultiSigFacet__InvalidSignatureType();\n uint256 offSet = _nextOffset + ADDRESS + SIG_TYPE;\n uint256 siglen = uint256(\n uint32(bytes4(_signatures[offSet:offSet + SIG_LEN]))\n );\n if (offSet + siglen > signaturesLength)\n revert MultiSigFacet__InvalidSignatureLength();\n\n offSet += SIG_LEN;\n if (offSet + siglen == signaturesLength) nextOffset = 0;\n else nextOffset = offSet + siglen;\n\n signature = _signatures[offSet:offSet + siglen];\n }\n\n /**\n * @notice Approves the hash of userOperation on-chain. This can only be called by owners.\n * @param _hashToApprove Bytes value of UserOperation hash to approve\n */\n function approveHash(bytes32 _hashToApprove) external {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (ms.owners[msg.sender] == address(0))\n revert MultiSigFacet__OnlyOwner();\n\n ms.approvedHashes[ms.counter][msg.sender][_hashToApprove] = 1;\n emit HashApproved(_hashToApprove, msg.sender);\n }\n\n /**\n * @notice Add owner to Barz. Update thresold if threshold is given different from current threshold\n * @dev This can only be done via a Self call.\n * @param _newOwner Address of new owner to be added\n * @param _threshold Uint256 value of threshold\n */\n function addOwner(address _newOwner, uint256 _threshold) external {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (\n _newOwner == address(0) ||\n _newOwner == SENTINEL_OWNERS ||\n _newOwner == address(this)\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_newOwner] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n\n ms.owners[_newOwner] = ms.owners[SENTINEL_OWNERS];\n ms.owners[SENTINEL_OWNERS] = _newOwner;\n ++ms.ownerCount;\n emit OwnerAdded(_newOwner);\n\n if (ms.threshold != _threshold) changeThreshold(_threshold);\n }\n\n /**\n * @notice Remove owner from Barz. Update thresold if threshold is given different from current threshold\n * @dev This can only be done via a Self call.\n * @param _prevOwner Address of owner located right behind the removed owner address in the linked list\n * @param _removedOwner Address of owner to be removed\n * @param _threshold Uint256 value of threshold\n */\n function removeOwner(\n address _prevOwner,\n address _removedOwner,\n uint256 _threshold\n ) external {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (ms.ownerCount - 1 < _threshold)\n revert MultiSigFacet__InvalidThreshold();\n if (_removedOwner == address(0) || _removedOwner == SENTINEL_OWNERS)\n revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_prevOwner] != _removedOwner)\n revert MultiSigFacet__InvalidOwnerPair();\n\n ms.owners[_prevOwner] = ms.owners[_removedOwner];\n ms.owners[_removedOwner] = address(0);\n --ms.ownerCount;\n emit OwnerRemoved(_removedOwner);\n\n if (ms.threshold != _threshold) changeThreshold(_threshold);\n }\n\n /**\n * @notice Swap owner in Barz.\n * @dev This can only be done via a Self call.\n * @param _prevOwner Address of owner located right behind the removed owner address in the linked list\n * @param _oldOwner Address of owner to be removed\n * @param _newOwner Address of owner to be added\n */\n function swapOwner(\n address _prevOwner,\n address _oldOwner,\n address _newOwner\n ) public {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (\n _newOwner == address(0) ||\n _newOwner == SENTINEL_OWNERS ||\n _newOwner == address(this)\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_newOwner] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n if (_oldOwner == address(0) || _oldOwner == SENTINEL_OWNERS)\n revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_prevOwner] != _oldOwner)\n revert MultiSigFacet__InvalidOwnerPair();\n\n ms.owners[_newOwner] = ms.owners[_oldOwner];\n ms.owners[_prevOwner] = _newOwner;\n ms.owners[_oldOwner] = address(0);\n emit OwnerRemoved(_oldOwner);\n emit OwnerAdded(_newOwner);\n }\n\n /**\n * @notice Changes the threshold of the Barz to `_threshold`.\n * @dev This can only be done via a Self call.\n * @param _threshold New threshold\n */\n function changeThreshold(uint256 _threshold) public {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (_threshold > ms.ownerCount || _threshold == 0)\n revert MultiSigFacet__InvalidThreshold();\n\n ms.threshold = _threshold;\n emit ThresholdChanged(_threshold);\n }\n\n /**\n * @notice Checks if the given address is owner\n * @param _owner Address to be checked if it's owner\n * @return isOwner_ Bool value showing if it's owner address\n */\n function isOwner(address _owner) public view returns (bool isOwner_) {\n isOwner_ = (_owner != SENTINEL_OWNERS &&\n LibMultiSigStorage.multisigStorage().owners[_owner] != address(0));\n }\n\n /**\n * @notice Returns the threshold of Barz\n * @return threshold Threshold of the Barz account\n */\n function getThreshold() public view returns (uint256 threshold) {\n threshold = LibMultiSigStorage.multisigStorage().threshold;\n }\n\n /**\n * @notice Returns the list of owner addresses\n * @return owners List of owners\n */\n function getOwners() public view returns (address[] memory owners) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n owners = new address[](ms.ownerCount);\n\n uint256 index;\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n while (currentOwner != SENTINEL_OWNERS) {\n owners[index] = currentOwner;\n currentOwner = ms.owners[currentOwner];\n index++;\n }\n }\n\n /**\n * @notice Returns the previous owner in the linked list\n * @param _owner Address of owner\n * @return prevOwner Address of previous owner\n */\n function getPrevOwner(\n address _owner\n ) public view returns (address prevOwner) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n if (currentOwner == _owner) return SENTINEL_OWNERS;\n while (currentOwner != SENTINEL_OWNERS) {\n if (ms.owners[currentOwner] == _owner) return currentOwner;\n\n currentOwner = ms.owners[currentOwner];\n }\n return address(0);\n }\n\n /**\n * @notice Returns of the owner is approved by given owner address\n * @param _owner Address of owner\n * @param _hash Hash of UserOperation\n * @return isApproved Bool value showing if the hash is approved by owner\n */\n function isApprovedHash(\n address _owner,\n bytes32 _hash\n ) public view returns (bool isApproved) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n isApproved = (ms.approvedHashes[ms.counter][_owner][_hash] == 1);\n }\n}\n" + }, + "contracts/facets/verification/secp256k1/Secp256k1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {UserOperation} from \"../../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibAppStorage} from \"../../../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, Secp256k1VerificationStorage} from \"../../../libraries/LibFacetStorage.sol\";\nimport {LibLoupe} from \"../../../libraries/LibLoupe.sol\";\nimport {IERC1271} from \"../../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../../interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Secp256k1 verification facet\n * @dev Default Ethereum's elliptic curve\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract Secp256k1VerificationFacet is IVerificationFacet, IERC1271 {\n using ECDSA for bytes32;\n error Secp256k1VerificationFacet__InvalidSignerLength();\n address public immutable self;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in K1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\n * @param _publicKey Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _publicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n if (!isValidKeyType(_publicKey))\n revert Secp256k1VerificationFacet__InvalidSignerLength();\n\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(uint160(uint256(keccak256(_publicKey[1:]))));\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_publicKey);\n }\n\n /**\n * @notice Uninitialize signer in K1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\n * signer public key.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n validationData = validateSignature(\n userOp,\n userOpHash,\n k1Storage.signer\n );\n }\n\n /**\n * @notice Validates if the signature of UserOperation is signed by the given signer\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @param signer Address of signer who signed the contract, to be validated\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n address signer\n ) public pure returns (uint256 isValid) {\n bytes32 hash = userOpHash.toEthSignedMessageHash();\n isValid = (signer != hash.recover(userOp.signature)) ? 1 : 0;\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n ownerSignatureValidatorSelector = this.validateOwnerSignature.selector;\n // NOTE: The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory signer) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n signer = abi.encodePacked(k1Storage.signer);\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key length should be 65 in an uncompressed public key format\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (_hash.recover(_signature) ==\n LibFacetStorage.k1Storage().signer)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/Secp256r1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {UserOperation} from \"../../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibAppStorage} from \"../../../libraries/LibAppStorage.sol\";\nimport {LibLoupe} from \"../../../libraries/LibLoupe.sol\";\nimport {LibFacetStorage, Secp256r1VerificationStorage} from \"../../../libraries/LibFacetStorage.sol\";\nimport {Base64} from \"./utils/Base64.sol\";\nimport {LibSecp256r1} from \"./utils/LibSecp256r1.sol\";\nimport {IERC1271} from \"../../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../../interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Secp256r1 verification facet\n * @dev Primarily used to verify user ops signed with passkeys\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract Secp256r1VerificationFacet is IVerificationFacet, IERC1271 {\n error Secp256r1VerificationFacet__InvalidSignerLength();\n address public immutable self;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in R1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\n * @param _publicKey Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _publicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n\n if (!isValidKeyType(_publicKey))\n revert Secp256r1VerificationFacet__InvalidSignerLength();\n\n bytes memory publicKeyCoordinates = _publicKey[1:];\n uint256[2] memory q;\n assembly {\n // Copy the bytes from the input data into the uint256 array\n mstore(q, mload(add(publicKeyCoordinates, 32)))\n mstore(add(q, 32), mload(add(publicKeyCoordinates, 64)))\n }\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n r1Storage.q = q;\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_publicKey);\n }\n\n /**\n * @notice Uninitialize signer in R1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n r1Storage.q = [0, 0];\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\n * signer public key.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n validationData = validateSignature(userOp, userOpHash, r1Storage.q);\n }\n\n /**\n * @notice Validates if the signature of UserOperation is signed by the given signer\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @param q Public Key of signer who signed the contract, to be validated\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256[2] memory q\n ) public view returns (uint256 isValid) {\n isValid = (_validateSignature(q, userOpHash, userOp.signature)) ? 0 : 1;\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n return this.validateOwnerSignature.selector; // validateOwnerSignature(UserOperation calldata userOp,bytes32 userOpHash)\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory signer) {\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n signer = abi.encodePacked(r1Storage.q);\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key should in an uncompressed public key format\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = _validateSignature(\n LibFacetStorage.r1Storage().q,\n _hash,\n _signature\n )\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n\n function _validateSignature(\n uint256[2] memory q,\n bytes32 _hash,\n bytes memory _signature\n ) internal view returns (bool) {\n (\n uint256 rValue,\n uint256 sValue,\n bytes memory authenticatorData,\n string memory clientDataJSONPre,\n string memory clientDataJSONPost\n ) = abi.decode(_signature, (uint256, uint256, bytes, string, string));\n bytes32 clientHash;\n {\n string memory opHashBase64 = Base64.encode(bytes.concat(_hash));\n string memory clientDataJSON = string.concat(\n clientDataJSONPre,\n opHashBase64,\n clientDataJSONPost\n );\n clientHash = sha256(bytes(clientDataJSON));\n }\n bytes32 sigHash = sha256(bytes.concat(authenticatorData, clientHash));\n return LibSecp256r1.Verify(q, rValue, sValue, uint256(sigHash));\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/utils/Base64.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @dev Provides a set of functions to operate with Base64 strings.\n * modified for base64url https://datatracker.ietf.org/doc/html/rfc4648#section-5\n * _Available since v4.5._\n */\nlibrary Base64 {\n /**\n * @dev Base64 Encoding/Decoding Table\n */\n string internal constant _TABLE =\n \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_\";\n\n /**\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\n */\n function encode(bytes memory data) internal pure returns (string memory) {\n /**\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\n */\n if (data.length == 0) return \"\";\n\n // Loads the table into memory\n string memory table = _TABLE;\n\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\n // and split into 4 numbers of 6 bits.\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\n // - `data.length + 2` -> Round up\n // - `/ 3` -> Number of 3-bytes chunks\n // - `4 *` -> 4 characters for each chunk\n uint256 newlength = (data.length * 8) / 6;\n if (data.length % 6 > 0) {\n newlength++;\n }\n string memory result = new string(newlength);\n\n /// @solidity memory-safe-assembly\n assembly {\n // Prepare the lookup table (skip the first \"length\" byte)\n let tablePtr := add(table, 1)\n\n // Prepare result pointer, jump over length\n let resultPtr := add(result, 32)\n\n // Run over the input, 3 bytes at a time\n for {\n let dataPtr := data\n let endPtr := add(data, mload(data))\n } lt(dataPtr, endPtr) {\n\n } {\n // Advance 3 bytes\n dataPtr := add(dataPtr, 3)\n let input := mload(dataPtr)\n\n // To write each character, shift the 3 bytes (18 bits) chunk\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\n // and apply logical AND with 0x3F which is the number of\n // the previous character in the ASCII table prior to the Base64 Table\n // The result is then added to the table to get the character to write,\n // and finally write it in the result pointer but with a left shift\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(18, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(12, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(6, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n }\n }\n\n return result;\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/utils/LibSecp256r1.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n// Heavily inspired from\n// https://github.com/maxrobot/elliptic-solidity/blob/master/contracts/Secp256r1.sol\n// https://github.com/tdrerup/elliptic-curve-solidity/blob/master/contracts/curves/EllipticCurve.sol\n// modified to use precompile 0x05 modexp\n// and modified jacobian double\n// optimisations to avoid to an from from affine and jacobian coordinates\n\n// Additional Elliptic curve Public key / Signature validation added by\n// David Yonjun Kim (@Powerstream3604)\n\nstruct JPoint {\n uint256 x;\n uint256 y;\n uint256 z;\n}\n\nlibrary LibSecp256r1 {\n uint256 constant gx =\n 0x6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296;\n uint256 constant gy =\n 0x4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5;\n uint256 public constant pp =\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF;\n\n uint256 public constant nn =\n 0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551;\n uint256 constant a =\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC;\n uint256 constant b =\n 0x5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B;\n uint256 constant MOST_SIGNIFICANT =\n 0xc000000000000000000000000000000000000000000000000000000000000000;\n\n /*\n * Verify\n * @description - verifies that a public key has signed a given message\n * @param Q - public key coordinates X & Y\n * @param R - signature half R\n * @param S - signature half S\n * @param input - hashed message\n */\n function Verify(\n uint256[2] memory q,\n uint r,\n uint s,\n uint e\n ) internal view returns (bool) {\n if (q[0] > pp - 1 || q[1] > pp - 1) {\n return false;\n }\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\n return false;\n }\n if (\n mulmod(q[1], q[1], pp) !=\n addmod(\n addmod(\n mulmod(q[0], mulmod(q[0], q[0], pp), pp),\n mulmod(a, q[0], pp),\n pp\n ),\n b,\n pp\n )\n ) {\n return false;\n }\n\n JPoint[16] memory points = _preComputeJacobianPoints(q);\n return VerifyWithPrecompute(points, r, s, e);\n }\n\n function VerifyWithPrecompute(\n JPoint[16] memory points,\n uint r,\n uint s,\n uint e\n ) internal view returns (bool) {\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\n return false;\n }\n\n uint w = _primemod(s, nn);\n\n uint u1 = mulmod(e, w, nn);\n uint u2 = mulmod(r, w, nn);\n\n uint x;\n uint y;\n\n (x, y) = ShamirMultJacobian(points, u1, u2);\n return (x == r);\n }\n\n /*\n * Strauss Shamir trick for EC multiplication\n * https://stackoverflow.com/questions/50993471/ec-scalar-multiplication-with-strauss-shamir-method\n * we optimise on this a bit to do with 2 bits at a time rather than a single bit\n * the individual points for a single pass are precomputed\n * overall this reduces the number of additions while keeping the same number of doublings\n */\n function ShamirMultJacobian(\n JPoint[16] memory points,\n uint u1,\n uint u2\n ) internal view returns (uint, uint) {\n uint x = 0;\n uint y = 0;\n uint z = 0;\n uint bits = 128;\n uint index = 0;\n\n while (bits > 0) {\n if (z > 0) {\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\n }\n index =\n ((u1 & MOST_SIGNIFICANT) >> 252) |\n ((u2 & MOST_SIGNIFICANT) >> 254);\n if (index > 0) {\n (x, y, z) = _jAdd(\n x,\n y,\n z,\n points[index].x,\n points[index].y,\n points[index].z\n );\n }\n u1 <<= 2;\n u2 <<= 2;\n bits--;\n }\n (x, y) = _affineFromJacobian(x, y, z);\n return (x, y);\n }\n\n function _preComputeJacobianPoints(\n uint256[2] memory q\n ) internal pure returns (JPoint[16] memory points) {\n points[0] = JPoint(0, 0, 0);\n points[1] = JPoint(q[0], q[1], 1); // u2\n points[2] = _jPointDouble(points[1]);\n points[3] = _jPointAdd(points[1], points[2]);\n\n points[4] = JPoint(gx, gy, 1); // u1Points[1]\n points[5] = _jPointAdd(points[4], points[1]);\n points[6] = _jPointAdd(points[4], points[2]);\n points[7] = _jPointAdd(points[4], points[3]);\n\n points[8] = _jPointDouble(points[4]); // u1Points[2]\n points[9] = _jPointAdd(points[8], points[1]);\n points[10] = _jPointAdd(points[8], points[2]);\n points[11] = _jPointAdd(points[8], points[3]);\n\n points[12] = _jPointAdd(points[4], points[8]); // u1Points[3]\n points[13] = _jPointAdd(points[12], points[1]);\n points[14] = _jPointAdd(points[12], points[2]);\n points[15] = _jPointAdd(points[12], points[3]);\n }\n\n function _jPointAdd(\n JPoint memory p1,\n JPoint memory p2\n ) internal pure returns (JPoint memory) {\n uint x;\n uint y;\n uint z;\n (x, y, z) = _jAdd(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z);\n return JPoint(x, y, z);\n }\n\n function _jPointDouble(\n JPoint memory p\n ) internal pure returns (JPoint memory) {\n uint x;\n uint y;\n uint z;\n (x, y, z) = _modifiedJacobianDouble(p.x, p.y, p.z);\n return JPoint(x, y, z);\n }\n\n /* _affineFromJacobian\n * @desription returns affine coordinates from a jacobian input follows\n * golang elliptic/crypto library\n */\n function _affineFromJacobian(\n uint x,\n uint y,\n uint z\n ) internal view returns (uint ax, uint ay) {\n if (z == 0) {\n return (0, 0);\n }\n\n uint zinv = _primemod(z, pp);\n uint zinvsq = mulmod(zinv, zinv, pp);\n\n ax = mulmod(x, zinvsq, pp);\n ay = mulmod(y, mulmod(zinvsq, zinv, pp), pp);\n }\n\n /*\n * _jAdd\n * @description performs Jacobian addition as defined below:\n * http://www.hyperelliptic.org/EFD/g1p/data/shortw/jacobian/addition/add-2007-bl\n */\n function _jAdd(\n uint p1,\n uint p2,\n uint p3,\n uint q1,\n uint q2,\n uint q3\n ) internal pure returns (uint r1, uint r2, uint r3) {\n if (p3 == 0) {\n r1 = q1;\n r2 = q2;\n r3 = q3;\n\n return (r1, r2, r3);\n } else if (q3 == 0) {\n r1 = p1;\n r2 = p2;\n r3 = p3;\n\n return (r1, r2, r3);\n }\n\n assembly {\n let\n pd\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\n let z1z1 := mulmod(p3, p3, pd) // Z1Z1 = Z1^2\n let z2z2 := mulmod(q3, q3, pd) // Z2Z2 = Z2^2\n\n let u1 := mulmod(p1, z2z2, pd) // U1 = X1*Z2Z2\n let u2 := mulmod(q1, z1z1, pd) // U2 = X2*Z1Z1\n\n let s1 := mulmod(p2, mulmod(z2z2, q3, pd), pd) // S1 = Y1*Z2*Z2Z2\n let s2 := mulmod(q2, mulmod(z1z1, p3, pd), pd) // S2 = Y2*Z1*Z1Z1\n\n let p3q3 := addmod(p3, q3, pd)\n\n if lt(u2, u1) {\n u2 := add(pd, u2) // u2 = u2+pd\n }\n let h := sub(u2, u1) // H = U2-U1\n\n let i := mulmod(0x02, h, pd)\n i := mulmod(i, i, pd) // I = (2*H)^2\n\n let j := mulmod(h, i, pd) // J = H*I\n if lt(s2, s1) {\n s2 := add(pd, s2) // u2 = u2+pd\n }\n let rr := mulmod(0x02, sub(s2, s1), pd) // r = 2*(S2-S1)\n r1 := mulmod(rr, rr, pd) // X3 = R^2\n\n let v := mulmod(u1, i, pd) // V = U1*I\n let j2v := addmod(j, mulmod(0x02, v, pd), pd)\n if lt(r1, j2v) {\n r1 := add(pd, r1) // X3 = X3+pd\n }\n r1 := sub(r1, j2v)\n\n // Y3 = r*(V-X3)-2*S1*J\n let s12j := mulmod(mulmod(0x02, s1, pd), j, pd)\n\n if lt(v, r1) {\n v := add(pd, v)\n }\n r2 := mulmod(rr, sub(v, r1), pd)\n\n if lt(r2, s12j) {\n r2 := add(pd, r2)\n }\n r2 := sub(r2, s12j)\n\n // Z3 = ((Z1+Z2)^2-Z1Z1-Z2Z2)*H\n z1z1 := addmod(z1z1, z2z2, pd)\n j2v := mulmod(p3q3, p3q3, pd)\n if lt(j2v, z1z1) {\n j2v := add(pd, j2v)\n }\n r3 := mulmod(sub(j2v, z1z1), h, pd)\n }\n return (r1, r2, r3);\n }\n\n // Point doubling on the modified jacobian coordinates\n // http://point-at-infinity.org/ecc/Prime_Curve_Modified_Jacobian_Coordinates.html\n function _modifiedJacobianDouble(\n uint x,\n uint y,\n uint z\n ) internal pure returns (uint x3, uint y3, uint z3) {\n if (y == 0) return (0, 0, 0);\n assembly {\n let\n pd\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\n let z2 := mulmod(z, z, pd)\n let az4 := mulmod(\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC,\n mulmod(z2, z2, pd),\n pd\n )\n let y2 := mulmod(y, y, pd)\n let s := mulmod(0x04, mulmod(x, y2, pd), pd)\n let u := mulmod(0x08, mulmod(y2, y2, pd), pd)\n let m := addmod(mulmod(0x03, mulmod(x, x, pd), pd), az4, pd)\n let twos := mulmod(0x02, s, pd)\n let m2 := mulmod(m, m, pd)\n if lt(m2, twos) {\n m2 := add(pd, m2)\n }\n x3 := sub(m2, twos)\n if lt(s, x3) {\n s := add(pd, s)\n }\n y3 := mulmod(m, sub(s, x3), pd)\n if lt(y3, u) {\n y3 := add(pd, y3)\n }\n y3 := sub(y3, u)\n z3 := mulmod(0x02, mulmod(y, z, pd), pd)\n }\n }\n\n // Fermats little theorem https://en.wikipedia.org/wiki/Fermat%27s_little_theorem\n // a^(p-1) = 1 mod p\n // a^(-1) ≅ a^(p-2) (mod p)\n // we then use the precompile bigModExp to compute a^(-1)\n function _primemod(uint value, uint p) internal view returns (uint ret) {\n ret = modexp(value, p - 2, p);\n return ret;\n }\n\n // Wrapper for built-in BigNumber_modexp (contract 0x5) as described here. https://github.com/ethereum/EIPs/pull/198\n function modexp(\n uint _base,\n uint _exp,\n uint _mod\n ) internal view returns (uint ret) {\n // bigModExp(_base, _exp, _mod);\n assembly {\n if gt(_base, _mod) {\n _base := mod(_base, _mod)\n }\n // Free memory pointer is always stored at 0x40\n let freemem := mload(0x40)\n\n mstore(freemem, 0x20)\n mstore(add(freemem, 0x20), 0x20)\n mstore(add(freemem, 0x40), 0x20)\n\n mstore(add(freemem, 0x60), _base)\n mstore(add(freemem, 0x80), _exp)\n mstore(add(freemem, 0xa0), _mod)\n\n let success := staticcall(14000, 0x5, freemem, 0xc0, freemem, 0x20)\n switch success\n case 0 {\n revert(0x0, 0x0)\n }\n default {\n ret := mload(freemem)\n }\n }\n }\n}\n" + }, + "contracts/infrastructure/DefaultFallbackHandler.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC1155Receiver} from \"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\";\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {BaseAccount} from \"../aa-4337/core/BaseAccount.sol\";\nimport {DefaultLibDiamond} from \"../libraries/DefaultLibDiamond.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IAccountFacet} from \"../facets/interfaces/IAccountFacet.sol\";\nimport {IStorageLoupe} from \"../facets/base/interfaces/IStorageLoupe.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IERC677Receiver} from \"../interfaces/ERC/IERC677Receiver.sol\";\nimport {IERC165} from \"../interfaces/ERC/IERC165.sol\";\n\n/**\n * @title DefaultFallbackHandler\n * @dev A default fallback handler for Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DefaultFallbackHandler is IDiamondLoupe {\n /**\n * @notice Sets the middleware diamond for Barz wallet as a fallback handler\n * @dev This contract is also a diamond that holds the default facets to reduce gas cost for wallet activation.\n * Within the constructor this conducts diamond cut to initially setup the diamond. This is a non-upgradeable contract\n * @param _diamondCutFacet Address if diamond cut facet\n * @param _accountFacet Address account facet\n * @param _tokenReceiverFacet Address of token receiver facet\n * @param _diamondLoupeFacet Address of diamond loupe facet\n */\n constructor(\n address _diamondCutFacet,\n address _accountFacet,\n address _tokenReceiverFacet,\n address _diamondLoupeFacet\n ) payable {\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](4);\n bytes4[] memory functionSelectors = new bytes4[](1);\n functionSelectors[0] = IDiamondCut.diamondCut.selector;\n\n bytes4[] memory accountFunctionSelectors = new bytes4[](5);\n accountFunctionSelectors[0] = IAccountFacet.execute.selector;\n accountFunctionSelectors[1] = IAccountFacet.executeBatch.selector;\n accountFunctionSelectors[2] = BaseAccount.validateUserOp.selector;\n accountFunctionSelectors[3] = BaseAccount.getNonce.selector;\n accountFunctionSelectors[4] = BaseAccount.entryPoint.selector;\n\n bytes4[] memory receiverFacetSelectors = new bytes4[](5);\n receiverFacetSelectors[0] = IERC721Receiver.onERC721Received.selector;\n receiverFacetSelectors[1] = IERC1155Receiver.onERC1155Received.selector;\n receiverFacetSelectors[2] = IERC1155Receiver\n .onERC1155BatchReceived\n .selector;\n receiverFacetSelectors[3] = IERC777Recipient.tokensReceived.selector;\n receiverFacetSelectors[4] = IERC677Receiver.onTokenTransfer.selector;\n\n bytes4[] memory loupeFacetSelectors = new bytes4[](9);\n loupeFacetSelectors[0] = IDiamondLoupe.facets.selector;\n loupeFacetSelectors[1] = IDiamondLoupe.facetFunctionSelectors.selector;\n loupeFacetSelectors[2] = IDiamondLoupe.facetAddresses.selector;\n loupeFacetSelectors[3] = IDiamondLoupe.facetAddress.selector;\n loupeFacetSelectors[4] = IERC165.supportsInterface.selector;\n loupeFacetSelectors[5] = IStorageLoupe.facetsFromStorage.selector;\n loupeFacetSelectors[6] = IStorageLoupe\n .facetFunctionSelectorsFromStorage\n .selector;\n loupeFacetSelectors[7] = IStorageLoupe\n .facetAddressesFromStorage\n .selector;\n loupeFacetSelectors[8] = IStorageLoupe.facetAddressFromStorage.selector;\n\n {\n cut[0] = IDiamondCut.FacetCut({\n facetAddress: _diamondCutFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: functionSelectors\n });\n cut[1] = IDiamondCut.FacetCut({\n facetAddress: _accountFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: accountFunctionSelectors\n });\n cut[2] = IDiamondCut.FacetCut({\n facetAddress: _tokenReceiverFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: receiverFacetSelectors\n });\n cut[3] = IDiamondCut.FacetCut({\n facetAddress: _diamondLoupeFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: loupeFacetSelectors\n });\n\n DefaultLibDiamond.diamondCut(cut, address(0), \"\");\n }\n }\n\n /**\n * @notice Returns the facet information of call facets registered to this diamond.\n * @return facets_ The facet struct array including all facet information\n */\n function facets() external view override returns (Facet[] memory facets_) {\n DefaultLibDiamond.DiamondStorage storage ds = DefaultLibDiamond\n .diamondStorage();\n uint256 numFacets = ds.facetAddresses.length;\n facets_ = new Facet[](numFacets);\n for (uint256 i; i < numFacets; ) {\n address facetAddress_ = ds.facetAddresses[i];\n facets_[i].facetAddress = facetAddress_;\n facets_[i].functionSelectors = ds\n .facetFunctionSelectors[facetAddress_]\n .functionSelectors;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Gets all the function selectors provided by a facet.\n * @param _facet The facet address.\n * @return facetFunctionSelectors_\n */\n function facetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n facetFunctionSelectors_ = DefaultLibDiamond\n .diamondStorage()\n .facetFunctionSelectors[_facet]\n .functionSelectors;\n }\n\n /**\n * @notice Get all the facet addresses used by a diamond.\n * @return facetAddresses_\n */\n function facetAddresses()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n facetAddresses_ = DefaultLibDiamond.diamondStorage().facetAddresses;\n }\n\n /** @notice Gets the facet that supports the given selector.\n * @dev If facet is not found return address(0).\n * @param _functionSelector The function selector.\n * @return facetAddress_ The facet address.\n */\n function facetAddress(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n facetAddress_ = DefaultLibDiamond\n .diamondStorage()\n .selectorToFacetAndPosition[_functionSelector]\n .facetAddress;\n }\n}\n" + }, + "contracts/infrastructure/FacetRegistry.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport {IFacetRegistry} from \"./interfaces/IFacetRegistry.sol\";\n\n/**\n * @title Facet Registry\n * @dev Contract to keep track of facets & function selectors addable to user wallets\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract FacetRegistry is IFacetRegistry, Ownable2Step {\n mapping(address => FacetRegistryConfig) private facets;\n\n /**\n * @notice Transfers the ownership of the contract to the given owner\n * @param _owner Address of owner who has access to initialize the default security variables for security manager\n */\n constructor(address _owner) {\n transferOwnership(_owner);\n _transferOwnership(_owner);\n }\n\n /**\n * @dev Registers a facet and it's function selectors to registry\n * @param _facet address of facet\n * @param _facetSelectors list of function selectors of the facet\n */\n function registerFacetFunctionSelectors(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external override onlyOwner {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n for (uint256 i; i < _facetSelectors.length; ) {\n if (facetConfig.info[_facetSelectors[i]].exists)\n revert FacetRegistry__FacetSelectorAlreadyRegistered();\n\n facetConfig.info[_facetSelectors[i]].exists = true;\n facetConfig.info[_facetSelectors[i]].index = uint128(\n facetConfig.selectors.length\n );\n facetConfig.selectors.push(_facetSelectors[i]);\n unchecked {\n ++i;\n }\n }\n emit FacetFunctionSelectorsRegistered(_facet, _facetSelectors);\n }\n\n /**\n * @dev Removes a registered facet and it's corresponding selectors from registry\n * @param _facet address of facet\n * @param _facetSelectors list of function selectors of the facet\n */\n function removeFacetFunctionSelectors(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external override onlyOwner {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n for (uint256 i; i < _facetSelectors.length; ) {\n if (!facetConfig.info[_facetSelectors[i]].exists)\n revert FacetRegistry__UnregisteredFacetSelector();\n\n bytes4 lastSelector = facetConfig.selectors[\n facetConfig.selectors.length - 1\n ];\n if (_facetSelectors[i] != lastSelector) {\n uint128 targetIndex = facetConfig\n .info[_facetSelectors[i]]\n .index;\n facetConfig.selectors[targetIndex] = lastSelector;\n facetConfig.info[lastSelector].index = targetIndex;\n }\n facetConfig.selectors.pop();\n delete facetConfig.info[_facetSelectors[i]];\n\n unchecked {\n ++i;\n }\n }\n emit FacetFunctionSelectorsRemoved(_facet, _facetSelectors);\n }\n\n /**\n * @dev Checks if a facet and it's selectors given is registered to facet registry\n * @param _facet Address of facet\n * @param _facetSelectors List of function selectors of the facet\n */\n function areFacetFunctionSelectorsRegistered(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external view override returns (bool) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n if (_facetSelectors.length == 0) return false;\n for (uint256 i; i < _facetSelectors.length; ) {\n if (!facetConfig.info[_facetSelectors[i]].exists) return false;\n unchecked {\n ++i;\n }\n }\n return true;\n }\n\n /**\n * @dev Checks if a facet and it's selector given is registered to facet registry\n * @param _facet Address of facet\n * @param _facetSelector List of function selectors of the facet\n * @return isRegistered Bool value showing if the selector is registered\n */\n function isFacetFunctionSelectorRegistered(\n address _facet,\n bytes4 _facetSelector\n ) external view override returns (bool isRegistered) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n isRegistered = facetConfig.info[_facetSelector].exists;\n }\n\n /**\n * @dev Get the registered selectors of facet from registry\n * @param _facet Address of facet\n * @return selectors Selectors registered to facet\n */\n function getFacetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory selectors) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n selectors = facetConfig.selectors;\n }\n}\n" + }, + "contracts/infrastructure/interfaces/IFacetRegistry.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Registry Interface\n * @dev Interface for Facet Registry contract to keep track of facets & function selectors addable to user wallets\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IFacetRegistry {\n struct FacetRegistryConfig {\n bytes4[] selectors;\n mapping(bytes4 => FacetInfo) info;\n }\n struct FacetInfo {\n bool exists;\n uint128 index;\n }\n\n event FacetFunctionSelectorsRegistered(\n address facet,\n bytes4[] facetSelectors\n );\n event FacetFunctionSelectorsRemoved(address facet, bytes4[] facetSelectors);\n\n error FacetRegistry__FacetSelectorAlreadyRegistered();\n error FacetRegistry__UnregisteredFacetSelector();\n\n function registerFacetFunctionSelectors(\n address facet,\n bytes4[] calldata facetSelectors\n ) external;\n\n function removeFacetFunctionSelectors(\n address facet,\n bytes4[] calldata facetSelectors\n ) external;\n\n function areFacetFunctionSelectorsRegistered(\n address facet,\n bytes4[] calldata facetSelectors\n ) external view returns (bool);\n\n function isFacetFunctionSelectorRegistered(\n address facet,\n bytes4 facetSelector\n ) external view returns (bool);\n\n function getFacetFunctionSelectors(\n address facet\n ) external view returns (bytes4[] memory);\n}\n" + }, + "contracts/infrastructure/interfaces/ISecurityManager.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Registry Interface\n * @dev Infrastructure contract to manage security parameters of users\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface ISecurityManager {\n error SecurityManager__OutOfBoundary();\n error SecurityManager__CallerNotWallet();\n error SecurityManager__AlreadyIntialized();\n\n function initializeAdditionSecurityPeriod(\n uint128 defaultAdditionSecurityPeriod,\n uint128 minAdditionSecurityPeriod,\n uint128 maxAdditionSecurityPeriod\n ) external;\n\n function initializeRemovalSecurityPeriod(\n uint128 defaultRemovalSecurityPeriod,\n uint128 minRemovalSecurityPeriod,\n uint128 maxRemovalSecurityPeriod\n ) external;\n\n function initializeApprovalValidationPeriod(\n uint128 defaultApprovalValidationPeriod,\n uint128 minApprovalValidationPeriod,\n uint128 maxApprovalValidationPeriod\n ) external;\n\n function initializeMigrationPeriod(\n uint128 defaultMigrationPeriod,\n uint128 minMigrationPeriod,\n uint128 maxMigrationPeriod\n ) external;\n\n function initializeLockPeriod(\n uint128 defaultLockPeriod,\n uint128 minLockPeriod,\n uint128 maxLockPeriod\n ) external;\n\n function initializeRecoveryPeriod(\n uint128 defaultRecoveryPeriod,\n uint128 minRecoveryPeriod,\n uint128 maxRecoveryPeriod\n ) external;\n\n function initializeSecurityWindow(\n uint128 defaultSecurityWindow,\n uint128 minSecurityWindow,\n uint128 maxSecurityWindow\n ) external;\n\n function setAdditionSecurityPeriod(\n address wallet,\n uint128 additionSecurityPeriod\n ) external;\n\n function setRemovalSecurityPeriod(\n address wallet,\n uint128 removalSecurityPeriod\n ) external;\n\n function setSecurityWindow(address wallet, uint128 securityWindow) external;\n\n function setRecoveryPeriod(address wallet, uint128 recoveryPeriod) external;\n\n function setLockPeriod(address wallet, uint128 lockPeriod) external;\n\n function setApprovalValidationPeriod(\n address wallet,\n uint128 approvalValidationPeriod\n ) external;\n\n function setMigrationPeriod(\n address wallet,\n uint128 migrationPeriod\n ) external;\n\n function additionSecurityPeriodOf(\n address wallet\n ) external view returns (uint128);\n\n function removalSecurityPeriodOf(\n address wallet\n ) external view returns (uint128);\n\n function securityWindowOf(address wallet) external view returns (uint128);\n\n function recoveryPeriodOf(address wallet) external view returns (uint128);\n\n function lockPeriodOf(address wallet) external view returns (uint128);\n\n function migrationPeriodOf(address wallet) external view returns (uint128);\n\n function approvalValidationPeriodOf(\n address wallet\n ) external view returns (uint128);\n}\n" + }, + "contracts/infrastructure/RemoteStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IGuardianFacet} from \"../facets/interfaces/IGuardianFacet.sol\";\n\n/**\n * @title Remote Storage\n * @dev Remote storage allows you to associate addresses with an array of addresses on a standalone smart contract.\n * This could be useful when you don't want to use the local diamond storage for some purpose.\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\nabstract contract RemoteStorage {\n struct StorageConfig {\n address[] addresses;\n mapping(address => Info) info;\n }\n\n struct Info {\n bool exists;\n uint128 index;\n }\n\n mapping(address => StorageConfig) internal configs;\n\n event Added(address _address);\n event Removed(address _address);\n\n error RemoteStorage__CallerNotOwner();\n error RemoteStorage__CallerNotGuardianOrOwner();\n error RemoteStorage__AlreadyExists();\n error RemoteStorage__NotFound();\n error RemoteStorage__CallerNotGuardian();\n\n bytes4 constant IS_GUARDIAN_SELECTOR =\n bytes4(keccak256(\"isGuardian(address)\"));\n bytes4 constant GUARDIAN_COUNT = bytes4(keccak256(\"guardianCount()\"));\n\n /**\n * @notice Modifier to only allow the self to call. Reverts otherwise\n */\n modifier onlyWallet(address _wallet) {\n if (msg.sender != _wallet) revert RemoteStorage__CallerNotOwner();\n _;\n }\n\n /**\n * @notice Enfore the callet to be wallet of guardian of the wallet\n * @param _wallet Address of wallet\n */\n function enforceGuardianOrWallet(address _wallet) internal view {\n if (msg.sender == _wallet) return;\n address facetAddress = IDiamondLoupe(_wallet).facetAddress(\n IS_GUARDIAN_SELECTOR\n );\n if (facetAddress != address(0))\n if (IGuardianFacet(_wallet).isGuardian(msg.sender)) return;\n revert RemoteStorage__CallerNotGuardianOrOwner();\n }\n\n /**\n * @notice Enforce the caller to be wallet IF guardians doesn't exists and only guardian when guardians exists\n * @param _wallet Target wallet address to be handled by infrastructure contracts\n */\n function enforceWalletOrGuardianIfExists(address _wallet) internal view {\n address facetAddress;\n if (msg.sender == _wallet) {\n facetAddress = IDiamondLoupe(_wallet).facetAddress(GUARDIAN_COUNT);\n if (facetAddress == address(0)) return;\n uint256 guardianCount = IGuardianFacet(_wallet).guardianCount();\n if (guardianCount != 0) revert RemoteStorage__CallerNotGuardian();\n return;\n }\n facetAddress = IDiamondLoupe(_wallet).facetAddress(\n IS_GUARDIAN_SELECTOR\n );\n if (facetAddress != address(0))\n if (IGuardianFacet(_wallet).isGuardian(msg.sender)) return;\n\n revert RemoteStorage__CallerNotGuardianOrOwner();\n }\n\n /**\n * @notice Add address to storage and reverts if the address already exists.\n * This is an internal function callable from contracts that inherit this abstract contract\n * @param _wallet Address of wallet to add the address\n * @param _address Address to be added to wallet\n */\n function addAddress(address _wallet, address _address) internal {\n StorageConfig storage config = configs[_wallet];\n if (config.info[_address].exists) revert RemoteStorage__AlreadyExists();\n\n config.info[_address].exists = true;\n config.info[_address].index = uint128(config.addresses.length);\n config.addresses.push(_address);\n\n emit Added(_address);\n }\n\n /**\n * @notice Remove address from storage and reverts if the address already exists.\n * This is an internal function callable from contracts that inherit this abstract contract\n * @param _wallet Address of wallet to remove the address\n * @param _address Address to be removed from wallet\n */\n function removeAddress(address _wallet, address _address) internal {\n StorageConfig storage config = configs[_wallet];\n if (!config.info[_address].exists) revert RemoteStorage__NotFound();\n\n address lastAddress = config.addresses[config.addresses.length - 1];\n if (_address != lastAddress) {\n uint128 targetIndex = config.info[_address].index;\n config.addresses[targetIndex] = lastAddress;\n config.info[lastAddress].index = targetIndex;\n }\n config.addresses.pop();\n delete config.info[_address];\n\n emit Removed(_address);\n }\n\n /**\n * @notice Returns the address added to the given wallet\n * @param _wallet Address of wallet to fetch the addresses added to it\n * @return addresses List of addresses added to the wallet\n */\n function getAddresses(\n address _wallet\n ) internal view returns (address[] memory addresses) {\n StorageConfig storage config = configs[_wallet];\n addresses = new address[](config.addresses.length);\n uint addressesLen = config.addresses.length;\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns bool value checking if the address exists in the given wallet address\n * @param _wallet Wallet address to check\n * @param _address Address to fetch if the address if added to given wallet\n * @return exists_ Bool value showing if the address exists in wallet\n */\n function exists(\n address _wallet,\n address _address\n ) internal view returns (bool exists_) {\n exists_ = configs[_wallet].info[_address].exists;\n }\n\n /**\n * @notice Returns the number of addresses added to the wallet\n * @param _wallet Address of wallet to check\n * @return count_ Number of addresses added to wallet\n */\n function count(address _wallet) internal view returns (uint256 count_) {\n count_ = configs[_wallet].addresses.length;\n }\n}\n" + }, + "contracts/infrastructure/SecurityManager.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport {ISecurityManager} from \"./interfaces/ISecurityManager.sol\";\n\n/**\n * @title Security Manager\n * @dev Infrastructure contract to manage security parameters of users\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract SecurityManager is ISecurityManager, Ownable2Step {\n uint128 public minAdditionSecurityPeriod;\n uint128 public maxAdditionSecurityPeriod;\n uint128 private defaultAdditionSecurityPeriod;\n\n uint128 public minRemovalSecurityPeriod;\n uint128 public maxRemovalSecurityPeriod;\n uint128 private defaultRemovalSecurityPeriod;\n\n uint128 public minSecurityWindow;\n uint128 public maxSecurityWindow;\n uint128 private defaultSecurityWindow;\n\n uint128 public minRecoveryPeriod;\n uint128 public maxRecoveryPeriod;\n uint128 private defaultRecoveryPeriod;\n\n uint128 public minLockPeriod;\n uint128 public maxLockPeriod;\n uint128 private defaultLockPeriod;\n\n uint128 public minApprovalValidationPeriod;\n uint128 public maxApprovalValidationPeriod;\n uint128 private defaultApprovalValidationPeriod;\n\n uint128 public minMigrationPeriod;\n uint128 public maxMigrationPeriod;\n uint128 private defaultMigrationPeriod;\n\n bool public _isAdditionSecurityPeriodInitialized;\n bool public _isRemovalSecurityPeriodInitialized;\n bool public _isSecurityWindowInitialized;\n bool public _isRecoveryPeriodInitialized;\n bool public _isLockPeriodInitialized;\n bool public _isApprovalValidationPeriodInitialized;\n bool public _isMigrationPeriodInitialized;\n\n mapping(address => CustomSecurityConfig) securityConfigs;\n\n struct CustomSecurityConfig {\n uint128 additionSecurityPeriod;\n uint128 removalSecurityPeriod;\n uint128 securityWindow;\n uint128 recoveryPeriod;\n uint128 lockPeriod;\n uint128 approvalValidationPeriod;\n uint128 migrationPeriod;\n }\n\n /**\n * @notice Modifier to only allow wallet itself to make a call to wallet\n */\n modifier onlyWallet(address _wallet) {\n if (msg.sender != _wallet) revert SecurityManager__CallerNotWallet();\n _;\n }\n\n /**\n * @notice Modifier to revert if the variable is already initialized\n */\n modifier initializer(bool _isInitialized) {\n if (_isInitialized) revert SecurityManager__AlreadyIntialized();\n _;\n }\n\n /**\n * @notice Transfers the ownership of the contract to the given owner\n * @param _owner Address of owner who has access to initialize the default security variables for security manager\n */\n constructor(address _owner) {\n transferOwnership(_owner);\n _transferOwnership(_owner);\n }\n\n /**\n * @notice Sets the initial default/min/max addition security period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultAdditionSecurityPeriod Default Addition Security Period for all Barz contracts\n * @param _minAdditionSecurityPeriod Minimum Addition Security Period for all Barz contracts\n * @param _maxAdditionSecurityPeriod Maximum Addition Security Period for all Barz contracts\n */\n function initializeAdditionSecurityPeriod(\n uint128 _defaultAdditionSecurityPeriod,\n uint128 _minAdditionSecurityPeriod,\n uint128 _maxAdditionSecurityPeriod\n )\n external\n override\n onlyOwner\n initializer(_isAdditionSecurityPeriodInitialized)\n {\n _isAdditionSecurityPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultAdditionSecurityPeriod,\n _minAdditionSecurityPeriod,\n _maxAdditionSecurityPeriod\n );\n defaultAdditionSecurityPeriod = _defaultAdditionSecurityPeriod;\n minAdditionSecurityPeriod = _minAdditionSecurityPeriod;\n maxAdditionSecurityPeriod = _maxAdditionSecurityPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max removal security period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultRemovalSecurityPeriod Default Removal Security Period for all Barz contracts\n * @param _minRemovalSecurityPeriod Minimum Removal Security Period for all Barz contracts\n * @param _maxRemovalSecurityPeriod Maximum Removal Security Period for all Barz contracts\n */\n function initializeRemovalSecurityPeriod(\n uint128 _defaultRemovalSecurityPeriod,\n uint128 _minRemovalSecurityPeriod,\n uint128 _maxRemovalSecurityPeriod\n )\n external\n override\n onlyOwner\n initializer(_isRemovalSecurityPeriodInitialized)\n {\n _isRemovalSecurityPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultRemovalSecurityPeriod,\n _minRemovalSecurityPeriod,\n _maxRemovalSecurityPeriod\n );\n defaultRemovalSecurityPeriod = _defaultRemovalSecurityPeriod;\n minRemovalSecurityPeriod = _minRemovalSecurityPeriod;\n maxRemovalSecurityPeriod = _maxRemovalSecurityPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/maxd security window for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultSecurityWindow Default Security Window for all Barz contracts\n * @param _minSecurityWindow Minimum Security Window for all Barz contracts\n * @param _maxSecurityWindow Maximum Security Window for all Barz contracts\n */\n function initializeSecurityWindow(\n uint128 _defaultSecurityWindow,\n uint128 _minSecurityWindow,\n uint128 _maxSecurityWindow\n ) external override onlyOwner initializer(_isSecurityWindowInitialized) {\n _isSecurityWindowInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultSecurityWindow,\n _minSecurityWindow,\n _maxSecurityWindow\n );\n defaultSecurityWindow = _defaultSecurityWindow;\n minSecurityWindow = _minSecurityWindow;\n maxSecurityWindow = _maxSecurityWindow;\n }\n\n /**\n * @notice Sets the initial default/min/max recovery period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultRecoveryPeriod Default Recovery Period for all Barz contracts\n * @param _minRecoveryPeriod Minimum Recovery Period for all Barz contracts\n * @param _maxRecoveryPeriod Maximum Recovery Period for all Barz contracts\n */\n function initializeRecoveryPeriod(\n uint128 _defaultRecoveryPeriod,\n uint128 _minRecoveryPeriod,\n uint128 _maxRecoveryPeriod\n ) external override onlyOwner initializer(_isRecoveryPeriodInitialized) {\n _isRecoveryPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultRecoveryPeriod,\n _minRecoveryPeriod,\n _maxRecoveryPeriod\n );\n defaultRecoveryPeriod = _defaultRecoveryPeriod;\n minRecoveryPeriod = _minRecoveryPeriod;\n maxRecoveryPeriod = _maxRecoveryPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max lock period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultLockPeriod Default Lock Period for all Barz contracts\n * @param _minLockPeriod Minimum Lock Period for all Barz contracts\n * @param _maxLockPeriod Maximum Lock Period for all Barz contracts\n */\n function initializeLockPeriod(\n uint128 _defaultLockPeriod,\n uint128 _minLockPeriod,\n uint128 _maxLockPeriod\n ) external override onlyOwner initializer(_isLockPeriodInitialized) {\n _isLockPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultLockPeriod,\n _minLockPeriod,\n _maxLockPeriod\n );\n defaultLockPeriod = _defaultLockPeriod;\n minLockPeriod = _minLockPeriod;\n maxLockPeriod = _maxLockPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max approval validation period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultApprovalValidationPeriod Default Approval Validation Period for all Barz contracts\n * @param _minApprovalValidationPeriod Minimum Approval Validation Period for all Barz contracts\n * @param _maxApprovalValidationPeriod Maximum Approval Validation Period for all Barz contracts\n */\n function initializeApprovalValidationPeriod(\n uint128 _defaultApprovalValidationPeriod,\n uint128 _minApprovalValidationPeriod,\n uint128 _maxApprovalValidationPeriod\n )\n external\n override\n onlyOwner\n initializer(_isApprovalValidationPeriodInitialized)\n {\n _isApprovalValidationPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultApprovalValidationPeriod,\n _minApprovalValidationPeriod,\n _maxApprovalValidationPeriod\n );\n defaultApprovalValidationPeriod = _defaultApprovalValidationPeriod;\n minApprovalValidationPeriod = _minApprovalValidationPeriod;\n maxApprovalValidationPeriod = _maxApprovalValidationPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max migration period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultMigrationPeriod Default Migration Period for all Barz contracts\n * @param _minMigrationPeriod Minimum Migration Period for all Barz contracts\n * @param _maxMigrationPeriod Maximum Migration Period for all Barz contracts\n */\n function initializeMigrationPeriod(\n uint128 _defaultMigrationPeriod,\n uint128 _minMigrationPeriod,\n uint128 _maxMigrationPeriod\n ) external override onlyOwner initializer(_isMigrationPeriodInitialized) {\n _isMigrationPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultMigrationPeriod,\n _minMigrationPeriod,\n _maxMigrationPeriod\n );\n defaultMigrationPeriod = _defaultMigrationPeriod;\n minMigrationPeriod = _minMigrationPeriod;\n maxMigrationPeriod = _maxMigrationPeriod;\n }\n\n /**\n * @notice Wallet owner sets the addition security period for the wallet. Only the owner of wallet can call this function.\n * The addition security period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _additionSecurityPeriod Custom Addition Security Period for the wallet\n */\n function setAdditionSecurityPeriod(\n address _wallet,\n uint128 _additionSecurityPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _additionSecurityPeriod,\n minAdditionSecurityPeriod,\n maxAdditionSecurityPeriod\n );\n securityConfigs[_wallet]\n .additionSecurityPeriod = _additionSecurityPeriod;\n }\n\n /**\n * @notice Wallet owner sets the removal security period for the wallet. Only the owner of wallet can call this function.\n * The removal security period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _removalSecurityPeriod Custom Removal Security Period for the wallet\n */\n function setRemovalSecurityPeriod(\n address _wallet,\n uint128 _removalSecurityPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _removalSecurityPeriod,\n minRemovalSecurityPeriod,\n maxRemovalSecurityPeriod\n );\n securityConfigs[_wallet].removalSecurityPeriod = _removalSecurityPeriod;\n }\n\n /**\n * @notice Wallet owner sets the security window for the wallet. Only the owner of wallet can call this function.\n * The security window should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _securityWindow Custom Security Window for the wallet\n */\n function setSecurityWindow(\n address _wallet,\n uint128 _securityWindow\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _securityWindow,\n minSecurityWindow,\n maxSecurityWindow\n );\n securityConfigs[_wallet].securityWindow = _securityWindow;\n }\n\n /**\n * @notice Wallet owner sets the recovery period for the wallet. Only the owner of wallet can call this function.\n * The recovery period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _recoveryPeriod Custom recovery period for the wallet\n */\n function setRecoveryPeriod(\n address _wallet,\n uint128 _recoveryPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _recoveryPeriod,\n minRecoveryPeriod,\n maxRecoveryPeriod\n );\n securityConfigs[_wallet].recoveryPeriod = _recoveryPeriod;\n }\n\n /**\n * @notice Wallet owner sets the lock period for the wallet. Only the owner of wallet can call this function.\n * The lock period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _lockPeriod Custom Lock period for the wallet\n */\n function setLockPeriod(\n address _wallet,\n uint128 _lockPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(_lockPeriod, minLockPeriod, maxLockPeriod);\n securityConfigs[_wallet].lockPeriod = _lockPeriod;\n }\n\n /**\n * @notice Wallet owner sets the approval validation period for the wallet. Only the owner of wallet can call this function.\n * The approval validation period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _approvalValidationPeriod Custom approval validation period for the wallet\n */\n function setApprovalValidationPeriod(\n address _wallet,\n uint128 _approvalValidationPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _approvalValidationPeriod,\n minApprovalValidationPeriod,\n maxApprovalValidationPeriod\n );\n securityConfigs[_wallet]\n .approvalValidationPeriod = _approvalValidationPeriod;\n }\n\n /**\n * @notice Wallet owner sets the migration period for the wallet. Only the owner of wallet can call this function.\n * The migration period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _migrationPeriod Custom migration period for the wallet\n */\n\n function setMigrationPeriod(\n address _wallet,\n uint128 _migrationPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _migrationPeriod,\n minMigrationPeriod,\n maxMigrationPeriod\n );\n securityConfigs[_wallet].migrationPeriod = _migrationPeriod;\n }\n\n /**\n * @notice Returns the addition security period. Returns default value when custom addition security period is not set\n * @param _wallet Address of wallet\n * @return additionSecurityPeriod Addition Security Period of the given Barz account or wallet\n */\n function additionSecurityPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 additionSecurityPeriod)\n {\n additionSecurityPeriod = securityConfigs[_wallet]\n .additionSecurityPeriod;\n additionSecurityPeriod = (additionSecurityPeriod == 0)\n ? defaultAdditionSecurityPeriod\n : additionSecurityPeriod;\n }\n\n /**\n * @notice Returns the removal security period. Returns default value when custom removal security period is not set\n * @param _wallet Address of wallet\n * @return removalSecurityPeriod Removal Security Period of the given Barz account or wallet\n */\n function removalSecurityPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 removalSecurityPeriod)\n {\n removalSecurityPeriod = securityConfigs[_wallet].removalSecurityPeriod;\n removalSecurityPeriod = (removalSecurityPeriod == 0)\n ? defaultRemovalSecurityPeriod\n : removalSecurityPeriod;\n }\n\n /**\n * @notice Returns the security window. Returns default value when custom security window is not set\n * @param _wallet Address of wallet\n * @return securityWindow Security window of the given Barz account or wallet\n */\n function securityWindowOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 securityWindow)\n {\n securityWindow = securityConfigs[_wallet].securityWindow;\n securityWindow = (securityWindow == 0)\n ? defaultSecurityWindow\n : securityWindow;\n }\n\n /**\n * @notice Returns the recovery period. Returns default value when custom recovery period is not set\n * @param _wallet Address of wallet\n * @return recoveryPeriod Recovery Period of the given Barz account or wallet\n */\n function recoveryPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 recoveryPeriod)\n {\n recoveryPeriod = securityConfigs[_wallet].recoveryPeriod;\n recoveryPeriod = (recoveryPeriod == 0)\n ? defaultRecoveryPeriod\n : recoveryPeriod;\n }\n\n /**\n * @notice Returns the lock period. Returns default value when custom lock period is not set\n * @param _wallet Address of wallet\n * @return lockPeriod Lock Period of the given Barz account or wallet\n */\n function lockPeriodOf(\n address _wallet\n ) public view override onlyWallet(_wallet) returns (uint128 lockPeriod) {\n lockPeriod = securityConfigs[_wallet].lockPeriod;\n lockPeriod = (lockPeriod == 0) ? defaultLockPeriod : lockPeriod;\n }\n\n /**\n * @notice Returns the approval validation period. Returns default value when custom approval validation period is not set\n * @param _wallet Address of wallet\n * @return approvalValidationPeriod Approval Validation Period of the given Barz account or wallet\n */\n function approvalValidationPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityConfigs[_wallet]\n .approvalValidationPeriod;\n approvalValidationPeriod = (approvalValidationPeriod == 0)\n ? defaultApprovalValidationPeriod\n : approvalValidationPeriod;\n }\n\n /**\n * @notice Returns the migration period. Returns default value when custom migration period is not set\n * @param _wallet Address of wallet\n * @return migrationPeriod Migration Period of the given Barz account or wallet\n */\n function migrationPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 migrationPeriod)\n {\n migrationPeriod = securityConfigs[_wallet].migrationPeriod;\n migrationPeriod = (migrationPeriod == 0)\n ? defaultMigrationPeriod\n : migrationPeriod;\n }\n\n /**\n * @notice Validates if the period is smaller than the max period or bigger than the min period\n * @param _period Period to be checked\n * @param _minPeriod Minimum period\n * @param _maxPeriod Maximum period\n */\n function _validatePeriodBoundaries(\n uint128 _period,\n uint128 _minPeriod,\n uint128 _maxPeriod\n ) internal pure {\n if (_period >= _maxPeriod || _period <= _minPeriod)\n revert SecurityManager__OutOfBoundary();\n }\n}\n" + }, + "contracts/infrastructure/WhitelistStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {RemoteStorage} from \"./RemoteStorage.sol\";\n\n/**\n * @title Whitelist storage\n * @dev Maps addresses to the corresponsing array of whitelisted addresses for each of them.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract WhitelistStorage is RemoteStorage {\n /**\n * @dev Add the address to the whitelist storage\n * @param _wallet User wallet\n * @param _address Address to be whitelisted\n */\n function whitelistAddress(address _wallet, address _address) external {\n enforceWalletOrGuardianIfExists(_wallet);\n addAddress(_wallet, _address);\n }\n\n /**\n * @dev Removes the address from the whitelist storage\n * @param _wallet User wallet\n * @param _address Address to be removed from the whitelist\n */\n function blacklistAddress(address _wallet, address _address) external {\n enforceGuardianOrWallet(_wallet);\n removeAddress(_wallet, _address);\n }\n\n /**\n * @dev Returns whether the address exists in the whitelist storage, associated with the wallet\n * @param _wallet User wallet\n * @param _address Address to be whitelisted\n */\n function isWhitelisted(\n address _wallet,\n address _address\n ) external view returns (bool) {\n return exists(_wallet, _address);\n }\n\n /**\n * @dev Returns all whitelisted addresses associated with the wallet\n * @param _wallet User wallet\n */\n function getWhitelistedAddresses(\n address _wallet\n ) external view returns (address[] memory) {\n return getAddresses(_wallet);\n }\n}\n" + }, + "contracts/interfaces/ERC/IERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\n\npragma solidity 0.8.21;\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155Receiver {\n /**\n * @dev Handles the receipt of a single ERC1155 token type. This function is\n * called at the end of a `safeTransferFrom` after the balance has been updated.\n *\n * NOTE: To accept the transfer, this must return\n * `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n * (i.e. 0xf23a6e61, or its own function selector).\n *\n * @param operator The address which initiated the transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param id The ID of the token being transferred\n * @param value The amount of tokens being transferred\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n ) external returns (bytes4);\n\n /**\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\n * is called at the end of a `safeBatchTransferFrom` after the balances have\n * been updated.\n *\n * NOTE: To accept the transfer(s), this must return\n * `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n * (i.e. 0xbc197c81, or its own function selector).\n *\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "contracts/interfaces/ERC/IERC1271.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\ninterface IERC1271 {\n function isValidSignature(\n bytes32 hash,\n bytes memory signature\n ) external view returns (bytes4);\n}\n" + }, + "contracts/interfaces/ERC/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\ninterface IERC165 {\n /// @notice Query if a contract implements an interface\n /// @param interfaceId The interface identifier, as specified in ERC-165\n /// @dev Interface identification is specified in ERC-165. This function\n /// uses less than 30,000 gas.\n /// @return `true` if the contract implements `interfaceID` and\n /// `interfaceID` is not 0xffffffff, `false` otherwise\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/IERC173.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\n/// @title ERC-173 Contract Ownership Standard\n/// Note: the ERC-165 identifier for this interface is 0x7f5828d0\n/* is ERC165 */\ninterface IERC173 {\n /// @dev This emits when ownership of a contract changes.\n event OwnershipTransferred(\n address indexed previousOwner,\n address indexed newOwner\n );\n\n /// @notice Get the address of the owner\n /// @return owner_ The address of the owner.\n function owner() external view returns (address owner_);\n\n /// @notice Set the address of the new owner of the contract\n /// @dev Set _newOwner to address(0) to renounce any ownership.\n /// @param _newOwner The address of the new owner of the contract\n function transferOwnership(address _newOwner) external;\n}\n" + }, + "contracts/interfaces/ERC/IERC677Receiver.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\ninterface IERC677Receiver {\n function onTokenTransfer(\n address sender,\n uint value,\n bytes calldata data\n ) external pure returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155 is IERC165 {\n /**\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n */\n event TransferSingle(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256 id,\n uint256 value\n );\n\n /**\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n * transfers.\n */\n event TransferBatch(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\n\n /**\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n * `approved`.\n */\n event ApprovalForAll(\n address indexed account,\n address indexed operator,\n bool approved\n );\n\n /**\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n *\n * If an {URI} event was emitted for `id`, the standard\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n * returned by {IERC1155MetadataURI-uri}.\n */\n event URI(string value, uint256 indexed id);\n\n /**\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(\n address account,\n uint256 id\n ) external view returns (uint256);\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] calldata accounts,\n uint256[] calldata ids\n ) external view returns (uint256[] memory);\n\n /**\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n *\n * Emits an {ApprovalForAll} event.\n *\n * Requirements:\n *\n * - `operator` cannot be the caller.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n *\n * See {setApprovalForAll}.\n */\n function isApprovedForAll(\n address account,\n address operator\n ) external view returns (bool);\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes calldata data\n ) external;\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(\n address indexed owner,\n address indexed spender,\n uint256 value\n );\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` 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 amount) 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(\n address owner,\n address spender\n ) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the 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 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` 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(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(\n address spender,\n uint256 addedValue\n ) external returns (bool);\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(\n address spender,\n uint256 subtractedValue\n ) external returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(\n address indexed from,\n address indexed to,\n uint256 indexed tokenId\n );\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(\n address indexed owner,\n address indexed approved,\n uint256 indexed tokenId\n );\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(\n address indexed owner,\n address indexed operator,\n bool approved\n );\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(\n uint256 tokenId\n ) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(\n address owner,\n address operator\n ) external view returns (bool);\n}\n" + }, + "contracts/interfaces/IBarz.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Barz Interface\n * @dev Interface of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IBarz {\n error Barz__InitializationFailure();\n}\n" + }, + "contracts/interfaces/IBarzFactory.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Barz} from \"../Barz.sol\";\n\n/**\n * @title Barz Factory Interface\n * @dev Interface of contract to easily deploy Barz to a pre-computed address with a single call\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IBarzFactory {\n event BarzDeployed(address);\n\n function createAccount(\n address verificationFacet,\n bytes calldata owner,\n uint256 salt\n ) external returns (Barz);\n\n function getAddress(\n address verificationFacet,\n bytes calldata owner,\n uint256 salt\n ) external view returns (address);\n\n function getBytecode(\n address accountFacet,\n address verificationFacet,\n address entryPoint,\n address facetRegistry,\n address defaultFallback,\n bytes memory ownerPublicKey\n ) external pure returns (bytes memory);\n\n function getCreationCode() external pure returns (bytes memory);\n}\n" + }, + "contracts/libraries/DefaultLibDiamond.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\n\nerror InitializationFunctionReverted(\n address _initializationContractAddress,\n bytes _calldata\n);\n\nlibrary DefaultLibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION =\n keccak256(\"trustwallet.barz.diamond.storage\");\n\n struct FacetAddressAndPosition {\n address facetAddress;\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\n }\n\n struct FacetFunctionSelectors {\n bytes4[] functionSelectors;\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\n }\n\n struct DiamondStorage {\n // maps function selector to the facet address and\n // the position of the selector in the facetFunctionSelectors.selectors array\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\n // maps facet addresses to function selectors\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\n // facet addresses\n address[] facetAddresses;\n // Used to query if a contract implements an interface.\n // Used to implement ERC-165.\n mapping(bytes4 => bool) supportedInterfaces;\n }\n\n function diamondStorage()\n internal\n pure\n returns (DiamondStorage storage ds)\n {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n event DiamondCut(\n IDiamondCut.FacetCut[] _diamondCut,\n address _init,\n bytes _calldata\n );\n\n // Internal function version of diamondCut\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n for (\n uint256 facetIndex;\n facetIndex < _diamondCut.length;\n facetIndex++\n ) {\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\n if (action == IDiamondCut.FacetCutAction.Add) {\n addFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\n replaceFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\n removeFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else {\n revert(\"LibDiamondCut: Incorrect FacetCutAction\");\n }\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Add facet can't be address(0)\"\n );\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n require(\n oldFacetAddress == address(0),\n \"LibDiamondCut: Can't add function that already exists\"\n );\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function replaceFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Replace facet can't be address(0)\"\n );\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n require(\n oldFacetAddress != _facetAddress,\n \"LibDiamondCut: Can't replace function with same facet\"\n );\n removeFunction(ds, oldFacetAddress, selector);\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function removeFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n // if function does not exist then do nothing and return\n require(\n _facetAddress == address(0),\n \"LibDiamondCut: Remove facet address must be address(0)\"\n );\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n removeFunction(ds, oldFacetAddress, selector);\n }\n }\n\n function addFacet(\n DiamondStorage storage ds,\n address _facetAddress\n ) internal {\n enforceHasContractCode(\n _facetAddress,\n \"LibDiamondCut: New facet has no code\"\n );\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds\n .facetAddresses\n .length;\n ds.facetAddresses.push(_facetAddress);\n }\n\n function addFunction(\n DiamondStorage storage ds,\n bytes4 _selector,\n uint96 _selectorPosition,\n address _facetAddress\n ) internal {\n ds\n .selectorToFacetAndPosition[_selector]\n .functionSelectorPosition = _selectorPosition;\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(\n _selector\n );\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\n }\n\n function removeFunction(\n DiamondStorage storage ds,\n address _facetAddress,\n bytes4 _selector\n ) internal {\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Can't remove function that doesn't exist\"\n );\n // an immutable function is a function defined directly in a diamond\n require(\n _facetAddress != address(this),\n \"LibDiamondCut: Can't remove immutable function\"\n );\n // replace selector with last selector, then delete last selector\n uint256 selectorPosition = ds\n .selectorToFacetAndPosition[_selector]\n .functionSelectorPosition;\n uint256 lastSelectorPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors\n .length - 1;\n // if not the same then replace _selector with lastSelector\n if (selectorPosition != lastSelectorPosition) {\n bytes4 lastSelector = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors[lastSelectorPosition];\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[\n selectorPosition\n ] = lastSelector;\n ds\n .selectorToFacetAndPosition[lastSelector]\n .functionSelectorPosition = uint96(selectorPosition);\n }\n // delete the last selector\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\n delete ds.selectorToFacetAndPosition[_selector];\n\n // if no more selectors for facet address then delete the facet address\n if (lastSelectorPosition == 0) {\n // replace facet address with last facet address and delete last facet address\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\n uint256 facetAddressPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .facetAddressPosition;\n if (facetAddressPosition != lastFacetAddressPosition) {\n address lastFacetAddress = ds.facetAddresses[\n lastFacetAddressPosition\n ];\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\n ds\n .facetFunctionSelectors[lastFacetAddress]\n .facetAddressPosition = facetAddressPosition;\n }\n ds.facetAddresses.pop();\n delete ds\n .facetFunctionSelectors[_facetAddress]\n .facetAddressPosition;\n }\n }\n\n function initializeDiamondCut(\n address _init,\n bytes memory _calldata\n ) internal {\n if (_init == address(0)) {\n return;\n }\n enforceHasContractCode(\n _init,\n \"LibDiamondCut: _init address has no code\"\n );\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length > 0) {\n // bubble up error\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(error)\n revert(add(32, error), returndata_size)\n }\n } else {\n revert InitializationFunctionReverted(_init, _calldata);\n }\n }\n }\n\n function enforceHasContractCode(\n address _contract,\n string memory _errorMessage\n ) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize > 0, _errorMessage);\n }\n}\n" + }, + "contracts/libraries/LibAppStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SafeCast} from \"@openzeppelin/contracts/utils/math/SafeCast.sol\";\nimport {IEntryPoint} from \"../aa-4337/interfaces/IEntryPoint.sol\";\nimport {IFacetRegistry} from \"../infrastructure/interfaces/IFacetRegistry.sol\";\n\n/*\n * @title App Storage\n * @dev App storage for Barz contract to prevent storage collision\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\n\nstruct Lock {\n uint64 release;\n bytes4 locker;\n}\n\nstruct InitializersStorage {\n // NOTE: initialized is a variable to make sure the initialization is only done once.\n uint8 signerInitialized;\n uint8 accountInitialized;\n uint8 restrictionsInitialized;\n}\n\nstruct AppStorage {\n mapping(uint256 => InitializersStorage) initStorage;\n uint8 signerMigration;\n bytes4 validateOwnerSignatureSelector;\n IEntryPoint entryPoint;\n IFacetRegistry facetRegistry;\n mapping(uint256 => Lock) locks;\n}\n\nlibrary LibAppStorage {\n error LibAppStorage__AccountAlreadyUninitialized();\n error LibAppStorage__AccountMustBeUninitialized();\n error LibAppStorage__SignerAlreadyUninitialized();\n error LibAppStorage__SignerMustBeUninitialized();\n\n function appStorage() internal pure returns (AppStorage storage ds) {\n assembly {\n ds.slot := 0\n }\n }\n\n function setSignerUninitialized() internal {\n AppStorage storage s = appStorage();\n if (1 != s.initStorage[0].signerInitialized) {\n revert LibAppStorage__SignerAlreadyUninitialized();\n }\n s.initStorage[0].signerInitialized = 0;\n }\n\n function getValidateOwnerSignatureSelector()\n internal\n view\n returns (bytes4 selector)\n {\n selector = appStorage().validateOwnerSignatureSelector;\n }\n\n function setValidateOwnerSignatureSelector(\n bytes4 _validateOwnerSignatureSelector\n ) internal {\n appStorage()\n .validateOwnerSignatureSelector = _validateOwnerSignatureSelector;\n }\n\n function enforceSignerInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].signerInitialized) {\n revert LibAppStorage__SignerMustBeUninitialized();\n }\n s.initStorage[0].signerInitialized = 1;\n }\n\n function enforceAccountInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].accountInitialized) {\n revert LibAppStorage__AccountMustBeUninitialized();\n }\n s.initStorage[0].accountInitialized = 1;\n }\n\n function initiateSignerMigration() internal {\n appStorage().signerMigration = 1;\n }\n\n function enforceSignerMigration() internal view {\n if (1 != appStorage().signerMigration) {\n revert LibAppStorage__AccountMustBeUninitialized();\n }\n }\n\n function finalizeSignerMigration() internal {\n appStorage().signerMigration = 0;\n }\n\n function setLock(uint256 _releaseAfter, bytes4 _locker) internal {\n appStorage().locks[0] = Lock(SafeCast.toUint64(_releaseAfter), _locker);\n }\n\n function enforceRestrictionsInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].restrictionsInitialized)\n revert LibAppStorage__SignerMustBeUninitialized();\n s.initStorage[0].restrictionsInitialized = 1;\n }\n\n function setRestrictionsUninitialized() internal {\n AppStorage storage s = appStorage();\n if (1 != s.initStorage[0].restrictionsInitialized)\n revert LibAppStorage__AccountAlreadyUninitialized();\n s.initStorage[0].restrictionsInitialized = 0;\n }\n}\n\ncontract BarzStorage {\n AppStorage internal s;\n modifier onlyWhenUnlocked() {\n require(\n uint64(block.timestamp) >= s.locks[0].release,\n \"Account Locked\"\n );\n _;\n }\n modifier onlyWhenLocked() {\n require(\n uint64(block.timestamp) < s.locks[0].release,\n \"Account Unlocked\"\n );\n _;\n }\n}\n" + }, + "contracts/libraries/LibDiamond.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\n\nerror InitializationFunctionReverted(\n address _initializationContractAddress,\n bytes _calldata\n);\n\nlibrary LibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION =\n keccak256(\"trustwallet.barz.diamond.storage\");\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\n bytes4(keccak256(\"verifyRestrictions(address,address,uint256,bytes)\"));\n struct DiamondStorage {\n // maps function selectors to the facets that execute the functions.\n // and maps the selectors to their position in the selectorSlots array.\n // func selector => address facet, selector position\n mapping(bytes4 => bytes32) facets;\n // array of slots of function selectors.\n // each slot holds 8 function selectors.\n mapping(uint256 => bytes32) selectorSlots;\n // The number of function selectors in selectorSlots\n uint16 selectorCount;\n // Used to query if a contract implements an interface.\n // Used to implement ERC-165.\n mapping(bytes4 => bool) supportedInterfaces;\n // Default Fallback Handler of the barz.\n IDiamondLoupe defaultFallbackHandler;\n }\n\n function diamondStorage()\n internal\n pure\n returns (DiamondStorage storage ds)\n {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n function enforceIsSelf() internal view {\n require(msg.sender == address(this), \"LibDiamond: Caller not self\");\n }\n\n event DiamondCut(\n IDiamondCut.FacetCut[] _diamondCut,\n address _init,\n bytes _calldata\n );\n\n bytes32 constant CLEAR_ADDRESS_MASK =\n bytes32(uint256(0xffffffffffffffffffffffff));\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\n\n // Internal function version of diamondCut\n // This code is almost the same as the external diamondCut,\n // except it is using 'Facet[] memory _diamondCut' instead of\n // 'Facet[] calldata _diamondCut'.\n // The code is duplicated to prevent copying calldata to memory which\n // causes an error for a two dimensional array.\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n DiamondStorage storage ds = diamondStorage();\n uint256 originalSelectorCount = ds.selectorCount;\n uint256 selectorCount = originalSelectorCount;\n bytes32 selectorSlot;\n // Check if last selector slot is not full\n // \"selectorCount & 7\" is a gas efficient modulo by eight \"selectorCount % 8\"\n if (selectorCount & 7 > 0) {\n // get last selectorSlot\n // \"selectorSlot >> 3\" is a gas efficient division by 8 \"selectorSlot / 8\"\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\n }\n // loop through diamond cut\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\n selectorCount,\n selectorSlot,\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].action,\n _diamondCut[facetIndex].functionSelectors\n );\n\n unchecked {\n facetIndex++;\n }\n }\n if (selectorCount != originalSelectorCount) {\n ds.selectorCount = uint16(selectorCount);\n }\n // If last selector slot is not full\n // \"selectorCount & 7\" is a gas efficient modulo by eight \"selectorCount % 8\"\n if (selectorCount & 7 > 0) {\n // \"selectorSlot >> 3\" is a gas efficient division by 8 \"selectorSlot / 8\"\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addReplaceRemoveFacetSelectors(\n uint256 _selectorCount,\n bytes32 _selectorSlot,\n address _newFacetAddress,\n IDiamondCut.FacetCutAction _action,\n bytes4[] memory _selectors\n ) internal returns (uint256, bytes32) {\n DiamondStorage storage ds = diamondStorage();\n require(\n _selectors.length > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n if (_action == IDiamondCut.FacetCutAction.Add) {\n enforceHasContractCode(\n _newFacetAddress,\n \"LibDiamondCut: Add facet has no code\"\n );\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n require(\n address(bytes20(oldFacet)) == address(0),\n \"LibDiamondCut: Can't add function that already exists\"\n );\n // add facet for selector\n ds.facets[selector] =\n bytes20(_newFacetAddress) |\n bytes32(_selectorCount);\n // \"_selectorCount & 7\" is a gas efficient modulo by eight \"_selectorCount % 8\"\n // \" << 5 is the same as multiplying by 32 ( * 32)\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\n // clear selector position in slot and add selector\n _selectorSlot =\n (_selectorSlot &\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\n (bytes32(selector) >> selectorInSlotPosition);\n // if slot is full then write it to storage\n if (selectorInSlotPosition == 224) {\n // \"_selectorSlot >> 3\" is a gas efficient division by 8 \"_selectorSlot / 8\"\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\n _selectorSlot = 0;\n }\n _selectorCount++;\n\n unchecked {\n selectorIndex++;\n }\n }\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\n enforceHasContractCode(\n _newFacetAddress,\n \"LibDiamondCut: Replace facet has no code\"\n );\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n address oldFacetAddress = address(bytes20(oldFacet));\n // only useful if immutable functions exist\n require(\n oldFacetAddress != address(this),\n \"LibDiamondCut: Can't replace immutable function\"\n );\n require(\n oldFacetAddress != _newFacetAddress,\n \"LibDiamondCut: Can't replace function with same function\"\n );\n require(\n oldFacetAddress != address(0),\n \"LibDiamondCut: Can't replace function that doesn't exist\"\n );\n // replace old facet address\n ds.facets[selector] =\n (oldFacet & CLEAR_ADDRESS_MASK) |\n bytes20(_newFacetAddress);\n\n unchecked {\n selectorIndex++;\n }\n }\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\n require(\n _newFacetAddress == address(0),\n \"LibDiamondCut: Remove facet address must be address(0)\"\n );\n // \"_selectorCount >> 3\" is a gas efficient division by 8 \"_selectorCount / 8\"\n uint256 selectorSlotCount = _selectorCount >> 3;\n // \"_selectorCount & 7\" is a gas efficient modulo by eight \"_selectorCount % 8\"\n uint256 selectorInSlotIndex = _selectorCount & 7;\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n if (_selectorSlot == 0) {\n // get last selectorSlot\n selectorSlotCount--;\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\n selectorInSlotIndex = 7;\n } else {\n selectorInSlotIndex--;\n }\n bytes4 lastSelector;\n uint256 oldSelectorsSlotCount;\n uint256 oldSelectorInSlotPosition;\n // adding a block here prevents stack too deep error\n {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n require(\n address(bytes20(oldFacet)) != address(0),\n \"LibDiamondCut: Can't remove function that doesn't exist\"\n );\n // only useful if immutable functions exist\n require(\n address(bytes20(oldFacet)) != address(this),\n \"LibDiamondCut: Can't remove immutable function\"\n );\n // replace selector with last selector in ds.facets\n // gets the last selector\n // \" << 5 is the same as multiplying by 32 ( * 32)\n lastSelector = bytes4(\n _selectorSlot << (selectorInSlotIndex << 5)\n );\n if (lastSelector != selector) {\n // update last selector slot position info\n ds.facets[lastSelector] =\n (oldFacet & CLEAR_ADDRESS_MASK) |\n bytes20(ds.facets[lastSelector]);\n }\n delete ds.facets[selector];\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\n // \"oldSelectorCount >> 3\" is a gas efficient division by 8 \"oldSelectorCount / 8\"\n oldSelectorsSlotCount = oldSelectorCount >> 3;\n // \"oldSelectorCount & 7\" is a gas efficient modulo by eight \"oldSelectorCount % 8\"\n // \" << 5 is the same as multiplying by 32 ( * 32)\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\n }\n if (oldSelectorsSlotCount != selectorSlotCount) {\n bytes32 oldSelectorSlot = ds.selectorSlots[\n oldSelectorsSlotCount\n ];\n // clears the selector we are deleting and puts the last selector in its place.\n oldSelectorSlot =\n (oldSelectorSlot &\n ~(CLEAR_SELECTOR_MASK >>\n oldSelectorInSlotPosition)) |\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\n // update storage with the modified slot\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\n } else {\n // clears the selector we are deleting and puts the last selector in its place.\n _selectorSlot =\n (_selectorSlot &\n ~(CLEAR_SELECTOR_MASK >>\n oldSelectorInSlotPosition)) |\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\n }\n if (selectorInSlotIndex == 0) {\n delete ds.selectorSlots[selectorSlotCount];\n _selectorSlot = 0;\n }\n\n unchecked {\n selectorIndex++;\n }\n }\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\n } else {\n revert(\"LibDiamondCut: Incorrect FacetCutAction\");\n }\n return (_selectorCount, _selectorSlot);\n }\n\n function initializeDiamondCut(\n address _init,\n bytes memory _calldata\n ) internal {\n if (_init == address(0)) {\n return;\n }\n enforceHasContractCode(\n _init,\n \"LibDiamondCut: _init address has no code\"\n );\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length > 0) {\n // bubble up error\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(error)\n revert(add(32, error), returndata_size)\n }\n } else {\n revert InitializationFunctionReverted(_init, _calldata);\n }\n }\n }\n\n function enforceHasContractCode(\n address _contract,\n string memory _errorMessage\n ) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize > 0, _errorMessage);\n }\n\n function restrictionsFacet() internal view returns (address facetAddress_) {\n facetAddress_ = address(\n bytes20(\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\n )\n );\n }\n}\n" + }, + "contracts/libraries/LibFacetStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Storage\n * @dev Storage contract to store each facets variables with diamond storage\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\n\nstruct Secp256k1VerificationStorage {\n address signer;\n}\n\nstruct Secp256r1VerificationStorage {\n uint256[2] q;\n}\n\nstruct GuardianStorage {\n mapping(bytes32 => uint256) pending;\n mapping(uint8 => StorageConfig) configs;\n}\n\nstruct Info {\n bool exists;\n uint128 index;\n}\n\nstruct StorageConfig {\n address[] addresses;\n mapping(address => Info) info;\n}\n\nstruct RecoveryConfig {\n bytes recoveryPublicKey;\n uint64 executeAfter;\n}\n\nstruct ApprovalConfig {\n bool isApproved;\n uint64 validUntil;\n}\n\nstruct RecoveryApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isNewOwnerApproved;\n}\n\nstruct RecoveryStorage {\n mapping(uint8 => RecoveryConfig) recoveryConfigs;\n mapping(uint8 => RecoveryApprovalConfig) recoveryApprovalConfigs;\n uint128 nonce;\n}\n\nstruct RestrictionsStorage {\n address[] restrictions;\n mapping(address => bool) exists;\n}\n\nstruct SignatureMigrationConfig {\n bytes migrationPublicKey;\n address migrationVerificationFacet;\n bytes4[] migrationSelectors;\n uint64 migrateAfter;\n}\n\nstruct SignatureMigrationApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isMigrationApproved;\n}\n\nstruct SignatureMigrationStorage {\n mapping(uint8 => SignatureMigrationConfig) migrationConfigs;\n mapping(uint8 => SignatureMigrationApprovalConfig) migrationApprovalConfigs;\n uint128 nonce;\n}\n\nstruct DiamondCutApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isDiamondCutApproved;\n}\n\nstruct DiamondCutStorage {\n mapping(uint8 => DiamondCutApprovalConfig) diamondCutApprovalConfigs;\n uint128 nonce;\n}\n\nstruct LockStorage {\n uint128 nonce;\n}\n\nlibrary LibFacetStorage {\n bytes32 constant K1_STORAGE_POSITION =\n keccak256(\n \"v0.trustwallet.diamond.storage.Secp256k1VerificationStorage\"\n );\n bytes32 constant R1_STORAGE_POSITION =\n keccak256(\n \"v0.trustwallet.diamond.storage.Secp256r1VerificationStorage\"\n );\n bytes32 constant GUARDIAN_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.GuardianStorage\");\n bytes32 constant RECOVERY_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.RecoveryStorage\");\n bytes32 constant RESTRICTION_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.RestrictionsStorage\");\n bytes32 constant MIGRATION_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.SignatureMigrationStorage\");\n bytes32 constant DIAMONDCUT_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.DiamondCutStorage\");\n bytes32 constant LOCK_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.LockStorage\");\n\n function k1Storage()\n internal\n pure\n returns (Secp256k1VerificationStorage storage ds)\n {\n bytes32 storagePosition = K1_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function r1Storage()\n internal\n pure\n returns (Secp256r1VerificationStorage storage ds)\n {\n bytes32 storagePosition = R1_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function guardianStorage()\n internal\n pure\n returns (GuardianStorage storage ds)\n {\n bytes32 storagePosition = GUARDIAN_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function recoveryStorage()\n internal\n pure\n returns (RecoveryStorage storage ds)\n {\n bytes32 storagePosition = RECOVERY_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function restrictionsStorage()\n internal\n pure\n returns (RestrictionsStorage storage ds)\n {\n bytes32 storagePosition = RESTRICTION_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function migrationStorage()\n internal\n pure\n returns (SignatureMigrationStorage storage ds)\n {\n bytes32 storagePosition = MIGRATION_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function diamondCutStorage()\n internal\n pure\n returns (DiamondCutStorage storage ds)\n {\n bytes32 storagePosition = DIAMONDCUT_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function lockStorage() internal pure returns (LockStorage storage ds) {\n bytes32 storagePosition = LOCK_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n}\n" + }, + "contracts/libraries/LibGuardian.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibFacetStorage, StorageConfig} from \"./LibFacetStorage.sol\";\n\n/**\n * @title LibGuardian\n * @dev Internal Library to provide utility feature for Guardians stored in Guardian Facet Storage\n * @author David Yongjun Kim (@Powerstream3604)\n */\nlibrary LibGuardian {\n function majorityOfGuardians()\n internal\n view\n returns (uint256 guardianNumber)\n {\n uint256 guardianLength = guardianCount();\n guardianNumber = (guardianLength == 0) ? 0 : guardianLength / 2 + 1;\n }\n\n function isGuardian(address _guardian) internal view returns (bool) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n return config.info[_guardian].exists;\n }\n\n function guardianCount() internal view returns (uint256) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n return config.addresses.length;\n }\n\n function getGuardians() internal view returns (address[] memory) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n address[] memory addresses = new address[](config.addresses.length);\n uint256 addressesLen = config.addresses.length;\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n return addresses;\n }\n}\n" + }, + "contracts/libraries/LibLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {LibDiamond} from \"./LibDiamond.sol\";\n\n/**\n * @title LibLoupe\n * @dev Internal Library to provide utility feature for reading the state of diamond facets\n * Originally from Diamond's implementation of Mudgen(author of EIP-2535)\n */\nlibrary LibLoupe {\n /// @notice Gets all facets and their selectors.\n /// @return facets_ Facet\n function facets()\n internal\n view\n returns (IDiamondLoupe.Facet[] memory facets_)\n {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facets_ = new IDiamondLoupe.Facet[](ds.selectorCount);\n uint16[] memory numFacetSelectors = new uint16[](ds.selectorCount);\n uint256 numFacets;\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facetAddress_ = address(bytes20(ds.facets[selector]));\n bool continueLoop;\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n if (facets_[facetIndex].facetAddress == facetAddress_) {\n facets_[facetIndex].functionSelectors[\n numFacetSelectors[facetIndex]\n ] = selector;\n // probably will never have more than 256 functions from one facet contract\n require(numFacetSelectors[facetIndex] < 255);\n numFacetSelectors[facetIndex]++;\n continueLoop = true;\n break;\n }\n }\n if (continueLoop) {\n continue;\n }\n facets_[numFacets].facetAddress = facetAddress_;\n facets_[numFacets].functionSelectors = new bytes4[](\n ds.selectorCount\n );\n facets_[numFacets].functionSelectors[0] = selector;\n numFacetSelectors[numFacets] = 1;\n numFacets++;\n }\n }\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n uint256 numSelectors = numFacetSelectors[facetIndex];\n bytes4[] memory selectors = facets_[facetIndex].functionSelectors;\n // setting the number of selectors\n assembly {\n mstore(selectors, numSelectors)\n }\n }\n // setting the number of facets\n assembly {\n mstore(facets_, numFacets)\n }\n }\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n /// @return _facetFunctionSelectors The selectors associated with a facet address.\n function facetFunctionSelectors(\n address _facet\n ) internal view returns (bytes4[] memory _facetFunctionSelectors) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n uint256 numSelectors;\n _facetFunctionSelectors = new bytes4[](ds.selectorCount);\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facet = address(bytes20(ds.facets[selector]));\n if (_facet == facet) {\n _facetFunctionSelectors[numSelectors] = selector;\n numSelectors++;\n }\n }\n }\n // Set the number of selectors in the array\n assembly {\n mstore(_facetFunctionSelectors, numSelectors)\n }\n }\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses()\n internal\n view\n returns (address[] memory facetAddresses_)\n {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facetAddresses_ = new address[](ds.selectorCount);\n uint256 numFacets;\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facetAddress_ = address(bytes20(ds.facets[selector]));\n bool continueLoop;\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n if (facetAddress_ == facetAddresses_[facetIndex]) {\n continueLoop = true;\n break;\n }\n }\n if (continueLoop) {\n continue;\n }\n facetAddresses_[numFacets] = facetAddress_;\n numFacets++;\n }\n }\n // Set the number of facet addresses in the array\n assembly {\n mstore(facetAddresses_, numFacets)\n }\n }\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(\n bytes4 _functionSelector\n ) internal view returns (address facetAddress_) {\n facetAddress_ = address(\n bytes20(LibDiamond.diamondStorage().facets[_functionSelector])\n );\n }\n}\n" + }, + "contracts/libraries/LibMultiSigStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Multi-sig Storage\n * @dev Storage contract for storing Multi-sig Facet variables in diamond storage pattern\n * @author David Yongjun Kim (@Powerstream3604)\n */\n\nstruct MultiSigStorage {\n mapping(address => address) owners;\n mapping(uint256 => mapping(address => mapping(bytes32 => uint256))) approvedHashes;\n uint256 ownerCount;\n uint256 threshold;\n uint256 counter;\n}\n\nlibrary LibMultiSigStorage {\n function multisigStorage()\n internal\n pure\n returns (MultiSigStorage storage ds)\n {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.MultiSigStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n}\n" + }, + "contracts/libraries/LibRecoverSpender.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title RecoverSpender\n * @dev Library to determine the action and spender of calldata\n * @author Ruslan Serebriakov (@rsrbk)\n */\nlibrary LibRecoverSpender {\n // ERC20, ERC721 & ERC1155 transfers & approvals\n bytes4 private constant ERC20_TRANSFER =\n bytes4(keccak256(\"transfer(address,uint256)\"));\n bytes4 private constant ERC20_APPROVE =\n bytes4(keccak256(\"approve(address,uint256)\"));\n bytes4 private constant ERC20_INCREASE_ALLOWANCE =\n bytes4(keccak256(\"increaseAllowance(address,uint256)\"));\n bytes4 private constant ERC20_DECREASE_ALLOWANCE =\n bytes4(keccak256(\"decreaseAllowance(address,uint256)\"));\n bytes4 private constant ERC721_SET_APPROVAL_FOR_ALL =\n bytes4(keccak256(\"setApprovalForAll(address,bool)\"));\n bytes4 private constant ERC721_TRANSFER_FROM =\n bytes4(keccak256(\"transferFrom(address,address,uint256)\"));\n bytes4 private constant ERC721_SAFE_TRANSFER_FROM =\n bytes4(keccak256(\"safeTransferFrom(address,address,uint256)\"));\n bytes4 private constant ERC721_SAFE_TRANSFER_FROM_BYTES =\n bytes4(keccak256(\"safeTransferFrom(address,address,uint256,bytes)\"));\n bytes4 private constant ERC1155_SAFE_TRANSFER_FROM =\n bytes4(\n keccak256(\"safeTransferFrom(address,address,uint256,uint256,bytes)\")\n );\n bytes4 private constant ERC1155_SAFE_BATCH_TRANSFER_FROM =\n bytes4(\n keccak256(\n \"safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)\"\n )\n );\n\n /**\n * @notice Helper method to recover the spender from a contract call.\n * The method returns the contract unless the call is to a standard method of a ERC20/ERC721/ERC1155 token\n * in which case the spender is recovered from the data.\n * @param _to The target contract.\n * @param _data The data payload.\n */\n function _recover(\n address _to,\n bytes memory _data\n ) internal pure returns (address spender) {\n if (_data.length >= 68) {\n bytes4 methodId;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n methodId := mload(add(_data, 0x20))\n }\n if (\n methodId == ERC20_TRANSFER ||\n methodId == ERC20_APPROVE ||\n methodId == ERC20_INCREASE_ALLOWANCE ||\n methodId == ERC20_DECREASE_ALLOWANCE ||\n methodId == ERC721_SET_APPROVAL_FOR_ALL\n ) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n spender := mload(add(_data, 0x24))\n }\n return spender;\n }\n if (\n methodId == ERC721_TRANSFER_FROM ||\n methodId == ERC721_SAFE_TRANSFER_FROM ||\n methodId == ERC721_SAFE_TRANSFER_FROM_BYTES ||\n methodId == ERC1155_SAFE_TRANSFER_FROM ||\n methodId == ERC1155_SAFE_BATCH_TRANSFER_FROM\n ) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n spender := mload(add(_data, 0x44))\n }\n return spender;\n }\n }\n\n spender = _to;\n }\n}\n" + }, + "contracts/libraries/LibUtils.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\n\nlibrary LibUtils {\n // Internal utility functions\n function mergeArrays(\n bytes4[] memory _array1,\n bytes4[] memory _array2\n ) internal pure returns (bytes4[] memory) {\n uint256 length1 = _array1.length;\n uint256 length2 = _array2.length;\n bytes4[] memory mergedArray = new bytes4[](length1 + length2);\n\n for (uint256 i; i < length1; ) {\n mergedArray[i] = _array1[i];\n unchecked {\n ++i;\n }\n }\n\n for (uint256 i; i < length2; ) {\n mergedArray[length1 + i] = _array2[i];\n unchecked {\n ++i;\n }\n }\n\n return mergedArray;\n }\n\n function removeFacetElement(\n IDiamondLoupe.Facet[] memory _facets,\n uint256 _index\n ) internal pure returns (IDiamondLoupe.Facet[] memory) {\n require(_index < _facets.length, \"Invalid index\");\n require(_facets.length != 0, \"Invalid array\");\n\n // Create a new array with a length of `_facets.length - 1`\n IDiamondLoupe.Facet[] memory newArray = new IDiamondLoupe.Facet[](\n _facets.length - 1\n );\n uint256 newArrayLength = newArray.length;\n // Iterate over the original array, skipping the element at the specified `index`\n for (uint256 i; i < newArrayLength; ) {\n if (i < _index) {\n newArray[i] = _facets[i];\n } else {\n newArray[i] = _facets[i + 1];\n }\n unchecked {\n ++i;\n }\n }\n\n return newArray;\n }\n\n function removeElement(\n bytes4[] memory _array,\n uint256 _index\n ) internal pure returns (bytes4[] memory) {\n require(_index < _array.length, \"Invalid index\");\n require(_array.length != 0, \"Invalid array\");\n\n bytes4[] memory newArray = new bytes4[](_array.length - 1);\n uint256 newArrayLength = newArray.length;\n for (uint256 i; i < newArrayLength; ) {\n if (i < _index) {\n newArray[i] = _array[i];\n } else {\n newArray[i] = _array[i + 1];\n }\n unchecked {\n ++i;\n }\n }\n\n return newArray;\n }\n\n function setValue(\n bytes4[] memory _keys,\n address[] memory _values,\n bytes4 _key,\n address _value\n ) internal pure returns (bytes4[] memory, address[] memory) {\n uint256 index = findIndex(_keys, _key);\n uint256 keysLength = _keys.length;\n if (index < keysLength) {\n _values[index] = _value;\n } else {\n // Create new storage arrays\n bytes4[] memory newKeys = new bytes4[](keysLength + 1);\n address[] memory newValues = new address[](_values.length + 1);\n\n // Copy values to the new storage arrays\n for (uint256 i; i < keysLength; ) {\n newKeys[i] = _keys[i];\n newValues[i] = _values[i];\n\n unchecked {\n ++i;\n }\n }\n\n // Add the new key-value pair\n newKeys[keysLength] = _key;\n newValues[_values.length] = _value;\n\n return (newKeys, newValues);\n }\n\n // If the key already exists, return the original arrays\n return (_keys, _values);\n }\n\n function getValue(\n bytes4[] memory _keys,\n address[] memory _values,\n bytes4 _key\n ) internal pure returns (address) {\n uint256 index = findIndex(_keys, _key);\n if (index >= _keys.length) return address(0);\n\n return _values[index];\n }\n\n function findIndex(\n bytes4[] memory _keys,\n bytes4 _key\n ) internal pure returns (uint256) {\n uint256 keysLength = _keys.length;\n for (uint256 i; i < keysLength; ) {\n if (_keys[i] == _key) {\n return i;\n }\n unchecked {\n ++i;\n }\n }\n return keysLength;\n }\n}\n" + }, + "contracts/restrictions/IRestriction.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Interface for restrictions\n * @dev Restriction is a contract which decides whether to approve a certain kind of transaction, based on its internal logic.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface IRestriction {\n /**\n * @dev Based on restriction's internal logic, it should accept or reject a certain transaction.\n * @param from The address of the sender, that will be signing the transaction.\n * @param to The receiving address.\n * @param value Amount of ETH to transfer from sender to recipient.\n * @param _calldata Optional field to include arbitrary data.\n * @return bool value for whether the check is passed\n */\n function check(\n address from,\n address to,\n uint256 value,\n bytes calldata _calldata\n ) external returns (bool);\n}\n" + }, + "contracts/restrictions/WhitelistRestriction.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibRecoverSpender} from \"../libraries/LibRecoverSpender.sol\";\nimport {WhitelistStorage} from \"../infrastructure/WhitelistStorage.sol\";\nimport {IRestriction} from \"./IRestriction.sol\";\n\n/**\n * @title Whitelist Restriction\n * @dev This restriction defines a list of accepted addresses and denies any interaction with addresses outside of it.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract WhitelistRestriction is IRestriction {\n WhitelistStorage public immutable whitelistStorage;\n\n constructor(WhitelistStorage _whitelistStorage) {\n whitelistStorage = _whitelistStorage;\n }\n\n /**\n * @notice Helper method to recover the spender from a contract call.\n * The method returns the contract unless the call is to a standard method of a ERC20/ERC721/ERC1155 token\n * in which case the spender is recovered from the data.\n * @param _to The target contract.\n * @param _data The data payload.\n */\n function recoverSpender(\n address _to,\n bytes memory _data\n ) public pure returns (address spender) {\n return LibRecoverSpender._recover(_to, _data);\n }\n\n /*\n * @dev IRestriction's implementation. It will allow transaction if the sender is whitelisted, or user, or the whitelist storage.\n * @param _from The address of the sender, that will be signing the transaction.\n * @param _to The receiving address.\n * @param _calldata Optional field to include arbitrary data.\n * @return result value for whether the check is passed\n */\n function check(\n address _from,\n address _to,\n uint256 /*_value*/,\n bytes calldata _calldata\n ) external view override returns (bool result) {\n return\n whitelistStorage.isWhitelisted(\n _from,\n LibRecoverSpender._recover(_to, _calldata)\n ) ||\n _to == address(whitelistStorage) ||\n _to == msg.sender;\n }\n}\n" + }, + "contracts/test/Counter.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\ncontract TestCounter {\n int private count = 0;\n\n function incrementCounter() public {\n count += 1;\n }\n\n function decrementCounter() public {\n count -= 1;\n }\n\n function getCount() public view returns (int) {\n return count;\n }\n}\n" + }, + "contracts/test/TestERC1155.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC1155/ERC1155.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\n\ncontract TestERC1155 is ERC1155 {\n using Counters for Counters.Counter;\n\n Counters.Counter private _tokenIds;\n\n constructor() ERC1155(\"\") {}\n\n function mint(address account, uint256 amount) external {\n uint256 tokenId = _getNextTokenId();\n _mint(account, tokenId, amount, \"\");\n }\n\n function mintBatch(\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes memory data\n ) external {\n require(\n ids.length == amounts.length,\n \"TestERC1155: arrays length mismatch\"\n );\n\n _mintBatch(to, ids, amounts, data);\n }\n\n function _getNextTokenId() private returns (uint256) {\n _tokenIds.increment();\n return _tokenIds.current();\n }\n}\n" + }, + "contracts/test/TestERC777.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC777/ERC777.sol\";\n\ncontract TestERC777 is ERC777 {\n constructor(\n address[] memory _operators\n ) ERC777(\"TestERC777\", \"TERC777\", _operators) {}\n\n function mint(address account, uint256 amount) external {\n _mint(account, amount, \"\", \"\");\n }\n}\n" + }, + "contracts/test/TestInvalidSecp256k1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IVerificationFacet} from \"../facets/interfaces/IVerificationFacet.sol\";\nimport {IERC1271} from \"../interfaces/ERC/IERC1271.sol\";\nimport {AppStorage, LibAppStorage, BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {LibFacetStorage, Secp256k1VerificationStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {UserOperation} from \"../aa-4337/interfaces/UserOperation.sol\";\n\n/**\n * @title Test Secp256k1 verification facet\n * @dev Default Ethereum's elliptic curve\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract TestInvalidSecp256k1VerificationFacet is BarzStorage, IERC1271 {\n using ECDSA for bytes32;\n error Secp256k1VerificationFacet__InvalidSignerLength();\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n\n event SignerUninitialized();\n\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n }\n\n // THIS INVALID FACET DOES NOT INCLUDE initializeSigner()\n // THIS FACET IS USED TO TEST WHEN initializeSigner() DOESN'T EXIST IN FACET\n\n function uninitializeSigner() external returns (uint256 uninitSuccess) {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view returns (uint256 validationData) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n return validateSignature(userOp, userOpHash, k1Storage.signer);\n }\n\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n address signer\n ) public pure returns (uint256) {\n bytes32 hash = userOpHash.toEthSignedMessageHash();\n if (signer != hash.recover(userOp.signature)) return 1;\n return 0;\n }\n\n // This is REMOVED for testing purpose\n function validateOwnerSignatureSelector() public pure returns (bytes4) {\n // return this.validateOwnerSignature.selector;\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n function owner() public view returns (bytes memory) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n return abi.encodePacked(k1Storage.signer);\n }\n\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure returns (bool) {\n return (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (_hash.recover(_signature) ==\n LibFacetStorage.k1Storage().signer)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n}\n" + }, + "contracts/test/TestNFT.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\n\ncontract TestNFT is ERC721 {\n using Counters for Counters.Counter;\n Counters.Counter private currentTokenId;\n\n constructor() ERC721(\"TestNFT\", \"TNFT\") {}\n\n function mint(address recipient) public returns (uint256) {\n currentTokenId.increment();\n uint256 newItemId = currentTokenId.current();\n _safeMint(recipient, newItemId);\n return newItemId;\n }\n}\n" + }, + "contracts/test/TestToken.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract TestToken is ERC20 {\n constructor()\n // solhint-disable-next-line no-empty-blocks\n ERC20(\"TST\", \"TestToken\")\n {}\n\n function mint(address sender, uint256 amount) external {\n _mint(sender, amount);\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 999999 + }, + "evmVersion": "paris", + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/deployments/avalanche/.chainId b/deployments/avalanche/.chainId new file mode 100644 index 0000000..2d1acc4 --- /dev/null +++ b/deployments/avalanche/.chainId @@ -0,0 +1 @@ +43114 \ No newline at end of file diff --git a/deployments/avalanche/AccountFacet.json b/deployments/avalanche/AccountFacet.json new file mode 100644 index 0000000..64323aa --- /dev/null +++ b/deployments/avalanche/AccountFacet.json @@ -0,0 +1,591 @@ +{ + "address": "0xFde53272dcd7938d16E031A6989753c321728332", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "AccountFacet__CallNotSuccessful", + "type": "error" + }, + { + "inputs": [], + "name": "AccountFacet__InitializationFailure", + "type": "error" + }, + { + "inputs": [], + "name": "AccountFacet__InvalidArrayLength", + "type": "error" + }, + { + "inputs": [], + "name": "AccountFacet__NonExistentVerificationFacet", + "type": "error" + }, + { + "inputs": [], + "name": "AccountFacet__RestrictionsFailure", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_initializationContractAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "InitializationFunctionReverted", + "type": "error" + }, + { + "inputs": [], + "name": "LibAppStorage__AccountMustBeUninitialized", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract IEntryPoint", + "name": "entryPoint", + "type": "address" + }, + { + "indexed": true, + "internalType": "bytes", + "name": "ownerPublicKey", + "type": "bytes" + } + ], + "name": "AccountInitialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "indexed": false, + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "DiamondCut", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "VerificationFailure", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "VerificationSuccess", + "type": "event" + }, + { + "inputs": [], + "name": "entryPoint", + "outputs": [ + { + "internalType": "contract IEntryPoint", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_dest", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_func", + "type": "bytes" + } + ], + "name": "execute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_dest", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "_value", + "type": "uint256[]" + }, + { + "internalType": "bytes[]", + "name": "_func", + "type": "bytes[]" + } + ], + "name": "executeBatch", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getNonce", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_verificationFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_anEntryPoint", + "type": "address" + }, + { + "internalType": "address", + "name": "_facetRegistry", + "type": "address" + }, + { + "internalType": "address", + "name": "_defaultFallBackHandler", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_ownerPublicKey", + "type": "bytes" + } + ], + "name": "initialize", + "outputs": [ + { + "internalType": "uint256", + "name": "initSuccess", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "initCode", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "callGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "verificationGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "preVerificationGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxFeePerGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPriorityFeePerGas", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "paymasterAndData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "internalType": "struct UserOperation", + "name": "userOp", + "type": "tuple" + }, + { + "internalType": "bytes32", + "name": "userOpHash", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "missingAccountFunds", + "type": "uint256" + } + ], + "name": "validateUserOp", + "outputs": [ + { + "internalType": "uint256", + "name": "validationData", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0xe1bbe0f1286380a6ab344f1b3cc84f124704f06af07019026d55d258629472e7", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 141, + "gasUsed": "2369950", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x0f94ff4951b7af9c5f804ec4d86c987354405336813ef043098e1a2f8bdfd1af", + "transactionHash": "0xe1bbe0f1286380a6ab344f1b3cc84f124704f06af07019026d55d258629472e7", + "logs": [], + "blockNumber": 38010857, + "cumulativeGasUsed": "6194496", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 3, + "solcInputHash": "4356503edd8ae34e73cb6dd1c8e2fc8a", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AccountFacet__CallNotSuccessful\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AccountFacet__InitializationFailure\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AccountFacet__InvalidArrayLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AccountFacet__NonExistentVerificationFacet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AccountFacet__RestrictionsFailure\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_initializationContractAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"InitializationFunctionReverted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LibAppStorage__AccountMustBeUninitialized\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract IEntryPoint\",\"name\":\"entryPoint\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes\",\"name\":\"ownerPublicKey\",\"type\":\"bytes\"}],\"name\":\"AccountInitialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"DiamondCut\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"VerificationFailure\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"VerificationSuccess\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"entryPoint\",\"outputs\":[{\"internalType\":\"contract IEntryPoint\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_dest\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_func\",\"type\":\"bytes\"}],\"name\":\"execute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_dest\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"_value\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes[]\",\"name\":\"_func\",\"type\":\"bytes[]\"}],\"name\":\"executeBatch\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_verificationFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_anEntryPoint\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_facetRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_defaultFallBackHandler\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_ownerPublicKey\",\"type\":\"bytes\"}],\"name\":\"initialize\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"initSuccess\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"userOp\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"missingAccountFunds\",\"type\":\"uint256\"}],\"name\":\"validateUserOp\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"validationData\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"Account module contract that provides the account features and initialization of signer compatible with EIP-1271 & EIP-4337\",\"kind\":\"dev\",\"methods\":{\"execute(address,uint256,bytes)\":{\"details\":\"This method executes the calldata coming from the EntryPoint. Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\",\"params\":{\"_dest\":\"Address of destination where the call will be forwarded to\",\"_func\":\"Bytes of calldata to execute in the destination address\",\"_value\":\"Amount of native coin the owner is willing to send(e.g. ETH, BNB)\"}},\"executeBatch(address[],uint256[],bytes[])\":{\"details\":\"This method batch executes the calldata coming from the EntryPoint. Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\",\"params\":{\"_dest\":\"Array of addresses of destination where the call will be forwarded to\",\"_func\":\"Array of bytes of calldata to execute in the destination address\",\"_value\":\"Array of amount of native coin the owner is willing to send(e.g. ETH, BNB)\"}},\"initialize(address,address,address,address,bytes)\":{\"details\":\"This method can only be called during the initialization or signature migration. If the proxy contract was created without initialization, anyone can call initialize. Barz calls initialize in constructor in an atomic transaction during deployment\",\"params\":{\"_anEntryPoint\":\"Entrypoint contract defined in EIP-4337 handling the flow of UserOp\",\"_defaultFallBackHandler\":\"Middleware contract for default facets\",\"_facetRegistry\":\"Registry of Facets that hold all facet information\",\"_ownerPublicKey\":\"Bytes of owner public key\",\"_verificationFacet\":\"Facet contract handling the verificationi\"}}},\"title\":\"Account Facet\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"This constructor ensures that this contract can only be used as singleton for Proxy contracts\"},\"entryPoint()\":{\"notice\":\"Returns the address of EntryPoint contract registered to Barz account\"},\"execute(address,uint256,bytes)\":{\"notice\":\"Calls the destination with inputted calldata and value from EntryPoint\"},\"executeBatch(address[],uint256[],bytes[])\":{\"notice\":\"Batch calls the destination with inputted calldata and value from EntryPoint\"},\"getNonce()\":{\"notice\":\"Return the account nonce. This method returns the next sequential nonce. For a nonce of a specific key, use `entrypoint.getNonce(account, key)`\"},\"initialize(address,address,address,address,bytes)\":{\"notice\":\"Initializes the initial storage of the Barz contract.\"},\"validateUserOp((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256)\":{\"notice\":\"Validate user's signature and nonce. subclass doesn't need to override this method. Instead, it should override the specific internal validation methods.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/AccountFacet.sol\":\"AccountFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./math/Math.sol\\\";\\nimport \\\"./math/SignedMath.sol\\\";\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n uint256 length = Math.log10(value) + 1;\\n string memory buffer = new string(length);\\n uint256 ptr;\\n /// @solidity memory-safe-assembly\\n assembly {\\n ptr := add(buffer, add(32, length))\\n }\\n while (true) {\\n ptr--;\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\\n }\\n value /= 10;\\n if (value == 0) break;\\n }\\n return buffer;\\n }\\n }\\n\\n /**\\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\\n */\\n function toString(int256 value) internal pure returns (string memory) {\\n return string(abi.encodePacked(value < 0 ? \\\"-\\\" : \\\"\\\", toString(SignedMath.abs(value))));\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n return toHexString(value, Math.log256(value) + 1);\\n }\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n\\n /**\\n * @dev Returns true if the two strings are equal.\\n */\\n function equal(string memory a, string memory b) internal pure returns (bool) {\\n return keccak256(bytes(a)) == keccak256(bytes(b));\\n }\\n}\\n\",\"keccak256\":\"0x3088eb2868e8d13d89d16670b5f8612c4ab9ff8956272837d8e90106c59c14a0\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Strings.sol\\\";\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSA {\\n enum RecoverError {\\n NoError,\\n InvalidSignature,\\n InvalidSignatureLength,\\n InvalidSignatureS,\\n InvalidSignatureV // Deprecated in v4.8\\n }\\n\\n function _throwError(RecoverError error) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert(\\\"ECDSA: invalid signature\\\");\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert(\\\"ECDSA: invalid signature length\\\");\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert(\\\"ECDSA: invalid signature 's' value\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature` or error string. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n *\\n * Documentation for signature generation:\\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n return tryRecover(hash, v, r, s);\\n } else {\\n return (address(0), RecoverError.InvalidSignatureLength);\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature`. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, signature);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\\n uint8 v = uint8((uint256(vs) >> 255) + 27);\\n return tryRecover(hash, v, r, s);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n *\\n * _Available since v4.2._\\n */\\n function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\\n // the valid range for s in (301): 0 < s < secp256k1n \\u00f7 2 + 1, and for v in (302): v \\u2208 {27, 28}. Most\\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\\n //\\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\\n // these malleable signatures as well.\\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n return (address(0), RecoverError.InvalidSignatureS);\\n }\\n\\n // If the signature is valid (and not malleable), return the signer address\\n address signer = ecrecover(hash, v, r, s);\\n if (signer == address(0)) {\\n return (address(0), RecoverError.InvalidSignature);\\n }\\n\\n return (signer, RecoverError.NoError);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore(0x00, \\\"\\\\x19Ethereum Signed Message:\\\\n32\\\")\\n mstore(0x1c, hash)\\n message := keccak256(0x00, 0x3c)\\n }\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from `s`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n\\\", Strings.toString(s.length), s));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Typed Data, created from a\\n * `domainSeparator` and a `structHash`. This produces hash corresponding\\n * to the one signed with the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n * JSON-RPC method as part of EIP-712.\\n *\\n * See {recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n let ptr := mload(0x40)\\n mstore(ptr, \\\"\\\\x19\\\\x01\\\")\\n mstore(add(ptr, 0x02), domainSeparator)\\n mstore(add(ptr, 0x22), structHash)\\n data := keccak256(ptr, 0x42)\\n }\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Data with intended validator, created from a\\n * `validator` and `data` according to the version 0 of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x00\\\", validator, data));\\n }\\n}\\n\",\"keccak256\":\"0x809bc3edb4bcbef8263fa616c1b60ee0004b50a8a1bfa164d8f57fd31f520c58\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n enum Rounding {\\n Down, // Toward negative infinity\\n Up, // Toward infinity\\n Zero // Toward zero\\n }\\n\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow.\\n return (a & b) + (a ^ b) / 2;\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a == 0 ? 0 : (a - 1) / b + 1;\\n }\\n\\n /**\\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\\n * with further edits by Uniswap Labs also under MIT license.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\\n unchecked {\\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2^256 + prod0.\\n uint256 prod0; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division.\\n if (prod1 == 0) {\\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\\n // The surrounding unchecked block does not change this fact.\\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\\n return prod0 / denominator;\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n require(denominator > prod1, \\\"Math: mulDiv overflow\\\");\\n\\n ///////////////////////////////////////////////\\n // 512 by 256 division.\\n ///////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0].\\n uint256 remainder;\\n assembly {\\n // Compute remainder using mulmod.\\n remainder := mulmod(x, y, denominator)\\n\\n // Subtract 256 bit number from 512 bit number.\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\\n // See https://cs.stackexchange.com/q/138556/92363.\\n\\n // Does not overflow because the denominator cannot be zero at this stage in the function.\\n uint256 twos = denominator & (~denominator + 1);\\n assembly {\\n // Divide denominator by twos.\\n denominator := div(denominator, twos)\\n\\n // Divide [prod1 prod0] by twos.\\n prod0 := div(prod0, twos)\\n\\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\\n twos := add(div(sub(0, twos), twos), 1)\\n }\\n\\n // Shift in bits from prod1 into prod0.\\n prod0 |= prod1 * twos;\\n\\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\\n // four bits. That is, denominator * inv = 1 mod 2^4.\\n uint256 inverse = (3 * denominator) ^ 2;\\n\\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\\n // in modular arithmetic, doubling the correct bits in each step.\\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\\n\\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inverse;\\n return result;\\n }\\n }\\n\\n /**\\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\\n uint256 result = mulDiv(x, y, denominator);\\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\\n result += 1;\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\\n *\\n * Inspired by Henry S. Warren, Jr.'s \\\"Hacker's Delight\\\" (Chapter 11).\\n */\\n function sqrt(uint256 a) internal pure returns (uint256) {\\n if (a == 0) {\\n return 0;\\n }\\n\\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\\n //\\n // We know that the \\\"msb\\\" (most significant bit) of our target number `a` is a power of 2 such that we have\\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\\n //\\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\\n // \\u2192 `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\\n // \\u2192 `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\\n //\\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\\n uint256 result = 1 << (log2(a) >> 1);\\n\\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\\n // into the expected uint128 result.\\n unchecked {\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n return min(result, a / result);\\n }\\n }\\n\\n /**\\n * @notice Calculates sqrt(a), following the selected rounding direction.\\n */\\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = sqrt(a);\\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 2, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 128;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 64;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 32;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 16;\\n }\\n if (value >> 8 > 0) {\\n value >>= 8;\\n result += 8;\\n }\\n if (value >> 4 > 0) {\\n value >>= 4;\\n result += 4;\\n }\\n if (value >> 2 > 0) {\\n value >>= 2;\\n result += 2;\\n }\\n if (value >> 1 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log2(value);\\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 10, rounded down, of a positive value.\\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 + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 256, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n *\\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\\n */\\n function log256(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 16;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 8;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 4;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 2;\\n }\\n if (value >> 8 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log256(value);\\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe4455ac1eb7fc497bb7402579e7b4d64d928b846fce7d2b6fde06d366f21c2b3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\\n * checks.\\n *\\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\\n * easily result in undesired exploitation or bugs, since developers usually\\n * assume that overflows raise errors. `SafeCast` restores this intuition by\\n * reverting the transaction when such an operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n *\\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\\n * all math on `uint256` and `int256` and then downcasting.\\n */\\nlibrary SafeCast {\\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 * _Available since v4.7._\\n */\\n function toUint248(uint256 value) internal pure returns (uint248) {\\n require(value <= type(uint248).max, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint240(uint256 value) internal pure returns (uint240) {\\n require(value <= type(uint240).max, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint232(uint256 value) internal pure returns (uint232) {\\n require(value <= type(uint232).max, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint224(uint256 value) internal pure returns (uint224) {\\n require(value <= type(uint224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint216(uint256 value) internal pure returns (uint216) {\\n require(value <= type(uint216).max, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint208(uint256 value) internal pure returns (uint208) {\\n require(value <= type(uint208).max, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint200(uint256 value) internal pure returns (uint200) {\\n require(value <= type(uint200).max, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint192(uint256 value) internal pure returns (uint192) {\\n require(value <= type(uint192).max, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint184(uint256 value) internal pure returns (uint184) {\\n require(value <= type(uint184).max, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint176(uint256 value) internal pure returns (uint176) {\\n require(value <= type(uint176).max, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint168(uint256 value) internal pure returns (uint168) {\\n require(value <= type(uint168).max, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint160(uint256 value) internal pure returns (uint160) {\\n require(value <= type(uint160).max, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint152(uint256 value) internal pure returns (uint152) {\\n require(value <= type(uint152).max, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint144(uint256 value) internal pure returns (uint144) {\\n require(value <= type(uint144).max, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint136(uint256 value) internal pure returns (uint136) {\\n require(value <= type(uint136).max, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint128(uint256 value) internal pure returns (uint128) {\\n require(value <= type(uint128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint120(uint256 value) internal pure returns (uint120) {\\n require(value <= type(uint120).max, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint112(uint256 value) internal pure returns (uint112) {\\n require(value <= type(uint112).max, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint104(uint256 value) internal pure returns (uint104) {\\n require(value <= type(uint104).max, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint96(uint256 value) internal pure returns (uint96) {\\n require(value <= type(uint96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint88(uint256 value) internal pure returns (uint88) {\\n require(value <= type(uint88).max, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint80(uint256 value) internal pure returns (uint80) {\\n require(value <= type(uint80).max, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint72(uint256 value) internal pure returns (uint72) {\\n require(value <= type(uint72).max, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint64(uint256 value) internal pure returns (uint64) {\\n require(value <= type(uint64).max, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint56(uint256 value) internal pure returns (uint56) {\\n require(value <= type(uint56).max, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint48(uint256 value) internal pure returns (uint48) {\\n require(value <= type(uint48).max, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint40(uint256 value) internal pure returns (uint40) {\\n require(value <= type(uint40).max, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint32(uint256 value) internal pure returns (uint32) {\\n require(value <= type(uint32).max, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint24(uint256 value) internal pure returns (uint24) {\\n require(value <= type(uint24).max, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint16(uint256 value) internal pure returns (uint16) {\\n require(value <= type(uint16).max, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint8(uint256 value) internal pure returns (uint8) {\\n require(value <= type(uint8).max, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\n */\\n function toUint256(int256 value) internal pure returns (uint256) {\\n require(value >= 0, \\\"SafeCast: value must be positive\\\");\\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 * _Available since v4.7._\\n */\\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\\n downcasted = int248(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\\n downcasted = int240(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\\n downcasted = int232(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\\n downcasted = int224(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\\n downcasted = int216(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\\n downcasted = int208(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\\n downcasted = int200(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\\n downcasted = int192(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\\n downcasted = int184(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\\n downcasted = int176(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\\n downcasted = int168(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\\n downcasted = int160(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\\n downcasted = int152(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\\n downcasted = int144(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\\n downcasted = int136(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\\n downcasted = int128(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\\n downcasted = int120(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\\n downcasted = int112(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\\n downcasted = int104(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\\n downcasted = int96(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\\n downcasted = int88(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\\n downcasted = int80(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\\n downcasted = int72(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\\n downcasted = int64(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\\n downcasted = int56(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\\n downcasted = int48(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\\n downcasted = int40(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\\n downcasted = int32(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\\n downcasted = int24(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\\n downcasted = int16(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\\n downcasted = int8(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\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 require(value <= uint256(type(int256).max), \\\"SafeCast: value doesn't fit in an int256\\\");\\n return int256(value);\\n }\\n}\\n\",\"keccak256\":\"0x52a8cfb0f5239d11b457dcdd1b326992ef672714ca8da71a157255bddd13f3ad\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SignedMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard signed math utilities missing in the Solidity language.\\n */\\nlibrary SignedMath {\\n /**\\n * @dev Returns the largest of two signed numbers.\\n */\\n function max(int256 a, int256 b) internal pure returns (int256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two signed numbers.\\n */\\n function min(int256 a, int256 b) internal pure returns (int256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two signed numbers without overflow.\\n * The result is rounded towards zero.\\n */\\n function average(int256 a, int256 b) internal pure returns (int256) {\\n // Formula from the book \\\"Hacker's Delight\\\"\\n int256 x = (a & b) + ((a ^ b) >> 1);\\n return x + (int256(uint256(x) >> 255) & (a ^ b));\\n }\\n\\n /**\\n * @dev Returns the absolute unsigned value of a signed value.\\n */\\n function abs(int256 n) internal pure returns (uint256) {\\n unchecked {\\n // must be unchecked in order to support `n = type(int256).min`\\n return uint256(n >= 0 ? n : -n);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf92515413956f529d95977adc9b0567d583c6203fc31ab1c23824c35187e3ddc\",\"license\":\"MIT\"},\"contracts/aa-4337/core/BaseAccount.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-empty-blocks */\\n\\nimport \\\"../interfaces/IAccount.sol\\\";\\nimport \\\"../interfaces/IEntryPoint.sol\\\";\\nimport \\\"./Helpers.sol\\\";\\n\\n/**\\n * Basic account implementation.\\n * this contract provides the basic logic for implementing the IAccount interface - validateUserOp\\n * specific account implementation should inherit it and provide the account-specific logic\\n */\\nabstract contract BaseAccount is IAccount {\\n using UserOperationLib for UserOperation;\\n\\n //return value in case of signature failure, with no time-range.\\n // equivalent to _packValidationData(true,0,0);\\n uint256 internal constant SIG_VALIDATION_FAILED = 1;\\n\\n /**\\n * Return the account nonce.\\n * This method returns the next sequential nonce.\\n * For a nonce of a specific key, use `entrypoint.getNonce(account, key)`\\n */\\n function getNonce() public view virtual returns (uint256) {\\n return entryPoint().getNonce(address(this), 0);\\n }\\n\\n /**\\n * return the entryPoint used by this account.\\n * subclass should return the current entryPoint used by this account.\\n */\\n function entryPoint() public view virtual returns (IEntryPoint);\\n\\n /**\\n * Validate user's signature and nonce.\\n * subclass doesn't need to override this method. Instead, it should override the specific internal validation methods.\\n */\\n function validateUserOp(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n uint256 missingAccountFunds\\n ) external virtual override returns (uint256 validationData) {\\n _requireFromEntryPoint();\\n validationData = _validateSignature(userOp, userOpHash);\\n _validateNonce(userOp.nonce);\\n _payPrefund(missingAccountFunds);\\n }\\n\\n /**\\n * ensure the request comes from the known entrypoint.\\n */\\n function _requireFromEntryPoint() internal view virtual {\\n require(\\n msg.sender == address(entryPoint()),\\n \\\"account: not from EntryPoint\\\"\\n );\\n }\\n\\n /**\\n * validate the signature is valid for this message.\\n * @param userOp validate the userOp.signature field\\n * @param userOpHash convenient field: the hash of the request, to check the signature against\\n * (also hashes the entrypoint and chain id)\\n * @return validationData signature and time-range of this operation\\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\\n * otherwise, an address of an \\\"authorizer\\\" contract.\\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \\\"indefinite\\\"\\n * <6-byte> validAfter - first timestamp this operation is valid\\n * If the account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\\n */\\n function _validateSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) internal virtual returns (uint256 validationData);\\n\\n /**\\n * Validate the nonce of the UserOperation.\\n * This method may validate the nonce requirement of this account.\\n * e.g.\\n * To limit the nonce to use sequenced UserOps only (no \\\"out of order\\\" UserOps):\\n * `require(nonce < type(uint64).max)`\\n * For a hypothetical account that *requires* the nonce to be out-of-order:\\n * `require(nonce & type(uint64).max == 0)`\\n *\\n * The actual nonce uniqueness is managed by the EntryPoint, and thus no other\\n * action is needed by the account itself.\\n *\\n * @param nonce to validate\\n *\\n * solhint-disable-next-line no-empty-blocks\\n */\\n function _validateNonce(uint256 nonce) internal view virtual {}\\n\\n /**\\n * sends to the entrypoint (msg.sender) the missing funds for this transaction.\\n * subclass MAY override this method for better funds management\\n * (e.g. send to the entryPoint more than the minimum required, so that in future transactions\\n * it will not be required to send again)\\n * @param missingAccountFunds the minimum value this method should send the entrypoint.\\n * this value MAY be zero, in case there is enough deposit, or the userOp has a paymaster.\\n */\\n function _payPrefund(uint256 missingAccountFunds) internal virtual {\\n if (missingAccountFunds != 0) {\\n (bool success, ) = payable(msg.sender).call{\\n value: missingAccountFunds,\\n gas: type(uint256).max\\n }(\\\"\\\");\\n (success);\\n //ignore failure (its EntryPoint's job to verify, not account.)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa0dcc386b0f04711db3e394fb50e55a3b3b1a4d19fac1f10895844e1aa4e3d5c\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/core/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable no-inline-assembly */\\n\\n/**\\n * returned data from validateUserOp.\\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\\n * @param aggregator - address(0) - the account validated the signature by itself.\\n * address(1) - the account failed to validate the signature.\\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\\n * @param validAfter - this UserOp is valid only after this timestamp.\\n * @param validaUntil - this UserOp is valid only up to this timestamp.\\n */\\nstruct ValidationData {\\n address aggregator;\\n uint48 validAfter;\\n uint48 validUntil;\\n}\\n\\n//extract sigFailed, validAfter, validUntil.\\n// also convert zero validUntil to type(uint48).max\\nfunction _parseValidationData(\\n uint validationData\\n) pure returns (ValidationData memory data) {\\n address aggregator = address(uint160(validationData));\\n uint48 validUntil = uint48(validationData >> 160);\\n if (validUntil == 0) {\\n validUntil = type(uint48).max;\\n }\\n uint48 validAfter = uint48(validationData >> (48 + 160));\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n// intersect account and paymaster ranges.\\nfunction _intersectTimeRange(\\n uint256 validationData,\\n uint256 paymasterValidationData\\n) pure returns (ValidationData memory) {\\n ValidationData memory accountValidationData = _parseValidationData(\\n validationData\\n );\\n ValidationData memory pmValidationData = _parseValidationData(\\n paymasterValidationData\\n );\\n address aggregator = accountValidationData.aggregator;\\n if (aggregator == address(0)) {\\n aggregator = pmValidationData.aggregator;\\n }\\n uint48 validAfter = accountValidationData.validAfter;\\n uint48 validUntil = accountValidationData.validUntil;\\n uint48 pmValidAfter = pmValidationData.validAfter;\\n uint48 pmValidUntil = pmValidationData.validUntil;\\n\\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp\\n * @param data - the ValidationData to pack\\n */\\nfunction _packValidationData(\\n ValidationData memory data\\n) pure returns (uint256) {\\n return\\n uint160(data.aggregator) |\\n (uint256(data.validUntil) << 160) |\\n (uint256(data.validAfter) << (160 + 48));\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp, when not using an aggregator\\n * @param sigFailed - true for signature failure, false for success\\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\\n * @param validAfter first timestamp this UserOperation is valid\\n */\\nfunction _packValidationData(\\n bool sigFailed,\\n uint48 validUntil,\\n uint48 validAfter\\n) pure returns (uint256) {\\n return\\n (sigFailed ? 1 : 0) |\\n (uint256(validUntil) << 160) |\\n (uint256(validAfter) << (160 + 48));\\n}\\n\\n/**\\n * keccak function over calldata.\\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\\n */\\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\\n assembly {\\n let mem := mload(0x40)\\n let len := data.length\\n calldatacopy(mem, data.offset, len)\\n ret := keccak256(mem, len)\\n }\\n}\\n\",\"keccak256\":\"0xa79f06cd158ecb8c0da95493a2f348933b8627a63e228b99738bff3aa107942d\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAccount.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\ninterface IAccount {\\n /**\\n * Validate user's signature and nonce\\n * the entryPoint will make the call to the recipient only if this validation call returns successfully.\\n * signature failure should be reported by returning SIG_VALIDATION_FAILED (1).\\n * This allows making a \\\"simulation call\\\" without a valid signature\\n * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure.\\n *\\n * @dev Must validate caller is the entryPoint.\\n * Must validate the signature and nonce\\n * @param userOp the operation that is about to be executed.\\n * @param userOpHash hash of the user's request data. can be used as the basis for signature.\\n * @param missingAccountFunds missing funds on the account's deposit in the entrypoint.\\n * This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call.\\n * The excess is left as a deposit in the entrypoint, for future calls.\\n * can be withdrawn anytime using \\\"entryPoint.withdrawTo()\\\"\\n * In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero.\\n * @return validationData packaged ValidationData structure. use `_packValidationData` and `_unpackValidationData` to encode and decode\\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\\n * otherwise, an address of an \\\"authorizer\\\" contract.\\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \\\"indefinite\\\"\\n * <6-byte> validAfter - first timestamp this operation is valid\\n * If an account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\\n */\\n function validateUserOp(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n uint256 missingAccountFunds\\n ) external returns (uint256 validationData);\\n}\\n\",\"keccak256\":\"0xcbc4b0973cf954c5895b7796335f651fbfcfb55f67dfa789a3d354f8e23c4f2b\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAggregator.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\n/**\\n * Aggregated Signatures validator.\\n */\\ninterface IAggregator {\\n /**\\n * validate aggregated signature.\\n * revert if the aggregated signature does not match the given list of operations.\\n */\\n function validateSignatures(\\n UserOperation[] calldata userOps,\\n bytes calldata signature\\n ) external view;\\n\\n /**\\n * validate signature of a single userOp\\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\\n * @param userOp the userOperation received from the user.\\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\\n * (usually empty, unless account and aggregator support some kind of \\\"multisig\\\"\\n */\\n function validateUserOpSignature(\\n UserOperation calldata userOp\\n ) external view returns (bytes memory sigForUserOp);\\n\\n /**\\n * aggregate multiple signatures into a single value.\\n * This method is called off-chain to calculate the signature to pass with handleOps()\\n * bundler MAY use optimized custom code perform this aggregation\\n * @param userOps array of UserOperations to collect the signatures from.\\n * @return aggregatedSignature the aggregated signature\\n */\\n function aggregateSignatures(\\n UserOperation[] calldata userOps\\n ) external view returns (bytes memory aggregatedSignature);\\n}\\n\",\"keccak256\":\"0xdfdcd80568f037716674619b31be630fcd8316262f05a815b41d1e81782c966a\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IEntryPoint.sol\":{\"content\":\"/**\\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\\n ** Only one instance required on each chain.\\n **/\\n// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-inline-assembly */\\n/* solhint-disable reason-string */\\n\\nimport \\\"./UserOperation.sol\\\";\\nimport \\\"./IStakeManager.sol\\\";\\nimport \\\"./IAggregator.sol\\\";\\nimport \\\"./INonceManager.sol\\\";\\n\\ninterface IEntryPoint is IStakeManager, INonceManager {\\n /***\\n * An event emitted after each successful request\\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\\n * @param sender - the account that generates this request.\\n * @param paymaster - if non-null, the paymaster that pays for this request.\\n * @param nonce - the nonce value from the request.\\n * @param success - true if the sender transaction succeeded, false if reverted.\\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\\n */\\n event UserOperationEvent(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address indexed paymaster,\\n uint256 nonce,\\n bool success,\\n uint256 actualGasCost,\\n uint256 actualGasUsed\\n );\\n\\n /**\\n * account \\\"sender\\\" was deployed.\\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\\n * @param sender the account that is deployed\\n * @param factory the factory used to deploy this account (in the initCode)\\n * @param paymaster the paymaster used by this UserOp\\n */\\n event AccountDeployed(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address factory,\\n address paymaster\\n );\\n\\n /**\\n * An event emitted if the UserOperation \\\"callData\\\" reverted with non-zero length\\n * @param userOpHash the request unique identifier.\\n * @param sender the sender of this request\\n * @param nonce the nonce used in the request\\n * @param revertReason - the return bytes from the (reverted) call to \\\"callData\\\".\\n */\\n event UserOperationRevertReason(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n uint256 nonce,\\n bytes revertReason\\n );\\n\\n /**\\n * an event emitted by handleOps(), before starting the execution loop.\\n * any event emitted before this event, is part of the validation.\\n */\\n event BeforeExecution();\\n\\n /**\\n * signature aggregator used by the following UserOperationEvents within this bundle.\\n */\\n event SignatureAggregatorChanged(address indexed aggregator);\\n\\n /**\\n * a custom revert error of handleOps, to identify the offending op.\\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\\n * @param reason - revert reason\\n * The string starts with a unique code \\\"AAmn\\\", where \\\"m\\\" is \\\"1\\\" for factory, \\\"2\\\" for account and \\\"3\\\" for paymaster issues,\\n * so a failure can be attributed to the correct entity.\\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\\n */\\n error FailedOp(uint256 opIndex, string reason);\\n\\n /**\\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\\n */\\n error SignatureValidationFailed(address aggregator);\\n\\n /**\\n * Successful result from simulateValidation.\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n */\\n error ValidationResult(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo\\n );\\n\\n /**\\n * Successful result from simulateValidation, if the account returns a signature aggregator\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\\n * bundler MUST use it to verify the signature, or reject the UserOperation\\n */\\n error ValidationResultWithAggregation(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo,\\n AggregatorStakeInfo aggregatorInfo\\n );\\n\\n /**\\n * return value of getSenderAddress\\n */\\n error SenderAddressResult(address sender);\\n\\n /**\\n * return value of simulateHandleOp\\n */\\n error ExecutionResult(\\n uint256 preOpGas,\\n uint256 paid,\\n uint48 validAfter,\\n uint48 validUntil,\\n bool targetSuccess,\\n bytes targetResult\\n );\\n\\n //UserOps handled, per aggregator\\n struct UserOpsPerAggregator {\\n UserOperation[] userOps;\\n // aggregator address\\n IAggregator aggregator;\\n // aggregated signature\\n bytes signature;\\n }\\n\\n /**\\n * Execute a batch of UserOperation.\\n * no signature aggregator is used.\\n * if any account requires an aggregator (that is, it returned an aggregator when\\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\\n * @param ops the operations to execute\\n * @param beneficiary the address to receive the fees\\n */\\n function handleOps(\\n UserOperation[] calldata ops,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * Execute a batch of UserOperation with Aggregators\\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\\n * @param beneficiary the address to receive the fees\\n */\\n function handleAggregatedOps(\\n UserOpsPerAggregator[] calldata opsPerAggregator,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * generate a request Id - unique identifier for this request.\\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\\n */\\n function getUserOpHash(\\n UserOperation calldata userOp\\n ) external view returns (bytes32);\\n\\n /**\\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\\n * @param userOp the user operation to validate.\\n */\\n function simulateValidation(UserOperation calldata userOp) external;\\n\\n /**\\n * gas and return values during simulation\\n * @param preOpGas the gas used for validation (including preValidationGas)\\n * @param prefund the required prefund for this operation\\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\\n */\\n struct ReturnInfo {\\n uint256 preOpGas;\\n uint256 prefund;\\n bool sigFailed;\\n uint48 validAfter;\\n uint48 validUntil;\\n bytes paymasterContext;\\n }\\n\\n /**\\n * returned aggregated signature info.\\n * the aggregator returned by the account, and its current stake.\\n */\\n struct AggregatorStakeInfo {\\n address aggregator;\\n StakeInfo stakeInfo;\\n }\\n\\n /**\\n * Get counterfactual sender address.\\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\\n * this method always revert, and returns the address in SenderAddressResult error\\n * @param initCode the constructor code to be passed into the UserOperation.\\n */\\n function getSenderAddress(bytes memory initCode) external;\\n\\n /**\\n * simulate full execution of a UserOperation (including both validation and target execution)\\n * this method will always revert with \\\"ExecutionResult\\\".\\n * it performs full validation of the UserOperation, but ignores signature error.\\n * an optional target address is called after the userop succeeds, and its value is returned\\n * (before the entire call is reverted)\\n * Note that in order to collect the the success/failure of the target call, it must be executed\\n * with trace enabled to track the emitted events.\\n * @param op the UserOperation to simulate\\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\\n * are set to the return from that call.\\n * @param targetCallData callData to pass to target address\\n */\\n function simulateHandleOp(\\n UserOperation calldata op,\\n address target,\\n bytes calldata targetCallData\\n ) external;\\n}\\n\",\"keccak256\":\"0x9ccb1b188eda8bbf5f6c2d01bd83c3d8b2b04fcf745283051d31fe96d1d8e40f\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/INonceManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\ninterface INonceManager {\\n /**\\n * Return the next nonce for this sender.\\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\\n * But UserOp with different keys can come with arbitrary order.\\n *\\n * @param sender the account address\\n * @param key the high 192 bit of the nonce\\n * @return nonce a full nonce to pass for next UserOp with this sender.\\n */\\n function getNonce(\\n address sender,\\n uint192 key\\n ) external view returns (uint256 nonce);\\n\\n /**\\n * Manually increment the nonce of the sender.\\n * This method is exposed just for completeness..\\n * Account does NOT need to call it, neither during validation, nor elsewhere,\\n * as the EntryPoint will update the nonce regardless.\\n * Possible use-case is call it with various keys to \\\"initialize\\\" their nonces to one, so that future\\n * UserOperations will not pay extra for the first transaction with a given key.\\n */\\n function incrementNonce(uint192 key) external;\\n}\\n\",\"keccak256\":\"0xce478ad0fa0d18a3b785ac854623029e7ab463d05873dfaa365abfa1bf100912\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IStakeManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8.12;\\n\\n/**\\n * manage deposits and stakes.\\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\\n * stake is value locked for at least \\\"unstakeDelay\\\" by the staked entity.\\n */\\ninterface IStakeManager {\\n event Deposited(address indexed account, uint256 totalDeposit);\\n\\n event Withdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /// Emitted when stake or unstake delay are modified\\n event StakeLocked(\\n address indexed account,\\n uint256 totalStaked,\\n uint256 unstakeDelaySec\\n );\\n\\n /// Emitted once a stake is scheduled for withdrawal\\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\\n\\n event StakeWithdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /**\\n * @param deposit the entity's deposit\\n * @param staked true if this entity is staked.\\n * @param stake actual amount of ether staked for this entity.\\n * @param unstakeDelaySec minimum delay to withdraw the stake.\\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\\n * and the rest fit into a 2nd cell.\\n * 112 bit allows for 10^15 eth\\n * 48 bit for full timestamp\\n * 32 bit allows 150 years for unstake delay\\n */\\n struct DepositInfo {\\n uint112 deposit;\\n bool staked;\\n uint112 stake;\\n uint32 unstakeDelaySec;\\n uint48 withdrawTime;\\n }\\n\\n //API struct used by getStakeInfo and simulateValidation\\n struct StakeInfo {\\n uint256 stake;\\n uint256 unstakeDelaySec;\\n }\\n\\n /// @return info - full deposit information of given account\\n function getDepositInfo(\\n address account\\n ) external view returns (DepositInfo memory info);\\n\\n /// @return the deposit (for gas payment) of the account\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * add to the deposit of the given account\\n */\\n function depositTo(address account) external payable;\\n\\n /**\\n * add to the account's stake - amount and delay\\n * any pending unstake is first cancelled.\\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\\n */\\n function addStake(uint32 _unstakeDelaySec) external payable;\\n\\n /**\\n * attempt to unlock the stake.\\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\\n */\\n function unlockStake() external;\\n\\n /**\\n * withdraw from the (unlocked) stake.\\n * must first call unlockStake and wait for the unstakeDelay to pass\\n * @param withdrawAddress the address to send withdrawn value.\\n */\\n function withdrawStake(address payable withdrawAddress) external;\\n\\n /**\\n * withdraw from the deposit.\\n * @param withdrawAddress the address to send withdrawn value.\\n * @param withdrawAmount the amount to withdraw.\\n */\\n function withdrawTo(\\n address payable withdrawAddress,\\n uint256 withdrawAmount\\n ) external;\\n}\\n\",\"keccak256\":\"0xadcea606c9b7aafe6645441f2154a60f271330b0eee5292a632aa71c1672d546\",\"license\":\"GPL-3.0-only\"},\"contracts/aa-4337/interfaces/UserOperation.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable no-inline-assembly */\\n\\nimport {calldataKeccak} from \\\"../core/Helpers.sol\\\";\\n\\n/**\\n * User Operation struct\\n * @param sender the sender account of this request.\\n * @param nonce unique value the sender uses to verify it is not a replay.\\n * @param initCode if set, the account contract will be created by this constructor/\\n * @param callData the method call to execute on this account.\\n * @param callGasLimit the gas limit passed to the callData method call.\\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\\n * @param maxFeePerGas same as EIP-1559 gas parameter.\\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\\n */\\nstruct UserOperation {\\n address sender;\\n uint256 nonce;\\n bytes initCode;\\n bytes callData;\\n uint256 callGasLimit;\\n uint256 verificationGasLimit;\\n uint256 preVerificationGas;\\n uint256 maxFeePerGas;\\n uint256 maxPriorityFeePerGas;\\n bytes paymasterAndData;\\n bytes signature;\\n}\\n\\n/**\\n * Utility functions helpful when working with UserOperation structs.\\n */\\nlibrary UserOperationLib {\\n function getSender(\\n UserOperation calldata userOp\\n ) internal pure returns (address) {\\n address data;\\n //read sender from userOp, which is first userOp member (saves 800 gas...)\\n assembly {\\n data := calldataload(userOp)\\n }\\n return address(uint160(data));\\n }\\n\\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\\n // pay above what he signed for.\\n function gasPrice(\\n UserOperation calldata userOp\\n ) internal view returns (uint256) {\\n unchecked {\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n if (maxFeePerGas == maxPriorityFeePerGas) {\\n //legacy mode (for networks that don't support basefee opcode)\\n return maxFeePerGas;\\n }\\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\\n }\\n }\\n\\n function pack(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes memory ret) {\\n address sender = getSender(userOp);\\n uint256 nonce = userOp.nonce;\\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\\n bytes32 hashCallData = calldataKeccak(userOp.callData);\\n uint256 callGasLimit = userOp.callGasLimit;\\n uint256 verificationGasLimit = userOp.verificationGasLimit;\\n uint256 preVerificationGas = userOp.preVerificationGas;\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\\n\\n return\\n abi.encode(\\n sender,\\n nonce,\\n hashInitCode,\\n hashCallData,\\n callGasLimit,\\n verificationGasLimit,\\n preVerificationGas,\\n maxFeePerGas,\\n maxPriorityFeePerGas,\\n hashPaymasterAndData\\n );\\n }\\n\\n function hash(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes32) {\\n return keccak256(pack(userOp));\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n}\\n\",\"keccak256\":\"0x2429f5cc546bdee08c7e63858d0dda8491eaa3ab5194df884dc948c1154d2834\",\"license\":\"GPL-3.0\"},\"contracts/facets/AccountFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {ECDSA} from \\\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\\\";\\nimport {UserOperation} from \\\"../aa-4337/interfaces/UserOperation.sol\\\";\\nimport {IEntryPoint} from \\\"../aa-4337/interfaces/IEntryPoint.sol\\\";\\nimport {BaseAccount} from \\\"../aa-4337/core/BaseAccount.sol\\\";\\nimport {LibAppStorage, BarzStorage} from \\\"../libraries/LibAppStorage.sol\\\";\\nimport {LibDiamond} from \\\"../libraries/LibDiamond.sol\\\";\\nimport {LibLoupe} from \\\"../libraries/LibLoupe.sol\\\";\\nimport {IFacetRegistry} from \\\"../infrastructure/interfaces/IFacetRegistry.sol\\\";\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\nimport {IVerificationFacet} from \\\"./interfaces/IVerificationFacet.sol\\\";\\nimport {IERC1271} from \\\"../interfaces/ERC/IERC1271.sol\\\";\\nimport {IAccountFacet} from \\\"./interfaces/IAccountFacet.sol\\\";\\n\\n/**\\n * @title Account Facet\\n * @dev Account module contract that provides the account features and initialization of signer\\n * compatible with EIP-1271 & EIP-4337\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract AccountFacet is IAccountFacet, BarzStorage, BaseAccount {\\n using ECDSA for bytes32;\\n\\n /**\\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\\n */\\n constructor() {\\n LibAppStorage.enforceAccountInitialize();\\n }\\n\\n /**\\n * @notice Returns the address of EntryPoint contract registered to Barz account\\n */\\n function entryPoint() public view override returns (IEntryPoint) {\\n return s.entryPoint;\\n }\\n\\n /**\\n * @notice Initializes the initial storage of the Barz contract.\\n * @dev This method can only be called during the initialization or signature migration.\\n * If the proxy contract was created without initialization, anyone can call initialize.\\n * Barz calls initialize in constructor in an atomic transaction during deployment\\n * @param _verificationFacet Facet contract handling the verificationi\\n * @param _anEntryPoint Entrypoint contract defined in EIP-4337 handling the flow of UserOp\\n * @param _facetRegistry Registry of Facets that hold all facet information\\n * @param _defaultFallBackHandler Middleware contract for default facets\\n * @param _ownerPublicKey Bytes of owner public key\\n */\\n function initialize(\\n address _verificationFacet,\\n address _anEntryPoint,\\n address _facetRegistry,\\n address _defaultFallBackHandler,\\n bytes calldata _ownerPublicKey\\n ) public override returns (uint256 initSuccess) {\\n LibAppStorage.enforceAccountInitialize();\\n s.entryPoint = IEntryPoint(_anEntryPoint);\\n s.facetRegistry = IFacetRegistry(_facetRegistry);\\n LibDiamond.diamondStorage().defaultFallbackHandler = IDiamondLoupe(\\n _defaultFallBackHandler\\n );\\n\\n _cutDiamondAccountFacet(_verificationFacet);\\n\\n bytes memory initCall = abi.encodeWithSignature(\\n \\\"initializeSigner(bytes)\\\",\\n _ownerPublicKey\\n );\\n // Every Verification Facet should comply with initializeSigner(bytes)\\n // to be compatible with the Barz contract(for initialization)\\n (bool success, bytes memory result) = _verificationFacet.delegatecall(\\n initCall\\n );\\n if (!success || uint256(bytes32(result)) != 1) {\\n revert AccountFacet__InitializationFailure();\\n }\\n\\n initSuccess = 1;\\n emit AccountInitialized(s.entryPoint, _ownerPublicKey);\\n }\\n\\n function _cutDiamondAccountFacet(address _verificationFacet) internal {\\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](1);\\n\\n bytes4 ownerVerificationFuncSelector = IVerificationFacet(\\n _verificationFacet\\n ).validateOwnerSignatureSelector();\\n\\n bytes4[] memory verificationFunctionSelectors = new bytes4[](3);\\n verificationFunctionSelectors[0] = IERC1271.isValidSignature.selector;\\n verificationFunctionSelectors[1] = ownerVerificationFuncSelector;\\n verificationFunctionSelectors[2] = IVerificationFacet.owner.selector;\\n cut[0] = IDiamondCut.FacetCut({\\n facetAddress: _verificationFacet,\\n action: IDiamondCut.FacetCutAction.Add,\\n functionSelectors: verificationFunctionSelectors\\n });\\n\\n LibDiamond.diamondCut(cut, address(0), \\\"\\\");\\n }\\n\\n /**\\n * @notice Calls the destination with inputted calldata and value from EntryPoint\\n * @dev This method executes the calldata coming from the EntryPoint.\\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\\n * @param _dest Address of destination where the call will be forwarded to\\n * @param _value Amount of native coin the owner is willing to send(e.g. ETH, BNB)\\n * @param _func Bytes of calldata to execute in the destination address\\n */\\n function execute(\\n address _dest,\\n uint256 _value,\\n bytes calldata _func\\n ) external override onlyWhenUnlocked {\\n _requireFromEntryPoint();\\n address restrictionsFacet = LibDiamond.restrictionsFacet();\\n if (restrictionsFacet == address(0)) _call(_dest, _value, _func);\\n else _callWithRestrictions(_dest, _value, _func, restrictionsFacet);\\n }\\n\\n /**\\n * @notice Batch calls the destination with inputted calldata and value from EntryPoint\\n * @dev This method batch executes the calldata coming from the EntryPoint.\\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\\n * @param _dest Array of addresses of destination where the call will be forwarded to\\n * @param _value Array of amount of native coin the owner is willing to send(e.g. ETH, BNB)\\n * @param _func Array of bytes of calldata to execute in the destination address\\n */\\n function executeBatch(\\n address[] calldata _dest,\\n uint256[] calldata _value,\\n bytes[] calldata _func\\n ) external override onlyWhenUnlocked {\\n _requireFromEntryPoint();\\n if (_dest.length != _func.length || _dest.length != _value.length)\\n revert AccountFacet__InvalidArrayLength();\\n address restrictionsFacet = LibDiamond.restrictionsFacet();\\n if (restrictionsFacet == address(0)) {\\n for (uint256 i; i < _dest.length; ) {\\n _call(_dest[i], _value[i], _func[i]);\\n unchecked {\\n ++i;\\n }\\n }\\n } else {\\n for (uint256 i; i < _dest.length; ) {\\n _callWithRestrictions(\\n _dest[i],\\n _value[i],\\n _func[i],\\n restrictionsFacet\\n );\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n }\\n\\n /**\\n * @notice Validates the signature field of UserOperation\\n * @dev This method validates if the signature of UserOp is indeed valid by delegating the call to Verification Facet\\n * Barz makes a call to the pre-registered Verification Facet address in App Storage\\n * @param _userOp UserOperation from owner to be validated\\n * @param _userOpHash Hash of UserOperation given from the EntryPoint contract\\n */\\n function _validateSignature(\\n UserOperation calldata _userOp,\\n bytes32 _userOpHash\\n ) internal override returns (uint256 validationData) {\\n // Get Facet with Function Selector\\n address facet = LibLoupe.facetAddress(s.validateOwnerSignatureSelector);\\n if (facet == address(0))\\n revert AccountFacet__NonExistentVerificationFacet();\\n\\n // Make function call to VerificationFacet\\n bytes memory validateCall = abi.encodeWithSelector(\\n s.validateOwnerSignatureSelector,\\n _userOp,\\n _userOpHash\\n );\\n (bool success, bytes memory result) = facet.delegatecall(validateCall);\\n if (!success) revert AccountFacet__CallNotSuccessful();\\n validationData = uint256(bytes32(result));\\n if (validationData == 0) emit VerificationSuccess(_userOpHash);\\n else emit VerificationFailure(_userOpHash);\\n }\\n\\n /**\\n * @notice Calls the target with the inputted value and calldata\\n * @dev This method is the actual function in Barz that makes a call with an arbitrary owner-given data\\n * @param _target Address of the destination contract which the call is getting forwarded to\\n * @param _value Amount of Native coin the owner is wanting to make in this call\\n * @param _data Calldata the owner is forwarding together in the call e.g. Swap/Token Transfer\\n */\\n function _call(\\n address _target,\\n uint256 _value,\\n bytes memory _data\\n ) internal {\\n (bool success, bytes memory result) = _target.call{value: _value}(\\n _data\\n );\\n if (!success) {\\n assembly {\\n revert(add(result, 32), mload(result))\\n }\\n }\\n }\\n\\n /**\\n * @notice Calls the target with the inputted value and calldata together with restrictions check\\n * @dev This method is the actual function in Barz that makes a call with an arbitrary owner-given data\\n * @param _target Address of the destination contract which the call is getting forwarded to\\n * @param _value Amount of Native coin the owner is wanting to make in this call\\n * @param _data Calldata the owner is forwarding together in the call e.g. Swap/Token Transfer\\n * @param _restrictionsFacet Address of Facet to validate restrictions\\n */\\n function _callWithRestrictions(\\n address _target,\\n uint256 _value,\\n bytes memory _data,\\n address _restrictionsFacet\\n ) internal {\\n // NOTE: No restrictions facet, so restriction validation passes\\n if (_checkRestrictions(_restrictionsFacet, _target, _value, _data) != 0)\\n revert AccountFacet__RestrictionsFailure();\\n\\n (bool success, bytes memory result) = _target.call{value: _value}(\\n _data\\n );\\n if (!success) {\\n assembly {\\n revert(add(result, 32), mload(result))\\n }\\n }\\n }\\n\\n /**\\n * @notice Checks restrictions if the restrictions facet exists\\n * @dev This method checks if the restrictions facet exists and makes a verification call to an array of restrictions facet\\n * @param _facet Address that holds the restrictions logic\\n * @param _target Address the call is getting forwarded to\\n * @param _value Amount of native coin the call is sending together with the call\\n * @param _data Calldata to trigger execution in target address\\n */\\n function _checkRestrictions(\\n address _facet,\\n address _target,\\n uint256 _value,\\n bytes memory _data\\n ) internal returns (uint256 result) {\\n bytes memory call = abi.encodeWithSignature(\\n \\\"verifyRestrictions(address,address,uint256,bytes)\\\",\\n address(this),\\n _target,\\n _value,\\n _data\\n );\\n (bool success, bytes memory response) = _facet.delegatecall(call);\\n if (!success) revert AccountFacet__RestrictionsFailure();\\n result = uint256(bytes32(response));\\n }\\n}\\n\",\"keccak256\":\"0xcd92bcdd447010880f78e57e213123269c9e023adfc0a540608daa127d8649ca\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/facets/interfaces/IAccountFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IEntryPoint} from \\\"../../aa-4337/interfaces/IEntryPoint.sol\\\";\\n\\n/**\\n * @title Account Facet Interface\\n * @dev Interface of module contract that provides the account features and init/unitialization of signer\\n * compatible with EIP-1271 & EIP-4337\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IAccountFacet {\\n event AccountInitialized(\\n IEntryPoint indexed entryPoint,\\n bytes indexed ownerPublicKey\\n );\\n // NOTE: Added Below Event\\n event VerificationSuccess(bytes32);\\n event VerificationFailure(bytes32);\\n\\n error AccountFacet__InitializationFailure();\\n error AccountFacet__RestrictionsFailure();\\n error AccountFacet__NonExistentVerificationFacet();\\n error AccountFacet__CallNotSuccessful();\\n error AccountFacet__InvalidArrayLength();\\n\\n function initialize(\\n address verificationFacet,\\n address anEntryPoint,\\n address facetRegistry,\\n address _defaultFallBack,\\n bytes calldata _ownerPublicKey\\n ) external returns (uint256);\\n\\n function execute(address dest, uint256 value, bytes calldata func) external;\\n\\n function executeBatch(\\n address[] calldata dest,\\n uint256[] calldata value,\\n bytes[] calldata func\\n ) external;\\n}\\n\",\"keccak256\":\"0x74a9cb0b8f2f4a5148e366a401a0354426c536c012c025025d07cc25a4cd5382\",\"license\":\"Apache-2.0\"},\"contracts/facets/interfaces/IVerificationFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {UserOperation} from \\\"../../aa-4337/interfaces/UserOperation.sol\\\";\\n\\n/**\\n * @title Verification Facet Interface\\n * @dev Implements logic for user ops signature verification\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\ninterface IVerificationFacet {\\n event SignerInitialized(bytes);\\n event SignerUninitialized();\\n\\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\\n error VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\\n error VerificationFacet__InitializationFailure();\\n error VerificationFacet__InvalidFacetMapping();\\n\\n function initializeSigner(bytes memory) external returns (uint256);\\n\\n function uninitializeSigner() external returns (uint256);\\n\\n function validateOwnerSignatureSelector() external view returns (bytes4);\\n\\n function owner() external view returns (bytes memory);\\n\\n function isValidKeyType(bytes calldata) external view returns (bool);\\n\\n function validateOwnerSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x72bc370a1d1b5a6d6bde67f5026733fd8f6ba434bb90e73b0bd8627fb1579928\",\"license\":\"Apache-2.0\"},\"contracts/infrastructure/interfaces/IFacetRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Registry Interface\\n * @dev Interface for Facet Registry contract to keep track of facets & function selectors addable to user wallets\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IFacetRegistry {\\n struct FacetRegistryConfig {\\n bytes4[] selectors;\\n mapping(bytes4 => FacetInfo) info;\\n }\\n struct FacetInfo {\\n bool exists;\\n uint128 index;\\n }\\n\\n event FacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] facetSelectors\\n );\\n event FacetFunctionSelectorsRemoved(address facet, bytes4[] facetSelectors);\\n\\n error FacetRegistry__FacetSelectorAlreadyRegistered();\\n error FacetRegistry__UnregisteredFacetSelector();\\n\\n function registerFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function removeFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function areFacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external view returns (bool);\\n\\n function isFacetFunctionSelectorRegistered(\\n address facet,\\n bytes4 facetSelector\\n ) external view returns (bool);\\n\\n function getFacetFunctionSelectors(\\n address facet\\n ) external view returns (bytes4[] memory);\\n}\\n\",\"keccak256\":\"0x6e6dd2cab346ef7c31230740ec48d2925e4a9ab24c2f2fb268baaf408dcf02ef\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC1271 {\\n function isValidSignature(\\n bytes32 hash,\\n bytes memory signature\\n ) external view returns (bytes4);\\n}\\n\",\"keccak256\":\"0xcdddb7d5641c9d3f2432dec7fd13fddb9ae1480f25c76c21511e2fa16b8bd422\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibAppStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {SafeCast} from \\\"@openzeppelin/contracts/utils/math/SafeCast.sol\\\";\\nimport {IEntryPoint} from \\\"../aa-4337/interfaces/IEntryPoint.sol\\\";\\nimport {IFacetRegistry} from \\\"../infrastructure/interfaces/IFacetRegistry.sol\\\";\\n\\n/*\\n * @title App Storage\\n * @dev App storage for Barz contract to prevent storage collision\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Lock {\\n uint64 release;\\n bytes4 locker;\\n}\\n\\nstruct InitializersStorage {\\n // NOTE: initialized is a variable to make sure the initialization is only done once.\\n uint8 signerInitialized;\\n uint8 accountInitialized;\\n uint8 restrictionsInitialized;\\n}\\n\\nstruct AppStorage {\\n mapping(uint256 => InitializersStorage) initStorage;\\n uint8 signerMigration;\\n bytes4 validateOwnerSignatureSelector;\\n IEntryPoint entryPoint;\\n IFacetRegistry facetRegistry;\\n mapping(uint256 => Lock) locks;\\n}\\n\\nlibrary LibAppStorage {\\n error LibAppStorage__AccountAlreadyUninitialized();\\n error LibAppStorage__AccountMustBeUninitialized();\\n error LibAppStorage__SignerAlreadyUninitialized();\\n error LibAppStorage__SignerMustBeUninitialized();\\n\\n function appStorage() internal pure returns (AppStorage storage ds) {\\n assembly {\\n ds.slot := 0\\n }\\n }\\n\\n function setSignerUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerAlreadyUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 0;\\n }\\n\\n function getValidateOwnerSignatureSelector()\\n internal\\n view\\n returns (bytes4 selector)\\n {\\n selector = appStorage().validateOwnerSignatureSelector;\\n }\\n\\n function setValidateOwnerSignatureSelector(\\n bytes4 _validateOwnerSignatureSelector\\n ) internal {\\n appStorage()\\n .validateOwnerSignatureSelector = _validateOwnerSignatureSelector;\\n }\\n\\n function enforceSignerInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerMustBeUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 1;\\n }\\n\\n function enforceAccountInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].accountInitialized) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n s.initStorage[0].accountInitialized = 1;\\n }\\n\\n function initiateSignerMigration() internal {\\n appStorage().signerMigration = 1;\\n }\\n\\n function enforceSignerMigration() internal view {\\n if (1 != appStorage().signerMigration) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n }\\n\\n function finalizeSignerMigration() internal {\\n appStorage().signerMigration = 0;\\n }\\n\\n function setLock(uint256 _releaseAfter, bytes4 _locker) internal {\\n appStorage().locks[0] = Lock(SafeCast.toUint64(_releaseAfter), _locker);\\n }\\n\\n function enforceRestrictionsInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__SignerMustBeUninitialized();\\n s.initStorage[0].restrictionsInitialized = 1;\\n }\\n\\n function setRestrictionsUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__AccountAlreadyUninitialized();\\n s.initStorage[0].restrictionsInitialized = 0;\\n }\\n}\\n\\ncontract BarzStorage {\\n AppStorage internal s;\\n modifier onlyWhenUnlocked() {\\n require(\\n uint64(block.timestamp) >= s.locks[0].release,\\n \\\"Account Locked\\\"\\n );\\n _;\\n }\\n modifier onlyWhenLocked() {\\n require(\\n uint64(block.timestamp) < s.locks[0].release,\\n \\\"Account Unlocked\\\"\\n );\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x48524007862a6ce0e07f645950613ce6513ce073c37a109c75019683d42bae27\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\\n bytes4(keccak256(\\\"verifyRestrictions(address,address,uint256,bytes)\\\"));\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // Default Fallback Handler of the barz.\\n IDiamondLoupe defaultFallbackHandler;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function enforceIsSelf() internal view {\\n require(msg.sender == address(this), \\\"LibDiamond: Caller not self\\\");\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n\\n unchecked {\\n facetIndex++;\\n }\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n\\n function restrictionsFacet() internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(\\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2cabdc00de859c3a3170ce3bda5d0e5fd3933d47ce904fd1585f9818b02572f8\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\nimport {LibDiamond} from \\\"./LibDiamond.sol\\\";\\n\\n/**\\n * @title LibLoupe\\n * @dev Internal Library to provide utility feature for reading the state of diamond facets\\n * Originally from Diamond's implementation of Mudgen(author of EIP-2535)\\n */\\nlibrary LibLoupe {\\n /// @notice Gets all facets and their selectors.\\n /// @return facets_ Facet\\n function facets()\\n internal\\n view\\n returns (IDiamondLoupe.Facet[] memory facets_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facets_ = new IDiamondLoupe.Facet[](ds.selectorCount);\\n uint16[] memory numFacetSelectors = new uint16[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facets_[facetIndex].facetAddress == facetAddress_) {\\n facets_[facetIndex].functionSelectors[\\n numFacetSelectors[facetIndex]\\n ] = selector;\\n // probably will never have more than 256 functions from one facet contract\\n require(numFacetSelectors[facetIndex] < 255);\\n numFacetSelectors[facetIndex]++;\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facets_[numFacets].facetAddress = facetAddress_;\\n facets_[numFacets].functionSelectors = new bytes4[](\\n ds.selectorCount\\n );\\n facets_[numFacets].functionSelectors[0] = selector;\\n numFacetSelectors[numFacets] = 1;\\n numFacets++;\\n }\\n }\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n uint256 numSelectors = numFacetSelectors[facetIndex];\\n bytes4[] memory selectors = facets_[facetIndex].functionSelectors;\\n // setting the number of selectors\\n assembly {\\n mstore(selectors, numSelectors)\\n }\\n }\\n // setting the number of facets\\n assembly {\\n mstore(facets_, numFacets)\\n }\\n }\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return _facetFunctionSelectors The selectors associated with a facet address.\\n function facetFunctionSelectors(\\n address _facet\\n ) internal view returns (bytes4[] memory _facetFunctionSelectors) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n uint256 numSelectors;\\n _facetFunctionSelectors = new bytes4[](ds.selectorCount);\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facet = address(bytes20(ds.facets[selector]));\\n if (_facet == facet) {\\n _facetFunctionSelectors[numSelectors] = selector;\\n numSelectors++;\\n }\\n }\\n }\\n // Set the number of selectors in the array\\n assembly {\\n mstore(_facetFunctionSelectors, numSelectors)\\n }\\n }\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n internal\\n view\\n returns (address[] memory facetAddresses_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetAddresses_ = new address[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facetAddress_ == facetAddresses_[facetIndex]) {\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facetAddresses_[numFacets] = facetAddress_;\\n numFacets++;\\n }\\n }\\n // Set the number of facet addresses in the array\\n assembly {\\n mstore(facetAddresses_, numFacets)\\n }\\n }\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(LibDiamond.diamondStorage().facets[_functionSelector])\\n );\\n }\\n}\\n\",\"keccak256\":\"0x0b11439c3cc657095e15ec2241fdcf67204b14001357b612fc5db4ff9e760a5a\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5061001961001e565b61008e565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb554610100900460ff1615610070576040516338fc28cb60e01b815260040160405180910390fd5b600080805260209190915260409020805461ff001916610100179055565b6129b6806200009e6000396000f3fe608060405234801561001057600080fd5b50600436106100725760003560e01c8063b0d691fe11610050578063b0d691fe146100c5578063b61d27f61461010c578063d087d2881461011f57600080fd5b80633a871cdd1461007757806347e1da2a1461009d5780634a936417146100b2575b600080fd5b61008a610085366004611fb5565b610127565b6040519081526020015b60405180910390f35b6100b06100ab366004612055565b61014d565b005b61008a6100c036600461215a565b610450565b60015465010000000000900473ffffffffffffffffffffffffffffffffffffffff1660405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610094565b6100b061011a3660046121ce565b6106d0565b61008a61089d565b600061013161095e565b61013b8484610a16565b905061014682610c5d565b9392505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff9081164290911610156101f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064015b60405180910390fd5b6101fd61095e565b848114158061020c5750848314155b15610243576040517fdde5716100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006102b87fac87185d000000000000000000000000000000000000000000000000000000006000527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020527f6d9f2463c8c0d8cb8be556a773ab21d4321328909a1725f2ef7cae0c320e95da5460601c90565b905073ffffffffffffffffffffffffffffffffffffffff811661038f5760005b86811015610389576103818888838181106102f5576102f5612228565b905060200201602081019061030a9190612257565b87878481811061031c5761031c612228565b9050602002013586868581811061033557610335612228565b90506020028101906103479190612272565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610cc892505050565b6001016102d8565b50610447565b60005b868110156104455761043d8888838181106103af576103af612228565b90506020020160208101906103c49190612257565b8787848181106103d6576103d6612228565b905060200201358686858181106103ef576103ef612228565b90506020028101906104019190612272565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250889250610d45915050565b600101610392565b505b50505050505050565b600061045a610e0d565b6001805473ffffffffffffffffffffffffffffffffffffffff88811665010000000000027fffffffffffffff0000000000000000000000000000000000000000ffffffffff90921691909117909155600280548783167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216179091557f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd492380549287169290911691909117905561051187610eb3565b60008383604051602401610526929190612320565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fcd9b47e40000000000000000000000000000000000000000000000000000000017905251909150600090819073ffffffffffffffffffffffffffffffffffffffff8b16906105c8908590612360565b600060405180830381855af49150503d8060008114610603576040519150601f19603f3d011682016040523d82523d6000602084013e610608565b606091505b5091509150811580610623575061061e8161237c565b600114155b1561065a576040517f1602372100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60019350858560405161066e9291906123c1565b60405190819003812060015490916501000000000090910473ffffffffffffffffffffffffffffffffffffffff16907fd429ff0b972be4ae725700a373d05007287994e4c86cb83315b43ffa85b595fd90600090a35050509695505050505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610773576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064016101ec565b61077b61095e565b60006107f07fac87185d000000000000000000000000000000000000000000000000000000006000527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020527f6d9f2463c8c0d8cb8be556a773ab21d4321328909a1725f2ef7cae0c320e95da5460601c90565b905073ffffffffffffffffffffffffffffffffffffffff81166108535761084e858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610cc892505050565b610896565b610896858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250879250610d45915050565b5050505050565b60015460009065010000000000900473ffffffffffffffffffffffffffffffffffffffff166040517f35567e1a0000000000000000000000000000000000000000000000000000000081523060048201526000602482015273ffffffffffffffffffffffffffffffffffffffff91909116906335567e1a90604401602060405180830381865afa158015610935573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061095991906123d1565b905090565b60015465010000000000900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a14576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f6163636f756e743a206e6f742066726f6d20456e747279506f696e740000000060448201526064016101ec565b565b600154610100900460e01b7fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604081205460601c80610aab576040517f6eb2360200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600154604051600091610100900460e01b90610acd908790879060240161244e565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090506000808373ffffffffffffffffffffffffffffffffffffffff1683604051610b549190612360565b600060405180830381855af49150503d8060008114610b8f576040519150601f19603f3d011682016040523d82523d6000602084013e610b94565b606091505b509150915081610bd0576040517f3cbbb65000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610bd98161237c565b94506000859003610c1c576040518681527f19e781916118c373dadcb7776fae0a2dbb6bbdeedae143ce68031e22801ef8659060200160405180910390a1610c50565b6040518681527fbbfee2df7f28b899771f1015dc85d7840ff9f6162f23f6aa99686e8fbd2ce1319060200160405180910390a15b5050505092915050565b50565b8015610c5a5760405160009033907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90849084818181858888f193505050503d8060008114610896576040519150601f19603f3d011682016040523d82523d6000602084013e610896565b6000808473ffffffffffffffffffffffffffffffffffffffff168484604051610cf19190612360565b60006040518083038185875af1925050503d8060008114610d2e576040519150601f19603f3d011682016040523d82523d6000602084013e610d33565b606091505b50915091508161089657805160208201fd5b610d5181858585611117565b15610d88576040517f01f595e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000808573ffffffffffffffffffffffffffffffffffffffff168585604051610db19190612360565b60006040518083038185875af1925050503d8060008114610dee576040519150601f19603f3d011682016040523d82523d6000602084013e610df3565b606091505b509150915081610e0557805160208201fd5b505050505050565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb554610100900460ff1615610e78576040517f38fc28cb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100179055565b604080516001808252818301909252600091816020015b60408051606080820183526000808352602083015291810191909152815260200190600190039081610eca57905050905060008273ffffffffffffffffffffffffffffffffffffffff16633253960f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f6c9190612592565b604080516003808252608082019092529192506000919060208201606080368337019050509050631626ba7e60e01b81600081518110610fae57610fae612228565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681525050818160018151811061100e5761100e612228565b7fffffffff000000000000000000000000000000000000000000000000000000009092166020928302919091019091015280517f8da5cb5b00000000000000000000000000000000000000000000000000000000908290600290811061107657611076612228565b7fffffffff00000000000000000000000000000000000000000000000000000000909216602092830291909101820152604080516060810190915273ffffffffffffffffffffffffffffffffffffffff861681529081016000815260200182815250836000815181106110eb576110eb612228565b602002602001018190525061111183600060405180602001604052806000815250611264565b50505050565b60008030858585604051602401611131949392919061264d565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fac87185d0000000000000000000000000000000000000000000000000000000017905251909150600090819073ffffffffffffffffffffffffffffffffffffffff8916906111d3908590612360565b600060405180830381855af49150503d806000811461120e576040519150601f19603f3d011682016040523d82523d6000602084013e611213565b606091505b50915091508161124f576040517f01f595e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6112588161237c565b98975050505050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921547f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff8116908190600090600716156112d35750600381901c60009081526001840160205260409020545b60005b87518110156113505761134383838a84815181106112f6576112f6612228565b6020026020010151600001518b858151811061131457611314612228565b6020026020010151602001518c868151811061133257611332612228565b6020026020010151604001516113f0565b90935091506001016112d6565b50828214611389576002840180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff84161790555b60078216156113ab57600382901c600090815260018501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb6738787876040516113de93929190612696565b60405180910390a16104478686611e81565b600080807f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f905060008451116114a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f2063757400000000000000000000000000000000000000000060648201526084016101ec565b60008560028111156114bc576114bc6125d4565b0361168c576114e38660405180606001604052806024815260200161290d60249139611f7a565b60005b845181101561168657600085828151811061150357611503612228565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c156115d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c726561647920657869737473000000000000000000000060648201526084016101ec565b7fffffffff0000000000000000000000000000000000000000000000000000000080831660008181526020879052604090207fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608d901b168e17905560e060058e901b811692831c199c909c1690821c179a81900361166a5760038c901c600090815260018601602052604081209b909b555b8b6116748161282d565b9c5050600190930192506114e6915050565b50611e75565b60018560028111156116a0576116a06125d4565b03611990576116c78660405180606001604052806028815260200161295960289139611f7a565b60005b84518110156116865760008582815181106116e7576116e7612228565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c3081036117bc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4c69624469616d6f6e644375743a2043616e2774207265706c61636520696d6d60448201527f757461626c652066756e6374696f6e000000000000000000000000000000000060648201526084016101ec565b8973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611877576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e000000000000000060648201526084016101ec565b73ffffffffffffffffffffffffffffffffffffffff811661191a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e207468617420646f65736e2774206578697374000000000000000060648201526084016101ec565b507fffffffff0000000000000000000000000000000000000000000000000000000090911660009081526020849052604090206bffffffffffffffffffffffff919091167fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608a901b161790556001016116ca565b60028560028111156119a4576119a46125d4565b03611ded5773ffffffffffffffffffffffffffffffffffffffff861615611a4d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d75737420626520616464726573732830290000000000000000000060648201526084016101ec565b600388901c6007891660005b8651811015611dcd5760008a9003611a955782611a7581612865565b60008181526001870160205260409020549b50935060079250611aa39050565b81611a9f81612865565b9250505b6000806000808a8581518110611abb57611abb612228565b6020908102919091018101517fffffffff0000000000000000000000000000000000000000000000000000000081166000908152918a9052604090912054909150606081901c611b8d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e277420657869737400000000000000000060648201526084016101ec565b30606082901c03611c20576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e00000000000000000000000000000000000060648201526084016101ec565b600587901b8f901b94507fffffffff0000000000000000000000000000000000000000000000000000000080861690831614611cbe577fffffffff000000000000000000000000000000000000000000000000000000008516600090815260208a90526040902080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff83161790555b7fffffffff0000000000000000000000000000000000000000000000000000000091909116600090815260208990526040812055600381901c611fff16925060051b60e0169050858214611d53576000828152600188016020526040902080547fffffffff0000000000000000000000000000000000000000000000000000000080841c19909116908516831c179055611da4565b80837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c817fffffffff0000000000000000000000000000000000000000000000000000000060001b901c198e16179c505b84600003611dc257600086815260018801602052604081208190559c505b505050600101611a59565b5080611dda83600861289a565b611de491906128b7565b99505050611e75565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560448201527f74416374696f6e0000000000000000000000000000000000000000000000000060648201526084016101ec565b50959694955050505050565b73ffffffffffffffffffffffffffffffffffffffff8216611ea0575050565b611ec28260405180606001604052806028815260200161293160289139611f7a565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051611eea9190612360565b600060405180830381855af49150503d8060008114611f25576040519150601f19603f3d011682016040523d82523d6000602084013e611f2a565b606091505b50915091508161111157805115611f445780518082602001fd5b83836040517f192105d70000000000000000000000000000000000000000000000000000000081526004016101ec9291906128ca565b813b8181611111576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101ec91906128f9565b600080600060608486031215611fca57600080fd5b833567ffffffffffffffff811115611fe157600080fd5b84016101608187031215611ff457600080fd5b95602085013595506040909401359392505050565b60008083601f84011261201b57600080fd5b50813567ffffffffffffffff81111561203357600080fd5b6020830191508360208260051b850101111561204e57600080fd5b9250929050565b6000806000806000806060878903121561206e57600080fd5b863567ffffffffffffffff8082111561208657600080fd5b6120928a838b01612009565b909850965060208901359150808211156120ab57600080fd5b6120b78a838b01612009565b909650945060408901359150808211156120d057600080fd5b506120dd89828a01612009565b979a9699509497509295939492505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461211357600080fd5b919050565b60008083601f84011261212a57600080fd5b50813567ffffffffffffffff81111561214257600080fd5b60208301915083602082850101111561204e57600080fd5b60008060008060008060a0878903121561217357600080fd5b61217c876120ef565b955061218a602088016120ef565b9450612198604088016120ef565b93506121a6606088016120ef565b9250608087013567ffffffffffffffff8111156121c257600080fd5b6120dd89828a01612118565b600080600080606085870312156121e457600080fd5b6121ed856120ef565b935060208501359250604085013567ffffffffffffffff81111561221057600080fd5b61221c87828801612118565b95989497509550505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561226957600080fd5b610146826120ef565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126122a757600080fd5b83018035915067ffffffffffffffff8211156122c257600080fd5b60200191503681900382131561204e57600080fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b6020815260006123346020830184866122d7565b949350505050565b60005b8381101561235757818101518382015260200161233f565b50506000910152565b6000825161237281846020870161233c565b9190910192915050565b805160208083015191908110156123bb577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8160200360031b1b821691505b50919050565b8183823760009101908152919050565b6000602082840312156123e357600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261241f57600080fd5b830160208101925035905067ffffffffffffffff81111561243f57600080fd5b80360382131561204e57600080fd5b6040815261247c60408201612462856120ef565b73ffffffffffffffffffffffffffffffffffffffff169052565b60208301356060820152600061249560408501856123ea565b6101608060808601526124ad6101a0860183856122d7565b92506124bc60608801886123ea565b92507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0808786030160a08801526124f48585846122d7565b9450608089013560c088015260a089013560e0880152610100935060c089013584880152610120915060e089013582880152610140848a01358189015261253d838b018b6123ea565b955092508188870301848901526125558686856122d7565b9550612563818b018b6123ea565b9550935050808786030161018088015250506125808383836122d7565b93505050508260208301529392505050565b6000602082840312156125a457600080fd5b81517fffffffff000000000000000000000000000000000000000000000000000000008116811461014657600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6000815180845261261b81602086016020860161233c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600073ffffffffffffffffffffffffffffffffffffffff80871683528086166020840152508360408301526080606083015261268c6080830184612603565b9695505050505050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b848110156127c1577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808a8503018652815188850173ffffffffffffffffffffffffffffffffffffffff82511686528482015160038110612748577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b808310156127ac5783517fffffffff0000000000000000000000000000000000000000000000000000000016825292860192600192909201919086019061276a565b509785019795505050908201906001016126bf565b505073ffffffffffffffffffffffffffffffffffffffff8a169088015286810360408801526127f08189612603565b9a9950505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361285e5761285e6127fe565b5060010190565b600081612874576128746127fe565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b80820281158282048414176128b1576128b16127fe565b92915050565b808201808211156128b1576128b16127fe565b73ffffffffffffffffffffffffffffffffffffffff831681526040602082015260006123346040830184612603565b602081526000610146602083018461260356fe4c69624469616d6f6e644375743a2041646420666163657420686173206e6f20636f64654c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a205265706c61636520666163657420686173206e6f20636f6465a2646970667358221220a952f19990a20474450919a2df9ddff4430a71350892e0954f2bb073575ad64864736f6c63430008150033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100725760003560e01c8063b0d691fe11610050578063b0d691fe146100c5578063b61d27f61461010c578063d087d2881461011f57600080fd5b80633a871cdd1461007757806347e1da2a1461009d5780634a936417146100b2575b600080fd5b61008a610085366004611fb5565b610127565b6040519081526020015b60405180910390f35b6100b06100ab366004612055565b61014d565b005b61008a6100c036600461215a565b610450565b60015465010000000000900473ffffffffffffffffffffffffffffffffffffffff1660405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610094565b6100b061011a3660046121ce565b6106d0565b61008a61089d565b600061013161095e565b61013b8484610a16565b905061014682610c5d565b9392505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff9081164290911610156101f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064015b60405180910390fd5b6101fd61095e565b848114158061020c5750848314155b15610243576040517fdde5716100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006102b87fac87185d000000000000000000000000000000000000000000000000000000006000527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020527f6d9f2463c8c0d8cb8be556a773ab21d4321328909a1725f2ef7cae0c320e95da5460601c90565b905073ffffffffffffffffffffffffffffffffffffffff811661038f5760005b86811015610389576103818888838181106102f5576102f5612228565b905060200201602081019061030a9190612257565b87878481811061031c5761031c612228565b9050602002013586868581811061033557610335612228565b90506020028101906103479190612272565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610cc892505050565b6001016102d8565b50610447565b60005b868110156104455761043d8888838181106103af576103af612228565b90506020020160208101906103c49190612257565b8787848181106103d6576103d6612228565b905060200201358686858181106103ef576103ef612228565b90506020028101906104019190612272565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250889250610d45915050565b600101610392565b505b50505050505050565b600061045a610e0d565b6001805473ffffffffffffffffffffffffffffffffffffffff88811665010000000000027fffffffffffffff0000000000000000000000000000000000000000ffffffffff90921691909117909155600280548783167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216179091557f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd492380549287169290911691909117905561051187610eb3565b60008383604051602401610526929190612320565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fcd9b47e40000000000000000000000000000000000000000000000000000000017905251909150600090819073ffffffffffffffffffffffffffffffffffffffff8b16906105c8908590612360565b600060405180830381855af49150503d8060008114610603576040519150601f19603f3d011682016040523d82523d6000602084013e610608565b606091505b5091509150811580610623575061061e8161237c565b600114155b1561065a576040517f1602372100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60019350858560405161066e9291906123c1565b60405190819003812060015490916501000000000090910473ffffffffffffffffffffffffffffffffffffffff16907fd429ff0b972be4ae725700a373d05007287994e4c86cb83315b43ffa85b595fd90600090a35050509695505050505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610773576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064016101ec565b61077b61095e565b60006107f07fac87185d000000000000000000000000000000000000000000000000000000006000527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020527f6d9f2463c8c0d8cb8be556a773ab21d4321328909a1725f2ef7cae0c320e95da5460601c90565b905073ffffffffffffffffffffffffffffffffffffffff81166108535761084e858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610cc892505050565b610896565b610896858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250879250610d45915050565b5050505050565b60015460009065010000000000900473ffffffffffffffffffffffffffffffffffffffff166040517f35567e1a0000000000000000000000000000000000000000000000000000000081523060048201526000602482015273ffffffffffffffffffffffffffffffffffffffff91909116906335567e1a90604401602060405180830381865afa158015610935573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061095991906123d1565b905090565b60015465010000000000900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a14576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f6163636f756e743a206e6f742066726f6d20456e747279506f696e740000000060448201526064016101ec565b565b600154610100900460e01b7fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604081205460601c80610aab576040517f6eb2360200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600154604051600091610100900460e01b90610acd908790879060240161244e565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090506000808373ffffffffffffffffffffffffffffffffffffffff1683604051610b549190612360565b600060405180830381855af49150503d8060008114610b8f576040519150601f19603f3d011682016040523d82523d6000602084013e610b94565b606091505b509150915081610bd0576040517f3cbbb65000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610bd98161237c565b94506000859003610c1c576040518681527f19e781916118c373dadcb7776fae0a2dbb6bbdeedae143ce68031e22801ef8659060200160405180910390a1610c50565b6040518681527fbbfee2df7f28b899771f1015dc85d7840ff9f6162f23f6aa99686e8fbd2ce1319060200160405180910390a15b5050505092915050565b50565b8015610c5a5760405160009033907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90849084818181858888f193505050503d8060008114610896576040519150601f19603f3d011682016040523d82523d6000602084013e610896565b6000808473ffffffffffffffffffffffffffffffffffffffff168484604051610cf19190612360565b60006040518083038185875af1925050503d8060008114610d2e576040519150601f19603f3d011682016040523d82523d6000602084013e610d33565b606091505b50915091508161089657805160208201fd5b610d5181858585611117565b15610d88576040517f01f595e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000808573ffffffffffffffffffffffffffffffffffffffff168585604051610db19190612360565b60006040518083038185875af1925050503d8060008114610dee576040519150601f19603f3d011682016040523d82523d6000602084013e610df3565b606091505b509150915081610e0557805160208201fd5b505050505050565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb554610100900460ff1615610e78576040517f38fc28cb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100179055565b604080516001808252818301909252600091816020015b60408051606080820183526000808352602083015291810191909152815260200190600190039081610eca57905050905060008273ffffffffffffffffffffffffffffffffffffffff16633253960f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f6c9190612592565b604080516003808252608082019092529192506000919060208201606080368337019050509050631626ba7e60e01b81600081518110610fae57610fae612228565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681525050818160018151811061100e5761100e612228565b7fffffffff000000000000000000000000000000000000000000000000000000009092166020928302919091019091015280517f8da5cb5b00000000000000000000000000000000000000000000000000000000908290600290811061107657611076612228565b7fffffffff00000000000000000000000000000000000000000000000000000000909216602092830291909101820152604080516060810190915273ffffffffffffffffffffffffffffffffffffffff861681529081016000815260200182815250836000815181106110eb576110eb612228565b602002602001018190525061111183600060405180602001604052806000815250611264565b50505050565b60008030858585604051602401611131949392919061264d565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fac87185d0000000000000000000000000000000000000000000000000000000017905251909150600090819073ffffffffffffffffffffffffffffffffffffffff8916906111d3908590612360565b600060405180830381855af49150503d806000811461120e576040519150601f19603f3d011682016040523d82523d6000602084013e611213565b606091505b50915091508161124f576040517f01f595e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6112588161237c565b98975050505050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921547f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff8116908190600090600716156112d35750600381901c60009081526001840160205260409020545b60005b87518110156113505761134383838a84815181106112f6576112f6612228565b6020026020010151600001518b858151811061131457611314612228565b6020026020010151602001518c868151811061133257611332612228565b6020026020010151604001516113f0565b90935091506001016112d6565b50828214611389576002840180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff84161790555b60078216156113ab57600382901c600090815260018501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb6738787876040516113de93929190612696565b60405180910390a16104478686611e81565b600080807f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f905060008451116114a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f2063757400000000000000000000000000000000000000000060648201526084016101ec565b60008560028111156114bc576114bc6125d4565b0361168c576114e38660405180606001604052806024815260200161290d60249139611f7a565b60005b845181101561168657600085828151811061150357611503612228565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c156115d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c726561647920657869737473000000000000000000000060648201526084016101ec565b7fffffffff0000000000000000000000000000000000000000000000000000000080831660008181526020879052604090207fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608d901b168e17905560e060058e901b811692831c199c909c1690821c179a81900361166a5760038c901c600090815260018601602052604081209b909b555b8b6116748161282d565b9c5050600190930192506114e6915050565b50611e75565b60018560028111156116a0576116a06125d4565b03611990576116c78660405180606001604052806028815260200161295960289139611f7a565b60005b84518110156116865760008582815181106116e7576116e7612228565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c3081036117bc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4c69624469616d6f6e644375743a2043616e2774207265706c61636520696d6d60448201527f757461626c652066756e6374696f6e000000000000000000000000000000000060648201526084016101ec565b8973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611877576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e000000000000000060648201526084016101ec565b73ffffffffffffffffffffffffffffffffffffffff811661191a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e207468617420646f65736e2774206578697374000000000000000060648201526084016101ec565b507fffffffff0000000000000000000000000000000000000000000000000000000090911660009081526020849052604090206bffffffffffffffffffffffff919091167fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608a901b161790556001016116ca565b60028560028111156119a4576119a46125d4565b03611ded5773ffffffffffffffffffffffffffffffffffffffff861615611a4d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d75737420626520616464726573732830290000000000000000000060648201526084016101ec565b600388901c6007891660005b8651811015611dcd5760008a9003611a955782611a7581612865565b60008181526001870160205260409020549b50935060079250611aa39050565b81611a9f81612865565b9250505b6000806000808a8581518110611abb57611abb612228565b6020908102919091018101517fffffffff0000000000000000000000000000000000000000000000000000000081166000908152918a9052604090912054909150606081901c611b8d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e277420657869737400000000000000000060648201526084016101ec565b30606082901c03611c20576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e00000000000000000000000000000000000060648201526084016101ec565b600587901b8f901b94507fffffffff0000000000000000000000000000000000000000000000000000000080861690831614611cbe577fffffffff000000000000000000000000000000000000000000000000000000008516600090815260208a90526040902080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff83161790555b7fffffffff0000000000000000000000000000000000000000000000000000000091909116600090815260208990526040812055600381901c611fff16925060051b60e0169050858214611d53576000828152600188016020526040902080547fffffffff0000000000000000000000000000000000000000000000000000000080841c19909116908516831c179055611da4565b80837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c817fffffffff0000000000000000000000000000000000000000000000000000000060001b901c198e16179c505b84600003611dc257600086815260018801602052604081208190559c505b505050600101611a59565b5080611dda83600861289a565b611de491906128b7565b99505050611e75565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560448201527f74416374696f6e0000000000000000000000000000000000000000000000000060648201526084016101ec565b50959694955050505050565b73ffffffffffffffffffffffffffffffffffffffff8216611ea0575050565b611ec28260405180606001604052806028815260200161293160289139611f7a565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051611eea9190612360565b600060405180830381855af49150503d8060008114611f25576040519150601f19603f3d011682016040523d82523d6000602084013e611f2a565b606091505b50915091508161111157805115611f445780518082602001fd5b83836040517f192105d70000000000000000000000000000000000000000000000000000000081526004016101ec9291906128ca565b813b8181611111576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101ec91906128f9565b600080600060608486031215611fca57600080fd5b833567ffffffffffffffff811115611fe157600080fd5b84016101608187031215611ff457600080fd5b95602085013595506040909401359392505050565b60008083601f84011261201b57600080fd5b50813567ffffffffffffffff81111561203357600080fd5b6020830191508360208260051b850101111561204e57600080fd5b9250929050565b6000806000806000806060878903121561206e57600080fd5b863567ffffffffffffffff8082111561208657600080fd5b6120928a838b01612009565b909850965060208901359150808211156120ab57600080fd5b6120b78a838b01612009565b909650945060408901359150808211156120d057600080fd5b506120dd89828a01612009565b979a9699509497509295939492505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461211357600080fd5b919050565b60008083601f84011261212a57600080fd5b50813567ffffffffffffffff81111561214257600080fd5b60208301915083602082850101111561204e57600080fd5b60008060008060008060a0878903121561217357600080fd5b61217c876120ef565b955061218a602088016120ef565b9450612198604088016120ef565b93506121a6606088016120ef565b9250608087013567ffffffffffffffff8111156121c257600080fd5b6120dd89828a01612118565b600080600080606085870312156121e457600080fd5b6121ed856120ef565b935060208501359250604085013567ffffffffffffffff81111561221057600080fd5b61221c87828801612118565b95989497509550505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561226957600080fd5b610146826120ef565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126122a757600080fd5b83018035915067ffffffffffffffff8211156122c257600080fd5b60200191503681900382131561204e57600080fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b6020815260006123346020830184866122d7565b949350505050565b60005b8381101561235757818101518382015260200161233f565b50506000910152565b6000825161237281846020870161233c565b9190910192915050565b805160208083015191908110156123bb577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8160200360031b1b821691505b50919050565b8183823760009101908152919050565b6000602082840312156123e357600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261241f57600080fd5b830160208101925035905067ffffffffffffffff81111561243f57600080fd5b80360382131561204e57600080fd5b6040815261247c60408201612462856120ef565b73ffffffffffffffffffffffffffffffffffffffff169052565b60208301356060820152600061249560408501856123ea565b6101608060808601526124ad6101a0860183856122d7565b92506124bc60608801886123ea565b92507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0808786030160a08801526124f48585846122d7565b9450608089013560c088015260a089013560e0880152610100935060c089013584880152610120915060e089013582880152610140848a01358189015261253d838b018b6123ea565b955092508188870301848901526125558686856122d7565b9550612563818b018b6123ea565b9550935050808786030161018088015250506125808383836122d7565b93505050508260208301529392505050565b6000602082840312156125a457600080fd5b81517fffffffff000000000000000000000000000000000000000000000000000000008116811461014657600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6000815180845261261b81602086016020860161233c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600073ffffffffffffffffffffffffffffffffffffffff80871683528086166020840152508360408301526080606083015261268c6080830184612603565b9695505050505050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b848110156127c1577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808a8503018652815188850173ffffffffffffffffffffffffffffffffffffffff82511686528482015160038110612748577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b808310156127ac5783517fffffffff0000000000000000000000000000000000000000000000000000000016825292860192600192909201919086019061276a565b509785019795505050908201906001016126bf565b505073ffffffffffffffffffffffffffffffffffffffff8a169088015286810360408801526127f08189612603565b9a9950505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361285e5761285e6127fe565b5060010190565b600081612874576128746127fe565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b80820281158282048414176128b1576128b16127fe565b92915050565b808201808211156128b1576128b16127fe565b73ffffffffffffffffffffffffffffffffffffffff831681526040602082015260006123346040830184612603565b602081526000610146602083018461260356fe4c69624469616d6f6e644375743a2041646420666163657420686173206e6f20636f64654c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a205265706c61636520666163657420686173206e6f20636f6465a2646970667358221220a952f19990a20474450919a2df9ddff4430a71350892e0954f2bb073575ad64864736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "Account module contract that provides the account features and initialization of signer compatible with EIP-1271 & EIP-4337", + "kind": "dev", + "methods": { + "execute(address,uint256,bytes)": { + "details": "This method executes the calldata coming from the EntryPoint. Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)", + "params": { + "_dest": "Address of destination where the call will be forwarded to", + "_func": "Bytes of calldata to execute in the destination address", + "_value": "Amount of native coin the owner is willing to send(e.g. ETH, BNB)" + } + }, + "executeBatch(address[],uint256[],bytes[])": { + "details": "This method batch executes the calldata coming from the EntryPoint. Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)", + "params": { + "_dest": "Array of addresses of destination where the call will be forwarded to", + "_func": "Array of bytes of calldata to execute in the destination address", + "_value": "Array of amount of native coin the owner is willing to send(e.g. ETH, BNB)" + } + }, + "initialize(address,address,address,address,bytes)": { + "details": "This method can only be called during the initialization or signature migration. If the proxy contract was created without initialization, anyone can call initialize. Barz calls initialize in constructor in an atomic transaction during deployment", + "params": { + "_anEntryPoint": "Entrypoint contract defined in EIP-4337 handling the flow of UserOp", + "_defaultFallBackHandler": "Middleware contract for default facets", + "_facetRegistry": "Registry of Facets that hold all facet information", + "_ownerPublicKey": "Bytes of owner public key", + "_verificationFacet": "Facet contract handling the verificationi" + } + } + }, + "title": "Account Facet", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "constructor": { + "notice": "This constructor ensures that this contract can only be used as singleton for Proxy contracts" + }, + "entryPoint()": { + "notice": "Returns the address of EntryPoint contract registered to Barz account" + }, + "execute(address,uint256,bytes)": { + "notice": "Calls the destination with inputted calldata and value from EntryPoint" + }, + "executeBatch(address[],uint256[],bytes[])": { + "notice": "Batch calls the destination with inputted calldata and value from EntryPoint" + }, + "getNonce()": { + "notice": "Return the account nonce. This method returns the next sequential nonce. For a nonce of a specific key, use `entrypoint.getNonce(account, key)`" + }, + "initialize(address,address,address,address,bytes)": { + "notice": "Initializes the initial storage of the Barz contract." + }, + "validateUserOp((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256)": { + "notice": "Validate user's signature and nonce. subclass doesn't need to override this method. Instead, it should override the specific internal validation methods." + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 27823, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "s", + "offset": 0, + "slot": "0", + "type": "t_struct(AppStorage)27570_storage" + } + ], + "types": { + "t_bytes4": { + "encoding": "inplace", + "label": "bytes4", + "numberOfBytes": "4" + }, + "t_contract(IEntryPoint)12286": { + "encoding": "inplace", + "label": "contract IEntryPoint", + "numberOfBytes": "20" + }, + "t_contract(IFacetRegistry)26105": { + "encoding": "inplace", + "label": "contract IFacetRegistry", + "numberOfBytes": "20" + }, + "t_mapping(t_uint256,t_struct(InitializersStorage)27549_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => struct InitializersStorage)", + "numberOfBytes": "32", + "value": "t_struct(InitializersStorage)27549_storage" + }, + "t_mapping(t_uint256,t_struct(Lock)27542_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => struct Lock)", + "numberOfBytes": "32", + "value": "t_struct(Lock)27542_storage" + }, + "t_struct(AppStorage)27570_storage": { + "encoding": "inplace", + "label": "struct AppStorage", + "members": [ + { + "astId": 27554, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "initStorage", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_uint256,t_struct(InitializersStorage)27549_storage)" + }, + { + "astId": 27556, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "signerMigration", + "offset": 0, + "slot": "1", + "type": "t_uint8" + }, + { + "astId": 27558, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "validateOwnerSignatureSelector", + "offset": 1, + "slot": "1", + "type": "t_bytes4" + }, + { + "astId": 27561, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "entryPoint", + "offset": 5, + "slot": "1", + "type": "t_contract(IEntryPoint)12286" + }, + { + "astId": 27564, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "facetRegistry", + "offset": 0, + "slot": "2", + "type": "t_contract(IFacetRegistry)26105" + }, + { + "astId": 27569, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "locks", + "offset": 0, + "slot": "3", + "type": "t_mapping(t_uint256,t_struct(Lock)27542_storage)" + } + ], + "numberOfBytes": "128" + }, + "t_struct(InitializersStorage)27549_storage": { + "encoding": "inplace", + "label": "struct InitializersStorage", + "members": [ + { + "astId": 27544, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "signerInitialized", + "offset": 0, + "slot": "0", + "type": "t_uint8" + }, + { + "astId": 27546, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "accountInitialized", + "offset": 1, + "slot": "0", + "type": "t_uint8" + }, + { + "astId": 27548, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "restrictionsInitialized", + "offset": 2, + "slot": "0", + "type": "t_uint8" + } + ], + "numberOfBytes": "32" + }, + "t_struct(Lock)27542_storage": { + "encoding": "inplace", + "label": "struct Lock", + "members": [ + { + "astId": 27539, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "release", + "offset": 0, + "slot": "0", + "type": "t_uint64" + }, + { + "astId": 27541, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "locker", + "offset": 8, + "slot": "0", + "type": "t_bytes4" + } + ], + "numberOfBytes": "32" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint64": { + "encoding": "inplace", + "label": "uint64", + "numberOfBytes": "8" + }, + "t_uint8": { + "encoding": "inplace", + "label": "uint8", + "numberOfBytes": "1" + } + } + } +} \ No newline at end of file diff --git a/deployments/avalanche/BarzFactory.json b/deployments/avalanche/BarzFactory.json new file mode 100644 index 0000000..4aa8ff3 --- /dev/null +++ b/deployments/avalanche/BarzFactory.json @@ -0,0 +1,318 @@ +{ + "address": "0x729c310186a57833f622630a16d13f710b83272a", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_accountFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_entryPoint", + "type": "address" + }, + { + "internalType": "address", + "name": "_facetRegistry", + "type": "address" + }, + { + "internalType": "address", + "name": "_defaultFallback", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "BarzDeployed", + "type": "event" + }, + { + "inputs": [], + "name": "accountFacet", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_verificationFacet", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_owner", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "_salt", + "type": "uint256" + } + ], + "name": "createAccount", + "outputs": [ + { + "internalType": "contract Barz", + "name": "barz", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "defaultFallback", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "entryPoint", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetRegistry", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_verificationFacet", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_owner", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "_salt", + "type": "uint256" + } + ], + "name": "getAddress", + "outputs": [ + { + "internalType": "address", + "name": "barzAddress", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_accountFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_verificationFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_entryPoint", + "type": "address" + }, + { + "internalType": "address", + "name": "_facetRegistry", + "type": "address" + }, + { + "internalType": "address", + "name": "_defaultFallback", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_ownerPublicKey", + "type": "bytes" + } + ], + "name": "getBytecode", + "outputs": [ + { + "internalType": "bytes", + "name": "barzBytecode", + "type": "bytes" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "getCreationCode", + "outputs": [ + { + "internalType": "bytes", + "name": "creationCode", + "type": "bytes" + } + ], + "stateMutability": "pure", + "type": "function" + } + ], + "transactionHash": "0x47ab720e3a967361af1fa4ea62143b11c7353a30b1185b456dc84ea21fe4df95", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 104, + "gasUsed": "801756", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0xa7bc06fef661ff9f59dfabd704beb66f8f35d12342f215f030e57ab0c996d05e", + "transactionHash": "0x47ab720e3a967361af1fa4ea62143b11c7353a30b1185b456dc84ea21fe4df95", + "logs": [], + "blockNumber": 38010884, + "cumulativeGasUsed": "3141377", + "status": 1, + "byzantium": true + }, + "args": [ + "0xFde53272dcd7938d16E031A6989753c321728332", + "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789", + "0xAfCb70e6e9514E2A15B23A01d2a9b9f7A34f2c33", + "0x2e7f1dAe1F3799d20f5c31bEFdc7A620f664728D" + ], + "numDeployments": 3, + "solcInputHash": "4356503edd8ae34e73cb6dd1c8e2fc8a", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_accountFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_entryPoint\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_facetRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_defaultFallback\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"BarzDeployed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"accountFacet\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_verificationFacet\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_owner\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_salt\",\"type\":\"uint256\"}],\"name\":\"createAccount\",\"outputs\":[{\"internalType\":\"contract Barz\",\"name\":\"barz\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"defaultFallback\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"entryPoint\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetRegistry\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_verificationFacet\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_owner\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_salt\",\"type\":\"uint256\"}],\"name\":\"getAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"barzAddress\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_accountFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_verificationFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_entryPoint\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_facetRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_defaultFallback\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_ownerPublicKey\",\"type\":\"bytes\"}],\"name\":\"getBytecode\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"barzBytecode\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCreationCode\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"creationCode\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"Contract to easily deploy Barz to a pre-computed address with a single call\",\"kind\":\"dev\",\"methods\":{\"constructor\":{\"params\":{\"_accountFacet\":\"Account Facet to be used to create Barz\",\"_defaultFallback\":\"Default Fallback Handler to be used to create Barz\",\"_entryPoint\":\"Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\",\"_facetRegistry\":\"Facet Registry to be used to create Barz\"}},\"createAccount(address,bytes,uint256)\":{\"params\":{\"_owner\":\"Public Key of the owner to initialize barz account\",\"_salt\":\"Salt used for deploying barz with create2\",\"_verificationFacet\":\"Address of verification facet used for creating the barz account\"},\"returns\":{\"barz\":\"Instance of Barz contract deployed with the given parameters\"}},\"getAddress(address,bytes,uint256)\":{\"params\":{\"_owner\":\"Public Key of the owner to initialize barz account\",\"_salt\":\"Salt used for deploying barz with create2\",\"_verificationFacet\":\"Address of verification facet used for creating the barz account\"},\"returns\":{\"barzAddress\":\"Precalculated Barz address\"}},\"getBytecode(address,address,address,address,address,bytes)\":{\"params\":{\"_accountFacet\":\"Account Facet to be used to create Barz\",\"_defaultFallback\":\"Default Fallback Handler to be used to create Barz\",\"_entryPoint\":\"Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\",\"_facetRegistry\":\"Facet Registry to be used to create Barz\",\"_ownerPublicKey\":\"Public Key of owner to be used to initialize Barz ownership\",\"_verificationFacet\":\"Verification Facet to be used to create Barz\"},\"returns\":{\"barzBytecode\":\"Bytecode of Barz\"}},\"getCreationCode()\":{\"returns\":{\"creationCode\":\"Creation code of Barz\"}}},\"title\":\"Barz Factory\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"Sets the initialization data for Barz contract initialization\"},\"createAccount(address,bytes,uint256)\":{\"notice\":\"Creates the Barz with a single call. It creates the Barz contract with the givent verification facet\"},\"getAddress(address,bytes,uint256)\":{\"notice\":\"Calculates the address of Barz with the given parameters\"},\"getBytecode(address,address,address,address,address,bytes)\":{\"notice\":\"Returns the bytecode of Barz with the given parameter\"},\"getCreationCode()\":{\"notice\":\"Returns the creation code of the Barz contract\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/BarzFactory.sol\":\"BarzFactory\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"contracts/Barz.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {LibDiamond} from \\\"./libraries/LibDiamond.sol\\\";\\nimport {IBarz} from \\\"./interfaces/IBarz.sol\\\";\\n\\n/**\\n * @title Barz\\n * @dev A diamond proxy wallet with a modular & upgradeable architecture\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract Barz is IBarz {\\n /**\\n * @notice Initializes Barz with the given parameters. Barz account is intended to be created from Barz Factory for stable deployment.\\n * @dev This method makes a delegate call to account facet and account facet handles the initialization.\\n * With modular architecture, Barz encompasses wide spectrum of architecture and logic.\\n * The only requirement is account facet to comply with initialize() interface.\\n * Barz doesn't include built-in functions and is a full proxy, for maximum extensibility and modularity.\\n * @param _accountFacet Address of Account Facet in charge of the Barz initialization\\n * @param _verificationFacet Address of Verification Facet for verifying the signature. Could be any signature scheme\\n * @param _entryPoint Address of Entry Point contract\\n * @param _facetRegistry Address of Facet Registry. Facet Registry is a registry holding trusted facets that could be added to user's wallet\\n * @param _defaultFallBack Address of Default FallBack Handler. Middleware contract for more efficient deployment\\n * @param _ownerPublicKey Bytes of Owner Public Key using for initialization\\n */\\n constructor(\\n address _accountFacet,\\n address _verificationFacet,\\n address _entryPoint,\\n address _facetRegistry,\\n address _defaultFallBack,\\n bytes memory _ownerPublicKey\\n ) payable {\\n bytes memory initCall = abi.encodeWithSignature(\\n \\\"initialize(address,address,address,address,bytes)\\\",\\n _verificationFacet,\\n _entryPoint,\\n _facetRegistry,\\n _defaultFallBack,\\n _ownerPublicKey\\n );\\n (bool success, bytes memory result) = _accountFacet.delegatecall(\\n initCall\\n );\\n if (!success || uint256(bytes32(result)) != 1) {\\n revert Barz__InitializationFailure();\\n }\\n }\\n\\n /**\\n * @notice Fallback function for Barz complying with Diamond Standard with customization of adding Default Fallback Handler\\n * @dev Find facet for function that is called and execute the function if a facet is found and return any value.\\n */\\n fallback() external payable {\\n LibDiamond.DiamondStorage storage ds;\\n bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION;\\n // get diamond storage\\n assembly {\\n ds.slot := position\\n }\\n // get facet from function selector\\n address facet = address(bytes20(ds.facets[msg.sig]));\\n if (facet == address(0))\\n facet = ds.defaultFallbackHandler.facetAddress(msg.sig);\\n require(facet != address(0), \\\"Barz: Function does not exist\\\");\\n // Execute external function from facet using delegatecall and return any value.\\n assembly {\\n // copy function selector and any arguments\\n calldatacopy(0, 0, calldatasize())\\n // execute function call using the facet\\n let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)\\n // get any return value\\n returndatacopy(0, 0, returndatasize())\\n // return any return value or error back to the caller\\n switch result\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @notice Receive function to receive native token without data\\n */\\n receive() external payable {}\\n}\\n\",\"keccak256\":\"0xd1c773409a4b3d1ca0316445d9ea1d686bab9cd5f6731fbdb0766a93edfd7bdb\",\"license\":\"Apache-2.0\"},\"contracts/BarzFactory.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {Barz} from \\\"./Barz.sol\\\";\\nimport {IBarzFactory} from \\\"./interfaces/IBarzFactory.sol\\\";\\n\\n/**\\n * @title Barz Factory\\n * @dev Contract to easily deploy Barz to a pre-computed address with a single call\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract BarzFactory is IBarzFactory {\\n address public immutable accountFacet;\\n address public immutable entryPoint;\\n address public immutable facetRegistry;\\n address public immutable defaultFallback;\\n\\n /**\\n * @notice Sets the initialization data for Barz contract initialization\\n * @param _accountFacet Account Facet to be used to create Barz\\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\\n * @param _facetRegistry Facet Registry to be used to create Barz\\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\\n */\\n constructor(\\n address _accountFacet,\\n address _entryPoint,\\n address _facetRegistry,\\n address _defaultFallback\\n ) {\\n accountFacet = _accountFacet;\\n entryPoint = _entryPoint;\\n facetRegistry = _facetRegistry;\\n defaultFallback = _defaultFallback;\\n }\\n\\n /**\\n * @notice Creates the Barz with a single call. It creates the Barz contract with the givent verification facet\\n * @param _verificationFacet Address of verification facet used for creating the barz account\\n * @param _owner Public Key of the owner to initialize barz account\\n * @param _salt Salt used for deploying barz with create2\\n * @return barz Instance of Barz contract deployed with the given parameters\\n */\\n function createAccount(\\n address _verificationFacet,\\n bytes calldata _owner,\\n uint256 _salt\\n ) external override returns (Barz barz) {\\n address addr = getAddress(_verificationFacet, _owner, _salt);\\n uint codeSize = addr.code.length;\\n if (codeSize > 0) {\\n return Barz(payable(addr));\\n }\\n barz = new Barz{salt: bytes32(_salt)}(\\n accountFacet,\\n _verificationFacet,\\n entryPoint,\\n facetRegistry,\\n defaultFallback,\\n _owner\\n );\\n emit BarzDeployed(address(barz));\\n }\\n\\n /**\\n * @notice Calculates the address of Barz with the given parameters\\n * @param _verificationFacet Address of verification facet used for creating the barz account\\n * @param _owner Public Key of the owner to initialize barz account\\n * @param _salt Salt used for deploying barz with create2\\n * @return barzAddress Precalculated Barz address\\n */\\n function getAddress(\\n address _verificationFacet,\\n bytes calldata _owner,\\n uint256 _salt\\n ) public view override returns (address barzAddress) {\\n bytes memory bytecode = getBytecode(\\n accountFacet,\\n _verificationFacet,\\n entryPoint,\\n facetRegistry,\\n defaultFallback,\\n _owner\\n );\\n bytes32 hash = keccak256(\\n abi.encodePacked(\\n bytes1(0xff),\\n address(this),\\n _salt,\\n keccak256(bytecode)\\n )\\n );\\n barzAddress = address(uint160(uint256(hash)));\\n }\\n\\n /**\\n * @notice Returns the bytecode of Barz with the given parameter\\n * @param _accountFacet Account Facet to be used to create Barz\\n * @param _verificationFacet Verification Facet to be used to create Barz\\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\\n * @param _facetRegistry Facet Registry to be used to create Barz\\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\\n * @param _ownerPublicKey Public Key of owner to be used to initialize Barz ownership\\n * @return barzBytecode Bytecode of Barz\\n */\\n function getBytecode(\\n address _accountFacet,\\n address _verificationFacet,\\n address _entryPoint,\\n address _facetRegistry,\\n address _defaultFallback,\\n bytes calldata _ownerPublicKey\\n ) public pure override returns (bytes memory barzBytecode) {\\n bytes memory bytecode = type(Barz).creationCode;\\n barzBytecode = abi.encodePacked(\\n bytecode,\\n abi.encode(\\n _accountFacet,\\n _verificationFacet,\\n _entryPoint,\\n _facetRegistry,\\n _defaultFallback,\\n _ownerPublicKey\\n )\\n );\\n }\\n\\n /**\\n * @notice Returns the creation code of the Barz contract\\n * @return creationCode Creation code of Barz\\n */\\n function getCreationCode()\\n public\\n pure\\n override\\n returns (bytes memory creationCode)\\n {\\n creationCode = type(Barz).creationCode;\\n }\\n}\\n\",\"keccak256\":\"0x76d6058fa4714f5ef87b876e49ce7e21f581164901eea906ec743e82362b1df6\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IBarz.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Barz Interface\\n * @dev Interface of Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IBarz {\\n error Barz__InitializationFailure();\\n}\\n\",\"keccak256\":\"0xca9f0c2c1ad7d06088fa16ae92d587416f2d10d8f999d7afe8ca5c4d73410aba\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IBarzFactory.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {Barz} from \\\"../Barz.sol\\\";\\n\\n/**\\n * @title Barz Factory Interface\\n * @dev Interface of contract to easily deploy Barz to a pre-computed address with a single call\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IBarzFactory {\\n event BarzDeployed(address);\\n\\n function createAccount(\\n address verificationFacet,\\n bytes calldata owner,\\n uint256 salt\\n ) external returns (Barz);\\n\\n function getAddress(\\n address verificationFacet,\\n bytes calldata owner,\\n uint256 salt\\n ) external view returns (address);\\n\\n function getBytecode(\\n address accountFacet,\\n address verificationFacet,\\n address entryPoint,\\n address facetRegistry,\\n address defaultFallback,\\n bytes memory ownerPublicKey\\n ) external pure returns (bytes memory);\\n\\n function getCreationCode() external pure returns (bytes memory);\\n}\\n\",\"keccak256\":\"0xadb48a6f3025f6395e26ffd5f9319da73ad2383906c8223e8455f41f420fba26\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\\n bytes4(keccak256(\\\"verifyRestrictions(address,address,uint256,bytes)\\\"));\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // Default Fallback Handler of the barz.\\n IDiamondLoupe defaultFallbackHandler;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function enforceIsSelf() internal view {\\n require(msg.sender == address(this), \\\"LibDiamond: Caller not self\\\");\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n\\n unchecked {\\n facetIndex++;\\n }\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n\\n function restrictionsFacet() internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(\\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2cabdc00de859c3a3170ce3bda5d0e5fd3933d47ce904fd1585f9818b02572f8\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x61010060405234801561001157600080fd5b50604051610eba380380610eba8339810160408190526100309161006e565b6001600160a01b0393841660805291831660a052821660c0521660e0526100c2565b80516001600160a01b038116811461006957600080fd5b919050565b6000806000806080858703121561008457600080fd5b61008d85610052565b935061009b60208601610052565b92506100a960408601610052565b91506100b760608601610052565b905092959194509250565b60805160a05160c05160e051610d886101326000396000818161013b015281816102b3015261048101526000818160bf01528181610292015261046001526000818161016301528181610271015261043f01526000818161018b0152818161024f015261041d0152610d886000f3fe60806040523480156200001157600080fd5b5060043610620000925760003560e01c806344409a82116200006257806344409a821462000135578063b0d691fe146200015d578063b0f5d4641462000185578063c8a7adf514620001ad57600080fd5b8062c194db14620000975780630a1acd7314620000b9578063296601cd146200010757806333bb64a7146200011e575b600080fd5b620000a1620001c4565b604051620000b091906200056c565b60405180910390f35b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001620000b0565b620000e16200011836600462000635565b6200020e565b620000a16200012f36600462000695565b6200036d565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e1620001be36600462000635565b62000414565b606060405180602001620001d89062000538565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082820381018352601f90910116604052919050565b6000806200021f8686868662000414565b905073ffffffffffffffffffffffffffffffffffffffff81163b8015620002495750905062000365565b8360001b7f0000000000000000000000000000000000000000000000000000000000000000887f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008b8b604051620002e29062000538565b620002f497969594939291906200073a565b8190604051809103906000f590508015801562000315573d6000803e3d6000fd5b5060405173ffffffffffffffffffffffffffffffffffffffff821681529093507f9e6e326008e68f57877e2bae766a5745c162e42359e34834a7f0661fa82d31b19060200160405180910390a150505b949350505050565b6060600060405180602001620003839062000538565b6020820181038252601f19601f8201166040525090508089898989898989604051602001620003b997969594939291906200073a565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052620003f79291602001620007cd565b604051602081830303815290604052915050979650505050505050565b600080620004a87f0000000000000000000000000000000000000000000000000000000000000000877f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008a8a6200036d565b8051602091820120604080517fff00000000000000000000000000000000000000000000000000000000000000818501523060601b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001660218201526035810196909652605580870192909252805180870390920182526075909501909452835193019290922095945050505050565b610552806200080183390190565b60005b838110156200056357818101518382015260200162000549565b50506000910152565b60208152600082518060208401526200058d81604085016020870162000546565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b803573ffffffffffffffffffffffffffffffffffffffff81168114620005e457600080fd5b919050565b60008083601f840112620005fc57600080fd5b50813567ffffffffffffffff8111156200061557600080fd5b6020830191508360208285010111156200062e57600080fd5b9250929050565b600080600080606085870312156200064c57600080fd5b6200065785620005bf565b9350602085013567ffffffffffffffff8111156200067457600080fd5b6200068287828801620005e9565b9598909750949560400135949350505050565b600080600080600080600060c0888a031215620006b157600080fd5b620006bc88620005bf565b9650620006cc60208901620005bf565b9550620006dc60408901620005bf565b9450620006ec60608901620005bf565b9350620006fc60808901620005bf565b925060a088013567ffffffffffffffff8111156200071957600080fd5b620007278a828b01620005e9565b989b979a50959850939692959293505050565b600073ffffffffffffffffffffffffffffffffffffffff808a16835280891660208401528088166040840152808716606084015280861660808401525060c060a08301528260c0830152828460e0840137600060e0848401015260e07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f850116830101905098975050505050505050565b60008351620007e181846020880162000546565b835190830190620007f781836020880162000546565b0194935050505056fe608060405260405161055238038061055283398101604081905261002291610163565b6000858585858560405160240161003d959493929190610264565b60408051601f198184030181529181526020820180516001600160e01b0316634a93641760e01b1790525190915060009081906001600160a01b038a16906100869085906102c3565b600060405180830381855af49150503d80600081146100c1576040519150601f19603f3d011682016040523d82523d6000602084013e6100c6565b606091505b50915091508115806100e157506100dc816102df565b600114155b156100ff57604051636ff35f8960e01b815260040160405180910390fd5b505050505050505050610306565b80516001600160a01b038116811461012457600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101561015a578181015183820152602001610142565b50506000910152565b60008060008060008060c0878903121561017c57600080fd5b6101858761010d565b95506101936020880161010d565b94506101a16040880161010d565b93506101af6060880161010d565b92506101bd6080880161010d565b60a08801519092506001600160401b03808211156101da57600080fd5b818901915089601f8301126101ee57600080fd5b81518181111561020057610200610129565b604051601f8201601f19908116603f0116810190838211818310171561022857610228610129565b816040528281528c602084870101111561024157600080fd5b61025283602083016020880161013f565b80955050505050509295509295509295565b600060018060a01b0380881683528087166020840152808616604084015280851660608401525060a0608083015282518060a08401526102ab8160c085016020870161013f565b601f01601f19169190910160c0019695505050505050565b600082516102d581846020870161013f565b9190910192915050565b80516020808301519190811015610300576000198160200360031b1b821691505b50919050565b61023d806103156000396000f3fe60806040523661000b57005b600080357fffffffff000000000000000000000000000000000000000000000000000000001681527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020819052604090912054819060601c80610125576004838101546040517fcdffacc60000000000000000000000000000000000000000000000000000000081526000357fffffffff00000000000000000000000000000000000000000000000000000000169281019290925273ffffffffffffffffffffffffffffffffffffffff169063cdffacc690602401602060405180830381865afa1580156100fe573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061012291906101ca565b90505b73ffffffffffffffffffffffffffffffffffffffff81166101a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4261727a3a2046756e6374696f6e20646f6573206e6f74206578697374000000604482015260640160405180910390fd5b3660008037600080366000845af43d6000803e8080156101c5573d6000f35b3d6000fd5b6000602082840312156101dc57600080fd5b815173ffffffffffffffffffffffffffffffffffffffff8116811461020057600080fd5b939250505056fea26469706673582212200f3fa76ace3be8675d8b4c0d6c210a922fff2c2f1444023b817d1f6c908cd56a64736f6c63430008150033a2646970667358221220329ad45a4ef4915180001cb1fc90a5f97ad94a0b280426a580cba65fce28c0f164736f6c63430008150033", + "deployedBytecode": "0x60806040523480156200001157600080fd5b5060043610620000925760003560e01c806344409a82116200006257806344409a821462000135578063b0d691fe146200015d578063b0f5d4641462000185578063c8a7adf514620001ad57600080fd5b8062c194db14620000975780630a1acd7314620000b9578063296601cd146200010757806333bb64a7146200011e575b600080fd5b620000a1620001c4565b604051620000b091906200056c565b60405180910390f35b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001620000b0565b620000e16200011836600462000635565b6200020e565b620000a16200012f36600462000695565b6200036d565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e1620001be36600462000635565b62000414565b606060405180602001620001d89062000538565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082820381018352601f90910116604052919050565b6000806200021f8686868662000414565b905073ffffffffffffffffffffffffffffffffffffffff81163b8015620002495750905062000365565b8360001b7f0000000000000000000000000000000000000000000000000000000000000000887f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008b8b604051620002e29062000538565b620002f497969594939291906200073a565b8190604051809103906000f590508015801562000315573d6000803e3d6000fd5b5060405173ffffffffffffffffffffffffffffffffffffffff821681529093507f9e6e326008e68f57877e2bae766a5745c162e42359e34834a7f0661fa82d31b19060200160405180910390a150505b949350505050565b6060600060405180602001620003839062000538565b6020820181038252601f19601f8201166040525090508089898989898989604051602001620003b997969594939291906200073a565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052620003f79291602001620007cd565b604051602081830303815290604052915050979650505050505050565b600080620004a87f0000000000000000000000000000000000000000000000000000000000000000877f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008a8a6200036d565b8051602091820120604080517fff00000000000000000000000000000000000000000000000000000000000000818501523060601b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001660218201526035810196909652605580870192909252805180870390920182526075909501909452835193019290922095945050505050565b610552806200080183390190565b60005b838110156200056357818101518382015260200162000549565b50506000910152565b60208152600082518060208401526200058d81604085016020870162000546565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b803573ffffffffffffffffffffffffffffffffffffffff81168114620005e457600080fd5b919050565b60008083601f840112620005fc57600080fd5b50813567ffffffffffffffff8111156200061557600080fd5b6020830191508360208285010111156200062e57600080fd5b9250929050565b600080600080606085870312156200064c57600080fd5b6200065785620005bf565b9350602085013567ffffffffffffffff8111156200067457600080fd5b6200068287828801620005e9565b9598909750949560400135949350505050565b600080600080600080600060c0888a031215620006b157600080fd5b620006bc88620005bf565b9650620006cc60208901620005bf565b9550620006dc60408901620005bf565b9450620006ec60608901620005bf565b9350620006fc60808901620005bf565b925060a088013567ffffffffffffffff8111156200071957600080fd5b620007278a828b01620005e9565b989b979a50959850939692959293505050565b600073ffffffffffffffffffffffffffffffffffffffff808a16835280891660208401528088166040840152808716606084015280861660808401525060c060a08301528260c0830152828460e0840137600060e0848401015260e07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f850116830101905098975050505050505050565b60008351620007e181846020880162000546565b835190830190620007f781836020880162000546565b0194935050505056fe608060405260405161055238038061055283398101604081905261002291610163565b6000858585858560405160240161003d959493929190610264565b60408051601f198184030181529181526020820180516001600160e01b0316634a93641760e01b1790525190915060009081906001600160a01b038a16906100869085906102c3565b600060405180830381855af49150503d80600081146100c1576040519150601f19603f3d011682016040523d82523d6000602084013e6100c6565b606091505b50915091508115806100e157506100dc816102df565b600114155b156100ff57604051636ff35f8960e01b815260040160405180910390fd5b505050505050505050610306565b80516001600160a01b038116811461012457600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101561015a578181015183820152602001610142565b50506000910152565b60008060008060008060c0878903121561017c57600080fd5b6101858761010d565b95506101936020880161010d565b94506101a16040880161010d565b93506101af6060880161010d565b92506101bd6080880161010d565b60a08801519092506001600160401b03808211156101da57600080fd5b818901915089601f8301126101ee57600080fd5b81518181111561020057610200610129565b604051601f8201601f19908116603f0116810190838211818310171561022857610228610129565b816040528281528c602084870101111561024157600080fd5b61025283602083016020880161013f565b80955050505050509295509295509295565b600060018060a01b0380881683528087166020840152808616604084015280851660608401525060a0608083015282518060a08401526102ab8160c085016020870161013f565b601f01601f19169190910160c0019695505050505050565b600082516102d581846020870161013f565b9190910192915050565b80516020808301519190811015610300576000198160200360031b1b821691505b50919050565b61023d806103156000396000f3fe60806040523661000b57005b600080357fffffffff000000000000000000000000000000000000000000000000000000001681527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020819052604090912054819060601c80610125576004838101546040517fcdffacc60000000000000000000000000000000000000000000000000000000081526000357fffffffff00000000000000000000000000000000000000000000000000000000169281019290925273ffffffffffffffffffffffffffffffffffffffff169063cdffacc690602401602060405180830381865afa1580156100fe573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061012291906101ca565b90505b73ffffffffffffffffffffffffffffffffffffffff81166101a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4261727a3a2046756e6374696f6e20646f6573206e6f74206578697374000000604482015260640160405180910390fd5b3660008037600080366000845af43d6000803e8080156101c5573d6000f35b3d6000fd5b6000602082840312156101dc57600080fd5b815173ffffffffffffffffffffffffffffffffffffffff8116811461020057600080fd5b939250505056fea26469706673582212200f3fa76ace3be8675d8b4c0d6c210a922fff2c2f1444023b817d1f6c908cd56a64736f6c63430008150033a2646970667358221220329ad45a4ef4915180001cb1fc90a5f97ad94a0b280426a580cba65fce28c0f164736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "Contract to easily deploy Barz to a pre-computed address with a single call", + "kind": "dev", + "methods": { + "constructor": { + "params": { + "_accountFacet": "Account Facet to be used to create Barz", + "_defaultFallback": "Default Fallback Handler to be used to create Barz", + "_entryPoint": "Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF", + "_facetRegistry": "Facet Registry to be used to create Barz" + } + }, + "createAccount(address,bytes,uint256)": { + "params": { + "_owner": "Public Key of the owner to initialize barz account", + "_salt": "Salt used for deploying barz with create2", + "_verificationFacet": "Address of verification facet used for creating the barz account" + }, + "returns": { + "barz": "Instance of Barz contract deployed with the given parameters" + } + }, + "getAddress(address,bytes,uint256)": { + "params": { + "_owner": "Public Key of the owner to initialize barz account", + "_salt": "Salt used for deploying barz with create2", + "_verificationFacet": "Address of verification facet used for creating the barz account" + }, + "returns": { + "barzAddress": "Precalculated Barz address" + } + }, + "getBytecode(address,address,address,address,address,bytes)": { + "params": { + "_accountFacet": "Account Facet to be used to create Barz", + "_defaultFallback": "Default Fallback Handler to be used to create Barz", + "_entryPoint": "Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF", + "_facetRegistry": "Facet Registry to be used to create Barz", + "_ownerPublicKey": "Public Key of owner to be used to initialize Barz ownership", + "_verificationFacet": "Verification Facet to be used to create Barz" + }, + "returns": { + "barzBytecode": "Bytecode of Barz" + } + }, + "getCreationCode()": { + "returns": { + "creationCode": "Creation code of Barz" + } + } + }, + "title": "Barz Factory", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "constructor": { + "notice": "Sets the initialization data for Barz contract initialization" + }, + "createAccount(address,bytes,uint256)": { + "notice": "Creates the Barz with a single call. It creates the Barz contract with the givent verification facet" + }, + "getAddress(address,bytes,uint256)": { + "notice": "Calculates the address of Barz with the given parameters" + }, + "getBytecode(address,address,address,address,address,bytes)": { + "notice": "Returns the bytecode of Barz with the given parameter" + }, + "getCreationCode()": { + "notice": "Returns the creation code of the Barz contract" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/avalanche/DefaultFallbackHandler.json b/deployments/avalanche/DefaultFallbackHandler.json new file mode 100644 index 0000000..cc275f0 --- /dev/null +++ b/deployments/avalanche/DefaultFallbackHandler.json @@ -0,0 +1,275 @@ +{ + "address": "0x2e7f1dAe1F3799d20f5c31bEFdc7A620f664728D", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_diamondCutFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_accountFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_tokenReceiverFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_diamondLoupeFacet", + "type": "address" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_initializationContractAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "InitializationFunctionReverted", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "indexed": false, + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "DiamondCut", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_functionSelector", + "type": "bytes4" + } + ], + "name": "facetAddress", + "outputs": [ + { + "internalType": "address", + "name": "facetAddress_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetAddresses", + "outputs": [ + { + "internalType": "address[]", + "name": "facetAddresses_", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_facet", + "type": "address" + } + ], + "name": "facetFunctionSelectors", + "outputs": [ + { + "internalType": "bytes4[]", + "name": "facetFunctionSelectors_", + "type": "bytes4[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facets", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondLoupe.Facet[]", + "name": "facets_", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0xd8a811941f1c9055b1d4a7f37946fd75f41eafea85c740f5fbda7c2d00ff9b4d", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 67, + "gasUsed": "1438535", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000001000000000800002000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000", + "blockHash": "0xa1a9b653394e588e4497ab995397e2bd769d51fc2faecf08187a450042935bd2", + "transactionHash": "0xd8a811941f1c9055b1d4a7f37946fd75f41eafea85c740f5fbda7c2d00ff9b4d", + "logs": [ + { + "transactionIndex": 67, + "blockNumber": 38010862, + "transactionHash": "0xd8a811941f1c9055b1d4a7f37946fd75f41eafea85c740f5fbda7c2d00ff9b4d", + "address": "0x2e7f1dAe1F3799d20f5c31bEFdc7A620f664728D", + "topics": [ + "0x8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb673" + ], + "data": "0x000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000580000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000000000000000000000000000000000003600000000000000000000000000b9504140771c3688ff041917192277d2f52e1e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000011f931c1c00000000000000000000000000000000000000000000000000000000000000000000000000000000fde53272dcd7938d16e031a6989753c321728332000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000005b61d27f60000000000000000000000000000000000000000000000000000000047e1da2a000000000000000000000000000000000000000000000000000000003a871cdd00000000000000000000000000000000000000000000000000000000d087d28800000000000000000000000000000000000000000000000000000000b0d691fe000000000000000000000000000000000000000000000000000000000000000000000000000000003143e1c0af0cdc153423863923cf4e3818e34daa000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000005150b7a0200000000000000000000000000000000000000000000000000000000f23a6e6100000000000000000000000000000000000000000000000000000000bc197c81000000000000000000000000000000000000000000000000000000000023de2900000000000000000000000000000000000000000000000000000000a4c0ed3600000000000000000000000000000000000000000000000000000000000000000000000000000000ce36b85d12d81cd619c745c7717f3396e184ac7c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000097a0ed62700000000000000000000000000000000000000000000000000000000adfca15e0000000000000000000000000000000000000000000000000000000052ef6b2c00000000000000000000000000000000000000000000000000000000cdffacc60000000000000000000000000000000000000000000000000000000001ffc9a700000000000000000000000000000000000000000000000000000000f9796ccf0000000000000000000000000000000000000000000000000000000001a5502200000000000000000000000000000000000000000000000000000000d42139a900000000000000000000000000000000000000000000000000000000e3a2f6fe000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "logIndex": 3, + "blockHash": "0xa1a9b653394e588e4497ab995397e2bd769d51fc2faecf08187a450042935bd2" + } + ], + "blockNumber": 38010862, + "cumulativeGasUsed": "3048527", + "status": 1, + "byzantium": true + }, + "args": [ + "0x0B9504140771C3688Ff041917192277D2f52E1e0", + "0xFde53272dcd7938d16E031A6989753c321728332", + "0x3143E1C0Af0Cdc153423863923Cf4e3818e34Daa", + "0xCe36b85d12D81cd619C745c7717f3396E184Ac7C" + ], + "numDeployments": 3, + "solcInputHash": "4356503edd8ae34e73cb6dd1c8e2fc8a", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_diamondCutFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_accountFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_tokenReceiverFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_diamondLoupeFacet\",\"type\":\"address\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_initializationContractAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"InitializationFunctionReverted\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"DiamondCut\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_functionSelector\",\"type\":\"bytes4\"}],\"name\":\"facetAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"facetAddress_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetAddresses\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"facetAddresses_\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_facet\",\"type\":\"address\"}],\"name\":\"facetFunctionSelectors\",\"outputs\":[{\"internalType\":\"bytes4[]\",\"name\":\"facetFunctionSelectors_\",\"type\":\"bytes4[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facets\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondLoupe.Facet[]\",\"name\":\"facets_\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"A default fallback handler for Barz\",\"kind\":\"dev\",\"methods\":{\"constructor\":{\"details\":\"This contract is also a diamond that holds the default facets to reduce gas cost for wallet activation. Within the constructor this conducts diamond cut to initially setup the diamond. This is a non-upgradeable contract\",\"params\":{\"_accountFacet\":\"Address account facet\",\"_diamondCutFacet\":\"Address if diamond cut facet\",\"_diamondLoupeFacet\":\"Address of diamond loupe facet\",\"_tokenReceiverFacet\":\"Address of token receiver facet\"}},\"facetAddress(bytes4)\":{\"details\":\"If facet is not found return address(0).\",\"params\":{\"_functionSelector\":\"The function selector.\"},\"returns\":{\"facetAddress_\":\"The facet address.\"}},\"facetAddresses()\":{\"returns\":{\"facetAddresses_\":\"facetAddresses_\"}},\"facetFunctionSelectors(address)\":{\"params\":{\"_facet\":\"The facet address.\"},\"returns\":{\"facetFunctionSelectors_\":\"facetFunctionSelectors_\"}},\"facets()\":{\"returns\":{\"facets_\":\"The facet struct array including all facet information\"}}},\"title\":\"DefaultFallbackHandler\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"Sets the middleware diamond for Barz wallet as a fallback handler\"},\"facetAddress(bytes4)\":{\"notice\":\"Gets the facet that supports the given selector.\"},\"facetAddresses()\":{\"notice\":\"Get all the facet addresses used by a diamond.\"},\"facetFunctionSelectors(address)\":{\"notice\":\"Gets all the function selectors provided by a facet.\"},\"facets()\":{\"notice\":\"Returns the facet information of call facets registered to this diamond.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/infrastructure/DefaultFallbackHandler.sol\":\"DefaultFallbackHandler\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/introspection/IERC165.sol\\\";\\n\\n/**\\n * @dev _Available since v3.1._\\n */\\ninterface IERC1155Receiver is IERC165 {\\n /**\\n * @dev Handles the receipt of a single ERC1155 token type. This function is\\n * called at the end of a `safeTransferFrom` after the balance has been updated.\\n *\\n * NOTE: To accept the transfer, this must return\\n * `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))`\\n * (i.e. 0xf23a6e61, or its own function selector).\\n *\\n * @param operator The address which initiated the transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param id The ID of the token being transferred\\n * @param value The amount of tokens being transferred\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155Received(\\n address operator,\\n address from,\\n uint256 id,\\n uint256 value,\\n bytes calldata data\\n ) external returns (bytes4);\\n\\n /**\\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\\n * is called at the end of a `safeBatchTransferFrom` after the balances have\\n * been updated.\\n *\\n * NOTE: To accept the transfer(s), this must return\\n * `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))`\\n * (i.e. 0xbc197c81, or its own function selector).\\n *\\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155BatchReceived(\\n address operator,\\n address from,\\n uint256[] calldata ids,\\n uint256[] calldata values,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xeb373f1fdc7b755c6a750123a9b9e3a8a02c1470042fd6505d875000a80bde0b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title ERC721 token receiver interface\\n * @dev Interface for any contract that wants to support safeTransfers\\n * from ERC721 asset contracts.\\n */\\ninterface IERC721Receiver {\\n /**\\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\\n * by `operator` from `from`, this function is called.\\n *\\n * It must return its Solidity selector to confirm the token transfer.\\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\\n *\\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\\n */\\n function onERC721Received(\\n address operator,\\n address from,\\n uint256 tokenId,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\\n *\\n * Accounts can be notified of {IERC777} tokens being sent to them by having a\\n * contract implement this interface (contract holders can be their own\\n * implementer) and registering it on the\\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\\n *\\n * See {IERC1820Registry} and {ERC1820Implementer}.\\n */\\ninterface IERC777Recipient {\\n /**\\n * @dev Called by an {IERC777} token contract whenever tokens are being\\n * moved or created into a registered account (`to`). The type of operation\\n * is conveyed by `from` being the zero address or not.\\n *\\n * This call occurs _after_ the token contract's state is updated, so\\n * {IERC777-balanceOf}, etc., can be used to query the post-operation state.\\n *\\n * This function may revert to prevent the operation from being executed.\\n */\\n function tokensReceived(\\n address operator,\\n address from,\\n address to,\\n uint256 amount,\\n bytes calldata userData,\\n bytes calldata operatorData\\n ) external;\\n}\\n\",\"keccak256\":\"0x1a5d61db2733202ba361e6d6741cd2e662380e22b80e987eacfc91973f2267dc\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"contracts/aa-4337/core/BaseAccount.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-empty-blocks */\\n\\nimport \\\"../interfaces/IAccount.sol\\\";\\nimport \\\"../interfaces/IEntryPoint.sol\\\";\\nimport \\\"./Helpers.sol\\\";\\n\\n/**\\n * Basic account implementation.\\n * this contract provides the basic logic for implementing the IAccount interface - validateUserOp\\n * specific account implementation should inherit it and provide the account-specific logic\\n */\\nabstract contract BaseAccount is IAccount {\\n using UserOperationLib for UserOperation;\\n\\n //return value in case of signature failure, with no time-range.\\n // equivalent to _packValidationData(true,0,0);\\n uint256 internal constant SIG_VALIDATION_FAILED = 1;\\n\\n /**\\n * Return the account nonce.\\n * This method returns the next sequential nonce.\\n * For a nonce of a specific key, use `entrypoint.getNonce(account, key)`\\n */\\n function getNonce() public view virtual returns (uint256) {\\n return entryPoint().getNonce(address(this), 0);\\n }\\n\\n /**\\n * return the entryPoint used by this account.\\n * subclass should return the current entryPoint used by this account.\\n */\\n function entryPoint() public view virtual returns (IEntryPoint);\\n\\n /**\\n * Validate user's signature and nonce.\\n * subclass doesn't need to override this method. Instead, it should override the specific internal validation methods.\\n */\\n function validateUserOp(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n uint256 missingAccountFunds\\n ) external virtual override returns (uint256 validationData) {\\n _requireFromEntryPoint();\\n validationData = _validateSignature(userOp, userOpHash);\\n _validateNonce(userOp.nonce);\\n _payPrefund(missingAccountFunds);\\n }\\n\\n /**\\n * ensure the request comes from the known entrypoint.\\n */\\n function _requireFromEntryPoint() internal view virtual {\\n require(\\n msg.sender == address(entryPoint()),\\n \\\"account: not from EntryPoint\\\"\\n );\\n }\\n\\n /**\\n * validate the signature is valid for this message.\\n * @param userOp validate the userOp.signature field\\n * @param userOpHash convenient field: the hash of the request, to check the signature against\\n * (also hashes the entrypoint and chain id)\\n * @return validationData signature and time-range of this operation\\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\\n * otherwise, an address of an \\\"authorizer\\\" contract.\\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \\\"indefinite\\\"\\n * <6-byte> validAfter - first timestamp this operation is valid\\n * If the account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\\n */\\n function _validateSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) internal virtual returns (uint256 validationData);\\n\\n /**\\n * Validate the nonce of the UserOperation.\\n * This method may validate the nonce requirement of this account.\\n * e.g.\\n * To limit the nonce to use sequenced UserOps only (no \\\"out of order\\\" UserOps):\\n * `require(nonce < type(uint64).max)`\\n * For a hypothetical account that *requires* the nonce to be out-of-order:\\n * `require(nonce & type(uint64).max == 0)`\\n *\\n * The actual nonce uniqueness is managed by the EntryPoint, and thus no other\\n * action is needed by the account itself.\\n *\\n * @param nonce to validate\\n *\\n * solhint-disable-next-line no-empty-blocks\\n */\\n function _validateNonce(uint256 nonce) internal view virtual {}\\n\\n /**\\n * sends to the entrypoint (msg.sender) the missing funds for this transaction.\\n * subclass MAY override this method for better funds management\\n * (e.g. send to the entryPoint more than the minimum required, so that in future transactions\\n * it will not be required to send again)\\n * @param missingAccountFunds the minimum value this method should send the entrypoint.\\n * this value MAY be zero, in case there is enough deposit, or the userOp has a paymaster.\\n */\\n function _payPrefund(uint256 missingAccountFunds) internal virtual {\\n if (missingAccountFunds != 0) {\\n (bool success, ) = payable(msg.sender).call{\\n value: missingAccountFunds,\\n gas: type(uint256).max\\n }(\\\"\\\");\\n (success);\\n //ignore failure (its EntryPoint's job to verify, not account.)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa0dcc386b0f04711db3e394fb50e55a3b3b1a4d19fac1f10895844e1aa4e3d5c\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/core/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable no-inline-assembly */\\n\\n/**\\n * returned data from validateUserOp.\\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\\n * @param aggregator - address(0) - the account validated the signature by itself.\\n * address(1) - the account failed to validate the signature.\\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\\n * @param validAfter - this UserOp is valid only after this timestamp.\\n * @param validaUntil - this UserOp is valid only up to this timestamp.\\n */\\nstruct ValidationData {\\n address aggregator;\\n uint48 validAfter;\\n uint48 validUntil;\\n}\\n\\n//extract sigFailed, validAfter, validUntil.\\n// also convert zero validUntil to type(uint48).max\\nfunction _parseValidationData(\\n uint validationData\\n) pure returns (ValidationData memory data) {\\n address aggregator = address(uint160(validationData));\\n uint48 validUntil = uint48(validationData >> 160);\\n if (validUntil == 0) {\\n validUntil = type(uint48).max;\\n }\\n uint48 validAfter = uint48(validationData >> (48 + 160));\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n// intersect account and paymaster ranges.\\nfunction _intersectTimeRange(\\n uint256 validationData,\\n uint256 paymasterValidationData\\n) pure returns (ValidationData memory) {\\n ValidationData memory accountValidationData = _parseValidationData(\\n validationData\\n );\\n ValidationData memory pmValidationData = _parseValidationData(\\n paymasterValidationData\\n );\\n address aggregator = accountValidationData.aggregator;\\n if (aggregator == address(0)) {\\n aggregator = pmValidationData.aggregator;\\n }\\n uint48 validAfter = accountValidationData.validAfter;\\n uint48 validUntil = accountValidationData.validUntil;\\n uint48 pmValidAfter = pmValidationData.validAfter;\\n uint48 pmValidUntil = pmValidationData.validUntil;\\n\\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp\\n * @param data - the ValidationData to pack\\n */\\nfunction _packValidationData(\\n ValidationData memory data\\n) pure returns (uint256) {\\n return\\n uint160(data.aggregator) |\\n (uint256(data.validUntil) << 160) |\\n (uint256(data.validAfter) << (160 + 48));\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp, when not using an aggregator\\n * @param sigFailed - true for signature failure, false for success\\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\\n * @param validAfter first timestamp this UserOperation is valid\\n */\\nfunction _packValidationData(\\n bool sigFailed,\\n uint48 validUntil,\\n uint48 validAfter\\n) pure returns (uint256) {\\n return\\n (sigFailed ? 1 : 0) |\\n (uint256(validUntil) << 160) |\\n (uint256(validAfter) << (160 + 48));\\n}\\n\\n/**\\n * keccak function over calldata.\\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\\n */\\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\\n assembly {\\n let mem := mload(0x40)\\n let len := data.length\\n calldatacopy(mem, data.offset, len)\\n ret := keccak256(mem, len)\\n }\\n}\\n\",\"keccak256\":\"0xa79f06cd158ecb8c0da95493a2f348933b8627a63e228b99738bff3aa107942d\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAccount.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\ninterface IAccount {\\n /**\\n * Validate user's signature and nonce\\n * the entryPoint will make the call to the recipient only if this validation call returns successfully.\\n * signature failure should be reported by returning SIG_VALIDATION_FAILED (1).\\n * This allows making a \\\"simulation call\\\" without a valid signature\\n * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure.\\n *\\n * @dev Must validate caller is the entryPoint.\\n * Must validate the signature and nonce\\n * @param userOp the operation that is about to be executed.\\n * @param userOpHash hash of the user's request data. can be used as the basis for signature.\\n * @param missingAccountFunds missing funds on the account's deposit in the entrypoint.\\n * This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call.\\n * The excess is left as a deposit in the entrypoint, for future calls.\\n * can be withdrawn anytime using \\\"entryPoint.withdrawTo()\\\"\\n * In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero.\\n * @return validationData packaged ValidationData structure. use `_packValidationData` and `_unpackValidationData` to encode and decode\\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\\n * otherwise, an address of an \\\"authorizer\\\" contract.\\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \\\"indefinite\\\"\\n * <6-byte> validAfter - first timestamp this operation is valid\\n * If an account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\\n */\\n function validateUserOp(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n uint256 missingAccountFunds\\n ) external returns (uint256 validationData);\\n}\\n\",\"keccak256\":\"0xcbc4b0973cf954c5895b7796335f651fbfcfb55f67dfa789a3d354f8e23c4f2b\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAggregator.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\n/**\\n * Aggregated Signatures validator.\\n */\\ninterface IAggregator {\\n /**\\n * validate aggregated signature.\\n * revert if the aggregated signature does not match the given list of operations.\\n */\\n function validateSignatures(\\n UserOperation[] calldata userOps,\\n bytes calldata signature\\n ) external view;\\n\\n /**\\n * validate signature of a single userOp\\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\\n * @param userOp the userOperation received from the user.\\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\\n * (usually empty, unless account and aggregator support some kind of \\\"multisig\\\"\\n */\\n function validateUserOpSignature(\\n UserOperation calldata userOp\\n ) external view returns (bytes memory sigForUserOp);\\n\\n /**\\n * aggregate multiple signatures into a single value.\\n * This method is called off-chain to calculate the signature to pass with handleOps()\\n * bundler MAY use optimized custom code perform this aggregation\\n * @param userOps array of UserOperations to collect the signatures from.\\n * @return aggregatedSignature the aggregated signature\\n */\\n function aggregateSignatures(\\n UserOperation[] calldata userOps\\n ) external view returns (bytes memory aggregatedSignature);\\n}\\n\",\"keccak256\":\"0xdfdcd80568f037716674619b31be630fcd8316262f05a815b41d1e81782c966a\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IEntryPoint.sol\":{\"content\":\"/**\\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\\n ** Only one instance required on each chain.\\n **/\\n// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-inline-assembly */\\n/* solhint-disable reason-string */\\n\\nimport \\\"./UserOperation.sol\\\";\\nimport \\\"./IStakeManager.sol\\\";\\nimport \\\"./IAggregator.sol\\\";\\nimport \\\"./INonceManager.sol\\\";\\n\\ninterface IEntryPoint is IStakeManager, INonceManager {\\n /***\\n * An event emitted after each successful request\\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\\n * @param sender - the account that generates this request.\\n * @param paymaster - if non-null, the paymaster that pays for this request.\\n * @param nonce - the nonce value from the request.\\n * @param success - true if the sender transaction succeeded, false if reverted.\\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\\n */\\n event UserOperationEvent(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address indexed paymaster,\\n uint256 nonce,\\n bool success,\\n uint256 actualGasCost,\\n uint256 actualGasUsed\\n );\\n\\n /**\\n * account \\\"sender\\\" was deployed.\\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\\n * @param sender the account that is deployed\\n * @param factory the factory used to deploy this account (in the initCode)\\n * @param paymaster the paymaster used by this UserOp\\n */\\n event AccountDeployed(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address factory,\\n address paymaster\\n );\\n\\n /**\\n * An event emitted if the UserOperation \\\"callData\\\" reverted with non-zero length\\n * @param userOpHash the request unique identifier.\\n * @param sender the sender of this request\\n * @param nonce the nonce used in the request\\n * @param revertReason - the return bytes from the (reverted) call to \\\"callData\\\".\\n */\\n event UserOperationRevertReason(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n uint256 nonce,\\n bytes revertReason\\n );\\n\\n /**\\n * an event emitted by handleOps(), before starting the execution loop.\\n * any event emitted before this event, is part of the validation.\\n */\\n event BeforeExecution();\\n\\n /**\\n * signature aggregator used by the following UserOperationEvents within this bundle.\\n */\\n event SignatureAggregatorChanged(address indexed aggregator);\\n\\n /**\\n * a custom revert error of handleOps, to identify the offending op.\\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\\n * @param reason - revert reason\\n * The string starts with a unique code \\\"AAmn\\\", where \\\"m\\\" is \\\"1\\\" for factory, \\\"2\\\" for account and \\\"3\\\" for paymaster issues,\\n * so a failure can be attributed to the correct entity.\\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\\n */\\n error FailedOp(uint256 opIndex, string reason);\\n\\n /**\\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\\n */\\n error SignatureValidationFailed(address aggregator);\\n\\n /**\\n * Successful result from simulateValidation.\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n */\\n error ValidationResult(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo\\n );\\n\\n /**\\n * Successful result from simulateValidation, if the account returns a signature aggregator\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\\n * bundler MUST use it to verify the signature, or reject the UserOperation\\n */\\n error ValidationResultWithAggregation(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo,\\n AggregatorStakeInfo aggregatorInfo\\n );\\n\\n /**\\n * return value of getSenderAddress\\n */\\n error SenderAddressResult(address sender);\\n\\n /**\\n * return value of simulateHandleOp\\n */\\n error ExecutionResult(\\n uint256 preOpGas,\\n uint256 paid,\\n uint48 validAfter,\\n uint48 validUntil,\\n bool targetSuccess,\\n bytes targetResult\\n );\\n\\n //UserOps handled, per aggregator\\n struct UserOpsPerAggregator {\\n UserOperation[] userOps;\\n // aggregator address\\n IAggregator aggregator;\\n // aggregated signature\\n bytes signature;\\n }\\n\\n /**\\n * Execute a batch of UserOperation.\\n * no signature aggregator is used.\\n * if any account requires an aggregator (that is, it returned an aggregator when\\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\\n * @param ops the operations to execute\\n * @param beneficiary the address to receive the fees\\n */\\n function handleOps(\\n UserOperation[] calldata ops,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * Execute a batch of UserOperation with Aggregators\\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\\n * @param beneficiary the address to receive the fees\\n */\\n function handleAggregatedOps(\\n UserOpsPerAggregator[] calldata opsPerAggregator,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * generate a request Id - unique identifier for this request.\\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\\n */\\n function getUserOpHash(\\n UserOperation calldata userOp\\n ) external view returns (bytes32);\\n\\n /**\\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\\n * @param userOp the user operation to validate.\\n */\\n function simulateValidation(UserOperation calldata userOp) external;\\n\\n /**\\n * gas and return values during simulation\\n * @param preOpGas the gas used for validation (including preValidationGas)\\n * @param prefund the required prefund for this operation\\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\\n */\\n struct ReturnInfo {\\n uint256 preOpGas;\\n uint256 prefund;\\n bool sigFailed;\\n uint48 validAfter;\\n uint48 validUntil;\\n bytes paymasterContext;\\n }\\n\\n /**\\n * returned aggregated signature info.\\n * the aggregator returned by the account, and its current stake.\\n */\\n struct AggregatorStakeInfo {\\n address aggregator;\\n StakeInfo stakeInfo;\\n }\\n\\n /**\\n * Get counterfactual sender address.\\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\\n * this method always revert, and returns the address in SenderAddressResult error\\n * @param initCode the constructor code to be passed into the UserOperation.\\n */\\n function getSenderAddress(bytes memory initCode) external;\\n\\n /**\\n * simulate full execution of a UserOperation (including both validation and target execution)\\n * this method will always revert with \\\"ExecutionResult\\\".\\n * it performs full validation of the UserOperation, but ignores signature error.\\n * an optional target address is called after the userop succeeds, and its value is returned\\n * (before the entire call is reverted)\\n * Note that in order to collect the the success/failure of the target call, it must be executed\\n * with trace enabled to track the emitted events.\\n * @param op the UserOperation to simulate\\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\\n * are set to the return from that call.\\n * @param targetCallData callData to pass to target address\\n */\\n function simulateHandleOp(\\n UserOperation calldata op,\\n address target,\\n bytes calldata targetCallData\\n ) external;\\n}\\n\",\"keccak256\":\"0x9ccb1b188eda8bbf5f6c2d01bd83c3d8b2b04fcf745283051d31fe96d1d8e40f\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/INonceManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\ninterface INonceManager {\\n /**\\n * Return the next nonce for this sender.\\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\\n * But UserOp with different keys can come with arbitrary order.\\n *\\n * @param sender the account address\\n * @param key the high 192 bit of the nonce\\n * @return nonce a full nonce to pass for next UserOp with this sender.\\n */\\n function getNonce(\\n address sender,\\n uint192 key\\n ) external view returns (uint256 nonce);\\n\\n /**\\n * Manually increment the nonce of the sender.\\n * This method is exposed just for completeness..\\n * Account does NOT need to call it, neither during validation, nor elsewhere,\\n * as the EntryPoint will update the nonce regardless.\\n * Possible use-case is call it with various keys to \\\"initialize\\\" their nonces to one, so that future\\n * UserOperations will not pay extra for the first transaction with a given key.\\n */\\n function incrementNonce(uint192 key) external;\\n}\\n\",\"keccak256\":\"0xce478ad0fa0d18a3b785ac854623029e7ab463d05873dfaa365abfa1bf100912\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IStakeManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8.12;\\n\\n/**\\n * manage deposits and stakes.\\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\\n * stake is value locked for at least \\\"unstakeDelay\\\" by the staked entity.\\n */\\ninterface IStakeManager {\\n event Deposited(address indexed account, uint256 totalDeposit);\\n\\n event Withdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /// Emitted when stake or unstake delay are modified\\n event StakeLocked(\\n address indexed account,\\n uint256 totalStaked,\\n uint256 unstakeDelaySec\\n );\\n\\n /// Emitted once a stake is scheduled for withdrawal\\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\\n\\n event StakeWithdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /**\\n * @param deposit the entity's deposit\\n * @param staked true if this entity is staked.\\n * @param stake actual amount of ether staked for this entity.\\n * @param unstakeDelaySec minimum delay to withdraw the stake.\\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\\n * and the rest fit into a 2nd cell.\\n * 112 bit allows for 10^15 eth\\n * 48 bit for full timestamp\\n * 32 bit allows 150 years for unstake delay\\n */\\n struct DepositInfo {\\n uint112 deposit;\\n bool staked;\\n uint112 stake;\\n uint32 unstakeDelaySec;\\n uint48 withdrawTime;\\n }\\n\\n //API struct used by getStakeInfo and simulateValidation\\n struct StakeInfo {\\n uint256 stake;\\n uint256 unstakeDelaySec;\\n }\\n\\n /// @return info - full deposit information of given account\\n function getDepositInfo(\\n address account\\n ) external view returns (DepositInfo memory info);\\n\\n /// @return the deposit (for gas payment) of the account\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * add to the deposit of the given account\\n */\\n function depositTo(address account) external payable;\\n\\n /**\\n * add to the account's stake - amount and delay\\n * any pending unstake is first cancelled.\\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\\n */\\n function addStake(uint32 _unstakeDelaySec) external payable;\\n\\n /**\\n * attempt to unlock the stake.\\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\\n */\\n function unlockStake() external;\\n\\n /**\\n * withdraw from the (unlocked) stake.\\n * must first call unlockStake and wait for the unstakeDelay to pass\\n * @param withdrawAddress the address to send withdrawn value.\\n */\\n function withdrawStake(address payable withdrawAddress) external;\\n\\n /**\\n * withdraw from the deposit.\\n * @param withdrawAddress the address to send withdrawn value.\\n * @param withdrawAmount the amount to withdraw.\\n */\\n function withdrawTo(\\n address payable withdrawAddress,\\n uint256 withdrawAmount\\n ) external;\\n}\\n\",\"keccak256\":\"0xadcea606c9b7aafe6645441f2154a60f271330b0eee5292a632aa71c1672d546\",\"license\":\"GPL-3.0-only\"},\"contracts/aa-4337/interfaces/UserOperation.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable no-inline-assembly */\\n\\nimport {calldataKeccak} from \\\"../core/Helpers.sol\\\";\\n\\n/**\\n * User Operation struct\\n * @param sender the sender account of this request.\\n * @param nonce unique value the sender uses to verify it is not a replay.\\n * @param initCode if set, the account contract will be created by this constructor/\\n * @param callData the method call to execute on this account.\\n * @param callGasLimit the gas limit passed to the callData method call.\\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\\n * @param maxFeePerGas same as EIP-1559 gas parameter.\\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\\n */\\nstruct UserOperation {\\n address sender;\\n uint256 nonce;\\n bytes initCode;\\n bytes callData;\\n uint256 callGasLimit;\\n uint256 verificationGasLimit;\\n uint256 preVerificationGas;\\n uint256 maxFeePerGas;\\n uint256 maxPriorityFeePerGas;\\n bytes paymasterAndData;\\n bytes signature;\\n}\\n\\n/**\\n * Utility functions helpful when working with UserOperation structs.\\n */\\nlibrary UserOperationLib {\\n function getSender(\\n UserOperation calldata userOp\\n ) internal pure returns (address) {\\n address data;\\n //read sender from userOp, which is first userOp member (saves 800 gas...)\\n assembly {\\n data := calldataload(userOp)\\n }\\n return address(uint160(data));\\n }\\n\\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\\n // pay above what he signed for.\\n function gasPrice(\\n UserOperation calldata userOp\\n ) internal view returns (uint256) {\\n unchecked {\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n if (maxFeePerGas == maxPriorityFeePerGas) {\\n //legacy mode (for networks that don't support basefee opcode)\\n return maxFeePerGas;\\n }\\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\\n }\\n }\\n\\n function pack(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes memory ret) {\\n address sender = getSender(userOp);\\n uint256 nonce = userOp.nonce;\\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\\n bytes32 hashCallData = calldataKeccak(userOp.callData);\\n uint256 callGasLimit = userOp.callGasLimit;\\n uint256 verificationGasLimit = userOp.verificationGasLimit;\\n uint256 preVerificationGas = userOp.preVerificationGas;\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\\n\\n return\\n abi.encode(\\n sender,\\n nonce,\\n hashInitCode,\\n hashCallData,\\n callGasLimit,\\n verificationGasLimit,\\n preVerificationGas,\\n maxFeePerGas,\\n maxPriorityFeePerGas,\\n hashPaymasterAndData\\n );\\n }\\n\\n function hash(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes32) {\\n return keccak256(pack(userOp));\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n}\\n\",\"keccak256\":\"0x2429f5cc546bdee08c7e63858d0dda8491eaa3ab5194df884dc948c1154d2834\",\"license\":\"GPL-3.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IStorageLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"./IDiamondLoupe.sol\\\";\\n\\n/**\\n * @title LoupeFromStorage Interface\\n * @dev Interface contract to function as a loupe facet directly attached to diamond storage of Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IStorageLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facetsFromStorage()\\n external\\n view\\n returns (IDiamondLoupe.Facet[] memory);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n function facetFunctionSelectorsFromStorage(\\n address _facet\\n ) external view returns (bytes4[] memory);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n function facetAddressesFromStorage()\\n external\\n view\\n returns (address[] memory);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n function facetAddressFromStorage(\\n bytes4 _functionSelector\\n ) external view returns (address);\\n}\\n\",\"keccak256\":\"0xdf5dc9c57319e9087628c9cf9404b4f75585b76d1c2f4f59ee796c933967ea5c\",\"license\":\"Apache-2.0\"},\"contracts/facets/interfaces/IAccountFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IEntryPoint} from \\\"../../aa-4337/interfaces/IEntryPoint.sol\\\";\\n\\n/**\\n * @title Account Facet Interface\\n * @dev Interface of module contract that provides the account features and init/unitialization of signer\\n * compatible with EIP-1271 & EIP-4337\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IAccountFacet {\\n event AccountInitialized(\\n IEntryPoint indexed entryPoint,\\n bytes indexed ownerPublicKey\\n );\\n // NOTE: Added Below Event\\n event VerificationSuccess(bytes32);\\n event VerificationFailure(bytes32);\\n\\n error AccountFacet__InitializationFailure();\\n error AccountFacet__RestrictionsFailure();\\n error AccountFacet__NonExistentVerificationFacet();\\n error AccountFacet__CallNotSuccessful();\\n error AccountFacet__InvalidArrayLength();\\n\\n function initialize(\\n address verificationFacet,\\n address anEntryPoint,\\n address facetRegistry,\\n address _defaultFallBack,\\n bytes calldata _ownerPublicKey\\n ) external returns (uint256);\\n\\n function execute(address dest, uint256 value, bytes calldata func) external;\\n\\n function executeBatch(\\n address[] calldata dest,\\n uint256[] calldata value,\\n bytes[] calldata func\\n ) external;\\n}\\n\",\"keccak256\":\"0x74a9cb0b8f2f4a5148e366a401a0354426c536c012c025025d07cc25a4cd5382\",\"license\":\"Apache-2.0\"},\"contracts/infrastructure/DefaultFallbackHandler.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IERC721Receiver} from \\\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\\\";\\nimport {IERC1155Receiver} from \\\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\\\";\\nimport {IERC777Recipient} from \\\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\\\";\\nimport {BaseAccount} from \\\"../aa-4337/core/BaseAccount.sol\\\";\\nimport {DefaultLibDiamond} from \\\"../libraries/DefaultLibDiamond.sol\\\";\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IAccountFacet} from \\\"../facets/interfaces/IAccountFacet.sol\\\";\\nimport {IStorageLoupe} from \\\"../facets/base/interfaces/IStorageLoupe.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\nimport {IERC677Receiver} from \\\"../interfaces/ERC/IERC677Receiver.sol\\\";\\nimport {IERC165} from \\\"../interfaces/ERC/IERC165.sol\\\";\\n\\n/**\\n * @title DefaultFallbackHandler\\n * @dev A default fallback handler for Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract DefaultFallbackHandler is IDiamondLoupe {\\n /**\\n * @notice Sets the middleware diamond for Barz wallet as a fallback handler\\n * @dev This contract is also a diamond that holds the default facets to reduce gas cost for wallet activation.\\n * Within the constructor this conducts diamond cut to initially setup the diamond. This is a non-upgradeable contract\\n * @param _diamondCutFacet Address if diamond cut facet\\n * @param _accountFacet Address account facet\\n * @param _tokenReceiverFacet Address of token receiver facet\\n * @param _diamondLoupeFacet Address of diamond loupe facet\\n */\\n constructor(\\n address _diamondCutFacet,\\n address _accountFacet,\\n address _tokenReceiverFacet,\\n address _diamondLoupeFacet\\n ) payable {\\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](4);\\n bytes4[] memory functionSelectors = new bytes4[](1);\\n functionSelectors[0] = IDiamondCut.diamondCut.selector;\\n\\n bytes4[] memory accountFunctionSelectors = new bytes4[](5);\\n accountFunctionSelectors[0] = IAccountFacet.execute.selector;\\n accountFunctionSelectors[1] = IAccountFacet.executeBatch.selector;\\n accountFunctionSelectors[2] = BaseAccount.validateUserOp.selector;\\n accountFunctionSelectors[3] = BaseAccount.getNonce.selector;\\n accountFunctionSelectors[4] = BaseAccount.entryPoint.selector;\\n\\n bytes4[] memory receiverFacetSelectors = new bytes4[](5);\\n receiverFacetSelectors[0] = IERC721Receiver.onERC721Received.selector;\\n receiverFacetSelectors[1] = IERC1155Receiver.onERC1155Received.selector;\\n receiverFacetSelectors[2] = IERC1155Receiver\\n .onERC1155BatchReceived\\n .selector;\\n receiverFacetSelectors[3] = IERC777Recipient.tokensReceived.selector;\\n receiverFacetSelectors[4] = IERC677Receiver.onTokenTransfer.selector;\\n\\n bytes4[] memory loupeFacetSelectors = new bytes4[](9);\\n loupeFacetSelectors[0] = IDiamondLoupe.facets.selector;\\n loupeFacetSelectors[1] = IDiamondLoupe.facetFunctionSelectors.selector;\\n loupeFacetSelectors[2] = IDiamondLoupe.facetAddresses.selector;\\n loupeFacetSelectors[3] = IDiamondLoupe.facetAddress.selector;\\n loupeFacetSelectors[4] = IERC165.supportsInterface.selector;\\n loupeFacetSelectors[5] = IStorageLoupe.facetsFromStorage.selector;\\n loupeFacetSelectors[6] = IStorageLoupe\\n .facetFunctionSelectorsFromStorage\\n .selector;\\n loupeFacetSelectors[7] = IStorageLoupe\\n .facetAddressesFromStorage\\n .selector;\\n loupeFacetSelectors[8] = IStorageLoupe.facetAddressFromStorage.selector;\\n\\n {\\n cut[0] = IDiamondCut.FacetCut({\\n facetAddress: _diamondCutFacet,\\n action: IDiamondCut.FacetCutAction.Add,\\n functionSelectors: functionSelectors\\n });\\n cut[1] = IDiamondCut.FacetCut({\\n facetAddress: _accountFacet,\\n action: IDiamondCut.FacetCutAction.Add,\\n functionSelectors: accountFunctionSelectors\\n });\\n cut[2] = IDiamondCut.FacetCut({\\n facetAddress: _tokenReceiverFacet,\\n action: IDiamondCut.FacetCutAction.Add,\\n functionSelectors: receiverFacetSelectors\\n });\\n cut[3] = IDiamondCut.FacetCut({\\n facetAddress: _diamondLoupeFacet,\\n action: IDiamondCut.FacetCutAction.Add,\\n functionSelectors: loupeFacetSelectors\\n });\\n\\n DefaultLibDiamond.diamondCut(cut, address(0), \\\"\\\");\\n }\\n }\\n\\n /**\\n * @notice Returns the facet information of call facets registered to this diamond.\\n * @return facets_ The facet struct array including all facet information\\n */\\n function facets() external view override returns (Facet[] memory facets_) {\\n DefaultLibDiamond.DiamondStorage storage ds = DefaultLibDiamond\\n .diamondStorage();\\n uint256 numFacets = ds.facetAddresses.length;\\n facets_ = new Facet[](numFacets);\\n for (uint256 i; i < numFacets; ) {\\n address facetAddress_ = ds.facetAddresses[i];\\n facets_[i].facetAddress = facetAddress_;\\n facets_[i].functionSelectors = ds\\n .facetFunctionSelectors[facetAddress_]\\n .functionSelectors;\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * @notice Gets all the function selectors provided by a facet.\\n * @param _facet The facet address.\\n * @return facetFunctionSelectors_\\n */\\n function facetFunctionSelectors(\\n address _facet\\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\\n facetFunctionSelectors_ = DefaultLibDiamond\\n .diamondStorage()\\n .facetFunctionSelectors[_facet]\\n .functionSelectors;\\n }\\n\\n /**\\n * @notice Get all the facet addresses used by a diamond.\\n * @return facetAddresses_\\n */\\n function facetAddresses()\\n external\\n view\\n override\\n returns (address[] memory facetAddresses_)\\n {\\n facetAddresses_ = DefaultLibDiamond.diamondStorage().facetAddresses;\\n }\\n\\n /** @notice Gets the facet that supports the given selector.\\n * @dev If facet is not found return address(0).\\n * @param _functionSelector The function selector.\\n * @return facetAddress_ The facet address.\\n */\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view override returns (address facetAddress_) {\\n facetAddress_ = DefaultLibDiamond\\n .diamondStorage()\\n .selectorToFacetAndPosition[_functionSelector]\\n .facetAddress;\\n }\\n}\\n\",\"keccak256\":\"0xa482fe778481e34e9fb3c4074231f8048437e934c0ca9a0c78e8e61d3a24470a\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.21;\\n\\ninterface IERC165 {\\n /// @notice Query if a contract implements an interface\\n /// @param interfaceId The interface identifier, as specified in ERC-165\\n /// @dev Interface identification is specified in ERC-165. This function\\n /// uses less than 30,000 gas.\\n /// @return `true` if the contract implements `interfaceID` and\\n /// `interfaceID` is not 0xffffffff, `false` otherwise\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xbb7f07e170898793c5535cc4b7e8944c4b990a631ac806d0b788e794abc788a3\",\"license\":\"MIT\"},\"contracts/interfaces/ERC/IERC677Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC677Receiver {\\n function onTokenTransfer(\\n address sender,\\n uint value,\\n bytes calldata data\\n ) external pure returns (bool);\\n}\\n\",\"keccak256\":\"0x4c1631cf45ea6daac0ec158c3edb9453099130b6b64f697004b83f95aa1f7350\",\"license\":\"Apache-2.0\"},\"contracts/libraries/DefaultLibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary DefaultLibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (\\n uint256 facetIndex;\\n facetIndex < _diamondCut.length;\\n facetIndex++\\n ) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(\\n address _facetAddress,\\n bytes4[] memory _functionSelectors\\n ) internal {\\n uint256 funcSelectorsLength = _functionSelectors.length;\\n require(\\n funcSelectorsLength > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _facetAddress != address(0),\\n \\\"LibDiamondCut: Add facet can't be address(0)\\\"\\n );\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (\\n uint256 selectorIndex;\\n selectorIndex < funcSelectorsLength;\\n selectorIndex++\\n ) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds\\n .selectorToFacetAndPosition[selector]\\n .facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(\\n address _facetAddress,\\n bytes4[] memory _functionSelectors\\n ) internal {\\n uint256 funcSelectorsLength = _functionSelectors.length;\\n require(\\n funcSelectorsLength > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _facetAddress != address(0),\\n \\\"LibDiamondCut: Replace facet can't be address(0)\\\"\\n );\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (\\n uint256 selectorIndex;\\n selectorIndex < funcSelectorsLength;\\n selectorIndex++\\n ) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds\\n .selectorToFacetAndPosition[selector]\\n .facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same facet\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(\\n address _facetAddress,\\n bytes4[] memory _functionSelectors\\n ) internal {\\n uint256 funcSelectorsLength = _functionSelectors.length;\\n require(\\n funcSelectorsLength > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(\\n _facetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n for (\\n uint256 selectorIndex;\\n selectorIndex < funcSelectorsLength;\\n selectorIndex++\\n ) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds\\n .selectorToFacetAndPosition[selector]\\n .facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(\\n DiamondStorage storage ds,\\n address _facetAddress\\n ) internal {\\n enforceHasContractCode(\\n _facetAddress,\\n \\\"LibDiamondCut: New facet has no code\\\"\\n );\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds\\n .facetAddresses\\n .length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds\\n .selectorToFacetAndPosition[_selector]\\n .functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(\\n _selector\\n );\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(\\n _facetAddress != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // an immutable function is a function defined directly in a diamond\\n require(\\n _facetAddress != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds\\n .selectorToFacetAndPosition[_selector]\\n .functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors[lastSelectorPosition];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n selectorPosition\\n ] = lastSelector;\\n ds\\n .selectorToFacetAndPosition[lastSelector]\\n .functionSelectorPosition = uint96(selectorPosition);\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[\\n lastFacetAddressPosition\\n ];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds\\n .facetFunctionSelectors[lastFacetAddress]\\n .facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds\\n .facetFunctionSelectors[_facetAddress]\\n .facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x1b08f332d62919288bb1f0d154ca4b85f4e167d2a06e680f8ec93dba65be3be1\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x6080604052604051620020183803806200201883398101604081905262000026916200156b565b60408051600480825260a08201909252600091816020015b604080516060808201835260008083526020830152918101919091528152602001906001900390816200003e5750506040805160018082528183019092529192506000919060208083019080368337019050509050631f931c1c60e01b81600081518110620000b157620000b1620015c8565b6001600160e01b03199290921660209283029190910182015260408051600580825260c08201909252600092909190820160a08036833701905050905063b61d27f660e01b816000815181106200010c576200010c620015c8565b6001600160e01b03199092166020928302919091019091015280516323f0ed1560e11b9082906001908110620001465762000146620015c8565b6001600160e01b0319909216602092830291909101909101528051633a871cdd60e01b9082906002908110620001805762000180620015c8565b6001600160e01b0319909216602092830291909101909101528051631a10fa5160e31b9082906003908110620001ba57620001ba620015c8565b6001600160e01b031990921660209283029190910190910152805163586b48ff60e11b9082906004908110620001f457620001f4620015c8565b6001600160e01b03199290921660209283029190910182015260408051600580825260c08201909252600092909190820160a08036833701905050905063150b7a0260e01b816000815181106200024f576200024f620015c8565b6001600160e01b031990921660209283029190910190910152805163f23a6e6160e01b9082906001908110620002895762000289620015c8565b6001600160e01b031990921660209283029190910190910152805163bc197c8160e01b9082906002908110620002c357620002c3620015c8565b6001600160e01b03199092166020928302919091019091015280516223de2960e01b9082906003908110620002fc57620002fc620015c8565b6001600160e01b0319909216602092830291909101909101528051635260769b60e11b9082906004908110620003365762000336620015c8565b6001600160e01b0319929092166020928302919091018201526040805160098082526101408201909252600092909190820161012080368337019050509050637a0ed62760e01b81600081518110620003935762000393620015c8565b6001600160e01b03199092166020928302919091019091015280516356fe50af60e11b9082906001908110620003cd57620003cd620015c8565b6001600160e01b03199092166020928302919091019091015280516314bbdacb60e21b9082906002908110620004075762000407620015c8565b6001600160e01b03199092166020928302919091019091015280516366ffd66360e11b9082906003908110620004415762000441620015c8565b6001600160e01b03199092166020928302919091019091015280516301ffc9a760e01b90829060049081106200047b576200047b620015c8565b6001600160e01b031990921660209283029190910190910152805163f9796ccf60e01b9082906005908110620004b557620004b5620015c8565b6001600160e01b031990921660209283029190910190910152805162d2a81160e11b9082906006908110620004ee57620004ee620015c8565b6001600160e01b031990921660209283029190910190910152805163d42139a960e01b9082906007908110620005285762000528620015c8565b6001600160e01b03199092166020928302919091019091015280516371d17b7f60e11b9082906008908110620005625762000562620015c8565b6001600160e01b031990921660209283029190910182015260408051606081019091526001600160a01b038b168152908101600081526020018581525085600081518110620005b557620005b5620015c8565b60200260200101819052506040518060600160405280896001600160a01b0316815260200160006002811115620005f057620005f0620015de565b815260200184815250856001815181106200060f576200060f620015c8565b60200260200101819052506040518060600160405280886001600160a01b03168152602001600060028111156200064a576200064a620015de565b81526020018381525085600281518110620006695762000669620015c8565b60200260200101819052506040518060600160405280876001600160a01b0316815260200160006002811115620006a457620006a4620015de565b81526020018281525085600381518110620006c357620006c3620015c8565b6020026020010181905250620006f1856000604051806020016040528060008152506200070060201b60201c565b5050505050505050506200184c565b60005b83518110156200090c576000848281518110620007245762000724620015c8565b602002602001015160200151905060006002811115620007485762000748620015de565b8160028111156200075d576200075d620015de565b03620007bb57620007b58583815181106200077c576200077c620015c8565b6020026020010151600001518684815181106200079d576200079d620015c8565b6020026020010151604001516200095b60201b60201c565b620008f6565b6001816002811115620007d257620007d2620015de565b036200082a57620007b5858381518110620007f157620007f1620015c8565b602002602001015160000151868481518110620008125762000812620015c8565b60200260200101516040015162000bf760201b60201c565b6002816002811115620008415762000841620015de565b036200089957620007b5858381518110620008605762000860620015c8565b602002602001015160000151868481518110620008815762000881620015c8565b60200260200101516040015162000ea160201b60201c565b60405162461bcd60e51b815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f727265637420466163657443756044820152663a20b1ba34b7b760c91b60648201526084015b60405180910390fd5b508062000903816200160a565b91505062000703565b507f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb67383838360405162000942939291906200167a565b60405180910390a162000956828262001005565b505050565b805180620009af5760405162461bcd60e51b815260206004820152602b602482015260008051602062001ff883398151915260448201526a1858d95d081d1bc818dd5d60aa1b6064820152608401620008ed565b60008051602062001f8c8339815191526001600160a01b03841662000a2c5760405162461bcd60e51b815260206004820152602c60248201527f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260448201526b65206164647265737328302960a01b6064820152608401620008ed565b6001600160a01b0384166000908152600182016020526040812054906001600160601b038216900362000a655762000a658286620010dd565b60005b8381101562000bef57600085828151811062000a885762000a88620015c8565b6020908102919091018101516001600160e01b031981166000908152918690526040909120549091506001600160a01b0316801562000b305760405162461bcd60e51b815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c72656164792065786973747300000000000000000000006064820152608401620008ed565b6001600160e01b0319821660008181526020878152604080832080546001600160a01b03908116600160a01b6001600160601b038c16021782558d168085526001808c0185529285208054938401815585528385206008840401805463ffffffff60079095166004026101000a948502191660e08a901c94909402939093179092559390925287905281546001600160a01b0319161790558362000bd48162001781565b9450505050808062000be6906200160a565b91505062000a68565b505050505050565b80518062000c4b5760405162461bcd60e51b815260206004820152602b602482015260008051602062001ff883398151915260448201526a1858d95d081d1bc818dd5d60aa1b6064820152608401620008ed565b60008051602062001f8c8339815191526001600160a01b03841662000ccc5760405162461bcd60e51b815260206004820152603060248201527f4c69624469616d6f6e644375743a205265706c6163652066616365742063616e60448201526f2774206265206164647265737328302960801b6064820152608401620008ed565b6001600160a01b0384166000908152600182016020526040812054906001600160601b038216900362000d055762000d058286620010dd565b60005b8381101562000bef57600085828151811062000d285762000d28620015c8565b6020908102919091018101516001600160e01b031981166000908152918690526040909120549091506001600160a01b03908116908816810362000dd55760405162461bcd60e51b815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d6520666163657400000000000000000000006064820152608401620008ed565b62000de28582846200114a565b6001600160e01b0319821660008181526020878152604080832080546001600160a01b03908116600160a01b6001600160601b038c16021782558d168085526001808c0185529285208054938401815585528385206008840401805463ffffffff60079095166004026101000a948502191660e08a901c94909402939093179092559390925287905281546001600160a01b0319161790558362000e868162001781565b9450505050808062000e98906200160a565b91505062000d08565b80518062000ef55760405162461bcd60e51b815260206004820152602b602482015260008051602062001ff883398151915260448201526a1858d95d081d1bc818dd5d60aa1b6064820152608401620008ed565b60008051602062001f8c8339815191526001600160a01b0384161562000f845760405162461bcd60e51b815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d7573742062652061646472657373283029000000000000000000006064820152608401620008ed565b60005b8281101562000ffe57600084828151811062000fa75762000fa7620015c8565b6020908102919091018101516001600160e01b031981166000908152918590526040909120549091506001600160a01b031662000fe68482846200114a565b5050808062000ff5906200160a565b91505062000f87565b5050505050565b6001600160a01b03821662001018575050565b6200103d8260405180606001604052806028815260200162001fac602891396200152a565b600080836001600160a01b0316836040516200105a9190620017b2565b600060405180830381855af49150503d806000811462001097576040519150601f19603f3d011682016040523d82523d6000602084013e6200109c565b606091505b509150915081620010d757805115620010b85780518082602001fd5b838360405163192105d760e01b8152600401620008ed929190620017d0565b50505050565b620011028160405180606001604052806024815260200162001fd4602491396200152a565b6002820180546001600160a01b0390921660008181526001948501602090815260408220860185905594840183559182529290200180546001600160a01b0319169091179055565b6001600160a01b038216620011c85760405162461bcd60e51b815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608401620008ed565b306001600160a01b03831603620012395760405162461bcd60e51b815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201526d3a30b1363290333ab731ba34b7b760911b6064820152608401620008ed565b6001600160e01b03198116600090815260208481526040808320546001600160a01b0386168452600180880190935290832054600160a01b9091046001600160601b031692916200128a91620017fe565b905080821462001383576001600160a01b03841660009081526001860160205260408120805483908110620012c357620012c3620015c8565b600091825260208083206008830401546001600160a01b038916845260018a019091526040909220805460079092166004026101000a90920460e01b925082919085908110620013175762001317620015c8565b600091825260208083206008830401805463ffffffff60079094166004026101000a938402191660e09590951c929092029390931790556001600160e01b03199290921682528690526040902080546001600160a01b0316600160a01b6001600160601b038516021790555b6001600160a01b03841660009081526001860160205260409020805480620013af57620013af6200181a565b60008281526020808220600860001990940193840401805463ffffffff600460078716026101000a0219169055919092556001600160e01b0319851682528690526040812081905581900362000ffe5760028501546000906200141590600190620017fe565b6001600160a01b0386166000908152600180890160205260409091200154909150808214620014cb576000876002018381548110620014585762001458620015c8565b6000918252602090912001546002890180546001600160a01b0390921692508291849081106200148c576200148c620015c8565b600091825260208083209190910180546001600160a01b0319166001600160a01b03948516179055929091168152600189810190925260409020018190555b86600201805480620014e157620014e16200181a565b60008281526020808220830160001990810180546001600160a01b03191690559092019092556001600160a01b0388168252600189810190915260408220015550505050505050565b813b8181620010d75760405162461bcd60e51b8152600401620008ed919062001830565b80516001600160a01b03811681146200156657600080fd5b919050565b600080600080608085870312156200158257600080fd5b6200158d856200154e565b93506200159d602086016200154e565b9250620015ad604086016200154e565b9150620015bd606086016200154e565b905092959194509250565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016200161f576200161f620015f4565b5060010190565b60005b838110156200164357818101518382015260200162001629565b50506000910152565b600081518084526200166681602086016020860162001626565b601f01601f19169290920160200192915050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b848110156200174f57898403607f19018652815180516001600160a01b03168552838101518986019060038110620016eb57634e487b7160e01b600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b80831015620017395783516001600160e01b03191682529286019260019290920191908601906200170d565b50978501979550505090820190600101620016a3565b50506001600160a01b038a169088015286810360408801526200177381896200164c565b9a9950505050505050505050565b60006001600160601b038281166002600160601b03198101620017a857620017a8620015f4565b6001019392505050565b60008251620017c681846020870162001626565b9190910192915050565b6001600160a01b0383168152604060208201819052600090620017f6908301846200164c565b949350505050565b81810381811115620018145762001814620015f4565b92915050565b634e487b7160e01b600052603160045260246000fd5b6020815260006200184560208301846200164c565b9392505050565b610730806200185c6000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806352ef6b2c146100515780637a0ed6271461006f578063adfca15e14610084578063cdffacc6146100a4575b600080fd5b610059610140565b60405161006691906104ab565b60405180910390f35b6100776101d1565b6040516100669190610562565b61009761009236600461060a565b6103d1565b6040516100669190610647565b61011b6100b236600461065a565b7fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610066565b60607f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6002018054806020026020016040519081016040528092919081815260200182805480156101c757602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161019c575b5050505050905090565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f908067ffffffffffffffff8111156102315761023161069c565b60405190808252806020026020018201604052801561027757816020015b60408051808201909152600081526060602082015281526020019060019003908161024f5790505b50925060005b818110156103cb57600083600201828154811061029c5761029c6106cb565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050808583815181106102dc576102dc6106cb565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff928316905290821660009081526001860182526040908190208054825181850281018501909352808352919290919083018282801561039d57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161034a5790505b50505050508583815181106103b4576103b46106cb565b60209081029190910181015101525060010161027d565b50505090565b73ffffffffffffffffffffffffffffffffffffffff811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4920602090815260409182902080548351818402810184019094528084526060939283018282801561049f57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161044c5790505b50505050509050919050565b6020808252825182820181905260009190848201906040850190845b818110156104f957835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016104c7565b50909695505050505050565b600081518084526020808501945080840160005b838110156105575781517fffffffff000000000000000000000000000000000000000000000000000000001687529582019590820190600101610519565b509495945050505050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b838110156105fc578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00185528151805173ffffffffffffffffffffffffffffffffffffffff1684528701518784018790526105e987850182610505565b9588019593505090860190600101610589565b509098975050505050505050565b60006020828403121561061c57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461064057600080fd5b9392505050565b6020815260006106406020830184610505565b60006020828403121561066c57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461064057600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea264697066735822122024a872696a5ad50024326567061c50adea63ff0d49edf0ac60339459d33d571664736f6c63430008150033183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f4c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a204e657720666163657420686173206e6f20636f64654c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e2066", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806352ef6b2c146100515780637a0ed6271461006f578063adfca15e14610084578063cdffacc6146100a4575b600080fd5b610059610140565b60405161006691906104ab565b60405180910390f35b6100776101d1565b6040516100669190610562565b61009761009236600461060a565b6103d1565b6040516100669190610647565b61011b6100b236600461065a565b7fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610066565b60607f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6002018054806020026020016040519081016040528092919081815260200182805480156101c757602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161019c575b5050505050905090565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f908067ffffffffffffffff8111156102315761023161069c565b60405190808252806020026020018201604052801561027757816020015b60408051808201909152600081526060602082015281526020019060019003908161024f5790505b50925060005b818110156103cb57600083600201828154811061029c5761029c6106cb565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050808583815181106102dc576102dc6106cb565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff928316905290821660009081526001860182526040908190208054825181850281018501909352808352919290919083018282801561039d57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161034a5790505b50505050508583815181106103b4576103b46106cb565b60209081029190910181015101525060010161027d565b50505090565b73ffffffffffffffffffffffffffffffffffffffff811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4920602090815260409182902080548351818402810184019094528084526060939283018282801561049f57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161044c5790505b50505050509050919050565b6020808252825182820181905260009190848201906040850190845b818110156104f957835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016104c7565b50909695505050505050565b600081518084526020808501945080840160005b838110156105575781517fffffffff000000000000000000000000000000000000000000000000000000001687529582019590820190600101610519565b509495945050505050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b838110156105fc578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00185528151805173ffffffffffffffffffffffffffffffffffffffff1684528701518784018790526105e987850182610505565b9588019593505090860190600101610589565b509098975050505050505050565b60006020828403121561061c57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461064057600080fd5b9392505050565b6020815260006106406020830184610505565b60006020828403121561066c57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461064057600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea264697066735822122024a872696a5ad50024326567061c50adea63ff0d49edf0ac60339459d33d571664736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "A default fallback handler for Barz", + "kind": "dev", + "methods": { + "constructor": { + "details": "This contract is also a diamond that holds the default facets to reduce gas cost for wallet activation. Within the constructor this conducts diamond cut to initially setup the diamond. This is a non-upgradeable contract", + "params": { + "_accountFacet": "Address account facet", + "_diamondCutFacet": "Address if diamond cut facet", + "_diamondLoupeFacet": "Address of diamond loupe facet", + "_tokenReceiverFacet": "Address of token receiver facet" + } + }, + "facetAddress(bytes4)": { + "details": "If facet is not found return address(0).", + "params": { + "_functionSelector": "The function selector." + }, + "returns": { + "facetAddress_": "The facet address." + } + }, + "facetAddresses()": { + "returns": { + "facetAddresses_": "facetAddresses_" + } + }, + "facetFunctionSelectors(address)": { + "params": { + "_facet": "The facet address." + }, + "returns": { + "facetFunctionSelectors_": "facetFunctionSelectors_" + } + }, + "facets()": { + "returns": { + "facets_": "The facet struct array including all facet information" + } + } + }, + "title": "DefaultFallbackHandler", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "constructor": { + "notice": "Sets the middleware diamond for Barz wallet as a fallback handler" + }, + "facetAddress(bytes4)": { + "notice": "Gets the facet that supports the given selector." + }, + "facetAddresses()": { + "notice": "Get all the facet addresses used by a diamond." + }, + "facetFunctionSelectors(address)": { + "notice": "Gets all the function selectors provided by a facet." + }, + "facets()": { + "notice": "Returns the facet information of call facets registered to this diamond." + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/avalanche/DiamondCutFacet.json b/deployments/avalanche/DiamondCutFacet.json new file mode 100644 index 0000000..cb410e9 --- /dev/null +++ b/deployments/avalanche/DiamondCutFacet.json @@ -0,0 +1,856 @@ +{ + "address": "0x0B9504140771C3688Ff041917192277D2f52E1e0", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_securityManager", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "CallerNotGuardian", + "type": "error" + }, + { + "inputs": [], + "name": "CallerNotGuardianOrOwner", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__CannotRevokeUnapproved", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__DuplicateApproval", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InsufficientApprovers", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidApprovalValidationPeriod", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidApprover", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidApproverSignature", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidArrayLength", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidInitAddress", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidRouteWithGuardian", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidRouteWithoutGuardian", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__LackOfOwnerApproval", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__OwnerAlreadyApproved", + "type": "error" + }, + { + "inputs": [], + "name": "DuplicateApprover", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_initializationContractAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "InitializationFunctionReverted", + "type": "error" + }, + { + "inputs": [], + "name": "UnregisteredFacetAndSelectors", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroApproverLength", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "indexed": false, + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "DiamondCut", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "diamondCut", + "type": "tuple[]" + } + ], + "name": "DiamondCutApprovalRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "diamondCut", + "type": "tuple[]" + } + ], + "name": "DiamondCutApproved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + }, + { + "indexed": false, + "internalType": "bool", + "name": "_lag", + "type": "bool" + } + ], + "name": "SupportsInterfaceUpdated", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_diamondCutHash", + "type": "bytes32" + }, + { + "internalType": "address[]", + "name": "_approvers", + "type": "address[]" + } + ], + "name": "_checkDuplicateOnChainApprover", + "outputs": [], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + } + ], + "name": "approveDiamondCut", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "diamondCut", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "internalType": "address[]", + "name": "_approvers", + "type": "address[]" + }, + { + "internalType": "bytes[]", + "name": "_signatures", + "type": "bytes[]" + } + ], + "name": "diamondCutWithGuardian", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_diamondCutHash", + "type": "bytes32" + } + ], + "name": "getDiamondCutApprovalCountWithTimeValidity", + "outputs": [ + { + "internalType": "uint256", + "name": "approvalCount", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + } + ], + "name": "getDiamondCutHash", + "outputs": [ + { + "internalType": "bytes32", + "name": "cutHash", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getDiamondCutNonce", + "outputs": [ + { + "internalType": "uint128", + "name": "cutNonce", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_diamondCutHash", + "type": "bytes32" + } + ], + "name": "getOwnerCutApprovalWithTimeValidity", + "outputs": [ + { + "internalType": "bool", + "name": "isApprovedByOwner", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_diamondCutHash", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "_approver", + "type": "address" + } + ], + "name": "isCutApproved", + "outputs": [ + { + "internalType": "bool", + "name": "isApproved", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + } + ], + "name": "revokeDiamondCutApproval", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "securityManager", + "outputs": [ + { + "internalType": "contract ISecurityManager", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_interfaceId", + "type": "bytes4" + }, + { + "internalType": "bool", + "name": "_flag", + "type": "bool" + } + ], + "name": "updateSupportsInterface", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0xd9d99750e34bdd46f0cb39defcbff2dac4d30ad645ae25fd3c7c58ff052883e0", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 281, + "gasUsed": "3078987", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x704973d960e79f43206406dda12d048f905a3e7c5f0f03bdb2c5b56d09f0792f", + "transactionHash": "0xd9d99750e34bdd46f0cb39defcbff2dac4d30ad645ae25fd3c7c58ff052883e0", + "logs": [], + "blockNumber": 38010718, + "cumulativeGasUsed": "9688153", + "status": 1, + "byzantium": true + }, + "args": [ + "0xcBe266adbfd7CB32988128e7f37b7c8b3C5521A8" + ], + "numDeployments": 3, + "solcInputHash": "4356503edd8ae34e73cb6dd1c8e2fc8a", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_securityManager\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"CallerNotGuardian\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallerNotGuardianOrOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__CannotRevokeUnapproved\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__DuplicateApproval\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InsufficientApprovers\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidApprovalValidationPeriod\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidApprover\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidApproverSignature\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidArrayLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidInitAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidRouteWithGuardian\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidRouteWithoutGuardian\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__LackOfOwnerApproval\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__OwnerAlreadyApproved\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateApprover\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_initializationContractAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"InitializationFunctionReverted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnregisteredFacetAndSelectors\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroApproverLength\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"DiamondCut\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"diamondCut\",\"type\":\"tuple[]\"}],\"name\":\"DiamondCutApprovalRevoked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"diamondCut\",\"type\":\"tuple[]\"}],\"name\":\"DiamondCutApproved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"_lag\",\"type\":\"bool\"}],\"name\":\"SupportsInterfaceUpdated\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_diamondCutHash\",\"type\":\"bytes32\"},{\"internalType\":\"address[]\",\"name\":\"_approvers\",\"type\":\"address[]\"}],\"name\":\"_checkDuplicateOnChainApprover\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"}],\"name\":\"approveDiamondCut\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"diamondCut\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"internalType\":\"address[]\",\"name\":\"_approvers\",\"type\":\"address[]\"},{\"internalType\":\"bytes[]\",\"name\":\"_signatures\",\"type\":\"bytes[]\"}],\"name\":\"diamondCutWithGuardian\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_diamondCutHash\",\"type\":\"bytes32\"}],\"name\":\"getDiamondCutApprovalCountWithTimeValidity\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"approvalCount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"}],\"name\":\"getDiamondCutHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"cutHash\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDiamondCutNonce\",\"outputs\":[{\"internalType\":\"uint128\",\"name\":\"cutNonce\",\"type\":\"uint128\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_diamondCutHash\",\"type\":\"bytes32\"}],\"name\":\"getOwnerCutApprovalWithTimeValidity\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isApprovedByOwner\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_diamondCutHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"_approver\",\"type\":\"address\"}],\"name\":\"isCutApproved\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isApproved\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"}],\"name\":\"revokeDiamondCutApproval\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"securityManager\",\"outputs\":[{\"internalType\":\"contract ISecurityManager\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_interfaceId\",\"type\":\"bytes4\"},{\"internalType\":\"bool\",\"name\":\"_flag\",\"type\":\"bool\"}],\"name\":\"updateSupportsInterface\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"Responsible for adding/removing/replace facets in Barz\",\"kind\":\"dev\",\"methods\":{\"_checkDuplicateOnChainApprover(bytes32,address[])\":{\"params\":{\"_approvers\":\"List of approver addresses\",\"_diamondCutHash\":\"Hash of diamondCut information including the facet addresses and function selectors\"}},\"approveDiamondCut((address,uint8,bytes4[])[])\":{\"params\":{\"_diamondCut\":\"Contains the facet addresses and function selectors\"}},\"constructor\":{\"params\":{\"_securityManager\":\"Security Manager contract that holds the security related variables for all wallets\"}},\"diamondCut((address,uint8,bytes4[])[],address,bytes)\":{\"params\":{\"_diamondCut\":\"Contains the facet addresses and function selectors\",\"_init\":\"The address of the contract or facet to execute _calldata. It's prohibited in Barz\"}},\"diamondCutWithGuardian((address,uint8,bytes4[])[],address[],bytes[])\":{\"params\":{\"_approvers\":\"Guardian or owner address that approves the diamond cut\",\"_diamondCut\":\"Contains the facet addresses and function selectors\",\"_signatures\":\"Signature of Guardians or owner that approves the diamond cut\"}},\"getDiamondCutApprovalCountWithTimeValidity(bytes32)\":{\"params\":{\"_diamondCutHash\":\"Hash of diamondCut information including the facet addresses and function selectors\"}},\"getDiamondCutHash((address,uint8,bytes4[])[])\":{\"params\":{\"_diamondCut\":\"Contains the facet addresses and function selectors\"},\"returns\":{\"cutHash\":\"Diamond Cut Hash\"}},\"getDiamondCutNonce()\":{\"details\":\"This method fetches the nonce from diamond cut storage\",\"returns\":{\"cutNonce\":\"Nonce of diamond cut to protect from reply attacks\"}},\"getOwnerCutApprovalWithTimeValidity(bytes32)\":{\"params\":{\"_diamondCutHash\":\"Hash of diamondCut information including the facet addresses and function selectors\"},\"returns\":{\"isApprovedByOwner\":\"Bool value showing if the owner approved the cut\"}},\"isCutApproved(bytes32,address)\":{\"params\":{\"_approver\":\"Address of approver\",\"_diamondCutHash\":\"Hash of diamondCut information including the facet addresses and function selectors\"},\"returns\":{\"isApproved\":\"Bool value showing if the approver approved the cut\"}},\"revokeDiamondCutApproval((address,uint8,bytes4[])[])\":{\"params\":{\"_diamondCut\":\"Contains the facet addresses and function selectors\"}},\"updateSupportsInterface(bytes4,bool)\":{\"params\":{\"_flag\":\"Bool value to update the mapping of the given interface ID\",\"_interfaceId\":\"InterfaceID to update the mapping\"}}},\"title\":\"DiamondCut Facet\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"_checkDuplicateOnChainApprover(bytes32,address[])\":{\"notice\":\"Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval Approvers who approved on-chain should not be included in the off-chain approval\"},\"approveDiamondCut((address,uint8,bytes4[])[])\":{\"notice\":\"Approves diamond cut. This can only be called directly from guardian or owner\"},\"constructor\":{\"notice\":\"This constructor sets the Security Manager address which is an immutable variable. Immutable variables do not impact the storage of diamond\"},\"diamondCut((address,uint8,bytes4[])[],address,bytes)\":{\"notice\":\"Add/replace/remove any number of functions and optionally execute a function with delegatecall when guardians don't exist\"},\"diamondCutWithGuardian((address,uint8,bytes4[])[],address[],bytes[])\":{\"notice\":\"Add/replace/remove any number of functions and optionally execute a function with delegatecall when guardians exist\"},\"getDiamondCutApprovalCountWithTimeValidity(bytes32)\":{\"notice\":\"Gets the number of approvals of diamond cut from guardians\"},\"getDiamondCutHash((address,uint8,bytes4[])[])\":{\"notice\":\"Returns the diamond cut hash. This function ensures that this hash is safe from replay attack by including salt, address, chainId, and nonce, etc.\"},\"getDiamondCutNonce()\":{\"notice\":\"Returns the diamond cut nonce of this wallet\"},\"getOwnerCutApprovalWithTimeValidity(bytes32)\":{\"notice\":\"Returns if the owner has approved the diamond cut\"},\"isCutApproved(bytes32,address)\":{\"notice\":\"Returns if the given approver has approved the diamond cut\"},\"revokeDiamondCutApproval((address,uint8,bytes4[])[])\":{\"notice\":\"Revokes the approval of diamond cut. This can only be called directly from guardian or owner\"},\"updateSupportsInterface(bytes4,bool)\":{\"notice\":\"Updates the flag for the interfaceId\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/base/DiamondCutFacet.sol\":\"DiamondCutFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/interfaces/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC1271 standard signature validation method for\\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC1271 {\\n /**\\n * @dev Should return whether the signature provided is valid for the provided data\\n * @param hash Hash of the data to be signed\\n * @param signature Signature byte array associated with _data\\n */\\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\\n}\\n\",\"keccak256\":\"0x0705a4b1b86d7b0bd8432118f226ba139c44b9dcaba0a6eafba2dd7d0639c544\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./math/Math.sol\\\";\\nimport \\\"./math/SignedMath.sol\\\";\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n uint256 length = Math.log10(value) + 1;\\n string memory buffer = new string(length);\\n uint256 ptr;\\n /// @solidity memory-safe-assembly\\n assembly {\\n ptr := add(buffer, add(32, length))\\n }\\n while (true) {\\n ptr--;\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\\n }\\n value /= 10;\\n if (value == 0) break;\\n }\\n return buffer;\\n }\\n }\\n\\n /**\\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\\n */\\n function toString(int256 value) internal pure returns (string memory) {\\n return string(abi.encodePacked(value < 0 ? \\\"-\\\" : \\\"\\\", toString(SignedMath.abs(value))));\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n return toHexString(value, Math.log256(value) + 1);\\n }\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n\\n /**\\n * @dev Returns true if the two strings are equal.\\n */\\n function equal(string memory a, string memory b) internal pure returns (bool) {\\n return keccak256(bytes(a)) == keccak256(bytes(b));\\n }\\n}\\n\",\"keccak256\":\"0x3088eb2868e8d13d89d16670b5f8612c4ab9ff8956272837d8e90106c59c14a0\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Strings.sol\\\";\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSA {\\n enum RecoverError {\\n NoError,\\n InvalidSignature,\\n InvalidSignatureLength,\\n InvalidSignatureS,\\n InvalidSignatureV // Deprecated in v4.8\\n }\\n\\n function _throwError(RecoverError error) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert(\\\"ECDSA: invalid signature\\\");\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert(\\\"ECDSA: invalid signature length\\\");\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert(\\\"ECDSA: invalid signature 's' value\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature` or error string. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n *\\n * Documentation for signature generation:\\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n return tryRecover(hash, v, r, s);\\n } else {\\n return (address(0), RecoverError.InvalidSignatureLength);\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature`. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, signature);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\\n uint8 v = uint8((uint256(vs) >> 255) + 27);\\n return tryRecover(hash, v, r, s);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n *\\n * _Available since v4.2._\\n */\\n function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\\n // the valid range for s in (301): 0 < s < secp256k1n \\u00f7 2 + 1, and for v in (302): v \\u2208 {27, 28}. Most\\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\\n //\\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\\n // these malleable signatures as well.\\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n return (address(0), RecoverError.InvalidSignatureS);\\n }\\n\\n // If the signature is valid (and not malleable), return the signer address\\n address signer = ecrecover(hash, v, r, s);\\n if (signer == address(0)) {\\n return (address(0), RecoverError.InvalidSignature);\\n }\\n\\n return (signer, RecoverError.NoError);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore(0x00, \\\"\\\\x19Ethereum Signed Message:\\\\n32\\\")\\n mstore(0x1c, hash)\\n message := keccak256(0x00, 0x3c)\\n }\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from `s`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n\\\", Strings.toString(s.length), s));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Typed Data, created from a\\n * `domainSeparator` and a `structHash`. This produces hash corresponding\\n * to the one signed with the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n * JSON-RPC method as part of EIP-712.\\n *\\n * See {recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n let ptr := mload(0x40)\\n mstore(ptr, \\\"\\\\x19\\\\x01\\\")\\n mstore(add(ptr, 0x02), domainSeparator)\\n mstore(add(ptr, 0x22), structHash)\\n data := keccak256(ptr, 0x42)\\n }\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Data with intended validator, created from a\\n * `validator` and `data` according to the version 0 of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x00\\\", validator, data));\\n }\\n}\\n\",\"keccak256\":\"0x809bc3edb4bcbef8263fa616c1b60ee0004b50a8a1bfa164d8f57fd31f520c58\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/SignatureChecker.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./ECDSA.sol\\\";\\nimport \\\"../../interfaces/IERC1271.sol\\\";\\n\\n/**\\n * @dev Signature verification helper that can be used instead of `ECDSA.recover` to seamlessly support both ECDSA\\n * signatures from externally owned accounts (EOAs) as well as ERC1271 signatures from smart contract wallets like\\n * Argent and Gnosis Safe.\\n *\\n * _Available since v4.1._\\n */\\nlibrary SignatureChecker {\\n /**\\n * @dev Checks if a signature is valid for a given signer and data hash. If the signer is a smart contract, the\\n * signature is validated against that smart contract using ERC1271, otherwise it's validated using `ECDSA.recover`.\\n *\\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\\n */\\n function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature) internal view returns (bool) {\\n (address recovered, ECDSA.RecoverError error) = ECDSA.tryRecover(hash, signature);\\n return\\n (error == ECDSA.RecoverError.NoError && recovered == signer) ||\\n isValidERC1271SignatureNow(signer, hash, signature);\\n }\\n\\n /**\\n * @dev Checks if a signature is valid for a given signer and data hash. The signature is validated\\n * against the signer smart contract using ERC1271.\\n *\\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\\n */\\n function isValidERC1271SignatureNow(\\n address signer,\\n bytes32 hash,\\n bytes memory signature\\n ) internal view returns (bool) {\\n (bool success, bytes memory result) = signer.staticcall(\\n abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, signature)\\n );\\n return (success &&\\n result.length >= 32 &&\\n abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector));\\n }\\n}\\n\",\"keccak256\":\"0x3af3ca86df39aac39a0514c84459d691434a108d2151c8ce9d69f32e315cab80\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n enum Rounding {\\n Down, // Toward negative infinity\\n Up, // Toward infinity\\n Zero // Toward zero\\n }\\n\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow.\\n return (a & b) + (a ^ b) / 2;\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a == 0 ? 0 : (a - 1) / b + 1;\\n }\\n\\n /**\\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\\n * with further edits by Uniswap Labs also under MIT license.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\\n unchecked {\\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2^256 + prod0.\\n uint256 prod0; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division.\\n if (prod1 == 0) {\\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\\n // The surrounding unchecked block does not change this fact.\\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\\n return prod0 / denominator;\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n require(denominator > prod1, \\\"Math: mulDiv overflow\\\");\\n\\n ///////////////////////////////////////////////\\n // 512 by 256 division.\\n ///////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0].\\n uint256 remainder;\\n assembly {\\n // Compute remainder using mulmod.\\n remainder := mulmod(x, y, denominator)\\n\\n // Subtract 256 bit number from 512 bit number.\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\\n // See https://cs.stackexchange.com/q/138556/92363.\\n\\n // Does not overflow because the denominator cannot be zero at this stage in the function.\\n uint256 twos = denominator & (~denominator + 1);\\n assembly {\\n // Divide denominator by twos.\\n denominator := div(denominator, twos)\\n\\n // Divide [prod1 prod0] by twos.\\n prod0 := div(prod0, twos)\\n\\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\\n twos := add(div(sub(0, twos), twos), 1)\\n }\\n\\n // Shift in bits from prod1 into prod0.\\n prod0 |= prod1 * twos;\\n\\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\\n // four bits. That is, denominator * inv = 1 mod 2^4.\\n uint256 inverse = (3 * denominator) ^ 2;\\n\\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\\n // in modular arithmetic, doubling the correct bits in each step.\\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\\n\\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inverse;\\n return result;\\n }\\n }\\n\\n /**\\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\\n uint256 result = mulDiv(x, y, denominator);\\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\\n result += 1;\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\\n *\\n * Inspired by Henry S. Warren, Jr.'s \\\"Hacker's Delight\\\" (Chapter 11).\\n */\\n function sqrt(uint256 a) internal pure returns (uint256) {\\n if (a == 0) {\\n return 0;\\n }\\n\\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\\n //\\n // We know that the \\\"msb\\\" (most significant bit) of our target number `a` is a power of 2 such that we have\\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\\n //\\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\\n // \\u2192 `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\\n // \\u2192 `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\\n //\\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\\n uint256 result = 1 << (log2(a) >> 1);\\n\\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\\n // into the expected uint128 result.\\n unchecked {\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n return min(result, a / result);\\n }\\n }\\n\\n /**\\n * @notice Calculates sqrt(a), following the selected rounding direction.\\n */\\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = sqrt(a);\\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 2, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 128;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 64;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 32;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 16;\\n }\\n if (value >> 8 > 0) {\\n value >>= 8;\\n result += 8;\\n }\\n if (value >> 4 > 0) {\\n value >>= 4;\\n result += 4;\\n }\\n if (value >> 2 > 0) {\\n value >>= 2;\\n result += 2;\\n }\\n if (value >> 1 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log2(value);\\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 10, rounded down, of a positive value.\\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 + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 256, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n *\\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\\n */\\n function log256(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 16;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 8;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 4;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 2;\\n }\\n if (value >> 8 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log256(value);\\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe4455ac1eb7fc497bb7402579e7b4d64d928b846fce7d2b6fde06d366f21c2b3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\\n * checks.\\n *\\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\\n * easily result in undesired exploitation or bugs, since developers usually\\n * assume that overflows raise errors. `SafeCast` restores this intuition by\\n * reverting the transaction when such an operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n *\\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\\n * all math on `uint256` and `int256` and then downcasting.\\n */\\nlibrary SafeCast {\\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 * _Available since v4.7._\\n */\\n function toUint248(uint256 value) internal pure returns (uint248) {\\n require(value <= type(uint248).max, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint240(uint256 value) internal pure returns (uint240) {\\n require(value <= type(uint240).max, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint232(uint256 value) internal pure returns (uint232) {\\n require(value <= type(uint232).max, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint224(uint256 value) internal pure returns (uint224) {\\n require(value <= type(uint224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint216(uint256 value) internal pure returns (uint216) {\\n require(value <= type(uint216).max, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint208(uint256 value) internal pure returns (uint208) {\\n require(value <= type(uint208).max, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint200(uint256 value) internal pure returns (uint200) {\\n require(value <= type(uint200).max, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint192(uint256 value) internal pure returns (uint192) {\\n require(value <= type(uint192).max, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint184(uint256 value) internal pure returns (uint184) {\\n require(value <= type(uint184).max, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint176(uint256 value) internal pure returns (uint176) {\\n require(value <= type(uint176).max, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint168(uint256 value) internal pure returns (uint168) {\\n require(value <= type(uint168).max, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint160(uint256 value) internal pure returns (uint160) {\\n require(value <= type(uint160).max, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint152(uint256 value) internal pure returns (uint152) {\\n require(value <= type(uint152).max, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint144(uint256 value) internal pure returns (uint144) {\\n require(value <= type(uint144).max, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint136(uint256 value) internal pure returns (uint136) {\\n require(value <= type(uint136).max, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint128(uint256 value) internal pure returns (uint128) {\\n require(value <= type(uint128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint120(uint256 value) internal pure returns (uint120) {\\n require(value <= type(uint120).max, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint112(uint256 value) internal pure returns (uint112) {\\n require(value <= type(uint112).max, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint104(uint256 value) internal pure returns (uint104) {\\n require(value <= type(uint104).max, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint96(uint256 value) internal pure returns (uint96) {\\n require(value <= type(uint96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint88(uint256 value) internal pure returns (uint88) {\\n require(value <= type(uint88).max, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint80(uint256 value) internal pure returns (uint80) {\\n require(value <= type(uint80).max, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint72(uint256 value) internal pure returns (uint72) {\\n require(value <= type(uint72).max, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint64(uint256 value) internal pure returns (uint64) {\\n require(value <= type(uint64).max, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint56(uint256 value) internal pure returns (uint56) {\\n require(value <= type(uint56).max, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint48(uint256 value) internal pure returns (uint48) {\\n require(value <= type(uint48).max, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint40(uint256 value) internal pure returns (uint40) {\\n require(value <= type(uint40).max, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint32(uint256 value) internal pure returns (uint32) {\\n require(value <= type(uint32).max, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint24(uint256 value) internal pure returns (uint24) {\\n require(value <= type(uint24).max, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint16(uint256 value) internal pure returns (uint16) {\\n require(value <= type(uint16).max, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint8(uint256 value) internal pure returns (uint8) {\\n require(value <= type(uint8).max, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\n */\\n function toUint256(int256 value) internal pure returns (uint256) {\\n require(value >= 0, \\\"SafeCast: value must be positive\\\");\\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 * _Available since v4.7._\\n */\\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\\n downcasted = int248(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\\n downcasted = int240(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\\n downcasted = int232(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\\n downcasted = int224(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\\n downcasted = int216(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\\n downcasted = int208(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\\n downcasted = int200(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\\n downcasted = int192(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\\n downcasted = int184(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\\n downcasted = int176(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\\n downcasted = int168(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\\n downcasted = int160(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\\n downcasted = int152(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\\n downcasted = int144(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\\n downcasted = int136(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\\n downcasted = int128(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\\n downcasted = int120(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\\n downcasted = int112(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\\n downcasted = int104(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\\n downcasted = int96(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\\n downcasted = int88(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\\n downcasted = int80(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\\n downcasted = int72(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\\n downcasted = int64(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\\n downcasted = int56(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\\n downcasted = int48(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\\n downcasted = int40(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\\n downcasted = int32(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\\n downcasted = int24(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\\n downcasted = int16(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\\n downcasted = int8(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\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 require(value <= uint256(type(int256).max), \\\"SafeCast: value doesn't fit in an int256\\\");\\n return int256(value);\\n }\\n}\\n\",\"keccak256\":\"0x52a8cfb0f5239d11b457dcdd1b326992ef672714ca8da71a157255bddd13f3ad\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SignedMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard signed math utilities missing in the Solidity language.\\n */\\nlibrary SignedMath {\\n /**\\n * @dev Returns the largest of two signed numbers.\\n */\\n function max(int256 a, int256 b) internal pure returns (int256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two signed numbers.\\n */\\n function min(int256 a, int256 b) internal pure returns (int256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two signed numbers without overflow.\\n * The result is rounded towards zero.\\n */\\n function average(int256 a, int256 b) internal pure returns (int256) {\\n // Formula from the book \\\"Hacker's Delight\\\"\\n int256 x = (a & b) + ((a ^ b) >> 1);\\n return x + (int256(uint256(x) >> 255) & (a ^ b));\\n }\\n\\n /**\\n * @dev Returns the absolute unsigned value of a signed value.\\n */\\n function abs(int256 n) internal pure returns (uint256) {\\n unchecked {\\n // must be unchecked in order to support `n = type(int256).min`\\n return uint256(n >= 0 ? n : -n);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf92515413956f529d95977adc9b0567d583c6203fc31ab1c23824c35187e3ddc\",\"license\":\"MIT\"},\"contracts/aa-4337/core/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable no-inline-assembly */\\n\\n/**\\n * returned data from validateUserOp.\\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\\n * @param aggregator - address(0) - the account validated the signature by itself.\\n * address(1) - the account failed to validate the signature.\\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\\n * @param validAfter - this UserOp is valid only after this timestamp.\\n * @param validaUntil - this UserOp is valid only up to this timestamp.\\n */\\nstruct ValidationData {\\n address aggregator;\\n uint48 validAfter;\\n uint48 validUntil;\\n}\\n\\n//extract sigFailed, validAfter, validUntil.\\n// also convert zero validUntil to type(uint48).max\\nfunction _parseValidationData(\\n uint validationData\\n) pure returns (ValidationData memory data) {\\n address aggregator = address(uint160(validationData));\\n uint48 validUntil = uint48(validationData >> 160);\\n if (validUntil == 0) {\\n validUntil = type(uint48).max;\\n }\\n uint48 validAfter = uint48(validationData >> (48 + 160));\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n// intersect account and paymaster ranges.\\nfunction _intersectTimeRange(\\n uint256 validationData,\\n uint256 paymasterValidationData\\n) pure returns (ValidationData memory) {\\n ValidationData memory accountValidationData = _parseValidationData(\\n validationData\\n );\\n ValidationData memory pmValidationData = _parseValidationData(\\n paymasterValidationData\\n );\\n address aggregator = accountValidationData.aggregator;\\n if (aggregator == address(0)) {\\n aggregator = pmValidationData.aggregator;\\n }\\n uint48 validAfter = accountValidationData.validAfter;\\n uint48 validUntil = accountValidationData.validUntil;\\n uint48 pmValidAfter = pmValidationData.validAfter;\\n uint48 pmValidUntil = pmValidationData.validUntil;\\n\\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp\\n * @param data - the ValidationData to pack\\n */\\nfunction _packValidationData(\\n ValidationData memory data\\n) pure returns (uint256) {\\n return\\n uint160(data.aggregator) |\\n (uint256(data.validUntil) << 160) |\\n (uint256(data.validAfter) << (160 + 48));\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp, when not using an aggregator\\n * @param sigFailed - true for signature failure, false for success\\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\\n * @param validAfter first timestamp this UserOperation is valid\\n */\\nfunction _packValidationData(\\n bool sigFailed,\\n uint48 validUntil,\\n uint48 validAfter\\n) pure returns (uint256) {\\n return\\n (sigFailed ? 1 : 0) |\\n (uint256(validUntil) << 160) |\\n (uint256(validAfter) << (160 + 48));\\n}\\n\\n/**\\n * keccak function over calldata.\\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\\n */\\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\\n assembly {\\n let mem := mload(0x40)\\n let len := data.length\\n calldatacopy(mem, data.offset, len)\\n ret := keccak256(mem, len)\\n }\\n}\\n\",\"keccak256\":\"0xa79f06cd158ecb8c0da95493a2f348933b8627a63e228b99738bff3aa107942d\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAggregator.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\n/**\\n * Aggregated Signatures validator.\\n */\\ninterface IAggregator {\\n /**\\n * validate aggregated signature.\\n * revert if the aggregated signature does not match the given list of operations.\\n */\\n function validateSignatures(\\n UserOperation[] calldata userOps,\\n bytes calldata signature\\n ) external view;\\n\\n /**\\n * validate signature of a single userOp\\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\\n * @param userOp the userOperation received from the user.\\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\\n * (usually empty, unless account and aggregator support some kind of \\\"multisig\\\"\\n */\\n function validateUserOpSignature(\\n UserOperation calldata userOp\\n ) external view returns (bytes memory sigForUserOp);\\n\\n /**\\n * aggregate multiple signatures into a single value.\\n * This method is called off-chain to calculate the signature to pass with handleOps()\\n * bundler MAY use optimized custom code perform this aggregation\\n * @param userOps array of UserOperations to collect the signatures from.\\n * @return aggregatedSignature the aggregated signature\\n */\\n function aggregateSignatures(\\n UserOperation[] calldata userOps\\n ) external view returns (bytes memory aggregatedSignature);\\n}\\n\",\"keccak256\":\"0xdfdcd80568f037716674619b31be630fcd8316262f05a815b41d1e81782c966a\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IEntryPoint.sol\":{\"content\":\"/**\\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\\n ** Only one instance required on each chain.\\n **/\\n// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-inline-assembly */\\n/* solhint-disable reason-string */\\n\\nimport \\\"./UserOperation.sol\\\";\\nimport \\\"./IStakeManager.sol\\\";\\nimport \\\"./IAggregator.sol\\\";\\nimport \\\"./INonceManager.sol\\\";\\n\\ninterface IEntryPoint is IStakeManager, INonceManager {\\n /***\\n * An event emitted after each successful request\\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\\n * @param sender - the account that generates this request.\\n * @param paymaster - if non-null, the paymaster that pays for this request.\\n * @param nonce - the nonce value from the request.\\n * @param success - true if the sender transaction succeeded, false if reverted.\\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\\n */\\n event UserOperationEvent(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address indexed paymaster,\\n uint256 nonce,\\n bool success,\\n uint256 actualGasCost,\\n uint256 actualGasUsed\\n );\\n\\n /**\\n * account \\\"sender\\\" was deployed.\\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\\n * @param sender the account that is deployed\\n * @param factory the factory used to deploy this account (in the initCode)\\n * @param paymaster the paymaster used by this UserOp\\n */\\n event AccountDeployed(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address factory,\\n address paymaster\\n );\\n\\n /**\\n * An event emitted if the UserOperation \\\"callData\\\" reverted with non-zero length\\n * @param userOpHash the request unique identifier.\\n * @param sender the sender of this request\\n * @param nonce the nonce used in the request\\n * @param revertReason - the return bytes from the (reverted) call to \\\"callData\\\".\\n */\\n event UserOperationRevertReason(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n uint256 nonce,\\n bytes revertReason\\n );\\n\\n /**\\n * an event emitted by handleOps(), before starting the execution loop.\\n * any event emitted before this event, is part of the validation.\\n */\\n event BeforeExecution();\\n\\n /**\\n * signature aggregator used by the following UserOperationEvents within this bundle.\\n */\\n event SignatureAggregatorChanged(address indexed aggregator);\\n\\n /**\\n * a custom revert error of handleOps, to identify the offending op.\\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\\n * @param reason - revert reason\\n * The string starts with a unique code \\\"AAmn\\\", where \\\"m\\\" is \\\"1\\\" for factory, \\\"2\\\" for account and \\\"3\\\" for paymaster issues,\\n * so a failure can be attributed to the correct entity.\\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\\n */\\n error FailedOp(uint256 opIndex, string reason);\\n\\n /**\\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\\n */\\n error SignatureValidationFailed(address aggregator);\\n\\n /**\\n * Successful result from simulateValidation.\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n */\\n error ValidationResult(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo\\n );\\n\\n /**\\n * Successful result from simulateValidation, if the account returns a signature aggregator\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\\n * bundler MUST use it to verify the signature, or reject the UserOperation\\n */\\n error ValidationResultWithAggregation(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo,\\n AggregatorStakeInfo aggregatorInfo\\n );\\n\\n /**\\n * return value of getSenderAddress\\n */\\n error SenderAddressResult(address sender);\\n\\n /**\\n * return value of simulateHandleOp\\n */\\n error ExecutionResult(\\n uint256 preOpGas,\\n uint256 paid,\\n uint48 validAfter,\\n uint48 validUntil,\\n bool targetSuccess,\\n bytes targetResult\\n );\\n\\n //UserOps handled, per aggregator\\n struct UserOpsPerAggregator {\\n UserOperation[] userOps;\\n // aggregator address\\n IAggregator aggregator;\\n // aggregated signature\\n bytes signature;\\n }\\n\\n /**\\n * Execute a batch of UserOperation.\\n * no signature aggregator is used.\\n * if any account requires an aggregator (that is, it returned an aggregator when\\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\\n * @param ops the operations to execute\\n * @param beneficiary the address to receive the fees\\n */\\n function handleOps(\\n UserOperation[] calldata ops,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * Execute a batch of UserOperation with Aggregators\\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\\n * @param beneficiary the address to receive the fees\\n */\\n function handleAggregatedOps(\\n UserOpsPerAggregator[] calldata opsPerAggregator,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * generate a request Id - unique identifier for this request.\\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\\n */\\n function getUserOpHash(\\n UserOperation calldata userOp\\n ) external view returns (bytes32);\\n\\n /**\\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\\n * @param userOp the user operation to validate.\\n */\\n function simulateValidation(UserOperation calldata userOp) external;\\n\\n /**\\n * gas and return values during simulation\\n * @param preOpGas the gas used for validation (including preValidationGas)\\n * @param prefund the required prefund for this operation\\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\\n */\\n struct ReturnInfo {\\n uint256 preOpGas;\\n uint256 prefund;\\n bool sigFailed;\\n uint48 validAfter;\\n uint48 validUntil;\\n bytes paymasterContext;\\n }\\n\\n /**\\n * returned aggregated signature info.\\n * the aggregator returned by the account, and its current stake.\\n */\\n struct AggregatorStakeInfo {\\n address aggregator;\\n StakeInfo stakeInfo;\\n }\\n\\n /**\\n * Get counterfactual sender address.\\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\\n * this method always revert, and returns the address in SenderAddressResult error\\n * @param initCode the constructor code to be passed into the UserOperation.\\n */\\n function getSenderAddress(bytes memory initCode) external;\\n\\n /**\\n * simulate full execution of a UserOperation (including both validation and target execution)\\n * this method will always revert with \\\"ExecutionResult\\\".\\n * it performs full validation of the UserOperation, but ignores signature error.\\n * an optional target address is called after the userop succeeds, and its value is returned\\n * (before the entire call is reverted)\\n * Note that in order to collect the the success/failure of the target call, it must be executed\\n * with trace enabled to track the emitted events.\\n * @param op the UserOperation to simulate\\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\\n * are set to the return from that call.\\n * @param targetCallData callData to pass to target address\\n */\\n function simulateHandleOp(\\n UserOperation calldata op,\\n address target,\\n bytes calldata targetCallData\\n ) external;\\n}\\n\",\"keccak256\":\"0x9ccb1b188eda8bbf5f6c2d01bd83c3d8b2b04fcf745283051d31fe96d1d8e40f\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/INonceManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\ninterface INonceManager {\\n /**\\n * Return the next nonce for this sender.\\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\\n * But UserOp with different keys can come with arbitrary order.\\n *\\n * @param sender the account address\\n * @param key the high 192 bit of the nonce\\n * @return nonce a full nonce to pass for next UserOp with this sender.\\n */\\n function getNonce(\\n address sender,\\n uint192 key\\n ) external view returns (uint256 nonce);\\n\\n /**\\n * Manually increment the nonce of the sender.\\n * This method is exposed just for completeness..\\n * Account does NOT need to call it, neither during validation, nor elsewhere,\\n * as the EntryPoint will update the nonce regardless.\\n * Possible use-case is call it with various keys to \\\"initialize\\\" their nonces to one, so that future\\n * UserOperations will not pay extra for the first transaction with a given key.\\n */\\n function incrementNonce(uint192 key) external;\\n}\\n\",\"keccak256\":\"0xce478ad0fa0d18a3b785ac854623029e7ab463d05873dfaa365abfa1bf100912\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IStakeManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8.12;\\n\\n/**\\n * manage deposits and stakes.\\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\\n * stake is value locked for at least \\\"unstakeDelay\\\" by the staked entity.\\n */\\ninterface IStakeManager {\\n event Deposited(address indexed account, uint256 totalDeposit);\\n\\n event Withdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /// Emitted when stake or unstake delay are modified\\n event StakeLocked(\\n address indexed account,\\n uint256 totalStaked,\\n uint256 unstakeDelaySec\\n );\\n\\n /// Emitted once a stake is scheduled for withdrawal\\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\\n\\n event StakeWithdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /**\\n * @param deposit the entity's deposit\\n * @param staked true if this entity is staked.\\n * @param stake actual amount of ether staked for this entity.\\n * @param unstakeDelaySec minimum delay to withdraw the stake.\\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\\n * and the rest fit into a 2nd cell.\\n * 112 bit allows for 10^15 eth\\n * 48 bit for full timestamp\\n * 32 bit allows 150 years for unstake delay\\n */\\n struct DepositInfo {\\n uint112 deposit;\\n bool staked;\\n uint112 stake;\\n uint32 unstakeDelaySec;\\n uint48 withdrawTime;\\n }\\n\\n //API struct used by getStakeInfo and simulateValidation\\n struct StakeInfo {\\n uint256 stake;\\n uint256 unstakeDelaySec;\\n }\\n\\n /// @return info - full deposit information of given account\\n function getDepositInfo(\\n address account\\n ) external view returns (DepositInfo memory info);\\n\\n /// @return the deposit (for gas payment) of the account\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * add to the deposit of the given account\\n */\\n function depositTo(address account) external payable;\\n\\n /**\\n * add to the account's stake - amount and delay\\n * any pending unstake is first cancelled.\\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\\n */\\n function addStake(uint32 _unstakeDelaySec) external payable;\\n\\n /**\\n * attempt to unlock the stake.\\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\\n */\\n function unlockStake() external;\\n\\n /**\\n * withdraw from the (unlocked) stake.\\n * must first call unlockStake and wait for the unstakeDelay to pass\\n * @param withdrawAddress the address to send withdrawn value.\\n */\\n function withdrawStake(address payable withdrawAddress) external;\\n\\n /**\\n * withdraw from the deposit.\\n * @param withdrawAddress the address to send withdrawn value.\\n * @param withdrawAmount the amount to withdraw.\\n */\\n function withdrawTo(\\n address payable withdrawAddress,\\n uint256 withdrawAmount\\n ) external;\\n}\\n\",\"keccak256\":\"0xadcea606c9b7aafe6645441f2154a60f271330b0eee5292a632aa71c1672d546\",\"license\":\"GPL-3.0-only\"},\"contracts/aa-4337/interfaces/UserOperation.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable no-inline-assembly */\\n\\nimport {calldataKeccak} from \\\"../core/Helpers.sol\\\";\\n\\n/**\\n * User Operation struct\\n * @param sender the sender account of this request.\\n * @param nonce unique value the sender uses to verify it is not a replay.\\n * @param initCode if set, the account contract will be created by this constructor/\\n * @param callData the method call to execute on this account.\\n * @param callGasLimit the gas limit passed to the callData method call.\\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\\n * @param maxFeePerGas same as EIP-1559 gas parameter.\\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\\n */\\nstruct UserOperation {\\n address sender;\\n uint256 nonce;\\n bytes initCode;\\n bytes callData;\\n uint256 callGasLimit;\\n uint256 verificationGasLimit;\\n uint256 preVerificationGas;\\n uint256 maxFeePerGas;\\n uint256 maxPriorityFeePerGas;\\n bytes paymasterAndData;\\n bytes signature;\\n}\\n\\n/**\\n * Utility functions helpful when working with UserOperation structs.\\n */\\nlibrary UserOperationLib {\\n function getSender(\\n UserOperation calldata userOp\\n ) internal pure returns (address) {\\n address data;\\n //read sender from userOp, which is first userOp member (saves 800 gas...)\\n assembly {\\n data := calldataload(userOp)\\n }\\n return address(uint160(data));\\n }\\n\\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\\n // pay above what he signed for.\\n function gasPrice(\\n UserOperation calldata userOp\\n ) internal view returns (uint256) {\\n unchecked {\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n if (maxFeePerGas == maxPriorityFeePerGas) {\\n //legacy mode (for networks that don't support basefee opcode)\\n return maxFeePerGas;\\n }\\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\\n }\\n }\\n\\n function pack(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes memory ret) {\\n address sender = getSender(userOp);\\n uint256 nonce = userOp.nonce;\\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\\n bytes32 hashCallData = calldataKeccak(userOp.callData);\\n uint256 callGasLimit = userOp.callGasLimit;\\n uint256 verificationGasLimit = userOp.verificationGasLimit;\\n uint256 preVerificationGas = userOp.preVerificationGas;\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\\n\\n return\\n abi.encode(\\n sender,\\n nonce,\\n hashInitCode,\\n hashCallData,\\n callGasLimit,\\n verificationGasLimit,\\n preVerificationGas,\\n maxFeePerGas,\\n maxPriorityFeePerGas,\\n hashPaymasterAndData\\n );\\n }\\n\\n function hash(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes32) {\\n return keccak256(pack(userOp));\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n}\\n\",\"keccak256\":\"0x2429f5cc546bdee08c7e63858d0dda8491eaa3ab5194df884dc948c1154d2834\",\"license\":\"GPL-3.0\"},\"contracts/facets/Modifiers.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {LibGuardian} from \\\"../libraries/LibGuardian.sol\\\";\\nimport {BarzStorage} from \\\"../libraries/LibAppStorage.sol\\\";\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\n\\n/**\\n * @title Modifiers\\n * @dev Responsible for providing modifiers/util functions to Facet contracts\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\nabstract contract Modifiers is BarzStorage {\\n uint8 constant INNER_STRUCT = 0;\\n\\n error CallerNotGuardian();\\n error CallerNotGuardianOrOwner();\\n error DuplicateApprover();\\n error ZeroApproverLength();\\n error UnregisteredFacetAndSelectors();\\n\\n /**\\n * @notice Modifier to only allow guardian to make a call, reverts if any other entity is the caller\\n */\\n modifier onlyGuardian() {\\n if (!LibGuardian.isGuardian(msg.sender)) revert CallerNotGuardian();\\n _;\\n }\\n\\n /**\\n * @notice Modifier to only allow guardian or owner to make a call, reverts if any other entity is the caller\\n */\\n modifier onlyGuardianOrOwner() {\\n if (!LibGuardian.isGuardian(msg.sender) && address(this) != msg.sender)\\n revert CallerNotGuardianOrOwner();\\n _;\\n }\\n\\n /**\\n * @notice Checks if the approver address is the array is unique with no duplicate\\n * @dev This method loops through the array and checks if a duplicate address exists, it reverts if duplicate address exists\\n * @param approvers Array of address\\n */\\n function _checkApprover(\\n address[] memory approvers\\n ) internal pure returns (bool) {\\n uint256 approverLength = approvers.length;\\n if (0 == approverLength) revert ZeroApproverLength();\\n for (uint256 i; i < approverLength - 1; ) {\\n for (uint256 j = i + 1; j < approverLength; ) {\\n if (approvers[i] == approvers[j]) {\\n revert DuplicateApprover(); // Found a duplicate\\n }\\n unchecked {\\n ++j;\\n }\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n return false; // No duplicates found\\n }\\n\\n /**\\n * @notice Checks if the facet getting added or replaced is registered to facet registry\\n * @dev This method loops through the cut and checks if the facet getting added/replaced is registered to facet registry\\n * @param _diamondCut Array of FacetCut, data for diamondCut defined in EIP-2535\\n */\\n function _checkFacetCutValidity(\\n IDiamondCut.FacetCut[] memory _diamondCut\\n ) internal view {\\n uint256 diamondCutLength = _diamondCut.length;\\n for (uint256 i; i < diamondCutLength; ) {\\n if (\\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Add ||\\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Replace\\n ) {\\n if (\\n !s.facetRegistry.areFacetFunctionSelectorsRegistered(\\n _diamondCut[i].facetAddress,\\n _diamondCut[i].functionSelectors\\n )\\n ) revert UnregisteredFacetAndSelectors();\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb42956323d199bdec243a5f9859439aae057fbfdd1d79e3a96afc857ecb3115f\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/DiamondCutFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {LibDiamond} from \\\"../../libraries/LibDiamond.sol\\\";\\nimport {LibGuardian} from \\\"../../libraries/LibGuardian.sol\\\";\\nimport {ISecurityManager} from \\\"../../infrastructure/interfaces/ISecurityManager.sol\\\";\\nimport {SignatureChecker} from \\\"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\\\";\\nimport {LibFacetStorage, DiamondCutApprovalConfig, ApprovalConfig} from \\\"../../libraries/LibFacetStorage.sol\\\";\\nimport {Modifiers} from \\\"../Modifiers.sol\\\";\\nimport {IDiamondCut} from \\\"./interfaces/IDiamondCut.sol\\\";\\n\\n/**\\n * @title DiamondCut Facet\\n * @dev Responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract DiamondCutFacet is Modifiers, IDiamondCut {\\n ISecurityManager public immutable securityManager;\\n\\n /**\\n * @notice This constructor sets the Security Manager address which is an immutable variable.\\n * Immutable variables do not impact the storage of diamond\\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\\n */\\n constructor(address _securityManager) {\\n securityManager = ISecurityManager(_securityManager);\\n }\\n\\n /**\\n * @notice Updates the flag for the interfaceId\\n * @param _interfaceId InterfaceID to update the mapping\\n * @param _flag Bool value to update the mapping of the given interface ID\\n */\\n function updateSupportsInterface(\\n bytes4 _interfaceId,\\n bool _flag\\n ) external override onlyWhenUnlocked {\\n LibDiamond.enforceIsSelf();\\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId] = _flag;\\n emit SupportsInterfaceUpdated(_interfaceId, _flag);\\n }\\n\\n /**\\n * @notice Add/replace/remove any number of functions and optionally execute\\n * a function with delegatecall when guardians don't exist\\n * @param _diamondCut Contains the facet addresses and function selectors\\n * @param _init The address of the contract or facet to execute _calldata. It's prohibited in Barz\\n */\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata\\n ) external override onlyWhenUnlocked {\\n LibDiamond.enforceIsSelf();\\n\\n _checkFacetCutValidity(_diamondCut);\\n // require approval from guardian if guardian exists\\n if (0 != LibGuardian.guardianCount())\\n revert DiamondCutFacet__InvalidRouteWithGuardian();\\n if (address(0) != _init) revert DiamondCutFacet__InvalidInitAddress();\\n\\n unchecked {\\n ++LibFacetStorage.diamondCutStorage().nonce;\\n }\\n LibDiamond.diamondCut(_diamondCut, address(0), \\\"\\\");\\n }\\n\\n /**\\n * @notice Add/replace/remove any number of functions and optionally execute\\n * a function with delegatecall when guardians exist\\n * @param _diamondCut Contains the facet addresses and function selectors\\n * @param _approvers Guardian or owner address that approves the diamond cut\\n * @param _signatures Signature of Guardians or owner that approves the diamond cut\\n */\\n function diamondCutWithGuardian(\\n FacetCut[] calldata _diamondCut,\\n address[] calldata _approvers,\\n bytes[] calldata _signatures\\n ) external override onlyWhenUnlocked {\\n if (_approvers.length != _signatures.length)\\n revert DiamondCutFacet__InvalidArrayLength();\\n _checkFacetCutValidity(_diamondCut);\\n if (0 == LibGuardian.guardianCount())\\n revert DiamondCutFacet__InvalidRouteWithGuardian();\\n\\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\\n\\n _checkApprover(_approvers);\\n _checkDuplicateOnChainApprover(cutHash, _approvers);\\n\\n bool onChainOwnerApproval = getOwnerCutApprovalWithTimeValidity(\\n cutHash\\n );\\n\\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\\n if (\\n _approvers.length +\\n getDiamondCutApprovalCountWithTimeValidity(cutHash) <\\n LibGuardian.majorityOfGuardians() + threshold\\n ) revert DiamondCutFacet__InsufficientApprovers();\\n\\n bool ownerApproved;\\n for (uint256 i; i < _approvers.length; ) {\\n if (\\n !LibGuardian.isGuardian(_approvers[i]) &&\\n _approvers[i] != address(this)\\n ) revert DiamondCutFacet__InvalidApprover();\\n if (_approvers[i] == address(this)) {\\n if (onChainOwnerApproval)\\n revert DiamondCutFacet__OwnerAlreadyApproved();\\n ownerApproved = true;\\n }\\n if (\\n !SignatureChecker.isValidSignatureNow(\\n _approvers[i],\\n cutHash,\\n _signatures[i]\\n )\\n ) revert DiamondCutFacet__InvalidApproverSignature();\\n unchecked {\\n ++i;\\n }\\n }\\n if (!ownerApproved && !onChainOwnerApproval)\\n revert DiamondCutFacet__LackOfOwnerApproval();\\n\\n unchecked {\\n ++LibFacetStorage.diamondCutStorage().nonce;\\n }\\n LibDiamond.diamondCut(_diamondCut, address(0), \\\"\\\");\\n }\\n\\n /**\\n * @notice Approves diamond cut. This can only be called directly from guardian or owner\\n * @param _diamondCut Contains the facet addresses and function selectors\\n */\\n function approveDiamondCut(\\n FacetCut[] calldata _diamondCut\\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\\n if (LibGuardian.guardianCount() == 0)\\n revert DiamondCutFacet__InvalidRouteWithoutGuardian();\\n DiamondCutApprovalConfig storage ds = LibFacetStorage\\n .diamondCutStorage()\\n .diamondCutApprovalConfigs[INNER_STRUCT];\\n _checkFacetCutValidity(_diamondCut);\\n\\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\\n uint64 approvalValidUntil = uint64(\\n block.timestamp + getApprovalValidationPeriod()\\n );\\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(\\n true,\\n approvalValidUntil\\n );\\n emit DiamondCutApproved(_diamondCut);\\n if (\\n (getDiamondCutApprovalCountWithTimeValidity(cutHash) >=\\n LibGuardian.majorityOfGuardians()) &&\\n getOwnerCutApprovalWithTimeValidity(cutHash)\\n ) {\\n unchecked {\\n ++LibFacetStorage.diamondCutStorage().nonce;\\n }\\n LibDiamond.diamondCut(_diamondCut, address(0), \\\"\\\");\\n }\\n }\\n\\n /**\\n * @notice Revokes the approval of diamond cut. This can only be called directly from guardian or owner\\n * @param _diamondCut Contains the facet addresses and function selectors\\n */\\n function revokeDiamondCutApproval(\\n FacetCut[] calldata _diamondCut\\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\\n DiamondCutApprovalConfig storage ds = LibFacetStorage\\n .diamondCutStorage()\\n .diamondCutApprovalConfigs[INNER_STRUCT];\\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\\n if (!ds.isDiamondCutApproved[cutHash][msg.sender].isApproved)\\n revert DiamondCutFacet__CannotRevokeUnapproved();\\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(false, 0);\\n emit DiamondCutApprovalRevoked(_diamondCut);\\n }\\n\\n /**\\n * @notice Gets the number of approvals of diamond cut from guardians\\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\\n */\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 _diamondCutHash\\n ) public view override returns (uint256 approvalCount) {\\n address[] memory guardians = LibGuardian.getGuardians();\\n uint256 guardiansLength = guardians.length;\\n for (uint256 i; i < guardiansLength; ) {\\n if (isCutApproved(_diamondCutHash, guardians[i])) {\\n unchecked {\\n ++approvalCount;\\n }\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n return approvalCount;\\n }\\n\\n /**\\n * @notice Returns if the owner has approved the diamond cut\\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\\n * @return isApprovedByOwner Bool value showing if the owner approved the cut\\n */\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 _diamondCutHash\\n ) public view override returns (bool isApprovedByOwner) {\\n isApprovedByOwner = isCutApproved(_diamondCutHash, address(this));\\n }\\n\\n /**\\n * @notice Returns if the given approver has approved the diamond cut\\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\\n * @param _approver Address of approver\\n * @return isApproved Bool value showing if the approver approved the cut\\n */\\n function isCutApproved(\\n bytes32 _diamondCutHash,\\n address _approver\\n ) public view override returns (bool isApproved) {\\n DiamondCutApprovalConfig storage ds = LibFacetStorage\\n .diamondCutStorage()\\n .diamondCutApprovalConfigs[INNER_STRUCT];\\n isApproved = (ds\\n .isDiamondCutApproved[_diamondCutHash][_approver].isApproved &&\\n block.timestamp <\\n ds.isDiamondCutApproved[_diamondCutHash][_approver].validUntil);\\n }\\n\\n /**\\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\\n * Approvers who approved on-chain should not be included in the off-chain approval\\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\\n * @param _approvers List of approver addresses\\n */\\n function _checkDuplicateOnChainApprover(\\n bytes32 _diamondCutHash,\\n address[] memory _approvers\\n ) public view {\\n address[] memory guardians = LibGuardian.getGuardians();\\n uint256 guardianLength = guardians.length;\\n uint256 approversLength = _approvers.length;\\n for (uint256 i; i < guardianLength; ) {\\n if (isCutApproved(_diamondCutHash, guardians[i])) {\\n for (uint256 j; j < approversLength; ) {\\n if (_approvers[j] == guardians[i])\\n revert DiamondCutFacet__DuplicateApproval();\\n unchecked {\\n ++j;\\n }\\n }\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * @notice Returns the diamond cut hash. This function ensures that this hash is safe from replay attack by including\\n * salt, address, chainId, and nonce, etc.\\n * @param _diamondCut Contains the facet addresses and function selectors\\n * @return cutHash Diamond Cut Hash\\n */\\n function getDiamondCutHash(\\n FacetCut[] calldata _diamondCut\\n ) public view override returns (bytes32 cutHash) {\\n cutHash = keccak256(\\n abi.encodePacked(\\n \\\"\\\\x19Ethereum Signed Message:\\\\n32\\\",\\n keccak256(\\n abi.encode(\\n keccak256(abi.encode(_diamondCut)),\\n address(this),\\n block.chainid,\\n LibFacetStorage.diamondCutStorage().nonce\\n )\\n )\\n )\\n );\\n }\\n\\n /**\\n * @notice Returns the approval validation Period\\n * @dev This method fetches the validation period from the security manager\\n * @return approvalValidationPeriod Approval validation period of Barz contract fetched from security manager\\n */\\n function getApprovalValidationPeriod()\\n internal\\n view\\n returns (uint256 approvalValidationPeriod)\\n {\\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\\n address(this)\\n );\\n if (approvalValidationPeriod <= 0)\\n revert DiamondCutFacet__InvalidApprovalValidationPeriod();\\n }\\n\\n /**\\n * @notice Returns the diamond cut nonce of this wallet\\n * @dev This method fetches the nonce from diamond cut storage\\n * @return cutNonce Nonce of diamond cut to protect from reply attacks\\n */\\n function getDiamondCutNonce()\\n public\\n view\\n override\\n returns (uint128 cutNonce)\\n {\\n cutNonce = LibFacetStorage.diamondCutStorage().nonce;\\n }\\n}\\n\",\"keccak256\":\"0xe91a7dd2daabf2e989c94089f4f1eb0da94276c3070559ac8988838e10dd1f5d\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/infrastructure/interfaces/IFacetRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Registry Interface\\n * @dev Interface for Facet Registry contract to keep track of facets & function selectors addable to user wallets\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IFacetRegistry {\\n struct FacetRegistryConfig {\\n bytes4[] selectors;\\n mapping(bytes4 => FacetInfo) info;\\n }\\n struct FacetInfo {\\n bool exists;\\n uint128 index;\\n }\\n\\n event FacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] facetSelectors\\n );\\n event FacetFunctionSelectorsRemoved(address facet, bytes4[] facetSelectors);\\n\\n error FacetRegistry__FacetSelectorAlreadyRegistered();\\n error FacetRegistry__UnregisteredFacetSelector();\\n\\n function registerFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function removeFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function areFacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external view returns (bool);\\n\\n function isFacetFunctionSelectorRegistered(\\n address facet,\\n bytes4 facetSelector\\n ) external view returns (bool);\\n\\n function getFacetFunctionSelectors(\\n address facet\\n ) external view returns (bytes4[] memory);\\n}\\n\",\"keccak256\":\"0x6e6dd2cab346ef7c31230740ec48d2925e4a9ab24c2f2fb268baaf408dcf02ef\",\"license\":\"Apache-2.0\"},\"contracts/infrastructure/interfaces/ISecurityManager.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Registry Interface\\n * @dev Infrastructure contract to manage security parameters of users\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\ninterface ISecurityManager {\\n error SecurityManager__OutOfBoundary();\\n error SecurityManager__CallerNotWallet();\\n error SecurityManager__AlreadyIntialized();\\n\\n function initializeAdditionSecurityPeriod(\\n uint128 defaultAdditionSecurityPeriod,\\n uint128 minAdditionSecurityPeriod,\\n uint128 maxAdditionSecurityPeriod\\n ) external;\\n\\n function initializeRemovalSecurityPeriod(\\n uint128 defaultRemovalSecurityPeriod,\\n uint128 minRemovalSecurityPeriod,\\n uint128 maxRemovalSecurityPeriod\\n ) external;\\n\\n function initializeApprovalValidationPeriod(\\n uint128 defaultApprovalValidationPeriod,\\n uint128 minApprovalValidationPeriod,\\n uint128 maxApprovalValidationPeriod\\n ) external;\\n\\n function initializeMigrationPeriod(\\n uint128 defaultMigrationPeriod,\\n uint128 minMigrationPeriod,\\n uint128 maxMigrationPeriod\\n ) external;\\n\\n function initializeLockPeriod(\\n uint128 defaultLockPeriod,\\n uint128 minLockPeriod,\\n uint128 maxLockPeriod\\n ) external;\\n\\n function initializeRecoveryPeriod(\\n uint128 defaultRecoveryPeriod,\\n uint128 minRecoveryPeriod,\\n uint128 maxRecoveryPeriod\\n ) external;\\n\\n function initializeSecurityWindow(\\n uint128 defaultSecurityWindow,\\n uint128 minSecurityWindow,\\n uint128 maxSecurityWindow\\n ) external;\\n\\n function setAdditionSecurityPeriod(\\n address wallet,\\n uint128 additionSecurityPeriod\\n ) external;\\n\\n function setRemovalSecurityPeriod(\\n address wallet,\\n uint128 removalSecurityPeriod\\n ) external;\\n\\n function setSecurityWindow(address wallet, uint128 securityWindow) external;\\n\\n function setRecoveryPeriod(address wallet, uint128 recoveryPeriod) external;\\n\\n function setLockPeriod(address wallet, uint128 lockPeriod) external;\\n\\n function setApprovalValidationPeriod(\\n address wallet,\\n uint128 approvalValidationPeriod\\n ) external;\\n\\n function setMigrationPeriod(\\n address wallet,\\n uint128 migrationPeriod\\n ) external;\\n\\n function additionSecurityPeriodOf(\\n address wallet\\n ) external view returns (uint128);\\n\\n function removalSecurityPeriodOf(\\n address wallet\\n ) external view returns (uint128);\\n\\n function securityWindowOf(address wallet) external view returns (uint128);\\n\\n function recoveryPeriodOf(address wallet) external view returns (uint128);\\n\\n function lockPeriodOf(address wallet) external view returns (uint128);\\n\\n function migrationPeriodOf(address wallet) external view returns (uint128);\\n\\n function approvalValidationPeriodOf(\\n address wallet\\n ) external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x9ac6566033ef81ba5744c8ed2b08f130b781b498ab9245bcca87567669549552\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibAppStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {SafeCast} from \\\"@openzeppelin/contracts/utils/math/SafeCast.sol\\\";\\nimport {IEntryPoint} from \\\"../aa-4337/interfaces/IEntryPoint.sol\\\";\\nimport {IFacetRegistry} from \\\"../infrastructure/interfaces/IFacetRegistry.sol\\\";\\n\\n/*\\n * @title App Storage\\n * @dev App storage for Barz contract to prevent storage collision\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Lock {\\n uint64 release;\\n bytes4 locker;\\n}\\n\\nstruct InitializersStorage {\\n // NOTE: initialized is a variable to make sure the initialization is only done once.\\n uint8 signerInitialized;\\n uint8 accountInitialized;\\n uint8 restrictionsInitialized;\\n}\\n\\nstruct AppStorage {\\n mapping(uint256 => InitializersStorage) initStorage;\\n uint8 signerMigration;\\n bytes4 validateOwnerSignatureSelector;\\n IEntryPoint entryPoint;\\n IFacetRegistry facetRegistry;\\n mapping(uint256 => Lock) locks;\\n}\\n\\nlibrary LibAppStorage {\\n error LibAppStorage__AccountAlreadyUninitialized();\\n error LibAppStorage__AccountMustBeUninitialized();\\n error LibAppStorage__SignerAlreadyUninitialized();\\n error LibAppStorage__SignerMustBeUninitialized();\\n\\n function appStorage() internal pure returns (AppStorage storage ds) {\\n assembly {\\n ds.slot := 0\\n }\\n }\\n\\n function setSignerUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerAlreadyUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 0;\\n }\\n\\n function getValidateOwnerSignatureSelector()\\n internal\\n view\\n returns (bytes4 selector)\\n {\\n selector = appStorage().validateOwnerSignatureSelector;\\n }\\n\\n function setValidateOwnerSignatureSelector(\\n bytes4 _validateOwnerSignatureSelector\\n ) internal {\\n appStorage()\\n .validateOwnerSignatureSelector = _validateOwnerSignatureSelector;\\n }\\n\\n function enforceSignerInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerMustBeUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 1;\\n }\\n\\n function enforceAccountInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].accountInitialized) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n s.initStorage[0].accountInitialized = 1;\\n }\\n\\n function initiateSignerMigration() internal {\\n appStorage().signerMigration = 1;\\n }\\n\\n function enforceSignerMigration() internal view {\\n if (1 != appStorage().signerMigration) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n }\\n\\n function finalizeSignerMigration() internal {\\n appStorage().signerMigration = 0;\\n }\\n\\n function setLock(uint256 _releaseAfter, bytes4 _locker) internal {\\n appStorage().locks[0] = Lock(SafeCast.toUint64(_releaseAfter), _locker);\\n }\\n\\n function enforceRestrictionsInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__SignerMustBeUninitialized();\\n s.initStorage[0].restrictionsInitialized = 1;\\n }\\n\\n function setRestrictionsUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__AccountAlreadyUninitialized();\\n s.initStorage[0].restrictionsInitialized = 0;\\n }\\n}\\n\\ncontract BarzStorage {\\n AppStorage internal s;\\n modifier onlyWhenUnlocked() {\\n require(\\n uint64(block.timestamp) >= s.locks[0].release,\\n \\\"Account Locked\\\"\\n );\\n _;\\n }\\n modifier onlyWhenLocked() {\\n require(\\n uint64(block.timestamp) < s.locks[0].release,\\n \\\"Account Unlocked\\\"\\n );\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x48524007862a6ce0e07f645950613ce6513ce073c37a109c75019683d42bae27\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\\n bytes4(keccak256(\\\"verifyRestrictions(address,address,uint256,bytes)\\\"));\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // Default Fallback Handler of the barz.\\n IDiamondLoupe defaultFallbackHandler;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function enforceIsSelf() internal view {\\n require(msg.sender == address(this), \\\"LibDiamond: Caller not self\\\");\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n\\n unchecked {\\n facetIndex++;\\n }\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n\\n function restrictionsFacet() internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(\\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2cabdc00de859c3a3170ce3bda5d0e5fd3933d47ce904fd1585f9818b02572f8\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibFacetStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Storage\\n * @dev Storage contract to store each facets variables with diamond storage\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Secp256k1VerificationStorage {\\n address signer;\\n}\\n\\nstruct Secp256r1VerificationStorage {\\n uint256[2] q;\\n}\\n\\nstruct GuardianStorage {\\n mapping(bytes32 => uint256) pending;\\n mapping(uint8 => StorageConfig) configs;\\n}\\n\\nstruct Info {\\n bool exists;\\n uint128 index;\\n}\\n\\nstruct StorageConfig {\\n address[] addresses;\\n mapping(address => Info) info;\\n}\\n\\nstruct RecoveryConfig {\\n bytes recoveryPublicKey;\\n uint64 executeAfter;\\n}\\n\\nstruct ApprovalConfig {\\n bool isApproved;\\n uint64 validUntil;\\n}\\n\\nstruct RecoveryApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isNewOwnerApproved;\\n}\\n\\nstruct RecoveryStorage {\\n mapping(uint8 => RecoveryConfig) recoveryConfigs;\\n mapping(uint8 => RecoveryApprovalConfig) recoveryApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct RestrictionsStorage {\\n address[] restrictions;\\n mapping(address => bool) exists;\\n}\\n\\nstruct SignatureMigrationConfig {\\n bytes migrationPublicKey;\\n address migrationVerificationFacet;\\n bytes4[] migrationSelectors;\\n uint64 migrateAfter;\\n}\\n\\nstruct SignatureMigrationApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isMigrationApproved;\\n}\\n\\nstruct SignatureMigrationStorage {\\n mapping(uint8 => SignatureMigrationConfig) migrationConfigs;\\n mapping(uint8 => SignatureMigrationApprovalConfig) migrationApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct DiamondCutApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isDiamondCutApproved;\\n}\\n\\nstruct DiamondCutStorage {\\n mapping(uint8 => DiamondCutApprovalConfig) diamondCutApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct LockStorage {\\n uint128 nonce;\\n}\\n\\nlibrary LibFacetStorage {\\n bytes32 constant K1_STORAGE_POSITION =\\n keccak256(\\n \\\"v0.trustwallet.diamond.storage.Secp256k1VerificationStorage\\\"\\n );\\n bytes32 constant R1_STORAGE_POSITION =\\n keccak256(\\n \\\"v0.trustwallet.diamond.storage.Secp256r1VerificationStorage\\\"\\n );\\n bytes32 constant GUARDIAN_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.GuardianStorage\\\");\\n bytes32 constant RECOVERY_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.RecoveryStorage\\\");\\n bytes32 constant RESTRICTION_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.RestrictionsStorage\\\");\\n bytes32 constant MIGRATION_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.SignatureMigrationStorage\\\");\\n bytes32 constant DIAMONDCUT_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.DiamondCutStorage\\\");\\n bytes32 constant LOCK_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.LockStorage\\\");\\n\\n function k1Storage()\\n internal\\n pure\\n returns (Secp256k1VerificationStorage storage ds)\\n {\\n bytes32 storagePosition = K1_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function r1Storage()\\n internal\\n pure\\n returns (Secp256r1VerificationStorage storage ds)\\n {\\n bytes32 storagePosition = R1_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function guardianStorage()\\n internal\\n pure\\n returns (GuardianStorage storage ds)\\n {\\n bytes32 storagePosition = GUARDIAN_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function recoveryStorage()\\n internal\\n pure\\n returns (RecoveryStorage storage ds)\\n {\\n bytes32 storagePosition = RECOVERY_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function restrictionsStorage()\\n internal\\n pure\\n returns (RestrictionsStorage storage ds)\\n {\\n bytes32 storagePosition = RESTRICTION_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function migrationStorage()\\n internal\\n pure\\n returns (SignatureMigrationStorage storage ds)\\n {\\n bytes32 storagePosition = MIGRATION_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function diamondCutStorage()\\n internal\\n pure\\n returns (DiamondCutStorage storage ds)\\n {\\n bytes32 storagePosition = DIAMONDCUT_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function lockStorage() internal pure returns (LockStorage storage ds) {\\n bytes32 storagePosition = LOCK_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n}\\n\",\"keccak256\":\"0x87c85decfd943deda9540733e464cb1a92eba735a301e89ce6f798016e359761\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibGuardian.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {LibFacetStorage, StorageConfig} from \\\"./LibFacetStorage.sol\\\";\\n\\n/**\\n * @title LibGuardian\\n * @dev Internal Library to provide utility feature for Guardians stored in Guardian Facet Storage\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\nlibrary LibGuardian {\\n function majorityOfGuardians()\\n internal\\n view\\n returns (uint256 guardianNumber)\\n {\\n uint256 guardianLength = guardianCount();\\n guardianNumber = (guardianLength == 0) ? 0 : guardianLength / 2 + 1;\\n }\\n\\n function isGuardian(address _guardian) internal view returns (bool) {\\n StorageConfig storage config = LibFacetStorage\\n .guardianStorage()\\n .configs[0];\\n return config.info[_guardian].exists;\\n }\\n\\n function guardianCount() internal view returns (uint256) {\\n StorageConfig storage config = LibFacetStorage\\n .guardianStorage()\\n .configs[0];\\n return config.addresses.length;\\n }\\n\\n function getGuardians() internal view returns (address[] memory) {\\n StorageConfig storage config = LibFacetStorage\\n .guardianStorage()\\n .configs[0];\\n address[] memory addresses = new address[](config.addresses.length);\\n uint256 addressesLen = config.addresses.length;\\n for (uint256 i; i < addressesLen; ) {\\n addresses[i] = config.addresses[i];\\n unchecked {\\n ++i;\\n }\\n }\\n return addresses;\\n }\\n}\\n\",\"keccak256\":\"0x6a620992d5535878fc03d1a27a6675f4c1509adfb3ddbbca1c52b546c25392dc\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x60a06040523480156200001157600080fd5b506040516200379b3803806200379b833981016040819052620000349162000046565b6001600160a01b031660805262000078565b6000602082840312156200005957600080fd5b81516001600160a01b03811681146200007157600080fd5b9392505050565b6080516137006200009b600039600081816101f10152611b2501526137006000f3fe608060405234801561001057600080fd5b50600436106100d45760003560e01c806379c0d58d11610081578063afb877bb1161005b578063afb877bb146101d9578063de675a6d146101ec578063e33ecf0a1461023857600080fd5b806379c0d58d14610192578063836d6bfb146101b35780638824a0bb146101c657600080fd5b806326fc3ef4116100b257806326fc3ef4146101145780632f4d98ea1461015c5780633c0985681461017f57600080fd5b806313c34f4b146100d95780631c776dd5146100ee5780631f931c1c14610101575b600080fd5b6100ec6100e7366004612a97565b61024b565b005b6100ec6100fc366004612ad9565b6104df565b6100ec61010f366004612b9c565b610a76565b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9bf546040516fffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b61016f61016a366004612c4a565b610c7b565b6040519015158152602001610153565b6100ec61018d366004612ca4565b610c8d565b6101a56101a0366004612c4a565b610df2565b604051908152602001610153565b61016f6101c1366004612cdb565b610e4c565b6100ec6101d4366004612dd2565b610eed565b6100ec6101e7366004612a97565b610fe1565b6102137f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610153565b6101a5610246366004612a97565b61130e565b3360009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff1615801561028a5750303314155b156102c1576040517f6238ee3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610369576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064015b60405180910390fd5b60008080527f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be6020527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d3906103be848461130e565b60008181526020848152604080832033845290915290205490915060ff16610412576040517fedc5708300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051808201825260008082526020808301828152858352868252848320338452909152908390209151825491517fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000009092169015157fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff161761010067ffffffffffffffff90921691909102179055517f3c3d8c1f0b0faff6fe0ace6b485d0595a0106dce9e303f956fd941ebdbe9a98e906104d19086908690612f54565b60405180910390a150505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610582576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b8281146105bb576040517fe854148500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6105cd6105c886886130aa565b611435565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b754600003610650576040517fa788861700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061065c878761130e565b905061069a8585808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506115b392505050565b506106d881868680806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250610eed92505050565b60006106e382610c7b565b90506000816106f35760016106f6565b60005b60ff169050806107046116d0565b61070e9190613201565b61071784610df2565b6107219088613201565b1015610759576040517f709fb08000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805b878110156109a0576107d989898381811061077a5761077a613214565b905060200201602081019061078f9190613243565b73ffffffffffffffffffffffffffffffffffffffff1660009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff1690565b1580156108225750308989838181106107f4576107f4613214565b90506020020160208101906108099190613243565b73ffffffffffffffffffffffffffffffffffffffff1614155b15610859576040517f7b2cbbb400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3089898381811061086c5761086c613214565b90506020020160208101906108819190613243565b73ffffffffffffffffffffffffffffffffffffffff16036108d95783156108d4576040517fee21708000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600191505b6109628989838181106108ee576108ee613214565b90506020020160208101906109039190613243565b8689898581811061091657610916613214565b90506020028101906109289190613265565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061174f92505050565b610998576040517fac3d341600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60010161075d565b50801580156109ad575082155b156109e4576040517f6d21730400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9bf80546fffffffffffffffffffffffffffffffff808216600101167fffffffffffffffffffffffffffffffff00000000000000000000000000000000909116179055610a6a610a538a8c6130aa565b6000604051806020016040528060008152506117ca565b50505050505050505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610b19576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b610b2161195f565b610b2e6105c885876130aa565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75415610baf576040517fa788861700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff831615610bfd576040517f871cb76100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be5b600190810180547fffffffffffffffffffffffffffffffff0000000000000000000000000000000081166fffffffffffffffffffffffffffffffff91821690930116919091179055610c74610a5385876130aa565b5050505050565b6000610c878230610e4c565b92915050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610d30576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b610d3861195f565b7fffffffff00000000000000000000000000000000000000000000000000000000821660008181527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4922602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001685151590811790915582519384529083015280517f4e6bd17989efa6d6a9607ccaac1bba27b29f99622bc830d99a3a9883b21a19c79281900390910190a15050565b600080610dfd6119ca565b805190915060005b81811015610e4457610e3085848381518110610e2357610e23613214565b6020026020010151610e4c565b15610e3c578360010193505b600101610e05565b505050919050565b60008281527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d36020818152604080842073ffffffffffffffffffffffffffffffffffffffff8616855290915282205460ff168015610ee5575060008481526020828152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152902054610100900467ffffffffffffffff1642105b949350505050565b6000610ef76119ca565b805183519192509060005b82811015610fd957610f2086858381518110610e2357610e23613214565b15610fd15760005b82811015610fcf57848281518110610f4257610f42613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16868281518110610f7257610f72613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603610fc7576040517f50f5729f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600101610f28565b505b600101610f02565b505050505050565b3360009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff161580156110205750303314155b15611057576040517f6238ee3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff9081164290911610156110fa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75460000361117d576040517f3a76e1f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080527f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be6020527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d36111d36105c883856130aa565b60006111df848461130e565b905060006111eb611af4565b6111f59042613201565b6040805180820182526001815267ffffffffffffffff838116602080840191825260008881528982528581203382529091528490209251835491517fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000009092169015157fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff16176101009190921602179055519091507f6248ff757895beed7d43d135bccf59a26b7fbdf0fe8233487c44e82c0f266ba3906112b89087908790612f54565b60405180910390a16112c86116d0565b6112d183610df2565b101580156112e357506112e382610c7b565b15610c74577f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be610c1f565b60008282604051602001611323929190612f54565b6040516020818303038152906040528051906020012030466113627f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be90565b6001015460408051602081019590955273ffffffffffffffffffffffffffffffffffffffff9093169284019290925260608301526fffffffffffffffffffffffffffffffff16608082015260a001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905280516020918201207f19457468657265756d205369676e6564204d6573736167653a0a33320000000091830191909152603c820152605c0160405160208183030381529060405280519060200120905092915050565b805160005b818110156115ae57600083828151811061145657611456613214565b602002602001015160200151600281111561147357611473612e8a565b14806114ad5750600183828151811061148e5761148e613214565b60200260200101516020015160028111156114ab576114ab612e8a565b145b156115a657600254835173ffffffffffffffffffffffffffffffffffffffff9091169063df871f72908590849081106114e8576114e8613214565b60200260200101516000015185848151811061150657611506613214565b6020026020010151604001516040518363ffffffff1660e01b815260040161152f92919061331c565b602060405180830381865afa15801561154c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611570919061334b565b6115a6576040517ff41a931c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60010161143a565b505050565b80516000908082036115f1576040517f3aee2eec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b6115ff600183613368565b8110156116c6576000611613826001613201565b90505b828110156116bd5784818151811061163057611630613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1685838151811061166057611660613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16036116b5576040517f8dd19e7d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600101611616565b506001016115f4565b5060009392505050565b600080611723600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75490565b905080156117465761173660028261337b565b611741906001613201565b611749565b60005b91505090565b600080600061175e8585611bf6565b9092509050600081600481111561177757611777612e8a565b1480156117af57508573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b806117c057506117c0868686611c3b565b9695505050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921547f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff8116908190600090600716156118395750600381901c60009081526001840160205260409020545b60005b87518110156118b6576118a983838a848151811061185c5761185c613214565b6020026020010151600001518b858151811061187a5761187a613214565b6020026020010151602001518c868151811061189857611898613214565b602002602001015160400151611d98565b909350915060010161183c565b508282146118ef576002840180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff84161790555b600782161561191157600382901c600090815260018501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb67387878760405161194493929190613424565b60405180910390a16119568686612829565b50505050505050565b3330146119c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4c69624469616d6f6e643a2043616c6c6572206e6f742073656c6600000000006044820152606401610360565b565b60008080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b780546060929067ffffffffffffffff811115611a3257611a32612d07565b604051908082528060200260200182016040528015611a5b578160200160208202803683370190505b50825490915060005b81811015611aeb57836000018181548110611a8157611a81613214565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16838281518110611abe57611abe613214565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101611a64565b50909392505050565b6040517f52430c8d0000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906352430c8d90602401602060405180830381865afa158015611b81573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ba59190613510565b6fffffffffffffffffffffffffffffffff16905060008111611bf3576040517fdac5ec8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b90565b6000808251604103611c2c5760208301516040840151606085015160001a611c2087828585612928565b94509450505050611c34565b506000905060025b9250929050565b60008060008573ffffffffffffffffffffffffffffffffffffffff16631626ba7e60e01b8686604051602401611c72929190613542565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909416939093179092529051611cfb919061355b565b600060405180830381855afa9150503d8060008114611d36576040519150601f19603f3d011682016040523d82523d6000602084013e611d3b565b606091505b5091509150818015611d4f57506020815110155b80156117c0575080517f1626ba7e0000000000000000000000000000000000000000000000000000000090611d8d9083016020908101908401613577565b149695505050505050565b600080807f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f90506000845111611e50576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610360565b6000856002811115611e6457611e64612e8a565b0361203457611e8b8660405180606001604052806024815260200161365760249139612a17565b60005b845181101561202e576000858281518110611eab57611eab613214565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c15611f7e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c72656164792065786973747300000000000000000000006064820152608401610360565b7fffffffff0000000000000000000000000000000000000000000000000000000080831660008181526020879052604090207fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608d901b168e17905560e060058e901b811692831c199c909c1690821c179a8190036120125760038c901c600090815260018601602052604081209b909b555b8b61201c81613590565b9c505060019093019250611e8e915050565b5061281d565b600185600281111561204857612048612e8a565b036123385761206f866040518060600160405280602881526020016136a360289139612a17565b60005b845181101561202e57600085828151811061208f5761208f613214565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c308103612164576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4c69624469616d6f6e644375743a2043616e2774207265706c61636520696d6d60448201527f757461626c652066756e6374696f6e00000000000000000000000000000000006064820152608401610360565b8973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361221f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e00000000000000006064820152608401610360565b73ffffffffffffffffffffffffffffffffffffffff81166122c2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e207468617420646f65736e277420657869737400000000000000006064820152608401610360565b507fffffffff0000000000000000000000000000000000000000000000000000000090911660009081526020849052604090206bffffffffffffffffffffffff919091167fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608a901b16179055600101612072565b600285600281111561234c5761234c612e8a565b036127955773ffffffffffffffffffffffffffffffffffffffff8616156123f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d7573742062652061646472657373283029000000000000000000006064820152608401610360565b600388901c6007891660005b86518110156127755760008a900361243d578261241d816135c8565b60008181526001870160205260409020549b5093506007925061244b9050565b81612447816135c8565b9250505b6000806000808a858151811061246357612463613214565b6020908102919091018101517fffffffff0000000000000000000000000000000000000000000000000000000081166000908152918a9052604090912054909150606081901c612535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608401610360565b30606082901c036125c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e0000000000000000000000000000000000006064820152608401610360565b600587901b8f901b94507fffffffff0000000000000000000000000000000000000000000000000000000080861690831614612666577fffffffff000000000000000000000000000000000000000000000000000000008516600090815260208a90526040902080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff83161790555b7fffffffff0000000000000000000000000000000000000000000000000000000091909116600090815260208990526040812055600381901c611fff16925060051b60e01690508582146126fb576000828152600188016020526040902080547fffffffff0000000000000000000000000000000000000000000000000000000080841c19909116908516831c17905561274c565b80837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c817fffffffff0000000000000000000000000000000000000000000000000000000060001b901c198e16179c505b8460000361276a57600086815260018801602052604081208190559c505b505050600101612401565b50806127828360086135fd565b61278c9190613201565b9950505061281d565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560448201527f74416374696f6e000000000000000000000000000000000000000000000000006064820152608401610360565b50959694955050505050565b73ffffffffffffffffffffffffffffffffffffffff8216612848575050565b61286a8260405180606001604052806028815260200161367b60289139612a17565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051612892919061355b565b600060405180830381855af49150503d80600081146128cd576040519150601f19603f3d011682016040523d82523d6000602084013e6128d2565b606091505b509150915081612922578051156128ec5780518082602001fd5b83836040517f192105d7000000000000000000000000000000000000000000000000000000008152600401610360929190613614565b50505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561295f5750600090506003612a0e565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156129b3573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116612a0757600060019250925050612a0e565b9150600090505b94509492505050565b813b8181612922576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103609190613643565b60008083601f840112612a6457600080fd5b50813567ffffffffffffffff811115612a7c57600080fd5b6020830191508360208260051b8501011115611c3457600080fd5b60008060208385031215612aaa57600080fd5b823567ffffffffffffffff811115612ac157600080fd5b612acd85828601612a52565b90969095509350505050565b60008060008060008060608789031215612af257600080fd5b863567ffffffffffffffff80821115612b0a57600080fd5b612b168a838b01612a52565b90985096506020890135915080821115612b2f57600080fd5b612b3b8a838b01612a52565b90965094506040890135915080821115612b5457600080fd5b50612b6189828a01612a52565b979a9699509497509295939492505050565b803573ffffffffffffffffffffffffffffffffffffffff81168114612b9757600080fd5b919050565b600080600080600060608688031215612bb457600080fd5b853567ffffffffffffffff80821115612bcc57600080fd5b612bd889838a01612a52565b9097509550859150612bec60208901612b73565b94506040880135915080821115612c0257600080fd5b818801915088601f830112612c1657600080fd5b813581811115612c2557600080fd5b896020828501011115612c3757600080fd5b9699959850939650602001949392505050565b600060208284031215612c5c57600080fd5b5035919050565b80357fffffffff0000000000000000000000000000000000000000000000000000000081168114612b9757600080fd5b8015158114612ca157600080fd5b50565b60008060408385031215612cb757600080fd5b612cc083612c63565b91506020830135612cd081612c93565b809150509250929050565b60008060408385031215612cee57600080fd5b82359150612cfe60208401612b73565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff81118282101715612d5957612d59612d07565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715612da657612da6612d07565b604052919050565b600067ffffffffffffffff821115612dc857612dc8612d07565b5060051b60200190565b60008060408385031215612de557600080fd5b8235915060208084013567ffffffffffffffff811115612e0457600080fd5b8401601f81018613612e1557600080fd5b8035612e28612e2382612dae565b612d5f565b81815260059190911b82018301908381019088831115612e4757600080fd5b928401925b82841015612e6c57612e5d84612b73565b82529284019290840190612e4c565b80955050505050509250929050565b803560038110612b9757600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60038110612ef0577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b8183526000602080850194508260005b85811015612f49577fffffffff00000000000000000000000000000000000000000000000000000000612f3683612c63565b1687529582019590820190600101612f04565b509495945050505050565b60208082528181018390526000906040808401600586811b8601830188865b8981101561309b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc089840301855281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa18c3603018112612fd457600080fd5b8b01606073ffffffffffffffffffffffffffffffffffffffff612ff683612b73565b168552613004898301612e7b565b6130108a870182612eb9565b50878201357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe183360301811261304557600080fd5b90910188810191903567ffffffffffffffff81111561306357600080fd5b80871b360383131561307457600080fd5b81898701526130868287018285612ef4565b978a0197955050509187019150600101612f73565b50909998505050505050505050565b60006130b8612e2384612dae565b83815260208082019190600586811b8601368111156130d657600080fd5b865b818110156131c557803567ffffffffffffffff808211156130f95760008081fd5b818a0191506060823603121561310f5760008081fd5b613117612d36565b61312083612b73565b815261312d878401612e7b565b87820152604080840135838111156131455760008081fd5b939093019236601f85011261315c57600092508283fd5b8335925061316c612e2384612dae565b83815292871b840188019288810190368511156131895760008081fd5b948901945b848610156131ae5761319f86612c63565b8252948901949089019061318e565b9183019190915250885250509483019483016130d8565b5092979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610c8757610c876131d2565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561325557600080fd5b61325e82612b73565b9392505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261329a57600080fd5b83018035915067ffffffffffffffff8211156132b557600080fd5b602001915036819003821315611c3457600080fd5b600081518084526020808501945080840160005b83811015612f495781517fffffffff0000000000000000000000000000000000000000000000000000000016875295820195908201906001016132de565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000610ee560408301846132ca565b60006020828403121561335d57600080fd5b815161325e81612c93565b81810381811115610c8757610c876131d2565b6000826133b1577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60005b838110156133d15781810151838201526020016133b9565b50506000910152565b600081518084526133f28160208601602086016133b6565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6000606080830181845280875180835260808601915060808160051b87010192506020808a0160005b838110156134d4577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80898703018552815173ffffffffffffffffffffffffffffffffffffffff8151168752838101516134a885890182612eb9565b506040908101519087018890526134c1878901826132ca565b965050938201939082019060010161344d565b505073ffffffffffffffffffffffffffffffffffffffff8916908701525050838103604085015261350581866133da565b979650505050505050565b60006020828403121561352257600080fd5b81516fffffffffffffffffffffffffffffffff8116811461325e57600080fd5b828152604060208201526000610ee560408301846133da565b6000825161356d8184602087016133b6565b9190910192915050565b60006020828403121561358957600080fd5b5051919050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036135c1576135c16131d2565b5060010190565b6000816135d7576135d76131d2565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b8082028115828204841417610c8757610c876131d2565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000610ee560408301846133da565b60208152600061325e60208301846133da56fe4c69624469616d6f6e644375743a2041646420666163657420686173206e6f20636f64654c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a205265706c61636520666163657420686173206e6f20636f6465a2646970667358221220c5a8c10b22f20cde3fe0431ff57305237423677a60888f5b349fc6751336ae1464736f6c63430008150033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100d45760003560e01c806379c0d58d11610081578063afb877bb1161005b578063afb877bb146101d9578063de675a6d146101ec578063e33ecf0a1461023857600080fd5b806379c0d58d14610192578063836d6bfb146101b35780638824a0bb146101c657600080fd5b806326fc3ef4116100b257806326fc3ef4146101145780632f4d98ea1461015c5780633c0985681461017f57600080fd5b806313c34f4b146100d95780631c776dd5146100ee5780631f931c1c14610101575b600080fd5b6100ec6100e7366004612a97565b61024b565b005b6100ec6100fc366004612ad9565b6104df565b6100ec61010f366004612b9c565b610a76565b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9bf546040516fffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b61016f61016a366004612c4a565b610c7b565b6040519015158152602001610153565b6100ec61018d366004612ca4565b610c8d565b6101a56101a0366004612c4a565b610df2565b604051908152602001610153565b61016f6101c1366004612cdb565b610e4c565b6100ec6101d4366004612dd2565b610eed565b6100ec6101e7366004612a97565b610fe1565b6102137f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610153565b6101a5610246366004612a97565b61130e565b3360009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff1615801561028a5750303314155b156102c1576040517f6238ee3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610369576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064015b60405180910390fd5b60008080527f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be6020527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d3906103be848461130e565b60008181526020848152604080832033845290915290205490915060ff16610412576040517fedc5708300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051808201825260008082526020808301828152858352868252848320338452909152908390209151825491517fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000009092169015157fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff161761010067ffffffffffffffff90921691909102179055517f3c3d8c1f0b0faff6fe0ace6b485d0595a0106dce9e303f956fd941ebdbe9a98e906104d19086908690612f54565b60405180910390a150505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610582576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b8281146105bb576040517fe854148500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6105cd6105c886886130aa565b611435565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b754600003610650576040517fa788861700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061065c878761130e565b905061069a8585808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506115b392505050565b506106d881868680806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250610eed92505050565b60006106e382610c7b565b90506000816106f35760016106f6565b60005b60ff169050806107046116d0565b61070e9190613201565b61071784610df2565b6107219088613201565b1015610759576040517f709fb08000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805b878110156109a0576107d989898381811061077a5761077a613214565b905060200201602081019061078f9190613243565b73ffffffffffffffffffffffffffffffffffffffff1660009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff1690565b1580156108225750308989838181106107f4576107f4613214565b90506020020160208101906108099190613243565b73ffffffffffffffffffffffffffffffffffffffff1614155b15610859576040517f7b2cbbb400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3089898381811061086c5761086c613214565b90506020020160208101906108819190613243565b73ffffffffffffffffffffffffffffffffffffffff16036108d95783156108d4576040517fee21708000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600191505b6109628989838181106108ee576108ee613214565b90506020020160208101906109039190613243565b8689898581811061091657610916613214565b90506020028101906109289190613265565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061174f92505050565b610998576040517fac3d341600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60010161075d565b50801580156109ad575082155b156109e4576040517f6d21730400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9bf80546fffffffffffffffffffffffffffffffff808216600101167fffffffffffffffffffffffffffffffff00000000000000000000000000000000909116179055610a6a610a538a8c6130aa565b6000604051806020016040528060008152506117ca565b50505050505050505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610b19576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b610b2161195f565b610b2e6105c885876130aa565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75415610baf576040517fa788861700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff831615610bfd576040517f871cb76100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be5b600190810180547fffffffffffffffffffffffffffffffff0000000000000000000000000000000081166fffffffffffffffffffffffffffffffff91821690930116919091179055610c74610a5385876130aa565b5050505050565b6000610c878230610e4c565b92915050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610d30576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b610d3861195f565b7fffffffff00000000000000000000000000000000000000000000000000000000821660008181527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4922602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001685151590811790915582519384529083015280517f4e6bd17989efa6d6a9607ccaac1bba27b29f99622bc830d99a3a9883b21a19c79281900390910190a15050565b600080610dfd6119ca565b805190915060005b81811015610e4457610e3085848381518110610e2357610e23613214565b6020026020010151610e4c565b15610e3c578360010193505b600101610e05565b505050919050565b60008281527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d36020818152604080842073ffffffffffffffffffffffffffffffffffffffff8616855290915282205460ff168015610ee5575060008481526020828152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152902054610100900467ffffffffffffffff1642105b949350505050565b6000610ef76119ca565b805183519192509060005b82811015610fd957610f2086858381518110610e2357610e23613214565b15610fd15760005b82811015610fcf57848281518110610f4257610f42613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16868281518110610f7257610f72613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603610fc7576040517f50f5729f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600101610f28565b505b600101610f02565b505050505050565b3360009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff161580156110205750303314155b15611057576040517f6238ee3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff9081164290911610156110fa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75460000361117d576040517f3a76e1f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080527f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be6020527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d36111d36105c883856130aa565b60006111df848461130e565b905060006111eb611af4565b6111f59042613201565b6040805180820182526001815267ffffffffffffffff838116602080840191825260008881528982528581203382529091528490209251835491517fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000009092169015157fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff16176101009190921602179055519091507f6248ff757895beed7d43d135bccf59a26b7fbdf0fe8233487c44e82c0f266ba3906112b89087908790612f54565b60405180910390a16112c86116d0565b6112d183610df2565b101580156112e357506112e382610c7b565b15610c74577f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be610c1f565b60008282604051602001611323929190612f54565b6040516020818303038152906040528051906020012030466113627f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be90565b6001015460408051602081019590955273ffffffffffffffffffffffffffffffffffffffff9093169284019290925260608301526fffffffffffffffffffffffffffffffff16608082015260a001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905280516020918201207f19457468657265756d205369676e6564204d6573736167653a0a33320000000091830191909152603c820152605c0160405160208183030381529060405280519060200120905092915050565b805160005b818110156115ae57600083828151811061145657611456613214565b602002602001015160200151600281111561147357611473612e8a565b14806114ad5750600183828151811061148e5761148e613214565b60200260200101516020015160028111156114ab576114ab612e8a565b145b156115a657600254835173ffffffffffffffffffffffffffffffffffffffff9091169063df871f72908590849081106114e8576114e8613214565b60200260200101516000015185848151811061150657611506613214565b6020026020010151604001516040518363ffffffff1660e01b815260040161152f92919061331c565b602060405180830381865afa15801561154c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611570919061334b565b6115a6576040517ff41a931c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60010161143a565b505050565b80516000908082036115f1576040517f3aee2eec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b6115ff600183613368565b8110156116c6576000611613826001613201565b90505b828110156116bd5784818151811061163057611630613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1685838151811061166057611660613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16036116b5576040517f8dd19e7d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600101611616565b506001016115f4565b5060009392505050565b600080611723600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75490565b905080156117465761173660028261337b565b611741906001613201565b611749565b60005b91505090565b600080600061175e8585611bf6565b9092509050600081600481111561177757611777612e8a565b1480156117af57508573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b806117c057506117c0868686611c3b565b9695505050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921547f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff8116908190600090600716156118395750600381901c60009081526001840160205260409020545b60005b87518110156118b6576118a983838a848151811061185c5761185c613214565b6020026020010151600001518b858151811061187a5761187a613214565b6020026020010151602001518c868151811061189857611898613214565b602002602001015160400151611d98565b909350915060010161183c565b508282146118ef576002840180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff84161790555b600782161561191157600382901c600090815260018501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb67387878760405161194493929190613424565b60405180910390a16119568686612829565b50505050505050565b3330146119c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4c69624469616d6f6e643a2043616c6c6572206e6f742073656c6600000000006044820152606401610360565b565b60008080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b780546060929067ffffffffffffffff811115611a3257611a32612d07565b604051908082528060200260200182016040528015611a5b578160200160208202803683370190505b50825490915060005b81811015611aeb57836000018181548110611a8157611a81613214565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16838281518110611abe57611abe613214565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101611a64565b50909392505050565b6040517f52430c8d0000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906352430c8d90602401602060405180830381865afa158015611b81573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ba59190613510565b6fffffffffffffffffffffffffffffffff16905060008111611bf3576040517fdac5ec8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b90565b6000808251604103611c2c5760208301516040840151606085015160001a611c2087828585612928565b94509450505050611c34565b506000905060025b9250929050565b60008060008573ffffffffffffffffffffffffffffffffffffffff16631626ba7e60e01b8686604051602401611c72929190613542565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909416939093179092529051611cfb919061355b565b600060405180830381855afa9150503d8060008114611d36576040519150601f19603f3d011682016040523d82523d6000602084013e611d3b565b606091505b5091509150818015611d4f57506020815110155b80156117c0575080517f1626ba7e0000000000000000000000000000000000000000000000000000000090611d8d9083016020908101908401613577565b149695505050505050565b600080807f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f90506000845111611e50576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610360565b6000856002811115611e6457611e64612e8a565b0361203457611e8b8660405180606001604052806024815260200161365760249139612a17565b60005b845181101561202e576000858281518110611eab57611eab613214565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c15611f7e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c72656164792065786973747300000000000000000000006064820152608401610360565b7fffffffff0000000000000000000000000000000000000000000000000000000080831660008181526020879052604090207fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608d901b168e17905560e060058e901b811692831c199c909c1690821c179a8190036120125760038c901c600090815260018601602052604081209b909b555b8b61201c81613590565b9c505060019093019250611e8e915050565b5061281d565b600185600281111561204857612048612e8a565b036123385761206f866040518060600160405280602881526020016136a360289139612a17565b60005b845181101561202e57600085828151811061208f5761208f613214565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c308103612164576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4c69624469616d6f6e644375743a2043616e2774207265706c61636520696d6d60448201527f757461626c652066756e6374696f6e00000000000000000000000000000000006064820152608401610360565b8973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361221f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e00000000000000006064820152608401610360565b73ffffffffffffffffffffffffffffffffffffffff81166122c2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e207468617420646f65736e277420657869737400000000000000006064820152608401610360565b507fffffffff0000000000000000000000000000000000000000000000000000000090911660009081526020849052604090206bffffffffffffffffffffffff919091167fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608a901b16179055600101612072565b600285600281111561234c5761234c612e8a565b036127955773ffffffffffffffffffffffffffffffffffffffff8616156123f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d7573742062652061646472657373283029000000000000000000006064820152608401610360565b600388901c6007891660005b86518110156127755760008a900361243d578261241d816135c8565b60008181526001870160205260409020549b5093506007925061244b9050565b81612447816135c8565b9250505b6000806000808a858151811061246357612463613214565b6020908102919091018101517fffffffff0000000000000000000000000000000000000000000000000000000081166000908152918a9052604090912054909150606081901c612535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608401610360565b30606082901c036125c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e0000000000000000000000000000000000006064820152608401610360565b600587901b8f901b94507fffffffff0000000000000000000000000000000000000000000000000000000080861690831614612666577fffffffff000000000000000000000000000000000000000000000000000000008516600090815260208a90526040902080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff83161790555b7fffffffff0000000000000000000000000000000000000000000000000000000091909116600090815260208990526040812055600381901c611fff16925060051b60e01690508582146126fb576000828152600188016020526040902080547fffffffff0000000000000000000000000000000000000000000000000000000080841c19909116908516831c17905561274c565b80837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c817fffffffff0000000000000000000000000000000000000000000000000000000060001b901c198e16179c505b8460000361276a57600086815260018801602052604081208190559c505b505050600101612401565b50806127828360086135fd565b61278c9190613201565b9950505061281d565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560448201527f74416374696f6e000000000000000000000000000000000000000000000000006064820152608401610360565b50959694955050505050565b73ffffffffffffffffffffffffffffffffffffffff8216612848575050565b61286a8260405180606001604052806028815260200161367b60289139612a17565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051612892919061355b565b600060405180830381855af49150503d80600081146128cd576040519150601f19603f3d011682016040523d82523d6000602084013e6128d2565b606091505b509150915081612922578051156128ec5780518082602001fd5b83836040517f192105d7000000000000000000000000000000000000000000000000000000008152600401610360929190613614565b50505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561295f5750600090506003612a0e565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156129b3573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116612a0757600060019250925050612a0e565b9150600090505b94509492505050565b813b8181612922576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103609190613643565b60008083601f840112612a6457600080fd5b50813567ffffffffffffffff811115612a7c57600080fd5b6020830191508360208260051b8501011115611c3457600080fd5b60008060208385031215612aaa57600080fd5b823567ffffffffffffffff811115612ac157600080fd5b612acd85828601612a52565b90969095509350505050565b60008060008060008060608789031215612af257600080fd5b863567ffffffffffffffff80821115612b0a57600080fd5b612b168a838b01612a52565b90985096506020890135915080821115612b2f57600080fd5b612b3b8a838b01612a52565b90965094506040890135915080821115612b5457600080fd5b50612b6189828a01612a52565b979a9699509497509295939492505050565b803573ffffffffffffffffffffffffffffffffffffffff81168114612b9757600080fd5b919050565b600080600080600060608688031215612bb457600080fd5b853567ffffffffffffffff80821115612bcc57600080fd5b612bd889838a01612a52565b9097509550859150612bec60208901612b73565b94506040880135915080821115612c0257600080fd5b818801915088601f830112612c1657600080fd5b813581811115612c2557600080fd5b896020828501011115612c3757600080fd5b9699959850939650602001949392505050565b600060208284031215612c5c57600080fd5b5035919050565b80357fffffffff0000000000000000000000000000000000000000000000000000000081168114612b9757600080fd5b8015158114612ca157600080fd5b50565b60008060408385031215612cb757600080fd5b612cc083612c63565b91506020830135612cd081612c93565b809150509250929050565b60008060408385031215612cee57600080fd5b82359150612cfe60208401612b73565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff81118282101715612d5957612d59612d07565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715612da657612da6612d07565b604052919050565b600067ffffffffffffffff821115612dc857612dc8612d07565b5060051b60200190565b60008060408385031215612de557600080fd5b8235915060208084013567ffffffffffffffff811115612e0457600080fd5b8401601f81018613612e1557600080fd5b8035612e28612e2382612dae565b612d5f565b81815260059190911b82018301908381019088831115612e4757600080fd5b928401925b82841015612e6c57612e5d84612b73565b82529284019290840190612e4c565b80955050505050509250929050565b803560038110612b9757600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60038110612ef0577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b8183526000602080850194508260005b85811015612f49577fffffffff00000000000000000000000000000000000000000000000000000000612f3683612c63565b1687529582019590820190600101612f04565b509495945050505050565b60208082528181018390526000906040808401600586811b8601830188865b8981101561309b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc089840301855281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa18c3603018112612fd457600080fd5b8b01606073ffffffffffffffffffffffffffffffffffffffff612ff683612b73565b168552613004898301612e7b565b6130108a870182612eb9565b50878201357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe183360301811261304557600080fd5b90910188810191903567ffffffffffffffff81111561306357600080fd5b80871b360383131561307457600080fd5b81898701526130868287018285612ef4565b978a0197955050509187019150600101612f73565b50909998505050505050505050565b60006130b8612e2384612dae565b83815260208082019190600586811b8601368111156130d657600080fd5b865b818110156131c557803567ffffffffffffffff808211156130f95760008081fd5b818a0191506060823603121561310f5760008081fd5b613117612d36565b61312083612b73565b815261312d878401612e7b565b87820152604080840135838111156131455760008081fd5b939093019236601f85011261315c57600092508283fd5b8335925061316c612e2384612dae565b83815292871b840188019288810190368511156131895760008081fd5b948901945b848610156131ae5761319f86612c63565b8252948901949089019061318e565b9183019190915250885250509483019483016130d8565b5092979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610c8757610c876131d2565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561325557600080fd5b61325e82612b73565b9392505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261329a57600080fd5b83018035915067ffffffffffffffff8211156132b557600080fd5b602001915036819003821315611c3457600080fd5b600081518084526020808501945080840160005b83811015612f495781517fffffffff0000000000000000000000000000000000000000000000000000000016875295820195908201906001016132de565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000610ee560408301846132ca565b60006020828403121561335d57600080fd5b815161325e81612c93565b81810381811115610c8757610c876131d2565b6000826133b1577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60005b838110156133d15781810151838201526020016133b9565b50506000910152565b600081518084526133f28160208601602086016133b6565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6000606080830181845280875180835260808601915060808160051b87010192506020808a0160005b838110156134d4577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80898703018552815173ffffffffffffffffffffffffffffffffffffffff8151168752838101516134a885890182612eb9565b506040908101519087018890526134c1878901826132ca565b965050938201939082019060010161344d565b505073ffffffffffffffffffffffffffffffffffffffff8916908701525050838103604085015261350581866133da565b979650505050505050565b60006020828403121561352257600080fd5b81516fffffffffffffffffffffffffffffffff8116811461325e57600080fd5b828152604060208201526000610ee560408301846133da565b6000825161356d8184602087016133b6565b9190910192915050565b60006020828403121561358957600080fd5b5051919050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036135c1576135c16131d2565b5060010190565b6000816135d7576135d76131d2565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b8082028115828204841417610c8757610c876131d2565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000610ee560408301846133da565b60208152600061325e60208301846133da56fe4c69624469616d6f6e644375743a2041646420666163657420686173206e6f20636f64654c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a205265706c61636520666163657420686173206e6f20636f6465a2646970667358221220c5a8c10b22f20cde3fe0431ff57305237423677a60888f5b349fc6751336ae1464736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "Responsible for adding/removing/replace facets in Barz", + "kind": "dev", + "methods": { + "_checkDuplicateOnChainApprover(bytes32,address[])": { + "params": { + "_approvers": "List of approver addresses", + "_diamondCutHash": "Hash of diamondCut information including the facet addresses and function selectors" + } + }, + "approveDiamondCut((address,uint8,bytes4[])[])": { + "params": { + "_diamondCut": "Contains the facet addresses and function selectors" + } + }, + "constructor": { + "params": { + "_securityManager": "Security Manager contract that holds the security related variables for all wallets" + } + }, + "diamondCut((address,uint8,bytes4[])[],address,bytes)": { + "params": { + "_diamondCut": "Contains the facet addresses and function selectors", + "_init": "The address of the contract or facet to execute _calldata. It's prohibited in Barz" + } + }, + "diamondCutWithGuardian((address,uint8,bytes4[])[],address[],bytes[])": { + "params": { + "_approvers": "Guardian or owner address that approves the diamond cut", + "_diamondCut": "Contains the facet addresses and function selectors", + "_signatures": "Signature of Guardians or owner that approves the diamond cut" + } + }, + "getDiamondCutApprovalCountWithTimeValidity(bytes32)": { + "params": { + "_diamondCutHash": "Hash of diamondCut information including the facet addresses and function selectors" + } + }, + "getDiamondCutHash((address,uint8,bytes4[])[])": { + "params": { + "_diamondCut": "Contains the facet addresses and function selectors" + }, + "returns": { + "cutHash": "Diamond Cut Hash" + } + }, + "getDiamondCutNonce()": { + "details": "This method fetches the nonce from diamond cut storage", + "returns": { + "cutNonce": "Nonce of diamond cut to protect from reply attacks" + } + }, + "getOwnerCutApprovalWithTimeValidity(bytes32)": { + "params": { + "_diamondCutHash": "Hash of diamondCut information including the facet addresses and function selectors" + }, + "returns": { + "isApprovedByOwner": "Bool value showing if the owner approved the cut" + } + }, + "isCutApproved(bytes32,address)": { + "params": { + "_approver": "Address of approver", + "_diamondCutHash": "Hash of diamondCut information including the facet addresses and function selectors" + }, + "returns": { + "isApproved": "Bool value showing if the approver approved the cut" + } + }, + "revokeDiamondCutApproval((address,uint8,bytes4[])[])": { + "params": { + "_diamondCut": "Contains the facet addresses and function selectors" + } + }, + "updateSupportsInterface(bytes4,bool)": { + "params": { + "_flag": "Bool value to update the mapping of the given interface ID", + "_interfaceId": "InterfaceID to update the mapping" + } + } + }, + "title": "DiamondCut Facet", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "_checkDuplicateOnChainApprover(bytes32,address[])": { + "notice": "Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval Approvers who approved on-chain should not be included in the off-chain approval" + }, + "approveDiamondCut((address,uint8,bytes4[])[])": { + "notice": "Approves diamond cut. This can only be called directly from guardian or owner" + }, + "constructor": { + "notice": "This constructor sets the Security Manager address which is an immutable variable. Immutable variables do not impact the storage of diamond" + }, + "diamondCut((address,uint8,bytes4[])[],address,bytes)": { + "notice": "Add/replace/remove any number of functions and optionally execute a function with delegatecall when guardians don't exist" + }, + "diamondCutWithGuardian((address,uint8,bytes4[])[],address[],bytes[])": { + "notice": "Add/replace/remove any number of functions and optionally execute a function with delegatecall when guardians exist" + }, + "getDiamondCutApprovalCountWithTimeValidity(bytes32)": { + "notice": "Gets the number of approvals of diamond cut from guardians" + }, + "getDiamondCutHash((address,uint8,bytes4[])[])": { + "notice": "Returns the diamond cut hash. This function ensures that this hash is safe from replay attack by including salt, address, chainId, and nonce, etc." + }, + "getDiamondCutNonce()": { + "notice": "Returns the diamond cut nonce of this wallet" + }, + "getOwnerCutApprovalWithTimeValidity(bytes32)": { + "notice": "Returns if the owner has approved the diamond cut" + }, + "isCutApproved(bytes32,address)": { + "notice": "Returns if the given approver has approved the diamond cut" + }, + "revokeDiamondCutApproval((address,uint8,bytes4[])[])": { + "notice": "Revokes the approval of diamond cut. This can only be called directly from guardian or owner" + }, + "updateSupportsInterface(bytes4,bool)": { + "notice": "Updates the flag for the interfaceId" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 27823, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "s", + "offset": 0, + "slot": "0", + "type": "t_struct(AppStorage)27570_storage" + } + ], + "types": { + "t_bytes4": { + "encoding": "inplace", + "label": "bytes4", + "numberOfBytes": "4" + }, + "t_contract(IEntryPoint)12286": { + "encoding": "inplace", + "label": "contract IEntryPoint", + "numberOfBytes": "20" + }, + "t_contract(IFacetRegistry)26105": { + "encoding": "inplace", + "label": "contract IFacetRegistry", + "numberOfBytes": "20" + }, + "t_mapping(t_uint256,t_struct(InitializersStorage)27549_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => struct InitializersStorage)", + "numberOfBytes": "32", + "value": "t_struct(InitializersStorage)27549_storage" + }, + "t_mapping(t_uint256,t_struct(Lock)27542_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => struct Lock)", + "numberOfBytes": "32", + "value": "t_struct(Lock)27542_storage" + }, + "t_struct(AppStorage)27570_storage": { + "encoding": "inplace", + "label": "struct AppStorage", + "members": [ + { + "astId": 27554, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "initStorage", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_uint256,t_struct(InitializersStorage)27549_storage)" + }, + { + "astId": 27556, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "signerMigration", + "offset": 0, + "slot": "1", + "type": "t_uint8" + }, + { + "astId": 27558, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "validateOwnerSignatureSelector", + "offset": 1, + "slot": "1", + "type": "t_bytes4" + }, + { + "astId": 27561, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "entryPoint", + "offset": 5, + "slot": "1", + "type": "t_contract(IEntryPoint)12286" + }, + { + "astId": 27564, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "facetRegistry", + "offset": 0, + "slot": "2", + "type": "t_contract(IFacetRegistry)26105" + }, + { + "astId": 27569, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "locks", + "offset": 0, + "slot": "3", + "type": "t_mapping(t_uint256,t_struct(Lock)27542_storage)" + } + ], + "numberOfBytes": "128" + }, + "t_struct(InitializersStorage)27549_storage": { + "encoding": "inplace", + "label": "struct InitializersStorage", + "members": [ + { + "astId": 27544, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "signerInitialized", + "offset": 0, + "slot": "0", + "type": "t_uint8" + }, + { + "astId": 27546, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "accountInitialized", + "offset": 1, + "slot": "0", + "type": "t_uint8" + }, + { + "astId": 27548, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "restrictionsInitialized", + "offset": 2, + "slot": "0", + "type": "t_uint8" + } + ], + "numberOfBytes": "32" + }, + "t_struct(Lock)27542_storage": { + "encoding": "inplace", + "label": "struct Lock", + "members": [ + { + "astId": 27539, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "release", + "offset": 0, + "slot": "0", + "type": "t_uint64" + }, + { + "astId": 27541, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "locker", + "offset": 8, + "slot": "0", + "type": "t_bytes4" + } + ], + "numberOfBytes": "32" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint64": { + "encoding": "inplace", + "label": "uint64", + "numberOfBytes": "8" + }, + "t_uint8": { + "encoding": "inplace", + "label": "uint8", + "numberOfBytes": "1" + } + } + } +} \ No newline at end of file diff --git a/deployments/avalanche/DiamondLoupeFacet.json b/deployments/avalanche/DiamondLoupeFacet.json new file mode 100644 index 0000000..daa0051 --- /dev/null +++ b/deployments/avalanche/DiamondLoupeFacet.json @@ -0,0 +1,306 @@ +{ + "address": "0xCe36b85d12D81cd619C745c7717f3396E184Ac7C", + "abi": [ + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_functionSelector", + "type": "bytes4" + } + ], + "name": "facetAddress", + "outputs": [ + { + "internalType": "address", + "name": "facetAddress_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_functionSelector", + "type": "bytes4" + } + ], + "name": "facetAddressFromStorage", + "outputs": [ + { + "internalType": "address", + "name": "facetAddress_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetAddresses", + "outputs": [ + { + "internalType": "address[]", + "name": "facetAddresses_", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetAddressesFromStorage", + "outputs": [ + { + "internalType": "address[]", + "name": "facetAddresses_", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_facet", + "type": "address" + } + ], + "name": "facetFunctionSelectors", + "outputs": [ + { + "internalType": "bytes4[]", + "name": "facetFunctionSelectors_", + "type": "bytes4[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_facet", + "type": "address" + } + ], + "name": "facetFunctionSelectorsFromStorage", + "outputs": [ + { + "internalType": "bytes4[]", + "name": "facetFunctionSelectors_", + "type": "bytes4[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facets", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondLoupe.Facet[]", + "name": "facets_", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetsFromStorage", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondLoupe.Facet[]", + "name": "facets_", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "isSupported", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0xfed67040c18928453fc92245a08390256dce0c741ff5dcc40331ccd7db4f71ab", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 251, + "gasUsed": "2036373", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0xd254f00272e5544628e403326f2f041896777213e6b332b37b358165d10b283c", + "transactionHash": "0xfed67040c18928453fc92245a08390256dce0c741ff5dcc40331ccd7db4f71ab", + "logs": [], + "blockNumber": 38010785, + "cumulativeGasUsed": "8904900", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 3, + "solcInputHash": "4356503edd8ae34e73cb6dd1c8e2fc8a", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_functionSelector\",\"type\":\"bytes4\"}],\"name\":\"facetAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"facetAddress_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_functionSelector\",\"type\":\"bytes4\"}],\"name\":\"facetAddressFromStorage\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"facetAddress_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetAddresses\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"facetAddresses_\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetAddressesFromStorage\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"facetAddresses_\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_facet\",\"type\":\"address\"}],\"name\":\"facetFunctionSelectors\",\"outputs\":[{\"internalType\":\"bytes4[]\",\"name\":\"facetFunctionSelectors_\",\"type\":\"bytes4[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_facet\",\"type\":\"address\"}],\"name\":\"facetFunctionSelectorsFromStorage\",\"outputs\":[{\"internalType\":\"bytes4[]\",\"name\":\"facetFunctionSelectors_\",\"type\":\"bytes4[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facets\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondLoupe.Facet[]\",\"name\":\"facets_\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetsFromStorage\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondLoupe.Facet[]\",\"name\":\"facets_\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isSupported\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"DiamondLoupe contract compatible with EIP-2535\",\"kind\":\"dev\",\"methods\":{\"facetAddress(bytes4)\":{\"details\":\"If facet is not found return address(0).\",\"params\":{\"_functionSelector\":\"The function selector.\"},\"returns\":{\"facetAddress_\":\"The facet address.\"}},\"facetAddressFromStorage(bytes4)\":{\"params\":{\"_functionSelector\":\"Function selector to fetch the facet address from diamond storage\"},\"returns\":{\"facetAddress_\":\"Facet address mapped with the function selector\"}},\"facetAddresses()\":{\"returns\":{\"facetAddresses_\":\"facetAddresses_\"}},\"facetAddressesFromStorage()\":{\"returns\":{\"facetAddresses_\":\"All facet addresses attached directly to diamond storage\"}},\"facetFunctionSelectors(address)\":{\"params\":{\"_facet\":\"The facet address.\"},\"returns\":{\"facetFunctionSelectors_\":\"facetFunctionSelectors_\"}},\"facetFunctionSelectorsFromStorage(address)\":{\"params\":{\"_facet\":\"Facet address to fetch the facet function selectors from diamond storage\"},\"returns\":{\"facetFunctionSelectors_\":\"Facet function selectors of the given facet address\"}},\"facets()\":{\"details\":\"Barz uses a special architecture called default fallback handler. Default Fallback handler is used as a middleware that holds the mapping of facet function selector and facet address that Barz uses. This helps Barz to reduce significant amount of gas during the initialization process. Hence, this method aggregates both the facet information from DefaulFallbackHandler and in diamond storage and shows the data to users.\",\"returns\":{\"facets_\":\"Facet\"}},\"facetsFromStorage()\":{\"returns\":{\"facets_\":\"Facet information attached directly to diamond storage\"}},\"supportsInterface(bytes4)\":{\"params\":{\"_interfaceId\":\"Interface ID for detecting the interface\"},\"returns\":{\"isSupported\":\"Bool value showing if the standard is supported in the contract\"}}},\"title\":\"DiamondLoupe Facet\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"facetAddress(bytes4)\":{\"notice\":\"Gets the facet that supports the given selector.\"},\"facetAddressFromStorage(bytes4)\":{\"notice\":\"Returns the facet address attached to the given function selector. This excludes the facets from the default fallback handler\"},\"facetAddresses()\":{\"notice\":\"Get all the facet addresses used by Barz.\"},\"facetAddressesFromStorage()\":{\"notice\":\"Returns all facet addresses attached directly to diamond storage. This excludes the facets from the default fallback handler\"},\"facetFunctionSelectors(address)\":{\"notice\":\"Gets all the function selectors provided by a facet.\"},\"facetFunctionSelectorsFromStorage(address)\":{\"notice\":\"Returns function selectors of given facet address attached directly to diamond storage. This excludes the facets from the default fallback handler\"},\"facets()\":{\"notice\":\"Gets all facets and their selectors.\"},\"facetsFromStorage()\":{\"notice\":\"Returns the facet from the diamond storage. This excludes the facets from the default fallback handler\"},\"supportsInterface(bytes4)\":{\"notice\":\"SupportInterface to be compatible with EIP 165\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/base/DiamondLoupeFacet.sol\":\"DiamondLoupeFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/introspection/IERC165.sol\\\";\\n\\n/**\\n * @dev _Available since v3.1._\\n */\\ninterface IERC1155Receiver is IERC165 {\\n /**\\n * @dev Handles the receipt of a single ERC1155 token type. This function is\\n * called at the end of a `safeTransferFrom` after the balance has been updated.\\n *\\n * NOTE: To accept the transfer, this must return\\n * `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))`\\n * (i.e. 0xf23a6e61, or its own function selector).\\n *\\n * @param operator The address which initiated the transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param id The ID of the token being transferred\\n * @param value The amount of tokens being transferred\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155Received(\\n address operator,\\n address from,\\n uint256 id,\\n uint256 value,\\n bytes calldata data\\n ) external returns (bytes4);\\n\\n /**\\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\\n * is called at the end of a `safeBatchTransferFrom` after the balances have\\n * been updated.\\n *\\n * NOTE: To accept the transfer(s), this must return\\n * `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))`\\n * (i.e. 0xbc197c81, or its own function selector).\\n *\\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155BatchReceived(\\n address operator,\\n address from,\\n uint256[] calldata ids,\\n uint256[] calldata values,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xeb373f1fdc7b755c6a750123a9b9e3a8a02c1470042fd6505d875000a80bde0b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title ERC721 token receiver interface\\n * @dev Interface for any contract that wants to support safeTransfers\\n * from ERC721 asset contracts.\\n */\\ninterface IERC721Receiver {\\n /**\\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\\n * by `operator` from `from`, this function is called.\\n *\\n * It must return its Solidity selector to confirm the token transfer.\\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\\n *\\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\\n */\\n function onERC721Received(\\n address operator,\\n address from,\\n uint256 tokenId,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\\n *\\n * Accounts can be notified of {IERC777} tokens being sent to them by having a\\n * contract implement this interface (contract holders can be their own\\n * implementer) and registering it on the\\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\\n *\\n * See {IERC1820Registry} and {ERC1820Implementer}.\\n */\\ninterface IERC777Recipient {\\n /**\\n * @dev Called by an {IERC777} token contract whenever tokens are being\\n * moved or created into a registered account (`to`). The type of operation\\n * is conveyed by `from` being the zero address or not.\\n *\\n * This call occurs _after_ the token contract's state is updated, so\\n * {IERC777-balanceOf}, etc., can be used to query the post-operation state.\\n *\\n * This function may revert to prevent the operation from being executed.\\n */\\n function tokensReceived(\\n address operator,\\n address from,\\n address to,\\n uint256 amount,\\n bytes calldata userData,\\n bytes calldata operatorData\\n ) external;\\n}\\n\",\"keccak256\":\"0x1a5d61db2733202ba361e6d6741cd2e662380e22b80e987eacfc91973f2267dc\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"contracts/facets/base/DiamondLoupeFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IERC777Recipient} from \\\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\\\";\\nimport {IERC165} from \\\"../../interfaces/ERC/IERC165.sol\\\";\\nimport {IERC1271} from \\\"../../interfaces/ERC/IERC1271.sol\\\";\\nimport {IERC677Receiver} from \\\"../../interfaces/ERC/IERC677Receiver.sol\\\";\\nimport {IERC721Receiver} from \\\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\\\";\\nimport {IERC1155Receiver} from \\\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\\\";\\nimport {LibDiamond} from \\\"../../libraries/LibDiamond.sol\\\";\\nimport {LibLoupe} from \\\"../../libraries/LibLoupe.sol\\\";\\nimport {LibUtils} from \\\"../../libraries/LibUtils.sol\\\";\\nimport {IDiamondCut} from \\\"../../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IStorageLoupe} from \\\"./interfaces/IStorageLoupe.sol\\\";\\nimport {IDiamondLoupe} from \\\"./interfaces/IDiamondLoupe.sol\\\";\\n\\n/**\\n * @title DiamondLoupe Facet\\n * @dev DiamondLoupe contract compatible with EIP-2535\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract DiamondLoupeFacet is IDiamondLoupe, IStorageLoupe, IERC165 {\\n // Diamond Loupe Functions\\n ////////////////////////////////////////////////////////////////////\\n /// These functions are expected to be called frequently by tools off-chain.\\n\\n /**\\n * @notice Gets all facets and their selectors.\\n * @dev Barz uses a special architecture called default fallback handler. Default Fallback handler is used as a middleware\\n * that holds the mapping of facet function selector and facet address that Barz uses. This helps Barz to reduce\\n * significant amount of gas during the initialization process.\\n * Hence, this method aggregates both the facet information from DefaulFallbackHandler and in diamond storage and shows the data to users.\\n * @return facets_ Facet\\n */\\n function facets() public view override returns (Facet[] memory facets_) {\\n Facet[] memory defaultFacet = LibDiamond\\n .diamondStorage()\\n .defaultFallbackHandler\\n .facets();\\n Facet[] memory _facets = LibLoupe.facets();\\n uint256 numFacets = _facets.length;\\n bytes4[] memory keys;\\n address[] memory values;\\n for (uint256 i; i < numFacets; ) {\\n uint256 selectorsLength = _facets[i].functionSelectors.length;\\n for (uint256 j; j < selectorsLength; ) {\\n (keys, values) = LibUtils.setValue(\\n keys,\\n values,\\n _facets[i].functionSelectors[j],\\n _facets[i].facetAddress\\n );\\n unchecked {\\n ++j;\\n }\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n {\\n bool iIncrement;\\n for (uint256 i; i < defaultFacet.length; ) {\\n bool jIncrement;\\n for (\\n uint256 j;\\n j < defaultFacet[i].functionSelectors.length;\\n\\n ) {\\n if (\\n LibUtils.getValue(\\n keys,\\n values,\\n defaultFacet[i].functionSelectors[j]\\n ) != address(0)\\n ) {\\n if (defaultFacet[i].functionSelectors.length == 1) {\\n defaultFacet = LibUtils.removeFacetElement(\\n defaultFacet,\\n i\\n );\\n iIncrement = true;\\n break;\\n }\\n defaultFacet[i].functionSelectors = LibUtils\\n .removeElement(\\n defaultFacet[i].functionSelectors,\\n j\\n );\\n jIncrement = true;\\n }\\n if (!jIncrement) {\\n unchecked {\\n ++j;\\n }\\n } else {\\n jIncrement = false;\\n }\\n }\\n if (!iIncrement) {\\n unchecked {\\n ++i;\\n }\\n } else {\\n iIncrement = false;\\n }\\n }\\n }\\n {\\n uint256 facetLength = numFacets + defaultFacet.length;\\n facets_ = new Facet[](facetLength);\\n uint256 defaultFacetIndex;\\n for (uint256 i; i < facetLength; ) {\\n if (i < numFacets) {\\n facets_[i] = _facets[i];\\n bool jIncrementor;\\n for (uint256 j; j < defaultFacet.length; ) {\\n if (\\n facets_[i].facetAddress ==\\n defaultFacet[j].facetAddress\\n ) {\\n facets_[i].functionSelectors = LibUtils.mergeArrays(\\n _facets[i].functionSelectors,\\n defaultFacet[j].functionSelectors\\n );\\n defaultFacet = LibUtils.removeFacetElement(\\n defaultFacet,\\n j\\n );\\n jIncrementor = true;\\n {\\n facets_ = LibUtils.removeFacetElement(\\n facets_,\\n facets_.length - 1\\n );\\n }\\n --facetLength;\\n }\\n if (!jIncrementor) {\\n unchecked {\\n ++j;\\n }\\n } else {\\n jIncrementor = false;\\n }\\n }\\n } else {\\n facets_[i] = defaultFacet[defaultFacetIndex];\\n ++defaultFacetIndex;\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n }\\n\\n /**\\n * @notice Gets all the function selectors provided by a facet.\\n * @param _facet The facet address.\\n * @return facetFunctionSelectors_\\n */\\n function facetFunctionSelectors(\\n address _facet\\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\\n Facet[] memory facet = facets();\\n uint256 facetLength = facet.length;\\n for (uint256 i; i < facetLength; ) {\\n if (facet[i].facetAddress == _facet)\\n return facet[i].functionSelectors;\\n unchecked {\\n ++i;\\n }\\n }\\n return facetFunctionSelectors_;\\n }\\n\\n /**\\n * @notice Get all the facet addresses used by Barz.\\n * @return facetAddresses_\\n */\\n function facetAddresses()\\n external\\n view\\n override\\n returns (address[] memory facetAddresses_)\\n {\\n Facet[] memory facet = facets();\\n uint256 facetLength = facet.length;\\n facetAddresses_ = new address[](facetLength);\\n for (uint256 i; i < facetLength; ) {\\n facetAddresses_[i] = facet[i].facetAddress;\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * @notice Gets the facet that supports the given selector.\\n * @dev If facet is not found return address(0).\\n * @param _functionSelector The function selector.\\n * @return facetAddress_ The facet address.\\n */\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view override returns (address facetAddress_) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n\\n facetAddress_ = address(bytes20(ds.facets[_functionSelector]));\\n if (facetAddress_ == address(0)) {\\n facetAddress_ = IDiamondLoupe(ds.defaultFallbackHandler)\\n .facetAddress(_functionSelector);\\n }\\n }\\n\\n /**\\n * @notice SupportInterface to be compatible with EIP 165\\n * @param _interfaceId Interface ID for detecting the interface\\n * @return isSupported Bool value showing if the standard is supported in the contract\\n */\\n function supportsInterface(\\n bytes4 _interfaceId\\n ) external view override returns (bool isSupported) {\\n isSupported =\\n _interfaceId == type(IERC165).interfaceId ||\\n _interfaceId == IDiamondCut.diamondCut.selector ||\\n _interfaceId == type(IDiamondLoupe).interfaceId ||\\n _interfaceId == type(IERC1155Receiver).interfaceId ||\\n _interfaceId == type(IERC721Receiver).interfaceId ||\\n _interfaceId == type(IERC777Recipient).interfaceId ||\\n _interfaceId == IERC1271.isValidSignature.selector ||\\n _interfaceId == type(IERC677Receiver).interfaceId ||\\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId];\\n }\\n\\n /**\\n * @notice Returns the facet from the diamond storage. This excludes the facets from the default fallback handler\\n * @return facets_ Facet information attached directly to diamond storage\\n */\\n function facetsFromStorage()\\n external\\n view\\n override\\n returns (Facet[] memory facets_)\\n {\\n facets_ = LibLoupe.facets();\\n }\\n\\n /**\\n * @notice Returns the facet address attached to the given function selector. This excludes the facets from the default fallback handler\\n * @param _functionSelector Function selector to fetch the facet address from diamond storage\\n * @return facetAddress_ Facet address mapped with the function selector\\n */\\n function facetAddressFromStorage(\\n bytes4 _functionSelector\\n ) external view override returns (address facetAddress_) {\\n facetAddress_ = LibLoupe.facetAddress(_functionSelector);\\n }\\n\\n /**\\n * @notice Returns all facet addresses attached directly to diamond storage. This excludes the facets from the default fallback handler\\n * @return facetAddresses_ All facet addresses attached directly to diamond storage\\n */\\n function facetAddressesFromStorage()\\n external\\n view\\n override\\n returns (address[] memory facetAddresses_)\\n {\\n facetAddresses_ = LibLoupe.facetAddresses();\\n }\\n\\n /**\\n * @notice Returns function selectors of given facet address attached directly to diamond storage. This excludes the facets from the default fallback handler\\n * @param _facet Facet address to fetch the facet function selectors from diamond storage\\n * @return facetFunctionSelectors_ Facet function selectors of the given facet address\\n */\\n function facetFunctionSelectorsFromStorage(\\n address _facet\\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\\n facetFunctionSelectors_ = LibLoupe.facetFunctionSelectors(_facet);\\n }\\n}\\n\",\"keccak256\":\"0xf392fde159eec6483fc15fa323ecd6d764028f5b8734a66662c4116292363794\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IStorageLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"./IDiamondLoupe.sol\\\";\\n\\n/**\\n * @title LoupeFromStorage Interface\\n * @dev Interface contract to function as a loupe facet directly attached to diamond storage of Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IStorageLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facetsFromStorage()\\n external\\n view\\n returns (IDiamondLoupe.Facet[] memory);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n function facetFunctionSelectorsFromStorage(\\n address _facet\\n ) external view returns (bytes4[] memory);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n function facetAddressesFromStorage()\\n external\\n view\\n returns (address[] memory);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n function facetAddressFromStorage(\\n bytes4 _functionSelector\\n ) external view returns (address);\\n}\\n\",\"keccak256\":\"0xdf5dc9c57319e9087628c9cf9404b4f75585b76d1c2f4f59ee796c933967ea5c\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC1271 {\\n function isValidSignature(\\n bytes32 hash,\\n bytes memory signature\\n ) external view returns (bytes4);\\n}\\n\",\"keccak256\":\"0xcdddb7d5641c9d3f2432dec7fd13fddb9ae1480f25c76c21511e2fa16b8bd422\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.21;\\n\\ninterface IERC165 {\\n /// @notice Query if a contract implements an interface\\n /// @param interfaceId The interface identifier, as specified in ERC-165\\n /// @dev Interface identification is specified in ERC-165. This function\\n /// uses less than 30,000 gas.\\n /// @return `true` if the contract implements `interfaceID` and\\n /// `interfaceID` is not 0xffffffff, `false` otherwise\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xbb7f07e170898793c5535cc4b7e8944c4b990a631ac806d0b788e794abc788a3\",\"license\":\"MIT\"},\"contracts/interfaces/ERC/IERC677Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC677Receiver {\\n function onTokenTransfer(\\n address sender,\\n uint value,\\n bytes calldata data\\n ) external pure returns (bool);\\n}\\n\",\"keccak256\":\"0x4c1631cf45ea6daac0ec158c3edb9453099130b6b64f697004b83f95aa1f7350\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\\n bytes4(keccak256(\\\"verifyRestrictions(address,address,uint256,bytes)\\\"));\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // Default Fallback Handler of the barz.\\n IDiamondLoupe defaultFallbackHandler;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function enforceIsSelf() internal view {\\n require(msg.sender == address(this), \\\"LibDiamond: Caller not self\\\");\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n\\n unchecked {\\n facetIndex++;\\n }\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n\\n function restrictionsFacet() internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(\\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2cabdc00de859c3a3170ce3bda5d0e5fd3933d47ce904fd1585f9818b02572f8\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\nimport {LibDiamond} from \\\"./LibDiamond.sol\\\";\\n\\n/**\\n * @title LibLoupe\\n * @dev Internal Library to provide utility feature for reading the state of diamond facets\\n * Originally from Diamond's implementation of Mudgen(author of EIP-2535)\\n */\\nlibrary LibLoupe {\\n /// @notice Gets all facets and their selectors.\\n /// @return facets_ Facet\\n function facets()\\n internal\\n view\\n returns (IDiamondLoupe.Facet[] memory facets_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facets_ = new IDiamondLoupe.Facet[](ds.selectorCount);\\n uint16[] memory numFacetSelectors = new uint16[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facets_[facetIndex].facetAddress == facetAddress_) {\\n facets_[facetIndex].functionSelectors[\\n numFacetSelectors[facetIndex]\\n ] = selector;\\n // probably will never have more than 256 functions from one facet contract\\n require(numFacetSelectors[facetIndex] < 255);\\n numFacetSelectors[facetIndex]++;\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facets_[numFacets].facetAddress = facetAddress_;\\n facets_[numFacets].functionSelectors = new bytes4[](\\n ds.selectorCount\\n );\\n facets_[numFacets].functionSelectors[0] = selector;\\n numFacetSelectors[numFacets] = 1;\\n numFacets++;\\n }\\n }\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n uint256 numSelectors = numFacetSelectors[facetIndex];\\n bytes4[] memory selectors = facets_[facetIndex].functionSelectors;\\n // setting the number of selectors\\n assembly {\\n mstore(selectors, numSelectors)\\n }\\n }\\n // setting the number of facets\\n assembly {\\n mstore(facets_, numFacets)\\n }\\n }\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return _facetFunctionSelectors The selectors associated with a facet address.\\n function facetFunctionSelectors(\\n address _facet\\n ) internal view returns (bytes4[] memory _facetFunctionSelectors) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n uint256 numSelectors;\\n _facetFunctionSelectors = new bytes4[](ds.selectorCount);\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facet = address(bytes20(ds.facets[selector]));\\n if (_facet == facet) {\\n _facetFunctionSelectors[numSelectors] = selector;\\n numSelectors++;\\n }\\n }\\n }\\n // Set the number of selectors in the array\\n assembly {\\n mstore(_facetFunctionSelectors, numSelectors)\\n }\\n }\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n internal\\n view\\n returns (address[] memory facetAddresses_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetAddresses_ = new address[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facetAddress_ == facetAddresses_[facetIndex]) {\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facetAddresses_[numFacets] = facetAddress_;\\n numFacets++;\\n }\\n }\\n // Set the number of facet addresses in the array\\n assembly {\\n mstore(facetAddresses_, numFacets)\\n }\\n }\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(LibDiamond.diamondStorage().facets[_functionSelector])\\n );\\n }\\n}\\n\",\"keccak256\":\"0x0b11439c3cc657095e15ec2241fdcf67204b14001357b612fc5db4ff9e760a5a\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibUtils.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nlibrary LibUtils {\\n // Internal utility functions\\n function mergeArrays(\\n bytes4[] memory _array1,\\n bytes4[] memory _array2\\n ) internal pure returns (bytes4[] memory) {\\n uint256 length1 = _array1.length;\\n uint256 length2 = _array2.length;\\n bytes4[] memory mergedArray = new bytes4[](length1 + length2);\\n\\n for (uint256 i; i < length1; ) {\\n mergedArray[i] = _array1[i];\\n unchecked {\\n ++i;\\n }\\n }\\n\\n for (uint256 i; i < length2; ) {\\n mergedArray[length1 + i] = _array2[i];\\n unchecked {\\n ++i;\\n }\\n }\\n\\n return mergedArray;\\n }\\n\\n function removeFacetElement(\\n IDiamondLoupe.Facet[] memory _facets,\\n uint256 _index\\n ) internal pure returns (IDiamondLoupe.Facet[] memory) {\\n require(_index < _facets.length, \\\"Invalid index\\\");\\n require(_facets.length != 0, \\\"Invalid array\\\");\\n\\n // Create a new array with a length of `_facets.length - 1`\\n IDiamondLoupe.Facet[] memory newArray = new IDiamondLoupe.Facet[](\\n _facets.length - 1\\n );\\n uint256 newArrayLength = newArray.length;\\n // Iterate over the original array, skipping the element at the specified `index`\\n for (uint256 i; i < newArrayLength; ) {\\n if (i < _index) {\\n newArray[i] = _facets[i];\\n } else {\\n newArray[i] = _facets[i + 1];\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n\\n return newArray;\\n }\\n\\n function removeElement(\\n bytes4[] memory _array,\\n uint256 _index\\n ) internal pure returns (bytes4[] memory) {\\n require(_index < _array.length, \\\"Invalid index\\\");\\n require(_array.length != 0, \\\"Invalid array\\\");\\n\\n bytes4[] memory newArray = new bytes4[](_array.length - 1);\\n uint256 newArrayLength = newArray.length;\\n for (uint256 i; i < newArrayLength; ) {\\n if (i < _index) {\\n newArray[i] = _array[i];\\n } else {\\n newArray[i] = _array[i + 1];\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n\\n return newArray;\\n }\\n\\n function setValue(\\n bytes4[] memory _keys,\\n address[] memory _values,\\n bytes4 _key,\\n address _value\\n ) internal pure returns (bytes4[] memory, address[] memory) {\\n uint256 index = findIndex(_keys, _key);\\n uint256 keysLength = _keys.length;\\n if (index < keysLength) {\\n _values[index] = _value;\\n } else {\\n // Create new storage arrays\\n bytes4[] memory newKeys = new bytes4[](keysLength + 1);\\n address[] memory newValues = new address[](_values.length + 1);\\n\\n // Copy values to the new storage arrays\\n for (uint256 i; i < keysLength; ) {\\n newKeys[i] = _keys[i];\\n newValues[i] = _values[i];\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n // Add the new key-value pair\\n newKeys[keysLength] = _key;\\n newValues[_values.length] = _value;\\n\\n return (newKeys, newValues);\\n }\\n\\n // If the key already exists, return the original arrays\\n return (_keys, _values);\\n }\\n\\n function getValue(\\n bytes4[] memory _keys,\\n address[] memory _values,\\n bytes4 _key\\n ) internal pure returns (address) {\\n uint256 index = findIndex(_keys, _key);\\n if (index >= _keys.length) return address(0);\\n\\n return _values[index];\\n }\\n\\n function findIndex(\\n bytes4[] memory _keys,\\n bytes4 _key\\n ) internal pure returns (uint256) {\\n uint256 keysLength = _keys.length;\\n for (uint256 i; i < keysLength; ) {\\n if (_keys[i] == _key) {\\n return i;\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n return keysLength;\\n }\\n}\\n\",\"keccak256\":\"0xde8aeefe54c4be483f2b2c055aca11e2830f7094c0586a82e10ec544933b5714\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5061240b806100206000396000f3fe608060405234801561001057600080fd5b50600436106100a35760003560e01c8063adfca15e11610076578063d42139a91161005b578063d42139a914610169578063e3a2f6fe14610171578063f9796ccf1461018457600080fd5b8063adfca15e1461011e578063cdffacc61461013157600080fd5b806301a55022146100a857806301ffc9a7146100d157806352ef6b2c146100f45780637a0ed62714610109575b600080fd5b6100bb6100b6366004611e4b565b61018c565b6040516100c89190611e68565b60405180910390f35b6100e46100df366004611efc565b61019d565b60405190151581526020016100c8565b6100fc610454565b6040516100c89190611f19565b610111610518565b6040516100c89190611f67565b6100bb61012c366004611e4b565b610a63565b61014461013f366004611efc565b610b07565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100c8565b6100fc610c24565b61014461017f366004611efc565b610c33565b610111610c8c565b606061019782610c96565b92915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000148061023057507fffffffff0000000000000000000000000000000000000000000000000000000082167f1f931c1c00000000000000000000000000000000000000000000000000000000145b8061027c57507fffffffff0000000000000000000000000000000000000000000000000000000082167f48e2b09300000000000000000000000000000000000000000000000000000000145b806102c857507fffffffff0000000000000000000000000000000000000000000000000000000082167f4e2312e000000000000000000000000000000000000000000000000000000000145b8061031457507fffffffff0000000000000000000000000000000000000000000000000000000082167f150b7a0200000000000000000000000000000000000000000000000000000000145b8061035f57507fffffffff0000000000000000000000000000000000000000000000000000000082167e23de2900000000000000000000000000000000000000000000000000000000145b806103ab57507fffffffff0000000000000000000000000000000000000000000000000000000082167f1626ba7e00000000000000000000000000000000000000000000000000000000145b806103f757507fffffffff0000000000000000000000000000000000000000000000000000000082167fa4c0ed3600000000000000000000000000000000000000000000000000000000145b806101975750507fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4922602052604090205460ff1690565b60606000610460610518565b80519091508067ffffffffffffffff81111561047e5761047e61205d565b6040519080825280602002602001820160405280156104a7578160200160208202803683370190505b50925060005b81811015610512578281815181106104c7576104c761208c565b6020026020010151600001518482815181106104e5576104e561208c565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526001016104ad565b50505090565b606060007f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f600490810154604080517f7a0ed627000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff90921692637a0ed6279282820192600092908290030181865afa1580156105ac573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526105f29190810190612157565b905060006105fe610e57565b805190915060608060005b838110156106b55760008582815181106106255761062561208c565b60200260200101516020015151905060005b818110156106ab5761069e85858986815181106106565761065661208c565b60200260200101516020015184815181106106735761067361208c565b60200260200101518a878151811061068d5761068d61208c565b60200260200101516000015161134a565b9095509350600101610637565b5050600101610609565b506000805b865181101561081b576000805b8883815181106106d9576106d961208c565b602002602001015160200151518110156107ff57600073ffffffffffffffffffffffffffffffffffffffff1661074687878c878151811061071c5761071c61208c565b60200260200101516020015185815181106107395761073961208c565b60200260200101516115f1565b73ffffffffffffffffffffffffffffffffffffffff16146107e9578883815181106107735761077361208c565b6020026020010151602001515160010361079c576107918984611637565b9850600193506107ff565b6107c38984815181106107b1576107b161208c565b6020026020010151602001518261182a565b8984815181106107d5576107d561208c565b602002602001015160200181905250600191505b816107f6576001016106c7565b600091506106c7565b508261081057816001019150610815565b600092505b506106ba565b5050600085518461082c9190612304565b90508067ffffffffffffffff8111156108475761084761205d565b60405190808252806020026020018201604052801561088d57816020015b6040805180820190915260008152606060208201528152602001906001900390816108655790505b5096506000805b82811015610a585785811015610a0c578681815181106108b6576108b661208c565b60200260200101518982815181106108d0576108d061208c565b60200260200101819052506000805b8951811015610a05578981815181106108fa576108fa61208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff168b848151811061092e5761092e61208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff16036109ef5761099989848151811061096a5761096a61208c565b6020026020010151602001518b83815181106109885761098861208c565b602002602001015160200151611a3d565b8b84815181106109ab576109ab61208c565b6020026020010151602001819052506109c48a82611637565b9950600191506109e18b60018d516109dc9190612317565b611637565b9a506109ec8561232a565b94505b816109fc576001016108df565b600091506108df565b5050610a50565b878281518110610a1e57610a1e61208c565b6020026020010151898281518110610a3857610a3861208c565b602002602001018190525081610a4d9061235f565b91505b600101610894565b505050505050505090565b60606000610a6f610518565b805190915060005b81811015610aff578473ffffffffffffffffffffffffffffffffffffffff16838281518110610aa857610aa861208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1603610af757828181518110610ae157610ae161208c565b6020026020010151602001519350505050919050565b600101610a77565b505050919050565b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602081905260409091205460601c9081610c1e576004818101546040517fcdffacc60000000000000000000000000000000000000000000000000000000081527fffffffff0000000000000000000000000000000000000000000000000000000086169281019290925273ffffffffffffffffffffffffffffffffffffffff169063cdffacc690602401602060405180830381865afa158015610bf7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c1b9190612397565b91505b50919050565b6060610c2e611b8b565b905090565b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604081205460601c610197565b6060610c2e610e57565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9060009061ffff1667ffffffffffffffff811115610cfc57610cfc61205d565b604051908082528060200260200182016040528015610d25578160200160208202803683370190505b5092506000805b600284015461ffff16821015610e4d576000818152600185016020526040812054905b6008811015610e385783610d628161235f565b600288015490955061ffff1685119050610e3857600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020889052604090205460601c73ffffffffffffffffffffffffffffffffffffffff8a16819003610e235781898881518110610de457610de461208c565b7fffffffff000000000000000000000000000000000000000000000000000000009092166020928302919091019091015286610e1f8161235f565b9750505b50508080610e309061235f565b915050610d4f565b50508080610e459061235f565b915050610d2c565b5050825250919050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff1667ffffffffffffffff811115610eba57610eba61205d565b604051908082528060200260200182016040528015610f0057816020015b604080518082019091526000815260606020820152815260200190600190039081610ed85790505b50600282015490925060009061ffff1667ffffffffffffffff811115610f2857610f2861205d565b604051908082528060200260200182016040528015610f51578160200160208202803683370190505b50905060008060005b600285015461ffff168210156112d7576000818152600186016020526040812054905b60088110156112c25783610f908161235f565b600289015490955061ffff16851190506112c257600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020899052604081205460601c90805b88811015611148578273ffffffffffffffffffffffffffffffffffffffff168c82815181106110155761101561208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff160361113657838c828151811061104f5761104f61208c565b6020026020010151602001518b838151811061106d5761106d61208c565b602002602001015161ffff16815181106110895761108961208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152505060ff8a82815181106110e9576110e961208c565b602002602001015161ffff16106110ff57600080fd5b8981815181106111115761111161208c565b602002602001018051809190611126906123b4565b61ffff1690525060019150611148565b806111408161235f565b915050610fe4565b508015611157575050506112b0565b818b898151811061116a5761116a61208c565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff909116905260028a015461ffff1667ffffffffffffffff8111156111b0576111b061205d565b6040519080825280602002602001820160405280156111d9578160200160208202803683370190505b508b89815181106111ec576111ec61208c565b602002602001015160200181905250828b898151811061120e5761120e61208c565b60200260200101516020015160008151811061122c5761122c61208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681525050600189898151811061128c5761128c61208c565b61ffff90921660209283029190910190910152876112a98161235f565b9850505050505b806112ba8161235f565b915050610f7d565b505080806112cf9061235f565b915050610f5a565b5060005b8281101561133f5760008482815181106112f7576112f761208c565b602002602001015161ffff16905060008783815181106113195761131961208c565b6020026020010151602001519050818152505080806113379061235f565b9150506112db565b508185525050505090565b60608060006113598786611da0565b8751909150808210156113b857848783815181106113795761137961208c565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250506115df565b60006113c5826001612304565b67ffffffffffffffff8111156113dd576113dd61205d565b604051908082528060200260200182016040528015611406578160200160208202803683370190505b5090506000885160016114199190612304565b67ffffffffffffffff8111156114315761143161205d565b60405190808252806020026020018201604052801561145a578160200160208202803683370190505b50905060005b83811015611539578a818151811061147a5761147a61208c565b60200260200101518382815181106114945761149461208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815250508981815181106114f2576114f261208c565b602002602001015182828151811061150c5761150c61208c565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101611460565b508782848151811061154d5761154d61208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152505086818a51815181106115ad576115ad61208c565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015290945092506115e8915050565b87879350935050505b94509492505050565b6000806115fe8584611da0565b905084518110611612576000915050611630565b8381815181106116245761162461208c565b60200260200101519150505b9392505050565b6060825182106116a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420696e6465780000000000000000000000000000000000000060448201526064015b60405180910390fd5b8251600003611713576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420617272617900000000000000000000000000000000000000604482015260640161169f565b6000600184516117239190612317565b67ffffffffffffffff81111561173b5761173b61205d565b60405190808252806020026020018201604052801561178157816020015b6040805180820190915260008152606060208201528152602001906001900390816117595790505b50805190915060005b8181101561182057848110156117d6578581815181106117ac576117ac61208c565b60200260200101518382815181106117c6576117c661208c565b6020026020010181905250611818565b856117e2826001612304565b815181106117f2576117f261208c565b602002602001015183828151811061180c5761180c61208c565b60200260200101819052505b60010161178a565b5090949350505050565b606082518210611896576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420696e64657800000000000000000000000000000000000000604482015260640161169f565b8251600003611901576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420617272617900000000000000000000000000000000000000604482015260640161169f565b6000600184516119119190612317565b67ffffffffffffffff8111156119295761192961205d565b604051908082528060200260200182016040528015611952578160200160208202803683370190505b50805190915060005b8181101561182057848110156119cd5785818151811061197d5761197d61208c565b60200260200101518382815181106119975761199761208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152611a35565b856119d9826001612304565b815181106119e9576119e961208c565b6020026020010151838281518110611a0357611a0361208c565b7fffffffff00000000000000000000000000000000000000000000000000000000909216602092830291909101909101525b60010161195b565b81518151606091906000611a518284612304565b67ffffffffffffffff811115611a6957611a6961205d565b604051908082528060200260200182016040528015611a92578160200160208202803683370190505b50905060005b83811015611b0557868181518110611ab257611ab261208c565b6020026020010151828281518110611acc57611acc61208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152600101611a98565b5060005b82811015611b8157858181518110611b2357611b2361208c565b6020026020010151828286611b389190612304565b81518110611b4857611b4861208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152600101611b09565b5095945050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff1667ffffffffffffffff811115611bee57611bee61205d565b604051908082528060200260200182016040528015611c17578160200160208202803683370190505b50915060008060005b600284015461ffff16821015611d98576000818152600185016020526040812054905b6008811015611d835783611c568161235f565b600288015490955061ffff1685119050611d8357600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020889052604081205460601c90805b88811015611d19578a8181518110611cc457611cc461208c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611d075760019150611d19565b80611d118161235f565b915050611caa565b508015611d2857505050611d71565b818a8981518110611d3b57611d3b61208c565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015287611d6a8161235f565b9850505050505b80611d7b8161235f565b915050611c43565b50508080611d909061235f565b915050611c20565b505082525090565b8151600090815b81811015611e1e57837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916858281518110611de157611de161208c565b60200260200101517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603611e165791506101979050565b600101611da7565b509392505050565b73ffffffffffffffffffffffffffffffffffffffff81168114611e4857600080fd5b50565b600060208284031215611e5d57600080fd5b813561163081611e26565b6020808252825182820181905260009190848201906040850190845b81811015611ec25783517fffffffff000000000000000000000000000000000000000000000000000000001683529284019291840191600101611e84565b50909695505050505050565b7fffffffff0000000000000000000000000000000000000000000000000000000081168114611e4857600080fd5b600060208284031215611f0e57600080fd5b813561163081611ece565b6020808252825182820181905260009190848201906040850190845b81811015611ec257835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101611f35565b60006020808301818452808551808352604092508286019150828160051b8701018488016000805b8481101561204e578984037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00186528251805173ffffffffffffffffffffffffffffffffffffffff168552880151888501889052805188860181905290890190839060608701905b808310156120395783517fffffffff00000000000000000000000000000000000000000000000000000000168252928b019260019290920191908b0190611ff7565b50978a01979550505091870191600101611f8f565b50919998505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6040805190810167ffffffffffffffff811182821017156120de576120de61205d565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561212b5761212b61205d565b604052919050565b600067ffffffffffffffff82111561214d5761214d61205d565b5060051b60200190565b6000602080838503121561216a57600080fd5b825167ffffffffffffffff8082111561218257600080fd5b818501915085601f83011261219657600080fd5b81516121a96121a482612133565b6120e4565b81815260059190911b830184019084810190888311156121c857600080fd5b8585015b838110156122c8578051858111156121e45760008081fd5b86016040818c037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00181131561221a5760008081fd5b6122226120bb565b8983015161222f81611e26565b815282820151888111156122435760008081fd5b8084019350508c603f8401126122595760008081fd5b898301516122696121a482612133565b81815260059190911b84018301908b8101908f8311156122895760008081fd5b948401945b828610156122b357855194506122a385611ece565b848252948c0194908c019061228e565b838d01525050855250509186019186016121cc565b5098975050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610197576101976122d5565b81810381811115610197576101976122d5565b600081612339576123396122d5565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612390576123906122d5565b5060010190565b6000602082840312156123a957600080fd5b815161163081611e26565b600061ffff8083168181036123cb576123cb6122d5565b600101939250505056fea26469706673582212205959d8d85aad6f29d5fc37d5a52c404c25392cec49195c3b761da0e863e99b0f64736f6c63430008150033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100a35760003560e01c8063adfca15e11610076578063d42139a91161005b578063d42139a914610169578063e3a2f6fe14610171578063f9796ccf1461018457600080fd5b8063adfca15e1461011e578063cdffacc61461013157600080fd5b806301a55022146100a857806301ffc9a7146100d157806352ef6b2c146100f45780637a0ed62714610109575b600080fd5b6100bb6100b6366004611e4b565b61018c565b6040516100c89190611e68565b60405180910390f35b6100e46100df366004611efc565b61019d565b60405190151581526020016100c8565b6100fc610454565b6040516100c89190611f19565b610111610518565b6040516100c89190611f67565b6100bb61012c366004611e4b565b610a63565b61014461013f366004611efc565b610b07565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100c8565b6100fc610c24565b61014461017f366004611efc565b610c33565b610111610c8c565b606061019782610c96565b92915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000148061023057507fffffffff0000000000000000000000000000000000000000000000000000000082167f1f931c1c00000000000000000000000000000000000000000000000000000000145b8061027c57507fffffffff0000000000000000000000000000000000000000000000000000000082167f48e2b09300000000000000000000000000000000000000000000000000000000145b806102c857507fffffffff0000000000000000000000000000000000000000000000000000000082167f4e2312e000000000000000000000000000000000000000000000000000000000145b8061031457507fffffffff0000000000000000000000000000000000000000000000000000000082167f150b7a0200000000000000000000000000000000000000000000000000000000145b8061035f57507fffffffff0000000000000000000000000000000000000000000000000000000082167e23de2900000000000000000000000000000000000000000000000000000000145b806103ab57507fffffffff0000000000000000000000000000000000000000000000000000000082167f1626ba7e00000000000000000000000000000000000000000000000000000000145b806103f757507fffffffff0000000000000000000000000000000000000000000000000000000082167fa4c0ed3600000000000000000000000000000000000000000000000000000000145b806101975750507fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4922602052604090205460ff1690565b60606000610460610518565b80519091508067ffffffffffffffff81111561047e5761047e61205d565b6040519080825280602002602001820160405280156104a7578160200160208202803683370190505b50925060005b81811015610512578281815181106104c7576104c761208c565b6020026020010151600001518482815181106104e5576104e561208c565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526001016104ad565b50505090565b606060007f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f600490810154604080517f7a0ed627000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff90921692637a0ed6279282820192600092908290030181865afa1580156105ac573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526105f29190810190612157565b905060006105fe610e57565b805190915060608060005b838110156106b55760008582815181106106255761062561208c565b60200260200101516020015151905060005b818110156106ab5761069e85858986815181106106565761065661208c565b60200260200101516020015184815181106106735761067361208c565b60200260200101518a878151811061068d5761068d61208c565b60200260200101516000015161134a565b9095509350600101610637565b5050600101610609565b506000805b865181101561081b576000805b8883815181106106d9576106d961208c565b602002602001015160200151518110156107ff57600073ffffffffffffffffffffffffffffffffffffffff1661074687878c878151811061071c5761071c61208c565b60200260200101516020015185815181106107395761073961208c565b60200260200101516115f1565b73ffffffffffffffffffffffffffffffffffffffff16146107e9578883815181106107735761077361208c565b6020026020010151602001515160010361079c576107918984611637565b9850600193506107ff565b6107c38984815181106107b1576107b161208c565b6020026020010151602001518261182a565b8984815181106107d5576107d561208c565b602002602001015160200181905250600191505b816107f6576001016106c7565b600091506106c7565b508261081057816001019150610815565b600092505b506106ba565b5050600085518461082c9190612304565b90508067ffffffffffffffff8111156108475761084761205d565b60405190808252806020026020018201604052801561088d57816020015b6040805180820190915260008152606060208201528152602001906001900390816108655790505b5096506000805b82811015610a585785811015610a0c578681815181106108b6576108b661208c565b60200260200101518982815181106108d0576108d061208c565b60200260200101819052506000805b8951811015610a05578981815181106108fa576108fa61208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff168b848151811061092e5761092e61208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff16036109ef5761099989848151811061096a5761096a61208c565b6020026020010151602001518b83815181106109885761098861208c565b602002602001015160200151611a3d565b8b84815181106109ab576109ab61208c565b6020026020010151602001819052506109c48a82611637565b9950600191506109e18b60018d516109dc9190612317565b611637565b9a506109ec8561232a565b94505b816109fc576001016108df565b600091506108df565b5050610a50565b878281518110610a1e57610a1e61208c565b6020026020010151898281518110610a3857610a3861208c565b602002602001018190525081610a4d9061235f565b91505b600101610894565b505050505050505090565b60606000610a6f610518565b805190915060005b81811015610aff578473ffffffffffffffffffffffffffffffffffffffff16838281518110610aa857610aa861208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1603610af757828181518110610ae157610ae161208c565b6020026020010151602001519350505050919050565b600101610a77565b505050919050565b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602081905260409091205460601c9081610c1e576004818101546040517fcdffacc60000000000000000000000000000000000000000000000000000000081527fffffffff0000000000000000000000000000000000000000000000000000000086169281019290925273ffffffffffffffffffffffffffffffffffffffff169063cdffacc690602401602060405180830381865afa158015610bf7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c1b9190612397565b91505b50919050565b6060610c2e611b8b565b905090565b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604081205460601c610197565b6060610c2e610e57565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9060009061ffff1667ffffffffffffffff811115610cfc57610cfc61205d565b604051908082528060200260200182016040528015610d25578160200160208202803683370190505b5092506000805b600284015461ffff16821015610e4d576000818152600185016020526040812054905b6008811015610e385783610d628161235f565b600288015490955061ffff1685119050610e3857600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020889052604090205460601c73ffffffffffffffffffffffffffffffffffffffff8a16819003610e235781898881518110610de457610de461208c565b7fffffffff000000000000000000000000000000000000000000000000000000009092166020928302919091019091015286610e1f8161235f565b9750505b50508080610e309061235f565b915050610d4f565b50508080610e459061235f565b915050610d2c565b5050825250919050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff1667ffffffffffffffff811115610eba57610eba61205d565b604051908082528060200260200182016040528015610f0057816020015b604080518082019091526000815260606020820152815260200190600190039081610ed85790505b50600282015490925060009061ffff1667ffffffffffffffff811115610f2857610f2861205d565b604051908082528060200260200182016040528015610f51578160200160208202803683370190505b50905060008060005b600285015461ffff168210156112d7576000818152600186016020526040812054905b60088110156112c25783610f908161235f565b600289015490955061ffff16851190506112c257600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020899052604081205460601c90805b88811015611148578273ffffffffffffffffffffffffffffffffffffffff168c82815181106110155761101561208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff160361113657838c828151811061104f5761104f61208c565b6020026020010151602001518b838151811061106d5761106d61208c565b602002602001015161ffff16815181106110895761108961208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152505060ff8a82815181106110e9576110e961208c565b602002602001015161ffff16106110ff57600080fd5b8981815181106111115761111161208c565b602002602001018051809190611126906123b4565b61ffff1690525060019150611148565b806111408161235f565b915050610fe4565b508015611157575050506112b0565b818b898151811061116a5761116a61208c565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff909116905260028a015461ffff1667ffffffffffffffff8111156111b0576111b061205d565b6040519080825280602002602001820160405280156111d9578160200160208202803683370190505b508b89815181106111ec576111ec61208c565b602002602001015160200181905250828b898151811061120e5761120e61208c565b60200260200101516020015160008151811061122c5761122c61208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681525050600189898151811061128c5761128c61208c565b61ffff90921660209283029190910190910152876112a98161235f565b9850505050505b806112ba8161235f565b915050610f7d565b505080806112cf9061235f565b915050610f5a565b5060005b8281101561133f5760008482815181106112f7576112f761208c565b602002602001015161ffff16905060008783815181106113195761131961208c565b6020026020010151602001519050818152505080806113379061235f565b9150506112db565b508185525050505090565b60608060006113598786611da0565b8751909150808210156113b857848783815181106113795761137961208c565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250506115df565b60006113c5826001612304565b67ffffffffffffffff8111156113dd576113dd61205d565b604051908082528060200260200182016040528015611406578160200160208202803683370190505b5090506000885160016114199190612304565b67ffffffffffffffff8111156114315761143161205d565b60405190808252806020026020018201604052801561145a578160200160208202803683370190505b50905060005b83811015611539578a818151811061147a5761147a61208c565b60200260200101518382815181106114945761149461208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815250508981815181106114f2576114f261208c565b602002602001015182828151811061150c5761150c61208c565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101611460565b508782848151811061154d5761154d61208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152505086818a51815181106115ad576115ad61208c565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015290945092506115e8915050565b87879350935050505b94509492505050565b6000806115fe8584611da0565b905084518110611612576000915050611630565b8381815181106116245761162461208c565b60200260200101519150505b9392505050565b6060825182106116a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420696e6465780000000000000000000000000000000000000060448201526064015b60405180910390fd5b8251600003611713576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420617272617900000000000000000000000000000000000000604482015260640161169f565b6000600184516117239190612317565b67ffffffffffffffff81111561173b5761173b61205d565b60405190808252806020026020018201604052801561178157816020015b6040805180820190915260008152606060208201528152602001906001900390816117595790505b50805190915060005b8181101561182057848110156117d6578581815181106117ac576117ac61208c565b60200260200101518382815181106117c6576117c661208c565b6020026020010181905250611818565b856117e2826001612304565b815181106117f2576117f261208c565b602002602001015183828151811061180c5761180c61208c565b60200260200101819052505b60010161178a565b5090949350505050565b606082518210611896576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420696e64657800000000000000000000000000000000000000604482015260640161169f565b8251600003611901576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420617272617900000000000000000000000000000000000000604482015260640161169f565b6000600184516119119190612317565b67ffffffffffffffff8111156119295761192961205d565b604051908082528060200260200182016040528015611952578160200160208202803683370190505b50805190915060005b8181101561182057848110156119cd5785818151811061197d5761197d61208c565b60200260200101518382815181106119975761199761208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152611a35565b856119d9826001612304565b815181106119e9576119e961208c565b6020026020010151838281518110611a0357611a0361208c565b7fffffffff00000000000000000000000000000000000000000000000000000000909216602092830291909101909101525b60010161195b565b81518151606091906000611a518284612304565b67ffffffffffffffff811115611a6957611a6961205d565b604051908082528060200260200182016040528015611a92578160200160208202803683370190505b50905060005b83811015611b0557868181518110611ab257611ab261208c565b6020026020010151828281518110611acc57611acc61208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152600101611a98565b5060005b82811015611b8157858181518110611b2357611b2361208c565b6020026020010151828286611b389190612304565b81518110611b4857611b4861208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152600101611b09565b5095945050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff1667ffffffffffffffff811115611bee57611bee61205d565b604051908082528060200260200182016040528015611c17578160200160208202803683370190505b50915060008060005b600284015461ffff16821015611d98576000818152600185016020526040812054905b6008811015611d835783611c568161235f565b600288015490955061ffff1685119050611d8357600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020889052604081205460601c90805b88811015611d19578a8181518110611cc457611cc461208c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611d075760019150611d19565b80611d118161235f565b915050611caa565b508015611d2857505050611d71565b818a8981518110611d3b57611d3b61208c565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015287611d6a8161235f565b9850505050505b80611d7b8161235f565b915050611c43565b50508080611d909061235f565b915050611c20565b505082525090565b8151600090815b81811015611e1e57837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916858281518110611de157611de161208c565b60200260200101517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603611e165791506101979050565b600101611da7565b509392505050565b73ffffffffffffffffffffffffffffffffffffffff81168114611e4857600080fd5b50565b600060208284031215611e5d57600080fd5b813561163081611e26565b6020808252825182820181905260009190848201906040850190845b81811015611ec25783517fffffffff000000000000000000000000000000000000000000000000000000001683529284019291840191600101611e84565b50909695505050505050565b7fffffffff0000000000000000000000000000000000000000000000000000000081168114611e4857600080fd5b600060208284031215611f0e57600080fd5b813561163081611ece565b6020808252825182820181905260009190848201906040850190845b81811015611ec257835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101611f35565b60006020808301818452808551808352604092508286019150828160051b8701018488016000805b8481101561204e578984037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00186528251805173ffffffffffffffffffffffffffffffffffffffff168552880151888501889052805188860181905290890190839060608701905b808310156120395783517fffffffff00000000000000000000000000000000000000000000000000000000168252928b019260019290920191908b0190611ff7565b50978a01979550505091870191600101611f8f565b50919998505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6040805190810167ffffffffffffffff811182821017156120de576120de61205d565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561212b5761212b61205d565b604052919050565b600067ffffffffffffffff82111561214d5761214d61205d565b5060051b60200190565b6000602080838503121561216a57600080fd5b825167ffffffffffffffff8082111561218257600080fd5b818501915085601f83011261219657600080fd5b81516121a96121a482612133565b6120e4565b81815260059190911b830184019084810190888311156121c857600080fd5b8585015b838110156122c8578051858111156121e45760008081fd5b86016040818c037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00181131561221a5760008081fd5b6122226120bb565b8983015161222f81611e26565b815282820151888111156122435760008081fd5b8084019350508c603f8401126122595760008081fd5b898301516122696121a482612133565b81815260059190911b84018301908b8101908f8311156122895760008081fd5b948401945b828610156122b357855194506122a385611ece565b848252948c0194908c019061228e565b838d01525050855250509186019186016121cc565b5098975050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610197576101976122d5565b81810381811115610197576101976122d5565b600081612339576123396122d5565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612390576123906122d5565b5060010190565b6000602082840312156123a957600080fd5b815161163081611e26565b600061ffff8083168181036123cb576123cb6122d5565b600101939250505056fea26469706673582212205959d8d85aad6f29d5fc37d5a52c404c25392cec49195c3b761da0e863e99b0f64736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "DiamondLoupe contract compatible with EIP-2535", + "kind": "dev", + "methods": { + "facetAddress(bytes4)": { + "details": "If facet is not found return address(0).", + "params": { + "_functionSelector": "The function selector." + }, + "returns": { + "facetAddress_": "The facet address." + } + }, + "facetAddressFromStorage(bytes4)": { + "params": { + "_functionSelector": "Function selector to fetch the facet address from diamond storage" + }, + "returns": { + "facetAddress_": "Facet address mapped with the function selector" + } + }, + "facetAddresses()": { + "returns": { + "facetAddresses_": "facetAddresses_" + } + }, + "facetAddressesFromStorage()": { + "returns": { + "facetAddresses_": "All facet addresses attached directly to diamond storage" + } + }, + "facetFunctionSelectors(address)": { + "params": { + "_facet": "The facet address." + }, + "returns": { + "facetFunctionSelectors_": "facetFunctionSelectors_" + } + }, + "facetFunctionSelectorsFromStorage(address)": { + "params": { + "_facet": "Facet address to fetch the facet function selectors from diamond storage" + }, + "returns": { + "facetFunctionSelectors_": "Facet function selectors of the given facet address" + } + }, + "facets()": { + "details": "Barz uses a special architecture called default fallback handler. Default Fallback handler is used as a middleware that holds the mapping of facet function selector and facet address that Barz uses. This helps Barz to reduce significant amount of gas during the initialization process. Hence, this method aggregates both the facet information from DefaulFallbackHandler and in diamond storage and shows the data to users.", + "returns": { + "facets_": "Facet" + } + }, + "facetsFromStorage()": { + "returns": { + "facets_": "Facet information attached directly to diamond storage" + } + }, + "supportsInterface(bytes4)": { + "params": { + "_interfaceId": "Interface ID for detecting the interface" + }, + "returns": { + "isSupported": "Bool value showing if the standard is supported in the contract" + } + } + }, + "title": "DiamondLoupe Facet", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "facetAddress(bytes4)": { + "notice": "Gets the facet that supports the given selector." + }, + "facetAddressFromStorage(bytes4)": { + "notice": "Returns the facet address attached to the given function selector. This excludes the facets from the default fallback handler" + }, + "facetAddresses()": { + "notice": "Get all the facet addresses used by Barz." + }, + "facetAddressesFromStorage()": { + "notice": "Returns all facet addresses attached directly to diamond storage. This excludes the facets from the default fallback handler" + }, + "facetFunctionSelectors(address)": { + "notice": "Gets all the function selectors provided by a facet." + }, + "facetFunctionSelectorsFromStorage(address)": { + "notice": "Returns function selectors of given facet address attached directly to diamond storage. This excludes the facets from the default fallback handler" + }, + "facets()": { + "notice": "Gets all facets and their selectors." + }, + "facetsFromStorage()": { + "notice": "Returns the facet from the diamond storage. This excludes the facets from the default fallback handler" + }, + "supportsInterface(bytes4)": { + "notice": "SupportInterface to be compatible with EIP 165" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/avalanche/Secp256r1VerificationFacet.json b/deployments/avalanche/Secp256r1VerificationFacet.json new file mode 100644 index 0000000..6e2ff3f --- /dev/null +++ b/deployments/avalanche/Secp256r1VerificationFacet.json @@ -0,0 +1,467 @@ +{ + "address": "0xeE1AF8E967eC04C84711842796A5E714D2FD33e6", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "LibAppStorage__AccountMustBeUninitialized", + "type": "error" + }, + { + "inputs": [], + "name": "LibAppStorage__SignerAlreadyUninitialized", + "type": "error" + }, + { + "inputs": [], + "name": "LibAppStorage__SignerMustBeUninitialized", + "type": "error" + }, + { + "inputs": [], + "name": "Secp256r1VerificationFacet__InvalidSignerLength", + "type": "error" + }, + { + "inputs": [], + "name": "VerificationFacet__InitializationFailure", + "type": "error" + }, + { + "inputs": [], + "name": "VerificationFacet__InvalidFacetMapping", + "type": "error" + }, + { + "inputs": [], + "name": "VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet", + "type": "error" + }, + { + "inputs": [], + "name": "VerificationFacet__ValidateOwnerSignatureSelectorNotSet", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "SignerInitialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "SignerUninitialized", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_publicKey", + "type": "bytes" + } + ], + "name": "initializeSigner", + "outputs": [ + { + "internalType": "uint256", + "name": "initSuccess", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_publicKey", + "type": "bytes" + } + ], + "name": "isValidKeyType", + "outputs": [ + { + "internalType": "bool", + "name": "isValid", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_hash", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "_signature", + "type": "bytes" + } + ], + "name": "isValidSignature", + "outputs": [ + { + "internalType": "bytes4", + "name": "magicValue", + "type": "bytes4" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "bytes", + "name": "signer", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "self", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "uninitializeSigner", + "outputs": [ + { + "internalType": "uint256", + "name": "uninitSuccess", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "initCode", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "callGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "verificationGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "preVerificationGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxFeePerGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPriorityFeePerGas", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "paymasterAndData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "internalType": "struct UserOperation", + "name": "userOp", + "type": "tuple" + }, + { + "internalType": "bytes32", + "name": "userOpHash", + "type": "bytes32" + } + ], + "name": "validateOwnerSignature", + "outputs": [ + { + "internalType": "uint256", + "name": "validationData", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "validateOwnerSignatureSelector", + "outputs": [ + { + "internalType": "bytes4", + "name": "ownerSignatureValidatorSelector", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "initCode", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "callGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "verificationGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "preVerificationGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxFeePerGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPriorityFeePerGas", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "paymasterAndData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "internalType": "struct UserOperation", + "name": "userOp", + "type": "tuple" + }, + { + "internalType": "bytes32", + "name": "userOpHash", + "type": "bytes32" + }, + { + "internalType": "uint256[2]", + "name": "q", + "type": "uint256[2]" + } + ], + "name": "validateSignature", + "outputs": [ + { + "internalType": "uint256", + "name": "isValid", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "args": [], + "numDeployments": 3, + "solcInputHash": "4356503edd8ae34e73cb6dd1c8e2fc8a", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"LibAppStorage__AccountMustBeUninitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LibAppStorage__SignerAlreadyUninitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LibAppStorage__SignerMustBeUninitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Secp256r1VerificationFacet__InvalidSignerLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerificationFacet__InitializationFailure\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerificationFacet__InvalidFacetMapping\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerificationFacet__ValidateOwnerSignatureSelectorNotSet\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"SignerInitialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"SignerUninitialized\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_publicKey\",\"type\":\"bytes\"}],\"name\":\"initializeSigner\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"initSuccess\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_publicKey\",\"type\":\"bytes\"}],\"name\":\"isValidKeyType\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isValid\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_hash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"_signature\",\"type\":\"bytes\"}],\"name\":\"isValidSignature\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"magicValue\",\"type\":\"bytes4\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"signer\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"self\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"uninitializeSigner\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"uninitSuccess\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"userOp\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"}],\"name\":\"validateOwnerSignature\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"validationData\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"validateOwnerSignatureSelector\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"ownerSignatureValidatorSelector\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"userOp\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256[2]\",\"name\":\"q\",\"type\":\"uint256[2]\"}],\"name\":\"validateSignature\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"isValid\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Ruslan Serebriakov (@rsrbk)David Yongjun Kim (@Powerstream3604)\",\"details\":\"Primarily used to verify user ops signed with passkeys\",\"kind\":\"dev\",\"methods\":{\"initializeSigner(bytes)\":{\"details\":\"This method checks if the signer has already been initialized. If already initialized, it reverts. It checks if the public key is in the light format and initializes signer storage in k1 storage.\",\"params\":{\"_publicKey\":\"Bytes of owner public key\"},\"returns\":{\"initSuccess\":\"Uint value representing the success of init operation\"}},\"isValidKeyType(bytes)\":{\"details\":\"For this Secp256k1Verification Facet, the public key should in an uncompressed public key format\",\"params\":{\"_publicKey\":\"Bytes of public key for format check\"},\"returns\":{\"isValid\":\"Boolean variable representing if the format of public key is valid\"}},\"isValidSignature(bytes32,bytes)\":{\"details\":\"This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\",\"params\":{\"_hash\":\"Hash value the owner signed\",\"_signature\":\"Signature that signed the above hash\"},\"returns\":{\"magicValue\":\"Bytes4 value representing the success/failure of validation\"}},\"owner()\":{\"returns\":{\"signer\":\"Bytes of owner address\"}},\"uninitializeSigner()\":{\"details\":\"This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\",\"returns\":{\"uninitSuccess\":\"Uint value representing the success of uninit operation\"}},\"validateOwnerSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32)\":{\"details\":\"This method validates if the user operation is signed by the owner. It internally calls validateSignature with signer public key.\",\"params\":{\"userOp\":\"UserOperation including all information for execution\",\"userOpHash\":\"Hash of UserOperation given from EntryPoint. This hash is used for signature validation\"},\"returns\":{\"validationData\":\"Uint value representing whether the validation is successful. 0 for success, 1 for failure\"}},\"validateOwnerSignatureSelector()\":{\"returns\":{\"ownerSignatureValidatorSelector\":\"Bytes4 selector of function signature to validate account owner's UserOperation signature\"}},\"validateSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256[2])\":{\"details\":\"This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\",\"params\":{\"q\":\"Public Key of signer who signed the contract, to be validated\",\"userOp\":\"UserOperation including all information for execution\",\"userOpHash\":\"Hash of UserOperation given from EntryPoint. This hash is used for signature validation\"},\"returns\":{\"isValid\":\"Uint value representing whether the validation is successful. 0 for success, 1 for failure\"}}},\"title\":\"Secp256r1 verification facet\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"This constructor ensures that this contract can only be used as singleton for Proxy contracts\"},\"initializeSigner(bytes)\":{\"notice\":\"Initializes the signer in R1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\"},\"isValidKeyType(bytes)\":{\"notice\":\"Validates if the format of public key is valid for this verification facet\"},\"isValidSignature(bytes32,bytes)\":{\"notice\":\"Validates if the signature is valid. Function to be compatible with EIP-1271\"},\"owner()\":{\"notice\":\"Returns the owner of the account\"},\"uninitializeSigner()\":{\"notice\":\"Uninitialize signer in R1 Facet Storage. This can only be called when the account is undergoing signature migration and has already been initialized.\"},\"validateOwnerSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32)\":{\"notice\":\"Validates if the user operation is signed by the owner.\"},\"validateOwnerSignatureSelector()\":{\"notice\":\"Returns the selector of function to validate the signature of UserOperation\"},\"validateSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256[2])\":{\"notice\":\"Validates if the signature of UserOperation is signed by the given signer\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/verification/secp256r1/Secp256r1VerificationFacet.sol\":\"Secp256r1VerificationFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/utils/math/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\\n * checks.\\n *\\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\\n * easily result in undesired exploitation or bugs, since developers usually\\n * assume that overflows raise errors. `SafeCast` restores this intuition by\\n * reverting the transaction when such an operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n *\\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\\n * all math on `uint256` and `int256` and then downcasting.\\n */\\nlibrary SafeCast {\\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 * _Available since v4.7._\\n */\\n function toUint248(uint256 value) internal pure returns (uint248) {\\n require(value <= type(uint248).max, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint240(uint256 value) internal pure returns (uint240) {\\n require(value <= type(uint240).max, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint232(uint256 value) internal pure returns (uint232) {\\n require(value <= type(uint232).max, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint224(uint256 value) internal pure returns (uint224) {\\n require(value <= type(uint224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint216(uint256 value) internal pure returns (uint216) {\\n require(value <= type(uint216).max, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint208(uint256 value) internal pure returns (uint208) {\\n require(value <= type(uint208).max, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint200(uint256 value) internal pure returns (uint200) {\\n require(value <= type(uint200).max, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint192(uint256 value) internal pure returns (uint192) {\\n require(value <= type(uint192).max, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint184(uint256 value) internal pure returns (uint184) {\\n require(value <= type(uint184).max, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint176(uint256 value) internal pure returns (uint176) {\\n require(value <= type(uint176).max, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint168(uint256 value) internal pure returns (uint168) {\\n require(value <= type(uint168).max, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint160(uint256 value) internal pure returns (uint160) {\\n require(value <= type(uint160).max, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint152(uint256 value) internal pure returns (uint152) {\\n require(value <= type(uint152).max, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint144(uint256 value) internal pure returns (uint144) {\\n require(value <= type(uint144).max, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint136(uint256 value) internal pure returns (uint136) {\\n require(value <= type(uint136).max, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint128(uint256 value) internal pure returns (uint128) {\\n require(value <= type(uint128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint120(uint256 value) internal pure returns (uint120) {\\n require(value <= type(uint120).max, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint112(uint256 value) internal pure returns (uint112) {\\n require(value <= type(uint112).max, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint104(uint256 value) internal pure returns (uint104) {\\n require(value <= type(uint104).max, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint96(uint256 value) internal pure returns (uint96) {\\n require(value <= type(uint96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint88(uint256 value) internal pure returns (uint88) {\\n require(value <= type(uint88).max, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint80(uint256 value) internal pure returns (uint80) {\\n require(value <= type(uint80).max, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint72(uint256 value) internal pure returns (uint72) {\\n require(value <= type(uint72).max, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint64(uint256 value) internal pure returns (uint64) {\\n require(value <= type(uint64).max, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint56(uint256 value) internal pure returns (uint56) {\\n require(value <= type(uint56).max, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint48(uint256 value) internal pure returns (uint48) {\\n require(value <= type(uint48).max, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint40(uint256 value) internal pure returns (uint40) {\\n require(value <= type(uint40).max, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint32(uint256 value) internal pure returns (uint32) {\\n require(value <= type(uint32).max, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint24(uint256 value) internal pure returns (uint24) {\\n require(value <= type(uint24).max, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint16(uint256 value) internal pure returns (uint16) {\\n require(value <= type(uint16).max, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint8(uint256 value) internal pure returns (uint8) {\\n require(value <= type(uint8).max, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\n */\\n function toUint256(int256 value) internal pure returns (uint256) {\\n require(value >= 0, \\\"SafeCast: value must be positive\\\");\\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 * _Available since v4.7._\\n */\\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\\n downcasted = int248(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\\n downcasted = int240(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\\n downcasted = int232(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\\n downcasted = int224(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\\n downcasted = int216(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\\n downcasted = int208(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\\n downcasted = int200(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\\n downcasted = int192(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\\n downcasted = int184(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\\n downcasted = int176(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\\n downcasted = int168(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\\n downcasted = int160(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\\n downcasted = int152(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\\n downcasted = int144(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\\n downcasted = int136(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\\n downcasted = int128(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\\n downcasted = int120(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\\n downcasted = int112(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\\n downcasted = int104(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\\n downcasted = int96(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\\n downcasted = int88(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\\n downcasted = int80(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\\n downcasted = int72(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\\n downcasted = int64(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\\n downcasted = int56(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\\n downcasted = int48(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\\n downcasted = int40(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\\n downcasted = int32(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\\n downcasted = int24(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\\n downcasted = int16(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\\n downcasted = int8(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\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 require(value <= uint256(type(int256).max), \\\"SafeCast: value doesn't fit in an int256\\\");\\n return int256(value);\\n }\\n}\\n\",\"keccak256\":\"0x52a8cfb0f5239d11b457dcdd1b326992ef672714ca8da71a157255bddd13f3ad\",\"license\":\"MIT\"},\"contracts/aa-4337/core/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable no-inline-assembly */\\n\\n/**\\n * returned data from validateUserOp.\\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\\n * @param aggregator - address(0) - the account validated the signature by itself.\\n * address(1) - the account failed to validate the signature.\\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\\n * @param validAfter - this UserOp is valid only after this timestamp.\\n * @param validaUntil - this UserOp is valid only up to this timestamp.\\n */\\nstruct ValidationData {\\n address aggregator;\\n uint48 validAfter;\\n uint48 validUntil;\\n}\\n\\n//extract sigFailed, validAfter, validUntil.\\n// also convert zero validUntil to type(uint48).max\\nfunction _parseValidationData(\\n uint validationData\\n) pure returns (ValidationData memory data) {\\n address aggregator = address(uint160(validationData));\\n uint48 validUntil = uint48(validationData >> 160);\\n if (validUntil == 0) {\\n validUntil = type(uint48).max;\\n }\\n uint48 validAfter = uint48(validationData >> (48 + 160));\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n// intersect account and paymaster ranges.\\nfunction _intersectTimeRange(\\n uint256 validationData,\\n uint256 paymasterValidationData\\n) pure returns (ValidationData memory) {\\n ValidationData memory accountValidationData = _parseValidationData(\\n validationData\\n );\\n ValidationData memory pmValidationData = _parseValidationData(\\n paymasterValidationData\\n );\\n address aggregator = accountValidationData.aggregator;\\n if (aggregator == address(0)) {\\n aggregator = pmValidationData.aggregator;\\n }\\n uint48 validAfter = accountValidationData.validAfter;\\n uint48 validUntil = accountValidationData.validUntil;\\n uint48 pmValidAfter = pmValidationData.validAfter;\\n uint48 pmValidUntil = pmValidationData.validUntil;\\n\\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp\\n * @param data - the ValidationData to pack\\n */\\nfunction _packValidationData(\\n ValidationData memory data\\n) pure returns (uint256) {\\n return\\n uint160(data.aggregator) |\\n (uint256(data.validUntil) << 160) |\\n (uint256(data.validAfter) << (160 + 48));\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp, when not using an aggregator\\n * @param sigFailed - true for signature failure, false for success\\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\\n * @param validAfter first timestamp this UserOperation is valid\\n */\\nfunction _packValidationData(\\n bool sigFailed,\\n uint48 validUntil,\\n uint48 validAfter\\n) pure returns (uint256) {\\n return\\n (sigFailed ? 1 : 0) |\\n (uint256(validUntil) << 160) |\\n (uint256(validAfter) << (160 + 48));\\n}\\n\\n/**\\n * keccak function over calldata.\\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\\n */\\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\\n assembly {\\n let mem := mload(0x40)\\n let len := data.length\\n calldatacopy(mem, data.offset, len)\\n ret := keccak256(mem, len)\\n }\\n}\\n\",\"keccak256\":\"0xa79f06cd158ecb8c0da95493a2f348933b8627a63e228b99738bff3aa107942d\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAggregator.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\n/**\\n * Aggregated Signatures validator.\\n */\\ninterface IAggregator {\\n /**\\n * validate aggregated signature.\\n * revert if the aggregated signature does not match the given list of operations.\\n */\\n function validateSignatures(\\n UserOperation[] calldata userOps,\\n bytes calldata signature\\n ) external view;\\n\\n /**\\n * validate signature of a single userOp\\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\\n * @param userOp the userOperation received from the user.\\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\\n * (usually empty, unless account and aggregator support some kind of \\\"multisig\\\"\\n */\\n function validateUserOpSignature(\\n UserOperation calldata userOp\\n ) external view returns (bytes memory sigForUserOp);\\n\\n /**\\n * aggregate multiple signatures into a single value.\\n * This method is called off-chain to calculate the signature to pass with handleOps()\\n * bundler MAY use optimized custom code perform this aggregation\\n * @param userOps array of UserOperations to collect the signatures from.\\n * @return aggregatedSignature the aggregated signature\\n */\\n function aggregateSignatures(\\n UserOperation[] calldata userOps\\n ) external view returns (bytes memory aggregatedSignature);\\n}\\n\",\"keccak256\":\"0xdfdcd80568f037716674619b31be630fcd8316262f05a815b41d1e81782c966a\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IEntryPoint.sol\":{\"content\":\"/**\\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\\n ** Only one instance required on each chain.\\n **/\\n// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-inline-assembly */\\n/* solhint-disable reason-string */\\n\\nimport \\\"./UserOperation.sol\\\";\\nimport \\\"./IStakeManager.sol\\\";\\nimport \\\"./IAggregator.sol\\\";\\nimport \\\"./INonceManager.sol\\\";\\n\\ninterface IEntryPoint is IStakeManager, INonceManager {\\n /***\\n * An event emitted after each successful request\\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\\n * @param sender - the account that generates this request.\\n * @param paymaster - if non-null, the paymaster that pays for this request.\\n * @param nonce - the nonce value from the request.\\n * @param success - true if the sender transaction succeeded, false if reverted.\\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\\n */\\n event UserOperationEvent(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address indexed paymaster,\\n uint256 nonce,\\n bool success,\\n uint256 actualGasCost,\\n uint256 actualGasUsed\\n );\\n\\n /**\\n * account \\\"sender\\\" was deployed.\\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\\n * @param sender the account that is deployed\\n * @param factory the factory used to deploy this account (in the initCode)\\n * @param paymaster the paymaster used by this UserOp\\n */\\n event AccountDeployed(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address factory,\\n address paymaster\\n );\\n\\n /**\\n * An event emitted if the UserOperation \\\"callData\\\" reverted with non-zero length\\n * @param userOpHash the request unique identifier.\\n * @param sender the sender of this request\\n * @param nonce the nonce used in the request\\n * @param revertReason - the return bytes from the (reverted) call to \\\"callData\\\".\\n */\\n event UserOperationRevertReason(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n uint256 nonce,\\n bytes revertReason\\n );\\n\\n /**\\n * an event emitted by handleOps(), before starting the execution loop.\\n * any event emitted before this event, is part of the validation.\\n */\\n event BeforeExecution();\\n\\n /**\\n * signature aggregator used by the following UserOperationEvents within this bundle.\\n */\\n event SignatureAggregatorChanged(address indexed aggregator);\\n\\n /**\\n * a custom revert error of handleOps, to identify the offending op.\\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\\n * @param reason - revert reason\\n * The string starts with a unique code \\\"AAmn\\\", where \\\"m\\\" is \\\"1\\\" for factory, \\\"2\\\" for account and \\\"3\\\" for paymaster issues,\\n * so a failure can be attributed to the correct entity.\\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\\n */\\n error FailedOp(uint256 opIndex, string reason);\\n\\n /**\\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\\n */\\n error SignatureValidationFailed(address aggregator);\\n\\n /**\\n * Successful result from simulateValidation.\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n */\\n error ValidationResult(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo\\n );\\n\\n /**\\n * Successful result from simulateValidation, if the account returns a signature aggregator\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\\n * bundler MUST use it to verify the signature, or reject the UserOperation\\n */\\n error ValidationResultWithAggregation(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo,\\n AggregatorStakeInfo aggregatorInfo\\n );\\n\\n /**\\n * return value of getSenderAddress\\n */\\n error SenderAddressResult(address sender);\\n\\n /**\\n * return value of simulateHandleOp\\n */\\n error ExecutionResult(\\n uint256 preOpGas,\\n uint256 paid,\\n uint48 validAfter,\\n uint48 validUntil,\\n bool targetSuccess,\\n bytes targetResult\\n );\\n\\n //UserOps handled, per aggregator\\n struct UserOpsPerAggregator {\\n UserOperation[] userOps;\\n // aggregator address\\n IAggregator aggregator;\\n // aggregated signature\\n bytes signature;\\n }\\n\\n /**\\n * Execute a batch of UserOperation.\\n * no signature aggregator is used.\\n * if any account requires an aggregator (that is, it returned an aggregator when\\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\\n * @param ops the operations to execute\\n * @param beneficiary the address to receive the fees\\n */\\n function handleOps(\\n UserOperation[] calldata ops,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * Execute a batch of UserOperation with Aggregators\\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\\n * @param beneficiary the address to receive the fees\\n */\\n function handleAggregatedOps(\\n UserOpsPerAggregator[] calldata opsPerAggregator,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * generate a request Id - unique identifier for this request.\\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\\n */\\n function getUserOpHash(\\n UserOperation calldata userOp\\n ) external view returns (bytes32);\\n\\n /**\\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\\n * @param userOp the user operation to validate.\\n */\\n function simulateValidation(UserOperation calldata userOp) external;\\n\\n /**\\n * gas and return values during simulation\\n * @param preOpGas the gas used for validation (including preValidationGas)\\n * @param prefund the required prefund for this operation\\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\\n */\\n struct ReturnInfo {\\n uint256 preOpGas;\\n uint256 prefund;\\n bool sigFailed;\\n uint48 validAfter;\\n uint48 validUntil;\\n bytes paymasterContext;\\n }\\n\\n /**\\n * returned aggregated signature info.\\n * the aggregator returned by the account, and its current stake.\\n */\\n struct AggregatorStakeInfo {\\n address aggregator;\\n StakeInfo stakeInfo;\\n }\\n\\n /**\\n * Get counterfactual sender address.\\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\\n * this method always revert, and returns the address in SenderAddressResult error\\n * @param initCode the constructor code to be passed into the UserOperation.\\n */\\n function getSenderAddress(bytes memory initCode) external;\\n\\n /**\\n * simulate full execution of a UserOperation (including both validation and target execution)\\n * this method will always revert with \\\"ExecutionResult\\\".\\n * it performs full validation of the UserOperation, but ignores signature error.\\n * an optional target address is called after the userop succeeds, and its value is returned\\n * (before the entire call is reverted)\\n * Note that in order to collect the the success/failure of the target call, it must be executed\\n * with trace enabled to track the emitted events.\\n * @param op the UserOperation to simulate\\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\\n * are set to the return from that call.\\n * @param targetCallData callData to pass to target address\\n */\\n function simulateHandleOp(\\n UserOperation calldata op,\\n address target,\\n bytes calldata targetCallData\\n ) external;\\n}\\n\",\"keccak256\":\"0x9ccb1b188eda8bbf5f6c2d01bd83c3d8b2b04fcf745283051d31fe96d1d8e40f\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/INonceManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\ninterface INonceManager {\\n /**\\n * Return the next nonce for this sender.\\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\\n * But UserOp with different keys can come with arbitrary order.\\n *\\n * @param sender the account address\\n * @param key the high 192 bit of the nonce\\n * @return nonce a full nonce to pass for next UserOp with this sender.\\n */\\n function getNonce(\\n address sender,\\n uint192 key\\n ) external view returns (uint256 nonce);\\n\\n /**\\n * Manually increment the nonce of the sender.\\n * This method is exposed just for completeness..\\n * Account does NOT need to call it, neither during validation, nor elsewhere,\\n * as the EntryPoint will update the nonce regardless.\\n * Possible use-case is call it with various keys to \\\"initialize\\\" their nonces to one, so that future\\n * UserOperations will not pay extra for the first transaction with a given key.\\n */\\n function incrementNonce(uint192 key) external;\\n}\\n\",\"keccak256\":\"0xce478ad0fa0d18a3b785ac854623029e7ab463d05873dfaa365abfa1bf100912\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IStakeManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8.12;\\n\\n/**\\n * manage deposits and stakes.\\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\\n * stake is value locked for at least \\\"unstakeDelay\\\" by the staked entity.\\n */\\ninterface IStakeManager {\\n event Deposited(address indexed account, uint256 totalDeposit);\\n\\n event Withdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /// Emitted when stake or unstake delay are modified\\n event StakeLocked(\\n address indexed account,\\n uint256 totalStaked,\\n uint256 unstakeDelaySec\\n );\\n\\n /// Emitted once a stake is scheduled for withdrawal\\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\\n\\n event StakeWithdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /**\\n * @param deposit the entity's deposit\\n * @param staked true if this entity is staked.\\n * @param stake actual amount of ether staked for this entity.\\n * @param unstakeDelaySec minimum delay to withdraw the stake.\\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\\n * and the rest fit into a 2nd cell.\\n * 112 bit allows for 10^15 eth\\n * 48 bit for full timestamp\\n * 32 bit allows 150 years for unstake delay\\n */\\n struct DepositInfo {\\n uint112 deposit;\\n bool staked;\\n uint112 stake;\\n uint32 unstakeDelaySec;\\n uint48 withdrawTime;\\n }\\n\\n //API struct used by getStakeInfo and simulateValidation\\n struct StakeInfo {\\n uint256 stake;\\n uint256 unstakeDelaySec;\\n }\\n\\n /// @return info - full deposit information of given account\\n function getDepositInfo(\\n address account\\n ) external view returns (DepositInfo memory info);\\n\\n /// @return the deposit (for gas payment) of the account\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * add to the deposit of the given account\\n */\\n function depositTo(address account) external payable;\\n\\n /**\\n * add to the account's stake - amount and delay\\n * any pending unstake is first cancelled.\\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\\n */\\n function addStake(uint32 _unstakeDelaySec) external payable;\\n\\n /**\\n * attempt to unlock the stake.\\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\\n */\\n function unlockStake() external;\\n\\n /**\\n * withdraw from the (unlocked) stake.\\n * must first call unlockStake and wait for the unstakeDelay to pass\\n * @param withdrawAddress the address to send withdrawn value.\\n */\\n function withdrawStake(address payable withdrawAddress) external;\\n\\n /**\\n * withdraw from the deposit.\\n * @param withdrawAddress the address to send withdrawn value.\\n * @param withdrawAmount the amount to withdraw.\\n */\\n function withdrawTo(\\n address payable withdrawAddress,\\n uint256 withdrawAmount\\n ) external;\\n}\\n\",\"keccak256\":\"0xadcea606c9b7aafe6645441f2154a60f271330b0eee5292a632aa71c1672d546\",\"license\":\"GPL-3.0-only\"},\"contracts/aa-4337/interfaces/UserOperation.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable no-inline-assembly */\\n\\nimport {calldataKeccak} from \\\"../core/Helpers.sol\\\";\\n\\n/**\\n * User Operation struct\\n * @param sender the sender account of this request.\\n * @param nonce unique value the sender uses to verify it is not a replay.\\n * @param initCode if set, the account contract will be created by this constructor/\\n * @param callData the method call to execute on this account.\\n * @param callGasLimit the gas limit passed to the callData method call.\\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\\n * @param maxFeePerGas same as EIP-1559 gas parameter.\\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\\n */\\nstruct UserOperation {\\n address sender;\\n uint256 nonce;\\n bytes initCode;\\n bytes callData;\\n uint256 callGasLimit;\\n uint256 verificationGasLimit;\\n uint256 preVerificationGas;\\n uint256 maxFeePerGas;\\n uint256 maxPriorityFeePerGas;\\n bytes paymasterAndData;\\n bytes signature;\\n}\\n\\n/**\\n * Utility functions helpful when working with UserOperation structs.\\n */\\nlibrary UserOperationLib {\\n function getSender(\\n UserOperation calldata userOp\\n ) internal pure returns (address) {\\n address data;\\n //read sender from userOp, which is first userOp member (saves 800 gas...)\\n assembly {\\n data := calldataload(userOp)\\n }\\n return address(uint160(data));\\n }\\n\\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\\n // pay above what he signed for.\\n function gasPrice(\\n UserOperation calldata userOp\\n ) internal view returns (uint256) {\\n unchecked {\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n if (maxFeePerGas == maxPriorityFeePerGas) {\\n //legacy mode (for networks that don't support basefee opcode)\\n return maxFeePerGas;\\n }\\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\\n }\\n }\\n\\n function pack(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes memory ret) {\\n address sender = getSender(userOp);\\n uint256 nonce = userOp.nonce;\\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\\n bytes32 hashCallData = calldataKeccak(userOp.callData);\\n uint256 callGasLimit = userOp.callGasLimit;\\n uint256 verificationGasLimit = userOp.verificationGasLimit;\\n uint256 preVerificationGas = userOp.preVerificationGas;\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\\n\\n return\\n abi.encode(\\n sender,\\n nonce,\\n hashInitCode,\\n hashCallData,\\n callGasLimit,\\n verificationGasLimit,\\n preVerificationGas,\\n maxFeePerGas,\\n maxPriorityFeePerGas,\\n hashPaymasterAndData\\n );\\n }\\n\\n function hash(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes32) {\\n return keccak256(pack(userOp));\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n}\\n\",\"keccak256\":\"0x2429f5cc546bdee08c7e63858d0dda8491eaa3ab5194df884dc948c1154d2834\",\"license\":\"GPL-3.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/facets/interfaces/IVerificationFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {UserOperation} from \\\"../../aa-4337/interfaces/UserOperation.sol\\\";\\n\\n/**\\n * @title Verification Facet Interface\\n * @dev Implements logic for user ops signature verification\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\ninterface IVerificationFacet {\\n event SignerInitialized(bytes);\\n event SignerUninitialized();\\n\\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\\n error VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\\n error VerificationFacet__InitializationFailure();\\n error VerificationFacet__InvalidFacetMapping();\\n\\n function initializeSigner(bytes memory) external returns (uint256);\\n\\n function uninitializeSigner() external returns (uint256);\\n\\n function validateOwnerSignatureSelector() external view returns (bytes4);\\n\\n function owner() external view returns (bytes memory);\\n\\n function isValidKeyType(bytes calldata) external view returns (bool);\\n\\n function validateOwnerSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x72bc370a1d1b5a6d6bde67f5026733fd8f6ba434bb90e73b0bd8627fb1579928\",\"license\":\"Apache-2.0\"},\"contracts/facets/verification/secp256r1/Secp256r1VerificationFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {UserOperation} from \\\"../../../aa-4337/interfaces/UserOperation.sol\\\";\\nimport {LibAppStorage} from \\\"../../../libraries/LibAppStorage.sol\\\";\\nimport {LibLoupe} from \\\"../../../libraries/LibLoupe.sol\\\";\\nimport {LibFacetStorage, Secp256r1VerificationStorage} from \\\"../../../libraries/LibFacetStorage.sol\\\";\\nimport {Base64} from \\\"./utils/Base64.sol\\\";\\nimport {LibSecp256r1} from \\\"./utils/LibSecp256r1.sol\\\";\\nimport {IERC1271} from \\\"../../../interfaces/ERC/IERC1271.sol\\\";\\nimport {IVerificationFacet} from \\\"../../interfaces/IVerificationFacet.sol\\\";\\n\\n/**\\n * @title Secp256r1 verification facet\\n * @dev Primarily used to verify user ops signed with passkeys\\n * @author Ruslan Serebriakov (@rsrbk)\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract Secp256r1VerificationFacet is IVerificationFacet, IERC1271 {\\n error Secp256r1VerificationFacet__InvalidSignerLength();\\n address public immutable self;\\n\\n /**\\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\\n */\\n constructor() {\\n LibAppStorage.enforceSignerInitialize();\\n self = address(this);\\n }\\n\\n /**\\n * @notice Initializes the signer in R1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\\n * @param _publicKey Bytes of owner public key\\n * @return initSuccess Uint value representing the success of init operation\\n */\\n function initializeSigner(\\n bytes calldata _publicKey\\n ) public override returns (uint256 initSuccess) {\\n LibAppStorage.enforceSignerInitialize();\\n\\n if (!isValidKeyType(_publicKey))\\n revert Secp256r1VerificationFacet__InvalidSignerLength();\\n\\n bytes memory publicKeyCoordinates = _publicKey[1:];\\n uint256[2] memory q;\\n assembly {\\n // Copy the bytes from the input data into the uint256 array\\n mstore(q, mload(add(publicKeyCoordinates, 32)))\\n mstore(add(q, 32), mload(add(publicKeyCoordinates, 64)))\\n }\\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\\n .r1Storage();\\n r1Storage.q = q;\\n\\n bytes4 validateSelector = validateOwnerSignatureSelector();\\n\\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\\n if (LibLoupe.facetAddress(validateSelector) != self)\\n revert VerificationFacet__InvalidFacetMapping();\\n\\n // initialize verification function selector\\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\\n\\n initSuccess = 1;\\n\\n emit SignerInitialized(_publicKey);\\n }\\n\\n /**\\n * @notice Uninitialize signer in R1 Facet Storage. This can only be called when the account is undergoing signature migration\\n * and has already been initialized.\\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\\n * @return uninitSuccess Uint value representing the success of uninit operation\\n */\\n function uninitializeSigner()\\n external\\n override\\n returns (uint256 uninitSuccess)\\n {\\n LibAppStorage.enforceSignerMigration();\\n LibAppStorage.setSignerUninitialized();\\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\\n .r1Storage();\\n r1Storage.q = [0, 0];\\n\\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\\n\\n uninitSuccess = 1;\\n\\n emit SignerUninitialized();\\n }\\n\\n /**\\n * @notice Validates if the user operation is signed by the owner.\\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\\n * signer public key.\\n * @param userOp UserOperation including all information for execution\\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\\n */\\n function validateOwnerSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) public view override returns (uint256 validationData) {\\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\\n .r1Storage();\\n validationData = validateSignature(userOp, userOpHash, r1Storage.q);\\n }\\n\\n /**\\n * @notice Validates if the signature of UserOperation is signed by the given signer\\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\\n * @param userOp UserOperation including all information for execution\\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\\n * @param q Public Key of signer who signed the contract, to be validated\\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\\n */\\n function validateSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n uint256[2] memory q\\n ) public view returns (uint256 isValid) {\\n isValid = (_validateSignature(q, userOpHash, userOp.signature)) ? 0 : 1;\\n }\\n\\n /**\\n * @notice Returns the selector of function to validate the signature of UserOperation\\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\\n */\\n function validateOwnerSignatureSelector()\\n public\\n pure\\n override\\n returns (bytes4 ownerSignatureValidatorSelector)\\n {\\n return this.validateOwnerSignature.selector; // validateOwnerSignature(UserOperation calldata userOp,bytes32 userOpHash)\\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\\n }\\n\\n /**\\n * @notice Returns the owner of the account\\n * @return signer Bytes of owner address\\n */\\n function owner() public view override returns (bytes memory signer) {\\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\\n .r1Storage();\\n signer = abi.encodePacked(r1Storage.q);\\n }\\n\\n /**\\n * @notice Validates if the format of public key is valid for this verification facet\\n * @dev For this Secp256k1Verification Facet, the public key should in an uncompressed public key format\\n * @param _publicKey Bytes of public key for format check\\n * @return isValid Boolean variable representing if the format of public key is valid\\n */\\n function isValidKeyType(\\n bytes memory _publicKey\\n ) public pure override returns (bool isValid) {\\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\\n }\\n\\n /**\\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\\n * @param _hash Hash value the owner signed\\n * @param _signature Signature that signed the above hash\\n * @return magicValue Bytes4 value representing the success/failure of validation\\n */\\n function isValidSignature(\\n bytes32 _hash,\\n bytes memory _signature\\n ) public view override returns (bytes4 magicValue) {\\n magicValue = _validateSignature(\\n LibFacetStorage.r1Storage().q,\\n _hash,\\n _signature\\n )\\n ? this.isValidSignature.selector\\n : bytes4(0xffffffff);\\n }\\n\\n function _validateSignature(\\n uint256[2] memory q,\\n bytes32 _hash,\\n bytes memory _signature\\n ) internal view returns (bool) {\\n (\\n uint256 rValue,\\n uint256 sValue,\\n bytes memory authenticatorData,\\n string memory clientDataJSONPre,\\n string memory clientDataJSONPost\\n ) = abi.decode(_signature, (uint256, uint256, bytes, string, string));\\n bytes32 clientHash;\\n {\\n string memory opHashBase64 = Base64.encode(bytes.concat(_hash));\\n string memory clientDataJSON = string.concat(\\n clientDataJSONPre,\\n opHashBase64,\\n clientDataJSONPost\\n );\\n clientHash = sha256(bytes(clientDataJSON));\\n }\\n bytes32 sigHash = sha256(bytes.concat(authenticatorData, clientHash));\\n return LibSecp256r1.Verify(q, rValue, sValue, uint256(sigHash));\\n }\\n}\\n\",\"keccak256\":\"0xdb3bae77323eef4e16ef5a5342f548527c9e82b44e8e9dab90906dc2c00082ff\",\"license\":\"Apache-2.0\"},\"contracts/facets/verification/secp256r1/utils/Base64.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @dev Provides a set of functions to operate with Base64 strings.\\n * modified for base64url https://datatracker.ietf.org/doc/html/rfc4648#section-5\\n * _Available since v4.5._\\n */\\nlibrary Base64 {\\n /**\\n * @dev Base64 Encoding/Decoding Table\\n */\\n string internal constant _TABLE =\\n \\\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_\\\";\\n\\n /**\\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\\n */\\n function encode(bytes memory data) internal pure returns (string memory) {\\n /**\\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\\n */\\n if (data.length == 0) return \\\"\\\";\\n\\n // Loads the table into memory\\n string memory table = _TABLE;\\n\\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\\n // and split into 4 numbers of 6 bits.\\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\\n // - `data.length + 2` -> Round up\\n // - `/ 3` -> Number of 3-bytes chunks\\n // - `4 *` -> 4 characters for each chunk\\n uint256 newlength = (data.length * 8) / 6;\\n if (data.length % 6 > 0) {\\n newlength++;\\n }\\n string memory result = new string(newlength);\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n // Prepare the lookup table (skip the first \\\"length\\\" byte)\\n let tablePtr := add(table, 1)\\n\\n // Prepare result pointer, jump over length\\n let resultPtr := add(result, 32)\\n\\n // Run over the input, 3 bytes at a time\\n for {\\n let dataPtr := data\\n let endPtr := add(data, mload(data))\\n } lt(dataPtr, endPtr) {\\n\\n } {\\n // Advance 3 bytes\\n dataPtr := add(dataPtr, 3)\\n let input := mload(dataPtr)\\n\\n // To write each character, shift the 3 bytes (18 bits) chunk\\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\\n // and apply logical AND with 0x3F which is the number of\\n // the previous character in the ASCII table prior to the Base64 Table\\n // The result is then added to the table to get the character to write,\\n // and finally write it in the result pointer but with a left shift\\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\\n\\n mstore8(\\n resultPtr,\\n mload(add(tablePtr, and(shr(18, input), 0x3F)))\\n )\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(\\n resultPtr,\\n mload(add(tablePtr, and(shr(12, input), 0x3F)))\\n )\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(\\n resultPtr,\\n mload(add(tablePtr, and(shr(6, input), 0x3F)))\\n )\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n }\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0xbf0afa21e5a128f260c1a8d4333dc0b0e8755a50d37dfa9b5d362d36ef9cdc14\",\"license\":\"Apache-2.0\"},\"contracts/facets/verification/secp256r1/utils/LibSecp256r1.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n// Heavily inspired from\\n// https://github.com/maxrobot/elliptic-solidity/blob/master/contracts/Secp256r1.sol\\n// https://github.com/tdrerup/elliptic-curve-solidity/blob/master/contracts/curves/EllipticCurve.sol\\n// modified to use precompile 0x05 modexp\\n// and modified jacobian double\\n// optimisations to avoid to an from from affine and jacobian coordinates\\n\\n// Additional Elliptic curve Public key / Signature validation added by\\n// David Yonjun Kim (@Powerstream3604)\\n\\nstruct JPoint {\\n uint256 x;\\n uint256 y;\\n uint256 z;\\n}\\n\\nlibrary LibSecp256r1 {\\n uint256 constant gx =\\n 0x6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296;\\n uint256 constant gy =\\n 0x4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5;\\n uint256 public constant pp =\\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF;\\n\\n uint256 public constant nn =\\n 0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551;\\n uint256 constant a =\\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC;\\n uint256 constant b =\\n 0x5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B;\\n uint256 constant MOST_SIGNIFICANT =\\n 0xc000000000000000000000000000000000000000000000000000000000000000;\\n\\n /*\\n * Verify\\n * @description - verifies that a public key has signed a given message\\n * @param Q - public key coordinates X & Y\\n * @param R - signature half R\\n * @param S - signature half S\\n * @param input - hashed message\\n */\\n function Verify(\\n uint256[2] memory q,\\n uint r,\\n uint s,\\n uint e\\n ) internal view returns (bool) {\\n if (q[0] > pp - 1 || q[1] > pp - 1) {\\n return false;\\n }\\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\\n return false;\\n }\\n if (\\n mulmod(q[1], q[1], pp) !=\\n addmod(\\n addmod(\\n mulmod(q[0], mulmod(q[0], q[0], pp), pp),\\n mulmod(a, q[0], pp),\\n pp\\n ),\\n b,\\n pp\\n )\\n ) {\\n return false;\\n }\\n\\n JPoint[16] memory points = _preComputeJacobianPoints(q);\\n return VerifyWithPrecompute(points, r, s, e);\\n }\\n\\n function VerifyWithPrecompute(\\n JPoint[16] memory points,\\n uint r,\\n uint s,\\n uint e\\n ) internal view returns (bool) {\\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\\n return false;\\n }\\n\\n uint w = _primemod(s, nn);\\n\\n uint u1 = mulmod(e, w, nn);\\n uint u2 = mulmod(r, w, nn);\\n\\n uint x;\\n uint y;\\n\\n (x, y) = ShamirMultJacobian(points, u1, u2);\\n return (x == r);\\n }\\n\\n /*\\n * Strauss Shamir trick for EC multiplication\\n * https://stackoverflow.com/questions/50993471/ec-scalar-multiplication-with-strauss-shamir-method\\n * we optimise on this a bit to do with 2 bits at a time rather than a single bit\\n * the individual points for a single pass are precomputed\\n * overall this reduces the number of additions while keeping the same number of doublings\\n */\\n function ShamirMultJacobian(\\n JPoint[16] memory points,\\n uint u1,\\n uint u2\\n ) internal view returns (uint, uint) {\\n uint x = 0;\\n uint y = 0;\\n uint z = 0;\\n uint bits = 128;\\n uint index = 0;\\n\\n while (bits > 0) {\\n if (z > 0) {\\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\\n }\\n index =\\n ((u1 & MOST_SIGNIFICANT) >> 252) |\\n ((u2 & MOST_SIGNIFICANT) >> 254);\\n if (index > 0) {\\n (x, y, z) = _jAdd(\\n x,\\n y,\\n z,\\n points[index].x,\\n points[index].y,\\n points[index].z\\n );\\n }\\n u1 <<= 2;\\n u2 <<= 2;\\n bits--;\\n }\\n (x, y) = _affineFromJacobian(x, y, z);\\n return (x, y);\\n }\\n\\n function _preComputeJacobianPoints(\\n uint256[2] memory q\\n ) internal pure returns (JPoint[16] memory points) {\\n points[0] = JPoint(0, 0, 0);\\n points[1] = JPoint(q[0], q[1], 1); // u2\\n points[2] = _jPointDouble(points[1]);\\n points[3] = _jPointAdd(points[1], points[2]);\\n\\n points[4] = JPoint(gx, gy, 1); // u1Points[1]\\n points[5] = _jPointAdd(points[4], points[1]);\\n points[6] = _jPointAdd(points[4], points[2]);\\n points[7] = _jPointAdd(points[4], points[3]);\\n\\n points[8] = _jPointDouble(points[4]); // u1Points[2]\\n points[9] = _jPointAdd(points[8], points[1]);\\n points[10] = _jPointAdd(points[8], points[2]);\\n points[11] = _jPointAdd(points[8], points[3]);\\n\\n points[12] = _jPointAdd(points[4], points[8]); // u1Points[3]\\n points[13] = _jPointAdd(points[12], points[1]);\\n points[14] = _jPointAdd(points[12], points[2]);\\n points[15] = _jPointAdd(points[12], points[3]);\\n }\\n\\n function _jPointAdd(\\n JPoint memory p1,\\n JPoint memory p2\\n ) internal pure returns (JPoint memory) {\\n uint x;\\n uint y;\\n uint z;\\n (x, y, z) = _jAdd(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z);\\n return JPoint(x, y, z);\\n }\\n\\n function _jPointDouble(\\n JPoint memory p\\n ) internal pure returns (JPoint memory) {\\n uint x;\\n uint y;\\n uint z;\\n (x, y, z) = _modifiedJacobianDouble(p.x, p.y, p.z);\\n return JPoint(x, y, z);\\n }\\n\\n /* _affineFromJacobian\\n * @desription returns affine coordinates from a jacobian input follows\\n * golang elliptic/crypto library\\n */\\n function _affineFromJacobian(\\n uint x,\\n uint y,\\n uint z\\n ) internal view returns (uint ax, uint ay) {\\n if (z == 0) {\\n return (0, 0);\\n }\\n\\n uint zinv = _primemod(z, pp);\\n uint zinvsq = mulmod(zinv, zinv, pp);\\n\\n ax = mulmod(x, zinvsq, pp);\\n ay = mulmod(y, mulmod(zinvsq, zinv, pp), pp);\\n }\\n\\n /*\\n * _jAdd\\n * @description performs Jacobian addition as defined below:\\n * http://www.hyperelliptic.org/EFD/g1p/data/shortw/jacobian/addition/add-2007-bl\\n */\\n function _jAdd(\\n uint p1,\\n uint p2,\\n uint p3,\\n uint q1,\\n uint q2,\\n uint q3\\n ) internal pure returns (uint r1, uint r2, uint r3) {\\n if (p3 == 0) {\\n r1 = q1;\\n r2 = q2;\\n r3 = q3;\\n\\n return (r1, r2, r3);\\n } else if (q3 == 0) {\\n r1 = p1;\\n r2 = p2;\\n r3 = p3;\\n\\n return (r1, r2, r3);\\n }\\n\\n assembly {\\n let\\n pd\\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\\n let z1z1 := mulmod(p3, p3, pd) // Z1Z1 = Z1^2\\n let z2z2 := mulmod(q3, q3, pd) // Z2Z2 = Z2^2\\n\\n let u1 := mulmod(p1, z2z2, pd) // U1 = X1*Z2Z2\\n let u2 := mulmod(q1, z1z1, pd) // U2 = X2*Z1Z1\\n\\n let s1 := mulmod(p2, mulmod(z2z2, q3, pd), pd) // S1 = Y1*Z2*Z2Z2\\n let s2 := mulmod(q2, mulmod(z1z1, p3, pd), pd) // S2 = Y2*Z1*Z1Z1\\n\\n let p3q3 := addmod(p3, q3, pd)\\n\\n if lt(u2, u1) {\\n u2 := add(pd, u2) // u2 = u2+pd\\n }\\n let h := sub(u2, u1) // H = U2-U1\\n\\n let i := mulmod(0x02, h, pd)\\n i := mulmod(i, i, pd) // I = (2*H)^2\\n\\n let j := mulmod(h, i, pd) // J = H*I\\n if lt(s2, s1) {\\n s2 := add(pd, s2) // u2 = u2+pd\\n }\\n let rr := mulmod(0x02, sub(s2, s1), pd) // r = 2*(S2-S1)\\n r1 := mulmod(rr, rr, pd) // X3 = R^2\\n\\n let v := mulmod(u1, i, pd) // V = U1*I\\n let j2v := addmod(j, mulmod(0x02, v, pd), pd)\\n if lt(r1, j2v) {\\n r1 := add(pd, r1) // X3 = X3+pd\\n }\\n r1 := sub(r1, j2v)\\n\\n // Y3 = r*(V-X3)-2*S1*J\\n let s12j := mulmod(mulmod(0x02, s1, pd), j, pd)\\n\\n if lt(v, r1) {\\n v := add(pd, v)\\n }\\n r2 := mulmod(rr, sub(v, r1), pd)\\n\\n if lt(r2, s12j) {\\n r2 := add(pd, r2)\\n }\\n r2 := sub(r2, s12j)\\n\\n // Z3 = ((Z1+Z2)^2-Z1Z1-Z2Z2)*H\\n z1z1 := addmod(z1z1, z2z2, pd)\\n j2v := mulmod(p3q3, p3q3, pd)\\n if lt(j2v, z1z1) {\\n j2v := add(pd, j2v)\\n }\\n r3 := mulmod(sub(j2v, z1z1), h, pd)\\n }\\n return (r1, r2, r3);\\n }\\n\\n // Point doubling on the modified jacobian coordinates\\n // http://point-at-infinity.org/ecc/Prime_Curve_Modified_Jacobian_Coordinates.html\\n function _modifiedJacobianDouble(\\n uint x,\\n uint y,\\n uint z\\n ) internal pure returns (uint x3, uint y3, uint z3) {\\n if (y == 0) return (0, 0, 0);\\n assembly {\\n let\\n pd\\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\\n let z2 := mulmod(z, z, pd)\\n let az4 := mulmod(\\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC,\\n mulmod(z2, z2, pd),\\n pd\\n )\\n let y2 := mulmod(y, y, pd)\\n let s := mulmod(0x04, mulmod(x, y2, pd), pd)\\n let u := mulmod(0x08, mulmod(y2, y2, pd), pd)\\n let m := addmod(mulmod(0x03, mulmod(x, x, pd), pd), az4, pd)\\n let twos := mulmod(0x02, s, pd)\\n let m2 := mulmod(m, m, pd)\\n if lt(m2, twos) {\\n m2 := add(pd, m2)\\n }\\n x3 := sub(m2, twos)\\n if lt(s, x3) {\\n s := add(pd, s)\\n }\\n y3 := mulmod(m, sub(s, x3), pd)\\n if lt(y3, u) {\\n y3 := add(pd, y3)\\n }\\n y3 := sub(y3, u)\\n z3 := mulmod(0x02, mulmod(y, z, pd), pd)\\n }\\n }\\n\\n // Fermats little theorem https://en.wikipedia.org/wiki/Fermat%27s_little_theorem\\n // a^(p-1) = 1 mod p\\n // a^(-1) \\u2245 a^(p-2) (mod p)\\n // we then use the precompile bigModExp to compute a^(-1)\\n function _primemod(uint value, uint p) internal view returns (uint ret) {\\n ret = modexp(value, p - 2, p);\\n return ret;\\n }\\n\\n // Wrapper for built-in BigNumber_modexp (contract 0x5) as described here. https://github.com/ethereum/EIPs/pull/198\\n function modexp(\\n uint _base,\\n uint _exp,\\n uint _mod\\n ) internal view returns (uint ret) {\\n // bigModExp(_base, _exp, _mod);\\n assembly {\\n if gt(_base, _mod) {\\n _base := mod(_base, _mod)\\n }\\n // Free memory pointer is always stored at 0x40\\n let freemem := mload(0x40)\\n\\n mstore(freemem, 0x20)\\n mstore(add(freemem, 0x20), 0x20)\\n mstore(add(freemem, 0x40), 0x20)\\n\\n mstore(add(freemem, 0x60), _base)\\n mstore(add(freemem, 0x80), _exp)\\n mstore(add(freemem, 0xa0), _mod)\\n\\n let success := staticcall(14000, 0x5, freemem, 0xc0, freemem, 0x20)\\n switch success\\n case 0 {\\n revert(0x0, 0x0)\\n }\\n default {\\n ret := mload(freemem)\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb53714ba63cddb379ba312c1e7f6a423f4d7a7e34fa1364ec8295cd57d544024\",\"license\":\"GPL-3.0\"},\"contracts/infrastructure/interfaces/IFacetRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Registry Interface\\n * @dev Interface for Facet Registry contract to keep track of facets & function selectors addable to user wallets\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IFacetRegistry {\\n struct FacetRegistryConfig {\\n bytes4[] selectors;\\n mapping(bytes4 => FacetInfo) info;\\n }\\n struct FacetInfo {\\n bool exists;\\n uint128 index;\\n }\\n\\n event FacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] facetSelectors\\n );\\n event FacetFunctionSelectorsRemoved(address facet, bytes4[] facetSelectors);\\n\\n error FacetRegistry__FacetSelectorAlreadyRegistered();\\n error FacetRegistry__UnregisteredFacetSelector();\\n\\n function registerFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function removeFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function areFacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external view returns (bool);\\n\\n function isFacetFunctionSelectorRegistered(\\n address facet,\\n bytes4 facetSelector\\n ) external view returns (bool);\\n\\n function getFacetFunctionSelectors(\\n address facet\\n ) external view returns (bytes4[] memory);\\n}\\n\",\"keccak256\":\"0x6e6dd2cab346ef7c31230740ec48d2925e4a9ab24c2f2fb268baaf408dcf02ef\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC1271 {\\n function isValidSignature(\\n bytes32 hash,\\n bytes memory signature\\n ) external view returns (bytes4);\\n}\\n\",\"keccak256\":\"0xcdddb7d5641c9d3f2432dec7fd13fddb9ae1480f25c76c21511e2fa16b8bd422\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibAppStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {SafeCast} from \\\"@openzeppelin/contracts/utils/math/SafeCast.sol\\\";\\nimport {IEntryPoint} from \\\"../aa-4337/interfaces/IEntryPoint.sol\\\";\\nimport {IFacetRegistry} from \\\"../infrastructure/interfaces/IFacetRegistry.sol\\\";\\n\\n/*\\n * @title App Storage\\n * @dev App storage for Barz contract to prevent storage collision\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Lock {\\n uint64 release;\\n bytes4 locker;\\n}\\n\\nstruct InitializersStorage {\\n // NOTE: initialized is a variable to make sure the initialization is only done once.\\n uint8 signerInitialized;\\n uint8 accountInitialized;\\n uint8 restrictionsInitialized;\\n}\\n\\nstruct AppStorage {\\n mapping(uint256 => InitializersStorage) initStorage;\\n uint8 signerMigration;\\n bytes4 validateOwnerSignatureSelector;\\n IEntryPoint entryPoint;\\n IFacetRegistry facetRegistry;\\n mapping(uint256 => Lock) locks;\\n}\\n\\nlibrary LibAppStorage {\\n error LibAppStorage__AccountAlreadyUninitialized();\\n error LibAppStorage__AccountMustBeUninitialized();\\n error LibAppStorage__SignerAlreadyUninitialized();\\n error LibAppStorage__SignerMustBeUninitialized();\\n\\n function appStorage() internal pure returns (AppStorage storage ds) {\\n assembly {\\n ds.slot := 0\\n }\\n }\\n\\n function setSignerUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerAlreadyUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 0;\\n }\\n\\n function getValidateOwnerSignatureSelector()\\n internal\\n view\\n returns (bytes4 selector)\\n {\\n selector = appStorage().validateOwnerSignatureSelector;\\n }\\n\\n function setValidateOwnerSignatureSelector(\\n bytes4 _validateOwnerSignatureSelector\\n ) internal {\\n appStorage()\\n .validateOwnerSignatureSelector = _validateOwnerSignatureSelector;\\n }\\n\\n function enforceSignerInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerMustBeUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 1;\\n }\\n\\n function enforceAccountInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].accountInitialized) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n s.initStorage[0].accountInitialized = 1;\\n }\\n\\n function initiateSignerMigration() internal {\\n appStorage().signerMigration = 1;\\n }\\n\\n function enforceSignerMigration() internal view {\\n if (1 != appStorage().signerMigration) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n }\\n\\n function finalizeSignerMigration() internal {\\n appStorage().signerMigration = 0;\\n }\\n\\n function setLock(uint256 _releaseAfter, bytes4 _locker) internal {\\n appStorage().locks[0] = Lock(SafeCast.toUint64(_releaseAfter), _locker);\\n }\\n\\n function enforceRestrictionsInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__SignerMustBeUninitialized();\\n s.initStorage[0].restrictionsInitialized = 1;\\n }\\n\\n function setRestrictionsUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__AccountAlreadyUninitialized();\\n s.initStorage[0].restrictionsInitialized = 0;\\n }\\n}\\n\\ncontract BarzStorage {\\n AppStorage internal s;\\n modifier onlyWhenUnlocked() {\\n require(\\n uint64(block.timestamp) >= s.locks[0].release,\\n \\\"Account Locked\\\"\\n );\\n _;\\n }\\n modifier onlyWhenLocked() {\\n require(\\n uint64(block.timestamp) < s.locks[0].release,\\n \\\"Account Unlocked\\\"\\n );\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x48524007862a6ce0e07f645950613ce6513ce073c37a109c75019683d42bae27\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\\n bytes4(keccak256(\\\"verifyRestrictions(address,address,uint256,bytes)\\\"));\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // Default Fallback Handler of the barz.\\n IDiamondLoupe defaultFallbackHandler;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function enforceIsSelf() internal view {\\n require(msg.sender == address(this), \\\"LibDiamond: Caller not self\\\");\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n\\n unchecked {\\n facetIndex++;\\n }\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n\\n function restrictionsFacet() internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(\\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2cabdc00de859c3a3170ce3bda5d0e5fd3933d47ce904fd1585f9818b02572f8\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibFacetStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Storage\\n * @dev Storage contract to store each facets variables with diamond storage\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Secp256k1VerificationStorage {\\n address signer;\\n}\\n\\nstruct Secp256r1VerificationStorage {\\n uint256[2] q;\\n}\\n\\nstruct GuardianStorage {\\n mapping(bytes32 => uint256) pending;\\n mapping(uint8 => StorageConfig) configs;\\n}\\n\\nstruct Info {\\n bool exists;\\n uint128 index;\\n}\\n\\nstruct StorageConfig {\\n address[] addresses;\\n mapping(address => Info) info;\\n}\\n\\nstruct RecoveryConfig {\\n bytes recoveryPublicKey;\\n uint64 executeAfter;\\n}\\n\\nstruct ApprovalConfig {\\n bool isApproved;\\n uint64 validUntil;\\n}\\n\\nstruct RecoveryApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isNewOwnerApproved;\\n}\\n\\nstruct RecoveryStorage {\\n mapping(uint8 => RecoveryConfig) recoveryConfigs;\\n mapping(uint8 => RecoveryApprovalConfig) recoveryApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct RestrictionsStorage {\\n address[] restrictions;\\n mapping(address => bool) exists;\\n}\\n\\nstruct SignatureMigrationConfig {\\n bytes migrationPublicKey;\\n address migrationVerificationFacet;\\n bytes4[] migrationSelectors;\\n uint64 migrateAfter;\\n}\\n\\nstruct SignatureMigrationApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isMigrationApproved;\\n}\\n\\nstruct SignatureMigrationStorage {\\n mapping(uint8 => SignatureMigrationConfig) migrationConfigs;\\n mapping(uint8 => SignatureMigrationApprovalConfig) migrationApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct DiamondCutApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isDiamondCutApproved;\\n}\\n\\nstruct DiamondCutStorage {\\n mapping(uint8 => DiamondCutApprovalConfig) diamondCutApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct LockStorage {\\n uint128 nonce;\\n}\\n\\nlibrary LibFacetStorage {\\n bytes32 constant K1_STORAGE_POSITION =\\n keccak256(\\n \\\"v0.trustwallet.diamond.storage.Secp256k1VerificationStorage\\\"\\n );\\n bytes32 constant R1_STORAGE_POSITION =\\n keccak256(\\n \\\"v0.trustwallet.diamond.storage.Secp256r1VerificationStorage\\\"\\n );\\n bytes32 constant GUARDIAN_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.GuardianStorage\\\");\\n bytes32 constant RECOVERY_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.RecoveryStorage\\\");\\n bytes32 constant RESTRICTION_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.RestrictionsStorage\\\");\\n bytes32 constant MIGRATION_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.SignatureMigrationStorage\\\");\\n bytes32 constant DIAMONDCUT_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.DiamondCutStorage\\\");\\n bytes32 constant LOCK_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.LockStorage\\\");\\n\\n function k1Storage()\\n internal\\n pure\\n returns (Secp256k1VerificationStorage storage ds)\\n {\\n bytes32 storagePosition = K1_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function r1Storage()\\n internal\\n pure\\n returns (Secp256r1VerificationStorage storage ds)\\n {\\n bytes32 storagePosition = R1_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function guardianStorage()\\n internal\\n pure\\n returns (GuardianStorage storage ds)\\n {\\n bytes32 storagePosition = GUARDIAN_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function recoveryStorage()\\n internal\\n pure\\n returns (RecoveryStorage storage ds)\\n {\\n bytes32 storagePosition = RECOVERY_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function restrictionsStorage()\\n internal\\n pure\\n returns (RestrictionsStorage storage ds)\\n {\\n bytes32 storagePosition = RESTRICTION_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function migrationStorage()\\n internal\\n pure\\n returns (SignatureMigrationStorage storage ds)\\n {\\n bytes32 storagePosition = MIGRATION_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function diamondCutStorage()\\n internal\\n pure\\n returns (DiamondCutStorage storage ds)\\n {\\n bytes32 storagePosition = DIAMONDCUT_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function lockStorage() internal pure returns (LockStorage storage ds) {\\n bytes32 storagePosition = LOCK_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n}\\n\",\"keccak256\":\"0x87c85decfd943deda9540733e464cb1a92eba735a301e89ce6f798016e359761\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\nimport {LibDiamond} from \\\"./LibDiamond.sol\\\";\\n\\n/**\\n * @title LibLoupe\\n * @dev Internal Library to provide utility feature for reading the state of diamond facets\\n * Originally from Diamond's implementation of Mudgen(author of EIP-2535)\\n */\\nlibrary LibLoupe {\\n /// @notice Gets all facets and their selectors.\\n /// @return facets_ Facet\\n function facets()\\n internal\\n view\\n returns (IDiamondLoupe.Facet[] memory facets_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facets_ = new IDiamondLoupe.Facet[](ds.selectorCount);\\n uint16[] memory numFacetSelectors = new uint16[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facets_[facetIndex].facetAddress == facetAddress_) {\\n facets_[facetIndex].functionSelectors[\\n numFacetSelectors[facetIndex]\\n ] = selector;\\n // probably will never have more than 256 functions from one facet contract\\n require(numFacetSelectors[facetIndex] < 255);\\n numFacetSelectors[facetIndex]++;\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facets_[numFacets].facetAddress = facetAddress_;\\n facets_[numFacets].functionSelectors = new bytes4[](\\n ds.selectorCount\\n );\\n facets_[numFacets].functionSelectors[0] = selector;\\n numFacetSelectors[numFacets] = 1;\\n numFacets++;\\n }\\n }\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n uint256 numSelectors = numFacetSelectors[facetIndex];\\n bytes4[] memory selectors = facets_[facetIndex].functionSelectors;\\n // setting the number of selectors\\n assembly {\\n mstore(selectors, numSelectors)\\n }\\n }\\n // setting the number of facets\\n assembly {\\n mstore(facets_, numFacets)\\n }\\n }\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return _facetFunctionSelectors The selectors associated with a facet address.\\n function facetFunctionSelectors(\\n address _facet\\n ) internal view returns (bytes4[] memory _facetFunctionSelectors) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n uint256 numSelectors;\\n _facetFunctionSelectors = new bytes4[](ds.selectorCount);\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facet = address(bytes20(ds.facets[selector]));\\n if (_facet == facet) {\\n _facetFunctionSelectors[numSelectors] = selector;\\n numSelectors++;\\n }\\n }\\n }\\n // Set the number of selectors in the array\\n assembly {\\n mstore(_facetFunctionSelectors, numSelectors)\\n }\\n }\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n internal\\n view\\n returns (address[] memory facetAddresses_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetAddresses_ = new address[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facetAddress_ == facetAddresses_[facetIndex]) {\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facetAddresses_[numFacets] = facetAddress_;\\n numFacets++;\\n }\\n }\\n // Set the number of facet addresses in the array\\n assembly {\\n mstore(facetAddresses_, numFacets)\\n }\\n }\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(LibDiamond.diamondStorage().facets[_functionSelector])\\n );\\n }\\n}\\n\",\"keccak256\":\"0x0b11439c3cc657095e15ec2241fdcf67204b14001357b612fc5db4ff9e760a5a\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x60a060405234801561001057600080fd5b50610019610022565b3060805261008b565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff161561006f57604051637c2cde8b60e01b815260040160405180910390fd5b600080805260209190915260409020805460ff19166001179055565b608051611f746100ad6000396000818161016001526106e10152611f746000f3fe608060405234801561001057600080fd5b50600436106100a35760003560e01c80637104ddb2116100765780638dd501211161005b5780638dd50121146101bc578063cd00e50a146101cf578063cd9b47e4146101d757600080fd5b80637104ddb21461015b5780638da5cb5b146101a757600080fd5b806311cfe388146100a85780631626ba7e146100ce5780633253960f14610112578063392dd6d914610138575b600080fd5b6100bb6100b6366004611823565b6101ea565b6040519081526020015b60405180910390f35b6100e16100dc366004611956565b610252565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020016100c5565b7f8dd50121000000000000000000000000000000000000000000000000000000006100e1565b61014b61014636600461199d565b6102fd565b60405190151581526020016100c5565b6101827f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100c5565b6101af61036f565b6040516100c591906119f6565b6100bb6101ca366004611a47565b6103ba565b6100bb61041f565b6100bb6101e5366004611a8c565b61053a565b600061023982846101ff610140880188611afe565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061083692505050565b610244576001610247565b60005b60ff16949350505050565b60006102aa7f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b1653646040805180820191829052919060029082845b81548152602001906001019080831161028b5750505050508484610836565b6102d4577fffffffff000000000000000000000000000000000000000000000000000000006102f6565b7f1626ba7e000000000000000000000000000000000000000000000000000000005b9392505050565b60008151604114801561036957508160008151811061031e5761031e611b6a565b6020910101517fff00000000000000000000000000000000000000000000000000000000000000167f0400000000000000000000000000000000000000000000000000000000000000145b92915050565b6040516060907f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364906103a5908290602001611b99565b60405160208183030381529060405291505090565b60408051808201918290526000917f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364916104179186918691859060029082845b8154815260200190600101908083116103fa5750505050506101ea565b949350505050565b60006104296109b4565b6104316109f4565b60408051808201909152600080825260208201527f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364906104749082906002611675565b506000610488600154610100900460e01b90565b7fffffffff0000000000000000000000000000000000000000000000000000000016036104e1576040517f127c609a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff169055604051600192507fcccd30db6bc000b8bb8d11162228d2d69e3c361983ca3ae8c1365ce64b0fae9e90600090a15090565b6000610544610a93565b61058383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102fd92505050565b6105b9576040517f6c334d2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006105c88360018187611bcd565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092935061060992506116b8915050565b602082015181526040820151602082015260006106437f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b16536490565b9050610651818360026116d6565b507f8dd50121000000000000000000000000000000000000000000000000000000006000610686600154610100900460e01b90565b7fffffffff0000000000000000000000000000000000000000000000000000000016146106df576040517f5f95a63c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16610770827fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604090205460601c90565b73ffffffffffffffffffffffffffffffffffffffff16146107bd576040517fbb4752b700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff1661010060e084901c02179055600194507f6d54821a69ec281ed7ba1bf2729c700768c47df1d80fad646b0a14cc1d5c39ed8787604051610824929190611bf7565b60405180910390a15050505092915050565b600080600080600080868060200190518101906108539190611c94565b9450945094509450945060008061088a8a60405160200161087691815260200190565b604051602081830303815290604052610b33565b905060008482856040516020016108a393929190611d47565b60405160208183030381529060405290506002816040516108c49190611d8a565b602060405180830381855afa1580156108e1573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906109049190611da6565b9250505060006002858360405160200161091f929190611dbf565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905261095791611d8a565b602060405180830381855afa158015610974573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906109979190611da6565b90506109a58b888884610c6f565b9b9a5050505050505050505050565b6001805460ff16146109f2576040517f38fc28cb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff16600114610a5c576040517fe00d7c7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff1615610af9576040517f7c2cde8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b60608151600003610b5257505060408051602081019091526000815290565b6000604051806060016040528060408152602001611eff6040913990506000600684516008610b819190611e10565b610b8b9190611e56565b9050600060068551610b9d9190611e6a565b1115610bb15780610bad81611e7e565b9150505b60008167ffffffffffffffff811115610bcc57610bcc61177c565b6040519080825280601f01601f191660200182016040528015610bf6576020820181803683370190505b509050600183016020820186875188015b80821015610c62576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f8116850151845350600183019250610c07565b5092979650505050505050565b6000610c9c60017fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611eb6565b85511180610cd75750610cd060017fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611eb6565b6020860151115b15610ce457506000610417565b831580610cef575082155b80610d1a57507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518410155b80610d4557507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518310155b15610d5257506000610417565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff7f5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff8088600060200201517fffffffff00000001000000000000000000000000fffffffffffffffffffffffc0988517fffffffff00000001000000000000000000000000ffffffffffffffffffffffff90819080098a5109080860208601517fffffffff00000001000000000000000000000000ffffffffffffffffffffffff90800914610e4357506000610417565b6000610e4e86610e66565b9050610e5c81868686611062565b9695505050505050565b610e6e611704565b60405180606001604052806000815260200160008152602001600081525081600060108110610e9f57610e9f611b6a565b60200201526040805160608101909152808360006020020151815260200183600160028110610ed057610ed0611b6a565b60200201518152602001600181525081600160108110610ef257610ef2611b6a565b6020020152610f088160015b602002015161116f565b6040820152610f278160015b60200201518260025b60200201516111d1565b6060828101919091526040805191820181527f6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c29682527f4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f560208301526001908201526080820152610fa18160045b6020020151826001610f1d565b60a0820152610fb1816004610f14565b60c0820152610fca8160045b6020020151826003610f1d565b60e0820152610fda816004610efe565b610100820152610feb816008610f94565b610120820152610ffc816008610f14565b61014082015261100d816008610fbd565b610160820152608081015161102490826008610f1d565b61018082015261103581600c610f94565b6101a082015261104681600c610f14565b6101c082015261105781600c610fbd565b6101e0820152919050565b600083158061106f575082155b8061109a57507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518410155b806110c557507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518310155b156110d257506000610417565b60006110fe847fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551611243565b905060007fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551828509905060007fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551838809905060008061115e8a858561125a565b509098149998505050505050505050565b61119360405180606001604052806000815260200160008152602001600081525090565b60008060006111af856000015186602001518760400151611346565b6040805160608101825293845260208401929092529082015295945050505050565b6111f560405180606001604052806000815260200160008152602001600081525090565b6000806000611220866000015187602001518860400151886000015189602001518a60400151611424565b604080516060810182529384526020840192909252908201529695505050505050565b60006102f683611254600285611eb6565b8461155c565b6000808080806080815b81156113285782156112955761127b858585611346565b9196509450925061128d858585611346565b919650945092505b50600c60fc89901c1660fe88901c17801561130b576113038585858d85601081106112c2576112c2611b6a565b6020020151518e86601081106112da576112da611b6a565b6020020151602001518f87601081106112f5576112f5611b6a565b602002015160400151611424565b919650945092505b600298891b989790971b968161132081611ec9565b925050611264565b6113338585856115b0565b909750955050505050505b935093915050565b6000806000846000036113615750600091508190508061141b565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff8085860981828283097fffffffff00000001000000000000000000000000fffffffffffffffffffffffc099050818788098283828b0960040983848384096008099150838385868d8e09600309089250838160020984848509818110156113e65785015b039650868110156113f45783015b8387820384099550508085101561140a57938201935b909303925080808688096002099150505b93509350939050565b60008060008660000361143e575084915083905082611550565b83600003611453575087915086905085611550565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff808889098186870982818d0983838b0984858a85098e0985868e87098c09868b8f08848410156114a357928701925b8484039350878460020988818209905088818609848410156114c457928901925b898585036002099350898485099c50898288099650898a8860020982089150818d10156114f0579b89019b5b818d039c5089818b87600209099450508b86101561150d57948801945b888c870384099a50838b101561152257998801995b838b039a508887890897508882830990508781101561153e5788015b88858983030999505050505050505050505b96509650969350505050565b60008184111561156c5781840693505b60405160208152602080820152602060408201528460608201528360808201528260a082015260208160c08360056136b0fa8080156100a357505051949350505050565b600080826000036115c65750600090508061133e565b60006115f2847fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611243565b905060007fffffffff00000001000000000000000000000000ffffffffffffffffffffffff82830990507fffffffff00000001000000000000000000000000ffffffffffffffffffffffff81880993507fffffffff00000001000000000000000000000000ffffffffffffffffffffffff80838309870992505050935093915050565b82600281019282156116a8579160200282015b828111156116a8578251829060ff16905591602001919060010190611688565b506116b492915061174e565b5090565b60405180604001604052806002906020820280368337509192915050565b82600281019282156116a8579160200282015b828111156116a85782518255916020019190600101906116e9565b6040518061020001604052806010905b61173860405180606001604052806000815260200160008152602001600081525090565b8152602001906001900390816117145790505090565b5b808211156116b4576000815560010161174f565b6000610160828403121561177657600080fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156117ce576117ce61177c565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561181b5761181b61177c565b604052919050565b60008060006080848603121561183857600080fd5b833567ffffffffffffffff81111561184f57600080fd5b61185b86828701611763565b935050602080850135925085605f86011261187557600080fd5b61187d6117ab565b80608087018881111561188f57600080fd5b604088015b818110156118ab5780358452928401928401611894565b50508093505050509250925092565b600067ffffffffffffffff8211156118d4576118d461177c565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261191157600080fd5b813561192461191f826118ba565b6117d4565b81815284602083860101111561193957600080fd5b816020850160208301376000918101602001919091529392505050565b6000806040838503121561196957600080fd5b82359150602083013567ffffffffffffffff81111561198757600080fd5b61199385828601611900565b9150509250929050565b6000602082840312156119af57600080fd5b813567ffffffffffffffff8111156119c657600080fd5b61041784828501611900565b60005b838110156119ed5781810151838201526020016119d5565b50506000910152565b6020815260008251806020840152611a158160408501602087016119d2565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b60008060408385031215611a5a57600080fd5b823567ffffffffffffffff811115611a7157600080fd5b611a7d85828601611763565b95602094909401359450505050565b60008060208385031215611a9f57600080fd5b823567ffffffffffffffff80821115611ab757600080fd5b818501915085601f830112611acb57600080fd5b813581811115611ada57600080fd5b866020828501011115611aec57600080fd5b60209290920196919550909350505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112611b3357600080fd5b83018035915067ffffffffffffffff821115611b4e57600080fd5b602001915036819003821315611b6357600080fd5b9250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008183825b6002811015611bbe578154835260209092019160019182019101611b9f565b50505060408201905092915050565b60008085851115611bdd57600080fd5b83861115611bea57600080fd5b5050820193919092039150565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b6000611c5261191f846118ba565b9050828152838383011115611c6657600080fd5b6102f68360208301846119d2565b600082601f830112611c8557600080fd5b6102f683835160208501611c44565b600080600080600060a08688031215611cac57600080fd5b8551945060208601519350604086015167ffffffffffffffff80821115611cd257600080fd5b818801915088601f830112611ce657600080fd5b611cf589835160208501611c44565b94506060880151915080821115611d0b57600080fd5b611d1789838a01611c74565b93506080880151915080821115611d2d57600080fd5b50611d3a88828901611c74565b9150509295509295909350565b60008451611d598184602089016119d2565b845190830190611d6d8183602089016119d2565b8451910190611d808183602088016119d2565b0195945050505050565b60008251611d9c8184602087016119d2565b9190910192915050565b600060208284031215611db857600080fd5b5051919050565b60008351611dd18184602088016119d2565b9190910191825250602001919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808202811582820484141761036957610369611de1565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082611e6557611e65611e27565b500490565b600082611e7957611e79611e27565b500690565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611eaf57611eaf611de1565b5060010190565b8181038181111561036957610369611de1565b600081611ed857611ed8611de1565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392d5fa2646970667358221220d4142da7b16effb6b95f41adeff2bc8ce0d59d3b70ca8d55e6e83224bbfbec0a64736f6c63430008150033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100a35760003560e01c80637104ddb2116100765780638dd501211161005b5780638dd50121146101bc578063cd00e50a146101cf578063cd9b47e4146101d757600080fd5b80637104ddb21461015b5780638da5cb5b146101a757600080fd5b806311cfe388146100a85780631626ba7e146100ce5780633253960f14610112578063392dd6d914610138575b600080fd5b6100bb6100b6366004611823565b6101ea565b6040519081526020015b60405180910390f35b6100e16100dc366004611956565b610252565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020016100c5565b7f8dd50121000000000000000000000000000000000000000000000000000000006100e1565b61014b61014636600461199d565b6102fd565b60405190151581526020016100c5565b6101827f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100c5565b6101af61036f565b6040516100c591906119f6565b6100bb6101ca366004611a47565b6103ba565b6100bb61041f565b6100bb6101e5366004611a8c565b61053a565b600061023982846101ff610140880188611afe565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061083692505050565b610244576001610247565b60005b60ff16949350505050565b60006102aa7f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b1653646040805180820191829052919060029082845b81548152602001906001019080831161028b5750505050508484610836565b6102d4577fffffffff000000000000000000000000000000000000000000000000000000006102f6565b7f1626ba7e000000000000000000000000000000000000000000000000000000005b9392505050565b60008151604114801561036957508160008151811061031e5761031e611b6a565b6020910101517fff00000000000000000000000000000000000000000000000000000000000000167f0400000000000000000000000000000000000000000000000000000000000000145b92915050565b6040516060907f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364906103a5908290602001611b99565b60405160208183030381529060405291505090565b60408051808201918290526000917f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364916104179186918691859060029082845b8154815260200190600101908083116103fa5750505050506101ea565b949350505050565b60006104296109b4565b6104316109f4565b60408051808201909152600080825260208201527f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364906104749082906002611675565b506000610488600154610100900460e01b90565b7fffffffff0000000000000000000000000000000000000000000000000000000016036104e1576040517f127c609a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff169055604051600192507fcccd30db6bc000b8bb8d11162228d2d69e3c361983ca3ae8c1365ce64b0fae9e90600090a15090565b6000610544610a93565b61058383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102fd92505050565b6105b9576040517f6c334d2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006105c88360018187611bcd565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092935061060992506116b8915050565b602082015181526040820151602082015260006106437f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b16536490565b9050610651818360026116d6565b507f8dd50121000000000000000000000000000000000000000000000000000000006000610686600154610100900460e01b90565b7fffffffff0000000000000000000000000000000000000000000000000000000016146106df576040517f5f95a63c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16610770827fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604090205460601c90565b73ffffffffffffffffffffffffffffffffffffffff16146107bd576040517fbb4752b700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff1661010060e084901c02179055600194507f6d54821a69ec281ed7ba1bf2729c700768c47df1d80fad646b0a14cc1d5c39ed8787604051610824929190611bf7565b60405180910390a15050505092915050565b600080600080600080868060200190518101906108539190611c94565b9450945094509450945060008061088a8a60405160200161087691815260200190565b604051602081830303815290604052610b33565b905060008482856040516020016108a393929190611d47565b60405160208183030381529060405290506002816040516108c49190611d8a565b602060405180830381855afa1580156108e1573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906109049190611da6565b9250505060006002858360405160200161091f929190611dbf565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905261095791611d8a565b602060405180830381855afa158015610974573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906109979190611da6565b90506109a58b888884610c6f565b9b9a5050505050505050505050565b6001805460ff16146109f2576040517f38fc28cb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff16600114610a5c576040517fe00d7c7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff1615610af9576040517f7c2cde8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b60608151600003610b5257505060408051602081019091526000815290565b6000604051806060016040528060408152602001611eff6040913990506000600684516008610b819190611e10565b610b8b9190611e56565b9050600060068551610b9d9190611e6a565b1115610bb15780610bad81611e7e565b9150505b60008167ffffffffffffffff811115610bcc57610bcc61177c565b6040519080825280601f01601f191660200182016040528015610bf6576020820181803683370190505b509050600183016020820186875188015b80821015610c62576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f8116850151845350600183019250610c07565b5092979650505050505050565b6000610c9c60017fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611eb6565b85511180610cd75750610cd060017fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611eb6565b6020860151115b15610ce457506000610417565b831580610cef575082155b80610d1a57507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518410155b80610d4557507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518310155b15610d5257506000610417565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff7f5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff8088600060200201517fffffffff00000001000000000000000000000000fffffffffffffffffffffffc0988517fffffffff00000001000000000000000000000000ffffffffffffffffffffffff90819080098a5109080860208601517fffffffff00000001000000000000000000000000ffffffffffffffffffffffff90800914610e4357506000610417565b6000610e4e86610e66565b9050610e5c81868686611062565b9695505050505050565b610e6e611704565b60405180606001604052806000815260200160008152602001600081525081600060108110610e9f57610e9f611b6a565b60200201526040805160608101909152808360006020020151815260200183600160028110610ed057610ed0611b6a565b60200201518152602001600181525081600160108110610ef257610ef2611b6a565b6020020152610f088160015b602002015161116f565b6040820152610f278160015b60200201518260025b60200201516111d1565b6060828101919091526040805191820181527f6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c29682527f4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f560208301526001908201526080820152610fa18160045b6020020151826001610f1d565b60a0820152610fb1816004610f14565b60c0820152610fca8160045b6020020151826003610f1d565b60e0820152610fda816004610efe565b610100820152610feb816008610f94565b610120820152610ffc816008610f14565b61014082015261100d816008610fbd565b610160820152608081015161102490826008610f1d565b61018082015261103581600c610f94565b6101a082015261104681600c610f14565b6101c082015261105781600c610fbd565b6101e0820152919050565b600083158061106f575082155b8061109a57507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518410155b806110c557507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518310155b156110d257506000610417565b60006110fe847fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551611243565b905060007fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551828509905060007fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551838809905060008061115e8a858561125a565b509098149998505050505050505050565b61119360405180606001604052806000815260200160008152602001600081525090565b60008060006111af856000015186602001518760400151611346565b6040805160608101825293845260208401929092529082015295945050505050565b6111f560405180606001604052806000815260200160008152602001600081525090565b6000806000611220866000015187602001518860400151886000015189602001518a60400151611424565b604080516060810182529384526020840192909252908201529695505050505050565b60006102f683611254600285611eb6565b8461155c565b6000808080806080815b81156113285782156112955761127b858585611346565b9196509450925061128d858585611346565b919650945092505b50600c60fc89901c1660fe88901c17801561130b576113038585858d85601081106112c2576112c2611b6a565b6020020151518e86601081106112da576112da611b6a565b6020020151602001518f87601081106112f5576112f5611b6a565b602002015160400151611424565b919650945092505b600298891b989790971b968161132081611ec9565b925050611264565b6113338585856115b0565b909750955050505050505b935093915050565b6000806000846000036113615750600091508190508061141b565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff8085860981828283097fffffffff00000001000000000000000000000000fffffffffffffffffffffffc099050818788098283828b0960040983848384096008099150838385868d8e09600309089250838160020984848509818110156113e65785015b039650868110156113f45783015b8387820384099550508085101561140a57938201935b909303925080808688096002099150505b93509350939050565b60008060008660000361143e575084915083905082611550565b83600003611453575087915086905085611550565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff808889098186870982818d0983838b0984858a85098e0985868e87098c09868b8f08848410156114a357928701925b8484039350878460020988818209905088818609848410156114c457928901925b898585036002099350898485099c50898288099650898a8860020982089150818d10156114f0579b89019b5b818d039c5089818b87600209099450508b86101561150d57948801945b888c870384099a50838b101561152257998801995b838b039a508887890897508882830990508781101561153e5788015b88858983030999505050505050505050505b96509650969350505050565b60008184111561156c5781840693505b60405160208152602080820152602060408201528460608201528360808201528260a082015260208160c08360056136b0fa8080156100a357505051949350505050565b600080826000036115c65750600090508061133e565b60006115f2847fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611243565b905060007fffffffff00000001000000000000000000000000ffffffffffffffffffffffff82830990507fffffffff00000001000000000000000000000000ffffffffffffffffffffffff81880993507fffffffff00000001000000000000000000000000ffffffffffffffffffffffff80838309870992505050935093915050565b82600281019282156116a8579160200282015b828111156116a8578251829060ff16905591602001919060010190611688565b506116b492915061174e565b5090565b60405180604001604052806002906020820280368337509192915050565b82600281019282156116a8579160200282015b828111156116a85782518255916020019190600101906116e9565b6040518061020001604052806010905b61173860405180606001604052806000815260200160008152602001600081525090565b8152602001906001900390816117145790505090565b5b808211156116b4576000815560010161174f565b6000610160828403121561177657600080fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156117ce576117ce61177c565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561181b5761181b61177c565b604052919050565b60008060006080848603121561183857600080fd5b833567ffffffffffffffff81111561184f57600080fd5b61185b86828701611763565b935050602080850135925085605f86011261187557600080fd5b61187d6117ab565b80608087018881111561188f57600080fd5b604088015b818110156118ab5780358452928401928401611894565b50508093505050509250925092565b600067ffffffffffffffff8211156118d4576118d461177c565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261191157600080fd5b813561192461191f826118ba565b6117d4565b81815284602083860101111561193957600080fd5b816020850160208301376000918101602001919091529392505050565b6000806040838503121561196957600080fd5b82359150602083013567ffffffffffffffff81111561198757600080fd5b61199385828601611900565b9150509250929050565b6000602082840312156119af57600080fd5b813567ffffffffffffffff8111156119c657600080fd5b61041784828501611900565b60005b838110156119ed5781810151838201526020016119d5565b50506000910152565b6020815260008251806020840152611a158160408501602087016119d2565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b60008060408385031215611a5a57600080fd5b823567ffffffffffffffff811115611a7157600080fd5b611a7d85828601611763565b95602094909401359450505050565b60008060208385031215611a9f57600080fd5b823567ffffffffffffffff80821115611ab757600080fd5b818501915085601f830112611acb57600080fd5b813581811115611ada57600080fd5b866020828501011115611aec57600080fd5b60209290920196919550909350505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112611b3357600080fd5b83018035915067ffffffffffffffff821115611b4e57600080fd5b602001915036819003821315611b6357600080fd5b9250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008183825b6002811015611bbe578154835260209092019160019182019101611b9f565b50505060408201905092915050565b60008085851115611bdd57600080fd5b83861115611bea57600080fd5b5050820193919092039150565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b6000611c5261191f846118ba565b9050828152838383011115611c6657600080fd5b6102f68360208301846119d2565b600082601f830112611c8557600080fd5b6102f683835160208501611c44565b600080600080600060a08688031215611cac57600080fd5b8551945060208601519350604086015167ffffffffffffffff80821115611cd257600080fd5b818801915088601f830112611ce657600080fd5b611cf589835160208501611c44565b94506060880151915080821115611d0b57600080fd5b611d1789838a01611c74565b93506080880151915080821115611d2d57600080fd5b50611d3a88828901611c74565b9150509295509295909350565b60008451611d598184602089016119d2565b845190830190611d6d8183602089016119d2565b8451910190611d808183602088016119d2565b0195945050505050565b60008251611d9c8184602087016119d2565b9190910192915050565b600060208284031215611db857600080fd5b5051919050565b60008351611dd18184602088016119d2565b9190910191825250602001919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808202811582820484141761036957610369611de1565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082611e6557611e65611e27565b500490565b600082611e7957611e79611e27565b500690565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611eaf57611eaf611de1565b5060010190565b8181038181111561036957610369611de1565b600081611ed857611ed8611de1565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392d5fa2646970667358221220d4142da7b16effb6b95f41adeff2bc8ce0d59d3b70ca8d55e6e83224bbfbec0a64736f6c63430008150033", + "devdoc": { + "author": "Ruslan Serebriakov (@rsrbk)David Yongjun Kim (@Powerstream3604)", + "details": "Primarily used to verify user ops signed with passkeys", + "kind": "dev", + "methods": { + "initializeSigner(bytes)": { + "details": "This method checks if the signer has already been initialized. If already initialized, it reverts. It checks if the public key is in the light format and initializes signer storage in k1 storage.", + "params": { + "_publicKey": "Bytes of owner public key" + }, + "returns": { + "initSuccess": "Uint value representing the success of init operation" + } + }, + "isValidKeyType(bytes)": { + "details": "For this Secp256k1Verification Facet, the public key should in an uncompressed public key format", + "params": { + "_publicKey": "Bytes of public key for format check" + }, + "returns": { + "isValid": "Boolean variable representing if the format of public key is valid" + } + }, + "isValidSignature(bytes32,bytes)": { + "details": "This method verifies the signature if the owner indeed signed the hash. Returns magic value if true", + "params": { + "_hash": "Hash value the owner signed", + "_signature": "Signature that signed the above hash" + }, + "returns": { + "magicValue": "Bytes4 value representing the success/failure of validation" + } + }, + "owner()": { + "returns": { + "signer": "Bytes of owner address" + } + }, + "uninitializeSigner()": { + "details": "This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.", + "returns": { + "uninitSuccess": "Uint value representing the success of uninit operation" + } + }, + "validateOwnerSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32)": { + "details": "This method validates if the user operation is signed by the owner. It internally calls validateSignature with signer public key.", + "params": { + "userOp": "UserOperation including all information for execution", + "userOpHash": "Hash of UserOperation given from EntryPoint. This hash is used for signature validation" + }, + "returns": { + "validationData": "Uint value representing whether the validation is successful. 0 for success, 1 for failure" + } + }, + "validateOwnerSignatureSelector()": { + "returns": { + "ownerSignatureValidatorSelector": "Bytes4 selector of function signature to validate account owner's UserOperation signature" + } + }, + "validateSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256[2])": { + "details": "This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address", + "params": { + "q": "Public Key of signer who signed the contract, to be validated", + "userOp": "UserOperation including all information for execution", + "userOpHash": "Hash of UserOperation given from EntryPoint. This hash is used for signature validation" + }, + "returns": { + "isValid": "Uint value representing whether the validation is successful. 0 for success, 1 for failure" + } + } + }, + "title": "Secp256r1 verification facet", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "constructor": { + "notice": "This constructor ensures that this contract can only be used as singleton for Proxy contracts" + }, + "initializeSigner(bytes)": { + "notice": "Initializes the signer in R1 Facet Storage. This can only be called when the account is uninitialized or during signature migration." + }, + "isValidKeyType(bytes)": { + "notice": "Validates if the format of public key is valid for this verification facet" + }, + "isValidSignature(bytes32,bytes)": { + "notice": "Validates if the signature is valid. Function to be compatible with EIP-1271" + }, + "owner()": { + "notice": "Returns the owner of the account" + }, + "uninitializeSigner()": { + "notice": "Uninitialize signer in R1 Facet Storage. This can only be called when the account is undergoing signature migration and has already been initialized." + }, + "validateOwnerSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32)": { + "notice": "Validates if the user operation is signed by the owner." + }, + "validateOwnerSignatureSelector()": { + "notice": "Returns the selector of function to validate the signature of UserOperation" + }, + "validateSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256[2])": { + "notice": "Validates if the signature of UserOperation is signed by the given signer" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/avalanche/TokenReceiverFacet.json b/deployments/avalanche/TokenReceiverFacet.json new file mode 100644 index 0000000..8b88645 --- /dev/null +++ b/deployments/avalanche/TokenReceiverFacet.json @@ -0,0 +1,239 @@ +{ + "address": "0x3143E1C0Af0Cdc153423863923Cf4e3818e34Daa", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onERC1155BatchReceived", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onERC1155Received", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onERC721Received", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onTokenTransfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "tokensReceived", + "outputs": [], + "stateMutability": "pure", + "type": "function" + } + ], + "transactionHash": "0x29e2e88e3192daf88cfded6510d279ec18a25dc609cdc62143a83edae0258c83", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 1, + "gasUsed": "329340", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x4140366d8b309a105ad8fbbbf2d181ede53519b1632f452e4f25cf043b52a817", + "transactionHash": "0x29e2e88e3192daf88cfded6510d279ec18a25dc609cdc62143a83edae0258c83", + "logs": [], + "blockNumber": 37014579, + "cumulativeGasUsed": "561565", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "0c861e53801b64e5ccc05669ea62a977", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onERC1155BatchReceived\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onERC1155Received\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onERC721Received\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"tokensReceived\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"Contract that enables receiving ERC721/ERC1155/ERC777/ERC677 Tokens with safe transfer\",\"kind\":\"dev\",\"methods\":{},\"title\":\"TokenReceiver Facet\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\":{\"notice\":\"Handles ERC1155 Token batch callback. return Standardized onERC1155BatchReceived return value.\"},\"onERC1155Received(address,address,uint256,uint256,bytes)\":{\"notice\":\"Handles ERC1155 Token callback. return Standardized onERC1155Received return value.\"},\"onERC721Received(address,address,uint256,bytes)\":{\"notice\":\"Handles ERC721 Token callback. return Standardized onERC721Received return value.\"},\"onTokenTransfer(address,uint256,bytes)\":{\"notice\":\"Handles ERC677 Token callback. return true.\"},\"tokensReceived(address,address,address,uint256,bytes,bytes)\":{\"notice\":\"Handles ERC777 Token callback. Does not return value, empty implementation.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/TokenReceiverFacet.sol\":\"TokenReceiverFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title ERC721 token receiver interface\\n * @dev Interface for any contract that wants to support safeTransfers\\n * from ERC721 asset contracts.\\n */\\ninterface IERC721Receiver {\\n /**\\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\\n * by `operator` from `from`, this function is called.\\n *\\n * It must return its Solidity selector to confirm the token transfer.\\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\\n *\\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\\n */\\n function onERC721Received(\\n address operator,\\n address from,\\n uint256 tokenId,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\\n *\\n * Accounts can be notified of {IERC777} tokens being sent to them by having a\\n * contract implement this interface (contract holders can be their own\\n * implementer) and registering it on the\\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\\n *\\n * See {IERC1820Registry} and {ERC1820Implementer}.\\n */\\ninterface IERC777Recipient {\\n /**\\n * @dev Called by an {IERC777} token contract whenever tokens are being\\n * moved or created into a registered account (`to`). The type of operation\\n * is conveyed by `from` being the zero address or not.\\n *\\n * This call occurs _after_ the token contract's state is updated, so\\n * {IERC777-balanceOf}, etc., can be used to query the post-operation state.\\n *\\n * This function may revert to prevent the operation from being executed.\\n */\\n function tokensReceived(\\n address operator,\\n address from,\\n address to,\\n uint256 amount,\\n bytes calldata userData,\\n bytes calldata operatorData\\n ) external;\\n}\\n\",\"keccak256\":\"0x1a5d61db2733202ba361e6d6741cd2e662380e22b80e987eacfc91973f2267dc\",\"license\":\"MIT\"},\"contracts/facets/TokenReceiverFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IERC721Receiver} from \\\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\\\";\\nimport {IERC777Recipient} from \\\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\\\";\\nimport {IERC1155Receiver} from \\\"../interfaces/ERC/IERC1155Receiver.sol\\\";\\nimport {IERC677Receiver} from \\\"../interfaces/ERC/IERC677Receiver.sol\\\";\\n\\n/**\\n * @title TokenReceiver Facet\\n * @dev Contract that enables receiving ERC721/ERC1155/ERC777/ERC677 Tokens with safe transfer\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract TokenReceiverFacet is\\n IERC721Receiver,\\n IERC1155Receiver,\\n IERC777Recipient,\\n IERC677Receiver\\n{\\n /**\\n * @notice Handles ERC721 Token callback.\\n * return Standardized onERC721Received return value.\\n */\\n function onERC721Received(\\n address,\\n address,\\n uint256,\\n bytes calldata\\n ) external pure override returns (bytes4) {\\n return IERC721Receiver.onERC721Received.selector;\\n }\\n\\n /**\\n * @notice Handles ERC1155 Token callback.\\n * return Standardized onERC1155Received return value.\\n */\\n function onERC1155Received(\\n address,\\n address,\\n uint256,\\n uint256,\\n bytes calldata\\n ) external pure override returns (bytes4) {\\n return IERC1155Receiver.onERC1155Received.selector;\\n }\\n\\n /**\\n * @notice Handles ERC1155 Token batch callback.\\n * return Standardized onERC1155BatchReceived return value.\\n */\\n function onERC1155BatchReceived(\\n address,\\n address,\\n uint256[] calldata,\\n uint256[] calldata,\\n bytes calldata\\n ) external pure override returns (bytes4) {\\n return IERC1155Receiver.onERC1155BatchReceived.selector;\\n }\\n\\n /**\\n * @notice Handles ERC777 Token callback.\\n * Does not return value, empty implementation.\\n */\\n function tokensReceived(\\n address,\\n address,\\n address,\\n uint256,\\n bytes calldata,\\n bytes calldata\\n ) external pure override {}\\n\\n /**\\n * @notice Handles ERC677 Token callback.\\n * return true.\\n */\\n function onTokenTransfer(\\n address,\\n uint256,\\n bytes calldata\\n ) external pure override returns (bool) {\\n return true;\\n }\\n}\\n\",\"keccak256\":\"0xdfe483d05ef4056bb464c34ade19ab527687aff3ed0b6303b447a68b5ff7abb4\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC1155Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\n\\npragma solidity 0.8.21;\\n\\n/**\\n * @dev _Available since v3.1._\\n */\\ninterface IERC1155Receiver {\\n /**\\n * @dev Handles the receipt of a single ERC1155 token type. This function is\\n * called at the end of a `safeTransferFrom` after the balance has been updated.\\n *\\n * NOTE: To accept the transfer, this must return\\n * `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))`\\n * (i.e. 0xf23a6e61, or its own function selector).\\n *\\n * @param operator The address which initiated the transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param id The ID of the token being transferred\\n * @param value The amount of tokens being transferred\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155Received(\\n address operator,\\n address from,\\n uint256 id,\\n uint256 value,\\n bytes calldata data\\n ) external returns (bytes4);\\n\\n /**\\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\\n * is called at the end of a `safeBatchTransferFrom` after the balances have\\n * been updated.\\n *\\n * NOTE: To accept the transfer(s), this must return\\n * `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))`\\n * (i.e. 0xbc197c81, or its own function selector).\\n *\\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155BatchReceived(\\n address operator,\\n address from,\\n uint256[] calldata ids,\\n uint256[] calldata values,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0x3729c6757bae3aba03ac1c5064d67ad13b94e2a9428bf44b9be510373406da0c\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC677Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC677Receiver {\\n function onTokenTransfer(\\n address sender,\\n uint value,\\n bytes calldata data\\n ) external pure returns (bool);\\n}\\n\",\"keccak256\":\"0x4c1631cf45ea6daac0ec158c3edb9453099130b6b64f697004b83f95aa1f7350\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50610502806100206000396000f3fe608060405234801561001057600080fd5b50600436106100665760003560e01c8063a4c0ed3611610050578063a4c0ed36146100f3578063bc197c811461011b578063f23a6e611461015657600080fd5b806223de291461006b578063150b7a0214610085575b600080fd5b610083610079366004610201565b5050505050505050565b005b6100bd6100933660046102ac565b7f150b7a020000000000000000000000000000000000000000000000000000000095945050505050565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020015b60405180910390f35b61010b61010136600461031b565b6001949350505050565b60405190151581526020016100ea565b6100bd6101293660046103ba565b7fbc197c810000000000000000000000000000000000000000000000000000000098975050505050505050565b6100bd610164366004610454565b7ff23a6e61000000000000000000000000000000000000000000000000000000009695505050505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146101b357600080fd5b919050565b60008083601f8401126101ca57600080fd5b50813567ffffffffffffffff8111156101e257600080fd5b6020830191508360208285010111156101fa57600080fd5b9250929050565b60008060008060008060008060c0898b03121561021d57600080fd5b6102268961018f565b975061023460208a0161018f565b965061024260408a0161018f565b955060608901359450608089013567ffffffffffffffff8082111561026657600080fd5b6102728c838d016101b8565b909650945060a08b013591508082111561028b57600080fd5b506102988b828c016101b8565b999c989b5096995094979396929594505050565b6000806000806000608086880312156102c457600080fd5b6102cd8661018f565b94506102db6020870161018f565b935060408601359250606086013567ffffffffffffffff8111156102fe57600080fd5b61030a888289016101b8565b969995985093965092949392505050565b6000806000806060858703121561033157600080fd5b61033a8561018f565b935060208501359250604085013567ffffffffffffffff81111561035d57600080fd5b610369878288016101b8565b95989497509550505050565b60008083601f84011261038757600080fd5b50813567ffffffffffffffff81111561039f57600080fd5b6020830191508360208260051b85010111156101fa57600080fd5b60008060008060008060008060a0898b0312156103d657600080fd5b6103df8961018f565b97506103ed60208a0161018f565b9650604089013567ffffffffffffffff8082111561040a57600080fd5b6104168c838d01610375565b909850965060608b013591508082111561042f57600080fd5b61043b8c838d01610375565b909650945060808b013591508082111561028b57600080fd5b60008060008060008060a0878903121561046d57600080fd5b6104768761018f565b95506104846020880161018f565b94506040870135935060608701359250608087013567ffffffffffffffff8111156104ae57600080fd5b6104ba89828a016101b8565b979a969950949750929593949250505056fea2646970667358221220ae9a97061ae9e1485161ca9c8d3228a23e47b18755fa935f51b40e927816ca2964736f6c63430008150033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100665760003560e01c8063a4c0ed3611610050578063a4c0ed36146100f3578063bc197c811461011b578063f23a6e611461015657600080fd5b806223de291461006b578063150b7a0214610085575b600080fd5b610083610079366004610201565b5050505050505050565b005b6100bd6100933660046102ac565b7f150b7a020000000000000000000000000000000000000000000000000000000095945050505050565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020015b60405180910390f35b61010b61010136600461031b565b6001949350505050565b60405190151581526020016100ea565b6100bd6101293660046103ba565b7fbc197c810000000000000000000000000000000000000000000000000000000098975050505050505050565b6100bd610164366004610454565b7ff23a6e61000000000000000000000000000000000000000000000000000000009695505050505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146101b357600080fd5b919050565b60008083601f8401126101ca57600080fd5b50813567ffffffffffffffff8111156101e257600080fd5b6020830191508360208285010111156101fa57600080fd5b9250929050565b60008060008060008060008060c0898b03121561021d57600080fd5b6102268961018f565b975061023460208a0161018f565b965061024260408a0161018f565b955060608901359450608089013567ffffffffffffffff8082111561026657600080fd5b6102728c838d016101b8565b909650945060a08b013591508082111561028b57600080fd5b506102988b828c016101b8565b999c989b5096995094979396929594505050565b6000806000806000608086880312156102c457600080fd5b6102cd8661018f565b94506102db6020870161018f565b935060408601359250606086013567ffffffffffffffff8111156102fe57600080fd5b61030a888289016101b8565b969995985093965092949392505050565b6000806000806060858703121561033157600080fd5b61033a8561018f565b935060208501359250604085013567ffffffffffffffff81111561035d57600080fd5b610369878288016101b8565b95989497509550505050565b60008083601f84011261038757600080fd5b50813567ffffffffffffffff81111561039f57600080fd5b6020830191508360208260051b85010111156101fa57600080fd5b60008060008060008060008060a0898b0312156103d657600080fd5b6103df8961018f565b97506103ed60208a0161018f565b9650604089013567ffffffffffffffff8082111561040a57600080fd5b6104168c838d01610375565b909850965060608b013591508082111561042f57600080fd5b61043b8c838d01610375565b909650945060808b013591508082111561028b57600080fd5b60008060008060008060a0878903121561046d57600080fd5b6104768761018f565b95506104846020880161018f565b94506040870135935060608701359250608087013567ffffffffffffffff8111156104ae57600080fd5b6104ba89828a016101b8565b979a969950949750929593949250505056fea2646970667358221220ae9a97061ae9e1485161ca9c8d3228a23e47b18755fa935f51b40e927816ca2964736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "Contract that enables receiving ERC721/ERC1155/ERC777/ERC677 Tokens with safe transfer", + "kind": "dev", + "methods": {}, + "title": "TokenReceiver Facet", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)": { + "notice": "Handles ERC1155 Token batch callback. return Standardized onERC1155BatchReceived return value." + }, + "onERC1155Received(address,address,uint256,uint256,bytes)": { + "notice": "Handles ERC1155 Token callback. return Standardized onERC1155Received return value." + }, + "onERC721Received(address,address,uint256,bytes)": { + "notice": "Handles ERC721 Token callback. return Standardized onERC721Received return value." + }, + "onTokenTransfer(address,uint256,bytes)": { + "notice": "Handles ERC677 Token callback. return true." + }, + "tokensReceived(address,address,address,uint256,bytes,bytes)": { + "notice": "Handles ERC777 Token callback. Does not return value, empty implementation." + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/avalanche/solcInputs/0c861e53801b64e5ccc05669ea62a977.json b/deployments/avalanche/solcInputs/0c861e53801b64e5ccc05669ea62a977.json new file mode 100644 index 0000000..47e9456 --- /dev/null +++ b/deployments/avalanche/solcInputs/0c861e53801b64e5ccc05669ea62a977.json @@ -0,0 +1,354 @@ +{ + "language": "Solidity", + "sources": { + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby disabling any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable2Step.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./Ownable.sol\";\n\n/**\n * @dev Contract module which provides access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership} and {acceptOwnership}.\n *\n * This module is used through inheritance. It will make available all functions\n * from parent (Ownable).\n */\nabstract contract Ownable2Step is Ownable {\n address private _pendingOwner;\n\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Returns the address of the pending owner.\n */\n function pendingOwner() public view virtual returns (address) {\n return _pendingOwner;\n }\n\n /**\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual override onlyOwner {\n _pendingOwner = newOwner;\n emit OwnershipTransferStarted(owner(), newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual override {\n delete _pendingOwner;\n super._transferOwnership(newOwner);\n }\n\n /**\n * @dev The new owner accepts the ownership transfer.\n */\n function acceptOwnership() public virtual {\n address sender = _msgSender();\n require(pendingOwner() == sender, \"Ownable2Step: caller is not the new owner\");\n _transferOwnership(sender);\n }\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC1271.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC1271 standard signature validation method for\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\n *\n * _Available since v4.1._\n */\ninterface IERC1271 {\n /**\n * @dev Should return whether the signature provided is valid for the provided data\n * @param hash Hash of the data to be signed\n * @param signature Signature byte array associated with _data\n */\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\n}\n" + }, + "@openzeppelin/contracts/security/ReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor() {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n _nonReentrantBefore();\n _;\n _nonReentrantAfter();\n }\n\n function _nonReentrantBefore() private {\n // On the first call to nonReentrant, _status will be _NOT_ENTERED\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n }\n\n function _nonReentrantAfter() private {\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Returns true if the reentrancy guard is currently set to \"entered\", which indicates there is a\n * `nonReentrant` function in the call stack.\n */\n function _reentrancyGuardEntered() internal view returns (bool) {\n return _status == _ENTERED;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/ERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/ERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC1155.sol\";\nimport \"./IERC1155Receiver.sol\";\nimport \"./extensions/IERC1155MetadataURI.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of the basic standard multi-token.\n * See https://eips.ethereum.org/EIPS/eip-1155\n * Originally based on code by Enjin: https://github.com/enjin/erc-1155\n *\n * _Available since v3.1._\n */\ncontract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {\n using Address for address;\n\n // Mapping from token ID to account balances\n mapping(uint256 => mapping(address => uint256)) private _balances;\n\n // Mapping from account to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json\n string private _uri;\n\n /**\n * @dev See {_setURI}.\n */\n constructor(string memory uri_) {\n _setURI(uri_);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return\n interfaceId == type(IERC1155).interfaceId ||\n interfaceId == type(IERC1155MetadataURI).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC1155MetadataURI-uri}.\n *\n * This implementation returns the same URI for *all* token types. It relies\n * on the token type ID substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * Clients calling this function must replace the `\\{id\\}` substring with the\n * actual token type ID.\n */\n function uri(uint256) public view virtual override returns (string memory) {\n return _uri;\n }\n\n /**\n * @dev See {IERC1155-balanceOf}.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {\n require(account != address(0), \"ERC1155: address zero is not a valid owner\");\n return _balances[id][account];\n }\n\n /**\n * @dev See {IERC1155-balanceOfBatch}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] memory accounts,\n uint256[] memory ids\n ) public view virtual override returns (uint256[] memory) {\n require(accounts.length == ids.length, \"ERC1155: accounts and ids length mismatch\");\n\n uint256[] memory batchBalances = new uint256[](accounts.length);\n\n for (uint256 i = 0; i < accounts.length; ++i) {\n batchBalances[i] = balanceOf(accounts[i], ids[i]);\n }\n\n return batchBalances;\n }\n\n /**\n * @dev See {IERC1155-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC1155-isApprovedForAll}.\n */\n function isApprovedForAll(address account, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[account][operator];\n }\n\n /**\n * @dev See {IERC1155-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n _safeTransferFrom(from, to, id, amount, data);\n }\n\n /**\n * @dev See {IERC1155-safeBatchTransferFrom}.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n _safeBatchTransferFrom(from, to, ids, amounts, data);\n }\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n\n emit TransferSingle(operator, from, to, id, amount);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n for (uint256 i = 0; i < ids.length; ++i) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n }\n\n emit TransferBatch(operator, from, to, ids, amounts);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\n\n _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);\n }\n\n /**\n * @dev Sets a new URI for all token types, by relying on the token type ID\n * substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * By this mechanism, any occurrence of the `\\{id\\}` substring in either the\n * URI or any of the amounts in the JSON file at said URI will be replaced by\n * clients with the token type ID.\n *\n * For example, the `https://token-cdn-domain/\\{id\\}.json` URI would be\n * interpreted by clients as\n * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`\n * for token type ID 0x4cce0.\n *\n * See {uri}.\n *\n * Because these URIs cannot be meaningfully represented by the {URI} event,\n * this function emits no events.\n */\n function _setURI(string memory newuri) internal virtual {\n _uri = newuri;\n }\n\n /**\n * @dev Creates `amount` tokens of token type `id`, and assigns them to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _mint(address to, uint256 id, uint256 amount, bytes memory data) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _balances[id][to] += amount;\n emit TransferSingle(operator, address(0), to, id, amount);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n for (uint256 i = 0; i < ids.length; i++) {\n _balances[ids[i]][to] += amounts[i];\n }\n\n emit TransferBatch(operator, address(0), to, ids, amounts);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);\n }\n\n /**\n * @dev Destroys `amount` tokens of token type `id` from `from`\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `from` must have at least `amount` tokens of token type `id`.\n */\n function _burn(address from, uint256 id, uint256 amount) internal virtual {\n require(from != address(0), \"ERC1155: burn from the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n\n emit TransferSingle(operator, from, address(0), id, amount);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n */\n function _burnBatch(address from, uint256[] memory ids, uint256[] memory amounts) internal virtual {\n require(from != address(0), \"ERC1155: burn from the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n\n for (uint256 i = 0; i < ids.length; i++) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n }\n\n emit TransferBatch(operator, from, address(0), ids, amounts);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {\n require(owner != operator, \"ERC1155: setting approval status for self\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning, as well as batched variants.\n *\n * The same hook is called on both single and batched variants. For single\n * transfers, the length of the `ids` and `amounts` arrays will be 1.\n *\n * Calling conditions (for each `id` and `amount` pair):\n *\n * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * of token type `id` will be transferred to `to`.\n * - When `from` is zero, `amount` tokens of token type `id` will be minted\n * for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n * will be burned.\n * - `from` and `to` are never both zero.\n * - `ids` and `amounts` have the same, non-zero length.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any token transfer. This includes minting\n * and burning, as well as batched variants.\n *\n * The same hook is called on both single and batched variants. For single\n * transfers, the length of the `id` and `amount` arrays will be 1.\n *\n * Calling conditions (for each `id` and `amount` pair):\n *\n * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * of token type `id` will be transferred to `to`.\n * - When `from` is zero, `amount` tokens of token type `id` will be minted\n * for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n * will be burned.\n * - `from` and `to` are never both zero.\n * - `ids` and `amounts` have the same, non-zero length.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {}\n\n function _doSafeTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155Receiver.onERC1155Received.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non-ERC1155Receiver implementer\");\n }\n }\n }\n\n function _doSafeBatchTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (\n bytes4 response\n ) {\n if (response != IERC1155Receiver.onERC1155BatchReceived.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non-ERC1155Receiver implementer\");\n }\n }\n }\n\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {\n uint256[] memory array = new uint256[](1);\n array[0] = element;\n\n return array;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC1155.sol\";\n\n/**\n * @dev Interface of the optional ERC1155MetadataExtension interface, as defined\n * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155MetadataURI is IERC1155 {\n /**\n * @dev Returns the URI for token type `id`.\n *\n * If the `\\{id\\}` substring is present in the URI, it must be replaced by\n * clients with the actual token type ID.\n */\n function uri(uint256 id) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155 is IERC165 {\n /**\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n */\n event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);\n\n /**\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n * transfers.\n */\n event TransferBatch(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\n\n /**\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n * `approved`.\n */\n event ApprovalForAll(address indexed account, address indexed operator, bool approved);\n\n /**\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n *\n * If an {URI} event was emitted for `id`, the standard\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n * returned by {IERC1155MetadataURI-uri}.\n */\n event URI(string value, uint256 indexed id);\n\n /**\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) external view returns (uint256);\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] calldata accounts,\n uint256[] calldata ids\n ) external view returns (uint256[] memory);\n\n /**\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n *\n * Emits an {ApprovalForAll} event.\n *\n * Requirements:\n *\n * - `operator` cannot be the caller.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n *\n * See {setApprovalForAll}.\n */\n function isApprovedForAll(address account, address operator) external view returns (bool);\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155Receiver is IERC165 {\n /**\n * @dev Handles the receipt of a single ERC1155 token type. This function is\n * called at the end of a `safeTransferFrom` after the balance has been updated.\n *\n * NOTE: To accept the transfer, this must return\n * `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n * (i.e. 0xf23a6e61, or its own function selector).\n *\n * @param operator The address which initiated the transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param id The ID of the token being transferred\n * @param value The amount of tokens being transferred\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n ) external returns (bytes4);\n\n /**\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\n * is called at the end of a `safeBatchTransferFrom` after the balances have\n * been updated.\n *\n * NOTE: To accept the transfer(s), this must return\n * `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n * (i.e. 0xbc197c81, or its own function selector).\n *\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the default value returned by this function, unless\n * it's overridden.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(address from, address to, uint256 amount) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\n // decrementing then incrementing.\n _balances[to] += amount;\n }\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n unchecked {\n // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\n _balances[account] += amount;\n }\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n // Overflow not possible: amount <= accountBalance <= totalSupply.\n _totalSupply -= amount;\n }\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\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" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` 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 amount) 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 `amount` as the allowance of `spender` over the 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 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` 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 amount) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/ERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721.sol\";\nimport \"./IERC721Receiver.sol\";\nimport \"./extensions/IERC721Metadata.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/Strings.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\n using Address for address;\n using Strings for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\n\n // Mapping from token ID to approved address\n mapping(uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return\n interfaceId == type(IERC721).interfaceId ||\n interfaceId == type(IERC721Metadata).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _ownerOf(tokenId);\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token owner or approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n _requireMinted(tokenId);\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n _safeTransfer(from, to, tokenId, data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(address from, address to, uint256 tokenId, bytes memory data) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist\n */\n function _ownerOf(uint256 tokenId) internal view virtual returns (address) {\n return _owners[tokenId];\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _ownerOf(tokenId) != address(0);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n address owner = ERC721.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(address to, uint256 tokenId, bytes memory data) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId, 1);\n\n // Check that tokenId was not minted by `_beforeTokenTransfer` hook\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n unchecked {\n // Will not overflow unless all 2**256 token ids are minted to the same owner.\n // Given that tokens are minted one by one, it is impossible in practice that\n // this ever happens. Might change if we allow batch minting.\n // The ERC fails to describe this case.\n _balances[to] += 1;\n }\n\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(address(0), to, tokenId, 1);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n * This is an internal function that does not check if the sender is authorized to operate on the token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId, 1);\n\n // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook\n owner = ERC721.ownerOf(tokenId);\n\n // Clear approvals\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // Cannot overflow, as that would require more tokens to be burned/transferred\n // out than the owner initially received through minting and transferring in.\n _balances[owner] -= 1;\n }\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(owner, address(0), tokenId, 1);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(address from, address to, uint256 tokenId) internal virtual {\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId, 1);\n\n // Check that tokenId was not transferred by `_beforeTokenTransfer` hook\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n\n // Clear approvals from the previous owner\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // `_balances[from]` cannot overflow for the same reason as described in `_burn`:\n // `from`'s balance is the number of token held, which is at least one before the current\n // transfer.\n // `_balances[to]` could overflow in the conditions described in `_mint`. That would require\n // all 2**256 token ids to be minted, which in practice is impossible.\n _balances[from] -= 1;\n _balances[to] += 1;\n }\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId, 1);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721Receiver.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`.\n * - When `from` is zero, the tokens will be minted for `to`.\n * - When `to` is zero, ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}\n\n /**\n * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`.\n * - When `from` is zero, the tokens were minted for `to`.\n * - When `to` is zero, ``from``'s tokens were burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}\n\n /**\n * @dev Unsafe write access to the balances, used by extensions that \"mint\" tokens using an {ownerOf} override.\n *\n * WARNING: Anyone calling this MUST ensure that the balances remain consistent with the ownership. The invariant\n * being that for any address `a` the value returned by `balanceOf(a)` must be equal to the number of tokens such\n * that `ownerOf(tokenId)` is `a`.\n */\n // solhint-disable-next-line func-name-mixedcase\n function __unsafe_increaseBalance(address account, uint256 amount) internal {\n _balances[account] += amount;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721Receiver {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/ERC777.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC777/ERC777.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC777.sol\";\nimport \"./IERC777Recipient.sol\";\nimport \"./IERC777Sender.sol\";\nimport \"../ERC20/IERC20.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/introspection/IERC1820Registry.sol\";\n\n/**\n * @dev Implementation of the {IERC777} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n *\n * Support for ERC20 is included in this contract, as specified by the EIP: both\n * the ERC777 and ERC20 interfaces can be safely used when interacting with it.\n * Both {IERC777-Sent} and {IERC20-Transfer} events are emitted on token\n * movements.\n *\n * Additionally, the {IERC777-granularity} value is hard-coded to `1`, meaning that there\n * are no special restrictions in the amount of tokens that created, moved, or\n * destroyed. This makes integration with ERC20 applications seamless.\n *\n * CAUTION: This file is deprecated as of v4.9 and will be removed in the next major release.\n */\ncontract ERC777 is Context, IERC777, IERC20 {\n using Address for address;\n\n IERC1820Registry internal constant _ERC1820_REGISTRY = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n mapping(address => uint256) private _balances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n bytes32 private constant _TOKENS_SENDER_INTERFACE_HASH = keccak256(\"ERC777TokensSender\");\n bytes32 private constant _TOKENS_RECIPIENT_INTERFACE_HASH = keccak256(\"ERC777TokensRecipient\");\n\n // This isn't ever read from - it's only used to respond to the defaultOperators query.\n address[] private _defaultOperatorsArray;\n\n // Immutable, but accounts may revoke them (tracked in __revokedDefaultOperators).\n mapping(address => bool) private _defaultOperators;\n\n // For each account, a mapping of its operators and revoked default operators.\n mapping(address => mapping(address => bool)) private _operators;\n mapping(address => mapping(address => bool)) private _revokedDefaultOperators;\n\n // ERC20-allowances\n mapping(address => mapping(address => uint256)) private _allowances;\n\n /**\n * @dev `defaultOperators` may be an empty array.\n */\n constructor(string memory name_, string memory symbol_, address[] memory defaultOperators_) {\n _name = name_;\n _symbol = symbol_;\n\n _defaultOperatorsArray = defaultOperators_;\n for (uint256 i = 0; i < defaultOperators_.length; i++) {\n _defaultOperators[defaultOperators_[i]] = true;\n }\n\n // register interfaces\n _ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256(\"ERC777Token\"), address(this));\n _ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256(\"ERC20Token\"), address(this));\n }\n\n /**\n * @dev See {IERC777-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC777-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {ERC20-decimals}.\n *\n * Always returns 18, as per the\n * [ERC777 EIP](https://eips.ethereum.org/EIPS/eip-777#backward-compatibility).\n */\n function decimals() public pure virtual returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC777-granularity}.\n *\n * This implementation always returns `1`.\n */\n function granularity() public view virtual override returns (uint256) {\n return 1;\n }\n\n /**\n * @dev See {IERC777-totalSupply}.\n */\n function totalSupply() public view virtual override(IERC20, IERC777) returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev Returns the amount of tokens owned by an account (`tokenHolder`).\n */\n function balanceOf(address tokenHolder) public view virtual override(IERC20, IERC777) returns (uint256) {\n return _balances[tokenHolder];\n }\n\n /**\n * @dev See {IERC777-send}.\n *\n * Also emits a {IERC20-Transfer} event for ERC20 compatibility.\n */\n function send(address recipient, uint256 amount, bytes memory data) public virtual override {\n _send(_msgSender(), recipient, amount, data, \"\", true);\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Unlike `send`, `recipient` is _not_ required to implement the {IERC777Recipient}\n * interface if it is a contract.\n *\n * Also emits a {Sent} event.\n */\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n _send(_msgSender(), recipient, amount, \"\", \"\", false);\n return true;\n }\n\n /**\n * @dev See {IERC777-burn}.\n *\n * Also emits a {IERC20-Transfer} event for ERC20 compatibility.\n */\n function burn(uint256 amount, bytes memory data) public virtual override {\n _burn(_msgSender(), amount, data, \"\");\n }\n\n /**\n * @dev See {IERC777-isOperatorFor}.\n */\n function isOperatorFor(address operator, address tokenHolder) public view virtual override returns (bool) {\n return\n operator == tokenHolder ||\n (_defaultOperators[operator] && !_revokedDefaultOperators[tokenHolder][operator]) ||\n _operators[tokenHolder][operator];\n }\n\n /**\n * @dev See {IERC777-authorizeOperator}.\n */\n function authorizeOperator(address operator) public virtual override {\n require(_msgSender() != operator, \"ERC777: authorizing self as operator\");\n\n if (_defaultOperators[operator]) {\n delete _revokedDefaultOperators[_msgSender()][operator];\n } else {\n _operators[_msgSender()][operator] = true;\n }\n\n emit AuthorizedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-revokeOperator}.\n */\n function revokeOperator(address operator) public virtual override {\n require(operator != _msgSender(), \"ERC777: revoking self as operator\");\n\n if (_defaultOperators[operator]) {\n _revokedDefaultOperators[_msgSender()][operator] = true;\n } else {\n delete _operators[_msgSender()][operator];\n }\n\n emit RevokedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-defaultOperators}.\n */\n function defaultOperators() public view virtual override returns (address[] memory) {\n return _defaultOperatorsArray;\n }\n\n /**\n * @dev See {IERC777-operatorSend}.\n *\n * Emits {Sent} and {IERC20-Transfer} events.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes memory data,\n bytes memory operatorData\n ) public virtual override {\n require(isOperatorFor(_msgSender(), sender), \"ERC777: caller is not an operator for holder\");\n _send(sender, recipient, amount, data, operatorData, true);\n }\n\n /**\n * @dev See {IERC777-operatorBurn}.\n *\n * Emits {Burned} and {IERC20-Transfer} events.\n */\n function operatorBurn(\n address account,\n uint256 amount,\n bytes memory data,\n bytes memory operatorData\n ) public virtual override {\n require(isOperatorFor(_msgSender(), account), \"ERC777: caller is not an operator for holder\");\n _burn(account, amount, data, operatorData);\n }\n\n /**\n * @dev See {IERC20-allowance}.\n *\n * Note that operator and allowance concepts are orthogonal: operators may\n * not have allowance, and accounts with allowance may not be operators\n * themselves.\n */\n function allowance(address holder, address spender) public view virtual override returns (uint256) {\n return _allowances[holder][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Note that accounts cannot have allowance issued by their operators.\n */\n function approve(address spender, uint256 value) public virtual override returns (bool) {\n address holder = _msgSender();\n _approve(holder, spender, value);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Note that operator and allowance concepts are orthogonal: operators cannot\n * call `transferFrom` (unless they have allowance), and accounts with\n * allowance cannot call `operatorSend` (unless they are operators).\n *\n * Emits {Sent}, {IERC20-Transfer} and {IERC20-Approval} events.\n */\n function transferFrom(address holder, address recipient, uint256 amount) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(holder, spender, amount);\n _send(holder, recipient, amount, \"\", \"\", false);\n return true;\n }\n\n /**\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with the caller address as the `operator` and with\n * `userData` and `operatorData`.\n *\n * See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits {Minted} and {IERC20-Transfer} events.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - if `account` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function _mint(address account, uint256 amount, bytes memory userData, bytes memory operatorData) internal virtual {\n _mint(account, amount, userData, operatorData, true);\n }\n\n /**\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * If `requireReceptionAck` is set to true, and if a send hook is\n * registered for `account`, the corresponding function will be called with\n * `operator`, `data` and `operatorData`.\n *\n * See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits {Minted} and {IERC20-Transfer} events.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - if `account` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function _mint(\n address account,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) internal virtual {\n require(account != address(0), \"ERC777: mint to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), account, amount);\n\n // Update state variables\n _totalSupply += amount;\n _balances[account] += amount;\n\n _callTokensReceived(operator, address(0), account, amount, userData, operatorData, requireReceptionAck);\n\n emit Minted(operator, account, amount, userData, operatorData);\n emit Transfer(address(0), account, amount);\n }\n\n /**\n * @dev Send tokens\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _send(\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) internal virtual {\n require(from != address(0), \"ERC777: transfer from the zero address\");\n require(to != address(0), \"ERC777: transfer to the zero address\");\n\n address operator = _msgSender();\n\n _callTokensToSend(operator, from, to, amount, userData, operatorData);\n\n _move(operator, from, to, amount, userData, operatorData);\n\n _callTokensReceived(operator, from, to, amount, userData, operatorData, requireReceptionAck);\n }\n\n /**\n * @dev Burn tokens\n * @param from address token holder address\n * @param amount uint256 amount of tokens to burn\n * @param data bytes extra information provided by the token holder\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _burn(address from, uint256 amount, bytes memory data, bytes memory operatorData) internal virtual {\n require(from != address(0), \"ERC777: burn from the zero address\");\n\n address operator = _msgSender();\n\n _callTokensToSend(operator, from, address(0), amount, data, operatorData);\n\n _beforeTokenTransfer(operator, from, address(0), amount);\n\n // Update state variables\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC777: burn amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Burned(operator, from, amount, data, operatorData);\n emit Transfer(from, address(0), amount);\n }\n\n function _move(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n ) private {\n _beforeTokenTransfer(operator, from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC777: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Sent(operator, from, to, amount, userData, operatorData);\n emit Transfer(from, to, amount);\n }\n\n /**\n * @dev See {ERC20-_approve}.\n *\n * Note that accounts cannot have allowance issued by their operators.\n */\n function _approve(address holder, address spender, uint256 value) internal virtual {\n require(holder != address(0), \"ERC777: approve from the zero address\");\n require(spender != address(0), \"ERC777: approve to the zero address\");\n\n _allowances[holder][spender] = value;\n emit Approval(holder, spender, value);\n }\n\n /**\n * @dev Call from.tokensToSend() if the interface is registered\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _callTokensToSend(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n ) private {\n address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(from, _TOKENS_SENDER_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Sender(implementer).tokensToSend(operator, from, to, amount, userData, operatorData);\n }\n }\n\n /**\n * @dev Call to.tokensReceived() if the interface is registered. Reverts if the recipient is a contract but\n * tokensReceived() was not registered for the recipient\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _callTokensReceived(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) private {\n address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(to, _TOKENS_RECIPIENT_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Recipient(implementer).tokensReceived(operator, from, to, amount, userData, operatorData);\n } else if (requireReceptionAck) {\n require(!to.isContract(), \"ERC777: token recipient contract has no implementer for ERC777TokensRecipient\");\n }\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {IERC20-Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC777: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes\n * calls to {send}, {transfer}, {operatorSend}, {transferFrom}, minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be to transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address operator, address from, address to, uint256 amount) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC777/IERC777.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777Token standard as defined in the EIP.\n *\n * This contract uses the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 registry standard] to let\n * token holders and recipients react to token movements by using setting implementers\n * for the associated interfaces in said registry. See {IERC1820Registry} and\n * {ERC1820Implementer}.\n */\ninterface IERC777 {\n /**\n * @dev Emitted when `amount` tokens are created by `operator` and assigned to `to`.\n *\n * Note that some additional user `data` and `operatorData` can be logged in the event.\n */\n event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);\n\n /**\n * @dev Emitted when `operator` destroys `amount` tokens from `account`.\n *\n * Note that some additional user `data` and `operatorData` can be logged in the event.\n */\n event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);\n\n /**\n * @dev Emitted when `operator` is made operator for `tokenHolder`.\n */\n event AuthorizedOperator(address indexed operator, address indexed tokenHolder);\n\n /**\n * @dev Emitted when `operator` is revoked its operator status for `tokenHolder`.\n */\n event RevokedOperator(address indexed operator, address indexed tokenHolder);\n\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, usually a shorter version of the\n * name.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the smallest part of the token that is not divisible. This\n * means all token operations (creation, movement and destruction) must have\n * amounts that are a multiple of this number.\n *\n * For most token contracts, this value will equal 1.\n */\n function granularity() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by an account (`owner`).\n */\n function balanceOf(address owner) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * If send or receive hooks are registered for the caller and `recipient`,\n * the corresponding functions will be called with `data` and empty\n * `operatorData`. See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits a {Sent} event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function send(address recipient, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Destroys `amount` tokens from the caller's account, reducing the\n * total supply.\n *\n * If a send hook is registered for the caller, the corresponding function\n * will be called with `data` and empty `operatorData`. See {IERC777Sender}.\n *\n * Emits a {Burned} event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n */\n function burn(uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Returns true if an account is an operator of `tokenHolder`.\n * Operators can send and burn tokens on behalf of their owners. All\n * accounts are their own operator.\n *\n * See {operatorSend} and {operatorBurn}.\n */\n function isOperatorFor(address operator, address tokenHolder) external view returns (bool);\n\n /**\n * @dev Make an account an operator of the caller.\n *\n * See {isOperatorFor}.\n *\n * Emits an {AuthorizedOperator} event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function authorizeOperator(address operator) external;\n\n /**\n * @dev Revoke an account's operator status for the caller.\n *\n * See {isOperatorFor} and {defaultOperators}.\n *\n * Emits a {RevokedOperator} event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function revokeOperator(address operator) external;\n\n /**\n * @dev Returns the list of default operators. These accounts are operators\n * for all token holders, even if {authorizeOperator} was never called on\n * them.\n *\n * This list is immutable, but individual holders may revoke these via\n * {revokeOperator}, in which case {isOperatorFor} will return false.\n */\n function defaultOperators() external view returns (address[] memory);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must\n * be an operator of `sender`.\n *\n * If send or receive hooks are registered for `sender` and `recipient`,\n * the corresponding functions will be called with `data` and\n * `operatorData`. See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits a {Sent} event.\n *\n * Requirements\n *\n * - `sender` cannot be the zero address.\n * - `sender` must have at least `amount` tokens.\n * - the caller must be an operator for `sender`.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes calldata data,\n bytes calldata operatorData\n ) external;\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the total supply.\n * The caller must be an operator of `account`.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with `data` and `operatorData`. See {IERC777Sender}.\n *\n * Emits a {Burned} event.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n * - the caller must be an operator for `account`.\n */\n function operatorBurn(address account, uint256 amount, bytes calldata data, bytes calldata operatorData) external;\n\n event Sent(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes data,\n bytes operatorData\n );\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\n *\n * Accounts can be notified of {IERC777} tokens being sent to them by having a\n * contract implement this interface (contract holders can be their own\n * implementer) and registering it on the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\n *\n * See {IERC1820Registry} and {ERC1820Implementer}.\n */\ninterface IERC777Recipient {\n /**\n * @dev Called by an {IERC777} token contract whenever tokens are being\n * moved or created into a registered account (`to`). The type of operation\n * is conveyed by `from` being the zero address or not.\n *\n * This call occurs _after_ the token contract's state is updated, so\n * {IERC777-balanceOf}, etc., can be used to query the post-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensReceived(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777Sender.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Sender.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777TokensSender standard as defined in the EIP.\n *\n * {IERC777} Token holders can be notified of operations performed on their\n * tokens by having a contract implement this interface (contract holders can be\n * their own implementer) and registering it on the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\n *\n * See {IERC1820Registry} and {ERC1820Implementer}.\n */\ninterface IERC777Sender {\n /**\n * @dev Called by an {IERC777} token contract whenever a registered holder's\n * (`from`) tokens are about to be moved or destroyed. The type of operation\n * is conveyed by `to` being the zero address or not.\n *\n * This call occurs _before_ the token contract's state is updated, so\n * {IERC777-balanceOf}, etc., can be used to query the pre-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensToSend(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n *\n * Furthermore, `isContract` will also return true if the target contract within\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n * which only has an effect at the end of a transaction.\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Counters.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary Counters {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/ECDSA.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Strings.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV // Deprecated in v4.8\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n /// @solidity memory-safe-assembly\n assembly {\n mstore(0x00, \"\\x19Ethereum Signed Message:\\n32\")\n mstore(0x1c, hash)\n message := keccak256(0x00, 0x3c)\n }\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\n /// @solidity memory-safe-assembly\n assembly {\n let ptr := mload(0x40)\n mstore(ptr, \"\\x19\\x01\")\n mstore(add(ptr, 0x02), domainSeparator)\n mstore(add(ptr, 0x22), structHash)\n data := keccak256(ptr, 0x42)\n }\n }\n\n /**\n * @dev Returns an Ethereum Signed Data with intended validator, created from a\n * `validator` and `data` according to the version 0 of EIP-191.\n *\n * See {recover}.\n */\n function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x00\", validator, data));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/SignatureChecker.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSA.sol\";\nimport \"../../interfaces/IERC1271.sol\";\n\n/**\n * @dev Signature verification helper that can be used instead of `ECDSA.recover` to seamlessly support both ECDSA\n * signatures from externally owned accounts (EOAs) as well as ERC1271 signatures from smart contract wallets like\n * Argent and Gnosis Safe.\n *\n * _Available since v4.1._\n */\nlibrary SignatureChecker {\n /**\n * @dev Checks if a signature is valid for a given signer and data hash. If the signer is a smart contract, the\n * signature is validated against that smart contract using ERC1271, otherwise it's validated using `ECDSA.recover`.\n *\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\n */\n function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature) internal view returns (bool) {\n (address recovered, ECDSA.RecoverError error) = ECDSA.tryRecover(hash, signature);\n return\n (error == ECDSA.RecoverError.NoError && recovered == signer) ||\n isValidERC1271SignatureNow(signer, hash, signature);\n }\n\n /**\n * @dev Checks if a signature is valid for a given signer and data hash. The signature is validated\n * against the signer smart contract using ERC1271.\n *\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\n */\n function isValidERC1271SignatureNow(\n address signer,\n bytes32 hash,\n bytes memory signature\n ) internal view returns (bool) {\n (bool success, bytes memory result) = signer.staticcall(\n abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, signature)\n );\n return (success &&\n result.length >= 32 &&\n abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/ERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165 is IERC165 {\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165).interfaceId;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC1820Registry.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/introspection/IERC1820Registry.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the global ERC1820 Registry, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register\n * implementers for interfaces in this registry, as well as query support.\n *\n * Implementers may be shared by multiple accounts, and can also implement more\n * than a single interface for each account. Contracts can implement interfaces\n * for themselves, but externally-owned accounts (EOA) must delegate this to a\n * contract.\n *\n * {IERC165} interfaces can also be queried via the registry.\n *\n * For an in-depth explanation and source code analysis, see the EIP text.\n */\ninterface IERC1820Registry {\n event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer);\n\n event ManagerChanged(address indexed account, address indexed newManager);\n\n /**\n * @dev Sets `newManager` as the manager for `account`. A manager of an\n * account is able to set interface implementers for it.\n *\n * By default, each account is its own manager. Passing a value of `0x0` in\n * `newManager` will reset the manager to this initial state.\n *\n * Emits a {ManagerChanged} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `account`.\n */\n function setManager(address account, address newManager) external;\n\n /**\n * @dev Returns the manager for `account`.\n *\n * See {setManager}.\n */\n function getManager(address account) external view returns (address);\n\n /**\n * @dev Sets the `implementer` contract as ``account``'s implementer for\n * `interfaceHash`.\n *\n * `account` being the zero address is an alias for the caller's address.\n * The zero address can also be used in `implementer` to remove an old one.\n *\n * See {interfaceHash} to learn how these are created.\n *\n * Emits an {InterfaceImplementerSet} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `account`.\n * - `interfaceHash` must not be an {IERC165} interface id (i.e. it must not\n * end in 28 zeroes).\n * - `implementer` must implement {IERC1820Implementer} and return true when\n * queried for support, unless `implementer` is the caller. See\n * {IERC1820Implementer-canImplementInterfaceForAddress}.\n */\n function setInterfaceImplementer(address account, bytes32 _interfaceHash, address implementer) external;\n\n /**\n * @dev Returns the implementer of `interfaceHash` for `account`. If no such\n * implementer is registered, returns the zero address.\n *\n * If `interfaceHash` is an {IERC165} interface id (i.e. it ends with 28\n * zeroes), `account` will be queried for support of it.\n *\n * `account` being the zero address is an alias for the caller's address.\n */\n function getInterfaceImplementer(address account, bytes32 _interfaceHash) external view returns (address);\n\n /**\n * @dev Returns the interface hash for an `interfaceName`, as defined in the\n * corresponding\n * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP].\n */\n function interfaceHash(string calldata interfaceName) external pure returns (bytes32);\n\n /**\n * @notice Updates the cache with whether the contract implements an ERC165 interface or not.\n * @param account Address of the contract for which to update the cache.\n * @param interfaceId ERC165 interface for which to update the cache.\n */\n function updateERC165Cache(address account, bytes4 interfaceId) external;\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not.\n * If the result is not cached a direct lookup on the contract address is performed.\n * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling\n * {updateERC165Cache} with the contract address.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool);\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not without using or updating the cache.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/math/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\n // The surrounding unchecked block does not change this fact.\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1, \"Math: mulDiv overflow\");\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n //\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n //\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n //\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1 << (log2(a) >> 1);\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = sqrt(a);\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 2, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 128;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 64;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 32;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 16;\n }\n if (value >> 8 > 0) {\n value >>= 8;\n result += 8;\n }\n if (value >> 4 > 0) {\n value >>= 4;\n result += 4;\n }\n if (value >> 2 > 0) {\n value >>= 2;\n result += 2;\n }\n if (value >> 1 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log2(value);\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 10, rounded down, of a positive value.\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 + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 256, rounded down, of a positive value.\n * Returns 0 if given 0.\n *\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n */\n function log256(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 16;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 8;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 4;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 2;\n }\n if (value >> 8 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log256(value);\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/SafeCast.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCast {\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 * _Available since v4.7._\n */\n function toUint248(uint256 value) internal pure returns (uint248) {\n require(value <= type(uint248).max, \"SafeCast: value doesn't fit in 248 bits\");\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 * _Available since v4.7._\n */\n function toUint240(uint256 value) internal pure returns (uint240) {\n require(value <= type(uint240).max, \"SafeCast: value doesn't fit in 240 bits\");\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 * _Available since v4.7._\n */\n function toUint232(uint256 value) internal pure returns (uint232) {\n require(value <= type(uint232).max, \"SafeCast: value doesn't fit in 232 bits\");\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 * _Available since v4.2._\n */\n function toUint224(uint256 value) internal pure returns (uint224) {\n require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\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 * _Available since v4.7._\n */\n function toUint216(uint256 value) internal pure returns (uint216) {\n require(value <= type(uint216).max, \"SafeCast: value doesn't fit in 216 bits\");\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 * _Available since v4.7._\n */\n function toUint208(uint256 value) internal pure returns (uint208) {\n require(value <= type(uint208).max, \"SafeCast: value doesn't fit in 208 bits\");\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 * _Available since v4.7._\n */\n function toUint200(uint256 value) internal pure returns (uint200) {\n require(value <= type(uint200).max, \"SafeCast: value doesn't fit in 200 bits\");\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 * _Available since v4.7._\n */\n function toUint192(uint256 value) internal pure returns (uint192) {\n require(value <= type(uint192).max, \"SafeCast: value doesn't fit in 192 bits\");\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 * _Available since v4.7._\n */\n function toUint184(uint256 value) internal pure returns (uint184) {\n require(value <= type(uint184).max, \"SafeCast: value doesn't fit in 184 bits\");\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 * _Available since v4.7._\n */\n function toUint176(uint256 value) internal pure returns (uint176) {\n require(value <= type(uint176).max, \"SafeCast: value doesn't fit in 176 bits\");\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 * _Available since v4.7._\n */\n function toUint168(uint256 value) internal pure returns (uint168) {\n require(value <= type(uint168).max, \"SafeCast: value doesn't fit in 168 bits\");\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 * _Available since v4.7._\n */\n function toUint160(uint256 value) internal pure returns (uint160) {\n require(value <= type(uint160).max, \"SafeCast: value doesn't fit in 160 bits\");\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 * _Available since v4.7._\n */\n function toUint152(uint256 value) internal pure returns (uint152) {\n require(value <= type(uint152).max, \"SafeCast: value doesn't fit in 152 bits\");\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 * _Available since v4.7._\n */\n function toUint144(uint256 value) internal pure returns (uint144) {\n require(value <= type(uint144).max, \"SafeCast: value doesn't fit in 144 bits\");\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 * _Available since v4.7._\n */\n function toUint136(uint256 value) internal pure returns (uint136) {\n require(value <= type(uint136).max, \"SafeCast: value doesn't fit in 136 bits\");\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 * _Available since v2.5._\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\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 * _Available since v4.7._\n */\n function toUint120(uint256 value) internal pure returns (uint120) {\n require(value <= type(uint120).max, \"SafeCast: value doesn't fit in 120 bits\");\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 * _Available since v4.7._\n */\n function toUint112(uint256 value) internal pure returns (uint112) {\n require(value <= type(uint112).max, \"SafeCast: value doesn't fit in 112 bits\");\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 * _Available since v4.7._\n */\n function toUint104(uint256 value) internal pure returns (uint104) {\n require(value <= type(uint104).max, \"SafeCast: value doesn't fit in 104 bits\");\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 * _Available since v4.2._\n */\n function toUint96(uint256 value) internal pure returns (uint96) {\n require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\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 * _Available since v4.7._\n */\n function toUint88(uint256 value) internal pure returns (uint88) {\n require(value <= type(uint88).max, \"SafeCast: value doesn't fit in 88 bits\");\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 * _Available since v4.7._\n */\n function toUint80(uint256 value) internal pure returns (uint80) {\n require(value <= type(uint80).max, \"SafeCast: value doesn't fit in 80 bits\");\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 * _Available since v4.7._\n */\n function toUint72(uint256 value) internal pure returns (uint72) {\n require(value <= type(uint72).max, \"SafeCast: value doesn't fit in 72 bits\");\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 * _Available since v2.5._\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\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 * _Available since v4.7._\n */\n function toUint56(uint256 value) internal pure returns (uint56) {\n require(value <= type(uint56).max, \"SafeCast: value doesn't fit in 56 bits\");\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 * _Available since v4.7._\n */\n function toUint48(uint256 value) internal pure returns (uint48) {\n require(value <= type(uint48).max, \"SafeCast: value doesn't fit in 48 bits\");\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 * _Available since v4.7._\n */\n function toUint40(uint256 value) internal pure returns (uint40) {\n require(value <= type(uint40).max, \"SafeCast: value doesn't fit in 40 bits\");\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 * _Available since v2.5._\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\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 * _Available since v4.7._\n */\n function toUint24(uint256 value) internal pure returns (uint24) {\n require(value <= type(uint24).max, \"SafeCast: value doesn't fit in 24 bits\");\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 * _Available since v2.5._\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\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 * _Available since v2.5._\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\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 * _Available since v3.0._\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\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 * _Available since v4.7._\n */\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\n downcasted = int248(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 248 bits\");\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 * _Available since v4.7._\n */\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\n downcasted = int240(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 240 bits\");\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 * _Available since v4.7._\n */\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\n downcasted = int232(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 232 bits\");\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 * _Available since v4.7._\n */\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\n downcasted = int224(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 224 bits\");\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 * _Available since v4.7._\n */\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\n downcasted = int216(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 216 bits\");\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 * _Available since v4.7._\n */\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\n downcasted = int208(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 208 bits\");\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 * _Available since v4.7._\n */\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\n downcasted = int200(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 200 bits\");\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 * _Available since v4.7._\n */\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\n downcasted = int192(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 192 bits\");\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 * _Available since v4.7._\n */\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\n downcasted = int184(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 184 bits\");\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 * _Available since v4.7._\n */\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\n downcasted = int176(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 176 bits\");\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 * _Available since v4.7._\n */\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\n downcasted = int168(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 168 bits\");\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 * _Available since v4.7._\n */\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\n downcasted = int160(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 160 bits\");\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 * _Available since v4.7._\n */\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\n downcasted = int152(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 152 bits\");\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 * _Available since v4.7._\n */\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\n downcasted = int144(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 144 bits\");\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 * _Available since v4.7._\n */\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\n downcasted = int136(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 136 bits\");\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 * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\n downcasted = int128(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 128 bits\");\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 * _Available since v4.7._\n */\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\n downcasted = int120(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 120 bits\");\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 * _Available since v4.7._\n */\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\n downcasted = int112(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 112 bits\");\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 * _Available since v4.7._\n */\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\n downcasted = int104(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 104 bits\");\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 * _Available since v4.7._\n */\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\n downcasted = int96(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 96 bits\");\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 * _Available since v4.7._\n */\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\n downcasted = int88(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 88 bits\");\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 * _Available since v4.7._\n */\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\n downcasted = int80(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 80 bits\");\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 * _Available since v4.7._\n */\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\n downcasted = int72(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 72 bits\");\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 * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\n downcasted = int64(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 64 bits\");\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 * _Available since v4.7._\n */\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\n downcasted = int56(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 56 bits\");\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 * _Available since v4.7._\n */\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\n downcasted = int48(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 48 bits\");\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 * _Available since v4.7._\n */\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\n downcasted = int40(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 40 bits\");\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 * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\n downcasted = int32(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 32 bits\");\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 * _Available since v4.7._\n */\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\n downcasted = int24(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 24 bits\");\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 * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\n downcasted = int16(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 16 bits\");\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 * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\n downcasted = int8(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 8 bits\");\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 * _Available since v3.0._\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 require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/SignedMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard signed math utilities missing in the Solidity language.\n */\nlibrary SignedMath {\n /**\n * @dev Returns the largest of two signed numbers.\n */\n function max(int256 a, int256 b) internal pure returns (int256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two signed numbers.\n */\n function min(int256 a, int256 b) internal pure returns (int256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two signed numbers without overflow.\n * The result is rounded towards zero.\n */\n function average(int256 a, int256 b) internal pure returns (int256) {\n // Formula from the book \"Hacker's Delight\"\n int256 x = (a & b) + ((a ^ b) >> 1);\n return x + (int256(uint256(x) >> 255) & (a ^ b));\n }\n\n /**\n * @dev Returns the absolute unsigned value of a signed value.\n */\n function abs(int256 n) internal pure returns (uint256) {\n unchecked {\n // must be unchecked in order to support `n = type(int256).min`\n return uint256(n >= 0 ? n : -n);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/Math.sol\";\nimport \"./math/SignedMath.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n unchecked {\n uint256 length = Math.log10(value) + 1;\n string memory buffer = new string(length);\n uint256 ptr;\n /// @solidity memory-safe-assembly\n assembly {\n ptr := add(buffer, add(32, length))\n }\n while (true) {\n ptr--;\n /// @solidity memory-safe-assembly\n assembly {\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n }\n value /= 10;\n if (value == 0) break;\n }\n return buffer;\n }\n }\n\n /**\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\n */\n function toString(int256 value) internal pure returns (string memory) {\n return string(abi.encodePacked(value < 0 ? \"-\" : \"\", toString(SignedMath.abs(value))));\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n unchecked {\n return toHexString(value, Math.log256(value) + 1);\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n\n /**\n * @dev Returns true if the two strings are equal.\n */\n function equal(string memory a, string memory b) internal pure returns (bool) {\n return keccak256(bytes(a)) == keccak256(bytes(b));\n }\n}\n" + }, + "contracts/aa-4337/core/BaseAccount.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-empty-blocks */\n\nimport \"../interfaces/IAccount.sol\";\nimport \"../interfaces/IEntryPoint.sol\";\nimport \"./Helpers.sol\";\n\n/**\n * Basic account implementation.\n * this contract provides the basic logic for implementing the IAccount interface - validateUserOp\n * specific account implementation should inherit it and provide the account-specific logic\n */\nabstract contract BaseAccount is IAccount {\n using UserOperationLib for UserOperation;\n\n //return value in case of signature failure, with no time-range.\n // equivalent to _packValidationData(true,0,0);\n uint256 internal constant SIG_VALIDATION_FAILED = 1;\n\n /**\n * Return the account nonce.\n * This method returns the next sequential nonce.\n * For a nonce of a specific key, use `entrypoint.getNonce(account, key)`\n */\n function getNonce() public view virtual returns (uint256) {\n return entryPoint().getNonce(address(this), 0);\n }\n\n /**\n * return the entryPoint used by this account.\n * subclass should return the current entryPoint used by this account.\n */\n function entryPoint() public view virtual returns (IEntryPoint);\n\n /**\n * Validate user's signature and nonce.\n * subclass doesn't need to override this method. Instead, it should override the specific internal validation methods.\n */\n function validateUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 missingAccountFunds\n ) external virtual override returns (uint256 validationData) {\n _requireFromEntryPoint();\n validationData = _validateSignature(userOp, userOpHash);\n _validateNonce(userOp.nonce);\n _payPrefund(missingAccountFunds);\n }\n\n /**\n * ensure the request comes from the known entrypoint.\n */\n function _requireFromEntryPoint() internal view virtual {\n require(\n msg.sender == address(entryPoint()),\n \"account: not from EntryPoint\"\n );\n }\n\n /**\n * validate the signature is valid for this message.\n * @param userOp validate the userOp.signature field\n * @param userOpHash convenient field: the hash of the request, to check the signature against\n * (also hashes the entrypoint and chain id)\n * @return validationData signature and time-range of this operation\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * If the account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function _validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) internal virtual returns (uint256 validationData);\n\n /**\n * Validate the nonce of the UserOperation.\n * This method may validate the nonce requirement of this account.\n * e.g.\n * To limit the nonce to use sequenced UserOps only (no \"out of order\" UserOps):\n * `require(nonce < type(uint64).max)`\n * For a hypothetical account that *requires* the nonce to be out-of-order:\n * `require(nonce & type(uint64).max == 0)`\n *\n * The actual nonce uniqueness is managed by the EntryPoint, and thus no other\n * action is needed by the account itself.\n *\n * @param nonce to validate\n *\n * solhint-disable-next-line no-empty-blocks\n */\n function _validateNonce(uint256 nonce) internal view virtual {}\n\n /**\n * sends to the entrypoint (msg.sender) the missing funds for this transaction.\n * subclass MAY override this method for better funds management\n * (e.g. send to the entryPoint more than the minimum required, so that in future transactions\n * it will not be required to send again)\n * @param missingAccountFunds the minimum value this method should send the entrypoint.\n * this value MAY be zero, in case there is enough deposit, or the userOp has a paymaster.\n */\n function _payPrefund(uint256 missingAccountFunds) internal virtual {\n if (missingAccountFunds != 0) {\n (bool success, ) = payable(msg.sender).call{\n value: missingAccountFunds,\n gas: type(uint256).max\n }(\"\");\n (success);\n //ignore failure (its EntryPoint's job to verify, not account.)\n }\n }\n}\n" + }, + "contracts/aa-4337/core/EntryPoint.sol": { + "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n\nimport \"../interfaces/IAccount.sol\";\nimport \"../interfaces/IPaymaster.sol\";\nimport \"../interfaces/IEntryPoint.sol\";\n\nimport \"../utils/Exec.sol\";\nimport \"./StakeManager.sol\";\nimport \"./SenderCreator.sol\";\nimport \"./Helpers.sol\";\nimport \"./NonceManager.sol\";\nimport \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\n\ncontract EntryPoint is\n IEntryPoint,\n StakeManager,\n NonceManager,\n ReentrancyGuard\n{\n using UserOperationLib for UserOperation;\n\n SenderCreator private immutable senderCreator = new SenderCreator();\n\n // internal value used during simulation: need to query aggregator.\n address private constant SIMULATE_FIND_AGGREGATOR = address(1);\n\n // marker for inner call revert on out of gas\n bytes32 private constant INNER_OUT_OF_GAS = hex\"deaddead\";\n\n uint256 private constant REVERT_REASON_MAX_LEN = 2048;\n\n /**\n * for simulation purposes, validateUserOp (and validatePaymasterUserOp) must return this value\n * in case of signature failure, instead of revert.\n */\n uint256 public constant SIG_VALIDATION_FAILED = 1;\n\n /**\n * compensate the caller's beneficiary address with the collected fees of all UserOperations.\n * @param beneficiary the address to receive the fees\n * @param amount amount to transfer.\n */\n function _compensate(address payable beneficiary, uint256 amount) internal {\n require(beneficiary != address(0), \"AA90 invalid beneficiary\");\n (bool success, ) = beneficiary.call{value: amount}(\"\");\n require(success, \"AA91 failed send to beneficiary\");\n }\n\n /**\n * execute a user op\n * @param opIndex index into the opInfo array\n * @param userOp the userOp to execute\n * @param opInfo the opInfo filled by validatePrepayment for this userOp.\n * @return collected the total amount this userOp paid.\n */\n function _executeUserOp(\n uint256 opIndex,\n UserOperation calldata userOp,\n UserOpInfo memory opInfo\n ) private returns (uint256 collected) {\n uint256 preGas = gasleft();\n bytes memory context = getMemoryBytesFromOffset(opInfo.contextOffset);\n\n try this.innerHandleOp(userOp.callData, opInfo, context) returns (\n uint256 _actualGasCost\n ) {\n collected = _actualGasCost;\n } catch {\n bytes32 innerRevertCode;\n assembly {\n returndatacopy(0, 0, 32)\n innerRevertCode := mload(0)\n }\n // handleOps was called with gas limit too low. abort entire bundle.\n if (innerRevertCode == INNER_OUT_OF_GAS) {\n //report paymaster, since if it is not deliberately caused by the bundler,\n // it must be a revert caused by paymaster.\n revert FailedOp(opIndex, \"AA95 out of gas\");\n }\n\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n collected = _handlePostOp(\n opIndex,\n IPaymaster.PostOpMode.postOpReverted,\n opInfo,\n context,\n actualGas\n );\n }\n }\n\n /**\n * Execute a batch of UserOperations.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(\n UserOperation[] calldata ops,\n address payable beneficiary\n ) public nonReentrant {\n uint256 opslen = ops.length;\n UserOpInfo[] memory opInfos = new UserOpInfo[](opslen);\n\n unchecked {\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[i];\n (\n uint256 validationData,\n uint256 pmValidationData\n ) = _validatePrepayment(i, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(\n i,\n validationData,\n pmValidationData,\n address(0)\n );\n }\n\n uint256 collected = 0;\n emit BeforeExecution();\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(i, ops[i], opInfos[i]);\n }\n\n _compensate(beneficiary, collected);\n } //unchecked\n }\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) public nonReentrant {\n uint256 opasLen = opsPerAggregator.length;\n uint256 totalOps = 0;\n for (uint256 i = 0; i < opasLen; i++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[i];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n //address(1) is special marker of \"signature error\"\n require(\n address(aggregator) != address(1),\n \"AA96 invalid aggregator\"\n );\n\n if (address(aggregator) != address(0)) {\n // solhint-disable-next-line no-empty-blocks\n try aggregator.validateSignatures(ops, opa.signature) {} catch {\n revert SignatureValidationFailed(address(aggregator));\n }\n }\n\n totalOps += ops.length;\n }\n\n UserOpInfo[] memory opInfos = new UserOpInfo[](totalOps);\n\n emit BeforeExecution();\n\n uint256 opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n uint256 opslen = ops.length;\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[opIndex];\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(opIndex, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(\n i,\n validationData,\n paymasterValidationData,\n address(aggregator)\n );\n opIndex++;\n }\n }\n\n uint256 collected = 0;\n opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n emit SignatureAggregatorChanged(address(opa.aggregator));\n UserOperation[] calldata ops = opa.userOps;\n uint256 opslen = ops.length;\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(opIndex, ops[i], opInfos[opIndex]);\n opIndex++;\n }\n }\n emit SignatureAggregatorChanged(address(0));\n\n _compensate(beneficiary, collected);\n }\n\n /// @inheritdoc IEntryPoint\n function simulateHandleOp(\n UserOperation calldata op,\n address target,\n bytes calldata targetCallData\n ) external override {\n UserOpInfo memory opInfo;\n _simulationOnlyValidations(op);\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(0, op, opInfo);\n ValidationData memory data = _intersectTimeRange(\n validationData,\n paymasterValidationData\n );\n\n numberMarker();\n uint256 paid = _executeUserOp(0, op, opInfo);\n numberMarker();\n bool targetSuccess;\n bytes memory targetResult;\n if (target != address(0)) {\n (targetSuccess, targetResult) = target.call(targetCallData);\n }\n revert ExecutionResult(\n opInfo.preOpGas,\n paid,\n data.validAfter,\n data.validUntil,\n targetSuccess,\n targetResult\n );\n }\n\n // A memory copy of UserOp static fields only.\n // Excluding: callData, initCode and signature. Replacing paymasterAndData with paymaster.\n struct MemoryUserOp {\n address sender;\n uint256 nonce;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n address paymaster;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n }\n\n struct UserOpInfo {\n MemoryUserOp mUserOp;\n bytes32 userOpHash;\n uint256 prefund;\n uint256 contextOffset;\n uint256 preOpGas;\n }\n\n /**\n * inner function to handle a UserOperation.\n * Must be declared \"external\" to open a call context, but it can only be called by handleOps.\n */\n function innerHandleOp(\n bytes memory callData,\n UserOpInfo memory opInfo,\n bytes calldata context\n ) external returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n require(msg.sender == address(this), \"AA92 internal call only\");\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n\n uint callGasLimit = mUserOp.callGasLimit;\n unchecked {\n // handleOps was called with gas limit too low. abort entire bundle.\n if (\n gasleft() < callGasLimit + mUserOp.verificationGasLimit + 5000\n ) {\n assembly {\n mstore(0, INNER_OUT_OF_GAS)\n revert(0, 32)\n }\n }\n }\n\n IPaymaster.PostOpMode mode = IPaymaster.PostOpMode.opSucceeded;\n if (callData.length > 0) {\n bool success = Exec.call(mUserOp.sender, 0, callData, callGasLimit);\n if (!success) {\n bytes memory result = Exec.getReturnData(REVERT_REASON_MAX_LEN);\n if (result.length > 0) {\n emit UserOperationRevertReason(\n opInfo.userOpHash,\n mUserOp.sender,\n mUserOp.nonce,\n result\n );\n }\n mode = IPaymaster.PostOpMode.opReverted;\n }\n }\n\n unchecked {\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n //note: opIndex is ignored (relevant only if mode==postOpReverted, which is only possible outside of innerHandleOp)\n return _handlePostOp(0, mode, opInfo, context, actualGas);\n }\n }\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(\n UserOperation calldata userOp\n ) public view returns (bytes32) {\n return\n keccak256(abi.encode(userOp.hash(), address(this), block.chainid));\n }\n\n /**\n * copy general fields from userOp into the memory opInfo structure.\n */\n function _copyUserOpToMemory(\n UserOperation calldata userOp,\n MemoryUserOp memory mUserOp\n ) internal pure {\n mUserOp.sender = userOp.sender;\n mUserOp.nonce = userOp.nonce;\n mUserOp.callGasLimit = userOp.callGasLimit;\n mUserOp.verificationGasLimit = userOp.verificationGasLimit;\n mUserOp.preVerificationGas = userOp.preVerificationGas;\n mUserOp.maxFeePerGas = userOp.maxFeePerGas;\n mUserOp.maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes calldata paymasterAndData = userOp.paymasterAndData;\n if (paymasterAndData.length > 0) {\n require(\n paymasterAndData.length >= 20,\n \"AA93 invalid paymasterAndData\"\n );\n mUserOp.paymaster = address(bytes20(paymasterAndData[:20]));\n } else {\n mUserOp.paymaster = address(0);\n }\n }\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external {\n UserOpInfo memory outOpInfo;\n\n _simulationOnlyValidations(userOp);\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(0, userOp, outOpInfo);\n StakeInfo memory paymasterInfo = _getStakeInfo(\n outOpInfo.mUserOp.paymaster\n );\n StakeInfo memory senderInfo = _getStakeInfo(outOpInfo.mUserOp.sender);\n StakeInfo memory factoryInfo;\n {\n bytes calldata initCode = userOp.initCode;\n address factory = initCode.length >= 20\n ? address(bytes20(initCode[0:20]))\n : address(0);\n factoryInfo = _getStakeInfo(factory);\n }\n\n ValidationData memory data = _intersectTimeRange(\n validationData,\n paymasterValidationData\n );\n address aggregator = data.aggregator;\n bool sigFailed = aggregator == address(1);\n ReturnInfo memory returnInfo = ReturnInfo(\n outOpInfo.preOpGas,\n outOpInfo.prefund,\n sigFailed,\n data.validAfter,\n data.validUntil,\n getMemoryBytesFromOffset(outOpInfo.contextOffset)\n );\n\n if (aggregator != address(0) && aggregator != address(1)) {\n AggregatorStakeInfo memory aggregatorInfo = AggregatorStakeInfo(\n aggregator,\n _getStakeInfo(aggregator)\n );\n revert ValidationResultWithAggregation(\n returnInfo,\n senderInfo,\n factoryInfo,\n paymasterInfo,\n aggregatorInfo\n );\n }\n revert ValidationResult(\n returnInfo,\n senderInfo,\n factoryInfo,\n paymasterInfo\n );\n }\n\n function _getRequiredPrefund(\n MemoryUserOp memory mUserOp\n ) internal pure returns (uint256 requiredPrefund) {\n unchecked {\n //when using a Paymaster, the verificationGasLimit is used also to as a limit for the postOp call.\n // our security model might call postOp eventually twice\n uint256 mul = mUserOp.paymaster != address(0) ? 3 : 1;\n uint256 requiredGas = mUserOp.callGasLimit +\n mUserOp.verificationGasLimit *\n mul +\n mUserOp.preVerificationGas;\n\n requiredPrefund = requiredGas * mUserOp.maxFeePerGas;\n }\n }\n\n // create the sender's contract if needed.\n function _createSenderIfNeeded(\n uint256 opIndex,\n UserOpInfo memory opInfo,\n bytes calldata initCode\n ) internal {\n if (initCode.length != 0) {\n address sender = opInfo.mUserOp.sender;\n if (sender.code.length != 0)\n revert FailedOp(opIndex, \"AA10 sender already constructed\");\n address sender1 = senderCreator.createSender{\n gas: opInfo.mUserOp.verificationGasLimit\n }(initCode);\n if (sender1 == address(0))\n revert FailedOp(opIndex, \"AA13 initCode failed or OOG\");\n if (sender1 != sender)\n revert FailedOp(opIndex, \"AA14 initCode must return sender\");\n if (sender1.code.length == 0)\n revert FailedOp(opIndex, \"AA15 initCode must create sender\");\n address factory = address(bytes20(initCode[0:20]));\n emit AccountDeployed(\n opInfo.userOpHash,\n sender,\n factory,\n opInfo.mUserOp.paymaster\n );\n }\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes calldata initCode) public {\n address sender = senderCreator.createSender(initCode);\n revert SenderAddressResult(sender);\n }\n\n function _simulationOnlyValidations(\n UserOperation calldata userOp\n ) internal view {\n // solhint-disable-next-line no-empty-blocks\n try\n this._validateSenderAndPaymaster(\n userOp.initCode,\n userOp.sender,\n userOp.paymasterAndData\n )\n {} catch Error(string memory revertReason) {\n if (bytes(revertReason).length != 0) {\n revert FailedOp(0, revertReason);\n }\n }\n }\n\n /**\n * Called only during simulation.\n * This function always reverts to prevent warm/cold storage differentiation in simulation vs execution.\n */\n function _validateSenderAndPaymaster(\n bytes calldata initCode,\n address sender,\n bytes calldata paymasterAndData\n ) external view {\n if (initCode.length == 0 && sender.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA20 account not deployed\");\n }\n if (paymasterAndData.length >= 20) {\n address paymaster = address(bytes20(paymasterAndData[0:20]));\n if (paymaster.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA30 paymaster not deployed\");\n }\n }\n // always revert\n revert(\"\");\n }\n\n /**\n * call account.validateUserOp.\n * revert (with FailedOp) in case validateUserOp reverts, or account didn't send required prefund.\n * decrement account's deposit if needed\n */\n function _validateAccountPrepayment(\n uint256 opIndex,\n UserOperation calldata op,\n UserOpInfo memory opInfo,\n uint256 requiredPrefund\n )\n internal\n returns (\n uint256 gasUsedByValidateAccountPrepayment,\n uint256 validationData\n )\n {\n unchecked {\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n address sender = mUserOp.sender;\n _createSenderIfNeeded(opIndex, opInfo, op.initCode);\n address paymaster = mUserOp.paymaster;\n numberMarker();\n uint256 missingAccountFunds = 0;\n if (paymaster == address(0)) {\n uint256 bal = balanceOf(sender);\n missingAccountFunds = bal > requiredPrefund\n ? 0\n : requiredPrefund - bal;\n }\n try\n IAccount(sender).validateUserOp{\n gas: mUserOp.verificationGasLimit\n }(op, opInfo.userOpHash, missingAccountFunds)\n returns (uint256 _validationData) {\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA23 reverted: \", revertReason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA23 reverted (or OOG)\");\n }\n if (paymaster == address(0)) {\n DepositInfo storage senderInfo = deposits[sender];\n uint256 deposit = senderInfo.deposit;\n if (requiredPrefund > deposit) {\n revert FailedOp(opIndex, \"AA21 didn't pay prefund\");\n }\n senderInfo.deposit = uint112(deposit - requiredPrefund);\n }\n gasUsedByValidateAccountPrepayment = preGas - gasleft();\n }\n }\n\n /**\n * In case the request has a paymaster:\n * Validate paymaster has enough deposit.\n * Call paymaster.validatePaymasterUserOp.\n * Revert with proper FailedOp in case paymaster reverts.\n * Decrement paymaster's deposit\n */\n function _validatePaymasterPrepayment(\n uint256 opIndex,\n UserOperation calldata op,\n UserOpInfo memory opInfo,\n uint256 requiredPreFund,\n uint256 gasUsedByValidateAccountPrepayment\n ) internal returns (bytes memory context, uint256 validationData) {\n unchecked {\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 verificationGasLimit = mUserOp.verificationGasLimit;\n require(\n verificationGasLimit > gasUsedByValidateAccountPrepayment,\n \"AA41 too little verificationGas\"\n );\n uint256 gas = verificationGasLimit -\n gasUsedByValidateAccountPrepayment;\n\n address paymaster = mUserOp.paymaster;\n DepositInfo storage paymasterInfo = deposits[paymaster];\n uint256 deposit = paymasterInfo.deposit;\n if (deposit < requiredPreFund) {\n revert FailedOp(opIndex, \"AA31 paymaster deposit too low\");\n }\n paymasterInfo.deposit = uint112(deposit - requiredPreFund);\n try\n IPaymaster(paymaster).validatePaymasterUserOp{gas: gas}(\n op,\n opInfo.userOpHash,\n requiredPreFund\n )\n returns (bytes memory _context, uint256 _validationData) {\n context = _context;\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA33 reverted: \", revertReason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA33 reverted (or OOG)\");\n }\n }\n }\n\n /**\n * revert if either account validationData or paymaster validationData is expired\n */\n function _validateAccountAndPaymasterValidationData(\n uint256 opIndex,\n uint256 validationData,\n uint256 paymasterValidationData,\n address expectedAggregator\n ) internal view {\n (address aggregator, bool outOfTimeRange) = _getValidationData(\n validationData\n );\n if (expectedAggregator != aggregator) {\n revert FailedOp(opIndex, \"AA24 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA22 expired or not due\");\n }\n //pmAggregator is not a real signature aggregator: we don't have logic to handle it as address.\n // non-zero address means that the paymaster fails due to some signature check (which is ok only during estimation)\n address pmAggregator;\n (pmAggregator, outOfTimeRange) = _getValidationData(\n paymasterValidationData\n );\n if (pmAggregator != address(0)) {\n revert FailedOp(opIndex, \"AA34 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA32 paymaster expired or not due\");\n }\n }\n\n function _getValidationData(\n uint256 validationData\n ) internal view returns (address aggregator, bool outOfTimeRange) {\n if (validationData == 0) {\n return (address(0), false);\n }\n ValidationData memory data = _parseValidationData(validationData);\n // solhint-disable-next-line not-rely-on-time\n outOfTimeRange =\n block.timestamp > data.validUntil ||\n block.timestamp < data.validAfter;\n aggregator = data.aggregator;\n }\n\n /**\n * validate account and paymaster (if defined).\n * also make sure total validation doesn't exceed verificationGasLimit\n * this method is called off-chain (simulateValidation()) and on-chain (from handleOps)\n * @param opIndex the index of this userOp into the \"opInfos\" array\n * @param userOp the userOp to validate\n */\n function _validatePrepayment(\n uint256 opIndex,\n UserOperation calldata userOp,\n UserOpInfo memory outOpInfo\n )\n private\n returns (uint256 validationData, uint256 paymasterValidationData)\n {\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = outOpInfo.mUserOp;\n _copyUserOpToMemory(userOp, mUserOp);\n outOpInfo.userOpHash = getUserOpHash(userOp);\n\n // validate all numeric values in userOp are well below 128 bit, so they can safely be added\n // and multiplied without causing overflow\n uint256 maxGasValues = mUserOp.preVerificationGas |\n mUserOp.verificationGasLimit |\n mUserOp.callGasLimit |\n userOp.maxFeePerGas |\n userOp.maxPriorityFeePerGas;\n require(maxGasValues <= type(uint120).max, \"AA94 gas values overflow\");\n\n uint256 gasUsedByValidateAccountPrepayment;\n uint256 requiredPreFund = _getRequiredPrefund(mUserOp);\n (\n gasUsedByValidateAccountPrepayment,\n validationData\n ) = _validateAccountPrepayment(\n opIndex,\n userOp,\n outOpInfo,\n requiredPreFund\n );\n\n if (!_validateAndUpdateNonce(mUserOp.sender, mUserOp.nonce)) {\n revert FailedOp(opIndex, \"AA25 invalid account nonce\");\n }\n\n //a \"marker\" where account opcode validation is done and paymaster opcode validation is about to start\n // (used only by off-chain simulateValidation)\n numberMarker();\n\n bytes memory context;\n if (mUserOp.paymaster != address(0)) {\n (context, paymasterValidationData) = _validatePaymasterPrepayment(\n opIndex,\n userOp,\n outOpInfo,\n requiredPreFund,\n gasUsedByValidateAccountPrepayment\n );\n }\n unchecked {\n uint256 gasUsed = preGas - gasleft();\n\n if (userOp.verificationGasLimit < gasUsed) {\n revert FailedOp(opIndex, \"AA40 over verificationGasLimit\");\n }\n outOpInfo.prefund = requiredPreFund;\n outOpInfo.contextOffset = getOffsetOfMemoryBytes(context);\n outOpInfo.preOpGas = preGas - gasleft() + userOp.preVerificationGas;\n }\n }\n\n /**\n * process post-operation.\n * called just after the callData is executed.\n * if a paymaster is defined and its validation returned a non-empty context, its postOp is called.\n * the excess amount is refunded to the account (or paymaster - if it was used in the request)\n * @param opIndex index in the batch\n * @param mode - whether is called from innerHandleOp, or outside (postOpReverted)\n * @param opInfo userOp fields and info collected during validation\n * @param context the context returned in validatePaymasterUserOp\n * @param actualGas the gas used so far by this user operation\n */\n function _handlePostOp(\n uint256 opIndex,\n IPaymaster.PostOpMode mode,\n UserOpInfo memory opInfo,\n bytes memory context,\n uint256 actualGas\n ) private returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n unchecked {\n address refundAddress;\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 gasPrice = getUserOpGasPrice(mUserOp);\n\n address paymaster = mUserOp.paymaster;\n if (paymaster == address(0)) {\n refundAddress = mUserOp.sender;\n } else {\n refundAddress = paymaster;\n if (context.length > 0) {\n actualGasCost = actualGas * gasPrice;\n if (mode != IPaymaster.PostOpMode.postOpReverted) {\n IPaymaster(paymaster).postOp{\n gas: mUserOp.verificationGasLimit\n }(mode, context, actualGasCost);\n } else {\n // solhint-disable-next-line no-empty-blocks\n try\n IPaymaster(paymaster).postOp{\n gas: mUserOp.verificationGasLimit\n }(mode, context, actualGasCost)\n {} catch Error(string memory reason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA50 postOp reverted: \", reason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA50 postOp revert\");\n }\n }\n }\n }\n actualGas += preGas - gasleft();\n actualGasCost = actualGas * gasPrice;\n if (opInfo.prefund < actualGasCost) {\n revert FailedOp(opIndex, \"AA51 prefund below actualGasCost\");\n }\n uint256 refund = opInfo.prefund - actualGasCost;\n _incrementDeposit(refundAddress, refund);\n bool success = mode == IPaymaster.PostOpMode.opSucceeded;\n emit UserOperationEvent(\n opInfo.userOpHash,\n mUserOp.sender,\n mUserOp.paymaster,\n mUserOp.nonce,\n success,\n actualGasCost,\n actualGas\n );\n } // unchecked\n }\n\n /**\n * the gas price this UserOp agrees to pay.\n * relayer/block builder might submit the TX with higher priorityFee, but the user should not\n */\n function getUserOpGasPrice(\n MemoryUserOp memory mUserOp\n ) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = mUserOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = mUserOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n function getOffsetOfMemoryBytes(\n bytes memory data\n ) internal pure returns (uint256 offset) {\n assembly {\n offset := data\n }\n }\n\n function getMemoryBytesFromOffset(\n uint256 offset\n ) internal pure returns (bytes memory data) {\n assembly {\n data := offset\n }\n }\n\n //place the NUMBER opcode in the code.\n // this is used as a marker during simulation, as this OP is completely banned from the simulated code of the\n // account and paymaster.\n function numberMarker() internal view {\n assembly {\n mstore(0, number())\n }\n }\n}\n" + }, + "contracts/aa-4337/core/Helpers.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable no-inline-assembly */\n\n/**\n * returned data from validateUserOp.\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\n * @param aggregator - address(0) - the account validated the signature by itself.\n * address(1) - the account failed to validate the signature.\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\n * @param validAfter - this UserOp is valid only after this timestamp.\n * @param validaUntil - this UserOp is valid only up to this timestamp.\n */\nstruct ValidationData {\n address aggregator;\n uint48 validAfter;\n uint48 validUntil;\n}\n\n//extract sigFailed, validAfter, validUntil.\n// also convert zero validUntil to type(uint48).max\nfunction _parseValidationData(\n uint validationData\n) pure returns (ValidationData memory data) {\n address aggregator = address(uint160(validationData));\n uint48 validUntil = uint48(validationData >> 160);\n if (validUntil == 0) {\n validUntil = type(uint48).max;\n }\n uint48 validAfter = uint48(validationData >> (48 + 160));\n return ValidationData(aggregator, validAfter, validUntil);\n}\n\n// intersect account and paymaster ranges.\nfunction _intersectTimeRange(\n uint256 validationData,\n uint256 paymasterValidationData\n) pure returns (ValidationData memory) {\n ValidationData memory accountValidationData = _parseValidationData(\n validationData\n );\n ValidationData memory pmValidationData = _parseValidationData(\n paymasterValidationData\n );\n address aggregator = accountValidationData.aggregator;\n if (aggregator == address(0)) {\n aggregator = pmValidationData.aggregator;\n }\n uint48 validAfter = accountValidationData.validAfter;\n uint48 validUntil = accountValidationData.validUntil;\n uint48 pmValidAfter = pmValidationData.validAfter;\n uint48 pmValidUntil = pmValidationData.validUntil;\n\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\n return ValidationData(aggregator, validAfter, validUntil);\n}\n\n/**\n * helper to pack the return value for validateUserOp\n * @param data - the ValidationData to pack\n */\nfunction _packValidationData(\n ValidationData memory data\n) pure returns (uint256) {\n return\n uint160(data.aggregator) |\n (uint256(data.validUntil) << 160) |\n (uint256(data.validAfter) << (160 + 48));\n}\n\n/**\n * helper to pack the return value for validateUserOp, when not using an aggregator\n * @param sigFailed - true for signature failure, false for success\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\n * @param validAfter first timestamp this UserOperation is valid\n */\nfunction _packValidationData(\n bool sigFailed,\n uint48 validUntil,\n uint48 validAfter\n) pure returns (uint256) {\n return\n (sigFailed ? 1 : 0) |\n (uint256(validUntil) << 160) |\n (uint256(validAfter) << (160 + 48));\n}\n\n/**\n * keccak function over calldata.\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\n */\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\n assembly {\n let mem := mload(0x40)\n let len := data.length\n calldatacopy(mem, data.offset, len)\n ret := keccak256(mem, len)\n }\n}\n" + }, + "contracts/aa-4337/core/NonceManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\nimport \"../interfaces/IEntryPoint.sol\";\n\n/**\n * nonce management functionality\n */\ncontract NonceManager is INonceManager {\n /**\n * The next valid sequence number for a given nonce key.\n */\n mapping(address => mapping(uint192 => uint256)) public nonceSequenceNumber;\n\n function getNonce(\n address sender,\n uint192 key\n ) public view override returns (uint256 nonce) {\n return nonceSequenceNumber[sender][key] | (uint256(key) << 64);\n }\n\n // allow an account to manually increment its own nonce.\n // (mainly so that during construction nonce can be made non-zero,\n // to \"absorb\" the gas cost of first nonce increment to 1st transaction (construction),\n // not to 2nd transaction)\n function incrementNonce(uint192 key) public override {\n nonceSequenceNumber[msg.sender][key]++;\n }\n\n /**\n * validate nonce uniqueness for this account.\n * called just after validateUserOp()\n */\n function _validateAndUpdateNonce(\n address sender,\n uint256 nonce\n ) internal returns (bool) {\n uint192 key = uint192(nonce >> 64);\n uint64 seq = uint64(nonce);\n return nonceSequenceNumber[sender][key]++ == seq;\n }\n}\n" + }, + "contracts/aa-4337/core/SenderCreator.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/**\n * helper contract for EntryPoint, to call userOp.initCode from a \"neutral\" address,\n * which is explicitly not the entryPoint itself.\n */\ncontract SenderCreator {\n /**\n * call the \"initCode\" factory to create and return the sender account address\n * @param initCode the initCode value from a UserOp. contains 20 bytes of factory address, followed by calldata\n * @return sender the returned address of the created account, or zero address on failure.\n */\n function createSender(\n bytes calldata initCode\n ) external returns (address sender) {\n address factory = address(bytes20(initCode[0:20]));\n bytes memory initCallData = initCode[20:];\n bool success;\n /* solhint-disable no-inline-assembly */\n assembly {\n success := call(\n gas(),\n factory,\n 0,\n add(initCallData, 0x20),\n mload(initCallData),\n 0,\n 32\n )\n sender := mload(0)\n }\n if (!success) {\n sender = address(0);\n }\n }\n}\n" + }, + "contracts/aa-4337/core/StakeManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity 0.8.21;\n\nimport \"../interfaces/IStakeManager.sol\";\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable not-rely-on-time */\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by a paymaster.\n */\nabstract contract StakeManager is IStakeManager {\n /// maps paymaster to their deposits and stakes\n mapping(address => DepositInfo) public deposits;\n\n /// @inheritdoc IStakeManager\n function getDepositInfo(\n address account\n ) public view returns (DepositInfo memory info) {\n return deposits[account];\n }\n\n // internal method to return just the stake info\n function _getStakeInfo(\n address addr\n ) internal view returns (StakeInfo memory info) {\n DepositInfo storage depositInfo = deposits[addr];\n info.stake = depositInfo.stake;\n info.unstakeDelaySec = depositInfo.unstakeDelaySec;\n }\n\n /// return the deposit (for gas payment) of the account\n function balanceOf(address account) public view returns (uint256) {\n return deposits[account].deposit;\n }\n\n receive() external payable {\n depositTo(msg.sender);\n }\n\n function _incrementDeposit(address account, uint256 amount) internal {\n DepositInfo storage info = deposits[account];\n uint256 newAmount = info.deposit + amount;\n require(newAmount <= type(uint112).max, \"deposit overflow\");\n info.deposit = uint112(newAmount);\n }\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) public payable {\n _incrementDeposit(account, msg.value);\n DepositInfo storage info = deposits[account];\n emit Deposited(account, info.deposit);\n }\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 unstakeDelaySec) public payable {\n DepositInfo storage info = deposits[msg.sender];\n require(unstakeDelaySec > 0, \"must specify unstake delay\");\n require(\n unstakeDelaySec >= info.unstakeDelaySec,\n \"cannot decrease unstake time\"\n );\n uint256 stake = info.stake + msg.value;\n require(stake > 0, \"no stake specified\");\n require(stake <= type(uint112).max, \"stake overflow\");\n deposits[msg.sender] = DepositInfo(\n info.deposit,\n true,\n uint112(stake),\n unstakeDelaySec,\n 0\n );\n emit StakeLocked(msg.sender, stake, unstakeDelaySec);\n }\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external {\n DepositInfo storage info = deposits[msg.sender];\n require(info.unstakeDelaySec != 0, \"not staked\");\n require(info.staked, \"already unstaking\");\n uint48 withdrawTime = uint48(block.timestamp) + info.unstakeDelaySec;\n info.withdrawTime = withdrawTime;\n info.staked = false;\n emit StakeUnlocked(msg.sender, withdrawTime);\n }\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external {\n DepositInfo storage info = deposits[msg.sender];\n uint256 stake = info.stake;\n require(stake > 0, \"No stake to withdraw\");\n require(info.withdrawTime > 0, \"must call unlockStake() first\");\n require(\n info.withdrawTime <= block.timestamp,\n \"Stake withdrawal is not due\"\n );\n info.unstakeDelaySec = 0;\n info.withdrawTime = 0;\n info.stake = 0;\n emit StakeWithdrawn(msg.sender, withdrawAddress, stake);\n (bool success, ) = withdrawAddress.call{value: stake}(\"\");\n require(success, \"failed to withdraw stake\");\n }\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(\n address payable withdrawAddress,\n uint256 withdrawAmount\n ) external {\n DepositInfo storage info = deposits[msg.sender];\n require(withdrawAmount <= info.deposit, \"Withdraw amount too large\");\n info.deposit = uint112(info.deposit - withdrawAmount);\n emit Withdrawn(msg.sender, withdrawAddress, withdrawAmount);\n (bool success, ) = withdrawAddress.call{value: withdrawAmount}(\"\");\n require(success, \"failed to withdraw\");\n }\n}\n" + }, + "contracts/aa-4337/interfaces/IAccount.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\ninterface IAccount {\n /**\n * Validate user's signature and nonce\n * the entryPoint will make the call to the recipient only if this validation call returns successfully.\n * signature failure should be reported by returning SIG_VALIDATION_FAILED (1).\n * This allows making a \"simulation call\" without a valid signature\n * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure.\n *\n * @dev Must validate caller is the entryPoint.\n * Must validate the signature and nonce\n * @param userOp the operation that is about to be executed.\n * @param userOpHash hash of the user's request data. can be used as the basis for signature.\n * @param missingAccountFunds missing funds on the account's deposit in the entrypoint.\n * This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call.\n * The excess is left as a deposit in the entrypoint, for future calls.\n * can be withdrawn anytime using \"entryPoint.withdrawTo()\"\n * In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero.\n * @return validationData packaged ValidationData structure. use `_packValidationData` and `_unpackValidationData` to encode and decode\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * If an account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validateUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 missingAccountFunds\n ) external returns (uint256 validationData);\n}\n" + }, + "contracts/aa-4337/interfaces/IAggregator.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * Aggregated Signatures validator.\n */\ninterface IAggregator {\n /**\n * validate aggregated signature.\n * revert if the aggregated signature does not match the given list of operations.\n */\n function validateSignatures(\n UserOperation[] calldata userOps,\n bytes calldata signature\n ) external view;\n\n /**\n * validate signature of a single userOp\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\n * @param userOp the userOperation received from the user.\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\n * (usually empty, unless account and aggregator support some kind of \"multisig\"\n */\n function validateUserOpSignature(\n UserOperation calldata userOp\n ) external view returns (bytes memory sigForUserOp);\n\n /**\n * aggregate multiple signatures into a single value.\n * This method is called off-chain to calculate the signature to pass with handleOps()\n * bundler MAY use optimized custom code perform this aggregation\n * @param userOps array of UserOperations to collect the signatures from.\n * @return aggregatedSignature the aggregated signature\n */\n function aggregateSignatures(\n UserOperation[] calldata userOps\n ) external view returns (bytes memory aggregatedSignature);\n}\n" + }, + "contracts/aa-4337/interfaces/IEntryPoint.sol": { + "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n/* solhint-disable reason-string */\n\nimport \"./UserOperation.sol\";\nimport \"./IStakeManager.sol\";\nimport \"./IAggregator.sol\";\nimport \"./INonceManager.sol\";\n\ninterface IEntryPoint is IStakeManager, INonceManager {\n /***\n * An event emitted after each successful request\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\n * @param sender - the account that generates this request.\n * @param paymaster - if non-null, the paymaster that pays for this request.\n * @param nonce - the nonce value from the request.\n * @param success - true if the sender transaction succeeded, false if reverted.\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\n */\n event UserOperationEvent(\n bytes32 indexed userOpHash,\n address indexed sender,\n address indexed paymaster,\n uint256 nonce,\n bool success,\n uint256 actualGasCost,\n uint256 actualGasUsed\n );\n\n /**\n * account \"sender\" was deployed.\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\n * @param sender the account that is deployed\n * @param factory the factory used to deploy this account (in the initCode)\n * @param paymaster the paymaster used by this UserOp\n */\n event AccountDeployed(\n bytes32 indexed userOpHash,\n address indexed sender,\n address factory,\n address paymaster\n );\n\n /**\n * An event emitted if the UserOperation \"callData\" reverted with non-zero length\n * @param userOpHash the request unique identifier.\n * @param sender the sender of this request\n * @param nonce the nonce used in the request\n * @param revertReason - the return bytes from the (reverted) call to \"callData\".\n */\n event UserOperationRevertReason(\n bytes32 indexed userOpHash,\n address indexed sender,\n uint256 nonce,\n bytes revertReason\n );\n\n /**\n * an event emitted by handleOps(), before starting the execution loop.\n * any event emitted before this event, is part of the validation.\n */\n event BeforeExecution();\n\n /**\n * signature aggregator used by the following UserOperationEvents within this bundle.\n */\n event SignatureAggregatorChanged(address indexed aggregator);\n\n /**\n * a custom revert error of handleOps, to identify the offending op.\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\n * @param reason - revert reason\n * The string starts with a unique code \"AAmn\", where \"m\" is \"1\" for factory, \"2\" for account and \"3\" for paymaster issues,\n * so a failure can be attributed to the correct entity.\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\n */\n error FailedOp(uint256 opIndex, string reason);\n\n /**\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\n */\n error SignatureValidationFailed(address aggregator);\n\n /**\n * Successful result from simulateValidation.\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n */\n error ValidationResult(\n ReturnInfo returnInfo,\n StakeInfo senderInfo,\n StakeInfo factoryInfo,\n StakeInfo paymasterInfo\n );\n\n /**\n * Successful result from simulateValidation, if the account returns a signature aggregator\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\n * bundler MUST use it to verify the signature, or reject the UserOperation\n */\n error ValidationResultWithAggregation(\n ReturnInfo returnInfo,\n StakeInfo senderInfo,\n StakeInfo factoryInfo,\n StakeInfo paymasterInfo,\n AggregatorStakeInfo aggregatorInfo\n );\n\n /**\n * return value of getSenderAddress\n */\n error SenderAddressResult(address sender);\n\n /**\n * return value of simulateHandleOp\n */\n error ExecutionResult(\n uint256 preOpGas,\n uint256 paid,\n uint48 validAfter,\n uint48 validUntil,\n bool targetSuccess,\n bytes targetResult\n );\n\n //UserOps handled, per aggregator\n struct UserOpsPerAggregator {\n UserOperation[] userOps;\n // aggregator address\n IAggregator aggregator;\n // aggregated signature\n bytes signature;\n }\n\n /**\n * Execute a batch of UserOperation.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(\n UserOperation[] calldata ops,\n address payable beneficiary\n ) external;\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) external;\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(\n UserOperation calldata userOp\n ) external view returns (bytes32);\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external;\n\n /**\n * gas and return values during simulation\n * @param preOpGas the gas used for validation (including preValidationGas)\n * @param prefund the required prefund for this operation\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\n */\n struct ReturnInfo {\n uint256 preOpGas;\n uint256 prefund;\n bool sigFailed;\n uint48 validAfter;\n uint48 validUntil;\n bytes paymasterContext;\n }\n\n /**\n * returned aggregated signature info.\n * the aggregator returned by the account, and its current stake.\n */\n struct AggregatorStakeInfo {\n address aggregator;\n StakeInfo stakeInfo;\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes memory initCode) external;\n\n /**\n * simulate full execution of a UserOperation (including both validation and target execution)\n * this method will always revert with \"ExecutionResult\".\n * it performs full validation of the UserOperation, but ignores signature error.\n * an optional target address is called after the userop succeeds, and its value is returned\n * (before the entire call is reverted)\n * Note that in order to collect the the success/failure of the target call, it must be executed\n * with trace enabled to track the emitted events.\n * @param op the UserOperation to simulate\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\n * are set to the return from that call.\n * @param targetCallData callData to pass to target address\n */\n function simulateHandleOp(\n UserOperation calldata op,\n address target,\n bytes calldata targetCallData\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/INonceManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\ninterface INonceManager {\n /**\n * Return the next nonce for this sender.\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\n * But UserOp with different keys can come with arbitrary order.\n *\n * @param sender the account address\n * @param key the high 192 bit of the nonce\n * @return nonce a full nonce to pass for next UserOp with this sender.\n */\n function getNonce(\n address sender,\n uint192 key\n ) external view returns (uint256 nonce);\n\n /**\n * Manually increment the nonce of the sender.\n * This method is exposed just for completeness..\n * Account does NOT need to call it, neither during validation, nor elsewhere,\n * as the EntryPoint will update the nonce regardless.\n * Possible use-case is call it with various keys to \"initialize\" their nonces to one, so that future\n * UserOperations will not pay extra for the first transaction with a given key.\n */\n function incrementNonce(uint192 key) external;\n}\n" + }, + "contracts/aa-4337/interfaces/IPaymaster.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * the interface exposed by a paymaster contract, who agrees to pay the gas for user's operations.\n * a paymaster must hold a stake to cover the required entrypoint stake and also the gas for the transaction.\n */\ninterface IPaymaster {\n enum PostOpMode {\n opSucceeded, // user op succeeded\n opReverted, // user op reverted. still has to pay for gas.\n postOpReverted //user op succeeded, but caused postOp to revert. Now it's a 2nd call, after user's op was deliberately reverted.\n }\n\n /**\n * payment validation: check if paymaster agrees to pay.\n * Must verify sender is the entryPoint.\n * Revert to reject this request.\n * Note that bundlers will reject this method if it changes the state, unless the paymaster is trusted (whitelisted)\n * The paymaster pre-pays using its deposit, and receive back a refund after the postOp method returns.\n * @param userOp the user operation\n * @param userOpHash hash of the user's request data.\n * @param maxCost the maximum cost of this transaction (based on maximum gas and gas price from userOp)\n * @return context value to send to a postOp\n * zero length to signify postOp is not required.\n * @return validationData signature and time-range of this operation, encoded the same as the return value of validateUserOperation\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validatePaymasterUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 maxCost\n ) external returns (bytes memory context, uint256 validationData);\n\n /**\n * post-operation handler.\n * Must verify sender is the entryPoint\n * @param mode enum with the following options:\n * opSucceeded - user operation succeeded.\n * opReverted - user op reverted. still has to pay for gas.\n * postOpReverted - user op succeeded, but caused postOp (in mode=opSucceeded) to revert.\n * Now this is the 2nd call, after user's op was deliberately reverted.\n * @param context - the context value returned by validatePaymasterUserOp\n * @param actualGasCost - actual gas used so far (without this postOp call).\n */\n function postOp(\n PostOpMode mode,\n bytes calldata context,\n uint256 actualGasCost\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/IStakeManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.12;\n\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by the staked entity.\n */\ninterface IStakeManager {\n event Deposited(address indexed account, uint256 totalDeposit);\n\n event Withdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /// Emitted when stake or unstake delay are modified\n event StakeLocked(\n address indexed account,\n uint256 totalStaked,\n uint256 unstakeDelaySec\n );\n\n /// Emitted once a stake is scheduled for withdrawal\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\n\n event StakeWithdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /**\n * @param deposit the entity's deposit\n * @param staked true if this entity is staked.\n * @param stake actual amount of ether staked for this entity.\n * @param unstakeDelaySec minimum delay to withdraw the stake.\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\n * and the rest fit into a 2nd cell.\n * 112 bit allows for 10^15 eth\n * 48 bit for full timestamp\n * 32 bit allows 150 years for unstake delay\n */\n struct DepositInfo {\n uint112 deposit;\n bool staked;\n uint112 stake;\n uint32 unstakeDelaySec;\n uint48 withdrawTime;\n }\n\n //API struct used by getStakeInfo and simulateValidation\n struct StakeInfo {\n uint256 stake;\n uint256 unstakeDelaySec;\n }\n\n /// @return info - full deposit information of given account\n function getDepositInfo(\n address account\n ) external view returns (DepositInfo memory info);\n\n /// @return the deposit (for gas payment) of the account\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) external payable;\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 _unstakeDelaySec) external payable;\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external;\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external;\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(\n address payable withdrawAddress,\n uint256 withdrawAmount\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/UserOperation.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable no-inline-assembly */\n\nimport {calldataKeccak} from \"../core/Helpers.sol\";\n\n/**\n * User Operation struct\n * @param sender the sender account of this request.\n * @param nonce unique value the sender uses to verify it is not a replay.\n * @param initCode if set, the account contract will be created by this constructor/\n * @param callData the method call to execute on this account.\n * @param callGasLimit the gas limit passed to the callData method call.\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\n * @param maxFeePerGas same as EIP-1559 gas parameter.\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\n */\nstruct UserOperation {\n address sender;\n uint256 nonce;\n bytes initCode;\n bytes callData;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n bytes paymasterAndData;\n bytes signature;\n}\n\n/**\n * Utility functions helpful when working with UserOperation structs.\n */\nlibrary UserOperationLib {\n function getSender(\n UserOperation calldata userOp\n ) internal pure returns (address) {\n address data;\n //read sender from userOp, which is first userOp member (saves 800 gas...)\n assembly {\n data := calldataload(userOp)\n }\n return address(uint160(data));\n }\n\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\n // pay above what he signed for.\n function gasPrice(\n UserOperation calldata userOp\n ) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function pack(\n UserOperation calldata userOp\n ) internal pure returns (bytes memory ret) {\n address sender = getSender(userOp);\n uint256 nonce = userOp.nonce;\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\n bytes32 hashCallData = calldataKeccak(userOp.callData);\n uint256 callGasLimit = userOp.callGasLimit;\n uint256 verificationGasLimit = userOp.verificationGasLimit;\n uint256 preVerificationGas = userOp.preVerificationGas;\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\n\n return\n abi.encode(\n sender,\n nonce,\n hashInitCode,\n hashCallData,\n callGasLimit,\n verificationGasLimit,\n preVerificationGas,\n maxFeePerGas,\n maxPriorityFeePerGas,\n hashPaymasterAndData\n );\n }\n\n function hash(\n UserOperation calldata userOp\n ) internal pure returns (bytes32) {\n return keccak256(pack(userOp));\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n}\n" + }, + "contracts/aa-4337/utils/Exec.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.5 <0.9.0;\n\n// solhint-disable no-inline-assembly\n\n/**\n * Utility functions helpful when making different kinds of contract calls in Solidity.\n */\nlibrary Exec {\n function call(\n address to,\n uint256 value,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := call(\n txGas,\n to,\n value,\n add(data, 0x20),\n mload(data),\n 0,\n 0\n )\n }\n }\n\n function staticcall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal view returns (bool success) {\n assembly {\n success := staticcall(txGas, to, add(data, 0x20), mload(data), 0, 0)\n }\n }\n\n function delegateCall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := delegatecall(\n txGas,\n to,\n add(data, 0x20),\n mload(data),\n 0,\n 0\n )\n }\n }\n\n // get returned data from last call or calldelegate\n function getReturnData(\n uint256 maxLen\n ) internal pure returns (bytes memory returnData) {\n assembly {\n let len := returndatasize()\n if gt(len, maxLen) {\n len := maxLen\n }\n let ptr := mload(0x40)\n mstore(0x40, add(ptr, add(len, 0x20)))\n mstore(ptr, len)\n returndatacopy(add(ptr, 0x20), 0, len)\n returnData := ptr\n }\n }\n\n // revert with explicit byte array (probably reverted info from call)\n function revertWithData(bytes memory returnData) internal pure {\n assembly {\n revert(add(returnData, 32), mload(returnData))\n }\n }\n\n function callAndRevert(\n address to,\n bytes memory data,\n uint256 maxLen\n ) internal {\n bool success = call(to, 0, data, gasleft());\n if (!success) {\n revertWithData(getReturnData(maxLen));\n }\n }\n}\n" + }, + "contracts/Barz.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"./libraries/LibDiamond.sol\";\nimport {IBarz} from \"./interfaces/IBarz.sol\";\n\n/**\n * @title Barz\n * @dev A diamond proxy wallet with a modular & upgradeable architecture\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract Barz is IBarz {\n /**\n * @notice Initializes Barz with the given parameters. Barz account is intended to be created from Barz Factory for stable deployment.\n * @dev This method makes a delegate call to account facet and account facet handles the initialization.\n * With modular architecture, Barz encompasses wide spectrum of architecture and logic.\n * The only requirement is account facet to comply with initialize() interface.\n * Barz doesn't include built-in functions and is a full proxy, for maximum extensibility and modularity.\n * @param _accountFacet Address of Account Facet in charge of the Barz initialization\n * @param _verificationFacet Address of Verification Facet for verifying the signature. Could be any signature scheme\n * @param _entryPoint Address of Entry Point contract\n * @param _facetRegistry Address of Facet Registry. Facet Registry is a registry holding trusted facets that could be added to user's wallet\n * @param _defaultFallBack Address of Default FallBack Handler. Middleware contract for more efficient deployment\n * @param _ownerPublicKey Bytes of Owner Public Key using for initialization\n */\n constructor(\n address _accountFacet,\n address _verificationFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallBack,\n bytes memory _ownerPublicKey\n ) payable {\n bytes memory initCall = abi.encodeWithSignature(\n \"initialize(address,address,address,address,bytes)\",\n _verificationFacet,\n _entryPoint,\n _facetRegistry,\n _defaultFallBack,\n _ownerPublicKey\n );\n (bool success, bytes memory result) = _accountFacet.delegatecall(\n initCall\n );\n if (!success || uint256(bytes32(result)) != 1) {\n revert Barz__InitializationFailure();\n }\n }\n\n /**\n * @notice Fallback function for Barz complying with Diamond Standard with customization of adding Default Fallback Handler\n * @dev Find facet for function that is called and execute the function if a facet is found and return any value.\n */\n fallback() external payable {\n LibDiamond.DiamondStorage storage ds;\n bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION;\n // get diamond storage\n assembly {\n ds.slot := position\n }\n // get facet from function selector\n address facet = address(bytes20(ds.facets[msg.sig]));\n if (facet == address(0))\n facet = ds.defaultFallbackHandler.facetAddress(msg.sig);\n require(facet != address(0), \"Barz: Function does not exist\");\n // Execute external function from facet using delegatecall and return any value.\n assembly {\n // copy function selector and any arguments\n calldatacopy(0, 0, calldatasize())\n // execute function call using the facet\n let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)\n // get any return value\n returndatacopy(0, 0, returndatasize())\n // return any return value or error back to the caller\n switch result\n case 0 {\n revert(0, returndatasize())\n }\n default {\n return(0, returndatasize())\n }\n }\n }\n\n /**\n * @notice Receive function to receive native token without data\n */\n receive() external payable {}\n}\n" + }, + "contracts/BarzFactory.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Barz} from \"./Barz.sol\";\nimport {IBarzFactory} from \"./interfaces/IBarzFactory.sol\";\n\n/**\n * @title Barz Factory\n * @dev Contract to easily deploy Barz to a pre-computed address with a single call\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract BarzFactory is IBarzFactory {\n event BarzDeployed(address);\n\n address public immutable accountFacet;\n address public immutable entryPoint;\n address public immutable facetRegistry;\n address public immutable defaultFallback;\n\n /**\n * @notice Sets the initialization data for Barz contract initialization\n * @param _accountFacet Account Facet to be used to create Barz\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\n * @param _facetRegistry Facet Registry to be used to create Barz\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\n */\n constructor(\n address _accountFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallback\n ) {\n accountFacet = _accountFacet;\n entryPoint = _entryPoint;\n facetRegistry = _facetRegistry;\n defaultFallback = _defaultFallback;\n }\n\n /**\n * @notice Creates the Barz with a single call. It creates the Barz contract with the givent verification facet\n * @param _verificationFacet Address of verification facet used for creating the barz account\n * @param _owner Public Key of the owner to initialize barz account\n * @param _salt Salt used for deploying barz with create2\n * @return barz Instance of Barz contract deployed with the given parameters\n */\n function createAccount(\n address _verificationFacet,\n bytes calldata _owner,\n uint256 _salt\n ) external override returns (Barz barz) {\n address addr = getAddress(_verificationFacet, _owner, _salt);\n uint codeSize = addr.code.length;\n if (codeSize > 0) {\n return Barz(payable(addr));\n }\n barz = new Barz{salt: bytes32(_salt)}(\n accountFacet,\n _verificationFacet,\n entryPoint,\n facetRegistry,\n defaultFallback,\n _owner\n );\n emit BarzDeployed(address(barz));\n }\n\n /**\n * @notice Calculates the address of Barz with the given parameters\n * @param _verificationFacet Address of verification facet used for creating the barz account\n * @param _owner Public Key of the owner to initialize barz account\n * @param _salt Salt used for deploying barz with create2\n * @return barzAddress Precalculated Barz address\n */\n function getAddress(\n address _verificationFacet,\n bytes calldata _owner,\n uint256 _salt\n ) public view override returns (address barzAddress) {\n bytes memory bytecode = getBytecode(\n accountFacet,\n _verificationFacet,\n entryPoint,\n facetRegistry,\n defaultFallback,\n _owner\n );\n bytes32 hash = keccak256(\n abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(bytecode)\n )\n );\n barzAddress = address(uint160(uint256(hash)));\n }\n\n /**\n * @notice Returns the bytecode of Barz with the given parameter\n * @param _accountFacet Account Facet to be used to create Barz\n * @param _verificationFacet Verification Facet to be used to create Barz\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\n * @param _facetRegistry Facet Registry to be used to create Barz\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\n * @param _ownerPublicKey Public Key of owner to be used to initialize Barz ownership\n * @return barzBytecode Bytecode of Barz\n */\n function getBytecode(\n address _accountFacet,\n address _verificationFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallback,\n bytes calldata _ownerPublicKey\n ) public pure override returns (bytes memory barzBytecode) {\n bytes memory bytecode = type(Barz).creationCode;\n barzBytecode = abi.encodePacked(\n bytecode,\n abi.encode(\n _accountFacet,\n _verificationFacet,\n _entryPoint,\n _facetRegistry,\n _defaultFallback,\n _ownerPublicKey\n )\n );\n }\n\n /**\n * @notice Returns the creation code of the Barz contract\n * @return creationCode Creation code of Barz\n */\n function getCreationCode()\n public\n pure\n override\n returns (bytes memory creationCode)\n {\n creationCode = type(Barz).creationCode;\n }\n}\n" + }, + "contracts/facets/AccountFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {UserOperation} from \"../aa-4337/interfaces/UserOperation.sol\";\nimport {IEntryPoint} from \"../aa-4337/interfaces/IEntryPoint.sol\";\nimport {BaseAccount} from \"../aa-4337/core/BaseAccount.sol\";\nimport {LibAppStorage, BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {IFacetRegistry} from \"../infrastructure/interfaces/IFacetRegistry.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {IERC1271} from \"../interfaces/ERC/IERC1271.sol\";\nimport {IAccountFacet} from \"./interfaces/IAccountFacet.sol\";\n\n/**\n * @title Account Facet\n * @dev Account module contract that provides the account features and initialization of signer\n * compatible with EIP-1271 & EIP-4337\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract AccountFacet is BarzStorage, BaseAccount, IAccountFacet {\n using ECDSA for bytes32;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceAccountInitialize();\n }\n\n /**\n * @notice Returns the address of EntryPoint contract registered to Barz account\n */\n function entryPoint() public view override returns (IEntryPoint) {\n return s.entryPoint;\n }\n\n /**\n * @notice Initializes the initial storage of the Barz contract.\n * @dev This method can only be called during the initialization or signature migration.\n * If the proxy contract was created without initialization, anyone can call initialize.\n * Barz calls initialize in constructor in an atomic transaction during deployment\n * @param _verificationFacet Facet contract handling the verificationi\n * @param _anEntryPoint Entrypoint contract defined in EIP-4337 handling the flow of UserOp\n * @param _facetRegistry Registry of Facets that hold all facet information\n * @param _defaultFallBackHandler Middleware contract for default facets\n * @param _ownerPublicKey Bytes of owner public key\n */\n function initialize(\n address _verificationFacet,\n address _anEntryPoint,\n address _facetRegistry,\n address _defaultFallBackHandler,\n bytes calldata _ownerPublicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceAccountInitialize();\n s.entryPoint = IEntryPoint(_anEntryPoint);\n s.facetRegistry = IFacetRegistry(_facetRegistry);\n LibDiamond.diamondStorage().defaultFallbackHandler = IDiamondLoupe(\n _defaultFallBackHandler\n );\n\n _cutDiamondAccountFacet(_verificationFacet);\n\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n _ownerPublicKey\n );\n // Every Verification Facet should comply with initializeSigner(bytes)\n // to be compatible with the Barz contract(for initialization)\n (bool success, bytes memory result) = _verificationFacet.delegatecall(\n initCall\n );\n if (!success || uint256(bytes32(result)) != 1) {\n revert AccountFacet__InitializationFailure();\n }\n\n initSuccess = 1;\n emit AccountInitialized(s.entryPoint, _ownerPublicKey);\n }\n\n function _cutDiamondAccountFacet(address _verificationFacet) internal {\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](1);\n\n bytes4 ownerVerificationFuncSelector = IVerificationFacet(\n _verificationFacet\n ).validateOwnerSignatureSelector();\n\n bytes4[] memory verificationFunctionSelectors = new bytes4[](3);\n verificationFunctionSelectors[0] = IERC1271.isValidSignature.selector;\n verificationFunctionSelectors[1] = ownerVerificationFuncSelector;\n verificationFunctionSelectors[2] = IVerificationFacet.owner.selector;\n cut[0] = IDiamondCut.FacetCut({\n facetAddress: _verificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: verificationFunctionSelectors\n });\n\n LibDiamond.diamondCut(cut, address(0), \"\");\n }\n\n /**\n * @notice Calls the destination with inputted calldata and value from EntryPoint\n * @dev This method executes the calldata coming from the EntryPoint.\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\n * @param _dest Address of destination where the call will be forwarded to\n * @param _value Amount of native coin the owner is willing to send(e.g. ETH, BNB)\n * @param _func Bytes of calldata to execute in the destination address\n */\n function execute(\n address _dest,\n uint256 _value,\n bytes calldata _func\n ) external override onlyWhenUnlocked {\n _requireFromEntryPoint();\n _call(_dest, _value, _func);\n }\n\n /**\n * @notice Batch calls the destination with inputted calldata and value from EntryPoint\n * @dev This method batch executes the calldata coming from the EntryPoint.\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\n * @param _dest Array of addresses of destination where the call will be forwarded to\n * @param _value Array of amount of native coin the owner is willing to send(e.g. ETH, BNB)\n * @param _func Array of bytes of calldata to execute in the destination address\n */\n function executeBatch(\n address[] calldata _dest,\n uint256[] calldata _value,\n bytes[] calldata _func\n ) external override onlyWhenUnlocked {\n _requireFromEntryPoint();\n uint256 destLength = _dest.length;\n require(\n destLength == _func.length && destLength == _value.length,\n \"wrong array lengths\"\n );\n for (uint256 i; i < destLength; ) {\n _call(_dest[i], _value[i], _func[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Validates the signature field of UserOperation\n * @dev This method validates if the signature of UserOp is indeed valid by delegating the call to Verification Facet\n * Barz makes a call to the pre-registered Verification Facet address in App Storage\n * @param _userOp UserOperation from owner to be validated\n * @param _userOpHash Hash of UserOperation given from the EntryPoint contract\n */\n function _validateSignature(\n UserOperation calldata _userOp,\n bytes32 _userOpHash\n ) internal override returns (uint256 validationData) {\n // Get Facet with Function Selector\n address facet = LibLoupe.facetAddress(s.validateOwnerSignatureSelector);\n if (facet == address(0))\n revert AccountFacet__NonExistentVerificationFacet();\n\n // Make function call to VerificationFacet\n bytes memory validateCall = abi.encodeWithSelector(\n s.validateOwnerSignatureSelector,\n _userOp,\n _userOpHash\n );\n (bool success, bytes memory result) = facet.delegatecall(validateCall);\n if (!success) revert AccountFacet__CallNotSuccessful();\n validationData = uint256(bytes32(result));\n if (validationData == 0) emit VerificationSuccess(_userOpHash);\n else emit VerificationFailure(_userOpHash);\n }\n\n /**\n * @notice Calls the target with the inputted value and calldata\n * @dev This method is the actual function in Barz that makes a call with an arbitrary owner-given data\n * @param _target Address of the destination contract which the call is getting forwarded to\n * @param _value Amount of Native coin the owner is wanting to make in this call\n * @param _data Calldata the owner is forwarding together in the call e.g. Swap/Token Transfer\n */\n function _call(\n address _target,\n uint256 _value,\n bytes memory _data\n ) internal {\n if (_checkRestrictions(_target, _value, _data) == 1)\n revert AccountFacet__RestrictionsFailure();\n\n (bool success, bytes memory result) = _target.call{value: _value}(\n _data\n );\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n }\n\n /**\n * @notice Checks restrictions if the restrictions facet exists\n * @dev This method checks if the restrictions facet exists and makes a verification call to an array of restrictions facet\n * @param _target Address the call is getting forwarded to\n * @param _value Amount of native coin the call is sending together with the call\n * @param _data Calldata to trigger execution in target address\n */\n function _checkRestrictions(\n address _target,\n uint256 _value,\n bytes memory _data\n ) internal returns (uint256 result) {\n address facet = LibDiamond.restrictionsFacet();\n // NOTE: No restrictions facet, so restriction validation passes\n if (facet == address(0)) return 0;\n bytes memory call = abi.encodeWithSignature(\n \"verifyRestrictions(address,address,uint256,bytes)\",\n address(this),\n _target,\n _value,\n _data\n );\n (bool success, bytes memory response) = facet.delegatecall(call);\n if (!success) revert AccountFacet__RestrictionsFailure();\n result = uint256(bytes32(response));\n }\n}\n" + }, + "contracts/facets/AccountRecoveryFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibFacetStorage, RecoveryStorage, RecoveryConfig, RecoveryApprovalConfig, ApprovalConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {IAccountRecoveryFacet} from \"./interfaces/IAccountRecoveryFacet.sol\";\n\n/**\n * @title Account Recovery Facet\n * @dev Contract that enables recovery of accounts when owner key is unavailable\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract AccountRecoveryFacet is IAccountRecoveryFacet, Modifiers {\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Approve recovery of account as guardian\n * @dev This method can only be called by guardian and guardian inputs the public key of the new owner\n * When the threshold(majority of guardians) passes, it automatically executes account recovery\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function approveAccountRecovery(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + _getApprovalValidationPeriod()\n );\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit RecoveryApproved(\n _recoveryPublicKey,\n msg.sender,\n approvalValidUntil\n );\n if (\n getRecoveryApprovalCountWithTimeValidity(recoveryPublicKeyHash) >=\n LibGuardian.majorityOfGuardians()\n ) _executeRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Revoke recovery of account as guardian\n * @dev This method can only be called by guardian and guardian inputs the public key of the new owner\n When the threshold(majority of guardians) passes, it automatically revokes account recovery when recovery is pending\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function revokeAccountRecoveryApproval(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n if (\n !rs\n .isNewOwnerApproved[recoveryPublicKeyHash][msg.sender].isApproved ||\n !(block.timestamp <\n rs\n .isNewOwnerApproved[recoveryPublicKeyHash][msg.sender]\n .validUntil)\n ) revert AccountRecoveryFacet__NonExistentApproval();\n\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(false, 0);\n emit RecoveryApprovalRevoked(_recoveryPublicKey, msg.sender);\n }\n\n /**\n * @notice Executes recovery with signatures or on-chain pre-approvals\n * @dev This method validates the signatures of guardians or checks the on-chain pre-approved calls to check if the threshold passes\n * When the threshold passes, account recovery is executed and revert otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _guardians Array of guardians address that are approving the recovery of Account\n * @param _signatures Array of signature bytes that signed the approval hash\n */\n function executeRecovery(\n bytes calldata _recoveryPublicKey,\n address[] calldata _guardians,\n bytes[] calldata _signatures\n ) external override {\n if (_isRecoveryPending())\n revert AccountRecoveryFacet__RecoveryAlreadyOngoing();\n uint256 guardiansLength = _guardians.length;\n if (guardiansLength != _signatures.length)\n revert AccountRecoveryFacet__InvalidArrayLength();\n validateNewOwner(_recoveryPublicKey);\n\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n\n _checkApprover(_guardians);\n _checkDuplicateOnChainApprover(recoveryPublicKeyHash, _guardians);\n\n if (\n guardiansLength +\n getRecoveryApprovalCountWithTimeValidity(\n recoveryPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians()\n ) revert AccountRecoveryFacet__InsufficientGuardians();\n for (uint256 i; i < guardiansLength; ) {\n if (!LibGuardian.isGuardian(_guardians[i]))\n revert AccountRecoveryFacet__InvalidGuardian();\n if (\n !SignatureChecker.isValidSignatureNow(\n _guardians[i],\n recoveryPublicKeyHash,\n _signatures[i]\n )\n ) revert AccountRecoveryFacet__InvalidGuardianSignature();\n unchecked {\n ++i;\n }\n }\n _executeRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Executes recovery of the account. Note that execution and finalization is a different process\n * @dev Executes the recovery and adds recovery data to recovery configuration. Locks the account\n * @param _recoveryPublicKey Public Key of the account for recovery\n */\n function _executeRecovery(bytes memory _recoveryPublicKey) internal {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n ++rs.nonce;\n uint64 executeAfter = uint64(block.timestamp + _getRecoveryPeriod());\n rs.recoveryConfigs[INNER_STRUCT] = RecoveryConfig(\n _recoveryPublicKey,\n executeAfter // NOTE: Remove guardian Count\n );\n LibAppStorage.setLock(\n block.timestamp + _getLockPeriod(),\n AccountRecoveryFacet.executeRecovery.selector\n );\n emit RecoveryExecuted(_recoveryPublicKey, executeAfter);\n }\n\n /**\n * @notice Finalize recovery after recovery pending period. Recovery pending period can be set by user beforehand in SecurityManager\n * @dev This method finalizes recovery and fully changes the ownership of the account to the newly inputted recovery public key\n */\n function finalizeRecovery() external override {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n if (\n uint64(block.timestamp) <=\n rs.recoveryConfigs[INNER_STRUCT].executeAfter\n ) revert AccountRecoveryFacet__RecoveryPeriodNotOver();\n bytes memory recoveryOwner = rs\n .recoveryConfigs[INNER_STRUCT]\n .recoveryPublicKey;\n\n delete rs.recoveryConfigs[INNER_STRUCT];\n\n LibAppStorage.setLock(0, bytes4(0));\n\n LibAppStorage.initiateSignerMigration();\n address verificationFacet = address(\n bytes20(\n LibDiamond.diamondStorage().facets[\n s.validateOwnerSignatureSelector\n ]\n )\n );\n bytes memory uninitCall = abi.encodeWithSignature(\n \"uninitializeSigner()\"\n );\n (bool success, bytes memory result) = verificationFacet.delegatecall(\n uninitCall\n );\n if (!success) revert AccountRecoveryFacet__CallNotSuccesful();\n uint256 validationData = uint256(bytes32(result));\n if (validationData != 1)\n revert AccountRecoveryFacet__SignerUninitializationFailure();\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n recoveryOwner\n );\n (success, result) = verificationFacet.delegatecall(initCall);\n if (!success) revert AccountRecoveryFacet__CallNotSuccesful();\n validationData = uint256(bytes32(result));\n if (validationData != 1)\n revert AccountRecoveryFacet__SignerInitializationFailure();\n LibAppStorage.finalizeSignerMigration();\n emit RecoveryFinalized(recoveryOwner);\n }\n\n /**\n * @notice Approves the cancellation of recovery\n * @dev This method approves the cancellation of recovery when recovery is still pending - waiting for finalization\n * @param _recoveryPublicKey Bytes of public key which is pending for recovery\n */\n function approveCancelRecovery(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"CancelRecovery\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + _getApprovalValidationPeriod()\n );\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit RecoveryCancellationApproved(_recoveryPublicKey, msg.sender);\n if (\n getRecoveryApprovalCountWithTimeValidity(recoveryPublicKeyHash) >=\n LibGuardian.majorityOfGuardians()\n ) {\n _cancelRecovery(_recoveryPublicKey);\n }\n }\n\n /**\n * @notice Hardstops an ongoing recovery\n * @dev This method provides a safety mechanism to protect owners of malicious guardians.\n * Owners can hardstop recovery when an malicious guardians starts the recovery process.\n * @param _signature Signature of the owner that signs the hash to hardstop recovery\n */\n function hardstopRecovery(bytes calldata _signature) external override {\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n \"0\",\n \"HardstopRecovery\"\n );\n if (\n !SignatureChecker.isValidSignatureNow(\n address(this),\n recoveryPublicKeyHash,\n _signature\n )\n ) revert AccountRecoveryFacet__InvalidOwnerSignature();\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n ++rs.nonce;\n delete rs.recoveryConfigs[INNER_STRUCT];\n LibAppStorage.setLock(0, bytes4(0));\n emit RecoveryHardstopped();\n }\n\n /**\n * @notice Cancels recovery with signatures or on-chain pre-approvals\n * @dev This method validates the signatures of guardians or checks the on-chain pre-approved calls to check if the threshold passes\n * When the threshold passes, account recovery is canceled and revert otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _guardians Array of guardians address that are approving the recovery of Account\n * @param _signatures Array of signature bytes that signed the cancellation approval hash\n */\n function cancelRecovery(\n bytes calldata _recoveryPublicKey,\n address[] calldata _guardians,\n bytes[] calldata _signatures\n ) external override {\n uint256 guardiansLength = _guardians.length;\n if (guardiansLength != _signatures.length)\n revert AccountRecoveryFacet__InvalidArrayLength();\n validateNewOwner(_recoveryPublicKey);\n\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"CancelRecovery\"\n );\n\n _checkApprover(_guardians);\n _checkDuplicateOnChainApprover(recoveryPublicKeyHash, _guardians);\n\n if (\n guardiansLength +\n getRecoveryApprovalCountWithTimeValidity(\n recoveryPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians()\n ) revert AccountRecoveryFacet__InsufficientGuardians();\n for (uint256 i; i < guardiansLength; ) {\n if (!LibGuardian.isGuardian(_guardians[i]))\n revert AccountRecoveryFacet__CallerNotGuardian();\n if (\n !SignatureChecker.isValidSignatureNow(\n _guardians[i],\n recoveryPublicKeyHash,\n _signatures[i]\n )\n ) revert AccountRecoveryFacet__InvalidGuardianSignature();\n unchecked {\n ++i;\n }\n }\n _cancelRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Cancel recovery when the recovery is pending. Unlock the account as well\n * @dev This method checks if the recovery is pending and reverts if not pending.\n * It increases the recovery nonce and deletes the recovery information and gets a small portion of gas in return\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function _cancelRecovery(bytes memory _recoveryPublicKey) internal {\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n LibAppStorage.setLock(0, bytes4(0));\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n ++rs.nonce;\n delete rs.recoveryConfigs[INNER_STRUCT];\n emit RecoveryCanceled(_recoveryPublicKey);\n }\n\n /**\n * @notice Validates the format of public key to be used for recovery\n * @dev This method checks if the public key format is correct and reverts otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function validateNewOwner(bytes memory _recoveryPublicKey) public view {\n if (\n !IVerificationFacet(\n LibLoupe.facetAddress(s.validateOwnerSignatureSelector)\n ).isValidKeyType(_recoveryPublicKey)\n ) revert AccountRecoveryFacet__InvalidRecoveryPublicKey();\n }\n\n /**\n * @notice Checks if recovery is currently pending\n * @return isPending Boolean indicating if recovery is pending\n */\n function _isRecoveryPending() internal view returns (bool isPending) {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n isPending = (rs.recoveryConfigs[INNER_STRUCT].executeAfter > 0);\n }\n\n /**\n * @notice Calculate the recovery hash dependent on chain, wallet address, nonce with EIP-191 prefix for safety\n * @dev Returns the keccak256 hash of EIP-191 msg hash packed with public key, salt, nonce, wallet address, etc\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _saltString Salt string to uniquely identify each recovery hash and for security\n * @return recoveryKeyHash Bytes32 string of the recovery hash\n */\n function getApprovalRecoveryKeyHash(\n bytes memory _recoveryPublicKey,\n string memory _saltString\n ) public view override returns (bytes32 recoveryKeyHash) {\n recoveryKeyHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n _recoveryPublicKey,\n _saltString,\n address(this),\n block.chainid,\n LibFacetStorage.recoveryStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Check the onchain approval of guardians and returns the number of guardians that approved\n * @dev Loop through the guardian addresses and returns the number of guardians that approved this recovery hash\n * @param _recoveryPublicKeyHash Bytes hash of newly recovered public key and recovery value of the account\n * @return approvalCount Number of guardians that approved\n */\n function getRecoveryApprovalCountWithTimeValidity(\n bytes32 _recoveryPublicKeyHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n for (uint256 i; i < guardianLength; ) {\n if (isRecoveryApproved(_recoveryPublicKeyHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Checks if the recovery is approved by the given approver\n * @param _recoveryPublicKeyHash Hash of the public key and configuration for recovery\n * @param _approver Address of approver\n * @return isApproved Bool value if recovery hash is approved\n */\n function isRecoveryApproved(\n bytes32 _recoveryPublicKeyHash,\n address _approver\n ) public view override returns (bool isApproved) {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n if (\n rs\n .isNewOwnerApproved[_recoveryPublicKeyHash][_approver].isApproved &&\n block.timestamp <\n rs.isNewOwnerApproved[_recoveryPublicKeyHash][_approver].validUntil\n ) {\n isApproved = true;\n }\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _recoveryPublicKeyHash Hash of recovery information\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _recoveryPublicKeyHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isRecoveryApproved(_recoveryPublicKeyHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert AccountRecoveryFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the lock period of this wallet address from security manager\n * @return lockPeriod value of lock period\n */\n function _getLockPeriod() internal view returns (uint256 lockPeriod) {\n lockPeriod = securityManager.lockPeriodOf(address(this));\n if (lockPeriod == 0) revert AccountRecoveryFacet__InvalidLockPeriod();\n }\n\n /**\n * @notice Returns the lock period of this wallet address from security manager\n * @return recoveryPeriod value of recovery period\n */\n function _getRecoveryPeriod()\n internal\n view\n returns (uint256 recoveryPeriod)\n {\n recoveryPeriod = securityManager.recoveryPeriodOf(address(this));\n if (recoveryPeriod == 0)\n revert AccountRecoveryFacet__InvalidRecoveryPeriod();\n }\n\n /**\n * @notice Returns the approval validation period of this wallet address from security manager\n * @return approvalValidationPeriod value of approval validation period\n */\n function _getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod == 0)\n revert AccountRecoveryFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the recovery nonce of this wallet address from security manager\n * @return nonce value of recovery nonce\n */\n function getRecoveryNonce() public view override returns (uint128 nonce) {\n nonce = LibFacetStorage.recoveryStorage().nonce;\n }\n\n /**\n * @notice Returns the recovery information of the pending recovery\n * @return recoveryConfig value struct of pending recovery\n */\n function getPendingRecovery()\n public\n view\n override\n returns (RecoveryConfig memory recoveryConfig)\n {\n recoveryConfig = LibFacetStorage.recoveryStorage().recoveryConfigs[\n INNER_STRUCT\n ];\n }\n}\n" + }, + "contracts/facets/base/DiamondCutFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibGuardian} from \"../../libraries/LibGuardian.sol\";\nimport {ISecurityManager} from \"../../infrastructure/interfaces/ISecurityManager.sol\";\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibFacetStorage, DiamondCutApprovalConfig, ApprovalConfig} from \"../../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"../Modifiers.sol\";\nimport {IDiamondCut} from \"./interfaces/IDiamondCut.sol\";\n\n/**\n * @title DiamondCut Facet\n * @dev Responsible for adding/removing/replace facets in Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DiamondCutFacet is Modifiers, IDiamondCut {\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Updates the flag for the interfaceId\n * @param _interfaceId InterfaceID to update the mapping\n * @param _flag Bool value to update the mapping of the given interface ID\n */\n function updateSupportsInterface(\n bytes4 _interfaceId,\n bool _flag\n ) external override onlyWhenUnlocked {\n LibDiamond.enforceIsSelf();\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId] = _flag;\n emit SupportsInterfaceUpdated(_interfaceId, _flag);\n }\n\n /**\n * @notice Add/replace/remove any number of functions and optionally execute\n * a function with delegatecall when guardians don't exist\n * @param _diamondCut Contains the facet addresses and function selectors\n * @param _init The address of the contract or facet to execute _calldata\n * @param _calldata A function call, including function selector and arguments\n * _calldata is executed with delegatecall on _init\n */\n function diamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) external override onlyWhenUnlocked {\n LibDiamond.enforceIsSelf();\n\n _checkFacetCutValidity(_diamondCut);\n // require approval from guardian if guardian exists\n if (0 != LibGuardian.guardianCount())\n revert DiamondCutFacet__InvalidRouteWithGuardian();\n\n ++LibFacetStorage.diamondCutStorage().nonce;\n LibDiamond.diamondCut(_diamondCut, _init, _calldata);\n }\n\n /**\n * @notice Add/replace/remove any number of functions and optionally execute\n * a function with delegatecall when guardians exist\n * @param _diamondCut Contains the facet addresses and function selectors\n * @param _init The address of the contract or facet to execute _calldata\n * @param _calldata A function call, including function selector and arguments\n * _calldata is executed with delegatecall on _init\n * @param _approvers Guardian or owner address that approves the diamond cut\n * @param _signatures Signature of Guardians or owner that approves the diamond cut\n */\n function diamondCutWithGuardian(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n ) external override onlyWhenUnlocked {\n uint256 approverLength = _approvers.length;\n if (approverLength != _signatures.length)\n revert DiamondCutFacet__InvalidArrayLength();\n _checkFacetCutValidity(_diamondCut);\n if (0 == LibGuardian.guardianCount())\n revert DiamondCutFacet__InvalidRouteWithGuardian();\n\n bytes32 cutHash = getDiamondCutHash(_diamondCut, _init, _calldata);\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(cutHash, _approvers);\n\n bool onChainOwnerApproval = getOwnerCutApprovalWithTimeValidity(\n cutHash\n );\n\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n if (\n approverLength +\n getDiamondCutApprovalCountWithTimeValidity(cutHash) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert DiamondCutFacet__InsufficientApprovers();\n\n bool ownerApproved;\n for (uint256 i; i < approverLength; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n _approvers[i] != address(this)\n ) revert DiamondCutFacet__InvalidApprover();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert DiamondCutFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n cutHash,\n _signatures[i]\n )\n ) revert DiamondCutFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n if (!ownerApproved && !onChainOwnerApproval)\n revert DiamondCutFacet__LackOfOwnerApproval();\n\n ++LibFacetStorage.diamondCutStorage().nonce;\n LibDiamond.diamondCut(_diamondCut, _init, _calldata);\n }\n\n /**\n * @notice Approves diamond cut. This can only be called directly from guardian or owner\n * @param _diamondCut Contains the facet addresses and function selectors\n * @param _init The address of the contract or facet to execute _calldata\n * @param _calldata A function call, including function selector and arguments\n * _calldata is executed with delegatecall on _init\n */\n function approveDiamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\n if (LibGuardian.guardianCount() == 0)\n revert DiamondCutFacet__InvalidRouteWithoutGuardian();\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n _checkFacetCutValidity(_diamondCut);\n\n bytes32 cutHash = getDiamondCutHash(_diamondCut, _init, _calldata);\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(\n true,\n approvalValidUntil\n );\n emit DiamondCutApproved(_diamondCut, _init, _calldata);\n if (\n (getDiamondCutApprovalCountWithTimeValidity(cutHash) >=\n LibGuardian.majorityOfGuardians()) &&\n getOwnerCutApprovalWithTimeValidity(cutHash)\n ) {\n ++LibFacetStorage.diamondCutStorage().nonce;\n LibDiamond.diamondCut(_diamondCut, _init, _calldata);\n }\n }\n\n /**\n * @notice Revokes the approval of diamond cut. This can only be called directly from guardian or owner\n * @param _diamondCut Contains the facet addresses and function selectors\n * @param _init The address of the contract or facet to execute _calldata\n * @param _calldata A function call, including function selector and arguments\n * _calldata is executed with delegatecall on _init\n */\n function revokeDiamondCutApproval(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n bytes32 cutHash = getDiamondCutHash(_diamondCut, _init, _calldata);\n if (!ds.isDiamondCutApproved[cutHash][msg.sender].isApproved)\n revert DiamondCutFacet__CannotRevokeUnapproved();\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(false, 0);\n emit DiamondCutApprovalRevoked(_diamondCut, _init, _calldata);\n }\n\n /**\n * @notice Gets the number of approvals of diamond cut from guardians\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n */\n function getDiamondCutApprovalCountWithTimeValidity(\n bytes32 _diamondCutHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardiansLength = guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n if (isCutApproved(_diamondCutHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n return approvalCount;\n }\n\n /**\n * @notice Returns if the owner has approved the diamond cut\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @return isApprovedByOwner Bool value showing if the owner approved the cut\n */\n function getOwnerCutApprovalWithTimeValidity(\n bytes32 _diamondCutHash\n ) public view override returns (bool isApprovedByOwner) {\n isApprovedByOwner = isCutApproved(_diamondCutHash, address(this));\n }\n\n /**\n * @notice Returns if the given approver has approved the diamond cut\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @param _approver Address of approver\n * @return isApproved Bool value showing if the approver approved the cut\n */\n function isCutApproved(\n bytes32 _diamondCutHash,\n address _approver\n ) public view override returns (bool isApproved) {\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n isApproved = (ds\n .isDiamondCutApproved[_diamondCutHash][_approver].isApproved &&\n block.timestamp <\n ds.isDiamondCutApproved[_diamondCutHash][_approver].validUntil);\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _diamondCutHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isCutApproved(_diamondCutHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert DiamondCutFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the diamond cut hash. This function ensures that this hash is safe from replay attack by including\n * salt, address, chainId, and nonce, etc.\n * @param _diamondCut Contains the facet addresses and function selectors\n * @param _init The address of the contract or facet to execute _calldata\n * @param _calldata A function call, including function selector and arguments\n * _calldata is executed with delegatecall on _init\n * @return cutHash Diamond Cut Hash\n */\n function getDiamondCutHash(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) public view override returns (bytes32 cutHash) {\n cutHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n keccak256(abi.encode(_diamondCut)),\n _init,\n _calldata,\n address(this),\n block.chainid,\n LibFacetStorage.diamondCutStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Returns the approval validation Period\n * @dev This method fetches the validation period from the security manager\n * @return approvalValidationPeriod Approval validation period of Barz contract fetched from security manager\n */\n function getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod <= 0)\n revert DiamondCutFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the diamond cut nonce of this wallet\n * @dev This method fetches the nonce from diamond cut storage\n * @return cutNonce Nonce of diamond cut to protect from reply attacks\n */\n function getDiamondCutNonce()\n public\n view\n override\n returns (uint128 cutNonce)\n {\n cutNonce = LibFacetStorage.diamondCutStorage().nonce;\n }\n}\n" + }, + "contracts/facets/base/DiamondLoupeFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {IERC165} from \"../../interfaces/ERC/IERC165.sol\";\nimport {IERC1271} from \"../../interfaces/ERC/IERC1271.sol\";\nimport {IERC677Receiver} from \"../../interfaces/ERC/IERC677Receiver.sol\";\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC1155Receiver} from \"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\";\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../../libraries/LibLoupe.sol\";\nimport {LibUtils} from \"../../libraries/LibUtils.sol\";\nimport {IDiamondCut} from \"../../facets/base/interfaces/IDiamondCut.sol\";\nimport {IStorageLoupe} from \"./interfaces/IStorageLoupe.sol\";\nimport {IDiamondLoupe} from \"./interfaces/IDiamondLoupe.sol\";\n\n/**\n * @title DiamondLoupe Facet\n * @dev DiamondLoupe contract compatible with EIP-2535\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DiamondLoupeFacet is IDiamondLoupe, IStorageLoupe, IERC165 {\n // Diamond Loupe Functions\n ////////////////////////////////////////////////////////////////////\n /// These functions are expected to be called frequently by tools off-chain.\n\n /**\n * @notice Gets all facets and their selectors.\n * @dev Barz uses a special architecture called default fallback handler. Default Fallback handler is used as a middleware\n * that holds the mapping of facet function selector and facet address that Barz uses. This helps Barz to reduce\n * significant amount of gas during the initialization process.\n * Hence, this method aggregates both the facet information from DefaulFallbackHandler and in diamond storage and shows the data to users.\n * @return facets_ Facet\n */\n function facets() public view override returns (Facet[] memory facets_) {\n Facet[] memory defaultFacet = LibDiamond\n .diamondStorage()\n .defaultFallbackHandler\n .facets();\n Facet[] memory _facets = LibLoupe.facets();\n uint256 numFacets = _facets.length;\n bytes4[] memory keys;\n address[] memory values;\n for (uint256 i; i < numFacets; ) {\n uint256 selectorsLength = _facets[i].functionSelectors.length;\n for (uint256 j; j < selectorsLength; ) {\n (keys, values) = LibUtils.setValue(\n keys,\n values,\n _facets[i].functionSelectors[j],\n _facets[i].facetAddress\n );\n unchecked {\n ++j;\n }\n }\n unchecked {\n ++i;\n }\n }\n {\n bool iIncrement;\n for (uint256 i; i < defaultFacet.length; ) {\n bool jIncrement;\n for (\n uint256 j;\n j < defaultFacet[i].functionSelectors.length;\n\n ) {\n if (\n LibUtils.getValue(\n keys,\n values,\n defaultFacet[i].functionSelectors[j]\n ) != address(0)\n ) {\n if (defaultFacet[i].functionSelectors.length == 1) {\n defaultFacet = LibUtils.removeFacetElement(\n defaultFacet,\n i\n );\n iIncrement = true;\n break;\n }\n defaultFacet[i].functionSelectors = LibUtils\n .removeElement(\n defaultFacet[i].functionSelectors,\n j\n );\n jIncrement = true;\n }\n if (!jIncrement) {\n unchecked {\n ++j;\n }\n } else {\n jIncrement = false;\n }\n }\n if (!iIncrement) {\n unchecked {\n ++i;\n }\n } else {\n iIncrement = false;\n }\n }\n }\n {\n uint256 facetLength = numFacets + defaultFacet.length;\n facets_ = new Facet[](facetLength);\n uint256 defaultFacetIndex;\n for (uint256 i; i < facetLength; ) {\n if (i < numFacets) {\n facets_[i] = _facets[i];\n bool jIncrementor;\n for (uint256 j; j < defaultFacet.length; ) {\n if (\n facets_[i].facetAddress ==\n defaultFacet[j].facetAddress\n ) {\n facets_[i].functionSelectors = LibUtils.mergeArrays(\n _facets[i].functionSelectors,\n defaultFacet[j].functionSelectors\n );\n defaultFacet = LibUtils.removeFacetElement(\n defaultFacet,\n j\n );\n jIncrementor = true;\n {\n facets_ = LibUtils.removeFacetElement(\n facets_,\n facets_.length - 1\n );\n }\n --facetLength;\n }\n if (!jIncrementor) {\n unchecked {\n ++j;\n }\n } else {\n jIncrementor = false;\n }\n }\n } else {\n facets_[i] = defaultFacet[defaultFacetIndex];\n ++defaultFacetIndex;\n }\n unchecked {\n ++i;\n }\n }\n }\n }\n\n /**\n * @notice Gets all the function selectors provided by a facet.\n * @param _facet The facet address.\n * @return facetFunctionSelectors_\n */\n function facetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n Facet[] memory facet = facets();\n uint256 facetLength = facet.length;\n for (uint256 i; i < facetLength; ) {\n if (facet[i].facetAddress == _facet)\n return facet[i].functionSelectors;\n unchecked {\n ++i;\n }\n }\n return facetFunctionSelectors_;\n }\n\n /**\n * @notice Get all the facet addresses used by Barz.\n * @return facetAddresses_\n */\n function facetAddresses()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n Facet[] memory facet = facets();\n uint256 facetLength = facet.length;\n facetAddresses_ = new address[](facetLength);\n for (uint256 i; i < facetLength; ) {\n facetAddresses_[i] = facet[i].facetAddress;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Gets the facet that supports the given selector.\n * @dev If facet is not found return address(0).\n * @param _functionSelector The function selector.\n * @return facetAddress_ The facet address.\n */\n function facetAddress(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n\n facetAddress_ = address(bytes20(ds.facets[_functionSelector]));\n if (facetAddress_ == address(0)) {\n facetAddress_ = IDiamondLoupe(ds.defaultFallbackHandler)\n .facetAddress(_functionSelector);\n }\n }\n\n /**\n * @notice SupportInterface to be compatible with EIP 165\n * @param _interfaceId Interface ID for detecting the interface\n * @return isSupported Bool value showing if the standard is supported in the contract\n */\n function supportsInterface(\n bytes4 _interfaceId\n ) external view override returns (bool isSupported) {\n isSupported =\n _interfaceId == type(IERC165).interfaceId ||\n _interfaceId == IDiamondCut.diamondCut.selector ||\n _interfaceId == type(IDiamondLoupe).interfaceId ||\n _interfaceId == type(IERC1155Receiver).interfaceId ||\n _interfaceId == type(IERC721Receiver).interfaceId ||\n _interfaceId == type(IERC777Recipient).interfaceId ||\n _interfaceId == IERC1271.isValidSignature.selector ||\n _interfaceId == type(IERC677Receiver).interfaceId ||\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId];\n }\n\n /**\n * @notice Returns the facet from the diamond storage. This excludes the facets from the default fallback handler\n * @return facets_ Facet information attached directly to diamond storage\n */\n function facetsFromStorage()\n external\n view\n override\n returns (Facet[] memory facets_)\n {\n facets_ = LibLoupe.facets();\n }\n\n /**\n * @notice Returns the facet address attached to the given function selector. This excludes the facets from the default fallback handler\n * @param _functionSelector Function selector to fetch the facet address from diamond storage\n * @return facetAddress_ Facet address mapped with the function selector\n */\n function facetAddressFromStorage(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n facetAddress_ = LibLoupe.facetAddress(_functionSelector);\n }\n\n /**\n * @notice Returns all facet addresses attached directly to diamond storage. This excludes the facets from the default fallback handler\n * @return facetAddresses_ All facet addresses attached directly to diamond storage\n */\n function facetAddressesFromStorage()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n facetAddresses_ = LibLoupe.facetAddresses();\n }\n\n /**\n * @notice Returns function selectors of given facet address attached directly to diamond storage. This excludes the facets from the default fallback handler\n * @param _facet Facet address to fetch the facet function selectors from diamond storage\n * @return facetFunctionSelectors_ Facet function selectors of the given facet address\n */\n function facetFunctionSelectorsFromStorage(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n facetFunctionSelectors_ = LibLoupe.facetFunctionSelectors(_facet);\n }\n}\n" + }, + "contracts/facets/base/interfaces/IDiamondCut.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title DiamondCut Facet Interface\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IDiamondCut {\n error DiamondCutFacet__InvalidRouteWithGuardian();\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\n error DiamondCutFacet__InvalidArrayLength();\n error DiamondCutFacet__InsufficientApprovers();\n error DiamondCutFacet__InvalidApprover();\n error DiamondCutFacet__InvalidApproverSignature();\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\n error DiamondCutFacet__CannotRevokeUnapproved();\n error DiamondCutFacet__GuardianApprovalNotRequired();\n error DiamondCutFacet__LackOfOwnerApproval();\n error DiamondCutFacet__OwnerAlreadyApproved();\n error DiamondCutFacet__DuplicateApproval();\n\n event DiamondCutApproved(\n FacetCut[] diamondCut,\n address init,\n bytes initCalldata\n );\n event DiamondCutApprovalRevoked(\n FacetCut[] diamondCut,\n address init,\n bytes initCalldata\n );\n\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\n\n enum FacetCutAction {\n Add,\n Replace,\n Remove\n }\n // Add=0, Replace=1, Remove=2\n\n struct FacetCut {\n address facetAddress;\n FacetCutAction action;\n bytes4[] functionSelectors;\n }\n\n /// @notice Add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param diamondCut Contains the facet addresses and function selectors\n /// @param init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function diamondCut(\n FacetCut[] calldata diamondCut,\n address init,\n bytes calldata _calldata\n ) external;\n\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\n\n function diamondCutWithGuardian(\n FacetCut[] calldata diamondCut,\n address init,\n bytes calldata _calldata,\n address[] calldata approvers,\n bytes[] calldata signatures\n ) external;\n\n function approveDiamondCut(\n FacetCut[] calldata diamondCut,\n address init,\n bytes calldata _calldata\n ) external;\n\n function revokeDiamondCutApproval(\n FacetCut[] calldata diamondCut,\n address init,\n bytes calldata _calldata\n ) external;\n\n function getDiamondCutApprovalCountWithTimeValidity(\n bytes32 diamondCutHash\n ) external view returns (uint256);\n\n function getOwnerCutApprovalWithTimeValidity(\n bytes32 diamondCutHash\n ) external view returns (bool);\n\n function isCutApproved(\n bytes32 diamondCutHash,\n address approver\n ) external view returns (bool);\n\n function getDiamondCutHash(\n FacetCut[] calldata diamondCut,\n address init,\n bytes calldata _calldata\n ) external view returns (bytes32);\n\n function getDiamondCutNonce() external view returns (uint128);\n}\n" + }, + "contracts/facets/base/interfaces/IDiamondLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n// A loupe is a small magnifying glass used to look at diamonds.\n// These functions look at diamonds\ninterface IDiamondLoupe {\n /// These functions are expected to be called frequently\n /// by tools.\n\n struct Facet {\n address facetAddress;\n bytes4[] functionSelectors;\n }\n\n /// @notice Gets all facet addresses and their four byte function selectors.\n /// @return facets_ Facet\n function facets() external view returns (Facet[] memory facets_);\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n /// @return facetFunctionSelectors_\n function facetFunctionSelectors(\n address _facet\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses()\n external\n view\n returns (address[] memory facetAddresses_);\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(\n bytes4 _functionSelector\n ) external view returns (address facetAddress_);\n}\n" + }, + "contracts/facets/base/interfaces/IStorageLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"./IDiamondLoupe.sol\";\n\n/**\n * @title LoupeFromStorage Interface\n * @dev Interface contract to function as a loupe facet directly attached to diamond storage of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IStorageLoupe {\n /// These functions are expected to be called frequently\n /// by tools.\n\n /// @notice Gets all facet addresses and their four byte function selectors.\n /// @return facets_ Facet\n function facetsFromStorage()\n external\n view\n returns (IDiamondLoupe.Facet[] memory);\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n function facetFunctionSelectorsFromStorage(\n address _facet\n ) external view returns (bytes4[] memory);\n\n /// @notice Get all the facet addresses used by a diamond.\n function facetAddressesFromStorage()\n external\n view\n returns (address[] memory);\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n function facetAddressFromStorage(\n bytes4 _functionSelector\n ) external view returns (address);\n}\n" + }, + "contracts/facets/GuardianFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibFacetStorage, GuardianStorage, StorageConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IGuardianFacet} from \"./interfaces/IGuardianFacet.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Guardian Facet\n * @dev Contract that enables addition/removal of guardians from Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract GuardianFacet is IGuardianFacet {\n ISecurityManager public immutable securityManager;\n uint8 public constant INNER_STRUCT = 0;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Add guardians to Barz.\n * @dev This method internally calls addGuardian which checks the validity of guardian address and adds\n * as guardian if valid\n * @param _guardians Array of addresses to add as guardian\n */\n function addGuardians(address[] calldata _guardians) external override {\n LibDiamond.enforceIsSelf();\n uint256 guardiansLength = _guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n addGuardian(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Add a guardian to Barz.\n * @dev This method checks if the function is called by the owner and validates the address of guardian\n * When the validation passes, guardian address is added to the pending state waiting for confirmation\n * @param _guardian Address to add as guardian\n */\n function addGuardian(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (_guardian == address(this))\n revert GuardianFacet__GuardianCannotBeSelf();\n if (isGuardian(_guardian)) revert GuardianFacet__DuplicateGuardian();\n if (_guardian == address(0))\n revert GuardianFacet__ZeroAddressGuardian();\n if (\n keccak256(abi.encodePacked(_guardian)) ==\n keccak256(IVerificationFacet(address(this)).owner())\n ) revert GuardianFacet__OwnerCannotBeGuardian();\n\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n if (\n gs.pending[id] != 0 ||\n block.timestamp <= gs.pending[id] + getSecurityWindow()\n ) revert GuardianFacet__DuplicateGuardianAddition();\n\n uint256 securityPeriod = getAdditionSecurityPeriod();\n gs.pending[id] = block.timestamp + securityPeriod;\n emit GuardianAdditionRequested(\n _guardian,\n block.timestamp + securityPeriod\n );\n }\n\n /**\n * @notice Remove guardians from Barz.\n * @dev This method internally calls removeGuardian which checks the validity of guardian and removes\n * guardian when the request is valid\n * @param _guardians Array of addresses to be removed\n */\n function removeGuardians(address[] calldata _guardians) external override {\n LibDiamond.enforceIsSelf();\n uint256 guardiansLength = _guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n removeGuardian(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Remove a guardian from Barz.\n * @dev This method validates if the guardian to be removed is a guardian and puts the guardian removal\n * to a pending state waiting to be confirmed.\n * @param _guardian Address of guardian to be removed\n */\n function removeGuardian(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n if (!isGuardian(_guardian)) revert GuardianFacet__NonExistentGuardian();\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n if (\n gs.pending[id] != 0 ||\n block.timestamp <= gs.pending[id] + getSecurityWindow()\n ) revert GuardianFacet__DuplicateGuardianRemoval();\n\n uint256 securityPeriod = getRemovalSecurityPeriod();\n gs.pending[id] = block.timestamp + securityPeriod;\n emit GuardianRemovalRequested(\n _guardian,\n block.timestamp + securityPeriod\n );\n }\n\n /**\n * @notice Confirm addition of guardians\n * @dev This method internally calls confirmGuardianAddition which checks the validity of pending request.\n * Guardians are fully added when they pass the validation. Anyone can call this function.\n * @param _guardians Array of guardian addresses to be added\n */\n function confirmGuardianAdditions(\n address[] calldata _guardians\n ) external override {\n uint256 guardiansLength = _guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n confirmGuardianAddition(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Confirm addition of a guardian\n * @dev This method checks the validity of pending request.\n * Guardians are fully added when they pass the validation. Anyone can call this function.\n * @param _guardian Guardian address to be added\n */\n function confirmGuardianAddition(address _guardian) public override {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingAddition();\n if (gs.pending[id] >= block.timestamp)\n revert GuardianFacet__PendingAdditionNotOver();\n if (block.timestamp >= gs.pending[id] + getSecurityWindow())\n revert GuardianFacet__PendingAdditionExpired();\n\n _addGuardian(_guardian);\n\n delete gs.pending[id];\n emit GuardianAdded(_guardian);\n }\n\n /**\n * @notice Confirm removal of guardians\n * @dev This method internally calls confirmGuardianRemoval to check the validity guardian removal confirmation.\n * Guardians are fully removed when they pass the validation. Anyone can call this function.\n * @param _guardians Array of guardian addresses to be removed\n */\n function confirmGuardianRemovals(\n address[] calldata _guardians\n ) external override {\n uint256 guardiansLength = _guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n confirmGuardianRemoval(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Confirm removal of a guardian\n * @dev This method checks the validity guardian removal confirmation.\n * Guardian is fully removed when they pass the validation. Anyone can call this function.\n * @param _guardian Guardian address to be removed\n */\n function confirmGuardianRemoval(address _guardian) public override {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingRemoval();\n if (gs.pending[id] >= block.timestamp)\n revert GuardianFacet__PendingRemovalNotOver();\n if (block.timestamp >= gs.pending[id] + getSecurityWindow())\n revert GuardianFacet__PendingAdditionExpired();\n\n _removeGuardian(_guardian);\n delete gs.pending[id];\n emit GuardianRemoved(_guardian);\n }\n\n /**\n * @notice Cancel pending guardian addition\n * @dev This method checks if the previous request for guardian request exists.\n * It reverts if previous request is not pending and cancels the addition otherwise.\n * @param _guardian Guardian address to be canceled from addition\n */\n function cancelGuardianAddition(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingAddition();\n delete gs.pending[id];\n emit GuardianAdditionCancelled(_guardian);\n }\n\n /**\n * @notice Cancel pending guardian removal\n * @dev This method checks if the previous request for guardian request exists.\n * It reverts if previous request is not pending and cancels the removal otherwise.\n * @param _guardian Guardian address to be canceled from removal\n */\n function cancelGuardianRemoval(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingRemoval();\n delete gs.pending[id];\n emit GuardianRemovalCancelled(_guardian);\n }\n\n /**\n * @notice Get the addition security period of current account from security manager\n * @dev This method returns the uint value if addition security period\n * @return additionSecurityPeriod Uint256 value of addition security period\n */\n function getAdditionSecurityPeriod()\n public\n view\n override\n returns (uint256 additionSecurityPeriod)\n {\n additionSecurityPeriod = securityManager.additionSecurityPeriodOf(\n address(this)\n );\n if (additionSecurityPeriod == 0)\n revert GuardianFacet__InvalidAdditionSecurityPeriod();\n }\n\n /**\n * @notice Get the removal security period of current account from security manager\n * @dev This method returns the uint value if removal security period\n * @return removalSecurityPeriod Uint256 value of removal security period\n */\n function getRemovalSecurityPeriod()\n public\n view\n override\n returns (uint256 removalSecurityPeriod)\n {\n removalSecurityPeriod = securityManager.removalSecurityPeriodOf(\n address(this)\n );\n if (removalSecurityPeriod == 0)\n revert GuardianFacet__InvalidRemovalSecurityPeriod();\n }\n\n /**\n * @notice Get the security window of current account from security manager\n * @dev This method returns the uint value if security window\n * @return securityWindow Uint256 value of removal security period\n */\n function getSecurityWindow()\n public\n view\n override\n returns (uint256 securityWindow)\n {\n securityWindow = securityManager.securityWindowOf(address(this));\n if (securityWindow == 0) revert GuardianFacet__InvalidSecurityWindow();\n }\n\n /**\n * @notice Checks if the addition of the given guardian address is pending\n * @dev This method returns the bool value of whether the guardian address is pending addition\n * @return isPending Bool value of representing the pending of guardian addition\n */\n function isAdditionPending(\n address _guardian\n ) public view override returns (bool isPending) {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n isPending = _isPending(id);\n }\n\n /**\n * @notice Checks if the removal of the given guardian address is pending\n * @dev This method returns the bool value of whether the guardian address is pending removal\n * @return isPending Bool value of representing the pending of guardian removal\n */\n function isRemovalPending(\n address _guardian\n ) public view override returns (bool isPending) {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n isPending = _isPending(id);\n }\n\n /**\n * @notice Checks if the given hash is pending\n * @dev This method returns the bool value whether the hash is pending\n * @return isPending Bool value of representing the pending of guardian operation\n */\n function _isPending(\n bytes32 _idHash\n ) internal view returns (bool isPending) {\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n isPending = ((gs.pending[_idHash] > 0 &&\n gs.pending[_idHash] < block.timestamp) &&\n block.timestamp < gs.pending[_idHash] + getSecurityWindow());\n }\n\n /**\n * @notice Adds guardian to storage config. This is called when guardian is fully added.\n * @dev This method add guardian address and config information to Facet Storage dedicated for guardian\n * When this function is called, guardian is fully added to this Barz Smart Account\n * @param _guardian Address of guardian to be added\n */\n function _addGuardian(address _guardian) internal {\n if (!isAdditionPending(_guardian))\n revert GuardianFacet__InvalidGuardianAddition();\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n if (config.info[_guardian].exists)\n revert GuardianFacet__AlreadyExists();\n\n config.info[_guardian].exists = true;\n config.info[_guardian].index = uint128(config.addresses.length);\n config.addresses.push(_guardian);\n }\n\n /**\n * @notice Removes guardian to storage config. This is called when guardian is fully removed.\n * @dev This method remove guardian address and config information to Facet Storage dedicated for guardian\n * When this function is called, guardian is fully removed from this Barz Smart Account\n * @param _guardian Address of guardian to be removed\n */\n function _removeGuardian(address _guardian) internal {\n if (!isRemovalPending(_guardian))\n revert GuardianFacet__InvalidGuardianRemoval();\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n if (!config.info[_guardian].exists)\n revert GuardianFacet__NonExistentGuardian();\n\n address lastAddress = config.addresses[config.addresses.length - 1];\n if (_guardian != lastAddress) {\n uint128 targetIndex = config.info[_guardian].index;\n config.addresses[targetIndex] = lastAddress;\n config.info[lastAddress].index = targetIndex;\n }\n config.addresses.pop();\n delete config.info[_guardian];\n\n emit GuardianRemoved(_guardian);\n }\n\n /**\n * @notice Reads guardian storage and fetches the addresses into an array from the storage\n * @dev This method fetches the guardian storage and returns the list of guardian addresses\n * @return addresses Array of addresses comprised of guardian\n */\n function getGuardians()\n public\n view\n override\n returns (address[] memory addresses)\n {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n addresses = new address[](config.addresses.length);\n uint256 addressesLen = config.addresses.length;\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the number of majority of guardians\n * @return majorityOfGuardians_ Number of majority of guardians e.g., 2 if 3 guardians / 3 if 5 guardians\n */\n function majorityOfGuardians()\n public\n view\n override\n returns (uint256 majorityOfGuardians_)\n {\n majorityOfGuardians_ = LibGuardian.majorityOfGuardians();\n }\n\n /**\n * @notice Reads guardian storage and fetches the addresses into an array from the storage\n * @dev This method fetches the guardian storage and returns the list of guardian addresses\n * @return guardianNumber Array of guardians in the account\n */\n function guardianCount()\n public\n view\n override\n returns (uint256 guardianNumber)\n {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n guardianNumber = config.addresses.length;\n }\n\n /**\n * @notice Reads guardian storage and checks if the given address is a guardian\n * @return isGuardian_ Bool value representing if the given address is guardian\n */\n function isGuardian(\n address _guardian\n ) public view override returns (bool isGuardian_) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n isGuardian_ = config.info[_guardian].exists;\n }\n\n /**\n * @notice Checks if the guardian number is zero and returns of guardian facet is okay to be removed\n * @return isRemovable Bool value representing if guardian facet is removable\n */\n function isGuardianFacetRemovable()\n external\n view\n override\n returns (bool isRemovable)\n {\n isRemovable = (0 == guardianCount());\n }\n}\n" + }, + "contracts/facets/interfaces/IAccountFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IEntryPoint} from \"../../aa-4337/interfaces/IEntryPoint.sol\";\n\n/**\n * @title Account Facet Interface\n * @dev Interface of module contract that provides the account features and init/unitialization of signer\n * compatible with EIP-1271 & EIP-4337\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IAccountFacet {\n event AccountInitialized(\n IEntryPoint indexed entryPoint,\n bytes indexed ownerPublicKey\n );\n // NOTE: Added Below Event\n event VerificationSuccess(bytes32);\n event VerificationFailure(bytes32);\n\n error AccountFacet__InitializationFailure();\n error AccountFacet__RestrictionsFailure();\n error AccountFacet__NonExistentVerificationFacet();\n error AccountFacet__CallNotSuccessful();\n\n function initialize(\n address verificationFacet,\n address anEntryPoint,\n address facetRegistry,\n address _defaultFallBack,\n bytes calldata _ownerPublicKey\n ) external returns (uint256);\n\n function execute(address dest, uint256 value, bytes calldata func) external;\n\n function executeBatch(\n address[] calldata dest,\n uint256[] calldata value,\n bytes[] calldata func\n ) external;\n}\n" + }, + "contracts/facets/interfaces/IAccountRecoveryFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {RecoveryConfig} from \"../../libraries/LibFacetStorage.sol\";\n\n/**\n * @title Account Recovery Facet Interface\n * @dev Interface of contract that enables recovery of accounts when owner key is unavailable\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IAccountRecoveryFacet {\n event RecoveryExecuted(\n bytes indexed recoveryPublicKey,\n uint64 executeAfter\n );\n event RecoveryFinalized(bytes indexed recoveryPublicKey);\n event RecoveryCanceled(bytes indexed recoveryPublicKey);\n event RecoveryApproved(\n bytes indexed recoveryPublicKey,\n address indexed guardian,\n uint64 validUntil\n );\n event RecoveryApprovalRevoked(\n bytes indexed recoveryPublicKey,\n address indexed guardian\n );\n event RecoveryCancellationApproved(\n bytes indexed recoveryPublicKey,\n address indexed guardian\n );\n event RecoveryHardstopped();\n\n error AccountRecoveryFacet__CallerNotGuardian();\n error AccountRecoveryFacet__InvalidRecoveryPublicKey();\n error AccountRecoveryFacet__SignerInitializationFailure();\n error AccountRecoveryFacet__SignerUninitializationFailure();\n error AccountRecoveryFacet__InvalidArrayLength();\n error AccountRecoveryFacet__InsufficientGuardians();\n error AccountRecoveryFacet__RecoveryAlreadyOngoing();\n error AccountRecoveryFacet__NonexistentRecovery();\n error AccountRecoveryFacet__NonExistentApproval();\n error AccountRecoveryFacet__RecoveryPeriodNotOver();\n error AccountRecoveryFacet__InvalidLockPeriod();\n error AccountRecoveryFacet__InvalidRecoveryPeriod();\n error AccountRecoveryFacet__InvalidApprovalValidationPeriod();\n error AccountRecoveryFacet__InvalidGuardian();\n error AccountRecoveryFacet__InvalidGuardianSignature();\n error AccountRecoveryFacet__InvalidOwnerSignature();\n error AccountRecoveryFacet__CallNotSuccesful();\n error AccountRecoveryFacet__DuplicateApproval();\n\n function approveAccountRecovery(bytes calldata recoveryPublicKey) external;\n\n function revokeAccountRecoveryApproval(\n bytes calldata recoveryPublicKey\n ) external;\n\n function executeRecovery(\n bytes calldata recoveryPublicKey,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function finalizeRecovery() external;\n\n function approveCancelRecovery(bytes calldata recoveryPublicKey) external;\n\n function cancelRecovery(\n bytes calldata recoveryPublicKey,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function hardstopRecovery(bytes calldata signature) external;\n\n function getApprovalRecoveryKeyHash(\n bytes memory recoveryPublicKey,\n string memory saltString\n ) external view returns (bytes32);\n\n function getRecoveryApprovalCountWithTimeValidity(\n bytes32 recoveryPublicKeyHash\n ) external view returns (uint256);\n\n function isRecoveryApproved(\n bytes32 recoveryPublicKeyHash,\n address approver\n ) external view returns (bool);\n\n function getRecoveryNonce() external view returns (uint128);\n\n function getPendingRecovery() external view returns (RecoveryConfig memory);\n}\n" + }, + "contracts/facets/interfaces/IGuardianFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Guardian Facet Interface\n * @dev Interface of guaridna contract that enables addition/removal of guardians from Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IGuardianFacet {\n event GuardianAdditionRequested(\n address indexed guardian,\n uint256 executeAfter\n );\n event GuardianRemovalRequested(\n address indexed guardian,\n uint256 executeAfter\n );\n event GuardianAdditionCancelled(address indexed guardian);\n event GuardianRemovalCancelled(address indexed guardian);\n event GuardianAdded(address indexed guardian);\n event GuardianRemoved(address indexed guardian);\n\n error GuardianFacet__GuardianCannotBeSelf();\n error GuardianFacet__DuplicateGuardian();\n error GuardianFacet__OwnerCannotBeGuardian();\n error GuardianFacet__DuplicateGuardianAddition();\n error GuardianFacet__DuplicateGuardianRemoval();\n error GuardianFacet__UnknownPendingAddition();\n error GuardianFacet__PendingAdditionNotOver();\n error GuardianFacet__UnknownPendingRemoval();\n error GuardianFacet__PendingRemovalNotOver();\n error GuardianFacet__PendingAdditionExpired();\n error GuardianFacet__InvalidAdditionSecurityPeriod();\n error GuardianFacet__InvalidRemovalSecurityPeriod();\n error GuardianFacet__InvalidSecurityWindow();\n error GuardianFacet__NonExistentGuardian();\n error GuardianFacet__AlreadyExists();\n error GuardianFacet__InvalidGuardianAddition();\n error GuardianFacet__InvalidGuardianRemoval();\n error GuardianFacet__ZeroAddressGuardian();\n\n function addGuardian(address guardian) external;\n\n function addGuardians(address[] calldata guardians) external;\n\n function removeGuardian(address guardian) external;\n\n function removeGuardians(address[] calldata guardians) external;\n\n function confirmGuardianAddition(address guardian) external;\n\n function confirmGuardianAdditions(address[] calldata guardian) external;\n\n function confirmGuardianRemoval(address guardian) external;\n\n function confirmGuardianRemovals(address[] calldata guardian) external;\n\n function cancelGuardianAddition(address guardian) external;\n\n function cancelGuardianRemoval(address guardian) external;\n\n function isGuardian(address guardian) external view returns (bool);\n\n function isAdditionPending(address guardian) external view returns (bool);\n\n function isRemovalPending(address guardian) external view returns (bool);\n\n function isGuardianFacetRemovable() external view returns (bool);\n\n function getAdditionSecurityPeriod() external view returns (uint256);\n\n function getRemovalSecurityPeriod() external view returns (uint256);\n\n function getSecurityWindow() external view returns (uint256);\n\n function getGuardians() external view returns (address[] memory);\n\n function majorityOfGuardians() external view returns (uint256);\n\n function guardianCount() external view returns (uint256);\n}\n" + }, + "contracts/facets/interfaces/ILockFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Lock} from \"../../libraries/LibAppStorage.sol\";\n\n/**\n * @title Lock Facet Interface\n * @dev Interface of Lock contract that enables full lock/unlock of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface ILockFacet {\n event Locked(uint64 releaseAfter);\n event Unlocked();\n\n error LockFacet__InvalidRecoveryPeriod();\n error LockFacet__CannotUnlock();\n error LockFacet__InvalidSignature();\n error LockFacet__InvalidApprover();\n\n function lock() external;\n\n function unlock(address approver, bytes calldata signature) external;\n\n function getLockPeriod() external view returns (uint256);\n\n function isLocked() external view returns (bool);\n\n function getUnlockHash() external view returns (bytes32);\n\n function lockNonce() external view returns (uint128);\n\n function getPendingLock() external view returns (Lock memory);\n}\n" + }, + "contracts/facets/interfaces/IMultiSigFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Multi-sig facet Interface\n * @dev Interface of Multi-signature Facet with custom threshold.\n Wallet that adds this facet becomes a multi-sig wallet\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IMultiSigFacet {\n event ThresholdChanged(uint256 threshold);\n event OwnerAdded(address indexed newOwner);\n event OwnerRemoved(address indexed prevOwner);\n event HashApproved(bytes32 hashToApprove, address indexed owner);\n\n error MultiSigFacet__InvalidThreshold();\n error MultisigFacet__InvalidOwnerCount();\n error MultiSigFacet__InvalidRoute();\n error MultiSigFacet__InsufficientSignerLength();\n error MultiSigFacet__InvalidInitData();\n error MultiSigFacet__InvalidOwnerAddress();\n error MultiSigFacet__InvalidOwnerPair();\n error MultiSigFacet__InvalidSignatureLength();\n error MultiSigFacet__InvalidSignatureType();\n error MultiSigFacet__DuplicateOwner();\n error MultiSigFacet__OnlyOwner();\n\n function checkSignatures(\n bytes32 _dataHash,\n bytes calldata _signatures,\n uint256 _threshold\n ) external view returns (uint256);\n\n function splitSignatures(\n bytes calldata _signatures,\n uint256 _nextOffset\n )\n external\n pure\n returns (\n address owner,\n bytes memory signature,\n uint256 signatureType,\n uint256 nextOffset\n );\n\n function approveHash(bytes32 hashToApprove) external;\n\n function addOwner(address newOwner, uint256 threshold) external;\n\n function removeOwner(\n address prevOwner,\n address removedOwner,\n uint256 threshold\n ) external;\n\n function swapOwner(\n address prevOwner,\n address oldOwner,\n address newOwner\n ) external;\n\n function changeThreshold(uint256 _threshold) external;\n\n function isOwner(address owner) external view returns (bool);\n\n function getThreshold() external view returns (uint256);\n\n function getOwners() external view returns (address[] memory);\n}\n" + }, + "contracts/facets/interfaces/IRestrictionsFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Restrictions Facet Interface\n * @dev Interface of Restrictions contract that enables modular restrictions in Barz\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IRestrictionsFacet {\n event RestrictionAdded(address indexed restriction);\n event RestrictionRemoved(address indexed restriction);\n\n error RestrictionsFacet__EmptyRestrictionsList();\n error RestrictionsFacet__RestrictionNotFound();\n error RestrictionsFacet__RestrictionAlreadyExists();\n error RestrictionsFacet__ZeroAddressRestrictions();\n error RestrictionsFacet__ZeroAddressRestrictionsFacet();\n error RestrictionsFacet__RemainingRestrictionsCantBeEmpty();\n\n function initializeRestrictions(\n address[] memory _restrictions\n ) external returns (uint256);\n\n function uninitializeRestrictions() external returns (uint256);\n\n function getRestrictions() external view returns (address[] memory);\n\n function addRestriction(address restriction) external;\n\n function removeRestriction(address restriction) external;\n\n function verifyRestrictions(\n address from,\n address to,\n uint256 value,\n bytes calldata _calldata\n ) external returns (uint256);\n}\n" + }, + "contracts/facets/interfaces/ISignatureMigrationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureMigrationConfig} from \"../../libraries/LibFacetStorage.sol\";\n\n/**\n * @title Signature Migration Facet Interface\n * @dev Interface of Signature Migration contract for migrating user signature scheme to a new scheme user sets\n * Which could include\n * - ECDSA on Secp256K1 Curve\n * - ECDSA on Secp256R1 Curve\n * - BLS, Schnorr, etc\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface ISignatureMigrationFacet {\n event SignatureSchemeMigration(\n address indexed prevVerificationFacet,\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n event SignatureMigrationApproved(\n bytes newPublicKey,\n address indexed newVerificationFacet,\n bytes4[] verificationFuncSelectors,\n address indexed guardian,\n uint128 approvalValidUntil\n );\n event SignatureMigrationApprovalRevoked(\n bytes newPublicKey,\n address indexed newVerificationFacet,\n bytes4[] verificationFuncSelectors,\n address indexed guardian\n );\n event SignatureMigrationExecuted(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors,\n uint128 migrateAfter\n );\n event SignatureMigrationCanceled(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n event SignatureMigrationCancellationApproved(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n\n error SignatureMigrationFacet__SignerUninitializationFailure();\n error SignatureMigrationFacet__InvalidRouteWithGuardian();\n error SignatureMigrationFacet__InvalidKeyType();\n error SignatureMigrationFacet__InsufficientApprovers();\n error SignatureMigrationFacet__InvalidApproverSignature();\n error SignatureMigrationFacet__InvalidGuardian();\n error SignatureMigrationFacet__NonExistentApprover();\n error SignatureMigrationFacet__InvalidMigrationPeriod();\n error SignatureMigrationFacet__NonexistentMigration();\n error SignatureMigrationFacet__MigrationPeriodNotOver();\n error SignatureMigrationFacet__InvalidArrayLength();\n error SignatureMigrationFacet__InvalidApprovalValidationPeriod();\n error SignatureMigrationFacet__CannotRevokeUnapproved();\n error SignatureMigrationFacet__LackOfOwnerApproval();\n error SignatureMigrationFacet__OwnerAlreadyApproved();\n error SignatureMigrationFacet__NonExistentVerificationFacet();\n error SignatureMigrationFacet__DuplicateApproval();\n\n function migrateSignatureScheme(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function migrateSignatureSchemeWithGuardian(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors,\n address[] calldata approvers,\n bytes[] calldata signatures\n ) external;\n\n function approveSignatureSchemeMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function revokeSignatureMigrationApproval(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function finalizeSignatureMigration() external;\n\n function approveCancelSignatureMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function cancelSignatureMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function getApprovalMigrationKeyHash(\n bytes memory recoveryPublicKey,\n address newVerificationFacet,\n bytes4[] memory newVerificationFuncSelectors,\n string memory saltString\n ) external view returns (bytes32);\n\n function getMigrationOwnerApprovalWithTimeValidity(\n bytes32 publicKeyHash\n ) external view returns (bool);\n\n function getMigrationApprovalCountWithTimeValidity(\n bytes32 publicKeyHash\n ) external view returns (uint256);\n\n function isMigrationApproved(\n bytes32 migrationPublicKeyHash,\n address approver\n ) external view returns (bool);\n\n function getMigrationNonce() external view returns (uint128);\n\n function isMigrationPending() external view returns (bool);\n\n function getPendingMigration()\n external\n view\n returns (SignatureMigrationConfig memory);\n}\n" + }, + "contracts/facets/interfaces/IVerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {UserOperation} from \"../../aa-4337/interfaces/UserOperation.sol\";\n\n/**\n * @title Verification Facet Interface\n * @dev Implements logic for user ops signature verification\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface IVerificationFacet {\n event SignerInitialized(bytes);\n event SignerUninitialized();\n\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n error VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n error VerificationFacet__InitializationFailure();\n error VerificationFacet__InvalidFacetMapping();\n\n function initializeSigner(bytes memory) external returns (uint256);\n\n function uninitializeSigner() external returns (uint256);\n\n function validateOwnerSignatureSelector() external view returns (bytes4);\n\n function owner() external view returns (bytes memory);\n\n function isValidKeyType(bytes calldata) external view returns (bool);\n\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) external view returns (uint256);\n}\n" + }, + "contracts/facets/LockFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage, Lock} from \"../libraries/LibAppStorage.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibFacetStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {ILockFacet} from \"./interfaces/ILockFacet.sol\";\n\n/**\n * @title Lock Facet\n * @dev Contract that enables full lock/unlock of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract LockFacet is ILockFacet, Modifiers {\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Locks the account for the lock period. Lock period is defined in the security manager and it's customizable\n * This function can only be called when account is unlocked by owner or guardians\n * @dev This method checks the caller and if the account is currently locked and locks the account after fetching the\n * Lock period from the owner.\n */\n function lock() external override onlyGuardianOrOwner onlyWhenUnlocked {\n uint256 unlockTime = block.timestamp + getLockPeriod();\n ++LibFacetStorage.lockStorage().nonce;\n LibAppStorage.setLock(unlockTime, LockFacet.lock.selector);\n emit Locked(uint64(unlockTime));\n }\n\n /**\n * @notice Locks the account when the account is locked. This function can be called by anyone but must provide the approver address and signature.\n * The approver should be one of the guardians or owner.\n * @dev This method takes the approver address and the signature. After validating the address and the signature, it unlocks the account immediately.\n * Only one of the guardian or owner is required to lock and unlock the account.\n * @param _approver Address of approver approving the unlock of Barz account\n * @param _signature Signature of the approver that signed the msg hash for unlocking the account\n */\n function unlock(\n address _approver,\n bytes calldata _signature\n ) external override onlyWhenLocked {\n if (_approver != address(this) && !LibGuardian.isGuardian(_approver))\n revert LockFacet__InvalidApprover();\n if (\n !SignatureChecker.isValidSignatureNow(\n _approver,\n getUnlockHash(),\n _signature\n )\n ) revert LockFacet__InvalidSignature();\n _unlock();\n }\n\n /**\n * @notice Unlocks the account and increments the lock nonce\n */\n function _unlock() private {\n if (s.locks[INNER_STRUCT].locker != LockFacet.lock.selector)\n revert LockFacet__CannotUnlock();\n ++LibFacetStorage.lockStorage().nonce;\n LibAppStorage.setLock(0, bytes4(0));\n emit Unlocked();\n }\n\n /**\n * @notice Returns the lock period of current Barz account. Lock period information is held by Security Manager\n * @return lockPeriod Uint value of lock period in seconds\n */\n function getLockPeriod() public view override returns (uint256 lockPeriod) {\n lockPeriod = securityManager.lockPeriodOf(address(this));\n if (lockPeriod == 0) revert LockFacet__InvalidRecoveryPeriod();\n }\n\n /**\n * @notice Returns if the account is locked or not\n * @dev This method fetches the current block timestamp and compares that with release time.\n * After checking the timestamp and release time, it returns if the account is still locked or not.\n * @return isLocked_ Uint value of lock period in seconds\n */\n function isLocked() public view override returns (bool isLocked_) {\n isLocked_ = uint64(block.timestamp) < s.locks[INNER_STRUCT].release;\n }\n\n /**\n * @notice Calculates the unlock hash and returns the unlock hash safe from signature reply attack\n * @dev This method calculates the unlock hash with EIP-191 prefix, wallet address, chainID, and nonce\n * It packs the result and packs them and hashes it.\n * @return unlockHash Bytes32 unlock hash\n */\n function getUnlockHash() public view override returns (bytes32 unlockHash) {\n unlockHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n \"Unlock\",\n address(this),\n block.chainid,\n lockNonce()\n )\n )\n )\n );\n }\n\n /**\n * @notice Returns lock nonce of account. Reads nonce from lock storage within facet storage\n * @return lockNonce_ Uint128 value of lock nonce. This is incremented whenever the account is lock/unlocked\n */\n function lockNonce() public view override returns (uint128 lockNonce_) {\n lockNonce_ = LibFacetStorage.lockStorage().nonce;\n }\n\n /**\n * @notice Returns the overall information of current lock\n * @return pendingLock Struct value including all information of pending lock\n */\n function getPendingLock()\n public\n view\n override\n returns (Lock memory pendingLock)\n {\n pendingLock = s.locks[INNER_STRUCT];\n }\n}\n" + }, + "contracts/facets/Modifiers.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {IFacetRegistry} from \"../infrastructure/interfaces/IFacetRegistry.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\n\n/**\n * @title Modifiers\n * @dev Responsible for providing modifiers/util functions to Facet contracts\n * @author David Yongjun Kim (@Powerstream3604)\n */\nabstract contract Modifiers is BarzStorage {\n uint8 constant INNER_STRUCT = 0;\n\n error CallerNotGuardian();\n error CallerNotGuardianOrOwner();\n error DuplicateApprover();\n error ZeroApproverLength();\n error UnregisteredFacetAndSelectors();\n\n /**\n * @notice Modifier to only allow guardian to make a call, reverts if any other entity is the caller\n */\n modifier onlyGuardian() {\n if (!LibGuardian.isGuardian(msg.sender)) revert CallerNotGuardian();\n _;\n }\n\n /**\n * @notice Modifier to only allow guardian or owner to make a call, reverts if any other entity is the caller\n */\n modifier onlyGuardianOrOwner() {\n if (!LibGuardian.isGuardian(msg.sender) && address(this) != msg.sender)\n revert CallerNotGuardianOrOwner();\n _;\n }\n\n /**\n * @notice Checks if the approver address is the array is unique with no duplicate\n * @dev This method loops through the array and checks if a duplicate address exists, it reverts if duplicate address exists\n * @param approvers Array of address\n */\n function _checkApprover(\n address[] memory approvers\n ) internal pure returns (bool) {\n uint256 approverLength = approvers.length;\n if (0 == approverLength) revert ZeroApproverLength();\n for (uint256 i; i < approverLength - 1; ) {\n for (uint256 j = i + 1; j < approverLength; ) {\n if (approvers[i] == approvers[j]) {\n revert DuplicateApprover(); // Found a duplicate\n }\n unchecked {\n ++j;\n }\n }\n unchecked {\n ++i;\n }\n }\n return false; // No duplicates found\n }\n\n /**\n * @notice Checks if the facet getting added or replaced is registered to facet registry\n * @dev This method loops through the cut and checks if the facet getting added/replaced is registered to facet registry\n * @param _diamondCut Array of FacetCut, data for diamondCut defined in EIP-2535\n */\n function _checkFacetCutValidity(\n IDiamondCut.FacetCut[] memory _diamondCut\n ) internal view {\n uint256 diamondCutLength = _diamondCut.length;\n for (uint256 i; i < diamondCutLength; ) {\n if (\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Add ||\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Replace\n ) {\n if (\n !s.facetRegistry.areFacetFunctionSelectorsRegistered(\n _diamondCut[i].facetAddress,\n _diamondCut[i].functionSelectors\n )\n ) revert UnregisteredFacetAndSelectors();\n }\n unchecked {\n ++i;\n }\n }\n }\n}\n" + }, + "contracts/facets/RestrictionsFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, RestrictionsStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {IRestriction} from \"../restrictions/IRestriction.sol\";\nimport {IRestrictionsFacet} from \"./interfaces/IRestrictionsFacet.sol\";\n\n/**\n * @title Restrictions facet\n * @dev Responsible for storing and verifying different kinds of restrictions, for example:\n * - Whitelist / Blacklist\n * - Daily limits\n * - Trading time restrictions\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract RestrictionsFacet is IRestrictionsFacet {\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceRestrictionsInitialize();\n }\n\n /**\n * @notice Intialize restrictions of Barz. Restrictions facet call restriction contracts for restriction validation\n * before each call\n * @param _restrictions The initial array of restrictions.\n * @return initSuccess Int value showing if the initialization of restriction is successful\n */\n function initializeRestrictions(\n address[] calldata _restrictions\n ) public override returns (uint256 initSuccess) {\n LibDiamond.enforceIsSelf();\n LibAppStorage.enforceRestrictionsInitialize();\n\n uint256 restrictionsLength = _restrictions.length;\n if (restrictionsLength == 0) {\n // You can't initialize RestrictionsFacet with an empty list of restrictions\n revert RestrictionsFacet__EmptyRestrictionsList();\n }\n for (uint256 i; i < restrictionsLength; ) {\n if (_restrictions[i] == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictions();\n unchecked {\n ++i;\n }\n }\n\n LibFacetStorage.restrictionsStorage().restrictions = _restrictions;\n _updateRestrictionsMap(_restrictions, true);\n initSuccess = 1;\n }\n\n /**\n * @notice Unitialize restrictions of Barz\n * @return uninitSuccess Int value showing if the initialization of restriction is successful\n */\n function uninitializeRestrictions()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibDiamond.enforceIsSelf();\n LibAppStorage.setRestrictionsUninitialized();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n _updateRestrictionsMap(restrictionsStorage.restrictions, false);\n restrictionsStorage.restrictions = new address[](0);\n uninitSuccess = 1;\n }\n\n /**\n * @notice Returns the list of Restrictions contract address\n * @return restrictions Addresses of IRestriction which are currently active\n */\n function getRestrictions()\n public\n view\n override\n returns (address[] memory restrictions)\n {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n restrictions = restrictionsStorage.restrictions;\n }\n\n /**\n * @notice Adds restrictions to Barz with validation on the restriction contract address.\n * This method is only callable by the owner(self).\n * @param _restriction The address of the restriction to be added.\n */\n function addRestriction(address _restriction) external override {\n LibDiamond.enforceIsSelf();\n if (LibDiamond.restrictionsFacet() == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictionsFacet();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n if (_restriction == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictions();\n if (restrictionsStorage.exists[_restriction])\n revert RestrictionsFacet__RestrictionAlreadyExists();\n\n restrictionsStorage.restrictions.push(_restriction);\n restrictionsStorage.exists[_restriction] = true;\n\n emit RestrictionAdded(_restriction);\n }\n\n /**\n * @notice Remove restrictions from Barz if it existed. This method is only callable by the owner(self).\n * @param _restriction The address of the restriction to be removed.\n */\n function removeRestriction(address _restriction) external override {\n LibDiamond.enforceIsSelf();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n if (!restrictionsStorage.exists[_restriction])\n revert RestrictionsFacet__RestrictionNotFound();\n\n address[] storage restrictions = restrictionsStorage.restrictions;\n\n uint256 indexToDelete = restrictions.length;\n uint256 restrictionsLen = restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n if (restrictions[i] == _restriction) {\n indexToDelete = i;\n break;\n }\n unchecked {\n ++i;\n }\n }\n\n if (indexToDelete == 0 && restrictionsLen == 1) {\n revert RestrictionsFacet__RemainingRestrictionsCantBeEmpty();\n } else if (indexToDelete == restrictionsLen) {\n revert RestrictionsFacet__RestrictionNotFound();\n } else {\n restrictions[indexToDelete] = restrictions[restrictionsLen - 1];\n restrictions.pop();\n }\n\n restrictionsStorage.exists[_restriction] = false;\n emit RestrictionRemoved(_restriction);\n }\n\n /**\n * @notice Sets the restrictions address value mapping to true or false when adding/removing restriction contracts\n * @param _restrictions List of restriction contracts address\n * @param _newValue Bool value to flag to the list of restrictions contracts\n */\n function _updateRestrictionsMap(\n address[] memory _restrictions,\n bool _newValue\n ) internal {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n uint restrictionsLen = _restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n restrictionsStorage.exists[_restrictions[i]] = _newValue;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @dev Iterates over all restrictions and verifies each of them with the transaction parameters.\n * @param _from The address of the sender, that will be signing the transaction.\n * @param _to The receiving address.\n * @param _value Amount of ETH to transfer from sender to recipient.\n * @param _calldata Optional field to include arbitrary data.\n * @return 0 if all the checks passed, 1 otherwise.\n */\n function verifyRestrictions(\n address _from,\n address _to,\n uint256 _value,\n bytes calldata _calldata\n ) external returns (uint256) {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n uint restrictionsLen = restrictionsStorage.restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n IRestriction restriction = IRestriction(\n restrictionsStorage.restrictions[i]\n );\n bool checkPassed = restriction.check(_from, _to, _value, _calldata);\n if (!checkPassed) {\n return 1;\n }\n unchecked {\n ++i;\n }\n }\n\n return 0;\n }\n}\n" + }, + "contracts/facets/SignatureMigrationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, SignatureMigrationStorage, SignatureMigrationConfig, SignatureMigrationApprovalConfig, ApprovalConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IDiamondCut} from \"./base/interfaces/IDiamondCut.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {ISignatureMigrationFacet} from \"./interfaces/ISignatureMigrationFacet.sol\";\n\n/**\n * @title Signature Migration Facet\n * @dev Responsible for migrating user signature scheme to a new scheme user sets\n * Which could include\n * - ECDSA on Secp256K1 Curve\n * - ECDSA on Secp256R1 Curve\n * - BLS, Schnorr, etc\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract SignatureMigrationFacet is ISignatureMigrationFacet, Modifiers {\n /**\n * @notice This modifier verifies if the public key format matches with the new verification facet\n * @param _publicKey Bytes of public key to be validated for the new verification facet\n * @param _newVerificationFacet Address of new verification facet\n */\n modifier validateKeyType(\n bytes memory _publicKey,\n address _newVerificationFacet\n ) {\n if (\n !IVerificationFacet(_newVerificationFacet).isValidKeyType(\n _publicKey\n )\n ) revert SignatureMigrationFacet__InvalidKeyType();\n _;\n }\n\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n // IMPORTANT NOTE: In the client side when they call this function, the func selectors should be sorted in ascending order\n // to prevent different hash with same items in the array\n /**\n * @notice Moves the state of migration to a pending state. When pending state is over after pending period time,\n * Migration can be finalized. This function can only be called by self and when the account is unlocked.\n * @dev This method checks if the caller is self and if guardians exists. It migrates signature request to a pending state\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function migrateSignatureScheme(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n public\n override\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n // Only self contract can call this function\n LibDiamond.enforceIsSelf();\n // Should revert if guardian exist\n if (0 != LibGuardian.guardianCount())\n revert SignatureMigrationFacet__InvalidRouteWithGuardian();\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n // NOTE: Migration requires a pending period & confirmation from owner to prevent a\n // single call changing the ownership of the wallet\n /**\n * @notice Migrate signature scheme when guardians exists. Verifies the signature of guardians and moves migration to pending state.\n * Which can then be finalized when pending period is over. Owner's approval is mandatory for migration to happen\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _approvers List of approvers. This could include owner\n */\n function migrateSignatureSchemeWithGuardian(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n )\n public\n override\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n // Should revert if does not guardian exist\n if (0 == LibGuardian.guardianCount())\n revert SignatureMigrationFacet__InvalidRouteWithGuardian();\n uint256 approversLength = _approvers.length;\n if (approversLength != _signatures.length)\n revert SignatureMigrationFacet__InvalidArrayLength();\n\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(migrationPublicKeyHash, _approvers);\n\n bool onChainOwnerApproval = getMigrationOwnerApprovalWithTimeValidity(\n migrationPublicKeyHash\n );\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n\n if (\n approversLength +\n getMigrationApprovalCountWithTimeValidity(\n migrationPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert SignatureMigrationFacet__InsufficientApprovers();\n {\n // To prevent Stack too deep\n bool ownerApproved;\n for (uint256 i; i < approversLength; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n address(this) != _approvers[i]\n ) revert SignatureMigrationFacet__InvalidGuardian();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert SignatureMigrationFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n migrationPublicKeyHash,\n _signatures[i]\n )\n ) revert SignatureMigrationFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n\n if (!ownerApproved && !onChainOwnerApproval)\n revert SignatureMigrationFacet__LackOfOwnerApproval();\n }\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Internal function that moves signature mgiration to a pending state.\n * @dev This method increments migration nonce and sets the migration in the migration config. Emits events for migration execution\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _migrateSignatureScheme(\n address _newVerificationFacet,\n bytes memory _newPublicKey,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal {\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n\n ++ms.nonce;\n uint64 migrateAfter = uint64(block.timestamp + getMigrationPeriod());\n\n ms.migrationConfigs[INNER_STRUCT] = SignatureMigrationConfig(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n migrateAfter\n );\n\n emit SignatureMigrationExecuted(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors,\n migrateAfter\n );\n }\n\n /**\n * @notice Approves signature scheme migration on-chain. This can be called by owner or guardian only when the account is unlocked.\n * When the threshold of the migration approval passed and owner approval is granted, it automatically moves migration to a pending state\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function approveSignatureSchemeMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n public\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit SignatureMigrationApproved(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n msg.sender,\n approvalValidUntil\n );\n if (\n getMigrationApprovalCountWithTimeValidity(migrationPublicKeyHash) >=\n LibGuardian.majorityOfGuardians() &&\n getMigrationOwnerApprovalWithTimeValidity(migrationPublicKeyHash)\n )\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Revokes the approval of signature migration done on-chain. Emits revoke event when revoked.\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function revokeSignatureMigrationApproval(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n external\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n if (!isMigrationApproved(migrationPublicKeyHash, msg.sender))\n revert SignatureMigrationFacet__CannotRevokeUnapproved();\n\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(false, 0);\n emit SignatureMigrationApprovalRevoked(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n msg.sender\n );\n }\n\n /**\n * @notice Finalizes the pending signature scheme migration. This function can only be called by owner.\n * It removes the facets of the previous verification facet and adds the new verification facet.\n * After finalizing migration, it emits migration event which shows the change of the verification facet\n */\n function finalizeSignatureMigration() external override {\n // NOTE: Only owner can call this function\n LibDiamond.enforceIsSelf();\n\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n\n if (!isMigrationPending())\n revert SignatureMigrationFacet__NonexistentMigration();\n\n if (\n uint64(block.timestamp) <=\n ms.migrationConfigs[INNER_STRUCT].migrateAfter\n ) revert SignatureMigrationFacet__MigrationPeriodNotOver();\n address newVerificationFacet = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationVerificationFacet;\n bytes4[] memory newVerificationFuncSelectors = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationSelectors;\n bytes memory newPublicKey = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationPublicKey;\n\n address prevVerificationFacet = LibLoupe.facetAddress(\n s.validateOwnerSignatureSelector\n );\n if (prevVerificationFacet == address(0))\n revert SignatureMigrationFacet__NonExistentVerificationFacet();\n\n IDiamondCut.FacetCut[] memory UninitCut;\n IDiamondCut.FacetCut[] memory InitCut;\n {\n bytes4[] memory prevVerificationFuncSelectors = LibLoupe\n .facetFunctionSelectors(prevVerificationFacet);\n\n UninitCut = new IDiamondCut.FacetCut[](1);\n InitCut = new IDiamondCut.FacetCut[](1);\n UninitCut[0] = IDiamondCut.FacetCut({\n facetAddress: address(0),\n action: IDiamondCut.FacetCutAction.Remove,\n functionSelectors: prevVerificationFuncSelectors\n });\n InitCut[0] = IDiamondCut.FacetCut({\n facetAddress: newVerificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: newVerificationFuncSelectors\n });\n {\n IDiamondCut.FacetCut[]\n memory facetCuts = new IDiamondCut.FacetCut[](2);\n facetCuts[0] = UninitCut[0];\n facetCuts[1] = InitCut[0];\n _checkFacetCutValidity(facetCuts);\n }\n LibAppStorage.initiateSignerMigration();\n address verificationFacet = address(\n bytes20(\n LibDiamond.diamondStorage().facets[\n s.validateOwnerSignatureSelector\n ]\n )\n );\n bytes memory uninitCall = abi.encodeWithSignature(\n \"uninitializeSigner()\"\n );\n (bool success, bytes memory result) = verificationFacet\n .delegatecall(uninitCall);\n require(success, \"MigrationFacet: uninitialize not successful\");\n uint256 validationData = uint256(bytes32(result));\n if (validationData == 0)\n revert SignatureMigrationFacet__SignerUninitializationFailure();\n\n LibDiamond.diamondCut(UninitCut, address(0), \"\");\n }\n {\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n newPublicKey\n );\n\n // Every Verification Facet should comply with initializeSigner(bytes)\n // to be compatible with the Barz contract(for initialization)\n LibDiamond.diamondCut(InitCut, newVerificationFacet, initCall);\n LibAppStorage.finalizeSignerMigration();\n emit SignatureSchemeMigration(\n prevVerificationFacet,\n newVerificationFacet,\n newPublicKey,\n newVerificationFuncSelectors\n );\n }\n }\n\n /**\n * @notice Approve cancellation of signature migration. If cancellation approval passes guardian threshold with owner approval\n * it automatically cancels the migration.\n * @dev This method checks if the caller is one of guardian or owner and sets true for the cancellation hash in the approval config.\n * It internally calls _cancelSignatureMigration for canceling the migration\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function approveCancelSignatureMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n external\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"CancelSignatureMigration\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit SignatureMigrationCancellationApproved(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n if (\n getMigrationApprovalCountWithTimeValidity(migrationPublicKeyHash) >=\n LibGuardian.majorityOfGuardians() &&\n getMigrationOwnerApprovalWithTimeValidity(migrationPublicKeyHash)\n )\n _cancelSignatureMigration(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Verifies the signature of guardians/owner and cancels the signature migration.\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _approvers List of approvers. This could include owner\n */\n function cancelSignatureMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n )\n external\n override\n validateKeyType(_newPublicKey, _newVerificationFacet)\n onlyWhenUnlocked\n {\n uint256 approversLength = _approvers.length;\n if (approversLength != _signatures.length)\n revert SignatureMigrationFacet__InvalidArrayLength();\n\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"CancelSignatureMigration\"\n );\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(migrationPublicKeyHash, _approvers);\n\n bool onChainOwnerApproval = getMigrationOwnerApprovalWithTimeValidity(\n migrationPublicKeyHash\n );\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n if (\n approversLength +\n getMigrationApprovalCountWithTimeValidity(\n migrationPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert SignatureMigrationFacet__InsufficientApprovers();\n {\n // To prevent stack too deep\n bool ownerApproved;\n for (uint256 i; i < approversLength; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n address(this) != _approvers[i]\n ) revert SignatureMigrationFacet__NonExistentApprover();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert SignatureMigrationFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n migrationPublicKeyHash,\n _signatures[i]\n )\n ) revert SignatureMigrationFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n if (!ownerApproved && !onChainOwnerApproval)\n revert SignatureMigrationFacet__LackOfOwnerApproval();\n }\n _cancelSignatureMigration(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Internal function that cancels signature migration.\n * @dev This method increments migration nonce and deletes the migration from the migration config. Emits events for migration cancellation\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _cancelSignatureMigration(\n address _newVerificationFacet,\n bytes memory _newPublicKey,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal {\n if (!isMigrationPending())\n revert SignatureMigrationFacet__NonexistentMigration();\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n ++ms.nonce;\n delete ms.migrationConfigs[INNER_STRUCT];\n emit SignatureMigrationCanceled(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Checks if the facets to be added from new verification facet is registered to facet registry\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _checkMigrationCutValidity(\n address _newVerificationFacet,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal view {\n IDiamondCut.FacetCut[] memory facetCuts = new IDiamondCut.FacetCut[](1);\n facetCuts[0] = IDiamondCut.FacetCut({\n facetAddress: _newVerificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: _newVerificationFuncSelectors\n });\n _checkFacetCutValidity(facetCuts);\n }\n\n /**\n * @notice Returns if the migration is pending of not\n * @dev This method fetches the migration storage and checks if the migrate after is above 0 value\n * @return isPending Bool value that shows if the migration is pending\n */\n function isMigrationPending()\n public\n view\n override\n returns (bool isPending)\n {\n SignatureMigrationStorage storage rs = LibFacetStorage\n .migrationStorage();\n isPending = rs.migrationConfigs[INNER_STRUCT].migrateAfter > 0;\n }\n\n /**\n * @notice Returns the migration hash. This function ensures that this hash is safe from replay attack by including\n * public key, verification facet, function selectors, salt, address, chainId, and nonce.\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _saltString Salt value for generating the migration hash\n * @return migrationKeyHash Bytes32 string of the migration key hash\n */\n function getApprovalMigrationKeyHash(\n bytes memory _newPublicKey,\n address _newVerificationFacet,\n bytes4[] memory _newVerificationFuncSelectors,\n string memory _saltString\n ) public view override returns (bytes32 migrationKeyHash) {\n migrationKeyHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n _newPublicKey,\n _newVerificationFacet,\n keccak256(abi.encode(_newVerificationFuncSelectors)),\n _saltString,\n address(this),\n block.chainid,\n LibFacetStorage.migrationStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Checks if the owner approved the hash for migration\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @return isApprovedByOwner Bool value of showing if the owner approved it or not\n */\n function getMigrationOwnerApprovalWithTimeValidity(\n bytes32 _migrationPublicKeyHash\n ) public view override returns (bool isApprovedByOwner) {\n isApprovedByOwner = isMigrationApproved(\n _migrationPublicKeyHash,\n address(this)\n );\n }\n\n /**\n * @notice Checks how many of the guardians approved the migration hash\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @return approvalCount Number of approvals\n */\n function getMigrationApprovalCountWithTimeValidity(\n bytes32 _migrationPublicKeyHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardiansLength = guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n if (isMigrationApproved(_migrationPublicKeyHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n return approvalCount;\n }\n\n /**\n * @notice Checks if the migration is approved by the given approver\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @param _approver Address of approver\n * @return isApproved Bool value if migration hash is approved\n */\n function isMigrationApproved(\n bytes32 _migrationPublicKeyHash,\n address _approver\n ) public view override returns (bool isApproved) {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n isApproved = (ms\n .isMigrationApproved[_migrationPublicKeyHash][_approver].isApproved &&\n block.timestamp <\n ms\n .isMigrationApproved[_migrationPublicKeyHash][_approver]\n .validUntil);\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _migrationPublicKeyHash Hash of migration information\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _migrationPublicKeyHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isMigrationApproved(_migrationPublicKeyHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert SignatureMigrationFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the migration period of this wallet\n * @dev This method fetches the migration period from the security manager\n * @return migrationPeriod Migration period of Barz contract fetched from security manager\n */\n function getMigrationPeriod()\n internal\n view\n returns (uint128 migrationPeriod)\n {\n migrationPeriod = securityManager.migrationPeriodOf(address(this));\n if (migrationPeriod == 0)\n revert SignatureMigrationFacet__InvalidMigrationPeriod();\n }\n\n /**\n * @notice Returns the validation period of this wallet\n * @dev This method fetches the validation period from the security manager\n * @return approvalValidationPeriod Validation period of Barz contract fetched from security manager\n */\n function getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod == 0)\n revert SignatureMigrationFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the migration nonce of this wallet\n * @dev This method fetches the nonce from migration storage\n * @return migrationNonce Nonce of migration to protect from reply attacks\n */\n function getMigrationNonce()\n public\n view\n override\n returns (uint128 migrationNonce)\n {\n migrationNonce = LibFacetStorage.migrationStorage().nonce;\n }\n\n /**\n * @notice Returns the migration configuration of this wallet\n * @dev This method fetches the migration config from the migration storage\n * @return pendingMigrationConfig Migration config currently pending for signature migration\n */\n function getPendingMigration()\n external\n view\n override\n returns (SignatureMigrationConfig memory pendingMigrationConfig)\n {\n pendingMigrationConfig = LibFacetStorage\n .migrationStorage()\n .migrationConfigs[INNER_STRUCT];\n }\n}\n" + }, + "contracts/facets/TokenReceiverFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {IERC1155Receiver} from \"../interfaces/ERC/IERC1155Receiver.sol\";\nimport {IERC677Receiver} from \"../interfaces/ERC/IERC677Receiver.sol\";\n\n/**\n * @title TokenReceiver Facet\n * @dev Contract that enables receiving ERC721/ERC1155/ERC777/ERC677 Tokens with safe transfer\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract TokenReceiverFacet is\n IERC721Receiver,\n IERC1155Receiver,\n IERC777Recipient,\n IERC677Receiver\n{\n /**\n * @notice Handles ERC721 Token callback.\n * return Standardized onERC721Received return value.\n */\n function onERC721Received(\n address,\n address,\n uint256,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC721Receiver.onERC721Received.selector;\n }\n\n /**\n * @notice Handles ERC1155 Token callback.\n * return Standardized onERC1155Received return value.\n */\n function onERC1155Received(\n address,\n address,\n uint256,\n uint256,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC1155Receiver.onERC1155Received.selector;\n }\n\n /**\n * @notice Handles ERC1155 Token batch callback.\n * return Standardized onERC1155BatchReceived return value.\n */\n function onERC1155BatchReceived(\n address,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC1155Receiver.onERC1155BatchReceived.selector;\n }\n\n /**\n * @notice Handles ERC777 Token callback.\n * Does not return value, empty implementation.\n */\n function tokensReceived(\n address,\n address,\n address,\n uint256,\n bytes calldata,\n bytes calldata\n ) external pure override {}\n\n /**\n * @notice Handles ERC677 Token callback.\n * return true.\n */\n function onTokenTransfer(\n address,\n uint256,\n bytes calldata\n ) external pure override returns (bool) {\n return true;\n }\n}\n" + }, + "contracts/facets/verification/MultiSigFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {UserOperation} from \"../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../../libraries/LibLoupe.sol\";\nimport {LibAppStorage} from \"../../libraries/LibAppStorage.sol\";\nimport {LibMultiSigStorage, MultiSigStorage} from \"../../libraries/LibMultiSigStorage.sol\";\nimport {IERC1271} from \"../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../interfaces/IVerificationFacet.sol\";\nimport {IMultiSigFacet} from \"../interfaces/IMultiSigFacet.sol\";\n\n/**\n * @title Multi-sig facet\n * @dev Multi-signature Facet with custom threshold.\n * Wallet that adds this facet becomes a multi-sig wallet.\n * Reference signature_format.md documentation for Multi-sig facet details\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract MultiSigFacet is IMultiSigFacet, IVerificationFacet, IERC1271 {\n using ECDSA for bytes32;\n\n address public immutable self;\n\n address internal constant SENTINEL_OWNERS = address(0x1);\n uint256 internal constant ADDRESS = 20;\n uint256 internal constant SIG_TYPE = 1;\n uint256 internal constant SIG_LEN = 4;\n uint256 internal constant THRESHOLD = 4;\n uint256 internal constant INVALID_SIG = 1;\n uint256 internal constant VALID_SIG = 0;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in Multisig Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the right format and initializes signer storage in k1 storage.\n * @param _owners Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _owners\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n\n if (!isValidKeyType(_owners)) revert MultiSigFacet__InvalidInitData();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n uint256 threshold = uint256(uint32(bytes4(_owners)));\n uint256 ownerCount = (_owners.length - THRESHOLD) / ADDRESS;\n\n if (threshold == 0) revert MultiSigFacet__InvalidThreshold();\n if (ownerCount == 0) revert MultisigFacet__InvalidOwnerCount();\n\n address currentOwner = SENTINEL_OWNERS;\n uint256 ptr = THRESHOLD;\n address owner_;\n for (uint256 i; i < ownerCount; ) {\n owner_ = address(bytes20(_owners[ptr:ptr + ADDRESS]));\n ptr += ADDRESS;\n if (\n owner_ == address(0) ||\n owner_ == SENTINEL_OWNERS ||\n owner_ == address(this) ||\n owner_ == currentOwner\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[owner_] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n\n ms.owners[currentOwner] = owner_;\n currentOwner = owner_;\n\n unchecked {\n ++i;\n }\n }\n ms.owners[currentOwner] = SENTINEL_OWNERS;\n ms.ownerCount = ownerCount;\n ms.threshold = threshold;\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_owners);\n }\n\n /**\n * @notice Uninitialize signer in K1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n ++ms.counter;\n address[] memory ownerlist = getOwners();\n uint256 ownerlistLength = ownerlist.length;\n for (uint256 i; i < ownerlistLength; ) {\n ms.owners[ownerlist[i]] = address(0);\n unchecked {\n ++i;\n }\n }\n ms.owners[SENTINEL_OWNERS] = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls checkSignatures with\n * user operation hash and signature together with the threshold.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n // Data 1 is invalid, Data 0 is valid\n validationData = checkSignatures(\n userOpHash,\n userOp.signature,\n LibMultiSigStorage.multisigStorage().threshold\n );\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n return this.validateOwnerSignature.selector;\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n uint totalLength = ms.ownerCount * ADDRESS;\n bytes memory result = new bytes(totalLength);\n\n // populate return array\n uint256 index;\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n while (currentOwner != SENTINEL_OWNERS) {\n assembly {\n mstore(\n add(result, add(32, mul(index, ADDRESS))),\n shl(96, currentOwner)\n )\n }\n currentOwner = ms.owners[currentOwner];\n index++;\n }\n\n return result;\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key should comply with the format in the signature_format.md doc\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n uint256 publicKeyLength = _publicKey.length;\n if (\n publicKeyLength < ADDRESS + THRESHOLD ||\n (publicKeyLength - THRESHOLD) % ADDRESS != 0\n ) return false;\n\n uint256 threshold = uint256(uint32(bytes4(_publicKey)));\n uint256 ownerCount = (publicKeyLength - THRESHOLD) / ADDRESS;\n\n isValid = !(ownerCount < threshold || threshold == 0);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes calldata _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (checkSignatures(\n _hash,\n _signature,\n LibMultiSigStorage.multisigStorage().threshold\n ) == VALID_SIG)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n\n /**\n * @notice Validates the format of the signature and verifies if the signature is signed by the expected key.\n * Reference signature_format.md doc for details about signature format and signature types\n * @param _dataHash Bytes value of data hash signed by the owners\n * @param _signatures Bytes value of signature which should comply with signature format\n * @param _threshold Uint256 value of current Multi-sig Barz's threshold\n */\n function checkSignatures(\n bytes32 _dataHash,\n bytes calldata _signatures,\n uint256 _threshold\n ) public view returns (uint256) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n address lastOwner = address(0);\n address currentOwner;\n bytes memory signature;\n uint256 signatureType;\n uint256 nextOffset;\n uint256 i;\n for (i; i < _threshold; ) {\n (\n currentOwner,\n signature,\n signatureType,\n nextOffset\n ) = splitSignatures(_signatures, nextOffset);\n if (nextOffset == 0 && i + 1 < _threshold) return INVALID_SIG;\n if (signatureType == 1) {\n // If signatureType is 1 then it is default dataHash signed.\n // This also includes the contract signature\n if (\n !SignatureChecker.isValidSignatureNow(\n currentOwner,\n _dataHash,\n signature\n )\n ) return INVALID_SIG;\n } else if (signatureType == 2) {\n // If signatureType is 2 then it is an approved hash\n if (ms.approvedHashes[ms.counter][currentOwner][_dataHash] == 0)\n return INVALID_SIG;\n } else if (signatureType == 3) {\n // If signatureType is 3 then it is a signed message hash\n // This also includes the contract signature\n bytes32 msgHash = _dataHash.toEthSignedMessageHash();\n if (\n !SignatureChecker.isValidSignatureNow(\n currentOwner,\n msgHash,\n signature\n )\n ) return INVALID_SIG;\n } else revert MultiSigFacet__InvalidRoute();\n if (\n currentOwner <= lastOwner ||\n ms.owners[currentOwner] == address(0) ||\n currentOwner == SENTINEL_OWNERS\n ) return INVALID_SIG;\n lastOwner = currentOwner;\n\n unchecked {\n ++i;\n }\n }\n return VALID_SIG;\n }\n\n /**\n * @notice Split signatures into each individual signatures. Should comply with signature format to be split\n * @param _signatures Bytes value of signature\n * @param _nextOffset Uint256 value of next offset to start splitting the signature\n */\n function splitSignatures(\n bytes calldata _signatures,\n uint256 _nextOffset\n )\n public\n pure\n returns (\n address owner_,\n bytes memory signature,\n uint256 signatureType,\n uint256 nextOffset\n )\n {\n uint256 signaturesLength = _signatures.length;\n\n if (signaturesLength <= _nextOffset + ADDRESS + SIG_LEN)\n revert MultiSigFacet__InsufficientSignerLength();\n\n owner_ = address(\n bytes20(_signatures[_nextOffset:_nextOffset + ADDRESS])\n );\n\n signatureType = uint256(\n uint8(\n bytes1(\n _signatures[_nextOffset + ADDRESS:_nextOffset +\n ADDRESS +\n SIG_TYPE]\n )\n )\n );\n\n if (signatureType > 3 || signatureType == 0)\n revert MultiSigFacet__InvalidSignatureType();\n uint256 offSet = _nextOffset + ADDRESS + SIG_TYPE;\n uint256 siglen = uint256(\n uint32(bytes4(_signatures[offSet:offSet + SIG_LEN]))\n );\n if (offSet + siglen > signaturesLength)\n revert MultiSigFacet__InvalidSignatureLength();\n\n offSet += SIG_LEN;\n if (offSet + siglen == signaturesLength) nextOffset = 0;\n else nextOffset = offSet + siglen;\n\n signature = _signatures[offSet:offSet + siglen];\n }\n\n /**\n * @notice Approves the hash of userOperation on-chain. This can only be called by owners.\n * @param _hashToApprove Bytes value of UserOperation hash to approve\n */\n function approveHash(bytes32 _hashToApprove) external {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (ms.owners[msg.sender] == address(0))\n revert MultiSigFacet__OnlyOwner();\n\n ms.approvedHashes[ms.counter][msg.sender][_hashToApprove] = 1;\n emit HashApproved(_hashToApprove, msg.sender);\n }\n\n /**\n * @notice Add owner to Barz. Update thresold if threshold is given different from current threshold\n * @dev This can only be done via a Self call.\n * @param _newOwner Address of new owner to be added\n * @param _threshold Uint256 value of threshold\n */\n function addOwner(address _newOwner, uint256 _threshold) external {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (\n _newOwner == address(0) ||\n _newOwner == SENTINEL_OWNERS ||\n _newOwner == address(this)\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_newOwner] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n\n ms.owners[_newOwner] = ms.owners[SENTINEL_OWNERS];\n ms.owners[SENTINEL_OWNERS] = _newOwner;\n ++ms.ownerCount;\n emit OwnerAdded(_newOwner);\n\n if (ms.threshold != _threshold) changeThreshold(_threshold);\n }\n\n /**\n * @notice Remove owner from Barz. Update thresold if threshold is given different from current threshold\n * @dev This can only be done via a Self call.\n * @param _prevOwner Address of owner located right behind the removed owner address in the linked list\n * @param _removedOwner Address of owner to be removed\n * @param _threshold Uint256 value of threshold\n */\n function removeOwner(\n address _prevOwner,\n address _removedOwner,\n uint256 _threshold\n ) external {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (ms.ownerCount - 1 < _threshold)\n revert MultiSigFacet__InvalidThreshold();\n if (_removedOwner == address(0) || _removedOwner == SENTINEL_OWNERS)\n revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_prevOwner] != _removedOwner)\n revert MultiSigFacet__InvalidOwnerPair();\n\n ms.owners[_prevOwner] = ms.owners[_removedOwner];\n ms.owners[_removedOwner] = address(0);\n --ms.ownerCount;\n emit OwnerRemoved(_removedOwner);\n\n if (ms.threshold != _threshold) changeThreshold(_threshold);\n }\n\n /**\n * @notice Swap owner in Barz.\n * @dev This can only be done via a Self call.\n * @param _prevOwner Address of owner located right behind the removed owner address in the linked list\n * @param _oldOwner Address of owner to be removed\n * @param _newOwner Address of owner to be added\n */\n function swapOwner(\n address _prevOwner,\n address _oldOwner,\n address _newOwner\n ) public {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (\n _newOwner == address(0) ||\n _newOwner == SENTINEL_OWNERS ||\n _newOwner == address(this)\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_newOwner] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n if (_oldOwner == address(0) || _oldOwner == SENTINEL_OWNERS)\n revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_prevOwner] != _oldOwner)\n revert MultiSigFacet__InvalidOwnerPair();\n\n ms.owners[_newOwner] = ms.owners[_oldOwner];\n ms.owners[_prevOwner] = _newOwner;\n ms.owners[_oldOwner] = address(0);\n emit OwnerRemoved(_oldOwner);\n emit OwnerAdded(_newOwner);\n }\n\n /**\n * @notice Changes the threshold of the Barz to `_threshold`.\n * @dev This can only be done via a Self call.\n * @param _threshold New threshold\n */\n function changeThreshold(uint256 _threshold) public {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (_threshold > ms.ownerCount || _threshold == 0)\n revert MultiSigFacet__InvalidThreshold();\n\n ms.threshold = _threshold;\n emit ThresholdChanged(_threshold);\n }\n\n /**\n * @notice Checks if the given address is owner\n * @param _owner Address to be checked if it's owner\n * @return isOwner_ Bool value showing if it's owner address\n */\n function isOwner(address _owner) public view returns (bool isOwner_) {\n isOwner_ = (_owner != SENTINEL_OWNERS &&\n LibMultiSigStorage.multisigStorage().owners[_owner] != address(0));\n }\n\n /**\n * @notice Returns the threshold of Barz\n * @return threshold Threshold of the Barz account\n */\n function getThreshold() public view returns (uint256 threshold) {\n threshold = LibMultiSigStorage.multisigStorage().threshold;\n }\n\n /**\n * @notice Returns the list of owner addresses\n * @return owners List of owners\n */\n function getOwners() public view returns (address[] memory owners) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n owners = new address[](ms.ownerCount);\n\n uint256 index;\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n while (currentOwner != SENTINEL_OWNERS) {\n owners[index] = currentOwner;\n currentOwner = ms.owners[currentOwner];\n index++;\n }\n }\n\n /**\n * @notice Returns the previous owner in the linked list\n * @param _owner Address of owner\n * @return prevOwner Address of previous owner\n */\n function getPrevOwner(\n address _owner\n ) public view returns (address prevOwner) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n if (currentOwner == _owner) return SENTINEL_OWNERS;\n while (currentOwner != SENTINEL_OWNERS) {\n if (ms.owners[currentOwner] == _owner) return currentOwner;\n\n currentOwner = ms.owners[currentOwner];\n }\n return address(0);\n }\n\n /**\n * @notice Returns of the owner is approved by given owner address\n * @param _owner Address of owner\n * @param _hash Hash of UserOperation\n * @return isApproved Bool value showing if the hash is approved by owner\n */\n function isApprovedHash(\n address _owner,\n bytes32 _hash\n ) public view returns (bool isApproved) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n isApproved = (ms.approvedHashes[ms.counter][_owner][_hash] == 1);\n }\n}\n" + }, + "contracts/facets/verification/secp256k1/Secp256k1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {UserOperation} from \"../../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibAppStorage} from \"../../../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, Secp256k1VerificationStorage} from \"../../../libraries/LibFacetStorage.sol\";\nimport {LibLoupe} from \"../../../libraries/LibLoupe.sol\";\nimport {IERC1271} from \"../../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../../interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Secp256k1 verification facet\n * @dev Default Ethereum's elliptic curve\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract Secp256k1VerificationFacet is IVerificationFacet, IERC1271 {\n using ECDSA for bytes32;\n error Secp256k1VerificationFacet__InvalidSignerLength();\n address public immutable self;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in K1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\n * @param _publicKey Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _publicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n if (!isValidKeyType(_publicKey))\n revert Secp256k1VerificationFacet__InvalidSignerLength();\n\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(uint160(uint256(keccak256(_publicKey[1:]))));\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_publicKey);\n }\n\n /**\n * @notice Uninitialize signer in K1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\n * signer public key.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n validationData = validateSignature(\n userOp,\n userOpHash,\n k1Storage.signer\n );\n }\n\n /**\n * @notice Validates if the signature of UserOperation is signed by the given signer\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @param signer Address of signer who signed the contract, to be validated\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n address signer\n ) public pure returns (uint256 isValid) {\n bytes32 hash = userOpHash.toEthSignedMessageHash();\n isValid = (signer != hash.recover(userOp.signature)) ? 1 : 0;\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n ownerSignatureValidatorSelector = this.validateOwnerSignature.selector;\n // NOTE: The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory signer) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n signer = abi.encodePacked(k1Storage.signer);\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key length should be 65 in an uncompressed public key format\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (_hash.recover(_signature) ==\n LibFacetStorage.k1Storage().signer)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/Secp256r1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {UserOperation} from \"../../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibAppStorage} from \"../../../libraries/LibAppStorage.sol\";\nimport {LibLoupe} from \"../../../libraries/LibLoupe.sol\";\nimport {LibFacetStorage, Secp256r1VerificationStorage} from \"../../../libraries/LibFacetStorage.sol\";\nimport {Base64} from \"./utils/Base64.sol\";\nimport {LibSecp256r1} from \"./utils/LibSecp256r1.sol\";\nimport {IERC1271} from \"../../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../../interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Secp256r1 verification facet\n * @dev Primarily used to verify user ops signed with passkeys\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract Secp256r1VerificationFacet is IVerificationFacet, IERC1271 {\n error Secp256r1VerificationFacet__InvalidSignerLength();\n address public immutable self;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in R1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\n * @param _publicKey Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _publicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n\n if (!isValidKeyType(_publicKey))\n revert Secp256r1VerificationFacet__InvalidSignerLength();\n\n bytes memory publicKeyCoordinates = _publicKey[1:];\n uint256[2] memory q;\n assembly {\n // Copy the bytes from the input data into the uint256 array\n mstore(q, mload(add(publicKeyCoordinates, 32)))\n mstore(add(q, 32), mload(add(publicKeyCoordinates, 64)))\n }\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n r1Storage.q = q;\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_publicKey);\n }\n\n /**\n * @notice Uninitialize signer in R1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n r1Storage.q = [0, 0];\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\n * signer public key.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n validationData = validateSignature(userOp, userOpHash, r1Storage.q);\n }\n\n /**\n * @notice Validates if the signature of UserOperation is signed by the given signer\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @param q Public Key of signer who signed the contract, to be validated\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256[2] memory q\n ) public view returns (uint256 isValid) {\n isValid = (_validateSignature(q, userOpHash, userOp.signature)) ? 0 : 1;\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n return this.validateOwnerSignature.selector; // validateOwnerSignature(UserOperation calldata userOp,bytes32 userOpHash)\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory signer) {\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n signer = abi.encodePacked(r1Storage.q);\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key should in an uncompressed public key format\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = _validateSignature(\n LibFacetStorage.r1Storage().q,\n _hash,\n _signature\n )\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n\n function _validateSignature(\n uint256[2] memory q,\n bytes32 _hash,\n bytes memory _signature\n ) internal view returns (bool) {\n (\n uint256 rValue,\n uint256 sValue,\n bytes memory authenticatorData,\n string memory clientDataJSONPre,\n string memory clientDataJSONPost\n ) = abi.decode(_signature, (uint256, uint256, bytes, string, string));\n bytes32 clientHash;\n {\n string memory opHashBase64 = Base64.encode(bytes.concat(_hash));\n string memory clientDataJSON = string.concat(\n clientDataJSONPre,\n opHashBase64,\n clientDataJSONPost\n );\n clientHash = sha256(bytes(clientDataJSON));\n }\n bytes32 sigHash = sha256(bytes.concat(authenticatorData, clientHash));\n return LibSecp256r1.Verify(q, rValue, sValue, uint256(sigHash));\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/utils/Base64.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @dev Provides a set of functions to operate with Base64 strings.\n * modified for base64url https://datatracker.ietf.org/doc/html/rfc4648#section-5\n * _Available since v4.5._\n */\nlibrary Base64 {\n /**\n * @dev Base64 Encoding/Decoding Table\n */\n string internal constant _TABLE =\n \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_\";\n\n /**\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\n */\n function encode(bytes memory data) internal pure returns (string memory) {\n /**\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\n */\n if (data.length == 0) return \"\";\n\n // Loads the table into memory\n string memory table = _TABLE;\n\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\n // and split into 4 numbers of 6 bits.\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\n // - `data.length + 2` -> Round up\n // - `/ 3` -> Number of 3-bytes chunks\n // - `4 *` -> 4 characters for each chunk\n uint256 newlength = (data.length * 8) / 6;\n if (data.length % 6 > 0) {\n newlength++;\n }\n string memory result = new string(newlength);\n\n /// @solidity memory-safe-assembly\n assembly {\n // Prepare the lookup table (skip the first \"length\" byte)\n let tablePtr := add(table, 1)\n\n // Prepare result pointer, jump over length\n let resultPtr := add(result, 32)\n\n // Run over the input, 3 bytes at a time\n for {\n let dataPtr := data\n let endPtr := add(data, mload(data))\n } lt(dataPtr, endPtr) {\n\n } {\n // Advance 3 bytes\n dataPtr := add(dataPtr, 3)\n let input := mload(dataPtr)\n\n // To write each character, shift the 3 bytes (18 bits) chunk\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\n // and apply logical AND with 0x3F which is the number of\n // the previous character in the ASCII table prior to the Base64 Table\n // The result is then added to the table to get the character to write,\n // and finally write it in the result pointer but with a left shift\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(18, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(12, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(6, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n }\n }\n\n return result;\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/utils/LibSecp256r1.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n// Heavily inspired from\n// https://github.com/maxrobot/elliptic-solidity/blob/master/contracts/Secp256r1.sol\n// https://github.com/tdrerup/elliptic-curve-solidity/blob/master/contracts/curves/EllipticCurve.sol\n// modified to use precompile 0x05 modexp\n// and modified jacobian double\n// optimisations to avoid to an from from affine and jacobian coordinates\n\n// Additional Elliptic curve Public key / Signature validation added by\n// David Yonjun Kim (@Powerstream3604)\n\nstruct JPoint {\n uint256 x;\n uint256 y;\n uint256 z;\n}\n\nlibrary LibSecp256r1 {\n uint256 constant gx =\n 0x6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296;\n uint256 constant gy =\n 0x4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5;\n uint256 public constant pp =\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF;\n\n uint256 public constant nn =\n 0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551;\n uint256 constant a =\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC;\n uint256 constant b =\n 0x5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B;\n uint256 constant MOST_SIGNIFICANT =\n 0xc000000000000000000000000000000000000000000000000000000000000000;\n\n /*\n * Verify\n * @description - verifies that a public key has signed a given message\n * @param Q - public key coordinates X & Y\n * @param R - signature half R\n * @param S - signature half S\n * @param input - hashed message\n */\n function Verify(\n uint256[2] memory q,\n uint r,\n uint s,\n uint e\n ) internal view returns (bool) {\n if (q[0] > pp - 1 || q[1] > pp - 1) {\n return false;\n }\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\n return false;\n }\n if (\n mulmod(q[1], q[1], pp) !=\n addmod(\n addmod(\n mulmod(q[0], mulmod(q[0], q[0], pp), pp),\n mulmod(a, q[0], pp),\n pp\n ),\n b,\n pp\n )\n ) {\n return false;\n }\n\n JPoint[16] memory points = _preComputeJacobianPoints(q);\n return VerifyWithPrecompute(points, r, s, e);\n }\n\n function VerifyWithPrecompute(\n JPoint[16] memory points,\n uint r,\n uint s,\n uint e\n ) internal view returns (bool) {\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\n return false;\n }\n\n uint w = _primemod(s, nn);\n\n uint u1 = mulmod(e, w, nn);\n uint u2 = mulmod(r, w, nn);\n\n uint x;\n uint y;\n\n (x, y) = ShamirMultJacobian(points, u1, u2);\n return (x == r);\n }\n\n /*\n * Strauss Shamir trick for EC multiplication\n * https://stackoverflow.com/questions/50993471/ec-scalar-multiplication-with-strauss-shamir-method\n * we optimise on this a bit to do with 2 bits at a time rather than a single bit\n * the individual points for a single pass are precomputed\n * overall this reduces the number of additions while keeping the same number of doublings\n */\n function ShamirMultJacobian(\n JPoint[16] memory points,\n uint u1,\n uint u2\n ) internal view returns (uint, uint) {\n uint x = 0;\n uint y = 0;\n uint z = 0;\n uint bits = 128;\n uint index = 0;\n\n while (bits > 0) {\n if (z > 0) {\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\n }\n index =\n ((u1 & MOST_SIGNIFICANT) >> 252) |\n ((u2 & MOST_SIGNIFICANT) >> 254);\n if (index > 0) {\n (x, y, z) = _jAdd(\n x,\n y,\n z,\n points[index].x,\n points[index].y,\n points[index].z\n );\n }\n u1 <<= 2;\n u2 <<= 2;\n bits--;\n }\n (x, y) = _affineFromJacobian(x, y, z);\n return (x, y);\n }\n\n function _preComputeJacobianPoints(\n uint256[2] memory q\n ) internal pure returns (JPoint[16] memory points) {\n points[0] = JPoint(0, 0, 0);\n points[1] = JPoint(q[0], q[1], 1); // u2\n points[2] = _jPointDouble(points[1]);\n points[3] = _jPointAdd(points[1], points[2]);\n\n points[4] = JPoint(gx, gy, 1); // u1Points[1]\n points[5] = _jPointAdd(points[4], points[1]);\n points[6] = _jPointAdd(points[4], points[2]);\n points[7] = _jPointAdd(points[4], points[3]);\n\n points[8] = _jPointDouble(points[4]); // u1Points[2]\n points[9] = _jPointAdd(points[8], points[1]);\n points[10] = _jPointAdd(points[8], points[2]);\n points[11] = _jPointAdd(points[8], points[3]);\n\n points[12] = _jPointAdd(points[4], points[8]); // u1Points[3]\n points[13] = _jPointAdd(points[12], points[1]);\n points[14] = _jPointAdd(points[12], points[2]);\n points[15] = _jPointAdd(points[12], points[3]);\n }\n\n function _jPointAdd(\n JPoint memory p1,\n JPoint memory p2\n ) internal pure returns (JPoint memory) {\n uint x;\n uint y;\n uint z;\n (x, y, z) = _jAdd(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z);\n return JPoint(x, y, z);\n }\n\n function _jPointDouble(\n JPoint memory p\n ) internal pure returns (JPoint memory) {\n uint x;\n uint y;\n uint z;\n (x, y, z) = _modifiedJacobianDouble(p.x, p.y, p.z);\n return JPoint(x, y, z);\n }\n\n /* _affineFromJacobian\n * @desription returns affine coordinates from a jacobian input follows\n * golang elliptic/crypto library\n */\n function _affineFromJacobian(\n uint x,\n uint y,\n uint z\n ) internal view returns (uint ax, uint ay) {\n if (z == 0) {\n return (0, 0);\n }\n\n uint zinv = _primemod(z, pp);\n uint zinvsq = mulmod(zinv, zinv, pp);\n\n ax = mulmod(x, zinvsq, pp);\n ay = mulmod(y, mulmod(zinvsq, zinv, pp), pp);\n }\n\n /*\n * _jAdd\n * @description performs Jacobian addition as defined below:\n * http://www.hyperelliptic.org/EFD/g1p/data/shortw/jacobian/addition/add-2007-bl\n */\n function _jAdd(\n uint p1,\n uint p2,\n uint p3,\n uint q1,\n uint q2,\n uint q3\n ) internal pure returns (uint r1, uint r2, uint r3) {\n if (p3 == 0) {\n r1 = q1;\n r2 = q2;\n r3 = q3;\n\n return (r1, r2, r3);\n } else if (q3 == 0) {\n r1 = p1;\n r2 = p2;\n r3 = p3;\n\n return (r1, r2, r3);\n }\n\n assembly {\n let\n pd\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\n let z1z1 := mulmod(p3, p3, pd) // Z1Z1 = Z1^2\n let z2z2 := mulmod(q3, q3, pd) // Z2Z2 = Z2^2\n\n let u1 := mulmod(p1, z2z2, pd) // U1 = X1*Z2Z2\n let u2 := mulmod(q1, z1z1, pd) // U2 = X2*Z1Z1\n\n let s1 := mulmod(p2, mulmod(z2z2, q3, pd), pd) // S1 = Y1*Z2*Z2Z2\n let s2 := mulmod(q2, mulmod(z1z1, p3, pd), pd) // S2 = Y2*Z1*Z1Z1\n\n let p3q3 := addmod(p3, q3, pd)\n\n if lt(u2, u1) {\n u2 := add(pd, u2) // u2 = u2+pd\n }\n let h := sub(u2, u1) // H = U2-U1\n\n let i := mulmod(0x02, h, pd)\n i := mulmod(i, i, pd) // I = (2*H)^2\n\n let j := mulmod(h, i, pd) // J = H*I\n if lt(s2, s1) {\n s2 := add(pd, s2) // u2 = u2+pd\n }\n let rr := mulmod(0x02, sub(s2, s1), pd) // r = 2*(S2-S1)\n r1 := mulmod(rr, rr, pd) // X3 = R^2\n\n let v := mulmod(u1, i, pd) // V = U1*I\n let j2v := addmod(j, mulmod(0x02, v, pd), pd)\n if lt(r1, j2v) {\n r1 := add(pd, r1) // X3 = X3+pd\n }\n r1 := sub(r1, j2v)\n\n // Y3 = r*(V-X3)-2*S1*J\n let s12j := mulmod(mulmod(0x02, s1, pd), j, pd)\n\n if lt(v, r1) {\n v := add(pd, v)\n }\n r2 := mulmod(rr, sub(v, r1), pd)\n\n if lt(r2, s12j) {\n r2 := add(pd, r2)\n }\n r2 := sub(r2, s12j)\n\n // Z3 = ((Z1+Z2)^2-Z1Z1-Z2Z2)*H\n z1z1 := addmod(z1z1, z2z2, pd)\n j2v := mulmod(p3q3, p3q3, pd)\n if lt(j2v, z1z1) {\n j2v := add(pd, j2v)\n }\n r3 := mulmod(sub(j2v, z1z1), h, pd)\n }\n return (r1, r2, r3);\n }\n\n // Point doubling on the modified jacobian coordinates\n // http://point-at-infinity.org/ecc/Prime_Curve_Modified_Jacobian_Coordinates.html\n function _modifiedJacobianDouble(\n uint x,\n uint y,\n uint z\n ) internal pure returns (uint x3, uint y3, uint z3) {\n if (y == 0) return (0, 0, 0);\n assembly {\n let\n pd\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\n let z2 := mulmod(z, z, pd)\n let az4 := mulmod(\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC,\n mulmod(z2, z2, pd),\n pd\n )\n let y2 := mulmod(y, y, pd)\n let s := mulmod(0x04, mulmod(x, y2, pd), pd)\n let u := mulmod(0x08, mulmod(y2, y2, pd), pd)\n let m := addmod(mulmod(0x03, mulmod(x, x, pd), pd), az4, pd)\n let twos := mulmod(0x02, s, pd)\n let m2 := mulmod(m, m, pd)\n if lt(m2, twos) {\n m2 := add(pd, m2)\n }\n x3 := sub(m2, twos)\n if lt(s, x3) {\n s := add(pd, s)\n }\n y3 := mulmod(m, sub(s, x3), pd)\n if lt(y3, u) {\n y3 := add(pd, y3)\n }\n y3 := sub(y3, u)\n z3 := mulmod(0x02, mulmod(y, z, pd), pd)\n }\n }\n\n // Fermats little theorem https://en.wikipedia.org/wiki/Fermat%27s_little_theorem\n // a^(p-1) = 1 mod p\n // a^(-1) ≅ a^(p-2) (mod p)\n // we then use the precompile bigModExp to compute a^(-1)\n function _primemod(uint value, uint p) internal view returns (uint ret) {\n ret = modexp(value, p - 2, p);\n return ret;\n }\n\n // Wrapper for built-in BigNumber_modexp (contract 0x5) as described here. https://github.com/ethereum/EIPs/pull/198\n function modexp(\n uint _base,\n uint _exp,\n uint _mod\n ) internal view returns (uint ret) {\n // bigModExp(_base, _exp, _mod);\n assembly {\n if gt(_base, _mod) {\n _base := mod(_base, _mod)\n }\n // Free memory pointer is always stored at 0x40\n let freemem := mload(0x40)\n\n mstore(freemem, 0x20)\n mstore(add(freemem, 0x20), 0x20)\n mstore(add(freemem, 0x40), 0x20)\n\n mstore(add(freemem, 0x60), _base)\n mstore(add(freemem, 0x80), _exp)\n mstore(add(freemem, 0xa0), _mod)\n\n let success := staticcall(14000, 0x5, freemem, 0xc0, freemem, 0x20)\n switch success\n case 0 {\n revert(0x0, 0x0)\n }\n default {\n ret := mload(freemem)\n }\n }\n }\n}\n" + }, + "contracts/infrastructure/DefaultFallbackHandler.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC1155Receiver} from \"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\";\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {BaseAccount} from \"../aa-4337/core/BaseAccount.sol\";\nimport {DefaultLibDiamond} from \"../libraries/DefaultLibDiamond.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IAccountFacet} from \"../facets/interfaces/IAccountFacet.sol\";\nimport {IStorageLoupe} from \"../facets/base/interfaces/IStorageLoupe.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IERC677Receiver} from \"../interfaces/ERC/IERC677Receiver.sol\";\nimport {IERC165} from \"../interfaces/ERC/IERC165.sol\";\n\n/**\n * @title DefaultFallbackHandler\n * @dev A default fallback handler for Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DefaultFallbackHandler is IDiamondLoupe {\n /**\n * @notice Sets the middleware diamond for Barz wallet as a fallback handler\n * @dev This contract is also a diamond that holds the default facets to reduce gas cost for wallet activation.\n * Within the constructor this conducts diamond cut to initially setup the diamond. This is a non-upgradeable contract\n * @param _diamondCutFacet Address if diamond cut facet\n * @param _accountFacet Address account facet\n * @param _tokenReceiverFacet Address of token receiver facet\n * @param _diamondLoupeFacet Address of diamond loupe facet\n */\n constructor(\n address _diamondCutFacet,\n address _accountFacet,\n address _tokenReceiverFacet,\n address _diamondLoupeFacet\n ) payable {\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](4);\n bytes4[] memory functionSelectors = new bytes4[](1);\n functionSelectors[0] = IDiamondCut.diamondCut.selector;\n\n bytes4[] memory accountFunctionSelectors = new bytes4[](5);\n accountFunctionSelectors[0] = IAccountFacet.execute.selector;\n accountFunctionSelectors[1] = IAccountFacet.executeBatch.selector;\n accountFunctionSelectors[2] = BaseAccount.validateUserOp.selector;\n accountFunctionSelectors[3] = BaseAccount.getNonce.selector;\n accountFunctionSelectors[4] = BaseAccount.entryPoint.selector;\n\n bytes4[] memory receiverFacetSelectors = new bytes4[](5);\n receiverFacetSelectors[0] = IERC721Receiver.onERC721Received.selector;\n receiverFacetSelectors[1] = IERC1155Receiver.onERC1155Received.selector;\n receiverFacetSelectors[2] = IERC1155Receiver\n .onERC1155BatchReceived\n .selector;\n receiverFacetSelectors[3] = IERC777Recipient.tokensReceived.selector;\n receiverFacetSelectors[4] = IERC677Receiver.onTokenTransfer.selector;\n\n bytes4[] memory loupeFacetSelectors = new bytes4[](9);\n loupeFacetSelectors[0] = IDiamondLoupe.facets.selector;\n loupeFacetSelectors[1] = IDiamondLoupe.facetFunctionSelectors.selector;\n loupeFacetSelectors[2] = IDiamondLoupe.facetAddresses.selector;\n loupeFacetSelectors[3] = IDiamondLoupe.facetAddress.selector;\n loupeFacetSelectors[4] = IERC165.supportsInterface.selector;\n loupeFacetSelectors[5] = IStorageLoupe.facetsFromStorage.selector;\n loupeFacetSelectors[6] = IStorageLoupe\n .facetFunctionSelectorsFromStorage\n .selector;\n loupeFacetSelectors[7] = IStorageLoupe\n .facetAddressesFromStorage\n .selector;\n loupeFacetSelectors[8] = IStorageLoupe.facetAddressFromStorage.selector;\n\n {\n cut[0] = IDiamondCut.FacetCut({\n facetAddress: _diamondCutFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: functionSelectors\n });\n cut[1] = IDiamondCut.FacetCut({\n facetAddress: _accountFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: accountFunctionSelectors\n });\n cut[2] = IDiamondCut.FacetCut({\n facetAddress: _tokenReceiverFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: receiverFacetSelectors\n });\n cut[3] = IDiamondCut.FacetCut({\n facetAddress: _diamondLoupeFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: loupeFacetSelectors\n });\n\n DefaultLibDiamond.diamondCut(cut, address(0), \"\");\n }\n }\n\n /**\n * @notice Returns the facet information of call facets registered to this diamond.\n * @return facets_ The facet struct array including all facet information\n */\n function facets() external view override returns (Facet[] memory facets_) {\n DefaultLibDiamond.DiamondStorage storage ds = DefaultLibDiamond\n .diamondStorage();\n uint256 numFacets = ds.facetAddresses.length;\n facets_ = new Facet[](numFacets);\n for (uint256 i; i < numFacets; ) {\n address facetAddress_ = ds.facetAddresses[i];\n facets_[i].facetAddress = facetAddress_;\n facets_[i].functionSelectors = ds\n .facetFunctionSelectors[facetAddress_]\n .functionSelectors;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Gets all the function selectors provided by a facet.\n * @param _facet The facet address.\n * @return facetFunctionSelectors_\n */\n function facetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n facetFunctionSelectors_ = DefaultLibDiamond\n .diamondStorage()\n .facetFunctionSelectors[_facet]\n .functionSelectors;\n }\n\n /**\n * @notice Get all the facet addresses used by a diamond.\n * @return facetAddresses_\n */\n function facetAddresses()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n facetAddresses_ = DefaultLibDiamond.diamondStorage().facetAddresses;\n }\n\n /** @notice Gets the facet that supports the given selector.\n * @dev If facet is not found return address(0).\n * @param _functionSelector The function selector.\n * @return facetAddress_ The facet address.\n */\n function facetAddress(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n facetAddress_ = DefaultLibDiamond\n .diamondStorage()\n .selectorToFacetAndPosition[_functionSelector]\n .facetAddress;\n }\n}\n" + }, + "contracts/infrastructure/FacetRegistry.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport {IFacetRegistry} from \"./interfaces/IFacetRegistry.sol\";\n\n/**\n * @title Facet Registry\n * @dev Contract to keep track of facets & function selectors addable to user wallets\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract FacetRegistry is IFacetRegistry, Ownable2Step {\n mapping(address => FacetRegistryConfig) private facets;\n\n /**\n * @notice Transfers the ownership of the contract to the given owner\n * @param _owner Address of owner who has access to initialize the default security variables for security manager\n */\n constructor(address _owner) {\n transferOwnership(_owner);\n _transferOwnership(_owner);\n }\n\n /**\n * @dev Registers a facet and it's function selectors to registry\n * @param _facet address of facet\n * @param _facetSelectors list of function selectors of the facet\n */\n function registerFacetFunctionSelectors(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external override onlyOwner {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n uint256 facetSelectorsLength = _facetSelectors.length;\n for (uint256 i; i < facetSelectorsLength; ) {\n if (facetConfig.info[_facetSelectors[i]].exists)\n revert FacetRegistry__FacetSelectorAlreadyRegistered();\n\n facetConfig.info[_facetSelectors[i]].exists = true;\n facetConfig.info[_facetSelectors[i]].index = uint128(\n facetConfig.selectors.length\n );\n facetConfig.selectors.push(_facetSelectors[i]);\n unchecked {\n ++i;\n }\n }\n emit FacetFunctionSelectorsRegistered(_facet, _facetSelectors);\n }\n\n /**\n * @dev Removes a registered facet and it's corresponding selectors from registry\n * @param _facet address of facet\n * @param _facetSelectors list of function selectors of the facet\n */\n function removeFacetFunctionSelectors(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external override onlyOwner {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n uint256 facetSelectorsLength = _facetSelectors.length;\n for (uint256 i; i < facetSelectorsLength; ) {\n if (!facetConfig.info[_facetSelectors[i]].exists)\n revert FacetRegistry__UnregisteredFacetSelector();\n\n bytes4 lastSelector = facetConfig.selectors[\n facetConfig.selectors.length - 1\n ];\n if (_facetSelectors[i] != lastSelector) {\n uint128 targetIndex = facetConfig\n .info[_facetSelectors[i]]\n .index;\n facetConfig.selectors[targetIndex] = lastSelector;\n facetConfig.info[lastSelector].index = targetIndex;\n }\n facetConfig.selectors.pop();\n delete facetConfig.info[_facetSelectors[i]];\n\n unchecked {\n ++i;\n }\n }\n emit FacetFunctionSelectorsRemoved(_facet, _facetSelectors);\n }\n\n /**\n * @dev Checks if a facet and it's selectors given is registered to facet registry\n * @param _facet Address of facet\n * @param _facetSelectors List of function selectors of the facet\n */\n function areFacetFunctionSelectorsRegistered(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external view override returns (bool) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n uint256 facetSelectorsLength = _facetSelectors.length;\n if (facetSelectorsLength == 0) return false;\n for (uint256 i; i < facetSelectorsLength; ) {\n if (!facetConfig.info[_facetSelectors[i]].exists) return false;\n unchecked {\n ++i;\n }\n }\n return true;\n }\n\n /**\n * @dev Checks if a facet and it's selector given is registered to facet registry\n * @param _facet Address of facet\n * @param _facetSelector List of function selectors of the facet\n * @return isRegistered Bool value showing if the selector is registered\n */\n function isFacetFunctionSelectorRegistered(\n address _facet,\n bytes4 _facetSelector\n ) external view override returns (bool isRegistered) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n isRegistered = facetConfig.info[_facetSelector].exists;\n }\n\n /**\n * @dev Get the registered selectors of facet from registry\n * @param _facet Address of facet\n * @return selectors Selectors registered to facet\n */\n function getFacetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory selectors) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n selectors = facetConfig.selectors;\n }\n}\n" + }, + "contracts/infrastructure/interfaces/IFacetRegistry.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Registry Interface\n * @dev Interface for Facet Registry contract to keep track of facets & function selectors addable to user wallets\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IFacetRegistry {\n struct FacetRegistryConfig {\n bytes4[] selectors;\n mapping(bytes4 => FacetInfo) info;\n }\n struct FacetInfo {\n bool exists;\n uint128 index;\n }\n\n event FacetFunctionSelectorsRegistered(\n address facet,\n bytes4[] facetSelectors\n );\n event FacetFunctionSelectorsRemoved(address facet, bytes4[] facetSelectors);\n\n error FacetRegistry__FacetSelectorAlreadyRegistered();\n error FacetRegistry__UnregisteredFacetSelector();\n\n function registerFacetFunctionSelectors(\n address facet,\n bytes4[] calldata facetSelectors\n ) external;\n\n function removeFacetFunctionSelectors(\n address facet,\n bytes4[] calldata facetSelectors\n ) external;\n\n function areFacetFunctionSelectorsRegistered(\n address facet,\n bytes4[] calldata facetSelectors\n ) external view returns (bool);\n\n function isFacetFunctionSelectorRegistered(\n address facet,\n bytes4 facetSelector\n ) external view returns (bool);\n\n function getFacetFunctionSelectors(\n address facet\n ) external view returns (bytes4[] memory);\n}\n" + }, + "contracts/infrastructure/interfaces/ISecurityManager.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Registry Interface\n * @dev Infrastructure contract to manage security parameters of users\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface ISecurityManager {\n error SecurityManager__OutOfBoundary();\n error SecurityManager__CallerNotWallet();\n error SecurityManager__AlreadyIntialized();\n\n function initializeAdditionSecurityPeriod(\n uint128 defaultAdditionSecurityPeriod,\n uint128 minAdditionSecurityPeriod,\n uint128 maxAdditionSecurityPeriod\n ) external;\n\n function initializeRemovalSecurityPeriod(\n uint128 defaultRemovalSecurityPeriod,\n uint128 minRemovalSecurityPeriod,\n uint128 maxRemovalSecurityPeriod\n ) external;\n\n function initializeApprovalValidationPeriod(\n uint128 defaultApprovalValidationPeriod,\n uint128 minApprovalValidationPeriod,\n uint128 maxApprovalValidationPeriod\n ) external;\n\n function initializeMigrationPeriod(\n uint128 defaultMigrationPeriod,\n uint128 minMigrationPeriod,\n uint128 maxMigrationPeriod\n ) external;\n\n function initializeLockPeriod(\n uint128 defaultLockPeriod,\n uint128 minLockPeriod,\n uint128 maxLockPeriod\n ) external;\n\n function initializeRecoveryPeriod(\n uint128 defaultRecoveryPeriod,\n uint128 minRecoveryPeriod,\n uint128 maxRecoveryPeriod\n ) external;\n\n function initializeSecurityWindow(\n uint128 defaultSecurityWindow,\n uint128 minSecurityWindow,\n uint128 maxSecurityWindow\n ) external;\n\n function setAdditionSecurityPeriod(\n address wallet,\n uint128 additionSecurityPeriod\n ) external;\n\n function setRemovalSecurityPeriod(\n address wallet,\n uint128 removalSecurityPeriod\n ) external;\n\n function setSecurityWindow(address wallet, uint128 securityWindow) external;\n\n function setRecoveryPeriod(address wallet, uint128 recoveryPeriod) external;\n\n function setLockPeriod(address wallet, uint128 lockPeriod) external;\n\n function setApprovalValidationPeriod(\n address wallet,\n uint128 approvalValidationPeriod\n ) external;\n\n function setMigrationPeriod(\n address wallet,\n uint128 migrationPeriod\n ) external;\n\n function additionSecurityPeriodOf(\n address wallet\n ) external view returns (uint128);\n\n function removalSecurityPeriodOf(\n address wallet\n ) external view returns (uint128);\n\n function securityWindowOf(address wallet) external view returns (uint128);\n\n function recoveryPeriodOf(address wallet) external view returns (uint128);\n\n function lockPeriodOf(address wallet) external view returns (uint128);\n\n function migrationPeriodOf(address wallet) external view returns (uint128);\n\n function approvalValidationPeriodOf(\n address wallet\n ) external view returns (uint128);\n}\n" + }, + "contracts/infrastructure/RemoteStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IGuardianFacet} from \"../facets/interfaces/IGuardianFacet.sol\";\n\n/**\n * @title Remote Storage\n * @dev Remote storage allows you to associate addresses with an array of addresses on a standalone smart contract.\n * This could be useful when you don't want to use the local diamond storage for some purpose.\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\nabstract contract RemoteStorage {\n struct StorageConfig {\n address[] addresses;\n mapping(address => Info) info;\n }\n\n struct Info {\n bool exists;\n uint128 index;\n }\n\n mapping(address => StorageConfig) internal configs;\n\n event Added(address _address);\n event Removed(address _address);\n\n error RemoteStorage__CallerNotOwner();\n error RemoteStorage__CallerNotGuardianOrOwner();\n error RemoteStorage__AlreadyExists();\n error RemoteStorage__NotFound();\n error RemoteStorage__CallerNotGuardian();\n\n bytes4 constant IS_GUARDIAN_SELECTOR =\n bytes4(keccak256(\"isGuardian(address)\"));\n bytes4 constant GUARDIAN_COUNT = bytes4(keccak256(\"guardianCount()\"));\n\n /**\n * @notice Modifier to only allow the self to call. Reverts otherwise\n */\n modifier onlyWallet(address _wallet) {\n if (msg.sender != _wallet) revert RemoteStorage__CallerNotOwner();\n _;\n }\n\n /**\n * @notice Enfore the callet to be wallet of guardian of the wallet\n * @param _wallet Address of wallet\n */\n function enforceGuardianOrWallet(address _wallet) internal view {\n if (msg.sender == _wallet) return;\n address facetAddress = IDiamondLoupe(_wallet).facetAddress(\n IS_GUARDIAN_SELECTOR\n );\n if (facetAddress != address(0))\n if (IGuardianFacet(_wallet).isGuardian(msg.sender)) return;\n revert RemoteStorage__CallerNotGuardianOrOwner();\n }\n\n /**\n * @notice Enforce the caller to be wallet IF guardians doesn't exists and only guardian when guardians exists\n * @param _wallet Target wallet address to be handled by infrastructure contracts\n */\n function enforceWalletOrGuardianIfExists(address _wallet) internal view {\n address facetAddress;\n if (msg.sender == _wallet) {\n facetAddress = IDiamondLoupe(_wallet).facetAddress(GUARDIAN_COUNT);\n if (facetAddress == address(0)) return;\n uint256 guardianCount = IGuardianFacet(_wallet).guardianCount();\n if (guardianCount != 0) revert RemoteStorage__CallerNotGuardian();\n return;\n }\n facetAddress = IDiamondLoupe(_wallet).facetAddress(\n IS_GUARDIAN_SELECTOR\n );\n if (facetAddress != address(0))\n if (IGuardianFacet(_wallet).isGuardian(msg.sender)) return;\n\n revert RemoteStorage__CallerNotGuardianOrOwner();\n }\n\n /**\n * @notice Add address to storage and reverts if the address already exists.\n * This is an internal function callable from contracts that inherit this abstract contract\n * @param _wallet Address of wallet to add the address\n * @param _address Address to be added to wallet\n */\n function addAddress(address _wallet, address _address) internal {\n StorageConfig storage config = configs[_wallet];\n if (config.info[_address].exists) revert RemoteStorage__AlreadyExists();\n\n config.info[_address].exists = true;\n config.info[_address].index = uint128(config.addresses.length);\n config.addresses.push(_address);\n\n emit Added(_address);\n }\n\n /**\n * @notice Remove address from storage and reverts if the address already exists.\n * This is an internal function callable from contracts that inherit this abstract contract\n * @param _wallet Address of wallet to remove the address\n * @param _address Address to be removed from wallet\n */\n function removeAddress(address _wallet, address _address) internal {\n StorageConfig storage config = configs[_wallet];\n if (!config.info[_address].exists) revert RemoteStorage__NotFound();\n\n address lastAddress = config.addresses[config.addresses.length - 1];\n if (_address != lastAddress) {\n uint128 targetIndex = config.info[_address].index;\n config.addresses[targetIndex] = lastAddress;\n config.info[lastAddress].index = targetIndex;\n }\n config.addresses.pop();\n delete config.info[_address];\n\n emit Removed(_address);\n }\n\n /**\n * @notice Returns the address added to the given wallet\n * @param _wallet Address of wallet to fetch the addresses added to it\n * @return addresses List of addresses added to the wallet\n */\n function getAddresses(\n address _wallet\n ) internal view returns (address[] memory addresses) {\n StorageConfig storage config = configs[_wallet];\n addresses = new address[](config.addresses.length);\n uint addressesLen = config.addresses.length;\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns bool value checking if the address exists in the given wallet address\n * @param _wallet Wallet address to check\n * @param _address Address to fetch if the address if added to given wallet\n * @return exists_ Bool value showing if the address exists in wallet\n */\n function exists(\n address _wallet,\n address _address\n ) internal view returns (bool exists_) {\n exists_ = configs[_wallet].info[_address].exists;\n }\n\n /**\n * @notice Returns the number of addresses added to the wallet\n * @param _wallet Address of wallet to check\n * @return count_ Number of addresses added to wallet\n */\n function count(address _wallet) internal view returns (uint256 count_) {\n count_ = configs[_wallet].addresses.length;\n }\n}\n" + }, + "contracts/infrastructure/SecurityManager.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport {ISecurityManager} from \"./interfaces/ISecurityManager.sol\";\n\n/**\n * @title Security Manager\n * @dev Infrastructure contract to manage security parameters of users\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract SecurityManager is ISecurityManager, Ownable2Step {\n uint128 public minAdditionSecurityPeriod;\n uint128 public maxAdditionSecurityPeriod;\n uint128 private defaultAdditionSecurityPeriod;\n\n uint128 public minRemovalSecurityPeriod;\n uint128 public maxRemovalSecurityPeriod;\n uint128 private defaultRemovalSecurityPeriod;\n\n uint128 public minSecurityWindow;\n uint128 public maxSecurityWindow;\n uint128 private defaultSecurityWindow;\n\n uint128 public minRecoveryPeriod;\n uint128 public maxRecoveryPeriod;\n uint128 private defaultRecoveryPeriod;\n\n uint128 public minLockPeriod;\n uint128 public maxLockPeriod;\n uint128 private defaultLockPeriod;\n\n uint128 public minApprovalValidationPeriod;\n uint128 public maxApprovalValidationPeriod;\n uint128 private defaultApprovalValidationPeriod;\n\n uint128 public minMigrationPeriod;\n uint128 public maxMigrationPeriod;\n uint128 private defaultMigrationPeriod;\n\n bool public _isAdditionSecurityPeriodInitialized;\n bool public _isRemovalSecurityPeriodInitialized;\n bool public _isSecurityWindowInitialized;\n bool public _isRecoveryPeriodInitialized;\n bool public _isLockPeriodInitialized;\n bool public _isApprovalValidationPeriodInitialized;\n bool public _isMigrationPeriodInitialized;\n\n mapping(address => CustomSecurityConfig) securityConfigs;\n\n struct CustomSecurityConfig {\n uint128 additionSecurityPeriod;\n uint128 removalSecurityPeriod;\n uint128 securityWindow;\n uint128 recoveryPeriod;\n uint128 lockPeriod;\n uint128 approvalValidationPeriod;\n uint128 migrationPeriod;\n }\n\n /**\n * @notice Modifier to only allow wallet itself to make a call to wallet\n */\n modifier onlyWallet(address _wallet) {\n if (msg.sender != _wallet) revert SecurityManager__CallerNotWallet();\n _;\n }\n\n /**\n * @notice Modifier to revert if the variable is already initialized\n */\n modifier initializer(bool _isInitialized) {\n if (_isInitialized) revert SecurityManager__AlreadyIntialized();\n _;\n }\n\n /**\n * @notice Transfers the ownership of the contract to the given owner\n * @param _owner Address of owner who has access to initialize the default security variables for security manager\n */\n constructor(address _owner) {\n transferOwnership(_owner);\n _transferOwnership(_owner);\n }\n\n /**\n * @notice Sets the initial default/min/max addition security period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultAdditionSecurityPeriod Default Addition Security Period for all Barz contracts\n * @param _minAdditionSecurityPeriod Minimum Addition Security Period for all Barz contracts\n * @param _maxAdditionSecurityPeriod Maximum Addition Security Period for all Barz contracts\n */\n function initializeAdditionSecurityPeriod(\n uint128 _defaultAdditionSecurityPeriod,\n uint128 _minAdditionSecurityPeriod,\n uint128 _maxAdditionSecurityPeriod\n )\n external\n override\n onlyOwner\n initializer(_isAdditionSecurityPeriodInitialized)\n {\n _isAdditionSecurityPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultAdditionSecurityPeriod,\n _minAdditionSecurityPeriod,\n _maxAdditionSecurityPeriod\n );\n defaultAdditionSecurityPeriod = _defaultAdditionSecurityPeriod;\n minAdditionSecurityPeriod = _minAdditionSecurityPeriod;\n maxAdditionSecurityPeriod = _maxAdditionSecurityPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max removal security period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultRemovalSecurityPeriod Default Removal Security Period for all Barz contracts\n * @param _minRemovalSecurityPeriod Minimum Removal Security Period for all Barz contracts\n * @param _maxRemovalSecurityPeriod Maximum Removal Security Period for all Barz contracts\n */\n function initializeRemovalSecurityPeriod(\n uint128 _defaultRemovalSecurityPeriod,\n uint128 _minRemovalSecurityPeriod,\n uint128 _maxRemovalSecurityPeriod\n )\n external\n override\n onlyOwner\n initializer(_isRemovalSecurityPeriodInitialized)\n {\n _isRemovalSecurityPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultRemovalSecurityPeriod,\n _minRemovalSecurityPeriod,\n _maxRemovalSecurityPeriod\n );\n defaultRemovalSecurityPeriod = _defaultRemovalSecurityPeriod;\n minRemovalSecurityPeriod = _minRemovalSecurityPeriod;\n maxRemovalSecurityPeriod = _maxRemovalSecurityPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/maxd security window for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultSecurityWindow Default Security Window for all Barz contracts\n * @param _minSecurityWindow Minimum Security Window for all Barz contracts\n * @param _maxSecurityWindow Maximum Security Window for all Barz contracts\n */\n function initializeSecurityWindow(\n uint128 _defaultSecurityWindow,\n uint128 _minSecurityWindow,\n uint128 _maxSecurityWindow\n ) external override onlyOwner initializer(_isSecurityWindowInitialized) {\n _isSecurityWindowInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultSecurityWindow,\n _minSecurityWindow,\n _maxSecurityWindow\n );\n defaultSecurityWindow = _defaultSecurityWindow;\n minSecurityWindow = _minSecurityWindow;\n maxSecurityWindow = _maxSecurityWindow;\n }\n\n /**\n * @notice Sets the initial default/min/max recovery period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultRecoveryPeriod Default Recovery Period for all Barz contracts\n * @param _minRecoveryPeriod Minimum Recovery Period for all Barz contracts\n * @param _maxRecoveryPeriod Maximum Recovery Period for all Barz contracts\n */\n function initializeRecoveryPeriod(\n uint128 _defaultRecoveryPeriod,\n uint128 _minRecoveryPeriod,\n uint128 _maxRecoveryPeriod\n ) external override onlyOwner initializer(_isRecoveryPeriodInitialized) {\n _isRecoveryPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultRecoveryPeriod,\n _minRecoveryPeriod,\n _maxRecoveryPeriod\n );\n defaultRecoveryPeriod = _defaultRecoveryPeriod;\n minRecoveryPeriod = _minRecoveryPeriod;\n maxRecoveryPeriod = _maxRecoveryPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max lock period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultLockPeriod Default Lock Period for all Barz contracts\n * @param _minLockPeriod Minimum Lock Period for all Barz contracts\n * @param _maxLockPeriod Maximum Lock Period for all Barz contracts\n */\n function initializeLockPeriod(\n uint128 _defaultLockPeriod,\n uint128 _minLockPeriod,\n uint128 _maxLockPeriod\n ) external override onlyOwner initializer(_isLockPeriodInitialized) {\n _isLockPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultLockPeriod,\n _minLockPeriod,\n _maxLockPeriod\n );\n defaultLockPeriod = _defaultLockPeriod;\n minLockPeriod = _minLockPeriod;\n maxLockPeriod = _maxLockPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max approval validation period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultApprovalValidationPeriod Default Approval Validation Period for all Barz contracts\n * @param _minApprovalValidationPeriod Minimum Approval Validation Period for all Barz contracts\n * @param _maxApprovalValidationPeriod Maximum Approval Validation Period for all Barz contracts\n */\n function initializeApprovalValidationPeriod(\n uint128 _defaultApprovalValidationPeriod,\n uint128 _minApprovalValidationPeriod,\n uint128 _maxApprovalValidationPeriod\n )\n external\n override\n onlyOwner\n initializer(_isApprovalValidationPeriodInitialized)\n {\n _isApprovalValidationPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultApprovalValidationPeriod,\n _minApprovalValidationPeriod,\n _maxApprovalValidationPeriod\n );\n defaultApprovalValidationPeriod = _defaultApprovalValidationPeriod;\n minApprovalValidationPeriod = _minApprovalValidationPeriod;\n maxApprovalValidationPeriod = _maxApprovalValidationPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max migration period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultMigrationPeriod Default Migration Period for all Barz contracts\n * @param _minMigrationPeriod Minimum Migration Period for all Barz contracts\n * @param _maxMigrationPeriod Maximum Migration Period for all Barz contracts\n */\n function initializeMigrationPeriod(\n uint128 _defaultMigrationPeriod,\n uint128 _minMigrationPeriod,\n uint128 _maxMigrationPeriod\n ) external override onlyOwner initializer(_isMigrationPeriodInitialized) {\n _isMigrationPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultMigrationPeriod,\n _minMigrationPeriod,\n _maxMigrationPeriod\n );\n defaultMigrationPeriod = _defaultMigrationPeriod;\n minMigrationPeriod = _minMigrationPeriod;\n maxMigrationPeriod = _maxMigrationPeriod;\n }\n\n /**\n * @notice Wallet owner sets the addition security period for the wallet. Only the owner of wallet can call this function.\n * The addition security period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _additionSecurityPeriod Custom Addition Security Period for the wallet\n */\n function setAdditionSecurityPeriod(\n address _wallet,\n uint128 _additionSecurityPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _additionSecurityPeriod,\n minAdditionSecurityPeriod,\n maxAdditionSecurityPeriod\n );\n securityConfigs[_wallet]\n .additionSecurityPeriod = _additionSecurityPeriod;\n }\n\n /**\n * @notice Wallet owner sets the removal security period for the wallet. Only the owner of wallet can call this function.\n * The removal security period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _removalSecurityPeriod Custom Removal Security Period for the wallet\n */\n function setRemovalSecurityPeriod(\n address _wallet,\n uint128 _removalSecurityPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _removalSecurityPeriod,\n minRemovalSecurityPeriod,\n maxRemovalSecurityPeriod\n );\n securityConfigs[_wallet].removalSecurityPeriod = _removalSecurityPeriod;\n }\n\n /**\n * @notice Wallet owner sets the security window for the wallet. Only the owner of wallet can call this function.\n * The security window should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _securityWindow Custom Security Window for the wallet\n */\n function setSecurityWindow(\n address _wallet,\n uint128 _securityWindow\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _securityWindow,\n minSecurityWindow,\n maxSecurityWindow\n );\n securityConfigs[_wallet].securityWindow = _securityWindow;\n }\n\n /**\n * @notice Wallet owner sets the recovery period for the wallet. Only the owner of wallet can call this function.\n * The recovery period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _recoveryPeriod Custom recovery period for the wallet\n */\n function setRecoveryPeriod(\n address _wallet,\n uint128 _recoveryPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _recoveryPeriod,\n minRecoveryPeriod,\n maxRecoveryPeriod\n );\n securityConfigs[_wallet].recoveryPeriod = _recoveryPeriod;\n }\n\n /**\n * @notice Wallet owner sets the lock period for the wallet. Only the owner of wallet can call this function.\n * The lock period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _lockPeriod Custom Lock period for the wallet\n */\n function setLockPeriod(\n address _wallet,\n uint128 _lockPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(_lockPeriod, minLockPeriod, maxLockPeriod);\n securityConfigs[_wallet].lockPeriod = _lockPeriod;\n }\n\n /**\n * @notice Wallet owner sets the approval validation period for the wallet. Only the owner of wallet can call this function.\n * The approval validation period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _approvalValidationPeriod Custom approval validation period for the wallet\n */\n function setApprovalValidationPeriod(\n address _wallet,\n uint128 _approvalValidationPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _approvalValidationPeriod,\n minApprovalValidationPeriod,\n maxApprovalValidationPeriod\n );\n securityConfigs[_wallet]\n .approvalValidationPeriod = _approvalValidationPeriod;\n }\n\n /**\n * @notice Wallet owner sets the migration period for the wallet. Only the owner of wallet can call this function.\n * The migration period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _migrationPeriod Custom migration period for the wallet\n */\n\n function setMigrationPeriod(\n address _wallet,\n uint128 _migrationPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _migrationPeriod,\n minMigrationPeriod,\n maxMigrationPeriod\n );\n securityConfigs[_wallet].migrationPeriod = _migrationPeriod;\n }\n\n /**\n * @notice Returns the addition security period. Returns default value when custom addition security period is not set\n * @param _wallet Address of wallet\n * @return additionSecurityPeriod Addition Security Period of the given Barz account or wallet\n */\n function additionSecurityPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 additionSecurityPeriod)\n {\n additionSecurityPeriod = securityConfigs[_wallet]\n .additionSecurityPeriod;\n additionSecurityPeriod = (additionSecurityPeriod == 0)\n ? defaultAdditionSecurityPeriod\n : additionSecurityPeriod;\n }\n\n /**\n * @notice Returns the removal security period. Returns default value when custom removal security period is not set\n * @param _wallet Address of wallet\n * @return removalSecurityPeriod Removal Security Period of the given Barz account or wallet\n */\n function removalSecurityPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 removalSecurityPeriod)\n {\n removalSecurityPeriod = securityConfigs[_wallet].removalSecurityPeriod;\n removalSecurityPeriod = (removalSecurityPeriod == 0)\n ? defaultRemovalSecurityPeriod\n : removalSecurityPeriod;\n }\n\n /**\n * @notice Returns the security window. Returns default value when custom security window is not set\n * @param _wallet Address of wallet\n * @return securityWindow Security window of the given Barz account or wallet\n */\n function securityWindowOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 securityWindow)\n {\n securityWindow = securityConfigs[_wallet].securityWindow;\n securityWindow = (securityWindow == 0)\n ? defaultSecurityWindow\n : securityWindow;\n }\n\n /**\n * @notice Returns the recovery period. Returns default value when custom recovery period is not set\n * @param _wallet Address of wallet\n * @return recoveryPeriod Recovery Period of the given Barz account or wallet\n */\n function recoveryPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 recoveryPeriod)\n {\n recoveryPeriod = securityConfigs[_wallet].recoveryPeriod;\n recoveryPeriod = (recoveryPeriod == 0)\n ? defaultRecoveryPeriod\n : recoveryPeriod;\n }\n\n /**\n * @notice Returns the lock period. Returns default value when custom lock period is not set\n * @param _wallet Address of wallet\n * @return lockPeriod Lock Period of the given Barz account or wallet\n */\n function lockPeriodOf(\n address _wallet\n ) public view override onlyWallet(_wallet) returns (uint128 lockPeriod) {\n lockPeriod = securityConfigs[_wallet].lockPeriod;\n lockPeriod = (lockPeriod == 0) ? defaultLockPeriod : lockPeriod;\n }\n\n /**\n * @notice Returns the approval validation period. Returns default value when custom approval validation period is not set\n * @param _wallet Address of wallet\n * @return approvalValidationPeriod Approval Validation Period of the given Barz account or wallet\n */\n function approvalValidationPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityConfigs[_wallet]\n .approvalValidationPeriod;\n approvalValidationPeriod = (approvalValidationPeriod == 0)\n ? defaultApprovalValidationPeriod\n : approvalValidationPeriod;\n }\n\n /**\n * @notice Returns the migration period. Returns default value when custom migration period is not set\n * @param _wallet Address of wallet\n * @return migrationPeriod Migration Period of the given Barz account or wallet\n */\n function migrationPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 migrationPeriod)\n {\n migrationPeriod = securityConfigs[_wallet].migrationPeriod;\n migrationPeriod = (migrationPeriod == 0)\n ? defaultMigrationPeriod\n : migrationPeriod;\n }\n\n /**\n * @notice Validates if the period is smaller than the max period or bigger than the min period\n * @param _period Period to be checked\n * @param _minPeriod Minimum period\n * @param _maxPeriod Maximum period\n */\n function _validatePeriodBoundaries(\n uint128 _period,\n uint128 _minPeriod,\n uint128 _maxPeriod\n ) internal pure {\n if (_period >= _maxPeriod || _period <= _minPeriod)\n revert SecurityManager__OutOfBoundary();\n }\n}\n" + }, + "contracts/infrastructure/WhitelistStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {RemoteStorage} from \"./RemoteStorage.sol\";\n\n/**\n * @title Whitelist storage\n * @dev Maps addresses to the corresponsing array of whitelisted addresses for each of them.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract WhitelistStorage is RemoteStorage {\n /**\n * @dev Add the address to the whitelist storage\n * @param _wallet User wallet\n * @param _address Address to be whitelisted\n */\n function whitelistAddress(address _wallet, address _address) external {\n enforceWalletOrGuardianIfExists(_wallet);\n addAddress(_wallet, _address);\n }\n\n /**\n * @dev Removes the address from the whitelist storage\n * @param _wallet User wallet\n * @param _address Address to be removed from the whitelist\n */\n function blacklistAddress(address _wallet, address _address) external {\n enforceGuardianOrWallet(_wallet);\n removeAddress(_wallet, _address);\n }\n\n /**\n * @dev Returns whether the address exists in the whitelist storage, associated with the wallet\n * @param _wallet User wallet\n * @param _address Address to be whitelisted\n */\n function isWhitelisted(\n address _wallet,\n address _address\n ) external view returns (bool) {\n return exists(_wallet, _address);\n }\n\n /**\n * @dev Returns all whitelisted addresses associated with the wallet\n * @param _wallet User wallet\n */\n function getWhitelistedAddresses(\n address _wallet\n ) external view returns (address[] memory) {\n return getAddresses(_wallet);\n }\n}\n" + }, + "contracts/interfaces/ERC/IERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\n\npragma solidity 0.8.21;\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155Receiver {\n /**\n * @dev Handles the receipt of a single ERC1155 token type. This function is\n * called at the end of a `safeTransferFrom` after the balance has been updated.\n *\n * NOTE: To accept the transfer, this must return\n * `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n * (i.e. 0xf23a6e61, or its own function selector).\n *\n * @param operator The address which initiated the transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param id The ID of the token being transferred\n * @param value The amount of tokens being transferred\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n ) external returns (bytes4);\n\n /**\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\n * is called at the end of a `safeBatchTransferFrom` after the balances have\n * been updated.\n *\n * NOTE: To accept the transfer(s), this must return\n * `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n * (i.e. 0xbc197c81, or its own function selector).\n *\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "contracts/interfaces/ERC/IERC1271.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\ninterface IERC1271 {\n function isValidSignature(\n bytes32 hash,\n bytes memory signature\n ) external view returns (bytes4);\n}\n" + }, + "contracts/interfaces/ERC/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\ninterface IERC165 {\n /// @notice Query if a contract implements an interface\n /// @param interfaceId The interface identifier, as specified in ERC-165\n /// @dev Interface identification is specified in ERC-165. This function\n /// uses less than 30,000 gas.\n /// @return `true` if the contract implements `interfaceID` and\n /// `interfaceID` is not 0xffffffff, `false` otherwise\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/IERC173.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\n/// @title ERC-173 Contract Ownership Standard\n/// Note: the ERC-165 identifier for this interface is 0x7f5828d0\n/* is ERC165 */\ninterface IERC173 {\n /// @dev This emits when ownership of a contract changes.\n event OwnershipTransferred(\n address indexed previousOwner,\n address indexed newOwner\n );\n\n /// @notice Get the address of the owner\n /// @return owner_ The address of the owner.\n function owner() external view returns (address owner_);\n\n /// @notice Set the address of the new owner of the contract\n /// @dev Set _newOwner to address(0) to renounce any ownership.\n /// @param _newOwner The address of the new owner of the contract\n function transferOwnership(address _newOwner) external;\n}\n" + }, + "contracts/interfaces/ERC/IERC677Receiver.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\ninterface IERC677Receiver {\n function onTokenTransfer(\n address sender,\n uint value,\n bytes calldata data\n ) external pure returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155 is IERC165 {\n /**\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n */\n event TransferSingle(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256 id,\n uint256 value\n );\n\n /**\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n * transfers.\n */\n event TransferBatch(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\n\n /**\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n * `approved`.\n */\n event ApprovalForAll(\n address indexed account,\n address indexed operator,\n bool approved\n );\n\n /**\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n *\n * If an {URI} event was emitted for `id`, the standard\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n * returned by {IERC1155MetadataURI-uri}.\n */\n event URI(string value, uint256 indexed id);\n\n /**\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(\n address account,\n uint256 id\n ) external view returns (uint256);\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] calldata accounts,\n uint256[] calldata ids\n ) external view returns (uint256[] memory);\n\n /**\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n *\n * Emits an {ApprovalForAll} event.\n *\n * Requirements:\n *\n * - `operator` cannot be the caller.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n *\n * See {setApprovalForAll}.\n */\n function isApprovedForAll(\n address account,\n address operator\n ) external view returns (bool);\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes calldata data\n ) external;\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(\n address indexed owner,\n address indexed spender,\n uint256 value\n );\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` 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 amount) 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(\n address owner,\n address spender\n ) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the 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 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` 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(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(\n address spender,\n uint256 addedValue\n ) external returns (bool);\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(\n address spender,\n uint256 subtractedValue\n ) external returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(\n address indexed from,\n address indexed to,\n uint256 indexed tokenId\n );\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(\n address indexed owner,\n address indexed approved,\n uint256 indexed tokenId\n );\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(\n address indexed owner,\n address indexed operator,\n bool approved\n );\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(\n uint256 tokenId\n ) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(\n address owner,\n address operator\n ) external view returns (bool);\n}\n" + }, + "contracts/interfaces/IBarz.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Barz Interface\n * @dev Interface of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IBarz {\n error Barz__InitializationFailure();\n}\n" + }, + "contracts/interfaces/IBarzFactory.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Barz} from \"../Barz.sol\";\n\n/**\n * @title Barz Factory Interface\n * @dev Interface of contract to easily deploy Barz to a pre-computed address with a single call\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IBarzFactory {\n function createAccount(\n address verificationFacet,\n bytes calldata owner,\n uint256 salt\n ) external returns (Barz);\n\n function getAddress(\n address verificationFacet,\n bytes calldata owner,\n uint256 salt\n ) external view returns (address);\n\n function getBytecode(\n address accountFacet,\n address verificationFacet,\n address entryPoint,\n address facetRegistry,\n address defaultFallback,\n bytes memory ownerPublicKey\n ) external pure returns (bytes memory);\n\n function getCreationCode() external pure returns (bytes memory);\n}\n" + }, + "contracts/libraries/DefaultLibDiamond.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\n\nerror InitializationFunctionReverted(\n address _initializationContractAddress,\n bytes _calldata\n);\n\nlibrary DefaultLibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION =\n keccak256(\"trustwallet.barz.diamond.storage\");\n\n struct FacetAddressAndPosition {\n address facetAddress;\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\n }\n\n struct FacetFunctionSelectors {\n bytes4[] functionSelectors;\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\n }\n\n struct DiamondStorage {\n // maps function selector to the facet address and\n // the position of the selector in the facetFunctionSelectors.selectors array\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\n // maps facet addresses to function selectors\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\n // facet addresses\n address[] facetAddresses;\n // Used to query if a contract implements an interface.\n // Used to implement ERC-165.\n mapping(bytes4 => bool) supportedInterfaces;\n }\n\n function diamondStorage()\n internal\n pure\n returns (DiamondStorage storage ds)\n {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n event DiamondCut(\n IDiamondCut.FacetCut[] _diamondCut,\n address _init,\n bytes _calldata\n );\n\n // Internal function version of diamondCut\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n for (\n uint256 facetIndex;\n facetIndex < _diamondCut.length;\n facetIndex++\n ) {\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\n if (action == IDiamondCut.FacetCutAction.Add) {\n addFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\n replaceFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\n removeFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else {\n revert(\"LibDiamondCut: Incorrect FacetCutAction\");\n }\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Add facet can't be address(0)\"\n );\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n require(\n oldFacetAddress == address(0),\n \"LibDiamondCut: Can't add function that already exists\"\n );\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function replaceFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Replace facet can't be address(0)\"\n );\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n require(\n oldFacetAddress != _facetAddress,\n \"LibDiamondCut: Can't replace function with same facet\"\n );\n removeFunction(ds, oldFacetAddress, selector);\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function removeFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n // if function does not exist then do nothing and return\n require(\n _facetAddress == address(0),\n \"LibDiamondCut: Remove facet address must be address(0)\"\n );\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n removeFunction(ds, oldFacetAddress, selector);\n }\n }\n\n function addFacet(\n DiamondStorage storage ds,\n address _facetAddress\n ) internal {\n enforceHasContractCode(\n _facetAddress,\n \"LibDiamondCut: New facet has no code\"\n );\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds\n .facetAddresses\n .length;\n ds.facetAddresses.push(_facetAddress);\n }\n\n function addFunction(\n DiamondStorage storage ds,\n bytes4 _selector,\n uint96 _selectorPosition,\n address _facetAddress\n ) internal {\n ds\n .selectorToFacetAndPosition[_selector]\n .functionSelectorPosition = _selectorPosition;\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(\n _selector\n );\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\n }\n\n function removeFunction(\n DiamondStorage storage ds,\n address _facetAddress,\n bytes4 _selector\n ) internal {\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Can't remove function that doesn't exist\"\n );\n // an immutable function is a function defined directly in a diamond\n require(\n _facetAddress != address(this),\n \"LibDiamondCut: Can't remove immutable function\"\n );\n // replace selector with last selector, then delete last selector\n uint256 selectorPosition = ds\n .selectorToFacetAndPosition[_selector]\n .functionSelectorPosition;\n uint256 lastSelectorPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors\n .length - 1;\n // if not the same then replace _selector with lastSelector\n if (selectorPosition != lastSelectorPosition) {\n bytes4 lastSelector = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors[lastSelectorPosition];\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[\n selectorPosition\n ] = lastSelector;\n ds\n .selectorToFacetAndPosition[lastSelector]\n .functionSelectorPosition = uint96(selectorPosition);\n }\n // delete the last selector\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\n delete ds.selectorToFacetAndPosition[_selector];\n\n // if no more selectors for facet address then delete the facet address\n if (lastSelectorPosition == 0) {\n // replace facet address with last facet address and delete last facet address\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\n uint256 facetAddressPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .facetAddressPosition;\n if (facetAddressPosition != lastFacetAddressPosition) {\n address lastFacetAddress = ds.facetAddresses[\n lastFacetAddressPosition\n ];\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\n ds\n .facetFunctionSelectors[lastFacetAddress]\n .facetAddressPosition = facetAddressPosition;\n }\n ds.facetAddresses.pop();\n delete ds\n .facetFunctionSelectors[_facetAddress]\n .facetAddressPosition;\n }\n }\n\n function initializeDiamondCut(\n address _init,\n bytes memory _calldata\n ) internal {\n if (_init == address(0)) {\n return;\n }\n enforceHasContractCode(\n _init,\n \"LibDiamondCut: _init address has no code\"\n );\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length > 0) {\n // bubble up error\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(error)\n revert(add(32, error), returndata_size)\n }\n } else {\n revert InitializationFunctionReverted(_init, _calldata);\n }\n }\n }\n\n function enforceHasContractCode(\n address _contract,\n string memory _errorMessage\n ) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize > 0, _errorMessage);\n }\n}\n" + }, + "contracts/libraries/LibAppStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SafeCast} from \"@openzeppelin/contracts/utils/math/SafeCast.sol\";\nimport {IEntryPoint} from \"../aa-4337/interfaces/IEntryPoint.sol\";\nimport {IFacetRegistry} from \"../infrastructure/interfaces/IFacetRegistry.sol\";\n\n/*\n * @title App Storage\n * @dev App storage for Barz contract to prevent storage collision\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\n\nstruct Lock {\n uint64 release;\n bytes4 locker;\n}\n\nstruct InitializersStorage {\n // NOTE: initialized is a variable to make sure the initialization is only done once.\n uint8 signerInitialized;\n uint8 accountInitialized;\n uint8 restrictionsInitialized;\n}\n\nstruct AppStorage {\n mapping(uint256 => InitializersStorage) initStorage;\n uint8 signerMigration;\n bytes4 validateOwnerSignatureSelector;\n IEntryPoint entryPoint;\n IFacetRegistry facetRegistry;\n mapping(uint256 => Lock) locks;\n}\n\nlibrary LibAppStorage {\n error LibAppStorage__AccountAlreadyUninitialized();\n error LibAppStorage__AccountMustBeUninitialized();\n error LibAppStorage__SignerAlreadyUninitialized();\n error LibAppStorage__SignerMustBeUninitialized();\n\n function appStorage() internal pure returns (AppStorage storage ds) {\n assembly {\n ds.slot := 0\n }\n }\n\n function setSignerUninitialized() internal {\n AppStorage storage s = appStorage();\n if (1 != s.initStorage[0].signerInitialized) {\n revert LibAppStorage__SignerAlreadyUninitialized();\n }\n s.initStorage[0].signerInitialized = 0;\n }\n\n function getValidateOwnerSignatureSelector()\n internal\n view\n returns (bytes4 selector)\n {\n selector = appStorage().validateOwnerSignatureSelector;\n }\n\n function setValidateOwnerSignatureSelector(\n bytes4 _validateOwnerSignatureSelector\n ) internal {\n appStorage()\n .validateOwnerSignatureSelector = _validateOwnerSignatureSelector;\n }\n\n function enforceSignerInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].signerInitialized) {\n revert LibAppStorage__SignerMustBeUninitialized();\n }\n s.initStorage[0].signerInitialized = 1;\n }\n\n function enforceAccountInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].accountInitialized) {\n revert LibAppStorage__AccountMustBeUninitialized();\n }\n s.initStorage[0].accountInitialized = 1;\n }\n\n function initiateSignerMigration() internal {\n appStorage().signerMigration = 1;\n }\n\n function enforceSignerMigration() internal view {\n if (1 != appStorage().signerMigration) {\n revert LibAppStorage__AccountMustBeUninitialized();\n }\n }\n\n function finalizeSignerMigration() internal {\n appStorage().signerMigration = 0;\n }\n\n function setLock(uint256 _releaseAfter, bytes4 _locker) internal {\n appStorage().locks[0] = Lock(SafeCast.toUint64(_releaseAfter), _locker);\n }\n\n function enforceRestrictionsInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].restrictionsInitialized)\n revert LibAppStorage__SignerMustBeUninitialized();\n s.initStorage[0].restrictionsInitialized = 1;\n }\n\n function setRestrictionsUninitialized() internal {\n AppStorage storage s = appStorage();\n if (1 != s.initStorage[0].restrictionsInitialized)\n revert LibAppStorage__AccountAlreadyUninitialized();\n s.initStorage[0].restrictionsInitialized = 0;\n }\n}\n\ncontract BarzStorage {\n AppStorage internal s;\n modifier onlyWhenUnlocked() {\n require(\n uint64(block.timestamp) >= s.locks[0].release,\n \"Account Locked\"\n );\n _;\n }\n modifier onlyWhenLocked() {\n require(\n uint64(block.timestamp) < s.locks[0].release,\n \"Account Unlocked\"\n );\n _;\n }\n}\n" + }, + "contracts/libraries/LibDiamond.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\n\nerror InitializationFunctionReverted(\n address _initializationContractAddress,\n bytes _calldata\n);\n\nlibrary LibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION =\n keccak256(\"trustwallet.barz.diamond.storage\");\n\n struct DiamondStorage {\n // maps function selectors to the facets that execute the functions.\n // and maps the selectors to their position in the selectorSlots array.\n // func selector => address facet, selector position\n mapping(bytes4 => bytes32) facets;\n // array of slots of function selectors.\n // each slot holds 8 function selectors.\n mapping(uint256 => bytes32) selectorSlots;\n // The number of function selectors in selectorSlots\n uint16 selectorCount;\n // Used to query if a contract implements an interface.\n // Used to implement ERC-165.\n mapping(bytes4 => bool) supportedInterfaces;\n // Default Fallback Handler of the barz.\n IDiamondLoupe defaultFallbackHandler;\n }\n\n function diamondStorage()\n internal\n pure\n returns (DiamondStorage storage ds)\n {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n function enforceIsSelf() internal view {\n require(msg.sender == address(this), \"LibDiamond: Caller not self\");\n }\n\n event DiamondCut(\n IDiamondCut.FacetCut[] _diamondCut,\n address _init,\n bytes _calldata\n );\n\n bytes32 constant CLEAR_ADDRESS_MASK =\n bytes32(uint256(0xffffffffffffffffffffffff));\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\n\n // Internal function version of diamondCut\n // This code is almost the same as the external diamondCut,\n // except it is using 'Facet[] memory _diamondCut' instead of\n // 'Facet[] calldata _diamondCut'.\n // The code is duplicated to prevent copying calldata to memory which\n // causes an error for a two dimensional array.\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n DiamondStorage storage ds = diamondStorage();\n uint256 originalSelectorCount = ds.selectorCount;\n uint256 selectorCount = originalSelectorCount;\n bytes32 selectorSlot;\n // Check if last selector slot is not full\n // \"selectorCount & 7\" is a gas efficient modulo by eight \"selectorCount % 8\"\n if (selectorCount & 7 > 0) {\n // get last selectorSlot\n // \"selectorSlot >> 3\" is a gas efficient division by 8 \"selectorSlot / 8\"\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\n }\n // loop through diamond cut\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\n selectorCount,\n selectorSlot,\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].action,\n _diamondCut[facetIndex].functionSelectors\n );\n\n unchecked {\n facetIndex++;\n }\n }\n if (selectorCount != originalSelectorCount) {\n ds.selectorCount = uint16(selectorCount);\n }\n // If last selector slot is not full\n // \"selectorCount & 7\" is a gas efficient modulo by eight \"selectorCount % 8\"\n if (selectorCount & 7 > 0) {\n // \"selectorSlot >> 3\" is a gas efficient division by 8 \"selectorSlot / 8\"\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addReplaceRemoveFacetSelectors(\n uint256 _selectorCount,\n bytes32 _selectorSlot,\n address _newFacetAddress,\n IDiamondCut.FacetCutAction _action,\n bytes4[] memory _selectors\n ) internal returns (uint256, bytes32) {\n DiamondStorage storage ds = diamondStorage();\n require(\n _selectors.length > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n if (_action == IDiamondCut.FacetCutAction.Add) {\n enforceHasContractCode(\n _newFacetAddress,\n \"LibDiamondCut: Add facet has no code\"\n );\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n require(\n address(bytes20(oldFacet)) == address(0),\n \"LibDiamondCut: Can't add function that already exists\"\n );\n // add facet for selector\n ds.facets[selector] =\n bytes20(_newFacetAddress) |\n bytes32(_selectorCount);\n // \"_selectorCount & 7\" is a gas efficient modulo by eight \"_selectorCount % 8\"\n // \" << 5 is the same as multiplying by 32 ( * 32)\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\n // clear selector position in slot and add selector\n _selectorSlot =\n (_selectorSlot &\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\n (bytes32(selector) >> selectorInSlotPosition);\n // if slot is full then write it to storage\n if (selectorInSlotPosition == 224) {\n // \"_selectorSlot >> 3\" is a gas efficient division by 8 \"_selectorSlot / 8\"\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\n _selectorSlot = 0;\n }\n _selectorCount++;\n\n unchecked {\n selectorIndex++;\n }\n }\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\n enforceHasContractCode(\n _newFacetAddress,\n \"LibDiamondCut: Replace facet has no code\"\n );\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n address oldFacetAddress = address(bytes20(oldFacet));\n // only useful if immutable functions exist\n require(\n oldFacetAddress != address(this),\n \"LibDiamondCut: Can't replace immutable function\"\n );\n require(\n oldFacetAddress != _newFacetAddress,\n \"LibDiamondCut: Can't replace function with same function\"\n );\n require(\n oldFacetAddress != address(0),\n \"LibDiamondCut: Can't replace function that doesn't exist\"\n );\n // replace old facet address\n ds.facets[selector] =\n (oldFacet & CLEAR_ADDRESS_MASK) |\n bytes20(_newFacetAddress);\n\n unchecked {\n selectorIndex++;\n }\n }\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\n require(\n _newFacetAddress == address(0),\n \"LibDiamondCut: Remove facet address must be address(0)\"\n );\n // \"_selectorCount >> 3\" is a gas efficient division by 8 \"_selectorCount / 8\"\n uint256 selectorSlotCount = _selectorCount >> 3;\n // \"_selectorCount & 7\" is a gas efficient modulo by eight \"_selectorCount % 8\"\n uint256 selectorInSlotIndex = _selectorCount & 7;\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n if (_selectorSlot == 0) {\n // get last selectorSlot\n selectorSlotCount--;\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\n selectorInSlotIndex = 7;\n } else {\n selectorInSlotIndex--;\n }\n bytes4 lastSelector;\n uint256 oldSelectorsSlotCount;\n uint256 oldSelectorInSlotPosition;\n // adding a block here prevents stack too deep error\n {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n require(\n address(bytes20(oldFacet)) != address(0),\n \"LibDiamondCut: Can't remove function that doesn't exist\"\n );\n // only useful if immutable functions exist\n require(\n address(bytes20(oldFacet)) != address(this),\n \"LibDiamondCut: Can't remove immutable function\"\n );\n // replace selector with last selector in ds.facets\n // gets the last selector\n // \" << 5 is the same as multiplying by 32 ( * 32)\n lastSelector = bytes4(\n _selectorSlot << (selectorInSlotIndex << 5)\n );\n if (lastSelector != selector) {\n // update last selector slot position info\n ds.facets[lastSelector] =\n (oldFacet & CLEAR_ADDRESS_MASK) |\n bytes20(ds.facets[lastSelector]);\n }\n delete ds.facets[selector];\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\n // \"oldSelectorCount >> 3\" is a gas efficient division by 8 \"oldSelectorCount / 8\"\n oldSelectorsSlotCount = oldSelectorCount >> 3;\n // \"oldSelectorCount & 7\" is a gas efficient modulo by eight \"oldSelectorCount % 8\"\n // \" << 5 is the same as multiplying by 32 ( * 32)\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\n }\n if (oldSelectorsSlotCount != selectorSlotCount) {\n bytes32 oldSelectorSlot = ds.selectorSlots[\n oldSelectorsSlotCount\n ];\n // clears the selector we are deleting and puts the last selector in its place.\n oldSelectorSlot =\n (oldSelectorSlot &\n ~(CLEAR_SELECTOR_MASK >>\n oldSelectorInSlotPosition)) |\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\n // update storage with the modified slot\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\n } else {\n // clears the selector we are deleting and puts the last selector in its place.\n _selectorSlot =\n (_selectorSlot &\n ~(CLEAR_SELECTOR_MASK >>\n oldSelectorInSlotPosition)) |\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\n }\n if (selectorInSlotIndex == 0) {\n delete ds.selectorSlots[selectorSlotCount];\n _selectorSlot = 0;\n }\n\n unchecked {\n selectorIndex++;\n }\n }\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\n } else {\n revert(\"LibDiamondCut: Incorrect FacetCutAction\");\n }\n return (_selectorCount, _selectorSlot);\n }\n\n function initializeDiamondCut(\n address _init,\n bytes memory _calldata\n ) internal {\n if (_init == address(0)) {\n return;\n }\n enforceHasContractCode(\n _init,\n \"LibDiamondCut: _init address has no code\"\n );\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length > 0) {\n // bubble up error\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(error)\n revert(add(32, error), returndata_size)\n }\n } else {\n revert InitializationFunctionReverted(_init, _calldata);\n }\n }\n }\n\n function enforceHasContractCode(\n address _contract,\n string memory _errorMessage\n ) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize > 0, _errorMessage);\n }\n\n function restrictionsFacet() internal view returns (address facetAddress_) {\n bytes4 selector = bytes4(\n keccak256(\"verifyRestrictions(address,address,uint256,bytes)\")\n );\n facetAddress_ = address(\n bytes20(LibDiamond.diamondStorage().facets[selector])\n );\n }\n}\n" + }, + "contracts/libraries/LibFacetStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Storage\n * @dev Storage contract to store each facets variables with diamond storage\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\n\nstruct Secp256k1VerificationStorage {\n address signer;\n}\n\nstruct Secp256r1VerificationStorage {\n uint256[2] q;\n}\n\nstruct GuardianStorage {\n mapping(bytes32 => uint256) pending;\n mapping(uint8 => StorageConfig) configs;\n}\n\nstruct Info {\n bool exists;\n uint128 index;\n}\n\nstruct StorageConfig {\n address[] addresses;\n mapping(address => Info) info;\n}\n\nstruct RecoveryConfig {\n bytes recoveryPublicKey;\n uint64 executeAfter;\n}\n\nstruct ApprovalConfig {\n bool isApproved;\n uint64 validUntil;\n}\n\nstruct RecoveryApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isNewOwnerApproved;\n}\n\nstruct RecoveryStorage {\n mapping(uint8 => RecoveryConfig) recoveryConfigs;\n mapping(uint8 => RecoveryApprovalConfig) recoveryApprovalConfigs;\n uint128 nonce;\n}\n\nstruct RestrictionsStorage {\n address[] restrictions;\n mapping(address => bool) exists;\n}\n\nstruct SignatureMigrationConfig {\n bytes migrationPublicKey;\n address migrationVerificationFacet;\n bytes4[] migrationSelectors;\n uint64 migrateAfter;\n}\n\nstruct SignatureMigrationApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isMigrationApproved;\n}\n\nstruct SignatureMigrationStorage {\n mapping(uint8 => SignatureMigrationConfig) migrationConfigs;\n mapping(uint8 => SignatureMigrationApprovalConfig) migrationApprovalConfigs;\n uint128 nonce;\n}\n\nstruct DiamondCutApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isDiamondCutApproved;\n}\n\nstruct DiamondCutStorage {\n mapping(uint8 => DiamondCutApprovalConfig) diamondCutApprovalConfigs;\n uint128 nonce;\n}\n\nstruct LockStorage {\n uint128 nonce;\n}\n\nlibrary LibFacetStorage {\n function k1Storage()\n internal\n pure\n returns (Secp256k1VerificationStorage storage ds)\n {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.Secp256k1VerificationStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function r1Storage()\n internal\n pure\n returns (Secp256r1VerificationStorage storage ds)\n {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.Secp256r1VerificationStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function guardianStorage()\n internal\n pure\n returns (GuardianStorage storage ds)\n {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.GuardianStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function recoveryStorage()\n internal\n pure\n returns (RecoveryStorage storage ds)\n {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.RecoveryStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function restrictionsStorage()\n internal\n pure\n returns (RestrictionsStorage storage ds)\n {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.RestrictionsStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function migrationStorage()\n internal\n pure\n returns (SignatureMigrationStorage storage ds)\n {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.SignatureMigrationStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function diamondCutStorage()\n internal\n pure\n returns (DiamondCutStorage storage ds)\n {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.DiamondCutStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function lockStorage() internal pure returns (LockStorage storage ds) {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.LockStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n}\n" + }, + "contracts/libraries/LibGuardian.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibFacetStorage, StorageConfig} from \"./LibFacetStorage.sol\";\n\n/**\n * @title LibGuardian\n * @dev Internal Library to provide utility feature for Guardians stored in Guardian Facet Storage\n * @author David Yongjun Kim (@Powerstream3604)\n */\nlibrary LibGuardian {\n function majorityOfGuardians()\n internal\n view\n returns (uint256 guardianNumber)\n {\n uint256 guardianLength = guardianCount();\n guardianNumber = (guardianLength == 0) ? 0 : guardianLength / 2 + 1;\n }\n\n function isGuardian(address _guardian) internal view returns (bool) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n return config.info[_guardian].exists;\n }\n\n function guardianCount() internal view returns (uint256) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n return config.addresses.length;\n }\n\n function getGuardians() internal view returns (address[] memory) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n address[] memory addresses = new address[](config.addresses.length);\n uint256 addressesLen = config.addresses.length;\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n return addresses;\n }\n}\n" + }, + "contracts/libraries/LibLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {LibDiamond} from \"./LibDiamond.sol\";\n\n/**\n * @title LibLoupe\n * @dev Internal Library to provide utility feature for reading the state of diamond facets\n * @author David Yongjun Kim (@Powerstream3604)\n */\nlibrary LibLoupe {\n /// @notice Gets all facets and their selectors.\n /// @return facets_ Facet\n function facets()\n internal\n view\n returns (IDiamondLoupe.Facet[] memory facets_)\n {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facets_ = new IDiamondLoupe.Facet[](ds.selectorCount);\n uint16[] memory numFacetSelectors = new uint16[](ds.selectorCount);\n uint256 numFacets;\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facetAddress_ = address(bytes20(ds.facets[selector]));\n bool continueLoop;\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n if (facets_[facetIndex].facetAddress == facetAddress_) {\n facets_[facetIndex].functionSelectors[\n numFacetSelectors[facetIndex]\n ] = selector;\n // probably will never have more than 256 functions from one facet contract\n require(numFacetSelectors[facetIndex] < 255);\n numFacetSelectors[facetIndex]++;\n continueLoop = true;\n break;\n }\n }\n if (continueLoop) {\n continue;\n }\n facets_[numFacets].facetAddress = facetAddress_;\n facets_[numFacets].functionSelectors = new bytes4[](\n ds.selectorCount\n );\n facets_[numFacets].functionSelectors[0] = selector;\n numFacetSelectors[numFacets] = 1;\n numFacets++;\n }\n }\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n uint256 numSelectors = numFacetSelectors[facetIndex];\n bytes4[] memory selectors = facets_[facetIndex].functionSelectors;\n // setting the number of selectors\n assembly {\n mstore(selectors, numSelectors)\n }\n }\n // setting the number of facets\n assembly {\n mstore(facets_, numFacets)\n }\n }\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n /// @return _facetFunctionSelectors The selectors associated with a facet address.\n function facetFunctionSelectors(\n address _facet\n ) internal view returns (bytes4[] memory _facetFunctionSelectors) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n uint256 numSelectors;\n _facetFunctionSelectors = new bytes4[](ds.selectorCount);\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facet = address(bytes20(ds.facets[selector]));\n if (_facet == facet) {\n _facetFunctionSelectors[numSelectors] = selector;\n numSelectors++;\n }\n }\n }\n // Set the number of selectors in the array\n assembly {\n mstore(_facetFunctionSelectors, numSelectors)\n }\n }\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses()\n internal\n view\n returns (address[] memory facetAddresses_)\n {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facetAddresses_ = new address[](ds.selectorCount);\n uint256 numFacets;\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facetAddress_ = address(bytes20(ds.facets[selector]));\n bool continueLoop;\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n if (facetAddress_ == facetAddresses_[facetIndex]) {\n continueLoop = true;\n break;\n }\n }\n if (continueLoop) {\n continue;\n }\n facetAddresses_[numFacets] = facetAddress_;\n numFacets++;\n }\n }\n // Set the number of facet addresses in the array\n assembly {\n mstore(facetAddresses_, numFacets)\n }\n }\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(\n bytes4 _functionSelector\n ) internal view returns (address facetAddress_) {\n facetAddress_ = address(\n bytes20(LibDiamond.diamondStorage().facets[_functionSelector])\n );\n }\n}\n" + }, + "contracts/libraries/LibMultiSigStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Multi-sig Storage\n * @dev Storage contract for storing Multi-sig Facet variables in diamond storage pattern\n * @author David Yongjun Kim (@Powerstream3604)\n */\n\nstruct MultiSigStorage {\n mapping(address => address) owners;\n mapping(uint256 => mapping(address => mapping(bytes32 => uint256))) approvedHashes;\n uint256 ownerCount;\n uint256 threshold;\n uint256 counter;\n}\n\nlibrary LibMultiSigStorage {\n function multisigStorage()\n internal\n pure\n returns (MultiSigStorage storage ds)\n {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.MultiSigStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n}\n" + }, + "contracts/libraries/LibRecoverSpender.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title RecoverSpender\n * @dev Library to determine the action and spender of calldata\n * @author Ruslan Serebriakov (@rsrbk)\n */\nlibrary LibRecoverSpender {\n // ERC20, ERC721 & ERC1155 transfers & approvals\n bytes4 private constant ERC20_TRANSFER =\n bytes4(keccak256(\"transfer(address,uint256)\"));\n bytes4 private constant ERC20_APPROVE =\n bytes4(keccak256(\"approve(address,uint256)\"));\n bytes4 private constant ERC20_INCREASE_ALLOWANCE =\n bytes4(keccak256(\"increaseAllowance(address,uint256)\"));\n bytes4 private constant ERC20_DECREASE_ALLOWANCE =\n bytes4(keccak256(\"decreaseAllowance(address,uint256)\"));\n bytes4 private constant ERC721_SET_APPROVAL_FOR_ALL =\n bytes4(keccak256(\"setApprovalForAll(address,bool)\"));\n bytes4 private constant ERC721_TRANSFER_FROM =\n bytes4(keccak256(\"transferFrom(address,address,uint256)\"));\n bytes4 private constant ERC721_SAFE_TRANSFER_FROM =\n bytes4(keccak256(\"safeTransferFrom(address,address,uint256)\"));\n bytes4 private constant ERC721_SAFE_TRANSFER_FROM_BYTES =\n bytes4(keccak256(\"safeTransferFrom(address,address,uint256,bytes)\"));\n bytes4 private constant ERC1155_SAFE_TRANSFER_FROM =\n bytes4(\n keccak256(\"safeTransferFrom(address,address,uint256,uint256,bytes)\")\n );\n bytes4 private constant ERC1155_SAFE_BATCH_TRANSFER_FROM =\n bytes4(\n keccak256(\n \"safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)\"\n )\n );\n\n /**\n * @notice Helper method to recover the spender from a contract call.\n * The method returns the contract unless the call is to a standard method of a ERC20/ERC721/ERC1155 token\n * in which case the spender is recovered from the data.\n * @param _to The target contract.\n * @param _data The data payload.\n */\n function _recover(\n address _to,\n bytes memory _data\n ) internal pure returns (address spender) {\n if (_data.length >= 68) {\n bytes4 methodId;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n methodId := mload(add(_data, 0x20))\n }\n if (\n methodId == ERC20_TRANSFER ||\n methodId == ERC20_APPROVE ||\n methodId == ERC20_INCREASE_ALLOWANCE ||\n methodId == ERC20_DECREASE_ALLOWANCE ||\n methodId == ERC721_SET_APPROVAL_FOR_ALL\n ) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n spender := mload(add(_data, 0x24))\n }\n return spender;\n }\n if (\n methodId == ERC721_TRANSFER_FROM ||\n methodId == ERC721_SAFE_TRANSFER_FROM ||\n methodId == ERC721_SAFE_TRANSFER_FROM_BYTES ||\n methodId == ERC1155_SAFE_TRANSFER_FROM ||\n methodId == ERC1155_SAFE_BATCH_TRANSFER_FROM\n ) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n spender := mload(add(_data, 0x44))\n }\n return spender;\n }\n }\n\n spender = _to;\n }\n}\n" + }, + "contracts/libraries/LibUtils.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\n\nlibrary LibUtils {\n // Internal utility functions\n function mergeArrays(\n bytes4[] memory _array1,\n bytes4[] memory _array2\n ) internal pure returns (bytes4[] memory) {\n uint256 length1 = _array1.length;\n uint256 length2 = _array2.length;\n bytes4[] memory mergedArray = new bytes4[](length1 + length2);\n\n for (uint256 i; i < length1; ) {\n mergedArray[i] = _array1[i];\n unchecked {\n ++i;\n }\n }\n\n for (uint256 i; i < length2; ) {\n mergedArray[length1 + i] = _array2[i];\n unchecked {\n ++i;\n }\n }\n\n return mergedArray;\n }\n\n function removeFacetElement(\n IDiamondLoupe.Facet[] memory _facets,\n uint256 _index\n ) internal pure returns (IDiamondLoupe.Facet[] memory) {\n require(_index < _facets.length, \"Invalid index\");\n require(_facets.length != 0, \"Invalid array\");\n\n // Create a new array with a length of `_facets.length - 1`\n IDiamondLoupe.Facet[] memory newArray = new IDiamondLoupe.Facet[](\n _facets.length - 1\n );\n uint256 newArrayLength = newArray.length;\n // Iterate over the original array, skipping the element at the specified `index`\n for (uint256 i; i < newArrayLength; ) {\n if (i < _index) {\n newArray[i] = _facets[i];\n } else {\n newArray[i] = _facets[i + 1];\n }\n unchecked {\n ++i;\n }\n }\n\n return newArray;\n }\n\n function removeElement(\n bytes4[] memory _array,\n uint256 _index\n ) internal pure returns (bytes4[] memory) {\n require(_index < _array.length, \"Invalid index\");\n require(_array.length != 0, \"Invalid array\");\n\n bytes4[] memory newArray = new bytes4[](_array.length - 1);\n uint256 newArrayLength = newArray.length;\n for (uint256 i; i < newArrayLength; ) {\n if (i < _index) {\n newArray[i] = _array[i];\n } else {\n newArray[i] = _array[i + 1];\n }\n unchecked {\n ++i;\n }\n }\n\n return newArray;\n }\n\n function setValue(\n bytes4[] memory _keys,\n address[] memory _values,\n bytes4 _key,\n address _value\n ) internal pure returns (bytes4[] memory, address[] memory) {\n uint256 index = findIndex(_keys, _key);\n uint256 keysLength = _keys.length;\n if (index < keysLength) {\n _values[index] = _value;\n } else {\n // Create new storage arrays\n bytes4[] memory newKeys = new bytes4[](keysLength + 1);\n address[] memory newValues = new address[](_values.length + 1);\n\n // Copy values to the new storage arrays\n for (uint256 i; i < keysLength; ) {\n newKeys[i] = _keys[i];\n newValues[i] = _values[i];\n\n unchecked {\n ++i;\n }\n }\n\n // Add the new key-value pair\n newKeys[keysLength] = _key;\n newValues[_values.length] = _value;\n\n return (newKeys, newValues);\n }\n\n // If the key already exists, return the original arrays\n return (_keys, _values);\n }\n\n function getValue(\n bytes4[] memory _keys,\n address[] memory _values,\n bytes4 _key\n ) internal pure returns (address) {\n uint256 index = findIndex(_keys, _key);\n if (index >= _keys.length) return address(0);\n\n return _values[index];\n }\n\n function findIndex(\n bytes4[] memory _keys,\n bytes4 _key\n ) internal pure returns (uint256) {\n uint256 keysLength = _keys.length;\n for (uint256 i; i < keysLength; ) {\n if (_keys[i] == _key) {\n return i;\n }\n unchecked {\n ++i;\n }\n }\n return keysLength;\n }\n}\n" + }, + "contracts/restrictions/IRestriction.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Interface for restrictions\n * @dev Restriction is a contract which decides whether to approve a certain kind of transaction, based on its internal logic.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface IRestriction {\n /**\n * @dev Based on restriction's internal logic, it should accept or reject a certain transaction.\n * @param from The address of the sender, that will be signing the transaction.\n * @param to The receiving address.\n * @param value Amount of ETH to transfer from sender to recipient.\n * @param _calldata Optional field to include arbitrary data.\n * @return bool value for whether the check is passed\n */\n function check(\n address from,\n address to,\n uint256 value,\n bytes calldata _calldata\n ) external returns (bool);\n}\n" + }, + "contracts/restrictions/WhitelistRestriction.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibRecoverSpender} from \"../libraries/LibRecoverSpender.sol\";\nimport {WhitelistStorage} from \"../infrastructure/WhitelistStorage.sol\";\nimport {IRestriction} from \"./IRestriction.sol\";\n\n/**\n * @title Whitelist Restriction\n * @dev This restriction defines a list of accepted addresses and denies any interaction with addresses outside of it.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract WhitelistRestriction is IRestriction {\n WhitelistStorage public immutable whitelistStorage;\n\n constructor(WhitelistStorage _whitelistStorage) {\n whitelistStorage = _whitelistStorage;\n }\n\n /**\n * @notice Helper method to recover the spender from a contract call.\n * The method returns the contract unless the call is to a standard method of a ERC20/ERC721/ERC1155 token\n * in which case the spender is recovered from the data.\n * @param _to The target contract.\n * @param _data The data payload.\n */\n function recoverSpender(\n address _to,\n bytes memory _data\n ) public pure returns (address spender) {\n return LibRecoverSpender._recover(_to, _data);\n }\n\n /*\n * @dev IRestriction's implementation. It will allow transaction if the sender is whitelisted, or user, or the whitelist storage.\n * @param _from The address of the sender, that will be signing the transaction.\n * @param _to The receiving address.\n * @param _calldata Optional field to include arbitrary data.\n * @return result value for whether the check is passed\n */\n function check(\n address _from,\n address _to,\n uint256 /*_value*/,\n bytes calldata _calldata\n ) external view override returns (bool result) {\n return\n whitelistStorage.isWhitelisted(\n _from,\n LibRecoverSpender._recover(_to, _calldata)\n ) ||\n _to == address(whitelistStorage) ||\n _to == msg.sender;\n }\n}\n" + }, + "contracts/test/Counter.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\ncontract TestCounter {\n int private count = 0;\n\n function incrementCounter() public {\n count += 1;\n }\n\n function decrementCounter() public {\n count -= 1;\n }\n\n function getCount() public view returns (int) {\n return count;\n }\n}\n" + }, + "contracts/test/TestERC1155.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC1155/ERC1155.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\n\ncontract TestERC1155 is ERC1155 {\n using Counters for Counters.Counter;\n\n Counters.Counter private _tokenIds;\n\n constructor() ERC1155(\"\") {}\n\n function mint(address account, uint256 amount) external {\n uint256 tokenId = _getNextTokenId();\n _mint(account, tokenId, amount, \"\");\n }\n\n function mintBatch(\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes memory data\n ) external {\n require(\n ids.length == amounts.length,\n \"TestERC1155: arrays length mismatch\"\n );\n\n _mintBatch(to, ids, amounts, data);\n }\n\n function _getNextTokenId() private returns (uint256) {\n _tokenIds.increment();\n return _tokenIds.current();\n }\n}\n" + }, + "contracts/test/TestERC777.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC777/ERC777.sol\";\n\ncontract TestERC777 is ERC777 {\n constructor(\n address[] memory _operators\n ) ERC777(\"TestERC777\", \"TERC777\", _operators) {}\n\n function mint(address account, uint256 amount) external {\n _mint(account, amount, \"\", \"\");\n }\n}\n" + }, + "contracts/test/TestInvalidSecp256k1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IVerificationFacet} from \"../facets/interfaces/IVerificationFacet.sol\";\nimport {IERC1271} from \"../interfaces/ERC/IERC1271.sol\";\nimport {AppStorage, LibAppStorage, BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {LibFacetStorage, Secp256k1VerificationStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {UserOperation} from \"../aa-4337/interfaces/UserOperation.sol\";\n\n/**\n * @title Test Secp256k1 verification facet\n * @dev Default Ethereum's elliptic curve\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract TestInvalidSecp256k1VerificationFacet is BarzStorage, IERC1271 {\n using ECDSA for bytes32;\n error Secp256k1VerificationFacet__InvalidSignerLength();\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n\n event SignerUninitialized();\n\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n }\n\n // THIS INVALID FACET DOES NOT INCLUDE initializeSigner()\n // THIS FACET IS USED TO TEST WHEN initializeSigner() DOESN'T EXIST IN FACET\n\n function uninitializeSigner() external returns (uint256 uninitSuccess) {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view returns (uint256 validationData) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n return validateSignature(userOp, userOpHash, k1Storage.signer);\n }\n\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n address signer\n ) public pure returns (uint256) {\n bytes32 hash = userOpHash.toEthSignedMessageHash();\n if (signer != hash.recover(userOp.signature)) return 1;\n return 0;\n }\n\n // This is REMOVED for testing purpose\n function validateOwnerSignatureSelector() public pure returns (bytes4) {\n // return this.validateOwnerSignature.selector;\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n function owner() public view returns (bytes memory) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n return abi.encodePacked(k1Storage.signer);\n }\n\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure returns (bool) {\n return (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (_hash.recover(_signature) ==\n LibFacetStorage.k1Storage().signer)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n}\n" + }, + "contracts/test/TestNFT.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\n\ncontract TestNFT is ERC721 {\n using Counters for Counters.Counter;\n Counters.Counter private currentTokenId;\n\n constructor() ERC721(\"TestNFT\", \"TNFT\") {}\n\n function mint(address recipient) public returns (uint256) {\n currentTokenId.increment();\n uint256 newItemId = currentTokenId.current();\n _safeMint(recipient, newItemId);\n return newItemId;\n }\n}\n" + }, + "contracts/test/TestToken.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract TestToken is ERC20 {\n constructor()\n // solhint-disable-next-line no-empty-blocks\n ERC20(\"TST\", \"TestToken\")\n {}\n\n function mint(address sender, uint256 amount) external {\n _mint(sender, amount);\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 999999 + }, + "evmVersion": "paris", + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/deployments/avalanche/solcInputs/167a830377988095f5f829bf03425fb0.json b/deployments/avalanche/solcInputs/167a830377988095f5f829bf03425fb0.json new file mode 100644 index 0000000..2833a16 --- /dev/null +++ b/deployments/avalanche/solcInputs/167a830377988095f5f829bf03425fb0.json @@ -0,0 +1,354 @@ +{ + "language": "Solidity", + "sources": { + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby disabling any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable2Step.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./Ownable.sol\";\n\n/**\n * @dev Contract module which provides access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership} and {acceptOwnership}.\n *\n * This module is used through inheritance. It will make available all functions\n * from parent (Ownable).\n */\nabstract contract Ownable2Step is Ownable {\n address private _pendingOwner;\n\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Returns the address of the pending owner.\n */\n function pendingOwner() public view virtual returns (address) {\n return _pendingOwner;\n }\n\n /**\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual override onlyOwner {\n _pendingOwner = newOwner;\n emit OwnershipTransferStarted(owner(), newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual override {\n delete _pendingOwner;\n super._transferOwnership(newOwner);\n }\n\n /**\n * @dev The new owner accepts the ownership transfer.\n */\n function acceptOwnership() public virtual {\n address sender = _msgSender();\n require(pendingOwner() == sender, \"Ownable2Step: caller is not the new owner\");\n _transferOwnership(sender);\n }\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC1271.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC1271 standard signature validation method for\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\n *\n * _Available since v4.1._\n */\ninterface IERC1271 {\n /**\n * @dev Should return whether the signature provided is valid for the provided data\n * @param hash Hash of the data to be signed\n * @param signature Signature byte array associated with _data\n */\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\n}\n" + }, + "@openzeppelin/contracts/security/ReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor() {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n _nonReentrantBefore();\n _;\n _nonReentrantAfter();\n }\n\n function _nonReentrantBefore() private {\n // On the first call to nonReentrant, _status will be _NOT_ENTERED\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n }\n\n function _nonReentrantAfter() private {\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Returns true if the reentrancy guard is currently set to \"entered\", which indicates there is a\n * `nonReentrant` function in the call stack.\n */\n function _reentrancyGuardEntered() internal view returns (bool) {\n return _status == _ENTERED;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/ERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/ERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC1155.sol\";\nimport \"./IERC1155Receiver.sol\";\nimport \"./extensions/IERC1155MetadataURI.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of the basic standard multi-token.\n * See https://eips.ethereum.org/EIPS/eip-1155\n * Originally based on code by Enjin: https://github.com/enjin/erc-1155\n *\n * _Available since v3.1._\n */\ncontract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {\n using Address for address;\n\n // Mapping from token ID to account balances\n mapping(uint256 => mapping(address => uint256)) private _balances;\n\n // Mapping from account to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json\n string private _uri;\n\n /**\n * @dev See {_setURI}.\n */\n constructor(string memory uri_) {\n _setURI(uri_);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return\n interfaceId == type(IERC1155).interfaceId ||\n interfaceId == type(IERC1155MetadataURI).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC1155MetadataURI-uri}.\n *\n * This implementation returns the same URI for *all* token types. It relies\n * on the token type ID substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * Clients calling this function must replace the `\\{id\\}` substring with the\n * actual token type ID.\n */\n function uri(uint256) public view virtual override returns (string memory) {\n return _uri;\n }\n\n /**\n * @dev See {IERC1155-balanceOf}.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {\n require(account != address(0), \"ERC1155: address zero is not a valid owner\");\n return _balances[id][account];\n }\n\n /**\n * @dev See {IERC1155-balanceOfBatch}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] memory accounts,\n uint256[] memory ids\n ) public view virtual override returns (uint256[] memory) {\n require(accounts.length == ids.length, \"ERC1155: accounts and ids length mismatch\");\n\n uint256[] memory batchBalances = new uint256[](accounts.length);\n\n for (uint256 i = 0; i < accounts.length; ++i) {\n batchBalances[i] = balanceOf(accounts[i], ids[i]);\n }\n\n return batchBalances;\n }\n\n /**\n * @dev See {IERC1155-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC1155-isApprovedForAll}.\n */\n function isApprovedForAll(address account, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[account][operator];\n }\n\n /**\n * @dev See {IERC1155-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n _safeTransferFrom(from, to, id, amount, data);\n }\n\n /**\n * @dev See {IERC1155-safeBatchTransferFrom}.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n _safeBatchTransferFrom(from, to, ids, amounts, data);\n }\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n\n emit TransferSingle(operator, from, to, id, amount);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n for (uint256 i = 0; i < ids.length; ++i) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n }\n\n emit TransferBatch(operator, from, to, ids, amounts);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\n\n _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);\n }\n\n /**\n * @dev Sets a new URI for all token types, by relying on the token type ID\n * substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * By this mechanism, any occurrence of the `\\{id\\}` substring in either the\n * URI or any of the amounts in the JSON file at said URI will be replaced by\n * clients with the token type ID.\n *\n * For example, the `https://token-cdn-domain/\\{id\\}.json` URI would be\n * interpreted by clients as\n * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`\n * for token type ID 0x4cce0.\n *\n * See {uri}.\n *\n * Because these URIs cannot be meaningfully represented by the {URI} event,\n * this function emits no events.\n */\n function _setURI(string memory newuri) internal virtual {\n _uri = newuri;\n }\n\n /**\n * @dev Creates `amount` tokens of token type `id`, and assigns them to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _mint(address to, uint256 id, uint256 amount, bytes memory data) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _balances[id][to] += amount;\n emit TransferSingle(operator, address(0), to, id, amount);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n for (uint256 i = 0; i < ids.length; i++) {\n _balances[ids[i]][to] += amounts[i];\n }\n\n emit TransferBatch(operator, address(0), to, ids, amounts);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);\n }\n\n /**\n * @dev Destroys `amount` tokens of token type `id` from `from`\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `from` must have at least `amount` tokens of token type `id`.\n */\n function _burn(address from, uint256 id, uint256 amount) internal virtual {\n require(from != address(0), \"ERC1155: burn from the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n\n emit TransferSingle(operator, from, address(0), id, amount);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n */\n function _burnBatch(address from, uint256[] memory ids, uint256[] memory amounts) internal virtual {\n require(from != address(0), \"ERC1155: burn from the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n\n for (uint256 i = 0; i < ids.length; i++) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n }\n\n emit TransferBatch(operator, from, address(0), ids, amounts);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {\n require(owner != operator, \"ERC1155: setting approval status for self\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning, as well as batched variants.\n *\n * The same hook is called on both single and batched variants. For single\n * transfers, the length of the `ids` and `amounts` arrays will be 1.\n *\n * Calling conditions (for each `id` and `amount` pair):\n *\n * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * of token type `id` will be transferred to `to`.\n * - When `from` is zero, `amount` tokens of token type `id` will be minted\n * for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n * will be burned.\n * - `from` and `to` are never both zero.\n * - `ids` and `amounts` have the same, non-zero length.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any token transfer. This includes minting\n * and burning, as well as batched variants.\n *\n * The same hook is called on both single and batched variants. For single\n * transfers, the length of the `id` and `amount` arrays will be 1.\n *\n * Calling conditions (for each `id` and `amount` pair):\n *\n * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * of token type `id` will be transferred to `to`.\n * - When `from` is zero, `amount` tokens of token type `id` will be minted\n * for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n * will be burned.\n * - `from` and `to` are never both zero.\n * - `ids` and `amounts` have the same, non-zero length.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {}\n\n function _doSafeTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155Receiver.onERC1155Received.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non-ERC1155Receiver implementer\");\n }\n }\n }\n\n function _doSafeBatchTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (\n bytes4 response\n ) {\n if (response != IERC1155Receiver.onERC1155BatchReceived.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non-ERC1155Receiver implementer\");\n }\n }\n }\n\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {\n uint256[] memory array = new uint256[](1);\n array[0] = element;\n\n return array;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC1155.sol\";\n\n/**\n * @dev Interface of the optional ERC1155MetadataExtension interface, as defined\n * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155MetadataURI is IERC1155 {\n /**\n * @dev Returns the URI for token type `id`.\n *\n * If the `\\{id\\}` substring is present in the URI, it must be replaced by\n * clients with the actual token type ID.\n */\n function uri(uint256 id) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155 is IERC165 {\n /**\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n */\n event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);\n\n /**\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n * transfers.\n */\n event TransferBatch(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\n\n /**\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n * `approved`.\n */\n event ApprovalForAll(address indexed account, address indexed operator, bool approved);\n\n /**\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n *\n * If an {URI} event was emitted for `id`, the standard\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n * returned by {IERC1155MetadataURI-uri}.\n */\n event URI(string value, uint256 indexed id);\n\n /**\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) external view returns (uint256);\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] calldata accounts,\n uint256[] calldata ids\n ) external view returns (uint256[] memory);\n\n /**\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n *\n * Emits an {ApprovalForAll} event.\n *\n * Requirements:\n *\n * - `operator` cannot be the caller.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n *\n * See {setApprovalForAll}.\n */\n function isApprovedForAll(address account, address operator) external view returns (bool);\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155Receiver is IERC165 {\n /**\n * @dev Handles the receipt of a single ERC1155 token type. This function is\n * called at the end of a `safeTransferFrom` after the balance has been updated.\n *\n * NOTE: To accept the transfer, this must return\n * `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n * (i.e. 0xf23a6e61, or its own function selector).\n *\n * @param operator The address which initiated the transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param id The ID of the token being transferred\n * @param value The amount of tokens being transferred\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n ) external returns (bytes4);\n\n /**\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\n * is called at the end of a `safeBatchTransferFrom` after the balances have\n * been updated.\n *\n * NOTE: To accept the transfer(s), this must return\n * `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n * (i.e. 0xbc197c81, or its own function selector).\n *\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the default value returned by this function, unless\n * it's overridden.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(address from, address to, uint256 amount) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\n // decrementing then incrementing.\n _balances[to] += amount;\n }\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n unchecked {\n // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\n _balances[account] += amount;\n }\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n // Overflow not possible: amount <= accountBalance <= totalSupply.\n _totalSupply -= amount;\n }\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\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" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` 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 amount) 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 `amount` as the allowance of `spender` over the 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 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` 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 amount) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/ERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721.sol\";\nimport \"./IERC721Receiver.sol\";\nimport \"./extensions/IERC721Metadata.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/Strings.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\n using Address for address;\n using Strings for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\n\n // Mapping from token ID to approved address\n mapping(uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return\n interfaceId == type(IERC721).interfaceId ||\n interfaceId == type(IERC721Metadata).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _ownerOf(tokenId);\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token owner or approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n _requireMinted(tokenId);\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n _safeTransfer(from, to, tokenId, data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(address from, address to, uint256 tokenId, bytes memory data) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist\n */\n function _ownerOf(uint256 tokenId) internal view virtual returns (address) {\n return _owners[tokenId];\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _ownerOf(tokenId) != address(0);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n address owner = ERC721.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(address to, uint256 tokenId, bytes memory data) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId, 1);\n\n // Check that tokenId was not minted by `_beforeTokenTransfer` hook\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n unchecked {\n // Will not overflow unless all 2**256 token ids are minted to the same owner.\n // Given that tokens are minted one by one, it is impossible in practice that\n // this ever happens. Might change if we allow batch minting.\n // The ERC fails to describe this case.\n _balances[to] += 1;\n }\n\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(address(0), to, tokenId, 1);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n * This is an internal function that does not check if the sender is authorized to operate on the token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId, 1);\n\n // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook\n owner = ERC721.ownerOf(tokenId);\n\n // Clear approvals\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // Cannot overflow, as that would require more tokens to be burned/transferred\n // out than the owner initially received through minting and transferring in.\n _balances[owner] -= 1;\n }\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(owner, address(0), tokenId, 1);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(address from, address to, uint256 tokenId) internal virtual {\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId, 1);\n\n // Check that tokenId was not transferred by `_beforeTokenTransfer` hook\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n\n // Clear approvals from the previous owner\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // `_balances[from]` cannot overflow for the same reason as described in `_burn`:\n // `from`'s balance is the number of token held, which is at least one before the current\n // transfer.\n // `_balances[to]` could overflow in the conditions described in `_mint`. That would require\n // all 2**256 token ids to be minted, which in practice is impossible.\n _balances[from] -= 1;\n _balances[to] += 1;\n }\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId, 1);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721Receiver.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`.\n * - When `from` is zero, the tokens will be minted for `to`.\n * - When `to` is zero, ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}\n\n /**\n * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`.\n * - When `from` is zero, the tokens were minted for `to`.\n * - When `to` is zero, ``from``'s tokens were burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}\n\n /**\n * @dev Unsafe write access to the balances, used by extensions that \"mint\" tokens using an {ownerOf} override.\n *\n * WARNING: Anyone calling this MUST ensure that the balances remain consistent with the ownership. The invariant\n * being that for any address `a` the value returned by `balanceOf(a)` must be equal to the number of tokens such\n * that `ownerOf(tokenId)` is `a`.\n */\n // solhint-disable-next-line func-name-mixedcase\n function __unsafe_increaseBalance(address account, uint256 amount) internal {\n _balances[account] += amount;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721Receiver {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/ERC777.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC777/ERC777.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC777.sol\";\nimport \"./IERC777Recipient.sol\";\nimport \"./IERC777Sender.sol\";\nimport \"../ERC20/IERC20.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/introspection/IERC1820Registry.sol\";\n\n/**\n * @dev Implementation of the {IERC777} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n *\n * Support for ERC20 is included in this contract, as specified by the EIP: both\n * the ERC777 and ERC20 interfaces can be safely used when interacting with it.\n * Both {IERC777-Sent} and {IERC20-Transfer} events are emitted on token\n * movements.\n *\n * Additionally, the {IERC777-granularity} value is hard-coded to `1`, meaning that there\n * are no special restrictions in the amount of tokens that created, moved, or\n * destroyed. This makes integration with ERC20 applications seamless.\n *\n * CAUTION: This file is deprecated as of v4.9 and will be removed in the next major release.\n */\ncontract ERC777 is Context, IERC777, IERC20 {\n using Address for address;\n\n IERC1820Registry internal constant _ERC1820_REGISTRY = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n mapping(address => uint256) private _balances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n bytes32 private constant _TOKENS_SENDER_INTERFACE_HASH = keccak256(\"ERC777TokensSender\");\n bytes32 private constant _TOKENS_RECIPIENT_INTERFACE_HASH = keccak256(\"ERC777TokensRecipient\");\n\n // This isn't ever read from - it's only used to respond to the defaultOperators query.\n address[] private _defaultOperatorsArray;\n\n // Immutable, but accounts may revoke them (tracked in __revokedDefaultOperators).\n mapping(address => bool) private _defaultOperators;\n\n // For each account, a mapping of its operators and revoked default operators.\n mapping(address => mapping(address => bool)) private _operators;\n mapping(address => mapping(address => bool)) private _revokedDefaultOperators;\n\n // ERC20-allowances\n mapping(address => mapping(address => uint256)) private _allowances;\n\n /**\n * @dev `defaultOperators` may be an empty array.\n */\n constructor(string memory name_, string memory symbol_, address[] memory defaultOperators_) {\n _name = name_;\n _symbol = symbol_;\n\n _defaultOperatorsArray = defaultOperators_;\n for (uint256 i = 0; i < defaultOperators_.length; i++) {\n _defaultOperators[defaultOperators_[i]] = true;\n }\n\n // register interfaces\n _ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256(\"ERC777Token\"), address(this));\n _ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256(\"ERC20Token\"), address(this));\n }\n\n /**\n * @dev See {IERC777-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC777-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {ERC20-decimals}.\n *\n * Always returns 18, as per the\n * [ERC777 EIP](https://eips.ethereum.org/EIPS/eip-777#backward-compatibility).\n */\n function decimals() public pure virtual returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC777-granularity}.\n *\n * This implementation always returns `1`.\n */\n function granularity() public view virtual override returns (uint256) {\n return 1;\n }\n\n /**\n * @dev See {IERC777-totalSupply}.\n */\n function totalSupply() public view virtual override(IERC20, IERC777) returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev Returns the amount of tokens owned by an account (`tokenHolder`).\n */\n function balanceOf(address tokenHolder) public view virtual override(IERC20, IERC777) returns (uint256) {\n return _balances[tokenHolder];\n }\n\n /**\n * @dev See {IERC777-send}.\n *\n * Also emits a {IERC20-Transfer} event for ERC20 compatibility.\n */\n function send(address recipient, uint256 amount, bytes memory data) public virtual override {\n _send(_msgSender(), recipient, amount, data, \"\", true);\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Unlike `send`, `recipient` is _not_ required to implement the {IERC777Recipient}\n * interface if it is a contract.\n *\n * Also emits a {Sent} event.\n */\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n _send(_msgSender(), recipient, amount, \"\", \"\", false);\n return true;\n }\n\n /**\n * @dev See {IERC777-burn}.\n *\n * Also emits a {IERC20-Transfer} event for ERC20 compatibility.\n */\n function burn(uint256 amount, bytes memory data) public virtual override {\n _burn(_msgSender(), amount, data, \"\");\n }\n\n /**\n * @dev See {IERC777-isOperatorFor}.\n */\n function isOperatorFor(address operator, address tokenHolder) public view virtual override returns (bool) {\n return\n operator == tokenHolder ||\n (_defaultOperators[operator] && !_revokedDefaultOperators[tokenHolder][operator]) ||\n _operators[tokenHolder][operator];\n }\n\n /**\n * @dev See {IERC777-authorizeOperator}.\n */\n function authorizeOperator(address operator) public virtual override {\n require(_msgSender() != operator, \"ERC777: authorizing self as operator\");\n\n if (_defaultOperators[operator]) {\n delete _revokedDefaultOperators[_msgSender()][operator];\n } else {\n _operators[_msgSender()][operator] = true;\n }\n\n emit AuthorizedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-revokeOperator}.\n */\n function revokeOperator(address operator) public virtual override {\n require(operator != _msgSender(), \"ERC777: revoking self as operator\");\n\n if (_defaultOperators[operator]) {\n _revokedDefaultOperators[_msgSender()][operator] = true;\n } else {\n delete _operators[_msgSender()][operator];\n }\n\n emit RevokedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-defaultOperators}.\n */\n function defaultOperators() public view virtual override returns (address[] memory) {\n return _defaultOperatorsArray;\n }\n\n /**\n * @dev See {IERC777-operatorSend}.\n *\n * Emits {Sent} and {IERC20-Transfer} events.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes memory data,\n bytes memory operatorData\n ) public virtual override {\n require(isOperatorFor(_msgSender(), sender), \"ERC777: caller is not an operator for holder\");\n _send(sender, recipient, amount, data, operatorData, true);\n }\n\n /**\n * @dev See {IERC777-operatorBurn}.\n *\n * Emits {Burned} and {IERC20-Transfer} events.\n */\n function operatorBurn(\n address account,\n uint256 amount,\n bytes memory data,\n bytes memory operatorData\n ) public virtual override {\n require(isOperatorFor(_msgSender(), account), \"ERC777: caller is not an operator for holder\");\n _burn(account, amount, data, operatorData);\n }\n\n /**\n * @dev See {IERC20-allowance}.\n *\n * Note that operator and allowance concepts are orthogonal: operators may\n * not have allowance, and accounts with allowance may not be operators\n * themselves.\n */\n function allowance(address holder, address spender) public view virtual override returns (uint256) {\n return _allowances[holder][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Note that accounts cannot have allowance issued by their operators.\n */\n function approve(address spender, uint256 value) public virtual override returns (bool) {\n address holder = _msgSender();\n _approve(holder, spender, value);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Note that operator and allowance concepts are orthogonal: operators cannot\n * call `transferFrom` (unless they have allowance), and accounts with\n * allowance cannot call `operatorSend` (unless they are operators).\n *\n * Emits {Sent}, {IERC20-Transfer} and {IERC20-Approval} events.\n */\n function transferFrom(address holder, address recipient, uint256 amount) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(holder, spender, amount);\n _send(holder, recipient, amount, \"\", \"\", false);\n return true;\n }\n\n /**\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with the caller address as the `operator` and with\n * `userData` and `operatorData`.\n *\n * See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits {Minted} and {IERC20-Transfer} events.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - if `account` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function _mint(address account, uint256 amount, bytes memory userData, bytes memory operatorData) internal virtual {\n _mint(account, amount, userData, operatorData, true);\n }\n\n /**\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * If `requireReceptionAck` is set to true, and if a send hook is\n * registered for `account`, the corresponding function will be called with\n * `operator`, `data` and `operatorData`.\n *\n * See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits {Minted} and {IERC20-Transfer} events.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - if `account` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function _mint(\n address account,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) internal virtual {\n require(account != address(0), \"ERC777: mint to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), account, amount);\n\n // Update state variables\n _totalSupply += amount;\n _balances[account] += amount;\n\n _callTokensReceived(operator, address(0), account, amount, userData, operatorData, requireReceptionAck);\n\n emit Minted(operator, account, amount, userData, operatorData);\n emit Transfer(address(0), account, amount);\n }\n\n /**\n * @dev Send tokens\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _send(\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) internal virtual {\n require(from != address(0), \"ERC777: transfer from the zero address\");\n require(to != address(0), \"ERC777: transfer to the zero address\");\n\n address operator = _msgSender();\n\n _callTokensToSend(operator, from, to, amount, userData, operatorData);\n\n _move(operator, from, to, amount, userData, operatorData);\n\n _callTokensReceived(operator, from, to, amount, userData, operatorData, requireReceptionAck);\n }\n\n /**\n * @dev Burn tokens\n * @param from address token holder address\n * @param amount uint256 amount of tokens to burn\n * @param data bytes extra information provided by the token holder\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _burn(address from, uint256 amount, bytes memory data, bytes memory operatorData) internal virtual {\n require(from != address(0), \"ERC777: burn from the zero address\");\n\n address operator = _msgSender();\n\n _callTokensToSend(operator, from, address(0), amount, data, operatorData);\n\n _beforeTokenTransfer(operator, from, address(0), amount);\n\n // Update state variables\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC777: burn amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Burned(operator, from, amount, data, operatorData);\n emit Transfer(from, address(0), amount);\n }\n\n function _move(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n ) private {\n _beforeTokenTransfer(operator, from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC777: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Sent(operator, from, to, amount, userData, operatorData);\n emit Transfer(from, to, amount);\n }\n\n /**\n * @dev See {ERC20-_approve}.\n *\n * Note that accounts cannot have allowance issued by their operators.\n */\n function _approve(address holder, address spender, uint256 value) internal virtual {\n require(holder != address(0), \"ERC777: approve from the zero address\");\n require(spender != address(0), \"ERC777: approve to the zero address\");\n\n _allowances[holder][spender] = value;\n emit Approval(holder, spender, value);\n }\n\n /**\n * @dev Call from.tokensToSend() if the interface is registered\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _callTokensToSend(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n ) private {\n address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(from, _TOKENS_SENDER_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Sender(implementer).tokensToSend(operator, from, to, amount, userData, operatorData);\n }\n }\n\n /**\n * @dev Call to.tokensReceived() if the interface is registered. Reverts if the recipient is a contract but\n * tokensReceived() was not registered for the recipient\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _callTokensReceived(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) private {\n address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(to, _TOKENS_RECIPIENT_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Recipient(implementer).tokensReceived(operator, from, to, amount, userData, operatorData);\n } else if (requireReceptionAck) {\n require(!to.isContract(), \"ERC777: token recipient contract has no implementer for ERC777TokensRecipient\");\n }\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {IERC20-Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC777: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes\n * calls to {send}, {transfer}, {operatorSend}, {transferFrom}, minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be to transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address operator, address from, address to, uint256 amount) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC777/IERC777.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777Token standard as defined in the EIP.\n *\n * This contract uses the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 registry standard] to let\n * token holders and recipients react to token movements by using setting implementers\n * for the associated interfaces in said registry. See {IERC1820Registry} and\n * {ERC1820Implementer}.\n */\ninterface IERC777 {\n /**\n * @dev Emitted when `amount` tokens are created by `operator` and assigned to `to`.\n *\n * Note that some additional user `data` and `operatorData` can be logged in the event.\n */\n event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);\n\n /**\n * @dev Emitted when `operator` destroys `amount` tokens from `account`.\n *\n * Note that some additional user `data` and `operatorData` can be logged in the event.\n */\n event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);\n\n /**\n * @dev Emitted when `operator` is made operator for `tokenHolder`.\n */\n event AuthorizedOperator(address indexed operator, address indexed tokenHolder);\n\n /**\n * @dev Emitted when `operator` is revoked its operator status for `tokenHolder`.\n */\n event RevokedOperator(address indexed operator, address indexed tokenHolder);\n\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, usually a shorter version of the\n * name.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the smallest part of the token that is not divisible. This\n * means all token operations (creation, movement and destruction) must have\n * amounts that are a multiple of this number.\n *\n * For most token contracts, this value will equal 1.\n */\n function granularity() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by an account (`owner`).\n */\n function balanceOf(address owner) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * If send or receive hooks are registered for the caller and `recipient`,\n * the corresponding functions will be called with `data` and empty\n * `operatorData`. See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits a {Sent} event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function send(address recipient, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Destroys `amount` tokens from the caller's account, reducing the\n * total supply.\n *\n * If a send hook is registered for the caller, the corresponding function\n * will be called with `data` and empty `operatorData`. See {IERC777Sender}.\n *\n * Emits a {Burned} event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n */\n function burn(uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Returns true if an account is an operator of `tokenHolder`.\n * Operators can send and burn tokens on behalf of their owners. All\n * accounts are their own operator.\n *\n * See {operatorSend} and {operatorBurn}.\n */\n function isOperatorFor(address operator, address tokenHolder) external view returns (bool);\n\n /**\n * @dev Make an account an operator of the caller.\n *\n * See {isOperatorFor}.\n *\n * Emits an {AuthorizedOperator} event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function authorizeOperator(address operator) external;\n\n /**\n * @dev Revoke an account's operator status for the caller.\n *\n * See {isOperatorFor} and {defaultOperators}.\n *\n * Emits a {RevokedOperator} event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function revokeOperator(address operator) external;\n\n /**\n * @dev Returns the list of default operators. These accounts are operators\n * for all token holders, even if {authorizeOperator} was never called on\n * them.\n *\n * This list is immutable, but individual holders may revoke these via\n * {revokeOperator}, in which case {isOperatorFor} will return false.\n */\n function defaultOperators() external view returns (address[] memory);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must\n * be an operator of `sender`.\n *\n * If send or receive hooks are registered for `sender` and `recipient`,\n * the corresponding functions will be called with `data` and\n * `operatorData`. See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits a {Sent} event.\n *\n * Requirements\n *\n * - `sender` cannot be the zero address.\n * - `sender` must have at least `amount` tokens.\n * - the caller must be an operator for `sender`.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes calldata data,\n bytes calldata operatorData\n ) external;\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the total supply.\n * The caller must be an operator of `account`.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with `data` and `operatorData`. See {IERC777Sender}.\n *\n * Emits a {Burned} event.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n * - the caller must be an operator for `account`.\n */\n function operatorBurn(address account, uint256 amount, bytes calldata data, bytes calldata operatorData) external;\n\n event Sent(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes data,\n bytes operatorData\n );\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\n *\n * Accounts can be notified of {IERC777} tokens being sent to them by having a\n * contract implement this interface (contract holders can be their own\n * implementer) and registering it on the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\n *\n * See {IERC1820Registry} and {ERC1820Implementer}.\n */\ninterface IERC777Recipient {\n /**\n * @dev Called by an {IERC777} token contract whenever tokens are being\n * moved or created into a registered account (`to`). The type of operation\n * is conveyed by `from` being the zero address or not.\n *\n * This call occurs _after_ the token contract's state is updated, so\n * {IERC777-balanceOf}, etc., can be used to query the post-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensReceived(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777Sender.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Sender.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777TokensSender standard as defined in the EIP.\n *\n * {IERC777} Token holders can be notified of operations performed on their\n * tokens by having a contract implement this interface (contract holders can be\n * their own implementer) and registering it on the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\n *\n * See {IERC1820Registry} and {ERC1820Implementer}.\n */\ninterface IERC777Sender {\n /**\n * @dev Called by an {IERC777} token contract whenever a registered holder's\n * (`from`) tokens are about to be moved or destroyed. The type of operation\n * is conveyed by `to` being the zero address or not.\n *\n * This call occurs _before_ the token contract's state is updated, so\n * {IERC777-balanceOf}, etc., can be used to query the pre-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensToSend(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n *\n * Furthermore, `isContract` will also return true if the target contract within\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n * which only has an effect at the end of a transaction.\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Counters.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary Counters {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/ECDSA.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Strings.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV // Deprecated in v4.8\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n /// @solidity memory-safe-assembly\n assembly {\n mstore(0x00, \"\\x19Ethereum Signed Message:\\n32\")\n mstore(0x1c, hash)\n message := keccak256(0x00, 0x3c)\n }\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\n /// @solidity memory-safe-assembly\n assembly {\n let ptr := mload(0x40)\n mstore(ptr, \"\\x19\\x01\")\n mstore(add(ptr, 0x02), domainSeparator)\n mstore(add(ptr, 0x22), structHash)\n data := keccak256(ptr, 0x42)\n }\n }\n\n /**\n * @dev Returns an Ethereum Signed Data with intended validator, created from a\n * `validator` and `data` according to the version 0 of EIP-191.\n *\n * See {recover}.\n */\n function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x00\", validator, data));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/SignatureChecker.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSA.sol\";\nimport \"../../interfaces/IERC1271.sol\";\n\n/**\n * @dev Signature verification helper that can be used instead of `ECDSA.recover` to seamlessly support both ECDSA\n * signatures from externally owned accounts (EOAs) as well as ERC1271 signatures from smart contract wallets like\n * Argent and Gnosis Safe.\n *\n * _Available since v4.1._\n */\nlibrary SignatureChecker {\n /**\n * @dev Checks if a signature is valid for a given signer and data hash. If the signer is a smart contract, the\n * signature is validated against that smart contract using ERC1271, otherwise it's validated using `ECDSA.recover`.\n *\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\n */\n function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature) internal view returns (bool) {\n (address recovered, ECDSA.RecoverError error) = ECDSA.tryRecover(hash, signature);\n return\n (error == ECDSA.RecoverError.NoError && recovered == signer) ||\n isValidERC1271SignatureNow(signer, hash, signature);\n }\n\n /**\n * @dev Checks if a signature is valid for a given signer and data hash. The signature is validated\n * against the signer smart contract using ERC1271.\n *\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\n */\n function isValidERC1271SignatureNow(\n address signer,\n bytes32 hash,\n bytes memory signature\n ) internal view returns (bool) {\n (bool success, bytes memory result) = signer.staticcall(\n abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, signature)\n );\n return (success &&\n result.length >= 32 &&\n abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/ERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165 is IERC165 {\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165).interfaceId;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC1820Registry.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/introspection/IERC1820Registry.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the global ERC1820 Registry, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register\n * implementers for interfaces in this registry, as well as query support.\n *\n * Implementers may be shared by multiple accounts, and can also implement more\n * than a single interface for each account. Contracts can implement interfaces\n * for themselves, but externally-owned accounts (EOA) must delegate this to a\n * contract.\n *\n * {IERC165} interfaces can also be queried via the registry.\n *\n * For an in-depth explanation and source code analysis, see the EIP text.\n */\ninterface IERC1820Registry {\n event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer);\n\n event ManagerChanged(address indexed account, address indexed newManager);\n\n /**\n * @dev Sets `newManager` as the manager for `account`. A manager of an\n * account is able to set interface implementers for it.\n *\n * By default, each account is its own manager. Passing a value of `0x0` in\n * `newManager` will reset the manager to this initial state.\n *\n * Emits a {ManagerChanged} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `account`.\n */\n function setManager(address account, address newManager) external;\n\n /**\n * @dev Returns the manager for `account`.\n *\n * See {setManager}.\n */\n function getManager(address account) external view returns (address);\n\n /**\n * @dev Sets the `implementer` contract as ``account``'s implementer for\n * `interfaceHash`.\n *\n * `account` being the zero address is an alias for the caller's address.\n * The zero address can also be used in `implementer` to remove an old one.\n *\n * See {interfaceHash} to learn how these are created.\n *\n * Emits an {InterfaceImplementerSet} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `account`.\n * - `interfaceHash` must not be an {IERC165} interface id (i.e. it must not\n * end in 28 zeroes).\n * - `implementer` must implement {IERC1820Implementer} and return true when\n * queried for support, unless `implementer` is the caller. See\n * {IERC1820Implementer-canImplementInterfaceForAddress}.\n */\n function setInterfaceImplementer(address account, bytes32 _interfaceHash, address implementer) external;\n\n /**\n * @dev Returns the implementer of `interfaceHash` for `account`. If no such\n * implementer is registered, returns the zero address.\n *\n * If `interfaceHash` is an {IERC165} interface id (i.e. it ends with 28\n * zeroes), `account` will be queried for support of it.\n *\n * `account` being the zero address is an alias for the caller's address.\n */\n function getInterfaceImplementer(address account, bytes32 _interfaceHash) external view returns (address);\n\n /**\n * @dev Returns the interface hash for an `interfaceName`, as defined in the\n * corresponding\n * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP].\n */\n function interfaceHash(string calldata interfaceName) external pure returns (bytes32);\n\n /**\n * @notice Updates the cache with whether the contract implements an ERC165 interface or not.\n * @param account Address of the contract for which to update the cache.\n * @param interfaceId ERC165 interface for which to update the cache.\n */\n function updateERC165Cache(address account, bytes4 interfaceId) external;\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not.\n * If the result is not cached a direct lookup on the contract address is performed.\n * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling\n * {updateERC165Cache} with the contract address.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool);\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not without using or updating the cache.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/math/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\n // The surrounding unchecked block does not change this fact.\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1, \"Math: mulDiv overflow\");\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n //\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n //\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n //\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1 << (log2(a) >> 1);\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = sqrt(a);\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 2, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 128;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 64;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 32;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 16;\n }\n if (value >> 8 > 0) {\n value >>= 8;\n result += 8;\n }\n if (value >> 4 > 0) {\n value >>= 4;\n result += 4;\n }\n if (value >> 2 > 0) {\n value >>= 2;\n result += 2;\n }\n if (value >> 1 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log2(value);\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 10, rounded down, of a positive value.\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 + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 256, rounded down, of a positive value.\n * Returns 0 if given 0.\n *\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n */\n function log256(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 16;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 8;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 4;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 2;\n }\n if (value >> 8 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log256(value);\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/SafeCast.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCast {\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 * _Available since v4.7._\n */\n function toUint248(uint256 value) internal pure returns (uint248) {\n require(value <= type(uint248).max, \"SafeCast: value doesn't fit in 248 bits\");\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 * _Available since v4.7._\n */\n function toUint240(uint256 value) internal pure returns (uint240) {\n require(value <= type(uint240).max, \"SafeCast: value doesn't fit in 240 bits\");\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 * _Available since v4.7._\n */\n function toUint232(uint256 value) internal pure returns (uint232) {\n require(value <= type(uint232).max, \"SafeCast: value doesn't fit in 232 bits\");\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 * _Available since v4.2._\n */\n function toUint224(uint256 value) internal pure returns (uint224) {\n require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\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 * _Available since v4.7._\n */\n function toUint216(uint256 value) internal pure returns (uint216) {\n require(value <= type(uint216).max, \"SafeCast: value doesn't fit in 216 bits\");\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 * _Available since v4.7._\n */\n function toUint208(uint256 value) internal pure returns (uint208) {\n require(value <= type(uint208).max, \"SafeCast: value doesn't fit in 208 bits\");\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 * _Available since v4.7._\n */\n function toUint200(uint256 value) internal pure returns (uint200) {\n require(value <= type(uint200).max, \"SafeCast: value doesn't fit in 200 bits\");\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 * _Available since v4.7._\n */\n function toUint192(uint256 value) internal pure returns (uint192) {\n require(value <= type(uint192).max, \"SafeCast: value doesn't fit in 192 bits\");\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 * _Available since v4.7._\n */\n function toUint184(uint256 value) internal pure returns (uint184) {\n require(value <= type(uint184).max, \"SafeCast: value doesn't fit in 184 bits\");\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 * _Available since v4.7._\n */\n function toUint176(uint256 value) internal pure returns (uint176) {\n require(value <= type(uint176).max, \"SafeCast: value doesn't fit in 176 bits\");\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 * _Available since v4.7._\n */\n function toUint168(uint256 value) internal pure returns (uint168) {\n require(value <= type(uint168).max, \"SafeCast: value doesn't fit in 168 bits\");\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 * _Available since v4.7._\n */\n function toUint160(uint256 value) internal pure returns (uint160) {\n require(value <= type(uint160).max, \"SafeCast: value doesn't fit in 160 bits\");\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 * _Available since v4.7._\n */\n function toUint152(uint256 value) internal pure returns (uint152) {\n require(value <= type(uint152).max, \"SafeCast: value doesn't fit in 152 bits\");\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 * _Available since v4.7._\n */\n function toUint144(uint256 value) internal pure returns (uint144) {\n require(value <= type(uint144).max, \"SafeCast: value doesn't fit in 144 bits\");\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 * _Available since v4.7._\n */\n function toUint136(uint256 value) internal pure returns (uint136) {\n require(value <= type(uint136).max, \"SafeCast: value doesn't fit in 136 bits\");\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 * _Available since v2.5._\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\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 * _Available since v4.7._\n */\n function toUint120(uint256 value) internal pure returns (uint120) {\n require(value <= type(uint120).max, \"SafeCast: value doesn't fit in 120 bits\");\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 * _Available since v4.7._\n */\n function toUint112(uint256 value) internal pure returns (uint112) {\n require(value <= type(uint112).max, \"SafeCast: value doesn't fit in 112 bits\");\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 * _Available since v4.7._\n */\n function toUint104(uint256 value) internal pure returns (uint104) {\n require(value <= type(uint104).max, \"SafeCast: value doesn't fit in 104 bits\");\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 * _Available since v4.2._\n */\n function toUint96(uint256 value) internal pure returns (uint96) {\n require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\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 * _Available since v4.7._\n */\n function toUint88(uint256 value) internal pure returns (uint88) {\n require(value <= type(uint88).max, \"SafeCast: value doesn't fit in 88 bits\");\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 * _Available since v4.7._\n */\n function toUint80(uint256 value) internal pure returns (uint80) {\n require(value <= type(uint80).max, \"SafeCast: value doesn't fit in 80 bits\");\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 * _Available since v4.7._\n */\n function toUint72(uint256 value) internal pure returns (uint72) {\n require(value <= type(uint72).max, \"SafeCast: value doesn't fit in 72 bits\");\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 * _Available since v2.5._\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\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 * _Available since v4.7._\n */\n function toUint56(uint256 value) internal pure returns (uint56) {\n require(value <= type(uint56).max, \"SafeCast: value doesn't fit in 56 bits\");\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 * _Available since v4.7._\n */\n function toUint48(uint256 value) internal pure returns (uint48) {\n require(value <= type(uint48).max, \"SafeCast: value doesn't fit in 48 bits\");\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 * _Available since v4.7._\n */\n function toUint40(uint256 value) internal pure returns (uint40) {\n require(value <= type(uint40).max, \"SafeCast: value doesn't fit in 40 bits\");\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 * _Available since v2.5._\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\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 * _Available since v4.7._\n */\n function toUint24(uint256 value) internal pure returns (uint24) {\n require(value <= type(uint24).max, \"SafeCast: value doesn't fit in 24 bits\");\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 * _Available since v2.5._\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\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 * _Available since v2.5._\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\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 * _Available since v3.0._\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\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 * _Available since v4.7._\n */\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\n downcasted = int248(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 248 bits\");\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 * _Available since v4.7._\n */\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\n downcasted = int240(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 240 bits\");\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 * _Available since v4.7._\n */\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\n downcasted = int232(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 232 bits\");\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 * _Available since v4.7._\n */\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\n downcasted = int224(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 224 bits\");\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 * _Available since v4.7._\n */\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\n downcasted = int216(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 216 bits\");\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 * _Available since v4.7._\n */\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\n downcasted = int208(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 208 bits\");\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 * _Available since v4.7._\n */\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\n downcasted = int200(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 200 bits\");\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 * _Available since v4.7._\n */\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\n downcasted = int192(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 192 bits\");\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 * _Available since v4.7._\n */\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\n downcasted = int184(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 184 bits\");\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 * _Available since v4.7._\n */\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\n downcasted = int176(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 176 bits\");\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 * _Available since v4.7._\n */\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\n downcasted = int168(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 168 bits\");\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 * _Available since v4.7._\n */\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\n downcasted = int160(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 160 bits\");\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 * _Available since v4.7._\n */\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\n downcasted = int152(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 152 bits\");\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 * _Available since v4.7._\n */\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\n downcasted = int144(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 144 bits\");\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 * _Available since v4.7._\n */\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\n downcasted = int136(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 136 bits\");\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 * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\n downcasted = int128(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 128 bits\");\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 * _Available since v4.7._\n */\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\n downcasted = int120(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 120 bits\");\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 * _Available since v4.7._\n */\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\n downcasted = int112(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 112 bits\");\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 * _Available since v4.7._\n */\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\n downcasted = int104(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 104 bits\");\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 * _Available since v4.7._\n */\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\n downcasted = int96(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 96 bits\");\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 * _Available since v4.7._\n */\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\n downcasted = int88(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 88 bits\");\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 * _Available since v4.7._\n */\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\n downcasted = int80(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 80 bits\");\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 * _Available since v4.7._\n */\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\n downcasted = int72(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 72 bits\");\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 * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\n downcasted = int64(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 64 bits\");\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 * _Available since v4.7._\n */\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\n downcasted = int56(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 56 bits\");\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 * _Available since v4.7._\n */\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\n downcasted = int48(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 48 bits\");\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 * _Available since v4.7._\n */\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\n downcasted = int40(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 40 bits\");\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 * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\n downcasted = int32(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 32 bits\");\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 * _Available since v4.7._\n */\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\n downcasted = int24(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 24 bits\");\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 * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\n downcasted = int16(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 16 bits\");\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 * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\n downcasted = int8(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 8 bits\");\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 * _Available since v3.0._\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 require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/SignedMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard signed math utilities missing in the Solidity language.\n */\nlibrary SignedMath {\n /**\n * @dev Returns the largest of two signed numbers.\n */\n function max(int256 a, int256 b) internal pure returns (int256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two signed numbers.\n */\n function min(int256 a, int256 b) internal pure returns (int256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two signed numbers without overflow.\n * The result is rounded towards zero.\n */\n function average(int256 a, int256 b) internal pure returns (int256) {\n // Formula from the book \"Hacker's Delight\"\n int256 x = (a & b) + ((a ^ b) >> 1);\n return x + (int256(uint256(x) >> 255) & (a ^ b));\n }\n\n /**\n * @dev Returns the absolute unsigned value of a signed value.\n */\n function abs(int256 n) internal pure returns (uint256) {\n unchecked {\n // must be unchecked in order to support `n = type(int256).min`\n return uint256(n >= 0 ? n : -n);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/Math.sol\";\nimport \"./math/SignedMath.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n unchecked {\n uint256 length = Math.log10(value) + 1;\n string memory buffer = new string(length);\n uint256 ptr;\n /// @solidity memory-safe-assembly\n assembly {\n ptr := add(buffer, add(32, length))\n }\n while (true) {\n ptr--;\n /// @solidity memory-safe-assembly\n assembly {\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n }\n value /= 10;\n if (value == 0) break;\n }\n return buffer;\n }\n }\n\n /**\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\n */\n function toString(int256 value) internal pure returns (string memory) {\n return string(abi.encodePacked(value < 0 ? \"-\" : \"\", toString(SignedMath.abs(value))));\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n unchecked {\n return toHexString(value, Math.log256(value) + 1);\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n\n /**\n * @dev Returns true if the two strings are equal.\n */\n function equal(string memory a, string memory b) internal pure returns (bool) {\n return keccak256(bytes(a)) == keccak256(bytes(b));\n }\n}\n" + }, + "contracts/aa-4337/core/BaseAccount.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-empty-blocks */\n\nimport \"../interfaces/IAccount.sol\";\nimport \"../interfaces/IEntryPoint.sol\";\nimport \"./Helpers.sol\";\n\n/**\n * Basic account implementation.\n * this contract provides the basic logic for implementing the IAccount interface - validateUserOp\n * specific account implementation should inherit it and provide the account-specific logic\n */\nabstract contract BaseAccount is IAccount {\n using UserOperationLib for UserOperation;\n\n //return value in case of signature failure, with no time-range.\n // equivalent to _packValidationData(true,0,0);\n uint256 internal constant SIG_VALIDATION_FAILED = 1;\n\n /**\n * Return the account nonce.\n * This method returns the next sequential nonce.\n * For a nonce of a specific key, use `entrypoint.getNonce(account, key)`\n */\n function getNonce() public view virtual returns (uint256) {\n return entryPoint().getNonce(address(this), 0);\n }\n\n /**\n * return the entryPoint used by this account.\n * subclass should return the current entryPoint used by this account.\n */\n function entryPoint() public view virtual returns (IEntryPoint);\n\n /**\n * Validate user's signature and nonce.\n * subclass doesn't need to override this method. Instead, it should override the specific internal validation methods.\n */\n function validateUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 missingAccountFunds\n ) external virtual override returns (uint256 validationData) {\n _requireFromEntryPoint();\n validationData = _validateSignature(userOp, userOpHash);\n _validateNonce(userOp.nonce);\n _payPrefund(missingAccountFunds);\n }\n\n /**\n * ensure the request comes from the known entrypoint.\n */\n function _requireFromEntryPoint() internal view virtual {\n require(\n msg.sender == address(entryPoint()),\n \"account: not from EntryPoint\"\n );\n }\n\n /**\n * validate the signature is valid for this message.\n * @param userOp validate the userOp.signature field\n * @param userOpHash convenient field: the hash of the request, to check the signature against\n * (also hashes the entrypoint and chain id)\n * @return validationData signature and time-range of this operation\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * If the account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function _validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) internal virtual returns (uint256 validationData);\n\n /**\n * Validate the nonce of the UserOperation.\n * This method may validate the nonce requirement of this account.\n * e.g.\n * To limit the nonce to use sequenced UserOps only (no \"out of order\" UserOps):\n * `require(nonce < type(uint64).max)`\n * For a hypothetical account that *requires* the nonce to be out-of-order:\n * `require(nonce & type(uint64).max == 0)`\n *\n * The actual nonce uniqueness is managed by the EntryPoint, and thus no other\n * action is needed by the account itself.\n *\n * @param nonce to validate\n *\n * solhint-disable-next-line no-empty-blocks\n */\n function _validateNonce(uint256 nonce) internal view virtual {}\n\n /**\n * sends to the entrypoint (msg.sender) the missing funds for this transaction.\n * subclass MAY override this method for better funds management\n * (e.g. send to the entryPoint more than the minimum required, so that in future transactions\n * it will not be required to send again)\n * @param missingAccountFunds the minimum value this method should send the entrypoint.\n * this value MAY be zero, in case there is enough deposit, or the userOp has a paymaster.\n */\n function _payPrefund(uint256 missingAccountFunds) internal virtual {\n if (missingAccountFunds != 0) {\n (bool success, ) = payable(msg.sender).call{\n value: missingAccountFunds,\n gas: type(uint256).max\n }(\"\");\n (success);\n //ignore failure (its EntryPoint's job to verify, not account.)\n }\n }\n}\n" + }, + "contracts/aa-4337/core/EntryPoint.sol": { + "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n\nimport \"../interfaces/IAccount.sol\";\nimport \"../interfaces/IPaymaster.sol\";\nimport \"../interfaces/IEntryPoint.sol\";\n\nimport \"../utils/Exec.sol\";\nimport \"./StakeManager.sol\";\nimport \"./SenderCreator.sol\";\nimport \"./Helpers.sol\";\nimport \"./NonceManager.sol\";\nimport \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\n\ncontract EntryPoint is\n IEntryPoint,\n StakeManager,\n NonceManager,\n ReentrancyGuard\n{\n using UserOperationLib for UserOperation;\n\n SenderCreator private immutable senderCreator = new SenderCreator();\n\n // internal value used during simulation: need to query aggregator.\n address private constant SIMULATE_FIND_AGGREGATOR = address(1);\n\n // marker for inner call revert on out of gas\n bytes32 private constant INNER_OUT_OF_GAS = hex\"deaddead\";\n\n uint256 private constant REVERT_REASON_MAX_LEN = 2048;\n\n /**\n * for simulation purposes, validateUserOp (and validatePaymasterUserOp) must return this value\n * in case of signature failure, instead of revert.\n */\n uint256 public constant SIG_VALIDATION_FAILED = 1;\n\n /**\n * compensate the caller's beneficiary address with the collected fees of all UserOperations.\n * @param beneficiary the address to receive the fees\n * @param amount amount to transfer.\n */\n function _compensate(address payable beneficiary, uint256 amount) internal {\n require(beneficiary != address(0), \"AA90 invalid beneficiary\");\n (bool success, ) = beneficiary.call{value: amount}(\"\");\n require(success, \"AA91 failed send to beneficiary\");\n }\n\n /**\n * execute a user op\n * @param opIndex index into the opInfo array\n * @param userOp the userOp to execute\n * @param opInfo the opInfo filled by validatePrepayment for this userOp.\n * @return collected the total amount this userOp paid.\n */\n function _executeUserOp(\n uint256 opIndex,\n UserOperation calldata userOp,\n UserOpInfo memory opInfo\n ) private returns (uint256 collected) {\n uint256 preGas = gasleft();\n bytes memory context = getMemoryBytesFromOffset(opInfo.contextOffset);\n\n try this.innerHandleOp(userOp.callData, opInfo, context) returns (\n uint256 _actualGasCost\n ) {\n collected = _actualGasCost;\n } catch {\n bytes32 innerRevertCode;\n assembly {\n returndatacopy(0, 0, 32)\n innerRevertCode := mload(0)\n }\n // handleOps was called with gas limit too low. abort entire bundle.\n if (innerRevertCode == INNER_OUT_OF_GAS) {\n //report paymaster, since if it is not deliberately caused by the bundler,\n // it must be a revert caused by paymaster.\n revert FailedOp(opIndex, \"AA95 out of gas\");\n }\n\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n collected = _handlePostOp(\n opIndex,\n IPaymaster.PostOpMode.postOpReverted,\n opInfo,\n context,\n actualGas\n );\n }\n }\n\n /**\n * Execute a batch of UserOperations.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(\n UserOperation[] calldata ops,\n address payable beneficiary\n ) public nonReentrant {\n uint256 opslen = ops.length;\n UserOpInfo[] memory opInfos = new UserOpInfo[](opslen);\n\n unchecked {\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[i];\n (\n uint256 validationData,\n uint256 pmValidationData\n ) = _validatePrepayment(i, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(\n i,\n validationData,\n pmValidationData,\n address(0)\n );\n }\n\n uint256 collected = 0;\n emit BeforeExecution();\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(i, ops[i], opInfos[i]);\n }\n\n _compensate(beneficiary, collected);\n } //unchecked\n }\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) public nonReentrant {\n uint256 opasLen = opsPerAggregator.length;\n uint256 totalOps = 0;\n for (uint256 i = 0; i < opasLen; i++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[i];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n //address(1) is special marker of \"signature error\"\n require(\n address(aggregator) != address(1),\n \"AA96 invalid aggregator\"\n );\n\n if (address(aggregator) != address(0)) {\n // solhint-disable-next-line no-empty-blocks\n try aggregator.validateSignatures(ops, opa.signature) {} catch {\n revert SignatureValidationFailed(address(aggregator));\n }\n }\n\n totalOps += ops.length;\n }\n\n UserOpInfo[] memory opInfos = new UserOpInfo[](totalOps);\n\n emit BeforeExecution();\n\n uint256 opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n uint256 opslen = ops.length;\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[opIndex];\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(opIndex, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(\n i,\n validationData,\n paymasterValidationData,\n address(aggregator)\n );\n opIndex++;\n }\n }\n\n uint256 collected = 0;\n opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n emit SignatureAggregatorChanged(address(opa.aggregator));\n UserOperation[] calldata ops = opa.userOps;\n uint256 opslen = ops.length;\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(opIndex, ops[i], opInfos[opIndex]);\n opIndex++;\n }\n }\n emit SignatureAggregatorChanged(address(0));\n\n _compensate(beneficiary, collected);\n }\n\n /// @inheritdoc IEntryPoint\n function simulateHandleOp(\n UserOperation calldata op,\n address target,\n bytes calldata targetCallData\n ) external override {\n UserOpInfo memory opInfo;\n _simulationOnlyValidations(op);\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(0, op, opInfo);\n ValidationData memory data = _intersectTimeRange(\n validationData,\n paymasterValidationData\n );\n\n numberMarker();\n uint256 paid = _executeUserOp(0, op, opInfo);\n numberMarker();\n bool targetSuccess;\n bytes memory targetResult;\n if (target != address(0)) {\n (targetSuccess, targetResult) = target.call(targetCallData);\n }\n revert ExecutionResult(\n opInfo.preOpGas,\n paid,\n data.validAfter,\n data.validUntil,\n targetSuccess,\n targetResult\n );\n }\n\n // A memory copy of UserOp static fields only.\n // Excluding: callData, initCode and signature. Replacing paymasterAndData with paymaster.\n struct MemoryUserOp {\n address sender;\n uint256 nonce;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n address paymaster;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n }\n\n struct UserOpInfo {\n MemoryUserOp mUserOp;\n bytes32 userOpHash;\n uint256 prefund;\n uint256 contextOffset;\n uint256 preOpGas;\n }\n\n /**\n * inner function to handle a UserOperation.\n * Must be declared \"external\" to open a call context, but it can only be called by handleOps.\n */\n function innerHandleOp(\n bytes memory callData,\n UserOpInfo memory opInfo,\n bytes calldata context\n ) external returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n require(msg.sender == address(this), \"AA92 internal call only\");\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n\n uint callGasLimit = mUserOp.callGasLimit;\n unchecked {\n // handleOps was called with gas limit too low. abort entire bundle.\n if (\n gasleft() < callGasLimit + mUserOp.verificationGasLimit + 5000\n ) {\n assembly {\n mstore(0, INNER_OUT_OF_GAS)\n revert(0, 32)\n }\n }\n }\n\n IPaymaster.PostOpMode mode = IPaymaster.PostOpMode.opSucceeded;\n if (callData.length > 0) {\n bool success = Exec.call(mUserOp.sender, 0, callData, callGasLimit);\n if (!success) {\n bytes memory result = Exec.getReturnData(REVERT_REASON_MAX_LEN);\n if (result.length > 0) {\n emit UserOperationRevertReason(\n opInfo.userOpHash,\n mUserOp.sender,\n mUserOp.nonce,\n result\n );\n }\n mode = IPaymaster.PostOpMode.opReverted;\n }\n }\n\n unchecked {\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n //note: opIndex is ignored (relevant only if mode==postOpReverted, which is only possible outside of innerHandleOp)\n return _handlePostOp(0, mode, opInfo, context, actualGas);\n }\n }\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(\n UserOperation calldata userOp\n ) public view returns (bytes32) {\n return\n keccak256(abi.encode(userOp.hash(), address(this), block.chainid));\n }\n\n /**\n * copy general fields from userOp into the memory opInfo structure.\n */\n function _copyUserOpToMemory(\n UserOperation calldata userOp,\n MemoryUserOp memory mUserOp\n ) internal pure {\n mUserOp.sender = userOp.sender;\n mUserOp.nonce = userOp.nonce;\n mUserOp.callGasLimit = userOp.callGasLimit;\n mUserOp.verificationGasLimit = userOp.verificationGasLimit;\n mUserOp.preVerificationGas = userOp.preVerificationGas;\n mUserOp.maxFeePerGas = userOp.maxFeePerGas;\n mUserOp.maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes calldata paymasterAndData = userOp.paymasterAndData;\n if (paymasterAndData.length > 0) {\n require(\n paymasterAndData.length >= 20,\n \"AA93 invalid paymasterAndData\"\n );\n mUserOp.paymaster = address(bytes20(paymasterAndData[:20]));\n } else {\n mUserOp.paymaster = address(0);\n }\n }\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external {\n UserOpInfo memory outOpInfo;\n\n _simulationOnlyValidations(userOp);\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(0, userOp, outOpInfo);\n StakeInfo memory paymasterInfo = _getStakeInfo(\n outOpInfo.mUserOp.paymaster\n );\n StakeInfo memory senderInfo = _getStakeInfo(outOpInfo.mUserOp.sender);\n StakeInfo memory factoryInfo;\n {\n bytes calldata initCode = userOp.initCode;\n address factory = initCode.length >= 20\n ? address(bytes20(initCode[0:20]))\n : address(0);\n factoryInfo = _getStakeInfo(factory);\n }\n\n ValidationData memory data = _intersectTimeRange(\n validationData,\n paymasterValidationData\n );\n address aggregator = data.aggregator;\n bool sigFailed = aggregator == address(1);\n ReturnInfo memory returnInfo = ReturnInfo(\n outOpInfo.preOpGas,\n outOpInfo.prefund,\n sigFailed,\n data.validAfter,\n data.validUntil,\n getMemoryBytesFromOffset(outOpInfo.contextOffset)\n );\n\n if (aggregator != address(0) && aggregator != address(1)) {\n AggregatorStakeInfo memory aggregatorInfo = AggregatorStakeInfo(\n aggregator,\n _getStakeInfo(aggregator)\n );\n revert ValidationResultWithAggregation(\n returnInfo,\n senderInfo,\n factoryInfo,\n paymasterInfo,\n aggregatorInfo\n );\n }\n revert ValidationResult(\n returnInfo,\n senderInfo,\n factoryInfo,\n paymasterInfo\n );\n }\n\n function _getRequiredPrefund(\n MemoryUserOp memory mUserOp\n ) internal pure returns (uint256 requiredPrefund) {\n unchecked {\n //when using a Paymaster, the verificationGasLimit is used also to as a limit for the postOp call.\n // our security model might call postOp eventually twice\n uint256 mul = mUserOp.paymaster != address(0) ? 3 : 1;\n uint256 requiredGas = mUserOp.callGasLimit +\n mUserOp.verificationGasLimit *\n mul +\n mUserOp.preVerificationGas;\n\n requiredPrefund = requiredGas * mUserOp.maxFeePerGas;\n }\n }\n\n // create the sender's contract if needed.\n function _createSenderIfNeeded(\n uint256 opIndex,\n UserOpInfo memory opInfo,\n bytes calldata initCode\n ) internal {\n if (initCode.length != 0) {\n address sender = opInfo.mUserOp.sender;\n if (sender.code.length != 0)\n revert FailedOp(opIndex, \"AA10 sender already constructed\");\n address sender1 = senderCreator.createSender{\n gas: opInfo.mUserOp.verificationGasLimit\n }(initCode);\n if (sender1 == address(0))\n revert FailedOp(opIndex, \"AA13 initCode failed or OOG\");\n if (sender1 != sender)\n revert FailedOp(opIndex, \"AA14 initCode must return sender\");\n if (sender1.code.length == 0)\n revert FailedOp(opIndex, \"AA15 initCode must create sender\");\n address factory = address(bytes20(initCode[0:20]));\n emit AccountDeployed(\n opInfo.userOpHash,\n sender,\n factory,\n opInfo.mUserOp.paymaster\n );\n }\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes calldata initCode) public {\n address sender = senderCreator.createSender(initCode);\n revert SenderAddressResult(sender);\n }\n\n function _simulationOnlyValidations(\n UserOperation calldata userOp\n ) internal view {\n // solhint-disable-next-line no-empty-blocks\n try\n this._validateSenderAndPaymaster(\n userOp.initCode,\n userOp.sender,\n userOp.paymasterAndData\n )\n {} catch Error(string memory revertReason) {\n if (bytes(revertReason).length != 0) {\n revert FailedOp(0, revertReason);\n }\n }\n }\n\n /**\n * Called only during simulation.\n * This function always reverts to prevent warm/cold storage differentiation in simulation vs execution.\n */\n function _validateSenderAndPaymaster(\n bytes calldata initCode,\n address sender,\n bytes calldata paymasterAndData\n ) external view {\n if (initCode.length == 0 && sender.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA20 account not deployed\");\n }\n if (paymasterAndData.length >= 20) {\n address paymaster = address(bytes20(paymasterAndData[0:20]));\n if (paymaster.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA30 paymaster not deployed\");\n }\n }\n // always revert\n revert(\"\");\n }\n\n /**\n * call account.validateUserOp.\n * revert (with FailedOp) in case validateUserOp reverts, or account didn't send required prefund.\n * decrement account's deposit if needed\n */\n function _validateAccountPrepayment(\n uint256 opIndex,\n UserOperation calldata op,\n UserOpInfo memory opInfo,\n uint256 requiredPrefund\n )\n internal\n returns (\n uint256 gasUsedByValidateAccountPrepayment,\n uint256 validationData\n )\n {\n unchecked {\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n address sender = mUserOp.sender;\n _createSenderIfNeeded(opIndex, opInfo, op.initCode);\n address paymaster = mUserOp.paymaster;\n numberMarker();\n uint256 missingAccountFunds = 0;\n if (paymaster == address(0)) {\n uint256 bal = balanceOf(sender);\n missingAccountFunds = bal > requiredPrefund\n ? 0\n : requiredPrefund - bal;\n }\n try\n IAccount(sender).validateUserOp{\n gas: mUserOp.verificationGasLimit\n }(op, opInfo.userOpHash, missingAccountFunds)\n returns (uint256 _validationData) {\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA23 reverted: \", revertReason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA23 reverted (or OOG)\");\n }\n if (paymaster == address(0)) {\n DepositInfo storage senderInfo = deposits[sender];\n uint256 deposit = senderInfo.deposit;\n if (requiredPrefund > deposit) {\n revert FailedOp(opIndex, \"AA21 didn't pay prefund\");\n }\n senderInfo.deposit = uint112(deposit - requiredPrefund);\n }\n gasUsedByValidateAccountPrepayment = preGas - gasleft();\n }\n }\n\n /**\n * In case the request has a paymaster:\n * Validate paymaster has enough deposit.\n * Call paymaster.validatePaymasterUserOp.\n * Revert with proper FailedOp in case paymaster reverts.\n * Decrement paymaster's deposit\n */\n function _validatePaymasterPrepayment(\n uint256 opIndex,\n UserOperation calldata op,\n UserOpInfo memory opInfo,\n uint256 requiredPreFund,\n uint256 gasUsedByValidateAccountPrepayment\n ) internal returns (bytes memory context, uint256 validationData) {\n unchecked {\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 verificationGasLimit = mUserOp.verificationGasLimit;\n require(\n verificationGasLimit > gasUsedByValidateAccountPrepayment,\n \"AA41 too little verificationGas\"\n );\n uint256 gas = verificationGasLimit -\n gasUsedByValidateAccountPrepayment;\n\n address paymaster = mUserOp.paymaster;\n DepositInfo storage paymasterInfo = deposits[paymaster];\n uint256 deposit = paymasterInfo.deposit;\n if (deposit < requiredPreFund) {\n revert FailedOp(opIndex, \"AA31 paymaster deposit too low\");\n }\n paymasterInfo.deposit = uint112(deposit - requiredPreFund);\n try\n IPaymaster(paymaster).validatePaymasterUserOp{gas: gas}(\n op,\n opInfo.userOpHash,\n requiredPreFund\n )\n returns (bytes memory _context, uint256 _validationData) {\n context = _context;\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA33 reverted: \", revertReason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA33 reverted (or OOG)\");\n }\n }\n }\n\n /**\n * revert if either account validationData or paymaster validationData is expired\n */\n function _validateAccountAndPaymasterValidationData(\n uint256 opIndex,\n uint256 validationData,\n uint256 paymasterValidationData,\n address expectedAggregator\n ) internal view {\n (address aggregator, bool outOfTimeRange) = _getValidationData(\n validationData\n );\n if (expectedAggregator != aggregator) {\n revert FailedOp(opIndex, \"AA24 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA22 expired or not due\");\n }\n //pmAggregator is not a real signature aggregator: we don't have logic to handle it as address.\n // non-zero address means that the paymaster fails due to some signature check (which is ok only during estimation)\n address pmAggregator;\n (pmAggregator, outOfTimeRange) = _getValidationData(\n paymasterValidationData\n );\n if (pmAggregator != address(0)) {\n revert FailedOp(opIndex, \"AA34 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA32 paymaster expired or not due\");\n }\n }\n\n function _getValidationData(\n uint256 validationData\n ) internal view returns (address aggregator, bool outOfTimeRange) {\n if (validationData == 0) {\n return (address(0), false);\n }\n ValidationData memory data = _parseValidationData(validationData);\n // solhint-disable-next-line not-rely-on-time\n outOfTimeRange =\n block.timestamp > data.validUntil ||\n block.timestamp < data.validAfter;\n aggregator = data.aggregator;\n }\n\n /**\n * validate account and paymaster (if defined).\n * also make sure total validation doesn't exceed verificationGasLimit\n * this method is called off-chain (simulateValidation()) and on-chain (from handleOps)\n * @param opIndex the index of this userOp into the \"opInfos\" array\n * @param userOp the userOp to validate\n */\n function _validatePrepayment(\n uint256 opIndex,\n UserOperation calldata userOp,\n UserOpInfo memory outOpInfo\n )\n private\n returns (uint256 validationData, uint256 paymasterValidationData)\n {\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = outOpInfo.mUserOp;\n _copyUserOpToMemory(userOp, mUserOp);\n outOpInfo.userOpHash = getUserOpHash(userOp);\n\n // validate all numeric values in userOp are well below 128 bit, so they can safely be added\n // and multiplied without causing overflow\n uint256 maxGasValues = mUserOp.preVerificationGas |\n mUserOp.verificationGasLimit |\n mUserOp.callGasLimit |\n userOp.maxFeePerGas |\n userOp.maxPriorityFeePerGas;\n require(maxGasValues <= type(uint120).max, \"AA94 gas values overflow\");\n\n uint256 gasUsedByValidateAccountPrepayment;\n uint256 requiredPreFund = _getRequiredPrefund(mUserOp);\n (\n gasUsedByValidateAccountPrepayment,\n validationData\n ) = _validateAccountPrepayment(\n opIndex,\n userOp,\n outOpInfo,\n requiredPreFund\n );\n\n if (!_validateAndUpdateNonce(mUserOp.sender, mUserOp.nonce)) {\n revert FailedOp(opIndex, \"AA25 invalid account nonce\");\n }\n\n //a \"marker\" where account opcode validation is done and paymaster opcode validation is about to start\n // (used only by off-chain simulateValidation)\n numberMarker();\n\n bytes memory context;\n if (mUserOp.paymaster != address(0)) {\n (context, paymasterValidationData) = _validatePaymasterPrepayment(\n opIndex,\n userOp,\n outOpInfo,\n requiredPreFund,\n gasUsedByValidateAccountPrepayment\n );\n }\n unchecked {\n uint256 gasUsed = preGas - gasleft();\n\n if (userOp.verificationGasLimit < gasUsed) {\n revert FailedOp(opIndex, \"AA40 over verificationGasLimit\");\n }\n outOpInfo.prefund = requiredPreFund;\n outOpInfo.contextOffset = getOffsetOfMemoryBytes(context);\n outOpInfo.preOpGas = preGas - gasleft() + userOp.preVerificationGas;\n }\n }\n\n /**\n * process post-operation.\n * called just after the callData is executed.\n * if a paymaster is defined and its validation returned a non-empty context, its postOp is called.\n * the excess amount is refunded to the account (or paymaster - if it was used in the request)\n * @param opIndex index in the batch\n * @param mode - whether is called from innerHandleOp, or outside (postOpReverted)\n * @param opInfo userOp fields and info collected during validation\n * @param context the context returned in validatePaymasterUserOp\n * @param actualGas the gas used so far by this user operation\n */\n function _handlePostOp(\n uint256 opIndex,\n IPaymaster.PostOpMode mode,\n UserOpInfo memory opInfo,\n bytes memory context,\n uint256 actualGas\n ) private returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n unchecked {\n address refundAddress;\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 gasPrice = getUserOpGasPrice(mUserOp);\n\n address paymaster = mUserOp.paymaster;\n if (paymaster == address(0)) {\n refundAddress = mUserOp.sender;\n } else {\n refundAddress = paymaster;\n if (context.length > 0) {\n actualGasCost = actualGas * gasPrice;\n if (mode != IPaymaster.PostOpMode.postOpReverted) {\n IPaymaster(paymaster).postOp{\n gas: mUserOp.verificationGasLimit\n }(mode, context, actualGasCost);\n } else {\n // solhint-disable-next-line no-empty-blocks\n try\n IPaymaster(paymaster).postOp{\n gas: mUserOp.verificationGasLimit\n }(mode, context, actualGasCost)\n {} catch Error(string memory reason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA50 postOp reverted: \", reason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA50 postOp revert\");\n }\n }\n }\n }\n actualGas += preGas - gasleft();\n actualGasCost = actualGas * gasPrice;\n if (opInfo.prefund < actualGasCost) {\n revert FailedOp(opIndex, \"AA51 prefund below actualGasCost\");\n }\n uint256 refund = opInfo.prefund - actualGasCost;\n _incrementDeposit(refundAddress, refund);\n bool success = mode == IPaymaster.PostOpMode.opSucceeded;\n emit UserOperationEvent(\n opInfo.userOpHash,\n mUserOp.sender,\n mUserOp.paymaster,\n mUserOp.nonce,\n success,\n actualGasCost,\n actualGas\n );\n } // unchecked\n }\n\n /**\n * the gas price this UserOp agrees to pay.\n * relayer/block builder might submit the TX with higher priorityFee, but the user should not\n */\n function getUserOpGasPrice(\n MemoryUserOp memory mUserOp\n ) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = mUserOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = mUserOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n function getOffsetOfMemoryBytes(\n bytes memory data\n ) internal pure returns (uint256 offset) {\n assembly {\n offset := data\n }\n }\n\n function getMemoryBytesFromOffset(\n uint256 offset\n ) internal pure returns (bytes memory data) {\n assembly {\n data := offset\n }\n }\n\n //place the NUMBER opcode in the code.\n // this is used as a marker during simulation, as this OP is completely banned from the simulated code of the\n // account and paymaster.\n function numberMarker() internal view {\n assembly {\n mstore(0, number())\n }\n }\n}\n" + }, + "contracts/aa-4337/core/Helpers.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable no-inline-assembly */\n\n/**\n * returned data from validateUserOp.\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\n * @param aggregator - address(0) - the account validated the signature by itself.\n * address(1) - the account failed to validate the signature.\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\n * @param validAfter - this UserOp is valid only after this timestamp.\n * @param validaUntil - this UserOp is valid only up to this timestamp.\n */\nstruct ValidationData {\n address aggregator;\n uint48 validAfter;\n uint48 validUntil;\n}\n\n//extract sigFailed, validAfter, validUntil.\n// also convert zero validUntil to type(uint48).max\nfunction _parseValidationData(\n uint validationData\n) pure returns (ValidationData memory data) {\n address aggregator = address(uint160(validationData));\n uint48 validUntil = uint48(validationData >> 160);\n if (validUntil == 0) {\n validUntil = type(uint48).max;\n }\n uint48 validAfter = uint48(validationData >> (48 + 160));\n return ValidationData(aggregator, validAfter, validUntil);\n}\n\n// intersect account and paymaster ranges.\nfunction _intersectTimeRange(\n uint256 validationData,\n uint256 paymasterValidationData\n) pure returns (ValidationData memory) {\n ValidationData memory accountValidationData = _parseValidationData(\n validationData\n );\n ValidationData memory pmValidationData = _parseValidationData(\n paymasterValidationData\n );\n address aggregator = accountValidationData.aggregator;\n if (aggregator == address(0)) {\n aggregator = pmValidationData.aggregator;\n }\n uint48 validAfter = accountValidationData.validAfter;\n uint48 validUntil = accountValidationData.validUntil;\n uint48 pmValidAfter = pmValidationData.validAfter;\n uint48 pmValidUntil = pmValidationData.validUntil;\n\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\n return ValidationData(aggregator, validAfter, validUntil);\n}\n\n/**\n * helper to pack the return value for validateUserOp\n * @param data - the ValidationData to pack\n */\nfunction _packValidationData(\n ValidationData memory data\n) pure returns (uint256) {\n return\n uint160(data.aggregator) |\n (uint256(data.validUntil) << 160) |\n (uint256(data.validAfter) << (160 + 48));\n}\n\n/**\n * helper to pack the return value for validateUserOp, when not using an aggregator\n * @param sigFailed - true for signature failure, false for success\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\n * @param validAfter first timestamp this UserOperation is valid\n */\nfunction _packValidationData(\n bool sigFailed,\n uint48 validUntil,\n uint48 validAfter\n) pure returns (uint256) {\n return\n (sigFailed ? 1 : 0) |\n (uint256(validUntil) << 160) |\n (uint256(validAfter) << (160 + 48));\n}\n\n/**\n * keccak function over calldata.\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\n */\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\n assembly {\n let mem := mload(0x40)\n let len := data.length\n calldatacopy(mem, data.offset, len)\n ret := keccak256(mem, len)\n }\n}\n" + }, + "contracts/aa-4337/core/NonceManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\nimport \"../interfaces/IEntryPoint.sol\";\n\n/**\n * nonce management functionality\n */\ncontract NonceManager is INonceManager {\n /**\n * The next valid sequence number for a given nonce key.\n */\n mapping(address => mapping(uint192 => uint256)) public nonceSequenceNumber;\n\n function getNonce(\n address sender,\n uint192 key\n ) public view override returns (uint256 nonce) {\n return nonceSequenceNumber[sender][key] | (uint256(key) << 64);\n }\n\n // allow an account to manually increment its own nonce.\n // (mainly so that during construction nonce can be made non-zero,\n // to \"absorb\" the gas cost of first nonce increment to 1st transaction (construction),\n // not to 2nd transaction)\n function incrementNonce(uint192 key) public override {\n nonceSequenceNumber[msg.sender][key]++;\n }\n\n /**\n * validate nonce uniqueness for this account.\n * called just after validateUserOp()\n */\n function _validateAndUpdateNonce(\n address sender,\n uint256 nonce\n ) internal returns (bool) {\n uint192 key = uint192(nonce >> 64);\n uint64 seq = uint64(nonce);\n return nonceSequenceNumber[sender][key]++ == seq;\n }\n}\n" + }, + "contracts/aa-4337/core/SenderCreator.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/**\n * helper contract for EntryPoint, to call userOp.initCode from a \"neutral\" address,\n * which is explicitly not the entryPoint itself.\n */\ncontract SenderCreator {\n /**\n * call the \"initCode\" factory to create and return the sender account address\n * @param initCode the initCode value from a UserOp. contains 20 bytes of factory address, followed by calldata\n * @return sender the returned address of the created account, or zero address on failure.\n */\n function createSender(\n bytes calldata initCode\n ) external returns (address sender) {\n address factory = address(bytes20(initCode[0:20]));\n bytes memory initCallData = initCode[20:];\n bool success;\n /* solhint-disable no-inline-assembly */\n assembly {\n success := call(\n gas(),\n factory,\n 0,\n add(initCallData, 0x20),\n mload(initCallData),\n 0,\n 32\n )\n sender := mload(0)\n }\n if (!success) {\n sender = address(0);\n }\n }\n}\n" + }, + "contracts/aa-4337/core/StakeManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity 0.8.21;\n\nimport \"../interfaces/IStakeManager.sol\";\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable not-rely-on-time */\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by a paymaster.\n */\nabstract contract StakeManager is IStakeManager {\n /// maps paymaster to their deposits and stakes\n mapping(address => DepositInfo) public deposits;\n\n /// @inheritdoc IStakeManager\n function getDepositInfo(\n address account\n ) public view returns (DepositInfo memory info) {\n return deposits[account];\n }\n\n // internal method to return just the stake info\n function _getStakeInfo(\n address addr\n ) internal view returns (StakeInfo memory info) {\n DepositInfo storage depositInfo = deposits[addr];\n info.stake = depositInfo.stake;\n info.unstakeDelaySec = depositInfo.unstakeDelaySec;\n }\n\n /// return the deposit (for gas payment) of the account\n function balanceOf(address account) public view returns (uint256) {\n return deposits[account].deposit;\n }\n\n receive() external payable {\n depositTo(msg.sender);\n }\n\n function _incrementDeposit(address account, uint256 amount) internal {\n DepositInfo storage info = deposits[account];\n uint256 newAmount = info.deposit + amount;\n require(newAmount <= type(uint112).max, \"deposit overflow\");\n info.deposit = uint112(newAmount);\n }\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) public payable {\n _incrementDeposit(account, msg.value);\n DepositInfo storage info = deposits[account];\n emit Deposited(account, info.deposit);\n }\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 unstakeDelaySec) public payable {\n DepositInfo storage info = deposits[msg.sender];\n require(unstakeDelaySec > 0, \"must specify unstake delay\");\n require(\n unstakeDelaySec >= info.unstakeDelaySec,\n \"cannot decrease unstake time\"\n );\n uint256 stake = info.stake + msg.value;\n require(stake > 0, \"no stake specified\");\n require(stake <= type(uint112).max, \"stake overflow\");\n deposits[msg.sender] = DepositInfo(\n info.deposit,\n true,\n uint112(stake),\n unstakeDelaySec,\n 0\n );\n emit StakeLocked(msg.sender, stake, unstakeDelaySec);\n }\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external {\n DepositInfo storage info = deposits[msg.sender];\n require(info.unstakeDelaySec != 0, \"not staked\");\n require(info.staked, \"already unstaking\");\n uint48 withdrawTime = uint48(block.timestamp) + info.unstakeDelaySec;\n info.withdrawTime = withdrawTime;\n info.staked = false;\n emit StakeUnlocked(msg.sender, withdrawTime);\n }\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external {\n DepositInfo storage info = deposits[msg.sender];\n uint256 stake = info.stake;\n require(stake > 0, \"No stake to withdraw\");\n require(info.withdrawTime > 0, \"must call unlockStake() first\");\n require(\n info.withdrawTime <= block.timestamp,\n \"Stake withdrawal is not due\"\n );\n info.unstakeDelaySec = 0;\n info.withdrawTime = 0;\n info.stake = 0;\n emit StakeWithdrawn(msg.sender, withdrawAddress, stake);\n (bool success, ) = withdrawAddress.call{value: stake}(\"\");\n require(success, \"failed to withdraw stake\");\n }\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(\n address payable withdrawAddress,\n uint256 withdrawAmount\n ) external {\n DepositInfo storage info = deposits[msg.sender];\n require(withdrawAmount <= info.deposit, \"Withdraw amount too large\");\n info.deposit = uint112(info.deposit - withdrawAmount);\n emit Withdrawn(msg.sender, withdrawAddress, withdrawAmount);\n (bool success, ) = withdrawAddress.call{value: withdrawAmount}(\"\");\n require(success, \"failed to withdraw\");\n }\n}\n" + }, + "contracts/aa-4337/interfaces/IAccount.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\ninterface IAccount {\n /**\n * Validate user's signature and nonce\n * the entryPoint will make the call to the recipient only if this validation call returns successfully.\n * signature failure should be reported by returning SIG_VALIDATION_FAILED (1).\n * This allows making a \"simulation call\" without a valid signature\n * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure.\n *\n * @dev Must validate caller is the entryPoint.\n * Must validate the signature and nonce\n * @param userOp the operation that is about to be executed.\n * @param userOpHash hash of the user's request data. can be used as the basis for signature.\n * @param missingAccountFunds missing funds on the account's deposit in the entrypoint.\n * This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call.\n * The excess is left as a deposit in the entrypoint, for future calls.\n * can be withdrawn anytime using \"entryPoint.withdrawTo()\"\n * In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero.\n * @return validationData packaged ValidationData structure. use `_packValidationData` and `_unpackValidationData` to encode and decode\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * If an account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validateUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 missingAccountFunds\n ) external returns (uint256 validationData);\n}\n" + }, + "contracts/aa-4337/interfaces/IAggregator.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * Aggregated Signatures validator.\n */\ninterface IAggregator {\n /**\n * validate aggregated signature.\n * revert if the aggregated signature does not match the given list of operations.\n */\n function validateSignatures(\n UserOperation[] calldata userOps,\n bytes calldata signature\n ) external view;\n\n /**\n * validate signature of a single userOp\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\n * @param userOp the userOperation received from the user.\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\n * (usually empty, unless account and aggregator support some kind of \"multisig\"\n */\n function validateUserOpSignature(\n UserOperation calldata userOp\n ) external view returns (bytes memory sigForUserOp);\n\n /**\n * aggregate multiple signatures into a single value.\n * This method is called off-chain to calculate the signature to pass with handleOps()\n * bundler MAY use optimized custom code perform this aggregation\n * @param userOps array of UserOperations to collect the signatures from.\n * @return aggregatedSignature the aggregated signature\n */\n function aggregateSignatures(\n UserOperation[] calldata userOps\n ) external view returns (bytes memory aggregatedSignature);\n}\n" + }, + "contracts/aa-4337/interfaces/IEntryPoint.sol": { + "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n/* solhint-disable reason-string */\n\nimport \"./UserOperation.sol\";\nimport \"./IStakeManager.sol\";\nimport \"./IAggregator.sol\";\nimport \"./INonceManager.sol\";\n\ninterface IEntryPoint is IStakeManager, INonceManager {\n /***\n * An event emitted after each successful request\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\n * @param sender - the account that generates this request.\n * @param paymaster - if non-null, the paymaster that pays for this request.\n * @param nonce - the nonce value from the request.\n * @param success - true if the sender transaction succeeded, false if reverted.\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\n */\n event UserOperationEvent(\n bytes32 indexed userOpHash,\n address indexed sender,\n address indexed paymaster,\n uint256 nonce,\n bool success,\n uint256 actualGasCost,\n uint256 actualGasUsed\n );\n\n /**\n * account \"sender\" was deployed.\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\n * @param sender the account that is deployed\n * @param factory the factory used to deploy this account (in the initCode)\n * @param paymaster the paymaster used by this UserOp\n */\n event AccountDeployed(\n bytes32 indexed userOpHash,\n address indexed sender,\n address factory,\n address paymaster\n );\n\n /**\n * An event emitted if the UserOperation \"callData\" reverted with non-zero length\n * @param userOpHash the request unique identifier.\n * @param sender the sender of this request\n * @param nonce the nonce used in the request\n * @param revertReason - the return bytes from the (reverted) call to \"callData\".\n */\n event UserOperationRevertReason(\n bytes32 indexed userOpHash,\n address indexed sender,\n uint256 nonce,\n bytes revertReason\n );\n\n /**\n * an event emitted by handleOps(), before starting the execution loop.\n * any event emitted before this event, is part of the validation.\n */\n event BeforeExecution();\n\n /**\n * signature aggregator used by the following UserOperationEvents within this bundle.\n */\n event SignatureAggregatorChanged(address indexed aggregator);\n\n /**\n * a custom revert error of handleOps, to identify the offending op.\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\n * @param reason - revert reason\n * The string starts with a unique code \"AAmn\", where \"m\" is \"1\" for factory, \"2\" for account and \"3\" for paymaster issues,\n * so a failure can be attributed to the correct entity.\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\n */\n error FailedOp(uint256 opIndex, string reason);\n\n /**\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\n */\n error SignatureValidationFailed(address aggregator);\n\n /**\n * Successful result from simulateValidation.\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n */\n error ValidationResult(\n ReturnInfo returnInfo,\n StakeInfo senderInfo,\n StakeInfo factoryInfo,\n StakeInfo paymasterInfo\n );\n\n /**\n * Successful result from simulateValidation, if the account returns a signature aggregator\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\n * bundler MUST use it to verify the signature, or reject the UserOperation\n */\n error ValidationResultWithAggregation(\n ReturnInfo returnInfo,\n StakeInfo senderInfo,\n StakeInfo factoryInfo,\n StakeInfo paymasterInfo,\n AggregatorStakeInfo aggregatorInfo\n );\n\n /**\n * return value of getSenderAddress\n */\n error SenderAddressResult(address sender);\n\n /**\n * return value of simulateHandleOp\n */\n error ExecutionResult(\n uint256 preOpGas,\n uint256 paid,\n uint48 validAfter,\n uint48 validUntil,\n bool targetSuccess,\n bytes targetResult\n );\n\n //UserOps handled, per aggregator\n struct UserOpsPerAggregator {\n UserOperation[] userOps;\n // aggregator address\n IAggregator aggregator;\n // aggregated signature\n bytes signature;\n }\n\n /**\n * Execute a batch of UserOperation.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(\n UserOperation[] calldata ops,\n address payable beneficiary\n ) external;\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) external;\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(\n UserOperation calldata userOp\n ) external view returns (bytes32);\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external;\n\n /**\n * gas and return values during simulation\n * @param preOpGas the gas used for validation (including preValidationGas)\n * @param prefund the required prefund for this operation\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\n */\n struct ReturnInfo {\n uint256 preOpGas;\n uint256 prefund;\n bool sigFailed;\n uint48 validAfter;\n uint48 validUntil;\n bytes paymasterContext;\n }\n\n /**\n * returned aggregated signature info.\n * the aggregator returned by the account, and its current stake.\n */\n struct AggregatorStakeInfo {\n address aggregator;\n StakeInfo stakeInfo;\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes memory initCode) external;\n\n /**\n * simulate full execution of a UserOperation (including both validation and target execution)\n * this method will always revert with \"ExecutionResult\".\n * it performs full validation of the UserOperation, but ignores signature error.\n * an optional target address is called after the userop succeeds, and its value is returned\n * (before the entire call is reverted)\n * Note that in order to collect the the success/failure of the target call, it must be executed\n * with trace enabled to track the emitted events.\n * @param op the UserOperation to simulate\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\n * are set to the return from that call.\n * @param targetCallData callData to pass to target address\n */\n function simulateHandleOp(\n UserOperation calldata op,\n address target,\n bytes calldata targetCallData\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/INonceManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\ninterface INonceManager {\n /**\n * Return the next nonce for this sender.\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\n * But UserOp with different keys can come with arbitrary order.\n *\n * @param sender the account address\n * @param key the high 192 bit of the nonce\n * @return nonce a full nonce to pass for next UserOp with this sender.\n */\n function getNonce(\n address sender,\n uint192 key\n ) external view returns (uint256 nonce);\n\n /**\n * Manually increment the nonce of the sender.\n * This method is exposed just for completeness..\n * Account does NOT need to call it, neither during validation, nor elsewhere,\n * as the EntryPoint will update the nonce regardless.\n * Possible use-case is call it with various keys to \"initialize\" their nonces to one, so that future\n * UserOperations will not pay extra for the first transaction with a given key.\n */\n function incrementNonce(uint192 key) external;\n}\n" + }, + "contracts/aa-4337/interfaces/IPaymaster.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * the interface exposed by a paymaster contract, who agrees to pay the gas for user's operations.\n * a paymaster must hold a stake to cover the required entrypoint stake and also the gas for the transaction.\n */\ninterface IPaymaster {\n enum PostOpMode {\n opSucceeded, // user op succeeded\n opReverted, // user op reverted. still has to pay for gas.\n postOpReverted //user op succeeded, but caused postOp to revert. Now it's a 2nd call, after user's op was deliberately reverted.\n }\n\n /**\n * payment validation: check if paymaster agrees to pay.\n * Must verify sender is the entryPoint.\n * Revert to reject this request.\n * Note that bundlers will reject this method if it changes the state, unless the paymaster is trusted (whitelisted)\n * The paymaster pre-pays using its deposit, and receive back a refund after the postOp method returns.\n * @param userOp the user operation\n * @param userOpHash hash of the user's request data.\n * @param maxCost the maximum cost of this transaction (based on maximum gas and gas price from userOp)\n * @return context value to send to a postOp\n * zero length to signify postOp is not required.\n * @return validationData signature and time-range of this operation, encoded the same as the return value of validateUserOperation\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validatePaymasterUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 maxCost\n ) external returns (bytes memory context, uint256 validationData);\n\n /**\n * post-operation handler.\n * Must verify sender is the entryPoint\n * @param mode enum with the following options:\n * opSucceeded - user operation succeeded.\n * opReverted - user op reverted. still has to pay for gas.\n * postOpReverted - user op succeeded, but caused postOp (in mode=opSucceeded) to revert.\n * Now this is the 2nd call, after user's op was deliberately reverted.\n * @param context - the context value returned by validatePaymasterUserOp\n * @param actualGasCost - actual gas used so far (without this postOp call).\n */\n function postOp(\n PostOpMode mode,\n bytes calldata context,\n uint256 actualGasCost\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/IStakeManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.12;\n\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by the staked entity.\n */\ninterface IStakeManager {\n event Deposited(address indexed account, uint256 totalDeposit);\n\n event Withdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /// Emitted when stake or unstake delay are modified\n event StakeLocked(\n address indexed account,\n uint256 totalStaked,\n uint256 unstakeDelaySec\n );\n\n /// Emitted once a stake is scheduled for withdrawal\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\n\n event StakeWithdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /**\n * @param deposit the entity's deposit\n * @param staked true if this entity is staked.\n * @param stake actual amount of ether staked for this entity.\n * @param unstakeDelaySec minimum delay to withdraw the stake.\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\n * and the rest fit into a 2nd cell.\n * 112 bit allows for 10^15 eth\n * 48 bit for full timestamp\n * 32 bit allows 150 years for unstake delay\n */\n struct DepositInfo {\n uint112 deposit;\n bool staked;\n uint112 stake;\n uint32 unstakeDelaySec;\n uint48 withdrawTime;\n }\n\n //API struct used by getStakeInfo and simulateValidation\n struct StakeInfo {\n uint256 stake;\n uint256 unstakeDelaySec;\n }\n\n /// @return info - full deposit information of given account\n function getDepositInfo(\n address account\n ) external view returns (DepositInfo memory info);\n\n /// @return the deposit (for gas payment) of the account\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) external payable;\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 _unstakeDelaySec) external payable;\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external;\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external;\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(\n address payable withdrawAddress,\n uint256 withdrawAmount\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/UserOperation.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable no-inline-assembly */\n\nimport {calldataKeccak} from \"../core/Helpers.sol\";\n\n/**\n * User Operation struct\n * @param sender the sender account of this request.\n * @param nonce unique value the sender uses to verify it is not a replay.\n * @param initCode if set, the account contract will be created by this constructor/\n * @param callData the method call to execute on this account.\n * @param callGasLimit the gas limit passed to the callData method call.\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\n * @param maxFeePerGas same as EIP-1559 gas parameter.\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\n */\nstruct UserOperation {\n address sender;\n uint256 nonce;\n bytes initCode;\n bytes callData;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n bytes paymasterAndData;\n bytes signature;\n}\n\n/**\n * Utility functions helpful when working with UserOperation structs.\n */\nlibrary UserOperationLib {\n function getSender(\n UserOperation calldata userOp\n ) internal pure returns (address) {\n address data;\n //read sender from userOp, which is first userOp member (saves 800 gas...)\n assembly {\n data := calldataload(userOp)\n }\n return address(uint160(data));\n }\n\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\n // pay above what he signed for.\n function gasPrice(\n UserOperation calldata userOp\n ) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function pack(\n UserOperation calldata userOp\n ) internal pure returns (bytes memory ret) {\n address sender = getSender(userOp);\n uint256 nonce = userOp.nonce;\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\n bytes32 hashCallData = calldataKeccak(userOp.callData);\n uint256 callGasLimit = userOp.callGasLimit;\n uint256 verificationGasLimit = userOp.verificationGasLimit;\n uint256 preVerificationGas = userOp.preVerificationGas;\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\n\n return\n abi.encode(\n sender,\n nonce,\n hashInitCode,\n hashCallData,\n callGasLimit,\n verificationGasLimit,\n preVerificationGas,\n maxFeePerGas,\n maxPriorityFeePerGas,\n hashPaymasterAndData\n );\n }\n\n function hash(\n UserOperation calldata userOp\n ) internal pure returns (bytes32) {\n return keccak256(pack(userOp));\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n}\n" + }, + "contracts/aa-4337/utils/Exec.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.5 <0.9.0;\n\n// solhint-disable no-inline-assembly\n\n/**\n * Utility functions helpful when making different kinds of contract calls in Solidity.\n */\nlibrary Exec {\n function call(\n address to,\n uint256 value,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := call(\n txGas,\n to,\n value,\n add(data, 0x20),\n mload(data),\n 0,\n 0\n )\n }\n }\n\n function staticcall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal view returns (bool success) {\n assembly {\n success := staticcall(txGas, to, add(data, 0x20), mload(data), 0, 0)\n }\n }\n\n function delegateCall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := delegatecall(\n txGas,\n to,\n add(data, 0x20),\n mload(data),\n 0,\n 0\n )\n }\n }\n\n // get returned data from last call or calldelegate\n function getReturnData(\n uint256 maxLen\n ) internal pure returns (bytes memory returnData) {\n assembly {\n let len := returndatasize()\n if gt(len, maxLen) {\n len := maxLen\n }\n let ptr := mload(0x40)\n mstore(0x40, add(ptr, add(len, 0x20)))\n mstore(ptr, len)\n returndatacopy(add(ptr, 0x20), 0, len)\n returnData := ptr\n }\n }\n\n // revert with explicit byte array (probably reverted info from call)\n function revertWithData(bytes memory returnData) internal pure {\n assembly {\n revert(add(returnData, 32), mload(returnData))\n }\n }\n\n function callAndRevert(\n address to,\n bytes memory data,\n uint256 maxLen\n ) internal {\n bool success = call(to, 0, data, gasleft());\n if (!success) {\n revertWithData(getReturnData(maxLen));\n }\n }\n}\n" + }, + "contracts/Barz.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"./libraries/LibDiamond.sol\";\nimport {IBarz} from \"./interfaces/IBarz.sol\";\n\n/**\n * @title Barz\n * @dev A diamond proxy wallet with a modular & upgradeable architecture\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract Barz is IBarz {\n /**\n * @notice Initializes Barz with the given parameters. Barz account is intended to be created from Barz Factory for stable deployment.\n * @dev This method makes a delegate call to account facet and account facet handles the initialization.\n * With modular architecture, Barz encompasses wide spectrum of architecture and logic.\n * The only requirement is account facet to comply with initialize() interface.\n * Barz doesn't include built-in functions and is a full proxy, for maximum extensibility and modularity.\n * @param _accountFacet Address of Account Facet in charge of the Barz initialization\n * @param _verificationFacet Address of Verification Facet for verifying the signature. Could be any signature scheme\n * @param _entryPoint Address of Entry Point contract\n * @param _facetRegistry Address of Facet Registry. Facet Registry is a registry holding trusted facets that could be added to user's wallet\n * @param _defaultFallBack Address of Default FallBack Handler. Middleware contract for more efficient deployment\n * @param _ownerPublicKey Bytes of Owner Public Key using for initialization\n */\n constructor(\n address _accountFacet,\n address _verificationFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallBack,\n bytes memory _ownerPublicKey\n ) payable {\n bytes memory initCall = abi.encodeWithSignature(\n \"initialize(address,address,address,address,bytes)\",\n _verificationFacet,\n _entryPoint,\n _facetRegistry,\n _defaultFallBack,\n _ownerPublicKey\n );\n (bool success, bytes memory result) = _accountFacet.delegatecall(\n initCall\n );\n if (!success || uint256(bytes32(result)) != 1) {\n revert Barz__InitializationFailure();\n }\n }\n\n /**\n * @notice Fallback function for Barz complying with Diamond Standard with customization of adding Default Fallback Handler\n * @dev Find facet for function that is called and execute the function if a facet is found and return any value.\n */\n fallback() external payable {\n LibDiamond.DiamondStorage storage ds;\n bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION;\n // get diamond storage\n assembly {\n ds.slot := position\n }\n // get facet from function selector\n address facet = address(bytes20(ds.facets[msg.sig]));\n if (facet == address(0))\n facet = ds.defaultFallbackHandler.facetAddress(msg.sig);\n require(facet != address(0), \"Barz: Function does not exist\");\n // Execute external function from facet using delegatecall and return any value.\n assembly {\n // copy function selector and any arguments\n calldatacopy(0, 0, calldatasize())\n // execute function call using the facet\n let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)\n // get any return value\n returndatacopy(0, 0, returndatasize())\n // return any return value or error back to the caller\n switch result\n case 0 {\n revert(0, returndatasize())\n }\n default {\n return(0, returndatasize())\n }\n }\n }\n\n /**\n * @notice Receive function to receive native token without data\n */\n receive() external payable {}\n}\n" + }, + "contracts/BarzFactory.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Barz} from \"./Barz.sol\";\nimport {IBarzFactory} from \"./interfaces/IBarzFactory.sol\";\n\n/**\n * @title Barz Factory\n * @dev Contract to easily deploy Barz to a pre-computed address with a single call\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract BarzFactory is IBarzFactory {\n event BarzDeployed(address);\n\n address public immutable accountFacet;\n address public immutable entryPoint;\n address public immutable facetRegistry;\n address public immutable defaultFallback;\n\n /**\n * @notice Sets the initialization data for Barz contract initialization\n * @param _accountFacet Account Facet to be used to create Barz\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\n * @param _facetRegistry Facet Registry to be used to create Barz\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\n */\n constructor(\n address _accountFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallback\n ) {\n accountFacet = _accountFacet;\n entryPoint = _entryPoint;\n facetRegistry = _facetRegistry;\n defaultFallback = _defaultFallback;\n }\n\n /**\n * @notice Creates the Barz with a single call. It creates the Barz contract with the givent verification facet\n * @param _verificationFacet Address of verification facet used for creating the barz account\n * @param _owner Public Key of the owner to initialize barz account\n * @param _salt Salt used for deploying barz with create2\n * @return barz Instance of Barz contract deployed with the given parameters\n */\n function createAccount(\n address _verificationFacet,\n bytes calldata _owner,\n uint256 _salt\n ) external override returns (Barz barz) {\n address addr = getAddress(_verificationFacet, _owner, _salt);\n uint codeSize = addr.code.length;\n if (codeSize > 0) {\n return Barz(payable(addr));\n }\n barz = new Barz{salt: bytes32(_salt)}(\n accountFacet,\n _verificationFacet,\n entryPoint,\n facetRegistry,\n defaultFallback,\n _owner\n );\n emit BarzDeployed(address(barz));\n }\n\n /**\n * @notice Calculates the address of Barz with the given parameters\n * @param _verificationFacet Address of verification facet used for creating the barz account\n * @param _owner Public Key of the owner to initialize barz account\n * @param _salt Salt used for deploying barz with create2\n * @return barzAddress Precalculated Barz address\n */\n function getAddress(\n address _verificationFacet,\n bytes calldata _owner,\n uint256 _salt\n ) public view override returns (address barzAddress) {\n bytes memory bytecode = getBytecode(\n accountFacet,\n _verificationFacet,\n entryPoint,\n facetRegistry,\n defaultFallback,\n _owner\n );\n bytes32 hash = keccak256(\n abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(bytecode)\n )\n );\n barzAddress = address(uint160(uint256(hash)));\n }\n\n /**\n * @notice Returns the bytecode of Barz with the given parameter\n * @param _accountFacet Account Facet to be used to create Barz\n * @param _verificationFacet Verification Facet to be used to create Barz\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\n * @param _facetRegistry Facet Registry to be used to create Barz\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\n * @param _ownerPublicKey Public Key of owner to be used to initialize Barz ownership\n * @return barzBytecode Bytecode of Barz\n */\n function getBytecode(\n address _accountFacet,\n address _verificationFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallback,\n bytes calldata _ownerPublicKey\n ) public pure override returns (bytes memory barzBytecode) {\n bytes memory bytecode = type(Barz).creationCode;\n barzBytecode = abi.encodePacked(\n bytecode,\n abi.encode(\n _accountFacet,\n _verificationFacet,\n _entryPoint,\n _facetRegistry,\n _defaultFallback,\n _ownerPublicKey\n )\n );\n }\n\n /**\n * @notice Returns the creation code of the Barz contract\n * @return creationCode Creation code of Barz\n */\n function getCreationCode()\n public\n pure\n override\n returns (bytes memory creationCode)\n {\n creationCode = type(Barz).creationCode;\n }\n}\n" + }, + "contracts/facets/AccountFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {UserOperation} from \"../aa-4337/interfaces/UserOperation.sol\";\nimport {IEntryPoint} from \"../aa-4337/interfaces/IEntryPoint.sol\";\nimport {BaseAccount} from \"../aa-4337/core/BaseAccount.sol\";\nimport {LibAppStorage, BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {IFacetRegistry} from \"../infrastructure/interfaces/IFacetRegistry.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {IERC1271} from \"../interfaces/ERC/IERC1271.sol\";\nimport {IAccountFacet} from \"./interfaces/IAccountFacet.sol\";\n\n/**\n * @title Account Facet\n * @dev Account module contract that provides the account features and initialization of signer\n * compatible with EIP-1271 & EIP-4337\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract AccountFacet is BarzStorage, BaseAccount, IAccountFacet {\n using ECDSA for bytes32;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceAccountInitialize();\n }\n\n /**\n * @notice Returns the address of EntryPoint contract registered to Barz account\n */\n function entryPoint() public view override returns (IEntryPoint) {\n return s.entryPoint;\n }\n\n /**\n * @notice Initializes the initial storage of the Barz contract.\n * @dev This method can only be called during the initialization or signature migration.\n * If the proxy contract was created without initialization, anyone can call initialize.\n * Barz calls initialize in constructor in an atomic transaction during deployment\n * @param _verificationFacet Facet contract handling the verificationi\n * @param _anEntryPoint Entrypoint contract defined in EIP-4337 handling the flow of UserOp\n * @param _facetRegistry Registry of Facets that hold all facet information\n * @param _defaultFallBackHandler Middleware contract for default facets\n * @param _ownerPublicKey Bytes of owner public key\n */\n function initialize(\n address _verificationFacet,\n address _anEntryPoint,\n address _facetRegistry,\n address _defaultFallBackHandler,\n bytes calldata _ownerPublicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceAccountInitialize();\n s.entryPoint = IEntryPoint(_anEntryPoint);\n s.facetRegistry = IFacetRegistry(_facetRegistry);\n LibDiamond.diamondStorage().defaultFallbackHandler = IDiamondLoupe(\n _defaultFallBackHandler\n );\n\n _cutDiamondAccountFacet(_verificationFacet);\n\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n _ownerPublicKey\n );\n // Every Verification Facet should comply with initializeSigner(bytes)\n // to be compatible with the Barz contract(for initialization)\n (bool success, bytes memory result) = _verificationFacet.delegatecall(\n initCall\n );\n if (!success || uint256(bytes32(result)) != 1) {\n revert AccountFacet__InitializationFailure();\n }\n\n initSuccess = 1;\n emit AccountInitialized(s.entryPoint, _ownerPublicKey);\n }\n\n function _cutDiamondAccountFacet(address _verificationFacet) internal {\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](1);\n\n bytes4 ownerVerificationFuncSelector = IVerificationFacet(\n _verificationFacet\n ).validateOwnerSignatureSelector();\n\n bytes4[] memory verificationFunctionSelectors = new bytes4[](3);\n verificationFunctionSelectors[0] = IERC1271.isValidSignature.selector;\n verificationFunctionSelectors[1] = ownerVerificationFuncSelector;\n verificationFunctionSelectors[2] = IVerificationFacet.owner.selector;\n cut[0] = IDiamondCut.FacetCut({\n facetAddress: _verificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: verificationFunctionSelectors\n });\n\n LibDiamond.diamondCut(cut, address(0), \"\");\n }\n\n /**\n * @notice Calls the destination with inputted calldata and value from EntryPoint\n * @dev This method executes the calldata coming from the EntryPoint.\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\n * @param _dest Address of destination where the call will be forwarded to\n * @param _value Amount of native coin the owner is willing to send(e.g. ETH, BNB)\n * @param _func Bytes of calldata to execute in the destination address\n */\n function execute(\n address _dest,\n uint256 _value,\n bytes calldata _func\n ) external override onlyWhenUnlocked {\n _requireFromEntryPoint();\n _call(_dest, _value, _func);\n }\n\n /**\n * @notice Batch calls the destination with inputted calldata and value from EntryPoint\n * @dev This method batch executes the calldata coming from the EntryPoint.\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\n * @param _dest Array of addresses of destination where the call will be forwarded to\n * @param _value Array of amount of native coin the owner is willing to send(e.g. ETH, BNB)\n * @param _func Array of bytes of calldata to execute in the destination address\n */\n function executeBatch(\n address[] calldata _dest,\n uint256[] calldata _value,\n bytes[] calldata _func\n ) external override onlyWhenUnlocked {\n _requireFromEntryPoint();\n require(\n _dest.length == _func.length && _dest.length == _value.length,\n \"wrong array lengths\"\n );\n for (uint256 i; i < _dest.length; ) {\n _call(_dest[i], _value[i], _func[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Validates the signature field of UserOperation\n * @dev This method validates if the signature of UserOp is indeed valid by delegating the call to Verification Facet\n * Barz makes a call to the pre-registered Verification Facet address in App Storage\n * @param _userOp UserOperation from owner to be validated\n * @param _userOpHash Hash of UserOperation given from the EntryPoint contract\n */\n function _validateSignature(\n UserOperation calldata _userOp,\n bytes32 _userOpHash\n ) internal override returns (uint256 validationData) {\n // Get Facet with Function Selector\n address facet = LibLoupe.facetAddress(s.validateOwnerSignatureSelector);\n if (facet == address(0))\n revert AccountFacet__NonExistentVerificationFacet();\n\n // Make function call to VerificationFacet\n bytes memory validateCall = abi.encodeWithSelector(\n s.validateOwnerSignatureSelector,\n _userOp,\n _userOpHash\n );\n (bool success, bytes memory result) = facet.delegatecall(validateCall);\n if (!success) revert AccountFacet__CallNotSuccessful();\n validationData = uint256(bytes32(result));\n if (validationData == 0) emit VerificationSuccess(_userOpHash);\n else emit VerificationFailure(_userOpHash);\n }\n\n /**\n * @notice Calls the target with the inputted value and calldata\n * @dev This method is the actual function in Barz that makes a call with an arbitrary owner-given data\n * @param _target Address of the destination contract which the call is getting forwarded to\n * @param _value Amount of Native coin the owner is wanting to make in this call\n * @param _data Calldata the owner is forwarding together in the call e.g. Swap/Token Transfer\n */\n function _call(\n address _target,\n uint256 _value,\n bytes memory _data\n ) internal {\n address facet = LibDiamond.restrictionsFacet();\n // NOTE: No restrictions facet, so restriction validation passes\n if (facet != address(0)) {\n if (_checkRestrictions(facet, _target, _value, _data) == 1)\n revert AccountFacet__RestrictionsFailure();\n }\n\n (bool success, bytes memory result) = _target.call{value: _value}(\n _data\n );\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n }\n\n /**\n * @notice Checks restrictions if the restrictions facet exists\n * @dev This method checks if the restrictions facet exists and makes a verification call to an array of restrictions facet\n * @param _facet Address that holds the restrictions logic\n * @param _target Address the call is getting forwarded to\n * @param _value Amount of native coin the call is sending together with the call\n * @param _data Calldata to trigger execution in target address\n */\n function _checkRestrictions(\n address _facet,\n address _target,\n uint256 _value,\n bytes memory _data\n ) internal returns (uint256 result) {\n bytes memory call = abi.encodeWithSignature(\n \"verifyRestrictions(address,address,uint256,bytes)\",\n address(this),\n _target,\n _value,\n _data\n );\n (bool success, bytes memory response) = _facet.delegatecall(call);\n if (!success) revert AccountFacet__RestrictionsFailure();\n result = uint256(bytes32(response));\n }\n}\n" + }, + "contracts/facets/AccountRecoveryFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibFacetStorage, RecoveryStorage, RecoveryConfig, RecoveryApprovalConfig, ApprovalConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {IAccountRecoveryFacet} from \"./interfaces/IAccountRecoveryFacet.sol\";\n\n/**\n * @title Account Recovery Facet\n * @dev Contract that enables recovery of accounts when owner key is unavailable\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract AccountRecoveryFacet is IAccountRecoveryFacet, Modifiers {\n bytes constant UNINIT_CALL =\n abi.encodeWithSignature(\"uninitializeSigner()\");\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Approve recovery of account as guardian\n * @dev This method can only be called by guardian and guardian inputs the public key of the new owner\n * When the threshold(majority of guardians) passes, it automatically executes account recovery\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function approveAccountRecovery(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + _getApprovalValidationPeriod()\n );\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit RecoveryApproved(\n _recoveryPublicKey,\n msg.sender,\n approvalValidUntil\n );\n if (\n getRecoveryApprovalCountWithTimeValidity(recoveryPublicKeyHash) >=\n LibGuardian.majorityOfGuardians()\n ) _executeRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Revoke recovery of account as guardian\n * @dev This method can only be called by guardian and guardian inputs the public key of the new owner\n When the threshold(majority of guardians) passes, it automatically revokes account recovery when recovery is pending\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function revokeAccountRecoveryApproval(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n if (\n !rs\n .isNewOwnerApproved[recoveryPublicKeyHash][msg.sender].isApproved ||\n !(block.timestamp <\n rs\n .isNewOwnerApproved[recoveryPublicKeyHash][msg.sender]\n .validUntil)\n ) revert AccountRecoveryFacet__NonExistentApproval();\n\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(false, 0);\n emit RecoveryApprovalRevoked(_recoveryPublicKey, msg.sender);\n }\n\n /**\n * @notice Executes recovery with signatures or on-chain pre-approvals\n * @dev This method validates the signatures of guardians or checks the on-chain pre-approved calls to check if the threshold passes\n * When the threshold passes, account recovery is executed and revert otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _guardians Array of guardians address that are approving the recovery of Account\n * @param _signatures Array of signature bytes that signed the approval hash\n */\n function executeRecovery(\n bytes calldata _recoveryPublicKey,\n address[] calldata _guardians,\n bytes[] calldata _signatures\n ) external override {\n if (_isRecoveryPending())\n revert AccountRecoveryFacet__RecoveryAlreadyOngoing();\n if (_guardians.length != _signatures.length)\n revert AccountRecoveryFacet__InvalidArrayLength();\n validateNewOwner(_recoveryPublicKey);\n\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n\n _checkApprover(_guardians);\n _checkDuplicateOnChainApprover(recoveryPublicKeyHash, _guardians);\n\n if (\n _guardians.length +\n getRecoveryApprovalCountWithTimeValidity(\n recoveryPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians()\n ) revert AccountRecoveryFacet__InsufficientGuardians();\n for (uint256 i; i < _guardians.length; ) {\n if (!LibGuardian.isGuardian(_guardians[i]))\n revert AccountRecoveryFacet__InvalidGuardian();\n if (\n !SignatureChecker.isValidSignatureNow(\n _guardians[i],\n recoveryPublicKeyHash,\n _signatures[i]\n )\n ) revert AccountRecoveryFacet__InvalidGuardianSignature();\n unchecked {\n ++i;\n }\n }\n _executeRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Executes recovery of the account. Note that execution and finalization is a different process\n * @dev Executes the recovery and adds recovery data to recovery configuration. Locks the account\n * @param _recoveryPublicKey Public Key of the account for recovery\n */\n function _executeRecovery(bytes memory _recoveryPublicKey) internal {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n ++rs.nonce;\n uint64 executeAfter = uint64(block.timestamp + _getRecoveryPeriod());\n rs.recoveryConfigs[INNER_STRUCT] = RecoveryConfig(\n _recoveryPublicKey,\n executeAfter // NOTE: Remove guardian Count\n );\n LibAppStorage.setLock(\n block.timestamp + _getLockPeriod(),\n AccountRecoveryFacet.executeRecovery.selector\n );\n emit RecoveryExecuted(_recoveryPublicKey, executeAfter);\n }\n\n /**\n * @notice Finalize recovery after recovery pending period. Recovery pending period can be set by user beforehand in SecurityManager\n * @dev This method finalizes recovery and fully changes the ownership of the account to the newly inputted recovery public key\n */\n function finalizeRecovery() external override {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n if (\n uint64(block.timestamp) <=\n rs.recoveryConfigs[INNER_STRUCT].executeAfter\n ) revert AccountRecoveryFacet__RecoveryPeriodNotOver();\n bytes memory recoveryOwner = rs\n .recoveryConfigs[INNER_STRUCT]\n .recoveryPublicKey;\n\n delete rs.recoveryConfigs[INNER_STRUCT];\n\n LibAppStorage.setLock(0, bytes4(0));\n\n LibAppStorage.initiateSignerMigration();\n address verificationFacet = address(\n bytes20(\n LibDiamond.diamondStorage().facets[\n s.validateOwnerSignatureSelector\n ]\n )\n );\n (bool success, bytes memory result) = verificationFacet.delegatecall(\n UNINIT_CALL\n );\n if (!success) revert AccountRecoveryFacet__CallNotSuccesful();\n uint256 validationData = uint256(bytes32(result));\n if (validationData != 1)\n revert AccountRecoveryFacet__SignerUninitializationFailure();\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n recoveryOwner\n );\n (success, result) = verificationFacet.delegatecall(initCall);\n if (!success) revert AccountRecoveryFacet__CallNotSuccesful();\n validationData = uint256(bytes32(result));\n if (validationData != 1)\n revert AccountRecoveryFacet__SignerInitializationFailure();\n LibAppStorage.finalizeSignerMigration();\n emit RecoveryFinalized(recoveryOwner);\n }\n\n /**\n * @notice Approves the cancellation of recovery\n * @dev This method approves the cancellation of recovery when recovery is still pending - waiting for finalization\n * @param _recoveryPublicKey Bytes of public key which is pending for recovery\n */\n function approveCancelRecovery(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"CancelRecovery\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + _getApprovalValidationPeriod()\n );\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit RecoveryCancellationApproved(_recoveryPublicKey, msg.sender);\n if (\n getRecoveryApprovalCountWithTimeValidity(recoveryPublicKeyHash) >=\n LibGuardian.majorityOfGuardians()\n ) {\n _cancelRecovery(_recoveryPublicKey);\n }\n }\n\n /**\n * @notice Hardstops an ongoing recovery\n * @dev This method provides a safety mechanism to protect owners of malicious guardians.\n * Owners can hardstop recovery when an malicious guardians starts the recovery process.\n * @param _signature Signature of the owner that signs the hash to hardstop recovery\n */\n function hardstopRecovery(bytes calldata _signature) external override {\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n \"0\",\n \"HardstopRecovery\"\n );\n if (\n !SignatureChecker.isValidSignatureNow(\n address(this),\n recoveryPublicKeyHash,\n _signature\n )\n ) revert AccountRecoveryFacet__InvalidOwnerSignature();\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n ++rs.nonce;\n delete rs.recoveryConfigs[INNER_STRUCT];\n LibAppStorage.setLock(0, bytes4(0));\n emit RecoveryHardstopped();\n }\n\n /**\n * @notice Cancels recovery with signatures or on-chain pre-approvals\n * @dev This method validates the signatures of guardians or checks the on-chain pre-approved calls to check if the threshold passes\n * When the threshold passes, account recovery is canceled and revert otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _guardians Array of guardians address that are approving the recovery of Account\n * @param _signatures Array of signature bytes that signed the cancellation approval hash\n */\n function cancelRecovery(\n bytes calldata _recoveryPublicKey,\n address[] calldata _guardians,\n bytes[] calldata _signatures\n ) external override {\n if (_guardians.length != _signatures.length)\n revert AccountRecoveryFacet__InvalidArrayLength();\n validateNewOwner(_recoveryPublicKey);\n\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"CancelRecovery\"\n );\n\n _checkApprover(_guardians);\n _checkDuplicateOnChainApprover(recoveryPublicKeyHash, _guardians);\n\n if (\n _guardians.length +\n getRecoveryApprovalCountWithTimeValidity(\n recoveryPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians()\n ) revert AccountRecoveryFacet__InsufficientGuardians();\n for (uint256 i; i < _guardians.length; ) {\n if (!LibGuardian.isGuardian(_guardians[i]))\n revert AccountRecoveryFacet__CallerNotGuardian();\n if (\n !SignatureChecker.isValidSignatureNow(\n _guardians[i],\n recoveryPublicKeyHash,\n _signatures[i]\n )\n ) revert AccountRecoveryFacet__InvalidGuardianSignature();\n unchecked {\n ++i;\n }\n }\n _cancelRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Cancel recovery when the recovery is pending. Unlock the account as well\n * @dev This method checks if the recovery is pending and reverts if not pending.\n * It increases the recovery nonce and deletes the recovery information and gets a small portion of gas in return\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function _cancelRecovery(bytes memory _recoveryPublicKey) internal {\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n LibAppStorage.setLock(0, bytes4(0));\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n ++rs.nonce;\n delete rs.recoveryConfigs[INNER_STRUCT];\n emit RecoveryCanceled(_recoveryPublicKey);\n }\n\n /**\n * @notice Validates the format of public key to be used for recovery\n * @dev This method checks if the public key format is correct and reverts otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function validateNewOwner(bytes memory _recoveryPublicKey) public view {\n if (\n !IVerificationFacet(\n LibLoupe.facetAddress(s.validateOwnerSignatureSelector)\n ).isValidKeyType(_recoveryPublicKey)\n ) revert AccountRecoveryFacet__InvalidRecoveryPublicKey();\n }\n\n /**\n * @notice Checks if recovery is currently pending\n * @return isPending Boolean indicating if recovery is pending\n */\n function _isRecoveryPending() internal view returns (bool isPending) {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n isPending = (rs.recoveryConfigs[INNER_STRUCT].executeAfter > 0);\n }\n\n /**\n * @notice Calculate the recovery hash dependent on chain, wallet address, nonce with EIP-191 prefix for safety\n * @dev Returns the keccak256 hash of EIP-191 msg hash packed with public key, salt, nonce, wallet address, etc\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _saltString Salt string to uniquely identify each recovery hash and for security\n * @return recoveryKeyHash Bytes32 string of the recovery hash\n */\n function getApprovalRecoveryKeyHash(\n bytes memory _recoveryPublicKey,\n string memory _saltString\n ) public view override returns (bytes32 recoveryKeyHash) {\n recoveryKeyHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n _recoveryPublicKey,\n _saltString,\n address(this),\n block.chainid,\n LibFacetStorage.recoveryStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Check the onchain approval of guardians and returns the number of guardians that approved\n * @dev Loop through the guardian addresses and returns the number of guardians that approved this recovery hash\n * @param _recoveryPublicKeyHash Bytes hash of newly recovered public key and recovery value of the account\n * @return approvalCount Number of guardians that approved\n */\n function getRecoveryApprovalCountWithTimeValidity(\n bytes32 _recoveryPublicKeyHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n for (uint256 i; i < guardianLength; ) {\n if (isRecoveryApproved(_recoveryPublicKeyHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Checks if the recovery is approved by the given approver\n * @param _recoveryPublicKeyHash Hash of the public key and configuration for recovery\n * @param _approver Address of approver\n * @return isApproved Bool value if recovery hash is approved\n */\n function isRecoveryApproved(\n bytes32 _recoveryPublicKeyHash,\n address _approver\n ) public view override returns (bool isApproved) {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n if (\n rs\n .isNewOwnerApproved[_recoveryPublicKeyHash][_approver].isApproved &&\n block.timestamp <\n rs.isNewOwnerApproved[_recoveryPublicKeyHash][_approver].validUntil\n ) {\n isApproved = true;\n }\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _recoveryPublicKeyHash Hash of recovery information\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _recoveryPublicKeyHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isRecoveryApproved(_recoveryPublicKeyHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert AccountRecoveryFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the lock period of this wallet address from security manager\n * @return lockPeriod value of lock period\n */\n function _getLockPeriod() internal view returns (uint256 lockPeriod) {\n lockPeriod = securityManager.lockPeriodOf(address(this));\n if (lockPeriod == 0) revert AccountRecoveryFacet__InvalidLockPeriod();\n }\n\n /**\n * @notice Returns the lock period of this wallet address from security manager\n * @return recoveryPeriod value of recovery period\n */\n function _getRecoveryPeriod()\n internal\n view\n returns (uint256 recoveryPeriod)\n {\n recoveryPeriod = securityManager.recoveryPeriodOf(address(this));\n if (recoveryPeriod == 0)\n revert AccountRecoveryFacet__InvalidRecoveryPeriod();\n }\n\n /**\n * @notice Returns the approval validation period of this wallet address from security manager\n * @return approvalValidationPeriod value of approval validation period\n */\n function _getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod == 0)\n revert AccountRecoveryFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the recovery nonce of this wallet address from security manager\n * @return nonce value of recovery nonce\n */\n function getRecoveryNonce() public view override returns (uint128 nonce) {\n nonce = LibFacetStorage.recoveryStorage().nonce;\n }\n\n /**\n * @notice Returns the recovery information of the pending recovery\n * @return recoveryConfig value struct of pending recovery\n */\n function getPendingRecovery()\n public\n view\n override\n returns (RecoveryConfig memory recoveryConfig)\n {\n recoveryConfig = LibFacetStorage.recoveryStorage().recoveryConfigs[\n INNER_STRUCT\n ];\n }\n}\n" + }, + "contracts/facets/base/DiamondCutFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibGuardian} from \"../../libraries/LibGuardian.sol\";\nimport {ISecurityManager} from \"../../infrastructure/interfaces/ISecurityManager.sol\";\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibFacetStorage, DiamondCutApprovalConfig, ApprovalConfig} from \"../../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"../Modifiers.sol\";\nimport {IDiamondCut} from \"./interfaces/IDiamondCut.sol\";\n\n/**\n * @title DiamondCut Facet\n * @dev Responsible for adding/removing/replace facets in Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DiamondCutFacet is Modifiers, IDiamondCut {\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Updates the flag for the interfaceId\n * @param _interfaceId InterfaceID to update the mapping\n * @param _flag Bool value to update the mapping of the given interface ID\n */\n function updateSupportsInterface(\n bytes4 _interfaceId,\n bool _flag\n ) external override onlyWhenUnlocked {\n LibDiamond.enforceIsSelf();\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId] = _flag;\n emit SupportsInterfaceUpdated(_interfaceId, _flag);\n }\n\n /**\n * @notice Add/replace/remove any number of functions and optionally execute\n * a function with delegatecall when guardians don't exist\n * @param _diamondCut Contains the facet addresses and function selectors\n * @param _init The address of the contract or facet to execute _calldata. It's prohibited in Barz\n */\n function diamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata\n ) external override onlyWhenUnlocked {\n LibDiamond.enforceIsSelf();\n\n _checkFacetCutValidity(_diamondCut);\n // require approval from guardian if guardian exists\n if (0 != LibGuardian.guardianCount())\n revert DiamondCutFacet__InvalidRouteWithGuardian();\n if (address(0) != _init) revert DiamondCutFacet__InvalidInitAddress();\n\n ++LibFacetStorage.diamondCutStorage().nonce;\n LibDiamond.diamondCut(_diamondCut, address(0), \"\");\n }\n\n /**\n * @notice Add/replace/remove any number of functions and optionally execute\n * a function with delegatecall when guardians exist\n * @param _diamondCut Contains the facet addresses and function selectors\n * @param _approvers Guardian or owner address that approves the diamond cut\n * @param _signatures Signature of Guardians or owner that approves the diamond cut\n */\n function diamondCutWithGuardian(\n FacetCut[] calldata _diamondCut,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n ) external override onlyWhenUnlocked {\n if (_approvers.length != _signatures.length)\n revert DiamondCutFacet__InvalidArrayLength();\n _checkFacetCutValidity(_diamondCut);\n if (0 == LibGuardian.guardianCount())\n revert DiamondCutFacet__InvalidRouteWithGuardian();\n\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(cutHash, _approvers);\n\n bool onChainOwnerApproval = getOwnerCutApprovalWithTimeValidity(\n cutHash\n );\n\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n if (\n _approvers.length +\n getDiamondCutApprovalCountWithTimeValidity(cutHash) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert DiamondCutFacet__InsufficientApprovers();\n\n bool ownerApproved;\n for (uint256 i; i < _approvers.length; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n _approvers[i] != address(this)\n ) revert DiamondCutFacet__InvalidApprover();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert DiamondCutFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n cutHash,\n _signatures[i]\n )\n ) revert DiamondCutFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n if (!ownerApproved && !onChainOwnerApproval)\n revert DiamondCutFacet__LackOfOwnerApproval();\n\n ++LibFacetStorage.diamondCutStorage().nonce;\n LibDiamond.diamondCut(_diamondCut, address(0), \"\");\n }\n\n /**\n * @notice Approves diamond cut. This can only be called directly from guardian or owner\n * @param _diamondCut Contains the facet addresses and function selectors\n */\n function approveDiamondCut(\n FacetCut[] calldata _diamondCut\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\n if (LibGuardian.guardianCount() == 0)\n revert DiamondCutFacet__InvalidRouteWithoutGuardian();\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n _checkFacetCutValidity(_diamondCut);\n\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(\n true,\n approvalValidUntil\n );\n emit DiamondCutApproved(_diamondCut);\n if (\n (getDiamondCutApprovalCountWithTimeValidity(cutHash) >=\n LibGuardian.majorityOfGuardians()) &&\n getOwnerCutApprovalWithTimeValidity(cutHash)\n ) {\n ++LibFacetStorage.diamondCutStorage().nonce;\n LibDiamond.diamondCut(_diamondCut, address(0), \"\");\n }\n }\n\n /**\n * @notice Revokes the approval of diamond cut. This can only be called directly from guardian or owner\n * @param _diamondCut Contains the facet addresses and function selectors\n */\n function revokeDiamondCutApproval(\n FacetCut[] calldata _diamondCut\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\n if (!ds.isDiamondCutApproved[cutHash][msg.sender].isApproved)\n revert DiamondCutFacet__CannotRevokeUnapproved();\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(false, 0);\n emit DiamondCutApprovalRevoked(_diamondCut);\n }\n\n /**\n * @notice Gets the number of approvals of diamond cut from guardians\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n */\n function getDiamondCutApprovalCountWithTimeValidity(\n bytes32 _diamondCutHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardiansLength = guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n if (isCutApproved(_diamondCutHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n return approvalCount;\n }\n\n /**\n * @notice Returns if the owner has approved the diamond cut\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @return isApprovedByOwner Bool value showing if the owner approved the cut\n */\n function getOwnerCutApprovalWithTimeValidity(\n bytes32 _diamondCutHash\n ) public view override returns (bool isApprovedByOwner) {\n isApprovedByOwner = isCutApproved(_diamondCutHash, address(this));\n }\n\n /**\n * @notice Returns if the given approver has approved the diamond cut\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @param _approver Address of approver\n * @return isApproved Bool value showing if the approver approved the cut\n */\n function isCutApproved(\n bytes32 _diamondCutHash,\n address _approver\n ) public view override returns (bool isApproved) {\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n isApproved = (ds\n .isDiamondCutApproved[_diamondCutHash][_approver].isApproved &&\n block.timestamp <\n ds.isDiamondCutApproved[_diamondCutHash][_approver].validUntil);\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _diamondCutHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isCutApproved(_diamondCutHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert DiamondCutFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the diamond cut hash. This function ensures that this hash is safe from replay attack by including\n * salt, address, chainId, and nonce, etc.\n * @param _diamondCut Contains the facet addresses and function selectors\n * @return cutHash Diamond Cut Hash\n */\n function getDiamondCutHash(\n FacetCut[] calldata _diamondCut\n ) public view override returns (bytes32 cutHash) {\n cutHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n keccak256(abi.encode(_diamondCut)),\n address(this),\n block.chainid,\n LibFacetStorage.diamondCutStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Returns the approval validation Period\n * @dev This method fetches the validation period from the security manager\n * @return approvalValidationPeriod Approval validation period of Barz contract fetched from security manager\n */\n function getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod <= 0)\n revert DiamondCutFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the diamond cut nonce of this wallet\n * @dev This method fetches the nonce from diamond cut storage\n * @return cutNonce Nonce of diamond cut to protect from reply attacks\n */\n function getDiamondCutNonce()\n public\n view\n override\n returns (uint128 cutNonce)\n {\n cutNonce = LibFacetStorage.diamondCutStorage().nonce;\n }\n}\n" + }, + "contracts/facets/base/DiamondLoupeFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {IERC165} from \"../../interfaces/ERC/IERC165.sol\";\nimport {IERC1271} from \"../../interfaces/ERC/IERC1271.sol\";\nimport {IERC677Receiver} from \"../../interfaces/ERC/IERC677Receiver.sol\";\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC1155Receiver} from \"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\";\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../../libraries/LibLoupe.sol\";\nimport {LibUtils} from \"../../libraries/LibUtils.sol\";\nimport {IDiamondCut} from \"../../facets/base/interfaces/IDiamondCut.sol\";\nimport {IStorageLoupe} from \"./interfaces/IStorageLoupe.sol\";\nimport {IDiamondLoupe} from \"./interfaces/IDiamondLoupe.sol\";\n\n/**\n * @title DiamondLoupe Facet\n * @dev DiamondLoupe contract compatible with EIP-2535\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DiamondLoupeFacet is IDiamondLoupe, IStorageLoupe, IERC165 {\n // Diamond Loupe Functions\n ////////////////////////////////////////////////////////////////////\n /// These functions are expected to be called frequently by tools off-chain.\n\n /**\n * @notice Gets all facets and their selectors.\n * @dev Barz uses a special architecture called default fallback handler. Default Fallback handler is used as a middleware\n * that holds the mapping of facet function selector and facet address that Barz uses. This helps Barz to reduce\n * significant amount of gas during the initialization process.\n * Hence, this method aggregates both the facet information from DefaulFallbackHandler and in diamond storage and shows the data to users.\n * @return facets_ Facet\n */\n function facets() public view override returns (Facet[] memory facets_) {\n Facet[] memory defaultFacet = LibDiamond\n .diamondStorage()\n .defaultFallbackHandler\n .facets();\n Facet[] memory _facets = LibLoupe.facets();\n uint256 numFacets = _facets.length;\n bytes4[] memory keys;\n address[] memory values;\n for (uint256 i; i < numFacets; ) {\n uint256 selectorsLength = _facets[i].functionSelectors.length;\n for (uint256 j; j < selectorsLength; ) {\n (keys, values) = LibUtils.setValue(\n keys,\n values,\n _facets[i].functionSelectors[j],\n _facets[i].facetAddress\n );\n unchecked {\n ++j;\n }\n }\n unchecked {\n ++i;\n }\n }\n {\n bool iIncrement;\n for (uint256 i; i < defaultFacet.length; ) {\n bool jIncrement;\n for (\n uint256 j;\n j < defaultFacet[i].functionSelectors.length;\n\n ) {\n if (\n LibUtils.getValue(\n keys,\n values,\n defaultFacet[i].functionSelectors[j]\n ) != address(0)\n ) {\n if (defaultFacet[i].functionSelectors.length == 1) {\n defaultFacet = LibUtils.removeFacetElement(\n defaultFacet,\n i\n );\n iIncrement = true;\n break;\n }\n defaultFacet[i].functionSelectors = LibUtils\n .removeElement(\n defaultFacet[i].functionSelectors,\n j\n );\n jIncrement = true;\n }\n if (!jIncrement) {\n unchecked {\n ++j;\n }\n } else {\n jIncrement = false;\n }\n }\n if (!iIncrement) {\n unchecked {\n ++i;\n }\n } else {\n iIncrement = false;\n }\n }\n }\n {\n uint256 facetLength = numFacets + defaultFacet.length;\n facets_ = new Facet[](facetLength);\n uint256 defaultFacetIndex;\n for (uint256 i; i < facetLength; ) {\n if (i < numFacets) {\n facets_[i] = _facets[i];\n bool jIncrementor;\n for (uint256 j; j < defaultFacet.length; ) {\n if (\n facets_[i].facetAddress ==\n defaultFacet[j].facetAddress\n ) {\n facets_[i].functionSelectors = LibUtils.mergeArrays(\n _facets[i].functionSelectors,\n defaultFacet[j].functionSelectors\n );\n defaultFacet = LibUtils.removeFacetElement(\n defaultFacet,\n j\n );\n jIncrementor = true;\n {\n facets_ = LibUtils.removeFacetElement(\n facets_,\n facets_.length - 1\n );\n }\n --facetLength;\n }\n if (!jIncrementor) {\n unchecked {\n ++j;\n }\n } else {\n jIncrementor = false;\n }\n }\n } else {\n facets_[i] = defaultFacet[defaultFacetIndex];\n ++defaultFacetIndex;\n }\n unchecked {\n ++i;\n }\n }\n }\n }\n\n /**\n * @notice Gets all the function selectors provided by a facet.\n * @param _facet The facet address.\n * @return facetFunctionSelectors_\n */\n function facetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n Facet[] memory facet = facets();\n uint256 facetLength = facet.length;\n for (uint256 i; i < facetLength; ) {\n if (facet[i].facetAddress == _facet)\n return facet[i].functionSelectors;\n unchecked {\n ++i;\n }\n }\n return facetFunctionSelectors_;\n }\n\n /**\n * @notice Get all the facet addresses used by Barz.\n * @return facetAddresses_\n */\n function facetAddresses()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n Facet[] memory facet = facets();\n uint256 facetLength = facet.length;\n facetAddresses_ = new address[](facetLength);\n for (uint256 i; i < facetLength; ) {\n facetAddresses_[i] = facet[i].facetAddress;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Gets the facet that supports the given selector.\n * @dev If facet is not found return address(0).\n * @param _functionSelector The function selector.\n * @return facetAddress_ The facet address.\n */\n function facetAddress(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n\n facetAddress_ = address(bytes20(ds.facets[_functionSelector]));\n if (facetAddress_ == address(0)) {\n facetAddress_ = IDiamondLoupe(ds.defaultFallbackHandler)\n .facetAddress(_functionSelector);\n }\n }\n\n /**\n * @notice SupportInterface to be compatible with EIP 165\n * @param _interfaceId Interface ID for detecting the interface\n * @return isSupported Bool value showing if the standard is supported in the contract\n */\n function supportsInterface(\n bytes4 _interfaceId\n ) external view override returns (bool isSupported) {\n isSupported =\n _interfaceId == type(IERC165).interfaceId ||\n _interfaceId == IDiamondCut.diamondCut.selector ||\n _interfaceId == type(IDiamondLoupe).interfaceId ||\n _interfaceId == type(IERC1155Receiver).interfaceId ||\n _interfaceId == type(IERC721Receiver).interfaceId ||\n _interfaceId == type(IERC777Recipient).interfaceId ||\n _interfaceId == IERC1271.isValidSignature.selector ||\n _interfaceId == type(IERC677Receiver).interfaceId ||\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId];\n }\n\n /**\n * @notice Returns the facet from the diamond storage. This excludes the facets from the default fallback handler\n * @return facets_ Facet information attached directly to diamond storage\n */\n function facetsFromStorage()\n external\n view\n override\n returns (Facet[] memory facets_)\n {\n facets_ = LibLoupe.facets();\n }\n\n /**\n * @notice Returns the facet address attached to the given function selector. This excludes the facets from the default fallback handler\n * @param _functionSelector Function selector to fetch the facet address from diamond storage\n * @return facetAddress_ Facet address mapped with the function selector\n */\n function facetAddressFromStorage(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n facetAddress_ = LibLoupe.facetAddress(_functionSelector);\n }\n\n /**\n * @notice Returns all facet addresses attached directly to diamond storage. This excludes the facets from the default fallback handler\n * @return facetAddresses_ All facet addresses attached directly to diamond storage\n */\n function facetAddressesFromStorage()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n facetAddresses_ = LibLoupe.facetAddresses();\n }\n\n /**\n * @notice Returns function selectors of given facet address attached directly to diamond storage. This excludes the facets from the default fallback handler\n * @param _facet Facet address to fetch the facet function selectors from diamond storage\n * @return facetFunctionSelectors_ Facet function selectors of the given facet address\n */\n function facetFunctionSelectorsFromStorage(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n facetFunctionSelectors_ = LibLoupe.facetFunctionSelectors(_facet);\n }\n}\n" + }, + "contracts/facets/base/interfaces/IDiamondCut.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title DiamondCut Facet Interface\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IDiamondCut {\n error DiamondCutFacet__InvalidRouteWithGuardian();\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\n error DiamondCutFacet__InvalidArrayLength();\n error DiamondCutFacet__InsufficientApprovers();\n error DiamondCutFacet__InvalidApprover();\n error DiamondCutFacet__InvalidApproverSignature();\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\n error DiamondCutFacet__CannotRevokeUnapproved();\n error DiamondCutFacet__LackOfOwnerApproval();\n error DiamondCutFacet__OwnerAlreadyApproved();\n error DiamondCutFacet__DuplicateApproval();\n error DiamondCutFacet__InvalidInitAddress();\n\n event DiamondCutApproved(FacetCut[] diamondCut);\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\n\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\n\n enum FacetCutAction {\n Add,\n Replace,\n Remove\n }\n // Add=0, Replace=1, Remove=2\n\n struct FacetCut {\n address facetAddress;\n FacetCutAction action;\n bytes4[] functionSelectors;\n }\n\n /// @notice Add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param diamondCut Contains the facet addresses and function selectors\n /// @param init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function diamondCut(\n FacetCut[] calldata diamondCut,\n address init,\n bytes calldata _calldata\n ) external;\n\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\n\n function diamondCutWithGuardian(\n FacetCut[] calldata diamondCut,\n address[] calldata approvers,\n bytes[] calldata signatures\n ) external;\n\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\n\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\n\n function getDiamondCutApprovalCountWithTimeValidity(\n bytes32 diamondCutHash\n ) external view returns (uint256);\n\n function getOwnerCutApprovalWithTimeValidity(\n bytes32 diamondCutHash\n ) external view returns (bool);\n\n function isCutApproved(\n bytes32 diamondCutHash,\n address approver\n ) external view returns (bool);\n\n function getDiamondCutHash(\n FacetCut[] calldata diamondCut\n ) external view returns (bytes32);\n\n function getDiamondCutNonce() external view returns (uint128);\n}\n" + }, + "contracts/facets/base/interfaces/IDiamondLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n// A loupe is a small magnifying glass used to look at diamonds.\n// These functions look at diamonds\ninterface IDiamondLoupe {\n /// These functions are expected to be called frequently\n /// by tools.\n\n struct Facet {\n address facetAddress;\n bytes4[] functionSelectors;\n }\n\n /// @notice Gets all facet addresses and their four byte function selectors.\n /// @return facets_ Facet\n function facets() external view returns (Facet[] memory facets_);\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n /// @return facetFunctionSelectors_\n function facetFunctionSelectors(\n address _facet\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses()\n external\n view\n returns (address[] memory facetAddresses_);\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(\n bytes4 _functionSelector\n ) external view returns (address facetAddress_);\n}\n" + }, + "contracts/facets/base/interfaces/IStorageLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"./IDiamondLoupe.sol\";\n\n/**\n * @title LoupeFromStorage Interface\n * @dev Interface contract to function as a loupe facet directly attached to diamond storage of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IStorageLoupe {\n /// These functions are expected to be called frequently\n /// by tools.\n\n /// @notice Gets all facet addresses and their four byte function selectors.\n /// @return facets_ Facet\n function facetsFromStorage()\n external\n view\n returns (IDiamondLoupe.Facet[] memory);\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n function facetFunctionSelectorsFromStorage(\n address _facet\n ) external view returns (bytes4[] memory);\n\n /// @notice Get all the facet addresses used by a diamond.\n function facetAddressesFromStorage()\n external\n view\n returns (address[] memory);\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n function facetAddressFromStorage(\n bytes4 _functionSelector\n ) external view returns (address);\n}\n" + }, + "contracts/facets/GuardianFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibFacetStorage, GuardianStorage, StorageConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IGuardianFacet} from \"./interfaces/IGuardianFacet.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Guardian Facet\n * @dev Contract that enables addition/removal of guardians from Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract GuardianFacet is IGuardianFacet {\n ISecurityManager public immutable securityManager;\n uint8 public constant INNER_STRUCT = 0;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Add guardians to Barz.\n * @dev This method internally calls addGuardian which checks the validity of guardian address and adds\n * as guardian if valid\n * @param _guardians Array of addresses to add as guardian\n */\n function addGuardians(address[] calldata _guardians) external override {\n LibDiamond.enforceIsSelf();\n for (uint256 i; i < _guardians.length; ) {\n addGuardian(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Add a guardian to Barz.\n * @dev This method checks if the function is called by the owner and validates the address of guardian\n * When the validation passes, guardian address is added to the pending state waiting for confirmation\n * @param _guardian Address to add as guardian\n */\n function addGuardian(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (_guardian == address(this))\n revert GuardianFacet__GuardianCannotBeSelf();\n if (isGuardian(_guardian)) revert GuardianFacet__DuplicateGuardian();\n if (_guardian == address(0))\n revert GuardianFacet__ZeroAddressGuardian();\n if (\n keccak256(abi.encodePacked(_guardian)) ==\n keccak256(IVerificationFacet(address(this)).owner())\n ) revert GuardianFacet__OwnerCannotBeGuardian();\n\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n if (\n gs.pending[id] != 0 ||\n block.timestamp <= gs.pending[id] + getSecurityWindow()\n ) revert GuardianFacet__DuplicateGuardianAddition();\n\n uint256 securityPeriod = getAdditionSecurityPeriod();\n gs.pending[id] = block.timestamp + securityPeriod;\n emit GuardianAdditionRequested(\n _guardian,\n block.timestamp + securityPeriod\n );\n }\n\n /**\n * @notice Remove guardians from Barz.\n * @dev This method internally calls removeGuardian which checks the validity of guardian and removes\n * guardian when the request is valid\n * @param _guardians Array of addresses to be removed\n */\n function removeGuardians(address[] calldata _guardians) external override {\n LibDiamond.enforceIsSelf();\n for (uint256 i; i < _guardians.length; ) {\n removeGuardian(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Remove a guardian from Barz.\n * @dev This method validates if the guardian to be removed is a guardian and puts the guardian removal\n * to a pending state waiting to be confirmed.\n * @param _guardian Address of guardian to be removed\n */\n function removeGuardian(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n if (!isGuardian(_guardian)) revert GuardianFacet__NonExistentGuardian();\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n if (\n gs.pending[id] != 0 ||\n block.timestamp <= gs.pending[id] + getSecurityWindow()\n ) revert GuardianFacet__DuplicateGuardianRemoval();\n\n uint256 securityPeriod = getRemovalSecurityPeriod();\n gs.pending[id] = block.timestamp + securityPeriod;\n emit GuardianRemovalRequested(\n _guardian,\n block.timestamp + securityPeriod\n );\n }\n\n /**\n * @notice Confirm addition of guardians\n * @dev This method internally calls confirmGuardianAddition which checks the validity of pending request.\n * Guardians are fully added when they pass the validation. Anyone can call this function.\n * @param _guardians Array of guardian addresses to be added\n */\n function confirmGuardianAdditions(\n address[] calldata _guardians\n ) external override {\n for (uint256 i; i < _guardians.length; ) {\n confirmGuardianAddition(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Confirm addition of a guardian\n * @dev This method checks the validity of pending request.\n * Guardians are fully added when they pass the validation. Anyone can call this function.\n * @param _guardian Guardian address to be added\n */\n function confirmGuardianAddition(address _guardian) public override {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingAddition();\n if (gs.pending[id] >= block.timestamp)\n revert GuardianFacet__PendingAdditionNotOver();\n if (block.timestamp >= gs.pending[id] + getSecurityWindow())\n revert GuardianFacet__PendingAdditionExpired();\n\n _addGuardian(_guardian);\n\n delete gs.pending[id];\n emit GuardianAdded(_guardian);\n }\n\n /**\n * @notice Confirm removal of guardians\n * @dev This method internally calls confirmGuardianRemoval to check the validity guardian removal confirmation.\n * Guardians are fully removed when they pass the validation. Anyone can call this function.\n * @param _guardians Array of guardian addresses to be removed\n */\n function confirmGuardianRemovals(\n address[] calldata _guardians\n ) external override {\n for (uint256 i; i < _guardians.length; ) {\n confirmGuardianRemoval(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Confirm removal of a guardian\n * @dev This method checks the validity guardian removal confirmation.\n * Guardian is fully removed when they pass the validation. Anyone can call this function.\n * @param _guardian Guardian address to be removed\n */\n function confirmGuardianRemoval(address _guardian) public override {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingRemoval();\n if (gs.pending[id] >= block.timestamp)\n revert GuardianFacet__PendingRemovalNotOver();\n if (block.timestamp >= gs.pending[id] + getSecurityWindow())\n revert GuardianFacet__PendingAdditionExpired();\n\n _removeGuardian(_guardian);\n delete gs.pending[id];\n emit GuardianRemoved(_guardian);\n }\n\n /**\n * @notice Cancel pending guardian addition\n * @dev This method checks if the previous request for guardian request exists.\n * It reverts if previous request is not pending and cancels the addition otherwise.\n * @param _guardian Guardian address to be canceled from addition\n */\n function cancelGuardianAddition(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingAddition();\n delete gs.pending[id];\n emit GuardianAdditionCancelled(_guardian);\n }\n\n /**\n * @notice Cancel pending guardian removal\n * @dev This method checks if the previous request for guardian request exists.\n * It reverts if previous request is not pending and cancels the removal otherwise.\n * @param _guardian Guardian address to be canceled from removal\n */\n function cancelGuardianRemoval(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingRemoval();\n delete gs.pending[id];\n emit GuardianRemovalCancelled(_guardian);\n }\n\n /**\n * @notice Get the addition security period of current account from security manager\n * @dev This method returns the uint value if addition security period\n * @return additionSecurityPeriod Uint256 value of addition security period\n */\n function getAdditionSecurityPeriod()\n public\n view\n override\n returns (uint256 additionSecurityPeriod)\n {\n additionSecurityPeriod = securityManager.additionSecurityPeriodOf(\n address(this)\n );\n if (additionSecurityPeriod == 0)\n revert GuardianFacet__InvalidAdditionSecurityPeriod();\n }\n\n /**\n * @notice Get the removal security period of current account from security manager\n * @dev This method returns the uint value if removal security period\n * @return removalSecurityPeriod Uint256 value of removal security period\n */\n function getRemovalSecurityPeriod()\n public\n view\n override\n returns (uint256 removalSecurityPeriod)\n {\n removalSecurityPeriod = securityManager.removalSecurityPeriodOf(\n address(this)\n );\n if (removalSecurityPeriod == 0)\n revert GuardianFacet__InvalidRemovalSecurityPeriod();\n }\n\n /**\n * @notice Get the security window of current account from security manager\n * @dev This method returns the uint value if security window\n * @return securityWindow Uint256 value of removal security period\n */\n function getSecurityWindow()\n public\n view\n override\n returns (uint256 securityWindow)\n {\n securityWindow = securityManager.securityWindowOf(address(this));\n if (securityWindow == 0) revert GuardianFacet__InvalidSecurityWindow();\n }\n\n /**\n * @notice Checks if the addition of the given guardian address is pending\n * @dev This method returns the bool value of whether the guardian address is pending addition\n * @return isPending Bool value of representing the pending of guardian addition\n */\n function isAdditionPending(\n address _guardian\n ) public view override returns (bool isPending) {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n isPending = _isPending(id);\n }\n\n /**\n * @notice Checks if the removal of the given guardian address is pending\n * @dev This method returns the bool value of whether the guardian address is pending removal\n * @return isPending Bool value of representing the pending of guardian removal\n */\n function isRemovalPending(\n address _guardian\n ) public view override returns (bool isPending) {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n isPending = _isPending(id);\n }\n\n /**\n * @notice Checks if the given hash is pending\n * @dev This method returns the bool value whether the hash is pending\n * @return isPending Bool value of representing the pending of guardian operation\n */\n function _isPending(\n bytes32 _idHash\n ) internal view returns (bool isPending) {\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n isPending = ((gs.pending[_idHash] > 0 &&\n gs.pending[_idHash] < block.timestamp) &&\n block.timestamp < gs.pending[_idHash] + getSecurityWindow());\n }\n\n /**\n * @notice Adds guardian to storage config. This is called when guardian is fully added.\n * @dev This method add guardian address and config information to Facet Storage dedicated for guardian\n * When this function is called, guardian is fully added to this Barz Smart Account\n * @param _guardian Address of guardian to be added\n */\n function _addGuardian(address _guardian) internal {\n if (!isAdditionPending(_guardian))\n revert GuardianFacet__InvalidGuardianAddition();\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n if (config.info[_guardian].exists)\n revert GuardianFacet__AlreadyExists();\n\n config.info[_guardian].exists = true;\n config.info[_guardian].index = uint128(config.addresses.length);\n config.addresses.push(_guardian);\n }\n\n /**\n * @notice Removes guardian to storage config. This is called when guardian is fully removed.\n * @dev This method remove guardian address and config information to Facet Storage dedicated for guardian\n * When this function is called, guardian is fully removed from this Barz Smart Account\n * @param _guardian Address of guardian to be removed\n */\n function _removeGuardian(address _guardian) internal {\n if (!isRemovalPending(_guardian))\n revert GuardianFacet__InvalidGuardianRemoval();\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n if (!config.info[_guardian].exists)\n revert GuardianFacet__NonExistentGuardian();\n\n address lastAddress = config.addresses[config.addresses.length - 1];\n if (_guardian != lastAddress) {\n uint128 targetIndex = config.info[_guardian].index;\n config.addresses[targetIndex] = lastAddress;\n config.info[lastAddress].index = targetIndex;\n }\n config.addresses.pop();\n delete config.info[_guardian];\n\n emit GuardianRemoved(_guardian);\n }\n\n /**\n * @notice Reads guardian storage and fetches the addresses into an array from the storage\n * @dev This method fetches the guardian storage and returns the list of guardian addresses\n * @return addresses Array of addresses comprised of guardian\n */\n function getGuardians()\n public\n view\n override\n returns (address[] memory addresses)\n {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n addresses = new address[](config.addresses.length);\n uint256 addressesLen = config.addresses.length;\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the number of majority of guardians\n * @return majorityOfGuardians_ Number of majority of guardians e.g., 2 if 3 guardians / 3 if 5 guardians\n */\n function majorityOfGuardians()\n public\n view\n override\n returns (uint256 majorityOfGuardians_)\n {\n majorityOfGuardians_ = LibGuardian.majorityOfGuardians();\n }\n\n /**\n * @notice Reads guardian storage and fetches the addresses into an array from the storage\n * @dev This method fetches the guardian storage and returns the list of guardian addresses\n * @return guardianNumber Array of guardians in the account\n */\n function guardianCount()\n public\n view\n override\n returns (uint256 guardianNumber)\n {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n guardianNumber = config.addresses.length;\n }\n\n /**\n * @notice Reads guardian storage and checks if the given address is a guardian\n * @return isGuardian_ Bool value representing if the given address is guardian\n */\n function isGuardian(\n address _guardian\n ) public view override returns (bool isGuardian_) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n isGuardian_ = config.info[_guardian].exists;\n }\n\n /**\n * @notice Checks if the guardian number is zero and returns of guardian facet is okay to be removed\n * @return isRemovable Bool value representing if guardian facet is removable\n */\n function isGuardianFacetRemovable()\n external\n view\n override\n returns (bool isRemovable)\n {\n isRemovable = (0 == guardianCount());\n }\n}\n" + }, + "contracts/facets/interfaces/IAccountFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IEntryPoint} from \"../../aa-4337/interfaces/IEntryPoint.sol\";\n\n/**\n * @title Account Facet Interface\n * @dev Interface of module contract that provides the account features and init/unitialization of signer\n * compatible with EIP-1271 & EIP-4337\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IAccountFacet {\n event AccountInitialized(\n IEntryPoint indexed entryPoint,\n bytes indexed ownerPublicKey\n );\n // NOTE: Added Below Event\n event VerificationSuccess(bytes32);\n event VerificationFailure(bytes32);\n\n error AccountFacet__InitializationFailure();\n error AccountFacet__RestrictionsFailure();\n error AccountFacet__NonExistentVerificationFacet();\n error AccountFacet__CallNotSuccessful();\n\n function initialize(\n address verificationFacet,\n address anEntryPoint,\n address facetRegistry,\n address _defaultFallBack,\n bytes calldata _ownerPublicKey\n ) external returns (uint256);\n\n function execute(address dest, uint256 value, bytes calldata func) external;\n\n function executeBatch(\n address[] calldata dest,\n uint256[] calldata value,\n bytes[] calldata func\n ) external;\n}\n" + }, + "contracts/facets/interfaces/IAccountRecoveryFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {RecoveryConfig} from \"../../libraries/LibFacetStorage.sol\";\n\n/**\n * @title Account Recovery Facet Interface\n * @dev Interface of contract that enables recovery of accounts when owner key is unavailable\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IAccountRecoveryFacet {\n event RecoveryExecuted(\n bytes indexed recoveryPublicKey,\n uint64 executeAfter\n );\n event RecoveryFinalized(bytes indexed recoveryPublicKey);\n event RecoveryCanceled(bytes indexed recoveryPublicKey);\n event RecoveryApproved(\n bytes indexed recoveryPublicKey,\n address indexed guardian,\n uint64 validUntil\n );\n event RecoveryApprovalRevoked(\n bytes indexed recoveryPublicKey,\n address indexed guardian\n );\n event RecoveryCancellationApproved(\n bytes indexed recoveryPublicKey,\n address indexed guardian\n );\n event RecoveryHardstopped();\n\n error AccountRecoveryFacet__CallerNotGuardian();\n error AccountRecoveryFacet__InvalidRecoveryPublicKey();\n error AccountRecoveryFacet__SignerInitializationFailure();\n error AccountRecoveryFacet__SignerUninitializationFailure();\n error AccountRecoveryFacet__InvalidArrayLength();\n error AccountRecoveryFacet__InsufficientGuardians();\n error AccountRecoveryFacet__RecoveryAlreadyOngoing();\n error AccountRecoveryFacet__NonexistentRecovery();\n error AccountRecoveryFacet__NonExistentApproval();\n error AccountRecoveryFacet__RecoveryPeriodNotOver();\n error AccountRecoveryFacet__InvalidLockPeriod();\n error AccountRecoveryFacet__InvalidRecoveryPeriod();\n error AccountRecoveryFacet__InvalidApprovalValidationPeriod();\n error AccountRecoveryFacet__InvalidGuardian();\n error AccountRecoveryFacet__InvalidGuardianSignature();\n error AccountRecoveryFacet__InvalidOwnerSignature();\n error AccountRecoveryFacet__CallNotSuccesful();\n error AccountRecoveryFacet__DuplicateApproval();\n\n function approveAccountRecovery(bytes calldata recoveryPublicKey) external;\n\n function revokeAccountRecoveryApproval(\n bytes calldata recoveryPublicKey\n ) external;\n\n function executeRecovery(\n bytes calldata recoveryPublicKey,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function finalizeRecovery() external;\n\n function approveCancelRecovery(bytes calldata recoveryPublicKey) external;\n\n function cancelRecovery(\n bytes calldata recoveryPublicKey,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function hardstopRecovery(bytes calldata signature) external;\n\n function getApprovalRecoveryKeyHash(\n bytes memory recoveryPublicKey,\n string memory saltString\n ) external view returns (bytes32);\n\n function getRecoveryApprovalCountWithTimeValidity(\n bytes32 recoveryPublicKeyHash\n ) external view returns (uint256);\n\n function isRecoveryApproved(\n bytes32 recoveryPublicKeyHash,\n address approver\n ) external view returns (bool);\n\n function getRecoveryNonce() external view returns (uint128);\n\n function getPendingRecovery() external view returns (RecoveryConfig memory);\n}\n" + }, + "contracts/facets/interfaces/IGuardianFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Guardian Facet Interface\n * @dev Interface of guaridna contract that enables addition/removal of guardians from Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IGuardianFacet {\n event GuardianAdditionRequested(\n address indexed guardian,\n uint256 executeAfter\n );\n event GuardianRemovalRequested(\n address indexed guardian,\n uint256 executeAfter\n );\n event GuardianAdditionCancelled(address indexed guardian);\n event GuardianRemovalCancelled(address indexed guardian);\n event GuardianAdded(address indexed guardian);\n event GuardianRemoved(address indexed guardian);\n\n error GuardianFacet__GuardianCannotBeSelf();\n error GuardianFacet__DuplicateGuardian();\n error GuardianFacet__OwnerCannotBeGuardian();\n error GuardianFacet__DuplicateGuardianAddition();\n error GuardianFacet__DuplicateGuardianRemoval();\n error GuardianFacet__UnknownPendingAddition();\n error GuardianFacet__PendingAdditionNotOver();\n error GuardianFacet__UnknownPendingRemoval();\n error GuardianFacet__PendingRemovalNotOver();\n error GuardianFacet__PendingAdditionExpired();\n error GuardianFacet__InvalidAdditionSecurityPeriod();\n error GuardianFacet__InvalidRemovalSecurityPeriod();\n error GuardianFacet__InvalidSecurityWindow();\n error GuardianFacet__NonExistentGuardian();\n error GuardianFacet__AlreadyExists();\n error GuardianFacet__InvalidGuardianAddition();\n error GuardianFacet__InvalidGuardianRemoval();\n error GuardianFacet__ZeroAddressGuardian();\n\n function addGuardian(address guardian) external;\n\n function addGuardians(address[] calldata guardians) external;\n\n function removeGuardian(address guardian) external;\n\n function removeGuardians(address[] calldata guardians) external;\n\n function confirmGuardianAddition(address guardian) external;\n\n function confirmGuardianAdditions(address[] calldata guardian) external;\n\n function confirmGuardianRemoval(address guardian) external;\n\n function confirmGuardianRemovals(address[] calldata guardian) external;\n\n function cancelGuardianAddition(address guardian) external;\n\n function cancelGuardianRemoval(address guardian) external;\n\n function isGuardian(address guardian) external view returns (bool);\n\n function isAdditionPending(address guardian) external view returns (bool);\n\n function isRemovalPending(address guardian) external view returns (bool);\n\n function isGuardianFacetRemovable() external view returns (bool);\n\n function getAdditionSecurityPeriod() external view returns (uint256);\n\n function getRemovalSecurityPeriod() external view returns (uint256);\n\n function getSecurityWindow() external view returns (uint256);\n\n function getGuardians() external view returns (address[] memory);\n\n function majorityOfGuardians() external view returns (uint256);\n\n function guardianCount() external view returns (uint256);\n}\n" + }, + "contracts/facets/interfaces/ILockFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Lock} from \"../../libraries/LibAppStorage.sol\";\n\n/**\n * @title Lock Facet Interface\n * @dev Interface of Lock contract that enables full lock/unlock of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface ILockFacet {\n event Locked(uint64 releaseAfter);\n event Unlocked();\n\n error LockFacet__InvalidRecoveryPeriod();\n error LockFacet__CannotUnlock();\n error LockFacet__InvalidSignature();\n error LockFacet__InvalidApprover();\n\n function lock() external;\n\n function unlock(address approver, bytes calldata signature) external;\n\n function getLockPeriod() external view returns (uint256);\n\n function isLocked() external view returns (bool);\n\n function getUnlockHash() external view returns (bytes32);\n\n function lockNonce() external view returns (uint128);\n\n function getPendingLock() external view returns (Lock memory);\n}\n" + }, + "contracts/facets/interfaces/IMultiSigFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Multi-sig facet Interface\n * @dev Interface of Multi-signature Facet with custom threshold.\n Wallet that adds this facet becomes a multi-sig wallet\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IMultiSigFacet {\n event ThresholdChanged(uint256 threshold);\n event OwnerAdded(address indexed newOwner);\n event OwnerRemoved(address indexed prevOwner);\n event HashApproved(bytes32 hashToApprove, address indexed owner);\n\n error MultiSigFacet__InvalidThreshold();\n error MultisigFacet__InvalidOwnerCount();\n error MultiSigFacet__InvalidRoute();\n error MultiSigFacet__InsufficientSignerLength();\n error MultiSigFacet__InvalidInitData();\n error MultiSigFacet__InvalidOwnerAddress();\n error MultiSigFacet__InvalidOwnerPair();\n error MultiSigFacet__InvalidSignatureLength();\n error MultiSigFacet__InvalidSignatureType();\n error MultiSigFacet__DuplicateOwner();\n error MultiSigFacet__OnlyOwner();\n\n function checkSignatures(\n bytes32 _dataHash,\n bytes calldata _signatures,\n uint256 _threshold\n ) external view returns (uint256);\n\n function splitSignatures(\n bytes calldata _signatures,\n uint256 _nextOffset\n )\n external\n pure\n returns (\n address owner,\n bytes memory signature,\n uint256 signatureType,\n uint256 nextOffset\n );\n\n function approveHash(bytes32 hashToApprove) external;\n\n function addOwner(address newOwner, uint256 threshold) external;\n\n function removeOwner(\n address prevOwner,\n address removedOwner,\n uint256 threshold\n ) external;\n\n function swapOwner(\n address prevOwner,\n address oldOwner,\n address newOwner\n ) external;\n\n function changeThreshold(uint256 _threshold) external;\n\n function isOwner(address owner) external view returns (bool);\n\n function getThreshold() external view returns (uint256);\n\n function getOwners() external view returns (address[] memory);\n}\n" + }, + "contracts/facets/interfaces/IRestrictionsFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Restrictions Facet Interface\n * @dev Interface of Restrictions contract that enables modular restrictions in Barz\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IRestrictionsFacet {\n event RestrictionAdded(address indexed restriction);\n event RestrictionRemoved(address indexed restriction);\n\n error RestrictionsFacet__EmptyRestrictionsList();\n error RestrictionsFacet__RestrictionNotFound();\n error RestrictionsFacet__RestrictionAlreadyExists();\n error RestrictionsFacet__ZeroAddressRestrictions();\n error RestrictionsFacet__ZeroAddressRestrictionsFacet();\n error RestrictionsFacet__RemainingRestrictionsCantBeEmpty();\n\n function initializeRestrictions(\n address[] memory _restrictions\n ) external returns (uint256);\n\n function uninitializeRestrictions() external returns (uint256);\n\n function getRestrictions() external view returns (address[] memory);\n\n function addRestriction(address restriction) external;\n\n function removeRestriction(address restriction) external;\n\n function verifyRestrictions(\n address from,\n address to,\n uint256 value,\n bytes calldata _calldata\n ) external returns (uint256);\n}\n" + }, + "contracts/facets/interfaces/ISignatureMigrationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureMigrationConfig} from \"../../libraries/LibFacetStorage.sol\";\n\n/**\n * @title Signature Migration Facet Interface\n * @dev Interface of Signature Migration contract for migrating user signature scheme to a new scheme user sets\n * Which could include\n * - ECDSA on Secp256K1 Curve\n * - ECDSA on Secp256R1 Curve\n * - BLS, Schnorr, etc\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface ISignatureMigrationFacet {\n event SignatureSchemeMigration(\n address indexed prevVerificationFacet,\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n event SignatureMigrationApproved(\n bytes newPublicKey,\n address indexed newVerificationFacet,\n bytes4[] verificationFuncSelectors,\n address indexed guardian,\n uint128 approvalValidUntil\n );\n event SignatureMigrationApprovalRevoked(\n bytes newPublicKey,\n address indexed newVerificationFacet,\n bytes4[] verificationFuncSelectors,\n address indexed guardian\n );\n event SignatureMigrationExecuted(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors,\n uint128 migrateAfter\n );\n event SignatureMigrationCanceled(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n event SignatureMigrationCancellationApproved(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n\n error SignatureMigrationFacet__SignerUninitializationFailure();\n error SignatureMigrationFacet__InvalidRouteWithGuardian();\n error SignatureMigrationFacet__InvalidKeyType();\n error SignatureMigrationFacet__InsufficientApprovers();\n error SignatureMigrationFacet__InvalidApproverSignature();\n error SignatureMigrationFacet__InvalidGuardian();\n error SignatureMigrationFacet__NonExistentApprover();\n error SignatureMigrationFacet__InvalidMigrationPeriod();\n error SignatureMigrationFacet__NonexistentMigration();\n error SignatureMigrationFacet__MigrationPeriodNotOver();\n error SignatureMigrationFacet__InvalidArrayLength();\n error SignatureMigrationFacet__InvalidApprovalValidationPeriod();\n error SignatureMigrationFacet__CannotRevokeUnapproved();\n error SignatureMigrationFacet__LackOfOwnerApproval();\n error SignatureMigrationFacet__OwnerAlreadyApproved();\n error SignatureMigrationFacet__NonExistentVerificationFacet();\n error SignatureMigrationFacet__DuplicateApproval();\n\n function migrateSignatureScheme(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function migrateSignatureSchemeWithGuardian(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors,\n address[] calldata approvers,\n bytes[] calldata signatures\n ) external;\n\n function approveSignatureSchemeMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function revokeSignatureMigrationApproval(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function finalizeSignatureMigration() external;\n\n function approveCancelSignatureMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function cancelSignatureMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function getApprovalMigrationKeyHash(\n bytes memory recoveryPublicKey,\n address newVerificationFacet,\n bytes4[] memory newVerificationFuncSelectors,\n string memory saltString\n ) external view returns (bytes32);\n\n function getMigrationOwnerApprovalWithTimeValidity(\n bytes32 publicKeyHash\n ) external view returns (bool);\n\n function getMigrationApprovalCountWithTimeValidity(\n bytes32 publicKeyHash\n ) external view returns (uint256);\n\n function isMigrationApproved(\n bytes32 migrationPublicKeyHash,\n address approver\n ) external view returns (bool);\n\n function getMigrationNonce() external view returns (uint128);\n\n function isMigrationPending() external view returns (bool);\n\n function getPendingMigration()\n external\n view\n returns (SignatureMigrationConfig memory);\n}\n" + }, + "contracts/facets/interfaces/IVerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {UserOperation} from \"../../aa-4337/interfaces/UserOperation.sol\";\n\n/**\n * @title Verification Facet Interface\n * @dev Implements logic for user ops signature verification\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface IVerificationFacet {\n event SignerInitialized(bytes);\n event SignerUninitialized();\n\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n error VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n error VerificationFacet__InitializationFailure();\n error VerificationFacet__InvalidFacetMapping();\n\n function initializeSigner(bytes memory) external returns (uint256);\n\n function uninitializeSigner() external returns (uint256);\n\n function validateOwnerSignatureSelector() external view returns (bytes4);\n\n function owner() external view returns (bytes memory);\n\n function isValidKeyType(bytes calldata) external view returns (bool);\n\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) external view returns (uint256);\n}\n" + }, + "contracts/facets/LockFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage, Lock} from \"../libraries/LibAppStorage.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibFacetStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {ILockFacet} from \"./interfaces/ILockFacet.sol\";\n\n/**\n * @title Lock Facet\n * @dev Contract that enables full lock/unlock of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract LockFacet is ILockFacet, Modifiers {\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Locks the account for the lock period. Lock period is defined in the security manager and it's customizable\n * This function can only be called when account is unlocked by owner or guardians\n * @dev This method checks the caller and if the account is currently locked and locks the account after fetching the\n * Lock period from the owner.\n */\n function lock() external override onlyGuardianOrOwner onlyWhenUnlocked {\n uint256 unlockTime = block.timestamp + getLockPeriod();\n ++LibFacetStorage.lockStorage().nonce;\n LibAppStorage.setLock(unlockTime, LockFacet.lock.selector);\n emit Locked(uint64(unlockTime));\n }\n\n /**\n * @notice Locks the account when the account is locked. This function can be called by anyone but must provide the approver address and signature.\n * The approver should be one of the guardians or owner.\n * @dev This method takes the approver address and the signature. After validating the address and the signature, it unlocks the account immediately.\n * Only one of the guardian or owner is required to lock and unlock the account.\n * @param _approver Address of approver approving the unlock of Barz account\n * @param _signature Signature of the approver that signed the msg hash for unlocking the account\n */\n function unlock(\n address _approver,\n bytes calldata _signature\n ) external override onlyWhenLocked {\n if (_approver != address(this) && !LibGuardian.isGuardian(_approver))\n revert LockFacet__InvalidApprover();\n if (\n !SignatureChecker.isValidSignatureNow(\n _approver,\n getUnlockHash(),\n _signature\n )\n ) revert LockFacet__InvalidSignature();\n _unlock();\n }\n\n /**\n * @notice Unlocks the account and increments the lock nonce\n */\n function _unlock() private {\n if (s.locks[INNER_STRUCT].locker != LockFacet.lock.selector)\n revert LockFacet__CannotUnlock();\n ++LibFacetStorage.lockStorage().nonce;\n LibAppStorage.setLock(0, bytes4(0));\n emit Unlocked();\n }\n\n /**\n * @notice Returns the lock period of current Barz account. Lock period information is held by Security Manager\n * @return lockPeriod Uint value of lock period in seconds\n */\n function getLockPeriod() public view override returns (uint256 lockPeriod) {\n lockPeriod = securityManager.lockPeriodOf(address(this));\n if (lockPeriod == 0) revert LockFacet__InvalidRecoveryPeriod();\n }\n\n /**\n * @notice Returns if the account is locked or not\n * @dev This method fetches the current block timestamp and compares that with release time.\n * After checking the timestamp and release time, it returns if the account is still locked or not.\n * @return isLocked_ Uint value of lock period in seconds\n */\n function isLocked() public view override returns (bool isLocked_) {\n isLocked_ = uint64(block.timestamp) < s.locks[INNER_STRUCT].release;\n }\n\n /**\n * @notice Calculates the unlock hash and returns the unlock hash safe from signature reply attack\n * @dev This method calculates the unlock hash with EIP-191 prefix, wallet address, chainID, and nonce\n * It packs the result and packs them and hashes it.\n * @return unlockHash Bytes32 unlock hash\n */\n function getUnlockHash() public view override returns (bytes32 unlockHash) {\n unlockHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n \"Unlock\",\n address(this),\n block.chainid,\n lockNonce()\n )\n )\n )\n );\n }\n\n /**\n * @notice Returns lock nonce of account. Reads nonce from lock storage within facet storage\n * @return lockNonce_ Uint128 value of lock nonce. This is incremented whenever the account is lock/unlocked\n */\n function lockNonce() public view override returns (uint128 lockNonce_) {\n lockNonce_ = LibFacetStorage.lockStorage().nonce;\n }\n\n /**\n * @notice Returns the overall information of current lock\n * @return pendingLock Struct value including all information of pending lock\n */\n function getPendingLock()\n public\n view\n override\n returns (Lock memory pendingLock)\n {\n pendingLock = s.locks[INNER_STRUCT];\n }\n}\n" + }, + "contracts/facets/Modifiers.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {IFacetRegistry} from \"../infrastructure/interfaces/IFacetRegistry.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\n\n/**\n * @title Modifiers\n * @dev Responsible for providing modifiers/util functions to Facet contracts\n * @author David Yongjun Kim (@Powerstream3604)\n */\nabstract contract Modifiers is BarzStorage {\n uint8 constant INNER_STRUCT = 0;\n\n error CallerNotGuardian();\n error CallerNotGuardianOrOwner();\n error DuplicateApprover();\n error ZeroApproverLength();\n error UnregisteredFacetAndSelectors();\n\n /**\n * @notice Modifier to only allow guardian to make a call, reverts if any other entity is the caller\n */\n modifier onlyGuardian() {\n if (!LibGuardian.isGuardian(msg.sender)) revert CallerNotGuardian();\n _;\n }\n\n /**\n * @notice Modifier to only allow guardian or owner to make a call, reverts if any other entity is the caller\n */\n modifier onlyGuardianOrOwner() {\n if (!LibGuardian.isGuardian(msg.sender) && address(this) != msg.sender)\n revert CallerNotGuardianOrOwner();\n _;\n }\n\n /**\n * @notice Checks if the approver address is the array is unique with no duplicate\n * @dev This method loops through the array and checks if a duplicate address exists, it reverts if duplicate address exists\n * @param approvers Array of address\n */\n function _checkApprover(\n address[] memory approvers\n ) internal pure returns (bool) {\n uint256 approverLength = approvers.length;\n if (0 == approverLength) revert ZeroApproverLength();\n for (uint256 i; i < approverLength - 1; ) {\n for (uint256 j = i + 1; j < approverLength; ) {\n if (approvers[i] == approvers[j]) {\n revert DuplicateApprover(); // Found a duplicate\n }\n unchecked {\n ++j;\n }\n }\n unchecked {\n ++i;\n }\n }\n return false; // No duplicates found\n }\n\n /**\n * @notice Checks if the facet getting added or replaced is registered to facet registry\n * @dev This method loops through the cut and checks if the facet getting added/replaced is registered to facet registry\n * @param _diamondCut Array of FacetCut, data for diamondCut defined in EIP-2535\n */\n function _checkFacetCutValidity(\n IDiamondCut.FacetCut[] memory _diamondCut\n ) internal view {\n uint256 diamondCutLength = _diamondCut.length;\n for (uint256 i; i < diamondCutLength; ) {\n if (\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Add ||\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Replace\n ) {\n if (\n !s.facetRegistry.areFacetFunctionSelectorsRegistered(\n _diamondCut[i].facetAddress,\n _diamondCut[i].functionSelectors\n )\n ) revert UnregisteredFacetAndSelectors();\n }\n unchecked {\n ++i;\n }\n }\n }\n}\n" + }, + "contracts/facets/RestrictionsFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, RestrictionsStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {IRestriction} from \"../restrictions/IRestriction.sol\";\nimport {IRestrictionsFacet} from \"./interfaces/IRestrictionsFacet.sol\";\n\n/**\n * @title Restrictions facet\n * @dev Responsible for storing and verifying different kinds of restrictions, for example:\n * - Whitelist / Blacklist\n * - Daily limits\n * - Trading time restrictions\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract RestrictionsFacet is IRestrictionsFacet {\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceRestrictionsInitialize();\n }\n\n /**\n * @notice Intialize restrictions of Barz. Restrictions facet call restriction contracts for restriction validation\n * before each call\n * @param _restrictions The initial array of restrictions.\n * @return initSuccess Int value showing if the initialization of restriction is successful\n */\n function initializeRestrictions(\n address[] calldata _restrictions\n ) public override returns (uint256 initSuccess) {\n LibDiamond.enforceIsSelf();\n LibAppStorage.enforceRestrictionsInitialize();\n\n if (_restrictions.length == 0) {\n // You can't initialize RestrictionsFacet with an empty list of restrictions\n revert RestrictionsFacet__EmptyRestrictionsList();\n }\n for (uint256 i; i < _restrictions.length; ) {\n if (_restrictions[i] == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictions();\n unchecked {\n ++i;\n }\n }\n\n LibFacetStorage.restrictionsStorage().restrictions = _restrictions;\n _updateRestrictionsMap(_restrictions, true);\n initSuccess = 1;\n }\n\n /**\n * @notice Unitialize restrictions of Barz\n * @return uninitSuccess Int value showing if the initialization of restriction is successful\n */\n function uninitializeRestrictions()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibDiamond.enforceIsSelf();\n LibAppStorage.setRestrictionsUninitialized();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n _updateRestrictionsMap(restrictionsStorage.restrictions, false);\n restrictionsStorage.restrictions = new address[](0);\n uninitSuccess = 1;\n }\n\n /**\n * @notice Returns the list of Restrictions contract address\n * @return restrictions Addresses of IRestriction which are currently active\n */\n function getRestrictions()\n public\n view\n override\n returns (address[] memory restrictions)\n {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n restrictions = restrictionsStorage.restrictions;\n }\n\n /**\n * @notice Adds restrictions to Barz with validation on the restriction contract address.\n * This method is only callable by the owner(self).\n * @param _restriction The address of the restriction to be added.\n */\n function addRestriction(address _restriction) external override {\n LibDiamond.enforceIsSelf();\n if (LibDiamond.restrictionsFacet() == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictionsFacet();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n if (_restriction == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictions();\n if (restrictionsStorage.exists[_restriction])\n revert RestrictionsFacet__RestrictionAlreadyExists();\n\n restrictionsStorage.restrictions.push(_restriction);\n restrictionsStorage.exists[_restriction] = true;\n\n emit RestrictionAdded(_restriction);\n }\n\n /**\n * @notice Remove restrictions from Barz if it existed. This method is only callable by the owner(self).\n * @param _restriction The address of the restriction to be removed.\n */\n function removeRestriction(address _restriction) external override {\n LibDiamond.enforceIsSelf();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n if (!restrictionsStorage.exists[_restriction])\n revert RestrictionsFacet__RestrictionNotFound();\n\n address[] storage restrictions = restrictionsStorage.restrictions;\n\n uint256 indexToDelete = restrictions.length;\n uint256 restrictionsLen = restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n if (restrictions[i] == _restriction) {\n indexToDelete = i;\n break;\n }\n unchecked {\n ++i;\n }\n }\n\n if (indexToDelete == 0 && restrictionsLen == 1) {\n revert RestrictionsFacet__RemainingRestrictionsCantBeEmpty();\n } else if (indexToDelete == restrictionsLen) {\n revert RestrictionsFacet__RestrictionNotFound();\n } else {\n restrictions[indexToDelete] = restrictions[restrictionsLen - 1];\n restrictions.pop();\n }\n\n restrictionsStorage.exists[_restriction] = false;\n emit RestrictionRemoved(_restriction);\n }\n\n /**\n * @notice Sets the restrictions address value mapping to true or false when adding/removing restriction contracts\n * @param _restrictions List of restriction contracts address\n * @param _newValue Bool value to flag to the list of restrictions contracts\n */\n function _updateRestrictionsMap(\n address[] memory _restrictions,\n bool _newValue\n ) internal {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n uint restrictionsLen = _restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n restrictionsStorage.exists[_restrictions[i]] = _newValue;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @dev Iterates over all restrictions and verifies each of them with the transaction parameters.\n * @param _from The address of the sender, that will be signing the transaction.\n * @param _to The receiving address.\n * @param _value Amount of ETH to transfer from sender to recipient.\n * @param _calldata Optional field to include arbitrary data.\n * @return 0 if all the checks passed, 1 otherwise.\n */\n function verifyRestrictions(\n address _from,\n address _to,\n uint256 _value,\n bytes calldata _calldata\n ) external returns (uint256) {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n uint restrictionsLen = restrictionsStorage.restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n IRestriction restriction = IRestriction(\n restrictionsStorage.restrictions[i]\n );\n bool checkPassed = restriction.check(_from, _to, _value, _calldata);\n if (!checkPassed) {\n return 1;\n }\n unchecked {\n ++i;\n }\n }\n\n return 0;\n }\n}\n" + }, + "contracts/facets/SignatureMigrationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, SignatureMigrationStorage, SignatureMigrationConfig, SignatureMigrationApprovalConfig, ApprovalConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IDiamondCut} from \"./base/interfaces/IDiamondCut.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {ISignatureMigrationFacet} from \"./interfaces/ISignatureMigrationFacet.sol\";\n\n/**\n * @title Signature Migration Facet\n * @dev Responsible for migrating user signature scheme to a new scheme user sets\n * Which could include\n * - ECDSA on Secp256K1 Curve\n * - ECDSA on Secp256R1 Curve\n * - BLS, Schnorr, etc\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract SignatureMigrationFacet is ISignatureMigrationFacet, Modifiers {\n bytes constant UNINIT_CALL =\n abi.encodeWithSignature(\"uninitializeSigner()\");\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This modifier verifies if the public key format matches with the new verification facet\n * @param _publicKey Bytes of public key to be validated for the new verification facet\n * @param _newVerificationFacet Address of new verification facet\n */\n modifier validateKeyType(\n bytes memory _publicKey,\n address _newVerificationFacet\n ) {\n if (\n !IVerificationFacet(_newVerificationFacet).isValidKeyType(\n _publicKey\n )\n ) revert SignatureMigrationFacet__InvalidKeyType();\n _;\n }\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n // IMPORTANT NOTE: In the client side when they call this function, the func selectors should be sorted in ascending order\n // to prevent different hash with same items in the array\n /**\n * @notice Moves the state of migration to a pending state. When pending state is over after pending period time,\n * Migration can be finalized. This function can only be called by self and when the account is unlocked.\n * @dev This method checks if the caller is self and if guardians exists. It migrates signature request to a pending state\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function migrateSignatureScheme(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n public\n override\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n // Only self contract can call this function\n LibDiamond.enforceIsSelf();\n // Should revert if guardian exist\n if (0 != LibGuardian.guardianCount())\n revert SignatureMigrationFacet__InvalidRouteWithGuardian();\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n // NOTE: Migration requires a pending period & confirmation from owner to prevent a\n // single call changing the ownership of the wallet\n /**\n * @notice Migrate signature scheme when guardians exists. Verifies the signature of guardians and moves migration to pending state.\n * Which can then be finalized when pending period is over. Owner's approval is mandatory for migration to happen\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _approvers List of approvers. This could include owner\n */\n function migrateSignatureSchemeWithGuardian(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n )\n public\n override\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n // Should revert if does not guardian exist\n if (0 == LibGuardian.guardianCount())\n revert SignatureMigrationFacet__InvalidRouteWithGuardian();\n if (_approvers.length != _signatures.length)\n revert SignatureMigrationFacet__InvalidArrayLength();\n\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(migrationPublicKeyHash, _approvers);\n\n bool onChainOwnerApproval = getMigrationOwnerApprovalWithTimeValidity(\n migrationPublicKeyHash\n );\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n\n if (\n _approvers.length +\n getMigrationApprovalCountWithTimeValidity(\n migrationPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert SignatureMigrationFacet__InsufficientApprovers();\n {\n // To prevent Stack too deep\n bool ownerApproved;\n for (uint256 i; i < _approvers.length; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n address(this) != _approvers[i]\n ) revert SignatureMigrationFacet__InvalidGuardian();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert SignatureMigrationFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n migrationPublicKeyHash,\n _signatures[i]\n )\n ) revert SignatureMigrationFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n\n if (!ownerApproved && !onChainOwnerApproval)\n revert SignatureMigrationFacet__LackOfOwnerApproval();\n }\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Internal function that moves signature mgiration to a pending state.\n * @dev This method increments migration nonce and sets the migration in the migration config. Emits events for migration execution\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _migrateSignatureScheme(\n address _newVerificationFacet,\n bytes memory _newPublicKey,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal {\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n\n ++ms.nonce;\n uint64 migrateAfter = uint64(block.timestamp + getMigrationPeriod());\n\n ms.migrationConfigs[INNER_STRUCT] = SignatureMigrationConfig(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n migrateAfter\n );\n\n emit SignatureMigrationExecuted(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors,\n migrateAfter\n );\n }\n\n /**\n * @notice Approves signature scheme migration on-chain. This can be called by owner or guardian only when the account is unlocked.\n * When the threshold of the migration approval passed and owner approval is granted, it automatically moves migration to a pending state\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function approveSignatureSchemeMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n public\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit SignatureMigrationApproved(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n msg.sender,\n approvalValidUntil\n );\n if (\n getMigrationApprovalCountWithTimeValidity(migrationPublicKeyHash) >=\n LibGuardian.majorityOfGuardians() &&\n getMigrationOwnerApprovalWithTimeValidity(migrationPublicKeyHash)\n )\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Revokes the approval of signature migration done on-chain. Emits revoke event when revoked.\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function revokeSignatureMigrationApproval(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n external\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n if (!isMigrationApproved(migrationPublicKeyHash, msg.sender))\n revert SignatureMigrationFacet__CannotRevokeUnapproved();\n\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(false, 0);\n emit SignatureMigrationApprovalRevoked(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n msg.sender\n );\n }\n\n /**\n * @notice Finalizes the pending signature scheme migration. This function can only be called by owner.\n * It removes the facets of the previous verification facet and adds the new verification facet.\n * After finalizing migration, it emits migration event which shows the change of the verification facet\n */\n function finalizeSignatureMigration() external override {\n // NOTE: Only owner can call this function\n LibDiamond.enforceIsSelf();\n\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n\n if (!isMigrationPending())\n revert SignatureMigrationFacet__NonexistentMigration();\n\n if (\n uint64(block.timestamp) <=\n ms.migrationConfigs[INNER_STRUCT].migrateAfter\n ) revert SignatureMigrationFacet__MigrationPeriodNotOver();\n address newVerificationFacet = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationVerificationFacet;\n bytes4[] memory newVerificationFuncSelectors = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationSelectors;\n bytes memory newPublicKey = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationPublicKey;\n\n address prevVerificationFacet = LibLoupe.facetAddress(\n s.validateOwnerSignatureSelector\n );\n if (prevVerificationFacet == address(0))\n revert SignatureMigrationFacet__NonExistentVerificationFacet();\n\n IDiamondCut.FacetCut[] memory UninitCut;\n IDiamondCut.FacetCut[] memory InitCut;\n {\n bytes4[] memory prevVerificationFuncSelectors = LibLoupe\n .facetFunctionSelectors(prevVerificationFacet);\n\n UninitCut = new IDiamondCut.FacetCut[](1);\n InitCut = new IDiamondCut.FacetCut[](1);\n UninitCut[0] = IDiamondCut.FacetCut({\n facetAddress: address(0),\n action: IDiamondCut.FacetCutAction.Remove,\n functionSelectors: prevVerificationFuncSelectors\n });\n InitCut[0] = IDiamondCut.FacetCut({\n facetAddress: newVerificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: newVerificationFuncSelectors\n });\n {\n IDiamondCut.FacetCut[]\n memory facetCuts = new IDiamondCut.FacetCut[](2);\n facetCuts[0] = UninitCut[0];\n facetCuts[1] = InitCut[0];\n _checkFacetCutValidity(facetCuts);\n }\n LibAppStorage.initiateSignerMigration();\n address verificationFacet = address(\n bytes20(\n LibDiamond.diamondStorage().facets[\n s.validateOwnerSignatureSelector\n ]\n )\n );\n\n (bool success, bytes memory result) = verificationFacet\n .delegatecall(UNINIT_CALL);\n require(success, \"MigrationFacet: uninitialize not successful\");\n uint256 validationData = uint256(bytes32(result));\n if (validationData == 0)\n revert SignatureMigrationFacet__SignerUninitializationFailure();\n\n LibDiamond.diamondCut(UninitCut, address(0), \"\");\n }\n {\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n newPublicKey\n );\n\n // Every Verification Facet should comply with initializeSigner(bytes)\n // to be compatible with the Barz contract(for initialization)\n LibDiamond.diamondCut(InitCut, newVerificationFacet, initCall);\n LibAppStorage.finalizeSignerMigration();\n emit SignatureSchemeMigration(\n prevVerificationFacet,\n newVerificationFacet,\n newPublicKey,\n newVerificationFuncSelectors\n );\n }\n }\n\n /**\n * @notice Approve cancellation of signature migration. If cancellation approval passes guardian threshold with owner approval\n * it automatically cancels the migration.\n * @dev This method checks if the caller is one of guardian or owner and sets true for the cancellation hash in the approval config.\n * It internally calls _cancelSignatureMigration for canceling the migration\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function approveCancelSignatureMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n external\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"CancelSignatureMigration\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit SignatureMigrationCancellationApproved(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n if (\n getMigrationApprovalCountWithTimeValidity(migrationPublicKeyHash) >=\n LibGuardian.majorityOfGuardians() &&\n getMigrationOwnerApprovalWithTimeValidity(migrationPublicKeyHash)\n )\n _cancelSignatureMigration(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Verifies the signature of guardians/owner and cancels the signature migration.\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _approvers List of approvers. This could include owner\n */\n function cancelSignatureMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n )\n external\n override\n validateKeyType(_newPublicKey, _newVerificationFacet)\n onlyWhenUnlocked\n {\n if (_approvers.length != _signatures.length)\n revert SignatureMigrationFacet__InvalidArrayLength();\n\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"CancelSignatureMigration\"\n );\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(migrationPublicKeyHash, _approvers);\n\n bool onChainOwnerApproval = getMigrationOwnerApprovalWithTimeValidity(\n migrationPublicKeyHash\n );\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n if (\n _approvers.length +\n getMigrationApprovalCountWithTimeValidity(\n migrationPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert SignatureMigrationFacet__InsufficientApprovers();\n {\n // To prevent stack too deep\n bool ownerApproved;\n for (uint256 i; i < _approvers.length; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n address(this) != _approvers[i]\n ) revert SignatureMigrationFacet__NonExistentApprover();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert SignatureMigrationFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n migrationPublicKeyHash,\n _signatures[i]\n )\n ) revert SignatureMigrationFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n if (!ownerApproved && !onChainOwnerApproval)\n revert SignatureMigrationFacet__LackOfOwnerApproval();\n }\n _cancelSignatureMigration(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Internal function that cancels signature migration.\n * @dev This method increments migration nonce and deletes the migration from the migration config. Emits events for migration cancellation\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _cancelSignatureMigration(\n address _newVerificationFacet,\n bytes memory _newPublicKey,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal {\n if (!isMigrationPending())\n revert SignatureMigrationFacet__NonexistentMigration();\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n ++ms.nonce;\n delete ms.migrationConfigs[INNER_STRUCT];\n emit SignatureMigrationCanceled(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Checks if the facets to be added from new verification facet is registered to facet registry\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _checkMigrationCutValidity(\n address _newVerificationFacet,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal view {\n IDiamondCut.FacetCut[] memory facetCuts = new IDiamondCut.FacetCut[](1);\n facetCuts[0] = IDiamondCut.FacetCut({\n facetAddress: _newVerificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: _newVerificationFuncSelectors\n });\n _checkFacetCutValidity(facetCuts);\n }\n\n /**\n * @notice Returns if the migration is pending of not\n * @dev This method fetches the migration storage and checks if the migrate after is above 0 value\n * @return isPending Bool value that shows if the migration is pending\n */\n function isMigrationPending()\n public\n view\n override\n returns (bool isPending)\n {\n SignatureMigrationStorage storage rs = LibFacetStorage\n .migrationStorage();\n isPending = rs.migrationConfigs[INNER_STRUCT].migrateAfter > 0;\n }\n\n /**\n * @notice Returns the migration hash. This function ensures that this hash is safe from replay attack by including\n * public key, verification facet, function selectors, salt, address, chainId, and nonce.\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _saltString Salt value for generating the migration hash\n * @return migrationKeyHash Bytes32 string of the migration key hash\n */\n function getApprovalMigrationKeyHash(\n bytes memory _newPublicKey,\n address _newVerificationFacet,\n bytes4[] memory _newVerificationFuncSelectors,\n string memory _saltString\n ) public view override returns (bytes32 migrationKeyHash) {\n migrationKeyHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n _newPublicKey,\n _newVerificationFacet,\n keccak256(abi.encode(_newVerificationFuncSelectors)),\n _saltString,\n address(this),\n block.chainid,\n LibFacetStorage.migrationStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Checks if the owner approved the hash for migration\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @return isApprovedByOwner Bool value of showing if the owner approved it or not\n */\n function getMigrationOwnerApprovalWithTimeValidity(\n bytes32 _migrationPublicKeyHash\n ) public view override returns (bool isApprovedByOwner) {\n isApprovedByOwner = isMigrationApproved(\n _migrationPublicKeyHash,\n address(this)\n );\n }\n\n /**\n * @notice Checks how many of the guardians approved the migration hash\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @return approvalCount Number of approvals\n */\n function getMigrationApprovalCountWithTimeValidity(\n bytes32 _migrationPublicKeyHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardiansLength = guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n if (isMigrationApproved(_migrationPublicKeyHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n return approvalCount;\n }\n\n /**\n * @notice Checks if the migration is approved by the given approver\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @param _approver Address of approver\n * @return isApproved Bool value if migration hash is approved\n */\n function isMigrationApproved(\n bytes32 _migrationPublicKeyHash,\n address _approver\n ) public view override returns (bool isApproved) {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n isApproved = (ms\n .isMigrationApproved[_migrationPublicKeyHash][_approver].isApproved &&\n block.timestamp <\n ms\n .isMigrationApproved[_migrationPublicKeyHash][_approver]\n .validUntil);\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _migrationPublicKeyHash Hash of migration information\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _migrationPublicKeyHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isMigrationApproved(_migrationPublicKeyHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert SignatureMigrationFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the migration period of this wallet\n * @dev This method fetches the migration period from the security manager\n * @return migrationPeriod Migration period of Barz contract fetched from security manager\n */\n function getMigrationPeriod()\n internal\n view\n returns (uint128 migrationPeriod)\n {\n migrationPeriod = securityManager.migrationPeriodOf(address(this));\n if (migrationPeriod == 0)\n revert SignatureMigrationFacet__InvalidMigrationPeriod();\n }\n\n /**\n * @notice Returns the validation period of this wallet\n * @dev This method fetches the validation period from the security manager\n * @return approvalValidationPeriod Validation period of Barz contract fetched from security manager\n */\n function getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod == 0)\n revert SignatureMigrationFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the migration nonce of this wallet\n * @dev This method fetches the nonce from migration storage\n * @return migrationNonce Nonce of migration to protect from reply attacks\n */\n function getMigrationNonce()\n public\n view\n override\n returns (uint128 migrationNonce)\n {\n migrationNonce = LibFacetStorage.migrationStorage().nonce;\n }\n\n /**\n * @notice Returns the migration configuration of this wallet\n * @dev This method fetches the migration config from the migration storage\n * @return pendingMigrationConfig Migration config currently pending for signature migration\n */\n function getPendingMigration()\n external\n view\n override\n returns (SignatureMigrationConfig memory pendingMigrationConfig)\n {\n pendingMigrationConfig = LibFacetStorage\n .migrationStorage()\n .migrationConfigs[INNER_STRUCT];\n }\n}\n" + }, + "contracts/facets/TokenReceiverFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {IERC1155Receiver} from \"../interfaces/ERC/IERC1155Receiver.sol\";\nimport {IERC677Receiver} from \"../interfaces/ERC/IERC677Receiver.sol\";\n\n/**\n * @title TokenReceiver Facet\n * @dev Contract that enables receiving ERC721/ERC1155/ERC777/ERC677 Tokens with safe transfer\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract TokenReceiverFacet is\n IERC721Receiver,\n IERC1155Receiver,\n IERC777Recipient,\n IERC677Receiver\n{\n /**\n * @notice Handles ERC721 Token callback.\n * return Standardized onERC721Received return value.\n */\n function onERC721Received(\n address,\n address,\n uint256,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC721Receiver.onERC721Received.selector;\n }\n\n /**\n * @notice Handles ERC1155 Token callback.\n * return Standardized onERC1155Received return value.\n */\n function onERC1155Received(\n address,\n address,\n uint256,\n uint256,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC1155Receiver.onERC1155Received.selector;\n }\n\n /**\n * @notice Handles ERC1155 Token batch callback.\n * return Standardized onERC1155BatchReceived return value.\n */\n function onERC1155BatchReceived(\n address,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC1155Receiver.onERC1155BatchReceived.selector;\n }\n\n /**\n * @notice Handles ERC777 Token callback.\n * Does not return value, empty implementation.\n */\n function tokensReceived(\n address,\n address,\n address,\n uint256,\n bytes calldata,\n bytes calldata\n ) external pure override {}\n\n /**\n * @notice Handles ERC677 Token callback.\n * return true.\n */\n function onTokenTransfer(\n address,\n uint256,\n bytes calldata\n ) external pure override returns (bool) {\n return true;\n }\n}\n" + }, + "contracts/facets/verification/MultiSigFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {UserOperation} from \"../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../../libraries/LibLoupe.sol\";\nimport {LibAppStorage} from \"../../libraries/LibAppStorage.sol\";\nimport {LibMultiSigStorage, MultiSigStorage} from \"../../libraries/LibMultiSigStorage.sol\";\nimport {IERC1271} from \"../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../interfaces/IVerificationFacet.sol\";\nimport {IMultiSigFacet} from \"../interfaces/IMultiSigFacet.sol\";\n\n/**\n * @title Multi-sig facet\n * @dev Multi-signature Facet with custom threshold.\n * Wallet that adds this facet becomes a multi-sig wallet.\n * Reference signature_format.md documentation for Multi-sig facet details\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract MultiSigFacet is IMultiSigFacet, IVerificationFacet, IERC1271 {\n using ECDSA for bytes32;\n\n address public immutable self;\n\n address internal constant SENTINEL_OWNERS = address(0x1);\n uint256 internal constant ADDRESS = 20;\n uint256 internal constant SIG_TYPE = 1;\n uint256 internal constant SIG_LEN = 4;\n uint256 internal constant THRESHOLD = 4;\n uint256 internal constant INVALID_SIG = 1;\n uint256 internal constant VALID_SIG = 0;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in Multisig Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the right format and initializes signer storage in k1 storage.\n * @param _owners Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _owners\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n\n if (!isValidKeyType(_owners)) revert MultiSigFacet__InvalidInitData();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n uint256 threshold = uint256(uint32(bytes4(_owners)));\n uint256 ownerCount = (_owners.length - THRESHOLD) / ADDRESS;\n\n if (threshold == 0) revert MultiSigFacet__InvalidThreshold();\n if (ownerCount == 0) revert MultisigFacet__InvalidOwnerCount();\n\n address currentOwner = SENTINEL_OWNERS;\n uint256 ptr = THRESHOLD;\n address owner_;\n for (uint256 i; i < ownerCount; ) {\n owner_ = address(bytes20(_owners[ptr:ptr + ADDRESS]));\n ptr += ADDRESS;\n if (\n owner_ == address(0) ||\n owner_ == SENTINEL_OWNERS ||\n owner_ == address(this) ||\n owner_ == currentOwner\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[owner_] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n\n ms.owners[currentOwner] = owner_;\n currentOwner = owner_;\n\n unchecked {\n ++i;\n }\n }\n ms.owners[currentOwner] = SENTINEL_OWNERS;\n ms.ownerCount = ownerCount;\n ms.threshold = threshold;\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_owners);\n }\n\n /**\n * @notice Uninitialize signer in K1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n ++ms.counter;\n address[] memory ownerlist = getOwners();\n uint256 ownerlistLength = ownerlist.length;\n for (uint256 i; i < ownerlistLength; ) {\n ms.owners[ownerlist[i]] = address(0);\n unchecked {\n ++i;\n }\n }\n ms.owners[SENTINEL_OWNERS] = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls checkSignatures with\n * user operation hash and signature together with the threshold.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n // Data 1 is invalid, Data 0 is valid\n validationData = checkSignatures(\n userOpHash,\n userOp.signature,\n LibMultiSigStorage.multisigStorage().threshold\n );\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n return this.validateOwnerSignature.selector;\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n uint totalLength = ms.ownerCount * ADDRESS;\n bytes memory result = new bytes(totalLength);\n\n // populate return array\n uint256 index;\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n while (currentOwner != SENTINEL_OWNERS) {\n assembly {\n mstore(\n add(result, add(32, mul(index, ADDRESS))),\n shl(96, currentOwner)\n )\n }\n currentOwner = ms.owners[currentOwner];\n index++;\n }\n\n return result;\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key should comply with the format in the signature_format.md doc\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n uint256 publicKeyLength = _publicKey.length;\n if (\n publicKeyLength < ADDRESS + THRESHOLD ||\n (publicKeyLength - THRESHOLD) % ADDRESS != 0\n ) return false;\n\n uint256 threshold = uint256(uint32(bytes4(_publicKey)));\n uint256 ownerCount = (publicKeyLength - THRESHOLD) / ADDRESS;\n\n isValid = !(ownerCount < threshold || threshold == 0);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes calldata _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (checkSignatures(\n _hash,\n _signature,\n LibMultiSigStorage.multisigStorage().threshold\n ) == VALID_SIG)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n\n /**\n * @notice Validates the format of the signature and verifies if the signature is signed by the expected key.\n * Reference signature_format.md doc for details about signature format and signature types\n * @param _dataHash Bytes value of data hash signed by the owners\n * @param _signatures Bytes value of signature which should comply with signature format\n * @param _threshold Uint256 value of current Multi-sig Barz's threshold\n */\n function checkSignatures(\n bytes32 _dataHash,\n bytes calldata _signatures,\n uint256 _threshold\n ) public view returns (uint256) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n address lastOwner = address(0);\n address currentOwner;\n bytes memory signature;\n uint256 signatureType;\n uint256 nextOffset;\n uint256 i;\n for (i; i < _threshold; ) {\n (\n currentOwner,\n signature,\n signatureType,\n nextOffset\n ) = splitSignatures(_signatures, nextOffset);\n if (nextOffset == 0 && i + 1 < _threshold) return INVALID_SIG;\n if (signatureType == 1) {\n // If signatureType is 1 then it is default dataHash signed.\n // This also includes the contract signature\n if (\n !SignatureChecker.isValidSignatureNow(\n currentOwner,\n _dataHash,\n signature\n )\n ) return INVALID_SIG;\n } else if (signatureType == 2) {\n // If signatureType is 2 then it is an approved hash\n if (ms.approvedHashes[ms.counter][currentOwner][_dataHash] == 0)\n return INVALID_SIG;\n } else if (signatureType == 3) {\n // If signatureType is 3 then it is a signed message hash\n // This also includes the contract signature\n bytes32 msgHash = _dataHash.toEthSignedMessageHash();\n if (\n !SignatureChecker.isValidSignatureNow(\n currentOwner,\n msgHash,\n signature\n )\n ) return INVALID_SIG;\n } else revert MultiSigFacet__InvalidRoute();\n if (\n currentOwner <= lastOwner ||\n ms.owners[currentOwner] == address(0) ||\n currentOwner == SENTINEL_OWNERS\n ) return INVALID_SIG;\n lastOwner = currentOwner;\n\n unchecked {\n ++i;\n }\n }\n return VALID_SIG;\n }\n\n /**\n * @notice Split signatures into each individual signatures. Should comply with signature format to be split\n * @param _signatures Bytes value of signature\n * @param _nextOffset Uint256 value of next offset to start splitting the signature\n */\n function splitSignatures(\n bytes calldata _signatures,\n uint256 _nextOffset\n )\n public\n pure\n returns (\n address owner_,\n bytes memory signature,\n uint256 signatureType,\n uint256 nextOffset\n )\n {\n uint256 signaturesLength = _signatures.length;\n\n if (signaturesLength <= _nextOffset + ADDRESS + SIG_LEN)\n revert MultiSigFacet__InsufficientSignerLength();\n\n owner_ = address(\n bytes20(_signatures[_nextOffset:_nextOffset + ADDRESS])\n );\n\n signatureType = uint256(\n uint8(\n bytes1(\n _signatures[_nextOffset + ADDRESS:_nextOffset +\n ADDRESS +\n SIG_TYPE]\n )\n )\n );\n\n if (signatureType > 3 || signatureType == 0)\n revert MultiSigFacet__InvalidSignatureType();\n uint256 offSet = _nextOffset + ADDRESS + SIG_TYPE;\n uint256 siglen = uint256(\n uint32(bytes4(_signatures[offSet:offSet + SIG_LEN]))\n );\n if (offSet + siglen > signaturesLength)\n revert MultiSigFacet__InvalidSignatureLength();\n\n offSet += SIG_LEN;\n if (offSet + siglen == signaturesLength) nextOffset = 0;\n else nextOffset = offSet + siglen;\n\n signature = _signatures[offSet:offSet + siglen];\n }\n\n /**\n * @notice Approves the hash of userOperation on-chain. This can only be called by owners.\n * @param _hashToApprove Bytes value of UserOperation hash to approve\n */\n function approveHash(bytes32 _hashToApprove) external {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (ms.owners[msg.sender] == address(0))\n revert MultiSigFacet__OnlyOwner();\n\n ms.approvedHashes[ms.counter][msg.sender][_hashToApprove] = 1;\n emit HashApproved(_hashToApprove, msg.sender);\n }\n\n /**\n * @notice Add owner to Barz. Update thresold if threshold is given different from current threshold\n * @dev This can only be done via a Self call.\n * @param _newOwner Address of new owner to be added\n * @param _threshold Uint256 value of threshold\n */\n function addOwner(address _newOwner, uint256 _threshold) external {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (\n _newOwner == address(0) ||\n _newOwner == SENTINEL_OWNERS ||\n _newOwner == address(this)\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_newOwner] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n\n ms.owners[_newOwner] = ms.owners[SENTINEL_OWNERS];\n ms.owners[SENTINEL_OWNERS] = _newOwner;\n ++ms.ownerCount;\n emit OwnerAdded(_newOwner);\n\n if (ms.threshold != _threshold) changeThreshold(_threshold);\n }\n\n /**\n * @notice Remove owner from Barz. Update thresold if threshold is given different from current threshold\n * @dev This can only be done via a Self call.\n * @param _prevOwner Address of owner located right behind the removed owner address in the linked list\n * @param _removedOwner Address of owner to be removed\n * @param _threshold Uint256 value of threshold\n */\n function removeOwner(\n address _prevOwner,\n address _removedOwner,\n uint256 _threshold\n ) external {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (ms.ownerCount - 1 < _threshold)\n revert MultiSigFacet__InvalidThreshold();\n if (_removedOwner == address(0) || _removedOwner == SENTINEL_OWNERS)\n revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_prevOwner] != _removedOwner)\n revert MultiSigFacet__InvalidOwnerPair();\n\n ms.owners[_prevOwner] = ms.owners[_removedOwner];\n ms.owners[_removedOwner] = address(0);\n --ms.ownerCount;\n emit OwnerRemoved(_removedOwner);\n\n if (ms.threshold != _threshold) changeThreshold(_threshold);\n }\n\n /**\n * @notice Swap owner in Barz.\n * @dev This can only be done via a Self call.\n * @param _prevOwner Address of owner located right behind the removed owner address in the linked list\n * @param _oldOwner Address of owner to be removed\n * @param _newOwner Address of owner to be added\n */\n function swapOwner(\n address _prevOwner,\n address _oldOwner,\n address _newOwner\n ) public {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (\n _newOwner == address(0) ||\n _newOwner == SENTINEL_OWNERS ||\n _newOwner == address(this)\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_newOwner] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n if (_oldOwner == address(0) || _oldOwner == SENTINEL_OWNERS)\n revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_prevOwner] != _oldOwner)\n revert MultiSigFacet__InvalidOwnerPair();\n\n ms.owners[_newOwner] = ms.owners[_oldOwner];\n ms.owners[_prevOwner] = _newOwner;\n ms.owners[_oldOwner] = address(0);\n emit OwnerRemoved(_oldOwner);\n emit OwnerAdded(_newOwner);\n }\n\n /**\n * @notice Changes the threshold of the Barz to `_threshold`.\n * @dev This can only be done via a Self call.\n * @param _threshold New threshold\n */\n function changeThreshold(uint256 _threshold) public {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (_threshold > ms.ownerCount || _threshold == 0)\n revert MultiSigFacet__InvalidThreshold();\n\n ms.threshold = _threshold;\n emit ThresholdChanged(_threshold);\n }\n\n /**\n * @notice Checks if the given address is owner\n * @param _owner Address to be checked if it's owner\n * @return isOwner_ Bool value showing if it's owner address\n */\n function isOwner(address _owner) public view returns (bool isOwner_) {\n isOwner_ = (_owner != SENTINEL_OWNERS &&\n LibMultiSigStorage.multisigStorage().owners[_owner] != address(0));\n }\n\n /**\n * @notice Returns the threshold of Barz\n * @return threshold Threshold of the Barz account\n */\n function getThreshold() public view returns (uint256 threshold) {\n threshold = LibMultiSigStorage.multisigStorage().threshold;\n }\n\n /**\n * @notice Returns the list of owner addresses\n * @return owners List of owners\n */\n function getOwners() public view returns (address[] memory owners) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n owners = new address[](ms.ownerCount);\n\n uint256 index;\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n while (currentOwner != SENTINEL_OWNERS) {\n owners[index] = currentOwner;\n currentOwner = ms.owners[currentOwner];\n index++;\n }\n }\n\n /**\n * @notice Returns the previous owner in the linked list\n * @param _owner Address of owner\n * @return prevOwner Address of previous owner\n */\n function getPrevOwner(\n address _owner\n ) public view returns (address prevOwner) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n if (currentOwner == _owner) return SENTINEL_OWNERS;\n while (currentOwner != SENTINEL_OWNERS) {\n if (ms.owners[currentOwner] == _owner) return currentOwner;\n\n currentOwner = ms.owners[currentOwner];\n }\n return address(0);\n }\n\n /**\n * @notice Returns of the owner is approved by given owner address\n * @param _owner Address of owner\n * @param _hash Hash of UserOperation\n * @return isApproved Bool value showing if the hash is approved by owner\n */\n function isApprovedHash(\n address _owner,\n bytes32 _hash\n ) public view returns (bool isApproved) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n isApproved = (ms.approvedHashes[ms.counter][_owner][_hash] == 1);\n }\n}\n" + }, + "contracts/facets/verification/secp256k1/Secp256k1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {UserOperation} from \"../../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibAppStorage} from \"../../../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, Secp256k1VerificationStorage} from \"../../../libraries/LibFacetStorage.sol\";\nimport {LibLoupe} from \"../../../libraries/LibLoupe.sol\";\nimport {IERC1271} from \"../../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../../interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Secp256k1 verification facet\n * @dev Default Ethereum's elliptic curve\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract Secp256k1VerificationFacet is IVerificationFacet, IERC1271 {\n using ECDSA for bytes32;\n error Secp256k1VerificationFacet__InvalidSignerLength();\n address public immutable self;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in K1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\n * @param _publicKey Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _publicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n if (!isValidKeyType(_publicKey))\n revert Secp256k1VerificationFacet__InvalidSignerLength();\n\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(uint160(uint256(keccak256(_publicKey[1:]))));\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_publicKey);\n }\n\n /**\n * @notice Uninitialize signer in K1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\n * signer public key.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n validationData = validateSignature(\n userOp,\n userOpHash,\n k1Storage.signer\n );\n }\n\n /**\n * @notice Validates if the signature of UserOperation is signed by the given signer\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @param signer Address of signer who signed the contract, to be validated\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n address signer\n ) public pure returns (uint256 isValid) {\n bytes32 hash = userOpHash.toEthSignedMessageHash();\n isValid = (signer != hash.recover(userOp.signature)) ? 1 : 0;\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n ownerSignatureValidatorSelector = this.validateOwnerSignature.selector;\n // NOTE: The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory signer) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n signer = abi.encodePacked(k1Storage.signer);\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key length should be 65 in an uncompressed public key format\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (_hash.recover(_signature) ==\n LibFacetStorage.k1Storage().signer)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/Secp256r1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {UserOperation} from \"../../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibAppStorage} from \"../../../libraries/LibAppStorage.sol\";\nimport {LibLoupe} from \"../../../libraries/LibLoupe.sol\";\nimport {LibFacetStorage, Secp256r1VerificationStorage} from \"../../../libraries/LibFacetStorage.sol\";\nimport {Base64} from \"./utils/Base64.sol\";\nimport {LibSecp256r1} from \"./utils/LibSecp256r1.sol\";\nimport {IERC1271} from \"../../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../../interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Secp256r1 verification facet\n * @dev Primarily used to verify user ops signed with passkeys\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract Secp256r1VerificationFacet is IVerificationFacet, IERC1271 {\n error Secp256r1VerificationFacet__InvalidSignerLength();\n address public immutable self;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in R1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\n * @param _publicKey Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _publicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n\n if (!isValidKeyType(_publicKey))\n revert Secp256r1VerificationFacet__InvalidSignerLength();\n\n bytes memory publicKeyCoordinates = _publicKey[1:];\n uint256[2] memory q;\n assembly {\n // Copy the bytes from the input data into the uint256 array\n mstore(q, mload(add(publicKeyCoordinates, 32)))\n mstore(add(q, 32), mload(add(publicKeyCoordinates, 64)))\n }\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n r1Storage.q = q;\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_publicKey);\n }\n\n /**\n * @notice Uninitialize signer in R1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n r1Storage.q = [0, 0];\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\n * signer public key.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n validationData = validateSignature(userOp, userOpHash, r1Storage.q);\n }\n\n /**\n * @notice Validates if the signature of UserOperation is signed by the given signer\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @param q Public Key of signer who signed the contract, to be validated\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256[2] memory q\n ) public view returns (uint256 isValid) {\n isValid = (_validateSignature(q, userOpHash, userOp.signature)) ? 0 : 1;\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n return this.validateOwnerSignature.selector; // validateOwnerSignature(UserOperation calldata userOp,bytes32 userOpHash)\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory signer) {\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n signer = abi.encodePacked(r1Storage.q);\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key should in an uncompressed public key format\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = _validateSignature(\n LibFacetStorage.r1Storage().q,\n _hash,\n _signature\n )\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n\n function _validateSignature(\n uint256[2] memory q,\n bytes32 _hash,\n bytes memory _signature\n ) internal view returns (bool) {\n (\n uint256 rValue,\n uint256 sValue,\n bytes memory authenticatorData,\n string memory clientDataJSONPre,\n string memory clientDataJSONPost\n ) = abi.decode(_signature, (uint256, uint256, bytes, string, string));\n bytes32 clientHash;\n {\n string memory opHashBase64 = Base64.encode(bytes.concat(_hash));\n string memory clientDataJSON = string.concat(\n clientDataJSONPre,\n opHashBase64,\n clientDataJSONPost\n );\n clientHash = sha256(bytes(clientDataJSON));\n }\n bytes32 sigHash = sha256(bytes.concat(authenticatorData, clientHash));\n return LibSecp256r1.Verify(q, rValue, sValue, uint256(sigHash));\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/utils/Base64.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @dev Provides a set of functions to operate with Base64 strings.\n * modified for base64url https://datatracker.ietf.org/doc/html/rfc4648#section-5\n * _Available since v4.5._\n */\nlibrary Base64 {\n /**\n * @dev Base64 Encoding/Decoding Table\n */\n string internal constant _TABLE =\n \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_\";\n\n /**\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\n */\n function encode(bytes memory data) internal pure returns (string memory) {\n /**\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\n */\n if (data.length == 0) return \"\";\n\n // Loads the table into memory\n string memory table = _TABLE;\n\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\n // and split into 4 numbers of 6 bits.\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\n // - `data.length + 2` -> Round up\n // - `/ 3` -> Number of 3-bytes chunks\n // - `4 *` -> 4 characters for each chunk\n uint256 newlength = (data.length * 8) / 6;\n if (data.length % 6 > 0) {\n newlength++;\n }\n string memory result = new string(newlength);\n\n /// @solidity memory-safe-assembly\n assembly {\n // Prepare the lookup table (skip the first \"length\" byte)\n let tablePtr := add(table, 1)\n\n // Prepare result pointer, jump over length\n let resultPtr := add(result, 32)\n\n // Run over the input, 3 bytes at a time\n for {\n let dataPtr := data\n let endPtr := add(data, mload(data))\n } lt(dataPtr, endPtr) {\n\n } {\n // Advance 3 bytes\n dataPtr := add(dataPtr, 3)\n let input := mload(dataPtr)\n\n // To write each character, shift the 3 bytes (18 bits) chunk\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\n // and apply logical AND with 0x3F which is the number of\n // the previous character in the ASCII table prior to the Base64 Table\n // The result is then added to the table to get the character to write,\n // and finally write it in the result pointer but with a left shift\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(18, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(12, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(6, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n }\n }\n\n return result;\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/utils/LibSecp256r1.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n// Heavily inspired from\n// https://github.com/maxrobot/elliptic-solidity/blob/master/contracts/Secp256r1.sol\n// https://github.com/tdrerup/elliptic-curve-solidity/blob/master/contracts/curves/EllipticCurve.sol\n// modified to use precompile 0x05 modexp\n// and modified jacobian double\n// optimisations to avoid to an from from affine and jacobian coordinates\n\n// Additional Elliptic curve Public key / Signature validation added by\n// David Yonjun Kim (@Powerstream3604)\n\nstruct JPoint {\n uint256 x;\n uint256 y;\n uint256 z;\n}\n\nlibrary LibSecp256r1 {\n uint256 constant gx =\n 0x6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296;\n uint256 constant gy =\n 0x4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5;\n uint256 public constant pp =\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF;\n\n uint256 public constant nn =\n 0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551;\n uint256 constant a =\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC;\n uint256 constant b =\n 0x5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B;\n uint256 constant MOST_SIGNIFICANT =\n 0xc000000000000000000000000000000000000000000000000000000000000000;\n\n /*\n * Verify\n * @description - verifies that a public key has signed a given message\n * @param Q - public key coordinates X & Y\n * @param R - signature half R\n * @param S - signature half S\n * @param input - hashed message\n */\n function Verify(\n uint256[2] memory q,\n uint r,\n uint s,\n uint e\n ) internal view returns (bool) {\n if (q[0] > pp - 1 || q[1] > pp - 1) {\n return false;\n }\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\n return false;\n }\n if (\n mulmod(q[1], q[1], pp) !=\n addmod(\n addmod(\n mulmod(q[0], mulmod(q[0], q[0], pp), pp),\n mulmod(a, q[0], pp),\n pp\n ),\n b,\n pp\n )\n ) {\n return false;\n }\n\n JPoint[16] memory points = _preComputeJacobianPoints(q);\n return VerifyWithPrecompute(points, r, s, e);\n }\n\n function VerifyWithPrecompute(\n JPoint[16] memory points,\n uint r,\n uint s,\n uint e\n ) internal view returns (bool) {\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\n return false;\n }\n\n uint w = _primemod(s, nn);\n\n uint u1 = mulmod(e, w, nn);\n uint u2 = mulmod(r, w, nn);\n\n uint x;\n uint y;\n\n (x, y) = ShamirMultJacobian(points, u1, u2);\n return (x == r);\n }\n\n /*\n * Strauss Shamir trick for EC multiplication\n * https://stackoverflow.com/questions/50993471/ec-scalar-multiplication-with-strauss-shamir-method\n * we optimise on this a bit to do with 2 bits at a time rather than a single bit\n * the individual points for a single pass are precomputed\n * overall this reduces the number of additions while keeping the same number of doublings\n */\n function ShamirMultJacobian(\n JPoint[16] memory points,\n uint u1,\n uint u2\n ) internal view returns (uint, uint) {\n uint x = 0;\n uint y = 0;\n uint z = 0;\n uint bits = 128;\n uint index = 0;\n\n while (bits > 0) {\n if (z > 0) {\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\n }\n index =\n ((u1 & MOST_SIGNIFICANT) >> 252) |\n ((u2 & MOST_SIGNIFICANT) >> 254);\n if (index > 0) {\n (x, y, z) = _jAdd(\n x,\n y,\n z,\n points[index].x,\n points[index].y,\n points[index].z\n );\n }\n u1 <<= 2;\n u2 <<= 2;\n bits--;\n }\n (x, y) = _affineFromJacobian(x, y, z);\n return (x, y);\n }\n\n function _preComputeJacobianPoints(\n uint256[2] memory q\n ) internal pure returns (JPoint[16] memory points) {\n points[0] = JPoint(0, 0, 0);\n points[1] = JPoint(q[0], q[1], 1); // u2\n points[2] = _jPointDouble(points[1]);\n points[3] = _jPointAdd(points[1], points[2]);\n\n points[4] = JPoint(gx, gy, 1); // u1Points[1]\n points[5] = _jPointAdd(points[4], points[1]);\n points[6] = _jPointAdd(points[4], points[2]);\n points[7] = _jPointAdd(points[4], points[3]);\n\n points[8] = _jPointDouble(points[4]); // u1Points[2]\n points[9] = _jPointAdd(points[8], points[1]);\n points[10] = _jPointAdd(points[8], points[2]);\n points[11] = _jPointAdd(points[8], points[3]);\n\n points[12] = _jPointAdd(points[4], points[8]); // u1Points[3]\n points[13] = _jPointAdd(points[12], points[1]);\n points[14] = _jPointAdd(points[12], points[2]);\n points[15] = _jPointAdd(points[12], points[3]);\n }\n\n function _jPointAdd(\n JPoint memory p1,\n JPoint memory p2\n ) internal pure returns (JPoint memory) {\n uint x;\n uint y;\n uint z;\n (x, y, z) = _jAdd(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z);\n return JPoint(x, y, z);\n }\n\n function _jPointDouble(\n JPoint memory p\n ) internal pure returns (JPoint memory) {\n uint x;\n uint y;\n uint z;\n (x, y, z) = _modifiedJacobianDouble(p.x, p.y, p.z);\n return JPoint(x, y, z);\n }\n\n /* _affineFromJacobian\n * @desription returns affine coordinates from a jacobian input follows\n * golang elliptic/crypto library\n */\n function _affineFromJacobian(\n uint x,\n uint y,\n uint z\n ) internal view returns (uint ax, uint ay) {\n if (z == 0) {\n return (0, 0);\n }\n\n uint zinv = _primemod(z, pp);\n uint zinvsq = mulmod(zinv, zinv, pp);\n\n ax = mulmod(x, zinvsq, pp);\n ay = mulmod(y, mulmod(zinvsq, zinv, pp), pp);\n }\n\n /*\n * _jAdd\n * @description performs Jacobian addition as defined below:\n * http://www.hyperelliptic.org/EFD/g1p/data/shortw/jacobian/addition/add-2007-bl\n */\n function _jAdd(\n uint p1,\n uint p2,\n uint p3,\n uint q1,\n uint q2,\n uint q3\n ) internal pure returns (uint r1, uint r2, uint r3) {\n if (p3 == 0) {\n r1 = q1;\n r2 = q2;\n r3 = q3;\n\n return (r1, r2, r3);\n } else if (q3 == 0) {\n r1 = p1;\n r2 = p2;\n r3 = p3;\n\n return (r1, r2, r3);\n }\n\n assembly {\n let\n pd\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\n let z1z1 := mulmod(p3, p3, pd) // Z1Z1 = Z1^2\n let z2z2 := mulmod(q3, q3, pd) // Z2Z2 = Z2^2\n\n let u1 := mulmod(p1, z2z2, pd) // U1 = X1*Z2Z2\n let u2 := mulmod(q1, z1z1, pd) // U2 = X2*Z1Z1\n\n let s1 := mulmod(p2, mulmod(z2z2, q3, pd), pd) // S1 = Y1*Z2*Z2Z2\n let s2 := mulmod(q2, mulmod(z1z1, p3, pd), pd) // S2 = Y2*Z1*Z1Z1\n\n let p3q3 := addmod(p3, q3, pd)\n\n if lt(u2, u1) {\n u2 := add(pd, u2) // u2 = u2+pd\n }\n let h := sub(u2, u1) // H = U2-U1\n\n let i := mulmod(0x02, h, pd)\n i := mulmod(i, i, pd) // I = (2*H)^2\n\n let j := mulmod(h, i, pd) // J = H*I\n if lt(s2, s1) {\n s2 := add(pd, s2) // u2 = u2+pd\n }\n let rr := mulmod(0x02, sub(s2, s1), pd) // r = 2*(S2-S1)\n r1 := mulmod(rr, rr, pd) // X3 = R^2\n\n let v := mulmod(u1, i, pd) // V = U1*I\n let j2v := addmod(j, mulmod(0x02, v, pd), pd)\n if lt(r1, j2v) {\n r1 := add(pd, r1) // X3 = X3+pd\n }\n r1 := sub(r1, j2v)\n\n // Y3 = r*(V-X3)-2*S1*J\n let s12j := mulmod(mulmod(0x02, s1, pd), j, pd)\n\n if lt(v, r1) {\n v := add(pd, v)\n }\n r2 := mulmod(rr, sub(v, r1), pd)\n\n if lt(r2, s12j) {\n r2 := add(pd, r2)\n }\n r2 := sub(r2, s12j)\n\n // Z3 = ((Z1+Z2)^2-Z1Z1-Z2Z2)*H\n z1z1 := addmod(z1z1, z2z2, pd)\n j2v := mulmod(p3q3, p3q3, pd)\n if lt(j2v, z1z1) {\n j2v := add(pd, j2v)\n }\n r3 := mulmod(sub(j2v, z1z1), h, pd)\n }\n return (r1, r2, r3);\n }\n\n // Point doubling on the modified jacobian coordinates\n // http://point-at-infinity.org/ecc/Prime_Curve_Modified_Jacobian_Coordinates.html\n function _modifiedJacobianDouble(\n uint x,\n uint y,\n uint z\n ) internal pure returns (uint x3, uint y3, uint z3) {\n if (y == 0) return (0, 0, 0);\n assembly {\n let\n pd\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\n let z2 := mulmod(z, z, pd)\n let az4 := mulmod(\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC,\n mulmod(z2, z2, pd),\n pd\n )\n let y2 := mulmod(y, y, pd)\n let s := mulmod(0x04, mulmod(x, y2, pd), pd)\n let u := mulmod(0x08, mulmod(y2, y2, pd), pd)\n let m := addmod(mulmod(0x03, mulmod(x, x, pd), pd), az4, pd)\n let twos := mulmod(0x02, s, pd)\n let m2 := mulmod(m, m, pd)\n if lt(m2, twos) {\n m2 := add(pd, m2)\n }\n x3 := sub(m2, twos)\n if lt(s, x3) {\n s := add(pd, s)\n }\n y3 := mulmod(m, sub(s, x3), pd)\n if lt(y3, u) {\n y3 := add(pd, y3)\n }\n y3 := sub(y3, u)\n z3 := mulmod(0x02, mulmod(y, z, pd), pd)\n }\n }\n\n // Fermats little theorem https://en.wikipedia.org/wiki/Fermat%27s_little_theorem\n // a^(p-1) = 1 mod p\n // a^(-1) ≅ a^(p-2) (mod p)\n // we then use the precompile bigModExp to compute a^(-1)\n function _primemod(uint value, uint p) internal view returns (uint ret) {\n ret = modexp(value, p - 2, p);\n return ret;\n }\n\n // Wrapper for built-in BigNumber_modexp (contract 0x5) as described here. https://github.com/ethereum/EIPs/pull/198\n function modexp(\n uint _base,\n uint _exp,\n uint _mod\n ) internal view returns (uint ret) {\n // bigModExp(_base, _exp, _mod);\n assembly {\n if gt(_base, _mod) {\n _base := mod(_base, _mod)\n }\n // Free memory pointer is always stored at 0x40\n let freemem := mload(0x40)\n\n mstore(freemem, 0x20)\n mstore(add(freemem, 0x20), 0x20)\n mstore(add(freemem, 0x40), 0x20)\n\n mstore(add(freemem, 0x60), _base)\n mstore(add(freemem, 0x80), _exp)\n mstore(add(freemem, 0xa0), _mod)\n\n let success := staticcall(14000, 0x5, freemem, 0xc0, freemem, 0x20)\n switch success\n case 0 {\n revert(0x0, 0x0)\n }\n default {\n ret := mload(freemem)\n }\n }\n }\n}\n" + }, + "contracts/infrastructure/DefaultFallbackHandler.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC1155Receiver} from \"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\";\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {BaseAccount} from \"../aa-4337/core/BaseAccount.sol\";\nimport {DefaultLibDiamond} from \"../libraries/DefaultLibDiamond.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IAccountFacet} from \"../facets/interfaces/IAccountFacet.sol\";\nimport {IStorageLoupe} from \"../facets/base/interfaces/IStorageLoupe.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IERC677Receiver} from \"../interfaces/ERC/IERC677Receiver.sol\";\nimport {IERC165} from \"../interfaces/ERC/IERC165.sol\";\n\n/**\n * @title DefaultFallbackHandler\n * @dev A default fallback handler for Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DefaultFallbackHandler is IDiamondLoupe {\n /**\n * @notice Sets the middleware diamond for Barz wallet as a fallback handler\n * @dev This contract is also a diamond that holds the default facets to reduce gas cost for wallet activation.\n * Within the constructor this conducts diamond cut to initially setup the diamond. This is a non-upgradeable contract\n * @param _diamondCutFacet Address if diamond cut facet\n * @param _accountFacet Address account facet\n * @param _tokenReceiverFacet Address of token receiver facet\n * @param _diamondLoupeFacet Address of diamond loupe facet\n */\n constructor(\n address _diamondCutFacet,\n address _accountFacet,\n address _tokenReceiverFacet,\n address _diamondLoupeFacet\n ) payable {\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](4);\n bytes4[] memory functionSelectors = new bytes4[](1);\n functionSelectors[0] = IDiamondCut.diamondCut.selector;\n\n bytes4[] memory accountFunctionSelectors = new bytes4[](5);\n accountFunctionSelectors[0] = IAccountFacet.execute.selector;\n accountFunctionSelectors[1] = IAccountFacet.executeBatch.selector;\n accountFunctionSelectors[2] = BaseAccount.validateUserOp.selector;\n accountFunctionSelectors[3] = BaseAccount.getNonce.selector;\n accountFunctionSelectors[4] = BaseAccount.entryPoint.selector;\n\n bytes4[] memory receiverFacetSelectors = new bytes4[](5);\n receiverFacetSelectors[0] = IERC721Receiver.onERC721Received.selector;\n receiverFacetSelectors[1] = IERC1155Receiver.onERC1155Received.selector;\n receiverFacetSelectors[2] = IERC1155Receiver\n .onERC1155BatchReceived\n .selector;\n receiverFacetSelectors[3] = IERC777Recipient.tokensReceived.selector;\n receiverFacetSelectors[4] = IERC677Receiver.onTokenTransfer.selector;\n\n bytes4[] memory loupeFacetSelectors = new bytes4[](9);\n loupeFacetSelectors[0] = IDiamondLoupe.facets.selector;\n loupeFacetSelectors[1] = IDiamondLoupe.facetFunctionSelectors.selector;\n loupeFacetSelectors[2] = IDiamondLoupe.facetAddresses.selector;\n loupeFacetSelectors[3] = IDiamondLoupe.facetAddress.selector;\n loupeFacetSelectors[4] = IERC165.supportsInterface.selector;\n loupeFacetSelectors[5] = IStorageLoupe.facetsFromStorage.selector;\n loupeFacetSelectors[6] = IStorageLoupe\n .facetFunctionSelectorsFromStorage\n .selector;\n loupeFacetSelectors[7] = IStorageLoupe\n .facetAddressesFromStorage\n .selector;\n loupeFacetSelectors[8] = IStorageLoupe.facetAddressFromStorage.selector;\n\n {\n cut[0] = IDiamondCut.FacetCut({\n facetAddress: _diamondCutFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: functionSelectors\n });\n cut[1] = IDiamondCut.FacetCut({\n facetAddress: _accountFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: accountFunctionSelectors\n });\n cut[2] = IDiamondCut.FacetCut({\n facetAddress: _tokenReceiverFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: receiverFacetSelectors\n });\n cut[3] = IDiamondCut.FacetCut({\n facetAddress: _diamondLoupeFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: loupeFacetSelectors\n });\n\n DefaultLibDiamond.diamondCut(cut, address(0), \"\");\n }\n }\n\n /**\n * @notice Returns the facet information of call facets registered to this diamond.\n * @return facets_ The facet struct array including all facet information\n */\n function facets() external view override returns (Facet[] memory facets_) {\n DefaultLibDiamond.DiamondStorage storage ds = DefaultLibDiamond\n .diamondStorage();\n uint256 numFacets = ds.facetAddresses.length;\n facets_ = new Facet[](numFacets);\n for (uint256 i; i < numFacets; ) {\n address facetAddress_ = ds.facetAddresses[i];\n facets_[i].facetAddress = facetAddress_;\n facets_[i].functionSelectors = ds\n .facetFunctionSelectors[facetAddress_]\n .functionSelectors;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Gets all the function selectors provided by a facet.\n * @param _facet The facet address.\n * @return facetFunctionSelectors_\n */\n function facetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n facetFunctionSelectors_ = DefaultLibDiamond\n .diamondStorage()\n .facetFunctionSelectors[_facet]\n .functionSelectors;\n }\n\n /**\n * @notice Get all the facet addresses used by a diamond.\n * @return facetAddresses_\n */\n function facetAddresses()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n facetAddresses_ = DefaultLibDiamond.diamondStorage().facetAddresses;\n }\n\n /** @notice Gets the facet that supports the given selector.\n * @dev If facet is not found return address(0).\n * @param _functionSelector The function selector.\n * @return facetAddress_ The facet address.\n */\n function facetAddress(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n facetAddress_ = DefaultLibDiamond\n .diamondStorage()\n .selectorToFacetAndPosition[_functionSelector]\n .facetAddress;\n }\n}\n" + }, + "contracts/infrastructure/FacetRegistry.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport {IFacetRegistry} from \"./interfaces/IFacetRegistry.sol\";\n\n/**\n * @title Facet Registry\n * @dev Contract to keep track of facets & function selectors addable to user wallets\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract FacetRegistry is IFacetRegistry, Ownable2Step {\n mapping(address => FacetRegistryConfig) private facets;\n\n /**\n * @notice Transfers the ownership of the contract to the given owner\n * @param _owner Address of owner who has access to initialize the default security variables for security manager\n */\n constructor(address _owner) {\n transferOwnership(_owner);\n _transferOwnership(_owner);\n }\n\n /**\n * @dev Registers a facet and it's function selectors to registry\n * @param _facet address of facet\n * @param _facetSelectors list of function selectors of the facet\n */\n function registerFacetFunctionSelectors(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external override onlyOwner {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n for (uint256 i; i < _facetSelectors.length; ) {\n if (facetConfig.info[_facetSelectors[i]].exists)\n revert FacetRegistry__FacetSelectorAlreadyRegistered();\n\n facetConfig.info[_facetSelectors[i]].exists = true;\n facetConfig.info[_facetSelectors[i]].index = uint128(\n facetConfig.selectors.length\n );\n facetConfig.selectors.push(_facetSelectors[i]);\n unchecked {\n ++i;\n }\n }\n emit FacetFunctionSelectorsRegistered(_facet, _facetSelectors);\n }\n\n /**\n * @dev Removes a registered facet and it's corresponding selectors from registry\n * @param _facet address of facet\n * @param _facetSelectors list of function selectors of the facet\n */\n function removeFacetFunctionSelectors(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external override onlyOwner {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n for (uint256 i; i < _facetSelectors.length; ) {\n if (!facetConfig.info[_facetSelectors[i]].exists)\n revert FacetRegistry__UnregisteredFacetSelector();\n\n bytes4 lastSelector = facetConfig.selectors[\n facetConfig.selectors.length - 1\n ];\n if (_facetSelectors[i] != lastSelector) {\n uint128 targetIndex = facetConfig\n .info[_facetSelectors[i]]\n .index;\n facetConfig.selectors[targetIndex] = lastSelector;\n facetConfig.info[lastSelector].index = targetIndex;\n }\n facetConfig.selectors.pop();\n delete facetConfig.info[_facetSelectors[i]];\n\n unchecked {\n ++i;\n }\n }\n emit FacetFunctionSelectorsRemoved(_facet, _facetSelectors);\n }\n\n /**\n * @dev Checks if a facet and it's selectors given is registered to facet registry\n * @param _facet Address of facet\n * @param _facetSelectors List of function selectors of the facet\n */\n function areFacetFunctionSelectorsRegistered(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external view override returns (bool) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n if (_facetSelectors.length == 0) return false;\n for (uint256 i; i < _facetSelectors.length; ) {\n if (!facetConfig.info[_facetSelectors[i]].exists) return false;\n unchecked {\n ++i;\n }\n }\n return true;\n }\n\n /**\n * @dev Checks if a facet and it's selector given is registered to facet registry\n * @param _facet Address of facet\n * @param _facetSelector List of function selectors of the facet\n * @return isRegistered Bool value showing if the selector is registered\n */\n function isFacetFunctionSelectorRegistered(\n address _facet,\n bytes4 _facetSelector\n ) external view override returns (bool isRegistered) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n isRegistered = facetConfig.info[_facetSelector].exists;\n }\n\n /**\n * @dev Get the registered selectors of facet from registry\n * @param _facet Address of facet\n * @return selectors Selectors registered to facet\n */\n function getFacetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory selectors) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n selectors = facetConfig.selectors;\n }\n}\n" + }, + "contracts/infrastructure/interfaces/IFacetRegistry.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Registry Interface\n * @dev Interface for Facet Registry contract to keep track of facets & function selectors addable to user wallets\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IFacetRegistry {\n struct FacetRegistryConfig {\n bytes4[] selectors;\n mapping(bytes4 => FacetInfo) info;\n }\n struct FacetInfo {\n bool exists;\n uint128 index;\n }\n\n event FacetFunctionSelectorsRegistered(\n address facet,\n bytes4[] facetSelectors\n );\n event FacetFunctionSelectorsRemoved(address facet, bytes4[] facetSelectors);\n\n error FacetRegistry__FacetSelectorAlreadyRegistered();\n error FacetRegistry__UnregisteredFacetSelector();\n\n function registerFacetFunctionSelectors(\n address facet,\n bytes4[] calldata facetSelectors\n ) external;\n\n function removeFacetFunctionSelectors(\n address facet,\n bytes4[] calldata facetSelectors\n ) external;\n\n function areFacetFunctionSelectorsRegistered(\n address facet,\n bytes4[] calldata facetSelectors\n ) external view returns (bool);\n\n function isFacetFunctionSelectorRegistered(\n address facet,\n bytes4 facetSelector\n ) external view returns (bool);\n\n function getFacetFunctionSelectors(\n address facet\n ) external view returns (bytes4[] memory);\n}\n" + }, + "contracts/infrastructure/interfaces/ISecurityManager.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Registry Interface\n * @dev Infrastructure contract to manage security parameters of users\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface ISecurityManager {\n error SecurityManager__OutOfBoundary();\n error SecurityManager__CallerNotWallet();\n error SecurityManager__AlreadyIntialized();\n\n function initializeAdditionSecurityPeriod(\n uint128 defaultAdditionSecurityPeriod,\n uint128 minAdditionSecurityPeriod,\n uint128 maxAdditionSecurityPeriod\n ) external;\n\n function initializeRemovalSecurityPeriod(\n uint128 defaultRemovalSecurityPeriod,\n uint128 minRemovalSecurityPeriod,\n uint128 maxRemovalSecurityPeriod\n ) external;\n\n function initializeApprovalValidationPeriod(\n uint128 defaultApprovalValidationPeriod,\n uint128 minApprovalValidationPeriod,\n uint128 maxApprovalValidationPeriod\n ) external;\n\n function initializeMigrationPeriod(\n uint128 defaultMigrationPeriod,\n uint128 minMigrationPeriod,\n uint128 maxMigrationPeriod\n ) external;\n\n function initializeLockPeriod(\n uint128 defaultLockPeriod,\n uint128 minLockPeriod,\n uint128 maxLockPeriod\n ) external;\n\n function initializeRecoveryPeriod(\n uint128 defaultRecoveryPeriod,\n uint128 minRecoveryPeriod,\n uint128 maxRecoveryPeriod\n ) external;\n\n function initializeSecurityWindow(\n uint128 defaultSecurityWindow,\n uint128 minSecurityWindow,\n uint128 maxSecurityWindow\n ) external;\n\n function setAdditionSecurityPeriod(\n address wallet,\n uint128 additionSecurityPeriod\n ) external;\n\n function setRemovalSecurityPeriod(\n address wallet,\n uint128 removalSecurityPeriod\n ) external;\n\n function setSecurityWindow(address wallet, uint128 securityWindow) external;\n\n function setRecoveryPeriod(address wallet, uint128 recoveryPeriod) external;\n\n function setLockPeriod(address wallet, uint128 lockPeriod) external;\n\n function setApprovalValidationPeriod(\n address wallet,\n uint128 approvalValidationPeriod\n ) external;\n\n function setMigrationPeriod(\n address wallet,\n uint128 migrationPeriod\n ) external;\n\n function additionSecurityPeriodOf(\n address wallet\n ) external view returns (uint128);\n\n function removalSecurityPeriodOf(\n address wallet\n ) external view returns (uint128);\n\n function securityWindowOf(address wallet) external view returns (uint128);\n\n function recoveryPeriodOf(address wallet) external view returns (uint128);\n\n function lockPeriodOf(address wallet) external view returns (uint128);\n\n function migrationPeriodOf(address wallet) external view returns (uint128);\n\n function approvalValidationPeriodOf(\n address wallet\n ) external view returns (uint128);\n}\n" + }, + "contracts/infrastructure/RemoteStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IGuardianFacet} from \"../facets/interfaces/IGuardianFacet.sol\";\n\n/**\n * @title Remote Storage\n * @dev Remote storage allows you to associate addresses with an array of addresses on a standalone smart contract.\n * This could be useful when you don't want to use the local diamond storage for some purpose.\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\nabstract contract RemoteStorage {\n struct StorageConfig {\n address[] addresses;\n mapping(address => Info) info;\n }\n\n struct Info {\n bool exists;\n uint128 index;\n }\n\n mapping(address => StorageConfig) internal configs;\n\n event Added(address _address);\n event Removed(address _address);\n\n error RemoteStorage__CallerNotOwner();\n error RemoteStorage__CallerNotGuardianOrOwner();\n error RemoteStorage__AlreadyExists();\n error RemoteStorage__NotFound();\n error RemoteStorage__CallerNotGuardian();\n\n bytes4 constant IS_GUARDIAN_SELECTOR =\n bytes4(keccak256(\"isGuardian(address)\"));\n bytes4 constant GUARDIAN_COUNT = bytes4(keccak256(\"guardianCount()\"));\n\n /**\n * @notice Modifier to only allow the self to call. Reverts otherwise\n */\n modifier onlyWallet(address _wallet) {\n if (msg.sender != _wallet) revert RemoteStorage__CallerNotOwner();\n _;\n }\n\n /**\n * @notice Enfore the callet to be wallet of guardian of the wallet\n * @param _wallet Address of wallet\n */\n function enforceGuardianOrWallet(address _wallet) internal view {\n if (msg.sender == _wallet) return;\n address facetAddress = IDiamondLoupe(_wallet).facetAddress(\n IS_GUARDIAN_SELECTOR\n );\n if (facetAddress != address(0))\n if (IGuardianFacet(_wallet).isGuardian(msg.sender)) return;\n revert RemoteStorage__CallerNotGuardianOrOwner();\n }\n\n /**\n * @notice Enforce the caller to be wallet IF guardians doesn't exists and only guardian when guardians exists\n * @param _wallet Target wallet address to be handled by infrastructure contracts\n */\n function enforceWalletOrGuardianIfExists(address _wallet) internal view {\n address facetAddress;\n if (msg.sender == _wallet) {\n facetAddress = IDiamondLoupe(_wallet).facetAddress(GUARDIAN_COUNT);\n if (facetAddress == address(0)) return;\n uint256 guardianCount = IGuardianFacet(_wallet).guardianCount();\n if (guardianCount != 0) revert RemoteStorage__CallerNotGuardian();\n return;\n }\n facetAddress = IDiamondLoupe(_wallet).facetAddress(\n IS_GUARDIAN_SELECTOR\n );\n if (facetAddress != address(0))\n if (IGuardianFacet(_wallet).isGuardian(msg.sender)) return;\n\n revert RemoteStorage__CallerNotGuardianOrOwner();\n }\n\n /**\n * @notice Add address to storage and reverts if the address already exists.\n * This is an internal function callable from contracts that inherit this abstract contract\n * @param _wallet Address of wallet to add the address\n * @param _address Address to be added to wallet\n */\n function addAddress(address _wallet, address _address) internal {\n StorageConfig storage config = configs[_wallet];\n if (config.info[_address].exists) revert RemoteStorage__AlreadyExists();\n\n config.info[_address].exists = true;\n config.info[_address].index = uint128(config.addresses.length);\n config.addresses.push(_address);\n\n emit Added(_address);\n }\n\n /**\n * @notice Remove address from storage and reverts if the address already exists.\n * This is an internal function callable from contracts that inherit this abstract contract\n * @param _wallet Address of wallet to remove the address\n * @param _address Address to be removed from wallet\n */\n function removeAddress(address _wallet, address _address) internal {\n StorageConfig storage config = configs[_wallet];\n if (!config.info[_address].exists) revert RemoteStorage__NotFound();\n\n address lastAddress = config.addresses[config.addresses.length - 1];\n if (_address != lastAddress) {\n uint128 targetIndex = config.info[_address].index;\n config.addresses[targetIndex] = lastAddress;\n config.info[lastAddress].index = targetIndex;\n }\n config.addresses.pop();\n delete config.info[_address];\n\n emit Removed(_address);\n }\n\n /**\n * @notice Returns the address added to the given wallet\n * @param _wallet Address of wallet to fetch the addresses added to it\n * @return addresses List of addresses added to the wallet\n */\n function getAddresses(\n address _wallet\n ) internal view returns (address[] memory addresses) {\n StorageConfig storage config = configs[_wallet];\n addresses = new address[](config.addresses.length);\n uint addressesLen = config.addresses.length;\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns bool value checking if the address exists in the given wallet address\n * @param _wallet Wallet address to check\n * @param _address Address to fetch if the address if added to given wallet\n * @return exists_ Bool value showing if the address exists in wallet\n */\n function exists(\n address _wallet,\n address _address\n ) internal view returns (bool exists_) {\n exists_ = configs[_wallet].info[_address].exists;\n }\n\n /**\n * @notice Returns the number of addresses added to the wallet\n * @param _wallet Address of wallet to check\n * @return count_ Number of addresses added to wallet\n */\n function count(address _wallet) internal view returns (uint256 count_) {\n count_ = configs[_wallet].addresses.length;\n }\n}\n" + }, + "contracts/infrastructure/SecurityManager.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport {ISecurityManager} from \"./interfaces/ISecurityManager.sol\";\n\n/**\n * @title Security Manager\n * @dev Infrastructure contract to manage security parameters of users\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract SecurityManager is ISecurityManager, Ownable2Step {\n uint128 public minAdditionSecurityPeriod;\n uint128 public maxAdditionSecurityPeriod;\n uint128 private defaultAdditionSecurityPeriod;\n\n uint128 public minRemovalSecurityPeriod;\n uint128 public maxRemovalSecurityPeriod;\n uint128 private defaultRemovalSecurityPeriod;\n\n uint128 public minSecurityWindow;\n uint128 public maxSecurityWindow;\n uint128 private defaultSecurityWindow;\n\n uint128 public minRecoveryPeriod;\n uint128 public maxRecoveryPeriod;\n uint128 private defaultRecoveryPeriod;\n\n uint128 public minLockPeriod;\n uint128 public maxLockPeriod;\n uint128 private defaultLockPeriod;\n\n uint128 public minApprovalValidationPeriod;\n uint128 public maxApprovalValidationPeriod;\n uint128 private defaultApprovalValidationPeriod;\n\n uint128 public minMigrationPeriod;\n uint128 public maxMigrationPeriod;\n uint128 private defaultMigrationPeriod;\n\n bool public _isAdditionSecurityPeriodInitialized;\n bool public _isRemovalSecurityPeriodInitialized;\n bool public _isSecurityWindowInitialized;\n bool public _isRecoveryPeriodInitialized;\n bool public _isLockPeriodInitialized;\n bool public _isApprovalValidationPeriodInitialized;\n bool public _isMigrationPeriodInitialized;\n\n mapping(address => CustomSecurityConfig) securityConfigs;\n\n struct CustomSecurityConfig {\n uint128 additionSecurityPeriod;\n uint128 removalSecurityPeriod;\n uint128 securityWindow;\n uint128 recoveryPeriod;\n uint128 lockPeriod;\n uint128 approvalValidationPeriod;\n uint128 migrationPeriod;\n }\n\n /**\n * @notice Modifier to only allow wallet itself to make a call to wallet\n */\n modifier onlyWallet(address _wallet) {\n if (msg.sender != _wallet) revert SecurityManager__CallerNotWallet();\n _;\n }\n\n /**\n * @notice Modifier to revert if the variable is already initialized\n */\n modifier initializer(bool _isInitialized) {\n if (_isInitialized) revert SecurityManager__AlreadyIntialized();\n _;\n }\n\n /**\n * @notice Transfers the ownership of the contract to the given owner\n * @param _owner Address of owner who has access to initialize the default security variables for security manager\n */\n constructor(address _owner) {\n transferOwnership(_owner);\n _transferOwnership(_owner);\n }\n\n /**\n * @notice Sets the initial default/min/max addition security period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultAdditionSecurityPeriod Default Addition Security Period for all Barz contracts\n * @param _minAdditionSecurityPeriod Minimum Addition Security Period for all Barz contracts\n * @param _maxAdditionSecurityPeriod Maximum Addition Security Period for all Barz contracts\n */\n function initializeAdditionSecurityPeriod(\n uint128 _defaultAdditionSecurityPeriod,\n uint128 _minAdditionSecurityPeriod,\n uint128 _maxAdditionSecurityPeriod\n )\n external\n override\n onlyOwner\n initializer(_isAdditionSecurityPeriodInitialized)\n {\n _isAdditionSecurityPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultAdditionSecurityPeriod,\n _minAdditionSecurityPeriod,\n _maxAdditionSecurityPeriod\n );\n defaultAdditionSecurityPeriod = _defaultAdditionSecurityPeriod;\n minAdditionSecurityPeriod = _minAdditionSecurityPeriod;\n maxAdditionSecurityPeriod = _maxAdditionSecurityPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max removal security period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultRemovalSecurityPeriod Default Removal Security Period for all Barz contracts\n * @param _minRemovalSecurityPeriod Minimum Removal Security Period for all Barz contracts\n * @param _maxRemovalSecurityPeriod Maximum Removal Security Period for all Barz contracts\n */\n function initializeRemovalSecurityPeriod(\n uint128 _defaultRemovalSecurityPeriod,\n uint128 _minRemovalSecurityPeriod,\n uint128 _maxRemovalSecurityPeriod\n )\n external\n override\n onlyOwner\n initializer(_isRemovalSecurityPeriodInitialized)\n {\n _isRemovalSecurityPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultRemovalSecurityPeriod,\n _minRemovalSecurityPeriod,\n _maxRemovalSecurityPeriod\n );\n defaultRemovalSecurityPeriod = _defaultRemovalSecurityPeriod;\n minRemovalSecurityPeriod = _minRemovalSecurityPeriod;\n maxRemovalSecurityPeriod = _maxRemovalSecurityPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/maxd security window for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultSecurityWindow Default Security Window for all Barz contracts\n * @param _minSecurityWindow Minimum Security Window for all Barz contracts\n * @param _maxSecurityWindow Maximum Security Window for all Barz contracts\n */\n function initializeSecurityWindow(\n uint128 _defaultSecurityWindow,\n uint128 _minSecurityWindow,\n uint128 _maxSecurityWindow\n ) external override onlyOwner initializer(_isSecurityWindowInitialized) {\n _isSecurityWindowInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultSecurityWindow,\n _minSecurityWindow,\n _maxSecurityWindow\n );\n defaultSecurityWindow = _defaultSecurityWindow;\n minSecurityWindow = _minSecurityWindow;\n maxSecurityWindow = _maxSecurityWindow;\n }\n\n /**\n * @notice Sets the initial default/min/max recovery period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultRecoveryPeriod Default Recovery Period for all Barz contracts\n * @param _minRecoveryPeriod Minimum Recovery Period for all Barz contracts\n * @param _maxRecoveryPeriod Maximum Recovery Period for all Barz contracts\n */\n function initializeRecoveryPeriod(\n uint128 _defaultRecoveryPeriod,\n uint128 _minRecoveryPeriod,\n uint128 _maxRecoveryPeriod\n ) external override onlyOwner initializer(_isRecoveryPeriodInitialized) {\n _isRecoveryPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultRecoveryPeriod,\n _minRecoveryPeriod,\n _maxRecoveryPeriod\n );\n defaultRecoveryPeriod = _defaultRecoveryPeriod;\n minRecoveryPeriod = _minRecoveryPeriod;\n maxRecoveryPeriod = _maxRecoveryPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max lock period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultLockPeriod Default Lock Period for all Barz contracts\n * @param _minLockPeriod Minimum Lock Period for all Barz contracts\n * @param _maxLockPeriod Maximum Lock Period for all Barz contracts\n */\n function initializeLockPeriod(\n uint128 _defaultLockPeriod,\n uint128 _minLockPeriod,\n uint128 _maxLockPeriod\n ) external override onlyOwner initializer(_isLockPeriodInitialized) {\n _isLockPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultLockPeriod,\n _minLockPeriod,\n _maxLockPeriod\n );\n defaultLockPeriod = _defaultLockPeriod;\n minLockPeriod = _minLockPeriod;\n maxLockPeriod = _maxLockPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max approval validation period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultApprovalValidationPeriod Default Approval Validation Period for all Barz contracts\n * @param _minApprovalValidationPeriod Minimum Approval Validation Period for all Barz contracts\n * @param _maxApprovalValidationPeriod Maximum Approval Validation Period for all Barz contracts\n */\n function initializeApprovalValidationPeriod(\n uint128 _defaultApprovalValidationPeriod,\n uint128 _minApprovalValidationPeriod,\n uint128 _maxApprovalValidationPeriod\n )\n external\n override\n onlyOwner\n initializer(_isApprovalValidationPeriodInitialized)\n {\n _isApprovalValidationPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultApprovalValidationPeriod,\n _minApprovalValidationPeriod,\n _maxApprovalValidationPeriod\n );\n defaultApprovalValidationPeriod = _defaultApprovalValidationPeriod;\n minApprovalValidationPeriod = _minApprovalValidationPeriod;\n maxApprovalValidationPeriod = _maxApprovalValidationPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max migration period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultMigrationPeriod Default Migration Period for all Barz contracts\n * @param _minMigrationPeriod Minimum Migration Period for all Barz contracts\n * @param _maxMigrationPeriod Maximum Migration Period for all Barz contracts\n */\n function initializeMigrationPeriod(\n uint128 _defaultMigrationPeriod,\n uint128 _minMigrationPeriod,\n uint128 _maxMigrationPeriod\n ) external override onlyOwner initializer(_isMigrationPeriodInitialized) {\n _isMigrationPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultMigrationPeriod,\n _minMigrationPeriod,\n _maxMigrationPeriod\n );\n defaultMigrationPeriod = _defaultMigrationPeriod;\n minMigrationPeriod = _minMigrationPeriod;\n maxMigrationPeriod = _maxMigrationPeriod;\n }\n\n /**\n * @notice Wallet owner sets the addition security period for the wallet. Only the owner of wallet can call this function.\n * The addition security period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _additionSecurityPeriod Custom Addition Security Period for the wallet\n */\n function setAdditionSecurityPeriod(\n address _wallet,\n uint128 _additionSecurityPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _additionSecurityPeriod,\n minAdditionSecurityPeriod,\n maxAdditionSecurityPeriod\n );\n securityConfigs[_wallet]\n .additionSecurityPeriod = _additionSecurityPeriod;\n }\n\n /**\n * @notice Wallet owner sets the removal security period for the wallet. Only the owner of wallet can call this function.\n * The removal security period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _removalSecurityPeriod Custom Removal Security Period for the wallet\n */\n function setRemovalSecurityPeriod(\n address _wallet,\n uint128 _removalSecurityPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _removalSecurityPeriod,\n minRemovalSecurityPeriod,\n maxRemovalSecurityPeriod\n );\n securityConfigs[_wallet].removalSecurityPeriod = _removalSecurityPeriod;\n }\n\n /**\n * @notice Wallet owner sets the security window for the wallet. Only the owner of wallet can call this function.\n * The security window should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _securityWindow Custom Security Window for the wallet\n */\n function setSecurityWindow(\n address _wallet,\n uint128 _securityWindow\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _securityWindow,\n minSecurityWindow,\n maxSecurityWindow\n );\n securityConfigs[_wallet].securityWindow = _securityWindow;\n }\n\n /**\n * @notice Wallet owner sets the recovery period for the wallet. Only the owner of wallet can call this function.\n * The recovery period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _recoveryPeriod Custom recovery period for the wallet\n */\n function setRecoveryPeriod(\n address _wallet,\n uint128 _recoveryPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _recoveryPeriod,\n minRecoveryPeriod,\n maxRecoveryPeriod\n );\n securityConfigs[_wallet].recoveryPeriod = _recoveryPeriod;\n }\n\n /**\n * @notice Wallet owner sets the lock period for the wallet. Only the owner of wallet can call this function.\n * The lock period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _lockPeriod Custom Lock period for the wallet\n */\n function setLockPeriod(\n address _wallet,\n uint128 _lockPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(_lockPeriod, minLockPeriod, maxLockPeriod);\n securityConfigs[_wallet].lockPeriod = _lockPeriod;\n }\n\n /**\n * @notice Wallet owner sets the approval validation period for the wallet. Only the owner of wallet can call this function.\n * The approval validation period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _approvalValidationPeriod Custom approval validation period for the wallet\n */\n function setApprovalValidationPeriod(\n address _wallet,\n uint128 _approvalValidationPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _approvalValidationPeriod,\n minApprovalValidationPeriod,\n maxApprovalValidationPeriod\n );\n securityConfigs[_wallet]\n .approvalValidationPeriod = _approvalValidationPeriod;\n }\n\n /**\n * @notice Wallet owner sets the migration period for the wallet. Only the owner of wallet can call this function.\n * The migration period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _migrationPeriod Custom migration period for the wallet\n */\n\n function setMigrationPeriod(\n address _wallet,\n uint128 _migrationPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _migrationPeriod,\n minMigrationPeriod,\n maxMigrationPeriod\n );\n securityConfigs[_wallet].migrationPeriod = _migrationPeriod;\n }\n\n /**\n * @notice Returns the addition security period. Returns default value when custom addition security period is not set\n * @param _wallet Address of wallet\n * @return additionSecurityPeriod Addition Security Period of the given Barz account or wallet\n */\n function additionSecurityPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 additionSecurityPeriod)\n {\n additionSecurityPeriod = securityConfigs[_wallet]\n .additionSecurityPeriod;\n additionSecurityPeriod = (additionSecurityPeriod == 0)\n ? defaultAdditionSecurityPeriod\n : additionSecurityPeriod;\n }\n\n /**\n * @notice Returns the removal security period. Returns default value when custom removal security period is not set\n * @param _wallet Address of wallet\n * @return removalSecurityPeriod Removal Security Period of the given Barz account or wallet\n */\n function removalSecurityPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 removalSecurityPeriod)\n {\n removalSecurityPeriod = securityConfigs[_wallet].removalSecurityPeriod;\n removalSecurityPeriod = (removalSecurityPeriod == 0)\n ? defaultRemovalSecurityPeriod\n : removalSecurityPeriod;\n }\n\n /**\n * @notice Returns the security window. Returns default value when custom security window is not set\n * @param _wallet Address of wallet\n * @return securityWindow Security window of the given Barz account or wallet\n */\n function securityWindowOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 securityWindow)\n {\n securityWindow = securityConfigs[_wallet].securityWindow;\n securityWindow = (securityWindow == 0)\n ? defaultSecurityWindow\n : securityWindow;\n }\n\n /**\n * @notice Returns the recovery period. Returns default value when custom recovery period is not set\n * @param _wallet Address of wallet\n * @return recoveryPeriod Recovery Period of the given Barz account or wallet\n */\n function recoveryPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 recoveryPeriod)\n {\n recoveryPeriod = securityConfigs[_wallet].recoveryPeriod;\n recoveryPeriod = (recoveryPeriod == 0)\n ? defaultRecoveryPeriod\n : recoveryPeriod;\n }\n\n /**\n * @notice Returns the lock period. Returns default value when custom lock period is not set\n * @param _wallet Address of wallet\n * @return lockPeriod Lock Period of the given Barz account or wallet\n */\n function lockPeriodOf(\n address _wallet\n ) public view override onlyWallet(_wallet) returns (uint128 lockPeriod) {\n lockPeriod = securityConfigs[_wallet].lockPeriod;\n lockPeriod = (lockPeriod == 0) ? defaultLockPeriod : lockPeriod;\n }\n\n /**\n * @notice Returns the approval validation period. Returns default value when custom approval validation period is not set\n * @param _wallet Address of wallet\n * @return approvalValidationPeriod Approval Validation Period of the given Barz account or wallet\n */\n function approvalValidationPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityConfigs[_wallet]\n .approvalValidationPeriod;\n approvalValidationPeriod = (approvalValidationPeriod == 0)\n ? defaultApprovalValidationPeriod\n : approvalValidationPeriod;\n }\n\n /**\n * @notice Returns the migration period. Returns default value when custom migration period is not set\n * @param _wallet Address of wallet\n * @return migrationPeriod Migration Period of the given Barz account or wallet\n */\n function migrationPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 migrationPeriod)\n {\n migrationPeriod = securityConfigs[_wallet].migrationPeriod;\n migrationPeriod = (migrationPeriod == 0)\n ? defaultMigrationPeriod\n : migrationPeriod;\n }\n\n /**\n * @notice Validates if the period is smaller than the max period or bigger than the min period\n * @param _period Period to be checked\n * @param _minPeriod Minimum period\n * @param _maxPeriod Maximum period\n */\n function _validatePeriodBoundaries(\n uint128 _period,\n uint128 _minPeriod,\n uint128 _maxPeriod\n ) internal pure {\n if (_period >= _maxPeriod || _period <= _minPeriod)\n revert SecurityManager__OutOfBoundary();\n }\n}\n" + }, + "contracts/infrastructure/WhitelistStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {RemoteStorage} from \"./RemoteStorage.sol\";\n\n/**\n * @title Whitelist storage\n * @dev Maps addresses to the corresponsing array of whitelisted addresses for each of them.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract WhitelistStorage is RemoteStorage {\n /**\n * @dev Add the address to the whitelist storage\n * @param _wallet User wallet\n * @param _address Address to be whitelisted\n */\n function whitelistAddress(address _wallet, address _address) external {\n enforceWalletOrGuardianIfExists(_wallet);\n addAddress(_wallet, _address);\n }\n\n /**\n * @dev Removes the address from the whitelist storage\n * @param _wallet User wallet\n * @param _address Address to be removed from the whitelist\n */\n function blacklistAddress(address _wallet, address _address) external {\n enforceGuardianOrWallet(_wallet);\n removeAddress(_wallet, _address);\n }\n\n /**\n * @dev Returns whether the address exists in the whitelist storage, associated with the wallet\n * @param _wallet User wallet\n * @param _address Address to be whitelisted\n */\n function isWhitelisted(\n address _wallet,\n address _address\n ) external view returns (bool) {\n return exists(_wallet, _address);\n }\n\n /**\n * @dev Returns all whitelisted addresses associated with the wallet\n * @param _wallet User wallet\n */\n function getWhitelistedAddresses(\n address _wallet\n ) external view returns (address[] memory) {\n return getAddresses(_wallet);\n }\n}\n" + }, + "contracts/interfaces/ERC/IERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\n\npragma solidity 0.8.21;\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155Receiver {\n /**\n * @dev Handles the receipt of a single ERC1155 token type. This function is\n * called at the end of a `safeTransferFrom` after the balance has been updated.\n *\n * NOTE: To accept the transfer, this must return\n * `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n * (i.e. 0xf23a6e61, or its own function selector).\n *\n * @param operator The address which initiated the transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param id The ID of the token being transferred\n * @param value The amount of tokens being transferred\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n ) external returns (bytes4);\n\n /**\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\n * is called at the end of a `safeBatchTransferFrom` after the balances have\n * been updated.\n *\n * NOTE: To accept the transfer(s), this must return\n * `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n * (i.e. 0xbc197c81, or its own function selector).\n *\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "contracts/interfaces/ERC/IERC1271.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\ninterface IERC1271 {\n function isValidSignature(\n bytes32 hash,\n bytes memory signature\n ) external view returns (bytes4);\n}\n" + }, + "contracts/interfaces/ERC/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\ninterface IERC165 {\n /// @notice Query if a contract implements an interface\n /// @param interfaceId The interface identifier, as specified in ERC-165\n /// @dev Interface identification is specified in ERC-165. This function\n /// uses less than 30,000 gas.\n /// @return `true` if the contract implements `interfaceID` and\n /// `interfaceID` is not 0xffffffff, `false` otherwise\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/IERC173.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\n/// @title ERC-173 Contract Ownership Standard\n/// Note: the ERC-165 identifier for this interface is 0x7f5828d0\n/* is ERC165 */\ninterface IERC173 {\n /// @dev This emits when ownership of a contract changes.\n event OwnershipTransferred(\n address indexed previousOwner,\n address indexed newOwner\n );\n\n /// @notice Get the address of the owner\n /// @return owner_ The address of the owner.\n function owner() external view returns (address owner_);\n\n /// @notice Set the address of the new owner of the contract\n /// @dev Set _newOwner to address(0) to renounce any ownership.\n /// @param _newOwner The address of the new owner of the contract\n function transferOwnership(address _newOwner) external;\n}\n" + }, + "contracts/interfaces/ERC/IERC677Receiver.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\ninterface IERC677Receiver {\n function onTokenTransfer(\n address sender,\n uint value,\n bytes calldata data\n ) external pure returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155 is IERC165 {\n /**\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n */\n event TransferSingle(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256 id,\n uint256 value\n );\n\n /**\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n * transfers.\n */\n event TransferBatch(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\n\n /**\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n * `approved`.\n */\n event ApprovalForAll(\n address indexed account,\n address indexed operator,\n bool approved\n );\n\n /**\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n *\n * If an {URI} event was emitted for `id`, the standard\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n * returned by {IERC1155MetadataURI-uri}.\n */\n event URI(string value, uint256 indexed id);\n\n /**\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(\n address account,\n uint256 id\n ) external view returns (uint256);\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] calldata accounts,\n uint256[] calldata ids\n ) external view returns (uint256[] memory);\n\n /**\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n *\n * Emits an {ApprovalForAll} event.\n *\n * Requirements:\n *\n * - `operator` cannot be the caller.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n *\n * See {setApprovalForAll}.\n */\n function isApprovedForAll(\n address account,\n address operator\n ) external view returns (bool);\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes calldata data\n ) external;\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(\n address indexed owner,\n address indexed spender,\n uint256 value\n );\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` 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 amount) 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(\n address owner,\n address spender\n ) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the 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 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` 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(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(\n address spender,\n uint256 addedValue\n ) external returns (bool);\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(\n address spender,\n uint256 subtractedValue\n ) external returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(\n address indexed from,\n address indexed to,\n uint256 indexed tokenId\n );\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(\n address indexed owner,\n address indexed approved,\n uint256 indexed tokenId\n );\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(\n address indexed owner,\n address indexed operator,\n bool approved\n );\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(\n uint256 tokenId\n ) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(\n address owner,\n address operator\n ) external view returns (bool);\n}\n" + }, + "contracts/interfaces/IBarz.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Barz Interface\n * @dev Interface of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IBarz {\n error Barz__InitializationFailure();\n}\n" + }, + "contracts/interfaces/IBarzFactory.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Barz} from \"../Barz.sol\";\n\n/**\n * @title Barz Factory Interface\n * @dev Interface of contract to easily deploy Barz to a pre-computed address with a single call\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IBarzFactory {\n function createAccount(\n address verificationFacet,\n bytes calldata owner,\n uint256 salt\n ) external returns (Barz);\n\n function getAddress(\n address verificationFacet,\n bytes calldata owner,\n uint256 salt\n ) external view returns (address);\n\n function getBytecode(\n address accountFacet,\n address verificationFacet,\n address entryPoint,\n address facetRegistry,\n address defaultFallback,\n bytes memory ownerPublicKey\n ) external pure returns (bytes memory);\n\n function getCreationCode() external pure returns (bytes memory);\n}\n" + }, + "contracts/libraries/DefaultLibDiamond.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\n\nerror InitializationFunctionReverted(\n address _initializationContractAddress,\n bytes _calldata\n);\n\nlibrary DefaultLibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION =\n keccak256(\"trustwallet.barz.diamond.storage\");\n\n struct FacetAddressAndPosition {\n address facetAddress;\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\n }\n\n struct FacetFunctionSelectors {\n bytes4[] functionSelectors;\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\n }\n\n struct DiamondStorage {\n // maps function selector to the facet address and\n // the position of the selector in the facetFunctionSelectors.selectors array\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\n // maps facet addresses to function selectors\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\n // facet addresses\n address[] facetAddresses;\n // Used to query if a contract implements an interface.\n // Used to implement ERC-165.\n mapping(bytes4 => bool) supportedInterfaces;\n }\n\n function diamondStorage()\n internal\n pure\n returns (DiamondStorage storage ds)\n {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n event DiamondCut(\n IDiamondCut.FacetCut[] _diamondCut,\n address _init,\n bytes _calldata\n );\n\n // Internal function version of diamondCut\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n for (\n uint256 facetIndex;\n facetIndex < _diamondCut.length;\n facetIndex++\n ) {\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\n if (action == IDiamondCut.FacetCutAction.Add) {\n addFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\n replaceFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\n removeFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else {\n revert(\"LibDiamondCut: Incorrect FacetCutAction\");\n }\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Add facet can't be address(0)\"\n );\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n require(\n oldFacetAddress == address(0),\n \"LibDiamondCut: Can't add function that already exists\"\n );\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function replaceFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Replace facet can't be address(0)\"\n );\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n require(\n oldFacetAddress != _facetAddress,\n \"LibDiamondCut: Can't replace function with same facet\"\n );\n removeFunction(ds, oldFacetAddress, selector);\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function removeFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n // if function does not exist then do nothing and return\n require(\n _facetAddress == address(0),\n \"LibDiamondCut: Remove facet address must be address(0)\"\n );\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n removeFunction(ds, oldFacetAddress, selector);\n }\n }\n\n function addFacet(\n DiamondStorage storage ds,\n address _facetAddress\n ) internal {\n enforceHasContractCode(\n _facetAddress,\n \"LibDiamondCut: New facet has no code\"\n );\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds\n .facetAddresses\n .length;\n ds.facetAddresses.push(_facetAddress);\n }\n\n function addFunction(\n DiamondStorage storage ds,\n bytes4 _selector,\n uint96 _selectorPosition,\n address _facetAddress\n ) internal {\n ds\n .selectorToFacetAndPosition[_selector]\n .functionSelectorPosition = _selectorPosition;\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(\n _selector\n );\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\n }\n\n function removeFunction(\n DiamondStorage storage ds,\n address _facetAddress,\n bytes4 _selector\n ) internal {\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Can't remove function that doesn't exist\"\n );\n // an immutable function is a function defined directly in a diamond\n require(\n _facetAddress != address(this),\n \"LibDiamondCut: Can't remove immutable function\"\n );\n // replace selector with last selector, then delete last selector\n uint256 selectorPosition = ds\n .selectorToFacetAndPosition[_selector]\n .functionSelectorPosition;\n uint256 lastSelectorPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors\n .length - 1;\n // if not the same then replace _selector with lastSelector\n if (selectorPosition != lastSelectorPosition) {\n bytes4 lastSelector = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors[lastSelectorPosition];\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[\n selectorPosition\n ] = lastSelector;\n ds\n .selectorToFacetAndPosition[lastSelector]\n .functionSelectorPosition = uint96(selectorPosition);\n }\n // delete the last selector\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\n delete ds.selectorToFacetAndPosition[_selector];\n\n // if no more selectors for facet address then delete the facet address\n if (lastSelectorPosition == 0) {\n // replace facet address with last facet address and delete last facet address\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\n uint256 facetAddressPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .facetAddressPosition;\n if (facetAddressPosition != lastFacetAddressPosition) {\n address lastFacetAddress = ds.facetAddresses[\n lastFacetAddressPosition\n ];\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\n ds\n .facetFunctionSelectors[lastFacetAddress]\n .facetAddressPosition = facetAddressPosition;\n }\n ds.facetAddresses.pop();\n delete ds\n .facetFunctionSelectors[_facetAddress]\n .facetAddressPosition;\n }\n }\n\n function initializeDiamondCut(\n address _init,\n bytes memory _calldata\n ) internal {\n if (_init == address(0)) {\n return;\n }\n enforceHasContractCode(\n _init,\n \"LibDiamondCut: _init address has no code\"\n );\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length > 0) {\n // bubble up error\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(error)\n revert(add(32, error), returndata_size)\n }\n } else {\n revert InitializationFunctionReverted(_init, _calldata);\n }\n }\n }\n\n function enforceHasContractCode(\n address _contract,\n string memory _errorMessage\n ) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize > 0, _errorMessage);\n }\n}\n" + }, + "contracts/libraries/LibAppStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SafeCast} from \"@openzeppelin/contracts/utils/math/SafeCast.sol\";\nimport {IEntryPoint} from \"../aa-4337/interfaces/IEntryPoint.sol\";\nimport {IFacetRegistry} from \"../infrastructure/interfaces/IFacetRegistry.sol\";\n\n/*\n * @title App Storage\n * @dev App storage for Barz contract to prevent storage collision\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\n\nstruct Lock {\n uint64 release;\n bytes4 locker;\n}\n\nstruct InitializersStorage {\n // NOTE: initialized is a variable to make sure the initialization is only done once.\n uint8 signerInitialized;\n uint8 accountInitialized;\n uint8 restrictionsInitialized;\n}\n\nstruct AppStorage {\n mapping(uint256 => InitializersStorage) initStorage;\n uint8 signerMigration;\n bytes4 validateOwnerSignatureSelector;\n IEntryPoint entryPoint;\n IFacetRegistry facetRegistry;\n mapping(uint256 => Lock) locks;\n}\n\nlibrary LibAppStorage {\n error LibAppStorage__AccountAlreadyUninitialized();\n error LibAppStorage__AccountMustBeUninitialized();\n error LibAppStorage__SignerAlreadyUninitialized();\n error LibAppStorage__SignerMustBeUninitialized();\n\n function appStorage() internal pure returns (AppStorage storage ds) {\n assembly {\n ds.slot := 0\n }\n }\n\n function setSignerUninitialized() internal {\n AppStorage storage s = appStorage();\n if (1 != s.initStorage[0].signerInitialized) {\n revert LibAppStorage__SignerAlreadyUninitialized();\n }\n s.initStorage[0].signerInitialized = 0;\n }\n\n function getValidateOwnerSignatureSelector()\n internal\n view\n returns (bytes4 selector)\n {\n selector = appStorage().validateOwnerSignatureSelector;\n }\n\n function setValidateOwnerSignatureSelector(\n bytes4 _validateOwnerSignatureSelector\n ) internal {\n appStorage()\n .validateOwnerSignatureSelector = _validateOwnerSignatureSelector;\n }\n\n function enforceSignerInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].signerInitialized) {\n revert LibAppStorage__SignerMustBeUninitialized();\n }\n s.initStorage[0].signerInitialized = 1;\n }\n\n function enforceAccountInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].accountInitialized) {\n revert LibAppStorage__AccountMustBeUninitialized();\n }\n s.initStorage[0].accountInitialized = 1;\n }\n\n function initiateSignerMigration() internal {\n appStorage().signerMigration = 1;\n }\n\n function enforceSignerMigration() internal view {\n if (1 != appStorage().signerMigration) {\n revert LibAppStorage__AccountMustBeUninitialized();\n }\n }\n\n function finalizeSignerMigration() internal {\n appStorage().signerMigration = 0;\n }\n\n function setLock(uint256 _releaseAfter, bytes4 _locker) internal {\n appStorage().locks[0] = Lock(SafeCast.toUint64(_releaseAfter), _locker);\n }\n\n function enforceRestrictionsInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].restrictionsInitialized)\n revert LibAppStorage__SignerMustBeUninitialized();\n s.initStorage[0].restrictionsInitialized = 1;\n }\n\n function setRestrictionsUninitialized() internal {\n AppStorage storage s = appStorage();\n if (1 != s.initStorage[0].restrictionsInitialized)\n revert LibAppStorage__AccountAlreadyUninitialized();\n s.initStorage[0].restrictionsInitialized = 0;\n }\n}\n\ncontract BarzStorage {\n AppStorage internal s;\n modifier onlyWhenUnlocked() {\n require(\n uint64(block.timestamp) >= s.locks[0].release,\n \"Account Locked\"\n );\n _;\n }\n modifier onlyWhenLocked() {\n require(\n uint64(block.timestamp) < s.locks[0].release,\n \"Account Unlocked\"\n );\n _;\n }\n}\n" + }, + "contracts/libraries/LibDiamond.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\n\nerror InitializationFunctionReverted(\n address _initializationContractAddress,\n bytes _calldata\n);\n\nlibrary LibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION =\n keccak256(\"trustwallet.barz.diamond.storage\");\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\n bytes4(keccak256(\"verifyRestrictions(address,address,uint256,bytes)\"));\n struct DiamondStorage {\n // maps function selectors to the facets that execute the functions.\n // and maps the selectors to their position in the selectorSlots array.\n // func selector => address facet, selector position\n mapping(bytes4 => bytes32) facets;\n // array of slots of function selectors.\n // each slot holds 8 function selectors.\n mapping(uint256 => bytes32) selectorSlots;\n // The number of function selectors in selectorSlots\n uint16 selectorCount;\n // Used to query if a contract implements an interface.\n // Used to implement ERC-165.\n mapping(bytes4 => bool) supportedInterfaces;\n // Default Fallback Handler of the barz.\n IDiamondLoupe defaultFallbackHandler;\n }\n\n function diamondStorage()\n internal\n pure\n returns (DiamondStorage storage ds)\n {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n function enforceIsSelf() internal view {\n require(msg.sender == address(this), \"LibDiamond: Caller not self\");\n }\n\n event DiamondCut(\n IDiamondCut.FacetCut[] _diamondCut,\n address _init,\n bytes _calldata\n );\n\n bytes32 constant CLEAR_ADDRESS_MASK =\n bytes32(uint256(0xffffffffffffffffffffffff));\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\n\n // Internal function version of diamondCut\n // This code is almost the same as the external diamondCut,\n // except it is using 'Facet[] memory _diamondCut' instead of\n // 'Facet[] calldata _diamondCut'.\n // The code is duplicated to prevent copying calldata to memory which\n // causes an error for a two dimensional array.\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n DiamondStorage storage ds = diamondStorage();\n uint256 originalSelectorCount = ds.selectorCount;\n uint256 selectorCount = originalSelectorCount;\n bytes32 selectorSlot;\n // Check if last selector slot is not full\n // \"selectorCount & 7\" is a gas efficient modulo by eight \"selectorCount % 8\"\n if (selectorCount & 7 > 0) {\n // get last selectorSlot\n // \"selectorSlot >> 3\" is a gas efficient division by 8 \"selectorSlot / 8\"\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\n }\n // loop through diamond cut\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\n selectorCount,\n selectorSlot,\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].action,\n _diamondCut[facetIndex].functionSelectors\n );\n\n unchecked {\n facetIndex++;\n }\n }\n if (selectorCount != originalSelectorCount) {\n ds.selectorCount = uint16(selectorCount);\n }\n // If last selector slot is not full\n // \"selectorCount & 7\" is a gas efficient modulo by eight \"selectorCount % 8\"\n if (selectorCount & 7 > 0) {\n // \"selectorSlot >> 3\" is a gas efficient division by 8 \"selectorSlot / 8\"\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addReplaceRemoveFacetSelectors(\n uint256 _selectorCount,\n bytes32 _selectorSlot,\n address _newFacetAddress,\n IDiamondCut.FacetCutAction _action,\n bytes4[] memory _selectors\n ) internal returns (uint256, bytes32) {\n DiamondStorage storage ds = diamondStorage();\n require(\n _selectors.length > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n if (_action == IDiamondCut.FacetCutAction.Add) {\n enforceHasContractCode(\n _newFacetAddress,\n \"LibDiamondCut: Add facet has no code\"\n );\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n require(\n address(bytes20(oldFacet)) == address(0),\n \"LibDiamondCut: Can't add function that already exists\"\n );\n // add facet for selector\n ds.facets[selector] =\n bytes20(_newFacetAddress) |\n bytes32(_selectorCount);\n // \"_selectorCount & 7\" is a gas efficient modulo by eight \"_selectorCount % 8\"\n // \" << 5 is the same as multiplying by 32 ( * 32)\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\n // clear selector position in slot and add selector\n _selectorSlot =\n (_selectorSlot &\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\n (bytes32(selector) >> selectorInSlotPosition);\n // if slot is full then write it to storage\n if (selectorInSlotPosition == 224) {\n // \"_selectorSlot >> 3\" is a gas efficient division by 8 \"_selectorSlot / 8\"\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\n _selectorSlot = 0;\n }\n _selectorCount++;\n\n unchecked {\n selectorIndex++;\n }\n }\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\n enforceHasContractCode(\n _newFacetAddress,\n \"LibDiamondCut: Replace facet has no code\"\n );\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n address oldFacetAddress = address(bytes20(oldFacet));\n // only useful if immutable functions exist\n require(\n oldFacetAddress != address(this),\n \"LibDiamondCut: Can't replace immutable function\"\n );\n require(\n oldFacetAddress != _newFacetAddress,\n \"LibDiamondCut: Can't replace function with same function\"\n );\n require(\n oldFacetAddress != address(0),\n \"LibDiamondCut: Can't replace function that doesn't exist\"\n );\n // replace old facet address\n ds.facets[selector] =\n (oldFacet & CLEAR_ADDRESS_MASK) |\n bytes20(_newFacetAddress);\n\n unchecked {\n selectorIndex++;\n }\n }\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\n require(\n _newFacetAddress == address(0),\n \"LibDiamondCut: Remove facet address must be address(0)\"\n );\n // \"_selectorCount >> 3\" is a gas efficient division by 8 \"_selectorCount / 8\"\n uint256 selectorSlotCount = _selectorCount >> 3;\n // \"_selectorCount & 7\" is a gas efficient modulo by eight \"_selectorCount % 8\"\n uint256 selectorInSlotIndex = _selectorCount & 7;\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n if (_selectorSlot == 0) {\n // get last selectorSlot\n selectorSlotCount--;\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\n selectorInSlotIndex = 7;\n } else {\n selectorInSlotIndex--;\n }\n bytes4 lastSelector;\n uint256 oldSelectorsSlotCount;\n uint256 oldSelectorInSlotPosition;\n // adding a block here prevents stack too deep error\n {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n require(\n address(bytes20(oldFacet)) != address(0),\n \"LibDiamondCut: Can't remove function that doesn't exist\"\n );\n // only useful if immutable functions exist\n require(\n address(bytes20(oldFacet)) != address(this),\n \"LibDiamondCut: Can't remove immutable function\"\n );\n // replace selector with last selector in ds.facets\n // gets the last selector\n // \" << 5 is the same as multiplying by 32 ( * 32)\n lastSelector = bytes4(\n _selectorSlot << (selectorInSlotIndex << 5)\n );\n if (lastSelector != selector) {\n // update last selector slot position info\n ds.facets[lastSelector] =\n (oldFacet & CLEAR_ADDRESS_MASK) |\n bytes20(ds.facets[lastSelector]);\n }\n delete ds.facets[selector];\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\n // \"oldSelectorCount >> 3\" is a gas efficient division by 8 \"oldSelectorCount / 8\"\n oldSelectorsSlotCount = oldSelectorCount >> 3;\n // \"oldSelectorCount & 7\" is a gas efficient modulo by eight \"oldSelectorCount % 8\"\n // \" << 5 is the same as multiplying by 32 ( * 32)\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\n }\n if (oldSelectorsSlotCount != selectorSlotCount) {\n bytes32 oldSelectorSlot = ds.selectorSlots[\n oldSelectorsSlotCount\n ];\n // clears the selector we are deleting and puts the last selector in its place.\n oldSelectorSlot =\n (oldSelectorSlot &\n ~(CLEAR_SELECTOR_MASK >>\n oldSelectorInSlotPosition)) |\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\n // update storage with the modified slot\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\n } else {\n // clears the selector we are deleting and puts the last selector in its place.\n _selectorSlot =\n (_selectorSlot &\n ~(CLEAR_SELECTOR_MASK >>\n oldSelectorInSlotPosition)) |\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\n }\n if (selectorInSlotIndex == 0) {\n delete ds.selectorSlots[selectorSlotCount];\n _selectorSlot = 0;\n }\n\n unchecked {\n selectorIndex++;\n }\n }\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\n } else {\n revert(\"LibDiamondCut: Incorrect FacetCutAction\");\n }\n return (_selectorCount, _selectorSlot);\n }\n\n function initializeDiamondCut(\n address _init,\n bytes memory _calldata\n ) internal {\n if (_init == address(0)) {\n return;\n }\n enforceHasContractCode(\n _init,\n \"LibDiamondCut: _init address has no code\"\n );\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length > 0) {\n // bubble up error\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(error)\n revert(add(32, error), returndata_size)\n }\n } else {\n revert InitializationFunctionReverted(_init, _calldata);\n }\n }\n }\n\n function enforceHasContractCode(\n address _contract,\n string memory _errorMessage\n ) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize > 0, _errorMessage);\n }\n\n function restrictionsFacet() internal view returns (address facetAddress_) {\n facetAddress_ = address(\n bytes20(\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\n )\n );\n }\n}\n" + }, + "contracts/libraries/LibFacetStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Storage\n * @dev Storage contract to store each facets variables with diamond storage\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\n\nstruct Secp256k1VerificationStorage {\n address signer;\n}\n\nstruct Secp256r1VerificationStorage {\n uint256[2] q;\n}\n\nstruct GuardianStorage {\n mapping(bytes32 => uint256) pending;\n mapping(uint8 => StorageConfig) configs;\n}\n\nstruct Info {\n bool exists;\n uint128 index;\n}\n\nstruct StorageConfig {\n address[] addresses;\n mapping(address => Info) info;\n}\n\nstruct RecoveryConfig {\n bytes recoveryPublicKey;\n uint64 executeAfter;\n}\n\nstruct ApprovalConfig {\n bool isApproved;\n uint64 validUntil;\n}\n\nstruct RecoveryApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isNewOwnerApproved;\n}\n\nstruct RecoveryStorage {\n mapping(uint8 => RecoveryConfig) recoveryConfigs;\n mapping(uint8 => RecoveryApprovalConfig) recoveryApprovalConfigs;\n uint128 nonce;\n}\n\nstruct RestrictionsStorage {\n address[] restrictions;\n mapping(address => bool) exists;\n}\n\nstruct SignatureMigrationConfig {\n bytes migrationPublicKey;\n address migrationVerificationFacet;\n bytes4[] migrationSelectors;\n uint64 migrateAfter;\n}\n\nstruct SignatureMigrationApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isMigrationApproved;\n}\n\nstruct SignatureMigrationStorage {\n mapping(uint8 => SignatureMigrationConfig) migrationConfigs;\n mapping(uint8 => SignatureMigrationApprovalConfig) migrationApprovalConfigs;\n uint128 nonce;\n}\n\nstruct DiamondCutApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isDiamondCutApproved;\n}\n\nstruct DiamondCutStorage {\n mapping(uint8 => DiamondCutApprovalConfig) diamondCutApprovalConfigs;\n uint128 nonce;\n}\n\nstruct LockStorage {\n uint128 nonce;\n}\n\nlibrary LibFacetStorage {\n bytes32 constant K1_STORAGE_POSITION =\n keccak256(\n \"v0.trustwallet.diamond.storage.Secp256k1VerificationStorage\"\n );\n bytes32 constant R1_STORAGE_POSITION =\n keccak256(\n \"v0.trustwallet.diamond.storage.Secp256r1VerificationStorage\"\n );\n bytes32 constant GUARDIAN_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.GuardianStorage\");\n bytes32 constant RECOVERY_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.RecoveryStorage\");\n bytes32 constant RESTRICTION_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.RestrictionsStorage\");\n bytes32 constant MIGRATION_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.SignatureMigrationStorage\");\n bytes32 constant DIAMONDCUT_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.DiamondCutStorage\");\n bytes32 constant LOCK_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.LockStorage\");\n\n function k1Storage()\n internal\n pure\n returns (Secp256k1VerificationStorage storage ds)\n {\n bytes32 storagePosition = K1_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function r1Storage()\n internal\n pure\n returns (Secp256r1VerificationStorage storage ds)\n {\n bytes32 storagePosition = R1_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function guardianStorage()\n internal\n pure\n returns (GuardianStorage storage ds)\n {\n bytes32 storagePosition = GUARDIAN_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function recoveryStorage()\n internal\n pure\n returns (RecoveryStorage storage ds)\n {\n bytes32 storagePosition = RECOVERY_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function restrictionsStorage()\n internal\n pure\n returns (RestrictionsStorage storage ds)\n {\n bytes32 storagePosition = RESTRICTION_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function migrationStorage()\n internal\n pure\n returns (SignatureMigrationStorage storage ds)\n {\n bytes32 storagePosition = MIGRATION_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function diamondCutStorage()\n internal\n pure\n returns (DiamondCutStorage storage ds)\n {\n bytes32 storagePosition = DIAMONDCUT_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function lockStorage() internal pure returns (LockStorage storage ds) {\n bytes32 storagePosition = LOCK_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n}\n" + }, + "contracts/libraries/LibGuardian.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibFacetStorage, StorageConfig} from \"./LibFacetStorage.sol\";\n\n/**\n * @title LibGuardian\n * @dev Internal Library to provide utility feature for Guardians stored in Guardian Facet Storage\n * @author David Yongjun Kim (@Powerstream3604)\n */\nlibrary LibGuardian {\n function majorityOfGuardians()\n internal\n view\n returns (uint256 guardianNumber)\n {\n uint256 guardianLength = guardianCount();\n guardianNumber = (guardianLength == 0) ? 0 : guardianLength / 2 + 1;\n }\n\n function isGuardian(address _guardian) internal view returns (bool) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n return config.info[_guardian].exists;\n }\n\n function guardianCount() internal view returns (uint256) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n return config.addresses.length;\n }\n\n function getGuardians() internal view returns (address[] memory) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n address[] memory addresses = new address[](config.addresses.length);\n uint256 addressesLen = config.addresses.length;\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n return addresses;\n }\n}\n" + }, + "contracts/libraries/LibLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {LibDiamond} from \"./LibDiamond.sol\";\n\n/**\n * @title LibLoupe\n * @dev Internal Library to provide utility feature for reading the state of diamond facets\n * @author David Yongjun Kim (@Powerstream3604)\n */\nlibrary LibLoupe {\n /// @notice Gets all facets and their selectors.\n /// @return facets_ Facet\n function facets()\n internal\n view\n returns (IDiamondLoupe.Facet[] memory facets_)\n {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facets_ = new IDiamondLoupe.Facet[](ds.selectorCount);\n uint16[] memory numFacetSelectors = new uint16[](ds.selectorCount);\n uint256 numFacets;\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facetAddress_ = address(bytes20(ds.facets[selector]));\n bool continueLoop;\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n if (facets_[facetIndex].facetAddress == facetAddress_) {\n facets_[facetIndex].functionSelectors[\n numFacetSelectors[facetIndex]\n ] = selector;\n // probably will never have more than 256 functions from one facet contract\n require(numFacetSelectors[facetIndex] < 255);\n numFacetSelectors[facetIndex]++;\n continueLoop = true;\n break;\n }\n }\n if (continueLoop) {\n continue;\n }\n facets_[numFacets].facetAddress = facetAddress_;\n facets_[numFacets].functionSelectors = new bytes4[](\n ds.selectorCount\n );\n facets_[numFacets].functionSelectors[0] = selector;\n numFacetSelectors[numFacets] = 1;\n numFacets++;\n }\n }\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n uint256 numSelectors = numFacetSelectors[facetIndex];\n bytes4[] memory selectors = facets_[facetIndex].functionSelectors;\n // setting the number of selectors\n assembly {\n mstore(selectors, numSelectors)\n }\n }\n // setting the number of facets\n assembly {\n mstore(facets_, numFacets)\n }\n }\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n /// @return _facetFunctionSelectors The selectors associated with a facet address.\n function facetFunctionSelectors(\n address _facet\n ) internal view returns (bytes4[] memory _facetFunctionSelectors) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n uint256 numSelectors;\n _facetFunctionSelectors = new bytes4[](ds.selectorCount);\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facet = address(bytes20(ds.facets[selector]));\n if (_facet == facet) {\n _facetFunctionSelectors[numSelectors] = selector;\n numSelectors++;\n }\n }\n }\n // Set the number of selectors in the array\n assembly {\n mstore(_facetFunctionSelectors, numSelectors)\n }\n }\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses()\n internal\n view\n returns (address[] memory facetAddresses_)\n {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facetAddresses_ = new address[](ds.selectorCount);\n uint256 numFacets;\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facetAddress_ = address(bytes20(ds.facets[selector]));\n bool continueLoop;\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n if (facetAddress_ == facetAddresses_[facetIndex]) {\n continueLoop = true;\n break;\n }\n }\n if (continueLoop) {\n continue;\n }\n facetAddresses_[numFacets] = facetAddress_;\n numFacets++;\n }\n }\n // Set the number of facet addresses in the array\n assembly {\n mstore(facetAddresses_, numFacets)\n }\n }\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(\n bytes4 _functionSelector\n ) internal view returns (address facetAddress_) {\n facetAddress_ = address(\n bytes20(LibDiamond.diamondStorage().facets[_functionSelector])\n );\n }\n}\n" + }, + "contracts/libraries/LibMultiSigStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Multi-sig Storage\n * @dev Storage contract for storing Multi-sig Facet variables in diamond storage pattern\n * @author David Yongjun Kim (@Powerstream3604)\n */\n\nstruct MultiSigStorage {\n mapping(address => address) owners;\n mapping(uint256 => mapping(address => mapping(bytes32 => uint256))) approvedHashes;\n uint256 ownerCount;\n uint256 threshold;\n uint256 counter;\n}\n\nlibrary LibMultiSigStorage {\n function multisigStorage()\n internal\n pure\n returns (MultiSigStorage storage ds)\n {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.MultiSigStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n}\n" + }, + "contracts/libraries/LibRecoverSpender.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title RecoverSpender\n * @dev Library to determine the action and spender of calldata\n * @author Ruslan Serebriakov (@rsrbk)\n */\nlibrary LibRecoverSpender {\n // ERC20, ERC721 & ERC1155 transfers & approvals\n bytes4 private constant ERC20_TRANSFER =\n bytes4(keccak256(\"transfer(address,uint256)\"));\n bytes4 private constant ERC20_APPROVE =\n bytes4(keccak256(\"approve(address,uint256)\"));\n bytes4 private constant ERC20_INCREASE_ALLOWANCE =\n bytes4(keccak256(\"increaseAllowance(address,uint256)\"));\n bytes4 private constant ERC20_DECREASE_ALLOWANCE =\n bytes4(keccak256(\"decreaseAllowance(address,uint256)\"));\n bytes4 private constant ERC721_SET_APPROVAL_FOR_ALL =\n bytes4(keccak256(\"setApprovalForAll(address,bool)\"));\n bytes4 private constant ERC721_TRANSFER_FROM =\n bytes4(keccak256(\"transferFrom(address,address,uint256)\"));\n bytes4 private constant ERC721_SAFE_TRANSFER_FROM =\n bytes4(keccak256(\"safeTransferFrom(address,address,uint256)\"));\n bytes4 private constant ERC721_SAFE_TRANSFER_FROM_BYTES =\n bytes4(keccak256(\"safeTransferFrom(address,address,uint256,bytes)\"));\n bytes4 private constant ERC1155_SAFE_TRANSFER_FROM =\n bytes4(\n keccak256(\"safeTransferFrom(address,address,uint256,uint256,bytes)\")\n );\n bytes4 private constant ERC1155_SAFE_BATCH_TRANSFER_FROM =\n bytes4(\n keccak256(\n \"safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)\"\n )\n );\n\n /**\n * @notice Helper method to recover the spender from a contract call.\n * The method returns the contract unless the call is to a standard method of a ERC20/ERC721/ERC1155 token\n * in which case the spender is recovered from the data.\n * @param _to The target contract.\n * @param _data The data payload.\n */\n function _recover(\n address _to,\n bytes memory _data\n ) internal pure returns (address spender) {\n if (_data.length >= 68) {\n bytes4 methodId;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n methodId := mload(add(_data, 0x20))\n }\n if (\n methodId == ERC20_TRANSFER ||\n methodId == ERC20_APPROVE ||\n methodId == ERC20_INCREASE_ALLOWANCE ||\n methodId == ERC20_DECREASE_ALLOWANCE ||\n methodId == ERC721_SET_APPROVAL_FOR_ALL\n ) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n spender := mload(add(_data, 0x24))\n }\n return spender;\n }\n if (\n methodId == ERC721_TRANSFER_FROM ||\n methodId == ERC721_SAFE_TRANSFER_FROM ||\n methodId == ERC721_SAFE_TRANSFER_FROM_BYTES ||\n methodId == ERC1155_SAFE_TRANSFER_FROM ||\n methodId == ERC1155_SAFE_BATCH_TRANSFER_FROM\n ) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n spender := mload(add(_data, 0x44))\n }\n return spender;\n }\n }\n\n spender = _to;\n }\n}\n" + }, + "contracts/libraries/LibUtils.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\n\nlibrary LibUtils {\n // Internal utility functions\n function mergeArrays(\n bytes4[] memory _array1,\n bytes4[] memory _array2\n ) internal pure returns (bytes4[] memory) {\n uint256 length1 = _array1.length;\n uint256 length2 = _array2.length;\n bytes4[] memory mergedArray = new bytes4[](length1 + length2);\n\n for (uint256 i; i < length1; ) {\n mergedArray[i] = _array1[i];\n unchecked {\n ++i;\n }\n }\n\n for (uint256 i; i < length2; ) {\n mergedArray[length1 + i] = _array2[i];\n unchecked {\n ++i;\n }\n }\n\n return mergedArray;\n }\n\n function removeFacetElement(\n IDiamondLoupe.Facet[] memory _facets,\n uint256 _index\n ) internal pure returns (IDiamondLoupe.Facet[] memory) {\n require(_index < _facets.length, \"Invalid index\");\n require(_facets.length != 0, \"Invalid array\");\n\n // Create a new array with a length of `_facets.length - 1`\n IDiamondLoupe.Facet[] memory newArray = new IDiamondLoupe.Facet[](\n _facets.length - 1\n );\n uint256 newArrayLength = newArray.length;\n // Iterate over the original array, skipping the element at the specified `index`\n for (uint256 i; i < newArrayLength; ) {\n if (i < _index) {\n newArray[i] = _facets[i];\n } else {\n newArray[i] = _facets[i + 1];\n }\n unchecked {\n ++i;\n }\n }\n\n return newArray;\n }\n\n function removeElement(\n bytes4[] memory _array,\n uint256 _index\n ) internal pure returns (bytes4[] memory) {\n require(_index < _array.length, \"Invalid index\");\n require(_array.length != 0, \"Invalid array\");\n\n bytes4[] memory newArray = new bytes4[](_array.length - 1);\n uint256 newArrayLength = newArray.length;\n for (uint256 i; i < newArrayLength; ) {\n if (i < _index) {\n newArray[i] = _array[i];\n } else {\n newArray[i] = _array[i + 1];\n }\n unchecked {\n ++i;\n }\n }\n\n return newArray;\n }\n\n function setValue(\n bytes4[] memory _keys,\n address[] memory _values,\n bytes4 _key,\n address _value\n ) internal pure returns (bytes4[] memory, address[] memory) {\n uint256 index = findIndex(_keys, _key);\n uint256 keysLength = _keys.length;\n if (index < keysLength) {\n _values[index] = _value;\n } else {\n // Create new storage arrays\n bytes4[] memory newKeys = new bytes4[](keysLength + 1);\n address[] memory newValues = new address[](_values.length + 1);\n\n // Copy values to the new storage arrays\n for (uint256 i; i < keysLength; ) {\n newKeys[i] = _keys[i];\n newValues[i] = _values[i];\n\n unchecked {\n ++i;\n }\n }\n\n // Add the new key-value pair\n newKeys[keysLength] = _key;\n newValues[_values.length] = _value;\n\n return (newKeys, newValues);\n }\n\n // If the key already exists, return the original arrays\n return (_keys, _values);\n }\n\n function getValue(\n bytes4[] memory _keys,\n address[] memory _values,\n bytes4 _key\n ) internal pure returns (address) {\n uint256 index = findIndex(_keys, _key);\n if (index >= _keys.length) return address(0);\n\n return _values[index];\n }\n\n function findIndex(\n bytes4[] memory _keys,\n bytes4 _key\n ) internal pure returns (uint256) {\n uint256 keysLength = _keys.length;\n for (uint256 i; i < keysLength; ) {\n if (_keys[i] == _key) {\n return i;\n }\n unchecked {\n ++i;\n }\n }\n return keysLength;\n }\n}\n" + }, + "contracts/restrictions/IRestriction.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Interface for restrictions\n * @dev Restriction is a contract which decides whether to approve a certain kind of transaction, based on its internal logic.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface IRestriction {\n /**\n * @dev Based on restriction's internal logic, it should accept or reject a certain transaction.\n * @param from The address of the sender, that will be signing the transaction.\n * @param to The receiving address.\n * @param value Amount of ETH to transfer from sender to recipient.\n * @param _calldata Optional field to include arbitrary data.\n * @return bool value for whether the check is passed\n */\n function check(\n address from,\n address to,\n uint256 value,\n bytes calldata _calldata\n ) external returns (bool);\n}\n" + }, + "contracts/restrictions/WhitelistRestriction.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibRecoverSpender} from \"../libraries/LibRecoverSpender.sol\";\nimport {WhitelistStorage} from \"../infrastructure/WhitelistStorage.sol\";\nimport {IRestriction} from \"./IRestriction.sol\";\n\n/**\n * @title Whitelist Restriction\n * @dev This restriction defines a list of accepted addresses and denies any interaction with addresses outside of it.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract WhitelistRestriction is IRestriction {\n WhitelistStorage public immutable whitelistStorage;\n\n constructor(WhitelistStorage _whitelistStorage) {\n whitelistStorage = _whitelistStorage;\n }\n\n /**\n * @notice Helper method to recover the spender from a contract call.\n * The method returns the contract unless the call is to a standard method of a ERC20/ERC721/ERC1155 token\n * in which case the spender is recovered from the data.\n * @param _to The target contract.\n * @param _data The data payload.\n */\n function recoverSpender(\n address _to,\n bytes memory _data\n ) public pure returns (address spender) {\n return LibRecoverSpender._recover(_to, _data);\n }\n\n /*\n * @dev IRestriction's implementation. It will allow transaction if the sender is whitelisted, or user, or the whitelist storage.\n * @param _from The address of the sender, that will be signing the transaction.\n * @param _to The receiving address.\n * @param _calldata Optional field to include arbitrary data.\n * @return result value for whether the check is passed\n */\n function check(\n address _from,\n address _to,\n uint256 /*_value*/,\n bytes calldata _calldata\n ) external view override returns (bool result) {\n return\n whitelistStorage.isWhitelisted(\n _from,\n LibRecoverSpender._recover(_to, _calldata)\n ) ||\n _to == address(whitelistStorage) ||\n _to == msg.sender;\n }\n}\n" + }, + "contracts/test/Counter.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\ncontract TestCounter {\n int private count = 0;\n\n function incrementCounter() public {\n count += 1;\n }\n\n function decrementCounter() public {\n count -= 1;\n }\n\n function getCount() public view returns (int) {\n return count;\n }\n}\n" + }, + "contracts/test/TestERC1155.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC1155/ERC1155.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\n\ncontract TestERC1155 is ERC1155 {\n using Counters for Counters.Counter;\n\n Counters.Counter private _tokenIds;\n\n constructor() ERC1155(\"\") {}\n\n function mint(address account, uint256 amount) external {\n uint256 tokenId = _getNextTokenId();\n _mint(account, tokenId, amount, \"\");\n }\n\n function mintBatch(\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes memory data\n ) external {\n require(\n ids.length == amounts.length,\n \"TestERC1155: arrays length mismatch\"\n );\n\n _mintBatch(to, ids, amounts, data);\n }\n\n function _getNextTokenId() private returns (uint256) {\n _tokenIds.increment();\n return _tokenIds.current();\n }\n}\n" + }, + "contracts/test/TestERC777.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC777/ERC777.sol\";\n\ncontract TestERC777 is ERC777 {\n constructor(\n address[] memory _operators\n ) ERC777(\"TestERC777\", \"TERC777\", _operators) {}\n\n function mint(address account, uint256 amount) external {\n _mint(account, amount, \"\", \"\");\n }\n}\n" + }, + "contracts/test/TestInvalidSecp256k1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IVerificationFacet} from \"../facets/interfaces/IVerificationFacet.sol\";\nimport {IERC1271} from \"../interfaces/ERC/IERC1271.sol\";\nimport {AppStorage, LibAppStorage, BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {LibFacetStorage, Secp256k1VerificationStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {UserOperation} from \"../aa-4337/interfaces/UserOperation.sol\";\n\n/**\n * @title Test Secp256k1 verification facet\n * @dev Default Ethereum's elliptic curve\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract TestInvalidSecp256k1VerificationFacet is BarzStorage, IERC1271 {\n using ECDSA for bytes32;\n error Secp256k1VerificationFacet__InvalidSignerLength();\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n\n event SignerUninitialized();\n\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n }\n\n // THIS INVALID FACET DOES NOT INCLUDE initializeSigner()\n // THIS FACET IS USED TO TEST WHEN initializeSigner() DOESN'T EXIST IN FACET\n\n function uninitializeSigner() external returns (uint256 uninitSuccess) {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view returns (uint256 validationData) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n return validateSignature(userOp, userOpHash, k1Storage.signer);\n }\n\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n address signer\n ) public pure returns (uint256) {\n bytes32 hash = userOpHash.toEthSignedMessageHash();\n if (signer != hash.recover(userOp.signature)) return 1;\n return 0;\n }\n\n // This is REMOVED for testing purpose\n function validateOwnerSignatureSelector() public pure returns (bytes4) {\n // return this.validateOwnerSignature.selector;\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n function owner() public view returns (bytes memory) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n return abi.encodePacked(k1Storage.signer);\n }\n\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure returns (bool) {\n return (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (_hash.recover(_signature) ==\n LibFacetStorage.k1Storage().signer)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n}\n" + }, + "contracts/test/TestNFT.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\n\ncontract TestNFT is ERC721 {\n using Counters for Counters.Counter;\n Counters.Counter private currentTokenId;\n\n constructor() ERC721(\"TestNFT\", \"TNFT\") {}\n\n function mint(address recipient) public returns (uint256) {\n currentTokenId.increment();\n uint256 newItemId = currentTokenId.current();\n _safeMint(recipient, newItemId);\n return newItemId;\n }\n}\n" + }, + "contracts/test/TestToken.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract TestToken is ERC20 {\n constructor()\n // solhint-disable-next-line no-empty-blocks\n ERC20(\"TST\", \"TestToken\")\n {}\n\n function mint(address sender, uint256 amount) external {\n _mint(sender, amount);\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 999999 + }, + "evmVersion": "paris", + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/deployments/avalanche/solcInputs/4356503edd8ae34e73cb6dd1c8e2fc8a.json b/deployments/avalanche/solcInputs/4356503edd8ae34e73cb6dd1c8e2fc8a.json new file mode 100644 index 0000000..db88715 --- /dev/null +++ b/deployments/avalanche/solcInputs/4356503edd8ae34e73cb6dd1c8e2fc8a.json @@ -0,0 +1,354 @@ +{ + "language": "Solidity", + "sources": { + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby disabling any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable2Step.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./Ownable.sol\";\n\n/**\n * @dev Contract module which provides access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership} and {acceptOwnership}.\n *\n * This module is used through inheritance. It will make available all functions\n * from parent (Ownable).\n */\nabstract contract Ownable2Step is Ownable {\n address private _pendingOwner;\n\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Returns the address of the pending owner.\n */\n function pendingOwner() public view virtual returns (address) {\n return _pendingOwner;\n }\n\n /**\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual override onlyOwner {\n _pendingOwner = newOwner;\n emit OwnershipTransferStarted(owner(), newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual override {\n delete _pendingOwner;\n super._transferOwnership(newOwner);\n }\n\n /**\n * @dev The new owner accepts the ownership transfer.\n */\n function acceptOwnership() public virtual {\n address sender = _msgSender();\n require(pendingOwner() == sender, \"Ownable2Step: caller is not the new owner\");\n _transferOwnership(sender);\n }\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC1271.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC1271 standard signature validation method for\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\n *\n * _Available since v4.1._\n */\ninterface IERC1271 {\n /**\n * @dev Should return whether the signature provided is valid for the provided data\n * @param hash Hash of the data to be signed\n * @param signature Signature byte array associated with _data\n */\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\n}\n" + }, + "@openzeppelin/contracts/security/ReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor() {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n _nonReentrantBefore();\n _;\n _nonReentrantAfter();\n }\n\n function _nonReentrantBefore() private {\n // On the first call to nonReentrant, _status will be _NOT_ENTERED\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n }\n\n function _nonReentrantAfter() private {\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Returns true if the reentrancy guard is currently set to \"entered\", which indicates there is a\n * `nonReentrant` function in the call stack.\n */\n function _reentrancyGuardEntered() internal view returns (bool) {\n return _status == _ENTERED;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/ERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/ERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC1155.sol\";\nimport \"./IERC1155Receiver.sol\";\nimport \"./extensions/IERC1155MetadataURI.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of the basic standard multi-token.\n * See https://eips.ethereum.org/EIPS/eip-1155\n * Originally based on code by Enjin: https://github.com/enjin/erc-1155\n *\n * _Available since v3.1._\n */\ncontract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {\n using Address for address;\n\n // Mapping from token ID to account balances\n mapping(uint256 => mapping(address => uint256)) private _balances;\n\n // Mapping from account to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json\n string private _uri;\n\n /**\n * @dev See {_setURI}.\n */\n constructor(string memory uri_) {\n _setURI(uri_);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return\n interfaceId == type(IERC1155).interfaceId ||\n interfaceId == type(IERC1155MetadataURI).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC1155MetadataURI-uri}.\n *\n * This implementation returns the same URI for *all* token types. It relies\n * on the token type ID substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * Clients calling this function must replace the `\\{id\\}` substring with the\n * actual token type ID.\n */\n function uri(uint256) public view virtual override returns (string memory) {\n return _uri;\n }\n\n /**\n * @dev See {IERC1155-balanceOf}.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {\n require(account != address(0), \"ERC1155: address zero is not a valid owner\");\n return _balances[id][account];\n }\n\n /**\n * @dev See {IERC1155-balanceOfBatch}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] memory accounts,\n uint256[] memory ids\n ) public view virtual override returns (uint256[] memory) {\n require(accounts.length == ids.length, \"ERC1155: accounts and ids length mismatch\");\n\n uint256[] memory batchBalances = new uint256[](accounts.length);\n\n for (uint256 i = 0; i < accounts.length; ++i) {\n batchBalances[i] = balanceOf(accounts[i], ids[i]);\n }\n\n return batchBalances;\n }\n\n /**\n * @dev See {IERC1155-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC1155-isApprovedForAll}.\n */\n function isApprovedForAll(address account, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[account][operator];\n }\n\n /**\n * @dev See {IERC1155-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n _safeTransferFrom(from, to, id, amount, data);\n }\n\n /**\n * @dev See {IERC1155-safeBatchTransferFrom}.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n _safeBatchTransferFrom(from, to, ids, amounts, data);\n }\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n\n emit TransferSingle(operator, from, to, id, amount);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n for (uint256 i = 0; i < ids.length; ++i) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n }\n\n emit TransferBatch(operator, from, to, ids, amounts);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\n\n _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);\n }\n\n /**\n * @dev Sets a new URI for all token types, by relying on the token type ID\n * substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * By this mechanism, any occurrence of the `\\{id\\}` substring in either the\n * URI or any of the amounts in the JSON file at said URI will be replaced by\n * clients with the token type ID.\n *\n * For example, the `https://token-cdn-domain/\\{id\\}.json` URI would be\n * interpreted by clients as\n * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`\n * for token type ID 0x4cce0.\n *\n * See {uri}.\n *\n * Because these URIs cannot be meaningfully represented by the {URI} event,\n * this function emits no events.\n */\n function _setURI(string memory newuri) internal virtual {\n _uri = newuri;\n }\n\n /**\n * @dev Creates `amount` tokens of token type `id`, and assigns them to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _mint(address to, uint256 id, uint256 amount, bytes memory data) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _balances[id][to] += amount;\n emit TransferSingle(operator, address(0), to, id, amount);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n for (uint256 i = 0; i < ids.length; i++) {\n _balances[ids[i]][to] += amounts[i];\n }\n\n emit TransferBatch(operator, address(0), to, ids, amounts);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);\n }\n\n /**\n * @dev Destroys `amount` tokens of token type `id` from `from`\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `from` must have at least `amount` tokens of token type `id`.\n */\n function _burn(address from, uint256 id, uint256 amount) internal virtual {\n require(from != address(0), \"ERC1155: burn from the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n\n emit TransferSingle(operator, from, address(0), id, amount);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n */\n function _burnBatch(address from, uint256[] memory ids, uint256[] memory amounts) internal virtual {\n require(from != address(0), \"ERC1155: burn from the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n\n for (uint256 i = 0; i < ids.length; i++) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n }\n\n emit TransferBatch(operator, from, address(0), ids, amounts);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {\n require(owner != operator, \"ERC1155: setting approval status for self\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning, as well as batched variants.\n *\n * The same hook is called on both single and batched variants. For single\n * transfers, the length of the `ids` and `amounts` arrays will be 1.\n *\n * Calling conditions (for each `id` and `amount` pair):\n *\n * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * of token type `id` will be transferred to `to`.\n * - When `from` is zero, `amount` tokens of token type `id` will be minted\n * for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n * will be burned.\n * - `from` and `to` are never both zero.\n * - `ids` and `amounts` have the same, non-zero length.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any token transfer. This includes minting\n * and burning, as well as batched variants.\n *\n * The same hook is called on both single and batched variants. For single\n * transfers, the length of the `id` and `amount` arrays will be 1.\n *\n * Calling conditions (for each `id` and `amount` pair):\n *\n * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * of token type `id` will be transferred to `to`.\n * - When `from` is zero, `amount` tokens of token type `id` will be minted\n * for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n * will be burned.\n * - `from` and `to` are never both zero.\n * - `ids` and `amounts` have the same, non-zero length.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {}\n\n function _doSafeTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155Receiver.onERC1155Received.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non-ERC1155Receiver implementer\");\n }\n }\n }\n\n function _doSafeBatchTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (\n bytes4 response\n ) {\n if (response != IERC1155Receiver.onERC1155BatchReceived.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non-ERC1155Receiver implementer\");\n }\n }\n }\n\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {\n uint256[] memory array = new uint256[](1);\n array[0] = element;\n\n return array;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC1155.sol\";\n\n/**\n * @dev Interface of the optional ERC1155MetadataExtension interface, as defined\n * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155MetadataURI is IERC1155 {\n /**\n * @dev Returns the URI for token type `id`.\n *\n * If the `\\{id\\}` substring is present in the URI, it must be replaced by\n * clients with the actual token type ID.\n */\n function uri(uint256 id) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155 is IERC165 {\n /**\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n */\n event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);\n\n /**\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n * transfers.\n */\n event TransferBatch(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\n\n /**\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n * `approved`.\n */\n event ApprovalForAll(address indexed account, address indexed operator, bool approved);\n\n /**\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n *\n * If an {URI} event was emitted for `id`, the standard\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n * returned by {IERC1155MetadataURI-uri}.\n */\n event URI(string value, uint256 indexed id);\n\n /**\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) external view returns (uint256);\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] calldata accounts,\n uint256[] calldata ids\n ) external view returns (uint256[] memory);\n\n /**\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n *\n * Emits an {ApprovalForAll} event.\n *\n * Requirements:\n *\n * - `operator` cannot be the caller.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n *\n * See {setApprovalForAll}.\n */\n function isApprovedForAll(address account, address operator) external view returns (bool);\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155Receiver is IERC165 {\n /**\n * @dev Handles the receipt of a single ERC1155 token type. This function is\n * called at the end of a `safeTransferFrom` after the balance has been updated.\n *\n * NOTE: To accept the transfer, this must return\n * `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n * (i.e. 0xf23a6e61, or its own function selector).\n *\n * @param operator The address which initiated the transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param id The ID of the token being transferred\n * @param value The amount of tokens being transferred\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n ) external returns (bytes4);\n\n /**\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\n * is called at the end of a `safeBatchTransferFrom` after the balances have\n * been updated.\n *\n * NOTE: To accept the transfer(s), this must return\n * `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n * (i.e. 0xbc197c81, or its own function selector).\n *\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the default value returned by this function, unless\n * it's overridden.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(address from, address to, uint256 amount) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\n // decrementing then incrementing.\n _balances[to] += amount;\n }\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n unchecked {\n // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\n _balances[account] += amount;\n }\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n // Overflow not possible: amount <= accountBalance <= totalSupply.\n _totalSupply -= amount;\n }\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\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" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` 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 amount) 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 `amount` as the allowance of `spender` over the 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 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` 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 amount) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/ERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721.sol\";\nimport \"./IERC721Receiver.sol\";\nimport \"./extensions/IERC721Metadata.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/Strings.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\n using Address for address;\n using Strings for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\n\n // Mapping from token ID to approved address\n mapping(uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return\n interfaceId == type(IERC721).interfaceId ||\n interfaceId == type(IERC721Metadata).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _ownerOf(tokenId);\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token owner or approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n _requireMinted(tokenId);\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n _safeTransfer(from, to, tokenId, data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(address from, address to, uint256 tokenId, bytes memory data) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist\n */\n function _ownerOf(uint256 tokenId) internal view virtual returns (address) {\n return _owners[tokenId];\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _ownerOf(tokenId) != address(0);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n address owner = ERC721.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(address to, uint256 tokenId, bytes memory data) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId, 1);\n\n // Check that tokenId was not minted by `_beforeTokenTransfer` hook\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n unchecked {\n // Will not overflow unless all 2**256 token ids are minted to the same owner.\n // Given that tokens are minted one by one, it is impossible in practice that\n // this ever happens. Might change if we allow batch minting.\n // The ERC fails to describe this case.\n _balances[to] += 1;\n }\n\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(address(0), to, tokenId, 1);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n * This is an internal function that does not check if the sender is authorized to operate on the token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId, 1);\n\n // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook\n owner = ERC721.ownerOf(tokenId);\n\n // Clear approvals\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // Cannot overflow, as that would require more tokens to be burned/transferred\n // out than the owner initially received through minting and transferring in.\n _balances[owner] -= 1;\n }\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(owner, address(0), tokenId, 1);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(address from, address to, uint256 tokenId) internal virtual {\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId, 1);\n\n // Check that tokenId was not transferred by `_beforeTokenTransfer` hook\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n\n // Clear approvals from the previous owner\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // `_balances[from]` cannot overflow for the same reason as described in `_burn`:\n // `from`'s balance is the number of token held, which is at least one before the current\n // transfer.\n // `_balances[to]` could overflow in the conditions described in `_mint`. That would require\n // all 2**256 token ids to be minted, which in practice is impossible.\n _balances[from] -= 1;\n _balances[to] += 1;\n }\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId, 1);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721Receiver.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`.\n * - When `from` is zero, the tokens will be minted for `to`.\n * - When `to` is zero, ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}\n\n /**\n * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`.\n * - When `from` is zero, the tokens were minted for `to`.\n * - When `to` is zero, ``from``'s tokens were burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}\n\n /**\n * @dev Unsafe write access to the balances, used by extensions that \"mint\" tokens using an {ownerOf} override.\n *\n * WARNING: Anyone calling this MUST ensure that the balances remain consistent with the ownership. The invariant\n * being that for any address `a` the value returned by `balanceOf(a)` must be equal to the number of tokens such\n * that `ownerOf(tokenId)` is `a`.\n */\n // solhint-disable-next-line func-name-mixedcase\n function __unsafe_increaseBalance(address account, uint256 amount) internal {\n _balances[account] += amount;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721Receiver {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/ERC777.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC777/ERC777.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC777.sol\";\nimport \"./IERC777Recipient.sol\";\nimport \"./IERC777Sender.sol\";\nimport \"../ERC20/IERC20.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/introspection/IERC1820Registry.sol\";\n\n/**\n * @dev Implementation of the {IERC777} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n *\n * Support for ERC20 is included in this contract, as specified by the EIP: both\n * the ERC777 and ERC20 interfaces can be safely used when interacting with it.\n * Both {IERC777-Sent} and {IERC20-Transfer} events are emitted on token\n * movements.\n *\n * Additionally, the {IERC777-granularity} value is hard-coded to `1`, meaning that there\n * are no special restrictions in the amount of tokens that created, moved, or\n * destroyed. This makes integration with ERC20 applications seamless.\n *\n * CAUTION: This file is deprecated as of v4.9 and will be removed in the next major release.\n */\ncontract ERC777 is Context, IERC777, IERC20 {\n using Address for address;\n\n IERC1820Registry internal constant _ERC1820_REGISTRY = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n mapping(address => uint256) private _balances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n bytes32 private constant _TOKENS_SENDER_INTERFACE_HASH = keccak256(\"ERC777TokensSender\");\n bytes32 private constant _TOKENS_RECIPIENT_INTERFACE_HASH = keccak256(\"ERC777TokensRecipient\");\n\n // This isn't ever read from - it's only used to respond to the defaultOperators query.\n address[] private _defaultOperatorsArray;\n\n // Immutable, but accounts may revoke them (tracked in __revokedDefaultOperators).\n mapping(address => bool) private _defaultOperators;\n\n // For each account, a mapping of its operators and revoked default operators.\n mapping(address => mapping(address => bool)) private _operators;\n mapping(address => mapping(address => bool)) private _revokedDefaultOperators;\n\n // ERC20-allowances\n mapping(address => mapping(address => uint256)) private _allowances;\n\n /**\n * @dev `defaultOperators` may be an empty array.\n */\n constructor(string memory name_, string memory symbol_, address[] memory defaultOperators_) {\n _name = name_;\n _symbol = symbol_;\n\n _defaultOperatorsArray = defaultOperators_;\n for (uint256 i = 0; i < defaultOperators_.length; i++) {\n _defaultOperators[defaultOperators_[i]] = true;\n }\n\n // register interfaces\n _ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256(\"ERC777Token\"), address(this));\n _ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256(\"ERC20Token\"), address(this));\n }\n\n /**\n * @dev See {IERC777-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC777-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {ERC20-decimals}.\n *\n * Always returns 18, as per the\n * [ERC777 EIP](https://eips.ethereum.org/EIPS/eip-777#backward-compatibility).\n */\n function decimals() public pure virtual returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC777-granularity}.\n *\n * This implementation always returns `1`.\n */\n function granularity() public view virtual override returns (uint256) {\n return 1;\n }\n\n /**\n * @dev See {IERC777-totalSupply}.\n */\n function totalSupply() public view virtual override(IERC20, IERC777) returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev Returns the amount of tokens owned by an account (`tokenHolder`).\n */\n function balanceOf(address tokenHolder) public view virtual override(IERC20, IERC777) returns (uint256) {\n return _balances[tokenHolder];\n }\n\n /**\n * @dev See {IERC777-send}.\n *\n * Also emits a {IERC20-Transfer} event for ERC20 compatibility.\n */\n function send(address recipient, uint256 amount, bytes memory data) public virtual override {\n _send(_msgSender(), recipient, amount, data, \"\", true);\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Unlike `send`, `recipient` is _not_ required to implement the {IERC777Recipient}\n * interface if it is a contract.\n *\n * Also emits a {Sent} event.\n */\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n _send(_msgSender(), recipient, amount, \"\", \"\", false);\n return true;\n }\n\n /**\n * @dev See {IERC777-burn}.\n *\n * Also emits a {IERC20-Transfer} event for ERC20 compatibility.\n */\n function burn(uint256 amount, bytes memory data) public virtual override {\n _burn(_msgSender(), amount, data, \"\");\n }\n\n /**\n * @dev See {IERC777-isOperatorFor}.\n */\n function isOperatorFor(address operator, address tokenHolder) public view virtual override returns (bool) {\n return\n operator == tokenHolder ||\n (_defaultOperators[operator] && !_revokedDefaultOperators[tokenHolder][operator]) ||\n _operators[tokenHolder][operator];\n }\n\n /**\n * @dev See {IERC777-authorizeOperator}.\n */\n function authorizeOperator(address operator) public virtual override {\n require(_msgSender() != operator, \"ERC777: authorizing self as operator\");\n\n if (_defaultOperators[operator]) {\n delete _revokedDefaultOperators[_msgSender()][operator];\n } else {\n _operators[_msgSender()][operator] = true;\n }\n\n emit AuthorizedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-revokeOperator}.\n */\n function revokeOperator(address operator) public virtual override {\n require(operator != _msgSender(), \"ERC777: revoking self as operator\");\n\n if (_defaultOperators[operator]) {\n _revokedDefaultOperators[_msgSender()][operator] = true;\n } else {\n delete _operators[_msgSender()][operator];\n }\n\n emit RevokedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-defaultOperators}.\n */\n function defaultOperators() public view virtual override returns (address[] memory) {\n return _defaultOperatorsArray;\n }\n\n /**\n * @dev See {IERC777-operatorSend}.\n *\n * Emits {Sent} and {IERC20-Transfer} events.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes memory data,\n bytes memory operatorData\n ) public virtual override {\n require(isOperatorFor(_msgSender(), sender), \"ERC777: caller is not an operator for holder\");\n _send(sender, recipient, amount, data, operatorData, true);\n }\n\n /**\n * @dev See {IERC777-operatorBurn}.\n *\n * Emits {Burned} and {IERC20-Transfer} events.\n */\n function operatorBurn(\n address account,\n uint256 amount,\n bytes memory data,\n bytes memory operatorData\n ) public virtual override {\n require(isOperatorFor(_msgSender(), account), \"ERC777: caller is not an operator for holder\");\n _burn(account, amount, data, operatorData);\n }\n\n /**\n * @dev See {IERC20-allowance}.\n *\n * Note that operator and allowance concepts are orthogonal: operators may\n * not have allowance, and accounts with allowance may not be operators\n * themselves.\n */\n function allowance(address holder, address spender) public view virtual override returns (uint256) {\n return _allowances[holder][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Note that accounts cannot have allowance issued by their operators.\n */\n function approve(address spender, uint256 value) public virtual override returns (bool) {\n address holder = _msgSender();\n _approve(holder, spender, value);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Note that operator and allowance concepts are orthogonal: operators cannot\n * call `transferFrom` (unless they have allowance), and accounts with\n * allowance cannot call `operatorSend` (unless they are operators).\n *\n * Emits {Sent}, {IERC20-Transfer} and {IERC20-Approval} events.\n */\n function transferFrom(address holder, address recipient, uint256 amount) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(holder, spender, amount);\n _send(holder, recipient, amount, \"\", \"\", false);\n return true;\n }\n\n /**\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with the caller address as the `operator` and with\n * `userData` and `operatorData`.\n *\n * See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits {Minted} and {IERC20-Transfer} events.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - if `account` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function _mint(address account, uint256 amount, bytes memory userData, bytes memory operatorData) internal virtual {\n _mint(account, amount, userData, operatorData, true);\n }\n\n /**\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * If `requireReceptionAck` is set to true, and if a send hook is\n * registered for `account`, the corresponding function will be called with\n * `operator`, `data` and `operatorData`.\n *\n * See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits {Minted} and {IERC20-Transfer} events.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - if `account` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function _mint(\n address account,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) internal virtual {\n require(account != address(0), \"ERC777: mint to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), account, amount);\n\n // Update state variables\n _totalSupply += amount;\n _balances[account] += amount;\n\n _callTokensReceived(operator, address(0), account, amount, userData, operatorData, requireReceptionAck);\n\n emit Minted(operator, account, amount, userData, operatorData);\n emit Transfer(address(0), account, amount);\n }\n\n /**\n * @dev Send tokens\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _send(\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) internal virtual {\n require(from != address(0), \"ERC777: transfer from the zero address\");\n require(to != address(0), \"ERC777: transfer to the zero address\");\n\n address operator = _msgSender();\n\n _callTokensToSend(operator, from, to, amount, userData, operatorData);\n\n _move(operator, from, to, amount, userData, operatorData);\n\n _callTokensReceived(operator, from, to, amount, userData, operatorData, requireReceptionAck);\n }\n\n /**\n * @dev Burn tokens\n * @param from address token holder address\n * @param amount uint256 amount of tokens to burn\n * @param data bytes extra information provided by the token holder\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _burn(address from, uint256 amount, bytes memory data, bytes memory operatorData) internal virtual {\n require(from != address(0), \"ERC777: burn from the zero address\");\n\n address operator = _msgSender();\n\n _callTokensToSend(operator, from, address(0), amount, data, operatorData);\n\n _beforeTokenTransfer(operator, from, address(0), amount);\n\n // Update state variables\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC777: burn amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Burned(operator, from, amount, data, operatorData);\n emit Transfer(from, address(0), amount);\n }\n\n function _move(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n ) private {\n _beforeTokenTransfer(operator, from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC777: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Sent(operator, from, to, amount, userData, operatorData);\n emit Transfer(from, to, amount);\n }\n\n /**\n * @dev See {ERC20-_approve}.\n *\n * Note that accounts cannot have allowance issued by their operators.\n */\n function _approve(address holder, address spender, uint256 value) internal virtual {\n require(holder != address(0), \"ERC777: approve from the zero address\");\n require(spender != address(0), \"ERC777: approve to the zero address\");\n\n _allowances[holder][spender] = value;\n emit Approval(holder, spender, value);\n }\n\n /**\n * @dev Call from.tokensToSend() if the interface is registered\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _callTokensToSend(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n ) private {\n address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(from, _TOKENS_SENDER_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Sender(implementer).tokensToSend(operator, from, to, amount, userData, operatorData);\n }\n }\n\n /**\n * @dev Call to.tokensReceived() if the interface is registered. Reverts if the recipient is a contract but\n * tokensReceived() was not registered for the recipient\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _callTokensReceived(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) private {\n address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(to, _TOKENS_RECIPIENT_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Recipient(implementer).tokensReceived(operator, from, to, amount, userData, operatorData);\n } else if (requireReceptionAck) {\n require(!to.isContract(), \"ERC777: token recipient contract has no implementer for ERC777TokensRecipient\");\n }\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {IERC20-Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC777: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes\n * calls to {send}, {transfer}, {operatorSend}, {transferFrom}, minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be to transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address operator, address from, address to, uint256 amount) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC777/IERC777.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777Token standard as defined in the EIP.\n *\n * This contract uses the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 registry standard] to let\n * token holders and recipients react to token movements by using setting implementers\n * for the associated interfaces in said registry. See {IERC1820Registry} and\n * {ERC1820Implementer}.\n */\ninterface IERC777 {\n /**\n * @dev Emitted when `amount` tokens are created by `operator` and assigned to `to`.\n *\n * Note that some additional user `data` and `operatorData` can be logged in the event.\n */\n event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);\n\n /**\n * @dev Emitted when `operator` destroys `amount` tokens from `account`.\n *\n * Note that some additional user `data` and `operatorData` can be logged in the event.\n */\n event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);\n\n /**\n * @dev Emitted when `operator` is made operator for `tokenHolder`.\n */\n event AuthorizedOperator(address indexed operator, address indexed tokenHolder);\n\n /**\n * @dev Emitted when `operator` is revoked its operator status for `tokenHolder`.\n */\n event RevokedOperator(address indexed operator, address indexed tokenHolder);\n\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, usually a shorter version of the\n * name.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the smallest part of the token that is not divisible. This\n * means all token operations (creation, movement and destruction) must have\n * amounts that are a multiple of this number.\n *\n * For most token contracts, this value will equal 1.\n */\n function granularity() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by an account (`owner`).\n */\n function balanceOf(address owner) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * If send or receive hooks are registered for the caller and `recipient`,\n * the corresponding functions will be called with `data` and empty\n * `operatorData`. See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits a {Sent} event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function send(address recipient, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Destroys `amount` tokens from the caller's account, reducing the\n * total supply.\n *\n * If a send hook is registered for the caller, the corresponding function\n * will be called with `data` and empty `operatorData`. See {IERC777Sender}.\n *\n * Emits a {Burned} event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n */\n function burn(uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Returns true if an account is an operator of `tokenHolder`.\n * Operators can send and burn tokens on behalf of their owners. All\n * accounts are their own operator.\n *\n * See {operatorSend} and {operatorBurn}.\n */\n function isOperatorFor(address operator, address tokenHolder) external view returns (bool);\n\n /**\n * @dev Make an account an operator of the caller.\n *\n * See {isOperatorFor}.\n *\n * Emits an {AuthorizedOperator} event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function authorizeOperator(address operator) external;\n\n /**\n * @dev Revoke an account's operator status for the caller.\n *\n * See {isOperatorFor} and {defaultOperators}.\n *\n * Emits a {RevokedOperator} event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function revokeOperator(address operator) external;\n\n /**\n * @dev Returns the list of default operators. These accounts are operators\n * for all token holders, even if {authorizeOperator} was never called on\n * them.\n *\n * This list is immutable, but individual holders may revoke these via\n * {revokeOperator}, in which case {isOperatorFor} will return false.\n */\n function defaultOperators() external view returns (address[] memory);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must\n * be an operator of `sender`.\n *\n * If send or receive hooks are registered for `sender` and `recipient`,\n * the corresponding functions will be called with `data` and\n * `operatorData`. See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits a {Sent} event.\n *\n * Requirements\n *\n * - `sender` cannot be the zero address.\n * - `sender` must have at least `amount` tokens.\n * - the caller must be an operator for `sender`.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes calldata data,\n bytes calldata operatorData\n ) external;\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the total supply.\n * The caller must be an operator of `account`.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with `data` and `operatorData`. See {IERC777Sender}.\n *\n * Emits a {Burned} event.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n * - the caller must be an operator for `account`.\n */\n function operatorBurn(address account, uint256 amount, bytes calldata data, bytes calldata operatorData) external;\n\n event Sent(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes data,\n bytes operatorData\n );\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\n *\n * Accounts can be notified of {IERC777} tokens being sent to them by having a\n * contract implement this interface (contract holders can be their own\n * implementer) and registering it on the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\n *\n * See {IERC1820Registry} and {ERC1820Implementer}.\n */\ninterface IERC777Recipient {\n /**\n * @dev Called by an {IERC777} token contract whenever tokens are being\n * moved or created into a registered account (`to`). The type of operation\n * is conveyed by `from` being the zero address or not.\n *\n * This call occurs _after_ the token contract's state is updated, so\n * {IERC777-balanceOf}, etc., can be used to query the post-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensReceived(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777Sender.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Sender.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777TokensSender standard as defined in the EIP.\n *\n * {IERC777} Token holders can be notified of operations performed on their\n * tokens by having a contract implement this interface (contract holders can be\n * their own implementer) and registering it on the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\n *\n * See {IERC1820Registry} and {ERC1820Implementer}.\n */\ninterface IERC777Sender {\n /**\n * @dev Called by an {IERC777} token contract whenever a registered holder's\n * (`from`) tokens are about to be moved or destroyed. The type of operation\n * is conveyed by `to` being the zero address or not.\n *\n * This call occurs _before_ the token contract's state is updated, so\n * {IERC777-balanceOf}, etc., can be used to query the pre-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensToSend(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n *\n * Furthermore, `isContract` will also return true if the target contract within\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n * which only has an effect at the end of a transaction.\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Counters.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary Counters {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/ECDSA.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Strings.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV // Deprecated in v4.8\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n /// @solidity memory-safe-assembly\n assembly {\n mstore(0x00, \"\\x19Ethereum Signed Message:\\n32\")\n mstore(0x1c, hash)\n message := keccak256(0x00, 0x3c)\n }\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\n /// @solidity memory-safe-assembly\n assembly {\n let ptr := mload(0x40)\n mstore(ptr, \"\\x19\\x01\")\n mstore(add(ptr, 0x02), domainSeparator)\n mstore(add(ptr, 0x22), structHash)\n data := keccak256(ptr, 0x42)\n }\n }\n\n /**\n * @dev Returns an Ethereum Signed Data with intended validator, created from a\n * `validator` and `data` according to the version 0 of EIP-191.\n *\n * See {recover}.\n */\n function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x00\", validator, data));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/SignatureChecker.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSA.sol\";\nimport \"../../interfaces/IERC1271.sol\";\n\n/**\n * @dev Signature verification helper that can be used instead of `ECDSA.recover` to seamlessly support both ECDSA\n * signatures from externally owned accounts (EOAs) as well as ERC1271 signatures from smart contract wallets like\n * Argent and Gnosis Safe.\n *\n * _Available since v4.1._\n */\nlibrary SignatureChecker {\n /**\n * @dev Checks if a signature is valid for a given signer and data hash. If the signer is a smart contract, the\n * signature is validated against that smart contract using ERC1271, otherwise it's validated using `ECDSA.recover`.\n *\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\n */\n function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature) internal view returns (bool) {\n (address recovered, ECDSA.RecoverError error) = ECDSA.tryRecover(hash, signature);\n return\n (error == ECDSA.RecoverError.NoError && recovered == signer) ||\n isValidERC1271SignatureNow(signer, hash, signature);\n }\n\n /**\n * @dev Checks if a signature is valid for a given signer and data hash. The signature is validated\n * against the signer smart contract using ERC1271.\n *\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\n */\n function isValidERC1271SignatureNow(\n address signer,\n bytes32 hash,\n bytes memory signature\n ) internal view returns (bool) {\n (bool success, bytes memory result) = signer.staticcall(\n abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, signature)\n );\n return (success &&\n result.length >= 32 &&\n abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/ERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165 is IERC165 {\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165).interfaceId;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC1820Registry.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/introspection/IERC1820Registry.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the global ERC1820 Registry, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register\n * implementers for interfaces in this registry, as well as query support.\n *\n * Implementers may be shared by multiple accounts, and can also implement more\n * than a single interface for each account. Contracts can implement interfaces\n * for themselves, but externally-owned accounts (EOA) must delegate this to a\n * contract.\n *\n * {IERC165} interfaces can also be queried via the registry.\n *\n * For an in-depth explanation and source code analysis, see the EIP text.\n */\ninterface IERC1820Registry {\n event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer);\n\n event ManagerChanged(address indexed account, address indexed newManager);\n\n /**\n * @dev Sets `newManager` as the manager for `account`. A manager of an\n * account is able to set interface implementers for it.\n *\n * By default, each account is its own manager. Passing a value of `0x0` in\n * `newManager` will reset the manager to this initial state.\n *\n * Emits a {ManagerChanged} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `account`.\n */\n function setManager(address account, address newManager) external;\n\n /**\n * @dev Returns the manager for `account`.\n *\n * See {setManager}.\n */\n function getManager(address account) external view returns (address);\n\n /**\n * @dev Sets the `implementer` contract as ``account``'s implementer for\n * `interfaceHash`.\n *\n * `account` being the zero address is an alias for the caller's address.\n * The zero address can also be used in `implementer` to remove an old one.\n *\n * See {interfaceHash} to learn how these are created.\n *\n * Emits an {InterfaceImplementerSet} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `account`.\n * - `interfaceHash` must not be an {IERC165} interface id (i.e. it must not\n * end in 28 zeroes).\n * - `implementer` must implement {IERC1820Implementer} and return true when\n * queried for support, unless `implementer` is the caller. See\n * {IERC1820Implementer-canImplementInterfaceForAddress}.\n */\n function setInterfaceImplementer(address account, bytes32 _interfaceHash, address implementer) external;\n\n /**\n * @dev Returns the implementer of `interfaceHash` for `account`. If no such\n * implementer is registered, returns the zero address.\n *\n * If `interfaceHash` is an {IERC165} interface id (i.e. it ends with 28\n * zeroes), `account` will be queried for support of it.\n *\n * `account` being the zero address is an alias for the caller's address.\n */\n function getInterfaceImplementer(address account, bytes32 _interfaceHash) external view returns (address);\n\n /**\n * @dev Returns the interface hash for an `interfaceName`, as defined in the\n * corresponding\n * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP].\n */\n function interfaceHash(string calldata interfaceName) external pure returns (bytes32);\n\n /**\n * @notice Updates the cache with whether the contract implements an ERC165 interface or not.\n * @param account Address of the contract for which to update the cache.\n * @param interfaceId ERC165 interface for which to update the cache.\n */\n function updateERC165Cache(address account, bytes4 interfaceId) external;\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not.\n * If the result is not cached a direct lookup on the contract address is performed.\n * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling\n * {updateERC165Cache} with the contract address.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool);\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not without using or updating the cache.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/math/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\n // The surrounding unchecked block does not change this fact.\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1, \"Math: mulDiv overflow\");\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n //\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n //\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n //\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1 << (log2(a) >> 1);\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = sqrt(a);\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 2, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 128;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 64;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 32;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 16;\n }\n if (value >> 8 > 0) {\n value >>= 8;\n result += 8;\n }\n if (value >> 4 > 0) {\n value >>= 4;\n result += 4;\n }\n if (value >> 2 > 0) {\n value >>= 2;\n result += 2;\n }\n if (value >> 1 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log2(value);\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 10, rounded down, of a positive value.\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 + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 256, rounded down, of a positive value.\n * Returns 0 if given 0.\n *\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n */\n function log256(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 16;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 8;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 4;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 2;\n }\n if (value >> 8 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log256(value);\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/SafeCast.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCast {\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 * _Available since v4.7._\n */\n function toUint248(uint256 value) internal pure returns (uint248) {\n require(value <= type(uint248).max, \"SafeCast: value doesn't fit in 248 bits\");\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 * _Available since v4.7._\n */\n function toUint240(uint256 value) internal pure returns (uint240) {\n require(value <= type(uint240).max, \"SafeCast: value doesn't fit in 240 bits\");\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 * _Available since v4.7._\n */\n function toUint232(uint256 value) internal pure returns (uint232) {\n require(value <= type(uint232).max, \"SafeCast: value doesn't fit in 232 bits\");\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 * _Available since v4.2._\n */\n function toUint224(uint256 value) internal pure returns (uint224) {\n require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\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 * _Available since v4.7._\n */\n function toUint216(uint256 value) internal pure returns (uint216) {\n require(value <= type(uint216).max, \"SafeCast: value doesn't fit in 216 bits\");\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 * _Available since v4.7._\n */\n function toUint208(uint256 value) internal pure returns (uint208) {\n require(value <= type(uint208).max, \"SafeCast: value doesn't fit in 208 bits\");\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 * _Available since v4.7._\n */\n function toUint200(uint256 value) internal pure returns (uint200) {\n require(value <= type(uint200).max, \"SafeCast: value doesn't fit in 200 bits\");\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 * _Available since v4.7._\n */\n function toUint192(uint256 value) internal pure returns (uint192) {\n require(value <= type(uint192).max, \"SafeCast: value doesn't fit in 192 bits\");\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 * _Available since v4.7._\n */\n function toUint184(uint256 value) internal pure returns (uint184) {\n require(value <= type(uint184).max, \"SafeCast: value doesn't fit in 184 bits\");\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 * _Available since v4.7._\n */\n function toUint176(uint256 value) internal pure returns (uint176) {\n require(value <= type(uint176).max, \"SafeCast: value doesn't fit in 176 bits\");\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 * _Available since v4.7._\n */\n function toUint168(uint256 value) internal pure returns (uint168) {\n require(value <= type(uint168).max, \"SafeCast: value doesn't fit in 168 bits\");\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 * _Available since v4.7._\n */\n function toUint160(uint256 value) internal pure returns (uint160) {\n require(value <= type(uint160).max, \"SafeCast: value doesn't fit in 160 bits\");\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 * _Available since v4.7._\n */\n function toUint152(uint256 value) internal pure returns (uint152) {\n require(value <= type(uint152).max, \"SafeCast: value doesn't fit in 152 bits\");\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 * _Available since v4.7._\n */\n function toUint144(uint256 value) internal pure returns (uint144) {\n require(value <= type(uint144).max, \"SafeCast: value doesn't fit in 144 bits\");\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 * _Available since v4.7._\n */\n function toUint136(uint256 value) internal pure returns (uint136) {\n require(value <= type(uint136).max, \"SafeCast: value doesn't fit in 136 bits\");\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 * _Available since v2.5._\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\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 * _Available since v4.7._\n */\n function toUint120(uint256 value) internal pure returns (uint120) {\n require(value <= type(uint120).max, \"SafeCast: value doesn't fit in 120 bits\");\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 * _Available since v4.7._\n */\n function toUint112(uint256 value) internal pure returns (uint112) {\n require(value <= type(uint112).max, \"SafeCast: value doesn't fit in 112 bits\");\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 * _Available since v4.7._\n */\n function toUint104(uint256 value) internal pure returns (uint104) {\n require(value <= type(uint104).max, \"SafeCast: value doesn't fit in 104 bits\");\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 * _Available since v4.2._\n */\n function toUint96(uint256 value) internal pure returns (uint96) {\n require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\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 * _Available since v4.7._\n */\n function toUint88(uint256 value) internal pure returns (uint88) {\n require(value <= type(uint88).max, \"SafeCast: value doesn't fit in 88 bits\");\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 * _Available since v4.7._\n */\n function toUint80(uint256 value) internal pure returns (uint80) {\n require(value <= type(uint80).max, \"SafeCast: value doesn't fit in 80 bits\");\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 * _Available since v4.7._\n */\n function toUint72(uint256 value) internal pure returns (uint72) {\n require(value <= type(uint72).max, \"SafeCast: value doesn't fit in 72 bits\");\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 * _Available since v2.5._\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\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 * _Available since v4.7._\n */\n function toUint56(uint256 value) internal pure returns (uint56) {\n require(value <= type(uint56).max, \"SafeCast: value doesn't fit in 56 bits\");\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 * _Available since v4.7._\n */\n function toUint48(uint256 value) internal pure returns (uint48) {\n require(value <= type(uint48).max, \"SafeCast: value doesn't fit in 48 bits\");\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 * _Available since v4.7._\n */\n function toUint40(uint256 value) internal pure returns (uint40) {\n require(value <= type(uint40).max, \"SafeCast: value doesn't fit in 40 bits\");\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 * _Available since v2.5._\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\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 * _Available since v4.7._\n */\n function toUint24(uint256 value) internal pure returns (uint24) {\n require(value <= type(uint24).max, \"SafeCast: value doesn't fit in 24 bits\");\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 * _Available since v2.5._\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\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 * _Available since v2.5._\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\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 * _Available since v3.0._\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\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 * _Available since v4.7._\n */\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\n downcasted = int248(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 248 bits\");\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 * _Available since v4.7._\n */\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\n downcasted = int240(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 240 bits\");\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 * _Available since v4.7._\n */\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\n downcasted = int232(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 232 bits\");\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 * _Available since v4.7._\n */\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\n downcasted = int224(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 224 bits\");\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 * _Available since v4.7._\n */\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\n downcasted = int216(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 216 bits\");\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 * _Available since v4.7._\n */\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\n downcasted = int208(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 208 bits\");\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 * _Available since v4.7._\n */\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\n downcasted = int200(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 200 bits\");\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 * _Available since v4.7._\n */\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\n downcasted = int192(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 192 bits\");\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 * _Available since v4.7._\n */\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\n downcasted = int184(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 184 bits\");\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 * _Available since v4.7._\n */\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\n downcasted = int176(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 176 bits\");\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 * _Available since v4.7._\n */\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\n downcasted = int168(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 168 bits\");\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 * _Available since v4.7._\n */\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\n downcasted = int160(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 160 bits\");\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 * _Available since v4.7._\n */\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\n downcasted = int152(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 152 bits\");\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 * _Available since v4.7._\n */\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\n downcasted = int144(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 144 bits\");\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 * _Available since v4.7._\n */\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\n downcasted = int136(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 136 bits\");\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 * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\n downcasted = int128(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 128 bits\");\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 * _Available since v4.7._\n */\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\n downcasted = int120(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 120 bits\");\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 * _Available since v4.7._\n */\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\n downcasted = int112(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 112 bits\");\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 * _Available since v4.7._\n */\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\n downcasted = int104(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 104 bits\");\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 * _Available since v4.7._\n */\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\n downcasted = int96(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 96 bits\");\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 * _Available since v4.7._\n */\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\n downcasted = int88(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 88 bits\");\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 * _Available since v4.7._\n */\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\n downcasted = int80(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 80 bits\");\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 * _Available since v4.7._\n */\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\n downcasted = int72(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 72 bits\");\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 * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\n downcasted = int64(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 64 bits\");\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 * _Available since v4.7._\n */\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\n downcasted = int56(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 56 bits\");\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 * _Available since v4.7._\n */\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\n downcasted = int48(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 48 bits\");\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 * _Available since v4.7._\n */\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\n downcasted = int40(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 40 bits\");\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 * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\n downcasted = int32(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 32 bits\");\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 * _Available since v4.7._\n */\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\n downcasted = int24(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 24 bits\");\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 * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\n downcasted = int16(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 16 bits\");\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 * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\n downcasted = int8(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 8 bits\");\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 * _Available since v3.0._\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 require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/SignedMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard signed math utilities missing in the Solidity language.\n */\nlibrary SignedMath {\n /**\n * @dev Returns the largest of two signed numbers.\n */\n function max(int256 a, int256 b) internal pure returns (int256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two signed numbers.\n */\n function min(int256 a, int256 b) internal pure returns (int256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two signed numbers without overflow.\n * The result is rounded towards zero.\n */\n function average(int256 a, int256 b) internal pure returns (int256) {\n // Formula from the book \"Hacker's Delight\"\n int256 x = (a & b) + ((a ^ b) >> 1);\n return x + (int256(uint256(x) >> 255) & (a ^ b));\n }\n\n /**\n * @dev Returns the absolute unsigned value of a signed value.\n */\n function abs(int256 n) internal pure returns (uint256) {\n unchecked {\n // must be unchecked in order to support `n = type(int256).min`\n return uint256(n >= 0 ? n : -n);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/Math.sol\";\nimport \"./math/SignedMath.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n unchecked {\n uint256 length = Math.log10(value) + 1;\n string memory buffer = new string(length);\n uint256 ptr;\n /// @solidity memory-safe-assembly\n assembly {\n ptr := add(buffer, add(32, length))\n }\n while (true) {\n ptr--;\n /// @solidity memory-safe-assembly\n assembly {\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n }\n value /= 10;\n if (value == 0) break;\n }\n return buffer;\n }\n }\n\n /**\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\n */\n function toString(int256 value) internal pure returns (string memory) {\n return string(abi.encodePacked(value < 0 ? \"-\" : \"\", toString(SignedMath.abs(value))));\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n unchecked {\n return toHexString(value, Math.log256(value) + 1);\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n\n /**\n * @dev Returns true if the two strings are equal.\n */\n function equal(string memory a, string memory b) internal pure returns (bool) {\n return keccak256(bytes(a)) == keccak256(bytes(b));\n }\n}\n" + }, + "contracts/aa-4337/core/BaseAccount.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-empty-blocks */\n\nimport \"../interfaces/IAccount.sol\";\nimport \"../interfaces/IEntryPoint.sol\";\nimport \"./Helpers.sol\";\n\n/**\n * Basic account implementation.\n * this contract provides the basic logic for implementing the IAccount interface - validateUserOp\n * specific account implementation should inherit it and provide the account-specific logic\n */\nabstract contract BaseAccount is IAccount {\n using UserOperationLib for UserOperation;\n\n //return value in case of signature failure, with no time-range.\n // equivalent to _packValidationData(true,0,0);\n uint256 internal constant SIG_VALIDATION_FAILED = 1;\n\n /**\n * Return the account nonce.\n * This method returns the next sequential nonce.\n * For a nonce of a specific key, use `entrypoint.getNonce(account, key)`\n */\n function getNonce() public view virtual returns (uint256) {\n return entryPoint().getNonce(address(this), 0);\n }\n\n /**\n * return the entryPoint used by this account.\n * subclass should return the current entryPoint used by this account.\n */\n function entryPoint() public view virtual returns (IEntryPoint);\n\n /**\n * Validate user's signature and nonce.\n * subclass doesn't need to override this method. Instead, it should override the specific internal validation methods.\n */\n function validateUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 missingAccountFunds\n ) external virtual override returns (uint256 validationData) {\n _requireFromEntryPoint();\n validationData = _validateSignature(userOp, userOpHash);\n _validateNonce(userOp.nonce);\n _payPrefund(missingAccountFunds);\n }\n\n /**\n * ensure the request comes from the known entrypoint.\n */\n function _requireFromEntryPoint() internal view virtual {\n require(\n msg.sender == address(entryPoint()),\n \"account: not from EntryPoint\"\n );\n }\n\n /**\n * validate the signature is valid for this message.\n * @param userOp validate the userOp.signature field\n * @param userOpHash convenient field: the hash of the request, to check the signature against\n * (also hashes the entrypoint and chain id)\n * @return validationData signature and time-range of this operation\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * If the account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function _validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) internal virtual returns (uint256 validationData);\n\n /**\n * Validate the nonce of the UserOperation.\n * This method may validate the nonce requirement of this account.\n * e.g.\n * To limit the nonce to use sequenced UserOps only (no \"out of order\" UserOps):\n * `require(nonce < type(uint64).max)`\n * For a hypothetical account that *requires* the nonce to be out-of-order:\n * `require(nonce & type(uint64).max == 0)`\n *\n * The actual nonce uniqueness is managed by the EntryPoint, and thus no other\n * action is needed by the account itself.\n *\n * @param nonce to validate\n *\n * solhint-disable-next-line no-empty-blocks\n */\n function _validateNonce(uint256 nonce) internal view virtual {}\n\n /**\n * sends to the entrypoint (msg.sender) the missing funds for this transaction.\n * subclass MAY override this method for better funds management\n * (e.g. send to the entryPoint more than the minimum required, so that in future transactions\n * it will not be required to send again)\n * @param missingAccountFunds the minimum value this method should send the entrypoint.\n * this value MAY be zero, in case there is enough deposit, or the userOp has a paymaster.\n */\n function _payPrefund(uint256 missingAccountFunds) internal virtual {\n if (missingAccountFunds != 0) {\n (bool success, ) = payable(msg.sender).call{\n value: missingAccountFunds,\n gas: type(uint256).max\n }(\"\");\n (success);\n //ignore failure (its EntryPoint's job to verify, not account.)\n }\n }\n}\n" + }, + "contracts/aa-4337/core/EntryPoint.sol": { + "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n\nimport \"../interfaces/IAccount.sol\";\nimport \"../interfaces/IPaymaster.sol\";\nimport \"../interfaces/IEntryPoint.sol\";\n\nimport \"../utils/Exec.sol\";\nimport \"./StakeManager.sol\";\nimport \"./SenderCreator.sol\";\nimport \"./Helpers.sol\";\nimport \"./NonceManager.sol\";\nimport \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\n\ncontract EntryPoint is\n IEntryPoint,\n StakeManager,\n NonceManager,\n ReentrancyGuard\n{\n using UserOperationLib for UserOperation;\n\n SenderCreator private immutable senderCreator = new SenderCreator();\n\n // internal value used during simulation: need to query aggregator.\n address private constant SIMULATE_FIND_AGGREGATOR = address(1);\n\n // marker for inner call revert on out of gas\n bytes32 private constant INNER_OUT_OF_GAS = hex\"deaddead\";\n\n uint256 private constant REVERT_REASON_MAX_LEN = 2048;\n\n /**\n * for simulation purposes, validateUserOp (and validatePaymasterUserOp) must return this value\n * in case of signature failure, instead of revert.\n */\n uint256 public constant SIG_VALIDATION_FAILED = 1;\n\n /**\n * compensate the caller's beneficiary address with the collected fees of all UserOperations.\n * @param beneficiary the address to receive the fees\n * @param amount amount to transfer.\n */\n function _compensate(address payable beneficiary, uint256 amount) internal {\n require(beneficiary != address(0), \"AA90 invalid beneficiary\");\n (bool success, ) = beneficiary.call{value: amount}(\"\");\n require(success, \"AA91 failed send to beneficiary\");\n }\n\n /**\n * execute a user op\n * @param opIndex index into the opInfo array\n * @param userOp the userOp to execute\n * @param opInfo the opInfo filled by validatePrepayment for this userOp.\n * @return collected the total amount this userOp paid.\n */\n function _executeUserOp(\n uint256 opIndex,\n UserOperation calldata userOp,\n UserOpInfo memory opInfo\n ) private returns (uint256 collected) {\n uint256 preGas = gasleft();\n bytes memory context = getMemoryBytesFromOffset(opInfo.contextOffset);\n\n try this.innerHandleOp(userOp.callData, opInfo, context) returns (\n uint256 _actualGasCost\n ) {\n collected = _actualGasCost;\n } catch {\n bytes32 innerRevertCode;\n assembly {\n returndatacopy(0, 0, 32)\n innerRevertCode := mload(0)\n }\n // handleOps was called with gas limit too low. abort entire bundle.\n if (innerRevertCode == INNER_OUT_OF_GAS) {\n //report paymaster, since if it is not deliberately caused by the bundler,\n // it must be a revert caused by paymaster.\n revert FailedOp(opIndex, \"AA95 out of gas\");\n }\n\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n collected = _handlePostOp(\n opIndex,\n IPaymaster.PostOpMode.postOpReverted,\n opInfo,\n context,\n actualGas\n );\n }\n }\n\n /**\n * Execute a batch of UserOperations.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(\n UserOperation[] calldata ops,\n address payable beneficiary\n ) public nonReentrant {\n uint256 opslen = ops.length;\n UserOpInfo[] memory opInfos = new UserOpInfo[](opslen);\n\n unchecked {\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[i];\n (\n uint256 validationData,\n uint256 pmValidationData\n ) = _validatePrepayment(i, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(\n i,\n validationData,\n pmValidationData,\n address(0)\n );\n }\n\n uint256 collected = 0;\n emit BeforeExecution();\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(i, ops[i], opInfos[i]);\n }\n\n _compensate(beneficiary, collected);\n } //unchecked\n }\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) public nonReentrant {\n uint256 opasLen = opsPerAggregator.length;\n uint256 totalOps = 0;\n for (uint256 i = 0; i < opasLen; i++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[i];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n //address(1) is special marker of \"signature error\"\n require(\n address(aggregator) != address(1),\n \"AA96 invalid aggregator\"\n );\n\n if (address(aggregator) != address(0)) {\n // solhint-disable-next-line no-empty-blocks\n try aggregator.validateSignatures(ops, opa.signature) {} catch {\n revert SignatureValidationFailed(address(aggregator));\n }\n }\n\n totalOps += ops.length;\n }\n\n UserOpInfo[] memory opInfos = new UserOpInfo[](totalOps);\n\n emit BeforeExecution();\n\n uint256 opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n uint256 opslen = ops.length;\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[opIndex];\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(opIndex, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(\n i,\n validationData,\n paymasterValidationData,\n address(aggregator)\n );\n opIndex++;\n }\n }\n\n uint256 collected = 0;\n opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n emit SignatureAggregatorChanged(address(opa.aggregator));\n UserOperation[] calldata ops = opa.userOps;\n uint256 opslen = ops.length;\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(opIndex, ops[i], opInfos[opIndex]);\n opIndex++;\n }\n }\n emit SignatureAggregatorChanged(address(0));\n\n _compensate(beneficiary, collected);\n }\n\n /// @inheritdoc IEntryPoint\n function simulateHandleOp(\n UserOperation calldata op,\n address target,\n bytes calldata targetCallData\n ) external override {\n UserOpInfo memory opInfo;\n _simulationOnlyValidations(op);\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(0, op, opInfo);\n ValidationData memory data = _intersectTimeRange(\n validationData,\n paymasterValidationData\n );\n\n numberMarker();\n uint256 paid = _executeUserOp(0, op, opInfo);\n numberMarker();\n bool targetSuccess;\n bytes memory targetResult;\n if (target != address(0)) {\n (targetSuccess, targetResult) = target.call(targetCallData);\n }\n revert ExecutionResult(\n opInfo.preOpGas,\n paid,\n data.validAfter,\n data.validUntil,\n targetSuccess,\n targetResult\n );\n }\n\n // A memory copy of UserOp static fields only.\n // Excluding: callData, initCode and signature. Replacing paymasterAndData with paymaster.\n struct MemoryUserOp {\n address sender;\n uint256 nonce;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n address paymaster;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n }\n\n struct UserOpInfo {\n MemoryUserOp mUserOp;\n bytes32 userOpHash;\n uint256 prefund;\n uint256 contextOffset;\n uint256 preOpGas;\n }\n\n /**\n * inner function to handle a UserOperation.\n * Must be declared \"external\" to open a call context, but it can only be called by handleOps.\n */\n function innerHandleOp(\n bytes memory callData,\n UserOpInfo memory opInfo,\n bytes calldata context\n ) external returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n require(msg.sender == address(this), \"AA92 internal call only\");\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n\n uint callGasLimit = mUserOp.callGasLimit;\n unchecked {\n // handleOps was called with gas limit too low. abort entire bundle.\n if (\n gasleft() < callGasLimit + mUserOp.verificationGasLimit + 5000\n ) {\n assembly {\n mstore(0, INNER_OUT_OF_GAS)\n revert(0, 32)\n }\n }\n }\n\n IPaymaster.PostOpMode mode = IPaymaster.PostOpMode.opSucceeded;\n if (callData.length > 0) {\n bool success = Exec.call(mUserOp.sender, 0, callData, callGasLimit);\n if (!success) {\n bytes memory result = Exec.getReturnData(REVERT_REASON_MAX_LEN);\n if (result.length > 0) {\n emit UserOperationRevertReason(\n opInfo.userOpHash,\n mUserOp.sender,\n mUserOp.nonce,\n result\n );\n }\n mode = IPaymaster.PostOpMode.opReverted;\n }\n }\n\n unchecked {\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n //note: opIndex is ignored (relevant only if mode==postOpReverted, which is only possible outside of innerHandleOp)\n return _handlePostOp(0, mode, opInfo, context, actualGas);\n }\n }\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(\n UserOperation calldata userOp\n ) public view returns (bytes32) {\n return\n keccak256(abi.encode(userOp.hash(), address(this), block.chainid));\n }\n\n /**\n * copy general fields from userOp into the memory opInfo structure.\n */\n function _copyUserOpToMemory(\n UserOperation calldata userOp,\n MemoryUserOp memory mUserOp\n ) internal pure {\n mUserOp.sender = userOp.sender;\n mUserOp.nonce = userOp.nonce;\n mUserOp.callGasLimit = userOp.callGasLimit;\n mUserOp.verificationGasLimit = userOp.verificationGasLimit;\n mUserOp.preVerificationGas = userOp.preVerificationGas;\n mUserOp.maxFeePerGas = userOp.maxFeePerGas;\n mUserOp.maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes calldata paymasterAndData = userOp.paymasterAndData;\n if (paymasterAndData.length > 0) {\n require(\n paymasterAndData.length >= 20,\n \"AA93 invalid paymasterAndData\"\n );\n mUserOp.paymaster = address(bytes20(paymasterAndData[:20]));\n } else {\n mUserOp.paymaster = address(0);\n }\n }\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external {\n UserOpInfo memory outOpInfo;\n\n _simulationOnlyValidations(userOp);\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(0, userOp, outOpInfo);\n StakeInfo memory paymasterInfo = _getStakeInfo(\n outOpInfo.mUserOp.paymaster\n );\n StakeInfo memory senderInfo = _getStakeInfo(outOpInfo.mUserOp.sender);\n StakeInfo memory factoryInfo;\n {\n bytes calldata initCode = userOp.initCode;\n address factory = initCode.length >= 20\n ? address(bytes20(initCode[0:20]))\n : address(0);\n factoryInfo = _getStakeInfo(factory);\n }\n\n ValidationData memory data = _intersectTimeRange(\n validationData,\n paymasterValidationData\n );\n address aggregator = data.aggregator;\n bool sigFailed = aggregator == address(1);\n ReturnInfo memory returnInfo = ReturnInfo(\n outOpInfo.preOpGas,\n outOpInfo.prefund,\n sigFailed,\n data.validAfter,\n data.validUntil,\n getMemoryBytesFromOffset(outOpInfo.contextOffset)\n );\n\n if (aggregator != address(0) && aggregator != address(1)) {\n AggregatorStakeInfo memory aggregatorInfo = AggregatorStakeInfo(\n aggregator,\n _getStakeInfo(aggregator)\n );\n revert ValidationResultWithAggregation(\n returnInfo,\n senderInfo,\n factoryInfo,\n paymasterInfo,\n aggregatorInfo\n );\n }\n revert ValidationResult(\n returnInfo,\n senderInfo,\n factoryInfo,\n paymasterInfo\n );\n }\n\n function _getRequiredPrefund(\n MemoryUserOp memory mUserOp\n ) internal pure returns (uint256 requiredPrefund) {\n unchecked {\n //when using a Paymaster, the verificationGasLimit is used also to as a limit for the postOp call.\n // our security model might call postOp eventually twice\n uint256 mul = mUserOp.paymaster != address(0) ? 3 : 1;\n uint256 requiredGas = mUserOp.callGasLimit +\n mUserOp.verificationGasLimit *\n mul +\n mUserOp.preVerificationGas;\n\n requiredPrefund = requiredGas * mUserOp.maxFeePerGas;\n }\n }\n\n // create the sender's contract if needed.\n function _createSenderIfNeeded(\n uint256 opIndex,\n UserOpInfo memory opInfo,\n bytes calldata initCode\n ) internal {\n if (initCode.length != 0) {\n address sender = opInfo.mUserOp.sender;\n if (sender.code.length != 0)\n revert FailedOp(opIndex, \"AA10 sender already constructed\");\n address sender1 = senderCreator.createSender{\n gas: opInfo.mUserOp.verificationGasLimit\n }(initCode);\n if (sender1 == address(0))\n revert FailedOp(opIndex, \"AA13 initCode failed or OOG\");\n if (sender1 != sender)\n revert FailedOp(opIndex, \"AA14 initCode must return sender\");\n if (sender1.code.length == 0)\n revert FailedOp(opIndex, \"AA15 initCode must create sender\");\n address factory = address(bytes20(initCode[0:20]));\n emit AccountDeployed(\n opInfo.userOpHash,\n sender,\n factory,\n opInfo.mUserOp.paymaster\n );\n }\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes calldata initCode) public {\n address sender = senderCreator.createSender(initCode);\n revert SenderAddressResult(sender);\n }\n\n function _simulationOnlyValidations(\n UserOperation calldata userOp\n ) internal view {\n // solhint-disable-next-line no-empty-blocks\n try\n this._validateSenderAndPaymaster(\n userOp.initCode,\n userOp.sender,\n userOp.paymasterAndData\n )\n {} catch Error(string memory revertReason) {\n if (bytes(revertReason).length != 0) {\n revert FailedOp(0, revertReason);\n }\n }\n }\n\n /**\n * Called only during simulation.\n * This function always reverts to prevent warm/cold storage differentiation in simulation vs execution.\n */\n function _validateSenderAndPaymaster(\n bytes calldata initCode,\n address sender,\n bytes calldata paymasterAndData\n ) external view {\n if (initCode.length == 0 && sender.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA20 account not deployed\");\n }\n if (paymasterAndData.length >= 20) {\n address paymaster = address(bytes20(paymasterAndData[0:20]));\n if (paymaster.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA30 paymaster not deployed\");\n }\n }\n // always revert\n revert(\"\");\n }\n\n /**\n * call account.validateUserOp.\n * revert (with FailedOp) in case validateUserOp reverts, or account didn't send required prefund.\n * decrement account's deposit if needed\n */\n function _validateAccountPrepayment(\n uint256 opIndex,\n UserOperation calldata op,\n UserOpInfo memory opInfo,\n uint256 requiredPrefund\n )\n internal\n returns (\n uint256 gasUsedByValidateAccountPrepayment,\n uint256 validationData\n )\n {\n unchecked {\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n address sender = mUserOp.sender;\n _createSenderIfNeeded(opIndex, opInfo, op.initCode);\n address paymaster = mUserOp.paymaster;\n numberMarker();\n uint256 missingAccountFunds = 0;\n if (paymaster == address(0)) {\n uint256 bal = balanceOf(sender);\n missingAccountFunds = bal > requiredPrefund\n ? 0\n : requiredPrefund - bal;\n }\n try\n IAccount(sender).validateUserOp{\n gas: mUserOp.verificationGasLimit\n }(op, opInfo.userOpHash, missingAccountFunds)\n returns (uint256 _validationData) {\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA23 reverted: \", revertReason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA23 reverted (or OOG)\");\n }\n if (paymaster == address(0)) {\n DepositInfo storage senderInfo = deposits[sender];\n uint256 deposit = senderInfo.deposit;\n if (requiredPrefund > deposit) {\n revert FailedOp(opIndex, \"AA21 didn't pay prefund\");\n }\n senderInfo.deposit = uint112(deposit - requiredPrefund);\n }\n gasUsedByValidateAccountPrepayment = preGas - gasleft();\n }\n }\n\n /**\n * In case the request has a paymaster:\n * Validate paymaster has enough deposit.\n * Call paymaster.validatePaymasterUserOp.\n * Revert with proper FailedOp in case paymaster reverts.\n * Decrement paymaster's deposit\n */\n function _validatePaymasterPrepayment(\n uint256 opIndex,\n UserOperation calldata op,\n UserOpInfo memory opInfo,\n uint256 requiredPreFund,\n uint256 gasUsedByValidateAccountPrepayment\n ) internal returns (bytes memory context, uint256 validationData) {\n unchecked {\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 verificationGasLimit = mUserOp.verificationGasLimit;\n require(\n verificationGasLimit > gasUsedByValidateAccountPrepayment,\n \"AA41 too little verificationGas\"\n );\n uint256 gas = verificationGasLimit -\n gasUsedByValidateAccountPrepayment;\n\n address paymaster = mUserOp.paymaster;\n DepositInfo storage paymasterInfo = deposits[paymaster];\n uint256 deposit = paymasterInfo.deposit;\n if (deposit < requiredPreFund) {\n revert FailedOp(opIndex, \"AA31 paymaster deposit too low\");\n }\n paymasterInfo.deposit = uint112(deposit - requiredPreFund);\n try\n IPaymaster(paymaster).validatePaymasterUserOp{gas: gas}(\n op,\n opInfo.userOpHash,\n requiredPreFund\n )\n returns (bytes memory _context, uint256 _validationData) {\n context = _context;\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA33 reverted: \", revertReason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA33 reverted (or OOG)\");\n }\n }\n }\n\n /**\n * revert if either account validationData or paymaster validationData is expired\n */\n function _validateAccountAndPaymasterValidationData(\n uint256 opIndex,\n uint256 validationData,\n uint256 paymasterValidationData,\n address expectedAggregator\n ) internal view {\n (address aggregator, bool outOfTimeRange) = _getValidationData(\n validationData\n );\n if (expectedAggregator != aggregator) {\n revert FailedOp(opIndex, \"AA24 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA22 expired or not due\");\n }\n //pmAggregator is not a real signature aggregator: we don't have logic to handle it as address.\n // non-zero address means that the paymaster fails due to some signature check (which is ok only during estimation)\n address pmAggregator;\n (pmAggregator, outOfTimeRange) = _getValidationData(\n paymasterValidationData\n );\n if (pmAggregator != address(0)) {\n revert FailedOp(opIndex, \"AA34 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA32 paymaster expired or not due\");\n }\n }\n\n function _getValidationData(\n uint256 validationData\n ) internal view returns (address aggregator, bool outOfTimeRange) {\n if (validationData == 0) {\n return (address(0), false);\n }\n ValidationData memory data = _parseValidationData(validationData);\n // solhint-disable-next-line not-rely-on-time\n outOfTimeRange =\n block.timestamp > data.validUntil ||\n block.timestamp < data.validAfter;\n aggregator = data.aggregator;\n }\n\n /**\n * validate account and paymaster (if defined).\n * also make sure total validation doesn't exceed verificationGasLimit\n * this method is called off-chain (simulateValidation()) and on-chain (from handleOps)\n * @param opIndex the index of this userOp into the \"opInfos\" array\n * @param userOp the userOp to validate\n */\n function _validatePrepayment(\n uint256 opIndex,\n UserOperation calldata userOp,\n UserOpInfo memory outOpInfo\n )\n private\n returns (uint256 validationData, uint256 paymasterValidationData)\n {\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = outOpInfo.mUserOp;\n _copyUserOpToMemory(userOp, mUserOp);\n outOpInfo.userOpHash = getUserOpHash(userOp);\n\n // validate all numeric values in userOp are well below 128 bit, so they can safely be added\n // and multiplied without causing overflow\n uint256 maxGasValues = mUserOp.preVerificationGas |\n mUserOp.verificationGasLimit |\n mUserOp.callGasLimit |\n userOp.maxFeePerGas |\n userOp.maxPriorityFeePerGas;\n require(maxGasValues <= type(uint120).max, \"AA94 gas values overflow\");\n\n uint256 gasUsedByValidateAccountPrepayment;\n uint256 requiredPreFund = _getRequiredPrefund(mUserOp);\n (\n gasUsedByValidateAccountPrepayment,\n validationData\n ) = _validateAccountPrepayment(\n opIndex,\n userOp,\n outOpInfo,\n requiredPreFund\n );\n\n if (!_validateAndUpdateNonce(mUserOp.sender, mUserOp.nonce)) {\n revert FailedOp(opIndex, \"AA25 invalid account nonce\");\n }\n\n //a \"marker\" where account opcode validation is done and paymaster opcode validation is about to start\n // (used only by off-chain simulateValidation)\n numberMarker();\n\n bytes memory context;\n if (mUserOp.paymaster != address(0)) {\n (context, paymasterValidationData) = _validatePaymasterPrepayment(\n opIndex,\n userOp,\n outOpInfo,\n requiredPreFund,\n gasUsedByValidateAccountPrepayment\n );\n }\n unchecked {\n uint256 gasUsed = preGas - gasleft();\n\n if (userOp.verificationGasLimit < gasUsed) {\n revert FailedOp(opIndex, \"AA40 over verificationGasLimit\");\n }\n outOpInfo.prefund = requiredPreFund;\n outOpInfo.contextOffset = getOffsetOfMemoryBytes(context);\n outOpInfo.preOpGas = preGas - gasleft() + userOp.preVerificationGas;\n }\n }\n\n /**\n * process post-operation.\n * called just after the callData is executed.\n * if a paymaster is defined and its validation returned a non-empty context, its postOp is called.\n * the excess amount is refunded to the account (or paymaster - if it was used in the request)\n * @param opIndex index in the batch\n * @param mode - whether is called from innerHandleOp, or outside (postOpReverted)\n * @param opInfo userOp fields and info collected during validation\n * @param context the context returned in validatePaymasterUserOp\n * @param actualGas the gas used so far by this user operation\n */\n function _handlePostOp(\n uint256 opIndex,\n IPaymaster.PostOpMode mode,\n UserOpInfo memory opInfo,\n bytes memory context,\n uint256 actualGas\n ) private returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n unchecked {\n address refundAddress;\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 gasPrice = getUserOpGasPrice(mUserOp);\n\n address paymaster = mUserOp.paymaster;\n if (paymaster == address(0)) {\n refundAddress = mUserOp.sender;\n } else {\n refundAddress = paymaster;\n if (context.length > 0) {\n actualGasCost = actualGas * gasPrice;\n if (mode != IPaymaster.PostOpMode.postOpReverted) {\n IPaymaster(paymaster).postOp{\n gas: mUserOp.verificationGasLimit\n }(mode, context, actualGasCost);\n } else {\n // solhint-disable-next-line no-empty-blocks\n try\n IPaymaster(paymaster).postOp{\n gas: mUserOp.verificationGasLimit\n }(mode, context, actualGasCost)\n {} catch Error(string memory reason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA50 postOp reverted: \", reason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA50 postOp revert\");\n }\n }\n }\n }\n actualGas += preGas - gasleft();\n actualGasCost = actualGas * gasPrice;\n if (opInfo.prefund < actualGasCost) {\n revert FailedOp(opIndex, \"AA51 prefund below actualGasCost\");\n }\n uint256 refund = opInfo.prefund - actualGasCost;\n _incrementDeposit(refundAddress, refund);\n bool success = mode == IPaymaster.PostOpMode.opSucceeded;\n emit UserOperationEvent(\n opInfo.userOpHash,\n mUserOp.sender,\n mUserOp.paymaster,\n mUserOp.nonce,\n success,\n actualGasCost,\n actualGas\n );\n } // unchecked\n }\n\n /**\n * the gas price this UserOp agrees to pay.\n * relayer/block builder might submit the TX with higher priorityFee, but the user should not\n */\n function getUserOpGasPrice(\n MemoryUserOp memory mUserOp\n ) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = mUserOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = mUserOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n function getOffsetOfMemoryBytes(\n bytes memory data\n ) internal pure returns (uint256 offset) {\n assembly {\n offset := data\n }\n }\n\n function getMemoryBytesFromOffset(\n uint256 offset\n ) internal pure returns (bytes memory data) {\n assembly {\n data := offset\n }\n }\n\n //place the NUMBER opcode in the code.\n // this is used as a marker during simulation, as this OP is completely banned from the simulated code of the\n // account and paymaster.\n function numberMarker() internal view {\n assembly {\n mstore(0, number())\n }\n }\n}\n" + }, + "contracts/aa-4337/core/Helpers.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable no-inline-assembly */\n\n/**\n * returned data from validateUserOp.\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\n * @param aggregator - address(0) - the account validated the signature by itself.\n * address(1) - the account failed to validate the signature.\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\n * @param validAfter - this UserOp is valid only after this timestamp.\n * @param validaUntil - this UserOp is valid only up to this timestamp.\n */\nstruct ValidationData {\n address aggregator;\n uint48 validAfter;\n uint48 validUntil;\n}\n\n//extract sigFailed, validAfter, validUntil.\n// also convert zero validUntil to type(uint48).max\nfunction _parseValidationData(\n uint validationData\n) pure returns (ValidationData memory data) {\n address aggregator = address(uint160(validationData));\n uint48 validUntil = uint48(validationData >> 160);\n if (validUntil == 0) {\n validUntil = type(uint48).max;\n }\n uint48 validAfter = uint48(validationData >> (48 + 160));\n return ValidationData(aggregator, validAfter, validUntil);\n}\n\n// intersect account and paymaster ranges.\nfunction _intersectTimeRange(\n uint256 validationData,\n uint256 paymasterValidationData\n) pure returns (ValidationData memory) {\n ValidationData memory accountValidationData = _parseValidationData(\n validationData\n );\n ValidationData memory pmValidationData = _parseValidationData(\n paymasterValidationData\n );\n address aggregator = accountValidationData.aggregator;\n if (aggregator == address(0)) {\n aggregator = pmValidationData.aggregator;\n }\n uint48 validAfter = accountValidationData.validAfter;\n uint48 validUntil = accountValidationData.validUntil;\n uint48 pmValidAfter = pmValidationData.validAfter;\n uint48 pmValidUntil = pmValidationData.validUntil;\n\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\n return ValidationData(aggregator, validAfter, validUntil);\n}\n\n/**\n * helper to pack the return value for validateUserOp\n * @param data - the ValidationData to pack\n */\nfunction _packValidationData(\n ValidationData memory data\n) pure returns (uint256) {\n return\n uint160(data.aggregator) |\n (uint256(data.validUntil) << 160) |\n (uint256(data.validAfter) << (160 + 48));\n}\n\n/**\n * helper to pack the return value for validateUserOp, when not using an aggregator\n * @param sigFailed - true for signature failure, false for success\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\n * @param validAfter first timestamp this UserOperation is valid\n */\nfunction _packValidationData(\n bool sigFailed,\n uint48 validUntil,\n uint48 validAfter\n) pure returns (uint256) {\n return\n (sigFailed ? 1 : 0) |\n (uint256(validUntil) << 160) |\n (uint256(validAfter) << (160 + 48));\n}\n\n/**\n * keccak function over calldata.\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\n */\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\n assembly {\n let mem := mload(0x40)\n let len := data.length\n calldatacopy(mem, data.offset, len)\n ret := keccak256(mem, len)\n }\n}\n" + }, + "contracts/aa-4337/core/NonceManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\nimport \"../interfaces/IEntryPoint.sol\";\n\n/**\n * nonce management functionality\n */\ncontract NonceManager is INonceManager {\n /**\n * The next valid sequence number for a given nonce key.\n */\n mapping(address => mapping(uint192 => uint256)) public nonceSequenceNumber;\n\n function getNonce(\n address sender,\n uint192 key\n ) public view override returns (uint256 nonce) {\n return nonceSequenceNumber[sender][key] | (uint256(key) << 64);\n }\n\n // allow an account to manually increment its own nonce.\n // (mainly so that during construction nonce can be made non-zero,\n // to \"absorb\" the gas cost of first nonce increment to 1st transaction (construction),\n // not to 2nd transaction)\n function incrementNonce(uint192 key) public override {\n nonceSequenceNumber[msg.sender][key]++;\n }\n\n /**\n * validate nonce uniqueness for this account.\n * called just after validateUserOp()\n */\n function _validateAndUpdateNonce(\n address sender,\n uint256 nonce\n ) internal returns (bool) {\n uint192 key = uint192(nonce >> 64);\n uint64 seq = uint64(nonce);\n return nonceSequenceNumber[sender][key]++ == seq;\n }\n}\n" + }, + "contracts/aa-4337/core/SenderCreator.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/**\n * helper contract for EntryPoint, to call userOp.initCode from a \"neutral\" address,\n * which is explicitly not the entryPoint itself.\n */\ncontract SenderCreator {\n /**\n * call the \"initCode\" factory to create and return the sender account address\n * @param initCode the initCode value from a UserOp. contains 20 bytes of factory address, followed by calldata\n * @return sender the returned address of the created account, or zero address on failure.\n */\n function createSender(\n bytes calldata initCode\n ) external returns (address sender) {\n address factory = address(bytes20(initCode[0:20]));\n bytes memory initCallData = initCode[20:];\n bool success;\n /* solhint-disable no-inline-assembly */\n assembly {\n success := call(\n gas(),\n factory,\n 0,\n add(initCallData, 0x20),\n mload(initCallData),\n 0,\n 32\n )\n sender := mload(0)\n }\n if (!success) {\n sender = address(0);\n }\n }\n}\n" + }, + "contracts/aa-4337/core/StakeManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity 0.8.21;\n\nimport \"../interfaces/IStakeManager.sol\";\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable not-rely-on-time */\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by a paymaster.\n */\nabstract contract StakeManager is IStakeManager {\n /// maps paymaster to their deposits and stakes\n mapping(address => DepositInfo) public deposits;\n\n /// @inheritdoc IStakeManager\n function getDepositInfo(\n address account\n ) public view returns (DepositInfo memory info) {\n return deposits[account];\n }\n\n // internal method to return just the stake info\n function _getStakeInfo(\n address addr\n ) internal view returns (StakeInfo memory info) {\n DepositInfo storage depositInfo = deposits[addr];\n info.stake = depositInfo.stake;\n info.unstakeDelaySec = depositInfo.unstakeDelaySec;\n }\n\n /// return the deposit (for gas payment) of the account\n function balanceOf(address account) public view returns (uint256) {\n return deposits[account].deposit;\n }\n\n receive() external payable {\n depositTo(msg.sender);\n }\n\n function _incrementDeposit(address account, uint256 amount) internal {\n DepositInfo storage info = deposits[account];\n uint256 newAmount = info.deposit + amount;\n require(newAmount <= type(uint112).max, \"deposit overflow\");\n info.deposit = uint112(newAmount);\n }\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) public payable {\n _incrementDeposit(account, msg.value);\n DepositInfo storage info = deposits[account];\n emit Deposited(account, info.deposit);\n }\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 unstakeDelaySec) public payable {\n DepositInfo storage info = deposits[msg.sender];\n require(unstakeDelaySec > 0, \"must specify unstake delay\");\n require(\n unstakeDelaySec >= info.unstakeDelaySec,\n \"cannot decrease unstake time\"\n );\n uint256 stake = info.stake + msg.value;\n require(stake > 0, \"no stake specified\");\n require(stake <= type(uint112).max, \"stake overflow\");\n deposits[msg.sender] = DepositInfo(\n info.deposit,\n true,\n uint112(stake),\n unstakeDelaySec,\n 0\n );\n emit StakeLocked(msg.sender, stake, unstakeDelaySec);\n }\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external {\n DepositInfo storage info = deposits[msg.sender];\n require(info.unstakeDelaySec != 0, \"not staked\");\n require(info.staked, \"already unstaking\");\n uint48 withdrawTime = uint48(block.timestamp) + info.unstakeDelaySec;\n info.withdrawTime = withdrawTime;\n info.staked = false;\n emit StakeUnlocked(msg.sender, withdrawTime);\n }\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external {\n DepositInfo storage info = deposits[msg.sender];\n uint256 stake = info.stake;\n require(stake > 0, \"No stake to withdraw\");\n require(info.withdrawTime > 0, \"must call unlockStake() first\");\n require(\n info.withdrawTime <= block.timestamp,\n \"Stake withdrawal is not due\"\n );\n info.unstakeDelaySec = 0;\n info.withdrawTime = 0;\n info.stake = 0;\n emit StakeWithdrawn(msg.sender, withdrawAddress, stake);\n (bool success, ) = withdrawAddress.call{value: stake}(\"\");\n require(success, \"failed to withdraw stake\");\n }\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(\n address payable withdrawAddress,\n uint256 withdrawAmount\n ) external {\n DepositInfo storage info = deposits[msg.sender];\n require(withdrawAmount <= info.deposit, \"Withdraw amount too large\");\n info.deposit = uint112(info.deposit - withdrawAmount);\n emit Withdrawn(msg.sender, withdrawAddress, withdrawAmount);\n (bool success, ) = withdrawAddress.call{value: withdrawAmount}(\"\");\n require(success, \"failed to withdraw\");\n }\n}\n" + }, + "contracts/aa-4337/interfaces/IAccount.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\ninterface IAccount {\n /**\n * Validate user's signature and nonce\n * the entryPoint will make the call to the recipient only if this validation call returns successfully.\n * signature failure should be reported by returning SIG_VALIDATION_FAILED (1).\n * This allows making a \"simulation call\" without a valid signature\n * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure.\n *\n * @dev Must validate caller is the entryPoint.\n * Must validate the signature and nonce\n * @param userOp the operation that is about to be executed.\n * @param userOpHash hash of the user's request data. can be used as the basis for signature.\n * @param missingAccountFunds missing funds on the account's deposit in the entrypoint.\n * This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call.\n * The excess is left as a deposit in the entrypoint, for future calls.\n * can be withdrawn anytime using \"entryPoint.withdrawTo()\"\n * In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero.\n * @return validationData packaged ValidationData structure. use `_packValidationData` and `_unpackValidationData` to encode and decode\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * If an account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validateUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 missingAccountFunds\n ) external returns (uint256 validationData);\n}\n" + }, + "contracts/aa-4337/interfaces/IAggregator.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * Aggregated Signatures validator.\n */\ninterface IAggregator {\n /**\n * validate aggregated signature.\n * revert if the aggregated signature does not match the given list of operations.\n */\n function validateSignatures(\n UserOperation[] calldata userOps,\n bytes calldata signature\n ) external view;\n\n /**\n * validate signature of a single userOp\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\n * @param userOp the userOperation received from the user.\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\n * (usually empty, unless account and aggregator support some kind of \"multisig\"\n */\n function validateUserOpSignature(\n UserOperation calldata userOp\n ) external view returns (bytes memory sigForUserOp);\n\n /**\n * aggregate multiple signatures into a single value.\n * This method is called off-chain to calculate the signature to pass with handleOps()\n * bundler MAY use optimized custom code perform this aggregation\n * @param userOps array of UserOperations to collect the signatures from.\n * @return aggregatedSignature the aggregated signature\n */\n function aggregateSignatures(\n UserOperation[] calldata userOps\n ) external view returns (bytes memory aggregatedSignature);\n}\n" + }, + "contracts/aa-4337/interfaces/IEntryPoint.sol": { + "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n/* solhint-disable reason-string */\n\nimport \"./UserOperation.sol\";\nimport \"./IStakeManager.sol\";\nimport \"./IAggregator.sol\";\nimport \"./INonceManager.sol\";\n\ninterface IEntryPoint is IStakeManager, INonceManager {\n /***\n * An event emitted after each successful request\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\n * @param sender - the account that generates this request.\n * @param paymaster - if non-null, the paymaster that pays for this request.\n * @param nonce - the nonce value from the request.\n * @param success - true if the sender transaction succeeded, false if reverted.\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\n */\n event UserOperationEvent(\n bytes32 indexed userOpHash,\n address indexed sender,\n address indexed paymaster,\n uint256 nonce,\n bool success,\n uint256 actualGasCost,\n uint256 actualGasUsed\n );\n\n /**\n * account \"sender\" was deployed.\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\n * @param sender the account that is deployed\n * @param factory the factory used to deploy this account (in the initCode)\n * @param paymaster the paymaster used by this UserOp\n */\n event AccountDeployed(\n bytes32 indexed userOpHash,\n address indexed sender,\n address factory,\n address paymaster\n );\n\n /**\n * An event emitted if the UserOperation \"callData\" reverted with non-zero length\n * @param userOpHash the request unique identifier.\n * @param sender the sender of this request\n * @param nonce the nonce used in the request\n * @param revertReason - the return bytes from the (reverted) call to \"callData\".\n */\n event UserOperationRevertReason(\n bytes32 indexed userOpHash,\n address indexed sender,\n uint256 nonce,\n bytes revertReason\n );\n\n /**\n * an event emitted by handleOps(), before starting the execution loop.\n * any event emitted before this event, is part of the validation.\n */\n event BeforeExecution();\n\n /**\n * signature aggregator used by the following UserOperationEvents within this bundle.\n */\n event SignatureAggregatorChanged(address indexed aggregator);\n\n /**\n * a custom revert error of handleOps, to identify the offending op.\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\n * @param reason - revert reason\n * The string starts with a unique code \"AAmn\", where \"m\" is \"1\" for factory, \"2\" for account and \"3\" for paymaster issues,\n * so a failure can be attributed to the correct entity.\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\n */\n error FailedOp(uint256 opIndex, string reason);\n\n /**\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\n */\n error SignatureValidationFailed(address aggregator);\n\n /**\n * Successful result from simulateValidation.\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n */\n error ValidationResult(\n ReturnInfo returnInfo,\n StakeInfo senderInfo,\n StakeInfo factoryInfo,\n StakeInfo paymasterInfo\n );\n\n /**\n * Successful result from simulateValidation, if the account returns a signature aggregator\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\n * bundler MUST use it to verify the signature, or reject the UserOperation\n */\n error ValidationResultWithAggregation(\n ReturnInfo returnInfo,\n StakeInfo senderInfo,\n StakeInfo factoryInfo,\n StakeInfo paymasterInfo,\n AggregatorStakeInfo aggregatorInfo\n );\n\n /**\n * return value of getSenderAddress\n */\n error SenderAddressResult(address sender);\n\n /**\n * return value of simulateHandleOp\n */\n error ExecutionResult(\n uint256 preOpGas,\n uint256 paid,\n uint48 validAfter,\n uint48 validUntil,\n bool targetSuccess,\n bytes targetResult\n );\n\n //UserOps handled, per aggregator\n struct UserOpsPerAggregator {\n UserOperation[] userOps;\n // aggregator address\n IAggregator aggregator;\n // aggregated signature\n bytes signature;\n }\n\n /**\n * Execute a batch of UserOperation.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(\n UserOperation[] calldata ops,\n address payable beneficiary\n ) external;\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) external;\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(\n UserOperation calldata userOp\n ) external view returns (bytes32);\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external;\n\n /**\n * gas and return values during simulation\n * @param preOpGas the gas used for validation (including preValidationGas)\n * @param prefund the required prefund for this operation\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\n */\n struct ReturnInfo {\n uint256 preOpGas;\n uint256 prefund;\n bool sigFailed;\n uint48 validAfter;\n uint48 validUntil;\n bytes paymasterContext;\n }\n\n /**\n * returned aggregated signature info.\n * the aggregator returned by the account, and its current stake.\n */\n struct AggregatorStakeInfo {\n address aggregator;\n StakeInfo stakeInfo;\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes memory initCode) external;\n\n /**\n * simulate full execution of a UserOperation (including both validation and target execution)\n * this method will always revert with \"ExecutionResult\".\n * it performs full validation of the UserOperation, but ignores signature error.\n * an optional target address is called after the userop succeeds, and its value is returned\n * (before the entire call is reverted)\n * Note that in order to collect the the success/failure of the target call, it must be executed\n * with trace enabled to track the emitted events.\n * @param op the UserOperation to simulate\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\n * are set to the return from that call.\n * @param targetCallData callData to pass to target address\n */\n function simulateHandleOp(\n UserOperation calldata op,\n address target,\n bytes calldata targetCallData\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/INonceManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\ninterface INonceManager {\n /**\n * Return the next nonce for this sender.\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\n * But UserOp with different keys can come with arbitrary order.\n *\n * @param sender the account address\n * @param key the high 192 bit of the nonce\n * @return nonce a full nonce to pass for next UserOp with this sender.\n */\n function getNonce(\n address sender,\n uint192 key\n ) external view returns (uint256 nonce);\n\n /**\n * Manually increment the nonce of the sender.\n * This method is exposed just for completeness..\n * Account does NOT need to call it, neither during validation, nor elsewhere,\n * as the EntryPoint will update the nonce regardless.\n * Possible use-case is call it with various keys to \"initialize\" their nonces to one, so that future\n * UserOperations will not pay extra for the first transaction with a given key.\n */\n function incrementNonce(uint192 key) external;\n}\n" + }, + "contracts/aa-4337/interfaces/IPaymaster.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * the interface exposed by a paymaster contract, who agrees to pay the gas for user's operations.\n * a paymaster must hold a stake to cover the required entrypoint stake and also the gas for the transaction.\n */\ninterface IPaymaster {\n enum PostOpMode {\n opSucceeded, // user op succeeded\n opReverted, // user op reverted. still has to pay for gas.\n postOpReverted //user op succeeded, but caused postOp to revert. Now it's a 2nd call, after user's op was deliberately reverted.\n }\n\n /**\n * payment validation: check if paymaster agrees to pay.\n * Must verify sender is the entryPoint.\n * Revert to reject this request.\n * Note that bundlers will reject this method if it changes the state, unless the paymaster is trusted (whitelisted)\n * The paymaster pre-pays using its deposit, and receive back a refund after the postOp method returns.\n * @param userOp the user operation\n * @param userOpHash hash of the user's request data.\n * @param maxCost the maximum cost of this transaction (based on maximum gas and gas price from userOp)\n * @return context value to send to a postOp\n * zero length to signify postOp is not required.\n * @return validationData signature and time-range of this operation, encoded the same as the return value of validateUserOperation\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validatePaymasterUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 maxCost\n ) external returns (bytes memory context, uint256 validationData);\n\n /**\n * post-operation handler.\n * Must verify sender is the entryPoint\n * @param mode enum with the following options:\n * opSucceeded - user operation succeeded.\n * opReverted - user op reverted. still has to pay for gas.\n * postOpReverted - user op succeeded, but caused postOp (in mode=opSucceeded) to revert.\n * Now this is the 2nd call, after user's op was deliberately reverted.\n * @param context - the context value returned by validatePaymasterUserOp\n * @param actualGasCost - actual gas used so far (without this postOp call).\n */\n function postOp(\n PostOpMode mode,\n bytes calldata context,\n uint256 actualGasCost\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/IStakeManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.12;\n\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by the staked entity.\n */\ninterface IStakeManager {\n event Deposited(address indexed account, uint256 totalDeposit);\n\n event Withdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /// Emitted when stake or unstake delay are modified\n event StakeLocked(\n address indexed account,\n uint256 totalStaked,\n uint256 unstakeDelaySec\n );\n\n /// Emitted once a stake is scheduled for withdrawal\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\n\n event StakeWithdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /**\n * @param deposit the entity's deposit\n * @param staked true if this entity is staked.\n * @param stake actual amount of ether staked for this entity.\n * @param unstakeDelaySec minimum delay to withdraw the stake.\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\n * and the rest fit into a 2nd cell.\n * 112 bit allows for 10^15 eth\n * 48 bit for full timestamp\n * 32 bit allows 150 years for unstake delay\n */\n struct DepositInfo {\n uint112 deposit;\n bool staked;\n uint112 stake;\n uint32 unstakeDelaySec;\n uint48 withdrawTime;\n }\n\n //API struct used by getStakeInfo and simulateValidation\n struct StakeInfo {\n uint256 stake;\n uint256 unstakeDelaySec;\n }\n\n /// @return info - full deposit information of given account\n function getDepositInfo(\n address account\n ) external view returns (DepositInfo memory info);\n\n /// @return the deposit (for gas payment) of the account\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) external payable;\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 _unstakeDelaySec) external payable;\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external;\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external;\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(\n address payable withdrawAddress,\n uint256 withdrawAmount\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/UserOperation.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable no-inline-assembly */\n\nimport {calldataKeccak} from \"../core/Helpers.sol\";\n\n/**\n * User Operation struct\n * @param sender the sender account of this request.\n * @param nonce unique value the sender uses to verify it is not a replay.\n * @param initCode if set, the account contract will be created by this constructor/\n * @param callData the method call to execute on this account.\n * @param callGasLimit the gas limit passed to the callData method call.\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\n * @param maxFeePerGas same as EIP-1559 gas parameter.\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\n */\nstruct UserOperation {\n address sender;\n uint256 nonce;\n bytes initCode;\n bytes callData;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n bytes paymasterAndData;\n bytes signature;\n}\n\n/**\n * Utility functions helpful when working with UserOperation structs.\n */\nlibrary UserOperationLib {\n function getSender(\n UserOperation calldata userOp\n ) internal pure returns (address) {\n address data;\n //read sender from userOp, which is first userOp member (saves 800 gas...)\n assembly {\n data := calldataload(userOp)\n }\n return address(uint160(data));\n }\n\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\n // pay above what he signed for.\n function gasPrice(\n UserOperation calldata userOp\n ) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function pack(\n UserOperation calldata userOp\n ) internal pure returns (bytes memory ret) {\n address sender = getSender(userOp);\n uint256 nonce = userOp.nonce;\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\n bytes32 hashCallData = calldataKeccak(userOp.callData);\n uint256 callGasLimit = userOp.callGasLimit;\n uint256 verificationGasLimit = userOp.verificationGasLimit;\n uint256 preVerificationGas = userOp.preVerificationGas;\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\n\n return\n abi.encode(\n sender,\n nonce,\n hashInitCode,\n hashCallData,\n callGasLimit,\n verificationGasLimit,\n preVerificationGas,\n maxFeePerGas,\n maxPriorityFeePerGas,\n hashPaymasterAndData\n );\n }\n\n function hash(\n UserOperation calldata userOp\n ) internal pure returns (bytes32) {\n return keccak256(pack(userOp));\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n}\n" + }, + "contracts/aa-4337/utils/Exec.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.5 <0.9.0;\n\n// solhint-disable no-inline-assembly\n\n/**\n * Utility functions helpful when making different kinds of contract calls in Solidity.\n */\nlibrary Exec {\n function call(\n address to,\n uint256 value,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := call(\n txGas,\n to,\n value,\n add(data, 0x20),\n mload(data),\n 0,\n 0\n )\n }\n }\n\n function staticcall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal view returns (bool success) {\n assembly {\n success := staticcall(txGas, to, add(data, 0x20), mload(data), 0, 0)\n }\n }\n\n function delegateCall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := delegatecall(\n txGas,\n to,\n add(data, 0x20),\n mload(data),\n 0,\n 0\n )\n }\n }\n\n // get returned data from last call or calldelegate\n function getReturnData(\n uint256 maxLen\n ) internal pure returns (bytes memory returnData) {\n assembly {\n let len := returndatasize()\n if gt(len, maxLen) {\n len := maxLen\n }\n let ptr := mload(0x40)\n mstore(0x40, add(ptr, add(len, 0x20)))\n mstore(ptr, len)\n returndatacopy(add(ptr, 0x20), 0, len)\n returnData := ptr\n }\n }\n\n // revert with explicit byte array (probably reverted info from call)\n function revertWithData(bytes memory returnData) internal pure {\n assembly {\n revert(add(returnData, 32), mload(returnData))\n }\n }\n\n function callAndRevert(\n address to,\n bytes memory data,\n uint256 maxLen\n ) internal {\n bool success = call(to, 0, data, gasleft());\n if (!success) {\n revertWithData(getReturnData(maxLen));\n }\n }\n}\n" + }, + "contracts/Barz.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"./libraries/LibDiamond.sol\";\nimport {IBarz} from \"./interfaces/IBarz.sol\";\n\n/**\n * @title Barz\n * @dev A diamond proxy wallet with a modular & upgradeable architecture\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract Barz is IBarz {\n /**\n * @notice Initializes Barz with the given parameters. Barz account is intended to be created from Barz Factory for stable deployment.\n * @dev This method makes a delegate call to account facet and account facet handles the initialization.\n * With modular architecture, Barz encompasses wide spectrum of architecture and logic.\n * The only requirement is account facet to comply with initialize() interface.\n * Barz doesn't include built-in functions and is a full proxy, for maximum extensibility and modularity.\n * @param _accountFacet Address of Account Facet in charge of the Barz initialization\n * @param _verificationFacet Address of Verification Facet for verifying the signature. Could be any signature scheme\n * @param _entryPoint Address of Entry Point contract\n * @param _facetRegistry Address of Facet Registry. Facet Registry is a registry holding trusted facets that could be added to user's wallet\n * @param _defaultFallBack Address of Default FallBack Handler. Middleware contract for more efficient deployment\n * @param _ownerPublicKey Bytes of Owner Public Key using for initialization\n */\n constructor(\n address _accountFacet,\n address _verificationFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallBack,\n bytes memory _ownerPublicKey\n ) payable {\n bytes memory initCall = abi.encodeWithSignature(\n \"initialize(address,address,address,address,bytes)\",\n _verificationFacet,\n _entryPoint,\n _facetRegistry,\n _defaultFallBack,\n _ownerPublicKey\n );\n (bool success, bytes memory result) = _accountFacet.delegatecall(\n initCall\n );\n if (!success || uint256(bytes32(result)) != 1) {\n revert Barz__InitializationFailure();\n }\n }\n\n /**\n * @notice Fallback function for Barz complying with Diamond Standard with customization of adding Default Fallback Handler\n * @dev Find facet for function that is called and execute the function if a facet is found and return any value.\n */\n fallback() external payable {\n LibDiamond.DiamondStorage storage ds;\n bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION;\n // get diamond storage\n assembly {\n ds.slot := position\n }\n // get facet from function selector\n address facet = address(bytes20(ds.facets[msg.sig]));\n if (facet == address(0))\n facet = ds.defaultFallbackHandler.facetAddress(msg.sig);\n require(facet != address(0), \"Barz: Function does not exist\");\n // Execute external function from facet using delegatecall and return any value.\n assembly {\n // copy function selector and any arguments\n calldatacopy(0, 0, calldatasize())\n // execute function call using the facet\n let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)\n // get any return value\n returndatacopy(0, 0, returndatasize())\n // return any return value or error back to the caller\n switch result\n case 0 {\n revert(0, returndatasize())\n }\n default {\n return(0, returndatasize())\n }\n }\n }\n\n /**\n * @notice Receive function to receive native token without data\n */\n receive() external payable {}\n}\n" + }, + "contracts/BarzFactory.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Barz} from \"./Barz.sol\";\nimport {IBarzFactory} from \"./interfaces/IBarzFactory.sol\";\n\n/**\n * @title Barz Factory\n * @dev Contract to easily deploy Barz to a pre-computed address with a single call\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract BarzFactory is IBarzFactory {\n address public immutable accountFacet;\n address public immutable entryPoint;\n address public immutable facetRegistry;\n address public immutable defaultFallback;\n\n /**\n * @notice Sets the initialization data for Barz contract initialization\n * @param _accountFacet Account Facet to be used to create Barz\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\n * @param _facetRegistry Facet Registry to be used to create Barz\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\n */\n constructor(\n address _accountFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallback\n ) {\n accountFacet = _accountFacet;\n entryPoint = _entryPoint;\n facetRegistry = _facetRegistry;\n defaultFallback = _defaultFallback;\n }\n\n /**\n * @notice Creates the Barz with a single call. It creates the Barz contract with the givent verification facet\n * @param _verificationFacet Address of verification facet used for creating the barz account\n * @param _owner Public Key of the owner to initialize barz account\n * @param _salt Salt used for deploying barz with create2\n * @return barz Instance of Barz contract deployed with the given parameters\n */\n function createAccount(\n address _verificationFacet,\n bytes calldata _owner,\n uint256 _salt\n ) external override returns (Barz barz) {\n address addr = getAddress(_verificationFacet, _owner, _salt);\n uint codeSize = addr.code.length;\n if (codeSize > 0) {\n return Barz(payable(addr));\n }\n barz = new Barz{salt: bytes32(_salt)}(\n accountFacet,\n _verificationFacet,\n entryPoint,\n facetRegistry,\n defaultFallback,\n _owner\n );\n emit BarzDeployed(address(barz));\n }\n\n /**\n * @notice Calculates the address of Barz with the given parameters\n * @param _verificationFacet Address of verification facet used for creating the barz account\n * @param _owner Public Key of the owner to initialize barz account\n * @param _salt Salt used for deploying barz with create2\n * @return barzAddress Precalculated Barz address\n */\n function getAddress(\n address _verificationFacet,\n bytes calldata _owner,\n uint256 _salt\n ) public view override returns (address barzAddress) {\n bytes memory bytecode = getBytecode(\n accountFacet,\n _verificationFacet,\n entryPoint,\n facetRegistry,\n defaultFallback,\n _owner\n );\n bytes32 hash = keccak256(\n abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(bytecode)\n )\n );\n barzAddress = address(uint160(uint256(hash)));\n }\n\n /**\n * @notice Returns the bytecode of Barz with the given parameter\n * @param _accountFacet Account Facet to be used to create Barz\n * @param _verificationFacet Verification Facet to be used to create Barz\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\n * @param _facetRegistry Facet Registry to be used to create Barz\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\n * @param _ownerPublicKey Public Key of owner to be used to initialize Barz ownership\n * @return barzBytecode Bytecode of Barz\n */\n function getBytecode(\n address _accountFacet,\n address _verificationFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallback,\n bytes calldata _ownerPublicKey\n ) public pure override returns (bytes memory barzBytecode) {\n bytes memory bytecode = type(Barz).creationCode;\n barzBytecode = abi.encodePacked(\n bytecode,\n abi.encode(\n _accountFacet,\n _verificationFacet,\n _entryPoint,\n _facetRegistry,\n _defaultFallback,\n _ownerPublicKey\n )\n );\n }\n\n /**\n * @notice Returns the creation code of the Barz contract\n * @return creationCode Creation code of Barz\n */\n function getCreationCode()\n public\n pure\n override\n returns (bytes memory creationCode)\n {\n creationCode = type(Barz).creationCode;\n }\n}\n" + }, + "contracts/facets/AccountFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {UserOperation} from \"../aa-4337/interfaces/UserOperation.sol\";\nimport {IEntryPoint} from \"../aa-4337/interfaces/IEntryPoint.sol\";\nimport {BaseAccount} from \"../aa-4337/core/BaseAccount.sol\";\nimport {LibAppStorage, BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {IFacetRegistry} from \"../infrastructure/interfaces/IFacetRegistry.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {IERC1271} from \"../interfaces/ERC/IERC1271.sol\";\nimport {IAccountFacet} from \"./interfaces/IAccountFacet.sol\";\n\n/**\n * @title Account Facet\n * @dev Account module contract that provides the account features and initialization of signer\n * compatible with EIP-1271 & EIP-4337\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract AccountFacet is IAccountFacet, BarzStorage, BaseAccount {\n using ECDSA for bytes32;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceAccountInitialize();\n }\n\n /**\n * @notice Returns the address of EntryPoint contract registered to Barz account\n */\n function entryPoint() public view override returns (IEntryPoint) {\n return s.entryPoint;\n }\n\n /**\n * @notice Initializes the initial storage of the Barz contract.\n * @dev This method can only be called during the initialization or signature migration.\n * If the proxy contract was created without initialization, anyone can call initialize.\n * Barz calls initialize in constructor in an atomic transaction during deployment\n * @param _verificationFacet Facet contract handling the verificationi\n * @param _anEntryPoint Entrypoint contract defined in EIP-4337 handling the flow of UserOp\n * @param _facetRegistry Registry of Facets that hold all facet information\n * @param _defaultFallBackHandler Middleware contract for default facets\n * @param _ownerPublicKey Bytes of owner public key\n */\n function initialize(\n address _verificationFacet,\n address _anEntryPoint,\n address _facetRegistry,\n address _defaultFallBackHandler,\n bytes calldata _ownerPublicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceAccountInitialize();\n s.entryPoint = IEntryPoint(_anEntryPoint);\n s.facetRegistry = IFacetRegistry(_facetRegistry);\n LibDiamond.diamondStorage().defaultFallbackHandler = IDiamondLoupe(\n _defaultFallBackHandler\n );\n\n _cutDiamondAccountFacet(_verificationFacet);\n\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n _ownerPublicKey\n );\n // Every Verification Facet should comply with initializeSigner(bytes)\n // to be compatible with the Barz contract(for initialization)\n (bool success, bytes memory result) = _verificationFacet.delegatecall(\n initCall\n );\n if (!success || uint256(bytes32(result)) != 1) {\n revert AccountFacet__InitializationFailure();\n }\n\n initSuccess = 1;\n emit AccountInitialized(s.entryPoint, _ownerPublicKey);\n }\n\n function _cutDiamondAccountFacet(address _verificationFacet) internal {\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](1);\n\n bytes4 ownerVerificationFuncSelector = IVerificationFacet(\n _verificationFacet\n ).validateOwnerSignatureSelector();\n\n bytes4[] memory verificationFunctionSelectors = new bytes4[](3);\n verificationFunctionSelectors[0] = IERC1271.isValidSignature.selector;\n verificationFunctionSelectors[1] = ownerVerificationFuncSelector;\n verificationFunctionSelectors[2] = IVerificationFacet.owner.selector;\n cut[0] = IDiamondCut.FacetCut({\n facetAddress: _verificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: verificationFunctionSelectors\n });\n\n LibDiamond.diamondCut(cut, address(0), \"\");\n }\n\n /**\n * @notice Calls the destination with inputted calldata and value from EntryPoint\n * @dev This method executes the calldata coming from the EntryPoint.\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\n * @param _dest Address of destination where the call will be forwarded to\n * @param _value Amount of native coin the owner is willing to send(e.g. ETH, BNB)\n * @param _func Bytes of calldata to execute in the destination address\n */\n function execute(\n address _dest,\n uint256 _value,\n bytes calldata _func\n ) external override onlyWhenUnlocked {\n _requireFromEntryPoint();\n address restrictionsFacet = LibDiamond.restrictionsFacet();\n if (restrictionsFacet == address(0)) _call(_dest, _value, _func);\n else _callWithRestrictions(_dest, _value, _func, restrictionsFacet);\n }\n\n /**\n * @notice Batch calls the destination with inputted calldata and value from EntryPoint\n * @dev This method batch executes the calldata coming from the EntryPoint.\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\n * @param _dest Array of addresses of destination where the call will be forwarded to\n * @param _value Array of amount of native coin the owner is willing to send(e.g. ETH, BNB)\n * @param _func Array of bytes of calldata to execute in the destination address\n */\n function executeBatch(\n address[] calldata _dest,\n uint256[] calldata _value,\n bytes[] calldata _func\n ) external override onlyWhenUnlocked {\n _requireFromEntryPoint();\n if (_dest.length != _func.length || _dest.length != _value.length)\n revert AccountFacet__InvalidArrayLength();\n address restrictionsFacet = LibDiamond.restrictionsFacet();\n if (restrictionsFacet == address(0)) {\n for (uint256 i; i < _dest.length; ) {\n _call(_dest[i], _value[i], _func[i]);\n unchecked {\n ++i;\n }\n }\n } else {\n for (uint256 i; i < _dest.length; ) {\n _callWithRestrictions(\n _dest[i],\n _value[i],\n _func[i],\n restrictionsFacet\n );\n unchecked {\n ++i;\n }\n }\n }\n }\n\n /**\n * @notice Validates the signature field of UserOperation\n * @dev This method validates if the signature of UserOp is indeed valid by delegating the call to Verification Facet\n * Barz makes a call to the pre-registered Verification Facet address in App Storage\n * @param _userOp UserOperation from owner to be validated\n * @param _userOpHash Hash of UserOperation given from the EntryPoint contract\n */\n function _validateSignature(\n UserOperation calldata _userOp,\n bytes32 _userOpHash\n ) internal override returns (uint256 validationData) {\n // Get Facet with Function Selector\n address facet = LibLoupe.facetAddress(s.validateOwnerSignatureSelector);\n if (facet == address(0))\n revert AccountFacet__NonExistentVerificationFacet();\n\n // Make function call to VerificationFacet\n bytes memory validateCall = abi.encodeWithSelector(\n s.validateOwnerSignatureSelector,\n _userOp,\n _userOpHash\n );\n (bool success, bytes memory result) = facet.delegatecall(validateCall);\n if (!success) revert AccountFacet__CallNotSuccessful();\n validationData = uint256(bytes32(result));\n if (validationData == 0) emit VerificationSuccess(_userOpHash);\n else emit VerificationFailure(_userOpHash);\n }\n\n /**\n * @notice Calls the target with the inputted value and calldata\n * @dev This method is the actual function in Barz that makes a call with an arbitrary owner-given data\n * @param _target Address of the destination contract which the call is getting forwarded to\n * @param _value Amount of Native coin the owner is wanting to make in this call\n * @param _data Calldata the owner is forwarding together in the call e.g. Swap/Token Transfer\n */\n function _call(\n address _target,\n uint256 _value,\n bytes memory _data\n ) internal {\n (bool success, bytes memory result) = _target.call{value: _value}(\n _data\n );\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n }\n\n /**\n * @notice Calls the target with the inputted value and calldata together with restrictions check\n * @dev This method is the actual function in Barz that makes a call with an arbitrary owner-given data\n * @param _target Address of the destination contract which the call is getting forwarded to\n * @param _value Amount of Native coin the owner is wanting to make in this call\n * @param _data Calldata the owner is forwarding together in the call e.g. Swap/Token Transfer\n * @param _restrictionsFacet Address of Facet to validate restrictions\n */\n function _callWithRestrictions(\n address _target,\n uint256 _value,\n bytes memory _data,\n address _restrictionsFacet\n ) internal {\n // NOTE: No restrictions facet, so restriction validation passes\n if (_checkRestrictions(_restrictionsFacet, _target, _value, _data) != 0)\n revert AccountFacet__RestrictionsFailure();\n\n (bool success, bytes memory result) = _target.call{value: _value}(\n _data\n );\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n }\n\n /**\n * @notice Checks restrictions if the restrictions facet exists\n * @dev This method checks if the restrictions facet exists and makes a verification call to an array of restrictions facet\n * @param _facet Address that holds the restrictions logic\n * @param _target Address the call is getting forwarded to\n * @param _value Amount of native coin the call is sending together with the call\n * @param _data Calldata to trigger execution in target address\n */\n function _checkRestrictions(\n address _facet,\n address _target,\n uint256 _value,\n bytes memory _data\n ) internal returns (uint256 result) {\n bytes memory call = abi.encodeWithSignature(\n \"verifyRestrictions(address,address,uint256,bytes)\",\n address(this),\n _target,\n _value,\n _data\n );\n (bool success, bytes memory response) = _facet.delegatecall(call);\n if (!success) revert AccountFacet__RestrictionsFailure();\n result = uint256(bytes32(response));\n }\n}\n" + }, + "contracts/facets/AccountRecoveryFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibFacetStorage, RecoveryStorage, RecoveryConfig, RecoveryApprovalConfig, ApprovalConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {IAccountRecoveryFacet} from \"./interfaces/IAccountRecoveryFacet.sol\";\n\n/**\n * @title Account Recovery Facet\n * @dev Contract that enables recovery of accounts when owner key is unavailable\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract AccountRecoveryFacet is IAccountRecoveryFacet, Modifiers {\n bytes constant UNINIT_CALL =\n abi.encodeWithSignature(\"uninitializeSigner()\");\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Approve recovery of account as guardian\n * @dev This method can only be called by guardian and guardian inputs the public key of the new owner\n * When the threshold(majority of guardians) passes, it automatically executes account recovery\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function approveAccountRecovery(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + _getApprovalValidationPeriod()\n );\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit RecoveryApproved(\n _recoveryPublicKey,\n msg.sender,\n approvalValidUntil\n );\n if (\n getRecoveryApprovalCountWithTimeValidity(recoveryPublicKeyHash) >=\n LibGuardian.majorityOfGuardians()\n ) _executeRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Revoke recovery of account as guardian\n * @dev This method can only be called by guardian and guardian inputs the public key of the new owner\n When the threshold(majority of guardians) passes, it automatically revokes account recovery when recovery is pending\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function revokeAccountRecoveryApproval(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n if (\n !rs\n .isNewOwnerApproved[recoveryPublicKeyHash][msg.sender].isApproved ||\n !(block.timestamp <\n rs\n .isNewOwnerApproved[recoveryPublicKeyHash][msg.sender]\n .validUntil)\n ) revert AccountRecoveryFacet__NonExistentApproval();\n\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(false, 0);\n emit RecoveryApprovalRevoked(_recoveryPublicKey, msg.sender);\n }\n\n /**\n * @notice Executes recovery with signatures or on-chain pre-approvals\n * @dev This method validates the signatures of guardians or checks the on-chain pre-approved calls to check if the threshold passes\n * When the threshold passes, account recovery is executed and revert otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _guardians Array of guardians address that are approving the recovery of Account\n * @param _signatures Array of signature bytes that signed the approval hash\n */\n function executeRecovery(\n bytes calldata _recoveryPublicKey,\n address[] calldata _guardians,\n bytes[] calldata _signatures\n ) external override {\n if (_isRecoveryPending())\n revert AccountRecoveryFacet__RecoveryAlreadyOngoing();\n if (_guardians.length != _signatures.length)\n revert AccountRecoveryFacet__InvalidArrayLength();\n validateNewOwner(_recoveryPublicKey);\n\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n\n _checkApprover(_guardians);\n _checkDuplicateOnChainApprover(recoveryPublicKeyHash, _guardians);\n\n if (\n _guardians.length +\n getRecoveryApprovalCountWithTimeValidity(\n recoveryPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians()\n ) revert AccountRecoveryFacet__InsufficientGuardians();\n for (uint256 i; i < _guardians.length; ) {\n if (!LibGuardian.isGuardian(_guardians[i]))\n revert AccountRecoveryFacet__InvalidGuardian();\n if (\n !SignatureChecker.isValidSignatureNow(\n _guardians[i],\n recoveryPublicKeyHash,\n _signatures[i]\n )\n ) revert AccountRecoveryFacet__InvalidGuardianSignature();\n unchecked {\n ++i;\n }\n }\n _executeRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Executes recovery of the account. Note that execution and finalization is a different process\n * @dev Executes the recovery and adds recovery data to recovery configuration. Locks the account\n * @param _recoveryPublicKey Public Key of the account for recovery\n */\n function _executeRecovery(bytes memory _recoveryPublicKey) internal {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n unchecked {\n ++rs.nonce;\n }\n uint64 executeAfter = uint64(block.timestamp + _getRecoveryPeriod());\n rs.recoveryConfigs[INNER_STRUCT] = RecoveryConfig(\n _recoveryPublicKey,\n executeAfter // NOTE: Remove guardian Count\n );\n LibAppStorage.setLock(\n block.timestamp + _getLockPeriod(),\n AccountRecoveryFacet.executeRecovery.selector\n );\n emit RecoveryExecuted(_recoveryPublicKey, executeAfter);\n }\n\n /**\n * @notice Finalize recovery after recovery pending period. Recovery pending period can be set by user beforehand in SecurityManager\n * @dev This method finalizes recovery and fully changes the ownership of the account to the newly inputted recovery public key\n */\n function finalizeRecovery() external override {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n if (\n uint64(block.timestamp) <=\n rs.recoveryConfigs[INNER_STRUCT].executeAfter\n ) revert AccountRecoveryFacet__RecoveryPeriodNotOver();\n bytes memory recoveryOwner = rs\n .recoveryConfigs[INNER_STRUCT]\n .recoveryPublicKey;\n\n delete rs.recoveryConfigs[INNER_STRUCT];\n\n LibAppStorage.setLock(0, bytes4(0));\n\n LibAppStorage.initiateSignerMigration();\n address verificationFacet = address(\n bytes20(\n LibDiamond.diamondStorage().facets[\n s.validateOwnerSignatureSelector\n ]\n )\n );\n (bool success, bytes memory result) = verificationFacet.delegatecall(\n UNINIT_CALL\n );\n if (!success) revert AccountRecoveryFacet__CallNotSuccesful();\n uint256 validationData = uint256(bytes32(result));\n if (validationData != 1)\n revert AccountRecoveryFacet__SignerUninitializationFailure();\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n recoveryOwner\n );\n (success, result) = verificationFacet.delegatecall(initCall);\n if (!success) revert AccountRecoveryFacet__CallNotSuccesful();\n validationData = uint256(bytes32(result));\n if (validationData != 1)\n revert AccountRecoveryFacet__SignerInitializationFailure();\n LibAppStorage.finalizeSignerMigration();\n emit RecoveryFinalized(recoveryOwner);\n }\n\n /**\n * @notice Approves the cancellation of recovery\n * @dev This method approves the cancellation of recovery when recovery is still pending - waiting for finalization\n * @param _recoveryPublicKey Bytes of public key which is pending for recovery\n */\n function approveCancelRecovery(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"CancelRecovery\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + _getApprovalValidationPeriod()\n );\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit RecoveryCancellationApproved(_recoveryPublicKey, msg.sender);\n if (\n getRecoveryApprovalCountWithTimeValidity(recoveryPublicKeyHash) >=\n LibGuardian.majorityOfGuardians()\n ) {\n _cancelRecovery(_recoveryPublicKey);\n }\n }\n\n /**\n * @notice Hardstops an ongoing recovery\n * @dev This method provides a safety mechanism to protect owners of malicious guardians.\n * Owners can hardstop recovery when an malicious guardians starts the recovery process.\n * @param _signature Signature of the owner that signs the hash to hardstop recovery\n */\n function hardstopRecovery(bytes calldata _signature) external override {\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n \"0\",\n \"HardstopRecovery\"\n );\n if (\n !SignatureChecker.isValidSignatureNow(\n address(this),\n recoveryPublicKeyHash,\n _signature\n )\n ) revert AccountRecoveryFacet__InvalidOwnerSignature();\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n unchecked {\n ++rs.nonce;\n }\n delete rs.recoveryConfigs[INNER_STRUCT];\n LibAppStorage.setLock(0, bytes4(0));\n emit RecoveryHardstopped();\n }\n\n /**\n * @notice Cancels recovery with signatures or on-chain pre-approvals\n * @dev This method validates the signatures of guardians or checks the on-chain pre-approved calls to check if the threshold passes\n * When the threshold passes, account recovery is canceled and revert otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _guardians Array of guardians address that are approving the recovery of Account\n * @param _signatures Array of signature bytes that signed the cancellation approval hash\n */\n function cancelRecovery(\n bytes calldata _recoveryPublicKey,\n address[] calldata _guardians,\n bytes[] calldata _signatures\n ) external override {\n if (_guardians.length != _signatures.length)\n revert AccountRecoveryFacet__InvalidArrayLength();\n validateNewOwner(_recoveryPublicKey);\n\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"CancelRecovery\"\n );\n\n _checkApprover(_guardians);\n _checkDuplicateOnChainApprover(recoveryPublicKeyHash, _guardians);\n\n if (\n _guardians.length +\n getRecoveryApprovalCountWithTimeValidity(\n recoveryPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians()\n ) revert AccountRecoveryFacet__InsufficientGuardians();\n for (uint256 i; i < _guardians.length; ) {\n if (!LibGuardian.isGuardian(_guardians[i]))\n revert AccountRecoveryFacet__CallerNotGuardian();\n if (\n !SignatureChecker.isValidSignatureNow(\n _guardians[i],\n recoveryPublicKeyHash,\n _signatures[i]\n )\n ) revert AccountRecoveryFacet__InvalidGuardianSignature();\n unchecked {\n ++i;\n }\n }\n _cancelRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Cancel recovery when the recovery is pending. Unlock the account as well\n * @dev This method checks if the recovery is pending and reverts if not pending.\n * It increases the recovery nonce and deletes the recovery information and gets a small portion of gas in return\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function _cancelRecovery(bytes memory _recoveryPublicKey) internal {\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n LibAppStorage.setLock(0, bytes4(0));\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n unchecked {\n ++rs.nonce;\n }\n delete rs.recoveryConfigs[INNER_STRUCT];\n emit RecoveryCanceled(_recoveryPublicKey);\n }\n\n /**\n * @notice Validates the format of public key to be used for recovery\n * @dev This method checks if the public key format is correct and reverts otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function validateNewOwner(bytes memory _recoveryPublicKey) public view {\n if (\n !IVerificationFacet(\n LibLoupe.facetAddress(s.validateOwnerSignatureSelector)\n ).isValidKeyType(_recoveryPublicKey)\n ) revert AccountRecoveryFacet__InvalidRecoveryPublicKey();\n }\n\n /**\n * @notice Checks if recovery is currently pending\n * @return isPending Boolean indicating if recovery is pending\n */\n function _isRecoveryPending() internal view returns (bool isPending) {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n isPending = (rs.recoveryConfigs[INNER_STRUCT].executeAfter > 0);\n }\n\n /**\n * @notice Calculate the recovery hash dependent on chain, wallet address, nonce with EIP-191 prefix for safety\n * @dev Returns the keccak256 hash of EIP-191 msg hash packed with public key, salt, nonce, wallet address, etc\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _saltString Salt string to uniquely identify each recovery hash and for security\n * @return recoveryKeyHash Bytes32 string of the recovery hash\n */\n function getApprovalRecoveryKeyHash(\n bytes memory _recoveryPublicKey,\n string memory _saltString\n ) public view override returns (bytes32 recoveryKeyHash) {\n recoveryKeyHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n _recoveryPublicKey,\n _saltString,\n address(this),\n block.chainid,\n LibFacetStorage.recoveryStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Check the onchain approval of guardians and returns the number of guardians that approved\n * @dev Loop through the guardian addresses and returns the number of guardians that approved this recovery hash\n * @param _recoveryPublicKeyHash Bytes hash of newly recovered public key and recovery value of the account\n * @return approvalCount Number of guardians that approved\n */\n function getRecoveryApprovalCountWithTimeValidity(\n bytes32 _recoveryPublicKeyHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n for (uint256 i; i < guardianLength; ) {\n if (isRecoveryApproved(_recoveryPublicKeyHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Checks if the recovery is approved by the given approver\n * @param _recoveryPublicKeyHash Hash of the public key and configuration for recovery\n * @param _approver Address of approver\n * @return isApproved Bool value if recovery hash is approved\n */\n function isRecoveryApproved(\n bytes32 _recoveryPublicKeyHash,\n address _approver\n ) public view override returns (bool isApproved) {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n if (\n rs\n .isNewOwnerApproved[_recoveryPublicKeyHash][_approver].isApproved &&\n block.timestamp <\n rs.isNewOwnerApproved[_recoveryPublicKeyHash][_approver].validUntil\n ) {\n isApproved = true;\n }\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _recoveryPublicKeyHash Hash of recovery information\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _recoveryPublicKeyHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isRecoveryApproved(_recoveryPublicKeyHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert AccountRecoveryFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the lock period of this wallet address from security manager\n * @return lockPeriod value of lock period\n */\n function _getLockPeriod() internal view returns (uint256 lockPeriod) {\n lockPeriod = securityManager.lockPeriodOf(address(this));\n if (lockPeriod == 0) revert AccountRecoveryFacet__InvalidLockPeriod();\n }\n\n /**\n * @notice Returns the lock period of this wallet address from security manager\n * @return recoveryPeriod value of recovery period\n */\n function _getRecoveryPeriod()\n internal\n view\n returns (uint256 recoveryPeriod)\n {\n recoveryPeriod = securityManager.recoveryPeriodOf(address(this));\n if (recoveryPeriod == 0)\n revert AccountRecoveryFacet__InvalidRecoveryPeriod();\n }\n\n /**\n * @notice Returns the approval validation period of this wallet address from security manager\n * @return approvalValidationPeriod value of approval validation period\n */\n function _getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod == 0)\n revert AccountRecoveryFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the recovery nonce of this wallet address from security manager\n * @return nonce value of recovery nonce\n */\n function getRecoveryNonce() public view override returns (uint128 nonce) {\n nonce = LibFacetStorage.recoveryStorage().nonce;\n }\n\n /**\n * @notice Returns the recovery information of the pending recovery\n * @return recoveryConfig value struct of pending recovery\n */\n function getPendingRecovery()\n public\n view\n override\n returns (RecoveryConfig memory recoveryConfig)\n {\n recoveryConfig = LibFacetStorage.recoveryStorage().recoveryConfigs[\n INNER_STRUCT\n ];\n }\n}\n" + }, + "contracts/facets/base/DiamondCutFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibGuardian} from \"../../libraries/LibGuardian.sol\";\nimport {ISecurityManager} from \"../../infrastructure/interfaces/ISecurityManager.sol\";\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibFacetStorage, DiamondCutApprovalConfig, ApprovalConfig} from \"../../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"../Modifiers.sol\";\nimport {IDiamondCut} from \"./interfaces/IDiamondCut.sol\";\n\n/**\n * @title DiamondCut Facet\n * @dev Responsible for adding/removing/replace facets in Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DiamondCutFacet is Modifiers, IDiamondCut {\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Updates the flag for the interfaceId\n * @param _interfaceId InterfaceID to update the mapping\n * @param _flag Bool value to update the mapping of the given interface ID\n */\n function updateSupportsInterface(\n bytes4 _interfaceId,\n bool _flag\n ) external override onlyWhenUnlocked {\n LibDiamond.enforceIsSelf();\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId] = _flag;\n emit SupportsInterfaceUpdated(_interfaceId, _flag);\n }\n\n /**\n * @notice Add/replace/remove any number of functions and optionally execute\n * a function with delegatecall when guardians don't exist\n * @param _diamondCut Contains the facet addresses and function selectors\n * @param _init The address of the contract or facet to execute _calldata. It's prohibited in Barz\n */\n function diamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata\n ) external override onlyWhenUnlocked {\n LibDiamond.enforceIsSelf();\n\n _checkFacetCutValidity(_diamondCut);\n // require approval from guardian if guardian exists\n if (0 != LibGuardian.guardianCount())\n revert DiamondCutFacet__InvalidRouteWithGuardian();\n if (address(0) != _init) revert DiamondCutFacet__InvalidInitAddress();\n\n unchecked {\n ++LibFacetStorage.diamondCutStorage().nonce;\n }\n LibDiamond.diamondCut(_diamondCut, address(0), \"\");\n }\n\n /**\n * @notice Add/replace/remove any number of functions and optionally execute\n * a function with delegatecall when guardians exist\n * @param _diamondCut Contains the facet addresses and function selectors\n * @param _approvers Guardian or owner address that approves the diamond cut\n * @param _signatures Signature of Guardians or owner that approves the diamond cut\n */\n function diamondCutWithGuardian(\n FacetCut[] calldata _diamondCut,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n ) external override onlyWhenUnlocked {\n if (_approvers.length != _signatures.length)\n revert DiamondCutFacet__InvalidArrayLength();\n _checkFacetCutValidity(_diamondCut);\n if (0 == LibGuardian.guardianCount())\n revert DiamondCutFacet__InvalidRouteWithGuardian();\n\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(cutHash, _approvers);\n\n bool onChainOwnerApproval = getOwnerCutApprovalWithTimeValidity(\n cutHash\n );\n\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n if (\n _approvers.length +\n getDiamondCutApprovalCountWithTimeValidity(cutHash) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert DiamondCutFacet__InsufficientApprovers();\n\n bool ownerApproved;\n for (uint256 i; i < _approvers.length; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n _approvers[i] != address(this)\n ) revert DiamondCutFacet__InvalidApprover();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert DiamondCutFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n cutHash,\n _signatures[i]\n )\n ) revert DiamondCutFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n if (!ownerApproved && !onChainOwnerApproval)\n revert DiamondCutFacet__LackOfOwnerApproval();\n\n unchecked {\n ++LibFacetStorage.diamondCutStorage().nonce;\n }\n LibDiamond.diamondCut(_diamondCut, address(0), \"\");\n }\n\n /**\n * @notice Approves diamond cut. This can only be called directly from guardian or owner\n * @param _diamondCut Contains the facet addresses and function selectors\n */\n function approveDiamondCut(\n FacetCut[] calldata _diamondCut\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\n if (LibGuardian.guardianCount() == 0)\n revert DiamondCutFacet__InvalidRouteWithoutGuardian();\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n _checkFacetCutValidity(_diamondCut);\n\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(\n true,\n approvalValidUntil\n );\n emit DiamondCutApproved(_diamondCut);\n if (\n (getDiamondCutApprovalCountWithTimeValidity(cutHash) >=\n LibGuardian.majorityOfGuardians()) &&\n getOwnerCutApprovalWithTimeValidity(cutHash)\n ) {\n unchecked {\n ++LibFacetStorage.diamondCutStorage().nonce;\n }\n LibDiamond.diamondCut(_diamondCut, address(0), \"\");\n }\n }\n\n /**\n * @notice Revokes the approval of diamond cut. This can only be called directly from guardian or owner\n * @param _diamondCut Contains the facet addresses and function selectors\n */\n function revokeDiamondCutApproval(\n FacetCut[] calldata _diamondCut\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\n if (!ds.isDiamondCutApproved[cutHash][msg.sender].isApproved)\n revert DiamondCutFacet__CannotRevokeUnapproved();\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(false, 0);\n emit DiamondCutApprovalRevoked(_diamondCut);\n }\n\n /**\n * @notice Gets the number of approvals of diamond cut from guardians\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n */\n function getDiamondCutApprovalCountWithTimeValidity(\n bytes32 _diamondCutHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardiansLength = guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n if (isCutApproved(_diamondCutHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n return approvalCount;\n }\n\n /**\n * @notice Returns if the owner has approved the diamond cut\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @return isApprovedByOwner Bool value showing if the owner approved the cut\n */\n function getOwnerCutApprovalWithTimeValidity(\n bytes32 _diamondCutHash\n ) public view override returns (bool isApprovedByOwner) {\n isApprovedByOwner = isCutApproved(_diamondCutHash, address(this));\n }\n\n /**\n * @notice Returns if the given approver has approved the diamond cut\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @param _approver Address of approver\n * @return isApproved Bool value showing if the approver approved the cut\n */\n function isCutApproved(\n bytes32 _diamondCutHash,\n address _approver\n ) public view override returns (bool isApproved) {\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n isApproved = (ds\n .isDiamondCutApproved[_diamondCutHash][_approver].isApproved &&\n block.timestamp <\n ds.isDiamondCutApproved[_diamondCutHash][_approver].validUntil);\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _diamondCutHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isCutApproved(_diamondCutHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert DiamondCutFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the diamond cut hash. This function ensures that this hash is safe from replay attack by including\n * salt, address, chainId, and nonce, etc.\n * @param _diamondCut Contains the facet addresses and function selectors\n * @return cutHash Diamond Cut Hash\n */\n function getDiamondCutHash(\n FacetCut[] calldata _diamondCut\n ) public view override returns (bytes32 cutHash) {\n cutHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n keccak256(abi.encode(_diamondCut)),\n address(this),\n block.chainid,\n LibFacetStorage.diamondCutStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Returns the approval validation Period\n * @dev This method fetches the validation period from the security manager\n * @return approvalValidationPeriod Approval validation period of Barz contract fetched from security manager\n */\n function getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod <= 0)\n revert DiamondCutFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the diamond cut nonce of this wallet\n * @dev This method fetches the nonce from diamond cut storage\n * @return cutNonce Nonce of diamond cut to protect from reply attacks\n */\n function getDiamondCutNonce()\n public\n view\n override\n returns (uint128 cutNonce)\n {\n cutNonce = LibFacetStorage.diamondCutStorage().nonce;\n }\n}\n" + }, + "contracts/facets/base/DiamondLoupeFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {IERC165} from \"../../interfaces/ERC/IERC165.sol\";\nimport {IERC1271} from \"../../interfaces/ERC/IERC1271.sol\";\nimport {IERC677Receiver} from \"../../interfaces/ERC/IERC677Receiver.sol\";\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC1155Receiver} from \"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\";\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../../libraries/LibLoupe.sol\";\nimport {LibUtils} from \"../../libraries/LibUtils.sol\";\nimport {IDiamondCut} from \"../../facets/base/interfaces/IDiamondCut.sol\";\nimport {IStorageLoupe} from \"./interfaces/IStorageLoupe.sol\";\nimport {IDiamondLoupe} from \"./interfaces/IDiamondLoupe.sol\";\n\n/**\n * @title DiamondLoupe Facet\n * @dev DiamondLoupe contract compatible with EIP-2535\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DiamondLoupeFacet is IDiamondLoupe, IStorageLoupe, IERC165 {\n // Diamond Loupe Functions\n ////////////////////////////////////////////////////////////////////\n /// These functions are expected to be called frequently by tools off-chain.\n\n /**\n * @notice Gets all facets and their selectors.\n * @dev Barz uses a special architecture called default fallback handler. Default Fallback handler is used as a middleware\n * that holds the mapping of facet function selector and facet address that Barz uses. This helps Barz to reduce\n * significant amount of gas during the initialization process.\n * Hence, this method aggregates both the facet information from DefaulFallbackHandler and in diamond storage and shows the data to users.\n * @return facets_ Facet\n */\n function facets() public view override returns (Facet[] memory facets_) {\n Facet[] memory defaultFacet = LibDiamond\n .diamondStorage()\n .defaultFallbackHandler\n .facets();\n Facet[] memory _facets = LibLoupe.facets();\n uint256 numFacets = _facets.length;\n bytes4[] memory keys;\n address[] memory values;\n for (uint256 i; i < numFacets; ) {\n uint256 selectorsLength = _facets[i].functionSelectors.length;\n for (uint256 j; j < selectorsLength; ) {\n (keys, values) = LibUtils.setValue(\n keys,\n values,\n _facets[i].functionSelectors[j],\n _facets[i].facetAddress\n );\n unchecked {\n ++j;\n }\n }\n unchecked {\n ++i;\n }\n }\n {\n bool iIncrement;\n for (uint256 i; i < defaultFacet.length; ) {\n bool jIncrement;\n for (\n uint256 j;\n j < defaultFacet[i].functionSelectors.length;\n\n ) {\n if (\n LibUtils.getValue(\n keys,\n values,\n defaultFacet[i].functionSelectors[j]\n ) != address(0)\n ) {\n if (defaultFacet[i].functionSelectors.length == 1) {\n defaultFacet = LibUtils.removeFacetElement(\n defaultFacet,\n i\n );\n iIncrement = true;\n break;\n }\n defaultFacet[i].functionSelectors = LibUtils\n .removeElement(\n defaultFacet[i].functionSelectors,\n j\n );\n jIncrement = true;\n }\n if (!jIncrement) {\n unchecked {\n ++j;\n }\n } else {\n jIncrement = false;\n }\n }\n if (!iIncrement) {\n unchecked {\n ++i;\n }\n } else {\n iIncrement = false;\n }\n }\n }\n {\n uint256 facetLength = numFacets + defaultFacet.length;\n facets_ = new Facet[](facetLength);\n uint256 defaultFacetIndex;\n for (uint256 i; i < facetLength; ) {\n if (i < numFacets) {\n facets_[i] = _facets[i];\n bool jIncrementor;\n for (uint256 j; j < defaultFacet.length; ) {\n if (\n facets_[i].facetAddress ==\n defaultFacet[j].facetAddress\n ) {\n facets_[i].functionSelectors = LibUtils.mergeArrays(\n _facets[i].functionSelectors,\n defaultFacet[j].functionSelectors\n );\n defaultFacet = LibUtils.removeFacetElement(\n defaultFacet,\n j\n );\n jIncrementor = true;\n {\n facets_ = LibUtils.removeFacetElement(\n facets_,\n facets_.length - 1\n );\n }\n --facetLength;\n }\n if (!jIncrementor) {\n unchecked {\n ++j;\n }\n } else {\n jIncrementor = false;\n }\n }\n } else {\n facets_[i] = defaultFacet[defaultFacetIndex];\n ++defaultFacetIndex;\n }\n unchecked {\n ++i;\n }\n }\n }\n }\n\n /**\n * @notice Gets all the function selectors provided by a facet.\n * @param _facet The facet address.\n * @return facetFunctionSelectors_\n */\n function facetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n Facet[] memory facet = facets();\n uint256 facetLength = facet.length;\n for (uint256 i; i < facetLength; ) {\n if (facet[i].facetAddress == _facet)\n return facet[i].functionSelectors;\n unchecked {\n ++i;\n }\n }\n return facetFunctionSelectors_;\n }\n\n /**\n * @notice Get all the facet addresses used by Barz.\n * @return facetAddresses_\n */\n function facetAddresses()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n Facet[] memory facet = facets();\n uint256 facetLength = facet.length;\n facetAddresses_ = new address[](facetLength);\n for (uint256 i; i < facetLength; ) {\n facetAddresses_[i] = facet[i].facetAddress;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Gets the facet that supports the given selector.\n * @dev If facet is not found return address(0).\n * @param _functionSelector The function selector.\n * @return facetAddress_ The facet address.\n */\n function facetAddress(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n\n facetAddress_ = address(bytes20(ds.facets[_functionSelector]));\n if (facetAddress_ == address(0)) {\n facetAddress_ = IDiamondLoupe(ds.defaultFallbackHandler)\n .facetAddress(_functionSelector);\n }\n }\n\n /**\n * @notice SupportInterface to be compatible with EIP 165\n * @param _interfaceId Interface ID for detecting the interface\n * @return isSupported Bool value showing if the standard is supported in the contract\n */\n function supportsInterface(\n bytes4 _interfaceId\n ) external view override returns (bool isSupported) {\n isSupported =\n _interfaceId == type(IERC165).interfaceId ||\n _interfaceId == IDiamondCut.diamondCut.selector ||\n _interfaceId == type(IDiamondLoupe).interfaceId ||\n _interfaceId == type(IERC1155Receiver).interfaceId ||\n _interfaceId == type(IERC721Receiver).interfaceId ||\n _interfaceId == type(IERC777Recipient).interfaceId ||\n _interfaceId == IERC1271.isValidSignature.selector ||\n _interfaceId == type(IERC677Receiver).interfaceId ||\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId];\n }\n\n /**\n * @notice Returns the facet from the diamond storage. This excludes the facets from the default fallback handler\n * @return facets_ Facet information attached directly to diamond storage\n */\n function facetsFromStorage()\n external\n view\n override\n returns (Facet[] memory facets_)\n {\n facets_ = LibLoupe.facets();\n }\n\n /**\n * @notice Returns the facet address attached to the given function selector. This excludes the facets from the default fallback handler\n * @param _functionSelector Function selector to fetch the facet address from diamond storage\n * @return facetAddress_ Facet address mapped with the function selector\n */\n function facetAddressFromStorage(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n facetAddress_ = LibLoupe.facetAddress(_functionSelector);\n }\n\n /**\n * @notice Returns all facet addresses attached directly to diamond storage. This excludes the facets from the default fallback handler\n * @return facetAddresses_ All facet addresses attached directly to diamond storage\n */\n function facetAddressesFromStorage()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n facetAddresses_ = LibLoupe.facetAddresses();\n }\n\n /**\n * @notice Returns function selectors of given facet address attached directly to diamond storage. This excludes the facets from the default fallback handler\n * @param _facet Facet address to fetch the facet function selectors from diamond storage\n * @return facetFunctionSelectors_ Facet function selectors of the given facet address\n */\n function facetFunctionSelectorsFromStorage(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n facetFunctionSelectors_ = LibLoupe.facetFunctionSelectors(_facet);\n }\n}\n" + }, + "contracts/facets/base/interfaces/IDiamondCut.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title DiamondCut Facet Interface\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IDiamondCut {\n error DiamondCutFacet__InvalidRouteWithGuardian();\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\n error DiamondCutFacet__InvalidArrayLength();\n error DiamondCutFacet__InsufficientApprovers();\n error DiamondCutFacet__InvalidApprover();\n error DiamondCutFacet__InvalidApproverSignature();\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\n error DiamondCutFacet__CannotRevokeUnapproved();\n error DiamondCutFacet__LackOfOwnerApproval();\n error DiamondCutFacet__OwnerAlreadyApproved();\n error DiamondCutFacet__DuplicateApproval();\n error DiamondCutFacet__InvalidInitAddress();\n\n event DiamondCutApproved(FacetCut[] diamondCut);\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\n\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\n\n enum FacetCutAction {\n Add,\n Replace,\n Remove\n }\n // Add=0, Replace=1, Remove=2\n\n struct FacetCut {\n address facetAddress;\n FacetCutAction action;\n bytes4[] functionSelectors;\n }\n\n /// @notice Add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param diamondCut Contains the facet addresses and function selectors\n /// @param init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function diamondCut(\n FacetCut[] calldata diamondCut,\n address init,\n bytes calldata _calldata\n ) external;\n\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\n\n function diamondCutWithGuardian(\n FacetCut[] calldata diamondCut,\n address[] calldata approvers,\n bytes[] calldata signatures\n ) external;\n\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\n\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\n\n function getDiamondCutApprovalCountWithTimeValidity(\n bytes32 diamondCutHash\n ) external view returns (uint256);\n\n function getOwnerCutApprovalWithTimeValidity(\n bytes32 diamondCutHash\n ) external view returns (bool);\n\n function isCutApproved(\n bytes32 diamondCutHash,\n address approver\n ) external view returns (bool);\n\n function getDiamondCutHash(\n FacetCut[] calldata diamondCut\n ) external view returns (bytes32);\n\n function getDiamondCutNonce() external view returns (uint128);\n}\n" + }, + "contracts/facets/base/interfaces/IDiamondLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n// A loupe is a small magnifying glass used to look at diamonds.\n// These functions look at diamonds\ninterface IDiamondLoupe {\n /// These functions are expected to be called frequently\n /// by tools.\n\n struct Facet {\n address facetAddress;\n bytes4[] functionSelectors;\n }\n\n /// @notice Gets all facet addresses and their four byte function selectors.\n /// @return facets_ Facet\n function facets() external view returns (Facet[] memory facets_);\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n /// @return facetFunctionSelectors_\n function facetFunctionSelectors(\n address _facet\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses()\n external\n view\n returns (address[] memory facetAddresses_);\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(\n bytes4 _functionSelector\n ) external view returns (address facetAddress_);\n}\n" + }, + "contracts/facets/base/interfaces/IStorageLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"./IDiamondLoupe.sol\";\n\n/**\n * @title LoupeFromStorage Interface\n * @dev Interface contract to function as a loupe facet directly attached to diamond storage of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IStorageLoupe {\n /// These functions are expected to be called frequently\n /// by tools.\n\n /// @notice Gets all facet addresses and their four byte function selectors.\n /// @return facets_ Facet\n function facetsFromStorage()\n external\n view\n returns (IDiamondLoupe.Facet[] memory);\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n function facetFunctionSelectorsFromStorage(\n address _facet\n ) external view returns (bytes4[] memory);\n\n /// @notice Get all the facet addresses used by a diamond.\n function facetAddressesFromStorage()\n external\n view\n returns (address[] memory);\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n function facetAddressFromStorage(\n bytes4 _functionSelector\n ) external view returns (address);\n}\n" + }, + "contracts/facets/GuardianFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibFacetStorage, GuardianStorage, StorageConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IGuardianFacet} from \"./interfaces/IGuardianFacet.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Guardian Facet\n * @dev Contract that enables addition/removal of guardians from Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract GuardianFacet is IGuardianFacet {\n ISecurityManager public immutable securityManager;\n uint8 public constant INNER_STRUCT = 0;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Add guardians to Barz.\n * @dev This method internally calls addGuardian which checks the validity of guardian address and adds\n * as guardian if valid\n * @param _guardians Array of addresses to add as guardian\n */\n function addGuardians(address[] calldata _guardians) external override {\n LibDiamond.enforceIsSelf();\n for (uint256 i; i < _guardians.length; ) {\n addGuardian(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Add a guardian to Barz.\n * @dev This method checks if the function is called by the owner and validates the address of guardian\n * When the validation passes, guardian address is added to the pending state waiting for confirmation\n * @param _guardian Address to add as guardian\n */\n function addGuardian(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (_guardian == address(this))\n revert GuardianFacet__GuardianCannotBeSelf();\n if (isGuardian(_guardian)) revert GuardianFacet__DuplicateGuardian();\n if (_guardian == address(0))\n revert GuardianFacet__ZeroAddressGuardian();\n if (\n keccak256(abi.encodePacked(_guardian)) ==\n keccak256(IVerificationFacet(address(this)).owner())\n ) revert GuardianFacet__OwnerCannotBeGuardian();\n\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n if (\n gs.pending[id] != 0 ||\n block.timestamp <= gs.pending[id] + getSecurityWindow()\n ) revert GuardianFacet__DuplicateGuardianAddition();\n\n uint256 securityPeriod = getAdditionSecurityPeriod();\n gs.pending[id] = block.timestamp + securityPeriod;\n emit GuardianAdditionRequested(\n _guardian,\n block.timestamp + securityPeriod\n );\n }\n\n /**\n * @notice Remove guardians from Barz.\n * @dev This method internally calls removeGuardian which checks the validity of guardian and removes\n * guardian when the request is valid\n * @param _guardians Array of addresses to be removed\n */\n function removeGuardians(address[] calldata _guardians) external override {\n LibDiamond.enforceIsSelf();\n for (uint256 i; i < _guardians.length; ) {\n removeGuardian(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Remove a guardian from Barz.\n * @dev This method validates if the guardian to be removed is a guardian and puts the guardian removal\n * to a pending state waiting to be confirmed.\n * @param _guardian Address of guardian to be removed\n */\n function removeGuardian(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n if (!isGuardian(_guardian)) revert GuardianFacet__NonExistentGuardian();\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n if (\n gs.pending[id] != 0 ||\n block.timestamp <= gs.pending[id] + getSecurityWindow()\n ) revert GuardianFacet__DuplicateGuardianRemoval();\n\n uint256 securityPeriod = getRemovalSecurityPeriod();\n gs.pending[id] = block.timestamp + securityPeriod;\n emit GuardianRemovalRequested(\n _guardian,\n block.timestamp + securityPeriod\n );\n }\n\n /**\n * @notice Confirm addition of guardians\n * @dev This method internally calls confirmGuardianAddition which checks the validity of pending request.\n * Guardians are fully added when they pass the validation. Anyone can call this function.\n * @param _guardians Array of guardian addresses to be added\n */\n function confirmGuardianAdditions(\n address[] calldata _guardians\n ) external override {\n for (uint256 i; i < _guardians.length; ) {\n confirmGuardianAddition(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Confirm addition of a guardian\n * @dev This method checks the validity of pending request.\n * Guardians are fully added when they pass the validation. Anyone can call this function.\n * @param _guardian Guardian address to be added\n */\n function confirmGuardianAddition(address _guardian) public override {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingAddition();\n if (gs.pending[id] >= block.timestamp)\n revert GuardianFacet__PendingAdditionNotOver();\n if (block.timestamp >= gs.pending[id] + getSecurityWindow())\n revert GuardianFacet__PendingAdditionExpired();\n\n _addGuardian(_guardian);\n\n delete gs.pending[id];\n emit GuardianAdded(_guardian);\n }\n\n /**\n * @notice Confirm removal of guardians\n * @dev This method internally calls confirmGuardianRemoval to check the validity guardian removal confirmation.\n * Guardians are fully removed when they pass the validation. Anyone can call this function.\n * @param _guardians Array of guardian addresses to be removed\n */\n function confirmGuardianRemovals(\n address[] calldata _guardians\n ) external override {\n for (uint256 i; i < _guardians.length; ) {\n confirmGuardianRemoval(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Confirm removal of a guardian\n * @dev This method checks the validity guardian removal confirmation.\n * Guardian is fully removed when they pass the validation. Anyone can call this function.\n * @param _guardian Guardian address to be removed\n */\n function confirmGuardianRemoval(address _guardian) public override {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingRemoval();\n if (gs.pending[id] >= block.timestamp)\n revert GuardianFacet__PendingRemovalNotOver();\n if (block.timestamp >= gs.pending[id] + getSecurityWindow())\n revert GuardianFacet__PendingAdditionExpired();\n\n _removeGuardian(_guardian);\n delete gs.pending[id];\n emit GuardianRemoved(_guardian);\n }\n\n /**\n * @notice Cancel pending guardian addition\n * @dev This method checks if the previous request for guardian request exists.\n * It reverts if previous request is not pending and cancels the addition otherwise.\n * @param _guardian Guardian address to be canceled from addition\n */\n function cancelGuardianAddition(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingAddition();\n delete gs.pending[id];\n emit GuardianAdditionCancelled(_guardian);\n }\n\n /**\n * @notice Cancel pending guardian removal\n * @dev This method checks if the previous request for guardian request exists.\n * It reverts if previous request is not pending and cancels the removal otherwise.\n * @param _guardian Guardian address to be canceled from removal\n */\n function cancelGuardianRemoval(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingRemoval();\n delete gs.pending[id];\n emit GuardianRemovalCancelled(_guardian);\n }\n\n /**\n * @notice Get the addition security period of current account from security manager\n * @dev This method returns the uint value if addition security period\n * @return additionSecurityPeriod Uint256 value of addition security period\n */\n function getAdditionSecurityPeriod()\n public\n view\n override\n returns (uint256 additionSecurityPeriod)\n {\n additionSecurityPeriod = securityManager.additionSecurityPeriodOf(\n address(this)\n );\n if (additionSecurityPeriod == 0)\n revert GuardianFacet__InvalidAdditionSecurityPeriod();\n }\n\n /**\n * @notice Get the removal security period of current account from security manager\n * @dev This method returns the uint value if removal security period\n * @return removalSecurityPeriod Uint256 value of removal security period\n */\n function getRemovalSecurityPeriod()\n public\n view\n override\n returns (uint256 removalSecurityPeriod)\n {\n removalSecurityPeriod = securityManager.removalSecurityPeriodOf(\n address(this)\n );\n if (removalSecurityPeriod == 0)\n revert GuardianFacet__InvalidRemovalSecurityPeriod();\n }\n\n /**\n * @notice Get the security window of current account from security manager\n * @dev This method returns the uint value if security window\n * @return securityWindow Uint256 value of removal security period\n */\n function getSecurityWindow()\n public\n view\n override\n returns (uint256 securityWindow)\n {\n securityWindow = securityManager.securityWindowOf(address(this));\n if (securityWindow == 0) revert GuardianFacet__InvalidSecurityWindow();\n }\n\n /**\n * @notice Checks if the addition of the given guardian address is pending\n * @dev This method returns the bool value of whether the guardian address is pending addition\n * @return isPending Bool value of representing the pending of guardian addition\n */\n function isAdditionPending(\n address _guardian\n ) public view override returns (bool isPending) {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n isPending = _isPending(id);\n }\n\n /**\n * @notice Checks if the removal of the given guardian address is pending\n * @dev This method returns the bool value of whether the guardian address is pending removal\n * @return isPending Bool value of representing the pending of guardian removal\n */\n function isRemovalPending(\n address _guardian\n ) public view override returns (bool isPending) {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n isPending = _isPending(id);\n }\n\n /**\n * @notice Checks if the given hash is pending\n * @dev This method returns the bool value whether the hash is pending\n * @return isPending Bool value of representing the pending of guardian operation\n */\n function _isPending(\n bytes32 _idHash\n ) internal view returns (bool isPending) {\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n isPending = ((gs.pending[_idHash] > 0 &&\n gs.pending[_idHash] < block.timestamp) &&\n block.timestamp < gs.pending[_idHash] + getSecurityWindow());\n }\n\n /**\n * @notice Adds guardian to storage config. This is called when guardian is fully added.\n * @dev This method add guardian address and config information to Facet Storage dedicated for guardian\n * When this function is called, guardian is fully added to this Barz Smart Account\n * @param _guardian Address of guardian to be added\n */\n function _addGuardian(address _guardian) internal {\n if (!isAdditionPending(_guardian))\n revert GuardianFacet__InvalidGuardianAddition();\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n if (config.info[_guardian].exists)\n revert GuardianFacet__AlreadyExists();\n\n config.info[_guardian].exists = true;\n config.info[_guardian].index = uint128(config.addresses.length);\n config.addresses.push(_guardian);\n }\n\n /**\n * @notice Removes guardian to storage config. This is called when guardian is fully removed.\n * @dev This method remove guardian address and config information to Facet Storage dedicated for guardian\n * When this function is called, guardian is fully removed from this Barz Smart Account\n * @param _guardian Address of guardian to be removed\n */\n function _removeGuardian(address _guardian) internal {\n if (!isRemovalPending(_guardian))\n revert GuardianFacet__InvalidGuardianRemoval();\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n if (!config.info[_guardian].exists)\n revert GuardianFacet__NonExistentGuardian();\n\n address lastAddress = config.addresses[config.addresses.length - 1];\n if (_guardian != lastAddress) {\n uint128 targetIndex = config.info[_guardian].index;\n config.addresses[targetIndex] = lastAddress;\n config.info[lastAddress].index = targetIndex;\n }\n config.addresses.pop();\n delete config.info[_guardian];\n\n emit GuardianRemoved(_guardian);\n }\n\n /**\n * @notice Reads guardian storage and fetches the addresses into an array from the storage\n * @dev This method fetches the guardian storage and returns the list of guardian addresses\n * @return addresses Array of addresses comprised of guardian\n */\n function getGuardians()\n public\n view\n override\n returns (address[] memory addresses)\n {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n uint256 addressesLen = config.addresses.length;\n addresses = new address[](addressesLen);\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the number of majority of guardians\n * @return majorityOfGuardians_ Number of majority of guardians e.g., 2 if 3 guardians / 3 if 5 guardians\n */\n function majorityOfGuardians()\n public\n view\n override\n returns (uint256 majorityOfGuardians_)\n {\n majorityOfGuardians_ = LibGuardian.majorityOfGuardians();\n }\n\n /**\n * @notice Reads guardian storage and fetches the addresses into an array from the storage\n * @dev This method fetches the guardian storage and returns the list of guardian addresses\n * @return guardianNumber Array of guardians in the account\n */\n function guardianCount()\n public\n view\n override\n returns (uint256 guardianNumber)\n {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n guardianNumber = config.addresses.length;\n }\n\n /**\n * @notice Reads guardian storage and checks if the given address is a guardian\n * @return isGuardian_ Bool value representing if the given address is guardian\n */\n function isGuardian(\n address _guardian\n ) public view override returns (bool isGuardian_) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n isGuardian_ = config.info[_guardian].exists;\n }\n\n /**\n * @notice Checks if the guardian number is zero and returns of guardian facet is okay to be removed\n * @return isRemovable Bool value representing if guardian facet is removable\n */\n function isGuardianFacetRemovable()\n external\n view\n override\n returns (bool isRemovable)\n {\n isRemovable = (0 == guardianCount());\n }\n}\n" + }, + "contracts/facets/interfaces/IAccountFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IEntryPoint} from \"../../aa-4337/interfaces/IEntryPoint.sol\";\n\n/**\n * @title Account Facet Interface\n * @dev Interface of module contract that provides the account features and init/unitialization of signer\n * compatible with EIP-1271 & EIP-4337\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IAccountFacet {\n event AccountInitialized(\n IEntryPoint indexed entryPoint,\n bytes indexed ownerPublicKey\n );\n // NOTE: Added Below Event\n event VerificationSuccess(bytes32);\n event VerificationFailure(bytes32);\n\n error AccountFacet__InitializationFailure();\n error AccountFacet__RestrictionsFailure();\n error AccountFacet__NonExistentVerificationFacet();\n error AccountFacet__CallNotSuccessful();\n error AccountFacet__InvalidArrayLength();\n\n function initialize(\n address verificationFacet,\n address anEntryPoint,\n address facetRegistry,\n address _defaultFallBack,\n bytes calldata _ownerPublicKey\n ) external returns (uint256);\n\n function execute(address dest, uint256 value, bytes calldata func) external;\n\n function executeBatch(\n address[] calldata dest,\n uint256[] calldata value,\n bytes[] calldata func\n ) external;\n}\n" + }, + "contracts/facets/interfaces/IAccountRecoveryFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {RecoveryConfig} from \"../../libraries/LibFacetStorage.sol\";\n\n/**\n * @title Account Recovery Facet Interface\n * @dev Interface of contract that enables recovery of accounts when owner key is unavailable\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IAccountRecoveryFacet {\n event RecoveryExecuted(\n bytes indexed recoveryPublicKey,\n uint64 executeAfter\n );\n event RecoveryFinalized(bytes indexed recoveryPublicKey);\n event RecoveryCanceled(bytes indexed recoveryPublicKey);\n event RecoveryApproved(\n bytes indexed recoveryPublicKey,\n address indexed guardian,\n uint64 validUntil\n );\n event RecoveryApprovalRevoked(\n bytes indexed recoveryPublicKey,\n address indexed guardian\n );\n event RecoveryCancellationApproved(\n bytes indexed recoveryPublicKey,\n address indexed guardian\n );\n event RecoveryHardstopped();\n\n error AccountRecoveryFacet__CallerNotGuardian();\n error AccountRecoveryFacet__InvalidRecoveryPublicKey();\n error AccountRecoveryFacet__SignerInitializationFailure();\n error AccountRecoveryFacet__SignerUninitializationFailure();\n error AccountRecoveryFacet__InvalidArrayLength();\n error AccountRecoveryFacet__InsufficientGuardians();\n error AccountRecoveryFacet__RecoveryAlreadyOngoing();\n error AccountRecoveryFacet__NonexistentRecovery();\n error AccountRecoveryFacet__NonExistentApproval();\n error AccountRecoveryFacet__RecoveryPeriodNotOver();\n error AccountRecoveryFacet__InvalidLockPeriod();\n error AccountRecoveryFacet__InvalidRecoveryPeriod();\n error AccountRecoveryFacet__InvalidApprovalValidationPeriod();\n error AccountRecoveryFacet__InvalidGuardian();\n error AccountRecoveryFacet__InvalidGuardianSignature();\n error AccountRecoveryFacet__InvalidOwnerSignature();\n error AccountRecoveryFacet__CallNotSuccesful();\n error AccountRecoveryFacet__DuplicateApproval();\n\n function approveAccountRecovery(bytes calldata recoveryPublicKey) external;\n\n function revokeAccountRecoveryApproval(\n bytes calldata recoveryPublicKey\n ) external;\n\n function executeRecovery(\n bytes calldata recoveryPublicKey,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function finalizeRecovery() external;\n\n function approveCancelRecovery(bytes calldata recoveryPublicKey) external;\n\n function cancelRecovery(\n bytes calldata recoveryPublicKey,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function hardstopRecovery(bytes calldata signature) external;\n\n function getApprovalRecoveryKeyHash(\n bytes memory recoveryPublicKey,\n string memory saltString\n ) external view returns (bytes32);\n\n function getRecoveryApprovalCountWithTimeValidity(\n bytes32 recoveryPublicKeyHash\n ) external view returns (uint256);\n\n function isRecoveryApproved(\n bytes32 recoveryPublicKeyHash,\n address approver\n ) external view returns (bool);\n\n function getRecoveryNonce() external view returns (uint128);\n\n function getPendingRecovery() external view returns (RecoveryConfig memory);\n}\n" + }, + "contracts/facets/interfaces/IGuardianFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Guardian Facet Interface\n * @dev Interface of guaridna contract that enables addition/removal of guardians from Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IGuardianFacet {\n event GuardianAdditionRequested(\n address indexed guardian,\n uint256 executeAfter\n );\n event GuardianRemovalRequested(\n address indexed guardian,\n uint256 executeAfter\n );\n event GuardianAdditionCancelled(address indexed guardian);\n event GuardianRemovalCancelled(address indexed guardian);\n event GuardianAdded(address indexed guardian);\n event GuardianRemoved(address indexed guardian);\n\n error GuardianFacet__GuardianCannotBeSelf();\n error GuardianFacet__DuplicateGuardian();\n error GuardianFacet__OwnerCannotBeGuardian();\n error GuardianFacet__DuplicateGuardianAddition();\n error GuardianFacet__DuplicateGuardianRemoval();\n error GuardianFacet__UnknownPendingAddition();\n error GuardianFacet__PendingAdditionNotOver();\n error GuardianFacet__UnknownPendingRemoval();\n error GuardianFacet__PendingRemovalNotOver();\n error GuardianFacet__PendingAdditionExpired();\n error GuardianFacet__InvalidAdditionSecurityPeriod();\n error GuardianFacet__InvalidRemovalSecurityPeriod();\n error GuardianFacet__InvalidSecurityWindow();\n error GuardianFacet__NonExistentGuardian();\n error GuardianFacet__AlreadyExists();\n error GuardianFacet__InvalidGuardianAddition();\n error GuardianFacet__InvalidGuardianRemoval();\n error GuardianFacet__ZeroAddressGuardian();\n\n function addGuardian(address guardian) external;\n\n function addGuardians(address[] calldata guardians) external;\n\n function removeGuardian(address guardian) external;\n\n function removeGuardians(address[] calldata guardians) external;\n\n function confirmGuardianAddition(address guardian) external;\n\n function confirmGuardianAdditions(address[] calldata guardian) external;\n\n function confirmGuardianRemoval(address guardian) external;\n\n function confirmGuardianRemovals(address[] calldata guardian) external;\n\n function cancelGuardianAddition(address guardian) external;\n\n function cancelGuardianRemoval(address guardian) external;\n\n function isGuardian(address guardian) external view returns (bool);\n\n function isAdditionPending(address guardian) external view returns (bool);\n\n function isRemovalPending(address guardian) external view returns (bool);\n\n function isGuardianFacetRemovable() external view returns (bool);\n\n function getAdditionSecurityPeriod() external view returns (uint256);\n\n function getRemovalSecurityPeriod() external view returns (uint256);\n\n function getSecurityWindow() external view returns (uint256);\n\n function getGuardians() external view returns (address[] memory);\n\n function majorityOfGuardians() external view returns (uint256);\n\n function guardianCount() external view returns (uint256);\n}\n" + }, + "contracts/facets/interfaces/ILockFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Lock} from \"../../libraries/LibAppStorage.sol\";\n\n/**\n * @title Lock Facet Interface\n * @dev Interface of Lock contract that enables full lock/unlock of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface ILockFacet {\n event Locked(uint64 releaseAfter);\n event Unlocked();\n\n error LockFacet__InvalidRecoveryPeriod();\n error LockFacet__CannotUnlock();\n error LockFacet__InvalidSignature();\n error LockFacet__InvalidApprover();\n\n function lock() external;\n\n function unlock(address approver, bytes calldata signature) external;\n\n function getLockPeriod() external view returns (uint256);\n\n function isLocked() external view returns (bool);\n\n function getUnlockHash() external view returns (bytes32);\n\n function lockNonce() external view returns (uint128);\n\n function getPendingLock() external view returns (Lock memory);\n}\n" + }, + "contracts/facets/interfaces/IMultiSigFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Multi-sig facet Interface\n * @dev Interface of Multi-signature Facet with custom threshold.\n Wallet that adds this facet becomes a multi-sig wallet\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IMultiSigFacet {\n event ThresholdChanged(uint256 threshold);\n event OwnerAdded(address indexed newOwner);\n event OwnerRemoved(address indexed prevOwner);\n event HashApproved(bytes32 hashToApprove, address indexed owner);\n\n error MultiSigFacet__InvalidThreshold();\n error MultisigFacet__InvalidOwnerCount();\n error MultiSigFacet__InvalidRoute();\n error MultiSigFacet__InsufficientSignerLength();\n error MultiSigFacet__InvalidInitData();\n error MultiSigFacet__InvalidOwnerAddress();\n error MultiSigFacet__InvalidOwnerPair();\n error MultiSigFacet__InvalidSignatureLength();\n error MultiSigFacet__InvalidSignatureType();\n error MultiSigFacet__DuplicateOwner();\n error MultiSigFacet__OnlyOwner();\n\n function checkSignatures(\n bytes32 _dataHash,\n bytes calldata _signatures,\n uint256 _threshold\n ) external view returns (uint256);\n\n function splitSignatures(\n bytes calldata _signatures,\n uint256 _nextOffset\n )\n external\n pure\n returns (\n address owner,\n bytes memory signature,\n uint256 signatureType,\n uint256 nextOffset\n );\n\n function approveHash(bytes32 hashToApprove) external;\n\n function addOwner(address newOwner, uint256 threshold) external;\n\n function removeOwner(\n address prevOwner,\n address removedOwner,\n uint256 threshold\n ) external;\n\n function swapOwner(\n address prevOwner,\n address oldOwner,\n address newOwner\n ) external;\n\n function changeThreshold(uint256 _threshold) external;\n\n function isOwner(address owner) external view returns (bool);\n\n function getThreshold() external view returns (uint256);\n\n function getOwners() external view returns (address[] memory);\n}\n" + }, + "contracts/facets/interfaces/IRestrictionsFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Restrictions Facet Interface\n * @dev Interface of Restrictions contract that enables modular restrictions in Barz\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IRestrictionsFacet {\n event RestrictionAdded(address indexed restriction);\n event RestrictionRemoved(address indexed restriction);\n\n error RestrictionsFacet__EmptyRestrictionsList();\n error RestrictionsFacet__RestrictionNotFound();\n error RestrictionsFacet__RestrictionAlreadyExists();\n error RestrictionsFacet__ZeroAddressRestrictions();\n error RestrictionsFacet__ZeroAddressRestrictionsFacet();\n error RestrictionsFacet__RemainingRestrictionsCantBeEmpty();\n\n function initializeRestrictions(\n address[] memory _restrictions\n ) external returns (uint256);\n\n function uninitializeRestrictions() external returns (uint256);\n\n function getRestrictions() external view returns (address[] memory);\n\n function addRestriction(address restriction) external;\n\n function removeRestriction(address restriction) external;\n\n function verifyRestrictions(\n address from,\n address to,\n uint256 value,\n bytes calldata _calldata\n ) external returns (uint256);\n}\n" + }, + "contracts/facets/interfaces/ISignatureMigrationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureMigrationConfig} from \"../../libraries/LibFacetStorage.sol\";\n\n/**\n * @title Signature Migration Facet Interface\n * @dev Interface of Signature Migration contract for migrating user signature scheme to a new scheme user sets\n * Which could include\n * - ECDSA on Secp256K1 Curve\n * - ECDSA on Secp256R1 Curve\n * - BLS, Schnorr, etc\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface ISignatureMigrationFacet {\n event SignatureSchemeMigration(\n address indexed prevVerificationFacet,\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n event SignatureMigrationApproved(\n bytes newPublicKey,\n address indexed newVerificationFacet,\n bytes4[] verificationFuncSelectors,\n address indexed guardian,\n uint128 approvalValidUntil\n );\n event SignatureMigrationApprovalRevoked(\n bytes newPublicKey,\n address indexed newVerificationFacet,\n bytes4[] verificationFuncSelectors,\n address indexed guardian\n );\n event SignatureMigrationExecuted(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors,\n uint128 migrateAfter\n );\n event SignatureMigrationCanceled(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n event SignatureMigrationCancellationApproved(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n\n error SignatureMigrationFacet__SignerUninitializationFailure();\n error SignatureMigrationFacet__SignerInitializationFailure();\n error SignatureMigrationFacet__InvalidRouteWithGuardian();\n error SignatureMigrationFacet__InvalidKeyType();\n error SignatureMigrationFacet__InsufficientApprovers();\n error SignatureMigrationFacet__InvalidApproverSignature();\n error SignatureMigrationFacet__InvalidGuardian();\n error SignatureMigrationFacet__NonExistentApprover();\n error SignatureMigrationFacet__InvalidMigrationPeriod();\n error SignatureMigrationFacet__NonexistentMigration();\n error SignatureMigrationFacet__MigrationPeriodNotOver();\n error SignatureMigrationFacet__InvalidArrayLength();\n error SignatureMigrationFacet__InvalidApprovalValidationPeriod();\n error SignatureMigrationFacet__CannotRevokeUnapproved();\n error SignatureMigrationFacet__LackOfOwnerApproval();\n error SignatureMigrationFacet__OwnerAlreadyApproved();\n error SignatureMigrationFacet__NonExistentVerificationFacet();\n error SignatureMigrationFacet__DuplicateApproval();\n\n function migrateSignatureScheme(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function migrateSignatureSchemeWithGuardian(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors,\n address[] calldata approvers,\n bytes[] calldata signatures\n ) external;\n\n function approveSignatureSchemeMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function revokeSignatureMigrationApproval(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function finalizeSignatureMigration() external;\n\n function approveCancelSignatureMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function cancelSignatureMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function getApprovalMigrationKeyHash(\n bytes memory recoveryPublicKey,\n address newVerificationFacet,\n bytes4[] memory newVerificationFuncSelectors,\n string memory saltString\n ) external view returns (bytes32);\n\n function getMigrationOwnerApprovalWithTimeValidity(\n bytes32 publicKeyHash\n ) external view returns (bool);\n\n function getMigrationApprovalCountWithTimeValidity(\n bytes32 publicKeyHash\n ) external view returns (uint256);\n\n function isMigrationApproved(\n bytes32 migrationPublicKeyHash,\n address approver\n ) external view returns (bool);\n\n function getMigrationNonce() external view returns (uint128);\n\n function isMigrationPending() external view returns (bool);\n\n function getPendingMigration()\n external\n view\n returns (SignatureMigrationConfig memory);\n}\n" + }, + "contracts/facets/interfaces/IVerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {UserOperation} from \"../../aa-4337/interfaces/UserOperation.sol\";\n\n/**\n * @title Verification Facet Interface\n * @dev Implements logic for user ops signature verification\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface IVerificationFacet {\n event SignerInitialized(bytes);\n event SignerUninitialized();\n\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n error VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n error VerificationFacet__InitializationFailure();\n error VerificationFacet__InvalidFacetMapping();\n\n function initializeSigner(bytes memory) external returns (uint256);\n\n function uninitializeSigner() external returns (uint256);\n\n function validateOwnerSignatureSelector() external view returns (bytes4);\n\n function owner() external view returns (bytes memory);\n\n function isValidKeyType(bytes calldata) external view returns (bool);\n\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) external view returns (uint256);\n}\n" + }, + "contracts/facets/LockFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage, Lock} from \"../libraries/LibAppStorage.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibFacetStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {ILockFacet} from \"./interfaces/ILockFacet.sol\";\n\n/**\n * @title Lock Facet\n * @dev Contract that enables full lock/unlock of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract LockFacet is ILockFacet, Modifiers {\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Locks the account for the lock period. Lock period is defined in the security manager and it's customizable\n * This function can only be called when account is unlocked by owner or guardians\n * @dev This method checks the caller and if the account is currently locked and locks the account after fetching the\n * Lock period from the owner.\n */\n function lock() external override onlyGuardianOrOwner onlyWhenUnlocked {\n uint256 unlockTime = block.timestamp + getLockPeriod();\n unchecked {\n ++LibFacetStorage.lockStorage().nonce;\n }\n LibAppStorage.setLock(unlockTime, LockFacet.lock.selector);\n emit Locked(uint64(unlockTime));\n }\n\n /**\n * @notice Locks the account when the account is locked. This function can be called by anyone but must provide the approver address and signature.\n * The approver should be one of the guardians or owner.\n * @dev This method takes the approver address and the signature. After validating the address and the signature, it unlocks the account immediately.\n * Only one of the guardian or owner is required to lock and unlock the account.\n * @param _approver Address of approver approving the unlock of Barz account\n * @param _signature Signature of the approver that signed the msg hash for unlocking the account\n */\n function unlock(\n address _approver,\n bytes calldata _signature\n ) external override onlyWhenLocked {\n if (_approver != address(this) && !LibGuardian.isGuardian(_approver))\n revert LockFacet__InvalidApprover();\n if (\n !SignatureChecker.isValidSignatureNow(\n _approver,\n getUnlockHash(),\n _signature\n )\n ) revert LockFacet__InvalidSignature();\n _unlock();\n }\n\n /**\n * @notice Unlocks the account and increments the lock nonce\n */\n function _unlock() private {\n if (s.locks[INNER_STRUCT].locker != LockFacet.lock.selector)\n revert LockFacet__CannotUnlock();\n unchecked {\n ++LibFacetStorage.lockStorage().nonce;\n }\n LibAppStorage.setLock(0, bytes4(0));\n emit Unlocked();\n }\n\n /**\n * @notice Returns the lock period of current Barz account. Lock period information is held by Security Manager\n * @return lockPeriod Uint value of lock period in seconds\n */\n function getLockPeriod() public view override returns (uint256 lockPeriod) {\n lockPeriod = securityManager.lockPeriodOf(address(this));\n if (lockPeriod == 0) revert LockFacet__InvalidRecoveryPeriod();\n }\n\n /**\n * @notice Returns if the account is locked or not\n * @dev This method fetches the current block timestamp and compares that with release time.\n * After checking the timestamp and release time, it returns if the account is still locked or not.\n * @return isLocked_ Uint value of lock period in seconds\n */\n function isLocked() public view override returns (bool isLocked_) {\n isLocked_ = uint64(block.timestamp) < s.locks[INNER_STRUCT].release;\n }\n\n /**\n * @notice Calculates the unlock hash and returns the unlock hash safe from signature reply attack\n * @dev This method calculates the unlock hash with EIP-191 prefix, wallet address, chainID, and nonce\n * It packs the result and packs them and hashes it.\n * @return unlockHash Bytes32 unlock hash\n */\n function getUnlockHash() public view override returns (bytes32 unlockHash) {\n unlockHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n \"Unlock\",\n address(this),\n block.chainid,\n lockNonce()\n )\n )\n )\n );\n }\n\n /**\n * @notice Returns lock nonce of account. Reads nonce from lock storage within facet storage\n * @return lockNonce_ Uint128 value of lock nonce. This is incremented whenever the account is lock/unlocked\n */\n function lockNonce() public view override returns (uint128 lockNonce_) {\n lockNonce_ = LibFacetStorage.lockStorage().nonce;\n }\n\n /**\n * @notice Returns the overall information of current lock\n * @return pendingLock Struct value including all information of pending lock\n */\n function getPendingLock()\n public\n view\n override\n returns (Lock memory pendingLock)\n {\n pendingLock = s.locks[INNER_STRUCT];\n }\n}\n" + }, + "contracts/facets/Modifiers.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\n\n/**\n * @title Modifiers\n * @dev Responsible for providing modifiers/util functions to Facet contracts\n * @author David Yongjun Kim (@Powerstream3604)\n */\nabstract contract Modifiers is BarzStorage {\n uint8 constant INNER_STRUCT = 0;\n\n error CallerNotGuardian();\n error CallerNotGuardianOrOwner();\n error DuplicateApprover();\n error ZeroApproverLength();\n error UnregisteredFacetAndSelectors();\n\n /**\n * @notice Modifier to only allow guardian to make a call, reverts if any other entity is the caller\n */\n modifier onlyGuardian() {\n if (!LibGuardian.isGuardian(msg.sender)) revert CallerNotGuardian();\n _;\n }\n\n /**\n * @notice Modifier to only allow guardian or owner to make a call, reverts if any other entity is the caller\n */\n modifier onlyGuardianOrOwner() {\n if (!LibGuardian.isGuardian(msg.sender) && address(this) != msg.sender)\n revert CallerNotGuardianOrOwner();\n _;\n }\n\n /**\n * @notice Checks if the approver address is the array is unique with no duplicate\n * @dev This method loops through the array and checks if a duplicate address exists, it reverts if duplicate address exists\n * @param approvers Array of address\n */\n function _checkApprover(\n address[] memory approvers\n ) internal pure returns (bool) {\n uint256 approverLength = approvers.length;\n if (0 == approverLength) revert ZeroApproverLength();\n for (uint256 i; i < approverLength - 1; ) {\n for (uint256 j = i + 1; j < approverLength; ) {\n if (approvers[i] == approvers[j]) {\n revert DuplicateApprover(); // Found a duplicate\n }\n unchecked {\n ++j;\n }\n }\n unchecked {\n ++i;\n }\n }\n return false; // No duplicates found\n }\n\n /**\n * @notice Checks if the facet getting added or replaced is registered to facet registry\n * @dev This method loops through the cut and checks if the facet getting added/replaced is registered to facet registry\n * @param _diamondCut Array of FacetCut, data for diamondCut defined in EIP-2535\n */\n function _checkFacetCutValidity(\n IDiamondCut.FacetCut[] memory _diamondCut\n ) internal view {\n uint256 diamondCutLength = _diamondCut.length;\n for (uint256 i; i < diamondCutLength; ) {\n if (\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Add ||\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Replace\n ) {\n if (\n !s.facetRegistry.areFacetFunctionSelectorsRegistered(\n _diamondCut[i].facetAddress,\n _diamondCut[i].functionSelectors\n )\n ) revert UnregisteredFacetAndSelectors();\n }\n unchecked {\n ++i;\n }\n }\n }\n}\n" + }, + "contracts/facets/RestrictionsFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ReentrancyGuard} from \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, RestrictionsStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {IRestriction} from \"../restrictions/IRestriction.sol\";\nimport {IRestrictionsFacet} from \"./interfaces/IRestrictionsFacet.sol\";\n\n/**\n * @title Restrictions facet\n * @dev Responsible for storing and verifying different kinds of restrictions, for example:\n * - Whitelist / Blacklist\n * - Daily limits\n * - Trading time restrictions\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract RestrictionsFacet is IRestrictionsFacet, ReentrancyGuard {\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceRestrictionsInitialize();\n }\n\n /**\n * @notice Intialize restrictions of Barz. Restrictions facet call restriction contracts for restriction validation\n * before each call\n * @param _restrictions The initial array of restrictions.\n * @return initSuccess Int value showing if the initialization of restriction is successful\n */\n function initializeRestrictions(\n address[] calldata _restrictions\n ) public override returns (uint256 initSuccess) {\n LibDiamond.enforceIsSelf();\n LibAppStorage.enforceRestrictionsInitialize();\n\n if (_restrictions.length == 0) {\n // You can't initialize RestrictionsFacet with an empty list of restrictions\n revert RestrictionsFacet__EmptyRestrictionsList();\n }\n for (uint256 i; i < _restrictions.length; ) {\n if (_restrictions[i] == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictions();\n unchecked {\n ++i;\n }\n }\n\n LibFacetStorage.restrictionsStorage().restrictions = _restrictions;\n _updateRestrictionsMap(_restrictions, true);\n initSuccess = 1;\n }\n\n /**\n * @notice Unitialize restrictions of Barz\n * @return uninitSuccess Int value showing if the initialization of restriction is successful\n */\n function uninitializeRestrictions()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibDiamond.enforceIsSelf();\n LibAppStorage.setRestrictionsUninitialized();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n _updateRestrictionsMap(restrictionsStorage.restrictions, false);\n restrictionsStorage.restrictions = new address[](0);\n uninitSuccess = 1;\n }\n\n /**\n * @notice Returns the list of Restrictions contract address\n * @return restrictions Addresses of IRestriction which are currently active\n */\n function getRestrictions()\n public\n view\n override\n returns (address[] memory restrictions)\n {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n restrictions = restrictionsStorage.restrictions;\n }\n\n /**\n * @notice Adds restrictions to Barz with validation on the restriction contract address.\n * This method is only callable by the owner(self).\n * @param _restriction The address of the restriction to be added.\n */\n function addRestriction(address _restriction) external override {\n LibDiamond.enforceIsSelf();\n if (LibDiamond.restrictionsFacet() == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictionsFacet();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n if (_restriction == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictions();\n if (restrictionsStorage.exists[_restriction])\n revert RestrictionsFacet__RestrictionAlreadyExists();\n\n restrictionsStorage.restrictions.push(_restriction);\n restrictionsStorage.exists[_restriction] = true;\n\n emit RestrictionAdded(_restriction);\n }\n\n /**\n * @notice Remove restrictions from Barz if it existed. This method is only callable by the owner(self).\n * @param _restriction The address of the restriction to be removed.\n */\n function removeRestriction(address _restriction) external override {\n LibDiamond.enforceIsSelf();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n if (!restrictionsStorage.exists[_restriction])\n revert RestrictionsFacet__RestrictionNotFound();\n\n address[] storage restrictions = restrictionsStorage.restrictions;\n\n uint256 indexToDelete = restrictions.length;\n uint256 restrictionsLen = restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n if (restrictions[i] == _restriction) {\n indexToDelete = i;\n break;\n }\n unchecked {\n ++i;\n }\n }\n\n if (indexToDelete == 0 && restrictionsLen == 1) {\n revert RestrictionsFacet__RemainingRestrictionsCantBeEmpty();\n } else if (indexToDelete == restrictionsLen) {\n revert RestrictionsFacet__RestrictionNotFound();\n } else {\n restrictions[indexToDelete] = restrictions[restrictionsLen - 1];\n restrictions.pop();\n }\n\n restrictionsStorage.exists[_restriction] = false;\n emit RestrictionRemoved(_restriction);\n }\n\n /**\n * @notice Sets the restrictions address value mapping to true or false when adding/removing restriction contracts\n * @param _restrictions List of restriction contracts address\n * @param _newValue Bool value to flag to the list of restrictions contracts\n */\n function _updateRestrictionsMap(\n address[] memory _restrictions,\n bool _newValue\n ) internal {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n uint restrictionsLen = _restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n restrictionsStorage.exists[_restrictions[i]] = _newValue;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @dev Iterates over all restrictions and verifies each of them with the transaction parameters.\n * @param _from The address of the sender, that will be signing the transaction.\n * @param _to The receiving address.\n * @param _value Amount of ETH to transfer from sender to recipient.\n * @param _calldata Optional field to include arbitrary data.\n * @return 0 if all the checks passed, 1 otherwise.\n */\n function verifyRestrictions(\n address _from,\n address _to,\n uint256 _value,\n bytes calldata _calldata\n ) external nonReentrant returns (uint256) {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n uint restrictionsLen = restrictionsStorage.restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n IRestriction restriction = IRestriction(\n restrictionsStorage.restrictions[i]\n );\n bool checkPassed = restriction.check(_from, _to, _value, _calldata);\n if (!checkPassed) {\n return 1;\n }\n unchecked {\n ++i;\n }\n }\n\n return 0;\n }\n}\n" + }, + "contracts/facets/SignatureMigrationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, SignatureMigrationStorage, SignatureMigrationConfig, SignatureMigrationApprovalConfig, ApprovalConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IDiamondCut} from \"./base/interfaces/IDiamondCut.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {ISignatureMigrationFacet} from \"./interfaces/ISignatureMigrationFacet.sol\";\n\n/**\n * @title Signature Migration Facet\n * @dev Responsible for migrating user signature scheme to a new scheme user sets\n * Which could include\n * - ECDSA on Secp256K1 Curve\n * - ECDSA on Secp256R1 Curve\n * - BLS, Schnorr, etc\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract SignatureMigrationFacet is ISignatureMigrationFacet, Modifiers {\n bytes constant UNINIT_CALL =\n abi.encodeWithSignature(\"uninitializeSigner()\");\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This modifier verifies if the public key format matches with the new verification facet\n * @param _publicKey Bytes of public key to be validated for the new verification facet\n * @param _newVerificationFacet Address of new verification facet\n */\n modifier validateKeyType(\n bytes memory _publicKey,\n address _newVerificationFacet\n ) {\n if (\n !IVerificationFacet(_newVerificationFacet).isValidKeyType(\n _publicKey\n )\n ) revert SignatureMigrationFacet__InvalidKeyType();\n _;\n }\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n // IMPORTANT NOTE: In the client side when they call this function, the func selectors should be sorted in ascending order\n // to prevent different hash with same items in the array\n /**\n * @notice Moves the state of migration to a pending state. When pending state is over after pending period time,\n * Migration can be finalized. This function can only be called by self and when the account is unlocked.\n * @dev This method checks if the caller is self and if guardians exists. It migrates signature request to a pending state\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function migrateSignatureScheme(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n public\n override\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n // Only self contract can call this function\n LibDiamond.enforceIsSelf();\n // Should revert if guardian exist\n if (0 != LibGuardian.guardianCount())\n revert SignatureMigrationFacet__InvalidRouteWithGuardian();\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n // NOTE: Migration requires a pending period & confirmation from owner to prevent a\n // single call changing the ownership of the wallet\n /**\n * @notice Migrate signature scheme when guardians exists. Verifies the signature of guardians and moves migration to pending state.\n * Which can then be finalized when pending period is over. Owner's approval is mandatory for migration to happen\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _approvers List of approvers. This could include owner\n */\n function migrateSignatureSchemeWithGuardian(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n )\n public\n override\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n // Should revert if does not guardian exist\n if (0 == LibGuardian.guardianCount())\n revert SignatureMigrationFacet__InvalidRouteWithGuardian();\n if (_approvers.length != _signatures.length)\n revert SignatureMigrationFacet__InvalidArrayLength();\n\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(migrationPublicKeyHash, _approvers);\n\n bool onChainOwnerApproval = getMigrationOwnerApprovalWithTimeValidity(\n migrationPublicKeyHash\n );\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n\n if (\n _approvers.length +\n getMigrationApprovalCountWithTimeValidity(\n migrationPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert SignatureMigrationFacet__InsufficientApprovers();\n {\n // To prevent Stack too deep\n bool ownerApproved;\n for (uint256 i; i < _approvers.length; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n address(this) != _approvers[i]\n ) revert SignatureMigrationFacet__InvalidGuardian();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert SignatureMigrationFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n migrationPublicKeyHash,\n _signatures[i]\n )\n ) revert SignatureMigrationFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n\n if (!ownerApproved && !onChainOwnerApproval)\n revert SignatureMigrationFacet__LackOfOwnerApproval();\n }\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Internal function that moves signature mgiration to a pending state.\n * @dev This method increments migration nonce and sets the migration in the migration config. Emits events for migration execution\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _migrateSignatureScheme(\n address _newVerificationFacet,\n bytes memory _newPublicKey,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal {\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n unchecked {\n ++ms.nonce;\n }\n uint64 migrateAfter = uint64(block.timestamp + getMigrationPeriod());\n\n ms.migrationConfigs[INNER_STRUCT] = SignatureMigrationConfig(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n migrateAfter\n );\n\n emit SignatureMigrationExecuted(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors,\n migrateAfter\n );\n }\n\n /**\n * @notice Approves signature scheme migration on-chain. This can be called by owner or guardian only when the account is unlocked.\n * When the threshold of the migration approval passed and owner approval is granted, it automatically moves migration to a pending state\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function approveSignatureSchemeMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n public\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit SignatureMigrationApproved(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n msg.sender,\n approvalValidUntil\n );\n if (\n getMigrationApprovalCountWithTimeValidity(migrationPublicKeyHash) >=\n LibGuardian.majorityOfGuardians() &&\n getMigrationOwnerApprovalWithTimeValidity(migrationPublicKeyHash)\n )\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Revokes the approval of signature migration done on-chain. Emits revoke event when revoked.\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function revokeSignatureMigrationApproval(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n external\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n if (!isMigrationApproved(migrationPublicKeyHash, msg.sender))\n revert SignatureMigrationFacet__CannotRevokeUnapproved();\n\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(false, 0);\n emit SignatureMigrationApprovalRevoked(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n msg.sender\n );\n }\n\n /**\n * @notice Finalizes the pending signature scheme migration. This function can only be called by owner.\n * It removes the facets of the previous verification facet and adds the new verification facet.\n * After finalizing migration, it emits migration event which shows the change of the verification facet\n */\n function finalizeSignatureMigration() external override {\n // NOTE: Only owner can call this function\n LibDiamond.enforceIsSelf();\n\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n\n if (!isMigrationPending())\n revert SignatureMigrationFacet__NonexistentMigration();\n\n if (\n uint64(block.timestamp) <=\n ms.migrationConfigs[INNER_STRUCT].migrateAfter\n ) revert SignatureMigrationFacet__MigrationPeriodNotOver();\n address newVerificationFacet = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationVerificationFacet;\n bytes4[] memory newVerificationFuncSelectors = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationSelectors;\n bytes memory newPublicKey = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationPublicKey;\n\n address prevVerificationFacet = LibLoupe.facetAddress(\n s.validateOwnerSignatureSelector\n );\n if (prevVerificationFacet == address(0))\n revert SignatureMigrationFacet__NonExistentVerificationFacet();\n\n IDiamondCut.FacetCut[] memory UninitCut;\n IDiamondCut.FacetCut[] memory InitCut;\n {\n bytes4[] memory prevVerificationFuncSelectors = LibLoupe\n .facetFunctionSelectors(prevVerificationFacet);\n\n UninitCut = new IDiamondCut.FacetCut[](1);\n InitCut = new IDiamondCut.FacetCut[](1);\n UninitCut[0] = IDiamondCut.FacetCut({\n facetAddress: address(0),\n action: IDiamondCut.FacetCutAction.Remove,\n functionSelectors: prevVerificationFuncSelectors\n });\n InitCut[0] = IDiamondCut.FacetCut({\n facetAddress: newVerificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: newVerificationFuncSelectors\n });\n {\n IDiamondCut.FacetCut[]\n memory facetCuts = new IDiamondCut.FacetCut[](2);\n facetCuts[0] = UninitCut[0];\n facetCuts[1] = InitCut[0];\n _checkFacetCutValidity(facetCuts);\n }\n LibAppStorage.initiateSignerMigration();\n address verificationFacet = address(\n bytes20(\n LibDiamond.diamondStorage().facets[\n s.validateOwnerSignatureSelector\n ]\n )\n );\n\n (bool uninitSuccess, bytes memory uninitResult) = verificationFacet\n .delegatecall(UNINIT_CALL);\n if (!uninitSuccess || uint256(bytes32(uninitResult)) != 1)\n revert SignatureMigrationFacet__SignerUninitializationFailure();\n LibAppStorage.finalizeSignerMigration();\n\n LibDiamond.diamondCut(UninitCut, address(0), \"\");\n }\n {\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n newPublicKey\n );\n\n // Every Verification Facet should comply with initializeSigner(bytes)\n // to be compatible with the Barz contract(for initialization)\n LibDiamond.diamondCut(InitCut, address(0), \"\");\n (bool initSuccess, bytes memory initResult) = newVerificationFacet\n .delegatecall(initCall);\n if (!initSuccess || uint256(bytes32(initResult)) != 1)\n revert SignatureMigrationFacet__SignerInitializationFailure();\n\n emit SignatureSchemeMigration(\n prevVerificationFacet,\n newVerificationFacet,\n newPublicKey,\n newVerificationFuncSelectors\n );\n }\n }\n\n /**\n * @notice Approve cancellation of signature migration. If cancellation approval passes guardian threshold with owner approval\n * it automatically cancels the migration.\n * @dev This method checks if the caller is one of guardian or owner and sets true for the cancellation hash in the approval config.\n * It internally calls _cancelSignatureMigration for canceling the migration\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function approveCancelSignatureMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n external\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"CancelSignatureMigration\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit SignatureMigrationCancellationApproved(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n if (\n getMigrationApprovalCountWithTimeValidity(migrationPublicKeyHash) >=\n LibGuardian.majorityOfGuardians() &&\n getMigrationOwnerApprovalWithTimeValidity(migrationPublicKeyHash)\n )\n _cancelSignatureMigration(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Verifies the signature of guardians/owner and cancels the signature migration.\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _approvers List of approvers. This could include owner\n */\n function cancelSignatureMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n )\n external\n override\n validateKeyType(_newPublicKey, _newVerificationFacet)\n onlyWhenUnlocked\n {\n if (_approvers.length != _signatures.length)\n revert SignatureMigrationFacet__InvalidArrayLength();\n\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"CancelSignatureMigration\"\n );\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(migrationPublicKeyHash, _approvers);\n\n bool onChainOwnerApproval = getMigrationOwnerApprovalWithTimeValidity(\n migrationPublicKeyHash\n );\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n if (\n _approvers.length +\n getMigrationApprovalCountWithTimeValidity(\n migrationPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert SignatureMigrationFacet__InsufficientApprovers();\n {\n // To prevent stack too deep\n bool ownerApproved;\n for (uint256 i; i < _approvers.length; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n address(this) != _approvers[i]\n ) revert SignatureMigrationFacet__NonExistentApprover();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert SignatureMigrationFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n migrationPublicKeyHash,\n _signatures[i]\n )\n ) revert SignatureMigrationFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n if (!ownerApproved && !onChainOwnerApproval)\n revert SignatureMigrationFacet__LackOfOwnerApproval();\n }\n _cancelSignatureMigration(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Internal function that cancels signature migration.\n * @dev This method increments migration nonce and deletes the migration from the migration config. Emits events for migration cancellation\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _cancelSignatureMigration(\n address _newVerificationFacet,\n bytes memory _newPublicKey,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal {\n if (!isMigrationPending())\n revert SignatureMigrationFacet__NonexistentMigration();\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n unchecked {\n ++ms.nonce;\n }\n delete ms.migrationConfigs[INNER_STRUCT];\n emit SignatureMigrationCanceled(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Checks if the facets to be added from new verification facet is registered to facet registry\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _checkMigrationCutValidity(\n address _newVerificationFacet,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal view {\n IDiamondCut.FacetCut[] memory facetCuts = new IDiamondCut.FacetCut[](1);\n facetCuts[0] = IDiamondCut.FacetCut({\n facetAddress: _newVerificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: _newVerificationFuncSelectors\n });\n _checkFacetCutValidity(facetCuts);\n }\n\n /**\n * @notice Returns if the migration is pending of not\n * @dev This method fetches the migration storage and checks if the migrate after is above 0 value\n * @return isPending Bool value that shows if the migration is pending\n */\n function isMigrationPending()\n public\n view\n override\n returns (bool isPending)\n {\n SignatureMigrationStorage storage rs = LibFacetStorage\n .migrationStorage();\n isPending = rs.migrationConfigs[INNER_STRUCT].migrateAfter > 0;\n }\n\n /**\n * @notice Returns the migration hash. This function ensures that this hash is safe from replay attack by including\n * public key, verification facet, function selectors, salt, address, chainId, and nonce.\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _saltString Salt value for generating the migration hash\n * @return migrationKeyHash Bytes32 string of the migration key hash\n */\n function getApprovalMigrationKeyHash(\n bytes memory _newPublicKey,\n address _newVerificationFacet,\n bytes4[] memory _newVerificationFuncSelectors,\n string memory _saltString\n ) public view override returns (bytes32 migrationKeyHash) {\n migrationKeyHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n _newPublicKey,\n _newVerificationFacet,\n keccak256(abi.encode(_newVerificationFuncSelectors)),\n _saltString,\n address(this),\n block.chainid,\n LibFacetStorage.migrationStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Checks if the owner approved the hash for migration\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @return isApprovedByOwner Bool value of showing if the owner approved it or not\n */\n function getMigrationOwnerApprovalWithTimeValidity(\n bytes32 _migrationPublicKeyHash\n ) public view override returns (bool isApprovedByOwner) {\n isApprovedByOwner = isMigrationApproved(\n _migrationPublicKeyHash,\n address(this)\n );\n }\n\n /**\n * @notice Checks how many of the guardians approved the migration hash\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @return approvalCount Number of approvals\n */\n function getMigrationApprovalCountWithTimeValidity(\n bytes32 _migrationPublicKeyHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardiansLength = guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n if (isMigrationApproved(_migrationPublicKeyHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n return approvalCount;\n }\n\n /**\n * @notice Checks if the migration is approved by the given approver\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @param _approver Address of approver\n * @return isApproved Bool value if migration hash is approved\n */\n function isMigrationApproved(\n bytes32 _migrationPublicKeyHash,\n address _approver\n ) public view override returns (bool isApproved) {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n isApproved = (ms\n .isMigrationApproved[_migrationPublicKeyHash][_approver].isApproved &&\n block.timestamp <\n ms\n .isMigrationApproved[_migrationPublicKeyHash][_approver]\n .validUntil);\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _migrationPublicKeyHash Hash of migration information\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _migrationPublicKeyHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isMigrationApproved(_migrationPublicKeyHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert SignatureMigrationFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the migration period of this wallet\n * @dev This method fetches the migration period from the security manager\n * @return migrationPeriod Migration period of Barz contract fetched from security manager\n */\n function getMigrationPeriod()\n internal\n view\n returns (uint128 migrationPeriod)\n {\n migrationPeriod = securityManager.migrationPeriodOf(address(this));\n if (migrationPeriod == 0)\n revert SignatureMigrationFacet__InvalidMigrationPeriod();\n }\n\n /**\n * @notice Returns the validation period of this wallet\n * @dev This method fetches the validation period from the security manager\n * @return approvalValidationPeriod Validation period of Barz contract fetched from security manager\n */\n function getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod == 0)\n revert SignatureMigrationFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the migration nonce of this wallet\n * @dev This method fetches the nonce from migration storage\n * @return migrationNonce Nonce of migration to protect from reply attacks\n */\n function getMigrationNonce()\n public\n view\n override\n returns (uint128 migrationNonce)\n {\n migrationNonce = LibFacetStorage.migrationStorage().nonce;\n }\n\n /**\n * @notice Returns the migration configuration of this wallet\n * @dev This method fetches the migration config from the migration storage\n * @return pendingMigrationConfig Migration config currently pending for signature migration\n */\n function getPendingMigration()\n external\n view\n override\n returns (SignatureMigrationConfig memory pendingMigrationConfig)\n {\n pendingMigrationConfig = LibFacetStorage\n .migrationStorage()\n .migrationConfigs[INNER_STRUCT];\n }\n}\n" + }, + "contracts/facets/TokenReceiverFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {IERC1155Receiver} from \"../interfaces/ERC/IERC1155Receiver.sol\";\nimport {IERC677Receiver} from \"../interfaces/ERC/IERC677Receiver.sol\";\n\n/**\n * @title TokenReceiver Facet\n * @dev Contract that enables receiving ERC721/ERC1155/ERC777/ERC677 Tokens with safe transfer\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract TokenReceiverFacet is\n IERC721Receiver,\n IERC1155Receiver,\n IERC777Recipient,\n IERC677Receiver\n{\n /**\n * @notice Handles ERC721 Token callback.\n * return Standardized onERC721Received return value.\n */\n function onERC721Received(\n address,\n address,\n uint256,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC721Receiver.onERC721Received.selector;\n }\n\n /**\n * @notice Handles ERC1155 Token callback.\n * return Standardized onERC1155Received return value.\n */\n function onERC1155Received(\n address,\n address,\n uint256,\n uint256,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC1155Receiver.onERC1155Received.selector;\n }\n\n /**\n * @notice Handles ERC1155 Token batch callback.\n * return Standardized onERC1155BatchReceived return value.\n */\n function onERC1155BatchReceived(\n address,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC1155Receiver.onERC1155BatchReceived.selector;\n }\n\n /**\n * @notice Handles ERC777 Token callback.\n * Does not return value, empty implementation.\n */\n function tokensReceived(\n address,\n address,\n address,\n uint256,\n bytes calldata,\n bytes calldata\n ) external pure override {}\n\n /**\n * @notice Handles ERC677 Token callback.\n * return true.\n */\n function onTokenTransfer(\n address,\n uint256,\n bytes calldata\n ) external pure override returns (bool) {\n return true;\n }\n}\n" + }, + "contracts/facets/verification/MultiSigFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {UserOperation} from \"../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../../libraries/LibLoupe.sol\";\nimport {LibAppStorage} from \"../../libraries/LibAppStorage.sol\";\nimport {LibMultiSigStorage, MultiSigStorage} from \"../../libraries/LibMultiSigStorage.sol\";\nimport {IERC1271} from \"../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../interfaces/IVerificationFacet.sol\";\nimport {IMultiSigFacet} from \"../interfaces/IMultiSigFacet.sol\";\n\n/**\n * @title Multi-sig facet\n * @dev Multi-signature Facet with custom threshold.\n * Wallet that adds this facet becomes a multi-sig wallet.\n * Reference signature_format.md documentation for Multi-sig facet details\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract MultiSigFacet is IMultiSigFacet, IVerificationFacet, IERC1271 {\n using ECDSA for bytes32;\n\n address public immutable self;\n\n address internal constant SENTINEL_OWNERS = address(0x1);\n uint256 internal constant ADDRESS = 20;\n uint256 internal constant SIG_TYPE = 1;\n uint256 internal constant SIG_LEN = 4;\n uint256 internal constant THRESHOLD = 4;\n uint256 internal constant INVALID_SIG = 1;\n uint256 internal constant VALID_SIG = 0;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in Multisig Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the right format and initializes signer storage in k1 storage.\n * @param _owners Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _owners\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n\n if (!isValidKeyType(_owners)) revert MultiSigFacet__InvalidInitData();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n uint256 threshold = uint256(uint32(bytes4(_owners)));\n uint256 ownerCount = (_owners.length - THRESHOLD) / ADDRESS;\n\n if (threshold == 0) revert MultiSigFacet__InvalidThreshold();\n if (ownerCount == 0) revert MultisigFacet__InvalidOwnerCount();\n\n address currentOwner = SENTINEL_OWNERS;\n uint256 ptr = THRESHOLD;\n address owner_;\n for (uint256 i; i < ownerCount; ) {\n owner_ = address(bytes20(_owners[ptr:ptr + ADDRESS]));\n ptr += ADDRESS;\n if (\n owner_ == address(0) ||\n owner_ == SENTINEL_OWNERS ||\n owner_ == address(this) ||\n owner_ == currentOwner\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[owner_] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n\n ms.owners[currentOwner] = owner_;\n currentOwner = owner_;\n\n unchecked {\n ++i;\n }\n }\n ms.owners[currentOwner] = SENTINEL_OWNERS;\n ms.ownerCount = ownerCount;\n ms.threshold = threshold;\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_owners);\n }\n\n /**\n * @notice Uninitialize signer in K1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n ++ms.counter;\n address[] memory ownerlist = getOwners();\n uint256 ownerlistLength = ownerlist.length;\n for (uint256 i; i < ownerlistLength; ) {\n ms.owners[ownerlist[i]] = address(0);\n unchecked {\n ++i;\n }\n }\n ms.owners[SENTINEL_OWNERS] = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls checkSignatures with\n * user operation hash and signature together with the threshold.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n // Data 1 is invalid, Data 0 is valid\n validationData = checkSignatures(\n userOpHash,\n userOp.signature,\n LibMultiSigStorage.multisigStorage().threshold\n );\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n return this.validateOwnerSignature.selector;\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n uint totalLength = ms.ownerCount * ADDRESS;\n bytes memory result = new bytes(totalLength);\n\n // populate return array\n uint256 index;\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n while (currentOwner != SENTINEL_OWNERS) {\n assembly {\n mstore(\n add(result, add(32, mul(index, ADDRESS))),\n shl(96, currentOwner)\n )\n }\n currentOwner = ms.owners[currentOwner];\n index++;\n }\n\n return result;\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key should comply with the format in the signature_format.md doc\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n uint256 publicKeyLength = _publicKey.length;\n if (\n publicKeyLength < ADDRESS + THRESHOLD ||\n (publicKeyLength - THRESHOLD) % ADDRESS != 0\n ) return false;\n\n uint256 threshold = uint256(uint32(bytes4(_publicKey)));\n uint256 ownerCount = (publicKeyLength - THRESHOLD) / ADDRESS;\n\n isValid = !(ownerCount < threshold || threshold == 0);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes calldata _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (checkSignatures(\n _hash,\n _signature,\n LibMultiSigStorage.multisigStorage().threshold\n ) == VALID_SIG)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n\n /**\n * @notice Validates the format of the signature and verifies if the signature is signed by the expected key.\n * Reference signature_format.md doc for details about signature format and signature types\n * @param _dataHash Bytes value of data hash signed by the owners\n * @param _signatures Bytes value of signature which should comply with signature format\n * @param _threshold Uint256 value of current Multi-sig Barz's threshold\n */\n function checkSignatures(\n bytes32 _dataHash,\n bytes calldata _signatures,\n uint256 _threshold\n ) public view returns (uint256) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n address lastOwner = address(0);\n address currentOwner;\n bytes memory signature;\n uint256 signatureType;\n uint256 nextOffset;\n uint256 i;\n for (i; i < _threshold; ) {\n (\n currentOwner,\n signature,\n signatureType,\n nextOffset\n ) = splitSignatures(_signatures, nextOffset);\n if (nextOffset == 0 && i + 1 < _threshold) return INVALID_SIG;\n if (signatureType == 1) {\n // If signatureType is 1 then it is default dataHash signed.\n // This also includes the contract signature\n if (\n !SignatureChecker.isValidSignatureNow(\n currentOwner,\n _dataHash,\n signature\n )\n ) return INVALID_SIG;\n } else if (signatureType == 2) {\n // If signatureType is 2 then it is an approved hash\n if (ms.approvedHashes[ms.counter][currentOwner][_dataHash] == 0)\n return INVALID_SIG;\n } else if (signatureType == 3) {\n // If signatureType is 3 then it is a signed message hash\n // This also includes the contract signature\n bytes32 msgHash = _dataHash.toEthSignedMessageHash();\n if (\n !SignatureChecker.isValidSignatureNow(\n currentOwner,\n msgHash,\n signature\n )\n ) return INVALID_SIG;\n } else revert MultiSigFacet__InvalidRoute();\n if (\n currentOwner <= lastOwner ||\n ms.owners[currentOwner] == address(0) ||\n currentOwner == SENTINEL_OWNERS\n ) return INVALID_SIG;\n lastOwner = currentOwner;\n\n unchecked {\n ++i;\n }\n }\n return VALID_SIG;\n }\n\n /**\n * @notice Split signatures into each individual signatures. Should comply with signature format to be split\n * @param _signatures Bytes value of signature\n * @param _nextOffset Uint256 value of next offset to start splitting the signature\n */\n function splitSignatures(\n bytes calldata _signatures,\n uint256 _nextOffset\n )\n public\n pure\n returns (\n address owner_,\n bytes memory signature,\n uint256 signatureType,\n uint256 nextOffset\n )\n {\n uint256 signaturesLength = _signatures.length;\n\n if (signaturesLength <= _nextOffset + ADDRESS + SIG_LEN)\n revert MultiSigFacet__InsufficientSignerLength();\n\n owner_ = address(\n bytes20(_signatures[_nextOffset:_nextOffset + ADDRESS])\n );\n\n signatureType = uint256(\n uint8(\n bytes1(\n _signatures[_nextOffset + ADDRESS:_nextOffset +\n ADDRESS +\n SIG_TYPE]\n )\n )\n );\n\n if (signatureType > 3 || signatureType == 0)\n revert MultiSigFacet__InvalidSignatureType();\n uint256 offSet = _nextOffset + ADDRESS + SIG_TYPE;\n uint256 siglen = uint256(\n uint32(bytes4(_signatures[offSet:offSet + SIG_LEN]))\n );\n if (offSet + siglen > signaturesLength)\n revert MultiSigFacet__InvalidSignatureLength();\n\n offSet += SIG_LEN;\n if (offSet + siglen == signaturesLength) nextOffset = 0;\n else nextOffset = offSet + siglen;\n\n signature = _signatures[offSet:offSet + siglen];\n }\n\n /**\n * @notice Approves the hash of userOperation on-chain. This can only be called by owners.\n * @param _hashToApprove Bytes value of UserOperation hash to approve\n */\n function approveHash(bytes32 _hashToApprove) external {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (ms.owners[msg.sender] == address(0))\n revert MultiSigFacet__OnlyOwner();\n\n ms.approvedHashes[ms.counter][msg.sender][_hashToApprove] = 1;\n emit HashApproved(_hashToApprove, msg.sender);\n }\n\n /**\n * @notice Add owner to Barz. Update thresold if threshold is given different from current threshold\n * @dev This can only be done via a Self call.\n * @param _newOwner Address of new owner to be added\n * @param _threshold Uint256 value of threshold\n */\n function addOwner(address _newOwner, uint256 _threshold) external {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (\n _newOwner == address(0) ||\n _newOwner == SENTINEL_OWNERS ||\n _newOwner == address(this)\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_newOwner] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n\n ms.owners[_newOwner] = ms.owners[SENTINEL_OWNERS];\n ms.owners[SENTINEL_OWNERS] = _newOwner;\n ++ms.ownerCount;\n emit OwnerAdded(_newOwner);\n\n if (ms.threshold != _threshold) changeThreshold(_threshold);\n }\n\n /**\n * @notice Remove owner from Barz. Update thresold if threshold is given different from current threshold\n * @dev This can only be done via a Self call.\n * @param _prevOwner Address of owner located right behind the removed owner address in the linked list\n * @param _removedOwner Address of owner to be removed\n * @param _threshold Uint256 value of threshold\n */\n function removeOwner(\n address _prevOwner,\n address _removedOwner,\n uint256 _threshold\n ) external {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (ms.ownerCount - 1 < _threshold)\n revert MultiSigFacet__InvalidThreshold();\n if (_removedOwner == address(0) || _removedOwner == SENTINEL_OWNERS)\n revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_prevOwner] != _removedOwner)\n revert MultiSigFacet__InvalidOwnerPair();\n\n ms.owners[_prevOwner] = ms.owners[_removedOwner];\n ms.owners[_removedOwner] = address(0);\n --ms.ownerCount;\n emit OwnerRemoved(_removedOwner);\n\n if (ms.threshold != _threshold) changeThreshold(_threshold);\n }\n\n /**\n * @notice Swap owner in Barz.\n * @dev This can only be done via a Self call.\n * @param _prevOwner Address of owner located right behind the removed owner address in the linked list\n * @param _oldOwner Address of owner to be removed\n * @param _newOwner Address of owner to be added\n */\n function swapOwner(\n address _prevOwner,\n address _oldOwner,\n address _newOwner\n ) public {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (\n _newOwner == address(0) ||\n _newOwner == SENTINEL_OWNERS ||\n _newOwner == address(this)\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_newOwner] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n if (_oldOwner == address(0) || _oldOwner == SENTINEL_OWNERS)\n revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_prevOwner] != _oldOwner)\n revert MultiSigFacet__InvalidOwnerPair();\n\n ms.owners[_newOwner] = ms.owners[_oldOwner];\n ms.owners[_prevOwner] = _newOwner;\n ms.owners[_oldOwner] = address(0);\n emit OwnerRemoved(_oldOwner);\n emit OwnerAdded(_newOwner);\n }\n\n /**\n * @notice Changes the threshold of the Barz to `_threshold`.\n * @dev This can only be done via a Self call.\n * @param _threshold New threshold\n */\n function changeThreshold(uint256 _threshold) public {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (_threshold > ms.ownerCount || _threshold == 0)\n revert MultiSigFacet__InvalidThreshold();\n\n ms.threshold = _threshold;\n emit ThresholdChanged(_threshold);\n }\n\n /**\n * @notice Checks if the given address is owner\n * @param _owner Address to be checked if it's owner\n * @return isOwner_ Bool value showing if it's owner address\n */\n function isOwner(address _owner) public view returns (bool isOwner_) {\n isOwner_ = (_owner != SENTINEL_OWNERS &&\n LibMultiSigStorage.multisigStorage().owners[_owner] != address(0));\n }\n\n /**\n * @notice Returns the threshold of Barz\n * @return threshold Threshold of the Barz account\n */\n function getThreshold() public view returns (uint256 threshold) {\n threshold = LibMultiSigStorage.multisigStorage().threshold;\n }\n\n /**\n * @notice Returns the list of owner addresses\n * @return owners List of owners\n */\n function getOwners() public view returns (address[] memory owners) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n owners = new address[](ms.ownerCount);\n\n uint256 index;\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n while (currentOwner != SENTINEL_OWNERS) {\n owners[index] = currentOwner;\n currentOwner = ms.owners[currentOwner];\n index++;\n }\n }\n\n /**\n * @notice Returns the previous owner in the linked list\n * @param _owner Address of owner\n * @return prevOwner Address of previous owner\n */\n function getPrevOwner(\n address _owner\n ) public view returns (address prevOwner) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n if (currentOwner == _owner) return SENTINEL_OWNERS;\n while (currentOwner != SENTINEL_OWNERS) {\n if (ms.owners[currentOwner] == _owner) return currentOwner;\n\n currentOwner = ms.owners[currentOwner];\n }\n return address(0);\n }\n\n /**\n * @notice Returns of the owner is approved by given owner address\n * @param _owner Address of owner\n * @param _hash Hash of UserOperation\n * @return isApproved Bool value showing if the hash is approved by owner\n */\n function isApprovedHash(\n address _owner,\n bytes32 _hash\n ) public view returns (bool isApproved) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n isApproved = (ms.approvedHashes[ms.counter][_owner][_hash] == 1);\n }\n}\n" + }, + "contracts/facets/verification/secp256k1/Secp256k1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {UserOperation} from \"../../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibAppStorage} from \"../../../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, Secp256k1VerificationStorage} from \"../../../libraries/LibFacetStorage.sol\";\nimport {LibLoupe} from \"../../../libraries/LibLoupe.sol\";\nimport {IERC1271} from \"../../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../../interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Secp256k1 verification facet\n * @dev Default Ethereum's elliptic curve\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract Secp256k1VerificationFacet is IVerificationFacet, IERC1271 {\n using ECDSA for bytes32;\n error Secp256k1VerificationFacet__InvalidSignerLength();\n address public immutable self;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in K1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\n * @param _publicKey Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _publicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n if (!isValidKeyType(_publicKey))\n revert Secp256k1VerificationFacet__InvalidSignerLength();\n\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(uint160(uint256(keccak256(_publicKey[1:]))));\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_publicKey);\n }\n\n /**\n * @notice Uninitialize signer in K1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\n * signer public key.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n validationData = validateSignature(\n userOp,\n userOpHash,\n k1Storage.signer\n );\n }\n\n /**\n * @notice Validates if the signature of UserOperation is signed by the given signer\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @param signer Address of signer who signed the contract, to be validated\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n address signer\n ) public pure returns (uint256 isValid) {\n bytes32 hash = userOpHash.toEthSignedMessageHash();\n isValid = (signer != hash.recover(userOp.signature)) ? 1 : 0;\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n ownerSignatureValidatorSelector = this.validateOwnerSignature.selector;\n // NOTE: The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory signer) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n signer = abi.encodePacked(k1Storage.signer);\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key length should be 65 in an uncompressed public key format\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (_hash.recover(_signature) ==\n LibFacetStorage.k1Storage().signer)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/Secp256r1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {UserOperation} from \"../../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibAppStorage} from \"../../../libraries/LibAppStorage.sol\";\nimport {LibLoupe} from \"../../../libraries/LibLoupe.sol\";\nimport {LibFacetStorage, Secp256r1VerificationStorage} from \"../../../libraries/LibFacetStorage.sol\";\nimport {Base64} from \"./utils/Base64.sol\";\nimport {LibSecp256r1} from \"./utils/LibSecp256r1.sol\";\nimport {IERC1271} from \"../../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../../interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Secp256r1 verification facet\n * @dev Primarily used to verify user ops signed with passkeys\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract Secp256r1VerificationFacet is IVerificationFacet, IERC1271 {\n error Secp256r1VerificationFacet__InvalidSignerLength();\n address public immutable self;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in R1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\n * @param _publicKey Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _publicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n\n if (!isValidKeyType(_publicKey))\n revert Secp256r1VerificationFacet__InvalidSignerLength();\n\n bytes memory publicKeyCoordinates = _publicKey[1:];\n uint256[2] memory q;\n assembly {\n // Copy the bytes from the input data into the uint256 array\n mstore(q, mload(add(publicKeyCoordinates, 32)))\n mstore(add(q, 32), mload(add(publicKeyCoordinates, 64)))\n }\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n r1Storage.q = q;\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_publicKey);\n }\n\n /**\n * @notice Uninitialize signer in R1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n r1Storage.q = [0, 0];\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\n * signer public key.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n validationData = validateSignature(userOp, userOpHash, r1Storage.q);\n }\n\n /**\n * @notice Validates if the signature of UserOperation is signed by the given signer\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @param q Public Key of signer who signed the contract, to be validated\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256[2] memory q\n ) public view returns (uint256 isValid) {\n isValid = (_validateSignature(q, userOpHash, userOp.signature)) ? 0 : 1;\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n return this.validateOwnerSignature.selector; // validateOwnerSignature(UserOperation calldata userOp,bytes32 userOpHash)\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory signer) {\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n signer = abi.encodePacked(r1Storage.q);\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key should in an uncompressed public key format\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = _validateSignature(\n LibFacetStorage.r1Storage().q,\n _hash,\n _signature\n )\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n\n function _validateSignature(\n uint256[2] memory q,\n bytes32 _hash,\n bytes memory _signature\n ) internal view returns (bool) {\n (\n uint256 rValue,\n uint256 sValue,\n bytes memory authenticatorData,\n string memory clientDataJSONPre,\n string memory clientDataJSONPost\n ) = abi.decode(_signature, (uint256, uint256, bytes, string, string));\n bytes32 clientHash;\n {\n string memory opHashBase64 = Base64.encode(bytes.concat(_hash));\n string memory clientDataJSON = string.concat(\n clientDataJSONPre,\n opHashBase64,\n clientDataJSONPost\n );\n clientHash = sha256(bytes(clientDataJSON));\n }\n bytes32 sigHash = sha256(bytes.concat(authenticatorData, clientHash));\n return LibSecp256r1.Verify(q, rValue, sValue, uint256(sigHash));\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/utils/Base64.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @dev Provides a set of functions to operate with Base64 strings.\n * modified for base64url https://datatracker.ietf.org/doc/html/rfc4648#section-5\n * _Available since v4.5._\n */\nlibrary Base64 {\n /**\n * @dev Base64 Encoding/Decoding Table\n */\n string internal constant _TABLE =\n \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_\";\n\n /**\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\n */\n function encode(bytes memory data) internal pure returns (string memory) {\n /**\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\n */\n if (data.length == 0) return \"\";\n\n // Loads the table into memory\n string memory table = _TABLE;\n\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\n // and split into 4 numbers of 6 bits.\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\n // - `data.length + 2` -> Round up\n // - `/ 3` -> Number of 3-bytes chunks\n // - `4 *` -> 4 characters for each chunk\n uint256 newlength = (data.length * 8) / 6;\n if (data.length % 6 > 0) {\n newlength++;\n }\n string memory result = new string(newlength);\n\n /// @solidity memory-safe-assembly\n assembly {\n // Prepare the lookup table (skip the first \"length\" byte)\n let tablePtr := add(table, 1)\n\n // Prepare result pointer, jump over length\n let resultPtr := add(result, 32)\n\n // Run over the input, 3 bytes at a time\n for {\n let dataPtr := data\n let endPtr := add(data, mload(data))\n } lt(dataPtr, endPtr) {\n\n } {\n // Advance 3 bytes\n dataPtr := add(dataPtr, 3)\n let input := mload(dataPtr)\n\n // To write each character, shift the 3 bytes (18 bits) chunk\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\n // and apply logical AND with 0x3F which is the number of\n // the previous character in the ASCII table prior to the Base64 Table\n // The result is then added to the table to get the character to write,\n // and finally write it in the result pointer but with a left shift\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(18, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(12, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(6, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n }\n }\n\n return result;\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/utils/LibSecp256r1.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n// Heavily inspired from\n// https://github.com/maxrobot/elliptic-solidity/blob/master/contracts/Secp256r1.sol\n// https://github.com/tdrerup/elliptic-curve-solidity/blob/master/contracts/curves/EllipticCurve.sol\n// modified to use precompile 0x05 modexp\n// and modified jacobian double\n// optimisations to avoid to an from from affine and jacobian coordinates\n\n// Additional Elliptic curve Public key / Signature validation added by\n// David Yonjun Kim (@Powerstream3604)\n\nstruct JPoint {\n uint256 x;\n uint256 y;\n uint256 z;\n}\n\nlibrary LibSecp256r1 {\n uint256 constant gx =\n 0x6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296;\n uint256 constant gy =\n 0x4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5;\n uint256 public constant pp =\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF;\n\n uint256 public constant nn =\n 0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551;\n uint256 constant a =\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC;\n uint256 constant b =\n 0x5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B;\n uint256 constant MOST_SIGNIFICANT =\n 0xc000000000000000000000000000000000000000000000000000000000000000;\n\n /*\n * Verify\n * @description - verifies that a public key has signed a given message\n * @param Q - public key coordinates X & Y\n * @param R - signature half R\n * @param S - signature half S\n * @param input - hashed message\n */\n function Verify(\n uint256[2] memory q,\n uint r,\n uint s,\n uint e\n ) internal view returns (bool) {\n if (q[0] > pp - 1 || q[1] > pp - 1) {\n return false;\n }\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\n return false;\n }\n if (\n mulmod(q[1], q[1], pp) !=\n addmod(\n addmod(\n mulmod(q[0], mulmod(q[0], q[0], pp), pp),\n mulmod(a, q[0], pp),\n pp\n ),\n b,\n pp\n )\n ) {\n return false;\n }\n\n JPoint[16] memory points = _preComputeJacobianPoints(q);\n return VerifyWithPrecompute(points, r, s, e);\n }\n\n function VerifyWithPrecompute(\n JPoint[16] memory points,\n uint r,\n uint s,\n uint e\n ) internal view returns (bool) {\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\n return false;\n }\n\n uint w = _primemod(s, nn);\n\n uint u1 = mulmod(e, w, nn);\n uint u2 = mulmod(r, w, nn);\n\n uint x;\n uint y;\n\n (x, y) = ShamirMultJacobian(points, u1, u2);\n return (x == r);\n }\n\n /*\n * Strauss Shamir trick for EC multiplication\n * https://stackoverflow.com/questions/50993471/ec-scalar-multiplication-with-strauss-shamir-method\n * we optimise on this a bit to do with 2 bits at a time rather than a single bit\n * the individual points for a single pass are precomputed\n * overall this reduces the number of additions while keeping the same number of doublings\n */\n function ShamirMultJacobian(\n JPoint[16] memory points,\n uint u1,\n uint u2\n ) internal view returns (uint, uint) {\n uint x = 0;\n uint y = 0;\n uint z = 0;\n uint bits = 128;\n uint index = 0;\n\n while (bits > 0) {\n if (z > 0) {\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\n }\n index =\n ((u1 & MOST_SIGNIFICANT) >> 252) |\n ((u2 & MOST_SIGNIFICANT) >> 254);\n if (index > 0) {\n (x, y, z) = _jAdd(\n x,\n y,\n z,\n points[index].x,\n points[index].y,\n points[index].z\n );\n }\n u1 <<= 2;\n u2 <<= 2;\n bits--;\n }\n (x, y) = _affineFromJacobian(x, y, z);\n return (x, y);\n }\n\n function _preComputeJacobianPoints(\n uint256[2] memory q\n ) internal pure returns (JPoint[16] memory points) {\n points[0] = JPoint(0, 0, 0);\n points[1] = JPoint(q[0], q[1], 1); // u2\n points[2] = _jPointDouble(points[1]);\n points[3] = _jPointAdd(points[1], points[2]);\n\n points[4] = JPoint(gx, gy, 1); // u1Points[1]\n points[5] = _jPointAdd(points[4], points[1]);\n points[6] = _jPointAdd(points[4], points[2]);\n points[7] = _jPointAdd(points[4], points[3]);\n\n points[8] = _jPointDouble(points[4]); // u1Points[2]\n points[9] = _jPointAdd(points[8], points[1]);\n points[10] = _jPointAdd(points[8], points[2]);\n points[11] = _jPointAdd(points[8], points[3]);\n\n points[12] = _jPointAdd(points[4], points[8]); // u1Points[3]\n points[13] = _jPointAdd(points[12], points[1]);\n points[14] = _jPointAdd(points[12], points[2]);\n points[15] = _jPointAdd(points[12], points[3]);\n }\n\n function _jPointAdd(\n JPoint memory p1,\n JPoint memory p2\n ) internal pure returns (JPoint memory) {\n uint x;\n uint y;\n uint z;\n (x, y, z) = _jAdd(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z);\n return JPoint(x, y, z);\n }\n\n function _jPointDouble(\n JPoint memory p\n ) internal pure returns (JPoint memory) {\n uint x;\n uint y;\n uint z;\n (x, y, z) = _modifiedJacobianDouble(p.x, p.y, p.z);\n return JPoint(x, y, z);\n }\n\n /* _affineFromJacobian\n * @desription returns affine coordinates from a jacobian input follows\n * golang elliptic/crypto library\n */\n function _affineFromJacobian(\n uint x,\n uint y,\n uint z\n ) internal view returns (uint ax, uint ay) {\n if (z == 0) {\n return (0, 0);\n }\n\n uint zinv = _primemod(z, pp);\n uint zinvsq = mulmod(zinv, zinv, pp);\n\n ax = mulmod(x, zinvsq, pp);\n ay = mulmod(y, mulmod(zinvsq, zinv, pp), pp);\n }\n\n /*\n * _jAdd\n * @description performs Jacobian addition as defined below:\n * http://www.hyperelliptic.org/EFD/g1p/data/shortw/jacobian/addition/add-2007-bl\n */\n function _jAdd(\n uint p1,\n uint p2,\n uint p3,\n uint q1,\n uint q2,\n uint q3\n ) internal pure returns (uint r1, uint r2, uint r3) {\n if (p3 == 0) {\n r1 = q1;\n r2 = q2;\n r3 = q3;\n\n return (r1, r2, r3);\n } else if (q3 == 0) {\n r1 = p1;\n r2 = p2;\n r3 = p3;\n\n return (r1, r2, r3);\n }\n\n assembly {\n let\n pd\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\n let z1z1 := mulmod(p3, p3, pd) // Z1Z1 = Z1^2\n let z2z2 := mulmod(q3, q3, pd) // Z2Z2 = Z2^2\n\n let u1 := mulmod(p1, z2z2, pd) // U1 = X1*Z2Z2\n let u2 := mulmod(q1, z1z1, pd) // U2 = X2*Z1Z1\n\n let s1 := mulmod(p2, mulmod(z2z2, q3, pd), pd) // S1 = Y1*Z2*Z2Z2\n let s2 := mulmod(q2, mulmod(z1z1, p3, pd), pd) // S2 = Y2*Z1*Z1Z1\n\n let p3q3 := addmod(p3, q3, pd)\n\n if lt(u2, u1) {\n u2 := add(pd, u2) // u2 = u2+pd\n }\n let h := sub(u2, u1) // H = U2-U1\n\n let i := mulmod(0x02, h, pd)\n i := mulmod(i, i, pd) // I = (2*H)^2\n\n let j := mulmod(h, i, pd) // J = H*I\n if lt(s2, s1) {\n s2 := add(pd, s2) // u2 = u2+pd\n }\n let rr := mulmod(0x02, sub(s2, s1), pd) // r = 2*(S2-S1)\n r1 := mulmod(rr, rr, pd) // X3 = R^2\n\n let v := mulmod(u1, i, pd) // V = U1*I\n let j2v := addmod(j, mulmod(0x02, v, pd), pd)\n if lt(r1, j2v) {\n r1 := add(pd, r1) // X3 = X3+pd\n }\n r1 := sub(r1, j2v)\n\n // Y3 = r*(V-X3)-2*S1*J\n let s12j := mulmod(mulmod(0x02, s1, pd), j, pd)\n\n if lt(v, r1) {\n v := add(pd, v)\n }\n r2 := mulmod(rr, sub(v, r1), pd)\n\n if lt(r2, s12j) {\n r2 := add(pd, r2)\n }\n r2 := sub(r2, s12j)\n\n // Z3 = ((Z1+Z2)^2-Z1Z1-Z2Z2)*H\n z1z1 := addmod(z1z1, z2z2, pd)\n j2v := mulmod(p3q3, p3q3, pd)\n if lt(j2v, z1z1) {\n j2v := add(pd, j2v)\n }\n r3 := mulmod(sub(j2v, z1z1), h, pd)\n }\n return (r1, r2, r3);\n }\n\n // Point doubling on the modified jacobian coordinates\n // http://point-at-infinity.org/ecc/Prime_Curve_Modified_Jacobian_Coordinates.html\n function _modifiedJacobianDouble(\n uint x,\n uint y,\n uint z\n ) internal pure returns (uint x3, uint y3, uint z3) {\n if (y == 0) return (0, 0, 0);\n assembly {\n let\n pd\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\n let z2 := mulmod(z, z, pd)\n let az4 := mulmod(\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC,\n mulmod(z2, z2, pd),\n pd\n )\n let y2 := mulmod(y, y, pd)\n let s := mulmod(0x04, mulmod(x, y2, pd), pd)\n let u := mulmod(0x08, mulmod(y2, y2, pd), pd)\n let m := addmod(mulmod(0x03, mulmod(x, x, pd), pd), az4, pd)\n let twos := mulmod(0x02, s, pd)\n let m2 := mulmod(m, m, pd)\n if lt(m2, twos) {\n m2 := add(pd, m2)\n }\n x3 := sub(m2, twos)\n if lt(s, x3) {\n s := add(pd, s)\n }\n y3 := mulmod(m, sub(s, x3), pd)\n if lt(y3, u) {\n y3 := add(pd, y3)\n }\n y3 := sub(y3, u)\n z3 := mulmod(0x02, mulmod(y, z, pd), pd)\n }\n }\n\n // Fermats little theorem https://en.wikipedia.org/wiki/Fermat%27s_little_theorem\n // a^(p-1) = 1 mod p\n // a^(-1) ≅ a^(p-2) (mod p)\n // we then use the precompile bigModExp to compute a^(-1)\n function _primemod(uint value, uint p) internal view returns (uint ret) {\n ret = modexp(value, p - 2, p);\n return ret;\n }\n\n // Wrapper for built-in BigNumber_modexp (contract 0x5) as described here. https://github.com/ethereum/EIPs/pull/198\n function modexp(\n uint _base,\n uint _exp,\n uint _mod\n ) internal view returns (uint ret) {\n // bigModExp(_base, _exp, _mod);\n assembly {\n if gt(_base, _mod) {\n _base := mod(_base, _mod)\n }\n // Free memory pointer is always stored at 0x40\n let freemem := mload(0x40)\n\n mstore(freemem, 0x20)\n mstore(add(freemem, 0x20), 0x20)\n mstore(add(freemem, 0x40), 0x20)\n\n mstore(add(freemem, 0x60), _base)\n mstore(add(freemem, 0x80), _exp)\n mstore(add(freemem, 0xa0), _mod)\n\n let success := staticcall(14000, 0x5, freemem, 0xc0, freemem, 0x20)\n switch success\n case 0 {\n revert(0x0, 0x0)\n }\n default {\n ret := mload(freemem)\n }\n }\n }\n}\n" + }, + "contracts/infrastructure/DefaultFallbackHandler.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC1155Receiver} from \"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\";\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {BaseAccount} from \"../aa-4337/core/BaseAccount.sol\";\nimport {DefaultLibDiamond} from \"../libraries/DefaultLibDiamond.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IAccountFacet} from \"../facets/interfaces/IAccountFacet.sol\";\nimport {IStorageLoupe} from \"../facets/base/interfaces/IStorageLoupe.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IERC677Receiver} from \"../interfaces/ERC/IERC677Receiver.sol\";\nimport {IERC165} from \"../interfaces/ERC/IERC165.sol\";\n\n/**\n * @title DefaultFallbackHandler\n * @dev A default fallback handler for Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DefaultFallbackHandler is IDiamondLoupe {\n /**\n * @notice Sets the middleware diamond for Barz wallet as a fallback handler\n * @dev This contract is also a diamond that holds the default facets to reduce gas cost for wallet activation.\n * Within the constructor this conducts diamond cut to initially setup the diamond. This is a non-upgradeable contract\n * @param _diamondCutFacet Address if diamond cut facet\n * @param _accountFacet Address account facet\n * @param _tokenReceiverFacet Address of token receiver facet\n * @param _diamondLoupeFacet Address of diamond loupe facet\n */\n constructor(\n address _diamondCutFacet,\n address _accountFacet,\n address _tokenReceiverFacet,\n address _diamondLoupeFacet\n ) payable {\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](4);\n bytes4[] memory functionSelectors = new bytes4[](1);\n functionSelectors[0] = IDiamondCut.diamondCut.selector;\n\n bytes4[] memory accountFunctionSelectors = new bytes4[](5);\n accountFunctionSelectors[0] = IAccountFacet.execute.selector;\n accountFunctionSelectors[1] = IAccountFacet.executeBatch.selector;\n accountFunctionSelectors[2] = BaseAccount.validateUserOp.selector;\n accountFunctionSelectors[3] = BaseAccount.getNonce.selector;\n accountFunctionSelectors[4] = BaseAccount.entryPoint.selector;\n\n bytes4[] memory receiverFacetSelectors = new bytes4[](5);\n receiverFacetSelectors[0] = IERC721Receiver.onERC721Received.selector;\n receiverFacetSelectors[1] = IERC1155Receiver.onERC1155Received.selector;\n receiverFacetSelectors[2] = IERC1155Receiver\n .onERC1155BatchReceived\n .selector;\n receiverFacetSelectors[3] = IERC777Recipient.tokensReceived.selector;\n receiverFacetSelectors[4] = IERC677Receiver.onTokenTransfer.selector;\n\n bytes4[] memory loupeFacetSelectors = new bytes4[](9);\n loupeFacetSelectors[0] = IDiamondLoupe.facets.selector;\n loupeFacetSelectors[1] = IDiamondLoupe.facetFunctionSelectors.selector;\n loupeFacetSelectors[2] = IDiamondLoupe.facetAddresses.selector;\n loupeFacetSelectors[3] = IDiamondLoupe.facetAddress.selector;\n loupeFacetSelectors[4] = IERC165.supportsInterface.selector;\n loupeFacetSelectors[5] = IStorageLoupe.facetsFromStorage.selector;\n loupeFacetSelectors[6] = IStorageLoupe\n .facetFunctionSelectorsFromStorage\n .selector;\n loupeFacetSelectors[7] = IStorageLoupe\n .facetAddressesFromStorage\n .selector;\n loupeFacetSelectors[8] = IStorageLoupe.facetAddressFromStorage.selector;\n\n {\n cut[0] = IDiamondCut.FacetCut({\n facetAddress: _diamondCutFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: functionSelectors\n });\n cut[1] = IDiamondCut.FacetCut({\n facetAddress: _accountFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: accountFunctionSelectors\n });\n cut[2] = IDiamondCut.FacetCut({\n facetAddress: _tokenReceiverFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: receiverFacetSelectors\n });\n cut[3] = IDiamondCut.FacetCut({\n facetAddress: _diamondLoupeFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: loupeFacetSelectors\n });\n\n DefaultLibDiamond.diamondCut(cut, address(0), \"\");\n }\n }\n\n /**\n * @notice Returns the facet information of call facets registered to this diamond.\n * @return facets_ The facet struct array including all facet information\n */\n function facets() external view override returns (Facet[] memory facets_) {\n DefaultLibDiamond.DiamondStorage storage ds = DefaultLibDiamond\n .diamondStorage();\n uint256 numFacets = ds.facetAddresses.length;\n facets_ = new Facet[](numFacets);\n for (uint256 i; i < numFacets; ) {\n address facetAddress_ = ds.facetAddresses[i];\n facets_[i].facetAddress = facetAddress_;\n facets_[i].functionSelectors = ds\n .facetFunctionSelectors[facetAddress_]\n .functionSelectors;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Gets all the function selectors provided by a facet.\n * @param _facet The facet address.\n * @return facetFunctionSelectors_\n */\n function facetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n facetFunctionSelectors_ = DefaultLibDiamond\n .diamondStorage()\n .facetFunctionSelectors[_facet]\n .functionSelectors;\n }\n\n /**\n * @notice Get all the facet addresses used by a diamond.\n * @return facetAddresses_\n */\n function facetAddresses()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n facetAddresses_ = DefaultLibDiamond.diamondStorage().facetAddresses;\n }\n\n /** @notice Gets the facet that supports the given selector.\n * @dev If facet is not found return address(0).\n * @param _functionSelector The function selector.\n * @return facetAddress_ The facet address.\n */\n function facetAddress(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n facetAddress_ = DefaultLibDiamond\n .diamondStorage()\n .selectorToFacetAndPosition[_functionSelector]\n .facetAddress;\n }\n}\n" + }, + "contracts/infrastructure/FacetRegistry.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport {IFacetRegistry} from \"./interfaces/IFacetRegistry.sol\";\n\n/**\n * @title Facet Registry\n * @dev Contract to keep track of facets & function selectors addable to user wallets\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract FacetRegistry is IFacetRegistry, Ownable2Step {\n mapping(address => FacetRegistryConfig) private facets;\n\n /**\n * @notice Transfers the ownership of the contract to the given owner\n * @param _owner Address of owner who has access to initialize the default security variables for security manager\n */\n constructor(address _owner) {\n transferOwnership(_owner);\n _transferOwnership(_owner);\n }\n\n /**\n * @dev Registers a facet and it's function selectors to registry\n * @param _facet address of facet\n * @param _facetSelectors list of function selectors of the facet\n */\n function registerFacetFunctionSelectors(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external override onlyOwner {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n for (uint256 i; i < _facetSelectors.length; ) {\n if (facetConfig.info[_facetSelectors[i]].exists)\n revert FacetRegistry__FacetSelectorAlreadyRegistered();\n\n facetConfig.info[_facetSelectors[i]].exists = true;\n facetConfig.info[_facetSelectors[i]].index = uint128(\n facetConfig.selectors.length\n );\n facetConfig.selectors.push(_facetSelectors[i]);\n unchecked {\n ++i;\n }\n }\n emit FacetFunctionSelectorsRegistered(_facet, _facetSelectors);\n }\n\n /**\n * @dev Removes a registered facet and it's corresponding selectors from registry\n * @param _facet address of facet\n * @param _facetSelectors list of function selectors of the facet\n */\n function removeFacetFunctionSelectors(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external override onlyOwner {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n for (uint256 i; i < _facetSelectors.length; ) {\n if (!facetConfig.info[_facetSelectors[i]].exists)\n revert FacetRegistry__UnregisteredFacetSelector();\n\n bytes4 lastSelector = facetConfig.selectors[\n facetConfig.selectors.length - 1\n ];\n if (_facetSelectors[i] != lastSelector) {\n uint128 targetIndex = facetConfig\n .info[_facetSelectors[i]]\n .index;\n facetConfig.selectors[targetIndex] = lastSelector;\n facetConfig.info[lastSelector].index = targetIndex;\n }\n facetConfig.selectors.pop();\n delete facetConfig.info[_facetSelectors[i]];\n\n unchecked {\n ++i;\n }\n }\n emit FacetFunctionSelectorsRemoved(_facet, _facetSelectors);\n }\n\n /**\n * @dev Checks if a facet and it's selectors given is registered to facet registry\n * @param _facet Address of facet\n * @param _facetSelectors List of function selectors of the facet\n */\n function areFacetFunctionSelectorsRegistered(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external view override returns (bool) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n if (_facetSelectors.length == 0) return false;\n for (uint256 i; i < _facetSelectors.length; ) {\n if (!facetConfig.info[_facetSelectors[i]].exists) return false;\n unchecked {\n ++i;\n }\n }\n return true;\n }\n\n /**\n * @dev Checks if a facet and it's selector given is registered to facet registry\n * @param _facet Address of facet\n * @param _facetSelector List of function selectors of the facet\n * @return isRegistered Bool value showing if the selector is registered\n */\n function isFacetFunctionSelectorRegistered(\n address _facet,\n bytes4 _facetSelector\n ) external view override returns (bool isRegistered) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n isRegistered = facetConfig.info[_facetSelector].exists;\n }\n\n /**\n * @dev Get the registered selectors of facet from registry\n * @param _facet Address of facet\n * @return selectors Selectors registered to facet\n */\n function getFacetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory selectors) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n selectors = facetConfig.selectors;\n }\n}\n" + }, + "contracts/infrastructure/interfaces/IFacetRegistry.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Registry Interface\n * @dev Interface for Facet Registry contract to keep track of facets & function selectors addable to user wallets\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IFacetRegistry {\n struct FacetRegistryConfig {\n bytes4[] selectors;\n mapping(bytes4 => FacetInfo) info;\n }\n struct FacetInfo {\n bool exists;\n uint128 index;\n }\n\n event FacetFunctionSelectorsRegistered(\n address facet,\n bytes4[] facetSelectors\n );\n event FacetFunctionSelectorsRemoved(address facet, bytes4[] facetSelectors);\n\n error FacetRegistry__FacetSelectorAlreadyRegistered();\n error FacetRegistry__UnregisteredFacetSelector();\n\n function registerFacetFunctionSelectors(\n address facet,\n bytes4[] calldata facetSelectors\n ) external;\n\n function removeFacetFunctionSelectors(\n address facet,\n bytes4[] calldata facetSelectors\n ) external;\n\n function areFacetFunctionSelectorsRegistered(\n address facet,\n bytes4[] calldata facetSelectors\n ) external view returns (bool);\n\n function isFacetFunctionSelectorRegistered(\n address facet,\n bytes4 facetSelector\n ) external view returns (bool);\n\n function getFacetFunctionSelectors(\n address facet\n ) external view returns (bytes4[] memory);\n}\n" + }, + "contracts/infrastructure/interfaces/ISecurityManager.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Registry Interface\n * @dev Infrastructure contract to manage security parameters of users\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface ISecurityManager {\n error SecurityManager__OutOfBoundary();\n error SecurityManager__CallerNotWallet();\n error SecurityManager__AlreadyIntialized();\n\n function initializeAdditionSecurityPeriod(\n uint128 defaultAdditionSecurityPeriod,\n uint128 minAdditionSecurityPeriod,\n uint128 maxAdditionSecurityPeriod\n ) external;\n\n function initializeRemovalSecurityPeriod(\n uint128 defaultRemovalSecurityPeriod,\n uint128 minRemovalSecurityPeriod,\n uint128 maxRemovalSecurityPeriod\n ) external;\n\n function initializeApprovalValidationPeriod(\n uint128 defaultApprovalValidationPeriod,\n uint128 minApprovalValidationPeriod,\n uint128 maxApprovalValidationPeriod\n ) external;\n\n function initializeMigrationPeriod(\n uint128 defaultMigrationPeriod,\n uint128 minMigrationPeriod,\n uint128 maxMigrationPeriod\n ) external;\n\n function initializeLockPeriod(\n uint128 defaultLockPeriod,\n uint128 minLockPeriod,\n uint128 maxLockPeriod\n ) external;\n\n function initializeRecoveryPeriod(\n uint128 defaultRecoveryPeriod,\n uint128 minRecoveryPeriod,\n uint128 maxRecoveryPeriod\n ) external;\n\n function initializeSecurityWindow(\n uint128 defaultSecurityWindow,\n uint128 minSecurityWindow,\n uint128 maxSecurityWindow\n ) external;\n\n function setAdditionSecurityPeriod(\n address wallet,\n uint128 additionSecurityPeriod\n ) external;\n\n function setRemovalSecurityPeriod(\n address wallet,\n uint128 removalSecurityPeriod\n ) external;\n\n function setSecurityWindow(address wallet, uint128 securityWindow) external;\n\n function setRecoveryPeriod(address wallet, uint128 recoveryPeriod) external;\n\n function setLockPeriod(address wallet, uint128 lockPeriod) external;\n\n function setApprovalValidationPeriod(\n address wallet,\n uint128 approvalValidationPeriod\n ) external;\n\n function setMigrationPeriod(\n address wallet,\n uint128 migrationPeriod\n ) external;\n\n function additionSecurityPeriodOf(\n address wallet\n ) external view returns (uint128);\n\n function removalSecurityPeriodOf(\n address wallet\n ) external view returns (uint128);\n\n function securityWindowOf(address wallet) external view returns (uint128);\n\n function recoveryPeriodOf(address wallet) external view returns (uint128);\n\n function lockPeriodOf(address wallet) external view returns (uint128);\n\n function migrationPeriodOf(address wallet) external view returns (uint128);\n\n function approvalValidationPeriodOf(\n address wallet\n ) external view returns (uint128);\n}\n" + }, + "contracts/infrastructure/RemoteStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IGuardianFacet} from \"../facets/interfaces/IGuardianFacet.sol\";\n\n/**\n * @title Remote Storage\n * @dev Remote storage allows you to associate addresses with an array of addresses on a standalone smart contract.\n * This could be useful when you don't want to use the local diamond storage for some purpose.\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\nabstract contract RemoteStorage {\n struct StorageConfig {\n address[] addresses;\n mapping(address => Info) info;\n }\n\n struct Info {\n bool exists;\n uint128 index;\n }\n\n mapping(address => StorageConfig) internal configs;\n\n event Added(address _address);\n event Removed(address _address);\n\n error RemoteStorage__CallerNotOwner();\n error RemoteStorage__CallerNotGuardianOrOwner();\n error RemoteStorage__AlreadyExists();\n error RemoteStorage__NotFound();\n error RemoteStorage__CallerNotGuardian();\n\n bytes4 constant IS_GUARDIAN_SELECTOR =\n bytes4(keccak256(\"isGuardian(address)\"));\n bytes4 constant GUARDIAN_COUNT = bytes4(keccak256(\"guardianCount()\"));\n\n /**\n * @notice Modifier to only allow the self to call. Reverts otherwise\n */\n modifier onlyWallet(address _wallet) {\n if (msg.sender != _wallet) revert RemoteStorage__CallerNotOwner();\n _;\n }\n\n /**\n * @notice Enfore the callet to be wallet of guardian of the wallet\n * @param _wallet Address of wallet\n */\n function enforceGuardianOrWallet(address _wallet) internal view {\n if (msg.sender == _wallet) return;\n address facetAddress = IDiamondLoupe(_wallet).facetAddress(\n IS_GUARDIAN_SELECTOR\n );\n if (facetAddress != address(0))\n if (IGuardianFacet(_wallet).isGuardian(msg.sender)) return;\n revert RemoteStorage__CallerNotGuardianOrOwner();\n }\n\n /**\n * @notice Enforce the caller to be wallet IF guardians doesn't exists and only guardian when guardians exists\n * @param _wallet Target wallet address to be handled by infrastructure contracts\n */\n function enforceWalletOrGuardianIfExists(address _wallet) internal view {\n address facetAddress;\n if (msg.sender == _wallet) {\n facetAddress = IDiamondLoupe(_wallet).facetAddress(GUARDIAN_COUNT);\n if (facetAddress == address(0)) return;\n uint256 guardianCount = IGuardianFacet(_wallet).guardianCount();\n if (guardianCount != 0) revert RemoteStorage__CallerNotGuardian();\n return;\n }\n facetAddress = IDiamondLoupe(_wallet).facetAddress(\n IS_GUARDIAN_SELECTOR\n );\n if (facetAddress != address(0))\n if (IGuardianFacet(_wallet).isGuardian(msg.sender)) return;\n\n revert RemoteStorage__CallerNotGuardianOrOwner();\n }\n\n /**\n * @notice Add address to storage and reverts if the address already exists.\n * This is an internal function callable from contracts that inherit this abstract contract\n * @param _wallet Address of wallet to add the address\n * @param _address Address to be added to wallet\n */\n function addAddress(address _wallet, address _address) internal {\n StorageConfig storage config = configs[_wallet];\n if (config.info[_address].exists) revert RemoteStorage__AlreadyExists();\n\n config.info[_address].exists = true;\n config.info[_address].index = uint128(config.addresses.length);\n config.addresses.push(_address);\n\n emit Added(_address);\n }\n\n /**\n * @notice Remove address from storage and reverts if the address already exists.\n * This is an internal function callable from contracts that inherit this abstract contract\n * @param _wallet Address of wallet to remove the address\n * @param _address Address to be removed from wallet\n */\n function removeAddress(address _wallet, address _address) internal {\n StorageConfig storage config = configs[_wallet];\n if (!config.info[_address].exists) revert RemoteStorage__NotFound();\n\n address lastAddress = config.addresses[config.addresses.length - 1];\n if (_address != lastAddress) {\n uint128 targetIndex = config.info[_address].index;\n config.addresses[targetIndex] = lastAddress;\n config.info[lastAddress].index = targetIndex;\n }\n config.addresses.pop();\n delete config.info[_address];\n\n emit Removed(_address);\n }\n\n /**\n * @notice Returns the address added to the given wallet\n * @param _wallet Address of wallet to fetch the addresses added to it\n * @return addresses List of addresses added to the wallet\n */\n function getAddresses(\n address _wallet\n ) internal view returns (address[] memory addresses) {\n StorageConfig storage config = configs[_wallet];\n addresses = new address[](config.addresses.length);\n uint addressesLen = config.addresses.length;\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns bool value checking if the address exists in the given wallet address\n * @param _wallet Wallet address to check\n * @param _address Address to fetch if the address if added to given wallet\n * @return exists_ Bool value showing if the address exists in wallet\n */\n function exists(\n address _wallet,\n address _address\n ) internal view returns (bool exists_) {\n exists_ = configs[_wallet].info[_address].exists;\n }\n\n /**\n * @notice Returns the number of addresses added to the wallet\n * @param _wallet Address of wallet to check\n * @return count_ Number of addresses added to wallet\n */\n function count(address _wallet) internal view returns (uint256 count_) {\n count_ = configs[_wallet].addresses.length;\n }\n}\n" + }, + "contracts/infrastructure/SecurityManager.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport {ISecurityManager} from \"./interfaces/ISecurityManager.sol\";\n\n/**\n * @title Security Manager\n * @dev Infrastructure contract to manage security parameters of users\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract SecurityManager is ISecurityManager, Ownable2Step {\n uint128 public minAdditionSecurityPeriod;\n uint128 public maxAdditionSecurityPeriod;\n uint128 private defaultAdditionSecurityPeriod;\n\n uint128 public minRemovalSecurityPeriod;\n uint128 public maxRemovalSecurityPeriod;\n uint128 private defaultRemovalSecurityPeriod;\n\n uint128 public minSecurityWindow;\n uint128 public maxSecurityWindow;\n uint128 private defaultSecurityWindow;\n\n uint128 public minRecoveryPeriod;\n uint128 public maxRecoveryPeriod;\n uint128 private defaultRecoveryPeriod;\n\n uint128 public minLockPeriod;\n uint128 public maxLockPeriod;\n uint128 private defaultLockPeriod;\n\n uint128 public minApprovalValidationPeriod;\n uint128 public maxApprovalValidationPeriod;\n uint128 private defaultApprovalValidationPeriod;\n\n uint128 public minMigrationPeriod;\n uint128 public maxMigrationPeriod;\n uint128 private defaultMigrationPeriod;\n\n bool public _isAdditionSecurityPeriodInitialized;\n bool public _isRemovalSecurityPeriodInitialized;\n bool public _isSecurityWindowInitialized;\n bool public _isRecoveryPeriodInitialized;\n bool public _isLockPeriodInitialized;\n bool public _isApprovalValidationPeriodInitialized;\n bool public _isMigrationPeriodInitialized;\n\n mapping(address => CustomSecurityConfig) securityConfigs;\n\n struct CustomSecurityConfig {\n uint128 additionSecurityPeriod;\n uint128 removalSecurityPeriod;\n uint128 securityWindow;\n uint128 recoveryPeriod;\n uint128 lockPeriod;\n uint128 approvalValidationPeriod;\n uint128 migrationPeriod;\n }\n\n /**\n * @notice Modifier to only allow wallet itself to make a call to wallet\n */\n modifier onlyWallet(address _wallet) {\n if (msg.sender != _wallet) revert SecurityManager__CallerNotWallet();\n _;\n }\n\n /**\n * @notice Modifier to revert if the variable is already initialized\n */\n modifier initializer(bool _isInitialized) {\n if (_isInitialized) revert SecurityManager__AlreadyIntialized();\n _;\n }\n\n /**\n * @notice Transfers the ownership of the contract to the given owner\n * @param _owner Address of owner who has access to initialize the default security variables for security manager\n */\n constructor(address _owner) {\n transferOwnership(_owner);\n _transferOwnership(_owner);\n }\n\n /**\n * @notice Sets the initial default/min/max addition security period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultAdditionSecurityPeriod Default Addition Security Period for all Barz contracts\n * @param _minAdditionSecurityPeriod Minimum Addition Security Period for all Barz contracts\n * @param _maxAdditionSecurityPeriod Maximum Addition Security Period for all Barz contracts\n */\n function initializeAdditionSecurityPeriod(\n uint128 _defaultAdditionSecurityPeriod,\n uint128 _minAdditionSecurityPeriod,\n uint128 _maxAdditionSecurityPeriod\n )\n external\n override\n onlyOwner\n initializer(_isAdditionSecurityPeriodInitialized)\n {\n _isAdditionSecurityPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultAdditionSecurityPeriod,\n _minAdditionSecurityPeriod,\n _maxAdditionSecurityPeriod\n );\n defaultAdditionSecurityPeriod = _defaultAdditionSecurityPeriod;\n minAdditionSecurityPeriod = _minAdditionSecurityPeriod;\n maxAdditionSecurityPeriod = _maxAdditionSecurityPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max removal security period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultRemovalSecurityPeriod Default Removal Security Period for all Barz contracts\n * @param _minRemovalSecurityPeriod Minimum Removal Security Period for all Barz contracts\n * @param _maxRemovalSecurityPeriod Maximum Removal Security Period for all Barz contracts\n */\n function initializeRemovalSecurityPeriod(\n uint128 _defaultRemovalSecurityPeriod,\n uint128 _minRemovalSecurityPeriod,\n uint128 _maxRemovalSecurityPeriod\n )\n external\n override\n onlyOwner\n initializer(_isRemovalSecurityPeriodInitialized)\n {\n _isRemovalSecurityPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultRemovalSecurityPeriod,\n _minRemovalSecurityPeriod,\n _maxRemovalSecurityPeriod\n );\n defaultRemovalSecurityPeriod = _defaultRemovalSecurityPeriod;\n minRemovalSecurityPeriod = _minRemovalSecurityPeriod;\n maxRemovalSecurityPeriod = _maxRemovalSecurityPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/maxd security window for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultSecurityWindow Default Security Window for all Barz contracts\n * @param _minSecurityWindow Minimum Security Window for all Barz contracts\n * @param _maxSecurityWindow Maximum Security Window for all Barz contracts\n */\n function initializeSecurityWindow(\n uint128 _defaultSecurityWindow,\n uint128 _minSecurityWindow,\n uint128 _maxSecurityWindow\n ) external override onlyOwner initializer(_isSecurityWindowInitialized) {\n _isSecurityWindowInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultSecurityWindow,\n _minSecurityWindow,\n _maxSecurityWindow\n );\n defaultSecurityWindow = _defaultSecurityWindow;\n minSecurityWindow = _minSecurityWindow;\n maxSecurityWindow = _maxSecurityWindow;\n }\n\n /**\n * @notice Sets the initial default/min/max recovery period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultRecoveryPeriod Default Recovery Period for all Barz contracts\n * @param _minRecoveryPeriod Minimum Recovery Period for all Barz contracts\n * @param _maxRecoveryPeriod Maximum Recovery Period for all Barz contracts\n */\n function initializeRecoveryPeriod(\n uint128 _defaultRecoveryPeriod,\n uint128 _minRecoveryPeriod,\n uint128 _maxRecoveryPeriod\n ) external override onlyOwner initializer(_isRecoveryPeriodInitialized) {\n _isRecoveryPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultRecoveryPeriod,\n _minRecoveryPeriod,\n _maxRecoveryPeriod\n );\n defaultRecoveryPeriod = _defaultRecoveryPeriod;\n minRecoveryPeriod = _minRecoveryPeriod;\n maxRecoveryPeriod = _maxRecoveryPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max lock period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultLockPeriod Default Lock Period for all Barz contracts\n * @param _minLockPeriod Minimum Lock Period for all Barz contracts\n * @param _maxLockPeriod Maximum Lock Period for all Barz contracts\n */\n function initializeLockPeriod(\n uint128 _defaultLockPeriod,\n uint128 _minLockPeriod,\n uint128 _maxLockPeriod\n ) external override onlyOwner initializer(_isLockPeriodInitialized) {\n _isLockPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultLockPeriod,\n _minLockPeriod,\n _maxLockPeriod\n );\n defaultLockPeriod = _defaultLockPeriod;\n minLockPeriod = _minLockPeriod;\n maxLockPeriod = _maxLockPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max approval validation period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultApprovalValidationPeriod Default Approval Validation Period for all Barz contracts\n * @param _minApprovalValidationPeriod Minimum Approval Validation Period for all Barz contracts\n * @param _maxApprovalValidationPeriod Maximum Approval Validation Period for all Barz contracts\n */\n function initializeApprovalValidationPeriod(\n uint128 _defaultApprovalValidationPeriod,\n uint128 _minApprovalValidationPeriod,\n uint128 _maxApprovalValidationPeriod\n )\n external\n override\n onlyOwner\n initializer(_isApprovalValidationPeriodInitialized)\n {\n _isApprovalValidationPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultApprovalValidationPeriod,\n _minApprovalValidationPeriod,\n _maxApprovalValidationPeriod\n );\n defaultApprovalValidationPeriod = _defaultApprovalValidationPeriod;\n minApprovalValidationPeriod = _minApprovalValidationPeriod;\n maxApprovalValidationPeriod = _maxApprovalValidationPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max migration period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultMigrationPeriod Default Migration Period for all Barz contracts\n * @param _minMigrationPeriod Minimum Migration Period for all Barz contracts\n * @param _maxMigrationPeriod Maximum Migration Period for all Barz contracts\n */\n function initializeMigrationPeriod(\n uint128 _defaultMigrationPeriod,\n uint128 _minMigrationPeriod,\n uint128 _maxMigrationPeriod\n ) external override onlyOwner initializer(_isMigrationPeriodInitialized) {\n _isMigrationPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultMigrationPeriod,\n _minMigrationPeriod,\n _maxMigrationPeriod\n );\n defaultMigrationPeriod = _defaultMigrationPeriod;\n minMigrationPeriod = _minMigrationPeriod;\n maxMigrationPeriod = _maxMigrationPeriod;\n }\n\n /**\n * @notice Wallet owner sets the addition security period for the wallet. Only the owner of wallet can call this function.\n * The addition security period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _additionSecurityPeriod Custom Addition Security Period for the wallet\n */\n function setAdditionSecurityPeriod(\n address _wallet,\n uint128 _additionSecurityPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _additionSecurityPeriod,\n minAdditionSecurityPeriod,\n maxAdditionSecurityPeriod\n );\n securityConfigs[_wallet]\n .additionSecurityPeriod = _additionSecurityPeriod;\n }\n\n /**\n * @notice Wallet owner sets the removal security period for the wallet. Only the owner of wallet can call this function.\n * The removal security period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _removalSecurityPeriod Custom Removal Security Period for the wallet\n */\n function setRemovalSecurityPeriod(\n address _wallet,\n uint128 _removalSecurityPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _removalSecurityPeriod,\n minRemovalSecurityPeriod,\n maxRemovalSecurityPeriod\n );\n securityConfigs[_wallet].removalSecurityPeriod = _removalSecurityPeriod;\n }\n\n /**\n * @notice Wallet owner sets the security window for the wallet. Only the owner of wallet can call this function.\n * The security window should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _securityWindow Custom Security Window for the wallet\n */\n function setSecurityWindow(\n address _wallet,\n uint128 _securityWindow\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _securityWindow,\n minSecurityWindow,\n maxSecurityWindow\n );\n securityConfigs[_wallet].securityWindow = _securityWindow;\n }\n\n /**\n * @notice Wallet owner sets the recovery period for the wallet. Only the owner of wallet can call this function.\n * The recovery period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _recoveryPeriod Custom recovery period for the wallet\n */\n function setRecoveryPeriod(\n address _wallet,\n uint128 _recoveryPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _recoveryPeriod,\n minRecoveryPeriod,\n maxRecoveryPeriod\n );\n securityConfigs[_wallet].recoveryPeriod = _recoveryPeriod;\n }\n\n /**\n * @notice Wallet owner sets the lock period for the wallet. Only the owner of wallet can call this function.\n * The lock period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _lockPeriod Custom Lock period for the wallet\n */\n function setLockPeriod(\n address _wallet,\n uint128 _lockPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(_lockPeriod, minLockPeriod, maxLockPeriod);\n securityConfigs[_wallet].lockPeriod = _lockPeriod;\n }\n\n /**\n * @notice Wallet owner sets the approval validation period for the wallet. Only the owner of wallet can call this function.\n * The approval validation period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _approvalValidationPeriod Custom approval validation period for the wallet\n */\n function setApprovalValidationPeriod(\n address _wallet,\n uint128 _approvalValidationPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _approvalValidationPeriod,\n minApprovalValidationPeriod,\n maxApprovalValidationPeriod\n );\n securityConfigs[_wallet]\n .approvalValidationPeriod = _approvalValidationPeriod;\n }\n\n /**\n * @notice Wallet owner sets the migration period for the wallet. Only the owner of wallet can call this function.\n * The migration period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _migrationPeriod Custom migration period for the wallet\n */\n\n function setMigrationPeriod(\n address _wallet,\n uint128 _migrationPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _migrationPeriod,\n minMigrationPeriod,\n maxMigrationPeriod\n );\n securityConfigs[_wallet].migrationPeriod = _migrationPeriod;\n }\n\n /**\n * @notice Returns the addition security period. Returns default value when custom addition security period is not set\n * @param _wallet Address of wallet\n * @return additionSecurityPeriod Addition Security Period of the given Barz account or wallet\n */\n function additionSecurityPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 additionSecurityPeriod)\n {\n additionSecurityPeriod = securityConfigs[_wallet]\n .additionSecurityPeriod;\n additionSecurityPeriod = (additionSecurityPeriod == 0)\n ? defaultAdditionSecurityPeriod\n : additionSecurityPeriod;\n }\n\n /**\n * @notice Returns the removal security period. Returns default value when custom removal security period is not set\n * @param _wallet Address of wallet\n * @return removalSecurityPeriod Removal Security Period of the given Barz account or wallet\n */\n function removalSecurityPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 removalSecurityPeriod)\n {\n removalSecurityPeriod = securityConfigs[_wallet].removalSecurityPeriod;\n removalSecurityPeriod = (removalSecurityPeriod == 0)\n ? defaultRemovalSecurityPeriod\n : removalSecurityPeriod;\n }\n\n /**\n * @notice Returns the security window. Returns default value when custom security window is not set\n * @param _wallet Address of wallet\n * @return securityWindow Security window of the given Barz account or wallet\n */\n function securityWindowOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 securityWindow)\n {\n securityWindow = securityConfigs[_wallet].securityWindow;\n securityWindow = (securityWindow == 0)\n ? defaultSecurityWindow\n : securityWindow;\n }\n\n /**\n * @notice Returns the recovery period. Returns default value when custom recovery period is not set\n * @param _wallet Address of wallet\n * @return recoveryPeriod Recovery Period of the given Barz account or wallet\n */\n function recoveryPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 recoveryPeriod)\n {\n recoveryPeriod = securityConfigs[_wallet].recoveryPeriod;\n recoveryPeriod = (recoveryPeriod == 0)\n ? defaultRecoveryPeriod\n : recoveryPeriod;\n }\n\n /**\n * @notice Returns the lock period. Returns default value when custom lock period is not set\n * @param _wallet Address of wallet\n * @return lockPeriod Lock Period of the given Barz account or wallet\n */\n function lockPeriodOf(\n address _wallet\n ) public view override onlyWallet(_wallet) returns (uint128 lockPeriod) {\n lockPeriod = securityConfigs[_wallet].lockPeriod;\n lockPeriod = (lockPeriod == 0) ? defaultLockPeriod : lockPeriod;\n }\n\n /**\n * @notice Returns the approval validation period. Returns default value when custom approval validation period is not set\n * @param _wallet Address of wallet\n * @return approvalValidationPeriod Approval Validation Period of the given Barz account or wallet\n */\n function approvalValidationPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityConfigs[_wallet]\n .approvalValidationPeriod;\n approvalValidationPeriod = (approvalValidationPeriod == 0)\n ? defaultApprovalValidationPeriod\n : approvalValidationPeriod;\n }\n\n /**\n * @notice Returns the migration period. Returns default value when custom migration period is not set\n * @param _wallet Address of wallet\n * @return migrationPeriod Migration Period of the given Barz account or wallet\n */\n function migrationPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 migrationPeriod)\n {\n migrationPeriod = securityConfigs[_wallet].migrationPeriod;\n migrationPeriod = (migrationPeriod == 0)\n ? defaultMigrationPeriod\n : migrationPeriod;\n }\n\n /**\n * @notice Validates if the period is smaller than the max period or bigger than the min period\n * @param _period Period to be checked\n * @param _minPeriod Minimum period\n * @param _maxPeriod Maximum period\n */\n function _validatePeriodBoundaries(\n uint128 _period,\n uint128 _minPeriod,\n uint128 _maxPeriod\n ) internal pure {\n if (_period >= _maxPeriod || _period <= _minPeriod)\n revert SecurityManager__OutOfBoundary();\n }\n}\n" + }, + "contracts/infrastructure/WhitelistStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {RemoteStorage} from \"./RemoteStorage.sol\";\n\n/**\n * @title Whitelist storage\n * @dev Maps addresses to the corresponsing array of whitelisted addresses for each of them.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract WhitelistStorage is RemoteStorage {\n /**\n * @dev Add the address to the whitelist storage\n * @param _wallet User wallet\n * @param _address Address to be whitelisted\n */\n function whitelistAddress(address _wallet, address _address) external {\n enforceWalletOrGuardianIfExists(_wallet);\n addAddress(_wallet, _address);\n }\n\n /**\n * @dev Removes the address from the whitelist storage\n * @param _wallet User wallet\n * @param _address Address to be removed from the whitelist\n */\n function blacklistAddress(address _wallet, address _address) external {\n enforceGuardianOrWallet(_wallet);\n removeAddress(_wallet, _address);\n }\n\n /**\n * @dev Returns whether the address exists in the whitelist storage, associated with the wallet\n * @param _wallet User wallet\n * @param _address Address to be whitelisted\n */\n function isWhitelisted(\n address _wallet,\n address _address\n ) external view returns (bool) {\n return exists(_wallet, _address);\n }\n\n /**\n * @dev Returns all whitelisted addresses associated with the wallet\n * @param _wallet User wallet\n */\n function getWhitelistedAddresses(\n address _wallet\n ) external view returns (address[] memory) {\n return getAddresses(_wallet);\n }\n}\n" + }, + "contracts/interfaces/ERC/IERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\n\npragma solidity 0.8.21;\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155Receiver {\n /**\n * @dev Handles the receipt of a single ERC1155 token type. This function is\n * called at the end of a `safeTransferFrom` after the balance has been updated.\n *\n * NOTE: To accept the transfer, this must return\n * `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n * (i.e. 0xf23a6e61, or its own function selector).\n *\n * @param operator The address which initiated the transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param id The ID of the token being transferred\n * @param value The amount of tokens being transferred\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n ) external returns (bytes4);\n\n /**\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\n * is called at the end of a `safeBatchTransferFrom` after the balances have\n * been updated.\n *\n * NOTE: To accept the transfer(s), this must return\n * `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n * (i.e. 0xbc197c81, or its own function selector).\n *\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "contracts/interfaces/ERC/IERC1271.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\ninterface IERC1271 {\n function isValidSignature(\n bytes32 hash,\n bytes memory signature\n ) external view returns (bytes4);\n}\n" + }, + "contracts/interfaces/ERC/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\ninterface IERC165 {\n /// @notice Query if a contract implements an interface\n /// @param interfaceId The interface identifier, as specified in ERC-165\n /// @dev Interface identification is specified in ERC-165. This function\n /// uses less than 30,000 gas.\n /// @return `true` if the contract implements `interfaceID` and\n /// `interfaceID` is not 0xffffffff, `false` otherwise\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/IERC173.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\n/// @title ERC-173 Contract Ownership Standard\n/// Note: the ERC-165 identifier for this interface is 0x7f5828d0\n/* is ERC165 */\ninterface IERC173 {\n /// @dev This emits when ownership of a contract changes.\n event OwnershipTransferred(\n address indexed previousOwner,\n address indexed newOwner\n );\n\n /// @notice Get the address of the owner\n /// @return owner_ The address of the owner.\n function owner() external view returns (address owner_);\n\n /// @notice Set the address of the new owner of the contract\n /// @dev Set _newOwner to address(0) to renounce any ownership.\n /// @param _newOwner The address of the new owner of the contract\n function transferOwnership(address _newOwner) external;\n}\n" + }, + "contracts/interfaces/ERC/IERC677Receiver.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\ninterface IERC677Receiver {\n function onTokenTransfer(\n address sender,\n uint value,\n bytes calldata data\n ) external pure returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155 is IERC165 {\n /**\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n */\n event TransferSingle(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256 id,\n uint256 value\n );\n\n /**\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n * transfers.\n */\n event TransferBatch(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\n\n /**\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n * `approved`.\n */\n event ApprovalForAll(\n address indexed account,\n address indexed operator,\n bool approved\n );\n\n /**\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n *\n * If an {URI} event was emitted for `id`, the standard\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n * returned by {IERC1155MetadataURI-uri}.\n */\n event URI(string value, uint256 indexed id);\n\n /**\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(\n address account,\n uint256 id\n ) external view returns (uint256);\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] calldata accounts,\n uint256[] calldata ids\n ) external view returns (uint256[] memory);\n\n /**\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n *\n * Emits an {ApprovalForAll} event.\n *\n * Requirements:\n *\n * - `operator` cannot be the caller.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n *\n * See {setApprovalForAll}.\n */\n function isApprovedForAll(\n address account,\n address operator\n ) external view returns (bool);\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes calldata data\n ) external;\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(\n address indexed owner,\n address indexed spender,\n uint256 value\n );\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` 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 amount) 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(\n address owner,\n address spender\n ) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the 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 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` 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(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(\n address spender,\n uint256 addedValue\n ) external returns (bool);\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(\n address spender,\n uint256 subtractedValue\n ) external returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(\n address indexed from,\n address indexed to,\n uint256 indexed tokenId\n );\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(\n address indexed owner,\n address indexed approved,\n uint256 indexed tokenId\n );\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(\n address indexed owner,\n address indexed operator,\n bool approved\n );\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(\n uint256 tokenId\n ) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(\n address owner,\n address operator\n ) external view returns (bool);\n}\n" + }, + "contracts/interfaces/IBarz.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Barz Interface\n * @dev Interface of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IBarz {\n error Barz__InitializationFailure();\n}\n" + }, + "contracts/interfaces/IBarzFactory.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Barz} from \"../Barz.sol\";\n\n/**\n * @title Barz Factory Interface\n * @dev Interface of contract to easily deploy Barz to a pre-computed address with a single call\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IBarzFactory {\n event BarzDeployed(address);\n\n function createAccount(\n address verificationFacet,\n bytes calldata owner,\n uint256 salt\n ) external returns (Barz);\n\n function getAddress(\n address verificationFacet,\n bytes calldata owner,\n uint256 salt\n ) external view returns (address);\n\n function getBytecode(\n address accountFacet,\n address verificationFacet,\n address entryPoint,\n address facetRegistry,\n address defaultFallback,\n bytes memory ownerPublicKey\n ) external pure returns (bytes memory);\n\n function getCreationCode() external pure returns (bytes memory);\n}\n" + }, + "contracts/libraries/DefaultLibDiamond.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\n\nerror InitializationFunctionReverted(\n address _initializationContractAddress,\n bytes _calldata\n);\n\nlibrary DefaultLibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION =\n keccak256(\"trustwallet.barz.diamond.storage\");\n\n struct FacetAddressAndPosition {\n address facetAddress;\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\n }\n\n struct FacetFunctionSelectors {\n bytes4[] functionSelectors;\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\n }\n\n struct DiamondStorage {\n // maps function selector to the facet address and\n // the position of the selector in the facetFunctionSelectors.selectors array\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\n // maps facet addresses to function selectors\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\n // facet addresses\n address[] facetAddresses;\n // Used to query if a contract implements an interface.\n // Used to implement ERC-165.\n mapping(bytes4 => bool) supportedInterfaces;\n }\n\n function diamondStorage()\n internal\n pure\n returns (DiamondStorage storage ds)\n {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n event DiamondCut(\n IDiamondCut.FacetCut[] _diamondCut,\n address _init,\n bytes _calldata\n );\n\n // Internal function version of diamondCut\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n for (\n uint256 facetIndex;\n facetIndex < _diamondCut.length;\n facetIndex++\n ) {\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\n if (action == IDiamondCut.FacetCutAction.Add) {\n addFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\n replaceFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\n removeFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else {\n revert(\"LibDiamondCut: Incorrect FacetCutAction\");\n }\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Add facet can't be address(0)\"\n );\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n require(\n oldFacetAddress == address(0),\n \"LibDiamondCut: Can't add function that already exists\"\n );\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function replaceFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Replace facet can't be address(0)\"\n );\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n require(\n oldFacetAddress != _facetAddress,\n \"LibDiamondCut: Can't replace function with same facet\"\n );\n removeFunction(ds, oldFacetAddress, selector);\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function removeFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n // if function does not exist then do nothing and return\n require(\n _facetAddress == address(0),\n \"LibDiamondCut: Remove facet address must be address(0)\"\n );\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n removeFunction(ds, oldFacetAddress, selector);\n }\n }\n\n function addFacet(\n DiamondStorage storage ds,\n address _facetAddress\n ) internal {\n enforceHasContractCode(\n _facetAddress,\n \"LibDiamondCut: New facet has no code\"\n );\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds\n .facetAddresses\n .length;\n ds.facetAddresses.push(_facetAddress);\n }\n\n function addFunction(\n DiamondStorage storage ds,\n bytes4 _selector,\n uint96 _selectorPosition,\n address _facetAddress\n ) internal {\n ds\n .selectorToFacetAndPosition[_selector]\n .functionSelectorPosition = _selectorPosition;\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(\n _selector\n );\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\n }\n\n function removeFunction(\n DiamondStorage storage ds,\n address _facetAddress,\n bytes4 _selector\n ) internal {\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Can't remove function that doesn't exist\"\n );\n // an immutable function is a function defined directly in a diamond\n require(\n _facetAddress != address(this),\n \"LibDiamondCut: Can't remove immutable function\"\n );\n // replace selector with last selector, then delete last selector\n uint256 selectorPosition = ds\n .selectorToFacetAndPosition[_selector]\n .functionSelectorPosition;\n uint256 lastSelectorPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors\n .length - 1;\n // if not the same then replace _selector with lastSelector\n if (selectorPosition != lastSelectorPosition) {\n bytes4 lastSelector = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors[lastSelectorPosition];\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[\n selectorPosition\n ] = lastSelector;\n ds\n .selectorToFacetAndPosition[lastSelector]\n .functionSelectorPosition = uint96(selectorPosition);\n }\n // delete the last selector\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\n delete ds.selectorToFacetAndPosition[_selector];\n\n // if no more selectors for facet address then delete the facet address\n if (lastSelectorPosition == 0) {\n // replace facet address with last facet address and delete last facet address\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\n uint256 facetAddressPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .facetAddressPosition;\n if (facetAddressPosition != lastFacetAddressPosition) {\n address lastFacetAddress = ds.facetAddresses[\n lastFacetAddressPosition\n ];\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\n ds\n .facetFunctionSelectors[lastFacetAddress]\n .facetAddressPosition = facetAddressPosition;\n }\n ds.facetAddresses.pop();\n delete ds\n .facetFunctionSelectors[_facetAddress]\n .facetAddressPosition;\n }\n }\n\n function initializeDiamondCut(\n address _init,\n bytes memory _calldata\n ) internal {\n if (_init == address(0)) {\n return;\n }\n enforceHasContractCode(\n _init,\n \"LibDiamondCut: _init address has no code\"\n );\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length > 0) {\n // bubble up error\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(error)\n revert(add(32, error), returndata_size)\n }\n } else {\n revert InitializationFunctionReverted(_init, _calldata);\n }\n }\n }\n\n function enforceHasContractCode(\n address _contract,\n string memory _errorMessage\n ) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize > 0, _errorMessage);\n }\n}\n" + }, + "contracts/libraries/LibAppStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SafeCast} from \"@openzeppelin/contracts/utils/math/SafeCast.sol\";\nimport {IEntryPoint} from \"../aa-4337/interfaces/IEntryPoint.sol\";\nimport {IFacetRegistry} from \"../infrastructure/interfaces/IFacetRegistry.sol\";\n\n/*\n * @title App Storage\n * @dev App storage for Barz contract to prevent storage collision\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\n\nstruct Lock {\n uint64 release;\n bytes4 locker;\n}\n\nstruct InitializersStorage {\n // NOTE: initialized is a variable to make sure the initialization is only done once.\n uint8 signerInitialized;\n uint8 accountInitialized;\n uint8 restrictionsInitialized;\n}\n\nstruct AppStorage {\n mapping(uint256 => InitializersStorage) initStorage;\n uint8 signerMigration;\n bytes4 validateOwnerSignatureSelector;\n IEntryPoint entryPoint;\n IFacetRegistry facetRegistry;\n mapping(uint256 => Lock) locks;\n}\n\nlibrary LibAppStorage {\n error LibAppStorage__AccountAlreadyUninitialized();\n error LibAppStorage__AccountMustBeUninitialized();\n error LibAppStorage__SignerAlreadyUninitialized();\n error LibAppStorage__SignerMustBeUninitialized();\n\n function appStorage() internal pure returns (AppStorage storage ds) {\n assembly {\n ds.slot := 0\n }\n }\n\n function setSignerUninitialized() internal {\n AppStorage storage s = appStorage();\n if (1 != s.initStorage[0].signerInitialized) {\n revert LibAppStorage__SignerAlreadyUninitialized();\n }\n s.initStorage[0].signerInitialized = 0;\n }\n\n function getValidateOwnerSignatureSelector()\n internal\n view\n returns (bytes4 selector)\n {\n selector = appStorage().validateOwnerSignatureSelector;\n }\n\n function setValidateOwnerSignatureSelector(\n bytes4 _validateOwnerSignatureSelector\n ) internal {\n appStorage()\n .validateOwnerSignatureSelector = _validateOwnerSignatureSelector;\n }\n\n function enforceSignerInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].signerInitialized) {\n revert LibAppStorage__SignerMustBeUninitialized();\n }\n s.initStorage[0].signerInitialized = 1;\n }\n\n function enforceAccountInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].accountInitialized) {\n revert LibAppStorage__AccountMustBeUninitialized();\n }\n s.initStorage[0].accountInitialized = 1;\n }\n\n function initiateSignerMigration() internal {\n appStorage().signerMigration = 1;\n }\n\n function enforceSignerMigration() internal view {\n if (1 != appStorage().signerMigration) {\n revert LibAppStorage__AccountMustBeUninitialized();\n }\n }\n\n function finalizeSignerMigration() internal {\n appStorage().signerMigration = 0;\n }\n\n function setLock(uint256 _releaseAfter, bytes4 _locker) internal {\n appStorage().locks[0] = Lock(SafeCast.toUint64(_releaseAfter), _locker);\n }\n\n function enforceRestrictionsInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].restrictionsInitialized)\n revert LibAppStorage__SignerMustBeUninitialized();\n s.initStorage[0].restrictionsInitialized = 1;\n }\n\n function setRestrictionsUninitialized() internal {\n AppStorage storage s = appStorage();\n if (1 != s.initStorage[0].restrictionsInitialized)\n revert LibAppStorage__AccountAlreadyUninitialized();\n s.initStorage[0].restrictionsInitialized = 0;\n }\n}\n\ncontract BarzStorage {\n AppStorage internal s;\n modifier onlyWhenUnlocked() {\n require(\n uint64(block.timestamp) >= s.locks[0].release,\n \"Account Locked\"\n );\n _;\n }\n modifier onlyWhenLocked() {\n require(\n uint64(block.timestamp) < s.locks[0].release,\n \"Account Unlocked\"\n );\n _;\n }\n}\n" + }, + "contracts/libraries/LibDiamond.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\n\nerror InitializationFunctionReverted(\n address _initializationContractAddress,\n bytes _calldata\n);\n\nlibrary LibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION =\n keccak256(\"trustwallet.barz.diamond.storage\");\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\n bytes4(keccak256(\"verifyRestrictions(address,address,uint256,bytes)\"));\n struct DiamondStorage {\n // maps function selectors to the facets that execute the functions.\n // and maps the selectors to their position in the selectorSlots array.\n // func selector => address facet, selector position\n mapping(bytes4 => bytes32) facets;\n // array of slots of function selectors.\n // each slot holds 8 function selectors.\n mapping(uint256 => bytes32) selectorSlots;\n // The number of function selectors in selectorSlots\n uint16 selectorCount;\n // Used to query if a contract implements an interface.\n // Used to implement ERC-165.\n mapping(bytes4 => bool) supportedInterfaces;\n // Default Fallback Handler of the barz.\n IDiamondLoupe defaultFallbackHandler;\n }\n\n function diamondStorage()\n internal\n pure\n returns (DiamondStorage storage ds)\n {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n function enforceIsSelf() internal view {\n require(msg.sender == address(this), \"LibDiamond: Caller not self\");\n }\n\n event DiamondCut(\n IDiamondCut.FacetCut[] _diamondCut,\n address _init,\n bytes _calldata\n );\n\n bytes32 constant CLEAR_ADDRESS_MASK =\n bytes32(uint256(0xffffffffffffffffffffffff));\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\n\n // Internal function version of diamondCut\n // This code is almost the same as the external diamondCut,\n // except it is using 'Facet[] memory _diamondCut' instead of\n // 'Facet[] calldata _diamondCut'.\n // The code is duplicated to prevent copying calldata to memory which\n // causes an error for a two dimensional array.\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n DiamondStorage storage ds = diamondStorage();\n uint256 originalSelectorCount = ds.selectorCount;\n uint256 selectorCount = originalSelectorCount;\n bytes32 selectorSlot;\n // Check if last selector slot is not full\n // \"selectorCount & 7\" is a gas efficient modulo by eight \"selectorCount % 8\"\n if (selectorCount & 7 > 0) {\n // get last selectorSlot\n // \"selectorSlot >> 3\" is a gas efficient division by 8 \"selectorSlot / 8\"\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\n }\n // loop through diamond cut\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\n selectorCount,\n selectorSlot,\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].action,\n _diamondCut[facetIndex].functionSelectors\n );\n\n unchecked {\n facetIndex++;\n }\n }\n if (selectorCount != originalSelectorCount) {\n ds.selectorCount = uint16(selectorCount);\n }\n // If last selector slot is not full\n // \"selectorCount & 7\" is a gas efficient modulo by eight \"selectorCount % 8\"\n if (selectorCount & 7 > 0) {\n // \"selectorSlot >> 3\" is a gas efficient division by 8 \"selectorSlot / 8\"\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addReplaceRemoveFacetSelectors(\n uint256 _selectorCount,\n bytes32 _selectorSlot,\n address _newFacetAddress,\n IDiamondCut.FacetCutAction _action,\n bytes4[] memory _selectors\n ) internal returns (uint256, bytes32) {\n DiamondStorage storage ds = diamondStorage();\n require(\n _selectors.length > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n if (_action == IDiamondCut.FacetCutAction.Add) {\n enforceHasContractCode(\n _newFacetAddress,\n \"LibDiamondCut: Add facet has no code\"\n );\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n require(\n address(bytes20(oldFacet)) == address(0),\n \"LibDiamondCut: Can't add function that already exists\"\n );\n // add facet for selector\n ds.facets[selector] =\n bytes20(_newFacetAddress) |\n bytes32(_selectorCount);\n // \"_selectorCount & 7\" is a gas efficient modulo by eight \"_selectorCount % 8\"\n // \" << 5 is the same as multiplying by 32 ( * 32)\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\n // clear selector position in slot and add selector\n _selectorSlot =\n (_selectorSlot &\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\n (bytes32(selector) >> selectorInSlotPosition);\n // if slot is full then write it to storage\n if (selectorInSlotPosition == 224) {\n // \"_selectorSlot >> 3\" is a gas efficient division by 8 \"_selectorSlot / 8\"\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\n _selectorSlot = 0;\n }\n _selectorCount++;\n\n unchecked {\n selectorIndex++;\n }\n }\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\n enforceHasContractCode(\n _newFacetAddress,\n \"LibDiamondCut: Replace facet has no code\"\n );\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n address oldFacetAddress = address(bytes20(oldFacet));\n // only useful if immutable functions exist\n require(\n oldFacetAddress != address(this),\n \"LibDiamondCut: Can't replace immutable function\"\n );\n require(\n oldFacetAddress != _newFacetAddress,\n \"LibDiamondCut: Can't replace function with same function\"\n );\n require(\n oldFacetAddress != address(0),\n \"LibDiamondCut: Can't replace function that doesn't exist\"\n );\n // replace old facet address\n ds.facets[selector] =\n (oldFacet & CLEAR_ADDRESS_MASK) |\n bytes20(_newFacetAddress);\n\n unchecked {\n selectorIndex++;\n }\n }\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\n require(\n _newFacetAddress == address(0),\n \"LibDiamondCut: Remove facet address must be address(0)\"\n );\n // \"_selectorCount >> 3\" is a gas efficient division by 8 \"_selectorCount / 8\"\n uint256 selectorSlotCount = _selectorCount >> 3;\n // \"_selectorCount & 7\" is a gas efficient modulo by eight \"_selectorCount % 8\"\n uint256 selectorInSlotIndex = _selectorCount & 7;\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n if (_selectorSlot == 0) {\n // get last selectorSlot\n selectorSlotCount--;\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\n selectorInSlotIndex = 7;\n } else {\n selectorInSlotIndex--;\n }\n bytes4 lastSelector;\n uint256 oldSelectorsSlotCount;\n uint256 oldSelectorInSlotPosition;\n // adding a block here prevents stack too deep error\n {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n require(\n address(bytes20(oldFacet)) != address(0),\n \"LibDiamondCut: Can't remove function that doesn't exist\"\n );\n // only useful if immutable functions exist\n require(\n address(bytes20(oldFacet)) != address(this),\n \"LibDiamondCut: Can't remove immutable function\"\n );\n // replace selector with last selector in ds.facets\n // gets the last selector\n // \" << 5 is the same as multiplying by 32 ( * 32)\n lastSelector = bytes4(\n _selectorSlot << (selectorInSlotIndex << 5)\n );\n if (lastSelector != selector) {\n // update last selector slot position info\n ds.facets[lastSelector] =\n (oldFacet & CLEAR_ADDRESS_MASK) |\n bytes20(ds.facets[lastSelector]);\n }\n delete ds.facets[selector];\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\n // \"oldSelectorCount >> 3\" is a gas efficient division by 8 \"oldSelectorCount / 8\"\n oldSelectorsSlotCount = oldSelectorCount >> 3;\n // \"oldSelectorCount & 7\" is a gas efficient modulo by eight \"oldSelectorCount % 8\"\n // \" << 5 is the same as multiplying by 32 ( * 32)\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\n }\n if (oldSelectorsSlotCount != selectorSlotCount) {\n bytes32 oldSelectorSlot = ds.selectorSlots[\n oldSelectorsSlotCount\n ];\n // clears the selector we are deleting and puts the last selector in its place.\n oldSelectorSlot =\n (oldSelectorSlot &\n ~(CLEAR_SELECTOR_MASK >>\n oldSelectorInSlotPosition)) |\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\n // update storage with the modified slot\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\n } else {\n // clears the selector we are deleting and puts the last selector in its place.\n _selectorSlot =\n (_selectorSlot &\n ~(CLEAR_SELECTOR_MASK >>\n oldSelectorInSlotPosition)) |\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\n }\n if (selectorInSlotIndex == 0) {\n delete ds.selectorSlots[selectorSlotCount];\n _selectorSlot = 0;\n }\n\n unchecked {\n selectorIndex++;\n }\n }\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\n } else {\n revert(\"LibDiamondCut: Incorrect FacetCutAction\");\n }\n return (_selectorCount, _selectorSlot);\n }\n\n function initializeDiamondCut(\n address _init,\n bytes memory _calldata\n ) internal {\n if (_init == address(0)) {\n return;\n }\n enforceHasContractCode(\n _init,\n \"LibDiamondCut: _init address has no code\"\n );\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length > 0) {\n // bubble up error\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(error)\n revert(add(32, error), returndata_size)\n }\n } else {\n revert InitializationFunctionReverted(_init, _calldata);\n }\n }\n }\n\n function enforceHasContractCode(\n address _contract,\n string memory _errorMessage\n ) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize > 0, _errorMessage);\n }\n\n function restrictionsFacet() internal view returns (address facetAddress_) {\n facetAddress_ = address(\n bytes20(\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\n )\n );\n }\n}\n" + }, + "contracts/libraries/LibFacetStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Storage\n * @dev Storage contract to store each facets variables with diamond storage\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\n\nstruct Secp256k1VerificationStorage {\n address signer;\n}\n\nstruct Secp256r1VerificationStorage {\n uint256[2] q;\n}\n\nstruct GuardianStorage {\n mapping(bytes32 => uint256) pending;\n mapping(uint8 => StorageConfig) configs;\n}\n\nstruct Info {\n bool exists;\n uint128 index;\n}\n\nstruct StorageConfig {\n address[] addresses;\n mapping(address => Info) info;\n}\n\nstruct RecoveryConfig {\n bytes recoveryPublicKey;\n uint64 executeAfter;\n}\n\nstruct ApprovalConfig {\n bool isApproved;\n uint64 validUntil;\n}\n\nstruct RecoveryApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isNewOwnerApproved;\n}\n\nstruct RecoveryStorage {\n mapping(uint8 => RecoveryConfig) recoveryConfigs;\n mapping(uint8 => RecoveryApprovalConfig) recoveryApprovalConfigs;\n uint128 nonce;\n}\n\nstruct RestrictionsStorage {\n address[] restrictions;\n mapping(address => bool) exists;\n}\n\nstruct SignatureMigrationConfig {\n bytes migrationPublicKey;\n address migrationVerificationFacet;\n bytes4[] migrationSelectors;\n uint64 migrateAfter;\n}\n\nstruct SignatureMigrationApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isMigrationApproved;\n}\n\nstruct SignatureMigrationStorage {\n mapping(uint8 => SignatureMigrationConfig) migrationConfigs;\n mapping(uint8 => SignatureMigrationApprovalConfig) migrationApprovalConfigs;\n uint128 nonce;\n}\n\nstruct DiamondCutApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isDiamondCutApproved;\n}\n\nstruct DiamondCutStorage {\n mapping(uint8 => DiamondCutApprovalConfig) diamondCutApprovalConfigs;\n uint128 nonce;\n}\n\nstruct LockStorage {\n uint128 nonce;\n}\n\nlibrary LibFacetStorage {\n bytes32 constant K1_STORAGE_POSITION =\n keccak256(\n \"v0.trustwallet.diamond.storage.Secp256k1VerificationStorage\"\n );\n bytes32 constant R1_STORAGE_POSITION =\n keccak256(\n \"v0.trustwallet.diamond.storage.Secp256r1VerificationStorage\"\n );\n bytes32 constant GUARDIAN_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.GuardianStorage\");\n bytes32 constant RECOVERY_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.RecoveryStorage\");\n bytes32 constant RESTRICTION_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.RestrictionsStorage\");\n bytes32 constant MIGRATION_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.SignatureMigrationStorage\");\n bytes32 constant DIAMONDCUT_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.DiamondCutStorage\");\n bytes32 constant LOCK_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.LockStorage\");\n\n function k1Storage()\n internal\n pure\n returns (Secp256k1VerificationStorage storage ds)\n {\n bytes32 storagePosition = K1_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function r1Storage()\n internal\n pure\n returns (Secp256r1VerificationStorage storage ds)\n {\n bytes32 storagePosition = R1_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function guardianStorage()\n internal\n pure\n returns (GuardianStorage storage ds)\n {\n bytes32 storagePosition = GUARDIAN_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function recoveryStorage()\n internal\n pure\n returns (RecoveryStorage storage ds)\n {\n bytes32 storagePosition = RECOVERY_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function restrictionsStorage()\n internal\n pure\n returns (RestrictionsStorage storage ds)\n {\n bytes32 storagePosition = RESTRICTION_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function migrationStorage()\n internal\n pure\n returns (SignatureMigrationStorage storage ds)\n {\n bytes32 storagePosition = MIGRATION_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function diamondCutStorage()\n internal\n pure\n returns (DiamondCutStorage storage ds)\n {\n bytes32 storagePosition = DIAMONDCUT_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function lockStorage() internal pure returns (LockStorage storage ds) {\n bytes32 storagePosition = LOCK_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n}\n" + }, + "contracts/libraries/LibGuardian.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibFacetStorage, StorageConfig} from \"./LibFacetStorage.sol\";\n\n/**\n * @title LibGuardian\n * @dev Internal Library to provide utility feature for Guardians stored in Guardian Facet Storage\n * @author David Yongjun Kim (@Powerstream3604)\n */\nlibrary LibGuardian {\n function majorityOfGuardians()\n internal\n view\n returns (uint256 guardianNumber)\n {\n uint256 guardianLength = guardianCount();\n guardianNumber = (guardianLength == 0) ? 0 : guardianLength / 2 + 1;\n }\n\n function isGuardian(address _guardian) internal view returns (bool) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n return config.info[_guardian].exists;\n }\n\n function guardianCount() internal view returns (uint256) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n return config.addresses.length;\n }\n\n function getGuardians() internal view returns (address[] memory) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n address[] memory addresses = new address[](config.addresses.length);\n uint256 addressesLen = config.addresses.length;\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n return addresses;\n }\n}\n" + }, + "contracts/libraries/LibLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {LibDiamond} from \"./LibDiamond.sol\";\n\n/**\n * @title LibLoupe\n * @dev Internal Library to provide utility feature for reading the state of diamond facets\n * Originally from Diamond's implementation of Mudgen(author of EIP-2535)\n */\nlibrary LibLoupe {\n /// @notice Gets all facets and their selectors.\n /// @return facets_ Facet\n function facets()\n internal\n view\n returns (IDiamondLoupe.Facet[] memory facets_)\n {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facets_ = new IDiamondLoupe.Facet[](ds.selectorCount);\n uint16[] memory numFacetSelectors = new uint16[](ds.selectorCount);\n uint256 numFacets;\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facetAddress_ = address(bytes20(ds.facets[selector]));\n bool continueLoop;\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n if (facets_[facetIndex].facetAddress == facetAddress_) {\n facets_[facetIndex].functionSelectors[\n numFacetSelectors[facetIndex]\n ] = selector;\n // probably will never have more than 256 functions from one facet contract\n require(numFacetSelectors[facetIndex] < 255);\n numFacetSelectors[facetIndex]++;\n continueLoop = true;\n break;\n }\n }\n if (continueLoop) {\n continue;\n }\n facets_[numFacets].facetAddress = facetAddress_;\n facets_[numFacets].functionSelectors = new bytes4[](\n ds.selectorCount\n );\n facets_[numFacets].functionSelectors[0] = selector;\n numFacetSelectors[numFacets] = 1;\n numFacets++;\n }\n }\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n uint256 numSelectors = numFacetSelectors[facetIndex];\n bytes4[] memory selectors = facets_[facetIndex].functionSelectors;\n // setting the number of selectors\n assembly {\n mstore(selectors, numSelectors)\n }\n }\n // setting the number of facets\n assembly {\n mstore(facets_, numFacets)\n }\n }\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n /// @return _facetFunctionSelectors The selectors associated with a facet address.\n function facetFunctionSelectors(\n address _facet\n ) internal view returns (bytes4[] memory _facetFunctionSelectors) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n uint256 numSelectors;\n _facetFunctionSelectors = new bytes4[](ds.selectorCount);\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facet = address(bytes20(ds.facets[selector]));\n if (_facet == facet) {\n _facetFunctionSelectors[numSelectors] = selector;\n numSelectors++;\n }\n }\n }\n // Set the number of selectors in the array\n assembly {\n mstore(_facetFunctionSelectors, numSelectors)\n }\n }\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses()\n internal\n view\n returns (address[] memory facetAddresses_)\n {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facetAddresses_ = new address[](ds.selectorCount);\n uint256 numFacets;\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facetAddress_ = address(bytes20(ds.facets[selector]));\n bool continueLoop;\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n if (facetAddress_ == facetAddresses_[facetIndex]) {\n continueLoop = true;\n break;\n }\n }\n if (continueLoop) {\n continue;\n }\n facetAddresses_[numFacets] = facetAddress_;\n numFacets++;\n }\n }\n // Set the number of facet addresses in the array\n assembly {\n mstore(facetAddresses_, numFacets)\n }\n }\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(\n bytes4 _functionSelector\n ) internal view returns (address facetAddress_) {\n facetAddress_ = address(\n bytes20(LibDiamond.diamondStorage().facets[_functionSelector])\n );\n }\n}\n" + }, + "contracts/libraries/LibMultiSigStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Multi-sig Storage\n * @dev Storage contract for storing Multi-sig Facet variables in diamond storage pattern\n * @author David Yongjun Kim (@Powerstream3604)\n */\n\nstruct MultiSigStorage {\n mapping(address => address) owners;\n mapping(uint256 => mapping(address => mapping(bytes32 => uint256))) approvedHashes;\n uint256 ownerCount;\n uint256 threshold;\n uint256 counter;\n}\n\nlibrary LibMultiSigStorage {\n function multisigStorage()\n internal\n pure\n returns (MultiSigStorage storage ds)\n {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.MultiSigStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n}\n" + }, + "contracts/libraries/LibRecoverSpender.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title RecoverSpender\n * @dev Library to determine the action and spender of calldata\n * @author Ruslan Serebriakov (@rsrbk)\n */\nlibrary LibRecoverSpender {\n // ERC20, ERC721 & ERC1155 transfers & approvals\n bytes4 private constant ERC20_TRANSFER =\n bytes4(keccak256(\"transfer(address,uint256)\"));\n bytes4 private constant ERC20_APPROVE =\n bytes4(keccak256(\"approve(address,uint256)\"));\n bytes4 private constant ERC20_INCREASE_ALLOWANCE =\n bytes4(keccak256(\"increaseAllowance(address,uint256)\"));\n bytes4 private constant ERC20_DECREASE_ALLOWANCE =\n bytes4(keccak256(\"decreaseAllowance(address,uint256)\"));\n bytes4 private constant ERC721_SET_APPROVAL_FOR_ALL =\n bytes4(keccak256(\"setApprovalForAll(address,bool)\"));\n bytes4 private constant ERC721_TRANSFER_FROM =\n bytes4(keccak256(\"transferFrom(address,address,uint256)\"));\n bytes4 private constant ERC721_SAFE_TRANSFER_FROM =\n bytes4(keccak256(\"safeTransferFrom(address,address,uint256)\"));\n bytes4 private constant ERC721_SAFE_TRANSFER_FROM_BYTES =\n bytes4(keccak256(\"safeTransferFrom(address,address,uint256,bytes)\"));\n bytes4 private constant ERC1155_SAFE_TRANSFER_FROM =\n bytes4(\n keccak256(\"safeTransferFrom(address,address,uint256,uint256,bytes)\")\n );\n bytes4 private constant ERC1155_SAFE_BATCH_TRANSFER_FROM =\n bytes4(\n keccak256(\n \"safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)\"\n )\n );\n\n /**\n * @notice Helper method to recover the spender from a contract call.\n * The method returns the contract unless the call is to a standard method of a ERC20/ERC721/ERC1155 token\n * in which case the spender is recovered from the data.\n * @param _to The target contract.\n * @param _data The data payload.\n */\n function _recover(\n address _to,\n bytes memory _data\n ) internal pure returns (address spender) {\n if (_data.length >= 68) {\n bytes4 methodId;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n methodId := mload(add(_data, 0x20))\n }\n if (\n methodId == ERC20_TRANSFER ||\n methodId == ERC20_APPROVE ||\n methodId == ERC20_INCREASE_ALLOWANCE ||\n methodId == ERC20_DECREASE_ALLOWANCE ||\n methodId == ERC721_SET_APPROVAL_FOR_ALL\n ) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n spender := mload(add(_data, 0x24))\n }\n return spender;\n }\n if (\n methodId == ERC721_TRANSFER_FROM ||\n methodId == ERC721_SAFE_TRANSFER_FROM ||\n methodId == ERC721_SAFE_TRANSFER_FROM_BYTES ||\n methodId == ERC1155_SAFE_TRANSFER_FROM ||\n methodId == ERC1155_SAFE_BATCH_TRANSFER_FROM\n ) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n spender := mload(add(_data, 0x44))\n }\n return spender;\n }\n }\n\n spender = _to;\n }\n}\n" + }, + "contracts/libraries/LibUtils.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\n\nlibrary LibUtils {\n // Internal utility functions\n function mergeArrays(\n bytes4[] memory _array1,\n bytes4[] memory _array2\n ) internal pure returns (bytes4[] memory) {\n uint256 length1 = _array1.length;\n uint256 length2 = _array2.length;\n bytes4[] memory mergedArray = new bytes4[](length1 + length2);\n\n for (uint256 i; i < length1; ) {\n mergedArray[i] = _array1[i];\n unchecked {\n ++i;\n }\n }\n\n for (uint256 i; i < length2; ) {\n mergedArray[length1 + i] = _array2[i];\n unchecked {\n ++i;\n }\n }\n\n return mergedArray;\n }\n\n function removeFacetElement(\n IDiamondLoupe.Facet[] memory _facets,\n uint256 _index\n ) internal pure returns (IDiamondLoupe.Facet[] memory) {\n require(_index < _facets.length, \"Invalid index\");\n require(_facets.length != 0, \"Invalid array\");\n\n // Create a new array with a length of `_facets.length - 1`\n IDiamondLoupe.Facet[] memory newArray = new IDiamondLoupe.Facet[](\n _facets.length - 1\n );\n uint256 newArrayLength = newArray.length;\n // Iterate over the original array, skipping the element at the specified `index`\n for (uint256 i; i < newArrayLength; ) {\n if (i < _index) {\n newArray[i] = _facets[i];\n } else {\n newArray[i] = _facets[i + 1];\n }\n unchecked {\n ++i;\n }\n }\n\n return newArray;\n }\n\n function removeElement(\n bytes4[] memory _array,\n uint256 _index\n ) internal pure returns (bytes4[] memory) {\n require(_index < _array.length, \"Invalid index\");\n require(_array.length != 0, \"Invalid array\");\n\n bytes4[] memory newArray = new bytes4[](_array.length - 1);\n uint256 newArrayLength = newArray.length;\n for (uint256 i; i < newArrayLength; ) {\n if (i < _index) {\n newArray[i] = _array[i];\n } else {\n newArray[i] = _array[i + 1];\n }\n unchecked {\n ++i;\n }\n }\n\n return newArray;\n }\n\n function setValue(\n bytes4[] memory _keys,\n address[] memory _values,\n bytes4 _key,\n address _value\n ) internal pure returns (bytes4[] memory, address[] memory) {\n uint256 index = findIndex(_keys, _key);\n uint256 keysLength = _keys.length;\n if (index < keysLength) {\n _values[index] = _value;\n } else {\n // Create new storage arrays\n bytes4[] memory newKeys = new bytes4[](keysLength + 1);\n address[] memory newValues = new address[](_values.length + 1);\n\n // Copy values to the new storage arrays\n for (uint256 i; i < keysLength; ) {\n newKeys[i] = _keys[i];\n newValues[i] = _values[i];\n\n unchecked {\n ++i;\n }\n }\n\n // Add the new key-value pair\n newKeys[keysLength] = _key;\n newValues[_values.length] = _value;\n\n return (newKeys, newValues);\n }\n\n // If the key already exists, return the original arrays\n return (_keys, _values);\n }\n\n function getValue(\n bytes4[] memory _keys,\n address[] memory _values,\n bytes4 _key\n ) internal pure returns (address) {\n uint256 index = findIndex(_keys, _key);\n if (index >= _keys.length) return address(0);\n\n return _values[index];\n }\n\n function findIndex(\n bytes4[] memory _keys,\n bytes4 _key\n ) internal pure returns (uint256) {\n uint256 keysLength = _keys.length;\n for (uint256 i; i < keysLength; ) {\n if (_keys[i] == _key) {\n return i;\n }\n unchecked {\n ++i;\n }\n }\n return keysLength;\n }\n}\n" + }, + "contracts/restrictions/IRestriction.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Interface for restrictions\n * @dev Restriction is a contract which decides whether to approve a certain kind of transaction, based on its internal logic.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface IRestriction {\n /**\n * @dev Based on restriction's internal logic, it should accept or reject a certain transaction.\n * @param from The address of the sender, that will be signing the transaction.\n * @param to The receiving address.\n * @param value Amount of ETH to transfer from sender to recipient.\n * @param _calldata Optional field to include arbitrary data.\n * @return bool value for whether the check is passed\n */\n function check(\n address from,\n address to,\n uint256 value,\n bytes calldata _calldata\n ) external returns (bool);\n}\n" + }, + "contracts/restrictions/WhitelistRestriction.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibRecoverSpender} from \"../libraries/LibRecoverSpender.sol\";\nimport {WhitelistStorage} from \"../infrastructure/WhitelistStorage.sol\";\nimport {IRestriction} from \"./IRestriction.sol\";\n\n/**\n * @title Whitelist Restriction\n * @dev This restriction defines a list of accepted addresses and denies any interaction with addresses outside of it.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract WhitelistRestriction is IRestriction {\n WhitelistStorage public immutable whitelistStorage;\n\n constructor(WhitelistStorage _whitelistStorage) {\n whitelistStorage = _whitelistStorage;\n }\n\n /**\n * @notice Helper method to recover the spender from a contract call.\n * The method returns the contract unless the call is to a standard method of a ERC20/ERC721/ERC1155 token\n * in which case the spender is recovered from the data.\n * @param _to The target contract.\n * @param _data The data payload.\n */\n function recoverSpender(\n address _to,\n bytes memory _data\n ) public pure returns (address spender) {\n return LibRecoverSpender._recover(_to, _data);\n }\n\n /*\n * @dev IRestriction's implementation. It will allow transaction if the sender is whitelisted, or user, or the whitelist storage.\n * @param _from The address of the sender, that will be signing the transaction.\n * @param _to The receiving address.\n * @param _calldata Optional field to include arbitrary data.\n * @return result value for whether the check is passed\n */\n function check(\n address _from,\n address _to,\n uint256 /*_value*/,\n bytes calldata _calldata\n ) external view override returns (bool result) {\n return\n whitelistStorage.isWhitelisted(\n _from,\n LibRecoverSpender._recover(_to, _calldata)\n ) ||\n _to == address(whitelistStorage) ||\n _to == msg.sender;\n }\n}\n" + }, + "contracts/test/Counter.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\ncontract TestCounter {\n int private count = 0;\n\n function incrementCounter() public {\n count += 1;\n }\n\n function decrementCounter() public {\n count -= 1;\n }\n\n function getCount() public view returns (int) {\n return count;\n }\n}\n" + }, + "contracts/test/TestERC1155.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC1155/ERC1155.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\n\ncontract TestERC1155 is ERC1155 {\n using Counters for Counters.Counter;\n\n Counters.Counter private _tokenIds;\n\n constructor() ERC1155(\"\") {}\n\n function mint(address account, uint256 amount) external {\n uint256 tokenId = _getNextTokenId();\n _mint(account, tokenId, amount, \"\");\n }\n\n function mintBatch(\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes memory data\n ) external {\n require(\n ids.length == amounts.length,\n \"TestERC1155: arrays length mismatch\"\n );\n\n _mintBatch(to, ids, amounts, data);\n }\n\n function _getNextTokenId() private returns (uint256) {\n _tokenIds.increment();\n return _tokenIds.current();\n }\n}\n" + }, + "contracts/test/TestERC777.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC777/ERC777.sol\";\n\ncontract TestERC777 is ERC777 {\n constructor(\n address[] memory _operators\n ) ERC777(\"TestERC777\", \"TERC777\", _operators) {}\n\n function mint(address account, uint256 amount) external {\n _mint(account, amount, \"\", \"\");\n }\n}\n" + }, + "contracts/test/TestInvalidSecp256k1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IVerificationFacet} from \"../facets/interfaces/IVerificationFacet.sol\";\nimport {IERC1271} from \"../interfaces/ERC/IERC1271.sol\";\nimport {AppStorage, LibAppStorage, BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {LibFacetStorage, Secp256k1VerificationStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {UserOperation} from \"../aa-4337/interfaces/UserOperation.sol\";\n\n/**\n * @title Test Secp256k1 verification facet\n * @dev Default Ethereum's elliptic curve\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract TestInvalidSecp256k1VerificationFacet is BarzStorage, IERC1271 {\n using ECDSA for bytes32;\n error Secp256k1VerificationFacet__InvalidSignerLength();\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n\n event SignerUninitialized();\n\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n }\n\n // THIS INVALID FACET DOES NOT INCLUDE initializeSigner()\n // THIS FACET IS USED TO TEST WHEN initializeSigner() DOESN'T EXIST IN FACET\n\n function uninitializeSigner() external returns (uint256 uninitSuccess) {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view returns (uint256 validationData) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n return validateSignature(userOp, userOpHash, k1Storage.signer);\n }\n\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n address signer\n ) public pure returns (uint256) {\n bytes32 hash = userOpHash.toEthSignedMessageHash();\n if (signer != hash.recover(userOp.signature)) return 1;\n return 0;\n }\n\n // This is REMOVED for testing purpose\n function validateOwnerSignatureSelector() public pure returns (bytes4) {\n // return this.validateOwnerSignature.selector;\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n function owner() public view returns (bytes memory) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n return abi.encodePacked(k1Storage.signer);\n }\n\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure returns (bool) {\n return (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (_hash.recover(_signature) ==\n LibFacetStorage.k1Storage().signer)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n}\n" + }, + "contracts/test/TestNFT.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\n\ncontract TestNFT is ERC721 {\n using Counters for Counters.Counter;\n Counters.Counter private currentTokenId;\n\n constructor() ERC721(\"TestNFT\", \"TNFT\") {}\n\n function mint(address recipient) public returns (uint256) {\n currentTokenId.increment();\n uint256 newItemId = currentTokenId.current();\n _safeMint(recipient, newItemId);\n return newItemId;\n }\n}\n" + }, + "contracts/test/TestToken.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract TestToken is ERC20 {\n constructor()\n // solhint-disable-next-line no-empty-blocks\n ERC20(\"TST\", \"TestToken\")\n {}\n\n function mint(address sender, uint256 amount) external {\n _mint(sender, amount);\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 999999 + }, + "evmVersion": "paris", + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/deployments/base/.chainId b/deployments/base/.chainId new file mode 100644 index 0000000..2a0c263 --- /dev/null +++ b/deployments/base/.chainId @@ -0,0 +1 @@ +8453 \ No newline at end of file diff --git a/deployments/base/AccountFacet.json b/deployments/base/AccountFacet.json new file mode 100644 index 0000000..7c66c16 --- /dev/null +++ b/deployments/base/AccountFacet.json @@ -0,0 +1,591 @@ +{ + "address": "0xFde53272dcd7938d16E031A6989753c321728332", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "AccountFacet__CallNotSuccessful", + "type": "error" + }, + { + "inputs": [], + "name": "AccountFacet__InitializationFailure", + "type": "error" + }, + { + "inputs": [], + "name": "AccountFacet__InvalidArrayLength", + "type": "error" + }, + { + "inputs": [], + "name": "AccountFacet__NonExistentVerificationFacet", + "type": "error" + }, + { + "inputs": [], + "name": "AccountFacet__RestrictionsFailure", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_initializationContractAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "InitializationFunctionReverted", + "type": "error" + }, + { + "inputs": [], + "name": "LibAppStorage__AccountMustBeUninitialized", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract IEntryPoint", + "name": "entryPoint", + "type": "address" + }, + { + "indexed": true, + "internalType": "bytes", + "name": "ownerPublicKey", + "type": "bytes" + } + ], + "name": "AccountInitialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "indexed": false, + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "DiamondCut", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "VerificationFailure", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "VerificationSuccess", + "type": "event" + }, + { + "inputs": [], + "name": "entryPoint", + "outputs": [ + { + "internalType": "contract IEntryPoint", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_dest", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_func", + "type": "bytes" + } + ], + "name": "execute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_dest", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "_value", + "type": "uint256[]" + }, + { + "internalType": "bytes[]", + "name": "_func", + "type": "bytes[]" + } + ], + "name": "executeBatch", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getNonce", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_verificationFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_anEntryPoint", + "type": "address" + }, + { + "internalType": "address", + "name": "_facetRegistry", + "type": "address" + }, + { + "internalType": "address", + "name": "_defaultFallBackHandler", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_ownerPublicKey", + "type": "bytes" + } + ], + "name": "initialize", + "outputs": [ + { + "internalType": "uint256", + "name": "initSuccess", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "initCode", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "callGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "verificationGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "preVerificationGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxFeePerGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPriorityFeePerGas", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "paymasterAndData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "internalType": "struct UserOperation", + "name": "userOp", + "type": "tuple" + }, + { + "internalType": "bytes32", + "name": "userOpHash", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "missingAccountFunds", + "type": "uint256" + } + ], + "name": "validateUserOp", + "outputs": [ + { + "internalType": "uint256", + "name": "validationData", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0xd88bac12a2ed524fb8df1d60091695ba5b016614fed2314698d9ee92a9a36b7d", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 1, + "gasUsed": "2369950", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x5b1ccfcb63b80e8ff751e8ae535013230982bddec5f7c6a73be1521edcbf070a", + "transactionHash": "0xd88bac12a2ed524fb8df1d60091695ba5b016614fed2314698d9ee92a9a36b7d", + "logs": [], + "blockNumber": 6847665, + "cumulativeGasUsed": "2433963", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 3, + "solcInputHash": "4356503edd8ae34e73cb6dd1c8e2fc8a", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AccountFacet__CallNotSuccessful\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AccountFacet__InitializationFailure\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AccountFacet__InvalidArrayLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AccountFacet__NonExistentVerificationFacet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AccountFacet__RestrictionsFailure\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_initializationContractAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"InitializationFunctionReverted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LibAppStorage__AccountMustBeUninitialized\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract IEntryPoint\",\"name\":\"entryPoint\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes\",\"name\":\"ownerPublicKey\",\"type\":\"bytes\"}],\"name\":\"AccountInitialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"DiamondCut\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"VerificationFailure\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"VerificationSuccess\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"entryPoint\",\"outputs\":[{\"internalType\":\"contract IEntryPoint\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_dest\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_func\",\"type\":\"bytes\"}],\"name\":\"execute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_dest\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"_value\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes[]\",\"name\":\"_func\",\"type\":\"bytes[]\"}],\"name\":\"executeBatch\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_verificationFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_anEntryPoint\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_facetRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_defaultFallBackHandler\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_ownerPublicKey\",\"type\":\"bytes\"}],\"name\":\"initialize\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"initSuccess\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"userOp\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"missingAccountFunds\",\"type\":\"uint256\"}],\"name\":\"validateUserOp\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"validationData\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"Account module contract that provides the account features and initialization of signer compatible with EIP-1271 & EIP-4337\",\"kind\":\"dev\",\"methods\":{\"execute(address,uint256,bytes)\":{\"details\":\"This method executes the calldata coming from the EntryPoint. Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\",\"params\":{\"_dest\":\"Address of destination where the call will be forwarded to\",\"_func\":\"Bytes of calldata to execute in the destination address\",\"_value\":\"Amount of native coin the owner is willing to send(e.g. ETH, BNB)\"}},\"executeBatch(address[],uint256[],bytes[])\":{\"details\":\"This method batch executes the calldata coming from the EntryPoint. Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\",\"params\":{\"_dest\":\"Array of addresses of destination where the call will be forwarded to\",\"_func\":\"Array of bytes of calldata to execute in the destination address\",\"_value\":\"Array of amount of native coin the owner is willing to send(e.g. ETH, BNB)\"}},\"initialize(address,address,address,address,bytes)\":{\"details\":\"This method can only be called during the initialization or signature migration. If the proxy contract was created without initialization, anyone can call initialize. Barz calls initialize in constructor in an atomic transaction during deployment\",\"params\":{\"_anEntryPoint\":\"Entrypoint contract defined in EIP-4337 handling the flow of UserOp\",\"_defaultFallBackHandler\":\"Middleware contract for default facets\",\"_facetRegistry\":\"Registry of Facets that hold all facet information\",\"_ownerPublicKey\":\"Bytes of owner public key\",\"_verificationFacet\":\"Facet contract handling the verificationi\"}}},\"title\":\"Account Facet\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"This constructor ensures that this contract can only be used as singleton for Proxy contracts\"},\"entryPoint()\":{\"notice\":\"Returns the address of EntryPoint contract registered to Barz account\"},\"execute(address,uint256,bytes)\":{\"notice\":\"Calls the destination with inputted calldata and value from EntryPoint\"},\"executeBatch(address[],uint256[],bytes[])\":{\"notice\":\"Batch calls the destination with inputted calldata and value from EntryPoint\"},\"getNonce()\":{\"notice\":\"Return the account nonce. This method returns the next sequential nonce. For a nonce of a specific key, use `entrypoint.getNonce(account, key)`\"},\"initialize(address,address,address,address,bytes)\":{\"notice\":\"Initializes the initial storage of the Barz contract.\"},\"validateUserOp((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256)\":{\"notice\":\"Validate user's signature and nonce. subclass doesn't need to override this method. Instead, it should override the specific internal validation methods.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/AccountFacet.sol\":\"AccountFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./math/Math.sol\\\";\\nimport \\\"./math/SignedMath.sol\\\";\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n uint256 length = Math.log10(value) + 1;\\n string memory buffer = new string(length);\\n uint256 ptr;\\n /// @solidity memory-safe-assembly\\n assembly {\\n ptr := add(buffer, add(32, length))\\n }\\n while (true) {\\n ptr--;\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\\n }\\n value /= 10;\\n if (value == 0) break;\\n }\\n return buffer;\\n }\\n }\\n\\n /**\\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\\n */\\n function toString(int256 value) internal pure returns (string memory) {\\n return string(abi.encodePacked(value < 0 ? \\\"-\\\" : \\\"\\\", toString(SignedMath.abs(value))));\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n return toHexString(value, Math.log256(value) + 1);\\n }\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n\\n /**\\n * @dev Returns true if the two strings are equal.\\n */\\n function equal(string memory a, string memory b) internal pure returns (bool) {\\n return keccak256(bytes(a)) == keccak256(bytes(b));\\n }\\n}\\n\",\"keccak256\":\"0x3088eb2868e8d13d89d16670b5f8612c4ab9ff8956272837d8e90106c59c14a0\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Strings.sol\\\";\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSA {\\n enum RecoverError {\\n NoError,\\n InvalidSignature,\\n InvalidSignatureLength,\\n InvalidSignatureS,\\n InvalidSignatureV // Deprecated in v4.8\\n }\\n\\n function _throwError(RecoverError error) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert(\\\"ECDSA: invalid signature\\\");\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert(\\\"ECDSA: invalid signature length\\\");\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert(\\\"ECDSA: invalid signature 's' value\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature` or error string. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n *\\n * Documentation for signature generation:\\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n return tryRecover(hash, v, r, s);\\n } else {\\n return (address(0), RecoverError.InvalidSignatureLength);\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature`. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, signature);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\\n uint8 v = uint8((uint256(vs) >> 255) + 27);\\n return tryRecover(hash, v, r, s);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n *\\n * _Available since v4.2._\\n */\\n function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\\n // the valid range for s in (301): 0 < s < secp256k1n \\u00f7 2 + 1, and for v in (302): v \\u2208 {27, 28}. Most\\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\\n //\\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\\n // these malleable signatures as well.\\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n return (address(0), RecoverError.InvalidSignatureS);\\n }\\n\\n // If the signature is valid (and not malleable), return the signer address\\n address signer = ecrecover(hash, v, r, s);\\n if (signer == address(0)) {\\n return (address(0), RecoverError.InvalidSignature);\\n }\\n\\n return (signer, RecoverError.NoError);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore(0x00, \\\"\\\\x19Ethereum Signed Message:\\\\n32\\\")\\n mstore(0x1c, hash)\\n message := keccak256(0x00, 0x3c)\\n }\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from `s`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n\\\", Strings.toString(s.length), s));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Typed Data, created from a\\n * `domainSeparator` and a `structHash`. This produces hash corresponding\\n * to the one signed with the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n * JSON-RPC method as part of EIP-712.\\n *\\n * See {recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n let ptr := mload(0x40)\\n mstore(ptr, \\\"\\\\x19\\\\x01\\\")\\n mstore(add(ptr, 0x02), domainSeparator)\\n mstore(add(ptr, 0x22), structHash)\\n data := keccak256(ptr, 0x42)\\n }\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Data with intended validator, created from a\\n * `validator` and `data` according to the version 0 of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x00\\\", validator, data));\\n }\\n}\\n\",\"keccak256\":\"0x809bc3edb4bcbef8263fa616c1b60ee0004b50a8a1bfa164d8f57fd31f520c58\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n enum Rounding {\\n Down, // Toward negative infinity\\n Up, // Toward infinity\\n Zero // Toward zero\\n }\\n\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow.\\n return (a & b) + (a ^ b) / 2;\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a == 0 ? 0 : (a - 1) / b + 1;\\n }\\n\\n /**\\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\\n * with further edits by Uniswap Labs also under MIT license.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\\n unchecked {\\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2^256 + prod0.\\n uint256 prod0; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division.\\n if (prod1 == 0) {\\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\\n // The surrounding unchecked block does not change this fact.\\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\\n return prod0 / denominator;\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n require(denominator > prod1, \\\"Math: mulDiv overflow\\\");\\n\\n ///////////////////////////////////////////////\\n // 512 by 256 division.\\n ///////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0].\\n uint256 remainder;\\n assembly {\\n // Compute remainder using mulmod.\\n remainder := mulmod(x, y, denominator)\\n\\n // Subtract 256 bit number from 512 bit number.\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\\n // See https://cs.stackexchange.com/q/138556/92363.\\n\\n // Does not overflow because the denominator cannot be zero at this stage in the function.\\n uint256 twos = denominator & (~denominator + 1);\\n assembly {\\n // Divide denominator by twos.\\n denominator := div(denominator, twos)\\n\\n // Divide [prod1 prod0] by twos.\\n prod0 := div(prod0, twos)\\n\\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\\n twos := add(div(sub(0, twos), twos), 1)\\n }\\n\\n // Shift in bits from prod1 into prod0.\\n prod0 |= prod1 * twos;\\n\\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\\n // four bits. That is, denominator * inv = 1 mod 2^4.\\n uint256 inverse = (3 * denominator) ^ 2;\\n\\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\\n // in modular arithmetic, doubling the correct bits in each step.\\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\\n\\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inverse;\\n return result;\\n }\\n }\\n\\n /**\\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\\n uint256 result = mulDiv(x, y, denominator);\\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\\n result += 1;\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\\n *\\n * Inspired by Henry S. Warren, Jr.'s \\\"Hacker's Delight\\\" (Chapter 11).\\n */\\n function sqrt(uint256 a) internal pure returns (uint256) {\\n if (a == 0) {\\n return 0;\\n }\\n\\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\\n //\\n // We know that the \\\"msb\\\" (most significant bit) of our target number `a` is a power of 2 such that we have\\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\\n //\\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\\n // \\u2192 `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\\n // \\u2192 `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\\n //\\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\\n uint256 result = 1 << (log2(a) >> 1);\\n\\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\\n // into the expected uint128 result.\\n unchecked {\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n return min(result, a / result);\\n }\\n }\\n\\n /**\\n * @notice Calculates sqrt(a), following the selected rounding direction.\\n */\\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = sqrt(a);\\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 2, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 128;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 64;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 32;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 16;\\n }\\n if (value >> 8 > 0) {\\n value >>= 8;\\n result += 8;\\n }\\n if (value >> 4 > 0) {\\n value >>= 4;\\n result += 4;\\n }\\n if (value >> 2 > 0) {\\n value >>= 2;\\n result += 2;\\n }\\n if (value >> 1 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log2(value);\\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 10, rounded down, of a positive value.\\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 + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 256, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n *\\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\\n */\\n function log256(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 16;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 8;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 4;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 2;\\n }\\n if (value >> 8 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log256(value);\\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe4455ac1eb7fc497bb7402579e7b4d64d928b846fce7d2b6fde06d366f21c2b3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\\n * checks.\\n *\\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\\n * easily result in undesired exploitation or bugs, since developers usually\\n * assume that overflows raise errors. `SafeCast` restores this intuition by\\n * reverting the transaction when such an operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n *\\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\\n * all math on `uint256` and `int256` and then downcasting.\\n */\\nlibrary SafeCast {\\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 * _Available since v4.7._\\n */\\n function toUint248(uint256 value) internal pure returns (uint248) {\\n require(value <= type(uint248).max, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint240(uint256 value) internal pure returns (uint240) {\\n require(value <= type(uint240).max, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint232(uint256 value) internal pure returns (uint232) {\\n require(value <= type(uint232).max, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint224(uint256 value) internal pure returns (uint224) {\\n require(value <= type(uint224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint216(uint256 value) internal pure returns (uint216) {\\n require(value <= type(uint216).max, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint208(uint256 value) internal pure returns (uint208) {\\n require(value <= type(uint208).max, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint200(uint256 value) internal pure returns (uint200) {\\n require(value <= type(uint200).max, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint192(uint256 value) internal pure returns (uint192) {\\n require(value <= type(uint192).max, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint184(uint256 value) internal pure returns (uint184) {\\n require(value <= type(uint184).max, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint176(uint256 value) internal pure returns (uint176) {\\n require(value <= type(uint176).max, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint168(uint256 value) internal pure returns (uint168) {\\n require(value <= type(uint168).max, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint160(uint256 value) internal pure returns (uint160) {\\n require(value <= type(uint160).max, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint152(uint256 value) internal pure returns (uint152) {\\n require(value <= type(uint152).max, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint144(uint256 value) internal pure returns (uint144) {\\n require(value <= type(uint144).max, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint136(uint256 value) internal pure returns (uint136) {\\n require(value <= type(uint136).max, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint128(uint256 value) internal pure returns (uint128) {\\n require(value <= type(uint128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint120(uint256 value) internal pure returns (uint120) {\\n require(value <= type(uint120).max, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint112(uint256 value) internal pure returns (uint112) {\\n require(value <= type(uint112).max, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint104(uint256 value) internal pure returns (uint104) {\\n require(value <= type(uint104).max, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint96(uint256 value) internal pure returns (uint96) {\\n require(value <= type(uint96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint88(uint256 value) internal pure returns (uint88) {\\n require(value <= type(uint88).max, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint80(uint256 value) internal pure returns (uint80) {\\n require(value <= type(uint80).max, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint72(uint256 value) internal pure returns (uint72) {\\n require(value <= type(uint72).max, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint64(uint256 value) internal pure returns (uint64) {\\n require(value <= type(uint64).max, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint56(uint256 value) internal pure returns (uint56) {\\n require(value <= type(uint56).max, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint48(uint256 value) internal pure returns (uint48) {\\n require(value <= type(uint48).max, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint40(uint256 value) internal pure returns (uint40) {\\n require(value <= type(uint40).max, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint32(uint256 value) internal pure returns (uint32) {\\n require(value <= type(uint32).max, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint24(uint256 value) internal pure returns (uint24) {\\n require(value <= type(uint24).max, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint16(uint256 value) internal pure returns (uint16) {\\n require(value <= type(uint16).max, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint8(uint256 value) internal pure returns (uint8) {\\n require(value <= type(uint8).max, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\n */\\n function toUint256(int256 value) internal pure returns (uint256) {\\n require(value >= 0, \\\"SafeCast: value must be positive\\\");\\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 * _Available since v4.7._\\n */\\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\\n downcasted = int248(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\\n downcasted = int240(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\\n downcasted = int232(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\\n downcasted = int224(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\\n downcasted = int216(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\\n downcasted = int208(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\\n downcasted = int200(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\\n downcasted = int192(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\\n downcasted = int184(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\\n downcasted = int176(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\\n downcasted = int168(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\\n downcasted = int160(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\\n downcasted = int152(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\\n downcasted = int144(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\\n downcasted = int136(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\\n downcasted = int128(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\\n downcasted = int120(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\\n downcasted = int112(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\\n downcasted = int104(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\\n downcasted = int96(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\\n downcasted = int88(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\\n downcasted = int80(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\\n downcasted = int72(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\\n downcasted = int64(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\\n downcasted = int56(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\\n downcasted = int48(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\\n downcasted = int40(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\\n downcasted = int32(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\\n downcasted = int24(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\\n downcasted = int16(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\\n downcasted = int8(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\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 require(value <= uint256(type(int256).max), \\\"SafeCast: value doesn't fit in an int256\\\");\\n return int256(value);\\n }\\n}\\n\",\"keccak256\":\"0x52a8cfb0f5239d11b457dcdd1b326992ef672714ca8da71a157255bddd13f3ad\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SignedMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard signed math utilities missing in the Solidity language.\\n */\\nlibrary SignedMath {\\n /**\\n * @dev Returns the largest of two signed numbers.\\n */\\n function max(int256 a, int256 b) internal pure returns (int256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two signed numbers.\\n */\\n function min(int256 a, int256 b) internal pure returns (int256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two signed numbers without overflow.\\n * The result is rounded towards zero.\\n */\\n function average(int256 a, int256 b) internal pure returns (int256) {\\n // Formula from the book \\\"Hacker's Delight\\\"\\n int256 x = (a & b) + ((a ^ b) >> 1);\\n return x + (int256(uint256(x) >> 255) & (a ^ b));\\n }\\n\\n /**\\n * @dev Returns the absolute unsigned value of a signed value.\\n */\\n function abs(int256 n) internal pure returns (uint256) {\\n unchecked {\\n // must be unchecked in order to support `n = type(int256).min`\\n return uint256(n >= 0 ? n : -n);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf92515413956f529d95977adc9b0567d583c6203fc31ab1c23824c35187e3ddc\",\"license\":\"MIT\"},\"contracts/aa-4337/core/BaseAccount.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-empty-blocks */\\n\\nimport \\\"../interfaces/IAccount.sol\\\";\\nimport \\\"../interfaces/IEntryPoint.sol\\\";\\nimport \\\"./Helpers.sol\\\";\\n\\n/**\\n * Basic account implementation.\\n * this contract provides the basic logic for implementing the IAccount interface - validateUserOp\\n * specific account implementation should inherit it and provide the account-specific logic\\n */\\nabstract contract BaseAccount is IAccount {\\n using UserOperationLib for UserOperation;\\n\\n //return value in case of signature failure, with no time-range.\\n // equivalent to _packValidationData(true,0,0);\\n uint256 internal constant SIG_VALIDATION_FAILED = 1;\\n\\n /**\\n * Return the account nonce.\\n * This method returns the next sequential nonce.\\n * For a nonce of a specific key, use `entrypoint.getNonce(account, key)`\\n */\\n function getNonce() public view virtual returns (uint256) {\\n return entryPoint().getNonce(address(this), 0);\\n }\\n\\n /**\\n * return the entryPoint used by this account.\\n * subclass should return the current entryPoint used by this account.\\n */\\n function entryPoint() public view virtual returns (IEntryPoint);\\n\\n /**\\n * Validate user's signature and nonce.\\n * subclass doesn't need to override this method. Instead, it should override the specific internal validation methods.\\n */\\n function validateUserOp(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n uint256 missingAccountFunds\\n ) external virtual override returns (uint256 validationData) {\\n _requireFromEntryPoint();\\n validationData = _validateSignature(userOp, userOpHash);\\n _validateNonce(userOp.nonce);\\n _payPrefund(missingAccountFunds);\\n }\\n\\n /**\\n * ensure the request comes from the known entrypoint.\\n */\\n function _requireFromEntryPoint() internal view virtual {\\n require(\\n msg.sender == address(entryPoint()),\\n \\\"account: not from EntryPoint\\\"\\n );\\n }\\n\\n /**\\n * validate the signature is valid for this message.\\n * @param userOp validate the userOp.signature field\\n * @param userOpHash convenient field: the hash of the request, to check the signature against\\n * (also hashes the entrypoint and chain id)\\n * @return validationData signature and time-range of this operation\\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\\n * otherwise, an address of an \\\"authorizer\\\" contract.\\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \\\"indefinite\\\"\\n * <6-byte> validAfter - first timestamp this operation is valid\\n * If the account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\\n */\\n function _validateSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) internal virtual returns (uint256 validationData);\\n\\n /**\\n * Validate the nonce of the UserOperation.\\n * This method may validate the nonce requirement of this account.\\n * e.g.\\n * To limit the nonce to use sequenced UserOps only (no \\\"out of order\\\" UserOps):\\n * `require(nonce < type(uint64).max)`\\n * For a hypothetical account that *requires* the nonce to be out-of-order:\\n * `require(nonce & type(uint64).max == 0)`\\n *\\n * The actual nonce uniqueness is managed by the EntryPoint, and thus no other\\n * action is needed by the account itself.\\n *\\n * @param nonce to validate\\n *\\n * solhint-disable-next-line no-empty-blocks\\n */\\n function _validateNonce(uint256 nonce) internal view virtual {}\\n\\n /**\\n * sends to the entrypoint (msg.sender) the missing funds for this transaction.\\n * subclass MAY override this method for better funds management\\n * (e.g. send to the entryPoint more than the minimum required, so that in future transactions\\n * it will not be required to send again)\\n * @param missingAccountFunds the minimum value this method should send the entrypoint.\\n * this value MAY be zero, in case there is enough deposit, or the userOp has a paymaster.\\n */\\n function _payPrefund(uint256 missingAccountFunds) internal virtual {\\n if (missingAccountFunds != 0) {\\n (bool success, ) = payable(msg.sender).call{\\n value: missingAccountFunds,\\n gas: type(uint256).max\\n }(\\\"\\\");\\n (success);\\n //ignore failure (its EntryPoint's job to verify, not account.)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa0dcc386b0f04711db3e394fb50e55a3b3b1a4d19fac1f10895844e1aa4e3d5c\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/core/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable no-inline-assembly */\\n\\n/**\\n * returned data from validateUserOp.\\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\\n * @param aggregator - address(0) - the account validated the signature by itself.\\n * address(1) - the account failed to validate the signature.\\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\\n * @param validAfter - this UserOp is valid only after this timestamp.\\n * @param validaUntil - this UserOp is valid only up to this timestamp.\\n */\\nstruct ValidationData {\\n address aggregator;\\n uint48 validAfter;\\n uint48 validUntil;\\n}\\n\\n//extract sigFailed, validAfter, validUntil.\\n// also convert zero validUntil to type(uint48).max\\nfunction _parseValidationData(\\n uint validationData\\n) pure returns (ValidationData memory data) {\\n address aggregator = address(uint160(validationData));\\n uint48 validUntil = uint48(validationData >> 160);\\n if (validUntil == 0) {\\n validUntil = type(uint48).max;\\n }\\n uint48 validAfter = uint48(validationData >> (48 + 160));\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n// intersect account and paymaster ranges.\\nfunction _intersectTimeRange(\\n uint256 validationData,\\n uint256 paymasterValidationData\\n) pure returns (ValidationData memory) {\\n ValidationData memory accountValidationData = _parseValidationData(\\n validationData\\n );\\n ValidationData memory pmValidationData = _parseValidationData(\\n paymasterValidationData\\n );\\n address aggregator = accountValidationData.aggregator;\\n if (aggregator == address(0)) {\\n aggregator = pmValidationData.aggregator;\\n }\\n uint48 validAfter = accountValidationData.validAfter;\\n uint48 validUntil = accountValidationData.validUntil;\\n uint48 pmValidAfter = pmValidationData.validAfter;\\n uint48 pmValidUntil = pmValidationData.validUntil;\\n\\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp\\n * @param data - the ValidationData to pack\\n */\\nfunction _packValidationData(\\n ValidationData memory data\\n) pure returns (uint256) {\\n return\\n uint160(data.aggregator) |\\n (uint256(data.validUntil) << 160) |\\n (uint256(data.validAfter) << (160 + 48));\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp, when not using an aggregator\\n * @param sigFailed - true for signature failure, false for success\\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\\n * @param validAfter first timestamp this UserOperation is valid\\n */\\nfunction _packValidationData(\\n bool sigFailed,\\n uint48 validUntil,\\n uint48 validAfter\\n) pure returns (uint256) {\\n return\\n (sigFailed ? 1 : 0) |\\n (uint256(validUntil) << 160) |\\n (uint256(validAfter) << (160 + 48));\\n}\\n\\n/**\\n * keccak function over calldata.\\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\\n */\\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\\n assembly {\\n let mem := mload(0x40)\\n let len := data.length\\n calldatacopy(mem, data.offset, len)\\n ret := keccak256(mem, len)\\n }\\n}\\n\",\"keccak256\":\"0xa79f06cd158ecb8c0da95493a2f348933b8627a63e228b99738bff3aa107942d\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAccount.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\ninterface IAccount {\\n /**\\n * Validate user's signature and nonce\\n * the entryPoint will make the call to the recipient only if this validation call returns successfully.\\n * signature failure should be reported by returning SIG_VALIDATION_FAILED (1).\\n * This allows making a \\\"simulation call\\\" without a valid signature\\n * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure.\\n *\\n * @dev Must validate caller is the entryPoint.\\n * Must validate the signature and nonce\\n * @param userOp the operation that is about to be executed.\\n * @param userOpHash hash of the user's request data. can be used as the basis for signature.\\n * @param missingAccountFunds missing funds on the account's deposit in the entrypoint.\\n * This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call.\\n * The excess is left as a deposit in the entrypoint, for future calls.\\n * can be withdrawn anytime using \\\"entryPoint.withdrawTo()\\\"\\n * In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero.\\n * @return validationData packaged ValidationData structure. use `_packValidationData` and `_unpackValidationData` to encode and decode\\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\\n * otherwise, an address of an \\\"authorizer\\\" contract.\\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \\\"indefinite\\\"\\n * <6-byte> validAfter - first timestamp this operation is valid\\n * If an account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\\n */\\n function validateUserOp(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n uint256 missingAccountFunds\\n ) external returns (uint256 validationData);\\n}\\n\",\"keccak256\":\"0xcbc4b0973cf954c5895b7796335f651fbfcfb55f67dfa789a3d354f8e23c4f2b\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAggregator.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\n/**\\n * Aggregated Signatures validator.\\n */\\ninterface IAggregator {\\n /**\\n * validate aggregated signature.\\n * revert if the aggregated signature does not match the given list of operations.\\n */\\n function validateSignatures(\\n UserOperation[] calldata userOps,\\n bytes calldata signature\\n ) external view;\\n\\n /**\\n * validate signature of a single userOp\\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\\n * @param userOp the userOperation received from the user.\\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\\n * (usually empty, unless account and aggregator support some kind of \\\"multisig\\\"\\n */\\n function validateUserOpSignature(\\n UserOperation calldata userOp\\n ) external view returns (bytes memory sigForUserOp);\\n\\n /**\\n * aggregate multiple signatures into a single value.\\n * This method is called off-chain to calculate the signature to pass with handleOps()\\n * bundler MAY use optimized custom code perform this aggregation\\n * @param userOps array of UserOperations to collect the signatures from.\\n * @return aggregatedSignature the aggregated signature\\n */\\n function aggregateSignatures(\\n UserOperation[] calldata userOps\\n ) external view returns (bytes memory aggregatedSignature);\\n}\\n\",\"keccak256\":\"0xdfdcd80568f037716674619b31be630fcd8316262f05a815b41d1e81782c966a\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IEntryPoint.sol\":{\"content\":\"/**\\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\\n ** Only one instance required on each chain.\\n **/\\n// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-inline-assembly */\\n/* solhint-disable reason-string */\\n\\nimport \\\"./UserOperation.sol\\\";\\nimport \\\"./IStakeManager.sol\\\";\\nimport \\\"./IAggregator.sol\\\";\\nimport \\\"./INonceManager.sol\\\";\\n\\ninterface IEntryPoint is IStakeManager, INonceManager {\\n /***\\n * An event emitted after each successful request\\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\\n * @param sender - the account that generates this request.\\n * @param paymaster - if non-null, the paymaster that pays for this request.\\n * @param nonce - the nonce value from the request.\\n * @param success - true if the sender transaction succeeded, false if reverted.\\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\\n */\\n event UserOperationEvent(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address indexed paymaster,\\n uint256 nonce,\\n bool success,\\n uint256 actualGasCost,\\n uint256 actualGasUsed\\n );\\n\\n /**\\n * account \\\"sender\\\" was deployed.\\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\\n * @param sender the account that is deployed\\n * @param factory the factory used to deploy this account (in the initCode)\\n * @param paymaster the paymaster used by this UserOp\\n */\\n event AccountDeployed(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address factory,\\n address paymaster\\n );\\n\\n /**\\n * An event emitted if the UserOperation \\\"callData\\\" reverted with non-zero length\\n * @param userOpHash the request unique identifier.\\n * @param sender the sender of this request\\n * @param nonce the nonce used in the request\\n * @param revertReason - the return bytes from the (reverted) call to \\\"callData\\\".\\n */\\n event UserOperationRevertReason(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n uint256 nonce,\\n bytes revertReason\\n );\\n\\n /**\\n * an event emitted by handleOps(), before starting the execution loop.\\n * any event emitted before this event, is part of the validation.\\n */\\n event BeforeExecution();\\n\\n /**\\n * signature aggregator used by the following UserOperationEvents within this bundle.\\n */\\n event SignatureAggregatorChanged(address indexed aggregator);\\n\\n /**\\n * a custom revert error of handleOps, to identify the offending op.\\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\\n * @param reason - revert reason\\n * The string starts with a unique code \\\"AAmn\\\", where \\\"m\\\" is \\\"1\\\" for factory, \\\"2\\\" for account and \\\"3\\\" for paymaster issues,\\n * so a failure can be attributed to the correct entity.\\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\\n */\\n error FailedOp(uint256 opIndex, string reason);\\n\\n /**\\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\\n */\\n error SignatureValidationFailed(address aggregator);\\n\\n /**\\n * Successful result from simulateValidation.\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n */\\n error ValidationResult(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo\\n );\\n\\n /**\\n * Successful result from simulateValidation, if the account returns a signature aggregator\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\\n * bundler MUST use it to verify the signature, or reject the UserOperation\\n */\\n error ValidationResultWithAggregation(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo,\\n AggregatorStakeInfo aggregatorInfo\\n );\\n\\n /**\\n * return value of getSenderAddress\\n */\\n error SenderAddressResult(address sender);\\n\\n /**\\n * return value of simulateHandleOp\\n */\\n error ExecutionResult(\\n uint256 preOpGas,\\n uint256 paid,\\n uint48 validAfter,\\n uint48 validUntil,\\n bool targetSuccess,\\n bytes targetResult\\n );\\n\\n //UserOps handled, per aggregator\\n struct UserOpsPerAggregator {\\n UserOperation[] userOps;\\n // aggregator address\\n IAggregator aggregator;\\n // aggregated signature\\n bytes signature;\\n }\\n\\n /**\\n * Execute a batch of UserOperation.\\n * no signature aggregator is used.\\n * if any account requires an aggregator (that is, it returned an aggregator when\\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\\n * @param ops the operations to execute\\n * @param beneficiary the address to receive the fees\\n */\\n function handleOps(\\n UserOperation[] calldata ops,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * Execute a batch of UserOperation with Aggregators\\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\\n * @param beneficiary the address to receive the fees\\n */\\n function handleAggregatedOps(\\n UserOpsPerAggregator[] calldata opsPerAggregator,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * generate a request Id - unique identifier for this request.\\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\\n */\\n function getUserOpHash(\\n UserOperation calldata userOp\\n ) external view returns (bytes32);\\n\\n /**\\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\\n * @param userOp the user operation to validate.\\n */\\n function simulateValidation(UserOperation calldata userOp) external;\\n\\n /**\\n * gas and return values during simulation\\n * @param preOpGas the gas used for validation (including preValidationGas)\\n * @param prefund the required prefund for this operation\\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\\n */\\n struct ReturnInfo {\\n uint256 preOpGas;\\n uint256 prefund;\\n bool sigFailed;\\n uint48 validAfter;\\n uint48 validUntil;\\n bytes paymasterContext;\\n }\\n\\n /**\\n * returned aggregated signature info.\\n * the aggregator returned by the account, and its current stake.\\n */\\n struct AggregatorStakeInfo {\\n address aggregator;\\n StakeInfo stakeInfo;\\n }\\n\\n /**\\n * Get counterfactual sender address.\\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\\n * this method always revert, and returns the address in SenderAddressResult error\\n * @param initCode the constructor code to be passed into the UserOperation.\\n */\\n function getSenderAddress(bytes memory initCode) external;\\n\\n /**\\n * simulate full execution of a UserOperation (including both validation and target execution)\\n * this method will always revert with \\\"ExecutionResult\\\".\\n * it performs full validation of the UserOperation, but ignores signature error.\\n * an optional target address is called after the userop succeeds, and its value is returned\\n * (before the entire call is reverted)\\n * Note that in order to collect the the success/failure of the target call, it must be executed\\n * with trace enabled to track the emitted events.\\n * @param op the UserOperation to simulate\\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\\n * are set to the return from that call.\\n * @param targetCallData callData to pass to target address\\n */\\n function simulateHandleOp(\\n UserOperation calldata op,\\n address target,\\n bytes calldata targetCallData\\n ) external;\\n}\\n\",\"keccak256\":\"0x9ccb1b188eda8bbf5f6c2d01bd83c3d8b2b04fcf745283051d31fe96d1d8e40f\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/INonceManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\ninterface INonceManager {\\n /**\\n * Return the next nonce for this sender.\\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\\n * But UserOp with different keys can come with arbitrary order.\\n *\\n * @param sender the account address\\n * @param key the high 192 bit of the nonce\\n * @return nonce a full nonce to pass for next UserOp with this sender.\\n */\\n function getNonce(\\n address sender,\\n uint192 key\\n ) external view returns (uint256 nonce);\\n\\n /**\\n * Manually increment the nonce of the sender.\\n * This method is exposed just for completeness..\\n * Account does NOT need to call it, neither during validation, nor elsewhere,\\n * as the EntryPoint will update the nonce regardless.\\n * Possible use-case is call it with various keys to \\\"initialize\\\" their nonces to one, so that future\\n * UserOperations will not pay extra for the first transaction with a given key.\\n */\\n function incrementNonce(uint192 key) external;\\n}\\n\",\"keccak256\":\"0xce478ad0fa0d18a3b785ac854623029e7ab463d05873dfaa365abfa1bf100912\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IStakeManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8.12;\\n\\n/**\\n * manage deposits and stakes.\\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\\n * stake is value locked for at least \\\"unstakeDelay\\\" by the staked entity.\\n */\\ninterface IStakeManager {\\n event Deposited(address indexed account, uint256 totalDeposit);\\n\\n event Withdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /// Emitted when stake or unstake delay are modified\\n event StakeLocked(\\n address indexed account,\\n uint256 totalStaked,\\n uint256 unstakeDelaySec\\n );\\n\\n /// Emitted once a stake is scheduled for withdrawal\\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\\n\\n event StakeWithdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /**\\n * @param deposit the entity's deposit\\n * @param staked true if this entity is staked.\\n * @param stake actual amount of ether staked for this entity.\\n * @param unstakeDelaySec minimum delay to withdraw the stake.\\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\\n * and the rest fit into a 2nd cell.\\n * 112 bit allows for 10^15 eth\\n * 48 bit for full timestamp\\n * 32 bit allows 150 years for unstake delay\\n */\\n struct DepositInfo {\\n uint112 deposit;\\n bool staked;\\n uint112 stake;\\n uint32 unstakeDelaySec;\\n uint48 withdrawTime;\\n }\\n\\n //API struct used by getStakeInfo and simulateValidation\\n struct StakeInfo {\\n uint256 stake;\\n uint256 unstakeDelaySec;\\n }\\n\\n /// @return info - full deposit information of given account\\n function getDepositInfo(\\n address account\\n ) external view returns (DepositInfo memory info);\\n\\n /// @return the deposit (for gas payment) of the account\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * add to the deposit of the given account\\n */\\n function depositTo(address account) external payable;\\n\\n /**\\n * add to the account's stake - amount and delay\\n * any pending unstake is first cancelled.\\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\\n */\\n function addStake(uint32 _unstakeDelaySec) external payable;\\n\\n /**\\n * attempt to unlock the stake.\\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\\n */\\n function unlockStake() external;\\n\\n /**\\n * withdraw from the (unlocked) stake.\\n * must first call unlockStake and wait for the unstakeDelay to pass\\n * @param withdrawAddress the address to send withdrawn value.\\n */\\n function withdrawStake(address payable withdrawAddress) external;\\n\\n /**\\n * withdraw from the deposit.\\n * @param withdrawAddress the address to send withdrawn value.\\n * @param withdrawAmount the amount to withdraw.\\n */\\n function withdrawTo(\\n address payable withdrawAddress,\\n uint256 withdrawAmount\\n ) external;\\n}\\n\",\"keccak256\":\"0xadcea606c9b7aafe6645441f2154a60f271330b0eee5292a632aa71c1672d546\",\"license\":\"GPL-3.0-only\"},\"contracts/aa-4337/interfaces/UserOperation.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable no-inline-assembly */\\n\\nimport {calldataKeccak} from \\\"../core/Helpers.sol\\\";\\n\\n/**\\n * User Operation struct\\n * @param sender the sender account of this request.\\n * @param nonce unique value the sender uses to verify it is not a replay.\\n * @param initCode if set, the account contract will be created by this constructor/\\n * @param callData the method call to execute on this account.\\n * @param callGasLimit the gas limit passed to the callData method call.\\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\\n * @param maxFeePerGas same as EIP-1559 gas parameter.\\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\\n */\\nstruct UserOperation {\\n address sender;\\n uint256 nonce;\\n bytes initCode;\\n bytes callData;\\n uint256 callGasLimit;\\n uint256 verificationGasLimit;\\n uint256 preVerificationGas;\\n uint256 maxFeePerGas;\\n uint256 maxPriorityFeePerGas;\\n bytes paymasterAndData;\\n bytes signature;\\n}\\n\\n/**\\n * Utility functions helpful when working with UserOperation structs.\\n */\\nlibrary UserOperationLib {\\n function getSender(\\n UserOperation calldata userOp\\n ) internal pure returns (address) {\\n address data;\\n //read sender from userOp, which is first userOp member (saves 800 gas...)\\n assembly {\\n data := calldataload(userOp)\\n }\\n return address(uint160(data));\\n }\\n\\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\\n // pay above what he signed for.\\n function gasPrice(\\n UserOperation calldata userOp\\n ) internal view returns (uint256) {\\n unchecked {\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n if (maxFeePerGas == maxPriorityFeePerGas) {\\n //legacy mode (for networks that don't support basefee opcode)\\n return maxFeePerGas;\\n }\\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\\n }\\n }\\n\\n function pack(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes memory ret) {\\n address sender = getSender(userOp);\\n uint256 nonce = userOp.nonce;\\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\\n bytes32 hashCallData = calldataKeccak(userOp.callData);\\n uint256 callGasLimit = userOp.callGasLimit;\\n uint256 verificationGasLimit = userOp.verificationGasLimit;\\n uint256 preVerificationGas = userOp.preVerificationGas;\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\\n\\n return\\n abi.encode(\\n sender,\\n nonce,\\n hashInitCode,\\n hashCallData,\\n callGasLimit,\\n verificationGasLimit,\\n preVerificationGas,\\n maxFeePerGas,\\n maxPriorityFeePerGas,\\n hashPaymasterAndData\\n );\\n }\\n\\n function hash(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes32) {\\n return keccak256(pack(userOp));\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n}\\n\",\"keccak256\":\"0x2429f5cc546bdee08c7e63858d0dda8491eaa3ab5194df884dc948c1154d2834\",\"license\":\"GPL-3.0\"},\"contracts/facets/AccountFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {ECDSA} from \\\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\\\";\\nimport {UserOperation} from \\\"../aa-4337/interfaces/UserOperation.sol\\\";\\nimport {IEntryPoint} from \\\"../aa-4337/interfaces/IEntryPoint.sol\\\";\\nimport {BaseAccount} from \\\"../aa-4337/core/BaseAccount.sol\\\";\\nimport {LibAppStorage, BarzStorage} from \\\"../libraries/LibAppStorage.sol\\\";\\nimport {LibDiamond} from \\\"../libraries/LibDiamond.sol\\\";\\nimport {LibLoupe} from \\\"../libraries/LibLoupe.sol\\\";\\nimport {IFacetRegistry} from \\\"../infrastructure/interfaces/IFacetRegistry.sol\\\";\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\nimport {IVerificationFacet} from \\\"./interfaces/IVerificationFacet.sol\\\";\\nimport {IERC1271} from \\\"../interfaces/ERC/IERC1271.sol\\\";\\nimport {IAccountFacet} from \\\"./interfaces/IAccountFacet.sol\\\";\\n\\n/**\\n * @title Account Facet\\n * @dev Account module contract that provides the account features and initialization of signer\\n * compatible with EIP-1271 & EIP-4337\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract AccountFacet is IAccountFacet, BarzStorage, BaseAccount {\\n using ECDSA for bytes32;\\n\\n /**\\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\\n */\\n constructor() {\\n LibAppStorage.enforceAccountInitialize();\\n }\\n\\n /**\\n * @notice Returns the address of EntryPoint contract registered to Barz account\\n */\\n function entryPoint() public view override returns (IEntryPoint) {\\n return s.entryPoint;\\n }\\n\\n /**\\n * @notice Initializes the initial storage of the Barz contract.\\n * @dev This method can only be called during the initialization or signature migration.\\n * If the proxy contract was created without initialization, anyone can call initialize.\\n * Barz calls initialize in constructor in an atomic transaction during deployment\\n * @param _verificationFacet Facet contract handling the verificationi\\n * @param _anEntryPoint Entrypoint contract defined in EIP-4337 handling the flow of UserOp\\n * @param _facetRegistry Registry of Facets that hold all facet information\\n * @param _defaultFallBackHandler Middleware contract for default facets\\n * @param _ownerPublicKey Bytes of owner public key\\n */\\n function initialize(\\n address _verificationFacet,\\n address _anEntryPoint,\\n address _facetRegistry,\\n address _defaultFallBackHandler,\\n bytes calldata _ownerPublicKey\\n ) public override returns (uint256 initSuccess) {\\n LibAppStorage.enforceAccountInitialize();\\n s.entryPoint = IEntryPoint(_anEntryPoint);\\n s.facetRegistry = IFacetRegistry(_facetRegistry);\\n LibDiamond.diamondStorage().defaultFallbackHandler = IDiamondLoupe(\\n _defaultFallBackHandler\\n );\\n\\n _cutDiamondAccountFacet(_verificationFacet);\\n\\n bytes memory initCall = abi.encodeWithSignature(\\n \\\"initializeSigner(bytes)\\\",\\n _ownerPublicKey\\n );\\n // Every Verification Facet should comply with initializeSigner(bytes)\\n // to be compatible with the Barz contract(for initialization)\\n (bool success, bytes memory result) = _verificationFacet.delegatecall(\\n initCall\\n );\\n if (!success || uint256(bytes32(result)) != 1) {\\n revert AccountFacet__InitializationFailure();\\n }\\n\\n initSuccess = 1;\\n emit AccountInitialized(s.entryPoint, _ownerPublicKey);\\n }\\n\\n function _cutDiamondAccountFacet(address _verificationFacet) internal {\\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](1);\\n\\n bytes4 ownerVerificationFuncSelector = IVerificationFacet(\\n _verificationFacet\\n ).validateOwnerSignatureSelector();\\n\\n bytes4[] memory verificationFunctionSelectors = new bytes4[](3);\\n verificationFunctionSelectors[0] = IERC1271.isValidSignature.selector;\\n verificationFunctionSelectors[1] = ownerVerificationFuncSelector;\\n verificationFunctionSelectors[2] = IVerificationFacet.owner.selector;\\n cut[0] = IDiamondCut.FacetCut({\\n facetAddress: _verificationFacet,\\n action: IDiamondCut.FacetCutAction.Add,\\n functionSelectors: verificationFunctionSelectors\\n });\\n\\n LibDiamond.diamondCut(cut, address(0), \\\"\\\");\\n }\\n\\n /**\\n * @notice Calls the destination with inputted calldata and value from EntryPoint\\n * @dev This method executes the calldata coming from the EntryPoint.\\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\\n * @param _dest Address of destination where the call will be forwarded to\\n * @param _value Amount of native coin the owner is willing to send(e.g. ETH, BNB)\\n * @param _func Bytes of calldata to execute in the destination address\\n */\\n function execute(\\n address _dest,\\n uint256 _value,\\n bytes calldata _func\\n ) external override onlyWhenUnlocked {\\n _requireFromEntryPoint();\\n address restrictionsFacet = LibDiamond.restrictionsFacet();\\n if (restrictionsFacet == address(0)) _call(_dest, _value, _func);\\n else _callWithRestrictions(_dest, _value, _func, restrictionsFacet);\\n }\\n\\n /**\\n * @notice Batch calls the destination with inputted calldata and value from EntryPoint\\n * @dev This method batch executes the calldata coming from the EntryPoint.\\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\\n * @param _dest Array of addresses of destination where the call will be forwarded to\\n * @param _value Array of amount of native coin the owner is willing to send(e.g. ETH, BNB)\\n * @param _func Array of bytes of calldata to execute in the destination address\\n */\\n function executeBatch(\\n address[] calldata _dest,\\n uint256[] calldata _value,\\n bytes[] calldata _func\\n ) external override onlyWhenUnlocked {\\n _requireFromEntryPoint();\\n if (_dest.length != _func.length || _dest.length != _value.length)\\n revert AccountFacet__InvalidArrayLength();\\n address restrictionsFacet = LibDiamond.restrictionsFacet();\\n if (restrictionsFacet == address(0)) {\\n for (uint256 i; i < _dest.length; ) {\\n _call(_dest[i], _value[i], _func[i]);\\n unchecked {\\n ++i;\\n }\\n }\\n } else {\\n for (uint256 i; i < _dest.length; ) {\\n _callWithRestrictions(\\n _dest[i],\\n _value[i],\\n _func[i],\\n restrictionsFacet\\n );\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n }\\n\\n /**\\n * @notice Validates the signature field of UserOperation\\n * @dev This method validates if the signature of UserOp is indeed valid by delegating the call to Verification Facet\\n * Barz makes a call to the pre-registered Verification Facet address in App Storage\\n * @param _userOp UserOperation from owner to be validated\\n * @param _userOpHash Hash of UserOperation given from the EntryPoint contract\\n */\\n function _validateSignature(\\n UserOperation calldata _userOp,\\n bytes32 _userOpHash\\n ) internal override returns (uint256 validationData) {\\n // Get Facet with Function Selector\\n address facet = LibLoupe.facetAddress(s.validateOwnerSignatureSelector);\\n if (facet == address(0))\\n revert AccountFacet__NonExistentVerificationFacet();\\n\\n // Make function call to VerificationFacet\\n bytes memory validateCall = abi.encodeWithSelector(\\n s.validateOwnerSignatureSelector,\\n _userOp,\\n _userOpHash\\n );\\n (bool success, bytes memory result) = facet.delegatecall(validateCall);\\n if (!success) revert AccountFacet__CallNotSuccessful();\\n validationData = uint256(bytes32(result));\\n if (validationData == 0) emit VerificationSuccess(_userOpHash);\\n else emit VerificationFailure(_userOpHash);\\n }\\n\\n /**\\n * @notice Calls the target with the inputted value and calldata\\n * @dev This method is the actual function in Barz that makes a call with an arbitrary owner-given data\\n * @param _target Address of the destination contract which the call is getting forwarded to\\n * @param _value Amount of Native coin the owner is wanting to make in this call\\n * @param _data Calldata the owner is forwarding together in the call e.g. Swap/Token Transfer\\n */\\n function _call(\\n address _target,\\n uint256 _value,\\n bytes memory _data\\n ) internal {\\n (bool success, bytes memory result) = _target.call{value: _value}(\\n _data\\n );\\n if (!success) {\\n assembly {\\n revert(add(result, 32), mload(result))\\n }\\n }\\n }\\n\\n /**\\n * @notice Calls the target with the inputted value and calldata together with restrictions check\\n * @dev This method is the actual function in Barz that makes a call with an arbitrary owner-given data\\n * @param _target Address of the destination contract which the call is getting forwarded to\\n * @param _value Amount of Native coin the owner is wanting to make in this call\\n * @param _data Calldata the owner is forwarding together in the call e.g. Swap/Token Transfer\\n * @param _restrictionsFacet Address of Facet to validate restrictions\\n */\\n function _callWithRestrictions(\\n address _target,\\n uint256 _value,\\n bytes memory _data,\\n address _restrictionsFacet\\n ) internal {\\n // NOTE: No restrictions facet, so restriction validation passes\\n if (_checkRestrictions(_restrictionsFacet, _target, _value, _data) != 0)\\n revert AccountFacet__RestrictionsFailure();\\n\\n (bool success, bytes memory result) = _target.call{value: _value}(\\n _data\\n );\\n if (!success) {\\n assembly {\\n revert(add(result, 32), mload(result))\\n }\\n }\\n }\\n\\n /**\\n * @notice Checks restrictions if the restrictions facet exists\\n * @dev This method checks if the restrictions facet exists and makes a verification call to an array of restrictions facet\\n * @param _facet Address that holds the restrictions logic\\n * @param _target Address the call is getting forwarded to\\n * @param _value Amount of native coin the call is sending together with the call\\n * @param _data Calldata to trigger execution in target address\\n */\\n function _checkRestrictions(\\n address _facet,\\n address _target,\\n uint256 _value,\\n bytes memory _data\\n ) internal returns (uint256 result) {\\n bytes memory call = abi.encodeWithSignature(\\n \\\"verifyRestrictions(address,address,uint256,bytes)\\\",\\n address(this),\\n _target,\\n _value,\\n _data\\n );\\n (bool success, bytes memory response) = _facet.delegatecall(call);\\n if (!success) revert AccountFacet__RestrictionsFailure();\\n result = uint256(bytes32(response));\\n }\\n}\\n\",\"keccak256\":\"0xcd92bcdd447010880f78e57e213123269c9e023adfc0a540608daa127d8649ca\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/facets/interfaces/IAccountFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IEntryPoint} from \\\"../../aa-4337/interfaces/IEntryPoint.sol\\\";\\n\\n/**\\n * @title Account Facet Interface\\n * @dev Interface of module contract that provides the account features and init/unitialization of signer\\n * compatible with EIP-1271 & EIP-4337\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IAccountFacet {\\n event AccountInitialized(\\n IEntryPoint indexed entryPoint,\\n bytes indexed ownerPublicKey\\n );\\n // NOTE: Added Below Event\\n event VerificationSuccess(bytes32);\\n event VerificationFailure(bytes32);\\n\\n error AccountFacet__InitializationFailure();\\n error AccountFacet__RestrictionsFailure();\\n error AccountFacet__NonExistentVerificationFacet();\\n error AccountFacet__CallNotSuccessful();\\n error AccountFacet__InvalidArrayLength();\\n\\n function initialize(\\n address verificationFacet,\\n address anEntryPoint,\\n address facetRegistry,\\n address _defaultFallBack,\\n bytes calldata _ownerPublicKey\\n ) external returns (uint256);\\n\\n function execute(address dest, uint256 value, bytes calldata func) external;\\n\\n function executeBatch(\\n address[] calldata dest,\\n uint256[] calldata value,\\n bytes[] calldata func\\n ) external;\\n}\\n\",\"keccak256\":\"0x74a9cb0b8f2f4a5148e366a401a0354426c536c012c025025d07cc25a4cd5382\",\"license\":\"Apache-2.0\"},\"contracts/facets/interfaces/IVerificationFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {UserOperation} from \\\"../../aa-4337/interfaces/UserOperation.sol\\\";\\n\\n/**\\n * @title Verification Facet Interface\\n * @dev Implements logic for user ops signature verification\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\ninterface IVerificationFacet {\\n event SignerInitialized(bytes);\\n event SignerUninitialized();\\n\\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\\n error VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\\n error VerificationFacet__InitializationFailure();\\n error VerificationFacet__InvalidFacetMapping();\\n\\n function initializeSigner(bytes memory) external returns (uint256);\\n\\n function uninitializeSigner() external returns (uint256);\\n\\n function validateOwnerSignatureSelector() external view returns (bytes4);\\n\\n function owner() external view returns (bytes memory);\\n\\n function isValidKeyType(bytes calldata) external view returns (bool);\\n\\n function validateOwnerSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x72bc370a1d1b5a6d6bde67f5026733fd8f6ba434bb90e73b0bd8627fb1579928\",\"license\":\"Apache-2.0\"},\"contracts/infrastructure/interfaces/IFacetRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Registry Interface\\n * @dev Interface for Facet Registry contract to keep track of facets & function selectors addable to user wallets\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IFacetRegistry {\\n struct FacetRegistryConfig {\\n bytes4[] selectors;\\n mapping(bytes4 => FacetInfo) info;\\n }\\n struct FacetInfo {\\n bool exists;\\n uint128 index;\\n }\\n\\n event FacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] facetSelectors\\n );\\n event FacetFunctionSelectorsRemoved(address facet, bytes4[] facetSelectors);\\n\\n error FacetRegistry__FacetSelectorAlreadyRegistered();\\n error FacetRegistry__UnregisteredFacetSelector();\\n\\n function registerFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function removeFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function areFacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external view returns (bool);\\n\\n function isFacetFunctionSelectorRegistered(\\n address facet,\\n bytes4 facetSelector\\n ) external view returns (bool);\\n\\n function getFacetFunctionSelectors(\\n address facet\\n ) external view returns (bytes4[] memory);\\n}\\n\",\"keccak256\":\"0x6e6dd2cab346ef7c31230740ec48d2925e4a9ab24c2f2fb268baaf408dcf02ef\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC1271 {\\n function isValidSignature(\\n bytes32 hash,\\n bytes memory signature\\n ) external view returns (bytes4);\\n}\\n\",\"keccak256\":\"0xcdddb7d5641c9d3f2432dec7fd13fddb9ae1480f25c76c21511e2fa16b8bd422\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibAppStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {SafeCast} from \\\"@openzeppelin/contracts/utils/math/SafeCast.sol\\\";\\nimport {IEntryPoint} from \\\"../aa-4337/interfaces/IEntryPoint.sol\\\";\\nimport {IFacetRegistry} from \\\"../infrastructure/interfaces/IFacetRegistry.sol\\\";\\n\\n/*\\n * @title App Storage\\n * @dev App storage for Barz contract to prevent storage collision\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Lock {\\n uint64 release;\\n bytes4 locker;\\n}\\n\\nstruct InitializersStorage {\\n // NOTE: initialized is a variable to make sure the initialization is only done once.\\n uint8 signerInitialized;\\n uint8 accountInitialized;\\n uint8 restrictionsInitialized;\\n}\\n\\nstruct AppStorage {\\n mapping(uint256 => InitializersStorage) initStorage;\\n uint8 signerMigration;\\n bytes4 validateOwnerSignatureSelector;\\n IEntryPoint entryPoint;\\n IFacetRegistry facetRegistry;\\n mapping(uint256 => Lock) locks;\\n}\\n\\nlibrary LibAppStorage {\\n error LibAppStorage__AccountAlreadyUninitialized();\\n error LibAppStorage__AccountMustBeUninitialized();\\n error LibAppStorage__SignerAlreadyUninitialized();\\n error LibAppStorage__SignerMustBeUninitialized();\\n\\n function appStorage() internal pure returns (AppStorage storage ds) {\\n assembly {\\n ds.slot := 0\\n }\\n }\\n\\n function setSignerUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerAlreadyUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 0;\\n }\\n\\n function getValidateOwnerSignatureSelector()\\n internal\\n view\\n returns (bytes4 selector)\\n {\\n selector = appStorage().validateOwnerSignatureSelector;\\n }\\n\\n function setValidateOwnerSignatureSelector(\\n bytes4 _validateOwnerSignatureSelector\\n ) internal {\\n appStorage()\\n .validateOwnerSignatureSelector = _validateOwnerSignatureSelector;\\n }\\n\\n function enforceSignerInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerMustBeUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 1;\\n }\\n\\n function enforceAccountInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].accountInitialized) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n s.initStorage[0].accountInitialized = 1;\\n }\\n\\n function initiateSignerMigration() internal {\\n appStorage().signerMigration = 1;\\n }\\n\\n function enforceSignerMigration() internal view {\\n if (1 != appStorage().signerMigration) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n }\\n\\n function finalizeSignerMigration() internal {\\n appStorage().signerMigration = 0;\\n }\\n\\n function setLock(uint256 _releaseAfter, bytes4 _locker) internal {\\n appStorage().locks[0] = Lock(SafeCast.toUint64(_releaseAfter), _locker);\\n }\\n\\n function enforceRestrictionsInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__SignerMustBeUninitialized();\\n s.initStorage[0].restrictionsInitialized = 1;\\n }\\n\\n function setRestrictionsUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__AccountAlreadyUninitialized();\\n s.initStorage[0].restrictionsInitialized = 0;\\n }\\n}\\n\\ncontract BarzStorage {\\n AppStorage internal s;\\n modifier onlyWhenUnlocked() {\\n require(\\n uint64(block.timestamp) >= s.locks[0].release,\\n \\\"Account Locked\\\"\\n );\\n _;\\n }\\n modifier onlyWhenLocked() {\\n require(\\n uint64(block.timestamp) < s.locks[0].release,\\n \\\"Account Unlocked\\\"\\n );\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x48524007862a6ce0e07f645950613ce6513ce073c37a109c75019683d42bae27\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\\n bytes4(keccak256(\\\"verifyRestrictions(address,address,uint256,bytes)\\\"));\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // Default Fallback Handler of the barz.\\n IDiamondLoupe defaultFallbackHandler;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function enforceIsSelf() internal view {\\n require(msg.sender == address(this), \\\"LibDiamond: Caller not self\\\");\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n\\n unchecked {\\n facetIndex++;\\n }\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n\\n function restrictionsFacet() internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(\\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2cabdc00de859c3a3170ce3bda5d0e5fd3933d47ce904fd1585f9818b02572f8\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\nimport {LibDiamond} from \\\"./LibDiamond.sol\\\";\\n\\n/**\\n * @title LibLoupe\\n * @dev Internal Library to provide utility feature for reading the state of diamond facets\\n * Originally from Diamond's implementation of Mudgen(author of EIP-2535)\\n */\\nlibrary LibLoupe {\\n /// @notice Gets all facets and their selectors.\\n /// @return facets_ Facet\\n function facets()\\n internal\\n view\\n returns (IDiamondLoupe.Facet[] memory facets_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facets_ = new IDiamondLoupe.Facet[](ds.selectorCount);\\n uint16[] memory numFacetSelectors = new uint16[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facets_[facetIndex].facetAddress == facetAddress_) {\\n facets_[facetIndex].functionSelectors[\\n numFacetSelectors[facetIndex]\\n ] = selector;\\n // probably will never have more than 256 functions from one facet contract\\n require(numFacetSelectors[facetIndex] < 255);\\n numFacetSelectors[facetIndex]++;\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facets_[numFacets].facetAddress = facetAddress_;\\n facets_[numFacets].functionSelectors = new bytes4[](\\n ds.selectorCount\\n );\\n facets_[numFacets].functionSelectors[0] = selector;\\n numFacetSelectors[numFacets] = 1;\\n numFacets++;\\n }\\n }\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n uint256 numSelectors = numFacetSelectors[facetIndex];\\n bytes4[] memory selectors = facets_[facetIndex].functionSelectors;\\n // setting the number of selectors\\n assembly {\\n mstore(selectors, numSelectors)\\n }\\n }\\n // setting the number of facets\\n assembly {\\n mstore(facets_, numFacets)\\n }\\n }\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return _facetFunctionSelectors The selectors associated with a facet address.\\n function facetFunctionSelectors(\\n address _facet\\n ) internal view returns (bytes4[] memory _facetFunctionSelectors) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n uint256 numSelectors;\\n _facetFunctionSelectors = new bytes4[](ds.selectorCount);\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facet = address(bytes20(ds.facets[selector]));\\n if (_facet == facet) {\\n _facetFunctionSelectors[numSelectors] = selector;\\n numSelectors++;\\n }\\n }\\n }\\n // Set the number of selectors in the array\\n assembly {\\n mstore(_facetFunctionSelectors, numSelectors)\\n }\\n }\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n internal\\n view\\n returns (address[] memory facetAddresses_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetAddresses_ = new address[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facetAddress_ == facetAddresses_[facetIndex]) {\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facetAddresses_[numFacets] = facetAddress_;\\n numFacets++;\\n }\\n }\\n // Set the number of facet addresses in the array\\n assembly {\\n mstore(facetAddresses_, numFacets)\\n }\\n }\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(LibDiamond.diamondStorage().facets[_functionSelector])\\n );\\n }\\n}\\n\",\"keccak256\":\"0x0b11439c3cc657095e15ec2241fdcf67204b14001357b612fc5db4ff9e760a5a\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5061001961001e565b61008e565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb554610100900460ff1615610070576040516338fc28cb60e01b815260040160405180910390fd5b600080805260209190915260409020805461ff001916610100179055565b6129b6806200009e6000396000f3fe608060405234801561001057600080fd5b50600436106100725760003560e01c8063b0d691fe11610050578063b0d691fe146100c5578063b61d27f61461010c578063d087d2881461011f57600080fd5b80633a871cdd1461007757806347e1da2a1461009d5780634a936417146100b2575b600080fd5b61008a610085366004611fb5565b610127565b6040519081526020015b60405180910390f35b6100b06100ab366004612055565b61014d565b005b61008a6100c036600461215a565b610450565b60015465010000000000900473ffffffffffffffffffffffffffffffffffffffff1660405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610094565b6100b061011a3660046121ce565b6106d0565b61008a61089d565b600061013161095e565b61013b8484610a16565b905061014682610c5d565b9392505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff9081164290911610156101f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064015b60405180910390fd5b6101fd61095e565b848114158061020c5750848314155b15610243576040517fdde5716100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006102b87fac87185d000000000000000000000000000000000000000000000000000000006000527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020527f6d9f2463c8c0d8cb8be556a773ab21d4321328909a1725f2ef7cae0c320e95da5460601c90565b905073ffffffffffffffffffffffffffffffffffffffff811661038f5760005b86811015610389576103818888838181106102f5576102f5612228565b905060200201602081019061030a9190612257565b87878481811061031c5761031c612228565b9050602002013586868581811061033557610335612228565b90506020028101906103479190612272565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610cc892505050565b6001016102d8565b50610447565b60005b868110156104455761043d8888838181106103af576103af612228565b90506020020160208101906103c49190612257565b8787848181106103d6576103d6612228565b905060200201358686858181106103ef576103ef612228565b90506020028101906104019190612272565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250889250610d45915050565b600101610392565b505b50505050505050565b600061045a610e0d565b6001805473ffffffffffffffffffffffffffffffffffffffff88811665010000000000027fffffffffffffff0000000000000000000000000000000000000000ffffffffff90921691909117909155600280548783167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216179091557f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd492380549287169290911691909117905561051187610eb3565b60008383604051602401610526929190612320565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fcd9b47e40000000000000000000000000000000000000000000000000000000017905251909150600090819073ffffffffffffffffffffffffffffffffffffffff8b16906105c8908590612360565b600060405180830381855af49150503d8060008114610603576040519150601f19603f3d011682016040523d82523d6000602084013e610608565b606091505b5091509150811580610623575061061e8161237c565b600114155b1561065a576040517f1602372100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60019350858560405161066e9291906123c1565b60405190819003812060015490916501000000000090910473ffffffffffffffffffffffffffffffffffffffff16907fd429ff0b972be4ae725700a373d05007287994e4c86cb83315b43ffa85b595fd90600090a35050509695505050505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610773576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064016101ec565b61077b61095e565b60006107f07fac87185d000000000000000000000000000000000000000000000000000000006000527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020527f6d9f2463c8c0d8cb8be556a773ab21d4321328909a1725f2ef7cae0c320e95da5460601c90565b905073ffffffffffffffffffffffffffffffffffffffff81166108535761084e858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610cc892505050565b610896565b610896858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250879250610d45915050565b5050505050565b60015460009065010000000000900473ffffffffffffffffffffffffffffffffffffffff166040517f35567e1a0000000000000000000000000000000000000000000000000000000081523060048201526000602482015273ffffffffffffffffffffffffffffffffffffffff91909116906335567e1a90604401602060405180830381865afa158015610935573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061095991906123d1565b905090565b60015465010000000000900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a14576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f6163636f756e743a206e6f742066726f6d20456e747279506f696e740000000060448201526064016101ec565b565b600154610100900460e01b7fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604081205460601c80610aab576040517f6eb2360200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600154604051600091610100900460e01b90610acd908790879060240161244e565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090506000808373ffffffffffffffffffffffffffffffffffffffff1683604051610b549190612360565b600060405180830381855af49150503d8060008114610b8f576040519150601f19603f3d011682016040523d82523d6000602084013e610b94565b606091505b509150915081610bd0576040517f3cbbb65000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610bd98161237c565b94506000859003610c1c576040518681527f19e781916118c373dadcb7776fae0a2dbb6bbdeedae143ce68031e22801ef8659060200160405180910390a1610c50565b6040518681527fbbfee2df7f28b899771f1015dc85d7840ff9f6162f23f6aa99686e8fbd2ce1319060200160405180910390a15b5050505092915050565b50565b8015610c5a5760405160009033907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90849084818181858888f193505050503d8060008114610896576040519150601f19603f3d011682016040523d82523d6000602084013e610896565b6000808473ffffffffffffffffffffffffffffffffffffffff168484604051610cf19190612360565b60006040518083038185875af1925050503d8060008114610d2e576040519150601f19603f3d011682016040523d82523d6000602084013e610d33565b606091505b50915091508161089657805160208201fd5b610d5181858585611117565b15610d88576040517f01f595e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000808573ffffffffffffffffffffffffffffffffffffffff168585604051610db19190612360565b60006040518083038185875af1925050503d8060008114610dee576040519150601f19603f3d011682016040523d82523d6000602084013e610df3565b606091505b509150915081610e0557805160208201fd5b505050505050565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb554610100900460ff1615610e78576040517f38fc28cb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100179055565b604080516001808252818301909252600091816020015b60408051606080820183526000808352602083015291810191909152815260200190600190039081610eca57905050905060008273ffffffffffffffffffffffffffffffffffffffff16633253960f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f6c9190612592565b604080516003808252608082019092529192506000919060208201606080368337019050509050631626ba7e60e01b81600081518110610fae57610fae612228565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681525050818160018151811061100e5761100e612228565b7fffffffff000000000000000000000000000000000000000000000000000000009092166020928302919091019091015280517f8da5cb5b00000000000000000000000000000000000000000000000000000000908290600290811061107657611076612228565b7fffffffff00000000000000000000000000000000000000000000000000000000909216602092830291909101820152604080516060810190915273ffffffffffffffffffffffffffffffffffffffff861681529081016000815260200182815250836000815181106110eb576110eb612228565b602002602001018190525061111183600060405180602001604052806000815250611264565b50505050565b60008030858585604051602401611131949392919061264d565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fac87185d0000000000000000000000000000000000000000000000000000000017905251909150600090819073ffffffffffffffffffffffffffffffffffffffff8916906111d3908590612360565b600060405180830381855af49150503d806000811461120e576040519150601f19603f3d011682016040523d82523d6000602084013e611213565b606091505b50915091508161124f576040517f01f595e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6112588161237c565b98975050505050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921547f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff8116908190600090600716156112d35750600381901c60009081526001840160205260409020545b60005b87518110156113505761134383838a84815181106112f6576112f6612228565b6020026020010151600001518b858151811061131457611314612228565b6020026020010151602001518c868151811061133257611332612228565b6020026020010151604001516113f0565b90935091506001016112d6565b50828214611389576002840180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff84161790555b60078216156113ab57600382901c600090815260018501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb6738787876040516113de93929190612696565b60405180910390a16104478686611e81565b600080807f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f905060008451116114a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f2063757400000000000000000000000000000000000000000060648201526084016101ec565b60008560028111156114bc576114bc6125d4565b0361168c576114e38660405180606001604052806024815260200161290d60249139611f7a565b60005b845181101561168657600085828151811061150357611503612228565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c156115d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c726561647920657869737473000000000000000000000060648201526084016101ec565b7fffffffff0000000000000000000000000000000000000000000000000000000080831660008181526020879052604090207fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608d901b168e17905560e060058e901b811692831c199c909c1690821c179a81900361166a5760038c901c600090815260018601602052604081209b909b555b8b6116748161282d565b9c5050600190930192506114e6915050565b50611e75565b60018560028111156116a0576116a06125d4565b03611990576116c78660405180606001604052806028815260200161295960289139611f7a565b60005b84518110156116865760008582815181106116e7576116e7612228565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c3081036117bc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4c69624469616d6f6e644375743a2043616e2774207265706c61636520696d6d60448201527f757461626c652066756e6374696f6e000000000000000000000000000000000060648201526084016101ec565b8973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611877576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e000000000000000060648201526084016101ec565b73ffffffffffffffffffffffffffffffffffffffff811661191a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e207468617420646f65736e2774206578697374000000000000000060648201526084016101ec565b507fffffffff0000000000000000000000000000000000000000000000000000000090911660009081526020849052604090206bffffffffffffffffffffffff919091167fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608a901b161790556001016116ca565b60028560028111156119a4576119a46125d4565b03611ded5773ffffffffffffffffffffffffffffffffffffffff861615611a4d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d75737420626520616464726573732830290000000000000000000060648201526084016101ec565b600388901c6007891660005b8651811015611dcd5760008a9003611a955782611a7581612865565b60008181526001870160205260409020549b50935060079250611aa39050565b81611a9f81612865565b9250505b6000806000808a8581518110611abb57611abb612228565b6020908102919091018101517fffffffff0000000000000000000000000000000000000000000000000000000081166000908152918a9052604090912054909150606081901c611b8d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e277420657869737400000000000000000060648201526084016101ec565b30606082901c03611c20576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e00000000000000000000000000000000000060648201526084016101ec565b600587901b8f901b94507fffffffff0000000000000000000000000000000000000000000000000000000080861690831614611cbe577fffffffff000000000000000000000000000000000000000000000000000000008516600090815260208a90526040902080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff83161790555b7fffffffff0000000000000000000000000000000000000000000000000000000091909116600090815260208990526040812055600381901c611fff16925060051b60e0169050858214611d53576000828152600188016020526040902080547fffffffff0000000000000000000000000000000000000000000000000000000080841c19909116908516831c179055611da4565b80837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c817fffffffff0000000000000000000000000000000000000000000000000000000060001b901c198e16179c505b84600003611dc257600086815260018801602052604081208190559c505b505050600101611a59565b5080611dda83600861289a565b611de491906128b7565b99505050611e75565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560448201527f74416374696f6e0000000000000000000000000000000000000000000000000060648201526084016101ec565b50959694955050505050565b73ffffffffffffffffffffffffffffffffffffffff8216611ea0575050565b611ec28260405180606001604052806028815260200161293160289139611f7a565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051611eea9190612360565b600060405180830381855af49150503d8060008114611f25576040519150601f19603f3d011682016040523d82523d6000602084013e611f2a565b606091505b50915091508161111157805115611f445780518082602001fd5b83836040517f192105d70000000000000000000000000000000000000000000000000000000081526004016101ec9291906128ca565b813b8181611111576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101ec91906128f9565b600080600060608486031215611fca57600080fd5b833567ffffffffffffffff811115611fe157600080fd5b84016101608187031215611ff457600080fd5b95602085013595506040909401359392505050565b60008083601f84011261201b57600080fd5b50813567ffffffffffffffff81111561203357600080fd5b6020830191508360208260051b850101111561204e57600080fd5b9250929050565b6000806000806000806060878903121561206e57600080fd5b863567ffffffffffffffff8082111561208657600080fd5b6120928a838b01612009565b909850965060208901359150808211156120ab57600080fd5b6120b78a838b01612009565b909650945060408901359150808211156120d057600080fd5b506120dd89828a01612009565b979a9699509497509295939492505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461211357600080fd5b919050565b60008083601f84011261212a57600080fd5b50813567ffffffffffffffff81111561214257600080fd5b60208301915083602082850101111561204e57600080fd5b60008060008060008060a0878903121561217357600080fd5b61217c876120ef565b955061218a602088016120ef565b9450612198604088016120ef565b93506121a6606088016120ef565b9250608087013567ffffffffffffffff8111156121c257600080fd5b6120dd89828a01612118565b600080600080606085870312156121e457600080fd5b6121ed856120ef565b935060208501359250604085013567ffffffffffffffff81111561221057600080fd5b61221c87828801612118565b95989497509550505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561226957600080fd5b610146826120ef565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126122a757600080fd5b83018035915067ffffffffffffffff8211156122c257600080fd5b60200191503681900382131561204e57600080fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b6020815260006123346020830184866122d7565b949350505050565b60005b8381101561235757818101518382015260200161233f565b50506000910152565b6000825161237281846020870161233c565b9190910192915050565b805160208083015191908110156123bb577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8160200360031b1b821691505b50919050565b8183823760009101908152919050565b6000602082840312156123e357600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261241f57600080fd5b830160208101925035905067ffffffffffffffff81111561243f57600080fd5b80360382131561204e57600080fd5b6040815261247c60408201612462856120ef565b73ffffffffffffffffffffffffffffffffffffffff169052565b60208301356060820152600061249560408501856123ea565b6101608060808601526124ad6101a0860183856122d7565b92506124bc60608801886123ea565b92507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0808786030160a08801526124f48585846122d7565b9450608089013560c088015260a089013560e0880152610100935060c089013584880152610120915060e089013582880152610140848a01358189015261253d838b018b6123ea565b955092508188870301848901526125558686856122d7565b9550612563818b018b6123ea565b9550935050808786030161018088015250506125808383836122d7565b93505050508260208301529392505050565b6000602082840312156125a457600080fd5b81517fffffffff000000000000000000000000000000000000000000000000000000008116811461014657600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6000815180845261261b81602086016020860161233c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600073ffffffffffffffffffffffffffffffffffffffff80871683528086166020840152508360408301526080606083015261268c6080830184612603565b9695505050505050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b848110156127c1577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808a8503018652815188850173ffffffffffffffffffffffffffffffffffffffff82511686528482015160038110612748577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b808310156127ac5783517fffffffff0000000000000000000000000000000000000000000000000000000016825292860192600192909201919086019061276a565b509785019795505050908201906001016126bf565b505073ffffffffffffffffffffffffffffffffffffffff8a169088015286810360408801526127f08189612603565b9a9950505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361285e5761285e6127fe565b5060010190565b600081612874576128746127fe565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b80820281158282048414176128b1576128b16127fe565b92915050565b808201808211156128b1576128b16127fe565b73ffffffffffffffffffffffffffffffffffffffff831681526040602082015260006123346040830184612603565b602081526000610146602083018461260356fe4c69624469616d6f6e644375743a2041646420666163657420686173206e6f20636f64654c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a205265706c61636520666163657420686173206e6f20636f6465a2646970667358221220a952f19990a20474450919a2df9ddff4430a71350892e0954f2bb073575ad64864736f6c63430008150033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100725760003560e01c8063b0d691fe11610050578063b0d691fe146100c5578063b61d27f61461010c578063d087d2881461011f57600080fd5b80633a871cdd1461007757806347e1da2a1461009d5780634a936417146100b2575b600080fd5b61008a610085366004611fb5565b610127565b6040519081526020015b60405180910390f35b6100b06100ab366004612055565b61014d565b005b61008a6100c036600461215a565b610450565b60015465010000000000900473ffffffffffffffffffffffffffffffffffffffff1660405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610094565b6100b061011a3660046121ce565b6106d0565b61008a61089d565b600061013161095e565b61013b8484610a16565b905061014682610c5d565b9392505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff9081164290911610156101f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064015b60405180910390fd5b6101fd61095e565b848114158061020c5750848314155b15610243576040517fdde5716100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006102b87fac87185d000000000000000000000000000000000000000000000000000000006000527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020527f6d9f2463c8c0d8cb8be556a773ab21d4321328909a1725f2ef7cae0c320e95da5460601c90565b905073ffffffffffffffffffffffffffffffffffffffff811661038f5760005b86811015610389576103818888838181106102f5576102f5612228565b905060200201602081019061030a9190612257565b87878481811061031c5761031c612228565b9050602002013586868581811061033557610335612228565b90506020028101906103479190612272565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610cc892505050565b6001016102d8565b50610447565b60005b868110156104455761043d8888838181106103af576103af612228565b90506020020160208101906103c49190612257565b8787848181106103d6576103d6612228565b905060200201358686858181106103ef576103ef612228565b90506020028101906104019190612272565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250889250610d45915050565b600101610392565b505b50505050505050565b600061045a610e0d565b6001805473ffffffffffffffffffffffffffffffffffffffff88811665010000000000027fffffffffffffff0000000000000000000000000000000000000000ffffffffff90921691909117909155600280548783167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216179091557f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd492380549287169290911691909117905561051187610eb3565b60008383604051602401610526929190612320565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fcd9b47e40000000000000000000000000000000000000000000000000000000017905251909150600090819073ffffffffffffffffffffffffffffffffffffffff8b16906105c8908590612360565b600060405180830381855af49150503d8060008114610603576040519150601f19603f3d011682016040523d82523d6000602084013e610608565b606091505b5091509150811580610623575061061e8161237c565b600114155b1561065a576040517f1602372100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60019350858560405161066e9291906123c1565b60405190819003812060015490916501000000000090910473ffffffffffffffffffffffffffffffffffffffff16907fd429ff0b972be4ae725700a373d05007287994e4c86cb83315b43ffa85b595fd90600090a35050509695505050505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610773576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064016101ec565b61077b61095e565b60006107f07fac87185d000000000000000000000000000000000000000000000000000000006000527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020527f6d9f2463c8c0d8cb8be556a773ab21d4321328909a1725f2ef7cae0c320e95da5460601c90565b905073ffffffffffffffffffffffffffffffffffffffff81166108535761084e858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610cc892505050565b610896565b610896858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250879250610d45915050565b5050505050565b60015460009065010000000000900473ffffffffffffffffffffffffffffffffffffffff166040517f35567e1a0000000000000000000000000000000000000000000000000000000081523060048201526000602482015273ffffffffffffffffffffffffffffffffffffffff91909116906335567e1a90604401602060405180830381865afa158015610935573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061095991906123d1565b905090565b60015465010000000000900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a14576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f6163636f756e743a206e6f742066726f6d20456e747279506f696e740000000060448201526064016101ec565b565b600154610100900460e01b7fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604081205460601c80610aab576040517f6eb2360200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600154604051600091610100900460e01b90610acd908790879060240161244e565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090506000808373ffffffffffffffffffffffffffffffffffffffff1683604051610b549190612360565b600060405180830381855af49150503d8060008114610b8f576040519150601f19603f3d011682016040523d82523d6000602084013e610b94565b606091505b509150915081610bd0576040517f3cbbb65000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610bd98161237c565b94506000859003610c1c576040518681527f19e781916118c373dadcb7776fae0a2dbb6bbdeedae143ce68031e22801ef8659060200160405180910390a1610c50565b6040518681527fbbfee2df7f28b899771f1015dc85d7840ff9f6162f23f6aa99686e8fbd2ce1319060200160405180910390a15b5050505092915050565b50565b8015610c5a5760405160009033907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90849084818181858888f193505050503d8060008114610896576040519150601f19603f3d011682016040523d82523d6000602084013e610896565b6000808473ffffffffffffffffffffffffffffffffffffffff168484604051610cf19190612360565b60006040518083038185875af1925050503d8060008114610d2e576040519150601f19603f3d011682016040523d82523d6000602084013e610d33565b606091505b50915091508161089657805160208201fd5b610d5181858585611117565b15610d88576040517f01f595e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000808573ffffffffffffffffffffffffffffffffffffffff168585604051610db19190612360565b60006040518083038185875af1925050503d8060008114610dee576040519150601f19603f3d011682016040523d82523d6000602084013e610df3565b606091505b509150915081610e0557805160208201fd5b505050505050565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb554610100900460ff1615610e78576040517f38fc28cb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100179055565b604080516001808252818301909252600091816020015b60408051606080820183526000808352602083015291810191909152815260200190600190039081610eca57905050905060008273ffffffffffffffffffffffffffffffffffffffff16633253960f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f6c9190612592565b604080516003808252608082019092529192506000919060208201606080368337019050509050631626ba7e60e01b81600081518110610fae57610fae612228565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681525050818160018151811061100e5761100e612228565b7fffffffff000000000000000000000000000000000000000000000000000000009092166020928302919091019091015280517f8da5cb5b00000000000000000000000000000000000000000000000000000000908290600290811061107657611076612228565b7fffffffff00000000000000000000000000000000000000000000000000000000909216602092830291909101820152604080516060810190915273ffffffffffffffffffffffffffffffffffffffff861681529081016000815260200182815250836000815181106110eb576110eb612228565b602002602001018190525061111183600060405180602001604052806000815250611264565b50505050565b60008030858585604051602401611131949392919061264d565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fac87185d0000000000000000000000000000000000000000000000000000000017905251909150600090819073ffffffffffffffffffffffffffffffffffffffff8916906111d3908590612360565b600060405180830381855af49150503d806000811461120e576040519150601f19603f3d011682016040523d82523d6000602084013e611213565b606091505b50915091508161124f576040517f01f595e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6112588161237c565b98975050505050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921547f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff8116908190600090600716156112d35750600381901c60009081526001840160205260409020545b60005b87518110156113505761134383838a84815181106112f6576112f6612228565b6020026020010151600001518b858151811061131457611314612228565b6020026020010151602001518c868151811061133257611332612228565b6020026020010151604001516113f0565b90935091506001016112d6565b50828214611389576002840180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff84161790555b60078216156113ab57600382901c600090815260018501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb6738787876040516113de93929190612696565b60405180910390a16104478686611e81565b600080807f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f905060008451116114a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f2063757400000000000000000000000000000000000000000060648201526084016101ec565b60008560028111156114bc576114bc6125d4565b0361168c576114e38660405180606001604052806024815260200161290d60249139611f7a565b60005b845181101561168657600085828151811061150357611503612228565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c156115d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c726561647920657869737473000000000000000000000060648201526084016101ec565b7fffffffff0000000000000000000000000000000000000000000000000000000080831660008181526020879052604090207fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608d901b168e17905560e060058e901b811692831c199c909c1690821c179a81900361166a5760038c901c600090815260018601602052604081209b909b555b8b6116748161282d565b9c5050600190930192506114e6915050565b50611e75565b60018560028111156116a0576116a06125d4565b03611990576116c78660405180606001604052806028815260200161295960289139611f7a565b60005b84518110156116865760008582815181106116e7576116e7612228565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c3081036117bc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4c69624469616d6f6e644375743a2043616e2774207265706c61636520696d6d60448201527f757461626c652066756e6374696f6e000000000000000000000000000000000060648201526084016101ec565b8973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611877576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e000000000000000060648201526084016101ec565b73ffffffffffffffffffffffffffffffffffffffff811661191a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e207468617420646f65736e2774206578697374000000000000000060648201526084016101ec565b507fffffffff0000000000000000000000000000000000000000000000000000000090911660009081526020849052604090206bffffffffffffffffffffffff919091167fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608a901b161790556001016116ca565b60028560028111156119a4576119a46125d4565b03611ded5773ffffffffffffffffffffffffffffffffffffffff861615611a4d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d75737420626520616464726573732830290000000000000000000060648201526084016101ec565b600388901c6007891660005b8651811015611dcd5760008a9003611a955782611a7581612865565b60008181526001870160205260409020549b50935060079250611aa39050565b81611a9f81612865565b9250505b6000806000808a8581518110611abb57611abb612228565b6020908102919091018101517fffffffff0000000000000000000000000000000000000000000000000000000081166000908152918a9052604090912054909150606081901c611b8d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e277420657869737400000000000000000060648201526084016101ec565b30606082901c03611c20576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e00000000000000000000000000000000000060648201526084016101ec565b600587901b8f901b94507fffffffff0000000000000000000000000000000000000000000000000000000080861690831614611cbe577fffffffff000000000000000000000000000000000000000000000000000000008516600090815260208a90526040902080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff83161790555b7fffffffff0000000000000000000000000000000000000000000000000000000091909116600090815260208990526040812055600381901c611fff16925060051b60e0169050858214611d53576000828152600188016020526040902080547fffffffff0000000000000000000000000000000000000000000000000000000080841c19909116908516831c179055611da4565b80837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c817fffffffff0000000000000000000000000000000000000000000000000000000060001b901c198e16179c505b84600003611dc257600086815260018801602052604081208190559c505b505050600101611a59565b5080611dda83600861289a565b611de491906128b7565b99505050611e75565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560448201527f74416374696f6e0000000000000000000000000000000000000000000000000060648201526084016101ec565b50959694955050505050565b73ffffffffffffffffffffffffffffffffffffffff8216611ea0575050565b611ec28260405180606001604052806028815260200161293160289139611f7a565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051611eea9190612360565b600060405180830381855af49150503d8060008114611f25576040519150601f19603f3d011682016040523d82523d6000602084013e611f2a565b606091505b50915091508161111157805115611f445780518082602001fd5b83836040517f192105d70000000000000000000000000000000000000000000000000000000081526004016101ec9291906128ca565b813b8181611111576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101ec91906128f9565b600080600060608486031215611fca57600080fd5b833567ffffffffffffffff811115611fe157600080fd5b84016101608187031215611ff457600080fd5b95602085013595506040909401359392505050565b60008083601f84011261201b57600080fd5b50813567ffffffffffffffff81111561203357600080fd5b6020830191508360208260051b850101111561204e57600080fd5b9250929050565b6000806000806000806060878903121561206e57600080fd5b863567ffffffffffffffff8082111561208657600080fd5b6120928a838b01612009565b909850965060208901359150808211156120ab57600080fd5b6120b78a838b01612009565b909650945060408901359150808211156120d057600080fd5b506120dd89828a01612009565b979a9699509497509295939492505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461211357600080fd5b919050565b60008083601f84011261212a57600080fd5b50813567ffffffffffffffff81111561214257600080fd5b60208301915083602082850101111561204e57600080fd5b60008060008060008060a0878903121561217357600080fd5b61217c876120ef565b955061218a602088016120ef565b9450612198604088016120ef565b93506121a6606088016120ef565b9250608087013567ffffffffffffffff8111156121c257600080fd5b6120dd89828a01612118565b600080600080606085870312156121e457600080fd5b6121ed856120ef565b935060208501359250604085013567ffffffffffffffff81111561221057600080fd5b61221c87828801612118565b95989497509550505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561226957600080fd5b610146826120ef565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126122a757600080fd5b83018035915067ffffffffffffffff8211156122c257600080fd5b60200191503681900382131561204e57600080fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b6020815260006123346020830184866122d7565b949350505050565b60005b8381101561235757818101518382015260200161233f565b50506000910152565b6000825161237281846020870161233c565b9190910192915050565b805160208083015191908110156123bb577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8160200360031b1b821691505b50919050565b8183823760009101908152919050565b6000602082840312156123e357600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261241f57600080fd5b830160208101925035905067ffffffffffffffff81111561243f57600080fd5b80360382131561204e57600080fd5b6040815261247c60408201612462856120ef565b73ffffffffffffffffffffffffffffffffffffffff169052565b60208301356060820152600061249560408501856123ea565b6101608060808601526124ad6101a0860183856122d7565b92506124bc60608801886123ea565b92507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0808786030160a08801526124f48585846122d7565b9450608089013560c088015260a089013560e0880152610100935060c089013584880152610120915060e089013582880152610140848a01358189015261253d838b018b6123ea565b955092508188870301848901526125558686856122d7565b9550612563818b018b6123ea565b9550935050808786030161018088015250506125808383836122d7565b93505050508260208301529392505050565b6000602082840312156125a457600080fd5b81517fffffffff000000000000000000000000000000000000000000000000000000008116811461014657600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6000815180845261261b81602086016020860161233c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600073ffffffffffffffffffffffffffffffffffffffff80871683528086166020840152508360408301526080606083015261268c6080830184612603565b9695505050505050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b848110156127c1577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808a8503018652815188850173ffffffffffffffffffffffffffffffffffffffff82511686528482015160038110612748577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b808310156127ac5783517fffffffff0000000000000000000000000000000000000000000000000000000016825292860192600192909201919086019061276a565b509785019795505050908201906001016126bf565b505073ffffffffffffffffffffffffffffffffffffffff8a169088015286810360408801526127f08189612603565b9a9950505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361285e5761285e6127fe565b5060010190565b600081612874576128746127fe565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b80820281158282048414176128b1576128b16127fe565b92915050565b808201808211156128b1576128b16127fe565b73ffffffffffffffffffffffffffffffffffffffff831681526040602082015260006123346040830184612603565b602081526000610146602083018461260356fe4c69624469616d6f6e644375743a2041646420666163657420686173206e6f20636f64654c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a205265706c61636520666163657420686173206e6f20636f6465a2646970667358221220a952f19990a20474450919a2df9ddff4430a71350892e0954f2bb073575ad64864736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "Account module contract that provides the account features and initialization of signer compatible with EIP-1271 & EIP-4337", + "kind": "dev", + "methods": { + "execute(address,uint256,bytes)": { + "details": "This method executes the calldata coming from the EntryPoint. Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)", + "params": { + "_dest": "Address of destination where the call will be forwarded to", + "_func": "Bytes of calldata to execute in the destination address", + "_value": "Amount of native coin the owner is willing to send(e.g. ETH, BNB)" + } + }, + "executeBatch(address[],uint256[],bytes[])": { + "details": "This method batch executes the calldata coming from the EntryPoint. Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)", + "params": { + "_dest": "Array of addresses of destination where the call will be forwarded to", + "_func": "Array of bytes of calldata to execute in the destination address", + "_value": "Array of amount of native coin the owner is willing to send(e.g. ETH, BNB)" + } + }, + "initialize(address,address,address,address,bytes)": { + "details": "This method can only be called during the initialization or signature migration. If the proxy contract was created without initialization, anyone can call initialize. Barz calls initialize in constructor in an atomic transaction during deployment", + "params": { + "_anEntryPoint": "Entrypoint contract defined in EIP-4337 handling the flow of UserOp", + "_defaultFallBackHandler": "Middleware contract for default facets", + "_facetRegistry": "Registry of Facets that hold all facet information", + "_ownerPublicKey": "Bytes of owner public key", + "_verificationFacet": "Facet contract handling the verificationi" + } + } + }, + "title": "Account Facet", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "constructor": { + "notice": "This constructor ensures that this contract can only be used as singleton for Proxy contracts" + }, + "entryPoint()": { + "notice": "Returns the address of EntryPoint contract registered to Barz account" + }, + "execute(address,uint256,bytes)": { + "notice": "Calls the destination with inputted calldata and value from EntryPoint" + }, + "executeBatch(address[],uint256[],bytes[])": { + "notice": "Batch calls the destination with inputted calldata and value from EntryPoint" + }, + "getNonce()": { + "notice": "Return the account nonce. This method returns the next sequential nonce. For a nonce of a specific key, use `entrypoint.getNonce(account, key)`" + }, + "initialize(address,address,address,address,bytes)": { + "notice": "Initializes the initial storage of the Barz contract." + }, + "validateUserOp((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256)": { + "notice": "Validate user's signature and nonce. subclass doesn't need to override this method. Instead, it should override the specific internal validation methods." + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 27823, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "s", + "offset": 0, + "slot": "0", + "type": "t_struct(AppStorage)27570_storage" + } + ], + "types": { + "t_bytes4": { + "encoding": "inplace", + "label": "bytes4", + "numberOfBytes": "4" + }, + "t_contract(IEntryPoint)12286": { + "encoding": "inplace", + "label": "contract IEntryPoint", + "numberOfBytes": "20" + }, + "t_contract(IFacetRegistry)26105": { + "encoding": "inplace", + "label": "contract IFacetRegistry", + "numberOfBytes": "20" + }, + "t_mapping(t_uint256,t_struct(InitializersStorage)27549_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => struct InitializersStorage)", + "numberOfBytes": "32", + "value": "t_struct(InitializersStorage)27549_storage" + }, + "t_mapping(t_uint256,t_struct(Lock)27542_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => struct Lock)", + "numberOfBytes": "32", + "value": "t_struct(Lock)27542_storage" + }, + "t_struct(AppStorage)27570_storage": { + "encoding": "inplace", + "label": "struct AppStorage", + "members": [ + { + "astId": 27554, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "initStorage", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_uint256,t_struct(InitializersStorage)27549_storage)" + }, + { + "astId": 27556, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "signerMigration", + "offset": 0, + "slot": "1", + "type": "t_uint8" + }, + { + "astId": 27558, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "validateOwnerSignatureSelector", + "offset": 1, + "slot": "1", + "type": "t_bytes4" + }, + { + "astId": 27561, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "entryPoint", + "offset": 5, + "slot": "1", + "type": "t_contract(IEntryPoint)12286" + }, + { + "astId": 27564, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "facetRegistry", + "offset": 0, + "slot": "2", + "type": "t_contract(IFacetRegistry)26105" + }, + { + "astId": 27569, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "locks", + "offset": 0, + "slot": "3", + "type": "t_mapping(t_uint256,t_struct(Lock)27542_storage)" + } + ], + "numberOfBytes": "128" + }, + "t_struct(InitializersStorage)27549_storage": { + "encoding": "inplace", + "label": "struct InitializersStorage", + "members": [ + { + "astId": 27544, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "signerInitialized", + "offset": 0, + "slot": "0", + "type": "t_uint8" + }, + { + "astId": 27546, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "accountInitialized", + "offset": 1, + "slot": "0", + "type": "t_uint8" + }, + { + "astId": 27548, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "restrictionsInitialized", + "offset": 2, + "slot": "0", + "type": "t_uint8" + } + ], + "numberOfBytes": "32" + }, + "t_struct(Lock)27542_storage": { + "encoding": "inplace", + "label": "struct Lock", + "members": [ + { + "astId": 27539, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "release", + "offset": 0, + "slot": "0", + "type": "t_uint64" + }, + { + "astId": 27541, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "locker", + "offset": 8, + "slot": "0", + "type": "t_bytes4" + } + ], + "numberOfBytes": "32" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint64": { + "encoding": "inplace", + "label": "uint64", + "numberOfBytes": "8" + }, + "t_uint8": { + "encoding": "inplace", + "label": "uint8", + "numberOfBytes": "1" + } + } + } +} \ No newline at end of file diff --git a/deployments/base/BarzFactory.json b/deployments/base/BarzFactory.json new file mode 100644 index 0000000..12b3969 --- /dev/null +++ b/deployments/base/BarzFactory.json @@ -0,0 +1,318 @@ +{ + "address": "0x729c310186a57833f622630a16d13f710b83272a", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_accountFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_entryPoint", + "type": "address" + }, + { + "internalType": "address", + "name": "_facetRegistry", + "type": "address" + }, + { + "internalType": "address", + "name": "_defaultFallback", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "BarzDeployed", + "type": "event" + }, + { + "inputs": [], + "name": "accountFacet", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_verificationFacet", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_owner", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "_salt", + "type": "uint256" + } + ], + "name": "createAccount", + "outputs": [ + { + "internalType": "contract Barz", + "name": "barz", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "defaultFallback", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "entryPoint", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetRegistry", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_verificationFacet", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_owner", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "_salt", + "type": "uint256" + } + ], + "name": "getAddress", + "outputs": [ + { + "internalType": "address", + "name": "barzAddress", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_accountFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_verificationFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_entryPoint", + "type": "address" + }, + { + "internalType": "address", + "name": "_facetRegistry", + "type": "address" + }, + { + "internalType": "address", + "name": "_defaultFallback", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_ownerPublicKey", + "type": "bytes" + } + ], + "name": "getBytecode", + "outputs": [ + { + "internalType": "bytes", + "name": "barzBytecode", + "type": "bytes" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "getCreationCode", + "outputs": [ + { + "internalType": "bytes", + "name": "creationCode", + "type": "bytes" + } + ], + "stateMutability": "pure", + "type": "function" + } + ], + "transactionHash": "0xc0194611a981cab9421424b7a566e8856c99f87f01b593ab6209b4c997316381", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 1, + "gasUsed": "801756", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0xa8ba48b79763b630dc69d2447736431a2ef8ddc8eaf9ba78a2ada0f35b90e17d", + "transactionHash": "0xc0194611a981cab9421424b7a566e8856c99f87f01b593ab6209b4c997316381", + "logs": [], + "blockNumber": 6847795, + "cumulativeGasUsed": "848669", + "status": 1, + "byzantium": true + }, + "args": [ + "0xFde53272dcd7938d16E031A6989753c321728332", + "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789", + "0xAfCb70e6e9514E2A15B23A01d2a9b9f7A34f2c33", + "0x2e7f1dAe1F3799d20f5c31bEFdc7A620f664728D" + ], + "numDeployments": 3, + "solcInputHash": "4356503edd8ae34e73cb6dd1c8e2fc8a", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_accountFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_entryPoint\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_facetRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_defaultFallback\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"BarzDeployed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"accountFacet\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_verificationFacet\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_owner\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_salt\",\"type\":\"uint256\"}],\"name\":\"createAccount\",\"outputs\":[{\"internalType\":\"contract Barz\",\"name\":\"barz\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"defaultFallback\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"entryPoint\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetRegistry\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_verificationFacet\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_owner\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_salt\",\"type\":\"uint256\"}],\"name\":\"getAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"barzAddress\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_accountFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_verificationFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_entryPoint\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_facetRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_defaultFallback\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_ownerPublicKey\",\"type\":\"bytes\"}],\"name\":\"getBytecode\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"barzBytecode\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCreationCode\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"creationCode\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"Contract to easily deploy Barz to a pre-computed address with a single call\",\"kind\":\"dev\",\"methods\":{\"constructor\":{\"params\":{\"_accountFacet\":\"Account Facet to be used to create Barz\",\"_defaultFallback\":\"Default Fallback Handler to be used to create Barz\",\"_entryPoint\":\"Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\",\"_facetRegistry\":\"Facet Registry to be used to create Barz\"}},\"createAccount(address,bytes,uint256)\":{\"params\":{\"_owner\":\"Public Key of the owner to initialize barz account\",\"_salt\":\"Salt used for deploying barz with create2\",\"_verificationFacet\":\"Address of verification facet used for creating the barz account\"},\"returns\":{\"barz\":\"Instance of Barz contract deployed with the given parameters\"}},\"getAddress(address,bytes,uint256)\":{\"params\":{\"_owner\":\"Public Key of the owner to initialize barz account\",\"_salt\":\"Salt used for deploying barz with create2\",\"_verificationFacet\":\"Address of verification facet used for creating the barz account\"},\"returns\":{\"barzAddress\":\"Precalculated Barz address\"}},\"getBytecode(address,address,address,address,address,bytes)\":{\"params\":{\"_accountFacet\":\"Account Facet to be used to create Barz\",\"_defaultFallback\":\"Default Fallback Handler to be used to create Barz\",\"_entryPoint\":\"Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\",\"_facetRegistry\":\"Facet Registry to be used to create Barz\",\"_ownerPublicKey\":\"Public Key of owner to be used to initialize Barz ownership\",\"_verificationFacet\":\"Verification Facet to be used to create Barz\"},\"returns\":{\"barzBytecode\":\"Bytecode of Barz\"}},\"getCreationCode()\":{\"returns\":{\"creationCode\":\"Creation code of Barz\"}}},\"title\":\"Barz Factory\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"Sets the initialization data for Barz contract initialization\"},\"createAccount(address,bytes,uint256)\":{\"notice\":\"Creates the Barz with a single call. It creates the Barz contract with the givent verification facet\"},\"getAddress(address,bytes,uint256)\":{\"notice\":\"Calculates the address of Barz with the given parameters\"},\"getBytecode(address,address,address,address,address,bytes)\":{\"notice\":\"Returns the bytecode of Barz with the given parameter\"},\"getCreationCode()\":{\"notice\":\"Returns the creation code of the Barz contract\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/BarzFactory.sol\":\"BarzFactory\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"contracts/Barz.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {LibDiamond} from \\\"./libraries/LibDiamond.sol\\\";\\nimport {IBarz} from \\\"./interfaces/IBarz.sol\\\";\\n\\n/**\\n * @title Barz\\n * @dev A diamond proxy wallet with a modular & upgradeable architecture\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract Barz is IBarz {\\n /**\\n * @notice Initializes Barz with the given parameters. Barz account is intended to be created from Barz Factory for stable deployment.\\n * @dev This method makes a delegate call to account facet and account facet handles the initialization.\\n * With modular architecture, Barz encompasses wide spectrum of architecture and logic.\\n * The only requirement is account facet to comply with initialize() interface.\\n * Barz doesn't include built-in functions and is a full proxy, for maximum extensibility and modularity.\\n * @param _accountFacet Address of Account Facet in charge of the Barz initialization\\n * @param _verificationFacet Address of Verification Facet for verifying the signature. Could be any signature scheme\\n * @param _entryPoint Address of Entry Point contract\\n * @param _facetRegistry Address of Facet Registry. Facet Registry is a registry holding trusted facets that could be added to user's wallet\\n * @param _defaultFallBack Address of Default FallBack Handler. Middleware contract for more efficient deployment\\n * @param _ownerPublicKey Bytes of Owner Public Key using for initialization\\n */\\n constructor(\\n address _accountFacet,\\n address _verificationFacet,\\n address _entryPoint,\\n address _facetRegistry,\\n address _defaultFallBack,\\n bytes memory _ownerPublicKey\\n ) payable {\\n bytes memory initCall = abi.encodeWithSignature(\\n \\\"initialize(address,address,address,address,bytes)\\\",\\n _verificationFacet,\\n _entryPoint,\\n _facetRegistry,\\n _defaultFallBack,\\n _ownerPublicKey\\n );\\n (bool success, bytes memory result) = _accountFacet.delegatecall(\\n initCall\\n );\\n if (!success || uint256(bytes32(result)) != 1) {\\n revert Barz__InitializationFailure();\\n }\\n }\\n\\n /**\\n * @notice Fallback function for Barz complying with Diamond Standard with customization of adding Default Fallback Handler\\n * @dev Find facet for function that is called and execute the function if a facet is found and return any value.\\n */\\n fallback() external payable {\\n LibDiamond.DiamondStorage storage ds;\\n bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION;\\n // get diamond storage\\n assembly {\\n ds.slot := position\\n }\\n // get facet from function selector\\n address facet = address(bytes20(ds.facets[msg.sig]));\\n if (facet == address(0))\\n facet = ds.defaultFallbackHandler.facetAddress(msg.sig);\\n require(facet != address(0), \\\"Barz: Function does not exist\\\");\\n // Execute external function from facet using delegatecall and return any value.\\n assembly {\\n // copy function selector and any arguments\\n calldatacopy(0, 0, calldatasize())\\n // execute function call using the facet\\n let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)\\n // get any return value\\n returndatacopy(0, 0, returndatasize())\\n // return any return value or error back to the caller\\n switch result\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @notice Receive function to receive native token without data\\n */\\n receive() external payable {}\\n}\\n\",\"keccak256\":\"0xd1c773409a4b3d1ca0316445d9ea1d686bab9cd5f6731fbdb0766a93edfd7bdb\",\"license\":\"Apache-2.0\"},\"contracts/BarzFactory.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {Barz} from \\\"./Barz.sol\\\";\\nimport {IBarzFactory} from \\\"./interfaces/IBarzFactory.sol\\\";\\n\\n/**\\n * @title Barz Factory\\n * @dev Contract to easily deploy Barz to a pre-computed address with a single call\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract BarzFactory is IBarzFactory {\\n address public immutable accountFacet;\\n address public immutable entryPoint;\\n address public immutable facetRegistry;\\n address public immutable defaultFallback;\\n\\n /**\\n * @notice Sets the initialization data for Barz contract initialization\\n * @param _accountFacet Account Facet to be used to create Barz\\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\\n * @param _facetRegistry Facet Registry to be used to create Barz\\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\\n */\\n constructor(\\n address _accountFacet,\\n address _entryPoint,\\n address _facetRegistry,\\n address _defaultFallback\\n ) {\\n accountFacet = _accountFacet;\\n entryPoint = _entryPoint;\\n facetRegistry = _facetRegistry;\\n defaultFallback = _defaultFallback;\\n }\\n\\n /**\\n * @notice Creates the Barz with a single call. It creates the Barz contract with the givent verification facet\\n * @param _verificationFacet Address of verification facet used for creating the barz account\\n * @param _owner Public Key of the owner to initialize barz account\\n * @param _salt Salt used for deploying barz with create2\\n * @return barz Instance of Barz contract deployed with the given parameters\\n */\\n function createAccount(\\n address _verificationFacet,\\n bytes calldata _owner,\\n uint256 _salt\\n ) external override returns (Barz barz) {\\n address addr = getAddress(_verificationFacet, _owner, _salt);\\n uint codeSize = addr.code.length;\\n if (codeSize > 0) {\\n return Barz(payable(addr));\\n }\\n barz = new Barz{salt: bytes32(_salt)}(\\n accountFacet,\\n _verificationFacet,\\n entryPoint,\\n facetRegistry,\\n defaultFallback,\\n _owner\\n );\\n emit BarzDeployed(address(barz));\\n }\\n\\n /**\\n * @notice Calculates the address of Barz with the given parameters\\n * @param _verificationFacet Address of verification facet used for creating the barz account\\n * @param _owner Public Key of the owner to initialize barz account\\n * @param _salt Salt used for deploying barz with create2\\n * @return barzAddress Precalculated Barz address\\n */\\n function getAddress(\\n address _verificationFacet,\\n bytes calldata _owner,\\n uint256 _salt\\n ) public view override returns (address barzAddress) {\\n bytes memory bytecode = getBytecode(\\n accountFacet,\\n _verificationFacet,\\n entryPoint,\\n facetRegistry,\\n defaultFallback,\\n _owner\\n );\\n bytes32 hash = keccak256(\\n abi.encodePacked(\\n bytes1(0xff),\\n address(this),\\n _salt,\\n keccak256(bytecode)\\n )\\n );\\n barzAddress = address(uint160(uint256(hash)));\\n }\\n\\n /**\\n * @notice Returns the bytecode of Barz with the given parameter\\n * @param _accountFacet Account Facet to be used to create Barz\\n * @param _verificationFacet Verification Facet to be used to create Barz\\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\\n * @param _facetRegistry Facet Registry to be used to create Barz\\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\\n * @param _ownerPublicKey Public Key of owner to be used to initialize Barz ownership\\n * @return barzBytecode Bytecode of Barz\\n */\\n function getBytecode(\\n address _accountFacet,\\n address _verificationFacet,\\n address _entryPoint,\\n address _facetRegistry,\\n address _defaultFallback,\\n bytes calldata _ownerPublicKey\\n ) public pure override returns (bytes memory barzBytecode) {\\n bytes memory bytecode = type(Barz).creationCode;\\n barzBytecode = abi.encodePacked(\\n bytecode,\\n abi.encode(\\n _accountFacet,\\n _verificationFacet,\\n _entryPoint,\\n _facetRegistry,\\n _defaultFallback,\\n _ownerPublicKey\\n )\\n );\\n }\\n\\n /**\\n * @notice Returns the creation code of the Barz contract\\n * @return creationCode Creation code of Barz\\n */\\n function getCreationCode()\\n public\\n pure\\n override\\n returns (bytes memory creationCode)\\n {\\n creationCode = type(Barz).creationCode;\\n }\\n}\\n\",\"keccak256\":\"0x76d6058fa4714f5ef87b876e49ce7e21f581164901eea906ec743e82362b1df6\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IBarz.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Barz Interface\\n * @dev Interface of Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IBarz {\\n error Barz__InitializationFailure();\\n}\\n\",\"keccak256\":\"0xca9f0c2c1ad7d06088fa16ae92d587416f2d10d8f999d7afe8ca5c4d73410aba\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IBarzFactory.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {Barz} from \\\"../Barz.sol\\\";\\n\\n/**\\n * @title Barz Factory Interface\\n * @dev Interface of contract to easily deploy Barz to a pre-computed address with a single call\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IBarzFactory {\\n event BarzDeployed(address);\\n\\n function createAccount(\\n address verificationFacet,\\n bytes calldata owner,\\n uint256 salt\\n ) external returns (Barz);\\n\\n function getAddress(\\n address verificationFacet,\\n bytes calldata owner,\\n uint256 salt\\n ) external view returns (address);\\n\\n function getBytecode(\\n address accountFacet,\\n address verificationFacet,\\n address entryPoint,\\n address facetRegistry,\\n address defaultFallback,\\n bytes memory ownerPublicKey\\n ) external pure returns (bytes memory);\\n\\n function getCreationCode() external pure returns (bytes memory);\\n}\\n\",\"keccak256\":\"0xadb48a6f3025f6395e26ffd5f9319da73ad2383906c8223e8455f41f420fba26\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\\n bytes4(keccak256(\\\"verifyRestrictions(address,address,uint256,bytes)\\\"));\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // Default Fallback Handler of the barz.\\n IDiamondLoupe defaultFallbackHandler;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function enforceIsSelf() internal view {\\n require(msg.sender == address(this), \\\"LibDiamond: Caller not self\\\");\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n\\n unchecked {\\n facetIndex++;\\n }\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n\\n function restrictionsFacet() internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(\\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2cabdc00de859c3a3170ce3bda5d0e5fd3933d47ce904fd1585f9818b02572f8\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x61010060405234801561001157600080fd5b50604051610eba380380610eba8339810160408190526100309161006e565b6001600160a01b0393841660805291831660a052821660c0521660e0526100c2565b80516001600160a01b038116811461006957600080fd5b919050565b6000806000806080858703121561008457600080fd5b61008d85610052565b935061009b60208601610052565b92506100a960408601610052565b91506100b760608601610052565b905092959194509250565b60805160a05160c05160e051610d886101326000396000818161013b015281816102b3015261048101526000818160bf01528181610292015261046001526000818161016301528181610271015261043f01526000818161018b0152818161024f015261041d0152610d886000f3fe60806040523480156200001157600080fd5b5060043610620000925760003560e01c806344409a82116200006257806344409a821462000135578063b0d691fe146200015d578063b0f5d4641462000185578063c8a7adf514620001ad57600080fd5b8062c194db14620000975780630a1acd7314620000b9578063296601cd146200010757806333bb64a7146200011e575b600080fd5b620000a1620001c4565b604051620000b091906200056c565b60405180910390f35b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001620000b0565b620000e16200011836600462000635565b6200020e565b620000a16200012f36600462000695565b6200036d565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e1620001be36600462000635565b62000414565b606060405180602001620001d89062000538565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082820381018352601f90910116604052919050565b6000806200021f8686868662000414565b905073ffffffffffffffffffffffffffffffffffffffff81163b8015620002495750905062000365565b8360001b7f0000000000000000000000000000000000000000000000000000000000000000887f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008b8b604051620002e29062000538565b620002f497969594939291906200073a565b8190604051809103906000f590508015801562000315573d6000803e3d6000fd5b5060405173ffffffffffffffffffffffffffffffffffffffff821681529093507f9e6e326008e68f57877e2bae766a5745c162e42359e34834a7f0661fa82d31b19060200160405180910390a150505b949350505050565b6060600060405180602001620003839062000538565b6020820181038252601f19601f8201166040525090508089898989898989604051602001620003b997969594939291906200073a565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052620003f79291602001620007cd565b604051602081830303815290604052915050979650505050505050565b600080620004a87f0000000000000000000000000000000000000000000000000000000000000000877f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008a8a6200036d565b8051602091820120604080517fff00000000000000000000000000000000000000000000000000000000000000818501523060601b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001660218201526035810196909652605580870192909252805180870390920182526075909501909452835193019290922095945050505050565b610552806200080183390190565b60005b838110156200056357818101518382015260200162000549565b50506000910152565b60208152600082518060208401526200058d81604085016020870162000546565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b803573ffffffffffffffffffffffffffffffffffffffff81168114620005e457600080fd5b919050565b60008083601f840112620005fc57600080fd5b50813567ffffffffffffffff8111156200061557600080fd5b6020830191508360208285010111156200062e57600080fd5b9250929050565b600080600080606085870312156200064c57600080fd5b6200065785620005bf565b9350602085013567ffffffffffffffff8111156200067457600080fd5b6200068287828801620005e9565b9598909750949560400135949350505050565b600080600080600080600060c0888a031215620006b157600080fd5b620006bc88620005bf565b9650620006cc60208901620005bf565b9550620006dc60408901620005bf565b9450620006ec60608901620005bf565b9350620006fc60808901620005bf565b925060a088013567ffffffffffffffff8111156200071957600080fd5b620007278a828b01620005e9565b989b979a50959850939692959293505050565b600073ffffffffffffffffffffffffffffffffffffffff808a16835280891660208401528088166040840152808716606084015280861660808401525060c060a08301528260c0830152828460e0840137600060e0848401015260e07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f850116830101905098975050505050505050565b60008351620007e181846020880162000546565b835190830190620007f781836020880162000546565b0194935050505056fe608060405260405161055238038061055283398101604081905261002291610163565b6000858585858560405160240161003d959493929190610264565b60408051601f198184030181529181526020820180516001600160e01b0316634a93641760e01b1790525190915060009081906001600160a01b038a16906100869085906102c3565b600060405180830381855af49150503d80600081146100c1576040519150601f19603f3d011682016040523d82523d6000602084013e6100c6565b606091505b50915091508115806100e157506100dc816102df565b600114155b156100ff57604051636ff35f8960e01b815260040160405180910390fd5b505050505050505050610306565b80516001600160a01b038116811461012457600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101561015a578181015183820152602001610142565b50506000910152565b60008060008060008060c0878903121561017c57600080fd5b6101858761010d565b95506101936020880161010d565b94506101a16040880161010d565b93506101af6060880161010d565b92506101bd6080880161010d565b60a08801519092506001600160401b03808211156101da57600080fd5b818901915089601f8301126101ee57600080fd5b81518181111561020057610200610129565b604051601f8201601f19908116603f0116810190838211818310171561022857610228610129565b816040528281528c602084870101111561024157600080fd5b61025283602083016020880161013f565b80955050505050509295509295509295565b600060018060a01b0380881683528087166020840152808616604084015280851660608401525060a0608083015282518060a08401526102ab8160c085016020870161013f565b601f01601f19169190910160c0019695505050505050565b600082516102d581846020870161013f565b9190910192915050565b80516020808301519190811015610300576000198160200360031b1b821691505b50919050565b61023d806103156000396000f3fe60806040523661000b57005b600080357fffffffff000000000000000000000000000000000000000000000000000000001681527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020819052604090912054819060601c80610125576004838101546040517fcdffacc60000000000000000000000000000000000000000000000000000000081526000357fffffffff00000000000000000000000000000000000000000000000000000000169281019290925273ffffffffffffffffffffffffffffffffffffffff169063cdffacc690602401602060405180830381865afa1580156100fe573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061012291906101ca565b90505b73ffffffffffffffffffffffffffffffffffffffff81166101a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4261727a3a2046756e6374696f6e20646f6573206e6f74206578697374000000604482015260640160405180910390fd5b3660008037600080366000845af43d6000803e8080156101c5573d6000f35b3d6000fd5b6000602082840312156101dc57600080fd5b815173ffffffffffffffffffffffffffffffffffffffff8116811461020057600080fd5b939250505056fea26469706673582212200f3fa76ace3be8675d8b4c0d6c210a922fff2c2f1444023b817d1f6c908cd56a64736f6c63430008150033a2646970667358221220329ad45a4ef4915180001cb1fc90a5f97ad94a0b280426a580cba65fce28c0f164736f6c63430008150033", + "deployedBytecode": "0x60806040523480156200001157600080fd5b5060043610620000925760003560e01c806344409a82116200006257806344409a821462000135578063b0d691fe146200015d578063b0f5d4641462000185578063c8a7adf514620001ad57600080fd5b8062c194db14620000975780630a1acd7314620000b9578063296601cd146200010757806333bb64a7146200011e575b600080fd5b620000a1620001c4565b604051620000b091906200056c565b60405180910390f35b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001620000b0565b620000e16200011836600462000635565b6200020e565b620000a16200012f36600462000695565b6200036d565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e1620001be36600462000635565b62000414565b606060405180602001620001d89062000538565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082820381018352601f90910116604052919050565b6000806200021f8686868662000414565b905073ffffffffffffffffffffffffffffffffffffffff81163b8015620002495750905062000365565b8360001b7f0000000000000000000000000000000000000000000000000000000000000000887f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008b8b604051620002e29062000538565b620002f497969594939291906200073a565b8190604051809103906000f590508015801562000315573d6000803e3d6000fd5b5060405173ffffffffffffffffffffffffffffffffffffffff821681529093507f9e6e326008e68f57877e2bae766a5745c162e42359e34834a7f0661fa82d31b19060200160405180910390a150505b949350505050565b6060600060405180602001620003839062000538565b6020820181038252601f19601f8201166040525090508089898989898989604051602001620003b997969594939291906200073a565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052620003f79291602001620007cd565b604051602081830303815290604052915050979650505050505050565b600080620004a87f0000000000000000000000000000000000000000000000000000000000000000877f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008a8a6200036d565b8051602091820120604080517fff00000000000000000000000000000000000000000000000000000000000000818501523060601b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001660218201526035810196909652605580870192909252805180870390920182526075909501909452835193019290922095945050505050565b610552806200080183390190565b60005b838110156200056357818101518382015260200162000549565b50506000910152565b60208152600082518060208401526200058d81604085016020870162000546565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b803573ffffffffffffffffffffffffffffffffffffffff81168114620005e457600080fd5b919050565b60008083601f840112620005fc57600080fd5b50813567ffffffffffffffff8111156200061557600080fd5b6020830191508360208285010111156200062e57600080fd5b9250929050565b600080600080606085870312156200064c57600080fd5b6200065785620005bf565b9350602085013567ffffffffffffffff8111156200067457600080fd5b6200068287828801620005e9565b9598909750949560400135949350505050565b600080600080600080600060c0888a031215620006b157600080fd5b620006bc88620005bf565b9650620006cc60208901620005bf565b9550620006dc60408901620005bf565b9450620006ec60608901620005bf565b9350620006fc60808901620005bf565b925060a088013567ffffffffffffffff8111156200071957600080fd5b620007278a828b01620005e9565b989b979a50959850939692959293505050565b600073ffffffffffffffffffffffffffffffffffffffff808a16835280891660208401528088166040840152808716606084015280861660808401525060c060a08301528260c0830152828460e0840137600060e0848401015260e07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f850116830101905098975050505050505050565b60008351620007e181846020880162000546565b835190830190620007f781836020880162000546565b0194935050505056fe608060405260405161055238038061055283398101604081905261002291610163565b6000858585858560405160240161003d959493929190610264565b60408051601f198184030181529181526020820180516001600160e01b0316634a93641760e01b1790525190915060009081906001600160a01b038a16906100869085906102c3565b600060405180830381855af49150503d80600081146100c1576040519150601f19603f3d011682016040523d82523d6000602084013e6100c6565b606091505b50915091508115806100e157506100dc816102df565b600114155b156100ff57604051636ff35f8960e01b815260040160405180910390fd5b505050505050505050610306565b80516001600160a01b038116811461012457600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101561015a578181015183820152602001610142565b50506000910152565b60008060008060008060c0878903121561017c57600080fd5b6101858761010d565b95506101936020880161010d565b94506101a16040880161010d565b93506101af6060880161010d565b92506101bd6080880161010d565b60a08801519092506001600160401b03808211156101da57600080fd5b818901915089601f8301126101ee57600080fd5b81518181111561020057610200610129565b604051601f8201601f19908116603f0116810190838211818310171561022857610228610129565b816040528281528c602084870101111561024157600080fd5b61025283602083016020880161013f565b80955050505050509295509295509295565b600060018060a01b0380881683528087166020840152808616604084015280851660608401525060a0608083015282518060a08401526102ab8160c085016020870161013f565b601f01601f19169190910160c0019695505050505050565b600082516102d581846020870161013f565b9190910192915050565b80516020808301519190811015610300576000198160200360031b1b821691505b50919050565b61023d806103156000396000f3fe60806040523661000b57005b600080357fffffffff000000000000000000000000000000000000000000000000000000001681527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020819052604090912054819060601c80610125576004838101546040517fcdffacc60000000000000000000000000000000000000000000000000000000081526000357fffffffff00000000000000000000000000000000000000000000000000000000169281019290925273ffffffffffffffffffffffffffffffffffffffff169063cdffacc690602401602060405180830381865afa1580156100fe573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061012291906101ca565b90505b73ffffffffffffffffffffffffffffffffffffffff81166101a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4261727a3a2046756e6374696f6e20646f6573206e6f74206578697374000000604482015260640160405180910390fd5b3660008037600080366000845af43d6000803e8080156101c5573d6000f35b3d6000fd5b6000602082840312156101dc57600080fd5b815173ffffffffffffffffffffffffffffffffffffffff8116811461020057600080fd5b939250505056fea26469706673582212200f3fa76ace3be8675d8b4c0d6c210a922fff2c2f1444023b817d1f6c908cd56a64736f6c63430008150033a2646970667358221220329ad45a4ef4915180001cb1fc90a5f97ad94a0b280426a580cba65fce28c0f164736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "Contract to easily deploy Barz to a pre-computed address with a single call", + "kind": "dev", + "methods": { + "constructor": { + "params": { + "_accountFacet": "Account Facet to be used to create Barz", + "_defaultFallback": "Default Fallback Handler to be used to create Barz", + "_entryPoint": "Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF", + "_facetRegistry": "Facet Registry to be used to create Barz" + } + }, + "createAccount(address,bytes,uint256)": { + "params": { + "_owner": "Public Key of the owner to initialize barz account", + "_salt": "Salt used for deploying barz with create2", + "_verificationFacet": "Address of verification facet used for creating the barz account" + }, + "returns": { + "barz": "Instance of Barz contract deployed with the given parameters" + } + }, + "getAddress(address,bytes,uint256)": { + "params": { + "_owner": "Public Key of the owner to initialize barz account", + "_salt": "Salt used for deploying barz with create2", + "_verificationFacet": "Address of verification facet used for creating the barz account" + }, + "returns": { + "barzAddress": "Precalculated Barz address" + } + }, + "getBytecode(address,address,address,address,address,bytes)": { + "params": { + "_accountFacet": "Account Facet to be used to create Barz", + "_defaultFallback": "Default Fallback Handler to be used to create Barz", + "_entryPoint": "Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF", + "_facetRegistry": "Facet Registry to be used to create Barz", + "_ownerPublicKey": "Public Key of owner to be used to initialize Barz ownership", + "_verificationFacet": "Verification Facet to be used to create Barz" + }, + "returns": { + "barzBytecode": "Bytecode of Barz" + } + }, + "getCreationCode()": { + "returns": { + "creationCode": "Creation code of Barz" + } + } + }, + "title": "Barz Factory", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "constructor": { + "notice": "Sets the initialization data for Barz contract initialization" + }, + "createAccount(address,bytes,uint256)": { + "notice": "Creates the Barz with a single call. It creates the Barz contract with the givent verification facet" + }, + "getAddress(address,bytes,uint256)": { + "notice": "Calculates the address of Barz with the given parameters" + }, + "getBytecode(address,address,address,address,address,bytes)": { + "notice": "Returns the bytecode of Barz with the given parameter" + }, + "getCreationCode()": { + "notice": "Returns the creation code of the Barz contract" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/base/DefaultFallbackHandler.json b/deployments/base/DefaultFallbackHandler.json new file mode 100644 index 0000000..fae56ed --- /dev/null +++ b/deployments/base/DefaultFallbackHandler.json @@ -0,0 +1,275 @@ +{ + "address": "0x2e7f1dAe1F3799d20f5c31bEFdc7A620f664728D", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_diamondCutFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_accountFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_tokenReceiverFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_diamondLoupeFacet", + "type": "address" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_initializationContractAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "InitializationFunctionReverted", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "indexed": false, + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "DiamondCut", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_functionSelector", + "type": "bytes4" + } + ], + "name": "facetAddress", + "outputs": [ + { + "internalType": "address", + "name": "facetAddress_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetAddresses", + "outputs": [ + { + "internalType": "address[]", + "name": "facetAddresses_", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_facet", + "type": "address" + } + ], + "name": "facetFunctionSelectors", + "outputs": [ + { + "internalType": "bytes4[]", + "name": "facetFunctionSelectors_", + "type": "bytes4[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facets", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondLoupe.Facet[]", + "name": "facets_", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0xda230cb91db5ef27dd8f37af14ef2dcf8d63120694f16cc654e5718ba8bbd121", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 2, + "gasUsed": "1438535", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000001000000000800002000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000", + "blockHash": "0xf7be0bdf36c0c1a531b6e2210265215119571567e4f5677bf6c08fcd98950cd4", + "transactionHash": "0xda230cb91db5ef27dd8f37af14ef2dcf8d63120694f16cc654e5718ba8bbd121", + "logs": [ + { + "transactionIndex": 2, + "blockNumber": 6847791, + "transactionHash": "0xda230cb91db5ef27dd8f37af14ef2dcf8d63120694f16cc654e5718ba8bbd121", + "address": "0x2e7f1dAe1F3799d20f5c31bEFdc7A620f664728D", + "topics": [ + "0x8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb673" + ], + "data": "0x000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000580000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000000000000000000000000000000000003600000000000000000000000000b9504140771c3688ff041917192277d2f52e1e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000011f931c1c00000000000000000000000000000000000000000000000000000000000000000000000000000000fde53272dcd7938d16e031a6989753c321728332000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000005b61d27f60000000000000000000000000000000000000000000000000000000047e1da2a000000000000000000000000000000000000000000000000000000003a871cdd00000000000000000000000000000000000000000000000000000000d087d28800000000000000000000000000000000000000000000000000000000b0d691fe000000000000000000000000000000000000000000000000000000000000000000000000000000003143e1c0af0cdc153423863923cf4e3818e34daa000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000005150b7a0200000000000000000000000000000000000000000000000000000000f23a6e6100000000000000000000000000000000000000000000000000000000bc197c81000000000000000000000000000000000000000000000000000000000023de2900000000000000000000000000000000000000000000000000000000a4c0ed3600000000000000000000000000000000000000000000000000000000000000000000000000000000ce36b85d12d81cd619c745c7717f3396e184ac7c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000097a0ed62700000000000000000000000000000000000000000000000000000000adfca15e0000000000000000000000000000000000000000000000000000000052ef6b2c00000000000000000000000000000000000000000000000000000000cdffacc60000000000000000000000000000000000000000000000000000000001ffc9a700000000000000000000000000000000000000000000000000000000f9796ccf0000000000000000000000000000000000000000000000000000000001a5502200000000000000000000000000000000000000000000000000000000d42139a900000000000000000000000000000000000000000000000000000000e3a2f6fe000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "logIndex": 4, + "blockHash": "0xf7be0bdf36c0c1a531b6e2210265215119571567e4f5677bf6c08fcd98950cd4" + } + ], + "blockNumber": 6847791, + "cumulativeGasUsed": "1720128", + "status": 1, + "byzantium": true + }, + "args": [ + "0x0B9504140771C3688Ff041917192277D2f52E1e0", + "0xFde53272dcd7938d16E031A6989753c321728332", + "0x3143E1C0Af0Cdc153423863923Cf4e3818e34Daa", + "0xCe36b85d12D81cd619C745c7717f3396E184Ac7C" + ], + "numDeployments": 3, + "solcInputHash": "4356503edd8ae34e73cb6dd1c8e2fc8a", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_diamondCutFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_accountFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_tokenReceiverFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_diamondLoupeFacet\",\"type\":\"address\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_initializationContractAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"InitializationFunctionReverted\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"DiamondCut\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_functionSelector\",\"type\":\"bytes4\"}],\"name\":\"facetAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"facetAddress_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetAddresses\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"facetAddresses_\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_facet\",\"type\":\"address\"}],\"name\":\"facetFunctionSelectors\",\"outputs\":[{\"internalType\":\"bytes4[]\",\"name\":\"facetFunctionSelectors_\",\"type\":\"bytes4[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facets\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondLoupe.Facet[]\",\"name\":\"facets_\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"A default fallback handler for Barz\",\"kind\":\"dev\",\"methods\":{\"constructor\":{\"details\":\"This contract is also a diamond that holds the default facets to reduce gas cost for wallet activation. Within the constructor this conducts diamond cut to initially setup the diamond. This is a non-upgradeable contract\",\"params\":{\"_accountFacet\":\"Address account facet\",\"_diamondCutFacet\":\"Address if diamond cut facet\",\"_diamondLoupeFacet\":\"Address of diamond loupe facet\",\"_tokenReceiverFacet\":\"Address of token receiver facet\"}},\"facetAddress(bytes4)\":{\"details\":\"If facet is not found return address(0).\",\"params\":{\"_functionSelector\":\"The function selector.\"},\"returns\":{\"facetAddress_\":\"The facet address.\"}},\"facetAddresses()\":{\"returns\":{\"facetAddresses_\":\"facetAddresses_\"}},\"facetFunctionSelectors(address)\":{\"params\":{\"_facet\":\"The facet address.\"},\"returns\":{\"facetFunctionSelectors_\":\"facetFunctionSelectors_\"}},\"facets()\":{\"returns\":{\"facets_\":\"The facet struct array including all facet information\"}}},\"title\":\"DefaultFallbackHandler\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"Sets the middleware diamond for Barz wallet as a fallback handler\"},\"facetAddress(bytes4)\":{\"notice\":\"Gets the facet that supports the given selector.\"},\"facetAddresses()\":{\"notice\":\"Get all the facet addresses used by a diamond.\"},\"facetFunctionSelectors(address)\":{\"notice\":\"Gets all the function selectors provided by a facet.\"},\"facets()\":{\"notice\":\"Returns the facet information of call facets registered to this diamond.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/infrastructure/DefaultFallbackHandler.sol\":\"DefaultFallbackHandler\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/introspection/IERC165.sol\\\";\\n\\n/**\\n * @dev _Available since v3.1._\\n */\\ninterface IERC1155Receiver is IERC165 {\\n /**\\n * @dev Handles the receipt of a single ERC1155 token type. This function is\\n * called at the end of a `safeTransferFrom` after the balance has been updated.\\n *\\n * NOTE: To accept the transfer, this must return\\n * `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))`\\n * (i.e. 0xf23a6e61, or its own function selector).\\n *\\n * @param operator The address which initiated the transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param id The ID of the token being transferred\\n * @param value The amount of tokens being transferred\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155Received(\\n address operator,\\n address from,\\n uint256 id,\\n uint256 value,\\n bytes calldata data\\n ) external returns (bytes4);\\n\\n /**\\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\\n * is called at the end of a `safeBatchTransferFrom` after the balances have\\n * been updated.\\n *\\n * NOTE: To accept the transfer(s), this must return\\n * `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))`\\n * (i.e. 0xbc197c81, or its own function selector).\\n *\\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155BatchReceived(\\n address operator,\\n address from,\\n uint256[] calldata ids,\\n uint256[] calldata values,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xeb373f1fdc7b755c6a750123a9b9e3a8a02c1470042fd6505d875000a80bde0b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title ERC721 token receiver interface\\n * @dev Interface for any contract that wants to support safeTransfers\\n * from ERC721 asset contracts.\\n */\\ninterface IERC721Receiver {\\n /**\\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\\n * by `operator` from `from`, this function is called.\\n *\\n * It must return its Solidity selector to confirm the token transfer.\\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\\n *\\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\\n */\\n function onERC721Received(\\n address operator,\\n address from,\\n uint256 tokenId,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\\n *\\n * Accounts can be notified of {IERC777} tokens being sent to them by having a\\n * contract implement this interface (contract holders can be their own\\n * implementer) and registering it on the\\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\\n *\\n * See {IERC1820Registry} and {ERC1820Implementer}.\\n */\\ninterface IERC777Recipient {\\n /**\\n * @dev Called by an {IERC777} token contract whenever tokens are being\\n * moved or created into a registered account (`to`). The type of operation\\n * is conveyed by `from` being the zero address or not.\\n *\\n * This call occurs _after_ the token contract's state is updated, so\\n * {IERC777-balanceOf}, etc., can be used to query the post-operation state.\\n *\\n * This function may revert to prevent the operation from being executed.\\n */\\n function tokensReceived(\\n address operator,\\n address from,\\n address to,\\n uint256 amount,\\n bytes calldata userData,\\n bytes calldata operatorData\\n ) external;\\n}\\n\",\"keccak256\":\"0x1a5d61db2733202ba361e6d6741cd2e662380e22b80e987eacfc91973f2267dc\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"contracts/aa-4337/core/BaseAccount.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-empty-blocks */\\n\\nimport \\\"../interfaces/IAccount.sol\\\";\\nimport \\\"../interfaces/IEntryPoint.sol\\\";\\nimport \\\"./Helpers.sol\\\";\\n\\n/**\\n * Basic account implementation.\\n * this contract provides the basic logic for implementing the IAccount interface - validateUserOp\\n * specific account implementation should inherit it and provide the account-specific logic\\n */\\nabstract contract BaseAccount is IAccount {\\n using UserOperationLib for UserOperation;\\n\\n //return value in case of signature failure, with no time-range.\\n // equivalent to _packValidationData(true,0,0);\\n uint256 internal constant SIG_VALIDATION_FAILED = 1;\\n\\n /**\\n * Return the account nonce.\\n * This method returns the next sequential nonce.\\n * For a nonce of a specific key, use `entrypoint.getNonce(account, key)`\\n */\\n function getNonce() public view virtual returns (uint256) {\\n return entryPoint().getNonce(address(this), 0);\\n }\\n\\n /**\\n * return the entryPoint used by this account.\\n * subclass should return the current entryPoint used by this account.\\n */\\n function entryPoint() public view virtual returns (IEntryPoint);\\n\\n /**\\n * Validate user's signature and nonce.\\n * subclass doesn't need to override this method. Instead, it should override the specific internal validation methods.\\n */\\n function validateUserOp(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n uint256 missingAccountFunds\\n ) external virtual override returns (uint256 validationData) {\\n _requireFromEntryPoint();\\n validationData = _validateSignature(userOp, userOpHash);\\n _validateNonce(userOp.nonce);\\n _payPrefund(missingAccountFunds);\\n }\\n\\n /**\\n * ensure the request comes from the known entrypoint.\\n */\\n function _requireFromEntryPoint() internal view virtual {\\n require(\\n msg.sender == address(entryPoint()),\\n \\\"account: not from EntryPoint\\\"\\n );\\n }\\n\\n /**\\n * validate the signature is valid for this message.\\n * @param userOp validate the userOp.signature field\\n * @param userOpHash convenient field: the hash of the request, to check the signature against\\n * (also hashes the entrypoint and chain id)\\n * @return validationData signature and time-range of this operation\\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\\n * otherwise, an address of an \\\"authorizer\\\" contract.\\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \\\"indefinite\\\"\\n * <6-byte> validAfter - first timestamp this operation is valid\\n * If the account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\\n */\\n function _validateSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) internal virtual returns (uint256 validationData);\\n\\n /**\\n * Validate the nonce of the UserOperation.\\n * This method may validate the nonce requirement of this account.\\n * e.g.\\n * To limit the nonce to use sequenced UserOps only (no \\\"out of order\\\" UserOps):\\n * `require(nonce < type(uint64).max)`\\n * For a hypothetical account that *requires* the nonce to be out-of-order:\\n * `require(nonce & type(uint64).max == 0)`\\n *\\n * The actual nonce uniqueness is managed by the EntryPoint, and thus no other\\n * action is needed by the account itself.\\n *\\n * @param nonce to validate\\n *\\n * solhint-disable-next-line no-empty-blocks\\n */\\n function _validateNonce(uint256 nonce) internal view virtual {}\\n\\n /**\\n * sends to the entrypoint (msg.sender) the missing funds for this transaction.\\n * subclass MAY override this method for better funds management\\n * (e.g. send to the entryPoint more than the minimum required, so that in future transactions\\n * it will not be required to send again)\\n * @param missingAccountFunds the minimum value this method should send the entrypoint.\\n * this value MAY be zero, in case there is enough deposit, or the userOp has a paymaster.\\n */\\n function _payPrefund(uint256 missingAccountFunds) internal virtual {\\n if (missingAccountFunds != 0) {\\n (bool success, ) = payable(msg.sender).call{\\n value: missingAccountFunds,\\n gas: type(uint256).max\\n }(\\\"\\\");\\n (success);\\n //ignore failure (its EntryPoint's job to verify, not account.)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa0dcc386b0f04711db3e394fb50e55a3b3b1a4d19fac1f10895844e1aa4e3d5c\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/core/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable no-inline-assembly */\\n\\n/**\\n * returned data from validateUserOp.\\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\\n * @param aggregator - address(0) - the account validated the signature by itself.\\n * address(1) - the account failed to validate the signature.\\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\\n * @param validAfter - this UserOp is valid only after this timestamp.\\n * @param validaUntil - this UserOp is valid only up to this timestamp.\\n */\\nstruct ValidationData {\\n address aggregator;\\n uint48 validAfter;\\n uint48 validUntil;\\n}\\n\\n//extract sigFailed, validAfter, validUntil.\\n// also convert zero validUntil to type(uint48).max\\nfunction _parseValidationData(\\n uint validationData\\n) pure returns (ValidationData memory data) {\\n address aggregator = address(uint160(validationData));\\n uint48 validUntil = uint48(validationData >> 160);\\n if (validUntil == 0) {\\n validUntil = type(uint48).max;\\n }\\n uint48 validAfter = uint48(validationData >> (48 + 160));\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n// intersect account and paymaster ranges.\\nfunction _intersectTimeRange(\\n uint256 validationData,\\n uint256 paymasterValidationData\\n) pure returns (ValidationData memory) {\\n ValidationData memory accountValidationData = _parseValidationData(\\n validationData\\n );\\n ValidationData memory pmValidationData = _parseValidationData(\\n paymasterValidationData\\n );\\n address aggregator = accountValidationData.aggregator;\\n if (aggregator == address(0)) {\\n aggregator = pmValidationData.aggregator;\\n }\\n uint48 validAfter = accountValidationData.validAfter;\\n uint48 validUntil = accountValidationData.validUntil;\\n uint48 pmValidAfter = pmValidationData.validAfter;\\n uint48 pmValidUntil = pmValidationData.validUntil;\\n\\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp\\n * @param data - the ValidationData to pack\\n */\\nfunction _packValidationData(\\n ValidationData memory data\\n) pure returns (uint256) {\\n return\\n uint160(data.aggregator) |\\n (uint256(data.validUntil) << 160) |\\n (uint256(data.validAfter) << (160 + 48));\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp, when not using an aggregator\\n * @param sigFailed - true for signature failure, false for success\\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\\n * @param validAfter first timestamp this UserOperation is valid\\n */\\nfunction _packValidationData(\\n bool sigFailed,\\n uint48 validUntil,\\n uint48 validAfter\\n) pure returns (uint256) {\\n return\\n (sigFailed ? 1 : 0) |\\n (uint256(validUntil) << 160) |\\n (uint256(validAfter) << (160 + 48));\\n}\\n\\n/**\\n * keccak function over calldata.\\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\\n */\\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\\n assembly {\\n let mem := mload(0x40)\\n let len := data.length\\n calldatacopy(mem, data.offset, len)\\n ret := keccak256(mem, len)\\n }\\n}\\n\",\"keccak256\":\"0xa79f06cd158ecb8c0da95493a2f348933b8627a63e228b99738bff3aa107942d\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAccount.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\ninterface IAccount {\\n /**\\n * Validate user's signature and nonce\\n * the entryPoint will make the call to the recipient only if this validation call returns successfully.\\n * signature failure should be reported by returning SIG_VALIDATION_FAILED (1).\\n * This allows making a \\\"simulation call\\\" without a valid signature\\n * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure.\\n *\\n * @dev Must validate caller is the entryPoint.\\n * Must validate the signature and nonce\\n * @param userOp the operation that is about to be executed.\\n * @param userOpHash hash of the user's request data. can be used as the basis for signature.\\n * @param missingAccountFunds missing funds on the account's deposit in the entrypoint.\\n * This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call.\\n * The excess is left as a deposit in the entrypoint, for future calls.\\n * can be withdrawn anytime using \\\"entryPoint.withdrawTo()\\\"\\n * In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero.\\n * @return validationData packaged ValidationData structure. use `_packValidationData` and `_unpackValidationData` to encode and decode\\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\\n * otherwise, an address of an \\\"authorizer\\\" contract.\\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \\\"indefinite\\\"\\n * <6-byte> validAfter - first timestamp this operation is valid\\n * If an account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\\n */\\n function validateUserOp(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n uint256 missingAccountFunds\\n ) external returns (uint256 validationData);\\n}\\n\",\"keccak256\":\"0xcbc4b0973cf954c5895b7796335f651fbfcfb55f67dfa789a3d354f8e23c4f2b\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAggregator.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\n/**\\n * Aggregated Signatures validator.\\n */\\ninterface IAggregator {\\n /**\\n * validate aggregated signature.\\n * revert if the aggregated signature does not match the given list of operations.\\n */\\n function validateSignatures(\\n UserOperation[] calldata userOps,\\n bytes calldata signature\\n ) external view;\\n\\n /**\\n * validate signature of a single userOp\\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\\n * @param userOp the userOperation received from the user.\\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\\n * (usually empty, unless account and aggregator support some kind of \\\"multisig\\\"\\n */\\n function validateUserOpSignature(\\n UserOperation calldata userOp\\n ) external view returns (bytes memory sigForUserOp);\\n\\n /**\\n * aggregate multiple signatures into a single value.\\n * This method is called off-chain to calculate the signature to pass with handleOps()\\n * bundler MAY use optimized custom code perform this aggregation\\n * @param userOps array of UserOperations to collect the signatures from.\\n * @return aggregatedSignature the aggregated signature\\n */\\n function aggregateSignatures(\\n UserOperation[] calldata userOps\\n ) external view returns (bytes memory aggregatedSignature);\\n}\\n\",\"keccak256\":\"0xdfdcd80568f037716674619b31be630fcd8316262f05a815b41d1e81782c966a\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IEntryPoint.sol\":{\"content\":\"/**\\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\\n ** Only one instance required on each chain.\\n **/\\n// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-inline-assembly */\\n/* solhint-disable reason-string */\\n\\nimport \\\"./UserOperation.sol\\\";\\nimport \\\"./IStakeManager.sol\\\";\\nimport \\\"./IAggregator.sol\\\";\\nimport \\\"./INonceManager.sol\\\";\\n\\ninterface IEntryPoint is IStakeManager, INonceManager {\\n /***\\n * An event emitted after each successful request\\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\\n * @param sender - the account that generates this request.\\n * @param paymaster - if non-null, the paymaster that pays for this request.\\n * @param nonce - the nonce value from the request.\\n * @param success - true if the sender transaction succeeded, false if reverted.\\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\\n */\\n event UserOperationEvent(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address indexed paymaster,\\n uint256 nonce,\\n bool success,\\n uint256 actualGasCost,\\n uint256 actualGasUsed\\n );\\n\\n /**\\n * account \\\"sender\\\" was deployed.\\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\\n * @param sender the account that is deployed\\n * @param factory the factory used to deploy this account (in the initCode)\\n * @param paymaster the paymaster used by this UserOp\\n */\\n event AccountDeployed(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address factory,\\n address paymaster\\n );\\n\\n /**\\n * An event emitted if the UserOperation \\\"callData\\\" reverted with non-zero length\\n * @param userOpHash the request unique identifier.\\n * @param sender the sender of this request\\n * @param nonce the nonce used in the request\\n * @param revertReason - the return bytes from the (reverted) call to \\\"callData\\\".\\n */\\n event UserOperationRevertReason(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n uint256 nonce,\\n bytes revertReason\\n );\\n\\n /**\\n * an event emitted by handleOps(), before starting the execution loop.\\n * any event emitted before this event, is part of the validation.\\n */\\n event BeforeExecution();\\n\\n /**\\n * signature aggregator used by the following UserOperationEvents within this bundle.\\n */\\n event SignatureAggregatorChanged(address indexed aggregator);\\n\\n /**\\n * a custom revert error of handleOps, to identify the offending op.\\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\\n * @param reason - revert reason\\n * The string starts with a unique code \\\"AAmn\\\", where \\\"m\\\" is \\\"1\\\" for factory, \\\"2\\\" for account and \\\"3\\\" for paymaster issues,\\n * so a failure can be attributed to the correct entity.\\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\\n */\\n error FailedOp(uint256 opIndex, string reason);\\n\\n /**\\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\\n */\\n error SignatureValidationFailed(address aggregator);\\n\\n /**\\n * Successful result from simulateValidation.\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n */\\n error ValidationResult(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo\\n );\\n\\n /**\\n * Successful result from simulateValidation, if the account returns a signature aggregator\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\\n * bundler MUST use it to verify the signature, or reject the UserOperation\\n */\\n error ValidationResultWithAggregation(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo,\\n AggregatorStakeInfo aggregatorInfo\\n );\\n\\n /**\\n * return value of getSenderAddress\\n */\\n error SenderAddressResult(address sender);\\n\\n /**\\n * return value of simulateHandleOp\\n */\\n error ExecutionResult(\\n uint256 preOpGas,\\n uint256 paid,\\n uint48 validAfter,\\n uint48 validUntil,\\n bool targetSuccess,\\n bytes targetResult\\n );\\n\\n //UserOps handled, per aggregator\\n struct UserOpsPerAggregator {\\n UserOperation[] userOps;\\n // aggregator address\\n IAggregator aggregator;\\n // aggregated signature\\n bytes signature;\\n }\\n\\n /**\\n * Execute a batch of UserOperation.\\n * no signature aggregator is used.\\n * if any account requires an aggregator (that is, it returned an aggregator when\\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\\n * @param ops the operations to execute\\n * @param beneficiary the address to receive the fees\\n */\\n function handleOps(\\n UserOperation[] calldata ops,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * Execute a batch of UserOperation with Aggregators\\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\\n * @param beneficiary the address to receive the fees\\n */\\n function handleAggregatedOps(\\n UserOpsPerAggregator[] calldata opsPerAggregator,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * generate a request Id - unique identifier for this request.\\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\\n */\\n function getUserOpHash(\\n UserOperation calldata userOp\\n ) external view returns (bytes32);\\n\\n /**\\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\\n * @param userOp the user operation to validate.\\n */\\n function simulateValidation(UserOperation calldata userOp) external;\\n\\n /**\\n * gas and return values during simulation\\n * @param preOpGas the gas used for validation (including preValidationGas)\\n * @param prefund the required prefund for this operation\\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\\n */\\n struct ReturnInfo {\\n uint256 preOpGas;\\n uint256 prefund;\\n bool sigFailed;\\n uint48 validAfter;\\n uint48 validUntil;\\n bytes paymasterContext;\\n }\\n\\n /**\\n * returned aggregated signature info.\\n * the aggregator returned by the account, and its current stake.\\n */\\n struct AggregatorStakeInfo {\\n address aggregator;\\n StakeInfo stakeInfo;\\n }\\n\\n /**\\n * Get counterfactual sender address.\\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\\n * this method always revert, and returns the address in SenderAddressResult error\\n * @param initCode the constructor code to be passed into the UserOperation.\\n */\\n function getSenderAddress(bytes memory initCode) external;\\n\\n /**\\n * simulate full execution of a UserOperation (including both validation and target execution)\\n * this method will always revert with \\\"ExecutionResult\\\".\\n * it performs full validation of the UserOperation, but ignores signature error.\\n * an optional target address is called after the userop succeeds, and its value is returned\\n * (before the entire call is reverted)\\n * Note that in order to collect the the success/failure of the target call, it must be executed\\n * with trace enabled to track the emitted events.\\n * @param op the UserOperation to simulate\\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\\n * are set to the return from that call.\\n * @param targetCallData callData to pass to target address\\n */\\n function simulateHandleOp(\\n UserOperation calldata op,\\n address target,\\n bytes calldata targetCallData\\n ) external;\\n}\\n\",\"keccak256\":\"0x9ccb1b188eda8bbf5f6c2d01bd83c3d8b2b04fcf745283051d31fe96d1d8e40f\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/INonceManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\ninterface INonceManager {\\n /**\\n * Return the next nonce for this sender.\\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\\n * But UserOp with different keys can come with arbitrary order.\\n *\\n * @param sender the account address\\n * @param key the high 192 bit of the nonce\\n * @return nonce a full nonce to pass for next UserOp with this sender.\\n */\\n function getNonce(\\n address sender,\\n uint192 key\\n ) external view returns (uint256 nonce);\\n\\n /**\\n * Manually increment the nonce of the sender.\\n * This method is exposed just for completeness..\\n * Account does NOT need to call it, neither during validation, nor elsewhere,\\n * as the EntryPoint will update the nonce regardless.\\n * Possible use-case is call it with various keys to \\\"initialize\\\" their nonces to one, so that future\\n * UserOperations will not pay extra for the first transaction with a given key.\\n */\\n function incrementNonce(uint192 key) external;\\n}\\n\",\"keccak256\":\"0xce478ad0fa0d18a3b785ac854623029e7ab463d05873dfaa365abfa1bf100912\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IStakeManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8.12;\\n\\n/**\\n * manage deposits and stakes.\\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\\n * stake is value locked for at least \\\"unstakeDelay\\\" by the staked entity.\\n */\\ninterface IStakeManager {\\n event Deposited(address indexed account, uint256 totalDeposit);\\n\\n event Withdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /// Emitted when stake or unstake delay are modified\\n event StakeLocked(\\n address indexed account,\\n uint256 totalStaked,\\n uint256 unstakeDelaySec\\n );\\n\\n /// Emitted once a stake is scheduled for withdrawal\\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\\n\\n event StakeWithdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /**\\n * @param deposit the entity's deposit\\n * @param staked true if this entity is staked.\\n * @param stake actual amount of ether staked for this entity.\\n * @param unstakeDelaySec minimum delay to withdraw the stake.\\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\\n * and the rest fit into a 2nd cell.\\n * 112 bit allows for 10^15 eth\\n * 48 bit for full timestamp\\n * 32 bit allows 150 years for unstake delay\\n */\\n struct DepositInfo {\\n uint112 deposit;\\n bool staked;\\n uint112 stake;\\n uint32 unstakeDelaySec;\\n uint48 withdrawTime;\\n }\\n\\n //API struct used by getStakeInfo and simulateValidation\\n struct StakeInfo {\\n uint256 stake;\\n uint256 unstakeDelaySec;\\n }\\n\\n /// @return info - full deposit information of given account\\n function getDepositInfo(\\n address account\\n ) external view returns (DepositInfo memory info);\\n\\n /// @return the deposit (for gas payment) of the account\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * add to the deposit of the given account\\n */\\n function depositTo(address account) external payable;\\n\\n /**\\n * add to the account's stake - amount and delay\\n * any pending unstake is first cancelled.\\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\\n */\\n function addStake(uint32 _unstakeDelaySec) external payable;\\n\\n /**\\n * attempt to unlock the stake.\\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\\n */\\n function unlockStake() external;\\n\\n /**\\n * withdraw from the (unlocked) stake.\\n * must first call unlockStake and wait for the unstakeDelay to pass\\n * @param withdrawAddress the address to send withdrawn value.\\n */\\n function withdrawStake(address payable withdrawAddress) external;\\n\\n /**\\n * withdraw from the deposit.\\n * @param withdrawAddress the address to send withdrawn value.\\n * @param withdrawAmount the amount to withdraw.\\n */\\n function withdrawTo(\\n address payable withdrawAddress,\\n uint256 withdrawAmount\\n ) external;\\n}\\n\",\"keccak256\":\"0xadcea606c9b7aafe6645441f2154a60f271330b0eee5292a632aa71c1672d546\",\"license\":\"GPL-3.0-only\"},\"contracts/aa-4337/interfaces/UserOperation.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable no-inline-assembly */\\n\\nimport {calldataKeccak} from \\\"../core/Helpers.sol\\\";\\n\\n/**\\n * User Operation struct\\n * @param sender the sender account of this request.\\n * @param nonce unique value the sender uses to verify it is not a replay.\\n * @param initCode if set, the account contract will be created by this constructor/\\n * @param callData the method call to execute on this account.\\n * @param callGasLimit the gas limit passed to the callData method call.\\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\\n * @param maxFeePerGas same as EIP-1559 gas parameter.\\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\\n */\\nstruct UserOperation {\\n address sender;\\n uint256 nonce;\\n bytes initCode;\\n bytes callData;\\n uint256 callGasLimit;\\n uint256 verificationGasLimit;\\n uint256 preVerificationGas;\\n uint256 maxFeePerGas;\\n uint256 maxPriorityFeePerGas;\\n bytes paymasterAndData;\\n bytes signature;\\n}\\n\\n/**\\n * Utility functions helpful when working with UserOperation structs.\\n */\\nlibrary UserOperationLib {\\n function getSender(\\n UserOperation calldata userOp\\n ) internal pure returns (address) {\\n address data;\\n //read sender from userOp, which is first userOp member (saves 800 gas...)\\n assembly {\\n data := calldataload(userOp)\\n }\\n return address(uint160(data));\\n }\\n\\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\\n // pay above what he signed for.\\n function gasPrice(\\n UserOperation calldata userOp\\n ) internal view returns (uint256) {\\n unchecked {\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n if (maxFeePerGas == maxPriorityFeePerGas) {\\n //legacy mode (for networks that don't support basefee opcode)\\n return maxFeePerGas;\\n }\\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\\n }\\n }\\n\\n function pack(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes memory ret) {\\n address sender = getSender(userOp);\\n uint256 nonce = userOp.nonce;\\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\\n bytes32 hashCallData = calldataKeccak(userOp.callData);\\n uint256 callGasLimit = userOp.callGasLimit;\\n uint256 verificationGasLimit = userOp.verificationGasLimit;\\n uint256 preVerificationGas = userOp.preVerificationGas;\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\\n\\n return\\n abi.encode(\\n sender,\\n nonce,\\n hashInitCode,\\n hashCallData,\\n callGasLimit,\\n verificationGasLimit,\\n preVerificationGas,\\n maxFeePerGas,\\n maxPriorityFeePerGas,\\n hashPaymasterAndData\\n );\\n }\\n\\n function hash(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes32) {\\n return keccak256(pack(userOp));\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n}\\n\",\"keccak256\":\"0x2429f5cc546bdee08c7e63858d0dda8491eaa3ab5194df884dc948c1154d2834\",\"license\":\"GPL-3.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IStorageLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"./IDiamondLoupe.sol\\\";\\n\\n/**\\n * @title LoupeFromStorage Interface\\n * @dev Interface contract to function as a loupe facet directly attached to diamond storage of Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IStorageLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facetsFromStorage()\\n external\\n view\\n returns (IDiamondLoupe.Facet[] memory);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n function facetFunctionSelectorsFromStorage(\\n address _facet\\n ) external view returns (bytes4[] memory);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n function facetAddressesFromStorage()\\n external\\n view\\n returns (address[] memory);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n function facetAddressFromStorage(\\n bytes4 _functionSelector\\n ) external view returns (address);\\n}\\n\",\"keccak256\":\"0xdf5dc9c57319e9087628c9cf9404b4f75585b76d1c2f4f59ee796c933967ea5c\",\"license\":\"Apache-2.0\"},\"contracts/facets/interfaces/IAccountFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IEntryPoint} from \\\"../../aa-4337/interfaces/IEntryPoint.sol\\\";\\n\\n/**\\n * @title Account Facet Interface\\n * @dev Interface of module contract that provides the account features and init/unitialization of signer\\n * compatible with EIP-1271 & EIP-4337\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IAccountFacet {\\n event AccountInitialized(\\n IEntryPoint indexed entryPoint,\\n bytes indexed ownerPublicKey\\n );\\n // NOTE: Added Below Event\\n event VerificationSuccess(bytes32);\\n event VerificationFailure(bytes32);\\n\\n error AccountFacet__InitializationFailure();\\n error AccountFacet__RestrictionsFailure();\\n error AccountFacet__NonExistentVerificationFacet();\\n error AccountFacet__CallNotSuccessful();\\n error AccountFacet__InvalidArrayLength();\\n\\n function initialize(\\n address verificationFacet,\\n address anEntryPoint,\\n address facetRegistry,\\n address _defaultFallBack,\\n bytes calldata _ownerPublicKey\\n ) external returns (uint256);\\n\\n function execute(address dest, uint256 value, bytes calldata func) external;\\n\\n function executeBatch(\\n address[] calldata dest,\\n uint256[] calldata value,\\n bytes[] calldata func\\n ) external;\\n}\\n\",\"keccak256\":\"0x74a9cb0b8f2f4a5148e366a401a0354426c536c012c025025d07cc25a4cd5382\",\"license\":\"Apache-2.0\"},\"contracts/infrastructure/DefaultFallbackHandler.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IERC721Receiver} from \\\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\\\";\\nimport {IERC1155Receiver} from \\\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\\\";\\nimport {IERC777Recipient} from \\\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\\\";\\nimport {BaseAccount} from \\\"../aa-4337/core/BaseAccount.sol\\\";\\nimport {DefaultLibDiamond} from \\\"../libraries/DefaultLibDiamond.sol\\\";\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IAccountFacet} from \\\"../facets/interfaces/IAccountFacet.sol\\\";\\nimport {IStorageLoupe} from \\\"../facets/base/interfaces/IStorageLoupe.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\nimport {IERC677Receiver} from \\\"../interfaces/ERC/IERC677Receiver.sol\\\";\\nimport {IERC165} from \\\"../interfaces/ERC/IERC165.sol\\\";\\n\\n/**\\n * @title DefaultFallbackHandler\\n * @dev A default fallback handler for Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract DefaultFallbackHandler is IDiamondLoupe {\\n /**\\n * @notice Sets the middleware diamond for Barz wallet as a fallback handler\\n * @dev This contract is also a diamond that holds the default facets to reduce gas cost for wallet activation.\\n * Within the constructor this conducts diamond cut to initially setup the diamond. This is a non-upgradeable contract\\n * @param _diamondCutFacet Address if diamond cut facet\\n * @param _accountFacet Address account facet\\n * @param _tokenReceiverFacet Address of token receiver facet\\n * @param _diamondLoupeFacet Address of diamond loupe facet\\n */\\n constructor(\\n address _diamondCutFacet,\\n address _accountFacet,\\n address _tokenReceiverFacet,\\n address _diamondLoupeFacet\\n ) payable {\\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](4);\\n bytes4[] memory functionSelectors = new bytes4[](1);\\n functionSelectors[0] = IDiamondCut.diamondCut.selector;\\n\\n bytes4[] memory accountFunctionSelectors = new bytes4[](5);\\n accountFunctionSelectors[0] = IAccountFacet.execute.selector;\\n accountFunctionSelectors[1] = IAccountFacet.executeBatch.selector;\\n accountFunctionSelectors[2] = BaseAccount.validateUserOp.selector;\\n accountFunctionSelectors[3] = BaseAccount.getNonce.selector;\\n accountFunctionSelectors[4] = BaseAccount.entryPoint.selector;\\n\\n bytes4[] memory receiverFacetSelectors = new bytes4[](5);\\n receiverFacetSelectors[0] = IERC721Receiver.onERC721Received.selector;\\n receiverFacetSelectors[1] = IERC1155Receiver.onERC1155Received.selector;\\n receiverFacetSelectors[2] = IERC1155Receiver\\n .onERC1155BatchReceived\\n .selector;\\n receiverFacetSelectors[3] = IERC777Recipient.tokensReceived.selector;\\n receiverFacetSelectors[4] = IERC677Receiver.onTokenTransfer.selector;\\n\\n bytes4[] memory loupeFacetSelectors = new bytes4[](9);\\n loupeFacetSelectors[0] = IDiamondLoupe.facets.selector;\\n loupeFacetSelectors[1] = IDiamondLoupe.facetFunctionSelectors.selector;\\n loupeFacetSelectors[2] = IDiamondLoupe.facetAddresses.selector;\\n loupeFacetSelectors[3] = IDiamondLoupe.facetAddress.selector;\\n loupeFacetSelectors[4] = IERC165.supportsInterface.selector;\\n loupeFacetSelectors[5] = IStorageLoupe.facetsFromStorage.selector;\\n loupeFacetSelectors[6] = IStorageLoupe\\n .facetFunctionSelectorsFromStorage\\n .selector;\\n loupeFacetSelectors[7] = IStorageLoupe\\n .facetAddressesFromStorage\\n .selector;\\n loupeFacetSelectors[8] = IStorageLoupe.facetAddressFromStorage.selector;\\n\\n {\\n cut[0] = IDiamondCut.FacetCut({\\n facetAddress: _diamondCutFacet,\\n action: IDiamondCut.FacetCutAction.Add,\\n functionSelectors: functionSelectors\\n });\\n cut[1] = IDiamondCut.FacetCut({\\n facetAddress: _accountFacet,\\n action: IDiamondCut.FacetCutAction.Add,\\n functionSelectors: accountFunctionSelectors\\n });\\n cut[2] = IDiamondCut.FacetCut({\\n facetAddress: _tokenReceiverFacet,\\n action: IDiamondCut.FacetCutAction.Add,\\n functionSelectors: receiverFacetSelectors\\n });\\n cut[3] = IDiamondCut.FacetCut({\\n facetAddress: _diamondLoupeFacet,\\n action: IDiamondCut.FacetCutAction.Add,\\n functionSelectors: loupeFacetSelectors\\n });\\n\\n DefaultLibDiamond.diamondCut(cut, address(0), \\\"\\\");\\n }\\n }\\n\\n /**\\n * @notice Returns the facet information of call facets registered to this diamond.\\n * @return facets_ The facet struct array including all facet information\\n */\\n function facets() external view override returns (Facet[] memory facets_) {\\n DefaultLibDiamond.DiamondStorage storage ds = DefaultLibDiamond\\n .diamondStorage();\\n uint256 numFacets = ds.facetAddresses.length;\\n facets_ = new Facet[](numFacets);\\n for (uint256 i; i < numFacets; ) {\\n address facetAddress_ = ds.facetAddresses[i];\\n facets_[i].facetAddress = facetAddress_;\\n facets_[i].functionSelectors = ds\\n .facetFunctionSelectors[facetAddress_]\\n .functionSelectors;\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * @notice Gets all the function selectors provided by a facet.\\n * @param _facet The facet address.\\n * @return facetFunctionSelectors_\\n */\\n function facetFunctionSelectors(\\n address _facet\\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\\n facetFunctionSelectors_ = DefaultLibDiamond\\n .diamondStorage()\\n .facetFunctionSelectors[_facet]\\n .functionSelectors;\\n }\\n\\n /**\\n * @notice Get all the facet addresses used by a diamond.\\n * @return facetAddresses_\\n */\\n function facetAddresses()\\n external\\n view\\n override\\n returns (address[] memory facetAddresses_)\\n {\\n facetAddresses_ = DefaultLibDiamond.diamondStorage().facetAddresses;\\n }\\n\\n /** @notice Gets the facet that supports the given selector.\\n * @dev If facet is not found return address(0).\\n * @param _functionSelector The function selector.\\n * @return facetAddress_ The facet address.\\n */\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view override returns (address facetAddress_) {\\n facetAddress_ = DefaultLibDiamond\\n .diamondStorage()\\n .selectorToFacetAndPosition[_functionSelector]\\n .facetAddress;\\n }\\n}\\n\",\"keccak256\":\"0xa482fe778481e34e9fb3c4074231f8048437e934c0ca9a0c78e8e61d3a24470a\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.21;\\n\\ninterface IERC165 {\\n /// @notice Query if a contract implements an interface\\n /// @param interfaceId The interface identifier, as specified in ERC-165\\n /// @dev Interface identification is specified in ERC-165. This function\\n /// uses less than 30,000 gas.\\n /// @return `true` if the contract implements `interfaceID` and\\n /// `interfaceID` is not 0xffffffff, `false` otherwise\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xbb7f07e170898793c5535cc4b7e8944c4b990a631ac806d0b788e794abc788a3\",\"license\":\"MIT\"},\"contracts/interfaces/ERC/IERC677Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC677Receiver {\\n function onTokenTransfer(\\n address sender,\\n uint value,\\n bytes calldata data\\n ) external pure returns (bool);\\n}\\n\",\"keccak256\":\"0x4c1631cf45ea6daac0ec158c3edb9453099130b6b64f697004b83f95aa1f7350\",\"license\":\"Apache-2.0\"},\"contracts/libraries/DefaultLibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary DefaultLibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (\\n uint256 facetIndex;\\n facetIndex < _diamondCut.length;\\n facetIndex++\\n ) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(\\n address _facetAddress,\\n bytes4[] memory _functionSelectors\\n ) internal {\\n uint256 funcSelectorsLength = _functionSelectors.length;\\n require(\\n funcSelectorsLength > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _facetAddress != address(0),\\n \\\"LibDiamondCut: Add facet can't be address(0)\\\"\\n );\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (\\n uint256 selectorIndex;\\n selectorIndex < funcSelectorsLength;\\n selectorIndex++\\n ) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds\\n .selectorToFacetAndPosition[selector]\\n .facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(\\n address _facetAddress,\\n bytes4[] memory _functionSelectors\\n ) internal {\\n uint256 funcSelectorsLength = _functionSelectors.length;\\n require(\\n funcSelectorsLength > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _facetAddress != address(0),\\n \\\"LibDiamondCut: Replace facet can't be address(0)\\\"\\n );\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (\\n uint256 selectorIndex;\\n selectorIndex < funcSelectorsLength;\\n selectorIndex++\\n ) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds\\n .selectorToFacetAndPosition[selector]\\n .facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same facet\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(\\n address _facetAddress,\\n bytes4[] memory _functionSelectors\\n ) internal {\\n uint256 funcSelectorsLength = _functionSelectors.length;\\n require(\\n funcSelectorsLength > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(\\n _facetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n for (\\n uint256 selectorIndex;\\n selectorIndex < funcSelectorsLength;\\n selectorIndex++\\n ) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds\\n .selectorToFacetAndPosition[selector]\\n .facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(\\n DiamondStorage storage ds,\\n address _facetAddress\\n ) internal {\\n enforceHasContractCode(\\n _facetAddress,\\n \\\"LibDiamondCut: New facet has no code\\\"\\n );\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds\\n .facetAddresses\\n .length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds\\n .selectorToFacetAndPosition[_selector]\\n .functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(\\n _selector\\n );\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(\\n _facetAddress != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // an immutable function is a function defined directly in a diamond\\n require(\\n _facetAddress != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds\\n .selectorToFacetAndPosition[_selector]\\n .functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors[lastSelectorPosition];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n selectorPosition\\n ] = lastSelector;\\n ds\\n .selectorToFacetAndPosition[lastSelector]\\n .functionSelectorPosition = uint96(selectorPosition);\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[\\n lastFacetAddressPosition\\n ];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds\\n .facetFunctionSelectors[lastFacetAddress]\\n .facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds\\n .facetFunctionSelectors[_facetAddress]\\n .facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x1b08f332d62919288bb1f0d154ca4b85f4e167d2a06e680f8ec93dba65be3be1\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x6080604052604051620020183803806200201883398101604081905262000026916200156b565b60408051600480825260a08201909252600091816020015b604080516060808201835260008083526020830152918101919091528152602001906001900390816200003e5750506040805160018082528183019092529192506000919060208083019080368337019050509050631f931c1c60e01b81600081518110620000b157620000b1620015c8565b6001600160e01b03199290921660209283029190910182015260408051600580825260c08201909252600092909190820160a08036833701905050905063b61d27f660e01b816000815181106200010c576200010c620015c8565b6001600160e01b03199092166020928302919091019091015280516323f0ed1560e11b9082906001908110620001465762000146620015c8565b6001600160e01b0319909216602092830291909101909101528051633a871cdd60e01b9082906002908110620001805762000180620015c8565b6001600160e01b0319909216602092830291909101909101528051631a10fa5160e31b9082906003908110620001ba57620001ba620015c8565b6001600160e01b031990921660209283029190910190910152805163586b48ff60e11b9082906004908110620001f457620001f4620015c8565b6001600160e01b03199290921660209283029190910182015260408051600580825260c08201909252600092909190820160a08036833701905050905063150b7a0260e01b816000815181106200024f576200024f620015c8565b6001600160e01b031990921660209283029190910190910152805163f23a6e6160e01b9082906001908110620002895762000289620015c8565b6001600160e01b031990921660209283029190910190910152805163bc197c8160e01b9082906002908110620002c357620002c3620015c8565b6001600160e01b03199092166020928302919091019091015280516223de2960e01b9082906003908110620002fc57620002fc620015c8565b6001600160e01b0319909216602092830291909101909101528051635260769b60e11b9082906004908110620003365762000336620015c8565b6001600160e01b0319929092166020928302919091018201526040805160098082526101408201909252600092909190820161012080368337019050509050637a0ed62760e01b81600081518110620003935762000393620015c8565b6001600160e01b03199092166020928302919091019091015280516356fe50af60e11b9082906001908110620003cd57620003cd620015c8565b6001600160e01b03199092166020928302919091019091015280516314bbdacb60e21b9082906002908110620004075762000407620015c8565b6001600160e01b03199092166020928302919091019091015280516366ffd66360e11b9082906003908110620004415762000441620015c8565b6001600160e01b03199092166020928302919091019091015280516301ffc9a760e01b90829060049081106200047b576200047b620015c8565b6001600160e01b031990921660209283029190910190910152805163f9796ccf60e01b9082906005908110620004b557620004b5620015c8565b6001600160e01b031990921660209283029190910190910152805162d2a81160e11b9082906006908110620004ee57620004ee620015c8565b6001600160e01b031990921660209283029190910190910152805163d42139a960e01b9082906007908110620005285762000528620015c8565b6001600160e01b03199092166020928302919091019091015280516371d17b7f60e11b9082906008908110620005625762000562620015c8565b6001600160e01b031990921660209283029190910182015260408051606081019091526001600160a01b038b168152908101600081526020018581525085600081518110620005b557620005b5620015c8565b60200260200101819052506040518060600160405280896001600160a01b0316815260200160006002811115620005f057620005f0620015de565b815260200184815250856001815181106200060f576200060f620015c8565b60200260200101819052506040518060600160405280886001600160a01b03168152602001600060028111156200064a576200064a620015de565b81526020018381525085600281518110620006695762000669620015c8565b60200260200101819052506040518060600160405280876001600160a01b0316815260200160006002811115620006a457620006a4620015de565b81526020018281525085600381518110620006c357620006c3620015c8565b6020026020010181905250620006f1856000604051806020016040528060008152506200070060201b60201c565b5050505050505050506200184c565b60005b83518110156200090c576000848281518110620007245762000724620015c8565b602002602001015160200151905060006002811115620007485762000748620015de565b8160028111156200075d576200075d620015de565b03620007bb57620007b58583815181106200077c576200077c620015c8565b6020026020010151600001518684815181106200079d576200079d620015c8565b6020026020010151604001516200095b60201b60201c565b620008f6565b6001816002811115620007d257620007d2620015de565b036200082a57620007b5858381518110620007f157620007f1620015c8565b602002602001015160000151868481518110620008125762000812620015c8565b60200260200101516040015162000bf760201b60201c565b6002816002811115620008415762000841620015de565b036200089957620007b5858381518110620008605762000860620015c8565b602002602001015160000151868481518110620008815762000881620015c8565b60200260200101516040015162000ea160201b60201c565b60405162461bcd60e51b815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f727265637420466163657443756044820152663a20b1ba34b7b760c91b60648201526084015b60405180910390fd5b508062000903816200160a565b91505062000703565b507f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb67383838360405162000942939291906200167a565b60405180910390a162000956828262001005565b505050565b805180620009af5760405162461bcd60e51b815260206004820152602b602482015260008051602062001ff883398151915260448201526a1858d95d081d1bc818dd5d60aa1b6064820152608401620008ed565b60008051602062001f8c8339815191526001600160a01b03841662000a2c5760405162461bcd60e51b815260206004820152602c60248201527f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260448201526b65206164647265737328302960a01b6064820152608401620008ed565b6001600160a01b0384166000908152600182016020526040812054906001600160601b038216900362000a655762000a658286620010dd565b60005b8381101562000bef57600085828151811062000a885762000a88620015c8565b6020908102919091018101516001600160e01b031981166000908152918690526040909120549091506001600160a01b0316801562000b305760405162461bcd60e51b815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c72656164792065786973747300000000000000000000006064820152608401620008ed565b6001600160e01b0319821660008181526020878152604080832080546001600160a01b03908116600160a01b6001600160601b038c16021782558d168085526001808c0185529285208054938401815585528385206008840401805463ffffffff60079095166004026101000a948502191660e08a901c94909402939093179092559390925287905281546001600160a01b0319161790558362000bd48162001781565b9450505050808062000be6906200160a565b91505062000a68565b505050505050565b80518062000c4b5760405162461bcd60e51b815260206004820152602b602482015260008051602062001ff883398151915260448201526a1858d95d081d1bc818dd5d60aa1b6064820152608401620008ed565b60008051602062001f8c8339815191526001600160a01b03841662000ccc5760405162461bcd60e51b815260206004820152603060248201527f4c69624469616d6f6e644375743a205265706c6163652066616365742063616e60448201526f2774206265206164647265737328302960801b6064820152608401620008ed565b6001600160a01b0384166000908152600182016020526040812054906001600160601b038216900362000d055762000d058286620010dd565b60005b8381101562000bef57600085828151811062000d285762000d28620015c8565b6020908102919091018101516001600160e01b031981166000908152918690526040909120549091506001600160a01b03908116908816810362000dd55760405162461bcd60e51b815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d6520666163657400000000000000000000006064820152608401620008ed565b62000de28582846200114a565b6001600160e01b0319821660008181526020878152604080832080546001600160a01b03908116600160a01b6001600160601b038c16021782558d168085526001808c0185529285208054938401815585528385206008840401805463ffffffff60079095166004026101000a948502191660e08a901c94909402939093179092559390925287905281546001600160a01b0319161790558362000e868162001781565b9450505050808062000e98906200160a565b91505062000d08565b80518062000ef55760405162461bcd60e51b815260206004820152602b602482015260008051602062001ff883398151915260448201526a1858d95d081d1bc818dd5d60aa1b6064820152608401620008ed565b60008051602062001f8c8339815191526001600160a01b0384161562000f845760405162461bcd60e51b815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d7573742062652061646472657373283029000000000000000000006064820152608401620008ed565b60005b8281101562000ffe57600084828151811062000fa75762000fa7620015c8565b6020908102919091018101516001600160e01b031981166000908152918590526040909120549091506001600160a01b031662000fe68482846200114a565b5050808062000ff5906200160a565b91505062000f87565b5050505050565b6001600160a01b03821662001018575050565b6200103d8260405180606001604052806028815260200162001fac602891396200152a565b600080836001600160a01b0316836040516200105a9190620017b2565b600060405180830381855af49150503d806000811462001097576040519150601f19603f3d011682016040523d82523d6000602084013e6200109c565b606091505b509150915081620010d757805115620010b85780518082602001fd5b838360405163192105d760e01b8152600401620008ed929190620017d0565b50505050565b620011028160405180606001604052806024815260200162001fd4602491396200152a565b6002820180546001600160a01b0390921660008181526001948501602090815260408220860185905594840183559182529290200180546001600160a01b0319169091179055565b6001600160a01b038216620011c85760405162461bcd60e51b815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608401620008ed565b306001600160a01b03831603620012395760405162461bcd60e51b815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201526d3a30b1363290333ab731ba34b7b760911b6064820152608401620008ed565b6001600160e01b03198116600090815260208481526040808320546001600160a01b0386168452600180880190935290832054600160a01b9091046001600160601b031692916200128a91620017fe565b905080821462001383576001600160a01b03841660009081526001860160205260408120805483908110620012c357620012c3620015c8565b600091825260208083206008830401546001600160a01b038916845260018a019091526040909220805460079092166004026101000a90920460e01b925082919085908110620013175762001317620015c8565b600091825260208083206008830401805463ffffffff60079094166004026101000a938402191660e09590951c929092029390931790556001600160e01b03199290921682528690526040902080546001600160a01b0316600160a01b6001600160601b038516021790555b6001600160a01b03841660009081526001860160205260409020805480620013af57620013af6200181a565b60008281526020808220600860001990940193840401805463ffffffff600460078716026101000a0219169055919092556001600160e01b0319851682528690526040812081905581900362000ffe5760028501546000906200141590600190620017fe565b6001600160a01b0386166000908152600180890160205260409091200154909150808214620014cb576000876002018381548110620014585762001458620015c8565b6000918252602090912001546002890180546001600160a01b0390921692508291849081106200148c576200148c620015c8565b600091825260208083209190910180546001600160a01b0319166001600160a01b03948516179055929091168152600189810190925260409020018190555b86600201805480620014e157620014e16200181a565b60008281526020808220830160001990810180546001600160a01b03191690559092019092556001600160a01b0388168252600189810190915260408220015550505050505050565b813b8181620010d75760405162461bcd60e51b8152600401620008ed919062001830565b80516001600160a01b03811681146200156657600080fd5b919050565b600080600080608085870312156200158257600080fd5b6200158d856200154e565b93506200159d602086016200154e565b9250620015ad604086016200154e565b9150620015bd606086016200154e565b905092959194509250565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016200161f576200161f620015f4565b5060010190565b60005b838110156200164357818101518382015260200162001629565b50506000910152565b600081518084526200166681602086016020860162001626565b601f01601f19169290920160200192915050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b848110156200174f57898403607f19018652815180516001600160a01b03168552838101518986019060038110620016eb57634e487b7160e01b600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b80831015620017395783516001600160e01b03191682529286019260019290920191908601906200170d565b50978501979550505090820190600101620016a3565b50506001600160a01b038a169088015286810360408801526200177381896200164c565b9a9950505050505050505050565b60006001600160601b038281166002600160601b03198101620017a857620017a8620015f4565b6001019392505050565b60008251620017c681846020870162001626565b9190910192915050565b6001600160a01b0383168152604060208201819052600090620017f6908301846200164c565b949350505050565b81810381811115620018145762001814620015f4565b92915050565b634e487b7160e01b600052603160045260246000fd5b6020815260006200184560208301846200164c565b9392505050565b610730806200185c6000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806352ef6b2c146100515780637a0ed6271461006f578063adfca15e14610084578063cdffacc6146100a4575b600080fd5b610059610140565b60405161006691906104ab565b60405180910390f35b6100776101d1565b6040516100669190610562565b61009761009236600461060a565b6103d1565b6040516100669190610647565b61011b6100b236600461065a565b7fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610066565b60607f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6002018054806020026020016040519081016040528092919081815260200182805480156101c757602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161019c575b5050505050905090565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f908067ffffffffffffffff8111156102315761023161069c565b60405190808252806020026020018201604052801561027757816020015b60408051808201909152600081526060602082015281526020019060019003908161024f5790505b50925060005b818110156103cb57600083600201828154811061029c5761029c6106cb565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050808583815181106102dc576102dc6106cb565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff928316905290821660009081526001860182526040908190208054825181850281018501909352808352919290919083018282801561039d57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161034a5790505b50505050508583815181106103b4576103b46106cb565b60209081029190910181015101525060010161027d565b50505090565b73ffffffffffffffffffffffffffffffffffffffff811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4920602090815260409182902080548351818402810184019094528084526060939283018282801561049f57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161044c5790505b50505050509050919050565b6020808252825182820181905260009190848201906040850190845b818110156104f957835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016104c7565b50909695505050505050565b600081518084526020808501945080840160005b838110156105575781517fffffffff000000000000000000000000000000000000000000000000000000001687529582019590820190600101610519565b509495945050505050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b838110156105fc578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00185528151805173ffffffffffffffffffffffffffffffffffffffff1684528701518784018790526105e987850182610505565b9588019593505090860190600101610589565b509098975050505050505050565b60006020828403121561061c57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461064057600080fd5b9392505050565b6020815260006106406020830184610505565b60006020828403121561066c57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461064057600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea264697066735822122024a872696a5ad50024326567061c50adea63ff0d49edf0ac60339459d33d571664736f6c63430008150033183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f4c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a204e657720666163657420686173206e6f20636f64654c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e2066", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806352ef6b2c146100515780637a0ed6271461006f578063adfca15e14610084578063cdffacc6146100a4575b600080fd5b610059610140565b60405161006691906104ab565b60405180910390f35b6100776101d1565b6040516100669190610562565b61009761009236600461060a565b6103d1565b6040516100669190610647565b61011b6100b236600461065a565b7fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610066565b60607f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6002018054806020026020016040519081016040528092919081815260200182805480156101c757602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161019c575b5050505050905090565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f908067ffffffffffffffff8111156102315761023161069c565b60405190808252806020026020018201604052801561027757816020015b60408051808201909152600081526060602082015281526020019060019003908161024f5790505b50925060005b818110156103cb57600083600201828154811061029c5761029c6106cb565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050808583815181106102dc576102dc6106cb565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff928316905290821660009081526001860182526040908190208054825181850281018501909352808352919290919083018282801561039d57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161034a5790505b50505050508583815181106103b4576103b46106cb565b60209081029190910181015101525060010161027d565b50505090565b73ffffffffffffffffffffffffffffffffffffffff811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4920602090815260409182902080548351818402810184019094528084526060939283018282801561049f57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161044c5790505b50505050509050919050565b6020808252825182820181905260009190848201906040850190845b818110156104f957835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016104c7565b50909695505050505050565b600081518084526020808501945080840160005b838110156105575781517fffffffff000000000000000000000000000000000000000000000000000000001687529582019590820190600101610519565b509495945050505050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b838110156105fc578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00185528151805173ffffffffffffffffffffffffffffffffffffffff1684528701518784018790526105e987850182610505565b9588019593505090860190600101610589565b509098975050505050505050565b60006020828403121561061c57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461064057600080fd5b9392505050565b6020815260006106406020830184610505565b60006020828403121561066c57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461064057600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea264697066735822122024a872696a5ad50024326567061c50adea63ff0d49edf0ac60339459d33d571664736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "A default fallback handler for Barz", + "kind": "dev", + "methods": { + "constructor": { + "details": "This contract is also a diamond that holds the default facets to reduce gas cost for wallet activation. Within the constructor this conducts diamond cut to initially setup the diamond. This is a non-upgradeable contract", + "params": { + "_accountFacet": "Address account facet", + "_diamondCutFacet": "Address if diamond cut facet", + "_diamondLoupeFacet": "Address of diamond loupe facet", + "_tokenReceiverFacet": "Address of token receiver facet" + } + }, + "facetAddress(bytes4)": { + "details": "If facet is not found return address(0).", + "params": { + "_functionSelector": "The function selector." + }, + "returns": { + "facetAddress_": "The facet address." + } + }, + "facetAddresses()": { + "returns": { + "facetAddresses_": "facetAddresses_" + } + }, + "facetFunctionSelectors(address)": { + "params": { + "_facet": "The facet address." + }, + "returns": { + "facetFunctionSelectors_": "facetFunctionSelectors_" + } + }, + "facets()": { + "returns": { + "facets_": "The facet struct array including all facet information" + } + } + }, + "title": "DefaultFallbackHandler", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "constructor": { + "notice": "Sets the middleware diamond for Barz wallet as a fallback handler" + }, + "facetAddress(bytes4)": { + "notice": "Gets the facet that supports the given selector." + }, + "facetAddresses()": { + "notice": "Get all the facet addresses used by a diamond." + }, + "facetFunctionSelectors(address)": { + "notice": "Gets all the function selectors provided by a facet." + }, + "facets()": { + "notice": "Returns the facet information of call facets registered to this diamond." + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/base/DiamondCutFacet.json b/deployments/base/DiamondCutFacet.json new file mode 100644 index 0000000..80fd3a6 --- /dev/null +++ b/deployments/base/DiamondCutFacet.json @@ -0,0 +1,856 @@ +{ + "address": "0x0B9504140771C3688Ff041917192277D2f52E1e0", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_securityManager", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "CallerNotGuardian", + "type": "error" + }, + { + "inputs": [], + "name": "CallerNotGuardianOrOwner", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__CannotRevokeUnapproved", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__DuplicateApproval", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InsufficientApprovers", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidApprovalValidationPeriod", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidApprover", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidApproverSignature", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidArrayLength", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidInitAddress", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidRouteWithGuardian", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidRouteWithoutGuardian", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__LackOfOwnerApproval", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__OwnerAlreadyApproved", + "type": "error" + }, + { + "inputs": [], + "name": "DuplicateApprover", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_initializationContractAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "InitializationFunctionReverted", + "type": "error" + }, + { + "inputs": [], + "name": "UnregisteredFacetAndSelectors", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroApproverLength", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "indexed": false, + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "DiamondCut", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "diamondCut", + "type": "tuple[]" + } + ], + "name": "DiamondCutApprovalRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "diamondCut", + "type": "tuple[]" + } + ], + "name": "DiamondCutApproved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + }, + { + "indexed": false, + "internalType": "bool", + "name": "_lag", + "type": "bool" + } + ], + "name": "SupportsInterfaceUpdated", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_diamondCutHash", + "type": "bytes32" + }, + { + "internalType": "address[]", + "name": "_approvers", + "type": "address[]" + } + ], + "name": "_checkDuplicateOnChainApprover", + "outputs": [], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + } + ], + "name": "approveDiamondCut", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "diamondCut", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "internalType": "address[]", + "name": "_approvers", + "type": "address[]" + }, + { + "internalType": "bytes[]", + "name": "_signatures", + "type": "bytes[]" + } + ], + "name": "diamondCutWithGuardian", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_diamondCutHash", + "type": "bytes32" + } + ], + "name": "getDiamondCutApprovalCountWithTimeValidity", + "outputs": [ + { + "internalType": "uint256", + "name": "approvalCount", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + } + ], + "name": "getDiamondCutHash", + "outputs": [ + { + "internalType": "bytes32", + "name": "cutHash", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getDiamondCutNonce", + "outputs": [ + { + "internalType": "uint128", + "name": "cutNonce", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_diamondCutHash", + "type": "bytes32" + } + ], + "name": "getOwnerCutApprovalWithTimeValidity", + "outputs": [ + { + "internalType": "bool", + "name": "isApprovedByOwner", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_diamondCutHash", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "_approver", + "type": "address" + } + ], + "name": "isCutApproved", + "outputs": [ + { + "internalType": "bool", + "name": "isApproved", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + } + ], + "name": "revokeDiamondCutApproval", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "securityManager", + "outputs": [ + { + "internalType": "contract ISecurityManager", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_interfaceId", + "type": "bytes4" + }, + { + "internalType": "bool", + "name": "_flag", + "type": "bool" + } + ], + "name": "updateSupportsInterface", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0xa8c65f8ec214022f0d848a1abdd34191676cd22638f196f77dbe3f98fac0c2e2", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 11, + "gasUsed": "3078987", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x472155485a80a0be53057c5a84abb375ba815f9e11731976e541ec9c92993004", + "transactionHash": "0xa8c65f8ec214022f0d848a1abdd34191676cd22638f196f77dbe3f98fac0c2e2", + "logs": [], + "blockNumber": 6847652, + "cumulativeGasUsed": "3781850", + "status": 1, + "byzantium": true + }, + "args": [ + "0xcBe266adbfd7CB32988128e7f37b7c8b3C5521A8" + ], + "numDeployments": 3, + "solcInputHash": "4356503edd8ae34e73cb6dd1c8e2fc8a", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_securityManager\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"CallerNotGuardian\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallerNotGuardianOrOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__CannotRevokeUnapproved\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__DuplicateApproval\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InsufficientApprovers\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidApprovalValidationPeriod\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidApprover\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidApproverSignature\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidArrayLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidInitAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidRouteWithGuardian\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidRouteWithoutGuardian\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__LackOfOwnerApproval\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__OwnerAlreadyApproved\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateApprover\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_initializationContractAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"InitializationFunctionReverted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnregisteredFacetAndSelectors\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroApproverLength\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"DiamondCut\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"diamondCut\",\"type\":\"tuple[]\"}],\"name\":\"DiamondCutApprovalRevoked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"diamondCut\",\"type\":\"tuple[]\"}],\"name\":\"DiamondCutApproved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"_lag\",\"type\":\"bool\"}],\"name\":\"SupportsInterfaceUpdated\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_diamondCutHash\",\"type\":\"bytes32\"},{\"internalType\":\"address[]\",\"name\":\"_approvers\",\"type\":\"address[]\"}],\"name\":\"_checkDuplicateOnChainApprover\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"}],\"name\":\"approveDiamondCut\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"diamondCut\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"internalType\":\"address[]\",\"name\":\"_approvers\",\"type\":\"address[]\"},{\"internalType\":\"bytes[]\",\"name\":\"_signatures\",\"type\":\"bytes[]\"}],\"name\":\"diamondCutWithGuardian\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_diamondCutHash\",\"type\":\"bytes32\"}],\"name\":\"getDiamondCutApprovalCountWithTimeValidity\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"approvalCount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"}],\"name\":\"getDiamondCutHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"cutHash\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDiamondCutNonce\",\"outputs\":[{\"internalType\":\"uint128\",\"name\":\"cutNonce\",\"type\":\"uint128\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_diamondCutHash\",\"type\":\"bytes32\"}],\"name\":\"getOwnerCutApprovalWithTimeValidity\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isApprovedByOwner\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_diamondCutHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"_approver\",\"type\":\"address\"}],\"name\":\"isCutApproved\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isApproved\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"}],\"name\":\"revokeDiamondCutApproval\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"securityManager\",\"outputs\":[{\"internalType\":\"contract ISecurityManager\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_interfaceId\",\"type\":\"bytes4\"},{\"internalType\":\"bool\",\"name\":\"_flag\",\"type\":\"bool\"}],\"name\":\"updateSupportsInterface\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"Responsible for adding/removing/replace facets in Barz\",\"kind\":\"dev\",\"methods\":{\"_checkDuplicateOnChainApprover(bytes32,address[])\":{\"params\":{\"_approvers\":\"List of approver addresses\",\"_diamondCutHash\":\"Hash of diamondCut information including the facet addresses and function selectors\"}},\"approveDiamondCut((address,uint8,bytes4[])[])\":{\"params\":{\"_diamondCut\":\"Contains the facet addresses and function selectors\"}},\"constructor\":{\"params\":{\"_securityManager\":\"Security Manager contract that holds the security related variables for all wallets\"}},\"diamondCut((address,uint8,bytes4[])[],address,bytes)\":{\"params\":{\"_diamondCut\":\"Contains the facet addresses and function selectors\",\"_init\":\"The address of the contract or facet to execute _calldata. It's prohibited in Barz\"}},\"diamondCutWithGuardian((address,uint8,bytes4[])[],address[],bytes[])\":{\"params\":{\"_approvers\":\"Guardian or owner address that approves the diamond cut\",\"_diamondCut\":\"Contains the facet addresses and function selectors\",\"_signatures\":\"Signature of Guardians or owner that approves the diamond cut\"}},\"getDiamondCutApprovalCountWithTimeValidity(bytes32)\":{\"params\":{\"_diamondCutHash\":\"Hash of diamondCut information including the facet addresses and function selectors\"}},\"getDiamondCutHash((address,uint8,bytes4[])[])\":{\"params\":{\"_diamondCut\":\"Contains the facet addresses and function selectors\"},\"returns\":{\"cutHash\":\"Diamond Cut Hash\"}},\"getDiamondCutNonce()\":{\"details\":\"This method fetches the nonce from diamond cut storage\",\"returns\":{\"cutNonce\":\"Nonce of diamond cut to protect from reply attacks\"}},\"getOwnerCutApprovalWithTimeValidity(bytes32)\":{\"params\":{\"_diamondCutHash\":\"Hash of diamondCut information including the facet addresses and function selectors\"},\"returns\":{\"isApprovedByOwner\":\"Bool value showing if the owner approved the cut\"}},\"isCutApproved(bytes32,address)\":{\"params\":{\"_approver\":\"Address of approver\",\"_diamondCutHash\":\"Hash of diamondCut information including the facet addresses and function selectors\"},\"returns\":{\"isApproved\":\"Bool value showing if the approver approved the cut\"}},\"revokeDiamondCutApproval((address,uint8,bytes4[])[])\":{\"params\":{\"_diamondCut\":\"Contains the facet addresses and function selectors\"}},\"updateSupportsInterface(bytes4,bool)\":{\"params\":{\"_flag\":\"Bool value to update the mapping of the given interface ID\",\"_interfaceId\":\"InterfaceID to update the mapping\"}}},\"title\":\"DiamondCut Facet\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"_checkDuplicateOnChainApprover(bytes32,address[])\":{\"notice\":\"Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval Approvers who approved on-chain should not be included in the off-chain approval\"},\"approveDiamondCut((address,uint8,bytes4[])[])\":{\"notice\":\"Approves diamond cut. This can only be called directly from guardian or owner\"},\"constructor\":{\"notice\":\"This constructor sets the Security Manager address which is an immutable variable. Immutable variables do not impact the storage of diamond\"},\"diamondCut((address,uint8,bytes4[])[],address,bytes)\":{\"notice\":\"Add/replace/remove any number of functions and optionally execute a function with delegatecall when guardians don't exist\"},\"diamondCutWithGuardian((address,uint8,bytes4[])[],address[],bytes[])\":{\"notice\":\"Add/replace/remove any number of functions and optionally execute a function with delegatecall when guardians exist\"},\"getDiamondCutApprovalCountWithTimeValidity(bytes32)\":{\"notice\":\"Gets the number of approvals of diamond cut from guardians\"},\"getDiamondCutHash((address,uint8,bytes4[])[])\":{\"notice\":\"Returns the diamond cut hash. This function ensures that this hash is safe from replay attack by including salt, address, chainId, and nonce, etc.\"},\"getDiamondCutNonce()\":{\"notice\":\"Returns the diamond cut nonce of this wallet\"},\"getOwnerCutApprovalWithTimeValidity(bytes32)\":{\"notice\":\"Returns if the owner has approved the diamond cut\"},\"isCutApproved(bytes32,address)\":{\"notice\":\"Returns if the given approver has approved the diamond cut\"},\"revokeDiamondCutApproval((address,uint8,bytes4[])[])\":{\"notice\":\"Revokes the approval of diamond cut. This can only be called directly from guardian or owner\"},\"updateSupportsInterface(bytes4,bool)\":{\"notice\":\"Updates the flag for the interfaceId\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/base/DiamondCutFacet.sol\":\"DiamondCutFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/interfaces/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC1271 standard signature validation method for\\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC1271 {\\n /**\\n * @dev Should return whether the signature provided is valid for the provided data\\n * @param hash Hash of the data to be signed\\n * @param signature Signature byte array associated with _data\\n */\\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\\n}\\n\",\"keccak256\":\"0x0705a4b1b86d7b0bd8432118f226ba139c44b9dcaba0a6eafba2dd7d0639c544\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./math/Math.sol\\\";\\nimport \\\"./math/SignedMath.sol\\\";\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n uint256 length = Math.log10(value) + 1;\\n string memory buffer = new string(length);\\n uint256 ptr;\\n /// @solidity memory-safe-assembly\\n assembly {\\n ptr := add(buffer, add(32, length))\\n }\\n while (true) {\\n ptr--;\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\\n }\\n value /= 10;\\n if (value == 0) break;\\n }\\n return buffer;\\n }\\n }\\n\\n /**\\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\\n */\\n function toString(int256 value) internal pure returns (string memory) {\\n return string(abi.encodePacked(value < 0 ? \\\"-\\\" : \\\"\\\", toString(SignedMath.abs(value))));\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n return toHexString(value, Math.log256(value) + 1);\\n }\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n\\n /**\\n * @dev Returns true if the two strings are equal.\\n */\\n function equal(string memory a, string memory b) internal pure returns (bool) {\\n return keccak256(bytes(a)) == keccak256(bytes(b));\\n }\\n}\\n\",\"keccak256\":\"0x3088eb2868e8d13d89d16670b5f8612c4ab9ff8956272837d8e90106c59c14a0\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Strings.sol\\\";\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSA {\\n enum RecoverError {\\n NoError,\\n InvalidSignature,\\n InvalidSignatureLength,\\n InvalidSignatureS,\\n InvalidSignatureV // Deprecated in v4.8\\n }\\n\\n function _throwError(RecoverError error) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert(\\\"ECDSA: invalid signature\\\");\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert(\\\"ECDSA: invalid signature length\\\");\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert(\\\"ECDSA: invalid signature 's' value\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature` or error string. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n *\\n * Documentation for signature generation:\\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n return tryRecover(hash, v, r, s);\\n } else {\\n return (address(0), RecoverError.InvalidSignatureLength);\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature`. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, signature);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\\n uint8 v = uint8((uint256(vs) >> 255) + 27);\\n return tryRecover(hash, v, r, s);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n *\\n * _Available since v4.2._\\n */\\n function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\\n // the valid range for s in (301): 0 < s < secp256k1n \\u00f7 2 + 1, and for v in (302): v \\u2208 {27, 28}. Most\\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\\n //\\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\\n // these malleable signatures as well.\\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n return (address(0), RecoverError.InvalidSignatureS);\\n }\\n\\n // If the signature is valid (and not malleable), return the signer address\\n address signer = ecrecover(hash, v, r, s);\\n if (signer == address(0)) {\\n return (address(0), RecoverError.InvalidSignature);\\n }\\n\\n return (signer, RecoverError.NoError);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore(0x00, \\\"\\\\x19Ethereum Signed Message:\\\\n32\\\")\\n mstore(0x1c, hash)\\n message := keccak256(0x00, 0x3c)\\n }\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from `s`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n\\\", Strings.toString(s.length), s));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Typed Data, created from a\\n * `domainSeparator` and a `structHash`. This produces hash corresponding\\n * to the one signed with the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n * JSON-RPC method as part of EIP-712.\\n *\\n * See {recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n let ptr := mload(0x40)\\n mstore(ptr, \\\"\\\\x19\\\\x01\\\")\\n mstore(add(ptr, 0x02), domainSeparator)\\n mstore(add(ptr, 0x22), structHash)\\n data := keccak256(ptr, 0x42)\\n }\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Data with intended validator, created from a\\n * `validator` and `data` according to the version 0 of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x00\\\", validator, data));\\n }\\n}\\n\",\"keccak256\":\"0x809bc3edb4bcbef8263fa616c1b60ee0004b50a8a1bfa164d8f57fd31f520c58\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/SignatureChecker.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./ECDSA.sol\\\";\\nimport \\\"../../interfaces/IERC1271.sol\\\";\\n\\n/**\\n * @dev Signature verification helper that can be used instead of `ECDSA.recover` to seamlessly support both ECDSA\\n * signatures from externally owned accounts (EOAs) as well as ERC1271 signatures from smart contract wallets like\\n * Argent and Gnosis Safe.\\n *\\n * _Available since v4.1._\\n */\\nlibrary SignatureChecker {\\n /**\\n * @dev Checks if a signature is valid for a given signer and data hash. If the signer is a smart contract, the\\n * signature is validated against that smart contract using ERC1271, otherwise it's validated using `ECDSA.recover`.\\n *\\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\\n */\\n function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature) internal view returns (bool) {\\n (address recovered, ECDSA.RecoverError error) = ECDSA.tryRecover(hash, signature);\\n return\\n (error == ECDSA.RecoverError.NoError && recovered == signer) ||\\n isValidERC1271SignatureNow(signer, hash, signature);\\n }\\n\\n /**\\n * @dev Checks if a signature is valid for a given signer and data hash. The signature is validated\\n * against the signer smart contract using ERC1271.\\n *\\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\\n */\\n function isValidERC1271SignatureNow(\\n address signer,\\n bytes32 hash,\\n bytes memory signature\\n ) internal view returns (bool) {\\n (bool success, bytes memory result) = signer.staticcall(\\n abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, signature)\\n );\\n return (success &&\\n result.length >= 32 &&\\n abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector));\\n }\\n}\\n\",\"keccak256\":\"0x3af3ca86df39aac39a0514c84459d691434a108d2151c8ce9d69f32e315cab80\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n enum Rounding {\\n Down, // Toward negative infinity\\n Up, // Toward infinity\\n Zero // Toward zero\\n }\\n\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow.\\n return (a & b) + (a ^ b) / 2;\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a == 0 ? 0 : (a - 1) / b + 1;\\n }\\n\\n /**\\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\\n * with further edits by Uniswap Labs also under MIT license.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\\n unchecked {\\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2^256 + prod0.\\n uint256 prod0; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division.\\n if (prod1 == 0) {\\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\\n // The surrounding unchecked block does not change this fact.\\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\\n return prod0 / denominator;\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n require(denominator > prod1, \\\"Math: mulDiv overflow\\\");\\n\\n ///////////////////////////////////////////////\\n // 512 by 256 division.\\n ///////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0].\\n uint256 remainder;\\n assembly {\\n // Compute remainder using mulmod.\\n remainder := mulmod(x, y, denominator)\\n\\n // Subtract 256 bit number from 512 bit number.\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\\n // See https://cs.stackexchange.com/q/138556/92363.\\n\\n // Does not overflow because the denominator cannot be zero at this stage in the function.\\n uint256 twos = denominator & (~denominator + 1);\\n assembly {\\n // Divide denominator by twos.\\n denominator := div(denominator, twos)\\n\\n // Divide [prod1 prod0] by twos.\\n prod0 := div(prod0, twos)\\n\\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\\n twos := add(div(sub(0, twos), twos), 1)\\n }\\n\\n // Shift in bits from prod1 into prod0.\\n prod0 |= prod1 * twos;\\n\\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\\n // four bits. That is, denominator * inv = 1 mod 2^4.\\n uint256 inverse = (3 * denominator) ^ 2;\\n\\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\\n // in modular arithmetic, doubling the correct bits in each step.\\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\\n\\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inverse;\\n return result;\\n }\\n }\\n\\n /**\\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\\n uint256 result = mulDiv(x, y, denominator);\\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\\n result += 1;\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\\n *\\n * Inspired by Henry S. Warren, Jr.'s \\\"Hacker's Delight\\\" (Chapter 11).\\n */\\n function sqrt(uint256 a) internal pure returns (uint256) {\\n if (a == 0) {\\n return 0;\\n }\\n\\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\\n //\\n // We know that the \\\"msb\\\" (most significant bit) of our target number `a` is a power of 2 such that we have\\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\\n //\\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\\n // \\u2192 `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\\n // \\u2192 `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\\n //\\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\\n uint256 result = 1 << (log2(a) >> 1);\\n\\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\\n // into the expected uint128 result.\\n unchecked {\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n return min(result, a / result);\\n }\\n }\\n\\n /**\\n * @notice Calculates sqrt(a), following the selected rounding direction.\\n */\\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = sqrt(a);\\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 2, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 128;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 64;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 32;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 16;\\n }\\n if (value >> 8 > 0) {\\n value >>= 8;\\n result += 8;\\n }\\n if (value >> 4 > 0) {\\n value >>= 4;\\n result += 4;\\n }\\n if (value >> 2 > 0) {\\n value >>= 2;\\n result += 2;\\n }\\n if (value >> 1 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log2(value);\\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 10, rounded down, of a positive value.\\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 + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 256, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n *\\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\\n */\\n function log256(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 16;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 8;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 4;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 2;\\n }\\n if (value >> 8 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log256(value);\\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe4455ac1eb7fc497bb7402579e7b4d64d928b846fce7d2b6fde06d366f21c2b3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\\n * checks.\\n *\\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\\n * easily result in undesired exploitation or bugs, since developers usually\\n * assume that overflows raise errors. `SafeCast` restores this intuition by\\n * reverting the transaction when such an operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n *\\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\\n * all math on `uint256` and `int256` and then downcasting.\\n */\\nlibrary SafeCast {\\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 * _Available since v4.7._\\n */\\n function toUint248(uint256 value) internal pure returns (uint248) {\\n require(value <= type(uint248).max, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint240(uint256 value) internal pure returns (uint240) {\\n require(value <= type(uint240).max, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint232(uint256 value) internal pure returns (uint232) {\\n require(value <= type(uint232).max, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint224(uint256 value) internal pure returns (uint224) {\\n require(value <= type(uint224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint216(uint256 value) internal pure returns (uint216) {\\n require(value <= type(uint216).max, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint208(uint256 value) internal pure returns (uint208) {\\n require(value <= type(uint208).max, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint200(uint256 value) internal pure returns (uint200) {\\n require(value <= type(uint200).max, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint192(uint256 value) internal pure returns (uint192) {\\n require(value <= type(uint192).max, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint184(uint256 value) internal pure returns (uint184) {\\n require(value <= type(uint184).max, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint176(uint256 value) internal pure returns (uint176) {\\n require(value <= type(uint176).max, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint168(uint256 value) internal pure returns (uint168) {\\n require(value <= type(uint168).max, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint160(uint256 value) internal pure returns (uint160) {\\n require(value <= type(uint160).max, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint152(uint256 value) internal pure returns (uint152) {\\n require(value <= type(uint152).max, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint144(uint256 value) internal pure returns (uint144) {\\n require(value <= type(uint144).max, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint136(uint256 value) internal pure returns (uint136) {\\n require(value <= type(uint136).max, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint128(uint256 value) internal pure returns (uint128) {\\n require(value <= type(uint128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint120(uint256 value) internal pure returns (uint120) {\\n require(value <= type(uint120).max, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint112(uint256 value) internal pure returns (uint112) {\\n require(value <= type(uint112).max, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint104(uint256 value) internal pure returns (uint104) {\\n require(value <= type(uint104).max, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint96(uint256 value) internal pure returns (uint96) {\\n require(value <= type(uint96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint88(uint256 value) internal pure returns (uint88) {\\n require(value <= type(uint88).max, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint80(uint256 value) internal pure returns (uint80) {\\n require(value <= type(uint80).max, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint72(uint256 value) internal pure returns (uint72) {\\n require(value <= type(uint72).max, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint64(uint256 value) internal pure returns (uint64) {\\n require(value <= type(uint64).max, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint56(uint256 value) internal pure returns (uint56) {\\n require(value <= type(uint56).max, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint48(uint256 value) internal pure returns (uint48) {\\n require(value <= type(uint48).max, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint40(uint256 value) internal pure returns (uint40) {\\n require(value <= type(uint40).max, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint32(uint256 value) internal pure returns (uint32) {\\n require(value <= type(uint32).max, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint24(uint256 value) internal pure returns (uint24) {\\n require(value <= type(uint24).max, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint16(uint256 value) internal pure returns (uint16) {\\n require(value <= type(uint16).max, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint8(uint256 value) internal pure returns (uint8) {\\n require(value <= type(uint8).max, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\n */\\n function toUint256(int256 value) internal pure returns (uint256) {\\n require(value >= 0, \\\"SafeCast: value must be positive\\\");\\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 * _Available since v4.7._\\n */\\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\\n downcasted = int248(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\\n downcasted = int240(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\\n downcasted = int232(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\\n downcasted = int224(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\\n downcasted = int216(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\\n downcasted = int208(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\\n downcasted = int200(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\\n downcasted = int192(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\\n downcasted = int184(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\\n downcasted = int176(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\\n downcasted = int168(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\\n downcasted = int160(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\\n downcasted = int152(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\\n downcasted = int144(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\\n downcasted = int136(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\\n downcasted = int128(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\\n downcasted = int120(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\\n downcasted = int112(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\\n downcasted = int104(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\\n downcasted = int96(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\\n downcasted = int88(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\\n downcasted = int80(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\\n downcasted = int72(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\\n downcasted = int64(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\\n downcasted = int56(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\\n downcasted = int48(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\\n downcasted = int40(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\\n downcasted = int32(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\\n downcasted = int24(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\\n downcasted = int16(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\\n downcasted = int8(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\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 require(value <= uint256(type(int256).max), \\\"SafeCast: value doesn't fit in an int256\\\");\\n return int256(value);\\n }\\n}\\n\",\"keccak256\":\"0x52a8cfb0f5239d11b457dcdd1b326992ef672714ca8da71a157255bddd13f3ad\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SignedMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard signed math utilities missing in the Solidity language.\\n */\\nlibrary SignedMath {\\n /**\\n * @dev Returns the largest of two signed numbers.\\n */\\n function max(int256 a, int256 b) internal pure returns (int256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two signed numbers.\\n */\\n function min(int256 a, int256 b) internal pure returns (int256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two signed numbers without overflow.\\n * The result is rounded towards zero.\\n */\\n function average(int256 a, int256 b) internal pure returns (int256) {\\n // Formula from the book \\\"Hacker's Delight\\\"\\n int256 x = (a & b) + ((a ^ b) >> 1);\\n return x + (int256(uint256(x) >> 255) & (a ^ b));\\n }\\n\\n /**\\n * @dev Returns the absolute unsigned value of a signed value.\\n */\\n function abs(int256 n) internal pure returns (uint256) {\\n unchecked {\\n // must be unchecked in order to support `n = type(int256).min`\\n return uint256(n >= 0 ? n : -n);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf92515413956f529d95977adc9b0567d583c6203fc31ab1c23824c35187e3ddc\",\"license\":\"MIT\"},\"contracts/aa-4337/core/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable no-inline-assembly */\\n\\n/**\\n * returned data from validateUserOp.\\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\\n * @param aggregator - address(0) - the account validated the signature by itself.\\n * address(1) - the account failed to validate the signature.\\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\\n * @param validAfter - this UserOp is valid only after this timestamp.\\n * @param validaUntil - this UserOp is valid only up to this timestamp.\\n */\\nstruct ValidationData {\\n address aggregator;\\n uint48 validAfter;\\n uint48 validUntil;\\n}\\n\\n//extract sigFailed, validAfter, validUntil.\\n// also convert zero validUntil to type(uint48).max\\nfunction _parseValidationData(\\n uint validationData\\n) pure returns (ValidationData memory data) {\\n address aggregator = address(uint160(validationData));\\n uint48 validUntil = uint48(validationData >> 160);\\n if (validUntil == 0) {\\n validUntil = type(uint48).max;\\n }\\n uint48 validAfter = uint48(validationData >> (48 + 160));\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n// intersect account and paymaster ranges.\\nfunction _intersectTimeRange(\\n uint256 validationData,\\n uint256 paymasterValidationData\\n) pure returns (ValidationData memory) {\\n ValidationData memory accountValidationData = _parseValidationData(\\n validationData\\n );\\n ValidationData memory pmValidationData = _parseValidationData(\\n paymasterValidationData\\n );\\n address aggregator = accountValidationData.aggregator;\\n if (aggregator == address(0)) {\\n aggregator = pmValidationData.aggregator;\\n }\\n uint48 validAfter = accountValidationData.validAfter;\\n uint48 validUntil = accountValidationData.validUntil;\\n uint48 pmValidAfter = pmValidationData.validAfter;\\n uint48 pmValidUntil = pmValidationData.validUntil;\\n\\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp\\n * @param data - the ValidationData to pack\\n */\\nfunction _packValidationData(\\n ValidationData memory data\\n) pure returns (uint256) {\\n return\\n uint160(data.aggregator) |\\n (uint256(data.validUntil) << 160) |\\n (uint256(data.validAfter) << (160 + 48));\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp, when not using an aggregator\\n * @param sigFailed - true for signature failure, false for success\\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\\n * @param validAfter first timestamp this UserOperation is valid\\n */\\nfunction _packValidationData(\\n bool sigFailed,\\n uint48 validUntil,\\n uint48 validAfter\\n) pure returns (uint256) {\\n return\\n (sigFailed ? 1 : 0) |\\n (uint256(validUntil) << 160) |\\n (uint256(validAfter) << (160 + 48));\\n}\\n\\n/**\\n * keccak function over calldata.\\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\\n */\\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\\n assembly {\\n let mem := mload(0x40)\\n let len := data.length\\n calldatacopy(mem, data.offset, len)\\n ret := keccak256(mem, len)\\n }\\n}\\n\",\"keccak256\":\"0xa79f06cd158ecb8c0da95493a2f348933b8627a63e228b99738bff3aa107942d\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAggregator.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\n/**\\n * Aggregated Signatures validator.\\n */\\ninterface IAggregator {\\n /**\\n * validate aggregated signature.\\n * revert if the aggregated signature does not match the given list of operations.\\n */\\n function validateSignatures(\\n UserOperation[] calldata userOps,\\n bytes calldata signature\\n ) external view;\\n\\n /**\\n * validate signature of a single userOp\\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\\n * @param userOp the userOperation received from the user.\\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\\n * (usually empty, unless account and aggregator support some kind of \\\"multisig\\\"\\n */\\n function validateUserOpSignature(\\n UserOperation calldata userOp\\n ) external view returns (bytes memory sigForUserOp);\\n\\n /**\\n * aggregate multiple signatures into a single value.\\n * This method is called off-chain to calculate the signature to pass with handleOps()\\n * bundler MAY use optimized custom code perform this aggregation\\n * @param userOps array of UserOperations to collect the signatures from.\\n * @return aggregatedSignature the aggregated signature\\n */\\n function aggregateSignatures(\\n UserOperation[] calldata userOps\\n ) external view returns (bytes memory aggregatedSignature);\\n}\\n\",\"keccak256\":\"0xdfdcd80568f037716674619b31be630fcd8316262f05a815b41d1e81782c966a\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IEntryPoint.sol\":{\"content\":\"/**\\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\\n ** Only one instance required on each chain.\\n **/\\n// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-inline-assembly */\\n/* solhint-disable reason-string */\\n\\nimport \\\"./UserOperation.sol\\\";\\nimport \\\"./IStakeManager.sol\\\";\\nimport \\\"./IAggregator.sol\\\";\\nimport \\\"./INonceManager.sol\\\";\\n\\ninterface IEntryPoint is IStakeManager, INonceManager {\\n /***\\n * An event emitted after each successful request\\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\\n * @param sender - the account that generates this request.\\n * @param paymaster - if non-null, the paymaster that pays for this request.\\n * @param nonce - the nonce value from the request.\\n * @param success - true if the sender transaction succeeded, false if reverted.\\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\\n */\\n event UserOperationEvent(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address indexed paymaster,\\n uint256 nonce,\\n bool success,\\n uint256 actualGasCost,\\n uint256 actualGasUsed\\n );\\n\\n /**\\n * account \\\"sender\\\" was deployed.\\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\\n * @param sender the account that is deployed\\n * @param factory the factory used to deploy this account (in the initCode)\\n * @param paymaster the paymaster used by this UserOp\\n */\\n event AccountDeployed(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address factory,\\n address paymaster\\n );\\n\\n /**\\n * An event emitted if the UserOperation \\\"callData\\\" reverted with non-zero length\\n * @param userOpHash the request unique identifier.\\n * @param sender the sender of this request\\n * @param nonce the nonce used in the request\\n * @param revertReason - the return bytes from the (reverted) call to \\\"callData\\\".\\n */\\n event UserOperationRevertReason(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n uint256 nonce,\\n bytes revertReason\\n );\\n\\n /**\\n * an event emitted by handleOps(), before starting the execution loop.\\n * any event emitted before this event, is part of the validation.\\n */\\n event BeforeExecution();\\n\\n /**\\n * signature aggregator used by the following UserOperationEvents within this bundle.\\n */\\n event SignatureAggregatorChanged(address indexed aggregator);\\n\\n /**\\n * a custom revert error of handleOps, to identify the offending op.\\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\\n * @param reason - revert reason\\n * The string starts with a unique code \\\"AAmn\\\", where \\\"m\\\" is \\\"1\\\" for factory, \\\"2\\\" for account and \\\"3\\\" for paymaster issues,\\n * so a failure can be attributed to the correct entity.\\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\\n */\\n error FailedOp(uint256 opIndex, string reason);\\n\\n /**\\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\\n */\\n error SignatureValidationFailed(address aggregator);\\n\\n /**\\n * Successful result from simulateValidation.\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n */\\n error ValidationResult(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo\\n );\\n\\n /**\\n * Successful result from simulateValidation, if the account returns a signature aggregator\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\\n * bundler MUST use it to verify the signature, or reject the UserOperation\\n */\\n error ValidationResultWithAggregation(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo,\\n AggregatorStakeInfo aggregatorInfo\\n );\\n\\n /**\\n * return value of getSenderAddress\\n */\\n error SenderAddressResult(address sender);\\n\\n /**\\n * return value of simulateHandleOp\\n */\\n error ExecutionResult(\\n uint256 preOpGas,\\n uint256 paid,\\n uint48 validAfter,\\n uint48 validUntil,\\n bool targetSuccess,\\n bytes targetResult\\n );\\n\\n //UserOps handled, per aggregator\\n struct UserOpsPerAggregator {\\n UserOperation[] userOps;\\n // aggregator address\\n IAggregator aggregator;\\n // aggregated signature\\n bytes signature;\\n }\\n\\n /**\\n * Execute a batch of UserOperation.\\n * no signature aggregator is used.\\n * if any account requires an aggregator (that is, it returned an aggregator when\\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\\n * @param ops the operations to execute\\n * @param beneficiary the address to receive the fees\\n */\\n function handleOps(\\n UserOperation[] calldata ops,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * Execute a batch of UserOperation with Aggregators\\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\\n * @param beneficiary the address to receive the fees\\n */\\n function handleAggregatedOps(\\n UserOpsPerAggregator[] calldata opsPerAggregator,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * generate a request Id - unique identifier for this request.\\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\\n */\\n function getUserOpHash(\\n UserOperation calldata userOp\\n ) external view returns (bytes32);\\n\\n /**\\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\\n * @param userOp the user operation to validate.\\n */\\n function simulateValidation(UserOperation calldata userOp) external;\\n\\n /**\\n * gas and return values during simulation\\n * @param preOpGas the gas used for validation (including preValidationGas)\\n * @param prefund the required prefund for this operation\\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\\n */\\n struct ReturnInfo {\\n uint256 preOpGas;\\n uint256 prefund;\\n bool sigFailed;\\n uint48 validAfter;\\n uint48 validUntil;\\n bytes paymasterContext;\\n }\\n\\n /**\\n * returned aggregated signature info.\\n * the aggregator returned by the account, and its current stake.\\n */\\n struct AggregatorStakeInfo {\\n address aggregator;\\n StakeInfo stakeInfo;\\n }\\n\\n /**\\n * Get counterfactual sender address.\\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\\n * this method always revert, and returns the address in SenderAddressResult error\\n * @param initCode the constructor code to be passed into the UserOperation.\\n */\\n function getSenderAddress(bytes memory initCode) external;\\n\\n /**\\n * simulate full execution of a UserOperation (including both validation and target execution)\\n * this method will always revert with \\\"ExecutionResult\\\".\\n * it performs full validation of the UserOperation, but ignores signature error.\\n * an optional target address is called after the userop succeeds, and its value is returned\\n * (before the entire call is reverted)\\n * Note that in order to collect the the success/failure of the target call, it must be executed\\n * with trace enabled to track the emitted events.\\n * @param op the UserOperation to simulate\\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\\n * are set to the return from that call.\\n * @param targetCallData callData to pass to target address\\n */\\n function simulateHandleOp(\\n UserOperation calldata op,\\n address target,\\n bytes calldata targetCallData\\n ) external;\\n}\\n\",\"keccak256\":\"0x9ccb1b188eda8bbf5f6c2d01bd83c3d8b2b04fcf745283051d31fe96d1d8e40f\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/INonceManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\ninterface INonceManager {\\n /**\\n * Return the next nonce for this sender.\\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\\n * But UserOp with different keys can come with arbitrary order.\\n *\\n * @param sender the account address\\n * @param key the high 192 bit of the nonce\\n * @return nonce a full nonce to pass for next UserOp with this sender.\\n */\\n function getNonce(\\n address sender,\\n uint192 key\\n ) external view returns (uint256 nonce);\\n\\n /**\\n * Manually increment the nonce of the sender.\\n * This method is exposed just for completeness..\\n * Account does NOT need to call it, neither during validation, nor elsewhere,\\n * as the EntryPoint will update the nonce regardless.\\n * Possible use-case is call it with various keys to \\\"initialize\\\" their nonces to one, so that future\\n * UserOperations will not pay extra for the first transaction with a given key.\\n */\\n function incrementNonce(uint192 key) external;\\n}\\n\",\"keccak256\":\"0xce478ad0fa0d18a3b785ac854623029e7ab463d05873dfaa365abfa1bf100912\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IStakeManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8.12;\\n\\n/**\\n * manage deposits and stakes.\\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\\n * stake is value locked for at least \\\"unstakeDelay\\\" by the staked entity.\\n */\\ninterface IStakeManager {\\n event Deposited(address indexed account, uint256 totalDeposit);\\n\\n event Withdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /// Emitted when stake or unstake delay are modified\\n event StakeLocked(\\n address indexed account,\\n uint256 totalStaked,\\n uint256 unstakeDelaySec\\n );\\n\\n /// Emitted once a stake is scheduled for withdrawal\\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\\n\\n event StakeWithdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /**\\n * @param deposit the entity's deposit\\n * @param staked true if this entity is staked.\\n * @param stake actual amount of ether staked for this entity.\\n * @param unstakeDelaySec minimum delay to withdraw the stake.\\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\\n * and the rest fit into a 2nd cell.\\n * 112 bit allows for 10^15 eth\\n * 48 bit for full timestamp\\n * 32 bit allows 150 years for unstake delay\\n */\\n struct DepositInfo {\\n uint112 deposit;\\n bool staked;\\n uint112 stake;\\n uint32 unstakeDelaySec;\\n uint48 withdrawTime;\\n }\\n\\n //API struct used by getStakeInfo and simulateValidation\\n struct StakeInfo {\\n uint256 stake;\\n uint256 unstakeDelaySec;\\n }\\n\\n /// @return info - full deposit information of given account\\n function getDepositInfo(\\n address account\\n ) external view returns (DepositInfo memory info);\\n\\n /// @return the deposit (for gas payment) of the account\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * add to the deposit of the given account\\n */\\n function depositTo(address account) external payable;\\n\\n /**\\n * add to the account's stake - amount and delay\\n * any pending unstake is first cancelled.\\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\\n */\\n function addStake(uint32 _unstakeDelaySec) external payable;\\n\\n /**\\n * attempt to unlock the stake.\\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\\n */\\n function unlockStake() external;\\n\\n /**\\n * withdraw from the (unlocked) stake.\\n * must first call unlockStake and wait for the unstakeDelay to pass\\n * @param withdrawAddress the address to send withdrawn value.\\n */\\n function withdrawStake(address payable withdrawAddress) external;\\n\\n /**\\n * withdraw from the deposit.\\n * @param withdrawAddress the address to send withdrawn value.\\n * @param withdrawAmount the amount to withdraw.\\n */\\n function withdrawTo(\\n address payable withdrawAddress,\\n uint256 withdrawAmount\\n ) external;\\n}\\n\",\"keccak256\":\"0xadcea606c9b7aafe6645441f2154a60f271330b0eee5292a632aa71c1672d546\",\"license\":\"GPL-3.0-only\"},\"contracts/aa-4337/interfaces/UserOperation.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable no-inline-assembly */\\n\\nimport {calldataKeccak} from \\\"../core/Helpers.sol\\\";\\n\\n/**\\n * User Operation struct\\n * @param sender the sender account of this request.\\n * @param nonce unique value the sender uses to verify it is not a replay.\\n * @param initCode if set, the account contract will be created by this constructor/\\n * @param callData the method call to execute on this account.\\n * @param callGasLimit the gas limit passed to the callData method call.\\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\\n * @param maxFeePerGas same as EIP-1559 gas parameter.\\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\\n */\\nstruct UserOperation {\\n address sender;\\n uint256 nonce;\\n bytes initCode;\\n bytes callData;\\n uint256 callGasLimit;\\n uint256 verificationGasLimit;\\n uint256 preVerificationGas;\\n uint256 maxFeePerGas;\\n uint256 maxPriorityFeePerGas;\\n bytes paymasterAndData;\\n bytes signature;\\n}\\n\\n/**\\n * Utility functions helpful when working with UserOperation structs.\\n */\\nlibrary UserOperationLib {\\n function getSender(\\n UserOperation calldata userOp\\n ) internal pure returns (address) {\\n address data;\\n //read sender from userOp, which is first userOp member (saves 800 gas...)\\n assembly {\\n data := calldataload(userOp)\\n }\\n return address(uint160(data));\\n }\\n\\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\\n // pay above what he signed for.\\n function gasPrice(\\n UserOperation calldata userOp\\n ) internal view returns (uint256) {\\n unchecked {\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n if (maxFeePerGas == maxPriorityFeePerGas) {\\n //legacy mode (for networks that don't support basefee opcode)\\n return maxFeePerGas;\\n }\\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\\n }\\n }\\n\\n function pack(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes memory ret) {\\n address sender = getSender(userOp);\\n uint256 nonce = userOp.nonce;\\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\\n bytes32 hashCallData = calldataKeccak(userOp.callData);\\n uint256 callGasLimit = userOp.callGasLimit;\\n uint256 verificationGasLimit = userOp.verificationGasLimit;\\n uint256 preVerificationGas = userOp.preVerificationGas;\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\\n\\n return\\n abi.encode(\\n sender,\\n nonce,\\n hashInitCode,\\n hashCallData,\\n callGasLimit,\\n verificationGasLimit,\\n preVerificationGas,\\n maxFeePerGas,\\n maxPriorityFeePerGas,\\n hashPaymasterAndData\\n );\\n }\\n\\n function hash(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes32) {\\n return keccak256(pack(userOp));\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n}\\n\",\"keccak256\":\"0x2429f5cc546bdee08c7e63858d0dda8491eaa3ab5194df884dc948c1154d2834\",\"license\":\"GPL-3.0\"},\"contracts/facets/Modifiers.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {LibGuardian} from \\\"../libraries/LibGuardian.sol\\\";\\nimport {BarzStorage} from \\\"../libraries/LibAppStorage.sol\\\";\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\n\\n/**\\n * @title Modifiers\\n * @dev Responsible for providing modifiers/util functions to Facet contracts\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\nabstract contract Modifiers is BarzStorage {\\n uint8 constant INNER_STRUCT = 0;\\n\\n error CallerNotGuardian();\\n error CallerNotGuardianOrOwner();\\n error DuplicateApprover();\\n error ZeroApproverLength();\\n error UnregisteredFacetAndSelectors();\\n\\n /**\\n * @notice Modifier to only allow guardian to make a call, reverts if any other entity is the caller\\n */\\n modifier onlyGuardian() {\\n if (!LibGuardian.isGuardian(msg.sender)) revert CallerNotGuardian();\\n _;\\n }\\n\\n /**\\n * @notice Modifier to only allow guardian or owner to make a call, reverts if any other entity is the caller\\n */\\n modifier onlyGuardianOrOwner() {\\n if (!LibGuardian.isGuardian(msg.sender) && address(this) != msg.sender)\\n revert CallerNotGuardianOrOwner();\\n _;\\n }\\n\\n /**\\n * @notice Checks if the approver address is the array is unique with no duplicate\\n * @dev This method loops through the array and checks if a duplicate address exists, it reverts if duplicate address exists\\n * @param approvers Array of address\\n */\\n function _checkApprover(\\n address[] memory approvers\\n ) internal pure returns (bool) {\\n uint256 approverLength = approvers.length;\\n if (0 == approverLength) revert ZeroApproverLength();\\n for (uint256 i; i < approverLength - 1; ) {\\n for (uint256 j = i + 1; j < approverLength; ) {\\n if (approvers[i] == approvers[j]) {\\n revert DuplicateApprover(); // Found a duplicate\\n }\\n unchecked {\\n ++j;\\n }\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n return false; // No duplicates found\\n }\\n\\n /**\\n * @notice Checks if the facet getting added or replaced is registered to facet registry\\n * @dev This method loops through the cut and checks if the facet getting added/replaced is registered to facet registry\\n * @param _diamondCut Array of FacetCut, data for diamondCut defined in EIP-2535\\n */\\n function _checkFacetCutValidity(\\n IDiamondCut.FacetCut[] memory _diamondCut\\n ) internal view {\\n uint256 diamondCutLength = _diamondCut.length;\\n for (uint256 i; i < diamondCutLength; ) {\\n if (\\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Add ||\\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Replace\\n ) {\\n if (\\n !s.facetRegistry.areFacetFunctionSelectorsRegistered(\\n _diamondCut[i].facetAddress,\\n _diamondCut[i].functionSelectors\\n )\\n ) revert UnregisteredFacetAndSelectors();\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb42956323d199bdec243a5f9859439aae057fbfdd1d79e3a96afc857ecb3115f\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/DiamondCutFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {LibDiamond} from \\\"../../libraries/LibDiamond.sol\\\";\\nimport {LibGuardian} from \\\"../../libraries/LibGuardian.sol\\\";\\nimport {ISecurityManager} from \\\"../../infrastructure/interfaces/ISecurityManager.sol\\\";\\nimport {SignatureChecker} from \\\"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\\\";\\nimport {LibFacetStorage, DiamondCutApprovalConfig, ApprovalConfig} from \\\"../../libraries/LibFacetStorage.sol\\\";\\nimport {Modifiers} from \\\"../Modifiers.sol\\\";\\nimport {IDiamondCut} from \\\"./interfaces/IDiamondCut.sol\\\";\\n\\n/**\\n * @title DiamondCut Facet\\n * @dev Responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract DiamondCutFacet is Modifiers, IDiamondCut {\\n ISecurityManager public immutable securityManager;\\n\\n /**\\n * @notice This constructor sets the Security Manager address which is an immutable variable.\\n * Immutable variables do not impact the storage of diamond\\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\\n */\\n constructor(address _securityManager) {\\n securityManager = ISecurityManager(_securityManager);\\n }\\n\\n /**\\n * @notice Updates the flag for the interfaceId\\n * @param _interfaceId InterfaceID to update the mapping\\n * @param _flag Bool value to update the mapping of the given interface ID\\n */\\n function updateSupportsInterface(\\n bytes4 _interfaceId,\\n bool _flag\\n ) external override onlyWhenUnlocked {\\n LibDiamond.enforceIsSelf();\\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId] = _flag;\\n emit SupportsInterfaceUpdated(_interfaceId, _flag);\\n }\\n\\n /**\\n * @notice Add/replace/remove any number of functions and optionally execute\\n * a function with delegatecall when guardians don't exist\\n * @param _diamondCut Contains the facet addresses and function selectors\\n * @param _init The address of the contract or facet to execute _calldata. It's prohibited in Barz\\n */\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata\\n ) external override onlyWhenUnlocked {\\n LibDiamond.enforceIsSelf();\\n\\n _checkFacetCutValidity(_diamondCut);\\n // require approval from guardian if guardian exists\\n if (0 != LibGuardian.guardianCount())\\n revert DiamondCutFacet__InvalidRouteWithGuardian();\\n if (address(0) != _init) revert DiamondCutFacet__InvalidInitAddress();\\n\\n unchecked {\\n ++LibFacetStorage.diamondCutStorage().nonce;\\n }\\n LibDiamond.diamondCut(_diamondCut, address(0), \\\"\\\");\\n }\\n\\n /**\\n * @notice Add/replace/remove any number of functions and optionally execute\\n * a function with delegatecall when guardians exist\\n * @param _diamondCut Contains the facet addresses and function selectors\\n * @param _approvers Guardian or owner address that approves the diamond cut\\n * @param _signatures Signature of Guardians or owner that approves the diamond cut\\n */\\n function diamondCutWithGuardian(\\n FacetCut[] calldata _diamondCut,\\n address[] calldata _approvers,\\n bytes[] calldata _signatures\\n ) external override onlyWhenUnlocked {\\n if (_approvers.length != _signatures.length)\\n revert DiamondCutFacet__InvalidArrayLength();\\n _checkFacetCutValidity(_diamondCut);\\n if (0 == LibGuardian.guardianCount())\\n revert DiamondCutFacet__InvalidRouteWithGuardian();\\n\\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\\n\\n _checkApprover(_approvers);\\n _checkDuplicateOnChainApprover(cutHash, _approvers);\\n\\n bool onChainOwnerApproval = getOwnerCutApprovalWithTimeValidity(\\n cutHash\\n );\\n\\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\\n if (\\n _approvers.length +\\n getDiamondCutApprovalCountWithTimeValidity(cutHash) <\\n LibGuardian.majorityOfGuardians() + threshold\\n ) revert DiamondCutFacet__InsufficientApprovers();\\n\\n bool ownerApproved;\\n for (uint256 i; i < _approvers.length; ) {\\n if (\\n !LibGuardian.isGuardian(_approvers[i]) &&\\n _approvers[i] != address(this)\\n ) revert DiamondCutFacet__InvalidApprover();\\n if (_approvers[i] == address(this)) {\\n if (onChainOwnerApproval)\\n revert DiamondCutFacet__OwnerAlreadyApproved();\\n ownerApproved = true;\\n }\\n if (\\n !SignatureChecker.isValidSignatureNow(\\n _approvers[i],\\n cutHash,\\n _signatures[i]\\n )\\n ) revert DiamondCutFacet__InvalidApproverSignature();\\n unchecked {\\n ++i;\\n }\\n }\\n if (!ownerApproved && !onChainOwnerApproval)\\n revert DiamondCutFacet__LackOfOwnerApproval();\\n\\n unchecked {\\n ++LibFacetStorage.diamondCutStorage().nonce;\\n }\\n LibDiamond.diamondCut(_diamondCut, address(0), \\\"\\\");\\n }\\n\\n /**\\n * @notice Approves diamond cut. This can only be called directly from guardian or owner\\n * @param _diamondCut Contains the facet addresses and function selectors\\n */\\n function approveDiamondCut(\\n FacetCut[] calldata _diamondCut\\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\\n if (LibGuardian.guardianCount() == 0)\\n revert DiamondCutFacet__InvalidRouteWithoutGuardian();\\n DiamondCutApprovalConfig storage ds = LibFacetStorage\\n .diamondCutStorage()\\n .diamondCutApprovalConfigs[INNER_STRUCT];\\n _checkFacetCutValidity(_diamondCut);\\n\\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\\n uint64 approvalValidUntil = uint64(\\n block.timestamp + getApprovalValidationPeriod()\\n );\\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(\\n true,\\n approvalValidUntil\\n );\\n emit DiamondCutApproved(_diamondCut);\\n if (\\n (getDiamondCutApprovalCountWithTimeValidity(cutHash) >=\\n LibGuardian.majorityOfGuardians()) &&\\n getOwnerCutApprovalWithTimeValidity(cutHash)\\n ) {\\n unchecked {\\n ++LibFacetStorage.diamondCutStorage().nonce;\\n }\\n LibDiamond.diamondCut(_diamondCut, address(0), \\\"\\\");\\n }\\n }\\n\\n /**\\n * @notice Revokes the approval of diamond cut. This can only be called directly from guardian or owner\\n * @param _diamondCut Contains the facet addresses and function selectors\\n */\\n function revokeDiamondCutApproval(\\n FacetCut[] calldata _diamondCut\\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\\n DiamondCutApprovalConfig storage ds = LibFacetStorage\\n .diamondCutStorage()\\n .diamondCutApprovalConfigs[INNER_STRUCT];\\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\\n if (!ds.isDiamondCutApproved[cutHash][msg.sender].isApproved)\\n revert DiamondCutFacet__CannotRevokeUnapproved();\\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(false, 0);\\n emit DiamondCutApprovalRevoked(_diamondCut);\\n }\\n\\n /**\\n * @notice Gets the number of approvals of diamond cut from guardians\\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\\n */\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 _diamondCutHash\\n ) public view override returns (uint256 approvalCount) {\\n address[] memory guardians = LibGuardian.getGuardians();\\n uint256 guardiansLength = guardians.length;\\n for (uint256 i; i < guardiansLength; ) {\\n if (isCutApproved(_diamondCutHash, guardians[i])) {\\n unchecked {\\n ++approvalCount;\\n }\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n return approvalCount;\\n }\\n\\n /**\\n * @notice Returns if the owner has approved the diamond cut\\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\\n * @return isApprovedByOwner Bool value showing if the owner approved the cut\\n */\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 _diamondCutHash\\n ) public view override returns (bool isApprovedByOwner) {\\n isApprovedByOwner = isCutApproved(_diamondCutHash, address(this));\\n }\\n\\n /**\\n * @notice Returns if the given approver has approved the diamond cut\\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\\n * @param _approver Address of approver\\n * @return isApproved Bool value showing if the approver approved the cut\\n */\\n function isCutApproved(\\n bytes32 _diamondCutHash,\\n address _approver\\n ) public view override returns (bool isApproved) {\\n DiamondCutApprovalConfig storage ds = LibFacetStorage\\n .diamondCutStorage()\\n .diamondCutApprovalConfigs[INNER_STRUCT];\\n isApproved = (ds\\n .isDiamondCutApproved[_diamondCutHash][_approver].isApproved &&\\n block.timestamp <\\n ds.isDiamondCutApproved[_diamondCutHash][_approver].validUntil);\\n }\\n\\n /**\\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\\n * Approvers who approved on-chain should not be included in the off-chain approval\\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\\n * @param _approvers List of approver addresses\\n */\\n function _checkDuplicateOnChainApprover(\\n bytes32 _diamondCutHash,\\n address[] memory _approvers\\n ) public view {\\n address[] memory guardians = LibGuardian.getGuardians();\\n uint256 guardianLength = guardians.length;\\n uint256 approversLength = _approvers.length;\\n for (uint256 i; i < guardianLength; ) {\\n if (isCutApproved(_diamondCutHash, guardians[i])) {\\n for (uint256 j; j < approversLength; ) {\\n if (_approvers[j] == guardians[i])\\n revert DiamondCutFacet__DuplicateApproval();\\n unchecked {\\n ++j;\\n }\\n }\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * @notice Returns the diamond cut hash. This function ensures that this hash is safe from replay attack by including\\n * salt, address, chainId, and nonce, etc.\\n * @param _diamondCut Contains the facet addresses and function selectors\\n * @return cutHash Diamond Cut Hash\\n */\\n function getDiamondCutHash(\\n FacetCut[] calldata _diamondCut\\n ) public view override returns (bytes32 cutHash) {\\n cutHash = keccak256(\\n abi.encodePacked(\\n \\\"\\\\x19Ethereum Signed Message:\\\\n32\\\",\\n keccak256(\\n abi.encode(\\n keccak256(abi.encode(_diamondCut)),\\n address(this),\\n block.chainid,\\n LibFacetStorage.diamondCutStorage().nonce\\n )\\n )\\n )\\n );\\n }\\n\\n /**\\n * @notice Returns the approval validation Period\\n * @dev This method fetches the validation period from the security manager\\n * @return approvalValidationPeriod Approval validation period of Barz contract fetched from security manager\\n */\\n function getApprovalValidationPeriod()\\n internal\\n view\\n returns (uint256 approvalValidationPeriod)\\n {\\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\\n address(this)\\n );\\n if (approvalValidationPeriod <= 0)\\n revert DiamondCutFacet__InvalidApprovalValidationPeriod();\\n }\\n\\n /**\\n * @notice Returns the diamond cut nonce of this wallet\\n * @dev This method fetches the nonce from diamond cut storage\\n * @return cutNonce Nonce of diamond cut to protect from reply attacks\\n */\\n function getDiamondCutNonce()\\n public\\n view\\n override\\n returns (uint128 cutNonce)\\n {\\n cutNonce = LibFacetStorage.diamondCutStorage().nonce;\\n }\\n}\\n\",\"keccak256\":\"0xe91a7dd2daabf2e989c94089f4f1eb0da94276c3070559ac8988838e10dd1f5d\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/infrastructure/interfaces/IFacetRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Registry Interface\\n * @dev Interface for Facet Registry contract to keep track of facets & function selectors addable to user wallets\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IFacetRegistry {\\n struct FacetRegistryConfig {\\n bytes4[] selectors;\\n mapping(bytes4 => FacetInfo) info;\\n }\\n struct FacetInfo {\\n bool exists;\\n uint128 index;\\n }\\n\\n event FacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] facetSelectors\\n );\\n event FacetFunctionSelectorsRemoved(address facet, bytes4[] facetSelectors);\\n\\n error FacetRegistry__FacetSelectorAlreadyRegistered();\\n error FacetRegistry__UnregisteredFacetSelector();\\n\\n function registerFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function removeFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function areFacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external view returns (bool);\\n\\n function isFacetFunctionSelectorRegistered(\\n address facet,\\n bytes4 facetSelector\\n ) external view returns (bool);\\n\\n function getFacetFunctionSelectors(\\n address facet\\n ) external view returns (bytes4[] memory);\\n}\\n\",\"keccak256\":\"0x6e6dd2cab346ef7c31230740ec48d2925e4a9ab24c2f2fb268baaf408dcf02ef\",\"license\":\"Apache-2.0\"},\"contracts/infrastructure/interfaces/ISecurityManager.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Registry Interface\\n * @dev Infrastructure contract to manage security parameters of users\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\ninterface ISecurityManager {\\n error SecurityManager__OutOfBoundary();\\n error SecurityManager__CallerNotWallet();\\n error SecurityManager__AlreadyIntialized();\\n\\n function initializeAdditionSecurityPeriod(\\n uint128 defaultAdditionSecurityPeriod,\\n uint128 minAdditionSecurityPeriod,\\n uint128 maxAdditionSecurityPeriod\\n ) external;\\n\\n function initializeRemovalSecurityPeriod(\\n uint128 defaultRemovalSecurityPeriod,\\n uint128 minRemovalSecurityPeriod,\\n uint128 maxRemovalSecurityPeriod\\n ) external;\\n\\n function initializeApprovalValidationPeriod(\\n uint128 defaultApprovalValidationPeriod,\\n uint128 minApprovalValidationPeriod,\\n uint128 maxApprovalValidationPeriod\\n ) external;\\n\\n function initializeMigrationPeriod(\\n uint128 defaultMigrationPeriod,\\n uint128 minMigrationPeriod,\\n uint128 maxMigrationPeriod\\n ) external;\\n\\n function initializeLockPeriod(\\n uint128 defaultLockPeriod,\\n uint128 minLockPeriod,\\n uint128 maxLockPeriod\\n ) external;\\n\\n function initializeRecoveryPeriod(\\n uint128 defaultRecoveryPeriod,\\n uint128 minRecoveryPeriod,\\n uint128 maxRecoveryPeriod\\n ) external;\\n\\n function initializeSecurityWindow(\\n uint128 defaultSecurityWindow,\\n uint128 minSecurityWindow,\\n uint128 maxSecurityWindow\\n ) external;\\n\\n function setAdditionSecurityPeriod(\\n address wallet,\\n uint128 additionSecurityPeriod\\n ) external;\\n\\n function setRemovalSecurityPeriod(\\n address wallet,\\n uint128 removalSecurityPeriod\\n ) external;\\n\\n function setSecurityWindow(address wallet, uint128 securityWindow) external;\\n\\n function setRecoveryPeriod(address wallet, uint128 recoveryPeriod) external;\\n\\n function setLockPeriod(address wallet, uint128 lockPeriod) external;\\n\\n function setApprovalValidationPeriod(\\n address wallet,\\n uint128 approvalValidationPeriod\\n ) external;\\n\\n function setMigrationPeriod(\\n address wallet,\\n uint128 migrationPeriod\\n ) external;\\n\\n function additionSecurityPeriodOf(\\n address wallet\\n ) external view returns (uint128);\\n\\n function removalSecurityPeriodOf(\\n address wallet\\n ) external view returns (uint128);\\n\\n function securityWindowOf(address wallet) external view returns (uint128);\\n\\n function recoveryPeriodOf(address wallet) external view returns (uint128);\\n\\n function lockPeriodOf(address wallet) external view returns (uint128);\\n\\n function migrationPeriodOf(address wallet) external view returns (uint128);\\n\\n function approvalValidationPeriodOf(\\n address wallet\\n ) external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x9ac6566033ef81ba5744c8ed2b08f130b781b498ab9245bcca87567669549552\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibAppStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {SafeCast} from \\\"@openzeppelin/contracts/utils/math/SafeCast.sol\\\";\\nimport {IEntryPoint} from \\\"../aa-4337/interfaces/IEntryPoint.sol\\\";\\nimport {IFacetRegistry} from \\\"../infrastructure/interfaces/IFacetRegistry.sol\\\";\\n\\n/*\\n * @title App Storage\\n * @dev App storage for Barz contract to prevent storage collision\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Lock {\\n uint64 release;\\n bytes4 locker;\\n}\\n\\nstruct InitializersStorage {\\n // NOTE: initialized is a variable to make sure the initialization is only done once.\\n uint8 signerInitialized;\\n uint8 accountInitialized;\\n uint8 restrictionsInitialized;\\n}\\n\\nstruct AppStorage {\\n mapping(uint256 => InitializersStorage) initStorage;\\n uint8 signerMigration;\\n bytes4 validateOwnerSignatureSelector;\\n IEntryPoint entryPoint;\\n IFacetRegistry facetRegistry;\\n mapping(uint256 => Lock) locks;\\n}\\n\\nlibrary LibAppStorage {\\n error LibAppStorage__AccountAlreadyUninitialized();\\n error LibAppStorage__AccountMustBeUninitialized();\\n error LibAppStorage__SignerAlreadyUninitialized();\\n error LibAppStorage__SignerMustBeUninitialized();\\n\\n function appStorage() internal pure returns (AppStorage storage ds) {\\n assembly {\\n ds.slot := 0\\n }\\n }\\n\\n function setSignerUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerAlreadyUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 0;\\n }\\n\\n function getValidateOwnerSignatureSelector()\\n internal\\n view\\n returns (bytes4 selector)\\n {\\n selector = appStorage().validateOwnerSignatureSelector;\\n }\\n\\n function setValidateOwnerSignatureSelector(\\n bytes4 _validateOwnerSignatureSelector\\n ) internal {\\n appStorage()\\n .validateOwnerSignatureSelector = _validateOwnerSignatureSelector;\\n }\\n\\n function enforceSignerInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerMustBeUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 1;\\n }\\n\\n function enforceAccountInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].accountInitialized) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n s.initStorage[0].accountInitialized = 1;\\n }\\n\\n function initiateSignerMigration() internal {\\n appStorage().signerMigration = 1;\\n }\\n\\n function enforceSignerMigration() internal view {\\n if (1 != appStorage().signerMigration) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n }\\n\\n function finalizeSignerMigration() internal {\\n appStorage().signerMigration = 0;\\n }\\n\\n function setLock(uint256 _releaseAfter, bytes4 _locker) internal {\\n appStorage().locks[0] = Lock(SafeCast.toUint64(_releaseAfter), _locker);\\n }\\n\\n function enforceRestrictionsInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__SignerMustBeUninitialized();\\n s.initStorage[0].restrictionsInitialized = 1;\\n }\\n\\n function setRestrictionsUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__AccountAlreadyUninitialized();\\n s.initStorage[0].restrictionsInitialized = 0;\\n }\\n}\\n\\ncontract BarzStorage {\\n AppStorage internal s;\\n modifier onlyWhenUnlocked() {\\n require(\\n uint64(block.timestamp) >= s.locks[0].release,\\n \\\"Account Locked\\\"\\n );\\n _;\\n }\\n modifier onlyWhenLocked() {\\n require(\\n uint64(block.timestamp) < s.locks[0].release,\\n \\\"Account Unlocked\\\"\\n );\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x48524007862a6ce0e07f645950613ce6513ce073c37a109c75019683d42bae27\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\\n bytes4(keccak256(\\\"verifyRestrictions(address,address,uint256,bytes)\\\"));\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // Default Fallback Handler of the barz.\\n IDiamondLoupe defaultFallbackHandler;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function enforceIsSelf() internal view {\\n require(msg.sender == address(this), \\\"LibDiamond: Caller not self\\\");\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n\\n unchecked {\\n facetIndex++;\\n }\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n\\n function restrictionsFacet() internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(\\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2cabdc00de859c3a3170ce3bda5d0e5fd3933d47ce904fd1585f9818b02572f8\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibFacetStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Storage\\n * @dev Storage contract to store each facets variables with diamond storage\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Secp256k1VerificationStorage {\\n address signer;\\n}\\n\\nstruct Secp256r1VerificationStorage {\\n uint256[2] q;\\n}\\n\\nstruct GuardianStorage {\\n mapping(bytes32 => uint256) pending;\\n mapping(uint8 => StorageConfig) configs;\\n}\\n\\nstruct Info {\\n bool exists;\\n uint128 index;\\n}\\n\\nstruct StorageConfig {\\n address[] addresses;\\n mapping(address => Info) info;\\n}\\n\\nstruct RecoveryConfig {\\n bytes recoveryPublicKey;\\n uint64 executeAfter;\\n}\\n\\nstruct ApprovalConfig {\\n bool isApproved;\\n uint64 validUntil;\\n}\\n\\nstruct RecoveryApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isNewOwnerApproved;\\n}\\n\\nstruct RecoveryStorage {\\n mapping(uint8 => RecoveryConfig) recoveryConfigs;\\n mapping(uint8 => RecoveryApprovalConfig) recoveryApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct RestrictionsStorage {\\n address[] restrictions;\\n mapping(address => bool) exists;\\n}\\n\\nstruct SignatureMigrationConfig {\\n bytes migrationPublicKey;\\n address migrationVerificationFacet;\\n bytes4[] migrationSelectors;\\n uint64 migrateAfter;\\n}\\n\\nstruct SignatureMigrationApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isMigrationApproved;\\n}\\n\\nstruct SignatureMigrationStorage {\\n mapping(uint8 => SignatureMigrationConfig) migrationConfigs;\\n mapping(uint8 => SignatureMigrationApprovalConfig) migrationApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct DiamondCutApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isDiamondCutApproved;\\n}\\n\\nstruct DiamondCutStorage {\\n mapping(uint8 => DiamondCutApprovalConfig) diamondCutApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct LockStorage {\\n uint128 nonce;\\n}\\n\\nlibrary LibFacetStorage {\\n bytes32 constant K1_STORAGE_POSITION =\\n keccak256(\\n \\\"v0.trustwallet.diamond.storage.Secp256k1VerificationStorage\\\"\\n );\\n bytes32 constant R1_STORAGE_POSITION =\\n keccak256(\\n \\\"v0.trustwallet.diamond.storage.Secp256r1VerificationStorage\\\"\\n );\\n bytes32 constant GUARDIAN_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.GuardianStorage\\\");\\n bytes32 constant RECOVERY_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.RecoveryStorage\\\");\\n bytes32 constant RESTRICTION_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.RestrictionsStorage\\\");\\n bytes32 constant MIGRATION_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.SignatureMigrationStorage\\\");\\n bytes32 constant DIAMONDCUT_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.DiamondCutStorage\\\");\\n bytes32 constant LOCK_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.LockStorage\\\");\\n\\n function k1Storage()\\n internal\\n pure\\n returns (Secp256k1VerificationStorage storage ds)\\n {\\n bytes32 storagePosition = K1_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function r1Storage()\\n internal\\n pure\\n returns (Secp256r1VerificationStorage storage ds)\\n {\\n bytes32 storagePosition = R1_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function guardianStorage()\\n internal\\n pure\\n returns (GuardianStorage storage ds)\\n {\\n bytes32 storagePosition = GUARDIAN_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function recoveryStorage()\\n internal\\n pure\\n returns (RecoveryStorage storage ds)\\n {\\n bytes32 storagePosition = RECOVERY_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function restrictionsStorage()\\n internal\\n pure\\n returns (RestrictionsStorage storage ds)\\n {\\n bytes32 storagePosition = RESTRICTION_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function migrationStorage()\\n internal\\n pure\\n returns (SignatureMigrationStorage storage ds)\\n {\\n bytes32 storagePosition = MIGRATION_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function diamondCutStorage()\\n internal\\n pure\\n returns (DiamondCutStorage storage ds)\\n {\\n bytes32 storagePosition = DIAMONDCUT_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function lockStorage() internal pure returns (LockStorage storage ds) {\\n bytes32 storagePosition = LOCK_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n}\\n\",\"keccak256\":\"0x87c85decfd943deda9540733e464cb1a92eba735a301e89ce6f798016e359761\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibGuardian.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {LibFacetStorage, StorageConfig} from \\\"./LibFacetStorage.sol\\\";\\n\\n/**\\n * @title LibGuardian\\n * @dev Internal Library to provide utility feature for Guardians stored in Guardian Facet Storage\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\nlibrary LibGuardian {\\n function majorityOfGuardians()\\n internal\\n view\\n returns (uint256 guardianNumber)\\n {\\n uint256 guardianLength = guardianCount();\\n guardianNumber = (guardianLength == 0) ? 0 : guardianLength / 2 + 1;\\n }\\n\\n function isGuardian(address _guardian) internal view returns (bool) {\\n StorageConfig storage config = LibFacetStorage\\n .guardianStorage()\\n .configs[0];\\n return config.info[_guardian].exists;\\n }\\n\\n function guardianCount() internal view returns (uint256) {\\n StorageConfig storage config = LibFacetStorage\\n .guardianStorage()\\n .configs[0];\\n return config.addresses.length;\\n }\\n\\n function getGuardians() internal view returns (address[] memory) {\\n StorageConfig storage config = LibFacetStorage\\n .guardianStorage()\\n .configs[0];\\n address[] memory addresses = new address[](config.addresses.length);\\n uint256 addressesLen = config.addresses.length;\\n for (uint256 i; i < addressesLen; ) {\\n addresses[i] = config.addresses[i];\\n unchecked {\\n ++i;\\n }\\n }\\n return addresses;\\n }\\n}\\n\",\"keccak256\":\"0x6a620992d5535878fc03d1a27a6675f4c1509adfb3ddbbca1c52b546c25392dc\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x60a06040523480156200001157600080fd5b506040516200379b3803806200379b833981016040819052620000349162000046565b6001600160a01b031660805262000078565b6000602082840312156200005957600080fd5b81516001600160a01b03811681146200007157600080fd5b9392505050565b6080516137006200009b600039600081816101f10152611b2501526137006000f3fe608060405234801561001057600080fd5b50600436106100d45760003560e01c806379c0d58d11610081578063afb877bb1161005b578063afb877bb146101d9578063de675a6d146101ec578063e33ecf0a1461023857600080fd5b806379c0d58d14610192578063836d6bfb146101b35780638824a0bb146101c657600080fd5b806326fc3ef4116100b257806326fc3ef4146101145780632f4d98ea1461015c5780633c0985681461017f57600080fd5b806313c34f4b146100d95780631c776dd5146100ee5780631f931c1c14610101575b600080fd5b6100ec6100e7366004612a97565b61024b565b005b6100ec6100fc366004612ad9565b6104df565b6100ec61010f366004612b9c565b610a76565b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9bf546040516fffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b61016f61016a366004612c4a565b610c7b565b6040519015158152602001610153565b6100ec61018d366004612ca4565b610c8d565b6101a56101a0366004612c4a565b610df2565b604051908152602001610153565b61016f6101c1366004612cdb565b610e4c565b6100ec6101d4366004612dd2565b610eed565b6100ec6101e7366004612a97565b610fe1565b6102137f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610153565b6101a5610246366004612a97565b61130e565b3360009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff1615801561028a5750303314155b156102c1576040517f6238ee3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610369576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064015b60405180910390fd5b60008080527f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be6020527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d3906103be848461130e565b60008181526020848152604080832033845290915290205490915060ff16610412576040517fedc5708300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051808201825260008082526020808301828152858352868252848320338452909152908390209151825491517fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000009092169015157fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff161761010067ffffffffffffffff90921691909102179055517f3c3d8c1f0b0faff6fe0ace6b485d0595a0106dce9e303f956fd941ebdbe9a98e906104d19086908690612f54565b60405180910390a150505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610582576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b8281146105bb576040517fe854148500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6105cd6105c886886130aa565b611435565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b754600003610650576040517fa788861700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061065c878761130e565b905061069a8585808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506115b392505050565b506106d881868680806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250610eed92505050565b60006106e382610c7b565b90506000816106f35760016106f6565b60005b60ff169050806107046116d0565b61070e9190613201565b61071784610df2565b6107219088613201565b1015610759576040517f709fb08000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805b878110156109a0576107d989898381811061077a5761077a613214565b905060200201602081019061078f9190613243565b73ffffffffffffffffffffffffffffffffffffffff1660009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff1690565b1580156108225750308989838181106107f4576107f4613214565b90506020020160208101906108099190613243565b73ffffffffffffffffffffffffffffffffffffffff1614155b15610859576040517f7b2cbbb400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3089898381811061086c5761086c613214565b90506020020160208101906108819190613243565b73ffffffffffffffffffffffffffffffffffffffff16036108d95783156108d4576040517fee21708000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600191505b6109628989838181106108ee576108ee613214565b90506020020160208101906109039190613243565b8689898581811061091657610916613214565b90506020028101906109289190613265565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061174f92505050565b610998576040517fac3d341600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60010161075d565b50801580156109ad575082155b156109e4576040517f6d21730400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9bf80546fffffffffffffffffffffffffffffffff808216600101167fffffffffffffffffffffffffffffffff00000000000000000000000000000000909116179055610a6a610a538a8c6130aa565b6000604051806020016040528060008152506117ca565b50505050505050505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610b19576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b610b2161195f565b610b2e6105c885876130aa565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75415610baf576040517fa788861700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff831615610bfd576040517f871cb76100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be5b600190810180547fffffffffffffffffffffffffffffffff0000000000000000000000000000000081166fffffffffffffffffffffffffffffffff91821690930116919091179055610c74610a5385876130aa565b5050505050565b6000610c878230610e4c565b92915050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610d30576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b610d3861195f565b7fffffffff00000000000000000000000000000000000000000000000000000000821660008181527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4922602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001685151590811790915582519384529083015280517f4e6bd17989efa6d6a9607ccaac1bba27b29f99622bc830d99a3a9883b21a19c79281900390910190a15050565b600080610dfd6119ca565b805190915060005b81811015610e4457610e3085848381518110610e2357610e23613214565b6020026020010151610e4c565b15610e3c578360010193505b600101610e05565b505050919050565b60008281527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d36020818152604080842073ffffffffffffffffffffffffffffffffffffffff8616855290915282205460ff168015610ee5575060008481526020828152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152902054610100900467ffffffffffffffff1642105b949350505050565b6000610ef76119ca565b805183519192509060005b82811015610fd957610f2086858381518110610e2357610e23613214565b15610fd15760005b82811015610fcf57848281518110610f4257610f42613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16868281518110610f7257610f72613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603610fc7576040517f50f5729f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600101610f28565b505b600101610f02565b505050505050565b3360009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff161580156110205750303314155b15611057576040517f6238ee3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff9081164290911610156110fa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75460000361117d576040517f3a76e1f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080527f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be6020527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d36111d36105c883856130aa565b60006111df848461130e565b905060006111eb611af4565b6111f59042613201565b6040805180820182526001815267ffffffffffffffff838116602080840191825260008881528982528581203382529091528490209251835491517fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000009092169015157fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff16176101009190921602179055519091507f6248ff757895beed7d43d135bccf59a26b7fbdf0fe8233487c44e82c0f266ba3906112b89087908790612f54565b60405180910390a16112c86116d0565b6112d183610df2565b101580156112e357506112e382610c7b565b15610c74577f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be610c1f565b60008282604051602001611323929190612f54565b6040516020818303038152906040528051906020012030466113627f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be90565b6001015460408051602081019590955273ffffffffffffffffffffffffffffffffffffffff9093169284019290925260608301526fffffffffffffffffffffffffffffffff16608082015260a001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905280516020918201207f19457468657265756d205369676e6564204d6573736167653a0a33320000000091830191909152603c820152605c0160405160208183030381529060405280519060200120905092915050565b805160005b818110156115ae57600083828151811061145657611456613214565b602002602001015160200151600281111561147357611473612e8a565b14806114ad5750600183828151811061148e5761148e613214565b60200260200101516020015160028111156114ab576114ab612e8a565b145b156115a657600254835173ffffffffffffffffffffffffffffffffffffffff9091169063df871f72908590849081106114e8576114e8613214565b60200260200101516000015185848151811061150657611506613214565b6020026020010151604001516040518363ffffffff1660e01b815260040161152f92919061331c565b602060405180830381865afa15801561154c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611570919061334b565b6115a6576040517ff41a931c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60010161143a565b505050565b80516000908082036115f1576040517f3aee2eec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b6115ff600183613368565b8110156116c6576000611613826001613201565b90505b828110156116bd5784818151811061163057611630613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1685838151811061166057611660613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16036116b5576040517f8dd19e7d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600101611616565b506001016115f4565b5060009392505050565b600080611723600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75490565b905080156117465761173660028261337b565b611741906001613201565b611749565b60005b91505090565b600080600061175e8585611bf6565b9092509050600081600481111561177757611777612e8a565b1480156117af57508573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b806117c057506117c0868686611c3b565b9695505050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921547f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff8116908190600090600716156118395750600381901c60009081526001840160205260409020545b60005b87518110156118b6576118a983838a848151811061185c5761185c613214565b6020026020010151600001518b858151811061187a5761187a613214565b6020026020010151602001518c868151811061189857611898613214565b602002602001015160400151611d98565b909350915060010161183c565b508282146118ef576002840180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff84161790555b600782161561191157600382901c600090815260018501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb67387878760405161194493929190613424565b60405180910390a16119568686612829565b50505050505050565b3330146119c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4c69624469616d6f6e643a2043616c6c6572206e6f742073656c6600000000006044820152606401610360565b565b60008080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b780546060929067ffffffffffffffff811115611a3257611a32612d07565b604051908082528060200260200182016040528015611a5b578160200160208202803683370190505b50825490915060005b81811015611aeb57836000018181548110611a8157611a81613214565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16838281518110611abe57611abe613214565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101611a64565b50909392505050565b6040517f52430c8d0000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906352430c8d90602401602060405180830381865afa158015611b81573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ba59190613510565b6fffffffffffffffffffffffffffffffff16905060008111611bf3576040517fdac5ec8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b90565b6000808251604103611c2c5760208301516040840151606085015160001a611c2087828585612928565b94509450505050611c34565b506000905060025b9250929050565b60008060008573ffffffffffffffffffffffffffffffffffffffff16631626ba7e60e01b8686604051602401611c72929190613542565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909416939093179092529051611cfb919061355b565b600060405180830381855afa9150503d8060008114611d36576040519150601f19603f3d011682016040523d82523d6000602084013e611d3b565b606091505b5091509150818015611d4f57506020815110155b80156117c0575080517f1626ba7e0000000000000000000000000000000000000000000000000000000090611d8d9083016020908101908401613577565b149695505050505050565b600080807f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f90506000845111611e50576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610360565b6000856002811115611e6457611e64612e8a565b0361203457611e8b8660405180606001604052806024815260200161365760249139612a17565b60005b845181101561202e576000858281518110611eab57611eab613214565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c15611f7e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c72656164792065786973747300000000000000000000006064820152608401610360565b7fffffffff0000000000000000000000000000000000000000000000000000000080831660008181526020879052604090207fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608d901b168e17905560e060058e901b811692831c199c909c1690821c179a8190036120125760038c901c600090815260018601602052604081209b909b555b8b61201c81613590565b9c505060019093019250611e8e915050565b5061281d565b600185600281111561204857612048612e8a565b036123385761206f866040518060600160405280602881526020016136a360289139612a17565b60005b845181101561202e57600085828151811061208f5761208f613214565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c308103612164576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4c69624469616d6f6e644375743a2043616e2774207265706c61636520696d6d60448201527f757461626c652066756e6374696f6e00000000000000000000000000000000006064820152608401610360565b8973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361221f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e00000000000000006064820152608401610360565b73ffffffffffffffffffffffffffffffffffffffff81166122c2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e207468617420646f65736e277420657869737400000000000000006064820152608401610360565b507fffffffff0000000000000000000000000000000000000000000000000000000090911660009081526020849052604090206bffffffffffffffffffffffff919091167fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608a901b16179055600101612072565b600285600281111561234c5761234c612e8a565b036127955773ffffffffffffffffffffffffffffffffffffffff8616156123f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d7573742062652061646472657373283029000000000000000000006064820152608401610360565b600388901c6007891660005b86518110156127755760008a900361243d578261241d816135c8565b60008181526001870160205260409020549b5093506007925061244b9050565b81612447816135c8565b9250505b6000806000808a858151811061246357612463613214565b6020908102919091018101517fffffffff0000000000000000000000000000000000000000000000000000000081166000908152918a9052604090912054909150606081901c612535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608401610360565b30606082901c036125c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e0000000000000000000000000000000000006064820152608401610360565b600587901b8f901b94507fffffffff0000000000000000000000000000000000000000000000000000000080861690831614612666577fffffffff000000000000000000000000000000000000000000000000000000008516600090815260208a90526040902080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff83161790555b7fffffffff0000000000000000000000000000000000000000000000000000000091909116600090815260208990526040812055600381901c611fff16925060051b60e01690508582146126fb576000828152600188016020526040902080547fffffffff0000000000000000000000000000000000000000000000000000000080841c19909116908516831c17905561274c565b80837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c817fffffffff0000000000000000000000000000000000000000000000000000000060001b901c198e16179c505b8460000361276a57600086815260018801602052604081208190559c505b505050600101612401565b50806127828360086135fd565b61278c9190613201565b9950505061281d565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560448201527f74416374696f6e000000000000000000000000000000000000000000000000006064820152608401610360565b50959694955050505050565b73ffffffffffffffffffffffffffffffffffffffff8216612848575050565b61286a8260405180606001604052806028815260200161367b60289139612a17565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051612892919061355b565b600060405180830381855af49150503d80600081146128cd576040519150601f19603f3d011682016040523d82523d6000602084013e6128d2565b606091505b509150915081612922578051156128ec5780518082602001fd5b83836040517f192105d7000000000000000000000000000000000000000000000000000000008152600401610360929190613614565b50505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561295f5750600090506003612a0e565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156129b3573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116612a0757600060019250925050612a0e565b9150600090505b94509492505050565b813b8181612922576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103609190613643565b60008083601f840112612a6457600080fd5b50813567ffffffffffffffff811115612a7c57600080fd5b6020830191508360208260051b8501011115611c3457600080fd5b60008060208385031215612aaa57600080fd5b823567ffffffffffffffff811115612ac157600080fd5b612acd85828601612a52565b90969095509350505050565b60008060008060008060608789031215612af257600080fd5b863567ffffffffffffffff80821115612b0a57600080fd5b612b168a838b01612a52565b90985096506020890135915080821115612b2f57600080fd5b612b3b8a838b01612a52565b90965094506040890135915080821115612b5457600080fd5b50612b6189828a01612a52565b979a9699509497509295939492505050565b803573ffffffffffffffffffffffffffffffffffffffff81168114612b9757600080fd5b919050565b600080600080600060608688031215612bb457600080fd5b853567ffffffffffffffff80821115612bcc57600080fd5b612bd889838a01612a52565b9097509550859150612bec60208901612b73565b94506040880135915080821115612c0257600080fd5b818801915088601f830112612c1657600080fd5b813581811115612c2557600080fd5b896020828501011115612c3757600080fd5b9699959850939650602001949392505050565b600060208284031215612c5c57600080fd5b5035919050565b80357fffffffff0000000000000000000000000000000000000000000000000000000081168114612b9757600080fd5b8015158114612ca157600080fd5b50565b60008060408385031215612cb757600080fd5b612cc083612c63565b91506020830135612cd081612c93565b809150509250929050565b60008060408385031215612cee57600080fd5b82359150612cfe60208401612b73565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff81118282101715612d5957612d59612d07565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715612da657612da6612d07565b604052919050565b600067ffffffffffffffff821115612dc857612dc8612d07565b5060051b60200190565b60008060408385031215612de557600080fd5b8235915060208084013567ffffffffffffffff811115612e0457600080fd5b8401601f81018613612e1557600080fd5b8035612e28612e2382612dae565b612d5f565b81815260059190911b82018301908381019088831115612e4757600080fd5b928401925b82841015612e6c57612e5d84612b73565b82529284019290840190612e4c565b80955050505050509250929050565b803560038110612b9757600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60038110612ef0577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b8183526000602080850194508260005b85811015612f49577fffffffff00000000000000000000000000000000000000000000000000000000612f3683612c63565b1687529582019590820190600101612f04565b509495945050505050565b60208082528181018390526000906040808401600586811b8601830188865b8981101561309b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc089840301855281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa18c3603018112612fd457600080fd5b8b01606073ffffffffffffffffffffffffffffffffffffffff612ff683612b73565b168552613004898301612e7b565b6130108a870182612eb9565b50878201357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe183360301811261304557600080fd5b90910188810191903567ffffffffffffffff81111561306357600080fd5b80871b360383131561307457600080fd5b81898701526130868287018285612ef4565b978a0197955050509187019150600101612f73565b50909998505050505050505050565b60006130b8612e2384612dae565b83815260208082019190600586811b8601368111156130d657600080fd5b865b818110156131c557803567ffffffffffffffff808211156130f95760008081fd5b818a0191506060823603121561310f5760008081fd5b613117612d36565b61312083612b73565b815261312d878401612e7b565b87820152604080840135838111156131455760008081fd5b939093019236601f85011261315c57600092508283fd5b8335925061316c612e2384612dae565b83815292871b840188019288810190368511156131895760008081fd5b948901945b848610156131ae5761319f86612c63565b8252948901949089019061318e565b9183019190915250885250509483019483016130d8565b5092979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610c8757610c876131d2565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561325557600080fd5b61325e82612b73565b9392505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261329a57600080fd5b83018035915067ffffffffffffffff8211156132b557600080fd5b602001915036819003821315611c3457600080fd5b600081518084526020808501945080840160005b83811015612f495781517fffffffff0000000000000000000000000000000000000000000000000000000016875295820195908201906001016132de565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000610ee560408301846132ca565b60006020828403121561335d57600080fd5b815161325e81612c93565b81810381811115610c8757610c876131d2565b6000826133b1577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60005b838110156133d15781810151838201526020016133b9565b50506000910152565b600081518084526133f28160208601602086016133b6565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6000606080830181845280875180835260808601915060808160051b87010192506020808a0160005b838110156134d4577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80898703018552815173ffffffffffffffffffffffffffffffffffffffff8151168752838101516134a885890182612eb9565b506040908101519087018890526134c1878901826132ca565b965050938201939082019060010161344d565b505073ffffffffffffffffffffffffffffffffffffffff8916908701525050838103604085015261350581866133da565b979650505050505050565b60006020828403121561352257600080fd5b81516fffffffffffffffffffffffffffffffff8116811461325e57600080fd5b828152604060208201526000610ee560408301846133da565b6000825161356d8184602087016133b6565b9190910192915050565b60006020828403121561358957600080fd5b5051919050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036135c1576135c16131d2565b5060010190565b6000816135d7576135d76131d2565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b8082028115828204841417610c8757610c876131d2565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000610ee560408301846133da565b60208152600061325e60208301846133da56fe4c69624469616d6f6e644375743a2041646420666163657420686173206e6f20636f64654c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a205265706c61636520666163657420686173206e6f20636f6465a2646970667358221220c5a8c10b22f20cde3fe0431ff57305237423677a60888f5b349fc6751336ae1464736f6c63430008150033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100d45760003560e01c806379c0d58d11610081578063afb877bb1161005b578063afb877bb146101d9578063de675a6d146101ec578063e33ecf0a1461023857600080fd5b806379c0d58d14610192578063836d6bfb146101b35780638824a0bb146101c657600080fd5b806326fc3ef4116100b257806326fc3ef4146101145780632f4d98ea1461015c5780633c0985681461017f57600080fd5b806313c34f4b146100d95780631c776dd5146100ee5780631f931c1c14610101575b600080fd5b6100ec6100e7366004612a97565b61024b565b005b6100ec6100fc366004612ad9565b6104df565b6100ec61010f366004612b9c565b610a76565b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9bf546040516fffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b61016f61016a366004612c4a565b610c7b565b6040519015158152602001610153565b6100ec61018d366004612ca4565b610c8d565b6101a56101a0366004612c4a565b610df2565b604051908152602001610153565b61016f6101c1366004612cdb565b610e4c565b6100ec6101d4366004612dd2565b610eed565b6100ec6101e7366004612a97565b610fe1565b6102137f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610153565b6101a5610246366004612a97565b61130e565b3360009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff1615801561028a5750303314155b156102c1576040517f6238ee3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610369576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064015b60405180910390fd5b60008080527f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be6020527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d3906103be848461130e565b60008181526020848152604080832033845290915290205490915060ff16610412576040517fedc5708300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051808201825260008082526020808301828152858352868252848320338452909152908390209151825491517fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000009092169015157fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff161761010067ffffffffffffffff90921691909102179055517f3c3d8c1f0b0faff6fe0ace6b485d0595a0106dce9e303f956fd941ebdbe9a98e906104d19086908690612f54565b60405180910390a150505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610582576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b8281146105bb576040517fe854148500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6105cd6105c886886130aa565b611435565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b754600003610650576040517fa788861700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061065c878761130e565b905061069a8585808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506115b392505050565b506106d881868680806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250610eed92505050565b60006106e382610c7b565b90506000816106f35760016106f6565b60005b60ff169050806107046116d0565b61070e9190613201565b61071784610df2565b6107219088613201565b1015610759576040517f709fb08000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805b878110156109a0576107d989898381811061077a5761077a613214565b905060200201602081019061078f9190613243565b73ffffffffffffffffffffffffffffffffffffffff1660009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff1690565b1580156108225750308989838181106107f4576107f4613214565b90506020020160208101906108099190613243565b73ffffffffffffffffffffffffffffffffffffffff1614155b15610859576040517f7b2cbbb400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3089898381811061086c5761086c613214565b90506020020160208101906108819190613243565b73ffffffffffffffffffffffffffffffffffffffff16036108d95783156108d4576040517fee21708000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600191505b6109628989838181106108ee576108ee613214565b90506020020160208101906109039190613243565b8689898581811061091657610916613214565b90506020028101906109289190613265565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061174f92505050565b610998576040517fac3d341600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60010161075d565b50801580156109ad575082155b156109e4576040517f6d21730400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9bf80546fffffffffffffffffffffffffffffffff808216600101167fffffffffffffffffffffffffffffffff00000000000000000000000000000000909116179055610a6a610a538a8c6130aa565b6000604051806020016040528060008152506117ca565b50505050505050505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610b19576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b610b2161195f565b610b2e6105c885876130aa565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75415610baf576040517fa788861700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff831615610bfd576040517f871cb76100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be5b600190810180547fffffffffffffffffffffffffffffffff0000000000000000000000000000000081166fffffffffffffffffffffffffffffffff91821690930116919091179055610c74610a5385876130aa565b5050505050565b6000610c878230610e4c565b92915050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610d30576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b610d3861195f565b7fffffffff00000000000000000000000000000000000000000000000000000000821660008181527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4922602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001685151590811790915582519384529083015280517f4e6bd17989efa6d6a9607ccaac1bba27b29f99622bc830d99a3a9883b21a19c79281900390910190a15050565b600080610dfd6119ca565b805190915060005b81811015610e4457610e3085848381518110610e2357610e23613214565b6020026020010151610e4c565b15610e3c578360010193505b600101610e05565b505050919050565b60008281527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d36020818152604080842073ffffffffffffffffffffffffffffffffffffffff8616855290915282205460ff168015610ee5575060008481526020828152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152902054610100900467ffffffffffffffff1642105b949350505050565b6000610ef76119ca565b805183519192509060005b82811015610fd957610f2086858381518110610e2357610e23613214565b15610fd15760005b82811015610fcf57848281518110610f4257610f42613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16868281518110610f7257610f72613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603610fc7576040517f50f5729f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600101610f28565b505b600101610f02565b505050505050565b3360009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff161580156110205750303314155b15611057576040517f6238ee3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff9081164290911610156110fa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75460000361117d576040517f3a76e1f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080527f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be6020527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d36111d36105c883856130aa565b60006111df848461130e565b905060006111eb611af4565b6111f59042613201565b6040805180820182526001815267ffffffffffffffff838116602080840191825260008881528982528581203382529091528490209251835491517fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000009092169015157fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff16176101009190921602179055519091507f6248ff757895beed7d43d135bccf59a26b7fbdf0fe8233487c44e82c0f266ba3906112b89087908790612f54565b60405180910390a16112c86116d0565b6112d183610df2565b101580156112e357506112e382610c7b565b15610c74577f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be610c1f565b60008282604051602001611323929190612f54565b6040516020818303038152906040528051906020012030466113627f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be90565b6001015460408051602081019590955273ffffffffffffffffffffffffffffffffffffffff9093169284019290925260608301526fffffffffffffffffffffffffffffffff16608082015260a001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905280516020918201207f19457468657265756d205369676e6564204d6573736167653a0a33320000000091830191909152603c820152605c0160405160208183030381529060405280519060200120905092915050565b805160005b818110156115ae57600083828151811061145657611456613214565b602002602001015160200151600281111561147357611473612e8a565b14806114ad5750600183828151811061148e5761148e613214565b60200260200101516020015160028111156114ab576114ab612e8a565b145b156115a657600254835173ffffffffffffffffffffffffffffffffffffffff9091169063df871f72908590849081106114e8576114e8613214565b60200260200101516000015185848151811061150657611506613214565b6020026020010151604001516040518363ffffffff1660e01b815260040161152f92919061331c565b602060405180830381865afa15801561154c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611570919061334b565b6115a6576040517ff41a931c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60010161143a565b505050565b80516000908082036115f1576040517f3aee2eec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b6115ff600183613368565b8110156116c6576000611613826001613201565b90505b828110156116bd5784818151811061163057611630613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1685838151811061166057611660613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16036116b5576040517f8dd19e7d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600101611616565b506001016115f4565b5060009392505050565b600080611723600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75490565b905080156117465761173660028261337b565b611741906001613201565b611749565b60005b91505090565b600080600061175e8585611bf6565b9092509050600081600481111561177757611777612e8a565b1480156117af57508573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b806117c057506117c0868686611c3b565b9695505050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921547f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff8116908190600090600716156118395750600381901c60009081526001840160205260409020545b60005b87518110156118b6576118a983838a848151811061185c5761185c613214565b6020026020010151600001518b858151811061187a5761187a613214565b6020026020010151602001518c868151811061189857611898613214565b602002602001015160400151611d98565b909350915060010161183c565b508282146118ef576002840180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff84161790555b600782161561191157600382901c600090815260018501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb67387878760405161194493929190613424565b60405180910390a16119568686612829565b50505050505050565b3330146119c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4c69624469616d6f6e643a2043616c6c6572206e6f742073656c6600000000006044820152606401610360565b565b60008080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b780546060929067ffffffffffffffff811115611a3257611a32612d07565b604051908082528060200260200182016040528015611a5b578160200160208202803683370190505b50825490915060005b81811015611aeb57836000018181548110611a8157611a81613214565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16838281518110611abe57611abe613214565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101611a64565b50909392505050565b6040517f52430c8d0000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906352430c8d90602401602060405180830381865afa158015611b81573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ba59190613510565b6fffffffffffffffffffffffffffffffff16905060008111611bf3576040517fdac5ec8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b90565b6000808251604103611c2c5760208301516040840151606085015160001a611c2087828585612928565b94509450505050611c34565b506000905060025b9250929050565b60008060008573ffffffffffffffffffffffffffffffffffffffff16631626ba7e60e01b8686604051602401611c72929190613542565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909416939093179092529051611cfb919061355b565b600060405180830381855afa9150503d8060008114611d36576040519150601f19603f3d011682016040523d82523d6000602084013e611d3b565b606091505b5091509150818015611d4f57506020815110155b80156117c0575080517f1626ba7e0000000000000000000000000000000000000000000000000000000090611d8d9083016020908101908401613577565b149695505050505050565b600080807f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f90506000845111611e50576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610360565b6000856002811115611e6457611e64612e8a565b0361203457611e8b8660405180606001604052806024815260200161365760249139612a17565b60005b845181101561202e576000858281518110611eab57611eab613214565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c15611f7e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c72656164792065786973747300000000000000000000006064820152608401610360565b7fffffffff0000000000000000000000000000000000000000000000000000000080831660008181526020879052604090207fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608d901b168e17905560e060058e901b811692831c199c909c1690821c179a8190036120125760038c901c600090815260018601602052604081209b909b555b8b61201c81613590565b9c505060019093019250611e8e915050565b5061281d565b600185600281111561204857612048612e8a565b036123385761206f866040518060600160405280602881526020016136a360289139612a17565b60005b845181101561202e57600085828151811061208f5761208f613214565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c308103612164576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4c69624469616d6f6e644375743a2043616e2774207265706c61636520696d6d60448201527f757461626c652066756e6374696f6e00000000000000000000000000000000006064820152608401610360565b8973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361221f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e00000000000000006064820152608401610360565b73ffffffffffffffffffffffffffffffffffffffff81166122c2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e207468617420646f65736e277420657869737400000000000000006064820152608401610360565b507fffffffff0000000000000000000000000000000000000000000000000000000090911660009081526020849052604090206bffffffffffffffffffffffff919091167fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608a901b16179055600101612072565b600285600281111561234c5761234c612e8a565b036127955773ffffffffffffffffffffffffffffffffffffffff8616156123f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d7573742062652061646472657373283029000000000000000000006064820152608401610360565b600388901c6007891660005b86518110156127755760008a900361243d578261241d816135c8565b60008181526001870160205260409020549b5093506007925061244b9050565b81612447816135c8565b9250505b6000806000808a858151811061246357612463613214565b6020908102919091018101517fffffffff0000000000000000000000000000000000000000000000000000000081166000908152918a9052604090912054909150606081901c612535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608401610360565b30606082901c036125c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e0000000000000000000000000000000000006064820152608401610360565b600587901b8f901b94507fffffffff0000000000000000000000000000000000000000000000000000000080861690831614612666577fffffffff000000000000000000000000000000000000000000000000000000008516600090815260208a90526040902080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff83161790555b7fffffffff0000000000000000000000000000000000000000000000000000000091909116600090815260208990526040812055600381901c611fff16925060051b60e01690508582146126fb576000828152600188016020526040902080547fffffffff0000000000000000000000000000000000000000000000000000000080841c19909116908516831c17905561274c565b80837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c817fffffffff0000000000000000000000000000000000000000000000000000000060001b901c198e16179c505b8460000361276a57600086815260018801602052604081208190559c505b505050600101612401565b50806127828360086135fd565b61278c9190613201565b9950505061281d565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560448201527f74416374696f6e000000000000000000000000000000000000000000000000006064820152608401610360565b50959694955050505050565b73ffffffffffffffffffffffffffffffffffffffff8216612848575050565b61286a8260405180606001604052806028815260200161367b60289139612a17565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051612892919061355b565b600060405180830381855af49150503d80600081146128cd576040519150601f19603f3d011682016040523d82523d6000602084013e6128d2565b606091505b509150915081612922578051156128ec5780518082602001fd5b83836040517f192105d7000000000000000000000000000000000000000000000000000000008152600401610360929190613614565b50505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561295f5750600090506003612a0e565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156129b3573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116612a0757600060019250925050612a0e565b9150600090505b94509492505050565b813b8181612922576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103609190613643565b60008083601f840112612a6457600080fd5b50813567ffffffffffffffff811115612a7c57600080fd5b6020830191508360208260051b8501011115611c3457600080fd5b60008060208385031215612aaa57600080fd5b823567ffffffffffffffff811115612ac157600080fd5b612acd85828601612a52565b90969095509350505050565b60008060008060008060608789031215612af257600080fd5b863567ffffffffffffffff80821115612b0a57600080fd5b612b168a838b01612a52565b90985096506020890135915080821115612b2f57600080fd5b612b3b8a838b01612a52565b90965094506040890135915080821115612b5457600080fd5b50612b6189828a01612a52565b979a9699509497509295939492505050565b803573ffffffffffffffffffffffffffffffffffffffff81168114612b9757600080fd5b919050565b600080600080600060608688031215612bb457600080fd5b853567ffffffffffffffff80821115612bcc57600080fd5b612bd889838a01612a52565b9097509550859150612bec60208901612b73565b94506040880135915080821115612c0257600080fd5b818801915088601f830112612c1657600080fd5b813581811115612c2557600080fd5b896020828501011115612c3757600080fd5b9699959850939650602001949392505050565b600060208284031215612c5c57600080fd5b5035919050565b80357fffffffff0000000000000000000000000000000000000000000000000000000081168114612b9757600080fd5b8015158114612ca157600080fd5b50565b60008060408385031215612cb757600080fd5b612cc083612c63565b91506020830135612cd081612c93565b809150509250929050565b60008060408385031215612cee57600080fd5b82359150612cfe60208401612b73565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff81118282101715612d5957612d59612d07565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715612da657612da6612d07565b604052919050565b600067ffffffffffffffff821115612dc857612dc8612d07565b5060051b60200190565b60008060408385031215612de557600080fd5b8235915060208084013567ffffffffffffffff811115612e0457600080fd5b8401601f81018613612e1557600080fd5b8035612e28612e2382612dae565b612d5f565b81815260059190911b82018301908381019088831115612e4757600080fd5b928401925b82841015612e6c57612e5d84612b73565b82529284019290840190612e4c565b80955050505050509250929050565b803560038110612b9757600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60038110612ef0577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b8183526000602080850194508260005b85811015612f49577fffffffff00000000000000000000000000000000000000000000000000000000612f3683612c63565b1687529582019590820190600101612f04565b509495945050505050565b60208082528181018390526000906040808401600586811b8601830188865b8981101561309b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc089840301855281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa18c3603018112612fd457600080fd5b8b01606073ffffffffffffffffffffffffffffffffffffffff612ff683612b73565b168552613004898301612e7b565b6130108a870182612eb9565b50878201357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe183360301811261304557600080fd5b90910188810191903567ffffffffffffffff81111561306357600080fd5b80871b360383131561307457600080fd5b81898701526130868287018285612ef4565b978a0197955050509187019150600101612f73565b50909998505050505050505050565b60006130b8612e2384612dae565b83815260208082019190600586811b8601368111156130d657600080fd5b865b818110156131c557803567ffffffffffffffff808211156130f95760008081fd5b818a0191506060823603121561310f5760008081fd5b613117612d36565b61312083612b73565b815261312d878401612e7b565b87820152604080840135838111156131455760008081fd5b939093019236601f85011261315c57600092508283fd5b8335925061316c612e2384612dae565b83815292871b840188019288810190368511156131895760008081fd5b948901945b848610156131ae5761319f86612c63565b8252948901949089019061318e565b9183019190915250885250509483019483016130d8565b5092979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610c8757610c876131d2565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561325557600080fd5b61325e82612b73565b9392505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261329a57600080fd5b83018035915067ffffffffffffffff8211156132b557600080fd5b602001915036819003821315611c3457600080fd5b600081518084526020808501945080840160005b83811015612f495781517fffffffff0000000000000000000000000000000000000000000000000000000016875295820195908201906001016132de565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000610ee560408301846132ca565b60006020828403121561335d57600080fd5b815161325e81612c93565b81810381811115610c8757610c876131d2565b6000826133b1577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60005b838110156133d15781810151838201526020016133b9565b50506000910152565b600081518084526133f28160208601602086016133b6565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6000606080830181845280875180835260808601915060808160051b87010192506020808a0160005b838110156134d4577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80898703018552815173ffffffffffffffffffffffffffffffffffffffff8151168752838101516134a885890182612eb9565b506040908101519087018890526134c1878901826132ca565b965050938201939082019060010161344d565b505073ffffffffffffffffffffffffffffffffffffffff8916908701525050838103604085015261350581866133da565b979650505050505050565b60006020828403121561352257600080fd5b81516fffffffffffffffffffffffffffffffff8116811461325e57600080fd5b828152604060208201526000610ee560408301846133da565b6000825161356d8184602087016133b6565b9190910192915050565b60006020828403121561358957600080fd5b5051919050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036135c1576135c16131d2565b5060010190565b6000816135d7576135d76131d2565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b8082028115828204841417610c8757610c876131d2565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000610ee560408301846133da565b60208152600061325e60208301846133da56fe4c69624469616d6f6e644375743a2041646420666163657420686173206e6f20636f64654c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a205265706c61636520666163657420686173206e6f20636f6465a2646970667358221220c5a8c10b22f20cde3fe0431ff57305237423677a60888f5b349fc6751336ae1464736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "Responsible for adding/removing/replace facets in Barz", + "kind": "dev", + "methods": { + "_checkDuplicateOnChainApprover(bytes32,address[])": { + "params": { + "_approvers": "List of approver addresses", + "_diamondCutHash": "Hash of diamondCut information including the facet addresses and function selectors" + } + }, + "approveDiamondCut((address,uint8,bytes4[])[])": { + "params": { + "_diamondCut": "Contains the facet addresses and function selectors" + } + }, + "constructor": { + "params": { + "_securityManager": "Security Manager contract that holds the security related variables for all wallets" + } + }, + "diamondCut((address,uint8,bytes4[])[],address,bytes)": { + "params": { + "_diamondCut": "Contains the facet addresses and function selectors", + "_init": "The address of the contract or facet to execute _calldata. It's prohibited in Barz" + } + }, + "diamondCutWithGuardian((address,uint8,bytes4[])[],address[],bytes[])": { + "params": { + "_approvers": "Guardian or owner address that approves the diamond cut", + "_diamondCut": "Contains the facet addresses and function selectors", + "_signatures": "Signature of Guardians or owner that approves the diamond cut" + } + }, + "getDiamondCutApprovalCountWithTimeValidity(bytes32)": { + "params": { + "_diamondCutHash": "Hash of diamondCut information including the facet addresses and function selectors" + } + }, + "getDiamondCutHash((address,uint8,bytes4[])[])": { + "params": { + "_diamondCut": "Contains the facet addresses and function selectors" + }, + "returns": { + "cutHash": "Diamond Cut Hash" + } + }, + "getDiamondCutNonce()": { + "details": "This method fetches the nonce from diamond cut storage", + "returns": { + "cutNonce": "Nonce of diamond cut to protect from reply attacks" + } + }, + "getOwnerCutApprovalWithTimeValidity(bytes32)": { + "params": { + "_diamondCutHash": "Hash of diamondCut information including the facet addresses and function selectors" + }, + "returns": { + "isApprovedByOwner": "Bool value showing if the owner approved the cut" + } + }, + "isCutApproved(bytes32,address)": { + "params": { + "_approver": "Address of approver", + "_diamondCutHash": "Hash of diamondCut information including the facet addresses and function selectors" + }, + "returns": { + "isApproved": "Bool value showing if the approver approved the cut" + } + }, + "revokeDiamondCutApproval((address,uint8,bytes4[])[])": { + "params": { + "_diamondCut": "Contains the facet addresses and function selectors" + } + }, + "updateSupportsInterface(bytes4,bool)": { + "params": { + "_flag": "Bool value to update the mapping of the given interface ID", + "_interfaceId": "InterfaceID to update the mapping" + } + } + }, + "title": "DiamondCut Facet", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "_checkDuplicateOnChainApprover(bytes32,address[])": { + "notice": "Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval Approvers who approved on-chain should not be included in the off-chain approval" + }, + "approveDiamondCut((address,uint8,bytes4[])[])": { + "notice": "Approves diamond cut. This can only be called directly from guardian or owner" + }, + "constructor": { + "notice": "This constructor sets the Security Manager address which is an immutable variable. Immutable variables do not impact the storage of diamond" + }, + "diamondCut((address,uint8,bytes4[])[],address,bytes)": { + "notice": "Add/replace/remove any number of functions and optionally execute a function with delegatecall when guardians don't exist" + }, + "diamondCutWithGuardian((address,uint8,bytes4[])[],address[],bytes[])": { + "notice": "Add/replace/remove any number of functions and optionally execute a function with delegatecall when guardians exist" + }, + "getDiamondCutApprovalCountWithTimeValidity(bytes32)": { + "notice": "Gets the number of approvals of diamond cut from guardians" + }, + "getDiamondCutHash((address,uint8,bytes4[])[])": { + "notice": "Returns the diamond cut hash. This function ensures that this hash is safe from replay attack by including salt, address, chainId, and nonce, etc." + }, + "getDiamondCutNonce()": { + "notice": "Returns the diamond cut nonce of this wallet" + }, + "getOwnerCutApprovalWithTimeValidity(bytes32)": { + "notice": "Returns if the owner has approved the diamond cut" + }, + "isCutApproved(bytes32,address)": { + "notice": "Returns if the given approver has approved the diamond cut" + }, + "revokeDiamondCutApproval((address,uint8,bytes4[])[])": { + "notice": "Revokes the approval of diamond cut. This can only be called directly from guardian or owner" + }, + "updateSupportsInterface(bytes4,bool)": { + "notice": "Updates the flag for the interfaceId" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 27823, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "s", + "offset": 0, + "slot": "0", + "type": "t_struct(AppStorage)27570_storage" + } + ], + "types": { + "t_bytes4": { + "encoding": "inplace", + "label": "bytes4", + "numberOfBytes": "4" + }, + "t_contract(IEntryPoint)12286": { + "encoding": "inplace", + "label": "contract IEntryPoint", + "numberOfBytes": "20" + }, + "t_contract(IFacetRegistry)26105": { + "encoding": "inplace", + "label": "contract IFacetRegistry", + "numberOfBytes": "20" + }, + "t_mapping(t_uint256,t_struct(InitializersStorage)27549_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => struct InitializersStorage)", + "numberOfBytes": "32", + "value": "t_struct(InitializersStorage)27549_storage" + }, + "t_mapping(t_uint256,t_struct(Lock)27542_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => struct Lock)", + "numberOfBytes": "32", + "value": "t_struct(Lock)27542_storage" + }, + "t_struct(AppStorage)27570_storage": { + "encoding": "inplace", + "label": "struct AppStorage", + "members": [ + { + "astId": 27554, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "initStorage", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_uint256,t_struct(InitializersStorage)27549_storage)" + }, + { + "astId": 27556, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "signerMigration", + "offset": 0, + "slot": "1", + "type": "t_uint8" + }, + { + "astId": 27558, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "validateOwnerSignatureSelector", + "offset": 1, + "slot": "1", + "type": "t_bytes4" + }, + { + "astId": 27561, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "entryPoint", + "offset": 5, + "slot": "1", + "type": "t_contract(IEntryPoint)12286" + }, + { + "astId": 27564, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "facetRegistry", + "offset": 0, + "slot": "2", + "type": "t_contract(IFacetRegistry)26105" + }, + { + "astId": 27569, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "locks", + "offset": 0, + "slot": "3", + "type": "t_mapping(t_uint256,t_struct(Lock)27542_storage)" + } + ], + "numberOfBytes": "128" + }, + "t_struct(InitializersStorage)27549_storage": { + "encoding": "inplace", + "label": "struct InitializersStorage", + "members": [ + { + "astId": 27544, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "signerInitialized", + "offset": 0, + "slot": "0", + "type": "t_uint8" + }, + { + "astId": 27546, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "accountInitialized", + "offset": 1, + "slot": "0", + "type": "t_uint8" + }, + { + "astId": 27548, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "restrictionsInitialized", + "offset": 2, + "slot": "0", + "type": "t_uint8" + } + ], + "numberOfBytes": "32" + }, + "t_struct(Lock)27542_storage": { + "encoding": "inplace", + "label": "struct Lock", + "members": [ + { + "astId": 27539, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "release", + "offset": 0, + "slot": "0", + "type": "t_uint64" + }, + { + "astId": 27541, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "locker", + "offset": 8, + "slot": "0", + "type": "t_bytes4" + } + ], + "numberOfBytes": "32" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint64": { + "encoding": "inplace", + "label": "uint64", + "numberOfBytes": "8" + }, + "t_uint8": { + "encoding": "inplace", + "label": "uint8", + "numberOfBytes": "1" + } + } + } +} \ No newline at end of file diff --git a/deployments/base/DiamondLoupeFacet.json b/deployments/base/DiamondLoupeFacet.json new file mode 100644 index 0000000..d6d2aa7 --- /dev/null +++ b/deployments/base/DiamondLoupeFacet.json @@ -0,0 +1,306 @@ +{ + "address": "0xCe36b85d12D81cd619C745c7717f3396E184Ac7C", + "abi": [ + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_functionSelector", + "type": "bytes4" + } + ], + "name": "facetAddress", + "outputs": [ + { + "internalType": "address", + "name": "facetAddress_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_functionSelector", + "type": "bytes4" + } + ], + "name": "facetAddressFromStorage", + "outputs": [ + { + "internalType": "address", + "name": "facetAddress_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetAddresses", + "outputs": [ + { + "internalType": "address[]", + "name": "facetAddresses_", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetAddressesFromStorage", + "outputs": [ + { + "internalType": "address[]", + "name": "facetAddresses_", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_facet", + "type": "address" + } + ], + "name": "facetFunctionSelectors", + "outputs": [ + { + "internalType": "bytes4[]", + "name": "facetFunctionSelectors_", + "type": "bytes4[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_facet", + "type": "address" + } + ], + "name": "facetFunctionSelectorsFromStorage", + "outputs": [ + { + "internalType": "bytes4[]", + "name": "facetFunctionSelectors_", + "type": "bytes4[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facets", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondLoupe.Facet[]", + "name": "facets_", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetsFromStorage", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondLoupe.Facet[]", + "name": "facets_", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "isSupported", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0xfc954193498ea16ff9ef28c0166a6c7207151953ea12121f6500be35d138a013", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 2, + "gasUsed": "2036373", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0xd3ffd939fe4574161a6575882780dd1c4a32d89e00e141e6b2494ade8fabf4d1", + "transactionHash": "0xfc954193498ea16ff9ef28c0166a6c7207151953ea12121f6500be35d138a013", + "logs": [], + "blockNumber": 6847656, + "cumulativeGasUsed": "2128152", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 3, + "solcInputHash": "4356503edd8ae34e73cb6dd1c8e2fc8a", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_functionSelector\",\"type\":\"bytes4\"}],\"name\":\"facetAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"facetAddress_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_functionSelector\",\"type\":\"bytes4\"}],\"name\":\"facetAddressFromStorage\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"facetAddress_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetAddresses\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"facetAddresses_\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetAddressesFromStorage\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"facetAddresses_\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_facet\",\"type\":\"address\"}],\"name\":\"facetFunctionSelectors\",\"outputs\":[{\"internalType\":\"bytes4[]\",\"name\":\"facetFunctionSelectors_\",\"type\":\"bytes4[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_facet\",\"type\":\"address\"}],\"name\":\"facetFunctionSelectorsFromStorage\",\"outputs\":[{\"internalType\":\"bytes4[]\",\"name\":\"facetFunctionSelectors_\",\"type\":\"bytes4[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facets\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondLoupe.Facet[]\",\"name\":\"facets_\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetsFromStorage\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondLoupe.Facet[]\",\"name\":\"facets_\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isSupported\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"DiamondLoupe contract compatible with EIP-2535\",\"kind\":\"dev\",\"methods\":{\"facetAddress(bytes4)\":{\"details\":\"If facet is not found return address(0).\",\"params\":{\"_functionSelector\":\"The function selector.\"},\"returns\":{\"facetAddress_\":\"The facet address.\"}},\"facetAddressFromStorage(bytes4)\":{\"params\":{\"_functionSelector\":\"Function selector to fetch the facet address from diamond storage\"},\"returns\":{\"facetAddress_\":\"Facet address mapped with the function selector\"}},\"facetAddresses()\":{\"returns\":{\"facetAddresses_\":\"facetAddresses_\"}},\"facetAddressesFromStorage()\":{\"returns\":{\"facetAddresses_\":\"All facet addresses attached directly to diamond storage\"}},\"facetFunctionSelectors(address)\":{\"params\":{\"_facet\":\"The facet address.\"},\"returns\":{\"facetFunctionSelectors_\":\"facetFunctionSelectors_\"}},\"facetFunctionSelectorsFromStorage(address)\":{\"params\":{\"_facet\":\"Facet address to fetch the facet function selectors from diamond storage\"},\"returns\":{\"facetFunctionSelectors_\":\"Facet function selectors of the given facet address\"}},\"facets()\":{\"details\":\"Barz uses a special architecture called default fallback handler. Default Fallback handler is used as a middleware that holds the mapping of facet function selector and facet address that Barz uses. This helps Barz to reduce significant amount of gas during the initialization process. Hence, this method aggregates both the facet information from DefaulFallbackHandler and in diamond storage and shows the data to users.\",\"returns\":{\"facets_\":\"Facet\"}},\"facetsFromStorage()\":{\"returns\":{\"facets_\":\"Facet information attached directly to diamond storage\"}},\"supportsInterface(bytes4)\":{\"params\":{\"_interfaceId\":\"Interface ID for detecting the interface\"},\"returns\":{\"isSupported\":\"Bool value showing if the standard is supported in the contract\"}}},\"title\":\"DiamondLoupe Facet\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"facetAddress(bytes4)\":{\"notice\":\"Gets the facet that supports the given selector.\"},\"facetAddressFromStorage(bytes4)\":{\"notice\":\"Returns the facet address attached to the given function selector. This excludes the facets from the default fallback handler\"},\"facetAddresses()\":{\"notice\":\"Get all the facet addresses used by Barz.\"},\"facetAddressesFromStorage()\":{\"notice\":\"Returns all facet addresses attached directly to diamond storage. This excludes the facets from the default fallback handler\"},\"facetFunctionSelectors(address)\":{\"notice\":\"Gets all the function selectors provided by a facet.\"},\"facetFunctionSelectorsFromStorage(address)\":{\"notice\":\"Returns function selectors of given facet address attached directly to diamond storage. This excludes the facets from the default fallback handler\"},\"facets()\":{\"notice\":\"Gets all facets and their selectors.\"},\"facetsFromStorage()\":{\"notice\":\"Returns the facet from the diamond storage. This excludes the facets from the default fallback handler\"},\"supportsInterface(bytes4)\":{\"notice\":\"SupportInterface to be compatible with EIP 165\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/base/DiamondLoupeFacet.sol\":\"DiamondLoupeFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/introspection/IERC165.sol\\\";\\n\\n/**\\n * @dev _Available since v3.1._\\n */\\ninterface IERC1155Receiver is IERC165 {\\n /**\\n * @dev Handles the receipt of a single ERC1155 token type. This function is\\n * called at the end of a `safeTransferFrom` after the balance has been updated.\\n *\\n * NOTE: To accept the transfer, this must return\\n * `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))`\\n * (i.e. 0xf23a6e61, or its own function selector).\\n *\\n * @param operator The address which initiated the transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param id The ID of the token being transferred\\n * @param value The amount of tokens being transferred\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155Received(\\n address operator,\\n address from,\\n uint256 id,\\n uint256 value,\\n bytes calldata data\\n ) external returns (bytes4);\\n\\n /**\\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\\n * is called at the end of a `safeBatchTransferFrom` after the balances have\\n * been updated.\\n *\\n * NOTE: To accept the transfer(s), this must return\\n * `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))`\\n * (i.e. 0xbc197c81, or its own function selector).\\n *\\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155BatchReceived(\\n address operator,\\n address from,\\n uint256[] calldata ids,\\n uint256[] calldata values,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xeb373f1fdc7b755c6a750123a9b9e3a8a02c1470042fd6505d875000a80bde0b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title ERC721 token receiver interface\\n * @dev Interface for any contract that wants to support safeTransfers\\n * from ERC721 asset contracts.\\n */\\ninterface IERC721Receiver {\\n /**\\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\\n * by `operator` from `from`, this function is called.\\n *\\n * It must return its Solidity selector to confirm the token transfer.\\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\\n *\\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\\n */\\n function onERC721Received(\\n address operator,\\n address from,\\n uint256 tokenId,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\\n *\\n * Accounts can be notified of {IERC777} tokens being sent to them by having a\\n * contract implement this interface (contract holders can be their own\\n * implementer) and registering it on the\\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\\n *\\n * See {IERC1820Registry} and {ERC1820Implementer}.\\n */\\ninterface IERC777Recipient {\\n /**\\n * @dev Called by an {IERC777} token contract whenever tokens are being\\n * moved or created into a registered account (`to`). The type of operation\\n * is conveyed by `from` being the zero address or not.\\n *\\n * This call occurs _after_ the token contract's state is updated, so\\n * {IERC777-balanceOf}, etc., can be used to query the post-operation state.\\n *\\n * This function may revert to prevent the operation from being executed.\\n */\\n function tokensReceived(\\n address operator,\\n address from,\\n address to,\\n uint256 amount,\\n bytes calldata userData,\\n bytes calldata operatorData\\n ) external;\\n}\\n\",\"keccak256\":\"0x1a5d61db2733202ba361e6d6741cd2e662380e22b80e987eacfc91973f2267dc\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"contracts/facets/base/DiamondLoupeFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IERC777Recipient} from \\\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\\\";\\nimport {IERC165} from \\\"../../interfaces/ERC/IERC165.sol\\\";\\nimport {IERC1271} from \\\"../../interfaces/ERC/IERC1271.sol\\\";\\nimport {IERC677Receiver} from \\\"../../interfaces/ERC/IERC677Receiver.sol\\\";\\nimport {IERC721Receiver} from \\\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\\\";\\nimport {IERC1155Receiver} from \\\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\\\";\\nimport {LibDiamond} from \\\"../../libraries/LibDiamond.sol\\\";\\nimport {LibLoupe} from \\\"../../libraries/LibLoupe.sol\\\";\\nimport {LibUtils} from \\\"../../libraries/LibUtils.sol\\\";\\nimport {IDiamondCut} from \\\"../../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IStorageLoupe} from \\\"./interfaces/IStorageLoupe.sol\\\";\\nimport {IDiamondLoupe} from \\\"./interfaces/IDiamondLoupe.sol\\\";\\n\\n/**\\n * @title DiamondLoupe Facet\\n * @dev DiamondLoupe contract compatible with EIP-2535\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract DiamondLoupeFacet is IDiamondLoupe, IStorageLoupe, IERC165 {\\n // Diamond Loupe Functions\\n ////////////////////////////////////////////////////////////////////\\n /// These functions are expected to be called frequently by tools off-chain.\\n\\n /**\\n * @notice Gets all facets and their selectors.\\n * @dev Barz uses a special architecture called default fallback handler. Default Fallback handler is used as a middleware\\n * that holds the mapping of facet function selector and facet address that Barz uses. This helps Barz to reduce\\n * significant amount of gas during the initialization process.\\n * Hence, this method aggregates both the facet information from DefaulFallbackHandler and in diamond storage and shows the data to users.\\n * @return facets_ Facet\\n */\\n function facets() public view override returns (Facet[] memory facets_) {\\n Facet[] memory defaultFacet = LibDiamond\\n .diamondStorage()\\n .defaultFallbackHandler\\n .facets();\\n Facet[] memory _facets = LibLoupe.facets();\\n uint256 numFacets = _facets.length;\\n bytes4[] memory keys;\\n address[] memory values;\\n for (uint256 i; i < numFacets; ) {\\n uint256 selectorsLength = _facets[i].functionSelectors.length;\\n for (uint256 j; j < selectorsLength; ) {\\n (keys, values) = LibUtils.setValue(\\n keys,\\n values,\\n _facets[i].functionSelectors[j],\\n _facets[i].facetAddress\\n );\\n unchecked {\\n ++j;\\n }\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n {\\n bool iIncrement;\\n for (uint256 i; i < defaultFacet.length; ) {\\n bool jIncrement;\\n for (\\n uint256 j;\\n j < defaultFacet[i].functionSelectors.length;\\n\\n ) {\\n if (\\n LibUtils.getValue(\\n keys,\\n values,\\n defaultFacet[i].functionSelectors[j]\\n ) != address(0)\\n ) {\\n if (defaultFacet[i].functionSelectors.length == 1) {\\n defaultFacet = LibUtils.removeFacetElement(\\n defaultFacet,\\n i\\n );\\n iIncrement = true;\\n break;\\n }\\n defaultFacet[i].functionSelectors = LibUtils\\n .removeElement(\\n defaultFacet[i].functionSelectors,\\n j\\n );\\n jIncrement = true;\\n }\\n if (!jIncrement) {\\n unchecked {\\n ++j;\\n }\\n } else {\\n jIncrement = false;\\n }\\n }\\n if (!iIncrement) {\\n unchecked {\\n ++i;\\n }\\n } else {\\n iIncrement = false;\\n }\\n }\\n }\\n {\\n uint256 facetLength = numFacets + defaultFacet.length;\\n facets_ = new Facet[](facetLength);\\n uint256 defaultFacetIndex;\\n for (uint256 i; i < facetLength; ) {\\n if (i < numFacets) {\\n facets_[i] = _facets[i];\\n bool jIncrementor;\\n for (uint256 j; j < defaultFacet.length; ) {\\n if (\\n facets_[i].facetAddress ==\\n defaultFacet[j].facetAddress\\n ) {\\n facets_[i].functionSelectors = LibUtils.mergeArrays(\\n _facets[i].functionSelectors,\\n defaultFacet[j].functionSelectors\\n );\\n defaultFacet = LibUtils.removeFacetElement(\\n defaultFacet,\\n j\\n );\\n jIncrementor = true;\\n {\\n facets_ = LibUtils.removeFacetElement(\\n facets_,\\n facets_.length - 1\\n );\\n }\\n --facetLength;\\n }\\n if (!jIncrementor) {\\n unchecked {\\n ++j;\\n }\\n } else {\\n jIncrementor = false;\\n }\\n }\\n } else {\\n facets_[i] = defaultFacet[defaultFacetIndex];\\n ++defaultFacetIndex;\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n }\\n\\n /**\\n * @notice Gets all the function selectors provided by a facet.\\n * @param _facet The facet address.\\n * @return facetFunctionSelectors_\\n */\\n function facetFunctionSelectors(\\n address _facet\\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\\n Facet[] memory facet = facets();\\n uint256 facetLength = facet.length;\\n for (uint256 i; i < facetLength; ) {\\n if (facet[i].facetAddress == _facet)\\n return facet[i].functionSelectors;\\n unchecked {\\n ++i;\\n }\\n }\\n return facetFunctionSelectors_;\\n }\\n\\n /**\\n * @notice Get all the facet addresses used by Barz.\\n * @return facetAddresses_\\n */\\n function facetAddresses()\\n external\\n view\\n override\\n returns (address[] memory facetAddresses_)\\n {\\n Facet[] memory facet = facets();\\n uint256 facetLength = facet.length;\\n facetAddresses_ = new address[](facetLength);\\n for (uint256 i; i < facetLength; ) {\\n facetAddresses_[i] = facet[i].facetAddress;\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * @notice Gets the facet that supports the given selector.\\n * @dev If facet is not found return address(0).\\n * @param _functionSelector The function selector.\\n * @return facetAddress_ The facet address.\\n */\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view override returns (address facetAddress_) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n\\n facetAddress_ = address(bytes20(ds.facets[_functionSelector]));\\n if (facetAddress_ == address(0)) {\\n facetAddress_ = IDiamondLoupe(ds.defaultFallbackHandler)\\n .facetAddress(_functionSelector);\\n }\\n }\\n\\n /**\\n * @notice SupportInterface to be compatible with EIP 165\\n * @param _interfaceId Interface ID for detecting the interface\\n * @return isSupported Bool value showing if the standard is supported in the contract\\n */\\n function supportsInterface(\\n bytes4 _interfaceId\\n ) external view override returns (bool isSupported) {\\n isSupported =\\n _interfaceId == type(IERC165).interfaceId ||\\n _interfaceId == IDiamondCut.diamondCut.selector ||\\n _interfaceId == type(IDiamondLoupe).interfaceId ||\\n _interfaceId == type(IERC1155Receiver).interfaceId ||\\n _interfaceId == type(IERC721Receiver).interfaceId ||\\n _interfaceId == type(IERC777Recipient).interfaceId ||\\n _interfaceId == IERC1271.isValidSignature.selector ||\\n _interfaceId == type(IERC677Receiver).interfaceId ||\\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId];\\n }\\n\\n /**\\n * @notice Returns the facet from the diamond storage. This excludes the facets from the default fallback handler\\n * @return facets_ Facet information attached directly to diamond storage\\n */\\n function facetsFromStorage()\\n external\\n view\\n override\\n returns (Facet[] memory facets_)\\n {\\n facets_ = LibLoupe.facets();\\n }\\n\\n /**\\n * @notice Returns the facet address attached to the given function selector. This excludes the facets from the default fallback handler\\n * @param _functionSelector Function selector to fetch the facet address from diamond storage\\n * @return facetAddress_ Facet address mapped with the function selector\\n */\\n function facetAddressFromStorage(\\n bytes4 _functionSelector\\n ) external view override returns (address facetAddress_) {\\n facetAddress_ = LibLoupe.facetAddress(_functionSelector);\\n }\\n\\n /**\\n * @notice Returns all facet addresses attached directly to diamond storage. This excludes the facets from the default fallback handler\\n * @return facetAddresses_ All facet addresses attached directly to diamond storage\\n */\\n function facetAddressesFromStorage()\\n external\\n view\\n override\\n returns (address[] memory facetAddresses_)\\n {\\n facetAddresses_ = LibLoupe.facetAddresses();\\n }\\n\\n /**\\n * @notice Returns function selectors of given facet address attached directly to diamond storage. This excludes the facets from the default fallback handler\\n * @param _facet Facet address to fetch the facet function selectors from diamond storage\\n * @return facetFunctionSelectors_ Facet function selectors of the given facet address\\n */\\n function facetFunctionSelectorsFromStorage(\\n address _facet\\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\\n facetFunctionSelectors_ = LibLoupe.facetFunctionSelectors(_facet);\\n }\\n}\\n\",\"keccak256\":\"0xf392fde159eec6483fc15fa323ecd6d764028f5b8734a66662c4116292363794\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IStorageLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"./IDiamondLoupe.sol\\\";\\n\\n/**\\n * @title LoupeFromStorage Interface\\n * @dev Interface contract to function as a loupe facet directly attached to diamond storage of Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IStorageLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facetsFromStorage()\\n external\\n view\\n returns (IDiamondLoupe.Facet[] memory);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n function facetFunctionSelectorsFromStorage(\\n address _facet\\n ) external view returns (bytes4[] memory);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n function facetAddressesFromStorage()\\n external\\n view\\n returns (address[] memory);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n function facetAddressFromStorage(\\n bytes4 _functionSelector\\n ) external view returns (address);\\n}\\n\",\"keccak256\":\"0xdf5dc9c57319e9087628c9cf9404b4f75585b76d1c2f4f59ee796c933967ea5c\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC1271 {\\n function isValidSignature(\\n bytes32 hash,\\n bytes memory signature\\n ) external view returns (bytes4);\\n}\\n\",\"keccak256\":\"0xcdddb7d5641c9d3f2432dec7fd13fddb9ae1480f25c76c21511e2fa16b8bd422\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.21;\\n\\ninterface IERC165 {\\n /// @notice Query if a contract implements an interface\\n /// @param interfaceId The interface identifier, as specified in ERC-165\\n /// @dev Interface identification is specified in ERC-165. This function\\n /// uses less than 30,000 gas.\\n /// @return `true` if the contract implements `interfaceID` and\\n /// `interfaceID` is not 0xffffffff, `false` otherwise\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xbb7f07e170898793c5535cc4b7e8944c4b990a631ac806d0b788e794abc788a3\",\"license\":\"MIT\"},\"contracts/interfaces/ERC/IERC677Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC677Receiver {\\n function onTokenTransfer(\\n address sender,\\n uint value,\\n bytes calldata data\\n ) external pure returns (bool);\\n}\\n\",\"keccak256\":\"0x4c1631cf45ea6daac0ec158c3edb9453099130b6b64f697004b83f95aa1f7350\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\\n bytes4(keccak256(\\\"verifyRestrictions(address,address,uint256,bytes)\\\"));\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // Default Fallback Handler of the barz.\\n IDiamondLoupe defaultFallbackHandler;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function enforceIsSelf() internal view {\\n require(msg.sender == address(this), \\\"LibDiamond: Caller not self\\\");\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n\\n unchecked {\\n facetIndex++;\\n }\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n\\n function restrictionsFacet() internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(\\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2cabdc00de859c3a3170ce3bda5d0e5fd3933d47ce904fd1585f9818b02572f8\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\nimport {LibDiamond} from \\\"./LibDiamond.sol\\\";\\n\\n/**\\n * @title LibLoupe\\n * @dev Internal Library to provide utility feature for reading the state of diamond facets\\n * Originally from Diamond's implementation of Mudgen(author of EIP-2535)\\n */\\nlibrary LibLoupe {\\n /// @notice Gets all facets and their selectors.\\n /// @return facets_ Facet\\n function facets()\\n internal\\n view\\n returns (IDiamondLoupe.Facet[] memory facets_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facets_ = new IDiamondLoupe.Facet[](ds.selectorCount);\\n uint16[] memory numFacetSelectors = new uint16[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facets_[facetIndex].facetAddress == facetAddress_) {\\n facets_[facetIndex].functionSelectors[\\n numFacetSelectors[facetIndex]\\n ] = selector;\\n // probably will never have more than 256 functions from one facet contract\\n require(numFacetSelectors[facetIndex] < 255);\\n numFacetSelectors[facetIndex]++;\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facets_[numFacets].facetAddress = facetAddress_;\\n facets_[numFacets].functionSelectors = new bytes4[](\\n ds.selectorCount\\n );\\n facets_[numFacets].functionSelectors[0] = selector;\\n numFacetSelectors[numFacets] = 1;\\n numFacets++;\\n }\\n }\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n uint256 numSelectors = numFacetSelectors[facetIndex];\\n bytes4[] memory selectors = facets_[facetIndex].functionSelectors;\\n // setting the number of selectors\\n assembly {\\n mstore(selectors, numSelectors)\\n }\\n }\\n // setting the number of facets\\n assembly {\\n mstore(facets_, numFacets)\\n }\\n }\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return _facetFunctionSelectors The selectors associated with a facet address.\\n function facetFunctionSelectors(\\n address _facet\\n ) internal view returns (bytes4[] memory _facetFunctionSelectors) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n uint256 numSelectors;\\n _facetFunctionSelectors = new bytes4[](ds.selectorCount);\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facet = address(bytes20(ds.facets[selector]));\\n if (_facet == facet) {\\n _facetFunctionSelectors[numSelectors] = selector;\\n numSelectors++;\\n }\\n }\\n }\\n // Set the number of selectors in the array\\n assembly {\\n mstore(_facetFunctionSelectors, numSelectors)\\n }\\n }\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n internal\\n view\\n returns (address[] memory facetAddresses_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetAddresses_ = new address[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facetAddress_ == facetAddresses_[facetIndex]) {\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facetAddresses_[numFacets] = facetAddress_;\\n numFacets++;\\n }\\n }\\n // Set the number of facet addresses in the array\\n assembly {\\n mstore(facetAddresses_, numFacets)\\n }\\n }\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(LibDiamond.diamondStorage().facets[_functionSelector])\\n );\\n }\\n}\\n\",\"keccak256\":\"0x0b11439c3cc657095e15ec2241fdcf67204b14001357b612fc5db4ff9e760a5a\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibUtils.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nlibrary LibUtils {\\n // Internal utility functions\\n function mergeArrays(\\n bytes4[] memory _array1,\\n bytes4[] memory _array2\\n ) internal pure returns (bytes4[] memory) {\\n uint256 length1 = _array1.length;\\n uint256 length2 = _array2.length;\\n bytes4[] memory mergedArray = new bytes4[](length1 + length2);\\n\\n for (uint256 i; i < length1; ) {\\n mergedArray[i] = _array1[i];\\n unchecked {\\n ++i;\\n }\\n }\\n\\n for (uint256 i; i < length2; ) {\\n mergedArray[length1 + i] = _array2[i];\\n unchecked {\\n ++i;\\n }\\n }\\n\\n return mergedArray;\\n }\\n\\n function removeFacetElement(\\n IDiamondLoupe.Facet[] memory _facets,\\n uint256 _index\\n ) internal pure returns (IDiamondLoupe.Facet[] memory) {\\n require(_index < _facets.length, \\\"Invalid index\\\");\\n require(_facets.length != 0, \\\"Invalid array\\\");\\n\\n // Create a new array with a length of `_facets.length - 1`\\n IDiamondLoupe.Facet[] memory newArray = new IDiamondLoupe.Facet[](\\n _facets.length - 1\\n );\\n uint256 newArrayLength = newArray.length;\\n // Iterate over the original array, skipping the element at the specified `index`\\n for (uint256 i; i < newArrayLength; ) {\\n if (i < _index) {\\n newArray[i] = _facets[i];\\n } else {\\n newArray[i] = _facets[i + 1];\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n\\n return newArray;\\n }\\n\\n function removeElement(\\n bytes4[] memory _array,\\n uint256 _index\\n ) internal pure returns (bytes4[] memory) {\\n require(_index < _array.length, \\\"Invalid index\\\");\\n require(_array.length != 0, \\\"Invalid array\\\");\\n\\n bytes4[] memory newArray = new bytes4[](_array.length - 1);\\n uint256 newArrayLength = newArray.length;\\n for (uint256 i; i < newArrayLength; ) {\\n if (i < _index) {\\n newArray[i] = _array[i];\\n } else {\\n newArray[i] = _array[i + 1];\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n\\n return newArray;\\n }\\n\\n function setValue(\\n bytes4[] memory _keys,\\n address[] memory _values,\\n bytes4 _key,\\n address _value\\n ) internal pure returns (bytes4[] memory, address[] memory) {\\n uint256 index = findIndex(_keys, _key);\\n uint256 keysLength = _keys.length;\\n if (index < keysLength) {\\n _values[index] = _value;\\n } else {\\n // Create new storage arrays\\n bytes4[] memory newKeys = new bytes4[](keysLength + 1);\\n address[] memory newValues = new address[](_values.length + 1);\\n\\n // Copy values to the new storage arrays\\n for (uint256 i; i < keysLength; ) {\\n newKeys[i] = _keys[i];\\n newValues[i] = _values[i];\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n // Add the new key-value pair\\n newKeys[keysLength] = _key;\\n newValues[_values.length] = _value;\\n\\n return (newKeys, newValues);\\n }\\n\\n // If the key already exists, return the original arrays\\n return (_keys, _values);\\n }\\n\\n function getValue(\\n bytes4[] memory _keys,\\n address[] memory _values,\\n bytes4 _key\\n ) internal pure returns (address) {\\n uint256 index = findIndex(_keys, _key);\\n if (index >= _keys.length) return address(0);\\n\\n return _values[index];\\n }\\n\\n function findIndex(\\n bytes4[] memory _keys,\\n bytes4 _key\\n ) internal pure returns (uint256) {\\n uint256 keysLength = _keys.length;\\n for (uint256 i; i < keysLength; ) {\\n if (_keys[i] == _key) {\\n return i;\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n return keysLength;\\n }\\n}\\n\",\"keccak256\":\"0xde8aeefe54c4be483f2b2c055aca11e2830f7094c0586a82e10ec544933b5714\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5061240b806100206000396000f3fe608060405234801561001057600080fd5b50600436106100a35760003560e01c8063adfca15e11610076578063d42139a91161005b578063d42139a914610169578063e3a2f6fe14610171578063f9796ccf1461018457600080fd5b8063adfca15e1461011e578063cdffacc61461013157600080fd5b806301a55022146100a857806301ffc9a7146100d157806352ef6b2c146100f45780637a0ed62714610109575b600080fd5b6100bb6100b6366004611e4b565b61018c565b6040516100c89190611e68565b60405180910390f35b6100e46100df366004611efc565b61019d565b60405190151581526020016100c8565b6100fc610454565b6040516100c89190611f19565b610111610518565b6040516100c89190611f67565b6100bb61012c366004611e4b565b610a63565b61014461013f366004611efc565b610b07565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100c8565b6100fc610c24565b61014461017f366004611efc565b610c33565b610111610c8c565b606061019782610c96565b92915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000148061023057507fffffffff0000000000000000000000000000000000000000000000000000000082167f1f931c1c00000000000000000000000000000000000000000000000000000000145b8061027c57507fffffffff0000000000000000000000000000000000000000000000000000000082167f48e2b09300000000000000000000000000000000000000000000000000000000145b806102c857507fffffffff0000000000000000000000000000000000000000000000000000000082167f4e2312e000000000000000000000000000000000000000000000000000000000145b8061031457507fffffffff0000000000000000000000000000000000000000000000000000000082167f150b7a0200000000000000000000000000000000000000000000000000000000145b8061035f57507fffffffff0000000000000000000000000000000000000000000000000000000082167e23de2900000000000000000000000000000000000000000000000000000000145b806103ab57507fffffffff0000000000000000000000000000000000000000000000000000000082167f1626ba7e00000000000000000000000000000000000000000000000000000000145b806103f757507fffffffff0000000000000000000000000000000000000000000000000000000082167fa4c0ed3600000000000000000000000000000000000000000000000000000000145b806101975750507fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4922602052604090205460ff1690565b60606000610460610518565b80519091508067ffffffffffffffff81111561047e5761047e61205d565b6040519080825280602002602001820160405280156104a7578160200160208202803683370190505b50925060005b81811015610512578281815181106104c7576104c761208c565b6020026020010151600001518482815181106104e5576104e561208c565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526001016104ad565b50505090565b606060007f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f600490810154604080517f7a0ed627000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff90921692637a0ed6279282820192600092908290030181865afa1580156105ac573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526105f29190810190612157565b905060006105fe610e57565b805190915060608060005b838110156106b55760008582815181106106255761062561208c565b60200260200101516020015151905060005b818110156106ab5761069e85858986815181106106565761065661208c565b60200260200101516020015184815181106106735761067361208c565b60200260200101518a878151811061068d5761068d61208c565b60200260200101516000015161134a565b9095509350600101610637565b5050600101610609565b506000805b865181101561081b576000805b8883815181106106d9576106d961208c565b602002602001015160200151518110156107ff57600073ffffffffffffffffffffffffffffffffffffffff1661074687878c878151811061071c5761071c61208c565b60200260200101516020015185815181106107395761073961208c565b60200260200101516115f1565b73ffffffffffffffffffffffffffffffffffffffff16146107e9578883815181106107735761077361208c565b6020026020010151602001515160010361079c576107918984611637565b9850600193506107ff565b6107c38984815181106107b1576107b161208c565b6020026020010151602001518261182a565b8984815181106107d5576107d561208c565b602002602001015160200181905250600191505b816107f6576001016106c7565b600091506106c7565b508261081057816001019150610815565b600092505b506106ba565b5050600085518461082c9190612304565b90508067ffffffffffffffff8111156108475761084761205d565b60405190808252806020026020018201604052801561088d57816020015b6040805180820190915260008152606060208201528152602001906001900390816108655790505b5096506000805b82811015610a585785811015610a0c578681815181106108b6576108b661208c565b60200260200101518982815181106108d0576108d061208c565b60200260200101819052506000805b8951811015610a05578981815181106108fa576108fa61208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff168b848151811061092e5761092e61208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff16036109ef5761099989848151811061096a5761096a61208c565b6020026020010151602001518b83815181106109885761098861208c565b602002602001015160200151611a3d565b8b84815181106109ab576109ab61208c565b6020026020010151602001819052506109c48a82611637565b9950600191506109e18b60018d516109dc9190612317565b611637565b9a506109ec8561232a565b94505b816109fc576001016108df565b600091506108df565b5050610a50565b878281518110610a1e57610a1e61208c565b6020026020010151898281518110610a3857610a3861208c565b602002602001018190525081610a4d9061235f565b91505b600101610894565b505050505050505090565b60606000610a6f610518565b805190915060005b81811015610aff578473ffffffffffffffffffffffffffffffffffffffff16838281518110610aa857610aa861208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1603610af757828181518110610ae157610ae161208c565b6020026020010151602001519350505050919050565b600101610a77565b505050919050565b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602081905260409091205460601c9081610c1e576004818101546040517fcdffacc60000000000000000000000000000000000000000000000000000000081527fffffffff0000000000000000000000000000000000000000000000000000000086169281019290925273ffffffffffffffffffffffffffffffffffffffff169063cdffacc690602401602060405180830381865afa158015610bf7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c1b9190612397565b91505b50919050565b6060610c2e611b8b565b905090565b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604081205460601c610197565b6060610c2e610e57565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9060009061ffff1667ffffffffffffffff811115610cfc57610cfc61205d565b604051908082528060200260200182016040528015610d25578160200160208202803683370190505b5092506000805b600284015461ffff16821015610e4d576000818152600185016020526040812054905b6008811015610e385783610d628161235f565b600288015490955061ffff1685119050610e3857600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020889052604090205460601c73ffffffffffffffffffffffffffffffffffffffff8a16819003610e235781898881518110610de457610de461208c565b7fffffffff000000000000000000000000000000000000000000000000000000009092166020928302919091019091015286610e1f8161235f565b9750505b50508080610e309061235f565b915050610d4f565b50508080610e459061235f565b915050610d2c565b5050825250919050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff1667ffffffffffffffff811115610eba57610eba61205d565b604051908082528060200260200182016040528015610f0057816020015b604080518082019091526000815260606020820152815260200190600190039081610ed85790505b50600282015490925060009061ffff1667ffffffffffffffff811115610f2857610f2861205d565b604051908082528060200260200182016040528015610f51578160200160208202803683370190505b50905060008060005b600285015461ffff168210156112d7576000818152600186016020526040812054905b60088110156112c25783610f908161235f565b600289015490955061ffff16851190506112c257600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020899052604081205460601c90805b88811015611148578273ffffffffffffffffffffffffffffffffffffffff168c82815181106110155761101561208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff160361113657838c828151811061104f5761104f61208c565b6020026020010151602001518b838151811061106d5761106d61208c565b602002602001015161ffff16815181106110895761108961208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152505060ff8a82815181106110e9576110e961208c565b602002602001015161ffff16106110ff57600080fd5b8981815181106111115761111161208c565b602002602001018051809190611126906123b4565b61ffff1690525060019150611148565b806111408161235f565b915050610fe4565b508015611157575050506112b0565b818b898151811061116a5761116a61208c565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff909116905260028a015461ffff1667ffffffffffffffff8111156111b0576111b061205d565b6040519080825280602002602001820160405280156111d9578160200160208202803683370190505b508b89815181106111ec576111ec61208c565b602002602001015160200181905250828b898151811061120e5761120e61208c565b60200260200101516020015160008151811061122c5761122c61208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681525050600189898151811061128c5761128c61208c565b61ffff90921660209283029190910190910152876112a98161235f565b9850505050505b806112ba8161235f565b915050610f7d565b505080806112cf9061235f565b915050610f5a565b5060005b8281101561133f5760008482815181106112f7576112f761208c565b602002602001015161ffff16905060008783815181106113195761131961208c565b6020026020010151602001519050818152505080806113379061235f565b9150506112db565b508185525050505090565b60608060006113598786611da0565b8751909150808210156113b857848783815181106113795761137961208c565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250506115df565b60006113c5826001612304565b67ffffffffffffffff8111156113dd576113dd61205d565b604051908082528060200260200182016040528015611406578160200160208202803683370190505b5090506000885160016114199190612304565b67ffffffffffffffff8111156114315761143161205d565b60405190808252806020026020018201604052801561145a578160200160208202803683370190505b50905060005b83811015611539578a818151811061147a5761147a61208c565b60200260200101518382815181106114945761149461208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815250508981815181106114f2576114f261208c565b602002602001015182828151811061150c5761150c61208c565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101611460565b508782848151811061154d5761154d61208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152505086818a51815181106115ad576115ad61208c565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015290945092506115e8915050565b87879350935050505b94509492505050565b6000806115fe8584611da0565b905084518110611612576000915050611630565b8381815181106116245761162461208c565b60200260200101519150505b9392505050565b6060825182106116a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420696e6465780000000000000000000000000000000000000060448201526064015b60405180910390fd5b8251600003611713576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420617272617900000000000000000000000000000000000000604482015260640161169f565b6000600184516117239190612317565b67ffffffffffffffff81111561173b5761173b61205d565b60405190808252806020026020018201604052801561178157816020015b6040805180820190915260008152606060208201528152602001906001900390816117595790505b50805190915060005b8181101561182057848110156117d6578581815181106117ac576117ac61208c565b60200260200101518382815181106117c6576117c661208c565b6020026020010181905250611818565b856117e2826001612304565b815181106117f2576117f261208c565b602002602001015183828151811061180c5761180c61208c565b60200260200101819052505b60010161178a565b5090949350505050565b606082518210611896576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420696e64657800000000000000000000000000000000000000604482015260640161169f565b8251600003611901576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420617272617900000000000000000000000000000000000000604482015260640161169f565b6000600184516119119190612317565b67ffffffffffffffff8111156119295761192961205d565b604051908082528060200260200182016040528015611952578160200160208202803683370190505b50805190915060005b8181101561182057848110156119cd5785818151811061197d5761197d61208c565b60200260200101518382815181106119975761199761208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152611a35565b856119d9826001612304565b815181106119e9576119e961208c565b6020026020010151838281518110611a0357611a0361208c565b7fffffffff00000000000000000000000000000000000000000000000000000000909216602092830291909101909101525b60010161195b565b81518151606091906000611a518284612304565b67ffffffffffffffff811115611a6957611a6961205d565b604051908082528060200260200182016040528015611a92578160200160208202803683370190505b50905060005b83811015611b0557868181518110611ab257611ab261208c565b6020026020010151828281518110611acc57611acc61208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152600101611a98565b5060005b82811015611b8157858181518110611b2357611b2361208c565b6020026020010151828286611b389190612304565b81518110611b4857611b4861208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152600101611b09565b5095945050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff1667ffffffffffffffff811115611bee57611bee61205d565b604051908082528060200260200182016040528015611c17578160200160208202803683370190505b50915060008060005b600284015461ffff16821015611d98576000818152600185016020526040812054905b6008811015611d835783611c568161235f565b600288015490955061ffff1685119050611d8357600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020889052604081205460601c90805b88811015611d19578a8181518110611cc457611cc461208c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611d075760019150611d19565b80611d118161235f565b915050611caa565b508015611d2857505050611d71565b818a8981518110611d3b57611d3b61208c565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015287611d6a8161235f565b9850505050505b80611d7b8161235f565b915050611c43565b50508080611d909061235f565b915050611c20565b505082525090565b8151600090815b81811015611e1e57837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916858281518110611de157611de161208c565b60200260200101517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603611e165791506101979050565b600101611da7565b509392505050565b73ffffffffffffffffffffffffffffffffffffffff81168114611e4857600080fd5b50565b600060208284031215611e5d57600080fd5b813561163081611e26565b6020808252825182820181905260009190848201906040850190845b81811015611ec25783517fffffffff000000000000000000000000000000000000000000000000000000001683529284019291840191600101611e84565b50909695505050505050565b7fffffffff0000000000000000000000000000000000000000000000000000000081168114611e4857600080fd5b600060208284031215611f0e57600080fd5b813561163081611ece565b6020808252825182820181905260009190848201906040850190845b81811015611ec257835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101611f35565b60006020808301818452808551808352604092508286019150828160051b8701018488016000805b8481101561204e578984037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00186528251805173ffffffffffffffffffffffffffffffffffffffff168552880151888501889052805188860181905290890190839060608701905b808310156120395783517fffffffff00000000000000000000000000000000000000000000000000000000168252928b019260019290920191908b0190611ff7565b50978a01979550505091870191600101611f8f565b50919998505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6040805190810167ffffffffffffffff811182821017156120de576120de61205d565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561212b5761212b61205d565b604052919050565b600067ffffffffffffffff82111561214d5761214d61205d565b5060051b60200190565b6000602080838503121561216a57600080fd5b825167ffffffffffffffff8082111561218257600080fd5b818501915085601f83011261219657600080fd5b81516121a96121a482612133565b6120e4565b81815260059190911b830184019084810190888311156121c857600080fd5b8585015b838110156122c8578051858111156121e45760008081fd5b86016040818c037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00181131561221a5760008081fd5b6122226120bb565b8983015161222f81611e26565b815282820151888111156122435760008081fd5b8084019350508c603f8401126122595760008081fd5b898301516122696121a482612133565b81815260059190911b84018301908b8101908f8311156122895760008081fd5b948401945b828610156122b357855194506122a385611ece565b848252948c0194908c019061228e565b838d01525050855250509186019186016121cc565b5098975050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610197576101976122d5565b81810381811115610197576101976122d5565b600081612339576123396122d5565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612390576123906122d5565b5060010190565b6000602082840312156123a957600080fd5b815161163081611e26565b600061ffff8083168181036123cb576123cb6122d5565b600101939250505056fea26469706673582212205959d8d85aad6f29d5fc37d5a52c404c25392cec49195c3b761da0e863e99b0f64736f6c63430008150033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100a35760003560e01c8063adfca15e11610076578063d42139a91161005b578063d42139a914610169578063e3a2f6fe14610171578063f9796ccf1461018457600080fd5b8063adfca15e1461011e578063cdffacc61461013157600080fd5b806301a55022146100a857806301ffc9a7146100d157806352ef6b2c146100f45780637a0ed62714610109575b600080fd5b6100bb6100b6366004611e4b565b61018c565b6040516100c89190611e68565b60405180910390f35b6100e46100df366004611efc565b61019d565b60405190151581526020016100c8565b6100fc610454565b6040516100c89190611f19565b610111610518565b6040516100c89190611f67565b6100bb61012c366004611e4b565b610a63565b61014461013f366004611efc565b610b07565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100c8565b6100fc610c24565b61014461017f366004611efc565b610c33565b610111610c8c565b606061019782610c96565b92915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000148061023057507fffffffff0000000000000000000000000000000000000000000000000000000082167f1f931c1c00000000000000000000000000000000000000000000000000000000145b8061027c57507fffffffff0000000000000000000000000000000000000000000000000000000082167f48e2b09300000000000000000000000000000000000000000000000000000000145b806102c857507fffffffff0000000000000000000000000000000000000000000000000000000082167f4e2312e000000000000000000000000000000000000000000000000000000000145b8061031457507fffffffff0000000000000000000000000000000000000000000000000000000082167f150b7a0200000000000000000000000000000000000000000000000000000000145b8061035f57507fffffffff0000000000000000000000000000000000000000000000000000000082167e23de2900000000000000000000000000000000000000000000000000000000145b806103ab57507fffffffff0000000000000000000000000000000000000000000000000000000082167f1626ba7e00000000000000000000000000000000000000000000000000000000145b806103f757507fffffffff0000000000000000000000000000000000000000000000000000000082167fa4c0ed3600000000000000000000000000000000000000000000000000000000145b806101975750507fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4922602052604090205460ff1690565b60606000610460610518565b80519091508067ffffffffffffffff81111561047e5761047e61205d565b6040519080825280602002602001820160405280156104a7578160200160208202803683370190505b50925060005b81811015610512578281815181106104c7576104c761208c565b6020026020010151600001518482815181106104e5576104e561208c565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526001016104ad565b50505090565b606060007f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f600490810154604080517f7a0ed627000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff90921692637a0ed6279282820192600092908290030181865afa1580156105ac573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526105f29190810190612157565b905060006105fe610e57565b805190915060608060005b838110156106b55760008582815181106106255761062561208c565b60200260200101516020015151905060005b818110156106ab5761069e85858986815181106106565761065661208c565b60200260200101516020015184815181106106735761067361208c565b60200260200101518a878151811061068d5761068d61208c565b60200260200101516000015161134a565b9095509350600101610637565b5050600101610609565b506000805b865181101561081b576000805b8883815181106106d9576106d961208c565b602002602001015160200151518110156107ff57600073ffffffffffffffffffffffffffffffffffffffff1661074687878c878151811061071c5761071c61208c565b60200260200101516020015185815181106107395761073961208c565b60200260200101516115f1565b73ffffffffffffffffffffffffffffffffffffffff16146107e9578883815181106107735761077361208c565b6020026020010151602001515160010361079c576107918984611637565b9850600193506107ff565b6107c38984815181106107b1576107b161208c565b6020026020010151602001518261182a565b8984815181106107d5576107d561208c565b602002602001015160200181905250600191505b816107f6576001016106c7565b600091506106c7565b508261081057816001019150610815565b600092505b506106ba565b5050600085518461082c9190612304565b90508067ffffffffffffffff8111156108475761084761205d565b60405190808252806020026020018201604052801561088d57816020015b6040805180820190915260008152606060208201528152602001906001900390816108655790505b5096506000805b82811015610a585785811015610a0c578681815181106108b6576108b661208c565b60200260200101518982815181106108d0576108d061208c565b60200260200101819052506000805b8951811015610a05578981815181106108fa576108fa61208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff168b848151811061092e5761092e61208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff16036109ef5761099989848151811061096a5761096a61208c565b6020026020010151602001518b83815181106109885761098861208c565b602002602001015160200151611a3d565b8b84815181106109ab576109ab61208c565b6020026020010151602001819052506109c48a82611637565b9950600191506109e18b60018d516109dc9190612317565b611637565b9a506109ec8561232a565b94505b816109fc576001016108df565b600091506108df565b5050610a50565b878281518110610a1e57610a1e61208c565b6020026020010151898281518110610a3857610a3861208c565b602002602001018190525081610a4d9061235f565b91505b600101610894565b505050505050505090565b60606000610a6f610518565b805190915060005b81811015610aff578473ffffffffffffffffffffffffffffffffffffffff16838281518110610aa857610aa861208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1603610af757828181518110610ae157610ae161208c565b6020026020010151602001519350505050919050565b600101610a77565b505050919050565b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602081905260409091205460601c9081610c1e576004818101546040517fcdffacc60000000000000000000000000000000000000000000000000000000081527fffffffff0000000000000000000000000000000000000000000000000000000086169281019290925273ffffffffffffffffffffffffffffffffffffffff169063cdffacc690602401602060405180830381865afa158015610bf7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c1b9190612397565b91505b50919050565b6060610c2e611b8b565b905090565b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604081205460601c610197565b6060610c2e610e57565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9060009061ffff1667ffffffffffffffff811115610cfc57610cfc61205d565b604051908082528060200260200182016040528015610d25578160200160208202803683370190505b5092506000805b600284015461ffff16821015610e4d576000818152600185016020526040812054905b6008811015610e385783610d628161235f565b600288015490955061ffff1685119050610e3857600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020889052604090205460601c73ffffffffffffffffffffffffffffffffffffffff8a16819003610e235781898881518110610de457610de461208c565b7fffffffff000000000000000000000000000000000000000000000000000000009092166020928302919091019091015286610e1f8161235f565b9750505b50508080610e309061235f565b915050610d4f565b50508080610e459061235f565b915050610d2c565b5050825250919050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff1667ffffffffffffffff811115610eba57610eba61205d565b604051908082528060200260200182016040528015610f0057816020015b604080518082019091526000815260606020820152815260200190600190039081610ed85790505b50600282015490925060009061ffff1667ffffffffffffffff811115610f2857610f2861205d565b604051908082528060200260200182016040528015610f51578160200160208202803683370190505b50905060008060005b600285015461ffff168210156112d7576000818152600186016020526040812054905b60088110156112c25783610f908161235f565b600289015490955061ffff16851190506112c257600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020899052604081205460601c90805b88811015611148578273ffffffffffffffffffffffffffffffffffffffff168c82815181106110155761101561208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff160361113657838c828151811061104f5761104f61208c565b6020026020010151602001518b838151811061106d5761106d61208c565b602002602001015161ffff16815181106110895761108961208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152505060ff8a82815181106110e9576110e961208c565b602002602001015161ffff16106110ff57600080fd5b8981815181106111115761111161208c565b602002602001018051809190611126906123b4565b61ffff1690525060019150611148565b806111408161235f565b915050610fe4565b508015611157575050506112b0565b818b898151811061116a5761116a61208c565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff909116905260028a015461ffff1667ffffffffffffffff8111156111b0576111b061205d565b6040519080825280602002602001820160405280156111d9578160200160208202803683370190505b508b89815181106111ec576111ec61208c565b602002602001015160200181905250828b898151811061120e5761120e61208c565b60200260200101516020015160008151811061122c5761122c61208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681525050600189898151811061128c5761128c61208c565b61ffff90921660209283029190910190910152876112a98161235f565b9850505050505b806112ba8161235f565b915050610f7d565b505080806112cf9061235f565b915050610f5a565b5060005b8281101561133f5760008482815181106112f7576112f761208c565b602002602001015161ffff16905060008783815181106113195761131961208c565b6020026020010151602001519050818152505080806113379061235f565b9150506112db565b508185525050505090565b60608060006113598786611da0565b8751909150808210156113b857848783815181106113795761137961208c565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250506115df565b60006113c5826001612304565b67ffffffffffffffff8111156113dd576113dd61205d565b604051908082528060200260200182016040528015611406578160200160208202803683370190505b5090506000885160016114199190612304565b67ffffffffffffffff8111156114315761143161205d565b60405190808252806020026020018201604052801561145a578160200160208202803683370190505b50905060005b83811015611539578a818151811061147a5761147a61208c565b60200260200101518382815181106114945761149461208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815250508981815181106114f2576114f261208c565b602002602001015182828151811061150c5761150c61208c565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101611460565b508782848151811061154d5761154d61208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152505086818a51815181106115ad576115ad61208c565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015290945092506115e8915050565b87879350935050505b94509492505050565b6000806115fe8584611da0565b905084518110611612576000915050611630565b8381815181106116245761162461208c565b60200260200101519150505b9392505050565b6060825182106116a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420696e6465780000000000000000000000000000000000000060448201526064015b60405180910390fd5b8251600003611713576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420617272617900000000000000000000000000000000000000604482015260640161169f565b6000600184516117239190612317565b67ffffffffffffffff81111561173b5761173b61205d565b60405190808252806020026020018201604052801561178157816020015b6040805180820190915260008152606060208201528152602001906001900390816117595790505b50805190915060005b8181101561182057848110156117d6578581815181106117ac576117ac61208c565b60200260200101518382815181106117c6576117c661208c565b6020026020010181905250611818565b856117e2826001612304565b815181106117f2576117f261208c565b602002602001015183828151811061180c5761180c61208c565b60200260200101819052505b60010161178a565b5090949350505050565b606082518210611896576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420696e64657800000000000000000000000000000000000000604482015260640161169f565b8251600003611901576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420617272617900000000000000000000000000000000000000604482015260640161169f565b6000600184516119119190612317565b67ffffffffffffffff8111156119295761192961205d565b604051908082528060200260200182016040528015611952578160200160208202803683370190505b50805190915060005b8181101561182057848110156119cd5785818151811061197d5761197d61208c565b60200260200101518382815181106119975761199761208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152611a35565b856119d9826001612304565b815181106119e9576119e961208c565b6020026020010151838281518110611a0357611a0361208c565b7fffffffff00000000000000000000000000000000000000000000000000000000909216602092830291909101909101525b60010161195b565b81518151606091906000611a518284612304565b67ffffffffffffffff811115611a6957611a6961205d565b604051908082528060200260200182016040528015611a92578160200160208202803683370190505b50905060005b83811015611b0557868181518110611ab257611ab261208c565b6020026020010151828281518110611acc57611acc61208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152600101611a98565b5060005b82811015611b8157858181518110611b2357611b2361208c565b6020026020010151828286611b389190612304565b81518110611b4857611b4861208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152600101611b09565b5095945050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff1667ffffffffffffffff811115611bee57611bee61205d565b604051908082528060200260200182016040528015611c17578160200160208202803683370190505b50915060008060005b600284015461ffff16821015611d98576000818152600185016020526040812054905b6008811015611d835783611c568161235f565b600288015490955061ffff1685119050611d8357600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020889052604081205460601c90805b88811015611d19578a8181518110611cc457611cc461208c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611d075760019150611d19565b80611d118161235f565b915050611caa565b508015611d2857505050611d71565b818a8981518110611d3b57611d3b61208c565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015287611d6a8161235f565b9850505050505b80611d7b8161235f565b915050611c43565b50508080611d909061235f565b915050611c20565b505082525090565b8151600090815b81811015611e1e57837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916858281518110611de157611de161208c565b60200260200101517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603611e165791506101979050565b600101611da7565b509392505050565b73ffffffffffffffffffffffffffffffffffffffff81168114611e4857600080fd5b50565b600060208284031215611e5d57600080fd5b813561163081611e26565b6020808252825182820181905260009190848201906040850190845b81811015611ec25783517fffffffff000000000000000000000000000000000000000000000000000000001683529284019291840191600101611e84565b50909695505050505050565b7fffffffff0000000000000000000000000000000000000000000000000000000081168114611e4857600080fd5b600060208284031215611f0e57600080fd5b813561163081611ece565b6020808252825182820181905260009190848201906040850190845b81811015611ec257835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101611f35565b60006020808301818452808551808352604092508286019150828160051b8701018488016000805b8481101561204e578984037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00186528251805173ffffffffffffffffffffffffffffffffffffffff168552880151888501889052805188860181905290890190839060608701905b808310156120395783517fffffffff00000000000000000000000000000000000000000000000000000000168252928b019260019290920191908b0190611ff7565b50978a01979550505091870191600101611f8f565b50919998505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6040805190810167ffffffffffffffff811182821017156120de576120de61205d565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561212b5761212b61205d565b604052919050565b600067ffffffffffffffff82111561214d5761214d61205d565b5060051b60200190565b6000602080838503121561216a57600080fd5b825167ffffffffffffffff8082111561218257600080fd5b818501915085601f83011261219657600080fd5b81516121a96121a482612133565b6120e4565b81815260059190911b830184019084810190888311156121c857600080fd5b8585015b838110156122c8578051858111156121e45760008081fd5b86016040818c037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00181131561221a5760008081fd5b6122226120bb565b8983015161222f81611e26565b815282820151888111156122435760008081fd5b8084019350508c603f8401126122595760008081fd5b898301516122696121a482612133565b81815260059190911b84018301908b8101908f8311156122895760008081fd5b948401945b828610156122b357855194506122a385611ece565b848252948c0194908c019061228e565b838d01525050855250509186019186016121cc565b5098975050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610197576101976122d5565b81810381811115610197576101976122d5565b600081612339576123396122d5565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612390576123906122d5565b5060010190565b6000602082840312156123a957600080fd5b815161163081611e26565b600061ffff8083168181036123cb576123cb6122d5565b600101939250505056fea26469706673582212205959d8d85aad6f29d5fc37d5a52c404c25392cec49195c3b761da0e863e99b0f64736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "DiamondLoupe contract compatible with EIP-2535", + "kind": "dev", + "methods": { + "facetAddress(bytes4)": { + "details": "If facet is not found return address(0).", + "params": { + "_functionSelector": "The function selector." + }, + "returns": { + "facetAddress_": "The facet address." + } + }, + "facetAddressFromStorage(bytes4)": { + "params": { + "_functionSelector": "Function selector to fetch the facet address from diamond storage" + }, + "returns": { + "facetAddress_": "Facet address mapped with the function selector" + } + }, + "facetAddresses()": { + "returns": { + "facetAddresses_": "facetAddresses_" + } + }, + "facetAddressesFromStorage()": { + "returns": { + "facetAddresses_": "All facet addresses attached directly to diamond storage" + } + }, + "facetFunctionSelectors(address)": { + "params": { + "_facet": "The facet address." + }, + "returns": { + "facetFunctionSelectors_": "facetFunctionSelectors_" + } + }, + "facetFunctionSelectorsFromStorage(address)": { + "params": { + "_facet": "Facet address to fetch the facet function selectors from diamond storage" + }, + "returns": { + "facetFunctionSelectors_": "Facet function selectors of the given facet address" + } + }, + "facets()": { + "details": "Barz uses a special architecture called default fallback handler. Default Fallback handler is used as a middleware that holds the mapping of facet function selector and facet address that Barz uses. This helps Barz to reduce significant amount of gas during the initialization process. Hence, this method aggregates both the facet information from DefaulFallbackHandler and in diamond storage and shows the data to users.", + "returns": { + "facets_": "Facet" + } + }, + "facetsFromStorage()": { + "returns": { + "facets_": "Facet information attached directly to diamond storage" + } + }, + "supportsInterface(bytes4)": { + "params": { + "_interfaceId": "Interface ID for detecting the interface" + }, + "returns": { + "isSupported": "Bool value showing if the standard is supported in the contract" + } + } + }, + "title": "DiamondLoupe Facet", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "facetAddress(bytes4)": { + "notice": "Gets the facet that supports the given selector." + }, + "facetAddressFromStorage(bytes4)": { + "notice": "Returns the facet address attached to the given function selector. This excludes the facets from the default fallback handler" + }, + "facetAddresses()": { + "notice": "Get all the facet addresses used by Barz." + }, + "facetAddressesFromStorage()": { + "notice": "Returns all facet addresses attached directly to diamond storage. This excludes the facets from the default fallback handler" + }, + "facetFunctionSelectors(address)": { + "notice": "Gets all the function selectors provided by a facet." + }, + "facetFunctionSelectorsFromStorage(address)": { + "notice": "Returns function selectors of given facet address attached directly to diamond storage. This excludes the facets from the default fallback handler" + }, + "facets()": { + "notice": "Gets all facets and their selectors." + }, + "facetsFromStorage()": { + "notice": "Returns the facet from the diamond storage. This excludes the facets from the default fallback handler" + }, + "supportsInterface(bytes4)": { + "notice": "SupportInterface to be compatible with EIP 165" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/base/Secp256r1VerificationFacet.json b/deployments/base/Secp256r1VerificationFacet.json new file mode 100644 index 0000000..229b8b3 --- /dev/null +++ b/deployments/base/Secp256r1VerificationFacet.json @@ -0,0 +1,483 @@ +{ + "address": "0xeE1AF8E967eC04C84711842796A5E714D2FD33e6", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "LibAppStorage__AccountMustBeUninitialized", + "type": "error" + }, + { + "inputs": [], + "name": "LibAppStorage__SignerAlreadyUninitialized", + "type": "error" + }, + { + "inputs": [], + "name": "LibAppStorage__SignerMustBeUninitialized", + "type": "error" + }, + { + "inputs": [], + "name": "Secp256r1VerificationFacet__InvalidSignerLength", + "type": "error" + }, + { + "inputs": [], + "name": "VerificationFacet__InitializationFailure", + "type": "error" + }, + { + "inputs": [], + "name": "VerificationFacet__InvalidFacetMapping", + "type": "error" + }, + { + "inputs": [], + "name": "VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet", + "type": "error" + }, + { + "inputs": [], + "name": "VerificationFacet__ValidateOwnerSignatureSelectorNotSet", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "SignerInitialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "SignerUninitialized", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_publicKey", + "type": "bytes" + } + ], + "name": "initializeSigner", + "outputs": [ + { + "internalType": "uint256", + "name": "initSuccess", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_publicKey", + "type": "bytes" + } + ], + "name": "isValidKeyType", + "outputs": [ + { + "internalType": "bool", + "name": "isValid", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_hash", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "_signature", + "type": "bytes" + } + ], + "name": "isValidSignature", + "outputs": [ + { + "internalType": "bytes4", + "name": "magicValue", + "type": "bytes4" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "bytes", + "name": "signer", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "self", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "uninitializeSigner", + "outputs": [ + { + "internalType": "uint256", + "name": "uninitSuccess", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "initCode", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "callGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "verificationGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "preVerificationGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxFeePerGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPriorityFeePerGas", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "paymasterAndData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "internalType": "struct UserOperation", + "name": "userOp", + "type": "tuple" + }, + { + "internalType": "bytes32", + "name": "userOpHash", + "type": "bytes32" + } + ], + "name": "validateOwnerSignature", + "outputs": [ + { + "internalType": "uint256", + "name": "validationData", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "validateOwnerSignatureSelector", + "outputs": [ + { + "internalType": "bytes4", + "name": "ownerSignatureValidatorSelector", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "initCode", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "callGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "verificationGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "preVerificationGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxFeePerGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPriorityFeePerGas", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "paymasterAndData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "internalType": "struct UserOperation", + "name": "userOp", + "type": "tuple" + }, + { + "internalType": "bytes32", + "name": "userOpHash", + "type": "bytes32" + }, + { + "internalType": "uint256[2]", + "name": "q", + "type": "uint256[2]" + } + ], + "name": "validateSignature", + "outputs": [ + { + "internalType": "uint256", + "name": "isValid", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0x457b578dff060b16704222abb0e8d14bf09afe63c30ebc639b61785c37d6876d", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 5, + "gasUsed": "1809225", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x77f59598af1ac7b8d81d99364752cb1132ae967de5bd5c5159f14b03ed8f7043", + "transactionHash": "0x457b578dff060b16704222abb0e8d14bf09afe63c30ebc639b61785c37d6876d", + "logs": [], + "blockNumber": 6847661, + "cumulativeGasUsed": "2369832", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 3, + "solcInputHash": "4356503edd8ae34e73cb6dd1c8e2fc8a", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"LibAppStorage__AccountMustBeUninitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LibAppStorage__SignerAlreadyUninitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LibAppStorage__SignerMustBeUninitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Secp256r1VerificationFacet__InvalidSignerLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerificationFacet__InitializationFailure\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerificationFacet__InvalidFacetMapping\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerificationFacet__ValidateOwnerSignatureSelectorNotSet\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"SignerInitialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"SignerUninitialized\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_publicKey\",\"type\":\"bytes\"}],\"name\":\"initializeSigner\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"initSuccess\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_publicKey\",\"type\":\"bytes\"}],\"name\":\"isValidKeyType\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isValid\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_hash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"_signature\",\"type\":\"bytes\"}],\"name\":\"isValidSignature\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"magicValue\",\"type\":\"bytes4\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"signer\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"self\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"uninitializeSigner\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"uninitSuccess\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"userOp\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"}],\"name\":\"validateOwnerSignature\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"validationData\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"validateOwnerSignatureSelector\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"ownerSignatureValidatorSelector\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"userOp\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256[2]\",\"name\":\"q\",\"type\":\"uint256[2]\"}],\"name\":\"validateSignature\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"isValid\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Ruslan Serebriakov (@rsrbk)David Yongjun Kim (@Powerstream3604)\",\"details\":\"Primarily used to verify user ops signed with passkeys\",\"kind\":\"dev\",\"methods\":{\"initializeSigner(bytes)\":{\"details\":\"This method checks if the signer has already been initialized. If already initialized, it reverts. It checks if the public key is in the light format and initializes signer storage in k1 storage.\",\"params\":{\"_publicKey\":\"Bytes of owner public key\"},\"returns\":{\"initSuccess\":\"Uint value representing the success of init operation\"}},\"isValidKeyType(bytes)\":{\"details\":\"For this Secp256k1Verification Facet, the public key should in an uncompressed public key format\",\"params\":{\"_publicKey\":\"Bytes of public key for format check\"},\"returns\":{\"isValid\":\"Boolean variable representing if the format of public key is valid\"}},\"isValidSignature(bytes32,bytes)\":{\"details\":\"This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\",\"params\":{\"_hash\":\"Hash value the owner signed\",\"_signature\":\"Signature that signed the above hash\"},\"returns\":{\"magicValue\":\"Bytes4 value representing the success/failure of validation\"}},\"owner()\":{\"returns\":{\"signer\":\"Bytes of owner address\"}},\"uninitializeSigner()\":{\"details\":\"This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\",\"returns\":{\"uninitSuccess\":\"Uint value representing the success of uninit operation\"}},\"validateOwnerSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32)\":{\"details\":\"This method validates if the user operation is signed by the owner. It internally calls validateSignature with signer public key.\",\"params\":{\"userOp\":\"UserOperation including all information for execution\",\"userOpHash\":\"Hash of UserOperation given from EntryPoint. This hash is used for signature validation\"},\"returns\":{\"validationData\":\"Uint value representing whether the validation is successful. 0 for success, 1 for failure\"}},\"validateOwnerSignatureSelector()\":{\"returns\":{\"ownerSignatureValidatorSelector\":\"Bytes4 selector of function signature to validate account owner's UserOperation signature\"}},\"validateSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256[2])\":{\"details\":\"This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\",\"params\":{\"q\":\"Public Key of signer who signed the contract, to be validated\",\"userOp\":\"UserOperation including all information for execution\",\"userOpHash\":\"Hash of UserOperation given from EntryPoint. This hash is used for signature validation\"},\"returns\":{\"isValid\":\"Uint value representing whether the validation is successful. 0 for success, 1 for failure\"}}},\"title\":\"Secp256r1 verification facet\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"This constructor ensures that this contract can only be used as singleton for Proxy contracts\"},\"initializeSigner(bytes)\":{\"notice\":\"Initializes the signer in R1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\"},\"isValidKeyType(bytes)\":{\"notice\":\"Validates if the format of public key is valid for this verification facet\"},\"isValidSignature(bytes32,bytes)\":{\"notice\":\"Validates if the signature is valid. Function to be compatible with EIP-1271\"},\"owner()\":{\"notice\":\"Returns the owner of the account\"},\"uninitializeSigner()\":{\"notice\":\"Uninitialize signer in R1 Facet Storage. This can only be called when the account is undergoing signature migration and has already been initialized.\"},\"validateOwnerSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32)\":{\"notice\":\"Validates if the user operation is signed by the owner.\"},\"validateOwnerSignatureSelector()\":{\"notice\":\"Returns the selector of function to validate the signature of UserOperation\"},\"validateSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256[2])\":{\"notice\":\"Validates if the signature of UserOperation is signed by the given signer\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/verification/secp256r1/Secp256r1VerificationFacet.sol\":\"Secp256r1VerificationFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/utils/math/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\\n * checks.\\n *\\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\\n * easily result in undesired exploitation or bugs, since developers usually\\n * assume that overflows raise errors. `SafeCast` restores this intuition by\\n * reverting the transaction when such an operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n *\\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\\n * all math on `uint256` and `int256` and then downcasting.\\n */\\nlibrary SafeCast {\\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 * _Available since v4.7._\\n */\\n function toUint248(uint256 value) internal pure returns (uint248) {\\n require(value <= type(uint248).max, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint240(uint256 value) internal pure returns (uint240) {\\n require(value <= type(uint240).max, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint232(uint256 value) internal pure returns (uint232) {\\n require(value <= type(uint232).max, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint224(uint256 value) internal pure returns (uint224) {\\n require(value <= type(uint224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint216(uint256 value) internal pure returns (uint216) {\\n require(value <= type(uint216).max, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint208(uint256 value) internal pure returns (uint208) {\\n require(value <= type(uint208).max, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint200(uint256 value) internal pure returns (uint200) {\\n require(value <= type(uint200).max, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint192(uint256 value) internal pure returns (uint192) {\\n require(value <= type(uint192).max, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint184(uint256 value) internal pure returns (uint184) {\\n require(value <= type(uint184).max, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint176(uint256 value) internal pure returns (uint176) {\\n require(value <= type(uint176).max, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint168(uint256 value) internal pure returns (uint168) {\\n require(value <= type(uint168).max, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint160(uint256 value) internal pure returns (uint160) {\\n require(value <= type(uint160).max, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint152(uint256 value) internal pure returns (uint152) {\\n require(value <= type(uint152).max, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint144(uint256 value) internal pure returns (uint144) {\\n require(value <= type(uint144).max, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint136(uint256 value) internal pure returns (uint136) {\\n require(value <= type(uint136).max, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint128(uint256 value) internal pure returns (uint128) {\\n require(value <= type(uint128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint120(uint256 value) internal pure returns (uint120) {\\n require(value <= type(uint120).max, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint112(uint256 value) internal pure returns (uint112) {\\n require(value <= type(uint112).max, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint104(uint256 value) internal pure returns (uint104) {\\n require(value <= type(uint104).max, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint96(uint256 value) internal pure returns (uint96) {\\n require(value <= type(uint96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint88(uint256 value) internal pure returns (uint88) {\\n require(value <= type(uint88).max, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint80(uint256 value) internal pure returns (uint80) {\\n require(value <= type(uint80).max, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint72(uint256 value) internal pure returns (uint72) {\\n require(value <= type(uint72).max, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint64(uint256 value) internal pure returns (uint64) {\\n require(value <= type(uint64).max, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint56(uint256 value) internal pure returns (uint56) {\\n require(value <= type(uint56).max, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint48(uint256 value) internal pure returns (uint48) {\\n require(value <= type(uint48).max, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint40(uint256 value) internal pure returns (uint40) {\\n require(value <= type(uint40).max, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint32(uint256 value) internal pure returns (uint32) {\\n require(value <= type(uint32).max, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint24(uint256 value) internal pure returns (uint24) {\\n require(value <= type(uint24).max, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint16(uint256 value) internal pure returns (uint16) {\\n require(value <= type(uint16).max, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint8(uint256 value) internal pure returns (uint8) {\\n require(value <= type(uint8).max, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\n */\\n function toUint256(int256 value) internal pure returns (uint256) {\\n require(value >= 0, \\\"SafeCast: value must be positive\\\");\\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 * _Available since v4.7._\\n */\\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\\n downcasted = int248(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\\n downcasted = int240(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\\n downcasted = int232(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\\n downcasted = int224(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\\n downcasted = int216(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\\n downcasted = int208(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\\n downcasted = int200(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\\n downcasted = int192(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\\n downcasted = int184(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\\n downcasted = int176(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\\n downcasted = int168(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\\n downcasted = int160(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\\n downcasted = int152(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\\n downcasted = int144(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\\n downcasted = int136(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\\n downcasted = int128(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\\n downcasted = int120(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\\n downcasted = int112(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\\n downcasted = int104(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\\n downcasted = int96(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\\n downcasted = int88(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\\n downcasted = int80(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\\n downcasted = int72(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\\n downcasted = int64(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\\n downcasted = int56(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\\n downcasted = int48(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\\n downcasted = int40(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\\n downcasted = int32(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\\n downcasted = int24(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\\n downcasted = int16(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\\n downcasted = int8(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\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 require(value <= uint256(type(int256).max), \\\"SafeCast: value doesn't fit in an int256\\\");\\n return int256(value);\\n }\\n}\\n\",\"keccak256\":\"0x52a8cfb0f5239d11b457dcdd1b326992ef672714ca8da71a157255bddd13f3ad\",\"license\":\"MIT\"},\"contracts/aa-4337/core/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable no-inline-assembly */\\n\\n/**\\n * returned data from validateUserOp.\\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\\n * @param aggregator - address(0) - the account validated the signature by itself.\\n * address(1) - the account failed to validate the signature.\\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\\n * @param validAfter - this UserOp is valid only after this timestamp.\\n * @param validaUntil - this UserOp is valid only up to this timestamp.\\n */\\nstruct ValidationData {\\n address aggregator;\\n uint48 validAfter;\\n uint48 validUntil;\\n}\\n\\n//extract sigFailed, validAfter, validUntil.\\n// also convert zero validUntil to type(uint48).max\\nfunction _parseValidationData(\\n uint validationData\\n) pure returns (ValidationData memory data) {\\n address aggregator = address(uint160(validationData));\\n uint48 validUntil = uint48(validationData >> 160);\\n if (validUntil == 0) {\\n validUntil = type(uint48).max;\\n }\\n uint48 validAfter = uint48(validationData >> (48 + 160));\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n// intersect account and paymaster ranges.\\nfunction _intersectTimeRange(\\n uint256 validationData,\\n uint256 paymasterValidationData\\n) pure returns (ValidationData memory) {\\n ValidationData memory accountValidationData = _parseValidationData(\\n validationData\\n );\\n ValidationData memory pmValidationData = _parseValidationData(\\n paymasterValidationData\\n );\\n address aggregator = accountValidationData.aggregator;\\n if (aggregator == address(0)) {\\n aggregator = pmValidationData.aggregator;\\n }\\n uint48 validAfter = accountValidationData.validAfter;\\n uint48 validUntil = accountValidationData.validUntil;\\n uint48 pmValidAfter = pmValidationData.validAfter;\\n uint48 pmValidUntil = pmValidationData.validUntil;\\n\\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp\\n * @param data - the ValidationData to pack\\n */\\nfunction _packValidationData(\\n ValidationData memory data\\n) pure returns (uint256) {\\n return\\n uint160(data.aggregator) |\\n (uint256(data.validUntil) << 160) |\\n (uint256(data.validAfter) << (160 + 48));\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp, when not using an aggregator\\n * @param sigFailed - true for signature failure, false for success\\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\\n * @param validAfter first timestamp this UserOperation is valid\\n */\\nfunction _packValidationData(\\n bool sigFailed,\\n uint48 validUntil,\\n uint48 validAfter\\n) pure returns (uint256) {\\n return\\n (sigFailed ? 1 : 0) |\\n (uint256(validUntil) << 160) |\\n (uint256(validAfter) << (160 + 48));\\n}\\n\\n/**\\n * keccak function over calldata.\\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\\n */\\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\\n assembly {\\n let mem := mload(0x40)\\n let len := data.length\\n calldatacopy(mem, data.offset, len)\\n ret := keccak256(mem, len)\\n }\\n}\\n\",\"keccak256\":\"0xa79f06cd158ecb8c0da95493a2f348933b8627a63e228b99738bff3aa107942d\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAggregator.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\n/**\\n * Aggregated Signatures validator.\\n */\\ninterface IAggregator {\\n /**\\n * validate aggregated signature.\\n * revert if the aggregated signature does not match the given list of operations.\\n */\\n function validateSignatures(\\n UserOperation[] calldata userOps,\\n bytes calldata signature\\n ) external view;\\n\\n /**\\n * validate signature of a single userOp\\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\\n * @param userOp the userOperation received from the user.\\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\\n * (usually empty, unless account and aggregator support some kind of \\\"multisig\\\"\\n */\\n function validateUserOpSignature(\\n UserOperation calldata userOp\\n ) external view returns (bytes memory sigForUserOp);\\n\\n /**\\n * aggregate multiple signatures into a single value.\\n * This method is called off-chain to calculate the signature to pass with handleOps()\\n * bundler MAY use optimized custom code perform this aggregation\\n * @param userOps array of UserOperations to collect the signatures from.\\n * @return aggregatedSignature the aggregated signature\\n */\\n function aggregateSignatures(\\n UserOperation[] calldata userOps\\n ) external view returns (bytes memory aggregatedSignature);\\n}\\n\",\"keccak256\":\"0xdfdcd80568f037716674619b31be630fcd8316262f05a815b41d1e81782c966a\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IEntryPoint.sol\":{\"content\":\"/**\\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\\n ** Only one instance required on each chain.\\n **/\\n// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-inline-assembly */\\n/* solhint-disable reason-string */\\n\\nimport \\\"./UserOperation.sol\\\";\\nimport \\\"./IStakeManager.sol\\\";\\nimport \\\"./IAggregator.sol\\\";\\nimport \\\"./INonceManager.sol\\\";\\n\\ninterface IEntryPoint is IStakeManager, INonceManager {\\n /***\\n * An event emitted after each successful request\\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\\n * @param sender - the account that generates this request.\\n * @param paymaster - if non-null, the paymaster that pays for this request.\\n * @param nonce - the nonce value from the request.\\n * @param success - true if the sender transaction succeeded, false if reverted.\\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\\n */\\n event UserOperationEvent(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address indexed paymaster,\\n uint256 nonce,\\n bool success,\\n uint256 actualGasCost,\\n uint256 actualGasUsed\\n );\\n\\n /**\\n * account \\\"sender\\\" was deployed.\\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\\n * @param sender the account that is deployed\\n * @param factory the factory used to deploy this account (in the initCode)\\n * @param paymaster the paymaster used by this UserOp\\n */\\n event AccountDeployed(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address factory,\\n address paymaster\\n );\\n\\n /**\\n * An event emitted if the UserOperation \\\"callData\\\" reverted with non-zero length\\n * @param userOpHash the request unique identifier.\\n * @param sender the sender of this request\\n * @param nonce the nonce used in the request\\n * @param revertReason - the return bytes from the (reverted) call to \\\"callData\\\".\\n */\\n event UserOperationRevertReason(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n uint256 nonce,\\n bytes revertReason\\n );\\n\\n /**\\n * an event emitted by handleOps(), before starting the execution loop.\\n * any event emitted before this event, is part of the validation.\\n */\\n event BeforeExecution();\\n\\n /**\\n * signature aggregator used by the following UserOperationEvents within this bundle.\\n */\\n event SignatureAggregatorChanged(address indexed aggregator);\\n\\n /**\\n * a custom revert error of handleOps, to identify the offending op.\\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\\n * @param reason - revert reason\\n * The string starts with a unique code \\\"AAmn\\\", where \\\"m\\\" is \\\"1\\\" for factory, \\\"2\\\" for account and \\\"3\\\" for paymaster issues,\\n * so a failure can be attributed to the correct entity.\\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\\n */\\n error FailedOp(uint256 opIndex, string reason);\\n\\n /**\\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\\n */\\n error SignatureValidationFailed(address aggregator);\\n\\n /**\\n * Successful result from simulateValidation.\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n */\\n error ValidationResult(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo\\n );\\n\\n /**\\n * Successful result from simulateValidation, if the account returns a signature aggregator\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\\n * bundler MUST use it to verify the signature, or reject the UserOperation\\n */\\n error ValidationResultWithAggregation(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo,\\n AggregatorStakeInfo aggregatorInfo\\n );\\n\\n /**\\n * return value of getSenderAddress\\n */\\n error SenderAddressResult(address sender);\\n\\n /**\\n * return value of simulateHandleOp\\n */\\n error ExecutionResult(\\n uint256 preOpGas,\\n uint256 paid,\\n uint48 validAfter,\\n uint48 validUntil,\\n bool targetSuccess,\\n bytes targetResult\\n );\\n\\n //UserOps handled, per aggregator\\n struct UserOpsPerAggregator {\\n UserOperation[] userOps;\\n // aggregator address\\n IAggregator aggregator;\\n // aggregated signature\\n bytes signature;\\n }\\n\\n /**\\n * Execute a batch of UserOperation.\\n * no signature aggregator is used.\\n * if any account requires an aggregator (that is, it returned an aggregator when\\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\\n * @param ops the operations to execute\\n * @param beneficiary the address to receive the fees\\n */\\n function handleOps(\\n UserOperation[] calldata ops,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * Execute a batch of UserOperation with Aggregators\\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\\n * @param beneficiary the address to receive the fees\\n */\\n function handleAggregatedOps(\\n UserOpsPerAggregator[] calldata opsPerAggregator,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * generate a request Id - unique identifier for this request.\\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\\n */\\n function getUserOpHash(\\n UserOperation calldata userOp\\n ) external view returns (bytes32);\\n\\n /**\\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\\n * @param userOp the user operation to validate.\\n */\\n function simulateValidation(UserOperation calldata userOp) external;\\n\\n /**\\n * gas and return values during simulation\\n * @param preOpGas the gas used for validation (including preValidationGas)\\n * @param prefund the required prefund for this operation\\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\\n */\\n struct ReturnInfo {\\n uint256 preOpGas;\\n uint256 prefund;\\n bool sigFailed;\\n uint48 validAfter;\\n uint48 validUntil;\\n bytes paymasterContext;\\n }\\n\\n /**\\n * returned aggregated signature info.\\n * the aggregator returned by the account, and its current stake.\\n */\\n struct AggregatorStakeInfo {\\n address aggregator;\\n StakeInfo stakeInfo;\\n }\\n\\n /**\\n * Get counterfactual sender address.\\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\\n * this method always revert, and returns the address in SenderAddressResult error\\n * @param initCode the constructor code to be passed into the UserOperation.\\n */\\n function getSenderAddress(bytes memory initCode) external;\\n\\n /**\\n * simulate full execution of a UserOperation (including both validation and target execution)\\n * this method will always revert with \\\"ExecutionResult\\\".\\n * it performs full validation of the UserOperation, but ignores signature error.\\n * an optional target address is called after the userop succeeds, and its value is returned\\n * (before the entire call is reverted)\\n * Note that in order to collect the the success/failure of the target call, it must be executed\\n * with trace enabled to track the emitted events.\\n * @param op the UserOperation to simulate\\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\\n * are set to the return from that call.\\n * @param targetCallData callData to pass to target address\\n */\\n function simulateHandleOp(\\n UserOperation calldata op,\\n address target,\\n bytes calldata targetCallData\\n ) external;\\n}\\n\",\"keccak256\":\"0x9ccb1b188eda8bbf5f6c2d01bd83c3d8b2b04fcf745283051d31fe96d1d8e40f\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/INonceManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\ninterface INonceManager {\\n /**\\n * Return the next nonce for this sender.\\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\\n * But UserOp with different keys can come with arbitrary order.\\n *\\n * @param sender the account address\\n * @param key the high 192 bit of the nonce\\n * @return nonce a full nonce to pass for next UserOp with this sender.\\n */\\n function getNonce(\\n address sender,\\n uint192 key\\n ) external view returns (uint256 nonce);\\n\\n /**\\n * Manually increment the nonce of the sender.\\n * This method is exposed just for completeness..\\n * Account does NOT need to call it, neither during validation, nor elsewhere,\\n * as the EntryPoint will update the nonce regardless.\\n * Possible use-case is call it with various keys to \\\"initialize\\\" their nonces to one, so that future\\n * UserOperations will not pay extra for the first transaction with a given key.\\n */\\n function incrementNonce(uint192 key) external;\\n}\\n\",\"keccak256\":\"0xce478ad0fa0d18a3b785ac854623029e7ab463d05873dfaa365abfa1bf100912\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IStakeManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8.12;\\n\\n/**\\n * manage deposits and stakes.\\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\\n * stake is value locked for at least \\\"unstakeDelay\\\" by the staked entity.\\n */\\ninterface IStakeManager {\\n event Deposited(address indexed account, uint256 totalDeposit);\\n\\n event Withdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /// Emitted when stake or unstake delay are modified\\n event StakeLocked(\\n address indexed account,\\n uint256 totalStaked,\\n uint256 unstakeDelaySec\\n );\\n\\n /// Emitted once a stake is scheduled for withdrawal\\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\\n\\n event StakeWithdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /**\\n * @param deposit the entity's deposit\\n * @param staked true if this entity is staked.\\n * @param stake actual amount of ether staked for this entity.\\n * @param unstakeDelaySec minimum delay to withdraw the stake.\\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\\n * and the rest fit into a 2nd cell.\\n * 112 bit allows for 10^15 eth\\n * 48 bit for full timestamp\\n * 32 bit allows 150 years for unstake delay\\n */\\n struct DepositInfo {\\n uint112 deposit;\\n bool staked;\\n uint112 stake;\\n uint32 unstakeDelaySec;\\n uint48 withdrawTime;\\n }\\n\\n //API struct used by getStakeInfo and simulateValidation\\n struct StakeInfo {\\n uint256 stake;\\n uint256 unstakeDelaySec;\\n }\\n\\n /// @return info - full deposit information of given account\\n function getDepositInfo(\\n address account\\n ) external view returns (DepositInfo memory info);\\n\\n /// @return the deposit (for gas payment) of the account\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * add to the deposit of the given account\\n */\\n function depositTo(address account) external payable;\\n\\n /**\\n * add to the account's stake - amount and delay\\n * any pending unstake is first cancelled.\\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\\n */\\n function addStake(uint32 _unstakeDelaySec) external payable;\\n\\n /**\\n * attempt to unlock the stake.\\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\\n */\\n function unlockStake() external;\\n\\n /**\\n * withdraw from the (unlocked) stake.\\n * must first call unlockStake and wait for the unstakeDelay to pass\\n * @param withdrawAddress the address to send withdrawn value.\\n */\\n function withdrawStake(address payable withdrawAddress) external;\\n\\n /**\\n * withdraw from the deposit.\\n * @param withdrawAddress the address to send withdrawn value.\\n * @param withdrawAmount the amount to withdraw.\\n */\\n function withdrawTo(\\n address payable withdrawAddress,\\n uint256 withdrawAmount\\n ) external;\\n}\\n\",\"keccak256\":\"0xadcea606c9b7aafe6645441f2154a60f271330b0eee5292a632aa71c1672d546\",\"license\":\"GPL-3.0-only\"},\"contracts/aa-4337/interfaces/UserOperation.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable no-inline-assembly */\\n\\nimport {calldataKeccak} from \\\"../core/Helpers.sol\\\";\\n\\n/**\\n * User Operation struct\\n * @param sender the sender account of this request.\\n * @param nonce unique value the sender uses to verify it is not a replay.\\n * @param initCode if set, the account contract will be created by this constructor/\\n * @param callData the method call to execute on this account.\\n * @param callGasLimit the gas limit passed to the callData method call.\\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\\n * @param maxFeePerGas same as EIP-1559 gas parameter.\\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\\n */\\nstruct UserOperation {\\n address sender;\\n uint256 nonce;\\n bytes initCode;\\n bytes callData;\\n uint256 callGasLimit;\\n uint256 verificationGasLimit;\\n uint256 preVerificationGas;\\n uint256 maxFeePerGas;\\n uint256 maxPriorityFeePerGas;\\n bytes paymasterAndData;\\n bytes signature;\\n}\\n\\n/**\\n * Utility functions helpful when working with UserOperation structs.\\n */\\nlibrary UserOperationLib {\\n function getSender(\\n UserOperation calldata userOp\\n ) internal pure returns (address) {\\n address data;\\n //read sender from userOp, which is first userOp member (saves 800 gas...)\\n assembly {\\n data := calldataload(userOp)\\n }\\n return address(uint160(data));\\n }\\n\\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\\n // pay above what he signed for.\\n function gasPrice(\\n UserOperation calldata userOp\\n ) internal view returns (uint256) {\\n unchecked {\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n if (maxFeePerGas == maxPriorityFeePerGas) {\\n //legacy mode (for networks that don't support basefee opcode)\\n return maxFeePerGas;\\n }\\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\\n }\\n }\\n\\n function pack(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes memory ret) {\\n address sender = getSender(userOp);\\n uint256 nonce = userOp.nonce;\\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\\n bytes32 hashCallData = calldataKeccak(userOp.callData);\\n uint256 callGasLimit = userOp.callGasLimit;\\n uint256 verificationGasLimit = userOp.verificationGasLimit;\\n uint256 preVerificationGas = userOp.preVerificationGas;\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\\n\\n return\\n abi.encode(\\n sender,\\n nonce,\\n hashInitCode,\\n hashCallData,\\n callGasLimit,\\n verificationGasLimit,\\n preVerificationGas,\\n maxFeePerGas,\\n maxPriorityFeePerGas,\\n hashPaymasterAndData\\n );\\n }\\n\\n function hash(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes32) {\\n return keccak256(pack(userOp));\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n}\\n\",\"keccak256\":\"0x2429f5cc546bdee08c7e63858d0dda8491eaa3ab5194df884dc948c1154d2834\",\"license\":\"GPL-3.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/facets/interfaces/IVerificationFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {UserOperation} from \\\"../../aa-4337/interfaces/UserOperation.sol\\\";\\n\\n/**\\n * @title Verification Facet Interface\\n * @dev Implements logic for user ops signature verification\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\ninterface IVerificationFacet {\\n event SignerInitialized(bytes);\\n event SignerUninitialized();\\n\\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\\n error VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\\n error VerificationFacet__InitializationFailure();\\n error VerificationFacet__InvalidFacetMapping();\\n\\n function initializeSigner(bytes memory) external returns (uint256);\\n\\n function uninitializeSigner() external returns (uint256);\\n\\n function validateOwnerSignatureSelector() external view returns (bytes4);\\n\\n function owner() external view returns (bytes memory);\\n\\n function isValidKeyType(bytes calldata) external view returns (bool);\\n\\n function validateOwnerSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x72bc370a1d1b5a6d6bde67f5026733fd8f6ba434bb90e73b0bd8627fb1579928\",\"license\":\"Apache-2.0\"},\"contracts/facets/verification/secp256r1/Secp256r1VerificationFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {UserOperation} from \\\"../../../aa-4337/interfaces/UserOperation.sol\\\";\\nimport {LibAppStorage} from \\\"../../../libraries/LibAppStorage.sol\\\";\\nimport {LibLoupe} from \\\"../../../libraries/LibLoupe.sol\\\";\\nimport {LibFacetStorage, Secp256r1VerificationStorage} from \\\"../../../libraries/LibFacetStorage.sol\\\";\\nimport {Base64} from \\\"./utils/Base64.sol\\\";\\nimport {LibSecp256r1} from \\\"./utils/LibSecp256r1.sol\\\";\\nimport {IERC1271} from \\\"../../../interfaces/ERC/IERC1271.sol\\\";\\nimport {IVerificationFacet} from \\\"../../interfaces/IVerificationFacet.sol\\\";\\n\\n/**\\n * @title Secp256r1 verification facet\\n * @dev Primarily used to verify user ops signed with passkeys\\n * @author Ruslan Serebriakov (@rsrbk)\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract Secp256r1VerificationFacet is IVerificationFacet, IERC1271 {\\n error Secp256r1VerificationFacet__InvalidSignerLength();\\n address public immutable self;\\n\\n /**\\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\\n */\\n constructor() {\\n LibAppStorage.enforceSignerInitialize();\\n self = address(this);\\n }\\n\\n /**\\n * @notice Initializes the signer in R1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\\n * @param _publicKey Bytes of owner public key\\n * @return initSuccess Uint value representing the success of init operation\\n */\\n function initializeSigner(\\n bytes calldata _publicKey\\n ) public override returns (uint256 initSuccess) {\\n LibAppStorage.enforceSignerInitialize();\\n\\n if (!isValidKeyType(_publicKey))\\n revert Secp256r1VerificationFacet__InvalidSignerLength();\\n\\n bytes memory publicKeyCoordinates = _publicKey[1:];\\n uint256[2] memory q;\\n assembly {\\n // Copy the bytes from the input data into the uint256 array\\n mstore(q, mload(add(publicKeyCoordinates, 32)))\\n mstore(add(q, 32), mload(add(publicKeyCoordinates, 64)))\\n }\\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\\n .r1Storage();\\n r1Storage.q = q;\\n\\n bytes4 validateSelector = validateOwnerSignatureSelector();\\n\\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\\n if (LibLoupe.facetAddress(validateSelector) != self)\\n revert VerificationFacet__InvalidFacetMapping();\\n\\n // initialize verification function selector\\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\\n\\n initSuccess = 1;\\n\\n emit SignerInitialized(_publicKey);\\n }\\n\\n /**\\n * @notice Uninitialize signer in R1 Facet Storage. This can only be called when the account is undergoing signature migration\\n * and has already been initialized.\\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\\n * @return uninitSuccess Uint value representing the success of uninit operation\\n */\\n function uninitializeSigner()\\n external\\n override\\n returns (uint256 uninitSuccess)\\n {\\n LibAppStorage.enforceSignerMigration();\\n LibAppStorage.setSignerUninitialized();\\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\\n .r1Storage();\\n r1Storage.q = [0, 0];\\n\\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\\n\\n uninitSuccess = 1;\\n\\n emit SignerUninitialized();\\n }\\n\\n /**\\n * @notice Validates if the user operation is signed by the owner.\\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\\n * signer public key.\\n * @param userOp UserOperation including all information for execution\\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\\n */\\n function validateOwnerSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) public view override returns (uint256 validationData) {\\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\\n .r1Storage();\\n validationData = validateSignature(userOp, userOpHash, r1Storage.q);\\n }\\n\\n /**\\n * @notice Validates if the signature of UserOperation is signed by the given signer\\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\\n * @param userOp UserOperation including all information for execution\\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\\n * @param q Public Key of signer who signed the contract, to be validated\\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\\n */\\n function validateSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n uint256[2] memory q\\n ) public view returns (uint256 isValid) {\\n isValid = (_validateSignature(q, userOpHash, userOp.signature)) ? 0 : 1;\\n }\\n\\n /**\\n * @notice Returns the selector of function to validate the signature of UserOperation\\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\\n */\\n function validateOwnerSignatureSelector()\\n public\\n pure\\n override\\n returns (bytes4 ownerSignatureValidatorSelector)\\n {\\n return this.validateOwnerSignature.selector; // validateOwnerSignature(UserOperation calldata userOp,bytes32 userOpHash)\\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\\n }\\n\\n /**\\n * @notice Returns the owner of the account\\n * @return signer Bytes of owner address\\n */\\n function owner() public view override returns (bytes memory signer) {\\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\\n .r1Storage();\\n signer = abi.encodePacked(r1Storage.q);\\n }\\n\\n /**\\n * @notice Validates if the format of public key is valid for this verification facet\\n * @dev For this Secp256k1Verification Facet, the public key should in an uncompressed public key format\\n * @param _publicKey Bytes of public key for format check\\n * @return isValid Boolean variable representing if the format of public key is valid\\n */\\n function isValidKeyType(\\n bytes memory _publicKey\\n ) public pure override returns (bool isValid) {\\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\\n }\\n\\n /**\\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\\n * @param _hash Hash value the owner signed\\n * @param _signature Signature that signed the above hash\\n * @return magicValue Bytes4 value representing the success/failure of validation\\n */\\n function isValidSignature(\\n bytes32 _hash,\\n bytes memory _signature\\n ) public view override returns (bytes4 magicValue) {\\n magicValue = _validateSignature(\\n LibFacetStorage.r1Storage().q,\\n _hash,\\n _signature\\n )\\n ? this.isValidSignature.selector\\n : bytes4(0xffffffff);\\n }\\n\\n function _validateSignature(\\n uint256[2] memory q,\\n bytes32 _hash,\\n bytes memory _signature\\n ) internal view returns (bool) {\\n (\\n uint256 rValue,\\n uint256 sValue,\\n bytes memory authenticatorData,\\n string memory clientDataJSONPre,\\n string memory clientDataJSONPost\\n ) = abi.decode(_signature, (uint256, uint256, bytes, string, string));\\n bytes32 clientHash;\\n {\\n string memory opHashBase64 = Base64.encode(bytes.concat(_hash));\\n string memory clientDataJSON = string.concat(\\n clientDataJSONPre,\\n opHashBase64,\\n clientDataJSONPost\\n );\\n clientHash = sha256(bytes(clientDataJSON));\\n }\\n bytes32 sigHash = sha256(bytes.concat(authenticatorData, clientHash));\\n return LibSecp256r1.Verify(q, rValue, sValue, uint256(sigHash));\\n }\\n}\\n\",\"keccak256\":\"0xdb3bae77323eef4e16ef5a5342f548527c9e82b44e8e9dab90906dc2c00082ff\",\"license\":\"Apache-2.0\"},\"contracts/facets/verification/secp256r1/utils/Base64.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @dev Provides a set of functions to operate with Base64 strings.\\n * modified for base64url https://datatracker.ietf.org/doc/html/rfc4648#section-5\\n * _Available since v4.5._\\n */\\nlibrary Base64 {\\n /**\\n * @dev Base64 Encoding/Decoding Table\\n */\\n string internal constant _TABLE =\\n \\\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_\\\";\\n\\n /**\\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\\n */\\n function encode(bytes memory data) internal pure returns (string memory) {\\n /**\\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\\n */\\n if (data.length == 0) return \\\"\\\";\\n\\n // Loads the table into memory\\n string memory table = _TABLE;\\n\\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\\n // and split into 4 numbers of 6 bits.\\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\\n // - `data.length + 2` -> Round up\\n // - `/ 3` -> Number of 3-bytes chunks\\n // - `4 *` -> 4 characters for each chunk\\n uint256 newlength = (data.length * 8) / 6;\\n if (data.length % 6 > 0) {\\n newlength++;\\n }\\n string memory result = new string(newlength);\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n // Prepare the lookup table (skip the first \\\"length\\\" byte)\\n let tablePtr := add(table, 1)\\n\\n // Prepare result pointer, jump over length\\n let resultPtr := add(result, 32)\\n\\n // Run over the input, 3 bytes at a time\\n for {\\n let dataPtr := data\\n let endPtr := add(data, mload(data))\\n } lt(dataPtr, endPtr) {\\n\\n } {\\n // Advance 3 bytes\\n dataPtr := add(dataPtr, 3)\\n let input := mload(dataPtr)\\n\\n // To write each character, shift the 3 bytes (18 bits) chunk\\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\\n // and apply logical AND with 0x3F which is the number of\\n // the previous character in the ASCII table prior to the Base64 Table\\n // The result is then added to the table to get the character to write,\\n // and finally write it in the result pointer but with a left shift\\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\\n\\n mstore8(\\n resultPtr,\\n mload(add(tablePtr, and(shr(18, input), 0x3F)))\\n )\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(\\n resultPtr,\\n mload(add(tablePtr, and(shr(12, input), 0x3F)))\\n )\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(\\n resultPtr,\\n mload(add(tablePtr, and(shr(6, input), 0x3F)))\\n )\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n }\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0xbf0afa21e5a128f260c1a8d4333dc0b0e8755a50d37dfa9b5d362d36ef9cdc14\",\"license\":\"Apache-2.0\"},\"contracts/facets/verification/secp256r1/utils/LibSecp256r1.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n// Heavily inspired from\\n// https://github.com/maxrobot/elliptic-solidity/blob/master/contracts/Secp256r1.sol\\n// https://github.com/tdrerup/elliptic-curve-solidity/blob/master/contracts/curves/EllipticCurve.sol\\n// modified to use precompile 0x05 modexp\\n// and modified jacobian double\\n// optimisations to avoid to an from from affine and jacobian coordinates\\n\\n// Additional Elliptic curve Public key / Signature validation added by\\n// David Yonjun Kim (@Powerstream3604)\\n\\nstruct JPoint {\\n uint256 x;\\n uint256 y;\\n uint256 z;\\n}\\n\\nlibrary LibSecp256r1 {\\n uint256 constant gx =\\n 0x6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296;\\n uint256 constant gy =\\n 0x4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5;\\n uint256 public constant pp =\\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF;\\n\\n uint256 public constant nn =\\n 0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551;\\n uint256 constant a =\\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC;\\n uint256 constant b =\\n 0x5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B;\\n uint256 constant MOST_SIGNIFICANT =\\n 0xc000000000000000000000000000000000000000000000000000000000000000;\\n\\n /*\\n * Verify\\n * @description - verifies that a public key has signed a given message\\n * @param Q - public key coordinates X & Y\\n * @param R - signature half R\\n * @param S - signature half S\\n * @param input - hashed message\\n */\\n function Verify(\\n uint256[2] memory q,\\n uint r,\\n uint s,\\n uint e\\n ) internal view returns (bool) {\\n if (q[0] > pp - 1 || q[1] > pp - 1) {\\n return false;\\n }\\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\\n return false;\\n }\\n if (\\n mulmod(q[1], q[1], pp) !=\\n addmod(\\n addmod(\\n mulmod(q[0], mulmod(q[0], q[0], pp), pp),\\n mulmod(a, q[0], pp),\\n pp\\n ),\\n b,\\n pp\\n )\\n ) {\\n return false;\\n }\\n\\n JPoint[16] memory points = _preComputeJacobianPoints(q);\\n return VerifyWithPrecompute(points, r, s, e);\\n }\\n\\n function VerifyWithPrecompute(\\n JPoint[16] memory points,\\n uint r,\\n uint s,\\n uint e\\n ) internal view returns (bool) {\\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\\n return false;\\n }\\n\\n uint w = _primemod(s, nn);\\n\\n uint u1 = mulmod(e, w, nn);\\n uint u2 = mulmod(r, w, nn);\\n\\n uint x;\\n uint y;\\n\\n (x, y) = ShamirMultJacobian(points, u1, u2);\\n return (x == r);\\n }\\n\\n /*\\n * Strauss Shamir trick for EC multiplication\\n * https://stackoverflow.com/questions/50993471/ec-scalar-multiplication-with-strauss-shamir-method\\n * we optimise on this a bit to do with 2 bits at a time rather than a single bit\\n * the individual points for a single pass are precomputed\\n * overall this reduces the number of additions while keeping the same number of doublings\\n */\\n function ShamirMultJacobian(\\n JPoint[16] memory points,\\n uint u1,\\n uint u2\\n ) internal view returns (uint, uint) {\\n uint x = 0;\\n uint y = 0;\\n uint z = 0;\\n uint bits = 128;\\n uint index = 0;\\n\\n while (bits > 0) {\\n if (z > 0) {\\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\\n }\\n index =\\n ((u1 & MOST_SIGNIFICANT) >> 252) |\\n ((u2 & MOST_SIGNIFICANT) >> 254);\\n if (index > 0) {\\n (x, y, z) = _jAdd(\\n x,\\n y,\\n z,\\n points[index].x,\\n points[index].y,\\n points[index].z\\n );\\n }\\n u1 <<= 2;\\n u2 <<= 2;\\n bits--;\\n }\\n (x, y) = _affineFromJacobian(x, y, z);\\n return (x, y);\\n }\\n\\n function _preComputeJacobianPoints(\\n uint256[2] memory q\\n ) internal pure returns (JPoint[16] memory points) {\\n points[0] = JPoint(0, 0, 0);\\n points[1] = JPoint(q[0], q[1], 1); // u2\\n points[2] = _jPointDouble(points[1]);\\n points[3] = _jPointAdd(points[1], points[2]);\\n\\n points[4] = JPoint(gx, gy, 1); // u1Points[1]\\n points[5] = _jPointAdd(points[4], points[1]);\\n points[6] = _jPointAdd(points[4], points[2]);\\n points[7] = _jPointAdd(points[4], points[3]);\\n\\n points[8] = _jPointDouble(points[4]); // u1Points[2]\\n points[9] = _jPointAdd(points[8], points[1]);\\n points[10] = _jPointAdd(points[8], points[2]);\\n points[11] = _jPointAdd(points[8], points[3]);\\n\\n points[12] = _jPointAdd(points[4], points[8]); // u1Points[3]\\n points[13] = _jPointAdd(points[12], points[1]);\\n points[14] = _jPointAdd(points[12], points[2]);\\n points[15] = _jPointAdd(points[12], points[3]);\\n }\\n\\n function _jPointAdd(\\n JPoint memory p1,\\n JPoint memory p2\\n ) internal pure returns (JPoint memory) {\\n uint x;\\n uint y;\\n uint z;\\n (x, y, z) = _jAdd(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z);\\n return JPoint(x, y, z);\\n }\\n\\n function _jPointDouble(\\n JPoint memory p\\n ) internal pure returns (JPoint memory) {\\n uint x;\\n uint y;\\n uint z;\\n (x, y, z) = _modifiedJacobianDouble(p.x, p.y, p.z);\\n return JPoint(x, y, z);\\n }\\n\\n /* _affineFromJacobian\\n * @desription returns affine coordinates from a jacobian input follows\\n * golang elliptic/crypto library\\n */\\n function _affineFromJacobian(\\n uint x,\\n uint y,\\n uint z\\n ) internal view returns (uint ax, uint ay) {\\n if (z == 0) {\\n return (0, 0);\\n }\\n\\n uint zinv = _primemod(z, pp);\\n uint zinvsq = mulmod(zinv, zinv, pp);\\n\\n ax = mulmod(x, zinvsq, pp);\\n ay = mulmod(y, mulmod(zinvsq, zinv, pp), pp);\\n }\\n\\n /*\\n * _jAdd\\n * @description performs Jacobian addition as defined below:\\n * http://www.hyperelliptic.org/EFD/g1p/data/shortw/jacobian/addition/add-2007-bl\\n */\\n function _jAdd(\\n uint p1,\\n uint p2,\\n uint p3,\\n uint q1,\\n uint q2,\\n uint q3\\n ) internal pure returns (uint r1, uint r2, uint r3) {\\n if (p3 == 0) {\\n r1 = q1;\\n r2 = q2;\\n r3 = q3;\\n\\n return (r1, r2, r3);\\n } else if (q3 == 0) {\\n r1 = p1;\\n r2 = p2;\\n r3 = p3;\\n\\n return (r1, r2, r3);\\n }\\n\\n assembly {\\n let\\n pd\\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\\n let z1z1 := mulmod(p3, p3, pd) // Z1Z1 = Z1^2\\n let z2z2 := mulmod(q3, q3, pd) // Z2Z2 = Z2^2\\n\\n let u1 := mulmod(p1, z2z2, pd) // U1 = X1*Z2Z2\\n let u2 := mulmod(q1, z1z1, pd) // U2 = X2*Z1Z1\\n\\n let s1 := mulmod(p2, mulmod(z2z2, q3, pd), pd) // S1 = Y1*Z2*Z2Z2\\n let s2 := mulmod(q2, mulmod(z1z1, p3, pd), pd) // S2 = Y2*Z1*Z1Z1\\n\\n let p3q3 := addmod(p3, q3, pd)\\n\\n if lt(u2, u1) {\\n u2 := add(pd, u2) // u2 = u2+pd\\n }\\n let h := sub(u2, u1) // H = U2-U1\\n\\n let i := mulmod(0x02, h, pd)\\n i := mulmod(i, i, pd) // I = (2*H)^2\\n\\n let j := mulmod(h, i, pd) // J = H*I\\n if lt(s2, s1) {\\n s2 := add(pd, s2) // u2 = u2+pd\\n }\\n let rr := mulmod(0x02, sub(s2, s1), pd) // r = 2*(S2-S1)\\n r1 := mulmod(rr, rr, pd) // X3 = R^2\\n\\n let v := mulmod(u1, i, pd) // V = U1*I\\n let j2v := addmod(j, mulmod(0x02, v, pd), pd)\\n if lt(r1, j2v) {\\n r1 := add(pd, r1) // X3 = X3+pd\\n }\\n r1 := sub(r1, j2v)\\n\\n // Y3 = r*(V-X3)-2*S1*J\\n let s12j := mulmod(mulmod(0x02, s1, pd), j, pd)\\n\\n if lt(v, r1) {\\n v := add(pd, v)\\n }\\n r2 := mulmod(rr, sub(v, r1), pd)\\n\\n if lt(r2, s12j) {\\n r2 := add(pd, r2)\\n }\\n r2 := sub(r2, s12j)\\n\\n // Z3 = ((Z1+Z2)^2-Z1Z1-Z2Z2)*H\\n z1z1 := addmod(z1z1, z2z2, pd)\\n j2v := mulmod(p3q3, p3q3, pd)\\n if lt(j2v, z1z1) {\\n j2v := add(pd, j2v)\\n }\\n r3 := mulmod(sub(j2v, z1z1), h, pd)\\n }\\n return (r1, r2, r3);\\n }\\n\\n // Point doubling on the modified jacobian coordinates\\n // http://point-at-infinity.org/ecc/Prime_Curve_Modified_Jacobian_Coordinates.html\\n function _modifiedJacobianDouble(\\n uint x,\\n uint y,\\n uint z\\n ) internal pure returns (uint x3, uint y3, uint z3) {\\n if (y == 0) return (0, 0, 0);\\n assembly {\\n let\\n pd\\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\\n let z2 := mulmod(z, z, pd)\\n let az4 := mulmod(\\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC,\\n mulmod(z2, z2, pd),\\n pd\\n )\\n let y2 := mulmod(y, y, pd)\\n let s := mulmod(0x04, mulmod(x, y2, pd), pd)\\n let u := mulmod(0x08, mulmod(y2, y2, pd), pd)\\n let m := addmod(mulmod(0x03, mulmod(x, x, pd), pd), az4, pd)\\n let twos := mulmod(0x02, s, pd)\\n let m2 := mulmod(m, m, pd)\\n if lt(m2, twos) {\\n m2 := add(pd, m2)\\n }\\n x3 := sub(m2, twos)\\n if lt(s, x3) {\\n s := add(pd, s)\\n }\\n y3 := mulmod(m, sub(s, x3), pd)\\n if lt(y3, u) {\\n y3 := add(pd, y3)\\n }\\n y3 := sub(y3, u)\\n z3 := mulmod(0x02, mulmod(y, z, pd), pd)\\n }\\n }\\n\\n // Fermats little theorem https://en.wikipedia.org/wiki/Fermat%27s_little_theorem\\n // a^(p-1) = 1 mod p\\n // a^(-1) \\u2245 a^(p-2) (mod p)\\n // we then use the precompile bigModExp to compute a^(-1)\\n function _primemod(uint value, uint p) internal view returns (uint ret) {\\n ret = modexp(value, p - 2, p);\\n return ret;\\n }\\n\\n // Wrapper for built-in BigNumber_modexp (contract 0x5) as described here. https://github.com/ethereum/EIPs/pull/198\\n function modexp(\\n uint _base,\\n uint _exp,\\n uint _mod\\n ) internal view returns (uint ret) {\\n // bigModExp(_base, _exp, _mod);\\n assembly {\\n if gt(_base, _mod) {\\n _base := mod(_base, _mod)\\n }\\n // Free memory pointer is always stored at 0x40\\n let freemem := mload(0x40)\\n\\n mstore(freemem, 0x20)\\n mstore(add(freemem, 0x20), 0x20)\\n mstore(add(freemem, 0x40), 0x20)\\n\\n mstore(add(freemem, 0x60), _base)\\n mstore(add(freemem, 0x80), _exp)\\n mstore(add(freemem, 0xa0), _mod)\\n\\n let success := staticcall(14000, 0x5, freemem, 0xc0, freemem, 0x20)\\n switch success\\n case 0 {\\n revert(0x0, 0x0)\\n }\\n default {\\n ret := mload(freemem)\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb53714ba63cddb379ba312c1e7f6a423f4d7a7e34fa1364ec8295cd57d544024\",\"license\":\"GPL-3.0\"},\"contracts/infrastructure/interfaces/IFacetRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Registry Interface\\n * @dev Interface for Facet Registry contract to keep track of facets & function selectors addable to user wallets\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IFacetRegistry {\\n struct FacetRegistryConfig {\\n bytes4[] selectors;\\n mapping(bytes4 => FacetInfo) info;\\n }\\n struct FacetInfo {\\n bool exists;\\n uint128 index;\\n }\\n\\n event FacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] facetSelectors\\n );\\n event FacetFunctionSelectorsRemoved(address facet, bytes4[] facetSelectors);\\n\\n error FacetRegistry__FacetSelectorAlreadyRegistered();\\n error FacetRegistry__UnregisteredFacetSelector();\\n\\n function registerFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function removeFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function areFacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external view returns (bool);\\n\\n function isFacetFunctionSelectorRegistered(\\n address facet,\\n bytes4 facetSelector\\n ) external view returns (bool);\\n\\n function getFacetFunctionSelectors(\\n address facet\\n ) external view returns (bytes4[] memory);\\n}\\n\",\"keccak256\":\"0x6e6dd2cab346ef7c31230740ec48d2925e4a9ab24c2f2fb268baaf408dcf02ef\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC1271 {\\n function isValidSignature(\\n bytes32 hash,\\n bytes memory signature\\n ) external view returns (bytes4);\\n}\\n\",\"keccak256\":\"0xcdddb7d5641c9d3f2432dec7fd13fddb9ae1480f25c76c21511e2fa16b8bd422\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibAppStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {SafeCast} from \\\"@openzeppelin/contracts/utils/math/SafeCast.sol\\\";\\nimport {IEntryPoint} from \\\"../aa-4337/interfaces/IEntryPoint.sol\\\";\\nimport {IFacetRegistry} from \\\"../infrastructure/interfaces/IFacetRegistry.sol\\\";\\n\\n/*\\n * @title App Storage\\n * @dev App storage for Barz contract to prevent storage collision\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Lock {\\n uint64 release;\\n bytes4 locker;\\n}\\n\\nstruct InitializersStorage {\\n // NOTE: initialized is a variable to make sure the initialization is only done once.\\n uint8 signerInitialized;\\n uint8 accountInitialized;\\n uint8 restrictionsInitialized;\\n}\\n\\nstruct AppStorage {\\n mapping(uint256 => InitializersStorage) initStorage;\\n uint8 signerMigration;\\n bytes4 validateOwnerSignatureSelector;\\n IEntryPoint entryPoint;\\n IFacetRegistry facetRegistry;\\n mapping(uint256 => Lock) locks;\\n}\\n\\nlibrary LibAppStorage {\\n error LibAppStorage__AccountAlreadyUninitialized();\\n error LibAppStorage__AccountMustBeUninitialized();\\n error LibAppStorage__SignerAlreadyUninitialized();\\n error LibAppStorage__SignerMustBeUninitialized();\\n\\n function appStorage() internal pure returns (AppStorage storage ds) {\\n assembly {\\n ds.slot := 0\\n }\\n }\\n\\n function setSignerUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerAlreadyUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 0;\\n }\\n\\n function getValidateOwnerSignatureSelector()\\n internal\\n view\\n returns (bytes4 selector)\\n {\\n selector = appStorage().validateOwnerSignatureSelector;\\n }\\n\\n function setValidateOwnerSignatureSelector(\\n bytes4 _validateOwnerSignatureSelector\\n ) internal {\\n appStorage()\\n .validateOwnerSignatureSelector = _validateOwnerSignatureSelector;\\n }\\n\\n function enforceSignerInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerMustBeUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 1;\\n }\\n\\n function enforceAccountInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].accountInitialized) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n s.initStorage[0].accountInitialized = 1;\\n }\\n\\n function initiateSignerMigration() internal {\\n appStorage().signerMigration = 1;\\n }\\n\\n function enforceSignerMigration() internal view {\\n if (1 != appStorage().signerMigration) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n }\\n\\n function finalizeSignerMigration() internal {\\n appStorage().signerMigration = 0;\\n }\\n\\n function setLock(uint256 _releaseAfter, bytes4 _locker) internal {\\n appStorage().locks[0] = Lock(SafeCast.toUint64(_releaseAfter), _locker);\\n }\\n\\n function enforceRestrictionsInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__SignerMustBeUninitialized();\\n s.initStorage[0].restrictionsInitialized = 1;\\n }\\n\\n function setRestrictionsUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__AccountAlreadyUninitialized();\\n s.initStorage[0].restrictionsInitialized = 0;\\n }\\n}\\n\\ncontract BarzStorage {\\n AppStorage internal s;\\n modifier onlyWhenUnlocked() {\\n require(\\n uint64(block.timestamp) >= s.locks[0].release,\\n \\\"Account Locked\\\"\\n );\\n _;\\n }\\n modifier onlyWhenLocked() {\\n require(\\n uint64(block.timestamp) < s.locks[0].release,\\n \\\"Account Unlocked\\\"\\n );\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x48524007862a6ce0e07f645950613ce6513ce073c37a109c75019683d42bae27\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\\n bytes4(keccak256(\\\"verifyRestrictions(address,address,uint256,bytes)\\\"));\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // Default Fallback Handler of the barz.\\n IDiamondLoupe defaultFallbackHandler;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function enforceIsSelf() internal view {\\n require(msg.sender == address(this), \\\"LibDiamond: Caller not self\\\");\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n\\n unchecked {\\n facetIndex++;\\n }\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n\\n function restrictionsFacet() internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(\\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2cabdc00de859c3a3170ce3bda5d0e5fd3933d47ce904fd1585f9818b02572f8\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibFacetStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Storage\\n * @dev Storage contract to store each facets variables with diamond storage\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Secp256k1VerificationStorage {\\n address signer;\\n}\\n\\nstruct Secp256r1VerificationStorage {\\n uint256[2] q;\\n}\\n\\nstruct GuardianStorage {\\n mapping(bytes32 => uint256) pending;\\n mapping(uint8 => StorageConfig) configs;\\n}\\n\\nstruct Info {\\n bool exists;\\n uint128 index;\\n}\\n\\nstruct StorageConfig {\\n address[] addresses;\\n mapping(address => Info) info;\\n}\\n\\nstruct RecoveryConfig {\\n bytes recoveryPublicKey;\\n uint64 executeAfter;\\n}\\n\\nstruct ApprovalConfig {\\n bool isApproved;\\n uint64 validUntil;\\n}\\n\\nstruct RecoveryApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isNewOwnerApproved;\\n}\\n\\nstruct RecoveryStorage {\\n mapping(uint8 => RecoveryConfig) recoveryConfigs;\\n mapping(uint8 => RecoveryApprovalConfig) recoveryApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct RestrictionsStorage {\\n address[] restrictions;\\n mapping(address => bool) exists;\\n}\\n\\nstruct SignatureMigrationConfig {\\n bytes migrationPublicKey;\\n address migrationVerificationFacet;\\n bytes4[] migrationSelectors;\\n uint64 migrateAfter;\\n}\\n\\nstruct SignatureMigrationApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isMigrationApproved;\\n}\\n\\nstruct SignatureMigrationStorage {\\n mapping(uint8 => SignatureMigrationConfig) migrationConfigs;\\n mapping(uint8 => SignatureMigrationApprovalConfig) migrationApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct DiamondCutApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isDiamondCutApproved;\\n}\\n\\nstruct DiamondCutStorage {\\n mapping(uint8 => DiamondCutApprovalConfig) diamondCutApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct LockStorage {\\n uint128 nonce;\\n}\\n\\nlibrary LibFacetStorage {\\n bytes32 constant K1_STORAGE_POSITION =\\n keccak256(\\n \\\"v0.trustwallet.diamond.storage.Secp256k1VerificationStorage\\\"\\n );\\n bytes32 constant R1_STORAGE_POSITION =\\n keccak256(\\n \\\"v0.trustwallet.diamond.storage.Secp256r1VerificationStorage\\\"\\n );\\n bytes32 constant GUARDIAN_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.GuardianStorage\\\");\\n bytes32 constant RECOVERY_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.RecoveryStorage\\\");\\n bytes32 constant RESTRICTION_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.RestrictionsStorage\\\");\\n bytes32 constant MIGRATION_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.SignatureMigrationStorage\\\");\\n bytes32 constant DIAMONDCUT_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.DiamondCutStorage\\\");\\n bytes32 constant LOCK_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.LockStorage\\\");\\n\\n function k1Storage()\\n internal\\n pure\\n returns (Secp256k1VerificationStorage storage ds)\\n {\\n bytes32 storagePosition = K1_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function r1Storage()\\n internal\\n pure\\n returns (Secp256r1VerificationStorage storage ds)\\n {\\n bytes32 storagePosition = R1_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function guardianStorage()\\n internal\\n pure\\n returns (GuardianStorage storage ds)\\n {\\n bytes32 storagePosition = GUARDIAN_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function recoveryStorage()\\n internal\\n pure\\n returns (RecoveryStorage storage ds)\\n {\\n bytes32 storagePosition = RECOVERY_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function restrictionsStorage()\\n internal\\n pure\\n returns (RestrictionsStorage storage ds)\\n {\\n bytes32 storagePosition = RESTRICTION_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function migrationStorage()\\n internal\\n pure\\n returns (SignatureMigrationStorage storage ds)\\n {\\n bytes32 storagePosition = MIGRATION_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function diamondCutStorage()\\n internal\\n pure\\n returns (DiamondCutStorage storage ds)\\n {\\n bytes32 storagePosition = DIAMONDCUT_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function lockStorage() internal pure returns (LockStorage storage ds) {\\n bytes32 storagePosition = LOCK_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n}\\n\",\"keccak256\":\"0x87c85decfd943deda9540733e464cb1a92eba735a301e89ce6f798016e359761\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\nimport {LibDiamond} from \\\"./LibDiamond.sol\\\";\\n\\n/**\\n * @title LibLoupe\\n * @dev Internal Library to provide utility feature for reading the state of diamond facets\\n * Originally from Diamond's implementation of Mudgen(author of EIP-2535)\\n */\\nlibrary LibLoupe {\\n /// @notice Gets all facets and their selectors.\\n /// @return facets_ Facet\\n function facets()\\n internal\\n view\\n returns (IDiamondLoupe.Facet[] memory facets_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facets_ = new IDiamondLoupe.Facet[](ds.selectorCount);\\n uint16[] memory numFacetSelectors = new uint16[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facets_[facetIndex].facetAddress == facetAddress_) {\\n facets_[facetIndex].functionSelectors[\\n numFacetSelectors[facetIndex]\\n ] = selector;\\n // probably will never have more than 256 functions from one facet contract\\n require(numFacetSelectors[facetIndex] < 255);\\n numFacetSelectors[facetIndex]++;\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facets_[numFacets].facetAddress = facetAddress_;\\n facets_[numFacets].functionSelectors = new bytes4[](\\n ds.selectorCount\\n );\\n facets_[numFacets].functionSelectors[0] = selector;\\n numFacetSelectors[numFacets] = 1;\\n numFacets++;\\n }\\n }\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n uint256 numSelectors = numFacetSelectors[facetIndex];\\n bytes4[] memory selectors = facets_[facetIndex].functionSelectors;\\n // setting the number of selectors\\n assembly {\\n mstore(selectors, numSelectors)\\n }\\n }\\n // setting the number of facets\\n assembly {\\n mstore(facets_, numFacets)\\n }\\n }\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return _facetFunctionSelectors The selectors associated with a facet address.\\n function facetFunctionSelectors(\\n address _facet\\n ) internal view returns (bytes4[] memory _facetFunctionSelectors) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n uint256 numSelectors;\\n _facetFunctionSelectors = new bytes4[](ds.selectorCount);\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facet = address(bytes20(ds.facets[selector]));\\n if (_facet == facet) {\\n _facetFunctionSelectors[numSelectors] = selector;\\n numSelectors++;\\n }\\n }\\n }\\n // Set the number of selectors in the array\\n assembly {\\n mstore(_facetFunctionSelectors, numSelectors)\\n }\\n }\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n internal\\n view\\n returns (address[] memory facetAddresses_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetAddresses_ = new address[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facetAddress_ == facetAddresses_[facetIndex]) {\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facetAddresses_[numFacets] = facetAddress_;\\n numFacets++;\\n }\\n }\\n // Set the number of facet addresses in the array\\n assembly {\\n mstore(facetAddresses_, numFacets)\\n }\\n }\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(LibDiamond.diamondStorage().facets[_functionSelector])\\n );\\n }\\n}\\n\",\"keccak256\":\"0x0b11439c3cc657095e15ec2241fdcf67204b14001357b612fc5db4ff9e760a5a\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x60a060405234801561001057600080fd5b50610019610022565b3060805261008b565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff161561006f57604051637c2cde8b60e01b815260040160405180910390fd5b600080805260209190915260409020805460ff19166001179055565b608051611f746100ad6000396000818161016001526106e10152611f746000f3fe608060405234801561001057600080fd5b50600436106100a35760003560e01c80637104ddb2116100765780638dd501211161005b5780638dd50121146101bc578063cd00e50a146101cf578063cd9b47e4146101d757600080fd5b80637104ddb21461015b5780638da5cb5b146101a757600080fd5b806311cfe388146100a85780631626ba7e146100ce5780633253960f14610112578063392dd6d914610138575b600080fd5b6100bb6100b6366004611823565b6101ea565b6040519081526020015b60405180910390f35b6100e16100dc366004611956565b610252565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020016100c5565b7f8dd50121000000000000000000000000000000000000000000000000000000006100e1565b61014b61014636600461199d565b6102fd565b60405190151581526020016100c5565b6101827f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100c5565b6101af61036f565b6040516100c591906119f6565b6100bb6101ca366004611a47565b6103ba565b6100bb61041f565b6100bb6101e5366004611a8c565b61053a565b600061023982846101ff610140880188611afe565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061083692505050565b610244576001610247565b60005b60ff16949350505050565b60006102aa7f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b1653646040805180820191829052919060029082845b81548152602001906001019080831161028b5750505050508484610836565b6102d4577fffffffff000000000000000000000000000000000000000000000000000000006102f6565b7f1626ba7e000000000000000000000000000000000000000000000000000000005b9392505050565b60008151604114801561036957508160008151811061031e5761031e611b6a565b6020910101517fff00000000000000000000000000000000000000000000000000000000000000167f0400000000000000000000000000000000000000000000000000000000000000145b92915050565b6040516060907f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364906103a5908290602001611b99565b60405160208183030381529060405291505090565b60408051808201918290526000917f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364916104179186918691859060029082845b8154815260200190600101908083116103fa5750505050506101ea565b949350505050565b60006104296109b4565b6104316109f4565b60408051808201909152600080825260208201527f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364906104749082906002611675565b506000610488600154610100900460e01b90565b7fffffffff0000000000000000000000000000000000000000000000000000000016036104e1576040517f127c609a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff169055604051600192507fcccd30db6bc000b8bb8d11162228d2d69e3c361983ca3ae8c1365ce64b0fae9e90600090a15090565b6000610544610a93565b61058383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102fd92505050565b6105b9576040517f6c334d2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006105c88360018187611bcd565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092935061060992506116b8915050565b602082015181526040820151602082015260006106437f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b16536490565b9050610651818360026116d6565b507f8dd50121000000000000000000000000000000000000000000000000000000006000610686600154610100900460e01b90565b7fffffffff0000000000000000000000000000000000000000000000000000000016146106df576040517f5f95a63c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16610770827fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604090205460601c90565b73ffffffffffffffffffffffffffffffffffffffff16146107bd576040517fbb4752b700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff1661010060e084901c02179055600194507f6d54821a69ec281ed7ba1bf2729c700768c47df1d80fad646b0a14cc1d5c39ed8787604051610824929190611bf7565b60405180910390a15050505092915050565b600080600080600080868060200190518101906108539190611c94565b9450945094509450945060008061088a8a60405160200161087691815260200190565b604051602081830303815290604052610b33565b905060008482856040516020016108a393929190611d47565b60405160208183030381529060405290506002816040516108c49190611d8a565b602060405180830381855afa1580156108e1573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906109049190611da6565b9250505060006002858360405160200161091f929190611dbf565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905261095791611d8a565b602060405180830381855afa158015610974573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906109979190611da6565b90506109a58b888884610c6f565b9b9a5050505050505050505050565b6001805460ff16146109f2576040517f38fc28cb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff16600114610a5c576040517fe00d7c7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff1615610af9576040517f7c2cde8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b60608151600003610b5257505060408051602081019091526000815290565b6000604051806060016040528060408152602001611eff6040913990506000600684516008610b819190611e10565b610b8b9190611e56565b9050600060068551610b9d9190611e6a565b1115610bb15780610bad81611e7e565b9150505b60008167ffffffffffffffff811115610bcc57610bcc61177c565b6040519080825280601f01601f191660200182016040528015610bf6576020820181803683370190505b509050600183016020820186875188015b80821015610c62576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f8116850151845350600183019250610c07565b5092979650505050505050565b6000610c9c60017fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611eb6565b85511180610cd75750610cd060017fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611eb6565b6020860151115b15610ce457506000610417565b831580610cef575082155b80610d1a57507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518410155b80610d4557507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518310155b15610d5257506000610417565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff7f5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff8088600060200201517fffffffff00000001000000000000000000000000fffffffffffffffffffffffc0988517fffffffff00000001000000000000000000000000ffffffffffffffffffffffff90819080098a5109080860208601517fffffffff00000001000000000000000000000000ffffffffffffffffffffffff90800914610e4357506000610417565b6000610e4e86610e66565b9050610e5c81868686611062565b9695505050505050565b610e6e611704565b60405180606001604052806000815260200160008152602001600081525081600060108110610e9f57610e9f611b6a565b60200201526040805160608101909152808360006020020151815260200183600160028110610ed057610ed0611b6a565b60200201518152602001600181525081600160108110610ef257610ef2611b6a565b6020020152610f088160015b602002015161116f565b6040820152610f278160015b60200201518260025b60200201516111d1565b6060828101919091526040805191820181527f6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c29682527f4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f560208301526001908201526080820152610fa18160045b6020020151826001610f1d565b60a0820152610fb1816004610f14565b60c0820152610fca8160045b6020020151826003610f1d565b60e0820152610fda816004610efe565b610100820152610feb816008610f94565b610120820152610ffc816008610f14565b61014082015261100d816008610fbd565b610160820152608081015161102490826008610f1d565b61018082015261103581600c610f94565b6101a082015261104681600c610f14565b6101c082015261105781600c610fbd565b6101e0820152919050565b600083158061106f575082155b8061109a57507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518410155b806110c557507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518310155b156110d257506000610417565b60006110fe847fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551611243565b905060007fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551828509905060007fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551838809905060008061115e8a858561125a565b509098149998505050505050505050565b61119360405180606001604052806000815260200160008152602001600081525090565b60008060006111af856000015186602001518760400151611346565b6040805160608101825293845260208401929092529082015295945050505050565b6111f560405180606001604052806000815260200160008152602001600081525090565b6000806000611220866000015187602001518860400151886000015189602001518a60400151611424565b604080516060810182529384526020840192909252908201529695505050505050565b60006102f683611254600285611eb6565b8461155c565b6000808080806080815b81156113285782156112955761127b858585611346565b9196509450925061128d858585611346565b919650945092505b50600c60fc89901c1660fe88901c17801561130b576113038585858d85601081106112c2576112c2611b6a565b6020020151518e86601081106112da576112da611b6a565b6020020151602001518f87601081106112f5576112f5611b6a565b602002015160400151611424565b919650945092505b600298891b989790971b968161132081611ec9565b925050611264565b6113338585856115b0565b909750955050505050505b935093915050565b6000806000846000036113615750600091508190508061141b565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff8085860981828283097fffffffff00000001000000000000000000000000fffffffffffffffffffffffc099050818788098283828b0960040983848384096008099150838385868d8e09600309089250838160020984848509818110156113e65785015b039650868110156113f45783015b8387820384099550508085101561140a57938201935b909303925080808688096002099150505b93509350939050565b60008060008660000361143e575084915083905082611550565b83600003611453575087915086905085611550565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff808889098186870982818d0983838b0984858a85098e0985868e87098c09868b8f08848410156114a357928701925b8484039350878460020988818209905088818609848410156114c457928901925b898585036002099350898485099c50898288099650898a8860020982089150818d10156114f0579b89019b5b818d039c5089818b87600209099450508b86101561150d57948801945b888c870384099a50838b101561152257998801995b838b039a508887890897508882830990508781101561153e5788015b88858983030999505050505050505050505b96509650969350505050565b60008184111561156c5781840693505b60405160208152602080820152602060408201528460608201528360808201528260a082015260208160c08360056136b0fa8080156100a357505051949350505050565b600080826000036115c65750600090508061133e565b60006115f2847fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611243565b905060007fffffffff00000001000000000000000000000000ffffffffffffffffffffffff82830990507fffffffff00000001000000000000000000000000ffffffffffffffffffffffff81880993507fffffffff00000001000000000000000000000000ffffffffffffffffffffffff80838309870992505050935093915050565b82600281019282156116a8579160200282015b828111156116a8578251829060ff16905591602001919060010190611688565b506116b492915061174e565b5090565b60405180604001604052806002906020820280368337509192915050565b82600281019282156116a8579160200282015b828111156116a85782518255916020019190600101906116e9565b6040518061020001604052806010905b61173860405180606001604052806000815260200160008152602001600081525090565b8152602001906001900390816117145790505090565b5b808211156116b4576000815560010161174f565b6000610160828403121561177657600080fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156117ce576117ce61177c565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561181b5761181b61177c565b604052919050565b60008060006080848603121561183857600080fd5b833567ffffffffffffffff81111561184f57600080fd5b61185b86828701611763565b935050602080850135925085605f86011261187557600080fd5b61187d6117ab565b80608087018881111561188f57600080fd5b604088015b818110156118ab5780358452928401928401611894565b50508093505050509250925092565b600067ffffffffffffffff8211156118d4576118d461177c565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261191157600080fd5b813561192461191f826118ba565b6117d4565b81815284602083860101111561193957600080fd5b816020850160208301376000918101602001919091529392505050565b6000806040838503121561196957600080fd5b82359150602083013567ffffffffffffffff81111561198757600080fd5b61199385828601611900565b9150509250929050565b6000602082840312156119af57600080fd5b813567ffffffffffffffff8111156119c657600080fd5b61041784828501611900565b60005b838110156119ed5781810151838201526020016119d5565b50506000910152565b6020815260008251806020840152611a158160408501602087016119d2565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b60008060408385031215611a5a57600080fd5b823567ffffffffffffffff811115611a7157600080fd5b611a7d85828601611763565b95602094909401359450505050565b60008060208385031215611a9f57600080fd5b823567ffffffffffffffff80821115611ab757600080fd5b818501915085601f830112611acb57600080fd5b813581811115611ada57600080fd5b866020828501011115611aec57600080fd5b60209290920196919550909350505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112611b3357600080fd5b83018035915067ffffffffffffffff821115611b4e57600080fd5b602001915036819003821315611b6357600080fd5b9250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008183825b6002811015611bbe578154835260209092019160019182019101611b9f565b50505060408201905092915050565b60008085851115611bdd57600080fd5b83861115611bea57600080fd5b5050820193919092039150565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b6000611c5261191f846118ba565b9050828152838383011115611c6657600080fd5b6102f68360208301846119d2565b600082601f830112611c8557600080fd5b6102f683835160208501611c44565b600080600080600060a08688031215611cac57600080fd5b8551945060208601519350604086015167ffffffffffffffff80821115611cd257600080fd5b818801915088601f830112611ce657600080fd5b611cf589835160208501611c44565b94506060880151915080821115611d0b57600080fd5b611d1789838a01611c74565b93506080880151915080821115611d2d57600080fd5b50611d3a88828901611c74565b9150509295509295909350565b60008451611d598184602089016119d2565b845190830190611d6d8183602089016119d2565b8451910190611d808183602088016119d2565b0195945050505050565b60008251611d9c8184602087016119d2565b9190910192915050565b600060208284031215611db857600080fd5b5051919050565b60008351611dd18184602088016119d2565b9190910191825250602001919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808202811582820484141761036957610369611de1565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082611e6557611e65611e27565b500490565b600082611e7957611e79611e27565b500690565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611eaf57611eaf611de1565b5060010190565b8181038181111561036957610369611de1565b600081611ed857611ed8611de1565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392d5fa2646970667358221220d4142da7b16effb6b95f41adeff2bc8ce0d59d3b70ca8d55e6e83224bbfbec0a64736f6c63430008150033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100a35760003560e01c80637104ddb2116100765780638dd501211161005b5780638dd50121146101bc578063cd00e50a146101cf578063cd9b47e4146101d757600080fd5b80637104ddb21461015b5780638da5cb5b146101a757600080fd5b806311cfe388146100a85780631626ba7e146100ce5780633253960f14610112578063392dd6d914610138575b600080fd5b6100bb6100b6366004611823565b6101ea565b6040519081526020015b60405180910390f35b6100e16100dc366004611956565b610252565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020016100c5565b7f8dd50121000000000000000000000000000000000000000000000000000000006100e1565b61014b61014636600461199d565b6102fd565b60405190151581526020016100c5565b6101827f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100c5565b6101af61036f565b6040516100c591906119f6565b6100bb6101ca366004611a47565b6103ba565b6100bb61041f565b6100bb6101e5366004611a8c565b61053a565b600061023982846101ff610140880188611afe565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061083692505050565b610244576001610247565b60005b60ff16949350505050565b60006102aa7f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b1653646040805180820191829052919060029082845b81548152602001906001019080831161028b5750505050508484610836565b6102d4577fffffffff000000000000000000000000000000000000000000000000000000006102f6565b7f1626ba7e000000000000000000000000000000000000000000000000000000005b9392505050565b60008151604114801561036957508160008151811061031e5761031e611b6a565b6020910101517fff00000000000000000000000000000000000000000000000000000000000000167f0400000000000000000000000000000000000000000000000000000000000000145b92915050565b6040516060907f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364906103a5908290602001611b99565b60405160208183030381529060405291505090565b60408051808201918290526000917f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364916104179186918691859060029082845b8154815260200190600101908083116103fa5750505050506101ea565b949350505050565b60006104296109b4565b6104316109f4565b60408051808201909152600080825260208201527f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364906104749082906002611675565b506000610488600154610100900460e01b90565b7fffffffff0000000000000000000000000000000000000000000000000000000016036104e1576040517f127c609a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff169055604051600192507fcccd30db6bc000b8bb8d11162228d2d69e3c361983ca3ae8c1365ce64b0fae9e90600090a15090565b6000610544610a93565b61058383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102fd92505050565b6105b9576040517f6c334d2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006105c88360018187611bcd565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092935061060992506116b8915050565b602082015181526040820151602082015260006106437f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b16536490565b9050610651818360026116d6565b507f8dd50121000000000000000000000000000000000000000000000000000000006000610686600154610100900460e01b90565b7fffffffff0000000000000000000000000000000000000000000000000000000016146106df576040517f5f95a63c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16610770827fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604090205460601c90565b73ffffffffffffffffffffffffffffffffffffffff16146107bd576040517fbb4752b700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff1661010060e084901c02179055600194507f6d54821a69ec281ed7ba1bf2729c700768c47df1d80fad646b0a14cc1d5c39ed8787604051610824929190611bf7565b60405180910390a15050505092915050565b600080600080600080868060200190518101906108539190611c94565b9450945094509450945060008061088a8a60405160200161087691815260200190565b604051602081830303815290604052610b33565b905060008482856040516020016108a393929190611d47565b60405160208183030381529060405290506002816040516108c49190611d8a565b602060405180830381855afa1580156108e1573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906109049190611da6565b9250505060006002858360405160200161091f929190611dbf565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905261095791611d8a565b602060405180830381855afa158015610974573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906109979190611da6565b90506109a58b888884610c6f565b9b9a5050505050505050505050565b6001805460ff16146109f2576040517f38fc28cb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff16600114610a5c576040517fe00d7c7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff1615610af9576040517f7c2cde8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b60608151600003610b5257505060408051602081019091526000815290565b6000604051806060016040528060408152602001611eff6040913990506000600684516008610b819190611e10565b610b8b9190611e56565b9050600060068551610b9d9190611e6a565b1115610bb15780610bad81611e7e565b9150505b60008167ffffffffffffffff811115610bcc57610bcc61177c565b6040519080825280601f01601f191660200182016040528015610bf6576020820181803683370190505b509050600183016020820186875188015b80821015610c62576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f8116850151845350600183019250610c07565b5092979650505050505050565b6000610c9c60017fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611eb6565b85511180610cd75750610cd060017fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611eb6565b6020860151115b15610ce457506000610417565b831580610cef575082155b80610d1a57507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518410155b80610d4557507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518310155b15610d5257506000610417565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff7f5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff8088600060200201517fffffffff00000001000000000000000000000000fffffffffffffffffffffffc0988517fffffffff00000001000000000000000000000000ffffffffffffffffffffffff90819080098a5109080860208601517fffffffff00000001000000000000000000000000ffffffffffffffffffffffff90800914610e4357506000610417565b6000610e4e86610e66565b9050610e5c81868686611062565b9695505050505050565b610e6e611704565b60405180606001604052806000815260200160008152602001600081525081600060108110610e9f57610e9f611b6a565b60200201526040805160608101909152808360006020020151815260200183600160028110610ed057610ed0611b6a565b60200201518152602001600181525081600160108110610ef257610ef2611b6a565b6020020152610f088160015b602002015161116f565b6040820152610f278160015b60200201518260025b60200201516111d1565b6060828101919091526040805191820181527f6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c29682527f4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f560208301526001908201526080820152610fa18160045b6020020151826001610f1d565b60a0820152610fb1816004610f14565b60c0820152610fca8160045b6020020151826003610f1d565b60e0820152610fda816004610efe565b610100820152610feb816008610f94565b610120820152610ffc816008610f14565b61014082015261100d816008610fbd565b610160820152608081015161102490826008610f1d565b61018082015261103581600c610f94565b6101a082015261104681600c610f14565b6101c082015261105781600c610fbd565b6101e0820152919050565b600083158061106f575082155b8061109a57507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518410155b806110c557507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518310155b156110d257506000610417565b60006110fe847fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551611243565b905060007fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551828509905060007fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551838809905060008061115e8a858561125a565b509098149998505050505050505050565b61119360405180606001604052806000815260200160008152602001600081525090565b60008060006111af856000015186602001518760400151611346565b6040805160608101825293845260208401929092529082015295945050505050565b6111f560405180606001604052806000815260200160008152602001600081525090565b6000806000611220866000015187602001518860400151886000015189602001518a60400151611424565b604080516060810182529384526020840192909252908201529695505050505050565b60006102f683611254600285611eb6565b8461155c565b6000808080806080815b81156113285782156112955761127b858585611346565b9196509450925061128d858585611346565b919650945092505b50600c60fc89901c1660fe88901c17801561130b576113038585858d85601081106112c2576112c2611b6a565b6020020151518e86601081106112da576112da611b6a565b6020020151602001518f87601081106112f5576112f5611b6a565b602002015160400151611424565b919650945092505b600298891b989790971b968161132081611ec9565b925050611264565b6113338585856115b0565b909750955050505050505b935093915050565b6000806000846000036113615750600091508190508061141b565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff8085860981828283097fffffffff00000001000000000000000000000000fffffffffffffffffffffffc099050818788098283828b0960040983848384096008099150838385868d8e09600309089250838160020984848509818110156113e65785015b039650868110156113f45783015b8387820384099550508085101561140a57938201935b909303925080808688096002099150505b93509350939050565b60008060008660000361143e575084915083905082611550565b83600003611453575087915086905085611550565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff808889098186870982818d0983838b0984858a85098e0985868e87098c09868b8f08848410156114a357928701925b8484039350878460020988818209905088818609848410156114c457928901925b898585036002099350898485099c50898288099650898a8860020982089150818d10156114f0579b89019b5b818d039c5089818b87600209099450508b86101561150d57948801945b888c870384099a50838b101561152257998801995b838b039a508887890897508882830990508781101561153e5788015b88858983030999505050505050505050505b96509650969350505050565b60008184111561156c5781840693505b60405160208152602080820152602060408201528460608201528360808201528260a082015260208160c08360056136b0fa8080156100a357505051949350505050565b600080826000036115c65750600090508061133e565b60006115f2847fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611243565b905060007fffffffff00000001000000000000000000000000ffffffffffffffffffffffff82830990507fffffffff00000001000000000000000000000000ffffffffffffffffffffffff81880993507fffffffff00000001000000000000000000000000ffffffffffffffffffffffff80838309870992505050935093915050565b82600281019282156116a8579160200282015b828111156116a8578251829060ff16905591602001919060010190611688565b506116b492915061174e565b5090565b60405180604001604052806002906020820280368337509192915050565b82600281019282156116a8579160200282015b828111156116a85782518255916020019190600101906116e9565b6040518061020001604052806010905b61173860405180606001604052806000815260200160008152602001600081525090565b8152602001906001900390816117145790505090565b5b808211156116b4576000815560010161174f565b6000610160828403121561177657600080fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156117ce576117ce61177c565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561181b5761181b61177c565b604052919050565b60008060006080848603121561183857600080fd5b833567ffffffffffffffff81111561184f57600080fd5b61185b86828701611763565b935050602080850135925085605f86011261187557600080fd5b61187d6117ab565b80608087018881111561188f57600080fd5b604088015b818110156118ab5780358452928401928401611894565b50508093505050509250925092565b600067ffffffffffffffff8211156118d4576118d461177c565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261191157600080fd5b813561192461191f826118ba565b6117d4565b81815284602083860101111561193957600080fd5b816020850160208301376000918101602001919091529392505050565b6000806040838503121561196957600080fd5b82359150602083013567ffffffffffffffff81111561198757600080fd5b61199385828601611900565b9150509250929050565b6000602082840312156119af57600080fd5b813567ffffffffffffffff8111156119c657600080fd5b61041784828501611900565b60005b838110156119ed5781810151838201526020016119d5565b50506000910152565b6020815260008251806020840152611a158160408501602087016119d2565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b60008060408385031215611a5a57600080fd5b823567ffffffffffffffff811115611a7157600080fd5b611a7d85828601611763565b95602094909401359450505050565b60008060208385031215611a9f57600080fd5b823567ffffffffffffffff80821115611ab757600080fd5b818501915085601f830112611acb57600080fd5b813581811115611ada57600080fd5b866020828501011115611aec57600080fd5b60209290920196919550909350505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112611b3357600080fd5b83018035915067ffffffffffffffff821115611b4e57600080fd5b602001915036819003821315611b6357600080fd5b9250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008183825b6002811015611bbe578154835260209092019160019182019101611b9f565b50505060408201905092915050565b60008085851115611bdd57600080fd5b83861115611bea57600080fd5b5050820193919092039150565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b6000611c5261191f846118ba565b9050828152838383011115611c6657600080fd5b6102f68360208301846119d2565b600082601f830112611c8557600080fd5b6102f683835160208501611c44565b600080600080600060a08688031215611cac57600080fd5b8551945060208601519350604086015167ffffffffffffffff80821115611cd257600080fd5b818801915088601f830112611ce657600080fd5b611cf589835160208501611c44565b94506060880151915080821115611d0b57600080fd5b611d1789838a01611c74565b93506080880151915080821115611d2d57600080fd5b50611d3a88828901611c74565b9150509295509295909350565b60008451611d598184602089016119d2565b845190830190611d6d8183602089016119d2565b8451910190611d808183602088016119d2565b0195945050505050565b60008251611d9c8184602087016119d2565b9190910192915050565b600060208284031215611db857600080fd5b5051919050565b60008351611dd18184602088016119d2565b9190910191825250602001919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808202811582820484141761036957610369611de1565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082611e6557611e65611e27565b500490565b600082611e7957611e79611e27565b500690565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611eaf57611eaf611de1565b5060010190565b8181038181111561036957610369611de1565b600081611ed857611ed8611de1565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392d5fa2646970667358221220d4142da7b16effb6b95f41adeff2bc8ce0d59d3b70ca8d55e6e83224bbfbec0a64736f6c63430008150033", + "devdoc": { + "author": "Ruslan Serebriakov (@rsrbk)David Yongjun Kim (@Powerstream3604)", + "details": "Primarily used to verify user ops signed with passkeys", + "kind": "dev", + "methods": { + "initializeSigner(bytes)": { + "details": "This method checks if the signer has already been initialized. If already initialized, it reverts. It checks if the public key is in the light format and initializes signer storage in k1 storage.", + "params": { + "_publicKey": "Bytes of owner public key" + }, + "returns": { + "initSuccess": "Uint value representing the success of init operation" + } + }, + "isValidKeyType(bytes)": { + "details": "For this Secp256k1Verification Facet, the public key should in an uncompressed public key format", + "params": { + "_publicKey": "Bytes of public key for format check" + }, + "returns": { + "isValid": "Boolean variable representing if the format of public key is valid" + } + }, + "isValidSignature(bytes32,bytes)": { + "details": "This method verifies the signature if the owner indeed signed the hash. Returns magic value if true", + "params": { + "_hash": "Hash value the owner signed", + "_signature": "Signature that signed the above hash" + }, + "returns": { + "magicValue": "Bytes4 value representing the success/failure of validation" + } + }, + "owner()": { + "returns": { + "signer": "Bytes of owner address" + } + }, + "uninitializeSigner()": { + "details": "This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.", + "returns": { + "uninitSuccess": "Uint value representing the success of uninit operation" + } + }, + "validateOwnerSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32)": { + "details": "This method validates if the user operation is signed by the owner. It internally calls validateSignature with signer public key.", + "params": { + "userOp": "UserOperation including all information for execution", + "userOpHash": "Hash of UserOperation given from EntryPoint. This hash is used for signature validation" + }, + "returns": { + "validationData": "Uint value representing whether the validation is successful. 0 for success, 1 for failure" + } + }, + "validateOwnerSignatureSelector()": { + "returns": { + "ownerSignatureValidatorSelector": "Bytes4 selector of function signature to validate account owner's UserOperation signature" + } + }, + "validateSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256[2])": { + "details": "This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address", + "params": { + "q": "Public Key of signer who signed the contract, to be validated", + "userOp": "UserOperation including all information for execution", + "userOpHash": "Hash of UserOperation given from EntryPoint. This hash is used for signature validation" + }, + "returns": { + "isValid": "Uint value representing whether the validation is successful. 0 for success, 1 for failure" + } + } + }, + "title": "Secp256r1 verification facet", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "constructor": { + "notice": "This constructor ensures that this contract can only be used as singleton for Proxy contracts" + }, + "initializeSigner(bytes)": { + "notice": "Initializes the signer in R1 Facet Storage. This can only be called when the account is uninitialized or during signature migration." + }, + "isValidKeyType(bytes)": { + "notice": "Validates if the format of public key is valid for this verification facet" + }, + "isValidSignature(bytes32,bytes)": { + "notice": "Validates if the signature is valid. Function to be compatible with EIP-1271" + }, + "owner()": { + "notice": "Returns the owner of the account" + }, + "uninitializeSigner()": { + "notice": "Uninitialize signer in R1 Facet Storage. This can only be called when the account is undergoing signature migration and has already been initialized." + }, + "validateOwnerSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32)": { + "notice": "Validates if the user operation is signed by the owner." + }, + "validateOwnerSignatureSelector()": { + "notice": "Returns the selector of function to validate the signature of UserOperation" + }, + "validateSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256[2])": { + "notice": "Validates if the signature of UserOperation is signed by the given signer" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/base/TokenReceiverFacet.json b/deployments/base/TokenReceiverFacet.json new file mode 100644 index 0000000..a756dfb --- /dev/null +++ b/deployments/base/TokenReceiverFacet.json @@ -0,0 +1,239 @@ +{ + "address": "0x3143E1C0Af0Cdc153423863923Cf4e3818e34Daa", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onERC1155BatchReceived", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onERC1155Received", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onERC721Received", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onTokenTransfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "tokensReceived", + "outputs": [], + "stateMutability": "pure", + "type": "function" + } + ], + "transactionHash": "0xdca03b7f813ed155b0ecde747d7d8e2f0565307cf1cefa54b74fee230f813b31", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 1, + "gasUsed": "329340", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x0c1845a6c33545c7fdb21ecccb2b152ccc82c18d727383b8ab4c247a61f7d342", + "transactionHash": "0xdca03b7f813ed155b0ecde747d7d8e2f0565307cf1cefa54b74fee230f813b31", + "logs": [], + "blockNumber": 5838116, + "cumulativeGasUsed": "376253", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "0c861e53801b64e5ccc05669ea62a977", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onERC1155BatchReceived\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onERC1155Received\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onERC721Received\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"tokensReceived\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"Contract that enables receiving ERC721/ERC1155/ERC777/ERC677 Tokens with safe transfer\",\"kind\":\"dev\",\"methods\":{},\"title\":\"TokenReceiver Facet\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\":{\"notice\":\"Handles ERC1155 Token batch callback. return Standardized onERC1155BatchReceived return value.\"},\"onERC1155Received(address,address,uint256,uint256,bytes)\":{\"notice\":\"Handles ERC1155 Token callback. return Standardized onERC1155Received return value.\"},\"onERC721Received(address,address,uint256,bytes)\":{\"notice\":\"Handles ERC721 Token callback. return Standardized onERC721Received return value.\"},\"onTokenTransfer(address,uint256,bytes)\":{\"notice\":\"Handles ERC677 Token callback. return true.\"},\"tokensReceived(address,address,address,uint256,bytes,bytes)\":{\"notice\":\"Handles ERC777 Token callback. Does not return value, empty implementation.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/TokenReceiverFacet.sol\":\"TokenReceiverFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title ERC721 token receiver interface\\n * @dev Interface for any contract that wants to support safeTransfers\\n * from ERC721 asset contracts.\\n */\\ninterface IERC721Receiver {\\n /**\\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\\n * by `operator` from `from`, this function is called.\\n *\\n * It must return its Solidity selector to confirm the token transfer.\\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\\n *\\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\\n */\\n function onERC721Received(\\n address operator,\\n address from,\\n uint256 tokenId,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\\n *\\n * Accounts can be notified of {IERC777} tokens being sent to them by having a\\n * contract implement this interface (contract holders can be their own\\n * implementer) and registering it on the\\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\\n *\\n * See {IERC1820Registry} and {ERC1820Implementer}.\\n */\\ninterface IERC777Recipient {\\n /**\\n * @dev Called by an {IERC777} token contract whenever tokens are being\\n * moved or created into a registered account (`to`). The type of operation\\n * is conveyed by `from` being the zero address or not.\\n *\\n * This call occurs _after_ the token contract's state is updated, so\\n * {IERC777-balanceOf}, etc., can be used to query the post-operation state.\\n *\\n * This function may revert to prevent the operation from being executed.\\n */\\n function tokensReceived(\\n address operator,\\n address from,\\n address to,\\n uint256 amount,\\n bytes calldata userData,\\n bytes calldata operatorData\\n ) external;\\n}\\n\",\"keccak256\":\"0x1a5d61db2733202ba361e6d6741cd2e662380e22b80e987eacfc91973f2267dc\",\"license\":\"MIT\"},\"contracts/facets/TokenReceiverFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IERC721Receiver} from \\\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\\\";\\nimport {IERC777Recipient} from \\\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\\\";\\nimport {IERC1155Receiver} from \\\"../interfaces/ERC/IERC1155Receiver.sol\\\";\\nimport {IERC677Receiver} from \\\"../interfaces/ERC/IERC677Receiver.sol\\\";\\n\\n/**\\n * @title TokenReceiver Facet\\n * @dev Contract that enables receiving ERC721/ERC1155/ERC777/ERC677 Tokens with safe transfer\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract TokenReceiverFacet is\\n IERC721Receiver,\\n IERC1155Receiver,\\n IERC777Recipient,\\n IERC677Receiver\\n{\\n /**\\n * @notice Handles ERC721 Token callback.\\n * return Standardized onERC721Received return value.\\n */\\n function onERC721Received(\\n address,\\n address,\\n uint256,\\n bytes calldata\\n ) external pure override returns (bytes4) {\\n return IERC721Receiver.onERC721Received.selector;\\n }\\n\\n /**\\n * @notice Handles ERC1155 Token callback.\\n * return Standardized onERC1155Received return value.\\n */\\n function onERC1155Received(\\n address,\\n address,\\n uint256,\\n uint256,\\n bytes calldata\\n ) external pure override returns (bytes4) {\\n return IERC1155Receiver.onERC1155Received.selector;\\n }\\n\\n /**\\n * @notice Handles ERC1155 Token batch callback.\\n * return Standardized onERC1155BatchReceived return value.\\n */\\n function onERC1155BatchReceived(\\n address,\\n address,\\n uint256[] calldata,\\n uint256[] calldata,\\n bytes calldata\\n ) external pure override returns (bytes4) {\\n return IERC1155Receiver.onERC1155BatchReceived.selector;\\n }\\n\\n /**\\n * @notice Handles ERC777 Token callback.\\n * Does not return value, empty implementation.\\n */\\n function tokensReceived(\\n address,\\n address,\\n address,\\n uint256,\\n bytes calldata,\\n bytes calldata\\n ) external pure override {}\\n\\n /**\\n * @notice Handles ERC677 Token callback.\\n * return true.\\n */\\n function onTokenTransfer(\\n address,\\n uint256,\\n bytes calldata\\n ) external pure override returns (bool) {\\n return true;\\n }\\n}\\n\",\"keccak256\":\"0xdfe483d05ef4056bb464c34ade19ab527687aff3ed0b6303b447a68b5ff7abb4\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC1155Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\n\\npragma solidity 0.8.21;\\n\\n/**\\n * @dev _Available since v3.1._\\n */\\ninterface IERC1155Receiver {\\n /**\\n * @dev Handles the receipt of a single ERC1155 token type. This function is\\n * called at the end of a `safeTransferFrom` after the balance has been updated.\\n *\\n * NOTE: To accept the transfer, this must return\\n * `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))`\\n * (i.e. 0xf23a6e61, or its own function selector).\\n *\\n * @param operator The address which initiated the transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param id The ID of the token being transferred\\n * @param value The amount of tokens being transferred\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155Received(\\n address operator,\\n address from,\\n uint256 id,\\n uint256 value,\\n bytes calldata data\\n ) external returns (bytes4);\\n\\n /**\\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\\n * is called at the end of a `safeBatchTransferFrom` after the balances have\\n * been updated.\\n *\\n * NOTE: To accept the transfer(s), this must return\\n * `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))`\\n * (i.e. 0xbc197c81, or its own function selector).\\n *\\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155BatchReceived(\\n address operator,\\n address from,\\n uint256[] calldata ids,\\n uint256[] calldata values,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0x3729c6757bae3aba03ac1c5064d67ad13b94e2a9428bf44b9be510373406da0c\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC677Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC677Receiver {\\n function onTokenTransfer(\\n address sender,\\n uint value,\\n bytes calldata data\\n ) external pure returns (bool);\\n}\\n\",\"keccak256\":\"0x4c1631cf45ea6daac0ec158c3edb9453099130b6b64f697004b83f95aa1f7350\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50610502806100206000396000f3fe608060405234801561001057600080fd5b50600436106100665760003560e01c8063a4c0ed3611610050578063a4c0ed36146100f3578063bc197c811461011b578063f23a6e611461015657600080fd5b806223de291461006b578063150b7a0214610085575b600080fd5b610083610079366004610201565b5050505050505050565b005b6100bd6100933660046102ac565b7f150b7a020000000000000000000000000000000000000000000000000000000095945050505050565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020015b60405180910390f35b61010b61010136600461031b565b6001949350505050565b60405190151581526020016100ea565b6100bd6101293660046103ba565b7fbc197c810000000000000000000000000000000000000000000000000000000098975050505050505050565b6100bd610164366004610454565b7ff23a6e61000000000000000000000000000000000000000000000000000000009695505050505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146101b357600080fd5b919050565b60008083601f8401126101ca57600080fd5b50813567ffffffffffffffff8111156101e257600080fd5b6020830191508360208285010111156101fa57600080fd5b9250929050565b60008060008060008060008060c0898b03121561021d57600080fd5b6102268961018f565b975061023460208a0161018f565b965061024260408a0161018f565b955060608901359450608089013567ffffffffffffffff8082111561026657600080fd5b6102728c838d016101b8565b909650945060a08b013591508082111561028b57600080fd5b506102988b828c016101b8565b999c989b5096995094979396929594505050565b6000806000806000608086880312156102c457600080fd5b6102cd8661018f565b94506102db6020870161018f565b935060408601359250606086013567ffffffffffffffff8111156102fe57600080fd5b61030a888289016101b8565b969995985093965092949392505050565b6000806000806060858703121561033157600080fd5b61033a8561018f565b935060208501359250604085013567ffffffffffffffff81111561035d57600080fd5b610369878288016101b8565b95989497509550505050565b60008083601f84011261038757600080fd5b50813567ffffffffffffffff81111561039f57600080fd5b6020830191508360208260051b85010111156101fa57600080fd5b60008060008060008060008060a0898b0312156103d657600080fd5b6103df8961018f565b97506103ed60208a0161018f565b9650604089013567ffffffffffffffff8082111561040a57600080fd5b6104168c838d01610375565b909850965060608b013591508082111561042f57600080fd5b61043b8c838d01610375565b909650945060808b013591508082111561028b57600080fd5b60008060008060008060a0878903121561046d57600080fd5b6104768761018f565b95506104846020880161018f565b94506040870135935060608701359250608087013567ffffffffffffffff8111156104ae57600080fd5b6104ba89828a016101b8565b979a969950949750929593949250505056fea2646970667358221220ae9a97061ae9e1485161ca9c8d3228a23e47b18755fa935f51b40e927816ca2964736f6c63430008150033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100665760003560e01c8063a4c0ed3611610050578063a4c0ed36146100f3578063bc197c811461011b578063f23a6e611461015657600080fd5b806223de291461006b578063150b7a0214610085575b600080fd5b610083610079366004610201565b5050505050505050565b005b6100bd6100933660046102ac565b7f150b7a020000000000000000000000000000000000000000000000000000000095945050505050565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020015b60405180910390f35b61010b61010136600461031b565b6001949350505050565b60405190151581526020016100ea565b6100bd6101293660046103ba565b7fbc197c810000000000000000000000000000000000000000000000000000000098975050505050505050565b6100bd610164366004610454565b7ff23a6e61000000000000000000000000000000000000000000000000000000009695505050505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146101b357600080fd5b919050565b60008083601f8401126101ca57600080fd5b50813567ffffffffffffffff8111156101e257600080fd5b6020830191508360208285010111156101fa57600080fd5b9250929050565b60008060008060008060008060c0898b03121561021d57600080fd5b6102268961018f565b975061023460208a0161018f565b965061024260408a0161018f565b955060608901359450608089013567ffffffffffffffff8082111561026657600080fd5b6102728c838d016101b8565b909650945060a08b013591508082111561028b57600080fd5b506102988b828c016101b8565b999c989b5096995094979396929594505050565b6000806000806000608086880312156102c457600080fd5b6102cd8661018f565b94506102db6020870161018f565b935060408601359250606086013567ffffffffffffffff8111156102fe57600080fd5b61030a888289016101b8565b969995985093965092949392505050565b6000806000806060858703121561033157600080fd5b61033a8561018f565b935060208501359250604085013567ffffffffffffffff81111561035d57600080fd5b610369878288016101b8565b95989497509550505050565b60008083601f84011261038757600080fd5b50813567ffffffffffffffff81111561039f57600080fd5b6020830191508360208260051b85010111156101fa57600080fd5b60008060008060008060008060a0898b0312156103d657600080fd5b6103df8961018f565b97506103ed60208a0161018f565b9650604089013567ffffffffffffffff8082111561040a57600080fd5b6104168c838d01610375565b909850965060608b013591508082111561042f57600080fd5b61043b8c838d01610375565b909650945060808b013591508082111561028b57600080fd5b60008060008060008060a0878903121561046d57600080fd5b6104768761018f565b95506104846020880161018f565b94506040870135935060608701359250608087013567ffffffffffffffff8111156104ae57600080fd5b6104ba89828a016101b8565b979a969950949750929593949250505056fea2646970667358221220ae9a97061ae9e1485161ca9c8d3228a23e47b18755fa935f51b40e927816ca2964736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "Contract that enables receiving ERC721/ERC1155/ERC777/ERC677 Tokens with safe transfer", + "kind": "dev", + "methods": {}, + "title": "TokenReceiver Facet", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)": { + "notice": "Handles ERC1155 Token batch callback. return Standardized onERC1155BatchReceived return value." + }, + "onERC1155Received(address,address,uint256,uint256,bytes)": { + "notice": "Handles ERC1155 Token callback. return Standardized onERC1155Received return value." + }, + "onERC721Received(address,address,uint256,bytes)": { + "notice": "Handles ERC721 Token callback. return Standardized onERC721Received return value." + }, + "onTokenTransfer(address,uint256,bytes)": { + "notice": "Handles ERC677 Token callback. return true." + }, + "tokensReceived(address,address,address,uint256,bytes,bytes)": { + "notice": "Handles ERC777 Token callback. Does not return value, empty implementation." + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/base/solcInputs/0c861e53801b64e5ccc05669ea62a977.json b/deployments/base/solcInputs/0c861e53801b64e5ccc05669ea62a977.json new file mode 100644 index 0000000..47e9456 --- /dev/null +++ b/deployments/base/solcInputs/0c861e53801b64e5ccc05669ea62a977.json @@ -0,0 +1,354 @@ +{ + "language": "Solidity", + "sources": { + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby disabling any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable2Step.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./Ownable.sol\";\n\n/**\n * @dev Contract module which provides access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership} and {acceptOwnership}.\n *\n * This module is used through inheritance. It will make available all functions\n * from parent (Ownable).\n */\nabstract contract Ownable2Step is Ownable {\n address private _pendingOwner;\n\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Returns the address of the pending owner.\n */\n function pendingOwner() public view virtual returns (address) {\n return _pendingOwner;\n }\n\n /**\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual override onlyOwner {\n _pendingOwner = newOwner;\n emit OwnershipTransferStarted(owner(), newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual override {\n delete _pendingOwner;\n super._transferOwnership(newOwner);\n }\n\n /**\n * @dev The new owner accepts the ownership transfer.\n */\n function acceptOwnership() public virtual {\n address sender = _msgSender();\n require(pendingOwner() == sender, \"Ownable2Step: caller is not the new owner\");\n _transferOwnership(sender);\n }\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC1271.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC1271 standard signature validation method for\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\n *\n * _Available since v4.1._\n */\ninterface IERC1271 {\n /**\n * @dev Should return whether the signature provided is valid for the provided data\n * @param hash Hash of the data to be signed\n * @param signature Signature byte array associated with _data\n */\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\n}\n" + }, + "@openzeppelin/contracts/security/ReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor() {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n _nonReentrantBefore();\n _;\n _nonReentrantAfter();\n }\n\n function _nonReentrantBefore() private {\n // On the first call to nonReentrant, _status will be _NOT_ENTERED\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n }\n\n function _nonReentrantAfter() private {\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Returns true if the reentrancy guard is currently set to \"entered\", which indicates there is a\n * `nonReentrant` function in the call stack.\n */\n function _reentrancyGuardEntered() internal view returns (bool) {\n return _status == _ENTERED;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/ERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/ERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC1155.sol\";\nimport \"./IERC1155Receiver.sol\";\nimport \"./extensions/IERC1155MetadataURI.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of the basic standard multi-token.\n * See https://eips.ethereum.org/EIPS/eip-1155\n * Originally based on code by Enjin: https://github.com/enjin/erc-1155\n *\n * _Available since v3.1._\n */\ncontract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {\n using Address for address;\n\n // Mapping from token ID to account balances\n mapping(uint256 => mapping(address => uint256)) private _balances;\n\n // Mapping from account to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json\n string private _uri;\n\n /**\n * @dev See {_setURI}.\n */\n constructor(string memory uri_) {\n _setURI(uri_);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return\n interfaceId == type(IERC1155).interfaceId ||\n interfaceId == type(IERC1155MetadataURI).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC1155MetadataURI-uri}.\n *\n * This implementation returns the same URI for *all* token types. It relies\n * on the token type ID substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * Clients calling this function must replace the `\\{id\\}` substring with the\n * actual token type ID.\n */\n function uri(uint256) public view virtual override returns (string memory) {\n return _uri;\n }\n\n /**\n * @dev See {IERC1155-balanceOf}.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {\n require(account != address(0), \"ERC1155: address zero is not a valid owner\");\n return _balances[id][account];\n }\n\n /**\n * @dev See {IERC1155-balanceOfBatch}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] memory accounts,\n uint256[] memory ids\n ) public view virtual override returns (uint256[] memory) {\n require(accounts.length == ids.length, \"ERC1155: accounts and ids length mismatch\");\n\n uint256[] memory batchBalances = new uint256[](accounts.length);\n\n for (uint256 i = 0; i < accounts.length; ++i) {\n batchBalances[i] = balanceOf(accounts[i], ids[i]);\n }\n\n return batchBalances;\n }\n\n /**\n * @dev See {IERC1155-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC1155-isApprovedForAll}.\n */\n function isApprovedForAll(address account, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[account][operator];\n }\n\n /**\n * @dev See {IERC1155-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n _safeTransferFrom(from, to, id, amount, data);\n }\n\n /**\n * @dev See {IERC1155-safeBatchTransferFrom}.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n _safeBatchTransferFrom(from, to, ids, amounts, data);\n }\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n\n emit TransferSingle(operator, from, to, id, amount);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n for (uint256 i = 0; i < ids.length; ++i) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n }\n\n emit TransferBatch(operator, from, to, ids, amounts);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\n\n _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);\n }\n\n /**\n * @dev Sets a new URI for all token types, by relying on the token type ID\n * substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * By this mechanism, any occurrence of the `\\{id\\}` substring in either the\n * URI or any of the amounts in the JSON file at said URI will be replaced by\n * clients with the token type ID.\n *\n * For example, the `https://token-cdn-domain/\\{id\\}.json` URI would be\n * interpreted by clients as\n * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`\n * for token type ID 0x4cce0.\n *\n * See {uri}.\n *\n * Because these URIs cannot be meaningfully represented by the {URI} event,\n * this function emits no events.\n */\n function _setURI(string memory newuri) internal virtual {\n _uri = newuri;\n }\n\n /**\n * @dev Creates `amount` tokens of token type `id`, and assigns them to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _mint(address to, uint256 id, uint256 amount, bytes memory data) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _balances[id][to] += amount;\n emit TransferSingle(operator, address(0), to, id, amount);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n for (uint256 i = 0; i < ids.length; i++) {\n _balances[ids[i]][to] += amounts[i];\n }\n\n emit TransferBatch(operator, address(0), to, ids, amounts);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);\n }\n\n /**\n * @dev Destroys `amount` tokens of token type `id` from `from`\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `from` must have at least `amount` tokens of token type `id`.\n */\n function _burn(address from, uint256 id, uint256 amount) internal virtual {\n require(from != address(0), \"ERC1155: burn from the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n\n emit TransferSingle(operator, from, address(0), id, amount);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n */\n function _burnBatch(address from, uint256[] memory ids, uint256[] memory amounts) internal virtual {\n require(from != address(0), \"ERC1155: burn from the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n\n for (uint256 i = 0; i < ids.length; i++) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n }\n\n emit TransferBatch(operator, from, address(0), ids, amounts);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {\n require(owner != operator, \"ERC1155: setting approval status for self\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning, as well as batched variants.\n *\n * The same hook is called on both single and batched variants. For single\n * transfers, the length of the `ids` and `amounts` arrays will be 1.\n *\n * Calling conditions (for each `id` and `amount` pair):\n *\n * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * of token type `id` will be transferred to `to`.\n * - When `from` is zero, `amount` tokens of token type `id` will be minted\n * for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n * will be burned.\n * - `from` and `to` are never both zero.\n * - `ids` and `amounts` have the same, non-zero length.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any token transfer. This includes minting\n * and burning, as well as batched variants.\n *\n * The same hook is called on both single and batched variants. For single\n * transfers, the length of the `id` and `amount` arrays will be 1.\n *\n * Calling conditions (for each `id` and `amount` pair):\n *\n * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * of token type `id` will be transferred to `to`.\n * - When `from` is zero, `amount` tokens of token type `id` will be minted\n * for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n * will be burned.\n * - `from` and `to` are never both zero.\n * - `ids` and `amounts` have the same, non-zero length.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {}\n\n function _doSafeTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155Receiver.onERC1155Received.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non-ERC1155Receiver implementer\");\n }\n }\n }\n\n function _doSafeBatchTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (\n bytes4 response\n ) {\n if (response != IERC1155Receiver.onERC1155BatchReceived.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non-ERC1155Receiver implementer\");\n }\n }\n }\n\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {\n uint256[] memory array = new uint256[](1);\n array[0] = element;\n\n return array;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC1155.sol\";\n\n/**\n * @dev Interface of the optional ERC1155MetadataExtension interface, as defined\n * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155MetadataURI is IERC1155 {\n /**\n * @dev Returns the URI for token type `id`.\n *\n * If the `\\{id\\}` substring is present in the URI, it must be replaced by\n * clients with the actual token type ID.\n */\n function uri(uint256 id) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155 is IERC165 {\n /**\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n */\n event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);\n\n /**\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n * transfers.\n */\n event TransferBatch(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\n\n /**\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n * `approved`.\n */\n event ApprovalForAll(address indexed account, address indexed operator, bool approved);\n\n /**\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n *\n * If an {URI} event was emitted for `id`, the standard\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n * returned by {IERC1155MetadataURI-uri}.\n */\n event URI(string value, uint256 indexed id);\n\n /**\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) external view returns (uint256);\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] calldata accounts,\n uint256[] calldata ids\n ) external view returns (uint256[] memory);\n\n /**\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n *\n * Emits an {ApprovalForAll} event.\n *\n * Requirements:\n *\n * - `operator` cannot be the caller.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n *\n * See {setApprovalForAll}.\n */\n function isApprovedForAll(address account, address operator) external view returns (bool);\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155Receiver is IERC165 {\n /**\n * @dev Handles the receipt of a single ERC1155 token type. This function is\n * called at the end of a `safeTransferFrom` after the balance has been updated.\n *\n * NOTE: To accept the transfer, this must return\n * `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n * (i.e. 0xf23a6e61, or its own function selector).\n *\n * @param operator The address which initiated the transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param id The ID of the token being transferred\n * @param value The amount of tokens being transferred\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n ) external returns (bytes4);\n\n /**\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\n * is called at the end of a `safeBatchTransferFrom` after the balances have\n * been updated.\n *\n * NOTE: To accept the transfer(s), this must return\n * `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n * (i.e. 0xbc197c81, or its own function selector).\n *\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the default value returned by this function, unless\n * it's overridden.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(address from, address to, uint256 amount) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\n // decrementing then incrementing.\n _balances[to] += amount;\n }\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n unchecked {\n // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\n _balances[account] += amount;\n }\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n // Overflow not possible: amount <= accountBalance <= totalSupply.\n _totalSupply -= amount;\n }\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\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" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` 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 amount) 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 `amount` as the allowance of `spender` over the 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 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` 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 amount) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/ERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721.sol\";\nimport \"./IERC721Receiver.sol\";\nimport \"./extensions/IERC721Metadata.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/Strings.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\n using Address for address;\n using Strings for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\n\n // Mapping from token ID to approved address\n mapping(uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return\n interfaceId == type(IERC721).interfaceId ||\n interfaceId == type(IERC721Metadata).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _ownerOf(tokenId);\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token owner or approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n _requireMinted(tokenId);\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n _safeTransfer(from, to, tokenId, data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(address from, address to, uint256 tokenId, bytes memory data) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist\n */\n function _ownerOf(uint256 tokenId) internal view virtual returns (address) {\n return _owners[tokenId];\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _ownerOf(tokenId) != address(0);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n address owner = ERC721.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(address to, uint256 tokenId, bytes memory data) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId, 1);\n\n // Check that tokenId was not minted by `_beforeTokenTransfer` hook\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n unchecked {\n // Will not overflow unless all 2**256 token ids are minted to the same owner.\n // Given that tokens are minted one by one, it is impossible in practice that\n // this ever happens. Might change if we allow batch minting.\n // The ERC fails to describe this case.\n _balances[to] += 1;\n }\n\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(address(0), to, tokenId, 1);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n * This is an internal function that does not check if the sender is authorized to operate on the token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId, 1);\n\n // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook\n owner = ERC721.ownerOf(tokenId);\n\n // Clear approvals\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // Cannot overflow, as that would require more tokens to be burned/transferred\n // out than the owner initially received through minting and transferring in.\n _balances[owner] -= 1;\n }\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(owner, address(0), tokenId, 1);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(address from, address to, uint256 tokenId) internal virtual {\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId, 1);\n\n // Check that tokenId was not transferred by `_beforeTokenTransfer` hook\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n\n // Clear approvals from the previous owner\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // `_balances[from]` cannot overflow for the same reason as described in `_burn`:\n // `from`'s balance is the number of token held, which is at least one before the current\n // transfer.\n // `_balances[to]` could overflow in the conditions described in `_mint`. That would require\n // all 2**256 token ids to be minted, which in practice is impossible.\n _balances[from] -= 1;\n _balances[to] += 1;\n }\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId, 1);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721Receiver.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`.\n * - When `from` is zero, the tokens will be minted for `to`.\n * - When `to` is zero, ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}\n\n /**\n * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`.\n * - When `from` is zero, the tokens were minted for `to`.\n * - When `to` is zero, ``from``'s tokens were burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}\n\n /**\n * @dev Unsafe write access to the balances, used by extensions that \"mint\" tokens using an {ownerOf} override.\n *\n * WARNING: Anyone calling this MUST ensure that the balances remain consistent with the ownership. The invariant\n * being that for any address `a` the value returned by `balanceOf(a)` must be equal to the number of tokens such\n * that `ownerOf(tokenId)` is `a`.\n */\n // solhint-disable-next-line func-name-mixedcase\n function __unsafe_increaseBalance(address account, uint256 amount) internal {\n _balances[account] += amount;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721Receiver {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/ERC777.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC777/ERC777.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC777.sol\";\nimport \"./IERC777Recipient.sol\";\nimport \"./IERC777Sender.sol\";\nimport \"../ERC20/IERC20.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/introspection/IERC1820Registry.sol\";\n\n/**\n * @dev Implementation of the {IERC777} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n *\n * Support for ERC20 is included in this contract, as specified by the EIP: both\n * the ERC777 and ERC20 interfaces can be safely used when interacting with it.\n * Both {IERC777-Sent} and {IERC20-Transfer} events are emitted on token\n * movements.\n *\n * Additionally, the {IERC777-granularity} value is hard-coded to `1`, meaning that there\n * are no special restrictions in the amount of tokens that created, moved, or\n * destroyed. This makes integration with ERC20 applications seamless.\n *\n * CAUTION: This file is deprecated as of v4.9 and will be removed in the next major release.\n */\ncontract ERC777 is Context, IERC777, IERC20 {\n using Address for address;\n\n IERC1820Registry internal constant _ERC1820_REGISTRY = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n mapping(address => uint256) private _balances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n bytes32 private constant _TOKENS_SENDER_INTERFACE_HASH = keccak256(\"ERC777TokensSender\");\n bytes32 private constant _TOKENS_RECIPIENT_INTERFACE_HASH = keccak256(\"ERC777TokensRecipient\");\n\n // This isn't ever read from - it's only used to respond to the defaultOperators query.\n address[] private _defaultOperatorsArray;\n\n // Immutable, but accounts may revoke them (tracked in __revokedDefaultOperators).\n mapping(address => bool) private _defaultOperators;\n\n // For each account, a mapping of its operators and revoked default operators.\n mapping(address => mapping(address => bool)) private _operators;\n mapping(address => mapping(address => bool)) private _revokedDefaultOperators;\n\n // ERC20-allowances\n mapping(address => mapping(address => uint256)) private _allowances;\n\n /**\n * @dev `defaultOperators` may be an empty array.\n */\n constructor(string memory name_, string memory symbol_, address[] memory defaultOperators_) {\n _name = name_;\n _symbol = symbol_;\n\n _defaultOperatorsArray = defaultOperators_;\n for (uint256 i = 0; i < defaultOperators_.length; i++) {\n _defaultOperators[defaultOperators_[i]] = true;\n }\n\n // register interfaces\n _ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256(\"ERC777Token\"), address(this));\n _ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256(\"ERC20Token\"), address(this));\n }\n\n /**\n * @dev See {IERC777-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC777-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {ERC20-decimals}.\n *\n * Always returns 18, as per the\n * [ERC777 EIP](https://eips.ethereum.org/EIPS/eip-777#backward-compatibility).\n */\n function decimals() public pure virtual returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC777-granularity}.\n *\n * This implementation always returns `1`.\n */\n function granularity() public view virtual override returns (uint256) {\n return 1;\n }\n\n /**\n * @dev See {IERC777-totalSupply}.\n */\n function totalSupply() public view virtual override(IERC20, IERC777) returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev Returns the amount of tokens owned by an account (`tokenHolder`).\n */\n function balanceOf(address tokenHolder) public view virtual override(IERC20, IERC777) returns (uint256) {\n return _balances[tokenHolder];\n }\n\n /**\n * @dev See {IERC777-send}.\n *\n * Also emits a {IERC20-Transfer} event for ERC20 compatibility.\n */\n function send(address recipient, uint256 amount, bytes memory data) public virtual override {\n _send(_msgSender(), recipient, amount, data, \"\", true);\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Unlike `send`, `recipient` is _not_ required to implement the {IERC777Recipient}\n * interface if it is a contract.\n *\n * Also emits a {Sent} event.\n */\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n _send(_msgSender(), recipient, amount, \"\", \"\", false);\n return true;\n }\n\n /**\n * @dev See {IERC777-burn}.\n *\n * Also emits a {IERC20-Transfer} event for ERC20 compatibility.\n */\n function burn(uint256 amount, bytes memory data) public virtual override {\n _burn(_msgSender(), amount, data, \"\");\n }\n\n /**\n * @dev See {IERC777-isOperatorFor}.\n */\n function isOperatorFor(address operator, address tokenHolder) public view virtual override returns (bool) {\n return\n operator == tokenHolder ||\n (_defaultOperators[operator] && !_revokedDefaultOperators[tokenHolder][operator]) ||\n _operators[tokenHolder][operator];\n }\n\n /**\n * @dev See {IERC777-authorizeOperator}.\n */\n function authorizeOperator(address operator) public virtual override {\n require(_msgSender() != operator, \"ERC777: authorizing self as operator\");\n\n if (_defaultOperators[operator]) {\n delete _revokedDefaultOperators[_msgSender()][operator];\n } else {\n _operators[_msgSender()][operator] = true;\n }\n\n emit AuthorizedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-revokeOperator}.\n */\n function revokeOperator(address operator) public virtual override {\n require(operator != _msgSender(), \"ERC777: revoking self as operator\");\n\n if (_defaultOperators[operator]) {\n _revokedDefaultOperators[_msgSender()][operator] = true;\n } else {\n delete _operators[_msgSender()][operator];\n }\n\n emit RevokedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-defaultOperators}.\n */\n function defaultOperators() public view virtual override returns (address[] memory) {\n return _defaultOperatorsArray;\n }\n\n /**\n * @dev See {IERC777-operatorSend}.\n *\n * Emits {Sent} and {IERC20-Transfer} events.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes memory data,\n bytes memory operatorData\n ) public virtual override {\n require(isOperatorFor(_msgSender(), sender), \"ERC777: caller is not an operator for holder\");\n _send(sender, recipient, amount, data, operatorData, true);\n }\n\n /**\n * @dev See {IERC777-operatorBurn}.\n *\n * Emits {Burned} and {IERC20-Transfer} events.\n */\n function operatorBurn(\n address account,\n uint256 amount,\n bytes memory data,\n bytes memory operatorData\n ) public virtual override {\n require(isOperatorFor(_msgSender(), account), \"ERC777: caller is not an operator for holder\");\n _burn(account, amount, data, operatorData);\n }\n\n /**\n * @dev See {IERC20-allowance}.\n *\n * Note that operator and allowance concepts are orthogonal: operators may\n * not have allowance, and accounts with allowance may not be operators\n * themselves.\n */\n function allowance(address holder, address spender) public view virtual override returns (uint256) {\n return _allowances[holder][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Note that accounts cannot have allowance issued by their operators.\n */\n function approve(address spender, uint256 value) public virtual override returns (bool) {\n address holder = _msgSender();\n _approve(holder, spender, value);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Note that operator and allowance concepts are orthogonal: operators cannot\n * call `transferFrom` (unless they have allowance), and accounts with\n * allowance cannot call `operatorSend` (unless they are operators).\n *\n * Emits {Sent}, {IERC20-Transfer} and {IERC20-Approval} events.\n */\n function transferFrom(address holder, address recipient, uint256 amount) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(holder, spender, amount);\n _send(holder, recipient, amount, \"\", \"\", false);\n return true;\n }\n\n /**\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with the caller address as the `operator` and with\n * `userData` and `operatorData`.\n *\n * See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits {Minted} and {IERC20-Transfer} events.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - if `account` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function _mint(address account, uint256 amount, bytes memory userData, bytes memory operatorData) internal virtual {\n _mint(account, amount, userData, operatorData, true);\n }\n\n /**\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * If `requireReceptionAck` is set to true, and if a send hook is\n * registered for `account`, the corresponding function will be called with\n * `operator`, `data` and `operatorData`.\n *\n * See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits {Minted} and {IERC20-Transfer} events.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - if `account` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function _mint(\n address account,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) internal virtual {\n require(account != address(0), \"ERC777: mint to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), account, amount);\n\n // Update state variables\n _totalSupply += amount;\n _balances[account] += amount;\n\n _callTokensReceived(operator, address(0), account, amount, userData, operatorData, requireReceptionAck);\n\n emit Minted(operator, account, amount, userData, operatorData);\n emit Transfer(address(0), account, amount);\n }\n\n /**\n * @dev Send tokens\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _send(\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) internal virtual {\n require(from != address(0), \"ERC777: transfer from the zero address\");\n require(to != address(0), \"ERC777: transfer to the zero address\");\n\n address operator = _msgSender();\n\n _callTokensToSend(operator, from, to, amount, userData, operatorData);\n\n _move(operator, from, to, amount, userData, operatorData);\n\n _callTokensReceived(operator, from, to, amount, userData, operatorData, requireReceptionAck);\n }\n\n /**\n * @dev Burn tokens\n * @param from address token holder address\n * @param amount uint256 amount of tokens to burn\n * @param data bytes extra information provided by the token holder\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _burn(address from, uint256 amount, bytes memory data, bytes memory operatorData) internal virtual {\n require(from != address(0), \"ERC777: burn from the zero address\");\n\n address operator = _msgSender();\n\n _callTokensToSend(operator, from, address(0), amount, data, operatorData);\n\n _beforeTokenTransfer(operator, from, address(0), amount);\n\n // Update state variables\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC777: burn amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Burned(operator, from, amount, data, operatorData);\n emit Transfer(from, address(0), amount);\n }\n\n function _move(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n ) private {\n _beforeTokenTransfer(operator, from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC777: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Sent(operator, from, to, amount, userData, operatorData);\n emit Transfer(from, to, amount);\n }\n\n /**\n * @dev See {ERC20-_approve}.\n *\n * Note that accounts cannot have allowance issued by their operators.\n */\n function _approve(address holder, address spender, uint256 value) internal virtual {\n require(holder != address(0), \"ERC777: approve from the zero address\");\n require(spender != address(0), \"ERC777: approve to the zero address\");\n\n _allowances[holder][spender] = value;\n emit Approval(holder, spender, value);\n }\n\n /**\n * @dev Call from.tokensToSend() if the interface is registered\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _callTokensToSend(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n ) private {\n address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(from, _TOKENS_SENDER_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Sender(implementer).tokensToSend(operator, from, to, amount, userData, operatorData);\n }\n }\n\n /**\n * @dev Call to.tokensReceived() if the interface is registered. Reverts if the recipient is a contract but\n * tokensReceived() was not registered for the recipient\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _callTokensReceived(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) private {\n address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(to, _TOKENS_RECIPIENT_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Recipient(implementer).tokensReceived(operator, from, to, amount, userData, operatorData);\n } else if (requireReceptionAck) {\n require(!to.isContract(), \"ERC777: token recipient contract has no implementer for ERC777TokensRecipient\");\n }\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {IERC20-Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC777: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes\n * calls to {send}, {transfer}, {operatorSend}, {transferFrom}, minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be to transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address operator, address from, address to, uint256 amount) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC777/IERC777.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777Token standard as defined in the EIP.\n *\n * This contract uses the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 registry standard] to let\n * token holders and recipients react to token movements by using setting implementers\n * for the associated interfaces in said registry. See {IERC1820Registry} and\n * {ERC1820Implementer}.\n */\ninterface IERC777 {\n /**\n * @dev Emitted when `amount` tokens are created by `operator` and assigned to `to`.\n *\n * Note that some additional user `data` and `operatorData` can be logged in the event.\n */\n event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);\n\n /**\n * @dev Emitted when `operator` destroys `amount` tokens from `account`.\n *\n * Note that some additional user `data` and `operatorData` can be logged in the event.\n */\n event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);\n\n /**\n * @dev Emitted when `operator` is made operator for `tokenHolder`.\n */\n event AuthorizedOperator(address indexed operator, address indexed tokenHolder);\n\n /**\n * @dev Emitted when `operator` is revoked its operator status for `tokenHolder`.\n */\n event RevokedOperator(address indexed operator, address indexed tokenHolder);\n\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, usually a shorter version of the\n * name.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the smallest part of the token that is not divisible. This\n * means all token operations (creation, movement and destruction) must have\n * amounts that are a multiple of this number.\n *\n * For most token contracts, this value will equal 1.\n */\n function granularity() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by an account (`owner`).\n */\n function balanceOf(address owner) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * If send or receive hooks are registered for the caller and `recipient`,\n * the corresponding functions will be called with `data` and empty\n * `operatorData`. See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits a {Sent} event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function send(address recipient, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Destroys `amount` tokens from the caller's account, reducing the\n * total supply.\n *\n * If a send hook is registered for the caller, the corresponding function\n * will be called with `data` and empty `operatorData`. See {IERC777Sender}.\n *\n * Emits a {Burned} event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n */\n function burn(uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Returns true if an account is an operator of `tokenHolder`.\n * Operators can send and burn tokens on behalf of their owners. All\n * accounts are their own operator.\n *\n * See {operatorSend} and {operatorBurn}.\n */\n function isOperatorFor(address operator, address tokenHolder) external view returns (bool);\n\n /**\n * @dev Make an account an operator of the caller.\n *\n * See {isOperatorFor}.\n *\n * Emits an {AuthorizedOperator} event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function authorizeOperator(address operator) external;\n\n /**\n * @dev Revoke an account's operator status for the caller.\n *\n * See {isOperatorFor} and {defaultOperators}.\n *\n * Emits a {RevokedOperator} event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function revokeOperator(address operator) external;\n\n /**\n * @dev Returns the list of default operators. These accounts are operators\n * for all token holders, even if {authorizeOperator} was never called on\n * them.\n *\n * This list is immutable, but individual holders may revoke these via\n * {revokeOperator}, in which case {isOperatorFor} will return false.\n */\n function defaultOperators() external view returns (address[] memory);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must\n * be an operator of `sender`.\n *\n * If send or receive hooks are registered for `sender` and `recipient`,\n * the corresponding functions will be called with `data` and\n * `operatorData`. See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits a {Sent} event.\n *\n * Requirements\n *\n * - `sender` cannot be the zero address.\n * - `sender` must have at least `amount` tokens.\n * - the caller must be an operator for `sender`.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes calldata data,\n bytes calldata operatorData\n ) external;\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the total supply.\n * The caller must be an operator of `account`.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with `data` and `operatorData`. See {IERC777Sender}.\n *\n * Emits a {Burned} event.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n * - the caller must be an operator for `account`.\n */\n function operatorBurn(address account, uint256 amount, bytes calldata data, bytes calldata operatorData) external;\n\n event Sent(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes data,\n bytes operatorData\n );\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\n *\n * Accounts can be notified of {IERC777} tokens being sent to them by having a\n * contract implement this interface (contract holders can be their own\n * implementer) and registering it on the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\n *\n * See {IERC1820Registry} and {ERC1820Implementer}.\n */\ninterface IERC777Recipient {\n /**\n * @dev Called by an {IERC777} token contract whenever tokens are being\n * moved or created into a registered account (`to`). The type of operation\n * is conveyed by `from` being the zero address or not.\n *\n * This call occurs _after_ the token contract's state is updated, so\n * {IERC777-balanceOf}, etc., can be used to query the post-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensReceived(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777Sender.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Sender.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777TokensSender standard as defined in the EIP.\n *\n * {IERC777} Token holders can be notified of operations performed on their\n * tokens by having a contract implement this interface (contract holders can be\n * their own implementer) and registering it on the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\n *\n * See {IERC1820Registry} and {ERC1820Implementer}.\n */\ninterface IERC777Sender {\n /**\n * @dev Called by an {IERC777} token contract whenever a registered holder's\n * (`from`) tokens are about to be moved or destroyed. The type of operation\n * is conveyed by `to` being the zero address or not.\n *\n * This call occurs _before_ the token contract's state is updated, so\n * {IERC777-balanceOf}, etc., can be used to query the pre-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensToSend(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n *\n * Furthermore, `isContract` will also return true if the target contract within\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n * which only has an effect at the end of a transaction.\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Counters.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary Counters {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/ECDSA.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Strings.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV // Deprecated in v4.8\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n /// @solidity memory-safe-assembly\n assembly {\n mstore(0x00, \"\\x19Ethereum Signed Message:\\n32\")\n mstore(0x1c, hash)\n message := keccak256(0x00, 0x3c)\n }\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\n /// @solidity memory-safe-assembly\n assembly {\n let ptr := mload(0x40)\n mstore(ptr, \"\\x19\\x01\")\n mstore(add(ptr, 0x02), domainSeparator)\n mstore(add(ptr, 0x22), structHash)\n data := keccak256(ptr, 0x42)\n }\n }\n\n /**\n * @dev Returns an Ethereum Signed Data with intended validator, created from a\n * `validator` and `data` according to the version 0 of EIP-191.\n *\n * See {recover}.\n */\n function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x00\", validator, data));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/SignatureChecker.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSA.sol\";\nimport \"../../interfaces/IERC1271.sol\";\n\n/**\n * @dev Signature verification helper that can be used instead of `ECDSA.recover` to seamlessly support both ECDSA\n * signatures from externally owned accounts (EOAs) as well as ERC1271 signatures from smart contract wallets like\n * Argent and Gnosis Safe.\n *\n * _Available since v4.1._\n */\nlibrary SignatureChecker {\n /**\n * @dev Checks if a signature is valid for a given signer and data hash. If the signer is a smart contract, the\n * signature is validated against that smart contract using ERC1271, otherwise it's validated using `ECDSA.recover`.\n *\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\n */\n function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature) internal view returns (bool) {\n (address recovered, ECDSA.RecoverError error) = ECDSA.tryRecover(hash, signature);\n return\n (error == ECDSA.RecoverError.NoError && recovered == signer) ||\n isValidERC1271SignatureNow(signer, hash, signature);\n }\n\n /**\n * @dev Checks if a signature is valid for a given signer and data hash. The signature is validated\n * against the signer smart contract using ERC1271.\n *\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\n */\n function isValidERC1271SignatureNow(\n address signer,\n bytes32 hash,\n bytes memory signature\n ) internal view returns (bool) {\n (bool success, bytes memory result) = signer.staticcall(\n abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, signature)\n );\n return (success &&\n result.length >= 32 &&\n abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/ERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165 is IERC165 {\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165).interfaceId;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC1820Registry.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/introspection/IERC1820Registry.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the global ERC1820 Registry, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register\n * implementers for interfaces in this registry, as well as query support.\n *\n * Implementers may be shared by multiple accounts, and can also implement more\n * than a single interface for each account. Contracts can implement interfaces\n * for themselves, but externally-owned accounts (EOA) must delegate this to a\n * contract.\n *\n * {IERC165} interfaces can also be queried via the registry.\n *\n * For an in-depth explanation and source code analysis, see the EIP text.\n */\ninterface IERC1820Registry {\n event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer);\n\n event ManagerChanged(address indexed account, address indexed newManager);\n\n /**\n * @dev Sets `newManager` as the manager for `account`. A manager of an\n * account is able to set interface implementers for it.\n *\n * By default, each account is its own manager. Passing a value of `0x0` in\n * `newManager` will reset the manager to this initial state.\n *\n * Emits a {ManagerChanged} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `account`.\n */\n function setManager(address account, address newManager) external;\n\n /**\n * @dev Returns the manager for `account`.\n *\n * See {setManager}.\n */\n function getManager(address account) external view returns (address);\n\n /**\n * @dev Sets the `implementer` contract as ``account``'s implementer for\n * `interfaceHash`.\n *\n * `account` being the zero address is an alias for the caller's address.\n * The zero address can also be used in `implementer` to remove an old one.\n *\n * See {interfaceHash} to learn how these are created.\n *\n * Emits an {InterfaceImplementerSet} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `account`.\n * - `interfaceHash` must not be an {IERC165} interface id (i.e. it must not\n * end in 28 zeroes).\n * - `implementer` must implement {IERC1820Implementer} and return true when\n * queried for support, unless `implementer` is the caller. See\n * {IERC1820Implementer-canImplementInterfaceForAddress}.\n */\n function setInterfaceImplementer(address account, bytes32 _interfaceHash, address implementer) external;\n\n /**\n * @dev Returns the implementer of `interfaceHash` for `account`. If no such\n * implementer is registered, returns the zero address.\n *\n * If `interfaceHash` is an {IERC165} interface id (i.e. it ends with 28\n * zeroes), `account` will be queried for support of it.\n *\n * `account` being the zero address is an alias for the caller's address.\n */\n function getInterfaceImplementer(address account, bytes32 _interfaceHash) external view returns (address);\n\n /**\n * @dev Returns the interface hash for an `interfaceName`, as defined in the\n * corresponding\n * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP].\n */\n function interfaceHash(string calldata interfaceName) external pure returns (bytes32);\n\n /**\n * @notice Updates the cache with whether the contract implements an ERC165 interface or not.\n * @param account Address of the contract for which to update the cache.\n * @param interfaceId ERC165 interface for which to update the cache.\n */\n function updateERC165Cache(address account, bytes4 interfaceId) external;\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not.\n * If the result is not cached a direct lookup on the contract address is performed.\n * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling\n * {updateERC165Cache} with the contract address.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool);\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not without using or updating the cache.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/math/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\n // The surrounding unchecked block does not change this fact.\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1, \"Math: mulDiv overflow\");\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n //\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n //\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n //\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1 << (log2(a) >> 1);\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = sqrt(a);\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 2, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 128;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 64;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 32;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 16;\n }\n if (value >> 8 > 0) {\n value >>= 8;\n result += 8;\n }\n if (value >> 4 > 0) {\n value >>= 4;\n result += 4;\n }\n if (value >> 2 > 0) {\n value >>= 2;\n result += 2;\n }\n if (value >> 1 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log2(value);\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 10, rounded down, of a positive value.\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 + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 256, rounded down, of a positive value.\n * Returns 0 if given 0.\n *\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n */\n function log256(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 16;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 8;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 4;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 2;\n }\n if (value >> 8 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log256(value);\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/SafeCast.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCast {\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 * _Available since v4.7._\n */\n function toUint248(uint256 value) internal pure returns (uint248) {\n require(value <= type(uint248).max, \"SafeCast: value doesn't fit in 248 bits\");\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 * _Available since v4.7._\n */\n function toUint240(uint256 value) internal pure returns (uint240) {\n require(value <= type(uint240).max, \"SafeCast: value doesn't fit in 240 bits\");\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 * _Available since v4.7._\n */\n function toUint232(uint256 value) internal pure returns (uint232) {\n require(value <= type(uint232).max, \"SafeCast: value doesn't fit in 232 bits\");\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 * _Available since v4.2._\n */\n function toUint224(uint256 value) internal pure returns (uint224) {\n require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\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 * _Available since v4.7._\n */\n function toUint216(uint256 value) internal pure returns (uint216) {\n require(value <= type(uint216).max, \"SafeCast: value doesn't fit in 216 bits\");\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 * _Available since v4.7._\n */\n function toUint208(uint256 value) internal pure returns (uint208) {\n require(value <= type(uint208).max, \"SafeCast: value doesn't fit in 208 bits\");\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 * _Available since v4.7._\n */\n function toUint200(uint256 value) internal pure returns (uint200) {\n require(value <= type(uint200).max, \"SafeCast: value doesn't fit in 200 bits\");\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 * _Available since v4.7._\n */\n function toUint192(uint256 value) internal pure returns (uint192) {\n require(value <= type(uint192).max, \"SafeCast: value doesn't fit in 192 bits\");\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 * _Available since v4.7._\n */\n function toUint184(uint256 value) internal pure returns (uint184) {\n require(value <= type(uint184).max, \"SafeCast: value doesn't fit in 184 bits\");\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 * _Available since v4.7._\n */\n function toUint176(uint256 value) internal pure returns (uint176) {\n require(value <= type(uint176).max, \"SafeCast: value doesn't fit in 176 bits\");\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 * _Available since v4.7._\n */\n function toUint168(uint256 value) internal pure returns (uint168) {\n require(value <= type(uint168).max, \"SafeCast: value doesn't fit in 168 bits\");\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 * _Available since v4.7._\n */\n function toUint160(uint256 value) internal pure returns (uint160) {\n require(value <= type(uint160).max, \"SafeCast: value doesn't fit in 160 bits\");\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 * _Available since v4.7._\n */\n function toUint152(uint256 value) internal pure returns (uint152) {\n require(value <= type(uint152).max, \"SafeCast: value doesn't fit in 152 bits\");\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 * _Available since v4.7._\n */\n function toUint144(uint256 value) internal pure returns (uint144) {\n require(value <= type(uint144).max, \"SafeCast: value doesn't fit in 144 bits\");\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 * _Available since v4.7._\n */\n function toUint136(uint256 value) internal pure returns (uint136) {\n require(value <= type(uint136).max, \"SafeCast: value doesn't fit in 136 bits\");\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 * _Available since v2.5._\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\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 * _Available since v4.7._\n */\n function toUint120(uint256 value) internal pure returns (uint120) {\n require(value <= type(uint120).max, \"SafeCast: value doesn't fit in 120 bits\");\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 * _Available since v4.7._\n */\n function toUint112(uint256 value) internal pure returns (uint112) {\n require(value <= type(uint112).max, \"SafeCast: value doesn't fit in 112 bits\");\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 * _Available since v4.7._\n */\n function toUint104(uint256 value) internal pure returns (uint104) {\n require(value <= type(uint104).max, \"SafeCast: value doesn't fit in 104 bits\");\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 * _Available since v4.2._\n */\n function toUint96(uint256 value) internal pure returns (uint96) {\n require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\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 * _Available since v4.7._\n */\n function toUint88(uint256 value) internal pure returns (uint88) {\n require(value <= type(uint88).max, \"SafeCast: value doesn't fit in 88 bits\");\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 * _Available since v4.7._\n */\n function toUint80(uint256 value) internal pure returns (uint80) {\n require(value <= type(uint80).max, \"SafeCast: value doesn't fit in 80 bits\");\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 * _Available since v4.7._\n */\n function toUint72(uint256 value) internal pure returns (uint72) {\n require(value <= type(uint72).max, \"SafeCast: value doesn't fit in 72 bits\");\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 * _Available since v2.5._\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\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 * _Available since v4.7._\n */\n function toUint56(uint256 value) internal pure returns (uint56) {\n require(value <= type(uint56).max, \"SafeCast: value doesn't fit in 56 bits\");\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 * _Available since v4.7._\n */\n function toUint48(uint256 value) internal pure returns (uint48) {\n require(value <= type(uint48).max, \"SafeCast: value doesn't fit in 48 bits\");\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 * _Available since v4.7._\n */\n function toUint40(uint256 value) internal pure returns (uint40) {\n require(value <= type(uint40).max, \"SafeCast: value doesn't fit in 40 bits\");\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 * _Available since v2.5._\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\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 * _Available since v4.7._\n */\n function toUint24(uint256 value) internal pure returns (uint24) {\n require(value <= type(uint24).max, \"SafeCast: value doesn't fit in 24 bits\");\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 * _Available since v2.5._\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\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 * _Available since v2.5._\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\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 * _Available since v3.0._\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\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 * _Available since v4.7._\n */\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\n downcasted = int248(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 248 bits\");\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 * _Available since v4.7._\n */\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\n downcasted = int240(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 240 bits\");\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 * _Available since v4.7._\n */\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\n downcasted = int232(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 232 bits\");\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 * _Available since v4.7._\n */\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\n downcasted = int224(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 224 bits\");\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 * _Available since v4.7._\n */\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\n downcasted = int216(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 216 bits\");\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 * _Available since v4.7._\n */\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\n downcasted = int208(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 208 bits\");\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 * _Available since v4.7._\n */\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\n downcasted = int200(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 200 bits\");\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 * _Available since v4.7._\n */\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\n downcasted = int192(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 192 bits\");\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 * _Available since v4.7._\n */\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\n downcasted = int184(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 184 bits\");\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 * _Available since v4.7._\n */\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\n downcasted = int176(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 176 bits\");\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 * _Available since v4.7._\n */\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\n downcasted = int168(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 168 bits\");\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 * _Available since v4.7._\n */\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\n downcasted = int160(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 160 bits\");\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 * _Available since v4.7._\n */\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\n downcasted = int152(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 152 bits\");\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 * _Available since v4.7._\n */\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\n downcasted = int144(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 144 bits\");\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 * _Available since v4.7._\n */\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\n downcasted = int136(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 136 bits\");\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 * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\n downcasted = int128(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 128 bits\");\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 * _Available since v4.7._\n */\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\n downcasted = int120(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 120 bits\");\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 * _Available since v4.7._\n */\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\n downcasted = int112(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 112 bits\");\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 * _Available since v4.7._\n */\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\n downcasted = int104(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 104 bits\");\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 * _Available since v4.7._\n */\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\n downcasted = int96(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 96 bits\");\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 * _Available since v4.7._\n */\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\n downcasted = int88(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 88 bits\");\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 * _Available since v4.7._\n */\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\n downcasted = int80(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 80 bits\");\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 * _Available since v4.7._\n */\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\n downcasted = int72(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 72 bits\");\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 * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\n downcasted = int64(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 64 bits\");\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 * _Available since v4.7._\n */\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\n downcasted = int56(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 56 bits\");\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 * _Available since v4.7._\n */\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\n downcasted = int48(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 48 bits\");\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 * _Available since v4.7._\n */\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\n downcasted = int40(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 40 bits\");\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 * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\n downcasted = int32(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 32 bits\");\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 * _Available since v4.7._\n */\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\n downcasted = int24(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 24 bits\");\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 * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\n downcasted = int16(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 16 bits\");\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 * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\n downcasted = int8(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 8 bits\");\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 * _Available since v3.0._\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 require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/SignedMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard signed math utilities missing in the Solidity language.\n */\nlibrary SignedMath {\n /**\n * @dev Returns the largest of two signed numbers.\n */\n function max(int256 a, int256 b) internal pure returns (int256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two signed numbers.\n */\n function min(int256 a, int256 b) internal pure returns (int256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two signed numbers without overflow.\n * The result is rounded towards zero.\n */\n function average(int256 a, int256 b) internal pure returns (int256) {\n // Formula from the book \"Hacker's Delight\"\n int256 x = (a & b) + ((a ^ b) >> 1);\n return x + (int256(uint256(x) >> 255) & (a ^ b));\n }\n\n /**\n * @dev Returns the absolute unsigned value of a signed value.\n */\n function abs(int256 n) internal pure returns (uint256) {\n unchecked {\n // must be unchecked in order to support `n = type(int256).min`\n return uint256(n >= 0 ? n : -n);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/Math.sol\";\nimport \"./math/SignedMath.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n unchecked {\n uint256 length = Math.log10(value) + 1;\n string memory buffer = new string(length);\n uint256 ptr;\n /// @solidity memory-safe-assembly\n assembly {\n ptr := add(buffer, add(32, length))\n }\n while (true) {\n ptr--;\n /// @solidity memory-safe-assembly\n assembly {\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n }\n value /= 10;\n if (value == 0) break;\n }\n return buffer;\n }\n }\n\n /**\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\n */\n function toString(int256 value) internal pure returns (string memory) {\n return string(abi.encodePacked(value < 0 ? \"-\" : \"\", toString(SignedMath.abs(value))));\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n unchecked {\n return toHexString(value, Math.log256(value) + 1);\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n\n /**\n * @dev Returns true if the two strings are equal.\n */\n function equal(string memory a, string memory b) internal pure returns (bool) {\n return keccak256(bytes(a)) == keccak256(bytes(b));\n }\n}\n" + }, + "contracts/aa-4337/core/BaseAccount.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-empty-blocks */\n\nimport \"../interfaces/IAccount.sol\";\nimport \"../interfaces/IEntryPoint.sol\";\nimport \"./Helpers.sol\";\n\n/**\n * Basic account implementation.\n * this contract provides the basic logic for implementing the IAccount interface - validateUserOp\n * specific account implementation should inherit it and provide the account-specific logic\n */\nabstract contract BaseAccount is IAccount {\n using UserOperationLib for UserOperation;\n\n //return value in case of signature failure, with no time-range.\n // equivalent to _packValidationData(true,0,0);\n uint256 internal constant SIG_VALIDATION_FAILED = 1;\n\n /**\n * Return the account nonce.\n * This method returns the next sequential nonce.\n * For a nonce of a specific key, use `entrypoint.getNonce(account, key)`\n */\n function getNonce() public view virtual returns (uint256) {\n return entryPoint().getNonce(address(this), 0);\n }\n\n /**\n * return the entryPoint used by this account.\n * subclass should return the current entryPoint used by this account.\n */\n function entryPoint() public view virtual returns (IEntryPoint);\n\n /**\n * Validate user's signature and nonce.\n * subclass doesn't need to override this method. Instead, it should override the specific internal validation methods.\n */\n function validateUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 missingAccountFunds\n ) external virtual override returns (uint256 validationData) {\n _requireFromEntryPoint();\n validationData = _validateSignature(userOp, userOpHash);\n _validateNonce(userOp.nonce);\n _payPrefund(missingAccountFunds);\n }\n\n /**\n * ensure the request comes from the known entrypoint.\n */\n function _requireFromEntryPoint() internal view virtual {\n require(\n msg.sender == address(entryPoint()),\n \"account: not from EntryPoint\"\n );\n }\n\n /**\n * validate the signature is valid for this message.\n * @param userOp validate the userOp.signature field\n * @param userOpHash convenient field: the hash of the request, to check the signature against\n * (also hashes the entrypoint and chain id)\n * @return validationData signature and time-range of this operation\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * If the account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function _validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) internal virtual returns (uint256 validationData);\n\n /**\n * Validate the nonce of the UserOperation.\n * This method may validate the nonce requirement of this account.\n * e.g.\n * To limit the nonce to use sequenced UserOps only (no \"out of order\" UserOps):\n * `require(nonce < type(uint64).max)`\n * For a hypothetical account that *requires* the nonce to be out-of-order:\n * `require(nonce & type(uint64).max == 0)`\n *\n * The actual nonce uniqueness is managed by the EntryPoint, and thus no other\n * action is needed by the account itself.\n *\n * @param nonce to validate\n *\n * solhint-disable-next-line no-empty-blocks\n */\n function _validateNonce(uint256 nonce) internal view virtual {}\n\n /**\n * sends to the entrypoint (msg.sender) the missing funds for this transaction.\n * subclass MAY override this method for better funds management\n * (e.g. send to the entryPoint more than the minimum required, so that in future transactions\n * it will not be required to send again)\n * @param missingAccountFunds the minimum value this method should send the entrypoint.\n * this value MAY be zero, in case there is enough deposit, or the userOp has a paymaster.\n */\n function _payPrefund(uint256 missingAccountFunds) internal virtual {\n if (missingAccountFunds != 0) {\n (bool success, ) = payable(msg.sender).call{\n value: missingAccountFunds,\n gas: type(uint256).max\n }(\"\");\n (success);\n //ignore failure (its EntryPoint's job to verify, not account.)\n }\n }\n}\n" + }, + "contracts/aa-4337/core/EntryPoint.sol": { + "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n\nimport \"../interfaces/IAccount.sol\";\nimport \"../interfaces/IPaymaster.sol\";\nimport \"../interfaces/IEntryPoint.sol\";\n\nimport \"../utils/Exec.sol\";\nimport \"./StakeManager.sol\";\nimport \"./SenderCreator.sol\";\nimport \"./Helpers.sol\";\nimport \"./NonceManager.sol\";\nimport \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\n\ncontract EntryPoint is\n IEntryPoint,\n StakeManager,\n NonceManager,\n ReentrancyGuard\n{\n using UserOperationLib for UserOperation;\n\n SenderCreator private immutable senderCreator = new SenderCreator();\n\n // internal value used during simulation: need to query aggregator.\n address private constant SIMULATE_FIND_AGGREGATOR = address(1);\n\n // marker for inner call revert on out of gas\n bytes32 private constant INNER_OUT_OF_GAS = hex\"deaddead\";\n\n uint256 private constant REVERT_REASON_MAX_LEN = 2048;\n\n /**\n * for simulation purposes, validateUserOp (and validatePaymasterUserOp) must return this value\n * in case of signature failure, instead of revert.\n */\n uint256 public constant SIG_VALIDATION_FAILED = 1;\n\n /**\n * compensate the caller's beneficiary address with the collected fees of all UserOperations.\n * @param beneficiary the address to receive the fees\n * @param amount amount to transfer.\n */\n function _compensate(address payable beneficiary, uint256 amount) internal {\n require(beneficiary != address(0), \"AA90 invalid beneficiary\");\n (bool success, ) = beneficiary.call{value: amount}(\"\");\n require(success, \"AA91 failed send to beneficiary\");\n }\n\n /**\n * execute a user op\n * @param opIndex index into the opInfo array\n * @param userOp the userOp to execute\n * @param opInfo the opInfo filled by validatePrepayment for this userOp.\n * @return collected the total amount this userOp paid.\n */\n function _executeUserOp(\n uint256 opIndex,\n UserOperation calldata userOp,\n UserOpInfo memory opInfo\n ) private returns (uint256 collected) {\n uint256 preGas = gasleft();\n bytes memory context = getMemoryBytesFromOffset(opInfo.contextOffset);\n\n try this.innerHandleOp(userOp.callData, opInfo, context) returns (\n uint256 _actualGasCost\n ) {\n collected = _actualGasCost;\n } catch {\n bytes32 innerRevertCode;\n assembly {\n returndatacopy(0, 0, 32)\n innerRevertCode := mload(0)\n }\n // handleOps was called with gas limit too low. abort entire bundle.\n if (innerRevertCode == INNER_OUT_OF_GAS) {\n //report paymaster, since if it is not deliberately caused by the bundler,\n // it must be a revert caused by paymaster.\n revert FailedOp(opIndex, \"AA95 out of gas\");\n }\n\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n collected = _handlePostOp(\n opIndex,\n IPaymaster.PostOpMode.postOpReverted,\n opInfo,\n context,\n actualGas\n );\n }\n }\n\n /**\n * Execute a batch of UserOperations.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(\n UserOperation[] calldata ops,\n address payable beneficiary\n ) public nonReentrant {\n uint256 opslen = ops.length;\n UserOpInfo[] memory opInfos = new UserOpInfo[](opslen);\n\n unchecked {\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[i];\n (\n uint256 validationData,\n uint256 pmValidationData\n ) = _validatePrepayment(i, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(\n i,\n validationData,\n pmValidationData,\n address(0)\n );\n }\n\n uint256 collected = 0;\n emit BeforeExecution();\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(i, ops[i], opInfos[i]);\n }\n\n _compensate(beneficiary, collected);\n } //unchecked\n }\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) public nonReentrant {\n uint256 opasLen = opsPerAggregator.length;\n uint256 totalOps = 0;\n for (uint256 i = 0; i < opasLen; i++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[i];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n //address(1) is special marker of \"signature error\"\n require(\n address(aggregator) != address(1),\n \"AA96 invalid aggregator\"\n );\n\n if (address(aggregator) != address(0)) {\n // solhint-disable-next-line no-empty-blocks\n try aggregator.validateSignatures(ops, opa.signature) {} catch {\n revert SignatureValidationFailed(address(aggregator));\n }\n }\n\n totalOps += ops.length;\n }\n\n UserOpInfo[] memory opInfos = new UserOpInfo[](totalOps);\n\n emit BeforeExecution();\n\n uint256 opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n uint256 opslen = ops.length;\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[opIndex];\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(opIndex, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(\n i,\n validationData,\n paymasterValidationData,\n address(aggregator)\n );\n opIndex++;\n }\n }\n\n uint256 collected = 0;\n opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n emit SignatureAggregatorChanged(address(opa.aggregator));\n UserOperation[] calldata ops = opa.userOps;\n uint256 opslen = ops.length;\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(opIndex, ops[i], opInfos[opIndex]);\n opIndex++;\n }\n }\n emit SignatureAggregatorChanged(address(0));\n\n _compensate(beneficiary, collected);\n }\n\n /// @inheritdoc IEntryPoint\n function simulateHandleOp(\n UserOperation calldata op,\n address target,\n bytes calldata targetCallData\n ) external override {\n UserOpInfo memory opInfo;\n _simulationOnlyValidations(op);\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(0, op, opInfo);\n ValidationData memory data = _intersectTimeRange(\n validationData,\n paymasterValidationData\n );\n\n numberMarker();\n uint256 paid = _executeUserOp(0, op, opInfo);\n numberMarker();\n bool targetSuccess;\n bytes memory targetResult;\n if (target != address(0)) {\n (targetSuccess, targetResult) = target.call(targetCallData);\n }\n revert ExecutionResult(\n opInfo.preOpGas,\n paid,\n data.validAfter,\n data.validUntil,\n targetSuccess,\n targetResult\n );\n }\n\n // A memory copy of UserOp static fields only.\n // Excluding: callData, initCode and signature. Replacing paymasterAndData with paymaster.\n struct MemoryUserOp {\n address sender;\n uint256 nonce;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n address paymaster;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n }\n\n struct UserOpInfo {\n MemoryUserOp mUserOp;\n bytes32 userOpHash;\n uint256 prefund;\n uint256 contextOffset;\n uint256 preOpGas;\n }\n\n /**\n * inner function to handle a UserOperation.\n * Must be declared \"external\" to open a call context, but it can only be called by handleOps.\n */\n function innerHandleOp(\n bytes memory callData,\n UserOpInfo memory opInfo,\n bytes calldata context\n ) external returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n require(msg.sender == address(this), \"AA92 internal call only\");\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n\n uint callGasLimit = mUserOp.callGasLimit;\n unchecked {\n // handleOps was called with gas limit too low. abort entire bundle.\n if (\n gasleft() < callGasLimit + mUserOp.verificationGasLimit + 5000\n ) {\n assembly {\n mstore(0, INNER_OUT_OF_GAS)\n revert(0, 32)\n }\n }\n }\n\n IPaymaster.PostOpMode mode = IPaymaster.PostOpMode.opSucceeded;\n if (callData.length > 0) {\n bool success = Exec.call(mUserOp.sender, 0, callData, callGasLimit);\n if (!success) {\n bytes memory result = Exec.getReturnData(REVERT_REASON_MAX_LEN);\n if (result.length > 0) {\n emit UserOperationRevertReason(\n opInfo.userOpHash,\n mUserOp.sender,\n mUserOp.nonce,\n result\n );\n }\n mode = IPaymaster.PostOpMode.opReverted;\n }\n }\n\n unchecked {\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n //note: opIndex is ignored (relevant only if mode==postOpReverted, which is only possible outside of innerHandleOp)\n return _handlePostOp(0, mode, opInfo, context, actualGas);\n }\n }\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(\n UserOperation calldata userOp\n ) public view returns (bytes32) {\n return\n keccak256(abi.encode(userOp.hash(), address(this), block.chainid));\n }\n\n /**\n * copy general fields from userOp into the memory opInfo structure.\n */\n function _copyUserOpToMemory(\n UserOperation calldata userOp,\n MemoryUserOp memory mUserOp\n ) internal pure {\n mUserOp.sender = userOp.sender;\n mUserOp.nonce = userOp.nonce;\n mUserOp.callGasLimit = userOp.callGasLimit;\n mUserOp.verificationGasLimit = userOp.verificationGasLimit;\n mUserOp.preVerificationGas = userOp.preVerificationGas;\n mUserOp.maxFeePerGas = userOp.maxFeePerGas;\n mUserOp.maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes calldata paymasterAndData = userOp.paymasterAndData;\n if (paymasterAndData.length > 0) {\n require(\n paymasterAndData.length >= 20,\n \"AA93 invalid paymasterAndData\"\n );\n mUserOp.paymaster = address(bytes20(paymasterAndData[:20]));\n } else {\n mUserOp.paymaster = address(0);\n }\n }\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external {\n UserOpInfo memory outOpInfo;\n\n _simulationOnlyValidations(userOp);\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(0, userOp, outOpInfo);\n StakeInfo memory paymasterInfo = _getStakeInfo(\n outOpInfo.mUserOp.paymaster\n );\n StakeInfo memory senderInfo = _getStakeInfo(outOpInfo.mUserOp.sender);\n StakeInfo memory factoryInfo;\n {\n bytes calldata initCode = userOp.initCode;\n address factory = initCode.length >= 20\n ? address(bytes20(initCode[0:20]))\n : address(0);\n factoryInfo = _getStakeInfo(factory);\n }\n\n ValidationData memory data = _intersectTimeRange(\n validationData,\n paymasterValidationData\n );\n address aggregator = data.aggregator;\n bool sigFailed = aggregator == address(1);\n ReturnInfo memory returnInfo = ReturnInfo(\n outOpInfo.preOpGas,\n outOpInfo.prefund,\n sigFailed,\n data.validAfter,\n data.validUntil,\n getMemoryBytesFromOffset(outOpInfo.contextOffset)\n );\n\n if (aggregator != address(0) && aggregator != address(1)) {\n AggregatorStakeInfo memory aggregatorInfo = AggregatorStakeInfo(\n aggregator,\n _getStakeInfo(aggregator)\n );\n revert ValidationResultWithAggregation(\n returnInfo,\n senderInfo,\n factoryInfo,\n paymasterInfo,\n aggregatorInfo\n );\n }\n revert ValidationResult(\n returnInfo,\n senderInfo,\n factoryInfo,\n paymasterInfo\n );\n }\n\n function _getRequiredPrefund(\n MemoryUserOp memory mUserOp\n ) internal pure returns (uint256 requiredPrefund) {\n unchecked {\n //when using a Paymaster, the verificationGasLimit is used also to as a limit for the postOp call.\n // our security model might call postOp eventually twice\n uint256 mul = mUserOp.paymaster != address(0) ? 3 : 1;\n uint256 requiredGas = mUserOp.callGasLimit +\n mUserOp.verificationGasLimit *\n mul +\n mUserOp.preVerificationGas;\n\n requiredPrefund = requiredGas * mUserOp.maxFeePerGas;\n }\n }\n\n // create the sender's contract if needed.\n function _createSenderIfNeeded(\n uint256 opIndex,\n UserOpInfo memory opInfo,\n bytes calldata initCode\n ) internal {\n if (initCode.length != 0) {\n address sender = opInfo.mUserOp.sender;\n if (sender.code.length != 0)\n revert FailedOp(opIndex, \"AA10 sender already constructed\");\n address sender1 = senderCreator.createSender{\n gas: opInfo.mUserOp.verificationGasLimit\n }(initCode);\n if (sender1 == address(0))\n revert FailedOp(opIndex, \"AA13 initCode failed or OOG\");\n if (sender1 != sender)\n revert FailedOp(opIndex, \"AA14 initCode must return sender\");\n if (sender1.code.length == 0)\n revert FailedOp(opIndex, \"AA15 initCode must create sender\");\n address factory = address(bytes20(initCode[0:20]));\n emit AccountDeployed(\n opInfo.userOpHash,\n sender,\n factory,\n opInfo.mUserOp.paymaster\n );\n }\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes calldata initCode) public {\n address sender = senderCreator.createSender(initCode);\n revert SenderAddressResult(sender);\n }\n\n function _simulationOnlyValidations(\n UserOperation calldata userOp\n ) internal view {\n // solhint-disable-next-line no-empty-blocks\n try\n this._validateSenderAndPaymaster(\n userOp.initCode,\n userOp.sender,\n userOp.paymasterAndData\n )\n {} catch Error(string memory revertReason) {\n if (bytes(revertReason).length != 0) {\n revert FailedOp(0, revertReason);\n }\n }\n }\n\n /**\n * Called only during simulation.\n * This function always reverts to prevent warm/cold storage differentiation in simulation vs execution.\n */\n function _validateSenderAndPaymaster(\n bytes calldata initCode,\n address sender,\n bytes calldata paymasterAndData\n ) external view {\n if (initCode.length == 0 && sender.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA20 account not deployed\");\n }\n if (paymasterAndData.length >= 20) {\n address paymaster = address(bytes20(paymasterAndData[0:20]));\n if (paymaster.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA30 paymaster not deployed\");\n }\n }\n // always revert\n revert(\"\");\n }\n\n /**\n * call account.validateUserOp.\n * revert (with FailedOp) in case validateUserOp reverts, or account didn't send required prefund.\n * decrement account's deposit if needed\n */\n function _validateAccountPrepayment(\n uint256 opIndex,\n UserOperation calldata op,\n UserOpInfo memory opInfo,\n uint256 requiredPrefund\n )\n internal\n returns (\n uint256 gasUsedByValidateAccountPrepayment,\n uint256 validationData\n )\n {\n unchecked {\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n address sender = mUserOp.sender;\n _createSenderIfNeeded(opIndex, opInfo, op.initCode);\n address paymaster = mUserOp.paymaster;\n numberMarker();\n uint256 missingAccountFunds = 0;\n if (paymaster == address(0)) {\n uint256 bal = balanceOf(sender);\n missingAccountFunds = bal > requiredPrefund\n ? 0\n : requiredPrefund - bal;\n }\n try\n IAccount(sender).validateUserOp{\n gas: mUserOp.verificationGasLimit\n }(op, opInfo.userOpHash, missingAccountFunds)\n returns (uint256 _validationData) {\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA23 reverted: \", revertReason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA23 reverted (or OOG)\");\n }\n if (paymaster == address(0)) {\n DepositInfo storage senderInfo = deposits[sender];\n uint256 deposit = senderInfo.deposit;\n if (requiredPrefund > deposit) {\n revert FailedOp(opIndex, \"AA21 didn't pay prefund\");\n }\n senderInfo.deposit = uint112(deposit - requiredPrefund);\n }\n gasUsedByValidateAccountPrepayment = preGas - gasleft();\n }\n }\n\n /**\n * In case the request has a paymaster:\n * Validate paymaster has enough deposit.\n * Call paymaster.validatePaymasterUserOp.\n * Revert with proper FailedOp in case paymaster reverts.\n * Decrement paymaster's deposit\n */\n function _validatePaymasterPrepayment(\n uint256 opIndex,\n UserOperation calldata op,\n UserOpInfo memory opInfo,\n uint256 requiredPreFund,\n uint256 gasUsedByValidateAccountPrepayment\n ) internal returns (bytes memory context, uint256 validationData) {\n unchecked {\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 verificationGasLimit = mUserOp.verificationGasLimit;\n require(\n verificationGasLimit > gasUsedByValidateAccountPrepayment,\n \"AA41 too little verificationGas\"\n );\n uint256 gas = verificationGasLimit -\n gasUsedByValidateAccountPrepayment;\n\n address paymaster = mUserOp.paymaster;\n DepositInfo storage paymasterInfo = deposits[paymaster];\n uint256 deposit = paymasterInfo.deposit;\n if (deposit < requiredPreFund) {\n revert FailedOp(opIndex, \"AA31 paymaster deposit too low\");\n }\n paymasterInfo.deposit = uint112(deposit - requiredPreFund);\n try\n IPaymaster(paymaster).validatePaymasterUserOp{gas: gas}(\n op,\n opInfo.userOpHash,\n requiredPreFund\n )\n returns (bytes memory _context, uint256 _validationData) {\n context = _context;\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA33 reverted: \", revertReason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA33 reverted (or OOG)\");\n }\n }\n }\n\n /**\n * revert if either account validationData or paymaster validationData is expired\n */\n function _validateAccountAndPaymasterValidationData(\n uint256 opIndex,\n uint256 validationData,\n uint256 paymasterValidationData,\n address expectedAggregator\n ) internal view {\n (address aggregator, bool outOfTimeRange) = _getValidationData(\n validationData\n );\n if (expectedAggregator != aggregator) {\n revert FailedOp(opIndex, \"AA24 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA22 expired or not due\");\n }\n //pmAggregator is not a real signature aggregator: we don't have logic to handle it as address.\n // non-zero address means that the paymaster fails due to some signature check (which is ok only during estimation)\n address pmAggregator;\n (pmAggregator, outOfTimeRange) = _getValidationData(\n paymasterValidationData\n );\n if (pmAggregator != address(0)) {\n revert FailedOp(opIndex, \"AA34 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA32 paymaster expired or not due\");\n }\n }\n\n function _getValidationData(\n uint256 validationData\n ) internal view returns (address aggregator, bool outOfTimeRange) {\n if (validationData == 0) {\n return (address(0), false);\n }\n ValidationData memory data = _parseValidationData(validationData);\n // solhint-disable-next-line not-rely-on-time\n outOfTimeRange =\n block.timestamp > data.validUntil ||\n block.timestamp < data.validAfter;\n aggregator = data.aggregator;\n }\n\n /**\n * validate account and paymaster (if defined).\n * also make sure total validation doesn't exceed verificationGasLimit\n * this method is called off-chain (simulateValidation()) and on-chain (from handleOps)\n * @param opIndex the index of this userOp into the \"opInfos\" array\n * @param userOp the userOp to validate\n */\n function _validatePrepayment(\n uint256 opIndex,\n UserOperation calldata userOp,\n UserOpInfo memory outOpInfo\n )\n private\n returns (uint256 validationData, uint256 paymasterValidationData)\n {\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = outOpInfo.mUserOp;\n _copyUserOpToMemory(userOp, mUserOp);\n outOpInfo.userOpHash = getUserOpHash(userOp);\n\n // validate all numeric values in userOp are well below 128 bit, so they can safely be added\n // and multiplied without causing overflow\n uint256 maxGasValues = mUserOp.preVerificationGas |\n mUserOp.verificationGasLimit |\n mUserOp.callGasLimit |\n userOp.maxFeePerGas |\n userOp.maxPriorityFeePerGas;\n require(maxGasValues <= type(uint120).max, \"AA94 gas values overflow\");\n\n uint256 gasUsedByValidateAccountPrepayment;\n uint256 requiredPreFund = _getRequiredPrefund(mUserOp);\n (\n gasUsedByValidateAccountPrepayment,\n validationData\n ) = _validateAccountPrepayment(\n opIndex,\n userOp,\n outOpInfo,\n requiredPreFund\n );\n\n if (!_validateAndUpdateNonce(mUserOp.sender, mUserOp.nonce)) {\n revert FailedOp(opIndex, \"AA25 invalid account nonce\");\n }\n\n //a \"marker\" where account opcode validation is done and paymaster opcode validation is about to start\n // (used only by off-chain simulateValidation)\n numberMarker();\n\n bytes memory context;\n if (mUserOp.paymaster != address(0)) {\n (context, paymasterValidationData) = _validatePaymasterPrepayment(\n opIndex,\n userOp,\n outOpInfo,\n requiredPreFund,\n gasUsedByValidateAccountPrepayment\n );\n }\n unchecked {\n uint256 gasUsed = preGas - gasleft();\n\n if (userOp.verificationGasLimit < gasUsed) {\n revert FailedOp(opIndex, \"AA40 over verificationGasLimit\");\n }\n outOpInfo.prefund = requiredPreFund;\n outOpInfo.contextOffset = getOffsetOfMemoryBytes(context);\n outOpInfo.preOpGas = preGas - gasleft() + userOp.preVerificationGas;\n }\n }\n\n /**\n * process post-operation.\n * called just after the callData is executed.\n * if a paymaster is defined and its validation returned a non-empty context, its postOp is called.\n * the excess amount is refunded to the account (or paymaster - if it was used in the request)\n * @param opIndex index in the batch\n * @param mode - whether is called from innerHandleOp, or outside (postOpReverted)\n * @param opInfo userOp fields and info collected during validation\n * @param context the context returned in validatePaymasterUserOp\n * @param actualGas the gas used so far by this user operation\n */\n function _handlePostOp(\n uint256 opIndex,\n IPaymaster.PostOpMode mode,\n UserOpInfo memory opInfo,\n bytes memory context,\n uint256 actualGas\n ) private returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n unchecked {\n address refundAddress;\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 gasPrice = getUserOpGasPrice(mUserOp);\n\n address paymaster = mUserOp.paymaster;\n if (paymaster == address(0)) {\n refundAddress = mUserOp.sender;\n } else {\n refundAddress = paymaster;\n if (context.length > 0) {\n actualGasCost = actualGas * gasPrice;\n if (mode != IPaymaster.PostOpMode.postOpReverted) {\n IPaymaster(paymaster).postOp{\n gas: mUserOp.verificationGasLimit\n }(mode, context, actualGasCost);\n } else {\n // solhint-disable-next-line no-empty-blocks\n try\n IPaymaster(paymaster).postOp{\n gas: mUserOp.verificationGasLimit\n }(mode, context, actualGasCost)\n {} catch Error(string memory reason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA50 postOp reverted: \", reason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA50 postOp revert\");\n }\n }\n }\n }\n actualGas += preGas - gasleft();\n actualGasCost = actualGas * gasPrice;\n if (opInfo.prefund < actualGasCost) {\n revert FailedOp(opIndex, \"AA51 prefund below actualGasCost\");\n }\n uint256 refund = opInfo.prefund - actualGasCost;\n _incrementDeposit(refundAddress, refund);\n bool success = mode == IPaymaster.PostOpMode.opSucceeded;\n emit UserOperationEvent(\n opInfo.userOpHash,\n mUserOp.sender,\n mUserOp.paymaster,\n mUserOp.nonce,\n success,\n actualGasCost,\n actualGas\n );\n } // unchecked\n }\n\n /**\n * the gas price this UserOp agrees to pay.\n * relayer/block builder might submit the TX with higher priorityFee, but the user should not\n */\n function getUserOpGasPrice(\n MemoryUserOp memory mUserOp\n ) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = mUserOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = mUserOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n function getOffsetOfMemoryBytes(\n bytes memory data\n ) internal pure returns (uint256 offset) {\n assembly {\n offset := data\n }\n }\n\n function getMemoryBytesFromOffset(\n uint256 offset\n ) internal pure returns (bytes memory data) {\n assembly {\n data := offset\n }\n }\n\n //place the NUMBER opcode in the code.\n // this is used as a marker during simulation, as this OP is completely banned from the simulated code of the\n // account and paymaster.\n function numberMarker() internal view {\n assembly {\n mstore(0, number())\n }\n }\n}\n" + }, + "contracts/aa-4337/core/Helpers.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable no-inline-assembly */\n\n/**\n * returned data from validateUserOp.\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\n * @param aggregator - address(0) - the account validated the signature by itself.\n * address(1) - the account failed to validate the signature.\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\n * @param validAfter - this UserOp is valid only after this timestamp.\n * @param validaUntil - this UserOp is valid only up to this timestamp.\n */\nstruct ValidationData {\n address aggregator;\n uint48 validAfter;\n uint48 validUntil;\n}\n\n//extract sigFailed, validAfter, validUntil.\n// also convert zero validUntil to type(uint48).max\nfunction _parseValidationData(\n uint validationData\n) pure returns (ValidationData memory data) {\n address aggregator = address(uint160(validationData));\n uint48 validUntil = uint48(validationData >> 160);\n if (validUntil == 0) {\n validUntil = type(uint48).max;\n }\n uint48 validAfter = uint48(validationData >> (48 + 160));\n return ValidationData(aggregator, validAfter, validUntil);\n}\n\n// intersect account and paymaster ranges.\nfunction _intersectTimeRange(\n uint256 validationData,\n uint256 paymasterValidationData\n) pure returns (ValidationData memory) {\n ValidationData memory accountValidationData = _parseValidationData(\n validationData\n );\n ValidationData memory pmValidationData = _parseValidationData(\n paymasterValidationData\n );\n address aggregator = accountValidationData.aggregator;\n if (aggregator == address(0)) {\n aggregator = pmValidationData.aggregator;\n }\n uint48 validAfter = accountValidationData.validAfter;\n uint48 validUntil = accountValidationData.validUntil;\n uint48 pmValidAfter = pmValidationData.validAfter;\n uint48 pmValidUntil = pmValidationData.validUntil;\n\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\n return ValidationData(aggregator, validAfter, validUntil);\n}\n\n/**\n * helper to pack the return value for validateUserOp\n * @param data - the ValidationData to pack\n */\nfunction _packValidationData(\n ValidationData memory data\n) pure returns (uint256) {\n return\n uint160(data.aggregator) |\n (uint256(data.validUntil) << 160) |\n (uint256(data.validAfter) << (160 + 48));\n}\n\n/**\n * helper to pack the return value for validateUserOp, when not using an aggregator\n * @param sigFailed - true for signature failure, false for success\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\n * @param validAfter first timestamp this UserOperation is valid\n */\nfunction _packValidationData(\n bool sigFailed,\n uint48 validUntil,\n uint48 validAfter\n) pure returns (uint256) {\n return\n (sigFailed ? 1 : 0) |\n (uint256(validUntil) << 160) |\n (uint256(validAfter) << (160 + 48));\n}\n\n/**\n * keccak function over calldata.\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\n */\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\n assembly {\n let mem := mload(0x40)\n let len := data.length\n calldatacopy(mem, data.offset, len)\n ret := keccak256(mem, len)\n }\n}\n" + }, + "contracts/aa-4337/core/NonceManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\nimport \"../interfaces/IEntryPoint.sol\";\n\n/**\n * nonce management functionality\n */\ncontract NonceManager is INonceManager {\n /**\n * The next valid sequence number for a given nonce key.\n */\n mapping(address => mapping(uint192 => uint256)) public nonceSequenceNumber;\n\n function getNonce(\n address sender,\n uint192 key\n ) public view override returns (uint256 nonce) {\n return nonceSequenceNumber[sender][key] | (uint256(key) << 64);\n }\n\n // allow an account to manually increment its own nonce.\n // (mainly so that during construction nonce can be made non-zero,\n // to \"absorb\" the gas cost of first nonce increment to 1st transaction (construction),\n // not to 2nd transaction)\n function incrementNonce(uint192 key) public override {\n nonceSequenceNumber[msg.sender][key]++;\n }\n\n /**\n * validate nonce uniqueness for this account.\n * called just after validateUserOp()\n */\n function _validateAndUpdateNonce(\n address sender,\n uint256 nonce\n ) internal returns (bool) {\n uint192 key = uint192(nonce >> 64);\n uint64 seq = uint64(nonce);\n return nonceSequenceNumber[sender][key]++ == seq;\n }\n}\n" + }, + "contracts/aa-4337/core/SenderCreator.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/**\n * helper contract for EntryPoint, to call userOp.initCode from a \"neutral\" address,\n * which is explicitly not the entryPoint itself.\n */\ncontract SenderCreator {\n /**\n * call the \"initCode\" factory to create and return the sender account address\n * @param initCode the initCode value from a UserOp. contains 20 bytes of factory address, followed by calldata\n * @return sender the returned address of the created account, or zero address on failure.\n */\n function createSender(\n bytes calldata initCode\n ) external returns (address sender) {\n address factory = address(bytes20(initCode[0:20]));\n bytes memory initCallData = initCode[20:];\n bool success;\n /* solhint-disable no-inline-assembly */\n assembly {\n success := call(\n gas(),\n factory,\n 0,\n add(initCallData, 0x20),\n mload(initCallData),\n 0,\n 32\n )\n sender := mload(0)\n }\n if (!success) {\n sender = address(0);\n }\n }\n}\n" + }, + "contracts/aa-4337/core/StakeManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity 0.8.21;\n\nimport \"../interfaces/IStakeManager.sol\";\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable not-rely-on-time */\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by a paymaster.\n */\nabstract contract StakeManager is IStakeManager {\n /// maps paymaster to their deposits and stakes\n mapping(address => DepositInfo) public deposits;\n\n /// @inheritdoc IStakeManager\n function getDepositInfo(\n address account\n ) public view returns (DepositInfo memory info) {\n return deposits[account];\n }\n\n // internal method to return just the stake info\n function _getStakeInfo(\n address addr\n ) internal view returns (StakeInfo memory info) {\n DepositInfo storage depositInfo = deposits[addr];\n info.stake = depositInfo.stake;\n info.unstakeDelaySec = depositInfo.unstakeDelaySec;\n }\n\n /// return the deposit (for gas payment) of the account\n function balanceOf(address account) public view returns (uint256) {\n return deposits[account].deposit;\n }\n\n receive() external payable {\n depositTo(msg.sender);\n }\n\n function _incrementDeposit(address account, uint256 amount) internal {\n DepositInfo storage info = deposits[account];\n uint256 newAmount = info.deposit + amount;\n require(newAmount <= type(uint112).max, \"deposit overflow\");\n info.deposit = uint112(newAmount);\n }\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) public payable {\n _incrementDeposit(account, msg.value);\n DepositInfo storage info = deposits[account];\n emit Deposited(account, info.deposit);\n }\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 unstakeDelaySec) public payable {\n DepositInfo storage info = deposits[msg.sender];\n require(unstakeDelaySec > 0, \"must specify unstake delay\");\n require(\n unstakeDelaySec >= info.unstakeDelaySec,\n \"cannot decrease unstake time\"\n );\n uint256 stake = info.stake + msg.value;\n require(stake > 0, \"no stake specified\");\n require(stake <= type(uint112).max, \"stake overflow\");\n deposits[msg.sender] = DepositInfo(\n info.deposit,\n true,\n uint112(stake),\n unstakeDelaySec,\n 0\n );\n emit StakeLocked(msg.sender, stake, unstakeDelaySec);\n }\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external {\n DepositInfo storage info = deposits[msg.sender];\n require(info.unstakeDelaySec != 0, \"not staked\");\n require(info.staked, \"already unstaking\");\n uint48 withdrawTime = uint48(block.timestamp) + info.unstakeDelaySec;\n info.withdrawTime = withdrawTime;\n info.staked = false;\n emit StakeUnlocked(msg.sender, withdrawTime);\n }\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external {\n DepositInfo storage info = deposits[msg.sender];\n uint256 stake = info.stake;\n require(stake > 0, \"No stake to withdraw\");\n require(info.withdrawTime > 0, \"must call unlockStake() first\");\n require(\n info.withdrawTime <= block.timestamp,\n \"Stake withdrawal is not due\"\n );\n info.unstakeDelaySec = 0;\n info.withdrawTime = 0;\n info.stake = 0;\n emit StakeWithdrawn(msg.sender, withdrawAddress, stake);\n (bool success, ) = withdrawAddress.call{value: stake}(\"\");\n require(success, \"failed to withdraw stake\");\n }\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(\n address payable withdrawAddress,\n uint256 withdrawAmount\n ) external {\n DepositInfo storage info = deposits[msg.sender];\n require(withdrawAmount <= info.deposit, \"Withdraw amount too large\");\n info.deposit = uint112(info.deposit - withdrawAmount);\n emit Withdrawn(msg.sender, withdrawAddress, withdrawAmount);\n (bool success, ) = withdrawAddress.call{value: withdrawAmount}(\"\");\n require(success, \"failed to withdraw\");\n }\n}\n" + }, + "contracts/aa-4337/interfaces/IAccount.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\ninterface IAccount {\n /**\n * Validate user's signature and nonce\n * the entryPoint will make the call to the recipient only if this validation call returns successfully.\n * signature failure should be reported by returning SIG_VALIDATION_FAILED (1).\n * This allows making a \"simulation call\" without a valid signature\n * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure.\n *\n * @dev Must validate caller is the entryPoint.\n * Must validate the signature and nonce\n * @param userOp the operation that is about to be executed.\n * @param userOpHash hash of the user's request data. can be used as the basis for signature.\n * @param missingAccountFunds missing funds on the account's deposit in the entrypoint.\n * This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call.\n * The excess is left as a deposit in the entrypoint, for future calls.\n * can be withdrawn anytime using \"entryPoint.withdrawTo()\"\n * In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero.\n * @return validationData packaged ValidationData structure. use `_packValidationData` and `_unpackValidationData` to encode and decode\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * If an account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validateUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 missingAccountFunds\n ) external returns (uint256 validationData);\n}\n" + }, + "contracts/aa-4337/interfaces/IAggregator.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * Aggregated Signatures validator.\n */\ninterface IAggregator {\n /**\n * validate aggregated signature.\n * revert if the aggregated signature does not match the given list of operations.\n */\n function validateSignatures(\n UserOperation[] calldata userOps,\n bytes calldata signature\n ) external view;\n\n /**\n * validate signature of a single userOp\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\n * @param userOp the userOperation received from the user.\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\n * (usually empty, unless account and aggregator support some kind of \"multisig\"\n */\n function validateUserOpSignature(\n UserOperation calldata userOp\n ) external view returns (bytes memory sigForUserOp);\n\n /**\n * aggregate multiple signatures into a single value.\n * This method is called off-chain to calculate the signature to pass with handleOps()\n * bundler MAY use optimized custom code perform this aggregation\n * @param userOps array of UserOperations to collect the signatures from.\n * @return aggregatedSignature the aggregated signature\n */\n function aggregateSignatures(\n UserOperation[] calldata userOps\n ) external view returns (bytes memory aggregatedSignature);\n}\n" + }, + "contracts/aa-4337/interfaces/IEntryPoint.sol": { + "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n/* solhint-disable reason-string */\n\nimport \"./UserOperation.sol\";\nimport \"./IStakeManager.sol\";\nimport \"./IAggregator.sol\";\nimport \"./INonceManager.sol\";\n\ninterface IEntryPoint is IStakeManager, INonceManager {\n /***\n * An event emitted after each successful request\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\n * @param sender - the account that generates this request.\n * @param paymaster - if non-null, the paymaster that pays for this request.\n * @param nonce - the nonce value from the request.\n * @param success - true if the sender transaction succeeded, false if reverted.\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\n */\n event UserOperationEvent(\n bytes32 indexed userOpHash,\n address indexed sender,\n address indexed paymaster,\n uint256 nonce,\n bool success,\n uint256 actualGasCost,\n uint256 actualGasUsed\n );\n\n /**\n * account \"sender\" was deployed.\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\n * @param sender the account that is deployed\n * @param factory the factory used to deploy this account (in the initCode)\n * @param paymaster the paymaster used by this UserOp\n */\n event AccountDeployed(\n bytes32 indexed userOpHash,\n address indexed sender,\n address factory,\n address paymaster\n );\n\n /**\n * An event emitted if the UserOperation \"callData\" reverted with non-zero length\n * @param userOpHash the request unique identifier.\n * @param sender the sender of this request\n * @param nonce the nonce used in the request\n * @param revertReason - the return bytes from the (reverted) call to \"callData\".\n */\n event UserOperationRevertReason(\n bytes32 indexed userOpHash,\n address indexed sender,\n uint256 nonce,\n bytes revertReason\n );\n\n /**\n * an event emitted by handleOps(), before starting the execution loop.\n * any event emitted before this event, is part of the validation.\n */\n event BeforeExecution();\n\n /**\n * signature aggregator used by the following UserOperationEvents within this bundle.\n */\n event SignatureAggregatorChanged(address indexed aggregator);\n\n /**\n * a custom revert error of handleOps, to identify the offending op.\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\n * @param reason - revert reason\n * The string starts with a unique code \"AAmn\", where \"m\" is \"1\" for factory, \"2\" for account and \"3\" for paymaster issues,\n * so a failure can be attributed to the correct entity.\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\n */\n error FailedOp(uint256 opIndex, string reason);\n\n /**\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\n */\n error SignatureValidationFailed(address aggregator);\n\n /**\n * Successful result from simulateValidation.\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n */\n error ValidationResult(\n ReturnInfo returnInfo,\n StakeInfo senderInfo,\n StakeInfo factoryInfo,\n StakeInfo paymasterInfo\n );\n\n /**\n * Successful result from simulateValidation, if the account returns a signature aggregator\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\n * bundler MUST use it to verify the signature, or reject the UserOperation\n */\n error ValidationResultWithAggregation(\n ReturnInfo returnInfo,\n StakeInfo senderInfo,\n StakeInfo factoryInfo,\n StakeInfo paymasterInfo,\n AggregatorStakeInfo aggregatorInfo\n );\n\n /**\n * return value of getSenderAddress\n */\n error SenderAddressResult(address sender);\n\n /**\n * return value of simulateHandleOp\n */\n error ExecutionResult(\n uint256 preOpGas,\n uint256 paid,\n uint48 validAfter,\n uint48 validUntil,\n bool targetSuccess,\n bytes targetResult\n );\n\n //UserOps handled, per aggregator\n struct UserOpsPerAggregator {\n UserOperation[] userOps;\n // aggregator address\n IAggregator aggregator;\n // aggregated signature\n bytes signature;\n }\n\n /**\n * Execute a batch of UserOperation.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(\n UserOperation[] calldata ops,\n address payable beneficiary\n ) external;\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) external;\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(\n UserOperation calldata userOp\n ) external view returns (bytes32);\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external;\n\n /**\n * gas and return values during simulation\n * @param preOpGas the gas used for validation (including preValidationGas)\n * @param prefund the required prefund for this operation\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\n */\n struct ReturnInfo {\n uint256 preOpGas;\n uint256 prefund;\n bool sigFailed;\n uint48 validAfter;\n uint48 validUntil;\n bytes paymasterContext;\n }\n\n /**\n * returned aggregated signature info.\n * the aggregator returned by the account, and its current stake.\n */\n struct AggregatorStakeInfo {\n address aggregator;\n StakeInfo stakeInfo;\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes memory initCode) external;\n\n /**\n * simulate full execution of a UserOperation (including both validation and target execution)\n * this method will always revert with \"ExecutionResult\".\n * it performs full validation of the UserOperation, but ignores signature error.\n * an optional target address is called after the userop succeeds, and its value is returned\n * (before the entire call is reverted)\n * Note that in order to collect the the success/failure of the target call, it must be executed\n * with trace enabled to track the emitted events.\n * @param op the UserOperation to simulate\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\n * are set to the return from that call.\n * @param targetCallData callData to pass to target address\n */\n function simulateHandleOp(\n UserOperation calldata op,\n address target,\n bytes calldata targetCallData\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/INonceManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\ninterface INonceManager {\n /**\n * Return the next nonce for this sender.\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\n * But UserOp with different keys can come with arbitrary order.\n *\n * @param sender the account address\n * @param key the high 192 bit of the nonce\n * @return nonce a full nonce to pass for next UserOp with this sender.\n */\n function getNonce(\n address sender,\n uint192 key\n ) external view returns (uint256 nonce);\n\n /**\n * Manually increment the nonce of the sender.\n * This method is exposed just for completeness..\n * Account does NOT need to call it, neither during validation, nor elsewhere,\n * as the EntryPoint will update the nonce regardless.\n * Possible use-case is call it with various keys to \"initialize\" their nonces to one, so that future\n * UserOperations will not pay extra for the first transaction with a given key.\n */\n function incrementNonce(uint192 key) external;\n}\n" + }, + "contracts/aa-4337/interfaces/IPaymaster.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * the interface exposed by a paymaster contract, who agrees to pay the gas for user's operations.\n * a paymaster must hold a stake to cover the required entrypoint stake and also the gas for the transaction.\n */\ninterface IPaymaster {\n enum PostOpMode {\n opSucceeded, // user op succeeded\n opReverted, // user op reverted. still has to pay for gas.\n postOpReverted //user op succeeded, but caused postOp to revert. Now it's a 2nd call, after user's op was deliberately reverted.\n }\n\n /**\n * payment validation: check if paymaster agrees to pay.\n * Must verify sender is the entryPoint.\n * Revert to reject this request.\n * Note that bundlers will reject this method if it changes the state, unless the paymaster is trusted (whitelisted)\n * The paymaster pre-pays using its deposit, and receive back a refund after the postOp method returns.\n * @param userOp the user operation\n * @param userOpHash hash of the user's request data.\n * @param maxCost the maximum cost of this transaction (based on maximum gas and gas price from userOp)\n * @return context value to send to a postOp\n * zero length to signify postOp is not required.\n * @return validationData signature and time-range of this operation, encoded the same as the return value of validateUserOperation\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validatePaymasterUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 maxCost\n ) external returns (bytes memory context, uint256 validationData);\n\n /**\n * post-operation handler.\n * Must verify sender is the entryPoint\n * @param mode enum with the following options:\n * opSucceeded - user operation succeeded.\n * opReverted - user op reverted. still has to pay for gas.\n * postOpReverted - user op succeeded, but caused postOp (in mode=opSucceeded) to revert.\n * Now this is the 2nd call, after user's op was deliberately reverted.\n * @param context - the context value returned by validatePaymasterUserOp\n * @param actualGasCost - actual gas used so far (without this postOp call).\n */\n function postOp(\n PostOpMode mode,\n bytes calldata context,\n uint256 actualGasCost\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/IStakeManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.12;\n\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by the staked entity.\n */\ninterface IStakeManager {\n event Deposited(address indexed account, uint256 totalDeposit);\n\n event Withdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /// Emitted when stake or unstake delay are modified\n event StakeLocked(\n address indexed account,\n uint256 totalStaked,\n uint256 unstakeDelaySec\n );\n\n /// Emitted once a stake is scheduled for withdrawal\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\n\n event StakeWithdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /**\n * @param deposit the entity's deposit\n * @param staked true if this entity is staked.\n * @param stake actual amount of ether staked for this entity.\n * @param unstakeDelaySec minimum delay to withdraw the stake.\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\n * and the rest fit into a 2nd cell.\n * 112 bit allows for 10^15 eth\n * 48 bit for full timestamp\n * 32 bit allows 150 years for unstake delay\n */\n struct DepositInfo {\n uint112 deposit;\n bool staked;\n uint112 stake;\n uint32 unstakeDelaySec;\n uint48 withdrawTime;\n }\n\n //API struct used by getStakeInfo and simulateValidation\n struct StakeInfo {\n uint256 stake;\n uint256 unstakeDelaySec;\n }\n\n /// @return info - full deposit information of given account\n function getDepositInfo(\n address account\n ) external view returns (DepositInfo memory info);\n\n /// @return the deposit (for gas payment) of the account\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) external payable;\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 _unstakeDelaySec) external payable;\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external;\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external;\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(\n address payable withdrawAddress,\n uint256 withdrawAmount\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/UserOperation.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable no-inline-assembly */\n\nimport {calldataKeccak} from \"../core/Helpers.sol\";\n\n/**\n * User Operation struct\n * @param sender the sender account of this request.\n * @param nonce unique value the sender uses to verify it is not a replay.\n * @param initCode if set, the account contract will be created by this constructor/\n * @param callData the method call to execute on this account.\n * @param callGasLimit the gas limit passed to the callData method call.\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\n * @param maxFeePerGas same as EIP-1559 gas parameter.\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\n */\nstruct UserOperation {\n address sender;\n uint256 nonce;\n bytes initCode;\n bytes callData;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n bytes paymasterAndData;\n bytes signature;\n}\n\n/**\n * Utility functions helpful when working with UserOperation structs.\n */\nlibrary UserOperationLib {\n function getSender(\n UserOperation calldata userOp\n ) internal pure returns (address) {\n address data;\n //read sender from userOp, which is first userOp member (saves 800 gas...)\n assembly {\n data := calldataload(userOp)\n }\n return address(uint160(data));\n }\n\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\n // pay above what he signed for.\n function gasPrice(\n UserOperation calldata userOp\n ) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function pack(\n UserOperation calldata userOp\n ) internal pure returns (bytes memory ret) {\n address sender = getSender(userOp);\n uint256 nonce = userOp.nonce;\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\n bytes32 hashCallData = calldataKeccak(userOp.callData);\n uint256 callGasLimit = userOp.callGasLimit;\n uint256 verificationGasLimit = userOp.verificationGasLimit;\n uint256 preVerificationGas = userOp.preVerificationGas;\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\n\n return\n abi.encode(\n sender,\n nonce,\n hashInitCode,\n hashCallData,\n callGasLimit,\n verificationGasLimit,\n preVerificationGas,\n maxFeePerGas,\n maxPriorityFeePerGas,\n hashPaymasterAndData\n );\n }\n\n function hash(\n UserOperation calldata userOp\n ) internal pure returns (bytes32) {\n return keccak256(pack(userOp));\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n}\n" + }, + "contracts/aa-4337/utils/Exec.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.5 <0.9.0;\n\n// solhint-disable no-inline-assembly\n\n/**\n * Utility functions helpful when making different kinds of contract calls in Solidity.\n */\nlibrary Exec {\n function call(\n address to,\n uint256 value,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := call(\n txGas,\n to,\n value,\n add(data, 0x20),\n mload(data),\n 0,\n 0\n )\n }\n }\n\n function staticcall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal view returns (bool success) {\n assembly {\n success := staticcall(txGas, to, add(data, 0x20), mload(data), 0, 0)\n }\n }\n\n function delegateCall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := delegatecall(\n txGas,\n to,\n add(data, 0x20),\n mload(data),\n 0,\n 0\n )\n }\n }\n\n // get returned data from last call or calldelegate\n function getReturnData(\n uint256 maxLen\n ) internal pure returns (bytes memory returnData) {\n assembly {\n let len := returndatasize()\n if gt(len, maxLen) {\n len := maxLen\n }\n let ptr := mload(0x40)\n mstore(0x40, add(ptr, add(len, 0x20)))\n mstore(ptr, len)\n returndatacopy(add(ptr, 0x20), 0, len)\n returnData := ptr\n }\n }\n\n // revert with explicit byte array (probably reverted info from call)\n function revertWithData(bytes memory returnData) internal pure {\n assembly {\n revert(add(returnData, 32), mload(returnData))\n }\n }\n\n function callAndRevert(\n address to,\n bytes memory data,\n uint256 maxLen\n ) internal {\n bool success = call(to, 0, data, gasleft());\n if (!success) {\n revertWithData(getReturnData(maxLen));\n }\n }\n}\n" + }, + "contracts/Barz.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"./libraries/LibDiamond.sol\";\nimport {IBarz} from \"./interfaces/IBarz.sol\";\n\n/**\n * @title Barz\n * @dev A diamond proxy wallet with a modular & upgradeable architecture\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract Barz is IBarz {\n /**\n * @notice Initializes Barz with the given parameters. Barz account is intended to be created from Barz Factory for stable deployment.\n * @dev This method makes a delegate call to account facet and account facet handles the initialization.\n * With modular architecture, Barz encompasses wide spectrum of architecture and logic.\n * The only requirement is account facet to comply with initialize() interface.\n * Barz doesn't include built-in functions and is a full proxy, for maximum extensibility and modularity.\n * @param _accountFacet Address of Account Facet in charge of the Barz initialization\n * @param _verificationFacet Address of Verification Facet for verifying the signature. Could be any signature scheme\n * @param _entryPoint Address of Entry Point contract\n * @param _facetRegistry Address of Facet Registry. Facet Registry is a registry holding trusted facets that could be added to user's wallet\n * @param _defaultFallBack Address of Default FallBack Handler. Middleware contract for more efficient deployment\n * @param _ownerPublicKey Bytes of Owner Public Key using for initialization\n */\n constructor(\n address _accountFacet,\n address _verificationFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallBack,\n bytes memory _ownerPublicKey\n ) payable {\n bytes memory initCall = abi.encodeWithSignature(\n \"initialize(address,address,address,address,bytes)\",\n _verificationFacet,\n _entryPoint,\n _facetRegistry,\n _defaultFallBack,\n _ownerPublicKey\n );\n (bool success, bytes memory result) = _accountFacet.delegatecall(\n initCall\n );\n if (!success || uint256(bytes32(result)) != 1) {\n revert Barz__InitializationFailure();\n }\n }\n\n /**\n * @notice Fallback function for Barz complying with Diamond Standard with customization of adding Default Fallback Handler\n * @dev Find facet for function that is called and execute the function if a facet is found and return any value.\n */\n fallback() external payable {\n LibDiamond.DiamondStorage storage ds;\n bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION;\n // get diamond storage\n assembly {\n ds.slot := position\n }\n // get facet from function selector\n address facet = address(bytes20(ds.facets[msg.sig]));\n if (facet == address(0))\n facet = ds.defaultFallbackHandler.facetAddress(msg.sig);\n require(facet != address(0), \"Barz: Function does not exist\");\n // Execute external function from facet using delegatecall and return any value.\n assembly {\n // copy function selector and any arguments\n calldatacopy(0, 0, calldatasize())\n // execute function call using the facet\n let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)\n // get any return value\n returndatacopy(0, 0, returndatasize())\n // return any return value or error back to the caller\n switch result\n case 0 {\n revert(0, returndatasize())\n }\n default {\n return(0, returndatasize())\n }\n }\n }\n\n /**\n * @notice Receive function to receive native token without data\n */\n receive() external payable {}\n}\n" + }, + "contracts/BarzFactory.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Barz} from \"./Barz.sol\";\nimport {IBarzFactory} from \"./interfaces/IBarzFactory.sol\";\n\n/**\n * @title Barz Factory\n * @dev Contract to easily deploy Barz to a pre-computed address with a single call\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract BarzFactory is IBarzFactory {\n event BarzDeployed(address);\n\n address public immutable accountFacet;\n address public immutable entryPoint;\n address public immutable facetRegistry;\n address public immutable defaultFallback;\n\n /**\n * @notice Sets the initialization data for Barz contract initialization\n * @param _accountFacet Account Facet to be used to create Barz\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\n * @param _facetRegistry Facet Registry to be used to create Barz\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\n */\n constructor(\n address _accountFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallback\n ) {\n accountFacet = _accountFacet;\n entryPoint = _entryPoint;\n facetRegistry = _facetRegistry;\n defaultFallback = _defaultFallback;\n }\n\n /**\n * @notice Creates the Barz with a single call. It creates the Barz contract with the givent verification facet\n * @param _verificationFacet Address of verification facet used for creating the barz account\n * @param _owner Public Key of the owner to initialize barz account\n * @param _salt Salt used for deploying barz with create2\n * @return barz Instance of Barz contract deployed with the given parameters\n */\n function createAccount(\n address _verificationFacet,\n bytes calldata _owner,\n uint256 _salt\n ) external override returns (Barz barz) {\n address addr = getAddress(_verificationFacet, _owner, _salt);\n uint codeSize = addr.code.length;\n if (codeSize > 0) {\n return Barz(payable(addr));\n }\n barz = new Barz{salt: bytes32(_salt)}(\n accountFacet,\n _verificationFacet,\n entryPoint,\n facetRegistry,\n defaultFallback,\n _owner\n );\n emit BarzDeployed(address(barz));\n }\n\n /**\n * @notice Calculates the address of Barz with the given parameters\n * @param _verificationFacet Address of verification facet used for creating the barz account\n * @param _owner Public Key of the owner to initialize barz account\n * @param _salt Salt used for deploying barz with create2\n * @return barzAddress Precalculated Barz address\n */\n function getAddress(\n address _verificationFacet,\n bytes calldata _owner,\n uint256 _salt\n ) public view override returns (address barzAddress) {\n bytes memory bytecode = getBytecode(\n accountFacet,\n _verificationFacet,\n entryPoint,\n facetRegistry,\n defaultFallback,\n _owner\n );\n bytes32 hash = keccak256(\n abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(bytecode)\n )\n );\n barzAddress = address(uint160(uint256(hash)));\n }\n\n /**\n * @notice Returns the bytecode of Barz with the given parameter\n * @param _accountFacet Account Facet to be used to create Barz\n * @param _verificationFacet Verification Facet to be used to create Barz\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\n * @param _facetRegistry Facet Registry to be used to create Barz\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\n * @param _ownerPublicKey Public Key of owner to be used to initialize Barz ownership\n * @return barzBytecode Bytecode of Barz\n */\n function getBytecode(\n address _accountFacet,\n address _verificationFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallback,\n bytes calldata _ownerPublicKey\n ) public pure override returns (bytes memory barzBytecode) {\n bytes memory bytecode = type(Barz).creationCode;\n barzBytecode = abi.encodePacked(\n bytecode,\n abi.encode(\n _accountFacet,\n _verificationFacet,\n _entryPoint,\n _facetRegistry,\n _defaultFallback,\n _ownerPublicKey\n )\n );\n }\n\n /**\n * @notice Returns the creation code of the Barz contract\n * @return creationCode Creation code of Barz\n */\n function getCreationCode()\n public\n pure\n override\n returns (bytes memory creationCode)\n {\n creationCode = type(Barz).creationCode;\n }\n}\n" + }, + "contracts/facets/AccountFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {UserOperation} from \"../aa-4337/interfaces/UserOperation.sol\";\nimport {IEntryPoint} from \"../aa-4337/interfaces/IEntryPoint.sol\";\nimport {BaseAccount} from \"../aa-4337/core/BaseAccount.sol\";\nimport {LibAppStorage, BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {IFacetRegistry} from \"../infrastructure/interfaces/IFacetRegistry.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {IERC1271} from \"../interfaces/ERC/IERC1271.sol\";\nimport {IAccountFacet} from \"./interfaces/IAccountFacet.sol\";\n\n/**\n * @title Account Facet\n * @dev Account module contract that provides the account features and initialization of signer\n * compatible with EIP-1271 & EIP-4337\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract AccountFacet is BarzStorage, BaseAccount, IAccountFacet {\n using ECDSA for bytes32;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceAccountInitialize();\n }\n\n /**\n * @notice Returns the address of EntryPoint contract registered to Barz account\n */\n function entryPoint() public view override returns (IEntryPoint) {\n return s.entryPoint;\n }\n\n /**\n * @notice Initializes the initial storage of the Barz contract.\n * @dev This method can only be called during the initialization or signature migration.\n * If the proxy contract was created without initialization, anyone can call initialize.\n * Barz calls initialize in constructor in an atomic transaction during deployment\n * @param _verificationFacet Facet contract handling the verificationi\n * @param _anEntryPoint Entrypoint contract defined in EIP-4337 handling the flow of UserOp\n * @param _facetRegistry Registry of Facets that hold all facet information\n * @param _defaultFallBackHandler Middleware contract for default facets\n * @param _ownerPublicKey Bytes of owner public key\n */\n function initialize(\n address _verificationFacet,\n address _anEntryPoint,\n address _facetRegistry,\n address _defaultFallBackHandler,\n bytes calldata _ownerPublicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceAccountInitialize();\n s.entryPoint = IEntryPoint(_anEntryPoint);\n s.facetRegistry = IFacetRegistry(_facetRegistry);\n LibDiamond.diamondStorage().defaultFallbackHandler = IDiamondLoupe(\n _defaultFallBackHandler\n );\n\n _cutDiamondAccountFacet(_verificationFacet);\n\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n _ownerPublicKey\n );\n // Every Verification Facet should comply with initializeSigner(bytes)\n // to be compatible with the Barz contract(for initialization)\n (bool success, bytes memory result) = _verificationFacet.delegatecall(\n initCall\n );\n if (!success || uint256(bytes32(result)) != 1) {\n revert AccountFacet__InitializationFailure();\n }\n\n initSuccess = 1;\n emit AccountInitialized(s.entryPoint, _ownerPublicKey);\n }\n\n function _cutDiamondAccountFacet(address _verificationFacet) internal {\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](1);\n\n bytes4 ownerVerificationFuncSelector = IVerificationFacet(\n _verificationFacet\n ).validateOwnerSignatureSelector();\n\n bytes4[] memory verificationFunctionSelectors = new bytes4[](3);\n verificationFunctionSelectors[0] = IERC1271.isValidSignature.selector;\n verificationFunctionSelectors[1] = ownerVerificationFuncSelector;\n verificationFunctionSelectors[2] = IVerificationFacet.owner.selector;\n cut[0] = IDiamondCut.FacetCut({\n facetAddress: _verificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: verificationFunctionSelectors\n });\n\n LibDiamond.diamondCut(cut, address(0), \"\");\n }\n\n /**\n * @notice Calls the destination with inputted calldata and value from EntryPoint\n * @dev This method executes the calldata coming from the EntryPoint.\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\n * @param _dest Address of destination where the call will be forwarded to\n * @param _value Amount of native coin the owner is willing to send(e.g. ETH, BNB)\n * @param _func Bytes of calldata to execute in the destination address\n */\n function execute(\n address _dest,\n uint256 _value,\n bytes calldata _func\n ) external override onlyWhenUnlocked {\n _requireFromEntryPoint();\n _call(_dest, _value, _func);\n }\n\n /**\n * @notice Batch calls the destination with inputted calldata and value from EntryPoint\n * @dev This method batch executes the calldata coming from the EntryPoint.\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\n * @param _dest Array of addresses of destination where the call will be forwarded to\n * @param _value Array of amount of native coin the owner is willing to send(e.g. ETH, BNB)\n * @param _func Array of bytes of calldata to execute in the destination address\n */\n function executeBatch(\n address[] calldata _dest,\n uint256[] calldata _value,\n bytes[] calldata _func\n ) external override onlyWhenUnlocked {\n _requireFromEntryPoint();\n uint256 destLength = _dest.length;\n require(\n destLength == _func.length && destLength == _value.length,\n \"wrong array lengths\"\n );\n for (uint256 i; i < destLength; ) {\n _call(_dest[i], _value[i], _func[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Validates the signature field of UserOperation\n * @dev This method validates if the signature of UserOp is indeed valid by delegating the call to Verification Facet\n * Barz makes a call to the pre-registered Verification Facet address in App Storage\n * @param _userOp UserOperation from owner to be validated\n * @param _userOpHash Hash of UserOperation given from the EntryPoint contract\n */\n function _validateSignature(\n UserOperation calldata _userOp,\n bytes32 _userOpHash\n ) internal override returns (uint256 validationData) {\n // Get Facet with Function Selector\n address facet = LibLoupe.facetAddress(s.validateOwnerSignatureSelector);\n if (facet == address(0))\n revert AccountFacet__NonExistentVerificationFacet();\n\n // Make function call to VerificationFacet\n bytes memory validateCall = abi.encodeWithSelector(\n s.validateOwnerSignatureSelector,\n _userOp,\n _userOpHash\n );\n (bool success, bytes memory result) = facet.delegatecall(validateCall);\n if (!success) revert AccountFacet__CallNotSuccessful();\n validationData = uint256(bytes32(result));\n if (validationData == 0) emit VerificationSuccess(_userOpHash);\n else emit VerificationFailure(_userOpHash);\n }\n\n /**\n * @notice Calls the target with the inputted value and calldata\n * @dev This method is the actual function in Barz that makes a call with an arbitrary owner-given data\n * @param _target Address of the destination contract which the call is getting forwarded to\n * @param _value Amount of Native coin the owner is wanting to make in this call\n * @param _data Calldata the owner is forwarding together in the call e.g. Swap/Token Transfer\n */\n function _call(\n address _target,\n uint256 _value,\n bytes memory _data\n ) internal {\n if (_checkRestrictions(_target, _value, _data) == 1)\n revert AccountFacet__RestrictionsFailure();\n\n (bool success, bytes memory result) = _target.call{value: _value}(\n _data\n );\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n }\n\n /**\n * @notice Checks restrictions if the restrictions facet exists\n * @dev This method checks if the restrictions facet exists and makes a verification call to an array of restrictions facet\n * @param _target Address the call is getting forwarded to\n * @param _value Amount of native coin the call is sending together with the call\n * @param _data Calldata to trigger execution in target address\n */\n function _checkRestrictions(\n address _target,\n uint256 _value,\n bytes memory _data\n ) internal returns (uint256 result) {\n address facet = LibDiamond.restrictionsFacet();\n // NOTE: No restrictions facet, so restriction validation passes\n if (facet == address(0)) return 0;\n bytes memory call = abi.encodeWithSignature(\n \"verifyRestrictions(address,address,uint256,bytes)\",\n address(this),\n _target,\n _value,\n _data\n );\n (bool success, bytes memory response) = facet.delegatecall(call);\n if (!success) revert AccountFacet__RestrictionsFailure();\n result = uint256(bytes32(response));\n }\n}\n" + }, + "contracts/facets/AccountRecoveryFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibFacetStorage, RecoveryStorage, RecoveryConfig, RecoveryApprovalConfig, ApprovalConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {IAccountRecoveryFacet} from \"./interfaces/IAccountRecoveryFacet.sol\";\n\n/**\n * @title Account Recovery Facet\n * @dev Contract that enables recovery of accounts when owner key is unavailable\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract AccountRecoveryFacet is IAccountRecoveryFacet, Modifiers {\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Approve recovery of account as guardian\n * @dev This method can only be called by guardian and guardian inputs the public key of the new owner\n * When the threshold(majority of guardians) passes, it automatically executes account recovery\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function approveAccountRecovery(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + _getApprovalValidationPeriod()\n );\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit RecoveryApproved(\n _recoveryPublicKey,\n msg.sender,\n approvalValidUntil\n );\n if (\n getRecoveryApprovalCountWithTimeValidity(recoveryPublicKeyHash) >=\n LibGuardian.majorityOfGuardians()\n ) _executeRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Revoke recovery of account as guardian\n * @dev This method can only be called by guardian and guardian inputs the public key of the new owner\n When the threshold(majority of guardians) passes, it automatically revokes account recovery when recovery is pending\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function revokeAccountRecoveryApproval(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n if (\n !rs\n .isNewOwnerApproved[recoveryPublicKeyHash][msg.sender].isApproved ||\n !(block.timestamp <\n rs\n .isNewOwnerApproved[recoveryPublicKeyHash][msg.sender]\n .validUntil)\n ) revert AccountRecoveryFacet__NonExistentApproval();\n\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(false, 0);\n emit RecoveryApprovalRevoked(_recoveryPublicKey, msg.sender);\n }\n\n /**\n * @notice Executes recovery with signatures or on-chain pre-approvals\n * @dev This method validates the signatures of guardians or checks the on-chain pre-approved calls to check if the threshold passes\n * When the threshold passes, account recovery is executed and revert otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _guardians Array of guardians address that are approving the recovery of Account\n * @param _signatures Array of signature bytes that signed the approval hash\n */\n function executeRecovery(\n bytes calldata _recoveryPublicKey,\n address[] calldata _guardians,\n bytes[] calldata _signatures\n ) external override {\n if (_isRecoveryPending())\n revert AccountRecoveryFacet__RecoveryAlreadyOngoing();\n uint256 guardiansLength = _guardians.length;\n if (guardiansLength != _signatures.length)\n revert AccountRecoveryFacet__InvalidArrayLength();\n validateNewOwner(_recoveryPublicKey);\n\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n\n _checkApprover(_guardians);\n _checkDuplicateOnChainApprover(recoveryPublicKeyHash, _guardians);\n\n if (\n guardiansLength +\n getRecoveryApprovalCountWithTimeValidity(\n recoveryPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians()\n ) revert AccountRecoveryFacet__InsufficientGuardians();\n for (uint256 i; i < guardiansLength; ) {\n if (!LibGuardian.isGuardian(_guardians[i]))\n revert AccountRecoveryFacet__InvalidGuardian();\n if (\n !SignatureChecker.isValidSignatureNow(\n _guardians[i],\n recoveryPublicKeyHash,\n _signatures[i]\n )\n ) revert AccountRecoveryFacet__InvalidGuardianSignature();\n unchecked {\n ++i;\n }\n }\n _executeRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Executes recovery of the account. Note that execution and finalization is a different process\n * @dev Executes the recovery and adds recovery data to recovery configuration. Locks the account\n * @param _recoveryPublicKey Public Key of the account for recovery\n */\n function _executeRecovery(bytes memory _recoveryPublicKey) internal {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n ++rs.nonce;\n uint64 executeAfter = uint64(block.timestamp + _getRecoveryPeriod());\n rs.recoveryConfigs[INNER_STRUCT] = RecoveryConfig(\n _recoveryPublicKey,\n executeAfter // NOTE: Remove guardian Count\n );\n LibAppStorage.setLock(\n block.timestamp + _getLockPeriod(),\n AccountRecoveryFacet.executeRecovery.selector\n );\n emit RecoveryExecuted(_recoveryPublicKey, executeAfter);\n }\n\n /**\n * @notice Finalize recovery after recovery pending period. Recovery pending period can be set by user beforehand in SecurityManager\n * @dev This method finalizes recovery and fully changes the ownership of the account to the newly inputted recovery public key\n */\n function finalizeRecovery() external override {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n if (\n uint64(block.timestamp) <=\n rs.recoveryConfigs[INNER_STRUCT].executeAfter\n ) revert AccountRecoveryFacet__RecoveryPeriodNotOver();\n bytes memory recoveryOwner = rs\n .recoveryConfigs[INNER_STRUCT]\n .recoveryPublicKey;\n\n delete rs.recoveryConfigs[INNER_STRUCT];\n\n LibAppStorage.setLock(0, bytes4(0));\n\n LibAppStorage.initiateSignerMigration();\n address verificationFacet = address(\n bytes20(\n LibDiamond.diamondStorage().facets[\n s.validateOwnerSignatureSelector\n ]\n )\n );\n bytes memory uninitCall = abi.encodeWithSignature(\n \"uninitializeSigner()\"\n );\n (bool success, bytes memory result) = verificationFacet.delegatecall(\n uninitCall\n );\n if (!success) revert AccountRecoveryFacet__CallNotSuccesful();\n uint256 validationData = uint256(bytes32(result));\n if (validationData != 1)\n revert AccountRecoveryFacet__SignerUninitializationFailure();\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n recoveryOwner\n );\n (success, result) = verificationFacet.delegatecall(initCall);\n if (!success) revert AccountRecoveryFacet__CallNotSuccesful();\n validationData = uint256(bytes32(result));\n if (validationData != 1)\n revert AccountRecoveryFacet__SignerInitializationFailure();\n LibAppStorage.finalizeSignerMigration();\n emit RecoveryFinalized(recoveryOwner);\n }\n\n /**\n * @notice Approves the cancellation of recovery\n * @dev This method approves the cancellation of recovery when recovery is still pending - waiting for finalization\n * @param _recoveryPublicKey Bytes of public key which is pending for recovery\n */\n function approveCancelRecovery(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"CancelRecovery\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + _getApprovalValidationPeriod()\n );\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit RecoveryCancellationApproved(_recoveryPublicKey, msg.sender);\n if (\n getRecoveryApprovalCountWithTimeValidity(recoveryPublicKeyHash) >=\n LibGuardian.majorityOfGuardians()\n ) {\n _cancelRecovery(_recoveryPublicKey);\n }\n }\n\n /**\n * @notice Hardstops an ongoing recovery\n * @dev This method provides a safety mechanism to protect owners of malicious guardians.\n * Owners can hardstop recovery when an malicious guardians starts the recovery process.\n * @param _signature Signature of the owner that signs the hash to hardstop recovery\n */\n function hardstopRecovery(bytes calldata _signature) external override {\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n \"0\",\n \"HardstopRecovery\"\n );\n if (\n !SignatureChecker.isValidSignatureNow(\n address(this),\n recoveryPublicKeyHash,\n _signature\n )\n ) revert AccountRecoveryFacet__InvalidOwnerSignature();\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n ++rs.nonce;\n delete rs.recoveryConfigs[INNER_STRUCT];\n LibAppStorage.setLock(0, bytes4(0));\n emit RecoveryHardstopped();\n }\n\n /**\n * @notice Cancels recovery with signatures or on-chain pre-approvals\n * @dev This method validates the signatures of guardians or checks the on-chain pre-approved calls to check if the threshold passes\n * When the threshold passes, account recovery is canceled and revert otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _guardians Array of guardians address that are approving the recovery of Account\n * @param _signatures Array of signature bytes that signed the cancellation approval hash\n */\n function cancelRecovery(\n bytes calldata _recoveryPublicKey,\n address[] calldata _guardians,\n bytes[] calldata _signatures\n ) external override {\n uint256 guardiansLength = _guardians.length;\n if (guardiansLength != _signatures.length)\n revert AccountRecoveryFacet__InvalidArrayLength();\n validateNewOwner(_recoveryPublicKey);\n\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"CancelRecovery\"\n );\n\n _checkApprover(_guardians);\n _checkDuplicateOnChainApprover(recoveryPublicKeyHash, _guardians);\n\n if (\n guardiansLength +\n getRecoveryApprovalCountWithTimeValidity(\n recoveryPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians()\n ) revert AccountRecoveryFacet__InsufficientGuardians();\n for (uint256 i; i < guardiansLength; ) {\n if (!LibGuardian.isGuardian(_guardians[i]))\n revert AccountRecoveryFacet__CallerNotGuardian();\n if (\n !SignatureChecker.isValidSignatureNow(\n _guardians[i],\n recoveryPublicKeyHash,\n _signatures[i]\n )\n ) revert AccountRecoveryFacet__InvalidGuardianSignature();\n unchecked {\n ++i;\n }\n }\n _cancelRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Cancel recovery when the recovery is pending. Unlock the account as well\n * @dev This method checks if the recovery is pending and reverts if not pending.\n * It increases the recovery nonce and deletes the recovery information and gets a small portion of gas in return\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function _cancelRecovery(bytes memory _recoveryPublicKey) internal {\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n LibAppStorage.setLock(0, bytes4(0));\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n ++rs.nonce;\n delete rs.recoveryConfigs[INNER_STRUCT];\n emit RecoveryCanceled(_recoveryPublicKey);\n }\n\n /**\n * @notice Validates the format of public key to be used for recovery\n * @dev This method checks if the public key format is correct and reverts otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function validateNewOwner(bytes memory _recoveryPublicKey) public view {\n if (\n !IVerificationFacet(\n LibLoupe.facetAddress(s.validateOwnerSignatureSelector)\n ).isValidKeyType(_recoveryPublicKey)\n ) revert AccountRecoveryFacet__InvalidRecoveryPublicKey();\n }\n\n /**\n * @notice Checks if recovery is currently pending\n * @return isPending Boolean indicating if recovery is pending\n */\n function _isRecoveryPending() internal view returns (bool isPending) {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n isPending = (rs.recoveryConfigs[INNER_STRUCT].executeAfter > 0);\n }\n\n /**\n * @notice Calculate the recovery hash dependent on chain, wallet address, nonce with EIP-191 prefix for safety\n * @dev Returns the keccak256 hash of EIP-191 msg hash packed with public key, salt, nonce, wallet address, etc\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _saltString Salt string to uniquely identify each recovery hash and for security\n * @return recoveryKeyHash Bytes32 string of the recovery hash\n */\n function getApprovalRecoveryKeyHash(\n bytes memory _recoveryPublicKey,\n string memory _saltString\n ) public view override returns (bytes32 recoveryKeyHash) {\n recoveryKeyHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n _recoveryPublicKey,\n _saltString,\n address(this),\n block.chainid,\n LibFacetStorage.recoveryStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Check the onchain approval of guardians and returns the number of guardians that approved\n * @dev Loop through the guardian addresses and returns the number of guardians that approved this recovery hash\n * @param _recoveryPublicKeyHash Bytes hash of newly recovered public key and recovery value of the account\n * @return approvalCount Number of guardians that approved\n */\n function getRecoveryApprovalCountWithTimeValidity(\n bytes32 _recoveryPublicKeyHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n for (uint256 i; i < guardianLength; ) {\n if (isRecoveryApproved(_recoveryPublicKeyHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Checks if the recovery is approved by the given approver\n * @param _recoveryPublicKeyHash Hash of the public key and configuration for recovery\n * @param _approver Address of approver\n * @return isApproved Bool value if recovery hash is approved\n */\n function isRecoveryApproved(\n bytes32 _recoveryPublicKeyHash,\n address _approver\n ) public view override returns (bool isApproved) {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n if (\n rs\n .isNewOwnerApproved[_recoveryPublicKeyHash][_approver].isApproved &&\n block.timestamp <\n rs.isNewOwnerApproved[_recoveryPublicKeyHash][_approver].validUntil\n ) {\n isApproved = true;\n }\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _recoveryPublicKeyHash Hash of recovery information\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _recoveryPublicKeyHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isRecoveryApproved(_recoveryPublicKeyHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert AccountRecoveryFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the lock period of this wallet address from security manager\n * @return lockPeriod value of lock period\n */\n function _getLockPeriod() internal view returns (uint256 lockPeriod) {\n lockPeriod = securityManager.lockPeriodOf(address(this));\n if (lockPeriod == 0) revert AccountRecoveryFacet__InvalidLockPeriod();\n }\n\n /**\n * @notice Returns the lock period of this wallet address from security manager\n * @return recoveryPeriod value of recovery period\n */\n function _getRecoveryPeriod()\n internal\n view\n returns (uint256 recoveryPeriod)\n {\n recoveryPeriod = securityManager.recoveryPeriodOf(address(this));\n if (recoveryPeriod == 0)\n revert AccountRecoveryFacet__InvalidRecoveryPeriod();\n }\n\n /**\n * @notice Returns the approval validation period of this wallet address from security manager\n * @return approvalValidationPeriod value of approval validation period\n */\n function _getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod == 0)\n revert AccountRecoveryFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the recovery nonce of this wallet address from security manager\n * @return nonce value of recovery nonce\n */\n function getRecoveryNonce() public view override returns (uint128 nonce) {\n nonce = LibFacetStorage.recoveryStorage().nonce;\n }\n\n /**\n * @notice Returns the recovery information of the pending recovery\n * @return recoveryConfig value struct of pending recovery\n */\n function getPendingRecovery()\n public\n view\n override\n returns (RecoveryConfig memory recoveryConfig)\n {\n recoveryConfig = LibFacetStorage.recoveryStorage().recoveryConfigs[\n INNER_STRUCT\n ];\n }\n}\n" + }, + "contracts/facets/base/DiamondCutFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibGuardian} from \"../../libraries/LibGuardian.sol\";\nimport {ISecurityManager} from \"../../infrastructure/interfaces/ISecurityManager.sol\";\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibFacetStorage, DiamondCutApprovalConfig, ApprovalConfig} from \"../../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"../Modifiers.sol\";\nimport {IDiamondCut} from \"./interfaces/IDiamondCut.sol\";\n\n/**\n * @title DiamondCut Facet\n * @dev Responsible for adding/removing/replace facets in Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DiamondCutFacet is Modifiers, IDiamondCut {\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Updates the flag for the interfaceId\n * @param _interfaceId InterfaceID to update the mapping\n * @param _flag Bool value to update the mapping of the given interface ID\n */\n function updateSupportsInterface(\n bytes4 _interfaceId,\n bool _flag\n ) external override onlyWhenUnlocked {\n LibDiamond.enforceIsSelf();\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId] = _flag;\n emit SupportsInterfaceUpdated(_interfaceId, _flag);\n }\n\n /**\n * @notice Add/replace/remove any number of functions and optionally execute\n * a function with delegatecall when guardians don't exist\n * @param _diamondCut Contains the facet addresses and function selectors\n * @param _init The address of the contract or facet to execute _calldata\n * @param _calldata A function call, including function selector and arguments\n * _calldata is executed with delegatecall on _init\n */\n function diamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) external override onlyWhenUnlocked {\n LibDiamond.enforceIsSelf();\n\n _checkFacetCutValidity(_diamondCut);\n // require approval from guardian if guardian exists\n if (0 != LibGuardian.guardianCount())\n revert DiamondCutFacet__InvalidRouteWithGuardian();\n\n ++LibFacetStorage.diamondCutStorage().nonce;\n LibDiamond.diamondCut(_diamondCut, _init, _calldata);\n }\n\n /**\n * @notice Add/replace/remove any number of functions and optionally execute\n * a function with delegatecall when guardians exist\n * @param _diamondCut Contains the facet addresses and function selectors\n * @param _init The address of the contract or facet to execute _calldata\n * @param _calldata A function call, including function selector and arguments\n * _calldata is executed with delegatecall on _init\n * @param _approvers Guardian or owner address that approves the diamond cut\n * @param _signatures Signature of Guardians or owner that approves the diamond cut\n */\n function diamondCutWithGuardian(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n ) external override onlyWhenUnlocked {\n uint256 approverLength = _approvers.length;\n if (approverLength != _signatures.length)\n revert DiamondCutFacet__InvalidArrayLength();\n _checkFacetCutValidity(_diamondCut);\n if (0 == LibGuardian.guardianCount())\n revert DiamondCutFacet__InvalidRouteWithGuardian();\n\n bytes32 cutHash = getDiamondCutHash(_diamondCut, _init, _calldata);\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(cutHash, _approvers);\n\n bool onChainOwnerApproval = getOwnerCutApprovalWithTimeValidity(\n cutHash\n );\n\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n if (\n approverLength +\n getDiamondCutApprovalCountWithTimeValidity(cutHash) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert DiamondCutFacet__InsufficientApprovers();\n\n bool ownerApproved;\n for (uint256 i; i < approverLength; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n _approvers[i] != address(this)\n ) revert DiamondCutFacet__InvalidApprover();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert DiamondCutFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n cutHash,\n _signatures[i]\n )\n ) revert DiamondCutFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n if (!ownerApproved && !onChainOwnerApproval)\n revert DiamondCutFacet__LackOfOwnerApproval();\n\n ++LibFacetStorage.diamondCutStorage().nonce;\n LibDiamond.diamondCut(_diamondCut, _init, _calldata);\n }\n\n /**\n * @notice Approves diamond cut. This can only be called directly from guardian or owner\n * @param _diamondCut Contains the facet addresses and function selectors\n * @param _init The address of the contract or facet to execute _calldata\n * @param _calldata A function call, including function selector and arguments\n * _calldata is executed with delegatecall on _init\n */\n function approveDiamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\n if (LibGuardian.guardianCount() == 0)\n revert DiamondCutFacet__InvalidRouteWithoutGuardian();\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n _checkFacetCutValidity(_diamondCut);\n\n bytes32 cutHash = getDiamondCutHash(_diamondCut, _init, _calldata);\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(\n true,\n approvalValidUntil\n );\n emit DiamondCutApproved(_diamondCut, _init, _calldata);\n if (\n (getDiamondCutApprovalCountWithTimeValidity(cutHash) >=\n LibGuardian.majorityOfGuardians()) &&\n getOwnerCutApprovalWithTimeValidity(cutHash)\n ) {\n ++LibFacetStorage.diamondCutStorage().nonce;\n LibDiamond.diamondCut(_diamondCut, _init, _calldata);\n }\n }\n\n /**\n * @notice Revokes the approval of diamond cut. This can only be called directly from guardian or owner\n * @param _diamondCut Contains the facet addresses and function selectors\n * @param _init The address of the contract or facet to execute _calldata\n * @param _calldata A function call, including function selector and arguments\n * _calldata is executed with delegatecall on _init\n */\n function revokeDiamondCutApproval(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n bytes32 cutHash = getDiamondCutHash(_diamondCut, _init, _calldata);\n if (!ds.isDiamondCutApproved[cutHash][msg.sender].isApproved)\n revert DiamondCutFacet__CannotRevokeUnapproved();\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(false, 0);\n emit DiamondCutApprovalRevoked(_diamondCut, _init, _calldata);\n }\n\n /**\n * @notice Gets the number of approvals of diamond cut from guardians\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n */\n function getDiamondCutApprovalCountWithTimeValidity(\n bytes32 _diamondCutHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardiansLength = guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n if (isCutApproved(_diamondCutHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n return approvalCount;\n }\n\n /**\n * @notice Returns if the owner has approved the diamond cut\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @return isApprovedByOwner Bool value showing if the owner approved the cut\n */\n function getOwnerCutApprovalWithTimeValidity(\n bytes32 _diamondCutHash\n ) public view override returns (bool isApprovedByOwner) {\n isApprovedByOwner = isCutApproved(_diamondCutHash, address(this));\n }\n\n /**\n * @notice Returns if the given approver has approved the diamond cut\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @param _approver Address of approver\n * @return isApproved Bool value showing if the approver approved the cut\n */\n function isCutApproved(\n bytes32 _diamondCutHash,\n address _approver\n ) public view override returns (bool isApproved) {\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n isApproved = (ds\n .isDiamondCutApproved[_diamondCutHash][_approver].isApproved &&\n block.timestamp <\n ds.isDiamondCutApproved[_diamondCutHash][_approver].validUntil);\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _diamondCutHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isCutApproved(_diamondCutHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert DiamondCutFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the diamond cut hash. This function ensures that this hash is safe from replay attack by including\n * salt, address, chainId, and nonce, etc.\n * @param _diamondCut Contains the facet addresses and function selectors\n * @param _init The address of the contract or facet to execute _calldata\n * @param _calldata A function call, including function selector and arguments\n * _calldata is executed with delegatecall on _init\n * @return cutHash Diamond Cut Hash\n */\n function getDiamondCutHash(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) public view override returns (bytes32 cutHash) {\n cutHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n keccak256(abi.encode(_diamondCut)),\n _init,\n _calldata,\n address(this),\n block.chainid,\n LibFacetStorage.diamondCutStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Returns the approval validation Period\n * @dev This method fetches the validation period from the security manager\n * @return approvalValidationPeriod Approval validation period of Barz contract fetched from security manager\n */\n function getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod <= 0)\n revert DiamondCutFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the diamond cut nonce of this wallet\n * @dev This method fetches the nonce from diamond cut storage\n * @return cutNonce Nonce of diamond cut to protect from reply attacks\n */\n function getDiamondCutNonce()\n public\n view\n override\n returns (uint128 cutNonce)\n {\n cutNonce = LibFacetStorage.diamondCutStorage().nonce;\n }\n}\n" + }, + "contracts/facets/base/DiamondLoupeFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {IERC165} from \"../../interfaces/ERC/IERC165.sol\";\nimport {IERC1271} from \"../../interfaces/ERC/IERC1271.sol\";\nimport {IERC677Receiver} from \"../../interfaces/ERC/IERC677Receiver.sol\";\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC1155Receiver} from \"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\";\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../../libraries/LibLoupe.sol\";\nimport {LibUtils} from \"../../libraries/LibUtils.sol\";\nimport {IDiamondCut} from \"../../facets/base/interfaces/IDiamondCut.sol\";\nimport {IStorageLoupe} from \"./interfaces/IStorageLoupe.sol\";\nimport {IDiamondLoupe} from \"./interfaces/IDiamondLoupe.sol\";\n\n/**\n * @title DiamondLoupe Facet\n * @dev DiamondLoupe contract compatible with EIP-2535\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DiamondLoupeFacet is IDiamondLoupe, IStorageLoupe, IERC165 {\n // Diamond Loupe Functions\n ////////////////////////////////////////////////////////////////////\n /// These functions are expected to be called frequently by tools off-chain.\n\n /**\n * @notice Gets all facets and their selectors.\n * @dev Barz uses a special architecture called default fallback handler. Default Fallback handler is used as a middleware\n * that holds the mapping of facet function selector and facet address that Barz uses. This helps Barz to reduce\n * significant amount of gas during the initialization process.\n * Hence, this method aggregates both the facet information from DefaulFallbackHandler and in diamond storage and shows the data to users.\n * @return facets_ Facet\n */\n function facets() public view override returns (Facet[] memory facets_) {\n Facet[] memory defaultFacet = LibDiamond\n .diamondStorage()\n .defaultFallbackHandler\n .facets();\n Facet[] memory _facets = LibLoupe.facets();\n uint256 numFacets = _facets.length;\n bytes4[] memory keys;\n address[] memory values;\n for (uint256 i; i < numFacets; ) {\n uint256 selectorsLength = _facets[i].functionSelectors.length;\n for (uint256 j; j < selectorsLength; ) {\n (keys, values) = LibUtils.setValue(\n keys,\n values,\n _facets[i].functionSelectors[j],\n _facets[i].facetAddress\n );\n unchecked {\n ++j;\n }\n }\n unchecked {\n ++i;\n }\n }\n {\n bool iIncrement;\n for (uint256 i; i < defaultFacet.length; ) {\n bool jIncrement;\n for (\n uint256 j;\n j < defaultFacet[i].functionSelectors.length;\n\n ) {\n if (\n LibUtils.getValue(\n keys,\n values,\n defaultFacet[i].functionSelectors[j]\n ) != address(0)\n ) {\n if (defaultFacet[i].functionSelectors.length == 1) {\n defaultFacet = LibUtils.removeFacetElement(\n defaultFacet,\n i\n );\n iIncrement = true;\n break;\n }\n defaultFacet[i].functionSelectors = LibUtils\n .removeElement(\n defaultFacet[i].functionSelectors,\n j\n );\n jIncrement = true;\n }\n if (!jIncrement) {\n unchecked {\n ++j;\n }\n } else {\n jIncrement = false;\n }\n }\n if (!iIncrement) {\n unchecked {\n ++i;\n }\n } else {\n iIncrement = false;\n }\n }\n }\n {\n uint256 facetLength = numFacets + defaultFacet.length;\n facets_ = new Facet[](facetLength);\n uint256 defaultFacetIndex;\n for (uint256 i; i < facetLength; ) {\n if (i < numFacets) {\n facets_[i] = _facets[i];\n bool jIncrementor;\n for (uint256 j; j < defaultFacet.length; ) {\n if (\n facets_[i].facetAddress ==\n defaultFacet[j].facetAddress\n ) {\n facets_[i].functionSelectors = LibUtils.mergeArrays(\n _facets[i].functionSelectors,\n defaultFacet[j].functionSelectors\n );\n defaultFacet = LibUtils.removeFacetElement(\n defaultFacet,\n j\n );\n jIncrementor = true;\n {\n facets_ = LibUtils.removeFacetElement(\n facets_,\n facets_.length - 1\n );\n }\n --facetLength;\n }\n if (!jIncrementor) {\n unchecked {\n ++j;\n }\n } else {\n jIncrementor = false;\n }\n }\n } else {\n facets_[i] = defaultFacet[defaultFacetIndex];\n ++defaultFacetIndex;\n }\n unchecked {\n ++i;\n }\n }\n }\n }\n\n /**\n * @notice Gets all the function selectors provided by a facet.\n * @param _facet The facet address.\n * @return facetFunctionSelectors_\n */\n function facetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n Facet[] memory facet = facets();\n uint256 facetLength = facet.length;\n for (uint256 i; i < facetLength; ) {\n if (facet[i].facetAddress == _facet)\n return facet[i].functionSelectors;\n unchecked {\n ++i;\n }\n }\n return facetFunctionSelectors_;\n }\n\n /**\n * @notice Get all the facet addresses used by Barz.\n * @return facetAddresses_\n */\n function facetAddresses()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n Facet[] memory facet = facets();\n uint256 facetLength = facet.length;\n facetAddresses_ = new address[](facetLength);\n for (uint256 i; i < facetLength; ) {\n facetAddresses_[i] = facet[i].facetAddress;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Gets the facet that supports the given selector.\n * @dev If facet is not found return address(0).\n * @param _functionSelector The function selector.\n * @return facetAddress_ The facet address.\n */\n function facetAddress(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n\n facetAddress_ = address(bytes20(ds.facets[_functionSelector]));\n if (facetAddress_ == address(0)) {\n facetAddress_ = IDiamondLoupe(ds.defaultFallbackHandler)\n .facetAddress(_functionSelector);\n }\n }\n\n /**\n * @notice SupportInterface to be compatible with EIP 165\n * @param _interfaceId Interface ID for detecting the interface\n * @return isSupported Bool value showing if the standard is supported in the contract\n */\n function supportsInterface(\n bytes4 _interfaceId\n ) external view override returns (bool isSupported) {\n isSupported =\n _interfaceId == type(IERC165).interfaceId ||\n _interfaceId == IDiamondCut.diamondCut.selector ||\n _interfaceId == type(IDiamondLoupe).interfaceId ||\n _interfaceId == type(IERC1155Receiver).interfaceId ||\n _interfaceId == type(IERC721Receiver).interfaceId ||\n _interfaceId == type(IERC777Recipient).interfaceId ||\n _interfaceId == IERC1271.isValidSignature.selector ||\n _interfaceId == type(IERC677Receiver).interfaceId ||\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId];\n }\n\n /**\n * @notice Returns the facet from the diamond storage. This excludes the facets from the default fallback handler\n * @return facets_ Facet information attached directly to diamond storage\n */\n function facetsFromStorage()\n external\n view\n override\n returns (Facet[] memory facets_)\n {\n facets_ = LibLoupe.facets();\n }\n\n /**\n * @notice Returns the facet address attached to the given function selector. This excludes the facets from the default fallback handler\n * @param _functionSelector Function selector to fetch the facet address from diamond storage\n * @return facetAddress_ Facet address mapped with the function selector\n */\n function facetAddressFromStorage(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n facetAddress_ = LibLoupe.facetAddress(_functionSelector);\n }\n\n /**\n * @notice Returns all facet addresses attached directly to diamond storage. This excludes the facets from the default fallback handler\n * @return facetAddresses_ All facet addresses attached directly to diamond storage\n */\n function facetAddressesFromStorage()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n facetAddresses_ = LibLoupe.facetAddresses();\n }\n\n /**\n * @notice Returns function selectors of given facet address attached directly to diamond storage. This excludes the facets from the default fallback handler\n * @param _facet Facet address to fetch the facet function selectors from diamond storage\n * @return facetFunctionSelectors_ Facet function selectors of the given facet address\n */\n function facetFunctionSelectorsFromStorage(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n facetFunctionSelectors_ = LibLoupe.facetFunctionSelectors(_facet);\n }\n}\n" + }, + "contracts/facets/base/interfaces/IDiamondCut.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title DiamondCut Facet Interface\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IDiamondCut {\n error DiamondCutFacet__InvalidRouteWithGuardian();\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\n error DiamondCutFacet__InvalidArrayLength();\n error DiamondCutFacet__InsufficientApprovers();\n error DiamondCutFacet__InvalidApprover();\n error DiamondCutFacet__InvalidApproverSignature();\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\n error DiamondCutFacet__CannotRevokeUnapproved();\n error DiamondCutFacet__GuardianApprovalNotRequired();\n error DiamondCutFacet__LackOfOwnerApproval();\n error DiamondCutFacet__OwnerAlreadyApproved();\n error DiamondCutFacet__DuplicateApproval();\n\n event DiamondCutApproved(\n FacetCut[] diamondCut,\n address init,\n bytes initCalldata\n );\n event DiamondCutApprovalRevoked(\n FacetCut[] diamondCut,\n address init,\n bytes initCalldata\n );\n\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\n\n enum FacetCutAction {\n Add,\n Replace,\n Remove\n }\n // Add=0, Replace=1, Remove=2\n\n struct FacetCut {\n address facetAddress;\n FacetCutAction action;\n bytes4[] functionSelectors;\n }\n\n /// @notice Add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param diamondCut Contains the facet addresses and function selectors\n /// @param init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function diamondCut(\n FacetCut[] calldata diamondCut,\n address init,\n bytes calldata _calldata\n ) external;\n\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\n\n function diamondCutWithGuardian(\n FacetCut[] calldata diamondCut,\n address init,\n bytes calldata _calldata,\n address[] calldata approvers,\n bytes[] calldata signatures\n ) external;\n\n function approveDiamondCut(\n FacetCut[] calldata diamondCut,\n address init,\n bytes calldata _calldata\n ) external;\n\n function revokeDiamondCutApproval(\n FacetCut[] calldata diamondCut,\n address init,\n bytes calldata _calldata\n ) external;\n\n function getDiamondCutApprovalCountWithTimeValidity(\n bytes32 diamondCutHash\n ) external view returns (uint256);\n\n function getOwnerCutApprovalWithTimeValidity(\n bytes32 diamondCutHash\n ) external view returns (bool);\n\n function isCutApproved(\n bytes32 diamondCutHash,\n address approver\n ) external view returns (bool);\n\n function getDiamondCutHash(\n FacetCut[] calldata diamondCut,\n address init,\n bytes calldata _calldata\n ) external view returns (bytes32);\n\n function getDiamondCutNonce() external view returns (uint128);\n}\n" + }, + "contracts/facets/base/interfaces/IDiamondLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n// A loupe is a small magnifying glass used to look at diamonds.\n// These functions look at diamonds\ninterface IDiamondLoupe {\n /// These functions are expected to be called frequently\n /// by tools.\n\n struct Facet {\n address facetAddress;\n bytes4[] functionSelectors;\n }\n\n /// @notice Gets all facet addresses and their four byte function selectors.\n /// @return facets_ Facet\n function facets() external view returns (Facet[] memory facets_);\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n /// @return facetFunctionSelectors_\n function facetFunctionSelectors(\n address _facet\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses()\n external\n view\n returns (address[] memory facetAddresses_);\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(\n bytes4 _functionSelector\n ) external view returns (address facetAddress_);\n}\n" + }, + "contracts/facets/base/interfaces/IStorageLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"./IDiamondLoupe.sol\";\n\n/**\n * @title LoupeFromStorage Interface\n * @dev Interface contract to function as a loupe facet directly attached to diamond storage of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IStorageLoupe {\n /// These functions are expected to be called frequently\n /// by tools.\n\n /// @notice Gets all facet addresses and their four byte function selectors.\n /// @return facets_ Facet\n function facetsFromStorage()\n external\n view\n returns (IDiamondLoupe.Facet[] memory);\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n function facetFunctionSelectorsFromStorage(\n address _facet\n ) external view returns (bytes4[] memory);\n\n /// @notice Get all the facet addresses used by a diamond.\n function facetAddressesFromStorage()\n external\n view\n returns (address[] memory);\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n function facetAddressFromStorage(\n bytes4 _functionSelector\n ) external view returns (address);\n}\n" + }, + "contracts/facets/GuardianFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibFacetStorage, GuardianStorage, StorageConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IGuardianFacet} from \"./interfaces/IGuardianFacet.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Guardian Facet\n * @dev Contract that enables addition/removal of guardians from Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract GuardianFacet is IGuardianFacet {\n ISecurityManager public immutable securityManager;\n uint8 public constant INNER_STRUCT = 0;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Add guardians to Barz.\n * @dev This method internally calls addGuardian which checks the validity of guardian address and adds\n * as guardian if valid\n * @param _guardians Array of addresses to add as guardian\n */\n function addGuardians(address[] calldata _guardians) external override {\n LibDiamond.enforceIsSelf();\n uint256 guardiansLength = _guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n addGuardian(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Add a guardian to Barz.\n * @dev This method checks if the function is called by the owner and validates the address of guardian\n * When the validation passes, guardian address is added to the pending state waiting for confirmation\n * @param _guardian Address to add as guardian\n */\n function addGuardian(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (_guardian == address(this))\n revert GuardianFacet__GuardianCannotBeSelf();\n if (isGuardian(_guardian)) revert GuardianFacet__DuplicateGuardian();\n if (_guardian == address(0))\n revert GuardianFacet__ZeroAddressGuardian();\n if (\n keccak256(abi.encodePacked(_guardian)) ==\n keccak256(IVerificationFacet(address(this)).owner())\n ) revert GuardianFacet__OwnerCannotBeGuardian();\n\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n if (\n gs.pending[id] != 0 ||\n block.timestamp <= gs.pending[id] + getSecurityWindow()\n ) revert GuardianFacet__DuplicateGuardianAddition();\n\n uint256 securityPeriod = getAdditionSecurityPeriod();\n gs.pending[id] = block.timestamp + securityPeriod;\n emit GuardianAdditionRequested(\n _guardian,\n block.timestamp + securityPeriod\n );\n }\n\n /**\n * @notice Remove guardians from Barz.\n * @dev This method internally calls removeGuardian which checks the validity of guardian and removes\n * guardian when the request is valid\n * @param _guardians Array of addresses to be removed\n */\n function removeGuardians(address[] calldata _guardians) external override {\n LibDiamond.enforceIsSelf();\n uint256 guardiansLength = _guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n removeGuardian(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Remove a guardian from Barz.\n * @dev This method validates if the guardian to be removed is a guardian and puts the guardian removal\n * to a pending state waiting to be confirmed.\n * @param _guardian Address of guardian to be removed\n */\n function removeGuardian(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n if (!isGuardian(_guardian)) revert GuardianFacet__NonExistentGuardian();\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n if (\n gs.pending[id] != 0 ||\n block.timestamp <= gs.pending[id] + getSecurityWindow()\n ) revert GuardianFacet__DuplicateGuardianRemoval();\n\n uint256 securityPeriod = getRemovalSecurityPeriod();\n gs.pending[id] = block.timestamp + securityPeriod;\n emit GuardianRemovalRequested(\n _guardian,\n block.timestamp + securityPeriod\n );\n }\n\n /**\n * @notice Confirm addition of guardians\n * @dev This method internally calls confirmGuardianAddition which checks the validity of pending request.\n * Guardians are fully added when they pass the validation. Anyone can call this function.\n * @param _guardians Array of guardian addresses to be added\n */\n function confirmGuardianAdditions(\n address[] calldata _guardians\n ) external override {\n uint256 guardiansLength = _guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n confirmGuardianAddition(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Confirm addition of a guardian\n * @dev This method checks the validity of pending request.\n * Guardians are fully added when they pass the validation. Anyone can call this function.\n * @param _guardian Guardian address to be added\n */\n function confirmGuardianAddition(address _guardian) public override {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingAddition();\n if (gs.pending[id] >= block.timestamp)\n revert GuardianFacet__PendingAdditionNotOver();\n if (block.timestamp >= gs.pending[id] + getSecurityWindow())\n revert GuardianFacet__PendingAdditionExpired();\n\n _addGuardian(_guardian);\n\n delete gs.pending[id];\n emit GuardianAdded(_guardian);\n }\n\n /**\n * @notice Confirm removal of guardians\n * @dev This method internally calls confirmGuardianRemoval to check the validity guardian removal confirmation.\n * Guardians are fully removed when they pass the validation. Anyone can call this function.\n * @param _guardians Array of guardian addresses to be removed\n */\n function confirmGuardianRemovals(\n address[] calldata _guardians\n ) external override {\n uint256 guardiansLength = _guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n confirmGuardianRemoval(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Confirm removal of a guardian\n * @dev This method checks the validity guardian removal confirmation.\n * Guardian is fully removed when they pass the validation. Anyone can call this function.\n * @param _guardian Guardian address to be removed\n */\n function confirmGuardianRemoval(address _guardian) public override {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingRemoval();\n if (gs.pending[id] >= block.timestamp)\n revert GuardianFacet__PendingRemovalNotOver();\n if (block.timestamp >= gs.pending[id] + getSecurityWindow())\n revert GuardianFacet__PendingAdditionExpired();\n\n _removeGuardian(_guardian);\n delete gs.pending[id];\n emit GuardianRemoved(_guardian);\n }\n\n /**\n * @notice Cancel pending guardian addition\n * @dev This method checks if the previous request for guardian request exists.\n * It reverts if previous request is not pending and cancels the addition otherwise.\n * @param _guardian Guardian address to be canceled from addition\n */\n function cancelGuardianAddition(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingAddition();\n delete gs.pending[id];\n emit GuardianAdditionCancelled(_guardian);\n }\n\n /**\n * @notice Cancel pending guardian removal\n * @dev This method checks if the previous request for guardian request exists.\n * It reverts if previous request is not pending and cancels the removal otherwise.\n * @param _guardian Guardian address to be canceled from removal\n */\n function cancelGuardianRemoval(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingRemoval();\n delete gs.pending[id];\n emit GuardianRemovalCancelled(_guardian);\n }\n\n /**\n * @notice Get the addition security period of current account from security manager\n * @dev This method returns the uint value if addition security period\n * @return additionSecurityPeriod Uint256 value of addition security period\n */\n function getAdditionSecurityPeriod()\n public\n view\n override\n returns (uint256 additionSecurityPeriod)\n {\n additionSecurityPeriod = securityManager.additionSecurityPeriodOf(\n address(this)\n );\n if (additionSecurityPeriod == 0)\n revert GuardianFacet__InvalidAdditionSecurityPeriod();\n }\n\n /**\n * @notice Get the removal security period of current account from security manager\n * @dev This method returns the uint value if removal security period\n * @return removalSecurityPeriod Uint256 value of removal security period\n */\n function getRemovalSecurityPeriod()\n public\n view\n override\n returns (uint256 removalSecurityPeriod)\n {\n removalSecurityPeriod = securityManager.removalSecurityPeriodOf(\n address(this)\n );\n if (removalSecurityPeriod == 0)\n revert GuardianFacet__InvalidRemovalSecurityPeriod();\n }\n\n /**\n * @notice Get the security window of current account from security manager\n * @dev This method returns the uint value if security window\n * @return securityWindow Uint256 value of removal security period\n */\n function getSecurityWindow()\n public\n view\n override\n returns (uint256 securityWindow)\n {\n securityWindow = securityManager.securityWindowOf(address(this));\n if (securityWindow == 0) revert GuardianFacet__InvalidSecurityWindow();\n }\n\n /**\n * @notice Checks if the addition of the given guardian address is pending\n * @dev This method returns the bool value of whether the guardian address is pending addition\n * @return isPending Bool value of representing the pending of guardian addition\n */\n function isAdditionPending(\n address _guardian\n ) public view override returns (bool isPending) {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n isPending = _isPending(id);\n }\n\n /**\n * @notice Checks if the removal of the given guardian address is pending\n * @dev This method returns the bool value of whether the guardian address is pending removal\n * @return isPending Bool value of representing the pending of guardian removal\n */\n function isRemovalPending(\n address _guardian\n ) public view override returns (bool isPending) {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n isPending = _isPending(id);\n }\n\n /**\n * @notice Checks if the given hash is pending\n * @dev This method returns the bool value whether the hash is pending\n * @return isPending Bool value of representing the pending of guardian operation\n */\n function _isPending(\n bytes32 _idHash\n ) internal view returns (bool isPending) {\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n isPending = ((gs.pending[_idHash] > 0 &&\n gs.pending[_idHash] < block.timestamp) &&\n block.timestamp < gs.pending[_idHash] + getSecurityWindow());\n }\n\n /**\n * @notice Adds guardian to storage config. This is called when guardian is fully added.\n * @dev This method add guardian address and config information to Facet Storage dedicated for guardian\n * When this function is called, guardian is fully added to this Barz Smart Account\n * @param _guardian Address of guardian to be added\n */\n function _addGuardian(address _guardian) internal {\n if (!isAdditionPending(_guardian))\n revert GuardianFacet__InvalidGuardianAddition();\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n if (config.info[_guardian].exists)\n revert GuardianFacet__AlreadyExists();\n\n config.info[_guardian].exists = true;\n config.info[_guardian].index = uint128(config.addresses.length);\n config.addresses.push(_guardian);\n }\n\n /**\n * @notice Removes guardian to storage config. This is called when guardian is fully removed.\n * @dev This method remove guardian address and config information to Facet Storage dedicated for guardian\n * When this function is called, guardian is fully removed from this Barz Smart Account\n * @param _guardian Address of guardian to be removed\n */\n function _removeGuardian(address _guardian) internal {\n if (!isRemovalPending(_guardian))\n revert GuardianFacet__InvalidGuardianRemoval();\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n if (!config.info[_guardian].exists)\n revert GuardianFacet__NonExistentGuardian();\n\n address lastAddress = config.addresses[config.addresses.length - 1];\n if (_guardian != lastAddress) {\n uint128 targetIndex = config.info[_guardian].index;\n config.addresses[targetIndex] = lastAddress;\n config.info[lastAddress].index = targetIndex;\n }\n config.addresses.pop();\n delete config.info[_guardian];\n\n emit GuardianRemoved(_guardian);\n }\n\n /**\n * @notice Reads guardian storage and fetches the addresses into an array from the storage\n * @dev This method fetches the guardian storage and returns the list of guardian addresses\n * @return addresses Array of addresses comprised of guardian\n */\n function getGuardians()\n public\n view\n override\n returns (address[] memory addresses)\n {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n addresses = new address[](config.addresses.length);\n uint256 addressesLen = config.addresses.length;\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the number of majority of guardians\n * @return majorityOfGuardians_ Number of majority of guardians e.g., 2 if 3 guardians / 3 if 5 guardians\n */\n function majorityOfGuardians()\n public\n view\n override\n returns (uint256 majorityOfGuardians_)\n {\n majorityOfGuardians_ = LibGuardian.majorityOfGuardians();\n }\n\n /**\n * @notice Reads guardian storage and fetches the addresses into an array from the storage\n * @dev This method fetches the guardian storage and returns the list of guardian addresses\n * @return guardianNumber Array of guardians in the account\n */\n function guardianCount()\n public\n view\n override\n returns (uint256 guardianNumber)\n {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n guardianNumber = config.addresses.length;\n }\n\n /**\n * @notice Reads guardian storage and checks if the given address is a guardian\n * @return isGuardian_ Bool value representing if the given address is guardian\n */\n function isGuardian(\n address _guardian\n ) public view override returns (bool isGuardian_) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n isGuardian_ = config.info[_guardian].exists;\n }\n\n /**\n * @notice Checks if the guardian number is zero and returns of guardian facet is okay to be removed\n * @return isRemovable Bool value representing if guardian facet is removable\n */\n function isGuardianFacetRemovable()\n external\n view\n override\n returns (bool isRemovable)\n {\n isRemovable = (0 == guardianCount());\n }\n}\n" + }, + "contracts/facets/interfaces/IAccountFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IEntryPoint} from \"../../aa-4337/interfaces/IEntryPoint.sol\";\n\n/**\n * @title Account Facet Interface\n * @dev Interface of module contract that provides the account features and init/unitialization of signer\n * compatible with EIP-1271 & EIP-4337\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IAccountFacet {\n event AccountInitialized(\n IEntryPoint indexed entryPoint,\n bytes indexed ownerPublicKey\n );\n // NOTE: Added Below Event\n event VerificationSuccess(bytes32);\n event VerificationFailure(bytes32);\n\n error AccountFacet__InitializationFailure();\n error AccountFacet__RestrictionsFailure();\n error AccountFacet__NonExistentVerificationFacet();\n error AccountFacet__CallNotSuccessful();\n\n function initialize(\n address verificationFacet,\n address anEntryPoint,\n address facetRegistry,\n address _defaultFallBack,\n bytes calldata _ownerPublicKey\n ) external returns (uint256);\n\n function execute(address dest, uint256 value, bytes calldata func) external;\n\n function executeBatch(\n address[] calldata dest,\n uint256[] calldata value,\n bytes[] calldata func\n ) external;\n}\n" + }, + "contracts/facets/interfaces/IAccountRecoveryFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {RecoveryConfig} from \"../../libraries/LibFacetStorage.sol\";\n\n/**\n * @title Account Recovery Facet Interface\n * @dev Interface of contract that enables recovery of accounts when owner key is unavailable\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IAccountRecoveryFacet {\n event RecoveryExecuted(\n bytes indexed recoveryPublicKey,\n uint64 executeAfter\n );\n event RecoveryFinalized(bytes indexed recoveryPublicKey);\n event RecoveryCanceled(bytes indexed recoveryPublicKey);\n event RecoveryApproved(\n bytes indexed recoveryPublicKey,\n address indexed guardian,\n uint64 validUntil\n );\n event RecoveryApprovalRevoked(\n bytes indexed recoveryPublicKey,\n address indexed guardian\n );\n event RecoveryCancellationApproved(\n bytes indexed recoveryPublicKey,\n address indexed guardian\n );\n event RecoveryHardstopped();\n\n error AccountRecoveryFacet__CallerNotGuardian();\n error AccountRecoveryFacet__InvalidRecoveryPublicKey();\n error AccountRecoveryFacet__SignerInitializationFailure();\n error AccountRecoveryFacet__SignerUninitializationFailure();\n error AccountRecoveryFacet__InvalidArrayLength();\n error AccountRecoveryFacet__InsufficientGuardians();\n error AccountRecoveryFacet__RecoveryAlreadyOngoing();\n error AccountRecoveryFacet__NonexistentRecovery();\n error AccountRecoveryFacet__NonExistentApproval();\n error AccountRecoveryFacet__RecoveryPeriodNotOver();\n error AccountRecoveryFacet__InvalidLockPeriod();\n error AccountRecoveryFacet__InvalidRecoveryPeriod();\n error AccountRecoveryFacet__InvalidApprovalValidationPeriod();\n error AccountRecoveryFacet__InvalidGuardian();\n error AccountRecoveryFacet__InvalidGuardianSignature();\n error AccountRecoveryFacet__InvalidOwnerSignature();\n error AccountRecoveryFacet__CallNotSuccesful();\n error AccountRecoveryFacet__DuplicateApproval();\n\n function approveAccountRecovery(bytes calldata recoveryPublicKey) external;\n\n function revokeAccountRecoveryApproval(\n bytes calldata recoveryPublicKey\n ) external;\n\n function executeRecovery(\n bytes calldata recoveryPublicKey,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function finalizeRecovery() external;\n\n function approveCancelRecovery(bytes calldata recoveryPublicKey) external;\n\n function cancelRecovery(\n bytes calldata recoveryPublicKey,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function hardstopRecovery(bytes calldata signature) external;\n\n function getApprovalRecoveryKeyHash(\n bytes memory recoveryPublicKey,\n string memory saltString\n ) external view returns (bytes32);\n\n function getRecoveryApprovalCountWithTimeValidity(\n bytes32 recoveryPublicKeyHash\n ) external view returns (uint256);\n\n function isRecoveryApproved(\n bytes32 recoveryPublicKeyHash,\n address approver\n ) external view returns (bool);\n\n function getRecoveryNonce() external view returns (uint128);\n\n function getPendingRecovery() external view returns (RecoveryConfig memory);\n}\n" + }, + "contracts/facets/interfaces/IGuardianFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Guardian Facet Interface\n * @dev Interface of guaridna contract that enables addition/removal of guardians from Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IGuardianFacet {\n event GuardianAdditionRequested(\n address indexed guardian,\n uint256 executeAfter\n );\n event GuardianRemovalRequested(\n address indexed guardian,\n uint256 executeAfter\n );\n event GuardianAdditionCancelled(address indexed guardian);\n event GuardianRemovalCancelled(address indexed guardian);\n event GuardianAdded(address indexed guardian);\n event GuardianRemoved(address indexed guardian);\n\n error GuardianFacet__GuardianCannotBeSelf();\n error GuardianFacet__DuplicateGuardian();\n error GuardianFacet__OwnerCannotBeGuardian();\n error GuardianFacet__DuplicateGuardianAddition();\n error GuardianFacet__DuplicateGuardianRemoval();\n error GuardianFacet__UnknownPendingAddition();\n error GuardianFacet__PendingAdditionNotOver();\n error GuardianFacet__UnknownPendingRemoval();\n error GuardianFacet__PendingRemovalNotOver();\n error GuardianFacet__PendingAdditionExpired();\n error GuardianFacet__InvalidAdditionSecurityPeriod();\n error GuardianFacet__InvalidRemovalSecurityPeriod();\n error GuardianFacet__InvalidSecurityWindow();\n error GuardianFacet__NonExistentGuardian();\n error GuardianFacet__AlreadyExists();\n error GuardianFacet__InvalidGuardianAddition();\n error GuardianFacet__InvalidGuardianRemoval();\n error GuardianFacet__ZeroAddressGuardian();\n\n function addGuardian(address guardian) external;\n\n function addGuardians(address[] calldata guardians) external;\n\n function removeGuardian(address guardian) external;\n\n function removeGuardians(address[] calldata guardians) external;\n\n function confirmGuardianAddition(address guardian) external;\n\n function confirmGuardianAdditions(address[] calldata guardian) external;\n\n function confirmGuardianRemoval(address guardian) external;\n\n function confirmGuardianRemovals(address[] calldata guardian) external;\n\n function cancelGuardianAddition(address guardian) external;\n\n function cancelGuardianRemoval(address guardian) external;\n\n function isGuardian(address guardian) external view returns (bool);\n\n function isAdditionPending(address guardian) external view returns (bool);\n\n function isRemovalPending(address guardian) external view returns (bool);\n\n function isGuardianFacetRemovable() external view returns (bool);\n\n function getAdditionSecurityPeriod() external view returns (uint256);\n\n function getRemovalSecurityPeriod() external view returns (uint256);\n\n function getSecurityWindow() external view returns (uint256);\n\n function getGuardians() external view returns (address[] memory);\n\n function majorityOfGuardians() external view returns (uint256);\n\n function guardianCount() external view returns (uint256);\n}\n" + }, + "contracts/facets/interfaces/ILockFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Lock} from \"../../libraries/LibAppStorage.sol\";\n\n/**\n * @title Lock Facet Interface\n * @dev Interface of Lock contract that enables full lock/unlock of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface ILockFacet {\n event Locked(uint64 releaseAfter);\n event Unlocked();\n\n error LockFacet__InvalidRecoveryPeriod();\n error LockFacet__CannotUnlock();\n error LockFacet__InvalidSignature();\n error LockFacet__InvalidApprover();\n\n function lock() external;\n\n function unlock(address approver, bytes calldata signature) external;\n\n function getLockPeriod() external view returns (uint256);\n\n function isLocked() external view returns (bool);\n\n function getUnlockHash() external view returns (bytes32);\n\n function lockNonce() external view returns (uint128);\n\n function getPendingLock() external view returns (Lock memory);\n}\n" + }, + "contracts/facets/interfaces/IMultiSigFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Multi-sig facet Interface\n * @dev Interface of Multi-signature Facet with custom threshold.\n Wallet that adds this facet becomes a multi-sig wallet\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IMultiSigFacet {\n event ThresholdChanged(uint256 threshold);\n event OwnerAdded(address indexed newOwner);\n event OwnerRemoved(address indexed prevOwner);\n event HashApproved(bytes32 hashToApprove, address indexed owner);\n\n error MultiSigFacet__InvalidThreshold();\n error MultisigFacet__InvalidOwnerCount();\n error MultiSigFacet__InvalidRoute();\n error MultiSigFacet__InsufficientSignerLength();\n error MultiSigFacet__InvalidInitData();\n error MultiSigFacet__InvalidOwnerAddress();\n error MultiSigFacet__InvalidOwnerPair();\n error MultiSigFacet__InvalidSignatureLength();\n error MultiSigFacet__InvalidSignatureType();\n error MultiSigFacet__DuplicateOwner();\n error MultiSigFacet__OnlyOwner();\n\n function checkSignatures(\n bytes32 _dataHash,\n bytes calldata _signatures,\n uint256 _threshold\n ) external view returns (uint256);\n\n function splitSignatures(\n bytes calldata _signatures,\n uint256 _nextOffset\n )\n external\n pure\n returns (\n address owner,\n bytes memory signature,\n uint256 signatureType,\n uint256 nextOffset\n );\n\n function approveHash(bytes32 hashToApprove) external;\n\n function addOwner(address newOwner, uint256 threshold) external;\n\n function removeOwner(\n address prevOwner,\n address removedOwner,\n uint256 threshold\n ) external;\n\n function swapOwner(\n address prevOwner,\n address oldOwner,\n address newOwner\n ) external;\n\n function changeThreshold(uint256 _threshold) external;\n\n function isOwner(address owner) external view returns (bool);\n\n function getThreshold() external view returns (uint256);\n\n function getOwners() external view returns (address[] memory);\n}\n" + }, + "contracts/facets/interfaces/IRestrictionsFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Restrictions Facet Interface\n * @dev Interface of Restrictions contract that enables modular restrictions in Barz\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IRestrictionsFacet {\n event RestrictionAdded(address indexed restriction);\n event RestrictionRemoved(address indexed restriction);\n\n error RestrictionsFacet__EmptyRestrictionsList();\n error RestrictionsFacet__RestrictionNotFound();\n error RestrictionsFacet__RestrictionAlreadyExists();\n error RestrictionsFacet__ZeroAddressRestrictions();\n error RestrictionsFacet__ZeroAddressRestrictionsFacet();\n error RestrictionsFacet__RemainingRestrictionsCantBeEmpty();\n\n function initializeRestrictions(\n address[] memory _restrictions\n ) external returns (uint256);\n\n function uninitializeRestrictions() external returns (uint256);\n\n function getRestrictions() external view returns (address[] memory);\n\n function addRestriction(address restriction) external;\n\n function removeRestriction(address restriction) external;\n\n function verifyRestrictions(\n address from,\n address to,\n uint256 value,\n bytes calldata _calldata\n ) external returns (uint256);\n}\n" + }, + "contracts/facets/interfaces/ISignatureMigrationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureMigrationConfig} from \"../../libraries/LibFacetStorage.sol\";\n\n/**\n * @title Signature Migration Facet Interface\n * @dev Interface of Signature Migration contract for migrating user signature scheme to a new scheme user sets\n * Which could include\n * - ECDSA on Secp256K1 Curve\n * - ECDSA on Secp256R1 Curve\n * - BLS, Schnorr, etc\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface ISignatureMigrationFacet {\n event SignatureSchemeMigration(\n address indexed prevVerificationFacet,\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n event SignatureMigrationApproved(\n bytes newPublicKey,\n address indexed newVerificationFacet,\n bytes4[] verificationFuncSelectors,\n address indexed guardian,\n uint128 approvalValidUntil\n );\n event SignatureMigrationApprovalRevoked(\n bytes newPublicKey,\n address indexed newVerificationFacet,\n bytes4[] verificationFuncSelectors,\n address indexed guardian\n );\n event SignatureMigrationExecuted(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors,\n uint128 migrateAfter\n );\n event SignatureMigrationCanceled(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n event SignatureMigrationCancellationApproved(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n\n error SignatureMigrationFacet__SignerUninitializationFailure();\n error SignatureMigrationFacet__InvalidRouteWithGuardian();\n error SignatureMigrationFacet__InvalidKeyType();\n error SignatureMigrationFacet__InsufficientApprovers();\n error SignatureMigrationFacet__InvalidApproverSignature();\n error SignatureMigrationFacet__InvalidGuardian();\n error SignatureMigrationFacet__NonExistentApprover();\n error SignatureMigrationFacet__InvalidMigrationPeriod();\n error SignatureMigrationFacet__NonexistentMigration();\n error SignatureMigrationFacet__MigrationPeriodNotOver();\n error SignatureMigrationFacet__InvalidArrayLength();\n error SignatureMigrationFacet__InvalidApprovalValidationPeriod();\n error SignatureMigrationFacet__CannotRevokeUnapproved();\n error SignatureMigrationFacet__LackOfOwnerApproval();\n error SignatureMigrationFacet__OwnerAlreadyApproved();\n error SignatureMigrationFacet__NonExistentVerificationFacet();\n error SignatureMigrationFacet__DuplicateApproval();\n\n function migrateSignatureScheme(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function migrateSignatureSchemeWithGuardian(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors,\n address[] calldata approvers,\n bytes[] calldata signatures\n ) external;\n\n function approveSignatureSchemeMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function revokeSignatureMigrationApproval(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function finalizeSignatureMigration() external;\n\n function approveCancelSignatureMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function cancelSignatureMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function getApprovalMigrationKeyHash(\n bytes memory recoveryPublicKey,\n address newVerificationFacet,\n bytes4[] memory newVerificationFuncSelectors,\n string memory saltString\n ) external view returns (bytes32);\n\n function getMigrationOwnerApprovalWithTimeValidity(\n bytes32 publicKeyHash\n ) external view returns (bool);\n\n function getMigrationApprovalCountWithTimeValidity(\n bytes32 publicKeyHash\n ) external view returns (uint256);\n\n function isMigrationApproved(\n bytes32 migrationPublicKeyHash,\n address approver\n ) external view returns (bool);\n\n function getMigrationNonce() external view returns (uint128);\n\n function isMigrationPending() external view returns (bool);\n\n function getPendingMigration()\n external\n view\n returns (SignatureMigrationConfig memory);\n}\n" + }, + "contracts/facets/interfaces/IVerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {UserOperation} from \"../../aa-4337/interfaces/UserOperation.sol\";\n\n/**\n * @title Verification Facet Interface\n * @dev Implements logic for user ops signature verification\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface IVerificationFacet {\n event SignerInitialized(bytes);\n event SignerUninitialized();\n\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n error VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n error VerificationFacet__InitializationFailure();\n error VerificationFacet__InvalidFacetMapping();\n\n function initializeSigner(bytes memory) external returns (uint256);\n\n function uninitializeSigner() external returns (uint256);\n\n function validateOwnerSignatureSelector() external view returns (bytes4);\n\n function owner() external view returns (bytes memory);\n\n function isValidKeyType(bytes calldata) external view returns (bool);\n\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) external view returns (uint256);\n}\n" + }, + "contracts/facets/LockFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage, Lock} from \"../libraries/LibAppStorage.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibFacetStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {ILockFacet} from \"./interfaces/ILockFacet.sol\";\n\n/**\n * @title Lock Facet\n * @dev Contract that enables full lock/unlock of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract LockFacet is ILockFacet, Modifiers {\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Locks the account for the lock period. Lock period is defined in the security manager and it's customizable\n * This function can only be called when account is unlocked by owner or guardians\n * @dev This method checks the caller and if the account is currently locked and locks the account after fetching the\n * Lock period from the owner.\n */\n function lock() external override onlyGuardianOrOwner onlyWhenUnlocked {\n uint256 unlockTime = block.timestamp + getLockPeriod();\n ++LibFacetStorage.lockStorage().nonce;\n LibAppStorage.setLock(unlockTime, LockFacet.lock.selector);\n emit Locked(uint64(unlockTime));\n }\n\n /**\n * @notice Locks the account when the account is locked. This function can be called by anyone but must provide the approver address and signature.\n * The approver should be one of the guardians or owner.\n * @dev This method takes the approver address and the signature. After validating the address and the signature, it unlocks the account immediately.\n * Only one of the guardian or owner is required to lock and unlock the account.\n * @param _approver Address of approver approving the unlock of Barz account\n * @param _signature Signature of the approver that signed the msg hash for unlocking the account\n */\n function unlock(\n address _approver,\n bytes calldata _signature\n ) external override onlyWhenLocked {\n if (_approver != address(this) && !LibGuardian.isGuardian(_approver))\n revert LockFacet__InvalidApprover();\n if (\n !SignatureChecker.isValidSignatureNow(\n _approver,\n getUnlockHash(),\n _signature\n )\n ) revert LockFacet__InvalidSignature();\n _unlock();\n }\n\n /**\n * @notice Unlocks the account and increments the lock nonce\n */\n function _unlock() private {\n if (s.locks[INNER_STRUCT].locker != LockFacet.lock.selector)\n revert LockFacet__CannotUnlock();\n ++LibFacetStorage.lockStorage().nonce;\n LibAppStorage.setLock(0, bytes4(0));\n emit Unlocked();\n }\n\n /**\n * @notice Returns the lock period of current Barz account. Lock period information is held by Security Manager\n * @return lockPeriod Uint value of lock period in seconds\n */\n function getLockPeriod() public view override returns (uint256 lockPeriod) {\n lockPeriod = securityManager.lockPeriodOf(address(this));\n if (lockPeriod == 0) revert LockFacet__InvalidRecoveryPeriod();\n }\n\n /**\n * @notice Returns if the account is locked or not\n * @dev This method fetches the current block timestamp and compares that with release time.\n * After checking the timestamp and release time, it returns if the account is still locked or not.\n * @return isLocked_ Uint value of lock period in seconds\n */\n function isLocked() public view override returns (bool isLocked_) {\n isLocked_ = uint64(block.timestamp) < s.locks[INNER_STRUCT].release;\n }\n\n /**\n * @notice Calculates the unlock hash and returns the unlock hash safe from signature reply attack\n * @dev This method calculates the unlock hash with EIP-191 prefix, wallet address, chainID, and nonce\n * It packs the result and packs them and hashes it.\n * @return unlockHash Bytes32 unlock hash\n */\n function getUnlockHash() public view override returns (bytes32 unlockHash) {\n unlockHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n \"Unlock\",\n address(this),\n block.chainid,\n lockNonce()\n )\n )\n )\n );\n }\n\n /**\n * @notice Returns lock nonce of account. Reads nonce from lock storage within facet storage\n * @return lockNonce_ Uint128 value of lock nonce. This is incremented whenever the account is lock/unlocked\n */\n function lockNonce() public view override returns (uint128 lockNonce_) {\n lockNonce_ = LibFacetStorage.lockStorage().nonce;\n }\n\n /**\n * @notice Returns the overall information of current lock\n * @return pendingLock Struct value including all information of pending lock\n */\n function getPendingLock()\n public\n view\n override\n returns (Lock memory pendingLock)\n {\n pendingLock = s.locks[INNER_STRUCT];\n }\n}\n" + }, + "contracts/facets/Modifiers.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {IFacetRegistry} from \"../infrastructure/interfaces/IFacetRegistry.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\n\n/**\n * @title Modifiers\n * @dev Responsible for providing modifiers/util functions to Facet contracts\n * @author David Yongjun Kim (@Powerstream3604)\n */\nabstract contract Modifiers is BarzStorage {\n uint8 constant INNER_STRUCT = 0;\n\n error CallerNotGuardian();\n error CallerNotGuardianOrOwner();\n error DuplicateApprover();\n error ZeroApproverLength();\n error UnregisteredFacetAndSelectors();\n\n /**\n * @notice Modifier to only allow guardian to make a call, reverts if any other entity is the caller\n */\n modifier onlyGuardian() {\n if (!LibGuardian.isGuardian(msg.sender)) revert CallerNotGuardian();\n _;\n }\n\n /**\n * @notice Modifier to only allow guardian or owner to make a call, reverts if any other entity is the caller\n */\n modifier onlyGuardianOrOwner() {\n if (!LibGuardian.isGuardian(msg.sender) && address(this) != msg.sender)\n revert CallerNotGuardianOrOwner();\n _;\n }\n\n /**\n * @notice Checks if the approver address is the array is unique with no duplicate\n * @dev This method loops through the array and checks if a duplicate address exists, it reverts if duplicate address exists\n * @param approvers Array of address\n */\n function _checkApprover(\n address[] memory approvers\n ) internal pure returns (bool) {\n uint256 approverLength = approvers.length;\n if (0 == approverLength) revert ZeroApproverLength();\n for (uint256 i; i < approverLength - 1; ) {\n for (uint256 j = i + 1; j < approverLength; ) {\n if (approvers[i] == approvers[j]) {\n revert DuplicateApprover(); // Found a duplicate\n }\n unchecked {\n ++j;\n }\n }\n unchecked {\n ++i;\n }\n }\n return false; // No duplicates found\n }\n\n /**\n * @notice Checks if the facet getting added or replaced is registered to facet registry\n * @dev This method loops through the cut and checks if the facet getting added/replaced is registered to facet registry\n * @param _diamondCut Array of FacetCut, data for diamondCut defined in EIP-2535\n */\n function _checkFacetCutValidity(\n IDiamondCut.FacetCut[] memory _diamondCut\n ) internal view {\n uint256 diamondCutLength = _diamondCut.length;\n for (uint256 i; i < diamondCutLength; ) {\n if (\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Add ||\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Replace\n ) {\n if (\n !s.facetRegistry.areFacetFunctionSelectorsRegistered(\n _diamondCut[i].facetAddress,\n _diamondCut[i].functionSelectors\n )\n ) revert UnregisteredFacetAndSelectors();\n }\n unchecked {\n ++i;\n }\n }\n }\n}\n" + }, + "contracts/facets/RestrictionsFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, RestrictionsStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {IRestriction} from \"../restrictions/IRestriction.sol\";\nimport {IRestrictionsFacet} from \"./interfaces/IRestrictionsFacet.sol\";\n\n/**\n * @title Restrictions facet\n * @dev Responsible for storing and verifying different kinds of restrictions, for example:\n * - Whitelist / Blacklist\n * - Daily limits\n * - Trading time restrictions\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract RestrictionsFacet is IRestrictionsFacet {\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceRestrictionsInitialize();\n }\n\n /**\n * @notice Intialize restrictions of Barz. Restrictions facet call restriction contracts for restriction validation\n * before each call\n * @param _restrictions The initial array of restrictions.\n * @return initSuccess Int value showing if the initialization of restriction is successful\n */\n function initializeRestrictions(\n address[] calldata _restrictions\n ) public override returns (uint256 initSuccess) {\n LibDiamond.enforceIsSelf();\n LibAppStorage.enforceRestrictionsInitialize();\n\n uint256 restrictionsLength = _restrictions.length;\n if (restrictionsLength == 0) {\n // You can't initialize RestrictionsFacet with an empty list of restrictions\n revert RestrictionsFacet__EmptyRestrictionsList();\n }\n for (uint256 i; i < restrictionsLength; ) {\n if (_restrictions[i] == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictions();\n unchecked {\n ++i;\n }\n }\n\n LibFacetStorage.restrictionsStorage().restrictions = _restrictions;\n _updateRestrictionsMap(_restrictions, true);\n initSuccess = 1;\n }\n\n /**\n * @notice Unitialize restrictions of Barz\n * @return uninitSuccess Int value showing if the initialization of restriction is successful\n */\n function uninitializeRestrictions()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibDiamond.enforceIsSelf();\n LibAppStorage.setRestrictionsUninitialized();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n _updateRestrictionsMap(restrictionsStorage.restrictions, false);\n restrictionsStorage.restrictions = new address[](0);\n uninitSuccess = 1;\n }\n\n /**\n * @notice Returns the list of Restrictions contract address\n * @return restrictions Addresses of IRestriction which are currently active\n */\n function getRestrictions()\n public\n view\n override\n returns (address[] memory restrictions)\n {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n restrictions = restrictionsStorage.restrictions;\n }\n\n /**\n * @notice Adds restrictions to Barz with validation on the restriction contract address.\n * This method is only callable by the owner(self).\n * @param _restriction The address of the restriction to be added.\n */\n function addRestriction(address _restriction) external override {\n LibDiamond.enforceIsSelf();\n if (LibDiamond.restrictionsFacet() == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictionsFacet();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n if (_restriction == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictions();\n if (restrictionsStorage.exists[_restriction])\n revert RestrictionsFacet__RestrictionAlreadyExists();\n\n restrictionsStorage.restrictions.push(_restriction);\n restrictionsStorage.exists[_restriction] = true;\n\n emit RestrictionAdded(_restriction);\n }\n\n /**\n * @notice Remove restrictions from Barz if it existed. This method is only callable by the owner(self).\n * @param _restriction The address of the restriction to be removed.\n */\n function removeRestriction(address _restriction) external override {\n LibDiamond.enforceIsSelf();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n if (!restrictionsStorage.exists[_restriction])\n revert RestrictionsFacet__RestrictionNotFound();\n\n address[] storage restrictions = restrictionsStorage.restrictions;\n\n uint256 indexToDelete = restrictions.length;\n uint256 restrictionsLen = restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n if (restrictions[i] == _restriction) {\n indexToDelete = i;\n break;\n }\n unchecked {\n ++i;\n }\n }\n\n if (indexToDelete == 0 && restrictionsLen == 1) {\n revert RestrictionsFacet__RemainingRestrictionsCantBeEmpty();\n } else if (indexToDelete == restrictionsLen) {\n revert RestrictionsFacet__RestrictionNotFound();\n } else {\n restrictions[indexToDelete] = restrictions[restrictionsLen - 1];\n restrictions.pop();\n }\n\n restrictionsStorage.exists[_restriction] = false;\n emit RestrictionRemoved(_restriction);\n }\n\n /**\n * @notice Sets the restrictions address value mapping to true or false when adding/removing restriction contracts\n * @param _restrictions List of restriction contracts address\n * @param _newValue Bool value to flag to the list of restrictions contracts\n */\n function _updateRestrictionsMap(\n address[] memory _restrictions,\n bool _newValue\n ) internal {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n uint restrictionsLen = _restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n restrictionsStorage.exists[_restrictions[i]] = _newValue;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @dev Iterates over all restrictions and verifies each of them with the transaction parameters.\n * @param _from The address of the sender, that will be signing the transaction.\n * @param _to The receiving address.\n * @param _value Amount of ETH to transfer from sender to recipient.\n * @param _calldata Optional field to include arbitrary data.\n * @return 0 if all the checks passed, 1 otherwise.\n */\n function verifyRestrictions(\n address _from,\n address _to,\n uint256 _value,\n bytes calldata _calldata\n ) external returns (uint256) {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n uint restrictionsLen = restrictionsStorage.restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n IRestriction restriction = IRestriction(\n restrictionsStorage.restrictions[i]\n );\n bool checkPassed = restriction.check(_from, _to, _value, _calldata);\n if (!checkPassed) {\n return 1;\n }\n unchecked {\n ++i;\n }\n }\n\n return 0;\n }\n}\n" + }, + "contracts/facets/SignatureMigrationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, SignatureMigrationStorage, SignatureMigrationConfig, SignatureMigrationApprovalConfig, ApprovalConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IDiamondCut} from \"./base/interfaces/IDiamondCut.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {ISignatureMigrationFacet} from \"./interfaces/ISignatureMigrationFacet.sol\";\n\n/**\n * @title Signature Migration Facet\n * @dev Responsible for migrating user signature scheme to a new scheme user sets\n * Which could include\n * - ECDSA on Secp256K1 Curve\n * - ECDSA on Secp256R1 Curve\n * - BLS, Schnorr, etc\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract SignatureMigrationFacet is ISignatureMigrationFacet, Modifiers {\n /**\n * @notice This modifier verifies if the public key format matches with the new verification facet\n * @param _publicKey Bytes of public key to be validated for the new verification facet\n * @param _newVerificationFacet Address of new verification facet\n */\n modifier validateKeyType(\n bytes memory _publicKey,\n address _newVerificationFacet\n ) {\n if (\n !IVerificationFacet(_newVerificationFacet).isValidKeyType(\n _publicKey\n )\n ) revert SignatureMigrationFacet__InvalidKeyType();\n _;\n }\n\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n // IMPORTANT NOTE: In the client side when they call this function, the func selectors should be sorted in ascending order\n // to prevent different hash with same items in the array\n /**\n * @notice Moves the state of migration to a pending state. When pending state is over after pending period time,\n * Migration can be finalized. This function can only be called by self and when the account is unlocked.\n * @dev This method checks if the caller is self and if guardians exists. It migrates signature request to a pending state\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function migrateSignatureScheme(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n public\n override\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n // Only self contract can call this function\n LibDiamond.enforceIsSelf();\n // Should revert if guardian exist\n if (0 != LibGuardian.guardianCount())\n revert SignatureMigrationFacet__InvalidRouteWithGuardian();\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n // NOTE: Migration requires a pending period & confirmation from owner to prevent a\n // single call changing the ownership of the wallet\n /**\n * @notice Migrate signature scheme when guardians exists. Verifies the signature of guardians and moves migration to pending state.\n * Which can then be finalized when pending period is over. Owner's approval is mandatory for migration to happen\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _approvers List of approvers. This could include owner\n */\n function migrateSignatureSchemeWithGuardian(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n )\n public\n override\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n // Should revert if does not guardian exist\n if (0 == LibGuardian.guardianCount())\n revert SignatureMigrationFacet__InvalidRouteWithGuardian();\n uint256 approversLength = _approvers.length;\n if (approversLength != _signatures.length)\n revert SignatureMigrationFacet__InvalidArrayLength();\n\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(migrationPublicKeyHash, _approvers);\n\n bool onChainOwnerApproval = getMigrationOwnerApprovalWithTimeValidity(\n migrationPublicKeyHash\n );\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n\n if (\n approversLength +\n getMigrationApprovalCountWithTimeValidity(\n migrationPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert SignatureMigrationFacet__InsufficientApprovers();\n {\n // To prevent Stack too deep\n bool ownerApproved;\n for (uint256 i; i < approversLength; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n address(this) != _approvers[i]\n ) revert SignatureMigrationFacet__InvalidGuardian();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert SignatureMigrationFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n migrationPublicKeyHash,\n _signatures[i]\n )\n ) revert SignatureMigrationFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n\n if (!ownerApproved && !onChainOwnerApproval)\n revert SignatureMigrationFacet__LackOfOwnerApproval();\n }\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Internal function that moves signature mgiration to a pending state.\n * @dev This method increments migration nonce and sets the migration in the migration config. Emits events for migration execution\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _migrateSignatureScheme(\n address _newVerificationFacet,\n bytes memory _newPublicKey,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal {\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n\n ++ms.nonce;\n uint64 migrateAfter = uint64(block.timestamp + getMigrationPeriod());\n\n ms.migrationConfigs[INNER_STRUCT] = SignatureMigrationConfig(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n migrateAfter\n );\n\n emit SignatureMigrationExecuted(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors,\n migrateAfter\n );\n }\n\n /**\n * @notice Approves signature scheme migration on-chain. This can be called by owner or guardian only when the account is unlocked.\n * When the threshold of the migration approval passed and owner approval is granted, it automatically moves migration to a pending state\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function approveSignatureSchemeMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n public\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit SignatureMigrationApproved(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n msg.sender,\n approvalValidUntil\n );\n if (\n getMigrationApprovalCountWithTimeValidity(migrationPublicKeyHash) >=\n LibGuardian.majorityOfGuardians() &&\n getMigrationOwnerApprovalWithTimeValidity(migrationPublicKeyHash)\n )\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Revokes the approval of signature migration done on-chain. Emits revoke event when revoked.\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function revokeSignatureMigrationApproval(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n external\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n if (!isMigrationApproved(migrationPublicKeyHash, msg.sender))\n revert SignatureMigrationFacet__CannotRevokeUnapproved();\n\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(false, 0);\n emit SignatureMigrationApprovalRevoked(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n msg.sender\n );\n }\n\n /**\n * @notice Finalizes the pending signature scheme migration. This function can only be called by owner.\n * It removes the facets of the previous verification facet and adds the new verification facet.\n * After finalizing migration, it emits migration event which shows the change of the verification facet\n */\n function finalizeSignatureMigration() external override {\n // NOTE: Only owner can call this function\n LibDiamond.enforceIsSelf();\n\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n\n if (!isMigrationPending())\n revert SignatureMigrationFacet__NonexistentMigration();\n\n if (\n uint64(block.timestamp) <=\n ms.migrationConfigs[INNER_STRUCT].migrateAfter\n ) revert SignatureMigrationFacet__MigrationPeriodNotOver();\n address newVerificationFacet = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationVerificationFacet;\n bytes4[] memory newVerificationFuncSelectors = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationSelectors;\n bytes memory newPublicKey = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationPublicKey;\n\n address prevVerificationFacet = LibLoupe.facetAddress(\n s.validateOwnerSignatureSelector\n );\n if (prevVerificationFacet == address(0))\n revert SignatureMigrationFacet__NonExistentVerificationFacet();\n\n IDiamondCut.FacetCut[] memory UninitCut;\n IDiamondCut.FacetCut[] memory InitCut;\n {\n bytes4[] memory prevVerificationFuncSelectors = LibLoupe\n .facetFunctionSelectors(prevVerificationFacet);\n\n UninitCut = new IDiamondCut.FacetCut[](1);\n InitCut = new IDiamondCut.FacetCut[](1);\n UninitCut[0] = IDiamondCut.FacetCut({\n facetAddress: address(0),\n action: IDiamondCut.FacetCutAction.Remove,\n functionSelectors: prevVerificationFuncSelectors\n });\n InitCut[0] = IDiamondCut.FacetCut({\n facetAddress: newVerificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: newVerificationFuncSelectors\n });\n {\n IDiamondCut.FacetCut[]\n memory facetCuts = new IDiamondCut.FacetCut[](2);\n facetCuts[0] = UninitCut[0];\n facetCuts[1] = InitCut[0];\n _checkFacetCutValidity(facetCuts);\n }\n LibAppStorage.initiateSignerMigration();\n address verificationFacet = address(\n bytes20(\n LibDiamond.diamondStorage().facets[\n s.validateOwnerSignatureSelector\n ]\n )\n );\n bytes memory uninitCall = abi.encodeWithSignature(\n \"uninitializeSigner()\"\n );\n (bool success, bytes memory result) = verificationFacet\n .delegatecall(uninitCall);\n require(success, \"MigrationFacet: uninitialize not successful\");\n uint256 validationData = uint256(bytes32(result));\n if (validationData == 0)\n revert SignatureMigrationFacet__SignerUninitializationFailure();\n\n LibDiamond.diamondCut(UninitCut, address(0), \"\");\n }\n {\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n newPublicKey\n );\n\n // Every Verification Facet should comply with initializeSigner(bytes)\n // to be compatible with the Barz contract(for initialization)\n LibDiamond.diamondCut(InitCut, newVerificationFacet, initCall);\n LibAppStorage.finalizeSignerMigration();\n emit SignatureSchemeMigration(\n prevVerificationFacet,\n newVerificationFacet,\n newPublicKey,\n newVerificationFuncSelectors\n );\n }\n }\n\n /**\n * @notice Approve cancellation of signature migration. If cancellation approval passes guardian threshold with owner approval\n * it automatically cancels the migration.\n * @dev This method checks if the caller is one of guardian or owner and sets true for the cancellation hash in the approval config.\n * It internally calls _cancelSignatureMigration for canceling the migration\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function approveCancelSignatureMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n external\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"CancelSignatureMigration\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit SignatureMigrationCancellationApproved(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n if (\n getMigrationApprovalCountWithTimeValidity(migrationPublicKeyHash) >=\n LibGuardian.majorityOfGuardians() &&\n getMigrationOwnerApprovalWithTimeValidity(migrationPublicKeyHash)\n )\n _cancelSignatureMigration(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Verifies the signature of guardians/owner and cancels the signature migration.\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _approvers List of approvers. This could include owner\n */\n function cancelSignatureMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n )\n external\n override\n validateKeyType(_newPublicKey, _newVerificationFacet)\n onlyWhenUnlocked\n {\n uint256 approversLength = _approvers.length;\n if (approversLength != _signatures.length)\n revert SignatureMigrationFacet__InvalidArrayLength();\n\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"CancelSignatureMigration\"\n );\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(migrationPublicKeyHash, _approvers);\n\n bool onChainOwnerApproval = getMigrationOwnerApprovalWithTimeValidity(\n migrationPublicKeyHash\n );\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n if (\n approversLength +\n getMigrationApprovalCountWithTimeValidity(\n migrationPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert SignatureMigrationFacet__InsufficientApprovers();\n {\n // To prevent stack too deep\n bool ownerApproved;\n for (uint256 i; i < approversLength; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n address(this) != _approvers[i]\n ) revert SignatureMigrationFacet__NonExistentApprover();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert SignatureMigrationFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n migrationPublicKeyHash,\n _signatures[i]\n )\n ) revert SignatureMigrationFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n if (!ownerApproved && !onChainOwnerApproval)\n revert SignatureMigrationFacet__LackOfOwnerApproval();\n }\n _cancelSignatureMigration(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Internal function that cancels signature migration.\n * @dev This method increments migration nonce and deletes the migration from the migration config. Emits events for migration cancellation\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _cancelSignatureMigration(\n address _newVerificationFacet,\n bytes memory _newPublicKey,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal {\n if (!isMigrationPending())\n revert SignatureMigrationFacet__NonexistentMigration();\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n ++ms.nonce;\n delete ms.migrationConfigs[INNER_STRUCT];\n emit SignatureMigrationCanceled(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Checks if the facets to be added from new verification facet is registered to facet registry\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _checkMigrationCutValidity(\n address _newVerificationFacet,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal view {\n IDiamondCut.FacetCut[] memory facetCuts = new IDiamondCut.FacetCut[](1);\n facetCuts[0] = IDiamondCut.FacetCut({\n facetAddress: _newVerificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: _newVerificationFuncSelectors\n });\n _checkFacetCutValidity(facetCuts);\n }\n\n /**\n * @notice Returns if the migration is pending of not\n * @dev This method fetches the migration storage and checks if the migrate after is above 0 value\n * @return isPending Bool value that shows if the migration is pending\n */\n function isMigrationPending()\n public\n view\n override\n returns (bool isPending)\n {\n SignatureMigrationStorage storage rs = LibFacetStorage\n .migrationStorage();\n isPending = rs.migrationConfigs[INNER_STRUCT].migrateAfter > 0;\n }\n\n /**\n * @notice Returns the migration hash. This function ensures that this hash is safe from replay attack by including\n * public key, verification facet, function selectors, salt, address, chainId, and nonce.\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _saltString Salt value for generating the migration hash\n * @return migrationKeyHash Bytes32 string of the migration key hash\n */\n function getApprovalMigrationKeyHash(\n bytes memory _newPublicKey,\n address _newVerificationFacet,\n bytes4[] memory _newVerificationFuncSelectors,\n string memory _saltString\n ) public view override returns (bytes32 migrationKeyHash) {\n migrationKeyHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n _newPublicKey,\n _newVerificationFacet,\n keccak256(abi.encode(_newVerificationFuncSelectors)),\n _saltString,\n address(this),\n block.chainid,\n LibFacetStorage.migrationStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Checks if the owner approved the hash for migration\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @return isApprovedByOwner Bool value of showing if the owner approved it or not\n */\n function getMigrationOwnerApprovalWithTimeValidity(\n bytes32 _migrationPublicKeyHash\n ) public view override returns (bool isApprovedByOwner) {\n isApprovedByOwner = isMigrationApproved(\n _migrationPublicKeyHash,\n address(this)\n );\n }\n\n /**\n * @notice Checks how many of the guardians approved the migration hash\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @return approvalCount Number of approvals\n */\n function getMigrationApprovalCountWithTimeValidity(\n bytes32 _migrationPublicKeyHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardiansLength = guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n if (isMigrationApproved(_migrationPublicKeyHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n return approvalCount;\n }\n\n /**\n * @notice Checks if the migration is approved by the given approver\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @param _approver Address of approver\n * @return isApproved Bool value if migration hash is approved\n */\n function isMigrationApproved(\n bytes32 _migrationPublicKeyHash,\n address _approver\n ) public view override returns (bool isApproved) {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n isApproved = (ms\n .isMigrationApproved[_migrationPublicKeyHash][_approver].isApproved &&\n block.timestamp <\n ms\n .isMigrationApproved[_migrationPublicKeyHash][_approver]\n .validUntil);\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _migrationPublicKeyHash Hash of migration information\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _migrationPublicKeyHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isMigrationApproved(_migrationPublicKeyHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert SignatureMigrationFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the migration period of this wallet\n * @dev This method fetches the migration period from the security manager\n * @return migrationPeriod Migration period of Barz contract fetched from security manager\n */\n function getMigrationPeriod()\n internal\n view\n returns (uint128 migrationPeriod)\n {\n migrationPeriod = securityManager.migrationPeriodOf(address(this));\n if (migrationPeriod == 0)\n revert SignatureMigrationFacet__InvalidMigrationPeriod();\n }\n\n /**\n * @notice Returns the validation period of this wallet\n * @dev This method fetches the validation period from the security manager\n * @return approvalValidationPeriod Validation period of Barz contract fetched from security manager\n */\n function getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod == 0)\n revert SignatureMigrationFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the migration nonce of this wallet\n * @dev This method fetches the nonce from migration storage\n * @return migrationNonce Nonce of migration to protect from reply attacks\n */\n function getMigrationNonce()\n public\n view\n override\n returns (uint128 migrationNonce)\n {\n migrationNonce = LibFacetStorage.migrationStorage().nonce;\n }\n\n /**\n * @notice Returns the migration configuration of this wallet\n * @dev This method fetches the migration config from the migration storage\n * @return pendingMigrationConfig Migration config currently pending for signature migration\n */\n function getPendingMigration()\n external\n view\n override\n returns (SignatureMigrationConfig memory pendingMigrationConfig)\n {\n pendingMigrationConfig = LibFacetStorage\n .migrationStorage()\n .migrationConfigs[INNER_STRUCT];\n }\n}\n" + }, + "contracts/facets/TokenReceiverFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {IERC1155Receiver} from \"../interfaces/ERC/IERC1155Receiver.sol\";\nimport {IERC677Receiver} from \"../interfaces/ERC/IERC677Receiver.sol\";\n\n/**\n * @title TokenReceiver Facet\n * @dev Contract that enables receiving ERC721/ERC1155/ERC777/ERC677 Tokens with safe transfer\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract TokenReceiverFacet is\n IERC721Receiver,\n IERC1155Receiver,\n IERC777Recipient,\n IERC677Receiver\n{\n /**\n * @notice Handles ERC721 Token callback.\n * return Standardized onERC721Received return value.\n */\n function onERC721Received(\n address,\n address,\n uint256,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC721Receiver.onERC721Received.selector;\n }\n\n /**\n * @notice Handles ERC1155 Token callback.\n * return Standardized onERC1155Received return value.\n */\n function onERC1155Received(\n address,\n address,\n uint256,\n uint256,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC1155Receiver.onERC1155Received.selector;\n }\n\n /**\n * @notice Handles ERC1155 Token batch callback.\n * return Standardized onERC1155BatchReceived return value.\n */\n function onERC1155BatchReceived(\n address,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC1155Receiver.onERC1155BatchReceived.selector;\n }\n\n /**\n * @notice Handles ERC777 Token callback.\n * Does not return value, empty implementation.\n */\n function tokensReceived(\n address,\n address,\n address,\n uint256,\n bytes calldata,\n bytes calldata\n ) external pure override {}\n\n /**\n * @notice Handles ERC677 Token callback.\n * return true.\n */\n function onTokenTransfer(\n address,\n uint256,\n bytes calldata\n ) external pure override returns (bool) {\n return true;\n }\n}\n" + }, + "contracts/facets/verification/MultiSigFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {UserOperation} from \"../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../../libraries/LibLoupe.sol\";\nimport {LibAppStorage} from \"../../libraries/LibAppStorage.sol\";\nimport {LibMultiSigStorage, MultiSigStorage} from \"../../libraries/LibMultiSigStorage.sol\";\nimport {IERC1271} from \"../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../interfaces/IVerificationFacet.sol\";\nimport {IMultiSigFacet} from \"../interfaces/IMultiSigFacet.sol\";\n\n/**\n * @title Multi-sig facet\n * @dev Multi-signature Facet with custom threshold.\n * Wallet that adds this facet becomes a multi-sig wallet.\n * Reference signature_format.md documentation for Multi-sig facet details\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract MultiSigFacet is IMultiSigFacet, IVerificationFacet, IERC1271 {\n using ECDSA for bytes32;\n\n address public immutable self;\n\n address internal constant SENTINEL_OWNERS = address(0x1);\n uint256 internal constant ADDRESS = 20;\n uint256 internal constant SIG_TYPE = 1;\n uint256 internal constant SIG_LEN = 4;\n uint256 internal constant THRESHOLD = 4;\n uint256 internal constant INVALID_SIG = 1;\n uint256 internal constant VALID_SIG = 0;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in Multisig Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the right format and initializes signer storage in k1 storage.\n * @param _owners Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _owners\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n\n if (!isValidKeyType(_owners)) revert MultiSigFacet__InvalidInitData();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n uint256 threshold = uint256(uint32(bytes4(_owners)));\n uint256 ownerCount = (_owners.length - THRESHOLD) / ADDRESS;\n\n if (threshold == 0) revert MultiSigFacet__InvalidThreshold();\n if (ownerCount == 0) revert MultisigFacet__InvalidOwnerCount();\n\n address currentOwner = SENTINEL_OWNERS;\n uint256 ptr = THRESHOLD;\n address owner_;\n for (uint256 i; i < ownerCount; ) {\n owner_ = address(bytes20(_owners[ptr:ptr + ADDRESS]));\n ptr += ADDRESS;\n if (\n owner_ == address(0) ||\n owner_ == SENTINEL_OWNERS ||\n owner_ == address(this) ||\n owner_ == currentOwner\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[owner_] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n\n ms.owners[currentOwner] = owner_;\n currentOwner = owner_;\n\n unchecked {\n ++i;\n }\n }\n ms.owners[currentOwner] = SENTINEL_OWNERS;\n ms.ownerCount = ownerCount;\n ms.threshold = threshold;\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_owners);\n }\n\n /**\n * @notice Uninitialize signer in K1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n ++ms.counter;\n address[] memory ownerlist = getOwners();\n uint256 ownerlistLength = ownerlist.length;\n for (uint256 i; i < ownerlistLength; ) {\n ms.owners[ownerlist[i]] = address(0);\n unchecked {\n ++i;\n }\n }\n ms.owners[SENTINEL_OWNERS] = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls checkSignatures with\n * user operation hash and signature together with the threshold.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n // Data 1 is invalid, Data 0 is valid\n validationData = checkSignatures(\n userOpHash,\n userOp.signature,\n LibMultiSigStorage.multisigStorage().threshold\n );\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n return this.validateOwnerSignature.selector;\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n uint totalLength = ms.ownerCount * ADDRESS;\n bytes memory result = new bytes(totalLength);\n\n // populate return array\n uint256 index;\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n while (currentOwner != SENTINEL_OWNERS) {\n assembly {\n mstore(\n add(result, add(32, mul(index, ADDRESS))),\n shl(96, currentOwner)\n )\n }\n currentOwner = ms.owners[currentOwner];\n index++;\n }\n\n return result;\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key should comply with the format in the signature_format.md doc\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n uint256 publicKeyLength = _publicKey.length;\n if (\n publicKeyLength < ADDRESS + THRESHOLD ||\n (publicKeyLength - THRESHOLD) % ADDRESS != 0\n ) return false;\n\n uint256 threshold = uint256(uint32(bytes4(_publicKey)));\n uint256 ownerCount = (publicKeyLength - THRESHOLD) / ADDRESS;\n\n isValid = !(ownerCount < threshold || threshold == 0);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes calldata _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (checkSignatures(\n _hash,\n _signature,\n LibMultiSigStorage.multisigStorage().threshold\n ) == VALID_SIG)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n\n /**\n * @notice Validates the format of the signature and verifies if the signature is signed by the expected key.\n * Reference signature_format.md doc for details about signature format and signature types\n * @param _dataHash Bytes value of data hash signed by the owners\n * @param _signatures Bytes value of signature which should comply with signature format\n * @param _threshold Uint256 value of current Multi-sig Barz's threshold\n */\n function checkSignatures(\n bytes32 _dataHash,\n bytes calldata _signatures,\n uint256 _threshold\n ) public view returns (uint256) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n address lastOwner = address(0);\n address currentOwner;\n bytes memory signature;\n uint256 signatureType;\n uint256 nextOffset;\n uint256 i;\n for (i; i < _threshold; ) {\n (\n currentOwner,\n signature,\n signatureType,\n nextOffset\n ) = splitSignatures(_signatures, nextOffset);\n if (nextOffset == 0 && i + 1 < _threshold) return INVALID_SIG;\n if (signatureType == 1) {\n // If signatureType is 1 then it is default dataHash signed.\n // This also includes the contract signature\n if (\n !SignatureChecker.isValidSignatureNow(\n currentOwner,\n _dataHash,\n signature\n )\n ) return INVALID_SIG;\n } else if (signatureType == 2) {\n // If signatureType is 2 then it is an approved hash\n if (ms.approvedHashes[ms.counter][currentOwner][_dataHash] == 0)\n return INVALID_SIG;\n } else if (signatureType == 3) {\n // If signatureType is 3 then it is a signed message hash\n // This also includes the contract signature\n bytes32 msgHash = _dataHash.toEthSignedMessageHash();\n if (\n !SignatureChecker.isValidSignatureNow(\n currentOwner,\n msgHash,\n signature\n )\n ) return INVALID_SIG;\n } else revert MultiSigFacet__InvalidRoute();\n if (\n currentOwner <= lastOwner ||\n ms.owners[currentOwner] == address(0) ||\n currentOwner == SENTINEL_OWNERS\n ) return INVALID_SIG;\n lastOwner = currentOwner;\n\n unchecked {\n ++i;\n }\n }\n return VALID_SIG;\n }\n\n /**\n * @notice Split signatures into each individual signatures. Should comply with signature format to be split\n * @param _signatures Bytes value of signature\n * @param _nextOffset Uint256 value of next offset to start splitting the signature\n */\n function splitSignatures(\n bytes calldata _signatures,\n uint256 _nextOffset\n )\n public\n pure\n returns (\n address owner_,\n bytes memory signature,\n uint256 signatureType,\n uint256 nextOffset\n )\n {\n uint256 signaturesLength = _signatures.length;\n\n if (signaturesLength <= _nextOffset + ADDRESS + SIG_LEN)\n revert MultiSigFacet__InsufficientSignerLength();\n\n owner_ = address(\n bytes20(_signatures[_nextOffset:_nextOffset + ADDRESS])\n );\n\n signatureType = uint256(\n uint8(\n bytes1(\n _signatures[_nextOffset + ADDRESS:_nextOffset +\n ADDRESS +\n SIG_TYPE]\n )\n )\n );\n\n if (signatureType > 3 || signatureType == 0)\n revert MultiSigFacet__InvalidSignatureType();\n uint256 offSet = _nextOffset + ADDRESS + SIG_TYPE;\n uint256 siglen = uint256(\n uint32(bytes4(_signatures[offSet:offSet + SIG_LEN]))\n );\n if (offSet + siglen > signaturesLength)\n revert MultiSigFacet__InvalidSignatureLength();\n\n offSet += SIG_LEN;\n if (offSet + siglen == signaturesLength) nextOffset = 0;\n else nextOffset = offSet + siglen;\n\n signature = _signatures[offSet:offSet + siglen];\n }\n\n /**\n * @notice Approves the hash of userOperation on-chain. This can only be called by owners.\n * @param _hashToApprove Bytes value of UserOperation hash to approve\n */\n function approveHash(bytes32 _hashToApprove) external {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (ms.owners[msg.sender] == address(0))\n revert MultiSigFacet__OnlyOwner();\n\n ms.approvedHashes[ms.counter][msg.sender][_hashToApprove] = 1;\n emit HashApproved(_hashToApprove, msg.sender);\n }\n\n /**\n * @notice Add owner to Barz. Update thresold if threshold is given different from current threshold\n * @dev This can only be done via a Self call.\n * @param _newOwner Address of new owner to be added\n * @param _threshold Uint256 value of threshold\n */\n function addOwner(address _newOwner, uint256 _threshold) external {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (\n _newOwner == address(0) ||\n _newOwner == SENTINEL_OWNERS ||\n _newOwner == address(this)\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_newOwner] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n\n ms.owners[_newOwner] = ms.owners[SENTINEL_OWNERS];\n ms.owners[SENTINEL_OWNERS] = _newOwner;\n ++ms.ownerCount;\n emit OwnerAdded(_newOwner);\n\n if (ms.threshold != _threshold) changeThreshold(_threshold);\n }\n\n /**\n * @notice Remove owner from Barz. Update thresold if threshold is given different from current threshold\n * @dev This can only be done via a Self call.\n * @param _prevOwner Address of owner located right behind the removed owner address in the linked list\n * @param _removedOwner Address of owner to be removed\n * @param _threshold Uint256 value of threshold\n */\n function removeOwner(\n address _prevOwner,\n address _removedOwner,\n uint256 _threshold\n ) external {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (ms.ownerCount - 1 < _threshold)\n revert MultiSigFacet__InvalidThreshold();\n if (_removedOwner == address(0) || _removedOwner == SENTINEL_OWNERS)\n revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_prevOwner] != _removedOwner)\n revert MultiSigFacet__InvalidOwnerPair();\n\n ms.owners[_prevOwner] = ms.owners[_removedOwner];\n ms.owners[_removedOwner] = address(0);\n --ms.ownerCount;\n emit OwnerRemoved(_removedOwner);\n\n if (ms.threshold != _threshold) changeThreshold(_threshold);\n }\n\n /**\n * @notice Swap owner in Barz.\n * @dev This can only be done via a Self call.\n * @param _prevOwner Address of owner located right behind the removed owner address in the linked list\n * @param _oldOwner Address of owner to be removed\n * @param _newOwner Address of owner to be added\n */\n function swapOwner(\n address _prevOwner,\n address _oldOwner,\n address _newOwner\n ) public {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (\n _newOwner == address(0) ||\n _newOwner == SENTINEL_OWNERS ||\n _newOwner == address(this)\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_newOwner] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n if (_oldOwner == address(0) || _oldOwner == SENTINEL_OWNERS)\n revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_prevOwner] != _oldOwner)\n revert MultiSigFacet__InvalidOwnerPair();\n\n ms.owners[_newOwner] = ms.owners[_oldOwner];\n ms.owners[_prevOwner] = _newOwner;\n ms.owners[_oldOwner] = address(0);\n emit OwnerRemoved(_oldOwner);\n emit OwnerAdded(_newOwner);\n }\n\n /**\n * @notice Changes the threshold of the Barz to `_threshold`.\n * @dev This can only be done via a Self call.\n * @param _threshold New threshold\n */\n function changeThreshold(uint256 _threshold) public {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (_threshold > ms.ownerCount || _threshold == 0)\n revert MultiSigFacet__InvalidThreshold();\n\n ms.threshold = _threshold;\n emit ThresholdChanged(_threshold);\n }\n\n /**\n * @notice Checks if the given address is owner\n * @param _owner Address to be checked if it's owner\n * @return isOwner_ Bool value showing if it's owner address\n */\n function isOwner(address _owner) public view returns (bool isOwner_) {\n isOwner_ = (_owner != SENTINEL_OWNERS &&\n LibMultiSigStorage.multisigStorage().owners[_owner] != address(0));\n }\n\n /**\n * @notice Returns the threshold of Barz\n * @return threshold Threshold of the Barz account\n */\n function getThreshold() public view returns (uint256 threshold) {\n threshold = LibMultiSigStorage.multisigStorage().threshold;\n }\n\n /**\n * @notice Returns the list of owner addresses\n * @return owners List of owners\n */\n function getOwners() public view returns (address[] memory owners) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n owners = new address[](ms.ownerCount);\n\n uint256 index;\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n while (currentOwner != SENTINEL_OWNERS) {\n owners[index] = currentOwner;\n currentOwner = ms.owners[currentOwner];\n index++;\n }\n }\n\n /**\n * @notice Returns the previous owner in the linked list\n * @param _owner Address of owner\n * @return prevOwner Address of previous owner\n */\n function getPrevOwner(\n address _owner\n ) public view returns (address prevOwner) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n if (currentOwner == _owner) return SENTINEL_OWNERS;\n while (currentOwner != SENTINEL_OWNERS) {\n if (ms.owners[currentOwner] == _owner) return currentOwner;\n\n currentOwner = ms.owners[currentOwner];\n }\n return address(0);\n }\n\n /**\n * @notice Returns of the owner is approved by given owner address\n * @param _owner Address of owner\n * @param _hash Hash of UserOperation\n * @return isApproved Bool value showing if the hash is approved by owner\n */\n function isApprovedHash(\n address _owner,\n bytes32 _hash\n ) public view returns (bool isApproved) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n isApproved = (ms.approvedHashes[ms.counter][_owner][_hash] == 1);\n }\n}\n" + }, + "contracts/facets/verification/secp256k1/Secp256k1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {UserOperation} from \"../../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibAppStorage} from \"../../../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, Secp256k1VerificationStorage} from \"../../../libraries/LibFacetStorage.sol\";\nimport {LibLoupe} from \"../../../libraries/LibLoupe.sol\";\nimport {IERC1271} from \"../../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../../interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Secp256k1 verification facet\n * @dev Default Ethereum's elliptic curve\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract Secp256k1VerificationFacet is IVerificationFacet, IERC1271 {\n using ECDSA for bytes32;\n error Secp256k1VerificationFacet__InvalidSignerLength();\n address public immutable self;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in K1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\n * @param _publicKey Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _publicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n if (!isValidKeyType(_publicKey))\n revert Secp256k1VerificationFacet__InvalidSignerLength();\n\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(uint160(uint256(keccak256(_publicKey[1:]))));\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_publicKey);\n }\n\n /**\n * @notice Uninitialize signer in K1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\n * signer public key.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n validationData = validateSignature(\n userOp,\n userOpHash,\n k1Storage.signer\n );\n }\n\n /**\n * @notice Validates if the signature of UserOperation is signed by the given signer\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @param signer Address of signer who signed the contract, to be validated\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n address signer\n ) public pure returns (uint256 isValid) {\n bytes32 hash = userOpHash.toEthSignedMessageHash();\n isValid = (signer != hash.recover(userOp.signature)) ? 1 : 0;\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n ownerSignatureValidatorSelector = this.validateOwnerSignature.selector;\n // NOTE: The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory signer) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n signer = abi.encodePacked(k1Storage.signer);\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key length should be 65 in an uncompressed public key format\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (_hash.recover(_signature) ==\n LibFacetStorage.k1Storage().signer)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/Secp256r1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {UserOperation} from \"../../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibAppStorage} from \"../../../libraries/LibAppStorage.sol\";\nimport {LibLoupe} from \"../../../libraries/LibLoupe.sol\";\nimport {LibFacetStorage, Secp256r1VerificationStorage} from \"../../../libraries/LibFacetStorage.sol\";\nimport {Base64} from \"./utils/Base64.sol\";\nimport {LibSecp256r1} from \"./utils/LibSecp256r1.sol\";\nimport {IERC1271} from \"../../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../../interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Secp256r1 verification facet\n * @dev Primarily used to verify user ops signed with passkeys\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract Secp256r1VerificationFacet is IVerificationFacet, IERC1271 {\n error Secp256r1VerificationFacet__InvalidSignerLength();\n address public immutable self;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in R1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\n * @param _publicKey Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _publicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n\n if (!isValidKeyType(_publicKey))\n revert Secp256r1VerificationFacet__InvalidSignerLength();\n\n bytes memory publicKeyCoordinates = _publicKey[1:];\n uint256[2] memory q;\n assembly {\n // Copy the bytes from the input data into the uint256 array\n mstore(q, mload(add(publicKeyCoordinates, 32)))\n mstore(add(q, 32), mload(add(publicKeyCoordinates, 64)))\n }\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n r1Storage.q = q;\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_publicKey);\n }\n\n /**\n * @notice Uninitialize signer in R1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n r1Storage.q = [0, 0];\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\n * signer public key.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n validationData = validateSignature(userOp, userOpHash, r1Storage.q);\n }\n\n /**\n * @notice Validates if the signature of UserOperation is signed by the given signer\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @param q Public Key of signer who signed the contract, to be validated\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256[2] memory q\n ) public view returns (uint256 isValid) {\n isValid = (_validateSignature(q, userOpHash, userOp.signature)) ? 0 : 1;\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n return this.validateOwnerSignature.selector; // validateOwnerSignature(UserOperation calldata userOp,bytes32 userOpHash)\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory signer) {\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n signer = abi.encodePacked(r1Storage.q);\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key should in an uncompressed public key format\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = _validateSignature(\n LibFacetStorage.r1Storage().q,\n _hash,\n _signature\n )\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n\n function _validateSignature(\n uint256[2] memory q,\n bytes32 _hash,\n bytes memory _signature\n ) internal view returns (bool) {\n (\n uint256 rValue,\n uint256 sValue,\n bytes memory authenticatorData,\n string memory clientDataJSONPre,\n string memory clientDataJSONPost\n ) = abi.decode(_signature, (uint256, uint256, bytes, string, string));\n bytes32 clientHash;\n {\n string memory opHashBase64 = Base64.encode(bytes.concat(_hash));\n string memory clientDataJSON = string.concat(\n clientDataJSONPre,\n opHashBase64,\n clientDataJSONPost\n );\n clientHash = sha256(bytes(clientDataJSON));\n }\n bytes32 sigHash = sha256(bytes.concat(authenticatorData, clientHash));\n return LibSecp256r1.Verify(q, rValue, sValue, uint256(sigHash));\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/utils/Base64.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @dev Provides a set of functions to operate with Base64 strings.\n * modified for base64url https://datatracker.ietf.org/doc/html/rfc4648#section-5\n * _Available since v4.5._\n */\nlibrary Base64 {\n /**\n * @dev Base64 Encoding/Decoding Table\n */\n string internal constant _TABLE =\n \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_\";\n\n /**\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\n */\n function encode(bytes memory data) internal pure returns (string memory) {\n /**\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\n */\n if (data.length == 0) return \"\";\n\n // Loads the table into memory\n string memory table = _TABLE;\n\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\n // and split into 4 numbers of 6 bits.\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\n // - `data.length + 2` -> Round up\n // - `/ 3` -> Number of 3-bytes chunks\n // - `4 *` -> 4 characters for each chunk\n uint256 newlength = (data.length * 8) / 6;\n if (data.length % 6 > 0) {\n newlength++;\n }\n string memory result = new string(newlength);\n\n /// @solidity memory-safe-assembly\n assembly {\n // Prepare the lookup table (skip the first \"length\" byte)\n let tablePtr := add(table, 1)\n\n // Prepare result pointer, jump over length\n let resultPtr := add(result, 32)\n\n // Run over the input, 3 bytes at a time\n for {\n let dataPtr := data\n let endPtr := add(data, mload(data))\n } lt(dataPtr, endPtr) {\n\n } {\n // Advance 3 bytes\n dataPtr := add(dataPtr, 3)\n let input := mload(dataPtr)\n\n // To write each character, shift the 3 bytes (18 bits) chunk\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\n // and apply logical AND with 0x3F which is the number of\n // the previous character in the ASCII table prior to the Base64 Table\n // The result is then added to the table to get the character to write,\n // and finally write it in the result pointer but with a left shift\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(18, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(12, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(6, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n }\n }\n\n return result;\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/utils/LibSecp256r1.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n// Heavily inspired from\n// https://github.com/maxrobot/elliptic-solidity/blob/master/contracts/Secp256r1.sol\n// https://github.com/tdrerup/elliptic-curve-solidity/blob/master/contracts/curves/EllipticCurve.sol\n// modified to use precompile 0x05 modexp\n// and modified jacobian double\n// optimisations to avoid to an from from affine and jacobian coordinates\n\n// Additional Elliptic curve Public key / Signature validation added by\n// David Yonjun Kim (@Powerstream3604)\n\nstruct JPoint {\n uint256 x;\n uint256 y;\n uint256 z;\n}\n\nlibrary LibSecp256r1 {\n uint256 constant gx =\n 0x6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296;\n uint256 constant gy =\n 0x4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5;\n uint256 public constant pp =\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF;\n\n uint256 public constant nn =\n 0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551;\n uint256 constant a =\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC;\n uint256 constant b =\n 0x5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B;\n uint256 constant MOST_SIGNIFICANT =\n 0xc000000000000000000000000000000000000000000000000000000000000000;\n\n /*\n * Verify\n * @description - verifies that a public key has signed a given message\n * @param Q - public key coordinates X & Y\n * @param R - signature half R\n * @param S - signature half S\n * @param input - hashed message\n */\n function Verify(\n uint256[2] memory q,\n uint r,\n uint s,\n uint e\n ) internal view returns (bool) {\n if (q[0] > pp - 1 || q[1] > pp - 1) {\n return false;\n }\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\n return false;\n }\n if (\n mulmod(q[1], q[1], pp) !=\n addmod(\n addmod(\n mulmod(q[0], mulmod(q[0], q[0], pp), pp),\n mulmod(a, q[0], pp),\n pp\n ),\n b,\n pp\n )\n ) {\n return false;\n }\n\n JPoint[16] memory points = _preComputeJacobianPoints(q);\n return VerifyWithPrecompute(points, r, s, e);\n }\n\n function VerifyWithPrecompute(\n JPoint[16] memory points,\n uint r,\n uint s,\n uint e\n ) internal view returns (bool) {\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\n return false;\n }\n\n uint w = _primemod(s, nn);\n\n uint u1 = mulmod(e, w, nn);\n uint u2 = mulmod(r, w, nn);\n\n uint x;\n uint y;\n\n (x, y) = ShamirMultJacobian(points, u1, u2);\n return (x == r);\n }\n\n /*\n * Strauss Shamir trick for EC multiplication\n * https://stackoverflow.com/questions/50993471/ec-scalar-multiplication-with-strauss-shamir-method\n * we optimise on this a bit to do with 2 bits at a time rather than a single bit\n * the individual points for a single pass are precomputed\n * overall this reduces the number of additions while keeping the same number of doublings\n */\n function ShamirMultJacobian(\n JPoint[16] memory points,\n uint u1,\n uint u2\n ) internal view returns (uint, uint) {\n uint x = 0;\n uint y = 0;\n uint z = 0;\n uint bits = 128;\n uint index = 0;\n\n while (bits > 0) {\n if (z > 0) {\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\n }\n index =\n ((u1 & MOST_SIGNIFICANT) >> 252) |\n ((u2 & MOST_SIGNIFICANT) >> 254);\n if (index > 0) {\n (x, y, z) = _jAdd(\n x,\n y,\n z,\n points[index].x,\n points[index].y,\n points[index].z\n );\n }\n u1 <<= 2;\n u2 <<= 2;\n bits--;\n }\n (x, y) = _affineFromJacobian(x, y, z);\n return (x, y);\n }\n\n function _preComputeJacobianPoints(\n uint256[2] memory q\n ) internal pure returns (JPoint[16] memory points) {\n points[0] = JPoint(0, 0, 0);\n points[1] = JPoint(q[0], q[1], 1); // u2\n points[2] = _jPointDouble(points[1]);\n points[3] = _jPointAdd(points[1], points[2]);\n\n points[4] = JPoint(gx, gy, 1); // u1Points[1]\n points[5] = _jPointAdd(points[4], points[1]);\n points[6] = _jPointAdd(points[4], points[2]);\n points[7] = _jPointAdd(points[4], points[3]);\n\n points[8] = _jPointDouble(points[4]); // u1Points[2]\n points[9] = _jPointAdd(points[8], points[1]);\n points[10] = _jPointAdd(points[8], points[2]);\n points[11] = _jPointAdd(points[8], points[3]);\n\n points[12] = _jPointAdd(points[4], points[8]); // u1Points[3]\n points[13] = _jPointAdd(points[12], points[1]);\n points[14] = _jPointAdd(points[12], points[2]);\n points[15] = _jPointAdd(points[12], points[3]);\n }\n\n function _jPointAdd(\n JPoint memory p1,\n JPoint memory p2\n ) internal pure returns (JPoint memory) {\n uint x;\n uint y;\n uint z;\n (x, y, z) = _jAdd(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z);\n return JPoint(x, y, z);\n }\n\n function _jPointDouble(\n JPoint memory p\n ) internal pure returns (JPoint memory) {\n uint x;\n uint y;\n uint z;\n (x, y, z) = _modifiedJacobianDouble(p.x, p.y, p.z);\n return JPoint(x, y, z);\n }\n\n /* _affineFromJacobian\n * @desription returns affine coordinates from a jacobian input follows\n * golang elliptic/crypto library\n */\n function _affineFromJacobian(\n uint x,\n uint y,\n uint z\n ) internal view returns (uint ax, uint ay) {\n if (z == 0) {\n return (0, 0);\n }\n\n uint zinv = _primemod(z, pp);\n uint zinvsq = mulmod(zinv, zinv, pp);\n\n ax = mulmod(x, zinvsq, pp);\n ay = mulmod(y, mulmod(zinvsq, zinv, pp), pp);\n }\n\n /*\n * _jAdd\n * @description performs Jacobian addition as defined below:\n * http://www.hyperelliptic.org/EFD/g1p/data/shortw/jacobian/addition/add-2007-bl\n */\n function _jAdd(\n uint p1,\n uint p2,\n uint p3,\n uint q1,\n uint q2,\n uint q3\n ) internal pure returns (uint r1, uint r2, uint r3) {\n if (p3 == 0) {\n r1 = q1;\n r2 = q2;\n r3 = q3;\n\n return (r1, r2, r3);\n } else if (q3 == 0) {\n r1 = p1;\n r2 = p2;\n r3 = p3;\n\n return (r1, r2, r3);\n }\n\n assembly {\n let\n pd\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\n let z1z1 := mulmod(p3, p3, pd) // Z1Z1 = Z1^2\n let z2z2 := mulmod(q3, q3, pd) // Z2Z2 = Z2^2\n\n let u1 := mulmod(p1, z2z2, pd) // U1 = X1*Z2Z2\n let u2 := mulmod(q1, z1z1, pd) // U2 = X2*Z1Z1\n\n let s1 := mulmod(p2, mulmod(z2z2, q3, pd), pd) // S1 = Y1*Z2*Z2Z2\n let s2 := mulmod(q2, mulmod(z1z1, p3, pd), pd) // S2 = Y2*Z1*Z1Z1\n\n let p3q3 := addmod(p3, q3, pd)\n\n if lt(u2, u1) {\n u2 := add(pd, u2) // u2 = u2+pd\n }\n let h := sub(u2, u1) // H = U2-U1\n\n let i := mulmod(0x02, h, pd)\n i := mulmod(i, i, pd) // I = (2*H)^2\n\n let j := mulmod(h, i, pd) // J = H*I\n if lt(s2, s1) {\n s2 := add(pd, s2) // u2 = u2+pd\n }\n let rr := mulmod(0x02, sub(s2, s1), pd) // r = 2*(S2-S1)\n r1 := mulmod(rr, rr, pd) // X3 = R^2\n\n let v := mulmod(u1, i, pd) // V = U1*I\n let j2v := addmod(j, mulmod(0x02, v, pd), pd)\n if lt(r1, j2v) {\n r1 := add(pd, r1) // X3 = X3+pd\n }\n r1 := sub(r1, j2v)\n\n // Y3 = r*(V-X3)-2*S1*J\n let s12j := mulmod(mulmod(0x02, s1, pd), j, pd)\n\n if lt(v, r1) {\n v := add(pd, v)\n }\n r2 := mulmod(rr, sub(v, r1), pd)\n\n if lt(r2, s12j) {\n r2 := add(pd, r2)\n }\n r2 := sub(r2, s12j)\n\n // Z3 = ((Z1+Z2)^2-Z1Z1-Z2Z2)*H\n z1z1 := addmod(z1z1, z2z2, pd)\n j2v := mulmod(p3q3, p3q3, pd)\n if lt(j2v, z1z1) {\n j2v := add(pd, j2v)\n }\n r3 := mulmod(sub(j2v, z1z1), h, pd)\n }\n return (r1, r2, r3);\n }\n\n // Point doubling on the modified jacobian coordinates\n // http://point-at-infinity.org/ecc/Prime_Curve_Modified_Jacobian_Coordinates.html\n function _modifiedJacobianDouble(\n uint x,\n uint y,\n uint z\n ) internal pure returns (uint x3, uint y3, uint z3) {\n if (y == 0) return (0, 0, 0);\n assembly {\n let\n pd\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\n let z2 := mulmod(z, z, pd)\n let az4 := mulmod(\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC,\n mulmod(z2, z2, pd),\n pd\n )\n let y2 := mulmod(y, y, pd)\n let s := mulmod(0x04, mulmod(x, y2, pd), pd)\n let u := mulmod(0x08, mulmod(y2, y2, pd), pd)\n let m := addmod(mulmod(0x03, mulmod(x, x, pd), pd), az4, pd)\n let twos := mulmod(0x02, s, pd)\n let m2 := mulmod(m, m, pd)\n if lt(m2, twos) {\n m2 := add(pd, m2)\n }\n x3 := sub(m2, twos)\n if lt(s, x3) {\n s := add(pd, s)\n }\n y3 := mulmod(m, sub(s, x3), pd)\n if lt(y3, u) {\n y3 := add(pd, y3)\n }\n y3 := sub(y3, u)\n z3 := mulmod(0x02, mulmod(y, z, pd), pd)\n }\n }\n\n // Fermats little theorem https://en.wikipedia.org/wiki/Fermat%27s_little_theorem\n // a^(p-1) = 1 mod p\n // a^(-1) ≅ a^(p-2) (mod p)\n // we then use the precompile bigModExp to compute a^(-1)\n function _primemod(uint value, uint p) internal view returns (uint ret) {\n ret = modexp(value, p - 2, p);\n return ret;\n }\n\n // Wrapper for built-in BigNumber_modexp (contract 0x5) as described here. https://github.com/ethereum/EIPs/pull/198\n function modexp(\n uint _base,\n uint _exp,\n uint _mod\n ) internal view returns (uint ret) {\n // bigModExp(_base, _exp, _mod);\n assembly {\n if gt(_base, _mod) {\n _base := mod(_base, _mod)\n }\n // Free memory pointer is always stored at 0x40\n let freemem := mload(0x40)\n\n mstore(freemem, 0x20)\n mstore(add(freemem, 0x20), 0x20)\n mstore(add(freemem, 0x40), 0x20)\n\n mstore(add(freemem, 0x60), _base)\n mstore(add(freemem, 0x80), _exp)\n mstore(add(freemem, 0xa0), _mod)\n\n let success := staticcall(14000, 0x5, freemem, 0xc0, freemem, 0x20)\n switch success\n case 0 {\n revert(0x0, 0x0)\n }\n default {\n ret := mload(freemem)\n }\n }\n }\n}\n" + }, + "contracts/infrastructure/DefaultFallbackHandler.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC1155Receiver} from \"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\";\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {BaseAccount} from \"../aa-4337/core/BaseAccount.sol\";\nimport {DefaultLibDiamond} from \"../libraries/DefaultLibDiamond.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IAccountFacet} from \"../facets/interfaces/IAccountFacet.sol\";\nimport {IStorageLoupe} from \"../facets/base/interfaces/IStorageLoupe.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IERC677Receiver} from \"../interfaces/ERC/IERC677Receiver.sol\";\nimport {IERC165} from \"../interfaces/ERC/IERC165.sol\";\n\n/**\n * @title DefaultFallbackHandler\n * @dev A default fallback handler for Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DefaultFallbackHandler is IDiamondLoupe {\n /**\n * @notice Sets the middleware diamond for Barz wallet as a fallback handler\n * @dev This contract is also a diamond that holds the default facets to reduce gas cost for wallet activation.\n * Within the constructor this conducts diamond cut to initially setup the diamond. This is a non-upgradeable contract\n * @param _diamondCutFacet Address if diamond cut facet\n * @param _accountFacet Address account facet\n * @param _tokenReceiverFacet Address of token receiver facet\n * @param _diamondLoupeFacet Address of diamond loupe facet\n */\n constructor(\n address _diamondCutFacet,\n address _accountFacet,\n address _tokenReceiverFacet,\n address _diamondLoupeFacet\n ) payable {\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](4);\n bytes4[] memory functionSelectors = new bytes4[](1);\n functionSelectors[0] = IDiamondCut.diamondCut.selector;\n\n bytes4[] memory accountFunctionSelectors = new bytes4[](5);\n accountFunctionSelectors[0] = IAccountFacet.execute.selector;\n accountFunctionSelectors[1] = IAccountFacet.executeBatch.selector;\n accountFunctionSelectors[2] = BaseAccount.validateUserOp.selector;\n accountFunctionSelectors[3] = BaseAccount.getNonce.selector;\n accountFunctionSelectors[4] = BaseAccount.entryPoint.selector;\n\n bytes4[] memory receiverFacetSelectors = new bytes4[](5);\n receiverFacetSelectors[0] = IERC721Receiver.onERC721Received.selector;\n receiverFacetSelectors[1] = IERC1155Receiver.onERC1155Received.selector;\n receiverFacetSelectors[2] = IERC1155Receiver\n .onERC1155BatchReceived\n .selector;\n receiverFacetSelectors[3] = IERC777Recipient.tokensReceived.selector;\n receiverFacetSelectors[4] = IERC677Receiver.onTokenTransfer.selector;\n\n bytes4[] memory loupeFacetSelectors = new bytes4[](9);\n loupeFacetSelectors[0] = IDiamondLoupe.facets.selector;\n loupeFacetSelectors[1] = IDiamondLoupe.facetFunctionSelectors.selector;\n loupeFacetSelectors[2] = IDiamondLoupe.facetAddresses.selector;\n loupeFacetSelectors[3] = IDiamondLoupe.facetAddress.selector;\n loupeFacetSelectors[4] = IERC165.supportsInterface.selector;\n loupeFacetSelectors[5] = IStorageLoupe.facetsFromStorage.selector;\n loupeFacetSelectors[6] = IStorageLoupe\n .facetFunctionSelectorsFromStorage\n .selector;\n loupeFacetSelectors[7] = IStorageLoupe\n .facetAddressesFromStorage\n .selector;\n loupeFacetSelectors[8] = IStorageLoupe.facetAddressFromStorage.selector;\n\n {\n cut[0] = IDiamondCut.FacetCut({\n facetAddress: _diamondCutFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: functionSelectors\n });\n cut[1] = IDiamondCut.FacetCut({\n facetAddress: _accountFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: accountFunctionSelectors\n });\n cut[2] = IDiamondCut.FacetCut({\n facetAddress: _tokenReceiverFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: receiverFacetSelectors\n });\n cut[3] = IDiamondCut.FacetCut({\n facetAddress: _diamondLoupeFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: loupeFacetSelectors\n });\n\n DefaultLibDiamond.diamondCut(cut, address(0), \"\");\n }\n }\n\n /**\n * @notice Returns the facet information of call facets registered to this diamond.\n * @return facets_ The facet struct array including all facet information\n */\n function facets() external view override returns (Facet[] memory facets_) {\n DefaultLibDiamond.DiamondStorage storage ds = DefaultLibDiamond\n .diamondStorage();\n uint256 numFacets = ds.facetAddresses.length;\n facets_ = new Facet[](numFacets);\n for (uint256 i; i < numFacets; ) {\n address facetAddress_ = ds.facetAddresses[i];\n facets_[i].facetAddress = facetAddress_;\n facets_[i].functionSelectors = ds\n .facetFunctionSelectors[facetAddress_]\n .functionSelectors;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Gets all the function selectors provided by a facet.\n * @param _facet The facet address.\n * @return facetFunctionSelectors_\n */\n function facetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n facetFunctionSelectors_ = DefaultLibDiamond\n .diamondStorage()\n .facetFunctionSelectors[_facet]\n .functionSelectors;\n }\n\n /**\n * @notice Get all the facet addresses used by a diamond.\n * @return facetAddresses_\n */\n function facetAddresses()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n facetAddresses_ = DefaultLibDiamond.diamondStorage().facetAddresses;\n }\n\n /** @notice Gets the facet that supports the given selector.\n * @dev If facet is not found return address(0).\n * @param _functionSelector The function selector.\n * @return facetAddress_ The facet address.\n */\n function facetAddress(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n facetAddress_ = DefaultLibDiamond\n .diamondStorage()\n .selectorToFacetAndPosition[_functionSelector]\n .facetAddress;\n }\n}\n" + }, + "contracts/infrastructure/FacetRegistry.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport {IFacetRegistry} from \"./interfaces/IFacetRegistry.sol\";\n\n/**\n * @title Facet Registry\n * @dev Contract to keep track of facets & function selectors addable to user wallets\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract FacetRegistry is IFacetRegistry, Ownable2Step {\n mapping(address => FacetRegistryConfig) private facets;\n\n /**\n * @notice Transfers the ownership of the contract to the given owner\n * @param _owner Address of owner who has access to initialize the default security variables for security manager\n */\n constructor(address _owner) {\n transferOwnership(_owner);\n _transferOwnership(_owner);\n }\n\n /**\n * @dev Registers a facet and it's function selectors to registry\n * @param _facet address of facet\n * @param _facetSelectors list of function selectors of the facet\n */\n function registerFacetFunctionSelectors(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external override onlyOwner {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n uint256 facetSelectorsLength = _facetSelectors.length;\n for (uint256 i; i < facetSelectorsLength; ) {\n if (facetConfig.info[_facetSelectors[i]].exists)\n revert FacetRegistry__FacetSelectorAlreadyRegistered();\n\n facetConfig.info[_facetSelectors[i]].exists = true;\n facetConfig.info[_facetSelectors[i]].index = uint128(\n facetConfig.selectors.length\n );\n facetConfig.selectors.push(_facetSelectors[i]);\n unchecked {\n ++i;\n }\n }\n emit FacetFunctionSelectorsRegistered(_facet, _facetSelectors);\n }\n\n /**\n * @dev Removes a registered facet and it's corresponding selectors from registry\n * @param _facet address of facet\n * @param _facetSelectors list of function selectors of the facet\n */\n function removeFacetFunctionSelectors(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external override onlyOwner {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n uint256 facetSelectorsLength = _facetSelectors.length;\n for (uint256 i; i < facetSelectorsLength; ) {\n if (!facetConfig.info[_facetSelectors[i]].exists)\n revert FacetRegistry__UnregisteredFacetSelector();\n\n bytes4 lastSelector = facetConfig.selectors[\n facetConfig.selectors.length - 1\n ];\n if (_facetSelectors[i] != lastSelector) {\n uint128 targetIndex = facetConfig\n .info[_facetSelectors[i]]\n .index;\n facetConfig.selectors[targetIndex] = lastSelector;\n facetConfig.info[lastSelector].index = targetIndex;\n }\n facetConfig.selectors.pop();\n delete facetConfig.info[_facetSelectors[i]];\n\n unchecked {\n ++i;\n }\n }\n emit FacetFunctionSelectorsRemoved(_facet, _facetSelectors);\n }\n\n /**\n * @dev Checks if a facet and it's selectors given is registered to facet registry\n * @param _facet Address of facet\n * @param _facetSelectors List of function selectors of the facet\n */\n function areFacetFunctionSelectorsRegistered(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external view override returns (bool) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n uint256 facetSelectorsLength = _facetSelectors.length;\n if (facetSelectorsLength == 0) return false;\n for (uint256 i; i < facetSelectorsLength; ) {\n if (!facetConfig.info[_facetSelectors[i]].exists) return false;\n unchecked {\n ++i;\n }\n }\n return true;\n }\n\n /**\n * @dev Checks if a facet and it's selector given is registered to facet registry\n * @param _facet Address of facet\n * @param _facetSelector List of function selectors of the facet\n * @return isRegistered Bool value showing if the selector is registered\n */\n function isFacetFunctionSelectorRegistered(\n address _facet,\n bytes4 _facetSelector\n ) external view override returns (bool isRegistered) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n isRegistered = facetConfig.info[_facetSelector].exists;\n }\n\n /**\n * @dev Get the registered selectors of facet from registry\n * @param _facet Address of facet\n * @return selectors Selectors registered to facet\n */\n function getFacetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory selectors) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n selectors = facetConfig.selectors;\n }\n}\n" + }, + "contracts/infrastructure/interfaces/IFacetRegistry.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Registry Interface\n * @dev Interface for Facet Registry contract to keep track of facets & function selectors addable to user wallets\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IFacetRegistry {\n struct FacetRegistryConfig {\n bytes4[] selectors;\n mapping(bytes4 => FacetInfo) info;\n }\n struct FacetInfo {\n bool exists;\n uint128 index;\n }\n\n event FacetFunctionSelectorsRegistered(\n address facet,\n bytes4[] facetSelectors\n );\n event FacetFunctionSelectorsRemoved(address facet, bytes4[] facetSelectors);\n\n error FacetRegistry__FacetSelectorAlreadyRegistered();\n error FacetRegistry__UnregisteredFacetSelector();\n\n function registerFacetFunctionSelectors(\n address facet,\n bytes4[] calldata facetSelectors\n ) external;\n\n function removeFacetFunctionSelectors(\n address facet,\n bytes4[] calldata facetSelectors\n ) external;\n\n function areFacetFunctionSelectorsRegistered(\n address facet,\n bytes4[] calldata facetSelectors\n ) external view returns (bool);\n\n function isFacetFunctionSelectorRegistered(\n address facet,\n bytes4 facetSelector\n ) external view returns (bool);\n\n function getFacetFunctionSelectors(\n address facet\n ) external view returns (bytes4[] memory);\n}\n" + }, + "contracts/infrastructure/interfaces/ISecurityManager.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Registry Interface\n * @dev Infrastructure contract to manage security parameters of users\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface ISecurityManager {\n error SecurityManager__OutOfBoundary();\n error SecurityManager__CallerNotWallet();\n error SecurityManager__AlreadyIntialized();\n\n function initializeAdditionSecurityPeriod(\n uint128 defaultAdditionSecurityPeriod,\n uint128 minAdditionSecurityPeriod,\n uint128 maxAdditionSecurityPeriod\n ) external;\n\n function initializeRemovalSecurityPeriod(\n uint128 defaultRemovalSecurityPeriod,\n uint128 minRemovalSecurityPeriod,\n uint128 maxRemovalSecurityPeriod\n ) external;\n\n function initializeApprovalValidationPeriod(\n uint128 defaultApprovalValidationPeriod,\n uint128 minApprovalValidationPeriod,\n uint128 maxApprovalValidationPeriod\n ) external;\n\n function initializeMigrationPeriod(\n uint128 defaultMigrationPeriod,\n uint128 minMigrationPeriod,\n uint128 maxMigrationPeriod\n ) external;\n\n function initializeLockPeriod(\n uint128 defaultLockPeriod,\n uint128 minLockPeriod,\n uint128 maxLockPeriod\n ) external;\n\n function initializeRecoveryPeriod(\n uint128 defaultRecoveryPeriod,\n uint128 minRecoveryPeriod,\n uint128 maxRecoveryPeriod\n ) external;\n\n function initializeSecurityWindow(\n uint128 defaultSecurityWindow,\n uint128 minSecurityWindow,\n uint128 maxSecurityWindow\n ) external;\n\n function setAdditionSecurityPeriod(\n address wallet,\n uint128 additionSecurityPeriod\n ) external;\n\n function setRemovalSecurityPeriod(\n address wallet,\n uint128 removalSecurityPeriod\n ) external;\n\n function setSecurityWindow(address wallet, uint128 securityWindow) external;\n\n function setRecoveryPeriod(address wallet, uint128 recoveryPeriod) external;\n\n function setLockPeriod(address wallet, uint128 lockPeriod) external;\n\n function setApprovalValidationPeriod(\n address wallet,\n uint128 approvalValidationPeriod\n ) external;\n\n function setMigrationPeriod(\n address wallet,\n uint128 migrationPeriod\n ) external;\n\n function additionSecurityPeriodOf(\n address wallet\n ) external view returns (uint128);\n\n function removalSecurityPeriodOf(\n address wallet\n ) external view returns (uint128);\n\n function securityWindowOf(address wallet) external view returns (uint128);\n\n function recoveryPeriodOf(address wallet) external view returns (uint128);\n\n function lockPeriodOf(address wallet) external view returns (uint128);\n\n function migrationPeriodOf(address wallet) external view returns (uint128);\n\n function approvalValidationPeriodOf(\n address wallet\n ) external view returns (uint128);\n}\n" + }, + "contracts/infrastructure/RemoteStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IGuardianFacet} from \"../facets/interfaces/IGuardianFacet.sol\";\n\n/**\n * @title Remote Storage\n * @dev Remote storage allows you to associate addresses with an array of addresses on a standalone smart contract.\n * This could be useful when you don't want to use the local diamond storage for some purpose.\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\nabstract contract RemoteStorage {\n struct StorageConfig {\n address[] addresses;\n mapping(address => Info) info;\n }\n\n struct Info {\n bool exists;\n uint128 index;\n }\n\n mapping(address => StorageConfig) internal configs;\n\n event Added(address _address);\n event Removed(address _address);\n\n error RemoteStorage__CallerNotOwner();\n error RemoteStorage__CallerNotGuardianOrOwner();\n error RemoteStorage__AlreadyExists();\n error RemoteStorage__NotFound();\n error RemoteStorage__CallerNotGuardian();\n\n bytes4 constant IS_GUARDIAN_SELECTOR =\n bytes4(keccak256(\"isGuardian(address)\"));\n bytes4 constant GUARDIAN_COUNT = bytes4(keccak256(\"guardianCount()\"));\n\n /**\n * @notice Modifier to only allow the self to call. Reverts otherwise\n */\n modifier onlyWallet(address _wallet) {\n if (msg.sender != _wallet) revert RemoteStorage__CallerNotOwner();\n _;\n }\n\n /**\n * @notice Enfore the callet to be wallet of guardian of the wallet\n * @param _wallet Address of wallet\n */\n function enforceGuardianOrWallet(address _wallet) internal view {\n if (msg.sender == _wallet) return;\n address facetAddress = IDiamondLoupe(_wallet).facetAddress(\n IS_GUARDIAN_SELECTOR\n );\n if (facetAddress != address(0))\n if (IGuardianFacet(_wallet).isGuardian(msg.sender)) return;\n revert RemoteStorage__CallerNotGuardianOrOwner();\n }\n\n /**\n * @notice Enforce the caller to be wallet IF guardians doesn't exists and only guardian when guardians exists\n * @param _wallet Target wallet address to be handled by infrastructure contracts\n */\n function enforceWalletOrGuardianIfExists(address _wallet) internal view {\n address facetAddress;\n if (msg.sender == _wallet) {\n facetAddress = IDiamondLoupe(_wallet).facetAddress(GUARDIAN_COUNT);\n if (facetAddress == address(0)) return;\n uint256 guardianCount = IGuardianFacet(_wallet).guardianCount();\n if (guardianCount != 0) revert RemoteStorage__CallerNotGuardian();\n return;\n }\n facetAddress = IDiamondLoupe(_wallet).facetAddress(\n IS_GUARDIAN_SELECTOR\n );\n if (facetAddress != address(0))\n if (IGuardianFacet(_wallet).isGuardian(msg.sender)) return;\n\n revert RemoteStorage__CallerNotGuardianOrOwner();\n }\n\n /**\n * @notice Add address to storage and reverts if the address already exists.\n * This is an internal function callable from contracts that inherit this abstract contract\n * @param _wallet Address of wallet to add the address\n * @param _address Address to be added to wallet\n */\n function addAddress(address _wallet, address _address) internal {\n StorageConfig storage config = configs[_wallet];\n if (config.info[_address].exists) revert RemoteStorage__AlreadyExists();\n\n config.info[_address].exists = true;\n config.info[_address].index = uint128(config.addresses.length);\n config.addresses.push(_address);\n\n emit Added(_address);\n }\n\n /**\n * @notice Remove address from storage and reverts if the address already exists.\n * This is an internal function callable from contracts that inherit this abstract contract\n * @param _wallet Address of wallet to remove the address\n * @param _address Address to be removed from wallet\n */\n function removeAddress(address _wallet, address _address) internal {\n StorageConfig storage config = configs[_wallet];\n if (!config.info[_address].exists) revert RemoteStorage__NotFound();\n\n address lastAddress = config.addresses[config.addresses.length - 1];\n if (_address != lastAddress) {\n uint128 targetIndex = config.info[_address].index;\n config.addresses[targetIndex] = lastAddress;\n config.info[lastAddress].index = targetIndex;\n }\n config.addresses.pop();\n delete config.info[_address];\n\n emit Removed(_address);\n }\n\n /**\n * @notice Returns the address added to the given wallet\n * @param _wallet Address of wallet to fetch the addresses added to it\n * @return addresses List of addresses added to the wallet\n */\n function getAddresses(\n address _wallet\n ) internal view returns (address[] memory addresses) {\n StorageConfig storage config = configs[_wallet];\n addresses = new address[](config.addresses.length);\n uint addressesLen = config.addresses.length;\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns bool value checking if the address exists in the given wallet address\n * @param _wallet Wallet address to check\n * @param _address Address to fetch if the address if added to given wallet\n * @return exists_ Bool value showing if the address exists in wallet\n */\n function exists(\n address _wallet,\n address _address\n ) internal view returns (bool exists_) {\n exists_ = configs[_wallet].info[_address].exists;\n }\n\n /**\n * @notice Returns the number of addresses added to the wallet\n * @param _wallet Address of wallet to check\n * @return count_ Number of addresses added to wallet\n */\n function count(address _wallet) internal view returns (uint256 count_) {\n count_ = configs[_wallet].addresses.length;\n }\n}\n" + }, + "contracts/infrastructure/SecurityManager.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport {ISecurityManager} from \"./interfaces/ISecurityManager.sol\";\n\n/**\n * @title Security Manager\n * @dev Infrastructure contract to manage security parameters of users\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract SecurityManager is ISecurityManager, Ownable2Step {\n uint128 public minAdditionSecurityPeriod;\n uint128 public maxAdditionSecurityPeriod;\n uint128 private defaultAdditionSecurityPeriod;\n\n uint128 public minRemovalSecurityPeriod;\n uint128 public maxRemovalSecurityPeriod;\n uint128 private defaultRemovalSecurityPeriod;\n\n uint128 public minSecurityWindow;\n uint128 public maxSecurityWindow;\n uint128 private defaultSecurityWindow;\n\n uint128 public minRecoveryPeriod;\n uint128 public maxRecoveryPeriod;\n uint128 private defaultRecoveryPeriod;\n\n uint128 public minLockPeriod;\n uint128 public maxLockPeriod;\n uint128 private defaultLockPeriod;\n\n uint128 public minApprovalValidationPeriod;\n uint128 public maxApprovalValidationPeriod;\n uint128 private defaultApprovalValidationPeriod;\n\n uint128 public minMigrationPeriod;\n uint128 public maxMigrationPeriod;\n uint128 private defaultMigrationPeriod;\n\n bool public _isAdditionSecurityPeriodInitialized;\n bool public _isRemovalSecurityPeriodInitialized;\n bool public _isSecurityWindowInitialized;\n bool public _isRecoveryPeriodInitialized;\n bool public _isLockPeriodInitialized;\n bool public _isApprovalValidationPeriodInitialized;\n bool public _isMigrationPeriodInitialized;\n\n mapping(address => CustomSecurityConfig) securityConfigs;\n\n struct CustomSecurityConfig {\n uint128 additionSecurityPeriod;\n uint128 removalSecurityPeriod;\n uint128 securityWindow;\n uint128 recoveryPeriod;\n uint128 lockPeriod;\n uint128 approvalValidationPeriod;\n uint128 migrationPeriod;\n }\n\n /**\n * @notice Modifier to only allow wallet itself to make a call to wallet\n */\n modifier onlyWallet(address _wallet) {\n if (msg.sender != _wallet) revert SecurityManager__CallerNotWallet();\n _;\n }\n\n /**\n * @notice Modifier to revert if the variable is already initialized\n */\n modifier initializer(bool _isInitialized) {\n if (_isInitialized) revert SecurityManager__AlreadyIntialized();\n _;\n }\n\n /**\n * @notice Transfers the ownership of the contract to the given owner\n * @param _owner Address of owner who has access to initialize the default security variables for security manager\n */\n constructor(address _owner) {\n transferOwnership(_owner);\n _transferOwnership(_owner);\n }\n\n /**\n * @notice Sets the initial default/min/max addition security period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultAdditionSecurityPeriod Default Addition Security Period for all Barz contracts\n * @param _minAdditionSecurityPeriod Minimum Addition Security Period for all Barz contracts\n * @param _maxAdditionSecurityPeriod Maximum Addition Security Period for all Barz contracts\n */\n function initializeAdditionSecurityPeriod(\n uint128 _defaultAdditionSecurityPeriod,\n uint128 _minAdditionSecurityPeriod,\n uint128 _maxAdditionSecurityPeriod\n )\n external\n override\n onlyOwner\n initializer(_isAdditionSecurityPeriodInitialized)\n {\n _isAdditionSecurityPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultAdditionSecurityPeriod,\n _minAdditionSecurityPeriod,\n _maxAdditionSecurityPeriod\n );\n defaultAdditionSecurityPeriod = _defaultAdditionSecurityPeriod;\n minAdditionSecurityPeriod = _minAdditionSecurityPeriod;\n maxAdditionSecurityPeriod = _maxAdditionSecurityPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max removal security period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultRemovalSecurityPeriod Default Removal Security Period for all Barz contracts\n * @param _minRemovalSecurityPeriod Minimum Removal Security Period for all Barz contracts\n * @param _maxRemovalSecurityPeriod Maximum Removal Security Period for all Barz contracts\n */\n function initializeRemovalSecurityPeriod(\n uint128 _defaultRemovalSecurityPeriod,\n uint128 _minRemovalSecurityPeriod,\n uint128 _maxRemovalSecurityPeriod\n )\n external\n override\n onlyOwner\n initializer(_isRemovalSecurityPeriodInitialized)\n {\n _isRemovalSecurityPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultRemovalSecurityPeriod,\n _minRemovalSecurityPeriod,\n _maxRemovalSecurityPeriod\n );\n defaultRemovalSecurityPeriod = _defaultRemovalSecurityPeriod;\n minRemovalSecurityPeriod = _minRemovalSecurityPeriod;\n maxRemovalSecurityPeriod = _maxRemovalSecurityPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/maxd security window for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultSecurityWindow Default Security Window for all Barz contracts\n * @param _minSecurityWindow Minimum Security Window for all Barz contracts\n * @param _maxSecurityWindow Maximum Security Window for all Barz contracts\n */\n function initializeSecurityWindow(\n uint128 _defaultSecurityWindow,\n uint128 _minSecurityWindow,\n uint128 _maxSecurityWindow\n ) external override onlyOwner initializer(_isSecurityWindowInitialized) {\n _isSecurityWindowInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultSecurityWindow,\n _minSecurityWindow,\n _maxSecurityWindow\n );\n defaultSecurityWindow = _defaultSecurityWindow;\n minSecurityWindow = _minSecurityWindow;\n maxSecurityWindow = _maxSecurityWindow;\n }\n\n /**\n * @notice Sets the initial default/min/max recovery period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultRecoveryPeriod Default Recovery Period for all Barz contracts\n * @param _minRecoveryPeriod Minimum Recovery Period for all Barz contracts\n * @param _maxRecoveryPeriod Maximum Recovery Period for all Barz contracts\n */\n function initializeRecoveryPeriod(\n uint128 _defaultRecoveryPeriod,\n uint128 _minRecoveryPeriod,\n uint128 _maxRecoveryPeriod\n ) external override onlyOwner initializer(_isRecoveryPeriodInitialized) {\n _isRecoveryPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultRecoveryPeriod,\n _minRecoveryPeriod,\n _maxRecoveryPeriod\n );\n defaultRecoveryPeriod = _defaultRecoveryPeriod;\n minRecoveryPeriod = _minRecoveryPeriod;\n maxRecoveryPeriod = _maxRecoveryPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max lock period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultLockPeriod Default Lock Period for all Barz contracts\n * @param _minLockPeriod Minimum Lock Period for all Barz contracts\n * @param _maxLockPeriod Maximum Lock Period for all Barz contracts\n */\n function initializeLockPeriod(\n uint128 _defaultLockPeriod,\n uint128 _minLockPeriod,\n uint128 _maxLockPeriod\n ) external override onlyOwner initializer(_isLockPeriodInitialized) {\n _isLockPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultLockPeriod,\n _minLockPeriod,\n _maxLockPeriod\n );\n defaultLockPeriod = _defaultLockPeriod;\n minLockPeriod = _minLockPeriod;\n maxLockPeriod = _maxLockPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max approval validation period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultApprovalValidationPeriod Default Approval Validation Period for all Barz contracts\n * @param _minApprovalValidationPeriod Minimum Approval Validation Period for all Barz contracts\n * @param _maxApprovalValidationPeriod Maximum Approval Validation Period for all Barz contracts\n */\n function initializeApprovalValidationPeriod(\n uint128 _defaultApprovalValidationPeriod,\n uint128 _minApprovalValidationPeriod,\n uint128 _maxApprovalValidationPeriod\n )\n external\n override\n onlyOwner\n initializer(_isApprovalValidationPeriodInitialized)\n {\n _isApprovalValidationPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultApprovalValidationPeriod,\n _minApprovalValidationPeriod,\n _maxApprovalValidationPeriod\n );\n defaultApprovalValidationPeriod = _defaultApprovalValidationPeriod;\n minApprovalValidationPeriod = _minApprovalValidationPeriod;\n maxApprovalValidationPeriod = _maxApprovalValidationPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max migration period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultMigrationPeriod Default Migration Period for all Barz contracts\n * @param _minMigrationPeriod Minimum Migration Period for all Barz contracts\n * @param _maxMigrationPeriod Maximum Migration Period for all Barz contracts\n */\n function initializeMigrationPeriod(\n uint128 _defaultMigrationPeriod,\n uint128 _minMigrationPeriod,\n uint128 _maxMigrationPeriod\n ) external override onlyOwner initializer(_isMigrationPeriodInitialized) {\n _isMigrationPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultMigrationPeriod,\n _minMigrationPeriod,\n _maxMigrationPeriod\n );\n defaultMigrationPeriod = _defaultMigrationPeriod;\n minMigrationPeriod = _minMigrationPeriod;\n maxMigrationPeriod = _maxMigrationPeriod;\n }\n\n /**\n * @notice Wallet owner sets the addition security period for the wallet. Only the owner of wallet can call this function.\n * The addition security period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _additionSecurityPeriod Custom Addition Security Period for the wallet\n */\n function setAdditionSecurityPeriod(\n address _wallet,\n uint128 _additionSecurityPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _additionSecurityPeriod,\n minAdditionSecurityPeriod,\n maxAdditionSecurityPeriod\n );\n securityConfigs[_wallet]\n .additionSecurityPeriod = _additionSecurityPeriod;\n }\n\n /**\n * @notice Wallet owner sets the removal security period for the wallet. Only the owner of wallet can call this function.\n * The removal security period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _removalSecurityPeriod Custom Removal Security Period for the wallet\n */\n function setRemovalSecurityPeriod(\n address _wallet,\n uint128 _removalSecurityPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _removalSecurityPeriod,\n minRemovalSecurityPeriod,\n maxRemovalSecurityPeriod\n );\n securityConfigs[_wallet].removalSecurityPeriod = _removalSecurityPeriod;\n }\n\n /**\n * @notice Wallet owner sets the security window for the wallet. Only the owner of wallet can call this function.\n * The security window should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _securityWindow Custom Security Window for the wallet\n */\n function setSecurityWindow(\n address _wallet,\n uint128 _securityWindow\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _securityWindow,\n minSecurityWindow,\n maxSecurityWindow\n );\n securityConfigs[_wallet].securityWindow = _securityWindow;\n }\n\n /**\n * @notice Wallet owner sets the recovery period for the wallet. Only the owner of wallet can call this function.\n * The recovery period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _recoveryPeriod Custom recovery period for the wallet\n */\n function setRecoveryPeriod(\n address _wallet,\n uint128 _recoveryPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _recoveryPeriod,\n minRecoveryPeriod,\n maxRecoveryPeriod\n );\n securityConfigs[_wallet].recoveryPeriod = _recoveryPeriod;\n }\n\n /**\n * @notice Wallet owner sets the lock period for the wallet. Only the owner of wallet can call this function.\n * The lock period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _lockPeriod Custom Lock period for the wallet\n */\n function setLockPeriod(\n address _wallet,\n uint128 _lockPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(_lockPeriod, minLockPeriod, maxLockPeriod);\n securityConfigs[_wallet].lockPeriod = _lockPeriod;\n }\n\n /**\n * @notice Wallet owner sets the approval validation period for the wallet. Only the owner of wallet can call this function.\n * The approval validation period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _approvalValidationPeriod Custom approval validation period for the wallet\n */\n function setApprovalValidationPeriod(\n address _wallet,\n uint128 _approvalValidationPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _approvalValidationPeriod,\n minApprovalValidationPeriod,\n maxApprovalValidationPeriod\n );\n securityConfigs[_wallet]\n .approvalValidationPeriod = _approvalValidationPeriod;\n }\n\n /**\n * @notice Wallet owner sets the migration period for the wallet. Only the owner of wallet can call this function.\n * The migration period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _migrationPeriod Custom migration period for the wallet\n */\n\n function setMigrationPeriod(\n address _wallet,\n uint128 _migrationPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _migrationPeriod,\n minMigrationPeriod,\n maxMigrationPeriod\n );\n securityConfigs[_wallet].migrationPeriod = _migrationPeriod;\n }\n\n /**\n * @notice Returns the addition security period. Returns default value when custom addition security period is not set\n * @param _wallet Address of wallet\n * @return additionSecurityPeriod Addition Security Period of the given Barz account or wallet\n */\n function additionSecurityPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 additionSecurityPeriod)\n {\n additionSecurityPeriod = securityConfigs[_wallet]\n .additionSecurityPeriod;\n additionSecurityPeriod = (additionSecurityPeriod == 0)\n ? defaultAdditionSecurityPeriod\n : additionSecurityPeriod;\n }\n\n /**\n * @notice Returns the removal security period. Returns default value when custom removal security period is not set\n * @param _wallet Address of wallet\n * @return removalSecurityPeriod Removal Security Period of the given Barz account or wallet\n */\n function removalSecurityPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 removalSecurityPeriod)\n {\n removalSecurityPeriod = securityConfigs[_wallet].removalSecurityPeriod;\n removalSecurityPeriod = (removalSecurityPeriod == 0)\n ? defaultRemovalSecurityPeriod\n : removalSecurityPeriod;\n }\n\n /**\n * @notice Returns the security window. Returns default value when custom security window is not set\n * @param _wallet Address of wallet\n * @return securityWindow Security window of the given Barz account or wallet\n */\n function securityWindowOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 securityWindow)\n {\n securityWindow = securityConfigs[_wallet].securityWindow;\n securityWindow = (securityWindow == 0)\n ? defaultSecurityWindow\n : securityWindow;\n }\n\n /**\n * @notice Returns the recovery period. Returns default value when custom recovery period is not set\n * @param _wallet Address of wallet\n * @return recoveryPeriod Recovery Period of the given Barz account or wallet\n */\n function recoveryPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 recoveryPeriod)\n {\n recoveryPeriod = securityConfigs[_wallet].recoveryPeriod;\n recoveryPeriod = (recoveryPeriod == 0)\n ? defaultRecoveryPeriod\n : recoveryPeriod;\n }\n\n /**\n * @notice Returns the lock period. Returns default value when custom lock period is not set\n * @param _wallet Address of wallet\n * @return lockPeriod Lock Period of the given Barz account or wallet\n */\n function lockPeriodOf(\n address _wallet\n ) public view override onlyWallet(_wallet) returns (uint128 lockPeriod) {\n lockPeriod = securityConfigs[_wallet].lockPeriod;\n lockPeriod = (lockPeriod == 0) ? defaultLockPeriod : lockPeriod;\n }\n\n /**\n * @notice Returns the approval validation period. Returns default value when custom approval validation period is not set\n * @param _wallet Address of wallet\n * @return approvalValidationPeriod Approval Validation Period of the given Barz account or wallet\n */\n function approvalValidationPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityConfigs[_wallet]\n .approvalValidationPeriod;\n approvalValidationPeriod = (approvalValidationPeriod == 0)\n ? defaultApprovalValidationPeriod\n : approvalValidationPeriod;\n }\n\n /**\n * @notice Returns the migration period. Returns default value when custom migration period is not set\n * @param _wallet Address of wallet\n * @return migrationPeriod Migration Period of the given Barz account or wallet\n */\n function migrationPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 migrationPeriod)\n {\n migrationPeriod = securityConfigs[_wallet].migrationPeriod;\n migrationPeriod = (migrationPeriod == 0)\n ? defaultMigrationPeriod\n : migrationPeriod;\n }\n\n /**\n * @notice Validates if the period is smaller than the max period or bigger than the min period\n * @param _period Period to be checked\n * @param _minPeriod Minimum period\n * @param _maxPeriod Maximum period\n */\n function _validatePeriodBoundaries(\n uint128 _period,\n uint128 _minPeriod,\n uint128 _maxPeriod\n ) internal pure {\n if (_period >= _maxPeriod || _period <= _minPeriod)\n revert SecurityManager__OutOfBoundary();\n }\n}\n" + }, + "contracts/infrastructure/WhitelistStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {RemoteStorage} from \"./RemoteStorage.sol\";\n\n/**\n * @title Whitelist storage\n * @dev Maps addresses to the corresponsing array of whitelisted addresses for each of them.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract WhitelistStorage is RemoteStorage {\n /**\n * @dev Add the address to the whitelist storage\n * @param _wallet User wallet\n * @param _address Address to be whitelisted\n */\n function whitelistAddress(address _wallet, address _address) external {\n enforceWalletOrGuardianIfExists(_wallet);\n addAddress(_wallet, _address);\n }\n\n /**\n * @dev Removes the address from the whitelist storage\n * @param _wallet User wallet\n * @param _address Address to be removed from the whitelist\n */\n function blacklistAddress(address _wallet, address _address) external {\n enforceGuardianOrWallet(_wallet);\n removeAddress(_wallet, _address);\n }\n\n /**\n * @dev Returns whether the address exists in the whitelist storage, associated with the wallet\n * @param _wallet User wallet\n * @param _address Address to be whitelisted\n */\n function isWhitelisted(\n address _wallet,\n address _address\n ) external view returns (bool) {\n return exists(_wallet, _address);\n }\n\n /**\n * @dev Returns all whitelisted addresses associated with the wallet\n * @param _wallet User wallet\n */\n function getWhitelistedAddresses(\n address _wallet\n ) external view returns (address[] memory) {\n return getAddresses(_wallet);\n }\n}\n" + }, + "contracts/interfaces/ERC/IERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\n\npragma solidity 0.8.21;\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155Receiver {\n /**\n * @dev Handles the receipt of a single ERC1155 token type. This function is\n * called at the end of a `safeTransferFrom` after the balance has been updated.\n *\n * NOTE: To accept the transfer, this must return\n * `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n * (i.e. 0xf23a6e61, or its own function selector).\n *\n * @param operator The address which initiated the transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param id The ID of the token being transferred\n * @param value The amount of tokens being transferred\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n ) external returns (bytes4);\n\n /**\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\n * is called at the end of a `safeBatchTransferFrom` after the balances have\n * been updated.\n *\n * NOTE: To accept the transfer(s), this must return\n * `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n * (i.e. 0xbc197c81, or its own function selector).\n *\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "contracts/interfaces/ERC/IERC1271.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\ninterface IERC1271 {\n function isValidSignature(\n bytes32 hash,\n bytes memory signature\n ) external view returns (bytes4);\n}\n" + }, + "contracts/interfaces/ERC/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\ninterface IERC165 {\n /// @notice Query if a contract implements an interface\n /// @param interfaceId The interface identifier, as specified in ERC-165\n /// @dev Interface identification is specified in ERC-165. This function\n /// uses less than 30,000 gas.\n /// @return `true` if the contract implements `interfaceID` and\n /// `interfaceID` is not 0xffffffff, `false` otherwise\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/IERC173.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\n/// @title ERC-173 Contract Ownership Standard\n/// Note: the ERC-165 identifier for this interface is 0x7f5828d0\n/* is ERC165 */\ninterface IERC173 {\n /// @dev This emits when ownership of a contract changes.\n event OwnershipTransferred(\n address indexed previousOwner,\n address indexed newOwner\n );\n\n /// @notice Get the address of the owner\n /// @return owner_ The address of the owner.\n function owner() external view returns (address owner_);\n\n /// @notice Set the address of the new owner of the contract\n /// @dev Set _newOwner to address(0) to renounce any ownership.\n /// @param _newOwner The address of the new owner of the contract\n function transferOwnership(address _newOwner) external;\n}\n" + }, + "contracts/interfaces/ERC/IERC677Receiver.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\ninterface IERC677Receiver {\n function onTokenTransfer(\n address sender,\n uint value,\n bytes calldata data\n ) external pure returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155 is IERC165 {\n /**\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n */\n event TransferSingle(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256 id,\n uint256 value\n );\n\n /**\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n * transfers.\n */\n event TransferBatch(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\n\n /**\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n * `approved`.\n */\n event ApprovalForAll(\n address indexed account,\n address indexed operator,\n bool approved\n );\n\n /**\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n *\n * If an {URI} event was emitted for `id`, the standard\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n * returned by {IERC1155MetadataURI-uri}.\n */\n event URI(string value, uint256 indexed id);\n\n /**\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(\n address account,\n uint256 id\n ) external view returns (uint256);\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] calldata accounts,\n uint256[] calldata ids\n ) external view returns (uint256[] memory);\n\n /**\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n *\n * Emits an {ApprovalForAll} event.\n *\n * Requirements:\n *\n * - `operator` cannot be the caller.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n *\n * See {setApprovalForAll}.\n */\n function isApprovedForAll(\n address account,\n address operator\n ) external view returns (bool);\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes calldata data\n ) external;\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(\n address indexed owner,\n address indexed spender,\n uint256 value\n );\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` 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 amount) 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(\n address owner,\n address spender\n ) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the 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 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` 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(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(\n address spender,\n uint256 addedValue\n ) external returns (bool);\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(\n address spender,\n uint256 subtractedValue\n ) external returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(\n address indexed from,\n address indexed to,\n uint256 indexed tokenId\n );\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(\n address indexed owner,\n address indexed approved,\n uint256 indexed tokenId\n );\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(\n address indexed owner,\n address indexed operator,\n bool approved\n );\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(\n uint256 tokenId\n ) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(\n address owner,\n address operator\n ) external view returns (bool);\n}\n" + }, + "contracts/interfaces/IBarz.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Barz Interface\n * @dev Interface of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IBarz {\n error Barz__InitializationFailure();\n}\n" + }, + "contracts/interfaces/IBarzFactory.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Barz} from \"../Barz.sol\";\n\n/**\n * @title Barz Factory Interface\n * @dev Interface of contract to easily deploy Barz to a pre-computed address with a single call\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IBarzFactory {\n function createAccount(\n address verificationFacet,\n bytes calldata owner,\n uint256 salt\n ) external returns (Barz);\n\n function getAddress(\n address verificationFacet,\n bytes calldata owner,\n uint256 salt\n ) external view returns (address);\n\n function getBytecode(\n address accountFacet,\n address verificationFacet,\n address entryPoint,\n address facetRegistry,\n address defaultFallback,\n bytes memory ownerPublicKey\n ) external pure returns (bytes memory);\n\n function getCreationCode() external pure returns (bytes memory);\n}\n" + }, + "contracts/libraries/DefaultLibDiamond.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\n\nerror InitializationFunctionReverted(\n address _initializationContractAddress,\n bytes _calldata\n);\n\nlibrary DefaultLibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION =\n keccak256(\"trustwallet.barz.diamond.storage\");\n\n struct FacetAddressAndPosition {\n address facetAddress;\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\n }\n\n struct FacetFunctionSelectors {\n bytes4[] functionSelectors;\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\n }\n\n struct DiamondStorage {\n // maps function selector to the facet address and\n // the position of the selector in the facetFunctionSelectors.selectors array\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\n // maps facet addresses to function selectors\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\n // facet addresses\n address[] facetAddresses;\n // Used to query if a contract implements an interface.\n // Used to implement ERC-165.\n mapping(bytes4 => bool) supportedInterfaces;\n }\n\n function diamondStorage()\n internal\n pure\n returns (DiamondStorage storage ds)\n {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n event DiamondCut(\n IDiamondCut.FacetCut[] _diamondCut,\n address _init,\n bytes _calldata\n );\n\n // Internal function version of diamondCut\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n for (\n uint256 facetIndex;\n facetIndex < _diamondCut.length;\n facetIndex++\n ) {\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\n if (action == IDiamondCut.FacetCutAction.Add) {\n addFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\n replaceFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\n removeFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else {\n revert(\"LibDiamondCut: Incorrect FacetCutAction\");\n }\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Add facet can't be address(0)\"\n );\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n require(\n oldFacetAddress == address(0),\n \"LibDiamondCut: Can't add function that already exists\"\n );\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function replaceFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Replace facet can't be address(0)\"\n );\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n require(\n oldFacetAddress != _facetAddress,\n \"LibDiamondCut: Can't replace function with same facet\"\n );\n removeFunction(ds, oldFacetAddress, selector);\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function removeFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n // if function does not exist then do nothing and return\n require(\n _facetAddress == address(0),\n \"LibDiamondCut: Remove facet address must be address(0)\"\n );\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n removeFunction(ds, oldFacetAddress, selector);\n }\n }\n\n function addFacet(\n DiamondStorage storage ds,\n address _facetAddress\n ) internal {\n enforceHasContractCode(\n _facetAddress,\n \"LibDiamondCut: New facet has no code\"\n );\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds\n .facetAddresses\n .length;\n ds.facetAddresses.push(_facetAddress);\n }\n\n function addFunction(\n DiamondStorage storage ds,\n bytes4 _selector,\n uint96 _selectorPosition,\n address _facetAddress\n ) internal {\n ds\n .selectorToFacetAndPosition[_selector]\n .functionSelectorPosition = _selectorPosition;\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(\n _selector\n );\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\n }\n\n function removeFunction(\n DiamondStorage storage ds,\n address _facetAddress,\n bytes4 _selector\n ) internal {\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Can't remove function that doesn't exist\"\n );\n // an immutable function is a function defined directly in a diamond\n require(\n _facetAddress != address(this),\n \"LibDiamondCut: Can't remove immutable function\"\n );\n // replace selector with last selector, then delete last selector\n uint256 selectorPosition = ds\n .selectorToFacetAndPosition[_selector]\n .functionSelectorPosition;\n uint256 lastSelectorPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors\n .length - 1;\n // if not the same then replace _selector with lastSelector\n if (selectorPosition != lastSelectorPosition) {\n bytes4 lastSelector = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors[lastSelectorPosition];\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[\n selectorPosition\n ] = lastSelector;\n ds\n .selectorToFacetAndPosition[lastSelector]\n .functionSelectorPosition = uint96(selectorPosition);\n }\n // delete the last selector\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\n delete ds.selectorToFacetAndPosition[_selector];\n\n // if no more selectors for facet address then delete the facet address\n if (lastSelectorPosition == 0) {\n // replace facet address with last facet address and delete last facet address\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\n uint256 facetAddressPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .facetAddressPosition;\n if (facetAddressPosition != lastFacetAddressPosition) {\n address lastFacetAddress = ds.facetAddresses[\n lastFacetAddressPosition\n ];\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\n ds\n .facetFunctionSelectors[lastFacetAddress]\n .facetAddressPosition = facetAddressPosition;\n }\n ds.facetAddresses.pop();\n delete ds\n .facetFunctionSelectors[_facetAddress]\n .facetAddressPosition;\n }\n }\n\n function initializeDiamondCut(\n address _init,\n bytes memory _calldata\n ) internal {\n if (_init == address(0)) {\n return;\n }\n enforceHasContractCode(\n _init,\n \"LibDiamondCut: _init address has no code\"\n );\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length > 0) {\n // bubble up error\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(error)\n revert(add(32, error), returndata_size)\n }\n } else {\n revert InitializationFunctionReverted(_init, _calldata);\n }\n }\n }\n\n function enforceHasContractCode(\n address _contract,\n string memory _errorMessage\n ) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize > 0, _errorMessage);\n }\n}\n" + }, + "contracts/libraries/LibAppStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SafeCast} from \"@openzeppelin/contracts/utils/math/SafeCast.sol\";\nimport {IEntryPoint} from \"../aa-4337/interfaces/IEntryPoint.sol\";\nimport {IFacetRegistry} from \"../infrastructure/interfaces/IFacetRegistry.sol\";\n\n/*\n * @title App Storage\n * @dev App storage for Barz contract to prevent storage collision\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\n\nstruct Lock {\n uint64 release;\n bytes4 locker;\n}\n\nstruct InitializersStorage {\n // NOTE: initialized is a variable to make sure the initialization is only done once.\n uint8 signerInitialized;\n uint8 accountInitialized;\n uint8 restrictionsInitialized;\n}\n\nstruct AppStorage {\n mapping(uint256 => InitializersStorage) initStorage;\n uint8 signerMigration;\n bytes4 validateOwnerSignatureSelector;\n IEntryPoint entryPoint;\n IFacetRegistry facetRegistry;\n mapping(uint256 => Lock) locks;\n}\n\nlibrary LibAppStorage {\n error LibAppStorage__AccountAlreadyUninitialized();\n error LibAppStorage__AccountMustBeUninitialized();\n error LibAppStorage__SignerAlreadyUninitialized();\n error LibAppStorage__SignerMustBeUninitialized();\n\n function appStorage() internal pure returns (AppStorage storage ds) {\n assembly {\n ds.slot := 0\n }\n }\n\n function setSignerUninitialized() internal {\n AppStorage storage s = appStorage();\n if (1 != s.initStorage[0].signerInitialized) {\n revert LibAppStorage__SignerAlreadyUninitialized();\n }\n s.initStorage[0].signerInitialized = 0;\n }\n\n function getValidateOwnerSignatureSelector()\n internal\n view\n returns (bytes4 selector)\n {\n selector = appStorage().validateOwnerSignatureSelector;\n }\n\n function setValidateOwnerSignatureSelector(\n bytes4 _validateOwnerSignatureSelector\n ) internal {\n appStorage()\n .validateOwnerSignatureSelector = _validateOwnerSignatureSelector;\n }\n\n function enforceSignerInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].signerInitialized) {\n revert LibAppStorage__SignerMustBeUninitialized();\n }\n s.initStorage[0].signerInitialized = 1;\n }\n\n function enforceAccountInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].accountInitialized) {\n revert LibAppStorage__AccountMustBeUninitialized();\n }\n s.initStorage[0].accountInitialized = 1;\n }\n\n function initiateSignerMigration() internal {\n appStorage().signerMigration = 1;\n }\n\n function enforceSignerMigration() internal view {\n if (1 != appStorage().signerMigration) {\n revert LibAppStorage__AccountMustBeUninitialized();\n }\n }\n\n function finalizeSignerMigration() internal {\n appStorage().signerMigration = 0;\n }\n\n function setLock(uint256 _releaseAfter, bytes4 _locker) internal {\n appStorage().locks[0] = Lock(SafeCast.toUint64(_releaseAfter), _locker);\n }\n\n function enforceRestrictionsInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].restrictionsInitialized)\n revert LibAppStorage__SignerMustBeUninitialized();\n s.initStorage[0].restrictionsInitialized = 1;\n }\n\n function setRestrictionsUninitialized() internal {\n AppStorage storage s = appStorage();\n if (1 != s.initStorage[0].restrictionsInitialized)\n revert LibAppStorage__AccountAlreadyUninitialized();\n s.initStorage[0].restrictionsInitialized = 0;\n }\n}\n\ncontract BarzStorage {\n AppStorage internal s;\n modifier onlyWhenUnlocked() {\n require(\n uint64(block.timestamp) >= s.locks[0].release,\n \"Account Locked\"\n );\n _;\n }\n modifier onlyWhenLocked() {\n require(\n uint64(block.timestamp) < s.locks[0].release,\n \"Account Unlocked\"\n );\n _;\n }\n}\n" + }, + "contracts/libraries/LibDiamond.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\n\nerror InitializationFunctionReverted(\n address _initializationContractAddress,\n bytes _calldata\n);\n\nlibrary LibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION =\n keccak256(\"trustwallet.barz.diamond.storage\");\n\n struct DiamondStorage {\n // maps function selectors to the facets that execute the functions.\n // and maps the selectors to their position in the selectorSlots array.\n // func selector => address facet, selector position\n mapping(bytes4 => bytes32) facets;\n // array of slots of function selectors.\n // each slot holds 8 function selectors.\n mapping(uint256 => bytes32) selectorSlots;\n // The number of function selectors in selectorSlots\n uint16 selectorCount;\n // Used to query if a contract implements an interface.\n // Used to implement ERC-165.\n mapping(bytes4 => bool) supportedInterfaces;\n // Default Fallback Handler of the barz.\n IDiamondLoupe defaultFallbackHandler;\n }\n\n function diamondStorage()\n internal\n pure\n returns (DiamondStorage storage ds)\n {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n function enforceIsSelf() internal view {\n require(msg.sender == address(this), \"LibDiamond: Caller not self\");\n }\n\n event DiamondCut(\n IDiamondCut.FacetCut[] _diamondCut,\n address _init,\n bytes _calldata\n );\n\n bytes32 constant CLEAR_ADDRESS_MASK =\n bytes32(uint256(0xffffffffffffffffffffffff));\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\n\n // Internal function version of diamondCut\n // This code is almost the same as the external diamondCut,\n // except it is using 'Facet[] memory _diamondCut' instead of\n // 'Facet[] calldata _diamondCut'.\n // The code is duplicated to prevent copying calldata to memory which\n // causes an error for a two dimensional array.\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n DiamondStorage storage ds = diamondStorage();\n uint256 originalSelectorCount = ds.selectorCount;\n uint256 selectorCount = originalSelectorCount;\n bytes32 selectorSlot;\n // Check if last selector slot is not full\n // \"selectorCount & 7\" is a gas efficient modulo by eight \"selectorCount % 8\"\n if (selectorCount & 7 > 0) {\n // get last selectorSlot\n // \"selectorSlot >> 3\" is a gas efficient division by 8 \"selectorSlot / 8\"\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\n }\n // loop through diamond cut\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\n selectorCount,\n selectorSlot,\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].action,\n _diamondCut[facetIndex].functionSelectors\n );\n\n unchecked {\n facetIndex++;\n }\n }\n if (selectorCount != originalSelectorCount) {\n ds.selectorCount = uint16(selectorCount);\n }\n // If last selector slot is not full\n // \"selectorCount & 7\" is a gas efficient modulo by eight \"selectorCount % 8\"\n if (selectorCount & 7 > 0) {\n // \"selectorSlot >> 3\" is a gas efficient division by 8 \"selectorSlot / 8\"\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addReplaceRemoveFacetSelectors(\n uint256 _selectorCount,\n bytes32 _selectorSlot,\n address _newFacetAddress,\n IDiamondCut.FacetCutAction _action,\n bytes4[] memory _selectors\n ) internal returns (uint256, bytes32) {\n DiamondStorage storage ds = diamondStorage();\n require(\n _selectors.length > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n if (_action == IDiamondCut.FacetCutAction.Add) {\n enforceHasContractCode(\n _newFacetAddress,\n \"LibDiamondCut: Add facet has no code\"\n );\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n require(\n address(bytes20(oldFacet)) == address(0),\n \"LibDiamondCut: Can't add function that already exists\"\n );\n // add facet for selector\n ds.facets[selector] =\n bytes20(_newFacetAddress) |\n bytes32(_selectorCount);\n // \"_selectorCount & 7\" is a gas efficient modulo by eight \"_selectorCount % 8\"\n // \" << 5 is the same as multiplying by 32 ( * 32)\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\n // clear selector position in slot and add selector\n _selectorSlot =\n (_selectorSlot &\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\n (bytes32(selector) >> selectorInSlotPosition);\n // if slot is full then write it to storage\n if (selectorInSlotPosition == 224) {\n // \"_selectorSlot >> 3\" is a gas efficient division by 8 \"_selectorSlot / 8\"\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\n _selectorSlot = 0;\n }\n _selectorCount++;\n\n unchecked {\n selectorIndex++;\n }\n }\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\n enforceHasContractCode(\n _newFacetAddress,\n \"LibDiamondCut: Replace facet has no code\"\n );\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n address oldFacetAddress = address(bytes20(oldFacet));\n // only useful if immutable functions exist\n require(\n oldFacetAddress != address(this),\n \"LibDiamondCut: Can't replace immutable function\"\n );\n require(\n oldFacetAddress != _newFacetAddress,\n \"LibDiamondCut: Can't replace function with same function\"\n );\n require(\n oldFacetAddress != address(0),\n \"LibDiamondCut: Can't replace function that doesn't exist\"\n );\n // replace old facet address\n ds.facets[selector] =\n (oldFacet & CLEAR_ADDRESS_MASK) |\n bytes20(_newFacetAddress);\n\n unchecked {\n selectorIndex++;\n }\n }\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\n require(\n _newFacetAddress == address(0),\n \"LibDiamondCut: Remove facet address must be address(0)\"\n );\n // \"_selectorCount >> 3\" is a gas efficient division by 8 \"_selectorCount / 8\"\n uint256 selectorSlotCount = _selectorCount >> 3;\n // \"_selectorCount & 7\" is a gas efficient modulo by eight \"_selectorCount % 8\"\n uint256 selectorInSlotIndex = _selectorCount & 7;\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n if (_selectorSlot == 0) {\n // get last selectorSlot\n selectorSlotCount--;\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\n selectorInSlotIndex = 7;\n } else {\n selectorInSlotIndex--;\n }\n bytes4 lastSelector;\n uint256 oldSelectorsSlotCount;\n uint256 oldSelectorInSlotPosition;\n // adding a block here prevents stack too deep error\n {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n require(\n address(bytes20(oldFacet)) != address(0),\n \"LibDiamondCut: Can't remove function that doesn't exist\"\n );\n // only useful if immutable functions exist\n require(\n address(bytes20(oldFacet)) != address(this),\n \"LibDiamondCut: Can't remove immutable function\"\n );\n // replace selector with last selector in ds.facets\n // gets the last selector\n // \" << 5 is the same as multiplying by 32 ( * 32)\n lastSelector = bytes4(\n _selectorSlot << (selectorInSlotIndex << 5)\n );\n if (lastSelector != selector) {\n // update last selector slot position info\n ds.facets[lastSelector] =\n (oldFacet & CLEAR_ADDRESS_MASK) |\n bytes20(ds.facets[lastSelector]);\n }\n delete ds.facets[selector];\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\n // \"oldSelectorCount >> 3\" is a gas efficient division by 8 \"oldSelectorCount / 8\"\n oldSelectorsSlotCount = oldSelectorCount >> 3;\n // \"oldSelectorCount & 7\" is a gas efficient modulo by eight \"oldSelectorCount % 8\"\n // \" << 5 is the same as multiplying by 32 ( * 32)\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\n }\n if (oldSelectorsSlotCount != selectorSlotCount) {\n bytes32 oldSelectorSlot = ds.selectorSlots[\n oldSelectorsSlotCount\n ];\n // clears the selector we are deleting and puts the last selector in its place.\n oldSelectorSlot =\n (oldSelectorSlot &\n ~(CLEAR_SELECTOR_MASK >>\n oldSelectorInSlotPosition)) |\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\n // update storage with the modified slot\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\n } else {\n // clears the selector we are deleting and puts the last selector in its place.\n _selectorSlot =\n (_selectorSlot &\n ~(CLEAR_SELECTOR_MASK >>\n oldSelectorInSlotPosition)) |\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\n }\n if (selectorInSlotIndex == 0) {\n delete ds.selectorSlots[selectorSlotCount];\n _selectorSlot = 0;\n }\n\n unchecked {\n selectorIndex++;\n }\n }\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\n } else {\n revert(\"LibDiamondCut: Incorrect FacetCutAction\");\n }\n return (_selectorCount, _selectorSlot);\n }\n\n function initializeDiamondCut(\n address _init,\n bytes memory _calldata\n ) internal {\n if (_init == address(0)) {\n return;\n }\n enforceHasContractCode(\n _init,\n \"LibDiamondCut: _init address has no code\"\n );\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length > 0) {\n // bubble up error\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(error)\n revert(add(32, error), returndata_size)\n }\n } else {\n revert InitializationFunctionReverted(_init, _calldata);\n }\n }\n }\n\n function enforceHasContractCode(\n address _contract,\n string memory _errorMessage\n ) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize > 0, _errorMessage);\n }\n\n function restrictionsFacet() internal view returns (address facetAddress_) {\n bytes4 selector = bytes4(\n keccak256(\"verifyRestrictions(address,address,uint256,bytes)\")\n );\n facetAddress_ = address(\n bytes20(LibDiamond.diamondStorage().facets[selector])\n );\n }\n}\n" + }, + "contracts/libraries/LibFacetStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Storage\n * @dev Storage contract to store each facets variables with diamond storage\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\n\nstruct Secp256k1VerificationStorage {\n address signer;\n}\n\nstruct Secp256r1VerificationStorage {\n uint256[2] q;\n}\n\nstruct GuardianStorage {\n mapping(bytes32 => uint256) pending;\n mapping(uint8 => StorageConfig) configs;\n}\n\nstruct Info {\n bool exists;\n uint128 index;\n}\n\nstruct StorageConfig {\n address[] addresses;\n mapping(address => Info) info;\n}\n\nstruct RecoveryConfig {\n bytes recoveryPublicKey;\n uint64 executeAfter;\n}\n\nstruct ApprovalConfig {\n bool isApproved;\n uint64 validUntil;\n}\n\nstruct RecoveryApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isNewOwnerApproved;\n}\n\nstruct RecoveryStorage {\n mapping(uint8 => RecoveryConfig) recoveryConfigs;\n mapping(uint8 => RecoveryApprovalConfig) recoveryApprovalConfigs;\n uint128 nonce;\n}\n\nstruct RestrictionsStorage {\n address[] restrictions;\n mapping(address => bool) exists;\n}\n\nstruct SignatureMigrationConfig {\n bytes migrationPublicKey;\n address migrationVerificationFacet;\n bytes4[] migrationSelectors;\n uint64 migrateAfter;\n}\n\nstruct SignatureMigrationApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isMigrationApproved;\n}\n\nstruct SignatureMigrationStorage {\n mapping(uint8 => SignatureMigrationConfig) migrationConfigs;\n mapping(uint8 => SignatureMigrationApprovalConfig) migrationApprovalConfigs;\n uint128 nonce;\n}\n\nstruct DiamondCutApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isDiamondCutApproved;\n}\n\nstruct DiamondCutStorage {\n mapping(uint8 => DiamondCutApprovalConfig) diamondCutApprovalConfigs;\n uint128 nonce;\n}\n\nstruct LockStorage {\n uint128 nonce;\n}\n\nlibrary LibFacetStorage {\n function k1Storage()\n internal\n pure\n returns (Secp256k1VerificationStorage storage ds)\n {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.Secp256k1VerificationStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function r1Storage()\n internal\n pure\n returns (Secp256r1VerificationStorage storage ds)\n {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.Secp256r1VerificationStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function guardianStorage()\n internal\n pure\n returns (GuardianStorage storage ds)\n {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.GuardianStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function recoveryStorage()\n internal\n pure\n returns (RecoveryStorage storage ds)\n {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.RecoveryStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function restrictionsStorage()\n internal\n pure\n returns (RestrictionsStorage storage ds)\n {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.RestrictionsStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function migrationStorage()\n internal\n pure\n returns (SignatureMigrationStorage storage ds)\n {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.SignatureMigrationStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function diamondCutStorage()\n internal\n pure\n returns (DiamondCutStorage storage ds)\n {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.DiamondCutStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function lockStorage() internal pure returns (LockStorage storage ds) {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.LockStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n}\n" + }, + "contracts/libraries/LibGuardian.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibFacetStorage, StorageConfig} from \"./LibFacetStorage.sol\";\n\n/**\n * @title LibGuardian\n * @dev Internal Library to provide utility feature for Guardians stored in Guardian Facet Storage\n * @author David Yongjun Kim (@Powerstream3604)\n */\nlibrary LibGuardian {\n function majorityOfGuardians()\n internal\n view\n returns (uint256 guardianNumber)\n {\n uint256 guardianLength = guardianCount();\n guardianNumber = (guardianLength == 0) ? 0 : guardianLength / 2 + 1;\n }\n\n function isGuardian(address _guardian) internal view returns (bool) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n return config.info[_guardian].exists;\n }\n\n function guardianCount() internal view returns (uint256) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n return config.addresses.length;\n }\n\n function getGuardians() internal view returns (address[] memory) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n address[] memory addresses = new address[](config.addresses.length);\n uint256 addressesLen = config.addresses.length;\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n return addresses;\n }\n}\n" + }, + "contracts/libraries/LibLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {LibDiamond} from \"./LibDiamond.sol\";\n\n/**\n * @title LibLoupe\n * @dev Internal Library to provide utility feature for reading the state of diamond facets\n * @author David Yongjun Kim (@Powerstream3604)\n */\nlibrary LibLoupe {\n /// @notice Gets all facets and their selectors.\n /// @return facets_ Facet\n function facets()\n internal\n view\n returns (IDiamondLoupe.Facet[] memory facets_)\n {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facets_ = new IDiamondLoupe.Facet[](ds.selectorCount);\n uint16[] memory numFacetSelectors = new uint16[](ds.selectorCount);\n uint256 numFacets;\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facetAddress_ = address(bytes20(ds.facets[selector]));\n bool continueLoop;\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n if (facets_[facetIndex].facetAddress == facetAddress_) {\n facets_[facetIndex].functionSelectors[\n numFacetSelectors[facetIndex]\n ] = selector;\n // probably will never have more than 256 functions from one facet contract\n require(numFacetSelectors[facetIndex] < 255);\n numFacetSelectors[facetIndex]++;\n continueLoop = true;\n break;\n }\n }\n if (continueLoop) {\n continue;\n }\n facets_[numFacets].facetAddress = facetAddress_;\n facets_[numFacets].functionSelectors = new bytes4[](\n ds.selectorCount\n );\n facets_[numFacets].functionSelectors[0] = selector;\n numFacetSelectors[numFacets] = 1;\n numFacets++;\n }\n }\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n uint256 numSelectors = numFacetSelectors[facetIndex];\n bytes4[] memory selectors = facets_[facetIndex].functionSelectors;\n // setting the number of selectors\n assembly {\n mstore(selectors, numSelectors)\n }\n }\n // setting the number of facets\n assembly {\n mstore(facets_, numFacets)\n }\n }\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n /// @return _facetFunctionSelectors The selectors associated with a facet address.\n function facetFunctionSelectors(\n address _facet\n ) internal view returns (bytes4[] memory _facetFunctionSelectors) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n uint256 numSelectors;\n _facetFunctionSelectors = new bytes4[](ds.selectorCount);\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facet = address(bytes20(ds.facets[selector]));\n if (_facet == facet) {\n _facetFunctionSelectors[numSelectors] = selector;\n numSelectors++;\n }\n }\n }\n // Set the number of selectors in the array\n assembly {\n mstore(_facetFunctionSelectors, numSelectors)\n }\n }\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses()\n internal\n view\n returns (address[] memory facetAddresses_)\n {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facetAddresses_ = new address[](ds.selectorCount);\n uint256 numFacets;\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facetAddress_ = address(bytes20(ds.facets[selector]));\n bool continueLoop;\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n if (facetAddress_ == facetAddresses_[facetIndex]) {\n continueLoop = true;\n break;\n }\n }\n if (continueLoop) {\n continue;\n }\n facetAddresses_[numFacets] = facetAddress_;\n numFacets++;\n }\n }\n // Set the number of facet addresses in the array\n assembly {\n mstore(facetAddresses_, numFacets)\n }\n }\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(\n bytes4 _functionSelector\n ) internal view returns (address facetAddress_) {\n facetAddress_ = address(\n bytes20(LibDiamond.diamondStorage().facets[_functionSelector])\n );\n }\n}\n" + }, + "contracts/libraries/LibMultiSigStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Multi-sig Storage\n * @dev Storage contract for storing Multi-sig Facet variables in diamond storage pattern\n * @author David Yongjun Kim (@Powerstream3604)\n */\n\nstruct MultiSigStorage {\n mapping(address => address) owners;\n mapping(uint256 => mapping(address => mapping(bytes32 => uint256))) approvedHashes;\n uint256 ownerCount;\n uint256 threshold;\n uint256 counter;\n}\n\nlibrary LibMultiSigStorage {\n function multisigStorage()\n internal\n pure\n returns (MultiSigStorage storage ds)\n {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.MultiSigStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n}\n" + }, + "contracts/libraries/LibRecoverSpender.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title RecoverSpender\n * @dev Library to determine the action and spender of calldata\n * @author Ruslan Serebriakov (@rsrbk)\n */\nlibrary LibRecoverSpender {\n // ERC20, ERC721 & ERC1155 transfers & approvals\n bytes4 private constant ERC20_TRANSFER =\n bytes4(keccak256(\"transfer(address,uint256)\"));\n bytes4 private constant ERC20_APPROVE =\n bytes4(keccak256(\"approve(address,uint256)\"));\n bytes4 private constant ERC20_INCREASE_ALLOWANCE =\n bytes4(keccak256(\"increaseAllowance(address,uint256)\"));\n bytes4 private constant ERC20_DECREASE_ALLOWANCE =\n bytes4(keccak256(\"decreaseAllowance(address,uint256)\"));\n bytes4 private constant ERC721_SET_APPROVAL_FOR_ALL =\n bytes4(keccak256(\"setApprovalForAll(address,bool)\"));\n bytes4 private constant ERC721_TRANSFER_FROM =\n bytes4(keccak256(\"transferFrom(address,address,uint256)\"));\n bytes4 private constant ERC721_SAFE_TRANSFER_FROM =\n bytes4(keccak256(\"safeTransferFrom(address,address,uint256)\"));\n bytes4 private constant ERC721_SAFE_TRANSFER_FROM_BYTES =\n bytes4(keccak256(\"safeTransferFrom(address,address,uint256,bytes)\"));\n bytes4 private constant ERC1155_SAFE_TRANSFER_FROM =\n bytes4(\n keccak256(\"safeTransferFrom(address,address,uint256,uint256,bytes)\")\n );\n bytes4 private constant ERC1155_SAFE_BATCH_TRANSFER_FROM =\n bytes4(\n keccak256(\n \"safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)\"\n )\n );\n\n /**\n * @notice Helper method to recover the spender from a contract call.\n * The method returns the contract unless the call is to a standard method of a ERC20/ERC721/ERC1155 token\n * in which case the spender is recovered from the data.\n * @param _to The target contract.\n * @param _data The data payload.\n */\n function _recover(\n address _to,\n bytes memory _data\n ) internal pure returns (address spender) {\n if (_data.length >= 68) {\n bytes4 methodId;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n methodId := mload(add(_data, 0x20))\n }\n if (\n methodId == ERC20_TRANSFER ||\n methodId == ERC20_APPROVE ||\n methodId == ERC20_INCREASE_ALLOWANCE ||\n methodId == ERC20_DECREASE_ALLOWANCE ||\n methodId == ERC721_SET_APPROVAL_FOR_ALL\n ) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n spender := mload(add(_data, 0x24))\n }\n return spender;\n }\n if (\n methodId == ERC721_TRANSFER_FROM ||\n methodId == ERC721_SAFE_TRANSFER_FROM ||\n methodId == ERC721_SAFE_TRANSFER_FROM_BYTES ||\n methodId == ERC1155_SAFE_TRANSFER_FROM ||\n methodId == ERC1155_SAFE_BATCH_TRANSFER_FROM\n ) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n spender := mload(add(_data, 0x44))\n }\n return spender;\n }\n }\n\n spender = _to;\n }\n}\n" + }, + "contracts/libraries/LibUtils.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\n\nlibrary LibUtils {\n // Internal utility functions\n function mergeArrays(\n bytes4[] memory _array1,\n bytes4[] memory _array2\n ) internal pure returns (bytes4[] memory) {\n uint256 length1 = _array1.length;\n uint256 length2 = _array2.length;\n bytes4[] memory mergedArray = new bytes4[](length1 + length2);\n\n for (uint256 i; i < length1; ) {\n mergedArray[i] = _array1[i];\n unchecked {\n ++i;\n }\n }\n\n for (uint256 i; i < length2; ) {\n mergedArray[length1 + i] = _array2[i];\n unchecked {\n ++i;\n }\n }\n\n return mergedArray;\n }\n\n function removeFacetElement(\n IDiamondLoupe.Facet[] memory _facets,\n uint256 _index\n ) internal pure returns (IDiamondLoupe.Facet[] memory) {\n require(_index < _facets.length, \"Invalid index\");\n require(_facets.length != 0, \"Invalid array\");\n\n // Create a new array with a length of `_facets.length - 1`\n IDiamondLoupe.Facet[] memory newArray = new IDiamondLoupe.Facet[](\n _facets.length - 1\n );\n uint256 newArrayLength = newArray.length;\n // Iterate over the original array, skipping the element at the specified `index`\n for (uint256 i; i < newArrayLength; ) {\n if (i < _index) {\n newArray[i] = _facets[i];\n } else {\n newArray[i] = _facets[i + 1];\n }\n unchecked {\n ++i;\n }\n }\n\n return newArray;\n }\n\n function removeElement(\n bytes4[] memory _array,\n uint256 _index\n ) internal pure returns (bytes4[] memory) {\n require(_index < _array.length, \"Invalid index\");\n require(_array.length != 0, \"Invalid array\");\n\n bytes4[] memory newArray = new bytes4[](_array.length - 1);\n uint256 newArrayLength = newArray.length;\n for (uint256 i; i < newArrayLength; ) {\n if (i < _index) {\n newArray[i] = _array[i];\n } else {\n newArray[i] = _array[i + 1];\n }\n unchecked {\n ++i;\n }\n }\n\n return newArray;\n }\n\n function setValue(\n bytes4[] memory _keys,\n address[] memory _values,\n bytes4 _key,\n address _value\n ) internal pure returns (bytes4[] memory, address[] memory) {\n uint256 index = findIndex(_keys, _key);\n uint256 keysLength = _keys.length;\n if (index < keysLength) {\n _values[index] = _value;\n } else {\n // Create new storage arrays\n bytes4[] memory newKeys = new bytes4[](keysLength + 1);\n address[] memory newValues = new address[](_values.length + 1);\n\n // Copy values to the new storage arrays\n for (uint256 i; i < keysLength; ) {\n newKeys[i] = _keys[i];\n newValues[i] = _values[i];\n\n unchecked {\n ++i;\n }\n }\n\n // Add the new key-value pair\n newKeys[keysLength] = _key;\n newValues[_values.length] = _value;\n\n return (newKeys, newValues);\n }\n\n // If the key already exists, return the original arrays\n return (_keys, _values);\n }\n\n function getValue(\n bytes4[] memory _keys,\n address[] memory _values,\n bytes4 _key\n ) internal pure returns (address) {\n uint256 index = findIndex(_keys, _key);\n if (index >= _keys.length) return address(0);\n\n return _values[index];\n }\n\n function findIndex(\n bytes4[] memory _keys,\n bytes4 _key\n ) internal pure returns (uint256) {\n uint256 keysLength = _keys.length;\n for (uint256 i; i < keysLength; ) {\n if (_keys[i] == _key) {\n return i;\n }\n unchecked {\n ++i;\n }\n }\n return keysLength;\n }\n}\n" + }, + "contracts/restrictions/IRestriction.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Interface for restrictions\n * @dev Restriction is a contract which decides whether to approve a certain kind of transaction, based on its internal logic.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface IRestriction {\n /**\n * @dev Based on restriction's internal logic, it should accept or reject a certain transaction.\n * @param from The address of the sender, that will be signing the transaction.\n * @param to The receiving address.\n * @param value Amount of ETH to transfer from sender to recipient.\n * @param _calldata Optional field to include arbitrary data.\n * @return bool value for whether the check is passed\n */\n function check(\n address from,\n address to,\n uint256 value,\n bytes calldata _calldata\n ) external returns (bool);\n}\n" + }, + "contracts/restrictions/WhitelistRestriction.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibRecoverSpender} from \"../libraries/LibRecoverSpender.sol\";\nimport {WhitelistStorage} from \"../infrastructure/WhitelistStorage.sol\";\nimport {IRestriction} from \"./IRestriction.sol\";\n\n/**\n * @title Whitelist Restriction\n * @dev This restriction defines a list of accepted addresses and denies any interaction with addresses outside of it.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract WhitelistRestriction is IRestriction {\n WhitelistStorage public immutable whitelistStorage;\n\n constructor(WhitelistStorage _whitelistStorage) {\n whitelistStorage = _whitelistStorage;\n }\n\n /**\n * @notice Helper method to recover the spender from a contract call.\n * The method returns the contract unless the call is to a standard method of a ERC20/ERC721/ERC1155 token\n * in which case the spender is recovered from the data.\n * @param _to The target contract.\n * @param _data The data payload.\n */\n function recoverSpender(\n address _to,\n bytes memory _data\n ) public pure returns (address spender) {\n return LibRecoverSpender._recover(_to, _data);\n }\n\n /*\n * @dev IRestriction's implementation. It will allow transaction if the sender is whitelisted, or user, or the whitelist storage.\n * @param _from The address of the sender, that will be signing the transaction.\n * @param _to The receiving address.\n * @param _calldata Optional field to include arbitrary data.\n * @return result value for whether the check is passed\n */\n function check(\n address _from,\n address _to,\n uint256 /*_value*/,\n bytes calldata _calldata\n ) external view override returns (bool result) {\n return\n whitelistStorage.isWhitelisted(\n _from,\n LibRecoverSpender._recover(_to, _calldata)\n ) ||\n _to == address(whitelistStorage) ||\n _to == msg.sender;\n }\n}\n" + }, + "contracts/test/Counter.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\ncontract TestCounter {\n int private count = 0;\n\n function incrementCounter() public {\n count += 1;\n }\n\n function decrementCounter() public {\n count -= 1;\n }\n\n function getCount() public view returns (int) {\n return count;\n }\n}\n" + }, + "contracts/test/TestERC1155.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC1155/ERC1155.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\n\ncontract TestERC1155 is ERC1155 {\n using Counters for Counters.Counter;\n\n Counters.Counter private _tokenIds;\n\n constructor() ERC1155(\"\") {}\n\n function mint(address account, uint256 amount) external {\n uint256 tokenId = _getNextTokenId();\n _mint(account, tokenId, amount, \"\");\n }\n\n function mintBatch(\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes memory data\n ) external {\n require(\n ids.length == amounts.length,\n \"TestERC1155: arrays length mismatch\"\n );\n\n _mintBatch(to, ids, amounts, data);\n }\n\n function _getNextTokenId() private returns (uint256) {\n _tokenIds.increment();\n return _tokenIds.current();\n }\n}\n" + }, + "contracts/test/TestERC777.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC777/ERC777.sol\";\n\ncontract TestERC777 is ERC777 {\n constructor(\n address[] memory _operators\n ) ERC777(\"TestERC777\", \"TERC777\", _operators) {}\n\n function mint(address account, uint256 amount) external {\n _mint(account, amount, \"\", \"\");\n }\n}\n" + }, + "contracts/test/TestInvalidSecp256k1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IVerificationFacet} from \"../facets/interfaces/IVerificationFacet.sol\";\nimport {IERC1271} from \"../interfaces/ERC/IERC1271.sol\";\nimport {AppStorage, LibAppStorage, BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {LibFacetStorage, Secp256k1VerificationStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {UserOperation} from \"../aa-4337/interfaces/UserOperation.sol\";\n\n/**\n * @title Test Secp256k1 verification facet\n * @dev Default Ethereum's elliptic curve\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract TestInvalidSecp256k1VerificationFacet is BarzStorage, IERC1271 {\n using ECDSA for bytes32;\n error Secp256k1VerificationFacet__InvalidSignerLength();\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n\n event SignerUninitialized();\n\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n }\n\n // THIS INVALID FACET DOES NOT INCLUDE initializeSigner()\n // THIS FACET IS USED TO TEST WHEN initializeSigner() DOESN'T EXIST IN FACET\n\n function uninitializeSigner() external returns (uint256 uninitSuccess) {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view returns (uint256 validationData) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n return validateSignature(userOp, userOpHash, k1Storage.signer);\n }\n\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n address signer\n ) public pure returns (uint256) {\n bytes32 hash = userOpHash.toEthSignedMessageHash();\n if (signer != hash.recover(userOp.signature)) return 1;\n return 0;\n }\n\n // This is REMOVED for testing purpose\n function validateOwnerSignatureSelector() public pure returns (bytes4) {\n // return this.validateOwnerSignature.selector;\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n function owner() public view returns (bytes memory) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n return abi.encodePacked(k1Storage.signer);\n }\n\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure returns (bool) {\n return (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (_hash.recover(_signature) ==\n LibFacetStorage.k1Storage().signer)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n}\n" + }, + "contracts/test/TestNFT.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\n\ncontract TestNFT is ERC721 {\n using Counters for Counters.Counter;\n Counters.Counter private currentTokenId;\n\n constructor() ERC721(\"TestNFT\", \"TNFT\") {}\n\n function mint(address recipient) public returns (uint256) {\n currentTokenId.increment();\n uint256 newItemId = currentTokenId.current();\n _safeMint(recipient, newItemId);\n return newItemId;\n }\n}\n" + }, + "contracts/test/TestToken.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract TestToken is ERC20 {\n constructor()\n // solhint-disable-next-line no-empty-blocks\n ERC20(\"TST\", \"TestToken\")\n {}\n\n function mint(address sender, uint256 amount) external {\n _mint(sender, amount);\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 999999 + }, + "evmVersion": "paris", + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/deployments/base/solcInputs/167a830377988095f5f829bf03425fb0.json b/deployments/base/solcInputs/167a830377988095f5f829bf03425fb0.json new file mode 100644 index 0000000..2833a16 --- /dev/null +++ b/deployments/base/solcInputs/167a830377988095f5f829bf03425fb0.json @@ -0,0 +1,354 @@ +{ + "language": "Solidity", + "sources": { + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby disabling any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable2Step.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./Ownable.sol\";\n\n/**\n * @dev Contract module which provides access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership} and {acceptOwnership}.\n *\n * This module is used through inheritance. It will make available all functions\n * from parent (Ownable).\n */\nabstract contract Ownable2Step is Ownable {\n address private _pendingOwner;\n\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Returns the address of the pending owner.\n */\n function pendingOwner() public view virtual returns (address) {\n return _pendingOwner;\n }\n\n /**\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual override onlyOwner {\n _pendingOwner = newOwner;\n emit OwnershipTransferStarted(owner(), newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual override {\n delete _pendingOwner;\n super._transferOwnership(newOwner);\n }\n\n /**\n * @dev The new owner accepts the ownership transfer.\n */\n function acceptOwnership() public virtual {\n address sender = _msgSender();\n require(pendingOwner() == sender, \"Ownable2Step: caller is not the new owner\");\n _transferOwnership(sender);\n }\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC1271.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC1271 standard signature validation method for\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\n *\n * _Available since v4.1._\n */\ninterface IERC1271 {\n /**\n * @dev Should return whether the signature provided is valid for the provided data\n * @param hash Hash of the data to be signed\n * @param signature Signature byte array associated with _data\n */\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\n}\n" + }, + "@openzeppelin/contracts/security/ReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor() {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n _nonReentrantBefore();\n _;\n _nonReentrantAfter();\n }\n\n function _nonReentrantBefore() private {\n // On the first call to nonReentrant, _status will be _NOT_ENTERED\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n }\n\n function _nonReentrantAfter() private {\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Returns true if the reentrancy guard is currently set to \"entered\", which indicates there is a\n * `nonReentrant` function in the call stack.\n */\n function _reentrancyGuardEntered() internal view returns (bool) {\n return _status == _ENTERED;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/ERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/ERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC1155.sol\";\nimport \"./IERC1155Receiver.sol\";\nimport \"./extensions/IERC1155MetadataURI.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of the basic standard multi-token.\n * See https://eips.ethereum.org/EIPS/eip-1155\n * Originally based on code by Enjin: https://github.com/enjin/erc-1155\n *\n * _Available since v3.1._\n */\ncontract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {\n using Address for address;\n\n // Mapping from token ID to account balances\n mapping(uint256 => mapping(address => uint256)) private _balances;\n\n // Mapping from account to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json\n string private _uri;\n\n /**\n * @dev See {_setURI}.\n */\n constructor(string memory uri_) {\n _setURI(uri_);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return\n interfaceId == type(IERC1155).interfaceId ||\n interfaceId == type(IERC1155MetadataURI).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC1155MetadataURI-uri}.\n *\n * This implementation returns the same URI for *all* token types. It relies\n * on the token type ID substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * Clients calling this function must replace the `\\{id\\}` substring with the\n * actual token type ID.\n */\n function uri(uint256) public view virtual override returns (string memory) {\n return _uri;\n }\n\n /**\n * @dev See {IERC1155-balanceOf}.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {\n require(account != address(0), \"ERC1155: address zero is not a valid owner\");\n return _balances[id][account];\n }\n\n /**\n * @dev See {IERC1155-balanceOfBatch}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] memory accounts,\n uint256[] memory ids\n ) public view virtual override returns (uint256[] memory) {\n require(accounts.length == ids.length, \"ERC1155: accounts and ids length mismatch\");\n\n uint256[] memory batchBalances = new uint256[](accounts.length);\n\n for (uint256 i = 0; i < accounts.length; ++i) {\n batchBalances[i] = balanceOf(accounts[i], ids[i]);\n }\n\n return batchBalances;\n }\n\n /**\n * @dev See {IERC1155-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC1155-isApprovedForAll}.\n */\n function isApprovedForAll(address account, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[account][operator];\n }\n\n /**\n * @dev See {IERC1155-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n _safeTransferFrom(from, to, id, amount, data);\n }\n\n /**\n * @dev See {IERC1155-safeBatchTransferFrom}.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n _safeBatchTransferFrom(from, to, ids, amounts, data);\n }\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n\n emit TransferSingle(operator, from, to, id, amount);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n for (uint256 i = 0; i < ids.length; ++i) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n }\n\n emit TransferBatch(operator, from, to, ids, amounts);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\n\n _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);\n }\n\n /**\n * @dev Sets a new URI for all token types, by relying on the token type ID\n * substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * By this mechanism, any occurrence of the `\\{id\\}` substring in either the\n * URI or any of the amounts in the JSON file at said URI will be replaced by\n * clients with the token type ID.\n *\n * For example, the `https://token-cdn-domain/\\{id\\}.json` URI would be\n * interpreted by clients as\n * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`\n * for token type ID 0x4cce0.\n *\n * See {uri}.\n *\n * Because these URIs cannot be meaningfully represented by the {URI} event,\n * this function emits no events.\n */\n function _setURI(string memory newuri) internal virtual {\n _uri = newuri;\n }\n\n /**\n * @dev Creates `amount` tokens of token type `id`, and assigns them to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _mint(address to, uint256 id, uint256 amount, bytes memory data) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _balances[id][to] += amount;\n emit TransferSingle(operator, address(0), to, id, amount);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n for (uint256 i = 0; i < ids.length; i++) {\n _balances[ids[i]][to] += amounts[i];\n }\n\n emit TransferBatch(operator, address(0), to, ids, amounts);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);\n }\n\n /**\n * @dev Destroys `amount` tokens of token type `id` from `from`\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `from` must have at least `amount` tokens of token type `id`.\n */\n function _burn(address from, uint256 id, uint256 amount) internal virtual {\n require(from != address(0), \"ERC1155: burn from the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n\n emit TransferSingle(operator, from, address(0), id, amount);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n */\n function _burnBatch(address from, uint256[] memory ids, uint256[] memory amounts) internal virtual {\n require(from != address(0), \"ERC1155: burn from the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n\n for (uint256 i = 0; i < ids.length; i++) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n }\n\n emit TransferBatch(operator, from, address(0), ids, amounts);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {\n require(owner != operator, \"ERC1155: setting approval status for self\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning, as well as batched variants.\n *\n * The same hook is called on both single and batched variants. For single\n * transfers, the length of the `ids` and `amounts` arrays will be 1.\n *\n * Calling conditions (for each `id` and `amount` pair):\n *\n * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * of token type `id` will be transferred to `to`.\n * - When `from` is zero, `amount` tokens of token type `id` will be minted\n * for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n * will be burned.\n * - `from` and `to` are never both zero.\n * - `ids` and `amounts` have the same, non-zero length.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any token transfer. This includes minting\n * and burning, as well as batched variants.\n *\n * The same hook is called on both single and batched variants. For single\n * transfers, the length of the `id` and `amount` arrays will be 1.\n *\n * Calling conditions (for each `id` and `amount` pair):\n *\n * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * of token type `id` will be transferred to `to`.\n * - When `from` is zero, `amount` tokens of token type `id` will be minted\n * for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n * will be burned.\n * - `from` and `to` are never both zero.\n * - `ids` and `amounts` have the same, non-zero length.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {}\n\n function _doSafeTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155Receiver.onERC1155Received.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non-ERC1155Receiver implementer\");\n }\n }\n }\n\n function _doSafeBatchTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (\n bytes4 response\n ) {\n if (response != IERC1155Receiver.onERC1155BatchReceived.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non-ERC1155Receiver implementer\");\n }\n }\n }\n\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {\n uint256[] memory array = new uint256[](1);\n array[0] = element;\n\n return array;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC1155.sol\";\n\n/**\n * @dev Interface of the optional ERC1155MetadataExtension interface, as defined\n * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155MetadataURI is IERC1155 {\n /**\n * @dev Returns the URI for token type `id`.\n *\n * If the `\\{id\\}` substring is present in the URI, it must be replaced by\n * clients with the actual token type ID.\n */\n function uri(uint256 id) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155 is IERC165 {\n /**\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n */\n event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);\n\n /**\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n * transfers.\n */\n event TransferBatch(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\n\n /**\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n * `approved`.\n */\n event ApprovalForAll(address indexed account, address indexed operator, bool approved);\n\n /**\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n *\n * If an {URI} event was emitted for `id`, the standard\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n * returned by {IERC1155MetadataURI-uri}.\n */\n event URI(string value, uint256 indexed id);\n\n /**\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) external view returns (uint256);\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] calldata accounts,\n uint256[] calldata ids\n ) external view returns (uint256[] memory);\n\n /**\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n *\n * Emits an {ApprovalForAll} event.\n *\n * Requirements:\n *\n * - `operator` cannot be the caller.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n *\n * See {setApprovalForAll}.\n */\n function isApprovedForAll(address account, address operator) external view returns (bool);\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155Receiver is IERC165 {\n /**\n * @dev Handles the receipt of a single ERC1155 token type. This function is\n * called at the end of a `safeTransferFrom` after the balance has been updated.\n *\n * NOTE: To accept the transfer, this must return\n * `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n * (i.e. 0xf23a6e61, or its own function selector).\n *\n * @param operator The address which initiated the transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param id The ID of the token being transferred\n * @param value The amount of tokens being transferred\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n ) external returns (bytes4);\n\n /**\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\n * is called at the end of a `safeBatchTransferFrom` after the balances have\n * been updated.\n *\n * NOTE: To accept the transfer(s), this must return\n * `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n * (i.e. 0xbc197c81, or its own function selector).\n *\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the default value returned by this function, unless\n * it's overridden.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(address from, address to, uint256 amount) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\n // decrementing then incrementing.\n _balances[to] += amount;\n }\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n unchecked {\n // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\n _balances[account] += amount;\n }\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n // Overflow not possible: amount <= accountBalance <= totalSupply.\n _totalSupply -= amount;\n }\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\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" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` 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 amount) 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 `amount` as the allowance of `spender` over the 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 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` 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 amount) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/ERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721.sol\";\nimport \"./IERC721Receiver.sol\";\nimport \"./extensions/IERC721Metadata.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/Strings.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\n using Address for address;\n using Strings for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\n\n // Mapping from token ID to approved address\n mapping(uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return\n interfaceId == type(IERC721).interfaceId ||\n interfaceId == type(IERC721Metadata).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _ownerOf(tokenId);\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token owner or approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n _requireMinted(tokenId);\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n _safeTransfer(from, to, tokenId, data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(address from, address to, uint256 tokenId, bytes memory data) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist\n */\n function _ownerOf(uint256 tokenId) internal view virtual returns (address) {\n return _owners[tokenId];\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _ownerOf(tokenId) != address(0);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n address owner = ERC721.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(address to, uint256 tokenId, bytes memory data) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId, 1);\n\n // Check that tokenId was not minted by `_beforeTokenTransfer` hook\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n unchecked {\n // Will not overflow unless all 2**256 token ids are minted to the same owner.\n // Given that tokens are minted one by one, it is impossible in practice that\n // this ever happens. Might change if we allow batch minting.\n // The ERC fails to describe this case.\n _balances[to] += 1;\n }\n\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(address(0), to, tokenId, 1);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n * This is an internal function that does not check if the sender is authorized to operate on the token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId, 1);\n\n // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook\n owner = ERC721.ownerOf(tokenId);\n\n // Clear approvals\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // Cannot overflow, as that would require more tokens to be burned/transferred\n // out than the owner initially received through minting and transferring in.\n _balances[owner] -= 1;\n }\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(owner, address(0), tokenId, 1);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(address from, address to, uint256 tokenId) internal virtual {\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId, 1);\n\n // Check that tokenId was not transferred by `_beforeTokenTransfer` hook\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n\n // Clear approvals from the previous owner\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // `_balances[from]` cannot overflow for the same reason as described in `_burn`:\n // `from`'s balance is the number of token held, which is at least one before the current\n // transfer.\n // `_balances[to]` could overflow in the conditions described in `_mint`. That would require\n // all 2**256 token ids to be minted, which in practice is impossible.\n _balances[from] -= 1;\n _balances[to] += 1;\n }\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId, 1);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721Receiver.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`.\n * - When `from` is zero, the tokens will be minted for `to`.\n * - When `to` is zero, ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}\n\n /**\n * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`.\n * - When `from` is zero, the tokens were minted for `to`.\n * - When `to` is zero, ``from``'s tokens were burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}\n\n /**\n * @dev Unsafe write access to the balances, used by extensions that \"mint\" tokens using an {ownerOf} override.\n *\n * WARNING: Anyone calling this MUST ensure that the balances remain consistent with the ownership. The invariant\n * being that for any address `a` the value returned by `balanceOf(a)` must be equal to the number of tokens such\n * that `ownerOf(tokenId)` is `a`.\n */\n // solhint-disable-next-line func-name-mixedcase\n function __unsafe_increaseBalance(address account, uint256 amount) internal {\n _balances[account] += amount;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721Receiver {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/ERC777.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC777/ERC777.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC777.sol\";\nimport \"./IERC777Recipient.sol\";\nimport \"./IERC777Sender.sol\";\nimport \"../ERC20/IERC20.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/introspection/IERC1820Registry.sol\";\n\n/**\n * @dev Implementation of the {IERC777} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n *\n * Support for ERC20 is included in this contract, as specified by the EIP: both\n * the ERC777 and ERC20 interfaces can be safely used when interacting with it.\n * Both {IERC777-Sent} and {IERC20-Transfer} events are emitted on token\n * movements.\n *\n * Additionally, the {IERC777-granularity} value is hard-coded to `1`, meaning that there\n * are no special restrictions in the amount of tokens that created, moved, or\n * destroyed. This makes integration with ERC20 applications seamless.\n *\n * CAUTION: This file is deprecated as of v4.9 and will be removed in the next major release.\n */\ncontract ERC777 is Context, IERC777, IERC20 {\n using Address for address;\n\n IERC1820Registry internal constant _ERC1820_REGISTRY = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n mapping(address => uint256) private _balances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n bytes32 private constant _TOKENS_SENDER_INTERFACE_HASH = keccak256(\"ERC777TokensSender\");\n bytes32 private constant _TOKENS_RECIPIENT_INTERFACE_HASH = keccak256(\"ERC777TokensRecipient\");\n\n // This isn't ever read from - it's only used to respond to the defaultOperators query.\n address[] private _defaultOperatorsArray;\n\n // Immutable, but accounts may revoke them (tracked in __revokedDefaultOperators).\n mapping(address => bool) private _defaultOperators;\n\n // For each account, a mapping of its operators and revoked default operators.\n mapping(address => mapping(address => bool)) private _operators;\n mapping(address => mapping(address => bool)) private _revokedDefaultOperators;\n\n // ERC20-allowances\n mapping(address => mapping(address => uint256)) private _allowances;\n\n /**\n * @dev `defaultOperators` may be an empty array.\n */\n constructor(string memory name_, string memory symbol_, address[] memory defaultOperators_) {\n _name = name_;\n _symbol = symbol_;\n\n _defaultOperatorsArray = defaultOperators_;\n for (uint256 i = 0; i < defaultOperators_.length; i++) {\n _defaultOperators[defaultOperators_[i]] = true;\n }\n\n // register interfaces\n _ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256(\"ERC777Token\"), address(this));\n _ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256(\"ERC20Token\"), address(this));\n }\n\n /**\n * @dev See {IERC777-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC777-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {ERC20-decimals}.\n *\n * Always returns 18, as per the\n * [ERC777 EIP](https://eips.ethereum.org/EIPS/eip-777#backward-compatibility).\n */\n function decimals() public pure virtual returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC777-granularity}.\n *\n * This implementation always returns `1`.\n */\n function granularity() public view virtual override returns (uint256) {\n return 1;\n }\n\n /**\n * @dev See {IERC777-totalSupply}.\n */\n function totalSupply() public view virtual override(IERC20, IERC777) returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev Returns the amount of tokens owned by an account (`tokenHolder`).\n */\n function balanceOf(address tokenHolder) public view virtual override(IERC20, IERC777) returns (uint256) {\n return _balances[tokenHolder];\n }\n\n /**\n * @dev See {IERC777-send}.\n *\n * Also emits a {IERC20-Transfer} event for ERC20 compatibility.\n */\n function send(address recipient, uint256 amount, bytes memory data) public virtual override {\n _send(_msgSender(), recipient, amount, data, \"\", true);\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Unlike `send`, `recipient` is _not_ required to implement the {IERC777Recipient}\n * interface if it is a contract.\n *\n * Also emits a {Sent} event.\n */\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n _send(_msgSender(), recipient, amount, \"\", \"\", false);\n return true;\n }\n\n /**\n * @dev See {IERC777-burn}.\n *\n * Also emits a {IERC20-Transfer} event for ERC20 compatibility.\n */\n function burn(uint256 amount, bytes memory data) public virtual override {\n _burn(_msgSender(), amount, data, \"\");\n }\n\n /**\n * @dev See {IERC777-isOperatorFor}.\n */\n function isOperatorFor(address operator, address tokenHolder) public view virtual override returns (bool) {\n return\n operator == tokenHolder ||\n (_defaultOperators[operator] && !_revokedDefaultOperators[tokenHolder][operator]) ||\n _operators[tokenHolder][operator];\n }\n\n /**\n * @dev See {IERC777-authorizeOperator}.\n */\n function authorizeOperator(address operator) public virtual override {\n require(_msgSender() != operator, \"ERC777: authorizing self as operator\");\n\n if (_defaultOperators[operator]) {\n delete _revokedDefaultOperators[_msgSender()][operator];\n } else {\n _operators[_msgSender()][operator] = true;\n }\n\n emit AuthorizedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-revokeOperator}.\n */\n function revokeOperator(address operator) public virtual override {\n require(operator != _msgSender(), \"ERC777: revoking self as operator\");\n\n if (_defaultOperators[operator]) {\n _revokedDefaultOperators[_msgSender()][operator] = true;\n } else {\n delete _operators[_msgSender()][operator];\n }\n\n emit RevokedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-defaultOperators}.\n */\n function defaultOperators() public view virtual override returns (address[] memory) {\n return _defaultOperatorsArray;\n }\n\n /**\n * @dev See {IERC777-operatorSend}.\n *\n * Emits {Sent} and {IERC20-Transfer} events.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes memory data,\n bytes memory operatorData\n ) public virtual override {\n require(isOperatorFor(_msgSender(), sender), \"ERC777: caller is not an operator for holder\");\n _send(sender, recipient, amount, data, operatorData, true);\n }\n\n /**\n * @dev See {IERC777-operatorBurn}.\n *\n * Emits {Burned} and {IERC20-Transfer} events.\n */\n function operatorBurn(\n address account,\n uint256 amount,\n bytes memory data,\n bytes memory operatorData\n ) public virtual override {\n require(isOperatorFor(_msgSender(), account), \"ERC777: caller is not an operator for holder\");\n _burn(account, amount, data, operatorData);\n }\n\n /**\n * @dev See {IERC20-allowance}.\n *\n * Note that operator and allowance concepts are orthogonal: operators may\n * not have allowance, and accounts with allowance may not be operators\n * themselves.\n */\n function allowance(address holder, address spender) public view virtual override returns (uint256) {\n return _allowances[holder][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Note that accounts cannot have allowance issued by their operators.\n */\n function approve(address spender, uint256 value) public virtual override returns (bool) {\n address holder = _msgSender();\n _approve(holder, spender, value);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Note that operator and allowance concepts are orthogonal: operators cannot\n * call `transferFrom` (unless they have allowance), and accounts with\n * allowance cannot call `operatorSend` (unless they are operators).\n *\n * Emits {Sent}, {IERC20-Transfer} and {IERC20-Approval} events.\n */\n function transferFrom(address holder, address recipient, uint256 amount) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(holder, spender, amount);\n _send(holder, recipient, amount, \"\", \"\", false);\n return true;\n }\n\n /**\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with the caller address as the `operator` and with\n * `userData` and `operatorData`.\n *\n * See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits {Minted} and {IERC20-Transfer} events.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - if `account` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function _mint(address account, uint256 amount, bytes memory userData, bytes memory operatorData) internal virtual {\n _mint(account, amount, userData, operatorData, true);\n }\n\n /**\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * If `requireReceptionAck` is set to true, and if a send hook is\n * registered for `account`, the corresponding function will be called with\n * `operator`, `data` and `operatorData`.\n *\n * See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits {Minted} and {IERC20-Transfer} events.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - if `account` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function _mint(\n address account,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) internal virtual {\n require(account != address(0), \"ERC777: mint to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), account, amount);\n\n // Update state variables\n _totalSupply += amount;\n _balances[account] += amount;\n\n _callTokensReceived(operator, address(0), account, amount, userData, operatorData, requireReceptionAck);\n\n emit Minted(operator, account, amount, userData, operatorData);\n emit Transfer(address(0), account, amount);\n }\n\n /**\n * @dev Send tokens\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _send(\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) internal virtual {\n require(from != address(0), \"ERC777: transfer from the zero address\");\n require(to != address(0), \"ERC777: transfer to the zero address\");\n\n address operator = _msgSender();\n\n _callTokensToSend(operator, from, to, amount, userData, operatorData);\n\n _move(operator, from, to, amount, userData, operatorData);\n\n _callTokensReceived(operator, from, to, amount, userData, operatorData, requireReceptionAck);\n }\n\n /**\n * @dev Burn tokens\n * @param from address token holder address\n * @param amount uint256 amount of tokens to burn\n * @param data bytes extra information provided by the token holder\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _burn(address from, uint256 amount, bytes memory data, bytes memory operatorData) internal virtual {\n require(from != address(0), \"ERC777: burn from the zero address\");\n\n address operator = _msgSender();\n\n _callTokensToSend(operator, from, address(0), amount, data, operatorData);\n\n _beforeTokenTransfer(operator, from, address(0), amount);\n\n // Update state variables\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC777: burn amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Burned(operator, from, amount, data, operatorData);\n emit Transfer(from, address(0), amount);\n }\n\n function _move(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n ) private {\n _beforeTokenTransfer(operator, from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC777: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Sent(operator, from, to, amount, userData, operatorData);\n emit Transfer(from, to, amount);\n }\n\n /**\n * @dev See {ERC20-_approve}.\n *\n * Note that accounts cannot have allowance issued by their operators.\n */\n function _approve(address holder, address spender, uint256 value) internal virtual {\n require(holder != address(0), \"ERC777: approve from the zero address\");\n require(spender != address(0), \"ERC777: approve to the zero address\");\n\n _allowances[holder][spender] = value;\n emit Approval(holder, spender, value);\n }\n\n /**\n * @dev Call from.tokensToSend() if the interface is registered\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _callTokensToSend(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n ) private {\n address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(from, _TOKENS_SENDER_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Sender(implementer).tokensToSend(operator, from, to, amount, userData, operatorData);\n }\n }\n\n /**\n * @dev Call to.tokensReceived() if the interface is registered. Reverts if the recipient is a contract but\n * tokensReceived() was not registered for the recipient\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _callTokensReceived(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) private {\n address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(to, _TOKENS_RECIPIENT_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Recipient(implementer).tokensReceived(operator, from, to, amount, userData, operatorData);\n } else if (requireReceptionAck) {\n require(!to.isContract(), \"ERC777: token recipient contract has no implementer for ERC777TokensRecipient\");\n }\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {IERC20-Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC777: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes\n * calls to {send}, {transfer}, {operatorSend}, {transferFrom}, minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be to transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address operator, address from, address to, uint256 amount) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC777/IERC777.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777Token standard as defined in the EIP.\n *\n * This contract uses the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 registry standard] to let\n * token holders and recipients react to token movements by using setting implementers\n * for the associated interfaces in said registry. See {IERC1820Registry} and\n * {ERC1820Implementer}.\n */\ninterface IERC777 {\n /**\n * @dev Emitted when `amount` tokens are created by `operator` and assigned to `to`.\n *\n * Note that some additional user `data` and `operatorData` can be logged in the event.\n */\n event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);\n\n /**\n * @dev Emitted when `operator` destroys `amount` tokens from `account`.\n *\n * Note that some additional user `data` and `operatorData` can be logged in the event.\n */\n event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);\n\n /**\n * @dev Emitted when `operator` is made operator for `tokenHolder`.\n */\n event AuthorizedOperator(address indexed operator, address indexed tokenHolder);\n\n /**\n * @dev Emitted when `operator` is revoked its operator status for `tokenHolder`.\n */\n event RevokedOperator(address indexed operator, address indexed tokenHolder);\n\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, usually a shorter version of the\n * name.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the smallest part of the token that is not divisible. This\n * means all token operations (creation, movement and destruction) must have\n * amounts that are a multiple of this number.\n *\n * For most token contracts, this value will equal 1.\n */\n function granularity() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by an account (`owner`).\n */\n function balanceOf(address owner) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * If send or receive hooks are registered for the caller and `recipient`,\n * the corresponding functions will be called with `data` and empty\n * `operatorData`. See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits a {Sent} event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function send(address recipient, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Destroys `amount` tokens from the caller's account, reducing the\n * total supply.\n *\n * If a send hook is registered for the caller, the corresponding function\n * will be called with `data` and empty `operatorData`. See {IERC777Sender}.\n *\n * Emits a {Burned} event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n */\n function burn(uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Returns true if an account is an operator of `tokenHolder`.\n * Operators can send and burn tokens on behalf of their owners. All\n * accounts are their own operator.\n *\n * See {operatorSend} and {operatorBurn}.\n */\n function isOperatorFor(address operator, address tokenHolder) external view returns (bool);\n\n /**\n * @dev Make an account an operator of the caller.\n *\n * See {isOperatorFor}.\n *\n * Emits an {AuthorizedOperator} event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function authorizeOperator(address operator) external;\n\n /**\n * @dev Revoke an account's operator status for the caller.\n *\n * See {isOperatorFor} and {defaultOperators}.\n *\n * Emits a {RevokedOperator} event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function revokeOperator(address operator) external;\n\n /**\n * @dev Returns the list of default operators. These accounts are operators\n * for all token holders, even if {authorizeOperator} was never called on\n * them.\n *\n * This list is immutable, but individual holders may revoke these via\n * {revokeOperator}, in which case {isOperatorFor} will return false.\n */\n function defaultOperators() external view returns (address[] memory);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must\n * be an operator of `sender`.\n *\n * If send or receive hooks are registered for `sender` and `recipient`,\n * the corresponding functions will be called with `data` and\n * `operatorData`. See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits a {Sent} event.\n *\n * Requirements\n *\n * - `sender` cannot be the zero address.\n * - `sender` must have at least `amount` tokens.\n * - the caller must be an operator for `sender`.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes calldata data,\n bytes calldata operatorData\n ) external;\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the total supply.\n * The caller must be an operator of `account`.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with `data` and `operatorData`. See {IERC777Sender}.\n *\n * Emits a {Burned} event.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n * - the caller must be an operator for `account`.\n */\n function operatorBurn(address account, uint256 amount, bytes calldata data, bytes calldata operatorData) external;\n\n event Sent(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes data,\n bytes operatorData\n );\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\n *\n * Accounts can be notified of {IERC777} tokens being sent to them by having a\n * contract implement this interface (contract holders can be their own\n * implementer) and registering it on the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\n *\n * See {IERC1820Registry} and {ERC1820Implementer}.\n */\ninterface IERC777Recipient {\n /**\n * @dev Called by an {IERC777} token contract whenever tokens are being\n * moved or created into a registered account (`to`). The type of operation\n * is conveyed by `from` being the zero address or not.\n *\n * This call occurs _after_ the token contract's state is updated, so\n * {IERC777-balanceOf}, etc., can be used to query the post-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensReceived(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777Sender.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Sender.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777TokensSender standard as defined in the EIP.\n *\n * {IERC777} Token holders can be notified of operations performed on their\n * tokens by having a contract implement this interface (contract holders can be\n * their own implementer) and registering it on the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\n *\n * See {IERC1820Registry} and {ERC1820Implementer}.\n */\ninterface IERC777Sender {\n /**\n * @dev Called by an {IERC777} token contract whenever a registered holder's\n * (`from`) tokens are about to be moved or destroyed. The type of operation\n * is conveyed by `to` being the zero address or not.\n *\n * This call occurs _before_ the token contract's state is updated, so\n * {IERC777-balanceOf}, etc., can be used to query the pre-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensToSend(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n *\n * Furthermore, `isContract` will also return true if the target contract within\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n * which only has an effect at the end of a transaction.\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Counters.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary Counters {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/ECDSA.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Strings.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV // Deprecated in v4.8\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n /// @solidity memory-safe-assembly\n assembly {\n mstore(0x00, \"\\x19Ethereum Signed Message:\\n32\")\n mstore(0x1c, hash)\n message := keccak256(0x00, 0x3c)\n }\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\n /// @solidity memory-safe-assembly\n assembly {\n let ptr := mload(0x40)\n mstore(ptr, \"\\x19\\x01\")\n mstore(add(ptr, 0x02), domainSeparator)\n mstore(add(ptr, 0x22), structHash)\n data := keccak256(ptr, 0x42)\n }\n }\n\n /**\n * @dev Returns an Ethereum Signed Data with intended validator, created from a\n * `validator` and `data` according to the version 0 of EIP-191.\n *\n * See {recover}.\n */\n function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x00\", validator, data));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/SignatureChecker.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSA.sol\";\nimport \"../../interfaces/IERC1271.sol\";\n\n/**\n * @dev Signature verification helper that can be used instead of `ECDSA.recover` to seamlessly support both ECDSA\n * signatures from externally owned accounts (EOAs) as well as ERC1271 signatures from smart contract wallets like\n * Argent and Gnosis Safe.\n *\n * _Available since v4.1._\n */\nlibrary SignatureChecker {\n /**\n * @dev Checks if a signature is valid for a given signer and data hash. If the signer is a smart contract, the\n * signature is validated against that smart contract using ERC1271, otherwise it's validated using `ECDSA.recover`.\n *\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\n */\n function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature) internal view returns (bool) {\n (address recovered, ECDSA.RecoverError error) = ECDSA.tryRecover(hash, signature);\n return\n (error == ECDSA.RecoverError.NoError && recovered == signer) ||\n isValidERC1271SignatureNow(signer, hash, signature);\n }\n\n /**\n * @dev Checks if a signature is valid for a given signer and data hash. The signature is validated\n * against the signer smart contract using ERC1271.\n *\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\n */\n function isValidERC1271SignatureNow(\n address signer,\n bytes32 hash,\n bytes memory signature\n ) internal view returns (bool) {\n (bool success, bytes memory result) = signer.staticcall(\n abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, signature)\n );\n return (success &&\n result.length >= 32 &&\n abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/ERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165 is IERC165 {\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165).interfaceId;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC1820Registry.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/introspection/IERC1820Registry.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the global ERC1820 Registry, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register\n * implementers for interfaces in this registry, as well as query support.\n *\n * Implementers may be shared by multiple accounts, and can also implement more\n * than a single interface for each account. Contracts can implement interfaces\n * for themselves, but externally-owned accounts (EOA) must delegate this to a\n * contract.\n *\n * {IERC165} interfaces can also be queried via the registry.\n *\n * For an in-depth explanation and source code analysis, see the EIP text.\n */\ninterface IERC1820Registry {\n event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer);\n\n event ManagerChanged(address indexed account, address indexed newManager);\n\n /**\n * @dev Sets `newManager` as the manager for `account`. A manager of an\n * account is able to set interface implementers for it.\n *\n * By default, each account is its own manager. Passing a value of `0x0` in\n * `newManager` will reset the manager to this initial state.\n *\n * Emits a {ManagerChanged} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `account`.\n */\n function setManager(address account, address newManager) external;\n\n /**\n * @dev Returns the manager for `account`.\n *\n * See {setManager}.\n */\n function getManager(address account) external view returns (address);\n\n /**\n * @dev Sets the `implementer` contract as ``account``'s implementer for\n * `interfaceHash`.\n *\n * `account` being the zero address is an alias for the caller's address.\n * The zero address can also be used in `implementer` to remove an old one.\n *\n * See {interfaceHash} to learn how these are created.\n *\n * Emits an {InterfaceImplementerSet} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `account`.\n * - `interfaceHash` must not be an {IERC165} interface id (i.e. it must not\n * end in 28 zeroes).\n * - `implementer` must implement {IERC1820Implementer} and return true when\n * queried for support, unless `implementer` is the caller. See\n * {IERC1820Implementer-canImplementInterfaceForAddress}.\n */\n function setInterfaceImplementer(address account, bytes32 _interfaceHash, address implementer) external;\n\n /**\n * @dev Returns the implementer of `interfaceHash` for `account`. If no such\n * implementer is registered, returns the zero address.\n *\n * If `interfaceHash` is an {IERC165} interface id (i.e. it ends with 28\n * zeroes), `account` will be queried for support of it.\n *\n * `account` being the zero address is an alias for the caller's address.\n */\n function getInterfaceImplementer(address account, bytes32 _interfaceHash) external view returns (address);\n\n /**\n * @dev Returns the interface hash for an `interfaceName`, as defined in the\n * corresponding\n * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP].\n */\n function interfaceHash(string calldata interfaceName) external pure returns (bytes32);\n\n /**\n * @notice Updates the cache with whether the contract implements an ERC165 interface or not.\n * @param account Address of the contract for which to update the cache.\n * @param interfaceId ERC165 interface for which to update the cache.\n */\n function updateERC165Cache(address account, bytes4 interfaceId) external;\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not.\n * If the result is not cached a direct lookup on the contract address is performed.\n * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling\n * {updateERC165Cache} with the contract address.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool);\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not without using or updating the cache.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/math/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\n // The surrounding unchecked block does not change this fact.\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1, \"Math: mulDiv overflow\");\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n //\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n //\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n //\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1 << (log2(a) >> 1);\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = sqrt(a);\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 2, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 128;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 64;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 32;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 16;\n }\n if (value >> 8 > 0) {\n value >>= 8;\n result += 8;\n }\n if (value >> 4 > 0) {\n value >>= 4;\n result += 4;\n }\n if (value >> 2 > 0) {\n value >>= 2;\n result += 2;\n }\n if (value >> 1 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log2(value);\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 10, rounded down, of a positive value.\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 + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 256, rounded down, of a positive value.\n * Returns 0 if given 0.\n *\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n */\n function log256(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 16;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 8;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 4;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 2;\n }\n if (value >> 8 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log256(value);\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/SafeCast.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCast {\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 * _Available since v4.7._\n */\n function toUint248(uint256 value) internal pure returns (uint248) {\n require(value <= type(uint248).max, \"SafeCast: value doesn't fit in 248 bits\");\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 * _Available since v4.7._\n */\n function toUint240(uint256 value) internal pure returns (uint240) {\n require(value <= type(uint240).max, \"SafeCast: value doesn't fit in 240 bits\");\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 * _Available since v4.7._\n */\n function toUint232(uint256 value) internal pure returns (uint232) {\n require(value <= type(uint232).max, \"SafeCast: value doesn't fit in 232 bits\");\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 * _Available since v4.2._\n */\n function toUint224(uint256 value) internal pure returns (uint224) {\n require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\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 * _Available since v4.7._\n */\n function toUint216(uint256 value) internal pure returns (uint216) {\n require(value <= type(uint216).max, \"SafeCast: value doesn't fit in 216 bits\");\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 * _Available since v4.7._\n */\n function toUint208(uint256 value) internal pure returns (uint208) {\n require(value <= type(uint208).max, \"SafeCast: value doesn't fit in 208 bits\");\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 * _Available since v4.7._\n */\n function toUint200(uint256 value) internal pure returns (uint200) {\n require(value <= type(uint200).max, \"SafeCast: value doesn't fit in 200 bits\");\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 * _Available since v4.7._\n */\n function toUint192(uint256 value) internal pure returns (uint192) {\n require(value <= type(uint192).max, \"SafeCast: value doesn't fit in 192 bits\");\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 * _Available since v4.7._\n */\n function toUint184(uint256 value) internal pure returns (uint184) {\n require(value <= type(uint184).max, \"SafeCast: value doesn't fit in 184 bits\");\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 * _Available since v4.7._\n */\n function toUint176(uint256 value) internal pure returns (uint176) {\n require(value <= type(uint176).max, \"SafeCast: value doesn't fit in 176 bits\");\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 * _Available since v4.7._\n */\n function toUint168(uint256 value) internal pure returns (uint168) {\n require(value <= type(uint168).max, \"SafeCast: value doesn't fit in 168 bits\");\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 * _Available since v4.7._\n */\n function toUint160(uint256 value) internal pure returns (uint160) {\n require(value <= type(uint160).max, \"SafeCast: value doesn't fit in 160 bits\");\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 * _Available since v4.7._\n */\n function toUint152(uint256 value) internal pure returns (uint152) {\n require(value <= type(uint152).max, \"SafeCast: value doesn't fit in 152 bits\");\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 * _Available since v4.7._\n */\n function toUint144(uint256 value) internal pure returns (uint144) {\n require(value <= type(uint144).max, \"SafeCast: value doesn't fit in 144 bits\");\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 * _Available since v4.7._\n */\n function toUint136(uint256 value) internal pure returns (uint136) {\n require(value <= type(uint136).max, \"SafeCast: value doesn't fit in 136 bits\");\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 * _Available since v2.5._\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\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 * _Available since v4.7._\n */\n function toUint120(uint256 value) internal pure returns (uint120) {\n require(value <= type(uint120).max, \"SafeCast: value doesn't fit in 120 bits\");\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 * _Available since v4.7._\n */\n function toUint112(uint256 value) internal pure returns (uint112) {\n require(value <= type(uint112).max, \"SafeCast: value doesn't fit in 112 bits\");\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 * _Available since v4.7._\n */\n function toUint104(uint256 value) internal pure returns (uint104) {\n require(value <= type(uint104).max, \"SafeCast: value doesn't fit in 104 bits\");\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 * _Available since v4.2._\n */\n function toUint96(uint256 value) internal pure returns (uint96) {\n require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\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 * _Available since v4.7._\n */\n function toUint88(uint256 value) internal pure returns (uint88) {\n require(value <= type(uint88).max, \"SafeCast: value doesn't fit in 88 bits\");\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 * _Available since v4.7._\n */\n function toUint80(uint256 value) internal pure returns (uint80) {\n require(value <= type(uint80).max, \"SafeCast: value doesn't fit in 80 bits\");\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 * _Available since v4.7._\n */\n function toUint72(uint256 value) internal pure returns (uint72) {\n require(value <= type(uint72).max, \"SafeCast: value doesn't fit in 72 bits\");\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 * _Available since v2.5._\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\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 * _Available since v4.7._\n */\n function toUint56(uint256 value) internal pure returns (uint56) {\n require(value <= type(uint56).max, \"SafeCast: value doesn't fit in 56 bits\");\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 * _Available since v4.7._\n */\n function toUint48(uint256 value) internal pure returns (uint48) {\n require(value <= type(uint48).max, \"SafeCast: value doesn't fit in 48 bits\");\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 * _Available since v4.7._\n */\n function toUint40(uint256 value) internal pure returns (uint40) {\n require(value <= type(uint40).max, \"SafeCast: value doesn't fit in 40 bits\");\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 * _Available since v2.5._\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\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 * _Available since v4.7._\n */\n function toUint24(uint256 value) internal pure returns (uint24) {\n require(value <= type(uint24).max, \"SafeCast: value doesn't fit in 24 bits\");\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 * _Available since v2.5._\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\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 * _Available since v2.5._\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\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 * _Available since v3.0._\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\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 * _Available since v4.7._\n */\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\n downcasted = int248(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 248 bits\");\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 * _Available since v4.7._\n */\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\n downcasted = int240(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 240 bits\");\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 * _Available since v4.7._\n */\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\n downcasted = int232(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 232 bits\");\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 * _Available since v4.7._\n */\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\n downcasted = int224(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 224 bits\");\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 * _Available since v4.7._\n */\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\n downcasted = int216(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 216 bits\");\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 * _Available since v4.7._\n */\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\n downcasted = int208(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 208 bits\");\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 * _Available since v4.7._\n */\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\n downcasted = int200(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 200 bits\");\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 * _Available since v4.7._\n */\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\n downcasted = int192(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 192 bits\");\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 * _Available since v4.7._\n */\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\n downcasted = int184(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 184 bits\");\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 * _Available since v4.7._\n */\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\n downcasted = int176(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 176 bits\");\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 * _Available since v4.7._\n */\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\n downcasted = int168(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 168 bits\");\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 * _Available since v4.7._\n */\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\n downcasted = int160(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 160 bits\");\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 * _Available since v4.7._\n */\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\n downcasted = int152(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 152 bits\");\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 * _Available since v4.7._\n */\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\n downcasted = int144(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 144 bits\");\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 * _Available since v4.7._\n */\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\n downcasted = int136(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 136 bits\");\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 * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\n downcasted = int128(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 128 bits\");\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 * _Available since v4.7._\n */\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\n downcasted = int120(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 120 bits\");\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 * _Available since v4.7._\n */\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\n downcasted = int112(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 112 bits\");\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 * _Available since v4.7._\n */\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\n downcasted = int104(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 104 bits\");\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 * _Available since v4.7._\n */\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\n downcasted = int96(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 96 bits\");\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 * _Available since v4.7._\n */\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\n downcasted = int88(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 88 bits\");\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 * _Available since v4.7._\n */\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\n downcasted = int80(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 80 bits\");\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 * _Available since v4.7._\n */\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\n downcasted = int72(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 72 bits\");\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 * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\n downcasted = int64(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 64 bits\");\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 * _Available since v4.7._\n */\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\n downcasted = int56(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 56 bits\");\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 * _Available since v4.7._\n */\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\n downcasted = int48(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 48 bits\");\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 * _Available since v4.7._\n */\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\n downcasted = int40(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 40 bits\");\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 * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\n downcasted = int32(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 32 bits\");\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 * _Available since v4.7._\n */\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\n downcasted = int24(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 24 bits\");\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 * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\n downcasted = int16(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 16 bits\");\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 * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\n downcasted = int8(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 8 bits\");\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 * _Available since v3.0._\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 require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/SignedMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard signed math utilities missing in the Solidity language.\n */\nlibrary SignedMath {\n /**\n * @dev Returns the largest of two signed numbers.\n */\n function max(int256 a, int256 b) internal pure returns (int256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two signed numbers.\n */\n function min(int256 a, int256 b) internal pure returns (int256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two signed numbers without overflow.\n * The result is rounded towards zero.\n */\n function average(int256 a, int256 b) internal pure returns (int256) {\n // Formula from the book \"Hacker's Delight\"\n int256 x = (a & b) + ((a ^ b) >> 1);\n return x + (int256(uint256(x) >> 255) & (a ^ b));\n }\n\n /**\n * @dev Returns the absolute unsigned value of a signed value.\n */\n function abs(int256 n) internal pure returns (uint256) {\n unchecked {\n // must be unchecked in order to support `n = type(int256).min`\n return uint256(n >= 0 ? n : -n);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/Math.sol\";\nimport \"./math/SignedMath.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n unchecked {\n uint256 length = Math.log10(value) + 1;\n string memory buffer = new string(length);\n uint256 ptr;\n /// @solidity memory-safe-assembly\n assembly {\n ptr := add(buffer, add(32, length))\n }\n while (true) {\n ptr--;\n /// @solidity memory-safe-assembly\n assembly {\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n }\n value /= 10;\n if (value == 0) break;\n }\n return buffer;\n }\n }\n\n /**\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\n */\n function toString(int256 value) internal pure returns (string memory) {\n return string(abi.encodePacked(value < 0 ? \"-\" : \"\", toString(SignedMath.abs(value))));\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n unchecked {\n return toHexString(value, Math.log256(value) + 1);\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n\n /**\n * @dev Returns true if the two strings are equal.\n */\n function equal(string memory a, string memory b) internal pure returns (bool) {\n return keccak256(bytes(a)) == keccak256(bytes(b));\n }\n}\n" + }, + "contracts/aa-4337/core/BaseAccount.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-empty-blocks */\n\nimport \"../interfaces/IAccount.sol\";\nimport \"../interfaces/IEntryPoint.sol\";\nimport \"./Helpers.sol\";\n\n/**\n * Basic account implementation.\n * this contract provides the basic logic for implementing the IAccount interface - validateUserOp\n * specific account implementation should inherit it and provide the account-specific logic\n */\nabstract contract BaseAccount is IAccount {\n using UserOperationLib for UserOperation;\n\n //return value in case of signature failure, with no time-range.\n // equivalent to _packValidationData(true,0,0);\n uint256 internal constant SIG_VALIDATION_FAILED = 1;\n\n /**\n * Return the account nonce.\n * This method returns the next sequential nonce.\n * For a nonce of a specific key, use `entrypoint.getNonce(account, key)`\n */\n function getNonce() public view virtual returns (uint256) {\n return entryPoint().getNonce(address(this), 0);\n }\n\n /**\n * return the entryPoint used by this account.\n * subclass should return the current entryPoint used by this account.\n */\n function entryPoint() public view virtual returns (IEntryPoint);\n\n /**\n * Validate user's signature and nonce.\n * subclass doesn't need to override this method. Instead, it should override the specific internal validation methods.\n */\n function validateUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 missingAccountFunds\n ) external virtual override returns (uint256 validationData) {\n _requireFromEntryPoint();\n validationData = _validateSignature(userOp, userOpHash);\n _validateNonce(userOp.nonce);\n _payPrefund(missingAccountFunds);\n }\n\n /**\n * ensure the request comes from the known entrypoint.\n */\n function _requireFromEntryPoint() internal view virtual {\n require(\n msg.sender == address(entryPoint()),\n \"account: not from EntryPoint\"\n );\n }\n\n /**\n * validate the signature is valid for this message.\n * @param userOp validate the userOp.signature field\n * @param userOpHash convenient field: the hash of the request, to check the signature against\n * (also hashes the entrypoint and chain id)\n * @return validationData signature and time-range of this operation\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * If the account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function _validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) internal virtual returns (uint256 validationData);\n\n /**\n * Validate the nonce of the UserOperation.\n * This method may validate the nonce requirement of this account.\n * e.g.\n * To limit the nonce to use sequenced UserOps only (no \"out of order\" UserOps):\n * `require(nonce < type(uint64).max)`\n * For a hypothetical account that *requires* the nonce to be out-of-order:\n * `require(nonce & type(uint64).max == 0)`\n *\n * The actual nonce uniqueness is managed by the EntryPoint, and thus no other\n * action is needed by the account itself.\n *\n * @param nonce to validate\n *\n * solhint-disable-next-line no-empty-blocks\n */\n function _validateNonce(uint256 nonce) internal view virtual {}\n\n /**\n * sends to the entrypoint (msg.sender) the missing funds for this transaction.\n * subclass MAY override this method for better funds management\n * (e.g. send to the entryPoint more than the minimum required, so that in future transactions\n * it will not be required to send again)\n * @param missingAccountFunds the minimum value this method should send the entrypoint.\n * this value MAY be zero, in case there is enough deposit, or the userOp has a paymaster.\n */\n function _payPrefund(uint256 missingAccountFunds) internal virtual {\n if (missingAccountFunds != 0) {\n (bool success, ) = payable(msg.sender).call{\n value: missingAccountFunds,\n gas: type(uint256).max\n }(\"\");\n (success);\n //ignore failure (its EntryPoint's job to verify, not account.)\n }\n }\n}\n" + }, + "contracts/aa-4337/core/EntryPoint.sol": { + "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n\nimport \"../interfaces/IAccount.sol\";\nimport \"../interfaces/IPaymaster.sol\";\nimport \"../interfaces/IEntryPoint.sol\";\n\nimport \"../utils/Exec.sol\";\nimport \"./StakeManager.sol\";\nimport \"./SenderCreator.sol\";\nimport \"./Helpers.sol\";\nimport \"./NonceManager.sol\";\nimport \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\n\ncontract EntryPoint is\n IEntryPoint,\n StakeManager,\n NonceManager,\n ReentrancyGuard\n{\n using UserOperationLib for UserOperation;\n\n SenderCreator private immutable senderCreator = new SenderCreator();\n\n // internal value used during simulation: need to query aggregator.\n address private constant SIMULATE_FIND_AGGREGATOR = address(1);\n\n // marker for inner call revert on out of gas\n bytes32 private constant INNER_OUT_OF_GAS = hex\"deaddead\";\n\n uint256 private constant REVERT_REASON_MAX_LEN = 2048;\n\n /**\n * for simulation purposes, validateUserOp (and validatePaymasterUserOp) must return this value\n * in case of signature failure, instead of revert.\n */\n uint256 public constant SIG_VALIDATION_FAILED = 1;\n\n /**\n * compensate the caller's beneficiary address with the collected fees of all UserOperations.\n * @param beneficiary the address to receive the fees\n * @param amount amount to transfer.\n */\n function _compensate(address payable beneficiary, uint256 amount) internal {\n require(beneficiary != address(0), \"AA90 invalid beneficiary\");\n (bool success, ) = beneficiary.call{value: amount}(\"\");\n require(success, \"AA91 failed send to beneficiary\");\n }\n\n /**\n * execute a user op\n * @param opIndex index into the opInfo array\n * @param userOp the userOp to execute\n * @param opInfo the opInfo filled by validatePrepayment for this userOp.\n * @return collected the total amount this userOp paid.\n */\n function _executeUserOp(\n uint256 opIndex,\n UserOperation calldata userOp,\n UserOpInfo memory opInfo\n ) private returns (uint256 collected) {\n uint256 preGas = gasleft();\n bytes memory context = getMemoryBytesFromOffset(opInfo.contextOffset);\n\n try this.innerHandleOp(userOp.callData, opInfo, context) returns (\n uint256 _actualGasCost\n ) {\n collected = _actualGasCost;\n } catch {\n bytes32 innerRevertCode;\n assembly {\n returndatacopy(0, 0, 32)\n innerRevertCode := mload(0)\n }\n // handleOps was called with gas limit too low. abort entire bundle.\n if (innerRevertCode == INNER_OUT_OF_GAS) {\n //report paymaster, since if it is not deliberately caused by the bundler,\n // it must be a revert caused by paymaster.\n revert FailedOp(opIndex, \"AA95 out of gas\");\n }\n\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n collected = _handlePostOp(\n opIndex,\n IPaymaster.PostOpMode.postOpReverted,\n opInfo,\n context,\n actualGas\n );\n }\n }\n\n /**\n * Execute a batch of UserOperations.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(\n UserOperation[] calldata ops,\n address payable beneficiary\n ) public nonReentrant {\n uint256 opslen = ops.length;\n UserOpInfo[] memory opInfos = new UserOpInfo[](opslen);\n\n unchecked {\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[i];\n (\n uint256 validationData,\n uint256 pmValidationData\n ) = _validatePrepayment(i, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(\n i,\n validationData,\n pmValidationData,\n address(0)\n );\n }\n\n uint256 collected = 0;\n emit BeforeExecution();\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(i, ops[i], opInfos[i]);\n }\n\n _compensate(beneficiary, collected);\n } //unchecked\n }\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) public nonReentrant {\n uint256 opasLen = opsPerAggregator.length;\n uint256 totalOps = 0;\n for (uint256 i = 0; i < opasLen; i++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[i];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n //address(1) is special marker of \"signature error\"\n require(\n address(aggregator) != address(1),\n \"AA96 invalid aggregator\"\n );\n\n if (address(aggregator) != address(0)) {\n // solhint-disable-next-line no-empty-blocks\n try aggregator.validateSignatures(ops, opa.signature) {} catch {\n revert SignatureValidationFailed(address(aggregator));\n }\n }\n\n totalOps += ops.length;\n }\n\n UserOpInfo[] memory opInfos = new UserOpInfo[](totalOps);\n\n emit BeforeExecution();\n\n uint256 opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n uint256 opslen = ops.length;\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[opIndex];\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(opIndex, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(\n i,\n validationData,\n paymasterValidationData,\n address(aggregator)\n );\n opIndex++;\n }\n }\n\n uint256 collected = 0;\n opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n emit SignatureAggregatorChanged(address(opa.aggregator));\n UserOperation[] calldata ops = opa.userOps;\n uint256 opslen = ops.length;\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(opIndex, ops[i], opInfos[opIndex]);\n opIndex++;\n }\n }\n emit SignatureAggregatorChanged(address(0));\n\n _compensate(beneficiary, collected);\n }\n\n /// @inheritdoc IEntryPoint\n function simulateHandleOp(\n UserOperation calldata op,\n address target,\n bytes calldata targetCallData\n ) external override {\n UserOpInfo memory opInfo;\n _simulationOnlyValidations(op);\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(0, op, opInfo);\n ValidationData memory data = _intersectTimeRange(\n validationData,\n paymasterValidationData\n );\n\n numberMarker();\n uint256 paid = _executeUserOp(0, op, opInfo);\n numberMarker();\n bool targetSuccess;\n bytes memory targetResult;\n if (target != address(0)) {\n (targetSuccess, targetResult) = target.call(targetCallData);\n }\n revert ExecutionResult(\n opInfo.preOpGas,\n paid,\n data.validAfter,\n data.validUntil,\n targetSuccess,\n targetResult\n );\n }\n\n // A memory copy of UserOp static fields only.\n // Excluding: callData, initCode and signature. Replacing paymasterAndData with paymaster.\n struct MemoryUserOp {\n address sender;\n uint256 nonce;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n address paymaster;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n }\n\n struct UserOpInfo {\n MemoryUserOp mUserOp;\n bytes32 userOpHash;\n uint256 prefund;\n uint256 contextOffset;\n uint256 preOpGas;\n }\n\n /**\n * inner function to handle a UserOperation.\n * Must be declared \"external\" to open a call context, but it can only be called by handleOps.\n */\n function innerHandleOp(\n bytes memory callData,\n UserOpInfo memory opInfo,\n bytes calldata context\n ) external returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n require(msg.sender == address(this), \"AA92 internal call only\");\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n\n uint callGasLimit = mUserOp.callGasLimit;\n unchecked {\n // handleOps was called with gas limit too low. abort entire bundle.\n if (\n gasleft() < callGasLimit + mUserOp.verificationGasLimit + 5000\n ) {\n assembly {\n mstore(0, INNER_OUT_OF_GAS)\n revert(0, 32)\n }\n }\n }\n\n IPaymaster.PostOpMode mode = IPaymaster.PostOpMode.opSucceeded;\n if (callData.length > 0) {\n bool success = Exec.call(mUserOp.sender, 0, callData, callGasLimit);\n if (!success) {\n bytes memory result = Exec.getReturnData(REVERT_REASON_MAX_LEN);\n if (result.length > 0) {\n emit UserOperationRevertReason(\n opInfo.userOpHash,\n mUserOp.sender,\n mUserOp.nonce,\n result\n );\n }\n mode = IPaymaster.PostOpMode.opReverted;\n }\n }\n\n unchecked {\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n //note: opIndex is ignored (relevant only if mode==postOpReverted, which is only possible outside of innerHandleOp)\n return _handlePostOp(0, mode, opInfo, context, actualGas);\n }\n }\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(\n UserOperation calldata userOp\n ) public view returns (bytes32) {\n return\n keccak256(abi.encode(userOp.hash(), address(this), block.chainid));\n }\n\n /**\n * copy general fields from userOp into the memory opInfo structure.\n */\n function _copyUserOpToMemory(\n UserOperation calldata userOp,\n MemoryUserOp memory mUserOp\n ) internal pure {\n mUserOp.sender = userOp.sender;\n mUserOp.nonce = userOp.nonce;\n mUserOp.callGasLimit = userOp.callGasLimit;\n mUserOp.verificationGasLimit = userOp.verificationGasLimit;\n mUserOp.preVerificationGas = userOp.preVerificationGas;\n mUserOp.maxFeePerGas = userOp.maxFeePerGas;\n mUserOp.maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes calldata paymasterAndData = userOp.paymasterAndData;\n if (paymasterAndData.length > 0) {\n require(\n paymasterAndData.length >= 20,\n \"AA93 invalid paymasterAndData\"\n );\n mUserOp.paymaster = address(bytes20(paymasterAndData[:20]));\n } else {\n mUserOp.paymaster = address(0);\n }\n }\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external {\n UserOpInfo memory outOpInfo;\n\n _simulationOnlyValidations(userOp);\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(0, userOp, outOpInfo);\n StakeInfo memory paymasterInfo = _getStakeInfo(\n outOpInfo.mUserOp.paymaster\n );\n StakeInfo memory senderInfo = _getStakeInfo(outOpInfo.mUserOp.sender);\n StakeInfo memory factoryInfo;\n {\n bytes calldata initCode = userOp.initCode;\n address factory = initCode.length >= 20\n ? address(bytes20(initCode[0:20]))\n : address(0);\n factoryInfo = _getStakeInfo(factory);\n }\n\n ValidationData memory data = _intersectTimeRange(\n validationData,\n paymasterValidationData\n );\n address aggregator = data.aggregator;\n bool sigFailed = aggregator == address(1);\n ReturnInfo memory returnInfo = ReturnInfo(\n outOpInfo.preOpGas,\n outOpInfo.prefund,\n sigFailed,\n data.validAfter,\n data.validUntil,\n getMemoryBytesFromOffset(outOpInfo.contextOffset)\n );\n\n if (aggregator != address(0) && aggregator != address(1)) {\n AggregatorStakeInfo memory aggregatorInfo = AggregatorStakeInfo(\n aggregator,\n _getStakeInfo(aggregator)\n );\n revert ValidationResultWithAggregation(\n returnInfo,\n senderInfo,\n factoryInfo,\n paymasterInfo,\n aggregatorInfo\n );\n }\n revert ValidationResult(\n returnInfo,\n senderInfo,\n factoryInfo,\n paymasterInfo\n );\n }\n\n function _getRequiredPrefund(\n MemoryUserOp memory mUserOp\n ) internal pure returns (uint256 requiredPrefund) {\n unchecked {\n //when using a Paymaster, the verificationGasLimit is used also to as a limit for the postOp call.\n // our security model might call postOp eventually twice\n uint256 mul = mUserOp.paymaster != address(0) ? 3 : 1;\n uint256 requiredGas = mUserOp.callGasLimit +\n mUserOp.verificationGasLimit *\n mul +\n mUserOp.preVerificationGas;\n\n requiredPrefund = requiredGas * mUserOp.maxFeePerGas;\n }\n }\n\n // create the sender's contract if needed.\n function _createSenderIfNeeded(\n uint256 opIndex,\n UserOpInfo memory opInfo,\n bytes calldata initCode\n ) internal {\n if (initCode.length != 0) {\n address sender = opInfo.mUserOp.sender;\n if (sender.code.length != 0)\n revert FailedOp(opIndex, \"AA10 sender already constructed\");\n address sender1 = senderCreator.createSender{\n gas: opInfo.mUserOp.verificationGasLimit\n }(initCode);\n if (sender1 == address(0))\n revert FailedOp(opIndex, \"AA13 initCode failed or OOG\");\n if (sender1 != sender)\n revert FailedOp(opIndex, \"AA14 initCode must return sender\");\n if (sender1.code.length == 0)\n revert FailedOp(opIndex, \"AA15 initCode must create sender\");\n address factory = address(bytes20(initCode[0:20]));\n emit AccountDeployed(\n opInfo.userOpHash,\n sender,\n factory,\n opInfo.mUserOp.paymaster\n );\n }\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes calldata initCode) public {\n address sender = senderCreator.createSender(initCode);\n revert SenderAddressResult(sender);\n }\n\n function _simulationOnlyValidations(\n UserOperation calldata userOp\n ) internal view {\n // solhint-disable-next-line no-empty-blocks\n try\n this._validateSenderAndPaymaster(\n userOp.initCode,\n userOp.sender,\n userOp.paymasterAndData\n )\n {} catch Error(string memory revertReason) {\n if (bytes(revertReason).length != 0) {\n revert FailedOp(0, revertReason);\n }\n }\n }\n\n /**\n * Called only during simulation.\n * This function always reverts to prevent warm/cold storage differentiation in simulation vs execution.\n */\n function _validateSenderAndPaymaster(\n bytes calldata initCode,\n address sender,\n bytes calldata paymasterAndData\n ) external view {\n if (initCode.length == 0 && sender.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA20 account not deployed\");\n }\n if (paymasterAndData.length >= 20) {\n address paymaster = address(bytes20(paymasterAndData[0:20]));\n if (paymaster.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA30 paymaster not deployed\");\n }\n }\n // always revert\n revert(\"\");\n }\n\n /**\n * call account.validateUserOp.\n * revert (with FailedOp) in case validateUserOp reverts, or account didn't send required prefund.\n * decrement account's deposit if needed\n */\n function _validateAccountPrepayment(\n uint256 opIndex,\n UserOperation calldata op,\n UserOpInfo memory opInfo,\n uint256 requiredPrefund\n )\n internal\n returns (\n uint256 gasUsedByValidateAccountPrepayment,\n uint256 validationData\n )\n {\n unchecked {\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n address sender = mUserOp.sender;\n _createSenderIfNeeded(opIndex, opInfo, op.initCode);\n address paymaster = mUserOp.paymaster;\n numberMarker();\n uint256 missingAccountFunds = 0;\n if (paymaster == address(0)) {\n uint256 bal = balanceOf(sender);\n missingAccountFunds = bal > requiredPrefund\n ? 0\n : requiredPrefund - bal;\n }\n try\n IAccount(sender).validateUserOp{\n gas: mUserOp.verificationGasLimit\n }(op, opInfo.userOpHash, missingAccountFunds)\n returns (uint256 _validationData) {\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA23 reverted: \", revertReason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA23 reverted (or OOG)\");\n }\n if (paymaster == address(0)) {\n DepositInfo storage senderInfo = deposits[sender];\n uint256 deposit = senderInfo.deposit;\n if (requiredPrefund > deposit) {\n revert FailedOp(opIndex, \"AA21 didn't pay prefund\");\n }\n senderInfo.deposit = uint112(deposit - requiredPrefund);\n }\n gasUsedByValidateAccountPrepayment = preGas - gasleft();\n }\n }\n\n /**\n * In case the request has a paymaster:\n * Validate paymaster has enough deposit.\n * Call paymaster.validatePaymasterUserOp.\n * Revert with proper FailedOp in case paymaster reverts.\n * Decrement paymaster's deposit\n */\n function _validatePaymasterPrepayment(\n uint256 opIndex,\n UserOperation calldata op,\n UserOpInfo memory opInfo,\n uint256 requiredPreFund,\n uint256 gasUsedByValidateAccountPrepayment\n ) internal returns (bytes memory context, uint256 validationData) {\n unchecked {\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 verificationGasLimit = mUserOp.verificationGasLimit;\n require(\n verificationGasLimit > gasUsedByValidateAccountPrepayment,\n \"AA41 too little verificationGas\"\n );\n uint256 gas = verificationGasLimit -\n gasUsedByValidateAccountPrepayment;\n\n address paymaster = mUserOp.paymaster;\n DepositInfo storage paymasterInfo = deposits[paymaster];\n uint256 deposit = paymasterInfo.deposit;\n if (deposit < requiredPreFund) {\n revert FailedOp(opIndex, \"AA31 paymaster deposit too low\");\n }\n paymasterInfo.deposit = uint112(deposit - requiredPreFund);\n try\n IPaymaster(paymaster).validatePaymasterUserOp{gas: gas}(\n op,\n opInfo.userOpHash,\n requiredPreFund\n )\n returns (bytes memory _context, uint256 _validationData) {\n context = _context;\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA33 reverted: \", revertReason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA33 reverted (or OOG)\");\n }\n }\n }\n\n /**\n * revert if either account validationData or paymaster validationData is expired\n */\n function _validateAccountAndPaymasterValidationData(\n uint256 opIndex,\n uint256 validationData,\n uint256 paymasterValidationData,\n address expectedAggregator\n ) internal view {\n (address aggregator, bool outOfTimeRange) = _getValidationData(\n validationData\n );\n if (expectedAggregator != aggregator) {\n revert FailedOp(opIndex, \"AA24 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA22 expired or not due\");\n }\n //pmAggregator is not a real signature aggregator: we don't have logic to handle it as address.\n // non-zero address means that the paymaster fails due to some signature check (which is ok only during estimation)\n address pmAggregator;\n (pmAggregator, outOfTimeRange) = _getValidationData(\n paymasterValidationData\n );\n if (pmAggregator != address(0)) {\n revert FailedOp(opIndex, \"AA34 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA32 paymaster expired or not due\");\n }\n }\n\n function _getValidationData(\n uint256 validationData\n ) internal view returns (address aggregator, bool outOfTimeRange) {\n if (validationData == 0) {\n return (address(0), false);\n }\n ValidationData memory data = _parseValidationData(validationData);\n // solhint-disable-next-line not-rely-on-time\n outOfTimeRange =\n block.timestamp > data.validUntil ||\n block.timestamp < data.validAfter;\n aggregator = data.aggregator;\n }\n\n /**\n * validate account and paymaster (if defined).\n * also make sure total validation doesn't exceed verificationGasLimit\n * this method is called off-chain (simulateValidation()) and on-chain (from handleOps)\n * @param opIndex the index of this userOp into the \"opInfos\" array\n * @param userOp the userOp to validate\n */\n function _validatePrepayment(\n uint256 opIndex,\n UserOperation calldata userOp,\n UserOpInfo memory outOpInfo\n )\n private\n returns (uint256 validationData, uint256 paymasterValidationData)\n {\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = outOpInfo.mUserOp;\n _copyUserOpToMemory(userOp, mUserOp);\n outOpInfo.userOpHash = getUserOpHash(userOp);\n\n // validate all numeric values in userOp are well below 128 bit, so they can safely be added\n // and multiplied without causing overflow\n uint256 maxGasValues = mUserOp.preVerificationGas |\n mUserOp.verificationGasLimit |\n mUserOp.callGasLimit |\n userOp.maxFeePerGas |\n userOp.maxPriorityFeePerGas;\n require(maxGasValues <= type(uint120).max, \"AA94 gas values overflow\");\n\n uint256 gasUsedByValidateAccountPrepayment;\n uint256 requiredPreFund = _getRequiredPrefund(mUserOp);\n (\n gasUsedByValidateAccountPrepayment,\n validationData\n ) = _validateAccountPrepayment(\n opIndex,\n userOp,\n outOpInfo,\n requiredPreFund\n );\n\n if (!_validateAndUpdateNonce(mUserOp.sender, mUserOp.nonce)) {\n revert FailedOp(opIndex, \"AA25 invalid account nonce\");\n }\n\n //a \"marker\" where account opcode validation is done and paymaster opcode validation is about to start\n // (used only by off-chain simulateValidation)\n numberMarker();\n\n bytes memory context;\n if (mUserOp.paymaster != address(0)) {\n (context, paymasterValidationData) = _validatePaymasterPrepayment(\n opIndex,\n userOp,\n outOpInfo,\n requiredPreFund,\n gasUsedByValidateAccountPrepayment\n );\n }\n unchecked {\n uint256 gasUsed = preGas - gasleft();\n\n if (userOp.verificationGasLimit < gasUsed) {\n revert FailedOp(opIndex, \"AA40 over verificationGasLimit\");\n }\n outOpInfo.prefund = requiredPreFund;\n outOpInfo.contextOffset = getOffsetOfMemoryBytes(context);\n outOpInfo.preOpGas = preGas - gasleft() + userOp.preVerificationGas;\n }\n }\n\n /**\n * process post-operation.\n * called just after the callData is executed.\n * if a paymaster is defined and its validation returned a non-empty context, its postOp is called.\n * the excess amount is refunded to the account (or paymaster - if it was used in the request)\n * @param opIndex index in the batch\n * @param mode - whether is called from innerHandleOp, or outside (postOpReverted)\n * @param opInfo userOp fields and info collected during validation\n * @param context the context returned in validatePaymasterUserOp\n * @param actualGas the gas used so far by this user operation\n */\n function _handlePostOp(\n uint256 opIndex,\n IPaymaster.PostOpMode mode,\n UserOpInfo memory opInfo,\n bytes memory context,\n uint256 actualGas\n ) private returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n unchecked {\n address refundAddress;\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 gasPrice = getUserOpGasPrice(mUserOp);\n\n address paymaster = mUserOp.paymaster;\n if (paymaster == address(0)) {\n refundAddress = mUserOp.sender;\n } else {\n refundAddress = paymaster;\n if (context.length > 0) {\n actualGasCost = actualGas * gasPrice;\n if (mode != IPaymaster.PostOpMode.postOpReverted) {\n IPaymaster(paymaster).postOp{\n gas: mUserOp.verificationGasLimit\n }(mode, context, actualGasCost);\n } else {\n // solhint-disable-next-line no-empty-blocks\n try\n IPaymaster(paymaster).postOp{\n gas: mUserOp.verificationGasLimit\n }(mode, context, actualGasCost)\n {} catch Error(string memory reason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA50 postOp reverted: \", reason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA50 postOp revert\");\n }\n }\n }\n }\n actualGas += preGas - gasleft();\n actualGasCost = actualGas * gasPrice;\n if (opInfo.prefund < actualGasCost) {\n revert FailedOp(opIndex, \"AA51 prefund below actualGasCost\");\n }\n uint256 refund = opInfo.prefund - actualGasCost;\n _incrementDeposit(refundAddress, refund);\n bool success = mode == IPaymaster.PostOpMode.opSucceeded;\n emit UserOperationEvent(\n opInfo.userOpHash,\n mUserOp.sender,\n mUserOp.paymaster,\n mUserOp.nonce,\n success,\n actualGasCost,\n actualGas\n );\n } // unchecked\n }\n\n /**\n * the gas price this UserOp agrees to pay.\n * relayer/block builder might submit the TX with higher priorityFee, but the user should not\n */\n function getUserOpGasPrice(\n MemoryUserOp memory mUserOp\n ) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = mUserOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = mUserOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n function getOffsetOfMemoryBytes(\n bytes memory data\n ) internal pure returns (uint256 offset) {\n assembly {\n offset := data\n }\n }\n\n function getMemoryBytesFromOffset(\n uint256 offset\n ) internal pure returns (bytes memory data) {\n assembly {\n data := offset\n }\n }\n\n //place the NUMBER opcode in the code.\n // this is used as a marker during simulation, as this OP is completely banned from the simulated code of the\n // account and paymaster.\n function numberMarker() internal view {\n assembly {\n mstore(0, number())\n }\n }\n}\n" + }, + "contracts/aa-4337/core/Helpers.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable no-inline-assembly */\n\n/**\n * returned data from validateUserOp.\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\n * @param aggregator - address(0) - the account validated the signature by itself.\n * address(1) - the account failed to validate the signature.\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\n * @param validAfter - this UserOp is valid only after this timestamp.\n * @param validaUntil - this UserOp is valid only up to this timestamp.\n */\nstruct ValidationData {\n address aggregator;\n uint48 validAfter;\n uint48 validUntil;\n}\n\n//extract sigFailed, validAfter, validUntil.\n// also convert zero validUntil to type(uint48).max\nfunction _parseValidationData(\n uint validationData\n) pure returns (ValidationData memory data) {\n address aggregator = address(uint160(validationData));\n uint48 validUntil = uint48(validationData >> 160);\n if (validUntil == 0) {\n validUntil = type(uint48).max;\n }\n uint48 validAfter = uint48(validationData >> (48 + 160));\n return ValidationData(aggregator, validAfter, validUntil);\n}\n\n// intersect account and paymaster ranges.\nfunction _intersectTimeRange(\n uint256 validationData,\n uint256 paymasterValidationData\n) pure returns (ValidationData memory) {\n ValidationData memory accountValidationData = _parseValidationData(\n validationData\n );\n ValidationData memory pmValidationData = _parseValidationData(\n paymasterValidationData\n );\n address aggregator = accountValidationData.aggregator;\n if (aggregator == address(0)) {\n aggregator = pmValidationData.aggregator;\n }\n uint48 validAfter = accountValidationData.validAfter;\n uint48 validUntil = accountValidationData.validUntil;\n uint48 pmValidAfter = pmValidationData.validAfter;\n uint48 pmValidUntil = pmValidationData.validUntil;\n\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\n return ValidationData(aggregator, validAfter, validUntil);\n}\n\n/**\n * helper to pack the return value for validateUserOp\n * @param data - the ValidationData to pack\n */\nfunction _packValidationData(\n ValidationData memory data\n) pure returns (uint256) {\n return\n uint160(data.aggregator) |\n (uint256(data.validUntil) << 160) |\n (uint256(data.validAfter) << (160 + 48));\n}\n\n/**\n * helper to pack the return value for validateUserOp, when not using an aggregator\n * @param sigFailed - true for signature failure, false for success\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\n * @param validAfter first timestamp this UserOperation is valid\n */\nfunction _packValidationData(\n bool sigFailed,\n uint48 validUntil,\n uint48 validAfter\n) pure returns (uint256) {\n return\n (sigFailed ? 1 : 0) |\n (uint256(validUntil) << 160) |\n (uint256(validAfter) << (160 + 48));\n}\n\n/**\n * keccak function over calldata.\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\n */\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\n assembly {\n let mem := mload(0x40)\n let len := data.length\n calldatacopy(mem, data.offset, len)\n ret := keccak256(mem, len)\n }\n}\n" + }, + "contracts/aa-4337/core/NonceManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\nimport \"../interfaces/IEntryPoint.sol\";\n\n/**\n * nonce management functionality\n */\ncontract NonceManager is INonceManager {\n /**\n * The next valid sequence number for a given nonce key.\n */\n mapping(address => mapping(uint192 => uint256)) public nonceSequenceNumber;\n\n function getNonce(\n address sender,\n uint192 key\n ) public view override returns (uint256 nonce) {\n return nonceSequenceNumber[sender][key] | (uint256(key) << 64);\n }\n\n // allow an account to manually increment its own nonce.\n // (mainly so that during construction nonce can be made non-zero,\n // to \"absorb\" the gas cost of first nonce increment to 1st transaction (construction),\n // not to 2nd transaction)\n function incrementNonce(uint192 key) public override {\n nonceSequenceNumber[msg.sender][key]++;\n }\n\n /**\n * validate nonce uniqueness for this account.\n * called just after validateUserOp()\n */\n function _validateAndUpdateNonce(\n address sender,\n uint256 nonce\n ) internal returns (bool) {\n uint192 key = uint192(nonce >> 64);\n uint64 seq = uint64(nonce);\n return nonceSequenceNumber[sender][key]++ == seq;\n }\n}\n" + }, + "contracts/aa-4337/core/SenderCreator.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/**\n * helper contract for EntryPoint, to call userOp.initCode from a \"neutral\" address,\n * which is explicitly not the entryPoint itself.\n */\ncontract SenderCreator {\n /**\n * call the \"initCode\" factory to create and return the sender account address\n * @param initCode the initCode value from a UserOp. contains 20 bytes of factory address, followed by calldata\n * @return sender the returned address of the created account, or zero address on failure.\n */\n function createSender(\n bytes calldata initCode\n ) external returns (address sender) {\n address factory = address(bytes20(initCode[0:20]));\n bytes memory initCallData = initCode[20:];\n bool success;\n /* solhint-disable no-inline-assembly */\n assembly {\n success := call(\n gas(),\n factory,\n 0,\n add(initCallData, 0x20),\n mload(initCallData),\n 0,\n 32\n )\n sender := mload(0)\n }\n if (!success) {\n sender = address(0);\n }\n }\n}\n" + }, + "contracts/aa-4337/core/StakeManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity 0.8.21;\n\nimport \"../interfaces/IStakeManager.sol\";\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable not-rely-on-time */\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by a paymaster.\n */\nabstract contract StakeManager is IStakeManager {\n /// maps paymaster to their deposits and stakes\n mapping(address => DepositInfo) public deposits;\n\n /// @inheritdoc IStakeManager\n function getDepositInfo(\n address account\n ) public view returns (DepositInfo memory info) {\n return deposits[account];\n }\n\n // internal method to return just the stake info\n function _getStakeInfo(\n address addr\n ) internal view returns (StakeInfo memory info) {\n DepositInfo storage depositInfo = deposits[addr];\n info.stake = depositInfo.stake;\n info.unstakeDelaySec = depositInfo.unstakeDelaySec;\n }\n\n /// return the deposit (for gas payment) of the account\n function balanceOf(address account) public view returns (uint256) {\n return deposits[account].deposit;\n }\n\n receive() external payable {\n depositTo(msg.sender);\n }\n\n function _incrementDeposit(address account, uint256 amount) internal {\n DepositInfo storage info = deposits[account];\n uint256 newAmount = info.deposit + amount;\n require(newAmount <= type(uint112).max, \"deposit overflow\");\n info.deposit = uint112(newAmount);\n }\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) public payable {\n _incrementDeposit(account, msg.value);\n DepositInfo storage info = deposits[account];\n emit Deposited(account, info.deposit);\n }\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 unstakeDelaySec) public payable {\n DepositInfo storage info = deposits[msg.sender];\n require(unstakeDelaySec > 0, \"must specify unstake delay\");\n require(\n unstakeDelaySec >= info.unstakeDelaySec,\n \"cannot decrease unstake time\"\n );\n uint256 stake = info.stake + msg.value;\n require(stake > 0, \"no stake specified\");\n require(stake <= type(uint112).max, \"stake overflow\");\n deposits[msg.sender] = DepositInfo(\n info.deposit,\n true,\n uint112(stake),\n unstakeDelaySec,\n 0\n );\n emit StakeLocked(msg.sender, stake, unstakeDelaySec);\n }\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external {\n DepositInfo storage info = deposits[msg.sender];\n require(info.unstakeDelaySec != 0, \"not staked\");\n require(info.staked, \"already unstaking\");\n uint48 withdrawTime = uint48(block.timestamp) + info.unstakeDelaySec;\n info.withdrawTime = withdrawTime;\n info.staked = false;\n emit StakeUnlocked(msg.sender, withdrawTime);\n }\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external {\n DepositInfo storage info = deposits[msg.sender];\n uint256 stake = info.stake;\n require(stake > 0, \"No stake to withdraw\");\n require(info.withdrawTime > 0, \"must call unlockStake() first\");\n require(\n info.withdrawTime <= block.timestamp,\n \"Stake withdrawal is not due\"\n );\n info.unstakeDelaySec = 0;\n info.withdrawTime = 0;\n info.stake = 0;\n emit StakeWithdrawn(msg.sender, withdrawAddress, stake);\n (bool success, ) = withdrawAddress.call{value: stake}(\"\");\n require(success, \"failed to withdraw stake\");\n }\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(\n address payable withdrawAddress,\n uint256 withdrawAmount\n ) external {\n DepositInfo storage info = deposits[msg.sender];\n require(withdrawAmount <= info.deposit, \"Withdraw amount too large\");\n info.deposit = uint112(info.deposit - withdrawAmount);\n emit Withdrawn(msg.sender, withdrawAddress, withdrawAmount);\n (bool success, ) = withdrawAddress.call{value: withdrawAmount}(\"\");\n require(success, \"failed to withdraw\");\n }\n}\n" + }, + "contracts/aa-4337/interfaces/IAccount.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\ninterface IAccount {\n /**\n * Validate user's signature and nonce\n * the entryPoint will make the call to the recipient only if this validation call returns successfully.\n * signature failure should be reported by returning SIG_VALIDATION_FAILED (1).\n * This allows making a \"simulation call\" without a valid signature\n * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure.\n *\n * @dev Must validate caller is the entryPoint.\n * Must validate the signature and nonce\n * @param userOp the operation that is about to be executed.\n * @param userOpHash hash of the user's request data. can be used as the basis for signature.\n * @param missingAccountFunds missing funds on the account's deposit in the entrypoint.\n * This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call.\n * The excess is left as a deposit in the entrypoint, for future calls.\n * can be withdrawn anytime using \"entryPoint.withdrawTo()\"\n * In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero.\n * @return validationData packaged ValidationData structure. use `_packValidationData` and `_unpackValidationData` to encode and decode\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * If an account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validateUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 missingAccountFunds\n ) external returns (uint256 validationData);\n}\n" + }, + "contracts/aa-4337/interfaces/IAggregator.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * Aggregated Signatures validator.\n */\ninterface IAggregator {\n /**\n * validate aggregated signature.\n * revert if the aggregated signature does not match the given list of operations.\n */\n function validateSignatures(\n UserOperation[] calldata userOps,\n bytes calldata signature\n ) external view;\n\n /**\n * validate signature of a single userOp\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\n * @param userOp the userOperation received from the user.\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\n * (usually empty, unless account and aggregator support some kind of \"multisig\"\n */\n function validateUserOpSignature(\n UserOperation calldata userOp\n ) external view returns (bytes memory sigForUserOp);\n\n /**\n * aggregate multiple signatures into a single value.\n * This method is called off-chain to calculate the signature to pass with handleOps()\n * bundler MAY use optimized custom code perform this aggregation\n * @param userOps array of UserOperations to collect the signatures from.\n * @return aggregatedSignature the aggregated signature\n */\n function aggregateSignatures(\n UserOperation[] calldata userOps\n ) external view returns (bytes memory aggregatedSignature);\n}\n" + }, + "contracts/aa-4337/interfaces/IEntryPoint.sol": { + "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n/* solhint-disable reason-string */\n\nimport \"./UserOperation.sol\";\nimport \"./IStakeManager.sol\";\nimport \"./IAggregator.sol\";\nimport \"./INonceManager.sol\";\n\ninterface IEntryPoint is IStakeManager, INonceManager {\n /***\n * An event emitted after each successful request\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\n * @param sender - the account that generates this request.\n * @param paymaster - if non-null, the paymaster that pays for this request.\n * @param nonce - the nonce value from the request.\n * @param success - true if the sender transaction succeeded, false if reverted.\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\n */\n event UserOperationEvent(\n bytes32 indexed userOpHash,\n address indexed sender,\n address indexed paymaster,\n uint256 nonce,\n bool success,\n uint256 actualGasCost,\n uint256 actualGasUsed\n );\n\n /**\n * account \"sender\" was deployed.\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\n * @param sender the account that is deployed\n * @param factory the factory used to deploy this account (in the initCode)\n * @param paymaster the paymaster used by this UserOp\n */\n event AccountDeployed(\n bytes32 indexed userOpHash,\n address indexed sender,\n address factory,\n address paymaster\n );\n\n /**\n * An event emitted if the UserOperation \"callData\" reverted with non-zero length\n * @param userOpHash the request unique identifier.\n * @param sender the sender of this request\n * @param nonce the nonce used in the request\n * @param revertReason - the return bytes from the (reverted) call to \"callData\".\n */\n event UserOperationRevertReason(\n bytes32 indexed userOpHash,\n address indexed sender,\n uint256 nonce,\n bytes revertReason\n );\n\n /**\n * an event emitted by handleOps(), before starting the execution loop.\n * any event emitted before this event, is part of the validation.\n */\n event BeforeExecution();\n\n /**\n * signature aggregator used by the following UserOperationEvents within this bundle.\n */\n event SignatureAggregatorChanged(address indexed aggregator);\n\n /**\n * a custom revert error of handleOps, to identify the offending op.\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\n * @param reason - revert reason\n * The string starts with a unique code \"AAmn\", where \"m\" is \"1\" for factory, \"2\" for account and \"3\" for paymaster issues,\n * so a failure can be attributed to the correct entity.\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\n */\n error FailedOp(uint256 opIndex, string reason);\n\n /**\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\n */\n error SignatureValidationFailed(address aggregator);\n\n /**\n * Successful result from simulateValidation.\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n */\n error ValidationResult(\n ReturnInfo returnInfo,\n StakeInfo senderInfo,\n StakeInfo factoryInfo,\n StakeInfo paymasterInfo\n );\n\n /**\n * Successful result from simulateValidation, if the account returns a signature aggregator\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\n * bundler MUST use it to verify the signature, or reject the UserOperation\n */\n error ValidationResultWithAggregation(\n ReturnInfo returnInfo,\n StakeInfo senderInfo,\n StakeInfo factoryInfo,\n StakeInfo paymasterInfo,\n AggregatorStakeInfo aggregatorInfo\n );\n\n /**\n * return value of getSenderAddress\n */\n error SenderAddressResult(address sender);\n\n /**\n * return value of simulateHandleOp\n */\n error ExecutionResult(\n uint256 preOpGas,\n uint256 paid,\n uint48 validAfter,\n uint48 validUntil,\n bool targetSuccess,\n bytes targetResult\n );\n\n //UserOps handled, per aggregator\n struct UserOpsPerAggregator {\n UserOperation[] userOps;\n // aggregator address\n IAggregator aggregator;\n // aggregated signature\n bytes signature;\n }\n\n /**\n * Execute a batch of UserOperation.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(\n UserOperation[] calldata ops,\n address payable beneficiary\n ) external;\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) external;\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(\n UserOperation calldata userOp\n ) external view returns (bytes32);\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external;\n\n /**\n * gas and return values during simulation\n * @param preOpGas the gas used for validation (including preValidationGas)\n * @param prefund the required prefund for this operation\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\n */\n struct ReturnInfo {\n uint256 preOpGas;\n uint256 prefund;\n bool sigFailed;\n uint48 validAfter;\n uint48 validUntil;\n bytes paymasterContext;\n }\n\n /**\n * returned aggregated signature info.\n * the aggregator returned by the account, and its current stake.\n */\n struct AggregatorStakeInfo {\n address aggregator;\n StakeInfo stakeInfo;\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes memory initCode) external;\n\n /**\n * simulate full execution of a UserOperation (including both validation and target execution)\n * this method will always revert with \"ExecutionResult\".\n * it performs full validation of the UserOperation, but ignores signature error.\n * an optional target address is called after the userop succeeds, and its value is returned\n * (before the entire call is reverted)\n * Note that in order to collect the the success/failure of the target call, it must be executed\n * with trace enabled to track the emitted events.\n * @param op the UserOperation to simulate\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\n * are set to the return from that call.\n * @param targetCallData callData to pass to target address\n */\n function simulateHandleOp(\n UserOperation calldata op,\n address target,\n bytes calldata targetCallData\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/INonceManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\ninterface INonceManager {\n /**\n * Return the next nonce for this sender.\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\n * But UserOp with different keys can come with arbitrary order.\n *\n * @param sender the account address\n * @param key the high 192 bit of the nonce\n * @return nonce a full nonce to pass for next UserOp with this sender.\n */\n function getNonce(\n address sender,\n uint192 key\n ) external view returns (uint256 nonce);\n\n /**\n * Manually increment the nonce of the sender.\n * This method is exposed just for completeness..\n * Account does NOT need to call it, neither during validation, nor elsewhere,\n * as the EntryPoint will update the nonce regardless.\n * Possible use-case is call it with various keys to \"initialize\" their nonces to one, so that future\n * UserOperations will not pay extra for the first transaction with a given key.\n */\n function incrementNonce(uint192 key) external;\n}\n" + }, + "contracts/aa-4337/interfaces/IPaymaster.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * the interface exposed by a paymaster contract, who agrees to pay the gas for user's operations.\n * a paymaster must hold a stake to cover the required entrypoint stake and also the gas for the transaction.\n */\ninterface IPaymaster {\n enum PostOpMode {\n opSucceeded, // user op succeeded\n opReverted, // user op reverted. still has to pay for gas.\n postOpReverted //user op succeeded, but caused postOp to revert. Now it's a 2nd call, after user's op was deliberately reverted.\n }\n\n /**\n * payment validation: check if paymaster agrees to pay.\n * Must verify sender is the entryPoint.\n * Revert to reject this request.\n * Note that bundlers will reject this method if it changes the state, unless the paymaster is trusted (whitelisted)\n * The paymaster pre-pays using its deposit, and receive back a refund after the postOp method returns.\n * @param userOp the user operation\n * @param userOpHash hash of the user's request data.\n * @param maxCost the maximum cost of this transaction (based on maximum gas and gas price from userOp)\n * @return context value to send to a postOp\n * zero length to signify postOp is not required.\n * @return validationData signature and time-range of this operation, encoded the same as the return value of validateUserOperation\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validatePaymasterUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 maxCost\n ) external returns (bytes memory context, uint256 validationData);\n\n /**\n * post-operation handler.\n * Must verify sender is the entryPoint\n * @param mode enum with the following options:\n * opSucceeded - user operation succeeded.\n * opReverted - user op reverted. still has to pay for gas.\n * postOpReverted - user op succeeded, but caused postOp (in mode=opSucceeded) to revert.\n * Now this is the 2nd call, after user's op was deliberately reverted.\n * @param context - the context value returned by validatePaymasterUserOp\n * @param actualGasCost - actual gas used so far (without this postOp call).\n */\n function postOp(\n PostOpMode mode,\n bytes calldata context,\n uint256 actualGasCost\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/IStakeManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.12;\n\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by the staked entity.\n */\ninterface IStakeManager {\n event Deposited(address indexed account, uint256 totalDeposit);\n\n event Withdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /// Emitted when stake or unstake delay are modified\n event StakeLocked(\n address indexed account,\n uint256 totalStaked,\n uint256 unstakeDelaySec\n );\n\n /// Emitted once a stake is scheduled for withdrawal\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\n\n event StakeWithdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /**\n * @param deposit the entity's deposit\n * @param staked true if this entity is staked.\n * @param stake actual amount of ether staked for this entity.\n * @param unstakeDelaySec minimum delay to withdraw the stake.\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\n * and the rest fit into a 2nd cell.\n * 112 bit allows for 10^15 eth\n * 48 bit for full timestamp\n * 32 bit allows 150 years for unstake delay\n */\n struct DepositInfo {\n uint112 deposit;\n bool staked;\n uint112 stake;\n uint32 unstakeDelaySec;\n uint48 withdrawTime;\n }\n\n //API struct used by getStakeInfo and simulateValidation\n struct StakeInfo {\n uint256 stake;\n uint256 unstakeDelaySec;\n }\n\n /// @return info - full deposit information of given account\n function getDepositInfo(\n address account\n ) external view returns (DepositInfo memory info);\n\n /// @return the deposit (for gas payment) of the account\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) external payable;\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 _unstakeDelaySec) external payable;\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external;\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external;\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(\n address payable withdrawAddress,\n uint256 withdrawAmount\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/UserOperation.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable no-inline-assembly */\n\nimport {calldataKeccak} from \"../core/Helpers.sol\";\n\n/**\n * User Operation struct\n * @param sender the sender account of this request.\n * @param nonce unique value the sender uses to verify it is not a replay.\n * @param initCode if set, the account contract will be created by this constructor/\n * @param callData the method call to execute on this account.\n * @param callGasLimit the gas limit passed to the callData method call.\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\n * @param maxFeePerGas same as EIP-1559 gas parameter.\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\n */\nstruct UserOperation {\n address sender;\n uint256 nonce;\n bytes initCode;\n bytes callData;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n bytes paymasterAndData;\n bytes signature;\n}\n\n/**\n * Utility functions helpful when working with UserOperation structs.\n */\nlibrary UserOperationLib {\n function getSender(\n UserOperation calldata userOp\n ) internal pure returns (address) {\n address data;\n //read sender from userOp, which is first userOp member (saves 800 gas...)\n assembly {\n data := calldataload(userOp)\n }\n return address(uint160(data));\n }\n\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\n // pay above what he signed for.\n function gasPrice(\n UserOperation calldata userOp\n ) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function pack(\n UserOperation calldata userOp\n ) internal pure returns (bytes memory ret) {\n address sender = getSender(userOp);\n uint256 nonce = userOp.nonce;\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\n bytes32 hashCallData = calldataKeccak(userOp.callData);\n uint256 callGasLimit = userOp.callGasLimit;\n uint256 verificationGasLimit = userOp.verificationGasLimit;\n uint256 preVerificationGas = userOp.preVerificationGas;\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\n\n return\n abi.encode(\n sender,\n nonce,\n hashInitCode,\n hashCallData,\n callGasLimit,\n verificationGasLimit,\n preVerificationGas,\n maxFeePerGas,\n maxPriorityFeePerGas,\n hashPaymasterAndData\n );\n }\n\n function hash(\n UserOperation calldata userOp\n ) internal pure returns (bytes32) {\n return keccak256(pack(userOp));\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n}\n" + }, + "contracts/aa-4337/utils/Exec.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.5 <0.9.0;\n\n// solhint-disable no-inline-assembly\n\n/**\n * Utility functions helpful when making different kinds of contract calls in Solidity.\n */\nlibrary Exec {\n function call(\n address to,\n uint256 value,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := call(\n txGas,\n to,\n value,\n add(data, 0x20),\n mload(data),\n 0,\n 0\n )\n }\n }\n\n function staticcall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal view returns (bool success) {\n assembly {\n success := staticcall(txGas, to, add(data, 0x20), mload(data), 0, 0)\n }\n }\n\n function delegateCall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := delegatecall(\n txGas,\n to,\n add(data, 0x20),\n mload(data),\n 0,\n 0\n )\n }\n }\n\n // get returned data from last call or calldelegate\n function getReturnData(\n uint256 maxLen\n ) internal pure returns (bytes memory returnData) {\n assembly {\n let len := returndatasize()\n if gt(len, maxLen) {\n len := maxLen\n }\n let ptr := mload(0x40)\n mstore(0x40, add(ptr, add(len, 0x20)))\n mstore(ptr, len)\n returndatacopy(add(ptr, 0x20), 0, len)\n returnData := ptr\n }\n }\n\n // revert with explicit byte array (probably reverted info from call)\n function revertWithData(bytes memory returnData) internal pure {\n assembly {\n revert(add(returnData, 32), mload(returnData))\n }\n }\n\n function callAndRevert(\n address to,\n bytes memory data,\n uint256 maxLen\n ) internal {\n bool success = call(to, 0, data, gasleft());\n if (!success) {\n revertWithData(getReturnData(maxLen));\n }\n }\n}\n" + }, + "contracts/Barz.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"./libraries/LibDiamond.sol\";\nimport {IBarz} from \"./interfaces/IBarz.sol\";\n\n/**\n * @title Barz\n * @dev A diamond proxy wallet with a modular & upgradeable architecture\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract Barz is IBarz {\n /**\n * @notice Initializes Barz with the given parameters. Barz account is intended to be created from Barz Factory for stable deployment.\n * @dev This method makes a delegate call to account facet and account facet handles the initialization.\n * With modular architecture, Barz encompasses wide spectrum of architecture and logic.\n * The only requirement is account facet to comply with initialize() interface.\n * Barz doesn't include built-in functions and is a full proxy, for maximum extensibility and modularity.\n * @param _accountFacet Address of Account Facet in charge of the Barz initialization\n * @param _verificationFacet Address of Verification Facet for verifying the signature. Could be any signature scheme\n * @param _entryPoint Address of Entry Point contract\n * @param _facetRegistry Address of Facet Registry. Facet Registry is a registry holding trusted facets that could be added to user's wallet\n * @param _defaultFallBack Address of Default FallBack Handler. Middleware contract for more efficient deployment\n * @param _ownerPublicKey Bytes of Owner Public Key using for initialization\n */\n constructor(\n address _accountFacet,\n address _verificationFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallBack,\n bytes memory _ownerPublicKey\n ) payable {\n bytes memory initCall = abi.encodeWithSignature(\n \"initialize(address,address,address,address,bytes)\",\n _verificationFacet,\n _entryPoint,\n _facetRegistry,\n _defaultFallBack,\n _ownerPublicKey\n );\n (bool success, bytes memory result) = _accountFacet.delegatecall(\n initCall\n );\n if (!success || uint256(bytes32(result)) != 1) {\n revert Barz__InitializationFailure();\n }\n }\n\n /**\n * @notice Fallback function for Barz complying with Diamond Standard with customization of adding Default Fallback Handler\n * @dev Find facet for function that is called and execute the function if a facet is found and return any value.\n */\n fallback() external payable {\n LibDiamond.DiamondStorage storage ds;\n bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION;\n // get diamond storage\n assembly {\n ds.slot := position\n }\n // get facet from function selector\n address facet = address(bytes20(ds.facets[msg.sig]));\n if (facet == address(0))\n facet = ds.defaultFallbackHandler.facetAddress(msg.sig);\n require(facet != address(0), \"Barz: Function does not exist\");\n // Execute external function from facet using delegatecall and return any value.\n assembly {\n // copy function selector and any arguments\n calldatacopy(0, 0, calldatasize())\n // execute function call using the facet\n let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)\n // get any return value\n returndatacopy(0, 0, returndatasize())\n // return any return value or error back to the caller\n switch result\n case 0 {\n revert(0, returndatasize())\n }\n default {\n return(0, returndatasize())\n }\n }\n }\n\n /**\n * @notice Receive function to receive native token without data\n */\n receive() external payable {}\n}\n" + }, + "contracts/BarzFactory.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Barz} from \"./Barz.sol\";\nimport {IBarzFactory} from \"./interfaces/IBarzFactory.sol\";\n\n/**\n * @title Barz Factory\n * @dev Contract to easily deploy Barz to a pre-computed address with a single call\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract BarzFactory is IBarzFactory {\n event BarzDeployed(address);\n\n address public immutable accountFacet;\n address public immutable entryPoint;\n address public immutable facetRegistry;\n address public immutable defaultFallback;\n\n /**\n * @notice Sets the initialization data for Barz contract initialization\n * @param _accountFacet Account Facet to be used to create Barz\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\n * @param _facetRegistry Facet Registry to be used to create Barz\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\n */\n constructor(\n address _accountFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallback\n ) {\n accountFacet = _accountFacet;\n entryPoint = _entryPoint;\n facetRegistry = _facetRegistry;\n defaultFallback = _defaultFallback;\n }\n\n /**\n * @notice Creates the Barz with a single call. It creates the Barz contract with the givent verification facet\n * @param _verificationFacet Address of verification facet used for creating the barz account\n * @param _owner Public Key of the owner to initialize barz account\n * @param _salt Salt used for deploying barz with create2\n * @return barz Instance of Barz contract deployed with the given parameters\n */\n function createAccount(\n address _verificationFacet,\n bytes calldata _owner,\n uint256 _salt\n ) external override returns (Barz barz) {\n address addr = getAddress(_verificationFacet, _owner, _salt);\n uint codeSize = addr.code.length;\n if (codeSize > 0) {\n return Barz(payable(addr));\n }\n barz = new Barz{salt: bytes32(_salt)}(\n accountFacet,\n _verificationFacet,\n entryPoint,\n facetRegistry,\n defaultFallback,\n _owner\n );\n emit BarzDeployed(address(barz));\n }\n\n /**\n * @notice Calculates the address of Barz with the given parameters\n * @param _verificationFacet Address of verification facet used for creating the barz account\n * @param _owner Public Key of the owner to initialize barz account\n * @param _salt Salt used for deploying barz with create2\n * @return barzAddress Precalculated Barz address\n */\n function getAddress(\n address _verificationFacet,\n bytes calldata _owner,\n uint256 _salt\n ) public view override returns (address barzAddress) {\n bytes memory bytecode = getBytecode(\n accountFacet,\n _verificationFacet,\n entryPoint,\n facetRegistry,\n defaultFallback,\n _owner\n );\n bytes32 hash = keccak256(\n abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(bytecode)\n )\n );\n barzAddress = address(uint160(uint256(hash)));\n }\n\n /**\n * @notice Returns the bytecode of Barz with the given parameter\n * @param _accountFacet Account Facet to be used to create Barz\n * @param _verificationFacet Verification Facet to be used to create Barz\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\n * @param _facetRegistry Facet Registry to be used to create Barz\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\n * @param _ownerPublicKey Public Key of owner to be used to initialize Barz ownership\n * @return barzBytecode Bytecode of Barz\n */\n function getBytecode(\n address _accountFacet,\n address _verificationFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallback,\n bytes calldata _ownerPublicKey\n ) public pure override returns (bytes memory barzBytecode) {\n bytes memory bytecode = type(Barz).creationCode;\n barzBytecode = abi.encodePacked(\n bytecode,\n abi.encode(\n _accountFacet,\n _verificationFacet,\n _entryPoint,\n _facetRegistry,\n _defaultFallback,\n _ownerPublicKey\n )\n );\n }\n\n /**\n * @notice Returns the creation code of the Barz contract\n * @return creationCode Creation code of Barz\n */\n function getCreationCode()\n public\n pure\n override\n returns (bytes memory creationCode)\n {\n creationCode = type(Barz).creationCode;\n }\n}\n" + }, + "contracts/facets/AccountFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {UserOperation} from \"../aa-4337/interfaces/UserOperation.sol\";\nimport {IEntryPoint} from \"../aa-4337/interfaces/IEntryPoint.sol\";\nimport {BaseAccount} from \"../aa-4337/core/BaseAccount.sol\";\nimport {LibAppStorage, BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {IFacetRegistry} from \"../infrastructure/interfaces/IFacetRegistry.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {IERC1271} from \"../interfaces/ERC/IERC1271.sol\";\nimport {IAccountFacet} from \"./interfaces/IAccountFacet.sol\";\n\n/**\n * @title Account Facet\n * @dev Account module contract that provides the account features and initialization of signer\n * compatible with EIP-1271 & EIP-4337\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract AccountFacet is BarzStorage, BaseAccount, IAccountFacet {\n using ECDSA for bytes32;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceAccountInitialize();\n }\n\n /**\n * @notice Returns the address of EntryPoint contract registered to Barz account\n */\n function entryPoint() public view override returns (IEntryPoint) {\n return s.entryPoint;\n }\n\n /**\n * @notice Initializes the initial storage of the Barz contract.\n * @dev This method can only be called during the initialization or signature migration.\n * If the proxy contract was created without initialization, anyone can call initialize.\n * Barz calls initialize in constructor in an atomic transaction during deployment\n * @param _verificationFacet Facet contract handling the verificationi\n * @param _anEntryPoint Entrypoint contract defined in EIP-4337 handling the flow of UserOp\n * @param _facetRegistry Registry of Facets that hold all facet information\n * @param _defaultFallBackHandler Middleware contract for default facets\n * @param _ownerPublicKey Bytes of owner public key\n */\n function initialize(\n address _verificationFacet,\n address _anEntryPoint,\n address _facetRegistry,\n address _defaultFallBackHandler,\n bytes calldata _ownerPublicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceAccountInitialize();\n s.entryPoint = IEntryPoint(_anEntryPoint);\n s.facetRegistry = IFacetRegistry(_facetRegistry);\n LibDiamond.diamondStorage().defaultFallbackHandler = IDiamondLoupe(\n _defaultFallBackHandler\n );\n\n _cutDiamondAccountFacet(_verificationFacet);\n\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n _ownerPublicKey\n );\n // Every Verification Facet should comply with initializeSigner(bytes)\n // to be compatible with the Barz contract(for initialization)\n (bool success, bytes memory result) = _verificationFacet.delegatecall(\n initCall\n );\n if (!success || uint256(bytes32(result)) != 1) {\n revert AccountFacet__InitializationFailure();\n }\n\n initSuccess = 1;\n emit AccountInitialized(s.entryPoint, _ownerPublicKey);\n }\n\n function _cutDiamondAccountFacet(address _verificationFacet) internal {\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](1);\n\n bytes4 ownerVerificationFuncSelector = IVerificationFacet(\n _verificationFacet\n ).validateOwnerSignatureSelector();\n\n bytes4[] memory verificationFunctionSelectors = new bytes4[](3);\n verificationFunctionSelectors[0] = IERC1271.isValidSignature.selector;\n verificationFunctionSelectors[1] = ownerVerificationFuncSelector;\n verificationFunctionSelectors[2] = IVerificationFacet.owner.selector;\n cut[0] = IDiamondCut.FacetCut({\n facetAddress: _verificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: verificationFunctionSelectors\n });\n\n LibDiamond.diamondCut(cut, address(0), \"\");\n }\n\n /**\n * @notice Calls the destination with inputted calldata and value from EntryPoint\n * @dev This method executes the calldata coming from the EntryPoint.\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\n * @param _dest Address of destination where the call will be forwarded to\n * @param _value Amount of native coin the owner is willing to send(e.g. ETH, BNB)\n * @param _func Bytes of calldata to execute in the destination address\n */\n function execute(\n address _dest,\n uint256 _value,\n bytes calldata _func\n ) external override onlyWhenUnlocked {\n _requireFromEntryPoint();\n _call(_dest, _value, _func);\n }\n\n /**\n * @notice Batch calls the destination with inputted calldata and value from EntryPoint\n * @dev This method batch executes the calldata coming from the EntryPoint.\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\n * @param _dest Array of addresses of destination where the call will be forwarded to\n * @param _value Array of amount of native coin the owner is willing to send(e.g. ETH, BNB)\n * @param _func Array of bytes of calldata to execute in the destination address\n */\n function executeBatch(\n address[] calldata _dest,\n uint256[] calldata _value,\n bytes[] calldata _func\n ) external override onlyWhenUnlocked {\n _requireFromEntryPoint();\n require(\n _dest.length == _func.length && _dest.length == _value.length,\n \"wrong array lengths\"\n );\n for (uint256 i; i < _dest.length; ) {\n _call(_dest[i], _value[i], _func[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Validates the signature field of UserOperation\n * @dev This method validates if the signature of UserOp is indeed valid by delegating the call to Verification Facet\n * Barz makes a call to the pre-registered Verification Facet address in App Storage\n * @param _userOp UserOperation from owner to be validated\n * @param _userOpHash Hash of UserOperation given from the EntryPoint contract\n */\n function _validateSignature(\n UserOperation calldata _userOp,\n bytes32 _userOpHash\n ) internal override returns (uint256 validationData) {\n // Get Facet with Function Selector\n address facet = LibLoupe.facetAddress(s.validateOwnerSignatureSelector);\n if (facet == address(0))\n revert AccountFacet__NonExistentVerificationFacet();\n\n // Make function call to VerificationFacet\n bytes memory validateCall = abi.encodeWithSelector(\n s.validateOwnerSignatureSelector,\n _userOp,\n _userOpHash\n );\n (bool success, bytes memory result) = facet.delegatecall(validateCall);\n if (!success) revert AccountFacet__CallNotSuccessful();\n validationData = uint256(bytes32(result));\n if (validationData == 0) emit VerificationSuccess(_userOpHash);\n else emit VerificationFailure(_userOpHash);\n }\n\n /**\n * @notice Calls the target with the inputted value and calldata\n * @dev This method is the actual function in Barz that makes a call with an arbitrary owner-given data\n * @param _target Address of the destination contract which the call is getting forwarded to\n * @param _value Amount of Native coin the owner is wanting to make in this call\n * @param _data Calldata the owner is forwarding together in the call e.g. Swap/Token Transfer\n */\n function _call(\n address _target,\n uint256 _value,\n bytes memory _data\n ) internal {\n address facet = LibDiamond.restrictionsFacet();\n // NOTE: No restrictions facet, so restriction validation passes\n if (facet != address(0)) {\n if (_checkRestrictions(facet, _target, _value, _data) == 1)\n revert AccountFacet__RestrictionsFailure();\n }\n\n (bool success, bytes memory result) = _target.call{value: _value}(\n _data\n );\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n }\n\n /**\n * @notice Checks restrictions if the restrictions facet exists\n * @dev This method checks if the restrictions facet exists and makes a verification call to an array of restrictions facet\n * @param _facet Address that holds the restrictions logic\n * @param _target Address the call is getting forwarded to\n * @param _value Amount of native coin the call is sending together with the call\n * @param _data Calldata to trigger execution in target address\n */\n function _checkRestrictions(\n address _facet,\n address _target,\n uint256 _value,\n bytes memory _data\n ) internal returns (uint256 result) {\n bytes memory call = abi.encodeWithSignature(\n \"verifyRestrictions(address,address,uint256,bytes)\",\n address(this),\n _target,\n _value,\n _data\n );\n (bool success, bytes memory response) = _facet.delegatecall(call);\n if (!success) revert AccountFacet__RestrictionsFailure();\n result = uint256(bytes32(response));\n }\n}\n" + }, + "contracts/facets/AccountRecoveryFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibFacetStorage, RecoveryStorage, RecoveryConfig, RecoveryApprovalConfig, ApprovalConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {IAccountRecoveryFacet} from \"./interfaces/IAccountRecoveryFacet.sol\";\n\n/**\n * @title Account Recovery Facet\n * @dev Contract that enables recovery of accounts when owner key is unavailable\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract AccountRecoveryFacet is IAccountRecoveryFacet, Modifiers {\n bytes constant UNINIT_CALL =\n abi.encodeWithSignature(\"uninitializeSigner()\");\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Approve recovery of account as guardian\n * @dev This method can only be called by guardian and guardian inputs the public key of the new owner\n * When the threshold(majority of guardians) passes, it automatically executes account recovery\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function approveAccountRecovery(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + _getApprovalValidationPeriod()\n );\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit RecoveryApproved(\n _recoveryPublicKey,\n msg.sender,\n approvalValidUntil\n );\n if (\n getRecoveryApprovalCountWithTimeValidity(recoveryPublicKeyHash) >=\n LibGuardian.majorityOfGuardians()\n ) _executeRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Revoke recovery of account as guardian\n * @dev This method can only be called by guardian and guardian inputs the public key of the new owner\n When the threshold(majority of guardians) passes, it automatically revokes account recovery when recovery is pending\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function revokeAccountRecoveryApproval(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n if (\n !rs\n .isNewOwnerApproved[recoveryPublicKeyHash][msg.sender].isApproved ||\n !(block.timestamp <\n rs\n .isNewOwnerApproved[recoveryPublicKeyHash][msg.sender]\n .validUntil)\n ) revert AccountRecoveryFacet__NonExistentApproval();\n\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(false, 0);\n emit RecoveryApprovalRevoked(_recoveryPublicKey, msg.sender);\n }\n\n /**\n * @notice Executes recovery with signatures or on-chain pre-approvals\n * @dev This method validates the signatures of guardians or checks the on-chain pre-approved calls to check if the threshold passes\n * When the threshold passes, account recovery is executed and revert otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _guardians Array of guardians address that are approving the recovery of Account\n * @param _signatures Array of signature bytes that signed the approval hash\n */\n function executeRecovery(\n bytes calldata _recoveryPublicKey,\n address[] calldata _guardians,\n bytes[] calldata _signatures\n ) external override {\n if (_isRecoveryPending())\n revert AccountRecoveryFacet__RecoveryAlreadyOngoing();\n if (_guardians.length != _signatures.length)\n revert AccountRecoveryFacet__InvalidArrayLength();\n validateNewOwner(_recoveryPublicKey);\n\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n\n _checkApprover(_guardians);\n _checkDuplicateOnChainApprover(recoveryPublicKeyHash, _guardians);\n\n if (\n _guardians.length +\n getRecoveryApprovalCountWithTimeValidity(\n recoveryPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians()\n ) revert AccountRecoveryFacet__InsufficientGuardians();\n for (uint256 i; i < _guardians.length; ) {\n if (!LibGuardian.isGuardian(_guardians[i]))\n revert AccountRecoveryFacet__InvalidGuardian();\n if (\n !SignatureChecker.isValidSignatureNow(\n _guardians[i],\n recoveryPublicKeyHash,\n _signatures[i]\n )\n ) revert AccountRecoveryFacet__InvalidGuardianSignature();\n unchecked {\n ++i;\n }\n }\n _executeRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Executes recovery of the account. Note that execution and finalization is a different process\n * @dev Executes the recovery and adds recovery data to recovery configuration. Locks the account\n * @param _recoveryPublicKey Public Key of the account for recovery\n */\n function _executeRecovery(bytes memory _recoveryPublicKey) internal {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n ++rs.nonce;\n uint64 executeAfter = uint64(block.timestamp + _getRecoveryPeriod());\n rs.recoveryConfigs[INNER_STRUCT] = RecoveryConfig(\n _recoveryPublicKey,\n executeAfter // NOTE: Remove guardian Count\n );\n LibAppStorage.setLock(\n block.timestamp + _getLockPeriod(),\n AccountRecoveryFacet.executeRecovery.selector\n );\n emit RecoveryExecuted(_recoveryPublicKey, executeAfter);\n }\n\n /**\n * @notice Finalize recovery after recovery pending period. Recovery pending period can be set by user beforehand in SecurityManager\n * @dev This method finalizes recovery and fully changes the ownership of the account to the newly inputted recovery public key\n */\n function finalizeRecovery() external override {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n if (\n uint64(block.timestamp) <=\n rs.recoveryConfigs[INNER_STRUCT].executeAfter\n ) revert AccountRecoveryFacet__RecoveryPeriodNotOver();\n bytes memory recoveryOwner = rs\n .recoveryConfigs[INNER_STRUCT]\n .recoveryPublicKey;\n\n delete rs.recoveryConfigs[INNER_STRUCT];\n\n LibAppStorage.setLock(0, bytes4(0));\n\n LibAppStorage.initiateSignerMigration();\n address verificationFacet = address(\n bytes20(\n LibDiamond.diamondStorage().facets[\n s.validateOwnerSignatureSelector\n ]\n )\n );\n (bool success, bytes memory result) = verificationFacet.delegatecall(\n UNINIT_CALL\n );\n if (!success) revert AccountRecoveryFacet__CallNotSuccesful();\n uint256 validationData = uint256(bytes32(result));\n if (validationData != 1)\n revert AccountRecoveryFacet__SignerUninitializationFailure();\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n recoveryOwner\n );\n (success, result) = verificationFacet.delegatecall(initCall);\n if (!success) revert AccountRecoveryFacet__CallNotSuccesful();\n validationData = uint256(bytes32(result));\n if (validationData != 1)\n revert AccountRecoveryFacet__SignerInitializationFailure();\n LibAppStorage.finalizeSignerMigration();\n emit RecoveryFinalized(recoveryOwner);\n }\n\n /**\n * @notice Approves the cancellation of recovery\n * @dev This method approves the cancellation of recovery when recovery is still pending - waiting for finalization\n * @param _recoveryPublicKey Bytes of public key which is pending for recovery\n */\n function approveCancelRecovery(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"CancelRecovery\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + _getApprovalValidationPeriod()\n );\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit RecoveryCancellationApproved(_recoveryPublicKey, msg.sender);\n if (\n getRecoveryApprovalCountWithTimeValidity(recoveryPublicKeyHash) >=\n LibGuardian.majorityOfGuardians()\n ) {\n _cancelRecovery(_recoveryPublicKey);\n }\n }\n\n /**\n * @notice Hardstops an ongoing recovery\n * @dev This method provides a safety mechanism to protect owners of malicious guardians.\n * Owners can hardstop recovery when an malicious guardians starts the recovery process.\n * @param _signature Signature of the owner that signs the hash to hardstop recovery\n */\n function hardstopRecovery(bytes calldata _signature) external override {\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n \"0\",\n \"HardstopRecovery\"\n );\n if (\n !SignatureChecker.isValidSignatureNow(\n address(this),\n recoveryPublicKeyHash,\n _signature\n )\n ) revert AccountRecoveryFacet__InvalidOwnerSignature();\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n ++rs.nonce;\n delete rs.recoveryConfigs[INNER_STRUCT];\n LibAppStorage.setLock(0, bytes4(0));\n emit RecoveryHardstopped();\n }\n\n /**\n * @notice Cancels recovery with signatures or on-chain pre-approvals\n * @dev This method validates the signatures of guardians or checks the on-chain pre-approved calls to check if the threshold passes\n * When the threshold passes, account recovery is canceled and revert otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _guardians Array of guardians address that are approving the recovery of Account\n * @param _signatures Array of signature bytes that signed the cancellation approval hash\n */\n function cancelRecovery(\n bytes calldata _recoveryPublicKey,\n address[] calldata _guardians,\n bytes[] calldata _signatures\n ) external override {\n if (_guardians.length != _signatures.length)\n revert AccountRecoveryFacet__InvalidArrayLength();\n validateNewOwner(_recoveryPublicKey);\n\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"CancelRecovery\"\n );\n\n _checkApprover(_guardians);\n _checkDuplicateOnChainApprover(recoveryPublicKeyHash, _guardians);\n\n if (\n _guardians.length +\n getRecoveryApprovalCountWithTimeValidity(\n recoveryPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians()\n ) revert AccountRecoveryFacet__InsufficientGuardians();\n for (uint256 i; i < _guardians.length; ) {\n if (!LibGuardian.isGuardian(_guardians[i]))\n revert AccountRecoveryFacet__CallerNotGuardian();\n if (\n !SignatureChecker.isValidSignatureNow(\n _guardians[i],\n recoveryPublicKeyHash,\n _signatures[i]\n )\n ) revert AccountRecoveryFacet__InvalidGuardianSignature();\n unchecked {\n ++i;\n }\n }\n _cancelRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Cancel recovery when the recovery is pending. Unlock the account as well\n * @dev This method checks if the recovery is pending and reverts if not pending.\n * It increases the recovery nonce and deletes the recovery information and gets a small portion of gas in return\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function _cancelRecovery(bytes memory _recoveryPublicKey) internal {\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n LibAppStorage.setLock(0, bytes4(0));\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n ++rs.nonce;\n delete rs.recoveryConfigs[INNER_STRUCT];\n emit RecoveryCanceled(_recoveryPublicKey);\n }\n\n /**\n * @notice Validates the format of public key to be used for recovery\n * @dev This method checks if the public key format is correct and reverts otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function validateNewOwner(bytes memory _recoveryPublicKey) public view {\n if (\n !IVerificationFacet(\n LibLoupe.facetAddress(s.validateOwnerSignatureSelector)\n ).isValidKeyType(_recoveryPublicKey)\n ) revert AccountRecoveryFacet__InvalidRecoveryPublicKey();\n }\n\n /**\n * @notice Checks if recovery is currently pending\n * @return isPending Boolean indicating if recovery is pending\n */\n function _isRecoveryPending() internal view returns (bool isPending) {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n isPending = (rs.recoveryConfigs[INNER_STRUCT].executeAfter > 0);\n }\n\n /**\n * @notice Calculate the recovery hash dependent on chain, wallet address, nonce with EIP-191 prefix for safety\n * @dev Returns the keccak256 hash of EIP-191 msg hash packed with public key, salt, nonce, wallet address, etc\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _saltString Salt string to uniquely identify each recovery hash and for security\n * @return recoveryKeyHash Bytes32 string of the recovery hash\n */\n function getApprovalRecoveryKeyHash(\n bytes memory _recoveryPublicKey,\n string memory _saltString\n ) public view override returns (bytes32 recoveryKeyHash) {\n recoveryKeyHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n _recoveryPublicKey,\n _saltString,\n address(this),\n block.chainid,\n LibFacetStorage.recoveryStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Check the onchain approval of guardians and returns the number of guardians that approved\n * @dev Loop through the guardian addresses and returns the number of guardians that approved this recovery hash\n * @param _recoveryPublicKeyHash Bytes hash of newly recovered public key and recovery value of the account\n * @return approvalCount Number of guardians that approved\n */\n function getRecoveryApprovalCountWithTimeValidity(\n bytes32 _recoveryPublicKeyHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n for (uint256 i; i < guardianLength; ) {\n if (isRecoveryApproved(_recoveryPublicKeyHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Checks if the recovery is approved by the given approver\n * @param _recoveryPublicKeyHash Hash of the public key and configuration for recovery\n * @param _approver Address of approver\n * @return isApproved Bool value if recovery hash is approved\n */\n function isRecoveryApproved(\n bytes32 _recoveryPublicKeyHash,\n address _approver\n ) public view override returns (bool isApproved) {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n if (\n rs\n .isNewOwnerApproved[_recoveryPublicKeyHash][_approver].isApproved &&\n block.timestamp <\n rs.isNewOwnerApproved[_recoveryPublicKeyHash][_approver].validUntil\n ) {\n isApproved = true;\n }\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _recoveryPublicKeyHash Hash of recovery information\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _recoveryPublicKeyHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isRecoveryApproved(_recoveryPublicKeyHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert AccountRecoveryFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the lock period of this wallet address from security manager\n * @return lockPeriod value of lock period\n */\n function _getLockPeriod() internal view returns (uint256 lockPeriod) {\n lockPeriod = securityManager.lockPeriodOf(address(this));\n if (lockPeriod == 0) revert AccountRecoveryFacet__InvalidLockPeriod();\n }\n\n /**\n * @notice Returns the lock period of this wallet address from security manager\n * @return recoveryPeriod value of recovery period\n */\n function _getRecoveryPeriod()\n internal\n view\n returns (uint256 recoveryPeriod)\n {\n recoveryPeriod = securityManager.recoveryPeriodOf(address(this));\n if (recoveryPeriod == 0)\n revert AccountRecoveryFacet__InvalidRecoveryPeriod();\n }\n\n /**\n * @notice Returns the approval validation period of this wallet address from security manager\n * @return approvalValidationPeriod value of approval validation period\n */\n function _getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod == 0)\n revert AccountRecoveryFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the recovery nonce of this wallet address from security manager\n * @return nonce value of recovery nonce\n */\n function getRecoveryNonce() public view override returns (uint128 nonce) {\n nonce = LibFacetStorage.recoveryStorage().nonce;\n }\n\n /**\n * @notice Returns the recovery information of the pending recovery\n * @return recoveryConfig value struct of pending recovery\n */\n function getPendingRecovery()\n public\n view\n override\n returns (RecoveryConfig memory recoveryConfig)\n {\n recoveryConfig = LibFacetStorage.recoveryStorage().recoveryConfigs[\n INNER_STRUCT\n ];\n }\n}\n" + }, + "contracts/facets/base/DiamondCutFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibGuardian} from \"../../libraries/LibGuardian.sol\";\nimport {ISecurityManager} from \"../../infrastructure/interfaces/ISecurityManager.sol\";\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibFacetStorage, DiamondCutApprovalConfig, ApprovalConfig} from \"../../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"../Modifiers.sol\";\nimport {IDiamondCut} from \"./interfaces/IDiamondCut.sol\";\n\n/**\n * @title DiamondCut Facet\n * @dev Responsible for adding/removing/replace facets in Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DiamondCutFacet is Modifiers, IDiamondCut {\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Updates the flag for the interfaceId\n * @param _interfaceId InterfaceID to update the mapping\n * @param _flag Bool value to update the mapping of the given interface ID\n */\n function updateSupportsInterface(\n bytes4 _interfaceId,\n bool _flag\n ) external override onlyWhenUnlocked {\n LibDiamond.enforceIsSelf();\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId] = _flag;\n emit SupportsInterfaceUpdated(_interfaceId, _flag);\n }\n\n /**\n * @notice Add/replace/remove any number of functions and optionally execute\n * a function with delegatecall when guardians don't exist\n * @param _diamondCut Contains the facet addresses and function selectors\n * @param _init The address of the contract or facet to execute _calldata. It's prohibited in Barz\n */\n function diamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata\n ) external override onlyWhenUnlocked {\n LibDiamond.enforceIsSelf();\n\n _checkFacetCutValidity(_diamondCut);\n // require approval from guardian if guardian exists\n if (0 != LibGuardian.guardianCount())\n revert DiamondCutFacet__InvalidRouteWithGuardian();\n if (address(0) != _init) revert DiamondCutFacet__InvalidInitAddress();\n\n ++LibFacetStorage.diamondCutStorage().nonce;\n LibDiamond.diamondCut(_diamondCut, address(0), \"\");\n }\n\n /**\n * @notice Add/replace/remove any number of functions and optionally execute\n * a function with delegatecall when guardians exist\n * @param _diamondCut Contains the facet addresses and function selectors\n * @param _approvers Guardian or owner address that approves the diamond cut\n * @param _signatures Signature of Guardians or owner that approves the diamond cut\n */\n function diamondCutWithGuardian(\n FacetCut[] calldata _diamondCut,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n ) external override onlyWhenUnlocked {\n if (_approvers.length != _signatures.length)\n revert DiamondCutFacet__InvalidArrayLength();\n _checkFacetCutValidity(_diamondCut);\n if (0 == LibGuardian.guardianCount())\n revert DiamondCutFacet__InvalidRouteWithGuardian();\n\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(cutHash, _approvers);\n\n bool onChainOwnerApproval = getOwnerCutApprovalWithTimeValidity(\n cutHash\n );\n\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n if (\n _approvers.length +\n getDiamondCutApprovalCountWithTimeValidity(cutHash) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert DiamondCutFacet__InsufficientApprovers();\n\n bool ownerApproved;\n for (uint256 i; i < _approvers.length; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n _approvers[i] != address(this)\n ) revert DiamondCutFacet__InvalidApprover();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert DiamondCutFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n cutHash,\n _signatures[i]\n )\n ) revert DiamondCutFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n if (!ownerApproved && !onChainOwnerApproval)\n revert DiamondCutFacet__LackOfOwnerApproval();\n\n ++LibFacetStorage.diamondCutStorage().nonce;\n LibDiamond.diamondCut(_diamondCut, address(0), \"\");\n }\n\n /**\n * @notice Approves diamond cut. This can only be called directly from guardian or owner\n * @param _diamondCut Contains the facet addresses and function selectors\n */\n function approveDiamondCut(\n FacetCut[] calldata _diamondCut\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\n if (LibGuardian.guardianCount() == 0)\n revert DiamondCutFacet__InvalidRouteWithoutGuardian();\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n _checkFacetCutValidity(_diamondCut);\n\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(\n true,\n approvalValidUntil\n );\n emit DiamondCutApproved(_diamondCut);\n if (\n (getDiamondCutApprovalCountWithTimeValidity(cutHash) >=\n LibGuardian.majorityOfGuardians()) &&\n getOwnerCutApprovalWithTimeValidity(cutHash)\n ) {\n ++LibFacetStorage.diamondCutStorage().nonce;\n LibDiamond.diamondCut(_diamondCut, address(0), \"\");\n }\n }\n\n /**\n * @notice Revokes the approval of diamond cut. This can only be called directly from guardian or owner\n * @param _diamondCut Contains the facet addresses and function selectors\n */\n function revokeDiamondCutApproval(\n FacetCut[] calldata _diamondCut\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\n if (!ds.isDiamondCutApproved[cutHash][msg.sender].isApproved)\n revert DiamondCutFacet__CannotRevokeUnapproved();\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(false, 0);\n emit DiamondCutApprovalRevoked(_diamondCut);\n }\n\n /**\n * @notice Gets the number of approvals of diamond cut from guardians\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n */\n function getDiamondCutApprovalCountWithTimeValidity(\n bytes32 _diamondCutHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardiansLength = guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n if (isCutApproved(_diamondCutHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n return approvalCount;\n }\n\n /**\n * @notice Returns if the owner has approved the diamond cut\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @return isApprovedByOwner Bool value showing if the owner approved the cut\n */\n function getOwnerCutApprovalWithTimeValidity(\n bytes32 _diamondCutHash\n ) public view override returns (bool isApprovedByOwner) {\n isApprovedByOwner = isCutApproved(_diamondCutHash, address(this));\n }\n\n /**\n * @notice Returns if the given approver has approved the diamond cut\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @param _approver Address of approver\n * @return isApproved Bool value showing if the approver approved the cut\n */\n function isCutApproved(\n bytes32 _diamondCutHash,\n address _approver\n ) public view override returns (bool isApproved) {\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n isApproved = (ds\n .isDiamondCutApproved[_diamondCutHash][_approver].isApproved &&\n block.timestamp <\n ds.isDiamondCutApproved[_diamondCutHash][_approver].validUntil);\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _diamondCutHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isCutApproved(_diamondCutHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert DiamondCutFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the diamond cut hash. This function ensures that this hash is safe from replay attack by including\n * salt, address, chainId, and nonce, etc.\n * @param _diamondCut Contains the facet addresses and function selectors\n * @return cutHash Diamond Cut Hash\n */\n function getDiamondCutHash(\n FacetCut[] calldata _diamondCut\n ) public view override returns (bytes32 cutHash) {\n cutHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n keccak256(abi.encode(_diamondCut)),\n address(this),\n block.chainid,\n LibFacetStorage.diamondCutStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Returns the approval validation Period\n * @dev This method fetches the validation period from the security manager\n * @return approvalValidationPeriod Approval validation period of Barz contract fetched from security manager\n */\n function getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod <= 0)\n revert DiamondCutFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the diamond cut nonce of this wallet\n * @dev This method fetches the nonce from diamond cut storage\n * @return cutNonce Nonce of diamond cut to protect from reply attacks\n */\n function getDiamondCutNonce()\n public\n view\n override\n returns (uint128 cutNonce)\n {\n cutNonce = LibFacetStorage.diamondCutStorage().nonce;\n }\n}\n" + }, + "contracts/facets/base/DiamondLoupeFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {IERC165} from \"../../interfaces/ERC/IERC165.sol\";\nimport {IERC1271} from \"../../interfaces/ERC/IERC1271.sol\";\nimport {IERC677Receiver} from \"../../interfaces/ERC/IERC677Receiver.sol\";\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC1155Receiver} from \"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\";\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../../libraries/LibLoupe.sol\";\nimport {LibUtils} from \"../../libraries/LibUtils.sol\";\nimport {IDiamondCut} from \"../../facets/base/interfaces/IDiamondCut.sol\";\nimport {IStorageLoupe} from \"./interfaces/IStorageLoupe.sol\";\nimport {IDiamondLoupe} from \"./interfaces/IDiamondLoupe.sol\";\n\n/**\n * @title DiamondLoupe Facet\n * @dev DiamondLoupe contract compatible with EIP-2535\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DiamondLoupeFacet is IDiamondLoupe, IStorageLoupe, IERC165 {\n // Diamond Loupe Functions\n ////////////////////////////////////////////////////////////////////\n /// These functions are expected to be called frequently by tools off-chain.\n\n /**\n * @notice Gets all facets and their selectors.\n * @dev Barz uses a special architecture called default fallback handler. Default Fallback handler is used as a middleware\n * that holds the mapping of facet function selector and facet address that Barz uses. This helps Barz to reduce\n * significant amount of gas during the initialization process.\n * Hence, this method aggregates both the facet information from DefaulFallbackHandler and in diamond storage and shows the data to users.\n * @return facets_ Facet\n */\n function facets() public view override returns (Facet[] memory facets_) {\n Facet[] memory defaultFacet = LibDiamond\n .diamondStorage()\n .defaultFallbackHandler\n .facets();\n Facet[] memory _facets = LibLoupe.facets();\n uint256 numFacets = _facets.length;\n bytes4[] memory keys;\n address[] memory values;\n for (uint256 i; i < numFacets; ) {\n uint256 selectorsLength = _facets[i].functionSelectors.length;\n for (uint256 j; j < selectorsLength; ) {\n (keys, values) = LibUtils.setValue(\n keys,\n values,\n _facets[i].functionSelectors[j],\n _facets[i].facetAddress\n );\n unchecked {\n ++j;\n }\n }\n unchecked {\n ++i;\n }\n }\n {\n bool iIncrement;\n for (uint256 i; i < defaultFacet.length; ) {\n bool jIncrement;\n for (\n uint256 j;\n j < defaultFacet[i].functionSelectors.length;\n\n ) {\n if (\n LibUtils.getValue(\n keys,\n values,\n defaultFacet[i].functionSelectors[j]\n ) != address(0)\n ) {\n if (defaultFacet[i].functionSelectors.length == 1) {\n defaultFacet = LibUtils.removeFacetElement(\n defaultFacet,\n i\n );\n iIncrement = true;\n break;\n }\n defaultFacet[i].functionSelectors = LibUtils\n .removeElement(\n defaultFacet[i].functionSelectors,\n j\n );\n jIncrement = true;\n }\n if (!jIncrement) {\n unchecked {\n ++j;\n }\n } else {\n jIncrement = false;\n }\n }\n if (!iIncrement) {\n unchecked {\n ++i;\n }\n } else {\n iIncrement = false;\n }\n }\n }\n {\n uint256 facetLength = numFacets + defaultFacet.length;\n facets_ = new Facet[](facetLength);\n uint256 defaultFacetIndex;\n for (uint256 i; i < facetLength; ) {\n if (i < numFacets) {\n facets_[i] = _facets[i];\n bool jIncrementor;\n for (uint256 j; j < defaultFacet.length; ) {\n if (\n facets_[i].facetAddress ==\n defaultFacet[j].facetAddress\n ) {\n facets_[i].functionSelectors = LibUtils.mergeArrays(\n _facets[i].functionSelectors,\n defaultFacet[j].functionSelectors\n );\n defaultFacet = LibUtils.removeFacetElement(\n defaultFacet,\n j\n );\n jIncrementor = true;\n {\n facets_ = LibUtils.removeFacetElement(\n facets_,\n facets_.length - 1\n );\n }\n --facetLength;\n }\n if (!jIncrementor) {\n unchecked {\n ++j;\n }\n } else {\n jIncrementor = false;\n }\n }\n } else {\n facets_[i] = defaultFacet[defaultFacetIndex];\n ++defaultFacetIndex;\n }\n unchecked {\n ++i;\n }\n }\n }\n }\n\n /**\n * @notice Gets all the function selectors provided by a facet.\n * @param _facet The facet address.\n * @return facetFunctionSelectors_\n */\n function facetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n Facet[] memory facet = facets();\n uint256 facetLength = facet.length;\n for (uint256 i; i < facetLength; ) {\n if (facet[i].facetAddress == _facet)\n return facet[i].functionSelectors;\n unchecked {\n ++i;\n }\n }\n return facetFunctionSelectors_;\n }\n\n /**\n * @notice Get all the facet addresses used by Barz.\n * @return facetAddresses_\n */\n function facetAddresses()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n Facet[] memory facet = facets();\n uint256 facetLength = facet.length;\n facetAddresses_ = new address[](facetLength);\n for (uint256 i; i < facetLength; ) {\n facetAddresses_[i] = facet[i].facetAddress;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Gets the facet that supports the given selector.\n * @dev If facet is not found return address(0).\n * @param _functionSelector The function selector.\n * @return facetAddress_ The facet address.\n */\n function facetAddress(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n\n facetAddress_ = address(bytes20(ds.facets[_functionSelector]));\n if (facetAddress_ == address(0)) {\n facetAddress_ = IDiamondLoupe(ds.defaultFallbackHandler)\n .facetAddress(_functionSelector);\n }\n }\n\n /**\n * @notice SupportInterface to be compatible with EIP 165\n * @param _interfaceId Interface ID for detecting the interface\n * @return isSupported Bool value showing if the standard is supported in the contract\n */\n function supportsInterface(\n bytes4 _interfaceId\n ) external view override returns (bool isSupported) {\n isSupported =\n _interfaceId == type(IERC165).interfaceId ||\n _interfaceId == IDiamondCut.diamondCut.selector ||\n _interfaceId == type(IDiamondLoupe).interfaceId ||\n _interfaceId == type(IERC1155Receiver).interfaceId ||\n _interfaceId == type(IERC721Receiver).interfaceId ||\n _interfaceId == type(IERC777Recipient).interfaceId ||\n _interfaceId == IERC1271.isValidSignature.selector ||\n _interfaceId == type(IERC677Receiver).interfaceId ||\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId];\n }\n\n /**\n * @notice Returns the facet from the diamond storage. This excludes the facets from the default fallback handler\n * @return facets_ Facet information attached directly to diamond storage\n */\n function facetsFromStorage()\n external\n view\n override\n returns (Facet[] memory facets_)\n {\n facets_ = LibLoupe.facets();\n }\n\n /**\n * @notice Returns the facet address attached to the given function selector. This excludes the facets from the default fallback handler\n * @param _functionSelector Function selector to fetch the facet address from diamond storage\n * @return facetAddress_ Facet address mapped with the function selector\n */\n function facetAddressFromStorage(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n facetAddress_ = LibLoupe.facetAddress(_functionSelector);\n }\n\n /**\n * @notice Returns all facet addresses attached directly to diamond storage. This excludes the facets from the default fallback handler\n * @return facetAddresses_ All facet addresses attached directly to diamond storage\n */\n function facetAddressesFromStorage()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n facetAddresses_ = LibLoupe.facetAddresses();\n }\n\n /**\n * @notice Returns function selectors of given facet address attached directly to diamond storage. This excludes the facets from the default fallback handler\n * @param _facet Facet address to fetch the facet function selectors from diamond storage\n * @return facetFunctionSelectors_ Facet function selectors of the given facet address\n */\n function facetFunctionSelectorsFromStorage(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n facetFunctionSelectors_ = LibLoupe.facetFunctionSelectors(_facet);\n }\n}\n" + }, + "contracts/facets/base/interfaces/IDiamondCut.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title DiamondCut Facet Interface\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IDiamondCut {\n error DiamondCutFacet__InvalidRouteWithGuardian();\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\n error DiamondCutFacet__InvalidArrayLength();\n error DiamondCutFacet__InsufficientApprovers();\n error DiamondCutFacet__InvalidApprover();\n error DiamondCutFacet__InvalidApproverSignature();\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\n error DiamondCutFacet__CannotRevokeUnapproved();\n error DiamondCutFacet__LackOfOwnerApproval();\n error DiamondCutFacet__OwnerAlreadyApproved();\n error DiamondCutFacet__DuplicateApproval();\n error DiamondCutFacet__InvalidInitAddress();\n\n event DiamondCutApproved(FacetCut[] diamondCut);\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\n\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\n\n enum FacetCutAction {\n Add,\n Replace,\n Remove\n }\n // Add=0, Replace=1, Remove=2\n\n struct FacetCut {\n address facetAddress;\n FacetCutAction action;\n bytes4[] functionSelectors;\n }\n\n /// @notice Add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param diamondCut Contains the facet addresses and function selectors\n /// @param init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function diamondCut(\n FacetCut[] calldata diamondCut,\n address init,\n bytes calldata _calldata\n ) external;\n\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\n\n function diamondCutWithGuardian(\n FacetCut[] calldata diamondCut,\n address[] calldata approvers,\n bytes[] calldata signatures\n ) external;\n\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\n\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\n\n function getDiamondCutApprovalCountWithTimeValidity(\n bytes32 diamondCutHash\n ) external view returns (uint256);\n\n function getOwnerCutApprovalWithTimeValidity(\n bytes32 diamondCutHash\n ) external view returns (bool);\n\n function isCutApproved(\n bytes32 diamondCutHash,\n address approver\n ) external view returns (bool);\n\n function getDiamondCutHash(\n FacetCut[] calldata diamondCut\n ) external view returns (bytes32);\n\n function getDiamondCutNonce() external view returns (uint128);\n}\n" + }, + "contracts/facets/base/interfaces/IDiamondLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n// A loupe is a small magnifying glass used to look at diamonds.\n// These functions look at diamonds\ninterface IDiamondLoupe {\n /// These functions are expected to be called frequently\n /// by tools.\n\n struct Facet {\n address facetAddress;\n bytes4[] functionSelectors;\n }\n\n /// @notice Gets all facet addresses and their four byte function selectors.\n /// @return facets_ Facet\n function facets() external view returns (Facet[] memory facets_);\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n /// @return facetFunctionSelectors_\n function facetFunctionSelectors(\n address _facet\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses()\n external\n view\n returns (address[] memory facetAddresses_);\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(\n bytes4 _functionSelector\n ) external view returns (address facetAddress_);\n}\n" + }, + "contracts/facets/base/interfaces/IStorageLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"./IDiamondLoupe.sol\";\n\n/**\n * @title LoupeFromStorage Interface\n * @dev Interface contract to function as a loupe facet directly attached to diamond storage of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IStorageLoupe {\n /// These functions are expected to be called frequently\n /// by tools.\n\n /// @notice Gets all facet addresses and their four byte function selectors.\n /// @return facets_ Facet\n function facetsFromStorage()\n external\n view\n returns (IDiamondLoupe.Facet[] memory);\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n function facetFunctionSelectorsFromStorage(\n address _facet\n ) external view returns (bytes4[] memory);\n\n /// @notice Get all the facet addresses used by a diamond.\n function facetAddressesFromStorage()\n external\n view\n returns (address[] memory);\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n function facetAddressFromStorage(\n bytes4 _functionSelector\n ) external view returns (address);\n}\n" + }, + "contracts/facets/GuardianFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibFacetStorage, GuardianStorage, StorageConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IGuardianFacet} from \"./interfaces/IGuardianFacet.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Guardian Facet\n * @dev Contract that enables addition/removal of guardians from Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract GuardianFacet is IGuardianFacet {\n ISecurityManager public immutable securityManager;\n uint8 public constant INNER_STRUCT = 0;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Add guardians to Barz.\n * @dev This method internally calls addGuardian which checks the validity of guardian address and adds\n * as guardian if valid\n * @param _guardians Array of addresses to add as guardian\n */\n function addGuardians(address[] calldata _guardians) external override {\n LibDiamond.enforceIsSelf();\n for (uint256 i; i < _guardians.length; ) {\n addGuardian(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Add a guardian to Barz.\n * @dev This method checks if the function is called by the owner and validates the address of guardian\n * When the validation passes, guardian address is added to the pending state waiting for confirmation\n * @param _guardian Address to add as guardian\n */\n function addGuardian(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (_guardian == address(this))\n revert GuardianFacet__GuardianCannotBeSelf();\n if (isGuardian(_guardian)) revert GuardianFacet__DuplicateGuardian();\n if (_guardian == address(0))\n revert GuardianFacet__ZeroAddressGuardian();\n if (\n keccak256(abi.encodePacked(_guardian)) ==\n keccak256(IVerificationFacet(address(this)).owner())\n ) revert GuardianFacet__OwnerCannotBeGuardian();\n\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n if (\n gs.pending[id] != 0 ||\n block.timestamp <= gs.pending[id] + getSecurityWindow()\n ) revert GuardianFacet__DuplicateGuardianAddition();\n\n uint256 securityPeriod = getAdditionSecurityPeriod();\n gs.pending[id] = block.timestamp + securityPeriod;\n emit GuardianAdditionRequested(\n _guardian,\n block.timestamp + securityPeriod\n );\n }\n\n /**\n * @notice Remove guardians from Barz.\n * @dev This method internally calls removeGuardian which checks the validity of guardian and removes\n * guardian when the request is valid\n * @param _guardians Array of addresses to be removed\n */\n function removeGuardians(address[] calldata _guardians) external override {\n LibDiamond.enforceIsSelf();\n for (uint256 i; i < _guardians.length; ) {\n removeGuardian(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Remove a guardian from Barz.\n * @dev This method validates if the guardian to be removed is a guardian and puts the guardian removal\n * to a pending state waiting to be confirmed.\n * @param _guardian Address of guardian to be removed\n */\n function removeGuardian(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n if (!isGuardian(_guardian)) revert GuardianFacet__NonExistentGuardian();\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n if (\n gs.pending[id] != 0 ||\n block.timestamp <= gs.pending[id] + getSecurityWindow()\n ) revert GuardianFacet__DuplicateGuardianRemoval();\n\n uint256 securityPeriod = getRemovalSecurityPeriod();\n gs.pending[id] = block.timestamp + securityPeriod;\n emit GuardianRemovalRequested(\n _guardian,\n block.timestamp + securityPeriod\n );\n }\n\n /**\n * @notice Confirm addition of guardians\n * @dev This method internally calls confirmGuardianAddition which checks the validity of pending request.\n * Guardians are fully added when they pass the validation. Anyone can call this function.\n * @param _guardians Array of guardian addresses to be added\n */\n function confirmGuardianAdditions(\n address[] calldata _guardians\n ) external override {\n for (uint256 i; i < _guardians.length; ) {\n confirmGuardianAddition(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Confirm addition of a guardian\n * @dev This method checks the validity of pending request.\n * Guardians are fully added when they pass the validation. Anyone can call this function.\n * @param _guardian Guardian address to be added\n */\n function confirmGuardianAddition(address _guardian) public override {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingAddition();\n if (gs.pending[id] >= block.timestamp)\n revert GuardianFacet__PendingAdditionNotOver();\n if (block.timestamp >= gs.pending[id] + getSecurityWindow())\n revert GuardianFacet__PendingAdditionExpired();\n\n _addGuardian(_guardian);\n\n delete gs.pending[id];\n emit GuardianAdded(_guardian);\n }\n\n /**\n * @notice Confirm removal of guardians\n * @dev This method internally calls confirmGuardianRemoval to check the validity guardian removal confirmation.\n * Guardians are fully removed when they pass the validation. Anyone can call this function.\n * @param _guardians Array of guardian addresses to be removed\n */\n function confirmGuardianRemovals(\n address[] calldata _guardians\n ) external override {\n for (uint256 i; i < _guardians.length; ) {\n confirmGuardianRemoval(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Confirm removal of a guardian\n * @dev This method checks the validity guardian removal confirmation.\n * Guardian is fully removed when they pass the validation. Anyone can call this function.\n * @param _guardian Guardian address to be removed\n */\n function confirmGuardianRemoval(address _guardian) public override {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingRemoval();\n if (gs.pending[id] >= block.timestamp)\n revert GuardianFacet__PendingRemovalNotOver();\n if (block.timestamp >= gs.pending[id] + getSecurityWindow())\n revert GuardianFacet__PendingAdditionExpired();\n\n _removeGuardian(_guardian);\n delete gs.pending[id];\n emit GuardianRemoved(_guardian);\n }\n\n /**\n * @notice Cancel pending guardian addition\n * @dev This method checks if the previous request for guardian request exists.\n * It reverts if previous request is not pending and cancels the addition otherwise.\n * @param _guardian Guardian address to be canceled from addition\n */\n function cancelGuardianAddition(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingAddition();\n delete gs.pending[id];\n emit GuardianAdditionCancelled(_guardian);\n }\n\n /**\n * @notice Cancel pending guardian removal\n * @dev This method checks if the previous request for guardian request exists.\n * It reverts if previous request is not pending and cancels the removal otherwise.\n * @param _guardian Guardian address to be canceled from removal\n */\n function cancelGuardianRemoval(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingRemoval();\n delete gs.pending[id];\n emit GuardianRemovalCancelled(_guardian);\n }\n\n /**\n * @notice Get the addition security period of current account from security manager\n * @dev This method returns the uint value if addition security period\n * @return additionSecurityPeriod Uint256 value of addition security period\n */\n function getAdditionSecurityPeriod()\n public\n view\n override\n returns (uint256 additionSecurityPeriod)\n {\n additionSecurityPeriod = securityManager.additionSecurityPeriodOf(\n address(this)\n );\n if (additionSecurityPeriod == 0)\n revert GuardianFacet__InvalidAdditionSecurityPeriod();\n }\n\n /**\n * @notice Get the removal security period of current account from security manager\n * @dev This method returns the uint value if removal security period\n * @return removalSecurityPeriod Uint256 value of removal security period\n */\n function getRemovalSecurityPeriod()\n public\n view\n override\n returns (uint256 removalSecurityPeriod)\n {\n removalSecurityPeriod = securityManager.removalSecurityPeriodOf(\n address(this)\n );\n if (removalSecurityPeriod == 0)\n revert GuardianFacet__InvalidRemovalSecurityPeriod();\n }\n\n /**\n * @notice Get the security window of current account from security manager\n * @dev This method returns the uint value if security window\n * @return securityWindow Uint256 value of removal security period\n */\n function getSecurityWindow()\n public\n view\n override\n returns (uint256 securityWindow)\n {\n securityWindow = securityManager.securityWindowOf(address(this));\n if (securityWindow == 0) revert GuardianFacet__InvalidSecurityWindow();\n }\n\n /**\n * @notice Checks if the addition of the given guardian address is pending\n * @dev This method returns the bool value of whether the guardian address is pending addition\n * @return isPending Bool value of representing the pending of guardian addition\n */\n function isAdditionPending(\n address _guardian\n ) public view override returns (bool isPending) {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n isPending = _isPending(id);\n }\n\n /**\n * @notice Checks if the removal of the given guardian address is pending\n * @dev This method returns the bool value of whether the guardian address is pending removal\n * @return isPending Bool value of representing the pending of guardian removal\n */\n function isRemovalPending(\n address _guardian\n ) public view override returns (bool isPending) {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n isPending = _isPending(id);\n }\n\n /**\n * @notice Checks if the given hash is pending\n * @dev This method returns the bool value whether the hash is pending\n * @return isPending Bool value of representing the pending of guardian operation\n */\n function _isPending(\n bytes32 _idHash\n ) internal view returns (bool isPending) {\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n isPending = ((gs.pending[_idHash] > 0 &&\n gs.pending[_idHash] < block.timestamp) &&\n block.timestamp < gs.pending[_idHash] + getSecurityWindow());\n }\n\n /**\n * @notice Adds guardian to storage config. This is called when guardian is fully added.\n * @dev This method add guardian address and config information to Facet Storage dedicated for guardian\n * When this function is called, guardian is fully added to this Barz Smart Account\n * @param _guardian Address of guardian to be added\n */\n function _addGuardian(address _guardian) internal {\n if (!isAdditionPending(_guardian))\n revert GuardianFacet__InvalidGuardianAddition();\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n if (config.info[_guardian].exists)\n revert GuardianFacet__AlreadyExists();\n\n config.info[_guardian].exists = true;\n config.info[_guardian].index = uint128(config.addresses.length);\n config.addresses.push(_guardian);\n }\n\n /**\n * @notice Removes guardian to storage config. This is called when guardian is fully removed.\n * @dev This method remove guardian address and config information to Facet Storage dedicated for guardian\n * When this function is called, guardian is fully removed from this Barz Smart Account\n * @param _guardian Address of guardian to be removed\n */\n function _removeGuardian(address _guardian) internal {\n if (!isRemovalPending(_guardian))\n revert GuardianFacet__InvalidGuardianRemoval();\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n if (!config.info[_guardian].exists)\n revert GuardianFacet__NonExistentGuardian();\n\n address lastAddress = config.addresses[config.addresses.length - 1];\n if (_guardian != lastAddress) {\n uint128 targetIndex = config.info[_guardian].index;\n config.addresses[targetIndex] = lastAddress;\n config.info[lastAddress].index = targetIndex;\n }\n config.addresses.pop();\n delete config.info[_guardian];\n\n emit GuardianRemoved(_guardian);\n }\n\n /**\n * @notice Reads guardian storage and fetches the addresses into an array from the storage\n * @dev This method fetches the guardian storage and returns the list of guardian addresses\n * @return addresses Array of addresses comprised of guardian\n */\n function getGuardians()\n public\n view\n override\n returns (address[] memory addresses)\n {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n addresses = new address[](config.addresses.length);\n uint256 addressesLen = config.addresses.length;\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the number of majority of guardians\n * @return majorityOfGuardians_ Number of majority of guardians e.g., 2 if 3 guardians / 3 if 5 guardians\n */\n function majorityOfGuardians()\n public\n view\n override\n returns (uint256 majorityOfGuardians_)\n {\n majorityOfGuardians_ = LibGuardian.majorityOfGuardians();\n }\n\n /**\n * @notice Reads guardian storage and fetches the addresses into an array from the storage\n * @dev This method fetches the guardian storage and returns the list of guardian addresses\n * @return guardianNumber Array of guardians in the account\n */\n function guardianCount()\n public\n view\n override\n returns (uint256 guardianNumber)\n {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n guardianNumber = config.addresses.length;\n }\n\n /**\n * @notice Reads guardian storage and checks if the given address is a guardian\n * @return isGuardian_ Bool value representing if the given address is guardian\n */\n function isGuardian(\n address _guardian\n ) public view override returns (bool isGuardian_) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n isGuardian_ = config.info[_guardian].exists;\n }\n\n /**\n * @notice Checks if the guardian number is zero and returns of guardian facet is okay to be removed\n * @return isRemovable Bool value representing if guardian facet is removable\n */\n function isGuardianFacetRemovable()\n external\n view\n override\n returns (bool isRemovable)\n {\n isRemovable = (0 == guardianCount());\n }\n}\n" + }, + "contracts/facets/interfaces/IAccountFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IEntryPoint} from \"../../aa-4337/interfaces/IEntryPoint.sol\";\n\n/**\n * @title Account Facet Interface\n * @dev Interface of module contract that provides the account features and init/unitialization of signer\n * compatible with EIP-1271 & EIP-4337\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IAccountFacet {\n event AccountInitialized(\n IEntryPoint indexed entryPoint,\n bytes indexed ownerPublicKey\n );\n // NOTE: Added Below Event\n event VerificationSuccess(bytes32);\n event VerificationFailure(bytes32);\n\n error AccountFacet__InitializationFailure();\n error AccountFacet__RestrictionsFailure();\n error AccountFacet__NonExistentVerificationFacet();\n error AccountFacet__CallNotSuccessful();\n\n function initialize(\n address verificationFacet,\n address anEntryPoint,\n address facetRegistry,\n address _defaultFallBack,\n bytes calldata _ownerPublicKey\n ) external returns (uint256);\n\n function execute(address dest, uint256 value, bytes calldata func) external;\n\n function executeBatch(\n address[] calldata dest,\n uint256[] calldata value,\n bytes[] calldata func\n ) external;\n}\n" + }, + "contracts/facets/interfaces/IAccountRecoveryFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {RecoveryConfig} from \"../../libraries/LibFacetStorage.sol\";\n\n/**\n * @title Account Recovery Facet Interface\n * @dev Interface of contract that enables recovery of accounts when owner key is unavailable\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IAccountRecoveryFacet {\n event RecoveryExecuted(\n bytes indexed recoveryPublicKey,\n uint64 executeAfter\n );\n event RecoveryFinalized(bytes indexed recoveryPublicKey);\n event RecoveryCanceled(bytes indexed recoveryPublicKey);\n event RecoveryApproved(\n bytes indexed recoveryPublicKey,\n address indexed guardian,\n uint64 validUntil\n );\n event RecoveryApprovalRevoked(\n bytes indexed recoveryPublicKey,\n address indexed guardian\n );\n event RecoveryCancellationApproved(\n bytes indexed recoveryPublicKey,\n address indexed guardian\n );\n event RecoveryHardstopped();\n\n error AccountRecoveryFacet__CallerNotGuardian();\n error AccountRecoveryFacet__InvalidRecoveryPublicKey();\n error AccountRecoveryFacet__SignerInitializationFailure();\n error AccountRecoveryFacet__SignerUninitializationFailure();\n error AccountRecoveryFacet__InvalidArrayLength();\n error AccountRecoveryFacet__InsufficientGuardians();\n error AccountRecoveryFacet__RecoveryAlreadyOngoing();\n error AccountRecoveryFacet__NonexistentRecovery();\n error AccountRecoveryFacet__NonExistentApproval();\n error AccountRecoveryFacet__RecoveryPeriodNotOver();\n error AccountRecoveryFacet__InvalidLockPeriod();\n error AccountRecoveryFacet__InvalidRecoveryPeriod();\n error AccountRecoveryFacet__InvalidApprovalValidationPeriod();\n error AccountRecoveryFacet__InvalidGuardian();\n error AccountRecoveryFacet__InvalidGuardianSignature();\n error AccountRecoveryFacet__InvalidOwnerSignature();\n error AccountRecoveryFacet__CallNotSuccesful();\n error AccountRecoveryFacet__DuplicateApproval();\n\n function approveAccountRecovery(bytes calldata recoveryPublicKey) external;\n\n function revokeAccountRecoveryApproval(\n bytes calldata recoveryPublicKey\n ) external;\n\n function executeRecovery(\n bytes calldata recoveryPublicKey,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function finalizeRecovery() external;\n\n function approveCancelRecovery(bytes calldata recoveryPublicKey) external;\n\n function cancelRecovery(\n bytes calldata recoveryPublicKey,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function hardstopRecovery(bytes calldata signature) external;\n\n function getApprovalRecoveryKeyHash(\n bytes memory recoveryPublicKey,\n string memory saltString\n ) external view returns (bytes32);\n\n function getRecoveryApprovalCountWithTimeValidity(\n bytes32 recoveryPublicKeyHash\n ) external view returns (uint256);\n\n function isRecoveryApproved(\n bytes32 recoveryPublicKeyHash,\n address approver\n ) external view returns (bool);\n\n function getRecoveryNonce() external view returns (uint128);\n\n function getPendingRecovery() external view returns (RecoveryConfig memory);\n}\n" + }, + "contracts/facets/interfaces/IGuardianFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Guardian Facet Interface\n * @dev Interface of guaridna contract that enables addition/removal of guardians from Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IGuardianFacet {\n event GuardianAdditionRequested(\n address indexed guardian,\n uint256 executeAfter\n );\n event GuardianRemovalRequested(\n address indexed guardian,\n uint256 executeAfter\n );\n event GuardianAdditionCancelled(address indexed guardian);\n event GuardianRemovalCancelled(address indexed guardian);\n event GuardianAdded(address indexed guardian);\n event GuardianRemoved(address indexed guardian);\n\n error GuardianFacet__GuardianCannotBeSelf();\n error GuardianFacet__DuplicateGuardian();\n error GuardianFacet__OwnerCannotBeGuardian();\n error GuardianFacet__DuplicateGuardianAddition();\n error GuardianFacet__DuplicateGuardianRemoval();\n error GuardianFacet__UnknownPendingAddition();\n error GuardianFacet__PendingAdditionNotOver();\n error GuardianFacet__UnknownPendingRemoval();\n error GuardianFacet__PendingRemovalNotOver();\n error GuardianFacet__PendingAdditionExpired();\n error GuardianFacet__InvalidAdditionSecurityPeriod();\n error GuardianFacet__InvalidRemovalSecurityPeriod();\n error GuardianFacet__InvalidSecurityWindow();\n error GuardianFacet__NonExistentGuardian();\n error GuardianFacet__AlreadyExists();\n error GuardianFacet__InvalidGuardianAddition();\n error GuardianFacet__InvalidGuardianRemoval();\n error GuardianFacet__ZeroAddressGuardian();\n\n function addGuardian(address guardian) external;\n\n function addGuardians(address[] calldata guardians) external;\n\n function removeGuardian(address guardian) external;\n\n function removeGuardians(address[] calldata guardians) external;\n\n function confirmGuardianAddition(address guardian) external;\n\n function confirmGuardianAdditions(address[] calldata guardian) external;\n\n function confirmGuardianRemoval(address guardian) external;\n\n function confirmGuardianRemovals(address[] calldata guardian) external;\n\n function cancelGuardianAddition(address guardian) external;\n\n function cancelGuardianRemoval(address guardian) external;\n\n function isGuardian(address guardian) external view returns (bool);\n\n function isAdditionPending(address guardian) external view returns (bool);\n\n function isRemovalPending(address guardian) external view returns (bool);\n\n function isGuardianFacetRemovable() external view returns (bool);\n\n function getAdditionSecurityPeriod() external view returns (uint256);\n\n function getRemovalSecurityPeriod() external view returns (uint256);\n\n function getSecurityWindow() external view returns (uint256);\n\n function getGuardians() external view returns (address[] memory);\n\n function majorityOfGuardians() external view returns (uint256);\n\n function guardianCount() external view returns (uint256);\n}\n" + }, + "contracts/facets/interfaces/ILockFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Lock} from \"../../libraries/LibAppStorage.sol\";\n\n/**\n * @title Lock Facet Interface\n * @dev Interface of Lock contract that enables full lock/unlock of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface ILockFacet {\n event Locked(uint64 releaseAfter);\n event Unlocked();\n\n error LockFacet__InvalidRecoveryPeriod();\n error LockFacet__CannotUnlock();\n error LockFacet__InvalidSignature();\n error LockFacet__InvalidApprover();\n\n function lock() external;\n\n function unlock(address approver, bytes calldata signature) external;\n\n function getLockPeriod() external view returns (uint256);\n\n function isLocked() external view returns (bool);\n\n function getUnlockHash() external view returns (bytes32);\n\n function lockNonce() external view returns (uint128);\n\n function getPendingLock() external view returns (Lock memory);\n}\n" + }, + "contracts/facets/interfaces/IMultiSigFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Multi-sig facet Interface\n * @dev Interface of Multi-signature Facet with custom threshold.\n Wallet that adds this facet becomes a multi-sig wallet\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IMultiSigFacet {\n event ThresholdChanged(uint256 threshold);\n event OwnerAdded(address indexed newOwner);\n event OwnerRemoved(address indexed prevOwner);\n event HashApproved(bytes32 hashToApprove, address indexed owner);\n\n error MultiSigFacet__InvalidThreshold();\n error MultisigFacet__InvalidOwnerCount();\n error MultiSigFacet__InvalidRoute();\n error MultiSigFacet__InsufficientSignerLength();\n error MultiSigFacet__InvalidInitData();\n error MultiSigFacet__InvalidOwnerAddress();\n error MultiSigFacet__InvalidOwnerPair();\n error MultiSigFacet__InvalidSignatureLength();\n error MultiSigFacet__InvalidSignatureType();\n error MultiSigFacet__DuplicateOwner();\n error MultiSigFacet__OnlyOwner();\n\n function checkSignatures(\n bytes32 _dataHash,\n bytes calldata _signatures,\n uint256 _threshold\n ) external view returns (uint256);\n\n function splitSignatures(\n bytes calldata _signatures,\n uint256 _nextOffset\n )\n external\n pure\n returns (\n address owner,\n bytes memory signature,\n uint256 signatureType,\n uint256 nextOffset\n );\n\n function approveHash(bytes32 hashToApprove) external;\n\n function addOwner(address newOwner, uint256 threshold) external;\n\n function removeOwner(\n address prevOwner,\n address removedOwner,\n uint256 threshold\n ) external;\n\n function swapOwner(\n address prevOwner,\n address oldOwner,\n address newOwner\n ) external;\n\n function changeThreshold(uint256 _threshold) external;\n\n function isOwner(address owner) external view returns (bool);\n\n function getThreshold() external view returns (uint256);\n\n function getOwners() external view returns (address[] memory);\n}\n" + }, + "contracts/facets/interfaces/IRestrictionsFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Restrictions Facet Interface\n * @dev Interface of Restrictions contract that enables modular restrictions in Barz\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IRestrictionsFacet {\n event RestrictionAdded(address indexed restriction);\n event RestrictionRemoved(address indexed restriction);\n\n error RestrictionsFacet__EmptyRestrictionsList();\n error RestrictionsFacet__RestrictionNotFound();\n error RestrictionsFacet__RestrictionAlreadyExists();\n error RestrictionsFacet__ZeroAddressRestrictions();\n error RestrictionsFacet__ZeroAddressRestrictionsFacet();\n error RestrictionsFacet__RemainingRestrictionsCantBeEmpty();\n\n function initializeRestrictions(\n address[] memory _restrictions\n ) external returns (uint256);\n\n function uninitializeRestrictions() external returns (uint256);\n\n function getRestrictions() external view returns (address[] memory);\n\n function addRestriction(address restriction) external;\n\n function removeRestriction(address restriction) external;\n\n function verifyRestrictions(\n address from,\n address to,\n uint256 value,\n bytes calldata _calldata\n ) external returns (uint256);\n}\n" + }, + "contracts/facets/interfaces/ISignatureMigrationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureMigrationConfig} from \"../../libraries/LibFacetStorage.sol\";\n\n/**\n * @title Signature Migration Facet Interface\n * @dev Interface of Signature Migration contract for migrating user signature scheme to a new scheme user sets\n * Which could include\n * - ECDSA on Secp256K1 Curve\n * - ECDSA on Secp256R1 Curve\n * - BLS, Schnorr, etc\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface ISignatureMigrationFacet {\n event SignatureSchemeMigration(\n address indexed prevVerificationFacet,\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n event SignatureMigrationApproved(\n bytes newPublicKey,\n address indexed newVerificationFacet,\n bytes4[] verificationFuncSelectors,\n address indexed guardian,\n uint128 approvalValidUntil\n );\n event SignatureMigrationApprovalRevoked(\n bytes newPublicKey,\n address indexed newVerificationFacet,\n bytes4[] verificationFuncSelectors,\n address indexed guardian\n );\n event SignatureMigrationExecuted(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors,\n uint128 migrateAfter\n );\n event SignatureMigrationCanceled(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n event SignatureMigrationCancellationApproved(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n\n error SignatureMigrationFacet__SignerUninitializationFailure();\n error SignatureMigrationFacet__InvalidRouteWithGuardian();\n error SignatureMigrationFacet__InvalidKeyType();\n error SignatureMigrationFacet__InsufficientApprovers();\n error SignatureMigrationFacet__InvalidApproverSignature();\n error SignatureMigrationFacet__InvalidGuardian();\n error SignatureMigrationFacet__NonExistentApprover();\n error SignatureMigrationFacet__InvalidMigrationPeriod();\n error SignatureMigrationFacet__NonexistentMigration();\n error SignatureMigrationFacet__MigrationPeriodNotOver();\n error SignatureMigrationFacet__InvalidArrayLength();\n error SignatureMigrationFacet__InvalidApprovalValidationPeriod();\n error SignatureMigrationFacet__CannotRevokeUnapproved();\n error SignatureMigrationFacet__LackOfOwnerApproval();\n error SignatureMigrationFacet__OwnerAlreadyApproved();\n error SignatureMigrationFacet__NonExistentVerificationFacet();\n error SignatureMigrationFacet__DuplicateApproval();\n\n function migrateSignatureScheme(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function migrateSignatureSchemeWithGuardian(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors,\n address[] calldata approvers,\n bytes[] calldata signatures\n ) external;\n\n function approveSignatureSchemeMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function revokeSignatureMigrationApproval(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function finalizeSignatureMigration() external;\n\n function approveCancelSignatureMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function cancelSignatureMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function getApprovalMigrationKeyHash(\n bytes memory recoveryPublicKey,\n address newVerificationFacet,\n bytes4[] memory newVerificationFuncSelectors,\n string memory saltString\n ) external view returns (bytes32);\n\n function getMigrationOwnerApprovalWithTimeValidity(\n bytes32 publicKeyHash\n ) external view returns (bool);\n\n function getMigrationApprovalCountWithTimeValidity(\n bytes32 publicKeyHash\n ) external view returns (uint256);\n\n function isMigrationApproved(\n bytes32 migrationPublicKeyHash,\n address approver\n ) external view returns (bool);\n\n function getMigrationNonce() external view returns (uint128);\n\n function isMigrationPending() external view returns (bool);\n\n function getPendingMigration()\n external\n view\n returns (SignatureMigrationConfig memory);\n}\n" + }, + "contracts/facets/interfaces/IVerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {UserOperation} from \"../../aa-4337/interfaces/UserOperation.sol\";\n\n/**\n * @title Verification Facet Interface\n * @dev Implements logic for user ops signature verification\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface IVerificationFacet {\n event SignerInitialized(bytes);\n event SignerUninitialized();\n\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n error VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n error VerificationFacet__InitializationFailure();\n error VerificationFacet__InvalidFacetMapping();\n\n function initializeSigner(bytes memory) external returns (uint256);\n\n function uninitializeSigner() external returns (uint256);\n\n function validateOwnerSignatureSelector() external view returns (bytes4);\n\n function owner() external view returns (bytes memory);\n\n function isValidKeyType(bytes calldata) external view returns (bool);\n\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) external view returns (uint256);\n}\n" + }, + "contracts/facets/LockFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage, Lock} from \"../libraries/LibAppStorage.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibFacetStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {ILockFacet} from \"./interfaces/ILockFacet.sol\";\n\n/**\n * @title Lock Facet\n * @dev Contract that enables full lock/unlock of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract LockFacet is ILockFacet, Modifiers {\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Locks the account for the lock period. Lock period is defined in the security manager and it's customizable\n * This function can only be called when account is unlocked by owner or guardians\n * @dev This method checks the caller and if the account is currently locked and locks the account after fetching the\n * Lock period from the owner.\n */\n function lock() external override onlyGuardianOrOwner onlyWhenUnlocked {\n uint256 unlockTime = block.timestamp + getLockPeriod();\n ++LibFacetStorage.lockStorage().nonce;\n LibAppStorage.setLock(unlockTime, LockFacet.lock.selector);\n emit Locked(uint64(unlockTime));\n }\n\n /**\n * @notice Locks the account when the account is locked. This function can be called by anyone but must provide the approver address and signature.\n * The approver should be one of the guardians or owner.\n * @dev This method takes the approver address and the signature. After validating the address and the signature, it unlocks the account immediately.\n * Only one of the guardian or owner is required to lock and unlock the account.\n * @param _approver Address of approver approving the unlock of Barz account\n * @param _signature Signature of the approver that signed the msg hash for unlocking the account\n */\n function unlock(\n address _approver,\n bytes calldata _signature\n ) external override onlyWhenLocked {\n if (_approver != address(this) && !LibGuardian.isGuardian(_approver))\n revert LockFacet__InvalidApprover();\n if (\n !SignatureChecker.isValidSignatureNow(\n _approver,\n getUnlockHash(),\n _signature\n )\n ) revert LockFacet__InvalidSignature();\n _unlock();\n }\n\n /**\n * @notice Unlocks the account and increments the lock nonce\n */\n function _unlock() private {\n if (s.locks[INNER_STRUCT].locker != LockFacet.lock.selector)\n revert LockFacet__CannotUnlock();\n ++LibFacetStorage.lockStorage().nonce;\n LibAppStorage.setLock(0, bytes4(0));\n emit Unlocked();\n }\n\n /**\n * @notice Returns the lock period of current Barz account. Lock period information is held by Security Manager\n * @return lockPeriod Uint value of lock period in seconds\n */\n function getLockPeriod() public view override returns (uint256 lockPeriod) {\n lockPeriod = securityManager.lockPeriodOf(address(this));\n if (lockPeriod == 0) revert LockFacet__InvalidRecoveryPeriod();\n }\n\n /**\n * @notice Returns if the account is locked or not\n * @dev This method fetches the current block timestamp and compares that with release time.\n * After checking the timestamp and release time, it returns if the account is still locked or not.\n * @return isLocked_ Uint value of lock period in seconds\n */\n function isLocked() public view override returns (bool isLocked_) {\n isLocked_ = uint64(block.timestamp) < s.locks[INNER_STRUCT].release;\n }\n\n /**\n * @notice Calculates the unlock hash and returns the unlock hash safe from signature reply attack\n * @dev This method calculates the unlock hash with EIP-191 prefix, wallet address, chainID, and nonce\n * It packs the result and packs them and hashes it.\n * @return unlockHash Bytes32 unlock hash\n */\n function getUnlockHash() public view override returns (bytes32 unlockHash) {\n unlockHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n \"Unlock\",\n address(this),\n block.chainid,\n lockNonce()\n )\n )\n )\n );\n }\n\n /**\n * @notice Returns lock nonce of account. Reads nonce from lock storage within facet storage\n * @return lockNonce_ Uint128 value of lock nonce. This is incremented whenever the account is lock/unlocked\n */\n function lockNonce() public view override returns (uint128 lockNonce_) {\n lockNonce_ = LibFacetStorage.lockStorage().nonce;\n }\n\n /**\n * @notice Returns the overall information of current lock\n * @return pendingLock Struct value including all information of pending lock\n */\n function getPendingLock()\n public\n view\n override\n returns (Lock memory pendingLock)\n {\n pendingLock = s.locks[INNER_STRUCT];\n }\n}\n" + }, + "contracts/facets/Modifiers.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {IFacetRegistry} from \"../infrastructure/interfaces/IFacetRegistry.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\n\n/**\n * @title Modifiers\n * @dev Responsible for providing modifiers/util functions to Facet contracts\n * @author David Yongjun Kim (@Powerstream3604)\n */\nabstract contract Modifiers is BarzStorage {\n uint8 constant INNER_STRUCT = 0;\n\n error CallerNotGuardian();\n error CallerNotGuardianOrOwner();\n error DuplicateApprover();\n error ZeroApproverLength();\n error UnregisteredFacetAndSelectors();\n\n /**\n * @notice Modifier to only allow guardian to make a call, reverts if any other entity is the caller\n */\n modifier onlyGuardian() {\n if (!LibGuardian.isGuardian(msg.sender)) revert CallerNotGuardian();\n _;\n }\n\n /**\n * @notice Modifier to only allow guardian or owner to make a call, reverts if any other entity is the caller\n */\n modifier onlyGuardianOrOwner() {\n if (!LibGuardian.isGuardian(msg.sender) && address(this) != msg.sender)\n revert CallerNotGuardianOrOwner();\n _;\n }\n\n /**\n * @notice Checks if the approver address is the array is unique with no duplicate\n * @dev This method loops through the array and checks if a duplicate address exists, it reverts if duplicate address exists\n * @param approvers Array of address\n */\n function _checkApprover(\n address[] memory approvers\n ) internal pure returns (bool) {\n uint256 approverLength = approvers.length;\n if (0 == approverLength) revert ZeroApproverLength();\n for (uint256 i; i < approverLength - 1; ) {\n for (uint256 j = i + 1; j < approverLength; ) {\n if (approvers[i] == approvers[j]) {\n revert DuplicateApprover(); // Found a duplicate\n }\n unchecked {\n ++j;\n }\n }\n unchecked {\n ++i;\n }\n }\n return false; // No duplicates found\n }\n\n /**\n * @notice Checks if the facet getting added or replaced is registered to facet registry\n * @dev This method loops through the cut and checks if the facet getting added/replaced is registered to facet registry\n * @param _diamondCut Array of FacetCut, data for diamondCut defined in EIP-2535\n */\n function _checkFacetCutValidity(\n IDiamondCut.FacetCut[] memory _diamondCut\n ) internal view {\n uint256 diamondCutLength = _diamondCut.length;\n for (uint256 i; i < diamondCutLength; ) {\n if (\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Add ||\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Replace\n ) {\n if (\n !s.facetRegistry.areFacetFunctionSelectorsRegistered(\n _diamondCut[i].facetAddress,\n _diamondCut[i].functionSelectors\n )\n ) revert UnregisteredFacetAndSelectors();\n }\n unchecked {\n ++i;\n }\n }\n }\n}\n" + }, + "contracts/facets/RestrictionsFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, RestrictionsStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {IRestriction} from \"../restrictions/IRestriction.sol\";\nimport {IRestrictionsFacet} from \"./interfaces/IRestrictionsFacet.sol\";\n\n/**\n * @title Restrictions facet\n * @dev Responsible for storing and verifying different kinds of restrictions, for example:\n * - Whitelist / Blacklist\n * - Daily limits\n * - Trading time restrictions\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract RestrictionsFacet is IRestrictionsFacet {\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceRestrictionsInitialize();\n }\n\n /**\n * @notice Intialize restrictions of Barz. Restrictions facet call restriction contracts for restriction validation\n * before each call\n * @param _restrictions The initial array of restrictions.\n * @return initSuccess Int value showing if the initialization of restriction is successful\n */\n function initializeRestrictions(\n address[] calldata _restrictions\n ) public override returns (uint256 initSuccess) {\n LibDiamond.enforceIsSelf();\n LibAppStorage.enforceRestrictionsInitialize();\n\n if (_restrictions.length == 0) {\n // You can't initialize RestrictionsFacet with an empty list of restrictions\n revert RestrictionsFacet__EmptyRestrictionsList();\n }\n for (uint256 i; i < _restrictions.length; ) {\n if (_restrictions[i] == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictions();\n unchecked {\n ++i;\n }\n }\n\n LibFacetStorage.restrictionsStorage().restrictions = _restrictions;\n _updateRestrictionsMap(_restrictions, true);\n initSuccess = 1;\n }\n\n /**\n * @notice Unitialize restrictions of Barz\n * @return uninitSuccess Int value showing if the initialization of restriction is successful\n */\n function uninitializeRestrictions()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibDiamond.enforceIsSelf();\n LibAppStorage.setRestrictionsUninitialized();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n _updateRestrictionsMap(restrictionsStorage.restrictions, false);\n restrictionsStorage.restrictions = new address[](0);\n uninitSuccess = 1;\n }\n\n /**\n * @notice Returns the list of Restrictions contract address\n * @return restrictions Addresses of IRestriction which are currently active\n */\n function getRestrictions()\n public\n view\n override\n returns (address[] memory restrictions)\n {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n restrictions = restrictionsStorage.restrictions;\n }\n\n /**\n * @notice Adds restrictions to Barz with validation on the restriction contract address.\n * This method is only callable by the owner(self).\n * @param _restriction The address of the restriction to be added.\n */\n function addRestriction(address _restriction) external override {\n LibDiamond.enforceIsSelf();\n if (LibDiamond.restrictionsFacet() == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictionsFacet();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n if (_restriction == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictions();\n if (restrictionsStorage.exists[_restriction])\n revert RestrictionsFacet__RestrictionAlreadyExists();\n\n restrictionsStorage.restrictions.push(_restriction);\n restrictionsStorage.exists[_restriction] = true;\n\n emit RestrictionAdded(_restriction);\n }\n\n /**\n * @notice Remove restrictions from Barz if it existed. This method is only callable by the owner(self).\n * @param _restriction The address of the restriction to be removed.\n */\n function removeRestriction(address _restriction) external override {\n LibDiamond.enforceIsSelf();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n if (!restrictionsStorage.exists[_restriction])\n revert RestrictionsFacet__RestrictionNotFound();\n\n address[] storage restrictions = restrictionsStorage.restrictions;\n\n uint256 indexToDelete = restrictions.length;\n uint256 restrictionsLen = restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n if (restrictions[i] == _restriction) {\n indexToDelete = i;\n break;\n }\n unchecked {\n ++i;\n }\n }\n\n if (indexToDelete == 0 && restrictionsLen == 1) {\n revert RestrictionsFacet__RemainingRestrictionsCantBeEmpty();\n } else if (indexToDelete == restrictionsLen) {\n revert RestrictionsFacet__RestrictionNotFound();\n } else {\n restrictions[indexToDelete] = restrictions[restrictionsLen - 1];\n restrictions.pop();\n }\n\n restrictionsStorage.exists[_restriction] = false;\n emit RestrictionRemoved(_restriction);\n }\n\n /**\n * @notice Sets the restrictions address value mapping to true or false when adding/removing restriction contracts\n * @param _restrictions List of restriction contracts address\n * @param _newValue Bool value to flag to the list of restrictions contracts\n */\n function _updateRestrictionsMap(\n address[] memory _restrictions,\n bool _newValue\n ) internal {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n uint restrictionsLen = _restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n restrictionsStorage.exists[_restrictions[i]] = _newValue;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @dev Iterates over all restrictions and verifies each of them with the transaction parameters.\n * @param _from The address of the sender, that will be signing the transaction.\n * @param _to The receiving address.\n * @param _value Amount of ETH to transfer from sender to recipient.\n * @param _calldata Optional field to include arbitrary data.\n * @return 0 if all the checks passed, 1 otherwise.\n */\n function verifyRestrictions(\n address _from,\n address _to,\n uint256 _value,\n bytes calldata _calldata\n ) external returns (uint256) {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n uint restrictionsLen = restrictionsStorage.restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n IRestriction restriction = IRestriction(\n restrictionsStorage.restrictions[i]\n );\n bool checkPassed = restriction.check(_from, _to, _value, _calldata);\n if (!checkPassed) {\n return 1;\n }\n unchecked {\n ++i;\n }\n }\n\n return 0;\n }\n}\n" + }, + "contracts/facets/SignatureMigrationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, SignatureMigrationStorage, SignatureMigrationConfig, SignatureMigrationApprovalConfig, ApprovalConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IDiamondCut} from \"./base/interfaces/IDiamondCut.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {ISignatureMigrationFacet} from \"./interfaces/ISignatureMigrationFacet.sol\";\n\n/**\n * @title Signature Migration Facet\n * @dev Responsible for migrating user signature scheme to a new scheme user sets\n * Which could include\n * - ECDSA on Secp256K1 Curve\n * - ECDSA on Secp256R1 Curve\n * - BLS, Schnorr, etc\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract SignatureMigrationFacet is ISignatureMigrationFacet, Modifiers {\n bytes constant UNINIT_CALL =\n abi.encodeWithSignature(\"uninitializeSigner()\");\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This modifier verifies if the public key format matches with the new verification facet\n * @param _publicKey Bytes of public key to be validated for the new verification facet\n * @param _newVerificationFacet Address of new verification facet\n */\n modifier validateKeyType(\n bytes memory _publicKey,\n address _newVerificationFacet\n ) {\n if (\n !IVerificationFacet(_newVerificationFacet).isValidKeyType(\n _publicKey\n )\n ) revert SignatureMigrationFacet__InvalidKeyType();\n _;\n }\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n // IMPORTANT NOTE: In the client side when they call this function, the func selectors should be sorted in ascending order\n // to prevent different hash with same items in the array\n /**\n * @notice Moves the state of migration to a pending state. When pending state is over after pending period time,\n * Migration can be finalized. This function can only be called by self and when the account is unlocked.\n * @dev This method checks if the caller is self and if guardians exists. It migrates signature request to a pending state\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function migrateSignatureScheme(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n public\n override\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n // Only self contract can call this function\n LibDiamond.enforceIsSelf();\n // Should revert if guardian exist\n if (0 != LibGuardian.guardianCount())\n revert SignatureMigrationFacet__InvalidRouteWithGuardian();\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n // NOTE: Migration requires a pending period & confirmation from owner to prevent a\n // single call changing the ownership of the wallet\n /**\n * @notice Migrate signature scheme when guardians exists. Verifies the signature of guardians and moves migration to pending state.\n * Which can then be finalized when pending period is over. Owner's approval is mandatory for migration to happen\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _approvers List of approvers. This could include owner\n */\n function migrateSignatureSchemeWithGuardian(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n )\n public\n override\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n // Should revert if does not guardian exist\n if (0 == LibGuardian.guardianCount())\n revert SignatureMigrationFacet__InvalidRouteWithGuardian();\n if (_approvers.length != _signatures.length)\n revert SignatureMigrationFacet__InvalidArrayLength();\n\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(migrationPublicKeyHash, _approvers);\n\n bool onChainOwnerApproval = getMigrationOwnerApprovalWithTimeValidity(\n migrationPublicKeyHash\n );\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n\n if (\n _approvers.length +\n getMigrationApprovalCountWithTimeValidity(\n migrationPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert SignatureMigrationFacet__InsufficientApprovers();\n {\n // To prevent Stack too deep\n bool ownerApproved;\n for (uint256 i; i < _approvers.length; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n address(this) != _approvers[i]\n ) revert SignatureMigrationFacet__InvalidGuardian();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert SignatureMigrationFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n migrationPublicKeyHash,\n _signatures[i]\n )\n ) revert SignatureMigrationFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n\n if (!ownerApproved && !onChainOwnerApproval)\n revert SignatureMigrationFacet__LackOfOwnerApproval();\n }\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Internal function that moves signature mgiration to a pending state.\n * @dev This method increments migration nonce and sets the migration in the migration config. Emits events for migration execution\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _migrateSignatureScheme(\n address _newVerificationFacet,\n bytes memory _newPublicKey,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal {\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n\n ++ms.nonce;\n uint64 migrateAfter = uint64(block.timestamp + getMigrationPeriod());\n\n ms.migrationConfigs[INNER_STRUCT] = SignatureMigrationConfig(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n migrateAfter\n );\n\n emit SignatureMigrationExecuted(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors,\n migrateAfter\n );\n }\n\n /**\n * @notice Approves signature scheme migration on-chain. This can be called by owner or guardian only when the account is unlocked.\n * When the threshold of the migration approval passed and owner approval is granted, it automatically moves migration to a pending state\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function approveSignatureSchemeMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n public\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit SignatureMigrationApproved(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n msg.sender,\n approvalValidUntil\n );\n if (\n getMigrationApprovalCountWithTimeValidity(migrationPublicKeyHash) >=\n LibGuardian.majorityOfGuardians() &&\n getMigrationOwnerApprovalWithTimeValidity(migrationPublicKeyHash)\n )\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Revokes the approval of signature migration done on-chain. Emits revoke event when revoked.\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function revokeSignatureMigrationApproval(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n external\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n if (!isMigrationApproved(migrationPublicKeyHash, msg.sender))\n revert SignatureMigrationFacet__CannotRevokeUnapproved();\n\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(false, 0);\n emit SignatureMigrationApprovalRevoked(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n msg.sender\n );\n }\n\n /**\n * @notice Finalizes the pending signature scheme migration. This function can only be called by owner.\n * It removes the facets of the previous verification facet and adds the new verification facet.\n * After finalizing migration, it emits migration event which shows the change of the verification facet\n */\n function finalizeSignatureMigration() external override {\n // NOTE: Only owner can call this function\n LibDiamond.enforceIsSelf();\n\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n\n if (!isMigrationPending())\n revert SignatureMigrationFacet__NonexistentMigration();\n\n if (\n uint64(block.timestamp) <=\n ms.migrationConfigs[INNER_STRUCT].migrateAfter\n ) revert SignatureMigrationFacet__MigrationPeriodNotOver();\n address newVerificationFacet = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationVerificationFacet;\n bytes4[] memory newVerificationFuncSelectors = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationSelectors;\n bytes memory newPublicKey = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationPublicKey;\n\n address prevVerificationFacet = LibLoupe.facetAddress(\n s.validateOwnerSignatureSelector\n );\n if (prevVerificationFacet == address(0))\n revert SignatureMigrationFacet__NonExistentVerificationFacet();\n\n IDiamondCut.FacetCut[] memory UninitCut;\n IDiamondCut.FacetCut[] memory InitCut;\n {\n bytes4[] memory prevVerificationFuncSelectors = LibLoupe\n .facetFunctionSelectors(prevVerificationFacet);\n\n UninitCut = new IDiamondCut.FacetCut[](1);\n InitCut = new IDiamondCut.FacetCut[](1);\n UninitCut[0] = IDiamondCut.FacetCut({\n facetAddress: address(0),\n action: IDiamondCut.FacetCutAction.Remove,\n functionSelectors: prevVerificationFuncSelectors\n });\n InitCut[0] = IDiamondCut.FacetCut({\n facetAddress: newVerificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: newVerificationFuncSelectors\n });\n {\n IDiamondCut.FacetCut[]\n memory facetCuts = new IDiamondCut.FacetCut[](2);\n facetCuts[0] = UninitCut[0];\n facetCuts[1] = InitCut[0];\n _checkFacetCutValidity(facetCuts);\n }\n LibAppStorage.initiateSignerMigration();\n address verificationFacet = address(\n bytes20(\n LibDiamond.diamondStorage().facets[\n s.validateOwnerSignatureSelector\n ]\n )\n );\n\n (bool success, bytes memory result) = verificationFacet\n .delegatecall(UNINIT_CALL);\n require(success, \"MigrationFacet: uninitialize not successful\");\n uint256 validationData = uint256(bytes32(result));\n if (validationData == 0)\n revert SignatureMigrationFacet__SignerUninitializationFailure();\n\n LibDiamond.diamondCut(UninitCut, address(0), \"\");\n }\n {\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n newPublicKey\n );\n\n // Every Verification Facet should comply with initializeSigner(bytes)\n // to be compatible with the Barz contract(for initialization)\n LibDiamond.diamondCut(InitCut, newVerificationFacet, initCall);\n LibAppStorage.finalizeSignerMigration();\n emit SignatureSchemeMigration(\n prevVerificationFacet,\n newVerificationFacet,\n newPublicKey,\n newVerificationFuncSelectors\n );\n }\n }\n\n /**\n * @notice Approve cancellation of signature migration. If cancellation approval passes guardian threshold with owner approval\n * it automatically cancels the migration.\n * @dev This method checks if the caller is one of guardian or owner and sets true for the cancellation hash in the approval config.\n * It internally calls _cancelSignatureMigration for canceling the migration\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function approveCancelSignatureMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n external\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"CancelSignatureMigration\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit SignatureMigrationCancellationApproved(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n if (\n getMigrationApprovalCountWithTimeValidity(migrationPublicKeyHash) >=\n LibGuardian.majorityOfGuardians() &&\n getMigrationOwnerApprovalWithTimeValidity(migrationPublicKeyHash)\n )\n _cancelSignatureMigration(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Verifies the signature of guardians/owner and cancels the signature migration.\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _approvers List of approvers. This could include owner\n */\n function cancelSignatureMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n )\n external\n override\n validateKeyType(_newPublicKey, _newVerificationFacet)\n onlyWhenUnlocked\n {\n if (_approvers.length != _signatures.length)\n revert SignatureMigrationFacet__InvalidArrayLength();\n\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"CancelSignatureMigration\"\n );\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(migrationPublicKeyHash, _approvers);\n\n bool onChainOwnerApproval = getMigrationOwnerApprovalWithTimeValidity(\n migrationPublicKeyHash\n );\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n if (\n _approvers.length +\n getMigrationApprovalCountWithTimeValidity(\n migrationPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert SignatureMigrationFacet__InsufficientApprovers();\n {\n // To prevent stack too deep\n bool ownerApproved;\n for (uint256 i; i < _approvers.length; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n address(this) != _approvers[i]\n ) revert SignatureMigrationFacet__NonExistentApprover();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert SignatureMigrationFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n migrationPublicKeyHash,\n _signatures[i]\n )\n ) revert SignatureMigrationFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n if (!ownerApproved && !onChainOwnerApproval)\n revert SignatureMigrationFacet__LackOfOwnerApproval();\n }\n _cancelSignatureMigration(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Internal function that cancels signature migration.\n * @dev This method increments migration nonce and deletes the migration from the migration config. Emits events for migration cancellation\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _cancelSignatureMigration(\n address _newVerificationFacet,\n bytes memory _newPublicKey,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal {\n if (!isMigrationPending())\n revert SignatureMigrationFacet__NonexistentMigration();\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n ++ms.nonce;\n delete ms.migrationConfigs[INNER_STRUCT];\n emit SignatureMigrationCanceled(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Checks if the facets to be added from new verification facet is registered to facet registry\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _checkMigrationCutValidity(\n address _newVerificationFacet,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal view {\n IDiamondCut.FacetCut[] memory facetCuts = new IDiamondCut.FacetCut[](1);\n facetCuts[0] = IDiamondCut.FacetCut({\n facetAddress: _newVerificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: _newVerificationFuncSelectors\n });\n _checkFacetCutValidity(facetCuts);\n }\n\n /**\n * @notice Returns if the migration is pending of not\n * @dev This method fetches the migration storage and checks if the migrate after is above 0 value\n * @return isPending Bool value that shows if the migration is pending\n */\n function isMigrationPending()\n public\n view\n override\n returns (bool isPending)\n {\n SignatureMigrationStorage storage rs = LibFacetStorage\n .migrationStorage();\n isPending = rs.migrationConfigs[INNER_STRUCT].migrateAfter > 0;\n }\n\n /**\n * @notice Returns the migration hash. This function ensures that this hash is safe from replay attack by including\n * public key, verification facet, function selectors, salt, address, chainId, and nonce.\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _saltString Salt value for generating the migration hash\n * @return migrationKeyHash Bytes32 string of the migration key hash\n */\n function getApprovalMigrationKeyHash(\n bytes memory _newPublicKey,\n address _newVerificationFacet,\n bytes4[] memory _newVerificationFuncSelectors,\n string memory _saltString\n ) public view override returns (bytes32 migrationKeyHash) {\n migrationKeyHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n _newPublicKey,\n _newVerificationFacet,\n keccak256(abi.encode(_newVerificationFuncSelectors)),\n _saltString,\n address(this),\n block.chainid,\n LibFacetStorage.migrationStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Checks if the owner approved the hash for migration\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @return isApprovedByOwner Bool value of showing if the owner approved it or not\n */\n function getMigrationOwnerApprovalWithTimeValidity(\n bytes32 _migrationPublicKeyHash\n ) public view override returns (bool isApprovedByOwner) {\n isApprovedByOwner = isMigrationApproved(\n _migrationPublicKeyHash,\n address(this)\n );\n }\n\n /**\n * @notice Checks how many of the guardians approved the migration hash\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @return approvalCount Number of approvals\n */\n function getMigrationApprovalCountWithTimeValidity(\n bytes32 _migrationPublicKeyHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardiansLength = guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n if (isMigrationApproved(_migrationPublicKeyHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n return approvalCount;\n }\n\n /**\n * @notice Checks if the migration is approved by the given approver\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @param _approver Address of approver\n * @return isApproved Bool value if migration hash is approved\n */\n function isMigrationApproved(\n bytes32 _migrationPublicKeyHash,\n address _approver\n ) public view override returns (bool isApproved) {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n isApproved = (ms\n .isMigrationApproved[_migrationPublicKeyHash][_approver].isApproved &&\n block.timestamp <\n ms\n .isMigrationApproved[_migrationPublicKeyHash][_approver]\n .validUntil);\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _migrationPublicKeyHash Hash of migration information\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _migrationPublicKeyHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isMigrationApproved(_migrationPublicKeyHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert SignatureMigrationFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the migration period of this wallet\n * @dev This method fetches the migration period from the security manager\n * @return migrationPeriod Migration period of Barz contract fetched from security manager\n */\n function getMigrationPeriod()\n internal\n view\n returns (uint128 migrationPeriod)\n {\n migrationPeriod = securityManager.migrationPeriodOf(address(this));\n if (migrationPeriod == 0)\n revert SignatureMigrationFacet__InvalidMigrationPeriod();\n }\n\n /**\n * @notice Returns the validation period of this wallet\n * @dev This method fetches the validation period from the security manager\n * @return approvalValidationPeriod Validation period of Barz contract fetched from security manager\n */\n function getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod == 0)\n revert SignatureMigrationFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the migration nonce of this wallet\n * @dev This method fetches the nonce from migration storage\n * @return migrationNonce Nonce of migration to protect from reply attacks\n */\n function getMigrationNonce()\n public\n view\n override\n returns (uint128 migrationNonce)\n {\n migrationNonce = LibFacetStorage.migrationStorage().nonce;\n }\n\n /**\n * @notice Returns the migration configuration of this wallet\n * @dev This method fetches the migration config from the migration storage\n * @return pendingMigrationConfig Migration config currently pending for signature migration\n */\n function getPendingMigration()\n external\n view\n override\n returns (SignatureMigrationConfig memory pendingMigrationConfig)\n {\n pendingMigrationConfig = LibFacetStorage\n .migrationStorage()\n .migrationConfigs[INNER_STRUCT];\n }\n}\n" + }, + "contracts/facets/TokenReceiverFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {IERC1155Receiver} from \"../interfaces/ERC/IERC1155Receiver.sol\";\nimport {IERC677Receiver} from \"../interfaces/ERC/IERC677Receiver.sol\";\n\n/**\n * @title TokenReceiver Facet\n * @dev Contract that enables receiving ERC721/ERC1155/ERC777/ERC677 Tokens with safe transfer\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract TokenReceiverFacet is\n IERC721Receiver,\n IERC1155Receiver,\n IERC777Recipient,\n IERC677Receiver\n{\n /**\n * @notice Handles ERC721 Token callback.\n * return Standardized onERC721Received return value.\n */\n function onERC721Received(\n address,\n address,\n uint256,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC721Receiver.onERC721Received.selector;\n }\n\n /**\n * @notice Handles ERC1155 Token callback.\n * return Standardized onERC1155Received return value.\n */\n function onERC1155Received(\n address,\n address,\n uint256,\n uint256,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC1155Receiver.onERC1155Received.selector;\n }\n\n /**\n * @notice Handles ERC1155 Token batch callback.\n * return Standardized onERC1155BatchReceived return value.\n */\n function onERC1155BatchReceived(\n address,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC1155Receiver.onERC1155BatchReceived.selector;\n }\n\n /**\n * @notice Handles ERC777 Token callback.\n * Does not return value, empty implementation.\n */\n function tokensReceived(\n address,\n address,\n address,\n uint256,\n bytes calldata,\n bytes calldata\n ) external pure override {}\n\n /**\n * @notice Handles ERC677 Token callback.\n * return true.\n */\n function onTokenTransfer(\n address,\n uint256,\n bytes calldata\n ) external pure override returns (bool) {\n return true;\n }\n}\n" + }, + "contracts/facets/verification/MultiSigFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {UserOperation} from \"../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../../libraries/LibLoupe.sol\";\nimport {LibAppStorage} from \"../../libraries/LibAppStorage.sol\";\nimport {LibMultiSigStorage, MultiSigStorage} from \"../../libraries/LibMultiSigStorage.sol\";\nimport {IERC1271} from \"../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../interfaces/IVerificationFacet.sol\";\nimport {IMultiSigFacet} from \"../interfaces/IMultiSigFacet.sol\";\n\n/**\n * @title Multi-sig facet\n * @dev Multi-signature Facet with custom threshold.\n * Wallet that adds this facet becomes a multi-sig wallet.\n * Reference signature_format.md documentation for Multi-sig facet details\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract MultiSigFacet is IMultiSigFacet, IVerificationFacet, IERC1271 {\n using ECDSA for bytes32;\n\n address public immutable self;\n\n address internal constant SENTINEL_OWNERS = address(0x1);\n uint256 internal constant ADDRESS = 20;\n uint256 internal constant SIG_TYPE = 1;\n uint256 internal constant SIG_LEN = 4;\n uint256 internal constant THRESHOLD = 4;\n uint256 internal constant INVALID_SIG = 1;\n uint256 internal constant VALID_SIG = 0;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in Multisig Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the right format and initializes signer storage in k1 storage.\n * @param _owners Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _owners\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n\n if (!isValidKeyType(_owners)) revert MultiSigFacet__InvalidInitData();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n uint256 threshold = uint256(uint32(bytes4(_owners)));\n uint256 ownerCount = (_owners.length - THRESHOLD) / ADDRESS;\n\n if (threshold == 0) revert MultiSigFacet__InvalidThreshold();\n if (ownerCount == 0) revert MultisigFacet__InvalidOwnerCount();\n\n address currentOwner = SENTINEL_OWNERS;\n uint256 ptr = THRESHOLD;\n address owner_;\n for (uint256 i; i < ownerCount; ) {\n owner_ = address(bytes20(_owners[ptr:ptr + ADDRESS]));\n ptr += ADDRESS;\n if (\n owner_ == address(0) ||\n owner_ == SENTINEL_OWNERS ||\n owner_ == address(this) ||\n owner_ == currentOwner\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[owner_] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n\n ms.owners[currentOwner] = owner_;\n currentOwner = owner_;\n\n unchecked {\n ++i;\n }\n }\n ms.owners[currentOwner] = SENTINEL_OWNERS;\n ms.ownerCount = ownerCount;\n ms.threshold = threshold;\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_owners);\n }\n\n /**\n * @notice Uninitialize signer in K1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n ++ms.counter;\n address[] memory ownerlist = getOwners();\n uint256 ownerlistLength = ownerlist.length;\n for (uint256 i; i < ownerlistLength; ) {\n ms.owners[ownerlist[i]] = address(0);\n unchecked {\n ++i;\n }\n }\n ms.owners[SENTINEL_OWNERS] = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls checkSignatures with\n * user operation hash and signature together with the threshold.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n // Data 1 is invalid, Data 0 is valid\n validationData = checkSignatures(\n userOpHash,\n userOp.signature,\n LibMultiSigStorage.multisigStorage().threshold\n );\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n return this.validateOwnerSignature.selector;\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n uint totalLength = ms.ownerCount * ADDRESS;\n bytes memory result = new bytes(totalLength);\n\n // populate return array\n uint256 index;\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n while (currentOwner != SENTINEL_OWNERS) {\n assembly {\n mstore(\n add(result, add(32, mul(index, ADDRESS))),\n shl(96, currentOwner)\n )\n }\n currentOwner = ms.owners[currentOwner];\n index++;\n }\n\n return result;\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key should comply with the format in the signature_format.md doc\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n uint256 publicKeyLength = _publicKey.length;\n if (\n publicKeyLength < ADDRESS + THRESHOLD ||\n (publicKeyLength - THRESHOLD) % ADDRESS != 0\n ) return false;\n\n uint256 threshold = uint256(uint32(bytes4(_publicKey)));\n uint256 ownerCount = (publicKeyLength - THRESHOLD) / ADDRESS;\n\n isValid = !(ownerCount < threshold || threshold == 0);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes calldata _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (checkSignatures(\n _hash,\n _signature,\n LibMultiSigStorage.multisigStorage().threshold\n ) == VALID_SIG)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n\n /**\n * @notice Validates the format of the signature and verifies if the signature is signed by the expected key.\n * Reference signature_format.md doc for details about signature format and signature types\n * @param _dataHash Bytes value of data hash signed by the owners\n * @param _signatures Bytes value of signature which should comply with signature format\n * @param _threshold Uint256 value of current Multi-sig Barz's threshold\n */\n function checkSignatures(\n bytes32 _dataHash,\n bytes calldata _signatures,\n uint256 _threshold\n ) public view returns (uint256) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n address lastOwner = address(0);\n address currentOwner;\n bytes memory signature;\n uint256 signatureType;\n uint256 nextOffset;\n uint256 i;\n for (i; i < _threshold; ) {\n (\n currentOwner,\n signature,\n signatureType,\n nextOffset\n ) = splitSignatures(_signatures, nextOffset);\n if (nextOffset == 0 && i + 1 < _threshold) return INVALID_SIG;\n if (signatureType == 1) {\n // If signatureType is 1 then it is default dataHash signed.\n // This also includes the contract signature\n if (\n !SignatureChecker.isValidSignatureNow(\n currentOwner,\n _dataHash,\n signature\n )\n ) return INVALID_SIG;\n } else if (signatureType == 2) {\n // If signatureType is 2 then it is an approved hash\n if (ms.approvedHashes[ms.counter][currentOwner][_dataHash] == 0)\n return INVALID_SIG;\n } else if (signatureType == 3) {\n // If signatureType is 3 then it is a signed message hash\n // This also includes the contract signature\n bytes32 msgHash = _dataHash.toEthSignedMessageHash();\n if (\n !SignatureChecker.isValidSignatureNow(\n currentOwner,\n msgHash,\n signature\n )\n ) return INVALID_SIG;\n } else revert MultiSigFacet__InvalidRoute();\n if (\n currentOwner <= lastOwner ||\n ms.owners[currentOwner] == address(0) ||\n currentOwner == SENTINEL_OWNERS\n ) return INVALID_SIG;\n lastOwner = currentOwner;\n\n unchecked {\n ++i;\n }\n }\n return VALID_SIG;\n }\n\n /**\n * @notice Split signatures into each individual signatures. Should comply with signature format to be split\n * @param _signatures Bytes value of signature\n * @param _nextOffset Uint256 value of next offset to start splitting the signature\n */\n function splitSignatures(\n bytes calldata _signatures,\n uint256 _nextOffset\n )\n public\n pure\n returns (\n address owner_,\n bytes memory signature,\n uint256 signatureType,\n uint256 nextOffset\n )\n {\n uint256 signaturesLength = _signatures.length;\n\n if (signaturesLength <= _nextOffset + ADDRESS + SIG_LEN)\n revert MultiSigFacet__InsufficientSignerLength();\n\n owner_ = address(\n bytes20(_signatures[_nextOffset:_nextOffset + ADDRESS])\n );\n\n signatureType = uint256(\n uint8(\n bytes1(\n _signatures[_nextOffset + ADDRESS:_nextOffset +\n ADDRESS +\n SIG_TYPE]\n )\n )\n );\n\n if (signatureType > 3 || signatureType == 0)\n revert MultiSigFacet__InvalidSignatureType();\n uint256 offSet = _nextOffset + ADDRESS + SIG_TYPE;\n uint256 siglen = uint256(\n uint32(bytes4(_signatures[offSet:offSet + SIG_LEN]))\n );\n if (offSet + siglen > signaturesLength)\n revert MultiSigFacet__InvalidSignatureLength();\n\n offSet += SIG_LEN;\n if (offSet + siglen == signaturesLength) nextOffset = 0;\n else nextOffset = offSet + siglen;\n\n signature = _signatures[offSet:offSet + siglen];\n }\n\n /**\n * @notice Approves the hash of userOperation on-chain. This can only be called by owners.\n * @param _hashToApprove Bytes value of UserOperation hash to approve\n */\n function approveHash(bytes32 _hashToApprove) external {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (ms.owners[msg.sender] == address(0))\n revert MultiSigFacet__OnlyOwner();\n\n ms.approvedHashes[ms.counter][msg.sender][_hashToApprove] = 1;\n emit HashApproved(_hashToApprove, msg.sender);\n }\n\n /**\n * @notice Add owner to Barz. Update thresold if threshold is given different from current threshold\n * @dev This can only be done via a Self call.\n * @param _newOwner Address of new owner to be added\n * @param _threshold Uint256 value of threshold\n */\n function addOwner(address _newOwner, uint256 _threshold) external {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (\n _newOwner == address(0) ||\n _newOwner == SENTINEL_OWNERS ||\n _newOwner == address(this)\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_newOwner] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n\n ms.owners[_newOwner] = ms.owners[SENTINEL_OWNERS];\n ms.owners[SENTINEL_OWNERS] = _newOwner;\n ++ms.ownerCount;\n emit OwnerAdded(_newOwner);\n\n if (ms.threshold != _threshold) changeThreshold(_threshold);\n }\n\n /**\n * @notice Remove owner from Barz. Update thresold if threshold is given different from current threshold\n * @dev This can only be done via a Self call.\n * @param _prevOwner Address of owner located right behind the removed owner address in the linked list\n * @param _removedOwner Address of owner to be removed\n * @param _threshold Uint256 value of threshold\n */\n function removeOwner(\n address _prevOwner,\n address _removedOwner,\n uint256 _threshold\n ) external {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (ms.ownerCount - 1 < _threshold)\n revert MultiSigFacet__InvalidThreshold();\n if (_removedOwner == address(0) || _removedOwner == SENTINEL_OWNERS)\n revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_prevOwner] != _removedOwner)\n revert MultiSigFacet__InvalidOwnerPair();\n\n ms.owners[_prevOwner] = ms.owners[_removedOwner];\n ms.owners[_removedOwner] = address(0);\n --ms.ownerCount;\n emit OwnerRemoved(_removedOwner);\n\n if (ms.threshold != _threshold) changeThreshold(_threshold);\n }\n\n /**\n * @notice Swap owner in Barz.\n * @dev This can only be done via a Self call.\n * @param _prevOwner Address of owner located right behind the removed owner address in the linked list\n * @param _oldOwner Address of owner to be removed\n * @param _newOwner Address of owner to be added\n */\n function swapOwner(\n address _prevOwner,\n address _oldOwner,\n address _newOwner\n ) public {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (\n _newOwner == address(0) ||\n _newOwner == SENTINEL_OWNERS ||\n _newOwner == address(this)\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_newOwner] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n if (_oldOwner == address(0) || _oldOwner == SENTINEL_OWNERS)\n revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_prevOwner] != _oldOwner)\n revert MultiSigFacet__InvalidOwnerPair();\n\n ms.owners[_newOwner] = ms.owners[_oldOwner];\n ms.owners[_prevOwner] = _newOwner;\n ms.owners[_oldOwner] = address(0);\n emit OwnerRemoved(_oldOwner);\n emit OwnerAdded(_newOwner);\n }\n\n /**\n * @notice Changes the threshold of the Barz to `_threshold`.\n * @dev This can only be done via a Self call.\n * @param _threshold New threshold\n */\n function changeThreshold(uint256 _threshold) public {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (_threshold > ms.ownerCount || _threshold == 0)\n revert MultiSigFacet__InvalidThreshold();\n\n ms.threshold = _threshold;\n emit ThresholdChanged(_threshold);\n }\n\n /**\n * @notice Checks if the given address is owner\n * @param _owner Address to be checked if it's owner\n * @return isOwner_ Bool value showing if it's owner address\n */\n function isOwner(address _owner) public view returns (bool isOwner_) {\n isOwner_ = (_owner != SENTINEL_OWNERS &&\n LibMultiSigStorage.multisigStorage().owners[_owner] != address(0));\n }\n\n /**\n * @notice Returns the threshold of Barz\n * @return threshold Threshold of the Barz account\n */\n function getThreshold() public view returns (uint256 threshold) {\n threshold = LibMultiSigStorage.multisigStorage().threshold;\n }\n\n /**\n * @notice Returns the list of owner addresses\n * @return owners List of owners\n */\n function getOwners() public view returns (address[] memory owners) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n owners = new address[](ms.ownerCount);\n\n uint256 index;\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n while (currentOwner != SENTINEL_OWNERS) {\n owners[index] = currentOwner;\n currentOwner = ms.owners[currentOwner];\n index++;\n }\n }\n\n /**\n * @notice Returns the previous owner in the linked list\n * @param _owner Address of owner\n * @return prevOwner Address of previous owner\n */\n function getPrevOwner(\n address _owner\n ) public view returns (address prevOwner) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n if (currentOwner == _owner) return SENTINEL_OWNERS;\n while (currentOwner != SENTINEL_OWNERS) {\n if (ms.owners[currentOwner] == _owner) return currentOwner;\n\n currentOwner = ms.owners[currentOwner];\n }\n return address(0);\n }\n\n /**\n * @notice Returns of the owner is approved by given owner address\n * @param _owner Address of owner\n * @param _hash Hash of UserOperation\n * @return isApproved Bool value showing if the hash is approved by owner\n */\n function isApprovedHash(\n address _owner,\n bytes32 _hash\n ) public view returns (bool isApproved) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n isApproved = (ms.approvedHashes[ms.counter][_owner][_hash] == 1);\n }\n}\n" + }, + "contracts/facets/verification/secp256k1/Secp256k1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {UserOperation} from \"../../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibAppStorage} from \"../../../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, Secp256k1VerificationStorage} from \"../../../libraries/LibFacetStorage.sol\";\nimport {LibLoupe} from \"../../../libraries/LibLoupe.sol\";\nimport {IERC1271} from \"../../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../../interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Secp256k1 verification facet\n * @dev Default Ethereum's elliptic curve\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract Secp256k1VerificationFacet is IVerificationFacet, IERC1271 {\n using ECDSA for bytes32;\n error Secp256k1VerificationFacet__InvalidSignerLength();\n address public immutable self;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in K1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\n * @param _publicKey Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _publicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n if (!isValidKeyType(_publicKey))\n revert Secp256k1VerificationFacet__InvalidSignerLength();\n\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(uint160(uint256(keccak256(_publicKey[1:]))));\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_publicKey);\n }\n\n /**\n * @notice Uninitialize signer in K1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\n * signer public key.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n validationData = validateSignature(\n userOp,\n userOpHash,\n k1Storage.signer\n );\n }\n\n /**\n * @notice Validates if the signature of UserOperation is signed by the given signer\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @param signer Address of signer who signed the contract, to be validated\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n address signer\n ) public pure returns (uint256 isValid) {\n bytes32 hash = userOpHash.toEthSignedMessageHash();\n isValid = (signer != hash.recover(userOp.signature)) ? 1 : 0;\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n ownerSignatureValidatorSelector = this.validateOwnerSignature.selector;\n // NOTE: The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory signer) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n signer = abi.encodePacked(k1Storage.signer);\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key length should be 65 in an uncompressed public key format\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (_hash.recover(_signature) ==\n LibFacetStorage.k1Storage().signer)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/Secp256r1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {UserOperation} from \"../../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibAppStorage} from \"../../../libraries/LibAppStorage.sol\";\nimport {LibLoupe} from \"../../../libraries/LibLoupe.sol\";\nimport {LibFacetStorage, Secp256r1VerificationStorage} from \"../../../libraries/LibFacetStorage.sol\";\nimport {Base64} from \"./utils/Base64.sol\";\nimport {LibSecp256r1} from \"./utils/LibSecp256r1.sol\";\nimport {IERC1271} from \"../../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../../interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Secp256r1 verification facet\n * @dev Primarily used to verify user ops signed with passkeys\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract Secp256r1VerificationFacet is IVerificationFacet, IERC1271 {\n error Secp256r1VerificationFacet__InvalidSignerLength();\n address public immutable self;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in R1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\n * @param _publicKey Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _publicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n\n if (!isValidKeyType(_publicKey))\n revert Secp256r1VerificationFacet__InvalidSignerLength();\n\n bytes memory publicKeyCoordinates = _publicKey[1:];\n uint256[2] memory q;\n assembly {\n // Copy the bytes from the input data into the uint256 array\n mstore(q, mload(add(publicKeyCoordinates, 32)))\n mstore(add(q, 32), mload(add(publicKeyCoordinates, 64)))\n }\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n r1Storage.q = q;\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_publicKey);\n }\n\n /**\n * @notice Uninitialize signer in R1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n r1Storage.q = [0, 0];\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\n * signer public key.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n validationData = validateSignature(userOp, userOpHash, r1Storage.q);\n }\n\n /**\n * @notice Validates if the signature of UserOperation is signed by the given signer\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @param q Public Key of signer who signed the contract, to be validated\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256[2] memory q\n ) public view returns (uint256 isValid) {\n isValid = (_validateSignature(q, userOpHash, userOp.signature)) ? 0 : 1;\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n return this.validateOwnerSignature.selector; // validateOwnerSignature(UserOperation calldata userOp,bytes32 userOpHash)\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory signer) {\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n signer = abi.encodePacked(r1Storage.q);\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key should in an uncompressed public key format\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = _validateSignature(\n LibFacetStorage.r1Storage().q,\n _hash,\n _signature\n )\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n\n function _validateSignature(\n uint256[2] memory q,\n bytes32 _hash,\n bytes memory _signature\n ) internal view returns (bool) {\n (\n uint256 rValue,\n uint256 sValue,\n bytes memory authenticatorData,\n string memory clientDataJSONPre,\n string memory clientDataJSONPost\n ) = abi.decode(_signature, (uint256, uint256, bytes, string, string));\n bytes32 clientHash;\n {\n string memory opHashBase64 = Base64.encode(bytes.concat(_hash));\n string memory clientDataJSON = string.concat(\n clientDataJSONPre,\n opHashBase64,\n clientDataJSONPost\n );\n clientHash = sha256(bytes(clientDataJSON));\n }\n bytes32 sigHash = sha256(bytes.concat(authenticatorData, clientHash));\n return LibSecp256r1.Verify(q, rValue, sValue, uint256(sigHash));\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/utils/Base64.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @dev Provides a set of functions to operate with Base64 strings.\n * modified for base64url https://datatracker.ietf.org/doc/html/rfc4648#section-5\n * _Available since v4.5._\n */\nlibrary Base64 {\n /**\n * @dev Base64 Encoding/Decoding Table\n */\n string internal constant _TABLE =\n \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_\";\n\n /**\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\n */\n function encode(bytes memory data) internal pure returns (string memory) {\n /**\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\n */\n if (data.length == 0) return \"\";\n\n // Loads the table into memory\n string memory table = _TABLE;\n\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\n // and split into 4 numbers of 6 bits.\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\n // - `data.length + 2` -> Round up\n // - `/ 3` -> Number of 3-bytes chunks\n // - `4 *` -> 4 characters for each chunk\n uint256 newlength = (data.length * 8) / 6;\n if (data.length % 6 > 0) {\n newlength++;\n }\n string memory result = new string(newlength);\n\n /// @solidity memory-safe-assembly\n assembly {\n // Prepare the lookup table (skip the first \"length\" byte)\n let tablePtr := add(table, 1)\n\n // Prepare result pointer, jump over length\n let resultPtr := add(result, 32)\n\n // Run over the input, 3 bytes at a time\n for {\n let dataPtr := data\n let endPtr := add(data, mload(data))\n } lt(dataPtr, endPtr) {\n\n } {\n // Advance 3 bytes\n dataPtr := add(dataPtr, 3)\n let input := mload(dataPtr)\n\n // To write each character, shift the 3 bytes (18 bits) chunk\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\n // and apply logical AND with 0x3F which is the number of\n // the previous character in the ASCII table prior to the Base64 Table\n // The result is then added to the table to get the character to write,\n // and finally write it in the result pointer but with a left shift\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(18, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(12, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(6, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n }\n }\n\n return result;\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/utils/LibSecp256r1.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n// Heavily inspired from\n// https://github.com/maxrobot/elliptic-solidity/blob/master/contracts/Secp256r1.sol\n// https://github.com/tdrerup/elliptic-curve-solidity/blob/master/contracts/curves/EllipticCurve.sol\n// modified to use precompile 0x05 modexp\n// and modified jacobian double\n// optimisations to avoid to an from from affine and jacobian coordinates\n\n// Additional Elliptic curve Public key / Signature validation added by\n// David Yonjun Kim (@Powerstream3604)\n\nstruct JPoint {\n uint256 x;\n uint256 y;\n uint256 z;\n}\n\nlibrary LibSecp256r1 {\n uint256 constant gx =\n 0x6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296;\n uint256 constant gy =\n 0x4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5;\n uint256 public constant pp =\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF;\n\n uint256 public constant nn =\n 0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551;\n uint256 constant a =\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC;\n uint256 constant b =\n 0x5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B;\n uint256 constant MOST_SIGNIFICANT =\n 0xc000000000000000000000000000000000000000000000000000000000000000;\n\n /*\n * Verify\n * @description - verifies that a public key has signed a given message\n * @param Q - public key coordinates X & Y\n * @param R - signature half R\n * @param S - signature half S\n * @param input - hashed message\n */\n function Verify(\n uint256[2] memory q,\n uint r,\n uint s,\n uint e\n ) internal view returns (bool) {\n if (q[0] > pp - 1 || q[1] > pp - 1) {\n return false;\n }\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\n return false;\n }\n if (\n mulmod(q[1], q[1], pp) !=\n addmod(\n addmod(\n mulmod(q[0], mulmod(q[0], q[0], pp), pp),\n mulmod(a, q[0], pp),\n pp\n ),\n b,\n pp\n )\n ) {\n return false;\n }\n\n JPoint[16] memory points = _preComputeJacobianPoints(q);\n return VerifyWithPrecompute(points, r, s, e);\n }\n\n function VerifyWithPrecompute(\n JPoint[16] memory points,\n uint r,\n uint s,\n uint e\n ) internal view returns (bool) {\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\n return false;\n }\n\n uint w = _primemod(s, nn);\n\n uint u1 = mulmod(e, w, nn);\n uint u2 = mulmod(r, w, nn);\n\n uint x;\n uint y;\n\n (x, y) = ShamirMultJacobian(points, u1, u2);\n return (x == r);\n }\n\n /*\n * Strauss Shamir trick for EC multiplication\n * https://stackoverflow.com/questions/50993471/ec-scalar-multiplication-with-strauss-shamir-method\n * we optimise on this a bit to do with 2 bits at a time rather than a single bit\n * the individual points for a single pass are precomputed\n * overall this reduces the number of additions while keeping the same number of doublings\n */\n function ShamirMultJacobian(\n JPoint[16] memory points,\n uint u1,\n uint u2\n ) internal view returns (uint, uint) {\n uint x = 0;\n uint y = 0;\n uint z = 0;\n uint bits = 128;\n uint index = 0;\n\n while (bits > 0) {\n if (z > 0) {\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\n }\n index =\n ((u1 & MOST_SIGNIFICANT) >> 252) |\n ((u2 & MOST_SIGNIFICANT) >> 254);\n if (index > 0) {\n (x, y, z) = _jAdd(\n x,\n y,\n z,\n points[index].x,\n points[index].y,\n points[index].z\n );\n }\n u1 <<= 2;\n u2 <<= 2;\n bits--;\n }\n (x, y) = _affineFromJacobian(x, y, z);\n return (x, y);\n }\n\n function _preComputeJacobianPoints(\n uint256[2] memory q\n ) internal pure returns (JPoint[16] memory points) {\n points[0] = JPoint(0, 0, 0);\n points[1] = JPoint(q[0], q[1], 1); // u2\n points[2] = _jPointDouble(points[1]);\n points[3] = _jPointAdd(points[1], points[2]);\n\n points[4] = JPoint(gx, gy, 1); // u1Points[1]\n points[5] = _jPointAdd(points[4], points[1]);\n points[6] = _jPointAdd(points[4], points[2]);\n points[7] = _jPointAdd(points[4], points[3]);\n\n points[8] = _jPointDouble(points[4]); // u1Points[2]\n points[9] = _jPointAdd(points[8], points[1]);\n points[10] = _jPointAdd(points[8], points[2]);\n points[11] = _jPointAdd(points[8], points[3]);\n\n points[12] = _jPointAdd(points[4], points[8]); // u1Points[3]\n points[13] = _jPointAdd(points[12], points[1]);\n points[14] = _jPointAdd(points[12], points[2]);\n points[15] = _jPointAdd(points[12], points[3]);\n }\n\n function _jPointAdd(\n JPoint memory p1,\n JPoint memory p2\n ) internal pure returns (JPoint memory) {\n uint x;\n uint y;\n uint z;\n (x, y, z) = _jAdd(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z);\n return JPoint(x, y, z);\n }\n\n function _jPointDouble(\n JPoint memory p\n ) internal pure returns (JPoint memory) {\n uint x;\n uint y;\n uint z;\n (x, y, z) = _modifiedJacobianDouble(p.x, p.y, p.z);\n return JPoint(x, y, z);\n }\n\n /* _affineFromJacobian\n * @desription returns affine coordinates from a jacobian input follows\n * golang elliptic/crypto library\n */\n function _affineFromJacobian(\n uint x,\n uint y,\n uint z\n ) internal view returns (uint ax, uint ay) {\n if (z == 0) {\n return (0, 0);\n }\n\n uint zinv = _primemod(z, pp);\n uint zinvsq = mulmod(zinv, zinv, pp);\n\n ax = mulmod(x, zinvsq, pp);\n ay = mulmod(y, mulmod(zinvsq, zinv, pp), pp);\n }\n\n /*\n * _jAdd\n * @description performs Jacobian addition as defined below:\n * http://www.hyperelliptic.org/EFD/g1p/data/shortw/jacobian/addition/add-2007-bl\n */\n function _jAdd(\n uint p1,\n uint p2,\n uint p3,\n uint q1,\n uint q2,\n uint q3\n ) internal pure returns (uint r1, uint r2, uint r3) {\n if (p3 == 0) {\n r1 = q1;\n r2 = q2;\n r3 = q3;\n\n return (r1, r2, r3);\n } else if (q3 == 0) {\n r1 = p1;\n r2 = p2;\n r3 = p3;\n\n return (r1, r2, r3);\n }\n\n assembly {\n let\n pd\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\n let z1z1 := mulmod(p3, p3, pd) // Z1Z1 = Z1^2\n let z2z2 := mulmod(q3, q3, pd) // Z2Z2 = Z2^2\n\n let u1 := mulmod(p1, z2z2, pd) // U1 = X1*Z2Z2\n let u2 := mulmod(q1, z1z1, pd) // U2 = X2*Z1Z1\n\n let s1 := mulmod(p2, mulmod(z2z2, q3, pd), pd) // S1 = Y1*Z2*Z2Z2\n let s2 := mulmod(q2, mulmod(z1z1, p3, pd), pd) // S2 = Y2*Z1*Z1Z1\n\n let p3q3 := addmod(p3, q3, pd)\n\n if lt(u2, u1) {\n u2 := add(pd, u2) // u2 = u2+pd\n }\n let h := sub(u2, u1) // H = U2-U1\n\n let i := mulmod(0x02, h, pd)\n i := mulmod(i, i, pd) // I = (2*H)^2\n\n let j := mulmod(h, i, pd) // J = H*I\n if lt(s2, s1) {\n s2 := add(pd, s2) // u2 = u2+pd\n }\n let rr := mulmod(0x02, sub(s2, s1), pd) // r = 2*(S2-S1)\n r1 := mulmod(rr, rr, pd) // X3 = R^2\n\n let v := mulmod(u1, i, pd) // V = U1*I\n let j2v := addmod(j, mulmod(0x02, v, pd), pd)\n if lt(r1, j2v) {\n r1 := add(pd, r1) // X3 = X3+pd\n }\n r1 := sub(r1, j2v)\n\n // Y3 = r*(V-X3)-2*S1*J\n let s12j := mulmod(mulmod(0x02, s1, pd), j, pd)\n\n if lt(v, r1) {\n v := add(pd, v)\n }\n r2 := mulmod(rr, sub(v, r1), pd)\n\n if lt(r2, s12j) {\n r2 := add(pd, r2)\n }\n r2 := sub(r2, s12j)\n\n // Z3 = ((Z1+Z2)^2-Z1Z1-Z2Z2)*H\n z1z1 := addmod(z1z1, z2z2, pd)\n j2v := mulmod(p3q3, p3q3, pd)\n if lt(j2v, z1z1) {\n j2v := add(pd, j2v)\n }\n r3 := mulmod(sub(j2v, z1z1), h, pd)\n }\n return (r1, r2, r3);\n }\n\n // Point doubling on the modified jacobian coordinates\n // http://point-at-infinity.org/ecc/Prime_Curve_Modified_Jacobian_Coordinates.html\n function _modifiedJacobianDouble(\n uint x,\n uint y,\n uint z\n ) internal pure returns (uint x3, uint y3, uint z3) {\n if (y == 0) return (0, 0, 0);\n assembly {\n let\n pd\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\n let z2 := mulmod(z, z, pd)\n let az4 := mulmod(\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC,\n mulmod(z2, z2, pd),\n pd\n )\n let y2 := mulmod(y, y, pd)\n let s := mulmod(0x04, mulmod(x, y2, pd), pd)\n let u := mulmod(0x08, mulmod(y2, y2, pd), pd)\n let m := addmod(mulmod(0x03, mulmod(x, x, pd), pd), az4, pd)\n let twos := mulmod(0x02, s, pd)\n let m2 := mulmod(m, m, pd)\n if lt(m2, twos) {\n m2 := add(pd, m2)\n }\n x3 := sub(m2, twos)\n if lt(s, x3) {\n s := add(pd, s)\n }\n y3 := mulmod(m, sub(s, x3), pd)\n if lt(y3, u) {\n y3 := add(pd, y3)\n }\n y3 := sub(y3, u)\n z3 := mulmod(0x02, mulmod(y, z, pd), pd)\n }\n }\n\n // Fermats little theorem https://en.wikipedia.org/wiki/Fermat%27s_little_theorem\n // a^(p-1) = 1 mod p\n // a^(-1) ≅ a^(p-2) (mod p)\n // we then use the precompile bigModExp to compute a^(-1)\n function _primemod(uint value, uint p) internal view returns (uint ret) {\n ret = modexp(value, p - 2, p);\n return ret;\n }\n\n // Wrapper for built-in BigNumber_modexp (contract 0x5) as described here. https://github.com/ethereum/EIPs/pull/198\n function modexp(\n uint _base,\n uint _exp,\n uint _mod\n ) internal view returns (uint ret) {\n // bigModExp(_base, _exp, _mod);\n assembly {\n if gt(_base, _mod) {\n _base := mod(_base, _mod)\n }\n // Free memory pointer is always stored at 0x40\n let freemem := mload(0x40)\n\n mstore(freemem, 0x20)\n mstore(add(freemem, 0x20), 0x20)\n mstore(add(freemem, 0x40), 0x20)\n\n mstore(add(freemem, 0x60), _base)\n mstore(add(freemem, 0x80), _exp)\n mstore(add(freemem, 0xa0), _mod)\n\n let success := staticcall(14000, 0x5, freemem, 0xc0, freemem, 0x20)\n switch success\n case 0 {\n revert(0x0, 0x0)\n }\n default {\n ret := mload(freemem)\n }\n }\n }\n}\n" + }, + "contracts/infrastructure/DefaultFallbackHandler.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC1155Receiver} from \"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\";\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {BaseAccount} from \"../aa-4337/core/BaseAccount.sol\";\nimport {DefaultLibDiamond} from \"../libraries/DefaultLibDiamond.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IAccountFacet} from \"../facets/interfaces/IAccountFacet.sol\";\nimport {IStorageLoupe} from \"../facets/base/interfaces/IStorageLoupe.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IERC677Receiver} from \"../interfaces/ERC/IERC677Receiver.sol\";\nimport {IERC165} from \"../interfaces/ERC/IERC165.sol\";\n\n/**\n * @title DefaultFallbackHandler\n * @dev A default fallback handler for Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DefaultFallbackHandler is IDiamondLoupe {\n /**\n * @notice Sets the middleware diamond for Barz wallet as a fallback handler\n * @dev This contract is also a diamond that holds the default facets to reduce gas cost for wallet activation.\n * Within the constructor this conducts diamond cut to initially setup the diamond. This is a non-upgradeable contract\n * @param _diamondCutFacet Address if diamond cut facet\n * @param _accountFacet Address account facet\n * @param _tokenReceiverFacet Address of token receiver facet\n * @param _diamondLoupeFacet Address of diamond loupe facet\n */\n constructor(\n address _diamondCutFacet,\n address _accountFacet,\n address _tokenReceiverFacet,\n address _diamondLoupeFacet\n ) payable {\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](4);\n bytes4[] memory functionSelectors = new bytes4[](1);\n functionSelectors[0] = IDiamondCut.diamondCut.selector;\n\n bytes4[] memory accountFunctionSelectors = new bytes4[](5);\n accountFunctionSelectors[0] = IAccountFacet.execute.selector;\n accountFunctionSelectors[1] = IAccountFacet.executeBatch.selector;\n accountFunctionSelectors[2] = BaseAccount.validateUserOp.selector;\n accountFunctionSelectors[3] = BaseAccount.getNonce.selector;\n accountFunctionSelectors[4] = BaseAccount.entryPoint.selector;\n\n bytes4[] memory receiverFacetSelectors = new bytes4[](5);\n receiverFacetSelectors[0] = IERC721Receiver.onERC721Received.selector;\n receiverFacetSelectors[1] = IERC1155Receiver.onERC1155Received.selector;\n receiverFacetSelectors[2] = IERC1155Receiver\n .onERC1155BatchReceived\n .selector;\n receiverFacetSelectors[3] = IERC777Recipient.tokensReceived.selector;\n receiverFacetSelectors[4] = IERC677Receiver.onTokenTransfer.selector;\n\n bytes4[] memory loupeFacetSelectors = new bytes4[](9);\n loupeFacetSelectors[0] = IDiamondLoupe.facets.selector;\n loupeFacetSelectors[1] = IDiamondLoupe.facetFunctionSelectors.selector;\n loupeFacetSelectors[2] = IDiamondLoupe.facetAddresses.selector;\n loupeFacetSelectors[3] = IDiamondLoupe.facetAddress.selector;\n loupeFacetSelectors[4] = IERC165.supportsInterface.selector;\n loupeFacetSelectors[5] = IStorageLoupe.facetsFromStorage.selector;\n loupeFacetSelectors[6] = IStorageLoupe\n .facetFunctionSelectorsFromStorage\n .selector;\n loupeFacetSelectors[7] = IStorageLoupe\n .facetAddressesFromStorage\n .selector;\n loupeFacetSelectors[8] = IStorageLoupe.facetAddressFromStorage.selector;\n\n {\n cut[0] = IDiamondCut.FacetCut({\n facetAddress: _diamondCutFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: functionSelectors\n });\n cut[1] = IDiamondCut.FacetCut({\n facetAddress: _accountFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: accountFunctionSelectors\n });\n cut[2] = IDiamondCut.FacetCut({\n facetAddress: _tokenReceiverFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: receiverFacetSelectors\n });\n cut[3] = IDiamondCut.FacetCut({\n facetAddress: _diamondLoupeFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: loupeFacetSelectors\n });\n\n DefaultLibDiamond.diamondCut(cut, address(0), \"\");\n }\n }\n\n /**\n * @notice Returns the facet information of call facets registered to this diamond.\n * @return facets_ The facet struct array including all facet information\n */\n function facets() external view override returns (Facet[] memory facets_) {\n DefaultLibDiamond.DiamondStorage storage ds = DefaultLibDiamond\n .diamondStorage();\n uint256 numFacets = ds.facetAddresses.length;\n facets_ = new Facet[](numFacets);\n for (uint256 i; i < numFacets; ) {\n address facetAddress_ = ds.facetAddresses[i];\n facets_[i].facetAddress = facetAddress_;\n facets_[i].functionSelectors = ds\n .facetFunctionSelectors[facetAddress_]\n .functionSelectors;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Gets all the function selectors provided by a facet.\n * @param _facet The facet address.\n * @return facetFunctionSelectors_\n */\n function facetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n facetFunctionSelectors_ = DefaultLibDiamond\n .diamondStorage()\n .facetFunctionSelectors[_facet]\n .functionSelectors;\n }\n\n /**\n * @notice Get all the facet addresses used by a diamond.\n * @return facetAddresses_\n */\n function facetAddresses()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n facetAddresses_ = DefaultLibDiamond.diamondStorage().facetAddresses;\n }\n\n /** @notice Gets the facet that supports the given selector.\n * @dev If facet is not found return address(0).\n * @param _functionSelector The function selector.\n * @return facetAddress_ The facet address.\n */\n function facetAddress(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n facetAddress_ = DefaultLibDiamond\n .diamondStorage()\n .selectorToFacetAndPosition[_functionSelector]\n .facetAddress;\n }\n}\n" + }, + "contracts/infrastructure/FacetRegistry.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport {IFacetRegistry} from \"./interfaces/IFacetRegistry.sol\";\n\n/**\n * @title Facet Registry\n * @dev Contract to keep track of facets & function selectors addable to user wallets\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract FacetRegistry is IFacetRegistry, Ownable2Step {\n mapping(address => FacetRegistryConfig) private facets;\n\n /**\n * @notice Transfers the ownership of the contract to the given owner\n * @param _owner Address of owner who has access to initialize the default security variables for security manager\n */\n constructor(address _owner) {\n transferOwnership(_owner);\n _transferOwnership(_owner);\n }\n\n /**\n * @dev Registers a facet and it's function selectors to registry\n * @param _facet address of facet\n * @param _facetSelectors list of function selectors of the facet\n */\n function registerFacetFunctionSelectors(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external override onlyOwner {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n for (uint256 i; i < _facetSelectors.length; ) {\n if (facetConfig.info[_facetSelectors[i]].exists)\n revert FacetRegistry__FacetSelectorAlreadyRegistered();\n\n facetConfig.info[_facetSelectors[i]].exists = true;\n facetConfig.info[_facetSelectors[i]].index = uint128(\n facetConfig.selectors.length\n );\n facetConfig.selectors.push(_facetSelectors[i]);\n unchecked {\n ++i;\n }\n }\n emit FacetFunctionSelectorsRegistered(_facet, _facetSelectors);\n }\n\n /**\n * @dev Removes a registered facet and it's corresponding selectors from registry\n * @param _facet address of facet\n * @param _facetSelectors list of function selectors of the facet\n */\n function removeFacetFunctionSelectors(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external override onlyOwner {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n for (uint256 i; i < _facetSelectors.length; ) {\n if (!facetConfig.info[_facetSelectors[i]].exists)\n revert FacetRegistry__UnregisteredFacetSelector();\n\n bytes4 lastSelector = facetConfig.selectors[\n facetConfig.selectors.length - 1\n ];\n if (_facetSelectors[i] != lastSelector) {\n uint128 targetIndex = facetConfig\n .info[_facetSelectors[i]]\n .index;\n facetConfig.selectors[targetIndex] = lastSelector;\n facetConfig.info[lastSelector].index = targetIndex;\n }\n facetConfig.selectors.pop();\n delete facetConfig.info[_facetSelectors[i]];\n\n unchecked {\n ++i;\n }\n }\n emit FacetFunctionSelectorsRemoved(_facet, _facetSelectors);\n }\n\n /**\n * @dev Checks if a facet and it's selectors given is registered to facet registry\n * @param _facet Address of facet\n * @param _facetSelectors List of function selectors of the facet\n */\n function areFacetFunctionSelectorsRegistered(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external view override returns (bool) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n if (_facetSelectors.length == 0) return false;\n for (uint256 i; i < _facetSelectors.length; ) {\n if (!facetConfig.info[_facetSelectors[i]].exists) return false;\n unchecked {\n ++i;\n }\n }\n return true;\n }\n\n /**\n * @dev Checks if a facet and it's selector given is registered to facet registry\n * @param _facet Address of facet\n * @param _facetSelector List of function selectors of the facet\n * @return isRegistered Bool value showing if the selector is registered\n */\n function isFacetFunctionSelectorRegistered(\n address _facet,\n bytes4 _facetSelector\n ) external view override returns (bool isRegistered) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n isRegistered = facetConfig.info[_facetSelector].exists;\n }\n\n /**\n * @dev Get the registered selectors of facet from registry\n * @param _facet Address of facet\n * @return selectors Selectors registered to facet\n */\n function getFacetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory selectors) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n selectors = facetConfig.selectors;\n }\n}\n" + }, + "contracts/infrastructure/interfaces/IFacetRegistry.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Registry Interface\n * @dev Interface for Facet Registry contract to keep track of facets & function selectors addable to user wallets\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IFacetRegistry {\n struct FacetRegistryConfig {\n bytes4[] selectors;\n mapping(bytes4 => FacetInfo) info;\n }\n struct FacetInfo {\n bool exists;\n uint128 index;\n }\n\n event FacetFunctionSelectorsRegistered(\n address facet,\n bytes4[] facetSelectors\n );\n event FacetFunctionSelectorsRemoved(address facet, bytes4[] facetSelectors);\n\n error FacetRegistry__FacetSelectorAlreadyRegistered();\n error FacetRegistry__UnregisteredFacetSelector();\n\n function registerFacetFunctionSelectors(\n address facet,\n bytes4[] calldata facetSelectors\n ) external;\n\n function removeFacetFunctionSelectors(\n address facet,\n bytes4[] calldata facetSelectors\n ) external;\n\n function areFacetFunctionSelectorsRegistered(\n address facet,\n bytes4[] calldata facetSelectors\n ) external view returns (bool);\n\n function isFacetFunctionSelectorRegistered(\n address facet,\n bytes4 facetSelector\n ) external view returns (bool);\n\n function getFacetFunctionSelectors(\n address facet\n ) external view returns (bytes4[] memory);\n}\n" + }, + "contracts/infrastructure/interfaces/ISecurityManager.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Registry Interface\n * @dev Infrastructure contract to manage security parameters of users\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface ISecurityManager {\n error SecurityManager__OutOfBoundary();\n error SecurityManager__CallerNotWallet();\n error SecurityManager__AlreadyIntialized();\n\n function initializeAdditionSecurityPeriod(\n uint128 defaultAdditionSecurityPeriod,\n uint128 minAdditionSecurityPeriod,\n uint128 maxAdditionSecurityPeriod\n ) external;\n\n function initializeRemovalSecurityPeriod(\n uint128 defaultRemovalSecurityPeriod,\n uint128 minRemovalSecurityPeriod,\n uint128 maxRemovalSecurityPeriod\n ) external;\n\n function initializeApprovalValidationPeriod(\n uint128 defaultApprovalValidationPeriod,\n uint128 minApprovalValidationPeriod,\n uint128 maxApprovalValidationPeriod\n ) external;\n\n function initializeMigrationPeriod(\n uint128 defaultMigrationPeriod,\n uint128 minMigrationPeriod,\n uint128 maxMigrationPeriod\n ) external;\n\n function initializeLockPeriod(\n uint128 defaultLockPeriod,\n uint128 minLockPeriod,\n uint128 maxLockPeriod\n ) external;\n\n function initializeRecoveryPeriod(\n uint128 defaultRecoveryPeriod,\n uint128 minRecoveryPeriod,\n uint128 maxRecoveryPeriod\n ) external;\n\n function initializeSecurityWindow(\n uint128 defaultSecurityWindow,\n uint128 minSecurityWindow,\n uint128 maxSecurityWindow\n ) external;\n\n function setAdditionSecurityPeriod(\n address wallet,\n uint128 additionSecurityPeriod\n ) external;\n\n function setRemovalSecurityPeriod(\n address wallet,\n uint128 removalSecurityPeriod\n ) external;\n\n function setSecurityWindow(address wallet, uint128 securityWindow) external;\n\n function setRecoveryPeriod(address wallet, uint128 recoveryPeriod) external;\n\n function setLockPeriod(address wallet, uint128 lockPeriod) external;\n\n function setApprovalValidationPeriod(\n address wallet,\n uint128 approvalValidationPeriod\n ) external;\n\n function setMigrationPeriod(\n address wallet,\n uint128 migrationPeriod\n ) external;\n\n function additionSecurityPeriodOf(\n address wallet\n ) external view returns (uint128);\n\n function removalSecurityPeriodOf(\n address wallet\n ) external view returns (uint128);\n\n function securityWindowOf(address wallet) external view returns (uint128);\n\n function recoveryPeriodOf(address wallet) external view returns (uint128);\n\n function lockPeriodOf(address wallet) external view returns (uint128);\n\n function migrationPeriodOf(address wallet) external view returns (uint128);\n\n function approvalValidationPeriodOf(\n address wallet\n ) external view returns (uint128);\n}\n" + }, + "contracts/infrastructure/RemoteStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IGuardianFacet} from \"../facets/interfaces/IGuardianFacet.sol\";\n\n/**\n * @title Remote Storage\n * @dev Remote storage allows you to associate addresses with an array of addresses on a standalone smart contract.\n * This could be useful when you don't want to use the local diamond storage for some purpose.\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\nabstract contract RemoteStorage {\n struct StorageConfig {\n address[] addresses;\n mapping(address => Info) info;\n }\n\n struct Info {\n bool exists;\n uint128 index;\n }\n\n mapping(address => StorageConfig) internal configs;\n\n event Added(address _address);\n event Removed(address _address);\n\n error RemoteStorage__CallerNotOwner();\n error RemoteStorage__CallerNotGuardianOrOwner();\n error RemoteStorage__AlreadyExists();\n error RemoteStorage__NotFound();\n error RemoteStorage__CallerNotGuardian();\n\n bytes4 constant IS_GUARDIAN_SELECTOR =\n bytes4(keccak256(\"isGuardian(address)\"));\n bytes4 constant GUARDIAN_COUNT = bytes4(keccak256(\"guardianCount()\"));\n\n /**\n * @notice Modifier to only allow the self to call. Reverts otherwise\n */\n modifier onlyWallet(address _wallet) {\n if (msg.sender != _wallet) revert RemoteStorage__CallerNotOwner();\n _;\n }\n\n /**\n * @notice Enfore the callet to be wallet of guardian of the wallet\n * @param _wallet Address of wallet\n */\n function enforceGuardianOrWallet(address _wallet) internal view {\n if (msg.sender == _wallet) return;\n address facetAddress = IDiamondLoupe(_wallet).facetAddress(\n IS_GUARDIAN_SELECTOR\n );\n if (facetAddress != address(0))\n if (IGuardianFacet(_wallet).isGuardian(msg.sender)) return;\n revert RemoteStorage__CallerNotGuardianOrOwner();\n }\n\n /**\n * @notice Enforce the caller to be wallet IF guardians doesn't exists and only guardian when guardians exists\n * @param _wallet Target wallet address to be handled by infrastructure contracts\n */\n function enforceWalletOrGuardianIfExists(address _wallet) internal view {\n address facetAddress;\n if (msg.sender == _wallet) {\n facetAddress = IDiamondLoupe(_wallet).facetAddress(GUARDIAN_COUNT);\n if (facetAddress == address(0)) return;\n uint256 guardianCount = IGuardianFacet(_wallet).guardianCount();\n if (guardianCount != 0) revert RemoteStorage__CallerNotGuardian();\n return;\n }\n facetAddress = IDiamondLoupe(_wallet).facetAddress(\n IS_GUARDIAN_SELECTOR\n );\n if (facetAddress != address(0))\n if (IGuardianFacet(_wallet).isGuardian(msg.sender)) return;\n\n revert RemoteStorage__CallerNotGuardianOrOwner();\n }\n\n /**\n * @notice Add address to storage and reverts if the address already exists.\n * This is an internal function callable from contracts that inherit this abstract contract\n * @param _wallet Address of wallet to add the address\n * @param _address Address to be added to wallet\n */\n function addAddress(address _wallet, address _address) internal {\n StorageConfig storage config = configs[_wallet];\n if (config.info[_address].exists) revert RemoteStorage__AlreadyExists();\n\n config.info[_address].exists = true;\n config.info[_address].index = uint128(config.addresses.length);\n config.addresses.push(_address);\n\n emit Added(_address);\n }\n\n /**\n * @notice Remove address from storage and reverts if the address already exists.\n * This is an internal function callable from contracts that inherit this abstract contract\n * @param _wallet Address of wallet to remove the address\n * @param _address Address to be removed from wallet\n */\n function removeAddress(address _wallet, address _address) internal {\n StorageConfig storage config = configs[_wallet];\n if (!config.info[_address].exists) revert RemoteStorage__NotFound();\n\n address lastAddress = config.addresses[config.addresses.length - 1];\n if (_address != lastAddress) {\n uint128 targetIndex = config.info[_address].index;\n config.addresses[targetIndex] = lastAddress;\n config.info[lastAddress].index = targetIndex;\n }\n config.addresses.pop();\n delete config.info[_address];\n\n emit Removed(_address);\n }\n\n /**\n * @notice Returns the address added to the given wallet\n * @param _wallet Address of wallet to fetch the addresses added to it\n * @return addresses List of addresses added to the wallet\n */\n function getAddresses(\n address _wallet\n ) internal view returns (address[] memory addresses) {\n StorageConfig storage config = configs[_wallet];\n addresses = new address[](config.addresses.length);\n uint addressesLen = config.addresses.length;\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns bool value checking if the address exists in the given wallet address\n * @param _wallet Wallet address to check\n * @param _address Address to fetch if the address if added to given wallet\n * @return exists_ Bool value showing if the address exists in wallet\n */\n function exists(\n address _wallet,\n address _address\n ) internal view returns (bool exists_) {\n exists_ = configs[_wallet].info[_address].exists;\n }\n\n /**\n * @notice Returns the number of addresses added to the wallet\n * @param _wallet Address of wallet to check\n * @return count_ Number of addresses added to wallet\n */\n function count(address _wallet) internal view returns (uint256 count_) {\n count_ = configs[_wallet].addresses.length;\n }\n}\n" + }, + "contracts/infrastructure/SecurityManager.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport {ISecurityManager} from \"./interfaces/ISecurityManager.sol\";\n\n/**\n * @title Security Manager\n * @dev Infrastructure contract to manage security parameters of users\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract SecurityManager is ISecurityManager, Ownable2Step {\n uint128 public minAdditionSecurityPeriod;\n uint128 public maxAdditionSecurityPeriod;\n uint128 private defaultAdditionSecurityPeriod;\n\n uint128 public minRemovalSecurityPeriod;\n uint128 public maxRemovalSecurityPeriod;\n uint128 private defaultRemovalSecurityPeriod;\n\n uint128 public minSecurityWindow;\n uint128 public maxSecurityWindow;\n uint128 private defaultSecurityWindow;\n\n uint128 public minRecoveryPeriod;\n uint128 public maxRecoveryPeriod;\n uint128 private defaultRecoveryPeriod;\n\n uint128 public minLockPeriod;\n uint128 public maxLockPeriod;\n uint128 private defaultLockPeriod;\n\n uint128 public minApprovalValidationPeriod;\n uint128 public maxApprovalValidationPeriod;\n uint128 private defaultApprovalValidationPeriod;\n\n uint128 public minMigrationPeriod;\n uint128 public maxMigrationPeriod;\n uint128 private defaultMigrationPeriod;\n\n bool public _isAdditionSecurityPeriodInitialized;\n bool public _isRemovalSecurityPeriodInitialized;\n bool public _isSecurityWindowInitialized;\n bool public _isRecoveryPeriodInitialized;\n bool public _isLockPeriodInitialized;\n bool public _isApprovalValidationPeriodInitialized;\n bool public _isMigrationPeriodInitialized;\n\n mapping(address => CustomSecurityConfig) securityConfigs;\n\n struct CustomSecurityConfig {\n uint128 additionSecurityPeriod;\n uint128 removalSecurityPeriod;\n uint128 securityWindow;\n uint128 recoveryPeriod;\n uint128 lockPeriod;\n uint128 approvalValidationPeriod;\n uint128 migrationPeriod;\n }\n\n /**\n * @notice Modifier to only allow wallet itself to make a call to wallet\n */\n modifier onlyWallet(address _wallet) {\n if (msg.sender != _wallet) revert SecurityManager__CallerNotWallet();\n _;\n }\n\n /**\n * @notice Modifier to revert if the variable is already initialized\n */\n modifier initializer(bool _isInitialized) {\n if (_isInitialized) revert SecurityManager__AlreadyIntialized();\n _;\n }\n\n /**\n * @notice Transfers the ownership of the contract to the given owner\n * @param _owner Address of owner who has access to initialize the default security variables for security manager\n */\n constructor(address _owner) {\n transferOwnership(_owner);\n _transferOwnership(_owner);\n }\n\n /**\n * @notice Sets the initial default/min/max addition security period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultAdditionSecurityPeriod Default Addition Security Period for all Barz contracts\n * @param _minAdditionSecurityPeriod Minimum Addition Security Period for all Barz contracts\n * @param _maxAdditionSecurityPeriod Maximum Addition Security Period for all Barz contracts\n */\n function initializeAdditionSecurityPeriod(\n uint128 _defaultAdditionSecurityPeriod,\n uint128 _minAdditionSecurityPeriod,\n uint128 _maxAdditionSecurityPeriod\n )\n external\n override\n onlyOwner\n initializer(_isAdditionSecurityPeriodInitialized)\n {\n _isAdditionSecurityPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultAdditionSecurityPeriod,\n _minAdditionSecurityPeriod,\n _maxAdditionSecurityPeriod\n );\n defaultAdditionSecurityPeriod = _defaultAdditionSecurityPeriod;\n minAdditionSecurityPeriod = _minAdditionSecurityPeriod;\n maxAdditionSecurityPeriod = _maxAdditionSecurityPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max removal security period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultRemovalSecurityPeriod Default Removal Security Period for all Barz contracts\n * @param _minRemovalSecurityPeriod Minimum Removal Security Period for all Barz contracts\n * @param _maxRemovalSecurityPeriod Maximum Removal Security Period for all Barz contracts\n */\n function initializeRemovalSecurityPeriod(\n uint128 _defaultRemovalSecurityPeriod,\n uint128 _minRemovalSecurityPeriod,\n uint128 _maxRemovalSecurityPeriod\n )\n external\n override\n onlyOwner\n initializer(_isRemovalSecurityPeriodInitialized)\n {\n _isRemovalSecurityPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultRemovalSecurityPeriod,\n _minRemovalSecurityPeriod,\n _maxRemovalSecurityPeriod\n );\n defaultRemovalSecurityPeriod = _defaultRemovalSecurityPeriod;\n minRemovalSecurityPeriod = _minRemovalSecurityPeriod;\n maxRemovalSecurityPeriod = _maxRemovalSecurityPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/maxd security window for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultSecurityWindow Default Security Window for all Barz contracts\n * @param _minSecurityWindow Minimum Security Window for all Barz contracts\n * @param _maxSecurityWindow Maximum Security Window for all Barz contracts\n */\n function initializeSecurityWindow(\n uint128 _defaultSecurityWindow,\n uint128 _minSecurityWindow,\n uint128 _maxSecurityWindow\n ) external override onlyOwner initializer(_isSecurityWindowInitialized) {\n _isSecurityWindowInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultSecurityWindow,\n _minSecurityWindow,\n _maxSecurityWindow\n );\n defaultSecurityWindow = _defaultSecurityWindow;\n minSecurityWindow = _minSecurityWindow;\n maxSecurityWindow = _maxSecurityWindow;\n }\n\n /**\n * @notice Sets the initial default/min/max recovery period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultRecoveryPeriod Default Recovery Period for all Barz contracts\n * @param _minRecoveryPeriod Minimum Recovery Period for all Barz contracts\n * @param _maxRecoveryPeriod Maximum Recovery Period for all Barz contracts\n */\n function initializeRecoveryPeriod(\n uint128 _defaultRecoveryPeriod,\n uint128 _minRecoveryPeriod,\n uint128 _maxRecoveryPeriod\n ) external override onlyOwner initializer(_isRecoveryPeriodInitialized) {\n _isRecoveryPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultRecoveryPeriod,\n _minRecoveryPeriod,\n _maxRecoveryPeriod\n );\n defaultRecoveryPeriod = _defaultRecoveryPeriod;\n minRecoveryPeriod = _minRecoveryPeriod;\n maxRecoveryPeriod = _maxRecoveryPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max lock period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultLockPeriod Default Lock Period for all Barz contracts\n * @param _minLockPeriod Minimum Lock Period for all Barz contracts\n * @param _maxLockPeriod Maximum Lock Period for all Barz contracts\n */\n function initializeLockPeriod(\n uint128 _defaultLockPeriod,\n uint128 _minLockPeriod,\n uint128 _maxLockPeriod\n ) external override onlyOwner initializer(_isLockPeriodInitialized) {\n _isLockPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultLockPeriod,\n _minLockPeriod,\n _maxLockPeriod\n );\n defaultLockPeriod = _defaultLockPeriod;\n minLockPeriod = _minLockPeriod;\n maxLockPeriod = _maxLockPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max approval validation period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultApprovalValidationPeriod Default Approval Validation Period for all Barz contracts\n * @param _minApprovalValidationPeriod Minimum Approval Validation Period for all Barz contracts\n * @param _maxApprovalValidationPeriod Maximum Approval Validation Period for all Barz contracts\n */\n function initializeApprovalValidationPeriod(\n uint128 _defaultApprovalValidationPeriod,\n uint128 _minApprovalValidationPeriod,\n uint128 _maxApprovalValidationPeriod\n )\n external\n override\n onlyOwner\n initializer(_isApprovalValidationPeriodInitialized)\n {\n _isApprovalValidationPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultApprovalValidationPeriod,\n _minApprovalValidationPeriod,\n _maxApprovalValidationPeriod\n );\n defaultApprovalValidationPeriod = _defaultApprovalValidationPeriod;\n minApprovalValidationPeriod = _minApprovalValidationPeriod;\n maxApprovalValidationPeriod = _maxApprovalValidationPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max migration period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultMigrationPeriod Default Migration Period for all Barz contracts\n * @param _minMigrationPeriod Minimum Migration Period for all Barz contracts\n * @param _maxMigrationPeriod Maximum Migration Period for all Barz contracts\n */\n function initializeMigrationPeriod(\n uint128 _defaultMigrationPeriod,\n uint128 _minMigrationPeriod,\n uint128 _maxMigrationPeriod\n ) external override onlyOwner initializer(_isMigrationPeriodInitialized) {\n _isMigrationPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultMigrationPeriod,\n _minMigrationPeriod,\n _maxMigrationPeriod\n );\n defaultMigrationPeriod = _defaultMigrationPeriod;\n minMigrationPeriod = _minMigrationPeriod;\n maxMigrationPeriod = _maxMigrationPeriod;\n }\n\n /**\n * @notice Wallet owner sets the addition security period for the wallet. Only the owner of wallet can call this function.\n * The addition security period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _additionSecurityPeriod Custom Addition Security Period for the wallet\n */\n function setAdditionSecurityPeriod(\n address _wallet,\n uint128 _additionSecurityPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _additionSecurityPeriod,\n minAdditionSecurityPeriod,\n maxAdditionSecurityPeriod\n );\n securityConfigs[_wallet]\n .additionSecurityPeriod = _additionSecurityPeriod;\n }\n\n /**\n * @notice Wallet owner sets the removal security period for the wallet. Only the owner of wallet can call this function.\n * The removal security period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _removalSecurityPeriod Custom Removal Security Period for the wallet\n */\n function setRemovalSecurityPeriod(\n address _wallet,\n uint128 _removalSecurityPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _removalSecurityPeriod,\n minRemovalSecurityPeriod,\n maxRemovalSecurityPeriod\n );\n securityConfigs[_wallet].removalSecurityPeriod = _removalSecurityPeriod;\n }\n\n /**\n * @notice Wallet owner sets the security window for the wallet. Only the owner of wallet can call this function.\n * The security window should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _securityWindow Custom Security Window for the wallet\n */\n function setSecurityWindow(\n address _wallet,\n uint128 _securityWindow\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _securityWindow,\n minSecurityWindow,\n maxSecurityWindow\n );\n securityConfigs[_wallet].securityWindow = _securityWindow;\n }\n\n /**\n * @notice Wallet owner sets the recovery period for the wallet. Only the owner of wallet can call this function.\n * The recovery period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _recoveryPeriod Custom recovery period for the wallet\n */\n function setRecoveryPeriod(\n address _wallet,\n uint128 _recoveryPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _recoveryPeriod,\n minRecoveryPeriod,\n maxRecoveryPeriod\n );\n securityConfigs[_wallet].recoveryPeriod = _recoveryPeriod;\n }\n\n /**\n * @notice Wallet owner sets the lock period for the wallet. Only the owner of wallet can call this function.\n * The lock period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _lockPeriod Custom Lock period for the wallet\n */\n function setLockPeriod(\n address _wallet,\n uint128 _lockPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(_lockPeriod, minLockPeriod, maxLockPeriod);\n securityConfigs[_wallet].lockPeriod = _lockPeriod;\n }\n\n /**\n * @notice Wallet owner sets the approval validation period for the wallet. Only the owner of wallet can call this function.\n * The approval validation period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _approvalValidationPeriod Custom approval validation period for the wallet\n */\n function setApprovalValidationPeriod(\n address _wallet,\n uint128 _approvalValidationPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _approvalValidationPeriod,\n minApprovalValidationPeriod,\n maxApprovalValidationPeriod\n );\n securityConfigs[_wallet]\n .approvalValidationPeriod = _approvalValidationPeriod;\n }\n\n /**\n * @notice Wallet owner sets the migration period for the wallet. Only the owner of wallet can call this function.\n * The migration period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _migrationPeriod Custom migration period for the wallet\n */\n\n function setMigrationPeriod(\n address _wallet,\n uint128 _migrationPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _migrationPeriod,\n minMigrationPeriod,\n maxMigrationPeriod\n );\n securityConfigs[_wallet].migrationPeriod = _migrationPeriod;\n }\n\n /**\n * @notice Returns the addition security period. Returns default value when custom addition security period is not set\n * @param _wallet Address of wallet\n * @return additionSecurityPeriod Addition Security Period of the given Barz account or wallet\n */\n function additionSecurityPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 additionSecurityPeriod)\n {\n additionSecurityPeriod = securityConfigs[_wallet]\n .additionSecurityPeriod;\n additionSecurityPeriod = (additionSecurityPeriod == 0)\n ? defaultAdditionSecurityPeriod\n : additionSecurityPeriod;\n }\n\n /**\n * @notice Returns the removal security period. Returns default value when custom removal security period is not set\n * @param _wallet Address of wallet\n * @return removalSecurityPeriod Removal Security Period of the given Barz account or wallet\n */\n function removalSecurityPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 removalSecurityPeriod)\n {\n removalSecurityPeriod = securityConfigs[_wallet].removalSecurityPeriod;\n removalSecurityPeriod = (removalSecurityPeriod == 0)\n ? defaultRemovalSecurityPeriod\n : removalSecurityPeriod;\n }\n\n /**\n * @notice Returns the security window. Returns default value when custom security window is not set\n * @param _wallet Address of wallet\n * @return securityWindow Security window of the given Barz account or wallet\n */\n function securityWindowOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 securityWindow)\n {\n securityWindow = securityConfigs[_wallet].securityWindow;\n securityWindow = (securityWindow == 0)\n ? defaultSecurityWindow\n : securityWindow;\n }\n\n /**\n * @notice Returns the recovery period. Returns default value when custom recovery period is not set\n * @param _wallet Address of wallet\n * @return recoveryPeriod Recovery Period of the given Barz account or wallet\n */\n function recoveryPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 recoveryPeriod)\n {\n recoveryPeriod = securityConfigs[_wallet].recoveryPeriod;\n recoveryPeriod = (recoveryPeriod == 0)\n ? defaultRecoveryPeriod\n : recoveryPeriod;\n }\n\n /**\n * @notice Returns the lock period. Returns default value when custom lock period is not set\n * @param _wallet Address of wallet\n * @return lockPeriod Lock Period of the given Barz account or wallet\n */\n function lockPeriodOf(\n address _wallet\n ) public view override onlyWallet(_wallet) returns (uint128 lockPeriod) {\n lockPeriod = securityConfigs[_wallet].lockPeriod;\n lockPeriod = (lockPeriod == 0) ? defaultLockPeriod : lockPeriod;\n }\n\n /**\n * @notice Returns the approval validation period. Returns default value when custom approval validation period is not set\n * @param _wallet Address of wallet\n * @return approvalValidationPeriod Approval Validation Period of the given Barz account or wallet\n */\n function approvalValidationPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityConfigs[_wallet]\n .approvalValidationPeriod;\n approvalValidationPeriod = (approvalValidationPeriod == 0)\n ? defaultApprovalValidationPeriod\n : approvalValidationPeriod;\n }\n\n /**\n * @notice Returns the migration period. Returns default value when custom migration period is not set\n * @param _wallet Address of wallet\n * @return migrationPeriod Migration Period of the given Barz account or wallet\n */\n function migrationPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 migrationPeriod)\n {\n migrationPeriod = securityConfigs[_wallet].migrationPeriod;\n migrationPeriod = (migrationPeriod == 0)\n ? defaultMigrationPeriod\n : migrationPeriod;\n }\n\n /**\n * @notice Validates if the period is smaller than the max period or bigger than the min period\n * @param _period Period to be checked\n * @param _minPeriod Minimum period\n * @param _maxPeriod Maximum period\n */\n function _validatePeriodBoundaries(\n uint128 _period,\n uint128 _minPeriod,\n uint128 _maxPeriod\n ) internal pure {\n if (_period >= _maxPeriod || _period <= _minPeriod)\n revert SecurityManager__OutOfBoundary();\n }\n}\n" + }, + "contracts/infrastructure/WhitelistStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {RemoteStorage} from \"./RemoteStorage.sol\";\n\n/**\n * @title Whitelist storage\n * @dev Maps addresses to the corresponsing array of whitelisted addresses for each of them.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract WhitelistStorage is RemoteStorage {\n /**\n * @dev Add the address to the whitelist storage\n * @param _wallet User wallet\n * @param _address Address to be whitelisted\n */\n function whitelistAddress(address _wallet, address _address) external {\n enforceWalletOrGuardianIfExists(_wallet);\n addAddress(_wallet, _address);\n }\n\n /**\n * @dev Removes the address from the whitelist storage\n * @param _wallet User wallet\n * @param _address Address to be removed from the whitelist\n */\n function blacklistAddress(address _wallet, address _address) external {\n enforceGuardianOrWallet(_wallet);\n removeAddress(_wallet, _address);\n }\n\n /**\n * @dev Returns whether the address exists in the whitelist storage, associated with the wallet\n * @param _wallet User wallet\n * @param _address Address to be whitelisted\n */\n function isWhitelisted(\n address _wallet,\n address _address\n ) external view returns (bool) {\n return exists(_wallet, _address);\n }\n\n /**\n * @dev Returns all whitelisted addresses associated with the wallet\n * @param _wallet User wallet\n */\n function getWhitelistedAddresses(\n address _wallet\n ) external view returns (address[] memory) {\n return getAddresses(_wallet);\n }\n}\n" + }, + "contracts/interfaces/ERC/IERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\n\npragma solidity 0.8.21;\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155Receiver {\n /**\n * @dev Handles the receipt of a single ERC1155 token type. This function is\n * called at the end of a `safeTransferFrom` after the balance has been updated.\n *\n * NOTE: To accept the transfer, this must return\n * `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n * (i.e. 0xf23a6e61, or its own function selector).\n *\n * @param operator The address which initiated the transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param id The ID of the token being transferred\n * @param value The amount of tokens being transferred\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n ) external returns (bytes4);\n\n /**\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\n * is called at the end of a `safeBatchTransferFrom` after the balances have\n * been updated.\n *\n * NOTE: To accept the transfer(s), this must return\n * `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n * (i.e. 0xbc197c81, or its own function selector).\n *\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "contracts/interfaces/ERC/IERC1271.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\ninterface IERC1271 {\n function isValidSignature(\n bytes32 hash,\n bytes memory signature\n ) external view returns (bytes4);\n}\n" + }, + "contracts/interfaces/ERC/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\ninterface IERC165 {\n /// @notice Query if a contract implements an interface\n /// @param interfaceId The interface identifier, as specified in ERC-165\n /// @dev Interface identification is specified in ERC-165. This function\n /// uses less than 30,000 gas.\n /// @return `true` if the contract implements `interfaceID` and\n /// `interfaceID` is not 0xffffffff, `false` otherwise\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/IERC173.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\n/// @title ERC-173 Contract Ownership Standard\n/// Note: the ERC-165 identifier for this interface is 0x7f5828d0\n/* is ERC165 */\ninterface IERC173 {\n /// @dev This emits when ownership of a contract changes.\n event OwnershipTransferred(\n address indexed previousOwner,\n address indexed newOwner\n );\n\n /// @notice Get the address of the owner\n /// @return owner_ The address of the owner.\n function owner() external view returns (address owner_);\n\n /// @notice Set the address of the new owner of the contract\n /// @dev Set _newOwner to address(0) to renounce any ownership.\n /// @param _newOwner The address of the new owner of the contract\n function transferOwnership(address _newOwner) external;\n}\n" + }, + "contracts/interfaces/ERC/IERC677Receiver.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\ninterface IERC677Receiver {\n function onTokenTransfer(\n address sender,\n uint value,\n bytes calldata data\n ) external pure returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155 is IERC165 {\n /**\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n */\n event TransferSingle(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256 id,\n uint256 value\n );\n\n /**\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n * transfers.\n */\n event TransferBatch(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\n\n /**\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n * `approved`.\n */\n event ApprovalForAll(\n address indexed account,\n address indexed operator,\n bool approved\n );\n\n /**\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n *\n * If an {URI} event was emitted for `id`, the standard\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n * returned by {IERC1155MetadataURI-uri}.\n */\n event URI(string value, uint256 indexed id);\n\n /**\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(\n address account,\n uint256 id\n ) external view returns (uint256);\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] calldata accounts,\n uint256[] calldata ids\n ) external view returns (uint256[] memory);\n\n /**\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n *\n * Emits an {ApprovalForAll} event.\n *\n * Requirements:\n *\n * - `operator` cannot be the caller.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n *\n * See {setApprovalForAll}.\n */\n function isApprovedForAll(\n address account,\n address operator\n ) external view returns (bool);\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes calldata data\n ) external;\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(\n address indexed owner,\n address indexed spender,\n uint256 value\n );\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` 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 amount) 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(\n address owner,\n address spender\n ) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the 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 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` 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(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(\n address spender,\n uint256 addedValue\n ) external returns (bool);\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(\n address spender,\n uint256 subtractedValue\n ) external returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(\n address indexed from,\n address indexed to,\n uint256 indexed tokenId\n );\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(\n address indexed owner,\n address indexed approved,\n uint256 indexed tokenId\n );\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(\n address indexed owner,\n address indexed operator,\n bool approved\n );\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(\n uint256 tokenId\n ) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(\n address owner,\n address operator\n ) external view returns (bool);\n}\n" + }, + "contracts/interfaces/IBarz.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Barz Interface\n * @dev Interface of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IBarz {\n error Barz__InitializationFailure();\n}\n" + }, + "contracts/interfaces/IBarzFactory.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Barz} from \"../Barz.sol\";\n\n/**\n * @title Barz Factory Interface\n * @dev Interface of contract to easily deploy Barz to a pre-computed address with a single call\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IBarzFactory {\n function createAccount(\n address verificationFacet,\n bytes calldata owner,\n uint256 salt\n ) external returns (Barz);\n\n function getAddress(\n address verificationFacet,\n bytes calldata owner,\n uint256 salt\n ) external view returns (address);\n\n function getBytecode(\n address accountFacet,\n address verificationFacet,\n address entryPoint,\n address facetRegistry,\n address defaultFallback,\n bytes memory ownerPublicKey\n ) external pure returns (bytes memory);\n\n function getCreationCode() external pure returns (bytes memory);\n}\n" + }, + "contracts/libraries/DefaultLibDiamond.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\n\nerror InitializationFunctionReverted(\n address _initializationContractAddress,\n bytes _calldata\n);\n\nlibrary DefaultLibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION =\n keccak256(\"trustwallet.barz.diamond.storage\");\n\n struct FacetAddressAndPosition {\n address facetAddress;\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\n }\n\n struct FacetFunctionSelectors {\n bytes4[] functionSelectors;\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\n }\n\n struct DiamondStorage {\n // maps function selector to the facet address and\n // the position of the selector in the facetFunctionSelectors.selectors array\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\n // maps facet addresses to function selectors\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\n // facet addresses\n address[] facetAddresses;\n // Used to query if a contract implements an interface.\n // Used to implement ERC-165.\n mapping(bytes4 => bool) supportedInterfaces;\n }\n\n function diamondStorage()\n internal\n pure\n returns (DiamondStorage storage ds)\n {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n event DiamondCut(\n IDiamondCut.FacetCut[] _diamondCut,\n address _init,\n bytes _calldata\n );\n\n // Internal function version of diamondCut\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n for (\n uint256 facetIndex;\n facetIndex < _diamondCut.length;\n facetIndex++\n ) {\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\n if (action == IDiamondCut.FacetCutAction.Add) {\n addFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\n replaceFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\n removeFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else {\n revert(\"LibDiamondCut: Incorrect FacetCutAction\");\n }\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Add facet can't be address(0)\"\n );\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n require(\n oldFacetAddress == address(0),\n \"LibDiamondCut: Can't add function that already exists\"\n );\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function replaceFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Replace facet can't be address(0)\"\n );\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n require(\n oldFacetAddress != _facetAddress,\n \"LibDiamondCut: Can't replace function with same facet\"\n );\n removeFunction(ds, oldFacetAddress, selector);\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function removeFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n // if function does not exist then do nothing and return\n require(\n _facetAddress == address(0),\n \"LibDiamondCut: Remove facet address must be address(0)\"\n );\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n removeFunction(ds, oldFacetAddress, selector);\n }\n }\n\n function addFacet(\n DiamondStorage storage ds,\n address _facetAddress\n ) internal {\n enforceHasContractCode(\n _facetAddress,\n \"LibDiamondCut: New facet has no code\"\n );\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds\n .facetAddresses\n .length;\n ds.facetAddresses.push(_facetAddress);\n }\n\n function addFunction(\n DiamondStorage storage ds,\n bytes4 _selector,\n uint96 _selectorPosition,\n address _facetAddress\n ) internal {\n ds\n .selectorToFacetAndPosition[_selector]\n .functionSelectorPosition = _selectorPosition;\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(\n _selector\n );\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\n }\n\n function removeFunction(\n DiamondStorage storage ds,\n address _facetAddress,\n bytes4 _selector\n ) internal {\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Can't remove function that doesn't exist\"\n );\n // an immutable function is a function defined directly in a diamond\n require(\n _facetAddress != address(this),\n \"LibDiamondCut: Can't remove immutable function\"\n );\n // replace selector with last selector, then delete last selector\n uint256 selectorPosition = ds\n .selectorToFacetAndPosition[_selector]\n .functionSelectorPosition;\n uint256 lastSelectorPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors\n .length - 1;\n // if not the same then replace _selector with lastSelector\n if (selectorPosition != lastSelectorPosition) {\n bytes4 lastSelector = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors[lastSelectorPosition];\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[\n selectorPosition\n ] = lastSelector;\n ds\n .selectorToFacetAndPosition[lastSelector]\n .functionSelectorPosition = uint96(selectorPosition);\n }\n // delete the last selector\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\n delete ds.selectorToFacetAndPosition[_selector];\n\n // if no more selectors for facet address then delete the facet address\n if (lastSelectorPosition == 0) {\n // replace facet address with last facet address and delete last facet address\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\n uint256 facetAddressPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .facetAddressPosition;\n if (facetAddressPosition != lastFacetAddressPosition) {\n address lastFacetAddress = ds.facetAddresses[\n lastFacetAddressPosition\n ];\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\n ds\n .facetFunctionSelectors[lastFacetAddress]\n .facetAddressPosition = facetAddressPosition;\n }\n ds.facetAddresses.pop();\n delete ds\n .facetFunctionSelectors[_facetAddress]\n .facetAddressPosition;\n }\n }\n\n function initializeDiamondCut(\n address _init,\n bytes memory _calldata\n ) internal {\n if (_init == address(0)) {\n return;\n }\n enforceHasContractCode(\n _init,\n \"LibDiamondCut: _init address has no code\"\n );\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length > 0) {\n // bubble up error\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(error)\n revert(add(32, error), returndata_size)\n }\n } else {\n revert InitializationFunctionReverted(_init, _calldata);\n }\n }\n }\n\n function enforceHasContractCode(\n address _contract,\n string memory _errorMessage\n ) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize > 0, _errorMessage);\n }\n}\n" + }, + "contracts/libraries/LibAppStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SafeCast} from \"@openzeppelin/contracts/utils/math/SafeCast.sol\";\nimport {IEntryPoint} from \"../aa-4337/interfaces/IEntryPoint.sol\";\nimport {IFacetRegistry} from \"../infrastructure/interfaces/IFacetRegistry.sol\";\n\n/*\n * @title App Storage\n * @dev App storage for Barz contract to prevent storage collision\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\n\nstruct Lock {\n uint64 release;\n bytes4 locker;\n}\n\nstruct InitializersStorage {\n // NOTE: initialized is a variable to make sure the initialization is only done once.\n uint8 signerInitialized;\n uint8 accountInitialized;\n uint8 restrictionsInitialized;\n}\n\nstruct AppStorage {\n mapping(uint256 => InitializersStorage) initStorage;\n uint8 signerMigration;\n bytes4 validateOwnerSignatureSelector;\n IEntryPoint entryPoint;\n IFacetRegistry facetRegistry;\n mapping(uint256 => Lock) locks;\n}\n\nlibrary LibAppStorage {\n error LibAppStorage__AccountAlreadyUninitialized();\n error LibAppStorage__AccountMustBeUninitialized();\n error LibAppStorage__SignerAlreadyUninitialized();\n error LibAppStorage__SignerMustBeUninitialized();\n\n function appStorage() internal pure returns (AppStorage storage ds) {\n assembly {\n ds.slot := 0\n }\n }\n\n function setSignerUninitialized() internal {\n AppStorage storage s = appStorage();\n if (1 != s.initStorage[0].signerInitialized) {\n revert LibAppStorage__SignerAlreadyUninitialized();\n }\n s.initStorage[0].signerInitialized = 0;\n }\n\n function getValidateOwnerSignatureSelector()\n internal\n view\n returns (bytes4 selector)\n {\n selector = appStorage().validateOwnerSignatureSelector;\n }\n\n function setValidateOwnerSignatureSelector(\n bytes4 _validateOwnerSignatureSelector\n ) internal {\n appStorage()\n .validateOwnerSignatureSelector = _validateOwnerSignatureSelector;\n }\n\n function enforceSignerInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].signerInitialized) {\n revert LibAppStorage__SignerMustBeUninitialized();\n }\n s.initStorage[0].signerInitialized = 1;\n }\n\n function enforceAccountInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].accountInitialized) {\n revert LibAppStorage__AccountMustBeUninitialized();\n }\n s.initStorage[0].accountInitialized = 1;\n }\n\n function initiateSignerMigration() internal {\n appStorage().signerMigration = 1;\n }\n\n function enforceSignerMigration() internal view {\n if (1 != appStorage().signerMigration) {\n revert LibAppStorage__AccountMustBeUninitialized();\n }\n }\n\n function finalizeSignerMigration() internal {\n appStorage().signerMigration = 0;\n }\n\n function setLock(uint256 _releaseAfter, bytes4 _locker) internal {\n appStorage().locks[0] = Lock(SafeCast.toUint64(_releaseAfter), _locker);\n }\n\n function enforceRestrictionsInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].restrictionsInitialized)\n revert LibAppStorage__SignerMustBeUninitialized();\n s.initStorage[0].restrictionsInitialized = 1;\n }\n\n function setRestrictionsUninitialized() internal {\n AppStorage storage s = appStorage();\n if (1 != s.initStorage[0].restrictionsInitialized)\n revert LibAppStorage__AccountAlreadyUninitialized();\n s.initStorage[0].restrictionsInitialized = 0;\n }\n}\n\ncontract BarzStorage {\n AppStorage internal s;\n modifier onlyWhenUnlocked() {\n require(\n uint64(block.timestamp) >= s.locks[0].release,\n \"Account Locked\"\n );\n _;\n }\n modifier onlyWhenLocked() {\n require(\n uint64(block.timestamp) < s.locks[0].release,\n \"Account Unlocked\"\n );\n _;\n }\n}\n" + }, + "contracts/libraries/LibDiamond.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\n\nerror InitializationFunctionReverted(\n address _initializationContractAddress,\n bytes _calldata\n);\n\nlibrary LibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION =\n keccak256(\"trustwallet.barz.diamond.storage\");\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\n bytes4(keccak256(\"verifyRestrictions(address,address,uint256,bytes)\"));\n struct DiamondStorage {\n // maps function selectors to the facets that execute the functions.\n // and maps the selectors to their position in the selectorSlots array.\n // func selector => address facet, selector position\n mapping(bytes4 => bytes32) facets;\n // array of slots of function selectors.\n // each slot holds 8 function selectors.\n mapping(uint256 => bytes32) selectorSlots;\n // The number of function selectors in selectorSlots\n uint16 selectorCount;\n // Used to query if a contract implements an interface.\n // Used to implement ERC-165.\n mapping(bytes4 => bool) supportedInterfaces;\n // Default Fallback Handler of the barz.\n IDiamondLoupe defaultFallbackHandler;\n }\n\n function diamondStorage()\n internal\n pure\n returns (DiamondStorage storage ds)\n {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n function enforceIsSelf() internal view {\n require(msg.sender == address(this), \"LibDiamond: Caller not self\");\n }\n\n event DiamondCut(\n IDiamondCut.FacetCut[] _diamondCut,\n address _init,\n bytes _calldata\n );\n\n bytes32 constant CLEAR_ADDRESS_MASK =\n bytes32(uint256(0xffffffffffffffffffffffff));\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\n\n // Internal function version of diamondCut\n // This code is almost the same as the external diamondCut,\n // except it is using 'Facet[] memory _diamondCut' instead of\n // 'Facet[] calldata _diamondCut'.\n // The code is duplicated to prevent copying calldata to memory which\n // causes an error for a two dimensional array.\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n DiamondStorage storage ds = diamondStorage();\n uint256 originalSelectorCount = ds.selectorCount;\n uint256 selectorCount = originalSelectorCount;\n bytes32 selectorSlot;\n // Check if last selector slot is not full\n // \"selectorCount & 7\" is a gas efficient modulo by eight \"selectorCount % 8\"\n if (selectorCount & 7 > 0) {\n // get last selectorSlot\n // \"selectorSlot >> 3\" is a gas efficient division by 8 \"selectorSlot / 8\"\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\n }\n // loop through diamond cut\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\n selectorCount,\n selectorSlot,\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].action,\n _diamondCut[facetIndex].functionSelectors\n );\n\n unchecked {\n facetIndex++;\n }\n }\n if (selectorCount != originalSelectorCount) {\n ds.selectorCount = uint16(selectorCount);\n }\n // If last selector slot is not full\n // \"selectorCount & 7\" is a gas efficient modulo by eight \"selectorCount % 8\"\n if (selectorCount & 7 > 0) {\n // \"selectorSlot >> 3\" is a gas efficient division by 8 \"selectorSlot / 8\"\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addReplaceRemoveFacetSelectors(\n uint256 _selectorCount,\n bytes32 _selectorSlot,\n address _newFacetAddress,\n IDiamondCut.FacetCutAction _action,\n bytes4[] memory _selectors\n ) internal returns (uint256, bytes32) {\n DiamondStorage storage ds = diamondStorage();\n require(\n _selectors.length > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n if (_action == IDiamondCut.FacetCutAction.Add) {\n enforceHasContractCode(\n _newFacetAddress,\n \"LibDiamondCut: Add facet has no code\"\n );\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n require(\n address(bytes20(oldFacet)) == address(0),\n \"LibDiamondCut: Can't add function that already exists\"\n );\n // add facet for selector\n ds.facets[selector] =\n bytes20(_newFacetAddress) |\n bytes32(_selectorCount);\n // \"_selectorCount & 7\" is a gas efficient modulo by eight \"_selectorCount % 8\"\n // \" << 5 is the same as multiplying by 32 ( * 32)\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\n // clear selector position in slot and add selector\n _selectorSlot =\n (_selectorSlot &\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\n (bytes32(selector) >> selectorInSlotPosition);\n // if slot is full then write it to storage\n if (selectorInSlotPosition == 224) {\n // \"_selectorSlot >> 3\" is a gas efficient division by 8 \"_selectorSlot / 8\"\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\n _selectorSlot = 0;\n }\n _selectorCount++;\n\n unchecked {\n selectorIndex++;\n }\n }\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\n enforceHasContractCode(\n _newFacetAddress,\n \"LibDiamondCut: Replace facet has no code\"\n );\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n address oldFacetAddress = address(bytes20(oldFacet));\n // only useful if immutable functions exist\n require(\n oldFacetAddress != address(this),\n \"LibDiamondCut: Can't replace immutable function\"\n );\n require(\n oldFacetAddress != _newFacetAddress,\n \"LibDiamondCut: Can't replace function with same function\"\n );\n require(\n oldFacetAddress != address(0),\n \"LibDiamondCut: Can't replace function that doesn't exist\"\n );\n // replace old facet address\n ds.facets[selector] =\n (oldFacet & CLEAR_ADDRESS_MASK) |\n bytes20(_newFacetAddress);\n\n unchecked {\n selectorIndex++;\n }\n }\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\n require(\n _newFacetAddress == address(0),\n \"LibDiamondCut: Remove facet address must be address(0)\"\n );\n // \"_selectorCount >> 3\" is a gas efficient division by 8 \"_selectorCount / 8\"\n uint256 selectorSlotCount = _selectorCount >> 3;\n // \"_selectorCount & 7\" is a gas efficient modulo by eight \"_selectorCount % 8\"\n uint256 selectorInSlotIndex = _selectorCount & 7;\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n if (_selectorSlot == 0) {\n // get last selectorSlot\n selectorSlotCount--;\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\n selectorInSlotIndex = 7;\n } else {\n selectorInSlotIndex--;\n }\n bytes4 lastSelector;\n uint256 oldSelectorsSlotCount;\n uint256 oldSelectorInSlotPosition;\n // adding a block here prevents stack too deep error\n {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n require(\n address(bytes20(oldFacet)) != address(0),\n \"LibDiamondCut: Can't remove function that doesn't exist\"\n );\n // only useful if immutable functions exist\n require(\n address(bytes20(oldFacet)) != address(this),\n \"LibDiamondCut: Can't remove immutable function\"\n );\n // replace selector with last selector in ds.facets\n // gets the last selector\n // \" << 5 is the same as multiplying by 32 ( * 32)\n lastSelector = bytes4(\n _selectorSlot << (selectorInSlotIndex << 5)\n );\n if (lastSelector != selector) {\n // update last selector slot position info\n ds.facets[lastSelector] =\n (oldFacet & CLEAR_ADDRESS_MASK) |\n bytes20(ds.facets[lastSelector]);\n }\n delete ds.facets[selector];\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\n // \"oldSelectorCount >> 3\" is a gas efficient division by 8 \"oldSelectorCount / 8\"\n oldSelectorsSlotCount = oldSelectorCount >> 3;\n // \"oldSelectorCount & 7\" is a gas efficient modulo by eight \"oldSelectorCount % 8\"\n // \" << 5 is the same as multiplying by 32 ( * 32)\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\n }\n if (oldSelectorsSlotCount != selectorSlotCount) {\n bytes32 oldSelectorSlot = ds.selectorSlots[\n oldSelectorsSlotCount\n ];\n // clears the selector we are deleting and puts the last selector in its place.\n oldSelectorSlot =\n (oldSelectorSlot &\n ~(CLEAR_SELECTOR_MASK >>\n oldSelectorInSlotPosition)) |\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\n // update storage with the modified slot\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\n } else {\n // clears the selector we are deleting and puts the last selector in its place.\n _selectorSlot =\n (_selectorSlot &\n ~(CLEAR_SELECTOR_MASK >>\n oldSelectorInSlotPosition)) |\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\n }\n if (selectorInSlotIndex == 0) {\n delete ds.selectorSlots[selectorSlotCount];\n _selectorSlot = 0;\n }\n\n unchecked {\n selectorIndex++;\n }\n }\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\n } else {\n revert(\"LibDiamondCut: Incorrect FacetCutAction\");\n }\n return (_selectorCount, _selectorSlot);\n }\n\n function initializeDiamondCut(\n address _init,\n bytes memory _calldata\n ) internal {\n if (_init == address(0)) {\n return;\n }\n enforceHasContractCode(\n _init,\n \"LibDiamondCut: _init address has no code\"\n );\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length > 0) {\n // bubble up error\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(error)\n revert(add(32, error), returndata_size)\n }\n } else {\n revert InitializationFunctionReverted(_init, _calldata);\n }\n }\n }\n\n function enforceHasContractCode(\n address _contract,\n string memory _errorMessage\n ) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize > 0, _errorMessage);\n }\n\n function restrictionsFacet() internal view returns (address facetAddress_) {\n facetAddress_ = address(\n bytes20(\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\n )\n );\n }\n}\n" + }, + "contracts/libraries/LibFacetStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Storage\n * @dev Storage contract to store each facets variables with diamond storage\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\n\nstruct Secp256k1VerificationStorage {\n address signer;\n}\n\nstruct Secp256r1VerificationStorage {\n uint256[2] q;\n}\n\nstruct GuardianStorage {\n mapping(bytes32 => uint256) pending;\n mapping(uint8 => StorageConfig) configs;\n}\n\nstruct Info {\n bool exists;\n uint128 index;\n}\n\nstruct StorageConfig {\n address[] addresses;\n mapping(address => Info) info;\n}\n\nstruct RecoveryConfig {\n bytes recoveryPublicKey;\n uint64 executeAfter;\n}\n\nstruct ApprovalConfig {\n bool isApproved;\n uint64 validUntil;\n}\n\nstruct RecoveryApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isNewOwnerApproved;\n}\n\nstruct RecoveryStorage {\n mapping(uint8 => RecoveryConfig) recoveryConfigs;\n mapping(uint8 => RecoveryApprovalConfig) recoveryApprovalConfigs;\n uint128 nonce;\n}\n\nstruct RestrictionsStorage {\n address[] restrictions;\n mapping(address => bool) exists;\n}\n\nstruct SignatureMigrationConfig {\n bytes migrationPublicKey;\n address migrationVerificationFacet;\n bytes4[] migrationSelectors;\n uint64 migrateAfter;\n}\n\nstruct SignatureMigrationApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isMigrationApproved;\n}\n\nstruct SignatureMigrationStorage {\n mapping(uint8 => SignatureMigrationConfig) migrationConfigs;\n mapping(uint8 => SignatureMigrationApprovalConfig) migrationApprovalConfigs;\n uint128 nonce;\n}\n\nstruct DiamondCutApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isDiamondCutApproved;\n}\n\nstruct DiamondCutStorage {\n mapping(uint8 => DiamondCutApprovalConfig) diamondCutApprovalConfigs;\n uint128 nonce;\n}\n\nstruct LockStorage {\n uint128 nonce;\n}\n\nlibrary LibFacetStorage {\n bytes32 constant K1_STORAGE_POSITION =\n keccak256(\n \"v0.trustwallet.diamond.storage.Secp256k1VerificationStorage\"\n );\n bytes32 constant R1_STORAGE_POSITION =\n keccak256(\n \"v0.trustwallet.diamond.storage.Secp256r1VerificationStorage\"\n );\n bytes32 constant GUARDIAN_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.GuardianStorage\");\n bytes32 constant RECOVERY_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.RecoveryStorage\");\n bytes32 constant RESTRICTION_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.RestrictionsStorage\");\n bytes32 constant MIGRATION_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.SignatureMigrationStorage\");\n bytes32 constant DIAMONDCUT_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.DiamondCutStorage\");\n bytes32 constant LOCK_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.LockStorage\");\n\n function k1Storage()\n internal\n pure\n returns (Secp256k1VerificationStorage storage ds)\n {\n bytes32 storagePosition = K1_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function r1Storage()\n internal\n pure\n returns (Secp256r1VerificationStorage storage ds)\n {\n bytes32 storagePosition = R1_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function guardianStorage()\n internal\n pure\n returns (GuardianStorage storage ds)\n {\n bytes32 storagePosition = GUARDIAN_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function recoveryStorage()\n internal\n pure\n returns (RecoveryStorage storage ds)\n {\n bytes32 storagePosition = RECOVERY_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function restrictionsStorage()\n internal\n pure\n returns (RestrictionsStorage storage ds)\n {\n bytes32 storagePosition = RESTRICTION_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function migrationStorage()\n internal\n pure\n returns (SignatureMigrationStorage storage ds)\n {\n bytes32 storagePosition = MIGRATION_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function diamondCutStorage()\n internal\n pure\n returns (DiamondCutStorage storage ds)\n {\n bytes32 storagePosition = DIAMONDCUT_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function lockStorage() internal pure returns (LockStorage storage ds) {\n bytes32 storagePosition = LOCK_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n}\n" + }, + "contracts/libraries/LibGuardian.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibFacetStorage, StorageConfig} from \"./LibFacetStorage.sol\";\n\n/**\n * @title LibGuardian\n * @dev Internal Library to provide utility feature for Guardians stored in Guardian Facet Storage\n * @author David Yongjun Kim (@Powerstream3604)\n */\nlibrary LibGuardian {\n function majorityOfGuardians()\n internal\n view\n returns (uint256 guardianNumber)\n {\n uint256 guardianLength = guardianCount();\n guardianNumber = (guardianLength == 0) ? 0 : guardianLength / 2 + 1;\n }\n\n function isGuardian(address _guardian) internal view returns (bool) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n return config.info[_guardian].exists;\n }\n\n function guardianCount() internal view returns (uint256) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n return config.addresses.length;\n }\n\n function getGuardians() internal view returns (address[] memory) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n address[] memory addresses = new address[](config.addresses.length);\n uint256 addressesLen = config.addresses.length;\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n return addresses;\n }\n}\n" + }, + "contracts/libraries/LibLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {LibDiamond} from \"./LibDiamond.sol\";\n\n/**\n * @title LibLoupe\n * @dev Internal Library to provide utility feature for reading the state of diamond facets\n * @author David Yongjun Kim (@Powerstream3604)\n */\nlibrary LibLoupe {\n /// @notice Gets all facets and their selectors.\n /// @return facets_ Facet\n function facets()\n internal\n view\n returns (IDiamondLoupe.Facet[] memory facets_)\n {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facets_ = new IDiamondLoupe.Facet[](ds.selectorCount);\n uint16[] memory numFacetSelectors = new uint16[](ds.selectorCount);\n uint256 numFacets;\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facetAddress_ = address(bytes20(ds.facets[selector]));\n bool continueLoop;\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n if (facets_[facetIndex].facetAddress == facetAddress_) {\n facets_[facetIndex].functionSelectors[\n numFacetSelectors[facetIndex]\n ] = selector;\n // probably will never have more than 256 functions from one facet contract\n require(numFacetSelectors[facetIndex] < 255);\n numFacetSelectors[facetIndex]++;\n continueLoop = true;\n break;\n }\n }\n if (continueLoop) {\n continue;\n }\n facets_[numFacets].facetAddress = facetAddress_;\n facets_[numFacets].functionSelectors = new bytes4[](\n ds.selectorCount\n );\n facets_[numFacets].functionSelectors[0] = selector;\n numFacetSelectors[numFacets] = 1;\n numFacets++;\n }\n }\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n uint256 numSelectors = numFacetSelectors[facetIndex];\n bytes4[] memory selectors = facets_[facetIndex].functionSelectors;\n // setting the number of selectors\n assembly {\n mstore(selectors, numSelectors)\n }\n }\n // setting the number of facets\n assembly {\n mstore(facets_, numFacets)\n }\n }\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n /// @return _facetFunctionSelectors The selectors associated with a facet address.\n function facetFunctionSelectors(\n address _facet\n ) internal view returns (bytes4[] memory _facetFunctionSelectors) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n uint256 numSelectors;\n _facetFunctionSelectors = new bytes4[](ds.selectorCount);\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facet = address(bytes20(ds.facets[selector]));\n if (_facet == facet) {\n _facetFunctionSelectors[numSelectors] = selector;\n numSelectors++;\n }\n }\n }\n // Set the number of selectors in the array\n assembly {\n mstore(_facetFunctionSelectors, numSelectors)\n }\n }\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses()\n internal\n view\n returns (address[] memory facetAddresses_)\n {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facetAddresses_ = new address[](ds.selectorCount);\n uint256 numFacets;\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facetAddress_ = address(bytes20(ds.facets[selector]));\n bool continueLoop;\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n if (facetAddress_ == facetAddresses_[facetIndex]) {\n continueLoop = true;\n break;\n }\n }\n if (continueLoop) {\n continue;\n }\n facetAddresses_[numFacets] = facetAddress_;\n numFacets++;\n }\n }\n // Set the number of facet addresses in the array\n assembly {\n mstore(facetAddresses_, numFacets)\n }\n }\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(\n bytes4 _functionSelector\n ) internal view returns (address facetAddress_) {\n facetAddress_ = address(\n bytes20(LibDiamond.diamondStorage().facets[_functionSelector])\n );\n }\n}\n" + }, + "contracts/libraries/LibMultiSigStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Multi-sig Storage\n * @dev Storage contract for storing Multi-sig Facet variables in diamond storage pattern\n * @author David Yongjun Kim (@Powerstream3604)\n */\n\nstruct MultiSigStorage {\n mapping(address => address) owners;\n mapping(uint256 => mapping(address => mapping(bytes32 => uint256))) approvedHashes;\n uint256 ownerCount;\n uint256 threshold;\n uint256 counter;\n}\n\nlibrary LibMultiSigStorage {\n function multisigStorage()\n internal\n pure\n returns (MultiSigStorage storage ds)\n {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.MultiSigStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n}\n" + }, + "contracts/libraries/LibRecoverSpender.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title RecoverSpender\n * @dev Library to determine the action and spender of calldata\n * @author Ruslan Serebriakov (@rsrbk)\n */\nlibrary LibRecoverSpender {\n // ERC20, ERC721 & ERC1155 transfers & approvals\n bytes4 private constant ERC20_TRANSFER =\n bytes4(keccak256(\"transfer(address,uint256)\"));\n bytes4 private constant ERC20_APPROVE =\n bytes4(keccak256(\"approve(address,uint256)\"));\n bytes4 private constant ERC20_INCREASE_ALLOWANCE =\n bytes4(keccak256(\"increaseAllowance(address,uint256)\"));\n bytes4 private constant ERC20_DECREASE_ALLOWANCE =\n bytes4(keccak256(\"decreaseAllowance(address,uint256)\"));\n bytes4 private constant ERC721_SET_APPROVAL_FOR_ALL =\n bytes4(keccak256(\"setApprovalForAll(address,bool)\"));\n bytes4 private constant ERC721_TRANSFER_FROM =\n bytes4(keccak256(\"transferFrom(address,address,uint256)\"));\n bytes4 private constant ERC721_SAFE_TRANSFER_FROM =\n bytes4(keccak256(\"safeTransferFrom(address,address,uint256)\"));\n bytes4 private constant ERC721_SAFE_TRANSFER_FROM_BYTES =\n bytes4(keccak256(\"safeTransferFrom(address,address,uint256,bytes)\"));\n bytes4 private constant ERC1155_SAFE_TRANSFER_FROM =\n bytes4(\n keccak256(\"safeTransferFrom(address,address,uint256,uint256,bytes)\")\n );\n bytes4 private constant ERC1155_SAFE_BATCH_TRANSFER_FROM =\n bytes4(\n keccak256(\n \"safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)\"\n )\n );\n\n /**\n * @notice Helper method to recover the spender from a contract call.\n * The method returns the contract unless the call is to a standard method of a ERC20/ERC721/ERC1155 token\n * in which case the spender is recovered from the data.\n * @param _to The target contract.\n * @param _data The data payload.\n */\n function _recover(\n address _to,\n bytes memory _data\n ) internal pure returns (address spender) {\n if (_data.length >= 68) {\n bytes4 methodId;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n methodId := mload(add(_data, 0x20))\n }\n if (\n methodId == ERC20_TRANSFER ||\n methodId == ERC20_APPROVE ||\n methodId == ERC20_INCREASE_ALLOWANCE ||\n methodId == ERC20_DECREASE_ALLOWANCE ||\n methodId == ERC721_SET_APPROVAL_FOR_ALL\n ) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n spender := mload(add(_data, 0x24))\n }\n return spender;\n }\n if (\n methodId == ERC721_TRANSFER_FROM ||\n methodId == ERC721_SAFE_TRANSFER_FROM ||\n methodId == ERC721_SAFE_TRANSFER_FROM_BYTES ||\n methodId == ERC1155_SAFE_TRANSFER_FROM ||\n methodId == ERC1155_SAFE_BATCH_TRANSFER_FROM\n ) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n spender := mload(add(_data, 0x44))\n }\n return spender;\n }\n }\n\n spender = _to;\n }\n}\n" + }, + "contracts/libraries/LibUtils.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\n\nlibrary LibUtils {\n // Internal utility functions\n function mergeArrays(\n bytes4[] memory _array1,\n bytes4[] memory _array2\n ) internal pure returns (bytes4[] memory) {\n uint256 length1 = _array1.length;\n uint256 length2 = _array2.length;\n bytes4[] memory mergedArray = new bytes4[](length1 + length2);\n\n for (uint256 i; i < length1; ) {\n mergedArray[i] = _array1[i];\n unchecked {\n ++i;\n }\n }\n\n for (uint256 i; i < length2; ) {\n mergedArray[length1 + i] = _array2[i];\n unchecked {\n ++i;\n }\n }\n\n return mergedArray;\n }\n\n function removeFacetElement(\n IDiamondLoupe.Facet[] memory _facets,\n uint256 _index\n ) internal pure returns (IDiamondLoupe.Facet[] memory) {\n require(_index < _facets.length, \"Invalid index\");\n require(_facets.length != 0, \"Invalid array\");\n\n // Create a new array with a length of `_facets.length - 1`\n IDiamondLoupe.Facet[] memory newArray = new IDiamondLoupe.Facet[](\n _facets.length - 1\n );\n uint256 newArrayLength = newArray.length;\n // Iterate over the original array, skipping the element at the specified `index`\n for (uint256 i; i < newArrayLength; ) {\n if (i < _index) {\n newArray[i] = _facets[i];\n } else {\n newArray[i] = _facets[i + 1];\n }\n unchecked {\n ++i;\n }\n }\n\n return newArray;\n }\n\n function removeElement(\n bytes4[] memory _array,\n uint256 _index\n ) internal pure returns (bytes4[] memory) {\n require(_index < _array.length, \"Invalid index\");\n require(_array.length != 0, \"Invalid array\");\n\n bytes4[] memory newArray = new bytes4[](_array.length - 1);\n uint256 newArrayLength = newArray.length;\n for (uint256 i; i < newArrayLength; ) {\n if (i < _index) {\n newArray[i] = _array[i];\n } else {\n newArray[i] = _array[i + 1];\n }\n unchecked {\n ++i;\n }\n }\n\n return newArray;\n }\n\n function setValue(\n bytes4[] memory _keys,\n address[] memory _values,\n bytes4 _key,\n address _value\n ) internal pure returns (bytes4[] memory, address[] memory) {\n uint256 index = findIndex(_keys, _key);\n uint256 keysLength = _keys.length;\n if (index < keysLength) {\n _values[index] = _value;\n } else {\n // Create new storage arrays\n bytes4[] memory newKeys = new bytes4[](keysLength + 1);\n address[] memory newValues = new address[](_values.length + 1);\n\n // Copy values to the new storage arrays\n for (uint256 i; i < keysLength; ) {\n newKeys[i] = _keys[i];\n newValues[i] = _values[i];\n\n unchecked {\n ++i;\n }\n }\n\n // Add the new key-value pair\n newKeys[keysLength] = _key;\n newValues[_values.length] = _value;\n\n return (newKeys, newValues);\n }\n\n // If the key already exists, return the original arrays\n return (_keys, _values);\n }\n\n function getValue(\n bytes4[] memory _keys,\n address[] memory _values,\n bytes4 _key\n ) internal pure returns (address) {\n uint256 index = findIndex(_keys, _key);\n if (index >= _keys.length) return address(0);\n\n return _values[index];\n }\n\n function findIndex(\n bytes4[] memory _keys,\n bytes4 _key\n ) internal pure returns (uint256) {\n uint256 keysLength = _keys.length;\n for (uint256 i; i < keysLength; ) {\n if (_keys[i] == _key) {\n return i;\n }\n unchecked {\n ++i;\n }\n }\n return keysLength;\n }\n}\n" + }, + "contracts/restrictions/IRestriction.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Interface for restrictions\n * @dev Restriction is a contract which decides whether to approve a certain kind of transaction, based on its internal logic.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface IRestriction {\n /**\n * @dev Based on restriction's internal logic, it should accept or reject a certain transaction.\n * @param from The address of the sender, that will be signing the transaction.\n * @param to The receiving address.\n * @param value Amount of ETH to transfer from sender to recipient.\n * @param _calldata Optional field to include arbitrary data.\n * @return bool value for whether the check is passed\n */\n function check(\n address from,\n address to,\n uint256 value,\n bytes calldata _calldata\n ) external returns (bool);\n}\n" + }, + "contracts/restrictions/WhitelistRestriction.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibRecoverSpender} from \"../libraries/LibRecoverSpender.sol\";\nimport {WhitelistStorage} from \"../infrastructure/WhitelistStorage.sol\";\nimport {IRestriction} from \"./IRestriction.sol\";\n\n/**\n * @title Whitelist Restriction\n * @dev This restriction defines a list of accepted addresses and denies any interaction with addresses outside of it.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract WhitelistRestriction is IRestriction {\n WhitelistStorage public immutable whitelistStorage;\n\n constructor(WhitelistStorage _whitelistStorage) {\n whitelistStorage = _whitelistStorage;\n }\n\n /**\n * @notice Helper method to recover the spender from a contract call.\n * The method returns the contract unless the call is to a standard method of a ERC20/ERC721/ERC1155 token\n * in which case the spender is recovered from the data.\n * @param _to The target contract.\n * @param _data The data payload.\n */\n function recoverSpender(\n address _to,\n bytes memory _data\n ) public pure returns (address spender) {\n return LibRecoverSpender._recover(_to, _data);\n }\n\n /*\n * @dev IRestriction's implementation. It will allow transaction if the sender is whitelisted, or user, or the whitelist storage.\n * @param _from The address of the sender, that will be signing the transaction.\n * @param _to The receiving address.\n * @param _calldata Optional field to include arbitrary data.\n * @return result value for whether the check is passed\n */\n function check(\n address _from,\n address _to,\n uint256 /*_value*/,\n bytes calldata _calldata\n ) external view override returns (bool result) {\n return\n whitelistStorage.isWhitelisted(\n _from,\n LibRecoverSpender._recover(_to, _calldata)\n ) ||\n _to == address(whitelistStorage) ||\n _to == msg.sender;\n }\n}\n" + }, + "contracts/test/Counter.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\ncontract TestCounter {\n int private count = 0;\n\n function incrementCounter() public {\n count += 1;\n }\n\n function decrementCounter() public {\n count -= 1;\n }\n\n function getCount() public view returns (int) {\n return count;\n }\n}\n" + }, + "contracts/test/TestERC1155.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC1155/ERC1155.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\n\ncontract TestERC1155 is ERC1155 {\n using Counters for Counters.Counter;\n\n Counters.Counter private _tokenIds;\n\n constructor() ERC1155(\"\") {}\n\n function mint(address account, uint256 amount) external {\n uint256 tokenId = _getNextTokenId();\n _mint(account, tokenId, amount, \"\");\n }\n\n function mintBatch(\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes memory data\n ) external {\n require(\n ids.length == amounts.length,\n \"TestERC1155: arrays length mismatch\"\n );\n\n _mintBatch(to, ids, amounts, data);\n }\n\n function _getNextTokenId() private returns (uint256) {\n _tokenIds.increment();\n return _tokenIds.current();\n }\n}\n" + }, + "contracts/test/TestERC777.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC777/ERC777.sol\";\n\ncontract TestERC777 is ERC777 {\n constructor(\n address[] memory _operators\n ) ERC777(\"TestERC777\", \"TERC777\", _operators) {}\n\n function mint(address account, uint256 amount) external {\n _mint(account, amount, \"\", \"\");\n }\n}\n" + }, + "contracts/test/TestInvalidSecp256k1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IVerificationFacet} from \"../facets/interfaces/IVerificationFacet.sol\";\nimport {IERC1271} from \"../interfaces/ERC/IERC1271.sol\";\nimport {AppStorage, LibAppStorage, BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {LibFacetStorage, Secp256k1VerificationStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {UserOperation} from \"../aa-4337/interfaces/UserOperation.sol\";\n\n/**\n * @title Test Secp256k1 verification facet\n * @dev Default Ethereum's elliptic curve\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract TestInvalidSecp256k1VerificationFacet is BarzStorage, IERC1271 {\n using ECDSA for bytes32;\n error Secp256k1VerificationFacet__InvalidSignerLength();\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n\n event SignerUninitialized();\n\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n }\n\n // THIS INVALID FACET DOES NOT INCLUDE initializeSigner()\n // THIS FACET IS USED TO TEST WHEN initializeSigner() DOESN'T EXIST IN FACET\n\n function uninitializeSigner() external returns (uint256 uninitSuccess) {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view returns (uint256 validationData) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n return validateSignature(userOp, userOpHash, k1Storage.signer);\n }\n\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n address signer\n ) public pure returns (uint256) {\n bytes32 hash = userOpHash.toEthSignedMessageHash();\n if (signer != hash.recover(userOp.signature)) return 1;\n return 0;\n }\n\n // This is REMOVED for testing purpose\n function validateOwnerSignatureSelector() public pure returns (bytes4) {\n // return this.validateOwnerSignature.selector;\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n function owner() public view returns (bytes memory) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n return abi.encodePacked(k1Storage.signer);\n }\n\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure returns (bool) {\n return (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (_hash.recover(_signature) ==\n LibFacetStorage.k1Storage().signer)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n}\n" + }, + "contracts/test/TestNFT.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\n\ncontract TestNFT is ERC721 {\n using Counters for Counters.Counter;\n Counters.Counter private currentTokenId;\n\n constructor() ERC721(\"TestNFT\", \"TNFT\") {}\n\n function mint(address recipient) public returns (uint256) {\n currentTokenId.increment();\n uint256 newItemId = currentTokenId.current();\n _safeMint(recipient, newItemId);\n return newItemId;\n }\n}\n" + }, + "contracts/test/TestToken.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract TestToken is ERC20 {\n constructor()\n // solhint-disable-next-line no-empty-blocks\n ERC20(\"TST\", \"TestToken\")\n {}\n\n function mint(address sender, uint256 amount) external {\n _mint(sender, amount);\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 999999 + }, + "evmVersion": "paris", + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/deployments/base/solcInputs/4356503edd8ae34e73cb6dd1c8e2fc8a.json b/deployments/base/solcInputs/4356503edd8ae34e73cb6dd1c8e2fc8a.json new file mode 100644 index 0000000..db88715 --- /dev/null +++ b/deployments/base/solcInputs/4356503edd8ae34e73cb6dd1c8e2fc8a.json @@ -0,0 +1,354 @@ +{ + "language": "Solidity", + "sources": { + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby disabling any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable2Step.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./Ownable.sol\";\n\n/**\n * @dev Contract module which provides access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership} and {acceptOwnership}.\n *\n * This module is used through inheritance. It will make available all functions\n * from parent (Ownable).\n */\nabstract contract Ownable2Step is Ownable {\n address private _pendingOwner;\n\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Returns the address of the pending owner.\n */\n function pendingOwner() public view virtual returns (address) {\n return _pendingOwner;\n }\n\n /**\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual override onlyOwner {\n _pendingOwner = newOwner;\n emit OwnershipTransferStarted(owner(), newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual override {\n delete _pendingOwner;\n super._transferOwnership(newOwner);\n }\n\n /**\n * @dev The new owner accepts the ownership transfer.\n */\n function acceptOwnership() public virtual {\n address sender = _msgSender();\n require(pendingOwner() == sender, \"Ownable2Step: caller is not the new owner\");\n _transferOwnership(sender);\n }\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC1271.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC1271 standard signature validation method for\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\n *\n * _Available since v4.1._\n */\ninterface IERC1271 {\n /**\n * @dev Should return whether the signature provided is valid for the provided data\n * @param hash Hash of the data to be signed\n * @param signature Signature byte array associated with _data\n */\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\n}\n" + }, + "@openzeppelin/contracts/security/ReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor() {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n _nonReentrantBefore();\n _;\n _nonReentrantAfter();\n }\n\n function _nonReentrantBefore() private {\n // On the first call to nonReentrant, _status will be _NOT_ENTERED\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n }\n\n function _nonReentrantAfter() private {\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Returns true if the reentrancy guard is currently set to \"entered\", which indicates there is a\n * `nonReentrant` function in the call stack.\n */\n function _reentrancyGuardEntered() internal view returns (bool) {\n return _status == _ENTERED;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/ERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/ERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC1155.sol\";\nimport \"./IERC1155Receiver.sol\";\nimport \"./extensions/IERC1155MetadataURI.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of the basic standard multi-token.\n * See https://eips.ethereum.org/EIPS/eip-1155\n * Originally based on code by Enjin: https://github.com/enjin/erc-1155\n *\n * _Available since v3.1._\n */\ncontract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {\n using Address for address;\n\n // Mapping from token ID to account balances\n mapping(uint256 => mapping(address => uint256)) private _balances;\n\n // Mapping from account to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json\n string private _uri;\n\n /**\n * @dev See {_setURI}.\n */\n constructor(string memory uri_) {\n _setURI(uri_);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return\n interfaceId == type(IERC1155).interfaceId ||\n interfaceId == type(IERC1155MetadataURI).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC1155MetadataURI-uri}.\n *\n * This implementation returns the same URI for *all* token types. It relies\n * on the token type ID substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * Clients calling this function must replace the `\\{id\\}` substring with the\n * actual token type ID.\n */\n function uri(uint256) public view virtual override returns (string memory) {\n return _uri;\n }\n\n /**\n * @dev See {IERC1155-balanceOf}.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {\n require(account != address(0), \"ERC1155: address zero is not a valid owner\");\n return _balances[id][account];\n }\n\n /**\n * @dev See {IERC1155-balanceOfBatch}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] memory accounts,\n uint256[] memory ids\n ) public view virtual override returns (uint256[] memory) {\n require(accounts.length == ids.length, \"ERC1155: accounts and ids length mismatch\");\n\n uint256[] memory batchBalances = new uint256[](accounts.length);\n\n for (uint256 i = 0; i < accounts.length; ++i) {\n batchBalances[i] = balanceOf(accounts[i], ids[i]);\n }\n\n return batchBalances;\n }\n\n /**\n * @dev See {IERC1155-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC1155-isApprovedForAll}.\n */\n function isApprovedForAll(address account, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[account][operator];\n }\n\n /**\n * @dev See {IERC1155-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n _safeTransferFrom(from, to, id, amount, data);\n }\n\n /**\n * @dev See {IERC1155-safeBatchTransferFrom}.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n _safeBatchTransferFrom(from, to, ids, amounts, data);\n }\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n\n emit TransferSingle(operator, from, to, id, amount);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n for (uint256 i = 0; i < ids.length; ++i) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n }\n\n emit TransferBatch(operator, from, to, ids, amounts);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\n\n _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);\n }\n\n /**\n * @dev Sets a new URI for all token types, by relying on the token type ID\n * substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * By this mechanism, any occurrence of the `\\{id\\}` substring in either the\n * URI or any of the amounts in the JSON file at said URI will be replaced by\n * clients with the token type ID.\n *\n * For example, the `https://token-cdn-domain/\\{id\\}.json` URI would be\n * interpreted by clients as\n * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`\n * for token type ID 0x4cce0.\n *\n * See {uri}.\n *\n * Because these URIs cannot be meaningfully represented by the {URI} event,\n * this function emits no events.\n */\n function _setURI(string memory newuri) internal virtual {\n _uri = newuri;\n }\n\n /**\n * @dev Creates `amount` tokens of token type `id`, and assigns them to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _mint(address to, uint256 id, uint256 amount, bytes memory data) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _balances[id][to] += amount;\n emit TransferSingle(operator, address(0), to, id, amount);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n for (uint256 i = 0; i < ids.length; i++) {\n _balances[ids[i]][to] += amounts[i];\n }\n\n emit TransferBatch(operator, address(0), to, ids, amounts);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);\n }\n\n /**\n * @dev Destroys `amount` tokens of token type `id` from `from`\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `from` must have at least `amount` tokens of token type `id`.\n */\n function _burn(address from, uint256 id, uint256 amount) internal virtual {\n require(from != address(0), \"ERC1155: burn from the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n\n emit TransferSingle(operator, from, address(0), id, amount);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n */\n function _burnBatch(address from, uint256[] memory ids, uint256[] memory amounts) internal virtual {\n require(from != address(0), \"ERC1155: burn from the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n\n for (uint256 i = 0; i < ids.length; i++) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n }\n\n emit TransferBatch(operator, from, address(0), ids, amounts);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {\n require(owner != operator, \"ERC1155: setting approval status for self\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning, as well as batched variants.\n *\n * The same hook is called on both single and batched variants. For single\n * transfers, the length of the `ids` and `amounts` arrays will be 1.\n *\n * Calling conditions (for each `id` and `amount` pair):\n *\n * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * of token type `id` will be transferred to `to`.\n * - When `from` is zero, `amount` tokens of token type `id` will be minted\n * for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n * will be burned.\n * - `from` and `to` are never both zero.\n * - `ids` and `amounts` have the same, non-zero length.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any token transfer. This includes minting\n * and burning, as well as batched variants.\n *\n * The same hook is called on both single and batched variants. For single\n * transfers, the length of the `id` and `amount` arrays will be 1.\n *\n * Calling conditions (for each `id` and `amount` pair):\n *\n * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * of token type `id` will be transferred to `to`.\n * - When `from` is zero, `amount` tokens of token type `id` will be minted\n * for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n * will be burned.\n * - `from` and `to` are never both zero.\n * - `ids` and `amounts` have the same, non-zero length.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {}\n\n function _doSafeTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155Receiver.onERC1155Received.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non-ERC1155Receiver implementer\");\n }\n }\n }\n\n function _doSafeBatchTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (\n bytes4 response\n ) {\n if (response != IERC1155Receiver.onERC1155BatchReceived.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non-ERC1155Receiver implementer\");\n }\n }\n }\n\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {\n uint256[] memory array = new uint256[](1);\n array[0] = element;\n\n return array;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC1155.sol\";\n\n/**\n * @dev Interface of the optional ERC1155MetadataExtension interface, as defined\n * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155MetadataURI is IERC1155 {\n /**\n * @dev Returns the URI for token type `id`.\n *\n * If the `\\{id\\}` substring is present in the URI, it must be replaced by\n * clients with the actual token type ID.\n */\n function uri(uint256 id) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155 is IERC165 {\n /**\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n */\n event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);\n\n /**\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n * transfers.\n */\n event TransferBatch(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\n\n /**\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n * `approved`.\n */\n event ApprovalForAll(address indexed account, address indexed operator, bool approved);\n\n /**\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n *\n * If an {URI} event was emitted for `id`, the standard\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n * returned by {IERC1155MetadataURI-uri}.\n */\n event URI(string value, uint256 indexed id);\n\n /**\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) external view returns (uint256);\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] calldata accounts,\n uint256[] calldata ids\n ) external view returns (uint256[] memory);\n\n /**\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n *\n * Emits an {ApprovalForAll} event.\n *\n * Requirements:\n *\n * - `operator` cannot be the caller.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n *\n * See {setApprovalForAll}.\n */\n function isApprovedForAll(address account, address operator) external view returns (bool);\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155Receiver is IERC165 {\n /**\n * @dev Handles the receipt of a single ERC1155 token type. This function is\n * called at the end of a `safeTransferFrom` after the balance has been updated.\n *\n * NOTE: To accept the transfer, this must return\n * `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n * (i.e. 0xf23a6e61, or its own function selector).\n *\n * @param operator The address which initiated the transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param id The ID of the token being transferred\n * @param value The amount of tokens being transferred\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n ) external returns (bytes4);\n\n /**\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\n * is called at the end of a `safeBatchTransferFrom` after the balances have\n * been updated.\n *\n * NOTE: To accept the transfer(s), this must return\n * `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n * (i.e. 0xbc197c81, or its own function selector).\n *\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the default value returned by this function, unless\n * it's overridden.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(address from, address to, uint256 amount) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\n // decrementing then incrementing.\n _balances[to] += amount;\n }\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n unchecked {\n // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\n _balances[account] += amount;\n }\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n // Overflow not possible: amount <= accountBalance <= totalSupply.\n _totalSupply -= amount;\n }\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\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" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` 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 amount) 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 `amount` as the allowance of `spender` over the 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 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` 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 amount) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/ERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721.sol\";\nimport \"./IERC721Receiver.sol\";\nimport \"./extensions/IERC721Metadata.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/Strings.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\n using Address for address;\n using Strings for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\n\n // Mapping from token ID to approved address\n mapping(uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return\n interfaceId == type(IERC721).interfaceId ||\n interfaceId == type(IERC721Metadata).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _ownerOf(tokenId);\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token owner or approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n _requireMinted(tokenId);\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n _safeTransfer(from, to, tokenId, data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(address from, address to, uint256 tokenId, bytes memory data) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist\n */\n function _ownerOf(uint256 tokenId) internal view virtual returns (address) {\n return _owners[tokenId];\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _ownerOf(tokenId) != address(0);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n address owner = ERC721.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(address to, uint256 tokenId, bytes memory data) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId, 1);\n\n // Check that tokenId was not minted by `_beforeTokenTransfer` hook\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n unchecked {\n // Will not overflow unless all 2**256 token ids are minted to the same owner.\n // Given that tokens are minted one by one, it is impossible in practice that\n // this ever happens. Might change if we allow batch minting.\n // The ERC fails to describe this case.\n _balances[to] += 1;\n }\n\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(address(0), to, tokenId, 1);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n * This is an internal function that does not check if the sender is authorized to operate on the token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId, 1);\n\n // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook\n owner = ERC721.ownerOf(tokenId);\n\n // Clear approvals\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // Cannot overflow, as that would require more tokens to be burned/transferred\n // out than the owner initially received through minting and transferring in.\n _balances[owner] -= 1;\n }\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(owner, address(0), tokenId, 1);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(address from, address to, uint256 tokenId) internal virtual {\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId, 1);\n\n // Check that tokenId was not transferred by `_beforeTokenTransfer` hook\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n\n // Clear approvals from the previous owner\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // `_balances[from]` cannot overflow for the same reason as described in `_burn`:\n // `from`'s balance is the number of token held, which is at least one before the current\n // transfer.\n // `_balances[to]` could overflow in the conditions described in `_mint`. That would require\n // all 2**256 token ids to be minted, which in practice is impossible.\n _balances[from] -= 1;\n _balances[to] += 1;\n }\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId, 1);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721Receiver.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`.\n * - When `from` is zero, the tokens will be minted for `to`.\n * - When `to` is zero, ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}\n\n /**\n * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`.\n * - When `from` is zero, the tokens were minted for `to`.\n * - When `to` is zero, ``from``'s tokens were burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}\n\n /**\n * @dev Unsafe write access to the balances, used by extensions that \"mint\" tokens using an {ownerOf} override.\n *\n * WARNING: Anyone calling this MUST ensure that the balances remain consistent with the ownership. The invariant\n * being that for any address `a` the value returned by `balanceOf(a)` must be equal to the number of tokens such\n * that `ownerOf(tokenId)` is `a`.\n */\n // solhint-disable-next-line func-name-mixedcase\n function __unsafe_increaseBalance(address account, uint256 amount) internal {\n _balances[account] += amount;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721Receiver {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/ERC777.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC777/ERC777.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC777.sol\";\nimport \"./IERC777Recipient.sol\";\nimport \"./IERC777Sender.sol\";\nimport \"../ERC20/IERC20.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/introspection/IERC1820Registry.sol\";\n\n/**\n * @dev Implementation of the {IERC777} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n *\n * Support for ERC20 is included in this contract, as specified by the EIP: both\n * the ERC777 and ERC20 interfaces can be safely used when interacting with it.\n * Both {IERC777-Sent} and {IERC20-Transfer} events are emitted on token\n * movements.\n *\n * Additionally, the {IERC777-granularity} value is hard-coded to `1`, meaning that there\n * are no special restrictions in the amount of tokens that created, moved, or\n * destroyed. This makes integration with ERC20 applications seamless.\n *\n * CAUTION: This file is deprecated as of v4.9 and will be removed in the next major release.\n */\ncontract ERC777 is Context, IERC777, IERC20 {\n using Address for address;\n\n IERC1820Registry internal constant _ERC1820_REGISTRY = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n mapping(address => uint256) private _balances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n bytes32 private constant _TOKENS_SENDER_INTERFACE_HASH = keccak256(\"ERC777TokensSender\");\n bytes32 private constant _TOKENS_RECIPIENT_INTERFACE_HASH = keccak256(\"ERC777TokensRecipient\");\n\n // This isn't ever read from - it's only used to respond to the defaultOperators query.\n address[] private _defaultOperatorsArray;\n\n // Immutable, but accounts may revoke them (tracked in __revokedDefaultOperators).\n mapping(address => bool) private _defaultOperators;\n\n // For each account, a mapping of its operators and revoked default operators.\n mapping(address => mapping(address => bool)) private _operators;\n mapping(address => mapping(address => bool)) private _revokedDefaultOperators;\n\n // ERC20-allowances\n mapping(address => mapping(address => uint256)) private _allowances;\n\n /**\n * @dev `defaultOperators` may be an empty array.\n */\n constructor(string memory name_, string memory symbol_, address[] memory defaultOperators_) {\n _name = name_;\n _symbol = symbol_;\n\n _defaultOperatorsArray = defaultOperators_;\n for (uint256 i = 0; i < defaultOperators_.length; i++) {\n _defaultOperators[defaultOperators_[i]] = true;\n }\n\n // register interfaces\n _ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256(\"ERC777Token\"), address(this));\n _ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256(\"ERC20Token\"), address(this));\n }\n\n /**\n * @dev See {IERC777-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC777-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {ERC20-decimals}.\n *\n * Always returns 18, as per the\n * [ERC777 EIP](https://eips.ethereum.org/EIPS/eip-777#backward-compatibility).\n */\n function decimals() public pure virtual returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC777-granularity}.\n *\n * This implementation always returns `1`.\n */\n function granularity() public view virtual override returns (uint256) {\n return 1;\n }\n\n /**\n * @dev See {IERC777-totalSupply}.\n */\n function totalSupply() public view virtual override(IERC20, IERC777) returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev Returns the amount of tokens owned by an account (`tokenHolder`).\n */\n function balanceOf(address tokenHolder) public view virtual override(IERC20, IERC777) returns (uint256) {\n return _balances[tokenHolder];\n }\n\n /**\n * @dev See {IERC777-send}.\n *\n * Also emits a {IERC20-Transfer} event for ERC20 compatibility.\n */\n function send(address recipient, uint256 amount, bytes memory data) public virtual override {\n _send(_msgSender(), recipient, amount, data, \"\", true);\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Unlike `send`, `recipient` is _not_ required to implement the {IERC777Recipient}\n * interface if it is a contract.\n *\n * Also emits a {Sent} event.\n */\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n _send(_msgSender(), recipient, amount, \"\", \"\", false);\n return true;\n }\n\n /**\n * @dev See {IERC777-burn}.\n *\n * Also emits a {IERC20-Transfer} event for ERC20 compatibility.\n */\n function burn(uint256 amount, bytes memory data) public virtual override {\n _burn(_msgSender(), amount, data, \"\");\n }\n\n /**\n * @dev See {IERC777-isOperatorFor}.\n */\n function isOperatorFor(address operator, address tokenHolder) public view virtual override returns (bool) {\n return\n operator == tokenHolder ||\n (_defaultOperators[operator] && !_revokedDefaultOperators[tokenHolder][operator]) ||\n _operators[tokenHolder][operator];\n }\n\n /**\n * @dev See {IERC777-authorizeOperator}.\n */\n function authorizeOperator(address operator) public virtual override {\n require(_msgSender() != operator, \"ERC777: authorizing self as operator\");\n\n if (_defaultOperators[operator]) {\n delete _revokedDefaultOperators[_msgSender()][operator];\n } else {\n _operators[_msgSender()][operator] = true;\n }\n\n emit AuthorizedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-revokeOperator}.\n */\n function revokeOperator(address operator) public virtual override {\n require(operator != _msgSender(), \"ERC777: revoking self as operator\");\n\n if (_defaultOperators[operator]) {\n _revokedDefaultOperators[_msgSender()][operator] = true;\n } else {\n delete _operators[_msgSender()][operator];\n }\n\n emit RevokedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-defaultOperators}.\n */\n function defaultOperators() public view virtual override returns (address[] memory) {\n return _defaultOperatorsArray;\n }\n\n /**\n * @dev See {IERC777-operatorSend}.\n *\n * Emits {Sent} and {IERC20-Transfer} events.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes memory data,\n bytes memory operatorData\n ) public virtual override {\n require(isOperatorFor(_msgSender(), sender), \"ERC777: caller is not an operator for holder\");\n _send(sender, recipient, amount, data, operatorData, true);\n }\n\n /**\n * @dev See {IERC777-operatorBurn}.\n *\n * Emits {Burned} and {IERC20-Transfer} events.\n */\n function operatorBurn(\n address account,\n uint256 amount,\n bytes memory data,\n bytes memory operatorData\n ) public virtual override {\n require(isOperatorFor(_msgSender(), account), \"ERC777: caller is not an operator for holder\");\n _burn(account, amount, data, operatorData);\n }\n\n /**\n * @dev See {IERC20-allowance}.\n *\n * Note that operator and allowance concepts are orthogonal: operators may\n * not have allowance, and accounts with allowance may not be operators\n * themselves.\n */\n function allowance(address holder, address spender) public view virtual override returns (uint256) {\n return _allowances[holder][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Note that accounts cannot have allowance issued by their operators.\n */\n function approve(address spender, uint256 value) public virtual override returns (bool) {\n address holder = _msgSender();\n _approve(holder, spender, value);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Note that operator and allowance concepts are orthogonal: operators cannot\n * call `transferFrom` (unless they have allowance), and accounts with\n * allowance cannot call `operatorSend` (unless they are operators).\n *\n * Emits {Sent}, {IERC20-Transfer} and {IERC20-Approval} events.\n */\n function transferFrom(address holder, address recipient, uint256 amount) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(holder, spender, amount);\n _send(holder, recipient, amount, \"\", \"\", false);\n return true;\n }\n\n /**\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with the caller address as the `operator` and with\n * `userData` and `operatorData`.\n *\n * See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits {Minted} and {IERC20-Transfer} events.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - if `account` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function _mint(address account, uint256 amount, bytes memory userData, bytes memory operatorData) internal virtual {\n _mint(account, amount, userData, operatorData, true);\n }\n\n /**\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * If `requireReceptionAck` is set to true, and if a send hook is\n * registered for `account`, the corresponding function will be called with\n * `operator`, `data` and `operatorData`.\n *\n * See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits {Minted} and {IERC20-Transfer} events.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - if `account` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function _mint(\n address account,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) internal virtual {\n require(account != address(0), \"ERC777: mint to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), account, amount);\n\n // Update state variables\n _totalSupply += amount;\n _balances[account] += amount;\n\n _callTokensReceived(operator, address(0), account, amount, userData, operatorData, requireReceptionAck);\n\n emit Minted(operator, account, amount, userData, operatorData);\n emit Transfer(address(0), account, amount);\n }\n\n /**\n * @dev Send tokens\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _send(\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) internal virtual {\n require(from != address(0), \"ERC777: transfer from the zero address\");\n require(to != address(0), \"ERC777: transfer to the zero address\");\n\n address operator = _msgSender();\n\n _callTokensToSend(operator, from, to, amount, userData, operatorData);\n\n _move(operator, from, to, amount, userData, operatorData);\n\n _callTokensReceived(operator, from, to, amount, userData, operatorData, requireReceptionAck);\n }\n\n /**\n * @dev Burn tokens\n * @param from address token holder address\n * @param amount uint256 amount of tokens to burn\n * @param data bytes extra information provided by the token holder\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _burn(address from, uint256 amount, bytes memory data, bytes memory operatorData) internal virtual {\n require(from != address(0), \"ERC777: burn from the zero address\");\n\n address operator = _msgSender();\n\n _callTokensToSend(operator, from, address(0), amount, data, operatorData);\n\n _beforeTokenTransfer(operator, from, address(0), amount);\n\n // Update state variables\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC777: burn amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Burned(operator, from, amount, data, operatorData);\n emit Transfer(from, address(0), amount);\n }\n\n function _move(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n ) private {\n _beforeTokenTransfer(operator, from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC777: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Sent(operator, from, to, amount, userData, operatorData);\n emit Transfer(from, to, amount);\n }\n\n /**\n * @dev See {ERC20-_approve}.\n *\n * Note that accounts cannot have allowance issued by their operators.\n */\n function _approve(address holder, address spender, uint256 value) internal virtual {\n require(holder != address(0), \"ERC777: approve from the zero address\");\n require(spender != address(0), \"ERC777: approve to the zero address\");\n\n _allowances[holder][spender] = value;\n emit Approval(holder, spender, value);\n }\n\n /**\n * @dev Call from.tokensToSend() if the interface is registered\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _callTokensToSend(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n ) private {\n address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(from, _TOKENS_SENDER_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Sender(implementer).tokensToSend(operator, from, to, amount, userData, operatorData);\n }\n }\n\n /**\n * @dev Call to.tokensReceived() if the interface is registered. Reverts if the recipient is a contract but\n * tokensReceived() was not registered for the recipient\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _callTokensReceived(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) private {\n address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(to, _TOKENS_RECIPIENT_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Recipient(implementer).tokensReceived(operator, from, to, amount, userData, operatorData);\n } else if (requireReceptionAck) {\n require(!to.isContract(), \"ERC777: token recipient contract has no implementer for ERC777TokensRecipient\");\n }\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {IERC20-Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC777: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes\n * calls to {send}, {transfer}, {operatorSend}, {transferFrom}, minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be to transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address operator, address from, address to, uint256 amount) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC777/IERC777.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777Token standard as defined in the EIP.\n *\n * This contract uses the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 registry standard] to let\n * token holders and recipients react to token movements by using setting implementers\n * for the associated interfaces in said registry. See {IERC1820Registry} and\n * {ERC1820Implementer}.\n */\ninterface IERC777 {\n /**\n * @dev Emitted when `amount` tokens are created by `operator` and assigned to `to`.\n *\n * Note that some additional user `data` and `operatorData` can be logged in the event.\n */\n event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);\n\n /**\n * @dev Emitted when `operator` destroys `amount` tokens from `account`.\n *\n * Note that some additional user `data` and `operatorData` can be logged in the event.\n */\n event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);\n\n /**\n * @dev Emitted when `operator` is made operator for `tokenHolder`.\n */\n event AuthorizedOperator(address indexed operator, address indexed tokenHolder);\n\n /**\n * @dev Emitted when `operator` is revoked its operator status for `tokenHolder`.\n */\n event RevokedOperator(address indexed operator, address indexed tokenHolder);\n\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, usually a shorter version of the\n * name.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the smallest part of the token that is not divisible. This\n * means all token operations (creation, movement and destruction) must have\n * amounts that are a multiple of this number.\n *\n * For most token contracts, this value will equal 1.\n */\n function granularity() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by an account (`owner`).\n */\n function balanceOf(address owner) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * If send or receive hooks are registered for the caller and `recipient`,\n * the corresponding functions will be called with `data` and empty\n * `operatorData`. See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits a {Sent} event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function send(address recipient, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Destroys `amount` tokens from the caller's account, reducing the\n * total supply.\n *\n * If a send hook is registered for the caller, the corresponding function\n * will be called with `data` and empty `operatorData`. See {IERC777Sender}.\n *\n * Emits a {Burned} event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n */\n function burn(uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Returns true if an account is an operator of `tokenHolder`.\n * Operators can send and burn tokens on behalf of their owners. All\n * accounts are their own operator.\n *\n * See {operatorSend} and {operatorBurn}.\n */\n function isOperatorFor(address operator, address tokenHolder) external view returns (bool);\n\n /**\n * @dev Make an account an operator of the caller.\n *\n * See {isOperatorFor}.\n *\n * Emits an {AuthorizedOperator} event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function authorizeOperator(address operator) external;\n\n /**\n * @dev Revoke an account's operator status for the caller.\n *\n * See {isOperatorFor} and {defaultOperators}.\n *\n * Emits a {RevokedOperator} event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function revokeOperator(address operator) external;\n\n /**\n * @dev Returns the list of default operators. These accounts are operators\n * for all token holders, even if {authorizeOperator} was never called on\n * them.\n *\n * This list is immutable, but individual holders may revoke these via\n * {revokeOperator}, in which case {isOperatorFor} will return false.\n */\n function defaultOperators() external view returns (address[] memory);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must\n * be an operator of `sender`.\n *\n * If send or receive hooks are registered for `sender` and `recipient`,\n * the corresponding functions will be called with `data` and\n * `operatorData`. See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits a {Sent} event.\n *\n * Requirements\n *\n * - `sender` cannot be the zero address.\n * - `sender` must have at least `amount` tokens.\n * - the caller must be an operator for `sender`.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes calldata data,\n bytes calldata operatorData\n ) external;\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the total supply.\n * The caller must be an operator of `account`.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with `data` and `operatorData`. See {IERC777Sender}.\n *\n * Emits a {Burned} event.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n * - the caller must be an operator for `account`.\n */\n function operatorBurn(address account, uint256 amount, bytes calldata data, bytes calldata operatorData) external;\n\n event Sent(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes data,\n bytes operatorData\n );\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\n *\n * Accounts can be notified of {IERC777} tokens being sent to them by having a\n * contract implement this interface (contract holders can be their own\n * implementer) and registering it on the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\n *\n * See {IERC1820Registry} and {ERC1820Implementer}.\n */\ninterface IERC777Recipient {\n /**\n * @dev Called by an {IERC777} token contract whenever tokens are being\n * moved or created into a registered account (`to`). The type of operation\n * is conveyed by `from` being the zero address or not.\n *\n * This call occurs _after_ the token contract's state is updated, so\n * {IERC777-balanceOf}, etc., can be used to query the post-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensReceived(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777Sender.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Sender.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777TokensSender standard as defined in the EIP.\n *\n * {IERC777} Token holders can be notified of operations performed on their\n * tokens by having a contract implement this interface (contract holders can be\n * their own implementer) and registering it on the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\n *\n * See {IERC1820Registry} and {ERC1820Implementer}.\n */\ninterface IERC777Sender {\n /**\n * @dev Called by an {IERC777} token contract whenever a registered holder's\n * (`from`) tokens are about to be moved or destroyed. The type of operation\n * is conveyed by `to` being the zero address or not.\n *\n * This call occurs _before_ the token contract's state is updated, so\n * {IERC777-balanceOf}, etc., can be used to query the pre-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensToSend(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n *\n * Furthermore, `isContract` will also return true if the target contract within\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n * which only has an effect at the end of a transaction.\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Counters.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary Counters {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/ECDSA.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Strings.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV // Deprecated in v4.8\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n /// @solidity memory-safe-assembly\n assembly {\n mstore(0x00, \"\\x19Ethereum Signed Message:\\n32\")\n mstore(0x1c, hash)\n message := keccak256(0x00, 0x3c)\n }\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\n /// @solidity memory-safe-assembly\n assembly {\n let ptr := mload(0x40)\n mstore(ptr, \"\\x19\\x01\")\n mstore(add(ptr, 0x02), domainSeparator)\n mstore(add(ptr, 0x22), structHash)\n data := keccak256(ptr, 0x42)\n }\n }\n\n /**\n * @dev Returns an Ethereum Signed Data with intended validator, created from a\n * `validator` and `data` according to the version 0 of EIP-191.\n *\n * See {recover}.\n */\n function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x00\", validator, data));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/SignatureChecker.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSA.sol\";\nimport \"../../interfaces/IERC1271.sol\";\n\n/**\n * @dev Signature verification helper that can be used instead of `ECDSA.recover` to seamlessly support both ECDSA\n * signatures from externally owned accounts (EOAs) as well as ERC1271 signatures from smart contract wallets like\n * Argent and Gnosis Safe.\n *\n * _Available since v4.1._\n */\nlibrary SignatureChecker {\n /**\n * @dev Checks if a signature is valid for a given signer and data hash. If the signer is a smart contract, the\n * signature is validated against that smart contract using ERC1271, otherwise it's validated using `ECDSA.recover`.\n *\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\n */\n function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature) internal view returns (bool) {\n (address recovered, ECDSA.RecoverError error) = ECDSA.tryRecover(hash, signature);\n return\n (error == ECDSA.RecoverError.NoError && recovered == signer) ||\n isValidERC1271SignatureNow(signer, hash, signature);\n }\n\n /**\n * @dev Checks if a signature is valid for a given signer and data hash. The signature is validated\n * against the signer smart contract using ERC1271.\n *\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\n */\n function isValidERC1271SignatureNow(\n address signer,\n bytes32 hash,\n bytes memory signature\n ) internal view returns (bool) {\n (bool success, bytes memory result) = signer.staticcall(\n abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, signature)\n );\n return (success &&\n result.length >= 32 &&\n abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/ERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165 is IERC165 {\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165).interfaceId;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC1820Registry.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/introspection/IERC1820Registry.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the global ERC1820 Registry, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register\n * implementers for interfaces in this registry, as well as query support.\n *\n * Implementers may be shared by multiple accounts, and can also implement more\n * than a single interface for each account. Contracts can implement interfaces\n * for themselves, but externally-owned accounts (EOA) must delegate this to a\n * contract.\n *\n * {IERC165} interfaces can also be queried via the registry.\n *\n * For an in-depth explanation and source code analysis, see the EIP text.\n */\ninterface IERC1820Registry {\n event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer);\n\n event ManagerChanged(address indexed account, address indexed newManager);\n\n /**\n * @dev Sets `newManager` as the manager for `account`. A manager of an\n * account is able to set interface implementers for it.\n *\n * By default, each account is its own manager. Passing a value of `0x0` in\n * `newManager` will reset the manager to this initial state.\n *\n * Emits a {ManagerChanged} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `account`.\n */\n function setManager(address account, address newManager) external;\n\n /**\n * @dev Returns the manager for `account`.\n *\n * See {setManager}.\n */\n function getManager(address account) external view returns (address);\n\n /**\n * @dev Sets the `implementer` contract as ``account``'s implementer for\n * `interfaceHash`.\n *\n * `account` being the zero address is an alias for the caller's address.\n * The zero address can also be used in `implementer` to remove an old one.\n *\n * See {interfaceHash} to learn how these are created.\n *\n * Emits an {InterfaceImplementerSet} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `account`.\n * - `interfaceHash` must not be an {IERC165} interface id (i.e. it must not\n * end in 28 zeroes).\n * - `implementer` must implement {IERC1820Implementer} and return true when\n * queried for support, unless `implementer` is the caller. See\n * {IERC1820Implementer-canImplementInterfaceForAddress}.\n */\n function setInterfaceImplementer(address account, bytes32 _interfaceHash, address implementer) external;\n\n /**\n * @dev Returns the implementer of `interfaceHash` for `account`. If no such\n * implementer is registered, returns the zero address.\n *\n * If `interfaceHash` is an {IERC165} interface id (i.e. it ends with 28\n * zeroes), `account` will be queried for support of it.\n *\n * `account` being the zero address is an alias for the caller's address.\n */\n function getInterfaceImplementer(address account, bytes32 _interfaceHash) external view returns (address);\n\n /**\n * @dev Returns the interface hash for an `interfaceName`, as defined in the\n * corresponding\n * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP].\n */\n function interfaceHash(string calldata interfaceName) external pure returns (bytes32);\n\n /**\n * @notice Updates the cache with whether the contract implements an ERC165 interface or not.\n * @param account Address of the contract for which to update the cache.\n * @param interfaceId ERC165 interface for which to update the cache.\n */\n function updateERC165Cache(address account, bytes4 interfaceId) external;\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not.\n * If the result is not cached a direct lookup on the contract address is performed.\n * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling\n * {updateERC165Cache} with the contract address.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool);\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not without using or updating the cache.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/math/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\n // The surrounding unchecked block does not change this fact.\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1, \"Math: mulDiv overflow\");\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n //\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n //\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n //\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1 << (log2(a) >> 1);\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = sqrt(a);\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 2, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 128;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 64;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 32;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 16;\n }\n if (value >> 8 > 0) {\n value >>= 8;\n result += 8;\n }\n if (value >> 4 > 0) {\n value >>= 4;\n result += 4;\n }\n if (value >> 2 > 0) {\n value >>= 2;\n result += 2;\n }\n if (value >> 1 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log2(value);\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 10, rounded down, of a positive value.\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 + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 256, rounded down, of a positive value.\n * Returns 0 if given 0.\n *\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n */\n function log256(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 16;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 8;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 4;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 2;\n }\n if (value >> 8 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log256(value);\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/SafeCast.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCast {\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 * _Available since v4.7._\n */\n function toUint248(uint256 value) internal pure returns (uint248) {\n require(value <= type(uint248).max, \"SafeCast: value doesn't fit in 248 bits\");\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 * _Available since v4.7._\n */\n function toUint240(uint256 value) internal pure returns (uint240) {\n require(value <= type(uint240).max, \"SafeCast: value doesn't fit in 240 bits\");\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 * _Available since v4.7._\n */\n function toUint232(uint256 value) internal pure returns (uint232) {\n require(value <= type(uint232).max, \"SafeCast: value doesn't fit in 232 bits\");\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 * _Available since v4.2._\n */\n function toUint224(uint256 value) internal pure returns (uint224) {\n require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\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 * _Available since v4.7._\n */\n function toUint216(uint256 value) internal pure returns (uint216) {\n require(value <= type(uint216).max, \"SafeCast: value doesn't fit in 216 bits\");\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 * _Available since v4.7._\n */\n function toUint208(uint256 value) internal pure returns (uint208) {\n require(value <= type(uint208).max, \"SafeCast: value doesn't fit in 208 bits\");\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 * _Available since v4.7._\n */\n function toUint200(uint256 value) internal pure returns (uint200) {\n require(value <= type(uint200).max, \"SafeCast: value doesn't fit in 200 bits\");\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 * _Available since v4.7._\n */\n function toUint192(uint256 value) internal pure returns (uint192) {\n require(value <= type(uint192).max, \"SafeCast: value doesn't fit in 192 bits\");\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 * _Available since v4.7._\n */\n function toUint184(uint256 value) internal pure returns (uint184) {\n require(value <= type(uint184).max, \"SafeCast: value doesn't fit in 184 bits\");\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 * _Available since v4.7._\n */\n function toUint176(uint256 value) internal pure returns (uint176) {\n require(value <= type(uint176).max, \"SafeCast: value doesn't fit in 176 bits\");\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 * _Available since v4.7._\n */\n function toUint168(uint256 value) internal pure returns (uint168) {\n require(value <= type(uint168).max, \"SafeCast: value doesn't fit in 168 bits\");\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 * _Available since v4.7._\n */\n function toUint160(uint256 value) internal pure returns (uint160) {\n require(value <= type(uint160).max, \"SafeCast: value doesn't fit in 160 bits\");\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 * _Available since v4.7._\n */\n function toUint152(uint256 value) internal pure returns (uint152) {\n require(value <= type(uint152).max, \"SafeCast: value doesn't fit in 152 bits\");\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 * _Available since v4.7._\n */\n function toUint144(uint256 value) internal pure returns (uint144) {\n require(value <= type(uint144).max, \"SafeCast: value doesn't fit in 144 bits\");\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 * _Available since v4.7._\n */\n function toUint136(uint256 value) internal pure returns (uint136) {\n require(value <= type(uint136).max, \"SafeCast: value doesn't fit in 136 bits\");\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 * _Available since v2.5._\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\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 * _Available since v4.7._\n */\n function toUint120(uint256 value) internal pure returns (uint120) {\n require(value <= type(uint120).max, \"SafeCast: value doesn't fit in 120 bits\");\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 * _Available since v4.7._\n */\n function toUint112(uint256 value) internal pure returns (uint112) {\n require(value <= type(uint112).max, \"SafeCast: value doesn't fit in 112 bits\");\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 * _Available since v4.7._\n */\n function toUint104(uint256 value) internal pure returns (uint104) {\n require(value <= type(uint104).max, \"SafeCast: value doesn't fit in 104 bits\");\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 * _Available since v4.2._\n */\n function toUint96(uint256 value) internal pure returns (uint96) {\n require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\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 * _Available since v4.7._\n */\n function toUint88(uint256 value) internal pure returns (uint88) {\n require(value <= type(uint88).max, \"SafeCast: value doesn't fit in 88 bits\");\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 * _Available since v4.7._\n */\n function toUint80(uint256 value) internal pure returns (uint80) {\n require(value <= type(uint80).max, \"SafeCast: value doesn't fit in 80 bits\");\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 * _Available since v4.7._\n */\n function toUint72(uint256 value) internal pure returns (uint72) {\n require(value <= type(uint72).max, \"SafeCast: value doesn't fit in 72 bits\");\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 * _Available since v2.5._\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\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 * _Available since v4.7._\n */\n function toUint56(uint256 value) internal pure returns (uint56) {\n require(value <= type(uint56).max, \"SafeCast: value doesn't fit in 56 bits\");\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 * _Available since v4.7._\n */\n function toUint48(uint256 value) internal pure returns (uint48) {\n require(value <= type(uint48).max, \"SafeCast: value doesn't fit in 48 bits\");\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 * _Available since v4.7._\n */\n function toUint40(uint256 value) internal pure returns (uint40) {\n require(value <= type(uint40).max, \"SafeCast: value doesn't fit in 40 bits\");\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 * _Available since v2.5._\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\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 * _Available since v4.7._\n */\n function toUint24(uint256 value) internal pure returns (uint24) {\n require(value <= type(uint24).max, \"SafeCast: value doesn't fit in 24 bits\");\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 * _Available since v2.5._\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\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 * _Available since v2.5._\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\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 * _Available since v3.0._\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\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 * _Available since v4.7._\n */\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\n downcasted = int248(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 248 bits\");\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 * _Available since v4.7._\n */\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\n downcasted = int240(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 240 bits\");\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 * _Available since v4.7._\n */\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\n downcasted = int232(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 232 bits\");\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 * _Available since v4.7._\n */\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\n downcasted = int224(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 224 bits\");\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 * _Available since v4.7._\n */\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\n downcasted = int216(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 216 bits\");\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 * _Available since v4.7._\n */\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\n downcasted = int208(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 208 bits\");\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 * _Available since v4.7._\n */\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\n downcasted = int200(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 200 bits\");\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 * _Available since v4.7._\n */\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\n downcasted = int192(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 192 bits\");\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 * _Available since v4.7._\n */\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\n downcasted = int184(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 184 bits\");\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 * _Available since v4.7._\n */\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\n downcasted = int176(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 176 bits\");\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 * _Available since v4.7._\n */\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\n downcasted = int168(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 168 bits\");\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 * _Available since v4.7._\n */\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\n downcasted = int160(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 160 bits\");\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 * _Available since v4.7._\n */\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\n downcasted = int152(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 152 bits\");\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 * _Available since v4.7._\n */\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\n downcasted = int144(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 144 bits\");\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 * _Available since v4.7._\n */\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\n downcasted = int136(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 136 bits\");\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 * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\n downcasted = int128(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 128 bits\");\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 * _Available since v4.7._\n */\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\n downcasted = int120(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 120 bits\");\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 * _Available since v4.7._\n */\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\n downcasted = int112(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 112 bits\");\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 * _Available since v4.7._\n */\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\n downcasted = int104(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 104 bits\");\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 * _Available since v4.7._\n */\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\n downcasted = int96(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 96 bits\");\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 * _Available since v4.7._\n */\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\n downcasted = int88(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 88 bits\");\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 * _Available since v4.7._\n */\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\n downcasted = int80(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 80 bits\");\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 * _Available since v4.7._\n */\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\n downcasted = int72(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 72 bits\");\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 * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\n downcasted = int64(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 64 bits\");\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 * _Available since v4.7._\n */\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\n downcasted = int56(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 56 bits\");\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 * _Available since v4.7._\n */\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\n downcasted = int48(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 48 bits\");\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 * _Available since v4.7._\n */\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\n downcasted = int40(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 40 bits\");\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 * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\n downcasted = int32(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 32 bits\");\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 * _Available since v4.7._\n */\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\n downcasted = int24(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 24 bits\");\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 * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\n downcasted = int16(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 16 bits\");\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 * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\n downcasted = int8(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 8 bits\");\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 * _Available since v3.0._\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 require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/SignedMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard signed math utilities missing in the Solidity language.\n */\nlibrary SignedMath {\n /**\n * @dev Returns the largest of two signed numbers.\n */\n function max(int256 a, int256 b) internal pure returns (int256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two signed numbers.\n */\n function min(int256 a, int256 b) internal pure returns (int256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two signed numbers without overflow.\n * The result is rounded towards zero.\n */\n function average(int256 a, int256 b) internal pure returns (int256) {\n // Formula from the book \"Hacker's Delight\"\n int256 x = (a & b) + ((a ^ b) >> 1);\n return x + (int256(uint256(x) >> 255) & (a ^ b));\n }\n\n /**\n * @dev Returns the absolute unsigned value of a signed value.\n */\n function abs(int256 n) internal pure returns (uint256) {\n unchecked {\n // must be unchecked in order to support `n = type(int256).min`\n return uint256(n >= 0 ? n : -n);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/Math.sol\";\nimport \"./math/SignedMath.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n unchecked {\n uint256 length = Math.log10(value) + 1;\n string memory buffer = new string(length);\n uint256 ptr;\n /// @solidity memory-safe-assembly\n assembly {\n ptr := add(buffer, add(32, length))\n }\n while (true) {\n ptr--;\n /// @solidity memory-safe-assembly\n assembly {\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n }\n value /= 10;\n if (value == 0) break;\n }\n return buffer;\n }\n }\n\n /**\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\n */\n function toString(int256 value) internal pure returns (string memory) {\n return string(abi.encodePacked(value < 0 ? \"-\" : \"\", toString(SignedMath.abs(value))));\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n unchecked {\n return toHexString(value, Math.log256(value) + 1);\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n\n /**\n * @dev Returns true if the two strings are equal.\n */\n function equal(string memory a, string memory b) internal pure returns (bool) {\n return keccak256(bytes(a)) == keccak256(bytes(b));\n }\n}\n" + }, + "contracts/aa-4337/core/BaseAccount.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-empty-blocks */\n\nimport \"../interfaces/IAccount.sol\";\nimport \"../interfaces/IEntryPoint.sol\";\nimport \"./Helpers.sol\";\n\n/**\n * Basic account implementation.\n * this contract provides the basic logic for implementing the IAccount interface - validateUserOp\n * specific account implementation should inherit it and provide the account-specific logic\n */\nabstract contract BaseAccount is IAccount {\n using UserOperationLib for UserOperation;\n\n //return value in case of signature failure, with no time-range.\n // equivalent to _packValidationData(true,0,0);\n uint256 internal constant SIG_VALIDATION_FAILED = 1;\n\n /**\n * Return the account nonce.\n * This method returns the next sequential nonce.\n * For a nonce of a specific key, use `entrypoint.getNonce(account, key)`\n */\n function getNonce() public view virtual returns (uint256) {\n return entryPoint().getNonce(address(this), 0);\n }\n\n /**\n * return the entryPoint used by this account.\n * subclass should return the current entryPoint used by this account.\n */\n function entryPoint() public view virtual returns (IEntryPoint);\n\n /**\n * Validate user's signature and nonce.\n * subclass doesn't need to override this method. Instead, it should override the specific internal validation methods.\n */\n function validateUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 missingAccountFunds\n ) external virtual override returns (uint256 validationData) {\n _requireFromEntryPoint();\n validationData = _validateSignature(userOp, userOpHash);\n _validateNonce(userOp.nonce);\n _payPrefund(missingAccountFunds);\n }\n\n /**\n * ensure the request comes from the known entrypoint.\n */\n function _requireFromEntryPoint() internal view virtual {\n require(\n msg.sender == address(entryPoint()),\n \"account: not from EntryPoint\"\n );\n }\n\n /**\n * validate the signature is valid for this message.\n * @param userOp validate the userOp.signature field\n * @param userOpHash convenient field: the hash of the request, to check the signature against\n * (also hashes the entrypoint and chain id)\n * @return validationData signature and time-range of this operation\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * If the account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function _validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) internal virtual returns (uint256 validationData);\n\n /**\n * Validate the nonce of the UserOperation.\n * This method may validate the nonce requirement of this account.\n * e.g.\n * To limit the nonce to use sequenced UserOps only (no \"out of order\" UserOps):\n * `require(nonce < type(uint64).max)`\n * For a hypothetical account that *requires* the nonce to be out-of-order:\n * `require(nonce & type(uint64).max == 0)`\n *\n * The actual nonce uniqueness is managed by the EntryPoint, and thus no other\n * action is needed by the account itself.\n *\n * @param nonce to validate\n *\n * solhint-disable-next-line no-empty-blocks\n */\n function _validateNonce(uint256 nonce) internal view virtual {}\n\n /**\n * sends to the entrypoint (msg.sender) the missing funds for this transaction.\n * subclass MAY override this method for better funds management\n * (e.g. send to the entryPoint more than the minimum required, so that in future transactions\n * it will not be required to send again)\n * @param missingAccountFunds the minimum value this method should send the entrypoint.\n * this value MAY be zero, in case there is enough deposit, or the userOp has a paymaster.\n */\n function _payPrefund(uint256 missingAccountFunds) internal virtual {\n if (missingAccountFunds != 0) {\n (bool success, ) = payable(msg.sender).call{\n value: missingAccountFunds,\n gas: type(uint256).max\n }(\"\");\n (success);\n //ignore failure (its EntryPoint's job to verify, not account.)\n }\n }\n}\n" + }, + "contracts/aa-4337/core/EntryPoint.sol": { + "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n\nimport \"../interfaces/IAccount.sol\";\nimport \"../interfaces/IPaymaster.sol\";\nimport \"../interfaces/IEntryPoint.sol\";\n\nimport \"../utils/Exec.sol\";\nimport \"./StakeManager.sol\";\nimport \"./SenderCreator.sol\";\nimport \"./Helpers.sol\";\nimport \"./NonceManager.sol\";\nimport \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\n\ncontract EntryPoint is\n IEntryPoint,\n StakeManager,\n NonceManager,\n ReentrancyGuard\n{\n using UserOperationLib for UserOperation;\n\n SenderCreator private immutable senderCreator = new SenderCreator();\n\n // internal value used during simulation: need to query aggregator.\n address private constant SIMULATE_FIND_AGGREGATOR = address(1);\n\n // marker for inner call revert on out of gas\n bytes32 private constant INNER_OUT_OF_GAS = hex\"deaddead\";\n\n uint256 private constant REVERT_REASON_MAX_LEN = 2048;\n\n /**\n * for simulation purposes, validateUserOp (and validatePaymasterUserOp) must return this value\n * in case of signature failure, instead of revert.\n */\n uint256 public constant SIG_VALIDATION_FAILED = 1;\n\n /**\n * compensate the caller's beneficiary address with the collected fees of all UserOperations.\n * @param beneficiary the address to receive the fees\n * @param amount amount to transfer.\n */\n function _compensate(address payable beneficiary, uint256 amount) internal {\n require(beneficiary != address(0), \"AA90 invalid beneficiary\");\n (bool success, ) = beneficiary.call{value: amount}(\"\");\n require(success, \"AA91 failed send to beneficiary\");\n }\n\n /**\n * execute a user op\n * @param opIndex index into the opInfo array\n * @param userOp the userOp to execute\n * @param opInfo the opInfo filled by validatePrepayment for this userOp.\n * @return collected the total amount this userOp paid.\n */\n function _executeUserOp(\n uint256 opIndex,\n UserOperation calldata userOp,\n UserOpInfo memory opInfo\n ) private returns (uint256 collected) {\n uint256 preGas = gasleft();\n bytes memory context = getMemoryBytesFromOffset(opInfo.contextOffset);\n\n try this.innerHandleOp(userOp.callData, opInfo, context) returns (\n uint256 _actualGasCost\n ) {\n collected = _actualGasCost;\n } catch {\n bytes32 innerRevertCode;\n assembly {\n returndatacopy(0, 0, 32)\n innerRevertCode := mload(0)\n }\n // handleOps was called with gas limit too low. abort entire bundle.\n if (innerRevertCode == INNER_OUT_OF_GAS) {\n //report paymaster, since if it is not deliberately caused by the bundler,\n // it must be a revert caused by paymaster.\n revert FailedOp(opIndex, \"AA95 out of gas\");\n }\n\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n collected = _handlePostOp(\n opIndex,\n IPaymaster.PostOpMode.postOpReverted,\n opInfo,\n context,\n actualGas\n );\n }\n }\n\n /**\n * Execute a batch of UserOperations.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(\n UserOperation[] calldata ops,\n address payable beneficiary\n ) public nonReentrant {\n uint256 opslen = ops.length;\n UserOpInfo[] memory opInfos = new UserOpInfo[](opslen);\n\n unchecked {\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[i];\n (\n uint256 validationData,\n uint256 pmValidationData\n ) = _validatePrepayment(i, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(\n i,\n validationData,\n pmValidationData,\n address(0)\n );\n }\n\n uint256 collected = 0;\n emit BeforeExecution();\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(i, ops[i], opInfos[i]);\n }\n\n _compensate(beneficiary, collected);\n } //unchecked\n }\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) public nonReentrant {\n uint256 opasLen = opsPerAggregator.length;\n uint256 totalOps = 0;\n for (uint256 i = 0; i < opasLen; i++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[i];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n //address(1) is special marker of \"signature error\"\n require(\n address(aggregator) != address(1),\n \"AA96 invalid aggregator\"\n );\n\n if (address(aggregator) != address(0)) {\n // solhint-disable-next-line no-empty-blocks\n try aggregator.validateSignatures(ops, opa.signature) {} catch {\n revert SignatureValidationFailed(address(aggregator));\n }\n }\n\n totalOps += ops.length;\n }\n\n UserOpInfo[] memory opInfos = new UserOpInfo[](totalOps);\n\n emit BeforeExecution();\n\n uint256 opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n uint256 opslen = ops.length;\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[opIndex];\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(opIndex, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(\n i,\n validationData,\n paymasterValidationData,\n address(aggregator)\n );\n opIndex++;\n }\n }\n\n uint256 collected = 0;\n opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n emit SignatureAggregatorChanged(address(opa.aggregator));\n UserOperation[] calldata ops = opa.userOps;\n uint256 opslen = ops.length;\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(opIndex, ops[i], opInfos[opIndex]);\n opIndex++;\n }\n }\n emit SignatureAggregatorChanged(address(0));\n\n _compensate(beneficiary, collected);\n }\n\n /// @inheritdoc IEntryPoint\n function simulateHandleOp(\n UserOperation calldata op,\n address target,\n bytes calldata targetCallData\n ) external override {\n UserOpInfo memory opInfo;\n _simulationOnlyValidations(op);\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(0, op, opInfo);\n ValidationData memory data = _intersectTimeRange(\n validationData,\n paymasterValidationData\n );\n\n numberMarker();\n uint256 paid = _executeUserOp(0, op, opInfo);\n numberMarker();\n bool targetSuccess;\n bytes memory targetResult;\n if (target != address(0)) {\n (targetSuccess, targetResult) = target.call(targetCallData);\n }\n revert ExecutionResult(\n opInfo.preOpGas,\n paid,\n data.validAfter,\n data.validUntil,\n targetSuccess,\n targetResult\n );\n }\n\n // A memory copy of UserOp static fields only.\n // Excluding: callData, initCode and signature. Replacing paymasterAndData with paymaster.\n struct MemoryUserOp {\n address sender;\n uint256 nonce;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n address paymaster;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n }\n\n struct UserOpInfo {\n MemoryUserOp mUserOp;\n bytes32 userOpHash;\n uint256 prefund;\n uint256 contextOffset;\n uint256 preOpGas;\n }\n\n /**\n * inner function to handle a UserOperation.\n * Must be declared \"external\" to open a call context, but it can only be called by handleOps.\n */\n function innerHandleOp(\n bytes memory callData,\n UserOpInfo memory opInfo,\n bytes calldata context\n ) external returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n require(msg.sender == address(this), \"AA92 internal call only\");\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n\n uint callGasLimit = mUserOp.callGasLimit;\n unchecked {\n // handleOps was called with gas limit too low. abort entire bundle.\n if (\n gasleft() < callGasLimit + mUserOp.verificationGasLimit + 5000\n ) {\n assembly {\n mstore(0, INNER_OUT_OF_GAS)\n revert(0, 32)\n }\n }\n }\n\n IPaymaster.PostOpMode mode = IPaymaster.PostOpMode.opSucceeded;\n if (callData.length > 0) {\n bool success = Exec.call(mUserOp.sender, 0, callData, callGasLimit);\n if (!success) {\n bytes memory result = Exec.getReturnData(REVERT_REASON_MAX_LEN);\n if (result.length > 0) {\n emit UserOperationRevertReason(\n opInfo.userOpHash,\n mUserOp.sender,\n mUserOp.nonce,\n result\n );\n }\n mode = IPaymaster.PostOpMode.opReverted;\n }\n }\n\n unchecked {\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n //note: opIndex is ignored (relevant only if mode==postOpReverted, which is only possible outside of innerHandleOp)\n return _handlePostOp(0, mode, opInfo, context, actualGas);\n }\n }\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(\n UserOperation calldata userOp\n ) public view returns (bytes32) {\n return\n keccak256(abi.encode(userOp.hash(), address(this), block.chainid));\n }\n\n /**\n * copy general fields from userOp into the memory opInfo structure.\n */\n function _copyUserOpToMemory(\n UserOperation calldata userOp,\n MemoryUserOp memory mUserOp\n ) internal pure {\n mUserOp.sender = userOp.sender;\n mUserOp.nonce = userOp.nonce;\n mUserOp.callGasLimit = userOp.callGasLimit;\n mUserOp.verificationGasLimit = userOp.verificationGasLimit;\n mUserOp.preVerificationGas = userOp.preVerificationGas;\n mUserOp.maxFeePerGas = userOp.maxFeePerGas;\n mUserOp.maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes calldata paymasterAndData = userOp.paymasterAndData;\n if (paymasterAndData.length > 0) {\n require(\n paymasterAndData.length >= 20,\n \"AA93 invalid paymasterAndData\"\n );\n mUserOp.paymaster = address(bytes20(paymasterAndData[:20]));\n } else {\n mUserOp.paymaster = address(0);\n }\n }\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external {\n UserOpInfo memory outOpInfo;\n\n _simulationOnlyValidations(userOp);\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(0, userOp, outOpInfo);\n StakeInfo memory paymasterInfo = _getStakeInfo(\n outOpInfo.mUserOp.paymaster\n );\n StakeInfo memory senderInfo = _getStakeInfo(outOpInfo.mUserOp.sender);\n StakeInfo memory factoryInfo;\n {\n bytes calldata initCode = userOp.initCode;\n address factory = initCode.length >= 20\n ? address(bytes20(initCode[0:20]))\n : address(0);\n factoryInfo = _getStakeInfo(factory);\n }\n\n ValidationData memory data = _intersectTimeRange(\n validationData,\n paymasterValidationData\n );\n address aggregator = data.aggregator;\n bool sigFailed = aggregator == address(1);\n ReturnInfo memory returnInfo = ReturnInfo(\n outOpInfo.preOpGas,\n outOpInfo.prefund,\n sigFailed,\n data.validAfter,\n data.validUntil,\n getMemoryBytesFromOffset(outOpInfo.contextOffset)\n );\n\n if (aggregator != address(0) && aggregator != address(1)) {\n AggregatorStakeInfo memory aggregatorInfo = AggregatorStakeInfo(\n aggregator,\n _getStakeInfo(aggregator)\n );\n revert ValidationResultWithAggregation(\n returnInfo,\n senderInfo,\n factoryInfo,\n paymasterInfo,\n aggregatorInfo\n );\n }\n revert ValidationResult(\n returnInfo,\n senderInfo,\n factoryInfo,\n paymasterInfo\n );\n }\n\n function _getRequiredPrefund(\n MemoryUserOp memory mUserOp\n ) internal pure returns (uint256 requiredPrefund) {\n unchecked {\n //when using a Paymaster, the verificationGasLimit is used also to as a limit for the postOp call.\n // our security model might call postOp eventually twice\n uint256 mul = mUserOp.paymaster != address(0) ? 3 : 1;\n uint256 requiredGas = mUserOp.callGasLimit +\n mUserOp.verificationGasLimit *\n mul +\n mUserOp.preVerificationGas;\n\n requiredPrefund = requiredGas * mUserOp.maxFeePerGas;\n }\n }\n\n // create the sender's contract if needed.\n function _createSenderIfNeeded(\n uint256 opIndex,\n UserOpInfo memory opInfo,\n bytes calldata initCode\n ) internal {\n if (initCode.length != 0) {\n address sender = opInfo.mUserOp.sender;\n if (sender.code.length != 0)\n revert FailedOp(opIndex, \"AA10 sender already constructed\");\n address sender1 = senderCreator.createSender{\n gas: opInfo.mUserOp.verificationGasLimit\n }(initCode);\n if (sender1 == address(0))\n revert FailedOp(opIndex, \"AA13 initCode failed or OOG\");\n if (sender1 != sender)\n revert FailedOp(opIndex, \"AA14 initCode must return sender\");\n if (sender1.code.length == 0)\n revert FailedOp(opIndex, \"AA15 initCode must create sender\");\n address factory = address(bytes20(initCode[0:20]));\n emit AccountDeployed(\n opInfo.userOpHash,\n sender,\n factory,\n opInfo.mUserOp.paymaster\n );\n }\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes calldata initCode) public {\n address sender = senderCreator.createSender(initCode);\n revert SenderAddressResult(sender);\n }\n\n function _simulationOnlyValidations(\n UserOperation calldata userOp\n ) internal view {\n // solhint-disable-next-line no-empty-blocks\n try\n this._validateSenderAndPaymaster(\n userOp.initCode,\n userOp.sender,\n userOp.paymasterAndData\n )\n {} catch Error(string memory revertReason) {\n if (bytes(revertReason).length != 0) {\n revert FailedOp(0, revertReason);\n }\n }\n }\n\n /**\n * Called only during simulation.\n * This function always reverts to prevent warm/cold storage differentiation in simulation vs execution.\n */\n function _validateSenderAndPaymaster(\n bytes calldata initCode,\n address sender,\n bytes calldata paymasterAndData\n ) external view {\n if (initCode.length == 0 && sender.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA20 account not deployed\");\n }\n if (paymasterAndData.length >= 20) {\n address paymaster = address(bytes20(paymasterAndData[0:20]));\n if (paymaster.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA30 paymaster not deployed\");\n }\n }\n // always revert\n revert(\"\");\n }\n\n /**\n * call account.validateUserOp.\n * revert (with FailedOp) in case validateUserOp reverts, or account didn't send required prefund.\n * decrement account's deposit if needed\n */\n function _validateAccountPrepayment(\n uint256 opIndex,\n UserOperation calldata op,\n UserOpInfo memory opInfo,\n uint256 requiredPrefund\n )\n internal\n returns (\n uint256 gasUsedByValidateAccountPrepayment,\n uint256 validationData\n )\n {\n unchecked {\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n address sender = mUserOp.sender;\n _createSenderIfNeeded(opIndex, opInfo, op.initCode);\n address paymaster = mUserOp.paymaster;\n numberMarker();\n uint256 missingAccountFunds = 0;\n if (paymaster == address(0)) {\n uint256 bal = balanceOf(sender);\n missingAccountFunds = bal > requiredPrefund\n ? 0\n : requiredPrefund - bal;\n }\n try\n IAccount(sender).validateUserOp{\n gas: mUserOp.verificationGasLimit\n }(op, opInfo.userOpHash, missingAccountFunds)\n returns (uint256 _validationData) {\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA23 reverted: \", revertReason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA23 reverted (or OOG)\");\n }\n if (paymaster == address(0)) {\n DepositInfo storage senderInfo = deposits[sender];\n uint256 deposit = senderInfo.deposit;\n if (requiredPrefund > deposit) {\n revert FailedOp(opIndex, \"AA21 didn't pay prefund\");\n }\n senderInfo.deposit = uint112(deposit - requiredPrefund);\n }\n gasUsedByValidateAccountPrepayment = preGas - gasleft();\n }\n }\n\n /**\n * In case the request has a paymaster:\n * Validate paymaster has enough deposit.\n * Call paymaster.validatePaymasterUserOp.\n * Revert with proper FailedOp in case paymaster reverts.\n * Decrement paymaster's deposit\n */\n function _validatePaymasterPrepayment(\n uint256 opIndex,\n UserOperation calldata op,\n UserOpInfo memory opInfo,\n uint256 requiredPreFund,\n uint256 gasUsedByValidateAccountPrepayment\n ) internal returns (bytes memory context, uint256 validationData) {\n unchecked {\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 verificationGasLimit = mUserOp.verificationGasLimit;\n require(\n verificationGasLimit > gasUsedByValidateAccountPrepayment,\n \"AA41 too little verificationGas\"\n );\n uint256 gas = verificationGasLimit -\n gasUsedByValidateAccountPrepayment;\n\n address paymaster = mUserOp.paymaster;\n DepositInfo storage paymasterInfo = deposits[paymaster];\n uint256 deposit = paymasterInfo.deposit;\n if (deposit < requiredPreFund) {\n revert FailedOp(opIndex, \"AA31 paymaster deposit too low\");\n }\n paymasterInfo.deposit = uint112(deposit - requiredPreFund);\n try\n IPaymaster(paymaster).validatePaymasterUserOp{gas: gas}(\n op,\n opInfo.userOpHash,\n requiredPreFund\n )\n returns (bytes memory _context, uint256 _validationData) {\n context = _context;\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA33 reverted: \", revertReason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA33 reverted (or OOG)\");\n }\n }\n }\n\n /**\n * revert if either account validationData or paymaster validationData is expired\n */\n function _validateAccountAndPaymasterValidationData(\n uint256 opIndex,\n uint256 validationData,\n uint256 paymasterValidationData,\n address expectedAggregator\n ) internal view {\n (address aggregator, bool outOfTimeRange) = _getValidationData(\n validationData\n );\n if (expectedAggregator != aggregator) {\n revert FailedOp(opIndex, \"AA24 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA22 expired or not due\");\n }\n //pmAggregator is not a real signature aggregator: we don't have logic to handle it as address.\n // non-zero address means that the paymaster fails due to some signature check (which is ok only during estimation)\n address pmAggregator;\n (pmAggregator, outOfTimeRange) = _getValidationData(\n paymasterValidationData\n );\n if (pmAggregator != address(0)) {\n revert FailedOp(opIndex, \"AA34 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA32 paymaster expired or not due\");\n }\n }\n\n function _getValidationData(\n uint256 validationData\n ) internal view returns (address aggregator, bool outOfTimeRange) {\n if (validationData == 0) {\n return (address(0), false);\n }\n ValidationData memory data = _parseValidationData(validationData);\n // solhint-disable-next-line not-rely-on-time\n outOfTimeRange =\n block.timestamp > data.validUntil ||\n block.timestamp < data.validAfter;\n aggregator = data.aggregator;\n }\n\n /**\n * validate account and paymaster (if defined).\n * also make sure total validation doesn't exceed verificationGasLimit\n * this method is called off-chain (simulateValidation()) and on-chain (from handleOps)\n * @param opIndex the index of this userOp into the \"opInfos\" array\n * @param userOp the userOp to validate\n */\n function _validatePrepayment(\n uint256 opIndex,\n UserOperation calldata userOp,\n UserOpInfo memory outOpInfo\n )\n private\n returns (uint256 validationData, uint256 paymasterValidationData)\n {\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = outOpInfo.mUserOp;\n _copyUserOpToMemory(userOp, mUserOp);\n outOpInfo.userOpHash = getUserOpHash(userOp);\n\n // validate all numeric values in userOp are well below 128 bit, so they can safely be added\n // and multiplied without causing overflow\n uint256 maxGasValues = mUserOp.preVerificationGas |\n mUserOp.verificationGasLimit |\n mUserOp.callGasLimit |\n userOp.maxFeePerGas |\n userOp.maxPriorityFeePerGas;\n require(maxGasValues <= type(uint120).max, \"AA94 gas values overflow\");\n\n uint256 gasUsedByValidateAccountPrepayment;\n uint256 requiredPreFund = _getRequiredPrefund(mUserOp);\n (\n gasUsedByValidateAccountPrepayment,\n validationData\n ) = _validateAccountPrepayment(\n opIndex,\n userOp,\n outOpInfo,\n requiredPreFund\n );\n\n if (!_validateAndUpdateNonce(mUserOp.sender, mUserOp.nonce)) {\n revert FailedOp(opIndex, \"AA25 invalid account nonce\");\n }\n\n //a \"marker\" where account opcode validation is done and paymaster opcode validation is about to start\n // (used only by off-chain simulateValidation)\n numberMarker();\n\n bytes memory context;\n if (mUserOp.paymaster != address(0)) {\n (context, paymasterValidationData) = _validatePaymasterPrepayment(\n opIndex,\n userOp,\n outOpInfo,\n requiredPreFund,\n gasUsedByValidateAccountPrepayment\n );\n }\n unchecked {\n uint256 gasUsed = preGas - gasleft();\n\n if (userOp.verificationGasLimit < gasUsed) {\n revert FailedOp(opIndex, \"AA40 over verificationGasLimit\");\n }\n outOpInfo.prefund = requiredPreFund;\n outOpInfo.contextOffset = getOffsetOfMemoryBytes(context);\n outOpInfo.preOpGas = preGas - gasleft() + userOp.preVerificationGas;\n }\n }\n\n /**\n * process post-operation.\n * called just after the callData is executed.\n * if a paymaster is defined and its validation returned a non-empty context, its postOp is called.\n * the excess amount is refunded to the account (or paymaster - if it was used in the request)\n * @param opIndex index in the batch\n * @param mode - whether is called from innerHandleOp, or outside (postOpReverted)\n * @param opInfo userOp fields and info collected during validation\n * @param context the context returned in validatePaymasterUserOp\n * @param actualGas the gas used so far by this user operation\n */\n function _handlePostOp(\n uint256 opIndex,\n IPaymaster.PostOpMode mode,\n UserOpInfo memory opInfo,\n bytes memory context,\n uint256 actualGas\n ) private returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n unchecked {\n address refundAddress;\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 gasPrice = getUserOpGasPrice(mUserOp);\n\n address paymaster = mUserOp.paymaster;\n if (paymaster == address(0)) {\n refundAddress = mUserOp.sender;\n } else {\n refundAddress = paymaster;\n if (context.length > 0) {\n actualGasCost = actualGas * gasPrice;\n if (mode != IPaymaster.PostOpMode.postOpReverted) {\n IPaymaster(paymaster).postOp{\n gas: mUserOp.verificationGasLimit\n }(mode, context, actualGasCost);\n } else {\n // solhint-disable-next-line no-empty-blocks\n try\n IPaymaster(paymaster).postOp{\n gas: mUserOp.verificationGasLimit\n }(mode, context, actualGasCost)\n {} catch Error(string memory reason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA50 postOp reverted: \", reason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA50 postOp revert\");\n }\n }\n }\n }\n actualGas += preGas - gasleft();\n actualGasCost = actualGas * gasPrice;\n if (opInfo.prefund < actualGasCost) {\n revert FailedOp(opIndex, \"AA51 prefund below actualGasCost\");\n }\n uint256 refund = opInfo.prefund - actualGasCost;\n _incrementDeposit(refundAddress, refund);\n bool success = mode == IPaymaster.PostOpMode.opSucceeded;\n emit UserOperationEvent(\n opInfo.userOpHash,\n mUserOp.sender,\n mUserOp.paymaster,\n mUserOp.nonce,\n success,\n actualGasCost,\n actualGas\n );\n } // unchecked\n }\n\n /**\n * the gas price this UserOp agrees to pay.\n * relayer/block builder might submit the TX with higher priorityFee, but the user should not\n */\n function getUserOpGasPrice(\n MemoryUserOp memory mUserOp\n ) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = mUserOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = mUserOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n function getOffsetOfMemoryBytes(\n bytes memory data\n ) internal pure returns (uint256 offset) {\n assembly {\n offset := data\n }\n }\n\n function getMemoryBytesFromOffset(\n uint256 offset\n ) internal pure returns (bytes memory data) {\n assembly {\n data := offset\n }\n }\n\n //place the NUMBER opcode in the code.\n // this is used as a marker during simulation, as this OP is completely banned from the simulated code of the\n // account and paymaster.\n function numberMarker() internal view {\n assembly {\n mstore(0, number())\n }\n }\n}\n" + }, + "contracts/aa-4337/core/Helpers.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable no-inline-assembly */\n\n/**\n * returned data from validateUserOp.\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\n * @param aggregator - address(0) - the account validated the signature by itself.\n * address(1) - the account failed to validate the signature.\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\n * @param validAfter - this UserOp is valid only after this timestamp.\n * @param validaUntil - this UserOp is valid only up to this timestamp.\n */\nstruct ValidationData {\n address aggregator;\n uint48 validAfter;\n uint48 validUntil;\n}\n\n//extract sigFailed, validAfter, validUntil.\n// also convert zero validUntil to type(uint48).max\nfunction _parseValidationData(\n uint validationData\n) pure returns (ValidationData memory data) {\n address aggregator = address(uint160(validationData));\n uint48 validUntil = uint48(validationData >> 160);\n if (validUntil == 0) {\n validUntil = type(uint48).max;\n }\n uint48 validAfter = uint48(validationData >> (48 + 160));\n return ValidationData(aggregator, validAfter, validUntil);\n}\n\n// intersect account and paymaster ranges.\nfunction _intersectTimeRange(\n uint256 validationData,\n uint256 paymasterValidationData\n) pure returns (ValidationData memory) {\n ValidationData memory accountValidationData = _parseValidationData(\n validationData\n );\n ValidationData memory pmValidationData = _parseValidationData(\n paymasterValidationData\n );\n address aggregator = accountValidationData.aggregator;\n if (aggregator == address(0)) {\n aggregator = pmValidationData.aggregator;\n }\n uint48 validAfter = accountValidationData.validAfter;\n uint48 validUntil = accountValidationData.validUntil;\n uint48 pmValidAfter = pmValidationData.validAfter;\n uint48 pmValidUntil = pmValidationData.validUntil;\n\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\n return ValidationData(aggregator, validAfter, validUntil);\n}\n\n/**\n * helper to pack the return value for validateUserOp\n * @param data - the ValidationData to pack\n */\nfunction _packValidationData(\n ValidationData memory data\n) pure returns (uint256) {\n return\n uint160(data.aggregator) |\n (uint256(data.validUntil) << 160) |\n (uint256(data.validAfter) << (160 + 48));\n}\n\n/**\n * helper to pack the return value for validateUserOp, when not using an aggregator\n * @param sigFailed - true for signature failure, false for success\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\n * @param validAfter first timestamp this UserOperation is valid\n */\nfunction _packValidationData(\n bool sigFailed,\n uint48 validUntil,\n uint48 validAfter\n) pure returns (uint256) {\n return\n (sigFailed ? 1 : 0) |\n (uint256(validUntil) << 160) |\n (uint256(validAfter) << (160 + 48));\n}\n\n/**\n * keccak function over calldata.\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\n */\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\n assembly {\n let mem := mload(0x40)\n let len := data.length\n calldatacopy(mem, data.offset, len)\n ret := keccak256(mem, len)\n }\n}\n" + }, + "contracts/aa-4337/core/NonceManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\nimport \"../interfaces/IEntryPoint.sol\";\n\n/**\n * nonce management functionality\n */\ncontract NonceManager is INonceManager {\n /**\n * The next valid sequence number for a given nonce key.\n */\n mapping(address => mapping(uint192 => uint256)) public nonceSequenceNumber;\n\n function getNonce(\n address sender,\n uint192 key\n ) public view override returns (uint256 nonce) {\n return nonceSequenceNumber[sender][key] | (uint256(key) << 64);\n }\n\n // allow an account to manually increment its own nonce.\n // (mainly so that during construction nonce can be made non-zero,\n // to \"absorb\" the gas cost of first nonce increment to 1st transaction (construction),\n // not to 2nd transaction)\n function incrementNonce(uint192 key) public override {\n nonceSequenceNumber[msg.sender][key]++;\n }\n\n /**\n * validate nonce uniqueness for this account.\n * called just after validateUserOp()\n */\n function _validateAndUpdateNonce(\n address sender,\n uint256 nonce\n ) internal returns (bool) {\n uint192 key = uint192(nonce >> 64);\n uint64 seq = uint64(nonce);\n return nonceSequenceNumber[sender][key]++ == seq;\n }\n}\n" + }, + "contracts/aa-4337/core/SenderCreator.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/**\n * helper contract for EntryPoint, to call userOp.initCode from a \"neutral\" address,\n * which is explicitly not the entryPoint itself.\n */\ncontract SenderCreator {\n /**\n * call the \"initCode\" factory to create and return the sender account address\n * @param initCode the initCode value from a UserOp. contains 20 bytes of factory address, followed by calldata\n * @return sender the returned address of the created account, or zero address on failure.\n */\n function createSender(\n bytes calldata initCode\n ) external returns (address sender) {\n address factory = address(bytes20(initCode[0:20]));\n bytes memory initCallData = initCode[20:];\n bool success;\n /* solhint-disable no-inline-assembly */\n assembly {\n success := call(\n gas(),\n factory,\n 0,\n add(initCallData, 0x20),\n mload(initCallData),\n 0,\n 32\n )\n sender := mload(0)\n }\n if (!success) {\n sender = address(0);\n }\n }\n}\n" + }, + "contracts/aa-4337/core/StakeManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity 0.8.21;\n\nimport \"../interfaces/IStakeManager.sol\";\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable not-rely-on-time */\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by a paymaster.\n */\nabstract contract StakeManager is IStakeManager {\n /// maps paymaster to their deposits and stakes\n mapping(address => DepositInfo) public deposits;\n\n /// @inheritdoc IStakeManager\n function getDepositInfo(\n address account\n ) public view returns (DepositInfo memory info) {\n return deposits[account];\n }\n\n // internal method to return just the stake info\n function _getStakeInfo(\n address addr\n ) internal view returns (StakeInfo memory info) {\n DepositInfo storage depositInfo = deposits[addr];\n info.stake = depositInfo.stake;\n info.unstakeDelaySec = depositInfo.unstakeDelaySec;\n }\n\n /// return the deposit (for gas payment) of the account\n function balanceOf(address account) public view returns (uint256) {\n return deposits[account].deposit;\n }\n\n receive() external payable {\n depositTo(msg.sender);\n }\n\n function _incrementDeposit(address account, uint256 amount) internal {\n DepositInfo storage info = deposits[account];\n uint256 newAmount = info.deposit + amount;\n require(newAmount <= type(uint112).max, \"deposit overflow\");\n info.deposit = uint112(newAmount);\n }\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) public payable {\n _incrementDeposit(account, msg.value);\n DepositInfo storage info = deposits[account];\n emit Deposited(account, info.deposit);\n }\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 unstakeDelaySec) public payable {\n DepositInfo storage info = deposits[msg.sender];\n require(unstakeDelaySec > 0, \"must specify unstake delay\");\n require(\n unstakeDelaySec >= info.unstakeDelaySec,\n \"cannot decrease unstake time\"\n );\n uint256 stake = info.stake + msg.value;\n require(stake > 0, \"no stake specified\");\n require(stake <= type(uint112).max, \"stake overflow\");\n deposits[msg.sender] = DepositInfo(\n info.deposit,\n true,\n uint112(stake),\n unstakeDelaySec,\n 0\n );\n emit StakeLocked(msg.sender, stake, unstakeDelaySec);\n }\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external {\n DepositInfo storage info = deposits[msg.sender];\n require(info.unstakeDelaySec != 0, \"not staked\");\n require(info.staked, \"already unstaking\");\n uint48 withdrawTime = uint48(block.timestamp) + info.unstakeDelaySec;\n info.withdrawTime = withdrawTime;\n info.staked = false;\n emit StakeUnlocked(msg.sender, withdrawTime);\n }\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external {\n DepositInfo storage info = deposits[msg.sender];\n uint256 stake = info.stake;\n require(stake > 0, \"No stake to withdraw\");\n require(info.withdrawTime > 0, \"must call unlockStake() first\");\n require(\n info.withdrawTime <= block.timestamp,\n \"Stake withdrawal is not due\"\n );\n info.unstakeDelaySec = 0;\n info.withdrawTime = 0;\n info.stake = 0;\n emit StakeWithdrawn(msg.sender, withdrawAddress, stake);\n (bool success, ) = withdrawAddress.call{value: stake}(\"\");\n require(success, \"failed to withdraw stake\");\n }\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(\n address payable withdrawAddress,\n uint256 withdrawAmount\n ) external {\n DepositInfo storage info = deposits[msg.sender];\n require(withdrawAmount <= info.deposit, \"Withdraw amount too large\");\n info.deposit = uint112(info.deposit - withdrawAmount);\n emit Withdrawn(msg.sender, withdrawAddress, withdrawAmount);\n (bool success, ) = withdrawAddress.call{value: withdrawAmount}(\"\");\n require(success, \"failed to withdraw\");\n }\n}\n" + }, + "contracts/aa-4337/interfaces/IAccount.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\ninterface IAccount {\n /**\n * Validate user's signature and nonce\n * the entryPoint will make the call to the recipient only if this validation call returns successfully.\n * signature failure should be reported by returning SIG_VALIDATION_FAILED (1).\n * This allows making a \"simulation call\" without a valid signature\n * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure.\n *\n * @dev Must validate caller is the entryPoint.\n * Must validate the signature and nonce\n * @param userOp the operation that is about to be executed.\n * @param userOpHash hash of the user's request data. can be used as the basis for signature.\n * @param missingAccountFunds missing funds on the account's deposit in the entrypoint.\n * This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call.\n * The excess is left as a deposit in the entrypoint, for future calls.\n * can be withdrawn anytime using \"entryPoint.withdrawTo()\"\n * In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero.\n * @return validationData packaged ValidationData structure. use `_packValidationData` and `_unpackValidationData` to encode and decode\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * If an account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validateUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 missingAccountFunds\n ) external returns (uint256 validationData);\n}\n" + }, + "contracts/aa-4337/interfaces/IAggregator.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * Aggregated Signatures validator.\n */\ninterface IAggregator {\n /**\n * validate aggregated signature.\n * revert if the aggregated signature does not match the given list of operations.\n */\n function validateSignatures(\n UserOperation[] calldata userOps,\n bytes calldata signature\n ) external view;\n\n /**\n * validate signature of a single userOp\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\n * @param userOp the userOperation received from the user.\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\n * (usually empty, unless account and aggregator support some kind of \"multisig\"\n */\n function validateUserOpSignature(\n UserOperation calldata userOp\n ) external view returns (bytes memory sigForUserOp);\n\n /**\n * aggregate multiple signatures into a single value.\n * This method is called off-chain to calculate the signature to pass with handleOps()\n * bundler MAY use optimized custom code perform this aggregation\n * @param userOps array of UserOperations to collect the signatures from.\n * @return aggregatedSignature the aggregated signature\n */\n function aggregateSignatures(\n UserOperation[] calldata userOps\n ) external view returns (bytes memory aggregatedSignature);\n}\n" + }, + "contracts/aa-4337/interfaces/IEntryPoint.sol": { + "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n/* solhint-disable reason-string */\n\nimport \"./UserOperation.sol\";\nimport \"./IStakeManager.sol\";\nimport \"./IAggregator.sol\";\nimport \"./INonceManager.sol\";\n\ninterface IEntryPoint is IStakeManager, INonceManager {\n /***\n * An event emitted after each successful request\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\n * @param sender - the account that generates this request.\n * @param paymaster - if non-null, the paymaster that pays for this request.\n * @param nonce - the nonce value from the request.\n * @param success - true if the sender transaction succeeded, false if reverted.\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\n */\n event UserOperationEvent(\n bytes32 indexed userOpHash,\n address indexed sender,\n address indexed paymaster,\n uint256 nonce,\n bool success,\n uint256 actualGasCost,\n uint256 actualGasUsed\n );\n\n /**\n * account \"sender\" was deployed.\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\n * @param sender the account that is deployed\n * @param factory the factory used to deploy this account (in the initCode)\n * @param paymaster the paymaster used by this UserOp\n */\n event AccountDeployed(\n bytes32 indexed userOpHash,\n address indexed sender,\n address factory,\n address paymaster\n );\n\n /**\n * An event emitted if the UserOperation \"callData\" reverted with non-zero length\n * @param userOpHash the request unique identifier.\n * @param sender the sender of this request\n * @param nonce the nonce used in the request\n * @param revertReason - the return bytes from the (reverted) call to \"callData\".\n */\n event UserOperationRevertReason(\n bytes32 indexed userOpHash,\n address indexed sender,\n uint256 nonce,\n bytes revertReason\n );\n\n /**\n * an event emitted by handleOps(), before starting the execution loop.\n * any event emitted before this event, is part of the validation.\n */\n event BeforeExecution();\n\n /**\n * signature aggregator used by the following UserOperationEvents within this bundle.\n */\n event SignatureAggregatorChanged(address indexed aggregator);\n\n /**\n * a custom revert error of handleOps, to identify the offending op.\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\n * @param reason - revert reason\n * The string starts with a unique code \"AAmn\", where \"m\" is \"1\" for factory, \"2\" for account and \"3\" for paymaster issues,\n * so a failure can be attributed to the correct entity.\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\n */\n error FailedOp(uint256 opIndex, string reason);\n\n /**\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\n */\n error SignatureValidationFailed(address aggregator);\n\n /**\n * Successful result from simulateValidation.\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n */\n error ValidationResult(\n ReturnInfo returnInfo,\n StakeInfo senderInfo,\n StakeInfo factoryInfo,\n StakeInfo paymasterInfo\n );\n\n /**\n * Successful result from simulateValidation, if the account returns a signature aggregator\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\n * bundler MUST use it to verify the signature, or reject the UserOperation\n */\n error ValidationResultWithAggregation(\n ReturnInfo returnInfo,\n StakeInfo senderInfo,\n StakeInfo factoryInfo,\n StakeInfo paymasterInfo,\n AggregatorStakeInfo aggregatorInfo\n );\n\n /**\n * return value of getSenderAddress\n */\n error SenderAddressResult(address sender);\n\n /**\n * return value of simulateHandleOp\n */\n error ExecutionResult(\n uint256 preOpGas,\n uint256 paid,\n uint48 validAfter,\n uint48 validUntil,\n bool targetSuccess,\n bytes targetResult\n );\n\n //UserOps handled, per aggregator\n struct UserOpsPerAggregator {\n UserOperation[] userOps;\n // aggregator address\n IAggregator aggregator;\n // aggregated signature\n bytes signature;\n }\n\n /**\n * Execute a batch of UserOperation.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(\n UserOperation[] calldata ops,\n address payable beneficiary\n ) external;\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) external;\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(\n UserOperation calldata userOp\n ) external view returns (bytes32);\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external;\n\n /**\n * gas and return values during simulation\n * @param preOpGas the gas used for validation (including preValidationGas)\n * @param prefund the required prefund for this operation\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\n */\n struct ReturnInfo {\n uint256 preOpGas;\n uint256 prefund;\n bool sigFailed;\n uint48 validAfter;\n uint48 validUntil;\n bytes paymasterContext;\n }\n\n /**\n * returned aggregated signature info.\n * the aggregator returned by the account, and its current stake.\n */\n struct AggregatorStakeInfo {\n address aggregator;\n StakeInfo stakeInfo;\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes memory initCode) external;\n\n /**\n * simulate full execution of a UserOperation (including both validation and target execution)\n * this method will always revert with \"ExecutionResult\".\n * it performs full validation of the UserOperation, but ignores signature error.\n * an optional target address is called after the userop succeeds, and its value is returned\n * (before the entire call is reverted)\n * Note that in order to collect the the success/failure of the target call, it must be executed\n * with trace enabled to track the emitted events.\n * @param op the UserOperation to simulate\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\n * are set to the return from that call.\n * @param targetCallData callData to pass to target address\n */\n function simulateHandleOp(\n UserOperation calldata op,\n address target,\n bytes calldata targetCallData\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/INonceManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\ninterface INonceManager {\n /**\n * Return the next nonce for this sender.\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\n * But UserOp with different keys can come with arbitrary order.\n *\n * @param sender the account address\n * @param key the high 192 bit of the nonce\n * @return nonce a full nonce to pass for next UserOp with this sender.\n */\n function getNonce(\n address sender,\n uint192 key\n ) external view returns (uint256 nonce);\n\n /**\n * Manually increment the nonce of the sender.\n * This method is exposed just for completeness..\n * Account does NOT need to call it, neither during validation, nor elsewhere,\n * as the EntryPoint will update the nonce regardless.\n * Possible use-case is call it with various keys to \"initialize\" their nonces to one, so that future\n * UserOperations will not pay extra for the first transaction with a given key.\n */\n function incrementNonce(uint192 key) external;\n}\n" + }, + "contracts/aa-4337/interfaces/IPaymaster.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * the interface exposed by a paymaster contract, who agrees to pay the gas for user's operations.\n * a paymaster must hold a stake to cover the required entrypoint stake and also the gas for the transaction.\n */\ninterface IPaymaster {\n enum PostOpMode {\n opSucceeded, // user op succeeded\n opReverted, // user op reverted. still has to pay for gas.\n postOpReverted //user op succeeded, but caused postOp to revert. Now it's a 2nd call, after user's op was deliberately reverted.\n }\n\n /**\n * payment validation: check if paymaster agrees to pay.\n * Must verify sender is the entryPoint.\n * Revert to reject this request.\n * Note that bundlers will reject this method if it changes the state, unless the paymaster is trusted (whitelisted)\n * The paymaster pre-pays using its deposit, and receive back a refund after the postOp method returns.\n * @param userOp the user operation\n * @param userOpHash hash of the user's request data.\n * @param maxCost the maximum cost of this transaction (based on maximum gas and gas price from userOp)\n * @return context value to send to a postOp\n * zero length to signify postOp is not required.\n * @return validationData signature and time-range of this operation, encoded the same as the return value of validateUserOperation\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validatePaymasterUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 maxCost\n ) external returns (bytes memory context, uint256 validationData);\n\n /**\n * post-operation handler.\n * Must verify sender is the entryPoint\n * @param mode enum with the following options:\n * opSucceeded - user operation succeeded.\n * opReverted - user op reverted. still has to pay for gas.\n * postOpReverted - user op succeeded, but caused postOp (in mode=opSucceeded) to revert.\n * Now this is the 2nd call, after user's op was deliberately reverted.\n * @param context - the context value returned by validatePaymasterUserOp\n * @param actualGasCost - actual gas used so far (without this postOp call).\n */\n function postOp(\n PostOpMode mode,\n bytes calldata context,\n uint256 actualGasCost\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/IStakeManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.12;\n\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by the staked entity.\n */\ninterface IStakeManager {\n event Deposited(address indexed account, uint256 totalDeposit);\n\n event Withdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /// Emitted when stake or unstake delay are modified\n event StakeLocked(\n address indexed account,\n uint256 totalStaked,\n uint256 unstakeDelaySec\n );\n\n /// Emitted once a stake is scheduled for withdrawal\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\n\n event StakeWithdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /**\n * @param deposit the entity's deposit\n * @param staked true if this entity is staked.\n * @param stake actual amount of ether staked for this entity.\n * @param unstakeDelaySec minimum delay to withdraw the stake.\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\n * and the rest fit into a 2nd cell.\n * 112 bit allows for 10^15 eth\n * 48 bit for full timestamp\n * 32 bit allows 150 years for unstake delay\n */\n struct DepositInfo {\n uint112 deposit;\n bool staked;\n uint112 stake;\n uint32 unstakeDelaySec;\n uint48 withdrawTime;\n }\n\n //API struct used by getStakeInfo and simulateValidation\n struct StakeInfo {\n uint256 stake;\n uint256 unstakeDelaySec;\n }\n\n /// @return info - full deposit information of given account\n function getDepositInfo(\n address account\n ) external view returns (DepositInfo memory info);\n\n /// @return the deposit (for gas payment) of the account\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) external payable;\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 _unstakeDelaySec) external payable;\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external;\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external;\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(\n address payable withdrawAddress,\n uint256 withdrawAmount\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/UserOperation.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable no-inline-assembly */\n\nimport {calldataKeccak} from \"../core/Helpers.sol\";\n\n/**\n * User Operation struct\n * @param sender the sender account of this request.\n * @param nonce unique value the sender uses to verify it is not a replay.\n * @param initCode if set, the account contract will be created by this constructor/\n * @param callData the method call to execute on this account.\n * @param callGasLimit the gas limit passed to the callData method call.\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\n * @param maxFeePerGas same as EIP-1559 gas parameter.\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\n */\nstruct UserOperation {\n address sender;\n uint256 nonce;\n bytes initCode;\n bytes callData;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n bytes paymasterAndData;\n bytes signature;\n}\n\n/**\n * Utility functions helpful when working with UserOperation structs.\n */\nlibrary UserOperationLib {\n function getSender(\n UserOperation calldata userOp\n ) internal pure returns (address) {\n address data;\n //read sender from userOp, which is first userOp member (saves 800 gas...)\n assembly {\n data := calldataload(userOp)\n }\n return address(uint160(data));\n }\n\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\n // pay above what he signed for.\n function gasPrice(\n UserOperation calldata userOp\n ) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function pack(\n UserOperation calldata userOp\n ) internal pure returns (bytes memory ret) {\n address sender = getSender(userOp);\n uint256 nonce = userOp.nonce;\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\n bytes32 hashCallData = calldataKeccak(userOp.callData);\n uint256 callGasLimit = userOp.callGasLimit;\n uint256 verificationGasLimit = userOp.verificationGasLimit;\n uint256 preVerificationGas = userOp.preVerificationGas;\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\n\n return\n abi.encode(\n sender,\n nonce,\n hashInitCode,\n hashCallData,\n callGasLimit,\n verificationGasLimit,\n preVerificationGas,\n maxFeePerGas,\n maxPriorityFeePerGas,\n hashPaymasterAndData\n );\n }\n\n function hash(\n UserOperation calldata userOp\n ) internal pure returns (bytes32) {\n return keccak256(pack(userOp));\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n}\n" + }, + "contracts/aa-4337/utils/Exec.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.5 <0.9.0;\n\n// solhint-disable no-inline-assembly\n\n/**\n * Utility functions helpful when making different kinds of contract calls in Solidity.\n */\nlibrary Exec {\n function call(\n address to,\n uint256 value,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := call(\n txGas,\n to,\n value,\n add(data, 0x20),\n mload(data),\n 0,\n 0\n )\n }\n }\n\n function staticcall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal view returns (bool success) {\n assembly {\n success := staticcall(txGas, to, add(data, 0x20), mload(data), 0, 0)\n }\n }\n\n function delegateCall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := delegatecall(\n txGas,\n to,\n add(data, 0x20),\n mload(data),\n 0,\n 0\n )\n }\n }\n\n // get returned data from last call or calldelegate\n function getReturnData(\n uint256 maxLen\n ) internal pure returns (bytes memory returnData) {\n assembly {\n let len := returndatasize()\n if gt(len, maxLen) {\n len := maxLen\n }\n let ptr := mload(0x40)\n mstore(0x40, add(ptr, add(len, 0x20)))\n mstore(ptr, len)\n returndatacopy(add(ptr, 0x20), 0, len)\n returnData := ptr\n }\n }\n\n // revert with explicit byte array (probably reverted info from call)\n function revertWithData(bytes memory returnData) internal pure {\n assembly {\n revert(add(returnData, 32), mload(returnData))\n }\n }\n\n function callAndRevert(\n address to,\n bytes memory data,\n uint256 maxLen\n ) internal {\n bool success = call(to, 0, data, gasleft());\n if (!success) {\n revertWithData(getReturnData(maxLen));\n }\n }\n}\n" + }, + "contracts/Barz.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"./libraries/LibDiamond.sol\";\nimport {IBarz} from \"./interfaces/IBarz.sol\";\n\n/**\n * @title Barz\n * @dev A diamond proxy wallet with a modular & upgradeable architecture\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract Barz is IBarz {\n /**\n * @notice Initializes Barz with the given parameters. Barz account is intended to be created from Barz Factory for stable deployment.\n * @dev This method makes a delegate call to account facet and account facet handles the initialization.\n * With modular architecture, Barz encompasses wide spectrum of architecture and logic.\n * The only requirement is account facet to comply with initialize() interface.\n * Barz doesn't include built-in functions and is a full proxy, for maximum extensibility and modularity.\n * @param _accountFacet Address of Account Facet in charge of the Barz initialization\n * @param _verificationFacet Address of Verification Facet for verifying the signature. Could be any signature scheme\n * @param _entryPoint Address of Entry Point contract\n * @param _facetRegistry Address of Facet Registry. Facet Registry is a registry holding trusted facets that could be added to user's wallet\n * @param _defaultFallBack Address of Default FallBack Handler. Middleware contract for more efficient deployment\n * @param _ownerPublicKey Bytes of Owner Public Key using for initialization\n */\n constructor(\n address _accountFacet,\n address _verificationFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallBack,\n bytes memory _ownerPublicKey\n ) payable {\n bytes memory initCall = abi.encodeWithSignature(\n \"initialize(address,address,address,address,bytes)\",\n _verificationFacet,\n _entryPoint,\n _facetRegistry,\n _defaultFallBack,\n _ownerPublicKey\n );\n (bool success, bytes memory result) = _accountFacet.delegatecall(\n initCall\n );\n if (!success || uint256(bytes32(result)) != 1) {\n revert Barz__InitializationFailure();\n }\n }\n\n /**\n * @notice Fallback function for Barz complying with Diamond Standard with customization of adding Default Fallback Handler\n * @dev Find facet for function that is called and execute the function if a facet is found and return any value.\n */\n fallback() external payable {\n LibDiamond.DiamondStorage storage ds;\n bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION;\n // get diamond storage\n assembly {\n ds.slot := position\n }\n // get facet from function selector\n address facet = address(bytes20(ds.facets[msg.sig]));\n if (facet == address(0))\n facet = ds.defaultFallbackHandler.facetAddress(msg.sig);\n require(facet != address(0), \"Barz: Function does not exist\");\n // Execute external function from facet using delegatecall and return any value.\n assembly {\n // copy function selector and any arguments\n calldatacopy(0, 0, calldatasize())\n // execute function call using the facet\n let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)\n // get any return value\n returndatacopy(0, 0, returndatasize())\n // return any return value or error back to the caller\n switch result\n case 0 {\n revert(0, returndatasize())\n }\n default {\n return(0, returndatasize())\n }\n }\n }\n\n /**\n * @notice Receive function to receive native token without data\n */\n receive() external payable {}\n}\n" + }, + "contracts/BarzFactory.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Barz} from \"./Barz.sol\";\nimport {IBarzFactory} from \"./interfaces/IBarzFactory.sol\";\n\n/**\n * @title Barz Factory\n * @dev Contract to easily deploy Barz to a pre-computed address with a single call\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract BarzFactory is IBarzFactory {\n address public immutable accountFacet;\n address public immutable entryPoint;\n address public immutable facetRegistry;\n address public immutable defaultFallback;\n\n /**\n * @notice Sets the initialization data for Barz contract initialization\n * @param _accountFacet Account Facet to be used to create Barz\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\n * @param _facetRegistry Facet Registry to be used to create Barz\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\n */\n constructor(\n address _accountFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallback\n ) {\n accountFacet = _accountFacet;\n entryPoint = _entryPoint;\n facetRegistry = _facetRegistry;\n defaultFallback = _defaultFallback;\n }\n\n /**\n * @notice Creates the Barz with a single call. It creates the Barz contract with the givent verification facet\n * @param _verificationFacet Address of verification facet used for creating the barz account\n * @param _owner Public Key of the owner to initialize barz account\n * @param _salt Salt used for deploying barz with create2\n * @return barz Instance of Barz contract deployed with the given parameters\n */\n function createAccount(\n address _verificationFacet,\n bytes calldata _owner,\n uint256 _salt\n ) external override returns (Barz barz) {\n address addr = getAddress(_verificationFacet, _owner, _salt);\n uint codeSize = addr.code.length;\n if (codeSize > 0) {\n return Barz(payable(addr));\n }\n barz = new Barz{salt: bytes32(_salt)}(\n accountFacet,\n _verificationFacet,\n entryPoint,\n facetRegistry,\n defaultFallback,\n _owner\n );\n emit BarzDeployed(address(barz));\n }\n\n /**\n * @notice Calculates the address of Barz with the given parameters\n * @param _verificationFacet Address of verification facet used for creating the barz account\n * @param _owner Public Key of the owner to initialize barz account\n * @param _salt Salt used for deploying barz with create2\n * @return barzAddress Precalculated Barz address\n */\n function getAddress(\n address _verificationFacet,\n bytes calldata _owner,\n uint256 _salt\n ) public view override returns (address barzAddress) {\n bytes memory bytecode = getBytecode(\n accountFacet,\n _verificationFacet,\n entryPoint,\n facetRegistry,\n defaultFallback,\n _owner\n );\n bytes32 hash = keccak256(\n abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(bytecode)\n )\n );\n barzAddress = address(uint160(uint256(hash)));\n }\n\n /**\n * @notice Returns the bytecode of Barz with the given parameter\n * @param _accountFacet Account Facet to be used to create Barz\n * @param _verificationFacet Verification Facet to be used to create Barz\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\n * @param _facetRegistry Facet Registry to be used to create Barz\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\n * @param _ownerPublicKey Public Key of owner to be used to initialize Barz ownership\n * @return barzBytecode Bytecode of Barz\n */\n function getBytecode(\n address _accountFacet,\n address _verificationFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallback,\n bytes calldata _ownerPublicKey\n ) public pure override returns (bytes memory barzBytecode) {\n bytes memory bytecode = type(Barz).creationCode;\n barzBytecode = abi.encodePacked(\n bytecode,\n abi.encode(\n _accountFacet,\n _verificationFacet,\n _entryPoint,\n _facetRegistry,\n _defaultFallback,\n _ownerPublicKey\n )\n );\n }\n\n /**\n * @notice Returns the creation code of the Barz contract\n * @return creationCode Creation code of Barz\n */\n function getCreationCode()\n public\n pure\n override\n returns (bytes memory creationCode)\n {\n creationCode = type(Barz).creationCode;\n }\n}\n" + }, + "contracts/facets/AccountFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {UserOperation} from \"../aa-4337/interfaces/UserOperation.sol\";\nimport {IEntryPoint} from \"../aa-4337/interfaces/IEntryPoint.sol\";\nimport {BaseAccount} from \"../aa-4337/core/BaseAccount.sol\";\nimport {LibAppStorage, BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {IFacetRegistry} from \"../infrastructure/interfaces/IFacetRegistry.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {IERC1271} from \"../interfaces/ERC/IERC1271.sol\";\nimport {IAccountFacet} from \"./interfaces/IAccountFacet.sol\";\n\n/**\n * @title Account Facet\n * @dev Account module contract that provides the account features and initialization of signer\n * compatible with EIP-1271 & EIP-4337\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract AccountFacet is IAccountFacet, BarzStorage, BaseAccount {\n using ECDSA for bytes32;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceAccountInitialize();\n }\n\n /**\n * @notice Returns the address of EntryPoint contract registered to Barz account\n */\n function entryPoint() public view override returns (IEntryPoint) {\n return s.entryPoint;\n }\n\n /**\n * @notice Initializes the initial storage of the Barz contract.\n * @dev This method can only be called during the initialization or signature migration.\n * If the proxy contract was created without initialization, anyone can call initialize.\n * Barz calls initialize in constructor in an atomic transaction during deployment\n * @param _verificationFacet Facet contract handling the verificationi\n * @param _anEntryPoint Entrypoint contract defined in EIP-4337 handling the flow of UserOp\n * @param _facetRegistry Registry of Facets that hold all facet information\n * @param _defaultFallBackHandler Middleware contract for default facets\n * @param _ownerPublicKey Bytes of owner public key\n */\n function initialize(\n address _verificationFacet,\n address _anEntryPoint,\n address _facetRegistry,\n address _defaultFallBackHandler,\n bytes calldata _ownerPublicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceAccountInitialize();\n s.entryPoint = IEntryPoint(_anEntryPoint);\n s.facetRegistry = IFacetRegistry(_facetRegistry);\n LibDiamond.diamondStorage().defaultFallbackHandler = IDiamondLoupe(\n _defaultFallBackHandler\n );\n\n _cutDiamondAccountFacet(_verificationFacet);\n\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n _ownerPublicKey\n );\n // Every Verification Facet should comply with initializeSigner(bytes)\n // to be compatible with the Barz contract(for initialization)\n (bool success, bytes memory result) = _verificationFacet.delegatecall(\n initCall\n );\n if (!success || uint256(bytes32(result)) != 1) {\n revert AccountFacet__InitializationFailure();\n }\n\n initSuccess = 1;\n emit AccountInitialized(s.entryPoint, _ownerPublicKey);\n }\n\n function _cutDiamondAccountFacet(address _verificationFacet) internal {\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](1);\n\n bytes4 ownerVerificationFuncSelector = IVerificationFacet(\n _verificationFacet\n ).validateOwnerSignatureSelector();\n\n bytes4[] memory verificationFunctionSelectors = new bytes4[](3);\n verificationFunctionSelectors[0] = IERC1271.isValidSignature.selector;\n verificationFunctionSelectors[1] = ownerVerificationFuncSelector;\n verificationFunctionSelectors[2] = IVerificationFacet.owner.selector;\n cut[0] = IDiamondCut.FacetCut({\n facetAddress: _verificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: verificationFunctionSelectors\n });\n\n LibDiamond.diamondCut(cut, address(0), \"\");\n }\n\n /**\n * @notice Calls the destination with inputted calldata and value from EntryPoint\n * @dev This method executes the calldata coming from the EntryPoint.\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\n * @param _dest Address of destination where the call will be forwarded to\n * @param _value Amount of native coin the owner is willing to send(e.g. ETH, BNB)\n * @param _func Bytes of calldata to execute in the destination address\n */\n function execute(\n address _dest,\n uint256 _value,\n bytes calldata _func\n ) external override onlyWhenUnlocked {\n _requireFromEntryPoint();\n address restrictionsFacet = LibDiamond.restrictionsFacet();\n if (restrictionsFacet == address(0)) _call(_dest, _value, _func);\n else _callWithRestrictions(_dest, _value, _func, restrictionsFacet);\n }\n\n /**\n * @notice Batch calls the destination with inputted calldata and value from EntryPoint\n * @dev This method batch executes the calldata coming from the EntryPoint.\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\n * @param _dest Array of addresses of destination where the call will be forwarded to\n * @param _value Array of amount of native coin the owner is willing to send(e.g. ETH, BNB)\n * @param _func Array of bytes of calldata to execute in the destination address\n */\n function executeBatch(\n address[] calldata _dest,\n uint256[] calldata _value,\n bytes[] calldata _func\n ) external override onlyWhenUnlocked {\n _requireFromEntryPoint();\n if (_dest.length != _func.length || _dest.length != _value.length)\n revert AccountFacet__InvalidArrayLength();\n address restrictionsFacet = LibDiamond.restrictionsFacet();\n if (restrictionsFacet == address(0)) {\n for (uint256 i; i < _dest.length; ) {\n _call(_dest[i], _value[i], _func[i]);\n unchecked {\n ++i;\n }\n }\n } else {\n for (uint256 i; i < _dest.length; ) {\n _callWithRestrictions(\n _dest[i],\n _value[i],\n _func[i],\n restrictionsFacet\n );\n unchecked {\n ++i;\n }\n }\n }\n }\n\n /**\n * @notice Validates the signature field of UserOperation\n * @dev This method validates if the signature of UserOp is indeed valid by delegating the call to Verification Facet\n * Barz makes a call to the pre-registered Verification Facet address in App Storage\n * @param _userOp UserOperation from owner to be validated\n * @param _userOpHash Hash of UserOperation given from the EntryPoint contract\n */\n function _validateSignature(\n UserOperation calldata _userOp,\n bytes32 _userOpHash\n ) internal override returns (uint256 validationData) {\n // Get Facet with Function Selector\n address facet = LibLoupe.facetAddress(s.validateOwnerSignatureSelector);\n if (facet == address(0))\n revert AccountFacet__NonExistentVerificationFacet();\n\n // Make function call to VerificationFacet\n bytes memory validateCall = abi.encodeWithSelector(\n s.validateOwnerSignatureSelector,\n _userOp,\n _userOpHash\n );\n (bool success, bytes memory result) = facet.delegatecall(validateCall);\n if (!success) revert AccountFacet__CallNotSuccessful();\n validationData = uint256(bytes32(result));\n if (validationData == 0) emit VerificationSuccess(_userOpHash);\n else emit VerificationFailure(_userOpHash);\n }\n\n /**\n * @notice Calls the target with the inputted value and calldata\n * @dev This method is the actual function in Barz that makes a call with an arbitrary owner-given data\n * @param _target Address of the destination contract which the call is getting forwarded to\n * @param _value Amount of Native coin the owner is wanting to make in this call\n * @param _data Calldata the owner is forwarding together in the call e.g. Swap/Token Transfer\n */\n function _call(\n address _target,\n uint256 _value,\n bytes memory _data\n ) internal {\n (bool success, bytes memory result) = _target.call{value: _value}(\n _data\n );\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n }\n\n /**\n * @notice Calls the target with the inputted value and calldata together with restrictions check\n * @dev This method is the actual function in Barz that makes a call with an arbitrary owner-given data\n * @param _target Address of the destination contract which the call is getting forwarded to\n * @param _value Amount of Native coin the owner is wanting to make in this call\n * @param _data Calldata the owner is forwarding together in the call e.g. Swap/Token Transfer\n * @param _restrictionsFacet Address of Facet to validate restrictions\n */\n function _callWithRestrictions(\n address _target,\n uint256 _value,\n bytes memory _data,\n address _restrictionsFacet\n ) internal {\n // NOTE: No restrictions facet, so restriction validation passes\n if (_checkRestrictions(_restrictionsFacet, _target, _value, _data) != 0)\n revert AccountFacet__RestrictionsFailure();\n\n (bool success, bytes memory result) = _target.call{value: _value}(\n _data\n );\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n }\n\n /**\n * @notice Checks restrictions if the restrictions facet exists\n * @dev This method checks if the restrictions facet exists and makes a verification call to an array of restrictions facet\n * @param _facet Address that holds the restrictions logic\n * @param _target Address the call is getting forwarded to\n * @param _value Amount of native coin the call is sending together with the call\n * @param _data Calldata to trigger execution in target address\n */\n function _checkRestrictions(\n address _facet,\n address _target,\n uint256 _value,\n bytes memory _data\n ) internal returns (uint256 result) {\n bytes memory call = abi.encodeWithSignature(\n \"verifyRestrictions(address,address,uint256,bytes)\",\n address(this),\n _target,\n _value,\n _data\n );\n (bool success, bytes memory response) = _facet.delegatecall(call);\n if (!success) revert AccountFacet__RestrictionsFailure();\n result = uint256(bytes32(response));\n }\n}\n" + }, + "contracts/facets/AccountRecoveryFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibFacetStorage, RecoveryStorage, RecoveryConfig, RecoveryApprovalConfig, ApprovalConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {IAccountRecoveryFacet} from \"./interfaces/IAccountRecoveryFacet.sol\";\n\n/**\n * @title Account Recovery Facet\n * @dev Contract that enables recovery of accounts when owner key is unavailable\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract AccountRecoveryFacet is IAccountRecoveryFacet, Modifiers {\n bytes constant UNINIT_CALL =\n abi.encodeWithSignature(\"uninitializeSigner()\");\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Approve recovery of account as guardian\n * @dev This method can only be called by guardian and guardian inputs the public key of the new owner\n * When the threshold(majority of guardians) passes, it automatically executes account recovery\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function approveAccountRecovery(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + _getApprovalValidationPeriod()\n );\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit RecoveryApproved(\n _recoveryPublicKey,\n msg.sender,\n approvalValidUntil\n );\n if (\n getRecoveryApprovalCountWithTimeValidity(recoveryPublicKeyHash) >=\n LibGuardian.majorityOfGuardians()\n ) _executeRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Revoke recovery of account as guardian\n * @dev This method can only be called by guardian and guardian inputs the public key of the new owner\n When the threshold(majority of guardians) passes, it automatically revokes account recovery when recovery is pending\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function revokeAccountRecoveryApproval(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n if (\n !rs\n .isNewOwnerApproved[recoveryPublicKeyHash][msg.sender].isApproved ||\n !(block.timestamp <\n rs\n .isNewOwnerApproved[recoveryPublicKeyHash][msg.sender]\n .validUntil)\n ) revert AccountRecoveryFacet__NonExistentApproval();\n\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(false, 0);\n emit RecoveryApprovalRevoked(_recoveryPublicKey, msg.sender);\n }\n\n /**\n * @notice Executes recovery with signatures or on-chain pre-approvals\n * @dev This method validates the signatures of guardians or checks the on-chain pre-approved calls to check if the threshold passes\n * When the threshold passes, account recovery is executed and revert otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _guardians Array of guardians address that are approving the recovery of Account\n * @param _signatures Array of signature bytes that signed the approval hash\n */\n function executeRecovery(\n bytes calldata _recoveryPublicKey,\n address[] calldata _guardians,\n bytes[] calldata _signatures\n ) external override {\n if (_isRecoveryPending())\n revert AccountRecoveryFacet__RecoveryAlreadyOngoing();\n if (_guardians.length != _signatures.length)\n revert AccountRecoveryFacet__InvalidArrayLength();\n validateNewOwner(_recoveryPublicKey);\n\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n\n _checkApprover(_guardians);\n _checkDuplicateOnChainApprover(recoveryPublicKeyHash, _guardians);\n\n if (\n _guardians.length +\n getRecoveryApprovalCountWithTimeValidity(\n recoveryPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians()\n ) revert AccountRecoveryFacet__InsufficientGuardians();\n for (uint256 i; i < _guardians.length; ) {\n if (!LibGuardian.isGuardian(_guardians[i]))\n revert AccountRecoveryFacet__InvalidGuardian();\n if (\n !SignatureChecker.isValidSignatureNow(\n _guardians[i],\n recoveryPublicKeyHash,\n _signatures[i]\n )\n ) revert AccountRecoveryFacet__InvalidGuardianSignature();\n unchecked {\n ++i;\n }\n }\n _executeRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Executes recovery of the account. Note that execution and finalization is a different process\n * @dev Executes the recovery and adds recovery data to recovery configuration. Locks the account\n * @param _recoveryPublicKey Public Key of the account for recovery\n */\n function _executeRecovery(bytes memory _recoveryPublicKey) internal {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n unchecked {\n ++rs.nonce;\n }\n uint64 executeAfter = uint64(block.timestamp + _getRecoveryPeriod());\n rs.recoveryConfigs[INNER_STRUCT] = RecoveryConfig(\n _recoveryPublicKey,\n executeAfter // NOTE: Remove guardian Count\n );\n LibAppStorage.setLock(\n block.timestamp + _getLockPeriod(),\n AccountRecoveryFacet.executeRecovery.selector\n );\n emit RecoveryExecuted(_recoveryPublicKey, executeAfter);\n }\n\n /**\n * @notice Finalize recovery after recovery pending period. Recovery pending period can be set by user beforehand in SecurityManager\n * @dev This method finalizes recovery and fully changes the ownership of the account to the newly inputted recovery public key\n */\n function finalizeRecovery() external override {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n if (\n uint64(block.timestamp) <=\n rs.recoveryConfigs[INNER_STRUCT].executeAfter\n ) revert AccountRecoveryFacet__RecoveryPeriodNotOver();\n bytes memory recoveryOwner = rs\n .recoveryConfigs[INNER_STRUCT]\n .recoveryPublicKey;\n\n delete rs.recoveryConfigs[INNER_STRUCT];\n\n LibAppStorage.setLock(0, bytes4(0));\n\n LibAppStorage.initiateSignerMigration();\n address verificationFacet = address(\n bytes20(\n LibDiamond.diamondStorage().facets[\n s.validateOwnerSignatureSelector\n ]\n )\n );\n (bool success, bytes memory result) = verificationFacet.delegatecall(\n UNINIT_CALL\n );\n if (!success) revert AccountRecoveryFacet__CallNotSuccesful();\n uint256 validationData = uint256(bytes32(result));\n if (validationData != 1)\n revert AccountRecoveryFacet__SignerUninitializationFailure();\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n recoveryOwner\n );\n (success, result) = verificationFacet.delegatecall(initCall);\n if (!success) revert AccountRecoveryFacet__CallNotSuccesful();\n validationData = uint256(bytes32(result));\n if (validationData != 1)\n revert AccountRecoveryFacet__SignerInitializationFailure();\n LibAppStorage.finalizeSignerMigration();\n emit RecoveryFinalized(recoveryOwner);\n }\n\n /**\n * @notice Approves the cancellation of recovery\n * @dev This method approves the cancellation of recovery when recovery is still pending - waiting for finalization\n * @param _recoveryPublicKey Bytes of public key which is pending for recovery\n */\n function approveCancelRecovery(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"CancelRecovery\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + _getApprovalValidationPeriod()\n );\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit RecoveryCancellationApproved(_recoveryPublicKey, msg.sender);\n if (\n getRecoveryApprovalCountWithTimeValidity(recoveryPublicKeyHash) >=\n LibGuardian.majorityOfGuardians()\n ) {\n _cancelRecovery(_recoveryPublicKey);\n }\n }\n\n /**\n * @notice Hardstops an ongoing recovery\n * @dev This method provides a safety mechanism to protect owners of malicious guardians.\n * Owners can hardstop recovery when an malicious guardians starts the recovery process.\n * @param _signature Signature of the owner that signs the hash to hardstop recovery\n */\n function hardstopRecovery(bytes calldata _signature) external override {\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n \"0\",\n \"HardstopRecovery\"\n );\n if (\n !SignatureChecker.isValidSignatureNow(\n address(this),\n recoveryPublicKeyHash,\n _signature\n )\n ) revert AccountRecoveryFacet__InvalidOwnerSignature();\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n unchecked {\n ++rs.nonce;\n }\n delete rs.recoveryConfigs[INNER_STRUCT];\n LibAppStorage.setLock(0, bytes4(0));\n emit RecoveryHardstopped();\n }\n\n /**\n * @notice Cancels recovery with signatures or on-chain pre-approvals\n * @dev This method validates the signatures of guardians or checks the on-chain pre-approved calls to check if the threshold passes\n * When the threshold passes, account recovery is canceled and revert otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _guardians Array of guardians address that are approving the recovery of Account\n * @param _signatures Array of signature bytes that signed the cancellation approval hash\n */\n function cancelRecovery(\n bytes calldata _recoveryPublicKey,\n address[] calldata _guardians,\n bytes[] calldata _signatures\n ) external override {\n if (_guardians.length != _signatures.length)\n revert AccountRecoveryFacet__InvalidArrayLength();\n validateNewOwner(_recoveryPublicKey);\n\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"CancelRecovery\"\n );\n\n _checkApprover(_guardians);\n _checkDuplicateOnChainApprover(recoveryPublicKeyHash, _guardians);\n\n if (\n _guardians.length +\n getRecoveryApprovalCountWithTimeValidity(\n recoveryPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians()\n ) revert AccountRecoveryFacet__InsufficientGuardians();\n for (uint256 i; i < _guardians.length; ) {\n if (!LibGuardian.isGuardian(_guardians[i]))\n revert AccountRecoveryFacet__CallerNotGuardian();\n if (\n !SignatureChecker.isValidSignatureNow(\n _guardians[i],\n recoveryPublicKeyHash,\n _signatures[i]\n )\n ) revert AccountRecoveryFacet__InvalidGuardianSignature();\n unchecked {\n ++i;\n }\n }\n _cancelRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Cancel recovery when the recovery is pending. Unlock the account as well\n * @dev This method checks if the recovery is pending and reverts if not pending.\n * It increases the recovery nonce and deletes the recovery information and gets a small portion of gas in return\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function _cancelRecovery(bytes memory _recoveryPublicKey) internal {\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n LibAppStorage.setLock(0, bytes4(0));\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n unchecked {\n ++rs.nonce;\n }\n delete rs.recoveryConfigs[INNER_STRUCT];\n emit RecoveryCanceled(_recoveryPublicKey);\n }\n\n /**\n * @notice Validates the format of public key to be used for recovery\n * @dev This method checks if the public key format is correct and reverts otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function validateNewOwner(bytes memory _recoveryPublicKey) public view {\n if (\n !IVerificationFacet(\n LibLoupe.facetAddress(s.validateOwnerSignatureSelector)\n ).isValidKeyType(_recoveryPublicKey)\n ) revert AccountRecoveryFacet__InvalidRecoveryPublicKey();\n }\n\n /**\n * @notice Checks if recovery is currently pending\n * @return isPending Boolean indicating if recovery is pending\n */\n function _isRecoveryPending() internal view returns (bool isPending) {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n isPending = (rs.recoveryConfigs[INNER_STRUCT].executeAfter > 0);\n }\n\n /**\n * @notice Calculate the recovery hash dependent on chain, wallet address, nonce with EIP-191 prefix for safety\n * @dev Returns the keccak256 hash of EIP-191 msg hash packed with public key, salt, nonce, wallet address, etc\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _saltString Salt string to uniquely identify each recovery hash and for security\n * @return recoveryKeyHash Bytes32 string of the recovery hash\n */\n function getApprovalRecoveryKeyHash(\n bytes memory _recoveryPublicKey,\n string memory _saltString\n ) public view override returns (bytes32 recoveryKeyHash) {\n recoveryKeyHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n _recoveryPublicKey,\n _saltString,\n address(this),\n block.chainid,\n LibFacetStorage.recoveryStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Check the onchain approval of guardians and returns the number of guardians that approved\n * @dev Loop through the guardian addresses and returns the number of guardians that approved this recovery hash\n * @param _recoveryPublicKeyHash Bytes hash of newly recovered public key and recovery value of the account\n * @return approvalCount Number of guardians that approved\n */\n function getRecoveryApprovalCountWithTimeValidity(\n bytes32 _recoveryPublicKeyHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n for (uint256 i; i < guardianLength; ) {\n if (isRecoveryApproved(_recoveryPublicKeyHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Checks if the recovery is approved by the given approver\n * @param _recoveryPublicKeyHash Hash of the public key and configuration for recovery\n * @param _approver Address of approver\n * @return isApproved Bool value if recovery hash is approved\n */\n function isRecoveryApproved(\n bytes32 _recoveryPublicKeyHash,\n address _approver\n ) public view override returns (bool isApproved) {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n if (\n rs\n .isNewOwnerApproved[_recoveryPublicKeyHash][_approver].isApproved &&\n block.timestamp <\n rs.isNewOwnerApproved[_recoveryPublicKeyHash][_approver].validUntil\n ) {\n isApproved = true;\n }\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _recoveryPublicKeyHash Hash of recovery information\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _recoveryPublicKeyHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isRecoveryApproved(_recoveryPublicKeyHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert AccountRecoveryFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the lock period of this wallet address from security manager\n * @return lockPeriod value of lock period\n */\n function _getLockPeriod() internal view returns (uint256 lockPeriod) {\n lockPeriod = securityManager.lockPeriodOf(address(this));\n if (lockPeriod == 0) revert AccountRecoveryFacet__InvalidLockPeriod();\n }\n\n /**\n * @notice Returns the lock period of this wallet address from security manager\n * @return recoveryPeriod value of recovery period\n */\n function _getRecoveryPeriod()\n internal\n view\n returns (uint256 recoveryPeriod)\n {\n recoveryPeriod = securityManager.recoveryPeriodOf(address(this));\n if (recoveryPeriod == 0)\n revert AccountRecoveryFacet__InvalidRecoveryPeriod();\n }\n\n /**\n * @notice Returns the approval validation period of this wallet address from security manager\n * @return approvalValidationPeriod value of approval validation period\n */\n function _getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod == 0)\n revert AccountRecoveryFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the recovery nonce of this wallet address from security manager\n * @return nonce value of recovery nonce\n */\n function getRecoveryNonce() public view override returns (uint128 nonce) {\n nonce = LibFacetStorage.recoveryStorage().nonce;\n }\n\n /**\n * @notice Returns the recovery information of the pending recovery\n * @return recoveryConfig value struct of pending recovery\n */\n function getPendingRecovery()\n public\n view\n override\n returns (RecoveryConfig memory recoveryConfig)\n {\n recoveryConfig = LibFacetStorage.recoveryStorage().recoveryConfigs[\n INNER_STRUCT\n ];\n }\n}\n" + }, + "contracts/facets/base/DiamondCutFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibGuardian} from \"../../libraries/LibGuardian.sol\";\nimport {ISecurityManager} from \"../../infrastructure/interfaces/ISecurityManager.sol\";\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibFacetStorage, DiamondCutApprovalConfig, ApprovalConfig} from \"../../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"../Modifiers.sol\";\nimport {IDiamondCut} from \"./interfaces/IDiamondCut.sol\";\n\n/**\n * @title DiamondCut Facet\n * @dev Responsible for adding/removing/replace facets in Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DiamondCutFacet is Modifiers, IDiamondCut {\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Updates the flag for the interfaceId\n * @param _interfaceId InterfaceID to update the mapping\n * @param _flag Bool value to update the mapping of the given interface ID\n */\n function updateSupportsInterface(\n bytes4 _interfaceId,\n bool _flag\n ) external override onlyWhenUnlocked {\n LibDiamond.enforceIsSelf();\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId] = _flag;\n emit SupportsInterfaceUpdated(_interfaceId, _flag);\n }\n\n /**\n * @notice Add/replace/remove any number of functions and optionally execute\n * a function with delegatecall when guardians don't exist\n * @param _diamondCut Contains the facet addresses and function selectors\n * @param _init The address of the contract or facet to execute _calldata. It's prohibited in Barz\n */\n function diamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata\n ) external override onlyWhenUnlocked {\n LibDiamond.enforceIsSelf();\n\n _checkFacetCutValidity(_diamondCut);\n // require approval from guardian if guardian exists\n if (0 != LibGuardian.guardianCount())\n revert DiamondCutFacet__InvalidRouteWithGuardian();\n if (address(0) != _init) revert DiamondCutFacet__InvalidInitAddress();\n\n unchecked {\n ++LibFacetStorage.diamondCutStorage().nonce;\n }\n LibDiamond.diamondCut(_diamondCut, address(0), \"\");\n }\n\n /**\n * @notice Add/replace/remove any number of functions and optionally execute\n * a function with delegatecall when guardians exist\n * @param _diamondCut Contains the facet addresses and function selectors\n * @param _approvers Guardian or owner address that approves the diamond cut\n * @param _signatures Signature of Guardians or owner that approves the diamond cut\n */\n function diamondCutWithGuardian(\n FacetCut[] calldata _diamondCut,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n ) external override onlyWhenUnlocked {\n if (_approvers.length != _signatures.length)\n revert DiamondCutFacet__InvalidArrayLength();\n _checkFacetCutValidity(_diamondCut);\n if (0 == LibGuardian.guardianCount())\n revert DiamondCutFacet__InvalidRouteWithGuardian();\n\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(cutHash, _approvers);\n\n bool onChainOwnerApproval = getOwnerCutApprovalWithTimeValidity(\n cutHash\n );\n\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n if (\n _approvers.length +\n getDiamondCutApprovalCountWithTimeValidity(cutHash) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert DiamondCutFacet__InsufficientApprovers();\n\n bool ownerApproved;\n for (uint256 i; i < _approvers.length; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n _approvers[i] != address(this)\n ) revert DiamondCutFacet__InvalidApprover();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert DiamondCutFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n cutHash,\n _signatures[i]\n )\n ) revert DiamondCutFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n if (!ownerApproved && !onChainOwnerApproval)\n revert DiamondCutFacet__LackOfOwnerApproval();\n\n unchecked {\n ++LibFacetStorage.diamondCutStorage().nonce;\n }\n LibDiamond.diamondCut(_diamondCut, address(0), \"\");\n }\n\n /**\n * @notice Approves diamond cut. This can only be called directly from guardian or owner\n * @param _diamondCut Contains the facet addresses and function selectors\n */\n function approveDiamondCut(\n FacetCut[] calldata _diamondCut\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\n if (LibGuardian.guardianCount() == 0)\n revert DiamondCutFacet__InvalidRouteWithoutGuardian();\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n _checkFacetCutValidity(_diamondCut);\n\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(\n true,\n approvalValidUntil\n );\n emit DiamondCutApproved(_diamondCut);\n if (\n (getDiamondCutApprovalCountWithTimeValidity(cutHash) >=\n LibGuardian.majorityOfGuardians()) &&\n getOwnerCutApprovalWithTimeValidity(cutHash)\n ) {\n unchecked {\n ++LibFacetStorage.diamondCutStorage().nonce;\n }\n LibDiamond.diamondCut(_diamondCut, address(0), \"\");\n }\n }\n\n /**\n * @notice Revokes the approval of diamond cut. This can only be called directly from guardian or owner\n * @param _diamondCut Contains the facet addresses and function selectors\n */\n function revokeDiamondCutApproval(\n FacetCut[] calldata _diamondCut\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\n if (!ds.isDiamondCutApproved[cutHash][msg.sender].isApproved)\n revert DiamondCutFacet__CannotRevokeUnapproved();\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(false, 0);\n emit DiamondCutApprovalRevoked(_diamondCut);\n }\n\n /**\n * @notice Gets the number of approvals of diamond cut from guardians\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n */\n function getDiamondCutApprovalCountWithTimeValidity(\n bytes32 _diamondCutHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardiansLength = guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n if (isCutApproved(_diamondCutHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n return approvalCount;\n }\n\n /**\n * @notice Returns if the owner has approved the diamond cut\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @return isApprovedByOwner Bool value showing if the owner approved the cut\n */\n function getOwnerCutApprovalWithTimeValidity(\n bytes32 _diamondCutHash\n ) public view override returns (bool isApprovedByOwner) {\n isApprovedByOwner = isCutApproved(_diamondCutHash, address(this));\n }\n\n /**\n * @notice Returns if the given approver has approved the diamond cut\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @param _approver Address of approver\n * @return isApproved Bool value showing if the approver approved the cut\n */\n function isCutApproved(\n bytes32 _diamondCutHash,\n address _approver\n ) public view override returns (bool isApproved) {\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n isApproved = (ds\n .isDiamondCutApproved[_diamondCutHash][_approver].isApproved &&\n block.timestamp <\n ds.isDiamondCutApproved[_diamondCutHash][_approver].validUntil);\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _diamondCutHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isCutApproved(_diamondCutHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert DiamondCutFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the diamond cut hash. This function ensures that this hash is safe from replay attack by including\n * salt, address, chainId, and nonce, etc.\n * @param _diamondCut Contains the facet addresses and function selectors\n * @return cutHash Diamond Cut Hash\n */\n function getDiamondCutHash(\n FacetCut[] calldata _diamondCut\n ) public view override returns (bytes32 cutHash) {\n cutHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n keccak256(abi.encode(_diamondCut)),\n address(this),\n block.chainid,\n LibFacetStorage.diamondCutStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Returns the approval validation Period\n * @dev This method fetches the validation period from the security manager\n * @return approvalValidationPeriod Approval validation period of Barz contract fetched from security manager\n */\n function getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod <= 0)\n revert DiamondCutFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the diamond cut nonce of this wallet\n * @dev This method fetches the nonce from diamond cut storage\n * @return cutNonce Nonce of diamond cut to protect from reply attacks\n */\n function getDiamondCutNonce()\n public\n view\n override\n returns (uint128 cutNonce)\n {\n cutNonce = LibFacetStorage.diamondCutStorage().nonce;\n }\n}\n" + }, + "contracts/facets/base/DiamondLoupeFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {IERC165} from \"../../interfaces/ERC/IERC165.sol\";\nimport {IERC1271} from \"../../interfaces/ERC/IERC1271.sol\";\nimport {IERC677Receiver} from \"../../interfaces/ERC/IERC677Receiver.sol\";\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC1155Receiver} from \"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\";\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../../libraries/LibLoupe.sol\";\nimport {LibUtils} from \"../../libraries/LibUtils.sol\";\nimport {IDiamondCut} from \"../../facets/base/interfaces/IDiamondCut.sol\";\nimport {IStorageLoupe} from \"./interfaces/IStorageLoupe.sol\";\nimport {IDiamondLoupe} from \"./interfaces/IDiamondLoupe.sol\";\n\n/**\n * @title DiamondLoupe Facet\n * @dev DiamondLoupe contract compatible with EIP-2535\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DiamondLoupeFacet is IDiamondLoupe, IStorageLoupe, IERC165 {\n // Diamond Loupe Functions\n ////////////////////////////////////////////////////////////////////\n /// These functions are expected to be called frequently by tools off-chain.\n\n /**\n * @notice Gets all facets and their selectors.\n * @dev Barz uses a special architecture called default fallback handler. Default Fallback handler is used as a middleware\n * that holds the mapping of facet function selector and facet address that Barz uses. This helps Barz to reduce\n * significant amount of gas during the initialization process.\n * Hence, this method aggregates both the facet information from DefaulFallbackHandler and in diamond storage and shows the data to users.\n * @return facets_ Facet\n */\n function facets() public view override returns (Facet[] memory facets_) {\n Facet[] memory defaultFacet = LibDiamond\n .diamondStorage()\n .defaultFallbackHandler\n .facets();\n Facet[] memory _facets = LibLoupe.facets();\n uint256 numFacets = _facets.length;\n bytes4[] memory keys;\n address[] memory values;\n for (uint256 i; i < numFacets; ) {\n uint256 selectorsLength = _facets[i].functionSelectors.length;\n for (uint256 j; j < selectorsLength; ) {\n (keys, values) = LibUtils.setValue(\n keys,\n values,\n _facets[i].functionSelectors[j],\n _facets[i].facetAddress\n );\n unchecked {\n ++j;\n }\n }\n unchecked {\n ++i;\n }\n }\n {\n bool iIncrement;\n for (uint256 i; i < defaultFacet.length; ) {\n bool jIncrement;\n for (\n uint256 j;\n j < defaultFacet[i].functionSelectors.length;\n\n ) {\n if (\n LibUtils.getValue(\n keys,\n values,\n defaultFacet[i].functionSelectors[j]\n ) != address(0)\n ) {\n if (defaultFacet[i].functionSelectors.length == 1) {\n defaultFacet = LibUtils.removeFacetElement(\n defaultFacet,\n i\n );\n iIncrement = true;\n break;\n }\n defaultFacet[i].functionSelectors = LibUtils\n .removeElement(\n defaultFacet[i].functionSelectors,\n j\n );\n jIncrement = true;\n }\n if (!jIncrement) {\n unchecked {\n ++j;\n }\n } else {\n jIncrement = false;\n }\n }\n if (!iIncrement) {\n unchecked {\n ++i;\n }\n } else {\n iIncrement = false;\n }\n }\n }\n {\n uint256 facetLength = numFacets + defaultFacet.length;\n facets_ = new Facet[](facetLength);\n uint256 defaultFacetIndex;\n for (uint256 i; i < facetLength; ) {\n if (i < numFacets) {\n facets_[i] = _facets[i];\n bool jIncrementor;\n for (uint256 j; j < defaultFacet.length; ) {\n if (\n facets_[i].facetAddress ==\n defaultFacet[j].facetAddress\n ) {\n facets_[i].functionSelectors = LibUtils.mergeArrays(\n _facets[i].functionSelectors,\n defaultFacet[j].functionSelectors\n );\n defaultFacet = LibUtils.removeFacetElement(\n defaultFacet,\n j\n );\n jIncrementor = true;\n {\n facets_ = LibUtils.removeFacetElement(\n facets_,\n facets_.length - 1\n );\n }\n --facetLength;\n }\n if (!jIncrementor) {\n unchecked {\n ++j;\n }\n } else {\n jIncrementor = false;\n }\n }\n } else {\n facets_[i] = defaultFacet[defaultFacetIndex];\n ++defaultFacetIndex;\n }\n unchecked {\n ++i;\n }\n }\n }\n }\n\n /**\n * @notice Gets all the function selectors provided by a facet.\n * @param _facet The facet address.\n * @return facetFunctionSelectors_\n */\n function facetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n Facet[] memory facet = facets();\n uint256 facetLength = facet.length;\n for (uint256 i; i < facetLength; ) {\n if (facet[i].facetAddress == _facet)\n return facet[i].functionSelectors;\n unchecked {\n ++i;\n }\n }\n return facetFunctionSelectors_;\n }\n\n /**\n * @notice Get all the facet addresses used by Barz.\n * @return facetAddresses_\n */\n function facetAddresses()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n Facet[] memory facet = facets();\n uint256 facetLength = facet.length;\n facetAddresses_ = new address[](facetLength);\n for (uint256 i; i < facetLength; ) {\n facetAddresses_[i] = facet[i].facetAddress;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Gets the facet that supports the given selector.\n * @dev If facet is not found return address(0).\n * @param _functionSelector The function selector.\n * @return facetAddress_ The facet address.\n */\n function facetAddress(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n\n facetAddress_ = address(bytes20(ds.facets[_functionSelector]));\n if (facetAddress_ == address(0)) {\n facetAddress_ = IDiamondLoupe(ds.defaultFallbackHandler)\n .facetAddress(_functionSelector);\n }\n }\n\n /**\n * @notice SupportInterface to be compatible with EIP 165\n * @param _interfaceId Interface ID for detecting the interface\n * @return isSupported Bool value showing if the standard is supported in the contract\n */\n function supportsInterface(\n bytes4 _interfaceId\n ) external view override returns (bool isSupported) {\n isSupported =\n _interfaceId == type(IERC165).interfaceId ||\n _interfaceId == IDiamondCut.diamondCut.selector ||\n _interfaceId == type(IDiamondLoupe).interfaceId ||\n _interfaceId == type(IERC1155Receiver).interfaceId ||\n _interfaceId == type(IERC721Receiver).interfaceId ||\n _interfaceId == type(IERC777Recipient).interfaceId ||\n _interfaceId == IERC1271.isValidSignature.selector ||\n _interfaceId == type(IERC677Receiver).interfaceId ||\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId];\n }\n\n /**\n * @notice Returns the facet from the diamond storage. This excludes the facets from the default fallback handler\n * @return facets_ Facet information attached directly to diamond storage\n */\n function facetsFromStorage()\n external\n view\n override\n returns (Facet[] memory facets_)\n {\n facets_ = LibLoupe.facets();\n }\n\n /**\n * @notice Returns the facet address attached to the given function selector. This excludes the facets from the default fallback handler\n * @param _functionSelector Function selector to fetch the facet address from diamond storage\n * @return facetAddress_ Facet address mapped with the function selector\n */\n function facetAddressFromStorage(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n facetAddress_ = LibLoupe.facetAddress(_functionSelector);\n }\n\n /**\n * @notice Returns all facet addresses attached directly to diamond storage. This excludes the facets from the default fallback handler\n * @return facetAddresses_ All facet addresses attached directly to diamond storage\n */\n function facetAddressesFromStorage()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n facetAddresses_ = LibLoupe.facetAddresses();\n }\n\n /**\n * @notice Returns function selectors of given facet address attached directly to diamond storage. This excludes the facets from the default fallback handler\n * @param _facet Facet address to fetch the facet function selectors from diamond storage\n * @return facetFunctionSelectors_ Facet function selectors of the given facet address\n */\n function facetFunctionSelectorsFromStorage(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n facetFunctionSelectors_ = LibLoupe.facetFunctionSelectors(_facet);\n }\n}\n" + }, + "contracts/facets/base/interfaces/IDiamondCut.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title DiamondCut Facet Interface\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IDiamondCut {\n error DiamondCutFacet__InvalidRouteWithGuardian();\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\n error DiamondCutFacet__InvalidArrayLength();\n error DiamondCutFacet__InsufficientApprovers();\n error DiamondCutFacet__InvalidApprover();\n error DiamondCutFacet__InvalidApproverSignature();\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\n error DiamondCutFacet__CannotRevokeUnapproved();\n error DiamondCutFacet__LackOfOwnerApproval();\n error DiamondCutFacet__OwnerAlreadyApproved();\n error DiamondCutFacet__DuplicateApproval();\n error DiamondCutFacet__InvalidInitAddress();\n\n event DiamondCutApproved(FacetCut[] diamondCut);\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\n\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\n\n enum FacetCutAction {\n Add,\n Replace,\n Remove\n }\n // Add=0, Replace=1, Remove=2\n\n struct FacetCut {\n address facetAddress;\n FacetCutAction action;\n bytes4[] functionSelectors;\n }\n\n /// @notice Add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param diamondCut Contains the facet addresses and function selectors\n /// @param init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function diamondCut(\n FacetCut[] calldata diamondCut,\n address init,\n bytes calldata _calldata\n ) external;\n\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\n\n function diamondCutWithGuardian(\n FacetCut[] calldata diamondCut,\n address[] calldata approvers,\n bytes[] calldata signatures\n ) external;\n\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\n\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\n\n function getDiamondCutApprovalCountWithTimeValidity(\n bytes32 diamondCutHash\n ) external view returns (uint256);\n\n function getOwnerCutApprovalWithTimeValidity(\n bytes32 diamondCutHash\n ) external view returns (bool);\n\n function isCutApproved(\n bytes32 diamondCutHash,\n address approver\n ) external view returns (bool);\n\n function getDiamondCutHash(\n FacetCut[] calldata diamondCut\n ) external view returns (bytes32);\n\n function getDiamondCutNonce() external view returns (uint128);\n}\n" + }, + "contracts/facets/base/interfaces/IDiamondLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n// A loupe is a small magnifying glass used to look at diamonds.\n// These functions look at diamonds\ninterface IDiamondLoupe {\n /// These functions are expected to be called frequently\n /// by tools.\n\n struct Facet {\n address facetAddress;\n bytes4[] functionSelectors;\n }\n\n /// @notice Gets all facet addresses and their four byte function selectors.\n /// @return facets_ Facet\n function facets() external view returns (Facet[] memory facets_);\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n /// @return facetFunctionSelectors_\n function facetFunctionSelectors(\n address _facet\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses()\n external\n view\n returns (address[] memory facetAddresses_);\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(\n bytes4 _functionSelector\n ) external view returns (address facetAddress_);\n}\n" + }, + "contracts/facets/base/interfaces/IStorageLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"./IDiamondLoupe.sol\";\n\n/**\n * @title LoupeFromStorage Interface\n * @dev Interface contract to function as a loupe facet directly attached to diamond storage of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IStorageLoupe {\n /// These functions are expected to be called frequently\n /// by tools.\n\n /// @notice Gets all facet addresses and their four byte function selectors.\n /// @return facets_ Facet\n function facetsFromStorage()\n external\n view\n returns (IDiamondLoupe.Facet[] memory);\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n function facetFunctionSelectorsFromStorage(\n address _facet\n ) external view returns (bytes4[] memory);\n\n /// @notice Get all the facet addresses used by a diamond.\n function facetAddressesFromStorage()\n external\n view\n returns (address[] memory);\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n function facetAddressFromStorage(\n bytes4 _functionSelector\n ) external view returns (address);\n}\n" + }, + "contracts/facets/GuardianFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibFacetStorage, GuardianStorage, StorageConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IGuardianFacet} from \"./interfaces/IGuardianFacet.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Guardian Facet\n * @dev Contract that enables addition/removal of guardians from Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract GuardianFacet is IGuardianFacet {\n ISecurityManager public immutable securityManager;\n uint8 public constant INNER_STRUCT = 0;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Add guardians to Barz.\n * @dev This method internally calls addGuardian which checks the validity of guardian address and adds\n * as guardian if valid\n * @param _guardians Array of addresses to add as guardian\n */\n function addGuardians(address[] calldata _guardians) external override {\n LibDiamond.enforceIsSelf();\n for (uint256 i; i < _guardians.length; ) {\n addGuardian(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Add a guardian to Barz.\n * @dev This method checks if the function is called by the owner and validates the address of guardian\n * When the validation passes, guardian address is added to the pending state waiting for confirmation\n * @param _guardian Address to add as guardian\n */\n function addGuardian(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (_guardian == address(this))\n revert GuardianFacet__GuardianCannotBeSelf();\n if (isGuardian(_guardian)) revert GuardianFacet__DuplicateGuardian();\n if (_guardian == address(0))\n revert GuardianFacet__ZeroAddressGuardian();\n if (\n keccak256(abi.encodePacked(_guardian)) ==\n keccak256(IVerificationFacet(address(this)).owner())\n ) revert GuardianFacet__OwnerCannotBeGuardian();\n\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n if (\n gs.pending[id] != 0 ||\n block.timestamp <= gs.pending[id] + getSecurityWindow()\n ) revert GuardianFacet__DuplicateGuardianAddition();\n\n uint256 securityPeriod = getAdditionSecurityPeriod();\n gs.pending[id] = block.timestamp + securityPeriod;\n emit GuardianAdditionRequested(\n _guardian,\n block.timestamp + securityPeriod\n );\n }\n\n /**\n * @notice Remove guardians from Barz.\n * @dev This method internally calls removeGuardian which checks the validity of guardian and removes\n * guardian when the request is valid\n * @param _guardians Array of addresses to be removed\n */\n function removeGuardians(address[] calldata _guardians) external override {\n LibDiamond.enforceIsSelf();\n for (uint256 i; i < _guardians.length; ) {\n removeGuardian(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Remove a guardian from Barz.\n * @dev This method validates if the guardian to be removed is a guardian and puts the guardian removal\n * to a pending state waiting to be confirmed.\n * @param _guardian Address of guardian to be removed\n */\n function removeGuardian(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n if (!isGuardian(_guardian)) revert GuardianFacet__NonExistentGuardian();\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n if (\n gs.pending[id] != 0 ||\n block.timestamp <= gs.pending[id] + getSecurityWindow()\n ) revert GuardianFacet__DuplicateGuardianRemoval();\n\n uint256 securityPeriod = getRemovalSecurityPeriod();\n gs.pending[id] = block.timestamp + securityPeriod;\n emit GuardianRemovalRequested(\n _guardian,\n block.timestamp + securityPeriod\n );\n }\n\n /**\n * @notice Confirm addition of guardians\n * @dev This method internally calls confirmGuardianAddition which checks the validity of pending request.\n * Guardians are fully added when they pass the validation. Anyone can call this function.\n * @param _guardians Array of guardian addresses to be added\n */\n function confirmGuardianAdditions(\n address[] calldata _guardians\n ) external override {\n for (uint256 i; i < _guardians.length; ) {\n confirmGuardianAddition(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Confirm addition of a guardian\n * @dev This method checks the validity of pending request.\n * Guardians are fully added when they pass the validation. Anyone can call this function.\n * @param _guardian Guardian address to be added\n */\n function confirmGuardianAddition(address _guardian) public override {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingAddition();\n if (gs.pending[id] >= block.timestamp)\n revert GuardianFacet__PendingAdditionNotOver();\n if (block.timestamp >= gs.pending[id] + getSecurityWindow())\n revert GuardianFacet__PendingAdditionExpired();\n\n _addGuardian(_guardian);\n\n delete gs.pending[id];\n emit GuardianAdded(_guardian);\n }\n\n /**\n * @notice Confirm removal of guardians\n * @dev This method internally calls confirmGuardianRemoval to check the validity guardian removal confirmation.\n * Guardians are fully removed when they pass the validation. Anyone can call this function.\n * @param _guardians Array of guardian addresses to be removed\n */\n function confirmGuardianRemovals(\n address[] calldata _guardians\n ) external override {\n for (uint256 i; i < _guardians.length; ) {\n confirmGuardianRemoval(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Confirm removal of a guardian\n * @dev This method checks the validity guardian removal confirmation.\n * Guardian is fully removed when they pass the validation. Anyone can call this function.\n * @param _guardian Guardian address to be removed\n */\n function confirmGuardianRemoval(address _guardian) public override {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingRemoval();\n if (gs.pending[id] >= block.timestamp)\n revert GuardianFacet__PendingRemovalNotOver();\n if (block.timestamp >= gs.pending[id] + getSecurityWindow())\n revert GuardianFacet__PendingAdditionExpired();\n\n _removeGuardian(_guardian);\n delete gs.pending[id];\n emit GuardianRemoved(_guardian);\n }\n\n /**\n * @notice Cancel pending guardian addition\n * @dev This method checks if the previous request for guardian request exists.\n * It reverts if previous request is not pending and cancels the addition otherwise.\n * @param _guardian Guardian address to be canceled from addition\n */\n function cancelGuardianAddition(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingAddition();\n delete gs.pending[id];\n emit GuardianAdditionCancelled(_guardian);\n }\n\n /**\n * @notice Cancel pending guardian removal\n * @dev This method checks if the previous request for guardian request exists.\n * It reverts if previous request is not pending and cancels the removal otherwise.\n * @param _guardian Guardian address to be canceled from removal\n */\n function cancelGuardianRemoval(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingRemoval();\n delete gs.pending[id];\n emit GuardianRemovalCancelled(_guardian);\n }\n\n /**\n * @notice Get the addition security period of current account from security manager\n * @dev This method returns the uint value if addition security period\n * @return additionSecurityPeriod Uint256 value of addition security period\n */\n function getAdditionSecurityPeriod()\n public\n view\n override\n returns (uint256 additionSecurityPeriod)\n {\n additionSecurityPeriod = securityManager.additionSecurityPeriodOf(\n address(this)\n );\n if (additionSecurityPeriod == 0)\n revert GuardianFacet__InvalidAdditionSecurityPeriod();\n }\n\n /**\n * @notice Get the removal security period of current account from security manager\n * @dev This method returns the uint value if removal security period\n * @return removalSecurityPeriod Uint256 value of removal security period\n */\n function getRemovalSecurityPeriod()\n public\n view\n override\n returns (uint256 removalSecurityPeriod)\n {\n removalSecurityPeriod = securityManager.removalSecurityPeriodOf(\n address(this)\n );\n if (removalSecurityPeriod == 0)\n revert GuardianFacet__InvalidRemovalSecurityPeriod();\n }\n\n /**\n * @notice Get the security window of current account from security manager\n * @dev This method returns the uint value if security window\n * @return securityWindow Uint256 value of removal security period\n */\n function getSecurityWindow()\n public\n view\n override\n returns (uint256 securityWindow)\n {\n securityWindow = securityManager.securityWindowOf(address(this));\n if (securityWindow == 0) revert GuardianFacet__InvalidSecurityWindow();\n }\n\n /**\n * @notice Checks if the addition of the given guardian address is pending\n * @dev This method returns the bool value of whether the guardian address is pending addition\n * @return isPending Bool value of representing the pending of guardian addition\n */\n function isAdditionPending(\n address _guardian\n ) public view override returns (bool isPending) {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n isPending = _isPending(id);\n }\n\n /**\n * @notice Checks if the removal of the given guardian address is pending\n * @dev This method returns the bool value of whether the guardian address is pending removal\n * @return isPending Bool value of representing the pending of guardian removal\n */\n function isRemovalPending(\n address _guardian\n ) public view override returns (bool isPending) {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n isPending = _isPending(id);\n }\n\n /**\n * @notice Checks if the given hash is pending\n * @dev This method returns the bool value whether the hash is pending\n * @return isPending Bool value of representing the pending of guardian operation\n */\n function _isPending(\n bytes32 _idHash\n ) internal view returns (bool isPending) {\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n isPending = ((gs.pending[_idHash] > 0 &&\n gs.pending[_idHash] < block.timestamp) &&\n block.timestamp < gs.pending[_idHash] + getSecurityWindow());\n }\n\n /**\n * @notice Adds guardian to storage config. This is called when guardian is fully added.\n * @dev This method add guardian address and config information to Facet Storage dedicated for guardian\n * When this function is called, guardian is fully added to this Barz Smart Account\n * @param _guardian Address of guardian to be added\n */\n function _addGuardian(address _guardian) internal {\n if (!isAdditionPending(_guardian))\n revert GuardianFacet__InvalidGuardianAddition();\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n if (config.info[_guardian].exists)\n revert GuardianFacet__AlreadyExists();\n\n config.info[_guardian].exists = true;\n config.info[_guardian].index = uint128(config.addresses.length);\n config.addresses.push(_guardian);\n }\n\n /**\n * @notice Removes guardian to storage config. This is called when guardian is fully removed.\n * @dev This method remove guardian address and config information to Facet Storage dedicated for guardian\n * When this function is called, guardian is fully removed from this Barz Smart Account\n * @param _guardian Address of guardian to be removed\n */\n function _removeGuardian(address _guardian) internal {\n if (!isRemovalPending(_guardian))\n revert GuardianFacet__InvalidGuardianRemoval();\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n if (!config.info[_guardian].exists)\n revert GuardianFacet__NonExistentGuardian();\n\n address lastAddress = config.addresses[config.addresses.length - 1];\n if (_guardian != lastAddress) {\n uint128 targetIndex = config.info[_guardian].index;\n config.addresses[targetIndex] = lastAddress;\n config.info[lastAddress].index = targetIndex;\n }\n config.addresses.pop();\n delete config.info[_guardian];\n\n emit GuardianRemoved(_guardian);\n }\n\n /**\n * @notice Reads guardian storage and fetches the addresses into an array from the storage\n * @dev This method fetches the guardian storage and returns the list of guardian addresses\n * @return addresses Array of addresses comprised of guardian\n */\n function getGuardians()\n public\n view\n override\n returns (address[] memory addresses)\n {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n uint256 addressesLen = config.addresses.length;\n addresses = new address[](addressesLen);\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the number of majority of guardians\n * @return majorityOfGuardians_ Number of majority of guardians e.g., 2 if 3 guardians / 3 if 5 guardians\n */\n function majorityOfGuardians()\n public\n view\n override\n returns (uint256 majorityOfGuardians_)\n {\n majorityOfGuardians_ = LibGuardian.majorityOfGuardians();\n }\n\n /**\n * @notice Reads guardian storage and fetches the addresses into an array from the storage\n * @dev This method fetches the guardian storage and returns the list of guardian addresses\n * @return guardianNumber Array of guardians in the account\n */\n function guardianCount()\n public\n view\n override\n returns (uint256 guardianNumber)\n {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n guardianNumber = config.addresses.length;\n }\n\n /**\n * @notice Reads guardian storage and checks if the given address is a guardian\n * @return isGuardian_ Bool value representing if the given address is guardian\n */\n function isGuardian(\n address _guardian\n ) public view override returns (bool isGuardian_) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n isGuardian_ = config.info[_guardian].exists;\n }\n\n /**\n * @notice Checks if the guardian number is zero and returns of guardian facet is okay to be removed\n * @return isRemovable Bool value representing if guardian facet is removable\n */\n function isGuardianFacetRemovable()\n external\n view\n override\n returns (bool isRemovable)\n {\n isRemovable = (0 == guardianCount());\n }\n}\n" + }, + "contracts/facets/interfaces/IAccountFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IEntryPoint} from \"../../aa-4337/interfaces/IEntryPoint.sol\";\n\n/**\n * @title Account Facet Interface\n * @dev Interface of module contract that provides the account features and init/unitialization of signer\n * compatible with EIP-1271 & EIP-4337\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IAccountFacet {\n event AccountInitialized(\n IEntryPoint indexed entryPoint,\n bytes indexed ownerPublicKey\n );\n // NOTE: Added Below Event\n event VerificationSuccess(bytes32);\n event VerificationFailure(bytes32);\n\n error AccountFacet__InitializationFailure();\n error AccountFacet__RestrictionsFailure();\n error AccountFacet__NonExistentVerificationFacet();\n error AccountFacet__CallNotSuccessful();\n error AccountFacet__InvalidArrayLength();\n\n function initialize(\n address verificationFacet,\n address anEntryPoint,\n address facetRegistry,\n address _defaultFallBack,\n bytes calldata _ownerPublicKey\n ) external returns (uint256);\n\n function execute(address dest, uint256 value, bytes calldata func) external;\n\n function executeBatch(\n address[] calldata dest,\n uint256[] calldata value,\n bytes[] calldata func\n ) external;\n}\n" + }, + "contracts/facets/interfaces/IAccountRecoveryFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {RecoveryConfig} from \"../../libraries/LibFacetStorage.sol\";\n\n/**\n * @title Account Recovery Facet Interface\n * @dev Interface of contract that enables recovery of accounts when owner key is unavailable\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IAccountRecoveryFacet {\n event RecoveryExecuted(\n bytes indexed recoveryPublicKey,\n uint64 executeAfter\n );\n event RecoveryFinalized(bytes indexed recoveryPublicKey);\n event RecoveryCanceled(bytes indexed recoveryPublicKey);\n event RecoveryApproved(\n bytes indexed recoveryPublicKey,\n address indexed guardian,\n uint64 validUntil\n );\n event RecoveryApprovalRevoked(\n bytes indexed recoveryPublicKey,\n address indexed guardian\n );\n event RecoveryCancellationApproved(\n bytes indexed recoveryPublicKey,\n address indexed guardian\n );\n event RecoveryHardstopped();\n\n error AccountRecoveryFacet__CallerNotGuardian();\n error AccountRecoveryFacet__InvalidRecoveryPublicKey();\n error AccountRecoveryFacet__SignerInitializationFailure();\n error AccountRecoveryFacet__SignerUninitializationFailure();\n error AccountRecoveryFacet__InvalidArrayLength();\n error AccountRecoveryFacet__InsufficientGuardians();\n error AccountRecoveryFacet__RecoveryAlreadyOngoing();\n error AccountRecoveryFacet__NonexistentRecovery();\n error AccountRecoveryFacet__NonExistentApproval();\n error AccountRecoveryFacet__RecoveryPeriodNotOver();\n error AccountRecoveryFacet__InvalidLockPeriod();\n error AccountRecoveryFacet__InvalidRecoveryPeriod();\n error AccountRecoveryFacet__InvalidApprovalValidationPeriod();\n error AccountRecoveryFacet__InvalidGuardian();\n error AccountRecoveryFacet__InvalidGuardianSignature();\n error AccountRecoveryFacet__InvalidOwnerSignature();\n error AccountRecoveryFacet__CallNotSuccesful();\n error AccountRecoveryFacet__DuplicateApproval();\n\n function approveAccountRecovery(bytes calldata recoveryPublicKey) external;\n\n function revokeAccountRecoveryApproval(\n bytes calldata recoveryPublicKey\n ) external;\n\n function executeRecovery(\n bytes calldata recoveryPublicKey,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function finalizeRecovery() external;\n\n function approveCancelRecovery(bytes calldata recoveryPublicKey) external;\n\n function cancelRecovery(\n bytes calldata recoveryPublicKey,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function hardstopRecovery(bytes calldata signature) external;\n\n function getApprovalRecoveryKeyHash(\n bytes memory recoveryPublicKey,\n string memory saltString\n ) external view returns (bytes32);\n\n function getRecoveryApprovalCountWithTimeValidity(\n bytes32 recoveryPublicKeyHash\n ) external view returns (uint256);\n\n function isRecoveryApproved(\n bytes32 recoveryPublicKeyHash,\n address approver\n ) external view returns (bool);\n\n function getRecoveryNonce() external view returns (uint128);\n\n function getPendingRecovery() external view returns (RecoveryConfig memory);\n}\n" + }, + "contracts/facets/interfaces/IGuardianFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Guardian Facet Interface\n * @dev Interface of guaridna contract that enables addition/removal of guardians from Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IGuardianFacet {\n event GuardianAdditionRequested(\n address indexed guardian,\n uint256 executeAfter\n );\n event GuardianRemovalRequested(\n address indexed guardian,\n uint256 executeAfter\n );\n event GuardianAdditionCancelled(address indexed guardian);\n event GuardianRemovalCancelled(address indexed guardian);\n event GuardianAdded(address indexed guardian);\n event GuardianRemoved(address indexed guardian);\n\n error GuardianFacet__GuardianCannotBeSelf();\n error GuardianFacet__DuplicateGuardian();\n error GuardianFacet__OwnerCannotBeGuardian();\n error GuardianFacet__DuplicateGuardianAddition();\n error GuardianFacet__DuplicateGuardianRemoval();\n error GuardianFacet__UnknownPendingAddition();\n error GuardianFacet__PendingAdditionNotOver();\n error GuardianFacet__UnknownPendingRemoval();\n error GuardianFacet__PendingRemovalNotOver();\n error GuardianFacet__PendingAdditionExpired();\n error GuardianFacet__InvalidAdditionSecurityPeriod();\n error GuardianFacet__InvalidRemovalSecurityPeriod();\n error GuardianFacet__InvalidSecurityWindow();\n error GuardianFacet__NonExistentGuardian();\n error GuardianFacet__AlreadyExists();\n error GuardianFacet__InvalidGuardianAddition();\n error GuardianFacet__InvalidGuardianRemoval();\n error GuardianFacet__ZeroAddressGuardian();\n\n function addGuardian(address guardian) external;\n\n function addGuardians(address[] calldata guardians) external;\n\n function removeGuardian(address guardian) external;\n\n function removeGuardians(address[] calldata guardians) external;\n\n function confirmGuardianAddition(address guardian) external;\n\n function confirmGuardianAdditions(address[] calldata guardian) external;\n\n function confirmGuardianRemoval(address guardian) external;\n\n function confirmGuardianRemovals(address[] calldata guardian) external;\n\n function cancelGuardianAddition(address guardian) external;\n\n function cancelGuardianRemoval(address guardian) external;\n\n function isGuardian(address guardian) external view returns (bool);\n\n function isAdditionPending(address guardian) external view returns (bool);\n\n function isRemovalPending(address guardian) external view returns (bool);\n\n function isGuardianFacetRemovable() external view returns (bool);\n\n function getAdditionSecurityPeriod() external view returns (uint256);\n\n function getRemovalSecurityPeriod() external view returns (uint256);\n\n function getSecurityWindow() external view returns (uint256);\n\n function getGuardians() external view returns (address[] memory);\n\n function majorityOfGuardians() external view returns (uint256);\n\n function guardianCount() external view returns (uint256);\n}\n" + }, + "contracts/facets/interfaces/ILockFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Lock} from \"../../libraries/LibAppStorage.sol\";\n\n/**\n * @title Lock Facet Interface\n * @dev Interface of Lock contract that enables full lock/unlock of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface ILockFacet {\n event Locked(uint64 releaseAfter);\n event Unlocked();\n\n error LockFacet__InvalidRecoveryPeriod();\n error LockFacet__CannotUnlock();\n error LockFacet__InvalidSignature();\n error LockFacet__InvalidApprover();\n\n function lock() external;\n\n function unlock(address approver, bytes calldata signature) external;\n\n function getLockPeriod() external view returns (uint256);\n\n function isLocked() external view returns (bool);\n\n function getUnlockHash() external view returns (bytes32);\n\n function lockNonce() external view returns (uint128);\n\n function getPendingLock() external view returns (Lock memory);\n}\n" + }, + "contracts/facets/interfaces/IMultiSigFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Multi-sig facet Interface\n * @dev Interface of Multi-signature Facet with custom threshold.\n Wallet that adds this facet becomes a multi-sig wallet\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IMultiSigFacet {\n event ThresholdChanged(uint256 threshold);\n event OwnerAdded(address indexed newOwner);\n event OwnerRemoved(address indexed prevOwner);\n event HashApproved(bytes32 hashToApprove, address indexed owner);\n\n error MultiSigFacet__InvalidThreshold();\n error MultisigFacet__InvalidOwnerCount();\n error MultiSigFacet__InvalidRoute();\n error MultiSigFacet__InsufficientSignerLength();\n error MultiSigFacet__InvalidInitData();\n error MultiSigFacet__InvalidOwnerAddress();\n error MultiSigFacet__InvalidOwnerPair();\n error MultiSigFacet__InvalidSignatureLength();\n error MultiSigFacet__InvalidSignatureType();\n error MultiSigFacet__DuplicateOwner();\n error MultiSigFacet__OnlyOwner();\n\n function checkSignatures(\n bytes32 _dataHash,\n bytes calldata _signatures,\n uint256 _threshold\n ) external view returns (uint256);\n\n function splitSignatures(\n bytes calldata _signatures,\n uint256 _nextOffset\n )\n external\n pure\n returns (\n address owner,\n bytes memory signature,\n uint256 signatureType,\n uint256 nextOffset\n );\n\n function approveHash(bytes32 hashToApprove) external;\n\n function addOwner(address newOwner, uint256 threshold) external;\n\n function removeOwner(\n address prevOwner,\n address removedOwner,\n uint256 threshold\n ) external;\n\n function swapOwner(\n address prevOwner,\n address oldOwner,\n address newOwner\n ) external;\n\n function changeThreshold(uint256 _threshold) external;\n\n function isOwner(address owner) external view returns (bool);\n\n function getThreshold() external view returns (uint256);\n\n function getOwners() external view returns (address[] memory);\n}\n" + }, + "contracts/facets/interfaces/IRestrictionsFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Restrictions Facet Interface\n * @dev Interface of Restrictions contract that enables modular restrictions in Barz\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IRestrictionsFacet {\n event RestrictionAdded(address indexed restriction);\n event RestrictionRemoved(address indexed restriction);\n\n error RestrictionsFacet__EmptyRestrictionsList();\n error RestrictionsFacet__RestrictionNotFound();\n error RestrictionsFacet__RestrictionAlreadyExists();\n error RestrictionsFacet__ZeroAddressRestrictions();\n error RestrictionsFacet__ZeroAddressRestrictionsFacet();\n error RestrictionsFacet__RemainingRestrictionsCantBeEmpty();\n\n function initializeRestrictions(\n address[] memory _restrictions\n ) external returns (uint256);\n\n function uninitializeRestrictions() external returns (uint256);\n\n function getRestrictions() external view returns (address[] memory);\n\n function addRestriction(address restriction) external;\n\n function removeRestriction(address restriction) external;\n\n function verifyRestrictions(\n address from,\n address to,\n uint256 value,\n bytes calldata _calldata\n ) external returns (uint256);\n}\n" + }, + "contracts/facets/interfaces/ISignatureMigrationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureMigrationConfig} from \"../../libraries/LibFacetStorage.sol\";\n\n/**\n * @title Signature Migration Facet Interface\n * @dev Interface of Signature Migration contract for migrating user signature scheme to a new scheme user sets\n * Which could include\n * - ECDSA on Secp256K1 Curve\n * - ECDSA on Secp256R1 Curve\n * - BLS, Schnorr, etc\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface ISignatureMigrationFacet {\n event SignatureSchemeMigration(\n address indexed prevVerificationFacet,\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n event SignatureMigrationApproved(\n bytes newPublicKey,\n address indexed newVerificationFacet,\n bytes4[] verificationFuncSelectors,\n address indexed guardian,\n uint128 approvalValidUntil\n );\n event SignatureMigrationApprovalRevoked(\n bytes newPublicKey,\n address indexed newVerificationFacet,\n bytes4[] verificationFuncSelectors,\n address indexed guardian\n );\n event SignatureMigrationExecuted(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors,\n uint128 migrateAfter\n );\n event SignatureMigrationCanceled(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n event SignatureMigrationCancellationApproved(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n\n error SignatureMigrationFacet__SignerUninitializationFailure();\n error SignatureMigrationFacet__SignerInitializationFailure();\n error SignatureMigrationFacet__InvalidRouteWithGuardian();\n error SignatureMigrationFacet__InvalidKeyType();\n error SignatureMigrationFacet__InsufficientApprovers();\n error SignatureMigrationFacet__InvalidApproverSignature();\n error SignatureMigrationFacet__InvalidGuardian();\n error SignatureMigrationFacet__NonExistentApprover();\n error SignatureMigrationFacet__InvalidMigrationPeriod();\n error SignatureMigrationFacet__NonexistentMigration();\n error SignatureMigrationFacet__MigrationPeriodNotOver();\n error SignatureMigrationFacet__InvalidArrayLength();\n error SignatureMigrationFacet__InvalidApprovalValidationPeriod();\n error SignatureMigrationFacet__CannotRevokeUnapproved();\n error SignatureMigrationFacet__LackOfOwnerApproval();\n error SignatureMigrationFacet__OwnerAlreadyApproved();\n error SignatureMigrationFacet__NonExistentVerificationFacet();\n error SignatureMigrationFacet__DuplicateApproval();\n\n function migrateSignatureScheme(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function migrateSignatureSchemeWithGuardian(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors,\n address[] calldata approvers,\n bytes[] calldata signatures\n ) external;\n\n function approveSignatureSchemeMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function revokeSignatureMigrationApproval(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function finalizeSignatureMigration() external;\n\n function approveCancelSignatureMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function cancelSignatureMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function getApprovalMigrationKeyHash(\n bytes memory recoveryPublicKey,\n address newVerificationFacet,\n bytes4[] memory newVerificationFuncSelectors,\n string memory saltString\n ) external view returns (bytes32);\n\n function getMigrationOwnerApprovalWithTimeValidity(\n bytes32 publicKeyHash\n ) external view returns (bool);\n\n function getMigrationApprovalCountWithTimeValidity(\n bytes32 publicKeyHash\n ) external view returns (uint256);\n\n function isMigrationApproved(\n bytes32 migrationPublicKeyHash,\n address approver\n ) external view returns (bool);\n\n function getMigrationNonce() external view returns (uint128);\n\n function isMigrationPending() external view returns (bool);\n\n function getPendingMigration()\n external\n view\n returns (SignatureMigrationConfig memory);\n}\n" + }, + "contracts/facets/interfaces/IVerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {UserOperation} from \"../../aa-4337/interfaces/UserOperation.sol\";\n\n/**\n * @title Verification Facet Interface\n * @dev Implements logic for user ops signature verification\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface IVerificationFacet {\n event SignerInitialized(bytes);\n event SignerUninitialized();\n\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n error VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n error VerificationFacet__InitializationFailure();\n error VerificationFacet__InvalidFacetMapping();\n\n function initializeSigner(bytes memory) external returns (uint256);\n\n function uninitializeSigner() external returns (uint256);\n\n function validateOwnerSignatureSelector() external view returns (bytes4);\n\n function owner() external view returns (bytes memory);\n\n function isValidKeyType(bytes calldata) external view returns (bool);\n\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) external view returns (uint256);\n}\n" + }, + "contracts/facets/LockFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage, Lock} from \"../libraries/LibAppStorage.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibFacetStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {ILockFacet} from \"./interfaces/ILockFacet.sol\";\n\n/**\n * @title Lock Facet\n * @dev Contract that enables full lock/unlock of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract LockFacet is ILockFacet, Modifiers {\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Locks the account for the lock period. Lock period is defined in the security manager and it's customizable\n * This function can only be called when account is unlocked by owner or guardians\n * @dev This method checks the caller and if the account is currently locked and locks the account after fetching the\n * Lock period from the owner.\n */\n function lock() external override onlyGuardianOrOwner onlyWhenUnlocked {\n uint256 unlockTime = block.timestamp + getLockPeriod();\n unchecked {\n ++LibFacetStorage.lockStorage().nonce;\n }\n LibAppStorage.setLock(unlockTime, LockFacet.lock.selector);\n emit Locked(uint64(unlockTime));\n }\n\n /**\n * @notice Locks the account when the account is locked. This function can be called by anyone but must provide the approver address and signature.\n * The approver should be one of the guardians or owner.\n * @dev This method takes the approver address and the signature. After validating the address and the signature, it unlocks the account immediately.\n * Only one of the guardian or owner is required to lock and unlock the account.\n * @param _approver Address of approver approving the unlock of Barz account\n * @param _signature Signature of the approver that signed the msg hash for unlocking the account\n */\n function unlock(\n address _approver,\n bytes calldata _signature\n ) external override onlyWhenLocked {\n if (_approver != address(this) && !LibGuardian.isGuardian(_approver))\n revert LockFacet__InvalidApprover();\n if (\n !SignatureChecker.isValidSignatureNow(\n _approver,\n getUnlockHash(),\n _signature\n )\n ) revert LockFacet__InvalidSignature();\n _unlock();\n }\n\n /**\n * @notice Unlocks the account and increments the lock nonce\n */\n function _unlock() private {\n if (s.locks[INNER_STRUCT].locker != LockFacet.lock.selector)\n revert LockFacet__CannotUnlock();\n unchecked {\n ++LibFacetStorage.lockStorage().nonce;\n }\n LibAppStorage.setLock(0, bytes4(0));\n emit Unlocked();\n }\n\n /**\n * @notice Returns the lock period of current Barz account. Lock period information is held by Security Manager\n * @return lockPeriod Uint value of lock period in seconds\n */\n function getLockPeriod() public view override returns (uint256 lockPeriod) {\n lockPeriod = securityManager.lockPeriodOf(address(this));\n if (lockPeriod == 0) revert LockFacet__InvalidRecoveryPeriod();\n }\n\n /**\n * @notice Returns if the account is locked or not\n * @dev This method fetches the current block timestamp and compares that with release time.\n * After checking the timestamp and release time, it returns if the account is still locked or not.\n * @return isLocked_ Uint value of lock period in seconds\n */\n function isLocked() public view override returns (bool isLocked_) {\n isLocked_ = uint64(block.timestamp) < s.locks[INNER_STRUCT].release;\n }\n\n /**\n * @notice Calculates the unlock hash and returns the unlock hash safe from signature reply attack\n * @dev This method calculates the unlock hash with EIP-191 prefix, wallet address, chainID, and nonce\n * It packs the result and packs them and hashes it.\n * @return unlockHash Bytes32 unlock hash\n */\n function getUnlockHash() public view override returns (bytes32 unlockHash) {\n unlockHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n \"Unlock\",\n address(this),\n block.chainid,\n lockNonce()\n )\n )\n )\n );\n }\n\n /**\n * @notice Returns lock nonce of account. Reads nonce from lock storage within facet storage\n * @return lockNonce_ Uint128 value of lock nonce. This is incremented whenever the account is lock/unlocked\n */\n function lockNonce() public view override returns (uint128 lockNonce_) {\n lockNonce_ = LibFacetStorage.lockStorage().nonce;\n }\n\n /**\n * @notice Returns the overall information of current lock\n * @return pendingLock Struct value including all information of pending lock\n */\n function getPendingLock()\n public\n view\n override\n returns (Lock memory pendingLock)\n {\n pendingLock = s.locks[INNER_STRUCT];\n }\n}\n" + }, + "contracts/facets/Modifiers.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\n\n/**\n * @title Modifiers\n * @dev Responsible for providing modifiers/util functions to Facet contracts\n * @author David Yongjun Kim (@Powerstream3604)\n */\nabstract contract Modifiers is BarzStorage {\n uint8 constant INNER_STRUCT = 0;\n\n error CallerNotGuardian();\n error CallerNotGuardianOrOwner();\n error DuplicateApprover();\n error ZeroApproverLength();\n error UnregisteredFacetAndSelectors();\n\n /**\n * @notice Modifier to only allow guardian to make a call, reverts if any other entity is the caller\n */\n modifier onlyGuardian() {\n if (!LibGuardian.isGuardian(msg.sender)) revert CallerNotGuardian();\n _;\n }\n\n /**\n * @notice Modifier to only allow guardian or owner to make a call, reverts if any other entity is the caller\n */\n modifier onlyGuardianOrOwner() {\n if (!LibGuardian.isGuardian(msg.sender) && address(this) != msg.sender)\n revert CallerNotGuardianOrOwner();\n _;\n }\n\n /**\n * @notice Checks if the approver address is the array is unique with no duplicate\n * @dev This method loops through the array and checks if a duplicate address exists, it reverts if duplicate address exists\n * @param approvers Array of address\n */\n function _checkApprover(\n address[] memory approvers\n ) internal pure returns (bool) {\n uint256 approverLength = approvers.length;\n if (0 == approverLength) revert ZeroApproverLength();\n for (uint256 i; i < approverLength - 1; ) {\n for (uint256 j = i + 1; j < approverLength; ) {\n if (approvers[i] == approvers[j]) {\n revert DuplicateApprover(); // Found a duplicate\n }\n unchecked {\n ++j;\n }\n }\n unchecked {\n ++i;\n }\n }\n return false; // No duplicates found\n }\n\n /**\n * @notice Checks if the facet getting added or replaced is registered to facet registry\n * @dev This method loops through the cut and checks if the facet getting added/replaced is registered to facet registry\n * @param _diamondCut Array of FacetCut, data for diamondCut defined in EIP-2535\n */\n function _checkFacetCutValidity(\n IDiamondCut.FacetCut[] memory _diamondCut\n ) internal view {\n uint256 diamondCutLength = _diamondCut.length;\n for (uint256 i; i < diamondCutLength; ) {\n if (\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Add ||\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Replace\n ) {\n if (\n !s.facetRegistry.areFacetFunctionSelectorsRegistered(\n _diamondCut[i].facetAddress,\n _diamondCut[i].functionSelectors\n )\n ) revert UnregisteredFacetAndSelectors();\n }\n unchecked {\n ++i;\n }\n }\n }\n}\n" + }, + "contracts/facets/RestrictionsFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ReentrancyGuard} from \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, RestrictionsStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {IRestriction} from \"../restrictions/IRestriction.sol\";\nimport {IRestrictionsFacet} from \"./interfaces/IRestrictionsFacet.sol\";\n\n/**\n * @title Restrictions facet\n * @dev Responsible for storing and verifying different kinds of restrictions, for example:\n * - Whitelist / Blacklist\n * - Daily limits\n * - Trading time restrictions\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract RestrictionsFacet is IRestrictionsFacet, ReentrancyGuard {\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceRestrictionsInitialize();\n }\n\n /**\n * @notice Intialize restrictions of Barz. Restrictions facet call restriction contracts for restriction validation\n * before each call\n * @param _restrictions The initial array of restrictions.\n * @return initSuccess Int value showing if the initialization of restriction is successful\n */\n function initializeRestrictions(\n address[] calldata _restrictions\n ) public override returns (uint256 initSuccess) {\n LibDiamond.enforceIsSelf();\n LibAppStorage.enforceRestrictionsInitialize();\n\n if (_restrictions.length == 0) {\n // You can't initialize RestrictionsFacet with an empty list of restrictions\n revert RestrictionsFacet__EmptyRestrictionsList();\n }\n for (uint256 i; i < _restrictions.length; ) {\n if (_restrictions[i] == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictions();\n unchecked {\n ++i;\n }\n }\n\n LibFacetStorage.restrictionsStorage().restrictions = _restrictions;\n _updateRestrictionsMap(_restrictions, true);\n initSuccess = 1;\n }\n\n /**\n * @notice Unitialize restrictions of Barz\n * @return uninitSuccess Int value showing if the initialization of restriction is successful\n */\n function uninitializeRestrictions()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibDiamond.enforceIsSelf();\n LibAppStorage.setRestrictionsUninitialized();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n _updateRestrictionsMap(restrictionsStorage.restrictions, false);\n restrictionsStorage.restrictions = new address[](0);\n uninitSuccess = 1;\n }\n\n /**\n * @notice Returns the list of Restrictions contract address\n * @return restrictions Addresses of IRestriction which are currently active\n */\n function getRestrictions()\n public\n view\n override\n returns (address[] memory restrictions)\n {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n restrictions = restrictionsStorage.restrictions;\n }\n\n /**\n * @notice Adds restrictions to Barz with validation on the restriction contract address.\n * This method is only callable by the owner(self).\n * @param _restriction The address of the restriction to be added.\n */\n function addRestriction(address _restriction) external override {\n LibDiamond.enforceIsSelf();\n if (LibDiamond.restrictionsFacet() == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictionsFacet();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n if (_restriction == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictions();\n if (restrictionsStorage.exists[_restriction])\n revert RestrictionsFacet__RestrictionAlreadyExists();\n\n restrictionsStorage.restrictions.push(_restriction);\n restrictionsStorage.exists[_restriction] = true;\n\n emit RestrictionAdded(_restriction);\n }\n\n /**\n * @notice Remove restrictions from Barz if it existed. This method is only callable by the owner(self).\n * @param _restriction The address of the restriction to be removed.\n */\n function removeRestriction(address _restriction) external override {\n LibDiamond.enforceIsSelf();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n if (!restrictionsStorage.exists[_restriction])\n revert RestrictionsFacet__RestrictionNotFound();\n\n address[] storage restrictions = restrictionsStorage.restrictions;\n\n uint256 indexToDelete = restrictions.length;\n uint256 restrictionsLen = restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n if (restrictions[i] == _restriction) {\n indexToDelete = i;\n break;\n }\n unchecked {\n ++i;\n }\n }\n\n if (indexToDelete == 0 && restrictionsLen == 1) {\n revert RestrictionsFacet__RemainingRestrictionsCantBeEmpty();\n } else if (indexToDelete == restrictionsLen) {\n revert RestrictionsFacet__RestrictionNotFound();\n } else {\n restrictions[indexToDelete] = restrictions[restrictionsLen - 1];\n restrictions.pop();\n }\n\n restrictionsStorage.exists[_restriction] = false;\n emit RestrictionRemoved(_restriction);\n }\n\n /**\n * @notice Sets the restrictions address value mapping to true or false when adding/removing restriction contracts\n * @param _restrictions List of restriction contracts address\n * @param _newValue Bool value to flag to the list of restrictions contracts\n */\n function _updateRestrictionsMap(\n address[] memory _restrictions,\n bool _newValue\n ) internal {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n uint restrictionsLen = _restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n restrictionsStorage.exists[_restrictions[i]] = _newValue;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @dev Iterates over all restrictions and verifies each of them with the transaction parameters.\n * @param _from The address of the sender, that will be signing the transaction.\n * @param _to The receiving address.\n * @param _value Amount of ETH to transfer from sender to recipient.\n * @param _calldata Optional field to include arbitrary data.\n * @return 0 if all the checks passed, 1 otherwise.\n */\n function verifyRestrictions(\n address _from,\n address _to,\n uint256 _value,\n bytes calldata _calldata\n ) external nonReentrant returns (uint256) {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n uint restrictionsLen = restrictionsStorage.restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n IRestriction restriction = IRestriction(\n restrictionsStorage.restrictions[i]\n );\n bool checkPassed = restriction.check(_from, _to, _value, _calldata);\n if (!checkPassed) {\n return 1;\n }\n unchecked {\n ++i;\n }\n }\n\n return 0;\n }\n}\n" + }, + "contracts/facets/SignatureMigrationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, SignatureMigrationStorage, SignatureMigrationConfig, SignatureMigrationApprovalConfig, ApprovalConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IDiamondCut} from \"./base/interfaces/IDiamondCut.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {ISignatureMigrationFacet} from \"./interfaces/ISignatureMigrationFacet.sol\";\n\n/**\n * @title Signature Migration Facet\n * @dev Responsible for migrating user signature scheme to a new scheme user sets\n * Which could include\n * - ECDSA on Secp256K1 Curve\n * - ECDSA on Secp256R1 Curve\n * - BLS, Schnorr, etc\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract SignatureMigrationFacet is ISignatureMigrationFacet, Modifiers {\n bytes constant UNINIT_CALL =\n abi.encodeWithSignature(\"uninitializeSigner()\");\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This modifier verifies if the public key format matches with the new verification facet\n * @param _publicKey Bytes of public key to be validated for the new verification facet\n * @param _newVerificationFacet Address of new verification facet\n */\n modifier validateKeyType(\n bytes memory _publicKey,\n address _newVerificationFacet\n ) {\n if (\n !IVerificationFacet(_newVerificationFacet).isValidKeyType(\n _publicKey\n )\n ) revert SignatureMigrationFacet__InvalidKeyType();\n _;\n }\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n // IMPORTANT NOTE: In the client side when they call this function, the func selectors should be sorted in ascending order\n // to prevent different hash with same items in the array\n /**\n * @notice Moves the state of migration to a pending state. When pending state is over after pending period time,\n * Migration can be finalized. This function can only be called by self and when the account is unlocked.\n * @dev This method checks if the caller is self and if guardians exists. It migrates signature request to a pending state\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function migrateSignatureScheme(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n public\n override\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n // Only self contract can call this function\n LibDiamond.enforceIsSelf();\n // Should revert if guardian exist\n if (0 != LibGuardian.guardianCount())\n revert SignatureMigrationFacet__InvalidRouteWithGuardian();\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n // NOTE: Migration requires a pending period & confirmation from owner to prevent a\n // single call changing the ownership of the wallet\n /**\n * @notice Migrate signature scheme when guardians exists. Verifies the signature of guardians and moves migration to pending state.\n * Which can then be finalized when pending period is over. Owner's approval is mandatory for migration to happen\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _approvers List of approvers. This could include owner\n */\n function migrateSignatureSchemeWithGuardian(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n )\n public\n override\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n // Should revert if does not guardian exist\n if (0 == LibGuardian.guardianCount())\n revert SignatureMigrationFacet__InvalidRouteWithGuardian();\n if (_approvers.length != _signatures.length)\n revert SignatureMigrationFacet__InvalidArrayLength();\n\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(migrationPublicKeyHash, _approvers);\n\n bool onChainOwnerApproval = getMigrationOwnerApprovalWithTimeValidity(\n migrationPublicKeyHash\n );\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n\n if (\n _approvers.length +\n getMigrationApprovalCountWithTimeValidity(\n migrationPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert SignatureMigrationFacet__InsufficientApprovers();\n {\n // To prevent Stack too deep\n bool ownerApproved;\n for (uint256 i; i < _approvers.length; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n address(this) != _approvers[i]\n ) revert SignatureMigrationFacet__InvalidGuardian();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert SignatureMigrationFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n migrationPublicKeyHash,\n _signatures[i]\n )\n ) revert SignatureMigrationFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n\n if (!ownerApproved && !onChainOwnerApproval)\n revert SignatureMigrationFacet__LackOfOwnerApproval();\n }\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Internal function that moves signature mgiration to a pending state.\n * @dev This method increments migration nonce and sets the migration in the migration config. Emits events for migration execution\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _migrateSignatureScheme(\n address _newVerificationFacet,\n bytes memory _newPublicKey,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal {\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n unchecked {\n ++ms.nonce;\n }\n uint64 migrateAfter = uint64(block.timestamp + getMigrationPeriod());\n\n ms.migrationConfigs[INNER_STRUCT] = SignatureMigrationConfig(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n migrateAfter\n );\n\n emit SignatureMigrationExecuted(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors,\n migrateAfter\n );\n }\n\n /**\n * @notice Approves signature scheme migration on-chain. This can be called by owner or guardian only when the account is unlocked.\n * When the threshold of the migration approval passed and owner approval is granted, it automatically moves migration to a pending state\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function approveSignatureSchemeMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n public\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit SignatureMigrationApproved(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n msg.sender,\n approvalValidUntil\n );\n if (\n getMigrationApprovalCountWithTimeValidity(migrationPublicKeyHash) >=\n LibGuardian.majorityOfGuardians() &&\n getMigrationOwnerApprovalWithTimeValidity(migrationPublicKeyHash)\n )\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Revokes the approval of signature migration done on-chain. Emits revoke event when revoked.\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function revokeSignatureMigrationApproval(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n external\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n if (!isMigrationApproved(migrationPublicKeyHash, msg.sender))\n revert SignatureMigrationFacet__CannotRevokeUnapproved();\n\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(false, 0);\n emit SignatureMigrationApprovalRevoked(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n msg.sender\n );\n }\n\n /**\n * @notice Finalizes the pending signature scheme migration. This function can only be called by owner.\n * It removes the facets of the previous verification facet and adds the new verification facet.\n * After finalizing migration, it emits migration event which shows the change of the verification facet\n */\n function finalizeSignatureMigration() external override {\n // NOTE: Only owner can call this function\n LibDiamond.enforceIsSelf();\n\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n\n if (!isMigrationPending())\n revert SignatureMigrationFacet__NonexistentMigration();\n\n if (\n uint64(block.timestamp) <=\n ms.migrationConfigs[INNER_STRUCT].migrateAfter\n ) revert SignatureMigrationFacet__MigrationPeriodNotOver();\n address newVerificationFacet = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationVerificationFacet;\n bytes4[] memory newVerificationFuncSelectors = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationSelectors;\n bytes memory newPublicKey = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationPublicKey;\n\n address prevVerificationFacet = LibLoupe.facetAddress(\n s.validateOwnerSignatureSelector\n );\n if (prevVerificationFacet == address(0))\n revert SignatureMigrationFacet__NonExistentVerificationFacet();\n\n IDiamondCut.FacetCut[] memory UninitCut;\n IDiamondCut.FacetCut[] memory InitCut;\n {\n bytes4[] memory prevVerificationFuncSelectors = LibLoupe\n .facetFunctionSelectors(prevVerificationFacet);\n\n UninitCut = new IDiamondCut.FacetCut[](1);\n InitCut = new IDiamondCut.FacetCut[](1);\n UninitCut[0] = IDiamondCut.FacetCut({\n facetAddress: address(0),\n action: IDiamondCut.FacetCutAction.Remove,\n functionSelectors: prevVerificationFuncSelectors\n });\n InitCut[0] = IDiamondCut.FacetCut({\n facetAddress: newVerificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: newVerificationFuncSelectors\n });\n {\n IDiamondCut.FacetCut[]\n memory facetCuts = new IDiamondCut.FacetCut[](2);\n facetCuts[0] = UninitCut[0];\n facetCuts[1] = InitCut[0];\n _checkFacetCutValidity(facetCuts);\n }\n LibAppStorage.initiateSignerMigration();\n address verificationFacet = address(\n bytes20(\n LibDiamond.diamondStorage().facets[\n s.validateOwnerSignatureSelector\n ]\n )\n );\n\n (bool uninitSuccess, bytes memory uninitResult) = verificationFacet\n .delegatecall(UNINIT_CALL);\n if (!uninitSuccess || uint256(bytes32(uninitResult)) != 1)\n revert SignatureMigrationFacet__SignerUninitializationFailure();\n LibAppStorage.finalizeSignerMigration();\n\n LibDiamond.diamondCut(UninitCut, address(0), \"\");\n }\n {\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n newPublicKey\n );\n\n // Every Verification Facet should comply with initializeSigner(bytes)\n // to be compatible with the Barz contract(for initialization)\n LibDiamond.diamondCut(InitCut, address(0), \"\");\n (bool initSuccess, bytes memory initResult) = newVerificationFacet\n .delegatecall(initCall);\n if (!initSuccess || uint256(bytes32(initResult)) != 1)\n revert SignatureMigrationFacet__SignerInitializationFailure();\n\n emit SignatureSchemeMigration(\n prevVerificationFacet,\n newVerificationFacet,\n newPublicKey,\n newVerificationFuncSelectors\n );\n }\n }\n\n /**\n * @notice Approve cancellation of signature migration. If cancellation approval passes guardian threshold with owner approval\n * it automatically cancels the migration.\n * @dev This method checks if the caller is one of guardian or owner and sets true for the cancellation hash in the approval config.\n * It internally calls _cancelSignatureMigration for canceling the migration\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function approveCancelSignatureMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n external\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"CancelSignatureMigration\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit SignatureMigrationCancellationApproved(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n if (\n getMigrationApprovalCountWithTimeValidity(migrationPublicKeyHash) >=\n LibGuardian.majorityOfGuardians() &&\n getMigrationOwnerApprovalWithTimeValidity(migrationPublicKeyHash)\n )\n _cancelSignatureMigration(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Verifies the signature of guardians/owner and cancels the signature migration.\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _approvers List of approvers. This could include owner\n */\n function cancelSignatureMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n )\n external\n override\n validateKeyType(_newPublicKey, _newVerificationFacet)\n onlyWhenUnlocked\n {\n if (_approvers.length != _signatures.length)\n revert SignatureMigrationFacet__InvalidArrayLength();\n\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"CancelSignatureMigration\"\n );\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(migrationPublicKeyHash, _approvers);\n\n bool onChainOwnerApproval = getMigrationOwnerApprovalWithTimeValidity(\n migrationPublicKeyHash\n );\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n if (\n _approvers.length +\n getMigrationApprovalCountWithTimeValidity(\n migrationPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert SignatureMigrationFacet__InsufficientApprovers();\n {\n // To prevent stack too deep\n bool ownerApproved;\n for (uint256 i; i < _approvers.length; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n address(this) != _approvers[i]\n ) revert SignatureMigrationFacet__NonExistentApprover();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert SignatureMigrationFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n migrationPublicKeyHash,\n _signatures[i]\n )\n ) revert SignatureMigrationFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n if (!ownerApproved && !onChainOwnerApproval)\n revert SignatureMigrationFacet__LackOfOwnerApproval();\n }\n _cancelSignatureMigration(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Internal function that cancels signature migration.\n * @dev This method increments migration nonce and deletes the migration from the migration config. Emits events for migration cancellation\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _cancelSignatureMigration(\n address _newVerificationFacet,\n bytes memory _newPublicKey,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal {\n if (!isMigrationPending())\n revert SignatureMigrationFacet__NonexistentMigration();\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n unchecked {\n ++ms.nonce;\n }\n delete ms.migrationConfigs[INNER_STRUCT];\n emit SignatureMigrationCanceled(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Checks if the facets to be added from new verification facet is registered to facet registry\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _checkMigrationCutValidity(\n address _newVerificationFacet,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal view {\n IDiamondCut.FacetCut[] memory facetCuts = new IDiamondCut.FacetCut[](1);\n facetCuts[0] = IDiamondCut.FacetCut({\n facetAddress: _newVerificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: _newVerificationFuncSelectors\n });\n _checkFacetCutValidity(facetCuts);\n }\n\n /**\n * @notice Returns if the migration is pending of not\n * @dev This method fetches the migration storage and checks if the migrate after is above 0 value\n * @return isPending Bool value that shows if the migration is pending\n */\n function isMigrationPending()\n public\n view\n override\n returns (bool isPending)\n {\n SignatureMigrationStorage storage rs = LibFacetStorage\n .migrationStorage();\n isPending = rs.migrationConfigs[INNER_STRUCT].migrateAfter > 0;\n }\n\n /**\n * @notice Returns the migration hash. This function ensures that this hash is safe from replay attack by including\n * public key, verification facet, function selectors, salt, address, chainId, and nonce.\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _saltString Salt value for generating the migration hash\n * @return migrationKeyHash Bytes32 string of the migration key hash\n */\n function getApprovalMigrationKeyHash(\n bytes memory _newPublicKey,\n address _newVerificationFacet,\n bytes4[] memory _newVerificationFuncSelectors,\n string memory _saltString\n ) public view override returns (bytes32 migrationKeyHash) {\n migrationKeyHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n _newPublicKey,\n _newVerificationFacet,\n keccak256(abi.encode(_newVerificationFuncSelectors)),\n _saltString,\n address(this),\n block.chainid,\n LibFacetStorage.migrationStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Checks if the owner approved the hash for migration\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @return isApprovedByOwner Bool value of showing if the owner approved it or not\n */\n function getMigrationOwnerApprovalWithTimeValidity(\n bytes32 _migrationPublicKeyHash\n ) public view override returns (bool isApprovedByOwner) {\n isApprovedByOwner = isMigrationApproved(\n _migrationPublicKeyHash,\n address(this)\n );\n }\n\n /**\n * @notice Checks how many of the guardians approved the migration hash\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @return approvalCount Number of approvals\n */\n function getMigrationApprovalCountWithTimeValidity(\n bytes32 _migrationPublicKeyHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardiansLength = guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n if (isMigrationApproved(_migrationPublicKeyHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n return approvalCount;\n }\n\n /**\n * @notice Checks if the migration is approved by the given approver\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @param _approver Address of approver\n * @return isApproved Bool value if migration hash is approved\n */\n function isMigrationApproved(\n bytes32 _migrationPublicKeyHash,\n address _approver\n ) public view override returns (bool isApproved) {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n isApproved = (ms\n .isMigrationApproved[_migrationPublicKeyHash][_approver].isApproved &&\n block.timestamp <\n ms\n .isMigrationApproved[_migrationPublicKeyHash][_approver]\n .validUntil);\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _migrationPublicKeyHash Hash of migration information\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _migrationPublicKeyHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isMigrationApproved(_migrationPublicKeyHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert SignatureMigrationFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the migration period of this wallet\n * @dev This method fetches the migration period from the security manager\n * @return migrationPeriod Migration period of Barz contract fetched from security manager\n */\n function getMigrationPeriod()\n internal\n view\n returns (uint128 migrationPeriod)\n {\n migrationPeriod = securityManager.migrationPeriodOf(address(this));\n if (migrationPeriod == 0)\n revert SignatureMigrationFacet__InvalidMigrationPeriod();\n }\n\n /**\n * @notice Returns the validation period of this wallet\n * @dev This method fetches the validation period from the security manager\n * @return approvalValidationPeriod Validation period of Barz contract fetched from security manager\n */\n function getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod == 0)\n revert SignatureMigrationFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the migration nonce of this wallet\n * @dev This method fetches the nonce from migration storage\n * @return migrationNonce Nonce of migration to protect from reply attacks\n */\n function getMigrationNonce()\n public\n view\n override\n returns (uint128 migrationNonce)\n {\n migrationNonce = LibFacetStorage.migrationStorage().nonce;\n }\n\n /**\n * @notice Returns the migration configuration of this wallet\n * @dev This method fetches the migration config from the migration storage\n * @return pendingMigrationConfig Migration config currently pending for signature migration\n */\n function getPendingMigration()\n external\n view\n override\n returns (SignatureMigrationConfig memory pendingMigrationConfig)\n {\n pendingMigrationConfig = LibFacetStorage\n .migrationStorage()\n .migrationConfigs[INNER_STRUCT];\n }\n}\n" + }, + "contracts/facets/TokenReceiverFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {IERC1155Receiver} from \"../interfaces/ERC/IERC1155Receiver.sol\";\nimport {IERC677Receiver} from \"../interfaces/ERC/IERC677Receiver.sol\";\n\n/**\n * @title TokenReceiver Facet\n * @dev Contract that enables receiving ERC721/ERC1155/ERC777/ERC677 Tokens with safe transfer\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract TokenReceiverFacet is\n IERC721Receiver,\n IERC1155Receiver,\n IERC777Recipient,\n IERC677Receiver\n{\n /**\n * @notice Handles ERC721 Token callback.\n * return Standardized onERC721Received return value.\n */\n function onERC721Received(\n address,\n address,\n uint256,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC721Receiver.onERC721Received.selector;\n }\n\n /**\n * @notice Handles ERC1155 Token callback.\n * return Standardized onERC1155Received return value.\n */\n function onERC1155Received(\n address,\n address,\n uint256,\n uint256,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC1155Receiver.onERC1155Received.selector;\n }\n\n /**\n * @notice Handles ERC1155 Token batch callback.\n * return Standardized onERC1155BatchReceived return value.\n */\n function onERC1155BatchReceived(\n address,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC1155Receiver.onERC1155BatchReceived.selector;\n }\n\n /**\n * @notice Handles ERC777 Token callback.\n * Does not return value, empty implementation.\n */\n function tokensReceived(\n address,\n address,\n address,\n uint256,\n bytes calldata,\n bytes calldata\n ) external pure override {}\n\n /**\n * @notice Handles ERC677 Token callback.\n * return true.\n */\n function onTokenTransfer(\n address,\n uint256,\n bytes calldata\n ) external pure override returns (bool) {\n return true;\n }\n}\n" + }, + "contracts/facets/verification/MultiSigFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {UserOperation} from \"../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../../libraries/LibLoupe.sol\";\nimport {LibAppStorage} from \"../../libraries/LibAppStorage.sol\";\nimport {LibMultiSigStorage, MultiSigStorage} from \"../../libraries/LibMultiSigStorage.sol\";\nimport {IERC1271} from \"../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../interfaces/IVerificationFacet.sol\";\nimport {IMultiSigFacet} from \"../interfaces/IMultiSigFacet.sol\";\n\n/**\n * @title Multi-sig facet\n * @dev Multi-signature Facet with custom threshold.\n * Wallet that adds this facet becomes a multi-sig wallet.\n * Reference signature_format.md documentation for Multi-sig facet details\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract MultiSigFacet is IMultiSigFacet, IVerificationFacet, IERC1271 {\n using ECDSA for bytes32;\n\n address public immutable self;\n\n address internal constant SENTINEL_OWNERS = address(0x1);\n uint256 internal constant ADDRESS = 20;\n uint256 internal constant SIG_TYPE = 1;\n uint256 internal constant SIG_LEN = 4;\n uint256 internal constant THRESHOLD = 4;\n uint256 internal constant INVALID_SIG = 1;\n uint256 internal constant VALID_SIG = 0;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in Multisig Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the right format and initializes signer storage in k1 storage.\n * @param _owners Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _owners\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n\n if (!isValidKeyType(_owners)) revert MultiSigFacet__InvalidInitData();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n uint256 threshold = uint256(uint32(bytes4(_owners)));\n uint256 ownerCount = (_owners.length - THRESHOLD) / ADDRESS;\n\n if (threshold == 0) revert MultiSigFacet__InvalidThreshold();\n if (ownerCount == 0) revert MultisigFacet__InvalidOwnerCount();\n\n address currentOwner = SENTINEL_OWNERS;\n uint256 ptr = THRESHOLD;\n address owner_;\n for (uint256 i; i < ownerCount; ) {\n owner_ = address(bytes20(_owners[ptr:ptr + ADDRESS]));\n ptr += ADDRESS;\n if (\n owner_ == address(0) ||\n owner_ == SENTINEL_OWNERS ||\n owner_ == address(this) ||\n owner_ == currentOwner\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[owner_] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n\n ms.owners[currentOwner] = owner_;\n currentOwner = owner_;\n\n unchecked {\n ++i;\n }\n }\n ms.owners[currentOwner] = SENTINEL_OWNERS;\n ms.ownerCount = ownerCount;\n ms.threshold = threshold;\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_owners);\n }\n\n /**\n * @notice Uninitialize signer in K1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n ++ms.counter;\n address[] memory ownerlist = getOwners();\n uint256 ownerlistLength = ownerlist.length;\n for (uint256 i; i < ownerlistLength; ) {\n ms.owners[ownerlist[i]] = address(0);\n unchecked {\n ++i;\n }\n }\n ms.owners[SENTINEL_OWNERS] = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls checkSignatures with\n * user operation hash and signature together with the threshold.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n // Data 1 is invalid, Data 0 is valid\n validationData = checkSignatures(\n userOpHash,\n userOp.signature,\n LibMultiSigStorage.multisigStorage().threshold\n );\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n return this.validateOwnerSignature.selector;\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n uint totalLength = ms.ownerCount * ADDRESS;\n bytes memory result = new bytes(totalLength);\n\n // populate return array\n uint256 index;\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n while (currentOwner != SENTINEL_OWNERS) {\n assembly {\n mstore(\n add(result, add(32, mul(index, ADDRESS))),\n shl(96, currentOwner)\n )\n }\n currentOwner = ms.owners[currentOwner];\n index++;\n }\n\n return result;\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key should comply with the format in the signature_format.md doc\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n uint256 publicKeyLength = _publicKey.length;\n if (\n publicKeyLength < ADDRESS + THRESHOLD ||\n (publicKeyLength - THRESHOLD) % ADDRESS != 0\n ) return false;\n\n uint256 threshold = uint256(uint32(bytes4(_publicKey)));\n uint256 ownerCount = (publicKeyLength - THRESHOLD) / ADDRESS;\n\n isValid = !(ownerCount < threshold || threshold == 0);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes calldata _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (checkSignatures(\n _hash,\n _signature,\n LibMultiSigStorage.multisigStorage().threshold\n ) == VALID_SIG)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n\n /**\n * @notice Validates the format of the signature and verifies if the signature is signed by the expected key.\n * Reference signature_format.md doc for details about signature format and signature types\n * @param _dataHash Bytes value of data hash signed by the owners\n * @param _signatures Bytes value of signature which should comply with signature format\n * @param _threshold Uint256 value of current Multi-sig Barz's threshold\n */\n function checkSignatures(\n bytes32 _dataHash,\n bytes calldata _signatures,\n uint256 _threshold\n ) public view returns (uint256) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n address lastOwner = address(0);\n address currentOwner;\n bytes memory signature;\n uint256 signatureType;\n uint256 nextOffset;\n uint256 i;\n for (i; i < _threshold; ) {\n (\n currentOwner,\n signature,\n signatureType,\n nextOffset\n ) = splitSignatures(_signatures, nextOffset);\n if (nextOffset == 0 && i + 1 < _threshold) return INVALID_SIG;\n if (signatureType == 1) {\n // If signatureType is 1 then it is default dataHash signed.\n // This also includes the contract signature\n if (\n !SignatureChecker.isValidSignatureNow(\n currentOwner,\n _dataHash,\n signature\n )\n ) return INVALID_SIG;\n } else if (signatureType == 2) {\n // If signatureType is 2 then it is an approved hash\n if (ms.approvedHashes[ms.counter][currentOwner][_dataHash] == 0)\n return INVALID_SIG;\n } else if (signatureType == 3) {\n // If signatureType is 3 then it is a signed message hash\n // This also includes the contract signature\n bytes32 msgHash = _dataHash.toEthSignedMessageHash();\n if (\n !SignatureChecker.isValidSignatureNow(\n currentOwner,\n msgHash,\n signature\n )\n ) return INVALID_SIG;\n } else revert MultiSigFacet__InvalidRoute();\n if (\n currentOwner <= lastOwner ||\n ms.owners[currentOwner] == address(0) ||\n currentOwner == SENTINEL_OWNERS\n ) return INVALID_SIG;\n lastOwner = currentOwner;\n\n unchecked {\n ++i;\n }\n }\n return VALID_SIG;\n }\n\n /**\n * @notice Split signatures into each individual signatures. Should comply with signature format to be split\n * @param _signatures Bytes value of signature\n * @param _nextOffset Uint256 value of next offset to start splitting the signature\n */\n function splitSignatures(\n bytes calldata _signatures,\n uint256 _nextOffset\n )\n public\n pure\n returns (\n address owner_,\n bytes memory signature,\n uint256 signatureType,\n uint256 nextOffset\n )\n {\n uint256 signaturesLength = _signatures.length;\n\n if (signaturesLength <= _nextOffset + ADDRESS + SIG_LEN)\n revert MultiSigFacet__InsufficientSignerLength();\n\n owner_ = address(\n bytes20(_signatures[_nextOffset:_nextOffset + ADDRESS])\n );\n\n signatureType = uint256(\n uint8(\n bytes1(\n _signatures[_nextOffset + ADDRESS:_nextOffset +\n ADDRESS +\n SIG_TYPE]\n )\n )\n );\n\n if (signatureType > 3 || signatureType == 0)\n revert MultiSigFacet__InvalidSignatureType();\n uint256 offSet = _nextOffset + ADDRESS + SIG_TYPE;\n uint256 siglen = uint256(\n uint32(bytes4(_signatures[offSet:offSet + SIG_LEN]))\n );\n if (offSet + siglen > signaturesLength)\n revert MultiSigFacet__InvalidSignatureLength();\n\n offSet += SIG_LEN;\n if (offSet + siglen == signaturesLength) nextOffset = 0;\n else nextOffset = offSet + siglen;\n\n signature = _signatures[offSet:offSet + siglen];\n }\n\n /**\n * @notice Approves the hash of userOperation on-chain. This can only be called by owners.\n * @param _hashToApprove Bytes value of UserOperation hash to approve\n */\n function approveHash(bytes32 _hashToApprove) external {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (ms.owners[msg.sender] == address(0))\n revert MultiSigFacet__OnlyOwner();\n\n ms.approvedHashes[ms.counter][msg.sender][_hashToApprove] = 1;\n emit HashApproved(_hashToApprove, msg.sender);\n }\n\n /**\n * @notice Add owner to Barz. Update thresold if threshold is given different from current threshold\n * @dev This can only be done via a Self call.\n * @param _newOwner Address of new owner to be added\n * @param _threshold Uint256 value of threshold\n */\n function addOwner(address _newOwner, uint256 _threshold) external {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (\n _newOwner == address(0) ||\n _newOwner == SENTINEL_OWNERS ||\n _newOwner == address(this)\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_newOwner] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n\n ms.owners[_newOwner] = ms.owners[SENTINEL_OWNERS];\n ms.owners[SENTINEL_OWNERS] = _newOwner;\n ++ms.ownerCount;\n emit OwnerAdded(_newOwner);\n\n if (ms.threshold != _threshold) changeThreshold(_threshold);\n }\n\n /**\n * @notice Remove owner from Barz. Update thresold if threshold is given different from current threshold\n * @dev This can only be done via a Self call.\n * @param _prevOwner Address of owner located right behind the removed owner address in the linked list\n * @param _removedOwner Address of owner to be removed\n * @param _threshold Uint256 value of threshold\n */\n function removeOwner(\n address _prevOwner,\n address _removedOwner,\n uint256 _threshold\n ) external {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (ms.ownerCount - 1 < _threshold)\n revert MultiSigFacet__InvalidThreshold();\n if (_removedOwner == address(0) || _removedOwner == SENTINEL_OWNERS)\n revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_prevOwner] != _removedOwner)\n revert MultiSigFacet__InvalidOwnerPair();\n\n ms.owners[_prevOwner] = ms.owners[_removedOwner];\n ms.owners[_removedOwner] = address(0);\n --ms.ownerCount;\n emit OwnerRemoved(_removedOwner);\n\n if (ms.threshold != _threshold) changeThreshold(_threshold);\n }\n\n /**\n * @notice Swap owner in Barz.\n * @dev This can only be done via a Self call.\n * @param _prevOwner Address of owner located right behind the removed owner address in the linked list\n * @param _oldOwner Address of owner to be removed\n * @param _newOwner Address of owner to be added\n */\n function swapOwner(\n address _prevOwner,\n address _oldOwner,\n address _newOwner\n ) public {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (\n _newOwner == address(0) ||\n _newOwner == SENTINEL_OWNERS ||\n _newOwner == address(this)\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_newOwner] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n if (_oldOwner == address(0) || _oldOwner == SENTINEL_OWNERS)\n revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_prevOwner] != _oldOwner)\n revert MultiSigFacet__InvalidOwnerPair();\n\n ms.owners[_newOwner] = ms.owners[_oldOwner];\n ms.owners[_prevOwner] = _newOwner;\n ms.owners[_oldOwner] = address(0);\n emit OwnerRemoved(_oldOwner);\n emit OwnerAdded(_newOwner);\n }\n\n /**\n * @notice Changes the threshold of the Barz to `_threshold`.\n * @dev This can only be done via a Self call.\n * @param _threshold New threshold\n */\n function changeThreshold(uint256 _threshold) public {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (_threshold > ms.ownerCount || _threshold == 0)\n revert MultiSigFacet__InvalidThreshold();\n\n ms.threshold = _threshold;\n emit ThresholdChanged(_threshold);\n }\n\n /**\n * @notice Checks if the given address is owner\n * @param _owner Address to be checked if it's owner\n * @return isOwner_ Bool value showing if it's owner address\n */\n function isOwner(address _owner) public view returns (bool isOwner_) {\n isOwner_ = (_owner != SENTINEL_OWNERS &&\n LibMultiSigStorage.multisigStorage().owners[_owner] != address(0));\n }\n\n /**\n * @notice Returns the threshold of Barz\n * @return threshold Threshold of the Barz account\n */\n function getThreshold() public view returns (uint256 threshold) {\n threshold = LibMultiSigStorage.multisigStorage().threshold;\n }\n\n /**\n * @notice Returns the list of owner addresses\n * @return owners List of owners\n */\n function getOwners() public view returns (address[] memory owners) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n owners = new address[](ms.ownerCount);\n\n uint256 index;\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n while (currentOwner != SENTINEL_OWNERS) {\n owners[index] = currentOwner;\n currentOwner = ms.owners[currentOwner];\n index++;\n }\n }\n\n /**\n * @notice Returns the previous owner in the linked list\n * @param _owner Address of owner\n * @return prevOwner Address of previous owner\n */\n function getPrevOwner(\n address _owner\n ) public view returns (address prevOwner) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n if (currentOwner == _owner) return SENTINEL_OWNERS;\n while (currentOwner != SENTINEL_OWNERS) {\n if (ms.owners[currentOwner] == _owner) return currentOwner;\n\n currentOwner = ms.owners[currentOwner];\n }\n return address(0);\n }\n\n /**\n * @notice Returns of the owner is approved by given owner address\n * @param _owner Address of owner\n * @param _hash Hash of UserOperation\n * @return isApproved Bool value showing if the hash is approved by owner\n */\n function isApprovedHash(\n address _owner,\n bytes32 _hash\n ) public view returns (bool isApproved) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n isApproved = (ms.approvedHashes[ms.counter][_owner][_hash] == 1);\n }\n}\n" + }, + "contracts/facets/verification/secp256k1/Secp256k1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {UserOperation} from \"../../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibAppStorage} from \"../../../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, Secp256k1VerificationStorage} from \"../../../libraries/LibFacetStorage.sol\";\nimport {LibLoupe} from \"../../../libraries/LibLoupe.sol\";\nimport {IERC1271} from \"../../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../../interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Secp256k1 verification facet\n * @dev Default Ethereum's elliptic curve\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract Secp256k1VerificationFacet is IVerificationFacet, IERC1271 {\n using ECDSA for bytes32;\n error Secp256k1VerificationFacet__InvalidSignerLength();\n address public immutable self;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in K1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\n * @param _publicKey Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _publicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n if (!isValidKeyType(_publicKey))\n revert Secp256k1VerificationFacet__InvalidSignerLength();\n\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(uint160(uint256(keccak256(_publicKey[1:]))));\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_publicKey);\n }\n\n /**\n * @notice Uninitialize signer in K1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\n * signer public key.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n validationData = validateSignature(\n userOp,\n userOpHash,\n k1Storage.signer\n );\n }\n\n /**\n * @notice Validates if the signature of UserOperation is signed by the given signer\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @param signer Address of signer who signed the contract, to be validated\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n address signer\n ) public pure returns (uint256 isValid) {\n bytes32 hash = userOpHash.toEthSignedMessageHash();\n isValid = (signer != hash.recover(userOp.signature)) ? 1 : 0;\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n ownerSignatureValidatorSelector = this.validateOwnerSignature.selector;\n // NOTE: The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory signer) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n signer = abi.encodePacked(k1Storage.signer);\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key length should be 65 in an uncompressed public key format\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (_hash.recover(_signature) ==\n LibFacetStorage.k1Storage().signer)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/Secp256r1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {UserOperation} from \"../../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibAppStorage} from \"../../../libraries/LibAppStorage.sol\";\nimport {LibLoupe} from \"../../../libraries/LibLoupe.sol\";\nimport {LibFacetStorage, Secp256r1VerificationStorage} from \"../../../libraries/LibFacetStorage.sol\";\nimport {Base64} from \"./utils/Base64.sol\";\nimport {LibSecp256r1} from \"./utils/LibSecp256r1.sol\";\nimport {IERC1271} from \"../../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../../interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Secp256r1 verification facet\n * @dev Primarily used to verify user ops signed with passkeys\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract Secp256r1VerificationFacet is IVerificationFacet, IERC1271 {\n error Secp256r1VerificationFacet__InvalidSignerLength();\n address public immutable self;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in R1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\n * @param _publicKey Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _publicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n\n if (!isValidKeyType(_publicKey))\n revert Secp256r1VerificationFacet__InvalidSignerLength();\n\n bytes memory publicKeyCoordinates = _publicKey[1:];\n uint256[2] memory q;\n assembly {\n // Copy the bytes from the input data into the uint256 array\n mstore(q, mload(add(publicKeyCoordinates, 32)))\n mstore(add(q, 32), mload(add(publicKeyCoordinates, 64)))\n }\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n r1Storage.q = q;\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_publicKey);\n }\n\n /**\n * @notice Uninitialize signer in R1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n r1Storage.q = [0, 0];\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\n * signer public key.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n validationData = validateSignature(userOp, userOpHash, r1Storage.q);\n }\n\n /**\n * @notice Validates if the signature of UserOperation is signed by the given signer\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @param q Public Key of signer who signed the contract, to be validated\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256[2] memory q\n ) public view returns (uint256 isValid) {\n isValid = (_validateSignature(q, userOpHash, userOp.signature)) ? 0 : 1;\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n return this.validateOwnerSignature.selector; // validateOwnerSignature(UserOperation calldata userOp,bytes32 userOpHash)\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory signer) {\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n signer = abi.encodePacked(r1Storage.q);\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key should in an uncompressed public key format\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = _validateSignature(\n LibFacetStorage.r1Storage().q,\n _hash,\n _signature\n )\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n\n function _validateSignature(\n uint256[2] memory q,\n bytes32 _hash,\n bytes memory _signature\n ) internal view returns (bool) {\n (\n uint256 rValue,\n uint256 sValue,\n bytes memory authenticatorData,\n string memory clientDataJSONPre,\n string memory clientDataJSONPost\n ) = abi.decode(_signature, (uint256, uint256, bytes, string, string));\n bytes32 clientHash;\n {\n string memory opHashBase64 = Base64.encode(bytes.concat(_hash));\n string memory clientDataJSON = string.concat(\n clientDataJSONPre,\n opHashBase64,\n clientDataJSONPost\n );\n clientHash = sha256(bytes(clientDataJSON));\n }\n bytes32 sigHash = sha256(bytes.concat(authenticatorData, clientHash));\n return LibSecp256r1.Verify(q, rValue, sValue, uint256(sigHash));\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/utils/Base64.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @dev Provides a set of functions to operate with Base64 strings.\n * modified for base64url https://datatracker.ietf.org/doc/html/rfc4648#section-5\n * _Available since v4.5._\n */\nlibrary Base64 {\n /**\n * @dev Base64 Encoding/Decoding Table\n */\n string internal constant _TABLE =\n \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_\";\n\n /**\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\n */\n function encode(bytes memory data) internal pure returns (string memory) {\n /**\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\n */\n if (data.length == 0) return \"\";\n\n // Loads the table into memory\n string memory table = _TABLE;\n\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\n // and split into 4 numbers of 6 bits.\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\n // - `data.length + 2` -> Round up\n // - `/ 3` -> Number of 3-bytes chunks\n // - `4 *` -> 4 characters for each chunk\n uint256 newlength = (data.length * 8) / 6;\n if (data.length % 6 > 0) {\n newlength++;\n }\n string memory result = new string(newlength);\n\n /// @solidity memory-safe-assembly\n assembly {\n // Prepare the lookup table (skip the first \"length\" byte)\n let tablePtr := add(table, 1)\n\n // Prepare result pointer, jump over length\n let resultPtr := add(result, 32)\n\n // Run over the input, 3 bytes at a time\n for {\n let dataPtr := data\n let endPtr := add(data, mload(data))\n } lt(dataPtr, endPtr) {\n\n } {\n // Advance 3 bytes\n dataPtr := add(dataPtr, 3)\n let input := mload(dataPtr)\n\n // To write each character, shift the 3 bytes (18 bits) chunk\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\n // and apply logical AND with 0x3F which is the number of\n // the previous character in the ASCII table prior to the Base64 Table\n // The result is then added to the table to get the character to write,\n // and finally write it in the result pointer but with a left shift\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(18, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(12, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(6, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n }\n }\n\n return result;\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/utils/LibSecp256r1.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n// Heavily inspired from\n// https://github.com/maxrobot/elliptic-solidity/blob/master/contracts/Secp256r1.sol\n// https://github.com/tdrerup/elliptic-curve-solidity/blob/master/contracts/curves/EllipticCurve.sol\n// modified to use precompile 0x05 modexp\n// and modified jacobian double\n// optimisations to avoid to an from from affine and jacobian coordinates\n\n// Additional Elliptic curve Public key / Signature validation added by\n// David Yonjun Kim (@Powerstream3604)\n\nstruct JPoint {\n uint256 x;\n uint256 y;\n uint256 z;\n}\n\nlibrary LibSecp256r1 {\n uint256 constant gx =\n 0x6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296;\n uint256 constant gy =\n 0x4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5;\n uint256 public constant pp =\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF;\n\n uint256 public constant nn =\n 0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551;\n uint256 constant a =\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC;\n uint256 constant b =\n 0x5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B;\n uint256 constant MOST_SIGNIFICANT =\n 0xc000000000000000000000000000000000000000000000000000000000000000;\n\n /*\n * Verify\n * @description - verifies that a public key has signed a given message\n * @param Q - public key coordinates X & Y\n * @param R - signature half R\n * @param S - signature half S\n * @param input - hashed message\n */\n function Verify(\n uint256[2] memory q,\n uint r,\n uint s,\n uint e\n ) internal view returns (bool) {\n if (q[0] > pp - 1 || q[1] > pp - 1) {\n return false;\n }\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\n return false;\n }\n if (\n mulmod(q[1], q[1], pp) !=\n addmod(\n addmod(\n mulmod(q[0], mulmod(q[0], q[0], pp), pp),\n mulmod(a, q[0], pp),\n pp\n ),\n b,\n pp\n )\n ) {\n return false;\n }\n\n JPoint[16] memory points = _preComputeJacobianPoints(q);\n return VerifyWithPrecompute(points, r, s, e);\n }\n\n function VerifyWithPrecompute(\n JPoint[16] memory points,\n uint r,\n uint s,\n uint e\n ) internal view returns (bool) {\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\n return false;\n }\n\n uint w = _primemod(s, nn);\n\n uint u1 = mulmod(e, w, nn);\n uint u2 = mulmod(r, w, nn);\n\n uint x;\n uint y;\n\n (x, y) = ShamirMultJacobian(points, u1, u2);\n return (x == r);\n }\n\n /*\n * Strauss Shamir trick for EC multiplication\n * https://stackoverflow.com/questions/50993471/ec-scalar-multiplication-with-strauss-shamir-method\n * we optimise on this a bit to do with 2 bits at a time rather than a single bit\n * the individual points for a single pass are precomputed\n * overall this reduces the number of additions while keeping the same number of doublings\n */\n function ShamirMultJacobian(\n JPoint[16] memory points,\n uint u1,\n uint u2\n ) internal view returns (uint, uint) {\n uint x = 0;\n uint y = 0;\n uint z = 0;\n uint bits = 128;\n uint index = 0;\n\n while (bits > 0) {\n if (z > 0) {\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\n }\n index =\n ((u1 & MOST_SIGNIFICANT) >> 252) |\n ((u2 & MOST_SIGNIFICANT) >> 254);\n if (index > 0) {\n (x, y, z) = _jAdd(\n x,\n y,\n z,\n points[index].x,\n points[index].y,\n points[index].z\n );\n }\n u1 <<= 2;\n u2 <<= 2;\n bits--;\n }\n (x, y) = _affineFromJacobian(x, y, z);\n return (x, y);\n }\n\n function _preComputeJacobianPoints(\n uint256[2] memory q\n ) internal pure returns (JPoint[16] memory points) {\n points[0] = JPoint(0, 0, 0);\n points[1] = JPoint(q[0], q[1], 1); // u2\n points[2] = _jPointDouble(points[1]);\n points[3] = _jPointAdd(points[1], points[2]);\n\n points[4] = JPoint(gx, gy, 1); // u1Points[1]\n points[5] = _jPointAdd(points[4], points[1]);\n points[6] = _jPointAdd(points[4], points[2]);\n points[7] = _jPointAdd(points[4], points[3]);\n\n points[8] = _jPointDouble(points[4]); // u1Points[2]\n points[9] = _jPointAdd(points[8], points[1]);\n points[10] = _jPointAdd(points[8], points[2]);\n points[11] = _jPointAdd(points[8], points[3]);\n\n points[12] = _jPointAdd(points[4], points[8]); // u1Points[3]\n points[13] = _jPointAdd(points[12], points[1]);\n points[14] = _jPointAdd(points[12], points[2]);\n points[15] = _jPointAdd(points[12], points[3]);\n }\n\n function _jPointAdd(\n JPoint memory p1,\n JPoint memory p2\n ) internal pure returns (JPoint memory) {\n uint x;\n uint y;\n uint z;\n (x, y, z) = _jAdd(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z);\n return JPoint(x, y, z);\n }\n\n function _jPointDouble(\n JPoint memory p\n ) internal pure returns (JPoint memory) {\n uint x;\n uint y;\n uint z;\n (x, y, z) = _modifiedJacobianDouble(p.x, p.y, p.z);\n return JPoint(x, y, z);\n }\n\n /* _affineFromJacobian\n * @desription returns affine coordinates from a jacobian input follows\n * golang elliptic/crypto library\n */\n function _affineFromJacobian(\n uint x,\n uint y,\n uint z\n ) internal view returns (uint ax, uint ay) {\n if (z == 0) {\n return (0, 0);\n }\n\n uint zinv = _primemod(z, pp);\n uint zinvsq = mulmod(zinv, zinv, pp);\n\n ax = mulmod(x, zinvsq, pp);\n ay = mulmod(y, mulmod(zinvsq, zinv, pp), pp);\n }\n\n /*\n * _jAdd\n * @description performs Jacobian addition as defined below:\n * http://www.hyperelliptic.org/EFD/g1p/data/shortw/jacobian/addition/add-2007-bl\n */\n function _jAdd(\n uint p1,\n uint p2,\n uint p3,\n uint q1,\n uint q2,\n uint q3\n ) internal pure returns (uint r1, uint r2, uint r3) {\n if (p3 == 0) {\n r1 = q1;\n r2 = q2;\n r3 = q3;\n\n return (r1, r2, r3);\n } else if (q3 == 0) {\n r1 = p1;\n r2 = p2;\n r3 = p3;\n\n return (r1, r2, r3);\n }\n\n assembly {\n let\n pd\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\n let z1z1 := mulmod(p3, p3, pd) // Z1Z1 = Z1^2\n let z2z2 := mulmod(q3, q3, pd) // Z2Z2 = Z2^2\n\n let u1 := mulmod(p1, z2z2, pd) // U1 = X1*Z2Z2\n let u2 := mulmod(q1, z1z1, pd) // U2 = X2*Z1Z1\n\n let s1 := mulmod(p2, mulmod(z2z2, q3, pd), pd) // S1 = Y1*Z2*Z2Z2\n let s2 := mulmod(q2, mulmod(z1z1, p3, pd), pd) // S2 = Y2*Z1*Z1Z1\n\n let p3q3 := addmod(p3, q3, pd)\n\n if lt(u2, u1) {\n u2 := add(pd, u2) // u2 = u2+pd\n }\n let h := sub(u2, u1) // H = U2-U1\n\n let i := mulmod(0x02, h, pd)\n i := mulmod(i, i, pd) // I = (2*H)^2\n\n let j := mulmod(h, i, pd) // J = H*I\n if lt(s2, s1) {\n s2 := add(pd, s2) // u2 = u2+pd\n }\n let rr := mulmod(0x02, sub(s2, s1), pd) // r = 2*(S2-S1)\n r1 := mulmod(rr, rr, pd) // X3 = R^2\n\n let v := mulmod(u1, i, pd) // V = U1*I\n let j2v := addmod(j, mulmod(0x02, v, pd), pd)\n if lt(r1, j2v) {\n r1 := add(pd, r1) // X3 = X3+pd\n }\n r1 := sub(r1, j2v)\n\n // Y3 = r*(V-X3)-2*S1*J\n let s12j := mulmod(mulmod(0x02, s1, pd), j, pd)\n\n if lt(v, r1) {\n v := add(pd, v)\n }\n r2 := mulmod(rr, sub(v, r1), pd)\n\n if lt(r2, s12j) {\n r2 := add(pd, r2)\n }\n r2 := sub(r2, s12j)\n\n // Z3 = ((Z1+Z2)^2-Z1Z1-Z2Z2)*H\n z1z1 := addmod(z1z1, z2z2, pd)\n j2v := mulmod(p3q3, p3q3, pd)\n if lt(j2v, z1z1) {\n j2v := add(pd, j2v)\n }\n r3 := mulmod(sub(j2v, z1z1), h, pd)\n }\n return (r1, r2, r3);\n }\n\n // Point doubling on the modified jacobian coordinates\n // http://point-at-infinity.org/ecc/Prime_Curve_Modified_Jacobian_Coordinates.html\n function _modifiedJacobianDouble(\n uint x,\n uint y,\n uint z\n ) internal pure returns (uint x3, uint y3, uint z3) {\n if (y == 0) return (0, 0, 0);\n assembly {\n let\n pd\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\n let z2 := mulmod(z, z, pd)\n let az4 := mulmod(\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC,\n mulmod(z2, z2, pd),\n pd\n )\n let y2 := mulmod(y, y, pd)\n let s := mulmod(0x04, mulmod(x, y2, pd), pd)\n let u := mulmod(0x08, mulmod(y2, y2, pd), pd)\n let m := addmod(mulmod(0x03, mulmod(x, x, pd), pd), az4, pd)\n let twos := mulmod(0x02, s, pd)\n let m2 := mulmod(m, m, pd)\n if lt(m2, twos) {\n m2 := add(pd, m2)\n }\n x3 := sub(m2, twos)\n if lt(s, x3) {\n s := add(pd, s)\n }\n y3 := mulmod(m, sub(s, x3), pd)\n if lt(y3, u) {\n y3 := add(pd, y3)\n }\n y3 := sub(y3, u)\n z3 := mulmod(0x02, mulmod(y, z, pd), pd)\n }\n }\n\n // Fermats little theorem https://en.wikipedia.org/wiki/Fermat%27s_little_theorem\n // a^(p-1) = 1 mod p\n // a^(-1) ≅ a^(p-2) (mod p)\n // we then use the precompile bigModExp to compute a^(-1)\n function _primemod(uint value, uint p) internal view returns (uint ret) {\n ret = modexp(value, p - 2, p);\n return ret;\n }\n\n // Wrapper for built-in BigNumber_modexp (contract 0x5) as described here. https://github.com/ethereum/EIPs/pull/198\n function modexp(\n uint _base,\n uint _exp,\n uint _mod\n ) internal view returns (uint ret) {\n // bigModExp(_base, _exp, _mod);\n assembly {\n if gt(_base, _mod) {\n _base := mod(_base, _mod)\n }\n // Free memory pointer is always stored at 0x40\n let freemem := mload(0x40)\n\n mstore(freemem, 0x20)\n mstore(add(freemem, 0x20), 0x20)\n mstore(add(freemem, 0x40), 0x20)\n\n mstore(add(freemem, 0x60), _base)\n mstore(add(freemem, 0x80), _exp)\n mstore(add(freemem, 0xa0), _mod)\n\n let success := staticcall(14000, 0x5, freemem, 0xc0, freemem, 0x20)\n switch success\n case 0 {\n revert(0x0, 0x0)\n }\n default {\n ret := mload(freemem)\n }\n }\n }\n}\n" + }, + "contracts/infrastructure/DefaultFallbackHandler.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC1155Receiver} from \"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\";\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {BaseAccount} from \"../aa-4337/core/BaseAccount.sol\";\nimport {DefaultLibDiamond} from \"../libraries/DefaultLibDiamond.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IAccountFacet} from \"../facets/interfaces/IAccountFacet.sol\";\nimport {IStorageLoupe} from \"../facets/base/interfaces/IStorageLoupe.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IERC677Receiver} from \"../interfaces/ERC/IERC677Receiver.sol\";\nimport {IERC165} from \"../interfaces/ERC/IERC165.sol\";\n\n/**\n * @title DefaultFallbackHandler\n * @dev A default fallback handler for Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DefaultFallbackHandler is IDiamondLoupe {\n /**\n * @notice Sets the middleware diamond for Barz wallet as a fallback handler\n * @dev This contract is also a diamond that holds the default facets to reduce gas cost for wallet activation.\n * Within the constructor this conducts diamond cut to initially setup the diamond. This is a non-upgradeable contract\n * @param _diamondCutFacet Address if diamond cut facet\n * @param _accountFacet Address account facet\n * @param _tokenReceiverFacet Address of token receiver facet\n * @param _diamondLoupeFacet Address of diamond loupe facet\n */\n constructor(\n address _diamondCutFacet,\n address _accountFacet,\n address _tokenReceiverFacet,\n address _diamondLoupeFacet\n ) payable {\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](4);\n bytes4[] memory functionSelectors = new bytes4[](1);\n functionSelectors[0] = IDiamondCut.diamondCut.selector;\n\n bytes4[] memory accountFunctionSelectors = new bytes4[](5);\n accountFunctionSelectors[0] = IAccountFacet.execute.selector;\n accountFunctionSelectors[1] = IAccountFacet.executeBatch.selector;\n accountFunctionSelectors[2] = BaseAccount.validateUserOp.selector;\n accountFunctionSelectors[3] = BaseAccount.getNonce.selector;\n accountFunctionSelectors[4] = BaseAccount.entryPoint.selector;\n\n bytes4[] memory receiverFacetSelectors = new bytes4[](5);\n receiverFacetSelectors[0] = IERC721Receiver.onERC721Received.selector;\n receiverFacetSelectors[1] = IERC1155Receiver.onERC1155Received.selector;\n receiverFacetSelectors[2] = IERC1155Receiver\n .onERC1155BatchReceived\n .selector;\n receiverFacetSelectors[3] = IERC777Recipient.tokensReceived.selector;\n receiverFacetSelectors[4] = IERC677Receiver.onTokenTransfer.selector;\n\n bytes4[] memory loupeFacetSelectors = new bytes4[](9);\n loupeFacetSelectors[0] = IDiamondLoupe.facets.selector;\n loupeFacetSelectors[1] = IDiamondLoupe.facetFunctionSelectors.selector;\n loupeFacetSelectors[2] = IDiamondLoupe.facetAddresses.selector;\n loupeFacetSelectors[3] = IDiamondLoupe.facetAddress.selector;\n loupeFacetSelectors[4] = IERC165.supportsInterface.selector;\n loupeFacetSelectors[5] = IStorageLoupe.facetsFromStorage.selector;\n loupeFacetSelectors[6] = IStorageLoupe\n .facetFunctionSelectorsFromStorage\n .selector;\n loupeFacetSelectors[7] = IStorageLoupe\n .facetAddressesFromStorage\n .selector;\n loupeFacetSelectors[8] = IStorageLoupe.facetAddressFromStorage.selector;\n\n {\n cut[0] = IDiamondCut.FacetCut({\n facetAddress: _diamondCutFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: functionSelectors\n });\n cut[1] = IDiamondCut.FacetCut({\n facetAddress: _accountFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: accountFunctionSelectors\n });\n cut[2] = IDiamondCut.FacetCut({\n facetAddress: _tokenReceiverFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: receiverFacetSelectors\n });\n cut[3] = IDiamondCut.FacetCut({\n facetAddress: _diamondLoupeFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: loupeFacetSelectors\n });\n\n DefaultLibDiamond.diamondCut(cut, address(0), \"\");\n }\n }\n\n /**\n * @notice Returns the facet information of call facets registered to this diamond.\n * @return facets_ The facet struct array including all facet information\n */\n function facets() external view override returns (Facet[] memory facets_) {\n DefaultLibDiamond.DiamondStorage storage ds = DefaultLibDiamond\n .diamondStorage();\n uint256 numFacets = ds.facetAddresses.length;\n facets_ = new Facet[](numFacets);\n for (uint256 i; i < numFacets; ) {\n address facetAddress_ = ds.facetAddresses[i];\n facets_[i].facetAddress = facetAddress_;\n facets_[i].functionSelectors = ds\n .facetFunctionSelectors[facetAddress_]\n .functionSelectors;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Gets all the function selectors provided by a facet.\n * @param _facet The facet address.\n * @return facetFunctionSelectors_\n */\n function facetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n facetFunctionSelectors_ = DefaultLibDiamond\n .diamondStorage()\n .facetFunctionSelectors[_facet]\n .functionSelectors;\n }\n\n /**\n * @notice Get all the facet addresses used by a diamond.\n * @return facetAddresses_\n */\n function facetAddresses()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n facetAddresses_ = DefaultLibDiamond.diamondStorage().facetAddresses;\n }\n\n /** @notice Gets the facet that supports the given selector.\n * @dev If facet is not found return address(0).\n * @param _functionSelector The function selector.\n * @return facetAddress_ The facet address.\n */\n function facetAddress(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n facetAddress_ = DefaultLibDiamond\n .diamondStorage()\n .selectorToFacetAndPosition[_functionSelector]\n .facetAddress;\n }\n}\n" + }, + "contracts/infrastructure/FacetRegistry.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport {IFacetRegistry} from \"./interfaces/IFacetRegistry.sol\";\n\n/**\n * @title Facet Registry\n * @dev Contract to keep track of facets & function selectors addable to user wallets\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract FacetRegistry is IFacetRegistry, Ownable2Step {\n mapping(address => FacetRegistryConfig) private facets;\n\n /**\n * @notice Transfers the ownership of the contract to the given owner\n * @param _owner Address of owner who has access to initialize the default security variables for security manager\n */\n constructor(address _owner) {\n transferOwnership(_owner);\n _transferOwnership(_owner);\n }\n\n /**\n * @dev Registers a facet and it's function selectors to registry\n * @param _facet address of facet\n * @param _facetSelectors list of function selectors of the facet\n */\n function registerFacetFunctionSelectors(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external override onlyOwner {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n for (uint256 i; i < _facetSelectors.length; ) {\n if (facetConfig.info[_facetSelectors[i]].exists)\n revert FacetRegistry__FacetSelectorAlreadyRegistered();\n\n facetConfig.info[_facetSelectors[i]].exists = true;\n facetConfig.info[_facetSelectors[i]].index = uint128(\n facetConfig.selectors.length\n );\n facetConfig.selectors.push(_facetSelectors[i]);\n unchecked {\n ++i;\n }\n }\n emit FacetFunctionSelectorsRegistered(_facet, _facetSelectors);\n }\n\n /**\n * @dev Removes a registered facet and it's corresponding selectors from registry\n * @param _facet address of facet\n * @param _facetSelectors list of function selectors of the facet\n */\n function removeFacetFunctionSelectors(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external override onlyOwner {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n for (uint256 i; i < _facetSelectors.length; ) {\n if (!facetConfig.info[_facetSelectors[i]].exists)\n revert FacetRegistry__UnregisteredFacetSelector();\n\n bytes4 lastSelector = facetConfig.selectors[\n facetConfig.selectors.length - 1\n ];\n if (_facetSelectors[i] != lastSelector) {\n uint128 targetIndex = facetConfig\n .info[_facetSelectors[i]]\n .index;\n facetConfig.selectors[targetIndex] = lastSelector;\n facetConfig.info[lastSelector].index = targetIndex;\n }\n facetConfig.selectors.pop();\n delete facetConfig.info[_facetSelectors[i]];\n\n unchecked {\n ++i;\n }\n }\n emit FacetFunctionSelectorsRemoved(_facet, _facetSelectors);\n }\n\n /**\n * @dev Checks if a facet and it's selectors given is registered to facet registry\n * @param _facet Address of facet\n * @param _facetSelectors List of function selectors of the facet\n */\n function areFacetFunctionSelectorsRegistered(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external view override returns (bool) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n if (_facetSelectors.length == 0) return false;\n for (uint256 i; i < _facetSelectors.length; ) {\n if (!facetConfig.info[_facetSelectors[i]].exists) return false;\n unchecked {\n ++i;\n }\n }\n return true;\n }\n\n /**\n * @dev Checks if a facet and it's selector given is registered to facet registry\n * @param _facet Address of facet\n * @param _facetSelector List of function selectors of the facet\n * @return isRegistered Bool value showing if the selector is registered\n */\n function isFacetFunctionSelectorRegistered(\n address _facet,\n bytes4 _facetSelector\n ) external view override returns (bool isRegistered) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n isRegistered = facetConfig.info[_facetSelector].exists;\n }\n\n /**\n * @dev Get the registered selectors of facet from registry\n * @param _facet Address of facet\n * @return selectors Selectors registered to facet\n */\n function getFacetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory selectors) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n selectors = facetConfig.selectors;\n }\n}\n" + }, + "contracts/infrastructure/interfaces/IFacetRegistry.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Registry Interface\n * @dev Interface for Facet Registry contract to keep track of facets & function selectors addable to user wallets\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IFacetRegistry {\n struct FacetRegistryConfig {\n bytes4[] selectors;\n mapping(bytes4 => FacetInfo) info;\n }\n struct FacetInfo {\n bool exists;\n uint128 index;\n }\n\n event FacetFunctionSelectorsRegistered(\n address facet,\n bytes4[] facetSelectors\n );\n event FacetFunctionSelectorsRemoved(address facet, bytes4[] facetSelectors);\n\n error FacetRegistry__FacetSelectorAlreadyRegistered();\n error FacetRegistry__UnregisteredFacetSelector();\n\n function registerFacetFunctionSelectors(\n address facet,\n bytes4[] calldata facetSelectors\n ) external;\n\n function removeFacetFunctionSelectors(\n address facet,\n bytes4[] calldata facetSelectors\n ) external;\n\n function areFacetFunctionSelectorsRegistered(\n address facet,\n bytes4[] calldata facetSelectors\n ) external view returns (bool);\n\n function isFacetFunctionSelectorRegistered(\n address facet,\n bytes4 facetSelector\n ) external view returns (bool);\n\n function getFacetFunctionSelectors(\n address facet\n ) external view returns (bytes4[] memory);\n}\n" + }, + "contracts/infrastructure/interfaces/ISecurityManager.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Registry Interface\n * @dev Infrastructure contract to manage security parameters of users\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface ISecurityManager {\n error SecurityManager__OutOfBoundary();\n error SecurityManager__CallerNotWallet();\n error SecurityManager__AlreadyIntialized();\n\n function initializeAdditionSecurityPeriod(\n uint128 defaultAdditionSecurityPeriod,\n uint128 minAdditionSecurityPeriod,\n uint128 maxAdditionSecurityPeriod\n ) external;\n\n function initializeRemovalSecurityPeriod(\n uint128 defaultRemovalSecurityPeriod,\n uint128 minRemovalSecurityPeriod,\n uint128 maxRemovalSecurityPeriod\n ) external;\n\n function initializeApprovalValidationPeriod(\n uint128 defaultApprovalValidationPeriod,\n uint128 minApprovalValidationPeriod,\n uint128 maxApprovalValidationPeriod\n ) external;\n\n function initializeMigrationPeriod(\n uint128 defaultMigrationPeriod,\n uint128 minMigrationPeriod,\n uint128 maxMigrationPeriod\n ) external;\n\n function initializeLockPeriod(\n uint128 defaultLockPeriod,\n uint128 minLockPeriod,\n uint128 maxLockPeriod\n ) external;\n\n function initializeRecoveryPeriod(\n uint128 defaultRecoveryPeriod,\n uint128 minRecoveryPeriod,\n uint128 maxRecoveryPeriod\n ) external;\n\n function initializeSecurityWindow(\n uint128 defaultSecurityWindow,\n uint128 minSecurityWindow,\n uint128 maxSecurityWindow\n ) external;\n\n function setAdditionSecurityPeriod(\n address wallet,\n uint128 additionSecurityPeriod\n ) external;\n\n function setRemovalSecurityPeriod(\n address wallet,\n uint128 removalSecurityPeriod\n ) external;\n\n function setSecurityWindow(address wallet, uint128 securityWindow) external;\n\n function setRecoveryPeriod(address wallet, uint128 recoveryPeriod) external;\n\n function setLockPeriod(address wallet, uint128 lockPeriod) external;\n\n function setApprovalValidationPeriod(\n address wallet,\n uint128 approvalValidationPeriod\n ) external;\n\n function setMigrationPeriod(\n address wallet,\n uint128 migrationPeriod\n ) external;\n\n function additionSecurityPeriodOf(\n address wallet\n ) external view returns (uint128);\n\n function removalSecurityPeriodOf(\n address wallet\n ) external view returns (uint128);\n\n function securityWindowOf(address wallet) external view returns (uint128);\n\n function recoveryPeriodOf(address wallet) external view returns (uint128);\n\n function lockPeriodOf(address wallet) external view returns (uint128);\n\n function migrationPeriodOf(address wallet) external view returns (uint128);\n\n function approvalValidationPeriodOf(\n address wallet\n ) external view returns (uint128);\n}\n" + }, + "contracts/infrastructure/RemoteStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IGuardianFacet} from \"../facets/interfaces/IGuardianFacet.sol\";\n\n/**\n * @title Remote Storage\n * @dev Remote storage allows you to associate addresses with an array of addresses on a standalone smart contract.\n * This could be useful when you don't want to use the local diamond storage for some purpose.\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\nabstract contract RemoteStorage {\n struct StorageConfig {\n address[] addresses;\n mapping(address => Info) info;\n }\n\n struct Info {\n bool exists;\n uint128 index;\n }\n\n mapping(address => StorageConfig) internal configs;\n\n event Added(address _address);\n event Removed(address _address);\n\n error RemoteStorage__CallerNotOwner();\n error RemoteStorage__CallerNotGuardianOrOwner();\n error RemoteStorage__AlreadyExists();\n error RemoteStorage__NotFound();\n error RemoteStorage__CallerNotGuardian();\n\n bytes4 constant IS_GUARDIAN_SELECTOR =\n bytes4(keccak256(\"isGuardian(address)\"));\n bytes4 constant GUARDIAN_COUNT = bytes4(keccak256(\"guardianCount()\"));\n\n /**\n * @notice Modifier to only allow the self to call. Reverts otherwise\n */\n modifier onlyWallet(address _wallet) {\n if (msg.sender != _wallet) revert RemoteStorage__CallerNotOwner();\n _;\n }\n\n /**\n * @notice Enfore the callet to be wallet of guardian of the wallet\n * @param _wallet Address of wallet\n */\n function enforceGuardianOrWallet(address _wallet) internal view {\n if (msg.sender == _wallet) return;\n address facetAddress = IDiamondLoupe(_wallet).facetAddress(\n IS_GUARDIAN_SELECTOR\n );\n if (facetAddress != address(0))\n if (IGuardianFacet(_wallet).isGuardian(msg.sender)) return;\n revert RemoteStorage__CallerNotGuardianOrOwner();\n }\n\n /**\n * @notice Enforce the caller to be wallet IF guardians doesn't exists and only guardian when guardians exists\n * @param _wallet Target wallet address to be handled by infrastructure contracts\n */\n function enforceWalletOrGuardianIfExists(address _wallet) internal view {\n address facetAddress;\n if (msg.sender == _wallet) {\n facetAddress = IDiamondLoupe(_wallet).facetAddress(GUARDIAN_COUNT);\n if (facetAddress == address(0)) return;\n uint256 guardianCount = IGuardianFacet(_wallet).guardianCount();\n if (guardianCount != 0) revert RemoteStorage__CallerNotGuardian();\n return;\n }\n facetAddress = IDiamondLoupe(_wallet).facetAddress(\n IS_GUARDIAN_SELECTOR\n );\n if (facetAddress != address(0))\n if (IGuardianFacet(_wallet).isGuardian(msg.sender)) return;\n\n revert RemoteStorage__CallerNotGuardianOrOwner();\n }\n\n /**\n * @notice Add address to storage and reverts if the address already exists.\n * This is an internal function callable from contracts that inherit this abstract contract\n * @param _wallet Address of wallet to add the address\n * @param _address Address to be added to wallet\n */\n function addAddress(address _wallet, address _address) internal {\n StorageConfig storage config = configs[_wallet];\n if (config.info[_address].exists) revert RemoteStorage__AlreadyExists();\n\n config.info[_address].exists = true;\n config.info[_address].index = uint128(config.addresses.length);\n config.addresses.push(_address);\n\n emit Added(_address);\n }\n\n /**\n * @notice Remove address from storage and reverts if the address already exists.\n * This is an internal function callable from contracts that inherit this abstract contract\n * @param _wallet Address of wallet to remove the address\n * @param _address Address to be removed from wallet\n */\n function removeAddress(address _wallet, address _address) internal {\n StorageConfig storage config = configs[_wallet];\n if (!config.info[_address].exists) revert RemoteStorage__NotFound();\n\n address lastAddress = config.addresses[config.addresses.length - 1];\n if (_address != lastAddress) {\n uint128 targetIndex = config.info[_address].index;\n config.addresses[targetIndex] = lastAddress;\n config.info[lastAddress].index = targetIndex;\n }\n config.addresses.pop();\n delete config.info[_address];\n\n emit Removed(_address);\n }\n\n /**\n * @notice Returns the address added to the given wallet\n * @param _wallet Address of wallet to fetch the addresses added to it\n * @return addresses List of addresses added to the wallet\n */\n function getAddresses(\n address _wallet\n ) internal view returns (address[] memory addresses) {\n StorageConfig storage config = configs[_wallet];\n addresses = new address[](config.addresses.length);\n uint addressesLen = config.addresses.length;\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns bool value checking if the address exists in the given wallet address\n * @param _wallet Wallet address to check\n * @param _address Address to fetch if the address if added to given wallet\n * @return exists_ Bool value showing if the address exists in wallet\n */\n function exists(\n address _wallet,\n address _address\n ) internal view returns (bool exists_) {\n exists_ = configs[_wallet].info[_address].exists;\n }\n\n /**\n * @notice Returns the number of addresses added to the wallet\n * @param _wallet Address of wallet to check\n * @return count_ Number of addresses added to wallet\n */\n function count(address _wallet) internal view returns (uint256 count_) {\n count_ = configs[_wallet].addresses.length;\n }\n}\n" + }, + "contracts/infrastructure/SecurityManager.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport {ISecurityManager} from \"./interfaces/ISecurityManager.sol\";\n\n/**\n * @title Security Manager\n * @dev Infrastructure contract to manage security parameters of users\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract SecurityManager is ISecurityManager, Ownable2Step {\n uint128 public minAdditionSecurityPeriod;\n uint128 public maxAdditionSecurityPeriod;\n uint128 private defaultAdditionSecurityPeriod;\n\n uint128 public minRemovalSecurityPeriod;\n uint128 public maxRemovalSecurityPeriod;\n uint128 private defaultRemovalSecurityPeriod;\n\n uint128 public minSecurityWindow;\n uint128 public maxSecurityWindow;\n uint128 private defaultSecurityWindow;\n\n uint128 public minRecoveryPeriod;\n uint128 public maxRecoveryPeriod;\n uint128 private defaultRecoveryPeriod;\n\n uint128 public minLockPeriod;\n uint128 public maxLockPeriod;\n uint128 private defaultLockPeriod;\n\n uint128 public minApprovalValidationPeriod;\n uint128 public maxApprovalValidationPeriod;\n uint128 private defaultApprovalValidationPeriod;\n\n uint128 public minMigrationPeriod;\n uint128 public maxMigrationPeriod;\n uint128 private defaultMigrationPeriod;\n\n bool public _isAdditionSecurityPeriodInitialized;\n bool public _isRemovalSecurityPeriodInitialized;\n bool public _isSecurityWindowInitialized;\n bool public _isRecoveryPeriodInitialized;\n bool public _isLockPeriodInitialized;\n bool public _isApprovalValidationPeriodInitialized;\n bool public _isMigrationPeriodInitialized;\n\n mapping(address => CustomSecurityConfig) securityConfigs;\n\n struct CustomSecurityConfig {\n uint128 additionSecurityPeriod;\n uint128 removalSecurityPeriod;\n uint128 securityWindow;\n uint128 recoveryPeriod;\n uint128 lockPeriod;\n uint128 approvalValidationPeriod;\n uint128 migrationPeriod;\n }\n\n /**\n * @notice Modifier to only allow wallet itself to make a call to wallet\n */\n modifier onlyWallet(address _wallet) {\n if (msg.sender != _wallet) revert SecurityManager__CallerNotWallet();\n _;\n }\n\n /**\n * @notice Modifier to revert if the variable is already initialized\n */\n modifier initializer(bool _isInitialized) {\n if (_isInitialized) revert SecurityManager__AlreadyIntialized();\n _;\n }\n\n /**\n * @notice Transfers the ownership of the contract to the given owner\n * @param _owner Address of owner who has access to initialize the default security variables for security manager\n */\n constructor(address _owner) {\n transferOwnership(_owner);\n _transferOwnership(_owner);\n }\n\n /**\n * @notice Sets the initial default/min/max addition security period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultAdditionSecurityPeriod Default Addition Security Period for all Barz contracts\n * @param _minAdditionSecurityPeriod Minimum Addition Security Period for all Barz contracts\n * @param _maxAdditionSecurityPeriod Maximum Addition Security Period for all Barz contracts\n */\n function initializeAdditionSecurityPeriod(\n uint128 _defaultAdditionSecurityPeriod,\n uint128 _minAdditionSecurityPeriod,\n uint128 _maxAdditionSecurityPeriod\n )\n external\n override\n onlyOwner\n initializer(_isAdditionSecurityPeriodInitialized)\n {\n _isAdditionSecurityPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultAdditionSecurityPeriod,\n _minAdditionSecurityPeriod,\n _maxAdditionSecurityPeriod\n );\n defaultAdditionSecurityPeriod = _defaultAdditionSecurityPeriod;\n minAdditionSecurityPeriod = _minAdditionSecurityPeriod;\n maxAdditionSecurityPeriod = _maxAdditionSecurityPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max removal security period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultRemovalSecurityPeriod Default Removal Security Period for all Barz contracts\n * @param _minRemovalSecurityPeriod Minimum Removal Security Period for all Barz contracts\n * @param _maxRemovalSecurityPeriod Maximum Removal Security Period for all Barz contracts\n */\n function initializeRemovalSecurityPeriod(\n uint128 _defaultRemovalSecurityPeriod,\n uint128 _minRemovalSecurityPeriod,\n uint128 _maxRemovalSecurityPeriod\n )\n external\n override\n onlyOwner\n initializer(_isRemovalSecurityPeriodInitialized)\n {\n _isRemovalSecurityPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultRemovalSecurityPeriod,\n _minRemovalSecurityPeriod,\n _maxRemovalSecurityPeriod\n );\n defaultRemovalSecurityPeriod = _defaultRemovalSecurityPeriod;\n minRemovalSecurityPeriod = _minRemovalSecurityPeriod;\n maxRemovalSecurityPeriod = _maxRemovalSecurityPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/maxd security window for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultSecurityWindow Default Security Window for all Barz contracts\n * @param _minSecurityWindow Minimum Security Window for all Barz contracts\n * @param _maxSecurityWindow Maximum Security Window for all Barz contracts\n */\n function initializeSecurityWindow(\n uint128 _defaultSecurityWindow,\n uint128 _minSecurityWindow,\n uint128 _maxSecurityWindow\n ) external override onlyOwner initializer(_isSecurityWindowInitialized) {\n _isSecurityWindowInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultSecurityWindow,\n _minSecurityWindow,\n _maxSecurityWindow\n );\n defaultSecurityWindow = _defaultSecurityWindow;\n minSecurityWindow = _minSecurityWindow;\n maxSecurityWindow = _maxSecurityWindow;\n }\n\n /**\n * @notice Sets the initial default/min/max recovery period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultRecoveryPeriod Default Recovery Period for all Barz contracts\n * @param _minRecoveryPeriod Minimum Recovery Period for all Barz contracts\n * @param _maxRecoveryPeriod Maximum Recovery Period for all Barz contracts\n */\n function initializeRecoveryPeriod(\n uint128 _defaultRecoveryPeriod,\n uint128 _minRecoveryPeriod,\n uint128 _maxRecoveryPeriod\n ) external override onlyOwner initializer(_isRecoveryPeriodInitialized) {\n _isRecoveryPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultRecoveryPeriod,\n _minRecoveryPeriod,\n _maxRecoveryPeriod\n );\n defaultRecoveryPeriod = _defaultRecoveryPeriod;\n minRecoveryPeriod = _minRecoveryPeriod;\n maxRecoveryPeriod = _maxRecoveryPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max lock period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultLockPeriod Default Lock Period for all Barz contracts\n * @param _minLockPeriod Minimum Lock Period for all Barz contracts\n * @param _maxLockPeriod Maximum Lock Period for all Barz contracts\n */\n function initializeLockPeriod(\n uint128 _defaultLockPeriod,\n uint128 _minLockPeriod,\n uint128 _maxLockPeriod\n ) external override onlyOwner initializer(_isLockPeriodInitialized) {\n _isLockPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultLockPeriod,\n _minLockPeriod,\n _maxLockPeriod\n );\n defaultLockPeriod = _defaultLockPeriod;\n minLockPeriod = _minLockPeriod;\n maxLockPeriod = _maxLockPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max approval validation period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultApprovalValidationPeriod Default Approval Validation Period for all Barz contracts\n * @param _minApprovalValidationPeriod Minimum Approval Validation Period for all Barz contracts\n * @param _maxApprovalValidationPeriod Maximum Approval Validation Period for all Barz contracts\n */\n function initializeApprovalValidationPeriod(\n uint128 _defaultApprovalValidationPeriod,\n uint128 _minApprovalValidationPeriod,\n uint128 _maxApprovalValidationPeriod\n )\n external\n override\n onlyOwner\n initializer(_isApprovalValidationPeriodInitialized)\n {\n _isApprovalValidationPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultApprovalValidationPeriod,\n _minApprovalValidationPeriod,\n _maxApprovalValidationPeriod\n );\n defaultApprovalValidationPeriod = _defaultApprovalValidationPeriod;\n minApprovalValidationPeriod = _minApprovalValidationPeriod;\n maxApprovalValidationPeriod = _maxApprovalValidationPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max migration period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultMigrationPeriod Default Migration Period for all Barz contracts\n * @param _minMigrationPeriod Minimum Migration Period for all Barz contracts\n * @param _maxMigrationPeriod Maximum Migration Period for all Barz contracts\n */\n function initializeMigrationPeriod(\n uint128 _defaultMigrationPeriod,\n uint128 _minMigrationPeriod,\n uint128 _maxMigrationPeriod\n ) external override onlyOwner initializer(_isMigrationPeriodInitialized) {\n _isMigrationPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultMigrationPeriod,\n _minMigrationPeriod,\n _maxMigrationPeriod\n );\n defaultMigrationPeriod = _defaultMigrationPeriod;\n minMigrationPeriod = _minMigrationPeriod;\n maxMigrationPeriod = _maxMigrationPeriod;\n }\n\n /**\n * @notice Wallet owner sets the addition security period for the wallet. Only the owner of wallet can call this function.\n * The addition security period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _additionSecurityPeriod Custom Addition Security Period for the wallet\n */\n function setAdditionSecurityPeriod(\n address _wallet,\n uint128 _additionSecurityPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _additionSecurityPeriod,\n minAdditionSecurityPeriod,\n maxAdditionSecurityPeriod\n );\n securityConfigs[_wallet]\n .additionSecurityPeriod = _additionSecurityPeriod;\n }\n\n /**\n * @notice Wallet owner sets the removal security period for the wallet. Only the owner of wallet can call this function.\n * The removal security period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _removalSecurityPeriod Custom Removal Security Period for the wallet\n */\n function setRemovalSecurityPeriod(\n address _wallet,\n uint128 _removalSecurityPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _removalSecurityPeriod,\n minRemovalSecurityPeriod,\n maxRemovalSecurityPeriod\n );\n securityConfigs[_wallet].removalSecurityPeriod = _removalSecurityPeriod;\n }\n\n /**\n * @notice Wallet owner sets the security window for the wallet. Only the owner of wallet can call this function.\n * The security window should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _securityWindow Custom Security Window for the wallet\n */\n function setSecurityWindow(\n address _wallet,\n uint128 _securityWindow\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _securityWindow,\n minSecurityWindow,\n maxSecurityWindow\n );\n securityConfigs[_wallet].securityWindow = _securityWindow;\n }\n\n /**\n * @notice Wallet owner sets the recovery period for the wallet. Only the owner of wallet can call this function.\n * The recovery period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _recoveryPeriod Custom recovery period for the wallet\n */\n function setRecoveryPeriod(\n address _wallet,\n uint128 _recoveryPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _recoveryPeriod,\n minRecoveryPeriod,\n maxRecoveryPeriod\n );\n securityConfigs[_wallet].recoveryPeriod = _recoveryPeriod;\n }\n\n /**\n * @notice Wallet owner sets the lock period for the wallet. Only the owner of wallet can call this function.\n * The lock period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _lockPeriod Custom Lock period for the wallet\n */\n function setLockPeriod(\n address _wallet,\n uint128 _lockPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(_lockPeriod, minLockPeriod, maxLockPeriod);\n securityConfigs[_wallet].lockPeriod = _lockPeriod;\n }\n\n /**\n * @notice Wallet owner sets the approval validation period for the wallet. Only the owner of wallet can call this function.\n * The approval validation period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _approvalValidationPeriod Custom approval validation period for the wallet\n */\n function setApprovalValidationPeriod(\n address _wallet,\n uint128 _approvalValidationPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _approvalValidationPeriod,\n minApprovalValidationPeriod,\n maxApprovalValidationPeriod\n );\n securityConfigs[_wallet]\n .approvalValidationPeriod = _approvalValidationPeriod;\n }\n\n /**\n * @notice Wallet owner sets the migration period for the wallet. Only the owner of wallet can call this function.\n * The migration period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _migrationPeriod Custom migration period for the wallet\n */\n\n function setMigrationPeriod(\n address _wallet,\n uint128 _migrationPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _migrationPeriod,\n minMigrationPeriod,\n maxMigrationPeriod\n );\n securityConfigs[_wallet].migrationPeriod = _migrationPeriod;\n }\n\n /**\n * @notice Returns the addition security period. Returns default value when custom addition security period is not set\n * @param _wallet Address of wallet\n * @return additionSecurityPeriod Addition Security Period of the given Barz account or wallet\n */\n function additionSecurityPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 additionSecurityPeriod)\n {\n additionSecurityPeriod = securityConfigs[_wallet]\n .additionSecurityPeriod;\n additionSecurityPeriod = (additionSecurityPeriod == 0)\n ? defaultAdditionSecurityPeriod\n : additionSecurityPeriod;\n }\n\n /**\n * @notice Returns the removal security period. Returns default value when custom removal security period is not set\n * @param _wallet Address of wallet\n * @return removalSecurityPeriod Removal Security Period of the given Barz account or wallet\n */\n function removalSecurityPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 removalSecurityPeriod)\n {\n removalSecurityPeriod = securityConfigs[_wallet].removalSecurityPeriod;\n removalSecurityPeriod = (removalSecurityPeriod == 0)\n ? defaultRemovalSecurityPeriod\n : removalSecurityPeriod;\n }\n\n /**\n * @notice Returns the security window. Returns default value when custom security window is not set\n * @param _wallet Address of wallet\n * @return securityWindow Security window of the given Barz account or wallet\n */\n function securityWindowOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 securityWindow)\n {\n securityWindow = securityConfigs[_wallet].securityWindow;\n securityWindow = (securityWindow == 0)\n ? defaultSecurityWindow\n : securityWindow;\n }\n\n /**\n * @notice Returns the recovery period. Returns default value when custom recovery period is not set\n * @param _wallet Address of wallet\n * @return recoveryPeriod Recovery Period of the given Barz account or wallet\n */\n function recoveryPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 recoveryPeriod)\n {\n recoveryPeriod = securityConfigs[_wallet].recoveryPeriod;\n recoveryPeriod = (recoveryPeriod == 0)\n ? defaultRecoveryPeriod\n : recoveryPeriod;\n }\n\n /**\n * @notice Returns the lock period. Returns default value when custom lock period is not set\n * @param _wallet Address of wallet\n * @return lockPeriod Lock Period of the given Barz account or wallet\n */\n function lockPeriodOf(\n address _wallet\n ) public view override onlyWallet(_wallet) returns (uint128 lockPeriod) {\n lockPeriod = securityConfigs[_wallet].lockPeriod;\n lockPeriod = (lockPeriod == 0) ? defaultLockPeriod : lockPeriod;\n }\n\n /**\n * @notice Returns the approval validation period. Returns default value when custom approval validation period is not set\n * @param _wallet Address of wallet\n * @return approvalValidationPeriod Approval Validation Period of the given Barz account or wallet\n */\n function approvalValidationPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityConfigs[_wallet]\n .approvalValidationPeriod;\n approvalValidationPeriod = (approvalValidationPeriod == 0)\n ? defaultApprovalValidationPeriod\n : approvalValidationPeriod;\n }\n\n /**\n * @notice Returns the migration period. Returns default value when custom migration period is not set\n * @param _wallet Address of wallet\n * @return migrationPeriod Migration Period of the given Barz account or wallet\n */\n function migrationPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 migrationPeriod)\n {\n migrationPeriod = securityConfigs[_wallet].migrationPeriod;\n migrationPeriod = (migrationPeriod == 0)\n ? defaultMigrationPeriod\n : migrationPeriod;\n }\n\n /**\n * @notice Validates if the period is smaller than the max period or bigger than the min period\n * @param _period Period to be checked\n * @param _minPeriod Minimum period\n * @param _maxPeriod Maximum period\n */\n function _validatePeriodBoundaries(\n uint128 _period,\n uint128 _minPeriod,\n uint128 _maxPeriod\n ) internal pure {\n if (_period >= _maxPeriod || _period <= _minPeriod)\n revert SecurityManager__OutOfBoundary();\n }\n}\n" + }, + "contracts/infrastructure/WhitelistStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {RemoteStorage} from \"./RemoteStorage.sol\";\n\n/**\n * @title Whitelist storage\n * @dev Maps addresses to the corresponsing array of whitelisted addresses for each of them.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract WhitelistStorage is RemoteStorage {\n /**\n * @dev Add the address to the whitelist storage\n * @param _wallet User wallet\n * @param _address Address to be whitelisted\n */\n function whitelistAddress(address _wallet, address _address) external {\n enforceWalletOrGuardianIfExists(_wallet);\n addAddress(_wallet, _address);\n }\n\n /**\n * @dev Removes the address from the whitelist storage\n * @param _wallet User wallet\n * @param _address Address to be removed from the whitelist\n */\n function blacklistAddress(address _wallet, address _address) external {\n enforceGuardianOrWallet(_wallet);\n removeAddress(_wallet, _address);\n }\n\n /**\n * @dev Returns whether the address exists in the whitelist storage, associated with the wallet\n * @param _wallet User wallet\n * @param _address Address to be whitelisted\n */\n function isWhitelisted(\n address _wallet,\n address _address\n ) external view returns (bool) {\n return exists(_wallet, _address);\n }\n\n /**\n * @dev Returns all whitelisted addresses associated with the wallet\n * @param _wallet User wallet\n */\n function getWhitelistedAddresses(\n address _wallet\n ) external view returns (address[] memory) {\n return getAddresses(_wallet);\n }\n}\n" + }, + "contracts/interfaces/ERC/IERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\n\npragma solidity 0.8.21;\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155Receiver {\n /**\n * @dev Handles the receipt of a single ERC1155 token type. This function is\n * called at the end of a `safeTransferFrom` after the balance has been updated.\n *\n * NOTE: To accept the transfer, this must return\n * `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n * (i.e. 0xf23a6e61, or its own function selector).\n *\n * @param operator The address which initiated the transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param id The ID of the token being transferred\n * @param value The amount of tokens being transferred\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n ) external returns (bytes4);\n\n /**\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\n * is called at the end of a `safeBatchTransferFrom` after the balances have\n * been updated.\n *\n * NOTE: To accept the transfer(s), this must return\n * `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n * (i.e. 0xbc197c81, or its own function selector).\n *\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "contracts/interfaces/ERC/IERC1271.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\ninterface IERC1271 {\n function isValidSignature(\n bytes32 hash,\n bytes memory signature\n ) external view returns (bytes4);\n}\n" + }, + "contracts/interfaces/ERC/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\ninterface IERC165 {\n /// @notice Query if a contract implements an interface\n /// @param interfaceId The interface identifier, as specified in ERC-165\n /// @dev Interface identification is specified in ERC-165. This function\n /// uses less than 30,000 gas.\n /// @return `true` if the contract implements `interfaceID` and\n /// `interfaceID` is not 0xffffffff, `false` otherwise\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/IERC173.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\n/// @title ERC-173 Contract Ownership Standard\n/// Note: the ERC-165 identifier for this interface is 0x7f5828d0\n/* is ERC165 */\ninterface IERC173 {\n /// @dev This emits when ownership of a contract changes.\n event OwnershipTransferred(\n address indexed previousOwner,\n address indexed newOwner\n );\n\n /// @notice Get the address of the owner\n /// @return owner_ The address of the owner.\n function owner() external view returns (address owner_);\n\n /// @notice Set the address of the new owner of the contract\n /// @dev Set _newOwner to address(0) to renounce any ownership.\n /// @param _newOwner The address of the new owner of the contract\n function transferOwnership(address _newOwner) external;\n}\n" + }, + "contracts/interfaces/ERC/IERC677Receiver.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\ninterface IERC677Receiver {\n function onTokenTransfer(\n address sender,\n uint value,\n bytes calldata data\n ) external pure returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155 is IERC165 {\n /**\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n */\n event TransferSingle(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256 id,\n uint256 value\n );\n\n /**\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n * transfers.\n */\n event TransferBatch(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\n\n /**\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n * `approved`.\n */\n event ApprovalForAll(\n address indexed account,\n address indexed operator,\n bool approved\n );\n\n /**\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n *\n * If an {URI} event was emitted for `id`, the standard\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n * returned by {IERC1155MetadataURI-uri}.\n */\n event URI(string value, uint256 indexed id);\n\n /**\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(\n address account,\n uint256 id\n ) external view returns (uint256);\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] calldata accounts,\n uint256[] calldata ids\n ) external view returns (uint256[] memory);\n\n /**\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n *\n * Emits an {ApprovalForAll} event.\n *\n * Requirements:\n *\n * - `operator` cannot be the caller.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n *\n * See {setApprovalForAll}.\n */\n function isApprovedForAll(\n address account,\n address operator\n ) external view returns (bool);\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes calldata data\n ) external;\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(\n address indexed owner,\n address indexed spender,\n uint256 value\n );\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` 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 amount) 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(\n address owner,\n address spender\n ) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the 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 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` 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(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(\n address spender,\n uint256 addedValue\n ) external returns (bool);\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(\n address spender,\n uint256 subtractedValue\n ) external returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(\n address indexed from,\n address indexed to,\n uint256 indexed tokenId\n );\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(\n address indexed owner,\n address indexed approved,\n uint256 indexed tokenId\n );\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(\n address indexed owner,\n address indexed operator,\n bool approved\n );\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(\n uint256 tokenId\n ) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(\n address owner,\n address operator\n ) external view returns (bool);\n}\n" + }, + "contracts/interfaces/IBarz.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Barz Interface\n * @dev Interface of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IBarz {\n error Barz__InitializationFailure();\n}\n" + }, + "contracts/interfaces/IBarzFactory.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Barz} from \"../Barz.sol\";\n\n/**\n * @title Barz Factory Interface\n * @dev Interface of contract to easily deploy Barz to a pre-computed address with a single call\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IBarzFactory {\n event BarzDeployed(address);\n\n function createAccount(\n address verificationFacet,\n bytes calldata owner,\n uint256 salt\n ) external returns (Barz);\n\n function getAddress(\n address verificationFacet,\n bytes calldata owner,\n uint256 salt\n ) external view returns (address);\n\n function getBytecode(\n address accountFacet,\n address verificationFacet,\n address entryPoint,\n address facetRegistry,\n address defaultFallback,\n bytes memory ownerPublicKey\n ) external pure returns (bytes memory);\n\n function getCreationCode() external pure returns (bytes memory);\n}\n" + }, + "contracts/libraries/DefaultLibDiamond.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\n\nerror InitializationFunctionReverted(\n address _initializationContractAddress,\n bytes _calldata\n);\n\nlibrary DefaultLibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION =\n keccak256(\"trustwallet.barz.diamond.storage\");\n\n struct FacetAddressAndPosition {\n address facetAddress;\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\n }\n\n struct FacetFunctionSelectors {\n bytes4[] functionSelectors;\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\n }\n\n struct DiamondStorage {\n // maps function selector to the facet address and\n // the position of the selector in the facetFunctionSelectors.selectors array\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\n // maps facet addresses to function selectors\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\n // facet addresses\n address[] facetAddresses;\n // Used to query if a contract implements an interface.\n // Used to implement ERC-165.\n mapping(bytes4 => bool) supportedInterfaces;\n }\n\n function diamondStorage()\n internal\n pure\n returns (DiamondStorage storage ds)\n {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n event DiamondCut(\n IDiamondCut.FacetCut[] _diamondCut,\n address _init,\n bytes _calldata\n );\n\n // Internal function version of diamondCut\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n for (\n uint256 facetIndex;\n facetIndex < _diamondCut.length;\n facetIndex++\n ) {\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\n if (action == IDiamondCut.FacetCutAction.Add) {\n addFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\n replaceFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\n removeFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else {\n revert(\"LibDiamondCut: Incorrect FacetCutAction\");\n }\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Add facet can't be address(0)\"\n );\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n require(\n oldFacetAddress == address(0),\n \"LibDiamondCut: Can't add function that already exists\"\n );\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function replaceFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Replace facet can't be address(0)\"\n );\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n require(\n oldFacetAddress != _facetAddress,\n \"LibDiamondCut: Can't replace function with same facet\"\n );\n removeFunction(ds, oldFacetAddress, selector);\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function removeFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n // if function does not exist then do nothing and return\n require(\n _facetAddress == address(0),\n \"LibDiamondCut: Remove facet address must be address(0)\"\n );\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n removeFunction(ds, oldFacetAddress, selector);\n }\n }\n\n function addFacet(\n DiamondStorage storage ds,\n address _facetAddress\n ) internal {\n enforceHasContractCode(\n _facetAddress,\n \"LibDiamondCut: New facet has no code\"\n );\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds\n .facetAddresses\n .length;\n ds.facetAddresses.push(_facetAddress);\n }\n\n function addFunction(\n DiamondStorage storage ds,\n bytes4 _selector,\n uint96 _selectorPosition,\n address _facetAddress\n ) internal {\n ds\n .selectorToFacetAndPosition[_selector]\n .functionSelectorPosition = _selectorPosition;\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(\n _selector\n );\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\n }\n\n function removeFunction(\n DiamondStorage storage ds,\n address _facetAddress,\n bytes4 _selector\n ) internal {\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Can't remove function that doesn't exist\"\n );\n // an immutable function is a function defined directly in a diamond\n require(\n _facetAddress != address(this),\n \"LibDiamondCut: Can't remove immutable function\"\n );\n // replace selector with last selector, then delete last selector\n uint256 selectorPosition = ds\n .selectorToFacetAndPosition[_selector]\n .functionSelectorPosition;\n uint256 lastSelectorPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors\n .length - 1;\n // if not the same then replace _selector with lastSelector\n if (selectorPosition != lastSelectorPosition) {\n bytes4 lastSelector = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors[lastSelectorPosition];\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[\n selectorPosition\n ] = lastSelector;\n ds\n .selectorToFacetAndPosition[lastSelector]\n .functionSelectorPosition = uint96(selectorPosition);\n }\n // delete the last selector\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\n delete ds.selectorToFacetAndPosition[_selector];\n\n // if no more selectors for facet address then delete the facet address\n if (lastSelectorPosition == 0) {\n // replace facet address with last facet address and delete last facet address\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\n uint256 facetAddressPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .facetAddressPosition;\n if (facetAddressPosition != lastFacetAddressPosition) {\n address lastFacetAddress = ds.facetAddresses[\n lastFacetAddressPosition\n ];\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\n ds\n .facetFunctionSelectors[lastFacetAddress]\n .facetAddressPosition = facetAddressPosition;\n }\n ds.facetAddresses.pop();\n delete ds\n .facetFunctionSelectors[_facetAddress]\n .facetAddressPosition;\n }\n }\n\n function initializeDiamondCut(\n address _init,\n bytes memory _calldata\n ) internal {\n if (_init == address(0)) {\n return;\n }\n enforceHasContractCode(\n _init,\n \"LibDiamondCut: _init address has no code\"\n );\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length > 0) {\n // bubble up error\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(error)\n revert(add(32, error), returndata_size)\n }\n } else {\n revert InitializationFunctionReverted(_init, _calldata);\n }\n }\n }\n\n function enforceHasContractCode(\n address _contract,\n string memory _errorMessage\n ) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize > 0, _errorMessage);\n }\n}\n" + }, + "contracts/libraries/LibAppStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SafeCast} from \"@openzeppelin/contracts/utils/math/SafeCast.sol\";\nimport {IEntryPoint} from \"../aa-4337/interfaces/IEntryPoint.sol\";\nimport {IFacetRegistry} from \"../infrastructure/interfaces/IFacetRegistry.sol\";\n\n/*\n * @title App Storage\n * @dev App storage for Barz contract to prevent storage collision\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\n\nstruct Lock {\n uint64 release;\n bytes4 locker;\n}\n\nstruct InitializersStorage {\n // NOTE: initialized is a variable to make sure the initialization is only done once.\n uint8 signerInitialized;\n uint8 accountInitialized;\n uint8 restrictionsInitialized;\n}\n\nstruct AppStorage {\n mapping(uint256 => InitializersStorage) initStorage;\n uint8 signerMigration;\n bytes4 validateOwnerSignatureSelector;\n IEntryPoint entryPoint;\n IFacetRegistry facetRegistry;\n mapping(uint256 => Lock) locks;\n}\n\nlibrary LibAppStorage {\n error LibAppStorage__AccountAlreadyUninitialized();\n error LibAppStorage__AccountMustBeUninitialized();\n error LibAppStorage__SignerAlreadyUninitialized();\n error LibAppStorage__SignerMustBeUninitialized();\n\n function appStorage() internal pure returns (AppStorage storage ds) {\n assembly {\n ds.slot := 0\n }\n }\n\n function setSignerUninitialized() internal {\n AppStorage storage s = appStorage();\n if (1 != s.initStorage[0].signerInitialized) {\n revert LibAppStorage__SignerAlreadyUninitialized();\n }\n s.initStorage[0].signerInitialized = 0;\n }\n\n function getValidateOwnerSignatureSelector()\n internal\n view\n returns (bytes4 selector)\n {\n selector = appStorage().validateOwnerSignatureSelector;\n }\n\n function setValidateOwnerSignatureSelector(\n bytes4 _validateOwnerSignatureSelector\n ) internal {\n appStorage()\n .validateOwnerSignatureSelector = _validateOwnerSignatureSelector;\n }\n\n function enforceSignerInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].signerInitialized) {\n revert LibAppStorage__SignerMustBeUninitialized();\n }\n s.initStorage[0].signerInitialized = 1;\n }\n\n function enforceAccountInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].accountInitialized) {\n revert LibAppStorage__AccountMustBeUninitialized();\n }\n s.initStorage[0].accountInitialized = 1;\n }\n\n function initiateSignerMigration() internal {\n appStorage().signerMigration = 1;\n }\n\n function enforceSignerMigration() internal view {\n if (1 != appStorage().signerMigration) {\n revert LibAppStorage__AccountMustBeUninitialized();\n }\n }\n\n function finalizeSignerMigration() internal {\n appStorage().signerMigration = 0;\n }\n\n function setLock(uint256 _releaseAfter, bytes4 _locker) internal {\n appStorage().locks[0] = Lock(SafeCast.toUint64(_releaseAfter), _locker);\n }\n\n function enforceRestrictionsInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].restrictionsInitialized)\n revert LibAppStorage__SignerMustBeUninitialized();\n s.initStorage[0].restrictionsInitialized = 1;\n }\n\n function setRestrictionsUninitialized() internal {\n AppStorage storage s = appStorage();\n if (1 != s.initStorage[0].restrictionsInitialized)\n revert LibAppStorage__AccountAlreadyUninitialized();\n s.initStorage[0].restrictionsInitialized = 0;\n }\n}\n\ncontract BarzStorage {\n AppStorage internal s;\n modifier onlyWhenUnlocked() {\n require(\n uint64(block.timestamp) >= s.locks[0].release,\n \"Account Locked\"\n );\n _;\n }\n modifier onlyWhenLocked() {\n require(\n uint64(block.timestamp) < s.locks[0].release,\n \"Account Unlocked\"\n );\n _;\n }\n}\n" + }, + "contracts/libraries/LibDiamond.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\n\nerror InitializationFunctionReverted(\n address _initializationContractAddress,\n bytes _calldata\n);\n\nlibrary LibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION =\n keccak256(\"trustwallet.barz.diamond.storage\");\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\n bytes4(keccak256(\"verifyRestrictions(address,address,uint256,bytes)\"));\n struct DiamondStorage {\n // maps function selectors to the facets that execute the functions.\n // and maps the selectors to their position in the selectorSlots array.\n // func selector => address facet, selector position\n mapping(bytes4 => bytes32) facets;\n // array of slots of function selectors.\n // each slot holds 8 function selectors.\n mapping(uint256 => bytes32) selectorSlots;\n // The number of function selectors in selectorSlots\n uint16 selectorCount;\n // Used to query if a contract implements an interface.\n // Used to implement ERC-165.\n mapping(bytes4 => bool) supportedInterfaces;\n // Default Fallback Handler of the barz.\n IDiamondLoupe defaultFallbackHandler;\n }\n\n function diamondStorage()\n internal\n pure\n returns (DiamondStorage storage ds)\n {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n function enforceIsSelf() internal view {\n require(msg.sender == address(this), \"LibDiamond: Caller not self\");\n }\n\n event DiamondCut(\n IDiamondCut.FacetCut[] _diamondCut,\n address _init,\n bytes _calldata\n );\n\n bytes32 constant CLEAR_ADDRESS_MASK =\n bytes32(uint256(0xffffffffffffffffffffffff));\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\n\n // Internal function version of diamondCut\n // This code is almost the same as the external diamondCut,\n // except it is using 'Facet[] memory _diamondCut' instead of\n // 'Facet[] calldata _diamondCut'.\n // The code is duplicated to prevent copying calldata to memory which\n // causes an error for a two dimensional array.\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n DiamondStorage storage ds = diamondStorage();\n uint256 originalSelectorCount = ds.selectorCount;\n uint256 selectorCount = originalSelectorCount;\n bytes32 selectorSlot;\n // Check if last selector slot is not full\n // \"selectorCount & 7\" is a gas efficient modulo by eight \"selectorCount % 8\"\n if (selectorCount & 7 > 0) {\n // get last selectorSlot\n // \"selectorSlot >> 3\" is a gas efficient division by 8 \"selectorSlot / 8\"\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\n }\n // loop through diamond cut\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\n selectorCount,\n selectorSlot,\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].action,\n _diamondCut[facetIndex].functionSelectors\n );\n\n unchecked {\n facetIndex++;\n }\n }\n if (selectorCount != originalSelectorCount) {\n ds.selectorCount = uint16(selectorCount);\n }\n // If last selector slot is not full\n // \"selectorCount & 7\" is a gas efficient modulo by eight \"selectorCount % 8\"\n if (selectorCount & 7 > 0) {\n // \"selectorSlot >> 3\" is a gas efficient division by 8 \"selectorSlot / 8\"\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addReplaceRemoveFacetSelectors(\n uint256 _selectorCount,\n bytes32 _selectorSlot,\n address _newFacetAddress,\n IDiamondCut.FacetCutAction _action,\n bytes4[] memory _selectors\n ) internal returns (uint256, bytes32) {\n DiamondStorage storage ds = diamondStorage();\n require(\n _selectors.length > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n if (_action == IDiamondCut.FacetCutAction.Add) {\n enforceHasContractCode(\n _newFacetAddress,\n \"LibDiamondCut: Add facet has no code\"\n );\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n require(\n address(bytes20(oldFacet)) == address(0),\n \"LibDiamondCut: Can't add function that already exists\"\n );\n // add facet for selector\n ds.facets[selector] =\n bytes20(_newFacetAddress) |\n bytes32(_selectorCount);\n // \"_selectorCount & 7\" is a gas efficient modulo by eight \"_selectorCount % 8\"\n // \" << 5 is the same as multiplying by 32 ( * 32)\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\n // clear selector position in slot and add selector\n _selectorSlot =\n (_selectorSlot &\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\n (bytes32(selector) >> selectorInSlotPosition);\n // if slot is full then write it to storage\n if (selectorInSlotPosition == 224) {\n // \"_selectorSlot >> 3\" is a gas efficient division by 8 \"_selectorSlot / 8\"\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\n _selectorSlot = 0;\n }\n _selectorCount++;\n\n unchecked {\n selectorIndex++;\n }\n }\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\n enforceHasContractCode(\n _newFacetAddress,\n \"LibDiamondCut: Replace facet has no code\"\n );\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n address oldFacetAddress = address(bytes20(oldFacet));\n // only useful if immutable functions exist\n require(\n oldFacetAddress != address(this),\n \"LibDiamondCut: Can't replace immutable function\"\n );\n require(\n oldFacetAddress != _newFacetAddress,\n \"LibDiamondCut: Can't replace function with same function\"\n );\n require(\n oldFacetAddress != address(0),\n \"LibDiamondCut: Can't replace function that doesn't exist\"\n );\n // replace old facet address\n ds.facets[selector] =\n (oldFacet & CLEAR_ADDRESS_MASK) |\n bytes20(_newFacetAddress);\n\n unchecked {\n selectorIndex++;\n }\n }\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\n require(\n _newFacetAddress == address(0),\n \"LibDiamondCut: Remove facet address must be address(0)\"\n );\n // \"_selectorCount >> 3\" is a gas efficient division by 8 \"_selectorCount / 8\"\n uint256 selectorSlotCount = _selectorCount >> 3;\n // \"_selectorCount & 7\" is a gas efficient modulo by eight \"_selectorCount % 8\"\n uint256 selectorInSlotIndex = _selectorCount & 7;\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n if (_selectorSlot == 0) {\n // get last selectorSlot\n selectorSlotCount--;\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\n selectorInSlotIndex = 7;\n } else {\n selectorInSlotIndex--;\n }\n bytes4 lastSelector;\n uint256 oldSelectorsSlotCount;\n uint256 oldSelectorInSlotPosition;\n // adding a block here prevents stack too deep error\n {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n require(\n address(bytes20(oldFacet)) != address(0),\n \"LibDiamondCut: Can't remove function that doesn't exist\"\n );\n // only useful if immutable functions exist\n require(\n address(bytes20(oldFacet)) != address(this),\n \"LibDiamondCut: Can't remove immutable function\"\n );\n // replace selector with last selector in ds.facets\n // gets the last selector\n // \" << 5 is the same as multiplying by 32 ( * 32)\n lastSelector = bytes4(\n _selectorSlot << (selectorInSlotIndex << 5)\n );\n if (lastSelector != selector) {\n // update last selector slot position info\n ds.facets[lastSelector] =\n (oldFacet & CLEAR_ADDRESS_MASK) |\n bytes20(ds.facets[lastSelector]);\n }\n delete ds.facets[selector];\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\n // \"oldSelectorCount >> 3\" is a gas efficient division by 8 \"oldSelectorCount / 8\"\n oldSelectorsSlotCount = oldSelectorCount >> 3;\n // \"oldSelectorCount & 7\" is a gas efficient modulo by eight \"oldSelectorCount % 8\"\n // \" << 5 is the same as multiplying by 32 ( * 32)\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\n }\n if (oldSelectorsSlotCount != selectorSlotCount) {\n bytes32 oldSelectorSlot = ds.selectorSlots[\n oldSelectorsSlotCount\n ];\n // clears the selector we are deleting and puts the last selector in its place.\n oldSelectorSlot =\n (oldSelectorSlot &\n ~(CLEAR_SELECTOR_MASK >>\n oldSelectorInSlotPosition)) |\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\n // update storage with the modified slot\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\n } else {\n // clears the selector we are deleting and puts the last selector in its place.\n _selectorSlot =\n (_selectorSlot &\n ~(CLEAR_SELECTOR_MASK >>\n oldSelectorInSlotPosition)) |\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\n }\n if (selectorInSlotIndex == 0) {\n delete ds.selectorSlots[selectorSlotCount];\n _selectorSlot = 0;\n }\n\n unchecked {\n selectorIndex++;\n }\n }\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\n } else {\n revert(\"LibDiamondCut: Incorrect FacetCutAction\");\n }\n return (_selectorCount, _selectorSlot);\n }\n\n function initializeDiamondCut(\n address _init,\n bytes memory _calldata\n ) internal {\n if (_init == address(0)) {\n return;\n }\n enforceHasContractCode(\n _init,\n \"LibDiamondCut: _init address has no code\"\n );\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length > 0) {\n // bubble up error\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(error)\n revert(add(32, error), returndata_size)\n }\n } else {\n revert InitializationFunctionReverted(_init, _calldata);\n }\n }\n }\n\n function enforceHasContractCode(\n address _contract,\n string memory _errorMessage\n ) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize > 0, _errorMessage);\n }\n\n function restrictionsFacet() internal view returns (address facetAddress_) {\n facetAddress_ = address(\n bytes20(\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\n )\n );\n }\n}\n" + }, + "contracts/libraries/LibFacetStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Storage\n * @dev Storage contract to store each facets variables with diamond storage\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\n\nstruct Secp256k1VerificationStorage {\n address signer;\n}\n\nstruct Secp256r1VerificationStorage {\n uint256[2] q;\n}\n\nstruct GuardianStorage {\n mapping(bytes32 => uint256) pending;\n mapping(uint8 => StorageConfig) configs;\n}\n\nstruct Info {\n bool exists;\n uint128 index;\n}\n\nstruct StorageConfig {\n address[] addresses;\n mapping(address => Info) info;\n}\n\nstruct RecoveryConfig {\n bytes recoveryPublicKey;\n uint64 executeAfter;\n}\n\nstruct ApprovalConfig {\n bool isApproved;\n uint64 validUntil;\n}\n\nstruct RecoveryApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isNewOwnerApproved;\n}\n\nstruct RecoveryStorage {\n mapping(uint8 => RecoveryConfig) recoveryConfigs;\n mapping(uint8 => RecoveryApprovalConfig) recoveryApprovalConfigs;\n uint128 nonce;\n}\n\nstruct RestrictionsStorage {\n address[] restrictions;\n mapping(address => bool) exists;\n}\n\nstruct SignatureMigrationConfig {\n bytes migrationPublicKey;\n address migrationVerificationFacet;\n bytes4[] migrationSelectors;\n uint64 migrateAfter;\n}\n\nstruct SignatureMigrationApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isMigrationApproved;\n}\n\nstruct SignatureMigrationStorage {\n mapping(uint8 => SignatureMigrationConfig) migrationConfigs;\n mapping(uint8 => SignatureMigrationApprovalConfig) migrationApprovalConfigs;\n uint128 nonce;\n}\n\nstruct DiamondCutApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isDiamondCutApproved;\n}\n\nstruct DiamondCutStorage {\n mapping(uint8 => DiamondCutApprovalConfig) diamondCutApprovalConfigs;\n uint128 nonce;\n}\n\nstruct LockStorage {\n uint128 nonce;\n}\n\nlibrary LibFacetStorage {\n bytes32 constant K1_STORAGE_POSITION =\n keccak256(\n \"v0.trustwallet.diamond.storage.Secp256k1VerificationStorage\"\n );\n bytes32 constant R1_STORAGE_POSITION =\n keccak256(\n \"v0.trustwallet.diamond.storage.Secp256r1VerificationStorage\"\n );\n bytes32 constant GUARDIAN_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.GuardianStorage\");\n bytes32 constant RECOVERY_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.RecoveryStorage\");\n bytes32 constant RESTRICTION_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.RestrictionsStorage\");\n bytes32 constant MIGRATION_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.SignatureMigrationStorage\");\n bytes32 constant DIAMONDCUT_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.DiamondCutStorage\");\n bytes32 constant LOCK_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.LockStorage\");\n\n function k1Storage()\n internal\n pure\n returns (Secp256k1VerificationStorage storage ds)\n {\n bytes32 storagePosition = K1_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function r1Storage()\n internal\n pure\n returns (Secp256r1VerificationStorage storage ds)\n {\n bytes32 storagePosition = R1_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function guardianStorage()\n internal\n pure\n returns (GuardianStorage storage ds)\n {\n bytes32 storagePosition = GUARDIAN_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function recoveryStorage()\n internal\n pure\n returns (RecoveryStorage storage ds)\n {\n bytes32 storagePosition = RECOVERY_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function restrictionsStorage()\n internal\n pure\n returns (RestrictionsStorage storage ds)\n {\n bytes32 storagePosition = RESTRICTION_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function migrationStorage()\n internal\n pure\n returns (SignatureMigrationStorage storage ds)\n {\n bytes32 storagePosition = MIGRATION_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function diamondCutStorage()\n internal\n pure\n returns (DiamondCutStorage storage ds)\n {\n bytes32 storagePosition = DIAMONDCUT_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function lockStorage() internal pure returns (LockStorage storage ds) {\n bytes32 storagePosition = LOCK_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n}\n" + }, + "contracts/libraries/LibGuardian.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibFacetStorage, StorageConfig} from \"./LibFacetStorage.sol\";\n\n/**\n * @title LibGuardian\n * @dev Internal Library to provide utility feature for Guardians stored in Guardian Facet Storage\n * @author David Yongjun Kim (@Powerstream3604)\n */\nlibrary LibGuardian {\n function majorityOfGuardians()\n internal\n view\n returns (uint256 guardianNumber)\n {\n uint256 guardianLength = guardianCount();\n guardianNumber = (guardianLength == 0) ? 0 : guardianLength / 2 + 1;\n }\n\n function isGuardian(address _guardian) internal view returns (bool) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n return config.info[_guardian].exists;\n }\n\n function guardianCount() internal view returns (uint256) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n return config.addresses.length;\n }\n\n function getGuardians() internal view returns (address[] memory) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n address[] memory addresses = new address[](config.addresses.length);\n uint256 addressesLen = config.addresses.length;\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n return addresses;\n }\n}\n" + }, + "contracts/libraries/LibLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {LibDiamond} from \"./LibDiamond.sol\";\n\n/**\n * @title LibLoupe\n * @dev Internal Library to provide utility feature for reading the state of diamond facets\n * Originally from Diamond's implementation of Mudgen(author of EIP-2535)\n */\nlibrary LibLoupe {\n /// @notice Gets all facets and their selectors.\n /// @return facets_ Facet\n function facets()\n internal\n view\n returns (IDiamondLoupe.Facet[] memory facets_)\n {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facets_ = new IDiamondLoupe.Facet[](ds.selectorCount);\n uint16[] memory numFacetSelectors = new uint16[](ds.selectorCount);\n uint256 numFacets;\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facetAddress_ = address(bytes20(ds.facets[selector]));\n bool continueLoop;\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n if (facets_[facetIndex].facetAddress == facetAddress_) {\n facets_[facetIndex].functionSelectors[\n numFacetSelectors[facetIndex]\n ] = selector;\n // probably will never have more than 256 functions from one facet contract\n require(numFacetSelectors[facetIndex] < 255);\n numFacetSelectors[facetIndex]++;\n continueLoop = true;\n break;\n }\n }\n if (continueLoop) {\n continue;\n }\n facets_[numFacets].facetAddress = facetAddress_;\n facets_[numFacets].functionSelectors = new bytes4[](\n ds.selectorCount\n );\n facets_[numFacets].functionSelectors[0] = selector;\n numFacetSelectors[numFacets] = 1;\n numFacets++;\n }\n }\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n uint256 numSelectors = numFacetSelectors[facetIndex];\n bytes4[] memory selectors = facets_[facetIndex].functionSelectors;\n // setting the number of selectors\n assembly {\n mstore(selectors, numSelectors)\n }\n }\n // setting the number of facets\n assembly {\n mstore(facets_, numFacets)\n }\n }\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n /// @return _facetFunctionSelectors The selectors associated with a facet address.\n function facetFunctionSelectors(\n address _facet\n ) internal view returns (bytes4[] memory _facetFunctionSelectors) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n uint256 numSelectors;\n _facetFunctionSelectors = new bytes4[](ds.selectorCount);\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facet = address(bytes20(ds.facets[selector]));\n if (_facet == facet) {\n _facetFunctionSelectors[numSelectors] = selector;\n numSelectors++;\n }\n }\n }\n // Set the number of selectors in the array\n assembly {\n mstore(_facetFunctionSelectors, numSelectors)\n }\n }\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses()\n internal\n view\n returns (address[] memory facetAddresses_)\n {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facetAddresses_ = new address[](ds.selectorCount);\n uint256 numFacets;\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facetAddress_ = address(bytes20(ds.facets[selector]));\n bool continueLoop;\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n if (facetAddress_ == facetAddresses_[facetIndex]) {\n continueLoop = true;\n break;\n }\n }\n if (continueLoop) {\n continue;\n }\n facetAddresses_[numFacets] = facetAddress_;\n numFacets++;\n }\n }\n // Set the number of facet addresses in the array\n assembly {\n mstore(facetAddresses_, numFacets)\n }\n }\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(\n bytes4 _functionSelector\n ) internal view returns (address facetAddress_) {\n facetAddress_ = address(\n bytes20(LibDiamond.diamondStorage().facets[_functionSelector])\n );\n }\n}\n" + }, + "contracts/libraries/LibMultiSigStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Multi-sig Storage\n * @dev Storage contract for storing Multi-sig Facet variables in diamond storage pattern\n * @author David Yongjun Kim (@Powerstream3604)\n */\n\nstruct MultiSigStorage {\n mapping(address => address) owners;\n mapping(uint256 => mapping(address => mapping(bytes32 => uint256))) approvedHashes;\n uint256 ownerCount;\n uint256 threshold;\n uint256 counter;\n}\n\nlibrary LibMultiSigStorage {\n function multisigStorage()\n internal\n pure\n returns (MultiSigStorage storage ds)\n {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.MultiSigStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n}\n" + }, + "contracts/libraries/LibRecoverSpender.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title RecoverSpender\n * @dev Library to determine the action and spender of calldata\n * @author Ruslan Serebriakov (@rsrbk)\n */\nlibrary LibRecoverSpender {\n // ERC20, ERC721 & ERC1155 transfers & approvals\n bytes4 private constant ERC20_TRANSFER =\n bytes4(keccak256(\"transfer(address,uint256)\"));\n bytes4 private constant ERC20_APPROVE =\n bytes4(keccak256(\"approve(address,uint256)\"));\n bytes4 private constant ERC20_INCREASE_ALLOWANCE =\n bytes4(keccak256(\"increaseAllowance(address,uint256)\"));\n bytes4 private constant ERC20_DECREASE_ALLOWANCE =\n bytes4(keccak256(\"decreaseAllowance(address,uint256)\"));\n bytes4 private constant ERC721_SET_APPROVAL_FOR_ALL =\n bytes4(keccak256(\"setApprovalForAll(address,bool)\"));\n bytes4 private constant ERC721_TRANSFER_FROM =\n bytes4(keccak256(\"transferFrom(address,address,uint256)\"));\n bytes4 private constant ERC721_SAFE_TRANSFER_FROM =\n bytes4(keccak256(\"safeTransferFrom(address,address,uint256)\"));\n bytes4 private constant ERC721_SAFE_TRANSFER_FROM_BYTES =\n bytes4(keccak256(\"safeTransferFrom(address,address,uint256,bytes)\"));\n bytes4 private constant ERC1155_SAFE_TRANSFER_FROM =\n bytes4(\n keccak256(\"safeTransferFrom(address,address,uint256,uint256,bytes)\")\n );\n bytes4 private constant ERC1155_SAFE_BATCH_TRANSFER_FROM =\n bytes4(\n keccak256(\n \"safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)\"\n )\n );\n\n /**\n * @notice Helper method to recover the spender from a contract call.\n * The method returns the contract unless the call is to a standard method of a ERC20/ERC721/ERC1155 token\n * in which case the spender is recovered from the data.\n * @param _to The target contract.\n * @param _data The data payload.\n */\n function _recover(\n address _to,\n bytes memory _data\n ) internal pure returns (address spender) {\n if (_data.length >= 68) {\n bytes4 methodId;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n methodId := mload(add(_data, 0x20))\n }\n if (\n methodId == ERC20_TRANSFER ||\n methodId == ERC20_APPROVE ||\n methodId == ERC20_INCREASE_ALLOWANCE ||\n methodId == ERC20_DECREASE_ALLOWANCE ||\n methodId == ERC721_SET_APPROVAL_FOR_ALL\n ) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n spender := mload(add(_data, 0x24))\n }\n return spender;\n }\n if (\n methodId == ERC721_TRANSFER_FROM ||\n methodId == ERC721_SAFE_TRANSFER_FROM ||\n methodId == ERC721_SAFE_TRANSFER_FROM_BYTES ||\n methodId == ERC1155_SAFE_TRANSFER_FROM ||\n methodId == ERC1155_SAFE_BATCH_TRANSFER_FROM\n ) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n spender := mload(add(_data, 0x44))\n }\n return spender;\n }\n }\n\n spender = _to;\n }\n}\n" + }, + "contracts/libraries/LibUtils.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\n\nlibrary LibUtils {\n // Internal utility functions\n function mergeArrays(\n bytes4[] memory _array1,\n bytes4[] memory _array2\n ) internal pure returns (bytes4[] memory) {\n uint256 length1 = _array1.length;\n uint256 length2 = _array2.length;\n bytes4[] memory mergedArray = new bytes4[](length1 + length2);\n\n for (uint256 i; i < length1; ) {\n mergedArray[i] = _array1[i];\n unchecked {\n ++i;\n }\n }\n\n for (uint256 i; i < length2; ) {\n mergedArray[length1 + i] = _array2[i];\n unchecked {\n ++i;\n }\n }\n\n return mergedArray;\n }\n\n function removeFacetElement(\n IDiamondLoupe.Facet[] memory _facets,\n uint256 _index\n ) internal pure returns (IDiamondLoupe.Facet[] memory) {\n require(_index < _facets.length, \"Invalid index\");\n require(_facets.length != 0, \"Invalid array\");\n\n // Create a new array with a length of `_facets.length - 1`\n IDiamondLoupe.Facet[] memory newArray = new IDiamondLoupe.Facet[](\n _facets.length - 1\n );\n uint256 newArrayLength = newArray.length;\n // Iterate over the original array, skipping the element at the specified `index`\n for (uint256 i; i < newArrayLength; ) {\n if (i < _index) {\n newArray[i] = _facets[i];\n } else {\n newArray[i] = _facets[i + 1];\n }\n unchecked {\n ++i;\n }\n }\n\n return newArray;\n }\n\n function removeElement(\n bytes4[] memory _array,\n uint256 _index\n ) internal pure returns (bytes4[] memory) {\n require(_index < _array.length, \"Invalid index\");\n require(_array.length != 0, \"Invalid array\");\n\n bytes4[] memory newArray = new bytes4[](_array.length - 1);\n uint256 newArrayLength = newArray.length;\n for (uint256 i; i < newArrayLength; ) {\n if (i < _index) {\n newArray[i] = _array[i];\n } else {\n newArray[i] = _array[i + 1];\n }\n unchecked {\n ++i;\n }\n }\n\n return newArray;\n }\n\n function setValue(\n bytes4[] memory _keys,\n address[] memory _values,\n bytes4 _key,\n address _value\n ) internal pure returns (bytes4[] memory, address[] memory) {\n uint256 index = findIndex(_keys, _key);\n uint256 keysLength = _keys.length;\n if (index < keysLength) {\n _values[index] = _value;\n } else {\n // Create new storage arrays\n bytes4[] memory newKeys = new bytes4[](keysLength + 1);\n address[] memory newValues = new address[](_values.length + 1);\n\n // Copy values to the new storage arrays\n for (uint256 i; i < keysLength; ) {\n newKeys[i] = _keys[i];\n newValues[i] = _values[i];\n\n unchecked {\n ++i;\n }\n }\n\n // Add the new key-value pair\n newKeys[keysLength] = _key;\n newValues[_values.length] = _value;\n\n return (newKeys, newValues);\n }\n\n // If the key already exists, return the original arrays\n return (_keys, _values);\n }\n\n function getValue(\n bytes4[] memory _keys,\n address[] memory _values,\n bytes4 _key\n ) internal pure returns (address) {\n uint256 index = findIndex(_keys, _key);\n if (index >= _keys.length) return address(0);\n\n return _values[index];\n }\n\n function findIndex(\n bytes4[] memory _keys,\n bytes4 _key\n ) internal pure returns (uint256) {\n uint256 keysLength = _keys.length;\n for (uint256 i; i < keysLength; ) {\n if (_keys[i] == _key) {\n return i;\n }\n unchecked {\n ++i;\n }\n }\n return keysLength;\n }\n}\n" + }, + "contracts/restrictions/IRestriction.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Interface for restrictions\n * @dev Restriction is a contract which decides whether to approve a certain kind of transaction, based on its internal logic.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface IRestriction {\n /**\n * @dev Based on restriction's internal logic, it should accept or reject a certain transaction.\n * @param from The address of the sender, that will be signing the transaction.\n * @param to The receiving address.\n * @param value Amount of ETH to transfer from sender to recipient.\n * @param _calldata Optional field to include arbitrary data.\n * @return bool value for whether the check is passed\n */\n function check(\n address from,\n address to,\n uint256 value,\n bytes calldata _calldata\n ) external returns (bool);\n}\n" + }, + "contracts/restrictions/WhitelistRestriction.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibRecoverSpender} from \"../libraries/LibRecoverSpender.sol\";\nimport {WhitelistStorage} from \"../infrastructure/WhitelistStorage.sol\";\nimport {IRestriction} from \"./IRestriction.sol\";\n\n/**\n * @title Whitelist Restriction\n * @dev This restriction defines a list of accepted addresses and denies any interaction with addresses outside of it.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract WhitelistRestriction is IRestriction {\n WhitelistStorage public immutable whitelistStorage;\n\n constructor(WhitelistStorage _whitelistStorage) {\n whitelistStorage = _whitelistStorage;\n }\n\n /**\n * @notice Helper method to recover the spender from a contract call.\n * The method returns the contract unless the call is to a standard method of a ERC20/ERC721/ERC1155 token\n * in which case the spender is recovered from the data.\n * @param _to The target contract.\n * @param _data The data payload.\n */\n function recoverSpender(\n address _to,\n bytes memory _data\n ) public pure returns (address spender) {\n return LibRecoverSpender._recover(_to, _data);\n }\n\n /*\n * @dev IRestriction's implementation. It will allow transaction if the sender is whitelisted, or user, or the whitelist storage.\n * @param _from The address of the sender, that will be signing the transaction.\n * @param _to The receiving address.\n * @param _calldata Optional field to include arbitrary data.\n * @return result value for whether the check is passed\n */\n function check(\n address _from,\n address _to,\n uint256 /*_value*/,\n bytes calldata _calldata\n ) external view override returns (bool result) {\n return\n whitelistStorage.isWhitelisted(\n _from,\n LibRecoverSpender._recover(_to, _calldata)\n ) ||\n _to == address(whitelistStorage) ||\n _to == msg.sender;\n }\n}\n" + }, + "contracts/test/Counter.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\ncontract TestCounter {\n int private count = 0;\n\n function incrementCounter() public {\n count += 1;\n }\n\n function decrementCounter() public {\n count -= 1;\n }\n\n function getCount() public view returns (int) {\n return count;\n }\n}\n" + }, + "contracts/test/TestERC1155.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC1155/ERC1155.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\n\ncontract TestERC1155 is ERC1155 {\n using Counters for Counters.Counter;\n\n Counters.Counter private _tokenIds;\n\n constructor() ERC1155(\"\") {}\n\n function mint(address account, uint256 amount) external {\n uint256 tokenId = _getNextTokenId();\n _mint(account, tokenId, amount, \"\");\n }\n\n function mintBatch(\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes memory data\n ) external {\n require(\n ids.length == amounts.length,\n \"TestERC1155: arrays length mismatch\"\n );\n\n _mintBatch(to, ids, amounts, data);\n }\n\n function _getNextTokenId() private returns (uint256) {\n _tokenIds.increment();\n return _tokenIds.current();\n }\n}\n" + }, + "contracts/test/TestERC777.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC777/ERC777.sol\";\n\ncontract TestERC777 is ERC777 {\n constructor(\n address[] memory _operators\n ) ERC777(\"TestERC777\", \"TERC777\", _operators) {}\n\n function mint(address account, uint256 amount) external {\n _mint(account, amount, \"\", \"\");\n }\n}\n" + }, + "contracts/test/TestInvalidSecp256k1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IVerificationFacet} from \"../facets/interfaces/IVerificationFacet.sol\";\nimport {IERC1271} from \"../interfaces/ERC/IERC1271.sol\";\nimport {AppStorage, LibAppStorage, BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {LibFacetStorage, Secp256k1VerificationStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {UserOperation} from \"../aa-4337/interfaces/UserOperation.sol\";\n\n/**\n * @title Test Secp256k1 verification facet\n * @dev Default Ethereum's elliptic curve\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract TestInvalidSecp256k1VerificationFacet is BarzStorage, IERC1271 {\n using ECDSA for bytes32;\n error Secp256k1VerificationFacet__InvalidSignerLength();\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n\n event SignerUninitialized();\n\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n }\n\n // THIS INVALID FACET DOES NOT INCLUDE initializeSigner()\n // THIS FACET IS USED TO TEST WHEN initializeSigner() DOESN'T EXIST IN FACET\n\n function uninitializeSigner() external returns (uint256 uninitSuccess) {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view returns (uint256 validationData) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n return validateSignature(userOp, userOpHash, k1Storage.signer);\n }\n\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n address signer\n ) public pure returns (uint256) {\n bytes32 hash = userOpHash.toEthSignedMessageHash();\n if (signer != hash.recover(userOp.signature)) return 1;\n return 0;\n }\n\n // This is REMOVED for testing purpose\n function validateOwnerSignatureSelector() public pure returns (bytes4) {\n // return this.validateOwnerSignature.selector;\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n function owner() public view returns (bytes memory) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n return abi.encodePacked(k1Storage.signer);\n }\n\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure returns (bool) {\n return (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (_hash.recover(_signature) ==\n LibFacetStorage.k1Storage().signer)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n}\n" + }, + "contracts/test/TestNFT.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\n\ncontract TestNFT is ERC721 {\n using Counters for Counters.Counter;\n Counters.Counter private currentTokenId;\n\n constructor() ERC721(\"TestNFT\", \"TNFT\") {}\n\n function mint(address recipient) public returns (uint256) {\n currentTokenId.increment();\n uint256 newItemId = currentTokenId.current();\n _safeMint(recipient, newItemId);\n return newItemId;\n }\n}\n" + }, + "contracts/test/TestToken.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract TestToken is ERC20 {\n constructor()\n // solhint-disable-next-line no-empty-blocks\n ERC20(\"TST\", \"TestToken\")\n {}\n\n function mint(address sender, uint256 amount) external {\n _mint(sender, amount);\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 999999 + }, + "evmVersion": "paris", + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/deployments/blast/.chainId b/deployments/blast/.chainId new file mode 100644 index 0000000..0b5f0e0 --- /dev/null +++ b/deployments/blast/.chainId @@ -0,0 +1 @@ +81457 \ No newline at end of file diff --git a/deployments/blast/AccountFacet.json b/deployments/blast/AccountFacet.json new file mode 100644 index 0000000..3510cc6 --- /dev/null +++ b/deployments/blast/AccountFacet.json @@ -0,0 +1,591 @@ +{ + "address": "0xFde53272dcd7938d16E031A6989753c321728332", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "AccountFacet__CallNotSuccessful", + "type": "error" + }, + { + "inputs": [], + "name": "AccountFacet__InitializationFailure", + "type": "error" + }, + { + "inputs": [], + "name": "AccountFacet__InvalidArrayLength", + "type": "error" + }, + { + "inputs": [], + "name": "AccountFacet__NonExistentVerificationFacet", + "type": "error" + }, + { + "inputs": [], + "name": "AccountFacet__RestrictionsFailure", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_initializationContractAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "InitializationFunctionReverted", + "type": "error" + }, + { + "inputs": [], + "name": "LibAppStorage__AccountMustBeUninitialized", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract IEntryPoint", + "name": "entryPoint", + "type": "address" + }, + { + "indexed": true, + "internalType": "bytes", + "name": "ownerPublicKey", + "type": "bytes" + } + ], + "name": "AccountInitialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "indexed": false, + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "DiamondCut", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "VerificationFailure", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "VerificationSuccess", + "type": "event" + }, + { + "inputs": [], + "name": "entryPoint", + "outputs": [ + { + "internalType": "contract IEntryPoint", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_dest", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_func", + "type": "bytes" + } + ], + "name": "execute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_dest", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "_value", + "type": "uint256[]" + }, + { + "internalType": "bytes[]", + "name": "_func", + "type": "bytes[]" + } + ], + "name": "executeBatch", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getNonce", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_verificationFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_anEntryPoint", + "type": "address" + }, + { + "internalType": "address", + "name": "_facetRegistry", + "type": "address" + }, + { + "internalType": "address", + "name": "_defaultFallBackHandler", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_ownerPublicKey", + "type": "bytes" + } + ], + "name": "initialize", + "outputs": [ + { + "internalType": "uint256", + "name": "initSuccess", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "initCode", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "callGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "verificationGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "preVerificationGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxFeePerGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPriorityFeePerGas", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "paymasterAndData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "internalType": "struct UserOperation", + "name": "userOp", + "type": "tuple" + }, + { + "internalType": "bytes32", + "name": "userOpHash", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "missingAccountFunds", + "type": "uint256" + } + ], + "name": "validateUserOp", + "outputs": [ + { + "internalType": "uint256", + "name": "validationData", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0xd20e4f5c079d783b708fa70bf4e49e18ffedf23ab0c3477e353d51d64d8c9e3d", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 15, + "gasUsed": "2370628", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0xea703e2184860b16141a4707cb03276efeee46de934c375c61ac43ff72adf24d", + "transactionHash": "0xd20e4f5c079d783b708fa70bf4e49e18ffedf23ab0c3477e353d51d64d8c9e3d", + "logs": [], + "blockNumber": 1317772, + "cumulativeGasUsed": "7485241", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "ad34345aa73d96f52b3e14df983b6b29", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AccountFacet__CallNotSuccessful\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AccountFacet__InitializationFailure\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AccountFacet__InvalidArrayLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AccountFacet__NonExistentVerificationFacet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AccountFacet__RestrictionsFailure\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_initializationContractAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"InitializationFunctionReverted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LibAppStorage__AccountMustBeUninitialized\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract IEntryPoint\",\"name\":\"entryPoint\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes\",\"name\":\"ownerPublicKey\",\"type\":\"bytes\"}],\"name\":\"AccountInitialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"DiamondCut\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"VerificationFailure\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"VerificationSuccess\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"entryPoint\",\"outputs\":[{\"internalType\":\"contract IEntryPoint\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_dest\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_func\",\"type\":\"bytes\"}],\"name\":\"execute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_dest\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"_value\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes[]\",\"name\":\"_func\",\"type\":\"bytes[]\"}],\"name\":\"executeBatch\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_verificationFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_anEntryPoint\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_facetRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_defaultFallBackHandler\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_ownerPublicKey\",\"type\":\"bytes\"}],\"name\":\"initialize\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"initSuccess\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"userOp\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"missingAccountFunds\",\"type\":\"uint256\"}],\"name\":\"validateUserOp\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"validationData\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"Account module contract that provides the account features and initialization of signer compatible with EIP-1271 & EIP-4337\",\"kind\":\"dev\",\"methods\":{\"execute(address,uint256,bytes)\":{\"details\":\"This method executes the calldata coming from the EntryPoint. Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\",\"params\":{\"_dest\":\"Address of destination where the call will be forwarded to\",\"_func\":\"Bytes of calldata to execute in the destination address\",\"_value\":\"Amount of native coin the owner is willing to send(e.g. ETH, BNB)\"}},\"executeBatch(address[],uint256[],bytes[])\":{\"details\":\"This method batch executes the calldata coming from the EntryPoint. Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\",\"params\":{\"_dest\":\"Array of addresses of destination where the call will be forwarded to\",\"_func\":\"Array of bytes of calldata to execute in the destination address\",\"_value\":\"Array of amount of native coin the owner is willing to send(e.g. ETH, BNB)\"}},\"initialize(address,address,address,address,bytes)\":{\"details\":\"This method can only be called during the initialization or signature migration. If the proxy contract was created without initialization, anyone can call initialize. Barz calls initialize in constructor in an atomic transaction during deployment\",\"params\":{\"_anEntryPoint\":\"Entrypoint contract defined in EIP-4337 handling the flow of UserOp\",\"_defaultFallBackHandler\":\"Middleware contract for default facets\",\"_facetRegistry\":\"Registry of Facets that hold all facet information\",\"_ownerPublicKey\":\"Bytes of owner public key\",\"_verificationFacet\":\"Facet contract handling the verificationi\"}}},\"title\":\"Account Facet\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"This constructor ensures that this contract can only be used as singleton for Proxy contracts\"},\"entryPoint()\":{\"notice\":\"Returns the address of EntryPoint contract registered to Barz account\"},\"execute(address,uint256,bytes)\":{\"notice\":\"Calls the destination with inputted calldata and value from EntryPoint\"},\"executeBatch(address[],uint256[],bytes[])\":{\"notice\":\"Batch calls the destination with inputted calldata and value from EntryPoint\"},\"getNonce()\":{\"notice\":\"Return the account nonce. This method returns the next sequential nonce. For a nonce of a specific key, use `entrypoint.getNonce(account, key)`\"},\"initialize(address,address,address,address,bytes)\":{\"notice\":\"Initializes the initial storage of the Barz contract.\"},\"validateUserOp((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256)\":{\"notice\":\"Validate user's signature and nonce. subclass doesn't need to override this method. Instead, it should override the specific internal validation methods.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/AccountFacet.sol\":\"AccountFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./math/Math.sol\\\";\\nimport \\\"./math/SignedMath.sol\\\";\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n uint256 length = Math.log10(value) + 1;\\n string memory buffer = new string(length);\\n uint256 ptr;\\n /// @solidity memory-safe-assembly\\n assembly {\\n ptr := add(buffer, add(32, length))\\n }\\n while (true) {\\n ptr--;\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\\n }\\n value /= 10;\\n if (value == 0) break;\\n }\\n return buffer;\\n }\\n }\\n\\n /**\\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\\n */\\n function toString(int256 value) internal pure returns (string memory) {\\n return string(abi.encodePacked(value < 0 ? \\\"-\\\" : \\\"\\\", toString(SignedMath.abs(value))));\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n return toHexString(value, Math.log256(value) + 1);\\n }\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n\\n /**\\n * @dev Returns true if the two strings are equal.\\n */\\n function equal(string memory a, string memory b) internal pure returns (bool) {\\n return keccak256(bytes(a)) == keccak256(bytes(b));\\n }\\n}\\n\",\"keccak256\":\"0x3088eb2868e8d13d89d16670b5f8612c4ab9ff8956272837d8e90106c59c14a0\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Strings.sol\\\";\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSA {\\n enum RecoverError {\\n NoError,\\n InvalidSignature,\\n InvalidSignatureLength,\\n InvalidSignatureS,\\n InvalidSignatureV // Deprecated in v4.8\\n }\\n\\n function _throwError(RecoverError error) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert(\\\"ECDSA: invalid signature\\\");\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert(\\\"ECDSA: invalid signature length\\\");\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert(\\\"ECDSA: invalid signature 's' value\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature` or error string. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n *\\n * Documentation for signature generation:\\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n return tryRecover(hash, v, r, s);\\n } else {\\n return (address(0), RecoverError.InvalidSignatureLength);\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature`. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, signature);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\\n uint8 v = uint8((uint256(vs) >> 255) + 27);\\n return tryRecover(hash, v, r, s);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n *\\n * _Available since v4.2._\\n */\\n function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\\n // the valid range for s in (301): 0 < s < secp256k1n \\u00f7 2 + 1, and for v in (302): v \\u2208 {27, 28}. Most\\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\\n //\\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\\n // these malleable signatures as well.\\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n return (address(0), RecoverError.InvalidSignatureS);\\n }\\n\\n // If the signature is valid (and not malleable), return the signer address\\n address signer = ecrecover(hash, v, r, s);\\n if (signer == address(0)) {\\n return (address(0), RecoverError.InvalidSignature);\\n }\\n\\n return (signer, RecoverError.NoError);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore(0x00, \\\"\\\\x19Ethereum Signed Message:\\\\n32\\\")\\n mstore(0x1c, hash)\\n message := keccak256(0x00, 0x3c)\\n }\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from `s`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n\\\", Strings.toString(s.length), s));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Typed Data, created from a\\n * `domainSeparator` and a `structHash`. This produces hash corresponding\\n * to the one signed with the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n * JSON-RPC method as part of EIP-712.\\n *\\n * See {recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n let ptr := mload(0x40)\\n mstore(ptr, \\\"\\\\x19\\\\x01\\\")\\n mstore(add(ptr, 0x02), domainSeparator)\\n mstore(add(ptr, 0x22), structHash)\\n data := keccak256(ptr, 0x42)\\n }\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Data with intended validator, created from a\\n * `validator` and `data` according to the version 0 of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x00\\\", validator, data));\\n }\\n}\\n\",\"keccak256\":\"0x809bc3edb4bcbef8263fa616c1b60ee0004b50a8a1bfa164d8f57fd31f520c58\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n enum Rounding {\\n Down, // Toward negative infinity\\n Up, // Toward infinity\\n Zero // Toward zero\\n }\\n\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow.\\n return (a & b) + (a ^ b) / 2;\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a == 0 ? 0 : (a - 1) / b + 1;\\n }\\n\\n /**\\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\\n * with further edits by Uniswap Labs also under MIT license.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\\n unchecked {\\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2^256 + prod0.\\n uint256 prod0; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division.\\n if (prod1 == 0) {\\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\\n // The surrounding unchecked block does not change this fact.\\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\\n return prod0 / denominator;\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n require(denominator > prod1, \\\"Math: mulDiv overflow\\\");\\n\\n ///////////////////////////////////////////////\\n // 512 by 256 division.\\n ///////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0].\\n uint256 remainder;\\n assembly {\\n // Compute remainder using mulmod.\\n remainder := mulmod(x, y, denominator)\\n\\n // Subtract 256 bit number from 512 bit number.\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\\n // See https://cs.stackexchange.com/q/138556/92363.\\n\\n // Does not overflow because the denominator cannot be zero at this stage in the function.\\n uint256 twos = denominator & (~denominator + 1);\\n assembly {\\n // Divide denominator by twos.\\n denominator := div(denominator, twos)\\n\\n // Divide [prod1 prod0] by twos.\\n prod0 := div(prod0, twos)\\n\\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\\n twos := add(div(sub(0, twos), twos), 1)\\n }\\n\\n // Shift in bits from prod1 into prod0.\\n prod0 |= prod1 * twos;\\n\\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\\n // four bits. That is, denominator * inv = 1 mod 2^4.\\n uint256 inverse = (3 * denominator) ^ 2;\\n\\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\\n // in modular arithmetic, doubling the correct bits in each step.\\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\\n\\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inverse;\\n return result;\\n }\\n }\\n\\n /**\\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\\n uint256 result = mulDiv(x, y, denominator);\\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\\n result += 1;\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\\n *\\n * Inspired by Henry S. Warren, Jr.'s \\\"Hacker's Delight\\\" (Chapter 11).\\n */\\n function sqrt(uint256 a) internal pure returns (uint256) {\\n if (a == 0) {\\n return 0;\\n }\\n\\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\\n //\\n // We know that the \\\"msb\\\" (most significant bit) of our target number `a` is a power of 2 such that we have\\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\\n //\\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\\n // \\u2192 `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\\n // \\u2192 `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\\n //\\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\\n uint256 result = 1 << (log2(a) >> 1);\\n\\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\\n // into the expected uint128 result.\\n unchecked {\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n return min(result, a / result);\\n }\\n }\\n\\n /**\\n * @notice Calculates sqrt(a), following the selected rounding direction.\\n */\\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = sqrt(a);\\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 2, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 128;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 64;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 32;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 16;\\n }\\n if (value >> 8 > 0) {\\n value >>= 8;\\n result += 8;\\n }\\n if (value >> 4 > 0) {\\n value >>= 4;\\n result += 4;\\n }\\n if (value >> 2 > 0) {\\n value >>= 2;\\n result += 2;\\n }\\n if (value >> 1 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log2(value);\\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 10, rounded down, of a positive value.\\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 + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 256, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n *\\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\\n */\\n function log256(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 16;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 8;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 4;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 2;\\n }\\n if (value >> 8 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log256(value);\\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe4455ac1eb7fc497bb7402579e7b4d64d928b846fce7d2b6fde06d366f21c2b3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\\n * checks.\\n *\\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\\n * easily result in undesired exploitation or bugs, since developers usually\\n * assume that overflows raise errors. `SafeCast` restores this intuition by\\n * reverting the transaction when such an operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n *\\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\\n * all math on `uint256` and `int256` and then downcasting.\\n */\\nlibrary SafeCast {\\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 * _Available since v4.7._\\n */\\n function toUint248(uint256 value) internal pure returns (uint248) {\\n require(value <= type(uint248).max, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint240(uint256 value) internal pure returns (uint240) {\\n require(value <= type(uint240).max, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint232(uint256 value) internal pure returns (uint232) {\\n require(value <= type(uint232).max, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint224(uint256 value) internal pure returns (uint224) {\\n require(value <= type(uint224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint216(uint256 value) internal pure returns (uint216) {\\n require(value <= type(uint216).max, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint208(uint256 value) internal pure returns (uint208) {\\n require(value <= type(uint208).max, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint200(uint256 value) internal pure returns (uint200) {\\n require(value <= type(uint200).max, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint192(uint256 value) internal pure returns (uint192) {\\n require(value <= type(uint192).max, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint184(uint256 value) internal pure returns (uint184) {\\n require(value <= type(uint184).max, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint176(uint256 value) internal pure returns (uint176) {\\n require(value <= type(uint176).max, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint168(uint256 value) internal pure returns (uint168) {\\n require(value <= type(uint168).max, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint160(uint256 value) internal pure returns (uint160) {\\n require(value <= type(uint160).max, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint152(uint256 value) internal pure returns (uint152) {\\n require(value <= type(uint152).max, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint144(uint256 value) internal pure returns (uint144) {\\n require(value <= type(uint144).max, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint136(uint256 value) internal pure returns (uint136) {\\n require(value <= type(uint136).max, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint128(uint256 value) internal pure returns (uint128) {\\n require(value <= type(uint128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint120(uint256 value) internal pure returns (uint120) {\\n require(value <= type(uint120).max, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint112(uint256 value) internal pure returns (uint112) {\\n require(value <= type(uint112).max, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint104(uint256 value) internal pure returns (uint104) {\\n require(value <= type(uint104).max, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint96(uint256 value) internal pure returns (uint96) {\\n require(value <= type(uint96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint88(uint256 value) internal pure returns (uint88) {\\n require(value <= type(uint88).max, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint80(uint256 value) internal pure returns (uint80) {\\n require(value <= type(uint80).max, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint72(uint256 value) internal pure returns (uint72) {\\n require(value <= type(uint72).max, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint64(uint256 value) internal pure returns (uint64) {\\n require(value <= type(uint64).max, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint56(uint256 value) internal pure returns (uint56) {\\n require(value <= type(uint56).max, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint48(uint256 value) internal pure returns (uint48) {\\n require(value <= type(uint48).max, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint40(uint256 value) internal pure returns (uint40) {\\n require(value <= type(uint40).max, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint32(uint256 value) internal pure returns (uint32) {\\n require(value <= type(uint32).max, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint24(uint256 value) internal pure returns (uint24) {\\n require(value <= type(uint24).max, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint16(uint256 value) internal pure returns (uint16) {\\n require(value <= type(uint16).max, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint8(uint256 value) internal pure returns (uint8) {\\n require(value <= type(uint8).max, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\n */\\n function toUint256(int256 value) internal pure returns (uint256) {\\n require(value >= 0, \\\"SafeCast: value must be positive\\\");\\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 * _Available since v4.7._\\n */\\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\\n downcasted = int248(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\\n downcasted = int240(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\\n downcasted = int232(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\\n downcasted = int224(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\\n downcasted = int216(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\\n downcasted = int208(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\\n downcasted = int200(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\\n downcasted = int192(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\\n downcasted = int184(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\\n downcasted = int176(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\\n downcasted = int168(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\\n downcasted = int160(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\\n downcasted = int152(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\\n downcasted = int144(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\\n downcasted = int136(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\\n downcasted = int128(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\\n downcasted = int120(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\\n downcasted = int112(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\\n downcasted = int104(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\\n downcasted = int96(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\\n downcasted = int88(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\\n downcasted = int80(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\\n downcasted = int72(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\\n downcasted = int64(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\\n downcasted = int56(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\\n downcasted = int48(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\\n downcasted = int40(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\\n downcasted = int32(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\\n downcasted = int24(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\\n downcasted = int16(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\\n downcasted = int8(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\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 require(value <= uint256(type(int256).max), \\\"SafeCast: value doesn't fit in an int256\\\");\\n return int256(value);\\n }\\n}\\n\",\"keccak256\":\"0x52a8cfb0f5239d11b457dcdd1b326992ef672714ca8da71a157255bddd13f3ad\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SignedMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard signed math utilities missing in the Solidity language.\\n */\\nlibrary SignedMath {\\n /**\\n * @dev Returns the largest of two signed numbers.\\n */\\n function max(int256 a, int256 b) internal pure returns (int256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two signed numbers.\\n */\\n function min(int256 a, int256 b) internal pure returns (int256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two signed numbers without overflow.\\n * The result is rounded towards zero.\\n */\\n function average(int256 a, int256 b) internal pure returns (int256) {\\n // Formula from the book \\\"Hacker's Delight\\\"\\n int256 x = (a & b) + ((a ^ b) >> 1);\\n return x + (int256(uint256(x) >> 255) & (a ^ b));\\n }\\n\\n /**\\n * @dev Returns the absolute unsigned value of a signed value.\\n */\\n function abs(int256 n) internal pure returns (uint256) {\\n unchecked {\\n // must be unchecked in order to support `n = type(int256).min`\\n return uint256(n >= 0 ? n : -n);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf92515413956f529d95977adc9b0567d583c6203fc31ab1c23824c35187e3ddc\",\"license\":\"MIT\"},\"contracts/aa-4337/core/BaseAccount.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-empty-blocks */\\n\\nimport \\\"../interfaces/IAccount.sol\\\";\\nimport \\\"../interfaces/IEntryPoint.sol\\\";\\nimport \\\"./Helpers.sol\\\";\\n\\n/**\\n * Basic account implementation.\\n * this contract provides the basic logic for implementing the IAccount interface - validateUserOp\\n * specific account implementation should inherit it and provide the account-specific logic\\n */\\nabstract contract BaseAccount is IAccount {\\n using UserOperationLib for UserOperation;\\n\\n //return value in case of signature failure, with no time-range.\\n // equivalent to _packValidationData(true,0,0);\\n uint256 internal constant SIG_VALIDATION_FAILED = 1;\\n\\n /**\\n * Return the account nonce.\\n * This method returns the next sequential nonce.\\n * For a nonce of a specific key, use `entrypoint.getNonce(account, key)`\\n */\\n function getNonce() public view virtual returns (uint256) {\\n return entryPoint().getNonce(address(this), 0);\\n }\\n\\n /**\\n * return the entryPoint used by this account.\\n * subclass should return the current entryPoint used by this account.\\n */\\n function entryPoint() public view virtual returns (IEntryPoint);\\n\\n /**\\n * Validate user's signature and nonce.\\n * subclass doesn't need to override this method. Instead, it should override the specific internal validation methods.\\n */\\n function validateUserOp(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n uint256 missingAccountFunds\\n ) external virtual override returns (uint256 validationData) {\\n _requireFromEntryPoint();\\n validationData = _validateSignature(userOp, userOpHash);\\n _validateNonce(userOp.nonce);\\n _payPrefund(missingAccountFunds);\\n }\\n\\n /**\\n * ensure the request comes from the known entrypoint.\\n */\\n function _requireFromEntryPoint() internal view virtual {\\n require(\\n msg.sender == address(entryPoint()),\\n \\\"account: not from EntryPoint\\\"\\n );\\n }\\n\\n /**\\n * validate the signature is valid for this message.\\n * @param userOp validate the userOp.signature field\\n * @param userOpHash convenient field: the hash of the request, to check the signature against\\n * (also hashes the entrypoint and chain id)\\n * @return validationData signature and time-range of this operation\\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\\n * otherwise, an address of an \\\"authorizer\\\" contract.\\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \\\"indefinite\\\"\\n * <6-byte> validAfter - first timestamp this operation is valid\\n * If the account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\\n */\\n function _validateSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) internal virtual returns (uint256 validationData);\\n\\n /**\\n * Validate the nonce of the UserOperation.\\n * This method may validate the nonce requirement of this account.\\n * e.g.\\n * To limit the nonce to use sequenced UserOps only (no \\\"out of order\\\" UserOps):\\n * `require(nonce < type(uint64).max)`\\n * For a hypothetical account that *requires* the nonce to be out-of-order:\\n * `require(nonce & type(uint64).max == 0)`\\n *\\n * The actual nonce uniqueness is managed by the EntryPoint, and thus no other\\n * action is needed by the account itself.\\n *\\n * @param nonce to validate\\n *\\n * solhint-disable-next-line no-empty-blocks\\n */\\n function _validateNonce(uint256 nonce) internal view virtual {}\\n\\n /**\\n * sends to the entrypoint (msg.sender) the missing funds for this transaction.\\n * subclass MAY override this method for better funds management\\n * (e.g. send to the entryPoint more than the minimum required, so that in future transactions\\n * it will not be required to send again)\\n * @param missingAccountFunds the minimum value this method should send the entrypoint.\\n * this value MAY be zero, in case there is enough deposit, or the userOp has a paymaster.\\n */\\n function _payPrefund(uint256 missingAccountFunds) internal virtual {\\n if (missingAccountFunds != 0) {\\n (bool success, ) = payable(msg.sender).call{\\n value: missingAccountFunds,\\n gas: type(uint256).max\\n }(\\\"\\\");\\n (success);\\n //ignore failure (its EntryPoint's job to verify, not account.)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa0dcc386b0f04711db3e394fb50e55a3b3b1a4d19fac1f10895844e1aa4e3d5c\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/core/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable no-inline-assembly */\\n\\n/**\\n * returned data from validateUserOp.\\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\\n * @param aggregator - address(0) - the account validated the signature by itself.\\n * address(1) - the account failed to validate the signature.\\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\\n * @param validAfter - this UserOp is valid only after this timestamp.\\n * @param validaUntil - this UserOp is valid only up to this timestamp.\\n */\\nstruct ValidationData {\\n address aggregator;\\n uint48 validAfter;\\n uint48 validUntil;\\n}\\n\\n//extract sigFailed, validAfter, validUntil.\\n// also convert zero validUntil to type(uint48).max\\nfunction _parseValidationData(\\n uint validationData\\n) pure returns (ValidationData memory data) {\\n address aggregator = address(uint160(validationData));\\n uint48 validUntil = uint48(validationData >> 160);\\n if (validUntil == 0) {\\n validUntil = type(uint48).max;\\n }\\n uint48 validAfter = uint48(validationData >> (48 + 160));\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n// intersect account and paymaster ranges.\\nfunction _intersectTimeRange(\\n uint256 validationData,\\n uint256 paymasterValidationData\\n) pure returns (ValidationData memory) {\\n ValidationData memory accountValidationData = _parseValidationData(\\n validationData\\n );\\n ValidationData memory pmValidationData = _parseValidationData(\\n paymasterValidationData\\n );\\n address aggregator = accountValidationData.aggregator;\\n if (aggregator == address(0)) {\\n aggregator = pmValidationData.aggregator;\\n }\\n uint48 validAfter = accountValidationData.validAfter;\\n uint48 validUntil = accountValidationData.validUntil;\\n uint48 pmValidAfter = pmValidationData.validAfter;\\n uint48 pmValidUntil = pmValidationData.validUntil;\\n\\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp\\n * @param data - the ValidationData to pack\\n */\\nfunction _packValidationData(\\n ValidationData memory data\\n) pure returns (uint256) {\\n return\\n uint160(data.aggregator) |\\n (uint256(data.validUntil) << 160) |\\n (uint256(data.validAfter) << (160 + 48));\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp, when not using an aggregator\\n * @param sigFailed - true for signature failure, false for success\\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\\n * @param validAfter first timestamp this UserOperation is valid\\n */\\nfunction _packValidationData(\\n bool sigFailed,\\n uint48 validUntil,\\n uint48 validAfter\\n) pure returns (uint256) {\\n return\\n (sigFailed ? 1 : 0) |\\n (uint256(validUntil) << 160) |\\n (uint256(validAfter) << (160 + 48));\\n}\\n\\n/**\\n * keccak function over calldata.\\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\\n */\\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\\n assembly {\\n let mem := mload(0x40)\\n let len := data.length\\n calldatacopy(mem, data.offset, len)\\n ret := keccak256(mem, len)\\n }\\n}\\n\",\"keccak256\":\"0xa79f06cd158ecb8c0da95493a2f348933b8627a63e228b99738bff3aa107942d\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAccount.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\ninterface IAccount {\\n /**\\n * Validate user's signature and nonce\\n * the entryPoint will make the call to the recipient only if this validation call returns successfully.\\n * signature failure should be reported by returning SIG_VALIDATION_FAILED (1).\\n * This allows making a \\\"simulation call\\\" without a valid signature\\n * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure.\\n *\\n * @dev Must validate caller is the entryPoint.\\n * Must validate the signature and nonce\\n * @param userOp the operation that is about to be executed.\\n * @param userOpHash hash of the user's request data. can be used as the basis for signature.\\n * @param missingAccountFunds missing funds on the account's deposit in the entrypoint.\\n * This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call.\\n * The excess is left as a deposit in the entrypoint, for future calls.\\n * can be withdrawn anytime using \\\"entryPoint.withdrawTo()\\\"\\n * In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero.\\n * @return validationData packaged ValidationData structure. use `_packValidationData` and `_unpackValidationData` to encode and decode\\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\\n * otherwise, an address of an \\\"authorizer\\\" contract.\\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \\\"indefinite\\\"\\n * <6-byte> validAfter - first timestamp this operation is valid\\n * If an account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\\n */\\n function validateUserOp(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n uint256 missingAccountFunds\\n ) external returns (uint256 validationData);\\n}\\n\",\"keccak256\":\"0xcbc4b0973cf954c5895b7796335f651fbfcfb55f67dfa789a3d354f8e23c4f2b\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAggregator.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\n/**\\n * Aggregated Signatures validator.\\n */\\ninterface IAggregator {\\n /**\\n * validate aggregated signature.\\n * revert if the aggregated signature does not match the given list of operations.\\n */\\n function validateSignatures(\\n UserOperation[] calldata userOps,\\n bytes calldata signature\\n ) external view;\\n\\n /**\\n * validate signature of a single userOp\\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\\n * @param userOp the userOperation received from the user.\\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\\n * (usually empty, unless account and aggregator support some kind of \\\"multisig\\\"\\n */\\n function validateUserOpSignature(\\n UserOperation calldata userOp\\n ) external view returns (bytes memory sigForUserOp);\\n\\n /**\\n * aggregate multiple signatures into a single value.\\n * This method is called off-chain to calculate the signature to pass with handleOps()\\n * bundler MAY use optimized custom code perform this aggregation\\n * @param userOps array of UserOperations to collect the signatures from.\\n * @return aggregatedSignature the aggregated signature\\n */\\n function aggregateSignatures(\\n UserOperation[] calldata userOps\\n ) external view returns (bytes memory aggregatedSignature);\\n}\\n\",\"keccak256\":\"0xdfdcd80568f037716674619b31be630fcd8316262f05a815b41d1e81782c966a\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IEntryPoint.sol\":{\"content\":\"/**\\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\\n ** Only one instance required on each chain.\\n **/\\n// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-inline-assembly */\\n/* solhint-disable reason-string */\\n\\nimport \\\"./UserOperation.sol\\\";\\nimport \\\"./IStakeManager.sol\\\";\\nimport \\\"./IAggregator.sol\\\";\\nimport \\\"./INonceManager.sol\\\";\\n\\ninterface IEntryPoint is IStakeManager, INonceManager {\\n /***\\n * An event emitted after each successful request\\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\\n * @param sender - the account that generates this request.\\n * @param paymaster - if non-null, the paymaster that pays for this request.\\n * @param nonce - the nonce value from the request.\\n * @param success - true if the sender transaction succeeded, false if reverted.\\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\\n */\\n event UserOperationEvent(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address indexed paymaster,\\n uint256 nonce,\\n bool success,\\n uint256 actualGasCost,\\n uint256 actualGasUsed\\n );\\n\\n /**\\n * account \\\"sender\\\" was deployed.\\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\\n * @param sender the account that is deployed\\n * @param factory the factory used to deploy this account (in the initCode)\\n * @param paymaster the paymaster used by this UserOp\\n */\\n event AccountDeployed(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address factory,\\n address paymaster\\n );\\n\\n /**\\n * An event emitted if the UserOperation \\\"callData\\\" reverted with non-zero length\\n * @param userOpHash the request unique identifier.\\n * @param sender the sender of this request\\n * @param nonce the nonce used in the request\\n * @param revertReason - the return bytes from the (reverted) call to \\\"callData\\\".\\n */\\n event UserOperationRevertReason(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n uint256 nonce,\\n bytes revertReason\\n );\\n\\n /**\\n * an event emitted by handleOps(), before starting the execution loop.\\n * any event emitted before this event, is part of the validation.\\n */\\n event BeforeExecution();\\n\\n /**\\n * signature aggregator used by the following UserOperationEvents within this bundle.\\n */\\n event SignatureAggregatorChanged(address indexed aggregator);\\n\\n /**\\n * a custom revert error of handleOps, to identify the offending op.\\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\\n * @param reason - revert reason\\n * The string starts with a unique code \\\"AAmn\\\", where \\\"m\\\" is \\\"1\\\" for factory, \\\"2\\\" for account and \\\"3\\\" for paymaster issues,\\n * so a failure can be attributed to the correct entity.\\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\\n */\\n error FailedOp(uint256 opIndex, string reason);\\n\\n /**\\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\\n */\\n error SignatureValidationFailed(address aggregator);\\n\\n /**\\n * Successful result from simulateValidation.\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n */\\n error ValidationResult(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo\\n );\\n\\n /**\\n * Successful result from simulateValidation, if the account returns a signature aggregator\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\\n * bundler MUST use it to verify the signature, or reject the UserOperation\\n */\\n error ValidationResultWithAggregation(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo,\\n AggregatorStakeInfo aggregatorInfo\\n );\\n\\n /**\\n * return value of getSenderAddress\\n */\\n error SenderAddressResult(address sender);\\n\\n /**\\n * return value of simulateHandleOp\\n */\\n error ExecutionResult(\\n uint256 preOpGas,\\n uint256 paid,\\n uint48 validAfter,\\n uint48 validUntil,\\n bool targetSuccess,\\n bytes targetResult\\n );\\n\\n //UserOps handled, per aggregator\\n struct UserOpsPerAggregator {\\n UserOperation[] userOps;\\n // aggregator address\\n IAggregator aggregator;\\n // aggregated signature\\n bytes signature;\\n }\\n\\n /**\\n * Execute a batch of UserOperation.\\n * no signature aggregator is used.\\n * if any account requires an aggregator (that is, it returned an aggregator when\\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\\n * @param ops the operations to execute\\n * @param beneficiary the address to receive the fees\\n */\\n function handleOps(\\n UserOperation[] calldata ops,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * Execute a batch of UserOperation with Aggregators\\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\\n * @param beneficiary the address to receive the fees\\n */\\n function handleAggregatedOps(\\n UserOpsPerAggregator[] calldata opsPerAggregator,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * generate a request Id - unique identifier for this request.\\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\\n */\\n function getUserOpHash(\\n UserOperation calldata userOp\\n ) external view returns (bytes32);\\n\\n /**\\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\\n * @param userOp the user operation to validate.\\n */\\n function simulateValidation(UserOperation calldata userOp) external;\\n\\n /**\\n * gas and return values during simulation\\n * @param preOpGas the gas used for validation (including preValidationGas)\\n * @param prefund the required prefund for this operation\\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\\n */\\n struct ReturnInfo {\\n uint256 preOpGas;\\n uint256 prefund;\\n bool sigFailed;\\n uint48 validAfter;\\n uint48 validUntil;\\n bytes paymasterContext;\\n }\\n\\n /**\\n * returned aggregated signature info.\\n * the aggregator returned by the account, and its current stake.\\n */\\n struct AggregatorStakeInfo {\\n address aggregator;\\n StakeInfo stakeInfo;\\n }\\n\\n /**\\n * Get counterfactual sender address.\\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\\n * this method always revert, and returns the address in SenderAddressResult error\\n * @param initCode the constructor code to be passed into the UserOperation.\\n */\\n function getSenderAddress(bytes memory initCode) external;\\n\\n /**\\n * simulate full execution of a UserOperation (including both validation and target execution)\\n * this method will always revert with \\\"ExecutionResult\\\".\\n * it performs full validation of the UserOperation, but ignores signature error.\\n * an optional target address is called after the userop succeeds, and its value is returned\\n * (before the entire call is reverted)\\n * Note that in order to collect the the success/failure of the target call, it must be executed\\n * with trace enabled to track the emitted events.\\n * @param op the UserOperation to simulate\\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\\n * are set to the return from that call.\\n * @param targetCallData callData to pass to target address\\n */\\n function simulateHandleOp(\\n UserOperation calldata op,\\n address target,\\n bytes calldata targetCallData\\n ) external;\\n}\\n\",\"keccak256\":\"0x9ccb1b188eda8bbf5f6c2d01bd83c3d8b2b04fcf745283051d31fe96d1d8e40f\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/INonceManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\ninterface INonceManager {\\n /**\\n * Return the next nonce for this sender.\\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\\n * But UserOp with different keys can come with arbitrary order.\\n *\\n * @param sender the account address\\n * @param key the high 192 bit of the nonce\\n * @return nonce a full nonce to pass for next UserOp with this sender.\\n */\\n function getNonce(\\n address sender,\\n uint192 key\\n ) external view returns (uint256 nonce);\\n\\n /**\\n * Manually increment the nonce of the sender.\\n * This method is exposed just for completeness..\\n * Account does NOT need to call it, neither during validation, nor elsewhere,\\n * as the EntryPoint will update the nonce regardless.\\n * Possible use-case is call it with various keys to \\\"initialize\\\" their nonces to one, so that future\\n * UserOperations will not pay extra for the first transaction with a given key.\\n */\\n function incrementNonce(uint192 key) external;\\n}\\n\",\"keccak256\":\"0xce478ad0fa0d18a3b785ac854623029e7ab463d05873dfaa365abfa1bf100912\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IStakeManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8.12;\\n\\n/**\\n * manage deposits and stakes.\\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\\n * stake is value locked for at least \\\"unstakeDelay\\\" by the staked entity.\\n */\\ninterface IStakeManager {\\n event Deposited(address indexed account, uint256 totalDeposit);\\n\\n event Withdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /// Emitted when stake or unstake delay are modified\\n event StakeLocked(\\n address indexed account,\\n uint256 totalStaked,\\n uint256 unstakeDelaySec\\n );\\n\\n /// Emitted once a stake is scheduled for withdrawal\\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\\n\\n event StakeWithdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /**\\n * @param deposit the entity's deposit\\n * @param staked true if this entity is staked.\\n * @param stake actual amount of ether staked for this entity.\\n * @param unstakeDelaySec minimum delay to withdraw the stake.\\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\\n * and the rest fit into a 2nd cell.\\n * 112 bit allows for 10^15 eth\\n * 48 bit for full timestamp\\n * 32 bit allows 150 years for unstake delay\\n */\\n struct DepositInfo {\\n uint112 deposit;\\n bool staked;\\n uint112 stake;\\n uint32 unstakeDelaySec;\\n uint48 withdrawTime;\\n }\\n\\n //API struct used by getStakeInfo and simulateValidation\\n struct StakeInfo {\\n uint256 stake;\\n uint256 unstakeDelaySec;\\n }\\n\\n /// @return info - full deposit information of given account\\n function getDepositInfo(\\n address account\\n ) external view returns (DepositInfo memory info);\\n\\n /// @return the deposit (for gas payment) of the account\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * add to the deposit of the given account\\n */\\n function depositTo(address account) external payable;\\n\\n /**\\n * add to the account's stake - amount and delay\\n * any pending unstake is first cancelled.\\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\\n */\\n function addStake(uint32 _unstakeDelaySec) external payable;\\n\\n /**\\n * attempt to unlock the stake.\\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\\n */\\n function unlockStake() external;\\n\\n /**\\n * withdraw from the (unlocked) stake.\\n * must first call unlockStake and wait for the unstakeDelay to pass\\n * @param withdrawAddress the address to send withdrawn value.\\n */\\n function withdrawStake(address payable withdrawAddress) external;\\n\\n /**\\n * withdraw from the deposit.\\n * @param withdrawAddress the address to send withdrawn value.\\n * @param withdrawAmount the amount to withdraw.\\n */\\n function withdrawTo(\\n address payable withdrawAddress,\\n uint256 withdrawAmount\\n ) external;\\n}\\n\",\"keccak256\":\"0xadcea606c9b7aafe6645441f2154a60f271330b0eee5292a632aa71c1672d546\",\"license\":\"GPL-3.0-only\"},\"contracts/aa-4337/interfaces/UserOperation.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable no-inline-assembly */\\n\\nimport {calldataKeccak} from \\\"../core/Helpers.sol\\\";\\n\\n/**\\n * User Operation struct\\n * @param sender the sender account of this request.\\n * @param nonce unique value the sender uses to verify it is not a replay.\\n * @param initCode if set, the account contract will be created by this constructor/\\n * @param callData the method call to execute on this account.\\n * @param callGasLimit the gas limit passed to the callData method call.\\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\\n * @param maxFeePerGas same as EIP-1559 gas parameter.\\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\\n */\\nstruct UserOperation {\\n address sender;\\n uint256 nonce;\\n bytes initCode;\\n bytes callData;\\n uint256 callGasLimit;\\n uint256 verificationGasLimit;\\n uint256 preVerificationGas;\\n uint256 maxFeePerGas;\\n uint256 maxPriorityFeePerGas;\\n bytes paymasterAndData;\\n bytes signature;\\n}\\n\\n/**\\n * Utility functions helpful when working with UserOperation structs.\\n */\\nlibrary UserOperationLib {\\n function getSender(\\n UserOperation calldata userOp\\n ) internal pure returns (address) {\\n address data;\\n //read sender from userOp, which is first userOp member (saves 800 gas...)\\n assembly {\\n data := calldataload(userOp)\\n }\\n return address(uint160(data));\\n }\\n\\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\\n // pay above what he signed for.\\n function gasPrice(\\n UserOperation calldata userOp\\n ) internal view returns (uint256) {\\n unchecked {\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n if (maxFeePerGas == maxPriorityFeePerGas) {\\n //legacy mode (for networks that don't support basefee opcode)\\n return maxFeePerGas;\\n }\\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\\n }\\n }\\n\\n function pack(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes memory ret) {\\n address sender = getSender(userOp);\\n uint256 nonce = userOp.nonce;\\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\\n bytes32 hashCallData = calldataKeccak(userOp.callData);\\n uint256 callGasLimit = userOp.callGasLimit;\\n uint256 verificationGasLimit = userOp.verificationGasLimit;\\n uint256 preVerificationGas = userOp.preVerificationGas;\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\\n\\n return\\n abi.encode(\\n sender,\\n nonce,\\n hashInitCode,\\n hashCallData,\\n callGasLimit,\\n verificationGasLimit,\\n preVerificationGas,\\n maxFeePerGas,\\n maxPriorityFeePerGas,\\n hashPaymasterAndData\\n );\\n }\\n\\n function hash(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes32) {\\n return keccak256(pack(userOp));\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n}\\n\",\"keccak256\":\"0x2429f5cc546bdee08c7e63858d0dda8491eaa3ab5194df884dc948c1154d2834\",\"license\":\"GPL-3.0\"},\"contracts/facets/AccountFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {ECDSA} from \\\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\\\";\\nimport {UserOperation} from \\\"../aa-4337/interfaces/UserOperation.sol\\\";\\nimport {IEntryPoint} from \\\"../aa-4337/interfaces/IEntryPoint.sol\\\";\\nimport {BaseAccount} from \\\"../aa-4337/core/BaseAccount.sol\\\";\\nimport {LibAppStorage, BarzStorage} from \\\"../libraries/LibAppStorage.sol\\\";\\nimport {LibDiamond} from \\\"../libraries/LibDiamond.sol\\\";\\nimport {LibLoupe} from \\\"../libraries/LibLoupe.sol\\\";\\nimport {IFacetRegistry} from \\\"../infrastructure/interfaces/IFacetRegistry.sol\\\";\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\nimport {IVerificationFacet} from \\\"./interfaces/IVerificationFacet.sol\\\";\\nimport {IERC1271} from \\\"../interfaces/ERC/IERC1271.sol\\\";\\nimport {IAccountFacet} from \\\"./interfaces/IAccountFacet.sol\\\";\\n\\n/**\\n * @title Account Facet\\n * @dev Account module contract that provides the account features and initialization of signer\\n * compatible with EIP-1271 & EIP-4337\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract AccountFacet is IAccountFacet, BarzStorage, BaseAccount {\\n using ECDSA for bytes32;\\n\\n /**\\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\\n */\\n constructor() {\\n LibAppStorage.enforceAccountInitialize();\\n }\\n\\n /**\\n * @notice Returns the address of EntryPoint contract registered to Barz account\\n */\\n function entryPoint() public view override returns (IEntryPoint) {\\n return s.entryPoint;\\n }\\n\\n /**\\n * @notice Initializes the initial storage of the Barz contract.\\n * @dev This method can only be called during the initialization or signature migration.\\n * If the proxy contract was created without initialization, anyone can call initialize.\\n * Barz calls initialize in constructor in an atomic transaction during deployment\\n * @param _verificationFacet Facet contract handling the verificationi\\n * @param _anEntryPoint Entrypoint contract defined in EIP-4337 handling the flow of UserOp\\n * @param _facetRegistry Registry of Facets that hold all facet information\\n * @param _defaultFallBackHandler Middleware contract for default facets\\n * @param _ownerPublicKey Bytes of owner public key\\n */\\n function initialize(\\n address _verificationFacet,\\n address _anEntryPoint,\\n address _facetRegistry,\\n address _defaultFallBackHandler,\\n bytes calldata _ownerPublicKey\\n ) public override returns (uint256 initSuccess) {\\n LibAppStorage.enforceAccountInitialize();\\n s.entryPoint = IEntryPoint(_anEntryPoint);\\n s.facetRegistry = IFacetRegistry(_facetRegistry);\\n LibDiamond.diamondStorage().defaultFallbackHandler = IDiamondLoupe(\\n _defaultFallBackHandler\\n );\\n\\n _cutDiamondAccountFacet(_verificationFacet);\\n\\n bytes memory initCall = abi.encodeWithSignature(\\n \\\"initializeSigner(bytes)\\\",\\n _ownerPublicKey\\n );\\n // Every Verification Facet should comply with initializeSigner(bytes)\\n // to be compatible with the Barz contract(for initialization)\\n (bool success, bytes memory result) = _verificationFacet.delegatecall(\\n initCall\\n );\\n if (!success || uint256(bytes32(result)) != 1) {\\n revert AccountFacet__InitializationFailure();\\n }\\n\\n initSuccess = 1;\\n emit AccountInitialized(s.entryPoint, _ownerPublicKey);\\n }\\n\\n function _cutDiamondAccountFacet(address _verificationFacet) internal {\\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](1);\\n\\n bytes4 ownerVerificationFuncSelector = IVerificationFacet(\\n _verificationFacet\\n ).validateOwnerSignatureSelector();\\n\\n bytes4[] memory verificationFunctionSelectors = new bytes4[](3);\\n verificationFunctionSelectors[0] = IERC1271.isValidSignature.selector;\\n verificationFunctionSelectors[1] = ownerVerificationFuncSelector;\\n verificationFunctionSelectors[2] = IVerificationFacet.owner.selector;\\n cut[0] = IDiamondCut.FacetCut({\\n facetAddress: _verificationFacet,\\n action: IDiamondCut.FacetCutAction.Add,\\n functionSelectors: verificationFunctionSelectors\\n });\\n\\n LibDiamond.diamondCut(cut, address(0), \\\"\\\");\\n }\\n\\n /**\\n * @notice Calls the destination with inputted calldata and value from EntryPoint\\n * @dev This method executes the calldata coming from the EntryPoint.\\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\\n * @param _dest Address of destination where the call will be forwarded to\\n * @param _value Amount of native coin the owner is willing to send(e.g. ETH, BNB)\\n * @param _func Bytes of calldata to execute in the destination address\\n */\\n function execute(\\n address _dest,\\n uint256 _value,\\n bytes calldata _func\\n ) external override onlyWhenUnlocked {\\n _requireFromEntryPoint();\\n address restrictionsFacet = LibDiamond.restrictionsFacet();\\n if (restrictionsFacet == address(0)) _call(_dest, _value, _func);\\n else _callWithRestrictions(_dest, _value, _func, restrictionsFacet);\\n }\\n\\n /**\\n * @notice Batch calls the destination with inputted calldata and value from EntryPoint\\n * @dev This method batch executes the calldata coming from the EntryPoint.\\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\\n * @param _dest Array of addresses of destination where the call will be forwarded to\\n * @param _value Array of amount of native coin the owner is willing to send(e.g. ETH, BNB)\\n * @param _func Array of bytes of calldata to execute in the destination address\\n */\\n function executeBatch(\\n address[] calldata _dest,\\n uint256[] calldata _value,\\n bytes[] calldata _func\\n ) external override onlyWhenUnlocked {\\n _requireFromEntryPoint();\\n if (_dest.length != _func.length || _dest.length != _value.length)\\n revert AccountFacet__InvalidArrayLength();\\n address restrictionsFacet = LibDiamond.restrictionsFacet();\\n if (restrictionsFacet == address(0)) {\\n for (uint256 i; i < _dest.length; ) {\\n _call(_dest[i], _value[i], _func[i]);\\n unchecked {\\n ++i;\\n }\\n }\\n } else {\\n for (uint256 i; i < _dest.length; ) {\\n _callWithRestrictions(\\n _dest[i],\\n _value[i],\\n _func[i],\\n restrictionsFacet\\n );\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n }\\n\\n /**\\n * @notice Validates the signature field of UserOperation\\n * @dev This method validates if the signature of UserOp is indeed valid by delegating the call to Verification Facet\\n * Barz makes a call to the pre-registered Verification Facet address in App Storage\\n * @param _userOp UserOperation from owner to be validated\\n * @param _userOpHash Hash of UserOperation given from the EntryPoint contract\\n */\\n function _validateSignature(\\n UserOperation calldata _userOp,\\n bytes32 _userOpHash\\n ) internal override returns (uint256 validationData) {\\n // Get Facet with Function Selector\\n address facet = LibLoupe.facetAddress(s.validateOwnerSignatureSelector);\\n if (facet == address(0))\\n revert AccountFacet__NonExistentVerificationFacet();\\n\\n // Make function call to VerificationFacet\\n bytes memory validateCall = abi.encodeWithSelector(\\n s.validateOwnerSignatureSelector,\\n _userOp,\\n _userOpHash\\n );\\n (bool success, bytes memory result) = facet.delegatecall(validateCall);\\n if (!success) revert AccountFacet__CallNotSuccessful();\\n validationData = uint256(bytes32(result));\\n if (validationData == 0) emit VerificationSuccess(_userOpHash);\\n else emit VerificationFailure(_userOpHash);\\n }\\n\\n /**\\n * @notice Calls the target with the inputted value and calldata\\n * @dev This method is the actual function in Barz that makes a call with an arbitrary owner-given data\\n * @param _target Address of the destination contract which the call is getting forwarded to\\n * @param _value Amount of Native coin the owner is wanting to make in this call\\n * @param _data Calldata the owner is forwarding together in the call e.g. Swap/Token Transfer\\n */\\n function _call(\\n address _target,\\n uint256 _value,\\n bytes memory _data\\n ) internal {\\n (bool success, bytes memory result) = _target.call{value: _value}(\\n _data\\n );\\n if (!success) {\\n assembly {\\n revert(add(result, 32), mload(result))\\n }\\n }\\n }\\n\\n /**\\n * @notice Calls the target with the inputted value and calldata together with restrictions check\\n * @dev This method is the actual function in Barz that makes a call with an arbitrary owner-given data\\n * @param _target Address of the destination contract which the call is getting forwarded to\\n * @param _value Amount of Native coin the owner is wanting to make in this call\\n * @param _data Calldata the owner is forwarding together in the call e.g. Swap/Token Transfer\\n * @param _restrictionsFacet Address of Facet to validate restrictions\\n */\\n function _callWithRestrictions(\\n address _target,\\n uint256 _value,\\n bytes memory _data,\\n address _restrictionsFacet\\n ) internal {\\n // NOTE: No restrictions facet, so restriction validation passes\\n if (_checkRestrictions(_restrictionsFacet, _target, _value, _data) != 0)\\n revert AccountFacet__RestrictionsFailure();\\n\\n (bool success, bytes memory result) = _target.call{value: _value}(\\n _data\\n );\\n if (!success) {\\n assembly {\\n revert(add(result, 32), mload(result))\\n }\\n }\\n }\\n\\n /**\\n * @notice Checks restrictions if the restrictions facet exists\\n * @dev This method checks if the restrictions facet exists and makes a verification call to an array of restrictions facet\\n * @param _facet Address that holds the restrictions logic\\n * @param _target Address the call is getting forwarded to\\n * @param _value Amount of native coin the call is sending together with the call\\n * @param _data Calldata to trigger execution in target address\\n */\\n function _checkRestrictions(\\n address _facet,\\n address _target,\\n uint256 _value,\\n bytes memory _data\\n ) internal returns (uint256 result) {\\n bytes memory call = abi.encodeWithSignature(\\n \\\"verifyRestrictions(address,address,uint256,bytes)\\\",\\n address(this),\\n _target,\\n _value,\\n _data\\n );\\n (bool success, bytes memory response) = _facet.delegatecall(call);\\n if (!success) revert AccountFacet__RestrictionsFailure();\\n result = uint256(bytes32(response));\\n }\\n}\\n\",\"keccak256\":\"0xcd92bcdd447010880f78e57e213123269c9e023adfc0a540608daa127d8649ca\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/facets/interfaces/IAccountFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IEntryPoint} from \\\"../../aa-4337/interfaces/IEntryPoint.sol\\\";\\n\\n/**\\n * @title Account Facet Interface\\n * @dev Interface of module contract that provides the account features and init/unitialization of signer\\n * compatible with EIP-1271 & EIP-4337\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IAccountFacet {\\n event AccountInitialized(\\n IEntryPoint indexed entryPoint,\\n bytes indexed ownerPublicKey\\n );\\n // NOTE: Added Below Event\\n event VerificationSuccess(bytes32);\\n event VerificationFailure(bytes32);\\n\\n error AccountFacet__InitializationFailure();\\n error AccountFacet__RestrictionsFailure();\\n error AccountFacet__NonExistentVerificationFacet();\\n error AccountFacet__CallNotSuccessful();\\n error AccountFacet__InvalidArrayLength();\\n\\n function initialize(\\n address verificationFacet,\\n address anEntryPoint,\\n address facetRegistry,\\n address _defaultFallBack,\\n bytes calldata _ownerPublicKey\\n ) external returns (uint256);\\n\\n function execute(address dest, uint256 value, bytes calldata func) external;\\n\\n function executeBatch(\\n address[] calldata dest,\\n uint256[] calldata value,\\n bytes[] calldata func\\n ) external;\\n}\\n\",\"keccak256\":\"0x74a9cb0b8f2f4a5148e366a401a0354426c536c012c025025d07cc25a4cd5382\",\"license\":\"Apache-2.0\"},\"contracts/facets/interfaces/IVerificationFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {UserOperation} from \\\"../../aa-4337/interfaces/UserOperation.sol\\\";\\n\\n/**\\n * @title Verification Facet Interface\\n * @dev Implements logic for user ops signature verification\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\ninterface IVerificationFacet {\\n event SignerInitialized(bytes);\\n event SignerUninitialized();\\n\\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\\n error VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\\n error VerificationFacet__InitializationFailure();\\n error VerificationFacet__InvalidFacetMapping();\\n\\n function initializeSigner(bytes memory) external returns (uint256);\\n\\n function uninitializeSigner() external returns (uint256);\\n\\n function validateOwnerSignatureSelector() external view returns (bytes4);\\n\\n function owner() external view returns (bytes memory);\\n\\n function isValidKeyType(bytes calldata) external view returns (bool);\\n\\n function validateOwnerSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x72bc370a1d1b5a6d6bde67f5026733fd8f6ba434bb90e73b0bd8627fb1579928\",\"license\":\"Apache-2.0\"},\"contracts/infrastructure/interfaces/IFacetRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Registry Interface\\n * @dev Interface for Facet Registry contract to keep track of facets & function selectors addable to user wallets\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IFacetRegistry {\\n struct FacetRegistryConfig {\\n bytes4[] selectors;\\n mapping(bytes4 => FacetInfo) info;\\n }\\n struct FacetInfo {\\n bool exists;\\n uint128 index;\\n }\\n\\n event FacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] facetSelectors\\n );\\n event FacetFunctionSelectorsRemoved(address facet, bytes4[] facetSelectors);\\n\\n error FacetRegistry__FacetSelectorAlreadyRegistered();\\n error FacetRegistry__UnregisteredFacetSelector();\\n\\n function registerFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function removeFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function areFacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external view returns (bool);\\n\\n function isFacetFunctionSelectorRegistered(\\n address facet,\\n bytes4 facetSelector\\n ) external view returns (bool);\\n\\n function getFacetFunctionSelectors(\\n address facet\\n ) external view returns (bytes4[] memory);\\n}\\n\",\"keccak256\":\"0x6e6dd2cab346ef7c31230740ec48d2925e4a9ab24c2f2fb268baaf408dcf02ef\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC1271 {\\n function isValidSignature(\\n bytes32 hash,\\n bytes memory signature\\n ) external view returns (bytes4);\\n}\\n\",\"keccak256\":\"0xcdddb7d5641c9d3f2432dec7fd13fddb9ae1480f25c76c21511e2fa16b8bd422\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibAppStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {SafeCast} from \\\"@openzeppelin/contracts/utils/math/SafeCast.sol\\\";\\nimport {IEntryPoint} from \\\"../aa-4337/interfaces/IEntryPoint.sol\\\";\\nimport {IFacetRegistry} from \\\"../infrastructure/interfaces/IFacetRegistry.sol\\\";\\n\\n/*\\n * @title App Storage\\n * @dev App storage for Barz contract to prevent storage collision\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Lock {\\n uint64 release;\\n bytes4 locker;\\n}\\n\\nstruct InitializersStorage {\\n // NOTE: initialized is a variable to make sure the initialization is only done once.\\n uint8 signerInitialized;\\n uint8 accountInitialized;\\n uint8 restrictionsInitialized;\\n}\\n\\nstruct AppStorage {\\n mapping(uint256 => InitializersStorage) initStorage;\\n uint8 signerMigration;\\n bytes4 validateOwnerSignatureSelector;\\n IEntryPoint entryPoint;\\n IFacetRegistry facetRegistry;\\n mapping(uint256 => Lock) locks;\\n}\\n\\nlibrary LibAppStorage {\\n error LibAppStorage__AccountAlreadyUninitialized();\\n error LibAppStorage__AccountMustBeUninitialized();\\n error LibAppStorage__SignerAlreadyUninitialized();\\n error LibAppStorage__SignerMustBeUninitialized();\\n\\n function appStorage() internal pure returns (AppStorage storage ds) {\\n assembly {\\n ds.slot := 0\\n }\\n }\\n\\n function setSignerUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerAlreadyUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 0;\\n }\\n\\n function getValidateOwnerSignatureSelector()\\n internal\\n view\\n returns (bytes4 selector)\\n {\\n selector = appStorage().validateOwnerSignatureSelector;\\n }\\n\\n function setValidateOwnerSignatureSelector(\\n bytes4 _validateOwnerSignatureSelector\\n ) internal {\\n appStorage()\\n .validateOwnerSignatureSelector = _validateOwnerSignatureSelector;\\n }\\n\\n function enforceSignerInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerMustBeUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 1;\\n }\\n\\n function enforceAccountInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].accountInitialized) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n s.initStorage[0].accountInitialized = 1;\\n }\\n\\n function initiateSignerMigration() internal {\\n appStorage().signerMigration = 1;\\n }\\n\\n function enforceSignerMigration() internal view {\\n if (1 != appStorage().signerMigration) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n }\\n\\n function finalizeSignerMigration() internal {\\n appStorage().signerMigration = 0;\\n }\\n\\n function setLock(uint256 _releaseAfter, bytes4 _locker) internal {\\n appStorage().locks[0] = Lock(SafeCast.toUint64(_releaseAfter), _locker);\\n }\\n\\n function enforceRestrictionsInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__SignerMustBeUninitialized();\\n s.initStorage[0].restrictionsInitialized = 1;\\n }\\n\\n function setRestrictionsUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__AccountAlreadyUninitialized();\\n s.initStorage[0].restrictionsInitialized = 0;\\n }\\n}\\n\\ncontract BarzStorage {\\n AppStorage internal s;\\n modifier onlyWhenUnlocked() {\\n require(\\n uint64(block.timestamp) >= s.locks[0].release,\\n \\\"Account Locked\\\"\\n );\\n _;\\n }\\n modifier onlyWhenLocked() {\\n require(\\n uint64(block.timestamp) < s.locks[0].release,\\n \\\"Account Unlocked\\\"\\n );\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x48524007862a6ce0e07f645950613ce6513ce073c37a109c75019683d42bae27\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\\n bytes4(keccak256(\\\"verifyRestrictions(address,address,uint256,bytes)\\\"));\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // Default Fallback Handler of the barz.\\n IDiamondLoupe defaultFallbackHandler;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function enforceIsSelf() internal view {\\n require(msg.sender == address(this), \\\"LibDiamond: Caller not self\\\");\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n\\n unchecked {\\n facetIndex++;\\n }\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n\\n function restrictionsFacet() internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(\\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2cabdc00de859c3a3170ce3bda5d0e5fd3933d47ce904fd1585f9818b02572f8\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\nimport {LibDiamond} from \\\"./LibDiamond.sol\\\";\\n\\n/**\\n * @title LibLoupe\\n * @dev Internal Library to provide utility feature for reading the state of diamond facets\\n * Originally from Diamond's implementation of Mudgen(author of EIP-2535)\\n */\\nlibrary LibLoupe {\\n /// @notice Gets all facets and their selectors.\\n /// @return facets_ Facet\\n function facets()\\n internal\\n view\\n returns (IDiamondLoupe.Facet[] memory facets_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facets_ = new IDiamondLoupe.Facet[](ds.selectorCount);\\n uint16[] memory numFacetSelectors = new uint16[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facets_[facetIndex].facetAddress == facetAddress_) {\\n facets_[facetIndex].functionSelectors[\\n numFacetSelectors[facetIndex]\\n ] = selector;\\n // probably will never have more than 256 functions from one facet contract\\n require(numFacetSelectors[facetIndex] < 255);\\n numFacetSelectors[facetIndex]++;\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facets_[numFacets].facetAddress = facetAddress_;\\n facets_[numFacets].functionSelectors = new bytes4[](\\n ds.selectorCount\\n );\\n facets_[numFacets].functionSelectors[0] = selector;\\n numFacetSelectors[numFacets] = 1;\\n numFacets++;\\n }\\n }\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n uint256 numSelectors = numFacetSelectors[facetIndex];\\n bytes4[] memory selectors = facets_[facetIndex].functionSelectors;\\n // setting the number of selectors\\n assembly {\\n mstore(selectors, numSelectors)\\n }\\n }\\n // setting the number of facets\\n assembly {\\n mstore(facets_, numFacets)\\n }\\n }\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return _facetFunctionSelectors The selectors associated with a facet address.\\n function facetFunctionSelectors(\\n address _facet\\n ) internal view returns (bytes4[] memory _facetFunctionSelectors) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n uint256 numSelectors;\\n _facetFunctionSelectors = new bytes4[](ds.selectorCount);\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facet = address(bytes20(ds.facets[selector]));\\n if (_facet == facet) {\\n _facetFunctionSelectors[numSelectors] = selector;\\n numSelectors++;\\n }\\n }\\n }\\n // Set the number of selectors in the array\\n assembly {\\n mstore(_facetFunctionSelectors, numSelectors)\\n }\\n }\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n internal\\n view\\n returns (address[] memory facetAddresses_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetAddresses_ = new address[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facetAddress_ == facetAddresses_[facetIndex]) {\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facetAddresses_[numFacets] = facetAddress_;\\n numFacets++;\\n }\\n }\\n // Set the number of facet addresses in the array\\n assembly {\\n mstore(facetAddresses_, numFacets)\\n }\\n }\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(LibDiamond.diamondStorage().facets[_functionSelector])\\n );\\n }\\n}\\n\",\"keccak256\":\"0x0b11439c3cc657095e15ec2241fdcf67204b14001357b612fc5db4ff9e760a5a\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5061001961001e565b61008e565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb554610100900460ff1615610070576040516338fc28cb60e01b815260040160405180910390fd5b600080805260209190915260409020805461ff001916610100179055565b6129b6806200009e6000396000f3fe608060405234801561001057600080fd5b50600436106100725760003560e01c8063b0d691fe11610050578063b0d691fe146100c5578063b61d27f61461010c578063d087d2881461011f57600080fd5b80633a871cdd1461007757806347e1da2a1461009d5780634a936417146100b2575b600080fd5b61008a610085366004611fb5565b610127565b6040519081526020015b60405180910390f35b6100b06100ab366004612055565b61014d565b005b61008a6100c036600461215a565b610450565b60015465010000000000900473ffffffffffffffffffffffffffffffffffffffff1660405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610094565b6100b061011a3660046121ce565b6106d0565b61008a61089d565b600061013161095e565b61013b8484610a16565b905061014682610c5d565b9392505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff9081164290911610156101f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064015b60405180910390fd5b6101fd61095e565b848114158061020c5750848314155b15610243576040517fdde5716100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006102b87fac87185d000000000000000000000000000000000000000000000000000000006000527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020527f6d9f2463c8c0d8cb8be556a773ab21d4321328909a1725f2ef7cae0c320e95da5460601c90565b905073ffffffffffffffffffffffffffffffffffffffff811661038f5760005b86811015610389576103818888838181106102f5576102f5612228565b905060200201602081019061030a9190612257565b87878481811061031c5761031c612228565b9050602002013586868581811061033557610335612228565b90506020028101906103479190612272565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610cc892505050565b6001016102d8565b50610447565b60005b868110156104455761043d8888838181106103af576103af612228565b90506020020160208101906103c49190612257565b8787848181106103d6576103d6612228565b905060200201358686858181106103ef576103ef612228565b90506020028101906104019190612272565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250889250610d45915050565b600101610392565b505b50505050505050565b600061045a610e0d565b6001805473ffffffffffffffffffffffffffffffffffffffff88811665010000000000027fffffffffffffff0000000000000000000000000000000000000000ffffffffff90921691909117909155600280548783167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216179091557f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd492380549287169290911691909117905561051187610eb3565b60008383604051602401610526929190612320565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fcd9b47e40000000000000000000000000000000000000000000000000000000017905251909150600090819073ffffffffffffffffffffffffffffffffffffffff8b16906105c8908590612360565b600060405180830381855af49150503d8060008114610603576040519150601f19603f3d011682016040523d82523d6000602084013e610608565b606091505b5091509150811580610623575061061e8161237c565b600114155b1561065a576040517f1602372100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60019350858560405161066e9291906123c1565b60405190819003812060015490916501000000000090910473ffffffffffffffffffffffffffffffffffffffff16907fd429ff0b972be4ae725700a373d05007287994e4c86cb83315b43ffa85b595fd90600090a35050509695505050505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610773576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064016101ec565b61077b61095e565b60006107f07fac87185d000000000000000000000000000000000000000000000000000000006000527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020527f6d9f2463c8c0d8cb8be556a773ab21d4321328909a1725f2ef7cae0c320e95da5460601c90565b905073ffffffffffffffffffffffffffffffffffffffff81166108535761084e858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610cc892505050565b610896565b610896858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250879250610d45915050565b5050505050565b60015460009065010000000000900473ffffffffffffffffffffffffffffffffffffffff166040517f35567e1a0000000000000000000000000000000000000000000000000000000081523060048201526000602482015273ffffffffffffffffffffffffffffffffffffffff91909116906335567e1a90604401602060405180830381865afa158015610935573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061095991906123d1565b905090565b60015465010000000000900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a14576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f6163636f756e743a206e6f742066726f6d20456e747279506f696e740000000060448201526064016101ec565b565b600154610100900460e01b7fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604081205460601c80610aab576040517f6eb2360200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600154604051600091610100900460e01b90610acd908790879060240161244e565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090506000808373ffffffffffffffffffffffffffffffffffffffff1683604051610b549190612360565b600060405180830381855af49150503d8060008114610b8f576040519150601f19603f3d011682016040523d82523d6000602084013e610b94565b606091505b509150915081610bd0576040517f3cbbb65000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610bd98161237c565b94506000859003610c1c576040518681527f19e781916118c373dadcb7776fae0a2dbb6bbdeedae143ce68031e22801ef8659060200160405180910390a1610c50565b6040518681527fbbfee2df7f28b899771f1015dc85d7840ff9f6162f23f6aa99686e8fbd2ce1319060200160405180910390a15b5050505092915050565b50565b8015610c5a5760405160009033907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90849084818181858888f193505050503d8060008114610896576040519150601f19603f3d011682016040523d82523d6000602084013e610896565b6000808473ffffffffffffffffffffffffffffffffffffffff168484604051610cf19190612360565b60006040518083038185875af1925050503d8060008114610d2e576040519150601f19603f3d011682016040523d82523d6000602084013e610d33565b606091505b50915091508161089657805160208201fd5b610d5181858585611117565b15610d88576040517f01f595e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000808573ffffffffffffffffffffffffffffffffffffffff168585604051610db19190612360565b60006040518083038185875af1925050503d8060008114610dee576040519150601f19603f3d011682016040523d82523d6000602084013e610df3565b606091505b509150915081610e0557805160208201fd5b505050505050565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb554610100900460ff1615610e78576040517f38fc28cb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100179055565b604080516001808252818301909252600091816020015b60408051606080820183526000808352602083015291810191909152815260200190600190039081610eca57905050905060008273ffffffffffffffffffffffffffffffffffffffff16633253960f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f6c9190612592565b604080516003808252608082019092529192506000919060208201606080368337019050509050631626ba7e60e01b81600081518110610fae57610fae612228565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681525050818160018151811061100e5761100e612228565b7fffffffff000000000000000000000000000000000000000000000000000000009092166020928302919091019091015280517f8da5cb5b00000000000000000000000000000000000000000000000000000000908290600290811061107657611076612228565b7fffffffff00000000000000000000000000000000000000000000000000000000909216602092830291909101820152604080516060810190915273ffffffffffffffffffffffffffffffffffffffff861681529081016000815260200182815250836000815181106110eb576110eb612228565b602002602001018190525061111183600060405180602001604052806000815250611264565b50505050565b60008030858585604051602401611131949392919061264d565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fac87185d0000000000000000000000000000000000000000000000000000000017905251909150600090819073ffffffffffffffffffffffffffffffffffffffff8916906111d3908590612360565b600060405180830381855af49150503d806000811461120e576040519150601f19603f3d011682016040523d82523d6000602084013e611213565b606091505b50915091508161124f576040517f01f595e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6112588161237c565b98975050505050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921547f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff8116908190600090600716156112d35750600381901c60009081526001840160205260409020545b60005b87518110156113505761134383838a84815181106112f6576112f6612228565b6020026020010151600001518b858151811061131457611314612228565b6020026020010151602001518c868151811061133257611332612228565b6020026020010151604001516113f0565b90935091506001016112d6565b50828214611389576002840180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff84161790555b60078216156113ab57600382901c600090815260018501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb6738787876040516113de93929190612696565b60405180910390a16104478686611e81565b600080807f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f905060008451116114a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f2063757400000000000000000000000000000000000000000060648201526084016101ec565b60008560028111156114bc576114bc6125d4565b0361168c576114e38660405180606001604052806024815260200161290d60249139611f7a565b60005b845181101561168657600085828151811061150357611503612228565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c156115d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c726561647920657869737473000000000000000000000060648201526084016101ec565b7fffffffff0000000000000000000000000000000000000000000000000000000080831660008181526020879052604090207fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608d901b168e17905560e060058e901b811692831c199c909c1690821c179a81900361166a5760038c901c600090815260018601602052604081209b909b555b8b6116748161282d565b9c5050600190930192506114e6915050565b50611e75565b60018560028111156116a0576116a06125d4565b03611990576116c78660405180606001604052806028815260200161295960289139611f7a565b60005b84518110156116865760008582815181106116e7576116e7612228565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c3081036117bc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4c69624469616d6f6e644375743a2043616e2774207265706c61636520696d6d60448201527f757461626c652066756e6374696f6e000000000000000000000000000000000060648201526084016101ec565b8973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611877576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e000000000000000060648201526084016101ec565b73ffffffffffffffffffffffffffffffffffffffff811661191a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e207468617420646f65736e2774206578697374000000000000000060648201526084016101ec565b507fffffffff0000000000000000000000000000000000000000000000000000000090911660009081526020849052604090206bffffffffffffffffffffffff919091167fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608a901b161790556001016116ca565b60028560028111156119a4576119a46125d4565b03611ded5773ffffffffffffffffffffffffffffffffffffffff861615611a4d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d75737420626520616464726573732830290000000000000000000060648201526084016101ec565b600388901c6007891660005b8651811015611dcd5760008a9003611a955782611a7581612865565b60008181526001870160205260409020549b50935060079250611aa39050565b81611a9f81612865565b9250505b6000806000808a8581518110611abb57611abb612228565b6020908102919091018101517fffffffff0000000000000000000000000000000000000000000000000000000081166000908152918a9052604090912054909150606081901c611b8d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e277420657869737400000000000000000060648201526084016101ec565b30606082901c03611c20576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e00000000000000000000000000000000000060648201526084016101ec565b600587901b8f901b94507fffffffff0000000000000000000000000000000000000000000000000000000080861690831614611cbe577fffffffff000000000000000000000000000000000000000000000000000000008516600090815260208a90526040902080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff83161790555b7fffffffff0000000000000000000000000000000000000000000000000000000091909116600090815260208990526040812055600381901c611fff16925060051b60e0169050858214611d53576000828152600188016020526040902080547fffffffff0000000000000000000000000000000000000000000000000000000080841c19909116908516831c179055611da4565b80837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c817fffffffff0000000000000000000000000000000000000000000000000000000060001b901c198e16179c505b84600003611dc257600086815260018801602052604081208190559c505b505050600101611a59565b5080611dda83600861289a565b611de491906128b7565b99505050611e75565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560448201527f74416374696f6e0000000000000000000000000000000000000000000000000060648201526084016101ec565b50959694955050505050565b73ffffffffffffffffffffffffffffffffffffffff8216611ea0575050565b611ec28260405180606001604052806028815260200161293160289139611f7a565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051611eea9190612360565b600060405180830381855af49150503d8060008114611f25576040519150601f19603f3d011682016040523d82523d6000602084013e611f2a565b606091505b50915091508161111157805115611f445780518082602001fd5b83836040517f192105d70000000000000000000000000000000000000000000000000000000081526004016101ec9291906128ca565b813b8181611111576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101ec91906128f9565b600080600060608486031215611fca57600080fd5b833567ffffffffffffffff811115611fe157600080fd5b84016101608187031215611ff457600080fd5b95602085013595506040909401359392505050565b60008083601f84011261201b57600080fd5b50813567ffffffffffffffff81111561203357600080fd5b6020830191508360208260051b850101111561204e57600080fd5b9250929050565b6000806000806000806060878903121561206e57600080fd5b863567ffffffffffffffff8082111561208657600080fd5b6120928a838b01612009565b909850965060208901359150808211156120ab57600080fd5b6120b78a838b01612009565b909650945060408901359150808211156120d057600080fd5b506120dd89828a01612009565b979a9699509497509295939492505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461211357600080fd5b919050565b60008083601f84011261212a57600080fd5b50813567ffffffffffffffff81111561214257600080fd5b60208301915083602082850101111561204e57600080fd5b60008060008060008060a0878903121561217357600080fd5b61217c876120ef565b955061218a602088016120ef565b9450612198604088016120ef565b93506121a6606088016120ef565b9250608087013567ffffffffffffffff8111156121c257600080fd5b6120dd89828a01612118565b600080600080606085870312156121e457600080fd5b6121ed856120ef565b935060208501359250604085013567ffffffffffffffff81111561221057600080fd5b61221c87828801612118565b95989497509550505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561226957600080fd5b610146826120ef565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126122a757600080fd5b83018035915067ffffffffffffffff8211156122c257600080fd5b60200191503681900382131561204e57600080fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b6020815260006123346020830184866122d7565b949350505050565b60005b8381101561235757818101518382015260200161233f565b50506000910152565b6000825161237281846020870161233c565b9190910192915050565b805160208083015191908110156123bb577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8160200360031b1b821691505b50919050565b8183823760009101908152919050565b6000602082840312156123e357600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261241f57600080fd5b830160208101925035905067ffffffffffffffff81111561243f57600080fd5b80360382131561204e57600080fd5b6040815261247c60408201612462856120ef565b73ffffffffffffffffffffffffffffffffffffffff169052565b60208301356060820152600061249560408501856123ea565b6101608060808601526124ad6101a0860183856122d7565b92506124bc60608801886123ea565b92507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0808786030160a08801526124f48585846122d7565b9450608089013560c088015260a089013560e0880152610100935060c089013584880152610120915060e089013582880152610140848a01358189015261253d838b018b6123ea565b955092508188870301848901526125558686856122d7565b9550612563818b018b6123ea565b9550935050808786030161018088015250506125808383836122d7565b93505050508260208301529392505050565b6000602082840312156125a457600080fd5b81517fffffffff000000000000000000000000000000000000000000000000000000008116811461014657600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6000815180845261261b81602086016020860161233c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600073ffffffffffffffffffffffffffffffffffffffff80871683528086166020840152508360408301526080606083015261268c6080830184612603565b9695505050505050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b848110156127c1577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808a8503018652815188850173ffffffffffffffffffffffffffffffffffffffff82511686528482015160038110612748577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b808310156127ac5783517fffffffff0000000000000000000000000000000000000000000000000000000016825292860192600192909201919086019061276a565b509785019795505050908201906001016126bf565b505073ffffffffffffffffffffffffffffffffffffffff8a169088015286810360408801526127f08189612603565b9a9950505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361285e5761285e6127fe565b5060010190565b600081612874576128746127fe565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b80820281158282048414176128b1576128b16127fe565b92915050565b808201808211156128b1576128b16127fe565b73ffffffffffffffffffffffffffffffffffffffff831681526040602082015260006123346040830184612603565b602081526000610146602083018461260356fe4c69624469616d6f6e644375743a2041646420666163657420686173206e6f20636f64654c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a205265706c61636520666163657420686173206e6f20636f6465a2646970667358221220a952f19990a20474450919a2df9ddff4430a71350892e0954f2bb073575ad64864736f6c63430008150033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100725760003560e01c8063b0d691fe11610050578063b0d691fe146100c5578063b61d27f61461010c578063d087d2881461011f57600080fd5b80633a871cdd1461007757806347e1da2a1461009d5780634a936417146100b2575b600080fd5b61008a610085366004611fb5565b610127565b6040519081526020015b60405180910390f35b6100b06100ab366004612055565b61014d565b005b61008a6100c036600461215a565b610450565b60015465010000000000900473ffffffffffffffffffffffffffffffffffffffff1660405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610094565b6100b061011a3660046121ce565b6106d0565b61008a61089d565b600061013161095e565b61013b8484610a16565b905061014682610c5d565b9392505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff9081164290911610156101f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064015b60405180910390fd5b6101fd61095e565b848114158061020c5750848314155b15610243576040517fdde5716100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006102b87fac87185d000000000000000000000000000000000000000000000000000000006000527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020527f6d9f2463c8c0d8cb8be556a773ab21d4321328909a1725f2ef7cae0c320e95da5460601c90565b905073ffffffffffffffffffffffffffffffffffffffff811661038f5760005b86811015610389576103818888838181106102f5576102f5612228565b905060200201602081019061030a9190612257565b87878481811061031c5761031c612228565b9050602002013586868581811061033557610335612228565b90506020028101906103479190612272565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610cc892505050565b6001016102d8565b50610447565b60005b868110156104455761043d8888838181106103af576103af612228565b90506020020160208101906103c49190612257565b8787848181106103d6576103d6612228565b905060200201358686858181106103ef576103ef612228565b90506020028101906104019190612272565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250889250610d45915050565b600101610392565b505b50505050505050565b600061045a610e0d565b6001805473ffffffffffffffffffffffffffffffffffffffff88811665010000000000027fffffffffffffff0000000000000000000000000000000000000000ffffffffff90921691909117909155600280548783167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216179091557f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd492380549287169290911691909117905561051187610eb3565b60008383604051602401610526929190612320565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fcd9b47e40000000000000000000000000000000000000000000000000000000017905251909150600090819073ffffffffffffffffffffffffffffffffffffffff8b16906105c8908590612360565b600060405180830381855af49150503d8060008114610603576040519150601f19603f3d011682016040523d82523d6000602084013e610608565b606091505b5091509150811580610623575061061e8161237c565b600114155b1561065a576040517f1602372100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60019350858560405161066e9291906123c1565b60405190819003812060015490916501000000000090910473ffffffffffffffffffffffffffffffffffffffff16907fd429ff0b972be4ae725700a373d05007287994e4c86cb83315b43ffa85b595fd90600090a35050509695505050505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610773576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064016101ec565b61077b61095e565b60006107f07fac87185d000000000000000000000000000000000000000000000000000000006000527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020527f6d9f2463c8c0d8cb8be556a773ab21d4321328909a1725f2ef7cae0c320e95da5460601c90565b905073ffffffffffffffffffffffffffffffffffffffff81166108535761084e858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610cc892505050565b610896565b610896858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250879250610d45915050565b5050505050565b60015460009065010000000000900473ffffffffffffffffffffffffffffffffffffffff166040517f35567e1a0000000000000000000000000000000000000000000000000000000081523060048201526000602482015273ffffffffffffffffffffffffffffffffffffffff91909116906335567e1a90604401602060405180830381865afa158015610935573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061095991906123d1565b905090565b60015465010000000000900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a14576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f6163636f756e743a206e6f742066726f6d20456e747279506f696e740000000060448201526064016101ec565b565b600154610100900460e01b7fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604081205460601c80610aab576040517f6eb2360200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600154604051600091610100900460e01b90610acd908790879060240161244e565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090506000808373ffffffffffffffffffffffffffffffffffffffff1683604051610b549190612360565b600060405180830381855af49150503d8060008114610b8f576040519150601f19603f3d011682016040523d82523d6000602084013e610b94565b606091505b509150915081610bd0576040517f3cbbb65000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610bd98161237c565b94506000859003610c1c576040518681527f19e781916118c373dadcb7776fae0a2dbb6bbdeedae143ce68031e22801ef8659060200160405180910390a1610c50565b6040518681527fbbfee2df7f28b899771f1015dc85d7840ff9f6162f23f6aa99686e8fbd2ce1319060200160405180910390a15b5050505092915050565b50565b8015610c5a5760405160009033907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90849084818181858888f193505050503d8060008114610896576040519150601f19603f3d011682016040523d82523d6000602084013e610896565b6000808473ffffffffffffffffffffffffffffffffffffffff168484604051610cf19190612360565b60006040518083038185875af1925050503d8060008114610d2e576040519150601f19603f3d011682016040523d82523d6000602084013e610d33565b606091505b50915091508161089657805160208201fd5b610d5181858585611117565b15610d88576040517f01f595e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000808573ffffffffffffffffffffffffffffffffffffffff168585604051610db19190612360565b60006040518083038185875af1925050503d8060008114610dee576040519150601f19603f3d011682016040523d82523d6000602084013e610df3565b606091505b509150915081610e0557805160208201fd5b505050505050565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb554610100900460ff1615610e78576040517f38fc28cb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100179055565b604080516001808252818301909252600091816020015b60408051606080820183526000808352602083015291810191909152815260200190600190039081610eca57905050905060008273ffffffffffffffffffffffffffffffffffffffff16633253960f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f6c9190612592565b604080516003808252608082019092529192506000919060208201606080368337019050509050631626ba7e60e01b81600081518110610fae57610fae612228565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681525050818160018151811061100e5761100e612228565b7fffffffff000000000000000000000000000000000000000000000000000000009092166020928302919091019091015280517f8da5cb5b00000000000000000000000000000000000000000000000000000000908290600290811061107657611076612228565b7fffffffff00000000000000000000000000000000000000000000000000000000909216602092830291909101820152604080516060810190915273ffffffffffffffffffffffffffffffffffffffff861681529081016000815260200182815250836000815181106110eb576110eb612228565b602002602001018190525061111183600060405180602001604052806000815250611264565b50505050565b60008030858585604051602401611131949392919061264d565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fac87185d0000000000000000000000000000000000000000000000000000000017905251909150600090819073ffffffffffffffffffffffffffffffffffffffff8916906111d3908590612360565b600060405180830381855af49150503d806000811461120e576040519150601f19603f3d011682016040523d82523d6000602084013e611213565b606091505b50915091508161124f576040517f01f595e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6112588161237c565b98975050505050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921547f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff8116908190600090600716156112d35750600381901c60009081526001840160205260409020545b60005b87518110156113505761134383838a84815181106112f6576112f6612228565b6020026020010151600001518b858151811061131457611314612228565b6020026020010151602001518c868151811061133257611332612228565b6020026020010151604001516113f0565b90935091506001016112d6565b50828214611389576002840180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff84161790555b60078216156113ab57600382901c600090815260018501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb6738787876040516113de93929190612696565b60405180910390a16104478686611e81565b600080807f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f905060008451116114a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f2063757400000000000000000000000000000000000000000060648201526084016101ec565b60008560028111156114bc576114bc6125d4565b0361168c576114e38660405180606001604052806024815260200161290d60249139611f7a565b60005b845181101561168657600085828151811061150357611503612228565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c156115d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c726561647920657869737473000000000000000000000060648201526084016101ec565b7fffffffff0000000000000000000000000000000000000000000000000000000080831660008181526020879052604090207fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608d901b168e17905560e060058e901b811692831c199c909c1690821c179a81900361166a5760038c901c600090815260018601602052604081209b909b555b8b6116748161282d565b9c5050600190930192506114e6915050565b50611e75565b60018560028111156116a0576116a06125d4565b03611990576116c78660405180606001604052806028815260200161295960289139611f7a565b60005b84518110156116865760008582815181106116e7576116e7612228565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c3081036117bc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4c69624469616d6f6e644375743a2043616e2774207265706c61636520696d6d60448201527f757461626c652066756e6374696f6e000000000000000000000000000000000060648201526084016101ec565b8973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611877576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e000000000000000060648201526084016101ec565b73ffffffffffffffffffffffffffffffffffffffff811661191a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e207468617420646f65736e2774206578697374000000000000000060648201526084016101ec565b507fffffffff0000000000000000000000000000000000000000000000000000000090911660009081526020849052604090206bffffffffffffffffffffffff919091167fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608a901b161790556001016116ca565b60028560028111156119a4576119a46125d4565b03611ded5773ffffffffffffffffffffffffffffffffffffffff861615611a4d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d75737420626520616464726573732830290000000000000000000060648201526084016101ec565b600388901c6007891660005b8651811015611dcd5760008a9003611a955782611a7581612865565b60008181526001870160205260409020549b50935060079250611aa39050565b81611a9f81612865565b9250505b6000806000808a8581518110611abb57611abb612228565b6020908102919091018101517fffffffff0000000000000000000000000000000000000000000000000000000081166000908152918a9052604090912054909150606081901c611b8d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e277420657869737400000000000000000060648201526084016101ec565b30606082901c03611c20576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e00000000000000000000000000000000000060648201526084016101ec565b600587901b8f901b94507fffffffff0000000000000000000000000000000000000000000000000000000080861690831614611cbe577fffffffff000000000000000000000000000000000000000000000000000000008516600090815260208a90526040902080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff83161790555b7fffffffff0000000000000000000000000000000000000000000000000000000091909116600090815260208990526040812055600381901c611fff16925060051b60e0169050858214611d53576000828152600188016020526040902080547fffffffff0000000000000000000000000000000000000000000000000000000080841c19909116908516831c179055611da4565b80837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c817fffffffff0000000000000000000000000000000000000000000000000000000060001b901c198e16179c505b84600003611dc257600086815260018801602052604081208190559c505b505050600101611a59565b5080611dda83600861289a565b611de491906128b7565b99505050611e75565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560448201527f74416374696f6e0000000000000000000000000000000000000000000000000060648201526084016101ec565b50959694955050505050565b73ffffffffffffffffffffffffffffffffffffffff8216611ea0575050565b611ec28260405180606001604052806028815260200161293160289139611f7a565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051611eea9190612360565b600060405180830381855af49150503d8060008114611f25576040519150601f19603f3d011682016040523d82523d6000602084013e611f2a565b606091505b50915091508161111157805115611f445780518082602001fd5b83836040517f192105d70000000000000000000000000000000000000000000000000000000081526004016101ec9291906128ca565b813b8181611111576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101ec91906128f9565b600080600060608486031215611fca57600080fd5b833567ffffffffffffffff811115611fe157600080fd5b84016101608187031215611ff457600080fd5b95602085013595506040909401359392505050565b60008083601f84011261201b57600080fd5b50813567ffffffffffffffff81111561203357600080fd5b6020830191508360208260051b850101111561204e57600080fd5b9250929050565b6000806000806000806060878903121561206e57600080fd5b863567ffffffffffffffff8082111561208657600080fd5b6120928a838b01612009565b909850965060208901359150808211156120ab57600080fd5b6120b78a838b01612009565b909650945060408901359150808211156120d057600080fd5b506120dd89828a01612009565b979a9699509497509295939492505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461211357600080fd5b919050565b60008083601f84011261212a57600080fd5b50813567ffffffffffffffff81111561214257600080fd5b60208301915083602082850101111561204e57600080fd5b60008060008060008060a0878903121561217357600080fd5b61217c876120ef565b955061218a602088016120ef565b9450612198604088016120ef565b93506121a6606088016120ef565b9250608087013567ffffffffffffffff8111156121c257600080fd5b6120dd89828a01612118565b600080600080606085870312156121e457600080fd5b6121ed856120ef565b935060208501359250604085013567ffffffffffffffff81111561221057600080fd5b61221c87828801612118565b95989497509550505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561226957600080fd5b610146826120ef565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126122a757600080fd5b83018035915067ffffffffffffffff8211156122c257600080fd5b60200191503681900382131561204e57600080fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b6020815260006123346020830184866122d7565b949350505050565b60005b8381101561235757818101518382015260200161233f565b50506000910152565b6000825161237281846020870161233c565b9190910192915050565b805160208083015191908110156123bb577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8160200360031b1b821691505b50919050565b8183823760009101908152919050565b6000602082840312156123e357600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261241f57600080fd5b830160208101925035905067ffffffffffffffff81111561243f57600080fd5b80360382131561204e57600080fd5b6040815261247c60408201612462856120ef565b73ffffffffffffffffffffffffffffffffffffffff169052565b60208301356060820152600061249560408501856123ea565b6101608060808601526124ad6101a0860183856122d7565b92506124bc60608801886123ea565b92507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0808786030160a08801526124f48585846122d7565b9450608089013560c088015260a089013560e0880152610100935060c089013584880152610120915060e089013582880152610140848a01358189015261253d838b018b6123ea565b955092508188870301848901526125558686856122d7565b9550612563818b018b6123ea565b9550935050808786030161018088015250506125808383836122d7565b93505050508260208301529392505050565b6000602082840312156125a457600080fd5b81517fffffffff000000000000000000000000000000000000000000000000000000008116811461014657600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6000815180845261261b81602086016020860161233c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600073ffffffffffffffffffffffffffffffffffffffff80871683528086166020840152508360408301526080606083015261268c6080830184612603565b9695505050505050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b848110156127c1577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808a8503018652815188850173ffffffffffffffffffffffffffffffffffffffff82511686528482015160038110612748577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b808310156127ac5783517fffffffff0000000000000000000000000000000000000000000000000000000016825292860192600192909201919086019061276a565b509785019795505050908201906001016126bf565b505073ffffffffffffffffffffffffffffffffffffffff8a169088015286810360408801526127f08189612603565b9a9950505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361285e5761285e6127fe565b5060010190565b600081612874576128746127fe565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b80820281158282048414176128b1576128b16127fe565b92915050565b808201808211156128b1576128b16127fe565b73ffffffffffffffffffffffffffffffffffffffff831681526040602082015260006123346040830184612603565b602081526000610146602083018461260356fe4c69624469616d6f6e644375743a2041646420666163657420686173206e6f20636f64654c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a205265706c61636520666163657420686173206e6f20636f6465a2646970667358221220a952f19990a20474450919a2df9ddff4430a71350892e0954f2bb073575ad64864736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "Account module contract that provides the account features and initialization of signer compatible with EIP-1271 & EIP-4337", + "kind": "dev", + "methods": { + "execute(address,uint256,bytes)": { + "details": "This method executes the calldata coming from the EntryPoint. Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)", + "params": { + "_dest": "Address of destination where the call will be forwarded to", + "_func": "Bytes of calldata to execute in the destination address", + "_value": "Amount of native coin the owner is willing to send(e.g. ETH, BNB)" + } + }, + "executeBatch(address[],uint256[],bytes[])": { + "details": "This method batch executes the calldata coming from the EntryPoint. Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)", + "params": { + "_dest": "Array of addresses of destination where the call will be forwarded to", + "_func": "Array of bytes of calldata to execute in the destination address", + "_value": "Array of amount of native coin the owner is willing to send(e.g. ETH, BNB)" + } + }, + "initialize(address,address,address,address,bytes)": { + "details": "This method can only be called during the initialization or signature migration. If the proxy contract was created without initialization, anyone can call initialize. Barz calls initialize in constructor in an atomic transaction during deployment", + "params": { + "_anEntryPoint": "Entrypoint contract defined in EIP-4337 handling the flow of UserOp", + "_defaultFallBackHandler": "Middleware contract for default facets", + "_facetRegistry": "Registry of Facets that hold all facet information", + "_ownerPublicKey": "Bytes of owner public key", + "_verificationFacet": "Facet contract handling the verificationi" + } + } + }, + "title": "Account Facet", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "constructor": { + "notice": "This constructor ensures that this contract can only be used as singleton for Proxy contracts" + }, + "entryPoint()": { + "notice": "Returns the address of EntryPoint contract registered to Barz account" + }, + "execute(address,uint256,bytes)": { + "notice": "Calls the destination with inputted calldata and value from EntryPoint" + }, + "executeBatch(address[],uint256[],bytes[])": { + "notice": "Batch calls the destination with inputted calldata and value from EntryPoint" + }, + "getNonce()": { + "notice": "Return the account nonce. This method returns the next sequential nonce. For a nonce of a specific key, use `entrypoint.getNonce(account, key)`" + }, + "initialize(address,address,address,address,bytes)": { + "notice": "Initializes the initial storage of the Barz contract." + }, + "validateUserOp((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256)": { + "notice": "Validate user's signature and nonce. subclass doesn't need to override this method. Instead, it should override the specific internal validation methods." + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 27866, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "s", + "offset": 0, + "slot": "0", + "type": "t_struct(AppStorage)27613_storage" + } + ], + "types": { + "t_bytes4": { + "encoding": "inplace", + "label": "bytes4", + "numberOfBytes": "4" + }, + "t_contract(IEntryPoint)12286": { + "encoding": "inplace", + "label": "contract IEntryPoint", + "numberOfBytes": "20" + }, + "t_contract(IFacetRegistry)26148": { + "encoding": "inplace", + "label": "contract IFacetRegistry", + "numberOfBytes": "20" + }, + "t_mapping(t_uint256,t_struct(InitializersStorage)27592_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => struct InitializersStorage)", + "numberOfBytes": "32", + "value": "t_struct(InitializersStorage)27592_storage" + }, + "t_mapping(t_uint256,t_struct(Lock)27585_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => struct Lock)", + "numberOfBytes": "32", + "value": "t_struct(Lock)27585_storage" + }, + "t_struct(AppStorage)27613_storage": { + "encoding": "inplace", + "label": "struct AppStorage", + "members": [ + { + "astId": 27597, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "initStorage", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_uint256,t_struct(InitializersStorage)27592_storage)" + }, + { + "astId": 27599, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "signerMigration", + "offset": 0, + "slot": "1", + "type": "t_uint8" + }, + { + "astId": 27601, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "validateOwnerSignatureSelector", + "offset": 1, + "slot": "1", + "type": "t_bytes4" + }, + { + "astId": 27604, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "entryPoint", + "offset": 5, + "slot": "1", + "type": "t_contract(IEntryPoint)12286" + }, + { + "astId": 27607, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "facetRegistry", + "offset": 0, + "slot": "2", + "type": "t_contract(IFacetRegistry)26148" + }, + { + "astId": 27612, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "locks", + "offset": 0, + "slot": "3", + "type": "t_mapping(t_uint256,t_struct(Lock)27585_storage)" + } + ], + "numberOfBytes": "128" + }, + "t_struct(InitializersStorage)27592_storage": { + "encoding": "inplace", + "label": "struct InitializersStorage", + "members": [ + { + "astId": 27587, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "signerInitialized", + "offset": 0, + "slot": "0", + "type": "t_uint8" + }, + { + "astId": 27589, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "accountInitialized", + "offset": 1, + "slot": "0", + "type": "t_uint8" + }, + { + "astId": 27591, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "restrictionsInitialized", + "offset": 2, + "slot": "0", + "type": "t_uint8" + } + ], + "numberOfBytes": "32" + }, + "t_struct(Lock)27585_storage": { + "encoding": "inplace", + "label": "struct Lock", + "members": [ + { + "astId": 27582, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "release", + "offset": 0, + "slot": "0", + "type": "t_uint64" + }, + { + "astId": 27584, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "locker", + "offset": 8, + "slot": "0", + "type": "t_bytes4" + } + ], + "numberOfBytes": "32" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint64": { + "encoding": "inplace", + "label": "uint64", + "numberOfBytes": "8" + }, + "t_uint8": { + "encoding": "inplace", + "label": "uint8", + "numberOfBytes": "1" + } + } + } +} \ No newline at end of file diff --git a/deployments/blast/BarzFactory.json b/deployments/blast/BarzFactory.json new file mode 100644 index 0000000..f249449 --- /dev/null +++ b/deployments/blast/BarzFactory.json @@ -0,0 +1,318 @@ +{ + "address": "0x729c310186a57833f622630a16d13f710b83272a", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_accountFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_entryPoint", + "type": "address" + }, + { + "internalType": "address", + "name": "_facetRegistry", + "type": "address" + }, + { + "internalType": "address", + "name": "_defaultFallback", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "BarzDeployed", + "type": "event" + }, + { + "inputs": [], + "name": "accountFacet", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_verificationFacet", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_owner", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "_salt", + "type": "uint256" + } + ], + "name": "createAccount", + "outputs": [ + { + "internalType": "contract Barz", + "name": "barz", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "defaultFallback", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "entryPoint", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetRegistry", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_verificationFacet", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_owner", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "_salt", + "type": "uint256" + } + ], + "name": "getAddress", + "outputs": [ + { + "internalType": "address", + "name": "barzAddress", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_accountFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_verificationFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_entryPoint", + "type": "address" + }, + { + "internalType": "address", + "name": "_facetRegistry", + "type": "address" + }, + { + "internalType": "address", + "name": "_defaultFallback", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_ownerPublicKey", + "type": "bytes" + } + ], + "name": "getBytecode", + "outputs": [ + { + "internalType": "bytes", + "name": "barzBytecode", + "type": "bytes" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "getCreationCode", + "outputs": [ + { + "internalType": "bytes", + "name": "creationCode", + "type": "bytes" + } + ], + "stateMutability": "pure", + "type": "function" + } + ], + "transactionHash": "0x57c229bf23b12debf4227ee745f40ba31d9d69d670a5a42d020f41b07767de6f", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 3, + "gasUsed": "802000", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x76b1ce4aed12dd880dfd47c807d7edce2e9be023e76a23e35e55af3ef60a5a5f", + "transactionHash": "0x57c229bf23b12debf4227ee745f40ba31d9d69d670a5a42d020f41b07767de6f", + "logs": [], + "blockNumber": 1317821, + "cumulativeGasUsed": "990314", + "status": 1, + "byzantium": true + }, + "args": [ + "0xFde53272dcd7938d16E031A6989753c321728332", + "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789", + "0xAfCb70e6e9514E2A15B23A01d2a9b9f7A34f2c33", + "0x2e7f1dAe1F3799d20f5c31bEFdc7A620f664728D" + ], + "numDeployments": 1, + "solcInputHash": "ad34345aa73d96f52b3e14df983b6b29", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_accountFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_entryPoint\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_facetRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_defaultFallback\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"BarzDeployed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"accountFacet\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_verificationFacet\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_owner\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_salt\",\"type\":\"uint256\"}],\"name\":\"createAccount\",\"outputs\":[{\"internalType\":\"contract Barz\",\"name\":\"barz\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"defaultFallback\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"entryPoint\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetRegistry\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_verificationFacet\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_owner\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_salt\",\"type\":\"uint256\"}],\"name\":\"getAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"barzAddress\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_accountFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_verificationFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_entryPoint\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_facetRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_defaultFallback\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_ownerPublicKey\",\"type\":\"bytes\"}],\"name\":\"getBytecode\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"barzBytecode\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCreationCode\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"creationCode\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"Contract to easily deploy Barz to a pre-computed address with a single call\",\"kind\":\"dev\",\"methods\":{\"constructor\":{\"params\":{\"_accountFacet\":\"Account Facet to be used to create Barz\",\"_defaultFallback\":\"Default Fallback Handler to be used to create Barz\",\"_entryPoint\":\"Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\",\"_facetRegistry\":\"Facet Registry to be used to create Barz\"}},\"createAccount(address,bytes,uint256)\":{\"params\":{\"_owner\":\"Public Key of the owner to initialize barz account\",\"_salt\":\"Salt used for deploying barz with create2\",\"_verificationFacet\":\"Address of verification facet used for creating the barz account\"},\"returns\":{\"barz\":\"Instance of Barz contract deployed with the given parameters\"}},\"getAddress(address,bytes,uint256)\":{\"params\":{\"_owner\":\"Public Key of the owner to initialize barz account\",\"_salt\":\"Salt used for deploying barz with create2\",\"_verificationFacet\":\"Address of verification facet used for creating the barz account\"},\"returns\":{\"barzAddress\":\"Precalculated Barz address\"}},\"getBytecode(address,address,address,address,address,bytes)\":{\"params\":{\"_accountFacet\":\"Account Facet to be used to create Barz\",\"_defaultFallback\":\"Default Fallback Handler to be used to create Barz\",\"_entryPoint\":\"Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\",\"_facetRegistry\":\"Facet Registry to be used to create Barz\",\"_ownerPublicKey\":\"Public Key of owner to be used to initialize Barz ownership\",\"_verificationFacet\":\"Verification Facet to be used to create Barz\"},\"returns\":{\"barzBytecode\":\"Bytecode of Barz\"}},\"getCreationCode()\":{\"returns\":{\"creationCode\":\"Creation code of Barz\"}}},\"title\":\"Barz Factory\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"Sets the initialization data for Barz contract initialization\"},\"createAccount(address,bytes,uint256)\":{\"notice\":\"Creates the Barz with a single call. It creates the Barz contract with the givent verification facet\"},\"getAddress(address,bytes,uint256)\":{\"notice\":\"Calculates the address of Barz with the given parameters\"},\"getBytecode(address,address,address,address,address,bytes)\":{\"notice\":\"Returns the bytecode of Barz with the given parameter\"},\"getCreationCode()\":{\"notice\":\"Returns the creation code of the Barz contract\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/BarzFactory.sol\":\"BarzFactory\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"contracts/Barz.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {LibDiamond} from \\\"./libraries/LibDiamond.sol\\\";\\nimport {IBarz} from \\\"./interfaces/IBarz.sol\\\";\\n\\n/**\\n * @title Barz\\n * @dev A diamond proxy wallet with a modular & upgradeable architecture\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract Barz is IBarz {\\n /**\\n * @notice Initializes Barz with the given parameters. Barz account is intended to be created from Barz Factory for stable deployment.\\n * @dev This method makes a delegate call to account facet and account facet handles the initialization.\\n * With modular architecture, Barz encompasses wide spectrum of architecture and logic.\\n * The only requirement is account facet to comply with initialize() interface.\\n * Barz doesn't include built-in functions and is a full proxy, for maximum extensibility and modularity.\\n * @param _accountFacet Address of Account Facet in charge of the Barz initialization\\n * @param _verificationFacet Address of Verification Facet for verifying the signature. Could be any signature scheme\\n * @param _entryPoint Address of Entry Point contract\\n * @param _facetRegistry Address of Facet Registry. Facet Registry is a registry holding trusted facets that could be added to user's wallet\\n * @param _defaultFallBack Address of Default FallBack Handler. Middleware contract for more efficient deployment\\n * @param _ownerPublicKey Bytes of Owner Public Key using for initialization\\n */\\n constructor(\\n address _accountFacet,\\n address _verificationFacet,\\n address _entryPoint,\\n address _facetRegistry,\\n address _defaultFallBack,\\n bytes memory _ownerPublicKey\\n ) payable {\\n bytes memory initCall = abi.encodeWithSignature(\\n \\\"initialize(address,address,address,address,bytes)\\\",\\n _verificationFacet,\\n _entryPoint,\\n _facetRegistry,\\n _defaultFallBack,\\n _ownerPublicKey\\n );\\n (bool success, bytes memory result) = _accountFacet.delegatecall(\\n initCall\\n );\\n if (!success || uint256(bytes32(result)) != 1) {\\n revert Barz__InitializationFailure();\\n }\\n }\\n\\n /**\\n * @notice Fallback function for Barz complying with Diamond Standard with customization of adding Default Fallback Handler\\n * @dev Find facet for function that is called and execute the function if a facet is found and return any value.\\n */\\n fallback() external payable {\\n LibDiamond.DiamondStorage storage ds;\\n bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION;\\n // get diamond storage\\n assembly {\\n ds.slot := position\\n }\\n // get facet from function selector\\n address facet = address(bytes20(ds.facets[msg.sig]));\\n if (facet == address(0))\\n facet = ds.defaultFallbackHandler.facetAddress(msg.sig);\\n require(facet != address(0), \\\"Barz: Function does not exist\\\");\\n // Execute external function from facet using delegatecall and return any value.\\n assembly {\\n // copy function selector and any arguments\\n calldatacopy(0, 0, calldatasize())\\n // execute function call using the facet\\n let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)\\n // get any return value\\n returndatacopy(0, 0, returndatasize())\\n // return any return value or error back to the caller\\n switch result\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @notice Receive function to receive native token without data\\n */\\n receive() external payable {}\\n}\\n\",\"keccak256\":\"0xd1c773409a4b3d1ca0316445d9ea1d686bab9cd5f6731fbdb0766a93edfd7bdb\",\"license\":\"Apache-2.0\"},\"contracts/BarzFactory.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {Barz} from \\\"./Barz.sol\\\";\\nimport {IBarzFactory} from \\\"./interfaces/IBarzFactory.sol\\\";\\n\\n/**\\n * @title Barz Factory\\n * @dev Contract to easily deploy Barz to a pre-computed address with a single call\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract BarzFactory is IBarzFactory {\\n address public immutable accountFacet;\\n address public immutable entryPoint;\\n address public immutable facetRegistry;\\n address public immutable defaultFallback;\\n\\n /**\\n * @notice Sets the initialization data for Barz contract initialization\\n * @param _accountFacet Account Facet to be used to create Barz\\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\\n * @param _facetRegistry Facet Registry to be used to create Barz\\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\\n */\\n constructor(\\n address _accountFacet,\\n address _entryPoint,\\n address _facetRegistry,\\n address _defaultFallback\\n ) {\\n accountFacet = _accountFacet;\\n entryPoint = _entryPoint;\\n facetRegistry = _facetRegistry;\\n defaultFallback = _defaultFallback;\\n }\\n\\n /**\\n * @notice Creates the Barz with a single call. It creates the Barz contract with the givent verification facet\\n * @param _verificationFacet Address of verification facet used for creating the barz account\\n * @param _owner Public Key of the owner to initialize barz account\\n * @param _salt Salt used for deploying barz with create2\\n * @return barz Instance of Barz contract deployed with the given parameters\\n */\\n function createAccount(\\n address _verificationFacet,\\n bytes calldata _owner,\\n uint256 _salt\\n ) external override returns (Barz barz) {\\n address addr = getAddress(_verificationFacet, _owner, _salt);\\n uint codeSize = addr.code.length;\\n if (codeSize > 0) {\\n return Barz(payable(addr));\\n }\\n barz = new Barz{salt: bytes32(_salt)}(\\n accountFacet,\\n _verificationFacet,\\n entryPoint,\\n facetRegistry,\\n defaultFallback,\\n _owner\\n );\\n emit BarzDeployed(address(barz));\\n }\\n\\n /**\\n * @notice Calculates the address of Barz with the given parameters\\n * @param _verificationFacet Address of verification facet used for creating the barz account\\n * @param _owner Public Key of the owner to initialize barz account\\n * @param _salt Salt used for deploying barz with create2\\n * @return barzAddress Precalculated Barz address\\n */\\n function getAddress(\\n address _verificationFacet,\\n bytes calldata _owner,\\n uint256 _salt\\n ) public view override returns (address barzAddress) {\\n bytes memory bytecode = getBytecode(\\n accountFacet,\\n _verificationFacet,\\n entryPoint,\\n facetRegistry,\\n defaultFallback,\\n _owner\\n );\\n bytes32 hash = keccak256(\\n abi.encodePacked(\\n bytes1(0xff),\\n address(this),\\n _salt,\\n keccak256(bytecode)\\n )\\n );\\n barzAddress = address(uint160(uint256(hash)));\\n }\\n\\n /**\\n * @notice Returns the bytecode of Barz with the given parameter\\n * @param _accountFacet Account Facet to be used to create Barz\\n * @param _verificationFacet Verification Facet to be used to create Barz\\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\\n * @param _facetRegistry Facet Registry to be used to create Barz\\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\\n * @param _ownerPublicKey Public Key of owner to be used to initialize Barz ownership\\n * @return barzBytecode Bytecode of Barz\\n */\\n function getBytecode(\\n address _accountFacet,\\n address _verificationFacet,\\n address _entryPoint,\\n address _facetRegistry,\\n address _defaultFallback,\\n bytes calldata _ownerPublicKey\\n ) public pure override returns (bytes memory barzBytecode) {\\n bytes memory bytecode = type(Barz).creationCode;\\n barzBytecode = abi.encodePacked(\\n bytecode,\\n abi.encode(\\n _accountFacet,\\n _verificationFacet,\\n _entryPoint,\\n _facetRegistry,\\n _defaultFallback,\\n _ownerPublicKey\\n )\\n );\\n }\\n\\n /**\\n * @notice Returns the creation code of the Barz contract\\n * @return creationCode Creation code of Barz\\n */\\n function getCreationCode()\\n public\\n pure\\n override\\n returns (bytes memory creationCode)\\n {\\n creationCode = type(Barz).creationCode;\\n }\\n}\\n\",\"keccak256\":\"0x76d6058fa4714f5ef87b876e49ce7e21f581164901eea906ec743e82362b1df6\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IBarz.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Barz Interface\\n * @dev Interface of Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IBarz {\\n error Barz__InitializationFailure();\\n}\\n\",\"keccak256\":\"0xca9f0c2c1ad7d06088fa16ae92d587416f2d10d8f999d7afe8ca5c4d73410aba\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IBarzFactory.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {Barz} from \\\"../Barz.sol\\\";\\n\\n/**\\n * @title Barz Factory Interface\\n * @dev Interface of contract to easily deploy Barz to a pre-computed address with a single call\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IBarzFactory {\\n event BarzDeployed(address);\\n\\n function createAccount(\\n address verificationFacet,\\n bytes calldata owner,\\n uint256 salt\\n ) external returns (Barz);\\n\\n function getAddress(\\n address verificationFacet,\\n bytes calldata owner,\\n uint256 salt\\n ) external view returns (address);\\n\\n function getBytecode(\\n address accountFacet,\\n address verificationFacet,\\n address entryPoint,\\n address facetRegistry,\\n address defaultFallback,\\n bytes memory ownerPublicKey\\n ) external pure returns (bytes memory);\\n\\n function getCreationCode() external pure returns (bytes memory);\\n}\\n\",\"keccak256\":\"0xadb48a6f3025f6395e26ffd5f9319da73ad2383906c8223e8455f41f420fba26\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\\n bytes4(keccak256(\\\"verifyRestrictions(address,address,uint256,bytes)\\\"));\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // Default Fallback Handler of the barz.\\n IDiamondLoupe defaultFallbackHandler;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function enforceIsSelf() internal view {\\n require(msg.sender == address(this), \\\"LibDiamond: Caller not self\\\");\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n\\n unchecked {\\n facetIndex++;\\n }\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n\\n function restrictionsFacet() internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(\\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2cabdc00de859c3a3170ce3bda5d0e5fd3933d47ce904fd1585f9818b02572f8\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x61010060405234801561001157600080fd5b50604051610eba380380610eba8339810160408190526100309161006e565b6001600160a01b0393841660805291831660a052821660c0521660e0526100c2565b80516001600160a01b038116811461006957600080fd5b919050565b6000806000806080858703121561008457600080fd5b61008d85610052565b935061009b60208601610052565b92506100a960408601610052565b91506100b760608601610052565b905092959194509250565b60805160a05160c05160e051610d886101326000396000818161013b015281816102b3015261048101526000818160bf01528181610292015261046001526000818161016301528181610271015261043f01526000818161018b0152818161024f015261041d0152610d886000f3fe60806040523480156200001157600080fd5b5060043610620000925760003560e01c806344409a82116200006257806344409a821462000135578063b0d691fe146200015d578063b0f5d4641462000185578063c8a7adf514620001ad57600080fd5b8062c194db14620000975780630a1acd7314620000b9578063296601cd146200010757806333bb64a7146200011e575b600080fd5b620000a1620001c4565b604051620000b091906200056c565b60405180910390f35b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001620000b0565b620000e16200011836600462000635565b6200020e565b620000a16200012f36600462000695565b6200036d565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e1620001be36600462000635565b62000414565b606060405180602001620001d89062000538565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082820381018352601f90910116604052919050565b6000806200021f8686868662000414565b905073ffffffffffffffffffffffffffffffffffffffff81163b8015620002495750905062000365565b8360001b7f0000000000000000000000000000000000000000000000000000000000000000887f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008b8b604051620002e29062000538565b620002f497969594939291906200073a565b8190604051809103906000f590508015801562000315573d6000803e3d6000fd5b5060405173ffffffffffffffffffffffffffffffffffffffff821681529093507f9e6e326008e68f57877e2bae766a5745c162e42359e34834a7f0661fa82d31b19060200160405180910390a150505b949350505050565b6060600060405180602001620003839062000538565b6020820181038252601f19601f8201166040525090508089898989898989604051602001620003b997969594939291906200073a565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052620003f79291602001620007cd565b604051602081830303815290604052915050979650505050505050565b600080620004a87f0000000000000000000000000000000000000000000000000000000000000000877f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008a8a6200036d565b8051602091820120604080517fff00000000000000000000000000000000000000000000000000000000000000818501523060601b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001660218201526035810196909652605580870192909252805180870390920182526075909501909452835193019290922095945050505050565b610552806200080183390190565b60005b838110156200056357818101518382015260200162000549565b50506000910152565b60208152600082518060208401526200058d81604085016020870162000546565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b803573ffffffffffffffffffffffffffffffffffffffff81168114620005e457600080fd5b919050565b60008083601f840112620005fc57600080fd5b50813567ffffffffffffffff8111156200061557600080fd5b6020830191508360208285010111156200062e57600080fd5b9250929050565b600080600080606085870312156200064c57600080fd5b6200065785620005bf565b9350602085013567ffffffffffffffff8111156200067457600080fd5b6200068287828801620005e9565b9598909750949560400135949350505050565b600080600080600080600060c0888a031215620006b157600080fd5b620006bc88620005bf565b9650620006cc60208901620005bf565b9550620006dc60408901620005bf565b9450620006ec60608901620005bf565b9350620006fc60808901620005bf565b925060a088013567ffffffffffffffff8111156200071957600080fd5b620007278a828b01620005e9565b989b979a50959850939692959293505050565b600073ffffffffffffffffffffffffffffffffffffffff808a16835280891660208401528088166040840152808716606084015280861660808401525060c060a08301528260c0830152828460e0840137600060e0848401015260e07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f850116830101905098975050505050505050565b60008351620007e181846020880162000546565b835190830190620007f781836020880162000546565b0194935050505056fe608060405260405161055238038061055283398101604081905261002291610163565b6000858585858560405160240161003d959493929190610264565b60408051601f198184030181529181526020820180516001600160e01b0316634a93641760e01b1790525190915060009081906001600160a01b038a16906100869085906102c3565b600060405180830381855af49150503d80600081146100c1576040519150601f19603f3d011682016040523d82523d6000602084013e6100c6565b606091505b50915091508115806100e157506100dc816102df565b600114155b156100ff57604051636ff35f8960e01b815260040160405180910390fd5b505050505050505050610306565b80516001600160a01b038116811461012457600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101561015a578181015183820152602001610142565b50506000910152565b60008060008060008060c0878903121561017c57600080fd5b6101858761010d565b95506101936020880161010d565b94506101a16040880161010d565b93506101af6060880161010d565b92506101bd6080880161010d565b60a08801519092506001600160401b03808211156101da57600080fd5b818901915089601f8301126101ee57600080fd5b81518181111561020057610200610129565b604051601f8201601f19908116603f0116810190838211818310171561022857610228610129565b816040528281528c602084870101111561024157600080fd5b61025283602083016020880161013f565b80955050505050509295509295509295565b600060018060a01b0380881683528087166020840152808616604084015280851660608401525060a0608083015282518060a08401526102ab8160c085016020870161013f565b601f01601f19169190910160c0019695505050505050565b600082516102d581846020870161013f565b9190910192915050565b80516020808301519190811015610300576000198160200360031b1b821691505b50919050565b61023d806103156000396000f3fe60806040523661000b57005b600080357fffffffff000000000000000000000000000000000000000000000000000000001681527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020819052604090912054819060601c80610125576004838101546040517fcdffacc60000000000000000000000000000000000000000000000000000000081526000357fffffffff00000000000000000000000000000000000000000000000000000000169281019290925273ffffffffffffffffffffffffffffffffffffffff169063cdffacc690602401602060405180830381865afa1580156100fe573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061012291906101ca565b90505b73ffffffffffffffffffffffffffffffffffffffff81166101a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4261727a3a2046756e6374696f6e20646f6573206e6f74206578697374000000604482015260640160405180910390fd5b3660008037600080366000845af43d6000803e8080156101c5573d6000f35b3d6000fd5b6000602082840312156101dc57600080fd5b815173ffffffffffffffffffffffffffffffffffffffff8116811461020057600080fd5b939250505056fea26469706673582212200f3fa76ace3be8675d8b4c0d6c210a922fff2c2f1444023b817d1f6c908cd56a64736f6c63430008150033a2646970667358221220329ad45a4ef4915180001cb1fc90a5f97ad94a0b280426a580cba65fce28c0f164736f6c63430008150033", + "deployedBytecode": "0x60806040523480156200001157600080fd5b5060043610620000925760003560e01c806344409a82116200006257806344409a821462000135578063b0d691fe146200015d578063b0f5d4641462000185578063c8a7adf514620001ad57600080fd5b8062c194db14620000975780630a1acd7314620000b9578063296601cd146200010757806333bb64a7146200011e575b600080fd5b620000a1620001c4565b604051620000b091906200056c565b60405180910390f35b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001620000b0565b620000e16200011836600462000635565b6200020e565b620000a16200012f36600462000695565b6200036d565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e1620001be36600462000635565b62000414565b606060405180602001620001d89062000538565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082820381018352601f90910116604052919050565b6000806200021f8686868662000414565b905073ffffffffffffffffffffffffffffffffffffffff81163b8015620002495750905062000365565b8360001b7f0000000000000000000000000000000000000000000000000000000000000000887f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008b8b604051620002e29062000538565b620002f497969594939291906200073a565b8190604051809103906000f590508015801562000315573d6000803e3d6000fd5b5060405173ffffffffffffffffffffffffffffffffffffffff821681529093507f9e6e326008e68f57877e2bae766a5745c162e42359e34834a7f0661fa82d31b19060200160405180910390a150505b949350505050565b6060600060405180602001620003839062000538565b6020820181038252601f19601f8201166040525090508089898989898989604051602001620003b997969594939291906200073a565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052620003f79291602001620007cd565b604051602081830303815290604052915050979650505050505050565b600080620004a87f0000000000000000000000000000000000000000000000000000000000000000877f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008a8a6200036d565b8051602091820120604080517fff00000000000000000000000000000000000000000000000000000000000000818501523060601b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001660218201526035810196909652605580870192909252805180870390920182526075909501909452835193019290922095945050505050565b610552806200080183390190565b60005b838110156200056357818101518382015260200162000549565b50506000910152565b60208152600082518060208401526200058d81604085016020870162000546565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b803573ffffffffffffffffffffffffffffffffffffffff81168114620005e457600080fd5b919050565b60008083601f840112620005fc57600080fd5b50813567ffffffffffffffff8111156200061557600080fd5b6020830191508360208285010111156200062e57600080fd5b9250929050565b600080600080606085870312156200064c57600080fd5b6200065785620005bf565b9350602085013567ffffffffffffffff8111156200067457600080fd5b6200068287828801620005e9565b9598909750949560400135949350505050565b600080600080600080600060c0888a031215620006b157600080fd5b620006bc88620005bf565b9650620006cc60208901620005bf565b9550620006dc60408901620005bf565b9450620006ec60608901620005bf565b9350620006fc60808901620005bf565b925060a088013567ffffffffffffffff8111156200071957600080fd5b620007278a828b01620005e9565b989b979a50959850939692959293505050565b600073ffffffffffffffffffffffffffffffffffffffff808a16835280891660208401528088166040840152808716606084015280861660808401525060c060a08301528260c0830152828460e0840137600060e0848401015260e07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f850116830101905098975050505050505050565b60008351620007e181846020880162000546565b835190830190620007f781836020880162000546565b0194935050505056fe608060405260405161055238038061055283398101604081905261002291610163565b6000858585858560405160240161003d959493929190610264565b60408051601f198184030181529181526020820180516001600160e01b0316634a93641760e01b1790525190915060009081906001600160a01b038a16906100869085906102c3565b600060405180830381855af49150503d80600081146100c1576040519150601f19603f3d011682016040523d82523d6000602084013e6100c6565b606091505b50915091508115806100e157506100dc816102df565b600114155b156100ff57604051636ff35f8960e01b815260040160405180910390fd5b505050505050505050610306565b80516001600160a01b038116811461012457600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101561015a578181015183820152602001610142565b50506000910152565b60008060008060008060c0878903121561017c57600080fd5b6101858761010d565b95506101936020880161010d565b94506101a16040880161010d565b93506101af6060880161010d565b92506101bd6080880161010d565b60a08801519092506001600160401b03808211156101da57600080fd5b818901915089601f8301126101ee57600080fd5b81518181111561020057610200610129565b604051601f8201601f19908116603f0116810190838211818310171561022857610228610129565b816040528281528c602084870101111561024157600080fd5b61025283602083016020880161013f565b80955050505050509295509295509295565b600060018060a01b0380881683528087166020840152808616604084015280851660608401525060a0608083015282518060a08401526102ab8160c085016020870161013f565b601f01601f19169190910160c0019695505050505050565b600082516102d581846020870161013f565b9190910192915050565b80516020808301519190811015610300576000198160200360031b1b821691505b50919050565b61023d806103156000396000f3fe60806040523661000b57005b600080357fffffffff000000000000000000000000000000000000000000000000000000001681527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020819052604090912054819060601c80610125576004838101546040517fcdffacc60000000000000000000000000000000000000000000000000000000081526000357fffffffff00000000000000000000000000000000000000000000000000000000169281019290925273ffffffffffffffffffffffffffffffffffffffff169063cdffacc690602401602060405180830381865afa1580156100fe573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061012291906101ca565b90505b73ffffffffffffffffffffffffffffffffffffffff81166101a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4261727a3a2046756e6374696f6e20646f6573206e6f74206578697374000000604482015260640160405180910390fd5b3660008037600080366000845af43d6000803e8080156101c5573d6000f35b3d6000fd5b6000602082840312156101dc57600080fd5b815173ffffffffffffffffffffffffffffffffffffffff8116811461020057600080fd5b939250505056fea26469706673582212200f3fa76ace3be8675d8b4c0d6c210a922fff2c2f1444023b817d1f6c908cd56a64736f6c63430008150033a2646970667358221220329ad45a4ef4915180001cb1fc90a5f97ad94a0b280426a580cba65fce28c0f164736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "Contract to easily deploy Barz to a pre-computed address with a single call", + "kind": "dev", + "methods": { + "constructor": { + "params": { + "_accountFacet": "Account Facet to be used to create Barz", + "_defaultFallback": "Default Fallback Handler to be used to create Barz", + "_entryPoint": "Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF", + "_facetRegistry": "Facet Registry to be used to create Barz" + } + }, + "createAccount(address,bytes,uint256)": { + "params": { + "_owner": "Public Key of the owner to initialize barz account", + "_salt": "Salt used for deploying barz with create2", + "_verificationFacet": "Address of verification facet used for creating the barz account" + }, + "returns": { + "barz": "Instance of Barz contract deployed with the given parameters" + } + }, + "getAddress(address,bytes,uint256)": { + "params": { + "_owner": "Public Key of the owner to initialize barz account", + "_salt": "Salt used for deploying barz with create2", + "_verificationFacet": "Address of verification facet used for creating the barz account" + }, + "returns": { + "barzAddress": "Precalculated Barz address" + } + }, + "getBytecode(address,address,address,address,address,bytes)": { + "params": { + "_accountFacet": "Account Facet to be used to create Barz", + "_defaultFallback": "Default Fallback Handler to be used to create Barz", + "_entryPoint": "Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF", + "_facetRegistry": "Facet Registry to be used to create Barz", + "_ownerPublicKey": "Public Key of owner to be used to initialize Barz ownership", + "_verificationFacet": "Verification Facet to be used to create Barz" + }, + "returns": { + "barzBytecode": "Bytecode of Barz" + } + }, + "getCreationCode()": { + "returns": { + "creationCode": "Creation code of Barz" + } + } + }, + "title": "Barz Factory", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "constructor": { + "notice": "Sets the initialization data for Barz contract initialization" + }, + "createAccount(address,bytes,uint256)": { + "notice": "Creates the Barz with a single call. It creates the Barz contract with the givent verification facet" + }, + "getAddress(address,bytes,uint256)": { + "notice": "Calculates the address of Barz with the given parameters" + }, + "getBytecode(address,address,address,address,address,bytes)": { + "notice": "Returns the bytecode of Barz with the given parameter" + }, + "getCreationCode()": { + "notice": "Returns the creation code of the Barz contract" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/blast/DefaultFallbackHandler.json b/deployments/blast/DefaultFallbackHandler.json new file mode 100644 index 0000000..4a909d9 --- /dev/null +++ b/deployments/blast/DefaultFallbackHandler.json @@ -0,0 +1,275 @@ +{ + "address": "0x2e7f1dAe1F3799d20f5c31bEFdc7A620f664728D", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_diamondCutFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_accountFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_tokenReceiverFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_diamondLoupeFacet", + "type": "address" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_initializationContractAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "InitializationFunctionReverted", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "indexed": false, + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "DiamondCut", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_functionSelector", + "type": "bytes4" + } + ], + "name": "facetAddress", + "outputs": [ + { + "internalType": "address", + "name": "facetAddress_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetAddresses", + "outputs": [ + { + "internalType": "address[]", + "name": "facetAddresses_", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_facet", + "type": "address" + } + ], + "name": "facetFunctionSelectors", + "outputs": [ + { + "internalType": "bytes4[]", + "name": "facetFunctionSelectors_", + "type": "bytes4[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facets", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondLoupe.Facet[]", + "name": "facets_", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0xde4fe864bb60e7fafbe1cc44c4165a36db83a7d9ab7cadbd45a2a645afdeae81", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 4, + "gasUsed": "1439057", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000001000000000800002000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000", + "blockHash": "0x4505c73ff1a4115f8d944ec1337d369d35a05f8614128414de98829341cc6bd0", + "transactionHash": "0xde4fe864bb60e7fafbe1cc44c4165a36db83a7d9ab7cadbd45a2a645afdeae81", + "logs": [ + { + "transactionIndex": 4, + "blockNumber": 1317801, + "transactionHash": "0xde4fe864bb60e7fafbe1cc44c4165a36db83a7d9ab7cadbd45a2a645afdeae81", + "address": "0x2e7f1dAe1F3799d20f5c31bEFdc7A620f664728D", + "topics": [ + "0x8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb673" + ], + "data": "0x000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000580000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000000000000000000000000000000000003600000000000000000000000000b9504140771c3688ff041917192277d2f52e1e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000011f931c1c00000000000000000000000000000000000000000000000000000000000000000000000000000000fde53272dcd7938d16e031a6989753c321728332000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000005b61d27f60000000000000000000000000000000000000000000000000000000047e1da2a000000000000000000000000000000000000000000000000000000003a871cdd00000000000000000000000000000000000000000000000000000000d087d28800000000000000000000000000000000000000000000000000000000b0d691fe000000000000000000000000000000000000000000000000000000000000000000000000000000003143e1c0af0cdc153423863923cf4e3818e34daa000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000005150b7a0200000000000000000000000000000000000000000000000000000000f23a6e6100000000000000000000000000000000000000000000000000000000bc197c81000000000000000000000000000000000000000000000000000000000023de2900000000000000000000000000000000000000000000000000000000a4c0ed3600000000000000000000000000000000000000000000000000000000000000000000000000000000ce36b85d12d81cd619c745c7717f3396e184ac7c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000097a0ed62700000000000000000000000000000000000000000000000000000000adfca15e0000000000000000000000000000000000000000000000000000000052ef6b2c00000000000000000000000000000000000000000000000000000000cdffacc60000000000000000000000000000000000000000000000000000000001ffc9a700000000000000000000000000000000000000000000000000000000f9796ccf0000000000000000000000000000000000000000000000000000000001a5502200000000000000000000000000000000000000000000000000000000d42139a900000000000000000000000000000000000000000000000000000000e3a2f6fe000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "logIndex": 18, + "blockHash": "0x4505c73ff1a4115f8d944ec1337d369d35a05f8614128414de98829341cc6bd0" + } + ], + "blockNumber": 1317801, + "cumulativeGasUsed": "2220102", + "status": 1, + "byzantium": true + }, + "args": [ + "0x0B9504140771C3688Ff041917192277D2f52E1e0", + "0xFde53272dcd7938d16E031A6989753c321728332", + "0x3143E1C0Af0Cdc153423863923Cf4e3818e34Daa", + "0xCe36b85d12D81cd619C745c7717f3396E184Ac7C" + ], + "numDeployments": 1, + "solcInputHash": "ad34345aa73d96f52b3e14df983b6b29", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_diamondCutFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_accountFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_tokenReceiverFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_diamondLoupeFacet\",\"type\":\"address\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_initializationContractAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"InitializationFunctionReverted\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"DiamondCut\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_functionSelector\",\"type\":\"bytes4\"}],\"name\":\"facetAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"facetAddress_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetAddresses\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"facetAddresses_\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_facet\",\"type\":\"address\"}],\"name\":\"facetFunctionSelectors\",\"outputs\":[{\"internalType\":\"bytes4[]\",\"name\":\"facetFunctionSelectors_\",\"type\":\"bytes4[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facets\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondLoupe.Facet[]\",\"name\":\"facets_\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"A default fallback handler for Barz\",\"kind\":\"dev\",\"methods\":{\"constructor\":{\"details\":\"This contract is also a diamond that holds the default facets to reduce gas cost for wallet activation. Within the constructor this conducts diamond cut to initially setup the diamond. This is a non-upgradeable contract\",\"params\":{\"_accountFacet\":\"Address account facet\",\"_diamondCutFacet\":\"Address if diamond cut facet\",\"_diamondLoupeFacet\":\"Address of diamond loupe facet\",\"_tokenReceiverFacet\":\"Address of token receiver facet\"}},\"facetAddress(bytes4)\":{\"details\":\"If facet is not found return address(0).\",\"params\":{\"_functionSelector\":\"The function selector.\"},\"returns\":{\"facetAddress_\":\"The facet address.\"}},\"facetAddresses()\":{\"returns\":{\"facetAddresses_\":\"facetAddresses_\"}},\"facetFunctionSelectors(address)\":{\"params\":{\"_facet\":\"The facet address.\"},\"returns\":{\"facetFunctionSelectors_\":\"facetFunctionSelectors_\"}},\"facets()\":{\"returns\":{\"facets_\":\"The facet struct array including all facet information\"}}},\"title\":\"DefaultFallbackHandler\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"Sets the middleware diamond for Barz wallet as a fallback handler\"},\"facetAddress(bytes4)\":{\"notice\":\"Gets the facet that supports the given selector.\"},\"facetAddresses()\":{\"notice\":\"Get all the facet addresses used by a diamond.\"},\"facetFunctionSelectors(address)\":{\"notice\":\"Gets all the function selectors provided by a facet.\"},\"facets()\":{\"notice\":\"Returns the facet information of call facets registered to this diamond.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/infrastructure/DefaultFallbackHandler.sol\":\"DefaultFallbackHandler\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/introspection/IERC165.sol\\\";\\n\\n/**\\n * @dev _Available since v3.1._\\n */\\ninterface IERC1155Receiver is IERC165 {\\n /**\\n * @dev Handles the receipt of a single ERC1155 token type. This function is\\n * called at the end of a `safeTransferFrom` after the balance has been updated.\\n *\\n * NOTE: To accept the transfer, this must return\\n * `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))`\\n * (i.e. 0xf23a6e61, or its own function selector).\\n *\\n * @param operator The address which initiated the transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param id The ID of the token being transferred\\n * @param value The amount of tokens being transferred\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155Received(\\n address operator,\\n address from,\\n uint256 id,\\n uint256 value,\\n bytes calldata data\\n ) external returns (bytes4);\\n\\n /**\\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\\n * is called at the end of a `safeBatchTransferFrom` after the balances have\\n * been updated.\\n *\\n * NOTE: To accept the transfer(s), this must return\\n * `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))`\\n * (i.e. 0xbc197c81, or its own function selector).\\n *\\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155BatchReceived(\\n address operator,\\n address from,\\n uint256[] calldata ids,\\n uint256[] calldata values,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xeb373f1fdc7b755c6a750123a9b9e3a8a02c1470042fd6505d875000a80bde0b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title ERC721 token receiver interface\\n * @dev Interface for any contract that wants to support safeTransfers\\n * from ERC721 asset contracts.\\n */\\ninterface IERC721Receiver {\\n /**\\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\\n * by `operator` from `from`, this function is called.\\n *\\n * It must return its Solidity selector to confirm the token transfer.\\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\\n *\\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\\n */\\n function onERC721Received(\\n address operator,\\n address from,\\n uint256 tokenId,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\\n *\\n * Accounts can be notified of {IERC777} tokens being sent to them by having a\\n * contract implement this interface (contract holders can be their own\\n * implementer) and registering it on the\\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\\n *\\n * See {IERC1820Registry} and {ERC1820Implementer}.\\n */\\ninterface IERC777Recipient {\\n /**\\n * @dev Called by an {IERC777} token contract whenever tokens are being\\n * moved or created into a registered account (`to`). The type of operation\\n * is conveyed by `from` being the zero address or not.\\n *\\n * This call occurs _after_ the token contract's state is updated, so\\n * {IERC777-balanceOf}, etc., can be used to query the post-operation state.\\n *\\n * This function may revert to prevent the operation from being executed.\\n */\\n function tokensReceived(\\n address operator,\\n address from,\\n address to,\\n uint256 amount,\\n bytes calldata userData,\\n bytes calldata operatorData\\n ) external;\\n}\\n\",\"keccak256\":\"0x1a5d61db2733202ba361e6d6741cd2e662380e22b80e987eacfc91973f2267dc\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"contracts/aa-4337/core/BaseAccount.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-empty-blocks */\\n\\nimport \\\"../interfaces/IAccount.sol\\\";\\nimport \\\"../interfaces/IEntryPoint.sol\\\";\\nimport \\\"./Helpers.sol\\\";\\n\\n/**\\n * Basic account implementation.\\n * this contract provides the basic logic for implementing the IAccount interface - validateUserOp\\n * specific account implementation should inherit it and provide the account-specific logic\\n */\\nabstract contract BaseAccount is IAccount {\\n using UserOperationLib for UserOperation;\\n\\n //return value in case of signature failure, with no time-range.\\n // equivalent to _packValidationData(true,0,0);\\n uint256 internal constant SIG_VALIDATION_FAILED = 1;\\n\\n /**\\n * Return the account nonce.\\n * This method returns the next sequential nonce.\\n * For a nonce of a specific key, use `entrypoint.getNonce(account, key)`\\n */\\n function getNonce() public view virtual returns (uint256) {\\n return entryPoint().getNonce(address(this), 0);\\n }\\n\\n /**\\n * return the entryPoint used by this account.\\n * subclass should return the current entryPoint used by this account.\\n */\\n function entryPoint() public view virtual returns (IEntryPoint);\\n\\n /**\\n * Validate user's signature and nonce.\\n * subclass doesn't need to override this method. Instead, it should override the specific internal validation methods.\\n */\\n function validateUserOp(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n uint256 missingAccountFunds\\n ) external virtual override returns (uint256 validationData) {\\n _requireFromEntryPoint();\\n validationData = _validateSignature(userOp, userOpHash);\\n _validateNonce(userOp.nonce);\\n _payPrefund(missingAccountFunds);\\n }\\n\\n /**\\n * ensure the request comes from the known entrypoint.\\n */\\n function _requireFromEntryPoint() internal view virtual {\\n require(\\n msg.sender == address(entryPoint()),\\n \\\"account: not from EntryPoint\\\"\\n );\\n }\\n\\n /**\\n * validate the signature is valid for this message.\\n * @param userOp validate the userOp.signature field\\n * @param userOpHash convenient field: the hash of the request, to check the signature against\\n * (also hashes the entrypoint and chain id)\\n * @return validationData signature and time-range of this operation\\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\\n * otherwise, an address of an \\\"authorizer\\\" contract.\\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \\\"indefinite\\\"\\n * <6-byte> validAfter - first timestamp this operation is valid\\n * If the account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\\n */\\n function _validateSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) internal virtual returns (uint256 validationData);\\n\\n /**\\n * Validate the nonce of the UserOperation.\\n * This method may validate the nonce requirement of this account.\\n * e.g.\\n * To limit the nonce to use sequenced UserOps only (no \\\"out of order\\\" UserOps):\\n * `require(nonce < type(uint64).max)`\\n * For a hypothetical account that *requires* the nonce to be out-of-order:\\n * `require(nonce & type(uint64).max == 0)`\\n *\\n * The actual nonce uniqueness is managed by the EntryPoint, and thus no other\\n * action is needed by the account itself.\\n *\\n * @param nonce to validate\\n *\\n * solhint-disable-next-line no-empty-blocks\\n */\\n function _validateNonce(uint256 nonce) internal view virtual {}\\n\\n /**\\n * sends to the entrypoint (msg.sender) the missing funds for this transaction.\\n * subclass MAY override this method for better funds management\\n * (e.g. send to the entryPoint more than the minimum required, so that in future transactions\\n * it will not be required to send again)\\n * @param missingAccountFunds the minimum value this method should send the entrypoint.\\n * this value MAY be zero, in case there is enough deposit, or the userOp has a paymaster.\\n */\\n function _payPrefund(uint256 missingAccountFunds) internal virtual {\\n if (missingAccountFunds != 0) {\\n (bool success, ) = payable(msg.sender).call{\\n value: missingAccountFunds,\\n gas: type(uint256).max\\n }(\\\"\\\");\\n (success);\\n //ignore failure (its EntryPoint's job to verify, not account.)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa0dcc386b0f04711db3e394fb50e55a3b3b1a4d19fac1f10895844e1aa4e3d5c\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/core/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable no-inline-assembly */\\n\\n/**\\n * returned data from validateUserOp.\\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\\n * @param aggregator - address(0) - the account validated the signature by itself.\\n * address(1) - the account failed to validate the signature.\\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\\n * @param validAfter - this UserOp is valid only after this timestamp.\\n * @param validaUntil - this UserOp is valid only up to this timestamp.\\n */\\nstruct ValidationData {\\n address aggregator;\\n uint48 validAfter;\\n uint48 validUntil;\\n}\\n\\n//extract sigFailed, validAfter, validUntil.\\n// also convert zero validUntil to type(uint48).max\\nfunction _parseValidationData(\\n uint validationData\\n) pure returns (ValidationData memory data) {\\n address aggregator = address(uint160(validationData));\\n uint48 validUntil = uint48(validationData >> 160);\\n if (validUntil == 0) {\\n validUntil = type(uint48).max;\\n }\\n uint48 validAfter = uint48(validationData >> (48 + 160));\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n// intersect account and paymaster ranges.\\nfunction _intersectTimeRange(\\n uint256 validationData,\\n uint256 paymasterValidationData\\n) pure returns (ValidationData memory) {\\n ValidationData memory accountValidationData = _parseValidationData(\\n validationData\\n );\\n ValidationData memory pmValidationData = _parseValidationData(\\n paymasterValidationData\\n );\\n address aggregator = accountValidationData.aggregator;\\n if (aggregator == address(0)) {\\n aggregator = pmValidationData.aggregator;\\n }\\n uint48 validAfter = accountValidationData.validAfter;\\n uint48 validUntil = accountValidationData.validUntil;\\n uint48 pmValidAfter = pmValidationData.validAfter;\\n uint48 pmValidUntil = pmValidationData.validUntil;\\n\\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp\\n * @param data - the ValidationData to pack\\n */\\nfunction _packValidationData(\\n ValidationData memory data\\n) pure returns (uint256) {\\n return\\n uint160(data.aggregator) |\\n (uint256(data.validUntil) << 160) |\\n (uint256(data.validAfter) << (160 + 48));\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp, when not using an aggregator\\n * @param sigFailed - true for signature failure, false for success\\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\\n * @param validAfter first timestamp this UserOperation is valid\\n */\\nfunction _packValidationData(\\n bool sigFailed,\\n uint48 validUntil,\\n uint48 validAfter\\n) pure returns (uint256) {\\n return\\n (sigFailed ? 1 : 0) |\\n (uint256(validUntil) << 160) |\\n (uint256(validAfter) << (160 + 48));\\n}\\n\\n/**\\n * keccak function over calldata.\\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\\n */\\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\\n assembly {\\n let mem := mload(0x40)\\n let len := data.length\\n calldatacopy(mem, data.offset, len)\\n ret := keccak256(mem, len)\\n }\\n}\\n\",\"keccak256\":\"0xa79f06cd158ecb8c0da95493a2f348933b8627a63e228b99738bff3aa107942d\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAccount.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\ninterface IAccount {\\n /**\\n * Validate user's signature and nonce\\n * the entryPoint will make the call to the recipient only if this validation call returns successfully.\\n * signature failure should be reported by returning SIG_VALIDATION_FAILED (1).\\n * This allows making a \\\"simulation call\\\" without a valid signature\\n * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure.\\n *\\n * @dev Must validate caller is the entryPoint.\\n * Must validate the signature and nonce\\n * @param userOp the operation that is about to be executed.\\n * @param userOpHash hash of the user's request data. can be used as the basis for signature.\\n * @param missingAccountFunds missing funds on the account's deposit in the entrypoint.\\n * This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call.\\n * The excess is left as a deposit in the entrypoint, for future calls.\\n * can be withdrawn anytime using \\\"entryPoint.withdrawTo()\\\"\\n * In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero.\\n * @return validationData packaged ValidationData structure. use `_packValidationData` and `_unpackValidationData` to encode and decode\\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\\n * otherwise, an address of an \\\"authorizer\\\" contract.\\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \\\"indefinite\\\"\\n * <6-byte> validAfter - first timestamp this operation is valid\\n * If an account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\\n */\\n function validateUserOp(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n uint256 missingAccountFunds\\n ) external returns (uint256 validationData);\\n}\\n\",\"keccak256\":\"0xcbc4b0973cf954c5895b7796335f651fbfcfb55f67dfa789a3d354f8e23c4f2b\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAggregator.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\n/**\\n * Aggregated Signatures validator.\\n */\\ninterface IAggregator {\\n /**\\n * validate aggregated signature.\\n * revert if the aggregated signature does not match the given list of operations.\\n */\\n function validateSignatures(\\n UserOperation[] calldata userOps,\\n bytes calldata signature\\n ) external view;\\n\\n /**\\n * validate signature of a single userOp\\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\\n * @param userOp the userOperation received from the user.\\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\\n * (usually empty, unless account and aggregator support some kind of \\\"multisig\\\"\\n */\\n function validateUserOpSignature(\\n UserOperation calldata userOp\\n ) external view returns (bytes memory sigForUserOp);\\n\\n /**\\n * aggregate multiple signatures into a single value.\\n * This method is called off-chain to calculate the signature to pass with handleOps()\\n * bundler MAY use optimized custom code perform this aggregation\\n * @param userOps array of UserOperations to collect the signatures from.\\n * @return aggregatedSignature the aggregated signature\\n */\\n function aggregateSignatures(\\n UserOperation[] calldata userOps\\n ) external view returns (bytes memory aggregatedSignature);\\n}\\n\",\"keccak256\":\"0xdfdcd80568f037716674619b31be630fcd8316262f05a815b41d1e81782c966a\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IEntryPoint.sol\":{\"content\":\"/**\\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\\n ** Only one instance required on each chain.\\n **/\\n// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-inline-assembly */\\n/* solhint-disable reason-string */\\n\\nimport \\\"./UserOperation.sol\\\";\\nimport \\\"./IStakeManager.sol\\\";\\nimport \\\"./IAggregator.sol\\\";\\nimport \\\"./INonceManager.sol\\\";\\n\\ninterface IEntryPoint is IStakeManager, INonceManager {\\n /***\\n * An event emitted after each successful request\\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\\n * @param sender - the account that generates this request.\\n * @param paymaster - if non-null, the paymaster that pays for this request.\\n * @param nonce - the nonce value from the request.\\n * @param success - true if the sender transaction succeeded, false if reverted.\\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\\n */\\n event UserOperationEvent(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address indexed paymaster,\\n uint256 nonce,\\n bool success,\\n uint256 actualGasCost,\\n uint256 actualGasUsed\\n );\\n\\n /**\\n * account \\\"sender\\\" was deployed.\\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\\n * @param sender the account that is deployed\\n * @param factory the factory used to deploy this account (in the initCode)\\n * @param paymaster the paymaster used by this UserOp\\n */\\n event AccountDeployed(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address factory,\\n address paymaster\\n );\\n\\n /**\\n * An event emitted if the UserOperation \\\"callData\\\" reverted with non-zero length\\n * @param userOpHash the request unique identifier.\\n * @param sender the sender of this request\\n * @param nonce the nonce used in the request\\n * @param revertReason - the return bytes from the (reverted) call to \\\"callData\\\".\\n */\\n event UserOperationRevertReason(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n uint256 nonce,\\n bytes revertReason\\n );\\n\\n /**\\n * an event emitted by handleOps(), before starting the execution loop.\\n * any event emitted before this event, is part of the validation.\\n */\\n event BeforeExecution();\\n\\n /**\\n * signature aggregator used by the following UserOperationEvents within this bundle.\\n */\\n event SignatureAggregatorChanged(address indexed aggregator);\\n\\n /**\\n * a custom revert error of handleOps, to identify the offending op.\\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\\n * @param reason - revert reason\\n * The string starts with a unique code \\\"AAmn\\\", where \\\"m\\\" is \\\"1\\\" for factory, \\\"2\\\" for account and \\\"3\\\" for paymaster issues,\\n * so a failure can be attributed to the correct entity.\\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\\n */\\n error FailedOp(uint256 opIndex, string reason);\\n\\n /**\\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\\n */\\n error SignatureValidationFailed(address aggregator);\\n\\n /**\\n * Successful result from simulateValidation.\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n */\\n error ValidationResult(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo\\n );\\n\\n /**\\n * Successful result from simulateValidation, if the account returns a signature aggregator\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\\n * bundler MUST use it to verify the signature, or reject the UserOperation\\n */\\n error ValidationResultWithAggregation(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo,\\n AggregatorStakeInfo aggregatorInfo\\n );\\n\\n /**\\n * return value of getSenderAddress\\n */\\n error SenderAddressResult(address sender);\\n\\n /**\\n * return value of simulateHandleOp\\n */\\n error ExecutionResult(\\n uint256 preOpGas,\\n uint256 paid,\\n uint48 validAfter,\\n uint48 validUntil,\\n bool targetSuccess,\\n bytes targetResult\\n );\\n\\n //UserOps handled, per aggregator\\n struct UserOpsPerAggregator {\\n UserOperation[] userOps;\\n // aggregator address\\n IAggregator aggregator;\\n // aggregated signature\\n bytes signature;\\n }\\n\\n /**\\n * Execute a batch of UserOperation.\\n * no signature aggregator is used.\\n * if any account requires an aggregator (that is, it returned an aggregator when\\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\\n * @param ops the operations to execute\\n * @param beneficiary the address to receive the fees\\n */\\n function handleOps(\\n UserOperation[] calldata ops,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * Execute a batch of UserOperation with Aggregators\\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\\n * @param beneficiary the address to receive the fees\\n */\\n function handleAggregatedOps(\\n UserOpsPerAggregator[] calldata opsPerAggregator,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * generate a request Id - unique identifier for this request.\\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\\n */\\n function getUserOpHash(\\n UserOperation calldata userOp\\n ) external view returns (bytes32);\\n\\n /**\\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\\n * @param userOp the user operation to validate.\\n */\\n function simulateValidation(UserOperation calldata userOp) external;\\n\\n /**\\n * gas and return values during simulation\\n * @param preOpGas the gas used for validation (including preValidationGas)\\n * @param prefund the required prefund for this operation\\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\\n */\\n struct ReturnInfo {\\n uint256 preOpGas;\\n uint256 prefund;\\n bool sigFailed;\\n uint48 validAfter;\\n uint48 validUntil;\\n bytes paymasterContext;\\n }\\n\\n /**\\n * returned aggregated signature info.\\n * the aggregator returned by the account, and its current stake.\\n */\\n struct AggregatorStakeInfo {\\n address aggregator;\\n StakeInfo stakeInfo;\\n }\\n\\n /**\\n * Get counterfactual sender address.\\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\\n * this method always revert, and returns the address in SenderAddressResult error\\n * @param initCode the constructor code to be passed into the UserOperation.\\n */\\n function getSenderAddress(bytes memory initCode) external;\\n\\n /**\\n * simulate full execution of a UserOperation (including both validation and target execution)\\n * this method will always revert with \\\"ExecutionResult\\\".\\n * it performs full validation of the UserOperation, but ignores signature error.\\n * an optional target address is called after the userop succeeds, and its value is returned\\n * (before the entire call is reverted)\\n * Note that in order to collect the the success/failure of the target call, it must be executed\\n * with trace enabled to track the emitted events.\\n * @param op the UserOperation to simulate\\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\\n * are set to the return from that call.\\n * @param targetCallData callData to pass to target address\\n */\\n function simulateHandleOp(\\n UserOperation calldata op,\\n address target,\\n bytes calldata targetCallData\\n ) external;\\n}\\n\",\"keccak256\":\"0x9ccb1b188eda8bbf5f6c2d01bd83c3d8b2b04fcf745283051d31fe96d1d8e40f\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/INonceManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\ninterface INonceManager {\\n /**\\n * Return the next nonce for this sender.\\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\\n * But UserOp with different keys can come with arbitrary order.\\n *\\n * @param sender the account address\\n * @param key the high 192 bit of the nonce\\n * @return nonce a full nonce to pass for next UserOp with this sender.\\n */\\n function getNonce(\\n address sender,\\n uint192 key\\n ) external view returns (uint256 nonce);\\n\\n /**\\n * Manually increment the nonce of the sender.\\n * This method is exposed just for completeness..\\n * Account does NOT need to call it, neither during validation, nor elsewhere,\\n * as the EntryPoint will update the nonce regardless.\\n * Possible use-case is call it with various keys to \\\"initialize\\\" their nonces to one, so that future\\n * UserOperations will not pay extra for the first transaction with a given key.\\n */\\n function incrementNonce(uint192 key) external;\\n}\\n\",\"keccak256\":\"0xce478ad0fa0d18a3b785ac854623029e7ab463d05873dfaa365abfa1bf100912\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IStakeManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8.12;\\n\\n/**\\n * manage deposits and stakes.\\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\\n * stake is value locked for at least \\\"unstakeDelay\\\" by the staked entity.\\n */\\ninterface IStakeManager {\\n event Deposited(address indexed account, uint256 totalDeposit);\\n\\n event Withdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /// Emitted when stake or unstake delay are modified\\n event StakeLocked(\\n address indexed account,\\n uint256 totalStaked,\\n uint256 unstakeDelaySec\\n );\\n\\n /// Emitted once a stake is scheduled for withdrawal\\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\\n\\n event StakeWithdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /**\\n * @param deposit the entity's deposit\\n * @param staked true if this entity is staked.\\n * @param stake actual amount of ether staked for this entity.\\n * @param unstakeDelaySec minimum delay to withdraw the stake.\\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\\n * and the rest fit into a 2nd cell.\\n * 112 bit allows for 10^15 eth\\n * 48 bit for full timestamp\\n * 32 bit allows 150 years for unstake delay\\n */\\n struct DepositInfo {\\n uint112 deposit;\\n bool staked;\\n uint112 stake;\\n uint32 unstakeDelaySec;\\n uint48 withdrawTime;\\n }\\n\\n //API struct used by getStakeInfo and simulateValidation\\n struct StakeInfo {\\n uint256 stake;\\n uint256 unstakeDelaySec;\\n }\\n\\n /// @return info - full deposit information of given account\\n function getDepositInfo(\\n address account\\n ) external view returns (DepositInfo memory info);\\n\\n /// @return the deposit (for gas payment) of the account\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * add to the deposit of the given account\\n */\\n function depositTo(address account) external payable;\\n\\n /**\\n * add to the account's stake - amount and delay\\n * any pending unstake is first cancelled.\\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\\n */\\n function addStake(uint32 _unstakeDelaySec) external payable;\\n\\n /**\\n * attempt to unlock the stake.\\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\\n */\\n function unlockStake() external;\\n\\n /**\\n * withdraw from the (unlocked) stake.\\n * must first call unlockStake and wait for the unstakeDelay to pass\\n * @param withdrawAddress the address to send withdrawn value.\\n */\\n function withdrawStake(address payable withdrawAddress) external;\\n\\n /**\\n * withdraw from the deposit.\\n * @param withdrawAddress the address to send withdrawn value.\\n * @param withdrawAmount the amount to withdraw.\\n */\\n function withdrawTo(\\n address payable withdrawAddress,\\n uint256 withdrawAmount\\n ) external;\\n}\\n\",\"keccak256\":\"0xadcea606c9b7aafe6645441f2154a60f271330b0eee5292a632aa71c1672d546\",\"license\":\"GPL-3.0-only\"},\"contracts/aa-4337/interfaces/UserOperation.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable no-inline-assembly */\\n\\nimport {calldataKeccak} from \\\"../core/Helpers.sol\\\";\\n\\n/**\\n * User Operation struct\\n * @param sender the sender account of this request.\\n * @param nonce unique value the sender uses to verify it is not a replay.\\n * @param initCode if set, the account contract will be created by this constructor/\\n * @param callData the method call to execute on this account.\\n * @param callGasLimit the gas limit passed to the callData method call.\\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\\n * @param maxFeePerGas same as EIP-1559 gas parameter.\\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\\n */\\nstruct UserOperation {\\n address sender;\\n uint256 nonce;\\n bytes initCode;\\n bytes callData;\\n uint256 callGasLimit;\\n uint256 verificationGasLimit;\\n uint256 preVerificationGas;\\n uint256 maxFeePerGas;\\n uint256 maxPriorityFeePerGas;\\n bytes paymasterAndData;\\n bytes signature;\\n}\\n\\n/**\\n * Utility functions helpful when working with UserOperation structs.\\n */\\nlibrary UserOperationLib {\\n function getSender(\\n UserOperation calldata userOp\\n ) internal pure returns (address) {\\n address data;\\n //read sender from userOp, which is first userOp member (saves 800 gas...)\\n assembly {\\n data := calldataload(userOp)\\n }\\n return address(uint160(data));\\n }\\n\\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\\n // pay above what he signed for.\\n function gasPrice(\\n UserOperation calldata userOp\\n ) internal view returns (uint256) {\\n unchecked {\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n if (maxFeePerGas == maxPriorityFeePerGas) {\\n //legacy mode (for networks that don't support basefee opcode)\\n return maxFeePerGas;\\n }\\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\\n }\\n }\\n\\n function pack(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes memory ret) {\\n address sender = getSender(userOp);\\n uint256 nonce = userOp.nonce;\\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\\n bytes32 hashCallData = calldataKeccak(userOp.callData);\\n uint256 callGasLimit = userOp.callGasLimit;\\n uint256 verificationGasLimit = userOp.verificationGasLimit;\\n uint256 preVerificationGas = userOp.preVerificationGas;\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\\n\\n return\\n abi.encode(\\n sender,\\n nonce,\\n hashInitCode,\\n hashCallData,\\n callGasLimit,\\n verificationGasLimit,\\n preVerificationGas,\\n maxFeePerGas,\\n maxPriorityFeePerGas,\\n hashPaymasterAndData\\n );\\n }\\n\\n function hash(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes32) {\\n return keccak256(pack(userOp));\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n}\\n\",\"keccak256\":\"0x2429f5cc546bdee08c7e63858d0dda8491eaa3ab5194df884dc948c1154d2834\",\"license\":\"GPL-3.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IStorageLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"./IDiamondLoupe.sol\\\";\\n\\n/**\\n * @title LoupeFromStorage Interface\\n * @dev Interface contract to function as a loupe facet directly attached to diamond storage of Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IStorageLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facetsFromStorage()\\n external\\n view\\n returns (IDiamondLoupe.Facet[] memory);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n function facetFunctionSelectorsFromStorage(\\n address _facet\\n ) external view returns (bytes4[] memory);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n function facetAddressesFromStorage()\\n external\\n view\\n returns (address[] memory);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n function facetAddressFromStorage(\\n bytes4 _functionSelector\\n ) external view returns (address);\\n}\\n\",\"keccak256\":\"0xdf5dc9c57319e9087628c9cf9404b4f75585b76d1c2f4f59ee796c933967ea5c\",\"license\":\"Apache-2.0\"},\"contracts/facets/interfaces/IAccountFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IEntryPoint} from \\\"../../aa-4337/interfaces/IEntryPoint.sol\\\";\\n\\n/**\\n * @title Account Facet Interface\\n * @dev Interface of module contract that provides the account features and init/unitialization of signer\\n * compatible with EIP-1271 & EIP-4337\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IAccountFacet {\\n event AccountInitialized(\\n IEntryPoint indexed entryPoint,\\n bytes indexed ownerPublicKey\\n );\\n // NOTE: Added Below Event\\n event VerificationSuccess(bytes32);\\n event VerificationFailure(bytes32);\\n\\n error AccountFacet__InitializationFailure();\\n error AccountFacet__RestrictionsFailure();\\n error AccountFacet__NonExistentVerificationFacet();\\n error AccountFacet__CallNotSuccessful();\\n error AccountFacet__InvalidArrayLength();\\n\\n function initialize(\\n address verificationFacet,\\n address anEntryPoint,\\n address facetRegistry,\\n address _defaultFallBack,\\n bytes calldata _ownerPublicKey\\n ) external returns (uint256);\\n\\n function execute(address dest, uint256 value, bytes calldata func) external;\\n\\n function executeBatch(\\n address[] calldata dest,\\n uint256[] calldata value,\\n bytes[] calldata func\\n ) external;\\n}\\n\",\"keccak256\":\"0x74a9cb0b8f2f4a5148e366a401a0354426c536c012c025025d07cc25a4cd5382\",\"license\":\"Apache-2.0\"},\"contracts/infrastructure/DefaultFallbackHandler.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IERC721Receiver} from \\\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\\\";\\nimport {IERC1155Receiver} from \\\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\\\";\\nimport {IERC777Recipient} from \\\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\\\";\\nimport {BaseAccount} from \\\"../aa-4337/core/BaseAccount.sol\\\";\\nimport {DefaultLibDiamond} from \\\"../libraries/DefaultLibDiamond.sol\\\";\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IAccountFacet} from \\\"../facets/interfaces/IAccountFacet.sol\\\";\\nimport {IStorageLoupe} from \\\"../facets/base/interfaces/IStorageLoupe.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\nimport {IERC677Receiver} from \\\"../interfaces/ERC/IERC677Receiver.sol\\\";\\nimport {IERC165} from \\\"../interfaces/ERC/IERC165.sol\\\";\\n\\n/**\\n * @title DefaultFallbackHandler\\n * @dev A default fallback handler for Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract DefaultFallbackHandler is IDiamondLoupe {\\n /**\\n * @notice Sets the middleware diamond for Barz wallet as a fallback handler\\n * @dev This contract is also a diamond that holds the default facets to reduce gas cost for wallet activation.\\n * Within the constructor this conducts diamond cut to initially setup the diamond. This is a non-upgradeable contract\\n * @param _diamondCutFacet Address if diamond cut facet\\n * @param _accountFacet Address account facet\\n * @param _tokenReceiverFacet Address of token receiver facet\\n * @param _diamondLoupeFacet Address of diamond loupe facet\\n */\\n constructor(\\n address _diamondCutFacet,\\n address _accountFacet,\\n address _tokenReceiverFacet,\\n address _diamondLoupeFacet\\n ) payable {\\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](4);\\n bytes4[] memory functionSelectors = new bytes4[](1);\\n functionSelectors[0] = IDiamondCut.diamondCut.selector;\\n\\n bytes4[] memory accountFunctionSelectors = new bytes4[](5);\\n accountFunctionSelectors[0] = IAccountFacet.execute.selector;\\n accountFunctionSelectors[1] = IAccountFacet.executeBatch.selector;\\n accountFunctionSelectors[2] = BaseAccount.validateUserOp.selector;\\n accountFunctionSelectors[3] = BaseAccount.getNonce.selector;\\n accountFunctionSelectors[4] = BaseAccount.entryPoint.selector;\\n\\n bytes4[] memory receiverFacetSelectors = new bytes4[](5);\\n receiverFacetSelectors[0] = IERC721Receiver.onERC721Received.selector;\\n receiverFacetSelectors[1] = IERC1155Receiver.onERC1155Received.selector;\\n receiverFacetSelectors[2] = IERC1155Receiver\\n .onERC1155BatchReceived\\n .selector;\\n receiverFacetSelectors[3] = IERC777Recipient.tokensReceived.selector;\\n receiverFacetSelectors[4] = IERC677Receiver.onTokenTransfer.selector;\\n\\n bytes4[] memory loupeFacetSelectors = new bytes4[](9);\\n loupeFacetSelectors[0] = IDiamondLoupe.facets.selector;\\n loupeFacetSelectors[1] = IDiamondLoupe.facetFunctionSelectors.selector;\\n loupeFacetSelectors[2] = IDiamondLoupe.facetAddresses.selector;\\n loupeFacetSelectors[3] = IDiamondLoupe.facetAddress.selector;\\n loupeFacetSelectors[4] = IERC165.supportsInterface.selector;\\n loupeFacetSelectors[5] = IStorageLoupe.facetsFromStorage.selector;\\n loupeFacetSelectors[6] = IStorageLoupe\\n .facetFunctionSelectorsFromStorage\\n .selector;\\n loupeFacetSelectors[7] = IStorageLoupe\\n .facetAddressesFromStorage\\n .selector;\\n loupeFacetSelectors[8] = IStorageLoupe.facetAddressFromStorage.selector;\\n\\n {\\n cut[0] = IDiamondCut.FacetCut({\\n facetAddress: _diamondCutFacet,\\n action: IDiamondCut.FacetCutAction.Add,\\n functionSelectors: functionSelectors\\n });\\n cut[1] = IDiamondCut.FacetCut({\\n facetAddress: _accountFacet,\\n action: IDiamondCut.FacetCutAction.Add,\\n functionSelectors: accountFunctionSelectors\\n });\\n cut[2] = IDiamondCut.FacetCut({\\n facetAddress: _tokenReceiverFacet,\\n action: IDiamondCut.FacetCutAction.Add,\\n functionSelectors: receiverFacetSelectors\\n });\\n cut[3] = IDiamondCut.FacetCut({\\n facetAddress: _diamondLoupeFacet,\\n action: IDiamondCut.FacetCutAction.Add,\\n functionSelectors: loupeFacetSelectors\\n });\\n\\n DefaultLibDiamond.diamondCut(cut, address(0), \\\"\\\");\\n }\\n }\\n\\n /**\\n * @notice Returns the facet information of call facets registered to this diamond.\\n * @return facets_ The facet struct array including all facet information\\n */\\n function facets() external view override returns (Facet[] memory facets_) {\\n DefaultLibDiamond.DiamondStorage storage ds = DefaultLibDiamond\\n .diamondStorage();\\n uint256 numFacets = ds.facetAddresses.length;\\n facets_ = new Facet[](numFacets);\\n for (uint256 i; i < numFacets; ) {\\n address facetAddress_ = ds.facetAddresses[i];\\n facets_[i].facetAddress = facetAddress_;\\n facets_[i].functionSelectors = ds\\n .facetFunctionSelectors[facetAddress_]\\n .functionSelectors;\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * @notice Gets all the function selectors provided by a facet.\\n * @param _facet The facet address.\\n * @return facetFunctionSelectors_\\n */\\n function facetFunctionSelectors(\\n address _facet\\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\\n facetFunctionSelectors_ = DefaultLibDiamond\\n .diamondStorage()\\n .facetFunctionSelectors[_facet]\\n .functionSelectors;\\n }\\n\\n /**\\n * @notice Get all the facet addresses used by a diamond.\\n * @return facetAddresses_\\n */\\n function facetAddresses()\\n external\\n view\\n override\\n returns (address[] memory facetAddresses_)\\n {\\n facetAddresses_ = DefaultLibDiamond.diamondStorage().facetAddresses;\\n }\\n\\n /** @notice Gets the facet that supports the given selector.\\n * @dev If facet is not found return address(0).\\n * @param _functionSelector The function selector.\\n * @return facetAddress_ The facet address.\\n */\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view override returns (address facetAddress_) {\\n facetAddress_ = DefaultLibDiamond\\n .diamondStorage()\\n .selectorToFacetAndPosition[_functionSelector]\\n .facetAddress;\\n }\\n}\\n\",\"keccak256\":\"0xa482fe778481e34e9fb3c4074231f8048437e934c0ca9a0c78e8e61d3a24470a\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.21;\\n\\ninterface IERC165 {\\n /// @notice Query if a contract implements an interface\\n /// @param interfaceId The interface identifier, as specified in ERC-165\\n /// @dev Interface identification is specified in ERC-165. This function\\n /// uses less than 30,000 gas.\\n /// @return `true` if the contract implements `interfaceID` and\\n /// `interfaceID` is not 0xffffffff, `false` otherwise\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xbb7f07e170898793c5535cc4b7e8944c4b990a631ac806d0b788e794abc788a3\",\"license\":\"MIT\"},\"contracts/interfaces/ERC/IERC677Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC677Receiver {\\n function onTokenTransfer(\\n address sender,\\n uint value,\\n bytes calldata data\\n ) external pure returns (bool);\\n}\\n\",\"keccak256\":\"0x4c1631cf45ea6daac0ec158c3edb9453099130b6b64f697004b83f95aa1f7350\",\"license\":\"Apache-2.0\"},\"contracts/libraries/DefaultLibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary DefaultLibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (\\n uint256 facetIndex;\\n facetIndex < _diamondCut.length;\\n facetIndex++\\n ) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(\\n address _facetAddress,\\n bytes4[] memory _functionSelectors\\n ) internal {\\n uint256 funcSelectorsLength = _functionSelectors.length;\\n require(\\n funcSelectorsLength > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _facetAddress != address(0),\\n \\\"LibDiamondCut: Add facet can't be address(0)\\\"\\n );\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (\\n uint256 selectorIndex;\\n selectorIndex < funcSelectorsLength;\\n selectorIndex++\\n ) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds\\n .selectorToFacetAndPosition[selector]\\n .facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(\\n address _facetAddress,\\n bytes4[] memory _functionSelectors\\n ) internal {\\n uint256 funcSelectorsLength = _functionSelectors.length;\\n require(\\n funcSelectorsLength > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _facetAddress != address(0),\\n \\\"LibDiamondCut: Replace facet can't be address(0)\\\"\\n );\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (\\n uint256 selectorIndex;\\n selectorIndex < funcSelectorsLength;\\n selectorIndex++\\n ) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds\\n .selectorToFacetAndPosition[selector]\\n .facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same facet\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(\\n address _facetAddress,\\n bytes4[] memory _functionSelectors\\n ) internal {\\n uint256 funcSelectorsLength = _functionSelectors.length;\\n require(\\n funcSelectorsLength > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(\\n _facetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n for (\\n uint256 selectorIndex;\\n selectorIndex < funcSelectorsLength;\\n selectorIndex++\\n ) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds\\n .selectorToFacetAndPosition[selector]\\n .facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(\\n DiamondStorage storage ds,\\n address _facetAddress\\n ) internal {\\n enforceHasContractCode(\\n _facetAddress,\\n \\\"LibDiamondCut: New facet has no code\\\"\\n );\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds\\n .facetAddresses\\n .length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds\\n .selectorToFacetAndPosition[_selector]\\n .functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(\\n _selector\\n );\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(\\n _facetAddress != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // an immutable function is a function defined directly in a diamond\\n require(\\n _facetAddress != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds\\n .selectorToFacetAndPosition[_selector]\\n .functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors[lastSelectorPosition];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n selectorPosition\\n ] = lastSelector;\\n ds\\n .selectorToFacetAndPosition[lastSelector]\\n .functionSelectorPosition = uint96(selectorPosition);\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[\\n lastFacetAddressPosition\\n ];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds\\n .facetFunctionSelectors[lastFacetAddress]\\n .facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds\\n .facetFunctionSelectors[_facetAddress]\\n .facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x1b08f332d62919288bb1f0d154ca4b85f4e167d2a06e680f8ec93dba65be3be1\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x6080604052604051620020183803806200201883398101604081905262000026916200156b565b60408051600480825260a08201909252600091816020015b604080516060808201835260008083526020830152918101919091528152602001906001900390816200003e5750506040805160018082528183019092529192506000919060208083019080368337019050509050631f931c1c60e01b81600081518110620000b157620000b1620015c8565b6001600160e01b03199290921660209283029190910182015260408051600580825260c08201909252600092909190820160a08036833701905050905063b61d27f660e01b816000815181106200010c576200010c620015c8565b6001600160e01b03199092166020928302919091019091015280516323f0ed1560e11b9082906001908110620001465762000146620015c8565b6001600160e01b0319909216602092830291909101909101528051633a871cdd60e01b9082906002908110620001805762000180620015c8565b6001600160e01b0319909216602092830291909101909101528051631a10fa5160e31b9082906003908110620001ba57620001ba620015c8565b6001600160e01b031990921660209283029190910190910152805163586b48ff60e11b9082906004908110620001f457620001f4620015c8565b6001600160e01b03199290921660209283029190910182015260408051600580825260c08201909252600092909190820160a08036833701905050905063150b7a0260e01b816000815181106200024f576200024f620015c8565b6001600160e01b031990921660209283029190910190910152805163f23a6e6160e01b9082906001908110620002895762000289620015c8565b6001600160e01b031990921660209283029190910190910152805163bc197c8160e01b9082906002908110620002c357620002c3620015c8565b6001600160e01b03199092166020928302919091019091015280516223de2960e01b9082906003908110620002fc57620002fc620015c8565b6001600160e01b0319909216602092830291909101909101528051635260769b60e11b9082906004908110620003365762000336620015c8565b6001600160e01b0319929092166020928302919091018201526040805160098082526101408201909252600092909190820161012080368337019050509050637a0ed62760e01b81600081518110620003935762000393620015c8565b6001600160e01b03199092166020928302919091019091015280516356fe50af60e11b9082906001908110620003cd57620003cd620015c8565b6001600160e01b03199092166020928302919091019091015280516314bbdacb60e21b9082906002908110620004075762000407620015c8565b6001600160e01b03199092166020928302919091019091015280516366ffd66360e11b9082906003908110620004415762000441620015c8565b6001600160e01b03199092166020928302919091019091015280516301ffc9a760e01b90829060049081106200047b576200047b620015c8565b6001600160e01b031990921660209283029190910190910152805163f9796ccf60e01b9082906005908110620004b557620004b5620015c8565b6001600160e01b031990921660209283029190910190910152805162d2a81160e11b9082906006908110620004ee57620004ee620015c8565b6001600160e01b031990921660209283029190910190910152805163d42139a960e01b9082906007908110620005285762000528620015c8565b6001600160e01b03199092166020928302919091019091015280516371d17b7f60e11b9082906008908110620005625762000562620015c8565b6001600160e01b031990921660209283029190910182015260408051606081019091526001600160a01b038b168152908101600081526020018581525085600081518110620005b557620005b5620015c8565b60200260200101819052506040518060600160405280896001600160a01b0316815260200160006002811115620005f057620005f0620015de565b815260200184815250856001815181106200060f576200060f620015c8565b60200260200101819052506040518060600160405280886001600160a01b03168152602001600060028111156200064a576200064a620015de565b81526020018381525085600281518110620006695762000669620015c8565b60200260200101819052506040518060600160405280876001600160a01b0316815260200160006002811115620006a457620006a4620015de565b81526020018281525085600381518110620006c357620006c3620015c8565b6020026020010181905250620006f1856000604051806020016040528060008152506200070060201b60201c565b5050505050505050506200184c565b60005b83518110156200090c576000848281518110620007245762000724620015c8565b602002602001015160200151905060006002811115620007485762000748620015de565b8160028111156200075d576200075d620015de565b03620007bb57620007b58583815181106200077c576200077c620015c8565b6020026020010151600001518684815181106200079d576200079d620015c8565b6020026020010151604001516200095b60201b60201c565b620008f6565b6001816002811115620007d257620007d2620015de565b036200082a57620007b5858381518110620007f157620007f1620015c8565b602002602001015160000151868481518110620008125762000812620015c8565b60200260200101516040015162000bf760201b60201c565b6002816002811115620008415762000841620015de565b036200089957620007b5858381518110620008605762000860620015c8565b602002602001015160000151868481518110620008815762000881620015c8565b60200260200101516040015162000ea160201b60201c565b60405162461bcd60e51b815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f727265637420466163657443756044820152663a20b1ba34b7b760c91b60648201526084015b60405180910390fd5b508062000903816200160a565b91505062000703565b507f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb67383838360405162000942939291906200167a565b60405180910390a162000956828262001005565b505050565b805180620009af5760405162461bcd60e51b815260206004820152602b602482015260008051602062001ff883398151915260448201526a1858d95d081d1bc818dd5d60aa1b6064820152608401620008ed565b60008051602062001f8c8339815191526001600160a01b03841662000a2c5760405162461bcd60e51b815260206004820152602c60248201527f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260448201526b65206164647265737328302960a01b6064820152608401620008ed565b6001600160a01b0384166000908152600182016020526040812054906001600160601b038216900362000a655762000a658286620010dd565b60005b8381101562000bef57600085828151811062000a885762000a88620015c8565b6020908102919091018101516001600160e01b031981166000908152918690526040909120549091506001600160a01b0316801562000b305760405162461bcd60e51b815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c72656164792065786973747300000000000000000000006064820152608401620008ed565b6001600160e01b0319821660008181526020878152604080832080546001600160a01b03908116600160a01b6001600160601b038c16021782558d168085526001808c0185529285208054938401815585528385206008840401805463ffffffff60079095166004026101000a948502191660e08a901c94909402939093179092559390925287905281546001600160a01b0319161790558362000bd48162001781565b9450505050808062000be6906200160a565b91505062000a68565b505050505050565b80518062000c4b5760405162461bcd60e51b815260206004820152602b602482015260008051602062001ff883398151915260448201526a1858d95d081d1bc818dd5d60aa1b6064820152608401620008ed565b60008051602062001f8c8339815191526001600160a01b03841662000ccc5760405162461bcd60e51b815260206004820152603060248201527f4c69624469616d6f6e644375743a205265706c6163652066616365742063616e60448201526f2774206265206164647265737328302960801b6064820152608401620008ed565b6001600160a01b0384166000908152600182016020526040812054906001600160601b038216900362000d055762000d058286620010dd565b60005b8381101562000bef57600085828151811062000d285762000d28620015c8565b6020908102919091018101516001600160e01b031981166000908152918690526040909120549091506001600160a01b03908116908816810362000dd55760405162461bcd60e51b815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d6520666163657400000000000000000000006064820152608401620008ed565b62000de28582846200114a565b6001600160e01b0319821660008181526020878152604080832080546001600160a01b03908116600160a01b6001600160601b038c16021782558d168085526001808c0185529285208054938401815585528385206008840401805463ffffffff60079095166004026101000a948502191660e08a901c94909402939093179092559390925287905281546001600160a01b0319161790558362000e868162001781565b9450505050808062000e98906200160a565b91505062000d08565b80518062000ef55760405162461bcd60e51b815260206004820152602b602482015260008051602062001ff883398151915260448201526a1858d95d081d1bc818dd5d60aa1b6064820152608401620008ed565b60008051602062001f8c8339815191526001600160a01b0384161562000f845760405162461bcd60e51b815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d7573742062652061646472657373283029000000000000000000006064820152608401620008ed565b60005b8281101562000ffe57600084828151811062000fa75762000fa7620015c8565b6020908102919091018101516001600160e01b031981166000908152918590526040909120549091506001600160a01b031662000fe68482846200114a565b5050808062000ff5906200160a565b91505062000f87565b5050505050565b6001600160a01b03821662001018575050565b6200103d8260405180606001604052806028815260200162001fac602891396200152a565b600080836001600160a01b0316836040516200105a9190620017b2565b600060405180830381855af49150503d806000811462001097576040519150601f19603f3d011682016040523d82523d6000602084013e6200109c565b606091505b509150915081620010d757805115620010b85780518082602001fd5b838360405163192105d760e01b8152600401620008ed929190620017d0565b50505050565b620011028160405180606001604052806024815260200162001fd4602491396200152a565b6002820180546001600160a01b0390921660008181526001948501602090815260408220860185905594840183559182529290200180546001600160a01b0319169091179055565b6001600160a01b038216620011c85760405162461bcd60e51b815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608401620008ed565b306001600160a01b03831603620012395760405162461bcd60e51b815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201526d3a30b1363290333ab731ba34b7b760911b6064820152608401620008ed565b6001600160e01b03198116600090815260208481526040808320546001600160a01b0386168452600180880190935290832054600160a01b9091046001600160601b031692916200128a91620017fe565b905080821462001383576001600160a01b03841660009081526001860160205260408120805483908110620012c357620012c3620015c8565b600091825260208083206008830401546001600160a01b038916845260018a019091526040909220805460079092166004026101000a90920460e01b925082919085908110620013175762001317620015c8565b600091825260208083206008830401805463ffffffff60079094166004026101000a938402191660e09590951c929092029390931790556001600160e01b03199290921682528690526040902080546001600160a01b0316600160a01b6001600160601b038516021790555b6001600160a01b03841660009081526001860160205260409020805480620013af57620013af6200181a565b60008281526020808220600860001990940193840401805463ffffffff600460078716026101000a0219169055919092556001600160e01b0319851682528690526040812081905581900362000ffe5760028501546000906200141590600190620017fe565b6001600160a01b0386166000908152600180890160205260409091200154909150808214620014cb576000876002018381548110620014585762001458620015c8565b6000918252602090912001546002890180546001600160a01b0390921692508291849081106200148c576200148c620015c8565b600091825260208083209190910180546001600160a01b0319166001600160a01b03948516179055929091168152600189810190925260409020018190555b86600201805480620014e157620014e16200181a565b60008281526020808220830160001990810180546001600160a01b03191690559092019092556001600160a01b0388168252600189810190915260408220015550505050505050565b813b8181620010d75760405162461bcd60e51b8152600401620008ed919062001830565b80516001600160a01b03811681146200156657600080fd5b919050565b600080600080608085870312156200158257600080fd5b6200158d856200154e565b93506200159d602086016200154e565b9250620015ad604086016200154e565b9150620015bd606086016200154e565b905092959194509250565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016200161f576200161f620015f4565b5060010190565b60005b838110156200164357818101518382015260200162001629565b50506000910152565b600081518084526200166681602086016020860162001626565b601f01601f19169290920160200192915050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b848110156200174f57898403607f19018652815180516001600160a01b03168552838101518986019060038110620016eb57634e487b7160e01b600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b80831015620017395783516001600160e01b03191682529286019260019290920191908601906200170d565b50978501979550505090820190600101620016a3565b50506001600160a01b038a169088015286810360408801526200177381896200164c565b9a9950505050505050505050565b60006001600160601b038281166002600160601b03198101620017a857620017a8620015f4565b6001019392505050565b60008251620017c681846020870162001626565b9190910192915050565b6001600160a01b0383168152604060208201819052600090620017f6908301846200164c565b949350505050565b81810381811115620018145762001814620015f4565b92915050565b634e487b7160e01b600052603160045260246000fd5b6020815260006200184560208301846200164c565b9392505050565b610730806200185c6000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806352ef6b2c146100515780637a0ed6271461006f578063adfca15e14610084578063cdffacc6146100a4575b600080fd5b610059610140565b60405161006691906104ab565b60405180910390f35b6100776101d1565b6040516100669190610562565b61009761009236600461060a565b6103d1565b6040516100669190610647565b61011b6100b236600461065a565b7fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610066565b60607f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6002018054806020026020016040519081016040528092919081815260200182805480156101c757602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161019c575b5050505050905090565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f908067ffffffffffffffff8111156102315761023161069c565b60405190808252806020026020018201604052801561027757816020015b60408051808201909152600081526060602082015281526020019060019003908161024f5790505b50925060005b818110156103cb57600083600201828154811061029c5761029c6106cb565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050808583815181106102dc576102dc6106cb565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff928316905290821660009081526001860182526040908190208054825181850281018501909352808352919290919083018282801561039d57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161034a5790505b50505050508583815181106103b4576103b46106cb565b60209081029190910181015101525060010161027d565b50505090565b73ffffffffffffffffffffffffffffffffffffffff811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4920602090815260409182902080548351818402810184019094528084526060939283018282801561049f57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161044c5790505b50505050509050919050565b6020808252825182820181905260009190848201906040850190845b818110156104f957835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016104c7565b50909695505050505050565b600081518084526020808501945080840160005b838110156105575781517fffffffff000000000000000000000000000000000000000000000000000000001687529582019590820190600101610519565b509495945050505050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b838110156105fc578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00185528151805173ffffffffffffffffffffffffffffffffffffffff1684528701518784018790526105e987850182610505565b9588019593505090860190600101610589565b509098975050505050505050565b60006020828403121561061c57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461064057600080fd5b9392505050565b6020815260006106406020830184610505565b60006020828403121561066c57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461064057600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea264697066735822122024a872696a5ad50024326567061c50adea63ff0d49edf0ac60339459d33d571664736f6c63430008150033183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f4c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a204e657720666163657420686173206e6f20636f64654c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e2066", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806352ef6b2c146100515780637a0ed6271461006f578063adfca15e14610084578063cdffacc6146100a4575b600080fd5b610059610140565b60405161006691906104ab565b60405180910390f35b6100776101d1565b6040516100669190610562565b61009761009236600461060a565b6103d1565b6040516100669190610647565b61011b6100b236600461065a565b7fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610066565b60607f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6002018054806020026020016040519081016040528092919081815260200182805480156101c757602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161019c575b5050505050905090565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f908067ffffffffffffffff8111156102315761023161069c565b60405190808252806020026020018201604052801561027757816020015b60408051808201909152600081526060602082015281526020019060019003908161024f5790505b50925060005b818110156103cb57600083600201828154811061029c5761029c6106cb565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050808583815181106102dc576102dc6106cb565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff928316905290821660009081526001860182526040908190208054825181850281018501909352808352919290919083018282801561039d57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161034a5790505b50505050508583815181106103b4576103b46106cb565b60209081029190910181015101525060010161027d565b50505090565b73ffffffffffffffffffffffffffffffffffffffff811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4920602090815260409182902080548351818402810184019094528084526060939283018282801561049f57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161044c5790505b50505050509050919050565b6020808252825182820181905260009190848201906040850190845b818110156104f957835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016104c7565b50909695505050505050565b600081518084526020808501945080840160005b838110156105575781517fffffffff000000000000000000000000000000000000000000000000000000001687529582019590820190600101610519565b509495945050505050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b838110156105fc578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00185528151805173ffffffffffffffffffffffffffffffffffffffff1684528701518784018790526105e987850182610505565b9588019593505090860190600101610589565b509098975050505050505050565b60006020828403121561061c57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461064057600080fd5b9392505050565b6020815260006106406020830184610505565b60006020828403121561066c57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461064057600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea264697066735822122024a872696a5ad50024326567061c50adea63ff0d49edf0ac60339459d33d571664736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "A default fallback handler for Barz", + "kind": "dev", + "methods": { + "constructor": { + "details": "This contract is also a diamond that holds the default facets to reduce gas cost for wallet activation. Within the constructor this conducts diamond cut to initially setup the diamond. This is a non-upgradeable contract", + "params": { + "_accountFacet": "Address account facet", + "_diamondCutFacet": "Address if diamond cut facet", + "_diamondLoupeFacet": "Address of diamond loupe facet", + "_tokenReceiverFacet": "Address of token receiver facet" + } + }, + "facetAddress(bytes4)": { + "details": "If facet is not found return address(0).", + "params": { + "_functionSelector": "The function selector." + }, + "returns": { + "facetAddress_": "The facet address." + } + }, + "facetAddresses()": { + "returns": { + "facetAddresses_": "facetAddresses_" + } + }, + "facetFunctionSelectors(address)": { + "params": { + "_facet": "The facet address." + }, + "returns": { + "facetFunctionSelectors_": "facetFunctionSelectors_" + } + }, + "facets()": { + "returns": { + "facets_": "The facet struct array including all facet information" + } + } + }, + "title": "DefaultFallbackHandler", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "constructor": { + "notice": "Sets the middleware diamond for Barz wallet as a fallback handler" + }, + "facetAddress(bytes4)": { + "notice": "Gets the facet that supports the given selector." + }, + "facetAddresses()": { + "notice": "Get all the facet addresses used by a diamond." + }, + "facetFunctionSelectors(address)": { + "notice": "Gets all the function selectors provided by a facet." + }, + "facets()": { + "notice": "Returns the facet information of call facets registered to this diamond." + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/blast/DiamondCutFacet.json b/deployments/blast/DiamondCutFacet.json new file mode 100644 index 0000000..9b0c69f --- /dev/null +++ b/deployments/blast/DiamondCutFacet.json @@ -0,0 +1,856 @@ +{ + "address": "0x0B9504140771C3688Ff041917192277D2f52E1e0", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_securityManager", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "CallerNotGuardian", + "type": "error" + }, + { + "inputs": [], + "name": "CallerNotGuardianOrOwner", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__CannotRevokeUnapproved", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__DuplicateApproval", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InsufficientApprovers", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidApprovalValidationPeriod", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidApprover", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidApproverSignature", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidArrayLength", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidInitAddress", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidRouteWithGuardian", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidRouteWithoutGuardian", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__LackOfOwnerApproval", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__OwnerAlreadyApproved", + "type": "error" + }, + { + "inputs": [], + "name": "DuplicateApprover", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_initializationContractAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "InitializationFunctionReverted", + "type": "error" + }, + { + "inputs": [], + "name": "UnregisteredFacetAndSelectors", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroApproverLength", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "indexed": false, + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "DiamondCut", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "diamondCut", + "type": "tuple[]" + } + ], + "name": "DiamondCutApprovalRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "diamondCut", + "type": "tuple[]" + } + ], + "name": "DiamondCutApproved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + }, + { + "indexed": false, + "internalType": "bool", + "name": "_lag", + "type": "bool" + } + ], + "name": "SupportsInterfaceUpdated", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_diamondCutHash", + "type": "bytes32" + }, + { + "internalType": "address[]", + "name": "_approvers", + "type": "address[]" + } + ], + "name": "_checkDuplicateOnChainApprover", + "outputs": [], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + } + ], + "name": "approveDiamondCut", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "diamondCut", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "internalType": "address[]", + "name": "_approvers", + "type": "address[]" + }, + { + "internalType": "bytes[]", + "name": "_signatures", + "type": "bytes[]" + } + ], + "name": "diamondCutWithGuardian", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_diamondCutHash", + "type": "bytes32" + } + ], + "name": "getDiamondCutApprovalCountWithTimeValidity", + "outputs": [ + { + "internalType": "uint256", + "name": "approvalCount", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + } + ], + "name": "getDiamondCutHash", + "outputs": [ + { + "internalType": "bytes32", + "name": "cutHash", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getDiamondCutNonce", + "outputs": [ + { + "internalType": "uint128", + "name": "cutNonce", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_diamondCutHash", + "type": "bytes32" + } + ], + "name": "getOwnerCutApprovalWithTimeValidity", + "outputs": [ + { + "internalType": "bool", + "name": "isApprovedByOwner", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_diamondCutHash", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "_approver", + "type": "address" + } + ], + "name": "isCutApproved", + "outputs": [ + { + "internalType": "bool", + "name": "isApproved", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + } + ], + "name": "revokeDiamondCutApproval", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "securityManager", + "outputs": [ + { + "internalType": "contract ISecurityManager", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_interfaceId", + "type": "bytes4" + }, + { + "internalType": "bool", + "name": "_flag", + "type": "bool" + } + ], + "name": "updateSupportsInterface", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0xd60ce780e82ff17e8019dfa2424015cabbd87f5e6d1bd5867356da0679c70bb1", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 13, + "gasUsed": "3079879", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x4cc1990c655a95d7ca832c8815cb9e6826ab2ed870adc4c100040a40d29aa710", + "transactionHash": "0xd60ce780e82ff17e8019dfa2424015cabbd87f5e6d1bd5867356da0679c70bb1", + "logs": [], + "blockNumber": 1317760, + "cumulativeGasUsed": "5078830", + "status": 1, + "byzantium": true + }, + "args": [ + "0xcBe266adbfd7CB32988128e7f37b7c8b3C5521A8" + ], + "numDeployments": 1, + "solcInputHash": "ad34345aa73d96f52b3e14df983b6b29", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_securityManager\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"CallerNotGuardian\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallerNotGuardianOrOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__CannotRevokeUnapproved\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__DuplicateApproval\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InsufficientApprovers\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidApprovalValidationPeriod\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidApprover\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidApproverSignature\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidArrayLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidInitAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidRouteWithGuardian\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidRouteWithoutGuardian\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__LackOfOwnerApproval\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__OwnerAlreadyApproved\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateApprover\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_initializationContractAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"InitializationFunctionReverted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnregisteredFacetAndSelectors\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroApproverLength\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"DiamondCut\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"diamondCut\",\"type\":\"tuple[]\"}],\"name\":\"DiamondCutApprovalRevoked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"diamondCut\",\"type\":\"tuple[]\"}],\"name\":\"DiamondCutApproved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"_lag\",\"type\":\"bool\"}],\"name\":\"SupportsInterfaceUpdated\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_diamondCutHash\",\"type\":\"bytes32\"},{\"internalType\":\"address[]\",\"name\":\"_approvers\",\"type\":\"address[]\"}],\"name\":\"_checkDuplicateOnChainApprover\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"}],\"name\":\"approveDiamondCut\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"diamondCut\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"internalType\":\"address[]\",\"name\":\"_approvers\",\"type\":\"address[]\"},{\"internalType\":\"bytes[]\",\"name\":\"_signatures\",\"type\":\"bytes[]\"}],\"name\":\"diamondCutWithGuardian\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_diamondCutHash\",\"type\":\"bytes32\"}],\"name\":\"getDiamondCutApprovalCountWithTimeValidity\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"approvalCount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"}],\"name\":\"getDiamondCutHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"cutHash\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDiamondCutNonce\",\"outputs\":[{\"internalType\":\"uint128\",\"name\":\"cutNonce\",\"type\":\"uint128\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_diamondCutHash\",\"type\":\"bytes32\"}],\"name\":\"getOwnerCutApprovalWithTimeValidity\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isApprovedByOwner\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_diamondCutHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"_approver\",\"type\":\"address\"}],\"name\":\"isCutApproved\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isApproved\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"}],\"name\":\"revokeDiamondCutApproval\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"securityManager\",\"outputs\":[{\"internalType\":\"contract ISecurityManager\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_interfaceId\",\"type\":\"bytes4\"},{\"internalType\":\"bool\",\"name\":\"_flag\",\"type\":\"bool\"}],\"name\":\"updateSupportsInterface\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"Responsible for adding/removing/replace facets in Barz\",\"kind\":\"dev\",\"methods\":{\"_checkDuplicateOnChainApprover(bytes32,address[])\":{\"params\":{\"_approvers\":\"List of approver addresses\",\"_diamondCutHash\":\"Hash of diamondCut information including the facet addresses and function selectors\"}},\"approveDiamondCut((address,uint8,bytes4[])[])\":{\"params\":{\"_diamondCut\":\"Contains the facet addresses and function selectors\"}},\"constructor\":{\"params\":{\"_securityManager\":\"Security Manager contract that holds the security related variables for all wallets\"}},\"diamondCut((address,uint8,bytes4[])[],address,bytes)\":{\"params\":{\"_diamondCut\":\"Contains the facet addresses and function selectors\",\"_init\":\"The address of the contract or facet to execute _calldata. It's prohibited in Barz\"}},\"diamondCutWithGuardian((address,uint8,bytes4[])[],address[],bytes[])\":{\"params\":{\"_approvers\":\"Guardian or owner address that approves the diamond cut\",\"_diamondCut\":\"Contains the facet addresses and function selectors\",\"_signatures\":\"Signature of Guardians or owner that approves the diamond cut\"}},\"getDiamondCutApprovalCountWithTimeValidity(bytes32)\":{\"params\":{\"_diamondCutHash\":\"Hash of diamondCut information including the facet addresses and function selectors\"}},\"getDiamondCutHash((address,uint8,bytes4[])[])\":{\"params\":{\"_diamondCut\":\"Contains the facet addresses and function selectors\"},\"returns\":{\"cutHash\":\"Diamond Cut Hash\"}},\"getDiamondCutNonce()\":{\"details\":\"This method fetches the nonce from diamond cut storage\",\"returns\":{\"cutNonce\":\"Nonce of diamond cut to protect from reply attacks\"}},\"getOwnerCutApprovalWithTimeValidity(bytes32)\":{\"params\":{\"_diamondCutHash\":\"Hash of diamondCut information including the facet addresses and function selectors\"},\"returns\":{\"isApprovedByOwner\":\"Bool value showing if the owner approved the cut\"}},\"isCutApproved(bytes32,address)\":{\"params\":{\"_approver\":\"Address of approver\",\"_diamondCutHash\":\"Hash of diamondCut information including the facet addresses and function selectors\"},\"returns\":{\"isApproved\":\"Bool value showing if the approver approved the cut\"}},\"revokeDiamondCutApproval((address,uint8,bytes4[])[])\":{\"params\":{\"_diamondCut\":\"Contains the facet addresses and function selectors\"}},\"updateSupportsInterface(bytes4,bool)\":{\"params\":{\"_flag\":\"Bool value to update the mapping of the given interface ID\",\"_interfaceId\":\"InterfaceID to update the mapping\"}}},\"title\":\"DiamondCut Facet\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"_checkDuplicateOnChainApprover(bytes32,address[])\":{\"notice\":\"Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval Approvers who approved on-chain should not be included in the off-chain approval\"},\"approveDiamondCut((address,uint8,bytes4[])[])\":{\"notice\":\"Approves diamond cut. This can only be called directly from guardian or owner\"},\"constructor\":{\"notice\":\"This constructor sets the Security Manager address which is an immutable variable. Immutable variables do not impact the storage of diamond\"},\"diamondCut((address,uint8,bytes4[])[],address,bytes)\":{\"notice\":\"Add/replace/remove any number of functions and optionally execute a function with delegatecall when guardians don't exist\"},\"diamondCutWithGuardian((address,uint8,bytes4[])[],address[],bytes[])\":{\"notice\":\"Add/replace/remove any number of functions and optionally execute a function with delegatecall when guardians exist\"},\"getDiamondCutApprovalCountWithTimeValidity(bytes32)\":{\"notice\":\"Gets the number of approvals of diamond cut from guardians\"},\"getDiamondCutHash((address,uint8,bytes4[])[])\":{\"notice\":\"Returns the diamond cut hash. This function ensures that this hash is safe from replay attack by including salt, address, chainId, and nonce, etc.\"},\"getDiamondCutNonce()\":{\"notice\":\"Returns the diamond cut nonce of this wallet\"},\"getOwnerCutApprovalWithTimeValidity(bytes32)\":{\"notice\":\"Returns if the owner has approved the diamond cut\"},\"isCutApproved(bytes32,address)\":{\"notice\":\"Returns if the given approver has approved the diamond cut\"},\"revokeDiamondCutApproval((address,uint8,bytes4[])[])\":{\"notice\":\"Revokes the approval of diamond cut. This can only be called directly from guardian or owner\"},\"updateSupportsInterface(bytes4,bool)\":{\"notice\":\"Updates the flag for the interfaceId\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/base/DiamondCutFacet.sol\":\"DiamondCutFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/interfaces/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC1271 standard signature validation method for\\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC1271 {\\n /**\\n * @dev Should return whether the signature provided is valid for the provided data\\n * @param hash Hash of the data to be signed\\n * @param signature Signature byte array associated with _data\\n */\\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\\n}\\n\",\"keccak256\":\"0x0705a4b1b86d7b0bd8432118f226ba139c44b9dcaba0a6eafba2dd7d0639c544\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./math/Math.sol\\\";\\nimport \\\"./math/SignedMath.sol\\\";\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n uint256 length = Math.log10(value) + 1;\\n string memory buffer = new string(length);\\n uint256 ptr;\\n /// @solidity memory-safe-assembly\\n assembly {\\n ptr := add(buffer, add(32, length))\\n }\\n while (true) {\\n ptr--;\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\\n }\\n value /= 10;\\n if (value == 0) break;\\n }\\n return buffer;\\n }\\n }\\n\\n /**\\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\\n */\\n function toString(int256 value) internal pure returns (string memory) {\\n return string(abi.encodePacked(value < 0 ? \\\"-\\\" : \\\"\\\", toString(SignedMath.abs(value))));\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n return toHexString(value, Math.log256(value) + 1);\\n }\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n\\n /**\\n * @dev Returns true if the two strings are equal.\\n */\\n function equal(string memory a, string memory b) internal pure returns (bool) {\\n return keccak256(bytes(a)) == keccak256(bytes(b));\\n }\\n}\\n\",\"keccak256\":\"0x3088eb2868e8d13d89d16670b5f8612c4ab9ff8956272837d8e90106c59c14a0\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Strings.sol\\\";\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSA {\\n enum RecoverError {\\n NoError,\\n InvalidSignature,\\n InvalidSignatureLength,\\n InvalidSignatureS,\\n InvalidSignatureV // Deprecated in v4.8\\n }\\n\\n function _throwError(RecoverError error) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert(\\\"ECDSA: invalid signature\\\");\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert(\\\"ECDSA: invalid signature length\\\");\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert(\\\"ECDSA: invalid signature 's' value\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature` or error string. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n *\\n * Documentation for signature generation:\\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n return tryRecover(hash, v, r, s);\\n } else {\\n return (address(0), RecoverError.InvalidSignatureLength);\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature`. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, signature);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\\n uint8 v = uint8((uint256(vs) >> 255) + 27);\\n return tryRecover(hash, v, r, s);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n *\\n * _Available since v4.2._\\n */\\n function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\\n // the valid range for s in (301): 0 < s < secp256k1n \\u00f7 2 + 1, and for v in (302): v \\u2208 {27, 28}. Most\\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\\n //\\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\\n // these malleable signatures as well.\\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n return (address(0), RecoverError.InvalidSignatureS);\\n }\\n\\n // If the signature is valid (and not malleable), return the signer address\\n address signer = ecrecover(hash, v, r, s);\\n if (signer == address(0)) {\\n return (address(0), RecoverError.InvalidSignature);\\n }\\n\\n return (signer, RecoverError.NoError);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore(0x00, \\\"\\\\x19Ethereum Signed Message:\\\\n32\\\")\\n mstore(0x1c, hash)\\n message := keccak256(0x00, 0x3c)\\n }\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from `s`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n\\\", Strings.toString(s.length), s));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Typed Data, created from a\\n * `domainSeparator` and a `structHash`. This produces hash corresponding\\n * to the one signed with the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n * JSON-RPC method as part of EIP-712.\\n *\\n * See {recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n let ptr := mload(0x40)\\n mstore(ptr, \\\"\\\\x19\\\\x01\\\")\\n mstore(add(ptr, 0x02), domainSeparator)\\n mstore(add(ptr, 0x22), structHash)\\n data := keccak256(ptr, 0x42)\\n }\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Data with intended validator, created from a\\n * `validator` and `data` according to the version 0 of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x00\\\", validator, data));\\n }\\n}\\n\",\"keccak256\":\"0x809bc3edb4bcbef8263fa616c1b60ee0004b50a8a1bfa164d8f57fd31f520c58\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/SignatureChecker.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./ECDSA.sol\\\";\\nimport \\\"../../interfaces/IERC1271.sol\\\";\\n\\n/**\\n * @dev Signature verification helper that can be used instead of `ECDSA.recover` to seamlessly support both ECDSA\\n * signatures from externally owned accounts (EOAs) as well as ERC1271 signatures from smart contract wallets like\\n * Argent and Gnosis Safe.\\n *\\n * _Available since v4.1._\\n */\\nlibrary SignatureChecker {\\n /**\\n * @dev Checks if a signature is valid for a given signer and data hash. If the signer is a smart contract, the\\n * signature is validated against that smart contract using ERC1271, otherwise it's validated using `ECDSA.recover`.\\n *\\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\\n */\\n function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature) internal view returns (bool) {\\n (address recovered, ECDSA.RecoverError error) = ECDSA.tryRecover(hash, signature);\\n return\\n (error == ECDSA.RecoverError.NoError && recovered == signer) ||\\n isValidERC1271SignatureNow(signer, hash, signature);\\n }\\n\\n /**\\n * @dev Checks if a signature is valid for a given signer and data hash. The signature is validated\\n * against the signer smart contract using ERC1271.\\n *\\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\\n */\\n function isValidERC1271SignatureNow(\\n address signer,\\n bytes32 hash,\\n bytes memory signature\\n ) internal view returns (bool) {\\n (bool success, bytes memory result) = signer.staticcall(\\n abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, signature)\\n );\\n return (success &&\\n result.length >= 32 &&\\n abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector));\\n }\\n}\\n\",\"keccak256\":\"0x3af3ca86df39aac39a0514c84459d691434a108d2151c8ce9d69f32e315cab80\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n enum Rounding {\\n Down, // Toward negative infinity\\n Up, // Toward infinity\\n Zero // Toward zero\\n }\\n\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow.\\n return (a & b) + (a ^ b) / 2;\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a == 0 ? 0 : (a - 1) / b + 1;\\n }\\n\\n /**\\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\\n * with further edits by Uniswap Labs also under MIT license.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\\n unchecked {\\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2^256 + prod0.\\n uint256 prod0; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division.\\n if (prod1 == 0) {\\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\\n // The surrounding unchecked block does not change this fact.\\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\\n return prod0 / denominator;\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n require(denominator > prod1, \\\"Math: mulDiv overflow\\\");\\n\\n ///////////////////////////////////////////////\\n // 512 by 256 division.\\n ///////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0].\\n uint256 remainder;\\n assembly {\\n // Compute remainder using mulmod.\\n remainder := mulmod(x, y, denominator)\\n\\n // Subtract 256 bit number from 512 bit number.\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\\n // See https://cs.stackexchange.com/q/138556/92363.\\n\\n // Does not overflow because the denominator cannot be zero at this stage in the function.\\n uint256 twos = denominator & (~denominator + 1);\\n assembly {\\n // Divide denominator by twos.\\n denominator := div(denominator, twos)\\n\\n // Divide [prod1 prod0] by twos.\\n prod0 := div(prod0, twos)\\n\\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\\n twos := add(div(sub(0, twos), twos), 1)\\n }\\n\\n // Shift in bits from prod1 into prod0.\\n prod0 |= prod1 * twos;\\n\\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\\n // four bits. That is, denominator * inv = 1 mod 2^4.\\n uint256 inverse = (3 * denominator) ^ 2;\\n\\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\\n // in modular arithmetic, doubling the correct bits in each step.\\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\\n\\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inverse;\\n return result;\\n }\\n }\\n\\n /**\\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\\n uint256 result = mulDiv(x, y, denominator);\\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\\n result += 1;\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\\n *\\n * Inspired by Henry S. Warren, Jr.'s \\\"Hacker's Delight\\\" (Chapter 11).\\n */\\n function sqrt(uint256 a) internal pure returns (uint256) {\\n if (a == 0) {\\n return 0;\\n }\\n\\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\\n //\\n // We know that the \\\"msb\\\" (most significant bit) of our target number `a` is a power of 2 such that we have\\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\\n //\\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\\n // \\u2192 `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\\n // \\u2192 `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\\n //\\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\\n uint256 result = 1 << (log2(a) >> 1);\\n\\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\\n // into the expected uint128 result.\\n unchecked {\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n return min(result, a / result);\\n }\\n }\\n\\n /**\\n * @notice Calculates sqrt(a), following the selected rounding direction.\\n */\\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = sqrt(a);\\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 2, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 128;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 64;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 32;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 16;\\n }\\n if (value >> 8 > 0) {\\n value >>= 8;\\n result += 8;\\n }\\n if (value >> 4 > 0) {\\n value >>= 4;\\n result += 4;\\n }\\n if (value >> 2 > 0) {\\n value >>= 2;\\n result += 2;\\n }\\n if (value >> 1 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log2(value);\\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 10, rounded down, of a positive value.\\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 + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 256, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n *\\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\\n */\\n function log256(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 16;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 8;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 4;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 2;\\n }\\n if (value >> 8 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log256(value);\\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe4455ac1eb7fc497bb7402579e7b4d64d928b846fce7d2b6fde06d366f21c2b3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\\n * checks.\\n *\\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\\n * easily result in undesired exploitation or bugs, since developers usually\\n * assume that overflows raise errors. `SafeCast` restores this intuition by\\n * reverting the transaction when such an operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n *\\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\\n * all math on `uint256` and `int256` and then downcasting.\\n */\\nlibrary SafeCast {\\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 * _Available since v4.7._\\n */\\n function toUint248(uint256 value) internal pure returns (uint248) {\\n require(value <= type(uint248).max, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint240(uint256 value) internal pure returns (uint240) {\\n require(value <= type(uint240).max, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint232(uint256 value) internal pure returns (uint232) {\\n require(value <= type(uint232).max, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint224(uint256 value) internal pure returns (uint224) {\\n require(value <= type(uint224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint216(uint256 value) internal pure returns (uint216) {\\n require(value <= type(uint216).max, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint208(uint256 value) internal pure returns (uint208) {\\n require(value <= type(uint208).max, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint200(uint256 value) internal pure returns (uint200) {\\n require(value <= type(uint200).max, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint192(uint256 value) internal pure returns (uint192) {\\n require(value <= type(uint192).max, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint184(uint256 value) internal pure returns (uint184) {\\n require(value <= type(uint184).max, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint176(uint256 value) internal pure returns (uint176) {\\n require(value <= type(uint176).max, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint168(uint256 value) internal pure returns (uint168) {\\n require(value <= type(uint168).max, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint160(uint256 value) internal pure returns (uint160) {\\n require(value <= type(uint160).max, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint152(uint256 value) internal pure returns (uint152) {\\n require(value <= type(uint152).max, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint144(uint256 value) internal pure returns (uint144) {\\n require(value <= type(uint144).max, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint136(uint256 value) internal pure returns (uint136) {\\n require(value <= type(uint136).max, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint128(uint256 value) internal pure returns (uint128) {\\n require(value <= type(uint128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint120(uint256 value) internal pure returns (uint120) {\\n require(value <= type(uint120).max, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint112(uint256 value) internal pure returns (uint112) {\\n require(value <= type(uint112).max, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint104(uint256 value) internal pure returns (uint104) {\\n require(value <= type(uint104).max, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint96(uint256 value) internal pure returns (uint96) {\\n require(value <= type(uint96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint88(uint256 value) internal pure returns (uint88) {\\n require(value <= type(uint88).max, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint80(uint256 value) internal pure returns (uint80) {\\n require(value <= type(uint80).max, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint72(uint256 value) internal pure returns (uint72) {\\n require(value <= type(uint72).max, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint64(uint256 value) internal pure returns (uint64) {\\n require(value <= type(uint64).max, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint56(uint256 value) internal pure returns (uint56) {\\n require(value <= type(uint56).max, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint48(uint256 value) internal pure returns (uint48) {\\n require(value <= type(uint48).max, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint40(uint256 value) internal pure returns (uint40) {\\n require(value <= type(uint40).max, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint32(uint256 value) internal pure returns (uint32) {\\n require(value <= type(uint32).max, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint24(uint256 value) internal pure returns (uint24) {\\n require(value <= type(uint24).max, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint16(uint256 value) internal pure returns (uint16) {\\n require(value <= type(uint16).max, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint8(uint256 value) internal pure returns (uint8) {\\n require(value <= type(uint8).max, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\n */\\n function toUint256(int256 value) internal pure returns (uint256) {\\n require(value >= 0, \\\"SafeCast: value must be positive\\\");\\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 * _Available since v4.7._\\n */\\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\\n downcasted = int248(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\\n downcasted = int240(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\\n downcasted = int232(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\\n downcasted = int224(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\\n downcasted = int216(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\\n downcasted = int208(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\\n downcasted = int200(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\\n downcasted = int192(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\\n downcasted = int184(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\\n downcasted = int176(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\\n downcasted = int168(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\\n downcasted = int160(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\\n downcasted = int152(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\\n downcasted = int144(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\\n downcasted = int136(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\\n downcasted = int128(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\\n downcasted = int120(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\\n downcasted = int112(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\\n downcasted = int104(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\\n downcasted = int96(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\\n downcasted = int88(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\\n downcasted = int80(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\\n downcasted = int72(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\\n downcasted = int64(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\\n downcasted = int56(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\\n downcasted = int48(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\\n downcasted = int40(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\\n downcasted = int32(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\\n downcasted = int24(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\\n downcasted = int16(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\\n downcasted = int8(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\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 require(value <= uint256(type(int256).max), \\\"SafeCast: value doesn't fit in an int256\\\");\\n return int256(value);\\n }\\n}\\n\",\"keccak256\":\"0x52a8cfb0f5239d11b457dcdd1b326992ef672714ca8da71a157255bddd13f3ad\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SignedMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard signed math utilities missing in the Solidity language.\\n */\\nlibrary SignedMath {\\n /**\\n * @dev Returns the largest of two signed numbers.\\n */\\n function max(int256 a, int256 b) internal pure returns (int256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two signed numbers.\\n */\\n function min(int256 a, int256 b) internal pure returns (int256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two signed numbers without overflow.\\n * The result is rounded towards zero.\\n */\\n function average(int256 a, int256 b) internal pure returns (int256) {\\n // Formula from the book \\\"Hacker's Delight\\\"\\n int256 x = (a & b) + ((a ^ b) >> 1);\\n return x + (int256(uint256(x) >> 255) & (a ^ b));\\n }\\n\\n /**\\n * @dev Returns the absolute unsigned value of a signed value.\\n */\\n function abs(int256 n) internal pure returns (uint256) {\\n unchecked {\\n // must be unchecked in order to support `n = type(int256).min`\\n return uint256(n >= 0 ? n : -n);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf92515413956f529d95977adc9b0567d583c6203fc31ab1c23824c35187e3ddc\",\"license\":\"MIT\"},\"contracts/aa-4337/core/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable no-inline-assembly */\\n\\n/**\\n * returned data from validateUserOp.\\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\\n * @param aggregator - address(0) - the account validated the signature by itself.\\n * address(1) - the account failed to validate the signature.\\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\\n * @param validAfter - this UserOp is valid only after this timestamp.\\n * @param validaUntil - this UserOp is valid only up to this timestamp.\\n */\\nstruct ValidationData {\\n address aggregator;\\n uint48 validAfter;\\n uint48 validUntil;\\n}\\n\\n//extract sigFailed, validAfter, validUntil.\\n// also convert zero validUntil to type(uint48).max\\nfunction _parseValidationData(\\n uint validationData\\n) pure returns (ValidationData memory data) {\\n address aggregator = address(uint160(validationData));\\n uint48 validUntil = uint48(validationData >> 160);\\n if (validUntil == 0) {\\n validUntil = type(uint48).max;\\n }\\n uint48 validAfter = uint48(validationData >> (48 + 160));\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n// intersect account and paymaster ranges.\\nfunction _intersectTimeRange(\\n uint256 validationData,\\n uint256 paymasterValidationData\\n) pure returns (ValidationData memory) {\\n ValidationData memory accountValidationData = _parseValidationData(\\n validationData\\n );\\n ValidationData memory pmValidationData = _parseValidationData(\\n paymasterValidationData\\n );\\n address aggregator = accountValidationData.aggregator;\\n if (aggregator == address(0)) {\\n aggregator = pmValidationData.aggregator;\\n }\\n uint48 validAfter = accountValidationData.validAfter;\\n uint48 validUntil = accountValidationData.validUntil;\\n uint48 pmValidAfter = pmValidationData.validAfter;\\n uint48 pmValidUntil = pmValidationData.validUntil;\\n\\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp\\n * @param data - the ValidationData to pack\\n */\\nfunction _packValidationData(\\n ValidationData memory data\\n) pure returns (uint256) {\\n return\\n uint160(data.aggregator) |\\n (uint256(data.validUntil) << 160) |\\n (uint256(data.validAfter) << (160 + 48));\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp, when not using an aggregator\\n * @param sigFailed - true for signature failure, false for success\\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\\n * @param validAfter first timestamp this UserOperation is valid\\n */\\nfunction _packValidationData(\\n bool sigFailed,\\n uint48 validUntil,\\n uint48 validAfter\\n) pure returns (uint256) {\\n return\\n (sigFailed ? 1 : 0) |\\n (uint256(validUntil) << 160) |\\n (uint256(validAfter) << (160 + 48));\\n}\\n\\n/**\\n * keccak function over calldata.\\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\\n */\\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\\n assembly {\\n let mem := mload(0x40)\\n let len := data.length\\n calldatacopy(mem, data.offset, len)\\n ret := keccak256(mem, len)\\n }\\n}\\n\",\"keccak256\":\"0xa79f06cd158ecb8c0da95493a2f348933b8627a63e228b99738bff3aa107942d\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAggregator.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\n/**\\n * Aggregated Signatures validator.\\n */\\ninterface IAggregator {\\n /**\\n * validate aggregated signature.\\n * revert if the aggregated signature does not match the given list of operations.\\n */\\n function validateSignatures(\\n UserOperation[] calldata userOps,\\n bytes calldata signature\\n ) external view;\\n\\n /**\\n * validate signature of a single userOp\\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\\n * @param userOp the userOperation received from the user.\\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\\n * (usually empty, unless account and aggregator support some kind of \\\"multisig\\\"\\n */\\n function validateUserOpSignature(\\n UserOperation calldata userOp\\n ) external view returns (bytes memory sigForUserOp);\\n\\n /**\\n * aggregate multiple signatures into a single value.\\n * This method is called off-chain to calculate the signature to pass with handleOps()\\n * bundler MAY use optimized custom code perform this aggregation\\n * @param userOps array of UserOperations to collect the signatures from.\\n * @return aggregatedSignature the aggregated signature\\n */\\n function aggregateSignatures(\\n UserOperation[] calldata userOps\\n ) external view returns (bytes memory aggregatedSignature);\\n}\\n\",\"keccak256\":\"0xdfdcd80568f037716674619b31be630fcd8316262f05a815b41d1e81782c966a\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IEntryPoint.sol\":{\"content\":\"/**\\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\\n ** Only one instance required on each chain.\\n **/\\n// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-inline-assembly */\\n/* solhint-disable reason-string */\\n\\nimport \\\"./UserOperation.sol\\\";\\nimport \\\"./IStakeManager.sol\\\";\\nimport \\\"./IAggregator.sol\\\";\\nimport \\\"./INonceManager.sol\\\";\\n\\ninterface IEntryPoint is IStakeManager, INonceManager {\\n /***\\n * An event emitted after each successful request\\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\\n * @param sender - the account that generates this request.\\n * @param paymaster - if non-null, the paymaster that pays for this request.\\n * @param nonce - the nonce value from the request.\\n * @param success - true if the sender transaction succeeded, false if reverted.\\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\\n */\\n event UserOperationEvent(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address indexed paymaster,\\n uint256 nonce,\\n bool success,\\n uint256 actualGasCost,\\n uint256 actualGasUsed\\n );\\n\\n /**\\n * account \\\"sender\\\" was deployed.\\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\\n * @param sender the account that is deployed\\n * @param factory the factory used to deploy this account (in the initCode)\\n * @param paymaster the paymaster used by this UserOp\\n */\\n event AccountDeployed(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address factory,\\n address paymaster\\n );\\n\\n /**\\n * An event emitted if the UserOperation \\\"callData\\\" reverted with non-zero length\\n * @param userOpHash the request unique identifier.\\n * @param sender the sender of this request\\n * @param nonce the nonce used in the request\\n * @param revertReason - the return bytes from the (reverted) call to \\\"callData\\\".\\n */\\n event UserOperationRevertReason(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n uint256 nonce,\\n bytes revertReason\\n );\\n\\n /**\\n * an event emitted by handleOps(), before starting the execution loop.\\n * any event emitted before this event, is part of the validation.\\n */\\n event BeforeExecution();\\n\\n /**\\n * signature aggregator used by the following UserOperationEvents within this bundle.\\n */\\n event SignatureAggregatorChanged(address indexed aggregator);\\n\\n /**\\n * a custom revert error of handleOps, to identify the offending op.\\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\\n * @param reason - revert reason\\n * The string starts with a unique code \\\"AAmn\\\", where \\\"m\\\" is \\\"1\\\" for factory, \\\"2\\\" for account and \\\"3\\\" for paymaster issues,\\n * so a failure can be attributed to the correct entity.\\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\\n */\\n error FailedOp(uint256 opIndex, string reason);\\n\\n /**\\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\\n */\\n error SignatureValidationFailed(address aggregator);\\n\\n /**\\n * Successful result from simulateValidation.\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n */\\n error ValidationResult(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo\\n );\\n\\n /**\\n * Successful result from simulateValidation, if the account returns a signature aggregator\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\\n * bundler MUST use it to verify the signature, or reject the UserOperation\\n */\\n error ValidationResultWithAggregation(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo,\\n AggregatorStakeInfo aggregatorInfo\\n );\\n\\n /**\\n * return value of getSenderAddress\\n */\\n error SenderAddressResult(address sender);\\n\\n /**\\n * return value of simulateHandleOp\\n */\\n error ExecutionResult(\\n uint256 preOpGas,\\n uint256 paid,\\n uint48 validAfter,\\n uint48 validUntil,\\n bool targetSuccess,\\n bytes targetResult\\n );\\n\\n //UserOps handled, per aggregator\\n struct UserOpsPerAggregator {\\n UserOperation[] userOps;\\n // aggregator address\\n IAggregator aggregator;\\n // aggregated signature\\n bytes signature;\\n }\\n\\n /**\\n * Execute a batch of UserOperation.\\n * no signature aggregator is used.\\n * if any account requires an aggregator (that is, it returned an aggregator when\\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\\n * @param ops the operations to execute\\n * @param beneficiary the address to receive the fees\\n */\\n function handleOps(\\n UserOperation[] calldata ops,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * Execute a batch of UserOperation with Aggregators\\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\\n * @param beneficiary the address to receive the fees\\n */\\n function handleAggregatedOps(\\n UserOpsPerAggregator[] calldata opsPerAggregator,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * generate a request Id - unique identifier for this request.\\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\\n */\\n function getUserOpHash(\\n UserOperation calldata userOp\\n ) external view returns (bytes32);\\n\\n /**\\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\\n * @param userOp the user operation to validate.\\n */\\n function simulateValidation(UserOperation calldata userOp) external;\\n\\n /**\\n * gas and return values during simulation\\n * @param preOpGas the gas used for validation (including preValidationGas)\\n * @param prefund the required prefund for this operation\\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\\n */\\n struct ReturnInfo {\\n uint256 preOpGas;\\n uint256 prefund;\\n bool sigFailed;\\n uint48 validAfter;\\n uint48 validUntil;\\n bytes paymasterContext;\\n }\\n\\n /**\\n * returned aggregated signature info.\\n * the aggregator returned by the account, and its current stake.\\n */\\n struct AggregatorStakeInfo {\\n address aggregator;\\n StakeInfo stakeInfo;\\n }\\n\\n /**\\n * Get counterfactual sender address.\\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\\n * this method always revert, and returns the address in SenderAddressResult error\\n * @param initCode the constructor code to be passed into the UserOperation.\\n */\\n function getSenderAddress(bytes memory initCode) external;\\n\\n /**\\n * simulate full execution of a UserOperation (including both validation and target execution)\\n * this method will always revert with \\\"ExecutionResult\\\".\\n * it performs full validation of the UserOperation, but ignores signature error.\\n * an optional target address is called after the userop succeeds, and its value is returned\\n * (before the entire call is reverted)\\n * Note that in order to collect the the success/failure of the target call, it must be executed\\n * with trace enabled to track the emitted events.\\n * @param op the UserOperation to simulate\\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\\n * are set to the return from that call.\\n * @param targetCallData callData to pass to target address\\n */\\n function simulateHandleOp(\\n UserOperation calldata op,\\n address target,\\n bytes calldata targetCallData\\n ) external;\\n}\\n\",\"keccak256\":\"0x9ccb1b188eda8bbf5f6c2d01bd83c3d8b2b04fcf745283051d31fe96d1d8e40f\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/INonceManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\ninterface INonceManager {\\n /**\\n * Return the next nonce for this sender.\\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\\n * But UserOp with different keys can come with arbitrary order.\\n *\\n * @param sender the account address\\n * @param key the high 192 bit of the nonce\\n * @return nonce a full nonce to pass for next UserOp with this sender.\\n */\\n function getNonce(\\n address sender,\\n uint192 key\\n ) external view returns (uint256 nonce);\\n\\n /**\\n * Manually increment the nonce of the sender.\\n * This method is exposed just for completeness..\\n * Account does NOT need to call it, neither during validation, nor elsewhere,\\n * as the EntryPoint will update the nonce regardless.\\n * Possible use-case is call it with various keys to \\\"initialize\\\" their nonces to one, so that future\\n * UserOperations will not pay extra for the first transaction with a given key.\\n */\\n function incrementNonce(uint192 key) external;\\n}\\n\",\"keccak256\":\"0xce478ad0fa0d18a3b785ac854623029e7ab463d05873dfaa365abfa1bf100912\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IStakeManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8.12;\\n\\n/**\\n * manage deposits and stakes.\\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\\n * stake is value locked for at least \\\"unstakeDelay\\\" by the staked entity.\\n */\\ninterface IStakeManager {\\n event Deposited(address indexed account, uint256 totalDeposit);\\n\\n event Withdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /// Emitted when stake or unstake delay are modified\\n event StakeLocked(\\n address indexed account,\\n uint256 totalStaked,\\n uint256 unstakeDelaySec\\n );\\n\\n /// Emitted once a stake is scheduled for withdrawal\\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\\n\\n event StakeWithdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /**\\n * @param deposit the entity's deposit\\n * @param staked true if this entity is staked.\\n * @param stake actual amount of ether staked for this entity.\\n * @param unstakeDelaySec minimum delay to withdraw the stake.\\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\\n * and the rest fit into a 2nd cell.\\n * 112 bit allows for 10^15 eth\\n * 48 bit for full timestamp\\n * 32 bit allows 150 years for unstake delay\\n */\\n struct DepositInfo {\\n uint112 deposit;\\n bool staked;\\n uint112 stake;\\n uint32 unstakeDelaySec;\\n uint48 withdrawTime;\\n }\\n\\n //API struct used by getStakeInfo and simulateValidation\\n struct StakeInfo {\\n uint256 stake;\\n uint256 unstakeDelaySec;\\n }\\n\\n /// @return info - full deposit information of given account\\n function getDepositInfo(\\n address account\\n ) external view returns (DepositInfo memory info);\\n\\n /// @return the deposit (for gas payment) of the account\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * add to the deposit of the given account\\n */\\n function depositTo(address account) external payable;\\n\\n /**\\n * add to the account's stake - amount and delay\\n * any pending unstake is first cancelled.\\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\\n */\\n function addStake(uint32 _unstakeDelaySec) external payable;\\n\\n /**\\n * attempt to unlock the stake.\\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\\n */\\n function unlockStake() external;\\n\\n /**\\n * withdraw from the (unlocked) stake.\\n * must first call unlockStake and wait for the unstakeDelay to pass\\n * @param withdrawAddress the address to send withdrawn value.\\n */\\n function withdrawStake(address payable withdrawAddress) external;\\n\\n /**\\n * withdraw from the deposit.\\n * @param withdrawAddress the address to send withdrawn value.\\n * @param withdrawAmount the amount to withdraw.\\n */\\n function withdrawTo(\\n address payable withdrawAddress,\\n uint256 withdrawAmount\\n ) external;\\n}\\n\",\"keccak256\":\"0xadcea606c9b7aafe6645441f2154a60f271330b0eee5292a632aa71c1672d546\",\"license\":\"GPL-3.0-only\"},\"contracts/aa-4337/interfaces/UserOperation.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable no-inline-assembly */\\n\\nimport {calldataKeccak} from \\\"../core/Helpers.sol\\\";\\n\\n/**\\n * User Operation struct\\n * @param sender the sender account of this request.\\n * @param nonce unique value the sender uses to verify it is not a replay.\\n * @param initCode if set, the account contract will be created by this constructor/\\n * @param callData the method call to execute on this account.\\n * @param callGasLimit the gas limit passed to the callData method call.\\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\\n * @param maxFeePerGas same as EIP-1559 gas parameter.\\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\\n */\\nstruct UserOperation {\\n address sender;\\n uint256 nonce;\\n bytes initCode;\\n bytes callData;\\n uint256 callGasLimit;\\n uint256 verificationGasLimit;\\n uint256 preVerificationGas;\\n uint256 maxFeePerGas;\\n uint256 maxPriorityFeePerGas;\\n bytes paymasterAndData;\\n bytes signature;\\n}\\n\\n/**\\n * Utility functions helpful when working with UserOperation structs.\\n */\\nlibrary UserOperationLib {\\n function getSender(\\n UserOperation calldata userOp\\n ) internal pure returns (address) {\\n address data;\\n //read sender from userOp, which is first userOp member (saves 800 gas...)\\n assembly {\\n data := calldataload(userOp)\\n }\\n return address(uint160(data));\\n }\\n\\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\\n // pay above what he signed for.\\n function gasPrice(\\n UserOperation calldata userOp\\n ) internal view returns (uint256) {\\n unchecked {\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n if (maxFeePerGas == maxPriorityFeePerGas) {\\n //legacy mode (for networks that don't support basefee opcode)\\n return maxFeePerGas;\\n }\\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\\n }\\n }\\n\\n function pack(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes memory ret) {\\n address sender = getSender(userOp);\\n uint256 nonce = userOp.nonce;\\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\\n bytes32 hashCallData = calldataKeccak(userOp.callData);\\n uint256 callGasLimit = userOp.callGasLimit;\\n uint256 verificationGasLimit = userOp.verificationGasLimit;\\n uint256 preVerificationGas = userOp.preVerificationGas;\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\\n\\n return\\n abi.encode(\\n sender,\\n nonce,\\n hashInitCode,\\n hashCallData,\\n callGasLimit,\\n verificationGasLimit,\\n preVerificationGas,\\n maxFeePerGas,\\n maxPriorityFeePerGas,\\n hashPaymasterAndData\\n );\\n }\\n\\n function hash(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes32) {\\n return keccak256(pack(userOp));\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n}\\n\",\"keccak256\":\"0x2429f5cc546bdee08c7e63858d0dda8491eaa3ab5194df884dc948c1154d2834\",\"license\":\"GPL-3.0\"},\"contracts/facets/Modifiers.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {LibGuardian} from \\\"../libraries/LibGuardian.sol\\\";\\nimport {BarzStorage} from \\\"../libraries/LibAppStorage.sol\\\";\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\n\\n/**\\n * @title Modifiers\\n * @dev Responsible for providing modifiers/util functions to Facet contracts\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\nabstract contract Modifiers is BarzStorage {\\n uint8 constant INNER_STRUCT = 0;\\n\\n error CallerNotGuardian();\\n error CallerNotGuardianOrOwner();\\n error DuplicateApprover();\\n error ZeroApproverLength();\\n error UnregisteredFacetAndSelectors();\\n\\n /**\\n * @notice Modifier to only allow guardian to make a call, reverts if any other entity is the caller\\n */\\n modifier onlyGuardian() {\\n if (!LibGuardian.isGuardian(msg.sender)) revert CallerNotGuardian();\\n _;\\n }\\n\\n /**\\n * @notice Modifier to only allow guardian or owner to make a call, reverts if any other entity is the caller\\n */\\n modifier onlyGuardianOrOwner() {\\n if (!LibGuardian.isGuardian(msg.sender) && address(this) != msg.sender)\\n revert CallerNotGuardianOrOwner();\\n _;\\n }\\n\\n /**\\n * @notice Checks if the approver address is the array is unique with no duplicate\\n * @dev This method loops through the array and checks if a duplicate address exists, it reverts if duplicate address exists\\n * @param approvers Array of address\\n */\\n function _checkApprover(\\n address[] memory approvers\\n ) internal pure returns (bool) {\\n uint256 approverLength = approvers.length;\\n if (0 == approverLength) revert ZeroApproverLength();\\n for (uint256 i; i < approverLength - 1; ) {\\n for (uint256 j = i + 1; j < approverLength; ) {\\n if (approvers[i] == approvers[j]) {\\n revert DuplicateApprover(); // Found a duplicate\\n }\\n unchecked {\\n ++j;\\n }\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n return false; // No duplicates found\\n }\\n\\n /**\\n * @notice Checks if the facet getting added or replaced is registered to facet registry\\n * @dev This method loops through the cut and checks if the facet getting added/replaced is registered to facet registry\\n * @param _diamondCut Array of FacetCut, data for diamondCut defined in EIP-2535\\n */\\n function _checkFacetCutValidity(\\n IDiamondCut.FacetCut[] memory _diamondCut\\n ) internal view {\\n uint256 diamondCutLength = _diamondCut.length;\\n for (uint256 i; i < diamondCutLength; ) {\\n if (\\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Add ||\\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Replace\\n ) {\\n if (\\n !s.facetRegistry.areFacetFunctionSelectorsRegistered(\\n _diamondCut[i].facetAddress,\\n _diamondCut[i].functionSelectors\\n )\\n ) revert UnregisteredFacetAndSelectors();\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb42956323d199bdec243a5f9859439aae057fbfdd1d79e3a96afc857ecb3115f\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/DiamondCutFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {LibDiamond} from \\\"../../libraries/LibDiamond.sol\\\";\\nimport {LibGuardian} from \\\"../../libraries/LibGuardian.sol\\\";\\nimport {ISecurityManager} from \\\"../../infrastructure/interfaces/ISecurityManager.sol\\\";\\nimport {SignatureChecker} from \\\"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\\\";\\nimport {LibFacetStorage, DiamondCutApprovalConfig, ApprovalConfig} from \\\"../../libraries/LibFacetStorage.sol\\\";\\nimport {Modifiers} from \\\"../Modifiers.sol\\\";\\nimport {IDiamondCut} from \\\"./interfaces/IDiamondCut.sol\\\";\\n\\n/**\\n * @title DiamondCut Facet\\n * @dev Responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract DiamondCutFacet is Modifiers, IDiamondCut {\\n ISecurityManager public immutable securityManager;\\n\\n /**\\n * @notice This constructor sets the Security Manager address which is an immutable variable.\\n * Immutable variables do not impact the storage of diamond\\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\\n */\\n constructor(address _securityManager) {\\n securityManager = ISecurityManager(_securityManager);\\n }\\n\\n /**\\n * @notice Updates the flag for the interfaceId\\n * @param _interfaceId InterfaceID to update the mapping\\n * @param _flag Bool value to update the mapping of the given interface ID\\n */\\n function updateSupportsInterface(\\n bytes4 _interfaceId,\\n bool _flag\\n ) external override onlyWhenUnlocked {\\n LibDiamond.enforceIsSelf();\\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId] = _flag;\\n emit SupportsInterfaceUpdated(_interfaceId, _flag);\\n }\\n\\n /**\\n * @notice Add/replace/remove any number of functions and optionally execute\\n * a function with delegatecall when guardians don't exist\\n * @param _diamondCut Contains the facet addresses and function selectors\\n * @param _init The address of the contract or facet to execute _calldata. It's prohibited in Barz\\n */\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata\\n ) external override onlyWhenUnlocked {\\n LibDiamond.enforceIsSelf();\\n\\n _checkFacetCutValidity(_diamondCut);\\n // require approval from guardian if guardian exists\\n if (0 != LibGuardian.guardianCount())\\n revert DiamondCutFacet__InvalidRouteWithGuardian();\\n if (address(0) != _init) revert DiamondCutFacet__InvalidInitAddress();\\n\\n unchecked {\\n ++LibFacetStorage.diamondCutStorage().nonce;\\n }\\n LibDiamond.diamondCut(_diamondCut, address(0), \\\"\\\");\\n }\\n\\n /**\\n * @notice Add/replace/remove any number of functions and optionally execute\\n * a function with delegatecall when guardians exist\\n * @param _diamondCut Contains the facet addresses and function selectors\\n * @param _approvers Guardian or owner address that approves the diamond cut\\n * @param _signatures Signature of Guardians or owner that approves the diamond cut\\n */\\n function diamondCutWithGuardian(\\n FacetCut[] calldata _diamondCut,\\n address[] calldata _approvers,\\n bytes[] calldata _signatures\\n ) external override onlyWhenUnlocked {\\n if (_approvers.length != _signatures.length)\\n revert DiamondCutFacet__InvalidArrayLength();\\n _checkFacetCutValidity(_diamondCut);\\n if (0 == LibGuardian.guardianCount())\\n revert DiamondCutFacet__InvalidRouteWithGuardian();\\n\\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\\n\\n _checkApprover(_approvers);\\n _checkDuplicateOnChainApprover(cutHash, _approvers);\\n\\n bool onChainOwnerApproval = getOwnerCutApprovalWithTimeValidity(\\n cutHash\\n );\\n\\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\\n if (\\n _approvers.length +\\n getDiamondCutApprovalCountWithTimeValidity(cutHash) <\\n LibGuardian.majorityOfGuardians() + threshold\\n ) revert DiamondCutFacet__InsufficientApprovers();\\n\\n bool ownerApproved;\\n for (uint256 i; i < _approvers.length; ) {\\n if (\\n !LibGuardian.isGuardian(_approvers[i]) &&\\n _approvers[i] != address(this)\\n ) revert DiamondCutFacet__InvalidApprover();\\n if (_approvers[i] == address(this)) {\\n if (onChainOwnerApproval)\\n revert DiamondCutFacet__OwnerAlreadyApproved();\\n ownerApproved = true;\\n }\\n if (\\n !SignatureChecker.isValidSignatureNow(\\n _approvers[i],\\n cutHash,\\n _signatures[i]\\n )\\n ) revert DiamondCutFacet__InvalidApproverSignature();\\n unchecked {\\n ++i;\\n }\\n }\\n if (!ownerApproved && !onChainOwnerApproval)\\n revert DiamondCutFacet__LackOfOwnerApproval();\\n\\n unchecked {\\n ++LibFacetStorage.diamondCutStorage().nonce;\\n }\\n LibDiamond.diamondCut(_diamondCut, address(0), \\\"\\\");\\n }\\n\\n /**\\n * @notice Approves diamond cut. This can only be called directly from guardian or owner\\n * @param _diamondCut Contains the facet addresses and function selectors\\n */\\n function approveDiamondCut(\\n FacetCut[] calldata _diamondCut\\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\\n if (LibGuardian.guardianCount() == 0)\\n revert DiamondCutFacet__InvalidRouteWithoutGuardian();\\n DiamondCutApprovalConfig storage ds = LibFacetStorage\\n .diamondCutStorage()\\n .diamondCutApprovalConfigs[INNER_STRUCT];\\n _checkFacetCutValidity(_diamondCut);\\n\\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\\n uint64 approvalValidUntil = uint64(\\n block.timestamp + getApprovalValidationPeriod()\\n );\\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(\\n true,\\n approvalValidUntil\\n );\\n emit DiamondCutApproved(_diamondCut);\\n if (\\n (getDiamondCutApprovalCountWithTimeValidity(cutHash) >=\\n LibGuardian.majorityOfGuardians()) &&\\n getOwnerCutApprovalWithTimeValidity(cutHash)\\n ) {\\n unchecked {\\n ++LibFacetStorage.diamondCutStorage().nonce;\\n }\\n LibDiamond.diamondCut(_diamondCut, address(0), \\\"\\\");\\n }\\n }\\n\\n /**\\n * @notice Revokes the approval of diamond cut. This can only be called directly from guardian or owner\\n * @param _diamondCut Contains the facet addresses and function selectors\\n */\\n function revokeDiamondCutApproval(\\n FacetCut[] calldata _diamondCut\\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\\n DiamondCutApprovalConfig storage ds = LibFacetStorage\\n .diamondCutStorage()\\n .diamondCutApprovalConfigs[INNER_STRUCT];\\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\\n if (!ds.isDiamondCutApproved[cutHash][msg.sender].isApproved)\\n revert DiamondCutFacet__CannotRevokeUnapproved();\\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(false, 0);\\n emit DiamondCutApprovalRevoked(_diamondCut);\\n }\\n\\n /**\\n * @notice Gets the number of approvals of diamond cut from guardians\\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\\n */\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 _diamondCutHash\\n ) public view override returns (uint256 approvalCount) {\\n address[] memory guardians = LibGuardian.getGuardians();\\n uint256 guardiansLength = guardians.length;\\n for (uint256 i; i < guardiansLength; ) {\\n if (isCutApproved(_diamondCutHash, guardians[i])) {\\n unchecked {\\n ++approvalCount;\\n }\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n return approvalCount;\\n }\\n\\n /**\\n * @notice Returns if the owner has approved the diamond cut\\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\\n * @return isApprovedByOwner Bool value showing if the owner approved the cut\\n */\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 _diamondCutHash\\n ) public view override returns (bool isApprovedByOwner) {\\n isApprovedByOwner = isCutApproved(_diamondCutHash, address(this));\\n }\\n\\n /**\\n * @notice Returns if the given approver has approved the diamond cut\\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\\n * @param _approver Address of approver\\n * @return isApproved Bool value showing if the approver approved the cut\\n */\\n function isCutApproved(\\n bytes32 _diamondCutHash,\\n address _approver\\n ) public view override returns (bool isApproved) {\\n DiamondCutApprovalConfig storage ds = LibFacetStorage\\n .diamondCutStorage()\\n .diamondCutApprovalConfigs[INNER_STRUCT];\\n isApproved = (ds\\n .isDiamondCutApproved[_diamondCutHash][_approver].isApproved &&\\n block.timestamp <\\n ds.isDiamondCutApproved[_diamondCutHash][_approver].validUntil);\\n }\\n\\n /**\\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\\n * Approvers who approved on-chain should not be included in the off-chain approval\\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\\n * @param _approvers List of approver addresses\\n */\\n function _checkDuplicateOnChainApprover(\\n bytes32 _diamondCutHash,\\n address[] memory _approvers\\n ) public view {\\n address[] memory guardians = LibGuardian.getGuardians();\\n uint256 guardianLength = guardians.length;\\n uint256 approversLength = _approvers.length;\\n for (uint256 i; i < guardianLength; ) {\\n if (isCutApproved(_diamondCutHash, guardians[i])) {\\n for (uint256 j; j < approversLength; ) {\\n if (_approvers[j] == guardians[i])\\n revert DiamondCutFacet__DuplicateApproval();\\n unchecked {\\n ++j;\\n }\\n }\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * @notice Returns the diamond cut hash. This function ensures that this hash is safe from replay attack by including\\n * salt, address, chainId, and nonce, etc.\\n * @param _diamondCut Contains the facet addresses and function selectors\\n * @return cutHash Diamond Cut Hash\\n */\\n function getDiamondCutHash(\\n FacetCut[] calldata _diamondCut\\n ) public view override returns (bytes32 cutHash) {\\n cutHash = keccak256(\\n abi.encodePacked(\\n \\\"\\\\x19Ethereum Signed Message:\\\\n32\\\",\\n keccak256(\\n abi.encode(\\n keccak256(abi.encode(_diamondCut)),\\n address(this),\\n block.chainid,\\n LibFacetStorage.diamondCutStorage().nonce\\n )\\n )\\n )\\n );\\n }\\n\\n /**\\n * @notice Returns the approval validation Period\\n * @dev This method fetches the validation period from the security manager\\n * @return approvalValidationPeriod Approval validation period of Barz contract fetched from security manager\\n */\\n function getApprovalValidationPeriod()\\n internal\\n view\\n returns (uint256 approvalValidationPeriod)\\n {\\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\\n address(this)\\n );\\n if (approvalValidationPeriod <= 0)\\n revert DiamondCutFacet__InvalidApprovalValidationPeriod();\\n }\\n\\n /**\\n * @notice Returns the diamond cut nonce of this wallet\\n * @dev This method fetches the nonce from diamond cut storage\\n * @return cutNonce Nonce of diamond cut to protect from reply attacks\\n */\\n function getDiamondCutNonce()\\n public\\n view\\n override\\n returns (uint128 cutNonce)\\n {\\n cutNonce = LibFacetStorage.diamondCutStorage().nonce;\\n }\\n}\\n\",\"keccak256\":\"0xe91a7dd2daabf2e989c94089f4f1eb0da94276c3070559ac8988838e10dd1f5d\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/infrastructure/interfaces/IFacetRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Registry Interface\\n * @dev Interface for Facet Registry contract to keep track of facets & function selectors addable to user wallets\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IFacetRegistry {\\n struct FacetRegistryConfig {\\n bytes4[] selectors;\\n mapping(bytes4 => FacetInfo) info;\\n }\\n struct FacetInfo {\\n bool exists;\\n uint128 index;\\n }\\n\\n event FacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] facetSelectors\\n );\\n event FacetFunctionSelectorsRemoved(address facet, bytes4[] facetSelectors);\\n\\n error FacetRegistry__FacetSelectorAlreadyRegistered();\\n error FacetRegistry__UnregisteredFacetSelector();\\n\\n function registerFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function removeFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function areFacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external view returns (bool);\\n\\n function isFacetFunctionSelectorRegistered(\\n address facet,\\n bytes4 facetSelector\\n ) external view returns (bool);\\n\\n function getFacetFunctionSelectors(\\n address facet\\n ) external view returns (bytes4[] memory);\\n}\\n\",\"keccak256\":\"0x6e6dd2cab346ef7c31230740ec48d2925e4a9ab24c2f2fb268baaf408dcf02ef\",\"license\":\"Apache-2.0\"},\"contracts/infrastructure/interfaces/ISecurityManager.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Registry Interface\\n * @dev Infrastructure contract to manage security parameters of users\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\ninterface ISecurityManager {\\n error SecurityManager__OutOfBoundary();\\n error SecurityManager__CallerNotWallet();\\n error SecurityManager__AlreadyIntialized();\\n\\n function initializeAdditionSecurityPeriod(\\n uint128 defaultAdditionSecurityPeriod,\\n uint128 minAdditionSecurityPeriod,\\n uint128 maxAdditionSecurityPeriod\\n ) external;\\n\\n function initializeRemovalSecurityPeriod(\\n uint128 defaultRemovalSecurityPeriod,\\n uint128 minRemovalSecurityPeriod,\\n uint128 maxRemovalSecurityPeriod\\n ) external;\\n\\n function initializeApprovalValidationPeriod(\\n uint128 defaultApprovalValidationPeriod,\\n uint128 minApprovalValidationPeriod,\\n uint128 maxApprovalValidationPeriod\\n ) external;\\n\\n function initializeMigrationPeriod(\\n uint128 defaultMigrationPeriod,\\n uint128 minMigrationPeriod,\\n uint128 maxMigrationPeriod\\n ) external;\\n\\n function initializeLockPeriod(\\n uint128 defaultLockPeriod,\\n uint128 minLockPeriod,\\n uint128 maxLockPeriod\\n ) external;\\n\\n function initializeRecoveryPeriod(\\n uint128 defaultRecoveryPeriod,\\n uint128 minRecoveryPeriod,\\n uint128 maxRecoveryPeriod\\n ) external;\\n\\n function initializeSecurityWindow(\\n uint128 defaultSecurityWindow,\\n uint128 minSecurityWindow,\\n uint128 maxSecurityWindow\\n ) external;\\n\\n function setAdditionSecurityPeriod(\\n address wallet,\\n uint128 additionSecurityPeriod\\n ) external;\\n\\n function setRemovalSecurityPeriod(\\n address wallet,\\n uint128 removalSecurityPeriod\\n ) external;\\n\\n function setSecurityWindow(address wallet, uint128 securityWindow) external;\\n\\n function setRecoveryPeriod(address wallet, uint128 recoveryPeriod) external;\\n\\n function setLockPeriod(address wallet, uint128 lockPeriod) external;\\n\\n function setApprovalValidationPeriod(\\n address wallet,\\n uint128 approvalValidationPeriod\\n ) external;\\n\\n function setMigrationPeriod(\\n address wallet,\\n uint128 migrationPeriod\\n ) external;\\n\\n function additionSecurityPeriodOf(\\n address wallet\\n ) external view returns (uint128);\\n\\n function removalSecurityPeriodOf(\\n address wallet\\n ) external view returns (uint128);\\n\\n function securityWindowOf(address wallet) external view returns (uint128);\\n\\n function recoveryPeriodOf(address wallet) external view returns (uint128);\\n\\n function lockPeriodOf(address wallet) external view returns (uint128);\\n\\n function migrationPeriodOf(address wallet) external view returns (uint128);\\n\\n function approvalValidationPeriodOf(\\n address wallet\\n ) external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x9ac6566033ef81ba5744c8ed2b08f130b781b498ab9245bcca87567669549552\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibAppStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {SafeCast} from \\\"@openzeppelin/contracts/utils/math/SafeCast.sol\\\";\\nimport {IEntryPoint} from \\\"../aa-4337/interfaces/IEntryPoint.sol\\\";\\nimport {IFacetRegistry} from \\\"../infrastructure/interfaces/IFacetRegistry.sol\\\";\\n\\n/*\\n * @title App Storage\\n * @dev App storage for Barz contract to prevent storage collision\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Lock {\\n uint64 release;\\n bytes4 locker;\\n}\\n\\nstruct InitializersStorage {\\n // NOTE: initialized is a variable to make sure the initialization is only done once.\\n uint8 signerInitialized;\\n uint8 accountInitialized;\\n uint8 restrictionsInitialized;\\n}\\n\\nstruct AppStorage {\\n mapping(uint256 => InitializersStorage) initStorage;\\n uint8 signerMigration;\\n bytes4 validateOwnerSignatureSelector;\\n IEntryPoint entryPoint;\\n IFacetRegistry facetRegistry;\\n mapping(uint256 => Lock) locks;\\n}\\n\\nlibrary LibAppStorage {\\n error LibAppStorage__AccountAlreadyUninitialized();\\n error LibAppStorage__AccountMustBeUninitialized();\\n error LibAppStorage__SignerAlreadyUninitialized();\\n error LibAppStorage__SignerMustBeUninitialized();\\n\\n function appStorage() internal pure returns (AppStorage storage ds) {\\n assembly {\\n ds.slot := 0\\n }\\n }\\n\\n function setSignerUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerAlreadyUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 0;\\n }\\n\\n function getValidateOwnerSignatureSelector()\\n internal\\n view\\n returns (bytes4 selector)\\n {\\n selector = appStorage().validateOwnerSignatureSelector;\\n }\\n\\n function setValidateOwnerSignatureSelector(\\n bytes4 _validateOwnerSignatureSelector\\n ) internal {\\n appStorage()\\n .validateOwnerSignatureSelector = _validateOwnerSignatureSelector;\\n }\\n\\n function enforceSignerInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerMustBeUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 1;\\n }\\n\\n function enforceAccountInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].accountInitialized) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n s.initStorage[0].accountInitialized = 1;\\n }\\n\\n function initiateSignerMigration() internal {\\n appStorage().signerMigration = 1;\\n }\\n\\n function enforceSignerMigration() internal view {\\n if (1 != appStorage().signerMigration) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n }\\n\\n function finalizeSignerMigration() internal {\\n appStorage().signerMigration = 0;\\n }\\n\\n function setLock(uint256 _releaseAfter, bytes4 _locker) internal {\\n appStorage().locks[0] = Lock(SafeCast.toUint64(_releaseAfter), _locker);\\n }\\n\\n function enforceRestrictionsInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__SignerMustBeUninitialized();\\n s.initStorage[0].restrictionsInitialized = 1;\\n }\\n\\n function setRestrictionsUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__AccountAlreadyUninitialized();\\n s.initStorage[0].restrictionsInitialized = 0;\\n }\\n}\\n\\ncontract BarzStorage {\\n AppStorage internal s;\\n modifier onlyWhenUnlocked() {\\n require(\\n uint64(block.timestamp) >= s.locks[0].release,\\n \\\"Account Locked\\\"\\n );\\n _;\\n }\\n modifier onlyWhenLocked() {\\n require(\\n uint64(block.timestamp) < s.locks[0].release,\\n \\\"Account Unlocked\\\"\\n );\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x48524007862a6ce0e07f645950613ce6513ce073c37a109c75019683d42bae27\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\\n bytes4(keccak256(\\\"verifyRestrictions(address,address,uint256,bytes)\\\"));\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // Default Fallback Handler of the barz.\\n IDiamondLoupe defaultFallbackHandler;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function enforceIsSelf() internal view {\\n require(msg.sender == address(this), \\\"LibDiamond: Caller not self\\\");\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n\\n unchecked {\\n facetIndex++;\\n }\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n\\n function restrictionsFacet() internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(\\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2cabdc00de859c3a3170ce3bda5d0e5fd3933d47ce904fd1585f9818b02572f8\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibFacetStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Storage\\n * @dev Storage contract to store each facets variables with diamond storage\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Secp256k1VerificationStorage {\\n address signer;\\n}\\n\\nstruct Secp256r1VerificationStorage {\\n uint256[2] q;\\n}\\n\\nstruct GuardianStorage {\\n mapping(bytes32 => uint256) pending;\\n mapping(uint8 => StorageConfig) configs;\\n}\\n\\nstruct Info {\\n bool exists;\\n uint128 index;\\n}\\n\\nstruct StorageConfig {\\n address[] addresses;\\n mapping(address => Info) info;\\n}\\n\\nstruct RecoveryConfig {\\n bytes recoveryPublicKey;\\n uint64 executeAfter;\\n}\\n\\nstruct ApprovalConfig {\\n bool isApproved;\\n uint64 validUntil;\\n}\\n\\nstruct RecoveryApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isNewOwnerApproved;\\n}\\n\\nstruct RecoveryStorage {\\n mapping(uint8 => RecoveryConfig) recoveryConfigs;\\n mapping(uint8 => RecoveryApprovalConfig) recoveryApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct RestrictionsStorage {\\n address[] restrictions;\\n mapping(address => bool) exists;\\n}\\n\\nstruct SignatureMigrationConfig {\\n bytes migrationPublicKey;\\n address migrationVerificationFacet;\\n bytes4[] migrationSelectors;\\n uint64 migrateAfter;\\n}\\n\\nstruct SignatureMigrationApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isMigrationApproved;\\n}\\n\\nstruct SignatureMigrationStorage {\\n mapping(uint8 => SignatureMigrationConfig) migrationConfigs;\\n mapping(uint8 => SignatureMigrationApprovalConfig) migrationApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct DiamondCutApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isDiamondCutApproved;\\n}\\n\\nstruct DiamondCutStorage {\\n mapping(uint8 => DiamondCutApprovalConfig) diamondCutApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct LockStorage {\\n uint128 nonce;\\n}\\n\\nlibrary LibFacetStorage {\\n bytes32 constant K1_STORAGE_POSITION =\\n keccak256(\\n \\\"v0.trustwallet.diamond.storage.Secp256k1VerificationStorage\\\"\\n );\\n bytes32 constant R1_STORAGE_POSITION =\\n keccak256(\\n \\\"v0.trustwallet.diamond.storage.Secp256r1VerificationStorage\\\"\\n );\\n bytes32 constant GUARDIAN_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.GuardianStorage\\\");\\n bytes32 constant RECOVERY_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.RecoveryStorage\\\");\\n bytes32 constant RESTRICTION_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.RestrictionsStorage\\\");\\n bytes32 constant MIGRATION_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.SignatureMigrationStorage\\\");\\n bytes32 constant DIAMONDCUT_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.DiamondCutStorage\\\");\\n bytes32 constant LOCK_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.LockStorage\\\");\\n\\n function k1Storage()\\n internal\\n pure\\n returns (Secp256k1VerificationStorage storage ds)\\n {\\n bytes32 storagePosition = K1_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function r1Storage()\\n internal\\n pure\\n returns (Secp256r1VerificationStorage storage ds)\\n {\\n bytes32 storagePosition = R1_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function guardianStorage()\\n internal\\n pure\\n returns (GuardianStorage storage ds)\\n {\\n bytes32 storagePosition = GUARDIAN_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function recoveryStorage()\\n internal\\n pure\\n returns (RecoveryStorage storage ds)\\n {\\n bytes32 storagePosition = RECOVERY_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function restrictionsStorage()\\n internal\\n pure\\n returns (RestrictionsStorage storage ds)\\n {\\n bytes32 storagePosition = RESTRICTION_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function migrationStorage()\\n internal\\n pure\\n returns (SignatureMigrationStorage storage ds)\\n {\\n bytes32 storagePosition = MIGRATION_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function diamondCutStorage()\\n internal\\n pure\\n returns (DiamondCutStorage storage ds)\\n {\\n bytes32 storagePosition = DIAMONDCUT_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function lockStorage() internal pure returns (LockStorage storage ds) {\\n bytes32 storagePosition = LOCK_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n}\\n\",\"keccak256\":\"0x87c85decfd943deda9540733e464cb1a92eba735a301e89ce6f798016e359761\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibGuardian.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {LibFacetStorage, StorageConfig} from \\\"./LibFacetStorage.sol\\\";\\n\\n/**\\n * @title LibGuardian\\n * @dev Internal Library to provide utility feature for Guardians stored in Guardian Facet Storage\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\nlibrary LibGuardian {\\n function majorityOfGuardians()\\n internal\\n view\\n returns (uint256 guardianNumber)\\n {\\n uint256 guardianLength = guardianCount();\\n guardianNumber = (guardianLength == 0) ? 0 : guardianLength / 2 + 1;\\n }\\n\\n function isGuardian(address _guardian) internal view returns (bool) {\\n StorageConfig storage config = LibFacetStorage\\n .guardianStorage()\\n .configs[0];\\n return config.info[_guardian].exists;\\n }\\n\\n function guardianCount() internal view returns (uint256) {\\n StorageConfig storage config = LibFacetStorage\\n .guardianStorage()\\n .configs[0];\\n return config.addresses.length;\\n }\\n\\n function getGuardians() internal view returns (address[] memory) {\\n StorageConfig storage config = LibFacetStorage\\n .guardianStorage()\\n .configs[0];\\n address[] memory addresses = new address[](config.addresses.length);\\n uint256 addressesLen = config.addresses.length;\\n for (uint256 i; i < addressesLen; ) {\\n addresses[i] = config.addresses[i];\\n unchecked {\\n ++i;\\n }\\n }\\n return addresses;\\n }\\n}\\n\",\"keccak256\":\"0x6a620992d5535878fc03d1a27a6675f4c1509adfb3ddbbca1c52b546c25392dc\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x60a06040523480156200001157600080fd5b506040516200379b3803806200379b833981016040819052620000349162000046565b6001600160a01b031660805262000078565b6000602082840312156200005957600080fd5b81516001600160a01b03811681146200007157600080fd5b9392505050565b6080516137006200009b600039600081816101f10152611b2501526137006000f3fe608060405234801561001057600080fd5b50600436106100d45760003560e01c806379c0d58d11610081578063afb877bb1161005b578063afb877bb146101d9578063de675a6d146101ec578063e33ecf0a1461023857600080fd5b806379c0d58d14610192578063836d6bfb146101b35780638824a0bb146101c657600080fd5b806326fc3ef4116100b257806326fc3ef4146101145780632f4d98ea1461015c5780633c0985681461017f57600080fd5b806313c34f4b146100d95780631c776dd5146100ee5780631f931c1c14610101575b600080fd5b6100ec6100e7366004612a97565b61024b565b005b6100ec6100fc366004612ad9565b6104df565b6100ec61010f366004612b9c565b610a76565b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9bf546040516fffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b61016f61016a366004612c4a565b610c7b565b6040519015158152602001610153565b6100ec61018d366004612ca4565b610c8d565b6101a56101a0366004612c4a565b610df2565b604051908152602001610153565b61016f6101c1366004612cdb565b610e4c565b6100ec6101d4366004612dd2565b610eed565b6100ec6101e7366004612a97565b610fe1565b6102137f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610153565b6101a5610246366004612a97565b61130e565b3360009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff1615801561028a5750303314155b156102c1576040517f6238ee3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610369576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064015b60405180910390fd5b60008080527f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be6020527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d3906103be848461130e565b60008181526020848152604080832033845290915290205490915060ff16610412576040517fedc5708300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051808201825260008082526020808301828152858352868252848320338452909152908390209151825491517fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000009092169015157fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff161761010067ffffffffffffffff90921691909102179055517f3c3d8c1f0b0faff6fe0ace6b485d0595a0106dce9e303f956fd941ebdbe9a98e906104d19086908690612f54565b60405180910390a150505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610582576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b8281146105bb576040517fe854148500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6105cd6105c886886130aa565b611435565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b754600003610650576040517fa788861700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061065c878761130e565b905061069a8585808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506115b392505050565b506106d881868680806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250610eed92505050565b60006106e382610c7b565b90506000816106f35760016106f6565b60005b60ff169050806107046116d0565b61070e9190613201565b61071784610df2565b6107219088613201565b1015610759576040517f709fb08000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805b878110156109a0576107d989898381811061077a5761077a613214565b905060200201602081019061078f9190613243565b73ffffffffffffffffffffffffffffffffffffffff1660009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff1690565b1580156108225750308989838181106107f4576107f4613214565b90506020020160208101906108099190613243565b73ffffffffffffffffffffffffffffffffffffffff1614155b15610859576040517f7b2cbbb400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3089898381811061086c5761086c613214565b90506020020160208101906108819190613243565b73ffffffffffffffffffffffffffffffffffffffff16036108d95783156108d4576040517fee21708000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600191505b6109628989838181106108ee576108ee613214565b90506020020160208101906109039190613243565b8689898581811061091657610916613214565b90506020028101906109289190613265565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061174f92505050565b610998576040517fac3d341600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60010161075d565b50801580156109ad575082155b156109e4576040517f6d21730400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9bf80546fffffffffffffffffffffffffffffffff808216600101167fffffffffffffffffffffffffffffffff00000000000000000000000000000000909116179055610a6a610a538a8c6130aa565b6000604051806020016040528060008152506117ca565b50505050505050505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610b19576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b610b2161195f565b610b2e6105c885876130aa565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75415610baf576040517fa788861700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff831615610bfd576040517f871cb76100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be5b600190810180547fffffffffffffffffffffffffffffffff0000000000000000000000000000000081166fffffffffffffffffffffffffffffffff91821690930116919091179055610c74610a5385876130aa565b5050505050565b6000610c878230610e4c565b92915050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610d30576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b610d3861195f565b7fffffffff00000000000000000000000000000000000000000000000000000000821660008181527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4922602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001685151590811790915582519384529083015280517f4e6bd17989efa6d6a9607ccaac1bba27b29f99622bc830d99a3a9883b21a19c79281900390910190a15050565b600080610dfd6119ca565b805190915060005b81811015610e4457610e3085848381518110610e2357610e23613214565b6020026020010151610e4c565b15610e3c578360010193505b600101610e05565b505050919050565b60008281527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d36020818152604080842073ffffffffffffffffffffffffffffffffffffffff8616855290915282205460ff168015610ee5575060008481526020828152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152902054610100900467ffffffffffffffff1642105b949350505050565b6000610ef76119ca565b805183519192509060005b82811015610fd957610f2086858381518110610e2357610e23613214565b15610fd15760005b82811015610fcf57848281518110610f4257610f42613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16868281518110610f7257610f72613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603610fc7576040517f50f5729f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600101610f28565b505b600101610f02565b505050505050565b3360009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff161580156110205750303314155b15611057576040517f6238ee3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff9081164290911610156110fa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75460000361117d576040517f3a76e1f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080527f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be6020527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d36111d36105c883856130aa565b60006111df848461130e565b905060006111eb611af4565b6111f59042613201565b6040805180820182526001815267ffffffffffffffff838116602080840191825260008881528982528581203382529091528490209251835491517fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000009092169015157fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff16176101009190921602179055519091507f6248ff757895beed7d43d135bccf59a26b7fbdf0fe8233487c44e82c0f266ba3906112b89087908790612f54565b60405180910390a16112c86116d0565b6112d183610df2565b101580156112e357506112e382610c7b565b15610c74577f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be610c1f565b60008282604051602001611323929190612f54565b6040516020818303038152906040528051906020012030466113627f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be90565b6001015460408051602081019590955273ffffffffffffffffffffffffffffffffffffffff9093169284019290925260608301526fffffffffffffffffffffffffffffffff16608082015260a001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905280516020918201207f19457468657265756d205369676e6564204d6573736167653a0a33320000000091830191909152603c820152605c0160405160208183030381529060405280519060200120905092915050565b805160005b818110156115ae57600083828151811061145657611456613214565b602002602001015160200151600281111561147357611473612e8a565b14806114ad5750600183828151811061148e5761148e613214565b60200260200101516020015160028111156114ab576114ab612e8a565b145b156115a657600254835173ffffffffffffffffffffffffffffffffffffffff9091169063df871f72908590849081106114e8576114e8613214565b60200260200101516000015185848151811061150657611506613214565b6020026020010151604001516040518363ffffffff1660e01b815260040161152f92919061331c565b602060405180830381865afa15801561154c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611570919061334b565b6115a6576040517ff41a931c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60010161143a565b505050565b80516000908082036115f1576040517f3aee2eec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b6115ff600183613368565b8110156116c6576000611613826001613201565b90505b828110156116bd5784818151811061163057611630613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1685838151811061166057611660613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16036116b5576040517f8dd19e7d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600101611616565b506001016115f4565b5060009392505050565b600080611723600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75490565b905080156117465761173660028261337b565b611741906001613201565b611749565b60005b91505090565b600080600061175e8585611bf6565b9092509050600081600481111561177757611777612e8a565b1480156117af57508573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b806117c057506117c0868686611c3b565b9695505050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921547f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff8116908190600090600716156118395750600381901c60009081526001840160205260409020545b60005b87518110156118b6576118a983838a848151811061185c5761185c613214565b6020026020010151600001518b858151811061187a5761187a613214565b6020026020010151602001518c868151811061189857611898613214565b602002602001015160400151611d98565b909350915060010161183c565b508282146118ef576002840180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff84161790555b600782161561191157600382901c600090815260018501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb67387878760405161194493929190613424565b60405180910390a16119568686612829565b50505050505050565b3330146119c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4c69624469616d6f6e643a2043616c6c6572206e6f742073656c6600000000006044820152606401610360565b565b60008080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b780546060929067ffffffffffffffff811115611a3257611a32612d07565b604051908082528060200260200182016040528015611a5b578160200160208202803683370190505b50825490915060005b81811015611aeb57836000018181548110611a8157611a81613214565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16838281518110611abe57611abe613214565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101611a64565b50909392505050565b6040517f52430c8d0000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906352430c8d90602401602060405180830381865afa158015611b81573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ba59190613510565b6fffffffffffffffffffffffffffffffff16905060008111611bf3576040517fdac5ec8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b90565b6000808251604103611c2c5760208301516040840151606085015160001a611c2087828585612928565b94509450505050611c34565b506000905060025b9250929050565b60008060008573ffffffffffffffffffffffffffffffffffffffff16631626ba7e60e01b8686604051602401611c72929190613542565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909416939093179092529051611cfb919061355b565b600060405180830381855afa9150503d8060008114611d36576040519150601f19603f3d011682016040523d82523d6000602084013e611d3b565b606091505b5091509150818015611d4f57506020815110155b80156117c0575080517f1626ba7e0000000000000000000000000000000000000000000000000000000090611d8d9083016020908101908401613577565b149695505050505050565b600080807f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f90506000845111611e50576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610360565b6000856002811115611e6457611e64612e8a565b0361203457611e8b8660405180606001604052806024815260200161365760249139612a17565b60005b845181101561202e576000858281518110611eab57611eab613214565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c15611f7e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c72656164792065786973747300000000000000000000006064820152608401610360565b7fffffffff0000000000000000000000000000000000000000000000000000000080831660008181526020879052604090207fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608d901b168e17905560e060058e901b811692831c199c909c1690821c179a8190036120125760038c901c600090815260018601602052604081209b909b555b8b61201c81613590565b9c505060019093019250611e8e915050565b5061281d565b600185600281111561204857612048612e8a565b036123385761206f866040518060600160405280602881526020016136a360289139612a17565b60005b845181101561202e57600085828151811061208f5761208f613214565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c308103612164576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4c69624469616d6f6e644375743a2043616e2774207265706c61636520696d6d60448201527f757461626c652066756e6374696f6e00000000000000000000000000000000006064820152608401610360565b8973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361221f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e00000000000000006064820152608401610360565b73ffffffffffffffffffffffffffffffffffffffff81166122c2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e207468617420646f65736e277420657869737400000000000000006064820152608401610360565b507fffffffff0000000000000000000000000000000000000000000000000000000090911660009081526020849052604090206bffffffffffffffffffffffff919091167fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608a901b16179055600101612072565b600285600281111561234c5761234c612e8a565b036127955773ffffffffffffffffffffffffffffffffffffffff8616156123f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d7573742062652061646472657373283029000000000000000000006064820152608401610360565b600388901c6007891660005b86518110156127755760008a900361243d578261241d816135c8565b60008181526001870160205260409020549b5093506007925061244b9050565b81612447816135c8565b9250505b6000806000808a858151811061246357612463613214565b6020908102919091018101517fffffffff0000000000000000000000000000000000000000000000000000000081166000908152918a9052604090912054909150606081901c612535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608401610360565b30606082901c036125c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e0000000000000000000000000000000000006064820152608401610360565b600587901b8f901b94507fffffffff0000000000000000000000000000000000000000000000000000000080861690831614612666577fffffffff000000000000000000000000000000000000000000000000000000008516600090815260208a90526040902080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff83161790555b7fffffffff0000000000000000000000000000000000000000000000000000000091909116600090815260208990526040812055600381901c611fff16925060051b60e01690508582146126fb576000828152600188016020526040902080547fffffffff0000000000000000000000000000000000000000000000000000000080841c19909116908516831c17905561274c565b80837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c817fffffffff0000000000000000000000000000000000000000000000000000000060001b901c198e16179c505b8460000361276a57600086815260018801602052604081208190559c505b505050600101612401565b50806127828360086135fd565b61278c9190613201565b9950505061281d565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560448201527f74416374696f6e000000000000000000000000000000000000000000000000006064820152608401610360565b50959694955050505050565b73ffffffffffffffffffffffffffffffffffffffff8216612848575050565b61286a8260405180606001604052806028815260200161367b60289139612a17565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051612892919061355b565b600060405180830381855af49150503d80600081146128cd576040519150601f19603f3d011682016040523d82523d6000602084013e6128d2565b606091505b509150915081612922578051156128ec5780518082602001fd5b83836040517f192105d7000000000000000000000000000000000000000000000000000000008152600401610360929190613614565b50505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561295f5750600090506003612a0e565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156129b3573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116612a0757600060019250925050612a0e565b9150600090505b94509492505050565b813b8181612922576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103609190613643565b60008083601f840112612a6457600080fd5b50813567ffffffffffffffff811115612a7c57600080fd5b6020830191508360208260051b8501011115611c3457600080fd5b60008060208385031215612aaa57600080fd5b823567ffffffffffffffff811115612ac157600080fd5b612acd85828601612a52565b90969095509350505050565b60008060008060008060608789031215612af257600080fd5b863567ffffffffffffffff80821115612b0a57600080fd5b612b168a838b01612a52565b90985096506020890135915080821115612b2f57600080fd5b612b3b8a838b01612a52565b90965094506040890135915080821115612b5457600080fd5b50612b6189828a01612a52565b979a9699509497509295939492505050565b803573ffffffffffffffffffffffffffffffffffffffff81168114612b9757600080fd5b919050565b600080600080600060608688031215612bb457600080fd5b853567ffffffffffffffff80821115612bcc57600080fd5b612bd889838a01612a52565b9097509550859150612bec60208901612b73565b94506040880135915080821115612c0257600080fd5b818801915088601f830112612c1657600080fd5b813581811115612c2557600080fd5b896020828501011115612c3757600080fd5b9699959850939650602001949392505050565b600060208284031215612c5c57600080fd5b5035919050565b80357fffffffff0000000000000000000000000000000000000000000000000000000081168114612b9757600080fd5b8015158114612ca157600080fd5b50565b60008060408385031215612cb757600080fd5b612cc083612c63565b91506020830135612cd081612c93565b809150509250929050565b60008060408385031215612cee57600080fd5b82359150612cfe60208401612b73565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff81118282101715612d5957612d59612d07565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715612da657612da6612d07565b604052919050565b600067ffffffffffffffff821115612dc857612dc8612d07565b5060051b60200190565b60008060408385031215612de557600080fd5b8235915060208084013567ffffffffffffffff811115612e0457600080fd5b8401601f81018613612e1557600080fd5b8035612e28612e2382612dae565b612d5f565b81815260059190911b82018301908381019088831115612e4757600080fd5b928401925b82841015612e6c57612e5d84612b73565b82529284019290840190612e4c565b80955050505050509250929050565b803560038110612b9757600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60038110612ef0577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b8183526000602080850194508260005b85811015612f49577fffffffff00000000000000000000000000000000000000000000000000000000612f3683612c63565b1687529582019590820190600101612f04565b509495945050505050565b60208082528181018390526000906040808401600586811b8601830188865b8981101561309b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc089840301855281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa18c3603018112612fd457600080fd5b8b01606073ffffffffffffffffffffffffffffffffffffffff612ff683612b73565b168552613004898301612e7b565b6130108a870182612eb9565b50878201357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe183360301811261304557600080fd5b90910188810191903567ffffffffffffffff81111561306357600080fd5b80871b360383131561307457600080fd5b81898701526130868287018285612ef4565b978a0197955050509187019150600101612f73565b50909998505050505050505050565b60006130b8612e2384612dae565b83815260208082019190600586811b8601368111156130d657600080fd5b865b818110156131c557803567ffffffffffffffff808211156130f95760008081fd5b818a0191506060823603121561310f5760008081fd5b613117612d36565b61312083612b73565b815261312d878401612e7b565b87820152604080840135838111156131455760008081fd5b939093019236601f85011261315c57600092508283fd5b8335925061316c612e2384612dae565b83815292871b840188019288810190368511156131895760008081fd5b948901945b848610156131ae5761319f86612c63565b8252948901949089019061318e565b9183019190915250885250509483019483016130d8565b5092979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610c8757610c876131d2565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561325557600080fd5b61325e82612b73565b9392505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261329a57600080fd5b83018035915067ffffffffffffffff8211156132b557600080fd5b602001915036819003821315611c3457600080fd5b600081518084526020808501945080840160005b83811015612f495781517fffffffff0000000000000000000000000000000000000000000000000000000016875295820195908201906001016132de565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000610ee560408301846132ca565b60006020828403121561335d57600080fd5b815161325e81612c93565b81810381811115610c8757610c876131d2565b6000826133b1577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60005b838110156133d15781810151838201526020016133b9565b50506000910152565b600081518084526133f28160208601602086016133b6565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6000606080830181845280875180835260808601915060808160051b87010192506020808a0160005b838110156134d4577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80898703018552815173ffffffffffffffffffffffffffffffffffffffff8151168752838101516134a885890182612eb9565b506040908101519087018890526134c1878901826132ca565b965050938201939082019060010161344d565b505073ffffffffffffffffffffffffffffffffffffffff8916908701525050838103604085015261350581866133da565b979650505050505050565b60006020828403121561352257600080fd5b81516fffffffffffffffffffffffffffffffff8116811461325e57600080fd5b828152604060208201526000610ee560408301846133da565b6000825161356d8184602087016133b6565b9190910192915050565b60006020828403121561358957600080fd5b5051919050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036135c1576135c16131d2565b5060010190565b6000816135d7576135d76131d2565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b8082028115828204841417610c8757610c876131d2565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000610ee560408301846133da565b60208152600061325e60208301846133da56fe4c69624469616d6f6e644375743a2041646420666163657420686173206e6f20636f64654c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a205265706c61636520666163657420686173206e6f20636f6465a2646970667358221220c5a8c10b22f20cde3fe0431ff57305237423677a60888f5b349fc6751336ae1464736f6c63430008150033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100d45760003560e01c806379c0d58d11610081578063afb877bb1161005b578063afb877bb146101d9578063de675a6d146101ec578063e33ecf0a1461023857600080fd5b806379c0d58d14610192578063836d6bfb146101b35780638824a0bb146101c657600080fd5b806326fc3ef4116100b257806326fc3ef4146101145780632f4d98ea1461015c5780633c0985681461017f57600080fd5b806313c34f4b146100d95780631c776dd5146100ee5780631f931c1c14610101575b600080fd5b6100ec6100e7366004612a97565b61024b565b005b6100ec6100fc366004612ad9565b6104df565b6100ec61010f366004612b9c565b610a76565b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9bf546040516fffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b61016f61016a366004612c4a565b610c7b565b6040519015158152602001610153565b6100ec61018d366004612ca4565b610c8d565b6101a56101a0366004612c4a565b610df2565b604051908152602001610153565b61016f6101c1366004612cdb565b610e4c565b6100ec6101d4366004612dd2565b610eed565b6100ec6101e7366004612a97565b610fe1565b6102137f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610153565b6101a5610246366004612a97565b61130e565b3360009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff1615801561028a5750303314155b156102c1576040517f6238ee3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610369576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064015b60405180910390fd5b60008080527f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be6020527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d3906103be848461130e565b60008181526020848152604080832033845290915290205490915060ff16610412576040517fedc5708300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051808201825260008082526020808301828152858352868252848320338452909152908390209151825491517fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000009092169015157fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff161761010067ffffffffffffffff90921691909102179055517f3c3d8c1f0b0faff6fe0ace6b485d0595a0106dce9e303f956fd941ebdbe9a98e906104d19086908690612f54565b60405180910390a150505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610582576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b8281146105bb576040517fe854148500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6105cd6105c886886130aa565b611435565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b754600003610650576040517fa788861700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061065c878761130e565b905061069a8585808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506115b392505050565b506106d881868680806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250610eed92505050565b60006106e382610c7b565b90506000816106f35760016106f6565b60005b60ff169050806107046116d0565b61070e9190613201565b61071784610df2565b6107219088613201565b1015610759576040517f709fb08000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805b878110156109a0576107d989898381811061077a5761077a613214565b905060200201602081019061078f9190613243565b73ffffffffffffffffffffffffffffffffffffffff1660009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff1690565b1580156108225750308989838181106107f4576107f4613214565b90506020020160208101906108099190613243565b73ffffffffffffffffffffffffffffffffffffffff1614155b15610859576040517f7b2cbbb400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3089898381811061086c5761086c613214565b90506020020160208101906108819190613243565b73ffffffffffffffffffffffffffffffffffffffff16036108d95783156108d4576040517fee21708000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600191505b6109628989838181106108ee576108ee613214565b90506020020160208101906109039190613243565b8689898581811061091657610916613214565b90506020028101906109289190613265565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061174f92505050565b610998576040517fac3d341600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60010161075d565b50801580156109ad575082155b156109e4576040517f6d21730400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9bf80546fffffffffffffffffffffffffffffffff808216600101167fffffffffffffffffffffffffffffffff00000000000000000000000000000000909116179055610a6a610a538a8c6130aa565b6000604051806020016040528060008152506117ca565b50505050505050505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610b19576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b610b2161195f565b610b2e6105c885876130aa565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75415610baf576040517fa788861700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff831615610bfd576040517f871cb76100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be5b600190810180547fffffffffffffffffffffffffffffffff0000000000000000000000000000000081166fffffffffffffffffffffffffffffffff91821690930116919091179055610c74610a5385876130aa565b5050505050565b6000610c878230610e4c565b92915050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610d30576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b610d3861195f565b7fffffffff00000000000000000000000000000000000000000000000000000000821660008181527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4922602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001685151590811790915582519384529083015280517f4e6bd17989efa6d6a9607ccaac1bba27b29f99622bc830d99a3a9883b21a19c79281900390910190a15050565b600080610dfd6119ca565b805190915060005b81811015610e4457610e3085848381518110610e2357610e23613214565b6020026020010151610e4c565b15610e3c578360010193505b600101610e05565b505050919050565b60008281527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d36020818152604080842073ffffffffffffffffffffffffffffffffffffffff8616855290915282205460ff168015610ee5575060008481526020828152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152902054610100900467ffffffffffffffff1642105b949350505050565b6000610ef76119ca565b805183519192509060005b82811015610fd957610f2086858381518110610e2357610e23613214565b15610fd15760005b82811015610fcf57848281518110610f4257610f42613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16868281518110610f7257610f72613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603610fc7576040517f50f5729f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600101610f28565b505b600101610f02565b505050505050565b3360009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff161580156110205750303314155b15611057576040517f6238ee3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff9081164290911610156110fa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75460000361117d576040517f3a76e1f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080527f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be6020527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d36111d36105c883856130aa565b60006111df848461130e565b905060006111eb611af4565b6111f59042613201565b6040805180820182526001815267ffffffffffffffff838116602080840191825260008881528982528581203382529091528490209251835491517fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000009092169015157fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff16176101009190921602179055519091507f6248ff757895beed7d43d135bccf59a26b7fbdf0fe8233487c44e82c0f266ba3906112b89087908790612f54565b60405180910390a16112c86116d0565b6112d183610df2565b101580156112e357506112e382610c7b565b15610c74577f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be610c1f565b60008282604051602001611323929190612f54565b6040516020818303038152906040528051906020012030466113627f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be90565b6001015460408051602081019590955273ffffffffffffffffffffffffffffffffffffffff9093169284019290925260608301526fffffffffffffffffffffffffffffffff16608082015260a001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905280516020918201207f19457468657265756d205369676e6564204d6573736167653a0a33320000000091830191909152603c820152605c0160405160208183030381529060405280519060200120905092915050565b805160005b818110156115ae57600083828151811061145657611456613214565b602002602001015160200151600281111561147357611473612e8a565b14806114ad5750600183828151811061148e5761148e613214565b60200260200101516020015160028111156114ab576114ab612e8a565b145b156115a657600254835173ffffffffffffffffffffffffffffffffffffffff9091169063df871f72908590849081106114e8576114e8613214565b60200260200101516000015185848151811061150657611506613214565b6020026020010151604001516040518363ffffffff1660e01b815260040161152f92919061331c565b602060405180830381865afa15801561154c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611570919061334b565b6115a6576040517ff41a931c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60010161143a565b505050565b80516000908082036115f1576040517f3aee2eec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b6115ff600183613368565b8110156116c6576000611613826001613201565b90505b828110156116bd5784818151811061163057611630613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1685838151811061166057611660613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16036116b5576040517f8dd19e7d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600101611616565b506001016115f4565b5060009392505050565b600080611723600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75490565b905080156117465761173660028261337b565b611741906001613201565b611749565b60005b91505090565b600080600061175e8585611bf6565b9092509050600081600481111561177757611777612e8a565b1480156117af57508573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b806117c057506117c0868686611c3b565b9695505050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921547f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff8116908190600090600716156118395750600381901c60009081526001840160205260409020545b60005b87518110156118b6576118a983838a848151811061185c5761185c613214565b6020026020010151600001518b858151811061187a5761187a613214565b6020026020010151602001518c868151811061189857611898613214565b602002602001015160400151611d98565b909350915060010161183c565b508282146118ef576002840180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff84161790555b600782161561191157600382901c600090815260018501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb67387878760405161194493929190613424565b60405180910390a16119568686612829565b50505050505050565b3330146119c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4c69624469616d6f6e643a2043616c6c6572206e6f742073656c6600000000006044820152606401610360565b565b60008080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b780546060929067ffffffffffffffff811115611a3257611a32612d07565b604051908082528060200260200182016040528015611a5b578160200160208202803683370190505b50825490915060005b81811015611aeb57836000018181548110611a8157611a81613214565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16838281518110611abe57611abe613214565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101611a64565b50909392505050565b6040517f52430c8d0000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906352430c8d90602401602060405180830381865afa158015611b81573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ba59190613510565b6fffffffffffffffffffffffffffffffff16905060008111611bf3576040517fdac5ec8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b90565b6000808251604103611c2c5760208301516040840151606085015160001a611c2087828585612928565b94509450505050611c34565b506000905060025b9250929050565b60008060008573ffffffffffffffffffffffffffffffffffffffff16631626ba7e60e01b8686604051602401611c72929190613542565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909416939093179092529051611cfb919061355b565b600060405180830381855afa9150503d8060008114611d36576040519150601f19603f3d011682016040523d82523d6000602084013e611d3b565b606091505b5091509150818015611d4f57506020815110155b80156117c0575080517f1626ba7e0000000000000000000000000000000000000000000000000000000090611d8d9083016020908101908401613577565b149695505050505050565b600080807f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f90506000845111611e50576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610360565b6000856002811115611e6457611e64612e8a565b0361203457611e8b8660405180606001604052806024815260200161365760249139612a17565b60005b845181101561202e576000858281518110611eab57611eab613214565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c15611f7e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c72656164792065786973747300000000000000000000006064820152608401610360565b7fffffffff0000000000000000000000000000000000000000000000000000000080831660008181526020879052604090207fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608d901b168e17905560e060058e901b811692831c199c909c1690821c179a8190036120125760038c901c600090815260018601602052604081209b909b555b8b61201c81613590565b9c505060019093019250611e8e915050565b5061281d565b600185600281111561204857612048612e8a565b036123385761206f866040518060600160405280602881526020016136a360289139612a17565b60005b845181101561202e57600085828151811061208f5761208f613214565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c308103612164576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4c69624469616d6f6e644375743a2043616e2774207265706c61636520696d6d60448201527f757461626c652066756e6374696f6e00000000000000000000000000000000006064820152608401610360565b8973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361221f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e00000000000000006064820152608401610360565b73ffffffffffffffffffffffffffffffffffffffff81166122c2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e207468617420646f65736e277420657869737400000000000000006064820152608401610360565b507fffffffff0000000000000000000000000000000000000000000000000000000090911660009081526020849052604090206bffffffffffffffffffffffff919091167fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608a901b16179055600101612072565b600285600281111561234c5761234c612e8a565b036127955773ffffffffffffffffffffffffffffffffffffffff8616156123f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d7573742062652061646472657373283029000000000000000000006064820152608401610360565b600388901c6007891660005b86518110156127755760008a900361243d578261241d816135c8565b60008181526001870160205260409020549b5093506007925061244b9050565b81612447816135c8565b9250505b6000806000808a858151811061246357612463613214565b6020908102919091018101517fffffffff0000000000000000000000000000000000000000000000000000000081166000908152918a9052604090912054909150606081901c612535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608401610360565b30606082901c036125c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e0000000000000000000000000000000000006064820152608401610360565b600587901b8f901b94507fffffffff0000000000000000000000000000000000000000000000000000000080861690831614612666577fffffffff000000000000000000000000000000000000000000000000000000008516600090815260208a90526040902080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff83161790555b7fffffffff0000000000000000000000000000000000000000000000000000000091909116600090815260208990526040812055600381901c611fff16925060051b60e01690508582146126fb576000828152600188016020526040902080547fffffffff0000000000000000000000000000000000000000000000000000000080841c19909116908516831c17905561274c565b80837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c817fffffffff0000000000000000000000000000000000000000000000000000000060001b901c198e16179c505b8460000361276a57600086815260018801602052604081208190559c505b505050600101612401565b50806127828360086135fd565b61278c9190613201565b9950505061281d565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560448201527f74416374696f6e000000000000000000000000000000000000000000000000006064820152608401610360565b50959694955050505050565b73ffffffffffffffffffffffffffffffffffffffff8216612848575050565b61286a8260405180606001604052806028815260200161367b60289139612a17565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051612892919061355b565b600060405180830381855af49150503d80600081146128cd576040519150601f19603f3d011682016040523d82523d6000602084013e6128d2565b606091505b509150915081612922578051156128ec5780518082602001fd5b83836040517f192105d7000000000000000000000000000000000000000000000000000000008152600401610360929190613614565b50505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561295f5750600090506003612a0e565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156129b3573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116612a0757600060019250925050612a0e565b9150600090505b94509492505050565b813b8181612922576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103609190613643565b60008083601f840112612a6457600080fd5b50813567ffffffffffffffff811115612a7c57600080fd5b6020830191508360208260051b8501011115611c3457600080fd5b60008060208385031215612aaa57600080fd5b823567ffffffffffffffff811115612ac157600080fd5b612acd85828601612a52565b90969095509350505050565b60008060008060008060608789031215612af257600080fd5b863567ffffffffffffffff80821115612b0a57600080fd5b612b168a838b01612a52565b90985096506020890135915080821115612b2f57600080fd5b612b3b8a838b01612a52565b90965094506040890135915080821115612b5457600080fd5b50612b6189828a01612a52565b979a9699509497509295939492505050565b803573ffffffffffffffffffffffffffffffffffffffff81168114612b9757600080fd5b919050565b600080600080600060608688031215612bb457600080fd5b853567ffffffffffffffff80821115612bcc57600080fd5b612bd889838a01612a52565b9097509550859150612bec60208901612b73565b94506040880135915080821115612c0257600080fd5b818801915088601f830112612c1657600080fd5b813581811115612c2557600080fd5b896020828501011115612c3757600080fd5b9699959850939650602001949392505050565b600060208284031215612c5c57600080fd5b5035919050565b80357fffffffff0000000000000000000000000000000000000000000000000000000081168114612b9757600080fd5b8015158114612ca157600080fd5b50565b60008060408385031215612cb757600080fd5b612cc083612c63565b91506020830135612cd081612c93565b809150509250929050565b60008060408385031215612cee57600080fd5b82359150612cfe60208401612b73565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff81118282101715612d5957612d59612d07565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715612da657612da6612d07565b604052919050565b600067ffffffffffffffff821115612dc857612dc8612d07565b5060051b60200190565b60008060408385031215612de557600080fd5b8235915060208084013567ffffffffffffffff811115612e0457600080fd5b8401601f81018613612e1557600080fd5b8035612e28612e2382612dae565b612d5f565b81815260059190911b82018301908381019088831115612e4757600080fd5b928401925b82841015612e6c57612e5d84612b73565b82529284019290840190612e4c565b80955050505050509250929050565b803560038110612b9757600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60038110612ef0577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b8183526000602080850194508260005b85811015612f49577fffffffff00000000000000000000000000000000000000000000000000000000612f3683612c63565b1687529582019590820190600101612f04565b509495945050505050565b60208082528181018390526000906040808401600586811b8601830188865b8981101561309b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc089840301855281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa18c3603018112612fd457600080fd5b8b01606073ffffffffffffffffffffffffffffffffffffffff612ff683612b73565b168552613004898301612e7b565b6130108a870182612eb9565b50878201357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe183360301811261304557600080fd5b90910188810191903567ffffffffffffffff81111561306357600080fd5b80871b360383131561307457600080fd5b81898701526130868287018285612ef4565b978a0197955050509187019150600101612f73565b50909998505050505050505050565b60006130b8612e2384612dae565b83815260208082019190600586811b8601368111156130d657600080fd5b865b818110156131c557803567ffffffffffffffff808211156130f95760008081fd5b818a0191506060823603121561310f5760008081fd5b613117612d36565b61312083612b73565b815261312d878401612e7b565b87820152604080840135838111156131455760008081fd5b939093019236601f85011261315c57600092508283fd5b8335925061316c612e2384612dae565b83815292871b840188019288810190368511156131895760008081fd5b948901945b848610156131ae5761319f86612c63565b8252948901949089019061318e565b9183019190915250885250509483019483016130d8565b5092979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610c8757610c876131d2565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561325557600080fd5b61325e82612b73565b9392505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261329a57600080fd5b83018035915067ffffffffffffffff8211156132b557600080fd5b602001915036819003821315611c3457600080fd5b600081518084526020808501945080840160005b83811015612f495781517fffffffff0000000000000000000000000000000000000000000000000000000016875295820195908201906001016132de565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000610ee560408301846132ca565b60006020828403121561335d57600080fd5b815161325e81612c93565b81810381811115610c8757610c876131d2565b6000826133b1577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60005b838110156133d15781810151838201526020016133b9565b50506000910152565b600081518084526133f28160208601602086016133b6565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6000606080830181845280875180835260808601915060808160051b87010192506020808a0160005b838110156134d4577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80898703018552815173ffffffffffffffffffffffffffffffffffffffff8151168752838101516134a885890182612eb9565b506040908101519087018890526134c1878901826132ca565b965050938201939082019060010161344d565b505073ffffffffffffffffffffffffffffffffffffffff8916908701525050838103604085015261350581866133da565b979650505050505050565b60006020828403121561352257600080fd5b81516fffffffffffffffffffffffffffffffff8116811461325e57600080fd5b828152604060208201526000610ee560408301846133da565b6000825161356d8184602087016133b6565b9190910192915050565b60006020828403121561358957600080fd5b5051919050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036135c1576135c16131d2565b5060010190565b6000816135d7576135d76131d2565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b8082028115828204841417610c8757610c876131d2565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000610ee560408301846133da565b60208152600061325e60208301846133da56fe4c69624469616d6f6e644375743a2041646420666163657420686173206e6f20636f64654c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a205265706c61636520666163657420686173206e6f20636f6465a2646970667358221220c5a8c10b22f20cde3fe0431ff57305237423677a60888f5b349fc6751336ae1464736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "Responsible for adding/removing/replace facets in Barz", + "kind": "dev", + "methods": { + "_checkDuplicateOnChainApprover(bytes32,address[])": { + "params": { + "_approvers": "List of approver addresses", + "_diamondCutHash": "Hash of diamondCut information including the facet addresses and function selectors" + } + }, + "approveDiamondCut((address,uint8,bytes4[])[])": { + "params": { + "_diamondCut": "Contains the facet addresses and function selectors" + } + }, + "constructor": { + "params": { + "_securityManager": "Security Manager contract that holds the security related variables for all wallets" + } + }, + "diamondCut((address,uint8,bytes4[])[],address,bytes)": { + "params": { + "_diamondCut": "Contains the facet addresses and function selectors", + "_init": "The address of the contract or facet to execute _calldata. It's prohibited in Barz" + } + }, + "diamondCutWithGuardian((address,uint8,bytes4[])[],address[],bytes[])": { + "params": { + "_approvers": "Guardian or owner address that approves the diamond cut", + "_diamondCut": "Contains the facet addresses and function selectors", + "_signatures": "Signature of Guardians or owner that approves the diamond cut" + } + }, + "getDiamondCutApprovalCountWithTimeValidity(bytes32)": { + "params": { + "_diamondCutHash": "Hash of diamondCut information including the facet addresses and function selectors" + } + }, + "getDiamondCutHash((address,uint8,bytes4[])[])": { + "params": { + "_diamondCut": "Contains the facet addresses and function selectors" + }, + "returns": { + "cutHash": "Diamond Cut Hash" + } + }, + "getDiamondCutNonce()": { + "details": "This method fetches the nonce from diamond cut storage", + "returns": { + "cutNonce": "Nonce of diamond cut to protect from reply attacks" + } + }, + "getOwnerCutApprovalWithTimeValidity(bytes32)": { + "params": { + "_diamondCutHash": "Hash of diamondCut information including the facet addresses and function selectors" + }, + "returns": { + "isApprovedByOwner": "Bool value showing if the owner approved the cut" + } + }, + "isCutApproved(bytes32,address)": { + "params": { + "_approver": "Address of approver", + "_diamondCutHash": "Hash of diamondCut information including the facet addresses and function selectors" + }, + "returns": { + "isApproved": "Bool value showing if the approver approved the cut" + } + }, + "revokeDiamondCutApproval((address,uint8,bytes4[])[])": { + "params": { + "_diamondCut": "Contains the facet addresses and function selectors" + } + }, + "updateSupportsInterface(bytes4,bool)": { + "params": { + "_flag": "Bool value to update the mapping of the given interface ID", + "_interfaceId": "InterfaceID to update the mapping" + } + } + }, + "title": "DiamondCut Facet", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "_checkDuplicateOnChainApprover(bytes32,address[])": { + "notice": "Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval Approvers who approved on-chain should not be included in the off-chain approval" + }, + "approveDiamondCut((address,uint8,bytes4[])[])": { + "notice": "Approves diamond cut. This can only be called directly from guardian or owner" + }, + "constructor": { + "notice": "This constructor sets the Security Manager address which is an immutable variable. Immutable variables do not impact the storage of diamond" + }, + "diamondCut((address,uint8,bytes4[])[],address,bytes)": { + "notice": "Add/replace/remove any number of functions and optionally execute a function with delegatecall when guardians don't exist" + }, + "diamondCutWithGuardian((address,uint8,bytes4[])[],address[],bytes[])": { + "notice": "Add/replace/remove any number of functions and optionally execute a function with delegatecall when guardians exist" + }, + "getDiamondCutApprovalCountWithTimeValidity(bytes32)": { + "notice": "Gets the number of approvals of diamond cut from guardians" + }, + "getDiamondCutHash((address,uint8,bytes4[])[])": { + "notice": "Returns the diamond cut hash. This function ensures that this hash is safe from replay attack by including salt, address, chainId, and nonce, etc." + }, + "getDiamondCutNonce()": { + "notice": "Returns the diamond cut nonce of this wallet" + }, + "getOwnerCutApprovalWithTimeValidity(bytes32)": { + "notice": "Returns if the owner has approved the diamond cut" + }, + "isCutApproved(bytes32,address)": { + "notice": "Returns if the given approver has approved the diamond cut" + }, + "revokeDiamondCutApproval((address,uint8,bytes4[])[])": { + "notice": "Revokes the approval of diamond cut. This can only be called directly from guardian or owner" + }, + "updateSupportsInterface(bytes4,bool)": { + "notice": "Updates the flag for the interfaceId" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 27866, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "s", + "offset": 0, + "slot": "0", + "type": "t_struct(AppStorage)27613_storage" + } + ], + "types": { + "t_bytes4": { + "encoding": "inplace", + "label": "bytes4", + "numberOfBytes": "4" + }, + "t_contract(IEntryPoint)12286": { + "encoding": "inplace", + "label": "contract IEntryPoint", + "numberOfBytes": "20" + }, + "t_contract(IFacetRegistry)26148": { + "encoding": "inplace", + "label": "contract IFacetRegistry", + "numberOfBytes": "20" + }, + "t_mapping(t_uint256,t_struct(InitializersStorage)27592_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => struct InitializersStorage)", + "numberOfBytes": "32", + "value": "t_struct(InitializersStorage)27592_storage" + }, + "t_mapping(t_uint256,t_struct(Lock)27585_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => struct Lock)", + "numberOfBytes": "32", + "value": "t_struct(Lock)27585_storage" + }, + "t_struct(AppStorage)27613_storage": { + "encoding": "inplace", + "label": "struct AppStorage", + "members": [ + { + "astId": 27597, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "initStorage", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_uint256,t_struct(InitializersStorage)27592_storage)" + }, + { + "astId": 27599, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "signerMigration", + "offset": 0, + "slot": "1", + "type": "t_uint8" + }, + { + "astId": 27601, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "validateOwnerSignatureSelector", + "offset": 1, + "slot": "1", + "type": "t_bytes4" + }, + { + "astId": 27604, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "entryPoint", + "offset": 5, + "slot": "1", + "type": "t_contract(IEntryPoint)12286" + }, + { + "astId": 27607, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "facetRegistry", + "offset": 0, + "slot": "2", + "type": "t_contract(IFacetRegistry)26148" + }, + { + "astId": 27612, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "locks", + "offset": 0, + "slot": "3", + "type": "t_mapping(t_uint256,t_struct(Lock)27585_storage)" + } + ], + "numberOfBytes": "128" + }, + "t_struct(InitializersStorage)27592_storage": { + "encoding": "inplace", + "label": "struct InitializersStorage", + "members": [ + { + "astId": 27587, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "signerInitialized", + "offset": 0, + "slot": "0", + "type": "t_uint8" + }, + { + "astId": 27589, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "accountInitialized", + "offset": 1, + "slot": "0", + "type": "t_uint8" + }, + { + "astId": 27591, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "restrictionsInitialized", + "offset": 2, + "slot": "0", + "type": "t_uint8" + } + ], + "numberOfBytes": "32" + }, + "t_struct(Lock)27585_storage": { + "encoding": "inplace", + "label": "struct Lock", + "members": [ + { + "astId": 27582, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "release", + "offset": 0, + "slot": "0", + "type": "t_uint64" + }, + { + "astId": 27584, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "locker", + "offset": 8, + "slot": "0", + "type": "t_bytes4" + } + ], + "numberOfBytes": "32" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint64": { + "encoding": "inplace", + "label": "uint64", + "numberOfBytes": "8" + }, + "t_uint8": { + "encoding": "inplace", + "label": "uint8", + "numberOfBytes": "1" + } + } + } +} \ No newline at end of file diff --git a/deployments/blast/DiamondLoupeFacet.json b/deployments/blast/DiamondLoupeFacet.json new file mode 100644 index 0000000..21563c9 --- /dev/null +++ b/deployments/blast/DiamondLoupeFacet.json @@ -0,0 +1,306 @@ +{ + "address": "0xCe36b85d12D81cd619C745c7717f3396E184Ac7C", + "abi": [ + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_functionSelector", + "type": "bytes4" + } + ], + "name": "facetAddress", + "outputs": [ + { + "internalType": "address", + "name": "facetAddress_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_functionSelector", + "type": "bytes4" + } + ], + "name": "facetAddressFromStorage", + "outputs": [ + { + "internalType": "address", + "name": "facetAddress_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetAddresses", + "outputs": [ + { + "internalType": "address[]", + "name": "facetAddresses_", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetAddressesFromStorage", + "outputs": [ + { + "internalType": "address[]", + "name": "facetAddresses_", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_facet", + "type": "address" + } + ], + "name": "facetFunctionSelectors", + "outputs": [ + { + "internalType": "bytes4[]", + "name": "facetFunctionSelectors_", + "type": "bytes4[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_facet", + "type": "address" + } + ], + "name": "facetFunctionSelectorsFromStorage", + "outputs": [ + { + "internalType": "bytes4[]", + "name": "facetFunctionSelectors_", + "type": "bytes4[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facets", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondLoupe.Facet[]", + "name": "facets_", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetsFromStorage", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondLoupe.Facet[]", + "name": "facets_", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "isSupported", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0xe5a3be58092852282019bd2994051a8ea0d32419aff68900bd519185d7433887", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 6, + "gasUsed": "2036953", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x2b4d512bacdc905b981f188a4baeac4d3d2a999006b3f17d6fe7fb2d9d8e5acc", + "transactionHash": "0xe5a3be58092852282019bd2994051a8ea0d32419aff68900bd519185d7433887", + "logs": [], + "blockNumber": 1317764, + "cumulativeGasUsed": "3209879", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "ad34345aa73d96f52b3e14df983b6b29", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_functionSelector\",\"type\":\"bytes4\"}],\"name\":\"facetAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"facetAddress_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_functionSelector\",\"type\":\"bytes4\"}],\"name\":\"facetAddressFromStorage\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"facetAddress_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetAddresses\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"facetAddresses_\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetAddressesFromStorage\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"facetAddresses_\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_facet\",\"type\":\"address\"}],\"name\":\"facetFunctionSelectors\",\"outputs\":[{\"internalType\":\"bytes4[]\",\"name\":\"facetFunctionSelectors_\",\"type\":\"bytes4[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_facet\",\"type\":\"address\"}],\"name\":\"facetFunctionSelectorsFromStorage\",\"outputs\":[{\"internalType\":\"bytes4[]\",\"name\":\"facetFunctionSelectors_\",\"type\":\"bytes4[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facets\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondLoupe.Facet[]\",\"name\":\"facets_\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetsFromStorage\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondLoupe.Facet[]\",\"name\":\"facets_\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isSupported\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"DiamondLoupe contract compatible with EIP-2535\",\"kind\":\"dev\",\"methods\":{\"facetAddress(bytes4)\":{\"details\":\"If facet is not found return address(0).\",\"params\":{\"_functionSelector\":\"The function selector.\"},\"returns\":{\"facetAddress_\":\"The facet address.\"}},\"facetAddressFromStorage(bytes4)\":{\"params\":{\"_functionSelector\":\"Function selector to fetch the facet address from diamond storage\"},\"returns\":{\"facetAddress_\":\"Facet address mapped with the function selector\"}},\"facetAddresses()\":{\"returns\":{\"facetAddresses_\":\"facetAddresses_\"}},\"facetAddressesFromStorage()\":{\"returns\":{\"facetAddresses_\":\"All facet addresses attached directly to diamond storage\"}},\"facetFunctionSelectors(address)\":{\"params\":{\"_facet\":\"The facet address.\"},\"returns\":{\"facetFunctionSelectors_\":\"facetFunctionSelectors_\"}},\"facetFunctionSelectorsFromStorage(address)\":{\"params\":{\"_facet\":\"Facet address to fetch the facet function selectors from diamond storage\"},\"returns\":{\"facetFunctionSelectors_\":\"Facet function selectors of the given facet address\"}},\"facets()\":{\"details\":\"Barz uses a special architecture called default fallback handler. Default Fallback handler is used as a middleware that holds the mapping of facet function selector and facet address that Barz uses. This helps Barz to reduce significant amount of gas during the initialization process. Hence, this method aggregates both the facet information from DefaulFallbackHandler and in diamond storage and shows the data to users.\",\"returns\":{\"facets_\":\"Facet\"}},\"facetsFromStorage()\":{\"returns\":{\"facets_\":\"Facet information attached directly to diamond storage\"}},\"supportsInterface(bytes4)\":{\"params\":{\"_interfaceId\":\"Interface ID for detecting the interface\"},\"returns\":{\"isSupported\":\"Bool value showing if the standard is supported in the contract\"}}},\"title\":\"DiamondLoupe Facet\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"facetAddress(bytes4)\":{\"notice\":\"Gets the facet that supports the given selector.\"},\"facetAddressFromStorage(bytes4)\":{\"notice\":\"Returns the facet address attached to the given function selector. This excludes the facets from the default fallback handler\"},\"facetAddresses()\":{\"notice\":\"Get all the facet addresses used by Barz.\"},\"facetAddressesFromStorage()\":{\"notice\":\"Returns all facet addresses attached directly to diamond storage. This excludes the facets from the default fallback handler\"},\"facetFunctionSelectors(address)\":{\"notice\":\"Gets all the function selectors provided by a facet.\"},\"facetFunctionSelectorsFromStorage(address)\":{\"notice\":\"Returns function selectors of given facet address attached directly to diamond storage. This excludes the facets from the default fallback handler\"},\"facets()\":{\"notice\":\"Gets all facets and their selectors.\"},\"facetsFromStorage()\":{\"notice\":\"Returns the facet from the diamond storage. This excludes the facets from the default fallback handler\"},\"supportsInterface(bytes4)\":{\"notice\":\"SupportInterface to be compatible with EIP 165\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/base/DiamondLoupeFacet.sol\":\"DiamondLoupeFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/introspection/IERC165.sol\\\";\\n\\n/**\\n * @dev _Available since v3.1._\\n */\\ninterface IERC1155Receiver is IERC165 {\\n /**\\n * @dev Handles the receipt of a single ERC1155 token type. This function is\\n * called at the end of a `safeTransferFrom` after the balance has been updated.\\n *\\n * NOTE: To accept the transfer, this must return\\n * `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))`\\n * (i.e. 0xf23a6e61, or its own function selector).\\n *\\n * @param operator The address which initiated the transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param id The ID of the token being transferred\\n * @param value The amount of tokens being transferred\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155Received(\\n address operator,\\n address from,\\n uint256 id,\\n uint256 value,\\n bytes calldata data\\n ) external returns (bytes4);\\n\\n /**\\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\\n * is called at the end of a `safeBatchTransferFrom` after the balances have\\n * been updated.\\n *\\n * NOTE: To accept the transfer(s), this must return\\n * `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))`\\n * (i.e. 0xbc197c81, or its own function selector).\\n *\\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155BatchReceived(\\n address operator,\\n address from,\\n uint256[] calldata ids,\\n uint256[] calldata values,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xeb373f1fdc7b755c6a750123a9b9e3a8a02c1470042fd6505d875000a80bde0b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title ERC721 token receiver interface\\n * @dev Interface for any contract that wants to support safeTransfers\\n * from ERC721 asset contracts.\\n */\\ninterface IERC721Receiver {\\n /**\\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\\n * by `operator` from `from`, this function is called.\\n *\\n * It must return its Solidity selector to confirm the token transfer.\\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\\n *\\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\\n */\\n function onERC721Received(\\n address operator,\\n address from,\\n uint256 tokenId,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\\n *\\n * Accounts can be notified of {IERC777} tokens being sent to them by having a\\n * contract implement this interface (contract holders can be their own\\n * implementer) and registering it on the\\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\\n *\\n * See {IERC1820Registry} and {ERC1820Implementer}.\\n */\\ninterface IERC777Recipient {\\n /**\\n * @dev Called by an {IERC777} token contract whenever tokens are being\\n * moved or created into a registered account (`to`). The type of operation\\n * is conveyed by `from` being the zero address or not.\\n *\\n * This call occurs _after_ the token contract's state is updated, so\\n * {IERC777-balanceOf}, etc., can be used to query the post-operation state.\\n *\\n * This function may revert to prevent the operation from being executed.\\n */\\n function tokensReceived(\\n address operator,\\n address from,\\n address to,\\n uint256 amount,\\n bytes calldata userData,\\n bytes calldata operatorData\\n ) external;\\n}\\n\",\"keccak256\":\"0x1a5d61db2733202ba361e6d6741cd2e662380e22b80e987eacfc91973f2267dc\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"contracts/facets/base/DiamondLoupeFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IERC777Recipient} from \\\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\\\";\\nimport {IERC165} from \\\"../../interfaces/ERC/IERC165.sol\\\";\\nimport {IERC1271} from \\\"../../interfaces/ERC/IERC1271.sol\\\";\\nimport {IERC677Receiver} from \\\"../../interfaces/ERC/IERC677Receiver.sol\\\";\\nimport {IERC721Receiver} from \\\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\\\";\\nimport {IERC1155Receiver} from \\\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\\\";\\nimport {LibDiamond} from \\\"../../libraries/LibDiamond.sol\\\";\\nimport {LibLoupe} from \\\"../../libraries/LibLoupe.sol\\\";\\nimport {LibUtils} from \\\"../../libraries/LibUtils.sol\\\";\\nimport {IDiamondCut} from \\\"../../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IStorageLoupe} from \\\"./interfaces/IStorageLoupe.sol\\\";\\nimport {IDiamondLoupe} from \\\"./interfaces/IDiamondLoupe.sol\\\";\\n\\n/**\\n * @title DiamondLoupe Facet\\n * @dev DiamondLoupe contract compatible with EIP-2535\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract DiamondLoupeFacet is IDiamondLoupe, IStorageLoupe, IERC165 {\\n // Diamond Loupe Functions\\n ////////////////////////////////////////////////////////////////////\\n /// These functions are expected to be called frequently by tools off-chain.\\n\\n /**\\n * @notice Gets all facets and their selectors.\\n * @dev Barz uses a special architecture called default fallback handler. Default Fallback handler is used as a middleware\\n * that holds the mapping of facet function selector and facet address that Barz uses. This helps Barz to reduce\\n * significant amount of gas during the initialization process.\\n * Hence, this method aggregates both the facet information from DefaulFallbackHandler and in diamond storage and shows the data to users.\\n * @return facets_ Facet\\n */\\n function facets() public view override returns (Facet[] memory facets_) {\\n Facet[] memory defaultFacet = LibDiamond\\n .diamondStorage()\\n .defaultFallbackHandler\\n .facets();\\n Facet[] memory _facets = LibLoupe.facets();\\n uint256 numFacets = _facets.length;\\n bytes4[] memory keys;\\n address[] memory values;\\n for (uint256 i; i < numFacets; ) {\\n uint256 selectorsLength = _facets[i].functionSelectors.length;\\n for (uint256 j; j < selectorsLength; ) {\\n (keys, values) = LibUtils.setValue(\\n keys,\\n values,\\n _facets[i].functionSelectors[j],\\n _facets[i].facetAddress\\n );\\n unchecked {\\n ++j;\\n }\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n {\\n bool iIncrement;\\n for (uint256 i; i < defaultFacet.length; ) {\\n bool jIncrement;\\n for (\\n uint256 j;\\n j < defaultFacet[i].functionSelectors.length;\\n\\n ) {\\n if (\\n LibUtils.getValue(\\n keys,\\n values,\\n defaultFacet[i].functionSelectors[j]\\n ) != address(0)\\n ) {\\n if (defaultFacet[i].functionSelectors.length == 1) {\\n defaultFacet = LibUtils.removeFacetElement(\\n defaultFacet,\\n i\\n );\\n iIncrement = true;\\n break;\\n }\\n defaultFacet[i].functionSelectors = LibUtils\\n .removeElement(\\n defaultFacet[i].functionSelectors,\\n j\\n );\\n jIncrement = true;\\n }\\n if (!jIncrement) {\\n unchecked {\\n ++j;\\n }\\n } else {\\n jIncrement = false;\\n }\\n }\\n if (!iIncrement) {\\n unchecked {\\n ++i;\\n }\\n } else {\\n iIncrement = false;\\n }\\n }\\n }\\n {\\n uint256 facetLength = numFacets + defaultFacet.length;\\n facets_ = new Facet[](facetLength);\\n uint256 defaultFacetIndex;\\n for (uint256 i; i < facetLength; ) {\\n if (i < numFacets) {\\n facets_[i] = _facets[i];\\n bool jIncrementor;\\n for (uint256 j; j < defaultFacet.length; ) {\\n if (\\n facets_[i].facetAddress ==\\n defaultFacet[j].facetAddress\\n ) {\\n facets_[i].functionSelectors = LibUtils.mergeArrays(\\n _facets[i].functionSelectors,\\n defaultFacet[j].functionSelectors\\n );\\n defaultFacet = LibUtils.removeFacetElement(\\n defaultFacet,\\n j\\n );\\n jIncrementor = true;\\n {\\n facets_ = LibUtils.removeFacetElement(\\n facets_,\\n facets_.length - 1\\n );\\n }\\n --facetLength;\\n }\\n if (!jIncrementor) {\\n unchecked {\\n ++j;\\n }\\n } else {\\n jIncrementor = false;\\n }\\n }\\n } else {\\n facets_[i] = defaultFacet[defaultFacetIndex];\\n ++defaultFacetIndex;\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n }\\n\\n /**\\n * @notice Gets all the function selectors provided by a facet.\\n * @param _facet The facet address.\\n * @return facetFunctionSelectors_\\n */\\n function facetFunctionSelectors(\\n address _facet\\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\\n Facet[] memory facet = facets();\\n uint256 facetLength = facet.length;\\n for (uint256 i; i < facetLength; ) {\\n if (facet[i].facetAddress == _facet)\\n return facet[i].functionSelectors;\\n unchecked {\\n ++i;\\n }\\n }\\n return facetFunctionSelectors_;\\n }\\n\\n /**\\n * @notice Get all the facet addresses used by Barz.\\n * @return facetAddresses_\\n */\\n function facetAddresses()\\n external\\n view\\n override\\n returns (address[] memory facetAddresses_)\\n {\\n Facet[] memory facet = facets();\\n uint256 facetLength = facet.length;\\n facetAddresses_ = new address[](facetLength);\\n for (uint256 i; i < facetLength; ) {\\n facetAddresses_[i] = facet[i].facetAddress;\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * @notice Gets the facet that supports the given selector.\\n * @dev If facet is not found return address(0).\\n * @param _functionSelector The function selector.\\n * @return facetAddress_ The facet address.\\n */\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view override returns (address facetAddress_) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n\\n facetAddress_ = address(bytes20(ds.facets[_functionSelector]));\\n if (facetAddress_ == address(0)) {\\n facetAddress_ = IDiamondLoupe(ds.defaultFallbackHandler)\\n .facetAddress(_functionSelector);\\n }\\n }\\n\\n /**\\n * @notice SupportInterface to be compatible with EIP 165\\n * @param _interfaceId Interface ID for detecting the interface\\n * @return isSupported Bool value showing if the standard is supported in the contract\\n */\\n function supportsInterface(\\n bytes4 _interfaceId\\n ) external view override returns (bool isSupported) {\\n isSupported =\\n _interfaceId == type(IERC165).interfaceId ||\\n _interfaceId == IDiamondCut.diamondCut.selector ||\\n _interfaceId == type(IDiamondLoupe).interfaceId ||\\n _interfaceId == type(IERC1155Receiver).interfaceId ||\\n _interfaceId == type(IERC721Receiver).interfaceId ||\\n _interfaceId == type(IERC777Recipient).interfaceId ||\\n _interfaceId == IERC1271.isValidSignature.selector ||\\n _interfaceId == type(IERC677Receiver).interfaceId ||\\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId];\\n }\\n\\n /**\\n * @notice Returns the facet from the diamond storage. This excludes the facets from the default fallback handler\\n * @return facets_ Facet information attached directly to diamond storage\\n */\\n function facetsFromStorage()\\n external\\n view\\n override\\n returns (Facet[] memory facets_)\\n {\\n facets_ = LibLoupe.facets();\\n }\\n\\n /**\\n * @notice Returns the facet address attached to the given function selector. This excludes the facets from the default fallback handler\\n * @param _functionSelector Function selector to fetch the facet address from diamond storage\\n * @return facetAddress_ Facet address mapped with the function selector\\n */\\n function facetAddressFromStorage(\\n bytes4 _functionSelector\\n ) external view override returns (address facetAddress_) {\\n facetAddress_ = LibLoupe.facetAddress(_functionSelector);\\n }\\n\\n /**\\n * @notice Returns all facet addresses attached directly to diamond storage. This excludes the facets from the default fallback handler\\n * @return facetAddresses_ All facet addresses attached directly to diamond storage\\n */\\n function facetAddressesFromStorage()\\n external\\n view\\n override\\n returns (address[] memory facetAddresses_)\\n {\\n facetAddresses_ = LibLoupe.facetAddresses();\\n }\\n\\n /**\\n * @notice Returns function selectors of given facet address attached directly to diamond storage. This excludes the facets from the default fallback handler\\n * @param _facet Facet address to fetch the facet function selectors from diamond storage\\n * @return facetFunctionSelectors_ Facet function selectors of the given facet address\\n */\\n function facetFunctionSelectorsFromStorage(\\n address _facet\\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\\n facetFunctionSelectors_ = LibLoupe.facetFunctionSelectors(_facet);\\n }\\n}\\n\",\"keccak256\":\"0xf392fde159eec6483fc15fa323ecd6d764028f5b8734a66662c4116292363794\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IStorageLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"./IDiamondLoupe.sol\\\";\\n\\n/**\\n * @title LoupeFromStorage Interface\\n * @dev Interface contract to function as a loupe facet directly attached to diamond storage of Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IStorageLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facetsFromStorage()\\n external\\n view\\n returns (IDiamondLoupe.Facet[] memory);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n function facetFunctionSelectorsFromStorage(\\n address _facet\\n ) external view returns (bytes4[] memory);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n function facetAddressesFromStorage()\\n external\\n view\\n returns (address[] memory);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n function facetAddressFromStorage(\\n bytes4 _functionSelector\\n ) external view returns (address);\\n}\\n\",\"keccak256\":\"0xdf5dc9c57319e9087628c9cf9404b4f75585b76d1c2f4f59ee796c933967ea5c\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC1271 {\\n function isValidSignature(\\n bytes32 hash,\\n bytes memory signature\\n ) external view returns (bytes4);\\n}\\n\",\"keccak256\":\"0xcdddb7d5641c9d3f2432dec7fd13fddb9ae1480f25c76c21511e2fa16b8bd422\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.21;\\n\\ninterface IERC165 {\\n /// @notice Query if a contract implements an interface\\n /// @param interfaceId The interface identifier, as specified in ERC-165\\n /// @dev Interface identification is specified in ERC-165. This function\\n /// uses less than 30,000 gas.\\n /// @return `true` if the contract implements `interfaceID` and\\n /// `interfaceID` is not 0xffffffff, `false` otherwise\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xbb7f07e170898793c5535cc4b7e8944c4b990a631ac806d0b788e794abc788a3\",\"license\":\"MIT\"},\"contracts/interfaces/ERC/IERC677Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC677Receiver {\\n function onTokenTransfer(\\n address sender,\\n uint value,\\n bytes calldata data\\n ) external pure returns (bool);\\n}\\n\",\"keccak256\":\"0x4c1631cf45ea6daac0ec158c3edb9453099130b6b64f697004b83f95aa1f7350\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\\n bytes4(keccak256(\\\"verifyRestrictions(address,address,uint256,bytes)\\\"));\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // Default Fallback Handler of the barz.\\n IDiamondLoupe defaultFallbackHandler;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function enforceIsSelf() internal view {\\n require(msg.sender == address(this), \\\"LibDiamond: Caller not self\\\");\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n\\n unchecked {\\n facetIndex++;\\n }\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n\\n function restrictionsFacet() internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(\\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2cabdc00de859c3a3170ce3bda5d0e5fd3933d47ce904fd1585f9818b02572f8\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\nimport {LibDiamond} from \\\"./LibDiamond.sol\\\";\\n\\n/**\\n * @title LibLoupe\\n * @dev Internal Library to provide utility feature for reading the state of diamond facets\\n * Originally from Diamond's implementation of Mudgen(author of EIP-2535)\\n */\\nlibrary LibLoupe {\\n /// @notice Gets all facets and their selectors.\\n /// @return facets_ Facet\\n function facets()\\n internal\\n view\\n returns (IDiamondLoupe.Facet[] memory facets_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facets_ = new IDiamondLoupe.Facet[](ds.selectorCount);\\n uint16[] memory numFacetSelectors = new uint16[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facets_[facetIndex].facetAddress == facetAddress_) {\\n facets_[facetIndex].functionSelectors[\\n numFacetSelectors[facetIndex]\\n ] = selector;\\n // probably will never have more than 256 functions from one facet contract\\n require(numFacetSelectors[facetIndex] < 255);\\n numFacetSelectors[facetIndex]++;\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facets_[numFacets].facetAddress = facetAddress_;\\n facets_[numFacets].functionSelectors = new bytes4[](\\n ds.selectorCount\\n );\\n facets_[numFacets].functionSelectors[0] = selector;\\n numFacetSelectors[numFacets] = 1;\\n numFacets++;\\n }\\n }\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n uint256 numSelectors = numFacetSelectors[facetIndex];\\n bytes4[] memory selectors = facets_[facetIndex].functionSelectors;\\n // setting the number of selectors\\n assembly {\\n mstore(selectors, numSelectors)\\n }\\n }\\n // setting the number of facets\\n assembly {\\n mstore(facets_, numFacets)\\n }\\n }\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return _facetFunctionSelectors The selectors associated with a facet address.\\n function facetFunctionSelectors(\\n address _facet\\n ) internal view returns (bytes4[] memory _facetFunctionSelectors) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n uint256 numSelectors;\\n _facetFunctionSelectors = new bytes4[](ds.selectorCount);\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facet = address(bytes20(ds.facets[selector]));\\n if (_facet == facet) {\\n _facetFunctionSelectors[numSelectors] = selector;\\n numSelectors++;\\n }\\n }\\n }\\n // Set the number of selectors in the array\\n assembly {\\n mstore(_facetFunctionSelectors, numSelectors)\\n }\\n }\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n internal\\n view\\n returns (address[] memory facetAddresses_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetAddresses_ = new address[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facetAddress_ == facetAddresses_[facetIndex]) {\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facetAddresses_[numFacets] = facetAddress_;\\n numFacets++;\\n }\\n }\\n // Set the number of facet addresses in the array\\n assembly {\\n mstore(facetAddresses_, numFacets)\\n }\\n }\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(LibDiamond.diamondStorage().facets[_functionSelector])\\n );\\n }\\n}\\n\",\"keccak256\":\"0x0b11439c3cc657095e15ec2241fdcf67204b14001357b612fc5db4ff9e760a5a\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibUtils.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nlibrary LibUtils {\\n // Internal utility functions\\n function mergeArrays(\\n bytes4[] memory _array1,\\n bytes4[] memory _array2\\n ) internal pure returns (bytes4[] memory) {\\n uint256 length1 = _array1.length;\\n uint256 length2 = _array2.length;\\n bytes4[] memory mergedArray = new bytes4[](length1 + length2);\\n\\n for (uint256 i; i < length1; ) {\\n mergedArray[i] = _array1[i];\\n unchecked {\\n ++i;\\n }\\n }\\n\\n for (uint256 i; i < length2; ) {\\n mergedArray[length1 + i] = _array2[i];\\n unchecked {\\n ++i;\\n }\\n }\\n\\n return mergedArray;\\n }\\n\\n function removeFacetElement(\\n IDiamondLoupe.Facet[] memory _facets,\\n uint256 _index\\n ) internal pure returns (IDiamondLoupe.Facet[] memory) {\\n require(_index < _facets.length, \\\"Invalid index\\\");\\n require(_facets.length != 0, \\\"Invalid array\\\");\\n\\n // Create a new array with a length of `_facets.length - 1`\\n IDiamondLoupe.Facet[] memory newArray = new IDiamondLoupe.Facet[](\\n _facets.length - 1\\n );\\n uint256 newArrayLength = newArray.length;\\n // Iterate over the original array, skipping the element at the specified `index`\\n for (uint256 i; i < newArrayLength; ) {\\n if (i < _index) {\\n newArray[i] = _facets[i];\\n } else {\\n newArray[i] = _facets[i + 1];\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n\\n return newArray;\\n }\\n\\n function removeElement(\\n bytes4[] memory _array,\\n uint256 _index\\n ) internal pure returns (bytes4[] memory) {\\n require(_index < _array.length, \\\"Invalid index\\\");\\n require(_array.length != 0, \\\"Invalid array\\\");\\n\\n bytes4[] memory newArray = new bytes4[](_array.length - 1);\\n uint256 newArrayLength = newArray.length;\\n for (uint256 i; i < newArrayLength; ) {\\n if (i < _index) {\\n newArray[i] = _array[i];\\n } else {\\n newArray[i] = _array[i + 1];\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n\\n return newArray;\\n }\\n\\n function setValue(\\n bytes4[] memory _keys,\\n address[] memory _values,\\n bytes4 _key,\\n address _value\\n ) internal pure returns (bytes4[] memory, address[] memory) {\\n uint256 index = findIndex(_keys, _key);\\n uint256 keysLength = _keys.length;\\n if (index < keysLength) {\\n _values[index] = _value;\\n } else {\\n // Create new storage arrays\\n bytes4[] memory newKeys = new bytes4[](keysLength + 1);\\n address[] memory newValues = new address[](_values.length + 1);\\n\\n // Copy values to the new storage arrays\\n for (uint256 i; i < keysLength; ) {\\n newKeys[i] = _keys[i];\\n newValues[i] = _values[i];\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n // Add the new key-value pair\\n newKeys[keysLength] = _key;\\n newValues[_values.length] = _value;\\n\\n return (newKeys, newValues);\\n }\\n\\n // If the key already exists, return the original arrays\\n return (_keys, _values);\\n }\\n\\n function getValue(\\n bytes4[] memory _keys,\\n address[] memory _values,\\n bytes4 _key\\n ) internal pure returns (address) {\\n uint256 index = findIndex(_keys, _key);\\n if (index >= _keys.length) return address(0);\\n\\n return _values[index];\\n }\\n\\n function findIndex(\\n bytes4[] memory _keys,\\n bytes4 _key\\n ) internal pure returns (uint256) {\\n uint256 keysLength = _keys.length;\\n for (uint256 i; i < keysLength; ) {\\n if (_keys[i] == _key) {\\n return i;\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n return keysLength;\\n }\\n}\\n\",\"keccak256\":\"0xde8aeefe54c4be483f2b2c055aca11e2830f7094c0586a82e10ec544933b5714\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5061240b806100206000396000f3fe608060405234801561001057600080fd5b50600436106100a35760003560e01c8063adfca15e11610076578063d42139a91161005b578063d42139a914610169578063e3a2f6fe14610171578063f9796ccf1461018457600080fd5b8063adfca15e1461011e578063cdffacc61461013157600080fd5b806301a55022146100a857806301ffc9a7146100d157806352ef6b2c146100f45780637a0ed62714610109575b600080fd5b6100bb6100b6366004611e4b565b61018c565b6040516100c89190611e68565b60405180910390f35b6100e46100df366004611efc565b61019d565b60405190151581526020016100c8565b6100fc610454565b6040516100c89190611f19565b610111610518565b6040516100c89190611f67565b6100bb61012c366004611e4b565b610a63565b61014461013f366004611efc565b610b07565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100c8565b6100fc610c24565b61014461017f366004611efc565b610c33565b610111610c8c565b606061019782610c96565b92915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000148061023057507fffffffff0000000000000000000000000000000000000000000000000000000082167f1f931c1c00000000000000000000000000000000000000000000000000000000145b8061027c57507fffffffff0000000000000000000000000000000000000000000000000000000082167f48e2b09300000000000000000000000000000000000000000000000000000000145b806102c857507fffffffff0000000000000000000000000000000000000000000000000000000082167f4e2312e000000000000000000000000000000000000000000000000000000000145b8061031457507fffffffff0000000000000000000000000000000000000000000000000000000082167f150b7a0200000000000000000000000000000000000000000000000000000000145b8061035f57507fffffffff0000000000000000000000000000000000000000000000000000000082167e23de2900000000000000000000000000000000000000000000000000000000145b806103ab57507fffffffff0000000000000000000000000000000000000000000000000000000082167f1626ba7e00000000000000000000000000000000000000000000000000000000145b806103f757507fffffffff0000000000000000000000000000000000000000000000000000000082167fa4c0ed3600000000000000000000000000000000000000000000000000000000145b806101975750507fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4922602052604090205460ff1690565b60606000610460610518565b80519091508067ffffffffffffffff81111561047e5761047e61205d565b6040519080825280602002602001820160405280156104a7578160200160208202803683370190505b50925060005b81811015610512578281815181106104c7576104c761208c565b6020026020010151600001518482815181106104e5576104e561208c565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526001016104ad565b50505090565b606060007f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f600490810154604080517f7a0ed627000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff90921692637a0ed6279282820192600092908290030181865afa1580156105ac573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526105f29190810190612157565b905060006105fe610e57565b805190915060608060005b838110156106b55760008582815181106106255761062561208c565b60200260200101516020015151905060005b818110156106ab5761069e85858986815181106106565761065661208c565b60200260200101516020015184815181106106735761067361208c565b60200260200101518a878151811061068d5761068d61208c565b60200260200101516000015161134a565b9095509350600101610637565b5050600101610609565b506000805b865181101561081b576000805b8883815181106106d9576106d961208c565b602002602001015160200151518110156107ff57600073ffffffffffffffffffffffffffffffffffffffff1661074687878c878151811061071c5761071c61208c565b60200260200101516020015185815181106107395761073961208c565b60200260200101516115f1565b73ffffffffffffffffffffffffffffffffffffffff16146107e9578883815181106107735761077361208c565b6020026020010151602001515160010361079c576107918984611637565b9850600193506107ff565b6107c38984815181106107b1576107b161208c565b6020026020010151602001518261182a565b8984815181106107d5576107d561208c565b602002602001015160200181905250600191505b816107f6576001016106c7565b600091506106c7565b508261081057816001019150610815565b600092505b506106ba565b5050600085518461082c9190612304565b90508067ffffffffffffffff8111156108475761084761205d565b60405190808252806020026020018201604052801561088d57816020015b6040805180820190915260008152606060208201528152602001906001900390816108655790505b5096506000805b82811015610a585785811015610a0c578681815181106108b6576108b661208c565b60200260200101518982815181106108d0576108d061208c565b60200260200101819052506000805b8951811015610a05578981815181106108fa576108fa61208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff168b848151811061092e5761092e61208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff16036109ef5761099989848151811061096a5761096a61208c565b6020026020010151602001518b83815181106109885761098861208c565b602002602001015160200151611a3d565b8b84815181106109ab576109ab61208c565b6020026020010151602001819052506109c48a82611637565b9950600191506109e18b60018d516109dc9190612317565b611637565b9a506109ec8561232a565b94505b816109fc576001016108df565b600091506108df565b5050610a50565b878281518110610a1e57610a1e61208c565b6020026020010151898281518110610a3857610a3861208c565b602002602001018190525081610a4d9061235f565b91505b600101610894565b505050505050505090565b60606000610a6f610518565b805190915060005b81811015610aff578473ffffffffffffffffffffffffffffffffffffffff16838281518110610aa857610aa861208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1603610af757828181518110610ae157610ae161208c565b6020026020010151602001519350505050919050565b600101610a77565b505050919050565b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602081905260409091205460601c9081610c1e576004818101546040517fcdffacc60000000000000000000000000000000000000000000000000000000081527fffffffff0000000000000000000000000000000000000000000000000000000086169281019290925273ffffffffffffffffffffffffffffffffffffffff169063cdffacc690602401602060405180830381865afa158015610bf7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c1b9190612397565b91505b50919050565b6060610c2e611b8b565b905090565b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604081205460601c610197565b6060610c2e610e57565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9060009061ffff1667ffffffffffffffff811115610cfc57610cfc61205d565b604051908082528060200260200182016040528015610d25578160200160208202803683370190505b5092506000805b600284015461ffff16821015610e4d576000818152600185016020526040812054905b6008811015610e385783610d628161235f565b600288015490955061ffff1685119050610e3857600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020889052604090205460601c73ffffffffffffffffffffffffffffffffffffffff8a16819003610e235781898881518110610de457610de461208c565b7fffffffff000000000000000000000000000000000000000000000000000000009092166020928302919091019091015286610e1f8161235f565b9750505b50508080610e309061235f565b915050610d4f565b50508080610e459061235f565b915050610d2c565b5050825250919050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff1667ffffffffffffffff811115610eba57610eba61205d565b604051908082528060200260200182016040528015610f0057816020015b604080518082019091526000815260606020820152815260200190600190039081610ed85790505b50600282015490925060009061ffff1667ffffffffffffffff811115610f2857610f2861205d565b604051908082528060200260200182016040528015610f51578160200160208202803683370190505b50905060008060005b600285015461ffff168210156112d7576000818152600186016020526040812054905b60088110156112c25783610f908161235f565b600289015490955061ffff16851190506112c257600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020899052604081205460601c90805b88811015611148578273ffffffffffffffffffffffffffffffffffffffff168c82815181106110155761101561208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff160361113657838c828151811061104f5761104f61208c565b6020026020010151602001518b838151811061106d5761106d61208c565b602002602001015161ffff16815181106110895761108961208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152505060ff8a82815181106110e9576110e961208c565b602002602001015161ffff16106110ff57600080fd5b8981815181106111115761111161208c565b602002602001018051809190611126906123b4565b61ffff1690525060019150611148565b806111408161235f565b915050610fe4565b508015611157575050506112b0565b818b898151811061116a5761116a61208c565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff909116905260028a015461ffff1667ffffffffffffffff8111156111b0576111b061205d565b6040519080825280602002602001820160405280156111d9578160200160208202803683370190505b508b89815181106111ec576111ec61208c565b602002602001015160200181905250828b898151811061120e5761120e61208c565b60200260200101516020015160008151811061122c5761122c61208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681525050600189898151811061128c5761128c61208c565b61ffff90921660209283029190910190910152876112a98161235f565b9850505050505b806112ba8161235f565b915050610f7d565b505080806112cf9061235f565b915050610f5a565b5060005b8281101561133f5760008482815181106112f7576112f761208c565b602002602001015161ffff16905060008783815181106113195761131961208c565b6020026020010151602001519050818152505080806113379061235f565b9150506112db565b508185525050505090565b60608060006113598786611da0565b8751909150808210156113b857848783815181106113795761137961208c565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250506115df565b60006113c5826001612304565b67ffffffffffffffff8111156113dd576113dd61205d565b604051908082528060200260200182016040528015611406578160200160208202803683370190505b5090506000885160016114199190612304565b67ffffffffffffffff8111156114315761143161205d565b60405190808252806020026020018201604052801561145a578160200160208202803683370190505b50905060005b83811015611539578a818151811061147a5761147a61208c565b60200260200101518382815181106114945761149461208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815250508981815181106114f2576114f261208c565b602002602001015182828151811061150c5761150c61208c565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101611460565b508782848151811061154d5761154d61208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152505086818a51815181106115ad576115ad61208c565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015290945092506115e8915050565b87879350935050505b94509492505050565b6000806115fe8584611da0565b905084518110611612576000915050611630565b8381815181106116245761162461208c565b60200260200101519150505b9392505050565b6060825182106116a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420696e6465780000000000000000000000000000000000000060448201526064015b60405180910390fd5b8251600003611713576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420617272617900000000000000000000000000000000000000604482015260640161169f565b6000600184516117239190612317565b67ffffffffffffffff81111561173b5761173b61205d565b60405190808252806020026020018201604052801561178157816020015b6040805180820190915260008152606060208201528152602001906001900390816117595790505b50805190915060005b8181101561182057848110156117d6578581815181106117ac576117ac61208c565b60200260200101518382815181106117c6576117c661208c565b6020026020010181905250611818565b856117e2826001612304565b815181106117f2576117f261208c565b602002602001015183828151811061180c5761180c61208c565b60200260200101819052505b60010161178a565b5090949350505050565b606082518210611896576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420696e64657800000000000000000000000000000000000000604482015260640161169f565b8251600003611901576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420617272617900000000000000000000000000000000000000604482015260640161169f565b6000600184516119119190612317565b67ffffffffffffffff8111156119295761192961205d565b604051908082528060200260200182016040528015611952578160200160208202803683370190505b50805190915060005b8181101561182057848110156119cd5785818151811061197d5761197d61208c565b60200260200101518382815181106119975761199761208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152611a35565b856119d9826001612304565b815181106119e9576119e961208c565b6020026020010151838281518110611a0357611a0361208c565b7fffffffff00000000000000000000000000000000000000000000000000000000909216602092830291909101909101525b60010161195b565b81518151606091906000611a518284612304565b67ffffffffffffffff811115611a6957611a6961205d565b604051908082528060200260200182016040528015611a92578160200160208202803683370190505b50905060005b83811015611b0557868181518110611ab257611ab261208c565b6020026020010151828281518110611acc57611acc61208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152600101611a98565b5060005b82811015611b8157858181518110611b2357611b2361208c565b6020026020010151828286611b389190612304565b81518110611b4857611b4861208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152600101611b09565b5095945050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff1667ffffffffffffffff811115611bee57611bee61205d565b604051908082528060200260200182016040528015611c17578160200160208202803683370190505b50915060008060005b600284015461ffff16821015611d98576000818152600185016020526040812054905b6008811015611d835783611c568161235f565b600288015490955061ffff1685119050611d8357600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020889052604081205460601c90805b88811015611d19578a8181518110611cc457611cc461208c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611d075760019150611d19565b80611d118161235f565b915050611caa565b508015611d2857505050611d71565b818a8981518110611d3b57611d3b61208c565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015287611d6a8161235f565b9850505050505b80611d7b8161235f565b915050611c43565b50508080611d909061235f565b915050611c20565b505082525090565b8151600090815b81811015611e1e57837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916858281518110611de157611de161208c565b60200260200101517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603611e165791506101979050565b600101611da7565b509392505050565b73ffffffffffffffffffffffffffffffffffffffff81168114611e4857600080fd5b50565b600060208284031215611e5d57600080fd5b813561163081611e26565b6020808252825182820181905260009190848201906040850190845b81811015611ec25783517fffffffff000000000000000000000000000000000000000000000000000000001683529284019291840191600101611e84565b50909695505050505050565b7fffffffff0000000000000000000000000000000000000000000000000000000081168114611e4857600080fd5b600060208284031215611f0e57600080fd5b813561163081611ece565b6020808252825182820181905260009190848201906040850190845b81811015611ec257835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101611f35565b60006020808301818452808551808352604092508286019150828160051b8701018488016000805b8481101561204e578984037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00186528251805173ffffffffffffffffffffffffffffffffffffffff168552880151888501889052805188860181905290890190839060608701905b808310156120395783517fffffffff00000000000000000000000000000000000000000000000000000000168252928b019260019290920191908b0190611ff7565b50978a01979550505091870191600101611f8f565b50919998505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6040805190810167ffffffffffffffff811182821017156120de576120de61205d565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561212b5761212b61205d565b604052919050565b600067ffffffffffffffff82111561214d5761214d61205d565b5060051b60200190565b6000602080838503121561216a57600080fd5b825167ffffffffffffffff8082111561218257600080fd5b818501915085601f83011261219657600080fd5b81516121a96121a482612133565b6120e4565b81815260059190911b830184019084810190888311156121c857600080fd5b8585015b838110156122c8578051858111156121e45760008081fd5b86016040818c037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00181131561221a5760008081fd5b6122226120bb565b8983015161222f81611e26565b815282820151888111156122435760008081fd5b8084019350508c603f8401126122595760008081fd5b898301516122696121a482612133565b81815260059190911b84018301908b8101908f8311156122895760008081fd5b948401945b828610156122b357855194506122a385611ece565b848252948c0194908c019061228e565b838d01525050855250509186019186016121cc565b5098975050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610197576101976122d5565b81810381811115610197576101976122d5565b600081612339576123396122d5565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612390576123906122d5565b5060010190565b6000602082840312156123a957600080fd5b815161163081611e26565b600061ffff8083168181036123cb576123cb6122d5565b600101939250505056fea26469706673582212205959d8d85aad6f29d5fc37d5a52c404c25392cec49195c3b761da0e863e99b0f64736f6c63430008150033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100a35760003560e01c8063adfca15e11610076578063d42139a91161005b578063d42139a914610169578063e3a2f6fe14610171578063f9796ccf1461018457600080fd5b8063adfca15e1461011e578063cdffacc61461013157600080fd5b806301a55022146100a857806301ffc9a7146100d157806352ef6b2c146100f45780637a0ed62714610109575b600080fd5b6100bb6100b6366004611e4b565b61018c565b6040516100c89190611e68565b60405180910390f35b6100e46100df366004611efc565b61019d565b60405190151581526020016100c8565b6100fc610454565b6040516100c89190611f19565b610111610518565b6040516100c89190611f67565b6100bb61012c366004611e4b565b610a63565b61014461013f366004611efc565b610b07565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100c8565b6100fc610c24565b61014461017f366004611efc565b610c33565b610111610c8c565b606061019782610c96565b92915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000148061023057507fffffffff0000000000000000000000000000000000000000000000000000000082167f1f931c1c00000000000000000000000000000000000000000000000000000000145b8061027c57507fffffffff0000000000000000000000000000000000000000000000000000000082167f48e2b09300000000000000000000000000000000000000000000000000000000145b806102c857507fffffffff0000000000000000000000000000000000000000000000000000000082167f4e2312e000000000000000000000000000000000000000000000000000000000145b8061031457507fffffffff0000000000000000000000000000000000000000000000000000000082167f150b7a0200000000000000000000000000000000000000000000000000000000145b8061035f57507fffffffff0000000000000000000000000000000000000000000000000000000082167e23de2900000000000000000000000000000000000000000000000000000000145b806103ab57507fffffffff0000000000000000000000000000000000000000000000000000000082167f1626ba7e00000000000000000000000000000000000000000000000000000000145b806103f757507fffffffff0000000000000000000000000000000000000000000000000000000082167fa4c0ed3600000000000000000000000000000000000000000000000000000000145b806101975750507fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4922602052604090205460ff1690565b60606000610460610518565b80519091508067ffffffffffffffff81111561047e5761047e61205d565b6040519080825280602002602001820160405280156104a7578160200160208202803683370190505b50925060005b81811015610512578281815181106104c7576104c761208c565b6020026020010151600001518482815181106104e5576104e561208c565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526001016104ad565b50505090565b606060007f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f600490810154604080517f7a0ed627000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff90921692637a0ed6279282820192600092908290030181865afa1580156105ac573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526105f29190810190612157565b905060006105fe610e57565b805190915060608060005b838110156106b55760008582815181106106255761062561208c565b60200260200101516020015151905060005b818110156106ab5761069e85858986815181106106565761065661208c565b60200260200101516020015184815181106106735761067361208c565b60200260200101518a878151811061068d5761068d61208c565b60200260200101516000015161134a565b9095509350600101610637565b5050600101610609565b506000805b865181101561081b576000805b8883815181106106d9576106d961208c565b602002602001015160200151518110156107ff57600073ffffffffffffffffffffffffffffffffffffffff1661074687878c878151811061071c5761071c61208c565b60200260200101516020015185815181106107395761073961208c565b60200260200101516115f1565b73ffffffffffffffffffffffffffffffffffffffff16146107e9578883815181106107735761077361208c565b6020026020010151602001515160010361079c576107918984611637565b9850600193506107ff565b6107c38984815181106107b1576107b161208c565b6020026020010151602001518261182a565b8984815181106107d5576107d561208c565b602002602001015160200181905250600191505b816107f6576001016106c7565b600091506106c7565b508261081057816001019150610815565b600092505b506106ba565b5050600085518461082c9190612304565b90508067ffffffffffffffff8111156108475761084761205d565b60405190808252806020026020018201604052801561088d57816020015b6040805180820190915260008152606060208201528152602001906001900390816108655790505b5096506000805b82811015610a585785811015610a0c578681815181106108b6576108b661208c565b60200260200101518982815181106108d0576108d061208c565b60200260200101819052506000805b8951811015610a05578981815181106108fa576108fa61208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff168b848151811061092e5761092e61208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff16036109ef5761099989848151811061096a5761096a61208c565b6020026020010151602001518b83815181106109885761098861208c565b602002602001015160200151611a3d565b8b84815181106109ab576109ab61208c565b6020026020010151602001819052506109c48a82611637565b9950600191506109e18b60018d516109dc9190612317565b611637565b9a506109ec8561232a565b94505b816109fc576001016108df565b600091506108df565b5050610a50565b878281518110610a1e57610a1e61208c565b6020026020010151898281518110610a3857610a3861208c565b602002602001018190525081610a4d9061235f565b91505b600101610894565b505050505050505090565b60606000610a6f610518565b805190915060005b81811015610aff578473ffffffffffffffffffffffffffffffffffffffff16838281518110610aa857610aa861208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1603610af757828181518110610ae157610ae161208c565b6020026020010151602001519350505050919050565b600101610a77565b505050919050565b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602081905260409091205460601c9081610c1e576004818101546040517fcdffacc60000000000000000000000000000000000000000000000000000000081527fffffffff0000000000000000000000000000000000000000000000000000000086169281019290925273ffffffffffffffffffffffffffffffffffffffff169063cdffacc690602401602060405180830381865afa158015610bf7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c1b9190612397565b91505b50919050565b6060610c2e611b8b565b905090565b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604081205460601c610197565b6060610c2e610e57565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9060009061ffff1667ffffffffffffffff811115610cfc57610cfc61205d565b604051908082528060200260200182016040528015610d25578160200160208202803683370190505b5092506000805b600284015461ffff16821015610e4d576000818152600185016020526040812054905b6008811015610e385783610d628161235f565b600288015490955061ffff1685119050610e3857600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020889052604090205460601c73ffffffffffffffffffffffffffffffffffffffff8a16819003610e235781898881518110610de457610de461208c565b7fffffffff000000000000000000000000000000000000000000000000000000009092166020928302919091019091015286610e1f8161235f565b9750505b50508080610e309061235f565b915050610d4f565b50508080610e459061235f565b915050610d2c565b5050825250919050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff1667ffffffffffffffff811115610eba57610eba61205d565b604051908082528060200260200182016040528015610f0057816020015b604080518082019091526000815260606020820152815260200190600190039081610ed85790505b50600282015490925060009061ffff1667ffffffffffffffff811115610f2857610f2861205d565b604051908082528060200260200182016040528015610f51578160200160208202803683370190505b50905060008060005b600285015461ffff168210156112d7576000818152600186016020526040812054905b60088110156112c25783610f908161235f565b600289015490955061ffff16851190506112c257600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020899052604081205460601c90805b88811015611148578273ffffffffffffffffffffffffffffffffffffffff168c82815181106110155761101561208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff160361113657838c828151811061104f5761104f61208c565b6020026020010151602001518b838151811061106d5761106d61208c565b602002602001015161ffff16815181106110895761108961208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152505060ff8a82815181106110e9576110e961208c565b602002602001015161ffff16106110ff57600080fd5b8981815181106111115761111161208c565b602002602001018051809190611126906123b4565b61ffff1690525060019150611148565b806111408161235f565b915050610fe4565b508015611157575050506112b0565b818b898151811061116a5761116a61208c565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff909116905260028a015461ffff1667ffffffffffffffff8111156111b0576111b061205d565b6040519080825280602002602001820160405280156111d9578160200160208202803683370190505b508b89815181106111ec576111ec61208c565b602002602001015160200181905250828b898151811061120e5761120e61208c565b60200260200101516020015160008151811061122c5761122c61208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681525050600189898151811061128c5761128c61208c565b61ffff90921660209283029190910190910152876112a98161235f565b9850505050505b806112ba8161235f565b915050610f7d565b505080806112cf9061235f565b915050610f5a565b5060005b8281101561133f5760008482815181106112f7576112f761208c565b602002602001015161ffff16905060008783815181106113195761131961208c565b6020026020010151602001519050818152505080806113379061235f565b9150506112db565b508185525050505090565b60608060006113598786611da0565b8751909150808210156113b857848783815181106113795761137961208c565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250506115df565b60006113c5826001612304565b67ffffffffffffffff8111156113dd576113dd61205d565b604051908082528060200260200182016040528015611406578160200160208202803683370190505b5090506000885160016114199190612304565b67ffffffffffffffff8111156114315761143161205d565b60405190808252806020026020018201604052801561145a578160200160208202803683370190505b50905060005b83811015611539578a818151811061147a5761147a61208c565b60200260200101518382815181106114945761149461208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815250508981815181106114f2576114f261208c565b602002602001015182828151811061150c5761150c61208c565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101611460565b508782848151811061154d5761154d61208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152505086818a51815181106115ad576115ad61208c565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015290945092506115e8915050565b87879350935050505b94509492505050565b6000806115fe8584611da0565b905084518110611612576000915050611630565b8381815181106116245761162461208c565b60200260200101519150505b9392505050565b6060825182106116a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420696e6465780000000000000000000000000000000000000060448201526064015b60405180910390fd5b8251600003611713576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420617272617900000000000000000000000000000000000000604482015260640161169f565b6000600184516117239190612317565b67ffffffffffffffff81111561173b5761173b61205d565b60405190808252806020026020018201604052801561178157816020015b6040805180820190915260008152606060208201528152602001906001900390816117595790505b50805190915060005b8181101561182057848110156117d6578581815181106117ac576117ac61208c565b60200260200101518382815181106117c6576117c661208c565b6020026020010181905250611818565b856117e2826001612304565b815181106117f2576117f261208c565b602002602001015183828151811061180c5761180c61208c565b60200260200101819052505b60010161178a565b5090949350505050565b606082518210611896576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420696e64657800000000000000000000000000000000000000604482015260640161169f565b8251600003611901576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420617272617900000000000000000000000000000000000000604482015260640161169f565b6000600184516119119190612317565b67ffffffffffffffff8111156119295761192961205d565b604051908082528060200260200182016040528015611952578160200160208202803683370190505b50805190915060005b8181101561182057848110156119cd5785818151811061197d5761197d61208c565b60200260200101518382815181106119975761199761208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152611a35565b856119d9826001612304565b815181106119e9576119e961208c565b6020026020010151838281518110611a0357611a0361208c565b7fffffffff00000000000000000000000000000000000000000000000000000000909216602092830291909101909101525b60010161195b565b81518151606091906000611a518284612304565b67ffffffffffffffff811115611a6957611a6961205d565b604051908082528060200260200182016040528015611a92578160200160208202803683370190505b50905060005b83811015611b0557868181518110611ab257611ab261208c565b6020026020010151828281518110611acc57611acc61208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152600101611a98565b5060005b82811015611b8157858181518110611b2357611b2361208c565b6020026020010151828286611b389190612304565b81518110611b4857611b4861208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152600101611b09565b5095945050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff1667ffffffffffffffff811115611bee57611bee61205d565b604051908082528060200260200182016040528015611c17578160200160208202803683370190505b50915060008060005b600284015461ffff16821015611d98576000818152600185016020526040812054905b6008811015611d835783611c568161235f565b600288015490955061ffff1685119050611d8357600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020889052604081205460601c90805b88811015611d19578a8181518110611cc457611cc461208c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611d075760019150611d19565b80611d118161235f565b915050611caa565b508015611d2857505050611d71565b818a8981518110611d3b57611d3b61208c565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015287611d6a8161235f565b9850505050505b80611d7b8161235f565b915050611c43565b50508080611d909061235f565b915050611c20565b505082525090565b8151600090815b81811015611e1e57837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916858281518110611de157611de161208c565b60200260200101517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603611e165791506101979050565b600101611da7565b509392505050565b73ffffffffffffffffffffffffffffffffffffffff81168114611e4857600080fd5b50565b600060208284031215611e5d57600080fd5b813561163081611e26565b6020808252825182820181905260009190848201906040850190845b81811015611ec25783517fffffffff000000000000000000000000000000000000000000000000000000001683529284019291840191600101611e84565b50909695505050505050565b7fffffffff0000000000000000000000000000000000000000000000000000000081168114611e4857600080fd5b600060208284031215611f0e57600080fd5b813561163081611ece565b6020808252825182820181905260009190848201906040850190845b81811015611ec257835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101611f35565b60006020808301818452808551808352604092508286019150828160051b8701018488016000805b8481101561204e578984037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00186528251805173ffffffffffffffffffffffffffffffffffffffff168552880151888501889052805188860181905290890190839060608701905b808310156120395783517fffffffff00000000000000000000000000000000000000000000000000000000168252928b019260019290920191908b0190611ff7565b50978a01979550505091870191600101611f8f565b50919998505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6040805190810167ffffffffffffffff811182821017156120de576120de61205d565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561212b5761212b61205d565b604052919050565b600067ffffffffffffffff82111561214d5761214d61205d565b5060051b60200190565b6000602080838503121561216a57600080fd5b825167ffffffffffffffff8082111561218257600080fd5b818501915085601f83011261219657600080fd5b81516121a96121a482612133565b6120e4565b81815260059190911b830184019084810190888311156121c857600080fd5b8585015b838110156122c8578051858111156121e45760008081fd5b86016040818c037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00181131561221a5760008081fd5b6122226120bb565b8983015161222f81611e26565b815282820151888111156122435760008081fd5b8084019350508c603f8401126122595760008081fd5b898301516122696121a482612133565b81815260059190911b84018301908b8101908f8311156122895760008081fd5b948401945b828610156122b357855194506122a385611ece565b848252948c0194908c019061228e565b838d01525050855250509186019186016121cc565b5098975050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610197576101976122d5565b81810381811115610197576101976122d5565b600081612339576123396122d5565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612390576123906122d5565b5060010190565b6000602082840312156123a957600080fd5b815161163081611e26565b600061ffff8083168181036123cb576123cb6122d5565b600101939250505056fea26469706673582212205959d8d85aad6f29d5fc37d5a52c404c25392cec49195c3b761da0e863e99b0f64736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "DiamondLoupe contract compatible with EIP-2535", + "kind": "dev", + "methods": { + "facetAddress(bytes4)": { + "details": "If facet is not found return address(0).", + "params": { + "_functionSelector": "The function selector." + }, + "returns": { + "facetAddress_": "The facet address." + } + }, + "facetAddressFromStorage(bytes4)": { + "params": { + "_functionSelector": "Function selector to fetch the facet address from diamond storage" + }, + "returns": { + "facetAddress_": "Facet address mapped with the function selector" + } + }, + "facetAddresses()": { + "returns": { + "facetAddresses_": "facetAddresses_" + } + }, + "facetAddressesFromStorage()": { + "returns": { + "facetAddresses_": "All facet addresses attached directly to diamond storage" + } + }, + "facetFunctionSelectors(address)": { + "params": { + "_facet": "The facet address." + }, + "returns": { + "facetFunctionSelectors_": "facetFunctionSelectors_" + } + }, + "facetFunctionSelectorsFromStorage(address)": { + "params": { + "_facet": "Facet address to fetch the facet function selectors from diamond storage" + }, + "returns": { + "facetFunctionSelectors_": "Facet function selectors of the given facet address" + } + }, + "facets()": { + "details": "Barz uses a special architecture called default fallback handler. Default Fallback handler is used as a middleware that holds the mapping of facet function selector and facet address that Barz uses. This helps Barz to reduce significant amount of gas during the initialization process. Hence, this method aggregates both the facet information from DefaulFallbackHandler and in diamond storage and shows the data to users.", + "returns": { + "facets_": "Facet" + } + }, + "facetsFromStorage()": { + "returns": { + "facets_": "Facet information attached directly to diamond storage" + } + }, + "supportsInterface(bytes4)": { + "params": { + "_interfaceId": "Interface ID for detecting the interface" + }, + "returns": { + "isSupported": "Bool value showing if the standard is supported in the contract" + } + } + }, + "title": "DiamondLoupe Facet", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "facetAddress(bytes4)": { + "notice": "Gets the facet that supports the given selector." + }, + "facetAddressFromStorage(bytes4)": { + "notice": "Returns the facet address attached to the given function selector. This excludes the facets from the default fallback handler" + }, + "facetAddresses()": { + "notice": "Get all the facet addresses used by Barz." + }, + "facetAddressesFromStorage()": { + "notice": "Returns all facet addresses attached directly to diamond storage. This excludes the facets from the default fallback handler" + }, + "facetFunctionSelectors(address)": { + "notice": "Gets all the function selectors provided by a facet." + }, + "facetFunctionSelectorsFromStorage(address)": { + "notice": "Returns function selectors of given facet address attached directly to diamond storage. This excludes the facets from the default fallback handler" + }, + "facets()": { + "notice": "Gets all facets and their selectors." + }, + "facetsFromStorage()": { + "notice": "Returns the facet from the diamond storage. This excludes the facets from the default fallback handler" + }, + "supportsInterface(bytes4)": { + "notice": "SupportInterface to be compatible with EIP 165" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/blast/Secp256r1VerificationFacet.json b/deployments/blast/Secp256r1VerificationFacet.json new file mode 100644 index 0000000..f3ef2bd --- /dev/null +++ b/deployments/blast/Secp256r1VerificationFacet.json @@ -0,0 +1,483 @@ +{ + "address": "0xeE1AF8E967eC04C84711842796A5E714D2FD33e6", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "LibAppStorage__AccountMustBeUninitialized", + "type": "error" + }, + { + "inputs": [], + "name": "LibAppStorage__SignerAlreadyUninitialized", + "type": "error" + }, + { + "inputs": [], + "name": "LibAppStorage__SignerMustBeUninitialized", + "type": "error" + }, + { + "inputs": [], + "name": "Secp256r1VerificationFacet__InvalidSignerLength", + "type": "error" + }, + { + "inputs": [], + "name": "VerificationFacet__InitializationFailure", + "type": "error" + }, + { + "inputs": [], + "name": "VerificationFacet__InvalidFacetMapping", + "type": "error" + }, + { + "inputs": [], + "name": "VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet", + "type": "error" + }, + { + "inputs": [], + "name": "VerificationFacet__ValidateOwnerSignatureSelectorNotSet", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "SignerInitialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "SignerUninitialized", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_publicKey", + "type": "bytes" + } + ], + "name": "initializeSigner", + "outputs": [ + { + "internalType": "uint256", + "name": "initSuccess", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_publicKey", + "type": "bytes" + } + ], + "name": "isValidKeyType", + "outputs": [ + { + "internalType": "bool", + "name": "isValid", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_hash", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "_signature", + "type": "bytes" + } + ], + "name": "isValidSignature", + "outputs": [ + { + "internalType": "bytes4", + "name": "magicValue", + "type": "bytes4" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "bytes", + "name": "signer", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "self", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "uninitializeSigner", + "outputs": [ + { + "internalType": "uint256", + "name": "uninitSuccess", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "initCode", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "callGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "verificationGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "preVerificationGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxFeePerGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPriorityFeePerGas", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "paymasterAndData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "internalType": "struct UserOperation", + "name": "userOp", + "type": "tuple" + }, + { + "internalType": "bytes32", + "name": "userOpHash", + "type": "bytes32" + } + ], + "name": "validateOwnerSignature", + "outputs": [ + { + "internalType": "uint256", + "name": "validationData", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "validateOwnerSignatureSelector", + "outputs": [ + { + "internalType": "bytes4", + "name": "ownerSignatureValidatorSelector", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "initCode", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "callGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "verificationGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "preVerificationGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxFeePerGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPriorityFeePerGas", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "paymasterAndData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "internalType": "struct UserOperation", + "name": "userOp", + "type": "tuple" + }, + { + "internalType": "bytes32", + "name": "userOpHash", + "type": "bytes32" + }, + { + "internalType": "uint256[2]", + "name": "q", + "type": "uint256[2]" + } + ], + "name": "validateSignature", + "outputs": [ + { + "internalType": "uint256", + "name": "isValid", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0x8b4f59014ccac74aec086d675aee09d62d070128e9baa82524f6ff6d80b1e4d7", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 9, + "gasUsed": "1809741", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x76011e11c82c2d36f42f517e6710d2b0d2eef2ff0088468b9210a17a4da394be", + "transactionHash": "0x8b4f59014ccac74aec086d675aee09d62d070128e9baa82524f6ff6d80b1e4d7", + "logs": [], + "blockNumber": 1317768, + "cumulativeGasUsed": "3193579", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "ad34345aa73d96f52b3e14df983b6b29", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"LibAppStorage__AccountMustBeUninitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LibAppStorage__SignerAlreadyUninitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LibAppStorage__SignerMustBeUninitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Secp256r1VerificationFacet__InvalidSignerLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerificationFacet__InitializationFailure\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerificationFacet__InvalidFacetMapping\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerificationFacet__ValidateOwnerSignatureSelectorNotSet\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"SignerInitialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"SignerUninitialized\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_publicKey\",\"type\":\"bytes\"}],\"name\":\"initializeSigner\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"initSuccess\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_publicKey\",\"type\":\"bytes\"}],\"name\":\"isValidKeyType\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isValid\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_hash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"_signature\",\"type\":\"bytes\"}],\"name\":\"isValidSignature\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"magicValue\",\"type\":\"bytes4\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"signer\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"self\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"uninitializeSigner\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"uninitSuccess\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"userOp\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"}],\"name\":\"validateOwnerSignature\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"validationData\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"validateOwnerSignatureSelector\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"ownerSignatureValidatorSelector\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"userOp\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256[2]\",\"name\":\"q\",\"type\":\"uint256[2]\"}],\"name\":\"validateSignature\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"isValid\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Ruslan Serebriakov (@rsrbk)David Yongjun Kim (@Powerstream3604)\",\"details\":\"Primarily used to verify user ops signed with passkeys\",\"kind\":\"dev\",\"methods\":{\"initializeSigner(bytes)\":{\"details\":\"This method checks if the signer has already been initialized. If already initialized, it reverts. It checks if the public key is in the light format and initializes signer storage in k1 storage.\",\"params\":{\"_publicKey\":\"Bytes of owner public key\"},\"returns\":{\"initSuccess\":\"Uint value representing the success of init operation\"}},\"isValidKeyType(bytes)\":{\"details\":\"For this Secp256k1Verification Facet, the public key should in an uncompressed public key format\",\"params\":{\"_publicKey\":\"Bytes of public key for format check\"},\"returns\":{\"isValid\":\"Boolean variable representing if the format of public key is valid\"}},\"isValidSignature(bytes32,bytes)\":{\"details\":\"This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\",\"params\":{\"_hash\":\"Hash value the owner signed\",\"_signature\":\"Signature that signed the above hash\"},\"returns\":{\"magicValue\":\"Bytes4 value representing the success/failure of validation\"}},\"owner()\":{\"returns\":{\"signer\":\"Bytes of owner address\"}},\"uninitializeSigner()\":{\"details\":\"This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\",\"returns\":{\"uninitSuccess\":\"Uint value representing the success of uninit operation\"}},\"validateOwnerSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32)\":{\"details\":\"This method validates if the user operation is signed by the owner. It internally calls validateSignature with signer public key.\",\"params\":{\"userOp\":\"UserOperation including all information for execution\",\"userOpHash\":\"Hash of UserOperation given from EntryPoint. This hash is used for signature validation\"},\"returns\":{\"validationData\":\"Uint value representing whether the validation is successful. 0 for success, 1 for failure\"}},\"validateOwnerSignatureSelector()\":{\"returns\":{\"ownerSignatureValidatorSelector\":\"Bytes4 selector of function signature to validate account owner's UserOperation signature\"}},\"validateSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256[2])\":{\"details\":\"This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\",\"params\":{\"q\":\"Public Key of signer who signed the contract, to be validated\",\"userOp\":\"UserOperation including all information for execution\",\"userOpHash\":\"Hash of UserOperation given from EntryPoint. This hash is used for signature validation\"},\"returns\":{\"isValid\":\"Uint value representing whether the validation is successful. 0 for success, 1 for failure\"}}},\"title\":\"Secp256r1 verification facet\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"This constructor ensures that this contract can only be used as singleton for Proxy contracts\"},\"initializeSigner(bytes)\":{\"notice\":\"Initializes the signer in R1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\"},\"isValidKeyType(bytes)\":{\"notice\":\"Validates if the format of public key is valid for this verification facet\"},\"isValidSignature(bytes32,bytes)\":{\"notice\":\"Validates if the signature is valid. Function to be compatible with EIP-1271\"},\"owner()\":{\"notice\":\"Returns the owner of the account\"},\"uninitializeSigner()\":{\"notice\":\"Uninitialize signer in R1 Facet Storage. This can only be called when the account is undergoing signature migration and has already been initialized.\"},\"validateOwnerSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32)\":{\"notice\":\"Validates if the user operation is signed by the owner.\"},\"validateOwnerSignatureSelector()\":{\"notice\":\"Returns the selector of function to validate the signature of UserOperation\"},\"validateSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256[2])\":{\"notice\":\"Validates if the signature of UserOperation is signed by the given signer\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/verification/secp256r1/Secp256r1VerificationFacet.sol\":\"Secp256r1VerificationFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/utils/math/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\\n * checks.\\n *\\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\\n * easily result in undesired exploitation or bugs, since developers usually\\n * assume that overflows raise errors. `SafeCast` restores this intuition by\\n * reverting the transaction when such an operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n *\\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\\n * all math on `uint256` and `int256` and then downcasting.\\n */\\nlibrary SafeCast {\\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 * _Available since v4.7._\\n */\\n function toUint248(uint256 value) internal pure returns (uint248) {\\n require(value <= type(uint248).max, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint240(uint256 value) internal pure returns (uint240) {\\n require(value <= type(uint240).max, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint232(uint256 value) internal pure returns (uint232) {\\n require(value <= type(uint232).max, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint224(uint256 value) internal pure returns (uint224) {\\n require(value <= type(uint224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint216(uint256 value) internal pure returns (uint216) {\\n require(value <= type(uint216).max, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint208(uint256 value) internal pure returns (uint208) {\\n require(value <= type(uint208).max, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint200(uint256 value) internal pure returns (uint200) {\\n require(value <= type(uint200).max, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint192(uint256 value) internal pure returns (uint192) {\\n require(value <= type(uint192).max, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint184(uint256 value) internal pure returns (uint184) {\\n require(value <= type(uint184).max, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint176(uint256 value) internal pure returns (uint176) {\\n require(value <= type(uint176).max, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint168(uint256 value) internal pure returns (uint168) {\\n require(value <= type(uint168).max, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint160(uint256 value) internal pure returns (uint160) {\\n require(value <= type(uint160).max, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint152(uint256 value) internal pure returns (uint152) {\\n require(value <= type(uint152).max, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint144(uint256 value) internal pure returns (uint144) {\\n require(value <= type(uint144).max, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint136(uint256 value) internal pure returns (uint136) {\\n require(value <= type(uint136).max, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint128(uint256 value) internal pure returns (uint128) {\\n require(value <= type(uint128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint120(uint256 value) internal pure returns (uint120) {\\n require(value <= type(uint120).max, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint112(uint256 value) internal pure returns (uint112) {\\n require(value <= type(uint112).max, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint104(uint256 value) internal pure returns (uint104) {\\n require(value <= type(uint104).max, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint96(uint256 value) internal pure returns (uint96) {\\n require(value <= type(uint96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint88(uint256 value) internal pure returns (uint88) {\\n require(value <= type(uint88).max, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint80(uint256 value) internal pure returns (uint80) {\\n require(value <= type(uint80).max, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint72(uint256 value) internal pure returns (uint72) {\\n require(value <= type(uint72).max, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint64(uint256 value) internal pure returns (uint64) {\\n require(value <= type(uint64).max, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint56(uint256 value) internal pure returns (uint56) {\\n require(value <= type(uint56).max, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint48(uint256 value) internal pure returns (uint48) {\\n require(value <= type(uint48).max, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint40(uint256 value) internal pure returns (uint40) {\\n require(value <= type(uint40).max, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint32(uint256 value) internal pure returns (uint32) {\\n require(value <= type(uint32).max, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint24(uint256 value) internal pure returns (uint24) {\\n require(value <= type(uint24).max, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint16(uint256 value) internal pure returns (uint16) {\\n require(value <= type(uint16).max, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint8(uint256 value) internal pure returns (uint8) {\\n require(value <= type(uint8).max, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\n */\\n function toUint256(int256 value) internal pure returns (uint256) {\\n require(value >= 0, \\\"SafeCast: value must be positive\\\");\\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 * _Available since v4.7._\\n */\\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\\n downcasted = int248(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\\n downcasted = int240(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\\n downcasted = int232(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\\n downcasted = int224(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\\n downcasted = int216(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\\n downcasted = int208(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\\n downcasted = int200(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\\n downcasted = int192(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\\n downcasted = int184(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\\n downcasted = int176(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\\n downcasted = int168(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\\n downcasted = int160(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\\n downcasted = int152(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\\n downcasted = int144(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\\n downcasted = int136(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\\n downcasted = int128(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\\n downcasted = int120(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\\n downcasted = int112(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\\n downcasted = int104(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\\n downcasted = int96(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\\n downcasted = int88(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\\n downcasted = int80(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\\n downcasted = int72(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\\n downcasted = int64(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\\n downcasted = int56(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\\n downcasted = int48(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\\n downcasted = int40(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\\n downcasted = int32(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\\n downcasted = int24(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\\n downcasted = int16(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\\n downcasted = int8(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\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 require(value <= uint256(type(int256).max), \\\"SafeCast: value doesn't fit in an int256\\\");\\n return int256(value);\\n }\\n}\\n\",\"keccak256\":\"0x52a8cfb0f5239d11b457dcdd1b326992ef672714ca8da71a157255bddd13f3ad\",\"license\":\"MIT\"},\"contracts/aa-4337/core/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable no-inline-assembly */\\n\\n/**\\n * returned data from validateUserOp.\\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\\n * @param aggregator - address(0) - the account validated the signature by itself.\\n * address(1) - the account failed to validate the signature.\\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\\n * @param validAfter - this UserOp is valid only after this timestamp.\\n * @param validaUntil - this UserOp is valid only up to this timestamp.\\n */\\nstruct ValidationData {\\n address aggregator;\\n uint48 validAfter;\\n uint48 validUntil;\\n}\\n\\n//extract sigFailed, validAfter, validUntil.\\n// also convert zero validUntil to type(uint48).max\\nfunction _parseValidationData(\\n uint validationData\\n) pure returns (ValidationData memory data) {\\n address aggregator = address(uint160(validationData));\\n uint48 validUntil = uint48(validationData >> 160);\\n if (validUntil == 0) {\\n validUntil = type(uint48).max;\\n }\\n uint48 validAfter = uint48(validationData >> (48 + 160));\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n// intersect account and paymaster ranges.\\nfunction _intersectTimeRange(\\n uint256 validationData,\\n uint256 paymasterValidationData\\n) pure returns (ValidationData memory) {\\n ValidationData memory accountValidationData = _parseValidationData(\\n validationData\\n );\\n ValidationData memory pmValidationData = _parseValidationData(\\n paymasterValidationData\\n );\\n address aggregator = accountValidationData.aggregator;\\n if (aggregator == address(0)) {\\n aggregator = pmValidationData.aggregator;\\n }\\n uint48 validAfter = accountValidationData.validAfter;\\n uint48 validUntil = accountValidationData.validUntil;\\n uint48 pmValidAfter = pmValidationData.validAfter;\\n uint48 pmValidUntil = pmValidationData.validUntil;\\n\\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp\\n * @param data - the ValidationData to pack\\n */\\nfunction _packValidationData(\\n ValidationData memory data\\n) pure returns (uint256) {\\n return\\n uint160(data.aggregator) |\\n (uint256(data.validUntil) << 160) |\\n (uint256(data.validAfter) << (160 + 48));\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp, when not using an aggregator\\n * @param sigFailed - true for signature failure, false for success\\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\\n * @param validAfter first timestamp this UserOperation is valid\\n */\\nfunction _packValidationData(\\n bool sigFailed,\\n uint48 validUntil,\\n uint48 validAfter\\n) pure returns (uint256) {\\n return\\n (sigFailed ? 1 : 0) |\\n (uint256(validUntil) << 160) |\\n (uint256(validAfter) << (160 + 48));\\n}\\n\\n/**\\n * keccak function over calldata.\\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\\n */\\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\\n assembly {\\n let mem := mload(0x40)\\n let len := data.length\\n calldatacopy(mem, data.offset, len)\\n ret := keccak256(mem, len)\\n }\\n}\\n\",\"keccak256\":\"0xa79f06cd158ecb8c0da95493a2f348933b8627a63e228b99738bff3aa107942d\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAggregator.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\n/**\\n * Aggregated Signatures validator.\\n */\\ninterface IAggregator {\\n /**\\n * validate aggregated signature.\\n * revert if the aggregated signature does not match the given list of operations.\\n */\\n function validateSignatures(\\n UserOperation[] calldata userOps,\\n bytes calldata signature\\n ) external view;\\n\\n /**\\n * validate signature of a single userOp\\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\\n * @param userOp the userOperation received from the user.\\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\\n * (usually empty, unless account and aggregator support some kind of \\\"multisig\\\"\\n */\\n function validateUserOpSignature(\\n UserOperation calldata userOp\\n ) external view returns (bytes memory sigForUserOp);\\n\\n /**\\n * aggregate multiple signatures into a single value.\\n * This method is called off-chain to calculate the signature to pass with handleOps()\\n * bundler MAY use optimized custom code perform this aggregation\\n * @param userOps array of UserOperations to collect the signatures from.\\n * @return aggregatedSignature the aggregated signature\\n */\\n function aggregateSignatures(\\n UserOperation[] calldata userOps\\n ) external view returns (bytes memory aggregatedSignature);\\n}\\n\",\"keccak256\":\"0xdfdcd80568f037716674619b31be630fcd8316262f05a815b41d1e81782c966a\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IEntryPoint.sol\":{\"content\":\"/**\\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\\n ** Only one instance required on each chain.\\n **/\\n// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-inline-assembly */\\n/* solhint-disable reason-string */\\n\\nimport \\\"./UserOperation.sol\\\";\\nimport \\\"./IStakeManager.sol\\\";\\nimport \\\"./IAggregator.sol\\\";\\nimport \\\"./INonceManager.sol\\\";\\n\\ninterface IEntryPoint is IStakeManager, INonceManager {\\n /***\\n * An event emitted after each successful request\\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\\n * @param sender - the account that generates this request.\\n * @param paymaster - if non-null, the paymaster that pays for this request.\\n * @param nonce - the nonce value from the request.\\n * @param success - true if the sender transaction succeeded, false if reverted.\\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\\n */\\n event UserOperationEvent(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address indexed paymaster,\\n uint256 nonce,\\n bool success,\\n uint256 actualGasCost,\\n uint256 actualGasUsed\\n );\\n\\n /**\\n * account \\\"sender\\\" was deployed.\\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\\n * @param sender the account that is deployed\\n * @param factory the factory used to deploy this account (in the initCode)\\n * @param paymaster the paymaster used by this UserOp\\n */\\n event AccountDeployed(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address factory,\\n address paymaster\\n );\\n\\n /**\\n * An event emitted if the UserOperation \\\"callData\\\" reverted with non-zero length\\n * @param userOpHash the request unique identifier.\\n * @param sender the sender of this request\\n * @param nonce the nonce used in the request\\n * @param revertReason - the return bytes from the (reverted) call to \\\"callData\\\".\\n */\\n event UserOperationRevertReason(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n uint256 nonce,\\n bytes revertReason\\n );\\n\\n /**\\n * an event emitted by handleOps(), before starting the execution loop.\\n * any event emitted before this event, is part of the validation.\\n */\\n event BeforeExecution();\\n\\n /**\\n * signature aggregator used by the following UserOperationEvents within this bundle.\\n */\\n event SignatureAggregatorChanged(address indexed aggregator);\\n\\n /**\\n * a custom revert error of handleOps, to identify the offending op.\\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\\n * @param reason - revert reason\\n * The string starts with a unique code \\\"AAmn\\\", where \\\"m\\\" is \\\"1\\\" for factory, \\\"2\\\" for account and \\\"3\\\" for paymaster issues,\\n * so a failure can be attributed to the correct entity.\\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\\n */\\n error FailedOp(uint256 opIndex, string reason);\\n\\n /**\\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\\n */\\n error SignatureValidationFailed(address aggregator);\\n\\n /**\\n * Successful result from simulateValidation.\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n */\\n error ValidationResult(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo\\n );\\n\\n /**\\n * Successful result from simulateValidation, if the account returns a signature aggregator\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\\n * bundler MUST use it to verify the signature, or reject the UserOperation\\n */\\n error ValidationResultWithAggregation(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo,\\n AggregatorStakeInfo aggregatorInfo\\n );\\n\\n /**\\n * return value of getSenderAddress\\n */\\n error SenderAddressResult(address sender);\\n\\n /**\\n * return value of simulateHandleOp\\n */\\n error ExecutionResult(\\n uint256 preOpGas,\\n uint256 paid,\\n uint48 validAfter,\\n uint48 validUntil,\\n bool targetSuccess,\\n bytes targetResult\\n );\\n\\n //UserOps handled, per aggregator\\n struct UserOpsPerAggregator {\\n UserOperation[] userOps;\\n // aggregator address\\n IAggregator aggregator;\\n // aggregated signature\\n bytes signature;\\n }\\n\\n /**\\n * Execute a batch of UserOperation.\\n * no signature aggregator is used.\\n * if any account requires an aggregator (that is, it returned an aggregator when\\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\\n * @param ops the operations to execute\\n * @param beneficiary the address to receive the fees\\n */\\n function handleOps(\\n UserOperation[] calldata ops,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * Execute a batch of UserOperation with Aggregators\\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\\n * @param beneficiary the address to receive the fees\\n */\\n function handleAggregatedOps(\\n UserOpsPerAggregator[] calldata opsPerAggregator,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * generate a request Id - unique identifier for this request.\\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\\n */\\n function getUserOpHash(\\n UserOperation calldata userOp\\n ) external view returns (bytes32);\\n\\n /**\\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\\n * @param userOp the user operation to validate.\\n */\\n function simulateValidation(UserOperation calldata userOp) external;\\n\\n /**\\n * gas and return values during simulation\\n * @param preOpGas the gas used for validation (including preValidationGas)\\n * @param prefund the required prefund for this operation\\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\\n */\\n struct ReturnInfo {\\n uint256 preOpGas;\\n uint256 prefund;\\n bool sigFailed;\\n uint48 validAfter;\\n uint48 validUntil;\\n bytes paymasterContext;\\n }\\n\\n /**\\n * returned aggregated signature info.\\n * the aggregator returned by the account, and its current stake.\\n */\\n struct AggregatorStakeInfo {\\n address aggregator;\\n StakeInfo stakeInfo;\\n }\\n\\n /**\\n * Get counterfactual sender address.\\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\\n * this method always revert, and returns the address in SenderAddressResult error\\n * @param initCode the constructor code to be passed into the UserOperation.\\n */\\n function getSenderAddress(bytes memory initCode) external;\\n\\n /**\\n * simulate full execution of a UserOperation (including both validation and target execution)\\n * this method will always revert with \\\"ExecutionResult\\\".\\n * it performs full validation of the UserOperation, but ignores signature error.\\n * an optional target address is called after the userop succeeds, and its value is returned\\n * (before the entire call is reverted)\\n * Note that in order to collect the the success/failure of the target call, it must be executed\\n * with trace enabled to track the emitted events.\\n * @param op the UserOperation to simulate\\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\\n * are set to the return from that call.\\n * @param targetCallData callData to pass to target address\\n */\\n function simulateHandleOp(\\n UserOperation calldata op,\\n address target,\\n bytes calldata targetCallData\\n ) external;\\n}\\n\",\"keccak256\":\"0x9ccb1b188eda8bbf5f6c2d01bd83c3d8b2b04fcf745283051d31fe96d1d8e40f\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/INonceManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\ninterface INonceManager {\\n /**\\n * Return the next nonce for this sender.\\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\\n * But UserOp with different keys can come with arbitrary order.\\n *\\n * @param sender the account address\\n * @param key the high 192 bit of the nonce\\n * @return nonce a full nonce to pass for next UserOp with this sender.\\n */\\n function getNonce(\\n address sender,\\n uint192 key\\n ) external view returns (uint256 nonce);\\n\\n /**\\n * Manually increment the nonce of the sender.\\n * This method is exposed just for completeness..\\n * Account does NOT need to call it, neither during validation, nor elsewhere,\\n * as the EntryPoint will update the nonce regardless.\\n * Possible use-case is call it with various keys to \\\"initialize\\\" their nonces to one, so that future\\n * UserOperations will not pay extra for the first transaction with a given key.\\n */\\n function incrementNonce(uint192 key) external;\\n}\\n\",\"keccak256\":\"0xce478ad0fa0d18a3b785ac854623029e7ab463d05873dfaa365abfa1bf100912\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IStakeManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8.12;\\n\\n/**\\n * manage deposits and stakes.\\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\\n * stake is value locked for at least \\\"unstakeDelay\\\" by the staked entity.\\n */\\ninterface IStakeManager {\\n event Deposited(address indexed account, uint256 totalDeposit);\\n\\n event Withdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /// Emitted when stake or unstake delay are modified\\n event StakeLocked(\\n address indexed account,\\n uint256 totalStaked,\\n uint256 unstakeDelaySec\\n );\\n\\n /// Emitted once a stake is scheduled for withdrawal\\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\\n\\n event StakeWithdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /**\\n * @param deposit the entity's deposit\\n * @param staked true if this entity is staked.\\n * @param stake actual amount of ether staked for this entity.\\n * @param unstakeDelaySec minimum delay to withdraw the stake.\\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\\n * and the rest fit into a 2nd cell.\\n * 112 bit allows for 10^15 eth\\n * 48 bit for full timestamp\\n * 32 bit allows 150 years for unstake delay\\n */\\n struct DepositInfo {\\n uint112 deposit;\\n bool staked;\\n uint112 stake;\\n uint32 unstakeDelaySec;\\n uint48 withdrawTime;\\n }\\n\\n //API struct used by getStakeInfo and simulateValidation\\n struct StakeInfo {\\n uint256 stake;\\n uint256 unstakeDelaySec;\\n }\\n\\n /// @return info - full deposit information of given account\\n function getDepositInfo(\\n address account\\n ) external view returns (DepositInfo memory info);\\n\\n /// @return the deposit (for gas payment) of the account\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * add to the deposit of the given account\\n */\\n function depositTo(address account) external payable;\\n\\n /**\\n * add to the account's stake - amount and delay\\n * any pending unstake is first cancelled.\\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\\n */\\n function addStake(uint32 _unstakeDelaySec) external payable;\\n\\n /**\\n * attempt to unlock the stake.\\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\\n */\\n function unlockStake() external;\\n\\n /**\\n * withdraw from the (unlocked) stake.\\n * must first call unlockStake and wait for the unstakeDelay to pass\\n * @param withdrawAddress the address to send withdrawn value.\\n */\\n function withdrawStake(address payable withdrawAddress) external;\\n\\n /**\\n * withdraw from the deposit.\\n * @param withdrawAddress the address to send withdrawn value.\\n * @param withdrawAmount the amount to withdraw.\\n */\\n function withdrawTo(\\n address payable withdrawAddress,\\n uint256 withdrawAmount\\n ) external;\\n}\\n\",\"keccak256\":\"0xadcea606c9b7aafe6645441f2154a60f271330b0eee5292a632aa71c1672d546\",\"license\":\"GPL-3.0-only\"},\"contracts/aa-4337/interfaces/UserOperation.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable no-inline-assembly */\\n\\nimport {calldataKeccak} from \\\"../core/Helpers.sol\\\";\\n\\n/**\\n * User Operation struct\\n * @param sender the sender account of this request.\\n * @param nonce unique value the sender uses to verify it is not a replay.\\n * @param initCode if set, the account contract will be created by this constructor/\\n * @param callData the method call to execute on this account.\\n * @param callGasLimit the gas limit passed to the callData method call.\\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\\n * @param maxFeePerGas same as EIP-1559 gas parameter.\\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\\n */\\nstruct UserOperation {\\n address sender;\\n uint256 nonce;\\n bytes initCode;\\n bytes callData;\\n uint256 callGasLimit;\\n uint256 verificationGasLimit;\\n uint256 preVerificationGas;\\n uint256 maxFeePerGas;\\n uint256 maxPriorityFeePerGas;\\n bytes paymasterAndData;\\n bytes signature;\\n}\\n\\n/**\\n * Utility functions helpful when working with UserOperation structs.\\n */\\nlibrary UserOperationLib {\\n function getSender(\\n UserOperation calldata userOp\\n ) internal pure returns (address) {\\n address data;\\n //read sender from userOp, which is first userOp member (saves 800 gas...)\\n assembly {\\n data := calldataload(userOp)\\n }\\n return address(uint160(data));\\n }\\n\\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\\n // pay above what he signed for.\\n function gasPrice(\\n UserOperation calldata userOp\\n ) internal view returns (uint256) {\\n unchecked {\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n if (maxFeePerGas == maxPriorityFeePerGas) {\\n //legacy mode (for networks that don't support basefee opcode)\\n return maxFeePerGas;\\n }\\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\\n }\\n }\\n\\n function pack(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes memory ret) {\\n address sender = getSender(userOp);\\n uint256 nonce = userOp.nonce;\\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\\n bytes32 hashCallData = calldataKeccak(userOp.callData);\\n uint256 callGasLimit = userOp.callGasLimit;\\n uint256 verificationGasLimit = userOp.verificationGasLimit;\\n uint256 preVerificationGas = userOp.preVerificationGas;\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\\n\\n return\\n abi.encode(\\n sender,\\n nonce,\\n hashInitCode,\\n hashCallData,\\n callGasLimit,\\n verificationGasLimit,\\n preVerificationGas,\\n maxFeePerGas,\\n maxPriorityFeePerGas,\\n hashPaymasterAndData\\n );\\n }\\n\\n function hash(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes32) {\\n return keccak256(pack(userOp));\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n}\\n\",\"keccak256\":\"0x2429f5cc546bdee08c7e63858d0dda8491eaa3ab5194df884dc948c1154d2834\",\"license\":\"GPL-3.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/facets/interfaces/IVerificationFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {UserOperation} from \\\"../../aa-4337/interfaces/UserOperation.sol\\\";\\n\\n/**\\n * @title Verification Facet Interface\\n * @dev Implements logic for user ops signature verification\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\ninterface IVerificationFacet {\\n event SignerInitialized(bytes);\\n event SignerUninitialized();\\n\\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\\n error VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\\n error VerificationFacet__InitializationFailure();\\n error VerificationFacet__InvalidFacetMapping();\\n\\n function initializeSigner(bytes memory) external returns (uint256);\\n\\n function uninitializeSigner() external returns (uint256);\\n\\n function validateOwnerSignatureSelector() external view returns (bytes4);\\n\\n function owner() external view returns (bytes memory);\\n\\n function isValidKeyType(bytes calldata) external view returns (bool);\\n\\n function validateOwnerSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x72bc370a1d1b5a6d6bde67f5026733fd8f6ba434bb90e73b0bd8627fb1579928\",\"license\":\"Apache-2.0\"},\"contracts/facets/verification/secp256r1/Secp256r1VerificationFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {UserOperation} from \\\"../../../aa-4337/interfaces/UserOperation.sol\\\";\\nimport {LibAppStorage} from \\\"../../../libraries/LibAppStorage.sol\\\";\\nimport {LibLoupe} from \\\"../../../libraries/LibLoupe.sol\\\";\\nimport {LibFacetStorage, Secp256r1VerificationStorage} from \\\"../../../libraries/LibFacetStorage.sol\\\";\\nimport {Base64} from \\\"./utils/Base64.sol\\\";\\nimport {LibSecp256r1} from \\\"./utils/LibSecp256r1.sol\\\";\\nimport {IERC1271} from \\\"../../../interfaces/ERC/IERC1271.sol\\\";\\nimport {IVerificationFacet} from \\\"../../interfaces/IVerificationFacet.sol\\\";\\n\\n/**\\n * @title Secp256r1 verification facet\\n * @dev Primarily used to verify user ops signed with passkeys\\n * @author Ruslan Serebriakov (@rsrbk)\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract Secp256r1VerificationFacet is IVerificationFacet, IERC1271 {\\n error Secp256r1VerificationFacet__InvalidSignerLength();\\n address public immutable self;\\n\\n /**\\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\\n */\\n constructor() {\\n LibAppStorage.enforceSignerInitialize();\\n self = address(this);\\n }\\n\\n /**\\n * @notice Initializes the signer in R1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\\n * @param _publicKey Bytes of owner public key\\n * @return initSuccess Uint value representing the success of init operation\\n */\\n function initializeSigner(\\n bytes calldata _publicKey\\n ) public override returns (uint256 initSuccess) {\\n LibAppStorage.enforceSignerInitialize();\\n\\n if (!isValidKeyType(_publicKey))\\n revert Secp256r1VerificationFacet__InvalidSignerLength();\\n\\n bytes memory publicKeyCoordinates = _publicKey[1:];\\n uint256[2] memory q;\\n assembly {\\n // Copy the bytes from the input data into the uint256 array\\n mstore(q, mload(add(publicKeyCoordinates, 32)))\\n mstore(add(q, 32), mload(add(publicKeyCoordinates, 64)))\\n }\\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\\n .r1Storage();\\n r1Storage.q = q;\\n\\n bytes4 validateSelector = validateOwnerSignatureSelector();\\n\\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\\n if (LibLoupe.facetAddress(validateSelector) != self)\\n revert VerificationFacet__InvalidFacetMapping();\\n\\n // initialize verification function selector\\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\\n\\n initSuccess = 1;\\n\\n emit SignerInitialized(_publicKey);\\n }\\n\\n /**\\n * @notice Uninitialize signer in R1 Facet Storage. This can only be called when the account is undergoing signature migration\\n * and has already been initialized.\\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\\n * @return uninitSuccess Uint value representing the success of uninit operation\\n */\\n function uninitializeSigner()\\n external\\n override\\n returns (uint256 uninitSuccess)\\n {\\n LibAppStorage.enforceSignerMigration();\\n LibAppStorage.setSignerUninitialized();\\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\\n .r1Storage();\\n r1Storage.q = [0, 0];\\n\\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\\n\\n uninitSuccess = 1;\\n\\n emit SignerUninitialized();\\n }\\n\\n /**\\n * @notice Validates if the user operation is signed by the owner.\\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\\n * signer public key.\\n * @param userOp UserOperation including all information for execution\\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\\n */\\n function validateOwnerSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) public view override returns (uint256 validationData) {\\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\\n .r1Storage();\\n validationData = validateSignature(userOp, userOpHash, r1Storage.q);\\n }\\n\\n /**\\n * @notice Validates if the signature of UserOperation is signed by the given signer\\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\\n * @param userOp UserOperation including all information for execution\\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\\n * @param q Public Key of signer who signed the contract, to be validated\\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\\n */\\n function validateSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n uint256[2] memory q\\n ) public view returns (uint256 isValid) {\\n isValid = (_validateSignature(q, userOpHash, userOp.signature)) ? 0 : 1;\\n }\\n\\n /**\\n * @notice Returns the selector of function to validate the signature of UserOperation\\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\\n */\\n function validateOwnerSignatureSelector()\\n public\\n pure\\n override\\n returns (bytes4 ownerSignatureValidatorSelector)\\n {\\n return this.validateOwnerSignature.selector; // validateOwnerSignature(UserOperation calldata userOp,bytes32 userOpHash)\\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\\n }\\n\\n /**\\n * @notice Returns the owner of the account\\n * @return signer Bytes of owner address\\n */\\n function owner() public view override returns (bytes memory signer) {\\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\\n .r1Storage();\\n signer = abi.encodePacked(r1Storage.q);\\n }\\n\\n /**\\n * @notice Validates if the format of public key is valid for this verification facet\\n * @dev For this Secp256k1Verification Facet, the public key should in an uncompressed public key format\\n * @param _publicKey Bytes of public key for format check\\n * @return isValid Boolean variable representing if the format of public key is valid\\n */\\n function isValidKeyType(\\n bytes memory _publicKey\\n ) public pure override returns (bool isValid) {\\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\\n }\\n\\n /**\\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\\n * @param _hash Hash value the owner signed\\n * @param _signature Signature that signed the above hash\\n * @return magicValue Bytes4 value representing the success/failure of validation\\n */\\n function isValidSignature(\\n bytes32 _hash,\\n bytes memory _signature\\n ) public view override returns (bytes4 magicValue) {\\n magicValue = _validateSignature(\\n LibFacetStorage.r1Storage().q,\\n _hash,\\n _signature\\n )\\n ? this.isValidSignature.selector\\n : bytes4(0xffffffff);\\n }\\n\\n function _validateSignature(\\n uint256[2] memory q,\\n bytes32 _hash,\\n bytes memory _signature\\n ) internal view returns (bool) {\\n (\\n uint256 rValue,\\n uint256 sValue,\\n bytes memory authenticatorData,\\n string memory clientDataJSONPre,\\n string memory clientDataJSONPost\\n ) = abi.decode(_signature, (uint256, uint256, bytes, string, string));\\n bytes32 clientHash;\\n {\\n string memory opHashBase64 = Base64.encode(bytes.concat(_hash));\\n string memory clientDataJSON = string.concat(\\n clientDataJSONPre,\\n opHashBase64,\\n clientDataJSONPost\\n );\\n clientHash = sha256(bytes(clientDataJSON));\\n }\\n bytes32 sigHash = sha256(bytes.concat(authenticatorData, clientHash));\\n return LibSecp256r1.Verify(q, rValue, sValue, uint256(sigHash));\\n }\\n}\\n\",\"keccak256\":\"0xdb3bae77323eef4e16ef5a5342f548527c9e82b44e8e9dab90906dc2c00082ff\",\"license\":\"Apache-2.0\"},\"contracts/facets/verification/secp256r1/utils/Base64.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @dev Provides a set of functions to operate with Base64 strings.\\n * modified for base64url https://datatracker.ietf.org/doc/html/rfc4648#section-5\\n * _Available since v4.5._\\n */\\nlibrary Base64 {\\n /**\\n * @dev Base64 Encoding/Decoding Table\\n */\\n string internal constant _TABLE =\\n \\\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_\\\";\\n\\n /**\\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\\n */\\n function encode(bytes memory data) internal pure returns (string memory) {\\n /**\\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\\n */\\n if (data.length == 0) return \\\"\\\";\\n\\n // Loads the table into memory\\n string memory table = _TABLE;\\n\\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\\n // and split into 4 numbers of 6 bits.\\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\\n // - `data.length + 2` -> Round up\\n // - `/ 3` -> Number of 3-bytes chunks\\n // - `4 *` -> 4 characters for each chunk\\n uint256 newlength = (data.length * 8) / 6;\\n if (data.length % 6 > 0) {\\n newlength++;\\n }\\n string memory result = new string(newlength);\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n // Prepare the lookup table (skip the first \\\"length\\\" byte)\\n let tablePtr := add(table, 1)\\n\\n // Prepare result pointer, jump over length\\n let resultPtr := add(result, 32)\\n\\n // Run over the input, 3 bytes at a time\\n for {\\n let dataPtr := data\\n let endPtr := add(data, mload(data))\\n } lt(dataPtr, endPtr) {\\n\\n } {\\n // Advance 3 bytes\\n dataPtr := add(dataPtr, 3)\\n let input := mload(dataPtr)\\n\\n // To write each character, shift the 3 bytes (18 bits) chunk\\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\\n // and apply logical AND with 0x3F which is the number of\\n // the previous character in the ASCII table prior to the Base64 Table\\n // The result is then added to the table to get the character to write,\\n // and finally write it in the result pointer but with a left shift\\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\\n\\n mstore8(\\n resultPtr,\\n mload(add(tablePtr, and(shr(18, input), 0x3F)))\\n )\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(\\n resultPtr,\\n mload(add(tablePtr, and(shr(12, input), 0x3F)))\\n )\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(\\n resultPtr,\\n mload(add(tablePtr, and(shr(6, input), 0x3F)))\\n )\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n }\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0xbf0afa21e5a128f260c1a8d4333dc0b0e8755a50d37dfa9b5d362d36ef9cdc14\",\"license\":\"Apache-2.0\"},\"contracts/facets/verification/secp256r1/utils/LibSecp256r1.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n// Heavily inspired from\\n// https://github.com/maxrobot/elliptic-solidity/blob/master/contracts/Secp256r1.sol\\n// https://github.com/tdrerup/elliptic-curve-solidity/blob/master/contracts/curves/EllipticCurve.sol\\n// modified to use precompile 0x05 modexp\\n// and modified jacobian double\\n// optimisations to avoid to an from from affine and jacobian coordinates\\n\\n// Additional Elliptic curve Public key / Signature validation added by\\n// David Yonjun Kim (@Powerstream3604)\\n\\nstruct JPoint {\\n uint256 x;\\n uint256 y;\\n uint256 z;\\n}\\n\\nlibrary LibSecp256r1 {\\n uint256 constant gx =\\n 0x6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296;\\n uint256 constant gy =\\n 0x4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5;\\n uint256 public constant pp =\\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF;\\n\\n uint256 public constant nn =\\n 0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551;\\n uint256 constant a =\\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC;\\n uint256 constant b =\\n 0x5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B;\\n uint256 constant MOST_SIGNIFICANT =\\n 0xc000000000000000000000000000000000000000000000000000000000000000;\\n\\n /*\\n * Verify\\n * @description - verifies that a public key has signed a given message\\n * @param Q - public key coordinates X & Y\\n * @param R - signature half R\\n * @param S - signature half S\\n * @param input - hashed message\\n */\\n function Verify(\\n uint256[2] memory q,\\n uint r,\\n uint s,\\n uint e\\n ) internal view returns (bool) {\\n if (q[0] > pp - 1 || q[1] > pp - 1) {\\n return false;\\n }\\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\\n return false;\\n }\\n if (\\n mulmod(q[1], q[1], pp) !=\\n addmod(\\n addmod(\\n mulmod(q[0], mulmod(q[0], q[0], pp), pp),\\n mulmod(a, q[0], pp),\\n pp\\n ),\\n b,\\n pp\\n )\\n ) {\\n return false;\\n }\\n\\n JPoint[16] memory points = _preComputeJacobianPoints(q);\\n return VerifyWithPrecompute(points, r, s, e);\\n }\\n\\n function VerifyWithPrecompute(\\n JPoint[16] memory points,\\n uint r,\\n uint s,\\n uint e\\n ) internal view returns (bool) {\\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\\n return false;\\n }\\n\\n uint w = _primemod(s, nn);\\n\\n uint u1 = mulmod(e, w, nn);\\n uint u2 = mulmod(r, w, nn);\\n\\n uint x;\\n uint y;\\n\\n (x, y) = ShamirMultJacobian(points, u1, u2);\\n return (x == r);\\n }\\n\\n /*\\n * Strauss Shamir trick for EC multiplication\\n * https://stackoverflow.com/questions/50993471/ec-scalar-multiplication-with-strauss-shamir-method\\n * we optimise on this a bit to do with 2 bits at a time rather than a single bit\\n * the individual points for a single pass are precomputed\\n * overall this reduces the number of additions while keeping the same number of doublings\\n */\\n function ShamirMultJacobian(\\n JPoint[16] memory points,\\n uint u1,\\n uint u2\\n ) internal view returns (uint, uint) {\\n uint x = 0;\\n uint y = 0;\\n uint z = 0;\\n uint bits = 128;\\n uint index = 0;\\n\\n while (bits > 0) {\\n if (z > 0) {\\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\\n }\\n index =\\n ((u1 & MOST_SIGNIFICANT) >> 252) |\\n ((u2 & MOST_SIGNIFICANT) >> 254);\\n if (index > 0) {\\n (x, y, z) = _jAdd(\\n x,\\n y,\\n z,\\n points[index].x,\\n points[index].y,\\n points[index].z\\n );\\n }\\n u1 <<= 2;\\n u2 <<= 2;\\n bits--;\\n }\\n (x, y) = _affineFromJacobian(x, y, z);\\n return (x, y);\\n }\\n\\n function _preComputeJacobianPoints(\\n uint256[2] memory q\\n ) internal pure returns (JPoint[16] memory points) {\\n points[0] = JPoint(0, 0, 0);\\n points[1] = JPoint(q[0], q[1], 1); // u2\\n points[2] = _jPointDouble(points[1]);\\n points[3] = _jPointAdd(points[1], points[2]);\\n\\n points[4] = JPoint(gx, gy, 1); // u1Points[1]\\n points[5] = _jPointAdd(points[4], points[1]);\\n points[6] = _jPointAdd(points[4], points[2]);\\n points[7] = _jPointAdd(points[4], points[3]);\\n\\n points[8] = _jPointDouble(points[4]); // u1Points[2]\\n points[9] = _jPointAdd(points[8], points[1]);\\n points[10] = _jPointAdd(points[8], points[2]);\\n points[11] = _jPointAdd(points[8], points[3]);\\n\\n points[12] = _jPointAdd(points[4], points[8]); // u1Points[3]\\n points[13] = _jPointAdd(points[12], points[1]);\\n points[14] = _jPointAdd(points[12], points[2]);\\n points[15] = _jPointAdd(points[12], points[3]);\\n }\\n\\n function _jPointAdd(\\n JPoint memory p1,\\n JPoint memory p2\\n ) internal pure returns (JPoint memory) {\\n uint x;\\n uint y;\\n uint z;\\n (x, y, z) = _jAdd(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z);\\n return JPoint(x, y, z);\\n }\\n\\n function _jPointDouble(\\n JPoint memory p\\n ) internal pure returns (JPoint memory) {\\n uint x;\\n uint y;\\n uint z;\\n (x, y, z) = _modifiedJacobianDouble(p.x, p.y, p.z);\\n return JPoint(x, y, z);\\n }\\n\\n /* _affineFromJacobian\\n * @desription returns affine coordinates from a jacobian input follows\\n * golang elliptic/crypto library\\n */\\n function _affineFromJacobian(\\n uint x,\\n uint y,\\n uint z\\n ) internal view returns (uint ax, uint ay) {\\n if (z == 0) {\\n return (0, 0);\\n }\\n\\n uint zinv = _primemod(z, pp);\\n uint zinvsq = mulmod(zinv, zinv, pp);\\n\\n ax = mulmod(x, zinvsq, pp);\\n ay = mulmod(y, mulmod(zinvsq, zinv, pp), pp);\\n }\\n\\n /*\\n * _jAdd\\n * @description performs Jacobian addition as defined below:\\n * http://www.hyperelliptic.org/EFD/g1p/data/shortw/jacobian/addition/add-2007-bl\\n */\\n function _jAdd(\\n uint p1,\\n uint p2,\\n uint p3,\\n uint q1,\\n uint q2,\\n uint q3\\n ) internal pure returns (uint r1, uint r2, uint r3) {\\n if (p3 == 0) {\\n r1 = q1;\\n r2 = q2;\\n r3 = q3;\\n\\n return (r1, r2, r3);\\n } else if (q3 == 0) {\\n r1 = p1;\\n r2 = p2;\\n r3 = p3;\\n\\n return (r1, r2, r3);\\n }\\n\\n assembly {\\n let\\n pd\\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\\n let z1z1 := mulmod(p3, p3, pd) // Z1Z1 = Z1^2\\n let z2z2 := mulmod(q3, q3, pd) // Z2Z2 = Z2^2\\n\\n let u1 := mulmod(p1, z2z2, pd) // U1 = X1*Z2Z2\\n let u2 := mulmod(q1, z1z1, pd) // U2 = X2*Z1Z1\\n\\n let s1 := mulmod(p2, mulmod(z2z2, q3, pd), pd) // S1 = Y1*Z2*Z2Z2\\n let s2 := mulmod(q2, mulmod(z1z1, p3, pd), pd) // S2 = Y2*Z1*Z1Z1\\n\\n let p3q3 := addmod(p3, q3, pd)\\n\\n if lt(u2, u1) {\\n u2 := add(pd, u2) // u2 = u2+pd\\n }\\n let h := sub(u2, u1) // H = U2-U1\\n\\n let i := mulmod(0x02, h, pd)\\n i := mulmod(i, i, pd) // I = (2*H)^2\\n\\n let j := mulmod(h, i, pd) // J = H*I\\n if lt(s2, s1) {\\n s2 := add(pd, s2) // u2 = u2+pd\\n }\\n let rr := mulmod(0x02, sub(s2, s1), pd) // r = 2*(S2-S1)\\n r1 := mulmod(rr, rr, pd) // X3 = R^2\\n\\n let v := mulmod(u1, i, pd) // V = U1*I\\n let j2v := addmod(j, mulmod(0x02, v, pd), pd)\\n if lt(r1, j2v) {\\n r1 := add(pd, r1) // X3 = X3+pd\\n }\\n r1 := sub(r1, j2v)\\n\\n // Y3 = r*(V-X3)-2*S1*J\\n let s12j := mulmod(mulmod(0x02, s1, pd), j, pd)\\n\\n if lt(v, r1) {\\n v := add(pd, v)\\n }\\n r2 := mulmod(rr, sub(v, r1), pd)\\n\\n if lt(r2, s12j) {\\n r2 := add(pd, r2)\\n }\\n r2 := sub(r2, s12j)\\n\\n // Z3 = ((Z1+Z2)^2-Z1Z1-Z2Z2)*H\\n z1z1 := addmod(z1z1, z2z2, pd)\\n j2v := mulmod(p3q3, p3q3, pd)\\n if lt(j2v, z1z1) {\\n j2v := add(pd, j2v)\\n }\\n r3 := mulmod(sub(j2v, z1z1), h, pd)\\n }\\n return (r1, r2, r3);\\n }\\n\\n // Point doubling on the modified jacobian coordinates\\n // http://point-at-infinity.org/ecc/Prime_Curve_Modified_Jacobian_Coordinates.html\\n function _modifiedJacobianDouble(\\n uint x,\\n uint y,\\n uint z\\n ) internal pure returns (uint x3, uint y3, uint z3) {\\n if (y == 0) return (0, 0, 0);\\n assembly {\\n let\\n pd\\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\\n let z2 := mulmod(z, z, pd)\\n let az4 := mulmod(\\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC,\\n mulmod(z2, z2, pd),\\n pd\\n )\\n let y2 := mulmod(y, y, pd)\\n let s := mulmod(0x04, mulmod(x, y2, pd), pd)\\n let u := mulmod(0x08, mulmod(y2, y2, pd), pd)\\n let m := addmod(mulmod(0x03, mulmod(x, x, pd), pd), az4, pd)\\n let twos := mulmod(0x02, s, pd)\\n let m2 := mulmod(m, m, pd)\\n if lt(m2, twos) {\\n m2 := add(pd, m2)\\n }\\n x3 := sub(m2, twos)\\n if lt(s, x3) {\\n s := add(pd, s)\\n }\\n y3 := mulmod(m, sub(s, x3), pd)\\n if lt(y3, u) {\\n y3 := add(pd, y3)\\n }\\n y3 := sub(y3, u)\\n z3 := mulmod(0x02, mulmod(y, z, pd), pd)\\n }\\n }\\n\\n // Fermats little theorem https://en.wikipedia.org/wiki/Fermat%27s_little_theorem\\n // a^(p-1) = 1 mod p\\n // a^(-1) \\u2245 a^(p-2) (mod p)\\n // we then use the precompile bigModExp to compute a^(-1)\\n function _primemod(uint value, uint p) internal view returns (uint ret) {\\n ret = modexp(value, p - 2, p);\\n return ret;\\n }\\n\\n // Wrapper for built-in BigNumber_modexp (contract 0x5) as described here. https://github.com/ethereum/EIPs/pull/198\\n function modexp(\\n uint _base,\\n uint _exp,\\n uint _mod\\n ) internal view returns (uint ret) {\\n // bigModExp(_base, _exp, _mod);\\n assembly {\\n if gt(_base, _mod) {\\n _base := mod(_base, _mod)\\n }\\n // Free memory pointer is always stored at 0x40\\n let freemem := mload(0x40)\\n\\n mstore(freemem, 0x20)\\n mstore(add(freemem, 0x20), 0x20)\\n mstore(add(freemem, 0x40), 0x20)\\n\\n mstore(add(freemem, 0x60), _base)\\n mstore(add(freemem, 0x80), _exp)\\n mstore(add(freemem, 0xa0), _mod)\\n\\n let success := staticcall(14000, 0x5, freemem, 0xc0, freemem, 0x20)\\n switch success\\n case 0 {\\n revert(0x0, 0x0)\\n }\\n default {\\n ret := mload(freemem)\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb53714ba63cddb379ba312c1e7f6a423f4d7a7e34fa1364ec8295cd57d544024\",\"license\":\"GPL-3.0\"},\"contracts/infrastructure/interfaces/IFacetRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Registry Interface\\n * @dev Interface for Facet Registry contract to keep track of facets & function selectors addable to user wallets\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IFacetRegistry {\\n struct FacetRegistryConfig {\\n bytes4[] selectors;\\n mapping(bytes4 => FacetInfo) info;\\n }\\n struct FacetInfo {\\n bool exists;\\n uint128 index;\\n }\\n\\n event FacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] facetSelectors\\n );\\n event FacetFunctionSelectorsRemoved(address facet, bytes4[] facetSelectors);\\n\\n error FacetRegistry__FacetSelectorAlreadyRegistered();\\n error FacetRegistry__UnregisteredFacetSelector();\\n\\n function registerFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function removeFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function areFacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external view returns (bool);\\n\\n function isFacetFunctionSelectorRegistered(\\n address facet,\\n bytes4 facetSelector\\n ) external view returns (bool);\\n\\n function getFacetFunctionSelectors(\\n address facet\\n ) external view returns (bytes4[] memory);\\n}\\n\",\"keccak256\":\"0x6e6dd2cab346ef7c31230740ec48d2925e4a9ab24c2f2fb268baaf408dcf02ef\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC1271 {\\n function isValidSignature(\\n bytes32 hash,\\n bytes memory signature\\n ) external view returns (bytes4);\\n}\\n\",\"keccak256\":\"0xcdddb7d5641c9d3f2432dec7fd13fddb9ae1480f25c76c21511e2fa16b8bd422\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibAppStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {SafeCast} from \\\"@openzeppelin/contracts/utils/math/SafeCast.sol\\\";\\nimport {IEntryPoint} from \\\"../aa-4337/interfaces/IEntryPoint.sol\\\";\\nimport {IFacetRegistry} from \\\"../infrastructure/interfaces/IFacetRegistry.sol\\\";\\n\\n/*\\n * @title App Storage\\n * @dev App storage for Barz contract to prevent storage collision\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Lock {\\n uint64 release;\\n bytes4 locker;\\n}\\n\\nstruct InitializersStorage {\\n // NOTE: initialized is a variable to make sure the initialization is only done once.\\n uint8 signerInitialized;\\n uint8 accountInitialized;\\n uint8 restrictionsInitialized;\\n}\\n\\nstruct AppStorage {\\n mapping(uint256 => InitializersStorage) initStorage;\\n uint8 signerMigration;\\n bytes4 validateOwnerSignatureSelector;\\n IEntryPoint entryPoint;\\n IFacetRegistry facetRegistry;\\n mapping(uint256 => Lock) locks;\\n}\\n\\nlibrary LibAppStorage {\\n error LibAppStorage__AccountAlreadyUninitialized();\\n error LibAppStorage__AccountMustBeUninitialized();\\n error LibAppStorage__SignerAlreadyUninitialized();\\n error LibAppStorage__SignerMustBeUninitialized();\\n\\n function appStorage() internal pure returns (AppStorage storage ds) {\\n assembly {\\n ds.slot := 0\\n }\\n }\\n\\n function setSignerUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerAlreadyUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 0;\\n }\\n\\n function getValidateOwnerSignatureSelector()\\n internal\\n view\\n returns (bytes4 selector)\\n {\\n selector = appStorage().validateOwnerSignatureSelector;\\n }\\n\\n function setValidateOwnerSignatureSelector(\\n bytes4 _validateOwnerSignatureSelector\\n ) internal {\\n appStorage()\\n .validateOwnerSignatureSelector = _validateOwnerSignatureSelector;\\n }\\n\\n function enforceSignerInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerMustBeUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 1;\\n }\\n\\n function enforceAccountInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].accountInitialized) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n s.initStorage[0].accountInitialized = 1;\\n }\\n\\n function initiateSignerMigration() internal {\\n appStorage().signerMigration = 1;\\n }\\n\\n function enforceSignerMigration() internal view {\\n if (1 != appStorage().signerMigration) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n }\\n\\n function finalizeSignerMigration() internal {\\n appStorage().signerMigration = 0;\\n }\\n\\n function setLock(uint256 _releaseAfter, bytes4 _locker) internal {\\n appStorage().locks[0] = Lock(SafeCast.toUint64(_releaseAfter), _locker);\\n }\\n\\n function enforceRestrictionsInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__SignerMustBeUninitialized();\\n s.initStorage[0].restrictionsInitialized = 1;\\n }\\n\\n function setRestrictionsUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__AccountAlreadyUninitialized();\\n s.initStorage[0].restrictionsInitialized = 0;\\n }\\n}\\n\\ncontract BarzStorage {\\n AppStorage internal s;\\n modifier onlyWhenUnlocked() {\\n require(\\n uint64(block.timestamp) >= s.locks[0].release,\\n \\\"Account Locked\\\"\\n );\\n _;\\n }\\n modifier onlyWhenLocked() {\\n require(\\n uint64(block.timestamp) < s.locks[0].release,\\n \\\"Account Unlocked\\\"\\n );\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x48524007862a6ce0e07f645950613ce6513ce073c37a109c75019683d42bae27\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\\n bytes4(keccak256(\\\"verifyRestrictions(address,address,uint256,bytes)\\\"));\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // Default Fallback Handler of the barz.\\n IDiamondLoupe defaultFallbackHandler;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function enforceIsSelf() internal view {\\n require(msg.sender == address(this), \\\"LibDiamond: Caller not self\\\");\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n\\n unchecked {\\n facetIndex++;\\n }\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n\\n function restrictionsFacet() internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(\\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2cabdc00de859c3a3170ce3bda5d0e5fd3933d47ce904fd1585f9818b02572f8\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibFacetStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Storage\\n * @dev Storage contract to store each facets variables with diamond storage\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Secp256k1VerificationStorage {\\n address signer;\\n}\\n\\nstruct Secp256r1VerificationStorage {\\n uint256[2] q;\\n}\\n\\nstruct GuardianStorage {\\n mapping(bytes32 => uint256) pending;\\n mapping(uint8 => StorageConfig) configs;\\n}\\n\\nstruct Info {\\n bool exists;\\n uint128 index;\\n}\\n\\nstruct StorageConfig {\\n address[] addresses;\\n mapping(address => Info) info;\\n}\\n\\nstruct RecoveryConfig {\\n bytes recoveryPublicKey;\\n uint64 executeAfter;\\n}\\n\\nstruct ApprovalConfig {\\n bool isApproved;\\n uint64 validUntil;\\n}\\n\\nstruct RecoveryApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isNewOwnerApproved;\\n}\\n\\nstruct RecoveryStorage {\\n mapping(uint8 => RecoveryConfig) recoveryConfigs;\\n mapping(uint8 => RecoveryApprovalConfig) recoveryApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct RestrictionsStorage {\\n address[] restrictions;\\n mapping(address => bool) exists;\\n}\\n\\nstruct SignatureMigrationConfig {\\n bytes migrationPublicKey;\\n address migrationVerificationFacet;\\n bytes4[] migrationSelectors;\\n uint64 migrateAfter;\\n}\\n\\nstruct SignatureMigrationApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isMigrationApproved;\\n}\\n\\nstruct SignatureMigrationStorage {\\n mapping(uint8 => SignatureMigrationConfig) migrationConfigs;\\n mapping(uint8 => SignatureMigrationApprovalConfig) migrationApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct DiamondCutApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isDiamondCutApproved;\\n}\\n\\nstruct DiamondCutStorage {\\n mapping(uint8 => DiamondCutApprovalConfig) diamondCutApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct LockStorage {\\n uint128 nonce;\\n}\\n\\nlibrary LibFacetStorage {\\n bytes32 constant K1_STORAGE_POSITION =\\n keccak256(\\n \\\"v0.trustwallet.diamond.storage.Secp256k1VerificationStorage\\\"\\n );\\n bytes32 constant R1_STORAGE_POSITION =\\n keccak256(\\n \\\"v0.trustwallet.diamond.storage.Secp256r1VerificationStorage\\\"\\n );\\n bytes32 constant GUARDIAN_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.GuardianStorage\\\");\\n bytes32 constant RECOVERY_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.RecoveryStorage\\\");\\n bytes32 constant RESTRICTION_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.RestrictionsStorage\\\");\\n bytes32 constant MIGRATION_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.SignatureMigrationStorage\\\");\\n bytes32 constant DIAMONDCUT_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.DiamondCutStorage\\\");\\n bytes32 constant LOCK_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.LockStorage\\\");\\n\\n function k1Storage()\\n internal\\n pure\\n returns (Secp256k1VerificationStorage storage ds)\\n {\\n bytes32 storagePosition = K1_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function r1Storage()\\n internal\\n pure\\n returns (Secp256r1VerificationStorage storage ds)\\n {\\n bytes32 storagePosition = R1_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function guardianStorage()\\n internal\\n pure\\n returns (GuardianStorage storage ds)\\n {\\n bytes32 storagePosition = GUARDIAN_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function recoveryStorage()\\n internal\\n pure\\n returns (RecoveryStorage storage ds)\\n {\\n bytes32 storagePosition = RECOVERY_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function restrictionsStorage()\\n internal\\n pure\\n returns (RestrictionsStorage storage ds)\\n {\\n bytes32 storagePosition = RESTRICTION_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function migrationStorage()\\n internal\\n pure\\n returns (SignatureMigrationStorage storage ds)\\n {\\n bytes32 storagePosition = MIGRATION_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function diamondCutStorage()\\n internal\\n pure\\n returns (DiamondCutStorage storage ds)\\n {\\n bytes32 storagePosition = DIAMONDCUT_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function lockStorage() internal pure returns (LockStorage storage ds) {\\n bytes32 storagePosition = LOCK_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n}\\n\",\"keccak256\":\"0x87c85decfd943deda9540733e464cb1a92eba735a301e89ce6f798016e359761\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\nimport {LibDiamond} from \\\"./LibDiamond.sol\\\";\\n\\n/**\\n * @title LibLoupe\\n * @dev Internal Library to provide utility feature for reading the state of diamond facets\\n * Originally from Diamond's implementation of Mudgen(author of EIP-2535)\\n */\\nlibrary LibLoupe {\\n /// @notice Gets all facets and their selectors.\\n /// @return facets_ Facet\\n function facets()\\n internal\\n view\\n returns (IDiamondLoupe.Facet[] memory facets_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facets_ = new IDiamondLoupe.Facet[](ds.selectorCount);\\n uint16[] memory numFacetSelectors = new uint16[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facets_[facetIndex].facetAddress == facetAddress_) {\\n facets_[facetIndex].functionSelectors[\\n numFacetSelectors[facetIndex]\\n ] = selector;\\n // probably will never have more than 256 functions from one facet contract\\n require(numFacetSelectors[facetIndex] < 255);\\n numFacetSelectors[facetIndex]++;\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facets_[numFacets].facetAddress = facetAddress_;\\n facets_[numFacets].functionSelectors = new bytes4[](\\n ds.selectorCount\\n );\\n facets_[numFacets].functionSelectors[0] = selector;\\n numFacetSelectors[numFacets] = 1;\\n numFacets++;\\n }\\n }\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n uint256 numSelectors = numFacetSelectors[facetIndex];\\n bytes4[] memory selectors = facets_[facetIndex].functionSelectors;\\n // setting the number of selectors\\n assembly {\\n mstore(selectors, numSelectors)\\n }\\n }\\n // setting the number of facets\\n assembly {\\n mstore(facets_, numFacets)\\n }\\n }\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return _facetFunctionSelectors The selectors associated with a facet address.\\n function facetFunctionSelectors(\\n address _facet\\n ) internal view returns (bytes4[] memory _facetFunctionSelectors) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n uint256 numSelectors;\\n _facetFunctionSelectors = new bytes4[](ds.selectorCount);\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facet = address(bytes20(ds.facets[selector]));\\n if (_facet == facet) {\\n _facetFunctionSelectors[numSelectors] = selector;\\n numSelectors++;\\n }\\n }\\n }\\n // Set the number of selectors in the array\\n assembly {\\n mstore(_facetFunctionSelectors, numSelectors)\\n }\\n }\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n internal\\n view\\n returns (address[] memory facetAddresses_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetAddresses_ = new address[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facetAddress_ == facetAddresses_[facetIndex]) {\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facetAddresses_[numFacets] = facetAddress_;\\n numFacets++;\\n }\\n }\\n // Set the number of facet addresses in the array\\n assembly {\\n mstore(facetAddresses_, numFacets)\\n }\\n }\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(LibDiamond.diamondStorage().facets[_functionSelector])\\n );\\n }\\n}\\n\",\"keccak256\":\"0x0b11439c3cc657095e15ec2241fdcf67204b14001357b612fc5db4ff9e760a5a\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x60a060405234801561001057600080fd5b50610019610022565b3060805261008b565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff161561006f57604051637c2cde8b60e01b815260040160405180910390fd5b600080805260209190915260409020805460ff19166001179055565b608051611f746100ad6000396000818161016001526106e10152611f746000f3fe608060405234801561001057600080fd5b50600436106100a35760003560e01c80637104ddb2116100765780638dd501211161005b5780638dd50121146101bc578063cd00e50a146101cf578063cd9b47e4146101d757600080fd5b80637104ddb21461015b5780638da5cb5b146101a757600080fd5b806311cfe388146100a85780631626ba7e146100ce5780633253960f14610112578063392dd6d914610138575b600080fd5b6100bb6100b6366004611823565b6101ea565b6040519081526020015b60405180910390f35b6100e16100dc366004611956565b610252565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020016100c5565b7f8dd50121000000000000000000000000000000000000000000000000000000006100e1565b61014b61014636600461199d565b6102fd565b60405190151581526020016100c5565b6101827f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100c5565b6101af61036f565b6040516100c591906119f6565b6100bb6101ca366004611a47565b6103ba565b6100bb61041f565b6100bb6101e5366004611a8c565b61053a565b600061023982846101ff610140880188611afe565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061083692505050565b610244576001610247565b60005b60ff16949350505050565b60006102aa7f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b1653646040805180820191829052919060029082845b81548152602001906001019080831161028b5750505050508484610836565b6102d4577fffffffff000000000000000000000000000000000000000000000000000000006102f6565b7f1626ba7e000000000000000000000000000000000000000000000000000000005b9392505050565b60008151604114801561036957508160008151811061031e5761031e611b6a565b6020910101517fff00000000000000000000000000000000000000000000000000000000000000167f0400000000000000000000000000000000000000000000000000000000000000145b92915050565b6040516060907f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364906103a5908290602001611b99565b60405160208183030381529060405291505090565b60408051808201918290526000917f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364916104179186918691859060029082845b8154815260200190600101908083116103fa5750505050506101ea565b949350505050565b60006104296109b4565b6104316109f4565b60408051808201909152600080825260208201527f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364906104749082906002611675565b506000610488600154610100900460e01b90565b7fffffffff0000000000000000000000000000000000000000000000000000000016036104e1576040517f127c609a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff169055604051600192507fcccd30db6bc000b8bb8d11162228d2d69e3c361983ca3ae8c1365ce64b0fae9e90600090a15090565b6000610544610a93565b61058383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102fd92505050565b6105b9576040517f6c334d2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006105c88360018187611bcd565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092935061060992506116b8915050565b602082015181526040820151602082015260006106437f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b16536490565b9050610651818360026116d6565b507f8dd50121000000000000000000000000000000000000000000000000000000006000610686600154610100900460e01b90565b7fffffffff0000000000000000000000000000000000000000000000000000000016146106df576040517f5f95a63c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16610770827fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604090205460601c90565b73ffffffffffffffffffffffffffffffffffffffff16146107bd576040517fbb4752b700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff1661010060e084901c02179055600194507f6d54821a69ec281ed7ba1bf2729c700768c47df1d80fad646b0a14cc1d5c39ed8787604051610824929190611bf7565b60405180910390a15050505092915050565b600080600080600080868060200190518101906108539190611c94565b9450945094509450945060008061088a8a60405160200161087691815260200190565b604051602081830303815290604052610b33565b905060008482856040516020016108a393929190611d47565b60405160208183030381529060405290506002816040516108c49190611d8a565b602060405180830381855afa1580156108e1573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906109049190611da6565b9250505060006002858360405160200161091f929190611dbf565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905261095791611d8a565b602060405180830381855afa158015610974573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906109979190611da6565b90506109a58b888884610c6f565b9b9a5050505050505050505050565b6001805460ff16146109f2576040517f38fc28cb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff16600114610a5c576040517fe00d7c7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff1615610af9576040517f7c2cde8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b60608151600003610b5257505060408051602081019091526000815290565b6000604051806060016040528060408152602001611eff6040913990506000600684516008610b819190611e10565b610b8b9190611e56565b9050600060068551610b9d9190611e6a565b1115610bb15780610bad81611e7e565b9150505b60008167ffffffffffffffff811115610bcc57610bcc61177c565b6040519080825280601f01601f191660200182016040528015610bf6576020820181803683370190505b509050600183016020820186875188015b80821015610c62576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f8116850151845350600183019250610c07565b5092979650505050505050565b6000610c9c60017fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611eb6565b85511180610cd75750610cd060017fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611eb6565b6020860151115b15610ce457506000610417565b831580610cef575082155b80610d1a57507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518410155b80610d4557507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518310155b15610d5257506000610417565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff7f5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff8088600060200201517fffffffff00000001000000000000000000000000fffffffffffffffffffffffc0988517fffffffff00000001000000000000000000000000ffffffffffffffffffffffff90819080098a5109080860208601517fffffffff00000001000000000000000000000000ffffffffffffffffffffffff90800914610e4357506000610417565b6000610e4e86610e66565b9050610e5c81868686611062565b9695505050505050565b610e6e611704565b60405180606001604052806000815260200160008152602001600081525081600060108110610e9f57610e9f611b6a565b60200201526040805160608101909152808360006020020151815260200183600160028110610ed057610ed0611b6a565b60200201518152602001600181525081600160108110610ef257610ef2611b6a565b6020020152610f088160015b602002015161116f565b6040820152610f278160015b60200201518260025b60200201516111d1565b6060828101919091526040805191820181527f6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c29682527f4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f560208301526001908201526080820152610fa18160045b6020020151826001610f1d565b60a0820152610fb1816004610f14565b60c0820152610fca8160045b6020020151826003610f1d565b60e0820152610fda816004610efe565b610100820152610feb816008610f94565b610120820152610ffc816008610f14565b61014082015261100d816008610fbd565b610160820152608081015161102490826008610f1d565b61018082015261103581600c610f94565b6101a082015261104681600c610f14565b6101c082015261105781600c610fbd565b6101e0820152919050565b600083158061106f575082155b8061109a57507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518410155b806110c557507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518310155b156110d257506000610417565b60006110fe847fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551611243565b905060007fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551828509905060007fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551838809905060008061115e8a858561125a565b509098149998505050505050505050565b61119360405180606001604052806000815260200160008152602001600081525090565b60008060006111af856000015186602001518760400151611346565b6040805160608101825293845260208401929092529082015295945050505050565b6111f560405180606001604052806000815260200160008152602001600081525090565b6000806000611220866000015187602001518860400151886000015189602001518a60400151611424565b604080516060810182529384526020840192909252908201529695505050505050565b60006102f683611254600285611eb6565b8461155c565b6000808080806080815b81156113285782156112955761127b858585611346565b9196509450925061128d858585611346565b919650945092505b50600c60fc89901c1660fe88901c17801561130b576113038585858d85601081106112c2576112c2611b6a565b6020020151518e86601081106112da576112da611b6a565b6020020151602001518f87601081106112f5576112f5611b6a565b602002015160400151611424565b919650945092505b600298891b989790971b968161132081611ec9565b925050611264565b6113338585856115b0565b909750955050505050505b935093915050565b6000806000846000036113615750600091508190508061141b565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff8085860981828283097fffffffff00000001000000000000000000000000fffffffffffffffffffffffc099050818788098283828b0960040983848384096008099150838385868d8e09600309089250838160020984848509818110156113e65785015b039650868110156113f45783015b8387820384099550508085101561140a57938201935b909303925080808688096002099150505b93509350939050565b60008060008660000361143e575084915083905082611550565b83600003611453575087915086905085611550565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff808889098186870982818d0983838b0984858a85098e0985868e87098c09868b8f08848410156114a357928701925b8484039350878460020988818209905088818609848410156114c457928901925b898585036002099350898485099c50898288099650898a8860020982089150818d10156114f0579b89019b5b818d039c5089818b87600209099450508b86101561150d57948801945b888c870384099a50838b101561152257998801995b838b039a508887890897508882830990508781101561153e5788015b88858983030999505050505050505050505b96509650969350505050565b60008184111561156c5781840693505b60405160208152602080820152602060408201528460608201528360808201528260a082015260208160c08360056136b0fa8080156100a357505051949350505050565b600080826000036115c65750600090508061133e565b60006115f2847fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611243565b905060007fffffffff00000001000000000000000000000000ffffffffffffffffffffffff82830990507fffffffff00000001000000000000000000000000ffffffffffffffffffffffff81880993507fffffffff00000001000000000000000000000000ffffffffffffffffffffffff80838309870992505050935093915050565b82600281019282156116a8579160200282015b828111156116a8578251829060ff16905591602001919060010190611688565b506116b492915061174e565b5090565b60405180604001604052806002906020820280368337509192915050565b82600281019282156116a8579160200282015b828111156116a85782518255916020019190600101906116e9565b6040518061020001604052806010905b61173860405180606001604052806000815260200160008152602001600081525090565b8152602001906001900390816117145790505090565b5b808211156116b4576000815560010161174f565b6000610160828403121561177657600080fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156117ce576117ce61177c565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561181b5761181b61177c565b604052919050565b60008060006080848603121561183857600080fd5b833567ffffffffffffffff81111561184f57600080fd5b61185b86828701611763565b935050602080850135925085605f86011261187557600080fd5b61187d6117ab565b80608087018881111561188f57600080fd5b604088015b818110156118ab5780358452928401928401611894565b50508093505050509250925092565b600067ffffffffffffffff8211156118d4576118d461177c565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261191157600080fd5b813561192461191f826118ba565b6117d4565b81815284602083860101111561193957600080fd5b816020850160208301376000918101602001919091529392505050565b6000806040838503121561196957600080fd5b82359150602083013567ffffffffffffffff81111561198757600080fd5b61199385828601611900565b9150509250929050565b6000602082840312156119af57600080fd5b813567ffffffffffffffff8111156119c657600080fd5b61041784828501611900565b60005b838110156119ed5781810151838201526020016119d5565b50506000910152565b6020815260008251806020840152611a158160408501602087016119d2565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b60008060408385031215611a5a57600080fd5b823567ffffffffffffffff811115611a7157600080fd5b611a7d85828601611763565b95602094909401359450505050565b60008060208385031215611a9f57600080fd5b823567ffffffffffffffff80821115611ab757600080fd5b818501915085601f830112611acb57600080fd5b813581811115611ada57600080fd5b866020828501011115611aec57600080fd5b60209290920196919550909350505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112611b3357600080fd5b83018035915067ffffffffffffffff821115611b4e57600080fd5b602001915036819003821315611b6357600080fd5b9250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008183825b6002811015611bbe578154835260209092019160019182019101611b9f565b50505060408201905092915050565b60008085851115611bdd57600080fd5b83861115611bea57600080fd5b5050820193919092039150565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b6000611c5261191f846118ba565b9050828152838383011115611c6657600080fd5b6102f68360208301846119d2565b600082601f830112611c8557600080fd5b6102f683835160208501611c44565b600080600080600060a08688031215611cac57600080fd5b8551945060208601519350604086015167ffffffffffffffff80821115611cd257600080fd5b818801915088601f830112611ce657600080fd5b611cf589835160208501611c44565b94506060880151915080821115611d0b57600080fd5b611d1789838a01611c74565b93506080880151915080821115611d2d57600080fd5b50611d3a88828901611c74565b9150509295509295909350565b60008451611d598184602089016119d2565b845190830190611d6d8183602089016119d2565b8451910190611d808183602088016119d2565b0195945050505050565b60008251611d9c8184602087016119d2565b9190910192915050565b600060208284031215611db857600080fd5b5051919050565b60008351611dd18184602088016119d2565b9190910191825250602001919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808202811582820484141761036957610369611de1565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082611e6557611e65611e27565b500490565b600082611e7957611e79611e27565b500690565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611eaf57611eaf611de1565b5060010190565b8181038181111561036957610369611de1565b600081611ed857611ed8611de1565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392d5fa2646970667358221220d4142da7b16effb6b95f41adeff2bc8ce0d59d3b70ca8d55e6e83224bbfbec0a64736f6c63430008150033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100a35760003560e01c80637104ddb2116100765780638dd501211161005b5780638dd50121146101bc578063cd00e50a146101cf578063cd9b47e4146101d757600080fd5b80637104ddb21461015b5780638da5cb5b146101a757600080fd5b806311cfe388146100a85780631626ba7e146100ce5780633253960f14610112578063392dd6d914610138575b600080fd5b6100bb6100b6366004611823565b6101ea565b6040519081526020015b60405180910390f35b6100e16100dc366004611956565b610252565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020016100c5565b7f8dd50121000000000000000000000000000000000000000000000000000000006100e1565b61014b61014636600461199d565b6102fd565b60405190151581526020016100c5565b6101827f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100c5565b6101af61036f565b6040516100c591906119f6565b6100bb6101ca366004611a47565b6103ba565b6100bb61041f565b6100bb6101e5366004611a8c565b61053a565b600061023982846101ff610140880188611afe565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061083692505050565b610244576001610247565b60005b60ff16949350505050565b60006102aa7f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b1653646040805180820191829052919060029082845b81548152602001906001019080831161028b5750505050508484610836565b6102d4577fffffffff000000000000000000000000000000000000000000000000000000006102f6565b7f1626ba7e000000000000000000000000000000000000000000000000000000005b9392505050565b60008151604114801561036957508160008151811061031e5761031e611b6a565b6020910101517fff00000000000000000000000000000000000000000000000000000000000000167f0400000000000000000000000000000000000000000000000000000000000000145b92915050565b6040516060907f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364906103a5908290602001611b99565b60405160208183030381529060405291505090565b60408051808201918290526000917f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364916104179186918691859060029082845b8154815260200190600101908083116103fa5750505050506101ea565b949350505050565b60006104296109b4565b6104316109f4565b60408051808201909152600080825260208201527f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364906104749082906002611675565b506000610488600154610100900460e01b90565b7fffffffff0000000000000000000000000000000000000000000000000000000016036104e1576040517f127c609a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff169055604051600192507fcccd30db6bc000b8bb8d11162228d2d69e3c361983ca3ae8c1365ce64b0fae9e90600090a15090565b6000610544610a93565b61058383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102fd92505050565b6105b9576040517f6c334d2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006105c88360018187611bcd565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092935061060992506116b8915050565b602082015181526040820151602082015260006106437f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b16536490565b9050610651818360026116d6565b507f8dd50121000000000000000000000000000000000000000000000000000000006000610686600154610100900460e01b90565b7fffffffff0000000000000000000000000000000000000000000000000000000016146106df576040517f5f95a63c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16610770827fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604090205460601c90565b73ffffffffffffffffffffffffffffffffffffffff16146107bd576040517fbb4752b700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff1661010060e084901c02179055600194507f6d54821a69ec281ed7ba1bf2729c700768c47df1d80fad646b0a14cc1d5c39ed8787604051610824929190611bf7565b60405180910390a15050505092915050565b600080600080600080868060200190518101906108539190611c94565b9450945094509450945060008061088a8a60405160200161087691815260200190565b604051602081830303815290604052610b33565b905060008482856040516020016108a393929190611d47565b60405160208183030381529060405290506002816040516108c49190611d8a565b602060405180830381855afa1580156108e1573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906109049190611da6565b9250505060006002858360405160200161091f929190611dbf565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905261095791611d8a565b602060405180830381855afa158015610974573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906109979190611da6565b90506109a58b888884610c6f565b9b9a5050505050505050505050565b6001805460ff16146109f2576040517f38fc28cb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff16600114610a5c576040517fe00d7c7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff1615610af9576040517f7c2cde8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b60608151600003610b5257505060408051602081019091526000815290565b6000604051806060016040528060408152602001611eff6040913990506000600684516008610b819190611e10565b610b8b9190611e56565b9050600060068551610b9d9190611e6a565b1115610bb15780610bad81611e7e565b9150505b60008167ffffffffffffffff811115610bcc57610bcc61177c565b6040519080825280601f01601f191660200182016040528015610bf6576020820181803683370190505b509050600183016020820186875188015b80821015610c62576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f8116850151845350600183019250610c07565b5092979650505050505050565b6000610c9c60017fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611eb6565b85511180610cd75750610cd060017fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611eb6565b6020860151115b15610ce457506000610417565b831580610cef575082155b80610d1a57507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518410155b80610d4557507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518310155b15610d5257506000610417565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff7f5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff8088600060200201517fffffffff00000001000000000000000000000000fffffffffffffffffffffffc0988517fffffffff00000001000000000000000000000000ffffffffffffffffffffffff90819080098a5109080860208601517fffffffff00000001000000000000000000000000ffffffffffffffffffffffff90800914610e4357506000610417565b6000610e4e86610e66565b9050610e5c81868686611062565b9695505050505050565b610e6e611704565b60405180606001604052806000815260200160008152602001600081525081600060108110610e9f57610e9f611b6a565b60200201526040805160608101909152808360006020020151815260200183600160028110610ed057610ed0611b6a565b60200201518152602001600181525081600160108110610ef257610ef2611b6a565b6020020152610f088160015b602002015161116f565b6040820152610f278160015b60200201518260025b60200201516111d1565b6060828101919091526040805191820181527f6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c29682527f4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f560208301526001908201526080820152610fa18160045b6020020151826001610f1d565b60a0820152610fb1816004610f14565b60c0820152610fca8160045b6020020151826003610f1d565b60e0820152610fda816004610efe565b610100820152610feb816008610f94565b610120820152610ffc816008610f14565b61014082015261100d816008610fbd565b610160820152608081015161102490826008610f1d565b61018082015261103581600c610f94565b6101a082015261104681600c610f14565b6101c082015261105781600c610fbd565b6101e0820152919050565b600083158061106f575082155b8061109a57507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518410155b806110c557507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518310155b156110d257506000610417565b60006110fe847fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551611243565b905060007fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551828509905060007fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551838809905060008061115e8a858561125a565b509098149998505050505050505050565b61119360405180606001604052806000815260200160008152602001600081525090565b60008060006111af856000015186602001518760400151611346565b6040805160608101825293845260208401929092529082015295945050505050565b6111f560405180606001604052806000815260200160008152602001600081525090565b6000806000611220866000015187602001518860400151886000015189602001518a60400151611424565b604080516060810182529384526020840192909252908201529695505050505050565b60006102f683611254600285611eb6565b8461155c565b6000808080806080815b81156113285782156112955761127b858585611346565b9196509450925061128d858585611346565b919650945092505b50600c60fc89901c1660fe88901c17801561130b576113038585858d85601081106112c2576112c2611b6a565b6020020151518e86601081106112da576112da611b6a565b6020020151602001518f87601081106112f5576112f5611b6a565b602002015160400151611424565b919650945092505b600298891b989790971b968161132081611ec9565b925050611264565b6113338585856115b0565b909750955050505050505b935093915050565b6000806000846000036113615750600091508190508061141b565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff8085860981828283097fffffffff00000001000000000000000000000000fffffffffffffffffffffffc099050818788098283828b0960040983848384096008099150838385868d8e09600309089250838160020984848509818110156113e65785015b039650868110156113f45783015b8387820384099550508085101561140a57938201935b909303925080808688096002099150505b93509350939050565b60008060008660000361143e575084915083905082611550565b83600003611453575087915086905085611550565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff808889098186870982818d0983838b0984858a85098e0985868e87098c09868b8f08848410156114a357928701925b8484039350878460020988818209905088818609848410156114c457928901925b898585036002099350898485099c50898288099650898a8860020982089150818d10156114f0579b89019b5b818d039c5089818b87600209099450508b86101561150d57948801945b888c870384099a50838b101561152257998801995b838b039a508887890897508882830990508781101561153e5788015b88858983030999505050505050505050505b96509650969350505050565b60008184111561156c5781840693505b60405160208152602080820152602060408201528460608201528360808201528260a082015260208160c08360056136b0fa8080156100a357505051949350505050565b600080826000036115c65750600090508061133e565b60006115f2847fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611243565b905060007fffffffff00000001000000000000000000000000ffffffffffffffffffffffff82830990507fffffffff00000001000000000000000000000000ffffffffffffffffffffffff81880993507fffffffff00000001000000000000000000000000ffffffffffffffffffffffff80838309870992505050935093915050565b82600281019282156116a8579160200282015b828111156116a8578251829060ff16905591602001919060010190611688565b506116b492915061174e565b5090565b60405180604001604052806002906020820280368337509192915050565b82600281019282156116a8579160200282015b828111156116a85782518255916020019190600101906116e9565b6040518061020001604052806010905b61173860405180606001604052806000815260200160008152602001600081525090565b8152602001906001900390816117145790505090565b5b808211156116b4576000815560010161174f565b6000610160828403121561177657600080fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156117ce576117ce61177c565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561181b5761181b61177c565b604052919050565b60008060006080848603121561183857600080fd5b833567ffffffffffffffff81111561184f57600080fd5b61185b86828701611763565b935050602080850135925085605f86011261187557600080fd5b61187d6117ab565b80608087018881111561188f57600080fd5b604088015b818110156118ab5780358452928401928401611894565b50508093505050509250925092565b600067ffffffffffffffff8211156118d4576118d461177c565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261191157600080fd5b813561192461191f826118ba565b6117d4565b81815284602083860101111561193957600080fd5b816020850160208301376000918101602001919091529392505050565b6000806040838503121561196957600080fd5b82359150602083013567ffffffffffffffff81111561198757600080fd5b61199385828601611900565b9150509250929050565b6000602082840312156119af57600080fd5b813567ffffffffffffffff8111156119c657600080fd5b61041784828501611900565b60005b838110156119ed5781810151838201526020016119d5565b50506000910152565b6020815260008251806020840152611a158160408501602087016119d2565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b60008060408385031215611a5a57600080fd5b823567ffffffffffffffff811115611a7157600080fd5b611a7d85828601611763565b95602094909401359450505050565b60008060208385031215611a9f57600080fd5b823567ffffffffffffffff80821115611ab757600080fd5b818501915085601f830112611acb57600080fd5b813581811115611ada57600080fd5b866020828501011115611aec57600080fd5b60209290920196919550909350505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112611b3357600080fd5b83018035915067ffffffffffffffff821115611b4e57600080fd5b602001915036819003821315611b6357600080fd5b9250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008183825b6002811015611bbe578154835260209092019160019182019101611b9f565b50505060408201905092915050565b60008085851115611bdd57600080fd5b83861115611bea57600080fd5b5050820193919092039150565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b6000611c5261191f846118ba565b9050828152838383011115611c6657600080fd5b6102f68360208301846119d2565b600082601f830112611c8557600080fd5b6102f683835160208501611c44565b600080600080600060a08688031215611cac57600080fd5b8551945060208601519350604086015167ffffffffffffffff80821115611cd257600080fd5b818801915088601f830112611ce657600080fd5b611cf589835160208501611c44565b94506060880151915080821115611d0b57600080fd5b611d1789838a01611c74565b93506080880151915080821115611d2d57600080fd5b50611d3a88828901611c74565b9150509295509295909350565b60008451611d598184602089016119d2565b845190830190611d6d8183602089016119d2565b8451910190611d808183602088016119d2565b0195945050505050565b60008251611d9c8184602087016119d2565b9190910192915050565b600060208284031215611db857600080fd5b5051919050565b60008351611dd18184602088016119d2565b9190910191825250602001919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808202811582820484141761036957610369611de1565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082611e6557611e65611e27565b500490565b600082611e7957611e79611e27565b500690565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611eaf57611eaf611de1565b5060010190565b8181038181111561036957610369611de1565b600081611ed857611ed8611de1565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392d5fa2646970667358221220d4142da7b16effb6b95f41adeff2bc8ce0d59d3b70ca8d55e6e83224bbfbec0a64736f6c63430008150033", + "devdoc": { + "author": "Ruslan Serebriakov (@rsrbk)David Yongjun Kim (@Powerstream3604)", + "details": "Primarily used to verify user ops signed with passkeys", + "kind": "dev", + "methods": { + "initializeSigner(bytes)": { + "details": "This method checks if the signer has already been initialized. If already initialized, it reverts. It checks if the public key is in the light format and initializes signer storage in k1 storage.", + "params": { + "_publicKey": "Bytes of owner public key" + }, + "returns": { + "initSuccess": "Uint value representing the success of init operation" + } + }, + "isValidKeyType(bytes)": { + "details": "For this Secp256k1Verification Facet, the public key should in an uncompressed public key format", + "params": { + "_publicKey": "Bytes of public key for format check" + }, + "returns": { + "isValid": "Boolean variable representing if the format of public key is valid" + } + }, + "isValidSignature(bytes32,bytes)": { + "details": "This method verifies the signature if the owner indeed signed the hash. Returns magic value if true", + "params": { + "_hash": "Hash value the owner signed", + "_signature": "Signature that signed the above hash" + }, + "returns": { + "magicValue": "Bytes4 value representing the success/failure of validation" + } + }, + "owner()": { + "returns": { + "signer": "Bytes of owner address" + } + }, + "uninitializeSigner()": { + "details": "This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.", + "returns": { + "uninitSuccess": "Uint value representing the success of uninit operation" + } + }, + "validateOwnerSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32)": { + "details": "This method validates if the user operation is signed by the owner. It internally calls validateSignature with signer public key.", + "params": { + "userOp": "UserOperation including all information for execution", + "userOpHash": "Hash of UserOperation given from EntryPoint. This hash is used for signature validation" + }, + "returns": { + "validationData": "Uint value representing whether the validation is successful. 0 for success, 1 for failure" + } + }, + "validateOwnerSignatureSelector()": { + "returns": { + "ownerSignatureValidatorSelector": "Bytes4 selector of function signature to validate account owner's UserOperation signature" + } + }, + "validateSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256[2])": { + "details": "This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address", + "params": { + "q": "Public Key of signer who signed the contract, to be validated", + "userOp": "UserOperation including all information for execution", + "userOpHash": "Hash of UserOperation given from EntryPoint. This hash is used for signature validation" + }, + "returns": { + "isValid": "Uint value representing whether the validation is successful. 0 for success, 1 for failure" + } + } + }, + "title": "Secp256r1 verification facet", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "constructor": { + "notice": "This constructor ensures that this contract can only be used as singleton for Proxy contracts" + }, + "initializeSigner(bytes)": { + "notice": "Initializes the signer in R1 Facet Storage. This can only be called when the account is uninitialized or during signature migration." + }, + "isValidKeyType(bytes)": { + "notice": "Validates if the format of public key is valid for this verification facet" + }, + "isValidSignature(bytes32,bytes)": { + "notice": "Validates if the signature is valid. Function to be compatible with EIP-1271" + }, + "owner()": { + "notice": "Returns the owner of the account" + }, + "uninitializeSigner()": { + "notice": "Uninitialize signer in R1 Facet Storage. This can only be called when the account is undergoing signature migration and has already been initialized." + }, + "validateOwnerSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32)": { + "notice": "Validates if the user operation is signed by the owner." + }, + "validateOwnerSignatureSelector()": { + "notice": "Returns the selector of function to validate the signature of UserOperation" + }, + "validateSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256[2])": { + "notice": "Validates if the signature of UserOperation is signed by the given signer" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/blast/TokenReceiverFacet.json b/deployments/blast/TokenReceiverFacet.json new file mode 100644 index 0000000..b4021cd --- /dev/null +++ b/deployments/blast/TokenReceiverFacet.json @@ -0,0 +1,239 @@ +{ + "address": "0x3143E1C0Af0Cdc153423863923Cf4e3818e34Daa", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onERC1155BatchReceived", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onERC1155Received", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onERC721Received", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onTokenTransfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "tokensReceived", + "outputs": [], + "stateMutability": "pure", + "type": "function" + } + ], + "transactionHash": "0x6c0baf47490a8b6ca2b64e9d76169cd0fe06ef25dcf561cdbf8cbffd978e02c7", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 4, + "gasUsed": "329424", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x2013370c83227b490120fc6f71c86f973194c0d566a59f03e87aade23dcc8d14", + "transactionHash": "0x6c0baf47490a8b6ca2b64e9d76169cd0fe06ef25dcf561cdbf8cbffd978e02c7", + "logs": [], + "blockNumber": 1317775, + "cumulativeGasUsed": "774894", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "ad34345aa73d96f52b3e14df983b6b29", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onERC1155BatchReceived\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onERC1155Received\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onERC721Received\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"tokensReceived\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"Contract that enables receiving ERC721/ERC1155/ERC777/ERC677 Tokens with safe transfer\",\"kind\":\"dev\",\"methods\":{},\"title\":\"TokenReceiver Facet\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\":{\"notice\":\"Handles ERC1155 Token batch callback. return Standardized onERC1155BatchReceived return value.\"},\"onERC1155Received(address,address,uint256,uint256,bytes)\":{\"notice\":\"Handles ERC1155 Token callback. return Standardized onERC1155Received return value.\"},\"onERC721Received(address,address,uint256,bytes)\":{\"notice\":\"Handles ERC721 Token callback. return Standardized onERC721Received return value.\"},\"onTokenTransfer(address,uint256,bytes)\":{\"notice\":\"Handles ERC677 Token callback. return true.\"},\"tokensReceived(address,address,address,uint256,bytes,bytes)\":{\"notice\":\"Handles ERC777 Token callback. Does not return value, empty implementation.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/TokenReceiverFacet.sol\":\"TokenReceiverFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title ERC721 token receiver interface\\n * @dev Interface for any contract that wants to support safeTransfers\\n * from ERC721 asset contracts.\\n */\\ninterface IERC721Receiver {\\n /**\\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\\n * by `operator` from `from`, this function is called.\\n *\\n * It must return its Solidity selector to confirm the token transfer.\\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\\n *\\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\\n */\\n function onERC721Received(\\n address operator,\\n address from,\\n uint256 tokenId,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\\n *\\n * Accounts can be notified of {IERC777} tokens being sent to them by having a\\n * contract implement this interface (contract holders can be their own\\n * implementer) and registering it on the\\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\\n *\\n * See {IERC1820Registry} and {ERC1820Implementer}.\\n */\\ninterface IERC777Recipient {\\n /**\\n * @dev Called by an {IERC777} token contract whenever tokens are being\\n * moved or created into a registered account (`to`). The type of operation\\n * is conveyed by `from` being the zero address or not.\\n *\\n * This call occurs _after_ the token contract's state is updated, so\\n * {IERC777-balanceOf}, etc., can be used to query the post-operation state.\\n *\\n * This function may revert to prevent the operation from being executed.\\n */\\n function tokensReceived(\\n address operator,\\n address from,\\n address to,\\n uint256 amount,\\n bytes calldata userData,\\n bytes calldata operatorData\\n ) external;\\n}\\n\",\"keccak256\":\"0x1a5d61db2733202ba361e6d6741cd2e662380e22b80e987eacfc91973f2267dc\",\"license\":\"MIT\"},\"contracts/facets/TokenReceiverFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IERC721Receiver} from \\\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\\\";\\nimport {IERC777Recipient} from \\\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\\\";\\nimport {IERC1155Receiver} from \\\"../interfaces/ERC/IERC1155Receiver.sol\\\";\\nimport {IERC677Receiver} from \\\"../interfaces/ERC/IERC677Receiver.sol\\\";\\n\\n/**\\n * @title TokenReceiver Facet\\n * @dev Contract that enables receiving ERC721/ERC1155/ERC777/ERC677 Tokens with safe transfer\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract TokenReceiverFacet is\\n IERC721Receiver,\\n IERC1155Receiver,\\n IERC777Recipient,\\n IERC677Receiver\\n{\\n /**\\n * @notice Handles ERC721 Token callback.\\n * return Standardized onERC721Received return value.\\n */\\n function onERC721Received(\\n address,\\n address,\\n uint256,\\n bytes calldata\\n ) external pure override returns (bytes4) {\\n return IERC721Receiver.onERC721Received.selector;\\n }\\n\\n /**\\n * @notice Handles ERC1155 Token callback.\\n * return Standardized onERC1155Received return value.\\n */\\n function onERC1155Received(\\n address,\\n address,\\n uint256,\\n uint256,\\n bytes calldata\\n ) external pure override returns (bytes4) {\\n return IERC1155Receiver.onERC1155Received.selector;\\n }\\n\\n /**\\n * @notice Handles ERC1155 Token batch callback.\\n * return Standardized onERC1155BatchReceived return value.\\n */\\n function onERC1155BatchReceived(\\n address,\\n address,\\n uint256[] calldata,\\n uint256[] calldata,\\n bytes calldata\\n ) external pure override returns (bytes4) {\\n return IERC1155Receiver.onERC1155BatchReceived.selector;\\n }\\n\\n /**\\n * @notice Handles ERC777 Token callback.\\n * Does not return value, empty implementation.\\n */\\n function tokensReceived(\\n address,\\n address,\\n address,\\n uint256,\\n bytes calldata,\\n bytes calldata\\n ) external pure override {}\\n\\n /**\\n * @notice Handles ERC677 Token callback.\\n * return true.\\n */\\n function onTokenTransfer(\\n address,\\n uint256,\\n bytes calldata\\n ) external pure override returns (bool) {\\n return true;\\n }\\n}\\n\",\"keccak256\":\"0xdfe483d05ef4056bb464c34ade19ab527687aff3ed0b6303b447a68b5ff7abb4\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC1155Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\n\\npragma solidity 0.8.21;\\n\\n/**\\n * @dev _Available since v3.1._\\n */\\ninterface IERC1155Receiver {\\n /**\\n * @dev Handles the receipt of a single ERC1155 token type. This function is\\n * called at the end of a `safeTransferFrom` after the balance has been updated.\\n *\\n * NOTE: To accept the transfer, this must return\\n * `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))`\\n * (i.e. 0xf23a6e61, or its own function selector).\\n *\\n * @param operator The address which initiated the transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param id The ID of the token being transferred\\n * @param value The amount of tokens being transferred\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155Received(\\n address operator,\\n address from,\\n uint256 id,\\n uint256 value,\\n bytes calldata data\\n ) external returns (bytes4);\\n\\n /**\\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\\n * is called at the end of a `safeBatchTransferFrom` after the balances have\\n * been updated.\\n *\\n * NOTE: To accept the transfer(s), this must return\\n * `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))`\\n * (i.e. 0xbc197c81, or its own function selector).\\n *\\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155BatchReceived(\\n address operator,\\n address from,\\n uint256[] calldata ids,\\n uint256[] calldata values,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0x3729c6757bae3aba03ac1c5064d67ad13b94e2a9428bf44b9be510373406da0c\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC677Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC677Receiver {\\n function onTokenTransfer(\\n address sender,\\n uint value,\\n bytes calldata data\\n ) external pure returns (bool);\\n}\\n\",\"keccak256\":\"0x4c1631cf45ea6daac0ec158c3edb9453099130b6b64f697004b83f95aa1f7350\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50610502806100206000396000f3fe608060405234801561001057600080fd5b50600436106100665760003560e01c8063a4c0ed3611610050578063a4c0ed36146100f3578063bc197c811461011b578063f23a6e611461015657600080fd5b806223de291461006b578063150b7a0214610085575b600080fd5b610083610079366004610201565b5050505050505050565b005b6100bd6100933660046102ac565b7f150b7a020000000000000000000000000000000000000000000000000000000095945050505050565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020015b60405180910390f35b61010b61010136600461031b565b6001949350505050565b60405190151581526020016100ea565b6100bd6101293660046103ba565b7fbc197c810000000000000000000000000000000000000000000000000000000098975050505050505050565b6100bd610164366004610454565b7ff23a6e61000000000000000000000000000000000000000000000000000000009695505050505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146101b357600080fd5b919050565b60008083601f8401126101ca57600080fd5b50813567ffffffffffffffff8111156101e257600080fd5b6020830191508360208285010111156101fa57600080fd5b9250929050565b60008060008060008060008060c0898b03121561021d57600080fd5b6102268961018f565b975061023460208a0161018f565b965061024260408a0161018f565b955060608901359450608089013567ffffffffffffffff8082111561026657600080fd5b6102728c838d016101b8565b909650945060a08b013591508082111561028b57600080fd5b506102988b828c016101b8565b999c989b5096995094979396929594505050565b6000806000806000608086880312156102c457600080fd5b6102cd8661018f565b94506102db6020870161018f565b935060408601359250606086013567ffffffffffffffff8111156102fe57600080fd5b61030a888289016101b8565b969995985093965092949392505050565b6000806000806060858703121561033157600080fd5b61033a8561018f565b935060208501359250604085013567ffffffffffffffff81111561035d57600080fd5b610369878288016101b8565b95989497509550505050565b60008083601f84011261038757600080fd5b50813567ffffffffffffffff81111561039f57600080fd5b6020830191508360208260051b85010111156101fa57600080fd5b60008060008060008060008060a0898b0312156103d657600080fd5b6103df8961018f565b97506103ed60208a0161018f565b9650604089013567ffffffffffffffff8082111561040a57600080fd5b6104168c838d01610375565b909850965060608b013591508082111561042f57600080fd5b61043b8c838d01610375565b909650945060808b013591508082111561028b57600080fd5b60008060008060008060a0878903121561046d57600080fd5b6104768761018f565b95506104846020880161018f565b94506040870135935060608701359250608087013567ffffffffffffffff8111156104ae57600080fd5b6104ba89828a016101b8565b979a969950949750929593949250505056fea2646970667358221220ae9a97061ae9e1485161ca9c8d3228a23e47b18755fa935f51b40e927816ca2964736f6c63430008150033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100665760003560e01c8063a4c0ed3611610050578063a4c0ed36146100f3578063bc197c811461011b578063f23a6e611461015657600080fd5b806223de291461006b578063150b7a0214610085575b600080fd5b610083610079366004610201565b5050505050505050565b005b6100bd6100933660046102ac565b7f150b7a020000000000000000000000000000000000000000000000000000000095945050505050565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020015b60405180910390f35b61010b61010136600461031b565b6001949350505050565b60405190151581526020016100ea565b6100bd6101293660046103ba565b7fbc197c810000000000000000000000000000000000000000000000000000000098975050505050505050565b6100bd610164366004610454565b7ff23a6e61000000000000000000000000000000000000000000000000000000009695505050505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146101b357600080fd5b919050565b60008083601f8401126101ca57600080fd5b50813567ffffffffffffffff8111156101e257600080fd5b6020830191508360208285010111156101fa57600080fd5b9250929050565b60008060008060008060008060c0898b03121561021d57600080fd5b6102268961018f565b975061023460208a0161018f565b965061024260408a0161018f565b955060608901359450608089013567ffffffffffffffff8082111561026657600080fd5b6102728c838d016101b8565b909650945060a08b013591508082111561028b57600080fd5b506102988b828c016101b8565b999c989b5096995094979396929594505050565b6000806000806000608086880312156102c457600080fd5b6102cd8661018f565b94506102db6020870161018f565b935060408601359250606086013567ffffffffffffffff8111156102fe57600080fd5b61030a888289016101b8565b969995985093965092949392505050565b6000806000806060858703121561033157600080fd5b61033a8561018f565b935060208501359250604085013567ffffffffffffffff81111561035d57600080fd5b610369878288016101b8565b95989497509550505050565b60008083601f84011261038757600080fd5b50813567ffffffffffffffff81111561039f57600080fd5b6020830191508360208260051b85010111156101fa57600080fd5b60008060008060008060008060a0898b0312156103d657600080fd5b6103df8961018f565b97506103ed60208a0161018f565b9650604089013567ffffffffffffffff8082111561040a57600080fd5b6104168c838d01610375565b909850965060608b013591508082111561042f57600080fd5b61043b8c838d01610375565b909650945060808b013591508082111561028b57600080fd5b60008060008060008060a0878903121561046d57600080fd5b6104768761018f565b95506104846020880161018f565b94506040870135935060608701359250608087013567ffffffffffffffff8111156104ae57600080fd5b6104ba89828a016101b8565b979a969950949750929593949250505056fea2646970667358221220ae9a97061ae9e1485161ca9c8d3228a23e47b18755fa935f51b40e927816ca2964736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "Contract that enables receiving ERC721/ERC1155/ERC777/ERC677 Tokens with safe transfer", + "kind": "dev", + "methods": {}, + "title": "TokenReceiver Facet", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)": { + "notice": "Handles ERC1155 Token batch callback. return Standardized onERC1155BatchReceived return value." + }, + "onERC1155Received(address,address,uint256,uint256,bytes)": { + "notice": "Handles ERC1155 Token callback. return Standardized onERC1155Received return value." + }, + "onERC721Received(address,address,uint256,bytes)": { + "notice": "Handles ERC721 Token callback. return Standardized onERC721Received return value." + }, + "onTokenTransfer(address,uint256,bytes)": { + "notice": "Handles ERC677 Token callback. return true." + }, + "tokensReceived(address,address,address,uint256,bytes,bytes)": { + "notice": "Handles ERC777 Token callback. Does not return value, empty implementation." + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/blast/solcInputs/ad34345aa73d96f52b3e14df983b6b29.json b/deployments/blast/solcInputs/ad34345aa73d96f52b3e14df983b6b29.json new file mode 100644 index 0000000..c2bd4dc --- /dev/null +++ b/deployments/blast/solcInputs/ad34345aa73d96f52b3e14df983b6b29.json @@ -0,0 +1,360 @@ +{ + "language": "Solidity", + "sources": { + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby disabling any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable2Step.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./Ownable.sol\";\n\n/**\n * @dev Contract module which provides access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership} and {acceptOwnership}.\n *\n * This module is used through inheritance. It will make available all functions\n * from parent (Ownable).\n */\nabstract contract Ownable2Step is Ownable {\n address private _pendingOwner;\n\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Returns the address of the pending owner.\n */\n function pendingOwner() public view virtual returns (address) {\n return _pendingOwner;\n }\n\n /**\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual override onlyOwner {\n _pendingOwner = newOwner;\n emit OwnershipTransferStarted(owner(), newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual override {\n delete _pendingOwner;\n super._transferOwnership(newOwner);\n }\n\n /**\n * @dev The new owner accepts the ownership transfer.\n */\n function acceptOwnership() public virtual {\n address sender = _msgSender();\n require(pendingOwner() == sender, \"Ownable2Step: caller is not the new owner\");\n _transferOwnership(sender);\n }\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC1271.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC1271 standard signature validation method for\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\n *\n * _Available since v4.1._\n */\ninterface IERC1271 {\n /**\n * @dev Should return whether the signature provided is valid for the provided data\n * @param hash Hash of the data to be signed\n * @param signature Signature byte array associated with _data\n */\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\n}\n" + }, + "@openzeppelin/contracts/security/ReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor() {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n _nonReentrantBefore();\n _;\n _nonReentrantAfter();\n }\n\n function _nonReentrantBefore() private {\n // On the first call to nonReentrant, _status will be _NOT_ENTERED\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n }\n\n function _nonReentrantAfter() private {\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Returns true if the reentrancy guard is currently set to \"entered\", which indicates there is a\n * `nonReentrant` function in the call stack.\n */\n function _reentrancyGuardEntered() internal view returns (bool) {\n return _status == _ENTERED;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/ERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/ERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC1155.sol\";\nimport \"./IERC1155Receiver.sol\";\nimport \"./extensions/IERC1155MetadataURI.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of the basic standard multi-token.\n * See https://eips.ethereum.org/EIPS/eip-1155\n * Originally based on code by Enjin: https://github.com/enjin/erc-1155\n *\n * _Available since v3.1._\n */\ncontract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {\n using Address for address;\n\n // Mapping from token ID to account balances\n mapping(uint256 => mapping(address => uint256)) private _balances;\n\n // Mapping from account to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json\n string private _uri;\n\n /**\n * @dev See {_setURI}.\n */\n constructor(string memory uri_) {\n _setURI(uri_);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return\n interfaceId == type(IERC1155).interfaceId ||\n interfaceId == type(IERC1155MetadataURI).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC1155MetadataURI-uri}.\n *\n * This implementation returns the same URI for *all* token types. It relies\n * on the token type ID substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * Clients calling this function must replace the `\\{id\\}` substring with the\n * actual token type ID.\n */\n function uri(uint256) public view virtual override returns (string memory) {\n return _uri;\n }\n\n /**\n * @dev See {IERC1155-balanceOf}.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {\n require(account != address(0), \"ERC1155: address zero is not a valid owner\");\n return _balances[id][account];\n }\n\n /**\n * @dev See {IERC1155-balanceOfBatch}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] memory accounts,\n uint256[] memory ids\n ) public view virtual override returns (uint256[] memory) {\n require(accounts.length == ids.length, \"ERC1155: accounts and ids length mismatch\");\n\n uint256[] memory batchBalances = new uint256[](accounts.length);\n\n for (uint256 i = 0; i < accounts.length; ++i) {\n batchBalances[i] = balanceOf(accounts[i], ids[i]);\n }\n\n return batchBalances;\n }\n\n /**\n * @dev See {IERC1155-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC1155-isApprovedForAll}.\n */\n function isApprovedForAll(address account, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[account][operator];\n }\n\n /**\n * @dev See {IERC1155-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n _safeTransferFrom(from, to, id, amount, data);\n }\n\n /**\n * @dev See {IERC1155-safeBatchTransferFrom}.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n _safeBatchTransferFrom(from, to, ids, amounts, data);\n }\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n\n emit TransferSingle(operator, from, to, id, amount);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n for (uint256 i = 0; i < ids.length; ++i) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n }\n\n emit TransferBatch(operator, from, to, ids, amounts);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\n\n _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);\n }\n\n /**\n * @dev Sets a new URI for all token types, by relying on the token type ID\n * substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * By this mechanism, any occurrence of the `\\{id\\}` substring in either the\n * URI or any of the amounts in the JSON file at said URI will be replaced by\n * clients with the token type ID.\n *\n * For example, the `https://token-cdn-domain/\\{id\\}.json` URI would be\n * interpreted by clients as\n * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`\n * for token type ID 0x4cce0.\n *\n * See {uri}.\n *\n * Because these URIs cannot be meaningfully represented by the {URI} event,\n * this function emits no events.\n */\n function _setURI(string memory newuri) internal virtual {\n _uri = newuri;\n }\n\n /**\n * @dev Creates `amount` tokens of token type `id`, and assigns them to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _mint(address to, uint256 id, uint256 amount, bytes memory data) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _balances[id][to] += amount;\n emit TransferSingle(operator, address(0), to, id, amount);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n for (uint256 i = 0; i < ids.length; i++) {\n _balances[ids[i]][to] += amounts[i];\n }\n\n emit TransferBatch(operator, address(0), to, ids, amounts);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);\n }\n\n /**\n * @dev Destroys `amount` tokens of token type `id` from `from`\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `from` must have at least `amount` tokens of token type `id`.\n */\n function _burn(address from, uint256 id, uint256 amount) internal virtual {\n require(from != address(0), \"ERC1155: burn from the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n\n emit TransferSingle(operator, from, address(0), id, amount);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n */\n function _burnBatch(address from, uint256[] memory ids, uint256[] memory amounts) internal virtual {\n require(from != address(0), \"ERC1155: burn from the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n\n for (uint256 i = 0; i < ids.length; i++) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n }\n\n emit TransferBatch(operator, from, address(0), ids, amounts);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {\n require(owner != operator, \"ERC1155: setting approval status for self\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning, as well as batched variants.\n *\n * The same hook is called on both single and batched variants. For single\n * transfers, the length of the `ids` and `amounts` arrays will be 1.\n *\n * Calling conditions (for each `id` and `amount` pair):\n *\n * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * of token type `id` will be transferred to `to`.\n * - When `from` is zero, `amount` tokens of token type `id` will be minted\n * for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n * will be burned.\n * - `from` and `to` are never both zero.\n * - `ids` and `amounts` have the same, non-zero length.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any token transfer. This includes minting\n * and burning, as well as batched variants.\n *\n * The same hook is called on both single and batched variants. For single\n * transfers, the length of the `id` and `amount` arrays will be 1.\n *\n * Calling conditions (for each `id` and `amount` pair):\n *\n * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * of token type `id` will be transferred to `to`.\n * - When `from` is zero, `amount` tokens of token type `id` will be minted\n * for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n * will be burned.\n * - `from` and `to` are never both zero.\n * - `ids` and `amounts` have the same, non-zero length.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {}\n\n function _doSafeTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155Receiver.onERC1155Received.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non-ERC1155Receiver implementer\");\n }\n }\n }\n\n function _doSafeBatchTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (\n bytes4 response\n ) {\n if (response != IERC1155Receiver.onERC1155BatchReceived.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non-ERC1155Receiver implementer\");\n }\n }\n }\n\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {\n uint256[] memory array = new uint256[](1);\n array[0] = element;\n\n return array;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC1155.sol\";\n\n/**\n * @dev Interface of the optional ERC1155MetadataExtension interface, as defined\n * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155MetadataURI is IERC1155 {\n /**\n * @dev Returns the URI for token type `id`.\n *\n * If the `\\{id\\}` substring is present in the URI, it must be replaced by\n * clients with the actual token type ID.\n */\n function uri(uint256 id) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155 is IERC165 {\n /**\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n */\n event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);\n\n /**\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n * transfers.\n */\n event TransferBatch(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\n\n /**\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n * `approved`.\n */\n event ApprovalForAll(address indexed account, address indexed operator, bool approved);\n\n /**\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n *\n * If an {URI} event was emitted for `id`, the standard\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n * returned by {IERC1155MetadataURI-uri}.\n */\n event URI(string value, uint256 indexed id);\n\n /**\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) external view returns (uint256);\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] calldata accounts,\n uint256[] calldata ids\n ) external view returns (uint256[] memory);\n\n /**\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n *\n * Emits an {ApprovalForAll} event.\n *\n * Requirements:\n *\n * - `operator` cannot be the caller.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n *\n * See {setApprovalForAll}.\n */\n function isApprovedForAll(address account, address operator) external view returns (bool);\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155Receiver is IERC165 {\n /**\n * @dev Handles the receipt of a single ERC1155 token type. This function is\n * called at the end of a `safeTransferFrom` after the balance has been updated.\n *\n * NOTE: To accept the transfer, this must return\n * `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n * (i.e. 0xf23a6e61, or its own function selector).\n *\n * @param operator The address which initiated the transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param id The ID of the token being transferred\n * @param value The amount of tokens being transferred\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n ) external returns (bytes4);\n\n /**\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\n * is called at the end of a `safeBatchTransferFrom` after the balances have\n * been updated.\n *\n * NOTE: To accept the transfer(s), this must return\n * `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n * (i.e. 0xbc197c81, or its own function selector).\n *\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the default value returned by this function, unless\n * it's overridden.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(address from, address to, uint256 amount) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\n // decrementing then incrementing.\n _balances[to] += amount;\n }\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n unchecked {\n // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\n _balances[account] += amount;\n }\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n // Overflow not possible: amount <= accountBalance <= totalSupply.\n _totalSupply -= amount;\n }\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\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" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` 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 amount) 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 `amount` as the allowance of `spender` over the 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 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` 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 amount) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/ERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721.sol\";\nimport \"./IERC721Receiver.sol\";\nimport \"./extensions/IERC721Metadata.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/Strings.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\n using Address for address;\n using Strings for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\n\n // Mapping from token ID to approved address\n mapping(uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return\n interfaceId == type(IERC721).interfaceId ||\n interfaceId == type(IERC721Metadata).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _ownerOf(tokenId);\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token owner or approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n _requireMinted(tokenId);\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n _safeTransfer(from, to, tokenId, data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(address from, address to, uint256 tokenId, bytes memory data) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist\n */\n function _ownerOf(uint256 tokenId) internal view virtual returns (address) {\n return _owners[tokenId];\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _ownerOf(tokenId) != address(0);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n address owner = ERC721.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(address to, uint256 tokenId, bytes memory data) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId, 1);\n\n // Check that tokenId was not minted by `_beforeTokenTransfer` hook\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n unchecked {\n // Will not overflow unless all 2**256 token ids are minted to the same owner.\n // Given that tokens are minted one by one, it is impossible in practice that\n // this ever happens. Might change if we allow batch minting.\n // The ERC fails to describe this case.\n _balances[to] += 1;\n }\n\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(address(0), to, tokenId, 1);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n * This is an internal function that does not check if the sender is authorized to operate on the token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId, 1);\n\n // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook\n owner = ERC721.ownerOf(tokenId);\n\n // Clear approvals\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // Cannot overflow, as that would require more tokens to be burned/transferred\n // out than the owner initially received through minting and transferring in.\n _balances[owner] -= 1;\n }\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(owner, address(0), tokenId, 1);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(address from, address to, uint256 tokenId) internal virtual {\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId, 1);\n\n // Check that tokenId was not transferred by `_beforeTokenTransfer` hook\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n\n // Clear approvals from the previous owner\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // `_balances[from]` cannot overflow for the same reason as described in `_burn`:\n // `from`'s balance is the number of token held, which is at least one before the current\n // transfer.\n // `_balances[to]` could overflow in the conditions described in `_mint`. That would require\n // all 2**256 token ids to be minted, which in practice is impossible.\n _balances[from] -= 1;\n _balances[to] += 1;\n }\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId, 1);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721Receiver.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`.\n * - When `from` is zero, the tokens will be minted for `to`.\n * - When `to` is zero, ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}\n\n /**\n * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`.\n * - When `from` is zero, the tokens were minted for `to`.\n * - When `to` is zero, ``from``'s tokens were burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}\n\n /**\n * @dev Unsafe write access to the balances, used by extensions that \"mint\" tokens using an {ownerOf} override.\n *\n * WARNING: Anyone calling this MUST ensure that the balances remain consistent with the ownership. The invariant\n * being that for any address `a` the value returned by `balanceOf(a)` must be equal to the number of tokens such\n * that `ownerOf(tokenId)` is `a`.\n */\n // solhint-disable-next-line func-name-mixedcase\n function __unsafe_increaseBalance(address account, uint256 amount) internal {\n _balances[account] += amount;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721Receiver {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/ERC777.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC777/ERC777.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC777.sol\";\nimport \"./IERC777Recipient.sol\";\nimport \"./IERC777Sender.sol\";\nimport \"../ERC20/IERC20.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/introspection/IERC1820Registry.sol\";\n\n/**\n * @dev Implementation of the {IERC777} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n *\n * Support for ERC20 is included in this contract, as specified by the EIP: both\n * the ERC777 and ERC20 interfaces can be safely used when interacting with it.\n * Both {IERC777-Sent} and {IERC20-Transfer} events are emitted on token\n * movements.\n *\n * Additionally, the {IERC777-granularity} value is hard-coded to `1`, meaning that there\n * are no special restrictions in the amount of tokens that created, moved, or\n * destroyed. This makes integration with ERC20 applications seamless.\n *\n * CAUTION: This file is deprecated as of v4.9 and will be removed in the next major release.\n */\ncontract ERC777 is Context, IERC777, IERC20 {\n using Address for address;\n\n IERC1820Registry internal constant _ERC1820_REGISTRY = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n mapping(address => uint256) private _balances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n bytes32 private constant _TOKENS_SENDER_INTERFACE_HASH = keccak256(\"ERC777TokensSender\");\n bytes32 private constant _TOKENS_RECIPIENT_INTERFACE_HASH = keccak256(\"ERC777TokensRecipient\");\n\n // This isn't ever read from - it's only used to respond to the defaultOperators query.\n address[] private _defaultOperatorsArray;\n\n // Immutable, but accounts may revoke them (tracked in __revokedDefaultOperators).\n mapping(address => bool) private _defaultOperators;\n\n // For each account, a mapping of its operators and revoked default operators.\n mapping(address => mapping(address => bool)) private _operators;\n mapping(address => mapping(address => bool)) private _revokedDefaultOperators;\n\n // ERC20-allowances\n mapping(address => mapping(address => uint256)) private _allowances;\n\n /**\n * @dev `defaultOperators` may be an empty array.\n */\n constructor(string memory name_, string memory symbol_, address[] memory defaultOperators_) {\n _name = name_;\n _symbol = symbol_;\n\n _defaultOperatorsArray = defaultOperators_;\n for (uint256 i = 0; i < defaultOperators_.length; i++) {\n _defaultOperators[defaultOperators_[i]] = true;\n }\n\n // register interfaces\n _ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256(\"ERC777Token\"), address(this));\n _ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256(\"ERC20Token\"), address(this));\n }\n\n /**\n * @dev See {IERC777-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC777-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {ERC20-decimals}.\n *\n * Always returns 18, as per the\n * [ERC777 EIP](https://eips.ethereum.org/EIPS/eip-777#backward-compatibility).\n */\n function decimals() public pure virtual returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC777-granularity}.\n *\n * This implementation always returns `1`.\n */\n function granularity() public view virtual override returns (uint256) {\n return 1;\n }\n\n /**\n * @dev See {IERC777-totalSupply}.\n */\n function totalSupply() public view virtual override(IERC20, IERC777) returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev Returns the amount of tokens owned by an account (`tokenHolder`).\n */\n function balanceOf(address tokenHolder) public view virtual override(IERC20, IERC777) returns (uint256) {\n return _balances[tokenHolder];\n }\n\n /**\n * @dev See {IERC777-send}.\n *\n * Also emits a {IERC20-Transfer} event for ERC20 compatibility.\n */\n function send(address recipient, uint256 amount, bytes memory data) public virtual override {\n _send(_msgSender(), recipient, amount, data, \"\", true);\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Unlike `send`, `recipient` is _not_ required to implement the {IERC777Recipient}\n * interface if it is a contract.\n *\n * Also emits a {Sent} event.\n */\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n _send(_msgSender(), recipient, amount, \"\", \"\", false);\n return true;\n }\n\n /**\n * @dev See {IERC777-burn}.\n *\n * Also emits a {IERC20-Transfer} event for ERC20 compatibility.\n */\n function burn(uint256 amount, bytes memory data) public virtual override {\n _burn(_msgSender(), amount, data, \"\");\n }\n\n /**\n * @dev See {IERC777-isOperatorFor}.\n */\n function isOperatorFor(address operator, address tokenHolder) public view virtual override returns (bool) {\n return\n operator == tokenHolder ||\n (_defaultOperators[operator] && !_revokedDefaultOperators[tokenHolder][operator]) ||\n _operators[tokenHolder][operator];\n }\n\n /**\n * @dev See {IERC777-authorizeOperator}.\n */\n function authorizeOperator(address operator) public virtual override {\n require(_msgSender() != operator, \"ERC777: authorizing self as operator\");\n\n if (_defaultOperators[operator]) {\n delete _revokedDefaultOperators[_msgSender()][operator];\n } else {\n _operators[_msgSender()][operator] = true;\n }\n\n emit AuthorizedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-revokeOperator}.\n */\n function revokeOperator(address operator) public virtual override {\n require(operator != _msgSender(), \"ERC777: revoking self as operator\");\n\n if (_defaultOperators[operator]) {\n _revokedDefaultOperators[_msgSender()][operator] = true;\n } else {\n delete _operators[_msgSender()][operator];\n }\n\n emit RevokedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-defaultOperators}.\n */\n function defaultOperators() public view virtual override returns (address[] memory) {\n return _defaultOperatorsArray;\n }\n\n /**\n * @dev See {IERC777-operatorSend}.\n *\n * Emits {Sent} and {IERC20-Transfer} events.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes memory data,\n bytes memory operatorData\n ) public virtual override {\n require(isOperatorFor(_msgSender(), sender), \"ERC777: caller is not an operator for holder\");\n _send(sender, recipient, amount, data, operatorData, true);\n }\n\n /**\n * @dev See {IERC777-operatorBurn}.\n *\n * Emits {Burned} and {IERC20-Transfer} events.\n */\n function operatorBurn(\n address account,\n uint256 amount,\n bytes memory data,\n bytes memory operatorData\n ) public virtual override {\n require(isOperatorFor(_msgSender(), account), \"ERC777: caller is not an operator for holder\");\n _burn(account, amount, data, operatorData);\n }\n\n /**\n * @dev See {IERC20-allowance}.\n *\n * Note that operator and allowance concepts are orthogonal: operators may\n * not have allowance, and accounts with allowance may not be operators\n * themselves.\n */\n function allowance(address holder, address spender) public view virtual override returns (uint256) {\n return _allowances[holder][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Note that accounts cannot have allowance issued by their operators.\n */\n function approve(address spender, uint256 value) public virtual override returns (bool) {\n address holder = _msgSender();\n _approve(holder, spender, value);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Note that operator and allowance concepts are orthogonal: operators cannot\n * call `transferFrom` (unless they have allowance), and accounts with\n * allowance cannot call `operatorSend` (unless they are operators).\n *\n * Emits {Sent}, {IERC20-Transfer} and {IERC20-Approval} events.\n */\n function transferFrom(address holder, address recipient, uint256 amount) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(holder, spender, amount);\n _send(holder, recipient, amount, \"\", \"\", false);\n return true;\n }\n\n /**\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with the caller address as the `operator` and with\n * `userData` and `operatorData`.\n *\n * See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits {Minted} and {IERC20-Transfer} events.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - if `account` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function _mint(address account, uint256 amount, bytes memory userData, bytes memory operatorData) internal virtual {\n _mint(account, amount, userData, operatorData, true);\n }\n\n /**\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * If `requireReceptionAck` is set to true, and if a send hook is\n * registered for `account`, the corresponding function will be called with\n * `operator`, `data` and `operatorData`.\n *\n * See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits {Minted} and {IERC20-Transfer} events.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - if `account` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function _mint(\n address account,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) internal virtual {\n require(account != address(0), \"ERC777: mint to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), account, amount);\n\n // Update state variables\n _totalSupply += amount;\n _balances[account] += amount;\n\n _callTokensReceived(operator, address(0), account, amount, userData, operatorData, requireReceptionAck);\n\n emit Minted(operator, account, amount, userData, operatorData);\n emit Transfer(address(0), account, amount);\n }\n\n /**\n * @dev Send tokens\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _send(\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) internal virtual {\n require(from != address(0), \"ERC777: transfer from the zero address\");\n require(to != address(0), \"ERC777: transfer to the zero address\");\n\n address operator = _msgSender();\n\n _callTokensToSend(operator, from, to, amount, userData, operatorData);\n\n _move(operator, from, to, amount, userData, operatorData);\n\n _callTokensReceived(operator, from, to, amount, userData, operatorData, requireReceptionAck);\n }\n\n /**\n * @dev Burn tokens\n * @param from address token holder address\n * @param amount uint256 amount of tokens to burn\n * @param data bytes extra information provided by the token holder\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _burn(address from, uint256 amount, bytes memory data, bytes memory operatorData) internal virtual {\n require(from != address(0), \"ERC777: burn from the zero address\");\n\n address operator = _msgSender();\n\n _callTokensToSend(operator, from, address(0), amount, data, operatorData);\n\n _beforeTokenTransfer(operator, from, address(0), amount);\n\n // Update state variables\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC777: burn amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Burned(operator, from, amount, data, operatorData);\n emit Transfer(from, address(0), amount);\n }\n\n function _move(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n ) private {\n _beforeTokenTransfer(operator, from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC777: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Sent(operator, from, to, amount, userData, operatorData);\n emit Transfer(from, to, amount);\n }\n\n /**\n * @dev See {ERC20-_approve}.\n *\n * Note that accounts cannot have allowance issued by their operators.\n */\n function _approve(address holder, address spender, uint256 value) internal virtual {\n require(holder != address(0), \"ERC777: approve from the zero address\");\n require(spender != address(0), \"ERC777: approve to the zero address\");\n\n _allowances[holder][spender] = value;\n emit Approval(holder, spender, value);\n }\n\n /**\n * @dev Call from.tokensToSend() if the interface is registered\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _callTokensToSend(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n ) private {\n address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(from, _TOKENS_SENDER_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Sender(implementer).tokensToSend(operator, from, to, amount, userData, operatorData);\n }\n }\n\n /**\n * @dev Call to.tokensReceived() if the interface is registered. Reverts if the recipient is a contract but\n * tokensReceived() was not registered for the recipient\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _callTokensReceived(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) private {\n address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(to, _TOKENS_RECIPIENT_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Recipient(implementer).tokensReceived(operator, from, to, amount, userData, operatorData);\n } else if (requireReceptionAck) {\n require(!to.isContract(), \"ERC777: token recipient contract has no implementer for ERC777TokensRecipient\");\n }\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {IERC20-Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC777: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes\n * calls to {send}, {transfer}, {operatorSend}, {transferFrom}, minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be to transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address operator, address from, address to, uint256 amount) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC777/IERC777.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777Token standard as defined in the EIP.\n *\n * This contract uses the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 registry standard] to let\n * token holders and recipients react to token movements by using setting implementers\n * for the associated interfaces in said registry. See {IERC1820Registry} and\n * {ERC1820Implementer}.\n */\ninterface IERC777 {\n /**\n * @dev Emitted when `amount` tokens are created by `operator` and assigned to `to`.\n *\n * Note that some additional user `data` and `operatorData` can be logged in the event.\n */\n event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);\n\n /**\n * @dev Emitted when `operator` destroys `amount` tokens from `account`.\n *\n * Note that some additional user `data` and `operatorData` can be logged in the event.\n */\n event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);\n\n /**\n * @dev Emitted when `operator` is made operator for `tokenHolder`.\n */\n event AuthorizedOperator(address indexed operator, address indexed tokenHolder);\n\n /**\n * @dev Emitted when `operator` is revoked its operator status for `tokenHolder`.\n */\n event RevokedOperator(address indexed operator, address indexed tokenHolder);\n\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, usually a shorter version of the\n * name.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the smallest part of the token that is not divisible. This\n * means all token operations (creation, movement and destruction) must have\n * amounts that are a multiple of this number.\n *\n * For most token contracts, this value will equal 1.\n */\n function granularity() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by an account (`owner`).\n */\n function balanceOf(address owner) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * If send or receive hooks are registered for the caller and `recipient`,\n * the corresponding functions will be called with `data` and empty\n * `operatorData`. See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits a {Sent} event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function send(address recipient, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Destroys `amount` tokens from the caller's account, reducing the\n * total supply.\n *\n * If a send hook is registered for the caller, the corresponding function\n * will be called with `data` and empty `operatorData`. See {IERC777Sender}.\n *\n * Emits a {Burned} event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n */\n function burn(uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Returns true if an account is an operator of `tokenHolder`.\n * Operators can send and burn tokens on behalf of their owners. All\n * accounts are their own operator.\n *\n * See {operatorSend} and {operatorBurn}.\n */\n function isOperatorFor(address operator, address tokenHolder) external view returns (bool);\n\n /**\n * @dev Make an account an operator of the caller.\n *\n * See {isOperatorFor}.\n *\n * Emits an {AuthorizedOperator} event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function authorizeOperator(address operator) external;\n\n /**\n * @dev Revoke an account's operator status for the caller.\n *\n * See {isOperatorFor} and {defaultOperators}.\n *\n * Emits a {RevokedOperator} event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function revokeOperator(address operator) external;\n\n /**\n * @dev Returns the list of default operators. These accounts are operators\n * for all token holders, even if {authorizeOperator} was never called on\n * them.\n *\n * This list is immutable, but individual holders may revoke these via\n * {revokeOperator}, in which case {isOperatorFor} will return false.\n */\n function defaultOperators() external view returns (address[] memory);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must\n * be an operator of `sender`.\n *\n * If send or receive hooks are registered for `sender` and `recipient`,\n * the corresponding functions will be called with `data` and\n * `operatorData`. See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits a {Sent} event.\n *\n * Requirements\n *\n * - `sender` cannot be the zero address.\n * - `sender` must have at least `amount` tokens.\n * - the caller must be an operator for `sender`.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes calldata data,\n bytes calldata operatorData\n ) external;\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the total supply.\n * The caller must be an operator of `account`.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with `data` and `operatorData`. See {IERC777Sender}.\n *\n * Emits a {Burned} event.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n * - the caller must be an operator for `account`.\n */\n function operatorBurn(address account, uint256 amount, bytes calldata data, bytes calldata operatorData) external;\n\n event Sent(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes data,\n bytes operatorData\n );\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\n *\n * Accounts can be notified of {IERC777} tokens being sent to them by having a\n * contract implement this interface (contract holders can be their own\n * implementer) and registering it on the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\n *\n * See {IERC1820Registry} and {ERC1820Implementer}.\n */\ninterface IERC777Recipient {\n /**\n * @dev Called by an {IERC777} token contract whenever tokens are being\n * moved or created into a registered account (`to`). The type of operation\n * is conveyed by `from` being the zero address or not.\n *\n * This call occurs _after_ the token contract's state is updated, so\n * {IERC777-balanceOf}, etc., can be used to query the post-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensReceived(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777Sender.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Sender.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777TokensSender standard as defined in the EIP.\n *\n * {IERC777} Token holders can be notified of operations performed on their\n * tokens by having a contract implement this interface (contract holders can be\n * their own implementer) and registering it on the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\n *\n * See {IERC1820Registry} and {ERC1820Implementer}.\n */\ninterface IERC777Sender {\n /**\n * @dev Called by an {IERC777} token contract whenever a registered holder's\n * (`from`) tokens are about to be moved or destroyed. The type of operation\n * is conveyed by `to` being the zero address or not.\n *\n * This call occurs _before_ the token contract's state is updated, so\n * {IERC777-balanceOf}, etc., can be used to query the pre-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensToSend(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n *\n * Furthermore, `isContract` will also return true if the target contract within\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n * which only has an effect at the end of a transaction.\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Counters.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary Counters {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/ECDSA.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Strings.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV // Deprecated in v4.8\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n /// @solidity memory-safe-assembly\n assembly {\n mstore(0x00, \"\\x19Ethereum Signed Message:\\n32\")\n mstore(0x1c, hash)\n message := keccak256(0x00, 0x3c)\n }\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\n /// @solidity memory-safe-assembly\n assembly {\n let ptr := mload(0x40)\n mstore(ptr, \"\\x19\\x01\")\n mstore(add(ptr, 0x02), domainSeparator)\n mstore(add(ptr, 0x22), structHash)\n data := keccak256(ptr, 0x42)\n }\n }\n\n /**\n * @dev Returns an Ethereum Signed Data with intended validator, created from a\n * `validator` and `data` according to the version 0 of EIP-191.\n *\n * See {recover}.\n */\n function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x00\", validator, data));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/SignatureChecker.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSA.sol\";\nimport \"../../interfaces/IERC1271.sol\";\n\n/**\n * @dev Signature verification helper that can be used instead of `ECDSA.recover` to seamlessly support both ECDSA\n * signatures from externally owned accounts (EOAs) as well as ERC1271 signatures from smart contract wallets like\n * Argent and Gnosis Safe.\n *\n * _Available since v4.1._\n */\nlibrary SignatureChecker {\n /**\n * @dev Checks if a signature is valid for a given signer and data hash. If the signer is a smart contract, the\n * signature is validated against that smart contract using ERC1271, otherwise it's validated using `ECDSA.recover`.\n *\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\n */\n function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature) internal view returns (bool) {\n (address recovered, ECDSA.RecoverError error) = ECDSA.tryRecover(hash, signature);\n return\n (error == ECDSA.RecoverError.NoError && recovered == signer) ||\n isValidERC1271SignatureNow(signer, hash, signature);\n }\n\n /**\n * @dev Checks if a signature is valid for a given signer and data hash. The signature is validated\n * against the signer smart contract using ERC1271.\n *\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\n */\n function isValidERC1271SignatureNow(\n address signer,\n bytes32 hash,\n bytes memory signature\n ) internal view returns (bool) {\n (bool success, bytes memory result) = signer.staticcall(\n abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, signature)\n );\n return (success &&\n result.length >= 32 &&\n abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/ERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165 is IERC165 {\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165).interfaceId;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC1820Registry.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/introspection/IERC1820Registry.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the global ERC1820 Registry, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register\n * implementers for interfaces in this registry, as well as query support.\n *\n * Implementers may be shared by multiple accounts, and can also implement more\n * than a single interface for each account. Contracts can implement interfaces\n * for themselves, but externally-owned accounts (EOA) must delegate this to a\n * contract.\n *\n * {IERC165} interfaces can also be queried via the registry.\n *\n * For an in-depth explanation and source code analysis, see the EIP text.\n */\ninterface IERC1820Registry {\n event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer);\n\n event ManagerChanged(address indexed account, address indexed newManager);\n\n /**\n * @dev Sets `newManager` as the manager for `account`. A manager of an\n * account is able to set interface implementers for it.\n *\n * By default, each account is its own manager. Passing a value of `0x0` in\n * `newManager` will reset the manager to this initial state.\n *\n * Emits a {ManagerChanged} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `account`.\n */\n function setManager(address account, address newManager) external;\n\n /**\n * @dev Returns the manager for `account`.\n *\n * See {setManager}.\n */\n function getManager(address account) external view returns (address);\n\n /**\n * @dev Sets the `implementer` contract as ``account``'s implementer for\n * `interfaceHash`.\n *\n * `account` being the zero address is an alias for the caller's address.\n * The zero address can also be used in `implementer` to remove an old one.\n *\n * See {interfaceHash} to learn how these are created.\n *\n * Emits an {InterfaceImplementerSet} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `account`.\n * - `interfaceHash` must not be an {IERC165} interface id (i.e. it must not\n * end in 28 zeroes).\n * - `implementer` must implement {IERC1820Implementer} and return true when\n * queried for support, unless `implementer` is the caller. See\n * {IERC1820Implementer-canImplementInterfaceForAddress}.\n */\n function setInterfaceImplementer(address account, bytes32 _interfaceHash, address implementer) external;\n\n /**\n * @dev Returns the implementer of `interfaceHash` for `account`. If no such\n * implementer is registered, returns the zero address.\n *\n * If `interfaceHash` is an {IERC165} interface id (i.e. it ends with 28\n * zeroes), `account` will be queried for support of it.\n *\n * `account` being the zero address is an alias for the caller's address.\n */\n function getInterfaceImplementer(address account, bytes32 _interfaceHash) external view returns (address);\n\n /**\n * @dev Returns the interface hash for an `interfaceName`, as defined in the\n * corresponding\n * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP].\n */\n function interfaceHash(string calldata interfaceName) external pure returns (bytes32);\n\n /**\n * @notice Updates the cache with whether the contract implements an ERC165 interface or not.\n * @param account Address of the contract for which to update the cache.\n * @param interfaceId ERC165 interface for which to update the cache.\n */\n function updateERC165Cache(address account, bytes4 interfaceId) external;\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not.\n * If the result is not cached a direct lookup on the contract address is performed.\n * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling\n * {updateERC165Cache} with the contract address.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool);\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not without using or updating the cache.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/math/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\n // The surrounding unchecked block does not change this fact.\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1, \"Math: mulDiv overflow\");\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n //\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n //\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n //\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1 << (log2(a) >> 1);\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = sqrt(a);\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 2, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 128;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 64;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 32;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 16;\n }\n if (value >> 8 > 0) {\n value >>= 8;\n result += 8;\n }\n if (value >> 4 > 0) {\n value >>= 4;\n result += 4;\n }\n if (value >> 2 > 0) {\n value >>= 2;\n result += 2;\n }\n if (value >> 1 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log2(value);\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 10, rounded down, of a positive value.\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 + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 256, rounded down, of a positive value.\n * Returns 0 if given 0.\n *\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n */\n function log256(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 16;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 8;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 4;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 2;\n }\n if (value >> 8 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log256(value);\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/SafeCast.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCast {\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 * _Available since v4.7._\n */\n function toUint248(uint256 value) internal pure returns (uint248) {\n require(value <= type(uint248).max, \"SafeCast: value doesn't fit in 248 bits\");\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 * _Available since v4.7._\n */\n function toUint240(uint256 value) internal pure returns (uint240) {\n require(value <= type(uint240).max, \"SafeCast: value doesn't fit in 240 bits\");\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 * _Available since v4.7._\n */\n function toUint232(uint256 value) internal pure returns (uint232) {\n require(value <= type(uint232).max, \"SafeCast: value doesn't fit in 232 bits\");\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 * _Available since v4.2._\n */\n function toUint224(uint256 value) internal pure returns (uint224) {\n require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\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 * _Available since v4.7._\n */\n function toUint216(uint256 value) internal pure returns (uint216) {\n require(value <= type(uint216).max, \"SafeCast: value doesn't fit in 216 bits\");\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 * _Available since v4.7._\n */\n function toUint208(uint256 value) internal pure returns (uint208) {\n require(value <= type(uint208).max, \"SafeCast: value doesn't fit in 208 bits\");\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 * _Available since v4.7._\n */\n function toUint200(uint256 value) internal pure returns (uint200) {\n require(value <= type(uint200).max, \"SafeCast: value doesn't fit in 200 bits\");\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 * _Available since v4.7._\n */\n function toUint192(uint256 value) internal pure returns (uint192) {\n require(value <= type(uint192).max, \"SafeCast: value doesn't fit in 192 bits\");\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 * _Available since v4.7._\n */\n function toUint184(uint256 value) internal pure returns (uint184) {\n require(value <= type(uint184).max, \"SafeCast: value doesn't fit in 184 bits\");\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 * _Available since v4.7._\n */\n function toUint176(uint256 value) internal pure returns (uint176) {\n require(value <= type(uint176).max, \"SafeCast: value doesn't fit in 176 bits\");\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 * _Available since v4.7._\n */\n function toUint168(uint256 value) internal pure returns (uint168) {\n require(value <= type(uint168).max, \"SafeCast: value doesn't fit in 168 bits\");\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 * _Available since v4.7._\n */\n function toUint160(uint256 value) internal pure returns (uint160) {\n require(value <= type(uint160).max, \"SafeCast: value doesn't fit in 160 bits\");\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 * _Available since v4.7._\n */\n function toUint152(uint256 value) internal pure returns (uint152) {\n require(value <= type(uint152).max, \"SafeCast: value doesn't fit in 152 bits\");\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 * _Available since v4.7._\n */\n function toUint144(uint256 value) internal pure returns (uint144) {\n require(value <= type(uint144).max, \"SafeCast: value doesn't fit in 144 bits\");\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 * _Available since v4.7._\n */\n function toUint136(uint256 value) internal pure returns (uint136) {\n require(value <= type(uint136).max, \"SafeCast: value doesn't fit in 136 bits\");\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 * _Available since v2.5._\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\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 * _Available since v4.7._\n */\n function toUint120(uint256 value) internal pure returns (uint120) {\n require(value <= type(uint120).max, \"SafeCast: value doesn't fit in 120 bits\");\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 * _Available since v4.7._\n */\n function toUint112(uint256 value) internal pure returns (uint112) {\n require(value <= type(uint112).max, \"SafeCast: value doesn't fit in 112 bits\");\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 * _Available since v4.7._\n */\n function toUint104(uint256 value) internal pure returns (uint104) {\n require(value <= type(uint104).max, \"SafeCast: value doesn't fit in 104 bits\");\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 * _Available since v4.2._\n */\n function toUint96(uint256 value) internal pure returns (uint96) {\n require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\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 * _Available since v4.7._\n */\n function toUint88(uint256 value) internal pure returns (uint88) {\n require(value <= type(uint88).max, \"SafeCast: value doesn't fit in 88 bits\");\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 * _Available since v4.7._\n */\n function toUint80(uint256 value) internal pure returns (uint80) {\n require(value <= type(uint80).max, \"SafeCast: value doesn't fit in 80 bits\");\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 * _Available since v4.7._\n */\n function toUint72(uint256 value) internal pure returns (uint72) {\n require(value <= type(uint72).max, \"SafeCast: value doesn't fit in 72 bits\");\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 * _Available since v2.5._\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\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 * _Available since v4.7._\n */\n function toUint56(uint256 value) internal pure returns (uint56) {\n require(value <= type(uint56).max, \"SafeCast: value doesn't fit in 56 bits\");\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 * _Available since v4.7._\n */\n function toUint48(uint256 value) internal pure returns (uint48) {\n require(value <= type(uint48).max, \"SafeCast: value doesn't fit in 48 bits\");\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 * _Available since v4.7._\n */\n function toUint40(uint256 value) internal pure returns (uint40) {\n require(value <= type(uint40).max, \"SafeCast: value doesn't fit in 40 bits\");\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 * _Available since v2.5._\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\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 * _Available since v4.7._\n */\n function toUint24(uint256 value) internal pure returns (uint24) {\n require(value <= type(uint24).max, \"SafeCast: value doesn't fit in 24 bits\");\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 * _Available since v2.5._\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\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 * _Available since v2.5._\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\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 * _Available since v3.0._\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\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 * _Available since v4.7._\n */\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\n downcasted = int248(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 248 bits\");\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 * _Available since v4.7._\n */\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\n downcasted = int240(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 240 bits\");\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 * _Available since v4.7._\n */\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\n downcasted = int232(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 232 bits\");\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 * _Available since v4.7._\n */\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\n downcasted = int224(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 224 bits\");\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 * _Available since v4.7._\n */\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\n downcasted = int216(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 216 bits\");\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 * _Available since v4.7._\n */\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\n downcasted = int208(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 208 bits\");\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 * _Available since v4.7._\n */\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\n downcasted = int200(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 200 bits\");\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 * _Available since v4.7._\n */\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\n downcasted = int192(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 192 bits\");\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 * _Available since v4.7._\n */\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\n downcasted = int184(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 184 bits\");\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 * _Available since v4.7._\n */\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\n downcasted = int176(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 176 bits\");\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 * _Available since v4.7._\n */\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\n downcasted = int168(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 168 bits\");\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 * _Available since v4.7._\n */\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\n downcasted = int160(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 160 bits\");\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 * _Available since v4.7._\n */\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\n downcasted = int152(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 152 bits\");\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 * _Available since v4.7._\n */\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\n downcasted = int144(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 144 bits\");\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 * _Available since v4.7._\n */\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\n downcasted = int136(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 136 bits\");\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 * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\n downcasted = int128(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 128 bits\");\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 * _Available since v4.7._\n */\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\n downcasted = int120(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 120 bits\");\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 * _Available since v4.7._\n */\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\n downcasted = int112(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 112 bits\");\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 * _Available since v4.7._\n */\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\n downcasted = int104(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 104 bits\");\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 * _Available since v4.7._\n */\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\n downcasted = int96(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 96 bits\");\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 * _Available since v4.7._\n */\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\n downcasted = int88(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 88 bits\");\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 * _Available since v4.7._\n */\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\n downcasted = int80(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 80 bits\");\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 * _Available since v4.7._\n */\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\n downcasted = int72(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 72 bits\");\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 * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\n downcasted = int64(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 64 bits\");\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 * _Available since v4.7._\n */\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\n downcasted = int56(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 56 bits\");\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 * _Available since v4.7._\n */\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\n downcasted = int48(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 48 bits\");\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 * _Available since v4.7._\n */\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\n downcasted = int40(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 40 bits\");\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 * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\n downcasted = int32(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 32 bits\");\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 * _Available since v4.7._\n */\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\n downcasted = int24(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 24 bits\");\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 * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\n downcasted = int16(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 16 bits\");\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 * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\n downcasted = int8(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 8 bits\");\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 * _Available since v3.0._\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 require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/SignedMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard signed math utilities missing in the Solidity language.\n */\nlibrary SignedMath {\n /**\n * @dev Returns the largest of two signed numbers.\n */\n function max(int256 a, int256 b) internal pure returns (int256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two signed numbers.\n */\n function min(int256 a, int256 b) internal pure returns (int256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two signed numbers without overflow.\n * The result is rounded towards zero.\n */\n function average(int256 a, int256 b) internal pure returns (int256) {\n // Formula from the book \"Hacker's Delight\"\n int256 x = (a & b) + ((a ^ b) >> 1);\n return x + (int256(uint256(x) >> 255) & (a ^ b));\n }\n\n /**\n * @dev Returns the absolute unsigned value of a signed value.\n */\n function abs(int256 n) internal pure returns (uint256) {\n unchecked {\n // must be unchecked in order to support `n = type(int256).min`\n return uint256(n >= 0 ? n : -n);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/Math.sol\";\nimport \"./math/SignedMath.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n unchecked {\n uint256 length = Math.log10(value) + 1;\n string memory buffer = new string(length);\n uint256 ptr;\n /// @solidity memory-safe-assembly\n assembly {\n ptr := add(buffer, add(32, length))\n }\n while (true) {\n ptr--;\n /// @solidity memory-safe-assembly\n assembly {\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n }\n value /= 10;\n if (value == 0) break;\n }\n return buffer;\n }\n }\n\n /**\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\n */\n function toString(int256 value) internal pure returns (string memory) {\n return string(abi.encodePacked(value < 0 ? \"-\" : \"\", toString(SignedMath.abs(value))));\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n unchecked {\n return toHexString(value, Math.log256(value) + 1);\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n\n /**\n * @dev Returns true if the two strings are equal.\n */\n function equal(string memory a, string memory b) internal pure returns (bool) {\n return keccak256(bytes(a)) == keccak256(bytes(b));\n }\n}\n" + }, + "contracts/aa-4337/core/BaseAccount.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-empty-blocks */\n\nimport \"../interfaces/IAccount.sol\";\nimport \"../interfaces/IEntryPoint.sol\";\nimport \"./Helpers.sol\";\n\n/**\n * Basic account implementation.\n * this contract provides the basic logic for implementing the IAccount interface - validateUserOp\n * specific account implementation should inherit it and provide the account-specific logic\n */\nabstract contract BaseAccount is IAccount {\n using UserOperationLib for UserOperation;\n\n //return value in case of signature failure, with no time-range.\n // equivalent to _packValidationData(true,0,0);\n uint256 internal constant SIG_VALIDATION_FAILED = 1;\n\n /**\n * Return the account nonce.\n * This method returns the next sequential nonce.\n * For a nonce of a specific key, use `entrypoint.getNonce(account, key)`\n */\n function getNonce() public view virtual returns (uint256) {\n return entryPoint().getNonce(address(this), 0);\n }\n\n /**\n * return the entryPoint used by this account.\n * subclass should return the current entryPoint used by this account.\n */\n function entryPoint() public view virtual returns (IEntryPoint);\n\n /**\n * Validate user's signature and nonce.\n * subclass doesn't need to override this method. Instead, it should override the specific internal validation methods.\n */\n function validateUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 missingAccountFunds\n ) external virtual override returns (uint256 validationData) {\n _requireFromEntryPoint();\n validationData = _validateSignature(userOp, userOpHash);\n _validateNonce(userOp.nonce);\n _payPrefund(missingAccountFunds);\n }\n\n /**\n * ensure the request comes from the known entrypoint.\n */\n function _requireFromEntryPoint() internal view virtual {\n require(\n msg.sender == address(entryPoint()),\n \"account: not from EntryPoint\"\n );\n }\n\n /**\n * validate the signature is valid for this message.\n * @param userOp validate the userOp.signature field\n * @param userOpHash convenient field: the hash of the request, to check the signature against\n * (also hashes the entrypoint and chain id)\n * @return validationData signature and time-range of this operation\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * If the account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function _validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) internal virtual returns (uint256 validationData);\n\n /**\n * Validate the nonce of the UserOperation.\n * This method may validate the nonce requirement of this account.\n * e.g.\n * To limit the nonce to use sequenced UserOps only (no \"out of order\" UserOps):\n * `require(nonce < type(uint64).max)`\n * For a hypothetical account that *requires* the nonce to be out-of-order:\n * `require(nonce & type(uint64).max == 0)`\n *\n * The actual nonce uniqueness is managed by the EntryPoint, and thus no other\n * action is needed by the account itself.\n *\n * @param nonce to validate\n *\n * solhint-disable-next-line no-empty-blocks\n */\n function _validateNonce(uint256 nonce) internal view virtual {}\n\n /**\n * sends to the entrypoint (msg.sender) the missing funds for this transaction.\n * subclass MAY override this method for better funds management\n * (e.g. send to the entryPoint more than the minimum required, so that in future transactions\n * it will not be required to send again)\n * @param missingAccountFunds the minimum value this method should send the entrypoint.\n * this value MAY be zero, in case there is enough deposit, or the userOp has a paymaster.\n */\n function _payPrefund(uint256 missingAccountFunds) internal virtual {\n if (missingAccountFunds != 0) {\n (bool success, ) = payable(msg.sender).call{\n value: missingAccountFunds,\n gas: type(uint256).max\n }(\"\");\n (success);\n //ignore failure (its EntryPoint's job to verify, not account.)\n }\n }\n}\n" + }, + "contracts/aa-4337/core/EntryPoint.sol": { + "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n\nimport \"../interfaces/IAccount.sol\";\nimport \"../interfaces/IPaymaster.sol\";\nimport \"../interfaces/IEntryPoint.sol\";\n\nimport \"../utils/Exec.sol\";\nimport \"./StakeManager.sol\";\nimport \"./SenderCreator.sol\";\nimport \"./Helpers.sol\";\nimport \"./NonceManager.sol\";\nimport \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\n\ncontract EntryPoint is\n IEntryPoint,\n StakeManager,\n NonceManager,\n ReentrancyGuard\n{\n using UserOperationLib for UserOperation;\n\n SenderCreator private immutable senderCreator = new SenderCreator();\n\n // internal value used during simulation: need to query aggregator.\n address private constant SIMULATE_FIND_AGGREGATOR = address(1);\n\n // marker for inner call revert on out of gas\n bytes32 private constant INNER_OUT_OF_GAS = hex\"deaddead\";\n\n uint256 private constant REVERT_REASON_MAX_LEN = 2048;\n\n /**\n * for simulation purposes, validateUserOp (and validatePaymasterUserOp) must return this value\n * in case of signature failure, instead of revert.\n */\n uint256 public constant SIG_VALIDATION_FAILED = 1;\n\n /**\n * compensate the caller's beneficiary address with the collected fees of all UserOperations.\n * @param beneficiary the address to receive the fees\n * @param amount amount to transfer.\n */\n function _compensate(address payable beneficiary, uint256 amount) internal {\n require(beneficiary != address(0), \"AA90 invalid beneficiary\");\n (bool success, ) = beneficiary.call{value: amount}(\"\");\n require(success, \"AA91 failed send to beneficiary\");\n }\n\n /**\n * execute a user op\n * @param opIndex index into the opInfo array\n * @param userOp the userOp to execute\n * @param opInfo the opInfo filled by validatePrepayment for this userOp.\n * @return collected the total amount this userOp paid.\n */\n function _executeUserOp(\n uint256 opIndex,\n UserOperation calldata userOp,\n UserOpInfo memory opInfo\n ) private returns (uint256 collected) {\n uint256 preGas = gasleft();\n bytes memory context = getMemoryBytesFromOffset(opInfo.contextOffset);\n\n try this.innerHandleOp(userOp.callData, opInfo, context) returns (\n uint256 _actualGasCost\n ) {\n collected = _actualGasCost;\n } catch {\n bytes32 innerRevertCode;\n assembly {\n returndatacopy(0, 0, 32)\n innerRevertCode := mload(0)\n }\n // handleOps was called with gas limit too low. abort entire bundle.\n if (innerRevertCode == INNER_OUT_OF_GAS) {\n //report paymaster, since if it is not deliberately caused by the bundler,\n // it must be a revert caused by paymaster.\n revert FailedOp(opIndex, \"AA95 out of gas\");\n }\n\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n collected = _handlePostOp(\n opIndex,\n IPaymaster.PostOpMode.postOpReverted,\n opInfo,\n context,\n actualGas\n );\n }\n }\n\n /**\n * Execute a batch of UserOperations.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(\n UserOperation[] calldata ops,\n address payable beneficiary\n ) public nonReentrant {\n uint256 opslen = ops.length;\n UserOpInfo[] memory opInfos = new UserOpInfo[](opslen);\n\n unchecked {\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[i];\n (\n uint256 validationData,\n uint256 pmValidationData\n ) = _validatePrepayment(i, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(\n i,\n validationData,\n pmValidationData,\n address(0)\n );\n }\n\n uint256 collected = 0;\n emit BeforeExecution();\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(i, ops[i], opInfos[i]);\n }\n\n _compensate(beneficiary, collected);\n } //unchecked\n }\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) public nonReentrant {\n uint256 opasLen = opsPerAggregator.length;\n uint256 totalOps = 0;\n for (uint256 i = 0; i < opasLen; i++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[i];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n //address(1) is special marker of \"signature error\"\n require(\n address(aggregator) != address(1),\n \"AA96 invalid aggregator\"\n );\n\n if (address(aggregator) != address(0)) {\n // solhint-disable-next-line no-empty-blocks\n try aggregator.validateSignatures(ops, opa.signature) {} catch {\n revert SignatureValidationFailed(address(aggregator));\n }\n }\n\n totalOps += ops.length;\n }\n\n UserOpInfo[] memory opInfos = new UserOpInfo[](totalOps);\n\n emit BeforeExecution();\n\n uint256 opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n uint256 opslen = ops.length;\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[opIndex];\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(opIndex, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(\n i,\n validationData,\n paymasterValidationData,\n address(aggregator)\n );\n opIndex++;\n }\n }\n\n uint256 collected = 0;\n opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n emit SignatureAggregatorChanged(address(opa.aggregator));\n UserOperation[] calldata ops = opa.userOps;\n uint256 opslen = ops.length;\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(opIndex, ops[i], opInfos[opIndex]);\n opIndex++;\n }\n }\n emit SignatureAggregatorChanged(address(0));\n\n _compensate(beneficiary, collected);\n }\n\n /// @inheritdoc IEntryPoint\n function simulateHandleOp(\n UserOperation calldata op,\n address target,\n bytes calldata targetCallData\n ) external override {\n UserOpInfo memory opInfo;\n _simulationOnlyValidations(op);\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(0, op, opInfo);\n ValidationData memory data = _intersectTimeRange(\n validationData,\n paymasterValidationData\n );\n\n numberMarker();\n uint256 paid = _executeUserOp(0, op, opInfo);\n numberMarker();\n bool targetSuccess;\n bytes memory targetResult;\n if (target != address(0)) {\n (targetSuccess, targetResult) = target.call(targetCallData);\n }\n revert ExecutionResult(\n opInfo.preOpGas,\n paid,\n data.validAfter,\n data.validUntil,\n targetSuccess,\n targetResult\n );\n }\n\n // A memory copy of UserOp static fields only.\n // Excluding: callData, initCode and signature. Replacing paymasterAndData with paymaster.\n struct MemoryUserOp {\n address sender;\n uint256 nonce;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n address paymaster;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n }\n\n struct UserOpInfo {\n MemoryUserOp mUserOp;\n bytes32 userOpHash;\n uint256 prefund;\n uint256 contextOffset;\n uint256 preOpGas;\n }\n\n /**\n * inner function to handle a UserOperation.\n * Must be declared \"external\" to open a call context, but it can only be called by handleOps.\n */\n function innerHandleOp(\n bytes memory callData,\n UserOpInfo memory opInfo,\n bytes calldata context\n ) external returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n require(msg.sender == address(this), \"AA92 internal call only\");\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n\n uint callGasLimit = mUserOp.callGasLimit;\n unchecked {\n // handleOps was called with gas limit too low. abort entire bundle.\n if (\n gasleft() < callGasLimit + mUserOp.verificationGasLimit + 5000\n ) {\n assembly {\n mstore(0, INNER_OUT_OF_GAS)\n revert(0, 32)\n }\n }\n }\n\n IPaymaster.PostOpMode mode = IPaymaster.PostOpMode.opSucceeded;\n if (callData.length > 0) {\n bool success = Exec.call(mUserOp.sender, 0, callData, callGasLimit);\n if (!success) {\n bytes memory result = Exec.getReturnData(REVERT_REASON_MAX_LEN);\n if (result.length > 0) {\n emit UserOperationRevertReason(\n opInfo.userOpHash,\n mUserOp.sender,\n mUserOp.nonce,\n result\n );\n }\n mode = IPaymaster.PostOpMode.opReverted;\n }\n }\n\n unchecked {\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n //note: opIndex is ignored (relevant only if mode==postOpReverted, which is only possible outside of innerHandleOp)\n return _handlePostOp(0, mode, opInfo, context, actualGas);\n }\n }\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(\n UserOperation calldata userOp\n ) public view returns (bytes32) {\n return\n keccak256(abi.encode(userOp.hash(), address(this), block.chainid));\n }\n\n /**\n * copy general fields from userOp into the memory opInfo structure.\n */\n function _copyUserOpToMemory(\n UserOperation calldata userOp,\n MemoryUserOp memory mUserOp\n ) internal pure {\n mUserOp.sender = userOp.sender;\n mUserOp.nonce = userOp.nonce;\n mUserOp.callGasLimit = userOp.callGasLimit;\n mUserOp.verificationGasLimit = userOp.verificationGasLimit;\n mUserOp.preVerificationGas = userOp.preVerificationGas;\n mUserOp.maxFeePerGas = userOp.maxFeePerGas;\n mUserOp.maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes calldata paymasterAndData = userOp.paymasterAndData;\n if (paymasterAndData.length > 0) {\n require(\n paymasterAndData.length >= 20,\n \"AA93 invalid paymasterAndData\"\n );\n mUserOp.paymaster = address(bytes20(paymasterAndData[:20]));\n } else {\n mUserOp.paymaster = address(0);\n }\n }\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external {\n UserOpInfo memory outOpInfo;\n\n _simulationOnlyValidations(userOp);\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(0, userOp, outOpInfo);\n StakeInfo memory paymasterInfo = _getStakeInfo(\n outOpInfo.mUserOp.paymaster\n );\n StakeInfo memory senderInfo = _getStakeInfo(outOpInfo.mUserOp.sender);\n StakeInfo memory factoryInfo;\n {\n bytes calldata initCode = userOp.initCode;\n address factory = initCode.length >= 20\n ? address(bytes20(initCode[0:20]))\n : address(0);\n factoryInfo = _getStakeInfo(factory);\n }\n\n ValidationData memory data = _intersectTimeRange(\n validationData,\n paymasterValidationData\n );\n address aggregator = data.aggregator;\n bool sigFailed = aggregator == address(1);\n ReturnInfo memory returnInfo = ReturnInfo(\n outOpInfo.preOpGas,\n outOpInfo.prefund,\n sigFailed,\n data.validAfter,\n data.validUntil,\n getMemoryBytesFromOffset(outOpInfo.contextOffset)\n );\n\n if (aggregator != address(0) && aggregator != address(1)) {\n AggregatorStakeInfo memory aggregatorInfo = AggregatorStakeInfo(\n aggregator,\n _getStakeInfo(aggregator)\n );\n revert ValidationResultWithAggregation(\n returnInfo,\n senderInfo,\n factoryInfo,\n paymasterInfo,\n aggregatorInfo\n );\n }\n revert ValidationResult(\n returnInfo,\n senderInfo,\n factoryInfo,\n paymasterInfo\n );\n }\n\n function _getRequiredPrefund(\n MemoryUserOp memory mUserOp\n ) internal pure returns (uint256 requiredPrefund) {\n unchecked {\n //when using a Paymaster, the verificationGasLimit is used also to as a limit for the postOp call.\n // our security model might call postOp eventually twice\n uint256 mul = mUserOp.paymaster != address(0) ? 3 : 1;\n uint256 requiredGas = mUserOp.callGasLimit +\n mUserOp.verificationGasLimit *\n mul +\n mUserOp.preVerificationGas;\n\n requiredPrefund = requiredGas * mUserOp.maxFeePerGas;\n }\n }\n\n // create the sender's contract if needed.\n function _createSenderIfNeeded(\n uint256 opIndex,\n UserOpInfo memory opInfo,\n bytes calldata initCode\n ) internal {\n if (initCode.length != 0) {\n address sender = opInfo.mUserOp.sender;\n if (sender.code.length != 0)\n revert FailedOp(opIndex, \"AA10 sender already constructed\");\n address sender1 = senderCreator.createSender{\n gas: opInfo.mUserOp.verificationGasLimit\n }(initCode);\n if (sender1 == address(0))\n revert FailedOp(opIndex, \"AA13 initCode failed or OOG\");\n if (sender1 != sender)\n revert FailedOp(opIndex, \"AA14 initCode must return sender\");\n if (sender1.code.length == 0)\n revert FailedOp(opIndex, \"AA15 initCode must create sender\");\n address factory = address(bytes20(initCode[0:20]));\n emit AccountDeployed(\n opInfo.userOpHash,\n sender,\n factory,\n opInfo.mUserOp.paymaster\n );\n }\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes calldata initCode) public {\n address sender = senderCreator.createSender(initCode);\n revert SenderAddressResult(sender);\n }\n\n function _simulationOnlyValidations(\n UserOperation calldata userOp\n ) internal view {\n // solhint-disable-next-line no-empty-blocks\n try\n this._validateSenderAndPaymaster(\n userOp.initCode,\n userOp.sender,\n userOp.paymasterAndData\n )\n {} catch Error(string memory revertReason) {\n if (bytes(revertReason).length != 0) {\n revert FailedOp(0, revertReason);\n }\n }\n }\n\n /**\n * Called only during simulation.\n * This function always reverts to prevent warm/cold storage differentiation in simulation vs execution.\n */\n function _validateSenderAndPaymaster(\n bytes calldata initCode,\n address sender,\n bytes calldata paymasterAndData\n ) external view {\n if (initCode.length == 0 && sender.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA20 account not deployed\");\n }\n if (paymasterAndData.length >= 20) {\n address paymaster = address(bytes20(paymasterAndData[0:20]));\n if (paymaster.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA30 paymaster not deployed\");\n }\n }\n // always revert\n revert(\"\");\n }\n\n /**\n * call account.validateUserOp.\n * revert (with FailedOp) in case validateUserOp reverts, or account didn't send required prefund.\n * decrement account's deposit if needed\n */\n function _validateAccountPrepayment(\n uint256 opIndex,\n UserOperation calldata op,\n UserOpInfo memory opInfo,\n uint256 requiredPrefund\n )\n internal\n returns (\n uint256 gasUsedByValidateAccountPrepayment,\n uint256 validationData\n )\n {\n unchecked {\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n address sender = mUserOp.sender;\n _createSenderIfNeeded(opIndex, opInfo, op.initCode);\n address paymaster = mUserOp.paymaster;\n numberMarker();\n uint256 missingAccountFunds = 0;\n if (paymaster == address(0)) {\n uint256 bal = balanceOf(sender);\n missingAccountFunds = bal > requiredPrefund\n ? 0\n : requiredPrefund - bal;\n }\n try\n IAccount(sender).validateUserOp{\n gas: mUserOp.verificationGasLimit\n }(op, opInfo.userOpHash, missingAccountFunds)\n returns (uint256 _validationData) {\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA23 reverted: \", revertReason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA23 reverted (or OOG)\");\n }\n if (paymaster == address(0)) {\n DepositInfo storage senderInfo = deposits[sender];\n uint256 deposit = senderInfo.deposit;\n if (requiredPrefund > deposit) {\n revert FailedOp(opIndex, \"AA21 didn't pay prefund\");\n }\n senderInfo.deposit = uint112(deposit - requiredPrefund);\n }\n gasUsedByValidateAccountPrepayment = preGas - gasleft();\n }\n }\n\n /**\n * In case the request has a paymaster:\n * Validate paymaster has enough deposit.\n * Call paymaster.validatePaymasterUserOp.\n * Revert with proper FailedOp in case paymaster reverts.\n * Decrement paymaster's deposit\n */\n function _validatePaymasterPrepayment(\n uint256 opIndex,\n UserOperation calldata op,\n UserOpInfo memory opInfo,\n uint256 requiredPreFund,\n uint256 gasUsedByValidateAccountPrepayment\n ) internal returns (bytes memory context, uint256 validationData) {\n unchecked {\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 verificationGasLimit = mUserOp.verificationGasLimit;\n require(\n verificationGasLimit > gasUsedByValidateAccountPrepayment,\n \"AA41 too little verificationGas\"\n );\n uint256 gas = verificationGasLimit -\n gasUsedByValidateAccountPrepayment;\n\n address paymaster = mUserOp.paymaster;\n DepositInfo storage paymasterInfo = deposits[paymaster];\n uint256 deposit = paymasterInfo.deposit;\n if (deposit < requiredPreFund) {\n revert FailedOp(opIndex, \"AA31 paymaster deposit too low\");\n }\n paymasterInfo.deposit = uint112(deposit - requiredPreFund);\n try\n IPaymaster(paymaster).validatePaymasterUserOp{gas: gas}(\n op,\n opInfo.userOpHash,\n requiredPreFund\n )\n returns (bytes memory _context, uint256 _validationData) {\n context = _context;\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA33 reverted: \", revertReason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA33 reverted (or OOG)\");\n }\n }\n }\n\n /**\n * revert if either account validationData or paymaster validationData is expired\n */\n function _validateAccountAndPaymasterValidationData(\n uint256 opIndex,\n uint256 validationData,\n uint256 paymasterValidationData,\n address expectedAggregator\n ) internal view {\n (address aggregator, bool outOfTimeRange) = _getValidationData(\n validationData\n );\n if (expectedAggregator != aggregator) {\n revert FailedOp(opIndex, \"AA24 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA22 expired or not due\");\n }\n //pmAggregator is not a real signature aggregator: we don't have logic to handle it as address.\n // non-zero address means that the paymaster fails due to some signature check (which is ok only during estimation)\n address pmAggregator;\n (pmAggregator, outOfTimeRange) = _getValidationData(\n paymasterValidationData\n );\n if (pmAggregator != address(0)) {\n revert FailedOp(opIndex, \"AA34 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA32 paymaster expired or not due\");\n }\n }\n\n function _getValidationData(\n uint256 validationData\n ) internal view returns (address aggregator, bool outOfTimeRange) {\n if (validationData == 0) {\n return (address(0), false);\n }\n ValidationData memory data = _parseValidationData(validationData);\n // solhint-disable-next-line not-rely-on-time\n outOfTimeRange =\n block.timestamp > data.validUntil ||\n block.timestamp < data.validAfter;\n aggregator = data.aggregator;\n }\n\n /**\n * validate account and paymaster (if defined).\n * also make sure total validation doesn't exceed verificationGasLimit\n * this method is called off-chain (simulateValidation()) and on-chain (from handleOps)\n * @param opIndex the index of this userOp into the \"opInfos\" array\n * @param userOp the userOp to validate\n */\n function _validatePrepayment(\n uint256 opIndex,\n UserOperation calldata userOp,\n UserOpInfo memory outOpInfo\n )\n private\n returns (uint256 validationData, uint256 paymasterValidationData)\n {\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = outOpInfo.mUserOp;\n _copyUserOpToMemory(userOp, mUserOp);\n outOpInfo.userOpHash = getUserOpHash(userOp);\n\n // validate all numeric values in userOp are well below 128 bit, so they can safely be added\n // and multiplied without causing overflow\n uint256 maxGasValues = mUserOp.preVerificationGas |\n mUserOp.verificationGasLimit |\n mUserOp.callGasLimit |\n userOp.maxFeePerGas |\n userOp.maxPriorityFeePerGas;\n require(maxGasValues <= type(uint120).max, \"AA94 gas values overflow\");\n\n uint256 gasUsedByValidateAccountPrepayment;\n uint256 requiredPreFund = _getRequiredPrefund(mUserOp);\n (\n gasUsedByValidateAccountPrepayment,\n validationData\n ) = _validateAccountPrepayment(\n opIndex,\n userOp,\n outOpInfo,\n requiredPreFund\n );\n\n if (!_validateAndUpdateNonce(mUserOp.sender, mUserOp.nonce)) {\n revert FailedOp(opIndex, \"AA25 invalid account nonce\");\n }\n\n //a \"marker\" where account opcode validation is done and paymaster opcode validation is about to start\n // (used only by off-chain simulateValidation)\n numberMarker();\n\n bytes memory context;\n if (mUserOp.paymaster != address(0)) {\n (context, paymasterValidationData) = _validatePaymasterPrepayment(\n opIndex,\n userOp,\n outOpInfo,\n requiredPreFund,\n gasUsedByValidateAccountPrepayment\n );\n }\n unchecked {\n uint256 gasUsed = preGas - gasleft();\n\n if (userOp.verificationGasLimit < gasUsed) {\n revert FailedOp(opIndex, \"AA40 over verificationGasLimit\");\n }\n outOpInfo.prefund = requiredPreFund;\n outOpInfo.contextOffset = getOffsetOfMemoryBytes(context);\n outOpInfo.preOpGas = preGas - gasleft() + userOp.preVerificationGas;\n }\n }\n\n /**\n * process post-operation.\n * called just after the callData is executed.\n * if a paymaster is defined and its validation returned a non-empty context, its postOp is called.\n * the excess amount is refunded to the account (or paymaster - if it was used in the request)\n * @param opIndex index in the batch\n * @param mode - whether is called from innerHandleOp, or outside (postOpReverted)\n * @param opInfo userOp fields and info collected during validation\n * @param context the context returned in validatePaymasterUserOp\n * @param actualGas the gas used so far by this user operation\n */\n function _handlePostOp(\n uint256 opIndex,\n IPaymaster.PostOpMode mode,\n UserOpInfo memory opInfo,\n bytes memory context,\n uint256 actualGas\n ) private returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n unchecked {\n address refundAddress;\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 gasPrice = getUserOpGasPrice(mUserOp);\n\n address paymaster = mUserOp.paymaster;\n if (paymaster == address(0)) {\n refundAddress = mUserOp.sender;\n } else {\n refundAddress = paymaster;\n if (context.length > 0) {\n actualGasCost = actualGas * gasPrice;\n if (mode != IPaymaster.PostOpMode.postOpReverted) {\n IPaymaster(paymaster).postOp{\n gas: mUserOp.verificationGasLimit\n }(mode, context, actualGasCost);\n } else {\n // solhint-disable-next-line no-empty-blocks\n try\n IPaymaster(paymaster).postOp{\n gas: mUserOp.verificationGasLimit\n }(mode, context, actualGasCost)\n {} catch Error(string memory reason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA50 postOp reverted: \", reason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA50 postOp revert\");\n }\n }\n }\n }\n actualGas += preGas - gasleft();\n actualGasCost = actualGas * gasPrice;\n if (opInfo.prefund < actualGasCost) {\n revert FailedOp(opIndex, \"AA51 prefund below actualGasCost\");\n }\n uint256 refund = opInfo.prefund - actualGasCost;\n _incrementDeposit(refundAddress, refund);\n bool success = mode == IPaymaster.PostOpMode.opSucceeded;\n emit UserOperationEvent(\n opInfo.userOpHash,\n mUserOp.sender,\n mUserOp.paymaster,\n mUserOp.nonce,\n success,\n actualGasCost,\n actualGas\n );\n } // unchecked\n }\n\n /**\n * the gas price this UserOp agrees to pay.\n * relayer/block builder might submit the TX with higher priorityFee, but the user should not\n */\n function getUserOpGasPrice(\n MemoryUserOp memory mUserOp\n ) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = mUserOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = mUserOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n function getOffsetOfMemoryBytes(\n bytes memory data\n ) internal pure returns (uint256 offset) {\n assembly {\n offset := data\n }\n }\n\n function getMemoryBytesFromOffset(\n uint256 offset\n ) internal pure returns (bytes memory data) {\n assembly {\n data := offset\n }\n }\n\n //place the NUMBER opcode in the code.\n // this is used as a marker during simulation, as this OP is completely banned from the simulated code of the\n // account and paymaster.\n function numberMarker() internal view {\n assembly {\n mstore(0, number())\n }\n }\n}\n" + }, + "contracts/aa-4337/core/Helpers.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable no-inline-assembly */\n\n/**\n * returned data from validateUserOp.\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\n * @param aggregator - address(0) - the account validated the signature by itself.\n * address(1) - the account failed to validate the signature.\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\n * @param validAfter - this UserOp is valid only after this timestamp.\n * @param validaUntil - this UserOp is valid only up to this timestamp.\n */\nstruct ValidationData {\n address aggregator;\n uint48 validAfter;\n uint48 validUntil;\n}\n\n//extract sigFailed, validAfter, validUntil.\n// also convert zero validUntil to type(uint48).max\nfunction _parseValidationData(\n uint validationData\n) pure returns (ValidationData memory data) {\n address aggregator = address(uint160(validationData));\n uint48 validUntil = uint48(validationData >> 160);\n if (validUntil == 0) {\n validUntil = type(uint48).max;\n }\n uint48 validAfter = uint48(validationData >> (48 + 160));\n return ValidationData(aggregator, validAfter, validUntil);\n}\n\n// intersect account and paymaster ranges.\nfunction _intersectTimeRange(\n uint256 validationData,\n uint256 paymasterValidationData\n) pure returns (ValidationData memory) {\n ValidationData memory accountValidationData = _parseValidationData(\n validationData\n );\n ValidationData memory pmValidationData = _parseValidationData(\n paymasterValidationData\n );\n address aggregator = accountValidationData.aggregator;\n if (aggregator == address(0)) {\n aggregator = pmValidationData.aggregator;\n }\n uint48 validAfter = accountValidationData.validAfter;\n uint48 validUntil = accountValidationData.validUntil;\n uint48 pmValidAfter = pmValidationData.validAfter;\n uint48 pmValidUntil = pmValidationData.validUntil;\n\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\n return ValidationData(aggregator, validAfter, validUntil);\n}\n\n/**\n * helper to pack the return value for validateUserOp\n * @param data - the ValidationData to pack\n */\nfunction _packValidationData(\n ValidationData memory data\n) pure returns (uint256) {\n return\n uint160(data.aggregator) |\n (uint256(data.validUntil) << 160) |\n (uint256(data.validAfter) << (160 + 48));\n}\n\n/**\n * helper to pack the return value for validateUserOp, when not using an aggregator\n * @param sigFailed - true for signature failure, false for success\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\n * @param validAfter first timestamp this UserOperation is valid\n */\nfunction _packValidationData(\n bool sigFailed,\n uint48 validUntil,\n uint48 validAfter\n) pure returns (uint256) {\n return\n (sigFailed ? 1 : 0) |\n (uint256(validUntil) << 160) |\n (uint256(validAfter) << (160 + 48));\n}\n\n/**\n * keccak function over calldata.\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\n */\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\n assembly {\n let mem := mload(0x40)\n let len := data.length\n calldatacopy(mem, data.offset, len)\n ret := keccak256(mem, len)\n }\n}\n" + }, + "contracts/aa-4337/core/NonceManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\nimport \"../interfaces/IEntryPoint.sol\";\n\n/**\n * nonce management functionality\n */\ncontract NonceManager is INonceManager {\n /**\n * The next valid sequence number for a given nonce key.\n */\n mapping(address => mapping(uint192 => uint256)) public nonceSequenceNumber;\n\n function getNonce(\n address sender,\n uint192 key\n ) public view override returns (uint256 nonce) {\n return nonceSequenceNumber[sender][key] | (uint256(key) << 64);\n }\n\n // allow an account to manually increment its own nonce.\n // (mainly so that during construction nonce can be made non-zero,\n // to \"absorb\" the gas cost of first nonce increment to 1st transaction (construction),\n // not to 2nd transaction)\n function incrementNonce(uint192 key) public override {\n nonceSequenceNumber[msg.sender][key]++;\n }\n\n /**\n * validate nonce uniqueness for this account.\n * called just after validateUserOp()\n */\n function _validateAndUpdateNonce(\n address sender,\n uint256 nonce\n ) internal returns (bool) {\n uint192 key = uint192(nonce >> 64);\n uint64 seq = uint64(nonce);\n return nonceSequenceNumber[sender][key]++ == seq;\n }\n}\n" + }, + "contracts/aa-4337/core/SenderCreator.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/**\n * helper contract for EntryPoint, to call userOp.initCode from a \"neutral\" address,\n * which is explicitly not the entryPoint itself.\n */\ncontract SenderCreator {\n /**\n * call the \"initCode\" factory to create and return the sender account address\n * @param initCode the initCode value from a UserOp. contains 20 bytes of factory address, followed by calldata\n * @return sender the returned address of the created account, or zero address on failure.\n */\n function createSender(\n bytes calldata initCode\n ) external returns (address sender) {\n address factory = address(bytes20(initCode[0:20]));\n bytes memory initCallData = initCode[20:];\n bool success;\n /* solhint-disable no-inline-assembly */\n assembly {\n success := call(\n gas(),\n factory,\n 0,\n add(initCallData, 0x20),\n mload(initCallData),\n 0,\n 32\n )\n sender := mload(0)\n }\n if (!success) {\n sender = address(0);\n }\n }\n}\n" + }, + "contracts/aa-4337/core/StakeManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity 0.8.21;\n\nimport \"../interfaces/IStakeManager.sol\";\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable not-rely-on-time */\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by a paymaster.\n */\nabstract contract StakeManager is IStakeManager {\n /// maps paymaster to their deposits and stakes\n mapping(address => DepositInfo) public deposits;\n\n /// @inheritdoc IStakeManager\n function getDepositInfo(\n address account\n ) public view returns (DepositInfo memory info) {\n return deposits[account];\n }\n\n // internal method to return just the stake info\n function _getStakeInfo(\n address addr\n ) internal view returns (StakeInfo memory info) {\n DepositInfo storage depositInfo = deposits[addr];\n info.stake = depositInfo.stake;\n info.unstakeDelaySec = depositInfo.unstakeDelaySec;\n }\n\n /// return the deposit (for gas payment) of the account\n function balanceOf(address account) public view returns (uint256) {\n return deposits[account].deposit;\n }\n\n receive() external payable {\n depositTo(msg.sender);\n }\n\n function _incrementDeposit(address account, uint256 amount) internal {\n DepositInfo storage info = deposits[account];\n uint256 newAmount = info.deposit + amount;\n require(newAmount <= type(uint112).max, \"deposit overflow\");\n info.deposit = uint112(newAmount);\n }\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) public payable {\n _incrementDeposit(account, msg.value);\n DepositInfo storage info = deposits[account];\n emit Deposited(account, info.deposit);\n }\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 unstakeDelaySec) public payable {\n DepositInfo storage info = deposits[msg.sender];\n require(unstakeDelaySec > 0, \"must specify unstake delay\");\n require(\n unstakeDelaySec >= info.unstakeDelaySec,\n \"cannot decrease unstake time\"\n );\n uint256 stake = info.stake + msg.value;\n require(stake > 0, \"no stake specified\");\n require(stake <= type(uint112).max, \"stake overflow\");\n deposits[msg.sender] = DepositInfo(\n info.deposit,\n true,\n uint112(stake),\n unstakeDelaySec,\n 0\n );\n emit StakeLocked(msg.sender, stake, unstakeDelaySec);\n }\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external {\n DepositInfo storage info = deposits[msg.sender];\n require(info.unstakeDelaySec != 0, \"not staked\");\n require(info.staked, \"already unstaking\");\n uint48 withdrawTime = uint48(block.timestamp) + info.unstakeDelaySec;\n info.withdrawTime = withdrawTime;\n info.staked = false;\n emit StakeUnlocked(msg.sender, withdrawTime);\n }\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external {\n DepositInfo storage info = deposits[msg.sender];\n uint256 stake = info.stake;\n require(stake > 0, \"No stake to withdraw\");\n require(info.withdrawTime > 0, \"must call unlockStake() first\");\n require(\n info.withdrawTime <= block.timestamp,\n \"Stake withdrawal is not due\"\n );\n info.unstakeDelaySec = 0;\n info.withdrawTime = 0;\n info.stake = 0;\n emit StakeWithdrawn(msg.sender, withdrawAddress, stake);\n (bool success, ) = withdrawAddress.call{value: stake}(\"\");\n require(success, \"failed to withdraw stake\");\n }\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(\n address payable withdrawAddress,\n uint256 withdrawAmount\n ) external {\n DepositInfo storage info = deposits[msg.sender];\n require(withdrawAmount <= info.deposit, \"Withdraw amount too large\");\n info.deposit = uint112(info.deposit - withdrawAmount);\n emit Withdrawn(msg.sender, withdrawAddress, withdrawAmount);\n (bool success, ) = withdrawAddress.call{value: withdrawAmount}(\"\");\n require(success, \"failed to withdraw\");\n }\n}\n" + }, + "contracts/aa-4337/interfaces/IAccount.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\ninterface IAccount {\n /**\n * Validate user's signature and nonce\n * the entryPoint will make the call to the recipient only if this validation call returns successfully.\n * signature failure should be reported by returning SIG_VALIDATION_FAILED (1).\n * This allows making a \"simulation call\" without a valid signature\n * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure.\n *\n * @dev Must validate caller is the entryPoint.\n * Must validate the signature and nonce\n * @param userOp the operation that is about to be executed.\n * @param userOpHash hash of the user's request data. can be used as the basis for signature.\n * @param missingAccountFunds missing funds on the account's deposit in the entrypoint.\n * This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call.\n * The excess is left as a deposit in the entrypoint, for future calls.\n * can be withdrawn anytime using \"entryPoint.withdrawTo()\"\n * In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero.\n * @return validationData packaged ValidationData structure. use `_packValidationData` and `_unpackValidationData` to encode and decode\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * If an account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validateUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 missingAccountFunds\n ) external returns (uint256 validationData);\n}\n" + }, + "contracts/aa-4337/interfaces/IAggregator.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * Aggregated Signatures validator.\n */\ninterface IAggregator {\n /**\n * validate aggregated signature.\n * revert if the aggregated signature does not match the given list of operations.\n */\n function validateSignatures(\n UserOperation[] calldata userOps,\n bytes calldata signature\n ) external view;\n\n /**\n * validate signature of a single userOp\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\n * @param userOp the userOperation received from the user.\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\n * (usually empty, unless account and aggregator support some kind of \"multisig\"\n */\n function validateUserOpSignature(\n UserOperation calldata userOp\n ) external view returns (bytes memory sigForUserOp);\n\n /**\n * aggregate multiple signatures into a single value.\n * This method is called off-chain to calculate the signature to pass with handleOps()\n * bundler MAY use optimized custom code perform this aggregation\n * @param userOps array of UserOperations to collect the signatures from.\n * @return aggregatedSignature the aggregated signature\n */\n function aggregateSignatures(\n UserOperation[] calldata userOps\n ) external view returns (bytes memory aggregatedSignature);\n}\n" + }, + "contracts/aa-4337/interfaces/IEntryPoint.sol": { + "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n/* solhint-disable reason-string */\n\nimport \"./UserOperation.sol\";\nimport \"./IStakeManager.sol\";\nimport \"./IAggregator.sol\";\nimport \"./INonceManager.sol\";\n\ninterface IEntryPoint is IStakeManager, INonceManager {\n /***\n * An event emitted after each successful request\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\n * @param sender - the account that generates this request.\n * @param paymaster - if non-null, the paymaster that pays for this request.\n * @param nonce - the nonce value from the request.\n * @param success - true if the sender transaction succeeded, false if reverted.\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\n */\n event UserOperationEvent(\n bytes32 indexed userOpHash,\n address indexed sender,\n address indexed paymaster,\n uint256 nonce,\n bool success,\n uint256 actualGasCost,\n uint256 actualGasUsed\n );\n\n /**\n * account \"sender\" was deployed.\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\n * @param sender the account that is deployed\n * @param factory the factory used to deploy this account (in the initCode)\n * @param paymaster the paymaster used by this UserOp\n */\n event AccountDeployed(\n bytes32 indexed userOpHash,\n address indexed sender,\n address factory,\n address paymaster\n );\n\n /**\n * An event emitted if the UserOperation \"callData\" reverted with non-zero length\n * @param userOpHash the request unique identifier.\n * @param sender the sender of this request\n * @param nonce the nonce used in the request\n * @param revertReason - the return bytes from the (reverted) call to \"callData\".\n */\n event UserOperationRevertReason(\n bytes32 indexed userOpHash,\n address indexed sender,\n uint256 nonce,\n bytes revertReason\n );\n\n /**\n * an event emitted by handleOps(), before starting the execution loop.\n * any event emitted before this event, is part of the validation.\n */\n event BeforeExecution();\n\n /**\n * signature aggregator used by the following UserOperationEvents within this bundle.\n */\n event SignatureAggregatorChanged(address indexed aggregator);\n\n /**\n * a custom revert error of handleOps, to identify the offending op.\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\n * @param reason - revert reason\n * The string starts with a unique code \"AAmn\", where \"m\" is \"1\" for factory, \"2\" for account and \"3\" for paymaster issues,\n * so a failure can be attributed to the correct entity.\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\n */\n error FailedOp(uint256 opIndex, string reason);\n\n /**\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\n */\n error SignatureValidationFailed(address aggregator);\n\n /**\n * Successful result from simulateValidation.\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n */\n error ValidationResult(\n ReturnInfo returnInfo,\n StakeInfo senderInfo,\n StakeInfo factoryInfo,\n StakeInfo paymasterInfo\n );\n\n /**\n * Successful result from simulateValidation, if the account returns a signature aggregator\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\n * bundler MUST use it to verify the signature, or reject the UserOperation\n */\n error ValidationResultWithAggregation(\n ReturnInfo returnInfo,\n StakeInfo senderInfo,\n StakeInfo factoryInfo,\n StakeInfo paymasterInfo,\n AggregatorStakeInfo aggregatorInfo\n );\n\n /**\n * return value of getSenderAddress\n */\n error SenderAddressResult(address sender);\n\n /**\n * return value of simulateHandleOp\n */\n error ExecutionResult(\n uint256 preOpGas,\n uint256 paid,\n uint48 validAfter,\n uint48 validUntil,\n bool targetSuccess,\n bytes targetResult\n );\n\n //UserOps handled, per aggregator\n struct UserOpsPerAggregator {\n UserOperation[] userOps;\n // aggregator address\n IAggregator aggregator;\n // aggregated signature\n bytes signature;\n }\n\n /**\n * Execute a batch of UserOperation.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(\n UserOperation[] calldata ops,\n address payable beneficiary\n ) external;\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) external;\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(\n UserOperation calldata userOp\n ) external view returns (bytes32);\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external;\n\n /**\n * gas and return values during simulation\n * @param preOpGas the gas used for validation (including preValidationGas)\n * @param prefund the required prefund for this operation\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\n */\n struct ReturnInfo {\n uint256 preOpGas;\n uint256 prefund;\n bool sigFailed;\n uint48 validAfter;\n uint48 validUntil;\n bytes paymasterContext;\n }\n\n /**\n * returned aggregated signature info.\n * the aggregator returned by the account, and its current stake.\n */\n struct AggregatorStakeInfo {\n address aggregator;\n StakeInfo stakeInfo;\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes memory initCode) external;\n\n /**\n * simulate full execution of a UserOperation (including both validation and target execution)\n * this method will always revert with \"ExecutionResult\".\n * it performs full validation of the UserOperation, but ignores signature error.\n * an optional target address is called after the userop succeeds, and its value is returned\n * (before the entire call is reverted)\n * Note that in order to collect the the success/failure of the target call, it must be executed\n * with trace enabled to track the emitted events.\n * @param op the UserOperation to simulate\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\n * are set to the return from that call.\n * @param targetCallData callData to pass to target address\n */\n function simulateHandleOp(\n UserOperation calldata op,\n address target,\n bytes calldata targetCallData\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/INonceManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\ninterface INonceManager {\n /**\n * Return the next nonce for this sender.\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\n * But UserOp with different keys can come with arbitrary order.\n *\n * @param sender the account address\n * @param key the high 192 bit of the nonce\n * @return nonce a full nonce to pass for next UserOp with this sender.\n */\n function getNonce(\n address sender,\n uint192 key\n ) external view returns (uint256 nonce);\n\n /**\n * Manually increment the nonce of the sender.\n * This method is exposed just for completeness..\n * Account does NOT need to call it, neither during validation, nor elsewhere,\n * as the EntryPoint will update the nonce regardless.\n * Possible use-case is call it with various keys to \"initialize\" their nonces to one, so that future\n * UserOperations will not pay extra for the first transaction with a given key.\n */\n function incrementNonce(uint192 key) external;\n}\n" + }, + "contracts/aa-4337/interfaces/IPaymaster.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * the interface exposed by a paymaster contract, who agrees to pay the gas for user's operations.\n * a paymaster must hold a stake to cover the required entrypoint stake and also the gas for the transaction.\n */\ninterface IPaymaster {\n enum PostOpMode {\n opSucceeded, // user op succeeded\n opReverted, // user op reverted. still has to pay for gas.\n postOpReverted //user op succeeded, but caused postOp to revert. Now it's a 2nd call, after user's op was deliberately reverted.\n }\n\n /**\n * payment validation: check if paymaster agrees to pay.\n * Must verify sender is the entryPoint.\n * Revert to reject this request.\n * Note that bundlers will reject this method if it changes the state, unless the paymaster is trusted (whitelisted)\n * The paymaster pre-pays using its deposit, and receive back a refund after the postOp method returns.\n * @param userOp the user operation\n * @param userOpHash hash of the user's request data.\n * @param maxCost the maximum cost of this transaction (based on maximum gas and gas price from userOp)\n * @return context value to send to a postOp\n * zero length to signify postOp is not required.\n * @return validationData signature and time-range of this operation, encoded the same as the return value of validateUserOperation\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validatePaymasterUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 maxCost\n ) external returns (bytes memory context, uint256 validationData);\n\n /**\n * post-operation handler.\n * Must verify sender is the entryPoint\n * @param mode enum with the following options:\n * opSucceeded - user operation succeeded.\n * opReverted - user op reverted. still has to pay for gas.\n * postOpReverted - user op succeeded, but caused postOp (in mode=opSucceeded) to revert.\n * Now this is the 2nd call, after user's op was deliberately reverted.\n * @param context - the context value returned by validatePaymasterUserOp\n * @param actualGasCost - actual gas used so far (without this postOp call).\n */\n function postOp(\n PostOpMode mode,\n bytes calldata context,\n uint256 actualGasCost\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/IStakeManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.12;\n\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by the staked entity.\n */\ninterface IStakeManager {\n event Deposited(address indexed account, uint256 totalDeposit);\n\n event Withdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /// Emitted when stake or unstake delay are modified\n event StakeLocked(\n address indexed account,\n uint256 totalStaked,\n uint256 unstakeDelaySec\n );\n\n /// Emitted once a stake is scheduled for withdrawal\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\n\n event StakeWithdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /**\n * @param deposit the entity's deposit\n * @param staked true if this entity is staked.\n * @param stake actual amount of ether staked for this entity.\n * @param unstakeDelaySec minimum delay to withdraw the stake.\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\n * and the rest fit into a 2nd cell.\n * 112 bit allows for 10^15 eth\n * 48 bit for full timestamp\n * 32 bit allows 150 years for unstake delay\n */\n struct DepositInfo {\n uint112 deposit;\n bool staked;\n uint112 stake;\n uint32 unstakeDelaySec;\n uint48 withdrawTime;\n }\n\n //API struct used by getStakeInfo and simulateValidation\n struct StakeInfo {\n uint256 stake;\n uint256 unstakeDelaySec;\n }\n\n /// @return info - full deposit information of given account\n function getDepositInfo(\n address account\n ) external view returns (DepositInfo memory info);\n\n /// @return the deposit (for gas payment) of the account\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) external payable;\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 _unstakeDelaySec) external payable;\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external;\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external;\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(\n address payable withdrawAddress,\n uint256 withdrawAmount\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/UserOperation.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable no-inline-assembly */\n\nimport {calldataKeccak} from \"../core/Helpers.sol\";\n\n/**\n * User Operation struct\n * @param sender the sender account of this request.\n * @param nonce unique value the sender uses to verify it is not a replay.\n * @param initCode if set, the account contract will be created by this constructor/\n * @param callData the method call to execute on this account.\n * @param callGasLimit the gas limit passed to the callData method call.\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\n * @param maxFeePerGas same as EIP-1559 gas parameter.\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\n */\nstruct UserOperation {\n address sender;\n uint256 nonce;\n bytes initCode;\n bytes callData;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n bytes paymasterAndData;\n bytes signature;\n}\n\n/**\n * Utility functions helpful when working with UserOperation structs.\n */\nlibrary UserOperationLib {\n function getSender(\n UserOperation calldata userOp\n ) internal pure returns (address) {\n address data;\n //read sender from userOp, which is first userOp member (saves 800 gas...)\n assembly {\n data := calldataload(userOp)\n }\n return address(uint160(data));\n }\n\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\n // pay above what he signed for.\n function gasPrice(\n UserOperation calldata userOp\n ) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function pack(\n UserOperation calldata userOp\n ) internal pure returns (bytes memory ret) {\n address sender = getSender(userOp);\n uint256 nonce = userOp.nonce;\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\n bytes32 hashCallData = calldataKeccak(userOp.callData);\n uint256 callGasLimit = userOp.callGasLimit;\n uint256 verificationGasLimit = userOp.verificationGasLimit;\n uint256 preVerificationGas = userOp.preVerificationGas;\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\n\n return\n abi.encode(\n sender,\n nonce,\n hashInitCode,\n hashCallData,\n callGasLimit,\n verificationGasLimit,\n preVerificationGas,\n maxFeePerGas,\n maxPriorityFeePerGas,\n hashPaymasterAndData\n );\n }\n\n function hash(\n UserOperation calldata userOp\n ) internal pure returns (bytes32) {\n return keccak256(pack(userOp));\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n}\n" + }, + "contracts/aa-4337/utils/Exec.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.5 <0.9.0;\n\n// solhint-disable no-inline-assembly\n\n/**\n * Utility functions helpful when making different kinds of contract calls in Solidity.\n */\nlibrary Exec {\n function call(\n address to,\n uint256 value,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := call(\n txGas,\n to,\n value,\n add(data, 0x20),\n mload(data),\n 0,\n 0\n )\n }\n }\n\n function staticcall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal view returns (bool success) {\n assembly {\n success := staticcall(txGas, to, add(data, 0x20), mload(data), 0, 0)\n }\n }\n\n function delegateCall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := delegatecall(\n txGas,\n to,\n add(data, 0x20),\n mload(data),\n 0,\n 0\n )\n }\n }\n\n // get returned data from last call or calldelegate\n function getReturnData(\n uint256 maxLen\n ) internal pure returns (bytes memory returnData) {\n assembly {\n let len := returndatasize()\n if gt(len, maxLen) {\n len := maxLen\n }\n let ptr := mload(0x40)\n mstore(0x40, add(ptr, add(len, 0x20)))\n mstore(ptr, len)\n returndatacopy(add(ptr, 0x20), 0, len)\n returnData := ptr\n }\n }\n\n // revert with explicit byte array (probably reverted info from call)\n function revertWithData(bytes memory returnData) internal pure {\n assembly {\n revert(add(returnData, 32), mload(returnData))\n }\n }\n\n function callAndRevert(\n address to,\n bytes memory data,\n uint256 maxLen\n ) internal {\n bool success = call(to, 0, data, gasleft());\n if (!success) {\n revertWithData(getReturnData(maxLen));\n }\n }\n}\n" + }, + "contracts/Barz.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"./libraries/LibDiamond.sol\";\nimport {IBarz} from \"./interfaces/IBarz.sol\";\n\n/**\n * @title Barz\n * @dev A diamond proxy wallet with a modular & upgradeable architecture\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract Barz is IBarz {\n /**\n * @notice Initializes Barz with the given parameters. Barz account is intended to be created from Barz Factory for stable deployment.\n * @dev This method makes a delegate call to account facet and account facet handles the initialization.\n * With modular architecture, Barz encompasses wide spectrum of architecture and logic.\n * The only requirement is account facet to comply with initialize() interface.\n * Barz doesn't include built-in functions and is a full proxy, for maximum extensibility and modularity.\n * @param _accountFacet Address of Account Facet in charge of the Barz initialization\n * @param _verificationFacet Address of Verification Facet for verifying the signature. Could be any signature scheme\n * @param _entryPoint Address of Entry Point contract\n * @param _facetRegistry Address of Facet Registry. Facet Registry is a registry holding trusted facets that could be added to user's wallet\n * @param _defaultFallBack Address of Default FallBack Handler. Middleware contract for more efficient deployment\n * @param _ownerPublicKey Bytes of Owner Public Key using for initialization\n */\n constructor(\n address _accountFacet,\n address _verificationFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallBack,\n bytes memory _ownerPublicKey\n ) payable {\n bytes memory initCall = abi.encodeWithSignature(\n \"initialize(address,address,address,address,bytes)\",\n _verificationFacet,\n _entryPoint,\n _facetRegistry,\n _defaultFallBack,\n _ownerPublicKey\n );\n (bool success, bytes memory result) = _accountFacet.delegatecall(\n initCall\n );\n if (!success || uint256(bytes32(result)) != 1) {\n revert Barz__InitializationFailure();\n }\n }\n\n /**\n * @notice Fallback function for Barz complying with Diamond Standard with customization of adding Default Fallback Handler\n * @dev Find facet for function that is called and execute the function if a facet is found and return any value.\n */\n fallback() external payable {\n LibDiamond.DiamondStorage storage ds;\n bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION;\n // get diamond storage\n assembly {\n ds.slot := position\n }\n // get facet from function selector\n address facet = address(bytes20(ds.facets[msg.sig]));\n if (facet == address(0))\n facet = ds.defaultFallbackHandler.facetAddress(msg.sig);\n require(facet != address(0), \"Barz: Function does not exist\");\n // Execute external function from facet using delegatecall and return any value.\n assembly {\n // copy function selector and any arguments\n calldatacopy(0, 0, calldatasize())\n // execute function call using the facet\n let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)\n // get any return value\n returndatacopy(0, 0, returndatasize())\n // return any return value or error back to the caller\n switch result\n case 0 {\n revert(0, returndatasize())\n }\n default {\n return(0, returndatasize())\n }\n }\n }\n\n /**\n * @notice Receive function to receive native token without data\n */\n receive() external payable {}\n}\n" + }, + "contracts/BarzFactory.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Barz} from \"./Barz.sol\";\nimport {IBarzFactory} from \"./interfaces/IBarzFactory.sol\";\n\n/**\n * @title Barz Factory\n * @dev Contract to easily deploy Barz to a pre-computed address with a single call\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract BarzFactory is IBarzFactory {\n address public immutable accountFacet;\n address public immutable entryPoint;\n address public immutable facetRegistry;\n address public immutable defaultFallback;\n\n /**\n * @notice Sets the initialization data for Barz contract initialization\n * @param _accountFacet Account Facet to be used to create Barz\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\n * @param _facetRegistry Facet Registry to be used to create Barz\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\n */\n constructor(\n address _accountFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallback\n ) {\n accountFacet = _accountFacet;\n entryPoint = _entryPoint;\n facetRegistry = _facetRegistry;\n defaultFallback = _defaultFallback;\n }\n\n /**\n * @notice Creates the Barz with a single call. It creates the Barz contract with the givent verification facet\n * @param _verificationFacet Address of verification facet used for creating the barz account\n * @param _owner Public Key of the owner to initialize barz account\n * @param _salt Salt used for deploying barz with create2\n * @return barz Instance of Barz contract deployed with the given parameters\n */\n function createAccount(\n address _verificationFacet,\n bytes calldata _owner,\n uint256 _salt\n ) external override returns (Barz barz) {\n address addr = getAddress(_verificationFacet, _owner, _salt);\n uint codeSize = addr.code.length;\n if (codeSize > 0) {\n return Barz(payable(addr));\n }\n barz = new Barz{salt: bytes32(_salt)}(\n accountFacet,\n _verificationFacet,\n entryPoint,\n facetRegistry,\n defaultFallback,\n _owner\n );\n emit BarzDeployed(address(barz));\n }\n\n /**\n * @notice Calculates the address of Barz with the given parameters\n * @param _verificationFacet Address of verification facet used for creating the barz account\n * @param _owner Public Key of the owner to initialize barz account\n * @param _salt Salt used for deploying barz with create2\n * @return barzAddress Precalculated Barz address\n */\n function getAddress(\n address _verificationFacet,\n bytes calldata _owner,\n uint256 _salt\n ) public view override returns (address barzAddress) {\n bytes memory bytecode = getBytecode(\n accountFacet,\n _verificationFacet,\n entryPoint,\n facetRegistry,\n defaultFallback,\n _owner\n );\n bytes32 hash = keccak256(\n abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(bytecode)\n )\n );\n barzAddress = address(uint160(uint256(hash)));\n }\n\n /**\n * @notice Returns the bytecode of Barz with the given parameter\n * @param _accountFacet Account Facet to be used to create Barz\n * @param _verificationFacet Verification Facet to be used to create Barz\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\n * @param _facetRegistry Facet Registry to be used to create Barz\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\n * @param _ownerPublicKey Public Key of owner to be used to initialize Barz ownership\n * @return barzBytecode Bytecode of Barz\n */\n function getBytecode(\n address _accountFacet,\n address _verificationFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallback,\n bytes calldata _ownerPublicKey\n ) public pure override returns (bytes memory barzBytecode) {\n bytes memory bytecode = type(Barz).creationCode;\n barzBytecode = abi.encodePacked(\n bytecode,\n abi.encode(\n _accountFacet,\n _verificationFacet,\n _entryPoint,\n _facetRegistry,\n _defaultFallback,\n _ownerPublicKey\n )\n );\n }\n\n /**\n * @notice Returns the creation code of the Barz contract\n * @return creationCode Creation code of Barz\n */\n function getCreationCode()\n public\n pure\n override\n returns (bytes memory creationCode)\n {\n creationCode = type(Barz).creationCode;\n }\n}\n" + }, + "contracts/facets/AccountFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {UserOperation} from \"../aa-4337/interfaces/UserOperation.sol\";\nimport {IEntryPoint} from \"../aa-4337/interfaces/IEntryPoint.sol\";\nimport {BaseAccount} from \"../aa-4337/core/BaseAccount.sol\";\nimport {LibAppStorage, BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {IFacetRegistry} from \"../infrastructure/interfaces/IFacetRegistry.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {IERC1271} from \"../interfaces/ERC/IERC1271.sol\";\nimport {IAccountFacet} from \"./interfaces/IAccountFacet.sol\";\n\n/**\n * @title Account Facet\n * @dev Account module contract that provides the account features and initialization of signer\n * compatible with EIP-1271 & EIP-4337\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract AccountFacet is IAccountFacet, BarzStorage, BaseAccount {\n using ECDSA for bytes32;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceAccountInitialize();\n }\n\n /**\n * @notice Returns the address of EntryPoint contract registered to Barz account\n */\n function entryPoint() public view override returns (IEntryPoint) {\n return s.entryPoint;\n }\n\n /**\n * @notice Initializes the initial storage of the Barz contract.\n * @dev This method can only be called during the initialization or signature migration.\n * If the proxy contract was created without initialization, anyone can call initialize.\n * Barz calls initialize in constructor in an atomic transaction during deployment\n * @param _verificationFacet Facet contract handling the verificationi\n * @param _anEntryPoint Entrypoint contract defined in EIP-4337 handling the flow of UserOp\n * @param _facetRegistry Registry of Facets that hold all facet information\n * @param _defaultFallBackHandler Middleware contract for default facets\n * @param _ownerPublicKey Bytes of owner public key\n */\n function initialize(\n address _verificationFacet,\n address _anEntryPoint,\n address _facetRegistry,\n address _defaultFallBackHandler,\n bytes calldata _ownerPublicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceAccountInitialize();\n s.entryPoint = IEntryPoint(_anEntryPoint);\n s.facetRegistry = IFacetRegistry(_facetRegistry);\n LibDiamond.diamondStorage().defaultFallbackHandler = IDiamondLoupe(\n _defaultFallBackHandler\n );\n\n _cutDiamondAccountFacet(_verificationFacet);\n\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n _ownerPublicKey\n );\n // Every Verification Facet should comply with initializeSigner(bytes)\n // to be compatible with the Barz contract(for initialization)\n (bool success, bytes memory result) = _verificationFacet.delegatecall(\n initCall\n );\n if (!success || uint256(bytes32(result)) != 1) {\n revert AccountFacet__InitializationFailure();\n }\n\n initSuccess = 1;\n emit AccountInitialized(s.entryPoint, _ownerPublicKey);\n }\n\n function _cutDiamondAccountFacet(address _verificationFacet) internal {\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](1);\n\n bytes4 ownerVerificationFuncSelector = IVerificationFacet(\n _verificationFacet\n ).validateOwnerSignatureSelector();\n\n bytes4[] memory verificationFunctionSelectors = new bytes4[](3);\n verificationFunctionSelectors[0] = IERC1271.isValidSignature.selector;\n verificationFunctionSelectors[1] = ownerVerificationFuncSelector;\n verificationFunctionSelectors[2] = IVerificationFacet.owner.selector;\n cut[0] = IDiamondCut.FacetCut({\n facetAddress: _verificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: verificationFunctionSelectors\n });\n\n LibDiamond.diamondCut(cut, address(0), \"\");\n }\n\n /**\n * @notice Calls the destination with inputted calldata and value from EntryPoint\n * @dev This method executes the calldata coming from the EntryPoint.\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\n * @param _dest Address of destination where the call will be forwarded to\n * @param _value Amount of native coin the owner is willing to send(e.g. ETH, BNB)\n * @param _func Bytes of calldata to execute in the destination address\n */\n function execute(\n address _dest,\n uint256 _value,\n bytes calldata _func\n ) external override onlyWhenUnlocked {\n _requireFromEntryPoint();\n address restrictionsFacet = LibDiamond.restrictionsFacet();\n if (restrictionsFacet == address(0)) _call(_dest, _value, _func);\n else _callWithRestrictions(_dest, _value, _func, restrictionsFacet);\n }\n\n /**\n * @notice Batch calls the destination with inputted calldata and value from EntryPoint\n * @dev This method batch executes the calldata coming from the EntryPoint.\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\n * @param _dest Array of addresses of destination where the call will be forwarded to\n * @param _value Array of amount of native coin the owner is willing to send(e.g. ETH, BNB)\n * @param _func Array of bytes of calldata to execute in the destination address\n */\n function executeBatch(\n address[] calldata _dest,\n uint256[] calldata _value,\n bytes[] calldata _func\n ) external override onlyWhenUnlocked {\n _requireFromEntryPoint();\n if (_dest.length != _func.length || _dest.length != _value.length)\n revert AccountFacet__InvalidArrayLength();\n address restrictionsFacet = LibDiamond.restrictionsFacet();\n if (restrictionsFacet == address(0)) {\n for (uint256 i; i < _dest.length; ) {\n _call(_dest[i], _value[i], _func[i]);\n unchecked {\n ++i;\n }\n }\n } else {\n for (uint256 i; i < _dest.length; ) {\n _callWithRestrictions(\n _dest[i],\n _value[i],\n _func[i],\n restrictionsFacet\n );\n unchecked {\n ++i;\n }\n }\n }\n }\n\n /**\n * @notice Validates the signature field of UserOperation\n * @dev This method validates if the signature of UserOp is indeed valid by delegating the call to Verification Facet\n * Barz makes a call to the pre-registered Verification Facet address in App Storage\n * @param _userOp UserOperation from owner to be validated\n * @param _userOpHash Hash of UserOperation given from the EntryPoint contract\n */\n function _validateSignature(\n UserOperation calldata _userOp,\n bytes32 _userOpHash\n ) internal override returns (uint256 validationData) {\n // Get Facet with Function Selector\n address facet = LibLoupe.facetAddress(s.validateOwnerSignatureSelector);\n if (facet == address(0))\n revert AccountFacet__NonExistentVerificationFacet();\n\n // Make function call to VerificationFacet\n bytes memory validateCall = abi.encodeWithSelector(\n s.validateOwnerSignatureSelector,\n _userOp,\n _userOpHash\n );\n (bool success, bytes memory result) = facet.delegatecall(validateCall);\n if (!success) revert AccountFacet__CallNotSuccessful();\n validationData = uint256(bytes32(result));\n if (validationData == 0) emit VerificationSuccess(_userOpHash);\n else emit VerificationFailure(_userOpHash);\n }\n\n /**\n * @notice Calls the target with the inputted value and calldata\n * @dev This method is the actual function in Barz that makes a call with an arbitrary owner-given data\n * @param _target Address of the destination contract which the call is getting forwarded to\n * @param _value Amount of Native coin the owner is wanting to make in this call\n * @param _data Calldata the owner is forwarding together in the call e.g. Swap/Token Transfer\n */\n function _call(\n address _target,\n uint256 _value,\n bytes memory _data\n ) internal {\n (bool success, bytes memory result) = _target.call{value: _value}(\n _data\n );\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n }\n\n /**\n * @notice Calls the target with the inputted value and calldata together with restrictions check\n * @dev This method is the actual function in Barz that makes a call with an arbitrary owner-given data\n * @param _target Address of the destination contract which the call is getting forwarded to\n * @param _value Amount of Native coin the owner is wanting to make in this call\n * @param _data Calldata the owner is forwarding together in the call e.g. Swap/Token Transfer\n * @param _restrictionsFacet Address of Facet to validate restrictions\n */\n function _callWithRestrictions(\n address _target,\n uint256 _value,\n bytes memory _data,\n address _restrictionsFacet\n ) internal {\n // NOTE: No restrictions facet, so restriction validation passes\n if (_checkRestrictions(_restrictionsFacet, _target, _value, _data) != 0)\n revert AccountFacet__RestrictionsFailure();\n\n (bool success, bytes memory result) = _target.call{value: _value}(\n _data\n );\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n }\n\n /**\n * @notice Checks restrictions if the restrictions facet exists\n * @dev This method checks if the restrictions facet exists and makes a verification call to an array of restrictions facet\n * @param _facet Address that holds the restrictions logic\n * @param _target Address the call is getting forwarded to\n * @param _value Amount of native coin the call is sending together with the call\n * @param _data Calldata to trigger execution in target address\n */\n function _checkRestrictions(\n address _facet,\n address _target,\n uint256 _value,\n bytes memory _data\n ) internal returns (uint256 result) {\n bytes memory call = abi.encodeWithSignature(\n \"verifyRestrictions(address,address,uint256,bytes)\",\n address(this),\n _target,\n _value,\n _data\n );\n (bool success, bytes memory response) = _facet.delegatecall(call);\n if (!success) revert AccountFacet__RestrictionsFailure();\n result = uint256(bytes32(response));\n }\n}\n" + }, + "contracts/facets/AccountRecoveryFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibFacetStorage, RecoveryStorage, RecoveryConfig, RecoveryApprovalConfig, ApprovalConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {IAccountRecoveryFacet} from \"./interfaces/IAccountRecoveryFacet.sol\";\n\n/**\n * @title Account Recovery Facet\n * @dev Contract that enables recovery of accounts when owner key is unavailable\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract AccountRecoveryFacet is IAccountRecoveryFacet, Modifiers {\n bytes constant UNINIT_CALL =\n abi.encodeWithSignature(\"uninitializeSigner()\");\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Approve recovery of account as guardian\n * @dev This method can only be called by guardian and guardian inputs the public key of the new owner\n * When the threshold(majority of guardians) passes, it automatically executes account recovery\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function approveAccountRecovery(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + _getApprovalValidationPeriod()\n );\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit RecoveryApproved(\n _recoveryPublicKey,\n msg.sender,\n approvalValidUntil\n );\n if (\n getRecoveryApprovalCountWithTimeValidity(recoveryPublicKeyHash) >=\n LibGuardian.majorityOfGuardians()\n ) _executeRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Revoke recovery of account as guardian\n * @dev This method can only be called by guardian and guardian inputs the public key of the new owner\n When the threshold(majority of guardians) passes, it automatically revokes account recovery when recovery is pending\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function revokeAccountRecoveryApproval(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n if (\n !rs\n .isNewOwnerApproved[recoveryPublicKeyHash][msg.sender].isApproved ||\n !(block.timestamp <\n rs\n .isNewOwnerApproved[recoveryPublicKeyHash][msg.sender]\n .validUntil)\n ) revert AccountRecoveryFacet__NonExistentApproval();\n\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(false, 0);\n emit RecoveryApprovalRevoked(_recoveryPublicKey, msg.sender);\n }\n\n /**\n * @notice Executes recovery with signatures or on-chain pre-approvals\n * @dev This method validates the signatures of guardians or checks the on-chain pre-approved calls to check if the threshold passes\n * When the threshold passes, account recovery is executed and revert otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _guardians Array of guardians address that are approving the recovery of Account\n * @param _signatures Array of signature bytes that signed the approval hash\n */\n function executeRecovery(\n bytes calldata _recoveryPublicKey,\n address[] calldata _guardians,\n bytes[] calldata _signatures\n ) external override {\n if (_isRecoveryPending())\n revert AccountRecoveryFacet__RecoveryAlreadyOngoing();\n if (_guardians.length != _signatures.length)\n revert AccountRecoveryFacet__InvalidArrayLength();\n validateNewOwner(_recoveryPublicKey);\n\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n\n _checkApprover(_guardians);\n _checkDuplicateOnChainApprover(recoveryPublicKeyHash, _guardians);\n\n if (\n _guardians.length +\n getRecoveryApprovalCountWithTimeValidity(\n recoveryPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians()\n ) revert AccountRecoveryFacet__InsufficientGuardians();\n for (uint256 i; i < _guardians.length; ) {\n if (!LibGuardian.isGuardian(_guardians[i]))\n revert AccountRecoveryFacet__InvalidGuardian();\n if (\n !SignatureChecker.isValidSignatureNow(\n _guardians[i],\n recoveryPublicKeyHash,\n _signatures[i]\n )\n ) revert AccountRecoveryFacet__InvalidGuardianSignature();\n unchecked {\n ++i;\n }\n }\n _executeRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Executes recovery of the account. Note that execution and finalization is a different process\n * @dev Executes the recovery and adds recovery data to recovery configuration. Locks the account\n * @param _recoveryPublicKey Public Key of the account for recovery\n */\n function _executeRecovery(bytes memory _recoveryPublicKey) internal {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n unchecked {\n ++rs.nonce;\n }\n uint64 executeAfter = uint64(block.timestamp + _getRecoveryPeriod());\n rs.recoveryConfigs[INNER_STRUCT] = RecoveryConfig(\n _recoveryPublicKey,\n executeAfter // NOTE: Remove guardian Count\n );\n LibAppStorage.setLock(\n block.timestamp + _getLockPeriod(),\n AccountRecoveryFacet.executeRecovery.selector\n );\n emit RecoveryExecuted(_recoveryPublicKey, executeAfter);\n }\n\n /**\n * @notice Finalize recovery after recovery pending period. Recovery pending period can be set by user beforehand in SecurityManager\n * @dev This method finalizes recovery and fully changes the ownership of the account to the newly inputted recovery public key\n */\n function finalizeRecovery() external override {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n if (\n uint64(block.timestamp) <=\n rs.recoveryConfigs[INNER_STRUCT].executeAfter\n ) revert AccountRecoveryFacet__RecoveryPeriodNotOver();\n bytes memory recoveryOwner = rs\n .recoveryConfigs[INNER_STRUCT]\n .recoveryPublicKey;\n\n delete rs.recoveryConfigs[INNER_STRUCT];\n\n LibAppStorage.setLock(0, bytes4(0));\n\n LibAppStorage.initiateSignerMigration();\n address verificationFacet = address(\n bytes20(\n LibDiamond.diamondStorage().facets[\n s.validateOwnerSignatureSelector\n ]\n )\n );\n (bool uninitSuccess, bytes memory uninitResult) = verificationFacet\n .delegatecall(UNINIT_CALL);\n if (!uninitSuccess) revert AccountRecoveryFacet__CallNotSuccesful();\n if (uint256(bytes32(uninitResult)) != 1)\n revert AccountRecoveryFacet__SignerUninitializationFailure();\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n recoveryOwner\n );\n (bool initSuccess, bytes memory initResult) = verificationFacet\n .delegatecall(initCall);\n if (!initSuccess) revert AccountRecoveryFacet__CallNotSuccesful();\n if (uint256(bytes32(initResult)) != 1)\n revert AccountRecoveryFacet__SignerInitializationFailure();\n LibAppStorage.finalizeSignerMigration();\n emit RecoveryFinalized(recoveryOwner);\n }\n\n /**\n * @notice Approves the cancellation of recovery\n * @dev This method approves the cancellation of recovery when recovery is still pending - waiting for finalization\n * @param _recoveryPublicKey Bytes of public key which is pending for recovery\n */\n function approveCancelRecovery(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"CancelRecovery\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + _getApprovalValidationPeriod()\n );\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit RecoveryCancellationApproved(_recoveryPublicKey, msg.sender);\n if (\n getRecoveryApprovalCountWithTimeValidity(recoveryPublicKeyHash) >=\n LibGuardian.majorityOfGuardians()\n ) {\n _cancelRecovery(_recoveryPublicKey);\n }\n }\n\n /**\n * @notice Hardstops an ongoing recovery\n * @dev This method provides a safety mechanism to protect owners of malicious guardians.\n * Owners can hardstop recovery when an malicious guardians starts the recovery process.\n * @param _signature Signature of the owner that signs the hash to hardstop recovery\n */\n function hardstopRecovery(bytes calldata _signature) external override {\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n \"0\",\n \"HardstopRecovery\"\n );\n if (\n !SignatureChecker.isValidSignatureNow(\n address(this),\n recoveryPublicKeyHash,\n _signature\n )\n ) revert AccountRecoveryFacet__InvalidOwnerSignature();\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n unchecked {\n ++rs.nonce;\n }\n delete rs.recoveryConfigs[INNER_STRUCT];\n LibAppStorage.setLock(0, bytes4(0));\n emit RecoveryHardstopped();\n }\n\n /**\n * @notice Cancels recovery with signatures or on-chain pre-approvals\n * @dev This method validates the signatures of guardians or checks the on-chain pre-approved calls to check if the threshold passes\n * When the threshold passes, account recovery is canceled and revert otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _guardians Array of guardians address that are approving the recovery of Account\n * @param _signatures Array of signature bytes that signed the cancellation approval hash\n */\n function cancelRecovery(\n bytes calldata _recoveryPublicKey,\n address[] calldata _guardians,\n bytes[] calldata _signatures\n ) external override {\n if (_guardians.length != _signatures.length)\n revert AccountRecoveryFacet__InvalidArrayLength();\n validateNewOwner(_recoveryPublicKey);\n\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"CancelRecovery\"\n );\n\n _checkApprover(_guardians);\n _checkDuplicateOnChainApprover(recoveryPublicKeyHash, _guardians);\n\n if (\n _guardians.length +\n getRecoveryApprovalCountWithTimeValidity(\n recoveryPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians()\n ) revert AccountRecoveryFacet__InsufficientGuardians();\n for (uint256 i; i < _guardians.length; ) {\n if (!LibGuardian.isGuardian(_guardians[i]))\n revert AccountRecoveryFacet__CallerNotGuardian();\n if (\n !SignatureChecker.isValidSignatureNow(\n _guardians[i],\n recoveryPublicKeyHash,\n _signatures[i]\n )\n ) revert AccountRecoveryFacet__InvalidGuardianSignature();\n unchecked {\n ++i;\n }\n }\n _cancelRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Cancel recovery when the recovery is pending. Unlock the account as well\n * @dev This method checks if the recovery is pending and reverts if not pending.\n * It increases the recovery nonce and deletes the recovery information and gets a small portion of gas in return\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function _cancelRecovery(bytes memory _recoveryPublicKey) internal {\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n LibAppStorage.setLock(0, bytes4(0));\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n unchecked {\n ++rs.nonce;\n }\n delete rs.recoveryConfigs[INNER_STRUCT];\n emit RecoveryCanceled(_recoveryPublicKey);\n }\n\n /**\n * @notice Validates the format of public key to be used for recovery\n * @dev This method checks if the public key format is correct and reverts otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function validateNewOwner(\n bytes calldata _recoveryPublicKey\n ) public view override {\n if (\n !IVerificationFacet(\n LibLoupe.facetAddress(s.validateOwnerSignatureSelector)\n ).isValidKeyType(_recoveryPublicKey)\n ) revert AccountRecoveryFacet__InvalidRecoveryPublicKey();\n }\n\n /**\n * @notice Checks if recovery is currently pending\n * @return isPending Boolean indicating if recovery is pending\n */\n function _isRecoveryPending() internal view returns (bool isPending) {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n isPending = (rs.recoveryConfigs[INNER_STRUCT].executeAfter > 0);\n }\n\n /**\n * @notice Calculate the recovery hash dependent on chain, wallet address, nonce with EIP-191 prefix for safety\n * @dev Returns the keccak256 hash of EIP-191 msg hash packed with public key, salt, nonce, wallet address, etc\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _saltString Salt string to uniquely identify each recovery hash and for security\n * @return recoveryKeyHash Bytes32 string of the recovery hash\n */\n function getApprovalRecoveryKeyHash(\n bytes memory _recoveryPublicKey,\n string memory _saltString\n ) public view override returns (bytes32 recoveryKeyHash) {\n recoveryKeyHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n _recoveryPublicKey,\n _saltString,\n address(this),\n block.chainid,\n LibFacetStorage.recoveryStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Check the onchain approval of guardians and returns the number of guardians that approved\n * @dev Loop through the guardian addresses and returns the number of guardians that approved this recovery hash\n * @param _recoveryPublicKeyHash Bytes hash of newly recovered public key and recovery value of the account\n * @return approvalCount Number of guardians that approved\n */\n function getRecoveryApprovalCountWithTimeValidity(\n bytes32 _recoveryPublicKeyHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n for (uint256 i; i < guardianLength; ) {\n if (isRecoveryApproved(_recoveryPublicKeyHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Checks if the recovery is approved by the given approver\n * @param _recoveryPublicKeyHash Hash of the public key and configuration for recovery\n * @param _approver Address of approver\n * @return isApproved Bool value if recovery hash is approved\n */\n function isRecoveryApproved(\n bytes32 _recoveryPublicKeyHash,\n address _approver\n ) public view override returns (bool isApproved) {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n if (\n rs\n .isNewOwnerApproved[_recoveryPublicKeyHash][_approver].isApproved &&\n block.timestamp <\n rs.isNewOwnerApproved[_recoveryPublicKeyHash][_approver].validUntil\n ) {\n isApproved = true;\n }\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _recoveryPublicKeyHash Hash of recovery information\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _recoveryPublicKeyHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isRecoveryApproved(_recoveryPublicKeyHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert AccountRecoveryFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the lock period of this wallet address from security manager\n * @return lockPeriod value of lock period\n */\n function _getLockPeriod() internal view returns (uint256 lockPeriod) {\n lockPeriod = securityManager.lockPeriodOf(address(this));\n if (lockPeriod == 0) revert AccountRecoveryFacet__InvalidLockPeriod();\n }\n\n /**\n * @notice Returns the lock period of this wallet address from security manager\n * @return recoveryPeriod value of recovery period\n */\n function _getRecoveryPeriod()\n internal\n view\n returns (uint256 recoveryPeriod)\n {\n recoveryPeriod = securityManager.recoveryPeriodOf(address(this));\n if (recoveryPeriod == 0)\n revert AccountRecoveryFacet__InvalidRecoveryPeriod();\n }\n\n /**\n * @notice Returns the approval validation period of this wallet address from security manager\n * @return approvalValidationPeriod value of approval validation period\n */\n function _getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod == 0)\n revert AccountRecoveryFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the recovery nonce of this wallet address from security manager\n * @return nonce value of recovery nonce\n */\n function getRecoveryNonce() public view override returns (uint128 nonce) {\n nonce = LibFacetStorage.recoveryStorage().nonce;\n }\n\n /**\n * @notice Returns the recovery information of the pending recovery\n * @return recoveryConfig value struct of pending recovery\n */\n function getPendingRecovery()\n public\n view\n override\n returns (RecoveryConfig memory recoveryConfig)\n {\n recoveryConfig = LibFacetStorage.recoveryStorage().recoveryConfigs[\n INNER_STRUCT\n ];\n }\n}\n" + }, + "contracts/facets/base/DiamondCutFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibGuardian} from \"../../libraries/LibGuardian.sol\";\nimport {ISecurityManager} from \"../../infrastructure/interfaces/ISecurityManager.sol\";\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibFacetStorage, DiamondCutApprovalConfig, ApprovalConfig} from \"../../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"../Modifiers.sol\";\nimport {IDiamondCut} from \"./interfaces/IDiamondCut.sol\";\n\n/**\n * @title DiamondCut Facet\n * @dev Responsible for adding/removing/replace facets in Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DiamondCutFacet is Modifiers, IDiamondCut {\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Updates the flag for the interfaceId\n * @param _interfaceId InterfaceID to update the mapping\n * @param _flag Bool value to update the mapping of the given interface ID\n */\n function updateSupportsInterface(\n bytes4 _interfaceId,\n bool _flag\n ) external override onlyWhenUnlocked {\n LibDiamond.enforceIsSelf();\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId] = _flag;\n emit SupportsInterfaceUpdated(_interfaceId, _flag);\n }\n\n /**\n * @notice Add/replace/remove any number of functions and optionally execute\n * a function with delegatecall when guardians don't exist\n * @param _diamondCut Contains the facet addresses and function selectors\n * @param _init The address of the contract or facet to execute _calldata. It's prohibited in Barz\n */\n function diamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata\n ) external override onlyWhenUnlocked {\n LibDiamond.enforceIsSelf();\n\n _checkFacetCutValidity(_diamondCut);\n // require approval from guardian if guardian exists\n if (0 != LibGuardian.guardianCount())\n revert DiamondCutFacet__InvalidRouteWithGuardian();\n if (address(0) != _init) revert DiamondCutFacet__InvalidInitAddress();\n\n unchecked {\n ++LibFacetStorage.diamondCutStorage().nonce;\n }\n LibDiamond.diamondCut(_diamondCut, address(0), \"\");\n }\n\n /**\n * @notice Add/replace/remove any number of functions and optionally execute\n * a function with delegatecall when guardians exist\n * @param _diamondCut Contains the facet addresses and function selectors\n * @param _approvers Guardian or owner address that approves the diamond cut\n * @param _signatures Signature of Guardians or owner that approves the diamond cut\n */\n function diamondCutWithGuardian(\n FacetCut[] calldata _diamondCut,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n ) external override onlyWhenUnlocked {\n if (_approvers.length != _signatures.length)\n revert DiamondCutFacet__InvalidArrayLength();\n _checkFacetCutValidity(_diamondCut);\n if (0 == LibGuardian.guardianCount())\n revert DiamondCutFacet__InvalidRouteWithGuardian();\n\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(cutHash, _approvers);\n\n bool onChainOwnerApproval = getOwnerCutApprovalWithTimeValidity(\n cutHash\n );\n\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n if (\n _approvers.length +\n getDiamondCutApprovalCountWithTimeValidity(cutHash) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert DiamondCutFacet__InsufficientApprovers();\n\n bool ownerApproved;\n for (uint256 i; i < _approvers.length; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n _approvers[i] != address(this)\n ) revert DiamondCutFacet__InvalidApprover();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert DiamondCutFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n cutHash,\n _signatures[i]\n )\n ) revert DiamondCutFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n if (!ownerApproved && !onChainOwnerApproval)\n revert DiamondCutFacet__LackOfOwnerApproval();\n\n unchecked {\n ++LibFacetStorage.diamondCutStorage().nonce;\n }\n LibDiamond.diamondCut(_diamondCut, address(0), \"\");\n }\n\n /**\n * @notice Approves diamond cut. This can only be called directly from guardian or owner\n * @param _diamondCut Contains the facet addresses and function selectors\n */\n function approveDiamondCut(\n FacetCut[] calldata _diamondCut\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\n if (LibGuardian.guardianCount() == 0)\n revert DiamondCutFacet__InvalidRouteWithoutGuardian();\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n _checkFacetCutValidity(_diamondCut);\n\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(\n true,\n approvalValidUntil\n );\n emit DiamondCutApproved(_diamondCut);\n if (\n (getDiamondCutApprovalCountWithTimeValidity(cutHash) >=\n LibGuardian.majorityOfGuardians()) &&\n getOwnerCutApprovalWithTimeValidity(cutHash)\n ) {\n unchecked {\n ++LibFacetStorage.diamondCutStorage().nonce;\n }\n LibDiamond.diamondCut(_diamondCut, address(0), \"\");\n }\n }\n\n /**\n * @notice Revokes the approval of diamond cut. This can only be called directly from guardian or owner\n * @param _diamondCut Contains the facet addresses and function selectors\n */\n function revokeDiamondCutApproval(\n FacetCut[] calldata _diamondCut\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\n if (!ds.isDiamondCutApproved[cutHash][msg.sender].isApproved)\n revert DiamondCutFacet__CannotRevokeUnapproved();\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(false, 0);\n emit DiamondCutApprovalRevoked(_diamondCut);\n }\n\n /**\n * @notice Gets the number of approvals of diamond cut from guardians\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n */\n function getDiamondCutApprovalCountWithTimeValidity(\n bytes32 _diamondCutHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardiansLength = guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n if (isCutApproved(_diamondCutHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n return approvalCount;\n }\n\n /**\n * @notice Returns if the owner has approved the diamond cut\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @return isApprovedByOwner Bool value showing if the owner approved the cut\n */\n function getOwnerCutApprovalWithTimeValidity(\n bytes32 _diamondCutHash\n ) public view override returns (bool isApprovedByOwner) {\n isApprovedByOwner = isCutApproved(_diamondCutHash, address(this));\n }\n\n /**\n * @notice Returns if the given approver has approved the diamond cut\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @param _approver Address of approver\n * @return isApproved Bool value showing if the approver approved the cut\n */\n function isCutApproved(\n bytes32 _diamondCutHash,\n address _approver\n ) public view override returns (bool isApproved) {\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n isApproved = (ds\n .isDiamondCutApproved[_diamondCutHash][_approver].isApproved &&\n block.timestamp <\n ds.isDiamondCutApproved[_diamondCutHash][_approver].validUntil);\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _diamondCutHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isCutApproved(_diamondCutHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert DiamondCutFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the diamond cut hash. This function ensures that this hash is safe from replay attack by including\n * salt, address, chainId, and nonce, etc.\n * @param _diamondCut Contains the facet addresses and function selectors\n * @return cutHash Diamond Cut Hash\n */\n function getDiamondCutHash(\n FacetCut[] calldata _diamondCut\n ) public view override returns (bytes32 cutHash) {\n cutHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n keccak256(abi.encode(_diamondCut)),\n address(this),\n block.chainid,\n LibFacetStorage.diamondCutStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Returns the approval validation Period\n * @dev This method fetches the validation period from the security manager\n * @return approvalValidationPeriod Approval validation period of Barz contract fetched from security manager\n */\n function getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod <= 0)\n revert DiamondCutFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the diamond cut nonce of this wallet\n * @dev This method fetches the nonce from diamond cut storage\n * @return cutNonce Nonce of diamond cut to protect from reply attacks\n */\n function getDiamondCutNonce()\n public\n view\n override\n returns (uint128 cutNonce)\n {\n cutNonce = LibFacetStorage.diamondCutStorage().nonce;\n }\n}\n" + }, + "contracts/facets/base/DiamondLoupeFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {IERC165} from \"../../interfaces/ERC/IERC165.sol\";\nimport {IERC1271} from \"../../interfaces/ERC/IERC1271.sol\";\nimport {IERC677Receiver} from \"../../interfaces/ERC/IERC677Receiver.sol\";\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC1155Receiver} from \"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\";\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../../libraries/LibLoupe.sol\";\nimport {LibUtils} from \"../../libraries/LibUtils.sol\";\nimport {IDiamondCut} from \"../../facets/base/interfaces/IDiamondCut.sol\";\nimport {IStorageLoupe} from \"./interfaces/IStorageLoupe.sol\";\nimport {IDiamondLoupe} from \"./interfaces/IDiamondLoupe.sol\";\n\n/**\n * @title DiamondLoupe Facet\n * @dev DiamondLoupe contract compatible with EIP-2535\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DiamondLoupeFacet is IDiamondLoupe, IStorageLoupe, IERC165 {\n // Diamond Loupe Functions\n ////////////////////////////////////////////////////////////////////\n /// These functions are expected to be called frequently by tools off-chain.\n\n /**\n * @notice Gets all facets and their selectors.\n * @dev Barz uses a special architecture called default fallback handler. Default Fallback handler is used as a middleware\n * that holds the mapping of facet function selector and facet address that Barz uses. This helps Barz to reduce\n * significant amount of gas during the initialization process.\n * Hence, this method aggregates both the facet information from DefaulFallbackHandler and in diamond storage and shows the data to users.\n * @return facets_ Facet\n */\n function facets() public view override returns (Facet[] memory facets_) {\n Facet[] memory defaultFacet = LibDiamond\n .diamondStorage()\n .defaultFallbackHandler\n .facets();\n Facet[] memory _facets = LibLoupe.facets();\n uint256 numFacets = _facets.length;\n bytes4[] memory keys;\n address[] memory values;\n for (uint256 i; i < numFacets; ) {\n uint256 selectorsLength = _facets[i].functionSelectors.length;\n for (uint256 j; j < selectorsLength; ) {\n (keys, values) = LibUtils.setValue(\n keys,\n values,\n _facets[i].functionSelectors[j],\n _facets[i].facetAddress\n );\n unchecked {\n ++j;\n }\n }\n unchecked {\n ++i;\n }\n }\n {\n bool iIncrement;\n for (uint256 i; i < defaultFacet.length; ) {\n bool jIncrement;\n for (\n uint256 j;\n j < defaultFacet[i].functionSelectors.length;\n\n ) {\n if (\n LibUtils.getValue(\n keys,\n values,\n defaultFacet[i].functionSelectors[j]\n ) != address(0)\n ) {\n if (defaultFacet[i].functionSelectors.length == 1) {\n defaultFacet = LibUtils.removeFacetElement(\n defaultFacet,\n i\n );\n iIncrement = true;\n break;\n }\n defaultFacet[i].functionSelectors = LibUtils\n .removeElement(\n defaultFacet[i].functionSelectors,\n j\n );\n jIncrement = true;\n }\n if (!jIncrement) {\n unchecked {\n ++j;\n }\n } else {\n jIncrement = false;\n }\n }\n if (!iIncrement) {\n unchecked {\n ++i;\n }\n } else {\n iIncrement = false;\n }\n }\n }\n {\n uint256 facetLength = numFacets + defaultFacet.length;\n facets_ = new Facet[](facetLength);\n uint256 defaultFacetIndex;\n for (uint256 i; i < facetLength; ) {\n if (i < numFacets) {\n facets_[i] = _facets[i];\n bool jIncrementor;\n for (uint256 j; j < defaultFacet.length; ) {\n if (\n facets_[i].facetAddress ==\n defaultFacet[j].facetAddress\n ) {\n facets_[i].functionSelectors = LibUtils.mergeArrays(\n _facets[i].functionSelectors,\n defaultFacet[j].functionSelectors\n );\n defaultFacet = LibUtils.removeFacetElement(\n defaultFacet,\n j\n );\n jIncrementor = true;\n {\n facets_ = LibUtils.removeFacetElement(\n facets_,\n facets_.length - 1\n );\n }\n --facetLength;\n }\n if (!jIncrementor) {\n unchecked {\n ++j;\n }\n } else {\n jIncrementor = false;\n }\n }\n } else {\n facets_[i] = defaultFacet[defaultFacetIndex];\n ++defaultFacetIndex;\n }\n unchecked {\n ++i;\n }\n }\n }\n }\n\n /**\n * @notice Gets all the function selectors provided by a facet.\n * @param _facet The facet address.\n * @return facetFunctionSelectors_\n */\n function facetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n Facet[] memory facet = facets();\n uint256 facetLength = facet.length;\n for (uint256 i; i < facetLength; ) {\n if (facet[i].facetAddress == _facet)\n return facet[i].functionSelectors;\n unchecked {\n ++i;\n }\n }\n return facetFunctionSelectors_;\n }\n\n /**\n * @notice Get all the facet addresses used by Barz.\n * @return facetAddresses_\n */\n function facetAddresses()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n Facet[] memory facet = facets();\n uint256 facetLength = facet.length;\n facetAddresses_ = new address[](facetLength);\n for (uint256 i; i < facetLength; ) {\n facetAddresses_[i] = facet[i].facetAddress;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Gets the facet that supports the given selector.\n * @dev If facet is not found return address(0).\n * @param _functionSelector The function selector.\n * @return facetAddress_ The facet address.\n */\n function facetAddress(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n\n facetAddress_ = address(bytes20(ds.facets[_functionSelector]));\n if (facetAddress_ == address(0)) {\n facetAddress_ = IDiamondLoupe(ds.defaultFallbackHandler)\n .facetAddress(_functionSelector);\n }\n }\n\n /**\n * @notice SupportInterface to be compatible with EIP 165\n * @param _interfaceId Interface ID for detecting the interface\n * @return isSupported Bool value showing if the standard is supported in the contract\n */\n function supportsInterface(\n bytes4 _interfaceId\n ) external view override returns (bool isSupported) {\n isSupported =\n _interfaceId == type(IERC165).interfaceId ||\n _interfaceId == IDiamondCut.diamondCut.selector ||\n _interfaceId == type(IDiamondLoupe).interfaceId ||\n _interfaceId == type(IERC1155Receiver).interfaceId ||\n _interfaceId == type(IERC721Receiver).interfaceId ||\n _interfaceId == type(IERC777Recipient).interfaceId ||\n _interfaceId == IERC1271.isValidSignature.selector ||\n _interfaceId == type(IERC677Receiver).interfaceId ||\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId];\n }\n\n /**\n * @notice Returns the facet from the diamond storage. This excludes the facets from the default fallback handler\n * @return facets_ Facet information attached directly to diamond storage\n */\n function facetsFromStorage()\n external\n view\n override\n returns (Facet[] memory facets_)\n {\n facets_ = LibLoupe.facets();\n }\n\n /**\n * @notice Returns the facet address attached to the given function selector. This excludes the facets from the default fallback handler\n * @param _functionSelector Function selector to fetch the facet address from diamond storage\n * @return facetAddress_ Facet address mapped with the function selector\n */\n function facetAddressFromStorage(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n facetAddress_ = LibLoupe.facetAddress(_functionSelector);\n }\n\n /**\n * @notice Returns all facet addresses attached directly to diamond storage. This excludes the facets from the default fallback handler\n * @return facetAddresses_ All facet addresses attached directly to diamond storage\n */\n function facetAddressesFromStorage()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n facetAddresses_ = LibLoupe.facetAddresses();\n }\n\n /**\n * @notice Returns function selectors of given facet address attached directly to diamond storage. This excludes the facets from the default fallback handler\n * @param _facet Facet address to fetch the facet function selectors from diamond storage\n * @return facetFunctionSelectors_ Facet function selectors of the given facet address\n */\n function facetFunctionSelectorsFromStorage(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n facetFunctionSelectors_ = LibLoupe.facetFunctionSelectors(_facet);\n }\n}\n" + }, + "contracts/facets/base/interfaces/IDiamondCut.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title DiamondCut Facet Interface\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IDiamondCut {\n error DiamondCutFacet__InvalidRouteWithGuardian();\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\n error DiamondCutFacet__InvalidArrayLength();\n error DiamondCutFacet__InsufficientApprovers();\n error DiamondCutFacet__InvalidApprover();\n error DiamondCutFacet__InvalidApproverSignature();\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\n error DiamondCutFacet__CannotRevokeUnapproved();\n error DiamondCutFacet__LackOfOwnerApproval();\n error DiamondCutFacet__OwnerAlreadyApproved();\n error DiamondCutFacet__DuplicateApproval();\n error DiamondCutFacet__InvalidInitAddress();\n\n event DiamondCutApproved(FacetCut[] diamondCut);\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\n\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\n\n enum FacetCutAction {\n Add,\n Replace,\n Remove\n }\n // Add=0, Replace=1, Remove=2\n\n struct FacetCut {\n address facetAddress;\n FacetCutAction action;\n bytes4[] functionSelectors;\n }\n\n /// @notice Add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param diamondCut Contains the facet addresses and function selectors\n /// @param init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function diamondCut(\n FacetCut[] calldata diamondCut,\n address init,\n bytes calldata _calldata\n ) external;\n\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\n\n function diamondCutWithGuardian(\n FacetCut[] calldata diamondCut,\n address[] calldata approvers,\n bytes[] calldata signatures\n ) external;\n\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\n\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\n\n function getDiamondCutApprovalCountWithTimeValidity(\n bytes32 diamondCutHash\n ) external view returns (uint256);\n\n function getOwnerCutApprovalWithTimeValidity(\n bytes32 diamondCutHash\n ) external view returns (bool);\n\n function isCutApproved(\n bytes32 diamondCutHash,\n address approver\n ) external view returns (bool);\n\n function getDiamondCutHash(\n FacetCut[] calldata diamondCut\n ) external view returns (bytes32);\n\n function getDiamondCutNonce() external view returns (uint128);\n}\n" + }, + "contracts/facets/base/interfaces/IDiamondLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n// A loupe is a small magnifying glass used to look at diamonds.\n// These functions look at diamonds\ninterface IDiamondLoupe {\n /// These functions are expected to be called frequently\n /// by tools.\n\n struct Facet {\n address facetAddress;\n bytes4[] functionSelectors;\n }\n\n /// @notice Gets all facet addresses and their four byte function selectors.\n /// @return facets_ Facet\n function facets() external view returns (Facet[] memory facets_);\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n /// @return facetFunctionSelectors_\n function facetFunctionSelectors(\n address _facet\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses()\n external\n view\n returns (address[] memory facetAddresses_);\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(\n bytes4 _functionSelector\n ) external view returns (address facetAddress_);\n}\n" + }, + "contracts/facets/base/interfaces/IStorageLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"./IDiamondLoupe.sol\";\n\n/**\n * @title LoupeFromStorage Interface\n * @dev Interface contract to function as a loupe facet directly attached to diamond storage of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IStorageLoupe {\n /// These functions are expected to be called frequently\n /// by tools.\n\n /// @notice Gets all facet addresses and their four byte function selectors.\n /// @return facets_ Facet\n function facetsFromStorage()\n external\n view\n returns (IDiamondLoupe.Facet[] memory);\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n function facetFunctionSelectorsFromStorage(\n address _facet\n ) external view returns (bytes4[] memory);\n\n /// @notice Get all the facet addresses used by a diamond.\n function facetAddressesFromStorage()\n external\n view\n returns (address[] memory);\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n function facetAddressFromStorage(\n bytes4 _functionSelector\n ) external view returns (address);\n}\n" + }, + "contracts/facets/GuardianFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibFacetStorage, GuardianStorage, StorageConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IGuardianFacet} from \"./interfaces/IGuardianFacet.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Guardian Facet\n * @dev Contract that enables addition/removal of guardians from Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract GuardianFacet is IGuardianFacet {\n ISecurityManager public immutable securityManager;\n uint8 public constant INNER_STRUCT = 0;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Add guardians to Barz.\n * @dev This method internally calls addGuardian which checks the validity of guardian address and adds\n * as guardian if valid\n * @param _guardians Array of addresses to add as guardian\n */\n function addGuardians(address[] calldata _guardians) external override {\n LibDiamond.enforceIsSelf();\n for (uint256 i; i < _guardians.length; ) {\n addGuardian(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Add a guardian to Barz.\n * @dev This method checks if the function is called by the owner and validates the address of guardian\n * When the validation passes, guardian address is added to the pending state waiting for confirmation\n * @param _guardian Address to add as guardian\n */\n function addGuardian(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (_guardian == address(this))\n revert GuardianFacet__GuardianCannotBeSelf();\n if (isGuardian(_guardian)) revert GuardianFacet__DuplicateGuardian();\n if (_guardian == address(0))\n revert GuardianFacet__ZeroAddressGuardian();\n if (\n keccak256(abi.encodePacked(_guardian)) ==\n keccak256(IVerificationFacet(address(this)).owner())\n ) revert GuardianFacet__OwnerCannotBeGuardian();\n\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n if (\n gs.pending[id] != 0 ||\n block.timestamp <= gs.pending[id] + getSecurityWindow()\n ) revert GuardianFacet__DuplicateGuardianAddition();\n\n uint256 securityPeriod = getAdditionSecurityPeriod();\n gs.pending[id] = block.timestamp + securityPeriod;\n emit GuardianAdditionRequested(\n _guardian,\n block.timestamp + securityPeriod\n );\n }\n\n /**\n * @notice Remove guardians from Barz.\n * @dev This method internally calls removeGuardian which checks the validity of guardian and removes\n * guardian when the request is valid\n * @param _guardians Array of addresses to be removed\n */\n function removeGuardians(address[] calldata _guardians) external override {\n LibDiamond.enforceIsSelf();\n for (uint256 i; i < _guardians.length; ) {\n removeGuardian(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Remove a guardian from Barz.\n * @dev This method validates if the guardian to be removed is a guardian and puts the guardian removal\n * to a pending state waiting to be confirmed.\n * @param _guardian Address of guardian to be removed\n */\n function removeGuardian(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n if (!isGuardian(_guardian)) revert GuardianFacet__NonExistentGuardian();\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n if (\n gs.pending[id] != 0 ||\n block.timestamp <= gs.pending[id] + getSecurityWindow()\n ) revert GuardianFacet__DuplicateGuardianRemoval();\n\n uint256 securityPeriod = getRemovalSecurityPeriod();\n gs.pending[id] = block.timestamp + securityPeriod;\n emit GuardianRemovalRequested(\n _guardian,\n block.timestamp + securityPeriod\n );\n }\n\n /**\n * @notice Confirm addition of guardians\n * @dev This method internally calls confirmGuardianAddition which checks the validity of pending request.\n * Guardians are fully added when they pass the validation. Anyone can call this function.\n * @param _guardians Array of guardian addresses to be added\n */\n function confirmGuardianAdditions(\n address[] calldata _guardians\n ) external override {\n for (uint256 i; i < _guardians.length; ) {\n confirmGuardianAddition(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Confirm addition of a guardian\n * @dev This method checks the validity of pending request.\n * Guardians are fully added when they pass the validation. Anyone can call this function.\n * @param _guardian Guardian address to be added\n */\n function confirmGuardianAddition(address _guardian) public override {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingAddition();\n if (gs.pending[id] >= block.timestamp)\n revert GuardianFacet__PendingAdditionNotOver();\n if (block.timestamp >= gs.pending[id] + getSecurityWindow())\n revert GuardianFacet__PendingAdditionExpired();\n\n _addGuardian(_guardian);\n\n delete gs.pending[id];\n emit GuardianAdded(_guardian);\n }\n\n /**\n * @notice Confirm removal of guardians\n * @dev This method internally calls confirmGuardianRemoval to check the validity guardian removal confirmation.\n * Guardians are fully removed when they pass the validation. Anyone can call this function.\n * @param _guardians Array of guardian addresses to be removed\n */\n function confirmGuardianRemovals(\n address[] calldata _guardians\n ) external override {\n for (uint256 i; i < _guardians.length; ) {\n confirmGuardianRemoval(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Confirm removal of a guardian\n * @dev This method checks the validity guardian removal confirmation.\n * Guardian is fully removed when they pass the validation. Anyone can call this function.\n * @param _guardian Guardian address to be removed\n */\n function confirmGuardianRemoval(address _guardian) public override {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingRemoval();\n if (gs.pending[id] >= block.timestamp)\n revert GuardianFacet__PendingRemovalNotOver();\n if (block.timestamp >= gs.pending[id] + getSecurityWindow())\n revert GuardianFacet__PendingAdditionExpired();\n\n _removeGuardian(_guardian);\n delete gs.pending[id];\n emit GuardianRemoved(_guardian);\n }\n\n /**\n * @notice Cancel pending guardian addition\n * @dev This method checks if the previous request for guardian request exists.\n * It reverts if previous request is not pending and cancels the addition otherwise.\n * @param _guardian Guardian address to be canceled from addition\n */\n function cancelGuardianAddition(address _guardian) external override {\n LibDiamond.enforceIsSelf();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingAddition();\n delete gs.pending[id];\n emit GuardianAdditionCancelled(_guardian);\n }\n\n /**\n * @notice Cancel pending guardian removal\n * @dev This method checks if the previous request for guardian request exists.\n * It reverts if previous request is not pending and cancels the removal otherwise.\n * @param _guardian Guardian address to be canceled from removal\n */\n function cancelGuardianRemoval(address _guardian) external override {\n LibDiamond.enforceIsSelf();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingRemoval();\n delete gs.pending[id];\n emit GuardianRemovalCancelled(_guardian);\n }\n\n /**\n * @notice Get the addition security period of current account from security manager\n * @dev This method returns the uint value if addition security period\n * @return additionSecurityPeriod Uint256 value of addition security period\n */\n function getAdditionSecurityPeriod()\n public\n view\n override\n returns (uint256 additionSecurityPeriod)\n {\n additionSecurityPeriod = securityManager.additionSecurityPeriodOf(\n address(this)\n );\n if (additionSecurityPeriod == 0)\n revert GuardianFacet__InvalidAdditionSecurityPeriod();\n }\n\n /**\n * @notice Get the removal security period of current account from security manager\n * @dev This method returns the uint value if removal security period\n * @return removalSecurityPeriod Uint256 value of removal security period\n */\n function getRemovalSecurityPeriod()\n public\n view\n override\n returns (uint256 removalSecurityPeriod)\n {\n removalSecurityPeriod = securityManager.removalSecurityPeriodOf(\n address(this)\n );\n if (removalSecurityPeriod == 0)\n revert GuardianFacet__InvalidRemovalSecurityPeriod();\n }\n\n /**\n * @notice Get the security window of current account from security manager\n * @dev This method returns the uint value if security window\n * @return securityWindow Uint256 value of removal security period\n */\n function getSecurityWindow()\n public\n view\n override\n returns (uint256 securityWindow)\n {\n securityWindow = securityManager.securityWindowOf(address(this));\n if (securityWindow == 0) revert GuardianFacet__InvalidSecurityWindow();\n }\n\n /**\n * @notice Checks if the addition of the given guardian address is pending\n * @dev This method returns the bool value of whether the guardian address is pending addition\n * @return isPending Bool value of representing the pending of guardian addition\n */\n function isAdditionPending(\n address _guardian\n ) public view override returns (bool isPending) {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n isPending = _isPending(id);\n }\n\n /**\n * @notice Checks if the removal of the given guardian address is pending\n * @dev This method returns the bool value of whether the guardian address is pending removal\n * @return isPending Bool value of representing the pending of guardian removal\n */\n function isRemovalPending(\n address _guardian\n ) public view override returns (bool isPending) {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n isPending = _isPending(id);\n }\n\n /**\n * @notice Checks if the given hash is pending\n * @dev This method returns the bool value whether the hash is pending\n * @return isPending Bool value of representing the pending of guardian operation\n */\n function _isPending(\n bytes32 _idHash\n ) internal view returns (bool isPending) {\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n isPending = ((gs.pending[_idHash] > 0 &&\n gs.pending[_idHash] < block.timestamp) &&\n block.timestamp < gs.pending[_idHash] + getSecurityWindow());\n }\n\n /**\n * @notice Adds guardian to storage config. This is called when guardian is fully added.\n * @dev This method add guardian address and config information to Facet Storage dedicated for guardian\n * When this function is called, guardian is fully added to this Barz Smart Account\n * @param _guardian Address of guardian to be added\n */\n function _addGuardian(address _guardian) internal {\n if (!isAdditionPending(_guardian))\n revert GuardianFacet__InvalidGuardianAddition();\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n if (config.info[_guardian].exists)\n revert GuardianFacet__AlreadyExists();\n\n config.info[_guardian].exists = true;\n config.info[_guardian].index = uint128(config.addresses.length);\n config.addresses.push(_guardian);\n }\n\n /**\n * @notice Removes guardian to storage config. This is called when guardian is fully removed.\n * @dev This method remove guardian address and config information to Facet Storage dedicated for guardian\n * When this function is called, guardian is fully removed from this Barz Smart Account\n * @param _guardian Address of guardian to be removed\n */\n function _removeGuardian(address _guardian) internal {\n if (!isRemovalPending(_guardian))\n revert GuardianFacet__InvalidGuardianRemoval();\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n if (!config.info[_guardian].exists)\n revert GuardianFacet__NonExistentGuardian();\n\n address lastAddress = config.addresses[config.addresses.length - 1];\n if (_guardian != lastAddress) {\n uint128 targetIndex = config.info[_guardian].index;\n config.addresses[targetIndex] = lastAddress;\n config.info[lastAddress].index = targetIndex;\n }\n config.addresses.pop();\n delete config.info[_guardian];\n\n emit GuardianRemoved(_guardian);\n }\n\n /**\n * @notice Reads guardian storage and fetches the addresses into an array from the storage\n * @dev This method fetches the guardian storage and returns the list of guardian addresses\n * @return guardians Array of addresses comprised of guardian\n */\n function getGuardians()\n public\n view\n override\n returns (address[] memory guardians)\n {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n uint256 guardiansLen = config.addresses.length;\n guardians = new address[](guardiansLen);\n for (uint256 i; i < guardiansLen; ) {\n guardians[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the number of majority of guardians\n * @return majorityOfGuardians_ Number of majority of guardians e.g., 2 if 3 guardians / 3 if 5 guardians\n */\n function majorityOfGuardians()\n public\n view\n override\n returns (uint256 majorityOfGuardians_)\n {\n majorityOfGuardians_ = LibGuardian.majorityOfGuardians();\n }\n\n /**\n * @notice Reads guardian storage and fetches the addresses into an array from the storage\n * @dev This method fetches the guardian storage and returns the list of guardian addresses\n * @return guardianNumber Array of guardians in the account\n */\n function guardianCount()\n public\n view\n override\n returns (uint256 guardianNumber)\n {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n guardianNumber = config.addresses.length;\n }\n\n /**\n * @notice Reads guardian storage and checks if the given address is a guardian\n * @return isGuardian_ Bool value representing if the given address is guardian\n */\n function isGuardian(\n address _guardian\n ) public view override returns (bool isGuardian_) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n isGuardian_ = config.info[_guardian].exists;\n }\n\n /**\n * @notice Checks if the guardian number is zero and returns of guardian facet is okay to be removed\n * @return isRemovable Bool value representing if guardian facet is removable\n */\n function isGuardianFacetRemovable()\n external\n view\n override\n returns (bool isRemovable)\n {\n isRemovable = (0 == guardianCount());\n }\n}\n" + }, + "contracts/facets/interfaces/IAccountFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IEntryPoint} from \"../../aa-4337/interfaces/IEntryPoint.sol\";\n\n/**\n * @title Account Facet Interface\n * @dev Interface of module contract that provides the account features and init/unitialization of signer\n * compatible with EIP-1271 & EIP-4337\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IAccountFacet {\n event AccountInitialized(\n IEntryPoint indexed entryPoint,\n bytes indexed ownerPublicKey\n );\n // NOTE: Added Below Event\n event VerificationSuccess(bytes32);\n event VerificationFailure(bytes32);\n\n error AccountFacet__InitializationFailure();\n error AccountFacet__RestrictionsFailure();\n error AccountFacet__NonExistentVerificationFacet();\n error AccountFacet__CallNotSuccessful();\n error AccountFacet__InvalidArrayLength();\n\n function initialize(\n address verificationFacet,\n address anEntryPoint,\n address facetRegistry,\n address _defaultFallBack,\n bytes calldata _ownerPublicKey\n ) external returns (uint256);\n\n function execute(address dest, uint256 value, bytes calldata func) external;\n\n function executeBatch(\n address[] calldata dest,\n uint256[] calldata value,\n bytes[] calldata func\n ) external;\n}\n" + }, + "contracts/facets/interfaces/IAccountRecoveryFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {RecoveryConfig} from \"../../libraries/LibFacetStorage.sol\";\n\n/**\n * @title Account Recovery Facet Interface\n * @dev Interface of contract that enables recovery of accounts when owner key is unavailable\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IAccountRecoveryFacet {\n event RecoveryExecuted(\n bytes indexed recoveryPublicKey,\n uint64 executeAfter\n );\n event RecoveryFinalized(bytes indexed recoveryPublicKey);\n event RecoveryCanceled(bytes indexed recoveryPublicKey);\n event RecoveryApproved(\n bytes indexed recoveryPublicKey,\n address indexed guardian,\n uint64 validUntil\n );\n event RecoveryApprovalRevoked(\n bytes indexed recoveryPublicKey,\n address indexed guardian\n );\n event RecoveryCancellationApproved(\n bytes indexed recoveryPublicKey,\n address indexed guardian\n );\n event RecoveryHardstopped();\n\n error AccountRecoveryFacet__CallerNotGuardian();\n error AccountRecoveryFacet__InvalidRecoveryPublicKey();\n error AccountRecoveryFacet__SignerInitializationFailure();\n error AccountRecoveryFacet__SignerUninitializationFailure();\n error AccountRecoveryFacet__InvalidArrayLength();\n error AccountRecoveryFacet__InsufficientGuardians();\n error AccountRecoveryFacet__RecoveryAlreadyOngoing();\n error AccountRecoveryFacet__NonexistentRecovery();\n error AccountRecoveryFacet__NonExistentApproval();\n error AccountRecoveryFacet__RecoveryPeriodNotOver();\n error AccountRecoveryFacet__InvalidLockPeriod();\n error AccountRecoveryFacet__InvalidRecoveryPeriod();\n error AccountRecoveryFacet__InvalidApprovalValidationPeriod();\n error AccountRecoveryFacet__InvalidGuardian();\n error AccountRecoveryFacet__InvalidGuardianSignature();\n error AccountRecoveryFacet__InvalidOwnerSignature();\n error AccountRecoveryFacet__CallNotSuccesful();\n error AccountRecoveryFacet__DuplicateApproval();\n\n function approveAccountRecovery(bytes calldata recoveryPublicKey) external;\n\n function revokeAccountRecoveryApproval(\n bytes calldata recoveryPublicKey\n ) external;\n\n function executeRecovery(\n bytes calldata recoveryPublicKey,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function finalizeRecovery() external;\n\n function approveCancelRecovery(bytes calldata recoveryPublicKey) external;\n\n function cancelRecovery(\n bytes calldata recoveryPublicKey,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function hardstopRecovery(bytes calldata signature) external;\n\n function validateNewOwner(bytes calldata recoveryPublicKey) external view;\n\n function getApprovalRecoveryKeyHash(\n bytes memory recoveryPublicKey,\n string memory saltString\n ) external view returns (bytes32);\n\n function getRecoveryApprovalCountWithTimeValidity(\n bytes32 recoveryPublicKeyHash\n ) external view returns (uint256);\n\n function isRecoveryApproved(\n bytes32 recoveryPublicKeyHash,\n address approver\n ) external view returns (bool);\n\n function getRecoveryNonce() external view returns (uint128);\n\n function getPendingRecovery() external view returns (RecoveryConfig memory);\n}\n" + }, + "contracts/facets/interfaces/IGuardianFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Guardian Facet Interface\n * @dev Interface of guaridna contract that enables addition/removal of guardians from Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IGuardianFacet {\n event GuardianAdditionRequested(\n address indexed guardian,\n uint256 executeAfter\n );\n event GuardianRemovalRequested(\n address indexed guardian,\n uint256 executeAfter\n );\n event GuardianAdditionCancelled(address indexed guardian);\n event GuardianRemovalCancelled(address indexed guardian);\n event GuardianAdded(address indexed guardian);\n event GuardianRemoved(address indexed guardian);\n\n error GuardianFacet__GuardianCannotBeSelf();\n error GuardianFacet__DuplicateGuardian();\n error GuardianFacet__OwnerCannotBeGuardian();\n error GuardianFacet__DuplicateGuardianAddition();\n error GuardianFacet__DuplicateGuardianRemoval();\n error GuardianFacet__UnknownPendingAddition();\n error GuardianFacet__PendingAdditionNotOver();\n error GuardianFacet__UnknownPendingRemoval();\n error GuardianFacet__PendingRemovalNotOver();\n error GuardianFacet__PendingAdditionExpired();\n error GuardianFacet__InvalidAdditionSecurityPeriod();\n error GuardianFacet__InvalidRemovalSecurityPeriod();\n error GuardianFacet__InvalidSecurityWindow();\n error GuardianFacet__NonExistentGuardian();\n error GuardianFacet__AlreadyExists();\n error GuardianFacet__InvalidGuardianAddition();\n error GuardianFacet__InvalidGuardianRemoval();\n error GuardianFacet__ZeroAddressGuardian();\n\n function addGuardian(address guardian) external;\n\n function addGuardians(address[] calldata guardians) external;\n\n function removeGuardian(address guardian) external;\n\n function removeGuardians(address[] calldata guardians) external;\n\n function confirmGuardianAddition(address guardian) external;\n\n function confirmGuardianAdditions(address[] calldata guardian) external;\n\n function confirmGuardianRemoval(address guardian) external;\n\n function confirmGuardianRemovals(address[] calldata guardian) external;\n\n function cancelGuardianAddition(address guardian) external;\n\n function cancelGuardianRemoval(address guardian) external;\n\n function isGuardian(address guardian) external view returns (bool);\n\n function isAdditionPending(address guardian) external view returns (bool);\n\n function isRemovalPending(address guardian) external view returns (bool);\n\n function isGuardianFacetRemovable() external view returns (bool);\n\n function getAdditionSecurityPeriod() external view returns (uint256);\n\n function getRemovalSecurityPeriod() external view returns (uint256);\n\n function getSecurityWindow() external view returns (uint256);\n\n function getGuardians() external view returns (address[] memory);\n\n function majorityOfGuardians() external view returns (uint256);\n\n function guardianCount() external view returns (uint256);\n}\n" + }, + "contracts/facets/interfaces/ILockFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Lock} from \"../../libraries/LibAppStorage.sol\";\n\n/**\n * @title Lock Facet Interface\n * @dev Interface of Lock contract that enables full lock/unlock of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface ILockFacet {\n event Locked(uint64 releaseAfter);\n event Unlocked();\n\n error LockFacet__InvalidRecoveryPeriod();\n error LockFacet__CannotUnlock();\n error LockFacet__InvalidSignature();\n error LockFacet__InvalidApprover();\n\n function lock() external;\n\n function unlock(address approver, bytes calldata signature) external;\n\n function getLockPeriod() external view returns (uint256);\n\n function isLocked() external view returns (bool);\n\n function getUnlockHash() external view returns (bytes32);\n\n function lockNonce() external view returns (uint128);\n\n function getPendingLock() external view returns (Lock memory);\n}\n" + }, + "contracts/facets/interfaces/IMultiSigFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Multi-sig facet Interface\n * @dev Interface of Multi-signature Facet with custom threshold.\n Wallet that adds this facet becomes a multi-sig wallet\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IMultiSigFacet {\n event ThresholdChanged(uint256 threshold);\n event OwnerAdded(address indexed newOwner);\n event OwnerRemoved(address indexed prevOwner);\n event HashApproved(bytes32 hashToApprove, address indexed owner);\n\n error MultiSigFacet__InvalidThreshold();\n error MultisigFacet__InvalidOwnerCount();\n error MultiSigFacet__InvalidRoute();\n error MultiSigFacet__InsufficientSignerLength();\n error MultiSigFacet__InvalidInitData();\n error MultiSigFacet__InvalidOwnerAddress();\n error MultiSigFacet__InvalidOwnerPair();\n error MultiSigFacet__InvalidSignatureLength();\n error MultiSigFacet__InvalidSignatureType();\n error MultiSigFacet__DuplicateOwner();\n error MultiSigFacet__OnlyOwner();\n\n function checkSignatures(\n bytes32 _dataHash,\n bytes calldata _signatures,\n uint256 _threshold\n ) external view returns (uint256);\n\n function splitSignatures(\n bytes calldata _signatures,\n uint256 _nextOffset\n )\n external\n pure\n returns (\n address owner,\n bytes memory signature,\n uint256 signatureType,\n uint256 nextOffset\n );\n\n function approveHash(bytes32 hashToApprove) external;\n\n function addOwner(address newOwner, uint256 threshold) external;\n\n function removeOwner(\n address prevOwner,\n address removedOwner,\n uint256 threshold\n ) external;\n\n function swapOwner(\n address prevOwner,\n address oldOwner,\n address newOwner\n ) external;\n\n function changeThreshold(uint256 _threshold) external;\n\n function isOwner(address owner) external view returns (bool);\n\n function getThreshold() external view returns (uint256);\n\n function getOwners() external view returns (address[] memory);\n}\n" + }, + "contracts/facets/interfaces/IRestrictionsFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Restrictions Facet Interface\n * @dev Interface of Restrictions contract that enables modular restrictions in Barz\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IRestrictionsFacet {\n event RestrictionAdded(address indexed restriction);\n event RestrictionRemoved(address indexed restriction);\n\n error RestrictionsFacet__EmptyRestrictionsList();\n error RestrictionsFacet__RestrictionNotFound();\n error RestrictionsFacet__RestrictionAlreadyExists();\n error RestrictionsFacet__ZeroAddressRestrictions();\n error RestrictionsFacet__ZeroAddressRestrictionsFacet();\n error RestrictionsFacet__RemainingRestrictionsCantBeEmpty();\n\n function initializeRestrictions(\n address[] memory _restrictions\n ) external returns (uint256);\n\n function uninitializeRestrictions() external returns (uint256);\n\n function getRestrictions() external view returns (address[] memory);\n\n function addRestriction(address restriction) external;\n\n function removeRestriction(address restriction) external;\n\n function verifyRestrictions(\n address from,\n address to,\n uint256 value,\n bytes calldata _calldata\n ) external returns (uint256);\n}\n" + }, + "contracts/facets/interfaces/ISignatureMigrationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureMigrationConfig} from \"../../libraries/LibFacetStorage.sol\";\n\n/**\n * @title Signature Migration Facet Interface\n * @dev Interface of Signature Migration contract for migrating user signature scheme to a new scheme user sets\n * Which could include\n * - ECDSA on Secp256K1 Curve\n * - ECDSA on Secp256R1 Curve\n * - BLS, Schnorr, etc\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface ISignatureMigrationFacet {\n event SignatureSchemeMigration(\n address indexed prevVerificationFacet,\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n event SignatureMigrationApproved(\n bytes newPublicKey,\n address indexed newVerificationFacet,\n bytes4[] verificationFuncSelectors,\n address indexed guardian,\n uint128 approvalValidUntil\n );\n event SignatureMigrationApprovalRevoked(\n bytes newPublicKey,\n address indexed newVerificationFacet,\n bytes4[] verificationFuncSelectors,\n address indexed guardian\n );\n event SignatureMigrationExecuted(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors,\n uint128 migrateAfter\n );\n event SignatureMigrationCanceled(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n event SignatureMigrationCancellationApproved(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n\n error SignatureMigrationFacet__SignerUninitializationFailure();\n error SignatureMigrationFacet__SignerInitializationFailure();\n error SignatureMigrationFacet__InvalidRouteWithGuardian();\n error SignatureMigrationFacet__InvalidKeyType();\n error SignatureMigrationFacet__InsufficientApprovers();\n error SignatureMigrationFacet__InvalidApproverSignature();\n error SignatureMigrationFacet__InvalidGuardian();\n error SignatureMigrationFacet__NonExistentApprover();\n error SignatureMigrationFacet__InvalidMigrationPeriod();\n error SignatureMigrationFacet__NonexistentMigration();\n error SignatureMigrationFacet__MigrationPeriodNotOver();\n error SignatureMigrationFacet__InvalidArrayLength();\n error SignatureMigrationFacet__InvalidApprovalValidationPeriod();\n error SignatureMigrationFacet__CannotRevokeUnapproved();\n error SignatureMigrationFacet__LackOfOwnerApproval();\n error SignatureMigrationFacet__OwnerAlreadyApproved();\n error SignatureMigrationFacet__NonExistentVerificationFacet();\n error SignatureMigrationFacet__DuplicateApproval();\n\n function migrateSignatureScheme(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function migrateSignatureSchemeWithGuardian(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors,\n address[] calldata approvers,\n bytes[] calldata signatures\n ) external;\n\n function approveSignatureSchemeMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function revokeSignatureMigrationApproval(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function finalizeSignatureMigration() external;\n\n function approveCancelSignatureMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function cancelSignatureMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function getApprovalMigrationKeyHash(\n bytes memory recoveryPublicKey,\n address newVerificationFacet,\n bytes4[] memory newVerificationFuncSelectors,\n string memory saltString\n ) external view returns (bytes32);\n\n function getMigrationOwnerApprovalWithTimeValidity(\n bytes32 publicKeyHash\n ) external view returns (bool);\n\n function getMigrationApprovalCountWithTimeValidity(\n bytes32 publicKeyHash\n ) external view returns (uint256);\n\n function isMigrationApproved(\n bytes32 migrationPublicKeyHash,\n address approver\n ) external view returns (bool);\n\n function getMigrationNonce() external view returns (uint128);\n\n function isMigrationPending() external view returns (bool);\n\n function getPendingMigration()\n external\n view\n returns (SignatureMigrationConfig memory);\n}\n" + }, + "contracts/facets/interfaces/IVerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {UserOperation} from \"../../aa-4337/interfaces/UserOperation.sol\";\n\n/**\n * @title Verification Facet Interface\n * @dev Implements logic for user ops signature verification\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface IVerificationFacet {\n event SignerInitialized(bytes);\n event SignerUninitialized();\n\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n error VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n error VerificationFacet__InitializationFailure();\n error VerificationFacet__InvalidFacetMapping();\n\n function initializeSigner(bytes memory) external returns (uint256);\n\n function uninitializeSigner() external returns (uint256);\n\n function validateOwnerSignatureSelector() external view returns (bytes4);\n\n function owner() external view returns (bytes memory);\n\n function isValidKeyType(bytes calldata) external view returns (bool);\n\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) external view returns (uint256);\n}\n" + }, + "contracts/facets/LockFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage, Lock} from \"../libraries/LibAppStorage.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibFacetStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {ILockFacet} from \"./interfaces/ILockFacet.sol\";\n\n/**\n * @title Lock Facet\n * @dev Contract that enables full lock/unlock of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract LockFacet is ILockFacet, Modifiers {\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Locks the account for the lock period. Lock period is defined in the security manager and it's customizable\n * This function can only be called when account is unlocked by owner or guardians\n * @dev This method checks the caller and if the account is currently locked and locks the account after fetching the\n * Lock period from the owner.\n */\n function lock() external override onlyGuardianOrOwner onlyWhenUnlocked {\n uint256 unlockTime = block.timestamp + getLockPeriod();\n unchecked {\n ++LibFacetStorage.lockStorage().nonce;\n }\n LibAppStorage.setLock(unlockTime, LockFacet.lock.selector);\n emit Locked(uint64(unlockTime));\n }\n\n /**\n * @notice Locks the account when the account is locked. This function can be called by anyone but must provide the approver address and signature.\n * The approver should be one of the guardians or owner.\n * @dev This method takes the approver address and the signature. After validating the address and the signature, it unlocks the account immediately.\n * Only one of the guardian or owner is required to lock and unlock the account.\n * @param _approver Address of approver approving the unlock of Barz account\n * @param _signature Signature of the approver that signed the msg hash for unlocking the account\n */\n function unlock(\n address _approver,\n bytes calldata _signature\n ) external override onlyWhenLocked {\n if (_approver != address(this) && !LibGuardian.isGuardian(_approver))\n revert LockFacet__InvalidApprover();\n if (\n !SignatureChecker.isValidSignatureNow(\n _approver,\n getUnlockHash(),\n _signature\n )\n ) revert LockFacet__InvalidSignature();\n _unlock();\n }\n\n /**\n * @notice Unlocks the account and increments the lock nonce\n */\n function _unlock() private {\n if (s.locks[INNER_STRUCT].locker != LockFacet.lock.selector)\n revert LockFacet__CannotUnlock();\n unchecked {\n ++LibFacetStorage.lockStorage().nonce;\n }\n LibAppStorage.setLock(0, bytes4(0));\n emit Unlocked();\n }\n\n /**\n * @notice Returns the lock period of current Barz account. Lock period information is held by Security Manager\n * @return lockPeriod Uint value of lock period in seconds\n */\n function getLockPeriod() public view override returns (uint256 lockPeriod) {\n lockPeriod = securityManager.lockPeriodOf(address(this));\n if (lockPeriod == 0) revert LockFacet__InvalidRecoveryPeriod();\n }\n\n /**\n * @notice Returns if the account is locked or not\n * @dev This method fetches the current block timestamp and compares that with release time.\n * After checking the timestamp and release time, it returns if the account is still locked or not.\n * @return isLocked_ Uint value of lock period in seconds\n */\n function isLocked() public view override returns (bool isLocked_) {\n isLocked_ = uint64(block.timestamp) < s.locks[INNER_STRUCT].release;\n }\n\n /**\n * @notice Calculates the unlock hash and returns the unlock hash safe from signature reply attack\n * @dev This method calculates the unlock hash with EIP-191 prefix, wallet address, chainID, and nonce\n * It packs the result and packs them and hashes it.\n * @return unlockHash Bytes32 unlock hash\n */\n function getUnlockHash() public view override returns (bytes32 unlockHash) {\n unlockHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n \"Unlock\",\n address(this),\n block.chainid,\n lockNonce()\n )\n )\n )\n );\n }\n\n /**\n * @notice Returns lock nonce of account. Reads nonce from lock storage within facet storage\n * @return lockNonce_ Uint128 value of lock nonce. This is incremented whenever the account is lock/unlocked\n */\n function lockNonce() public view override returns (uint128 lockNonce_) {\n lockNonce_ = LibFacetStorage.lockStorage().nonce;\n }\n\n /**\n * @notice Returns the overall information of current lock\n * @return pendingLock Struct value including all information of pending lock\n */\n function getPendingLock()\n public\n view\n override\n returns (Lock memory pendingLock)\n {\n pendingLock = s.locks[INNER_STRUCT];\n }\n}\n" + }, + "contracts/facets/Modifiers.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\n\n/**\n * @title Modifiers\n * @dev Responsible for providing modifiers/util functions to Facet contracts\n * @author David Yongjun Kim (@Powerstream3604)\n */\nabstract contract Modifiers is BarzStorage {\n uint8 constant INNER_STRUCT = 0;\n\n error CallerNotGuardian();\n error CallerNotGuardianOrOwner();\n error DuplicateApprover();\n error ZeroApproverLength();\n error UnregisteredFacetAndSelectors();\n\n /**\n * @notice Modifier to only allow guardian to make a call, reverts if any other entity is the caller\n */\n modifier onlyGuardian() {\n if (!LibGuardian.isGuardian(msg.sender)) revert CallerNotGuardian();\n _;\n }\n\n /**\n * @notice Modifier to only allow guardian or owner to make a call, reverts if any other entity is the caller\n */\n modifier onlyGuardianOrOwner() {\n if (!LibGuardian.isGuardian(msg.sender) && address(this) != msg.sender)\n revert CallerNotGuardianOrOwner();\n _;\n }\n\n /**\n * @notice Checks if the approver address is the array is unique with no duplicate\n * @dev This method loops through the array and checks if a duplicate address exists, it reverts if duplicate address exists\n * @param approvers Array of address\n */\n function _checkApprover(\n address[] memory approvers\n ) internal pure returns (bool) {\n uint256 approverLength = approvers.length;\n if (0 == approverLength) revert ZeroApproverLength();\n for (uint256 i; i < approverLength - 1; ) {\n for (uint256 j = i + 1; j < approverLength; ) {\n if (approvers[i] == approvers[j]) {\n revert DuplicateApprover(); // Found a duplicate\n }\n unchecked {\n ++j;\n }\n }\n unchecked {\n ++i;\n }\n }\n return false; // No duplicates found\n }\n\n /**\n * @notice Checks if the facet getting added or replaced is registered to facet registry\n * @dev This method loops through the cut and checks if the facet getting added/replaced is registered to facet registry\n * @param _diamondCut Array of FacetCut, data for diamondCut defined in EIP-2535\n */\n function _checkFacetCutValidity(\n IDiamondCut.FacetCut[] memory _diamondCut\n ) internal view {\n uint256 diamondCutLength = _diamondCut.length;\n for (uint256 i; i < diamondCutLength; ) {\n if (\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Add ||\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Replace\n ) {\n if (\n !s.facetRegistry.areFacetFunctionSelectorsRegistered(\n _diamondCut[i].facetAddress,\n _diamondCut[i].functionSelectors\n )\n ) revert UnregisteredFacetAndSelectors();\n }\n unchecked {\n ++i;\n }\n }\n }\n}\n" + }, + "contracts/facets/ReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibReentrancyGuardStorage, ReentrancyGuardStorage} from \"../libraries/LibReentrancyGuardStorage.sol\";\n\nabstract contract ReentrancyGuard {\n\n uint256 private constant _NOT_ENTERED = 0;\n uint256 private constant _ENTERED = 1;\n\n error ReentrancyGuard__ReentrantCall();\n\n modifier nonReentrant() {\n ReentrancyGuardStorage storage rgs = LibReentrancyGuardStorage.reentrancyguardStorage();\n\n if (rgs.status == _ENTERED) revert ReentrancyGuard__ReentrantCall();\n\n rgs.status = _ENTERED;\n\n _; // Execute function\n\n rgs.status = _NOT_ENTERED;\n }\n}\n" + }, + "contracts/facets/RestrictionsFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ReentrancyGuard} from \"./ReentrancyGuard.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, RestrictionsStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {IRestriction} from \"../restrictions/IRestriction.sol\";\nimport {IRestrictionsFacet} from \"./interfaces/IRestrictionsFacet.sol\";\n\n/**\n * @title Restrictions facet\n * @dev Responsible for storing and verifying different kinds of restrictions, for example:\n * - Whitelist / Blacklist\n * - Daily limits\n * - Trading time restrictions\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract RestrictionsFacet is IRestrictionsFacet, ReentrancyGuard {\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceRestrictionsInitialize();\n }\n\n /**\n * @notice Intialize restrictions of Barz. Restrictions facet call restriction contracts for restriction validation\n * before each call\n * @param _restrictions The initial array of restrictions.\n * @return initSuccess Int value showing if the initialization of restriction is successful\n */\n function initializeRestrictions(\n address[] calldata _restrictions\n ) public override returns (uint256 initSuccess) {\n LibDiamond.enforceIsSelf();\n LibAppStorage.enforceRestrictionsInitialize();\n\n if (_restrictions.length == 0) {\n // You can't initialize RestrictionsFacet with an empty list of restrictions\n revert RestrictionsFacet__EmptyRestrictionsList();\n }\n for (uint256 i; i < _restrictions.length; ) {\n if (_restrictions[i] == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictions();\n unchecked {\n ++i;\n }\n }\n\n LibFacetStorage.restrictionsStorage().restrictions = _restrictions;\n _updateRestrictionsMap(_restrictions, true);\n initSuccess = 1;\n }\n\n /**\n * @notice Unitialize restrictions of Barz\n * @return uninitSuccess Int value showing if the initialization of restriction is successful\n */\n function uninitializeRestrictions()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibDiamond.enforceIsSelf();\n LibAppStorage.setRestrictionsUninitialized();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n _updateRestrictionsMap(restrictionsStorage.restrictions, false);\n restrictionsStorage.restrictions = new address[](0);\n uninitSuccess = 1;\n }\n\n /**\n * @notice Returns the list of Restrictions contract address\n * @return restrictions Addresses of IRestriction which are currently active\n */\n function getRestrictions()\n public\n view\n override\n returns (address[] memory restrictions)\n {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n restrictions = restrictionsStorage.restrictions;\n }\n\n /**\n * @notice Adds restrictions to Barz with validation on the restriction contract address.\n * This method is only callable by the owner(self).\n * @param _restriction The address of the restriction to be added.\n */\n function addRestriction(address _restriction) external override {\n LibDiamond.enforceIsSelf();\n if (LibDiamond.restrictionsFacet() == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictionsFacet();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n if (_restriction == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictions();\n if (restrictionsStorage.exists[_restriction])\n revert RestrictionsFacet__RestrictionAlreadyExists();\n\n restrictionsStorage.restrictions.push(_restriction);\n restrictionsStorage.exists[_restriction] = true;\n\n emit RestrictionAdded(_restriction);\n }\n\n /**\n * @notice Remove restrictions from Barz if it existed. This method is only callable by the owner(self).\n * @param _restriction The address of the restriction to be removed.\n */\n function removeRestriction(address _restriction) external override {\n LibDiamond.enforceIsSelf();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n if (!restrictionsStorage.exists[_restriction])\n revert RestrictionsFacet__RestrictionNotFound();\n\n address[] storage restrictions = restrictionsStorage.restrictions;\n\n uint256 indexToDelete = restrictions.length;\n uint256 restrictionsLen = restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n if (restrictions[i] == _restriction) {\n indexToDelete = i;\n break;\n }\n unchecked {\n ++i;\n }\n }\n\n if (indexToDelete == 0 && restrictionsLen == 1) {\n revert RestrictionsFacet__RemainingRestrictionsCantBeEmpty();\n } else if (indexToDelete == restrictionsLen) {\n revert RestrictionsFacet__RestrictionNotFound();\n } else {\n restrictions[indexToDelete] = restrictions[restrictionsLen - 1];\n restrictions.pop();\n }\n\n restrictionsStorage.exists[_restriction] = false;\n emit RestrictionRemoved(_restriction);\n }\n\n /**\n * @notice Sets the restrictions address value mapping to true or false when adding/removing restriction contracts\n * @param _restrictions List of restriction contracts address\n * @param _newValue Bool value to flag to the list of restrictions contracts\n */\n function _updateRestrictionsMap(\n address[] memory _restrictions,\n bool _newValue\n ) internal {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n uint restrictionsLen = _restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n restrictionsStorage.exists[_restrictions[i]] = _newValue;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @dev Iterates over all restrictions and verifies each of them with the transaction parameters.\n * @param _from The address of the sender, that will be signing the transaction.\n * @param _to The receiving address.\n * @param _value Amount of ETH to transfer from sender to recipient.\n * @param _calldata Optional field to include arbitrary data.\n * @return 0 if all the checks passed, 1 otherwise.\n */\n function verifyRestrictions(\n address _from,\n address _to,\n uint256 _value,\n bytes calldata _calldata\n ) external nonReentrant returns (uint256) {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n uint restrictionsLen = restrictionsStorage.restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n IRestriction restriction = IRestriction(\n restrictionsStorage.restrictions[i]\n );\n bool checkPassed = restriction.check(_from, _to, _value, _calldata);\n if (!checkPassed) {\n return 1;\n }\n unchecked {\n ++i;\n }\n }\n\n return 0;\n }\n}\n" + }, + "contracts/facets/SignatureMigrationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, SignatureMigrationStorage, SignatureMigrationConfig, SignatureMigrationApprovalConfig, ApprovalConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IDiamondCut} from \"./base/interfaces/IDiamondCut.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {ISignatureMigrationFacet} from \"./interfaces/ISignatureMigrationFacet.sol\";\n\n/**\n * @title Signature Migration Facet\n * @dev Responsible for migrating user signature scheme to a new scheme user sets\n * Which could include\n * - ECDSA on Secp256K1 Curve\n * - ECDSA on Secp256R1 Curve\n * - BLS, Schnorr, etc\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract SignatureMigrationFacet is ISignatureMigrationFacet, Modifiers {\n bytes constant UNINIT_CALL =\n abi.encodeWithSignature(\"uninitializeSigner()\");\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This modifier verifies if the public key format matches with the new verification facet\n * @param _publicKey Bytes of public key to be validated for the new verification facet\n * @param _newVerificationFacet Address of new verification facet\n */\n modifier validateKeyType(\n bytes memory _publicKey,\n address _newVerificationFacet\n ) {\n if (\n !IVerificationFacet(_newVerificationFacet).isValidKeyType(\n _publicKey\n )\n ) revert SignatureMigrationFacet__InvalidKeyType();\n _;\n }\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n // IMPORTANT NOTE: In the client side when they call this function, the func selectors should be sorted in ascending order\n // to prevent different hash with same items in the array\n /**\n * @notice Moves the state of migration to a pending state. When pending state is over after pending period time,\n * Migration can be finalized. This function can only be called by self and when the account is unlocked.\n * @dev This method checks if the caller is self and if guardians exists. It migrates signature request to a pending state\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function migrateSignatureScheme(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n public\n override\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n // Only self contract can call this function\n LibDiamond.enforceIsSelf();\n // Should revert if guardian exist\n if (0 != LibGuardian.guardianCount())\n revert SignatureMigrationFacet__InvalidRouteWithGuardian();\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n // NOTE: Migration requires a pending period & confirmation from owner to prevent a\n // single call changing the ownership of the wallet\n /**\n * @notice Migrate signature scheme when guardians exists. Verifies the signature of guardians and moves migration to pending state.\n * Which can then be finalized when pending period is over. Owner's approval is mandatory for migration to happen\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _approvers List of approvers. This could include owner\n */\n function migrateSignatureSchemeWithGuardian(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n )\n public\n override\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n // Should revert if does not guardian exist\n if (0 == LibGuardian.guardianCount())\n revert SignatureMigrationFacet__InvalidRouteWithGuardian();\n if (_approvers.length != _signatures.length)\n revert SignatureMigrationFacet__InvalidArrayLength();\n\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(migrationPublicKeyHash, _approvers);\n\n bool onChainOwnerApproval = getMigrationOwnerApprovalWithTimeValidity(\n migrationPublicKeyHash\n );\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n\n if (\n _approvers.length +\n getMigrationApprovalCountWithTimeValidity(\n migrationPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert SignatureMigrationFacet__InsufficientApprovers();\n {\n // To prevent Stack too deep\n bool ownerApproved;\n for (uint256 i; i < _approvers.length; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n address(this) != _approvers[i]\n ) revert SignatureMigrationFacet__InvalidGuardian();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert SignatureMigrationFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n migrationPublicKeyHash,\n _signatures[i]\n )\n ) revert SignatureMigrationFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n\n if (!ownerApproved && !onChainOwnerApproval)\n revert SignatureMigrationFacet__LackOfOwnerApproval();\n }\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Internal function that moves signature mgiration to a pending state.\n * @dev This method increments migration nonce and sets the migration in the migration config. Emits events for migration execution\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _migrateSignatureScheme(\n address _newVerificationFacet,\n bytes memory _newPublicKey,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal {\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n unchecked {\n ++ms.nonce;\n }\n uint64 migrateAfter = uint64(block.timestamp + getMigrationPeriod());\n\n ms.migrationConfigs[INNER_STRUCT] = SignatureMigrationConfig(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n migrateAfter\n );\n\n emit SignatureMigrationExecuted(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors,\n migrateAfter\n );\n }\n\n /**\n * @notice Approves signature scheme migration on-chain. This can be called by owner or guardian only when the account is unlocked.\n * When the threshold of the migration approval passed and owner approval is granted, it automatically moves migration to a pending state\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function approveSignatureSchemeMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n public\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit SignatureMigrationApproved(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n msg.sender,\n approvalValidUntil\n );\n if (\n getMigrationApprovalCountWithTimeValidity(migrationPublicKeyHash) >=\n LibGuardian.majorityOfGuardians() &&\n getMigrationOwnerApprovalWithTimeValidity(migrationPublicKeyHash)\n )\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Revokes the approval of signature migration done on-chain. Emits revoke event when revoked.\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function revokeSignatureMigrationApproval(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n external\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n if (!isMigrationApproved(migrationPublicKeyHash, msg.sender))\n revert SignatureMigrationFacet__CannotRevokeUnapproved();\n\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(false, 0);\n emit SignatureMigrationApprovalRevoked(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n msg.sender\n );\n }\n\n /**\n * @notice Finalizes the pending signature scheme migration. This function can only be called by owner.\n * It removes the facets of the previous verification facet and adds the new verification facet.\n * After finalizing migration, it emits migration event which shows the change of the verification facet\n */\n function finalizeSignatureMigration() external override {\n // NOTE: Only owner can call this function\n LibDiamond.enforceIsSelf();\n\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n\n if (!isMigrationPending())\n revert SignatureMigrationFacet__NonexistentMigration();\n\n if (\n uint64(block.timestamp) <=\n ms.migrationConfigs[INNER_STRUCT].migrateAfter\n ) revert SignatureMigrationFacet__MigrationPeriodNotOver();\n address newVerificationFacet = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationVerificationFacet;\n bytes4[] memory newVerificationFuncSelectors = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationSelectors;\n bytes memory newPublicKey = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationPublicKey;\n\n address prevVerificationFacet = LibLoupe.facetAddress(\n s.validateOwnerSignatureSelector\n );\n if (prevVerificationFacet == address(0))\n revert SignatureMigrationFacet__NonExistentVerificationFacet();\n\n IDiamondCut.FacetCut[] memory UninitCut;\n IDiamondCut.FacetCut[] memory InitCut;\n {\n bytes4[] memory prevVerificationFuncSelectors = LibLoupe\n .facetFunctionSelectors(prevVerificationFacet);\n\n UninitCut = new IDiamondCut.FacetCut[](1);\n InitCut = new IDiamondCut.FacetCut[](1);\n UninitCut[0] = IDiamondCut.FacetCut({\n facetAddress: address(0),\n action: IDiamondCut.FacetCutAction.Remove,\n functionSelectors: prevVerificationFuncSelectors\n });\n InitCut[0] = IDiamondCut.FacetCut({\n facetAddress: newVerificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: newVerificationFuncSelectors\n });\n {\n IDiamondCut.FacetCut[]\n memory facetCuts = new IDiamondCut.FacetCut[](2);\n facetCuts[0] = UninitCut[0];\n facetCuts[1] = InitCut[0];\n _checkFacetCutValidity(facetCuts);\n }\n LibAppStorage.initiateSignerMigration();\n address verificationFacet = address(\n bytes20(\n LibDiamond.diamondStorage().facets[\n s.validateOwnerSignatureSelector\n ]\n )\n );\n\n (bool uninitSuccess, bytes memory uninitResult) = verificationFacet\n .delegatecall(UNINIT_CALL);\n if (!uninitSuccess || uint256(bytes32(uninitResult)) != 1)\n revert SignatureMigrationFacet__SignerUninitializationFailure();\n LibAppStorage.finalizeSignerMigration();\n\n LibDiamond.diamondCut(UninitCut, address(0), \"\");\n }\n {\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n newPublicKey\n );\n\n // Every Verification Facet should comply with initializeSigner(bytes)\n // to be compatible with the Barz contract(for initialization)\n LibDiamond.diamondCut(InitCut, address(0), \"\");\n (bool initSuccess, bytes memory initResult) = newVerificationFacet\n .delegatecall(initCall);\n if (!initSuccess || uint256(bytes32(initResult)) != 1)\n revert SignatureMigrationFacet__SignerInitializationFailure();\n\n emit SignatureSchemeMigration(\n prevVerificationFacet,\n newVerificationFacet,\n newPublicKey,\n newVerificationFuncSelectors\n );\n }\n }\n\n /**\n * @notice Approve cancellation of signature migration. If cancellation approval passes guardian threshold with owner approval\n * it automatically cancels the migration.\n * @dev This method checks if the caller is one of guardian or owner and sets true for the cancellation hash in the approval config.\n * It internally calls _cancelSignatureMigration for canceling the migration\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function approveCancelSignatureMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n external\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"CancelSignatureMigration\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit SignatureMigrationCancellationApproved(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n if (\n getMigrationApprovalCountWithTimeValidity(migrationPublicKeyHash) >=\n LibGuardian.majorityOfGuardians() &&\n getMigrationOwnerApprovalWithTimeValidity(migrationPublicKeyHash)\n )\n _cancelSignatureMigration(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Verifies the signature of guardians/owner and cancels the signature migration.\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _approvers List of approvers. This could include owner\n */\n function cancelSignatureMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n )\n external\n override\n validateKeyType(_newPublicKey, _newVerificationFacet)\n onlyWhenUnlocked\n {\n if (_approvers.length != _signatures.length)\n revert SignatureMigrationFacet__InvalidArrayLength();\n\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"CancelSignatureMigration\"\n );\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(migrationPublicKeyHash, _approvers);\n\n bool onChainOwnerApproval = getMigrationOwnerApprovalWithTimeValidity(\n migrationPublicKeyHash\n );\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n if (\n _approvers.length +\n getMigrationApprovalCountWithTimeValidity(\n migrationPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert SignatureMigrationFacet__InsufficientApprovers();\n {\n // To prevent stack too deep\n bool ownerApproved;\n for (uint256 i; i < _approvers.length; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n address(this) != _approvers[i]\n ) revert SignatureMigrationFacet__NonExistentApprover();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert SignatureMigrationFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n migrationPublicKeyHash,\n _signatures[i]\n )\n ) revert SignatureMigrationFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n if (!ownerApproved && !onChainOwnerApproval)\n revert SignatureMigrationFacet__LackOfOwnerApproval();\n }\n _cancelSignatureMigration(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Internal function that cancels signature migration.\n * @dev This method increments migration nonce and deletes the migration from the migration config. Emits events for migration cancellation\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _cancelSignatureMigration(\n address _newVerificationFacet,\n bytes memory _newPublicKey,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal {\n if (!isMigrationPending())\n revert SignatureMigrationFacet__NonexistentMigration();\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n unchecked {\n ++ms.nonce;\n }\n delete ms.migrationConfigs[INNER_STRUCT];\n emit SignatureMigrationCanceled(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Checks if the facets to be added from new verification facet is registered to facet registry\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _checkMigrationCutValidity(\n address _newVerificationFacet,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal view {\n IDiamondCut.FacetCut[] memory facetCuts = new IDiamondCut.FacetCut[](1);\n facetCuts[0] = IDiamondCut.FacetCut({\n facetAddress: _newVerificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: _newVerificationFuncSelectors\n });\n _checkFacetCutValidity(facetCuts);\n }\n\n /**\n * @notice Returns if the migration is pending of not\n * @dev This method fetches the migration storage and checks if the migrate after is above 0 value\n * @return isPending Bool value that shows if the migration is pending\n */\n function isMigrationPending()\n public\n view\n override\n returns (bool isPending)\n {\n SignatureMigrationStorage storage rs = LibFacetStorage\n .migrationStorage();\n isPending = rs.migrationConfigs[INNER_STRUCT].migrateAfter > 0;\n }\n\n /**\n * @notice Returns the migration hash. This function ensures that this hash is safe from replay attack by including\n * public key, verification facet, function selectors, salt, address, chainId, and nonce.\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _saltString Salt value for generating the migration hash\n * @return migrationKeyHash Bytes32 string of the migration key hash\n */\n function getApprovalMigrationKeyHash(\n bytes memory _newPublicKey,\n address _newVerificationFacet,\n bytes4[] memory _newVerificationFuncSelectors,\n string memory _saltString\n ) public view override returns (bytes32 migrationKeyHash) {\n migrationKeyHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n _newPublicKey,\n _newVerificationFacet,\n keccak256(abi.encode(_newVerificationFuncSelectors)),\n _saltString,\n address(this),\n block.chainid,\n LibFacetStorage.migrationStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Checks if the owner approved the hash for migration\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @return isApprovedByOwner Bool value of showing if the owner approved it or not\n */\n function getMigrationOwnerApprovalWithTimeValidity(\n bytes32 _migrationPublicKeyHash\n ) public view override returns (bool isApprovedByOwner) {\n isApprovedByOwner = isMigrationApproved(\n _migrationPublicKeyHash,\n address(this)\n );\n }\n\n /**\n * @notice Checks how many of the guardians approved the migration hash\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @return approvalCount Number of approvals\n */\n function getMigrationApprovalCountWithTimeValidity(\n bytes32 _migrationPublicKeyHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardiansLength = guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n if (isMigrationApproved(_migrationPublicKeyHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n return approvalCount;\n }\n\n /**\n * @notice Checks if the migration is approved by the given approver\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @param _approver Address of approver\n * @return isApproved Bool value if migration hash is approved\n */\n function isMigrationApproved(\n bytes32 _migrationPublicKeyHash,\n address _approver\n ) public view override returns (bool isApproved) {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n isApproved = (ms\n .isMigrationApproved[_migrationPublicKeyHash][_approver].isApproved &&\n block.timestamp <\n ms\n .isMigrationApproved[_migrationPublicKeyHash][_approver]\n .validUntil);\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _migrationPublicKeyHash Hash of migration information\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _migrationPublicKeyHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isMigrationApproved(_migrationPublicKeyHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert SignatureMigrationFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the migration period of this wallet\n * @dev This method fetches the migration period from the security manager\n * @return migrationPeriod Migration period of Barz contract fetched from security manager\n */\n function getMigrationPeriod()\n internal\n view\n returns (uint128 migrationPeriod)\n {\n migrationPeriod = securityManager.migrationPeriodOf(address(this));\n if (migrationPeriod == 0)\n revert SignatureMigrationFacet__InvalidMigrationPeriod();\n }\n\n /**\n * @notice Returns the validation period of this wallet\n * @dev This method fetches the validation period from the security manager\n * @return approvalValidationPeriod Validation period of Barz contract fetched from security manager\n */\n function getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod == 0)\n revert SignatureMigrationFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the migration nonce of this wallet\n * @dev This method fetches the nonce from migration storage\n * @return migrationNonce Nonce of migration to protect from reply attacks\n */\n function getMigrationNonce()\n public\n view\n override\n returns (uint128 migrationNonce)\n {\n migrationNonce = LibFacetStorage.migrationStorage().nonce;\n }\n\n /**\n * @notice Returns the migration configuration of this wallet\n * @dev This method fetches the migration config from the migration storage\n * @return pendingMigrationConfig Migration config currently pending for signature migration\n */\n function getPendingMigration()\n external\n view\n override\n returns (SignatureMigrationConfig memory pendingMigrationConfig)\n {\n pendingMigrationConfig = LibFacetStorage\n .migrationStorage()\n .migrationConfigs[INNER_STRUCT];\n }\n}\n" + }, + "contracts/facets/TokenReceiverFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {IERC1155Receiver} from \"../interfaces/ERC/IERC1155Receiver.sol\";\nimport {IERC677Receiver} from \"../interfaces/ERC/IERC677Receiver.sol\";\n\n/**\n * @title TokenReceiver Facet\n * @dev Contract that enables receiving ERC721/ERC1155/ERC777/ERC677 Tokens with safe transfer\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract TokenReceiverFacet is\n IERC721Receiver,\n IERC1155Receiver,\n IERC777Recipient,\n IERC677Receiver\n{\n /**\n * @notice Handles ERC721 Token callback.\n * return Standardized onERC721Received return value.\n */\n function onERC721Received(\n address,\n address,\n uint256,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC721Receiver.onERC721Received.selector;\n }\n\n /**\n * @notice Handles ERC1155 Token callback.\n * return Standardized onERC1155Received return value.\n */\n function onERC1155Received(\n address,\n address,\n uint256,\n uint256,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC1155Receiver.onERC1155Received.selector;\n }\n\n /**\n * @notice Handles ERC1155 Token batch callback.\n * return Standardized onERC1155BatchReceived return value.\n */\n function onERC1155BatchReceived(\n address,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC1155Receiver.onERC1155BatchReceived.selector;\n }\n\n /**\n * @notice Handles ERC777 Token callback.\n * Does not return value, empty implementation.\n */\n function tokensReceived(\n address,\n address,\n address,\n uint256,\n bytes calldata,\n bytes calldata\n ) external pure override {}\n\n /**\n * @notice Handles ERC677 Token callback.\n * return true.\n */\n function onTokenTransfer(\n address,\n uint256,\n bytes calldata\n ) external pure override returns (bool) {\n return true;\n }\n}\n" + }, + "contracts/facets/verification/MultiSigFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {UserOperation} from \"../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../../libraries/LibLoupe.sol\";\nimport {LibAppStorage} from \"../../libraries/LibAppStorage.sol\";\nimport {LibMultiSigStorage, MultiSigStorage} from \"../../libraries/LibMultiSigStorage.sol\";\nimport {IERC1271} from \"../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../interfaces/IVerificationFacet.sol\";\nimport {IMultiSigFacet} from \"../interfaces/IMultiSigFacet.sol\";\n\n/**\n * @title Multi-sig facet\n * @dev Multi-signature Facet with custom threshold.\n * Wallet that adds this facet becomes a multi-sig wallet.\n * Reference signature_format.md documentation for Multi-sig facet details\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract MultiSigFacet is IMultiSigFacet, IVerificationFacet, IERC1271 {\n using ECDSA for bytes32;\n\n address public immutable self;\n\n address internal constant SENTINEL_OWNERS = address(0x1);\n uint256 internal constant ADDRESS = 20;\n uint256 internal constant SIG_TYPE = 1;\n uint256 internal constant SIG_LEN = 4;\n uint256 internal constant THRESHOLD = 4;\n uint256 internal constant INVALID_SIG = 1;\n uint256 internal constant VALID_SIG = 0;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in Multisig Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the right format and initializes signer storage in k1 storage.\n * @param _owners Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _owners\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n\n if (!isValidKeyType(_owners)) revert MultiSigFacet__InvalidInitData();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n uint256 threshold = uint256(uint32(bytes4(_owners)));\n uint256 ownerCount = (_owners.length - THRESHOLD) / ADDRESS;\n\n if (threshold == 0) revert MultiSigFacet__InvalidThreshold();\n if (ownerCount == 0) revert MultisigFacet__InvalidOwnerCount();\n\n address currentOwner = SENTINEL_OWNERS;\n uint256 ptr = THRESHOLD;\n address owner_;\n for (uint256 i; i < ownerCount; ) {\n owner_ = address(bytes20(_owners[ptr:ptr + ADDRESS]));\n ptr += ADDRESS;\n if (\n owner_ == address(0) ||\n owner_ == SENTINEL_OWNERS ||\n owner_ == address(this) ||\n owner_ == currentOwner\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[owner_] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n\n ms.owners[currentOwner] = owner_;\n currentOwner = owner_;\n\n unchecked {\n ++i;\n }\n }\n ms.owners[currentOwner] = SENTINEL_OWNERS;\n ms.ownerCount = ownerCount;\n ms.threshold = threshold;\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_owners);\n }\n\n /**\n * @notice Uninitialize signer in K1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n ++ms.counter;\n address[] memory ownerlist = getOwners();\n uint256 ownerlistLength = ownerlist.length;\n for (uint256 i; i < ownerlistLength; ) {\n ms.owners[ownerlist[i]] = address(0);\n unchecked {\n ++i;\n }\n }\n ms.owners[SENTINEL_OWNERS] = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls checkSignatures with\n * user operation hash and signature together with the threshold.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n // Data 1 is invalid, Data 0 is valid\n validationData = checkSignatures(\n userOpHash,\n userOp.signature,\n LibMultiSigStorage.multisigStorage().threshold\n );\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n return this.validateOwnerSignature.selector;\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n uint totalLength = ms.ownerCount * ADDRESS;\n bytes memory result = new bytes(totalLength);\n\n // populate return array\n uint256 index;\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n while (currentOwner != SENTINEL_OWNERS) {\n assembly {\n mstore(\n add(result, add(32, mul(index, ADDRESS))),\n shl(96, currentOwner)\n )\n }\n currentOwner = ms.owners[currentOwner];\n index++;\n }\n\n return result;\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key should comply with the format in the signature_format.md doc\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n uint256 publicKeyLength = _publicKey.length;\n if (\n publicKeyLength < ADDRESS + THRESHOLD ||\n (publicKeyLength - THRESHOLD) % ADDRESS != 0\n ) return false;\n\n uint256 threshold = uint256(uint32(bytes4(_publicKey)));\n uint256 ownerCount = (publicKeyLength - THRESHOLD) / ADDRESS;\n\n isValid = !(ownerCount < threshold || threshold == 0);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes calldata _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (checkSignatures(\n _hash,\n _signature,\n LibMultiSigStorage.multisigStorage().threshold\n ) == VALID_SIG)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n\n /**\n * @notice Validates the format of the signature and verifies if the signature is signed by the expected key.\n * Reference signature_format.md doc for details about signature format and signature types\n * @param _dataHash Bytes value of data hash signed by the owners\n * @param _signatures Bytes value of signature which should comply with signature format\n * @param _threshold Uint256 value of current Multi-sig Barz's threshold\n */\n function checkSignatures(\n bytes32 _dataHash,\n bytes calldata _signatures,\n uint256 _threshold\n ) public view returns (uint256) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n address lastOwner = address(0);\n address currentOwner;\n bytes memory signature;\n uint256 signatureType;\n uint256 nextOffset;\n uint256 i;\n for (i; i < _threshold; ) {\n (\n currentOwner,\n signature,\n signatureType,\n nextOffset\n ) = splitSignatures(_signatures, nextOffset);\n if (nextOffset == 0 && i + 1 < _threshold) return INVALID_SIG;\n if (signatureType == 1) {\n // If signatureType is 1 then it is default dataHash signed.\n // This also includes the contract signature\n if (\n !SignatureChecker.isValidSignatureNow(\n currentOwner,\n _dataHash,\n signature\n )\n ) return INVALID_SIG;\n } else if (signatureType == 2) {\n // If signatureType is 2 then it is an approved hash\n if (ms.approvedHashes[ms.counter][currentOwner][_dataHash] == 0)\n return INVALID_SIG;\n } else if (signatureType == 3) {\n // If signatureType is 3 then it is a signed message hash\n // This also includes the contract signature\n bytes32 msgHash = _dataHash.toEthSignedMessageHash();\n if (\n !SignatureChecker.isValidSignatureNow(\n currentOwner,\n msgHash,\n signature\n )\n ) return INVALID_SIG;\n } else revert MultiSigFacet__InvalidRoute();\n if (\n currentOwner <= lastOwner ||\n ms.owners[currentOwner] == address(0) ||\n currentOwner == SENTINEL_OWNERS\n ) return INVALID_SIG;\n lastOwner = currentOwner;\n\n unchecked {\n ++i;\n }\n }\n return VALID_SIG;\n }\n\n /**\n * @notice Split signatures into each individual signatures. Should comply with signature format to be split\n * @param _signatures Bytes value of signature\n * @param _nextOffset Uint256 value of next offset to start splitting the signature\n */\n function splitSignatures(\n bytes calldata _signatures,\n uint256 _nextOffset\n )\n public\n pure\n returns (\n address owner_,\n bytes memory signature,\n uint256 signatureType,\n uint256 nextOffset\n )\n {\n uint256 signaturesLength = _signatures.length;\n\n if (signaturesLength <= _nextOffset + ADDRESS + SIG_LEN)\n revert MultiSigFacet__InsufficientSignerLength();\n\n owner_ = address(\n bytes20(_signatures[_nextOffset:_nextOffset + ADDRESS])\n );\n\n signatureType = uint256(\n uint8(\n bytes1(\n _signatures[_nextOffset + ADDRESS:_nextOffset +\n ADDRESS +\n SIG_TYPE]\n )\n )\n );\n\n if (signatureType > 3 || signatureType == 0)\n revert MultiSigFacet__InvalidSignatureType();\n uint256 offSet = _nextOffset + ADDRESS + SIG_TYPE;\n uint256 siglen = uint256(\n uint32(bytes4(_signatures[offSet:offSet + SIG_LEN]))\n );\n if (offSet + siglen > signaturesLength)\n revert MultiSigFacet__InvalidSignatureLength();\n\n offSet += SIG_LEN;\n if (offSet + siglen == signaturesLength) nextOffset = 0;\n else nextOffset = offSet + siglen;\n\n signature = _signatures[offSet:offSet + siglen];\n }\n\n /**\n * @notice Approves the hash of userOperation on-chain. This can only be called by owners.\n * @param _hashToApprove Bytes value of UserOperation hash to approve\n */\n function approveHash(bytes32 _hashToApprove) external {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (ms.owners[msg.sender] == address(0))\n revert MultiSigFacet__OnlyOwner();\n\n ms.approvedHashes[ms.counter][msg.sender][_hashToApprove] = 1;\n emit HashApproved(_hashToApprove, msg.sender);\n }\n\n /**\n * @notice Add owner to Barz. Update thresold if threshold is given different from current threshold\n * @dev This can only be done via a Self call.\n * @param _newOwner Address of new owner to be added\n * @param _threshold Uint256 value of threshold\n */\n function addOwner(address _newOwner, uint256 _threshold) external {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (\n _newOwner == address(0) ||\n _newOwner == SENTINEL_OWNERS ||\n _newOwner == address(this)\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_newOwner] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n\n ms.owners[_newOwner] = ms.owners[SENTINEL_OWNERS];\n ms.owners[SENTINEL_OWNERS] = _newOwner;\n ++ms.ownerCount;\n emit OwnerAdded(_newOwner);\n\n if (ms.threshold != _threshold) changeThreshold(_threshold);\n }\n\n /**\n * @notice Remove owner from Barz. Update thresold if threshold is given different from current threshold\n * @dev This can only be done via a Self call.\n * @param _prevOwner Address of owner located right behind the removed owner address in the linked list\n * @param _removedOwner Address of owner to be removed\n * @param _threshold Uint256 value of threshold\n */\n function removeOwner(\n address _prevOwner,\n address _removedOwner,\n uint256 _threshold\n ) external {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (ms.ownerCount - 1 < _threshold)\n revert MultiSigFacet__InvalidThreshold();\n if (_removedOwner == address(0) || _removedOwner == SENTINEL_OWNERS)\n revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_prevOwner] != _removedOwner)\n revert MultiSigFacet__InvalidOwnerPair();\n\n ms.owners[_prevOwner] = ms.owners[_removedOwner];\n ms.owners[_removedOwner] = address(0);\n --ms.ownerCount;\n emit OwnerRemoved(_removedOwner);\n\n if (ms.threshold != _threshold) changeThreshold(_threshold);\n }\n\n /**\n * @notice Swap owner in Barz.\n * @dev This can only be done via a Self call.\n * @param _prevOwner Address of owner located right behind the removed owner address in the linked list\n * @param _oldOwner Address of owner to be removed\n * @param _newOwner Address of owner to be added\n */\n function swapOwner(\n address _prevOwner,\n address _oldOwner,\n address _newOwner\n ) public {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (\n _newOwner == address(0) ||\n _newOwner == SENTINEL_OWNERS ||\n _newOwner == address(this)\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_newOwner] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n if (_oldOwner == address(0) || _oldOwner == SENTINEL_OWNERS)\n revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_prevOwner] != _oldOwner)\n revert MultiSigFacet__InvalidOwnerPair();\n\n ms.owners[_newOwner] = ms.owners[_oldOwner];\n ms.owners[_prevOwner] = _newOwner;\n ms.owners[_oldOwner] = address(0);\n emit OwnerRemoved(_oldOwner);\n emit OwnerAdded(_newOwner);\n }\n\n /**\n * @notice Changes the threshold of the Barz to `_threshold`.\n * @dev This can only be done via a Self call.\n * @param _threshold New threshold\n */\n function changeThreshold(uint256 _threshold) public {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (_threshold > ms.ownerCount || _threshold == 0)\n revert MultiSigFacet__InvalidThreshold();\n\n ms.threshold = _threshold;\n emit ThresholdChanged(_threshold);\n }\n\n /**\n * @notice Checks if the given address is owner\n * @param _owner Address to be checked if it's owner\n * @return isOwner_ Bool value showing if it's owner address\n */\n function isOwner(address _owner) public view returns (bool isOwner_) {\n isOwner_ = (_owner != SENTINEL_OWNERS &&\n LibMultiSigStorage.multisigStorage().owners[_owner] != address(0));\n }\n\n /**\n * @notice Returns the threshold of Barz\n * @return threshold Threshold of the Barz account\n */\n function getThreshold() public view returns (uint256 threshold) {\n threshold = LibMultiSigStorage.multisigStorage().threshold;\n }\n\n /**\n * @notice Returns the list of owner addresses\n * @return owners List of owners\n */\n function getOwners() public view returns (address[] memory owners) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n owners = new address[](ms.ownerCount);\n\n uint256 index;\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n while (currentOwner != SENTINEL_OWNERS) {\n owners[index] = currentOwner;\n currentOwner = ms.owners[currentOwner];\n index++;\n }\n }\n\n /**\n * @notice Returns the previous owner in the linked list\n * @param _owner Address of owner\n * @return prevOwner Address of previous owner\n */\n function getPrevOwner(\n address _owner\n ) public view returns (address prevOwner) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n if (currentOwner == _owner) return SENTINEL_OWNERS;\n while (currentOwner != SENTINEL_OWNERS) {\n if (ms.owners[currentOwner] == _owner) return currentOwner;\n\n currentOwner = ms.owners[currentOwner];\n }\n return address(0);\n }\n\n /**\n * @notice Returns of the owner is approved by given owner address\n * @param _owner Address of owner\n * @param _hash Hash of UserOperation\n * @return isApproved Bool value showing if the hash is approved by owner\n */\n function isApprovedHash(\n address _owner,\n bytes32 _hash\n ) public view returns (bool isApproved) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n isApproved = (ms.approvedHashes[ms.counter][_owner][_hash] == 1);\n }\n}\n" + }, + "contracts/facets/verification/secp256k1/Secp256k1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {UserOperation} from \"../../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibAppStorage} from \"../../../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, Secp256k1VerificationStorage} from \"../../../libraries/LibFacetStorage.sol\";\nimport {LibLoupe} from \"../../../libraries/LibLoupe.sol\";\nimport {IERC1271} from \"../../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../../interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Secp256k1 verification facet\n * @dev Default Ethereum's elliptic curve\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract Secp256k1VerificationFacet is IVerificationFacet, IERC1271 {\n using ECDSA for bytes32;\n error Secp256k1VerificationFacet__InvalidSignerLength();\n address public immutable self;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in K1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\n * @param _publicKey Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _publicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n if (!isValidKeyType(_publicKey))\n revert Secp256k1VerificationFacet__InvalidSignerLength();\n\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(uint160(uint256(keccak256(_publicKey[1:]))));\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_publicKey);\n }\n\n /**\n * @notice Uninitialize signer in K1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\n * signer public key.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n validationData = validateSignature(\n userOp,\n userOpHash,\n k1Storage.signer\n );\n }\n\n /**\n * @notice Validates if the signature of UserOperation is signed by the given signer\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @param signer Address of signer who signed the contract, to be validated\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n address signer\n ) public pure returns (uint256 isValid) {\n bytes32 hash = userOpHash.toEthSignedMessageHash();\n isValid = (signer != hash.recover(userOp.signature)) ? 1 : 0;\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n ownerSignatureValidatorSelector = this.validateOwnerSignature.selector;\n // NOTE: The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory signer) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n signer = abi.encodePacked(k1Storage.signer);\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key length should be 65 in an uncompressed public key format\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (_hash.recover(_signature) ==\n LibFacetStorage.k1Storage().signer)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/Secp256r1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {UserOperation} from \"../../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibAppStorage} from \"../../../libraries/LibAppStorage.sol\";\nimport {LibLoupe} from \"../../../libraries/LibLoupe.sol\";\nimport {LibFacetStorage, Secp256r1VerificationStorage} from \"../../../libraries/LibFacetStorage.sol\";\nimport {Base64} from \"./utils/Base64.sol\";\nimport {LibSecp256r1} from \"./utils/LibSecp256r1.sol\";\nimport {IERC1271} from \"../../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../../interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Secp256r1 verification facet\n * @dev Primarily used to verify user ops signed with passkeys\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract Secp256r1VerificationFacet is IVerificationFacet, IERC1271 {\n error Secp256r1VerificationFacet__InvalidSignerLength();\n address public immutable self;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in R1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\n * @param _publicKey Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _publicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n\n if (!isValidKeyType(_publicKey))\n revert Secp256r1VerificationFacet__InvalidSignerLength();\n\n bytes memory publicKeyCoordinates = _publicKey[1:];\n uint256[2] memory q;\n assembly {\n // Copy the bytes from the input data into the uint256 array\n mstore(q, mload(add(publicKeyCoordinates, 32)))\n mstore(add(q, 32), mload(add(publicKeyCoordinates, 64)))\n }\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n r1Storage.q = q;\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_publicKey);\n }\n\n /**\n * @notice Uninitialize signer in R1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n r1Storage.q = [0, 0];\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\n * signer public key.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n validationData = validateSignature(userOp, userOpHash, r1Storage.q);\n }\n\n /**\n * @notice Validates if the signature of UserOperation is signed by the given signer\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @param q Public Key of signer who signed the contract, to be validated\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256[2] memory q\n ) public view returns (uint256 isValid) {\n isValid = (_validateSignature(q, userOpHash, userOp.signature)) ? 0 : 1;\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n return this.validateOwnerSignature.selector; // validateOwnerSignature(UserOperation calldata userOp,bytes32 userOpHash)\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory signer) {\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n signer = abi.encodePacked(r1Storage.q);\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key should in an uncompressed public key format\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = _validateSignature(\n LibFacetStorage.r1Storage().q,\n _hash,\n _signature\n )\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n\n function _validateSignature(\n uint256[2] memory q,\n bytes32 _hash,\n bytes memory _signature\n ) internal view returns (bool) {\n (\n uint256 rValue,\n uint256 sValue,\n bytes memory authenticatorData,\n string memory clientDataJSONPre,\n string memory clientDataJSONPost\n ) = abi.decode(_signature, (uint256, uint256, bytes, string, string));\n bytes32 clientHash;\n {\n string memory opHashBase64 = Base64.encode(bytes.concat(_hash));\n string memory clientDataJSON = string.concat(\n clientDataJSONPre,\n opHashBase64,\n clientDataJSONPost\n );\n clientHash = sha256(bytes(clientDataJSON));\n }\n bytes32 sigHash = sha256(bytes.concat(authenticatorData, clientHash));\n return LibSecp256r1.Verify(q, rValue, sValue, uint256(sigHash));\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/utils/Base64.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @dev Provides a set of functions to operate with Base64 strings.\n * modified for base64url https://datatracker.ietf.org/doc/html/rfc4648#section-5\n * _Available since v4.5._\n */\nlibrary Base64 {\n /**\n * @dev Base64 Encoding/Decoding Table\n */\n string internal constant _TABLE =\n \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_\";\n\n /**\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\n */\n function encode(bytes memory data) internal pure returns (string memory) {\n /**\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\n */\n if (data.length == 0) return \"\";\n\n // Loads the table into memory\n string memory table = _TABLE;\n\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\n // and split into 4 numbers of 6 bits.\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\n // - `data.length + 2` -> Round up\n // - `/ 3` -> Number of 3-bytes chunks\n // - `4 *` -> 4 characters for each chunk\n uint256 newlength = (data.length * 8) / 6;\n if (data.length % 6 > 0) {\n newlength++;\n }\n string memory result = new string(newlength);\n\n /// @solidity memory-safe-assembly\n assembly {\n // Prepare the lookup table (skip the first \"length\" byte)\n let tablePtr := add(table, 1)\n\n // Prepare result pointer, jump over length\n let resultPtr := add(result, 32)\n\n // Run over the input, 3 bytes at a time\n for {\n let dataPtr := data\n let endPtr := add(data, mload(data))\n } lt(dataPtr, endPtr) {\n\n } {\n // Advance 3 bytes\n dataPtr := add(dataPtr, 3)\n let input := mload(dataPtr)\n\n // To write each character, shift the 3 bytes (18 bits) chunk\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\n // and apply logical AND with 0x3F which is the number of\n // the previous character in the ASCII table prior to the Base64 Table\n // The result is then added to the table to get the character to write,\n // and finally write it in the result pointer but with a left shift\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(18, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(12, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(6, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n }\n }\n\n return result;\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/utils/LibSecp256r1.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n// Heavily inspired from\n// https://github.com/maxrobot/elliptic-solidity/blob/master/contracts/Secp256r1.sol\n// https://github.com/tdrerup/elliptic-curve-solidity/blob/master/contracts/curves/EllipticCurve.sol\n// modified to use precompile 0x05 modexp\n// and modified jacobian double\n// optimisations to avoid to an from from affine and jacobian coordinates\n\n// Additional Elliptic curve Public key / Signature validation added by\n// David Yonjun Kim (@Powerstream3604)\n\nstruct JPoint {\n uint256 x;\n uint256 y;\n uint256 z;\n}\n\nlibrary LibSecp256r1 {\n uint256 constant gx =\n 0x6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296;\n uint256 constant gy =\n 0x4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5;\n uint256 public constant pp =\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF;\n\n uint256 public constant nn =\n 0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551;\n uint256 constant a =\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC;\n uint256 constant b =\n 0x5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B;\n uint256 constant MOST_SIGNIFICANT =\n 0xc000000000000000000000000000000000000000000000000000000000000000;\n\n /*\n * Verify\n * @description - verifies that a public key has signed a given message\n * @param Q - public key coordinates X & Y\n * @param R - signature half R\n * @param S - signature half S\n * @param input - hashed message\n */\n function Verify(\n uint256[2] memory q,\n uint r,\n uint s,\n uint e\n ) internal view returns (bool) {\n if (q[0] > pp - 1 || q[1] > pp - 1) {\n return false;\n }\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\n return false;\n }\n if (\n mulmod(q[1], q[1], pp) !=\n addmod(\n addmod(\n mulmod(q[0], mulmod(q[0], q[0], pp), pp),\n mulmod(a, q[0], pp),\n pp\n ),\n b,\n pp\n )\n ) {\n return false;\n }\n\n JPoint[16] memory points = _preComputeJacobianPoints(q);\n return VerifyWithPrecompute(points, r, s, e);\n }\n\n function VerifyWithPrecompute(\n JPoint[16] memory points,\n uint r,\n uint s,\n uint e\n ) internal view returns (bool) {\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\n return false;\n }\n\n uint w = _primemod(s, nn);\n\n uint u1 = mulmod(e, w, nn);\n uint u2 = mulmod(r, w, nn);\n\n uint x;\n uint y;\n\n (x, y) = ShamirMultJacobian(points, u1, u2);\n return (x == r);\n }\n\n /*\n * Strauss Shamir trick for EC multiplication\n * https://stackoverflow.com/questions/50993471/ec-scalar-multiplication-with-strauss-shamir-method\n * we optimise on this a bit to do with 2 bits at a time rather than a single bit\n * the individual points for a single pass are precomputed\n * overall this reduces the number of additions while keeping the same number of doublings\n */\n function ShamirMultJacobian(\n JPoint[16] memory points,\n uint u1,\n uint u2\n ) internal view returns (uint, uint) {\n uint x = 0;\n uint y = 0;\n uint z = 0;\n uint bits = 128;\n uint index = 0;\n\n while (bits > 0) {\n if (z > 0) {\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\n }\n index =\n ((u1 & MOST_SIGNIFICANT) >> 252) |\n ((u2 & MOST_SIGNIFICANT) >> 254);\n if (index > 0) {\n (x, y, z) = _jAdd(\n x,\n y,\n z,\n points[index].x,\n points[index].y,\n points[index].z\n );\n }\n u1 <<= 2;\n u2 <<= 2;\n bits--;\n }\n (x, y) = _affineFromJacobian(x, y, z);\n return (x, y);\n }\n\n function _preComputeJacobianPoints(\n uint256[2] memory q\n ) internal pure returns (JPoint[16] memory points) {\n points[0] = JPoint(0, 0, 0);\n points[1] = JPoint(q[0], q[1], 1); // u2\n points[2] = _jPointDouble(points[1]);\n points[3] = _jPointAdd(points[1], points[2]);\n\n points[4] = JPoint(gx, gy, 1); // u1Points[1]\n points[5] = _jPointAdd(points[4], points[1]);\n points[6] = _jPointAdd(points[4], points[2]);\n points[7] = _jPointAdd(points[4], points[3]);\n\n points[8] = _jPointDouble(points[4]); // u1Points[2]\n points[9] = _jPointAdd(points[8], points[1]);\n points[10] = _jPointAdd(points[8], points[2]);\n points[11] = _jPointAdd(points[8], points[3]);\n\n points[12] = _jPointAdd(points[4], points[8]); // u1Points[3]\n points[13] = _jPointAdd(points[12], points[1]);\n points[14] = _jPointAdd(points[12], points[2]);\n points[15] = _jPointAdd(points[12], points[3]);\n }\n\n function _jPointAdd(\n JPoint memory p1,\n JPoint memory p2\n ) internal pure returns (JPoint memory) {\n uint x;\n uint y;\n uint z;\n (x, y, z) = _jAdd(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z);\n return JPoint(x, y, z);\n }\n\n function _jPointDouble(\n JPoint memory p\n ) internal pure returns (JPoint memory) {\n uint x;\n uint y;\n uint z;\n (x, y, z) = _modifiedJacobianDouble(p.x, p.y, p.z);\n return JPoint(x, y, z);\n }\n\n /* _affineFromJacobian\n * @desription returns affine coordinates from a jacobian input follows\n * golang elliptic/crypto library\n */\n function _affineFromJacobian(\n uint x,\n uint y,\n uint z\n ) internal view returns (uint ax, uint ay) {\n if (z == 0) {\n return (0, 0);\n }\n\n uint zinv = _primemod(z, pp);\n uint zinvsq = mulmod(zinv, zinv, pp);\n\n ax = mulmod(x, zinvsq, pp);\n ay = mulmod(y, mulmod(zinvsq, zinv, pp), pp);\n }\n\n /*\n * _jAdd\n * @description performs Jacobian addition as defined below:\n * http://www.hyperelliptic.org/EFD/g1p/data/shortw/jacobian/addition/add-2007-bl\n */\n function _jAdd(\n uint p1,\n uint p2,\n uint p3,\n uint q1,\n uint q2,\n uint q3\n ) internal pure returns (uint r1, uint r2, uint r3) {\n if (p3 == 0) {\n r1 = q1;\n r2 = q2;\n r3 = q3;\n\n return (r1, r2, r3);\n } else if (q3 == 0) {\n r1 = p1;\n r2 = p2;\n r3 = p3;\n\n return (r1, r2, r3);\n }\n\n assembly {\n let\n pd\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\n let z1z1 := mulmod(p3, p3, pd) // Z1Z1 = Z1^2\n let z2z2 := mulmod(q3, q3, pd) // Z2Z2 = Z2^2\n\n let u1 := mulmod(p1, z2z2, pd) // U1 = X1*Z2Z2\n let u2 := mulmod(q1, z1z1, pd) // U2 = X2*Z1Z1\n\n let s1 := mulmod(p2, mulmod(z2z2, q3, pd), pd) // S1 = Y1*Z2*Z2Z2\n let s2 := mulmod(q2, mulmod(z1z1, p3, pd), pd) // S2 = Y2*Z1*Z1Z1\n\n let p3q3 := addmod(p3, q3, pd)\n\n if lt(u2, u1) {\n u2 := add(pd, u2) // u2 = u2+pd\n }\n let h := sub(u2, u1) // H = U2-U1\n\n let i := mulmod(0x02, h, pd)\n i := mulmod(i, i, pd) // I = (2*H)^2\n\n let j := mulmod(h, i, pd) // J = H*I\n if lt(s2, s1) {\n s2 := add(pd, s2) // u2 = u2+pd\n }\n let rr := mulmod(0x02, sub(s2, s1), pd) // r = 2*(S2-S1)\n r1 := mulmod(rr, rr, pd) // X3 = R^2\n\n let v := mulmod(u1, i, pd) // V = U1*I\n let j2v := addmod(j, mulmod(0x02, v, pd), pd)\n if lt(r1, j2v) {\n r1 := add(pd, r1) // X3 = X3+pd\n }\n r1 := sub(r1, j2v)\n\n // Y3 = r*(V-X3)-2*S1*J\n let s12j := mulmod(mulmod(0x02, s1, pd), j, pd)\n\n if lt(v, r1) {\n v := add(pd, v)\n }\n r2 := mulmod(rr, sub(v, r1), pd)\n\n if lt(r2, s12j) {\n r2 := add(pd, r2)\n }\n r2 := sub(r2, s12j)\n\n // Z3 = ((Z1+Z2)^2-Z1Z1-Z2Z2)*H\n z1z1 := addmod(z1z1, z2z2, pd)\n j2v := mulmod(p3q3, p3q3, pd)\n if lt(j2v, z1z1) {\n j2v := add(pd, j2v)\n }\n r3 := mulmod(sub(j2v, z1z1), h, pd)\n }\n return (r1, r2, r3);\n }\n\n // Point doubling on the modified jacobian coordinates\n // http://point-at-infinity.org/ecc/Prime_Curve_Modified_Jacobian_Coordinates.html\n function _modifiedJacobianDouble(\n uint x,\n uint y,\n uint z\n ) internal pure returns (uint x3, uint y3, uint z3) {\n if (y == 0) return (0, 0, 0);\n assembly {\n let\n pd\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\n let z2 := mulmod(z, z, pd)\n let az4 := mulmod(\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC,\n mulmod(z2, z2, pd),\n pd\n )\n let y2 := mulmod(y, y, pd)\n let s := mulmod(0x04, mulmod(x, y2, pd), pd)\n let u := mulmod(0x08, mulmod(y2, y2, pd), pd)\n let m := addmod(mulmod(0x03, mulmod(x, x, pd), pd), az4, pd)\n let twos := mulmod(0x02, s, pd)\n let m2 := mulmod(m, m, pd)\n if lt(m2, twos) {\n m2 := add(pd, m2)\n }\n x3 := sub(m2, twos)\n if lt(s, x3) {\n s := add(pd, s)\n }\n y3 := mulmod(m, sub(s, x3), pd)\n if lt(y3, u) {\n y3 := add(pd, y3)\n }\n y3 := sub(y3, u)\n z3 := mulmod(0x02, mulmod(y, z, pd), pd)\n }\n }\n\n // Fermats little theorem https://en.wikipedia.org/wiki/Fermat%27s_little_theorem\n // a^(p-1) = 1 mod p\n // a^(-1) ≅ a^(p-2) (mod p)\n // we then use the precompile bigModExp to compute a^(-1)\n function _primemod(uint value, uint p) internal view returns (uint ret) {\n ret = modexp(value, p - 2, p);\n return ret;\n }\n\n // Wrapper for built-in BigNumber_modexp (contract 0x5) as described here. https://github.com/ethereum/EIPs/pull/198\n function modexp(\n uint _base,\n uint _exp,\n uint _mod\n ) internal view returns (uint ret) {\n // bigModExp(_base, _exp, _mod);\n assembly {\n if gt(_base, _mod) {\n _base := mod(_base, _mod)\n }\n // Free memory pointer is always stored at 0x40\n let freemem := mload(0x40)\n\n mstore(freemem, 0x20)\n mstore(add(freemem, 0x20), 0x20)\n mstore(add(freemem, 0x40), 0x20)\n\n mstore(add(freemem, 0x60), _base)\n mstore(add(freemem, 0x80), _exp)\n mstore(add(freemem, 0xa0), _mod)\n\n let success := staticcall(14000, 0x5, freemem, 0xc0, freemem, 0x20)\n switch success\n case 0 {\n revert(0x0, 0x0)\n }\n default {\n ret := mload(freemem)\n }\n }\n }\n}\n" + }, + "contracts/infrastructure/DefaultFallbackHandler.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC1155Receiver} from \"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\";\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {BaseAccount} from \"../aa-4337/core/BaseAccount.sol\";\nimport {DefaultLibDiamond} from \"../libraries/DefaultLibDiamond.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IAccountFacet} from \"../facets/interfaces/IAccountFacet.sol\";\nimport {IStorageLoupe} from \"../facets/base/interfaces/IStorageLoupe.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IERC677Receiver} from \"../interfaces/ERC/IERC677Receiver.sol\";\nimport {IERC165} from \"../interfaces/ERC/IERC165.sol\";\n\n/**\n * @title DefaultFallbackHandler\n * @dev A default fallback handler for Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DefaultFallbackHandler is IDiamondLoupe {\n /**\n * @notice Sets the middleware diamond for Barz wallet as a fallback handler\n * @dev This contract is also a diamond that holds the default facets to reduce gas cost for wallet activation.\n * Within the constructor this conducts diamond cut to initially setup the diamond. This is a non-upgradeable contract\n * @param _diamondCutFacet Address if diamond cut facet\n * @param _accountFacet Address account facet\n * @param _tokenReceiverFacet Address of token receiver facet\n * @param _diamondLoupeFacet Address of diamond loupe facet\n */\n constructor(\n address _diamondCutFacet,\n address _accountFacet,\n address _tokenReceiverFacet,\n address _diamondLoupeFacet\n ) payable {\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](4);\n bytes4[] memory functionSelectors = new bytes4[](1);\n functionSelectors[0] = IDiamondCut.diamondCut.selector;\n\n bytes4[] memory accountFunctionSelectors = new bytes4[](5);\n accountFunctionSelectors[0] = IAccountFacet.execute.selector;\n accountFunctionSelectors[1] = IAccountFacet.executeBatch.selector;\n accountFunctionSelectors[2] = BaseAccount.validateUserOp.selector;\n accountFunctionSelectors[3] = BaseAccount.getNonce.selector;\n accountFunctionSelectors[4] = BaseAccount.entryPoint.selector;\n\n bytes4[] memory receiverFacetSelectors = new bytes4[](5);\n receiverFacetSelectors[0] = IERC721Receiver.onERC721Received.selector;\n receiverFacetSelectors[1] = IERC1155Receiver.onERC1155Received.selector;\n receiverFacetSelectors[2] = IERC1155Receiver\n .onERC1155BatchReceived\n .selector;\n receiverFacetSelectors[3] = IERC777Recipient.tokensReceived.selector;\n receiverFacetSelectors[4] = IERC677Receiver.onTokenTransfer.selector;\n\n bytes4[] memory loupeFacetSelectors = new bytes4[](9);\n loupeFacetSelectors[0] = IDiamondLoupe.facets.selector;\n loupeFacetSelectors[1] = IDiamondLoupe.facetFunctionSelectors.selector;\n loupeFacetSelectors[2] = IDiamondLoupe.facetAddresses.selector;\n loupeFacetSelectors[3] = IDiamondLoupe.facetAddress.selector;\n loupeFacetSelectors[4] = IERC165.supportsInterface.selector;\n loupeFacetSelectors[5] = IStorageLoupe.facetsFromStorage.selector;\n loupeFacetSelectors[6] = IStorageLoupe\n .facetFunctionSelectorsFromStorage\n .selector;\n loupeFacetSelectors[7] = IStorageLoupe\n .facetAddressesFromStorage\n .selector;\n loupeFacetSelectors[8] = IStorageLoupe.facetAddressFromStorage.selector;\n\n {\n cut[0] = IDiamondCut.FacetCut({\n facetAddress: _diamondCutFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: functionSelectors\n });\n cut[1] = IDiamondCut.FacetCut({\n facetAddress: _accountFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: accountFunctionSelectors\n });\n cut[2] = IDiamondCut.FacetCut({\n facetAddress: _tokenReceiverFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: receiverFacetSelectors\n });\n cut[3] = IDiamondCut.FacetCut({\n facetAddress: _diamondLoupeFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: loupeFacetSelectors\n });\n\n DefaultLibDiamond.diamondCut(cut, address(0), \"\");\n }\n }\n\n /**\n * @notice Returns the facet information of call facets registered to this diamond.\n * @return facets_ The facet struct array including all facet information\n */\n function facets() external view override returns (Facet[] memory facets_) {\n DefaultLibDiamond.DiamondStorage storage ds = DefaultLibDiamond\n .diamondStorage();\n uint256 numFacets = ds.facetAddresses.length;\n facets_ = new Facet[](numFacets);\n for (uint256 i; i < numFacets; ) {\n address facetAddress_ = ds.facetAddresses[i];\n facets_[i].facetAddress = facetAddress_;\n facets_[i].functionSelectors = ds\n .facetFunctionSelectors[facetAddress_]\n .functionSelectors;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Gets all the function selectors provided by a facet.\n * @param _facet The facet address.\n * @return facetFunctionSelectors_\n */\n function facetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n facetFunctionSelectors_ = DefaultLibDiamond\n .diamondStorage()\n .facetFunctionSelectors[_facet]\n .functionSelectors;\n }\n\n /**\n * @notice Get all the facet addresses used by a diamond.\n * @return facetAddresses_\n */\n function facetAddresses()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n facetAddresses_ = DefaultLibDiamond.diamondStorage().facetAddresses;\n }\n\n /** @notice Gets the facet that supports the given selector.\n * @dev If facet is not found return address(0).\n * @param _functionSelector The function selector.\n * @return facetAddress_ The facet address.\n */\n function facetAddress(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n facetAddress_ = DefaultLibDiamond\n .diamondStorage()\n .selectorToFacetAndPosition[_functionSelector]\n .facetAddress;\n }\n}\n" + }, + "contracts/infrastructure/FacetRegistry.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport {IFacetRegistry} from \"./interfaces/IFacetRegistry.sol\";\n\n/**\n * @title Facet Registry\n * @dev Contract to keep track of facets & function selectors addable to user wallets\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract FacetRegistry is IFacetRegistry, Ownable2Step {\n mapping(address => FacetRegistryConfig) private facets;\n\n /**\n * @notice Transfers the ownership of the contract to the given owner\n * @param _owner Address of owner who has access to initialize the default security variables for security manager\n */\n constructor(address _owner) {\n transferOwnership(_owner);\n _transferOwnership(_owner);\n }\n\n /**\n * @dev Registers a facet and it's function selectors to registry\n * @param _facet address of facet\n * @param _facetSelectors list of function selectors of the facet\n */\n function registerFacetFunctionSelectors(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external override onlyOwner {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n for (uint256 i; i < _facetSelectors.length; ) {\n if (facetConfig.info[_facetSelectors[i]].exists)\n revert FacetRegistry__FacetSelectorAlreadyRegistered();\n\n facetConfig.info[_facetSelectors[i]].exists = true;\n facetConfig.info[_facetSelectors[i]].index = uint128(\n facetConfig.selectors.length\n );\n facetConfig.selectors.push(_facetSelectors[i]);\n unchecked {\n ++i;\n }\n }\n emit FacetFunctionSelectorsRegistered(_facet, _facetSelectors);\n }\n\n /**\n * @dev Removes a registered facet and it's corresponding selectors from registry\n * @param _facet address of facet\n * @param _facetSelectors list of function selectors of the facet\n */\n function removeFacetFunctionSelectors(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external override onlyOwner {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n for (uint256 i; i < _facetSelectors.length; ) {\n if (!facetConfig.info[_facetSelectors[i]].exists)\n revert FacetRegistry__UnregisteredFacetSelector();\n\n bytes4 lastSelector = facetConfig.selectors[\n facetConfig.selectors.length - 1\n ];\n if (_facetSelectors[i] != lastSelector) {\n uint128 targetIndex = facetConfig\n .info[_facetSelectors[i]]\n .index;\n facetConfig.selectors[targetIndex] = lastSelector;\n facetConfig.info[lastSelector].index = targetIndex;\n }\n facetConfig.selectors.pop();\n delete facetConfig.info[_facetSelectors[i]];\n\n unchecked {\n ++i;\n }\n }\n emit FacetFunctionSelectorsRemoved(_facet, _facetSelectors);\n }\n\n /**\n * @dev Checks if a facet and it's selectors given is registered to facet registry\n * @param _facet Address of facet\n * @param _facetSelectors List of function selectors of the facet\n */\n function areFacetFunctionSelectorsRegistered(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external view override returns (bool) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n if (_facetSelectors.length == 0) return false;\n for (uint256 i; i < _facetSelectors.length; ) {\n if (!facetConfig.info[_facetSelectors[i]].exists) return false;\n unchecked {\n ++i;\n }\n }\n return true;\n }\n\n /**\n * @dev Checks if a facet and it's selector given is registered to facet registry\n * @param _facet Address of facet\n * @param _facetSelector List of function selectors of the facet\n * @return isRegistered Bool value showing if the selector is registered\n */\n function isFacetFunctionSelectorRegistered(\n address _facet,\n bytes4 _facetSelector\n ) external view override returns (bool isRegistered) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n isRegistered = facetConfig.info[_facetSelector].exists;\n }\n\n /**\n * @dev Get the registered selectors of facet from registry\n * @param _facet Address of facet\n * @return selectors Selectors registered to facet\n */\n function getFacetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory selectors) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n selectors = facetConfig.selectors;\n }\n}\n" + }, + "contracts/infrastructure/interfaces/IFacetRegistry.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Registry Interface\n * @dev Interface for Facet Registry contract to keep track of facets & function selectors addable to user wallets\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IFacetRegistry {\n struct FacetRegistryConfig {\n bytes4[] selectors;\n mapping(bytes4 => FacetInfo) info;\n }\n struct FacetInfo {\n bool exists;\n uint128 index;\n }\n\n event FacetFunctionSelectorsRegistered(\n address facet,\n bytes4[] facetSelectors\n );\n event FacetFunctionSelectorsRemoved(address facet, bytes4[] facetSelectors);\n\n error FacetRegistry__FacetSelectorAlreadyRegistered();\n error FacetRegistry__UnregisteredFacetSelector();\n\n function registerFacetFunctionSelectors(\n address facet,\n bytes4[] calldata facetSelectors\n ) external;\n\n function removeFacetFunctionSelectors(\n address facet,\n bytes4[] calldata facetSelectors\n ) external;\n\n function areFacetFunctionSelectorsRegistered(\n address facet,\n bytes4[] calldata facetSelectors\n ) external view returns (bool);\n\n function isFacetFunctionSelectorRegistered(\n address facet,\n bytes4 facetSelector\n ) external view returns (bool);\n\n function getFacetFunctionSelectors(\n address facet\n ) external view returns (bytes4[] memory);\n}\n" + }, + "contracts/infrastructure/interfaces/ISecurityManager.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Registry Interface\n * @dev Infrastructure contract to manage security parameters of users\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface ISecurityManager {\n error SecurityManager__OutOfBoundary();\n error SecurityManager__CallerNotWallet();\n error SecurityManager__AlreadyIntialized();\n\n function initializeAdditionSecurityPeriod(\n uint128 defaultAdditionSecurityPeriod,\n uint128 minAdditionSecurityPeriod,\n uint128 maxAdditionSecurityPeriod\n ) external;\n\n function initializeRemovalSecurityPeriod(\n uint128 defaultRemovalSecurityPeriod,\n uint128 minRemovalSecurityPeriod,\n uint128 maxRemovalSecurityPeriod\n ) external;\n\n function initializeApprovalValidationPeriod(\n uint128 defaultApprovalValidationPeriod,\n uint128 minApprovalValidationPeriod,\n uint128 maxApprovalValidationPeriod\n ) external;\n\n function initializeMigrationPeriod(\n uint128 defaultMigrationPeriod,\n uint128 minMigrationPeriod,\n uint128 maxMigrationPeriod\n ) external;\n\n function initializeLockPeriod(\n uint128 defaultLockPeriod,\n uint128 minLockPeriod,\n uint128 maxLockPeriod\n ) external;\n\n function initializeRecoveryPeriod(\n uint128 defaultRecoveryPeriod,\n uint128 minRecoveryPeriod,\n uint128 maxRecoveryPeriod\n ) external;\n\n function initializeSecurityWindow(\n uint128 defaultSecurityWindow,\n uint128 minSecurityWindow,\n uint128 maxSecurityWindow\n ) external;\n\n function setAdditionSecurityPeriod(\n address wallet,\n uint128 additionSecurityPeriod\n ) external;\n\n function setRemovalSecurityPeriod(\n address wallet,\n uint128 removalSecurityPeriod\n ) external;\n\n function setSecurityWindow(address wallet, uint128 securityWindow) external;\n\n function setRecoveryPeriod(address wallet, uint128 recoveryPeriod) external;\n\n function setLockPeriod(address wallet, uint128 lockPeriod) external;\n\n function setApprovalValidationPeriod(\n address wallet,\n uint128 approvalValidationPeriod\n ) external;\n\n function setMigrationPeriod(\n address wallet,\n uint128 migrationPeriod\n ) external;\n\n function additionSecurityPeriodOf(\n address wallet\n ) external view returns (uint128);\n\n function removalSecurityPeriodOf(\n address wallet\n ) external view returns (uint128);\n\n function securityWindowOf(address wallet) external view returns (uint128);\n\n function recoveryPeriodOf(address wallet) external view returns (uint128);\n\n function lockPeriodOf(address wallet) external view returns (uint128);\n\n function migrationPeriodOf(address wallet) external view returns (uint128);\n\n function approvalValidationPeriodOf(\n address wallet\n ) external view returns (uint128);\n}\n" + }, + "contracts/infrastructure/RemoteStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IGuardianFacet} from \"../facets/interfaces/IGuardianFacet.sol\";\n\n/**\n * @title Remote Storage\n * @dev Remote storage allows you to associate addresses with an array of addresses on a standalone smart contract.\n * This could be useful when you don't want to use the local diamond storage for some purpose.\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\nabstract contract RemoteStorage {\n struct StorageConfig {\n address[] addresses;\n mapping(address => Info) info;\n }\n\n struct Info {\n bool exists;\n uint128 index;\n }\n\n mapping(address => StorageConfig) internal configs;\n\n event Added(address _address);\n event Removed(address _address);\n\n error RemoteStorage__CallerNotOwner();\n error RemoteStorage__CallerNotGuardianOrOwner();\n error RemoteStorage__AlreadyExists();\n error RemoteStorage__NotFound();\n error RemoteStorage__CallerNotGuardian();\n\n bytes4 constant IS_GUARDIAN_SELECTOR =\n bytes4(keccak256(\"isGuardian(address)\"));\n bytes4 constant GUARDIAN_COUNT = bytes4(keccak256(\"guardianCount()\"));\n\n /**\n * @notice Modifier to only allow the self to call. Reverts otherwise\n */\n modifier onlyWallet(address _wallet) {\n if (msg.sender != _wallet) revert RemoteStorage__CallerNotOwner();\n _;\n }\n\n /**\n * @notice Enfore the callet to be wallet of guardian of the wallet\n * @param _wallet Address of wallet\n */\n function enforceGuardianOrWallet(address _wallet) internal view {\n if (msg.sender == _wallet) return;\n address facetAddress = IDiamondLoupe(_wallet).facetAddress(\n IS_GUARDIAN_SELECTOR\n );\n if (facetAddress != address(0))\n if (IGuardianFacet(_wallet).isGuardian(msg.sender)) return;\n revert RemoteStorage__CallerNotGuardianOrOwner();\n }\n\n /**\n * @notice Enforce the caller to be wallet IF guardians doesn't exists and only guardian when guardians exists\n * @param _wallet Target wallet address to be handled by infrastructure contracts\n */\n function enforceWalletOrGuardianIfExists(address _wallet) internal view {\n address facetAddress;\n if (msg.sender == _wallet) {\n facetAddress = IDiamondLoupe(_wallet).facetAddress(GUARDIAN_COUNT);\n if (facetAddress == address(0)) return;\n uint256 guardianCount = IGuardianFacet(_wallet).guardianCount();\n if (guardianCount != 0) revert RemoteStorage__CallerNotGuardian();\n return;\n }\n facetAddress = IDiamondLoupe(_wallet).facetAddress(\n IS_GUARDIAN_SELECTOR\n );\n if (facetAddress != address(0))\n if (IGuardianFacet(_wallet).isGuardian(msg.sender)) return;\n\n revert RemoteStorage__CallerNotGuardianOrOwner();\n }\n\n /**\n * @notice Add address to storage and reverts if the address already exists.\n * This is an internal function callable from contracts that inherit this abstract contract\n * @param _wallet Address of wallet to add the address\n * @param _address Address to be added to wallet\n */\n function addAddress(address _wallet, address _address) internal {\n StorageConfig storage config = configs[_wallet];\n if (config.info[_address].exists) revert RemoteStorage__AlreadyExists();\n\n config.info[_address].exists = true;\n config.info[_address].index = uint128(config.addresses.length);\n config.addresses.push(_address);\n\n emit Added(_address);\n }\n\n /**\n * @notice Remove address from storage and reverts if the address already exists.\n * This is an internal function callable from contracts that inherit this abstract contract\n * @param _wallet Address of wallet to remove the address\n * @param _address Address to be removed from wallet\n */\n function removeAddress(address _wallet, address _address) internal {\n StorageConfig storage config = configs[_wallet];\n if (!config.info[_address].exists) revert RemoteStorage__NotFound();\n\n address lastAddress = config.addresses[config.addresses.length - 1];\n if (_address != lastAddress) {\n uint128 targetIndex = config.info[_address].index;\n config.addresses[targetIndex] = lastAddress;\n config.info[lastAddress].index = targetIndex;\n }\n config.addresses.pop();\n delete config.info[_address];\n\n emit Removed(_address);\n }\n\n /**\n * @notice Returns the address added to the given wallet\n * @param _wallet Address of wallet to fetch the addresses added to it\n * @return addresses List of addresses added to the wallet\n */\n function getAddresses(\n address _wallet\n ) internal view returns (address[] memory addresses) {\n StorageConfig storage config = configs[_wallet];\n addresses = new address[](config.addresses.length);\n uint addressesLen = config.addresses.length;\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns bool value checking if the address exists in the given wallet address\n * @param _wallet Wallet address to check\n * @param _address Address to fetch if the address if added to given wallet\n * @return exists_ Bool value showing if the address exists in wallet\n */\n function exists(\n address _wallet,\n address _address\n ) internal view returns (bool exists_) {\n exists_ = configs[_wallet].info[_address].exists;\n }\n\n /**\n * @notice Returns the number of addresses added to the wallet\n * @param _wallet Address of wallet to check\n * @return count_ Number of addresses added to wallet\n */\n function count(address _wallet) internal view returns (uint256 count_) {\n count_ = configs[_wallet].addresses.length;\n }\n}\n" + }, + "contracts/infrastructure/SecurityManager.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport {ISecurityManager} from \"./interfaces/ISecurityManager.sol\";\n\n/**\n * @title Security Manager\n * @dev Infrastructure contract to manage security parameters of users\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract SecurityManager is ISecurityManager, Ownable2Step {\n uint128 public minAdditionSecurityPeriod;\n uint128 public maxAdditionSecurityPeriod;\n uint128 private defaultAdditionSecurityPeriod;\n\n uint128 public minRemovalSecurityPeriod;\n uint128 public maxRemovalSecurityPeriod;\n uint128 private defaultRemovalSecurityPeriod;\n\n uint128 public minSecurityWindow;\n uint128 public maxSecurityWindow;\n uint128 private defaultSecurityWindow;\n\n uint128 public minRecoveryPeriod;\n uint128 public maxRecoveryPeriod;\n uint128 private defaultRecoveryPeriod;\n\n uint128 public minLockPeriod;\n uint128 public maxLockPeriod;\n uint128 private defaultLockPeriod;\n\n uint128 public minApprovalValidationPeriod;\n uint128 public maxApprovalValidationPeriod;\n uint128 private defaultApprovalValidationPeriod;\n\n uint128 public minMigrationPeriod;\n uint128 public maxMigrationPeriod;\n uint128 private defaultMigrationPeriod;\n\n bool public _isAdditionSecurityPeriodInitialized;\n bool public _isRemovalSecurityPeriodInitialized;\n bool public _isSecurityWindowInitialized;\n bool public _isRecoveryPeriodInitialized;\n bool public _isLockPeriodInitialized;\n bool public _isApprovalValidationPeriodInitialized;\n bool public _isMigrationPeriodInitialized;\n\n mapping(address => CustomSecurityConfig) securityConfigs;\n\n struct CustomSecurityConfig {\n uint128 additionSecurityPeriod;\n uint128 removalSecurityPeriod;\n uint128 securityWindow;\n uint128 recoveryPeriod;\n uint128 lockPeriod;\n uint128 approvalValidationPeriod;\n uint128 migrationPeriod;\n }\n\n /**\n * @notice Modifier to only allow wallet itself to make a call to wallet\n */\n modifier onlyWallet(address _wallet) {\n if (msg.sender != _wallet) revert SecurityManager__CallerNotWallet();\n _;\n }\n\n /**\n * @notice Modifier to revert if the variable is already initialized\n */\n modifier initializer(bool _isInitialized) {\n if (_isInitialized) revert SecurityManager__AlreadyIntialized();\n _;\n }\n\n /**\n * @notice Transfers the ownership of the contract to the given owner\n * @param _owner Address of owner who has access to initialize the default security variables for security manager\n */\n constructor(address _owner) {\n transferOwnership(_owner);\n _transferOwnership(_owner);\n }\n\n /**\n * @notice Sets the initial default/min/max addition security period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultAdditionSecurityPeriod Default Addition Security Period for all Barz contracts\n * @param _minAdditionSecurityPeriod Minimum Addition Security Period for all Barz contracts\n * @param _maxAdditionSecurityPeriod Maximum Addition Security Period for all Barz contracts\n */\n function initializeAdditionSecurityPeriod(\n uint128 _defaultAdditionSecurityPeriod,\n uint128 _minAdditionSecurityPeriod,\n uint128 _maxAdditionSecurityPeriod\n )\n external\n override\n onlyOwner\n initializer(_isAdditionSecurityPeriodInitialized)\n {\n _isAdditionSecurityPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultAdditionSecurityPeriod,\n _minAdditionSecurityPeriod,\n _maxAdditionSecurityPeriod\n );\n defaultAdditionSecurityPeriod = _defaultAdditionSecurityPeriod;\n minAdditionSecurityPeriod = _minAdditionSecurityPeriod;\n maxAdditionSecurityPeriod = _maxAdditionSecurityPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max removal security period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultRemovalSecurityPeriod Default Removal Security Period for all Barz contracts\n * @param _minRemovalSecurityPeriod Minimum Removal Security Period for all Barz contracts\n * @param _maxRemovalSecurityPeriod Maximum Removal Security Period for all Barz contracts\n */\n function initializeRemovalSecurityPeriod(\n uint128 _defaultRemovalSecurityPeriod,\n uint128 _minRemovalSecurityPeriod,\n uint128 _maxRemovalSecurityPeriod\n )\n external\n override\n onlyOwner\n initializer(_isRemovalSecurityPeriodInitialized)\n {\n _isRemovalSecurityPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultRemovalSecurityPeriod,\n _minRemovalSecurityPeriod,\n _maxRemovalSecurityPeriod\n );\n defaultRemovalSecurityPeriod = _defaultRemovalSecurityPeriod;\n minRemovalSecurityPeriod = _minRemovalSecurityPeriod;\n maxRemovalSecurityPeriod = _maxRemovalSecurityPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/maxd security window for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultSecurityWindow Default Security Window for all Barz contracts\n * @param _minSecurityWindow Minimum Security Window for all Barz contracts\n * @param _maxSecurityWindow Maximum Security Window for all Barz contracts\n */\n function initializeSecurityWindow(\n uint128 _defaultSecurityWindow,\n uint128 _minSecurityWindow,\n uint128 _maxSecurityWindow\n ) external override onlyOwner initializer(_isSecurityWindowInitialized) {\n _isSecurityWindowInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultSecurityWindow,\n _minSecurityWindow,\n _maxSecurityWindow\n );\n defaultSecurityWindow = _defaultSecurityWindow;\n minSecurityWindow = _minSecurityWindow;\n maxSecurityWindow = _maxSecurityWindow;\n }\n\n /**\n * @notice Sets the initial default/min/max recovery period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultRecoveryPeriod Default Recovery Period for all Barz contracts\n * @param _minRecoveryPeriod Minimum Recovery Period for all Barz contracts\n * @param _maxRecoveryPeriod Maximum Recovery Period for all Barz contracts\n */\n function initializeRecoveryPeriod(\n uint128 _defaultRecoveryPeriod,\n uint128 _minRecoveryPeriod,\n uint128 _maxRecoveryPeriod\n ) external override onlyOwner initializer(_isRecoveryPeriodInitialized) {\n _isRecoveryPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultRecoveryPeriod,\n _minRecoveryPeriod,\n _maxRecoveryPeriod\n );\n defaultRecoveryPeriod = _defaultRecoveryPeriod;\n minRecoveryPeriod = _minRecoveryPeriod;\n maxRecoveryPeriod = _maxRecoveryPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max lock period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultLockPeriod Default Lock Period for all Barz contracts\n * @param _minLockPeriod Minimum Lock Period for all Barz contracts\n * @param _maxLockPeriod Maximum Lock Period for all Barz contracts\n */\n function initializeLockPeriod(\n uint128 _defaultLockPeriod,\n uint128 _minLockPeriod,\n uint128 _maxLockPeriod\n ) external override onlyOwner initializer(_isLockPeriodInitialized) {\n _isLockPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultLockPeriod,\n _minLockPeriod,\n _maxLockPeriod\n );\n defaultLockPeriod = _defaultLockPeriod;\n minLockPeriod = _minLockPeriod;\n maxLockPeriod = _maxLockPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max approval validation period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultApprovalValidationPeriod Default Approval Validation Period for all Barz contracts\n * @param _minApprovalValidationPeriod Minimum Approval Validation Period for all Barz contracts\n * @param _maxApprovalValidationPeriod Maximum Approval Validation Period for all Barz contracts\n */\n function initializeApprovalValidationPeriod(\n uint128 _defaultApprovalValidationPeriod,\n uint128 _minApprovalValidationPeriod,\n uint128 _maxApprovalValidationPeriod\n )\n external\n override\n onlyOwner\n initializer(_isApprovalValidationPeriodInitialized)\n {\n _isApprovalValidationPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultApprovalValidationPeriod,\n _minApprovalValidationPeriod,\n _maxApprovalValidationPeriod\n );\n defaultApprovalValidationPeriod = _defaultApprovalValidationPeriod;\n minApprovalValidationPeriod = _minApprovalValidationPeriod;\n maxApprovalValidationPeriod = _maxApprovalValidationPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max migration period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultMigrationPeriod Default Migration Period for all Barz contracts\n * @param _minMigrationPeriod Minimum Migration Period for all Barz contracts\n * @param _maxMigrationPeriod Maximum Migration Period for all Barz contracts\n */\n function initializeMigrationPeriod(\n uint128 _defaultMigrationPeriod,\n uint128 _minMigrationPeriod,\n uint128 _maxMigrationPeriod\n ) external override onlyOwner initializer(_isMigrationPeriodInitialized) {\n _isMigrationPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultMigrationPeriod,\n _minMigrationPeriod,\n _maxMigrationPeriod\n );\n defaultMigrationPeriod = _defaultMigrationPeriod;\n minMigrationPeriod = _minMigrationPeriod;\n maxMigrationPeriod = _maxMigrationPeriod;\n }\n\n /**\n * @notice Wallet owner sets the addition security period for the wallet. Only the owner of wallet can call this function.\n * The addition security period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _additionSecurityPeriod Custom Addition Security Period for the wallet\n */\n function setAdditionSecurityPeriod(\n address _wallet,\n uint128 _additionSecurityPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _additionSecurityPeriod,\n minAdditionSecurityPeriod,\n maxAdditionSecurityPeriod\n );\n securityConfigs[_wallet]\n .additionSecurityPeriod = _additionSecurityPeriod;\n }\n\n /**\n * @notice Wallet owner sets the removal security period for the wallet. Only the owner of wallet can call this function.\n * The removal security period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _removalSecurityPeriod Custom Removal Security Period for the wallet\n */\n function setRemovalSecurityPeriod(\n address _wallet,\n uint128 _removalSecurityPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _removalSecurityPeriod,\n minRemovalSecurityPeriod,\n maxRemovalSecurityPeriod\n );\n securityConfigs[_wallet].removalSecurityPeriod = _removalSecurityPeriod;\n }\n\n /**\n * @notice Wallet owner sets the security window for the wallet. Only the owner of wallet can call this function.\n * The security window should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _securityWindow Custom Security Window for the wallet\n */\n function setSecurityWindow(\n address _wallet,\n uint128 _securityWindow\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _securityWindow,\n minSecurityWindow,\n maxSecurityWindow\n );\n securityConfigs[_wallet].securityWindow = _securityWindow;\n }\n\n /**\n * @notice Wallet owner sets the recovery period for the wallet. Only the owner of wallet can call this function.\n * The recovery period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _recoveryPeriod Custom recovery period for the wallet\n */\n function setRecoveryPeriod(\n address _wallet,\n uint128 _recoveryPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _recoveryPeriod,\n minRecoveryPeriod,\n maxRecoveryPeriod\n );\n securityConfigs[_wallet].recoveryPeriod = _recoveryPeriod;\n }\n\n /**\n * @notice Wallet owner sets the lock period for the wallet. Only the owner of wallet can call this function.\n * The lock period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _lockPeriod Custom Lock period for the wallet\n */\n function setLockPeriod(\n address _wallet,\n uint128 _lockPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(_lockPeriod, minLockPeriod, maxLockPeriod);\n securityConfigs[_wallet].lockPeriod = _lockPeriod;\n }\n\n /**\n * @notice Wallet owner sets the approval validation period for the wallet. Only the owner of wallet can call this function.\n * The approval validation period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _approvalValidationPeriod Custom approval validation period for the wallet\n */\n function setApprovalValidationPeriod(\n address _wallet,\n uint128 _approvalValidationPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _approvalValidationPeriod,\n minApprovalValidationPeriod,\n maxApprovalValidationPeriod\n );\n securityConfigs[_wallet]\n .approvalValidationPeriod = _approvalValidationPeriod;\n }\n\n /**\n * @notice Wallet owner sets the migration period for the wallet. Only the owner of wallet can call this function.\n * The migration period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _migrationPeriod Custom migration period for the wallet\n */\n\n function setMigrationPeriod(\n address _wallet,\n uint128 _migrationPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _migrationPeriod,\n minMigrationPeriod,\n maxMigrationPeriod\n );\n securityConfigs[_wallet].migrationPeriod = _migrationPeriod;\n }\n\n /**\n * @notice Returns the addition security period. Returns default value when custom addition security period is not set\n * @param _wallet Address of wallet\n * @return additionSecurityPeriod Addition Security Period of the given Barz account or wallet\n */\n function additionSecurityPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 additionSecurityPeriod)\n {\n additionSecurityPeriod = securityConfigs[_wallet]\n .additionSecurityPeriod;\n additionSecurityPeriod = (additionSecurityPeriod == 0)\n ? defaultAdditionSecurityPeriod\n : additionSecurityPeriod;\n }\n\n /**\n * @notice Returns the removal security period. Returns default value when custom removal security period is not set\n * @param _wallet Address of wallet\n * @return removalSecurityPeriod Removal Security Period of the given Barz account or wallet\n */\n function removalSecurityPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 removalSecurityPeriod)\n {\n removalSecurityPeriod = securityConfigs[_wallet].removalSecurityPeriod;\n removalSecurityPeriod = (removalSecurityPeriod == 0)\n ? defaultRemovalSecurityPeriod\n : removalSecurityPeriod;\n }\n\n /**\n * @notice Returns the security window. Returns default value when custom security window is not set\n * @param _wallet Address of wallet\n * @return securityWindow Security window of the given Barz account or wallet\n */\n function securityWindowOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 securityWindow)\n {\n securityWindow = securityConfigs[_wallet].securityWindow;\n securityWindow = (securityWindow == 0)\n ? defaultSecurityWindow\n : securityWindow;\n }\n\n /**\n * @notice Returns the recovery period. Returns default value when custom recovery period is not set\n * @param _wallet Address of wallet\n * @return recoveryPeriod Recovery Period of the given Barz account or wallet\n */\n function recoveryPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 recoveryPeriod)\n {\n recoveryPeriod = securityConfigs[_wallet].recoveryPeriod;\n recoveryPeriod = (recoveryPeriod == 0)\n ? defaultRecoveryPeriod\n : recoveryPeriod;\n }\n\n /**\n * @notice Returns the lock period. Returns default value when custom lock period is not set\n * @param _wallet Address of wallet\n * @return lockPeriod Lock Period of the given Barz account or wallet\n */\n function lockPeriodOf(\n address _wallet\n ) public view override onlyWallet(_wallet) returns (uint128 lockPeriod) {\n lockPeriod = securityConfigs[_wallet].lockPeriod;\n lockPeriod = (lockPeriod == 0) ? defaultLockPeriod : lockPeriod;\n }\n\n /**\n * @notice Returns the approval validation period. Returns default value when custom approval validation period is not set\n * @param _wallet Address of wallet\n * @return approvalValidationPeriod Approval Validation Period of the given Barz account or wallet\n */\n function approvalValidationPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityConfigs[_wallet]\n .approvalValidationPeriod;\n approvalValidationPeriod = (approvalValidationPeriod == 0)\n ? defaultApprovalValidationPeriod\n : approvalValidationPeriod;\n }\n\n /**\n * @notice Returns the migration period. Returns default value when custom migration period is not set\n * @param _wallet Address of wallet\n * @return migrationPeriod Migration Period of the given Barz account or wallet\n */\n function migrationPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 migrationPeriod)\n {\n migrationPeriod = securityConfigs[_wallet].migrationPeriod;\n migrationPeriod = (migrationPeriod == 0)\n ? defaultMigrationPeriod\n : migrationPeriod;\n }\n\n /**\n * @notice Validates if the period is smaller than the max period or bigger than the min period\n * @param _period Period to be checked\n * @param _minPeriod Minimum period\n * @param _maxPeriod Maximum period\n */\n function _validatePeriodBoundaries(\n uint128 _period,\n uint128 _minPeriod,\n uint128 _maxPeriod\n ) internal pure {\n if (_period >= _maxPeriod || _period <= _minPeriod)\n revert SecurityManager__OutOfBoundary();\n }\n}\n" + }, + "contracts/infrastructure/WhitelistStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {RemoteStorage} from \"./RemoteStorage.sol\";\n\n/**\n * @title Whitelist storage\n * @dev Maps addresses to the corresponsing array of whitelisted addresses for each of them.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract WhitelistStorage is RemoteStorage {\n /**\n * @dev Add the address to the whitelist storage\n * @param _wallet User wallet\n * @param _address Address to be whitelisted\n */\n function whitelistAddress(address _wallet, address _address) external {\n enforceWalletOrGuardianIfExists(_wallet);\n addAddress(_wallet, _address);\n }\n\n /**\n * @dev Removes the address from the whitelist storage\n * @param _wallet User wallet\n * @param _address Address to be removed from the whitelist\n */\n function blacklistAddress(address _wallet, address _address) external {\n enforceGuardianOrWallet(_wallet);\n removeAddress(_wallet, _address);\n }\n\n /**\n * @dev Returns whether the address exists in the whitelist storage, associated with the wallet\n * @param _wallet User wallet\n * @param _address Address to be whitelisted\n */\n function isWhitelisted(\n address _wallet,\n address _address\n ) external view returns (bool) {\n return exists(_wallet, _address);\n }\n\n /**\n * @dev Returns all whitelisted addresses associated with the wallet\n * @param _wallet User wallet\n */\n function getWhitelistedAddresses(\n address _wallet\n ) external view returns (address[] memory) {\n return getAddresses(_wallet);\n }\n}\n" + }, + "contracts/interfaces/ERC/IERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\n\npragma solidity 0.8.21;\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155Receiver {\n /**\n * @dev Handles the receipt of a single ERC1155 token type. This function is\n * called at the end of a `safeTransferFrom` after the balance has been updated.\n *\n * NOTE: To accept the transfer, this must return\n * `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n * (i.e. 0xf23a6e61, or its own function selector).\n *\n * @param operator The address which initiated the transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param id The ID of the token being transferred\n * @param value The amount of tokens being transferred\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n ) external returns (bytes4);\n\n /**\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\n * is called at the end of a `safeBatchTransferFrom` after the balances have\n * been updated.\n *\n * NOTE: To accept the transfer(s), this must return\n * `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n * (i.e. 0xbc197c81, or its own function selector).\n *\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "contracts/interfaces/ERC/IERC1271.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\ninterface IERC1271 {\n function isValidSignature(\n bytes32 hash,\n bytes memory signature\n ) external view returns (bytes4);\n}\n" + }, + "contracts/interfaces/ERC/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\ninterface IERC165 {\n /// @notice Query if a contract implements an interface\n /// @param interfaceId The interface identifier, as specified in ERC-165\n /// @dev Interface identification is specified in ERC-165. This function\n /// uses less than 30,000 gas.\n /// @return `true` if the contract implements `interfaceID` and\n /// `interfaceID` is not 0xffffffff, `false` otherwise\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/IERC173.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\n/// @title ERC-173 Contract Ownership Standard\n/// Note: the ERC-165 identifier for this interface is 0x7f5828d0\n/* is ERC165 */\ninterface IERC173 {\n /// @dev This emits when ownership of a contract changes.\n event OwnershipTransferred(\n address indexed previousOwner,\n address indexed newOwner\n );\n\n /// @notice Get the address of the owner\n /// @return owner_ The address of the owner.\n function owner() external view returns (address owner_);\n\n /// @notice Set the address of the new owner of the contract\n /// @dev Set _newOwner to address(0) to renounce any ownership.\n /// @param _newOwner The address of the new owner of the contract\n function transferOwnership(address _newOwner) external;\n}\n" + }, + "contracts/interfaces/ERC/IERC677Receiver.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\ninterface IERC677Receiver {\n function onTokenTransfer(\n address sender,\n uint value,\n bytes calldata data\n ) external pure returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155 is IERC165 {\n /**\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n */\n event TransferSingle(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256 id,\n uint256 value\n );\n\n /**\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n * transfers.\n */\n event TransferBatch(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\n\n /**\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n * `approved`.\n */\n event ApprovalForAll(\n address indexed account,\n address indexed operator,\n bool approved\n );\n\n /**\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n *\n * If an {URI} event was emitted for `id`, the standard\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n * returned by {IERC1155MetadataURI-uri}.\n */\n event URI(string value, uint256 indexed id);\n\n /**\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(\n address account,\n uint256 id\n ) external view returns (uint256);\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] calldata accounts,\n uint256[] calldata ids\n ) external view returns (uint256[] memory);\n\n /**\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n *\n * Emits an {ApprovalForAll} event.\n *\n * Requirements:\n *\n * - `operator` cannot be the caller.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n *\n * See {setApprovalForAll}.\n */\n function isApprovedForAll(\n address account,\n address operator\n ) external view returns (bool);\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes calldata data\n ) external;\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(\n address indexed owner,\n address indexed spender,\n uint256 value\n );\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` 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 amount) 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(\n address owner,\n address spender\n ) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the 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 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` 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(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(\n address spender,\n uint256 addedValue\n ) external returns (bool);\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(\n address spender,\n uint256 subtractedValue\n ) external returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(\n address indexed from,\n address indexed to,\n uint256 indexed tokenId\n );\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(\n address indexed owner,\n address indexed approved,\n uint256 indexed tokenId\n );\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(\n address indexed owner,\n address indexed operator,\n bool approved\n );\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(\n uint256 tokenId\n ) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(\n address owner,\n address operator\n ) external view returns (bool);\n}\n" + }, + "contracts/interfaces/IBarz.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Barz Interface\n * @dev Interface of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IBarz {\n error Barz__InitializationFailure();\n}\n" + }, + "contracts/interfaces/IBarzFactory.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Barz} from \"../Barz.sol\";\n\n/**\n * @title Barz Factory Interface\n * @dev Interface of contract to easily deploy Barz to a pre-computed address with a single call\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IBarzFactory {\n event BarzDeployed(address);\n\n function createAccount(\n address verificationFacet,\n bytes calldata owner,\n uint256 salt\n ) external returns (Barz);\n\n function getAddress(\n address verificationFacet,\n bytes calldata owner,\n uint256 salt\n ) external view returns (address);\n\n function getBytecode(\n address accountFacet,\n address verificationFacet,\n address entryPoint,\n address facetRegistry,\n address defaultFallback,\n bytes memory ownerPublicKey\n ) external pure returns (bytes memory);\n\n function getCreationCode() external pure returns (bytes memory);\n}\n" + }, + "contracts/libraries/DefaultLibDiamond.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\n\nerror InitializationFunctionReverted(\n address _initializationContractAddress,\n bytes _calldata\n);\n\nlibrary DefaultLibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION =\n keccak256(\"trustwallet.barz.diamond.storage\");\n\n struct FacetAddressAndPosition {\n address facetAddress;\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\n }\n\n struct FacetFunctionSelectors {\n bytes4[] functionSelectors;\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\n }\n\n struct DiamondStorage {\n // maps function selector to the facet address and\n // the position of the selector in the facetFunctionSelectors.selectors array\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\n // maps facet addresses to function selectors\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\n // facet addresses\n address[] facetAddresses;\n // Used to query if a contract implements an interface.\n // Used to implement ERC-165.\n mapping(bytes4 => bool) supportedInterfaces;\n }\n\n function diamondStorage()\n internal\n pure\n returns (DiamondStorage storage ds)\n {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n event DiamondCut(\n IDiamondCut.FacetCut[] _diamondCut,\n address _init,\n bytes _calldata\n );\n\n // Internal function version of diamondCut\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n for (\n uint256 facetIndex;\n facetIndex < _diamondCut.length;\n facetIndex++\n ) {\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\n if (action == IDiamondCut.FacetCutAction.Add) {\n addFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\n replaceFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\n removeFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else {\n revert(\"LibDiamondCut: Incorrect FacetCutAction\");\n }\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Add facet can't be address(0)\"\n );\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n require(\n oldFacetAddress == address(0),\n \"LibDiamondCut: Can't add function that already exists\"\n );\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function replaceFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Replace facet can't be address(0)\"\n );\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n require(\n oldFacetAddress != _facetAddress,\n \"LibDiamondCut: Can't replace function with same facet\"\n );\n removeFunction(ds, oldFacetAddress, selector);\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function removeFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n // if function does not exist then do nothing and return\n require(\n _facetAddress == address(0),\n \"LibDiamondCut: Remove facet address must be address(0)\"\n );\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n removeFunction(ds, oldFacetAddress, selector);\n }\n }\n\n function addFacet(\n DiamondStorage storage ds,\n address _facetAddress\n ) internal {\n enforceHasContractCode(\n _facetAddress,\n \"LibDiamondCut: New facet has no code\"\n );\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds\n .facetAddresses\n .length;\n ds.facetAddresses.push(_facetAddress);\n }\n\n function addFunction(\n DiamondStorage storage ds,\n bytes4 _selector,\n uint96 _selectorPosition,\n address _facetAddress\n ) internal {\n ds\n .selectorToFacetAndPosition[_selector]\n .functionSelectorPosition = _selectorPosition;\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(\n _selector\n );\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\n }\n\n function removeFunction(\n DiamondStorage storage ds,\n address _facetAddress,\n bytes4 _selector\n ) internal {\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Can't remove function that doesn't exist\"\n );\n // an immutable function is a function defined directly in a diamond\n require(\n _facetAddress != address(this),\n \"LibDiamondCut: Can't remove immutable function\"\n );\n // replace selector with last selector, then delete last selector\n uint256 selectorPosition = ds\n .selectorToFacetAndPosition[_selector]\n .functionSelectorPosition;\n uint256 lastSelectorPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors\n .length - 1;\n // if not the same then replace _selector with lastSelector\n if (selectorPosition != lastSelectorPosition) {\n bytes4 lastSelector = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors[lastSelectorPosition];\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[\n selectorPosition\n ] = lastSelector;\n ds\n .selectorToFacetAndPosition[lastSelector]\n .functionSelectorPosition = uint96(selectorPosition);\n }\n // delete the last selector\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\n delete ds.selectorToFacetAndPosition[_selector];\n\n // if no more selectors for facet address then delete the facet address\n if (lastSelectorPosition == 0) {\n // replace facet address with last facet address and delete last facet address\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\n uint256 facetAddressPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .facetAddressPosition;\n if (facetAddressPosition != lastFacetAddressPosition) {\n address lastFacetAddress = ds.facetAddresses[\n lastFacetAddressPosition\n ];\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\n ds\n .facetFunctionSelectors[lastFacetAddress]\n .facetAddressPosition = facetAddressPosition;\n }\n ds.facetAddresses.pop();\n delete ds\n .facetFunctionSelectors[_facetAddress]\n .facetAddressPosition;\n }\n }\n\n function initializeDiamondCut(\n address _init,\n bytes memory _calldata\n ) internal {\n if (_init == address(0)) {\n return;\n }\n enforceHasContractCode(\n _init,\n \"LibDiamondCut: _init address has no code\"\n );\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length > 0) {\n // bubble up error\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(error)\n revert(add(32, error), returndata_size)\n }\n } else {\n revert InitializationFunctionReverted(_init, _calldata);\n }\n }\n }\n\n function enforceHasContractCode(\n address _contract,\n string memory _errorMessage\n ) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize > 0, _errorMessage);\n }\n}\n" + }, + "contracts/libraries/LibAppStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SafeCast} from \"@openzeppelin/contracts/utils/math/SafeCast.sol\";\nimport {IEntryPoint} from \"../aa-4337/interfaces/IEntryPoint.sol\";\nimport {IFacetRegistry} from \"../infrastructure/interfaces/IFacetRegistry.sol\";\n\n/*\n * @title App Storage\n * @dev App storage for Barz contract to prevent storage collision\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\n\nstruct Lock {\n uint64 release;\n bytes4 locker;\n}\n\nstruct InitializersStorage {\n // NOTE: initialized is a variable to make sure the initialization is only done once.\n uint8 signerInitialized;\n uint8 accountInitialized;\n uint8 restrictionsInitialized;\n}\n\nstruct AppStorage {\n mapping(uint256 => InitializersStorage) initStorage;\n uint8 signerMigration;\n bytes4 validateOwnerSignatureSelector;\n IEntryPoint entryPoint;\n IFacetRegistry facetRegistry;\n mapping(uint256 => Lock) locks;\n}\n\nlibrary LibAppStorage {\n error LibAppStorage__AccountAlreadyUninitialized();\n error LibAppStorage__AccountMustBeUninitialized();\n error LibAppStorage__SignerAlreadyUninitialized();\n error LibAppStorage__SignerMustBeUninitialized();\n\n function appStorage() internal pure returns (AppStorage storage ds) {\n assembly {\n ds.slot := 0\n }\n }\n\n function setSignerUninitialized() internal {\n AppStorage storage s = appStorage();\n if (1 != s.initStorage[0].signerInitialized) {\n revert LibAppStorage__SignerAlreadyUninitialized();\n }\n s.initStorage[0].signerInitialized = 0;\n }\n\n function getValidateOwnerSignatureSelector()\n internal\n view\n returns (bytes4 selector)\n {\n selector = appStorage().validateOwnerSignatureSelector;\n }\n\n function setValidateOwnerSignatureSelector(\n bytes4 _validateOwnerSignatureSelector\n ) internal {\n appStorage()\n .validateOwnerSignatureSelector = _validateOwnerSignatureSelector;\n }\n\n function enforceSignerInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].signerInitialized) {\n revert LibAppStorage__SignerMustBeUninitialized();\n }\n s.initStorage[0].signerInitialized = 1;\n }\n\n function enforceAccountInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].accountInitialized) {\n revert LibAppStorage__AccountMustBeUninitialized();\n }\n s.initStorage[0].accountInitialized = 1;\n }\n\n function initiateSignerMigration() internal {\n appStorage().signerMigration = 1;\n }\n\n function enforceSignerMigration() internal view {\n if (1 != appStorage().signerMigration) {\n revert LibAppStorage__AccountMustBeUninitialized();\n }\n }\n\n function finalizeSignerMigration() internal {\n appStorage().signerMigration = 0;\n }\n\n function setLock(uint256 _releaseAfter, bytes4 _locker) internal {\n appStorage().locks[0] = Lock(SafeCast.toUint64(_releaseAfter), _locker);\n }\n\n function enforceRestrictionsInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].restrictionsInitialized)\n revert LibAppStorage__SignerMustBeUninitialized();\n s.initStorage[0].restrictionsInitialized = 1;\n }\n\n function setRestrictionsUninitialized() internal {\n AppStorage storage s = appStorage();\n if (1 != s.initStorage[0].restrictionsInitialized)\n revert LibAppStorage__AccountAlreadyUninitialized();\n s.initStorage[0].restrictionsInitialized = 0;\n }\n}\n\ncontract BarzStorage {\n AppStorage internal s;\n modifier onlyWhenUnlocked() {\n require(\n uint64(block.timestamp) >= s.locks[0].release,\n \"Account Locked\"\n );\n _;\n }\n modifier onlyWhenLocked() {\n require(\n uint64(block.timestamp) < s.locks[0].release,\n \"Account Unlocked\"\n );\n _;\n }\n}\n" + }, + "contracts/libraries/LibDiamond.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\n\nerror InitializationFunctionReverted(\n address _initializationContractAddress,\n bytes _calldata\n);\n\nlibrary LibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION =\n keccak256(\"trustwallet.barz.diamond.storage\");\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\n bytes4(keccak256(\"verifyRestrictions(address,address,uint256,bytes)\"));\n struct DiamondStorage {\n // maps function selectors to the facets that execute the functions.\n // and maps the selectors to their position in the selectorSlots array.\n // func selector => address facet, selector position\n mapping(bytes4 => bytes32) facets;\n // array of slots of function selectors.\n // each slot holds 8 function selectors.\n mapping(uint256 => bytes32) selectorSlots;\n // The number of function selectors in selectorSlots\n uint16 selectorCount;\n // Used to query if a contract implements an interface.\n // Used to implement ERC-165.\n mapping(bytes4 => bool) supportedInterfaces;\n // Default Fallback Handler of the barz.\n IDiamondLoupe defaultFallbackHandler;\n }\n\n function diamondStorage()\n internal\n pure\n returns (DiamondStorage storage ds)\n {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n function enforceIsSelf() internal view {\n require(msg.sender == address(this), \"LibDiamond: Caller not self\");\n }\n\n event DiamondCut(\n IDiamondCut.FacetCut[] _diamondCut,\n address _init,\n bytes _calldata\n );\n\n bytes32 constant CLEAR_ADDRESS_MASK =\n bytes32(uint256(0xffffffffffffffffffffffff));\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\n\n // Internal function version of diamondCut\n // This code is almost the same as the external diamondCut,\n // except it is using 'Facet[] memory _diamondCut' instead of\n // 'Facet[] calldata _diamondCut'.\n // The code is duplicated to prevent copying calldata to memory which\n // causes an error for a two dimensional array.\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n DiamondStorage storage ds = diamondStorage();\n uint256 originalSelectorCount = ds.selectorCount;\n uint256 selectorCount = originalSelectorCount;\n bytes32 selectorSlot;\n // Check if last selector slot is not full\n // \"selectorCount & 7\" is a gas efficient modulo by eight \"selectorCount % 8\"\n if (selectorCount & 7 > 0) {\n // get last selectorSlot\n // \"selectorSlot >> 3\" is a gas efficient division by 8 \"selectorSlot / 8\"\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\n }\n // loop through diamond cut\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\n selectorCount,\n selectorSlot,\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].action,\n _diamondCut[facetIndex].functionSelectors\n );\n\n unchecked {\n facetIndex++;\n }\n }\n if (selectorCount != originalSelectorCount) {\n ds.selectorCount = uint16(selectorCount);\n }\n // If last selector slot is not full\n // \"selectorCount & 7\" is a gas efficient modulo by eight \"selectorCount % 8\"\n if (selectorCount & 7 > 0) {\n // \"selectorSlot >> 3\" is a gas efficient division by 8 \"selectorSlot / 8\"\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addReplaceRemoveFacetSelectors(\n uint256 _selectorCount,\n bytes32 _selectorSlot,\n address _newFacetAddress,\n IDiamondCut.FacetCutAction _action,\n bytes4[] memory _selectors\n ) internal returns (uint256, bytes32) {\n DiamondStorage storage ds = diamondStorage();\n require(\n _selectors.length > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n if (_action == IDiamondCut.FacetCutAction.Add) {\n enforceHasContractCode(\n _newFacetAddress,\n \"LibDiamondCut: Add facet has no code\"\n );\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n require(\n address(bytes20(oldFacet)) == address(0),\n \"LibDiamondCut: Can't add function that already exists\"\n );\n // add facet for selector\n ds.facets[selector] =\n bytes20(_newFacetAddress) |\n bytes32(_selectorCount);\n // \"_selectorCount & 7\" is a gas efficient modulo by eight \"_selectorCount % 8\"\n // \" << 5 is the same as multiplying by 32 ( * 32)\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\n // clear selector position in slot and add selector\n _selectorSlot =\n (_selectorSlot &\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\n (bytes32(selector) >> selectorInSlotPosition);\n // if slot is full then write it to storage\n if (selectorInSlotPosition == 224) {\n // \"_selectorSlot >> 3\" is a gas efficient division by 8 \"_selectorSlot / 8\"\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\n _selectorSlot = 0;\n }\n _selectorCount++;\n\n unchecked {\n selectorIndex++;\n }\n }\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\n enforceHasContractCode(\n _newFacetAddress,\n \"LibDiamondCut: Replace facet has no code\"\n );\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n address oldFacetAddress = address(bytes20(oldFacet));\n // only useful if immutable functions exist\n require(\n oldFacetAddress != address(this),\n \"LibDiamondCut: Can't replace immutable function\"\n );\n require(\n oldFacetAddress != _newFacetAddress,\n \"LibDiamondCut: Can't replace function with same function\"\n );\n require(\n oldFacetAddress != address(0),\n \"LibDiamondCut: Can't replace function that doesn't exist\"\n );\n // replace old facet address\n ds.facets[selector] =\n (oldFacet & CLEAR_ADDRESS_MASK) |\n bytes20(_newFacetAddress);\n\n unchecked {\n selectorIndex++;\n }\n }\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\n require(\n _newFacetAddress == address(0),\n \"LibDiamondCut: Remove facet address must be address(0)\"\n );\n // \"_selectorCount >> 3\" is a gas efficient division by 8 \"_selectorCount / 8\"\n uint256 selectorSlotCount = _selectorCount >> 3;\n // \"_selectorCount & 7\" is a gas efficient modulo by eight \"_selectorCount % 8\"\n uint256 selectorInSlotIndex = _selectorCount & 7;\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n if (_selectorSlot == 0) {\n // get last selectorSlot\n selectorSlotCount--;\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\n selectorInSlotIndex = 7;\n } else {\n selectorInSlotIndex--;\n }\n bytes4 lastSelector;\n uint256 oldSelectorsSlotCount;\n uint256 oldSelectorInSlotPosition;\n // adding a block here prevents stack too deep error\n {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n require(\n address(bytes20(oldFacet)) != address(0),\n \"LibDiamondCut: Can't remove function that doesn't exist\"\n );\n // only useful if immutable functions exist\n require(\n address(bytes20(oldFacet)) != address(this),\n \"LibDiamondCut: Can't remove immutable function\"\n );\n // replace selector with last selector in ds.facets\n // gets the last selector\n // \" << 5 is the same as multiplying by 32 ( * 32)\n lastSelector = bytes4(\n _selectorSlot << (selectorInSlotIndex << 5)\n );\n if (lastSelector != selector) {\n // update last selector slot position info\n ds.facets[lastSelector] =\n (oldFacet & CLEAR_ADDRESS_MASK) |\n bytes20(ds.facets[lastSelector]);\n }\n delete ds.facets[selector];\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\n // \"oldSelectorCount >> 3\" is a gas efficient division by 8 \"oldSelectorCount / 8\"\n oldSelectorsSlotCount = oldSelectorCount >> 3;\n // \"oldSelectorCount & 7\" is a gas efficient modulo by eight \"oldSelectorCount % 8\"\n // \" << 5 is the same as multiplying by 32 ( * 32)\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\n }\n if (oldSelectorsSlotCount != selectorSlotCount) {\n bytes32 oldSelectorSlot = ds.selectorSlots[\n oldSelectorsSlotCount\n ];\n // clears the selector we are deleting and puts the last selector in its place.\n oldSelectorSlot =\n (oldSelectorSlot &\n ~(CLEAR_SELECTOR_MASK >>\n oldSelectorInSlotPosition)) |\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\n // update storage with the modified slot\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\n } else {\n // clears the selector we are deleting and puts the last selector in its place.\n _selectorSlot =\n (_selectorSlot &\n ~(CLEAR_SELECTOR_MASK >>\n oldSelectorInSlotPosition)) |\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\n }\n if (selectorInSlotIndex == 0) {\n delete ds.selectorSlots[selectorSlotCount];\n _selectorSlot = 0;\n }\n\n unchecked {\n selectorIndex++;\n }\n }\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\n } else {\n revert(\"LibDiamondCut: Incorrect FacetCutAction\");\n }\n return (_selectorCount, _selectorSlot);\n }\n\n function initializeDiamondCut(\n address _init,\n bytes memory _calldata\n ) internal {\n if (_init == address(0)) {\n return;\n }\n enforceHasContractCode(\n _init,\n \"LibDiamondCut: _init address has no code\"\n );\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length > 0) {\n // bubble up error\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(error)\n revert(add(32, error), returndata_size)\n }\n } else {\n revert InitializationFunctionReverted(_init, _calldata);\n }\n }\n }\n\n function enforceHasContractCode(\n address _contract,\n string memory _errorMessage\n ) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize > 0, _errorMessage);\n }\n\n function restrictionsFacet() internal view returns (address facetAddress_) {\n facetAddress_ = address(\n bytes20(\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\n )\n );\n }\n}\n" + }, + "contracts/libraries/LibFacetStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Storage\n * @dev Storage contract to store each facets variables with diamond storage\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\n\nstruct Secp256k1VerificationStorage {\n address signer;\n}\n\nstruct Secp256r1VerificationStorage {\n uint256[2] q;\n}\n\nstruct GuardianStorage {\n mapping(bytes32 => uint256) pending;\n mapping(uint8 => StorageConfig) configs;\n}\n\nstruct Info {\n bool exists;\n uint128 index;\n}\n\nstruct StorageConfig {\n address[] addresses;\n mapping(address => Info) info;\n}\n\nstruct RecoveryConfig {\n bytes recoveryPublicKey;\n uint64 executeAfter;\n}\n\nstruct ApprovalConfig {\n bool isApproved;\n uint64 validUntil;\n}\n\nstruct RecoveryApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isNewOwnerApproved;\n}\n\nstruct RecoveryStorage {\n mapping(uint8 => RecoveryConfig) recoveryConfigs;\n mapping(uint8 => RecoveryApprovalConfig) recoveryApprovalConfigs;\n uint128 nonce;\n}\n\nstruct RestrictionsStorage {\n address[] restrictions;\n mapping(address => bool) exists;\n}\n\nstruct SignatureMigrationConfig {\n bytes migrationPublicKey;\n address migrationVerificationFacet;\n bytes4[] migrationSelectors;\n uint64 migrateAfter;\n}\n\nstruct SignatureMigrationApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isMigrationApproved;\n}\n\nstruct SignatureMigrationStorage {\n mapping(uint8 => SignatureMigrationConfig) migrationConfigs;\n mapping(uint8 => SignatureMigrationApprovalConfig) migrationApprovalConfigs;\n uint128 nonce;\n}\n\nstruct DiamondCutApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isDiamondCutApproved;\n}\n\nstruct DiamondCutStorage {\n mapping(uint8 => DiamondCutApprovalConfig) diamondCutApprovalConfigs;\n uint128 nonce;\n}\n\nstruct LockStorage {\n uint128 nonce;\n}\n\nlibrary LibFacetStorage {\n bytes32 constant K1_STORAGE_POSITION =\n keccak256(\n \"v0.trustwallet.diamond.storage.Secp256k1VerificationStorage\"\n );\n bytes32 constant R1_STORAGE_POSITION =\n keccak256(\n \"v0.trustwallet.diamond.storage.Secp256r1VerificationStorage\"\n );\n bytes32 constant GUARDIAN_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.GuardianStorage\");\n bytes32 constant RECOVERY_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.RecoveryStorage\");\n bytes32 constant RESTRICTION_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.RestrictionsStorage\");\n bytes32 constant MIGRATION_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.SignatureMigrationStorage\");\n bytes32 constant DIAMONDCUT_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.DiamondCutStorage\");\n bytes32 constant LOCK_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.LockStorage\");\n\n function k1Storage()\n internal\n pure\n returns (Secp256k1VerificationStorage storage ds)\n {\n bytes32 storagePosition = K1_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function r1Storage()\n internal\n pure\n returns (Secp256r1VerificationStorage storage ds)\n {\n bytes32 storagePosition = R1_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function guardianStorage()\n internal\n pure\n returns (GuardianStorage storage ds)\n {\n bytes32 storagePosition = GUARDIAN_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function recoveryStorage()\n internal\n pure\n returns (RecoveryStorage storage ds)\n {\n bytes32 storagePosition = RECOVERY_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function restrictionsStorage()\n internal\n pure\n returns (RestrictionsStorage storage ds)\n {\n bytes32 storagePosition = RESTRICTION_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function migrationStorage()\n internal\n pure\n returns (SignatureMigrationStorage storage ds)\n {\n bytes32 storagePosition = MIGRATION_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function diamondCutStorage()\n internal\n pure\n returns (DiamondCutStorage storage ds)\n {\n bytes32 storagePosition = DIAMONDCUT_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function lockStorage() internal pure returns (LockStorage storage ds) {\n bytes32 storagePosition = LOCK_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n}\n" + }, + "contracts/libraries/LibGuardian.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibFacetStorage, StorageConfig} from \"./LibFacetStorage.sol\";\n\n/**\n * @title LibGuardian\n * @dev Internal Library to provide utility feature for Guardians stored in Guardian Facet Storage\n * @author David Yongjun Kim (@Powerstream3604)\n */\nlibrary LibGuardian {\n function majorityOfGuardians()\n internal\n view\n returns (uint256 guardianNumber)\n {\n uint256 guardianLength = guardianCount();\n guardianNumber = (guardianLength == 0) ? 0 : guardianLength / 2 + 1;\n }\n\n function isGuardian(address _guardian) internal view returns (bool) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n return config.info[_guardian].exists;\n }\n\n function guardianCount() internal view returns (uint256) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n return config.addresses.length;\n }\n\n function getGuardians() internal view returns (address[] memory) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n address[] memory addresses = new address[](config.addresses.length);\n uint256 addressesLen = config.addresses.length;\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n return addresses;\n }\n}\n" + }, + "contracts/libraries/LibLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {LibDiamond} from \"./LibDiamond.sol\";\n\n/**\n * @title LibLoupe\n * @dev Internal Library to provide utility feature for reading the state of diamond facets\n * Originally from Diamond's implementation of Mudgen(author of EIP-2535)\n */\nlibrary LibLoupe {\n /// @notice Gets all facets and their selectors.\n /// @return facets_ Facet\n function facets()\n internal\n view\n returns (IDiamondLoupe.Facet[] memory facets_)\n {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facets_ = new IDiamondLoupe.Facet[](ds.selectorCount);\n uint16[] memory numFacetSelectors = new uint16[](ds.selectorCount);\n uint256 numFacets;\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facetAddress_ = address(bytes20(ds.facets[selector]));\n bool continueLoop;\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n if (facets_[facetIndex].facetAddress == facetAddress_) {\n facets_[facetIndex].functionSelectors[\n numFacetSelectors[facetIndex]\n ] = selector;\n // probably will never have more than 256 functions from one facet contract\n require(numFacetSelectors[facetIndex] < 255);\n numFacetSelectors[facetIndex]++;\n continueLoop = true;\n break;\n }\n }\n if (continueLoop) {\n continue;\n }\n facets_[numFacets].facetAddress = facetAddress_;\n facets_[numFacets].functionSelectors = new bytes4[](\n ds.selectorCount\n );\n facets_[numFacets].functionSelectors[0] = selector;\n numFacetSelectors[numFacets] = 1;\n numFacets++;\n }\n }\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n uint256 numSelectors = numFacetSelectors[facetIndex];\n bytes4[] memory selectors = facets_[facetIndex].functionSelectors;\n // setting the number of selectors\n assembly {\n mstore(selectors, numSelectors)\n }\n }\n // setting the number of facets\n assembly {\n mstore(facets_, numFacets)\n }\n }\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n /// @return _facetFunctionSelectors The selectors associated with a facet address.\n function facetFunctionSelectors(\n address _facet\n ) internal view returns (bytes4[] memory _facetFunctionSelectors) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n uint256 numSelectors;\n _facetFunctionSelectors = new bytes4[](ds.selectorCount);\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facet = address(bytes20(ds.facets[selector]));\n if (_facet == facet) {\n _facetFunctionSelectors[numSelectors] = selector;\n numSelectors++;\n }\n }\n }\n // Set the number of selectors in the array\n assembly {\n mstore(_facetFunctionSelectors, numSelectors)\n }\n }\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses()\n internal\n view\n returns (address[] memory facetAddresses_)\n {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facetAddresses_ = new address[](ds.selectorCount);\n uint256 numFacets;\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facetAddress_ = address(bytes20(ds.facets[selector]));\n bool continueLoop;\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n if (facetAddress_ == facetAddresses_[facetIndex]) {\n continueLoop = true;\n break;\n }\n }\n if (continueLoop) {\n continue;\n }\n facetAddresses_[numFacets] = facetAddress_;\n numFacets++;\n }\n }\n // Set the number of facet addresses in the array\n assembly {\n mstore(facetAddresses_, numFacets)\n }\n }\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(\n bytes4 _functionSelector\n ) internal view returns (address facetAddress_) {\n facetAddress_ = address(\n bytes20(LibDiamond.diamondStorage().facets[_functionSelector])\n );\n }\n}\n" + }, + "contracts/libraries/LibMultiSigStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Multi-sig Storage\n * @dev Storage contract for storing Multi-sig Facet variables in diamond storage pattern\n * @author David Yongjun Kim (@Powerstream3604)\n */\n\nstruct MultiSigStorage {\n mapping(address => address) owners;\n mapping(uint256 => mapping(address => mapping(bytes32 => uint256))) approvedHashes;\n uint256 ownerCount;\n uint256 threshold;\n uint256 counter;\n}\n\nlibrary LibMultiSigStorage {\n function multisigStorage()\n internal\n pure\n returns (MultiSigStorage storage ds)\n {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.MultiSigStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n}\n" + }, + "contracts/libraries/LibRecoverSpender.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title RecoverSpender\n * @dev Library to determine the action and spender of calldata\n * @author Ruslan Serebriakov (@rsrbk)\n */\nlibrary LibRecoverSpender {\n // ERC20, ERC721 & ERC1155 transfers & approvals\n bytes4 private constant ERC20_TRANSFER =\n bytes4(keccak256(\"transfer(address,uint256)\"));\n bytes4 private constant ERC20_APPROVE =\n bytes4(keccak256(\"approve(address,uint256)\"));\n bytes4 private constant ERC20_INCREASE_ALLOWANCE =\n bytes4(keccak256(\"increaseAllowance(address,uint256)\"));\n bytes4 private constant ERC20_DECREASE_ALLOWANCE =\n bytes4(keccak256(\"decreaseAllowance(address,uint256)\"));\n bytes4 private constant ERC721_SET_APPROVAL_FOR_ALL =\n bytes4(keccak256(\"setApprovalForAll(address,bool)\"));\n bytes4 private constant ERC721_TRANSFER_FROM =\n bytes4(keccak256(\"transferFrom(address,address,uint256)\"));\n bytes4 private constant ERC721_SAFE_TRANSFER_FROM =\n bytes4(keccak256(\"safeTransferFrom(address,address,uint256)\"));\n bytes4 private constant ERC721_SAFE_TRANSFER_FROM_BYTES =\n bytes4(keccak256(\"safeTransferFrom(address,address,uint256,bytes)\"));\n bytes4 private constant ERC1155_SAFE_TRANSFER_FROM =\n bytes4(\n keccak256(\"safeTransferFrom(address,address,uint256,uint256,bytes)\")\n );\n bytes4 private constant ERC1155_SAFE_BATCH_TRANSFER_FROM =\n bytes4(\n keccak256(\n \"safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)\"\n )\n );\n\n /**\n * @notice Helper method to recover the spender from a contract call.\n * The method returns the contract unless the call is to a standard method of a ERC20/ERC721/ERC1155 token\n * in which case the spender is recovered from the data.\n * @param _to The target contract.\n * @param _data The data payload.\n */\n function _recover(\n address _to,\n bytes memory _data\n ) internal pure returns (address spender) {\n if (_data.length >= 68) {\n bytes4 methodId;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n methodId := mload(add(_data, 0x20))\n }\n if (\n methodId == ERC20_TRANSFER ||\n methodId == ERC20_APPROVE ||\n methodId == ERC20_INCREASE_ALLOWANCE ||\n methodId == ERC20_DECREASE_ALLOWANCE ||\n methodId == ERC721_SET_APPROVAL_FOR_ALL\n ) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n spender := mload(add(_data, 0x24))\n }\n return spender;\n }\n if (\n methodId == ERC721_TRANSFER_FROM ||\n methodId == ERC721_SAFE_TRANSFER_FROM ||\n methodId == ERC721_SAFE_TRANSFER_FROM_BYTES ||\n methodId == ERC1155_SAFE_TRANSFER_FROM ||\n methodId == ERC1155_SAFE_BATCH_TRANSFER_FROM\n ) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n spender := mload(add(_data, 0x44))\n }\n return spender;\n }\n }\n\n spender = _to;\n }\n}\n" + }, + "contracts/libraries/LibReentrancyGuardStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nstruct ReentrancyGuardStorage {\n uint256 status;\n}\n\nlibrary LibReentrancyGuardStorage {\n bytes32 private constant REENTRANCY_GUARD_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.ReentrancyGuardStorage\");\n\n function reentrancyguardStorage()\n internal\n pure\n returns (ReentrancyGuardStorage storage ds)\n {\n bytes32 storagePosition = REENTRANCY_GUARD_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n}" + }, + "contracts/libraries/LibUtils.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\n\nlibrary LibUtils {\n // Internal utility functions\n function mergeArrays(\n bytes4[] memory _array1,\n bytes4[] memory _array2\n ) internal pure returns (bytes4[] memory) {\n uint256 length1 = _array1.length;\n uint256 length2 = _array2.length;\n bytes4[] memory mergedArray = new bytes4[](length1 + length2);\n\n for (uint256 i; i < length1; ) {\n mergedArray[i] = _array1[i];\n unchecked {\n ++i;\n }\n }\n\n for (uint256 i; i < length2; ) {\n mergedArray[length1 + i] = _array2[i];\n unchecked {\n ++i;\n }\n }\n\n return mergedArray;\n }\n\n function removeFacetElement(\n IDiamondLoupe.Facet[] memory _facets,\n uint256 _index\n ) internal pure returns (IDiamondLoupe.Facet[] memory) {\n require(_index < _facets.length, \"Invalid index\");\n require(_facets.length != 0, \"Invalid array\");\n\n // Create a new array with a length of `_facets.length - 1`\n IDiamondLoupe.Facet[] memory newArray = new IDiamondLoupe.Facet[](\n _facets.length - 1\n );\n uint256 newArrayLength = newArray.length;\n // Iterate over the original array, skipping the element at the specified `index`\n for (uint256 i; i < newArrayLength; ) {\n if (i < _index) {\n newArray[i] = _facets[i];\n } else {\n newArray[i] = _facets[i + 1];\n }\n unchecked {\n ++i;\n }\n }\n\n return newArray;\n }\n\n function removeElement(\n bytes4[] memory _array,\n uint256 _index\n ) internal pure returns (bytes4[] memory) {\n require(_index < _array.length, \"Invalid index\");\n require(_array.length != 0, \"Invalid array\");\n\n bytes4[] memory newArray = new bytes4[](_array.length - 1);\n uint256 newArrayLength = newArray.length;\n for (uint256 i; i < newArrayLength; ) {\n if (i < _index) {\n newArray[i] = _array[i];\n } else {\n newArray[i] = _array[i + 1];\n }\n unchecked {\n ++i;\n }\n }\n\n return newArray;\n }\n\n function setValue(\n bytes4[] memory _keys,\n address[] memory _values,\n bytes4 _key,\n address _value\n ) internal pure returns (bytes4[] memory, address[] memory) {\n uint256 index = findIndex(_keys, _key);\n uint256 keysLength = _keys.length;\n if (index < keysLength) {\n _values[index] = _value;\n } else {\n // Create new storage arrays\n bytes4[] memory newKeys = new bytes4[](keysLength + 1);\n address[] memory newValues = new address[](_values.length + 1);\n\n // Copy values to the new storage arrays\n for (uint256 i; i < keysLength; ) {\n newKeys[i] = _keys[i];\n newValues[i] = _values[i];\n\n unchecked {\n ++i;\n }\n }\n\n // Add the new key-value pair\n newKeys[keysLength] = _key;\n newValues[_values.length] = _value;\n\n return (newKeys, newValues);\n }\n\n // If the key already exists, return the original arrays\n return (_keys, _values);\n }\n\n function getValue(\n bytes4[] memory _keys,\n address[] memory _values,\n bytes4 _key\n ) internal pure returns (address) {\n uint256 index = findIndex(_keys, _key);\n if (index >= _keys.length) return address(0);\n\n return _values[index];\n }\n\n function findIndex(\n bytes4[] memory _keys,\n bytes4 _key\n ) internal pure returns (uint256) {\n uint256 keysLength = _keys.length;\n for (uint256 i; i < keysLength; ) {\n if (_keys[i] == _key) {\n return i;\n }\n unchecked {\n ++i;\n }\n }\n return keysLength;\n }\n}\n" + }, + "contracts/restrictions/IRestriction.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Interface for restrictions\n * @dev Restriction is a contract which decides whether to approve a certain kind of transaction, based on its internal logic.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface IRestriction {\n /**\n * @dev Based on restriction's internal logic, it should accept or reject a certain transaction.\n * @param from The address of the sender, that will be signing the transaction.\n * @param to The receiving address.\n * @param value Amount of ETH to transfer from sender to recipient.\n * @param _calldata Optional field to include arbitrary data.\n * @return bool value for whether the check is passed\n */\n function check(\n address from,\n address to,\n uint256 value,\n bytes calldata _calldata\n ) external returns (bool);\n}\n" + }, + "contracts/restrictions/WhitelistRestriction.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibRecoverSpender} from \"../libraries/LibRecoverSpender.sol\";\nimport {WhitelistStorage} from \"../infrastructure/WhitelistStorage.sol\";\nimport {IRestriction} from \"./IRestriction.sol\";\n\n/**\n * @title Whitelist Restriction\n * @dev This restriction defines a list of accepted addresses and denies any interaction with addresses outside of it.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract WhitelistRestriction is IRestriction {\n WhitelistStorage public immutable whitelistStorage;\n\n constructor(WhitelistStorage _whitelistStorage) {\n whitelistStorage = _whitelistStorage;\n }\n\n /**\n * @notice Helper method to recover the spender from a contract call.\n * The method returns the contract unless the call is to a standard method of a ERC20/ERC721/ERC1155 token\n * in which case the spender is recovered from the data.\n * @param _to The target contract.\n * @param _data The data payload.\n */\n function recoverSpender(\n address _to,\n bytes memory _data\n ) public pure returns (address spender) {\n return LibRecoverSpender._recover(_to, _data);\n }\n\n /*\n * @dev IRestriction's implementation. It will allow transaction if the sender is whitelisted, or user, or the whitelist storage.\n * @param _from The address of the sender, that will be signing the transaction.\n * @param _to The receiving address.\n * @param _calldata Optional field to include arbitrary data.\n * @return result value for whether the check is passed\n */\n function check(\n address _from,\n address _to,\n uint256 /*_value*/,\n bytes calldata _calldata\n ) external view override returns (bool result) {\n return\n whitelistStorage.isWhitelisted(\n _from,\n LibRecoverSpender._recover(_to, _calldata)\n ) ||\n _to == address(whitelistStorage) ||\n _to == msg.sender;\n }\n}\n" + }, + "contracts/test/TestCounter.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\ncontract TestCounter {\n int private count = 0;\n\n event CounterIncremented(int count);\n event CounterDecremented(int count);\n\n function incrementCounter() public {\n count += 1;\n emit CounterIncremented(count);\n }\n\n function decrementCounter() public {\n count -= 1;\n emit CounterIncremented(count);\n }\n\n function getCount() public view returns (int) {\n return count;\n }\n}\n" + }, + "contracts/test/TestERC1155.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC1155/ERC1155.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\n\ncontract TestERC1155 is ERC1155 {\n using Counters for Counters.Counter;\n\n Counters.Counter private _tokenIds;\n\n constructor() ERC1155(\"\") {}\n\n function mint(address account, uint256 amount) external {\n uint256 tokenId = _getNextTokenId();\n _mint(account, tokenId, amount, \"\");\n }\n\n function mintBatch(\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes memory data\n ) external {\n require(\n ids.length == amounts.length,\n \"TestERC1155: arrays length mismatch\"\n );\n\n _mintBatch(to, ids, amounts, data);\n }\n\n function _getNextTokenId() private returns (uint256) {\n _tokenIds.increment();\n return _tokenIds.current();\n }\n}\n" + }, + "contracts/test/TestERC777.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC777/ERC777.sol\";\n\ncontract TestERC777 is ERC777 {\n constructor(\n address[] memory _operators\n ) ERC777(\"TestERC777\", \"TERC777\", _operators) {}\n\n function mint(address account, uint256 amount) external {\n _mint(account, amount, \"\", \"\");\n }\n}\n" + }, + "contracts/test/TestInvalidSecp256k1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IVerificationFacet} from \"../facets/interfaces/IVerificationFacet.sol\";\nimport {IERC1271} from \"../interfaces/ERC/IERC1271.sol\";\nimport {AppStorage, LibAppStorage, BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {LibFacetStorage, Secp256k1VerificationStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {UserOperation} from \"../aa-4337/interfaces/UserOperation.sol\";\n\n/**\n * @title Test Secp256k1 verification facet\n * @dev Default Ethereum's elliptic curve\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract TestInvalidSecp256k1VerificationFacet is BarzStorage, IERC1271 {\n using ECDSA for bytes32;\n error Secp256k1VerificationFacet__InvalidSignerLength();\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n\n event SignerUninitialized();\n\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n }\n\n // THIS INVALID FACET DOES NOT INCLUDE initializeSigner()\n // THIS FACET IS USED TO TEST WHEN initializeSigner() DOESN'T EXIST IN FACET\n\n function uninitializeSigner() external returns (uint256 uninitSuccess) {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view returns (uint256 validationData) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n return validateSignature(userOp, userOpHash, k1Storage.signer);\n }\n\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n address signer\n ) public pure returns (uint256) {\n bytes32 hash = userOpHash.toEthSignedMessageHash();\n if (signer != hash.recover(userOp.signature)) return 1;\n return 0;\n }\n\n // This is REMOVED for testing purpose\n function validateOwnerSignatureSelector() public pure returns (bytes4) {\n // return this.validateOwnerSignature.selector;\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n function owner() public view returns (bytes memory) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n return abi.encodePacked(k1Storage.signer);\n }\n\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure returns (bool) {\n return (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (_hash.recover(_signature) ==\n LibFacetStorage.k1Storage().signer)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n}\n" + }, + "contracts/test/TestNFT.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\n\ncontract TestNFT is ERC721 {\n using Counters for Counters.Counter;\n Counters.Counter private currentTokenId;\n\n constructor() ERC721(\"TestNFT\", \"TNFT\") {}\n\n function mint(address recipient) public returns (uint256) {\n currentTokenId.increment();\n uint256 newItemId = currentTokenId.current();\n _safeMint(recipient, newItemId);\n return newItemId;\n }\n}\n" + }, + "contracts/test/TestToken.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract TestToken is ERC20 {\n constructor()\n // solhint-disable-next-line no-empty-blocks\n ERC20(\"TST\", \"TestToken\")\n {}\n\n function mint(address sender, uint256 amount) external {\n _mint(sender, amount);\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 999999 + }, + "evmVersion": "paris", + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/deployments/bsc/.chainId b/deployments/bsc/.chainId new file mode 100644 index 0000000..2ebc651 --- /dev/null +++ b/deployments/bsc/.chainId @@ -0,0 +1 @@ +56 \ No newline at end of file diff --git a/deployments/bsc/AccountFacet.json b/deployments/bsc/AccountFacet.json new file mode 100644 index 0000000..51ec819 --- /dev/null +++ b/deployments/bsc/AccountFacet.json @@ -0,0 +1,591 @@ +{ + "address": "0xFde53272dcd7938d16E031A6989753c321728332", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "AccountFacet__CallNotSuccessful", + "type": "error" + }, + { + "inputs": [], + "name": "AccountFacet__InitializationFailure", + "type": "error" + }, + { + "inputs": [], + "name": "AccountFacet__InvalidArrayLength", + "type": "error" + }, + { + "inputs": [], + "name": "AccountFacet__NonExistentVerificationFacet", + "type": "error" + }, + { + "inputs": [], + "name": "AccountFacet__RestrictionsFailure", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_initializationContractAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "InitializationFunctionReverted", + "type": "error" + }, + { + "inputs": [], + "name": "LibAppStorage__AccountMustBeUninitialized", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract IEntryPoint", + "name": "entryPoint", + "type": "address" + }, + { + "indexed": true, + "internalType": "bytes", + "name": "ownerPublicKey", + "type": "bytes" + } + ], + "name": "AccountInitialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "indexed": false, + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "DiamondCut", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "VerificationFailure", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "VerificationSuccess", + "type": "event" + }, + { + "inputs": [], + "name": "entryPoint", + "outputs": [ + { + "internalType": "contract IEntryPoint", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_dest", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_func", + "type": "bytes" + } + ], + "name": "execute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_dest", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "_value", + "type": "uint256[]" + }, + { + "internalType": "bytes[]", + "name": "_func", + "type": "bytes[]" + } + ], + "name": "executeBatch", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getNonce", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_verificationFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_anEntryPoint", + "type": "address" + }, + { + "internalType": "address", + "name": "_facetRegistry", + "type": "address" + }, + { + "internalType": "address", + "name": "_defaultFallBackHandler", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_ownerPublicKey", + "type": "bytes" + } + ], + "name": "initialize", + "outputs": [ + { + "internalType": "uint256", + "name": "initSuccess", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "initCode", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "callGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "verificationGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "preVerificationGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxFeePerGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPriorityFeePerGas", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "paymasterAndData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "internalType": "struct UserOperation", + "name": "userOp", + "type": "tuple" + }, + { + "internalType": "bytes32", + "name": "userOpHash", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "missingAccountFunds", + "type": "uint256" + } + ], + "name": "validateUserOp", + "outputs": [ + { + "internalType": "uint256", + "name": "validationData", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0x15e68109e0b536849a9b5802ba0696bbde96d16dbb912daded8a4cf90616d744", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 97, + "gasUsed": "2369950", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0xd20d3e8be0f11064eab20a617e32b2a204e99f7c1aeafe3927bdfa0bfc583e11", + "transactionHash": "0x15e68109e0b536849a9b5802ba0696bbde96d16dbb912daded8a4cf90616d744", + "logs": [], + "blockNumber": 33657815, + "cumulativeGasUsed": "10147227", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 4, + "solcInputHash": "4356503edd8ae34e73cb6dd1c8e2fc8a", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AccountFacet__CallNotSuccessful\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AccountFacet__InitializationFailure\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AccountFacet__InvalidArrayLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AccountFacet__NonExistentVerificationFacet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AccountFacet__RestrictionsFailure\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_initializationContractAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"InitializationFunctionReverted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LibAppStorage__AccountMustBeUninitialized\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract IEntryPoint\",\"name\":\"entryPoint\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes\",\"name\":\"ownerPublicKey\",\"type\":\"bytes\"}],\"name\":\"AccountInitialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"DiamondCut\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"VerificationFailure\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"VerificationSuccess\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"entryPoint\",\"outputs\":[{\"internalType\":\"contract IEntryPoint\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_dest\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_func\",\"type\":\"bytes\"}],\"name\":\"execute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_dest\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"_value\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes[]\",\"name\":\"_func\",\"type\":\"bytes[]\"}],\"name\":\"executeBatch\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_verificationFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_anEntryPoint\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_facetRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_defaultFallBackHandler\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_ownerPublicKey\",\"type\":\"bytes\"}],\"name\":\"initialize\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"initSuccess\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"userOp\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"missingAccountFunds\",\"type\":\"uint256\"}],\"name\":\"validateUserOp\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"validationData\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"Account module contract that provides the account features and initialization of signer compatible with EIP-1271 & EIP-4337\",\"kind\":\"dev\",\"methods\":{\"execute(address,uint256,bytes)\":{\"details\":\"This method executes the calldata coming from the EntryPoint. Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\",\"params\":{\"_dest\":\"Address of destination where the call will be forwarded to\",\"_func\":\"Bytes of calldata to execute in the destination address\",\"_value\":\"Amount of native coin the owner is willing to send(e.g. ETH, BNB)\"}},\"executeBatch(address[],uint256[],bytes[])\":{\"details\":\"This method batch executes the calldata coming from the EntryPoint. Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\",\"params\":{\"_dest\":\"Array of addresses of destination where the call will be forwarded to\",\"_func\":\"Array of bytes of calldata to execute in the destination address\",\"_value\":\"Array of amount of native coin the owner is willing to send(e.g. ETH, BNB)\"}},\"initialize(address,address,address,address,bytes)\":{\"details\":\"This method can only be called during the initialization or signature migration. If the proxy contract was created without initialization, anyone can call initialize. Barz calls initialize in constructor in an atomic transaction during deployment\",\"params\":{\"_anEntryPoint\":\"Entrypoint contract defined in EIP-4337 handling the flow of UserOp\",\"_defaultFallBackHandler\":\"Middleware contract for default facets\",\"_facetRegistry\":\"Registry of Facets that hold all facet information\",\"_ownerPublicKey\":\"Bytes of owner public key\",\"_verificationFacet\":\"Facet contract handling the verificationi\"}}},\"title\":\"Account Facet\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"This constructor ensures that this contract can only be used as singleton for Proxy contracts\"},\"entryPoint()\":{\"notice\":\"Returns the address of EntryPoint contract registered to Barz account\"},\"execute(address,uint256,bytes)\":{\"notice\":\"Calls the destination with inputted calldata and value from EntryPoint\"},\"executeBatch(address[],uint256[],bytes[])\":{\"notice\":\"Batch calls the destination with inputted calldata and value from EntryPoint\"},\"getNonce()\":{\"notice\":\"Return the account nonce. This method returns the next sequential nonce. For a nonce of a specific key, use `entrypoint.getNonce(account, key)`\"},\"initialize(address,address,address,address,bytes)\":{\"notice\":\"Initializes the initial storage of the Barz contract.\"},\"validateUserOp((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256)\":{\"notice\":\"Validate user's signature and nonce. subclass doesn't need to override this method. Instead, it should override the specific internal validation methods.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/AccountFacet.sol\":\"AccountFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./math/Math.sol\\\";\\nimport \\\"./math/SignedMath.sol\\\";\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n uint256 length = Math.log10(value) + 1;\\n string memory buffer = new string(length);\\n uint256 ptr;\\n /// @solidity memory-safe-assembly\\n assembly {\\n ptr := add(buffer, add(32, length))\\n }\\n while (true) {\\n ptr--;\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\\n }\\n value /= 10;\\n if (value == 0) break;\\n }\\n return buffer;\\n }\\n }\\n\\n /**\\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\\n */\\n function toString(int256 value) internal pure returns (string memory) {\\n return string(abi.encodePacked(value < 0 ? \\\"-\\\" : \\\"\\\", toString(SignedMath.abs(value))));\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n return toHexString(value, Math.log256(value) + 1);\\n }\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n\\n /**\\n * @dev Returns true if the two strings are equal.\\n */\\n function equal(string memory a, string memory b) internal pure returns (bool) {\\n return keccak256(bytes(a)) == keccak256(bytes(b));\\n }\\n}\\n\",\"keccak256\":\"0x3088eb2868e8d13d89d16670b5f8612c4ab9ff8956272837d8e90106c59c14a0\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Strings.sol\\\";\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSA {\\n enum RecoverError {\\n NoError,\\n InvalidSignature,\\n InvalidSignatureLength,\\n InvalidSignatureS,\\n InvalidSignatureV // Deprecated in v4.8\\n }\\n\\n function _throwError(RecoverError error) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert(\\\"ECDSA: invalid signature\\\");\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert(\\\"ECDSA: invalid signature length\\\");\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert(\\\"ECDSA: invalid signature 's' value\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature` or error string. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n *\\n * Documentation for signature generation:\\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n return tryRecover(hash, v, r, s);\\n } else {\\n return (address(0), RecoverError.InvalidSignatureLength);\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature`. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, signature);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\\n uint8 v = uint8((uint256(vs) >> 255) + 27);\\n return tryRecover(hash, v, r, s);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n *\\n * _Available since v4.2._\\n */\\n function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\\n // the valid range for s in (301): 0 < s < secp256k1n \\u00f7 2 + 1, and for v in (302): v \\u2208 {27, 28}. Most\\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\\n //\\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\\n // these malleable signatures as well.\\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n return (address(0), RecoverError.InvalidSignatureS);\\n }\\n\\n // If the signature is valid (and not malleable), return the signer address\\n address signer = ecrecover(hash, v, r, s);\\n if (signer == address(0)) {\\n return (address(0), RecoverError.InvalidSignature);\\n }\\n\\n return (signer, RecoverError.NoError);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore(0x00, \\\"\\\\x19Ethereum Signed Message:\\\\n32\\\")\\n mstore(0x1c, hash)\\n message := keccak256(0x00, 0x3c)\\n }\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from `s`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n\\\", Strings.toString(s.length), s));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Typed Data, created from a\\n * `domainSeparator` and a `structHash`. This produces hash corresponding\\n * to the one signed with the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n * JSON-RPC method as part of EIP-712.\\n *\\n * See {recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n let ptr := mload(0x40)\\n mstore(ptr, \\\"\\\\x19\\\\x01\\\")\\n mstore(add(ptr, 0x02), domainSeparator)\\n mstore(add(ptr, 0x22), structHash)\\n data := keccak256(ptr, 0x42)\\n }\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Data with intended validator, created from a\\n * `validator` and `data` according to the version 0 of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x00\\\", validator, data));\\n }\\n}\\n\",\"keccak256\":\"0x809bc3edb4bcbef8263fa616c1b60ee0004b50a8a1bfa164d8f57fd31f520c58\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n enum Rounding {\\n Down, // Toward negative infinity\\n Up, // Toward infinity\\n Zero // Toward zero\\n }\\n\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow.\\n return (a & b) + (a ^ b) / 2;\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a == 0 ? 0 : (a - 1) / b + 1;\\n }\\n\\n /**\\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\\n * with further edits by Uniswap Labs also under MIT license.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\\n unchecked {\\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2^256 + prod0.\\n uint256 prod0; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division.\\n if (prod1 == 0) {\\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\\n // The surrounding unchecked block does not change this fact.\\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\\n return prod0 / denominator;\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n require(denominator > prod1, \\\"Math: mulDiv overflow\\\");\\n\\n ///////////////////////////////////////////////\\n // 512 by 256 division.\\n ///////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0].\\n uint256 remainder;\\n assembly {\\n // Compute remainder using mulmod.\\n remainder := mulmod(x, y, denominator)\\n\\n // Subtract 256 bit number from 512 bit number.\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\\n // See https://cs.stackexchange.com/q/138556/92363.\\n\\n // Does not overflow because the denominator cannot be zero at this stage in the function.\\n uint256 twos = denominator & (~denominator + 1);\\n assembly {\\n // Divide denominator by twos.\\n denominator := div(denominator, twos)\\n\\n // Divide [prod1 prod0] by twos.\\n prod0 := div(prod0, twos)\\n\\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\\n twos := add(div(sub(0, twos), twos), 1)\\n }\\n\\n // Shift in bits from prod1 into prod0.\\n prod0 |= prod1 * twos;\\n\\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\\n // four bits. That is, denominator * inv = 1 mod 2^4.\\n uint256 inverse = (3 * denominator) ^ 2;\\n\\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\\n // in modular arithmetic, doubling the correct bits in each step.\\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\\n\\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inverse;\\n return result;\\n }\\n }\\n\\n /**\\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\\n uint256 result = mulDiv(x, y, denominator);\\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\\n result += 1;\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\\n *\\n * Inspired by Henry S. Warren, Jr.'s \\\"Hacker's Delight\\\" (Chapter 11).\\n */\\n function sqrt(uint256 a) internal pure returns (uint256) {\\n if (a == 0) {\\n return 0;\\n }\\n\\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\\n //\\n // We know that the \\\"msb\\\" (most significant bit) of our target number `a` is a power of 2 such that we have\\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\\n //\\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\\n // \\u2192 `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\\n // \\u2192 `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\\n //\\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\\n uint256 result = 1 << (log2(a) >> 1);\\n\\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\\n // into the expected uint128 result.\\n unchecked {\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n return min(result, a / result);\\n }\\n }\\n\\n /**\\n * @notice Calculates sqrt(a), following the selected rounding direction.\\n */\\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = sqrt(a);\\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 2, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 128;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 64;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 32;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 16;\\n }\\n if (value >> 8 > 0) {\\n value >>= 8;\\n result += 8;\\n }\\n if (value >> 4 > 0) {\\n value >>= 4;\\n result += 4;\\n }\\n if (value >> 2 > 0) {\\n value >>= 2;\\n result += 2;\\n }\\n if (value >> 1 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log2(value);\\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 10, rounded down, of a positive value.\\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 + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 256, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n *\\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\\n */\\n function log256(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 16;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 8;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 4;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 2;\\n }\\n if (value >> 8 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log256(value);\\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe4455ac1eb7fc497bb7402579e7b4d64d928b846fce7d2b6fde06d366f21c2b3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\\n * checks.\\n *\\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\\n * easily result in undesired exploitation or bugs, since developers usually\\n * assume that overflows raise errors. `SafeCast` restores this intuition by\\n * reverting the transaction when such an operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n *\\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\\n * all math on `uint256` and `int256` and then downcasting.\\n */\\nlibrary SafeCast {\\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 * _Available since v4.7._\\n */\\n function toUint248(uint256 value) internal pure returns (uint248) {\\n require(value <= type(uint248).max, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint240(uint256 value) internal pure returns (uint240) {\\n require(value <= type(uint240).max, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint232(uint256 value) internal pure returns (uint232) {\\n require(value <= type(uint232).max, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint224(uint256 value) internal pure returns (uint224) {\\n require(value <= type(uint224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint216(uint256 value) internal pure returns (uint216) {\\n require(value <= type(uint216).max, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint208(uint256 value) internal pure returns (uint208) {\\n require(value <= type(uint208).max, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint200(uint256 value) internal pure returns (uint200) {\\n require(value <= type(uint200).max, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint192(uint256 value) internal pure returns (uint192) {\\n require(value <= type(uint192).max, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint184(uint256 value) internal pure returns (uint184) {\\n require(value <= type(uint184).max, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint176(uint256 value) internal pure returns (uint176) {\\n require(value <= type(uint176).max, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint168(uint256 value) internal pure returns (uint168) {\\n require(value <= type(uint168).max, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint160(uint256 value) internal pure returns (uint160) {\\n require(value <= type(uint160).max, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint152(uint256 value) internal pure returns (uint152) {\\n require(value <= type(uint152).max, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint144(uint256 value) internal pure returns (uint144) {\\n require(value <= type(uint144).max, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint136(uint256 value) internal pure returns (uint136) {\\n require(value <= type(uint136).max, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint128(uint256 value) internal pure returns (uint128) {\\n require(value <= type(uint128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint120(uint256 value) internal pure returns (uint120) {\\n require(value <= type(uint120).max, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint112(uint256 value) internal pure returns (uint112) {\\n require(value <= type(uint112).max, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint104(uint256 value) internal pure returns (uint104) {\\n require(value <= type(uint104).max, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint96(uint256 value) internal pure returns (uint96) {\\n require(value <= type(uint96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint88(uint256 value) internal pure returns (uint88) {\\n require(value <= type(uint88).max, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint80(uint256 value) internal pure returns (uint80) {\\n require(value <= type(uint80).max, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint72(uint256 value) internal pure returns (uint72) {\\n require(value <= type(uint72).max, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint64(uint256 value) internal pure returns (uint64) {\\n require(value <= type(uint64).max, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint56(uint256 value) internal pure returns (uint56) {\\n require(value <= type(uint56).max, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint48(uint256 value) internal pure returns (uint48) {\\n require(value <= type(uint48).max, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint40(uint256 value) internal pure returns (uint40) {\\n require(value <= type(uint40).max, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint32(uint256 value) internal pure returns (uint32) {\\n require(value <= type(uint32).max, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint24(uint256 value) internal pure returns (uint24) {\\n require(value <= type(uint24).max, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint16(uint256 value) internal pure returns (uint16) {\\n require(value <= type(uint16).max, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint8(uint256 value) internal pure returns (uint8) {\\n require(value <= type(uint8).max, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\n */\\n function toUint256(int256 value) internal pure returns (uint256) {\\n require(value >= 0, \\\"SafeCast: value must be positive\\\");\\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 * _Available since v4.7._\\n */\\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\\n downcasted = int248(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\\n downcasted = int240(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\\n downcasted = int232(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\\n downcasted = int224(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\\n downcasted = int216(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\\n downcasted = int208(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\\n downcasted = int200(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\\n downcasted = int192(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\\n downcasted = int184(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\\n downcasted = int176(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\\n downcasted = int168(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\\n downcasted = int160(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\\n downcasted = int152(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\\n downcasted = int144(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\\n downcasted = int136(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\\n downcasted = int128(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\\n downcasted = int120(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\\n downcasted = int112(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\\n downcasted = int104(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\\n downcasted = int96(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\\n downcasted = int88(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\\n downcasted = int80(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\\n downcasted = int72(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\\n downcasted = int64(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\\n downcasted = int56(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\\n downcasted = int48(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\\n downcasted = int40(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\\n downcasted = int32(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\\n downcasted = int24(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\\n downcasted = int16(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\\n downcasted = int8(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\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 require(value <= uint256(type(int256).max), \\\"SafeCast: value doesn't fit in an int256\\\");\\n return int256(value);\\n }\\n}\\n\",\"keccak256\":\"0x52a8cfb0f5239d11b457dcdd1b326992ef672714ca8da71a157255bddd13f3ad\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SignedMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard signed math utilities missing in the Solidity language.\\n */\\nlibrary SignedMath {\\n /**\\n * @dev Returns the largest of two signed numbers.\\n */\\n function max(int256 a, int256 b) internal pure returns (int256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two signed numbers.\\n */\\n function min(int256 a, int256 b) internal pure returns (int256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two signed numbers without overflow.\\n * The result is rounded towards zero.\\n */\\n function average(int256 a, int256 b) internal pure returns (int256) {\\n // Formula from the book \\\"Hacker's Delight\\\"\\n int256 x = (a & b) + ((a ^ b) >> 1);\\n return x + (int256(uint256(x) >> 255) & (a ^ b));\\n }\\n\\n /**\\n * @dev Returns the absolute unsigned value of a signed value.\\n */\\n function abs(int256 n) internal pure returns (uint256) {\\n unchecked {\\n // must be unchecked in order to support `n = type(int256).min`\\n return uint256(n >= 0 ? n : -n);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf92515413956f529d95977adc9b0567d583c6203fc31ab1c23824c35187e3ddc\",\"license\":\"MIT\"},\"contracts/aa-4337/core/BaseAccount.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-empty-blocks */\\n\\nimport \\\"../interfaces/IAccount.sol\\\";\\nimport \\\"../interfaces/IEntryPoint.sol\\\";\\nimport \\\"./Helpers.sol\\\";\\n\\n/**\\n * Basic account implementation.\\n * this contract provides the basic logic for implementing the IAccount interface - validateUserOp\\n * specific account implementation should inherit it and provide the account-specific logic\\n */\\nabstract contract BaseAccount is IAccount {\\n using UserOperationLib for UserOperation;\\n\\n //return value in case of signature failure, with no time-range.\\n // equivalent to _packValidationData(true,0,0);\\n uint256 internal constant SIG_VALIDATION_FAILED = 1;\\n\\n /**\\n * Return the account nonce.\\n * This method returns the next sequential nonce.\\n * For a nonce of a specific key, use `entrypoint.getNonce(account, key)`\\n */\\n function getNonce() public view virtual returns (uint256) {\\n return entryPoint().getNonce(address(this), 0);\\n }\\n\\n /**\\n * return the entryPoint used by this account.\\n * subclass should return the current entryPoint used by this account.\\n */\\n function entryPoint() public view virtual returns (IEntryPoint);\\n\\n /**\\n * Validate user's signature and nonce.\\n * subclass doesn't need to override this method. Instead, it should override the specific internal validation methods.\\n */\\n function validateUserOp(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n uint256 missingAccountFunds\\n ) external virtual override returns (uint256 validationData) {\\n _requireFromEntryPoint();\\n validationData = _validateSignature(userOp, userOpHash);\\n _validateNonce(userOp.nonce);\\n _payPrefund(missingAccountFunds);\\n }\\n\\n /**\\n * ensure the request comes from the known entrypoint.\\n */\\n function _requireFromEntryPoint() internal view virtual {\\n require(\\n msg.sender == address(entryPoint()),\\n \\\"account: not from EntryPoint\\\"\\n );\\n }\\n\\n /**\\n * validate the signature is valid for this message.\\n * @param userOp validate the userOp.signature field\\n * @param userOpHash convenient field: the hash of the request, to check the signature against\\n * (also hashes the entrypoint and chain id)\\n * @return validationData signature and time-range of this operation\\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\\n * otherwise, an address of an \\\"authorizer\\\" contract.\\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \\\"indefinite\\\"\\n * <6-byte> validAfter - first timestamp this operation is valid\\n * If the account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\\n */\\n function _validateSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) internal virtual returns (uint256 validationData);\\n\\n /**\\n * Validate the nonce of the UserOperation.\\n * This method may validate the nonce requirement of this account.\\n * e.g.\\n * To limit the nonce to use sequenced UserOps only (no \\\"out of order\\\" UserOps):\\n * `require(nonce < type(uint64).max)`\\n * For a hypothetical account that *requires* the nonce to be out-of-order:\\n * `require(nonce & type(uint64).max == 0)`\\n *\\n * The actual nonce uniqueness is managed by the EntryPoint, and thus no other\\n * action is needed by the account itself.\\n *\\n * @param nonce to validate\\n *\\n * solhint-disable-next-line no-empty-blocks\\n */\\n function _validateNonce(uint256 nonce) internal view virtual {}\\n\\n /**\\n * sends to the entrypoint (msg.sender) the missing funds for this transaction.\\n * subclass MAY override this method for better funds management\\n * (e.g. send to the entryPoint more than the minimum required, so that in future transactions\\n * it will not be required to send again)\\n * @param missingAccountFunds the minimum value this method should send the entrypoint.\\n * this value MAY be zero, in case there is enough deposit, or the userOp has a paymaster.\\n */\\n function _payPrefund(uint256 missingAccountFunds) internal virtual {\\n if (missingAccountFunds != 0) {\\n (bool success, ) = payable(msg.sender).call{\\n value: missingAccountFunds,\\n gas: type(uint256).max\\n }(\\\"\\\");\\n (success);\\n //ignore failure (its EntryPoint's job to verify, not account.)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa0dcc386b0f04711db3e394fb50e55a3b3b1a4d19fac1f10895844e1aa4e3d5c\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/core/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable no-inline-assembly */\\n\\n/**\\n * returned data from validateUserOp.\\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\\n * @param aggregator - address(0) - the account validated the signature by itself.\\n * address(1) - the account failed to validate the signature.\\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\\n * @param validAfter - this UserOp is valid only after this timestamp.\\n * @param validaUntil - this UserOp is valid only up to this timestamp.\\n */\\nstruct ValidationData {\\n address aggregator;\\n uint48 validAfter;\\n uint48 validUntil;\\n}\\n\\n//extract sigFailed, validAfter, validUntil.\\n// also convert zero validUntil to type(uint48).max\\nfunction _parseValidationData(\\n uint validationData\\n) pure returns (ValidationData memory data) {\\n address aggregator = address(uint160(validationData));\\n uint48 validUntil = uint48(validationData >> 160);\\n if (validUntil == 0) {\\n validUntil = type(uint48).max;\\n }\\n uint48 validAfter = uint48(validationData >> (48 + 160));\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n// intersect account and paymaster ranges.\\nfunction _intersectTimeRange(\\n uint256 validationData,\\n uint256 paymasterValidationData\\n) pure returns (ValidationData memory) {\\n ValidationData memory accountValidationData = _parseValidationData(\\n validationData\\n );\\n ValidationData memory pmValidationData = _parseValidationData(\\n paymasterValidationData\\n );\\n address aggregator = accountValidationData.aggregator;\\n if (aggregator == address(0)) {\\n aggregator = pmValidationData.aggregator;\\n }\\n uint48 validAfter = accountValidationData.validAfter;\\n uint48 validUntil = accountValidationData.validUntil;\\n uint48 pmValidAfter = pmValidationData.validAfter;\\n uint48 pmValidUntil = pmValidationData.validUntil;\\n\\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp\\n * @param data - the ValidationData to pack\\n */\\nfunction _packValidationData(\\n ValidationData memory data\\n) pure returns (uint256) {\\n return\\n uint160(data.aggregator) |\\n (uint256(data.validUntil) << 160) |\\n (uint256(data.validAfter) << (160 + 48));\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp, when not using an aggregator\\n * @param sigFailed - true for signature failure, false for success\\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\\n * @param validAfter first timestamp this UserOperation is valid\\n */\\nfunction _packValidationData(\\n bool sigFailed,\\n uint48 validUntil,\\n uint48 validAfter\\n) pure returns (uint256) {\\n return\\n (sigFailed ? 1 : 0) |\\n (uint256(validUntil) << 160) |\\n (uint256(validAfter) << (160 + 48));\\n}\\n\\n/**\\n * keccak function over calldata.\\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\\n */\\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\\n assembly {\\n let mem := mload(0x40)\\n let len := data.length\\n calldatacopy(mem, data.offset, len)\\n ret := keccak256(mem, len)\\n }\\n}\\n\",\"keccak256\":\"0xa79f06cd158ecb8c0da95493a2f348933b8627a63e228b99738bff3aa107942d\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAccount.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\ninterface IAccount {\\n /**\\n * Validate user's signature and nonce\\n * the entryPoint will make the call to the recipient only if this validation call returns successfully.\\n * signature failure should be reported by returning SIG_VALIDATION_FAILED (1).\\n * This allows making a \\\"simulation call\\\" without a valid signature\\n * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure.\\n *\\n * @dev Must validate caller is the entryPoint.\\n * Must validate the signature and nonce\\n * @param userOp the operation that is about to be executed.\\n * @param userOpHash hash of the user's request data. can be used as the basis for signature.\\n * @param missingAccountFunds missing funds on the account's deposit in the entrypoint.\\n * This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call.\\n * The excess is left as a deposit in the entrypoint, for future calls.\\n * can be withdrawn anytime using \\\"entryPoint.withdrawTo()\\\"\\n * In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero.\\n * @return validationData packaged ValidationData structure. use `_packValidationData` and `_unpackValidationData` to encode and decode\\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\\n * otherwise, an address of an \\\"authorizer\\\" contract.\\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \\\"indefinite\\\"\\n * <6-byte> validAfter - first timestamp this operation is valid\\n * If an account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\\n */\\n function validateUserOp(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n uint256 missingAccountFunds\\n ) external returns (uint256 validationData);\\n}\\n\",\"keccak256\":\"0xcbc4b0973cf954c5895b7796335f651fbfcfb55f67dfa789a3d354f8e23c4f2b\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAggregator.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\n/**\\n * Aggregated Signatures validator.\\n */\\ninterface IAggregator {\\n /**\\n * validate aggregated signature.\\n * revert if the aggregated signature does not match the given list of operations.\\n */\\n function validateSignatures(\\n UserOperation[] calldata userOps,\\n bytes calldata signature\\n ) external view;\\n\\n /**\\n * validate signature of a single userOp\\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\\n * @param userOp the userOperation received from the user.\\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\\n * (usually empty, unless account and aggregator support some kind of \\\"multisig\\\"\\n */\\n function validateUserOpSignature(\\n UserOperation calldata userOp\\n ) external view returns (bytes memory sigForUserOp);\\n\\n /**\\n * aggregate multiple signatures into a single value.\\n * This method is called off-chain to calculate the signature to pass with handleOps()\\n * bundler MAY use optimized custom code perform this aggregation\\n * @param userOps array of UserOperations to collect the signatures from.\\n * @return aggregatedSignature the aggregated signature\\n */\\n function aggregateSignatures(\\n UserOperation[] calldata userOps\\n ) external view returns (bytes memory aggregatedSignature);\\n}\\n\",\"keccak256\":\"0xdfdcd80568f037716674619b31be630fcd8316262f05a815b41d1e81782c966a\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IEntryPoint.sol\":{\"content\":\"/**\\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\\n ** Only one instance required on each chain.\\n **/\\n// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-inline-assembly */\\n/* solhint-disable reason-string */\\n\\nimport \\\"./UserOperation.sol\\\";\\nimport \\\"./IStakeManager.sol\\\";\\nimport \\\"./IAggregator.sol\\\";\\nimport \\\"./INonceManager.sol\\\";\\n\\ninterface IEntryPoint is IStakeManager, INonceManager {\\n /***\\n * An event emitted after each successful request\\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\\n * @param sender - the account that generates this request.\\n * @param paymaster - if non-null, the paymaster that pays for this request.\\n * @param nonce - the nonce value from the request.\\n * @param success - true if the sender transaction succeeded, false if reverted.\\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\\n */\\n event UserOperationEvent(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address indexed paymaster,\\n uint256 nonce,\\n bool success,\\n uint256 actualGasCost,\\n uint256 actualGasUsed\\n );\\n\\n /**\\n * account \\\"sender\\\" was deployed.\\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\\n * @param sender the account that is deployed\\n * @param factory the factory used to deploy this account (in the initCode)\\n * @param paymaster the paymaster used by this UserOp\\n */\\n event AccountDeployed(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address factory,\\n address paymaster\\n );\\n\\n /**\\n * An event emitted if the UserOperation \\\"callData\\\" reverted with non-zero length\\n * @param userOpHash the request unique identifier.\\n * @param sender the sender of this request\\n * @param nonce the nonce used in the request\\n * @param revertReason - the return bytes from the (reverted) call to \\\"callData\\\".\\n */\\n event UserOperationRevertReason(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n uint256 nonce,\\n bytes revertReason\\n );\\n\\n /**\\n * an event emitted by handleOps(), before starting the execution loop.\\n * any event emitted before this event, is part of the validation.\\n */\\n event BeforeExecution();\\n\\n /**\\n * signature aggregator used by the following UserOperationEvents within this bundle.\\n */\\n event SignatureAggregatorChanged(address indexed aggregator);\\n\\n /**\\n * a custom revert error of handleOps, to identify the offending op.\\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\\n * @param reason - revert reason\\n * The string starts with a unique code \\\"AAmn\\\", where \\\"m\\\" is \\\"1\\\" for factory, \\\"2\\\" for account and \\\"3\\\" for paymaster issues,\\n * so a failure can be attributed to the correct entity.\\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\\n */\\n error FailedOp(uint256 opIndex, string reason);\\n\\n /**\\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\\n */\\n error SignatureValidationFailed(address aggregator);\\n\\n /**\\n * Successful result from simulateValidation.\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n */\\n error ValidationResult(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo\\n );\\n\\n /**\\n * Successful result from simulateValidation, if the account returns a signature aggregator\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\\n * bundler MUST use it to verify the signature, or reject the UserOperation\\n */\\n error ValidationResultWithAggregation(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo,\\n AggregatorStakeInfo aggregatorInfo\\n );\\n\\n /**\\n * return value of getSenderAddress\\n */\\n error SenderAddressResult(address sender);\\n\\n /**\\n * return value of simulateHandleOp\\n */\\n error ExecutionResult(\\n uint256 preOpGas,\\n uint256 paid,\\n uint48 validAfter,\\n uint48 validUntil,\\n bool targetSuccess,\\n bytes targetResult\\n );\\n\\n //UserOps handled, per aggregator\\n struct UserOpsPerAggregator {\\n UserOperation[] userOps;\\n // aggregator address\\n IAggregator aggregator;\\n // aggregated signature\\n bytes signature;\\n }\\n\\n /**\\n * Execute a batch of UserOperation.\\n * no signature aggregator is used.\\n * if any account requires an aggregator (that is, it returned an aggregator when\\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\\n * @param ops the operations to execute\\n * @param beneficiary the address to receive the fees\\n */\\n function handleOps(\\n UserOperation[] calldata ops,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * Execute a batch of UserOperation with Aggregators\\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\\n * @param beneficiary the address to receive the fees\\n */\\n function handleAggregatedOps(\\n UserOpsPerAggregator[] calldata opsPerAggregator,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * generate a request Id - unique identifier for this request.\\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\\n */\\n function getUserOpHash(\\n UserOperation calldata userOp\\n ) external view returns (bytes32);\\n\\n /**\\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\\n * @param userOp the user operation to validate.\\n */\\n function simulateValidation(UserOperation calldata userOp) external;\\n\\n /**\\n * gas and return values during simulation\\n * @param preOpGas the gas used for validation (including preValidationGas)\\n * @param prefund the required prefund for this operation\\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\\n */\\n struct ReturnInfo {\\n uint256 preOpGas;\\n uint256 prefund;\\n bool sigFailed;\\n uint48 validAfter;\\n uint48 validUntil;\\n bytes paymasterContext;\\n }\\n\\n /**\\n * returned aggregated signature info.\\n * the aggregator returned by the account, and its current stake.\\n */\\n struct AggregatorStakeInfo {\\n address aggregator;\\n StakeInfo stakeInfo;\\n }\\n\\n /**\\n * Get counterfactual sender address.\\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\\n * this method always revert, and returns the address in SenderAddressResult error\\n * @param initCode the constructor code to be passed into the UserOperation.\\n */\\n function getSenderAddress(bytes memory initCode) external;\\n\\n /**\\n * simulate full execution of a UserOperation (including both validation and target execution)\\n * this method will always revert with \\\"ExecutionResult\\\".\\n * it performs full validation of the UserOperation, but ignores signature error.\\n * an optional target address is called after the userop succeeds, and its value is returned\\n * (before the entire call is reverted)\\n * Note that in order to collect the the success/failure of the target call, it must be executed\\n * with trace enabled to track the emitted events.\\n * @param op the UserOperation to simulate\\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\\n * are set to the return from that call.\\n * @param targetCallData callData to pass to target address\\n */\\n function simulateHandleOp(\\n UserOperation calldata op,\\n address target,\\n bytes calldata targetCallData\\n ) external;\\n}\\n\",\"keccak256\":\"0x9ccb1b188eda8bbf5f6c2d01bd83c3d8b2b04fcf745283051d31fe96d1d8e40f\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/INonceManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\ninterface INonceManager {\\n /**\\n * Return the next nonce for this sender.\\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\\n * But UserOp with different keys can come with arbitrary order.\\n *\\n * @param sender the account address\\n * @param key the high 192 bit of the nonce\\n * @return nonce a full nonce to pass for next UserOp with this sender.\\n */\\n function getNonce(\\n address sender,\\n uint192 key\\n ) external view returns (uint256 nonce);\\n\\n /**\\n * Manually increment the nonce of the sender.\\n * This method is exposed just for completeness..\\n * Account does NOT need to call it, neither during validation, nor elsewhere,\\n * as the EntryPoint will update the nonce regardless.\\n * Possible use-case is call it with various keys to \\\"initialize\\\" their nonces to one, so that future\\n * UserOperations will not pay extra for the first transaction with a given key.\\n */\\n function incrementNonce(uint192 key) external;\\n}\\n\",\"keccak256\":\"0xce478ad0fa0d18a3b785ac854623029e7ab463d05873dfaa365abfa1bf100912\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IStakeManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8.12;\\n\\n/**\\n * manage deposits and stakes.\\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\\n * stake is value locked for at least \\\"unstakeDelay\\\" by the staked entity.\\n */\\ninterface IStakeManager {\\n event Deposited(address indexed account, uint256 totalDeposit);\\n\\n event Withdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /// Emitted when stake or unstake delay are modified\\n event StakeLocked(\\n address indexed account,\\n uint256 totalStaked,\\n uint256 unstakeDelaySec\\n );\\n\\n /// Emitted once a stake is scheduled for withdrawal\\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\\n\\n event StakeWithdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /**\\n * @param deposit the entity's deposit\\n * @param staked true if this entity is staked.\\n * @param stake actual amount of ether staked for this entity.\\n * @param unstakeDelaySec minimum delay to withdraw the stake.\\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\\n * and the rest fit into a 2nd cell.\\n * 112 bit allows for 10^15 eth\\n * 48 bit for full timestamp\\n * 32 bit allows 150 years for unstake delay\\n */\\n struct DepositInfo {\\n uint112 deposit;\\n bool staked;\\n uint112 stake;\\n uint32 unstakeDelaySec;\\n uint48 withdrawTime;\\n }\\n\\n //API struct used by getStakeInfo and simulateValidation\\n struct StakeInfo {\\n uint256 stake;\\n uint256 unstakeDelaySec;\\n }\\n\\n /// @return info - full deposit information of given account\\n function getDepositInfo(\\n address account\\n ) external view returns (DepositInfo memory info);\\n\\n /// @return the deposit (for gas payment) of the account\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * add to the deposit of the given account\\n */\\n function depositTo(address account) external payable;\\n\\n /**\\n * add to the account's stake - amount and delay\\n * any pending unstake is first cancelled.\\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\\n */\\n function addStake(uint32 _unstakeDelaySec) external payable;\\n\\n /**\\n * attempt to unlock the stake.\\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\\n */\\n function unlockStake() external;\\n\\n /**\\n * withdraw from the (unlocked) stake.\\n * must first call unlockStake and wait for the unstakeDelay to pass\\n * @param withdrawAddress the address to send withdrawn value.\\n */\\n function withdrawStake(address payable withdrawAddress) external;\\n\\n /**\\n * withdraw from the deposit.\\n * @param withdrawAddress the address to send withdrawn value.\\n * @param withdrawAmount the amount to withdraw.\\n */\\n function withdrawTo(\\n address payable withdrawAddress,\\n uint256 withdrawAmount\\n ) external;\\n}\\n\",\"keccak256\":\"0xadcea606c9b7aafe6645441f2154a60f271330b0eee5292a632aa71c1672d546\",\"license\":\"GPL-3.0-only\"},\"contracts/aa-4337/interfaces/UserOperation.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable no-inline-assembly */\\n\\nimport {calldataKeccak} from \\\"../core/Helpers.sol\\\";\\n\\n/**\\n * User Operation struct\\n * @param sender the sender account of this request.\\n * @param nonce unique value the sender uses to verify it is not a replay.\\n * @param initCode if set, the account contract will be created by this constructor/\\n * @param callData the method call to execute on this account.\\n * @param callGasLimit the gas limit passed to the callData method call.\\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\\n * @param maxFeePerGas same as EIP-1559 gas parameter.\\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\\n */\\nstruct UserOperation {\\n address sender;\\n uint256 nonce;\\n bytes initCode;\\n bytes callData;\\n uint256 callGasLimit;\\n uint256 verificationGasLimit;\\n uint256 preVerificationGas;\\n uint256 maxFeePerGas;\\n uint256 maxPriorityFeePerGas;\\n bytes paymasterAndData;\\n bytes signature;\\n}\\n\\n/**\\n * Utility functions helpful when working with UserOperation structs.\\n */\\nlibrary UserOperationLib {\\n function getSender(\\n UserOperation calldata userOp\\n ) internal pure returns (address) {\\n address data;\\n //read sender from userOp, which is first userOp member (saves 800 gas...)\\n assembly {\\n data := calldataload(userOp)\\n }\\n return address(uint160(data));\\n }\\n\\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\\n // pay above what he signed for.\\n function gasPrice(\\n UserOperation calldata userOp\\n ) internal view returns (uint256) {\\n unchecked {\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n if (maxFeePerGas == maxPriorityFeePerGas) {\\n //legacy mode (for networks that don't support basefee opcode)\\n return maxFeePerGas;\\n }\\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\\n }\\n }\\n\\n function pack(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes memory ret) {\\n address sender = getSender(userOp);\\n uint256 nonce = userOp.nonce;\\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\\n bytes32 hashCallData = calldataKeccak(userOp.callData);\\n uint256 callGasLimit = userOp.callGasLimit;\\n uint256 verificationGasLimit = userOp.verificationGasLimit;\\n uint256 preVerificationGas = userOp.preVerificationGas;\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\\n\\n return\\n abi.encode(\\n sender,\\n nonce,\\n hashInitCode,\\n hashCallData,\\n callGasLimit,\\n verificationGasLimit,\\n preVerificationGas,\\n maxFeePerGas,\\n maxPriorityFeePerGas,\\n hashPaymasterAndData\\n );\\n }\\n\\n function hash(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes32) {\\n return keccak256(pack(userOp));\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n}\\n\",\"keccak256\":\"0x2429f5cc546bdee08c7e63858d0dda8491eaa3ab5194df884dc948c1154d2834\",\"license\":\"GPL-3.0\"},\"contracts/facets/AccountFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {ECDSA} from \\\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\\\";\\nimport {UserOperation} from \\\"../aa-4337/interfaces/UserOperation.sol\\\";\\nimport {IEntryPoint} from \\\"../aa-4337/interfaces/IEntryPoint.sol\\\";\\nimport {BaseAccount} from \\\"../aa-4337/core/BaseAccount.sol\\\";\\nimport {LibAppStorage, BarzStorage} from \\\"../libraries/LibAppStorage.sol\\\";\\nimport {LibDiamond} from \\\"../libraries/LibDiamond.sol\\\";\\nimport {LibLoupe} from \\\"../libraries/LibLoupe.sol\\\";\\nimport {IFacetRegistry} from \\\"../infrastructure/interfaces/IFacetRegistry.sol\\\";\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\nimport {IVerificationFacet} from \\\"./interfaces/IVerificationFacet.sol\\\";\\nimport {IERC1271} from \\\"../interfaces/ERC/IERC1271.sol\\\";\\nimport {IAccountFacet} from \\\"./interfaces/IAccountFacet.sol\\\";\\n\\n/**\\n * @title Account Facet\\n * @dev Account module contract that provides the account features and initialization of signer\\n * compatible with EIP-1271 & EIP-4337\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract AccountFacet is IAccountFacet, BarzStorage, BaseAccount {\\n using ECDSA for bytes32;\\n\\n /**\\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\\n */\\n constructor() {\\n LibAppStorage.enforceAccountInitialize();\\n }\\n\\n /**\\n * @notice Returns the address of EntryPoint contract registered to Barz account\\n */\\n function entryPoint() public view override returns (IEntryPoint) {\\n return s.entryPoint;\\n }\\n\\n /**\\n * @notice Initializes the initial storage of the Barz contract.\\n * @dev This method can only be called during the initialization or signature migration.\\n * If the proxy contract was created without initialization, anyone can call initialize.\\n * Barz calls initialize in constructor in an atomic transaction during deployment\\n * @param _verificationFacet Facet contract handling the verificationi\\n * @param _anEntryPoint Entrypoint contract defined in EIP-4337 handling the flow of UserOp\\n * @param _facetRegistry Registry of Facets that hold all facet information\\n * @param _defaultFallBackHandler Middleware contract for default facets\\n * @param _ownerPublicKey Bytes of owner public key\\n */\\n function initialize(\\n address _verificationFacet,\\n address _anEntryPoint,\\n address _facetRegistry,\\n address _defaultFallBackHandler,\\n bytes calldata _ownerPublicKey\\n ) public override returns (uint256 initSuccess) {\\n LibAppStorage.enforceAccountInitialize();\\n s.entryPoint = IEntryPoint(_anEntryPoint);\\n s.facetRegistry = IFacetRegistry(_facetRegistry);\\n LibDiamond.diamondStorage().defaultFallbackHandler = IDiamondLoupe(\\n _defaultFallBackHandler\\n );\\n\\n _cutDiamondAccountFacet(_verificationFacet);\\n\\n bytes memory initCall = abi.encodeWithSignature(\\n \\\"initializeSigner(bytes)\\\",\\n _ownerPublicKey\\n );\\n // Every Verification Facet should comply with initializeSigner(bytes)\\n // to be compatible with the Barz contract(for initialization)\\n (bool success, bytes memory result) = _verificationFacet.delegatecall(\\n initCall\\n );\\n if (!success || uint256(bytes32(result)) != 1) {\\n revert AccountFacet__InitializationFailure();\\n }\\n\\n initSuccess = 1;\\n emit AccountInitialized(s.entryPoint, _ownerPublicKey);\\n }\\n\\n function _cutDiamondAccountFacet(address _verificationFacet) internal {\\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](1);\\n\\n bytes4 ownerVerificationFuncSelector = IVerificationFacet(\\n _verificationFacet\\n ).validateOwnerSignatureSelector();\\n\\n bytes4[] memory verificationFunctionSelectors = new bytes4[](3);\\n verificationFunctionSelectors[0] = IERC1271.isValidSignature.selector;\\n verificationFunctionSelectors[1] = ownerVerificationFuncSelector;\\n verificationFunctionSelectors[2] = IVerificationFacet.owner.selector;\\n cut[0] = IDiamondCut.FacetCut({\\n facetAddress: _verificationFacet,\\n action: IDiamondCut.FacetCutAction.Add,\\n functionSelectors: verificationFunctionSelectors\\n });\\n\\n LibDiamond.diamondCut(cut, address(0), \\\"\\\");\\n }\\n\\n /**\\n * @notice Calls the destination with inputted calldata and value from EntryPoint\\n * @dev This method executes the calldata coming from the EntryPoint.\\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\\n * @param _dest Address of destination where the call will be forwarded to\\n * @param _value Amount of native coin the owner is willing to send(e.g. ETH, BNB)\\n * @param _func Bytes of calldata to execute in the destination address\\n */\\n function execute(\\n address _dest,\\n uint256 _value,\\n bytes calldata _func\\n ) external override onlyWhenUnlocked {\\n _requireFromEntryPoint();\\n address restrictionsFacet = LibDiamond.restrictionsFacet();\\n if (restrictionsFacet == address(0)) _call(_dest, _value, _func);\\n else _callWithRestrictions(_dest, _value, _func, restrictionsFacet);\\n }\\n\\n /**\\n * @notice Batch calls the destination with inputted calldata and value from EntryPoint\\n * @dev This method batch executes the calldata coming from the EntryPoint.\\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\\n * @param _dest Array of addresses of destination where the call will be forwarded to\\n * @param _value Array of amount of native coin the owner is willing to send(e.g. ETH, BNB)\\n * @param _func Array of bytes of calldata to execute in the destination address\\n */\\n function executeBatch(\\n address[] calldata _dest,\\n uint256[] calldata _value,\\n bytes[] calldata _func\\n ) external override onlyWhenUnlocked {\\n _requireFromEntryPoint();\\n if (_dest.length != _func.length || _dest.length != _value.length)\\n revert AccountFacet__InvalidArrayLength();\\n address restrictionsFacet = LibDiamond.restrictionsFacet();\\n if (restrictionsFacet == address(0)) {\\n for (uint256 i; i < _dest.length; ) {\\n _call(_dest[i], _value[i], _func[i]);\\n unchecked {\\n ++i;\\n }\\n }\\n } else {\\n for (uint256 i; i < _dest.length; ) {\\n _callWithRestrictions(\\n _dest[i],\\n _value[i],\\n _func[i],\\n restrictionsFacet\\n );\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n }\\n\\n /**\\n * @notice Validates the signature field of UserOperation\\n * @dev This method validates if the signature of UserOp is indeed valid by delegating the call to Verification Facet\\n * Barz makes a call to the pre-registered Verification Facet address in App Storage\\n * @param _userOp UserOperation from owner to be validated\\n * @param _userOpHash Hash of UserOperation given from the EntryPoint contract\\n */\\n function _validateSignature(\\n UserOperation calldata _userOp,\\n bytes32 _userOpHash\\n ) internal override returns (uint256 validationData) {\\n // Get Facet with Function Selector\\n address facet = LibLoupe.facetAddress(s.validateOwnerSignatureSelector);\\n if (facet == address(0))\\n revert AccountFacet__NonExistentVerificationFacet();\\n\\n // Make function call to VerificationFacet\\n bytes memory validateCall = abi.encodeWithSelector(\\n s.validateOwnerSignatureSelector,\\n _userOp,\\n _userOpHash\\n );\\n (bool success, bytes memory result) = facet.delegatecall(validateCall);\\n if (!success) revert AccountFacet__CallNotSuccessful();\\n validationData = uint256(bytes32(result));\\n if (validationData == 0) emit VerificationSuccess(_userOpHash);\\n else emit VerificationFailure(_userOpHash);\\n }\\n\\n /**\\n * @notice Calls the target with the inputted value and calldata\\n * @dev This method is the actual function in Barz that makes a call with an arbitrary owner-given data\\n * @param _target Address of the destination contract which the call is getting forwarded to\\n * @param _value Amount of Native coin the owner is wanting to make in this call\\n * @param _data Calldata the owner is forwarding together in the call e.g. Swap/Token Transfer\\n */\\n function _call(\\n address _target,\\n uint256 _value,\\n bytes memory _data\\n ) internal {\\n (bool success, bytes memory result) = _target.call{value: _value}(\\n _data\\n );\\n if (!success) {\\n assembly {\\n revert(add(result, 32), mload(result))\\n }\\n }\\n }\\n\\n /**\\n * @notice Calls the target with the inputted value and calldata together with restrictions check\\n * @dev This method is the actual function in Barz that makes a call with an arbitrary owner-given data\\n * @param _target Address of the destination contract which the call is getting forwarded to\\n * @param _value Amount of Native coin the owner is wanting to make in this call\\n * @param _data Calldata the owner is forwarding together in the call e.g. Swap/Token Transfer\\n * @param _restrictionsFacet Address of Facet to validate restrictions\\n */\\n function _callWithRestrictions(\\n address _target,\\n uint256 _value,\\n bytes memory _data,\\n address _restrictionsFacet\\n ) internal {\\n // NOTE: No restrictions facet, so restriction validation passes\\n if (_checkRestrictions(_restrictionsFacet, _target, _value, _data) != 0)\\n revert AccountFacet__RestrictionsFailure();\\n\\n (bool success, bytes memory result) = _target.call{value: _value}(\\n _data\\n );\\n if (!success) {\\n assembly {\\n revert(add(result, 32), mload(result))\\n }\\n }\\n }\\n\\n /**\\n * @notice Checks restrictions if the restrictions facet exists\\n * @dev This method checks if the restrictions facet exists and makes a verification call to an array of restrictions facet\\n * @param _facet Address that holds the restrictions logic\\n * @param _target Address the call is getting forwarded to\\n * @param _value Amount of native coin the call is sending together with the call\\n * @param _data Calldata to trigger execution in target address\\n */\\n function _checkRestrictions(\\n address _facet,\\n address _target,\\n uint256 _value,\\n bytes memory _data\\n ) internal returns (uint256 result) {\\n bytes memory call = abi.encodeWithSignature(\\n \\\"verifyRestrictions(address,address,uint256,bytes)\\\",\\n address(this),\\n _target,\\n _value,\\n _data\\n );\\n (bool success, bytes memory response) = _facet.delegatecall(call);\\n if (!success) revert AccountFacet__RestrictionsFailure();\\n result = uint256(bytes32(response));\\n }\\n}\\n\",\"keccak256\":\"0xcd92bcdd447010880f78e57e213123269c9e023adfc0a540608daa127d8649ca\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/facets/interfaces/IAccountFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IEntryPoint} from \\\"../../aa-4337/interfaces/IEntryPoint.sol\\\";\\n\\n/**\\n * @title Account Facet Interface\\n * @dev Interface of module contract that provides the account features and init/unitialization of signer\\n * compatible with EIP-1271 & EIP-4337\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IAccountFacet {\\n event AccountInitialized(\\n IEntryPoint indexed entryPoint,\\n bytes indexed ownerPublicKey\\n );\\n // NOTE: Added Below Event\\n event VerificationSuccess(bytes32);\\n event VerificationFailure(bytes32);\\n\\n error AccountFacet__InitializationFailure();\\n error AccountFacet__RestrictionsFailure();\\n error AccountFacet__NonExistentVerificationFacet();\\n error AccountFacet__CallNotSuccessful();\\n error AccountFacet__InvalidArrayLength();\\n\\n function initialize(\\n address verificationFacet,\\n address anEntryPoint,\\n address facetRegistry,\\n address _defaultFallBack,\\n bytes calldata _ownerPublicKey\\n ) external returns (uint256);\\n\\n function execute(address dest, uint256 value, bytes calldata func) external;\\n\\n function executeBatch(\\n address[] calldata dest,\\n uint256[] calldata value,\\n bytes[] calldata func\\n ) external;\\n}\\n\",\"keccak256\":\"0x74a9cb0b8f2f4a5148e366a401a0354426c536c012c025025d07cc25a4cd5382\",\"license\":\"Apache-2.0\"},\"contracts/facets/interfaces/IVerificationFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {UserOperation} from \\\"../../aa-4337/interfaces/UserOperation.sol\\\";\\n\\n/**\\n * @title Verification Facet Interface\\n * @dev Implements logic for user ops signature verification\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\ninterface IVerificationFacet {\\n event SignerInitialized(bytes);\\n event SignerUninitialized();\\n\\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\\n error VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\\n error VerificationFacet__InitializationFailure();\\n error VerificationFacet__InvalidFacetMapping();\\n\\n function initializeSigner(bytes memory) external returns (uint256);\\n\\n function uninitializeSigner() external returns (uint256);\\n\\n function validateOwnerSignatureSelector() external view returns (bytes4);\\n\\n function owner() external view returns (bytes memory);\\n\\n function isValidKeyType(bytes calldata) external view returns (bool);\\n\\n function validateOwnerSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x72bc370a1d1b5a6d6bde67f5026733fd8f6ba434bb90e73b0bd8627fb1579928\",\"license\":\"Apache-2.0\"},\"contracts/infrastructure/interfaces/IFacetRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Registry Interface\\n * @dev Interface for Facet Registry contract to keep track of facets & function selectors addable to user wallets\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IFacetRegistry {\\n struct FacetRegistryConfig {\\n bytes4[] selectors;\\n mapping(bytes4 => FacetInfo) info;\\n }\\n struct FacetInfo {\\n bool exists;\\n uint128 index;\\n }\\n\\n event FacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] facetSelectors\\n );\\n event FacetFunctionSelectorsRemoved(address facet, bytes4[] facetSelectors);\\n\\n error FacetRegistry__FacetSelectorAlreadyRegistered();\\n error FacetRegistry__UnregisteredFacetSelector();\\n\\n function registerFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function removeFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function areFacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external view returns (bool);\\n\\n function isFacetFunctionSelectorRegistered(\\n address facet,\\n bytes4 facetSelector\\n ) external view returns (bool);\\n\\n function getFacetFunctionSelectors(\\n address facet\\n ) external view returns (bytes4[] memory);\\n}\\n\",\"keccak256\":\"0x6e6dd2cab346ef7c31230740ec48d2925e4a9ab24c2f2fb268baaf408dcf02ef\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC1271 {\\n function isValidSignature(\\n bytes32 hash,\\n bytes memory signature\\n ) external view returns (bytes4);\\n}\\n\",\"keccak256\":\"0xcdddb7d5641c9d3f2432dec7fd13fddb9ae1480f25c76c21511e2fa16b8bd422\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibAppStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {SafeCast} from \\\"@openzeppelin/contracts/utils/math/SafeCast.sol\\\";\\nimport {IEntryPoint} from \\\"../aa-4337/interfaces/IEntryPoint.sol\\\";\\nimport {IFacetRegistry} from \\\"../infrastructure/interfaces/IFacetRegistry.sol\\\";\\n\\n/*\\n * @title App Storage\\n * @dev App storage for Barz contract to prevent storage collision\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Lock {\\n uint64 release;\\n bytes4 locker;\\n}\\n\\nstruct InitializersStorage {\\n // NOTE: initialized is a variable to make sure the initialization is only done once.\\n uint8 signerInitialized;\\n uint8 accountInitialized;\\n uint8 restrictionsInitialized;\\n}\\n\\nstruct AppStorage {\\n mapping(uint256 => InitializersStorage) initStorage;\\n uint8 signerMigration;\\n bytes4 validateOwnerSignatureSelector;\\n IEntryPoint entryPoint;\\n IFacetRegistry facetRegistry;\\n mapping(uint256 => Lock) locks;\\n}\\n\\nlibrary LibAppStorage {\\n error LibAppStorage__AccountAlreadyUninitialized();\\n error LibAppStorage__AccountMustBeUninitialized();\\n error LibAppStorage__SignerAlreadyUninitialized();\\n error LibAppStorage__SignerMustBeUninitialized();\\n\\n function appStorage() internal pure returns (AppStorage storage ds) {\\n assembly {\\n ds.slot := 0\\n }\\n }\\n\\n function setSignerUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerAlreadyUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 0;\\n }\\n\\n function getValidateOwnerSignatureSelector()\\n internal\\n view\\n returns (bytes4 selector)\\n {\\n selector = appStorage().validateOwnerSignatureSelector;\\n }\\n\\n function setValidateOwnerSignatureSelector(\\n bytes4 _validateOwnerSignatureSelector\\n ) internal {\\n appStorage()\\n .validateOwnerSignatureSelector = _validateOwnerSignatureSelector;\\n }\\n\\n function enforceSignerInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerMustBeUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 1;\\n }\\n\\n function enforceAccountInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].accountInitialized) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n s.initStorage[0].accountInitialized = 1;\\n }\\n\\n function initiateSignerMigration() internal {\\n appStorage().signerMigration = 1;\\n }\\n\\n function enforceSignerMigration() internal view {\\n if (1 != appStorage().signerMigration) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n }\\n\\n function finalizeSignerMigration() internal {\\n appStorage().signerMigration = 0;\\n }\\n\\n function setLock(uint256 _releaseAfter, bytes4 _locker) internal {\\n appStorage().locks[0] = Lock(SafeCast.toUint64(_releaseAfter), _locker);\\n }\\n\\n function enforceRestrictionsInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__SignerMustBeUninitialized();\\n s.initStorage[0].restrictionsInitialized = 1;\\n }\\n\\n function setRestrictionsUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__AccountAlreadyUninitialized();\\n s.initStorage[0].restrictionsInitialized = 0;\\n }\\n}\\n\\ncontract BarzStorage {\\n AppStorage internal s;\\n modifier onlyWhenUnlocked() {\\n require(\\n uint64(block.timestamp) >= s.locks[0].release,\\n \\\"Account Locked\\\"\\n );\\n _;\\n }\\n modifier onlyWhenLocked() {\\n require(\\n uint64(block.timestamp) < s.locks[0].release,\\n \\\"Account Unlocked\\\"\\n );\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x48524007862a6ce0e07f645950613ce6513ce073c37a109c75019683d42bae27\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\\n bytes4(keccak256(\\\"verifyRestrictions(address,address,uint256,bytes)\\\"));\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // Default Fallback Handler of the barz.\\n IDiamondLoupe defaultFallbackHandler;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function enforceIsSelf() internal view {\\n require(msg.sender == address(this), \\\"LibDiamond: Caller not self\\\");\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n\\n unchecked {\\n facetIndex++;\\n }\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n\\n function restrictionsFacet() internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(\\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2cabdc00de859c3a3170ce3bda5d0e5fd3933d47ce904fd1585f9818b02572f8\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\nimport {LibDiamond} from \\\"./LibDiamond.sol\\\";\\n\\n/**\\n * @title LibLoupe\\n * @dev Internal Library to provide utility feature for reading the state of diamond facets\\n * Originally from Diamond's implementation of Mudgen(author of EIP-2535)\\n */\\nlibrary LibLoupe {\\n /// @notice Gets all facets and their selectors.\\n /// @return facets_ Facet\\n function facets()\\n internal\\n view\\n returns (IDiamondLoupe.Facet[] memory facets_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facets_ = new IDiamondLoupe.Facet[](ds.selectorCount);\\n uint16[] memory numFacetSelectors = new uint16[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facets_[facetIndex].facetAddress == facetAddress_) {\\n facets_[facetIndex].functionSelectors[\\n numFacetSelectors[facetIndex]\\n ] = selector;\\n // probably will never have more than 256 functions from one facet contract\\n require(numFacetSelectors[facetIndex] < 255);\\n numFacetSelectors[facetIndex]++;\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facets_[numFacets].facetAddress = facetAddress_;\\n facets_[numFacets].functionSelectors = new bytes4[](\\n ds.selectorCount\\n );\\n facets_[numFacets].functionSelectors[0] = selector;\\n numFacetSelectors[numFacets] = 1;\\n numFacets++;\\n }\\n }\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n uint256 numSelectors = numFacetSelectors[facetIndex];\\n bytes4[] memory selectors = facets_[facetIndex].functionSelectors;\\n // setting the number of selectors\\n assembly {\\n mstore(selectors, numSelectors)\\n }\\n }\\n // setting the number of facets\\n assembly {\\n mstore(facets_, numFacets)\\n }\\n }\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return _facetFunctionSelectors The selectors associated with a facet address.\\n function facetFunctionSelectors(\\n address _facet\\n ) internal view returns (bytes4[] memory _facetFunctionSelectors) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n uint256 numSelectors;\\n _facetFunctionSelectors = new bytes4[](ds.selectorCount);\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facet = address(bytes20(ds.facets[selector]));\\n if (_facet == facet) {\\n _facetFunctionSelectors[numSelectors] = selector;\\n numSelectors++;\\n }\\n }\\n }\\n // Set the number of selectors in the array\\n assembly {\\n mstore(_facetFunctionSelectors, numSelectors)\\n }\\n }\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n internal\\n view\\n returns (address[] memory facetAddresses_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetAddresses_ = new address[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facetAddress_ == facetAddresses_[facetIndex]) {\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facetAddresses_[numFacets] = facetAddress_;\\n numFacets++;\\n }\\n }\\n // Set the number of facet addresses in the array\\n assembly {\\n mstore(facetAddresses_, numFacets)\\n }\\n }\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(LibDiamond.diamondStorage().facets[_functionSelector])\\n );\\n }\\n}\\n\",\"keccak256\":\"0x0b11439c3cc657095e15ec2241fdcf67204b14001357b612fc5db4ff9e760a5a\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5061001961001e565b61008e565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb554610100900460ff1615610070576040516338fc28cb60e01b815260040160405180910390fd5b600080805260209190915260409020805461ff001916610100179055565b6129b6806200009e6000396000f3fe608060405234801561001057600080fd5b50600436106100725760003560e01c8063b0d691fe11610050578063b0d691fe146100c5578063b61d27f61461010c578063d087d2881461011f57600080fd5b80633a871cdd1461007757806347e1da2a1461009d5780634a936417146100b2575b600080fd5b61008a610085366004611fb5565b610127565b6040519081526020015b60405180910390f35b6100b06100ab366004612055565b61014d565b005b61008a6100c036600461215a565b610450565b60015465010000000000900473ffffffffffffffffffffffffffffffffffffffff1660405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610094565b6100b061011a3660046121ce565b6106d0565b61008a61089d565b600061013161095e565b61013b8484610a16565b905061014682610c5d565b9392505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff9081164290911610156101f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064015b60405180910390fd5b6101fd61095e565b848114158061020c5750848314155b15610243576040517fdde5716100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006102b87fac87185d000000000000000000000000000000000000000000000000000000006000527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020527f6d9f2463c8c0d8cb8be556a773ab21d4321328909a1725f2ef7cae0c320e95da5460601c90565b905073ffffffffffffffffffffffffffffffffffffffff811661038f5760005b86811015610389576103818888838181106102f5576102f5612228565b905060200201602081019061030a9190612257565b87878481811061031c5761031c612228565b9050602002013586868581811061033557610335612228565b90506020028101906103479190612272565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610cc892505050565b6001016102d8565b50610447565b60005b868110156104455761043d8888838181106103af576103af612228565b90506020020160208101906103c49190612257565b8787848181106103d6576103d6612228565b905060200201358686858181106103ef576103ef612228565b90506020028101906104019190612272565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250889250610d45915050565b600101610392565b505b50505050505050565b600061045a610e0d565b6001805473ffffffffffffffffffffffffffffffffffffffff88811665010000000000027fffffffffffffff0000000000000000000000000000000000000000ffffffffff90921691909117909155600280548783167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216179091557f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd492380549287169290911691909117905561051187610eb3565b60008383604051602401610526929190612320565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fcd9b47e40000000000000000000000000000000000000000000000000000000017905251909150600090819073ffffffffffffffffffffffffffffffffffffffff8b16906105c8908590612360565b600060405180830381855af49150503d8060008114610603576040519150601f19603f3d011682016040523d82523d6000602084013e610608565b606091505b5091509150811580610623575061061e8161237c565b600114155b1561065a576040517f1602372100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60019350858560405161066e9291906123c1565b60405190819003812060015490916501000000000090910473ffffffffffffffffffffffffffffffffffffffff16907fd429ff0b972be4ae725700a373d05007287994e4c86cb83315b43ffa85b595fd90600090a35050509695505050505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610773576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064016101ec565b61077b61095e565b60006107f07fac87185d000000000000000000000000000000000000000000000000000000006000527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020527f6d9f2463c8c0d8cb8be556a773ab21d4321328909a1725f2ef7cae0c320e95da5460601c90565b905073ffffffffffffffffffffffffffffffffffffffff81166108535761084e858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610cc892505050565b610896565b610896858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250879250610d45915050565b5050505050565b60015460009065010000000000900473ffffffffffffffffffffffffffffffffffffffff166040517f35567e1a0000000000000000000000000000000000000000000000000000000081523060048201526000602482015273ffffffffffffffffffffffffffffffffffffffff91909116906335567e1a90604401602060405180830381865afa158015610935573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061095991906123d1565b905090565b60015465010000000000900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a14576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f6163636f756e743a206e6f742066726f6d20456e747279506f696e740000000060448201526064016101ec565b565b600154610100900460e01b7fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604081205460601c80610aab576040517f6eb2360200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600154604051600091610100900460e01b90610acd908790879060240161244e565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090506000808373ffffffffffffffffffffffffffffffffffffffff1683604051610b549190612360565b600060405180830381855af49150503d8060008114610b8f576040519150601f19603f3d011682016040523d82523d6000602084013e610b94565b606091505b509150915081610bd0576040517f3cbbb65000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610bd98161237c565b94506000859003610c1c576040518681527f19e781916118c373dadcb7776fae0a2dbb6bbdeedae143ce68031e22801ef8659060200160405180910390a1610c50565b6040518681527fbbfee2df7f28b899771f1015dc85d7840ff9f6162f23f6aa99686e8fbd2ce1319060200160405180910390a15b5050505092915050565b50565b8015610c5a5760405160009033907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90849084818181858888f193505050503d8060008114610896576040519150601f19603f3d011682016040523d82523d6000602084013e610896565b6000808473ffffffffffffffffffffffffffffffffffffffff168484604051610cf19190612360565b60006040518083038185875af1925050503d8060008114610d2e576040519150601f19603f3d011682016040523d82523d6000602084013e610d33565b606091505b50915091508161089657805160208201fd5b610d5181858585611117565b15610d88576040517f01f595e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000808573ffffffffffffffffffffffffffffffffffffffff168585604051610db19190612360565b60006040518083038185875af1925050503d8060008114610dee576040519150601f19603f3d011682016040523d82523d6000602084013e610df3565b606091505b509150915081610e0557805160208201fd5b505050505050565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb554610100900460ff1615610e78576040517f38fc28cb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100179055565b604080516001808252818301909252600091816020015b60408051606080820183526000808352602083015291810191909152815260200190600190039081610eca57905050905060008273ffffffffffffffffffffffffffffffffffffffff16633253960f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f6c9190612592565b604080516003808252608082019092529192506000919060208201606080368337019050509050631626ba7e60e01b81600081518110610fae57610fae612228565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681525050818160018151811061100e5761100e612228565b7fffffffff000000000000000000000000000000000000000000000000000000009092166020928302919091019091015280517f8da5cb5b00000000000000000000000000000000000000000000000000000000908290600290811061107657611076612228565b7fffffffff00000000000000000000000000000000000000000000000000000000909216602092830291909101820152604080516060810190915273ffffffffffffffffffffffffffffffffffffffff861681529081016000815260200182815250836000815181106110eb576110eb612228565b602002602001018190525061111183600060405180602001604052806000815250611264565b50505050565b60008030858585604051602401611131949392919061264d565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fac87185d0000000000000000000000000000000000000000000000000000000017905251909150600090819073ffffffffffffffffffffffffffffffffffffffff8916906111d3908590612360565b600060405180830381855af49150503d806000811461120e576040519150601f19603f3d011682016040523d82523d6000602084013e611213565b606091505b50915091508161124f576040517f01f595e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6112588161237c565b98975050505050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921547f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff8116908190600090600716156112d35750600381901c60009081526001840160205260409020545b60005b87518110156113505761134383838a84815181106112f6576112f6612228565b6020026020010151600001518b858151811061131457611314612228565b6020026020010151602001518c868151811061133257611332612228565b6020026020010151604001516113f0565b90935091506001016112d6565b50828214611389576002840180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff84161790555b60078216156113ab57600382901c600090815260018501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb6738787876040516113de93929190612696565b60405180910390a16104478686611e81565b600080807f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f905060008451116114a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f2063757400000000000000000000000000000000000000000060648201526084016101ec565b60008560028111156114bc576114bc6125d4565b0361168c576114e38660405180606001604052806024815260200161290d60249139611f7a565b60005b845181101561168657600085828151811061150357611503612228565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c156115d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c726561647920657869737473000000000000000000000060648201526084016101ec565b7fffffffff0000000000000000000000000000000000000000000000000000000080831660008181526020879052604090207fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608d901b168e17905560e060058e901b811692831c199c909c1690821c179a81900361166a5760038c901c600090815260018601602052604081209b909b555b8b6116748161282d565b9c5050600190930192506114e6915050565b50611e75565b60018560028111156116a0576116a06125d4565b03611990576116c78660405180606001604052806028815260200161295960289139611f7a565b60005b84518110156116865760008582815181106116e7576116e7612228565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c3081036117bc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4c69624469616d6f6e644375743a2043616e2774207265706c61636520696d6d60448201527f757461626c652066756e6374696f6e000000000000000000000000000000000060648201526084016101ec565b8973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611877576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e000000000000000060648201526084016101ec565b73ffffffffffffffffffffffffffffffffffffffff811661191a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e207468617420646f65736e2774206578697374000000000000000060648201526084016101ec565b507fffffffff0000000000000000000000000000000000000000000000000000000090911660009081526020849052604090206bffffffffffffffffffffffff919091167fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608a901b161790556001016116ca565b60028560028111156119a4576119a46125d4565b03611ded5773ffffffffffffffffffffffffffffffffffffffff861615611a4d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d75737420626520616464726573732830290000000000000000000060648201526084016101ec565b600388901c6007891660005b8651811015611dcd5760008a9003611a955782611a7581612865565b60008181526001870160205260409020549b50935060079250611aa39050565b81611a9f81612865565b9250505b6000806000808a8581518110611abb57611abb612228565b6020908102919091018101517fffffffff0000000000000000000000000000000000000000000000000000000081166000908152918a9052604090912054909150606081901c611b8d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e277420657869737400000000000000000060648201526084016101ec565b30606082901c03611c20576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e00000000000000000000000000000000000060648201526084016101ec565b600587901b8f901b94507fffffffff0000000000000000000000000000000000000000000000000000000080861690831614611cbe577fffffffff000000000000000000000000000000000000000000000000000000008516600090815260208a90526040902080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff83161790555b7fffffffff0000000000000000000000000000000000000000000000000000000091909116600090815260208990526040812055600381901c611fff16925060051b60e0169050858214611d53576000828152600188016020526040902080547fffffffff0000000000000000000000000000000000000000000000000000000080841c19909116908516831c179055611da4565b80837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c817fffffffff0000000000000000000000000000000000000000000000000000000060001b901c198e16179c505b84600003611dc257600086815260018801602052604081208190559c505b505050600101611a59565b5080611dda83600861289a565b611de491906128b7565b99505050611e75565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560448201527f74416374696f6e0000000000000000000000000000000000000000000000000060648201526084016101ec565b50959694955050505050565b73ffffffffffffffffffffffffffffffffffffffff8216611ea0575050565b611ec28260405180606001604052806028815260200161293160289139611f7a565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051611eea9190612360565b600060405180830381855af49150503d8060008114611f25576040519150601f19603f3d011682016040523d82523d6000602084013e611f2a565b606091505b50915091508161111157805115611f445780518082602001fd5b83836040517f192105d70000000000000000000000000000000000000000000000000000000081526004016101ec9291906128ca565b813b8181611111576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101ec91906128f9565b600080600060608486031215611fca57600080fd5b833567ffffffffffffffff811115611fe157600080fd5b84016101608187031215611ff457600080fd5b95602085013595506040909401359392505050565b60008083601f84011261201b57600080fd5b50813567ffffffffffffffff81111561203357600080fd5b6020830191508360208260051b850101111561204e57600080fd5b9250929050565b6000806000806000806060878903121561206e57600080fd5b863567ffffffffffffffff8082111561208657600080fd5b6120928a838b01612009565b909850965060208901359150808211156120ab57600080fd5b6120b78a838b01612009565b909650945060408901359150808211156120d057600080fd5b506120dd89828a01612009565b979a9699509497509295939492505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461211357600080fd5b919050565b60008083601f84011261212a57600080fd5b50813567ffffffffffffffff81111561214257600080fd5b60208301915083602082850101111561204e57600080fd5b60008060008060008060a0878903121561217357600080fd5b61217c876120ef565b955061218a602088016120ef565b9450612198604088016120ef565b93506121a6606088016120ef565b9250608087013567ffffffffffffffff8111156121c257600080fd5b6120dd89828a01612118565b600080600080606085870312156121e457600080fd5b6121ed856120ef565b935060208501359250604085013567ffffffffffffffff81111561221057600080fd5b61221c87828801612118565b95989497509550505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561226957600080fd5b610146826120ef565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126122a757600080fd5b83018035915067ffffffffffffffff8211156122c257600080fd5b60200191503681900382131561204e57600080fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b6020815260006123346020830184866122d7565b949350505050565b60005b8381101561235757818101518382015260200161233f565b50506000910152565b6000825161237281846020870161233c565b9190910192915050565b805160208083015191908110156123bb577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8160200360031b1b821691505b50919050565b8183823760009101908152919050565b6000602082840312156123e357600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261241f57600080fd5b830160208101925035905067ffffffffffffffff81111561243f57600080fd5b80360382131561204e57600080fd5b6040815261247c60408201612462856120ef565b73ffffffffffffffffffffffffffffffffffffffff169052565b60208301356060820152600061249560408501856123ea565b6101608060808601526124ad6101a0860183856122d7565b92506124bc60608801886123ea565b92507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0808786030160a08801526124f48585846122d7565b9450608089013560c088015260a089013560e0880152610100935060c089013584880152610120915060e089013582880152610140848a01358189015261253d838b018b6123ea565b955092508188870301848901526125558686856122d7565b9550612563818b018b6123ea565b9550935050808786030161018088015250506125808383836122d7565b93505050508260208301529392505050565b6000602082840312156125a457600080fd5b81517fffffffff000000000000000000000000000000000000000000000000000000008116811461014657600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6000815180845261261b81602086016020860161233c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600073ffffffffffffffffffffffffffffffffffffffff80871683528086166020840152508360408301526080606083015261268c6080830184612603565b9695505050505050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b848110156127c1577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808a8503018652815188850173ffffffffffffffffffffffffffffffffffffffff82511686528482015160038110612748577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b808310156127ac5783517fffffffff0000000000000000000000000000000000000000000000000000000016825292860192600192909201919086019061276a565b509785019795505050908201906001016126bf565b505073ffffffffffffffffffffffffffffffffffffffff8a169088015286810360408801526127f08189612603565b9a9950505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361285e5761285e6127fe565b5060010190565b600081612874576128746127fe565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b80820281158282048414176128b1576128b16127fe565b92915050565b808201808211156128b1576128b16127fe565b73ffffffffffffffffffffffffffffffffffffffff831681526040602082015260006123346040830184612603565b602081526000610146602083018461260356fe4c69624469616d6f6e644375743a2041646420666163657420686173206e6f20636f64654c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a205265706c61636520666163657420686173206e6f20636f6465a2646970667358221220a952f19990a20474450919a2df9ddff4430a71350892e0954f2bb073575ad64864736f6c63430008150033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100725760003560e01c8063b0d691fe11610050578063b0d691fe146100c5578063b61d27f61461010c578063d087d2881461011f57600080fd5b80633a871cdd1461007757806347e1da2a1461009d5780634a936417146100b2575b600080fd5b61008a610085366004611fb5565b610127565b6040519081526020015b60405180910390f35b6100b06100ab366004612055565b61014d565b005b61008a6100c036600461215a565b610450565b60015465010000000000900473ffffffffffffffffffffffffffffffffffffffff1660405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610094565b6100b061011a3660046121ce565b6106d0565b61008a61089d565b600061013161095e565b61013b8484610a16565b905061014682610c5d565b9392505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff9081164290911610156101f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064015b60405180910390fd5b6101fd61095e565b848114158061020c5750848314155b15610243576040517fdde5716100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006102b87fac87185d000000000000000000000000000000000000000000000000000000006000527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020527f6d9f2463c8c0d8cb8be556a773ab21d4321328909a1725f2ef7cae0c320e95da5460601c90565b905073ffffffffffffffffffffffffffffffffffffffff811661038f5760005b86811015610389576103818888838181106102f5576102f5612228565b905060200201602081019061030a9190612257565b87878481811061031c5761031c612228565b9050602002013586868581811061033557610335612228565b90506020028101906103479190612272565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610cc892505050565b6001016102d8565b50610447565b60005b868110156104455761043d8888838181106103af576103af612228565b90506020020160208101906103c49190612257565b8787848181106103d6576103d6612228565b905060200201358686858181106103ef576103ef612228565b90506020028101906104019190612272565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250889250610d45915050565b600101610392565b505b50505050505050565b600061045a610e0d565b6001805473ffffffffffffffffffffffffffffffffffffffff88811665010000000000027fffffffffffffff0000000000000000000000000000000000000000ffffffffff90921691909117909155600280548783167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216179091557f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd492380549287169290911691909117905561051187610eb3565b60008383604051602401610526929190612320565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fcd9b47e40000000000000000000000000000000000000000000000000000000017905251909150600090819073ffffffffffffffffffffffffffffffffffffffff8b16906105c8908590612360565b600060405180830381855af49150503d8060008114610603576040519150601f19603f3d011682016040523d82523d6000602084013e610608565b606091505b5091509150811580610623575061061e8161237c565b600114155b1561065a576040517f1602372100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60019350858560405161066e9291906123c1565b60405190819003812060015490916501000000000090910473ffffffffffffffffffffffffffffffffffffffff16907fd429ff0b972be4ae725700a373d05007287994e4c86cb83315b43ffa85b595fd90600090a35050509695505050505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610773576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064016101ec565b61077b61095e565b60006107f07fac87185d000000000000000000000000000000000000000000000000000000006000527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020527f6d9f2463c8c0d8cb8be556a773ab21d4321328909a1725f2ef7cae0c320e95da5460601c90565b905073ffffffffffffffffffffffffffffffffffffffff81166108535761084e858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610cc892505050565b610896565b610896858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250879250610d45915050565b5050505050565b60015460009065010000000000900473ffffffffffffffffffffffffffffffffffffffff166040517f35567e1a0000000000000000000000000000000000000000000000000000000081523060048201526000602482015273ffffffffffffffffffffffffffffffffffffffff91909116906335567e1a90604401602060405180830381865afa158015610935573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061095991906123d1565b905090565b60015465010000000000900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a14576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f6163636f756e743a206e6f742066726f6d20456e747279506f696e740000000060448201526064016101ec565b565b600154610100900460e01b7fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604081205460601c80610aab576040517f6eb2360200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600154604051600091610100900460e01b90610acd908790879060240161244e565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090506000808373ffffffffffffffffffffffffffffffffffffffff1683604051610b549190612360565b600060405180830381855af49150503d8060008114610b8f576040519150601f19603f3d011682016040523d82523d6000602084013e610b94565b606091505b509150915081610bd0576040517f3cbbb65000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610bd98161237c565b94506000859003610c1c576040518681527f19e781916118c373dadcb7776fae0a2dbb6bbdeedae143ce68031e22801ef8659060200160405180910390a1610c50565b6040518681527fbbfee2df7f28b899771f1015dc85d7840ff9f6162f23f6aa99686e8fbd2ce1319060200160405180910390a15b5050505092915050565b50565b8015610c5a5760405160009033907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90849084818181858888f193505050503d8060008114610896576040519150601f19603f3d011682016040523d82523d6000602084013e610896565b6000808473ffffffffffffffffffffffffffffffffffffffff168484604051610cf19190612360565b60006040518083038185875af1925050503d8060008114610d2e576040519150601f19603f3d011682016040523d82523d6000602084013e610d33565b606091505b50915091508161089657805160208201fd5b610d5181858585611117565b15610d88576040517f01f595e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000808573ffffffffffffffffffffffffffffffffffffffff168585604051610db19190612360565b60006040518083038185875af1925050503d8060008114610dee576040519150601f19603f3d011682016040523d82523d6000602084013e610df3565b606091505b509150915081610e0557805160208201fd5b505050505050565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb554610100900460ff1615610e78576040517f38fc28cb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100179055565b604080516001808252818301909252600091816020015b60408051606080820183526000808352602083015291810191909152815260200190600190039081610eca57905050905060008273ffffffffffffffffffffffffffffffffffffffff16633253960f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f6c9190612592565b604080516003808252608082019092529192506000919060208201606080368337019050509050631626ba7e60e01b81600081518110610fae57610fae612228565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681525050818160018151811061100e5761100e612228565b7fffffffff000000000000000000000000000000000000000000000000000000009092166020928302919091019091015280517f8da5cb5b00000000000000000000000000000000000000000000000000000000908290600290811061107657611076612228565b7fffffffff00000000000000000000000000000000000000000000000000000000909216602092830291909101820152604080516060810190915273ffffffffffffffffffffffffffffffffffffffff861681529081016000815260200182815250836000815181106110eb576110eb612228565b602002602001018190525061111183600060405180602001604052806000815250611264565b50505050565b60008030858585604051602401611131949392919061264d565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fac87185d0000000000000000000000000000000000000000000000000000000017905251909150600090819073ffffffffffffffffffffffffffffffffffffffff8916906111d3908590612360565b600060405180830381855af49150503d806000811461120e576040519150601f19603f3d011682016040523d82523d6000602084013e611213565b606091505b50915091508161124f576040517f01f595e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6112588161237c565b98975050505050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921547f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff8116908190600090600716156112d35750600381901c60009081526001840160205260409020545b60005b87518110156113505761134383838a84815181106112f6576112f6612228565b6020026020010151600001518b858151811061131457611314612228565b6020026020010151602001518c868151811061133257611332612228565b6020026020010151604001516113f0565b90935091506001016112d6565b50828214611389576002840180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff84161790555b60078216156113ab57600382901c600090815260018501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb6738787876040516113de93929190612696565b60405180910390a16104478686611e81565b600080807f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f905060008451116114a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f2063757400000000000000000000000000000000000000000060648201526084016101ec565b60008560028111156114bc576114bc6125d4565b0361168c576114e38660405180606001604052806024815260200161290d60249139611f7a565b60005b845181101561168657600085828151811061150357611503612228565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c156115d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c726561647920657869737473000000000000000000000060648201526084016101ec565b7fffffffff0000000000000000000000000000000000000000000000000000000080831660008181526020879052604090207fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608d901b168e17905560e060058e901b811692831c199c909c1690821c179a81900361166a5760038c901c600090815260018601602052604081209b909b555b8b6116748161282d565b9c5050600190930192506114e6915050565b50611e75565b60018560028111156116a0576116a06125d4565b03611990576116c78660405180606001604052806028815260200161295960289139611f7a565b60005b84518110156116865760008582815181106116e7576116e7612228565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c3081036117bc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4c69624469616d6f6e644375743a2043616e2774207265706c61636520696d6d60448201527f757461626c652066756e6374696f6e000000000000000000000000000000000060648201526084016101ec565b8973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611877576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e000000000000000060648201526084016101ec565b73ffffffffffffffffffffffffffffffffffffffff811661191a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e207468617420646f65736e2774206578697374000000000000000060648201526084016101ec565b507fffffffff0000000000000000000000000000000000000000000000000000000090911660009081526020849052604090206bffffffffffffffffffffffff919091167fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608a901b161790556001016116ca565b60028560028111156119a4576119a46125d4565b03611ded5773ffffffffffffffffffffffffffffffffffffffff861615611a4d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d75737420626520616464726573732830290000000000000000000060648201526084016101ec565b600388901c6007891660005b8651811015611dcd5760008a9003611a955782611a7581612865565b60008181526001870160205260409020549b50935060079250611aa39050565b81611a9f81612865565b9250505b6000806000808a8581518110611abb57611abb612228565b6020908102919091018101517fffffffff0000000000000000000000000000000000000000000000000000000081166000908152918a9052604090912054909150606081901c611b8d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e277420657869737400000000000000000060648201526084016101ec565b30606082901c03611c20576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e00000000000000000000000000000000000060648201526084016101ec565b600587901b8f901b94507fffffffff0000000000000000000000000000000000000000000000000000000080861690831614611cbe577fffffffff000000000000000000000000000000000000000000000000000000008516600090815260208a90526040902080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff83161790555b7fffffffff0000000000000000000000000000000000000000000000000000000091909116600090815260208990526040812055600381901c611fff16925060051b60e0169050858214611d53576000828152600188016020526040902080547fffffffff0000000000000000000000000000000000000000000000000000000080841c19909116908516831c179055611da4565b80837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c817fffffffff0000000000000000000000000000000000000000000000000000000060001b901c198e16179c505b84600003611dc257600086815260018801602052604081208190559c505b505050600101611a59565b5080611dda83600861289a565b611de491906128b7565b99505050611e75565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560448201527f74416374696f6e0000000000000000000000000000000000000000000000000060648201526084016101ec565b50959694955050505050565b73ffffffffffffffffffffffffffffffffffffffff8216611ea0575050565b611ec28260405180606001604052806028815260200161293160289139611f7a565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051611eea9190612360565b600060405180830381855af49150503d8060008114611f25576040519150601f19603f3d011682016040523d82523d6000602084013e611f2a565b606091505b50915091508161111157805115611f445780518082602001fd5b83836040517f192105d70000000000000000000000000000000000000000000000000000000081526004016101ec9291906128ca565b813b8181611111576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101ec91906128f9565b600080600060608486031215611fca57600080fd5b833567ffffffffffffffff811115611fe157600080fd5b84016101608187031215611ff457600080fd5b95602085013595506040909401359392505050565b60008083601f84011261201b57600080fd5b50813567ffffffffffffffff81111561203357600080fd5b6020830191508360208260051b850101111561204e57600080fd5b9250929050565b6000806000806000806060878903121561206e57600080fd5b863567ffffffffffffffff8082111561208657600080fd5b6120928a838b01612009565b909850965060208901359150808211156120ab57600080fd5b6120b78a838b01612009565b909650945060408901359150808211156120d057600080fd5b506120dd89828a01612009565b979a9699509497509295939492505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461211357600080fd5b919050565b60008083601f84011261212a57600080fd5b50813567ffffffffffffffff81111561214257600080fd5b60208301915083602082850101111561204e57600080fd5b60008060008060008060a0878903121561217357600080fd5b61217c876120ef565b955061218a602088016120ef565b9450612198604088016120ef565b93506121a6606088016120ef565b9250608087013567ffffffffffffffff8111156121c257600080fd5b6120dd89828a01612118565b600080600080606085870312156121e457600080fd5b6121ed856120ef565b935060208501359250604085013567ffffffffffffffff81111561221057600080fd5b61221c87828801612118565b95989497509550505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561226957600080fd5b610146826120ef565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126122a757600080fd5b83018035915067ffffffffffffffff8211156122c257600080fd5b60200191503681900382131561204e57600080fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b6020815260006123346020830184866122d7565b949350505050565b60005b8381101561235757818101518382015260200161233f565b50506000910152565b6000825161237281846020870161233c565b9190910192915050565b805160208083015191908110156123bb577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8160200360031b1b821691505b50919050565b8183823760009101908152919050565b6000602082840312156123e357600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261241f57600080fd5b830160208101925035905067ffffffffffffffff81111561243f57600080fd5b80360382131561204e57600080fd5b6040815261247c60408201612462856120ef565b73ffffffffffffffffffffffffffffffffffffffff169052565b60208301356060820152600061249560408501856123ea565b6101608060808601526124ad6101a0860183856122d7565b92506124bc60608801886123ea565b92507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0808786030160a08801526124f48585846122d7565b9450608089013560c088015260a089013560e0880152610100935060c089013584880152610120915060e089013582880152610140848a01358189015261253d838b018b6123ea565b955092508188870301848901526125558686856122d7565b9550612563818b018b6123ea565b9550935050808786030161018088015250506125808383836122d7565b93505050508260208301529392505050565b6000602082840312156125a457600080fd5b81517fffffffff000000000000000000000000000000000000000000000000000000008116811461014657600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6000815180845261261b81602086016020860161233c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600073ffffffffffffffffffffffffffffffffffffffff80871683528086166020840152508360408301526080606083015261268c6080830184612603565b9695505050505050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b848110156127c1577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808a8503018652815188850173ffffffffffffffffffffffffffffffffffffffff82511686528482015160038110612748577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b808310156127ac5783517fffffffff0000000000000000000000000000000000000000000000000000000016825292860192600192909201919086019061276a565b509785019795505050908201906001016126bf565b505073ffffffffffffffffffffffffffffffffffffffff8a169088015286810360408801526127f08189612603565b9a9950505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361285e5761285e6127fe565b5060010190565b600081612874576128746127fe565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b80820281158282048414176128b1576128b16127fe565b92915050565b808201808211156128b1576128b16127fe565b73ffffffffffffffffffffffffffffffffffffffff831681526040602082015260006123346040830184612603565b602081526000610146602083018461260356fe4c69624469616d6f6e644375743a2041646420666163657420686173206e6f20636f64654c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a205265706c61636520666163657420686173206e6f20636f6465a2646970667358221220a952f19990a20474450919a2df9ddff4430a71350892e0954f2bb073575ad64864736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "Account module contract that provides the account features and initialization of signer compatible with EIP-1271 & EIP-4337", + "kind": "dev", + "methods": { + "execute(address,uint256,bytes)": { + "details": "This method executes the calldata coming from the EntryPoint. Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)", + "params": { + "_dest": "Address of destination where the call will be forwarded to", + "_func": "Bytes of calldata to execute in the destination address", + "_value": "Amount of native coin the owner is willing to send(e.g. ETH, BNB)" + } + }, + "executeBatch(address[],uint256[],bytes[])": { + "details": "This method batch executes the calldata coming from the EntryPoint. Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)", + "params": { + "_dest": "Array of addresses of destination where the call will be forwarded to", + "_func": "Array of bytes of calldata to execute in the destination address", + "_value": "Array of amount of native coin the owner is willing to send(e.g. ETH, BNB)" + } + }, + "initialize(address,address,address,address,bytes)": { + "details": "This method can only be called during the initialization or signature migration. If the proxy contract was created without initialization, anyone can call initialize. Barz calls initialize in constructor in an atomic transaction during deployment", + "params": { + "_anEntryPoint": "Entrypoint contract defined in EIP-4337 handling the flow of UserOp", + "_defaultFallBackHandler": "Middleware contract for default facets", + "_facetRegistry": "Registry of Facets that hold all facet information", + "_ownerPublicKey": "Bytes of owner public key", + "_verificationFacet": "Facet contract handling the verificationi" + } + } + }, + "title": "Account Facet", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "constructor": { + "notice": "This constructor ensures that this contract can only be used as singleton for Proxy contracts" + }, + "entryPoint()": { + "notice": "Returns the address of EntryPoint contract registered to Barz account" + }, + "execute(address,uint256,bytes)": { + "notice": "Calls the destination with inputted calldata and value from EntryPoint" + }, + "executeBatch(address[],uint256[],bytes[])": { + "notice": "Batch calls the destination with inputted calldata and value from EntryPoint" + }, + "getNonce()": { + "notice": "Return the account nonce. This method returns the next sequential nonce. For a nonce of a specific key, use `entrypoint.getNonce(account, key)`" + }, + "initialize(address,address,address,address,bytes)": { + "notice": "Initializes the initial storage of the Barz contract." + }, + "validateUserOp((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256)": { + "notice": "Validate user's signature and nonce. subclass doesn't need to override this method. Instead, it should override the specific internal validation methods." + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 27823, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "s", + "offset": 0, + "slot": "0", + "type": "t_struct(AppStorage)27570_storage" + } + ], + "types": { + "t_bytes4": { + "encoding": "inplace", + "label": "bytes4", + "numberOfBytes": "4" + }, + "t_contract(IEntryPoint)12286": { + "encoding": "inplace", + "label": "contract IEntryPoint", + "numberOfBytes": "20" + }, + "t_contract(IFacetRegistry)26105": { + "encoding": "inplace", + "label": "contract IFacetRegistry", + "numberOfBytes": "20" + }, + "t_mapping(t_uint256,t_struct(InitializersStorage)27549_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => struct InitializersStorage)", + "numberOfBytes": "32", + "value": "t_struct(InitializersStorage)27549_storage" + }, + "t_mapping(t_uint256,t_struct(Lock)27542_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => struct Lock)", + "numberOfBytes": "32", + "value": "t_struct(Lock)27542_storage" + }, + "t_struct(AppStorage)27570_storage": { + "encoding": "inplace", + "label": "struct AppStorage", + "members": [ + { + "astId": 27554, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "initStorage", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_uint256,t_struct(InitializersStorage)27549_storage)" + }, + { + "astId": 27556, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "signerMigration", + "offset": 0, + "slot": "1", + "type": "t_uint8" + }, + { + "astId": 27558, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "validateOwnerSignatureSelector", + "offset": 1, + "slot": "1", + "type": "t_bytes4" + }, + { + "astId": 27561, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "entryPoint", + "offset": 5, + "slot": "1", + "type": "t_contract(IEntryPoint)12286" + }, + { + "astId": 27564, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "facetRegistry", + "offset": 0, + "slot": "2", + "type": "t_contract(IFacetRegistry)26105" + }, + { + "astId": 27569, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "locks", + "offset": 0, + "slot": "3", + "type": "t_mapping(t_uint256,t_struct(Lock)27542_storage)" + } + ], + "numberOfBytes": "128" + }, + "t_struct(InitializersStorage)27549_storage": { + "encoding": "inplace", + "label": "struct InitializersStorage", + "members": [ + { + "astId": 27544, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "signerInitialized", + "offset": 0, + "slot": "0", + "type": "t_uint8" + }, + { + "astId": 27546, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "accountInitialized", + "offset": 1, + "slot": "0", + "type": "t_uint8" + }, + { + "astId": 27548, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "restrictionsInitialized", + "offset": 2, + "slot": "0", + "type": "t_uint8" + } + ], + "numberOfBytes": "32" + }, + "t_struct(Lock)27542_storage": { + "encoding": "inplace", + "label": "struct Lock", + "members": [ + { + "astId": 27539, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "release", + "offset": 0, + "slot": "0", + "type": "t_uint64" + }, + { + "astId": 27541, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "locker", + "offset": 8, + "slot": "0", + "type": "t_bytes4" + } + ], + "numberOfBytes": "32" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint64": { + "encoding": "inplace", + "label": "uint64", + "numberOfBytes": "8" + }, + "t_uint8": { + "encoding": "inplace", + "label": "uint8", + "numberOfBytes": "1" + } + } + } +} \ No newline at end of file diff --git a/deployments/bsc/BarzFactory.json b/deployments/bsc/BarzFactory.json new file mode 100644 index 0000000..5c335e9 --- /dev/null +++ b/deployments/bsc/BarzFactory.json @@ -0,0 +1,318 @@ +{ + "address": "0x729c310186a57833f622630a16d13f710b83272a", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_accountFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_entryPoint", + "type": "address" + }, + { + "internalType": "address", + "name": "_facetRegistry", + "type": "address" + }, + { + "internalType": "address", + "name": "_defaultFallback", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "BarzDeployed", + "type": "event" + }, + { + "inputs": [], + "name": "accountFacet", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_verificationFacet", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_owner", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "_salt", + "type": "uint256" + } + ], + "name": "createAccount", + "outputs": [ + { + "internalType": "contract Barz", + "name": "barz", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "defaultFallback", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "entryPoint", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetRegistry", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_verificationFacet", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_owner", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "_salt", + "type": "uint256" + } + ], + "name": "getAddress", + "outputs": [ + { + "internalType": "address", + "name": "barzAddress", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_accountFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_verificationFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_entryPoint", + "type": "address" + }, + { + "internalType": "address", + "name": "_facetRegistry", + "type": "address" + }, + { + "internalType": "address", + "name": "_defaultFallback", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_ownerPublicKey", + "type": "bytes" + } + ], + "name": "getBytecode", + "outputs": [ + { + "internalType": "bytes", + "name": "barzBytecode", + "type": "bytes" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "getCreationCode", + "outputs": [ + { + "internalType": "bytes", + "name": "creationCode", + "type": "bytes" + } + ], + "stateMutability": "pure", + "type": "function" + } + ], + "transactionHash": "0xc2f13a5bccf5087cf47ef860cca9e2699af99e61845dc7590aaf25dee0ddae5c", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 81, + "gasUsed": "801756", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x08f27599af1b9ca1cb32daf35eee33e81401bcd65d46b16edbf6a33a9758bc30", + "transactionHash": "0xc2f13a5bccf5087cf47ef860cca9e2699af99e61845dc7590aaf25dee0ddae5c", + "logs": [], + "blockNumber": 33657835, + "cumulativeGasUsed": "7560022", + "status": 1, + "byzantium": true + }, + "args": [ + "0xFde53272dcd7938d16E031A6989753c321728332", + "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789", + "0xAfCb70e6e9514E2A15B23A01d2a9b9f7A34f2c33", + "0x2e7f1dAe1F3799d20f5c31bEFdc7A620f664728D" + ], + "numDeployments": 4, + "solcInputHash": "4356503edd8ae34e73cb6dd1c8e2fc8a", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_accountFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_entryPoint\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_facetRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_defaultFallback\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"BarzDeployed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"accountFacet\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_verificationFacet\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_owner\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_salt\",\"type\":\"uint256\"}],\"name\":\"createAccount\",\"outputs\":[{\"internalType\":\"contract Barz\",\"name\":\"barz\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"defaultFallback\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"entryPoint\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetRegistry\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_verificationFacet\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_owner\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_salt\",\"type\":\"uint256\"}],\"name\":\"getAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"barzAddress\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_accountFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_verificationFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_entryPoint\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_facetRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_defaultFallback\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_ownerPublicKey\",\"type\":\"bytes\"}],\"name\":\"getBytecode\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"barzBytecode\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCreationCode\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"creationCode\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"Contract to easily deploy Barz to a pre-computed address with a single call\",\"kind\":\"dev\",\"methods\":{\"constructor\":{\"params\":{\"_accountFacet\":\"Account Facet to be used to create Barz\",\"_defaultFallback\":\"Default Fallback Handler to be used to create Barz\",\"_entryPoint\":\"Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\",\"_facetRegistry\":\"Facet Registry to be used to create Barz\"}},\"createAccount(address,bytes,uint256)\":{\"params\":{\"_owner\":\"Public Key of the owner to initialize barz account\",\"_salt\":\"Salt used for deploying barz with create2\",\"_verificationFacet\":\"Address of verification facet used for creating the barz account\"},\"returns\":{\"barz\":\"Instance of Barz contract deployed with the given parameters\"}},\"getAddress(address,bytes,uint256)\":{\"params\":{\"_owner\":\"Public Key of the owner to initialize barz account\",\"_salt\":\"Salt used for deploying barz with create2\",\"_verificationFacet\":\"Address of verification facet used for creating the barz account\"},\"returns\":{\"barzAddress\":\"Precalculated Barz address\"}},\"getBytecode(address,address,address,address,address,bytes)\":{\"params\":{\"_accountFacet\":\"Account Facet to be used to create Barz\",\"_defaultFallback\":\"Default Fallback Handler to be used to create Barz\",\"_entryPoint\":\"Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\",\"_facetRegistry\":\"Facet Registry to be used to create Barz\",\"_ownerPublicKey\":\"Public Key of owner to be used to initialize Barz ownership\",\"_verificationFacet\":\"Verification Facet to be used to create Barz\"},\"returns\":{\"barzBytecode\":\"Bytecode of Barz\"}},\"getCreationCode()\":{\"returns\":{\"creationCode\":\"Creation code of Barz\"}}},\"title\":\"Barz Factory\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"Sets the initialization data for Barz contract initialization\"},\"createAccount(address,bytes,uint256)\":{\"notice\":\"Creates the Barz with a single call. It creates the Barz contract with the givent verification facet\"},\"getAddress(address,bytes,uint256)\":{\"notice\":\"Calculates the address of Barz with the given parameters\"},\"getBytecode(address,address,address,address,address,bytes)\":{\"notice\":\"Returns the bytecode of Barz with the given parameter\"},\"getCreationCode()\":{\"notice\":\"Returns the creation code of the Barz contract\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/BarzFactory.sol\":\"BarzFactory\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"contracts/Barz.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {LibDiamond} from \\\"./libraries/LibDiamond.sol\\\";\\nimport {IBarz} from \\\"./interfaces/IBarz.sol\\\";\\n\\n/**\\n * @title Barz\\n * @dev A diamond proxy wallet with a modular & upgradeable architecture\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract Barz is IBarz {\\n /**\\n * @notice Initializes Barz with the given parameters. Barz account is intended to be created from Barz Factory for stable deployment.\\n * @dev This method makes a delegate call to account facet and account facet handles the initialization.\\n * With modular architecture, Barz encompasses wide spectrum of architecture and logic.\\n * The only requirement is account facet to comply with initialize() interface.\\n * Barz doesn't include built-in functions and is a full proxy, for maximum extensibility and modularity.\\n * @param _accountFacet Address of Account Facet in charge of the Barz initialization\\n * @param _verificationFacet Address of Verification Facet for verifying the signature. Could be any signature scheme\\n * @param _entryPoint Address of Entry Point contract\\n * @param _facetRegistry Address of Facet Registry. Facet Registry is a registry holding trusted facets that could be added to user's wallet\\n * @param _defaultFallBack Address of Default FallBack Handler. Middleware contract for more efficient deployment\\n * @param _ownerPublicKey Bytes of Owner Public Key using for initialization\\n */\\n constructor(\\n address _accountFacet,\\n address _verificationFacet,\\n address _entryPoint,\\n address _facetRegistry,\\n address _defaultFallBack,\\n bytes memory _ownerPublicKey\\n ) payable {\\n bytes memory initCall = abi.encodeWithSignature(\\n \\\"initialize(address,address,address,address,bytes)\\\",\\n _verificationFacet,\\n _entryPoint,\\n _facetRegistry,\\n _defaultFallBack,\\n _ownerPublicKey\\n );\\n (bool success, bytes memory result) = _accountFacet.delegatecall(\\n initCall\\n );\\n if (!success || uint256(bytes32(result)) != 1) {\\n revert Barz__InitializationFailure();\\n }\\n }\\n\\n /**\\n * @notice Fallback function for Barz complying with Diamond Standard with customization of adding Default Fallback Handler\\n * @dev Find facet for function that is called and execute the function if a facet is found and return any value.\\n */\\n fallback() external payable {\\n LibDiamond.DiamondStorage storage ds;\\n bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION;\\n // get diamond storage\\n assembly {\\n ds.slot := position\\n }\\n // get facet from function selector\\n address facet = address(bytes20(ds.facets[msg.sig]));\\n if (facet == address(0))\\n facet = ds.defaultFallbackHandler.facetAddress(msg.sig);\\n require(facet != address(0), \\\"Barz: Function does not exist\\\");\\n // Execute external function from facet using delegatecall and return any value.\\n assembly {\\n // copy function selector and any arguments\\n calldatacopy(0, 0, calldatasize())\\n // execute function call using the facet\\n let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)\\n // get any return value\\n returndatacopy(0, 0, returndatasize())\\n // return any return value or error back to the caller\\n switch result\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @notice Receive function to receive native token without data\\n */\\n receive() external payable {}\\n}\\n\",\"keccak256\":\"0xd1c773409a4b3d1ca0316445d9ea1d686bab9cd5f6731fbdb0766a93edfd7bdb\",\"license\":\"Apache-2.0\"},\"contracts/BarzFactory.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {Barz} from \\\"./Barz.sol\\\";\\nimport {IBarzFactory} from \\\"./interfaces/IBarzFactory.sol\\\";\\n\\n/**\\n * @title Barz Factory\\n * @dev Contract to easily deploy Barz to a pre-computed address with a single call\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract BarzFactory is IBarzFactory {\\n address public immutable accountFacet;\\n address public immutable entryPoint;\\n address public immutable facetRegistry;\\n address public immutable defaultFallback;\\n\\n /**\\n * @notice Sets the initialization data for Barz contract initialization\\n * @param _accountFacet Account Facet to be used to create Barz\\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\\n * @param _facetRegistry Facet Registry to be used to create Barz\\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\\n */\\n constructor(\\n address _accountFacet,\\n address _entryPoint,\\n address _facetRegistry,\\n address _defaultFallback\\n ) {\\n accountFacet = _accountFacet;\\n entryPoint = _entryPoint;\\n facetRegistry = _facetRegistry;\\n defaultFallback = _defaultFallback;\\n }\\n\\n /**\\n * @notice Creates the Barz with a single call. It creates the Barz contract with the givent verification facet\\n * @param _verificationFacet Address of verification facet used for creating the barz account\\n * @param _owner Public Key of the owner to initialize barz account\\n * @param _salt Salt used for deploying barz with create2\\n * @return barz Instance of Barz contract deployed with the given parameters\\n */\\n function createAccount(\\n address _verificationFacet,\\n bytes calldata _owner,\\n uint256 _salt\\n ) external override returns (Barz barz) {\\n address addr = getAddress(_verificationFacet, _owner, _salt);\\n uint codeSize = addr.code.length;\\n if (codeSize > 0) {\\n return Barz(payable(addr));\\n }\\n barz = new Barz{salt: bytes32(_salt)}(\\n accountFacet,\\n _verificationFacet,\\n entryPoint,\\n facetRegistry,\\n defaultFallback,\\n _owner\\n );\\n emit BarzDeployed(address(barz));\\n }\\n\\n /**\\n * @notice Calculates the address of Barz with the given parameters\\n * @param _verificationFacet Address of verification facet used for creating the barz account\\n * @param _owner Public Key of the owner to initialize barz account\\n * @param _salt Salt used for deploying barz with create2\\n * @return barzAddress Precalculated Barz address\\n */\\n function getAddress(\\n address _verificationFacet,\\n bytes calldata _owner,\\n uint256 _salt\\n ) public view override returns (address barzAddress) {\\n bytes memory bytecode = getBytecode(\\n accountFacet,\\n _verificationFacet,\\n entryPoint,\\n facetRegistry,\\n defaultFallback,\\n _owner\\n );\\n bytes32 hash = keccak256(\\n abi.encodePacked(\\n bytes1(0xff),\\n address(this),\\n _salt,\\n keccak256(bytecode)\\n )\\n );\\n barzAddress = address(uint160(uint256(hash)));\\n }\\n\\n /**\\n * @notice Returns the bytecode of Barz with the given parameter\\n * @param _accountFacet Account Facet to be used to create Barz\\n * @param _verificationFacet Verification Facet to be used to create Barz\\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\\n * @param _facetRegistry Facet Registry to be used to create Barz\\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\\n * @param _ownerPublicKey Public Key of owner to be used to initialize Barz ownership\\n * @return barzBytecode Bytecode of Barz\\n */\\n function getBytecode(\\n address _accountFacet,\\n address _verificationFacet,\\n address _entryPoint,\\n address _facetRegistry,\\n address _defaultFallback,\\n bytes calldata _ownerPublicKey\\n ) public pure override returns (bytes memory barzBytecode) {\\n bytes memory bytecode = type(Barz).creationCode;\\n barzBytecode = abi.encodePacked(\\n bytecode,\\n abi.encode(\\n _accountFacet,\\n _verificationFacet,\\n _entryPoint,\\n _facetRegistry,\\n _defaultFallback,\\n _ownerPublicKey\\n )\\n );\\n }\\n\\n /**\\n * @notice Returns the creation code of the Barz contract\\n * @return creationCode Creation code of Barz\\n */\\n function getCreationCode()\\n public\\n pure\\n override\\n returns (bytes memory creationCode)\\n {\\n creationCode = type(Barz).creationCode;\\n }\\n}\\n\",\"keccak256\":\"0x76d6058fa4714f5ef87b876e49ce7e21f581164901eea906ec743e82362b1df6\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IBarz.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Barz Interface\\n * @dev Interface of Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IBarz {\\n error Barz__InitializationFailure();\\n}\\n\",\"keccak256\":\"0xca9f0c2c1ad7d06088fa16ae92d587416f2d10d8f999d7afe8ca5c4d73410aba\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IBarzFactory.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {Barz} from \\\"../Barz.sol\\\";\\n\\n/**\\n * @title Barz Factory Interface\\n * @dev Interface of contract to easily deploy Barz to a pre-computed address with a single call\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IBarzFactory {\\n event BarzDeployed(address);\\n\\n function createAccount(\\n address verificationFacet,\\n bytes calldata owner,\\n uint256 salt\\n ) external returns (Barz);\\n\\n function getAddress(\\n address verificationFacet,\\n bytes calldata owner,\\n uint256 salt\\n ) external view returns (address);\\n\\n function getBytecode(\\n address accountFacet,\\n address verificationFacet,\\n address entryPoint,\\n address facetRegistry,\\n address defaultFallback,\\n bytes memory ownerPublicKey\\n ) external pure returns (bytes memory);\\n\\n function getCreationCode() external pure returns (bytes memory);\\n}\\n\",\"keccak256\":\"0xadb48a6f3025f6395e26ffd5f9319da73ad2383906c8223e8455f41f420fba26\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\\n bytes4(keccak256(\\\"verifyRestrictions(address,address,uint256,bytes)\\\"));\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // Default Fallback Handler of the barz.\\n IDiamondLoupe defaultFallbackHandler;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function enforceIsSelf() internal view {\\n require(msg.sender == address(this), \\\"LibDiamond: Caller not self\\\");\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n\\n unchecked {\\n facetIndex++;\\n }\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n\\n function restrictionsFacet() internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(\\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2cabdc00de859c3a3170ce3bda5d0e5fd3933d47ce904fd1585f9818b02572f8\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x61010060405234801561001157600080fd5b50604051610eba380380610eba8339810160408190526100309161006e565b6001600160a01b0393841660805291831660a052821660c0521660e0526100c2565b80516001600160a01b038116811461006957600080fd5b919050565b6000806000806080858703121561008457600080fd5b61008d85610052565b935061009b60208601610052565b92506100a960408601610052565b91506100b760608601610052565b905092959194509250565b60805160a05160c05160e051610d886101326000396000818161013b015281816102b3015261048101526000818160bf01528181610292015261046001526000818161016301528181610271015261043f01526000818161018b0152818161024f015261041d0152610d886000f3fe60806040523480156200001157600080fd5b5060043610620000925760003560e01c806344409a82116200006257806344409a821462000135578063b0d691fe146200015d578063b0f5d4641462000185578063c8a7adf514620001ad57600080fd5b8062c194db14620000975780630a1acd7314620000b9578063296601cd146200010757806333bb64a7146200011e575b600080fd5b620000a1620001c4565b604051620000b091906200056c565b60405180910390f35b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001620000b0565b620000e16200011836600462000635565b6200020e565b620000a16200012f36600462000695565b6200036d565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e1620001be36600462000635565b62000414565b606060405180602001620001d89062000538565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082820381018352601f90910116604052919050565b6000806200021f8686868662000414565b905073ffffffffffffffffffffffffffffffffffffffff81163b8015620002495750905062000365565b8360001b7f0000000000000000000000000000000000000000000000000000000000000000887f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008b8b604051620002e29062000538565b620002f497969594939291906200073a565b8190604051809103906000f590508015801562000315573d6000803e3d6000fd5b5060405173ffffffffffffffffffffffffffffffffffffffff821681529093507f9e6e326008e68f57877e2bae766a5745c162e42359e34834a7f0661fa82d31b19060200160405180910390a150505b949350505050565b6060600060405180602001620003839062000538565b6020820181038252601f19601f8201166040525090508089898989898989604051602001620003b997969594939291906200073a565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052620003f79291602001620007cd565b604051602081830303815290604052915050979650505050505050565b600080620004a87f0000000000000000000000000000000000000000000000000000000000000000877f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008a8a6200036d565b8051602091820120604080517fff00000000000000000000000000000000000000000000000000000000000000818501523060601b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001660218201526035810196909652605580870192909252805180870390920182526075909501909452835193019290922095945050505050565b610552806200080183390190565b60005b838110156200056357818101518382015260200162000549565b50506000910152565b60208152600082518060208401526200058d81604085016020870162000546565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b803573ffffffffffffffffffffffffffffffffffffffff81168114620005e457600080fd5b919050565b60008083601f840112620005fc57600080fd5b50813567ffffffffffffffff8111156200061557600080fd5b6020830191508360208285010111156200062e57600080fd5b9250929050565b600080600080606085870312156200064c57600080fd5b6200065785620005bf565b9350602085013567ffffffffffffffff8111156200067457600080fd5b6200068287828801620005e9565b9598909750949560400135949350505050565b600080600080600080600060c0888a031215620006b157600080fd5b620006bc88620005bf565b9650620006cc60208901620005bf565b9550620006dc60408901620005bf565b9450620006ec60608901620005bf565b9350620006fc60808901620005bf565b925060a088013567ffffffffffffffff8111156200071957600080fd5b620007278a828b01620005e9565b989b979a50959850939692959293505050565b600073ffffffffffffffffffffffffffffffffffffffff808a16835280891660208401528088166040840152808716606084015280861660808401525060c060a08301528260c0830152828460e0840137600060e0848401015260e07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f850116830101905098975050505050505050565b60008351620007e181846020880162000546565b835190830190620007f781836020880162000546565b0194935050505056fe608060405260405161055238038061055283398101604081905261002291610163565b6000858585858560405160240161003d959493929190610264565b60408051601f198184030181529181526020820180516001600160e01b0316634a93641760e01b1790525190915060009081906001600160a01b038a16906100869085906102c3565b600060405180830381855af49150503d80600081146100c1576040519150601f19603f3d011682016040523d82523d6000602084013e6100c6565b606091505b50915091508115806100e157506100dc816102df565b600114155b156100ff57604051636ff35f8960e01b815260040160405180910390fd5b505050505050505050610306565b80516001600160a01b038116811461012457600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101561015a578181015183820152602001610142565b50506000910152565b60008060008060008060c0878903121561017c57600080fd5b6101858761010d565b95506101936020880161010d565b94506101a16040880161010d565b93506101af6060880161010d565b92506101bd6080880161010d565b60a08801519092506001600160401b03808211156101da57600080fd5b818901915089601f8301126101ee57600080fd5b81518181111561020057610200610129565b604051601f8201601f19908116603f0116810190838211818310171561022857610228610129565b816040528281528c602084870101111561024157600080fd5b61025283602083016020880161013f565b80955050505050509295509295509295565b600060018060a01b0380881683528087166020840152808616604084015280851660608401525060a0608083015282518060a08401526102ab8160c085016020870161013f565b601f01601f19169190910160c0019695505050505050565b600082516102d581846020870161013f565b9190910192915050565b80516020808301519190811015610300576000198160200360031b1b821691505b50919050565b61023d806103156000396000f3fe60806040523661000b57005b600080357fffffffff000000000000000000000000000000000000000000000000000000001681527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020819052604090912054819060601c80610125576004838101546040517fcdffacc60000000000000000000000000000000000000000000000000000000081526000357fffffffff00000000000000000000000000000000000000000000000000000000169281019290925273ffffffffffffffffffffffffffffffffffffffff169063cdffacc690602401602060405180830381865afa1580156100fe573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061012291906101ca565b90505b73ffffffffffffffffffffffffffffffffffffffff81166101a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4261727a3a2046756e6374696f6e20646f6573206e6f74206578697374000000604482015260640160405180910390fd5b3660008037600080366000845af43d6000803e8080156101c5573d6000f35b3d6000fd5b6000602082840312156101dc57600080fd5b815173ffffffffffffffffffffffffffffffffffffffff8116811461020057600080fd5b939250505056fea26469706673582212200f3fa76ace3be8675d8b4c0d6c210a922fff2c2f1444023b817d1f6c908cd56a64736f6c63430008150033a2646970667358221220329ad45a4ef4915180001cb1fc90a5f97ad94a0b280426a580cba65fce28c0f164736f6c63430008150033", + "deployedBytecode": "0x60806040523480156200001157600080fd5b5060043610620000925760003560e01c806344409a82116200006257806344409a821462000135578063b0d691fe146200015d578063b0f5d4641462000185578063c8a7adf514620001ad57600080fd5b8062c194db14620000975780630a1acd7314620000b9578063296601cd146200010757806333bb64a7146200011e575b600080fd5b620000a1620001c4565b604051620000b091906200056c565b60405180910390f35b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001620000b0565b620000e16200011836600462000635565b6200020e565b620000a16200012f36600462000695565b6200036d565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e1620001be36600462000635565b62000414565b606060405180602001620001d89062000538565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082820381018352601f90910116604052919050565b6000806200021f8686868662000414565b905073ffffffffffffffffffffffffffffffffffffffff81163b8015620002495750905062000365565b8360001b7f0000000000000000000000000000000000000000000000000000000000000000887f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008b8b604051620002e29062000538565b620002f497969594939291906200073a565b8190604051809103906000f590508015801562000315573d6000803e3d6000fd5b5060405173ffffffffffffffffffffffffffffffffffffffff821681529093507f9e6e326008e68f57877e2bae766a5745c162e42359e34834a7f0661fa82d31b19060200160405180910390a150505b949350505050565b6060600060405180602001620003839062000538565b6020820181038252601f19601f8201166040525090508089898989898989604051602001620003b997969594939291906200073a565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052620003f79291602001620007cd565b604051602081830303815290604052915050979650505050505050565b600080620004a87f0000000000000000000000000000000000000000000000000000000000000000877f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008a8a6200036d565b8051602091820120604080517fff00000000000000000000000000000000000000000000000000000000000000818501523060601b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001660218201526035810196909652605580870192909252805180870390920182526075909501909452835193019290922095945050505050565b610552806200080183390190565b60005b838110156200056357818101518382015260200162000549565b50506000910152565b60208152600082518060208401526200058d81604085016020870162000546565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b803573ffffffffffffffffffffffffffffffffffffffff81168114620005e457600080fd5b919050565b60008083601f840112620005fc57600080fd5b50813567ffffffffffffffff8111156200061557600080fd5b6020830191508360208285010111156200062e57600080fd5b9250929050565b600080600080606085870312156200064c57600080fd5b6200065785620005bf565b9350602085013567ffffffffffffffff8111156200067457600080fd5b6200068287828801620005e9565b9598909750949560400135949350505050565b600080600080600080600060c0888a031215620006b157600080fd5b620006bc88620005bf565b9650620006cc60208901620005bf565b9550620006dc60408901620005bf565b9450620006ec60608901620005bf565b9350620006fc60808901620005bf565b925060a088013567ffffffffffffffff8111156200071957600080fd5b620007278a828b01620005e9565b989b979a50959850939692959293505050565b600073ffffffffffffffffffffffffffffffffffffffff808a16835280891660208401528088166040840152808716606084015280861660808401525060c060a08301528260c0830152828460e0840137600060e0848401015260e07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f850116830101905098975050505050505050565b60008351620007e181846020880162000546565b835190830190620007f781836020880162000546565b0194935050505056fe608060405260405161055238038061055283398101604081905261002291610163565b6000858585858560405160240161003d959493929190610264565b60408051601f198184030181529181526020820180516001600160e01b0316634a93641760e01b1790525190915060009081906001600160a01b038a16906100869085906102c3565b600060405180830381855af49150503d80600081146100c1576040519150601f19603f3d011682016040523d82523d6000602084013e6100c6565b606091505b50915091508115806100e157506100dc816102df565b600114155b156100ff57604051636ff35f8960e01b815260040160405180910390fd5b505050505050505050610306565b80516001600160a01b038116811461012457600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101561015a578181015183820152602001610142565b50506000910152565b60008060008060008060c0878903121561017c57600080fd5b6101858761010d565b95506101936020880161010d565b94506101a16040880161010d565b93506101af6060880161010d565b92506101bd6080880161010d565b60a08801519092506001600160401b03808211156101da57600080fd5b818901915089601f8301126101ee57600080fd5b81518181111561020057610200610129565b604051601f8201601f19908116603f0116810190838211818310171561022857610228610129565b816040528281528c602084870101111561024157600080fd5b61025283602083016020880161013f565b80955050505050509295509295509295565b600060018060a01b0380881683528087166020840152808616604084015280851660608401525060a0608083015282518060a08401526102ab8160c085016020870161013f565b601f01601f19169190910160c0019695505050505050565b600082516102d581846020870161013f565b9190910192915050565b80516020808301519190811015610300576000198160200360031b1b821691505b50919050565b61023d806103156000396000f3fe60806040523661000b57005b600080357fffffffff000000000000000000000000000000000000000000000000000000001681527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020819052604090912054819060601c80610125576004838101546040517fcdffacc60000000000000000000000000000000000000000000000000000000081526000357fffffffff00000000000000000000000000000000000000000000000000000000169281019290925273ffffffffffffffffffffffffffffffffffffffff169063cdffacc690602401602060405180830381865afa1580156100fe573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061012291906101ca565b90505b73ffffffffffffffffffffffffffffffffffffffff81166101a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4261727a3a2046756e6374696f6e20646f6573206e6f74206578697374000000604482015260640160405180910390fd5b3660008037600080366000845af43d6000803e8080156101c5573d6000f35b3d6000fd5b6000602082840312156101dc57600080fd5b815173ffffffffffffffffffffffffffffffffffffffff8116811461020057600080fd5b939250505056fea26469706673582212200f3fa76ace3be8675d8b4c0d6c210a922fff2c2f1444023b817d1f6c908cd56a64736f6c63430008150033a2646970667358221220329ad45a4ef4915180001cb1fc90a5f97ad94a0b280426a580cba65fce28c0f164736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "Contract to easily deploy Barz to a pre-computed address with a single call", + "kind": "dev", + "methods": { + "constructor": { + "params": { + "_accountFacet": "Account Facet to be used to create Barz", + "_defaultFallback": "Default Fallback Handler to be used to create Barz", + "_entryPoint": "Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF", + "_facetRegistry": "Facet Registry to be used to create Barz" + } + }, + "createAccount(address,bytes,uint256)": { + "params": { + "_owner": "Public Key of the owner to initialize barz account", + "_salt": "Salt used for deploying barz with create2", + "_verificationFacet": "Address of verification facet used for creating the barz account" + }, + "returns": { + "barz": "Instance of Barz contract deployed with the given parameters" + } + }, + "getAddress(address,bytes,uint256)": { + "params": { + "_owner": "Public Key of the owner to initialize barz account", + "_salt": "Salt used for deploying barz with create2", + "_verificationFacet": "Address of verification facet used for creating the barz account" + }, + "returns": { + "barzAddress": "Precalculated Barz address" + } + }, + "getBytecode(address,address,address,address,address,bytes)": { + "params": { + "_accountFacet": "Account Facet to be used to create Barz", + "_defaultFallback": "Default Fallback Handler to be used to create Barz", + "_entryPoint": "Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF", + "_facetRegistry": "Facet Registry to be used to create Barz", + "_ownerPublicKey": "Public Key of owner to be used to initialize Barz ownership", + "_verificationFacet": "Verification Facet to be used to create Barz" + }, + "returns": { + "barzBytecode": "Bytecode of Barz" + } + }, + "getCreationCode()": { + "returns": { + "creationCode": "Creation code of Barz" + } + } + }, + "title": "Barz Factory", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "constructor": { + "notice": "Sets the initialization data for Barz contract initialization" + }, + "createAccount(address,bytes,uint256)": { + "notice": "Creates the Barz with a single call. It creates the Barz contract with the givent verification facet" + }, + "getAddress(address,bytes,uint256)": { + "notice": "Calculates the address of Barz with the given parameters" + }, + "getBytecode(address,address,address,address,address,bytes)": { + "notice": "Returns the bytecode of Barz with the given parameter" + }, + "getCreationCode()": { + "notice": "Returns the creation code of the Barz contract" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/bsc/DefaultFallbackHandler.json b/deployments/bsc/DefaultFallbackHandler.json new file mode 100644 index 0000000..16bce46 --- /dev/null +++ b/deployments/bsc/DefaultFallbackHandler.json @@ -0,0 +1,275 @@ +{ + "address": "0x2e7f1dAe1F3799d20f5c31bEFdc7A620f664728D", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_diamondCutFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_accountFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_tokenReceiverFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_diamondLoupeFacet", + "type": "address" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_initializationContractAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "InitializationFunctionReverted", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "indexed": false, + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "DiamondCut", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_functionSelector", + "type": "bytes4" + } + ], + "name": "facetAddress", + "outputs": [ + { + "internalType": "address", + "name": "facetAddress_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetAddresses", + "outputs": [ + { + "internalType": "address[]", + "name": "facetAddresses_", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_facet", + "type": "address" + } + ], + "name": "facetFunctionSelectors", + "outputs": [ + { + "internalType": "bytes4[]", + "name": "facetFunctionSelectors_", + "type": "bytes4[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facets", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondLoupe.Facet[]", + "name": "facets_", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0xf18b9bddf9a8d9a7d92de8ef2a0c04ef233d8e18256de185f3e055ad039c1e1b", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 108, + "gasUsed": "1438535", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000001000000000800002000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000", + "blockHash": "0x6cd70f80b3f3a859ab77c4974bc564a198fd54a9dc396413cbae2124ca994137", + "transactionHash": "0xf18b9bddf9a8d9a7d92de8ef2a0c04ef233d8e18256de185f3e055ad039c1e1b", + "logs": [ + { + "transactionIndex": 108, + "blockNumber": 33657826, + "transactionHash": "0xf18b9bddf9a8d9a7d92de8ef2a0c04ef233d8e18256de185f3e055ad039c1e1b", + "address": "0x2e7f1dAe1F3799d20f5c31bEFdc7A620f664728D", + "topics": [ + "0x8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb673" + ], + "data": "0x000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000580000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000000000000000000000000000000000003600000000000000000000000000b9504140771c3688ff041917192277d2f52e1e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000011f931c1c00000000000000000000000000000000000000000000000000000000000000000000000000000000fde53272dcd7938d16e031a6989753c321728332000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000005b61d27f60000000000000000000000000000000000000000000000000000000047e1da2a000000000000000000000000000000000000000000000000000000003a871cdd00000000000000000000000000000000000000000000000000000000d087d28800000000000000000000000000000000000000000000000000000000b0d691fe000000000000000000000000000000000000000000000000000000000000000000000000000000003143e1c0af0cdc153423863923cf4e3818e34daa000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000005150b7a0200000000000000000000000000000000000000000000000000000000f23a6e6100000000000000000000000000000000000000000000000000000000bc197c81000000000000000000000000000000000000000000000000000000000023de2900000000000000000000000000000000000000000000000000000000a4c0ed3600000000000000000000000000000000000000000000000000000000000000000000000000000000ce36b85d12d81cd619c745c7717f3396e184ac7c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000097a0ed62700000000000000000000000000000000000000000000000000000000adfca15e0000000000000000000000000000000000000000000000000000000052ef6b2c00000000000000000000000000000000000000000000000000000000cdffacc60000000000000000000000000000000000000000000000000000000001ffc9a700000000000000000000000000000000000000000000000000000000f9796ccf0000000000000000000000000000000000000000000000000000000001a5502200000000000000000000000000000000000000000000000000000000d42139a900000000000000000000000000000000000000000000000000000000e3a2f6fe000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "logIndex": 533, + "blockHash": "0x6cd70f80b3f3a859ab77c4974bc564a198fd54a9dc396413cbae2124ca994137" + } + ], + "blockNumber": 33657826, + "cumulativeGasUsed": "14698886", + "status": 1, + "byzantium": true + }, + "args": [ + "0x0B9504140771C3688Ff041917192277D2f52E1e0", + "0xFde53272dcd7938d16E031A6989753c321728332", + "0x3143E1C0Af0Cdc153423863923Cf4e3818e34Daa", + "0xCe36b85d12D81cd619C745c7717f3396E184Ac7C" + ], + "numDeployments": 4, + "solcInputHash": "4356503edd8ae34e73cb6dd1c8e2fc8a", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_diamondCutFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_accountFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_tokenReceiverFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_diamondLoupeFacet\",\"type\":\"address\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_initializationContractAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"InitializationFunctionReverted\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"DiamondCut\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_functionSelector\",\"type\":\"bytes4\"}],\"name\":\"facetAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"facetAddress_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetAddresses\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"facetAddresses_\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_facet\",\"type\":\"address\"}],\"name\":\"facetFunctionSelectors\",\"outputs\":[{\"internalType\":\"bytes4[]\",\"name\":\"facetFunctionSelectors_\",\"type\":\"bytes4[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facets\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondLoupe.Facet[]\",\"name\":\"facets_\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"A default fallback handler for Barz\",\"kind\":\"dev\",\"methods\":{\"constructor\":{\"details\":\"This contract is also a diamond that holds the default facets to reduce gas cost for wallet activation. Within the constructor this conducts diamond cut to initially setup the diamond. This is a non-upgradeable contract\",\"params\":{\"_accountFacet\":\"Address account facet\",\"_diamondCutFacet\":\"Address if diamond cut facet\",\"_diamondLoupeFacet\":\"Address of diamond loupe facet\",\"_tokenReceiverFacet\":\"Address of token receiver facet\"}},\"facetAddress(bytes4)\":{\"details\":\"If facet is not found return address(0).\",\"params\":{\"_functionSelector\":\"The function selector.\"},\"returns\":{\"facetAddress_\":\"The facet address.\"}},\"facetAddresses()\":{\"returns\":{\"facetAddresses_\":\"facetAddresses_\"}},\"facetFunctionSelectors(address)\":{\"params\":{\"_facet\":\"The facet address.\"},\"returns\":{\"facetFunctionSelectors_\":\"facetFunctionSelectors_\"}},\"facets()\":{\"returns\":{\"facets_\":\"The facet struct array including all facet information\"}}},\"title\":\"DefaultFallbackHandler\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"Sets the middleware diamond for Barz wallet as a fallback handler\"},\"facetAddress(bytes4)\":{\"notice\":\"Gets the facet that supports the given selector.\"},\"facetAddresses()\":{\"notice\":\"Get all the facet addresses used by a diamond.\"},\"facetFunctionSelectors(address)\":{\"notice\":\"Gets all the function selectors provided by a facet.\"},\"facets()\":{\"notice\":\"Returns the facet information of call facets registered to this diamond.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/infrastructure/DefaultFallbackHandler.sol\":\"DefaultFallbackHandler\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/introspection/IERC165.sol\\\";\\n\\n/**\\n * @dev _Available since v3.1._\\n */\\ninterface IERC1155Receiver is IERC165 {\\n /**\\n * @dev Handles the receipt of a single ERC1155 token type. This function is\\n * called at the end of a `safeTransferFrom` after the balance has been updated.\\n *\\n * NOTE: To accept the transfer, this must return\\n * `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))`\\n * (i.e. 0xf23a6e61, or its own function selector).\\n *\\n * @param operator The address which initiated the transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param id The ID of the token being transferred\\n * @param value The amount of tokens being transferred\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155Received(\\n address operator,\\n address from,\\n uint256 id,\\n uint256 value,\\n bytes calldata data\\n ) external returns (bytes4);\\n\\n /**\\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\\n * is called at the end of a `safeBatchTransferFrom` after the balances have\\n * been updated.\\n *\\n * NOTE: To accept the transfer(s), this must return\\n * `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))`\\n * (i.e. 0xbc197c81, or its own function selector).\\n *\\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155BatchReceived(\\n address operator,\\n address from,\\n uint256[] calldata ids,\\n uint256[] calldata values,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xeb373f1fdc7b755c6a750123a9b9e3a8a02c1470042fd6505d875000a80bde0b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title ERC721 token receiver interface\\n * @dev Interface for any contract that wants to support safeTransfers\\n * from ERC721 asset contracts.\\n */\\ninterface IERC721Receiver {\\n /**\\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\\n * by `operator` from `from`, this function is called.\\n *\\n * It must return its Solidity selector to confirm the token transfer.\\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\\n *\\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\\n */\\n function onERC721Received(\\n address operator,\\n address from,\\n uint256 tokenId,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\\n *\\n * Accounts can be notified of {IERC777} tokens being sent to them by having a\\n * contract implement this interface (contract holders can be their own\\n * implementer) and registering it on the\\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\\n *\\n * See {IERC1820Registry} and {ERC1820Implementer}.\\n */\\ninterface IERC777Recipient {\\n /**\\n * @dev Called by an {IERC777} token contract whenever tokens are being\\n * moved or created into a registered account (`to`). The type of operation\\n * is conveyed by `from` being the zero address or not.\\n *\\n * This call occurs _after_ the token contract's state is updated, so\\n * {IERC777-balanceOf}, etc., can be used to query the post-operation state.\\n *\\n * This function may revert to prevent the operation from being executed.\\n */\\n function tokensReceived(\\n address operator,\\n address from,\\n address to,\\n uint256 amount,\\n bytes calldata userData,\\n bytes calldata operatorData\\n ) external;\\n}\\n\",\"keccak256\":\"0x1a5d61db2733202ba361e6d6741cd2e662380e22b80e987eacfc91973f2267dc\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"contracts/aa-4337/core/BaseAccount.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-empty-blocks */\\n\\nimport \\\"../interfaces/IAccount.sol\\\";\\nimport \\\"../interfaces/IEntryPoint.sol\\\";\\nimport \\\"./Helpers.sol\\\";\\n\\n/**\\n * Basic account implementation.\\n * this contract provides the basic logic for implementing the IAccount interface - validateUserOp\\n * specific account implementation should inherit it and provide the account-specific logic\\n */\\nabstract contract BaseAccount is IAccount {\\n using UserOperationLib for UserOperation;\\n\\n //return value in case of signature failure, with no time-range.\\n // equivalent to _packValidationData(true,0,0);\\n uint256 internal constant SIG_VALIDATION_FAILED = 1;\\n\\n /**\\n * Return the account nonce.\\n * This method returns the next sequential nonce.\\n * For a nonce of a specific key, use `entrypoint.getNonce(account, key)`\\n */\\n function getNonce() public view virtual returns (uint256) {\\n return entryPoint().getNonce(address(this), 0);\\n }\\n\\n /**\\n * return the entryPoint used by this account.\\n * subclass should return the current entryPoint used by this account.\\n */\\n function entryPoint() public view virtual returns (IEntryPoint);\\n\\n /**\\n * Validate user's signature and nonce.\\n * subclass doesn't need to override this method. Instead, it should override the specific internal validation methods.\\n */\\n function validateUserOp(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n uint256 missingAccountFunds\\n ) external virtual override returns (uint256 validationData) {\\n _requireFromEntryPoint();\\n validationData = _validateSignature(userOp, userOpHash);\\n _validateNonce(userOp.nonce);\\n _payPrefund(missingAccountFunds);\\n }\\n\\n /**\\n * ensure the request comes from the known entrypoint.\\n */\\n function _requireFromEntryPoint() internal view virtual {\\n require(\\n msg.sender == address(entryPoint()),\\n \\\"account: not from EntryPoint\\\"\\n );\\n }\\n\\n /**\\n * validate the signature is valid for this message.\\n * @param userOp validate the userOp.signature field\\n * @param userOpHash convenient field: the hash of the request, to check the signature against\\n * (also hashes the entrypoint and chain id)\\n * @return validationData signature and time-range of this operation\\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\\n * otherwise, an address of an \\\"authorizer\\\" contract.\\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \\\"indefinite\\\"\\n * <6-byte> validAfter - first timestamp this operation is valid\\n * If the account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\\n */\\n function _validateSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) internal virtual returns (uint256 validationData);\\n\\n /**\\n * Validate the nonce of the UserOperation.\\n * This method may validate the nonce requirement of this account.\\n * e.g.\\n * To limit the nonce to use sequenced UserOps only (no \\\"out of order\\\" UserOps):\\n * `require(nonce < type(uint64).max)`\\n * For a hypothetical account that *requires* the nonce to be out-of-order:\\n * `require(nonce & type(uint64).max == 0)`\\n *\\n * The actual nonce uniqueness is managed by the EntryPoint, and thus no other\\n * action is needed by the account itself.\\n *\\n * @param nonce to validate\\n *\\n * solhint-disable-next-line no-empty-blocks\\n */\\n function _validateNonce(uint256 nonce) internal view virtual {}\\n\\n /**\\n * sends to the entrypoint (msg.sender) the missing funds for this transaction.\\n * subclass MAY override this method for better funds management\\n * (e.g. send to the entryPoint more than the minimum required, so that in future transactions\\n * it will not be required to send again)\\n * @param missingAccountFunds the minimum value this method should send the entrypoint.\\n * this value MAY be zero, in case there is enough deposit, or the userOp has a paymaster.\\n */\\n function _payPrefund(uint256 missingAccountFunds) internal virtual {\\n if (missingAccountFunds != 0) {\\n (bool success, ) = payable(msg.sender).call{\\n value: missingAccountFunds,\\n gas: type(uint256).max\\n }(\\\"\\\");\\n (success);\\n //ignore failure (its EntryPoint's job to verify, not account.)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa0dcc386b0f04711db3e394fb50e55a3b3b1a4d19fac1f10895844e1aa4e3d5c\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/core/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable no-inline-assembly */\\n\\n/**\\n * returned data from validateUserOp.\\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\\n * @param aggregator - address(0) - the account validated the signature by itself.\\n * address(1) - the account failed to validate the signature.\\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\\n * @param validAfter - this UserOp is valid only after this timestamp.\\n * @param validaUntil - this UserOp is valid only up to this timestamp.\\n */\\nstruct ValidationData {\\n address aggregator;\\n uint48 validAfter;\\n uint48 validUntil;\\n}\\n\\n//extract sigFailed, validAfter, validUntil.\\n// also convert zero validUntil to type(uint48).max\\nfunction _parseValidationData(\\n uint validationData\\n) pure returns (ValidationData memory data) {\\n address aggregator = address(uint160(validationData));\\n uint48 validUntil = uint48(validationData >> 160);\\n if (validUntil == 0) {\\n validUntil = type(uint48).max;\\n }\\n uint48 validAfter = uint48(validationData >> (48 + 160));\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n// intersect account and paymaster ranges.\\nfunction _intersectTimeRange(\\n uint256 validationData,\\n uint256 paymasterValidationData\\n) pure returns (ValidationData memory) {\\n ValidationData memory accountValidationData = _parseValidationData(\\n validationData\\n );\\n ValidationData memory pmValidationData = _parseValidationData(\\n paymasterValidationData\\n );\\n address aggregator = accountValidationData.aggregator;\\n if (aggregator == address(0)) {\\n aggregator = pmValidationData.aggregator;\\n }\\n uint48 validAfter = accountValidationData.validAfter;\\n uint48 validUntil = accountValidationData.validUntil;\\n uint48 pmValidAfter = pmValidationData.validAfter;\\n uint48 pmValidUntil = pmValidationData.validUntil;\\n\\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp\\n * @param data - the ValidationData to pack\\n */\\nfunction _packValidationData(\\n ValidationData memory data\\n) pure returns (uint256) {\\n return\\n uint160(data.aggregator) |\\n (uint256(data.validUntil) << 160) |\\n (uint256(data.validAfter) << (160 + 48));\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp, when not using an aggregator\\n * @param sigFailed - true for signature failure, false for success\\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\\n * @param validAfter first timestamp this UserOperation is valid\\n */\\nfunction _packValidationData(\\n bool sigFailed,\\n uint48 validUntil,\\n uint48 validAfter\\n) pure returns (uint256) {\\n return\\n (sigFailed ? 1 : 0) |\\n (uint256(validUntil) << 160) |\\n (uint256(validAfter) << (160 + 48));\\n}\\n\\n/**\\n * keccak function over calldata.\\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\\n */\\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\\n assembly {\\n let mem := mload(0x40)\\n let len := data.length\\n calldatacopy(mem, data.offset, len)\\n ret := keccak256(mem, len)\\n }\\n}\\n\",\"keccak256\":\"0xa79f06cd158ecb8c0da95493a2f348933b8627a63e228b99738bff3aa107942d\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAccount.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\ninterface IAccount {\\n /**\\n * Validate user's signature and nonce\\n * the entryPoint will make the call to the recipient only if this validation call returns successfully.\\n * signature failure should be reported by returning SIG_VALIDATION_FAILED (1).\\n * This allows making a \\\"simulation call\\\" without a valid signature\\n * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure.\\n *\\n * @dev Must validate caller is the entryPoint.\\n * Must validate the signature and nonce\\n * @param userOp the operation that is about to be executed.\\n * @param userOpHash hash of the user's request data. can be used as the basis for signature.\\n * @param missingAccountFunds missing funds on the account's deposit in the entrypoint.\\n * This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call.\\n * The excess is left as a deposit in the entrypoint, for future calls.\\n * can be withdrawn anytime using \\\"entryPoint.withdrawTo()\\\"\\n * In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero.\\n * @return validationData packaged ValidationData structure. use `_packValidationData` and `_unpackValidationData` to encode and decode\\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\\n * otherwise, an address of an \\\"authorizer\\\" contract.\\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \\\"indefinite\\\"\\n * <6-byte> validAfter - first timestamp this operation is valid\\n * If an account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\\n */\\n function validateUserOp(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n uint256 missingAccountFunds\\n ) external returns (uint256 validationData);\\n}\\n\",\"keccak256\":\"0xcbc4b0973cf954c5895b7796335f651fbfcfb55f67dfa789a3d354f8e23c4f2b\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAggregator.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\n/**\\n * Aggregated Signatures validator.\\n */\\ninterface IAggregator {\\n /**\\n * validate aggregated signature.\\n * revert if the aggregated signature does not match the given list of operations.\\n */\\n function validateSignatures(\\n UserOperation[] calldata userOps,\\n bytes calldata signature\\n ) external view;\\n\\n /**\\n * validate signature of a single userOp\\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\\n * @param userOp the userOperation received from the user.\\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\\n * (usually empty, unless account and aggregator support some kind of \\\"multisig\\\"\\n */\\n function validateUserOpSignature(\\n UserOperation calldata userOp\\n ) external view returns (bytes memory sigForUserOp);\\n\\n /**\\n * aggregate multiple signatures into a single value.\\n * This method is called off-chain to calculate the signature to pass with handleOps()\\n * bundler MAY use optimized custom code perform this aggregation\\n * @param userOps array of UserOperations to collect the signatures from.\\n * @return aggregatedSignature the aggregated signature\\n */\\n function aggregateSignatures(\\n UserOperation[] calldata userOps\\n ) external view returns (bytes memory aggregatedSignature);\\n}\\n\",\"keccak256\":\"0xdfdcd80568f037716674619b31be630fcd8316262f05a815b41d1e81782c966a\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IEntryPoint.sol\":{\"content\":\"/**\\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\\n ** Only one instance required on each chain.\\n **/\\n// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-inline-assembly */\\n/* solhint-disable reason-string */\\n\\nimport \\\"./UserOperation.sol\\\";\\nimport \\\"./IStakeManager.sol\\\";\\nimport \\\"./IAggregator.sol\\\";\\nimport \\\"./INonceManager.sol\\\";\\n\\ninterface IEntryPoint is IStakeManager, INonceManager {\\n /***\\n * An event emitted after each successful request\\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\\n * @param sender - the account that generates this request.\\n * @param paymaster - if non-null, the paymaster that pays for this request.\\n * @param nonce - the nonce value from the request.\\n * @param success - true if the sender transaction succeeded, false if reverted.\\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\\n */\\n event UserOperationEvent(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address indexed paymaster,\\n uint256 nonce,\\n bool success,\\n uint256 actualGasCost,\\n uint256 actualGasUsed\\n );\\n\\n /**\\n * account \\\"sender\\\" was deployed.\\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\\n * @param sender the account that is deployed\\n * @param factory the factory used to deploy this account (in the initCode)\\n * @param paymaster the paymaster used by this UserOp\\n */\\n event AccountDeployed(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address factory,\\n address paymaster\\n );\\n\\n /**\\n * An event emitted if the UserOperation \\\"callData\\\" reverted with non-zero length\\n * @param userOpHash the request unique identifier.\\n * @param sender the sender of this request\\n * @param nonce the nonce used in the request\\n * @param revertReason - the return bytes from the (reverted) call to \\\"callData\\\".\\n */\\n event UserOperationRevertReason(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n uint256 nonce,\\n bytes revertReason\\n );\\n\\n /**\\n * an event emitted by handleOps(), before starting the execution loop.\\n * any event emitted before this event, is part of the validation.\\n */\\n event BeforeExecution();\\n\\n /**\\n * signature aggregator used by the following UserOperationEvents within this bundle.\\n */\\n event SignatureAggregatorChanged(address indexed aggregator);\\n\\n /**\\n * a custom revert error of handleOps, to identify the offending op.\\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\\n * @param reason - revert reason\\n * The string starts with a unique code \\\"AAmn\\\", where \\\"m\\\" is \\\"1\\\" for factory, \\\"2\\\" for account and \\\"3\\\" for paymaster issues,\\n * so a failure can be attributed to the correct entity.\\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\\n */\\n error FailedOp(uint256 opIndex, string reason);\\n\\n /**\\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\\n */\\n error SignatureValidationFailed(address aggregator);\\n\\n /**\\n * Successful result from simulateValidation.\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n */\\n error ValidationResult(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo\\n );\\n\\n /**\\n * Successful result from simulateValidation, if the account returns a signature aggregator\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\\n * bundler MUST use it to verify the signature, or reject the UserOperation\\n */\\n error ValidationResultWithAggregation(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo,\\n AggregatorStakeInfo aggregatorInfo\\n );\\n\\n /**\\n * return value of getSenderAddress\\n */\\n error SenderAddressResult(address sender);\\n\\n /**\\n * return value of simulateHandleOp\\n */\\n error ExecutionResult(\\n uint256 preOpGas,\\n uint256 paid,\\n uint48 validAfter,\\n uint48 validUntil,\\n bool targetSuccess,\\n bytes targetResult\\n );\\n\\n //UserOps handled, per aggregator\\n struct UserOpsPerAggregator {\\n UserOperation[] userOps;\\n // aggregator address\\n IAggregator aggregator;\\n // aggregated signature\\n bytes signature;\\n }\\n\\n /**\\n * Execute a batch of UserOperation.\\n * no signature aggregator is used.\\n * if any account requires an aggregator (that is, it returned an aggregator when\\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\\n * @param ops the operations to execute\\n * @param beneficiary the address to receive the fees\\n */\\n function handleOps(\\n UserOperation[] calldata ops,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * Execute a batch of UserOperation with Aggregators\\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\\n * @param beneficiary the address to receive the fees\\n */\\n function handleAggregatedOps(\\n UserOpsPerAggregator[] calldata opsPerAggregator,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * generate a request Id - unique identifier for this request.\\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\\n */\\n function getUserOpHash(\\n UserOperation calldata userOp\\n ) external view returns (bytes32);\\n\\n /**\\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\\n * @param userOp the user operation to validate.\\n */\\n function simulateValidation(UserOperation calldata userOp) external;\\n\\n /**\\n * gas and return values during simulation\\n * @param preOpGas the gas used for validation (including preValidationGas)\\n * @param prefund the required prefund for this operation\\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\\n */\\n struct ReturnInfo {\\n uint256 preOpGas;\\n uint256 prefund;\\n bool sigFailed;\\n uint48 validAfter;\\n uint48 validUntil;\\n bytes paymasterContext;\\n }\\n\\n /**\\n * returned aggregated signature info.\\n * the aggregator returned by the account, and its current stake.\\n */\\n struct AggregatorStakeInfo {\\n address aggregator;\\n StakeInfo stakeInfo;\\n }\\n\\n /**\\n * Get counterfactual sender address.\\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\\n * this method always revert, and returns the address in SenderAddressResult error\\n * @param initCode the constructor code to be passed into the UserOperation.\\n */\\n function getSenderAddress(bytes memory initCode) external;\\n\\n /**\\n * simulate full execution of a UserOperation (including both validation and target execution)\\n * this method will always revert with \\\"ExecutionResult\\\".\\n * it performs full validation of the UserOperation, but ignores signature error.\\n * an optional target address is called after the userop succeeds, and its value is returned\\n * (before the entire call is reverted)\\n * Note that in order to collect the the success/failure of the target call, it must be executed\\n * with trace enabled to track the emitted events.\\n * @param op the UserOperation to simulate\\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\\n * are set to the return from that call.\\n * @param targetCallData callData to pass to target address\\n */\\n function simulateHandleOp(\\n UserOperation calldata op,\\n address target,\\n bytes calldata targetCallData\\n ) external;\\n}\\n\",\"keccak256\":\"0x9ccb1b188eda8bbf5f6c2d01bd83c3d8b2b04fcf745283051d31fe96d1d8e40f\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/INonceManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\ninterface INonceManager {\\n /**\\n * Return the next nonce for this sender.\\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\\n * But UserOp with different keys can come with arbitrary order.\\n *\\n * @param sender the account address\\n * @param key the high 192 bit of the nonce\\n * @return nonce a full nonce to pass for next UserOp with this sender.\\n */\\n function getNonce(\\n address sender,\\n uint192 key\\n ) external view returns (uint256 nonce);\\n\\n /**\\n * Manually increment the nonce of the sender.\\n * This method is exposed just for completeness..\\n * Account does NOT need to call it, neither during validation, nor elsewhere,\\n * as the EntryPoint will update the nonce regardless.\\n * Possible use-case is call it with various keys to \\\"initialize\\\" their nonces to one, so that future\\n * UserOperations will not pay extra for the first transaction with a given key.\\n */\\n function incrementNonce(uint192 key) external;\\n}\\n\",\"keccak256\":\"0xce478ad0fa0d18a3b785ac854623029e7ab463d05873dfaa365abfa1bf100912\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IStakeManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8.12;\\n\\n/**\\n * manage deposits and stakes.\\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\\n * stake is value locked for at least \\\"unstakeDelay\\\" by the staked entity.\\n */\\ninterface IStakeManager {\\n event Deposited(address indexed account, uint256 totalDeposit);\\n\\n event Withdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /// Emitted when stake or unstake delay are modified\\n event StakeLocked(\\n address indexed account,\\n uint256 totalStaked,\\n uint256 unstakeDelaySec\\n );\\n\\n /// Emitted once a stake is scheduled for withdrawal\\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\\n\\n event StakeWithdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /**\\n * @param deposit the entity's deposit\\n * @param staked true if this entity is staked.\\n * @param stake actual amount of ether staked for this entity.\\n * @param unstakeDelaySec minimum delay to withdraw the stake.\\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\\n * and the rest fit into a 2nd cell.\\n * 112 bit allows for 10^15 eth\\n * 48 bit for full timestamp\\n * 32 bit allows 150 years for unstake delay\\n */\\n struct DepositInfo {\\n uint112 deposit;\\n bool staked;\\n uint112 stake;\\n uint32 unstakeDelaySec;\\n uint48 withdrawTime;\\n }\\n\\n //API struct used by getStakeInfo and simulateValidation\\n struct StakeInfo {\\n uint256 stake;\\n uint256 unstakeDelaySec;\\n }\\n\\n /// @return info - full deposit information of given account\\n function getDepositInfo(\\n address account\\n ) external view returns (DepositInfo memory info);\\n\\n /// @return the deposit (for gas payment) of the account\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * add to the deposit of the given account\\n */\\n function depositTo(address account) external payable;\\n\\n /**\\n * add to the account's stake - amount and delay\\n * any pending unstake is first cancelled.\\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\\n */\\n function addStake(uint32 _unstakeDelaySec) external payable;\\n\\n /**\\n * attempt to unlock the stake.\\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\\n */\\n function unlockStake() external;\\n\\n /**\\n * withdraw from the (unlocked) stake.\\n * must first call unlockStake and wait for the unstakeDelay to pass\\n * @param withdrawAddress the address to send withdrawn value.\\n */\\n function withdrawStake(address payable withdrawAddress) external;\\n\\n /**\\n * withdraw from the deposit.\\n * @param withdrawAddress the address to send withdrawn value.\\n * @param withdrawAmount the amount to withdraw.\\n */\\n function withdrawTo(\\n address payable withdrawAddress,\\n uint256 withdrawAmount\\n ) external;\\n}\\n\",\"keccak256\":\"0xadcea606c9b7aafe6645441f2154a60f271330b0eee5292a632aa71c1672d546\",\"license\":\"GPL-3.0-only\"},\"contracts/aa-4337/interfaces/UserOperation.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable no-inline-assembly */\\n\\nimport {calldataKeccak} from \\\"../core/Helpers.sol\\\";\\n\\n/**\\n * User Operation struct\\n * @param sender the sender account of this request.\\n * @param nonce unique value the sender uses to verify it is not a replay.\\n * @param initCode if set, the account contract will be created by this constructor/\\n * @param callData the method call to execute on this account.\\n * @param callGasLimit the gas limit passed to the callData method call.\\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\\n * @param maxFeePerGas same as EIP-1559 gas parameter.\\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\\n */\\nstruct UserOperation {\\n address sender;\\n uint256 nonce;\\n bytes initCode;\\n bytes callData;\\n uint256 callGasLimit;\\n uint256 verificationGasLimit;\\n uint256 preVerificationGas;\\n uint256 maxFeePerGas;\\n uint256 maxPriorityFeePerGas;\\n bytes paymasterAndData;\\n bytes signature;\\n}\\n\\n/**\\n * Utility functions helpful when working with UserOperation structs.\\n */\\nlibrary UserOperationLib {\\n function getSender(\\n UserOperation calldata userOp\\n ) internal pure returns (address) {\\n address data;\\n //read sender from userOp, which is first userOp member (saves 800 gas...)\\n assembly {\\n data := calldataload(userOp)\\n }\\n return address(uint160(data));\\n }\\n\\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\\n // pay above what he signed for.\\n function gasPrice(\\n UserOperation calldata userOp\\n ) internal view returns (uint256) {\\n unchecked {\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n if (maxFeePerGas == maxPriorityFeePerGas) {\\n //legacy mode (for networks that don't support basefee opcode)\\n return maxFeePerGas;\\n }\\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\\n }\\n }\\n\\n function pack(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes memory ret) {\\n address sender = getSender(userOp);\\n uint256 nonce = userOp.nonce;\\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\\n bytes32 hashCallData = calldataKeccak(userOp.callData);\\n uint256 callGasLimit = userOp.callGasLimit;\\n uint256 verificationGasLimit = userOp.verificationGasLimit;\\n uint256 preVerificationGas = userOp.preVerificationGas;\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\\n\\n return\\n abi.encode(\\n sender,\\n nonce,\\n hashInitCode,\\n hashCallData,\\n callGasLimit,\\n verificationGasLimit,\\n preVerificationGas,\\n maxFeePerGas,\\n maxPriorityFeePerGas,\\n hashPaymasterAndData\\n );\\n }\\n\\n function hash(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes32) {\\n return keccak256(pack(userOp));\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n}\\n\",\"keccak256\":\"0x2429f5cc546bdee08c7e63858d0dda8491eaa3ab5194df884dc948c1154d2834\",\"license\":\"GPL-3.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IStorageLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"./IDiamondLoupe.sol\\\";\\n\\n/**\\n * @title LoupeFromStorage Interface\\n * @dev Interface contract to function as a loupe facet directly attached to diamond storage of Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IStorageLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facetsFromStorage()\\n external\\n view\\n returns (IDiamondLoupe.Facet[] memory);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n function facetFunctionSelectorsFromStorage(\\n address _facet\\n ) external view returns (bytes4[] memory);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n function facetAddressesFromStorage()\\n external\\n view\\n returns (address[] memory);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n function facetAddressFromStorage(\\n bytes4 _functionSelector\\n ) external view returns (address);\\n}\\n\",\"keccak256\":\"0xdf5dc9c57319e9087628c9cf9404b4f75585b76d1c2f4f59ee796c933967ea5c\",\"license\":\"Apache-2.0\"},\"contracts/facets/interfaces/IAccountFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IEntryPoint} from \\\"../../aa-4337/interfaces/IEntryPoint.sol\\\";\\n\\n/**\\n * @title Account Facet Interface\\n * @dev Interface of module contract that provides the account features and init/unitialization of signer\\n * compatible with EIP-1271 & EIP-4337\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IAccountFacet {\\n event AccountInitialized(\\n IEntryPoint indexed entryPoint,\\n bytes indexed ownerPublicKey\\n );\\n // NOTE: Added Below Event\\n event VerificationSuccess(bytes32);\\n event VerificationFailure(bytes32);\\n\\n error AccountFacet__InitializationFailure();\\n error AccountFacet__RestrictionsFailure();\\n error AccountFacet__NonExistentVerificationFacet();\\n error AccountFacet__CallNotSuccessful();\\n error AccountFacet__InvalidArrayLength();\\n\\n function initialize(\\n address verificationFacet,\\n address anEntryPoint,\\n address facetRegistry,\\n address _defaultFallBack,\\n bytes calldata _ownerPublicKey\\n ) external returns (uint256);\\n\\n function execute(address dest, uint256 value, bytes calldata func) external;\\n\\n function executeBatch(\\n address[] calldata dest,\\n uint256[] calldata value,\\n bytes[] calldata func\\n ) external;\\n}\\n\",\"keccak256\":\"0x74a9cb0b8f2f4a5148e366a401a0354426c536c012c025025d07cc25a4cd5382\",\"license\":\"Apache-2.0\"},\"contracts/infrastructure/DefaultFallbackHandler.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IERC721Receiver} from \\\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\\\";\\nimport {IERC1155Receiver} from \\\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\\\";\\nimport {IERC777Recipient} from \\\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\\\";\\nimport {BaseAccount} from \\\"../aa-4337/core/BaseAccount.sol\\\";\\nimport {DefaultLibDiamond} from \\\"../libraries/DefaultLibDiamond.sol\\\";\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IAccountFacet} from \\\"../facets/interfaces/IAccountFacet.sol\\\";\\nimport {IStorageLoupe} from \\\"../facets/base/interfaces/IStorageLoupe.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\nimport {IERC677Receiver} from \\\"../interfaces/ERC/IERC677Receiver.sol\\\";\\nimport {IERC165} from \\\"../interfaces/ERC/IERC165.sol\\\";\\n\\n/**\\n * @title DefaultFallbackHandler\\n * @dev A default fallback handler for Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract DefaultFallbackHandler is IDiamondLoupe {\\n /**\\n * @notice Sets the middleware diamond for Barz wallet as a fallback handler\\n * @dev This contract is also a diamond that holds the default facets to reduce gas cost for wallet activation.\\n * Within the constructor this conducts diamond cut to initially setup the diamond. This is a non-upgradeable contract\\n * @param _diamondCutFacet Address if diamond cut facet\\n * @param _accountFacet Address account facet\\n * @param _tokenReceiverFacet Address of token receiver facet\\n * @param _diamondLoupeFacet Address of diamond loupe facet\\n */\\n constructor(\\n address _diamondCutFacet,\\n address _accountFacet,\\n address _tokenReceiverFacet,\\n address _diamondLoupeFacet\\n ) payable {\\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](4);\\n bytes4[] memory functionSelectors = new bytes4[](1);\\n functionSelectors[0] = IDiamondCut.diamondCut.selector;\\n\\n bytes4[] memory accountFunctionSelectors = new bytes4[](5);\\n accountFunctionSelectors[0] = IAccountFacet.execute.selector;\\n accountFunctionSelectors[1] = IAccountFacet.executeBatch.selector;\\n accountFunctionSelectors[2] = BaseAccount.validateUserOp.selector;\\n accountFunctionSelectors[3] = BaseAccount.getNonce.selector;\\n accountFunctionSelectors[4] = BaseAccount.entryPoint.selector;\\n\\n bytes4[] memory receiverFacetSelectors = new bytes4[](5);\\n receiverFacetSelectors[0] = IERC721Receiver.onERC721Received.selector;\\n receiverFacetSelectors[1] = IERC1155Receiver.onERC1155Received.selector;\\n receiverFacetSelectors[2] = IERC1155Receiver\\n .onERC1155BatchReceived\\n .selector;\\n receiverFacetSelectors[3] = IERC777Recipient.tokensReceived.selector;\\n receiverFacetSelectors[4] = IERC677Receiver.onTokenTransfer.selector;\\n\\n bytes4[] memory loupeFacetSelectors = new bytes4[](9);\\n loupeFacetSelectors[0] = IDiamondLoupe.facets.selector;\\n loupeFacetSelectors[1] = IDiamondLoupe.facetFunctionSelectors.selector;\\n loupeFacetSelectors[2] = IDiamondLoupe.facetAddresses.selector;\\n loupeFacetSelectors[3] = IDiamondLoupe.facetAddress.selector;\\n loupeFacetSelectors[4] = IERC165.supportsInterface.selector;\\n loupeFacetSelectors[5] = IStorageLoupe.facetsFromStorage.selector;\\n loupeFacetSelectors[6] = IStorageLoupe\\n .facetFunctionSelectorsFromStorage\\n .selector;\\n loupeFacetSelectors[7] = IStorageLoupe\\n .facetAddressesFromStorage\\n .selector;\\n loupeFacetSelectors[8] = IStorageLoupe.facetAddressFromStorage.selector;\\n\\n {\\n cut[0] = IDiamondCut.FacetCut({\\n facetAddress: _diamondCutFacet,\\n action: IDiamondCut.FacetCutAction.Add,\\n functionSelectors: functionSelectors\\n });\\n cut[1] = IDiamondCut.FacetCut({\\n facetAddress: _accountFacet,\\n action: IDiamondCut.FacetCutAction.Add,\\n functionSelectors: accountFunctionSelectors\\n });\\n cut[2] = IDiamondCut.FacetCut({\\n facetAddress: _tokenReceiverFacet,\\n action: IDiamondCut.FacetCutAction.Add,\\n functionSelectors: receiverFacetSelectors\\n });\\n cut[3] = IDiamondCut.FacetCut({\\n facetAddress: _diamondLoupeFacet,\\n action: IDiamondCut.FacetCutAction.Add,\\n functionSelectors: loupeFacetSelectors\\n });\\n\\n DefaultLibDiamond.diamondCut(cut, address(0), \\\"\\\");\\n }\\n }\\n\\n /**\\n * @notice Returns the facet information of call facets registered to this diamond.\\n * @return facets_ The facet struct array including all facet information\\n */\\n function facets() external view override returns (Facet[] memory facets_) {\\n DefaultLibDiamond.DiamondStorage storage ds = DefaultLibDiamond\\n .diamondStorage();\\n uint256 numFacets = ds.facetAddresses.length;\\n facets_ = new Facet[](numFacets);\\n for (uint256 i; i < numFacets; ) {\\n address facetAddress_ = ds.facetAddresses[i];\\n facets_[i].facetAddress = facetAddress_;\\n facets_[i].functionSelectors = ds\\n .facetFunctionSelectors[facetAddress_]\\n .functionSelectors;\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * @notice Gets all the function selectors provided by a facet.\\n * @param _facet The facet address.\\n * @return facetFunctionSelectors_\\n */\\n function facetFunctionSelectors(\\n address _facet\\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\\n facetFunctionSelectors_ = DefaultLibDiamond\\n .diamondStorage()\\n .facetFunctionSelectors[_facet]\\n .functionSelectors;\\n }\\n\\n /**\\n * @notice Get all the facet addresses used by a diamond.\\n * @return facetAddresses_\\n */\\n function facetAddresses()\\n external\\n view\\n override\\n returns (address[] memory facetAddresses_)\\n {\\n facetAddresses_ = DefaultLibDiamond.diamondStorage().facetAddresses;\\n }\\n\\n /** @notice Gets the facet that supports the given selector.\\n * @dev If facet is not found return address(0).\\n * @param _functionSelector The function selector.\\n * @return facetAddress_ The facet address.\\n */\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view override returns (address facetAddress_) {\\n facetAddress_ = DefaultLibDiamond\\n .diamondStorage()\\n .selectorToFacetAndPosition[_functionSelector]\\n .facetAddress;\\n }\\n}\\n\",\"keccak256\":\"0xa482fe778481e34e9fb3c4074231f8048437e934c0ca9a0c78e8e61d3a24470a\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.21;\\n\\ninterface IERC165 {\\n /// @notice Query if a contract implements an interface\\n /// @param interfaceId The interface identifier, as specified in ERC-165\\n /// @dev Interface identification is specified in ERC-165. This function\\n /// uses less than 30,000 gas.\\n /// @return `true` if the contract implements `interfaceID` and\\n /// `interfaceID` is not 0xffffffff, `false` otherwise\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xbb7f07e170898793c5535cc4b7e8944c4b990a631ac806d0b788e794abc788a3\",\"license\":\"MIT\"},\"contracts/interfaces/ERC/IERC677Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC677Receiver {\\n function onTokenTransfer(\\n address sender,\\n uint value,\\n bytes calldata data\\n ) external pure returns (bool);\\n}\\n\",\"keccak256\":\"0x4c1631cf45ea6daac0ec158c3edb9453099130b6b64f697004b83f95aa1f7350\",\"license\":\"Apache-2.0\"},\"contracts/libraries/DefaultLibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary DefaultLibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (\\n uint256 facetIndex;\\n facetIndex < _diamondCut.length;\\n facetIndex++\\n ) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(\\n address _facetAddress,\\n bytes4[] memory _functionSelectors\\n ) internal {\\n uint256 funcSelectorsLength = _functionSelectors.length;\\n require(\\n funcSelectorsLength > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _facetAddress != address(0),\\n \\\"LibDiamondCut: Add facet can't be address(0)\\\"\\n );\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (\\n uint256 selectorIndex;\\n selectorIndex < funcSelectorsLength;\\n selectorIndex++\\n ) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds\\n .selectorToFacetAndPosition[selector]\\n .facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(\\n address _facetAddress,\\n bytes4[] memory _functionSelectors\\n ) internal {\\n uint256 funcSelectorsLength = _functionSelectors.length;\\n require(\\n funcSelectorsLength > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _facetAddress != address(0),\\n \\\"LibDiamondCut: Replace facet can't be address(0)\\\"\\n );\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (\\n uint256 selectorIndex;\\n selectorIndex < funcSelectorsLength;\\n selectorIndex++\\n ) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds\\n .selectorToFacetAndPosition[selector]\\n .facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same facet\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(\\n address _facetAddress,\\n bytes4[] memory _functionSelectors\\n ) internal {\\n uint256 funcSelectorsLength = _functionSelectors.length;\\n require(\\n funcSelectorsLength > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(\\n _facetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n for (\\n uint256 selectorIndex;\\n selectorIndex < funcSelectorsLength;\\n selectorIndex++\\n ) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds\\n .selectorToFacetAndPosition[selector]\\n .facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(\\n DiamondStorage storage ds,\\n address _facetAddress\\n ) internal {\\n enforceHasContractCode(\\n _facetAddress,\\n \\\"LibDiamondCut: New facet has no code\\\"\\n );\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds\\n .facetAddresses\\n .length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds\\n .selectorToFacetAndPosition[_selector]\\n .functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(\\n _selector\\n );\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(\\n _facetAddress != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // an immutable function is a function defined directly in a diamond\\n require(\\n _facetAddress != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds\\n .selectorToFacetAndPosition[_selector]\\n .functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors[lastSelectorPosition];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n selectorPosition\\n ] = lastSelector;\\n ds\\n .selectorToFacetAndPosition[lastSelector]\\n .functionSelectorPosition = uint96(selectorPosition);\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[\\n lastFacetAddressPosition\\n ];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds\\n .facetFunctionSelectors[lastFacetAddress]\\n .facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds\\n .facetFunctionSelectors[_facetAddress]\\n .facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x1b08f332d62919288bb1f0d154ca4b85f4e167d2a06e680f8ec93dba65be3be1\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x6080604052604051620020183803806200201883398101604081905262000026916200156b565b60408051600480825260a08201909252600091816020015b604080516060808201835260008083526020830152918101919091528152602001906001900390816200003e5750506040805160018082528183019092529192506000919060208083019080368337019050509050631f931c1c60e01b81600081518110620000b157620000b1620015c8565b6001600160e01b03199290921660209283029190910182015260408051600580825260c08201909252600092909190820160a08036833701905050905063b61d27f660e01b816000815181106200010c576200010c620015c8565b6001600160e01b03199092166020928302919091019091015280516323f0ed1560e11b9082906001908110620001465762000146620015c8565b6001600160e01b0319909216602092830291909101909101528051633a871cdd60e01b9082906002908110620001805762000180620015c8565b6001600160e01b0319909216602092830291909101909101528051631a10fa5160e31b9082906003908110620001ba57620001ba620015c8565b6001600160e01b031990921660209283029190910190910152805163586b48ff60e11b9082906004908110620001f457620001f4620015c8565b6001600160e01b03199290921660209283029190910182015260408051600580825260c08201909252600092909190820160a08036833701905050905063150b7a0260e01b816000815181106200024f576200024f620015c8565b6001600160e01b031990921660209283029190910190910152805163f23a6e6160e01b9082906001908110620002895762000289620015c8565b6001600160e01b031990921660209283029190910190910152805163bc197c8160e01b9082906002908110620002c357620002c3620015c8565b6001600160e01b03199092166020928302919091019091015280516223de2960e01b9082906003908110620002fc57620002fc620015c8565b6001600160e01b0319909216602092830291909101909101528051635260769b60e11b9082906004908110620003365762000336620015c8565b6001600160e01b0319929092166020928302919091018201526040805160098082526101408201909252600092909190820161012080368337019050509050637a0ed62760e01b81600081518110620003935762000393620015c8565b6001600160e01b03199092166020928302919091019091015280516356fe50af60e11b9082906001908110620003cd57620003cd620015c8565b6001600160e01b03199092166020928302919091019091015280516314bbdacb60e21b9082906002908110620004075762000407620015c8565b6001600160e01b03199092166020928302919091019091015280516366ffd66360e11b9082906003908110620004415762000441620015c8565b6001600160e01b03199092166020928302919091019091015280516301ffc9a760e01b90829060049081106200047b576200047b620015c8565b6001600160e01b031990921660209283029190910190910152805163f9796ccf60e01b9082906005908110620004b557620004b5620015c8565b6001600160e01b031990921660209283029190910190910152805162d2a81160e11b9082906006908110620004ee57620004ee620015c8565b6001600160e01b031990921660209283029190910190910152805163d42139a960e01b9082906007908110620005285762000528620015c8565b6001600160e01b03199092166020928302919091019091015280516371d17b7f60e11b9082906008908110620005625762000562620015c8565b6001600160e01b031990921660209283029190910182015260408051606081019091526001600160a01b038b168152908101600081526020018581525085600081518110620005b557620005b5620015c8565b60200260200101819052506040518060600160405280896001600160a01b0316815260200160006002811115620005f057620005f0620015de565b815260200184815250856001815181106200060f576200060f620015c8565b60200260200101819052506040518060600160405280886001600160a01b03168152602001600060028111156200064a576200064a620015de565b81526020018381525085600281518110620006695762000669620015c8565b60200260200101819052506040518060600160405280876001600160a01b0316815260200160006002811115620006a457620006a4620015de565b81526020018281525085600381518110620006c357620006c3620015c8565b6020026020010181905250620006f1856000604051806020016040528060008152506200070060201b60201c565b5050505050505050506200184c565b60005b83518110156200090c576000848281518110620007245762000724620015c8565b602002602001015160200151905060006002811115620007485762000748620015de565b8160028111156200075d576200075d620015de565b03620007bb57620007b58583815181106200077c576200077c620015c8565b6020026020010151600001518684815181106200079d576200079d620015c8565b6020026020010151604001516200095b60201b60201c565b620008f6565b6001816002811115620007d257620007d2620015de565b036200082a57620007b5858381518110620007f157620007f1620015c8565b602002602001015160000151868481518110620008125762000812620015c8565b60200260200101516040015162000bf760201b60201c565b6002816002811115620008415762000841620015de565b036200089957620007b5858381518110620008605762000860620015c8565b602002602001015160000151868481518110620008815762000881620015c8565b60200260200101516040015162000ea160201b60201c565b60405162461bcd60e51b815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f727265637420466163657443756044820152663a20b1ba34b7b760c91b60648201526084015b60405180910390fd5b508062000903816200160a565b91505062000703565b507f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb67383838360405162000942939291906200167a565b60405180910390a162000956828262001005565b505050565b805180620009af5760405162461bcd60e51b815260206004820152602b602482015260008051602062001ff883398151915260448201526a1858d95d081d1bc818dd5d60aa1b6064820152608401620008ed565b60008051602062001f8c8339815191526001600160a01b03841662000a2c5760405162461bcd60e51b815260206004820152602c60248201527f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260448201526b65206164647265737328302960a01b6064820152608401620008ed565b6001600160a01b0384166000908152600182016020526040812054906001600160601b038216900362000a655762000a658286620010dd565b60005b8381101562000bef57600085828151811062000a885762000a88620015c8565b6020908102919091018101516001600160e01b031981166000908152918690526040909120549091506001600160a01b0316801562000b305760405162461bcd60e51b815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c72656164792065786973747300000000000000000000006064820152608401620008ed565b6001600160e01b0319821660008181526020878152604080832080546001600160a01b03908116600160a01b6001600160601b038c16021782558d168085526001808c0185529285208054938401815585528385206008840401805463ffffffff60079095166004026101000a948502191660e08a901c94909402939093179092559390925287905281546001600160a01b0319161790558362000bd48162001781565b9450505050808062000be6906200160a565b91505062000a68565b505050505050565b80518062000c4b5760405162461bcd60e51b815260206004820152602b602482015260008051602062001ff883398151915260448201526a1858d95d081d1bc818dd5d60aa1b6064820152608401620008ed565b60008051602062001f8c8339815191526001600160a01b03841662000ccc5760405162461bcd60e51b815260206004820152603060248201527f4c69624469616d6f6e644375743a205265706c6163652066616365742063616e60448201526f2774206265206164647265737328302960801b6064820152608401620008ed565b6001600160a01b0384166000908152600182016020526040812054906001600160601b038216900362000d055762000d058286620010dd565b60005b8381101562000bef57600085828151811062000d285762000d28620015c8565b6020908102919091018101516001600160e01b031981166000908152918690526040909120549091506001600160a01b03908116908816810362000dd55760405162461bcd60e51b815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d6520666163657400000000000000000000006064820152608401620008ed565b62000de28582846200114a565b6001600160e01b0319821660008181526020878152604080832080546001600160a01b03908116600160a01b6001600160601b038c16021782558d168085526001808c0185529285208054938401815585528385206008840401805463ffffffff60079095166004026101000a948502191660e08a901c94909402939093179092559390925287905281546001600160a01b0319161790558362000e868162001781565b9450505050808062000e98906200160a565b91505062000d08565b80518062000ef55760405162461bcd60e51b815260206004820152602b602482015260008051602062001ff883398151915260448201526a1858d95d081d1bc818dd5d60aa1b6064820152608401620008ed565b60008051602062001f8c8339815191526001600160a01b0384161562000f845760405162461bcd60e51b815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d7573742062652061646472657373283029000000000000000000006064820152608401620008ed565b60005b8281101562000ffe57600084828151811062000fa75762000fa7620015c8565b6020908102919091018101516001600160e01b031981166000908152918590526040909120549091506001600160a01b031662000fe68482846200114a565b5050808062000ff5906200160a565b91505062000f87565b5050505050565b6001600160a01b03821662001018575050565b6200103d8260405180606001604052806028815260200162001fac602891396200152a565b600080836001600160a01b0316836040516200105a9190620017b2565b600060405180830381855af49150503d806000811462001097576040519150601f19603f3d011682016040523d82523d6000602084013e6200109c565b606091505b509150915081620010d757805115620010b85780518082602001fd5b838360405163192105d760e01b8152600401620008ed929190620017d0565b50505050565b620011028160405180606001604052806024815260200162001fd4602491396200152a565b6002820180546001600160a01b0390921660008181526001948501602090815260408220860185905594840183559182529290200180546001600160a01b0319169091179055565b6001600160a01b038216620011c85760405162461bcd60e51b815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608401620008ed565b306001600160a01b03831603620012395760405162461bcd60e51b815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201526d3a30b1363290333ab731ba34b7b760911b6064820152608401620008ed565b6001600160e01b03198116600090815260208481526040808320546001600160a01b0386168452600180880190935290832054600160a01b9091046001600160601b031692916200128a91620017fe565b905080821462001383576001600160a01b03841660009081526001860160205260408120805483908110620012c357620012c3620015c8565b600091825260208083206008830401546001600160a01b038916845260018a019091526040909220805460079092166004026101000a90920460e01b925082919085908110620013175762001317620015c8565b600091825260208083206008830401805463ffffffff60079094166004026101000a938402191660e09590951c929092029390931790556001600160e01b03199290921682528690526040902080546001600160a01b0316600160a01b6001600160601b038516021790555b6001600160a01b03841660009081526001860160205260409020805480620013af57620013af6200181a565b60008281526020808220600860001990940193840401805463ffffffff600460078716026101000a0219169055919092556001600160e01b0319851682528690526040812081905581900362000ffe5760028501546000906200141590600190620017fe565b6001600160a01b0386166000908152600180890160205260409091200154909150808214620014cb576000876002018381548110620014585762001458620015c8565b6000918252602090912001546002890180546001600160a01b0390921692508291849081106200148c576200148c620015c8565b600091825260208083209190910180546001600160a01b0319166001600160a01b03948516179055929091168152600189810190925260409020018190555b86600201805480620014e157620014e16200181a565b60008281526020808220830160001990810180546001600160a01b03191690559092019092556001600160a01b0388168252600189810190915260408220015550505050505050565b813b8181620010d75760405162461bcd60e51b8152600401620008ed919062001830565b80516001600160a01b03811681146200156657600080fd5b919050565b600080600080608085870312156200158257600080fd5b6200158d856200154e565b93506200159d602086016200154e565b9250620015ad604086016200154e565b9150620015bd606086016200154e565b905092959194509250565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016200161f576200161f620015f4565b5060010190565b60005b838110156200164357818101518382015260200162001629565b50506000910152565b600081518084526200166681602086016020860162001626565b601f01601f19169290920160200192915050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b848110156200174f57898403607f19018652815180516001600160a01b03168552838101518986019060038110620016eb57634e487b7160e01b600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b80831015620017395783516001600160e01b03191682529286019260019290920191908601906200170d565b50978501979550505090820190600101620016a3565b50506001600160a01b038a169088015286810360408801526200177381896200164c565b9a9950505050505050505050565b60006001600160601b038281166002600160601b03198101620017a857620017a8620015f4565b6001019392505050565b60008251620017c681846020870162001626565b9190910192915050565b6001600160a01b0383168152604060208201819052600090620017f6908301846200164c565b949350505050565b81810381811115620018145762001814620015f4565b92915050565b634e487b7160e01b600052603160045260246000fd5b6020815260006200184560208301846200164c565b9392505050565b610730806200185c6000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806352ef6b2c146100515780637a0ed6271461006f578063adfca15e14610084578063cdffacc6146100a4575b600080fd5b610059610140565b60405161006691906104ab565b60405180910390f35b6100776101d1565b6040516100669190610562565b61009761009236600461060a565b6103d1565b6040516100669190610647565b61011b6100b236600461065a565b7fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610066565b60607f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6002018054806020026020016040519081016040528092919081815260200182805480156101c757602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161019c575b5050505050905090565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f908067ffffffffffffffff8111156102315761023161069c565b60405190808252806020026020018201604052801561027757816020015b60408051808201909152600081526060602082015281526020019060019003908161024f5790505b50925060005b818110156103cb57600083600201828154811061029c5761029c6106cb565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050808583815181106102dc576102dc6106cb565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff928316905290821660009081526001860182526040908190208054825181850281018501909352808352919290919083018282801561039d57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161034a5790505b50505050508583815181106103b4576103b46106cb565b60209081029190910181015101525060010161027d565b50505090565b73ffffffffffffffffffffffffffffffffffffffff811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4920602090815260409182902080548351818402810184019094528084526060939283018282801561049f57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161044c5790505b50505050509050919050565b6020808252825182820181905260009190848201906040850190845b818110156104f957835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016104c7565b50909695505050505050565b600081518084526020808501945080840160005b838110156105575781517fffffffff000000000000000000000000000000000000000000000000000000001687529582019590820190600101610519565b509495945050505050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b838110156105fc578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00185528151805173ffffffffffffffffffffffffffffffffffffffff1684528701518784018790526105e987850182610505565b9588019593505090860190600101610589565b509098975050505050505050565b60006020828403121561061c57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461064057600080fd5b9392505050565b6020815260006106406020830184610505565b60006020828403121561066c57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461064057600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea264697066735822122024a872696a5ad50024326567061c50adea63ff0d49edf0ac60339459d33d571664736f6c63430008150033183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f4c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a204e657720666163657420686173206e6f20636f64654c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e2066", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806352ef6b2c146100515780637a0ed6271461006f578063adfca15e14610084578063cdffacc6146100a4575b600080fd5b610059610140565b60405161006691906104ab565b60405180910390f35b6100776101d1565b6040516100669190610562565b61009761009236600461060a565b6103d1565b6040516100669190610647565b61011b6100b236600461065a565b7fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610066565b60607f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6002018054806020026020016040519081016040528092919081815260200182805480156101c757602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161019c575b5050505050905090565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f908067ffffffffffffffff8111156102315761023161069c565b60405190808252806020026020018201604052801561027757816020015b60408051808201909152600081526060602082015281526020019060019003908161024f5790505b50925060005b818110156103cb57600083600201828154811061029c5761029c6106cb565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050808583815181106102dc576102dc6106cb565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff928316905290821660009081526001860182526040908190208054825181850281018501909352808352919290919083018282801561039d57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161034a5790505b50505050508583815181106103b4576103b46106cb565b60209081029190910181015101525060010161027d565b50505090565b73ffffffffffffffffffffffffffffffffffffffff811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4920602090815260409182902080548351818402810184019094528084526060939283018282801561049f57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161044c5790505b50505050509050919050565b6020808252825182820181905260009190848201906040850190845b818110156104f957835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016104c7565b50909695505050505050565b600081518084526020808501945080840160005b838110156105575781517fffffffff000000000000000000000000000000000000000000000000000000001687529582019590820190600101610519565b509495945050505050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b838110156105fc578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00185528151805173ffffffffffffffffffffffffffffffffffffffff1684528701518784018790526105e987850182610505565b9588019593505090860190600101610589565b509098975050505050505050565b60006020828403121561061c57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461064057600080fd5b9392505050565b6020815260006106406020830184610505565b60006020828403121561066c57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461064057600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea264697066735822122024a872696a5ad50024326567061c50adea63ff0d49edf0ac60339459d33d571664736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "A default fallback handler for Barz", + "kind": "dev", + "methods": { + "constructor": { + "details": "This contract is also a diamond that holds the default facets to reduce gas cost for wallet activation. Within the constructor this conducts diamond cut to initially setup the diamond. This is a non-upgradeable contract", + "params": { + "_accountFacet": "Address account facet", + "_diamondCutFacet": "Address if diamond cut facet", + "_diamondLoupeFacet": "Address of diamond loupe facet", + "_tokenReceiverFacet": "Address of token receiver facet" + } + }, + "facetAddress(bytes4)": { + "details": "If facet is not found return address(0).", + "params": { + "_functionSelector": "The function selector." + }, + "returns": { + "facetAddress_": "The facet address." + } + }, + "facetAddresses()": { + "returns": { + "facetAddresses_": "facetAddresses_" + } + }, + "facetFunctionSelectors(address)": { + "params": { + "_facet": "The facet address." + }, + "returns": { + "facetFunctionSelectors_": "facetFunctionSelectors_" + } + }, + "facets()": { + "returns": { + "facets_": "The facet struct array including all facet information" + } + } + }, + "title": "DefaultFallbackHandler", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "constructor": { + "notice": "Sets the middleware diamond for Barz wallet as a fallback handler" + }, + "facetAddress(bytes4)": { + "notice": "Gets the facet that supports the given selector." + }, + "facetAddresses()": { + "notice": "Get all the facet addresses used by a diamond." + }, + "facetFunctionSelectors(address)": { + "notice": "Gets all the function selectors provided by a facet." + }, + "facets()": { + "notice": "Returns the facet information of call facets registered to this diamond." + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/bsc/DiamondCutFacet.json b/deployments/bsc/DiamondCutFacet.json new file mode 100644 index 0000000..920febb --- /dev/null +++ b/deployments/bsc/DiamondCutFacet.json @@ -0,0 +1,856 @@ +{ + "address": "0x0B9504140771C3688Ff041917192277D2f52E1e0", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_securityManager", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "CallerNotGuardian", + "type": "error" + }, + { + "inputs": [], + "name": "CallerNotGuardianOrOwner", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__CannotRevokeUnapproved", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__DuplicateApproval", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InsufficientApprovers", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidApprovalValidationPeriod", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidApprover", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidApproverSignature", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidArrayLength", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidInitAddress", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidRouteWithGuardian", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidRouteWithoutGuardian", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__LackOfOwnerApproval", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__OwnerAlreadyApproved", + "type": "error" + }, + { + "inputs": [], + "name": "DuplicateApprover", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_initializationContractAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "InitializationFunctionReverted", + "type": "error" + }, + { + "inputs": [], + "name": "UnregisteredFacetAndSelectors", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroApproverLength", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "indexed": false, + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "DiamondCut", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "diamondCut", + "type": "tuple[]" + } + ], + "name": "DiamondCutApprovalRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "diamondCut", + "type": "tuple[]" + } + ], + "name": "DiamondCutApproved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + }, + { + "indexed": false, + "internalType": "bool", + "name": "_lag", + "type": "bool" + } + ], + "name": "SupportsInterfaceUpdated", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_diamondCutHash", + "type": "bytes32" + }, + { + "internalType": "address[]", + "name": "_approvers", + "type": "address[]" + } + ], + "name": "_checkDuplicateOnChainApprover", + "outputs": [], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + } + ], + "name": "approveDiamondCut", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "diamondCut", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "internalType": "address[]", + "name": "_approvers", + "type": "address[]" + }, + { + "internalType": "bytes[]", + "name": "_signatures", + "type": "bytes[]" + } + ], + "name": "diamondCutWithGuardian", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_diamondCutHash", + "type": "bytes32" + } + ], + "name": "getDiamondCutApprovalCountWithTimeValidity", + "outputs": [ + { + "internalType": "uint256", + "name": "approvalCount", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + } + ], + "name": "getDiamondCutHash", + "outputs": [ + { + "internalType": "bytes32", + "name": "cutHash", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getDiamondCutNonce", + "outputs": [ + { + "internalType": "uint128", + "name": "cutNonce", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_diamondCutHash", + "type": "bytes32" + } + ], + "name": "getOwnerCutApprovalWithTimeValidity", + "outputs": [ + { + "internalType": "bool", + "name": "isApprovedByOwner", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_diamondCutHash", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "_approver", + "type": "address" + } + ], + "name": "isCutApproved", + "outputs": [ + { + "internalType": "bool", + "name": "isApproved", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + } + ], + "name": "revokeDiamondCutApproval", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "securityManager", + "outputs": [ + { + "internalType": "contract ISecurityManager", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_interfaceId", + "type": "bytes4" + }, + { + "internalType": "bool", + "name": "_flag", + "type": "bool" + } + ], + "name": "updateSupportsInterface", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0x20489f2508cfbdbbc2c0e8c6f56a1eab23a38a799550bc1c9337b4af83263770", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 113, + "gasUsed": "3078987", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0xf5d28810199d50f91a75ad16e13b145d43ef8ad3a39da4d093913d5d15e1bb9a", + "transactionHash": "0x20489f2508cfbdbbc2c0e8c6f56a1eab23a38a799550bc1c9337b4af83263770", + "logs": [], + "blockNumber": 33657810, + "cumulativeGasUsed": "11225376", + "status": 1, + "byzantium": true + }, + "args": [ + "0xcBe266adbfd7CB32988128e7f37b7c8b3C5521A8" + ], + "numDeployments": 5, + "solcInputHash": "4356503edd8ae34e73cb6dd1c8e2fc8a", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_securityManager\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"CallerNotGuardian\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallerNotGuardianOrOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__CannotRevokeUnapproved\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__DuplicateApproval\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InsufficientApprovers\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidApprovalValidationPeriod\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidApprover\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidApproverSignature\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidArrayLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidInitAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidRouteWithGuardian\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidRouteWithoutGuardian\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__LackOfOwnerApproval\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__OwnerAlreadyApproved\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateApprover\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_initializationContractAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"InitializationFunctionReverted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnregisteredFacetAndSelectors\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroApproverLength\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"DiamondCut\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"diamondCut\",\"type\":\"tuple[]\"}],\"name\":\"DiamondCutApprovalRevoked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"diamondCut\",\"type\":\"tuple[]\"}],\"name\":\"DiamondCutApproved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"_lag\",\"type\":\"bool\"}],\"name\":\"SupportsInterfaceUpdated\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_diamondCutHash\",\"type\":\"bytes32\"},{\"internalType\":\"address[]\",\"name\":\"_approvers\",\"type\":\"address[]\"}],\"name\":\"_checkDuplicateOnChainApprover\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"}],\"name\":\"approveDiamondCut\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"diamondCut\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"internalType\":\"address[]\",\"name\":\"_approvers\",\"type\":\"address[]\"},{\"internalType\":\"bytes[]\",\"name\":\"_signatures\",\"type\":\"bytes[]\"}],\"name\":\"diamondCutWithGuardian\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_diamondCutHash\",\"type\":\"bytes32\"}],\"name\":\"getDiamondCutApprovalCountWithTimeValidity\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"approvalCount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"}],\"name\":\"getDiamondCutHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"cutHash\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDiamondCutNonce\",\"outputs\":[{\"internalType\":\"uint128\",\"name\":\"cutNonce\",\"type\":\"uint128\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_diamondCutHash\",\"type\":\"bytes32\"}],\"name\":\"getOwnerCutApprovalWithTimeValidity\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isApprovedByOwner\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_diamondCutHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"_approver\",\"type\":\"address\"}],\"name\":\"isCutApproved\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isApproved\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"}],\"name\":\"revokeDiamondCutApproval\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"securityManager\",\"outputs\":[{\"internalType\":\"contract ISecurityManager\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_interfaceId\",\"type\":\"bytes4\"},{\"internalType\":\"bool\",\"name\":\"_flag\",\"type\":\"bool\"}],\"name\":\"updateSupportsInterface\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"Responsible for adding/removing/replace facets in Barz\",\"kind\":\"dev\",\"methods\":{\"_checkDuplicateOnChainApprover(bytes32,address[])\":{\"params\":{\"_approvers\":\"List of approver addresses\",\"_diamondCutHash\":\"Hash of diamondCut information including the facet addresses and function selectors\"}},\"approveDiamondCut((address,uint8,bytes4[])[])\":{\"params\":{\"_diamondCut\":\"Contains the facet addresses and function selectors\"}},\"constructor\":{\"params\":{\"_securityManager\":\"Security Manager contract that holds the security related variables for all wallets\"}},\"diamondCut((address,uint8,bytes4[])[],address,bytes)\":{\"params\":{\"_diamondCut\":\"Contains the facet addresses and function selectors\",\"_init\":\"The address of the contract or facet to execute _calldata. It's prohibited in Barz\"}},\"diamondCutWithGuardian((address,uint8,bytes4[])[],address[],bytes[])\":{\"params\":{\"_approvers\":\"Guardian or owner address that approves the diamond cut\",\"_diamondCut\":\"Contains the facet addresses and function selectors\",\"_signatures\":\"Signature of Guardians or owner that approves the diamond cut\"}},\"getDiamondCutApprovalCountWithTimeValidity(bytes32)\":{\"params\":{\"_diamondCutHash\":\"Hash of diamondCut information including the facet addresses and function selectors\"}},\"getDiamondCutHash((address,uint8,bytes4[])[])\":{\"params\":{\"_diamondCut\":\"Contains the facet addresses and function selectors\"},\"returns\":{\"cutHash\":\"Diamond Cut Hash\"}},\"getDiamondCutNonce()\":{\"details\":\"This method fetches the nonce from diamond cut storage\",\"returns\":{\"cutNonce\":\"Nonce of diamond cut to protect from reply attacks\"}},\"getOwnerCutApprovalWithTimeValidity(bytes32)\":{\"params\":{\"_diamondCutHash\":\"Hash of diamondCut information including the facet addresses and function selectors\"},\"returns\":{\"isApprovedByOwner\":\"Bool value showing if the owner approved the cut\"}},\"isCutApproved(bytes32,address)\":{\"params\":{\"_approver\":\"Address of approver\",\"_diamondCutHash\":\"Hash of diamondCut information including the facet addresses and function selectors\"},\"returns\":{\"isApproved\":\"Bool value showing if the approver approved the cut\"}},\"revokeDiamondCutApproval((address,uint8,bytes4[])[])\":{\"params\":{\"_diamondCut\":\"Contains the facet addresses and function selectors\"}},\"updateSupportsInterface(bytes4,bool)\":{\"params\":{\"_flag\":\"Bool value to update the mapping of the given interface ID\",\"_interfaceId\":\"InterfaceID to update the mapping\"}}},\"title\":\"DiamondCut Facet\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"_checkDuplicateOnChainApprover(bytes32,address[])\":{\"notice\":\"Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval Approvers who approved on-chain should not be included in the off-chain approval\"},\"approveDiamondCut((address,uint8,bytes4[])[])\":{\"notice\":\"Approves diamond cut. This can only be called directly from guardian or owner\"},\"constructor\":{\"notice\":\"This constructor sets the Security Manager address which is an immutable variable. Immutable variables do not impact the storage of diamond\"},\"diamondCut((address,uint8,bytes4[])[],address,bytes)\":{\"notice\":\"Add/replace/remove any number of functions and optionally execute a function with delegatecall when guardians don't exist\"},\"diamondCutWithGuardian((address,uint8,bytes4[])[],address[],bytes[])\":{\"notice\":\"Add/replace/remove any number of functions and optionally execute a function with delegatecall when guardians exist\"},\"getDiamondCutApprovalCountWithTimeValidity(bytes32)\":{\"notice\":\"Gets the number of approvals of diamond cut from guardians\"},\"getDiamondCutHash((address,uint8,bytes4[])[])\":{\"notice\":\"Returns the diamond cut hash. This function ensures that this hash is safe from replay attack by including salt, address, chainId, and nonce, etc.\"},\"getDiamondCutNonce()\":{\"notice\":\"Returns the diamond cut nonce of this wallet\"},\"getOwnerCutApprovalWithTimeValidity(bytes32)\":{\"notice\":\"Returns if the owner has approved the diamond cut\"},\"isCutApproved(bytes32,address)\":{\"notice\":\"Returns if the given approver has approved the diamond cut\"},\"revokeDiamondCutApproval((address,uint8,bytes4[])[])\":{\"notice\":\"Revokes the approval of diamond cut. This can only be called directly from guardian or owner\"},\"updateSupportsInterface(bytes4,bool)\":{\"notice\":\"Updates the flag for the interfaceId\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/base/DiamondCutFacet.sol\":\"DiamondCutFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/interfaces/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC1271 standard signature validation method for\\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC1271 {\\n /**\\n * @dev Should return whether the signature provided is valid for the provided data\\n * @param hash Hash of the data to be signed\\n * @param signature Signature byte array associated with _data\\n */\\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\\n}\\n\",\"keccak256\":\"0x0705a4b1b86d7b0bd8432118f226ba139c44b9dcaba0a6eafba2dd7d0639c544\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./math/Math.sol\\\";\\nimport \\\"./math/SignedMath.sol\\\";\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n uint256 length = Math.log10(value) + 1;\\n string memory buffer = new string(length);\\n uint256 ptr;\\n /// @solidity memory-safe-assembly\\n assembly {\\n ptr := add(buffer, add(32, length))\\n }\\n while (true) {\\n ptr--;\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\\n }\\n value /= 10;\\n if (value == 0) break;\\n }\\n return buffer;\\n }\\n }\\n\\n /**\\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\\n */\\n function toString(int256 value) internal pure returns (string memory) {\\n return string(abi.encodePacked(value < 0 ? \\\"-\\\" : \\\"\\\", toString(SignedMath.abs(value))));\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n return toHexString(value, Math.log256(value) + 1);\\n }\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n\\n /**\\n * @dev Returns true if the two strings are equal.\\n */\\n function equal(string memory a, string memory b) internal pure returns (bool) {\\n return keccak256(bytes(a)) == keccak256(bytes(b));\\n }\\n}\\n\",\"keccak256\":\"0x3088eb2868e8d13d89d16670b5f8612c4ab9ff8956272837d8e90106c59c14a0\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Strings.sol\\\";\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSA {\\n enum RecoverError {\\n NoError,\\n InvalidSignature,\\n InvalidSignatureLength,\\n InvalidSignatureS,\\n InvalidSignatureV // Deprecated in v4.8\\n }\\n\\n function _throwError(RecoverError error) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert(\\\"ECDSA: invalid signature\\\");\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert(\\\"ECDSA: invalid signature length\\\");\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert(\\\"ECDSA: invalid signature 's' value\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature` or error string. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n *\\n * Documentation for signature generation:\\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n return tryRecover(hash, v, r, s);\\n } else {\\n return (address(0), RecoverError.InvalidSignatureLength);\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature`. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, signature);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\\n uint8 v = uint8((uint256(vs) >> 255) + 27);\\n return tryRecover(hash, v, r, s);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n *\\n * _Available since v4.2._\\n */\\n function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\\n // the valid range for s in (301): 0 < s < secp256k1n \\u00f7 2 + 1, and for v in (302): v \\u2208 {27, 28}. Most\\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\\n //\\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\\n // these malleable signatures as well.\\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n return (address(0), RecoverError.InvalidSignatureS);\\n }\\n\\n // If the signature is valid (and not malleable), return the signer address\\n address signer = ecrecover(hash, v, r, s);\\n if (signer == address(0)) {\\n return (address(0), RecoverError.InvalidSignature);\\n }\\n\\n return (signer, RecoverError.NoError);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore(0x00, \\\"\\\\x19Ethereum Signed Message:\\\\n32\\\")\\n mstore(0x1c, hash)\\n message := keccak256(0x00, 0x3c)\\n }\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from `s`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n\\\", Strings.toString(s.length), s));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Typed Data, created from a\\n * `domainSeparator` and a `structHash`. This produces hash corresponding\\n * to the one signed with the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n * JSON-RPC method as part of EIP-712.\\n *\\n * See {recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n let ptr := mload(0x40)\\n mstore(ptr, \\\"\\\\x19\\\\x01\\\")\\n mstore(add(ptr, 0x02), domainSeparator)\\n mstore(add(ptr, 0x22), structHash)\\n data := keccak256(ptr, 0x42)\\n }\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Data with intended validator, created from a\\n * `validator` and `data` according to the version 0 of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x00\\\", validator, data));\\n }\\n}\\n\",\"keccak256\":\"0x809bc3edb4bcbef8263fa616c1b60ee0004b50a8a1bfa164d8f57fd31f520c58\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/SignatureChecker.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./ECDSA.sol\\\";\\nimport \\\"../../interfaces/IERC1271.sol\\\";\\n\\n/**\\n * @dev Signature verification helper that can be used instead of `ECDSA.recover` to seamlessly support both ECDSA\\n * signatures from externally owned accounts (EOAs) as well as ERC1271 signatures from smart contract wallets like\\n * Argent and Gnosis Safe.\\n *\\n * _Available since v4.1._\\n */\\nlibrary SignatureChecker {\\n /**\\n * @dev Checks if a signature is valid for a given signer and data hash. If the signer is a smart contract, the\\n * signature is validated against that smart contract using ERC1271, otherwise it's validated using `ECDSA.recover`.\\n *\\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\\n */\\n function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature) internal view returns (bool) {\\n (address recovered, ECDSA.RecoverError error) = ECDSA.tryRecover(hash, signature);\\n return\\n (error == ECDSA.RecoverError.NoError && recovered == signer) ||\\n isValidERC1271SignatureNow(signer, hash, signature);\\n }\\n\\n /**\\n * @dev Checks if a signature is valid for a given signer and data hash. The signature is validated\\n * against the signer smart contract using ERC1271.\\n *\\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\\n */\\n function isValidERC1271SignatureNow(\\n address signer,\\n bytes32 hash,\\n bytes memory signature\\n ) internal view returns (bool) {\\n (bool success, bytes memory result) = signer.staticcall(\\n abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, signature)\\n );\\n return (success &&\\n result.length >= 32 &&\\n abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector));\\n }\\n}\\n\",\"keccak256\":\"0x3af3ca86df39aac39a0514c84459d691434a108d2151c8ce9d69f32e315cab80\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n enum Rounding {\\n Down, // Toward negative infinity\\n Up, // Toward infinity\\n Zero // Toward zero\\n }\\n\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow.\\n return (a & b) + (a ^ b) / 2;\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a == 0 ? 0 : (a - 1) / b + 1;\\n }\\n\\n /**\\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\\n * with further edits by Uniswap Labs also under MIT license.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\\n unchecked {\\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2^256 + prod0.\\n uint256 prod0; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division.\\n if (prod1 == 0) {\\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\\n // The surrounding unchecked block does not change this fact.\\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\\n return prod0 / denominator;\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n require(denominator > prod1, \\\"Math: mulDiv overflow\\\");\\n\\n ///////////////////////////////////////////////\\n // 512 by 256 division.\\n ///////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0].\\n uint256 remainder;\\n assembly {\\n // Compute remainder using mulmod.\\n remainder := mulmod(x, y, denominator)\\n\\n // Subtract 256 bit number from 512 bit number.\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\\n // See https://cs.stackexchange.com/q/138556/92363.\\n\\n // Does not overflow because the denominator cannot be zero at this stage in the function.\\n uint256 twos = denominator & (~denominator + 1);\\n assembly {\\n // Divide denominator by twos.\\n denominator := div(denominator, twos)\\n\\n // Divide [prod1 prod0] by twos.\\n prod0 := div(prod0, twos)\\n\\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\\n twos := add(div(sub(0, twos), twos), 1)\\n }\\n\\n // Shift in bits from prod1 into prod0.\\n prod0 |= prod1 * twos;\\n\\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\\n // four bits. That is, denominator * inv = 1 mod 2^4.\\n uint256 inverse = (3 * denominator) ^ 2;\\n\\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\\n // in modular arithmetic, doubling the correct bits in each step.\\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\\n\\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inverse;\\n return result;\\n }\\n }\\n\\n /**\\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\\n uint256 result = mulDiv(x, y, denominator);\\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\\n result += 1;\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\\n *\\n * Inspired by Henry S. Warren, Jr.'s \\\"Hacker's Delight\\\" (Chapter 11).\\n */\\n function sqrt(uint256 a) internal pure returns (uint256) {\\n if (a == 0) {\\n return 0;\\n }\\n\\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\\n //\\n // We know that the \\\"msb\\\" (most significant bit) of our target number `a` is a power of 2 such that we have\\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\\n //\\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\\n // \\u2192 `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\\n // \\u2192 `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\\n //\\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\\n uint256 result = 1 << (log2(a) >> 1);\\n\\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\\n // into the expected uint128 result.\\n unchecked {\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n return min(result, a / result);\\n }\\n }\\n\\n /**\\n * @notice Calculates sqrt(a), following the selected rounding direction.\\n */\\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = sqrt(a);\\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 2, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 128;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 64;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 32;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 16;\\n }\\n if (value >> 8 > 0) {\\n value >>= 8;\\n result += 8;\\n }\\n if (value >> 4 > 0) {\\n value >>= 4;\\n result += 4;\\n }\\n if (value >> 2 > 0) {\\n value >>= 2;\\n result += 2;\\n }\\n if (value >> 1 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log2(value);\\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 10, rounded down, of a positive value.\\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 + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 256, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n *\\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\\n */\\n function log256(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 16;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 8;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 4;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 2;\\n }\\n if (value >> 8 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log256(value);\\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe4455ac1eb7fc497bb7402579e7b4d64d928b846fce7d2b6fde06d366f21c2b3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\\n * checks.\\n *\\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\\n * easily result in undesired exploitation or bugs, since developers usually\\n * assume that overflows raise errors. `SafeCast` restores this intuition by\\n * reverting the transaction when such an operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n *\\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\\n * all math on `uint256` and `int256` and then downcasting.\\n */\\nlibrary SafeCast {\\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 * _Available since v4.7._\\n */\\n function toUint248(uint256 value) internal pure returns (uint248) {\\n require(value <= type(uint248).max, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint240(uint256 value) internal pure returns (uint240) {\\n require(value <= type(uint240).max, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint232(uint256 value) internal pure returns (uint232) {\\n require(value <= type(uint232).max, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint224(uint256 value) internal pure returns (uint224) {\\n require(value <= type(uint224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint216(uint256 value) internal pure returns (uint216) {\\n require(value <= type(uint216).max, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint208(uint256 value) internal pure returns (uint208) {\\n require(value <= type(uint208).max, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint200(uint256 value) internal pure returns (uint200) {\\n require(value <= type(uint200).max, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint192(uint256 value) internal pure returns (uint192) {\\n require(value <= type(uint192).max, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint184(uint256 value) internal pure returns (uint184) {\\n require(value <= type(uint184).max, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint176(uint256 value) internal pure returns (uint176) {\\n require(value <= type(uint176).max, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint168(uint256 value) internal pure returns (uint168) {\\n require(value <= type(uint168).max, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint160(uint256 value) internal pure returns (uint160) {\\n require(value <= type(uint160).max, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint152(uint256 value) internal pure returns (uint152) {\\n require(value <= type(uint152).max, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint144(uint256 value) internal pure returns (uint144) {\\n require(value <= type(uint144).max, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint136(uint256 value) internal pure returns (uint136) {\\n require(value <= type(uint136).max, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint128(uint256 value) internal pure returns (uint128) {\\n require(value <= type(uint128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint120(uint256 value) internal pure returns (uint120) {\\n require(value <= type(uint120).max, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint112(uint256 value) internal pure returns (uint112) {\\n require(value <= type(uint112).max, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint104(uint256 value) internal pure returns (uint104) {\\n require(value <= type(uint104).max, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint96(uint256 value) internal pure returns (uint96) {\\n require(value <= type(uint96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint88(uint256 value) internal pure returns (uint88) {\\n require(value <= type(uint88).max, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint80(uint256 value) internal pure returns (uint80) {\\n require(value <= type(uint80).max, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint72(uint256 value) internal pure returns (uint72) {\\n require(value <= type(uint72).max, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint64(uint256 value) internal pure returns (uint64) {\\n require(value <= type(uint64).max, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint56(uint256 value) internal pure returns (uint56) {\\n require(value <= type(uint56).max, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint48(uint256 value) internal pure returns (uint48) {\\n require(value <= type(uint48).max, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint40(uint256 value) internal pure returns (uint40) {\\n require(value <= type(uint40).max, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint32(uint256 value) internal pure returns (uint32) {\\n require(value <= type(uint32).max, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint24(uint256 value) internal pure returns (uint24) {\\n require(value <= type(uint24).max, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint16(uint256 value) internal pure returns (uint16) {\\n require(value <= type(uint16).max, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint8(uint256 value) internal pure returns (uint8) {\\n require(value <= type(uint8).max, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\n */\\n function toUint256(int256 value) internal pure returns (uint256) {\\n require(value >= 0, \\\"SafeCast: value must be positive\\\");\\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 * _Available since v4.7._\\n */\\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\\n downcasted = int248(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\\n downcasted = int240(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\\n downcasted = int232(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\\n downcasted = int224(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\\n downcasted = int216(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\\n downcasted = int208(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\\n downcasted = int200(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\\n downcasted = int192(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\\n downcasted = int184(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\\n downcasted = int176(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\\n downcasted = int168(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\\n downcasted = int160(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\\n downcasted = int152(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\\n downcasted = int144(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\\n downcasted = int136(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\\n downcasted = int128(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\\n downcasted = int120(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\\n downcasted = int112(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\\n downcasted = int104(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\\n downcasted = int96(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\\n downcasted = int88(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\\n downcasted = int80(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\\n downcasted = int72(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\\n downcasted = int64(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\\n downcasted = int56(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\\n downcasted = int48(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\\n downcasted = int40(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\\n downcasted = int32(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\\n downcasted = int24(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\\n downcasted = int16(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\\n downcasted = int8(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\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 require(value <= uint256(type(int256).max), \\\"SafeCast: value doesn't fit in an int256\\\");\\n return int256(value);\\n }\\n}\\n\",\"keccak256\":\"0x52a8cfb0f5239d11b457dcdd1b326992ef672714ca8da71a157255bddd13f3ad\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SignedMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard signed math utilities missing in the Solidity language.\\n */\\nlibrary SignedMath {\\n /**\\n * @dev Returns the largest of two signed numbers.\\n */\\n function max(int256 a, int256 b) internal pure returns (int256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two signed numbers.\\n */\\n function min(int256 a, int256 b) internal pure returns (int256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two signed numbers without overflow.\\n * The result is rounded towards zero.\\n */\\n function average(int256 a, int256 b) internal pure returns (int256) {\\n // Formula from the book \\\"Hacker's Delight\\\"\\n int256 x = (a & b) + ((a ^ b) >> 1);\\n return x + (int256(uint256(x) >> 255) & (a ^ b));\\n }\\n\\n /**\\n * @dev Returns the absolute unsigned value of a signed value.\\n */\\n function abs(int256 n) internal pure returns (uint256) {\\n unchecked {\\n // must be unchecked in order to support `n = type(int256).min`\\n return uint256(n >= 0 ? n : -n);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf92515413956f529d95977adc9b0567d583c6203fc31ab1c23824c35187e3ddc\",\"license\":\"MIT\"},\"contracts/aa-4337/core/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable no-inline-assembly */\\n\\n/**\\n * returned data from validateUserOp.\\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\\n * @param aggregator - address(0) - the account validated the signature by itself.\\n * address(1) - the account failed to validate the signature.\\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\\n * @param validAfter - this UserOp is valid only after this timestamp.\\n * @param validaUntil - this UserOp is valid only up to this timestamp.\\n */\\nstruct ValidationData {\\n address aggregator;\\n uint48 validAfter;\\n uint48 validUntil;\\n}\\n\\n//extract sigFailed, validAfter, validUntil.\\n// also convert zero validUntil to type(uint48).max\\nfunction _parseValidationData(\\n uint validationData\\n) pure returns (ValidationData memory data) {\\n address aggregator = address(uint160(validationData));\\n uint48 validUntil = uint48(validationData >> 160);\\n if (validUntil == 0) {\\n validUntil = type(uint48).max;\\n }\\n uint48 validAfter = uint48(validationData >> (48 + 160));\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n// intersect account and paymaster ranges.\\nfunction _intersectTimeRange(\\n uint256 validationData,\\n uint256 paymasterValidationData\\n) pure returns (ValidationData memory) {\\n ValidationData memory accountValidationData = _parseValidationData(\\n validationData\\n );\\n ValidationData memory pmValidationData = _parseValidationData(\\n paymasterValidationData\\n );\\n address aggregator = accountValidationData.aggregator;\\n if (aggregator == address(0)) {\\n aggregator = pmValidationData.aggregator;\\n }\\n uint48 validAfter = accountValidationData.validAfter;\\n uint48 validUntil = accountValidationData.validUntil;\\n uint48 pmValidAfter = pmValidationData.validAfter;\\n uint48 pmValidUntil = pmValidationData.validUntil;\\n\\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp\\n * @param data - the ValidationData to pack\\n */\\nfunction _packValidationData(\\n ValidationData memory data\\n) pure returns (uint256) {\\n return\\n uint160(data.aggregator) |\\n (uint256(data.validUntil) << 160) |\\n (uint256(data.validAfter) << (160 + 48));\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp, when not using an aggregator\\n * @param sigFailed - true for signature failure, false for success\\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\\n * @param validAfter first timestamp this UserOperation is valid\\n */\\nfunction _packValidationData(\\n bool sigFailed,\\n uint48 validUntil,\\n uint48 validAfter\\n) pure returns (uint256) {\\n return\\n (sigFailed ? 1 : 0) |\\n (uint256(validUntil) << 160) |\\n (uint256(validAfter) << (160 + 48));\\n}\\n\\n/**\\n * keccak function over calldata.\\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\\n */\\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\\n assembly {\\n let mem := mload(0x40)\\n let len := data.length\\n calldatacopy(mem, data.offset, len)\\n ret := keccak256(mem, len)\\n }\\n}\\n\",\"keccak256\":\"0xa79f06cd158ecb8c0da95493a2f348933b8627a63e228b99738bff3aa107942d\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAggregator.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\n/**\\n * Aggregated Signatures validator.\\n */\\ninterface IAggregator {\\n /**\\n * validate aggregated signature.\\n * revert if the aggregated signature does not match the given list of operations.\\n */\\n function validateSignatures(\\n UserOperation[] calldata userOps,\\n bytes calldata signature\\n ) external view;\\n\\n /**\\n * validate signature of a single userOp\\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\\n * @param userOp the userOperation received from the user.\\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\\n * (usually empty, unless account and aggregator support some kind of \\\"multisig\\\"\\n */\\n function validateUserOpSignature(\\n UserOperation calldata userOp\\n ) external view returns (bytes memory sigForUserOp);\\n\\n /**\\n * aggregate multiple signatures into a single value.\\n * This method is called off-chain to calculate the signature to pass with handleOps()\\n * bundler MAY use optimized custom code perform this aggregation\\n * @param userOps array of UserOperations to collect the signatures from.\\n * @return aggregatedSignature the aggregated signature\\n */\\n function aggregateSignatures(\\n UserOperation[] calldata userOps\\n ) external view returns (bytes memory aggregatedSignature);\\n}\\n\",\"keccak256\":\"0xdfdcd80568f037716674619b31be630fcd8316262f05a815b41d1e81782c966a\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IEntryPoint.sol\":{\"content\":\"/**\\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\\n ** Only one instance required on each chain.\\n **/\\n// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-inline-assembly */\\n/* solhint-disable reason-string */\\n\\nimport \\\"./UserOperation.sol\\\";\\nimport \\\"./IStakeManager.sol\\\";\\nimport \\\"./IAggregator.sol\\\";\\nimport \\\"./INonceManager.sol\\\";\\n\\ninterface IEntryPoint is IStakeManager, INonceManager {\\n /***\\n * An event emitted after each successful request\\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\\n * @param sender - the account that generates this request.\\n * @param paymaster - if non-null, the paymaster that pays for this request.\\n * @param nonce - the nonce value from the request.\\n * @param success - true if the sender transaction succeeded, false if reverted.\\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\\n */\\n event UserOperationEvent(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address indexed paymaster,\\n uint256 nonce,\\n bool success,\\n uint256 actualGasCost,\\n uint256 actualGasUsed\\n );\\n\\n /**\\n * account \\\"sender\\\" was deployed.\\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\\n * @param sender the account that is deployed\\n * @param factory the factory used to deploy this account (in the initCode)\\n * @param paymaster the paymaster used by this UserOp\\n */\\n event AccountDeployed(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address factory,\\n address paymaster\\n );\\n\\n /**\\n * An event emitted if the UserOperation \\\"callData\\\" reverted with non-zero length\\n * @param userOpHash the request unique identifier.\\n * @param sender the sender of this request\\n * @param nonce the nonce used in the request\\n * @param revertReason - the return bytes from the (reverted) call to \\\"callData\\\".\\n */\\n event UserOperationRevertReason(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n uint256 nonce,\\n bytes revertReason\\n );\\n\\n /**\\n * an event emitted by handleOps(), before starting the execution loop.\\n * any event emitted before this event, is part of the validation.\\n */\\n event BeforeExecution();\\n\\n /**\\n * signature aggregator used by the following UserOperationEvents within this bundle.\\n */\\n event SignatureAggregatorChanged(address indexed aggregator);\\n\\n /**\\n * a custom revert error of handleOps, to identify the offending op.\\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\\n * @param reason - revert reason\\n * The string starts with a unique code \\\"AAmn\\\", where \\\"m\\\" is \\\"1\\\" for factory, \\\"2\\\" for account and \\\"3\\\" for paymaster issues,\\n * so a failure can be attributed to the correct entity.\\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\\n */\\n error FailedOp(uint256 opIndex, string reason);\\n\\n /**\\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\\n */\\n error SignatureValidationFailed(address aggregator);\\n\\n /**\\n * Successful result from simulateValidation.\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n */\\n error ValidationResult(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo\\n );\\n\\n /**\\n * Successful result from simulateValidation, if the account returns a signature aggregator\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\\n * bundler MUST use it to verify the signature, or reject the UserOperation\\n */\\n error ValidationResultWithAggregation(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo,\\n AggregatorStakeInfo aggregatorInfo\\n );\\n\\n /**\\n * return value of getSenderAddress\\n */\\n error SenderAddressResult(address sender);\\n\\n /**\\n * return value of simulateHandleOp\\n */\\n error ExecutionResult(\\n uint256 preOpGas,\\n uint256 paid,\\n uint48 validAfter,\\n uint48 validUntil,\\n bool targetSuccess,\\n bytes targetResult\\n );\\n\\n //UserOps handled, per aggregator\\n struct UserOpsPerAggregator {\\n UserOperation[] userOps;\\n // aggregator address\\n IAggregator aggregator;\\n // aggregated signature\\n bytes signature;\\n }\\n\\n /**\\n * Execute a batch of UserOperation.\\n * no signature aggregator is used.\\n * if any account requires an aggregator (that is, it returned an aggregator when\\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\\n * @param ops the operations to execute\\n * @param beneficiary the address to receive the fees\\n */\\n function handleOps(\\n UserOperation[] calldata ops,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * Execute a batch of UserOperation with Aggregators\\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\\n * @param beneficiary the address to receive the fees\\n */\\n function handleAggregatedOps(\\n UserOpsPerAggregator[] calldata opsPerAggregator,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * generate a request Id - unique identifier for this request.\\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\\n */\\n function getUserOpHash(\\n UserOperation calldata userOp\\n ) external view returns (bytes32);\\n\\n /**\\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\\n * @param userOp the user operation to validate.\\n */\\n function simulateValidation(UserOperation calldata userOp) external;\\n\\n /**\\n * gas and return values during simulation\\n * @param preOpGas the gas used for validation (including preValidationGas)\\n * @param prefund the required prefund for this operation\\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\\n */\\n struct ReturnInfo {\\n uint256 preOpGas;\\n uint256 prefund;\\n bool sigFailed;\\n uint48 validAfter;\\n uint48 validUntil;\\n bytes paymasterContext;\\n }\\n\\n /**\\n * returned aggregated signature info.\\n * the aggregator returned by the account, and its current stake.\\n */\\n struct AggregatorStakeInfo {\\n address aggregator;\\n StakeInfo stakeInfo;\\n }\\n\\n /**\\n * Get counterfactual sender address.\\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\\n * this method always revert, and returns the address in SenderAddressResult error\\n * @param initCode the constructor code to be passed into the UserOperation.\\n */\\n function getSenderAddress(bytes memory initCode) external;\\n\\n /**\\n * simulate full execution of a UserOperation (including both validation and target execution)\\n * this method will always revert with \\\"ExecutionResult\\\".\\n * it performs full validation of the UserOperation, but ignores signature error.\\n * an optional target address is called after the userop succeeds, and its value is returned\\n * (before the entire call is reverted)\\n * Note that in order to collect the the success/failure of the target call, it must be executed\\n * with trace enabled to track the emitted events.\\n * @param op the UserOperation to simulate\\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\\n * are set to the return from that call.\\n * @param targetCallData callData to pass to target address\\n */\\n function simulateHandleOp(\\n UserOperation calldata op,\\n address target,\\n bytes calldata targetCallData\\n ) external;\\n}\\n\",\"keccak256\":\"0x9ccb1b188eda8bbf5f6c2d01bd83c3d8b2b04fcf745283051d31fe96d1d8e40f\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/INonceManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\ninterface INonceManager {\\n /**\\n * Return the next nonce for this sender.\\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\\n * But UserOp with different keys can come with arbitrary order.\\n *\\n * @param sender the account address\\n * @param key the high 192 bit of the nonce\\n * @return nonce a full nonce to pass for next UserOp with this sender.\\n */\\n function getNonce(\\n address sender,\\n uint192 key\\n ) external view returns (uint256 nonce);\\n\\n /**\\n * Manually increment the nonce of the sender.\\n * This method is exposed just for completeness..\\n * Account does NOT need to call it, neither during validation, nor elsewhere,\\n * as the EntryPoint will update the nonce regardless.\\n * Possible use-case is call it with various keys to \\\"initialize\\\" their nonces to one, so that future\\n * UserOperations will not pay extra for the first transaction with a given key.\\n */\\n function incrementNonce(uint192 key) external;\\n}\\n\",\"keccak256\":\"0xce478ad0fa0d18a3b785ac854623029e7ab463d05873dfaa365abfa1bf100912\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IStakeManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8.12;\\n\\n/**\\n * manage deposits and stakes.\\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\\n * stake is value locked for at least \\\"unstakeDelay\\\" by the staked entity.\\n */\\ninterface IStakeManager {\\n event Deposited(address indexed account, uint256 totalDeposit);\\n\\n event Withdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /// Emitted when stake or unstake delay are modified\\n event StakeLocked(\\n address indexed account,\\n uint256 totalStaked,\\n uint256 unstakeDelaySec\\n );\\n\\n /// Emitted once a stake is scheduled for withdrawal\\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\\n\\n event StakeWithdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /**\\n * @param deposit the entity's deposit\\n * @param staked true if this entity is staked.\\n * @param stake actual amount of ether staked for this entity.\\n * @param unstakeDelaySec minimum delay to withdraw the stake.\\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\\n * and the rest fit into a 2nd cell.\\n * 112 bit allows for 10^15 eth\\n * 48 bit for full timestamp\\n * 32 bit allows 150 years for unstake delay\\n */\\n struct DepositInfo {\\n uint112 deposit;\\n bool staked;\\n uint112 stake;\\n uint32 unstakeDelaySec;\\n uint48 withdrawTime;\\n }\\n\\n //API struct used by getStakeInfo and simulateValidation\\n struct StakeInfo {\\n uint256 stake;\\n uint256 unstakeDelaySec;\\n }\\n\\n /// @return info - full deposit information of given account\\n function getDepositInfo(\\n address account\\n ) external view returns (DepositInfo memory info);\\n\\n /// @return the deposit (for gas payment) of the account\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * add to the deposit of the given account\\n */\\n function depositTo(address account) external payable;\\n\\n /**\\n * add to the account's stake - amount and delay\\n * any pending unstake is first cancelled.\\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\\n */\\n function addStake(uint32 _unstakeDelaySec) external payable;\\n\\n /**\\n * attempt to unlock the stake.\\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\\n */\\n function unlockStake() external;\\n\\n /**\\n * withdraw from the (unlocked) stake.\\n * must first call unlockStake and wait for the unstakeDelay to pass\\n * @param withdrawAddress the address to send withdrawn value.\\n */\\n function withdrawStake(address payable withdrawAddress) external;\\n\\n /**\\n * withdraw from the deposit.\\n * @param withdrawAddress the address to send withdrawn value.\\n * @param withdrawAmount the amount to withdraw.\\n */\\n function withdrawTo(\\n address payable withdrawAddress,\\n uint256 withdrawAmount\\n ) external;\\n}\\n\",\"keccak256\":\"0xadcea606c9b7aafe6645441f2154a60f271330b0eee5292a632aa71c1672d546\",\"license\":\"GPL-3.0-only\"},\"contracts/aa-4337/interfaces/UserOperation.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable no-inline-assembly */\\n\\nimport {calldataKeccak} from \\\"../core/Helpers.sol\\\";\\n\\n/**\\n * User Operation struct\\n * @param sender the sender account of this request.\\n * @param nonce unique value the sender uses to verify it is not a replay.\\n * @param initCode if set, the account contract will be created by this constructor/\\n * @param callData the method call to execute on this account.\\n * @param callGasLimit the gas limit passed to the callData method call.\\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\\n * @param maxFeePerGas same as EIP-1559 gas parameter.\\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\\n */\\nstruct UserOperation {\\n address sender;\\n uint256 nonce;\\n bytes initCode;\\n bytes callData;\\n uint256 callGasLimit;\\n uint256 verificationGasLimit;\\n uint256 preVerificationGas;\\n uint256 maxFeePerGas;\\n uint256 maxPriorityFeePerGas;\\n bytes paymasterAndData;\\n bytes signature;\\n}\\n\\n/**\\n * Utility functions helpful when working with UserOperation structs.\\n */\\nlibrary UserOperationLib {\\n function getSender(\\n UserOperation calldata userOp\\n ) internal pure returns (address) {\\n address data;\\n //read sender from userOp, which is first userOp member (saves 800 gas...)\\n assembly {\\n data := calldataload(userOp)\\n }\\n return address(uint160(data));\\n }\\n\\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\\n // pay above what he signed for.\\n function gasPrice(\\n UserOperation calldata userOp\\n ) internal view returns (uint256) {\\n unchecked {\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n if (maxFeePerGas == maxPriorityFeePerGas) {\\n //legacy mode (for networks that don't support basefee opcode)\\n return maxFeePerGas;\\n }\\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\\n }\\n }\\n\\n function pack(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes memory ret) {\\n address sender = getSender(userOp);\\n uint256 nonce = userOp.nonce;\\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\\n bytes32 hashCallData = calldataKeccak(userOp.callData);\\n uint256 callGasLimit = userOp.callGasLimit;\\n uint256 verificationGasLimit = userOp.verificationGasLimit;\\n uint256 preVerificationGas = userOp.preVerificationGas;\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\\n\\n return\\n abi.encode(\\n sender,\\n nonce,\\n hashInitCode,\\n hashCallData,\\n callGasLimit,\\n verificationGasLimit,\\n preVerificationGas,\\n maxFeePerGas,\\n maxPriorityFeePerGas,\\n hashPaymasterAndData\\n );\\n }\\n\\n function hash(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes32) {\\n return keccak256(pack(userOp));\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n}\\n\",\"keccak256\":\"0x2429f5cc546bdee08c7e63858d0dda8491eaa3ab5194df884dc948c1154d2834\",\"license\":\"GPL-3.0\"},\"contracts/facets/Modifiers.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {LibGuardian} from \\\"../libraries/LibGuardian.sol\\\";\\nimport {BarzStorage} from \\\"../libraries/LibAppStorage.sol\\\";\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\n\\n/**\\n * @title Modifiers\\n * @dev Responsible for providing modifiers/util functions to Facet contracts\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\nabstract contract Modifiers is BarzStorage {\\n uint8 constant INNER_STRUCT = 0;\\n\\n error CallerNotGuardian();\\n error CallerNotGuardianOrOwner();\\n error DuplicateApprover();\\n error ZeroApproverLength();\\n error UnregisteredFacetAndSelectors();\\n\\n /**\\n * @notice Modifier to only allow guardian to make a call, reverts if any other entity is the caller\\n */\\n modifier onlyGuardian() {\\n if (!LibGuardian.isGuardian(msg.sender)) revert CallerNotGuardian();\\n _;\\n }\\n\\n /**\\n * @notice Modifier to only allow guardian or owner to make a call, reverts if any other entity is the caller\\n */\\n modifier onlyGuardianOrOwner() {\\n if (!LibGuardian.isGuardian(msg.sender) && address(this) != msg.sender)\\n revert CallerNotGuardianOrOwner();\\n _;\\n }\\n\\n /**\\n * @notice Checks if the approver address is the array is unique with no duplicate\\n * @dev This method loops through the array and checks if a duplicate address exists, it reverts if duplicate address exists\\n * @param approvers Array of address\\n */\\n function _checkApprover(\\n address[] memory approvers\\n ) internal pure returns (bool) {\\n uint256 approverLength = approvers.length;\\n if (0 == approverLength) revert ZeroApproverLength();\\n for (uint256 i; i < approverLength - 1; ) {\\n for (uint256 j = i + 1; j < approverLength; ) {\\n if (approvers[i] == approvers[j]) {\\n revert DuplicateApprover(); // Found a duplicate\\n }\\n unchecked {\\n ++j;\\n }\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n return false; // No duplicates found\\n }\\n\\n /**\\n * @notice Checks if the facet getting added or replaced is registered to facet registry\\n * @dev This method loops through the cut and checks if the facet getting added/replaced is registered to facet registry\\n * @param _diamondCut Array of FacetCut, data for diamondCut defined in EIP-2535\\n */\\n function _checkFacetCutValidity(\\n IDiamondCut.FacetCut[] memory _diamondCut\\n ) internal view {\\n uint256 diamondCutLength = _diamondCut.length;\\n for (uint256 i; i < diamondCutLength; ) {\\n if (\\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Add ||\\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Replace\\n ) {\\n if (\\n !s.facetRegistry.areFacetFunctionSelectorsRegistered(\\n _diamondCut[i].facetAddress,\\n _diamondCut[i].functionSelectors\\n )\\n ) revert UnregisteredFacetAndSelectors();\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb42956323d199bdec243a5f9859439aae057fbfdd1d79e3a96afc857ecb3115f\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/DiamondCutFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {LibDiamond} from \\\"../../libraries/LibDiamond.sol\\\";\\nimport {LibGuardian} from \\\"../../libraries/LibGuardian.sol\\\";\\nimport {ISecurityManager} from \\\"../../infrastructure/interfaces/ISecurityManager.sol\\\";\\nimport {SignatureChecker} from \\\"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\\\";\\nimport {LibFacetStorage, DiamondCutApprovalConfig, ApprovalConfig} from \\\"../../libraries/LibFacetStorage.sol\\\";\\nimport {Modifiers} from \\\"../Modifiers.sol\\\";\\nimport {IDiamondCut} from \\\"./interfaces/IDiamondCut.sol\\\";\\n\\n/**\\n * @title DiamondCut Facet\\n * @dev Responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract DiamondCutFacet is Modifiers, IDiamondCut {\\n ISecurityManager public immutable securityManager;\\n\\n /**\\n * @notice This constructor sets the Security Manager address which is an immutable variable.\\n * Immutable variables do not impact the storage of diamond\\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\\n */\\n constructor(address _securityManager) {\\n securityManager = ISecurityManager(_securityManager);\\n }\\n\\n /**\\n * @notice Updates the flag for the interfaceId\\n * @param _interfaceId InterfaceID to update the mapping\\n * @param _flag Bool value to update the mapping of the given interface ID\\n */\\n function updateSupportsInterface(\\n bytes4 _interfaceId,\\n bool _flag\\n ) external override onlyWhenUnlocked {\\n LibDiamond.enforceIsSelf();\\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId] = _flag;\\n emit SupportsInterfaceUpdated(_interfaceId, _flag);\\n }\\n\\n /**\\n * @notice Add/replace/remove any number of functions and optionally execute\\n * a function with delegatecall when guardians don't exist\\n * @param _diamondCut Contains the facet addresses and function selectors\\n * @param _init The address of the contract or facet to execute _calldata. It's prohibited in Barz\\n */\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata\\n ) external override onlyWhenUnlocked {\\n LibDiamond.enforceIsSelf();\\n\\n _checkFacetCutValidity(_diamondCut);\\n // require approval from guardian if guardian exists\\n if (0 != LibGuardian.guardianCount())\\n revert DiamondCutFacet__InvalidRouteWithGuardian();\\n if (address(0) != _init) revert DiamondCutFacet__InvalidInitAddress();\\n\\n unchecked {\\n ++LibFacetStorage.diamondCutStorage().nonce;\\n }\\n LibDiamond.diamondCut(_diamondCut, address(0), \\\"\\\");\\n }\\n\\n /**\\n * @notice Add/replace/remove any number of functions and optionally execute\\n * a function with delegatecall when guardians exist\\n * @param _diamondCut Contains the facet addresses and function selectors\\n * @param _approvers Guardian or owner address that approves the diamond cut\\n * @param _signatures Signature of Guardians or owner that approves the diamond cut\\n */\\n function diamondCutWithGuardian(\\n FacetCut[] calldata _diamondCut,\\n address[] calldata _approvers,\\n bytes[] calldata _signatures\\n ) external override onlyWhenUnlocked {\\n if (_approvers.length != _signatures.length)\\n revert DiamondCutFacet__InvalidArrayLength();\\n _checkFacetCutValidity(_diamondCut);\\n if (0 == LibGuardian.guardianCount())\\n revert DiamondCutFacet__InvalidRouteWithGuardian();\\n\\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\\n\\n _checkApprover(_approvers);\\n _checkDuplicateOnChainApprover(cutHash, _approvers);\\n\\n bool onChainOwnerApproval = getOwnerCutApprovalWithTimeValidity(\\n cutHash\\n );\\n\\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\\n if (\\n _approvers.length +\\n getDiamondCutApprovalCountWithTimeValidity(cutHash) <\\n LibGuardian.majorityOfGuardians() + threshold\\n ) revert DiamondCutFacet__InsufficientApprovers();\\n\\n bool ownerApproved;\\n for (uint256 i; i < _approvers.length; ) {\\n if (\\n !LibGuardian.isGuardian(_approvers[i]) &&\\n _approvers[i] != address(this)\\n ) revert DiamondCutFacet__InvalidApprover();\\n if (_approvers[i] == address(this)) {\\n if (onChainOwnerApproval)\\n revert DiamondCutFacet__OwnerAlreadyApproved();\\n ownerApproved = true;\\n }\\n if (\\n !SignatureChecker.isValidSignatureNow(\\n _approvers[i],\\n cutHash,\\n _signatures[i]\\n )\\n ) revert DiamondCutFacet__InvalidApproverSignature();\\n unchecked {\\n ++i;\\n }\\n }\\n if (!ownerApproved && !onChainOwnerApproval)\\n revert DiamondCutFacet__LackOfOwnerApproval();\\n\\n unchecked {\\n ++LibFacetStorage.diamondCutStorage().nonce;\\n }\\n LibDiamond.diamondCut(_diamondCut, address(0), \\\"\\\");\\n }\\n\\n /**\\n * @notice Approves diamond cut. This can only be called directly from guardian or owner\\n * @param _diamondCut Contains the facet addresses and function selectors\\n */\\n function approveDiamondCut(\\n FacetCut[] calldata _diamondCut\\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\\n if (LibGuardian.guardianCount() == 0)\\n revert DiamondCutFacet__InvalidRouteWithoutGuardian();\\n DiamondCutApprovalConfig storage ds = LibFacetStorage\\n .diamondCutStorage()\\n .diamondCutApprovalConfigs[INNER_STRUCT];\\n _checkFacetCutValidity(_diamondCut);\\n\\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\\n uint64 approvalValidUntil = uint64(\\n block.timestamp + getApprovalValidationPeriod()\\n );\\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(\\n true,\\n approvalValidUntil\\n );\\n emit DiamondCutApproved(_diamondCut);\\n if (\\n (getDiamondCutApprovalCountWithTimeValidity(cutHash) >=\\n LibGuardian.majorityOfGuardians()) &&\\n getOwnerCutApprovalWithTimeValidity(cutHash)\\n ) {\\n unchecked {\\n ++LibFacetStorage.diamondCutStorage().nonce;\\n }\\n LibDiamond.diamondCut(_diamondCut, address(0), \\\"\\\");\\n }\\n }\\n\\n /**\\n * @notice Revokes the approval of diamond cut. This can only be called directly from guardian or owner\\n * @param _diamondCut Contains the facet addresses and function selectors\\n */\\n function revokeDiamondCutApproval(\\n FacetCut[] calldata _diamondCut\\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\\n DiamondCutApprovalConfig storage ds = LibFacetStorage\\n .diamondCutStorage()\\n .diamondCutApprovalConfigs[INNER_STRUCT];\\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\\n if (!ds.isDiamondCutApproved[cutHash][msg.sender].isApproved)\\n revert DiamondCutFacet__CannotRevokeUnapproved();\\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(false, 0);\\n emit DiamondCutApprovalRevoked(_diamondCut);\\n }\\n\\n /**\\n * @notice Gets the number of approvals of diamond cut from guardians\\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\\n */\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 _diamondCutHash\\n ) public view override returns (uint256 approvalCount) {\\n address[] memory guardians = LibGuardian.getGuardians();\\n uint256 guardiansLength = guardians.length;\\n for (uint256 i; i < guardiansLength; ) {\\n if (isCutApproved(_diamondCutHash, guardians[i])) {\\n unchecked {\\n ++approvalCount;\\n }\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n return approvalCount;\\n }\\n\\n /**\\n * @notice Returns if the owner has approved the diamond cut\\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\\n * @return isApprovedByOwner Bool value showing if the owner approved the cut\\n */\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 _diamondCutHash\\n ) public view override returns (bool isApprovedByOwner) {\\n isApprovedByOwner = isCutApproved(_diamondCutHash, address(this));\\n }\\n\\n /**\\n * @notice Returns if the given approver has approved the diamond cut\\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\\n * @param _approver Address of approver\\n * @return isApproved Bool value showing if the approver approved the cut\\n */\\n function isCutApproved(\\n bytes32 _diamondCutHash,\\n address _approver\\n ) public view override returns (bool isApproved) {\\n DiamondCutApprovalConfig storage ds = LibFacetStorage\\n .diamondCutStorage()\\n .diamondCutApprovalConfigs[INNER_STRUCT];\\n isApproved = (ds\\n .isDiamondCutApproved[_diamondCutHash][_approver].isApproved &&\\n block.timestamp <\\n ds.isDiamondCutApproved[_diamondCutHash][_approver].validUntil);\\n }\\n\\n /**\\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\\n * Approvers who approved on-chain should not be included in the off-chain approval\\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\\n * @param _approvers List of approver addresses\\n */\\n function _checkDuplicateOnChainApprover(\\n bytes32 _diamondCutHash,\\n address[] memory _approvers\\n ) public view {\\n address[] memory guardians = LibGuardian.getGuardians();\\n uint256 guardianLength = guardians.length;\\n uint256 approversLength = _approvers.length;\\n for (uint256 i; i < guardianLength; ) {\\n if (isCutApproved(_diamondCutHash, guardians[i])) {\\n for (uint256 j; j < approversLength; ) {\\n if (_approvers[j] == guardians[i])\\n revert DiamondCutFacet__DuplicateApproval();\\n unchecked {\\n ++j;\\n }\\n }\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * @notice Returns the diamond cut hash. This function ensures that this hash is safe from replay attack by including\\n * salt, address, chainId, and nonce, etc.\\n * @param _diamondCut Contains the facet addresses and function selectors\\n * @return cutHash Diamond Cut Hash\\n */\\n function getDiamondCutHash(\\n FacetCut[] calldata _diamondCut\\n ) public view override returns (bytes32 cutHash) {\\n cutHash = keccak256(\\n abi.encodePacked(\\n \\\"\\\\x19Ethereum Signed Message:\\\\n32\\\",\\n keccak256(\\n abi.encode(\\n keccak256(abi.encode(_diamondCut)),\\n address(this),\\n block.chainid,\\n LibFacetStorage.diamondCutStorage().nonce\\n )\\n )\\n )\\n );\\n }\\n\\n /**\\n * @notice Returns the approval validation Period\\n * @dev This method fetches the validation period from the security manager\\n * @return approvalValidationPeriod Approval validation period of Barz contract fetched from security manager\\n */\\n function getApprovalValidationPeriod()\\n internal\\n view\\n returns (uint256 approvalValidationPeriod)\\n {\\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\\n address(this)\\n );\\n if (approvalValidationPeriod <= 0)\\n revert DiamondCutFacet__InvalidApprovalValidationPeriod();\\n }\\n\\n /**\\n * @notice Returns the diamond cut nonce of this wallet\\n * @dev This method fetches the nonce from diamond cut storage\\n * @return cutNonce Nonce of diamond cut to protect from reply attacks\\n */\\n function getDiamondCutNonce()\\n public\\n view\\n override\\n returns (uint128 cutNonce)\\n {\\n cutNonce = LibFacetStorage.diamondCutStorage().nonce;\\n }\\n}\\n\",\"keccak256\":\"0xe91a7dd2daabf2e989c94089f4f1eb0da94276c3070559ac8988838e10dd1f5d\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/infrastructure/interfaces/IFacetRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Registry Interface\\n * @dev Interface for Facet Registry contract to keep track of facets & function selectors addable to user wallets\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IFacetRegistry {\\n struct FacetRegistryConfig {\\n bytes4[] selectors;\\n mapping(bytes4 => FacetInfo) info;\\n }\\n struct FacetInfo {\\n bool exists;\\n uint128 index;\\n }\\n\\n event FacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] facetSelectors\\n );\\n event FacetFunctionSelectorsRemoved(address facet, bytes4[] facetSelectors);\\n\\n error FacetRegistry__FacetSelectorAlreadyRegistered();\\n error FacetRegistry__UnregisteredFacetSelector();\\n\\n function registerFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function removeFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function areFacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external view returns (bool);\\n\\n function isFacetFunctionSelectorRegistered(\\n address facet,\\n bytes4 facetSelector\\n ) external view returns (bool);\\n\\n function getFacetFunctionSelectors(\\n address facet\\n ) external view returns (bytes4[] memory);\\n}\\n\",\"keccak256\":\"0x6e6dd2cab346ef7c31230740ec48d2925e4a9ab24c2f2fb268baaf408dcf02ef\",\"license\":\"Apache-2.0\"},\"contracts/infrastructure/interfaces/ISecurityManager.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Registry Interface\\n * @dev Infrastructure contract to manage security parameters of users\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\ninterface ISecurityManager {\\n error SecurityManager__OutOfBoundary();\\n error SecurityManager__CallerNotWallet();\\n error SecurityManager__AlreadyIntialized();\\n\\n function initializeAdditionSecurityPeriod(\\n uint128 defaultAdditionSecurityPeriod,\\n uint128 minAdditionSecurityPeriod,\\n uint128 maxAdditionSecurityPeriod\\n ) external;\\n\\n function initializeRemovalSecurityPeriod(\\n uint128 defaultRemovalSecurityPeriod,\\n uint128 minRemovalSecurityPeriod,\\n uint128 maxRemovalSecurityPeriod\\n ) external;\\n\\n function initializeApprovalValidationPeriod(\\n uint128 defaultApprovalValidationPeriod,\\n uint128 minApprovalValidationPeriod,\\n uint128 maxApprovalValidationPeriod\\n ) external;\\n\\n function initializeMigrationPeriod(\\n uint128 defaultMigrationPeriod,\\n uint128 minMigrationPeriod,\\n uint128 maxMigrationPeriod\\n ) external;\\n\\n function initializeLockPeriod(\\n uint128 defaultLockPeriod,\\n uint128 minLockPeriod,\\n uint128 maxLockPeriod\\n ) external;\\n\\n function initializeRecoveryPeriod(\\n uint128 defaultRecoveryPeriod,\\n uint128 minRecoveryPeriod,\\n uint128 maxRecoveryPeriod\\n ) external;\\n\\n function initializeSecurityWindow(\\n uint128 defaultSecurityWindow,\\n uint128 minSecurityWindow,\\n uint128 maxSecurityWindow\\n ) external;\\n\\n function setAdditionSecurityPeriod(\\n address wallet,\\n uint128 additionSecurityPeriod\\n ) external;\\n\\n function setRemovalSecurityPeriod(\\n address wallet,\\n uint128 removalSecurityPeriod\\n ) external;\\n\\n function setSecurityWindow(address wallet, uint128 securityWindow) external;\\n\\n function setRecoveryPeriod(address wallet, uint128 recoveryPeriod) external;\\n\\n function setLockPeriod(address wallet, uint128 lockPeriod) external;\\n\\n function setApprovalValidationPeriod(\\n address wallet,\\n uint128 approvalValidationPeriod\\n ) external;\\n\\n function setMigrationPeriod(\\n address wallet,\\n uint128 migrationPeriod\\n ) external;\\n\\n function additionSecurityPeriodOf(\\n address wallet\\n ) external view returns (uint128);\\n\\n function removalSecurityPeriodOf(\\n address wallet\\n ) external view returns (uint128);\\n\\n function securityWindowOf(address wallet) external view returns (uint128);\\n\\n function recoveryPeriodOf(address wallet) external view returns (uint128);\\n\\n function lockPeriodOf(address wallet) external view returns (uint128);\\n\\n function migrationPeriodOf(address wallet) external view returns (uint128);\\n\\n function approvalValidationPeriodOf(\\n address wallet\\n ) external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x9ac6566033ef81ba5744c8ed2b08f130b781b498ab9245bcca87567669549552\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibAppStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {SafeCast} from \\\"@openzeppelin/contracts/utils/math/SafeCast.sol\\\";\\nimport {IEntryPoint} from \\\"../aa-4337/interfaces/IEntryPoint.sol\\\";\\nimport {IFacetRegistry} from \\\"../infrastructure/interfaces/IFacetRegistry.sol\\\";\\n\\n/*\\n * @title App Storage\\n * @dev App storage for Barz contract to prevent storage collision\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Lock {\\n uint64 release;\\n bytes4 locker;\\n}\\n\\nstruct InitializersStorage {\\n // NOTE: initialized is a variable to make sure the initialization is only done once.\\n uint8 signerInitialized;\\n uint8 accountInitialized;\\n uint8 restrictionsInitialized;\\n}\\n\\nstruct AppStorage {\\n mapping(uint256 => InitializersStorage) initStorage;\\n uint8 signerMigration;\\n bytes4 validateOwnerSignatureSelector;\\n IEntryPoint entryPoint;\\n IFacetRegistry facetRegistry;\\n mapping(uint256 => Lock) locks;\\n}\\n\\nlibrary LibAppStorage {\\n error LibAppStorage__AccountAlreadyUninitialized();\\n error LibAppStorage__AccountMustBeUninitialized();\\n error LibAppStorage__SignerAlreadyUninitialized();\\n error LibAppStorage__SignerMustBeUninitialized();\\n\\n function appStorage() internal pure returns (AppStorage storage ds) {\\n assembly {\\n ds.slot := 0\\n }\\n }\\n\\n function setSignerUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerAlreadyUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 0;\\n }\\n\\n function getValidateOwnerSignatureSelector()\\n internal\\n view\\n returns (bytes4 selector)\\n {\\n selector = appStorage().validateOwnerSignatureSelector;\\n }\\n\\n function setValidateOwnerSignatureSelector(\\n bytes4 _validateOwnerSignatureSelector\\n ) internal {\\n appStorage()\\n .validateOwnerSignatureSelector = _validateOwnerSignatureSelector;\\n }\\n\\n function enforceSignerInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerMustBeUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 1;\\n }\\n\\n function enforceAccountInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].accountInitialized) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n s.initStorage[0].accountInitialized = 1;\\n }\\n\\n function initiateSignerMigration() internal {\\n appStorage().signerMigration = 1;\\n }\\n\\n function enforceSignerMigration() internal view {\\n if (1 != appStorage().signerMigration) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n }\\n\\n function finalizeSignerMigration() internal {\\n appStorage().signerMigration = 0;\\n }\\n\\n function setLock(uint256 _releaseAfter, bytes4 _locker) internal {\\n appStorage().locks[0] = Lock(SafeCast.toUint64(_releaseAfter), _locker);\\n }\\n\\n function enforceRestrictionsInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__SignerMustBeUninitialized();\\n s.initStorage[0].restrictionsInitialized = 1;\\n }\\n\\n function setRestrictionsUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__AccountAlreadyUninitialized();\\n s.initStorage[0].restrictionsInitialized = 0;\\n }\\n}\\n\\ncontract BarzStorage {\\n AppStorage internal s;\\n modifier onlyWhenUnlocked() {\\n require(\\n uint64(block.timestamp) >= s.locks[0].release,\\n \\\"Account Locked\\\"\\n );\\n _;\\n }\\n modifier onlyWhenLocked() {\\n require(\\n uint64(block.timestamp) < s.locks[0].release,\\n \\\"Account Unlocked\\\"\\n );\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x48524007862a6ce0e07f645950613ce6513ce073c37a109c75019683d42bae27\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\\n bytes4(keccak256(\\\"verifyRestrictions(address,address,uint256,bytes)\\\"));\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // Default Fallback Handler of the barz.\\n IDiamondLoupe defaultFallbackHandler;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function enforceIsSelf() internal view {\\n require(msg.sender == address(this), \\\"LibDiamond: Caller not self\\\");\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n\\n unchecked {\\n facetIndex++;\\n }\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n\\n function restrictionsFacet() internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(\\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2cabdc00de859c3a3170ce3bda5d0e5fd3933d47ce904fd1585f9818b02572f8\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibFacetStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Storage\\n * @dev Storage contract to store each facets variables with diamond storage\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Secp256k1VerificationStorage {\\n address signer;\\n}\\n\\nstruct Secp256r1VerificationStorage {\\n uint256[2] q;\\n}\\n\\nstruct GuardianStorage {\\n mapping(bytes32 => uint256) pending;\\n mapping(uint8 => StorageConfig) configs;\\n}\\n\\nstruct Info {\\n bool exists;\\n uint128 index;\\n}\\n\\nstruct StorageConfig {\\n address[] addresses;\\n mapping(address => Info) info;\\n}\\n\\nstruct RecoveryConfig {\\n bytes recoveryPublicKey;\\n uint64 executeAfter;\\n}\\n\\nstruct ApprovalConfig {\\n bool isApproved;\\n uint64 validUntil;\\n}\\n\\nstruct RecoveryApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isNewOwnerApproved;\\n}\\n\\nstruct RecoveryStorage {\\n mapping(uint8 => RecoveryConfig) recoveryConfigs;\\n mapping(uint8 => RecoveryApprovalConfig) recoveryApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct RestrictionsStorage {\\n address[] restrictions;\\n mapping(address => bool) exists;\\n}\\n\\nstruct SignatureMigrationConfig {\\n bytes migrationPublicKey;\\n address migrationVerificationFacet;\\n bytes4[] migrationSelectors;\\n uint64 migrateAfter;\\n}\\n\\nstruct SignatureMigrationApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isMigrationApproved;\\n}\\n\\nstruct SignatureMigrationStorage {\\n mapping(uint8 => SignatureMigrationConfig) migrationConfigs;\\n mapping(uint8 => SignatureMigrationApprovalConfig) migrationApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct DiamondCutApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isDiamondCutApproved;\\n}\\n\\nstruct DiamondCutStorage {\\n mapping(uint8 => DiamondCutApprovalConfig) diamondCutApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct LockStorage {\\n uint128 nonce;\\n}\\n\\nlibrary LibFacetStorage {\\n bytes32 constant K1_STORAGE_POSITION =\\n keccak256(\\n \\\"v0.trustwallet.diamond.storage.Secp256k1VerificationStorage\\\"\\n );\\n bytes32 constant R1_STORAGE_POSITION =\\n keccak256(\\n \\\"v0.trustwallet.diamond.storage.Secp256r1VerificationStorage\\\"\\n );\\n bytes32 constant GUARDIAN_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.GuardianStorage\\\");\\n bytes32 constant RECOVERY_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.RecoveryStorage\\\");\\n bytes32 constant RESTRICTION_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.RestrictionsStorage\\\");\\n bytes32 constant MIGRATION_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.SignatureMigrationStorage\\\");\\n bytes32 constant DIAMONDCUT_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.DiamondCutStorage\\\");\\n bytes32 constant LOCK_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.LockStorage\\\");\\n\\n function k1Storage()\\n internal\\n pure\\n returns (Secp256k1VerificationStorage storage ds)\\n {\\n bytes32 storagePosition = K1_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function r1Storage()\\n internal\\n pure\\n returns (Secp256r1VerificationStorage storage ds)\\n {\\n bytes32 storagePosition = R1_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function guardianStorage()\\n internal\\n pure\\n returns (GuardianStorage storage ds)\\n {\\n bytes32 storagePosition = GUARDIAN_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function recoveryStorage()\\n internal\\n pure\\n returns (RecoveryStorage storage ds)\\n {\\n bytes32 storagePosition = RECOVERY_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function restrictionsStorage()\\n internal\\n pure\\n returns (RestrictionsStorage storage ds)\\n {\\n bytes32 storagePosition = RESTRICTION_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function migrationStorage()\\n internal\\n pure\\n returns (SignatureMigrationStorage storage ds)\\n {\\n bytes32 storagePosition = MIGRATION_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function diamondCutStorage()\\n internal\\n pure\\n returns (DiamondCutStorage storage ds)\\n {\\n bytes32 storagePosition = DIAMONDCUT_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function lockStorage() internal pure returns (LockStorage storage ds) {\\n bytes32 storagePosition = LOCK_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n}\\n\",\"keccak256\":\"0x87c85decfd943deda9540733e464cb1a92eba735a301e89ce6f798016e359761\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibGuardian.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {LibFacetStorage, StorageConfig} from \\\"./LibFacetStorage.sol\\\";\\n\\n/**\\n * @title LibGuardian\\n * @dev Internal Library to provide utility feature for Guardians stored in Guardian Facet Storage\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\nlibrary LibGuardian {\\n function majorityOfGuardians()\\n internal\\n view\\n returns (uint256 guardianNumber)\\n {\\n uint256 guardianLength = guardianCount();\\n guardianNumber = (guardianLength == 0) ? 0 : guardianLength / 2 + 1;\\n }\\n\\n function isGuardian(address _guardian) internal view returns (bool) {\\n StorageConfig storage config = LibFacetStorage\\n .guardianStorage()\\n .configs[0];\\n return config.info[_guardian].exists;\\n }\\n\\n function guardianCount() internal view returns (uint256) {\\n StorageConfig storage config = LibFacetStorage\\n .guardianStorage()\\n .configs[0];\\n return config.addresses.length;\\n }\\n\\n function getGuardians() internal view returns (address[] memory) {\\n StorageConfig storage config = LibFacetStorage\\n .guardianStorage()\\n .configs[0];\\n address[] memory addresses = new address[](config.addresses.length);\\n uint256 addressesLen = config.addresses.length;\\n for (uint256 i; i < addressesLen; ) {\\n addresses[i] = config.addresses[i];\\n unchecked {\\n ++i;\\n }\\n }\\n return addresses;\\n }\\n}\\n\",\"keccak256\":\"0x6a620992d5535878fc03d1a27a6675f4c1509adfb3ddbbca1c52b546c25392dc\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x60a06040523480156200001157600080fd5b506040516200379b3803806200379b833981016040819052620000349162000046565b6001600160a01b031660805262000078565b6000602082840312156200005957600080fd5b81516001600160a01b03811681146200007157600080fd5b9392505050565b6080516137006200009b600039600081816101f10152611b2501526137006000f3fe608060405234801561001057600080fd5b50600436106100d45760003560e01c806379c0d58d11610081578063afb877bb1161005b578063afb877bb146101d9578063de675a6d146101ec578063e33ecf0a1461023857600080fd5b806379c0d58d14610192578063836d6bfb146101b35780638824a0bb146101c657600080fd5b806326fc3ef4116100b257806326fc3ef4146101145780632f4d98ea1461015c5780633c0985681461017f57600080fd5b806313c34f4b146100d95780631c776dd5146100ee5780631f931c1c14610101575b600080fd5b6100ec6100e7366004612a97565b61024b565b005b6100ec6100fc366004612ad9565b6104df565b6100ec61010f366004612b9c565b610a76565b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9bf546040516fffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b61016f61016a366004612c4a565b610c7b565b6040519015158152602001610153565b6100ec61018d366004612ca4565b610c8d565b6101a56101a0366004612c4a565b610df2565b604051908152602001610153565b61016f6101c1366004612cdb565b610e4c565b6100ec6101d4366004612dd2565b610eed565b6100ec6101e7366004612a97565b610fe1565b6102137f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610153565b6101a5610246366004612a97565b61130e565b3360009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff1615801561028a5750303314155b156102c1576040517f6238ee3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610369576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064015b60405180910390fd5b60008080527f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be6020527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d3906103be848461130e565b60008181526020848152604080832033845290915290205490915060ff16610412576040517fedc5708300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051808201825260008082526020808301828152858352868252848320338452909152908390209151825491517fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000009092169015157fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff161761010067ffffffffffffffff90921691909102179055517f3c3d8c1f0b0faff6fe0ace6b485d0595a0106dce9e303f956fd941ebdbe9a98e906104d19086908690612f54565b60405180910390a150505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610582576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b8281146105bb576040517fe854148500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6105cd6105c886886130aa565b611435565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b754600003610650576040517fa788861700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061065c878761130e565b905061069a8585808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506115b392505050565b506106d881868680806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250610eed92505050565b60006106e382610c7b565b90506000816106f35760016106f6565b60005b60ff169050806107046116d0565b61070e9190613201565b61071784610df2565b6107219088613201565b1015610759576040517f709fb08000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805b878110156109a0576107d989898381811061077a5761077a613214565b905060200201602081019061078f9190613243565b73ffffffffffffffffffffffffffffffffffffffff1660009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff1690565b1580156108225750308989838181106107f4576107f4613214565b90506020020160208101906108099190613243565b73ffffffffffffffffffffffffffffffffffffffff1614155b15610859576040517f7b2cbbb400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3089898381811061086c5761086c613214565b90506020020160208101906108819190613243565b73ffffffffffffffffffffffffffffffffffffffff16036108d95783156108d4576040517fee21708000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600191505b6109628989838181106108ee576108ee613214565b90506020020160208101906109039190613243565b8689898581811061091657610916613214565b90506020028101906109289190613265565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061174f92505050565b610998576040517fac3d341600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60010161075d565b50801580156109ad575082155b156109e4576040517f6d21730400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9bf80546fffffffffffffffffffffffffffffffff808216600101167fffffffffffffffffffffffffffffffff00000000000000000000000000000000909116179055610a6a610a538a8c6130aa565b6000604051806020016040528060008152506117ca565b50505050505050505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610b19576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b610b2161195f565b610b2e6105c885876130aa565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75415610baf576040517fa788861700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff831615610bfd576040517f871cb76100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be5b600190810180547fffffffffffffffffffffffffffffffff0000000000000000000000000000000081166fffffffffffffffffffffffffffffffff91821690930116919091179055610c74610a5385876130aa565b5050505050565b6000610c878230610e4c565b92915050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610d30576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b610d3861195f565b7fffffffff00000000000000000000000000000000000000000000000000000000821660008181527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4922602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001685151590811790915582519384529083015280517f4e6bd17989efa6d6a9607ccaac1bba27b29f99622bc830d99a3a9883b21a19c79281900390910190a15050565b600080610dfd6119ca565b805190915060005b81811015610e4457610e3085848381518110610e2357610e23613214565b6020026020010151610e4c565b15610e3c578360010193505b600101610e05565b505050919050565b60008281527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d36020818152604080842073ffffffffffffffffffffffffffffffffffffffff8616855290915282205460ff168015610ee5575060008481526020828152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152902054610100900467ffffffffffffffff1642105b949350505050565b6000610ef76119ca565b805183519192509060005b82811015610fd957610f2086858381518110610e2357610e23613214565b15610fd15760005b82811015610fcf57848281518110610f4257610f42613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16868281518110610f7257610f72613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603610fc7576040517f50f5729f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600101610f28565b505b600101610f02565b505050505050565b3360009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff161580156110205750303314155b15611057576040517f6238ee3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff9081164290911610156110fa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75460000361117d576040517f3a76e1f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080527f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be6020527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d36111d36105c883856130aa565b60006111df848461130e565b905060006111eb611af4565b6111f59042613201565b6040805180820182526001815267ffffffffffffffff838116602080840191825260008881528982528581203382529091528490209251835491517fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000009092169015157fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff16176101009190921602179055519091507f6248ff757895beed7d43d135bccf59a26b7fbdf0fe8233487c44e82c0f266ba3906112b89087908790612f54565b60405180910390a16112c86116d0565b6112d183610df2565b101580156112e357506112e382610c7b565b15610c74577f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be610c1f565b60008282604051602001611323929190612f54565b6040516020818303038152906040528051906020012030466113627f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be90565b6001015460408051602081019590955273ffffffffffffffffffffffffffffffffffffffff9093169284019290925260608301526fffffffffffffffffffffffffffffffff16608082015260a001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905280516020918201207f19457468657265756d205369676e6564204d6573736167653a0a33320000000091830191909152603c820152605c0160405160208183030381529060405280519060200120905092915050565b805160005b818110156115ae57600083828151811061145657611456613214565b602002602001015160200151600281111561147357611473612e8a565b14806114ad5750600183828151811061148e5761148e613214565b60200260200101516020015160028111156114ab576114ab612e8a565b145b156115a657600254835173ffffffffffffffffffffffffffffffffffffffff9091169063df871f72908590849081106114e8576114e8613214565b60200260200101516000015185848151811061150657611506613214565b6020026020010151604001516040518363ffffffff1660e01b815260040161152f92919061331c565b602060405180830381865afa15801561154c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611570919061334b565b6115a6576040517ff41a931c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60010161143a565b505050565b80516000908082036115f1576040517f3aee2eec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b6115ff600183613368565b8110156116c6576000611613826001613201565b90505b828110156116bd5784818151811061163057611630613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1685838151811061166057611660613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16036116b5576040517f8dd19e7d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600101611616565b506001016115f4565b5060009392505050565b600080611723600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75490565b905080156117465761173660028261337b565b611741906001613201565b611749565b60005b91505090565b600080600061175e8585611bf6565b9092509050600081600481111561177757611777612e8a565b1480156117af57508573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b806117c057506117c0868686611c3b565b9695505050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921547f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff8116908190600090600716156118395750600381901c60009081526001840160205260409020545b60005b87518110156118b6576118a983838a848151811061185c5761185c613214565b6020026020010151600001518b858151811061187a5761187a613214565b6020026020010151602001518c868151811061189857611898613214565b602002602001015160400151611d98565b909350915060010161183c565b508282146118ef576002840180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff84161790555b600782161561191157600382901c600090815260018501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb67387878760405161194493929190613424565b60405180910390a16119568686612829565b50505050505050565b3330146119c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4c69624469616d6f6e643a2043616c6c6572206e6f742073656c6600000000006044820152606401610360565b565b60008080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b780546060929067ffffffffffffffff811115611a3257611a32612d07565b604051908082528060200260200182016040528015611a5b578160200160208202803683370190505b50825490915060005b81811015611aeb57836000018181548110611a8157611a81613214565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16838281518110611abe57611abe613214565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101611a64565b50909392505050565b6040517f52430c8d0000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906352430c8d90602401602060405180830381865afa158015611b81573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ba59190613510565b6fffffffffffffffffffffffffffffffff16905060008111611bf3576040517fdac5ec8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b90565b6000808251604103611c2c5760208301516040840151606085015160001a611c2087828585612928565b94509450505050611c34565b506000905060025b9250929050565b60008060008573ffffffffffffffffffffffffffffffffffffffff16631626ba7e60e01b8686604051602401611c72929190613542565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909416939093179092529051611cfb919061355b565b600060405180830381855afa9150503d8060008114611d36576040519150601f19603f3d011682016040523d82523d6000602084013e611d3b565b606091505b5091509150818015611d4f57506020815110155b80156117c0575080517f1626ba7e0000000000000000000000000000000000000000000000000000000090611d8d9083016020908101908401613577565b149695505050505050565b600080807f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f90506000845111611e50576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610360565b6000856002811115611e6457611e64612e8a565b0361203457611e8b8660405180606001604052806024815260200161365760249139612a17565b60005b845181101561202e576000858281518110611eab57611eab613214565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c15611f7e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c72656164792065786973747300000000000000000000006064820152608401610360565b7fffffffff0000000000000000000000000000000000000000000000000000000080831660008181526020879052604090207fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608d901b168e17905560e060058e901b811692831c199c909c1690821c179a8190036120125760038c901c600090815260018601602052604081209b909b555b8b61201c81613590565b9c505060019093019250611e8e915050565b5061281d565b600185600281111561204857612048612e8a565b036123385761206f866040518060600160405280602881526020016136a360289139612a17565b60005b845181101561202e57600085828151811061208f5761208f613214565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c308103612164576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4c69624469616d6f6e644375743a2043616e2774207265706c61636520696d6d60448201527f757461626c652066756e6374696f6e00000000000000000000000000000000006064820152608401610360565b8973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361221f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e00000000000000006064820152608401610360565b73ffffffffffffffffffffffffffffffffffffffff81166122c2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e207468617420646f65736e277420657869737400000000000000006064820152608401610360565b507fffffffff0000000000000000000000000000000000000000000000000000000090911660009081526020849052604090206bffffffffffffffffffffffff919091167fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608a901b16179055600101612072565b600285600281111561234c5761234c612e8a565b036127955773ffffffffffffffffffffffffffffffffffffffff8616156123f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d7573742062652061646472657373283029000000000000000000006064820152608401610360565b600388901c6007891660005b86518110156127755760008a900361243d578261241d816135c8565b60008181526001870160205260409020549b5093506007925061244b9050565b81612447816135c8565b9250505b6000806000808a858151811061246357612463613214565b6020908102919091018101517fffffffff0000000000000000000000000000000000000000000000000000000081166000908152918a9052604090912054909150606081901c612535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608401610360565b30606082901c036125c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e0000000000000000000000000000000000006064820152608401610360565b600587901b8f901b94507fffffffff0000000000000000000000000000000000000000000000000000000080861690831614612666577fffffffff000000000000000000000000000000000000000000000000000000008516600090815260208a90526040902080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff83161790555b7fffffffff0000000000000000000000000000000000000000000000000000000091909116600090815260208990526040812055600381901c611fff16925060051b60e01690508582146126fb576000828152600188016020526040902080547fffffffff0000000000000000000000000000000000000000000000000000000080841c19909116908516831c17905561274c565b80837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c817fffffffff0000000000000000000000000000000000000000000000000000000060001b901c198e16179c505b8460000361276a57600086815260018801602052604081208190559c505b505050600101612401565b50806127828360086135fd565b61278c9190613201565b9950505061281d565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560448201527f74416374696f6e000000000000000000000000000000000000000000000000006064820152608401610360565b50959694955050505050565b73ffffffffffffffffffffffffffffffffffffffff8216612848575050565b61286a8260405180606001604052806028815260200161367b60289139612a17565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051612892919061355b565b600060405180830381855af49150503d80600081146128cd576040519150601f19603f3d011682016040523d82523d6000602084013e6128d2565b606091505b509150915081612922578051156128ec5780518082602001fd5b83836040517f192105d7000000000000000000000000000000000000000000000000000000008152600401610360929190613614565b50505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561295f5750600090506003612a0e565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156129b3573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116612a0757600060019250925050612a0e565b9150600090505b94509492505050565b813b8181612922576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103609190613643565b60008083601f840112612a6457600080fd5b50813567ffffffffffffffff811115612a7c57600080fd5b6020830191508360208260051b8501011115611c3457600080fd5b60008060208385031215612aaa57600080fd5b823567ffffffffffffffff811115612ac157600080fd5b612acd85828601612a52565b90969095509350505050565b60008060008060008060608789031215612af257600080fd5b863567ffffffffffffffff80821115612b0a57600080fd5b612b168a838b01612a52565b90985096506020890135915080821115612b2f57600080fd5b612b3b8a838b01612a52565b90965094506040890135915080821115612b5457600080fd5b50612b6189828a01612a52565b979a9699509497509295939492505050565b803573ffffffffffffffffffffffffffffffffffffffff81168114612b9757600080fd5b919050565b600080600080600060608688031215612bb457600080fd5b853567ffffffffffffffff80821115612bcc57600080fd5b612bd889838a01612a52565b9097509550859150612bec60208901612b73565b94506040880135915080821115612c0257600080fd5b818801915088601f830112612c1657600080fd5b813581811115612c2557600080fd5b896020828501011115612c3757600080fd5b9699959850939650602001949392505050565b600060208284031215612c5c57600080fd5b5035919050565b80357fffffffff0000000000000000000000000000000000000000000000000000000081168114612b9757600080fd5b8015158114612ca157600080fd5b50565b60008060408385031215612cb757600080fd5b612cc083612c63565b91506020830135612cd081612c93565b809150509250929050565b60008060408385031215612cee57600080fd5b82359150612cfe60208401612b73565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff81118282101715612d5957612d59612d07565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715612da657612da6612d07565b604052919050565b600067ffffffffffffffff821115612dc857612dc8612d07565b5060051b60200190565b60008060408385031215612de557600080fd5b8235915060208084013567ffffffffffffffff811115612e0457600080fd5b8401601f81018613612e1557600080fd5b8035612e28612e2382612dae565b612d5f565b81815260059190911b82018301908381019088831115612e4757600080fd5b928401925b82841015612e6c57612e5d84612b73565b82529284019290840190612e4c565b80955050505050509250929050565b803560038110612b9757600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60038110612ef0577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b8183526000602080850194508260005b85811015612f49577fffffffff00000000000000000000000000000000000000000000000000000000612f3683612c63565b1687529582019590820190600101612f04565b509495945050505050565b60208082528181018390526000906040808401600586811b8601830188865b8981101561309b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc089840301855281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa18c3603018112612fd457600080fd5b8b01606073ffffffffffffffffffffffffffffffffffffffff612ff683612b73565b168552613004898301612e7b565b6130108a870182612eb9565b50878201357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe183360301811261304557600080fd5b90910188810191903567ffffffffffffffff81111561306357600080fd5b80871b360383131561307457600080fd5b81898701526130868287018285612ef4565b978a0197955050509187019150600101612f73565b50909998505050505050505050565b60006130b8612e2384612dae565b83815260208082019190600586811b8601368111156130d657600080fd5b865b818110156131c557803567ffffffffffffffff808211156130f95760008081fd5b818a0191506060823603121561310f5760008081fd5b613117612d36565b61312083612b73565b815261312d878401612e7b565b87820152604080840135838111156131455760008081fd5b939093019236601f85011261315c57600092508283fd5b8335925061316c612e2384612dae565b83815292871b840188019288810190368511156131895760008081fd5b948901945b848610156131ae5761319f86612c63565b8252948901949089019061318e565b9183019190915250885250509483019483016130d8565b5092979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610c8757610c876131d2565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561325557600080fd5b61325e82612b73565b9392505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261329a57600080fd5b83018035915067ffffffffffffffff8211156132b557600080fd5b602001915036819003821315611c3457600080fd5b600081518084526020808501945080840160005b83811015612f495781517fffffffff0000000000000000000000000000000000000000000000000000000016875295820195908201906001016132de565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000610ee560408301846132ca565b60006020828403121561335d57600080fd5b815161325e81612c93565b81810381811115610c8757610c876131d2565b6000826133b1577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60005b838110156133d15781810151838201526020016133b9565b50506000910152565b600081518084526133f28160208601602086016133b6565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6000606080830181845280875180835260808601915060808160051b87010192506020808a0160005b838110156134d4577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80898703018552815173ffffffffffffffffffffffffffffffffffffffff8151168752838101516134a885890182612eb9565b506040908101519087018890526134c1878901826132ca565b965050938201939082019060010161344d565b505073ffffffffffffffffffffffffffffffffffffffff8916908701525050838103604085015261350581866133da565b979650505050505050565b60006020828403121561352257600080fd5b81516fffffffffffffffffffffffffffffffff8116811461325e57600080fd5b828152604060208201526000610ee560408301846133da565b6000825161356d8184602087016133b6565b9190910192915050565b60006020828403121561358957600080fd5b5051919050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036135c1576135c16131d2565b5060010190565b6000816135d7576135d76131d2565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b8082028115828204841417610c8757610c876131d2565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000610ee560408301846133da565b60208152600061325e60208301846133da56fe4c69624469616d6f6e644375743a2041646420666163657420686173206e6f20636f64654c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a205265706c61636520666163657420686173206e6f20636f6465a2646970667358221220c5a8c10b22f20cde3fe0431ff57305237423677a60888f5b349fc6751336ae1464736f6c63430008150033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100d45760003560e01c806379c0d58d11610081578063afb877bb1161005b578063afb877bb146101d9578063de675a6d146101ec578063e33ecf0a1461023857600080fd5b806379c0d58d14610192578063836d6bfb146101b35780638824a0bb146101c657600080fd5b806326fc3ef4116100b257806326fc3ef4146101145780632f4d98ea1461015c5780633c0985681461017f57600080fd5b806313c34f4b146100d95780631c776dd5146100ee5780631f931c1c14610101575b600080fd5b6100ec6100e7366004612a97565b61024b565b005b6100ec6100fc366004612ad9565b6104df565b6100ec61010f366004612b9c565b610a76565b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9bf546040516fffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b61016f61016a366004612c4a565b610c7b565b6040519015158152602001610153565b6100ec61018d366004612ca4565b610c8d565b6101a56101a0366004612c4a565b610df2565b604051908152602001610153565b61016f6101c1366004612cdb565b610e4c565b6100ec6101d4366004612dd2565b610eed565b6100ec6101e7366004612a97565b610fe1565b6102137f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610153565b6101a5610246366004612a97565b61130e565b3360009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff1615801561028a5750303314155b156102c1576040517f6238ee3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610369576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064015b60405180910390fd5b60008080527f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be6020527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d3906103be848461130e565b60008181526020848152604080832033845290915290205490915060ff16610412576040517fedc5708300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051808201825260008082526020808301828152858352868252848320338452909152908390209151825491517fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000009092169015157fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff161761010067ffffffffffffffff90921691909102179055517f3c3d8c1f0b0faff6fe0ace6b485d0595a0106dce9e303f956fd941ebdbe9a98e906104d19086908690612f54565b60405180910390a150505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610582576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b8281146105bb576040517fe854148500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6105cd6105c886886130aa565b611435565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b754600003610650576040517fa788861700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061065c878761130e565b905061069a8585808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506115b392505050565b506106d881868680806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250610eed92505050565b60006106e382610c7b565b90506000816106f35760016106f6565b60005b60ff169050806107046116d0565b61070e9190613201565b61071784610df2565b6107219088613201565b1015610759576040517f709fb08000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805b878110156109a0576107d989898381811061077a5761077a613214565b905060200201602081019061078f9190613243565b73ffffffffffffffffffffffffffffffffffffffff1660009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff1690565b1580156108225750308989838181106107f4576107f4613214565b90506020020160208101906108099190613243565b73ffffffffffffffffffffffffffffffffffffffff1614155b15610859576040517f7b2cbbb400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3089898381811061086c5761086c613214565b90506020020160208101906108819190613243565b73ffffffffffffffffffffffffffffffffffffffff16036108d95783156108d4576040517fee21708000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600191505b6109628989838181106108ee576108ee613214565b90506020020160208101906109039190613243565b8689898581811061091657610916613214565b90506020028101906109289190613265565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061174f92505050565b610998576040517fac3d341600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60010161075d565b50801580156109ad575082155b156109e4576040517f6d21730400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9bf80546fffffffffffffffffffffffffffffffff808216600101167fffffffffffffffffffffffffffffffff00000000000000000000000000000000909116179055610a6a610a538a8c6130aa565b6000604051806020016040528060008152506117ca565b50505050505050505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610b19576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b610b2161195f565b610b2e6105c885876130aa565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75415610baf576040517fa788861700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff831615610bfd576040517f871cb76100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be5b600190810180547fffffffffffffffffffffffffffffffff0000000000000000000000000000000081166fffffffffffffffffffffffffffffffff91821690930116919091179055610c74610a5385876130aa565b5050505050565b6000610c878230610e4c565b92915050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610d30576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b610d3861195f565b7fffffffff00000000000000000000000000000000000000000000000000000000821660008181527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4922602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001685151590811790915582519384529083015280517f4e6bd17989efa6d6a9607ccaac1bba27b29f99622bc830d99a3a9883b21a19c79281900390910190a15050565b600080610dfd6119ca565b805190915060005b81811015610e4457610e3085848381518110610e2357610e23613214565b6020026020010151610e4c565b15610e3c578360010193505b600101610e05565b505050919050565b60008281527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d36020818152604080842073ffffffffffffffffffffffffffffffffffffffff8616855290915282205460ff168015610ee5575060008481526020828152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152902054610100900467ffffffffffffffff1642105b949350505050565b6000610ef76119ca565b805183519192509060005b82811015610fd957610f2086858381518110610e2357610e23613214565b15610fd15760005b82811015610fcf57848281518110610f4257610f42613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16868281518110610f7257610f72613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603610fc7576040517f50f5729f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600101610f28565b505b600101610f02565b505050505050565b3360009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff161580156110205750303314155b15611057576040517f6238ee3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff9081164290911610156110fa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75460000361117d576040517f3a76e1f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080527f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be6020527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d36111d36105c883856130aa565b60006111df848461130e565b905060006111eb611af4565b6111f59042613201565b6040805180820182526001815267ffffffffffffffff838116602080840191825260008881528982528581203382529091528490209251835491517fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000009092169015157fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff16176101009190921602179055519091507f6248ff757895beed7d43d135bccf59a26b7fbdf0fe8233487c44e82c0f266ba3906112b89087908790612f54565b60405180910390a16112c86116d0565b6112d183610df2565b101580156112e357506112e382610c7b565b15610c74577f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be610c1f565b60008282604051602001611323929190612f54565b6040516020818303038152906040528051906020012030466113627f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be90565b6001015460408051602081019590955273ffffffffffffffffffffffffffffffffffffffff9093169284019290925260608301526fffffffffffffffffffffffffffffffff16608082015260a001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905280516020918201207f19457468657265756d205369676e6564204d6573736167653a0a33320000000091830191909152603c820152605c0160405160208183030381529060405280519060200120905092915050565b805160005b818110156115ae57600083828151811061145657611456613214565b602002602001015160200151600281111561147357611473612e8a565b14806114ad5750600183828151811061148e5761148e613214565b60200260200101516020015160028111156114ab576114ab612e8a565b145b156115a657600254835173ffffffffffffffffffffffffffffffffffffffff9091169063df871f72908590849081106114e8576114e8613214565b60200260200101516000015185848151811061150657611506613214565b6020026020010151604001516040518363ffffffff1660e01b815260040161152f92919061331c565b602060405180830381865afa15801561154c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611570919061334b565b6115a6576040517ff41a931c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60010161143a565b505050565b80516000908082036115f1576040517f3aee2eec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b6115ff600183613368565b8110156116c6576000611613826001613201565b90505b828110156116bd5784818151811061163057611630613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1685838151811061166057611660613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16036116b5576040517f8dd19e7d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600101611616565b506001016115f4565b5060009392505050565b600080611723600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75490565b905080156117465761173660028261337b565b611741906001613201565b611749565b60005b91505090565b600080600061175e8585611bf6565b9092509050600081600481111561177757611777612e8a565b1480156117af57508573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b806117c057506117c0868686611c3b565b9695505050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921547f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff8116908190600090600716156118395750600381901c60009081526001840160205260409020545b60005b87518110156118b6576118a983838a848151811061185c5761185c613214565b6020026020010151600001518b858151811061187a5761187a613214565b6020026020010151602001518c868151811061189857611898613214565b602002602001015160400151611d98565b909350915060010161183c565b508282146118ef576002840180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff84161790555b600782161561191157600382901c600090815260018501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb67387878760405161194493929190613424565b60405180910390a16119568686612829565b50505050505050565b3330146119c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4c69624469616d6f6e643a2043616c6c6572206e6f742073656c6600000000006044820152606401610360565b565b60008080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b780546060929067ffffffffffffffff811115611a3257611a32612d07565b604051908082528060200260200182016040528015611a5b578160200160208202803683370190505b50825490915060005b81811015611aeb57836000018181548110611a8157611a81613214565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16838281518110611abe57611abe613214565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101611a64565b50909392505050565b6040517f52430c8d0000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906352430c8d90602401602060405180830381865afa158015611b81573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ba59190613510565b6fffffffffffffffffffffffffffffffff16905060008111611bf3576040517fdac5ec8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b90565b6000808251604103611c2c5760208301516040840151606085015160001a611c2087828585612928565b94509450505050611c34565b506000905060025b9250929050565b60008060008573ffffffffffffffffffffffffffffffffffffffff16631626ba7e60e01b8686604051602401611c72929190613542565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909416939093179092529051611cfb919061355b565b600060405180830381855afa9150503d8060008114611d36576040519150601f19603f3d011682016040523d82523d6000602084013e611d3b565b606091505b5091509150818015611d4f57506020815110155b80156117c0575080517f1626ba7e0000000000000000000000000000000000000000000000000000000090611d8d9083016020908101908401613577565b149695505050505050565b600080807f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f90506000845111611e50576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610360565b6000856002811115611e6457611e64612e8a565b0361203457611e8b8660405180606001604052806024815260200161365760249139612a17565b60005b845181101561202e576000858281518110611eab57611eab613214565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c15611f7e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c72656164792065786973747300000000000000000000006064820152608401610360565b7fffffffff0000000000000000000000000000000000000000000000000000000080831660008181526020879052604090207fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608d901b168e17905560e060058e901b811692831c199c909c1690821c179a8190036120125760038c901c600090815260018601602052604081209b909b555b8b61201c81613590565b9c505060019093019250611e8e915050565b5061281d565b600185600281111561204857612048612e8a565b036123385761206f866040518060600160405280602881526020016136a360289139612a17565b60005b845181101561202e57600085828151811061208f5761208f613214565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c308103612164576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4c69624469616d6f6e644375743a2043616e2774207265706c61636520696d6d60448201527f757461626c652066756e6374696f6e00000000000000000000000000000000006064820152608401610360565b8973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361221f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e00000000000000006064820152608401610360565b73ffffffffffffffffffffffffffffffffffffffff81166122c2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e207468617420646f65736e277420657869737400000000000000006064820152608401610360565b507fffffffff0000000000000000000000000000000000000000000000000000000090911660009081526020849052604090206bffffffffffffffffffffffff919091167fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608a901b16179055600101612072565b600285600281111561234c5761234c612e8a565b036127955773ffffffffffffffffffffffffffffffffffffffff8616156123f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d7573742062652061646472657373283029000000000000000000006064820152608401610360565b600388901c6007891660005b86518110156127755760008a900361243d578261241d816135c8565b60008181526001870160205260409020549b5093506007925061244b9050565b81612447816135c8565b9250505b6000806000808a858151811061246357612463613214565b6020908102919091018101517fffffffff0000000000000000000000000000000000000000000000000000000081166000908152918a9052604090912054909150606081901c612535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608401610360565b30606082901c036125c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e0000000000000000000000000000000000006064820152608401610360565b600587901b8f901b94507fffffffff0000000000000000000000000000000000000000000000000000000080861690831614612666577fffffffff000000000000000000000000000000000000000000000000000000008516600090815260208a90526040902080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff83161790555b7fffffffff0000000000000000000000000000000000000000000000000000000091909116600090815260208990526040812055600381901c611fff16925060051b60e01690508582146126fb576000828152600188016020526040902080547fffffffff0000000000000000000000000000000000000000000000000000000080841c19909116908516831c17905561274c565b80837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c817fffffffff0000000000000000000000000000000000000000000000000000000060001b901c198e16179c505b8460000361276a57600086815260018801602052604081208190559c505b505050600101612401565b50806127828360086135fd565b61278c9190613201565b9950505061281d565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560448201527f74416374696f6e000000000000000000000000000000000000000000000000006064820152608401610360565b50959694955050505050565b73ffffffffffffffffffffffffffffffffffffffff8216612848575050565b61286a8260405180606001604052806028815260200161367b60289139612a17565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051612892919061355b565b600060405180830381855af49150503d80600081146128cd576040519150601f19603f3d011682016040523d82523d6000602084013e6128d2565b606091505b509150915081612922578051156128ec5780518082602001fd5b83836040517f192105d7000000000000000000000000000000000000000000000000000000008152600401610360929190613614565b50505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561295f5750600090506003612a0e565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156129b3573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116612a0757600060019250925050612a0e565b9150600090505b94509492505050565b813b8181612922576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103609190613643565b60008083601f840112612a6457600080fd5b50813567ffffffffffffffff811115612a7c57600080fd5b6020830191508360208260051b8501011115611c3457600080fd5b60008060208385031215612aaa57600080fd5b823567ffffffffffffffff811115612ac157600080fd5b612acd85828601612a52565b90969095509350505050565b60008060008060008060608789031215612af257600080fd5b863567ffffffffffffffff80821115612b0a57600080fd5b612b168a838b01612a52565b90985096506020890135915080821115612b2f57600080fd5b612b3b8a838b01612a52565b90965094506040890135915080821115612b5457600080fd5b50612b6189828a01612a52565b979a9699509497509295939492505050565b803573ffffffffffffffffffffffffffffffffffffffff81168114612b9757600080fd5b919050565b600080600080600060608688031215612bb457600080fd5b853567ffffffffffffffff80821115612bcc57600080fd5b612bd889838a01612a52565b9097509550859150612bec60208901612b73565b94506040880135915080821115612c0257600080fd5b818801915088601f830112612c1657600080fd5b813581811115612c2557600080fd5b896020828501011115612c3757600080fd5b9699959850939650602001949392505050565b600060208284031215612c5c57600080fd5b5035919050565b80357fffffffff0000000000000000000000000000000000000000000000000000000081168114612b9757600080fd5b8015158114612ca157600080fd5b50565b60008060408385031215612cb757600080fd5b612cc083612c63565b91506020830135612cd081612c93565b809150509250929050565b60008060408385031215612cee57600080fd5b82359150612cfe60208401612b73565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff81118282101715612d5957612d59612d07565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715612da657612da6612d07565b604052919050565b600067ffffffffffffffff821115612dc857612dc8612d07565b5060051b60200190565b60008060408385031215612de557600080fd5b8235915060208084013567ffffffffffffffff811115612e0457600080fd5b8401601f81018613612e1557600080fd5b8035612e28612e2382612dae565b612d5f565b81815260059190911b82018301908381019088831115612e4757600080fd5b928401925b82841015612e6c57612e5d84612b73565b82529284019290840190612e4c565b80955050505050509250929050565b803560038110612b9757600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60038110612ef0577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b8183526000602080850194508260005b85811015612f49577fffffffff00000000000000000000000000000000000000000000000000000000612f3683612c63565b1687529582019590820190600101612f04565b509495945050505050565b60208082528181018390526000906040808401600586811b8601830188865b8981101561309b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc089840301855281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa18c3603018112612fd457600080fd5b8b01606073ffffffffffffffffffffffffffffffffffffffff612ff683612b73565b168552613004898301612e7b565b6130108a870182612eb9565b50878201357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe183360301811261304557600080fd5b90910188810191903567ffffffffffffffff81111561306357600080fd5b80871b360383131561307457600080fd5b81898701526130868287018285612ef4565b978a0197955050509187019150600101612f73565b50909998505050505050505050565b60006130b8612e2384612dae565b83815260208082019190600586811b8601368111156130d657600080fd5b865b818110156131c557803567ffffffffffffffff808211156130f95760008081fd5b818a0191506060823603121561310f5760008081fd5b613117612d36565b61312083612b73565b815261312d878401612e7b565b87820152604080840135838111156131455760008081fd5b939093019236601f85011261315c57600092508283fd5b8335925061316c612e2384612dae565b83815292871b840188019288810190368511156131895760008081fd5b948901945b848610156131ae5761319f86612c63565b8252948901949089019061318e565b9183019190915250885250509483019483016130d8565b5092979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610c8757610c876131d2565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561325557600080fd5b61325e82612b73565b9392505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261329a57600080fd5b83018035915067ffffffffffffffff8211156132b557600080fd5b602001915036819003821315611c3457600080fd5b600081518084526020808501945080840160005b83811015612f495781517fffffffff0000000000000000000000000000000000000000000000000000000016875295820195908201906001016132de565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000610ee560408301846132ca565b60006020828403121561335d57600080fd5b815161325e81612c93565b81810381811115610c8757610c876131d2565b6000826133b1577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60005b838110156133d15781810151838201526020016133b9565b50506000910152565b600081518084526133f28160208601602086016133b6565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6000606080830181845280875180835260808601915060808160051b87010192506020808a0160005b838110156134d4577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80898703018552815173ffffffffffffffffffffffffffffffffffffffff8151168752838101516134a885890182612eb9565b506040908101519087018890526134c1878901826132ca565b965050938201939082019060010161344d565b505073ffffffffffffffffffffffffffffffffffffffff8916908701525050838103604085015261350581866133da565b979650505050505050565b60006020828403121561352257600080fd5b81516fffffffffffffffffffffffffffffffff8116811461325e57600080fd5b828152604060208201526000610ee560408301846133da565b6000825161356d8184602087016133b6565b9190910192915050565b60006020828403121561358957600080fd5b5051919050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036135c1576135c16131d2565b5060010190565b6000816135d7576135d76131d2565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b8082028115828204841417610c8757610c876131d2565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000610ee560408301846133da565b60208152600061325e60208301846133da56fe4c69624469616d6f6e644375743a2041646420666163657420686173206e6f20636f64654c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a205265706c61636520666163657420686173206e6f20636f6465a2646970667358221220c5a8c10b22f20cde3fe0431ff57305237423677a60888f5b349fc6751336ae1464736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "Responsible for adding/removing/replace facets in Barz", + "kind": "dev", + "methods": { + "_checkDuplicateOnChainApprover(bytes32,address[])": { + "params": { + "_approvers": "List of approver addresses", + "_diamondCutHash": "Hash of diamondCut information including the facet addresses and function selectors" + } + }, + "approveDiamondCut((address,uint8,bytes4[])[])": { + "params": { + "_diamondCut": "Contains the facet addresses and function selectors" + } + }, + "constructor": { + "params": { + "_securityManager": "Security Manager contract that holds the security related variables for all wallets" + } + }, + "diamondCut((address,uint8,bytes4[])[],address,bytes)": { + "params": { + "_diamondCut": "Contains the facet addresses and function selectors", + "_init": "The address of the contract or facet to execute _calldata. It's prohibited in Barz" + } + }, + "diamondCutWithGuardian((address,uint8,bytes4[])[],address[],bytes[])": { + "params": { + "_approvers": "Guardian or owner address that approves the diamond cut", + "_diamondCut": "Contains the facet addresses and function selectors", + "_signatures": "Signature of Guardians or owner that approves the diamond cut" + } + }, + "getDiamondCutApprovalCountWithTimeValidity(bytes32)": { + "params": { + "_diamondCutHash": "Hash of diamondCut information including the facet addresses and function selectors" + } + }, + "getDiamondCutHash((address,uint8,bytes4[])[])": { + "params": { + "_diamondCut": "Contains the facet addresses and function selectors" + }, + "returns": { + "cutHash": "Diamond Cut Hash" + } + }, + "getDiamondCutNonce()": { + "details": "This method fetches the nonce from diamond cut storage", + "returns": { + "cutNonce": "Nonce of diamond cut to protect from reply attacks" + } + }, + "getOwnerCutApprovalWithTimeValidity(bytes32)": { + "params": { + "_diamondCutHash": "Hash of diamondCut information including the facet addresses and function selectors" + }, + "returns": { + "isApprovedByOwner": "Bool value showing if the owner approved the cut" + } + }, + "isCutApproved(bytes32,address)": { + "params": { + "_approver": "Address of approver", + "_diamondCutHash": "Hash of diamondCut information including the facet addresses and function selectors" + }, + "returns": { + "isApproved": "Bool value showing if the approver approved the cut" + } + }, + "revokeDiamondCutApproval((address,uint8,bytes4[])[])": { + "params": { + "_diamondCut": "Contains the facet addresses and function selectors" + } + }, + "updateSupportsInterface(bytes4,bool)": { + "params": { + "_flag": "Bool value to update the mapping of the given interface ID", + "_interfaceId": "InterfaceID to update the mapping" + } + } + }, + "title": "DiamondCut Facet", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "_checkDuplicateOnChainApprover(bytes32,address[])": { + "notice": "Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval Approvers who approved on-chain should not be included in the off-chain approval" + }, + "approveDiamondCut((address,uint8,bytes4[])[])": { + "notice": "Approves diamond cut. This can only be called directly from guardian or owner" + }, + "constructor": { + "notice": "This constructor sets the Security Manager address which is an immutable variable. Immutable variables do not impact the storage of diamond" + }, + "diamondCut((address,uint8,bytes4[])[],address,bytes)": { + "notice": "Add/replace/remove any number of functions and optionally execute a function with delegatecall when guardians don't exist" + }, + "diamondCutWithGuardian((address,uint8,bytes4[])[],address[],bytes[])": { + "notice": "Add/replace/remove any number of functions and optionally execute a function with delegatecall when guardians exist" + }, + "getDiamondCutApprovalCountWithTimeValidity(bytes32)": { + "notice": "Gets the number of approvals of diamond cut from guardians" + }, + "getDiamondCutHash((address,uint8,bytes4[])[])": { + "notice": "Returns the diamond cut hash. This function ensures that this hash is safe from replay attack by including salt, address, chainId, and nonce, etc." + }, + "getDiamondCutNonce()": { + "notice": "Returns the diamond cut nonce of this wallet" + }, + "getOwnerCutApprovalWithTimeValidity(bytes32)": { + "notice": "Returns if the owner has approved the diamond cut" + }, + "isCutApproved(bytes32,address)": { + "notice": "Returns if the given approver has approved the diamond cut" + }, + "revokeDiamondCutApproval((address,uint8,bytes4[])[])": { + "notice": "Revokes the approval of diamond cut. This can only be called directly from guardian or owner" + }, + "updateSupportsInterface(bytes4,bool)": { + "notice": "Updates the flag for the interfaceId" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 27823, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "s", + "offset": 0, + "slot": "0", + "type": "t_struct(AppStorage)27570_storage" + } + ], + "types": { + "t_bytes4": { + "encoding": "inplace", + "label": "bytes4", + "numberOfBytes": "4" + }, + "t_contract(IEntryPoint)12286": { + "encoding": "inplace", + "label": "contract IEntryPoint", + "numberOfBytes": "20" + }, + "t_contract(IFacetRegistry)26105": { + "encoding": "inplace", + "label": "contract IFacetRegistry", + "numberOfBytes": "20" + }, + "t_mapping(t_uint256,t_struct(InitializersStorage)27549_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => struct InitializersStorage)", + "numberOfBytes": "32", + "value": "t_struct(InitializersStorage)27549_storage" + }, + "t_mapping(t_uint256,t_struct(Lock)27542_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => struct Lock)", + "numberOfBytes": "32", + "value": "t_struct(Lock)27542_storage" + }, + "t_struct(AppStorage)27570_storage": { + "encoding": "inplace", + "label": "struct AppStorage", + "members": [ + { + "astId": 27554, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "initStorage", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_uint256,t_struct(InitializersStorage)27549_storage)" + }, + { + "astId": 27556, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "signerMigration", + "offset": 0, + "slot": "1", + "type": "t_uint8" + }, + { + "astId": 27558, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "validateOwnerSignatureSelector", + "offset": 1, + "slot": "1", + "type": "t_bytes4" + }, + { + "astId": 27561, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "entryPoint", + "offset": 5, + "slot": "1", + "type": "t_contract(IEntryPoint)12286" + }, + { + "astId": 27564, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "facetRegistry", + "offset": 0, + "slot": "2", + "type": "t_contract(IFacetRegistry)26105" + }, + { + "astId": 27569, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "locks", + "offset": 0, + "slot": "3", + "type": "t_mapping(t_uint256,t_struct(Lock)27542_storage)" + } + ], + "numberOfBytes": "128" + }, + "t_struct(InitializersStorage)27549_storage": { + "encoding": "inplace", + "label": "struct InitializersStorage", + "members": [ + { + "astId": 27544, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "signerInitialized", + "offset": 0, + "slot": "0", + "type": "t_uint8" + }, + { + "astId": 27546, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "accountInitialized", + "offset": 1, + "slot": "0", + "type": "t_uint8" + }, + { + "astId": 27548, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "restrictionsInitialized", + "offset": 2, + "slot": "0", + "type": "t_uint8" + } + ], + "numberOfBytes": "32" + }, + "t_struct(Lock)27542_storage": { + "encoding": "inplace", + "label": "struct Lock", + "members": [ + { + "astId": 27539, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "release", + "offset": 0, + "slot": "0", + "type": "t_uint64" + }, + { + "astId": 27541, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "locker", + "offset": 8, + "slot": "0", + "type": "t_bytes4" + } + ], + "numberOfBytes": "32" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint64": { + "encoding": "inplace", + "label": "uint64", + "numberOfBytes": "8" + }, + "t_uint8": { + "encoding": "inplace", + "label": "uint8", + "numberOfBytes": "1" + } + } + } +} \ No newline at end of file diff --git a/deployments/bsc/DiamondLoupeFacet.json b/deployments/bsc/DiamondLoupeFacet.json new file mode 100644 index 0000000..97269c7 --- /dev/null +++ b/deployments/bsc/DiamondLoupeFacet.json @@ -0,0 +1,306 @@ +{ + "address": "0xCe36b85d12D81cd619C745c7717f3396E184Ac7C", + "abi": [ + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_functionSelector", + "type": "bytes4" + } + ], + "name": "facetAddress", + "outputs": [ + { + "internalType": "address", + "name": "facetAddress_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_functionSelector", + "type": "bytes4" + } + ], + "name": "facetAddressFromStorage", + "outputs": [ + { + "internalType": "address", + "name": "facetAddress_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetAddresses", + "outputs": [ + { + "internalType": "address[]", + "name": "facetAddresses_", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetAddressesFromStorage", + "outputs": [ + { + "internalType": "address[]", + "name": "facetAddresses_", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_facet", + "type": "address" + } + ], + "name": "facetFunctionSelectors", + "outputs": [ + { + "internalType": "bytes4[]", + "name": "facetFunctionSelectors_", + "type": "bytes4[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_facet", + "type": "address" + } + ], + "name": "facetFunctionSelectorsFromStorage", + "outputs": [ + { + "internalType": "bytes4[]", + "name": "facetFunctionSelectors_", + "type": "bytes4[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facets", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondLoupe.Facet[]", + "name": "facets_", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetsFromStorage", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondLoupe.Facet[]", + "name": "facets_", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "isSupported", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0x9c9f2a8205b82949eb3f094fe6b467f2964ba0ae0b80f1f0deaa4e5ac45ebafe", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 92, + "gasUsed": "2036373", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x643cfecbe8b2f16a93dc420354765453b753c79a76c7a8f1339b4a62372e938b", + "transactionHash": "0x9c9f2a8205b82949eb3f094fe6b467f2964ba0ae0b80f1f0deaa4e5ac45ebafe", + "logs": [], + "blockNumber": 33657812, + "cumulativeGasUsed": "10115131", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 4, + "solcInputHash": "4356503edd8ae34e73cb6dd1c8e2fc8a", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_functionSelector\",\"type\":\"bytes4\"}],\"name\":\"facetAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"facetAddress_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_functionSelector\",\"type\":\"bytes4\"}],\"name\":\"facetAddressFromStorage\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"facetAddress_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetAddresses\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"facetAddresses_\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetAddressesFromStorage\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"facetAddresses_\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_facet\",\"type\":\"address\"}],\"name\":\"facetFunctionSelectors\",\"outputs\":[{\"internalType\":\"bytes4[]\",\"name\":\"facetFunctionSelectors_\",\"type\":\"bytes4[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_facet\",\"type\":\"address\"}],\"name\":\"facetFunctionSelectorsFromStorage\",\"outputs\":[{\"internalType\":\"bytes4[]\",\"name\":\"facetFunctionSelectors_\",\"type\":\"bytes4[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facets\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondLoupe.Facet[]\",\"name\":\"facets_\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetsFromStorage\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondLoupe.Facet[]\",\"name\":\"facets_\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isSupported\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"DiamondLoupe contract compatible with EIP-2535\",\"kind\":\"dev\",\"methods\":{\"facetAddress(bytes4)\":{\"details\":\"If facet is not found return address(0).\",\"params\":{\"_functionSelector\":\"The function selector.\"},\"returns\":{\"facetAddress_\":\"The facet address.\"}},\"facetAddressFromStorage(bytes4)\":{\"params\":{\"_functionSelector\":\"Function selector to fetch the facet address from diamond storage\"},\"returns\":{\"facetAddress_\":\"Facet address mapped with the function selector\"}},\"facetAddresses()\":{\"returns\":{\"facetAddresses_\":\"facetAddresses_\"}},\"facetAddressesFromStorage()\":{\"returns\":{\"facetAddresses_\":\"All facet addresses attached directly to diamond storage\"}},\"facetFunctionSelectors(address)\":{\"params\":{\"_facet\":\"The facet address.\"},\"returns\":{\"facetFunctionSelectors_\":\"facetFunctionSelectors_\"}},\"facetFunctionSelectorsFromStorage(address)\":{\"params\":{\"_facet\":\"Facet address to fetch the facet function selectors from diamond storage\"},\"returns\":{\"facetFunctionSelectors_\":\"Facet function selectors of the given facet address\"}},\"facets()\":{\"details\":\"Barz uses a special architecture called default fallback handler. Default Fallback handler is used as a middleware that holds the mapping of facet function selector and facet address that Barz uses. This helps Barz to reduce significant amount of gas during the initialization process. Hence, this method aggregates both the facet information from DefaulFallbackHandler and in diamond storage and shows the data to users.\",\"returns\":{\"facets_\":\"Facet\"}},\"facetsFromStorage()\":{\"returns\":{\"facets_\":\"Facet information attached directly to diamond storage\"}},\"supportsInterface(bytes4)\":{\"params\":{\"_interfaceId\":\"Interface ID for detecting the interface\"},\"returns\":{\"isSupported\":\"Bool value showing if the standard is supported in the contract\"}}},\"title\":\"DiamondLoupe Facet\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"facetAddress(bytes4)\":{\"notice\":\"Gets the facet that supports the given selector.\"},\"facetAddressFromStorage(bytes4)\":{\"notice\":\"Returns the facet address attached to the given function selector. This excludes the facets from the default fallback handler\"},\"facetAddresses()\":{\"notice\":\"Get all the facet addresses used by Barz.\"},\"facetAddressesFromStorage()\":{\"notice\":\"Returns all facet addresses attached directly to diamond storage. This excludes the facets from the default fallback handler\"},\"facetFunctionSelectors(address)\":{\"notice\":\"Gets all the function selectors provided by a facet.\"},\"facetFunctionSelectorsFromStorage(address)\":{\"notice\":\"Returns function selectors of given facet address attached directly to diamond storage. This excludes the facets from the default fallback handler\"},\"facets()\":{\"notice\":\"Gets all facets and their selectors.\"},\"facetsFromStorage()\":{\"notice\":\"Returns the facet from the diamond storage. This excludes the facets from the default fallback handler\"},\"supportsInterface(bytes4)\":{\"notice\":\"SupportInterface to be compatible with EIP 165\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/base/DiamondLoupeFacet.sol\":\"DiamondLoupeFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/introspection/IERC165.sol\\\";\\n\\n/**\\n * @dev _Available since v3.1._\\n */\\ninterface IERC1155Receiver is IERC165 {\\n /**\\n * @dev Handles the receipt of a single ERC1155 token type. This function is\\n * called at the end of a `safeTransferFrom` after the balance has been updated.\\n *\\n * NOTE: To accept the transfer, this must return\\n * `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))`\\n * (i.e. 0xf23a6e61, or its own function selector).\\n *\\n * @param operator The address which initiated the transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param id The ID of the token being transferred\\n * @param value The amount of tokens being transferred\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155Received(\\n address operator,\\n address from,\\n uint256 id,\\n uint256 value,\\n bytes calldata data\\n ) external returns (bytes4);\\n\\n /**\\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\\n * is called at the end of a `safeBatchTransferFrom` after the balances have\\n * been updated.\\n *\\n * NOTE: To accept the transfer(s), this must return\\n * `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))`\\n * (i.e. 0xbc197c81, or its own function selector).\\n *\\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155BatchReceived(\\n address operator,\\n address from,\\n uint256[] calldata ids,\\n uint256[] calldata values,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xeb373f1fdc7b755c6a750123a9b9e3a8a02c1470042fd6505d875000a80bde0b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title ERC721 token receiver interface\\n * @dev Interface for any contract that wants to support safeTransfers\\n * from ERC721 asset contracts.\\n */\\ninterface IERC721Receiver {\\n /**\\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\\n * by `operator` from `from`, this function is called.\\n *\\n * It must return its Solidity selector to confirm the token transfer.\\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\\n *\\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\\n */\\n function onERC721Received(\\n address operator,\\n address from,\\n uint256 tokenId,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\\n *\\n * Accounts can be notified of {IERC777} tokens being sent to them by having a\\n * contract implement this interface (contract holders can be their own\\n * implementer) and registering it on the\\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\\n *\\n * See {IERC1820Registry} and {ERC1820Implementer}.\\n */\\ninterface IERC777Recipient {\\n /**\\n * @dev Called by an {IERC777} token contract whenever tokens are being\\n * moved or created into a registered account (`to`). The type of operation\\n * is conveyed by `from` being the zero address or not.\\n *\\n * This call occurs _after_ the token contract's state is updated, so\\n * {IERC777-balanceOf}, etc., can be used to query the post-operation state.\\n *\\n * This function may revert to prevent the operation from being executed.\\n */\\n function tokensReceived(\\n address operator,\\n address from,\\n address to,\\n uint256 amount,\\n bytes calldata userData,\\n bytes calldata operatorData\\n ) external;\\n}\\n\",\"keccak256\":\"0x1a5d61db2733202ba361e6d6741cd2e662380e22b80e987eacfc91973f2267dc\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"contracts/facets/base/DiamondLoupeFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IERC777Recipient} from \\\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\\\";\\nimport {IERC165} from \\\"../../interfaces/ERC/IERC165.sol\\\";\\nimport {IERC1271} from \\\"../../interfaces/ERC/IERC1271.sol\\\";\\nimport {IERC677Receiver} from \\\"../../interfaces/ERC/IERC677Receiver.sol\\\";\\nimport {IERC721Receiver} from \\\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\\\";\\nimport {IERC1155Receiver} from \\\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\\\";\\nimport {LibDiamond} from \\\"../../libraries/LibDiamond.sol\\\";\\nimport {LibLoupe} from \\\"../../libraries/LibLoupe.sol\\\";\\nimport {LibUtils} from \\\"../../libraries/LibUtils.sol\\\";\\nimport {IDiamondCut} from \\\"../../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IStorageLoupe} from \\\"./interfaces/IStorageLoupe.sol\\\";\\nimport {IDiamondLoupe} from \\\"./interfaces/IDiamondLoupe.sol\\\";\\n\\n/**\\n * @title DiamondLoupe Facet\\n * @dev DiamondLoupe contract compatible with EIP-2535\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract DiamondLoupeFacet is IDiamondLoupe, IStorageLoupe, IERC165 {\\n // Diamond Loupe Functions\\n ////////////////////////////////////////////////////////////////////\\n /// These functions are expected to be called frequently by tools off-chain.\\n\\n /**\\n * @notice Gets all facets and their selectors.\\n * @dev Barz uses a special architecture called default fallback handler. Default Fallback handler is used as a middleware\\n * that holds the mapping of facet function selector and facet address that Barz uses. This helps Barz to reduce\\n * significant amount of gas during the initialization process.\\n * Hence, this method aggregates both the facet information from DefaulFallbackHandler and in diamond storage and shows the data to users.\\n * @return facets_ Facet\\n */\\n function facets() public view override returns (Facet[] memory facets_) {\\n Facet[] memory defaultFacet = LibDiamond\\n .diamondStorage()\\n .defaultFallbackHandler\\n .facets();\\n Facet[] memory _facets = LibLoupe.facets();\\n uint256 numFacets = _facets.length;\\n bytes4[] memory keys;\\n address[] memory values;\\n for (uint256 i; i < numFacets; ) {\\n uint256 selectorsLength = _facets[i].functionSelectors.length;\\n for (uint256 j; j < selectorsLength; ) {\\n (keys, values) = LibUtils.setValue(\\n keys,\\n values,\\n _facets[i].functionSelectors[j],\\n _facets[i].facetAddress\\n );\\n unchecked {\\n ++j;\\n }\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n {\\n bool iIncrement;\\n for (uint256 i; i < defaultFacet.length; ) {\\n bool jIncrement;\\n for (\\n uint256 j;\\n j < defaultFacet[i].functionSelectors.length;\\n\\n ) {\\n if (\\n LibUtils.getValue(\\n keys,\\n values,\\n defaultFacet[i].functionSelectors[j]\\n ) != address(0)\\n ) {\\n if (defaultFacet[i].functionSelectors.length == 1) {\\n defaultFacet = LibUtils.removeFacetElement(\\n defaultFacet,\\n i\\n );\\n iIncrement = true;\\n break;\\n }\\n defaultFacet[i].functionSelectors = LibUtils\\n .removeElement(\\n defaultFacet[i].functionSelectors,\\n j\\n );\\n jIncrement = true;\\n }\\n if (!jIncrement) {\\n unchecked {\\n ++j;\\n }\\n } else {\\n jIncrement = false;\\n }\\n }\\n if (!iIncrement) {\\n unchecked {\\n ++i;\\n }\\n } else {\\n iIncrement = false;\\n }\\n }\\n }\\n {\\n uint256 facetLength = numFacets + defaultFacet.length;\\n facets_ = new Facet[](facetLength);\\n uint256 defaultFacetIndex;\\n for (uint256 i; i < facetLength; ) {\\n if (i < numFacets) {\\n facets_[i] = _facets[i];\\n bool jIncrementor;\\n for (uint256 j; j < defaultFacet.length; ) {\\n if (\\n facets_[i].facetAddress ==\\n defaultFacet[j].facetAddress\\n ) {\\n facets_[i].functionSelectors = LibUtils.mergeArrays(\\n _facets[i].functionSelectors,\\n defaultFacet[j].functionSelectors\\n );\\n defaultFacet = LibUtils.removeFacetElement(\\n defaultFacet,\\n j\\n );\\n jIncrementor = true;\\n {\\n facets_ = LibUtils.removeFacetElement(\\n facets_,\\n facets_.length - 1\\n );\\n }\\n --facetLength;\\n }\\n if (!jIncrementor) {\\n unchecked {\\n ++j;\\n }\\n } else {\\n jIncrementor = false;\\n }\\n }\\n } else {\\n facets_[i] = defaultFacet[defaultFacetIndex];\\n ++defaultFacetIndex;\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n }\\n\\n /**\\n * @notice Gets all the function selectors provided by a facet.\\n * @param _facet The facet address.\\n * @return facetFunctionSelectors_\\n */\\n function facetFunctionSelectors(\\n address _facet\\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\\n Facet[] memory facet = facets();\\n uint256 facetLength = facet.length;\\n for (uint256 i; i < facetLength; ) {\\n if (facet[i].facetAddress == _facet)\\n return facet[i].functionSelectors;\\n unchecked {\\n ++i;\\n }\\n }\\n return facetFunctionSelectors_;\\n }\\n\\n /**\\n * @notice Get all the facet addresses used by Barz.\\n * @return facetAddresses_\\n */\\n function facetAddresses()\\n external\\n view\\n override\\n returns (address[] memory facetAddresses_)\\n {\\n Facet[] memory facet = facets();\\n uint256 facetLength = facet.length;\\n facetAddresses_ = new address[](facetLength);\\n for (uint256 i; i < facetLength; ) {\\n facetAddresses_[i] = facet[i].facetAddress;\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * @notice Gets the facet that supports the given selector.\\n * @dev If facet is not found return address(0).\\n * @param _functionSelector The function selector.\\n * @return facetAddress_ The facet address.\\n */\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view override returns (address facetAddress_) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n\\n facetAddress_ = address(bytes20(ds.facets[_functionSelector]));\\n if (facetAddress_ == address(0)) {\\n facetAddress_ = IDiamondLoupe(ds.defaultFallbackHandler)\\n .facetAddress(_functionSelector);\\n }\\n }\\n\\n /**\\n * @notice SupportInterface to be compatible with EIP 165\\n * @param _interfaceId Interface ID for detecting the interface\\n * @return isSupported Bool value showing if the standard is supported in the contract\\n */\\n function supportsInterface(\\n bytes4 _interfaceId\\n ) external view override returns (bool isSupported) {\\n isSupported =\\n _interfaceId == type(IERC165).interfaceId ||\\n _interfaceId == IDiamondCut.diamondCut.selector ||\\n _interfaceId == type(IDiamondLoupe).interfaceId ||\\n _interfaceId == type(IERC1155Receiver).interfaceId ||\\n _interfaceId == type(IERC721Receiver).interfaceId ||\\n _interfaceId == type(IERC777Recipient).interfaceId ||\\n _interfaceId == IERC1271.isValidSignature.selector ||\\n _interfaceId == type(IERC677Receiver).interfaceId ||\\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId];\\n }\\n\\n /**\\n * @notice Returns the facet from the diamond storage. This excludes the facets from the default fallback handler\\n * @return facets_ Facet information attached directly to diamond storage\\n */\\n function facetsFromStorage()\\n external\\n view\\n override\\n returns (Facet[] memory facets_)\\n {\\n facets_ = LibLoupe.facets();\\n }\\n\\n /**\\n * @notice Returns the facet address attached to the given function selector. This excludes the facets from the default fallback handler\\n * @param _functionSelector Function selector to fetch the facet address from diamond storage\\n * @return facetAddress_ Facet address mapped with the function selector\\n */\\n function facetAddressFromStorage(\\n bytes4 _functionSelector\\n ) external view override returns (address facetAddress_) {\\n facetAddress_ = LibLoupe.facetAddress(_functionSelector);\\n }\\n\\n /**\\n * @notice Returns all facet addresses attached directly to diamond storage. This excludes the facets from the default fallback handler\\n * @return facetAddresses_ All facet addresses attached directly to diamond storage\\n */\\n function facetAddressesFromStorage()\\n external\\n view\\n override\\n returns (address[] memory facetAddresses_)\\n {\\n facetAddresses_ = LibLoupe.facetAddresses();\\n }\\n\\n /**\\n * @notice Returns function selectors of given facet address attached directly to diamond storage. This excludes the facets from the default fallback handler\\n * @param _facet Facet address to fetch the facet function selectors from diamond storage\\n * @return facetFunctionSelectors_ Facet function selectors of the given facet address\\n */\\n function facetFunctionSelectorsFromStorage(\\n address _facet\\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\\n facetFunctionSelectors_ = LibLoupe.facetFunctionSelectors(_facet);\\n }\\n}\\n\",\"keccak256\":\"0xf392fde159eec6483fc15fa323ecd6d764028f5b8734a66662c4116292363794\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IStorageLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"./IDiamondLoupe.sol\\\";\\n\\n/**\\n * @title LoupeFromStorage Interface\\n * @dev Interface contract to function as a loupe facet directly attached to diamond storage of Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IStorageLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facetsFromStorage()\\n external\\n view\\n returns (IDiamondLoupe.Facet[] memory);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n function facetFunctionSelectorsFromStorage(\\n address _facet\\n ) external view returns (bytes4[] memory);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n function facetAddressesFromStorage()\\n external\\n view\\n returns (address[] memory);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n function facetAddressFromStorage(\\n bytes4 _functionSelector\\n ) external view returns (address);\\n}\\n\",\"keccak256\":\"0xdf5dc9c57319e9087628c9cf9404b4f75585b76d1c2f4f59ee796c933967ea5c\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC1271 {\\n function isValidSignature(\\n bytes32 hash,\\n bytes memory signature\\n ) external view returns (bytes4);\\n}\\n\",\"keccak256\":\"0xcdddb7d5641c9d3f2432dec7fd13fddb9ae1480f25c76c21511e2fa16b8bd422\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.21;\\n\\ninterface IERC165 {\\n /// @notice Query if a contract implements an interface\\n /// @param interfaceId The interface identifier, as specified in ERC-165\\n /// @dev Interface identification is specified in ERC-165. This function\\n /// uses less than 30,000 gas.\\n /// @return `true` if the contract implements `interfaceID` and\\n /// `interfaceID` is not 0xffffffff, `false` otherwise\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xbb7f07e170898793c5535cc4b7e8944c4b990a631ac806d0b788e794abc788a3\",\"license\":\"MIT\"},\"contracts/interfaces/ERC/IERC677Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC677Receiver {\\n function onTokenTransfer(\\n address sender,\\n uint value,\\n bytes calldata data\\n ) external pure returns (bool);\\n}\\n\",\"keccak256\":\"0x4c1631cf45ea6daac0ec158c3edb9453099130b6b64f697004b83f95aa1f7350\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\\n bytes4(keccak256(\\\"verifyRestrictions(address,address,uint256,bytes)\\\"));\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // Default Fallback Handler of the barz.\\n IDiamondLoupe defaultFallbackHandler;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function enforceIsSelf() internal view {\\n require(msg.sender == address(this), \\\"LibDiamond: Caller not self\\\");\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n\\n unchecked {\\n facetIndex++;\\n }\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n\\n function restrictionsFacet() internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(\\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2cabdc00de859c3a3170ce3bda5d0e5fd3933d47ce904fd1585f9818b02572f8\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\nimport {LibDiamond} from \\\"./LibDiamond.sol\\\";\\n\\n/**\\n * @title LibLoupe\\n * @dev Internal Library to provide utility feature for reading the state of diamond facets\\n * Originally from Diamond's implementation of Mudgen(author of EIP-2535)\\n */\\nlibrary LibLoupe {\\n /// @notice Gets all facets and their selectors.\\n /// @return facets_ Facet\\n function facets()\\n internal\\n view\\n returns (IDiamondLoupe.Facet[] memory facets_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facets_ = new IDiamondLoupe.Facet[](ds.selectorCount);\\n uint16[] memory numFacetSelectors = new uint16[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facets_[facetIndex].facetAddress == facetAddress_) {\\n facets_[facetIndex].functionSelectors[\\n numFacetSelectors[facetIndex]\\n ] = selector;\\n // probably will never have more than 256 functions from one facet contract\\n require(numFacetSelectors[facetIndex] < 255);\\n numFacetSelectors[facetIndex]++;\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facets_[numFacets].facetAddress = facetAddress_;\\n facets_[numFacets].functionSelectors = new bytes4[](\\n ds.selectorCount\\n );\\n facets_[numFacets].functionSelectors[0] = selector;\\n numFacetSelectors[numFacets] = 1;\\n numFacets++;\\n }\\n }\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n uint256 numSelectors = numFacetSelectors[facetIndex];\\n bytes4[] memory selectors = facets_[facetIndex].functionSelectors;\\n // setting the number of selectors\\n assembly {\\n mstore(selectors, numSelectors)\\n }\\n }\\n // setting the number of facets\\n assembly {\\n mstore(facets_, numFacets)\\n }\\n }\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return _facetFunctionSelectors The selectors associated with a facet address.\\n function facetFunctionSelectors(\\n address _facet\\n ) internal view returns (bytes4[] memory _facetFunctionSelectors) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n uint256 numSelectors;\\n _facetFunctionSelectors = new bytes4[](ds.selectorCount);\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facet = address(bytes20(ds.facets[selector]));\\n if (_facet == facet) {\\n _facetFunctionSelectors[numSelectors] = selector;\\n numSelectors++;\\n }\\n }\\n }\\n // Set the number of selectors in the array\\n assembly {\\n mstore(_facetFunctionSelectors, numSelectors)\\n }\\n }\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n internal\\n view\\n returns (address[] memory facetAddresses_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetAddresses_ = new address[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facetAddress_ == facetAddresses_[facetIndex]) {\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facetAddresses_[numFacets] = facetAddress_;\\n numFacets++;\\n }\\n }\\n // Set the number of facet addresses in the array\\n assembly {\\n mstore(facetAddresses_, numFacets)\\n }\\n }\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(LibDiamond.diamondStorage().facets[_functionSelector])\\n );\\n }\\n}\\n\",\"keccak256\":\"0x0b11439c3cc657095e15ec2241fdcf67204b14001357b612fc5db4ff9e760a5a\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibUtils.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nlibrary LibUtils {\\n // Internal utility functions\\n function mergeArrays(\\n bytes4[] memory _array1,\\n bytes4[] memory _array2\\n ) internal pure returns (bytes4[] memory) {\\n uint256 length1 = _array1.length;\\n uint256 length2 = _array2.length;\\n bytes4[] memory mergedArray = new bytes4[](length1 + length2);\\n\\n for (uint256 i; i < length1; ) {\\n mergedArray[i] = _array1[i];\\n unchecked {\\n ++i;\\n }\\n }\\n\\n for (uint256 i; i < length2; ) {\\n mergedArray[length1 + i] = _array2[i];\\n unchecked {\\n ++i;\\n }\\n }\\n\\n return mergedArray;\\n }\\n\\n function removeFacetElement(\\n IDiamondLoupe.Facet[] memory _facets,\\n uint256 _index\\n ) internal pure returns (IDiamondLoupe.Facet[] memory) {\\n require(_index < _facets.length, \\\"Invalid index\\\");\\n require(_facets.length != 0, \\\"Invalid array\\\");\\n\\n // Create a new array with a length of `_facets.length - 1`\\n IDiamondLoupe.Facet[] memory newArray = new IDiamondLoupe.Facet[](\\n _facets.length - 1\\n );\\n uint256 newArrayLength = newArray.length;\\n // Iterate over the original array, skipping the element at the specified `index`\\n for (uint256 i; i < newArrayLength; ) {\\n if (i < _index) {\\n newArray[i] = _facets[i];\\n } else {\\n newArray[i] = _facets[i + 1];\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n\\n return newArray;\\n }\\n\\n function removeElement(\\n bytes4[] memory _array,\\n uint256 _index\\n ) internal pure returns (bytes4[] memory) {\\n require(_index < _array.length, \\\"Invalid index\\\");\\n require(_array.length != 0, \\\"Invalid array\\\");\\n\\n bytes4[] memory newArray = new bytes4[](_array.length - 1);\\n uint256 newArrayLength = newArray.length;\\n for (uint256 i; i < newArrayLength; ) {\\n if (i < _index) {\\n newArray[i] = _array[i];\\n } else {\\n newArray[i] = _array[i + 1];\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n\\n return newArray;\\n }\\n\\n function setValue(\\n bytes4[] memory _keys,\\n address[] memory _values,\\n bytes4 _key,\\n address _value\\n ) internal pure returns (bytes4[] memory, address[] memory) {\\n uint256 index = findIndex(_keys, _key);\\n uint256 keysLength = _keys.length;\\n if (index < keysLength) {\\n _values[index] = _value;\\n } else {\\n // Create new storage arrays\\n bytes4[] memory newKeys = new bytes4[](keysLength + 1);\\n address[] memory newValues = new address[](_values.length + 1);\\n\\n // Copy values to the new storage arrays\\n for (uint256 i; i < keysLength; ) {\\n newKeys[i] = _keys[i];\\n newValues[i] = _values[i];\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n // Add the new key-value pair\\n newKeys[keysLength] = _key;\\n newValues[_values.length] = _value;\\n\\n return (newKeys, newValues);\\n }\\n\\n // If the key already exists, return the original arrays\\n return (_keys, _values);\\n }\\n\\n function getValue(\\n bytes4[] memory _keys,\\n address[] memory _values,\\n bytes4 _key\\n ) internal pure returns (address) {\\n uint256 index = findIndex(_keys, _key);\\n if (index >= _keys.length) return address(0);\\n\\n return _values[index];\\n }\\n\\n function findIndex(\\n bytes4[] memory _keys,\\n bytes4 _key\\n ) internal pure returns (uint256) {\\n uint256 keysLength = _keys.length;\\n for (uint256 i; i < keysLength; ) {\\n if (_keys[i] == _key) {\\n return i;\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n return keysLength;\\n }\\n}\\n\",\"keccak256\":\"0xde8aeefe54c4be483f2b2c055aca11e2830f7094c0586a82e10ec544933b5714\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5061240b806100206000396000f3fe608060405234801561001057600080fd5b50600436106100a35760003560e01c8063adfca15e11610076578063d42139a91161005b578063d42139a914610169578063e3a2f6fe14610171578063f9796ccf1461018457600080fd5b8063adfca15e1461011e578063cdffacc61461013157600080fd5b806301a55022146100a857806301ffc9a7146100d157806352ef6b2c146100f45780637a0ed62714610109575b600080fd5b6100bb6100b6366004611e4b565b61018c565b6040516100c89190611e68565b60405180910390f35b6100e46100df366004611efc565b61019d565b60405190151581526020016100c8565b6100fc610454565b6040516100c89190611f19565b610111610518565b6040516100c89190611f67565b6100bb61012c366004611e4b565b610a63565b61014461013f366004611efc565b610b07565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100c8565b6100fc610c24565b61014461017f366004611efc565b610c33565b610111610c8c565b606061019782610c96565b92915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000148061023057507fffffffff0000000000000000000000000000000000000000000000000000000082167f1f931c1c00000000000000000000000000000000000000000000000000000000145b8061027c57507fffffffff0000000000000000000000000000000000000000000000000000000082167f48e2b09300000000000000000000000000000000000000000000000000000000145b806102c857507fffffffff0000000000000000000000000000000000000000000000000000000082167f4e2312e000000000000000000000000000000000000000000000000000000000145b8061031457507fffffffff0000000000000000000000000000000000000000000000000000000082167f150b7a0200000000000000000000000000000000000000000000000000000000145b8061035f57507fffffffff0000000000000000000000000000000000000000000000000000000082167e23de2900000000000000000000000000000000000000000000000000000000145b806103ab57507fffffffff0000000000000000000000000000000000000000000000000000000082167f1626ba7e00000000000000000000000000000000000000000000000000000000145b806103f757507fffffffff0000000000000000000000000000000000000000000000000000000082167fa4c0ed3600000000000000000000000000000000000000000000000000000000145b806101975750507fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4922602052604090205460ff1690565b60606000610460610518565b80519091508067ffffffffffffffff81111561047e5761047e61205d565b6040519080825280602002602001820160405280156104a7578160200160208202803683370190505b50925060005b81811015610512578281815181106104c7576104c761208c565b6020026020010151600001518482815181106104e5576104e561208c565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526001016104ad565b50505090565b606060007f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f600490810154604080517f7a0ed627000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff90921692637a0ed6279282820192600092908290030181865afa1580156105ac573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526105f29190810190612157565b905060006105fe610e57565b805190915060608060005b838110156106b55760008582815181106106255761062561208c565b60200260200101516020015151905060005b818110156106ab5761069e85858986815181106106565761065661208c565b60200260200101516020015184815181106106735761067361208c565b60200260200101518a878151811061068d5761068d61208c565b60200260200101516000015161134a565b9095509350600101610637565b5050600101610609565b506000805b865181101561081b576000805b8883815181106106d9576106d961208c565b602002602001015160200151518110156107ff57600073ffffffffffffffffffffffffffffffffffffffff1661074687878c878151811061071c5761071c61208c565b60200260200101516020015185815181106107395761073961208c565b60200260200101516115f1565b73ffffffffffffffffffffffffffffffffffffffff16146107e9578883815181106107735761077361208c565b6020026020010151602001515160010361079c576107918984611637565b9850600193506107ff565b6107c38984815181106107b1576107b161208c565b6020026020010151602001518261182a565b8984815181106107d5576107d561208c565b602002602001015160200181905250600191505b816107f6576001016106c7565b600091506106c7565b508261081057816001019150610815565b600092505b506106ba565b5050600085518461082c9190612304565b90508067ffffffffffffffff8111156108475761084761205d565b60405190808252806020026020018201604052801561088d57816020015b6040805180820190915260008152606060208201528152602001906001900390816108655790505b5096506000805b82811015610a585785811015610a0c578681815181106108b6576108b661208c565b60200260200101518982815181106108d0576108d061208c565b60200260200101819052506000805b8951811015610a05578981815181106108fa576108fa61208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff168b848151811061092e5761092e61208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff16036109ef5761099989848151811061096a5761096a61208c565b6020026020010151602001518b83815181106109885761098861208c565b602002602001015160200151611a3d565b8b84815181106109ab576109ab61208c565b6020026020010151602001819052506109c48a82611637565b9950600191506109e18b60018d516109dc9190612317565b611637565b9a506109ec8561232a565b94505b816109fc576001016108df565b600091506108df565b5050610a50565b878281518110610a1e57610a1e61208c565b6020026020010151898281518110610a3857610a3861208c565b602002602001018190525081610a4d9061235f565b91505b600101610894565b505050505050505090565b60606000610a6f610518565b805190915060005b81811015610aff578473ffffffffffffffffffffffffffffffffffffffff16838281518110610aa857610aa861208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1603610af757828181518110610ae157610ae161208c565b6020026020010151602001519350505050919050565b600101610a77565b505050919050565b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602081905260409091205460601c9081610c1e576004818101546040517fcdffacc60000000000000000000000000000000000000000000000000000000081527fffffffff0000000000000000000000000000000000000000000000000000000086169281019290925273ffffffffffffffffffffffffffffffffffffffff169063cdffacc690602401602060405180830381865afa158015610bf7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c1b9190612397565b91505b50919050565b6060610c2e611b8b565b905090565b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604081205460601c610197565b6060610c2e610e57565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9060009061ffff1667ffffffffffffffff811115610cfc57610cfc61205d565b604051908082528060200260200182016040528015610d25578160200160208202803683370190505b5092506000805b600284015461ffff16821015610e4d576000818152600185016020526040812054905b6008811015610e385783610d628161235f565b600288015490955061ffff1685119050610e3857600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020889052604090205460601c73ffffffffffffffffffffffffffffffffffffffff8a16819003610e235781898881518110610de457610de461208c565b7fffffffff000000000000000000000000000000000000000000000000000000009092166020928302919091019091015286610e1f8161235f565b9750505b50508080610e309061235f565b915050610d4f565b50508080610e459061235f565b915050610d2c565b5050825250919050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff1667ffffffffffffffff811115610eba57610eba61205d565b604051908082528060200260200182016040528015610f0057816020015b604080518082019091526000815260606020820152815260200190600190039081610ed85790505b50600282015490925060009061ffff1667ffffffffffffffff811115610f2857610f2861205d565b604051908082528060200260200182016040528015610f51578160200160208202803683370190505b50905060008060005b600285015461ffff168210156112d7576000818152600186016020526040812054905b60088110156112c25783610f908161235f565b600289015490955061ffff16851190506112c257600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020899052604081205460601c90805b88811015611148578273ffffffffffffffffffffffffffffffffffffffff168c82815181106110155761101561208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff160361113657838c828151811061104f5761104f61208c565b6020026020010151602001518b838151811061106d5761106d61208c565b602002602001015161ffff16815181106110895761108961208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152505060ff8a82815181106110e9576110e961208c565b602002602001015161ffff16106110ff57600080fd5b8981815181106111115761111161208c565b602002602001018051809190611126906123b4565b61ffff1690525060019150611148565b806111408161235f565b915050610fe4565b508015611157575050506112b0565b818b898151811061116a5761116a61208c565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff909116905260028a015461ffff1667ffffffffffffffff8111156111b0576111b061205d565b6040519080825280602002602001820160405280156111d9578160200160208202803683370190505b508b89815181106111ec576111ec61208c565b602002602001015160200181905250828b898151811061120e5761120e61208c565b60200260200101516020015160008151811061122c5761122c61208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681525050600189898151811061128c5761128c61208c565b61ffff90921660209283029190910190910152876112a98161235f565b9850505050505b806112ba8161235f565b915050610f7d565b505080806112cf9061235f565b915050610f5a565b5060005b8281101561133f5760008482815181106112f7576112f761208c565b602002602001015161ffff16905060008783815181106113195761131961208c565b6020026020010151602001519050818152505080806113379061235f565b9150506112db565b508185525050505090565b60608060006113598786611da0565b8751909150808210156113b857848783815181106113795761137961208c565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250506115df565b60006113c5826001612304565b67ffffffffffffffff8111156113dd576113dd61205d565b604051908082528060200260200182016040528015611406578160200160208202803683370190505b5090506000885160016114199190612304565b67ffffffffffffffff8111156114315761143161205d565b60405190808252806020026020018201604052801561145a578160200160208202803683370190505b50905060005b83811015611539578a818151811061147a5761147a61208c565b60200260200101518382815181106114945761149461208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815250508981815181106114f2576114f261208c565b602002602001015182828151811061150c5761150c61208c565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101611460565b508782848151811061154d5761154d61208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152505086818a51815181106115ad576115ad61208c565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015290945092506115e8915050565b87879350935050505b94509492505050565b6000806115fe8584611da0565b905084518110611612576000915050611630565b8381815181106116245761162461208c565b60200260200101519150505b9392505050565b6060825182106116a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420696e6465780000000000000000000000000000000000000060448201526064015b60405180910390fd5b8251600003611713576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420617272617900000000000000000000000000000000000000604482015260640161169f565b6000600184516117239190612317565b67ffffffffffffffff81111561173b5761173b61205d565b60405190808252806020026020018201604052801561178157816020015b6040805180820190915260008152606060208201528152602001906001900390816117595790505b50805190915060005b8181101561182057848110156117d6578581815181106117ac576117ac61208c565b60200260200101518382815181106117c6576117c661208c565b6020026020010181905250611818565b856117e2826001612304565b815181106117f2576117f261208c565b602002602001015183828151811061180c5761180c61208c565b60200260200101819052505b60010161178a565b5090949350505050565b606082518210611896576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420696e64657800000000000000000000000000000000000000604482015260640161169f565b8251600003611901576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420617272617900000000000000000000000000000000000000604482015260640161169f565b6000600184516119119190612317565b67ffffffffffffffff8111156119295761192961205d565b604051908082528060200260200182016040528015611952578160200160208202803683370190505b50805190915060005b8181101561182057848110156119cd5785818151811061197d5761197d61208c565b60200260200101518382815181106119975761199761208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152611a35565b856119d9826001612304565b815181106119e9576119e961208c565b6020026020010151838281518110611a0357611a0361208c565b7fffffffff00000000000000000000000000000000000000000000000000000000909216602092830291909101909101525b60010161195b565b81518151606091906000611a518284612304565b67ffffffffffffffff811115611a6957611a6961205d565b604051908082528060200260200182016040528015611a92578160200160208202803683370190505b50905060005b83811015611b0557868181518110611ab257611ab261208c565b6020026020010151828281518110611acc57611acc61208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152600101611a98565b5060005b82811015611b8157858181518110611b2357611b2361208c565b6020026020010151828286611b389190612304565b81518110611b4857611b4861208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152600101611b09565b5095945050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff1667ffffffffffffffff811115611bee57611bee61205d565b604051908082528060200260200182016040528015611c17578160200160208202803683370190505b50915060008060005b600284015461ffff16821015611d98576000818152600185016020526040812054905b6008811015611d835783611c568161235f565b600288015490955061ffff1685119050611d8357600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020889052604081205460601c90805b88811015611d19578a8181518110611cc457611cc461208c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611d075760019150611d19565b80611d118161235f565b915050611caa565b508015611d2857505050611d71565b818a8981518110611d3b57611d3b61208c565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015287611d6a8161235f565b9850505050505b80611d7b8161235f565b915050611c43565b50508080611d909061235f565b915050611c20565b505082525090565b8151600090815b81811015611e1e57837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916858281518110611de157611de161208c565b60200260200101517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603611e165791506101979050565b600101611da7565b509392505050565b73ffffffffffffffffffffffffffffffffffffffff81168114611e4857600080fd5b50565b600060208284031215611e5d57600080fd5b813561163081611e26565b6020808252825182820181905260009190848201906040850190845b81811015611ec25783517fffffffff000000000000000000000000000000000000000000000000000000001683529284019291840191600101611e84565b50909695505050505050565b7fffffffff0000000000000000000000000000000000000000000000000000000081168114611e4857600080fd5b600060208284031215611f0e57600080fd5b813561163081611ece565b6020808252825182820181905260009190848201906040850190845b81811015611ec257835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101611f35565b60006020808301818452808551808352604092508286019150828160051b8701018488016000805b8481101561204e578984037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00186528251805173ffffffffffffffffffffffffffffffffffffffff168552880151888501889052805188860181905290890190839060608701905b808310156120395783517fffffffff00000000000000000000000000000000000000000000000000000000168252928b019260019290920191908b0190611ff7565b50978a01979550505091870191600101611f8f565b50919998505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6040805190810167ffffffffffffffff811182821017156120de576120de61205d565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561212b5761212b61205d565b604052919050565b600067ffffffffffffffff82111561214d5761214d61205d565b5060051b60200190565b6000602080838503121561216a57600080fd5b825167ffffffffffffffff8082111561218257600080fd5b818501915085601f83011261219657600080fd5b81516121a96121a482612133565b6120e4565b81815260059190911b830184019084810190888311156121c857600080fd5b8585015b838110156122c8578051858111156121e45760008081fd5b86016040818c037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00181131561221a5760008081fd5b6122226120bb565b8983015161222f81611e26565b815282820151888111156122435760008081fd5b8084019350508c603f8401126122595760008081fd5b898301516122696121a482612133565b81815260059190911b84018301908b8101908f8311156122895760008081fd5b948401945b828610156122b357855194506122a385611ece565b848252948c0194908c019061228e565b838d01525050855250509186019186016121cc565b5098975050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610197576101976122d5565b81810381811115610197576101976122d5565b600081612339576123396122d5565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612390576123906122d5565b5060010190565b6000602082840312156123a957600080fd5b815161163081611e26565b600061ffff8083168181036123cb576123cb6122d5565b600101939250505056fea26469706673582212205959d8d85aad6f29d5fc37d5a52c404c25392cec49195c3b761da0e863e99b0f64736f6c63430008150033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100a35760003560e01c8063adfca15e11610076578063d42139a91161005b578063d42139a914610169578063e3a2f6fe14610171578063f9796ccf1461018457600080fd5b8063adfca15e1461011e578063cdffacc61461013157600080fd5b806301a55022146100a857806301ffc9a7146100d157806352ef6b2c146100f45780637a0ed62714610109575b600080fd5b6100bb6100b6366004611e4b565b61018c565b6040516100c89190611e68565b60405180910390f35b6100e46100df366004611efc565b61019d565b60405190151581526020016100c8565b6100fc610454565b6040516100c89190611f19565b610111610518565b6040516100c89190611f67565b6100bb61012c366004611e4b565b610a63565b61014461013f366004611efc565b610b07565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100c8565b6100fc610c24565b61014461017f366004611efc565b610c33565b610111610c8c565b606061019782610c96565b92915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000148061023057507fffffffff0000000000000000000000000000000000000000000000000000000082167f1f931c1c00000000000000000000000000000000000000000000000000000000145b8061027c57507fffffffff0000000000000000000000000000000000000000000000000000000082167f48e2b09300000000000000000000000000000000000000000000000000000000145b806102c857507fffffffff0000000000000000000000000000000000000000000000000000000082167f4e2312e000000000000000000000000000000000000000000000000000000000145b8061031457507fffffffff0000000000000000000000000000000000000000000000000000000082167f150b7a0200000000000000000000000000000000000000000000000000000000145b8061035f57507fffffffff0000000000000000000000000000000000000000000000000000000082167e23de2900000000000000000000000000000000000000000000000000000000145b806103ab57507fffffffff0000000000000000000000000000000000000000000000000000000082167f1626ba7e00000000000000000000000000000000000000000000000000000000145b806103f757507fffffffff0000000000000000000000000000000000000000000000000000000082167fa4c0ed3600000000000000000000000000000000000000000000000000000000145b806101975750507fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4922602052604090205460ff1690565b60606000610460610518565b80519091508067ffffffffffffffff81111561047e5761047e61205d565b6040519080825280602002602001820160405280156104a7578160200160208202803683370190505b50925060005b81811015610512578281815181106104c7576104c761208c565b6020026020010151600001518482815181106104e5576104e561208c565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526001016104ad565b50505090565b606060007f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f600490810154604080517f7a0ed627000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff90921692637a0ed6279282820192600092908290030181865afa1580156105ac573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526105f29190810190612157565b905060006105fe610e57565b805190915060608060005b838110156106b55760008582815181106106255761062561208c565b60200260200101516020015151905060005b818110156106ab5761069e85858986815181106106565761065661208c565b60200260200101516020015184815181106106735761067361208c565b60200260200101518a878151811061068d5761068d61208c565b60200260200101516000015161134a565b9095509350600101610637565b5050600101610609565b506000805b865181101561081b576000805b8883815181106106d9576106d961208c565b602002602001015160200151518110156107ff57600073ffffffffffffffffffffffffffffffffffffffff1661074687878c878151811061071c5761071c61208c565b60200260200101516020015185815181106107395761073961208c565b60200260200101516115f1565b73ffffffffffffffffffffffffffffffffffffffff16146107e9578883815181106107735761077361208c565b6020026020010151602001515160010361079c576107918984611637565b9850600193506107ff565b6107c38984815181106107b1576107b161208c565b6020026020010151602001518261182a565b8984815181106107d5576107d561208c565b602002602001015160200181905250600191505b816107f6576001016106c7565b600091506106c7565b508261081057816001019150610815565b600092505b506106ba565b5050600085518461082c9190612304565b90508067ffffffffffffffff8111156108475761084761205d565b60405190808252806020026020018201604052801561088d57816020015b6040805180820190915260008152606060208201528152602001906001900390816108655790505b5096506000805b82811015610a585785811015610a0c578681815181106108b6576108b661208c565b60200260200101518982815181106108d0576108d061208c565b60200260200101819052506000805b8951811015610a05578981815181106108fa576108fa61208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff168b848151811061092e5761092e61208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff16036109ef5761099989848151811061096a5761096a61208c565b6020026020010151602001518b83815181106109885761098861208c565b602002602001015160200151611a3d565b8b84815181106109ab576109ab61208c565b6020026020010151602001819052506109c48a82611637565b9950600191506109e18b60018d516109dc9190612317565b611637565b9a506109ec8561232a565b94505b816109fc576001016108df565b600091506108df565b5050610a50565b878281518110610a1e57610a1e61208c565b6020026020010151898281518110610a3857610a3861208c565b602002602001018190525081610a4d9061235f565b91505b600101610894565b505050505050505090565b60606000610a6f610518565b805190915060005b81811015610aff578473ffffffffffffffffffffffffffffffffffffffff16838281518110610aa857610aa861208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1603610af757828181518110610ae157610ae161208c565b6020026020010151602001519350505050919050565b600101610a77565b505050919050565b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602081905260409091205460601c9081610c1e576004818101546040517fcdffacc60000000000000000000000000000000000000000000000000000000081527fffffffff0000000000000000000000000000000000000000000000000000000086169281019290925273ffffffffffffffffffffffffffffffffffffffff169063cdffacc690602401602060405180830381865afa158015610bf7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c1b9190612397565b91505b50919050565b6060610c2e611b8b565b905090565b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604081205460601c610197565b6060610c2e610e57565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9060009061ffff1667ffffffffffffffff811115610cfc57610cfc61205d565b604051908082528060200260200182016040528015610d25578160200160208202803683370190505b5092506000805b600284015461ffff16821015610e4d576000818152600185016020526040812054905b6008811015610e385783610d628161235f565b600288015490955061ffff1685119050610e3857600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020889052604090205460601c73ffffffffffffffffffffffffffffffffffffffff8a16819003610e235781898881518110610de457610de461208c565b7fffffffff000000000000000000000000000000000000000000000000000000009092166020928302919091019091015286610e1f8161235f565b9750505b50508080610e309061235f565b915050610d4f565b50508080610e459061235f565b915050610d2c565b5050825250919050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff1667ffffffffffffffff811115610eba57610eba61205d565b604051908082528060200260200182016040528015610f0057816020015b604080518082019091526000815260606020820152815260200190600190039081610ed85790505b50600282015490925060009061ffff1667ffffffffffffffff811115610f2857610f2861205d565b604051908082528060200260200182016040528015610f51578160200160208202803683370190505b50905060008060005b600285015461ffff168210156112d7576000818152600186016020526040812054905b60088110156112c25783610f908161235f565b600289015490955061ffff16851190506112c257600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020899052604081205460601c90805b88811015611148578273ffffffffffffffffffffffffffffffffffffffff168c82815181106110155761101561208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff160361113657838c828151811061104f5761104f61208c565b6020026020010151602001518b838151811061106d5761106d61208c565b602002602001015161ffff16815181106110895761108961208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152505060ff8a82815181106110e9576110e961208c565b602002602001015161ffff16106110ff57600080fd5b8981815181106111115761111161208c565b602002602001018051809190611126906123b4565b61ffff1690525060019150611148565b806111408161235f565b915050610fe4565b508015611157575050506112b0565b818b898151811061116a5761116a61208c565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff909116905260028a015461ffff1667ffffffffffffffff8111156111b0576111b061205d565b6040519080825280602002602001820160405280156111d9578160200160208202803683370190505b508b89815181106111ec576111ec61208c565b602002602001015160200181905250828b898151811061120e5761120e61208c565b60200260200101516020015160008151811061122c5761122c61208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681525050600189898151811061128c5761128c61208c565b61ffff90921660209283029190910190910152876112a98161235f565b9850505050505b806112ba8161235f565b915050610f7d565b505080806112cf9061235f565b915050610f5a565b5060005b8281101561133f5760008482815181106112f7576112f761208c565b602002602001015161ffff16905060008783815181106113195761131961208c565b6020026020010151602001519050818152505080806113379061235f565b9150506112db565b508185525050505090565b60608060006113598786611da0565b8751909150808210156113b857848783815181106113795761137961208c565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250506115df565b60006113c5826001612304565b67ffffffffffffffff8111156113dd576113dd61205d565b604051908082528060200260200182016040528015611406578160200160208202803683370190505b5090506000885160016114199190612304565b67ffffffffffffffff8111156114315761143161205d565b60405190808252806020026020018201604052801561145a578160200160208202803683370190505b50905060005b83811015611539578a818151811061147a5761147a61208c565b60200260200101518382815181106114945761149461208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815250508981815181106114f2576114f261208c565b602002602001015182828151811061150c5761150c61208c565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101611460565b508782848151811061154d5761154d61208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152505086818a51815181106115ad576115ad61208c565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015290945092506115e8915050565b87879350935050505b94509492505050565b6000806115fe8584611da0565b905084518110611612576000915050611630565b8381815181106116245761162461208c565b60200260200101519150505b9392505050565b6060825182106116a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420696e6465780000000000000000000000000000000000000060448201526064015b60405180910390fd5b8251600003611713576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420617272617900000000000000000000000000000000000000604482015260640161169f565b6000600184516117239190612317565b67ffffffffffffffff81111561173b5761173b61205d565b60405190808252806020026020018201604052801561178157816020015b6040805180820190915260008152606060208201528152602001906001900390816117595790505b50805190915060005b8181101561182057848110156117d6578581815181106117ac576117ac61208c565b60200260200101518382815181106117c6576117c661208c565b6020026020010181905250611818565b856117e2826001612304565b815181106117f2576117f261208c565b602002602001015183828151811061180c5761180c61208c565b60200260200101819052505b60010161178a565b5090949350505050565b606082518210611896576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420696e64657800000000000000000000000000000000000000604482015260640161169f565b8251600003611901576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420617272617900000000000000000000000000000000000000604482015260640161169f565b6000600184516119119190612317565b67ffffffffffffffff8111156119295761192961205d565b604051908082528060200260200182016040528015611952578160200160208202803683370190505b50805190915060005b8181101561182057848110156119cd5785818151811061197d5761197d61208c565b60200260200101518382815181106119975761199761208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152611a35565b856119d9826001612304565b815181106119e9576119e961208c565b6020026020010151838281518110611a0357611a0361208c565b7fffffffff00000000000000000000000000000000000000000000000000000000909216602092830291909101909101525b60010161195b565b81518151606091906000611a518284612304565b67ffffffffffffffff811115611a6957611a6961205d565b604051908082528060200260200182016040528015611a92578160200160208202803683370190505b50905060005b83811015611b0557868181518110611ab257611ab261208c565b6020026020010151828281518110611acc57611acc61208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152600101611a98565b5060005b82811015611b8157858181518110611b2357611b2361208c565b6020026020010151828286611b389190612304565b81518110611b4857611b4861208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152600101611b09565b5095945050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff1667ffffffffffffffff811115611bee57611bee61205d565b604051908082528060200260200182016040528015611c17578160200160208202803683370190505b50915060008060005b600284015461ffff16821015611d98576000818152600185016020526040812054905b6008811015611d835783611c568161235f565b600288015490955061ffff1685119050611d8357600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020889052604081205460601c90805b88811015611d19578a8181518110611cc457611cc461208c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611d075760019150611d19565b80611d118161235f565b915050611caa565b508015611d2857505050611d71565b818a8981518110611d3b57611d3b61208c565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015287611d6a8161235f565b9850505050505b80611d7b8161235f565b915050611c43565b50508080611d909061235f565b915050611c20565b505082525090565b8151600090815b81811015611e1e57837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916858281518110611de157611de161208c565b60200260200101517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603611e165791506101979050565b600101611da7565b509392505050565b73ffffffffffffffffffffffffffffffffffffffff81168114611e4857600080fd5b50565b600060208284031215611e5d57600080fd5b813561163081611e26565b6020808252825182820181905260009190848201906040850190845b81811015611ec25783517fffffffff000000000000000000000000000000000000000000000000000000001683529284019291840191600101611e84565b50909695505050505050565b7fffffffff0000000000000000000000000000000000000000000000000000000081168114611e4857600080fd5b600060208284031215611f0e57600080fd5b813561163081611ece565b6020808252825182820181905260009190848201906040850190845b81811015611ec257835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101611f35565b60006020808301818452808551808352604092508286019150828160051b8701018488016000805b8481101561204e578984037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00186528251805173ffffffffffffffffffffffffffffffffffffffff168552880151888501889052805188860181905290890190839060608701905b808310156120395783517fffffffff00000000000000000000000000000000000000000000000000000000168252928b019260019290920191908b0190611ff7565b50978a01979550505091870191600101611f8f565b50919998505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6040805190810167ffffffffffffffff811182821017156120de576120de61205d565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561212b5761212b61205d565b604052919050565b600067ffffffffffffffff82111561214d5761214d61205d565b5060051b60200190565b6000602080838503121561216a57600080fd5b825167ffffffffffffffff8082111561218257600080fd5b818501915085601f83011261219657600080fd5b81516121a96121a482612133565b6120e4565b81815260059190911b830184019084810190888311156121c857600080fd5b8585015b838110156122c8578051858111156121e45760008081fd5b86016040818c037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00181131561221a5760008081fd5b6122226120bb565b8983015161222f81611e26565b815282820151888111156122435760008081fd5b8084019350508c603f8401126122595760008081fd5b898301516122696121a482612133565b81815260059190911b84018301908b8101908f8311156122895760008081fd5b948401945b828610156122b357855194506122a385611ece565b848252948c0194908c019061228e565b838d01525050855250509186019186016121cc565b5098975050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610197576101976122d5565b81810381811115610197576101976122d5565b600081612339576123396122d5565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612390576123906122d5565b5060010190565b6000602082840312156123a957600080fd5b815161163081611e26565b600061ffff8083168181036123cb576123cb6122d5565b600101939250505056fea26469706673582212205959d8d85aad6f29d5fc37d5a52c404c25392cec49195c3b761da0e863e99b0f64736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "DiamondLoupe contract compatible with EIP-2535", + "kind": "dev", + "methods": { + "facetAddress(bytes4)": { + "details": "If facet is not found return address(0).", + "params": { + "_functionSelector": "The function selector." + }, + "returns": { + "facetAddress_": "The facet address." + } + }, + "facetAddressFromStorage(bytes4)": { + "params": { + "_functionSelector": "Function selector to fetch the facet address from diamond storage" + }, + "returns": { + "facetAddress_": "Facet address mapped with the function selector" + } + }, + "facetAddresses()": { + "returns": { + "facetAddresses_": "facetAddresses_" + } + }, + "facetAddressesFromStorage()": { + "returns": { + "facetAddresses_": "All facet addresses attached directly to diamond storage" + } + }, + "facetFunctionSelectors(address)": { + "params": { + "_facet": "The facet address." + }, + "returns": { + "facetFunctionSelectors_": "facetFunctionSelectors_" + } + }, + "facetFunctionSelectorsFromStorage(address)": { + "params": { + "_facet": "Facet address to fetch the facet function selectors from diamond storage" + }, + "returns": { + "facetFunctionSelectors_": "Facet function selectors of the given facet address" + } + }, + "facets()": { + "details": "Barz uses a special architecture called default fallback handler. Default Fallback handler is used as a middleware that holds the mapping of facet function selector and facet address that Barz uses. This helps Barz to reduce significant amount of gas during the initialization process. Hence, this method aggregates both the facet information from DefaulFallbackHandler and in diamond storage and shows the data to users.", + "returns": { + "facets_": "Facet" + } + }, + "facetsFromStorage()": { + "returns": { + "facets_": "Facet information attached directly to diamond storage" + } + }, + "supportsInterface(bytes4)": { + "params": { + "_interfaceId": "Interface ID for detecting the interface" + }, + "returns": { + "isSupported": "Bool value showing if the standard is supported in the contract" + } + } + }, + "title": "DiamondLoupe Facet", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "facetAddress(bytes4)": { + "notice": "Gets the facet that supports the given selector." + }, + "facetAddressFromStorage(bytes4)": { + "notice": "Returns the facet address attached to the given function selector. This excludes the facets from the default fallback handler" + }, + "facetAddresses()": { + "notice": "Get all the facet addresses used by Barz." + }, + "facetAddressesFromStorage()": { + "notice": "Returns all facet addresses attached directly to diamond storage. This excludes the facets from the default fallback handler" + }, + "facetFunctionSelectors(address)": { + "notice": "Gets all the function selectors provided by a facet." + }, + "facetFunctionSelectorsFromStorage(address)": { + "notice": "Returns function selectors of given facet address attached directly to diamond storage. This excludes the facets from the default fallback handler" + }, + "facets()": { + "notice": "Gets all facets and their selectors." + }, + "facetsFromStorage()": { + "notice": "Returns the facet from the diamond storage. This excludes the facets from the default fallback handler" + }, + "supportsInterface(bytes4)": { + "notice": "SupportInterface to be compatible with EIP 165" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/bsc/Secp256r1VerificationFacet.json b/deployments/bsc/Secp256r1VerificationFacet.json new file mode 100644 index 0000000..8f7529b --- /dev/null +++ b/deployments/bsc/Secp256r1VerificationFacet.json @@ -0,0 +1,483 @@ +{ + "address": "0xeE1AF8E967eC04C84711842796A5E714D2FD33e6", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "LibAppStorage__AccountMustBeUninitialized", + "type": "error" + }, + { + "inputs": [], + "name": "LibAppStorage__SignerAlreadyUninitialized", + "type": "error" + }, + { + "inputs": [], + "name": "LibAppStorage__SignerMustBeUninitialized", + "type": "error" + }, + { + "inputs": [], + "name": "Secp256r1VerificationFacet__InvalidSignerLength", + "type": "error" + }, + { + "inputs": [], + "name": "VerificationFacet__InitializationFailure", + "type": "error" + }, + { + "inputs": [], + "name": "VerificationFacet__InvalidFacetMapping", + "type": "error" + }, + { + "inputs": [], + "name": "VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet", + "type": "error" + }, + { + "inputs": [], + "name": "VerificationFacet__ValidateOwnerSignatureSelectorNotSet", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "SignerInitialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "SignerUninitialized", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_publicKey", + "type": "bytes" + } + ], + "name": "initializeSigner", + "outputs": [ + { + "internalType": "uint256", + "name": "initSuccess", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_publicKey", + "type": "bytes" + } + ], + "name": "isValidKeyType", + "outputs": [ + { + "internalType": "bool", + "name": "isValid", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_hash", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "_signature", + "type": "bytes" + } + ], + "name": "isValidSignature", + "outputs": [ + { + "internalType": "bytes4", + "name": "magicValue", + "type": "bytes4" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "bytes", + "name": "signer", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "self", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "uninitializeSigner", + "outputs": [ + { + "internalType": "uint256", + "name": "uninitSuccess", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "initCode", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "callGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "verificationGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "preVerificationGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxFeePerGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPriorityFeePerGas", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "paymasterAndData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "internalType": "struct UserOperation", + "name": "userOp", + "type": "tuple" + }, + { + "internalType": "bytes32", + "name": "userOpHash", + "type": "bytes32" + } + ], + "name": "validateOwnerSignature", + "outputs": [ + { + "internalType": "uint256", + "name": "validationData", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "validateOwnerSignatureSelector", + "outputs": [ + { + "internalType": "bytes4", + "name": "ownerSignatureValidatorSelector", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "initCode", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "callGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "verificationGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "preVerificationGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxFeePerGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPriorityFeePerGas", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "paymasterAndData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "internalType": "struct UserOperation", + "name": "userOp", + "type": "tuple" + }, + { + "internalType": "bytes32", + "name": "userOpHash", + "type": "bytes32" + }, + { + "internalType": "uint256[2]", + "name": "q", + "type": "uint256[2]" + } + ], + "name": "validateSignature", + "outputs": [ + { + "internalType": "uint256", + "name": "isValid", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0x9cf67f894ed13d7faa40d8c3b326f3c74c0d39f82d48871ff96463694a1dac87", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 125, + "gasUsed": "1809225", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x64a3553dd28d81d599e520a6bc6f0888ee39db9e150816394c1802b97738998e", + "transactionHash": "0x9cf67f894ed13d7faa40d8c3b326f3c74c0d39f82d48871ff96463694a1dac87", + "logs": [], + "blockNumber": 33657814, + "cumulativeGasUsed": "16436410", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 4, + "solcInputHash": "4356503edd8ae34e73cb6dd1c8e2fc8a", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"LibAppStorage__AccountMustBeUninitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LibAppStorage__SignerAlreadyUninitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LibAppStorage__SignerMustBeUninitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Secp256r1VerificationFacet__InvalidSignerLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerificationFacet__InitializationFailure\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerificationFacet__InvalidFacetMapping\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerificationFacet__ValidateOwnerSignatureSelectorNotSet\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"SignerInitialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"SignerUninitialized\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_publicKey\",\"type\":\"bytes\"}],\"name\":\"initializeSigner\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"initSuccess\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_publicKey\",\"type\":\"bytes\"}],\"name\":\"isValidKeyType\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isValid\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_hash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"_signature\",\"type\":\"bytes\"}],\"name\":\"isValidSignature\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"magicValue\",\"type\":\"bytes4\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"signer\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"self\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"uninitializeSigner\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"uninitSuccess\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"userOp\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"}],\"name\":\"validateOwnerSignature\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"validationData\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"validateOwnerSignatureSelector\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"ownerSignatureValidatorSelector\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"userOp\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256[2]\",\"name\":\"q\",\"type\":\"uint256[2]\"}],\"name\":\"validateSignature\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"isValid\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Ruslan Serebriakov (@rsrbk)David Yongjun Kim (@Powerstream3604)\",\"details\":\"Primarily used to verify user ops signed with passkeys\",\"kind\":\"dev\",\"methods\":{\"initializeSigner(bytes)\":{\"details\":\"This method checks if the signer has already been initialized. If already initialized, it reverts. It checks if the public key is in the light format and initializes signer storage in k1 storage.\",\"params\":{\"_publicKey\":\"Bytes of owner public key\"},\"returns\":{\"initSuccess\":\"Uint value representing the success of init operation\"}},\"isValidKeyType(bytes)\":{\"details\":\"For this Secp256k1Verification Facet, the public key should in an uncompressed public key format\",\"params\":{\"_publicKey\":\"Bytes of public key for format check\"},\"returns\":{\"isValid\":\"Boolean variable representing if the format of public key is valid\"}},\"isValidSignature(bytes32,bytes)\":{\"details\":\"This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\",\"params\":{\"_hash\":\"Hash value the owner signed\",\"_signature\":\"Signature that signed the above hash\"},\"returns\":{\"magicValue\":\"Bytes4 value representing the success/failure of validation\"}},\"owner()\":{\"returns\":{\"signer\":\"Bytes of owner address\"}},\"uninitializeSigner()\":{\"details\":\"This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\",\"returns\":{\"uninitSuccess\":\"Uint value representing the success of uninit operation\"}},\"validateOwnerSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32)\":{\"details\":\"This method validates if the user operation is signed by the owner. It internally calls validateSignature with signer public key.\",\"params\":{\"userOp\":\"UserOperation including all information for execution\",\"userOpHash\":\"Hash of UserOperation given from EntryPoint. This hash is used for signature validation\"},\"returns\":{\"validationData\":\"Uint value representing whether the validation is successful. 0 for success, 1 for failure\"}},\"validateOwnerSignatureSelector()\":{\"returns\":{\"ownerSignatureValidatorSelector\":\"Bytes4 selector of function signature to validate account owner's UserOperation signature\"}},\"validateSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256[2])\":{\"details\":\"This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\",\"params\":{\"q\":\"Public Key of signer who signed the contract, to be validated\",\"userOp\":\"UserOperation including all information for execution\",\"userOpHash\":\"Hash of UserOperation given from EntryPoint. This hash is used for signature validation\"},\"returns\":{\"isValid\":\"Uint value representing whether the validation is successful. 0 for success, 1 for failure\"}}},\"title\":\"Secp256r1 verification facet\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"This constructor ensures that this contract can only be used as singleton for Proxy contracts\"},\"initializeSigner(bytes)\":{\"notice\":\"Initializes the signer in R1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\"},\"isValidKeyType(bytes)\":{\"notice\":\"Validates if the format of public key is valid for this verification facet\"},\"isValidSignature(bytes32,bytes)\":{\"notice\":\"Validates if the signature is valid. Function to be compatible with EIP-1271\"},\"owner()\":{\"notice\":\"Returns the owner of the account\"},\"uninitializeSigner()\":{\"notice\":\"Uninitialize signer in R1 Facet Storage. This can only be called when the account is undergoing signature migration and has already been initialized.\"},\"validateOwnerSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32)\":{\"notice\":\"Validates if the user operation is signed by the owner.\"},\"validateOwnerSignatureSelector()\":{\"notice\":\"Returns the selector of function to validate the signature of UserOperation\"},\"validateSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256[2])\":{\"notice\":\"Validates if the signature of UserOperation is signed by the given signer\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/verification/secp256r1/Secp256r1VerificationFacet.sol\":\"Secp256r1VerificationFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/utils/math/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\\n * checks.\\n *\\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\\n * easily result in undesired exploitation or bugs, since developers usually\\n * assume that overflows raise errors. `SafeCast` restores this intuition by\\n * reverting the transaction when such an operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n *\\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\\n * all math on `uint256` and `int256` and then downcasting.\\n */\\nlibrary SafeCast {\\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 * _Available since v4.7._\\n */\\n function toUint248(uint256 value) internal pure returns (uint248) {\\n require(value <= type(uint248).max, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint240(uint256 value) internal pure returns (uint240) {\\n require(value <= type(uint240).max, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint232(uint256 value) internal pure returns (uint232) {\\n require(value <= type(uint232).max, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint224(uint256 value) internal pure returns (uint224) {\\n require(value <= type(uint224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint216(uint256 value) internal pure returns (uint216) {\\n require(value <= type(uint216).max, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint208(uint256 value) internal pure returns (uint208) {\\n require(value <= type(uint208).max, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint200(uint256 value) internal pure returns (uint200) {\\n require(value <= type(uint200).max, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint192(uint256 value) internal pure returns (uint192) {\\n require(value <= type(uint192).max, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint184(uint256 value) internal pure returns (uint184) {\\n require(value <= type(uint184).max, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint176(uint256 value) internal pure returns (uint176) {\\n require(value <= type(uint176).max, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint168(uint256 value) internal pure returns (uint168) {\\n require(value <= type(uint168).max, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint160(uint256 value) internal pure returns (uint160) {\\n require(value <= type(uint160).max, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint152(uint256 value) internal pure returns (uint152) {\\n require(value <= type(uint152).max, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint144(uint256 value) internal pure returns (uint144) {\\n require(value <= type(uint144).max, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint136(uint256 value) internal pure returns (uint136) {\\n require(value <= type(uint136).max, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint128(uint256 value) internal pure returns (uint128) {\\n require(value <= type(uint128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint120(uint256 value) internal pure returns (uint120) {\\n require(value <= type(uint120).max, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint112(uint256 value) internal pure returns (uint112) {\\n require(value <= type(uint112).max, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint104(uint256 value) internal pure returns (uint104) {\\n require(value <= type(uint104).max, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint96(uint256 value) internal pure returns (uint96) {\\n require(value <= type(uint96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint88(uint256 value) internal pure returns (uint88) {\\n require(value <= type(uint88).max, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint80(uint256 value) internal pure returns (uint80) {\\n require(value <= type(uint80).max, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint72(uint256 value) internal pure returns (uint72) {\\n require(value <= type(uint72).max, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint64(uint256 value) internal pure returns (uint64) {\\n require(value <= type(uint64).max, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint56(uint256 value) internal pure returns (uint56) {\\n require(value <= type(uint56).max, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint48(uint256 value) internal pure returns (uint48) {\\n require(value <= type(uint48).max, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint40(uint256 value) internal pure returns (uint40) {\\n require(value <= type(uint40).max, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint32(uint256 value) internal pure returns (uint32) {\\n require(value <= type(uint32).max, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint24(uint256 value) internal pure returns (uint24) {\\n require(value <= type(uint24).max, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint16(uint256 value) internal pure returns (uint16) {\\n require(value <= type(uint16).max, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint8(uint256 value) internal pure returns (uint8) {\\n require(value <= type(uint8).max, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\n */\\n function toUint256(int256 value) internal pure returns (uint256) {\\n require(value >= 0, \\\"SafeCast: value must be positive\\\");\\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 * _Available since v4.7._\\n */\\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\\n downcasted = int248(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\\n downcasted = int240(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\\n downcasted = int232(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\\n downcasted = int224(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\\n downcasted = int216(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\\n downcasted = int208(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\\n downcasted = int200(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\\n downcasted = int192(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\\n downcasted = int184(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\\n downcasted = int176(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\\n downcasted = int168(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\\n downcasted = int160(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\\n downcasted = int152(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\\n downcasted = int144(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\\n downcasted = int136(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\\n downcasted = int128(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\\n downcasted = int120(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\\n downcasted = int112(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\\n downcasted = int104(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\\n downcasted = int96(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\\n downcasted = int88(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\\n downcasted = int80(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\\n downcasted = int72(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\\n downcasted = int64(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\\n downcasted = int56(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\\n downcasted = int48(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\\n downcasted = int40(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\\n downcasted = int32(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\\n downcasted = int24(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\\n downcasted = int16(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\\n downcasted = int8(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\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 require(value <= uint256(type(int256).max), \\\"SafeCast: value doesn't fit in an int256\\\");\\n return int256(value);\\n }\\n}\\n\",\"keccak256\":\"0x52a8cfb0f5239d11b457dcdd1b326992ef672714ca8da71a157255bddd13f3ad\",\"license\":\"MIT\"},\"contracts/aa-4337/core/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable no-inline-assembly */\\n\\n/**\\n * returned data from validateUserOp.\\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\\n * @param aggregator - address(0) - the account validated the signature by itself.\\n * address(1) - the account failed to validate the signature.\\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\\n * @param validAfter - this UserOp is valid only after this timestamp.\\n * @param validaUntil - this UserOp is valid only up to this timestamp.\\n */\\nstruct ValidationData {\\n address aggregator;\\n uint48 validAfter;\\n uint48 validUntil;\\n}\\n\\n//extract sigFailed, validAfter, validUntil.\\n// also convert zero validUntil to type(uint48).max\\nfunction _parseValidationData(\\n uint validationData\\n) pure returns (ValidationData memory data) {\\n address aggregator = address(uint160(validationData));\\n uint48 validUntil = uint48(validationData >> 160);\\n if (validUntil == 0) {\\n validUntil = type(uint48).max;\\n }\\n uint48 validAfter = uint48(validationData >> (48 + 160));\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n// intersect account and paymaster ranges.\\nfunction _intersectTimeRange(\\n uint256 validationData,\\n uint256 paymasterValidationData\\n) pure returns (ValidationData memory) {\\n ValidationData memory accountValidationData = _parseValidationData(\\n validationData\\n );\\n ValidationData memory pmValidationData = _parseValidationData(\\n paymasterValidationData\\n );\\n address aggregator = accountValidationData.aggregator;\\n if (aggregator == address(0)) {\\n aggregator = pmValidationData.aggregator;\\n }\\n uint48 validAfter = accountValidationData.validAfter;\\n uint48 validUntil = accountValidationData.validUntil;\\n uint48 pmValidAfter = pmValidationData.validAfter;\\n uint48 pmValidUntil = pmValidationData.validUntil;\\n\\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp\\n * @param data - the ValidationData to pack\\n */\\nfunction _packValidationData(\\n ValidationData memory data\\n) pure returns (uint256) {\\n return\\n uint160(data.aggregator) |\\n (uint256(data.validUntil) << 160) |\\n (uint256(data.validAfter) << (160 + 48));\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp, when not using an aggregator\\n * @param sigFailed - true for signature failure, false for success\\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\\n * @param validAfter first timestamp this UserOperation is valid\\n */\\nfunction _packValidationData(\\n bool sigFailed,\\n uint48 validUntil,\\n uint48 validAfter\\n) pure returns (uint256) {\\n return\\n (sigFailed ? 1 : 0) |\\n (uint256(validUntil) << 160) |\\n (uint256(validAfter) << (160 + 48));\\n}\\n\\n/**\\n * keccak function over calldata.\\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\\n */\\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\\n assembly {\\n let mem := mload(0x40)\\n let len := data.length\\n calldatacopy(mem, data.offset, len)\\n ret := keccak256(mem, len)\\n }\\n}\\n\",\"keccak256\":\"0xa79f06cd158ecb8c0da95493a2f348933b8627a63e228b99738bff3aa107942d\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAggregator.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\n/**\\n * Aggregated Signatures validator.\\n */\\ninterface IAggregator {\\n /**\\n * validate aggregated signature.\\n * revert if the aggregated signature does not match the given list of operations.\\n */\\n function validateSignatures(\\n UserOperation[] calldata userOps,\\n bytes calldata signature\\n ) external view;\\n\\n /**\\n * validate signature of a single userOp\\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\\n * @param userOp the userOperation received from the user.\\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\\n * (usually empty, unless account and aggregator support some kind of \\\"multisig\\\"\\n */\\n function validateUserOpSignature(\\n UserOperation calldata userOp\\n ) external view returns (bytes memory sigForUserOp);\\n\\n /**\\n * aggregate multiple signatures into a single value.\\n * This method is called off-chain to calculate the signature to pass with handleOps()\\n * bundler MAY use optimized custom code perform this aggregation\\n * @param userOps array of UserOperations to collect the signatures from.\\n * @return aggregatedSignature the aggregated signature\\n */\\n function aggregateSignatures(\\n UserOperation[] calldata userOps\\n ) external view returns (bytes memory aggregatedSignature);\\n}\\n\",\"keccak256\":\"0xdfdcd80568f037716674619b31be630fcd8316262f05a815b41d1e81782c966a\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IEntryPoint.sol\":{\"content\":\"/**\\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\\n ** Only one instance required on each chain.\\n **/\\n// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-inline-assembly */\\n/* solhint-disable reason-string */\\n\\nimport \\\"./UserOperation.sol\\\";\\nimport \\\"./IStakeManager.sol\\\";\\nimport \\\"./IAggregator.sol\\\";\\nimport \\\"./INonceManager.sol\\\";\\n\\ninterface IEntryPoint is IStakeManager, INonceManager {\\n /***\\n * An event emitted after each successful request\\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\\n * @param sender - the account that generates this request.\\n * @param paymaster - if non-null, the paymaster that pays for this request.\\n * @param nonce - the nonce value from the request.\\n * @param success - true if the sender transaction succeeded, false if reverted.\\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\\n */\\n event UserOperationEvent(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address indexed paymaster,\\n uint256 nonce,\\n bool success,\\n uint256 actualGasCost,\\n uint256 actualGasUsed\\n );\\n\\n /**\\n * account \\\"sender\\\" was deployed.\\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\\n * @param sender the account that is deployed\\n * @param factory the factory used to deploy this account (in the initCode)\\n * @param paymaster the paymaster used by this UserOp\\n */\\n event AccountDeployed(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address factory,\\n address paymaster\\n );\\n\\n /**\\n * An event emitted if the UserOperation \\\"callData\\\" reverted with non-zero length\\n * @param userOpHash the request unique identifier.\\n * @param sender the sender of this request\\n * @param nonce the nonce used in the request\\n * @param revertReason - the return bytes from the (reverted) call to \\\"callData\\\".\\n */\\n event UserOperationRevertReason(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n uint256 nonce,\\n bytes revertReason\\n );\\n\\n /**\\n * an event emitted by handleOps(), before starting the execution loop.\\n * any event emitted before this event, is part of the validation.\\n */\\n event BeforeExecution();\\n\\n /**\\n * signature aggregator used by the following UserOperationEvents within this bundle.\\n */\\n event SignatureAggregatorChanged(address indexed aggregator);\\n\\n /**\\n * a custom revert error of handleOps, to identify the offending op.\\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\\n * @param reason - revert reason\\n * The string starts with a unique code \\\"AAmn\\\", where \\\"m\\\" is \\\"1\\\" for factory, \\\"2\\\" for account and \\\"3\\\" for paymaster issues,\\n * so a failure can be attributed to the correct entity.\\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\\n */\\n error FailedOp(uint256 opIndex, string reason);\\n\\n /**\\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\\n */\\n error SignatureValidationFailed(address aggregator);\\n\\n /**\\n * Successful result from simulateValidation.\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n */\\n error ValidationResult(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo\\n );\\n\\n /**\\n * Successful result from simulateValidation, if the account returns a signature aggregator\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\\n * bundler MUST use it to verify the signature, or reject the UserOperation\\n */\\n error ValidationResultWithAggregation(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo,\\n AggregatorStakeInfo aggregatorInfo\\n );\\n\\n /**\\n * return value of getSenderAddress\\n */\\n error SenderAddressResult(address sender);\\n\\n /**\\n * return value of simulateHandleOp\\n */\\n error ExecutionResult(\\n uint256 preOpGas,\\n uint256 paid,\\n uint48 validAfter,\\n uint48 validUntil,\\n bool targetSuccess,\\n bytes targetResult\\n );\\n\\n //UserOps handled, per aggregator\\n struct UserOpsPerAggregator {\\n UserOperation[] userOps;\\n // aggregator address\\n IAggregator aggregator;\\n // aggregated signature\\n bytes signature;\\n }\\n\\n /**\\n * Execute a batch of UserOperation.\\n * no signature aggregator is used.\\n * if any account requires an aggregator (that is, it returned an aggregator when\\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\\n * @param ops the operations to execute\\n * @param beneficiary the address to receive the fees\\n */\\n function handleOps(\\n UserOperation[] calldata ops,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * Execute a batch of UserOperation with Aggregators\\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\\n * @param beneficiary the address to receive the fees\\n */\\n function handleAggregatedOps(\\n UserOpsPerAggregator[] calldata opsPerAggregator,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * generate a request Id - unique identifier for this request.\\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\\n */\\n function getUserOpHash(\\n UserOperation calldata userOp\\n ) external view returns (bytes32);\\n\\n /**\\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\\n * @param userOp the user operation to validate.\\n */\\n function simulateValidation(UserOperation calldata userOp) external;\\n\\n /**\\n * gas and return values during simulation\\n * @param preOpGas the gas used for validation (including preValidationGas)\\n * @param prefund the required prefund for this operation\\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\\n */\\n struct ReturnInfo {\\n uint256 preOpGas;\\n uint256 prefund;\\n bool sigFailed;\\n uint48 validAfter;\\n uint48 validUntil;\\n bytes paymasterContext;\\n }\\n\\n /**\\n * returned aggregated signature info.\\n * the aggregator returned by the account, and its current stake.\\n */\\n struct AggregatorStakeInfo {\\n address aggregator;\\n StakeInfo stakeInfo;\\n }\\n\\n /**\\n * Get counterfactual sender address.\\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\\n * this method always revert, and returns the address in SenderAddressResult error\\n * @param initCode the constructor code to be passed into the UserOperation.\\n */\\n function getSenderAddress(bytes memory initCode) external;\\n\\n /**\\n * simulate full execution of a UserOperation (including both validation and target execution)\\n * this method will always revert with \\\"ExecutionResult\\\".\\n * it performs full validation of the UserOperation, but ignores signature error.\\n * an optional target address is called after the userop succeeds, and its value is returned\\n * (before the entire call is reverted)\\n * Note that in order to collect the the success/failure of the target call, it must be executed\\n * with trace enabled to track the emitted events.\\n * @param op the UserOperation to simulate\\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\\n * are set to the return from that call.\\n * @param targetCallData callData to pass to target address\\n */\\n function simulateHandleOp(\\n UserOperation calldata op,\\n address target,\\n bytes calldata targetCallData\\n ) external;\\n}\\n\",\"keccak256\":\"0x9ccb1b188eda8bbf5f6c2d01bd83c3d8b2b04fcf745283051d31fe96d1d8e40f\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/INonceManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\ninterface INonceManager {\\n /**\\n * Return the next nonce for this sender.\\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\\n * But UserOp with different keys can come with arbitrary order.\\n *\\n * @param sender the account address\\n * @param key the high 192 bit of the nonce\\n * @return nonce a full nonce to pass for next UserOp with this sender.\\n */\\n function getNonce(\\n address sender,\\n uint192 key\\n ) external view returns (uint256 nonce);\\n\\n /**\\n * Manually increment the nonce of the sender.\\n * This method is exposed just for completeness..\\n * Account does NOT need to call it, neither during validation, nor elsewhere,\\n * as the EntryPoint will update the nonce regardless.\\n * Possible use-case is call it with various keys to \\\"initialize\\\" their nonces to one, so that future\\n * UserOperations will not pay extra for the first transaction with a given key.\\n */\\n function incrementNonce(uint192 key) external;\\n}\\n\",\"keccak256\":\"0xce478ad0fa0d18a3b785ac854623029e7ab463d05873dfaa365abfa1bf100912\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IStakeManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8.12;\\n\\n/**\\n * manage deposits and stakes.\\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\\n * stake is value locked for at least \\\"unstakeDelay\\\" by the staked entity.\\n */\\ninterface IStakeManager {\\n event Deposited(address indexed account, uint256 totalDeposit);\\n\\n event Withdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /// Emitted when stake or unstake delay are modified\\n event StakeLocked(\\n address indexed account,\\n uint256 totalStaked,\\n uint256 unstakeDelaySec\\n );\\n\\n /// Emitted once a stake is scheduled for withdrawal\\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\\n\\n event StakeWithdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /**\\n * @param deposit the entity's deposit\\n * @param staked true if this entity is staked.\\n * @param stake actual amount of ether staked for this entity.\\n * @param unstakeDelaySec minimum delay to withdraw the stake.\\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\\n * and the rest fit into a 2nd cell.\\n * 112 bit allows for 10^15 eth\\n * 48 bit for full timestamp\\n * 32 bit allows 150 years for unstake delay\\n */\\n struct DepositInfo {\\n uint112 deposit;\\n bool staked;\\n uint112 stake;\\n uint32 unstakeDelaySec;\\n uint48 withdrawTime;\\n }\\n\\n //API struct used by getStakeInfo and simulateValidation\\n struct StakeInfo {\\n uint256 stake;\\n uint256 unstakeDelaySec;\\n }\\n\\n /// @return info - full deposit information of given account\\n function getDepositInfo(\\n address account\\n ) external view returns (DepositInfo memory info);\\n\\n /// @return the deposit (for gas payment) of the account\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * add to the deposit of the given account\\n */\\n function depositTo(address account) external payable;\\n\\n /**\\n * add to the account's stake - amount and delay\\n * any pending unstake is first cancelled.\\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\\n */\\n function addStake(uint32 _unstakeDelaySec) external payable;\\n\\n /**\\n * attempt to unlock the stake.\\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\\n */\\n function unlockStake() external;\\n\\n /**\\n * withdraw from the (unlocked) stake.\\n * must first call unlockStake and wait for the unstakeDelay to pass\\n * @param withdrawAddress the address to send withdrawn value.\\n */\\n function withdrawStake(address payable withdrawAddress) external;\\n\\n /**\\n * withdraw from the deposit.\\n * @param withdrawAddress the address to send withdrawn value.\\n * @param withdrawAmount the amount to withdraw.\\n */\\n function withdrawTo(\\n address payable withdrawAddress,\\n uint256 withdrawAmount\\n ) external;\\n}\\n\",\"keccak256\":\"0xadcea606c9b7aafe6645441f2154a60f271330b0eee5292a632aa71c1672d546\",\"license\":\"GPL-3.0-only\"},\"contracts/aa-4337/interfaces/UserOperation.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable no-inline-assembly */\\n\\nimport {calldataKeccak} from \\\"../core/Helpers.sol\\\";\\n\\n/**\\n * User Operation struct\\n * @param sender the sender account of this request.\\n * @param nonce unique value the sender uses to verify it is not a replay.\\n * @param initCode if set, the account contract will be created by this constructor/\\n * @param callData the method call to execute on this account.\\n * @param callGasLimit the gas limit passed to the callData method call.\\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\\n * @param maxFeePerGas same as EIP-1559 gas parameter.\\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\\n */\\nstruct UserOperation {\\n address sender;\\n uint256 nonce;\\n bytes initCode;\\n bytes callData;\\n uint256 callGasLimit;\\n uint256 verificationGasLimit;\\n uint256 preVerificationGas;\\n uint256 maxFeePerGas;\\n uint256 maxPriorityFeePerGas;\\n bytes paymasterAndData;\\n bytes signature;\\n}\\n\\n/**\\n * Utility functions helpful when working with UserOperation structs.\\n */\\nlibrary UserOperationLib {\\n function getSender(\\n UserOperation calldata userOp\\n ) internal pure returns (address) {\\n address data;\\n //read sender from userOp, which is first userOp member (saves 800 gas...)\\n assembly {\\n data := calldataload(userOp)\\n }\\n return address(uint160(data));\\n }\\n\\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\\n // pay above what he signed for.\\n function gasPrice(\\n UserOperation calldata userOp\\n ) internal view returns (uint256) {\\n unchecked {\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n if (maxFeePerGas == maxPriorityFeePerGas) {\\n //legacy mode (for networks that don't support basefee opcode)\\n return maxFeePerGas;\\n }\\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\\n }\\n }\\n\\n function pack(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes memory ret) {\\n address sender = getSender(userOp);\\n uint256 nonce = userOp.nonce;\\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\\n bytes32 hashCallData = calldataKeccak(userOp.callData);\\n uint256 callGasLimit = userOp.callGasLimit;\\n uint256 verificationGasLimit = userOp.verificationGasLimit;\\n uint256 preVerificationGas = userOp.preVerificationGas;\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\\n\\n return\\n abi.encode(\\n sender,\\n nonce,\\n hashInitCode,\\n hashCallData,\\n callGasLimit,\\n verificationGasLimit,\\n preVerificationGas,\\n maxFeePerGas,\\n maxPriorityFeePerGas,\\n hashPaymasterAndData\\n );\\n }\\n\\n function hash(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes32) {\\n return keccak256(pack(userOp));\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n}\\n\",\"keccak256\":\"0x2429f5cc546bdee08c7e63858d0dda8491eaa3ab5194df884dc948c1154d2834\",\"license\":\"GPL-3.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/facets/interfaces/IVerificationFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {UserOperation} from \\\"../../aa-4337/interfaces/UserOperation.sol\\\";\\n\\n/**\\n * @title Verification Facet Interface\\n * @dev Implements logic for user ops signature verification\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\ninterface IVerificationFacet {\\n event SignerInitialized(bytes);\\n event SignerUninitialized();\\n\\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\\n error VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\\n error VerificationFacet__InitializationFailure();\\n error VerificationFacet__InvalidFacetMapping();\\n\\n function initializeSigner(bytes memory) external returns (uint256);\\n\\n function uninitializeSigner() external returns (uint256);\\n\\n function validateOwnerSignatureSelector() external view returns (bytes4);\\n\\n function owner() external view returns (bytes memory);\\n\\n function isValidKeyType(bytes calldata) external view returns (bool);\\n\\n function validateOwnerSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x72bc370a1d1b5a6d6bde67f5026733fd8f6ba434bb90e73b0bd8627fb1579928\",\"license\":\"Apache-2.0\"},\"contracts/facets/verification/secp256r1/Secp256r1VerificationFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {UserOperation} from \\\"../../../aa-4337/interfaces/UserOperation.sol\\\";\\nimport {LibAppStorage} from \\\"../../../libraries/LibAppStorage.sol\\\";\\nimport {LibLoupe} from \\\"../../../libraries/LibLoupe.sol\\\";\\nimport {LibFacetStorage, Secp256r1VerificationStorage} from \\\"../../../libraries/LibFacetStorage.sol\\\";\\nimport {Base64} from \\\"./utils/Base64.sol\\\";\\nimport {LibSecp256r1} from \\\"./utils/LibSecp256r1.sol\\\";\\nimport {IERC1271} from \\\"../../../interfaces/ERC/IERC1271.sol\\\";\\nimport {IVerificationFacet} from \\\"../../interfaces/IVerificationFacet.sol\\\";\\n\\n/**\\n * @title Secp256r1 verification facet\\n * @dev Primarily used to verify user ops signed with passkeys\\n * @author Ruslan Serebriakov (@rsrbk)\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract Secp256r1VerificationFacet is IVerificationFacet, IERC1271 {\\n error Secp256r1VerificationFacet__InvalidSignerLength();\\n address public immutable self;\\n\\n /**\\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\\n */\\n constructor() {\\n LibAppStorage.enforceSignerInitialize();\\n self = address(this);\\n }\\n\\n /**\\n * @notice Initializes the signer in R1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\\n * @param _publicKey Bytes of owner public key\\n * @return initSuccess Uint value representing the success of init operation\\n */\\n function initializeSigner(\\n bytes calldata _publicKey\\n ) public override returns (uint256 initSuccess) {\\n LibAppStorage.enforceSignerInitialize();\\n\\n if (!isValidKeyType(_publicKey))\\n revert Secp256r1VerificationFacet__InvalidSignerLength();\\n\\n bytes memory publicKeyCoordinates = _publicKey[1:];\\n uint256[2] memory q;\\n assembly {\\n // Copy the bytes from the input data into the uint256 array\\n mstore(q, mload(add(publicKeyCoordinates, 32)))\\n mstore(add(q, 32), mload(add(publicKeyCoordinates, 64)))\\n }\\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\\n .r1Storage();\\n r1Storage.q = q;\\n\\n bytes4 validateSelector = validateOwnerSignatureSelector();\\n\\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\\n if (LibLoupe.facetAddress(validateSelector) != self)\\n revert VerificationFacet__InvalidFacetMapping();\\n\\n // initialize verification function selector\\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\\n\\n initSuccess = 1;\\n\\n emit SignerInitialized(_publicKey);\\n }\\n\\n /**\\n * @notice Uninitialize signer in R1 Facet Storage. This can only be called when the account is undergoing signature migration\\n * and has already been initialized.\\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\\n * @return uninitSuccess Uint value representing the success of uninit operation\\n */\\n function uninitializeSigner()\\n external\\n override\\n returns (uint256 uninitSuccess)\\n {\\n LibAppStorage.enforceSignerMigration();\\n LibAppStorage.setSignerUninitialized();\\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\\n .r1Storage();\\n r1Storage.q = [0, 0];\\n\\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\\n\\n uninitSuccess = 1;\\n\\n emit SignerUninitialized();\\n }\\n\\n /**\\n * @notice Validates if the user operation is signed by the owner.\\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\\n * signer public key.\\n * @param userOp UserOperation including all information for execution\\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\\n */\\n function validateOwnerSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) public view override returns (uint256 validationData) {\\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\\n .r1Storage();\\n validationData = validateSignature(userOp, userOpHash, r1Storage.q);\\n }\\n\\n /**\\n * @notice Validates if the signature of UserOperation is signed by the given signer\\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\\n * @param userOp UserOperation including all information for execution\\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\\n * @param q Public Key of signer who signed the contract, to be validated\\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\\n */\\n function validateSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n uint256[2] memory q\\n ) public view returns (uint256 isValid) {\\n isValid = (_validateSignature(q, userOpHash, userOp.signature)) ? 0 : 1;\\n }\\n\\n /**\\n * @notice Returns the selector of function to validate the signature of UserOperation\\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\\n */\\n function validateOwnerSignatureSelector()\\n public\\n pure\\n override\\n returns (bytes4 ownerSignatureValidatorSelector)\\n {\\n return this.validateOwnerSignature.selector; // validateOwnerSignature(UserOperation calldata userOp,bytes32 userOpHash)\\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\\n }\\n\\n /**\\n * @notice Returns the owner of the account\\n * @return signer Bytes of owner address\\n */\\n function owner() public view override returns (bytes memory signer) {\\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\\n .r1Storage();\\n signer = abi.encodePacked(r1Storage.q);\\n }\\n\\n /**\\n * @notice Validates if the format of public key is valid for this verification facet\\n * @dev For this Secp256k1Verification Facet, the public key should in an uncompressed public key format\\n * @param _publicKey Bytes of public key for format check\\n * @return isValid Boolean variable representing if the format of public key is valid\\n */\\n function isValidKeyType(\\n bytes memory _publicKey\\n ) public pure override returns (bool isValid) {\\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\\n }\\n\\n /**\\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\\n * @param _hash Hash value the owner signed\\n * @param _signature Signature that signed the above hash\\n * @return magicValue Bytes4 value representing the success/failure of validation\\n */\\n function isValidSignature(\\n bytes32 _hash,\\n bytes memory _signature\\n ) public view override returns (bytes4 magicValue) {\\n magicValue = _validateSignature(\\n LibFacetStorage.r1Storage().q,\\n _hash,\\n _signature\\n )\\n ? this.isValidSignature.selector\\n : bytes4(0xffffffff);\\n }\\n\\n function _validateSignature(\\n uint256[2] memory q,\\n bytes32 _hash,\\n bytes memory _signature\\n ) internal view returns (bool) {\\n (\\n uint256 rValue,\\n uint256 sValue,\\n bytes memory authenticatorData,\\n string memory clientDataJSONPre,\\n string memory clientDataJSONPost\\n ) = abi.decode(_signature, (uint256, uint256, bytes, string, string));\\n bytes32 clientHash;\\n {\\n string memory opHashBase64 = Base64.encode(bytes.concat(_hash));\\n string memory clientDataJSON = string.concat(\\n clientDataJSONPre,\\n opHashBase64,\\n clientDataJSONPost\\n );\\n clientHash = sha256(bytes(clientDataJSON));\\n }\\n bytes32 sigHash = sha256(bytes.concat(authenticatorData, clientHash));\\n return LibSecp256r1.Verify(q, rValue, sValue, uint256(sigHash));\\n }\\n}\\n\",\"keccak256\":\"0xdb3bae77323eef4e16ef5a5342f548527c9e82b44e8e9dab90906dc2c00082ff\",\"license\":\"Apache-2.0\"},\"contracts/facets/verification/secp256r1/utils/Base64.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @dev Provides a set of functions to operate with Base64 strings.\\n * modified for base64url https://datatracker.ietf.org/doc/html/rfc4648#section-5\\n * _Available since v4.5._\\n */\\nlibrary Base64 {\\n /**\\n * @dev Base64 Encoding/Decoding Table\\n */\\n string internal constant _TABLE =\\n \\\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_\\\";\\n\\n /**\\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\\n */\\n function encode(bytes memory data) internal pure returns (string memory) {\\n /**\\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\\n */\\n if (data.length == 0) return \\\"\\\";\\n\\n // Loads the table into memory\\n string memory table = _TABLE;\\n\\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\\n // and split into 4 numbers of 6 bits.\\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\\n // - `data.length + 2` -> Round up\\n // - `/ 3` -> Number of 3-bytes chunks\\n // - `4 *` -> 4 characters for each chunk\\n uint256 newlength = (data.length * 8) / 6;\\n if (data.length % 6 > 0) {\\n newlength++;\\n }\\n string memory result = new string(newlength);\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n // Prepare the lookup table (skip the first \\\"length\\\" byte)\\n let tablePtr := add(table, 1)\\n\\n // Prepare result pointer, jump over length\\n let resultPtr := add(result, 32)\\n\\n // Run over the input, 3 bytes at a time\\n for {\\n let dataPtr := data\\n let endPtr := add(data, mload(data))\\n } lt(dataPtr, endPtr) {\\n\\n } {\\n // Advance 3 bytes\\n dataPtr := add(dataPtr, 3)\\n let input := mload(dataPtr)\\n\\n // To write each character, shift the 3 bytes (18 bits) chunk\\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\\n // and apply logical AND with 0x3F which is the number of\\n // the previous character in the ASCII table prior to the Base64 Table\\n // The result is then added to the table to get the character to write,\\n // and finally write it in the result pointer but with a left shift\\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\\n\\n mstore8(\\n resultPtr,\\n mload(add(tablePtr, and(shr(18, input), 0x3F)))\\n )\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(\\n resultPtr,\\n mload(add(tablePtr, and(shr(12, input), 0x3F)))\\n )\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(\\n resultPtr,\\n mload(add(tablePtr, and(shr(6, input), 0x3F)))\\n )\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n }\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0xbf0afa21e5a128f260c1a8d4333dc0b0e8755a50d37dfa9b5d362d36ef9cdc14\",\"license\":\"Apache-2.0\"},\"contracts/facets/verification/secp256r1/utils/LibSecp256r1.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n// Heavily inspired from\\n// https://github.com/maxrobot/elliptic-solidity/blob/master/contracts/Secp256r1.sol\\n// https://github.com/tdrerup/elliptic-curve-solidity/blob/master/contracts/curves/EllipticCurve.sol\\n// modified to use precompile 0x05 modexp\\n// and modified jacobian double\\n// optimisations to avoid to an from from affine and jacobian coordinates\\n\\n// Additional Elliptic curve Public key / Signature validation added by\\n// David Yonjun Kim (@Powerstream3604)\\n\\nstruct JPoint {\\n uint256 x;\\n uint256 y;\\n uint256 z;\\n}\\n\\nlibrary LibSecp256r1 {\\n uint256 constant gx =\\n 0x6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296;\\n uint256 constant gy =\\n 0x4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5;\\n uint256 public constant pp =\\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF;\\n\\n uint256 public constant nn =\\n 0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551;\\n uint256 constant a =\\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC;\\n uint256 constant b =\\n 0x5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B;\\n uint256 constant MOST_SIGNIFICANT =\\n 0xc000000000000000000000000000000000000000000000000000000000000000;\\n\\n /*\\n * Verify\\n * @description - verifies that a public key has signed a given message\\n * @param Q - public key coordinates X & Y\\n * @param R - signature half R\\n * @param S - signature half S\\n * @param input - hashed message\\n */\\n function Verify(\\n uint256[2] memory q,\\n uint r,\\n uint s,\\n uint e\\n ) internal view returns (bool) {\\n if (q[0] > pp - 1 || q[1] > pp - 1) {\\n return false;\\n }\\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\\n return false;\\n }\\n if (\\n mulmod(q[1], q[1], pp) !=\\n addmod(\\n addmod(\\n mulmod(q[0], mulmod(q[0], q[0], pp), pp),\\n mulmod(a, q[0], pp),\\n pp\\n ),\\n b,\\n pp\\n )\\n ) {\\n return false;\\n }\\n\\n JPoint[16] memory points = _preComputeJacobianPoints(q);\\n return VerifyWithPrecompute(points, r, s, e);\\n }\\n\\n function VerifyWithPrecompute(\\n JPoint[16] memory points,\\n uint r,\\n uint s,\\n uint e\\n ) internal view returns (bool) {\\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\\n return false;\\n }\\n\\n uint w = _primemod(s, nn);\\n\\n uint u1 = mulmod(e, w, nn);\\n uint u2 = mulmod(r, w, nn);\\n\\n uint x;\\n uint y;\\n\\n (x, y) = ShamirMultJacobian(points, u1, u2);\\n return (x == r);\\n }\\n\\n /*\\n * Strauss Shamir trick for EC multiplication\\n * https://stackoverflow.com/questions/50993471/ec-scalar-multiplication-with-strauss-shamir-method\\n * we optimise on this a bit to do with 2 bits at a time rather than a single bit\\n * the individual points for a single pass are precomputed\\n * overall this reduces the number of additions while keeping the same number of doublings\\n */\\n function ShamirMultJacobian(\\n JPoint[16] memory points,\\n uint u1,\\n uint u2\\n ) internal view returns (uint, uint) {\\n uint x = 0;\\n uint y = 0;\\n uint z = 0;\\n uint bits = 128;\\n uint index = 0;\\n\\n while (bits > 0) {\\n if (z > 0) {\\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\\n }\\n index =\\n ((u1 & MOST_SIGNIFICANT) >> 252) |\\n ((u2 & MOST_SIGNIFICANT) >> 254);\\n if (index > 0) {\\n (x, y, z) = _jAdd(\\n x,\\n y,\\n z,\\n points[index].x,\\n points[index].y,\\n points[index].z\\n );\\n }\\n u1 <<= 2;\\n u2 <<= 2;\\n bits--;\\n }\\n (x, y) = _affineFromJacobian(x, y, z);\\n return (x, y);\\n }\\n\\n function _preComputeJacobianPoints(\\n uint256[2] memory q\\n ) internal pure returns (JPoint[16] memory points) {\\n points[0] = JPoint(0, 0, 0);\\n points[1] = JPoint(q[0], q[1], 1); // u2\\n points[2] = _jPointDouble(points[1]);\\n points[3] = _jPointAdd(points[1], points[2]);\\n\\n points[4] = JPoint(gx, gy, 1); // u1Points[1]\\n points[5] = _jPointAdd(points[4], points[1]);\\n points[6] = _jPointAdd(points[4], points[2]);\\n points[7] = _jPointAdd(points[4], points[3]);\\n\\n points[8] = _jPointDouble(points[4]); // u1Points[2]\\n points[9] = _jPointAdd(points[8], points[1]);\\n points[10] = _jPointAdd(points[8], points[2]);\\n points[11] = _jPointAdd(points[8], points[3]);\\n\\n points[12] = _jPointAdd(points[4], points[8]); // u1Points[3]\\n points[13] = _jPointAdd(points[12], points[1]);\\n points[14] = _jPointAdd(points[12], points[2]);\\n points[15] = _jPointAdd(points[12], points[3]);\\n }\\n\\n function _jPointAdd(\\n JPoint memory p1,\\n JPoint memory p2\\n ) internal pure returns (JPoint memory) {\\n uint x;\\n uint y;\\n uint z;\\n (x, y, z) = _jAdd(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z);\\n return JPoint(x, y, z);\\n }\\n\\n function _jPointDouble(\\n JPoint memory p\\n ) internal pure returns (JPoint memory) {\\n uint x;\\n uint y;\\n uint z;\\n (x, y, z) = _modifiedJacobianDouble(p.x, p.y, p.z);\\n return JPoint(x, y, z);\\n }\\n\\n /* _affineFromJacobian\\n * @desription returns affine coordinates from a jacobian input follows\\n * golang elliptic/crypto library\\n */\\n function _affineFromJacobian(\\n uint x,\\n uint y,\\n uint z\\n ) internal view returns (uint ax, uint ay) {\\n if (z == 0) {\\n return (0, 0);\\n }\\n\\n uint zinv = _primemod(z, pp);\\n uint zinvsq = mulmod(zinv, zinv, pp);\\n\\n ax = mulmod(x, zinvsq, pp);\\n ay = mulmod(y, mulmod(zinvsq, zinv, pp), pp);\\n }\\n\\n /*\\n * _jAdd\\n * @description performs Jacobian addition as defined below:\\n * http://www.hyperelliptic.org/EFD/g1p/data/shortw/jacobian/addition/add-2007-bl\\n */\\n function _jAdd(\\n uint p1,\\n uint p2,\\n uint p3,\\n uint q1,\\n uint q2,\\n uint q3\\n ) internal pure returns (uint r1, uint r2, uint r3) {\\n if (p3 == 0) {\\n r1 = q1;\\n r2 = q2;\\n r3 = q3;\\n\\n return (r1, r2, r3);\\n } else if (q3 == 0) {\\n r1 = p1;\\n r2 = p2;\\n r3 = p3;\\n\\n return (r1, r2, r3);\\n }\\n\\n assembly {\\n let\\n pd\\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\\n let z1z1 := mulmod(p3, p3, pd) // Z1Z1 = Z1^2\\n let z2z2 := mulmod(q3, q3, pd) // Z2Z2 = Z2^2\\n\\n let u1 := mulmod(p1, z2z2, pd) // U1 = X1*Z2Z2\\n let u2 := mulmod(q1, z1z1, pd) // U2 = X2*Z1Z1\\n\\n let s1 := mulmod(p2, mulmod(z2z2, q3, pd), pd) // S1 = Y1*Z2*Z2Z2\\n let s2 := mulmod(q2, mulmod(z1z1, p3, pd), pd) // S2 = Y2*Z1*Z1Z1\\n\\n let p3q3 := addmod(p3, q3, pd)\\n\\n if lt(u2, u1) {\\n u2 := add(pd, u2) // u2 = u2+pd\\n }\\n let h := sub(u2, u1) // H = U2-U1\\n\\n let i := mulmod(0x02, h, pd)\\n i := mulmod(i, i, pd) // I = (2*H)^2\\n\\n let j := mulmod(h, i, pd) // J = H*I\\n if lt(s2, s1) {\\n s2 := add(pd, s2) // u2 = u2+pd\\n }\\n let rr := mulmod(0x02, sub(s2, s1), pd) // r = 2*(S2-S1)\\n r1 := mulmod(rr, rr, pd) // X3 = R^2\\n\\n let v := mulmod(u1, i, pd) // V = U1*I\\n let j2v := addmod(j, mulmod(0x02, v, pd), pd)\\n if lt(r1, j2v) {\\n r1 := add(pd, r1) // X3 = X3+pd\\n }\\n r1 := sub(r1, j2v)\\n\\n // Y3 = r*(V-X3)-2*S1*J\\n let s12j := mulmod(mulmod(0x02, s1, pd), j, pd)\\n\\n if lt(v, r1) {\\n v := add(pd, v)\\n }\\n r2 := mulmod(rr, sub(v, r1), pd)\\n\\n if lt(r2, s12j) {\\n r2 := add(pd, r2)\\n }\\n r2 := sub(r2, s12j)\\n\\n // Z3 = ((Z1+Z2)^2-Z1Z1-Z2Z2)*H\\n z1z1 := addmod(z1z1, z2z2, pd)\\n j2v := mulmod(p3q3, p3q3, pd)\\n if lt(j2v, z1z1) {\\n j2v := add(pd, j2v)\\n }\\n r3 := mulmod(sub(j2v, z1z1), h, pd)\\n }\\n return (r1, r2, r3);\\n }\\n\\n // Point doubling on the modified jacobian coordinates\\n // http://point-at-infinity.org/ecc/Prime_Curve_Modified_Jacobian_Coordinates.html\\n function _modifiedJacobianDouble(\\n uint x,\\n uint y,\\n uint z\\n ) internal pure returns (uint x3, uint y3, uint z3) {\\n if (y == 0) return (0, 0, 0);\\n assembly {\\n let\\n pd\\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\\n let z2 := mulmod(z, z, pd)\\n let az4 := mulmod(\\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC,\\n mulmod(z2, z2, pd),\\n pd\\n )\\n let y2 := mulmod(y, y, pd)\\n let s := mulmod(0x04, mulmod(x, y2, pd), pd)\\n let u := mulmod(0x08, mulmod(y2, y2, pd), pd)\\n let m := addmod(mulmod(0x03, mulmod(x, x, pd), pd), az4, pd)\\n let twos := mulmod(0x02, s, pd)\\n let m2 := mulmod(m, m, pd)\\n if lt(m2, twos) {\\n m2 := add(pd, m2)\\n }\\n x3 := sub(m2, twos)\\n if lt(s, x3) {\\n s := add(pd, s)\\n }\\n y3 := mulmod(m, sub(s, x3), pd)\\n if lt(y3, u) {\\n y3 := add(pd, y3)\\n }\\n y3 := sub(y3, u)\\n z3 := mulmod(0x02, mulmod(y, z, pd), pd)\\n }\\n }\\n\\n // Fermats little theorem https://en.wikipedia.org/wiki/Fermat%27s_little_theorem\\n // a^(p-1) = 1 mod p\\n // a^(-1) \\u2245 a^(p-2) (mod p)\\n // we then use the precompile bigModExp to compute a^(-1)\\n function _primemod(uint value, uint p) internal view returns (uint ret) {\\n ret = modexp(value, p - 2, p);\\n return ret;\\n }\\n\\n // Wrapper for built-in BigNumber_modexp (contract 0x5) as described here. https://github.com/ethereum/EIPs/pull/198\\n function modexp(\\n uint _base,\\n uint _exp,\\n uint _mod\\n ) internal view returns (uint ret) {\\n // bigModExp(_base, _exp, _mod);\\n assembly {\\n if gt(_base, _mod) {\\n _base := mod(_base, _mod)\\n }\\n // Free memory pointer is always stored at 0x40\\n let freemem := mload(0x40)\\n\\n mstore(freemem, 0x20)\\n mstore(add(freemem, 0x20), 0x20)\\n mstore(add(freemem, 0x40), 0x20)\\n\\n mstore(add(freemem, 0x60), _base)\\n mstore(add(freemem, 0x80), _exp)\\n mstore(add(freemem, 0xa0), _mod)\\n\\n let success := staticcall(14000, 0x5, freemem, 0xc0, freemem, 0x20)\\n switch success\\n case 0 {\\n revert(0x0, 0x0)\\n }\\n default {\\n ret := mload(freemem)\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb53714ba63cddb379ba312c1e7f6a423f4d7a7e34fa1364ec8295cd57d544024\",\"license\":\"GPL-3.0\"},\"contracts/infrastructure/interfaces/IFacetRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Registry Interface\\n * @dev Interface for Facet Registry contract to keep track of facets & function selectors addable to user wallets\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IFacetRegistry {\\n struct FacetRegistryConfig {\\n bytes4[] selectors;\\n mapping(bytes4 => FacetInfo) info;\\n }\\n struct FacetInfo {\\n bool exists;\\n uint128 index;\\n }\\n\\n event FacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] facetSelectors\\n );\\n event FacetFunctionSelectorsRemoved(address facet, bytes4[] facetSelectors);\\n\\n error FacetRegistry__FacetSelectorAlreadyRegistered();\\n error FacetRegistry__UnregisteredFacetSelector();\\n\\n function registerFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function removeFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function areFacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external view returns (bool);\\n\\n function isFacetFunctionSelectorRegistered(\\n address facet,\\n bytes4 facetSelector\\n ) external view returns (bool);\\n\\n function getFacetFunctionSelectors(\\n address facet\\n ) external view returns (bytes4[] memory);\\n}\\n\",\"keccak256\":\"0x6e6dd2cab346ef7c31230740ec48d2925e4a9ab24c2f2fb268baaf408dcf02ef\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC1271 {\\n function isValidSignature(\\n bytes32 hash,\\n bytes memory signature\\n ) external view returns (bytes4);\\n}\\n\",\"keccak256\":\"0xcdddb7d5641c9d3f2432dec7fd13fddb9ae1480f25c76c21511e2fa16b8bd422\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibAppStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {SafeCast} from \\\"@openzeppelin/contracts/utils/math/SafeCast.sol\\\";\\nimport {IEntryPoint} from \\\"../aa-4337/interfaces/IEntryPoint.sol\\\";\\nimport {IFacetRegistry} from \\\"../infrastructure/interfaces/IFacetRegistry.sol\\\";\\n\\n/*\\n * @title App Storage\\n * @dev App storage for Barz contract to prevent storage collision\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Lock {\\n uint64 release;\\n bytes4 locker;\\n}\\n\\nstruct InitializersStorage {\\n // NOTE: initialized is a variable to make sure the initialization is only done once.\\n uint8 signerInitialized;\\n uint8 accountInitialized;\\n uint8 restrictionsInitialized;\\n}\\n\\nstruct AppStorage {\\n mapping(uint256 => InitializersStorage) initStorage;\\n uint8 signerMigration;\\n bytes4 validateOwnerSignatureSelector;\\n IEntryPoint entryPoint;\\n IFacetRegistry facetRegistry;\\n mapping(uint256 => Lock) locks;\\n}\\n\\nlibrary LibAppStorage {\\n error LibAppStorage__AccountAlreadyUninitialized();\\n error LibAppStorage__AccountMustBeUninitialized();\\n error LibAppStorage__SignerAlreadyUninitialized();\\n error LibAppStorage__SignerMustBeUninitialized();\\n\\n function appStorage() internal pure returns (AppStorage storage ds) {\\n assembly {\\n ds.slot := 0\\n }\\n }\\n\\n function setSignerUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerAlreadyUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 0;\\n }\\n\\n function getValidateOwnerSignatureSelector()\\n internal\\n view\\n returns (bytes4 selector)\\n {\\n selector = appStorage().validateOwnerSignatureSelector;\\n }\\n\\n function setValidateOwnerSignatureSelector(\\n bytes4 _validateOwnerSignatureSelector\\n ) internal {\\n appStorage()\\n .validateOwnerSignatureSelector = _validateOwnerSignatureSelector;\\n }\\n\\n function enforceSignerInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerMustBeUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 1;\\n }\\n\\n function enforceAccountInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].accountInitialized) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n s.initStorage[0].accountInitialized = 1;\\n }\\n\\n function initiateSignerMigration() internal {\\n appStorage().signerMigration = 1;\\n }\\n\\n function enforceSignerMigration() internal view {\\n if (1 != appStorage().signerMigration) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n }\\n\\n function finalizeSignerMigration() internal {\\n appStorage().signerMigration = 0;\\n }\\n\\n function setLock(uint256 _releaseAfter, bytes4 _locker) internal {\\n appStorage().locks[0] = Lock(SafeCast.toUint64(_releaseAfter), _locker);\\n }\\n\\n function enforceRestrictionsInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__SignerMustBeUninitialized();\\n s.initStorage[0].restrictionsInitialized = 1;\\n }\\n\\n function setRestrictionsUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__AccountAlreadyUninitialized();\\n s.initStorage[0].restrictionsInitialized = 0;\\n }\\n}\\n\\ncontract BarzStorage {\\n AppStorage internal s;\\n modifier onlyWhenUnlocked() {\\n require(\\n uint64(block.timestamp) >= s.locks[0].release,\\n \\\"Account Locked\\\"\\n );\\n _;\\n }\\n modifier onlyWhenLocked() {\\n require(\\n uint64(block.timestamp) < s.locks[0].release,\\n \\\"Account Unlocked\\\"\\n );\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x48524007862a6ce0e07f645950613ce6513ce073c37a109c75019683d42bae27\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\\n bytes4(keccak256(\\\"verifyRestrictions(address,address,uint256,bytes)\\\"));\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // Default Fallback Handler of the barz.\\n IDiamondLoupe defaultFallbackHandler;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function enforceIsSelf() internal view {\\n require(msg.sender == address(this), \\\"LibDiamond: Caller not self\\\");\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n\\n unchecked {\\n facetIndex++;\\n }\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n\\n function restrictionsFacet() internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(\\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2cabdc00de859c3a3170ce3bda5d0e5fd3933d47ce904fd1585f9818b02572f8\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibFacetStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Storage\\n * @dev Storage contract to store each facets variables with diamond storage\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Secp256k1VerificationStorage {\\n address signer;\\n}\\n\\nstruct Secp256r1VerificationStorage {\\n uint256[2] q;\\n}\\n\\nstruct GuardianStorage {\\n mapping(bytes32 => uint256) pending;\\n mapping(uint8 => StorageConfig) configs;\\n}\\n\\nstruct Info {\\n bool exists;\\n uint128 index;\\n}\\n\\nstruct StorageConfig {\\n address[] addresses;\\n mapping(address => Info) info;\\n}\\n\\nstruct RecoveryConfig {\\n bytes recoveryPublicKey;\\n uint64 executeAfter;\\n}\\n\\nstruct ApprovalConfig {\\n bool isApproved;\\n uint64 validUntil;\\n}\\n\\nstruct RecoveryApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isNewOwnerApproved;\\n}\\n\\nstruct RecoveryStorage {\\n mapping(uint8 => RecoveryConfig) recoveryConfigs;\\n mapping(uint8 => RecoveryApprovalConfig) recoveryApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct RestrictionsStorage {\\n address[] restrictions;\\n mapping(address => bool) exists;\\n}\\n\\nstruct SignatureMigrationConfig {\\n bytes migrationPublicKey;\\n address migrationVerificationFacet;\\n bytes4[] migrationSelectors;\\n uint64 migrateAfter;\\n}\\n\\nstruct SignatureMigrationApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isMigrationApproved;\\n}\\n\\nstruct SignatureMigrationStorage {\\n mapping(uint8 => SignatureMigrationConfig) migrationConfigs;\\n mapping(uint8 => SignatureMigrationApprovalConfig) migrationApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct DiamondCutApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isDiamondCutApproved;\\n}\\n\\nstruct DiamondCutStorage {\\n mapping(uint8 => DiamondCutApprovalConfig) diamondCutApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct LockStorage {\\n uint128 nonce;\\n}\\n\\nlibrary LibFacetStorage {\\n bytes32 constant K1_STORAGE_POSITION =\\n keccak256(\\n \\\"v0.trustwallet.diamond.storage.Secp256k1VerificationStorage\\\"\\n );\\n bytes32 constant R1_STORAGE_POSITION =\\n keccak256(\\n \\\"v0.trustwallet.diamond.storage.Secp256r1VerificationStorage\\\"\\n );\\n bytes32 constant GUARDIAN_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.GuardianStorage\\\");\\n bytes32 constant RECOVERY_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.RecoveryStorage\\\");\\n bytes32 constant RESTRICTION_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.RestrictionsStorage\\\");\\n bytes32 constant MIGRATION_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.SignatureMigrationStorage\\\");\\n bytes32 constant DIAMONDCUT_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.DiamondCutStorage\\\");\\n bytes32 constant LOCK_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.LockStorage\\\");\\n\\n function k1Storage()\\n internal\\n pure\\n returns (Secp256k1VerificationStorage storage ds)\\n {\\n bytes32 storagePosition = K1_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function r1Storage()\\n internal\\n pure\\n returns (Secp256r1VerificationStorage storage ds)\\n {\\n bytes32 storagePosition = R1_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function guardianStorage()\\n internal\\n pure\\n returns (GuardianStorage storage ds)\\n {\\n bytes32 storagePosition = GUARDIAN_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function recoveryStorage()\\n internal\\n pure\\n returns (RecoveryStorage storage ds)\\n {\\n bytes32 storagePosition = RECOVERY_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function restrictionsStorage()\\n internal\\n pure\\n returns (RestrictionsStorage storage ds)\\n {\\n bytes32 storagePosition = RESTRICTION_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function migrationStorage()\\n internal\\n pure\\n returns (SignatureMigrationStorage storage ds)\\n {\\n bytes32 storagePosition = MIGRATION_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function diamondCutStorage()\\n internal\\n pure\\n returns (DiamondCutStorage storage ds)\\n {\\n bytes32 storagePosition = DIAMONDCUT_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function lockStorage() internal pure returns (LockStorage storage ds) {\\n bytes32 storagePosition = LOCK_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n}\\n\",\"keccak256\":\"0x87c85decfd943deda9540733e464cb1a92eba735a301e89ce6f798016e359761\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\nimport {LibDiamond} from \\\"./LibDiamond.sol\\\";\\n\\n/**\\n * @title LibLoupe\\n * @dev Internal Library to provide utility feature for reading the state of diamond facets\\n * Originally from Diamond's implementation of Mudgen(author of EIP-2535)\\n */\\nlibrary LibLoupe {\\n /// @notice Gets all facets and their selectors.\\n /// @return facets_ Facet\\n function facets()\\n internal\\n view\\n returns (IDiamondLoupe.Facet[] memory facets_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facets_ = new IDiamondLoupe.Facet[](ds.selectorCount);\\n uint16[] memory numFacetSelectors = new uint16[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facets_[facetIndex].facetAddress == facetAddress_) {\\n facets_[facetIndex].functionSelectors[\\n numFacetSelectors[facetIndex]\\n ] = selector;\\n // probably will never have more than 256 functions from one facet contract\\n require(numFacetSelectors[facetIndex] < 255);\\n numFacetSelectors[facetIndex]++;\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facets_[numFacets].facetAddress = facetAddress_;\\n facets_[numFacets].functionSelectors = new bytes4[](\\n ds.selectorCount\\n );\\n facets_[numFacets].functionSelectors[0] = selector;\\n numFacetSelectors[numFacets] = 1;\\n numFacets++;\\n }\\n }\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n uint256 numSelectors = numFacetSelectors[facetIndex];\\n bytes4[] memory selectors = facets_[facetIndex].functionSelectors;\\n // setting the number of selectors\\n assembly {\\n mstore(selectors, numSelectors)\\n }\\n }\\n // setting the number of facets\\n assembly {\\n mstore(facets_, numFacets)\\n }\\n }\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return _facetFunctionSelectors The selectors associated with a facet address.\\n function facetFunctionSelectors(\\n address _facet\\n ) internal view returns (bytes4[] memory _facetFunctionSelectors) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n uint256 numSelectors;\\n _facetFunctionSelectors = new bytes4[](ds.selectorCount);\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facet = address(bytes20(ds.facets[selector]));\\n if (_facet == facet) {\\n _facetFunctionSelectors[numSelectors] = selector;\\n numSelectors++;\\n }\\n }\\n }\\n // Set the number of selectors in the array\\n assembly {\\n mstore(_facetFunctionSelectors, numSelectors)\\n }\\n }\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n internal\\n view\\n returns (address[] memory facetAddresses_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetAddresses_ = new address[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facetAddress_ == facetAddresses_[facetIndex]) {\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facetAddresses_[numFacets] = facetAddress_;\\n numFacets++;\\n }\\n }\\n // Set the number of facet addresses in the array\\n assembly {\\n mstore(facetAddresses_, numFacets)\\n }\\n }\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(LibDiamond.diamondStorage().facets[_functionSelector])\\n );\\n }\\n}\\n\",\"keccak256\":\"0x0b11439c3cc657095e15ec2241fdcf67204b14001357b612fc5db4ff9e760a5a\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x60a060405234801561001057600080fd5b50610019610022565b3060805261008b565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff161561006f57604051637c2cde8b60e01b815260040160405180910390fd5b600080805260209190915260409020805460ff19166001179055565b608051611f746100ad6000396000818161016001526106e10152611f746000f3fe608060405234801561001057600080fd5b50600436106100a35760003560e01c80637104ddb2116100765780638dd501211161005b5780638dd50121146101bc578063cd00e50a146101cf578063cd9b47e4146101d757600080fd5b80637104ddb21461015b5780638da5cb5b146101a757600080fd5b806311cfe388146100a85780631626ba7e146100ce5780633253960f14610112578063392dd6d914610138575b600080fd5b6100bb6100b6366004611823565b6101ea565b6040519081526020015b60405180910390f35b6100e16100dc366004611956565b610252565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020016100c5565b7f8dd50121000000000000000000000000000000000000000000000000000000006100e1565b61014b61014636600461199d565b6102fd565b60405190151581526020016100c5565b6101827f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100c5565b6101af61036f565b6040516100c591906119f6565b6100bb6101ca366004611a47565b6103ba565b6100bb61041f565b6100bb6101e5366004611a8c565b61053a565b600061023982846101ff610140880188611afe565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061083692505050565b610244576001610247565b60005b60ff16949350505050565b60006102aa7f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b1653646040805180820191829052919060029082845b81548152602001906001019080831161028b5750505050508484610836565b6102d4577fffffffff000000000000000000000000000000000000000000000000000000006102f6565b7f1626ba7e000000000000000000000000000000000000000000000000000000005b9392505050565b60008151604114801561036957508160008151811061031e5761031e611b6a565b6020910101517fff00000000000000000000000000000000000000000000000000000000000000167f0400000000000000000000000000000000000000000000000000000000000000145b92915050565b6040516060907f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364906103a5908290602001611b99565b60405160208183030381529060405291505090565b60408051808201918290526000917f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364916104179186918691859060029082845b8154815260200190600101908083116103fa5750505050506101ea565b949350505050565b60006104296109b4565b6104316109f4565b60408051808201909152600080825260208201527f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364906104749082906002611675565b506000610488600154610100900460e01b90565b7fffffffff0000000000000000000000000000000000000000000000000000000016036104e1576040517f127c609a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff169055604051600192507fcccd30db6bc000b8bb8d11162228d2d69e3c361983ca3ae8c1365ce64b0fae9e90600090a15090565b6000610544610a93565b61058383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102fd92505050565b6105b9576040517f6c334d2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006105c88360018187611bcd565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092935061060992506116b8915050565b602082015181526040820151602082015260006106437f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b16536490565b9050610651818360026116d6565b507f8dd50121000000000000000000000000000000000000000000000000000000006000610686600154610100900460e01b90565b7fffffffff0000000000000000000000000000000000000000000000000000000016146106df576040517f5f95a63c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16610770827fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604090205460601c90565b73ffffffffffffffffffffffffffffffffffffffff16146107bd576040517fbb4752b700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff1661010060e084901c02179055600194507f6d54821a69ec281ed7ba1bf2729c700768c47df1d80fad646b0a14cc1d5c39ed8787604051610824929190611bf7565b60405180910390a15050505092915050565b600080600080600080868060200190518101906108539190611c94565b9450945094509450945060008061088a8a60405160200161087691815260200190565b604051602081830303815290604052610b33565b905060008482856040516020016108a393929190611d47565b60405160208183030381529060405290506002816040516108c49190611d8a565b602060405180830381855afa1580156108e1573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906109049190611da6565b9250505060006002858360405160200161091f929190611dbf565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905261095791611d8a565b602060405180830381855afa158015610974573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906109979190611da6565b90506109a58b888884610c6f565b9b9a5050505050505050505050565b6001805460ff16146109f2576040517f38fc28cb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff16600114610a5c576040517fe00d7c7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff1615610af9576040517f7c2cde8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b60608151600003610b5257505060408051602081019091526000815290565b6000604051806060016040528060408152602001611eff6040913990506000600684516008610b819190611e10565b610b8b9190611e56565b9050600060068551610b9d9190611e6a565b1115610bb15780610bad81611e7e565b9150505b60008167ffffffffffffffff811115610bcc57610bcc61177c565b6040519080825280601f01601f191660200182016040528015610bf6576020820181803683370190505b509050600183016020820186875188015b80821015610c62576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f8116850151845350600183019250610c07565b5092979650505050505050565b6000610c9c60017fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611eb6565b85511180610cd75750610cd060017fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611eb6565b6020860151115b15610ce457506000610417565b831580610cef575082155b80610d1a57507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518410155b80610d4557507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518310155b15610d5257506000610417565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff7f5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff8088600060200201517fffffffff00000001000000000000000000000000fffffffffffffffffffffffc0988517fffffffff00000001000000000000000000000000ffffffffffffffffffffffff90819080098a5109080860208601517fffffffff00000001000000000000000000000000ffffffffffffffffffffffff90800914610e4357506000610417565b6000610e4e86610e66565b9050610e5c81868686611062565b9695505050505050565b610e6e611704565b60405180606001604052806000815260200160008152602001600081525081600060108110610e9f57610e9f611b6a565b60200201526040805160608101909152808360006020020151815260200183600160028110610ed057610ed0611b6a565b60200201518152602001600181525081600160108110610ef257610ef2611b6a565b6020020152610f088160015b602002015161116f565b6040820152610f278160015b60200201518260025b60200201516111d1565b6060828101919091526040805191820181527f6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c29682527f4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f560208301526001908201526080820152610fa18160045b6020020151826001610f1d565b60a0820152610fb1816004610f14565b60c0820152610fca8160045b6020020151826003610f1d565b60e0820152610fda816004610efe565b610100820152610feb816008610f94565b610120820152610ffc816008610f14565b61014082015261100d816008610fbd565b610160820152608081015161102490826008610f1d565b61018082015261103581600c610f94565b6101a082015261104681600c610f14565b6101c082015261105781600c610fbd565b6101e0820152919050565b600083158061106f575082155b8061109a57507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518410155b806110c557507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518310155b156110d257506000610417565b60006110fe847fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551611243565b905060007fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551828509905060007fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551838809905060008061115e8a858561125a565b509098149998505050505050505050565b61119360405180606001604052806000815260200160008152602001600081525090565b60008060006111af856000015186602001518760400151611346565b6040805160608101825293845260208401929092529082015295945050505050565b6111f560405180606001604052806000815260200160008152602001600081525090565b6000806000611220866000015187602001518860400151886000015189602001518a60400151611424565b604080516060810182529384526020840192909252908201529695505050505050565b60006102f683611254600285611eb6565b8461155c565b6000808080806080815b81156113285782156112955761127b858585611346565b9196509450925061128d858585611346565b919650945092505b50600c60fc89901c1660fe88901c17801561130b576113038585858d85601081106112c2576112c2611b6a565b6020020151518e86601081106112da576112da611b6a565b6020020151602001518f87601081106112f5576112f5611b6a565b602002015160400151611424565b919650945092505b600298891b989790971b968161132081611ec9565b925050611264565b6113338585856115b0565b909750955050505050505b935093915050565b6000806000846000036113615750600091508190508061141b565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff8085860981828283097fffffffff00000001000000000000000000000000fffffffffffffffffffffffc099050818788098283828b0960040983848384096008099150838385868d8e09600309089250838160020984848509818110156113e65785015b039650868110156113f45783015b8387820384099550508085101561140a57938201935b909303925080808688096002099150505b93509350939050565b60008060008660000361143e575084915083905082611550565b83600003611453575087915086905085611550565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff808889098186870982818d0983838b0984858a85098e0985868e87098c09868b8f08848410156114a357928701925b8484039350878460020988818209905088818609848410156114c457928901925b898585036002099350898485099c50898288099650898a8860020982089150818d10156114f0579b89019b5b818d039c5089818b87600209099450508b86101561150d57948801945b888c870384099a50838b101561152257998801995b838b039a508887890897508882830990508781101561153e5788015b88858983030999505050505050505050505b96509650969350505050565b60008184111561156c5781840693505b60405160208152602080820152602060408201528460608201528360808201528260a082015260208160c08360056136b0fa8080156100a357505051949350505050565b600080826000036115c65750600090508061133e565b60006115f2847fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611243565b905060007fffffffff00000001000000000000000000000000ffffffffffffffffffffffff82830990507fffffffff00000001000000000000000000000000ffffffffffffffffffffffff81880993507fffffffff00000001000000000000000000000000ffffffffffffffffffffffff80838309870992505050935093915050565b82600281019282156116a8579160200282015b828111156116a8578251829060ff16905591602001919060010190611688565b506116b492915061174e565b5090565b60405180604001604052806002906020820280368337509192915050565b82600281019282156116a8579160200282015b828111156116a85782518255916020019190600101906116e9565b6040518061020001604052806010905b61173860405180606001604052806000815260200160008152602001600081525090565b8152602001906001900390816117145790505090565b5b808211156116b4576000815560010161174f565b6000610160828403121561177657600080fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156117ce576117ce61177c565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561181b5761181b61177c565b604052919050565b60008060006080848603121561183857600080fd5b833567ffffffffffffffff81111561184f57600080fd5b61185b86828701611763565b935050602080850135925085605f86011261187557600080fd5b61187d6117ab565b80608087018881111561188f57600080fd5b604088015b818110156118ab5780358452928401928401611894565b50508093505050509250925092565b600067ffffffffffffffff8211156118d4576118d461177c565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261191157600080fd5b813561192461191f826118ba565b6117d4565b81815284602083860101111561193957600080fd5b816020850160208301376000918101602001919091529392505050565b6000806040838503121561196957600080fd5b82359150602083013567ffffffffffffffff81111561198757600080fd5b61199385828601611900565b9150509250929050565b6000602082840312156119af57600080fd5b813567ffffffffffffffff8111156119c657600080fd5b61041784828501611900565b60005b838110156119ed5781810151838201526020016119d5565b50506000910152565b6020815260008251806020840152611a158160408501602087016119d2565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b60008060408385031215611a5a57600080fd5b823567ffffffffffffffff811115611a7157600080fd5b611a7d85828601611763565b95602094909401359450505050565b60008060208385031215611a9f57600080fd5b823567ffffffffffffffff80821115611ab757600080fd5b818501915085601f830112611acb57600080fd5b813581811115611ada57600080fd5b866020828501011115611aec57600080fd5b60209290920196919550909350505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112611b3357600080fd5b83018035915067ffffffffffffffff821115611b4e57600080fd5b602001915036819003821315611b6357600080fd5b9250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008183825b6002811015611bbe578154835260209092019160019182019101611b9f565b50505060408201905092915050565b60008085851115611bdd57600080fd5b83861115611bea57600080fd5b5050820193919092039150565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b6000611c5261191f846118ba565b9050828152838383011115611c6657600080fd5b6102f68360208301846119d2565b600082601f830112611c8557600080fd5b6102f683835160208501611c44565b600080600080600060a08688031215611cac57600080fd5b8551945060208601519350604086015167ffffffffffffffff80821115611cd257600080fd5b818801915088601f830112611ce657600080fd5b611cf589835160208501611c44565b94506060880151915080821115611d0b57600080fd5b611d1789838a01611c74565b93506080880151915080821115611d2d57600080fd5b50611d3a88828901611c74565b9150509295509295909350565b60008451611d598184602089016119d2565b845190830190611d6d8183602089016119d2565b8451910190611d808183602088016119d2565b0195945050505050565b60008251611d9c8184602087016119d2565b9190910192915050565b600060208284031215611db857600080fd5b5051919050565b60008351611dd18184602088016119d2565b9190910191825250602001919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808202811582820484141761036957610369611de1565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082611e6557611e65611e27565b500490565b600082611e7957611e79611e27565b500690565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611eaf57611eaf611de1565b5060010190565b8181038181111561036957610369611de1565b600081611ed857611ed8611de1565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392d5fa2646970667358221220d4142da7b16effb6b95f41adeff2bc8ce0d59d3b70ca8d55e6e83224bbfbec0a64736f6c63430008150033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100a35760003560e01c80637104ddb2116100765780638dd501211161005b5780638dd50121146101bc578063cd00e50a146101cf578063cd9b47e4146101d757600080fd5b80637104ddb21461015b5780638da5cb5b146101a757600080fd5b806311cfe388146100a85780631626ba7e146100ce5780633253960f14610112578063392dd6d914610138575b600080fd5b6100bb6100b6366004611823565b6101ea565b6040519081526020015b60405180910390f35b6100e16100dc366004611956565b610252565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020016100c5565b7f8dd50121000000000000000000000000000000000000000000000000000000006100e1565b61014b61014636600461199d565b6102fd565b60405190151581526020016100c5565b6101827f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100c5565b6101af61036f565b6040516100c591906119f6565b6100bb6101ca366004611a47565b6103ba565b6100bb61041f565b6100bb6101e5366004611a8c565b61053a565b600061023982846101ff610140880188611afe565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061083692505050565b610244576001610247565b60005b60ff16949350505050565b60006102aa7f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b1653646040805180820191829052919060029082845b81548152602001906001019080831161028b5750505050508484610836565b6102d4577fffffffff000000000000000000000000000000000000000000000000000000006102f6565b7f1626ba7e000000000000000000000000000000000000000000000000000000005b9392505050565b60008151604114801561036957508160008151811061031e5761031e611b6a565b6020910101517fff00000000000000000000000000000000000000000000000000000000000000167f0400000000000000000000000000000000000000000000000000000000000000145b92915050565b6040516060907f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364906103a5908290602001611b99565b60405160208183030381529060405291505090565b60408051808201918290526000917f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364916104179186918691859060029082845b8154815260200190600101908083116103fa5750505050506101ea565b949350505050565b60006104296109b4565b6104316109f4565b60408051808201909152600080825260208201527f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364906104749082906002611675565b506000610488600154610100900460e01b90565b7fffffffff0000000000000000000000000000000000000000000000000000000016036104e1576040517f127c609a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff169055604051600192507fcccd30db6bc000b8bb8d11162228d2d69e3c361983ca3ae8c1365ce64b0fae9e90600090a15090565b6000610544610a93565b61058383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102fd92505050565b6105b9576040517f6c334d2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006105c88360018187611bcd565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092935061060992506116b8915050565b602082015181526040820151602082015260006106437f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b16536490565b9050610651818360026116d6565b507f8dd50121000000000000000000000000000000000000000000000000000000006000610686600154610100900460e01b90565b7fffffffff0000000000000000000000000000000000000000000000000000000016146106df576040517f5f95a63c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16610770827fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604090205460601c90565b73ffffffffffffffffffffffffffffffffffffffff16146107bd576040517fbb4752b700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff1661010060e084901c02179055600194507f6d54821a69ec281ed7ba1bf2729c700768c47df1d80fad646b0a14cc1d5c39ed8787604051610824929190611bf7565b60405180910390a15050505092915050565b600080600080600080868060200190518101906108539190611c94565b9450945094509450945060008061088a8a60405160200161087691815260200190565b604051602081830303815290604052610b33565b905060008482856040516020016108a393929190611d47565b60405160208183030381529060405290506002816040516108c49190611d8a565b602060405180830381855afa1580156108e1573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906109049190611da6565b9250505060006002858360405160200161091f929190611dbf565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905261095791611d8a565b602060405180830381855afa158015610974573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906109979190611da6565b90506109a58b888884610c6f565b9b9a5050505050505050505050565b6001805460ff16146109f2576040517f38fc28cb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff16600114610a5c576040517fe00d7c7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff1615610af9576040517f7c2cde8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b60608151600003610b5257505060408051602081019091526000815290565b6000604051806060016040528060408152602001611eff6040913990506000600684516008610b819190611e10565b610b8b9190611e56565b9050600060068551610b9d9190611e6a565b1115610bb15780610bad81611e7e565b9150505b60008167ffffffffffffffff811115610bcc57610bcc61177c565b6040519080825280601f01601f191660200182016040528015610bf6576020820181803683370190505b509050600183016020820186875188015b80821015610c62576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f8116850151845350600183019250610c07565b5092979650505050505050565b6000610c9c60017fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611eb6565b85511180610cd75750610cd060017fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611eb6565b6020860151115b15610ce457506000610417565b831580610cef575082155b80610d1a57507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518410155b80610d4557507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518310155b15610d5257506000610417565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff7f5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff8088600060200201517fffffffff00000001000000000000000000000000fffffffffffffffffffffffc0988517fffffffff00000001000000000000000000000000ffffffffffffffffffffffff90819080098a5109080860208601517fffffffff00000001000000000000000000000000ffffffffffffffffffffffff90800914610e4357506000610417565b6000610e4e86610e66565b9050610e5c81868686611062565b9695505050505050565b610e6e611704565b60405180606001604052806000815260200160008152602001600081525081600060108110610e9f57610e9f611b6a565b60200201526040805160608101909152808360006020020151815260200183600160028110610ed057610ed0611b6a565b60200201518152602001600181525081600160108110610ef257610ef2611b6a565b6020020152610f088160015b602002015161116f565b6040820152610f278160015b60200201518260025b60200201516111d1565b6060828101919091526040805191820181527f6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c29682527f4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f560208301526001908201526080820152610fa18160045b6020020151826001610f1d565b60a0820152610fb1816004610f14565b60c0820152610fca8160045b6020020151826003610f1d565b60e0820152610fda816004610efe565b610100820152610feb816008610f94565b610120820152610ffc816008610f14565b61014082015261100d816008610fbd565b610160820152608081015161102490826008610f1d565b61018082015261103581600c610f94565b6101a082015261104681600c610f14565b6101c082015261105781600c610fbd565b6101e0820152919050565b600083158061106f575082155b8061109a57507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518410155b806110c557507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518310155b156110d257506000610417565b60006110fe847fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551611243565b905060007fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551828509905060007fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551838809905060008061115e8a858561125a565b509098149998505050505050505050565b61119360405180606001604052806000815260200160008152602001600081525090565b60008060006111af856000015186602001518760400151611346565b6040805160608101825293845260208401929092529082015295945050505050565b6111f560405180606001604052806000815260200160008152602001600081525090565b6000806000611220866000015187602001518860400151886000015189602001518a60400151611424565b604080516060810182529384526020840192909252908201529695505050505050565b60006102f683611254600285611eb6565b8461155c565b6000808080806080815b81156113285782156112955761127b858585611346565b9196509450925061128d858585611346565b919650945092505b50600c60fc89901c1660fe88901c17801561130b576113038585858d85601081106112c2576112c2611b6a565b6020020151518e86601081106112da576112da611b6a565b6020020151602001518f87601081106112f5576112f5611b6a565b602002015160400151611424565b919650945092505b600298891b989790971b968161132081611ec9565b925050611264565b6113338585856115b0565b909750955050505050505b935093915050565b6000806000846000036113615750600091508190508061141b565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff8085860981828283097fffffffff00000001000000000000000000000000fffffffffffffffffffffffc099050818788098283828b0960040983848384096008099150838385868d8e09600309089250838160020984848509818110156113e65785015b039650868110156113f45783015b8387820384099550508085101561140a57938201935b909303925080808688096002099150505b93509350939050565b60008060008660000361143e575084915083905082611550565b83600003611453575087915086905085611550565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff808889098186870982818d0983838b0984858a85098e0985868e87098c09868b8f08848410156114a357928701925b8484039350878460020988818209905088818609848410156114c457928901925b898585036002099350898485099c50898288099650898a8860020982089150818d10156114f0579b89019b5b818d039c5089818b87600209099450508b86101561150d57948801945b888c870384099a50838b101561152257998801995b838b039a508887890897508882830990508781101561153e5788015b88858983030999505050505050505050505b96509650969350505050565b60008184111561156c5781840693505b60405160208152602080820152602060408201528460608201528360808201528260a082015260208160c08360056136b0fa8080156100a357505051949350505050565b600080826000036115c65750600090508061133e565b60006115f2847fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611243565b905060007fffffffff00000001000000000000000000000000ffffffffffffffffffffffff82830990507fffffffff00000001000000000000000000000000ffffffffffffffffffffffff81880993507fffffffff00000001000000000000000000000000ffffffffffffffffffffffff80838309870992505050935093915050565b82600281019282156116a8579160200282015b828111156116a8578251829060ff16905591602001919060010190611688565b506116b492915061174e565b5090565b60405180604001604052806002906020820280368337509192915050565b82600281019282156116a8579160200282015b828111156116a85782518255916020019190600101906116e9565b6040518061020001604052806010905b61173860405180606001604052806000815260200160008152602001600081525090565b8152602001906001900390816117145790505090565b5b808211156116b4576000815560010161174f565b6000610160828403121561177657600080fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156117ce576117ce61177c565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561181b5761181b61177c565b604052919050565b60008060006080848603121561183857600080fd5b833567ffffffffffffffff81111561184f57600080fd5b61185b86828701611763565b935050602080850135925085605f86011261187557600080fd5b61187d6117ab565b80608087018881111561188f57600080fd5b604088015b818110156118ab5780358452928401928401611894565b50508093505050509250925092565b600067ffffffffffffffff8211156118d4576118d461177c565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261191157600080fd5b813561192461191f826118ba565b6117d4565b81815284602083860101111561193957600080fd5b816020850160208301376000918101602001919091529392505050565b6000806040838503121561196957600080fd5b82359150602083013567ffffffffffffffff81111561198757600080fd5b61199385828601611900565b9150509250929050565b6000602082840312156119af57600080fd5b813567ffffffffffffffff8111156119c657600080fd5b61041784828501611900565b60005b838110156119ed5781810151838201526020016119d5565b50506000910152565b6020815260008251806020840152611a158160408501602087016119d2565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b60008060408385031215611a5a57600080fd5b823567ffffffffffffffff811115611a7157600080fd5b611a7d85828601611763565b95602094909401359450505050565b60008060208385031215611a9f57600080fd5b823567ffffffffffffffff80821115611ab757600080fd5b818501915085601f830112611acb57600080fd5b813581811115611ada57600080fd5b866020828501011115611aec57600080fd5b60209290920196919550909350505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112611b3357600080fd5b83018035915067ffffffffffffffff821115611b4e57600080fd5b602001915036819003821315611b6357600080fd5b9250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008183825b6002811015611bbe578154835260209092019160019182019101611b9f565b50505060408201905092915050565b60008085851115611bdd57600080fd5b83861115611bea57600080fd5b5050820193919092039150565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b6000611c5261191f846118ba565b9050828152838383011115611c6657600080fd5b6102f68360208301846119d2565b600082601f830112611c8557600080fd5b6102f683835160208501611c44565b600080600080600060a08688031215611cac57600080fd5b8551945060208601519350604086015167ffffffffffffffff80821115611cd257600080fd5b818801915088601f830112611ce657600080fd5b611cf589835160208501611c44565b94506060880151915080821115611d0b57600080fd5b611d1789838a01611c74565b93506080880151915080821115611d2d57600080fd5b50611d3a88828901611c74565b9150509295509295909350565b60008451611d598184602089016119d2565b845190830190611d6d8183602089016119d2565b8451910190611d808183602088016119d2565b0195945050505050565b60008251611d9c8184602087016119d2565b9190910192915050565b600060208284031215611db857600080fd5b5051919050565b60008351611dd18184602088016119d2565b9190910191825250602001919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808202811582820484141761036957610369611de1565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082611e6557611e65611e27565b500490565b600082611e7957611e79611e27565b500690565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611eaf57611eaf611de1565b5060010190565b8181038181111561036957610369611de1565b600081611ed857611ed8611de1565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392d5fa2646970667358221220d4142da7b16effb6b95f41adeff2bc8ce0d59d3b70ca8d55e6e83224bbfbec0a64736f6c63430008150033", + "devdoc": { + "author": "Ruslan Serebriakov (@rsrbk)David Yongjun Kim (@Powerstream3604)", + "details": "Primarily used to verify user ops signed with passkeys", + "kind": "dev", + "methods": { + "initializeSigner(bytes)": { + "details": "This method checks if the signer has already been initialized. If already initialized, it reverts. It checks if the public key is in the light format and initializes signer storage in k1 storage.", + "params": { + "_publicKey": "Bytes of owner public key" + }, + "returns": { + "initSuccess": "Uint value representing the success of init operation" + } + }, + "isValidKeyType(bytes)": { + "details": "For this Secp256k1Verification Facet, the public key should in an uncompressed public key format", + "params": { + "_publicKey": "Bytes of public key for format check" + }, + "returns": { + "isValid": "Boolean variable representing if the format of public key is valid" + } + }, + "isValidSignature(bytes32,bytes)": { + "details": "This method verifies the signature if the owner indeed signed the hash. Returns magic value if true", + "params": { + "_hash": "Hash value the owner signed", + "_signature": "Signature that signed the above hash" + }, + "returns": { + "magicValue": "Bytes4 value representing the success/failure of validation" + } + }, + "owner()": { + "returns": { + "signer": "Bytes of owner address" + } + }, + "uninitializeSigner()": { + "details": "This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.", + "returns": { + "uninitSuccess": "Uint value representing the success of uninit operation" + } + }, + "validateOwnerSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32)": { + "details": "This method validates if the user operation is signed by the owner. It internally calls validateSignature with signer public key.", + "params": { + "userOp": "UserOperation including all information for execution", + "userOpHash": "Hash of UserOperation given from EntryPoint. This hash is used for signature validation" + }, + "returns": { + "validationData": "Uint value representing whether the validation is successful. 0 for success, 1 for failure" + } + }, + "validateOwnerSignatureSelector()": { + "returns": { + "ownerSignatureValidatorSelector": "Bytes4 selector of function signature to validate account owner's UserOperation signature" + } + }, + "validateSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256[2])": { + "details": "This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address", + "params": { + "q": "Public Key of signer who signed the contract, to be validated", + "userOp": "UserOperation including all information for execution", + "userOpHash": "Hash of UserOperation given from EntryPoint. This hash is used for signature validation" + }, + "returns": { + "isValid": "Uint value representing whether the validation is successful. 0 for success, 1 for failure" + } + } + }, + "title": "Secp256r1 verification facet", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "constructor": { + "notice": "This constructor ensures that this contract can only be used as singleton for Proxy contracts" + }, + "initializeSigner(bytes)": { + "notice": "Initializes the signer in R1 Facet Storage. This can only be called when the account is uninitialized or during signature migration." + }, + "isValidKeyType(bytes)": { + "notice": "Validates if the format of public key is valid for this verification facet" + }, + "isValidSignature(bytes32,bytes)": { + "notice": "Validates if the signature is valid. Function to be compatible with EIP-1271" + }, + "owner()": { + "notice": "Returns the owner of the account" + }, + "uninitializeSigner()": { + "notice": "Uninitialize signer in R1 Facet Storage. This can only be called when the account is undergoing signature migration and has already been initialized." + }, + "validateOwnerSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32)": { + "notice": "Validates if the user operation is signed by the owner." + }, + "validateOwnerSignatureSelector()": { + "notice": "Returns the selector of function to validate the signature of UserOperation" + }, + "validateSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256[2])": { + "notice": "Validates if the signature of UserOperation is signed by the given signer" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/bsc/TokenReceiverFacet.json b/deployments/bsc/TokenReceiverFacet.json new file mode 100644 index 0000000..f399cd1 --- /dev/null +++ b/deployments/bsc/TokenReceiverFacet.json @@ -0,0 +1,239 @@ +{ + "address": "0x3143E1C0Af0Cdc153423863923Cf4e3818e34Daa", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onERC1155BatchReceived", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onERC1155Received", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onERC721Received", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onTokenTransfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "tokensReceived", + "outputs": [], + "stateMutability": "pure", + "type": "function" + } + ], + "transactionHash": "0x6668484184644c2a5f201d3e3c29339f13fb8d838944b12afd3378c6dfed9664", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 6, + "gasUsed": "329340", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x4d5e42533d59d5368981521c5750a32c9df090bdecda933b05e2afd15f7e2b99", + "transactionHash": "0x6668484184644c2a5f201d3e3c29339f13fb8d838944b12afd3378c6dfed9664", + "logs": [], + "blockNumber": 32971451, + "cumulativeGasUsed": "1186729", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 3, + "solcInputHash": "0c861e53801b64e5ccc05669ea62a977", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onERC1155BatchReceived\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onERC1155Received\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onERC721Received\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"tokensReceived\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"Contract that enables receiving ERC721/ERC1155/ERC777/ERC677 Tokens with safe transfer\",\"kind\":\"dev\",\"methods\":{},\"title\":\"TokenReceiver Facet\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\":{\"notice\":\"Handles ERC1155 Token batch callback. return Standardized onERC1155BatchReceived return value.\"},\"onERC1155Received(address,address,uint256,uint256,bytes)\":{\"notice\":\"Handles ERC1155 Token callback. return Standardized onERC1155Received return value.\"},\"onERC721Received(address,address,uint256,bytes)\":{\"notice\":\"Handles ERC721 Token callback. return Standardized onERC721Received return value.\"},\"onTokenTransfer(address,uint256,bytes)\":{\"notice\":\"Handles ERC677 Token callback. return true.\"},\"tokensReceived(address,address,address,uint256,bytes,bytes)\":{\"notice\":\"Handles ERC777 Token callback. Does not return value, empty implementation.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/TokenReceiverFacet.sol\":\"TokenReceiverFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title ERC721 token receiver interface\\n * @dev Interface for any contract that wants to support safeTransfers\\n * from ERC721 asset contracts.\\n */\\ninterface IERC721Receiver {\\n /**\\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\\n * by `operator` from `from`, this function is called.\\n *\\n * It must return its Solidity selector to confirm the token transfer.\\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\\n *\\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\\n */\\n function onERC721Received(\\n address operator,\\n address from,\\n uint256 tokenId,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\\n *\\n * Accounts can be notified of {IERC777} tokens being sent to them by having a\\n * contract implement this interface (contract holders can be their own\\n * implementer) and registering it on the\\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\\n *\\n * See {IERC1820Registry} and {ERC1820Implementer}.\\n */\\ninterface IERC777Recipient {\\n /**\\n * @dev Called by an {IERC777} token contract whenever tokens are being\\n * moved or created into a registered account (`to`). The type of operation\\n * is conveyed by `from` being the zero address or not.\\n *\\n * This call occurs _after_ the token contract's state is updated, so\\n * {IERC777-balanceOf}, etc., can be used to query the post-operation state.\\n *\\n * This function may revert to prevent the operation from being executed.\\n */\\n function tokensReceived(\\n address operator,\\n address from,\\n address to,\\n uint256 amount,\\n bytes calldata userData,\\n bytes calldata operatorData\\n ) external;\\n}\\n\",\"keccak256\":\"0x1a5d61db2733202ba361e6d6741cd2e662380e22b80e987eacfc91973f2267dc\",\"license\":\"MIT\"},\"contracts/facets/TokenReceiverFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IERC721Receiver} from \\\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\\\";\\nimport {IERC777Recipient} from \\\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\\\";\\nimport {IERC1155Receiver} from \\\"../interfaces/ERC/IERC1155Receiver.sol\\\";\\nimport {IERC677Receiver} from \\\"../interfaces/ERC/IERC677Receiver.sol\\\";\\n\\n/**\\n * @title TokenReceiver Facet\\n * @dev Contract that enables receiving ERC721/ERC1155/ERC777/ERC677 Tokens with safe transfer\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract TokenReceiverFacet is\\n IERC721Receiver,\\n IERC1155Receiver,\\n IERC777Recipient,\\n IERC677Receiver\\n{\\n /**\\n * @notice Handles ERC721 Token callback.\\n * return Standardized onERC721Received return value.\\n */\\n function onERC721Received(\\n address,\\n address,\\n uint256,\\n bytes calldata\\n ) external pure override returns (bytes4) {\\n return IERC721Receiver.onERC721Received.selector;\\n }\\n\\n /**\\n * @notice Handles ERC1155 Token callback.\\n * return Standardized onERC1155Received return value.\\n */\\n function onERC1155Received(\\n address,\\n address,\\n uint256,\\n uint256,\\n bytes calldata\\n ) external pure override returns (bytes4) {\\n return IERC1155Receiver.onERC1155Received.selector;\\n }\\n\\n /**\\n * @notice Handles ERC1155 Token batch callback.\\n * return Standardized onERC1155BatchReceived return value.\\n */\\n function onERC1155BatchReceived(\\n address,\\n address,\\n uint256[] calldata,\\n uint256[] calldata,\\n bytes calldata\\n ) external pure override returns (bytes4) {\\n return IERC1155Receiver.onERC1155BatchReceived.selector;\\n }\\n\\n /**\\n * @notice Handles ERC777 Token callback.\\n * Does not return value, empty implementation.\\n */\\n function tokensReceived(\\n address,\\n address,\\n address,\\n uint256,\\n bytes calldata,\\n bytes calldata\\n ) external pure override {}\\n\\n /**\\n * @notice Handles ERC677 Token callback.\\n * return true.\\n */\\n function onTokenTransfer(\\n address,\\n uint256,\\n bytes calldata\\n ) external pure override returns (bool) {\\n return true;\\n }\\n}\\n\",\"keccak256\":\"0xdfe483d05ef4056bb464c34ade19ab527687aff3ed0b6303b447a68b5ff7abb4\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC1155Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\n\\npragma solidity 0.8.21;\\n\\n/**\\n * @dev _Available since v3.1._\\n */\\ninterface IERC1155Receiver {\\n /**\\n * @dev Handles the receipt of a single ERC1155 token type. This function is\\n * called at the end of a `safeTransferFrom` after the balance has been updated.\\n *\\n * NOTE: To accept the transfer, this must return\\n * `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))`\\n * (i.e. 0xf23a6e61, or its own function selector).\\n *\\n * @param operator The address which initiated the transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param id The ID of the token being transferred\\n * @param value The amount of tokens being transferred\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155Received(\\n address operator,\\n address from,\\n uint256 id,\\n uint256 value,\\n bytes calldata data\\n ) external returns (bytes4);\\n\\n /**\\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\\n * is called at the end of a `safeBatchTransferFrom` after the balances have\\n * been updated.\\n *\\n * NOTE: To accept the transfer(s), this must return\\n * `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))`\\n * (i.e. 0xbc197c81, or its own function selector).\\n *\\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155BatchReceived(\\n address operator,\\n address from,\\n uint256[] calldata ids,\\n uint256[] calldata values,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0x3729c6757bae3aba03ac1c5064d67ad13b94e2a9428bf44b9be510373406da0c\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC677Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC677Receiver {\\n function onTokenTransfer(\\n address sender,\\n uint value,\\n bytes calldata data\\n ) external pure returns (bool);\\n}\\n\",\"keccak256\":\"0x4c1631cf45ea6daac0ec158c3edb9453099130b6b64f697004b83f95aa1f7350\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50610502806100206000396000f3fe608060405234801561001057600080fd5b50600436106100665760003560e01c8063a4c0ed3611610050578063a4c0ed36146100f3578063bc197c811461011b578063f23a6e611461015657600080fd5b806223de291461006b578063150b7a0214610085575b600080fd5b610083610079366004610201565b5050505050505050565b005b6100bd6100933660046102ac565b7f150b7a020000000000000000000000000000000000000000000000000000000095945050505050565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020015b60405180910390f35b61010b61010136600461031b565b6001949350505050565b60405190151581526020016100ea565b6100bd6101293660046103ba565b7fbc197c810000000000000000000000000000000000000000000000000000000098975050505050505050565b6100bd610164366004610454565b7ff23a6e61000000000000000000000000000000000000000000000000000000009695505050505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146101b357600080fd5b919050565b60008083601f8401126101ca57600080fd5b50813567ffffffffffffffff8111156101e257600080fd5b6020830191508360208285010111156101fa57600080fd5b9250929050565b60008060008060008060008060c0898b03121561021d57600080fd5b6102268961018f565b975061023460208a0161018f565b965061024260408a0161018f565b955060608901359450608089013567ffffffffffffffff8082111561026657600080fd5b6102728c838d016101b8565b909650945060a08b013591508082111561028b57600080fd5b506102988b828c016101b8565b999c989b5096995094979396929594505050565b6000806000806000608086880312156102c457600080fd5b6102cd8661018f565b94506102db6020870161018f565b935060408601359250606086013567ffffffffffffffff8111156102fe57600080fd5b61030a888289016101b8565b969995985093965092949392505050565b6000806000806060858703121561033157600080fd5b61033a8561018f565b935060208501359250604085013567ffffffffffffffff81111561035d57600080fd5b610369878288016101b8565b95989497509550505050565b60008083601f84011261038757600080fd5b50813567ffffffffffffffff81111561039f57600080fd5b6020830191508360208260051b85010111156101fa57600080fd5b60008060008060008060008060a0898b0312156103d657600080fd5b6103df8961018f565b97506103ed60208a0161018f565b9650604089013567ffffffffffffffff8082111561040a57600080fd5b6104168c838d01610375565b909850965060608b013591508082111561042f57600080fd5b61043b8c838d01610375565b909650945060808b013591508082111561028b57600080fd5b60008060008060008060a0878903121561046d57600080fd5b6104768761018f565b95506104846020880161018f565b94506040870135935060608701359250608087013567ffffffffffffffff8111156104ae57600080fd5b6104ba89828a016101b8565b979a969950949750929593949250505056fea2646970667358221220ae9a97061ae9e1485161ca9c8d3228a23e47b18755fa935f51b40e927816ca2964736f6c63430008150033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100665760003560e01c8063a4c0ed3611610050578063a4c0ed36146100f3578063bc197c811461011b578063f23a6e611461015657600080fd5b806223de291461006b578063150b7a0214610085575b600080fd5b610083610079366004610201565b5050505050505050565b005b6100bd6100933660046102ac565b7f150b7a020000000000000000000000000000000000000000000000000000000095945050505050565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020015b60405180910390f35b61010b61010136600461031b565b6001949350505050565b60405190151581526020016100ea565b6100bd6101293660046103ba565b7fbc197c810000000000000000000000000000000000000000000000000000000098975050505050505050565b6100bd610164366004610454565b7ff23a6e61000000000000000000000000000000000000000000000000000000009695505050505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146101b357600080fd5b919050565b60008083601f8401126101ca57600080fd5b50813567ffffffffffffffff8111156101e257600080fd5b6020830191508360208285010111156101fa57600080fd5b9250929050565b60008060008060008060008060c0898b03121561021d57600080fd5b6102268961018f565b975061023460208a0161018f565b965061024260408a0161018f565b955060608901359450608089013567ffffffffffffffff8082111561026657600080fd5b6102728c838d016101b8565b909650945060a08b013591508082111561028b57600080fd5b506102988b828c016101b8565b999c989b5096995094979396929594505050565b6000806000806000608086880312156102c457600080fd5b6102cd8661018f565b94506102db6020870161018f565b935060408601359250606086013567ffffffffffffffff8111156102fe57600080fd5b61030a888289016101b8565b969995985093965092949392505050565b6000806000806060858703121561033157600080fd5b61033a8561018f565b935060208501359250604085013567ffffffffffffffff81111561035d57600080fd5b610369878288016101b8565b95989497509550505050565b60008083601f84011261038757600080fd5b50813567ffffffffffffffff81111561039f57600080fd5b6020830191508360208260051b85010111156101fa57600080fd5b60008060008060008060008060a0898b0312156103d657600080fd5b6103df8961018f565b97506103ed60208a0161018f565b9650604089013567ffffffffffffffff8082111561040a57600080fd5b6104168c838d01610375565b909850965060608b013591508082111561042f57600080fd5b61043b8c838d01610375565b909650945060808b013591508082111561028b57600080fd5b60008060008060008060a0878903121561046d57600080fd5b6104768761018f565b95506104846020880161018f565b94506040870135935060608701359250608087013567ffffffffffffffff8111156104ae57600080fd5b6104ba89828a016101b8565b979a969950949750929593949250505056fea2646970667358221220ae9a97061ae9e1485161ca9c8d3228a23e47b18755fa935f51b40e927816ca2964736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "Contract that enables receiving ERC721/ERC1155/ERC777/ERC677 Tokens with safe transfer", + "kind": "dev", + "methods": {}, + "title": "TokenReceiver Facet", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)": { + "notice": "Handles ERC1155 Token batch callback. return Standardized onERC1155BatchReceived return value." + }, + "onERC1155Received(address,address,uint256,uint256,bytes)": { + "notice": "Handles ERC1155 Token callback. return Standardized onERC1155Received return value." + }, + "onERC721Received(address,address,uint256,bytes)": { + "notice": "Handles ERC721 Token callback. return Standardized onERC721Received return value." + }, + "onTokenTransfer(address,uint256,bytes)": { + "notice": "Handles ERC677 Token callback. return true." + }, + "tokensReceived(address,address,address,uint256,bytes,bytes)": { + "notice": "Handles ERC777 Token callback. Does not return value, empty implementation." + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/bsc/solcInputs/0c861e53801b64e5ccc05669ea62a977.json b/deployments/bsc/solcInputs/0c861e53801b64e5ccc05669ea62a977.json new file mode 100644 index 0000000..47e9456 --- /dev/null +++ b/deployments/bsc/solcInputs/0c861e53801b64e5ccc05669ea62a977.json @@ -0,0 +1,354 @@ +{ + "language": "Solidity", + "sources": { + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby disabling any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable2Step.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./Ownable.sol\";\n\n/**\n * @dev Contract module which provides access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership} and {acceptOwnership}.\n *\n * This module is used through inheritance. It will make available all functions\n * from parent (Ownable).\n */\nabstract contract Ownable2Step is Ownable {\n address private _pendingOwner;\n\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Returns the address of the pending owner.\n */\n function pendingOwner() public view virtual returns (address) {\n return _pendingOwner;\n }\n\n /**\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual override onlyOwner {\n _pendingOwner = newOwner;\n emit OwnershipTransferStarted(owner(), newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual override {\n delete _pendingOwner;\n super._transferOwnership(newOwner);\n }\n\n /**\n * @dev The new owner accepts the ownership transfer.\n */\n function acceptOwnership() public virtual {\n address sender = _msgSender();\n require(pendingOwner() == sender, \"Ownable2Step: caller is not the new owner\");\n _transferOwnership(sender);\n }\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC1271.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC1271 standard signature validation method for\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\n *\n * _Available since v4.1._\n */\ninterface IERC1271 {\n /**\n * @dev Should return whether the signature provided is valid for the provided data\n * @param hash Hash of the data to be signed\n * @param signature Signature byte array associated with _data\n */\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\n}\n" + }, + "@openzeppelin/contracts/security/ReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor() {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n _nonReentrantBefore();\n _;\n _nonReentrantAfter();\n }\n\n function _nonReentrantBefore() private {\n // On the first call to nonReentrant, _status will be _NOT_ENTERED\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n }\n\n function _nonReentrantAfter() private {\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Returns true if the reentrancy guard is currently set to \"entered\", which indicates there is a\n * `nonReentrant` function in the call stack.\n */\n function _reentrancyGuardEntered() internal view returns (bool) {\n return _status == _ENTERED;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/ERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/ERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC1155.sol\";\nimport \"./IERC1155Receiver.sol\";\nimport \"./extensions/IERC1155MetadataURI.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of the basic standard multi-token.\n * See https://eips.ethereum.org/EIPS/eip-1155\n * Originally based on code by Enjin: https://github.com/enjin/erc-1155\n *\n * _Available since v3.1._\n */\ncontract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {\n using Address for address;\n\n // Mapping from token ID to account balances\n mapping(uint256 => mapping(address => uint256)) private _balances;\n\n // Mapping from account to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json\n string private _uri;\n\n /**\n * @dev See {_setURI}.\n */\n constructor(string memory uri_) {\n _setURI(uri_);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return\n interfaceId == type(IERC1155).interfaceId ||\n interfaceId == type(IERC1155MetadataURI).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC1155MetadataURI-uri}.\n *\n * This implementation returns the same URI for *all* token types. It relies\n * on the token type ID substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * Clients calling this function must replace the `\\{id\\}` substring with the\n * actual token type ID.\n */\n function uri(uint256) public view virtual override returns (string memory) {\n return _uri;\n }\n\n /**\n * @dev See {IERC1155-balanceOf}.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {\n require(account != address(0), \"ERC1155: address zero is not a valid owner\");\n return _balances[id][account];\n }\n\n /**\n * @dev See {IERC1155-balanceOfBatch}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] memory accounts,\n uint256[] memory ids\n ) public view virtual override returns (uint256[] memory) {\n require(accounts.length == ids.length, \"ERC1155: accounts and ids length mismatch\");\n\n uint256[] memory batchBalances = new uint256[](accounts.length);\n\n for (uint256 i = 0; i < accounts.length; ++i) {\n batchBalances[i] = balanceOf(accounts[i], ids[i]);\n }\n\n return batchBalances;\n }\n\n /**\n * @dev See {IERC1155-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC1155-isApprovedForAll}.\n */\n function isApprovedForAll(address account, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[account][operator];\n }\n\n /**\n * @dev See {IERC1155-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n _safeTransferFrom(from, to, id, amount, data);\n }\n\n /**\n * @dev See {IERC1155-safeBatchTransferFrom}.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n _safeBatchTransferFrom(from, to, ids, amounts, data);\n }\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n\n emit TransferSingle(operator, from, to, id, amount);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n for (uint256 i = 0; i < ids.length; ++i) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n }\n\n emit TransferBatch(operator, from, to, ids, amounts);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\n\n _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);\n }\n\n /**\n * @dev Sets a new URI for all token types, by relying on the token type ID\n * substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * By this mechanism, any occurrence of the `\\{id\\}` substring in either the\n * URI or any of the amounts in the JSON file at said URI will be replaced by\n * clients with the token type ID.\n *\n * For example, the `https://token-cdn-domain/\\{id\\}.json` URI would be\n * interpreted by clients as\n * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`\n * for token type ID 0x4cce0.\n *\n * See {uri}.\n *\n * Because these URIs cannot be meaningfully represented by the {URI} event,\n * this function emits no events.\n */\n function _setURI(string memory newuri) internal virtual {\n _uri = newuri;\n }\n\n /**\n * @dev Creates `amount` tokens of token type `id`, and assigns them to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _mint(address to, uint256 id, uint256 amount, bytes memory data) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _balances[id][to] += amount;\n emit TransferSingle(operator, address(0), to, id, amount);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n for (uint256 i = 0; i < ids.length; i++) {\n _balances[ids[i]][to] += amounts[i];\n }\n\n emit TransferBatch(operator, address(0), to, ids, amounts);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);\n }\n\n /**\n * @dev Destroys `amount` tokens of token type `id` from `from`\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `from` must have at least `amount` tokens of token type `id`.\n */\n function _burn(address from, uint256 id, uint256 amount) internal virtual {\n require(from != address(0), \"ERC1155: burn from the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n\n emit TransferSingle(operator, from, address(0), id, amount);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n */\n function _burnBatch(address from, uint256[] memory ids, uint256[] memory amounts) internal virtual {\n require(from != address(0), \"ERC1155: burn from the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n\n for (uint256 i = 0; i < ids.length; i++) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n }\n\n emit TransferBatch(operator, from, address(0), ids, amounts);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {\n require(owner != operator, \"ERC1155: setting approval status for self\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning, as well as batched variants.\n *\n * The same hook is called on both single and batched variants. For single\n * transfers, the length of the `ids` and `amounts` arrays will be 1.\n *\n * Calling conditions (for each `id` and `amount` pair):\n *\n * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * of token type `id` will be transferred to `to`.\n * - When `from` is zero, `amount` tokens of token type `id` will be minted\n * for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n * will be burned.\n * - `from` and `to` are never both zero.\n * - `ids` and `amounts` have the same, non-zero length.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any token transfer. This includes minting\n * and burning, as well as batched variants.\n *\n * The same hook is called on both single and batched variants. For single\n * transfers, the length of the `id` and `amount` arrays will be 1.\n *\n * Calling conditions (for each `id` and `amount` pair):\n *\n * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * of token type `id` will be transferred to `to`.\n * - When `from` is zero, `amount` tokens of token type `id` will be minted\n * for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n * will be burned.\n * - `from` and `to` are never both zero.\n * - `ids` and `amounts` have the same, non-zero length.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {}\n\n function _doSafeTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155Receiver.onERC1155Received.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non-ERC1155Receiver implementer\");\n }\n }\n }\n\n function _doSafeBatchTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (\n bytes4 response\n ) {\n if (response != IERC1155Receiver.onERC1155BatchReceived.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non-ERC1155Receiver implementer\");\n }\n }\n }\n\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {\n uint256[] memory array = new uint256[](1);\n array[0] = element;\n\n return array;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC1155.sol\";\n\n/**\n * @dev Interface of the optional ERC1155MetadataExtension interface, as defined\n * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155MetadataURI is IERC1155 {\n /**\n * @dev Returns the URI for token type `id`.\n *\n * If the `\\{id\\}` substring is present in the URI, it must be replaced by\n * clients with the actual token type ID.\n */\n function uri(uint256 id) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155 is IERC165 {\n /**\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n */\n event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);\n\n /**\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n * transfers.\n */\n event TransferBatch(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\n\n /**\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n * `approved`.\n */\n event ApprovalForAll(address indexed account, address indexed operator, bool approved);\n\n /**\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n *\n * If an {URI} event was emitted for `id`, the standard\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n * returned by {IERC1155MetadataURI-uri}.\n */\n event URI(string value, uint256 indexed id);\n\n /**\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) external view returns (uint256);\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] calldata accounts,\n uint256[] calldata ids\n ) external view returns (uint256[] memory);\n\n /**\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n *\n * Emits an {ApprovalForAll} event.\n *\n * Requirements:\n *\n * - `operator` cannot be the caller.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n *\n * See {setApprovalForAll}.\n */\n function isApprovedForAll(address account, address operator) external view returns (bool);\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155Receiver is IERC165 {\n /**\n * @dev Handles the receipt of a single ERC1155 token type. This function is\n * called at the end of a `safeTransferFrom` after the balance has been updated.\n *\n * NOTE: To accept the transfer, this must return\n * `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n * (i.e. 0xf23a6e61, or its own function selector).\n *\n * @param operator The address which initiated the transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param id The ID of the token being transferred\n * @param value The amount of tokens being transferred\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n ) external returns (bytes4);\n\n /**\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\n * is called at the end of a `safeBatchTransferFrom` after the balances have\n * been updated.\n *\n * NOTE: To accept the transfer(s), this must return\n * `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n * (i.e. 0xbc197c81, or its own function selector).\n *\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the default value returned by this function, unless\n * it's overridden.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(address from, address to, uint256 amount) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\n // decrementing then incrementing.\n _balances[to] += amount;\n }\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n unchecked {\n // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\n _balances[account] += amount;\n }\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n // Overflow not possible: amount <= accountBalance <= totalSupply.\n _totalSupply -= amount;\n }\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\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" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` 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 amount) 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 `amount` as the allowance of `spender` over the 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 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` 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 amount) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/ERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721.sol\";\nimport \"./IERC721Receiver.sol\";\nimport \"./extensions/IERC721Metadata.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/Strings.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\n using Address for address;\n using Strings for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\n\n // Mapping from token ID to approved address\n mapping(uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return\n interfaceId == type(IERC721).interfaceId ||\n interfaceId == type(IERC721Metadata).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _ownerOf(tokenId);\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token owner or approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n _requireMinted(tokenId);\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n _safeTransfer(from, to, tokenId, data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(address from, address to, uint256 tokenId, bytes memory data) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist\n */\n function _ownerOf(uint256 tokenId) internal view virtual returns (address) {\n return _owners[tokenId];\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _ownerOf(tokenId) != address(0);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n address owner = ERC721.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(address to, uint256 tokenId, bytes memory data) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId, 1);\n\n // Check that tokenId was not minted by `_beforeTokenTransfer` hook\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n unchecked {\n // Will not overflow unless all 2**256 token ids are minted to the same owner.\n // Given that tokens are minted one by one, it is impossible in practice that\n // this ever happens. Might change if we allow batch minting.\n // The ERC fails to describe this case.\n _balances[to] += 1;\n }\n\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(address(0), to, tokenId, 1);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n * This is an internal function that does not check if the sender is authorized to operate on the token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId, 1);\n\n // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook\n owner = ERC721.ownerOf(tokenId);\n\n // Clear approvals\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // Cannot overflow, as that would require more tokens to be burned/transferred\n // out than the owner initially received through minting and transferring in.\n _balances[owner] -= 1;\n }\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(owner, address(0), tokenId, 1);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(address from, address to, uint256 tokenId) internal virtual {\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId, 1);\n\n // Check that tokenId was not transferred by `_beforeTokenTransfer` hook\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n\n // Clear approvals from the previous owner\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // `_balances[from]` cannot overflow for the same reason as described in `_burn`:\n // `from`'s balance is the number of token held, which is at least one before the current\n // transfer.\n // `_balances[to]` could overflow in the conditions described in `_mint`. That would require\n // all 2**256 token ids to be minted, which in practice is impossible.\n _balances[from] -= 1;\n _balances[to] += 1;\n }\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId, 1);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721Receiver.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`.\n * - When `from` is zero, the tokens will be minted for `to`.\n * - When `to` is zero, ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}\n\n /**\n * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`.\n * - When `from` is zero, the tokens were minted for `to`.\n * - When `to` is zero, ``from``'s tokens were burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}\n\n /**\n * @dev Unsafe write access to the balances, used by extensions that \"mint\" tokens using an {ownerOf} override.\n *\n * WARNING: Anyone calling this MUST ensure that the balances remain consistent with the ownership. The invariant\n * being that for any address `a` the value returned by `balanceOf(a)` must be equal to the number of tokens such\n * that `ownerOf(tokenId)` is `a`.\n */\n // solhint-disable-next-line func-name-mixedcase\n function __unsafe_increaseBalance(address account, uint256 amount) internal {\n _balances[account] += amount;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721Receiver {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/ERC777.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC777/ERC777.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC777.sol\";\nimport \"./IERC777Recipient.sol\";\nimport \"./IERC777Sender.sol\";\nimport \"../ERC20/IERC20.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/introspection/IERC1820Registry.sol\";\n\n/**\n * @dev Implementation of the {IERC777} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n *\n * Support for ERC20 is included in this contract, as specified by the EIP: both\n * the ERC777 and ERC20 interfaces can be safely used when interacting with it.\n * Both {IERC777-Sent} and {IERC20-Transfer} events are emitted on token\n * movements.\n *\n * Additionally, the {IERC777-granularity} value is hard-coded to `1`, meaning that there\n * are no special restrictions in the amount of tokens that created, moved, or\n * destroyed. This makes integration with ERC20 applications seamless.\n *\n * CAUTION: This file is deprecated as of v4.9 and will be removed in the next major release.\n */\ncontract ERC777 is Context, IERC777, IERC20 {\n using Address for address;\n\n IERC1820Registry internal constant _ERC1820_REGISTRY = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n mapping(address => uint256) private _balances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n bytes32 private constant _TOKENS_SENDER_INTERFACE_HASH = keccak256(\"ERC777TokensSender\");\n bytes32 private constant _TOKENS_RECIPIENT_INTERFACE_HASH = keccak256(\"ERC777TokensRecipient\");\n\n // This isn't ever read from - it's only used to respond to the defaultOperators query.\n address[] private _defaultOperatorsArray;\n\n // Immutable, but accounts may revoke them (tracked in __revokedDefaultOperators).\n mapping(address => bool) private _defaultOperators;\n\n // For each account, a mapping of its operators and revoked default operators.\n mapping(address => mapping(address => bool)) private _operators;\n mapping(address => mapping(address => bool)) private _revokedDefaultOperators;\n\n // ERC20-allowances\n mapping(address => mapping(address => uint256)) private _allowances;\n\n /**\n * @dev `defaultOperators` may be an empty array.\n */\n constructor(string memory name_, string memory symbol_, address[] memory defaultOperators_) {\n _name = name_;\n _symbol = symbol_;\n\n _defaultOperatorsArray = defaultOperators_;\n for (uint256 i = 0; i < defaultOperators_.length; i++) {\n _defaultOperators[defaultOperators_[i]] = true;\n }\n\n // register interfaces\n _ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256(\"ERC777Token\"), address(this));\n _ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256(\"ERC20Token\"), address(this));\n }\n\n /**\n * @dev See {IERC777-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC777-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {ERC20-decimals}.\n *\n * Always returns 18, as per the\n * [ERC777 EIP](https://eips.ethereum.org/EIPS/eip-777#backward-compatibility).\n */\n function decimals() public pure virtual returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC777-granularity}.\n *\n * This implementation always returns `1`.\n */\n function granularity() public view virtual override returns (uint256) {\n return 1;\n }\n\n /**\n * @dev See {IERC777-totalSupply}.\n */\n function totalSupply() public view virtual override(IERC20, IERC777) returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev Returns the amount of tokens owned by an account (`tokenHolder`).\n */\n function balanceOf(address tokenHolder) public view virtual override(IERC20, IERC777) returns (uint256) {\n return _balances[tokenHolder];\n }\n\n /**\n * @dev See {IERC777-send}.\n *\n * Also emits a {IERC20-Transfer} event for ERC20 compatibility.\n */\n function send(address recipient, uint256 amount, bytes memory data) public virtual override {\n _send(_msgSender(), recipient, amount, data, \"\", true);\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Unlike `send`, `recipient` is _not_ required to implement the {IERC777Recipient}\n * interface if it is a contract.\n *\n * Also emits a {Sent} event.\n */\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n _send(_msgSender(), recipient, amount, \"\", \"\", false);\n return true;\n }\n\n /**\n * @dev See {IERC777-burn}.\n *\n * Also emits a {IERC20-Transfer} event for ERC20 compatibility.\n */\n function burn(uint256 amount, bytes memory data) public virtual override {\n _burn(_msgSender(), amount, data, \"\");\n }\n\n /**\n * @dev See {IERC777-isOperatorFor}.\n */\n function isOperatorFor(address operator, address tokenHolder) public view virtual override returns (bool) {\n return\n operator == tokenHolder ||\n (_defaultOperators[operator] && !_revokedDefaultOperators[tokenHolder][operator]) ||\n _operators[tokenHolder][operator];\n }\n\n /**\n * @dev See {IERC777-authorizeOperator}.\n */\n function authorizeOperator(address operator) public virtual override {\n require(_msgSender() != operator, \"ERC777: authorizing self as operator\");\n\n if (_defaultOperators[operator]) {\n delete _revokedDefaultOperators[_msgSender()][operator];\n } else {\n _operators[_msgSender()][operator] = true;\n }\n\n emit AuthorizedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-revokeOperator}.\n */\n function revokeOperator(address operator) public virtual override {\n require(operator != _msgSender(), \"ERC777: revoking self as operator\");\n\n if (_defaultOperators[operator]) {\n _revokedDefaultOperators[_msgSender()][operator] = true;\n } else {\n delete _operators[_msgSender()][operator];\n }\n\n emit RevokedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-defaultOperators}.\n */\n function defaultOperators() public view virtual override returns (address[] memory) {\n return _defaultOperatorsArray;\n }\n\n /**\n * @dev See {IERC777-operatorSend}.\n *\n * Emits {Sent} and {IERC20-Transfer} events.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes memory data,\n bytes memory operatorData\n ) public virtual override {\n require(isOperatorFor(_msgSender(), sender), \"ERC777: caller is not an operator for holder\");\n _send(sender, recipient, amount, data, operatorData, true);\n }\n\n /**\n * @dev See {IERC777-operatorBurn}.\n *\n * Emits {Burned} and {IERC20-Transfer} events.\n */\n function operatorBurn(\n address account,\n uint256 amount,\n bytes memory data,\n bytes memory operatorData\n ) public virtual override {\n require(isOperatorFor(_msgSender(), account), \"ERC777: caller is not an operator for holder\");\n _burn(account, amount, data, operatorData);\n }\n\n /**\n * @dev See {IERC20-allowance}.\n *\n * Note that operator and allowance concepts are orthogonal: operators may\n * not have allowance, and accounts with allowance may not be operators\n * themselves.\n */\n function allowance(address holder, address spender) public view virtual override returns (uint256) {\n return _allowances[holder][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Note that accounts cannot have allowance issued by their operators.\n */\n function approve(address spender, uint256 value) public virtual override returns (bool) {\n address holder = _msgSender();\n _approve(holder, spender, value);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Note that operator and allowance concepts are orthogonal: operators cannot\n * call `transferFrom` (unless they have allowance), and accounts with\n * allowance cannot call `operatorSend` (unless they are operators).\n *\n * Emits {Sent}, {IERC20-Transfer} and {IERC20-Approval} events.\n */\n function transferFrom(address holder, address recipient, uint256 amount) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(holder, spender, amount);\n _send(holder, recipient, amount, \"\", \"\", false);\n return true;\n }\n\n /**\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with the caller address as the `operator` and with\n * `userData` and `operatorData`.\n *\n * See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits {Minted} and {IERC20-Transfer} events.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - if `account` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function _mint(address account, uint256 amount, bytes memory userData, bytes memory operatorData) internal virtual {\n _mint(account, amount, userData, operatorData, true);\n }\n\n /**\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * If `requireReceptionAck` is set to true, and if a send hook is\n * registered for `account`, the corresponding function will be called with\n * `operator`, `data` and `operatorData`.\n *\n * See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits {Minted} and {IERC20-Transfer} events.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - if `account` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function _mint(\n address account,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) internal virtual {\n require(account != address(0), \"ERC777: mint to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), account, amount);\n\n // Update state variables\n _totalSupply += amount;\n _balances[account] += amount;\n\n _callTokensReceived(operator, address(0), account, amount, userData, operatorData, requireReceptionAck);\n\n emit Minted(operator, account, amount, userData, operatorData);\n emit Transfer(address(0), account, amount);\n }\n\n /**\n * @dev Send tokens\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _send(\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) internal virtual {\n require(from != address(0), \"ERC777: transfer from the zero address\");\n require(to != address(0), \"ERC777: transfer to the zero address\");\n\n address operator = _msgSender();\n\n _callTokensToSend(operator, from, to, amount, userData, operatorData);\n\n _move(operator, from, to, amount, userData, operatorData);\n\n _callTokensReceived(operator, from, to, amount, userData, operatorData, requireReceptionAck);\n }\n\n /**\n * @dev Burn tokens\n * @param from address token holder address\n * @param amount uint256 amount of tokens to burn\n * @param data bytes extra information provided by the token holder\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _burn(address from, uint256 amount, bytes memory data, bytes memory operatorData) internal virtual {\n require(from != address(0), \"ERC777: burn from the zero address\");\n\n address operator = _msgSender();\n\n _callTokensToSend(operator, from, address(0), amount, data, operatorData);\n\n _beforeTokenTransfer(operator, from, address(0), amount);\n\n // Update state variables\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC777: burn amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Burned(operator, from, amount, data, operatorData);\n emit Transfer(from, address(0), amount);\n }\n\n function _move(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n ) private {\n _beforeTokenTransfer(operator, from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC777: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Sent(operator, from, to, amount, userData, operatorData);\n emit Transfer(from, to, amount);\n }\n\n /**\n * @dev See {ERC20-_approve}.\n *\n * Note that accounts cannot have allowance issued by their operators.\n */\n function _approve(address holder, address spender, uint256 value) internal virtual {\n require(holder != address(0), \"ERC777: approve from the zero address\");\n require(spender != address(0), \"ERC777: approve to the zero address\");\n\n _allowances[holder][spender] = value;\n emit Approval(holder, spender, value);\n }\n\n /**\n * @dev Call from.tokensToSend() if the interface is registered\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _callTokensToSend(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n ) private {\n address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(from, _TOKENS_SENDER_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Sender(implementer).tokensToSend(operator, from, to, amount, userData, operatorData);\n }\n }\n\n /**\n * @dev Call to.tokensReceived() if the interface is registered. Reverts if the recipient is a contract but\n * tokensReceived() was not registered for the recipient\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _callTokensReceived(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) private {\n address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(to, _TOKENS_RECIPIENT_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Recipient(implementer).tokensReceived(operator, from, to, amount, userData, operatorData);\n } else if (requireReceptionAck) {\n require(!to.isContract(), \"ERC777: token recipient contract has no implementer for ERC777TokensRecipient\");\n }\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {IERC20-Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC777: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes\n * calls to {send}, {transfer}, {operatorSend}, {transferFrom}, minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be to transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address operator, address from, address to, uint256 amount) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC777/IERC777.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777Token standard as defined in the EIP.\n *\n * This contract uses the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 registry standard] to let\n * token holders and recipients react to token movements by using setting implementers\n * for the associated interfaces in said registry. See {IERC1820Registry} and\n * {ERC1820Implementer}.\n */\ninterface IERC777 {\n /**\n * @dev Emitted when `amount` tokens are created by `operator` and assigned to `to`.\n *\n * Note that some additional user `data` and `operatorData` can be logged in the event.\n */\n event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);\n\n /**\n * @dev Emitted when `operator` destroys `amount` tokens from `account`.\n *\n * Note that some additional user `data` and `operatorData` can be logged in the event.\n */\n event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);\n\n /**\n * @dev Emitted when `operator` is made operator for `tokenHolder`.\n */\n event AuthorizedOperator(address indexed operator, address indexed tokenHolder);\n\n /**\n * @dev Emitted when `operator` is revoked its operator status for `tokenHolder`.\n */\n event RevokedOperator(address indexed operator, address indexed tokenHolder);\n\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, usually a shorter version of the\n * name.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the smallest part of the token that is not divisible. This\n * means all token operations (creation, movement and destruction) must have\n * amounts that are a multiple of this number.\n *\n * For most token contracts, this value will equal 1.\n */\n function granularity() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by an account (`owner`).\n */\n function balanceOf(address owner) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * If send or receive hooks are registered for the caller and `recipient`,\n * the corresponding functions will be called with `data` and empty\n * `operatorData`. See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits a {Sent} event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function send(address recipient, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Destroys `amount` tokens from the caller's account, reducing the\n * total supply.\n *\n * If a send hook is registered for the caller, the corresponding function\n * will be called with `data` and empty `operatorData`. See {IERC777Sender}.\n *\n * Emits a {Burned} event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n */\n function burn(uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Returns true if an account is an operator of `tokenHolder`.\n * Operators can send and burn tokens on behalf of their owners. All\n * accounts are their own operator.\n *\n * See {operatorSend} and {operatorBurn}.\n */\n function isOperatorFor(address operator, address tokenHolder) external view returns (bool);\n\n /**\n * @dev Make an account an operator of the caller.\n *\n * See {isOperatorFor}.\n *\n * Emits an {AuthorizedOperator} event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function authorizeOperator(address operator) external;\n\n /**\n * @dev Revoke an account's operator status for the caller.\n *\n * See {isOperatorFor} and {defaultOperators}.\n *\n * Emits a {RevokedOperator} event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function revokeOperator(address operator) external;\n\n /**\n * @dev Returns the list of default operators. These accounts are operators\n * for all token holders, even if {authorizeOperator} was never called on\n * them.\n *\n * This list is immutable, but individual holders may revoke these via\n * {revokeOperator}, in which case {isOperatorFor} will return false.\n */\n function defaultOperators() external view returns (address[] memory);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must\n * be an operator of `sender`.\n *\n * If send or receive hooks are registered for `sender` and `recipient`,\n * the corresponding functions will be called with `data` and\n * `operatorData`. See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits a {Sent} event.\n *\n * Requirements\n *\n * - `sender` cannot be the zero address.\n * - `sender` must have at least `amount` tokens.\n * - the caller must be an operator for `sender`.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes calldata data,\n bytes calldata operatorData\n ) external;\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the total supply.\n * The caller must be an operator of `account`.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with `data` and `operatorData`. See {IERC777Sender}.\n *\n * Emits a {Burned} event.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n * - the caller must be an operator for `account`.\n */\n function operatorBurn(address account, uint256 amount, bytes calldata data, bytes calldata operatorData) external;\n\n event Sent(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes data,\n bytes operatorData\n );\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\n *\n * Accounts can be notified of {IERC777} tokens being sent to them by having a\n * contract implement this interface (contract holders can be their own\n * implementer) and registering it on the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\n *\n * See {IERC1820Registry} and {ERC1820Implementer}.\n */\ninterface IERC777Recipient {\n /**\n * @dev Called by an {IERC777} token contract whenever tokens are being\n * moved or created into a registered account (`to`). The type of operation\n * is conveyed by `from` being the zero address or not.\n *\n * This call occurs _after_ the token contract's state is updated, so\n * {IERC777-balanceOf}, etc., can be used to query the post-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensReceived(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777Sender.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Sender.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777TokensSender standard as defined in the EIP.\n *\n * {IERC777} Token holders can be notified of operations performed on their\n * tokens by having a contract implement this interface (contract holders can be\n * their own implementer) and registering it on the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\n *\n * See {IERC1820Registry} and {ERC1820Implementer}.\n */\ninterface IERC777Sender {\n /**\n * @dev Called by an {IERC777} token contract whenever a registered holder's\n * (`from`) tokens are about to be moved or destroyed. The type of operation\n * is conveyed by `to` being the zero address or not.\n *\n * This call occurs _before_ the token contract's state is updated, so\n * {IERC777-balanceOf}, etc., can be used to query the pre-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensToSend(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n *\n * Furthermore, `isContract` will also return true if the target contract within\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n * which only has an effect at the end of a transaction.\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Counters.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary Counters {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/ECDSA.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Strings.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV // Deprecated in v4.8\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n /// @solidity memory-safe-assembly\n assembly {\n mstore(0x00, \"\\x19Ethereum Signed Message:\\n32\")\n mstore(0x1c, hash)\n message := keccak256(0x00, 0x3c)\n }\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\n /// @solidity memory-safe-assembly\n assembly {\n let ptr := mload(0x40)\n mstore(ptr, \"\\x19\\x01\")\n mstore(add(ptr, 0x02), domainSeparator)\n mstore(add(ptr, 0x22), structHash)\n data := keccak256(ptr, 0x42)\n }\n }\n\n /**\n * @dev Returns an Ethereum Signed Data with intended validator, created from a\n * `validator` and `data` according to the version 0 of EIP-191.\n *\n * See {recover}.\n */\n function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x00\", validator, data));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/SignatureChecker.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSA.sol\";\nimport \"../../interfaces/IERC1271.sol\";\n\n/**\n * @dev Signature verification helper that can be used instead of `ECDSA.recover` to seamlessly support both ECDSA\n * signatures from externally owned accounts (EOAs) as well as ERC1271 signatures from smart contract wallets like\n * Argent and Gnosis Safe.\n *\n * _Available since v4.1._\n */\nlibrary SignatureChecker {\n /**\n * @dev Checks if a signature is valid for a given signer and data hash. If the signer is a smart contract, the\n * signature is validated against that smart contract using ERC1271, otherwise it's validated using `ECDSA.recover`.\n *\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\n */\n function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature) internal view returns (bool) {\n (address recovered, ECDSA.RecoverError error) = ECDSA.tryRecover(hash, signature);\n return\n (error == ECDSA.RecoverError.NoError && recovered == signer) ||\n isValidERC1271SignatureNow(signer, hash, signature);\n }\n\n /**\n * @dev Checks if a signature is valid for a given signer and data hash. The signature is validated\n * against the signer smart contract using ERC1271.\n *\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\n */\n function isValidERC1271SignatureNow(\n address signer,\n bytes32 hash,\n bytes memory signature\n ) internal view returns (bool) {\n (bool success, bytes memory result) = signer.staticcall(\n abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, signature)\n );\n return (success &&\n result.length >= 32 &&\n abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/ERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165 is IERC165 {\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165).interfaceId;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC1820Registry.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/introspection/IERC1820Registry.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the global ERC1820 Registry, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register\n * implementers for interfaces in this registry, as well as query support.\n *\n * Implementers may be shared by multiple accounts, and can also implement more\n * than a single interface for each account. Contracts can implement interfaces\n * for themselves, but externally-owned accounts (EOA) must delegate this to a\n * contract.\n *\n * {IERC165} interfaces can also be queried via the registry.\n *\n * For an in-depth explanation and source code analysis, see the EIP text.\n */\ninterface IERC1820Registry {\n event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer);\n\n event ManagerChanged(address indexed account, address indexed newManager);\n\n /**\n * @dev Sets `newManager` as the manager for `account`. A manager of an\n * account is able to set interface implementers for it.\n *\n * By default, each account is its own manager. Passing a value of `0x0` in\n * `newManager` will reset the manager to this initial state.\n *\n * Emits a {ManagerChanged} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `account`.\n */\n function setManager(address account, address newManager) external;\n\n /**\n * @dev Returns the manager for `account`.\n *\n * See {setManager}.\n */\n function getManager(address account) external view returns (address);\n\n /**\n * @dev Sets the `implementer` contract as ``account``'s implementer for\n * `interfaceHash`.\n *\n * `account` being the zero address is an alias for the caller's address.\n * The zero address can also be used in `implementer` to remove an old one.\n *\n * See {interfaceHash} to learn how these are created.\n *\n * Emits an {InterfaceImplementerSet} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `account`.\n * - `interfaceHash` must not be an {IERC165} interface id (i.e. it must not\n * end in 28 zeroes).\n * - `implementer` must implement {IERC1820Implementer} and return true when\n * queried for support, unless `implementer` is the caller. See\n * {IERC1820Implementer-canImplementInterfaceForAddress}.\n */\n function setInterfaceImplementer(address account, bytes32 _interfaceHash, address implementer) external;\n\n /**\n * @dev Returns the implementer of `interfaceHash` for `account`. If no such\n * implementer is registered, returns the zero address.\n *\n * If `interfaceHash` is an {IERC165} interface id (i.e. it ends with 28\n * zeroes), `account` will be queried for support of it.\n *\n * `account` being the zero address is an alias for the caller's address.\n */\n function getInterfaceImplementer(address account, bytes32 _interfaceHash) external view returns (address);\n\n /**\n * @dev Returns the interface hash for an `interfaceName`, as defined in the\n * corresponding\n * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP].\n */\n function interfaceHash(string calldata interfaceName) external pure returns (bytes32);\n\n /**\n * @notice Updates the cache with whether the contract implements an ERC165 interface or not.\n * @param account Address of the contract for which to update the cache.\n * @param interfaceId ERC165 interface for which to update the cache.\n */\n function updateERC165Cache(address account, bytes4 interfaceId) external;\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not.\n * If the result is not cached a direct lookup on the contract address is performed.\n * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling\n * {updateERC165Cache} with the contract address.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool);\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not without using or updating the cache.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/math/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\n // The surrounding unchecked block does not change this fact.\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1, \"Math: mulDiv overflow\");\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n //\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n //\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n //\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1 << (log2(a) >> 1);\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = sqrt(a);\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 2, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 128;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 64;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 32;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 16;\n }\n if (value >> 8 > 0) {\n value >>= 8;\n result += 8;\n }\n if (value >> 4 > 0) {\n value >>= 4;\n result += 4;\n }\n if (value >> 2 > 0) {\n value >>= 2;\n result += 2;\n }\n if (value >> 1 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log2(value);\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 10, rounded down, of a positive value.\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 + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 256, rounded down, of a positive value.\n * Returns 0 if given 0.\n *\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n */\n function log256(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 16;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 8;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 4;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 2;\n }\n if (value >> 8 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log256(value);\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/SafeCast.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCast {\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 * _Available since v4.7._\n */\n function toUint248(uint256 value) internal pure returns (uint248) {\n require(value <= type(uint248).max, \"SafeCast: value doesn't fit in 248 bits\");\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 * _Available since v4.7._\n */\n function toUint240(uint256 value) internal pure returns (uint240) {\n require(value <= type(uint240).max, \"SafeCast: value doesn't fit in 240 bits\");\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 * _Available since v4.7._\n */\n function toUint232(uint256 value) internal pure returns (uint232) {\n require(value <= type(uint232).max, \"SafeCast: value doesn't fit in 232 bits\");\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 * _Available since v4.2._\n */\n function toUint224(uint256 value) internal pure returns (uint224) {\n require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\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 * _Available since v4.7._\n */\n function toUint216(uint256 value) internal pure returns (uint216) {\n require(value <= type(uint216).max, \"SafeCast: value doesn't fit in 216 bits\");\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 * _Available since v4.7._\n */\n function toUint208(uint256 value) internal pure returns (uint208) {\n require(value <= type(uint208).max, \"SafeCast: value doesn't fit in 208 bits\");\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 * _Available since v4.7._\n */\n function toUint200(uint256 value) internal pure returns (uint200) {\n require(value <= type(uint200).max, \"SafeCast: value doesn't fit in 200 bits\");\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 * _Available since v4.7._\n */\n function toUint192(uint256 value) internal pure returns (uint192) {\n require(value <= type(uint192).max, \"SafeCast: value doesn't fit in 192 bits\");\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 * _Available since v4.7._\n */\n function toUint184(uint256 value) internal pure returns (uint184) {\n require(value <= type(uint184).max, \"SafeCast: value doesn't fit in 184 bits\");\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 * _Available since v4.7._\n */\n function toUint176(uint256 value) internal pure returns (uint176) {\n require(value <= type(uint176).max, \"SafeCast: value doesn't fit in 176 bits\");\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 * _Available since v4.7._\n */\n function toUint168(uint256 value) internal pure returns (uint168) {\n require(value <= type(uint168).max, \"SafeCast: value doesn't fit in 168 bits\");\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 * _Available since v4.7._\n */\n function toUint160(uint256 value) internal pure returns (uint160) {\n require(value <= type(uint160).max, \"SafeCast: value doesn't fit in 160 bits\");\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 * _Available since v4.7._\n */\n function toUint152(uint256 value) internal pure returns (uint152) {\n require(value <= type(uint152).max, \"SafeCast: value doesn't fit in 152 bits\");\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 * _Available since v4.7._\n */\n function toUint144(uint256 value) internal pure returns (uint144) {\n require(value <= type(uint144).max, \"SafeCast: value doesn't fit in 144 bits\");\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 * _Available since v4.7._\n */\n function toUint136(uint256 value) internal pure returns (uint136) {\n require(value <= type(uint136).max, \"SafeCast: value doesn't fit in 136 bits\");\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 * _Available since v2.5._\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\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 * _Available since v4.7._\n */\n function toUint120(uint256 value) internal pure returns (uint120) {\n require(value <= type(uint120).max, \"SafeCast: value doesn't fit in 120 bits\");\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 * _Available since v4.7._\n */\n function toUint112(uint256 value) internal pure returns (uint112) {\n require(value <= type(uint112).max, \"SafeCast: value doesn't fit in 112 bits\");\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 * _Available since v4.7._\n */\n function toUint104(uint256 value) internal pure returns (uint104) {\n require(value <= type(uint104).max, \"SafeCast: value doesn't fit in 104 bits\");\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 * _Available since v4.2._\n */\n function toUint96(uint256 value) internal pure returns (uint96) {\n require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\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 * _Available since v4.7._\n */\n function toUint88(uint256 value) internal pure returns (uint88) {\n require(value <= type(uint88).max, \"SafeCast: value doesn't fit in 88 bits\");\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 * _Available since v4.7._\n */\n function toUint80(uint256 value) internal pure returns (uint80) {\n require(value <= type(uint80).max, \"SafeCast: value doesn't fit in 80 bits\");\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 * _Available since v4.7._\n */\n function toUint72(uint256 value) internal pure returns (uint72) {\n require(value <= type(uint72).max, \"SafeCast: value doesn't fit in 72 bits\");\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 * _Available since v2.5._\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\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 * _Available since v4.7._\n */\n function toUint56(uint256 value) internal pure returns (uint56) {\n require(value <= type(uint56).max, \"SafeCast: value doesn't fit in 56 bits\");\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 * _Available since v4.7._\n */\n function toUint48(uint256 value) internal pure returns (uint48) {\n require(value <= type(uint48).max, \"SafeCast: value doesn't fit in 48 bits\");\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 * _Available since v4.7._\n */\n function toUint40(uint256 value) internal pure returns (uint40) {\n require(value <= type(uint40).max, \"SafeCast: value doesn't fit in 40 bits\");\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 * _Available since v2.5._\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\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 * _Available since v4.7._\n */\n function toUint24(uint256 value) internal pure returns (uint24) {\n require(value <= type(uint24).max, \"SafeCast: value doesn't fit in 24 bits\");\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 * _Available since v2.5._\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\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 * _Available since v2.5._\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\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 * _Available since v3.0._\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\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 * _Available since v4.7._\n */\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\n downcasted = int248(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 248 bits\");\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 * _Available since v4.7._\n */\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\n downcasted = int240(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 240 bits\");\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 * _Available since v4.7._\n */\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\n downcasted = int232(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 232 bits\");\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 * _Available since v4.7._\n */\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\n downcasted = int224(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 224 bits\");\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 * _Available since v4.7._\n */\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\n downcasted = int216(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 216 bits\");\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 * _Available since v4.7._\n */\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\n downcasted = int208(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 208 bits\");\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 * _Available since v4.7._\n */\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\n downcasted = int200(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 200 bits\");\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 * _Available since v4.7._\n */\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\n downcasted = int192(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 192 bits\");\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 * _Available since v4.7._\n */\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\n downcasted = int184(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 184 bits\");\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 * _Available since v4.7._\n */\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\n downcasted = int176(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 176 bits\");\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 * _Available since v4.7._\n */\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\n downcasted = int168(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 168 bits\");\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 * _Available since v4.7._\n */\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\n downcasted = int160(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 160 bits\");\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 * _Available since v4.7._\n */\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\n downcasted = int152(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 152 bits\");\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 * _Available since v4.7._\n */\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\n downcasted = int144(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 144 bits\");\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 * _Available since v4.7._\n */\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\n downcasted = int136(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 136 bits\");\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 * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\n downcasted = int128(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 128 bits\");\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 * _Available since v4.7._\n */\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\n downcasted = int120(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 120 bits\");\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 * _Available since v4.7._\n */\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\n downcasted = int112(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 112 bits\");\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 * _Available since v4.7._\n */\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\n downcasted = int104(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 104 bits\");\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 * _Available since v4.7._\n */\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\n downcasted = int96(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 96 bits\");\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 * _Available since v4.7._\n */\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\n downcasted = int88(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 88 bits\");\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 * _Available since v4.7._\n */\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\n downcasted = int80(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 80 bits\");\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 * _Available since v4.7._\n */\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\n downcasted = int72(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 72 bits\");\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 * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\n downcasted = int64(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 64 bits\");\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 * _Available since v4.7._\n */\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\n downcasted = int56(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 56 bits\");\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 * _Available since v4.7._\n */\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\n downcasted = int48(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 48 bits\");\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 * _Available since v4.7._\n */\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\n downcasted = int40(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 40 bits\");\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 * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\n downcasted = int32(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 32 bits\");\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 * _Available since v4.7._\n */\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\n downcasted = int24(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 24 bits\");\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 * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\n downcasted = int16(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 16 bits\");\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 * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\n downcasted = int8(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 8 bits\");\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 * _Available since v3.0._\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 require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/SignedMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard signed math utilities missing in the Solidity language.\n */\nlibrary SignedMath {\n /**\n * @dev Returns the largest of two signed numbers.\n */\n function max(int256 a, int256 b) internal pure returns (int256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two signed numbers.\n */\n function min(int256 a, int256 b) internal pure returns (int256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two signed numbers without overflow.\n * The result is rounded towards zero.\n */\n function average(int256 a, int256 b) internal pure returns (int256) {\n // Formula from the book \"Hacker's Delight\"\n int256 x = (a & b) + ((a ^ b) >> 1);\n return x + (int256(uint256(x) >> 255) & (a ^ b));\n }\n\n /**\n * @dev Returns the absolute unsigned value of a signed value.\n */\n function abs(int256 n) internal pure returns (uint256) {\n unchecked {\n // must be unchecked in order to support `n = type(int256).min`\n return uint256(n >= 0 ? n : -n);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/Math.sol\";\nimport \"./math/SignedMath.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n unchecked {\n uint256 length = Math.log10(value) + 1;\n string memory buffer = new string(length);\n uint256 ptr;\n /// @solidity memory-safe-assembly\n assembly {\n ptr := add(buffer, add(32, length))\n }\n while (true) {\n ptr--;\n /// @solidity memory-safe-assembly\n assembly {\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n }\n value /= 10;\n if (value == 0) break;\n }\n return buffer;\n }\n }\n\n /**\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\n */\n function toString(int256 value) internal pure returns (string memory) {\n return string(abi.encodePacked(value < 0 ? \"-\" : \"\", toString(SignedMath.abs(value))));\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n unchecked {\n return toHexString(value, Math.log256(value) + 1);\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n\n /**\n * @dev Returns true if the two strings are equal.\n */\n function equal(string memory a, string memory b) internal pure returns (bool) {\n return keccak256(bytes(a)) == keccak256(bytes(b));\n }\n}\n" + }, + "contracts/aa-4337/core/BaseAccount.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-empty-blocks */\n\nimport \"../interfaces/IAccount.sol\";\nimport \"../interfaces/IEntryPoint.sol\";\nimport \"./Helpers.sol\";\n\n/**\n * Basic account implementation.\n * this contract provides the basic logic for implementing the IAccount interface - validateUserOp\n * specific account implementation should inherit it and provide the account-specific logic\n */\nabstract contract BaseAccount is IAccount {\n using UserOperationLib for UserOperation;\n\n //return value in case of signature failure, with no time-range.\n // equivalent to _packValidationData(true,0,0);\n uint256 internal constant SIG_VALIDATION_FAILED = 1;\n\n /**\n * Return the account nonce.\n * This method returns the next sequential nonce.\n * For a nonce of a specific key, use `entrypoint.getNonce(account, key)`\n */\n function getNonce() public view virtual returns (uint256) {\n return entryPoint().getNonce(address(this), 0);\n }\n\n /**\n * return the entryPoint used by this account.\n * subclass should return the current entryPoint used by this account.\n */\n function entryPoint() public view virtual returns (IEntryPoint);\n\n /**\n * Validate user's signature and nonce.\n * subclass doesn't need to override this method. Instead, it should override the specific internal validation methods.\n */\n function validateUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 missingAccountFunds\n ) external virtual override returns (uint256 validationData) {\n _requireFromEntryPoint();\n validationData = _validateSignature(userOp, userOpHash);\n _validateNonce(userOp.nonce);\n _payPrefund(missingAccountFunds);\n }\n\n /**\n * ensure the request comes from the known entrypoint.\n */\n function _requireFromEntryPoint() internal view virtual {\n require(\n msg.sender == address(entryPoint()),\n \"account: not from EntryPoint\"\n );\n }\n\n /**\n * validate the signature is valid for this message.\n * @param userOp validate the userOp.signature field\n * @param userOpHash convenient field: the hash of the request, to check the signature against\n * (also hashes the entrypoint and chain id)\n * @return validationData signature and time-range of this operation\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * If the account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function _validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) internal virtual returns (uint256 validationData);\n\n /**\n * Validate the nonce of the UserOperation.\n * This method may validate the nonce requirement of this account.\n * e.g.\n * To limit the nonce to use sequenced UserOps only (no \"out of order\" UserOps):\n * `require(nonce < type(uint64).max)`\n * For a hypothetical account that *requires* the nonce to be out-of-order:\n * `require(nonce & type(uint64).max == 0)`\n *\n * The actual nonce uniqueness is managed by the EntryPoint, and thus no other\n * action is needed by the account itself.\n *\n * @param nonce to validate\n *\n * solhint-disable-next-line no-empty-blocks\n */\n function _validateNonce(uint256 nonce) internal view virtual {}\n\n /**\n * sends to the entrypoint (msg.sender) the missing funds for this transaction.\n * subclass MAY override this method for better funds management\n * (e.g. send to the entryPoint more than the minimum required, so that in future transactions\n * it will not be required to send again)\n * @param missingAccountFunds the minimum value this method should send the entrypoint.\n * this value MAY be zero, in case there is enough deposit, or the userOp has a paymaster.\n */\n function _payPrefund(uint256 missingAccountFunds) internal virtual {\n if (missingAccountFunds != 0) {\n (bool success, ) = payable(msg.sender).call{\n value: missingAccountFunds,\n gas: type(uint256).max\n }(\"\");\n (success);\n //ignore failure (its EntryPoint's job to verify, not account.)\n }\n }\n}\n" + }, + "contracts/aa-4337/core/EntryPoint.sol": { + "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n\nimport \"../interfaces/IAccount.sol\";\nimport \"../interfaces/IPaymaster.sol\";\nimport \"../interfaces/IEntryPoint.sol\";\n\nimport \"../utils/Exec.sol\";\nimport \"./StakeManager.sol\";\nimport \"./SenderCreator.sol\";\nimport \"./Helpers.sol\";\nimport \"./NonceManager.sol\";\nimport \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\n\ncontract EntryPoint is\n IEntryPoint,\n StakeManager,\n NonceManager,\n ReentrancyGuard\n{\n using UserOperationLib for UserOperation;\n\n SenderCreator private immutable senderCreator = new SenderCreator();\n\n // internal value used during simulation: need to query aggregator.\n address private constant SIMULATE_FIND_AGGREGATOR = address(1);\n\n // marker for inner call revert on out of gas\n bytes32 private constant INNER_OUT_OF_GAS = hex\"deaddead\";\n\n uint256 private constant REVERT_REASON_MAX_LEN = 2048;\n\n /**\n * for simulation purposes, validateUserOp (and validatePaymasterUserOp) must return this value\n * in case of signature failure, instead of revert.\n */\n uint256 public constant SIG_VALIDATION_FAILED = 1;\n\n /**\n * compensate the caller's beneficiary address with the collected fees of all UserOperations.\n * @param beneficiary the address to receive the fees\n * @param amount amount to transfer.\n */\n function _compensate(address payable beneficiary, uint256 amount) internal {\n require(beneficiary != address(0), \"AA90 invalid beneficiary\");\n (bool success, ) = beneficiary.call{value: amount}(\"\");\n require(success, \"AA91 failed send to beneficiary\");\n }\n\n /**\n * execute a user op\n * @param opIndex index into the opInfo array\n * @param userOp the userOp to execute\n * @param opInfo the opInfo filled by validatePrepayment for this userOp.\n * @return collected the total amount this userOp paid.\n */\n function _executeUserOp(\n uint256 opIndex,\n UserOperation calldata userOp,\n UserOpInfo memory opInfo\n ) private returns (uint256 collected) {\n uint256 preGas = gasleft();\n bytes memory context = getMemoryBytesFromOffset(opInfo.contextOffset);\n\n try this.innerHandleOp(userOp.callData, opInfo, context) returns (\n uint256 _actualGasCost\n ) {\n collected = _actualGasCost;\n } catch {\n bytes32 innerRevertCode;\n assembly {\n returndatacopy(0, 0, 32)\n innerRevertCode := mload(0)\n }\n // handleOps was called with gas limit too low. abort entire bundle.\n if (innerRevertCode == INNER_OUT_OF_GAS) {\n //report paymaster, since if it is not deliberately caused by the bundler,\n // it must be a revert caused by paymaster.\n revert FailedOp(opIndex, \"AA95 out of gas\");\n }\n\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n collected = _handlePostOp(\n opIndex,\n IPaymaster.PostOpMode.postOpReverted,\n opInfo,\n context,\n actualGas\n );\n }\n }\n\n /**\n * Execute a batch of UserOperations.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(\n UserOperation[] calldata ops,\n address payable beneficiary\n ) public nonReentrant {\n uint256 opslen = ops.length;\n UserOpInfo[] memory opInfos = new UserOpInfo[](opslen);\n\n unchecked {\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[i];\n (\n uint256 validationData,\n uint256 pmValidationData\n ) = _validatePrepayment(i, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(\n i,\n validationData,\n pmValidationData,\n address(0)\n );\n }\n\n uint256 collected = 0;\n emit BeforeExecution();\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(i, ops[i], opInfos[i]);\n }\n\n _compensate(beneficiary, collected);\n } //unchecked\n }\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) public nonReentrant {\n uint256 opasLen = opsPerAggregator.length;\n uint256 totalOps = 0;\n for (uint256 i = 0; i < opasLen; i++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[i];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n //address(1) is special marker of \"signature error\"\n require(\n address(aggregator) != address(1),\n \"AA96 invalid aggregator\"\n );\n\n if (address(aggregator) != address(0)) {\n // solhint-disable-next-line no-empty-blocks\n try aggregator.validateSignatures(ops, opa.signature) {} catch {\n revert SignatureValidationFailed(address(aggregator));\n }\n }\n\n totalOps += ops.length;\n }\n\n UserOpInfo[] memory opInfos = new UserOpInfo[](totalOps);\n\n emit BeforeExecution();\n\n uint256 opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n uint256 opslen = ops.length;\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[opIndex];\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(opIndex, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(\n i,\n validationData,\n paymasterValidationData,\n address(aggregator)\n );\n opIndex++;\n }\n }\n\n uint256 collected = 0;\n opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n emit SignatureAggregatorChanged(address(opa.aggregator));\n UserOperation[] calldata ops = opa.userOps;\n uint256 opslen = ops.length;\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(opIndex, ops[i], opInfos[opIndex]);\n opIndex++;\n }\n }\n emit SignatureAggregatorChanged(address(0));\n\n _compensate(beneficiary, collected);\n }\n\n /// @inheritdoc IEntryPoint\n function simulateHandleOp(\n UserOperation calldata op,\n address target,\n bytes calldata targetCallData\n ) external override {\n UserOpInfo memory opInfo;\n _simulationOnlyValidations(op);\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(0, op, opInfo);\n ValidationData memory data = _intersectTimeRange(\n validationData,\n paymasterValidationData\n );\n\n numberMarker();\n uint256 paid = _executeUserOp(0, op, opInfo);\n numberMarker();\n bool targetSuccess;\n bytes memory targetResult;\n if (target != address(0)) {\n (targetSuccess, targetResult) = target.call(targetCallData);\n }\n revert ExecutionResult(\n opInfo.preOpGas,\n paid,\n data.validAfter,\n data.validUntil,\n targetSuccess,\n targetResult\n );\n }\n\n // A memory copy of UserOp static fields only.\n // Excluding: callData, initCode and signature. Replacing paymasterAndData with paymaster.\n struct MemoryUserOp {\n address sender;\n uint256 nonce;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n address paymaster;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n }\n\n struct UserOpInfo {\n MemoryUserOp mUserOp;\n bytes32 userOpHash;\n uint256 prefund;\n uint256 contextOffset;\n uint256 preOpGas;\n }\n\n /**\n * inner function to handle a UserOperation.\n * Must be declared \"external\" to open a call context, but it can only be called by handleOps.\n */\n function innerHandleOp(\n bytes memory callData,\n UserOpInfo memory opInfo,\n bytes calldata context\n ) external returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n require(msg.sender == address(this), \"AA92 internal call only\");\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n\n uint callGasLimit = mUserOp.callGasLimit;\n unchecked {\n // handleOps was called with gas limit too low. abort entire bundle.\n if (\n gasleft() < callGasLimit + mUserOp.verificationGasLimit + 5000\n ) {\n assembly {\n mstore(0, INNER_OUT_OF_GAS)\n revert(0, 32)\n }\n }\n }\n\n IPaymaster.PostOpMode mode = IPaymaster.PostOpMode.opSucceeded;\n if (callData.length > 0) {\n bool success = Exec.call(mUserOp.sender, 0, callData, callGasLimit);\n if (!success) {\n bytes memory result = Exec.getReturnData(REVERT_REASON_MAX_LEN);\n if (result.length > 0) {\n emit UserOperationRevertReason(\n opInfo.userOpHash,\n mUserOp.sender,\n mUserOp.nonce,\n result\n );\n }\n mode = IPaymaster.PostOpMode.opReverted;\n }\n }\n\n unchecked {\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n //note: opIndex is ignored (relevant only if mode==postOpReverted, which is only possible outside of innerHandleOp)\n return _handlePostOp(0, mode, opInfo, context, actualGas);\n }\n }\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(\n UserOperation calldata userOp\n ) public view returns (bytes32) {\n return\n keccak256(abi.encode(userOp.hash(), address(this), block.chainid));\n }\n\n /**\n * copy general fields from userOp into the memory opInfo structure.\n */\n function _copyUserOpToMemory(\n UserOperation calldata userOp,\n MemoryUserOp memory mUserOp\n ) internal pure {\n mUserOp.sender = userOp.sender;\n mUserOp.nonce = userOp.nonce;\n mUserOp.callGasLimit = userOp.callGasLimit;\n mUserOp.verificationGasLimit = userOp.verificationGasLimit;\n mUserOp.preVerificationGas = userOp.preVerificationGas;\n mUserOp.maxFeePerGas = userOp.maxFeePerGas;\n mUserOp.maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes calldata paymasterAndData = userOp.paymasterAndData;\n if (paymasterAndData.length > 0) {\n require(\n paymasterAndData.length >= 20,\n \"AA93 invalid paymasterAndData\"\n );\n mUserOp.paymaster = address(bytes20(paymasterAndData[:20]));\n } else {\n mUserOp.paymaster = address(0);\n }\n }\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external {\n UserOpInfo memory outOpInfo;\n\n _simulationOnlyValidations(userOp);\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(0, userOp, outOpInfo);\n StakeInfo memory paymasterInfo = _getStakeInfo(\n outOpInfo.mUserOp.paymaster\n );\n StakeInfo memory senderInfo = _getStakeInfo(outOpInfo.mUserOp.sender);\n StakeInfo memory factoryInfo;\n {\n bytes calldata initCode = userOp.initCode;\n address factory = initCode.length >= 20\n ? address(bytes20(initCode[0:20]))\n : address(0);\n factoryInfo = _getStakeInfo(factory);\n }\n\n ValidationData memory data = _intersectTimeRange(\n validationData,\n paymasterValidationData\n );\n address aggregator = data.aggregator;\n bool sigFailed = aggregator == address(1);\n ReturnInfo memory returnInfo = ReturnInfo(\n outOpInfo.preOpGas,\n outOpInfo.prefund,\n sigFailed,\n data.validAfter,\n data.validUntil,\n getMemoryBytesFromOffset(outOpInfo.contextOffset)\n );\n\n if (aggregator != address(0) && aggregator != address(1)) {\n AggregatorStakeInfo memory aggregatorInfo = AggregatorStakeInfo(\n aggregator,\n _getStakeInfo(aggregator)\n );\n revert ValidationResultWithAggregation(\n returnInfo,\n senderInfo,\n factoryInfo,\n paymasterInfo,\n aggregatorInfo\n );\n }\n revert ValidationResult(\n returnInfo,\n senderInfo,\n factoryInfo,\n paymasterInfo\n );\n }\n\n function _getRequiredPrefund(\n MemoryUserOp memory mUserOp\n ) internal pure returns (uint256 requiredPrefund) {\n unchecked {\n //when using a Paymaster, the verificationGasLimit is used also to as a limit for the postOp call.\n // our security model might call postOp eventually twice\n uint256 mul = mUserOp.paymaster != address(0) ? 3 : 1;\n uint256 requiredGas = mUserOp.callGasLimit +\n mUserOp.verificationGasLimit *\n mul +\n mUserOp.preVerificationGas;\n\n requiredPrefund = requiredGas * mUserOp.maxFeePerGas;\n }\n }\n\n // create the sender's contract if needed.\n function _createSenderIfNeeded(\n uint256 opIndex,\n UserOpInfo memory opInfo,\n bytes calldata initCode\n ) internal {\n if (initCode.length != 0) {\n address sender = opInfo.mUserOp.sender;\n if (sender.code.length != 0)\n revert FailedOp(opIndex, \"AA10 sender already constructed\");\n address sender1 = senderCreator.createSender{\n gas: opInfo.mUserOp.verificationGasLimit\n }(initCode);\n if (sender1 == address(0))\n revert FailedOp(opIndex, \"AA13 initCode failed or OOG\");\n if (sender1 != sender)\n revert FailedOp(opIndex, \"AA14 initCode must return sender\");\n if (sender1.code.length == 0)\n revert FailedOp(opIndex, \"AA15 initCode must create sender\");\n address factory = address(bytes20(initCode[0:20]));\n emit AccountDeployed(\n opInfo.userOpHash,\n sender,\n factory,\n opInfo.mUserOp.paymaster\n );\n }\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes calldata initCode) public {\n address sender = senderCreator.createSender(initCode);\n revert SenderAddressResult(sender);\n }\n\n function _simulationOnlyValidations(\n UserOperation calldata userOp\n ) internal view {\n // solhint-disable-next-line no-empty-blocks\n try\n this._validateSenderAndPaymaster(\n userOp.initCode,\n userOp.sender,\n userOp.paymasterAndData\n )\n {} catch Error(string memory revertReason) {\n if (bytes(revertReason).length != 0) {\n revert FailedOp(0, revertReason);\n }\n }\n }\n\n /**\n * Called only during simulation.\n * This function always reverts to prevent warm/cold storage differentiation in simulation vs execution.\n */\n function _validateSenderAndPaymaster(\n bytes calldata initCode,\n address sender,\n bytes calldata paymasterAndData\n ) external view {\n if (initCode.length == 0 && sender.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA20 account not deployed\");\n }\n if (paymasterAndData.length >= 20) {\n address paymaster = address(bytes20(paymasterAndData[0:20]));\n if (paymaster.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA30 paymaster not deployed\");\n }\n }\n // always revert\n revert(\"\");\n }\n\n /**\n * call account.validateUserOp.\n * revert (with FailedOp) in case validateUserOp reverts, or account didn't send required prefund.\n * decrement account's deposit if needed\n */\n function _validateAccountPrepayment(\n uint256 opIndex,\n UserOperation calldata op,\n UserOpInfo memory opInfo,\n uint256 requiredPrefund\n )\n internal\n returns (\n uint256 gasUsedByValidateAccountPrepayment,\n uint256 validationData\n )\n {\n unchecked {\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n address sender = mUserOp.sender;\n _createSenderIfNeeded(opIndex, opInfo, op.initCode);\n address paymaster = mUserOp.paymaster;\n numberMarker();\n uint256 missingAccountFunds = 0;\n if (paymaster == address(0)) {\n uint256 bal = balanceOf(sender);\n missingAccountFunds = bal > requiredPrefund\n ? 0\n : requiredPrefund - bal;\n }\n try\n IAccount(sender).validateUserOp{\n gas: mUserOp.verificationGasLimit\n }(op, opInfo.userOpHash, missingAccountFunds)\n returns (uint256 _validationData) {\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA23 reverted: \", revertReason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA23 reverted (or OOG)\");\n }\n if (paymaster == address(0)) {\n DepositInfo storage senderInfo = deposits[sender];\n uint256 deposit = senderInfo.deposit;\n if (requiredPrefund > deposit) {\n revert FailedOp(opIndex, \"AA21 didn't pay prefund\");\n }\n senderInfo.deposit = uint112(deposit - requiredPrefund);\n }\n gasUsedByValidateAccountPrepayment = preGas - gasleft();\n }\n }\n\n /**\n * In case the request has a paymaster:\n * Validate paymaster has enough deposit.\n * Call paymaster.validatePaymasterUserOp.\n * Revert with proper FailedOp in case paymaster reverts.\n * Decrement paymaster's deposit\n */\n function _validatePaymasterPrepayment(\n uint256 opIndex,\n UserOperation calldata op,\n UserOpInfo memory opInfo,\n uint256 requiredPreFund,\n uint256 gasUsedByValidateAccountPrepayment\n ) internal returns (bytes memory context, uint256 validationData) {\n unchecked {\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 verificationGasLimit = mUserOp.verificationGasLimit;\n require(\n verificationGasLimit > gasUsedByValidateAccountPrepayment,\n \"AA41 too little verificationGas\"\n );\n uint256 gas = verificationGasLimit -\n gasUsedByValidateAccountPrepayment;\n\n address paymaster = mUserOp.paymaster;\n DepositInfo storage paymasterInfo = deposits[paymaster];\n uint256 deposit = paymasterInfo.deposit;\n if (deposit < requiredPreFund) {\n revert FailedOp(opIndex, \"AA31 paymaster deposit too low\");\n }\n paymasterInfo.deposit = uint112(deposit - requiredPreFund);\n try\n IPaymaster(paymaster).validatePaymasterUserOp{gas: gas}(\n op,\n opInfo.userOpHash,\n requiredPreFund\n )\n returns (bytes memory _context, uint256 _validationData) {\n context = _context;\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA33 reverted: \", revertReason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA33 reverted (or OOG)\");\n }\n }\n }\n\n /**\n * revert if either account validationData or paymaster validationData is expired\n */\n function _validateAccountAndPaymasterValidationData(\n uint256 opIndex,\n uint256 validationData,\n uint256 paymasterValidationData,\n address expectedAggregator\n ) internal view {\n (address aggregator, bool outOfTimeRange) = _getValidationData(\n validationData\n );\n if (expectedAggregator != aggregator) {\n revert FailedOp(opIndex, \"AA24 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA22 expired or not due\");\n }\n //pmAggregator is not a real signature aggregator: we don't have logic to handle it as address.\n // non-zero address means that the paymaster fails due to some signature check (which is ok only during estimation)\n address pmAggregator;\n (pmAggregator, outOfTimeRange) = _getValidationData(\n paymasterValidationData\n );\n if (pmAggregator != address(0)) {\n revert FailedOp(opIndex, \"AA34 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA32 paymaster expired or not due\");\n }\n }\n\n function _getValidationData(\n uint256 validationData\n ) internal view returns (address aggregator, bool outOfTimeRange) {\n if (validationData == 0) {\n return (address(0), false);\n }\n ValidationData memory data = _parseValidationData(validationData);\n // solhint-disable-next-line not-rely-on-time\n outOfTimeRange =\n block.timestamp > data.validUntil ||\n block.timestamp < data.validAfter;\n aggregator = data.aggregator;\n }\n\n /**\n * validate account and paymaster (if defined).\n * also make sure total validation doesn't exceed verificationGasLimit\n * this method is called off-chain (simulateValidation()) and on-chain (from handleOps)\n * @param opIndex the index of this userOp into the \"opInfos\" array\n * @param userOp the userOp to validate\n */\n function _validatePrepayment(\n uint256 opIndex,\n UserOperation calldata userOp,\n UserOpInfo memory outOpInfo\n )\n private\n returns (uint256 validationData, uint256 paymasterValidationData)\n {\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = outOpInfo.mUserOp;\n _copyUserOpToMemory(userOp, mUserOp);\n outOpInfo.userOpHash = getUserOpHash(userOp);\n\n // validate all numeric values in userOp are well below 128 bit, so they can safely be added\n // and multiplied without causing overflow\n uint256 maxGasValues = mUserOp.preVerificationGas |\n mUserOp.verificationGasLimit |\n mUserOp.callGasLimit |\n userOp.maxFeePerGas |\n userOp.maxPriorityFeePerGas;\n require(maxGasValues <= type(uint120).max, \"AA94 gas values overflow\");\n\n uint256 gasUsedByValidateAccountPrepayment;\n uint256 requiredPreFund = _getRequiredPrefund(mUserOp);\n (\n gasUsedByValidateAccountPrepayment,\n validationData\n ) = _validateAccountPrepayment(\n opIndex,\n userOp,\n outOpInfo,\n requiredPreFund\n );\n\n if (!_validateAndUpdateNonce(mUserOp.sender, mUserOp.nonce)) {\n revert FailedOp(opIndex, \"AA25 invalid account nonce\");\n }\n\n //a \"marker\" where account opcode validation is done and paymaster opcode validation is about to start\n // (used only by off-chain simulateValidation)\n numberMarker();\n\n bytes memory context;\n if (mUserOp.paymaster != address(0)) {\n (context, paymasterValidationData) = _validatePaymasterPrepayment(\n opIndex,\n userOp,\n outOpInfo,\n requiredPreFund,\n gasUsedByValidateAccountPrepayment\n );\n }\n unchecked {\n uint256 gasUsed = preGas - gasleft();\n\n if (userOp.verificationGasLimit < gasUsed) {\n revert FailedOp(opIndex, \"AA40 over verificationGasLimit\");\n }\n outOpInfo.prefund = requiredPreFund;\n outOpInfo.contextOffset = getOffsetOfMemoryBytes(context);\n outOpInfo.preOpGas = preGas - gasleft() + userOp.preVerificationGas;\n }\n }\n\n /**\n * process post-operation.\n * called just after the callData is executed.\n * if a paymaster is defined and its validation returned a non-empty context, its postOp is called.\n * the excess amount is refunded to the account (or paymaster - if it was used in the request)\n * @param opIndex index in the batch\n * @param mode - whether is called from innerHandleOp, or outside (postOpReverted)\n * @param opInfo userOp fields and info collected during validation\n * @param context the context returned in validatePaymasterUserOp\n * @param actualGas the gas used so far by this user operation\n */\n function _handlePostOp(\n uint256 opIndex,\n IPaymaster.PostOpMode mode,\n UserOpInfo memory opInfo,\n bytes memory context,\n uint256 actualGas\n ) private returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n unchecked {\n address refundAddress;\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 gasPrice = getUserOpGasPrice(mUserOp);\n\n address paymaster = mUserOp.paymaster;\n if (paymaster == address(0)) {\n refundAddress = mUserOp.sender;\n } else {\n refundAddress = paymaster;\n if (context.length > 0) {\n actualGasCost = actualGas * gasPrice;\n if (mode != IPaymaster.PostOpMode.postOpReverted) {\n IPaymaster(paymaster).postOp{\n gas: mUserOp.verificationGasLimit\n }(mode, context, actualGasCost);\n } else {\n // solhint-disable-next-line no-empty-blocks\n try\n IPaymaster(paymaster).postOp{\n gas: mUserOp.verificationGasLimit\n }(mode, context, actualGasCost)\n {} catch Error(string memory reason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA50 postOp reverted: \", reason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA50 postOp revert\");\n }\n }\n }\n }\n actualGas += preGas - gasleft();\n actualGasCost = actualGas * gasPrice;\n if (opInfo.prefund < actualGasCost) {\n revert FailedOp(opIndex, \"AA51 prefund below actualGasCost\");\n }\n uint256 refund = opInfo.prefund - actualGasCost;\n _incrementDeposit(refundAddress, refund);\n bool success = mode == IPaymaster.PostOpMode.opSucceeded;\n emit UserOperationEvent(\n opInfo.userOpHash,\n mUserOp.sender,\n mUserOp.paymaster,\n mUserOp.nonce,\n success,\n actualGasCost,\n actualGas\n );\n } // unchecked\n }\n\n /**\n * the gas price this UserOp agrees to pay.\n * relayer/block builder might submit the TX with higher priorityFee, but the user should not\n */\n function getUserOpGasPrice(\n MemoryUserOp memory mUserOp\n ) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = mUserOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = mUserOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n function getOffsetOfMemoryBytes(\n bytes memory data\n ) internal pure returns (uint256 offset) {\n assembly {\n offset := data\n }\n }\n\n function getMemoryBytesFromOffset(\n uint256 offset\n ) internal pure returns (bytes memory data) {\n assembly {\n data := offset\n }\n }\n\n //place the NUMBER opcode in the code.\n // this is used as a marker during simulation, as this OP is completely banned from the simulated code of the\n // account and paymaster.\n function numberMarker() internal view {\n assembly {\n mstore(0, number())\n }\n }\n}\n" + }, + "contracts/aa-4337/core/Helpers.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable no-inline-assembly */\n\n/**\n * returned data from validateUserOp.\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\n * @param aggregator - address(0) - the account validated the signature by itself.\n * address(1) - the account failed to validate the signature.\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\n * @param validAfter - this UserOp is valid only after this timestamp.\n * @param validaUntil - this UserOp is valid only up to this timestamp.\n */\nstruct ValidationData {\n address aggregator;\n uint48 validAfter;\n uint48 validUntil;\n}\n\n//extract sigFailed, validAfter, validUntil.\n// also convert zero validUntil to type(uint48).max\nfunction _parseValidationData(\n uint validationData\n) pure returns (ValidationData memory data) {\n address aggregator = address(uint160(validationData));\n uint48 validUntil = uint48(validationData >> 160);\n if (validUntil == 0) {\n validUntil = type(uint48).max;\n }\n uint48 validAfter = uint48(validationData >> (48 + 160));\n return ValidationData(aggregator, validAfter, validUntil);\n}\n\n// intersect account and paymaster ranges.\nfunction _intersectTimeRange(\n uint256 validationData,\n uint256 paymasterValidationData\n) pure returns (ValidationData memory) {\n ValidationData memory accountValidationData = _parseValidationData(\n validationData\n );\n ValidationData memory pmValidationData = _parseValidationData(\n paymasterValidationData\n );\n address aggregator = accountValidationData.aggregator;\n if (aggregator == address(0)) {\n aggregator = pmValidationData.aggregator;\n }\n uint48 validAfter = accountValidationData.validAfter;\n uint48 validUntil = accountValidationData.validUntil;\n uint48 pmValidAfter = pmValidationData.validAfter;\n uint48 pmValidUntil = pmValidationData.validUntil;\n\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\n return ValidationData(aggregator, validAfter, validUntil);\n}\n\n/**\n * helper to pack the return value for validateUserOp\n * @param data - the ValidationData to pack\n */\nfunction _packValidationData(\n ValidationData memory data\n) pure returns (uint256) {\n return\n uint160(data.aggregator) |\n (uint256(data.validUntil) << 160) |\n (uint256(data.validAfter) << (160 + 48));\n}\n\n/**\n * helper to pack the return value for validateUserOp, when not using an aggregator\n * @param sigFailed - true for signature failure, false for success\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\n * @param validAfter first timestamp this UserOperation is valid\n */\nfunction _packValidationData(\n bool sigFailed,\n uint48 validUntil,\n uint48 validAfter\n) pure returns (uint256) {\n return\n (sigFailed ? 1 : 0) |\n (uint256(validUntil) << 160) |\n (uint256(validAfter) << (160 + 48));\n}\n\n/**\n * keccak function over calldata.\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\n */\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\n assembly {\n let mem := mload(0x40)\n let len := data.length\n calldatacopy(mem, data.offset, len)\n ret := keccak256(mem, len)\n }\n}\n" + }, + "contracts/aa-4337/core/NonceManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\nimport \"../interfaces/IEntryPoint.sol\";\n\n/**\n * nonce management functionality\n */\ncontract NonceManager is INonceManager {\n /**\n * The next valid sequence number for a given nonce key.\n */\n mapping(address => mapping(uint192 => uint256)) public nonceSequenceNumber;\n\n function getNonce(\n address sender,\n uint192 key\n ) public view override returns (uint256 nonce) {\n return nonceSequenceNumber[sender][key] | (uint256(key) << 64);\n }\n\n // allow an account to manually increment its own nonce.\n // (mainly so that during construction nonce can be made non-zero,\n // to \"absorb\" the gas cost of first nonce increment to 1st transaction (construction),\n // not to 2nd transaction)\n function incrementNonce(uint192 key) public override {\n nonceSequenceNumber[msg.sender][key]++;\n }\n\n /**\n * validate nonce uniqueness for this account.\n * called just after validateUserOp()\n */\n function _validateAndUpdateNonce(\n address sender,\n uint256 nonce\n ) internal returns (bool) {\n uint192 key = uint192(nonce >> 64);\n uint64 seq = uint64(nonce);\n return nonceSequenceNumber[sender][key]++ == seq;\n }\n}\n" + }, + "contracts/aa-4337/core/SenderCreator.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/**\n * helper contract for EntryPoint, to call userOp.initCode from a \"neutral\" address,\n * which is explicitly not the entryPoint itself.\n */\ncontract SenderCreator {\n /**\n * call the \"initCode\" factory to create and return the sender account address\n * @param initCode the initCode value from a UserOp. contains 20 bytes of factory address, followed by calldata\n * @return sender the returned address of the created account, or zero address on failure.\n */\n function createSender(\n bytes calldata initCode\n ) external returns (address sender) {\n address factory = address(bytes20(initCode[0:20]));\n bytes memory initCallData = initCode[20:];\n bool success;\n /* solhint-disable no-inline-assembly */\n assembly {\n success := call(\n gas(),\n factory,\n 0,\n add(initCallData, 0x20),\n mload(initCallData),\n 0,\n 32\n )\n sender := mload(0)\n }\n if (!success) {\n sender = address(0);\n }\n }\n}\n" + }, + "contracts/aa-4337/core/StakeManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity 0.8.21;\n\nimport \"../interfaces/IStakeManager.sol\";\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable not-rely-on-time */\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by a paymaster.\n */\nabstract contract StakeManager is IStakeManager {\n /// maps paymaster to their deposits and stakes\n mapping(address => DepositInfo) public deposits;\n\n /// @inheritdoc IStakeManager\n function getDepositInfo(\n address account\n ) public view returns (DepositInfo memory info) {\n return deposits[account];\n }\n\n // internal method to return just the stake info\n function _getStakeInfo(\n address addr\n ) internal view returns (StakeInfo memory info) {\n DepositInfo storage depositInfo = deposits[addr];\n info.stake = depositInfo.stake;\n info.unstakeDelaySec = depositInfo.unstakeDelaySec;\n }\n\n /// return the deposit (for gas payment) of the account\n function balanceOf(address account) public view returns (uint256) {\n return deposits[account].deposit;\n }\n\n receive() external payable {\n depositTo(msg.sender);\n }\n\n function _incrementDeposit(address account, uint256 amount) internal {\n DepositInfo storage info = deposits[account];\n uint256 newAmount = info.deposit + amount;\n require(newAmount <= type(uint112).max, \"deposit overflow\");\n info.deposit = uint112(newAmount);\n }\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) public payable {\n _incrementDeposit(account, msg.value);\n DepositInfo storage info = deposits[account];\n emit Deposited(account, info.deposit);\n }\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 unstakeDelaySec) public payable {\n DepositInfo storage info = deposits[msg.sender];\n require(unstakeDelaySec > 0, \"must specify unstake delay\");\n require(\n unstakeDelaySec >= info.unstakeDelaySec,\n \"cannot decrease unstake time\"\n );\n uint256 stake = info.stake + msg.value;\n require(stake > 0, \"no stake specified\");\n require(stake <= type(uint112).max, \"stake overflow\");\n deposits[msg.sender] = DepositInfo(\n info.deposit,\n true,\n uint112(stake),\n unstakeDelaySec,\n 0\n );\n emit StakeLocked(msg.sender, stake, unstakeDelaySec);\n }\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external {\n DepositInfo storage info = deposits[msg.sender];\n require(info.unstakeDelaySec != 0, \"not staked\");\n require(info.staked, \"already unstaking\");\n uint48 withdrawTime = uint48(block.timestamp) + info.unstakeDelaySec;\n info.withdrawTime = withdrawTime;\n info.staked = false;\n emit StakeUnlocked(msg.sender, withdrawTime);\n }\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external {\n DepositInfo storage info = deposits[msg.sender];\n uint256 stake = info.stake;\n require(stake > 0, \"No stake to withdraw\");\n require(info.withdrawTime > 0, \"must call unlockStake() first\");\n require(\n info.withdrawTime <= block.timestamp,\n \"Stake withdrawal is not due\"\n );\n info.unstakeDelaySec = 0;\n info.withdrawTime = 0;\n info.stake = 0;\n emit StakeWithdrawn(msg.sender, withdrawAddress, stake);\n (bool success, ) = withdrawAddress.call{value: stake}(\"\");\n require(success, \"failed to withdraw stake\");\n }\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(\n address payable withdrawAddress,\n uint256 withdrawAmount\n ) external {\n DepositInfo storage info = deposits[msg.sender];\n require(withdrawAmount <= info.deposit, \"Withdraw amount too large\");\n info.deposit = uint112(info.deposit - withdrawAmount);\n emit Withdrawn(msg.sender, withdrawAddress, withdrawAmount);\n (bool success, ) = withdrawAddress.call{value: withdrawAmount}(\"\");\n require(success, \"failed to withdraw\");\n }\n}\n" + }, + "contracts/aa-4337/interfaces/IAccount.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\ninterface IAccount {\n /**\n * Validate user's signature and nonce\n * the entryPoint will make the call to the recipient only if this validation call returns successfully.\n * signature failure should be reported by returning SIG_VALIDATION_FAILED (1).\n * This allows making a \"simulation call\" without a valid signature\n * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure.\n *\n * @dev Must validate caller is the entryPoint.\n * Must validate the signature and nonce\n * @param userOp the operation that is about to be executed.\n * @param userOpHash hash of the user's request data. can be used as the basis for signature.\n * @param missingAccountFunds missing funds on the account's deposit in the entrypoint.\n * This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call.\n * The excess is left as a deposit in the entrypoint, for future calls.\n * can be withdrawn anytime using \"entryPoint.withdrawTo()\"\n * In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero.\n * @return validationData packaged ValidationData structure. use `_packValidationData` and `_unpackValidationData` to encode and decode\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * If an account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validateUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 missingAccountFunds\n ) external returns (uint256 validationData);\n}\n" + }, + "contracts/aa-4337/interfaces/IAggregator.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * Aggregated Signatures validator.\n */\ninterface IAggregator {\n /**\n * validate aggregated signature.\n * revert if the aggregated signature does not match the given list of operations.\n */\n function validateSignatures(\n UserOperation[] calldata userOps,\n bytes calldata signature\n ) external view;\n\n /**\n * validate signature of a single userOp\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\n * @param userOp the userOperation received from the user.\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\n * (usually empty, unless account and aggregator support some kind of \"multisig\"\n */\n function validateUserOpSignature(\n UserOperation calldata userOp\n ) external view returns (bytes memory sigForUserOp);\n\n /**\n * aggregate multiple signatures into a single value.\n * This method is called off-chain to calculate the signature to pass with handleOps()\n * bundler MAY use optimized custom code perform this aggregation\n * @param userOps array of UserOperations to collect the signatures from.\n * @return aggregatedSignature the aggregated signature\n */\n function aggregateSignatures(\n UserOperation[] calldata userOps\n ) external view returns (bytes memory aggregatedSignature);\n}\n" + }, + "contracts/aa-4337/interfaces/IEntryPoint.sol": { + "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n/* solhint-disable reason-string */\n\nimport \"./UserOperation.sol\";\nimport \"./IStakeManager.sol\";\nimport \"./IAggregator.sol\";\nimport \"./INonceManager.sol\";\n\ninterface IEntryPoint is IStakeManager, INonceManager {\n /***\n * An event emitted after each successful request\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\n * @param sender - the account that generates this request.\n * @param paymaster - if non-null, the paymaster that pays for this request.\n * @param nonce - the nonce value from the request.\n * @param success - true if the sender transaction succeeded, false if reverted.\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\n */\n event UserOperationEvent(\n bytes32 indexed userOpHash,\n address indexed sender,\n address indexed paymaster,\n uint256 nonce,\n bool success,\n uint256 actualGasCost,\n uint256 actualGasUsed\n );\n\n /**\n * account \"sender\" was deployed.\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\n * @param sender the account that is deployed\n * @param factory the factory used to deploy this account (in the initCode)\n * @param paymaster the paymaster used by this UserOp\n */\n event AccountDeployed(\n bytes32 indexed userOpHash,\n address indexed sender,\n address factory,\n address paymaster\n );\n\n /**\n * An event emitted if the UserOperation \"callData\" reverted with non-zero length\n * @param userOpHash the request unique identifier.\n * @param sender the sender of this request\n * @param nonce the nonce used in the request\n * @param revertReason - the return bytes from the (reverted) call to \"callData\".\n */\n event UserOperationRevertReason(\n bytes32 indexed userOpHash,\n address indexed sender,\n uint256 nonce,\n bytes revertReason\n );\n\n /**\n * an event emitted by handleOps(), before starting the execution loop.\n * any event emitted before this event, is part of the validation.\n */\n event BeforeExecution();\n\n /**\n * signature aggregator used by the following UserOperationEvents within this bundle.\n */\n event SignatureAggregatorChanged(address indexed aggregator);\n\n /**\n * a custom revert error of handleOps, to identify the offending op.\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\n * @param reason - revert reason\n * The string starts with a unique code \"AAmn\", where \"m\" is \"1\" for factory, \"2\" for account and \"3\" for paymaster issues,\n * so a failure can be attributed to the correct entity.\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\n */\n error FailedOp(uint256 opIndex, string reason);\n\n /**\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\n */\n error SignatureValidationFailed(address aggregator);\n\n /**\n * Successful result from simulateValidation.\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n */\n error ValidationResult(\n ReturnInfo returnInfo,\n StakeInfo senderInfo,\n StakeInfo factoryInfo,\n StakeInfo paymasterInfo\n );\n\n /**\n * Successful result from simulateValidation, if the account returns a signature aggregator\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\n * bundler MUST use it to verify the signature, or reject the UserOperation\n */\n error ValidationResultWithAggregation(\n ReturnInfo returnInfo,\n StakeInfo senderInfo,\n StakeInfo factoryInfo,\n StakeInfo paymasterInfo,\n AggregatorStakeInfo aggregatorInfo\n );\n\n /**\n * return value of getSenderAddress\n */\n error SenderAddressResult(address sender);\n\n /**\n * return value of simulateHandleOp\n */\n error ExecutionResult(\n uint256 preOpGas,\n uint256 paid,\n uint48 validAfter,\n uint48 validUntil,\n bool targetSuccess,\n bytes targetResult\n );\n\n //UserOps handled, per aggregator\n struct UserOpsPerAggregator {\n UserOperation[] userOps;\n // aggregator address\n IAggregator aggregator;\n // aggregated signature\n bytes signature;\n }\n\n /**\n * Execute a batch of UserOperation.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(\n UserOperation[] calldata ops,\n address payable beneficiary\n ) external;\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) external;\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(\n UserOperation calldata userOp\n ) external view returns (bytes32);\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external;\n\n /**\n * gas and return values during simulation\n * @param preOpGas the gas used for validation (including preValidationGas)\n * @param prefund the required prefund for this operation\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\n */\n struct ReturnInfo {\n uint256 preOpGas;\n uint256 prefund;\n bool sigFailed;\n uint48 validAfter;\n uint48 validUntil;\n bytes paymasterContext;\n }\n\n /**\n * returned aggregated signature info.\n * the aggregator returned by the account, and its current stake.\n */\n struct AggregatorStakeInfo {\n address aggregator;\n StakeInfo stakeInfo;\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes memory initCode) external;\n\n /**\n * simulate full execution of a UserOperation (including both validation and target execution)\n * this method will always revert with \"ExecutionResult\".\n * it performs full validation of the UserOperation, but ignores signature error.\n * an optional target address is called after the userop succeeds, and its value is returned\n * (before the entire call is reverted)\n * Note that in order to collect the the success/failure of the target call, it must be executed\n * with trace enabled to track the emitted events.\n * @param op the UserOperation to simulate\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\n * are set to the return from that call.\n * @param targetCallData callData to pass to target address\n */\n function simulateHandleOp(\n UserOperation calldata op,\n address target,\n bytes calldata targetCallData\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/INonceManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\ninterface INonceManager {\n /**\n * Return the next nonce for this sender.\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\n * But UserOp with different keys can come with arbitrary order.\n *\n * @param sender the account address\n * @param key the high 192 bit of the nonce\n * @return nonce a full nonce to pass for next UserOp with this sender.\n */\n function getNonce(\n address sender,\n uint192 key\n ) external view returns (uint256 nonce);\n\n /**\n * Manually increment the nonce of the sender.\n * This method is exposed just for completeness..\n * Account does NOT need to call it, neither during validation, nor elsewhere,\n * as the EntryPoint will update the nonce regardless.\n * Possible use-case is call it with various keys to \"initialize\" their nonces to one, so that future\n * UserOperations will not pay extra for the first transaction with a given key.\n */\n function incrementNonce(uint192 key) external;\n}\n" + }, + "contracts/aa-4337/interfaces/IPaymaster.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * the interface exposed by a paymaster contract, who agrees to pay the gas for user's operations.\n * a paymaster must hold a stake to cover the required entrypoint stake and also the gas for the transaction.\n */\ninterface IPaymaster {\n enum PostOpMode {\n opSucceeded, // user op succeeded\n opReverted, // user op reverted. still has to pay for gas.\n postOpReverted //user op succeeded, but caused postOp to revert. Now it's a 2nd call, after user's op was deliberately reverted.\n }\n\n /**\n * payment validation: check if paymaster agrees to pay.\n * Must verify sender is the entryPoint.\n * Revert to reject this request.\n * Note that bundlers will reject this method if it changes the state, unless the paymaster is trusted (whitelisted)\n * The paymaster pre-pays using its deposit, and receive back a refund after the postOp method returns.\n * @param userOp the user operation\n * @param userOpHash hash of the user's request data.\n * @param maxCost the maximum cost of this transaction (based on maximum gas and gas price from userOp)\n * @return context value to send to a postOp\n * zero length to signify postOp is not required.\n * @return validationData signature and time-range of this operation, encoded the same as the return value of validateUserOperation\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validatePaymasterUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 maxCost\n ) external returns (bytes memory context, uint256 validationData);\n\n /**\n * post-operation handler.\n * Must verify sender is the entryPoint\n * @param mode enum with the following options:\n * opSucceeded - user operation succeeded.\n * opReverted - user op reverted. still has to pay for gas.\n * postOpReverted - user op succeeded, but caused postOp (in mode=opSucceeded) to revert.\n * Now this is the 2nd call, after user's op was deliberately reverted.\n * @param context - the context value returned by validatePaymasterUserOp\n * @param actualGasCost - actual gas used so far (without this postOp call).\n */\n function postOp(\n PostOpMode mode,\n bytes calldata context,\n uint256 actualGasCost\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/IStakeManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.12;\n\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by the staked entity.\n */\ninterface IStakeManager {\n event Deposited(address indexed account, uint256 totalDeposit);\n\n event Withdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /// Emitted when stake or unstake delay are modified\n event StakeLocked(\n address indexed account,\n uint256 totalStaked,\n uint256 unstakeDelaySec\n );\n\n /// Emitted once a stake is scheduled for withdrawal\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\n\n event StakeWithdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /**\n * @param deposit the entity's deposit\n * @param staked true if this entity is staked.\n * @param stake actual amount of ether staked for this entity.\n * @param unstakeDelaySec minimum delay to withdraw the stake.\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\n * and the rest fit into a 2nd cell.\n * 112 bit allows for 10^15 eth\n * 48 bit for full timestamp\n * 32 bit allows 150 years for unstake delay\n */\n struct DepositInfo {\n uint112 deposit;\n bool staked;\n uint112 stake;\n uint32 unstakeDelaySec;\n uint48 withdrawTime;\n }\n\n //API struct used by getStakeInfo and simulateValidation\n struct StakeInfo {\n uint256 stake;\n uint256 unstakeDelaySec;\n }\n\n /// @return info - full deposit information of given account\n function getDepositInfo(\n address account\n ) external view returns (DepositInfo memory info);\n\n /// @return the deposit (for gas payment) of the account\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) external payable;\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 _unstakeDelaySec) external payable;\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external;\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external;\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(\n address payable withdrawAddress,\n uint256 withdrawAmount\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/UserOperation.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable no-inline-assembly */\n\nimport {calldataKeccak} from \"../core/Helpers.sol\";\n\n/**\n * User Operation struct\n * @param sender the sender account of this request.\n * @param nonce unique value the sender uses to verify it is not a replay.\n * @param initCode if set, the account contract will be created by this constructor/\n * @param callData the method call to execute on this account.\n * @param callGasLimit the gas limit passed to the callData method call.\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\n * @param maxFeePerGas same as EIP-1559 gas parameter.\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\n */\nstruct UserOperation {\n address sender;\n uint256 nonce;\n bytes initCode;\n bytes callData;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n bytes paymasterAndData;\n bytes signature;\n}\n\n/**\n * Utility functions helpful when working with UserOperation structs.\n */\nlibrary UserOperationLib {\n function getSender(\n UserOperation calldata userOp\n ) internal pure returns (address) {\n address data;\n //read sender from userOp, which is first userOp member (saves 800 gas...)\n assembly {\n data := calldataload(userOp)\n }\n return address(uint160(data));\n }\n\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\n // pay above what he signed for.\n function gasPrice(\n UserOperation calldata userOp\n ) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function pack(\n UserOperation calldata userOp\n ) internal pure returns (bytes memory ret) {\n address sender = getSender(userOp);\n uint256 nonce = userOp.nonce;\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\n bytes32 hashCallData = calldataKeccak(userOp.callData);\n uint256 callGasLimit = userOp.callGasLimit;\n uint256 verificationGasLimit = userOp.verificationGasLimit;\n uint256 preVerificationGas = userOp.preVerificationGas;\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\n\n return\n abi.encode(\n sender,\n nonce,\n hashInitCode,\n hashCallData,\n callGasLimit,\n verificationGasLimit,\n preVerificationGas,\n maxFeePerGas,\n maxPriorityFeePerGas,\n hashPaymasterAndData\n );\n }\n\n function hash(\n UserOperation calldata userOp\n ) internal pure returns (bytes32) {\n return keccak256(pack(userOp));\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n}\n" + }, + "contracts/aa-4337/utils/Exec.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.5 <0.9.0;\n\n// solhint-disable no-inline-assembly\n\n/**\n * Utility functions helpful when making different kinds of contract calls in Solidity.\n */\nlibrary Exec {\n function call(\n address to,\n uint256 value,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := call(\n txGas,\n to,\n value,\n add(data, 0x20),\n mload(data),\n 0,\n 0\n )\n }\n }\n\n function staticcall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal view returns (bool success) {\n assembly {\n success := staticcall(txGas, to, add(data, 0x20), mload(data), 0, 0)\n }\n }\n\n function delegateCall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := delegatecall(\n txGas,\n to,\n add(data, 0x20),\n mload(data),\n 0,\n 0\n )\n }\n }\n\n // get returned data from last call or calldelegate\n function getReturnData(\n uint256 maxLen\n ) internal pure returns (bytes memory returnData) {\n assembly {\n let len := returndatasize()\n if gt(len, maxLen) {\n len := maxLen\n }\n let ptr := mload(0x40)\n mstore(0x40, add(ptr, add(len, 0x20)))\n mstore(ptr, len)\n returndatacopy(add(ptr, 0x20), 0, len)\n returnData := ptr\n }\n }\n\n // revert with explicit byte array (probably reverted info from call)\n function revertWithData(bytes memory returnData) internal pure {\n assembly {\n revert(add(returnData, 32), mload(returnData))\n }\n }\n\n function callAndRevert(\n address to,\n bytes memory data,\n uint256 maxLen\n ) internal {\n bool success = call(to, 0, data, gasleft());\n if (!success) {\n revertWithData(getReturnData(maxLen));\n }\n }\n}\n" + }, + "contracts/Barz.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"./libraries/LibDiamond.sol\";\nimport {IBarz} from \"./interfaces/IBarz.sol\";\n\n/**\n * @title Barz\n * @dev A diamond proxy wallet with a modular & upgradeable architecture\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract Barz is IBarz {\n /**\n * @notice Initializes Barz with the given parameters. Barz account is intended to be created from Barz Factory for stable deployment.\n * @dev This method makes a delegate call to account facet and account facet handles the initialization.\n * With modular architecture, Barz encompasses wide spectrum of architecture and logic.\n * The only requirement is account facet to comply with initialize() interface.\n * Barz doesn't include built-in functions and is a full proxy, for maximum extensibility and modularity.\n * @param _accountFacet Address of Account Facet in charge of the Barz initialization\n * @param _verificationFacet Address of Verification Facet for verifying the signature. Could be any signature scheme\n * @param _entryPoint Address of Entry Point contract\n * @param _facetRegistry Address of Facet Registry. Facet Registry is a registry holding trusted facets that could be added to user's wallet\n * @param _defaultFallBack Address of Default FallBack Handler. Middleware contract for more efficient deployment\n * @param _ownerPublicKey Bytes of Owner Public Key using for initialization\n */\n constructor(\n address _accountFacet,\n address _verificationFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallBack,\n bytes memory _ownerPublicKey\n ) payable {\n bytes memory initCall = abi.encodeWithSignature(\n \"initialize(address,address,address,address,bytes)\",\n _verificationFacet,\n _entryPoint,\n _facetRegistry,\n _defaultFallBack,\n _ownerPublicKey\n );\n (bool success, bytes memory result) = _accountFacet.delegatecall(\n initCall\n );\n if (!success || uint256(bytes32(result)) != 1) {\n revert Barz__InitializationFailure();\n }\n }\n\n /**\n * @notice Fallback function for Barz complying with Diamond Standard with customization of adding Default Fallback Handler\n * @dev Find facet for function that is called and execute the function if a facet is found and return any value.\n */\n fallback() external payable {\n LibDiamond.DiamondStorage storage ds;\n bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION;\n // get diamond storage\n assembly {\n ds.slot := position\n }\n // get facet from function selector\n address facet = address(bytes20(ds.facets[msg.sig]));\n if (facet == address(0))\n facet = ds.defaultFallbackHandler.facetAddress(msg.sig);\n require(facet != address(0), \"Barz: Function does not exist\");\n // Execute external function from facet using delegatecall and return any value.\n assembly {\n // copy function selector and any arguments\n calldatacopy(0, 0, calldatasize())\n // execute function call using the facet\n let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)\n // get any return value\n returndatacopy(0, 0, returndatasize())\n // return any return value or error back to the caller\n switch result\n case 0 {\n revert(0, returndatasize())\n }\n default {\n return(0, returndatasize())\n }\n }\n }\n\n /**\n * @notice Receive function to receive native token without data\n */\n receive() external payable {}\n}\n" + }, + "contracts/BarzFactory.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Barz} from \"./Barz.sol\";\nimport {IBarzFactory} from \"./interfaces/IBarzFactory.sol\";\n\n/**\n * @title Barz Factory\n * @dev Contract to easily deploy Barz to a pre-computed address with a single call\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract BarzFactory is IBarzFactory {\n event BarzDeployed(address);\n\n address public immutable accountFacet;\n address public immutable entryPoint;\n address public immutable facetRegistry;\n address public immutable defaultFallback;\n\n /**\n * @notice Sets the initialization data for Barz contract initialization\n * @param _accountFacet Account Facet to be used to create Barz\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\n * @param _facetRegistry Facet Registry to be used to create Barz\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\n */\n constructor(\n address _accountFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallback\n ) {\n accountFacet = _accountFacet;\n entryPoint = _entryPoint;\n facetRegistry = _facetRegistry;\n defaultFallback = _defaultFallback;\n }\n\n /**\n * @notice Creates the Barz with a single call. It creates the Barz contract with the givent verification facet\n * @param _verificationFacet Address of verification facet used for creating the barz account\n * @param _owner Public Key of the owner to initialize barz account\n * @param _salt Salt used for deploying barz with create2\n * @return barz Instance of Barz contract deployed with the given parameters\n */\n function createAccount(\n address _verificationFacet,\n bytes calldata _owner,\n uint256 _salt\n ) external override returns (Barz barz) {\n address addr = getAddress(_verificationFacet, _owner, _salt);\n uint codeSize = addr.code.length;\n if (codeSize > 0) {\n return Barz(payable(addr));\n }\n barz = new Barz{salt: bytes32(_salt)}(\n accountFacet,\n _verificationFacet,\n entryPoint,\n facetRegistry,\n defaultFallback,\n _owner\n );\n emit BarzDeployed(address(barz));\n }\n\n /**\n * @notice Calculates the address of Barz with the given parameters\n * @param _verificationFacet Address of verification facet used for creating the barz account\n * @param _owner Public Key of the owner to initialize barz account\n * @param _salt Salt used for deploying barz with create2\n * @return barzAddress Precalculated Barz address\n */\n function getAddress(\n address _verificationFacet,\n bytes calldata _owner,\n uint256 _salt\n ) public view override returns (address barzAddress) {\n bytes memory bytecode = getBytecode(\n accountFacet,\n _verificationFacet,\n entryPoint,\n facetRegistry,\n defaultFallback,\n _owner\n );\n bytes32 hash = keccak256(\n abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(bytecode)\n )\n );\n barzAddress = address(uint160(uint256(hash)));\n }\n\n /**\n * @notice Returns the bytecode of Barz with the given parameter\n * @param _accountFacet Account Facet to be used to create Barz\n * @param _verificationFacet Verification Facet to be used to create Barz\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\n * @param _facetRegistry Facet Registry to be used to create Barz\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\n * @param _ownerPublicKey Public Key of owner to be used to initialize Barz ownership\n * @return barzBytecode Bytecode of Barz\n */\n function getBytecode(\n address _accountFacet,\n address _verificationFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallback,\n bytes calldata _ownerPublicKey\n ) public pure override returns (bytes memory barzBytecode) {\n bytes memory bytecode = type(Barz).creationCode;\n barzBytecode = abi.encodePacked(\n bytecode,\n abi.encode(\n _accountFacet,\n _verificationFacet,\n _entryPoint,\n _facetRegistry,\n _defaultFallback,\n _ownerPublicKey\n )\n );\n }\n\n /**\n * @notice Returns the creation code of the Barz contract\n * @return creationCode Creation code of Barz\n */\n function getCreationCode()\n public\n pure\n override\n returns (bytes memory creationCode)\n {\n creationCode = type(Barz).creationCode;\n }\n}\n" + }, + "contracts/facets/AccountFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {UserOperation} from \"../aa-4337/interfaces/UserOperation.sol\";\nimport {IEntryPoint} from \"../aa-4337/interfaces/IEntryPoint.sol\";\nimport {BaseAccount} from \"../aa-4337/core/BaseAccount.sol\";\nimport {LibAppStorage, BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {IFacetRegistry} from \"../infrastructure/interfaces/IFacetRegistry.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {IERC1271} from \"../interfaces/ERC/IERC1271.sol\";\nimport {IAccountFacet} from \"./interfaces/IAccountFacet.sol\";\n\n/**\n * @title Account Facet\n * @dev Account module contract that provides the account features and initialization of signer\n * compatible with EIP-1271 & EIP-4337\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract AccountFacet is BarzStorage, BaseAccount, IAccountFacet {\n using ECDSA for bytes32;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceAccountInitialize();\n }\n\n /**\n * @notice Returns the address of EntryPoint contract registered to Barz account\n */\n function entryPoint() public view override returns (IEntryPoint) {\n return s.entryPoint;\n }\n\n /**\n * @notice Initializes the initial storage of the Barz contract.\n * @dev This method can only be called during the initialization or signature migration.\n * If the proxy contract was created without initialization, anyone can call initialize.\n * Barz calls initialize in constructor in an atomic transaction during deployment\n * @param _verificationFacet Facet contract handling the verificationi\n * @param _anEntryPoint Entrypoint contract defined in EIP-4337 handling the flow of UserOp\n * @param _facetRegistry Registry of Facets that hold all facet information\n * @param _defaultFallBackHandler Middleware contract for default facets\n * @param _ownerPublicKey Bytes of owner public key\n */\n function initialize(\n address _verificationFacet,\n address _anEntryPoint,\n address _facetRegistry,\n address _defaultFallBackHandler,\n bytes calldata _ownerPublicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceAccountInitialize();\n s.entryPoint = IEntryPoint(_anEntryPoint);\n s.facetRegistry = IFacetRegistry(_facetRegistry);\n LibDiamond.diamondStorage().defaultFallbackHandler = IDiamondLoupe(\n _defaultFallBackHandler\n );\n\n _cutDiamondAccountFacet(_verificationFacet);\n\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n _ownerPublicKey\n );\n // Every Verification Facet should comply with initializeSigner(bytes)\n // to be compatible with the Barz contract(for initialization)\n (bool success, bytes memory result) = _verificationFacet.delegatecall(\n initCall\n );\n if (!success || uint256(bytes32(result)) != 1) {\n revert AccountFacet__InitializationFailure();\n }\n\n initSuccess = 1;\n emit AccountInitialized(s.entryPoint, _ownerPublicKey);\n }\n\n function _cutDiamondAccountFacet(address _verificationFacet) internal {\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](1);\n\n bytes4 ownerVerificationFuncSelector = IVerificationFacet(\n _verificationFacet\n ).validateOwnerSignatureSelector();\n\n bytes4[] memory verificationFunctionSelectors = new bytes4[](3);\n verificationFunctionSelectors[0] = IERC1271.isValidSignature.selector;\n verificationFunctionSelectors[1] = ownerVerificationFuncSelector;\n verificationFunctionSelectors[2] = IVerificationFacet.owner.selector;\n cut[0] = IDiamondCut.FacetCut({\n facetAddress: _verificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: verificationFunctionSelectors\n });\n\n LibDiamond.diamondCut(cut, address(0), \"\");\n }\n\n /**\n * @notice Calls the destination with inputted calldata and value from EntryPoint\n * @dev This method executes the calldata coming from the EntryPoint.\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\n * @param _dest Address of destination where the call will be forwarded to\n * @param _value Amount of native coin the owner is willing to send(e.g. ETH, BNB)\n * @param _func Bytes of calldata to execute in the destination address\n */\n function execute(\n address _dest,\n uint256 _value,\n bytes calldata _func\n ) external override onlyWhenUnlocked {\n _requireFromEntryPoint();\n _call(_dest, _value, _func);\n }\n\n /**\n * @notice Batch calls the destination with inputted calldata and value from EntryPoint\n * @dev This method batch executes the calldata coming from the EntryPoint.\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\n * @param _dest Array of addresses of destination where the call will be forwarded to\n * @param _value Array of amount of native coin the owner is willing to send(e.g. ETH, BNB)\n * @param _func Array of bytes of calldata to execute in the destination address\n */\n function executeBatch(\n address[] calldata _dest,\n uint256[] calldata _value,\n bytes[] calldata _func\n ) external override onlyWhenUnlocked {\n _requireFromEntryPoint();\n uint256 destLength = _dest.length;\n require(\n destLength == _func.length && destLength == _value.length,\n \"wrong array lengths\"\n );\n for (uint256 i; i < destLength; ) {\n _call(_dest[i], _value[i], _func[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Validates the signature field of UserOperation\n * @dev This method validates if the signature of UserOp is indeed valid by delegating the call to Verification Facet\n * Barz makes a call to the pre-registered Verification Facet address in App Storage\n * @param _userOp UserOperation from owner to be validated\n * @param _userOpHash Hash of UserOperation given from the EntryPoint contract\n */\n function _validateSignature(\n UserOperation calldata _userOp,\n bytes32 _userOpHash\n ) internal override returns (uint256 validationData) {\n // Get Facet with Function Selector\n address facet = LibLoupe.facetAddress(s.validateOwnerSignatureSelector);\n if (facet == address(0))\n revert AccountFacet__NonExistentVerificationFacet();\n\n // Make function call to VerificationFacet\n bytes memory validateCall = abi.encodeWithSelector(\n s.validateOwnerSignatureSelector,\n _userOp,\n _userOpHash\n );\n (bool success, bytes memory result) = facet.delegatecall(validateCall);\n if (!success) revert AccountFacet__CallNotSuccessful();\n validationData = uint256(bytes32(result));\n if (validationData == 0) emit VerificationSuccess(_userOpHash);\n else emit VerificationFailure(_userOpHash);\n }\n\n /**\n * @notice Calls the target with the inputted value and calldata\n * @dev This method is the actual function in Barz that makes a call with an arbitrary owner-given data\n * @param _target Address of the destination contract which the call is getting forwarded to\n * @param _value Amount of Native coin the owner is wanting to make in this call\n * @param _data Calldata the owner is forwarding together in the call e.g. Swap/Token Transfer\n */\n function _call(\n address _target,\n uint256 _value,\n bytes memory _data\n ) internal {\n if (_checkRestrictions(_target, _value, _data) == 1)\n revert AccountFacet__RestrictionsFailure();\n\n (bool success, bytes memory result) = _target.call{value: _value}(\n _data\n );\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n }\n\n /**\n * @notice Checks restrictions if the restrictions facet exists\n * @dev This method checks if the restrictions facet exists and makes a verification call to an array of restrictions facet\n * @param _target Address the call is getting forwarded to\n * @param _value Amount of native coin the call is sending together with the call\n * @param _data Calldata to trigger execution in target address\n */\n function _checkRestrictions(\n address _target,\n uint256 _value,\n bytes memory _data\n ) internal returns (uint256 result) {\n address facet = LibDiamond.restrictionsFacet();\n // NOTE: No restrictions facet, so restriction validation passes\n if (facet == address(0)) return 0;\n bytes memory call = abi.encodeWithSignature(\n \"verifyRestrictions(address,address,uint256,bytes)\",\n address(this),\n _target,\n _value,\n _data\n );\n (bool success, bytes memory response) = facet.delegatecall(call);\n if (!success) revert AccountFacet__RestrictionsFailure();\n result = uint256(bytes32(response));\n }\n}\n" + }, + "contracts/facets/AccountRecoveryFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibFacetStorage, RecoveryStorage, RecoveryConfig, RecoveryApprovalConfig, ApprovalConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {IAccountRecoveryFacet} from \"./interfaces/IAccountRecoveryFacet.sol\";\n\n/**\n * @title Account Recovery Facet\n * @dev Contract that enables recovery of accounts when owner key is unavailable\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract AccountRecoveryFacet is IAccountRecoveryFacet, Modifiers {\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Approve recovery of account as guardian\n * @dev This method can only be called by guardian and guardian inputs the public key of the new owner\n * When the threshold(majority of guardians) passes, it automatically executes account recovery\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function approveAccountRecovery(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + _getApprovalValidationPeriod()\n );\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit RecoveryApproved(\n _recoveryPublicKey,\n msg.sender,\n approvalValidUntil\n );\n if (\n getRecoveryApprovalCountWithTimeValidity(recoveryPublicKeyHash) >=\n LibGuardian.majorityOfGuardians()\n ) _executeRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Revoke recovery of account as guardian\n * @dev This method can only be called by guardian and guardian inputs the public key of the new owner\n When the threshold(majority of guardians) passes, it automatically revokes account recovery when recovery is pending\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function revokeAccountRecoveryApproval(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n if (\n !rs\n .isNewOwnerApproved[recoveryPublicKeyHash][msg.sender].isApproved ||\n !(block.timestamp <\n rs\n .isNewOwnerApproved[recoveryPublicKeyHash][msg.sender]\n .validUntil)\n ) revert AccountRecoveryFacet__NonExistentApproval();\n\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(false, 0);\n emit RecoveryApprovalRevoked(_recoveryPublicKey, msg.sender);\n }\n\n /**\n * @notice Executes recovery with signatures or on-chain pre-approvals\n * @dev This method validates the signatures of guardians or checks the on-chain pre-approved calls to check if the threshold passes\n * When the threshold passes, account recovery is executed and revert otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _guardians Array of guardians address that are approving the recovery of Account\n * @param _signatures Array of signature bytes that signed the approval hash\n */\n function executeRecovery(\n bytes calldata _recoveryPublicKey,\n address[] calldata _guardians,\n bytes[] calldata _signatures\n ) external override {\n if (_isRecoveryPending())\n revert AccountRecoveryFacet__RecoveryAlreadyOngoing();\n uint256 guardiansLength = _guardians.length;\n if (guardiansLength != _signatures.length)\n revert AccountRecoveryFacet__InvalidArrayLength();\n validateNewOwner(_recoveryPublicKey);\n\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n\n _checkApprover(_guardians);\n _checkDuplicateOnChainApprover(recoveryPublicKeyHash, _guardians);\n\n if (\n guardiansLength +\n getRecoveryApprovalCountWithTimeValidity(\n recoveryPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians()\n ) revert AccountRecoveryFacet__InsufficientGuardians();\n for (uint256 i; i < guardiansLength; ) {\n if (!LibGuardian.isGuardian(_guardians[i]))\n revert AccountRecoveryFacet__InvalidGuardian();\n if (\n !SignatureChecker.isValidSignatureNow(\n _guardians[i],\n recoveryPublicKeyHash,\n _signatures[i]\n )\n ) revert AccountRecoveryFacet__InvalidGuardianSignature();\n unchecked {\n ++i;\n }\n }\n _executeRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Executes recovery of the account. Note that execution and finalization is a different process\n * @dev Executes the recovery and adds recovery data to recovery configuration. Locks the account\n * @param _recoveryPublicKey Public Key of the account for recovery\n */\n function _executeRecovery(bytes memory _recoveryPublicKey) internal {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n ++rs.nonce;\n uint64 executeAfter = uint64(block.timestamp + _getRecoveryPeriod());\n rs.recoveryConfigs[INNER_STRUCT] = RecoveryConfig(\n _recoveryPublicKey,\n executeAfter // NOTE: Remove guardian Count\n );\n LibAppStorage.setLock(\n block.timestamp + _getLockPeriod(),\n AccountRecoveryFacet.executeRecovery.selector\n );\n emit RecoveryExecuted(_recoveryPublicKey, executeAfter);\n }\n\n /**\n * @notice Finalize recovery after recovery pending period. Recovery pending period can be set by user beforehand in SecurityManager\n * @dev This method finalizes recovery and fully changes the ownership of the account to the newly inputted recovery public key\n */\n function finalizeRecovery() external override {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n if (\n uint64(block.timestamp) <=\n rs.recoveryConfigs[INNER_STRUCT].executeAfter\n ) revert AccountRecoveryFacet__RecoveryPeriodNotOver();\n bytes memory recoveryOwner = rs\n .recoveryConfigs[INNER_STRUCT]\n .recoveryPublicKey;\n\n delete rs.recoveryConfigs[INNER_STRUCT];\n\n LibAppStorage.setLock(0, bytes4(0));\n\n LibAppStorage.initiateSignerMigration();\n address verificationFacet = address(\n bytes20(\n LibDiamond.diamondStorage().facets[\n s.validateOwnerSignatureSelector\n ]\n )\n );\n bytes memory uninitCall = abi.encodeWithSignature(\n \"uninitializeSigner()\"\n );\n (bool success, bytes memory result) = verificationFacet.delegatecall(\n uninitCall\n );\n if (!success) revert AccountRecoveryFacet__CallNotSuccesful();\n uint256 validationData = uint256(bytes32(result));\n if (validationData != 1)\n revert AccountRecoveryFacet__SignerUninitializationFailure();\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n recoveryOwner\n );\n (success, result) = verificationFacet.delegatecall(initCall);\n if (!success) revert AccountRecoveryFacet__CallNotSuccesful();\n validationData = uint256(bytes32(result));\n if (validationData != 1)\n revert AccountRecoveryFacet__SignerInitializationFailure();\n LibAppStorage.finalizeSignerMigration();\n emit RecoveryFinalized(recoveryOwner);\n }\n\n /**\n * @notice Approves the cancellation of recovery\n * @dev This method approves the cancellation of recovery when recovery is still pending - waiting for finalization\n * @param _recoveryPublicKey Bytes of public key which is pending for recovery\n */\n function approveCancelRecovery(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"CancelRecovery\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + _getApprovalValidationPeriod()\n );\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit RecoveryCancellationApproved(_recoveryPublicKey, msg.sender);\n if (\n getRecoveryApprovalCountWithTimeValidity(recoveryPublicKeyHash) >=\n LibGuardian.majorityOfGuardians()\n ) {\n _cancelRecovery(_recoveryPublicKey);\n }\n }\n\n /**\n * @notice Hardstops an ongoing recovery\n * @dev This method provides a safety mechanism to protect owners of malicious guardians.\n * Owners can hardstop recovery when an malicious guardians starts the recovery process.\n * @param _signature Signature of the owner that signs the hash to hardstop recovery\n */\n function hardstopRecovery(bytes calldata _signature) external override {\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n \"0\",\n \"HardstopRecovery\"\n );\n if (\n !SignatureChecker.isValidSignatureNow(\n address(this),\n recoveryPublicKeyHash,\n _signature\n )\n ) revert AccountRecoveryFacet__InvalidOwnerSignature();\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n ++rs.nonce;\n delete rs.recoveryConfigs[INNER_STRUCT];\n LibAppStorage.setLock(0, bytes4(0));\n emit RecoveryHardstopped();\n }\n\n /**\n * @notice Cancels recovery with signatures or on-chain pre-approvals\n * @dev This method validates the signatures of guardians or checks the on-chain pre-approved calls to check if the threshold passes\n * When the threshold passes, account recovery is canceled and revert otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _guardians Array of guardians address that are approving the recovery of Account\n * @param _signatures Array of signature bytes that signed the cancellation approval hash\n */\n function cancelRecovery(\n bytes calldata _recoveryPublicKey,\n address[] calldata _guardians,\n bytes[] calldata _signatures\n ) external override {\n uint256 guardiansLength = _guardians.length;\n if (guardiansLength != _signatures.length)\n revert AccountRecoveryFacet__InvalidArrayLength();\n validateNewOwner(_recoveryPublicKey);\n\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"CancelRecovery\"\n );\n\n _checkApprover(_guardians);\n _checkDuplicateOnChainApprover(recoveryPublicKeyHash, _guardians);\n\n if (\n guardiansLength +\n getRecoveryApprovalCountWithTimeValidity(\n recoveryPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians()\n ) revert AccountRecoveryFacet__InsufficientGuardians();\n for (uint256 i; i < guardiansLength; ) {\n if (!LibGuardian.isGuardian(_guardians[i]))\n revert AccountRecoveryFacet__CallerNotGuardian();\n if (\n !SignatureChecker.isValidSignatureNow(\n _guardians[i],\n recoveryPublicKeyHash,\n _signatures[i]\n )\n ) revert AccountRecoveryFacet__InvalidGuardianSignature();\n unchecked {\n ++i;\n }\n }\n _cancelRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Cancel recovery when the recovery is pending. Unlock the account as well\n * @dev This method checks if the recovery is pending and reverts if not pending.\n * It increases the recovery nonce and deletes the recovery information and gets a small portion of gas in return\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function _cancelRecovery(bytes memory _recoveryPublicKey) internal {\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n LibAppStorage.setLock(0, bytes4(0));\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n ++rs.nonce;\n delete rs.recoveryConfigs[INNER_STRUCT];\n emit RecoveryCanceled(_recoveryPublicKey);\n }\n\n /**\n * @notice Validates the format of public key to be used for recovery\n * @dev This method checks if the public key format is correct and reverts otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function validateNewOwner(bytes memory _recoveryPublicKey) public view {\n if (\n !IVerificationFacet(\n LibLoupe.facetAddress(s.validateOwnerSignatureSelector)\n ).isValidKeyType(_recoveryPublicKey)\n ) revert AccountRecoveryFacet__InvalidRecoveryPublicKey();\n }\n\n /**\n * @notice Checks if recovery is currently pending\n * @return isPending Boolean indicating if recovery is pending\n */\n function _isRecoveryPending() internal view returns (bool isPending) {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n isPending = (rs.recoveryConfigs[INNER_STRUCT].executeAfter > 0);\n }\n\n /**\n * @notice Calculate the recovery hash dependent on chain, wallet address, nonce with EIP-191 prefix for safety\n * @dev Returns the keccak256 hash of EIP-191 msg hash packed with public key, salt, nonce, wallet address, etc\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _saltString Salt string to uniquely identify each recovery hash and for security\n * @return recoveryKeyHash Bytes32 string of the recovery hash\n */\n function getApprovalRecoveryKeyHash(\n bytes memory _recoveryPublicKey,\n string memory _saltString\n ) public view override returns (bytes32 recoveryKeyHash) {\n recoveryKeyHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n _recoveryPublicKey,\n _saltString,\n address(this),\n block.chainid,\n LibFacetStorage.recoveryStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Check the onchain approval of guardians and returns the number of guardians that approved\n * @dev Loop through the guardian addresses and returns the number of guardians that approved this recovery hash\n * @param _recoveryPublicKeyHash Bytes hash of newly recovered public key and recovery value of the account\n * @return approvalCount Number of guardians that approved\n */\n function getRecoveryApprovalCountWithTimeValidity(\n bytes32 _recoveryPublicKeyHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n for (uint256 i; i < guardianLength; ) {\n if (isRecoveryApproved(_recoveryPublicKeyHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Checks if the recovery is approved by the given approver\n * @param _recoveryPublicKeyHash Hash of the public key and configuration for recovery\n * @param _approver Address of approver\n * @return isApproved Bool value if recovery hash is approved\n */\n function isRecoveryApproved(\n bytes32 _recoveryPublicKeyHash,\n address _approver\n ) public view override returns (bool isApproved) {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n if (\n rs\n .isNewOwnerApproved[_recoveryPublicKeyHash][_approver].isApproved &&\n block.timestamp <\n rs.isNewOwnerApproved[_recoveryPublicKeyHash][_approver].validUntil\n ) {\n isApproved = true;\n }\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _recoveryPublicKeyHash Hash of recovery information\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _recoveryPublicKeyHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isRecoveryApproved(_recoveryPublicKeyHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert AccountRecoveryFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the lock period of this wallet address from security manager\n * @return lockPeriod value of lock period\n */\n function _getLockPeriod() internal view returns (uint256 lockPeriod) {\n lockPeriod = securityManager.lockPeriodOf(address(this));\n if (lockPeriod == 0) revert AccountRecoveryFacet__InvalidLockPeriod();\n }\n\n /**\n * @notice Returns the lock period of this wallet address from security manager\n * @return recoveryPeriod value of recovery period\n */\n function _getRecoveryPeriod()\n internal\n view\n returns (uint256 recoveryPeriod)\n {\n recoveryPeriod = securityManager.recoveryPeriodOf(address(this));\n if (recoveryPeriod == 0)\n revert AccountRecoveryFacet__InvalidRecoveryPeriod();\n }\n\n /**\n * @notice Returns the approval validation period of this wallet address from security manager\n * @return approvalValidationPeriod value of approval validation period\n */\n function _getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod == 0)\n revert AccountRecoveryFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the recovery nonce of this wallet address from security manager\n * @return nonce value of recovery nonce\n */\n function getRecoveryNonce() public view override returns (uint128 nonce) {\n nonce = LibFacetStorage.recoveryStorage().nonce;\n }\n\n /**\n * @notice Returns the recovery information of the pending recovery\n * @return recoveryConfig value struct of pending recovery\n */\n function getPendingRecovery()\n public\n view\n override\n returns (RecoveryConfig memory recoveryConfig)\n {\n recoveryConfig = LibFacetStorage.recoveryStorage().recoveryConfigs[\n INNER_STRUCT\n ];\n }\n}\n" + }, + "contracts/facets/base/DiamondCutFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibGuardian} from \"../../libraries/LibGuardian.sol\";\nimport {ISecurityManager} from \"../../infrastructure/interfaces/ISecurityManager.sol\";\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibFacetStorage, DiamondCutApprovalConfig, ApprovalConfig} from \"../../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"../Modifiers.sol\";\nimport {IDiamondCut} from \"./interfaces/IDiamondCut.sol\";\n\n/**\n * @title DiamondCut Facet\n * @dev Responsible for adding/removing/replace facets in Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DiamondCutFacet is Modifiers, IDiamondCut {\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Updates the flag for the interfaceId\n * @param _interfaceId InterfaceID to update the mapping\n * @param _flag Bool value to update the mapping of the given interface ID\n */\n function updateSupportsInterface(\n bytes4 _interfaceId,\n bool _flag\n ) external override onlyWhenUnlocked {\n LibDiamond.enforceIsSelf();\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId] = _flag;\n emit SupportsInterfaceUpdated(_interfaceId, _flag);\n }\n\n /**\n * @notice Add/replace/remove any number of functions and optionally execute\n * a function with delegatecall when guardians don't exist\n * @param _diamondCut Contains the facet addresses and function selectors\n * @param _init The address of the contract or facet to execute _calldata\n * @param _calldata A function call, including function selector and arguments\n * _calldata is executed with delegatecall on _init\n */\n function diamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) external override onlyWhenUnlocked {\n LibDiamond.enforceIsSelf();\n\n _checkFacetCutValidity(_diamondCut);\n // require approval from guardian if guardian exists\n if (0 != LibGuardian.guardianCount())\n revert DiamondCutFacet__InvalidRouteWithGuardian();\n\n ++LibFacetStorage.diamondCutStorage().nonce;\n LibDiamond.diamondCut(_diamondCut, _init, _calldata);\n }\n\n /**\n * @notice Add/replace/remove any number of functions and optionally execute\n * a function with delegatecall when guardians exist\n * @param _diamondCut Contains the facet addresses and function selectors\n * @param _init The address of the contract or facet to execute _calldata\n * @param _calldata A function call, including function selector and arguments\n * _calldata is executed with delegatecall on _init\n * @param _approvers Guardian or owner address that approves the diamond cut\n * @param _signatures Signature of Guardians or owner that approves the diamond cut\n */\n function diamondCutWithGuardian(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n ) external override onlyWhenUnlocked {\n uint256 approverLength = _approvers.length;\n if (approverLength != _signatures.length)\n revert DiamondCutFacet__InvalidArrayLength();\n _checkFacetCutValidity(_diamondCut);\n if (0 == LibGuardian.guardianCount())\n revert DiamondCutFacet__InvalidRouteWithGuardian();\n\n bytes32 cutHash = getDiamondCutHash(_diamondCut, _init, _calldata);\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(cutHash, _approvers);\n\n bool onChainOwnerApproval = getOwnerCutApprovalWithTimeValidity(\n cutHash\n );\n\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n if (\n approverLength +\n getDiamondCutApprovalCountWithTimeValidity(cutHash) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert DiamondCutFacet__InsufficientApprovers();\n\n bool ownerApproved;\n for (uint256 i; i < approverLength; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n _approvers[i] != address(this)\n ) revert DiamondCutFacet__InvalidApprover();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert DiamondCutFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n cutHash,\n _signatures[i]\n )\n ) revert DiamondCutFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n if (!ownerApproved && !onChainOwnerApproval)\n revert DiamondCutFacet__LackOfOwnerApproval();\n\n ++LibFacetStorage.diamondCutStorage().nonce;\n LibDiamond.diamondCut(_diamondCut, _init, _calldata);\n }\n\n /**\n * @notice Approves diamond cut. This can only be called directly from guardian or owner\n * @param _diamondCut Contains the facet addresses and function selectors\n * @param _init The address of the contract or facet to execute _calldata\n * @param _calldata A function call, including function selector and arguments\n * _calldata is executed with delegatecall on _init\n */\n function approveDiamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\n if (LibGuardian.guardianCount() == 0)\n revert DiamondCutFacet__InvalidRouteWithoutGuardian();\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n _checkFacetCutValidity(_diamondCut);\n\n bytes32 cutHash = getDiamondCutHash(_diamondCut, _init, _calldata);\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(\n true,\n approvalValidUntil\n );\n emit DiamondCutApproved(_diamondCut, _init, _calldata);\n if (\n (getDiamondCutApprovalCountWithTimeValidity(cutHash) >=\n LibGuardian.majorityOfGuardians()) &&\n getOwnerCutApprovalWithTimeValidity(cutHash)\n ) {\n ++LibFacetStorage.diamondCutStorage().nonce;\n LibDiamond.diamondCut(_diamondCut, _init, _calldata);\n }\n }\n\n /**\n * @notice Revokes the approval of diamond cut. This can only be called directly from guardian or owner\n * @param _diamondCut Contains the facet addresses and function selectors\n * @param _init The address of the contract or facet to execute _calldata\n * @param _calldata A function call, including function selector and arguments\n * _calldata is executed with delegatecall on _init\n */\n function revokeDiamondCutApproval(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n bytes32 cutHash = getDiamondCutHash(_diamondCut, _init, _calldata);\n if (!ds.isDiamondCutApproved[cutHash][msg.sender].isApproved)\n revert DiamondCutFacet__CannotRevokeUnapproved();\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(false, 0);\n emit DiamondCutApprovalRevoked(_diamondCut, _init, _calldata);\n }\n\n /**\n * @notice Gets the number of approvals of diamond cut from guardians\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n */\n function getDiamondCutApprovalCountWithTimeValidity(\n bytes32 _diamondCutHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardiansLength = guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n if (isCutApproved(_diamondCutHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n return approvalCount;\n }\n\n /**\n * @notice Returns if the owner has approved the diamond cut\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @return isApprovedByOwner Bool value showing if the owner approved the cut\n */\n function getOwnerCutApprovalWithTimeValidity(\n bytes32 _diamondCutHash\n ) public view override returns (bool isApprovedByOwner) {\n isApprovedByOwner = isCutApproved(_diamondCutHash, address(this));\n }\n\n /**\n * @notice Returns if the given approver has approved the diamond cut\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @param _approver Address of approver\n * @return isApproved Bool value showing if the approver approved the cut\n */\n function isCutApproved(\n bytes32 _diamondCutHash,\n address _approver\n ) public view override returns (bool isApproved) {\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n isApproved = (ds\n .isDiamondCutApproved[_diamondCutHash][_approver].isApproved &&\n block.timestamp <\n ds.isDiamondCutApproved[_diamondCutHash][_approver].validUntil);\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _diamondCutHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isCutApproved(_diamondCutHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert DiamondCutFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the diamond cut hash. This function ensures that this hash is safe from replay attack by including\n * salt, address, chainId, and nonce, etc.\n * @param _diamondCut Contains the facet addresses and function selectors\n * @param _init The address of the contract or facet to execute _calldata\n * @param _calldata A function call, including function selector and arguments\n * _calldata is executed with delegatecall on _init\n * @return cutHash Diamond Cut Hash\n */\n function getDiamondCutHash(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) public view override returns (bytes32 cutHash) {\n cutHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n keccak256(abi.encode(_diamondCut)),\n _init,\n _calldata,\n address(this),\n block.chainid,\n LibFacetStorage.diamondCutStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Returns the approval validation Period\n * @dev This method fetches the validation period from the security manager\n * @return approvalValidationPeriod Approval validation period of Barz contract fetched from security manager\n */\n function getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod <= 0)\n revert DiamondCutFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the diamond cut nonce of this wallet\n * @dev This method fetches the nonce from diamond cut storage\n * @return cutNonce Nonce of diamond cut to protect from reply attacks\n */\n function getDiamondCutNonce()\n public\n view\n override\n returns (uint128 cutNonce)\n {\n cutNonce = LibFacetStorage.diamondCutStorage().nonce;\n }\n}\n" + }, + "contracts/facets/base/DiamondLoupeFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {IERC165} from \"../../interfaces/ERC/IERC165.sol\";\nimport {IERC1271} from \"../../interfaces/ERC/IERC1271.sol\";\nimport {IERC677Receiver} from \"../../interfaces/ERC/IERC677Receiver.sol\";\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC1155Receiver} from \"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\";\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../../libraries/LibLoupe.sol\";\nimport {LibUtils} from \"../../libraries/LibUtils.sol\";\nimport {IDiamondCut} from \"../../facets/base/interfaces/IDiamondCut.sol\";\nimport {IStorageLoupe} from \"./interfaces/IStorageLoupe.sol\";\nimport {IDiamondLoupe} from \"./interfaces/IDiamondLoupe.sol\";\n\n/**\n * @title DiamondLoupe Facet\n * @dev DiamondLoupe contract compatible with EIP-2535\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DiamondLoupeFacet is IDiamondLoupe, IStorageLoupe, IERC165 {\n // Diamond Loupe Functions\n ////////////////////////////////////////////////////////////////////\n /// These functions are expected to be called frequently by tools off-chain.\n\n /**\n * @notice Gets all facets and their selectors.\n * @dev Barz uses a special architecture called default fallback handler. Default Fallback handler is used as a middleware\n * that holds the mapping of facet function selector and facet address that Barz uses. This helps Barz to reduce\n * significant amount of gas during the initialization process.\n * Hence, this method aggregates both the facet information from DefaulFallbackHandler and in diamond storage and shows the data to users.\n * @return facets_ Facet\n */\n function facets() public view override returns (Facet[] memory facets_) {\n Facet[] memory defaultFacet = LibDiamond\n .diamondStorage()\n .defaultFallbackHandler\n .facets();\n Facet[] memory _facets = LibLoupe.facets();\n uint256 numFacets = _facets.length;\n bytes4[] memory keys;\n address[] memory values;\n for (uint256 i; i < numFacets; ) {\n uint256 selectorsLength = _facets[i].functionSelectors.length;\n for (uint256 j; j < selectorsLength; ) {\n (keys, values) = LibUtils.setValue(\n keys,\n values,\n _facets[i].functionSelectors[j],\n _facets[i].facetAddress\n );\n unchecked {\n ++j;\n }\n }\n unchecked {\n ++i;\n }\n }\n {\n bool iIncrement;\n for (uint256 i; i < defaultFacet.length; ) {\n bool jIncrement;\n for (\n uint256 j;\n j < defaultFacet[i].functionSelectors.length;\n\n ) {\n if (\n LibUtils.getValue(\n keys,\n values,\n defaultFacet[i].functionSelectors[j]\n ) != address(0)\n ) {\n if (defaultFacet[i].functionSelectors.length == 1) {\n defaultFacet = LibUtils.removeFacetElement(\n defaultFacet,\n i\n );\n iIncrement = true;\n break;\n }\n defaultFacet[i].functionSelectors = LibUtils\n .removeElement(\n defaultFacet[i].functionSelectors,\n j\n );\n jIncrement = true;\n }\n if (!jIncrement) {\n unchecked {\n ++j;\n }\n } else {\n jIncrement = false;\n }\n }\n if (!iIncrement) {\n unchecked {\n ++i;\n }\n } else {\n iIncrement = false;\n }\n }\n }\n {\n uint256 facetLength = numFacets + defaultFacet.length;\n facets_ = new Facet[](facetLength);\n uint256 defaultFacetIndex;\n for (uint256 i; i < facetLength; ) {\n if (i < numFacets) {\n facets_[i] = _facets[i];\n bool jIncrementor;\n for (uint256 j; j < defaultFacet.length; ) {\n if (\n facets_[i].facetAddress ==\n defaultFacet[j].facetAddress\n ) {\n facets_[i].functionSelectors = LibUtils.mergeArrays(\n _facets[i].functionSelectors,\n defaultFacet[j].functionSelectors\n );\n defaultFacet = LibUtils.removeFacetElement(\n defaultFacet,\n j\n );\n jIncrementor = true;\n {\n facets_ = LibUtils.removeFacetElement(\n facets_,\n facets_.length - 1\n );\n }\n --facetLength;\n }\n if (!jIncrementor) {\n unchecked {\n ++j;\n }\n } else {\n jIncrementor = false;\n }\n }\n } else {\n facets_[i] = defaultFacet[defaultFacetIndex];\n ++defaultFacetIndex;\n }\n unchecked {\n ++i;\n }\n }\n }\n }\n\n /**\n * @notice Gets all the function selectors provided by a facet.\n * @param _facet The facet address.\n * @return facetFunctionSelectors_\n */\n function facetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n Facet[] memory facet = facets();\n uint256 facetLength = facet.length;\n for (uint256 i; i < facetLength; ) {\n if (facet[i].facetAddress == _facet)\n return facet[i].functionSelectors;\n unchecked {\n ++i;\n }\n }\n return facetFunctionSelectors_;\n }\n\n /**\n * @notice Get all the facet addresses used by Barz.\n * @return facetAddresses_\n */\n function facetAddresses()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n Facet[] memory facet = facets();\n uint256 facetLength = facet.length;\n facetAddresses_ = new address[](facetLength);\n for (uint256 i; i < facetLength; ) {\n facetAddresses_[i] = facet[i].facetAddress;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Gets the facet that supports the given selector.\n * @dev If facet is not found return address(0).\n * @param _functionSelector The function selector.\n * @return facetAddress_ The facet address.\n */\n function facetAddress(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n\n facetAddress_ = address(bytes20(ds.facets[_functionSelector]));\n if (facetAddress_ == address(0)) {\n facetAddress_ = IDiamondLoupe(ds.defaultFallbackHandler)\n .facetAddress(_functionSelector);\n }\n }\n\n /**\n * @notice SupportInterface to be compatible with EIP 165\n * @param _interfaceId Interface ID for detecting the interface\n * @return isSupported Bool value showing if the standard is supported in the contract\n */\n function supportsInterface(\n bytes4 _interfaceId\n ) external view override returns (bool isSupported) {\n isSupported =\n _interfaceId == type(IERC165).interfaceId ||\n _interfaceId == IDiamondCut.diamondCut.selector ||\n _interfaceId == type(IDiamondLoupe).interfaceId ||\n _interfaceId == type(IERC1155Receiver).interfaceId ||\n _interfaceId == type(IERC721Receiver).interfaceId ||\n _interfaceId == type(IERC777Recipient).interfaceId ||\n _interfaceId == IERC1271.isValidSignature.selector ||\n _interfaceId == type(IERC677Receiver).interfaceId ||\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId];\n }\n\n /**\n * @notice Returns the facet from the diamond storage. This excludes the facets from the default fallback handler\n * @return facets_ Facet information attached directly to diamond storage\n */\n function facetsFromStorage()\n external\n view\n override\n returns (Facet[] memory facets_)\n {\n facets_ = LibLoupe.facets();\n }\n\n /**\n * @notice Returns the facet address attached to the given function selector. This excludes the facets from the default fallback handler\n * @param _functionSelector Function selector to fetch the facet address from diamond storage\n * @return facetAddress_ Facet address mapped with the function selector\n */\n function facetAddressFromStorage(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n facetAddress_ = LibLoupe.facetAddress(_functionSelector);\n }\n\n /**\n * @notice Returns all facet addresses attached directly to diamond storage. This excludes the facets from the default fallback handler\n * @return facetAddresses_ All facet addresses attached directly to diamond storage\n */\n function facetAddressesFromStorage()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n facetAddresses_ = LibLoupe.facetAddresses();\n }\n\n /**\n * @notice Returns function selectors of given facet address attached directly to diamond storage. This excludes the facets from the default fallback handler\n * @param _facet Facet address to fetch the facet function selectors from diamond storage\n * @return facetFunctionSelectors_ Facet function selectors of the given facet address\n */\n function facetFunctionSelectorsFromStorage(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n facetFunctionSelectors_ = LibLoupe.facetFunctionSelectors(_facet);\n }\n}\n" + }, + "contracts/facets/base/interfaces/IDiamondCut.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title DiamondCut Facet Interface\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IDiamondCut {\n error DiamondCutFacet__InvalidRouteWithGuardian();\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\n error DiamondCutFacet__InvalidArrayLength();\n error DiamondCutFacet__InsufficientApprovers();\n error DiamondCutFacet__InvalidApprover();\n error DiamondCutFacet__InvalidApproverSignature();\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\n error DiamondCutFacet__CannotRevokeUnapproved();\n error DiamondCutFacet__GuardianApprovalNotRequired();\n error DiamondCutFacet__LackOfOwnerApproval();\n error DiamondCutFacet__OwnerAlreadyApproved();\n error DiamondCutFacet__DuplicateApproval();\n\n event DiamondCutApproved(\n FacetCut[] diamondCut,\n address init,\n bytes initCalldata\n );\n event DiamondCutApprovalRevoked(\n FacetCut[] diamondCut,\n address init,\n bytes initCalldata\n );\n\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\n\n enum FacetCutAction {\n Add,\n Replace,\n Remove\n }\n // Add=0, Replace=1, Remove=2\n\n struct FacetCut {\n address facetAddress;\n FacetCutAction action;\n bytes4[] functionSelectors;\n }\n\n /// @notice Add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param diamondCut Contains the facet addresses and function selectors\n /// @param init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function diamondCut(\n FacetCut[] calldata diamondCut,\n address init,\n bytes calldata _calldata\n ) external;\n\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\n\n function diamondCutWithGuardian(\n FacetCut[] calldata diamondCut,\n address init,\n bytes calldata _calldata,\n address[] calldata approvers,\n bytes[] calldata signatures\n ) external;\n\n function approveDiamondCut(\n FacetCut[] calldata diamondCut,\n address init,\n bytes calldata _calldata\n ) external;\n\n function revokeDiamondCutApproval(\n FacetCut[] calldata diamondCut,\n address init,\n bytes calldata _calldata\n ) external;\n\n function getDiamondCutApprovalCountWithTimeValidity(\n bytes32 diamondCutHash\n ) external view returns (uint256);\n\n function getOwnerCutApprovalWithTimeValidity(\n bytes32 diamondCutHash\n ) external view returns (bool);\n\n function isCutApproved(\n bytes32 diamondCutHash,\n address approver\n ) external view returns (bool);\n\n function getDiamondCutHash(\n FacetCut[] calldata diamondCut,\n address init,\n bytes calldata _calldata\n ) external view returns (bytes32);\n\n function getDiamondCutNonce() external view returns (uint128);\n}\n" + }, + "contracts/facets/base/interfaces/IDiamondLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n// A loupe is a small magnifying glass used to look at diamonds.\n// These functions look at diamonds\ninterface IDiamondLoupe {\n /// These functions are expected to be called frequently\n /// by tools.\n\n struct Facet {\n address facetAddress;\n bytes4[] functionSelectors;\n }\n\n /// @notice Gets all facet addresses and their four byte function selectors.\n /// @return facets_ Facet\n function facets() external view returns (Facet[] memory facets_);\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n /// @return facetFunctionSelectors_\n function facetFunctionSelectors(\n address _facet\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses()\n external\n view\n returns (address[] memory facetAddresses_);\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(\n bytes4 _functionSelector\n ) external view returns (address facetAddress_);\n}\n" + }, + "contracts/facets/base/interfaces/IStorageLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"./IDiamondLoupe.sol\";\n\n/**\n * @title LoupeFromStorage Interface\n * @dev Interface contract to function as a loupe facet directly attached to diamond storage of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IStorageLoupe {\n /// These functions are expected to be called frequently\n /// by tools.\n\n /// @notice Gets all facet addresses and their four byte function selectors.\n /// @return facets_ Facet\n function facetsFromStorage()\n external\n view\n returns (IDiamondLoupe.Facet[] memory);\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n function facetFunctionSelectorsFromStorage(\n address _facet\n ) external view returns (bytes4[] memory);\n\n /// @notice Get all the facet addresses used by a diamond.\n function facetAddressesFromStorage()\n external\n view\n returns (address[] memory);\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n function facetAddressFromStorage(\n bytes4 _functionSelector\n ) external view returns (address);\n}\n" + }, + "contracts/facets/GuardianFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibFacetStorage, GuardianStorage, StorageConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IGuardianFacet} from \"./interfaces/IGuardianFacet.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Guardian Facet\n * @dev Contract that enables addition/removal of guardians from Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract GuardianFacet is IGuardianFacet {\n ISecurityManager public immutable securityManager;\n uint8 public constant INNER_STRUCT = 0;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Add guardians to Barz.\n * @dev This method internally calls addGuardian which checks the validity of guardian address and adds\n * as guardian if valid\n * @param _guardians Array of addresses to add as guardian\n */\n function addGuardians(address[] calldata _guardians) external override {\n LibDiamond.enforceIsSelf();\n uint256 guardiansLength = _guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n addGuardian(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Add a guardian to Barz.\n * @dev This method checks if the function is called by the owner and validates the address of guardian\n * When the validation passes, guardian address is added to the pending state waiting for confirmation\n * @param _guardian Address to add as guardian\n */\n function addGuardian(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (_guardian == address(this))\n revert GuardianFacet__GuardianCannotBeSelf();\n if (isGuardian(_guardian)) revert GuardianFacet__DuplicateGuardian();\n if (_guardian == address(0))\n revert GuardianFacet__ZeroAddressGuardian();\n if (\n keccak256(abi.encodePacked(_guardian)) ==\n keccak256(IVerificationFacet(address(this)).owner())\n ) revert GuardianFacet__OwnerCannotBeGuardian();\n\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n if (\n gs.pending[id] != 0 ||\n block.timestamp <= gs.pending[id] + getSecurityWindow()\n ) revert GuardianFacet__DuplicateGuardianAddition();\n\n uint256 securityPeriod = getAdditionSecurityPeriod();\n gs.pending[id] = block.timestamp + securityPeriod;\n emit GuardianAdditionRequested(\n _guardian,\n block.timestamp + securityPeriod\n );\n }\n\n /**\n * @notice Remove guardians from Barz.\n * @dev This method internally calls removeGuardian which checks the validity of guardian and removes\n * guardian when the request is valid\n * @param _guardians Array of addresses to be removed\n */\n function removeGuardians(address[] calldata _guardians) external override {\n LibDiamond.enforceIsSelf();\n uint256 guardiansLength = _guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n removeGuardian(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Remove a guardian from Barz.\n * @dev This method validates if the guardian to be removed is a guardian and puts the guardian removal\n * to a pending state waiting to be confirmed.\n * @param _guardian Address of guardian to be removed\n */\n function removeGuardian(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n if (!isGuardian(_guardian)) revert GuardianFacet__NonExistentGuardian();\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n if (\n gs.pending[id] != 0 ||\n block.timestamp <= gs.pending[id] + getSecurityWindow()\n ) revert GuardianFacet__DuplicateGuardianRemoval();\n\n uint256 securityPeriod = getRemovalSecurityPeriod();\n gs.pending[id] = block.timestamp + securityPeriod;\n emit GuardianRemovalRequested(\n _guardian,\n block.timestamp + securityPeriod\n );\n }\n\n /**\n * @notice Confirm addition of guardians\n * @dev This method internally calls confirmGuardianAddition which checks the validity of pending request.\n * Guardians are fully added when they pass the validation. Anyone can call this function.\n * @param _guardians Array of guardian addresses to be added\n */\n function confirmGuardianAdditions(\n address[] calldata _guardians\n ) external override {\n uint256 guardiansLength = _guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n confirmGuardianAddition(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Confirm addition of a guardian\n * @dev This method checks the validity of pending request.\n * Guardians are fully added when they pass the validation. Anyone can call this function.\n * @param _guardian Guardian address to be added\n */\n function confirmGuardianAddition(address _guardian) public override {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingAddition();\n if (gs.pending[id] >= block.timestamp)\n revert GuardianFacet__PendingAdditionNotOver();\n if (block.timestamp >= gs.pending[id] + getSecurityWindow())\n revert GuardianFacet__PendingAdditionExpired();\n\n _addGuardian(_guardian);\n\n delete gs.pending[id];\n emit GuardianAdded(_guardian);\n }\n\n /**\n * @notice Confirm removal of guardians\n * @dev This method internally calls confirmGuardianRemoval to check the validity guardian removal confirmation.\n * Guardians are fully removed when they pass the validation. Anyone can call this function.\n * @param _guardians Array of guardian addresses to be removed\n */\n function confirmGuardianRemovals(\n address[] calldata _guardians\n ) external override {\n uint256 guardiansLength = _guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n confirmGuardianRemoval(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Confirm removal of a guardian\n * @dev This method checks the validity guardian removal confirmation.\n * Guardian is fully removed when they pass the validation. Anyone can call this function.\n * @param _guardian Guardian address to be removed\n */\n function confirmGuardianRemoval(address _guardian) public override {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingRemoval();\n if (gs.pending[id] >= block.timestamp)\n revert GuardianFacet__PendingRemovalNotOver();\n if (block.timestamp >= gs.pending[id] + getSecurityWindow())\n revert GuardianFacet__PendingAdditionExpired();\n\n _removeGuardian(_guardian);\n delete gs.pending[id];\n emit GuardianRemoved(_guardian);\n }\n\n /**\n * @notice Cancel pending guardian addition\n * @dev This method checks if the previous request for guardian request exists.\n * It reverts if previous request is not pending and cancels the addition otherwise.\n * @param _guardian Guardian address to be canceled from addition\n */\n function cancelGuardianAddition(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingAddition();\n delete gs.pending[id];\n emit GuardianAdditionCancelled(_guardian);\n }\n\n /**\n * @notice Cancel pending guardian removal\n * @dev This method checks if the previous request for guardian request exists.\n * It reverts if previous request is not pending and cancels the removal otherwise.\n * @param _guardian Guardian address to be canceled from removal\n */\n function cancelGuardianRemoval(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingRemoval();\n delete gs.pending[id];\n emit GuardianRemovalCancelled(_guardian);\n }\n\n /**\n * @notice Get the addition security period of current account from security manager\n * @dev This method returns the uint value if addition security period\n * @return additionSecurityPeriod Uint256 value of addition security period\n */\n function getAdditionSecurityPeriod()\n public\n view\n override\n returns (uint256 additionSecurityPeriod)\n {\n additionSecurityPeriod = securityManager.additionSecurityPeriodOf(\n address(this)\n );\n if (additionSecurityPeriod == 0)\n revert GuardianFacet__InvalidAdditionSecurityPeriod();\n }\n\n /**\n * @notice Get the removal security period of current account from security manager\n * @dev This method returns the uint value if removal security period\n * @return removalSecurityPeriod Uint256 value of removal security period\n */\n function getRemovalSecurityPeriod()\n public\n view\n override\n returns (uint256 removalSecurityPeriod)\n {\n removalSecurityPeriod = securityManager.removalSecurityPeriodOf(\n address(this)\n );\n if (removalSecurityPeriod == 0)\n revert GuardianFacet__InvalidRemovalSecurityPeriod();\n }\n\n /**\n * @notice Get the security window of current account from security manager\n * @dev This method returns the uint value if security window\n * @return securityWindow Uint256 value of removal security period\n */\n function getSecurityWindow()\n public\n view\n override\n returns (uint256 securityWindow)\n {\n securityWindow = securityManager.securityWindowOf(address(this));\n if (securityWindow == 0) revert GuardianFacet__InvalidSecurityWindow();\n }\n\n /**\n * @notice Checks if the addition of the given guardian address is pending\n * @dev This method returns the bool value of whether the guardian address is pending addition\n * @return isPending Bool value of representing the pending of guardian addition\n */\n function isAdditionPending(\n address _guardian\n ) public view override returns (bool isPending) {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n isPending = _isPending(id);\n }\n\n /**\n * @notice Checks if the removal of the given guardian address is pending\n * @dev This method returns the bool value of whether the guardian address is pending removal\n * @return isPending Bool value of representing the pending of guardian removal\n */\n function isRemovalPending(\n address _guardian\n ) public view override returns (bool isPending) {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n isPending = _isPending(id);\n }\n\n /**\n * @notice Checks if the given hash is pending\n * @dev This method returns the bool value whether the hash is pending\n * @return isPending Bool value of representing the pending of guardian operation\n */\n function _isPending(\n bytes32 _idHash\n ) internal view returns (bool isPending) {\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n isPending = ((gs.pending[_idHash] > 0 &&\n gs.pending[_idHash] < block.timestamp) &&\n block.timestamp < gs.pending[_idHash] + getSecurityWindow());\n }\n\n /**\n * @notice Adds guardian to storage config. This is called when guardian is fully added.\n * @dev This method add guardian address and config information to Facet Storage dedicated for guardian\n * When this function is called, guardian is fully added to this Barz Smart Account\n * @param _guardian Address of guardian to be added\n */\n function _addGuardian(address _guardian) internal {\n if (!isAdditionPending(_guardian))\n revert GuardianFacet__InvalidGuardianAddition();\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n if (config.info[_guardian].exists)\n revert GuardianFacet__AlreadyExists();\n\n config.info[_guardian].exists = true;\n config.info[_guardian].index = uint128(config.addresses.length);\n config.addresses.push(_guardian);\n }\n\n /**\n * @notice Removes guardian to storage config. This is called when guardian is fully removed.\n * @dev This method remove guardian address and config information to Facet Storage dedicated for guardian\n * When this function is called, guardian is fully removed from this Barz Smart Account\n * @param _guardian Address of guardian to be removed\n */\n function _removeGuardian(address _guardian) internal {\n if (!isRemovalPending(_guardian))\n revert GuardianFacet__InvalidGuardianRemoval();\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n if (!config.info[_guardian].exists)\n revert GuardianFacet__NonExistentGuardian();\n\n address lastAddress = config.addresses[config.addresses.length - 1];\n if (_guardian != lastAddress) {\n uint128 targetIndex = config.info[_guardian].index;\n config.addresses[targetIndex] = lastAddress;\n config.info[lastAddress].index = targetIndex;\n }\n config.addresses.pop();\n delete config.info[_guardian];\n\n emit GuardianRemoved(_guardian);\n }\n\n /**\n * @notice Reads guardian storage and fetches the addresses into an array from the storage\n * @dev This method fetches the guardian storage and returns the list of guardian addresses\n * @return addresses Array of addresses comprised of guardian\n */\n function getGuardians()\n public\n view\n override\n returns (address[] memory addresses)\n {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n addresses = new address[](config.addresses.length);\n uint256 addressesLen = config.addresses.length;\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the number of majority of guardians\n * @return majorityOfGuardians_ Number of majority of guardians e.g., 2 if 3 guardians / 3 if 5 guardians\n */\n function majorityOfGuardians()\n public\n view\n override\n returns (uint256 majorityOfGuardians_)\n {\n majorityOfGuardians_ = LibGuardian.majorityOfGuardians();\n }\n\n /**\n * @notice Reads guardian storage and fetches the addresses into an array from the storage\n * @dev This method fetches the guardian storage and returns the list of guardian addresses\n * @return guardianNumber Array of guardians in the account\n */\n function guardianCount()\n public\n view\n override\n returns (uint256 guardianNumber)\n {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n guardianNumber = config.addresses.length;\n }\n\n /**\n * @notice Reads guardian storage and checks if the given address is a guardian\n * @return isGuardian_ Bool value representing if the given address is guardian\n */\n function isGuardian(\n address _guardian\n ) public view override returns (bool isGuardian_) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n isGuardian_ = config.info[_guardian].exists;\n }\n\n /**\n * @notice Checks if the guardian number is zero and returns of guardian facet is okay to be removed\n * @return isRemovable Bool value representing if guardian facet is removable\n */\n function isGuardianFacetRemovable()\n external\n view\n override\n returns (bool isRemovable)\n {\n isRemovable = (0 == guardianCount());\n }\n}\n" + }, + "contracts/facets/interfaces/IAccountFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IEntryPoint} from \"../../aa-4337/interfaces/IEntryPoint.sol\";\n\n/**\n * @title Account Facet Interface\n * @dev Interface of module contract that provides the account features and init/unitialization of signer\n * compatible with EIP-1271 & EIP-4337\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IAccountFacet {\n event AccountInitialized(\n IEntryPoint indexed entryPoint,\n bytes indexed ownerPublicKey\n );\n // NOTE: Added Below Event\n event VerificationSuccess(bytes32);\n event VerificationFailure(bytes32);\n\n error AccountFacet__InitializationFailure();\n error AccountFacet__RestrictionsFailure();\n error AccountFacet__NonExistentVerificationFacet();\n error AccountFacet__CallNotSuccessful();\n\n function initialize(\n address verificationFacet,\n address anEntryPoint,\n address facetRegistry,\n address _defaultFallBack,\n bytes calldata _ownerPublicKey\n ) external returns (uint256);\n\n function execute(address dest, uint256 value, bytes calldata func) external;\n\n function executeBatch(\n address[] calldata dest,\n uint256[] calldata value,\n bytes[] calldata func\n ) external;\n}\n" + }, + "contracts/facets/interfaces/IAccountRecoveryFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {RecoveryConfig} from \"../../libraries/LibFacetStorage.sol\";\n\n/**\n * @title Account Recovery Facet Interface\n * @dev Interface of contract that enables recovery of accounts when owner key is unavailable\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IAccountRecoveryFacet {\n event RecoveryExecuted(\n bytes indexed recoveryPublicKey,\n uint64 executeAfter\n );\n event RecoveryFinalized(bytes indexed recoveryPublicKey);\n event RecoveryCanceled(bytes indexed recoveryPublicKey);\n event RecoveryApproved(\n bytes indexed recoveryPublicKey,\n address indexed guardian,\n uint64 validUntil\n );\n event RecoveryApprovalRevoked(\n bytes indexed recoveryPublicKey,\n address indexed guardian\n );\n event RecoveryCancellationApproved(\n bytes indexed recoveryPublicKey,\n address indexed guardian\n );\n event RecoveryHardstopped();\n\n error AccountRecoveryFacet__CallerNotGuardian();\n error AccountRecoveryFacet__InvalidRecoveryPublicKey();\n error AccountRecoveryFacet__SignerInitializationFailure();\n error AccountRecoveryFacet__SignerUninitializationFailure();\n error AccountRecoveryFacet__InvalidArrayLength();\n error AccountRecoveryFacet__InsufficientGuardians();\n error AccountRecoveryFacet__RecoveryAlreadyOngoing();\n error AccountRecoveryFacet__NonexistentRecovery();\n error AccountRecoveryFacet__NonExistentApproval();\n error AccountRecoveryFacet__RecoveryPeriodNotOver();\n error AccountRecoveryFacet__InvalidLockPeriod();\n error AccountRecoveryFacet__InvalidRecoveryPeriod();\n error AccountRecoveryFacet__InvalidApprovalValidationPeriod();\n error AccountRecoveryFacet__InvalidGuardian();\n error AccountRecoveryFacet__InvalidGuardianSignature();\n error AccountRecoveryFacet__InvalidOwnerSignature();\n error AccountRecoveryFacet__CallNotSuccesful();\n error AccountRecoveryFacet__DuplicateApproval();\n\n function approveAccountRecovery(bytes calldata recoveryPublicKey) external;\n\n function revokeAccountRecoveryApproval(\n bytes calldata recoveryPublicKey\n ) external;\n\n function executeRecovery(\n bytes calldata recoveryPublicKey,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function finalizeRecovery() external;\n\n function approveCancelRecovery(bytes calldata recoveryPublicKey) external;\n\n function cancelRecovery(\n bytes calldata recoveryPublicKey,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function hardstopRecovery(bytes calldata signature) external;\n\n function getApprovalRecoveryKeyHash(\n bytes memory recoveryPublicKey,\n string memory saltString\n ) external view returns (bytes32);\n\n function getRecoveryApprovalCountWithTimeValidity(\n bytes32 recoveryPublicKeyHash\n ) external view returns (uint256);\n\n function isRecoveryApproved(\n bytes32 recoveryPublicKeyHash,\n address approver\n ) external view returns (bool);\n\n function getRecoveryNonce() external view returns (uint128);\n\n function getPendingRecovery() external view returns (RecoveryConfig memory);\n}\n" + }, + "contracts/facets/interfaces/IGuardianFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Guardian Facet Interface\n * @dev Interface of guaridna contract that enables addition/removal of guardians from Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IGuardianFacet {\n event GuardianAdditionRequested(\n address indexed guardian,\n uint256 executeAfter\n );\n event GuardianRemovalRequested(\n address indexed guardian,\n uint256 executeAfter\n );\n event GuardianAdditionCancelled(address indexed guardian);\n event GuardianRemovalCancelled(address indexed guardian);\n event GuardianAdded(address indexed guardian);\n event GuardianRemoved(address indexed guardian);\n\n error GuardianFacet__GuardianCannotBeSelf();\n error GuardianFacet__DuplicateGuardian();\n error GuardianFacet__OwnerCannotBeGuardian();\n error GuardianFacet__DuplicateGuardianAddition();\n error GuardianFacet__DuplicateGuardianRemoval();\n error GuardianFacet__UnknownPendingAddition();\n error GuardianFacet__PendingAdditionNotOver();\n error GuardianFacet__UnknownPendingRemoval();\n error GuardianFacet__PendingRemovalNotOver();\n error GuardianFacet__PendingAdditionExpired();\n error GuardianFacet__InvalidAdditionSecurityPeriod();\n error GuardianFacet__InvalidRemovalSecurityPeriod();\n error GuardianFacet__InvalidSecurityWindow();\n error GuardianFacet__NonExistentGuardian();\n error GuardianFacet__AlreadyExists();\n error GuardianFacet__InvalidGuardianAddition();\n error GuardianFacet__InvalidGuardianRemoval();\n error GuardianFacet__ZeroAddressGuardian();\n\n function addGuardian(address guardian) external;\n\n function addGuardians(address[] calldata guardians) external;\n\n function removeGuardian(address guardian) external;\n\n function removeGuardians(address[] calldata guardians) external;\n\n function confirmGuardianAddition(address guardian) external;\n\n function confirmGuardianAdditions(address[] calldata guardian) external;\n\n function confirmGuardianRemoval(address guardian) external;\n\n function confirmGuardianRemovals(address[] calldata guardian) external;\n\n function cancelGuardianAddition(address guardian) external;\n\n function cancelGuardianRemoval(address guardian) external;\n\n function isGuardian(address guardian) external view returns (bool);\n\n function isAdditionPending(address guardian) external view returns (bool);\n\n function isRemovalPending(address guardian) external view returns (bool);\n\n function isGuardianFacetRemovable() external view returns (bool);\n\n function getAdditionSecurityPeriod() external view returns (uint256);\n\n function getRemovalSecurityPeriod() external view returns (uint256);\n\n function getSecurityWindow() external view returns (uint256);\n\n function getGuardians() external view returns (address[] memory);\n\n function majorityOfGuardians() external view returns (uint256);\n\n function guardianCount() external view returns (uint256);\n}\n" + }, + "contracts/facets/interfaces/ILockFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Lock} from \"../../libraries/LibAppStorage.sol\";\n\n/**\n * @title Lock Facet Interface\n * @dev Interface of Lock contract that enables full lock/unlock of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface ILockFacet {\n event Locked(uint64 releaseAfter);\n event Unlocked();\n\n error LockFacet__InvalidRecoveryPeriod();\n error LockFacet__CannotUnlock();\n error LockFacet__InvalidSignature();\n error LockFacet__InvalidApprover();\n\n function lock() external;\n\n function unlock(address approver, bytes calldata signature) external;\n\n function getLockPeriod() external view returns (uint256);\n\n function isLocked() external view returns (bool);\n\n function getUnlockHash() external view returns (bytes32);\n\n function lockNonce() external view returns (uint128);\n\n function getPendingLock() external view returns (Lock memory);\n}\n" + }, + "contracts/facets/interfaces/IMultiSigFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Multi-sig facet Interface\n * @dev Interface of Multi-signature Facet with custom threshold.\n Wallet that adds this facet becomes a multi-sig wallet\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IMultiSigFacet {\n event ThresholdChanged(uint256 threshold);\n event OwnerAdded(address indexed newOwner);\n event OwnerRemoved(address indexed prevOwner);\n event HashApproved(bytes32 hashToApprove, address indexed owner);\n\n error MultiSigFacet__InvalidThreshold();\n error MultisigFacet__InvalidOwnerCount();\n error MultiSigFacet__InvalidRoute();\n error MultiSigFacet__InsufficientSignerLength();\n error MultiSigFacet__InvalidInitData();\n error MultiSigFacet__InvalidOwnerAddress();\n error MultiSigFacet__InvalidOwnerPair();\n error MultiSigFacet__InvalidSignatureLength();\n error MultiSigFacet__InvalidSignatureType();\n error MultiSigFacet__DuplicateOwner();\n error MultiSigFacet__OnlyOwner();\n\n function checkSignatures(\n bytes32 _dataHash,\n bytes calldata _signatures,\n uint256 _threshold\n ) external view returns (uint256);\n\n function splitSignatures(\n bytes calldata _signatures,\n uint256 _nextOffset\n )\n external\n pure\n returns (\n address owner,\n bytes memory signature,\n uint256 signatureType,\n uint256 nextOffset\n );\n\n function approveHash(bytes32 hashToApprove) external;\n\n function addOwner(address newOwner, uint256 threshold) external;\n\n function removeOwner(\n address prevOwner,\n address removedOwner,\n uint256 threshold\n ) external;\n\n function swapOwner(\n address prevOwner,\n address oldOwner,\n address newOwner\n ) external;\n\n function changeThreshold(uint256 _threshold) external;\n\n function isOwner(address owner) external view returns (bool);\n\n function getThreshold() external view returns (uint256);\n\n function getOwners() external view returns (address[] memory);\n}\n" + }, + "contracts/facets/interfaces/IRestrictionsFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Restrictions Facet Interface\n * @dev Interface of Restrictions contract that enables modular restrictions in Barz\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IRestrictionsFacet {\n event RestrictionAdded(address indexed restriction);\n event RestrictionRemoved(address indexed restriction);\n\n error RestrictionsFacet__EmptyRestrictionsList();\n error RestrictionsFacet__RestrictionNotFound();\n error RestrictionsFacet__RestrictionAlreadyExists();\n error RestrictionsFacet__ZeroAddressRestrictions();\n error RestrictionsFacet__ZeroAddressRestrictionsFacet();\n error RestrictionsFacet__RemainingRestrictionsCantBeEmpty();\n\n function initializeRestrictions(\n address[] memory _restrictions\n ) external returns (uint256);\n\n function uninitializeRestrictions() external returns (uint256);\n\n function getRestrictions() external view returns (address[] memory);\n\n function addRestriction(address restriction) external;\n\n function removeRestriction(address restriction) external;\n\n function verifyRestrictions(\n address from,\n address to,\n uint256 value,\n bytes calldata _calldata\n ) external returns (uint256);\n}\n" + }, + "contracts/facets/interfaces/ISignatureMigrationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureMigrationConfig} from \"../../libraries/LibFacetStorage.sol\";\n\n/**\n * @title Signature Migration Facet Interface\n * @dev Interface of Signature Migration contract for migrating user signature scheme to a new scheme user sets\n * Which could include\n * - ECDSA on Secp256K1 Curve\n * - ECDSA on Secp256R1 Curve\n * - BLS, Schnorr, etc\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface ISignatureMigrationFacet {\n event SignatureSchemeMigration(\n address indexed prevVerificationFacet,\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n event SignatureMigrationApproved(\n bytes newPublicKey,\n address indexed newVerificationFacet,\n bytes4[] verificationFuncSelectors,\n address indexed guardian,\n uint128 approvalValidUntil\n );\n event SignatureMigrationApprovalRevoked(\n bytes newPublicKey,\n address indexed newVerificationFacet,\n bytes4[] verificationFuncSelectors,\n address indexed guardian\n );\n event SignatureMigrationExecuted(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors,\n uint128 migrateAfter\n );\n event SignatureMigrationCanceled(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n event SignatureMigrationCancellationApproved(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n\n error SignatureMigrationFacet__SignerUninitializationFailure();\n error SignatureMigrationFacet__InvalidRouteWithGuardian();\n error SignatureMigrationFacet__InvalidKeyType();\n error SignatureMigrationFacet__InsufficientApprovers();\n error SignatureMigrationFacet__InvalidApproverSignature();\n error SignatureMigrationFacet__InvalidGuardian();\n error SignatureMigrationFacet__NonExistentApprover();\n error SignatureMigrationFacet__InvalidMigrationPeriod();\n error SignatureMigrationFacet__NonexistentMigration();\n error SignatureMigrationFacet__MigrationPeriodNotOver();\n error SignatureMigrationFacet__InvalidArrayLength();\n error SignatureMigrationFacet__InvalidApprovalValidationPeriod();\n error SignatureMigrationFacet__CannotRevokeUnapproved();\n error SignatureMigrationFacet__LackOfOwnerApproval();\n error SignatureMigrationFacet__OwnerAlreadyApproved();\n error SignatureMigrationFacet__NonExistentVerificationFacet();\n error SignatureMigrationFacet__DuplicateApproval();\n\n function migrateSignatureScheme(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function migrateSignatureSchemeWithGuardian(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors,\n address[] calldata approvers,\n bytes[] calldata signatures\n ) external;\n\n function approveSignatureSchemeMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function revokeSignatureMigrationApproval(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function finalizeSignatureMigration() external;\n\n function approveCancelSignatureMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function cancelSignatureMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function getApprovalMigrationKeyHash(\n bytes memory recoveryPublicKey,\n address newVerificationFacet,\n bytes4[] memory newVerificationFuncSelectors,\n string memory saltString\n ) external view returns (bytes32);\n\n function getMigrationOwnerApprovalWithTimeValidity(\n bytes32 publicKeyHash\n ) external view returns (bool);\n\n function getMigrationApprovalCountWithTimeValidity(\n bytes32 publicKeyHash\n ) external view returns (uint256);\n\n function isMigrationApproved(\n bytes32 migrationPublicKeyHash,\n address approver\n ) external view returns (bool);\n\n function getMigrationNonce() external view returns (uint128);\n\n function isMigrationPending() external view returns (bool);\n\n function getPendingMigration()\n external\n view\n returns (SignatureMigrationConfig memory);\n}\n" + }, + "contracts/facets/interfaces/IVerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {UserOperation} from \"../../aa-4337/interfaces/UserOperation.sol\";\n\n/**\n * @title Verification Facet Interface\n * @dev Implements logic for user ops signature verification\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface IVerificationFacet {\n event SignerInitialized(bytes);\n event SignerUninitialized();\n\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n error VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n error VerificationFacet__InitializationFailure();\n error VerificationFacet__InvalidFacetMapping();\n\n function initializeSigner(bytes memory) external returns (uint256);\n\n function uninitializeSigner() external returns (uint256);\n\n function validateOwnerSignatureSelector() external view returns (bytes4);\n\n function owner() external view returns (bytes memory);\n\n function isValidKeyType(bytes calldata) external view returns (bool);\n\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) external view returns (uint256);\n}\n" + }, + "contracts/facets/LockFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage, Lock} from \"../libraries/LibAppStorage.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibFacetStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {ILockFacet} from \"./interfaces/ILockFacet.sol\";\n\n/**\n * @title Lock Facet\n * @dev Contract that enables full lock/unlock of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract LockFacet is ILockFacet, Modifiers {\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Locks the account for the lock period. Lock period is defined in the security manager and it's customizable\n * This function can only be called when account is unlocked by owner or guardians\n * @dev This method checks the caller and if the account is currently locked and locks the account after fetching the\n * Lock period from the owner.\n */\n function lock() external override onlyGuardianOrOwner onlyWhenUnlocked {\n uint256 unlockTime = block.timestamp + getLockPeriod();\n ++LibFacetStorage.lockStorage().nonce;\n LibAppStorage.setLock(unlockTime, LockFacet.lock.selector);\n emit Locked(uint64(unlockTime));\n }\n\n /**\n * @notice Locks the account when the account is locked. This function can be called by anyone but must provide the approver address and signature.\n * The approver should be one of the guardians or owner.\n * @dev This method takes the approver address and the signature. After validating the address and the signature, it unlocks the account immediately.\n * Only one of the guardian or owner is required to lock and unlock the account.\n * @param _approver Address of approver approving the unlock of Barz account\n * @param _signature Signature of the approver that signed the msg hash for unlocking the account\n */\n function unlock(\n address _approver,\n bytes calldata _signature\n ) external override onlyWhenLocked {\n if (_approver != address(this) && !LibGuardian.isGuardian(_approver))\n revert LockFacet__InvalidApprover();\n if (\n !SignatureChecker.isValidSignatureNow(\n _approver,\n getUnlockHash(),\n _signature\n )\n ) revert LockFacet__InvalidSignature();\n _unlock();\n }\n\n /**\n * @notice Unlocks the account and increments the lock nonce\n */\n function _unlock() private {\n if (s.locks[INNER_STRUCT].locker != LockFacet.lock.selector)\n revert LockFacet__CannotUnlock();\n ++LibFacetStorage.lockStorage().nonce;\n LibAppStorage.setLock(0, bytes4(0));\n emit Unlocked();\n }\n\n /**\n * @notice Returns the lock period of current Barz account. Lock period information is held by Security Manager\n * @return lockPeriod Uint value of lock period in seconds\n */\n function getLockPeriod() public view override returns (uint256 lockPeriod) {\n lockPeriod = securityManager.lockPeriodOf(address(this));\n if (lockPeriod == 0) revert LockFacet__InvalidRecoveryPeriod();\n }\n\n /**\n * @notice Returns if the account is locked or not\n * @dev This method fetches the current block timestamp and compares that with release time.\n * After checking the timestamp and release time, it returns if the account is still locked or not.\n * @return isLocked_ Uint value of lock period in seconds\n */\n function isLocked() public view override returns (bool isLocked_) {\n isLocked_ = uint64(block.timestamp) < s.locks[INNER_STRUCT].release;\n }\n\n /**\n * @notice Calculates the unlock hash and returns the unlock hash safe from signature reply attack\n * @dev This method calculates the unlock hash with EIP-191 prefix, wallet address, chainID, and nonce\n * It packs the result and packs them and hashes it.\n * @return unlockHash Bytes32 unlock hash\n */\n function getUnlockHash() public view override returns (bytes32 unlockHash) {\n unlockHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n \"Unlock\",\n address(this),\n block.chainid,\n lockNonce()\n )\n )\n )\n );\n }\n\n /**\n * @notice Returns lock nonce of account. Reads nonce from lock storage within facet storage\n * @return lockNonce_ Uint128 value of lock nonce. This is incremented whenever the account is lock/unlocked\n */\n function lockNonce() public view override returns (uint128 lockNonce_) {\n lockNonce_ = LibFacetStorage.lockStorage().nonce;\n }\n\n /**\n * @notice Returns the overall information of current lock\n * @return pendingLock Struct value including all information of pending lock\n */\n function getPendingLock()\n public\n view\n override\n returns (Lock memory pendingLock)\n {\n pendingLock = s.locks[INNER_STRUCT];\n }\n}\n" + }, + "contracts/facets/Modifiers.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {IFacetRegistry} from \"../infrastructure/interfaces/IFacetRegistry.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\n\n/**\n * @title Modifiers\n * @dev Responsible for providing modifiers/util functions to Facet contracts\n * @author David Yongjun Kim (@Powerstream3604)\n */\nabstract contract Modifiers is BarzStorage {\n uint8 constant INNER_STRUCT = 0;\n\n error CallerNotGuardian();\n error CallerNotGuardianOrOwner();\n error DuplicateApprover();\n error ZeroApproverLength();\n error UnregisteredFacetAndSelectors();\n\n /**\n * @notice Modifier to only allow guardian to make a call, reverts if any other entity is the caller\n */\n modifier onlyGuardian() {\n if (!LibGuardian.isGuardian(msg.sender)) revert CallerNotGuardian();\n _;\n }\n\n /**\n * @notice Modifier to only allow guardian or owner to make a call, reverts if any other entity is the caller\n */\n modifier onlyGuardianOrOwner() {\n if (!LibGuardian.isGuardian(msg.sender) && address(this) != msg.sender)\n revert CallerNotGuardianOrOwner();\n _;\n }\n\n /**\n * @notice Checks if the approver address is the array is unique with no duplicate\n * @dev This method loops through the array and checks if a duplicate address exists, it reverts if duplicate address exists\n * @param approvers Array of address\n */\n function _checkApprover(\n address[] memory approvers\n ) internal pure returns (bool) {\n uint256 approverLength = approvers.length;\n if (0 == approverLength) revert ZeroApproverLength();\n for (uint256 i; i < approverLength - 1; ) {\n for (uint256 j = i + 1; j < approverLength; ) {\n if (approvers[i] == approvers[j]) {\n revert DuplicateApprover(); // Found a duplicate\n }\n unchecked {\n ++j;\n }\n }\n unchecked {\n ++i;\n }\n }\n return false; // No duplicates found\n }\n\n /**\n * @notice Checks if the facet getting added or replaced is registered to facet registry\n * @dev This method loops through the cut and checks if the facet getting added/replaced is registered to facet registry\n * @param _diamondCut Array of FacetCut, data for diamondCut defined in EIP-2535\n */\n function _checkFacetCutValidity(\n IDiamondCut.FacetCut[] memory _diamondCut\n ) internal view {\n uint256 diamondCutLength = _diamondCut.length;\n for (uint256 i; i < diamondCutLength; ) {\n if (\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Add ||\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Replace\n ) {\n if (\n !s.facetRegistry.areFacetFunctionSelectorsRegistered(\n _diamondCut[i].facetAddress,\n _diamondCut[i].functionSelectors\n )\n ) revert UnregisteredFacetAndSelectors();\n }\n unchecked {\n ++i;\n }\n }\n }\n}\n" + }, + "contracts/facets/RestrictionsFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, RestrictionsStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {IRestriction} from \"../restrictions/IRestriction.sol\";\nimport {IRestrictionsFacet} from \"./interfaces/IRestrictionsFacet.sol\";\n\n/**\n * @title Restrictions facet\n * @dev Responsible for storing and verifying different kinds of restrictions, for example:\n * - Whitelist / Blacklist\n * - Daily limits\n * - Trading time restrictions\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract RestrictionsFacet is IRestrictionsFacet {\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceRestrictionsInitialize();\n }\n\n /**\n * @notice Intialize restrictions of Barz. Restrictions facet call restriction contracts for restriction validation\n * before each call\n * @param _restrictions The initial array of restrictions.\n * @return initSuccess Int value showing if the initialization of restriction is successful\n */\n function initializeRestrictions(\n address[] calldata _restrictions\n ) public override returns (uint256 initSuccess) {\n LibDiamond.enforceIsSelf();\n LibAppStorage.enforceRestrictionsInitialize();\n\n uint256 restrictionsLength = _restrictions.length;\n if (restrictionsLength == 0) {\n // You can't initialize RestrictionsFacet with an empty list of restrictions\n revert RestrictionsFacet__EmptyRestrictionsList();\n }\n for (uint256 i; i < restrictionsLength; ) {\n if (_restrictions[i] == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictions();\n unchecked {\n ++i;\n }\n }\n\n LibFacetStorage.restrictionsStorage().restrictions = _restrictions;\n _updateRestrictionsMap(_restrictions, true);\n initSuccess = 1;\n }\n\n /**\n * @notice Unitialize restrictions of Barz\n * @return uninitSuccess Int value showing if the initialization of restriction is successful\n */\n function uninitializeRestrictions()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibDiamond.enforceIsSelf();\n LibAppStorage.setRestrictionsUninitialized();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n _updateRestrictionsMap(restrictionsStorage.restrictions, false);\n restrictionsStorage.restrictions = new address[](0);\n uninitSuccess = 1;\n }\n\n /**\n * @notice Returns the list of Restrictions contract address\n * @return restrictions Addresses of IRestriction which are currently active\n */\n function getRestrictions()\n public\n view\n override\n returns (address[] memory restrictions)\n {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n restrictions = restrictionsStorage.restrictions;\n }\n\n /**\n * @notice Adds restrictions to Barz with validation on the restriction contract address.\n * This method is only callable by the owner(self).\n * @param _restriction The address of the restriction to be added.\n */\n function addRestriction(address _restriction) external override {\n LibDiamond.enforceIsSelf();\n if (LibDiamond.restrictionsFacet() == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictionsFacet();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n if (_restriction == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictions();\n if (restrictionsStorage.exists[_restriction])\n revert RestrictionsFacet__RestrictionAlreadyExists();\n\n restrictionsStorage.restrictions.push(_restriction);\n restrictionsStorage.exists[_restriction] = true;\n\n emit RestrictionAdded(_restriction);\n }\n\n /**\n * @notice Remove restrictions from Barz if it existed. This method is only callable by the owner(self).\n * @param _restriction The address of the restriction to be removed.\n */\n function removeRestriction(address _restriction) external override {\n LibDiamond.enforceIsSelf();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n if (!restrictionsStorage.exists[_restriction])\n revert RestrictionsFacet__RestrictionNotFound();\n\n address[] storage restrictions = restrictionsStorage.restrictions;\n\n uint256 indexToDelete = restrictions.length;\n uint256 restrictionsLen = restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n if (restrictions[i] == _restriction) {\n indexToDelete = i;\n break;\n }\n unchecked {\n ++i;\n }\n }\n\n if (indexToDelete == 0 && restrictionsLen == 1) {\n revert RestrictionsFacet__RemainingRestrictionsCantBeEmpty();\n } else if (indexToDelete == restrictionsLen) {\n revert RestrictionsFacet__RestrictionNotFound();\n } else {\n restrictions[indexToDelete] = restrictions[restrictionsLen - 1];\n restrictions.pop();\n }\n\n restrictionsStorage.exists[_restriction] = false;\n emit RestrictionRemoved(_restriction);\n }\n\n /**\n * @notice Sets the restrictions address value mapping to true or false when adding/removing restriction contracts\n * @param _restrictions List of restriction contracts address\n * @param _newValue Bool value to flag to the list of restrictions contracts\n */\n function _updateRestrictionsMap(\n address[] memory _restrictions,\n bool _newValue\n ) internal {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n uint restrictionsLen = _restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n restrictionsStorage.exists[_restrictions[i]] = _newValue;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @dev Iterates over all restrictions and verifies each of them with the transaction parameters.\n * @param _from The address of the sender, that will be signing the transaction.\n * @param _to The receiving address.\n * @param _value Amount of ETH to transfer from sender to recipient.\n * @param _calldata Optional field to include arbitrary data.\n * @return 0 if all the checks passed, 1 otherwise.\n */\n function verifyRestrictions(\n address _from,\n address _to,\n uint256 _value,\n bytes calldata _calldata\n ) external returns (uint256) {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n uint restrictionsLen = restrictionsStorage.restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n IRestriction restriction = IRestriction(\n restrictionsStorage.restrictions[i]\n );\n bool checkPassed = restriction.check(_from, _to, _value, _calldata);\n if (!checkPassed) {\n return 1;\n }\n unchecked {\n ++i;\n }\n }\n\n return 0;\n }\n}\n" + }, + "contracts/facets/SignatureMigrationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, SignatureMigrationStorage, SignatureMigrationConfig, SignatureMigrationApprovalConfig, ApprovalConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IDiamondCut} from \"./base/interfaces/IDiamondCut.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {ISignatureMigrationFacet} from \"./interfaces/ISignatureMigrationFacet.sol\";\n\n/**\n * @title Signature Migration Facet\n * @dev Responsible for migrating user signature scheme to a new scheme user sets\n * Which could include\n * - ECDSA on Secp256K1 Curve\n * - ECDSA on Secp256R1 Curve\n * - BLS, Schnorr, etc\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract SignatureMigrationFacet is ISignatureMigrationFacet, Modifiers {\n /**\n * @notice This modifier verifies if the public key format matches with the new verification facet\n * @param _publicKey Bytes of public key to be validated for the new verification facet\n * @param _newVerificationFacet Address of new verification facet\n */\n modifier validateKeyType(\n bytes memory _publicKey,\n address _newVerificationFacet\n ) {\n if (\n !IVerificationFacet(_newVerificationFacet).isValidKeyType(\n _publicKey\n )\n ) revert SignatureMigrationFacet__InvalidKeyType();\n _;\n }\n\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n // IMPORTANT NOTE: In the client side when they call this function, the func selectors should be sorted in ascending order\n // to prevent different hash with same items in the array\n /**\n * @notice Moves the state of migration to a pending state. When pending state is over after pending period time,\n * Migration can be finalized. This function can only be called by self and when the account is unlocked.\n * @dev This method checks if the caller is self and if guardians exists. It migrates signature request to a pending state\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function migrateSignatureScheme(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n public\n override\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n // Only self contract can call this function\n LibDiamond.enforceIsSelf();\n // Should revert if guardian exist\n if (0 != LibGuardian.guardianCount())\n revert SignatureMigrationFacet__InvalidRouteWithGuardian();\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n // NOTE: Migration requires a pending period & confirmation from owner to prevent a\n // single call changing the ownership of the wallet\n /**\n * @notice Migrate signature scheme when guardians exists. Verifies the signature of guardians and moves migration to pending state.\n * Which can then be finalized when pending period is over. Owner's approval is mandatory for migration to happen\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _approvers List of approvers. This could include owner\n */\n function migrateSignatureSchemeWithGuardian(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n )\n public\n override\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n // Should revert if does not guardian exist\n if (0 == LibGuardian.guardianCount())\n revert SignatureMigrationFacet__InvalidRouteWithGuardian();\n uint256 approversLength = _approvers.length;\n if (approversLength != _signatures.length)\n revert SignatureMigrationFacet__InvalidArrayLength();\n\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(migrationPublicKeyHash, _approvers);\n\n bool onChainOwnerApproval = getMigrationOwnerApprovalWithTimeValidity(\n migrationPublicKeyHash\n );\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n\n if (\n approversLength +\n getMigrationApprovalCountWithTimeValidity(\n migrationPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert SignatureMigrationFacet__InsufficientApprovers();\n {\n // To prevent Stack too deep\n bool ownerApproved;\n for (uint256 i; i < approversLength; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n address(this) != _approvers[i]\n ) revert SignatureMigrationFacet__InvalidGuardian();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert SignatureMigrationFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n migrationPublicKeyHash,\n _signatures[i]\n )\n ) revert SignatureMigrationFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n\n if (!ownerApproved && !onChainOwnerApproval)\n revert SignatureMigrationFacet__LackOfOwnerApproval();\n }\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Internal function that moves signature mgiration to a pending state.\n * @dev This method increments migration nonce and sets the migration in the migration config. Emits events for migration execution\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _migrateSignatureScheme(\n address _newVerificationFacet,\n bytes memory _newPublicKey,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal {\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n\n ++ms.nonce;\n uint64 migrateAfter = uint64(block.timestamp + getMigrationPeriod());\n\n ms.migrationConfigs[INNER_STRUCT] = SignatureMigrationConfig(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n migrateAfter\n );\n\n emit SignatureMigrationExecuted(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors,\n migrateAfter\n );\n }\n\n /**\n * @notice Approves signature scheme migration on-chain. This can be called by owner or guardian only when the account is unlocked.\n * When the threshold of the migration approval passed and owner approval is granted, it automatically moves migration to a pending state\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function approveSignatureSchemeMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n public\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit SignatureMigrationApproved(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n msg.sender,\n approvalValidUntil\n );\n if (\n getMigrationApprovalCountWithTimeValidity(migrationPublicKeyHash) >=\n LibGuardian.majorityOfGuardians() &&\n getMigrationOwnerApprovalWithTimeValidity(migrationPublicKeyHash)\n )\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Revokes the approval of signature migration done on-chain. Emits revoke event when revoked.\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function revokeSignatureMigrationApproval(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n external\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n if (!isMigrationApproved(migrationPublicKeyHash, msg.sender))\n revert SignatureMigrationFacet__CannotRevokeUnapproved();\n\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(false, 0);\n emit SignatureMigrationApprovalRevoked(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n msg.sender\n );\n }\n\n /**\n * @notice Finalizes the pending signature scheme migration. This function can only be called by owner.\n * It removes the facets of the previous verification facet and adds the new verification facet.\n * After finalizing migration, it emits migration event which shows the change of the verification facet\n */\n function finalizeSignatureMigration() external override {\n // NOTE: Only owner can call this function\n LibDiamond.enforceIsSelf();\n\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n\n if (!isMigrationPending())\n revert SignatureMigrationFacet__NonexistentMigration();\n\n if (\n uint64(block.timestamp) <=\n ms.migrationConfigs[INNER_STRUCT].migrateAfter\n ) revert SignatureMigrationFacet__MigrationPeriodNotOver();\n address newVerificationFacet = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationVerificationFacet;\n bytes4[] memory newVerificationFuncSelectors = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationSelectors;\n bytes memory newPublicKey = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationPublicKey;\n\n address prevVerificationFacet = LibLoupe.facetAddress(\n s.validateOwnerSignatureSelector\n );\n if (prevVerificationFacet == address(0))\n revert SignatureMigrationFacet__NonExistentVerificationFacet();\n\n IDiamondCut.FacetCut[] memory UninitCut;\n IDiamondCut.FacetCut[] memory InitCut;\n {\n bytes4[] memory prevVerificationFuncSelectors = LibLoupe\n .facetFunctionSelectors(prevVerificationFacet);\n\n UninitCut = new IDiamondCut.FacetCut[](1);\n InitCut = new IDiamondCut.FacetCut[](1);\n UninitCut[0] = IDiamondCut.FacetCut({\n facetAddress: address(0),\n action: IDiamondCut.FacetCutAction.Remove,\n functionSelectors: prevVerificationFuncSelectors\n });\n InitCut[0] = IDiamondCut.FacetCut({\n facetAddress: newVerificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: newVerificationFuncSelectors\n });\n {\n IDiamondCut.FacetCut[]\n memory facetCuts = new IDiamondCut.FacetCut[](2);\n facetCuts[0] = UninitCut[0];\n facetCuts[1] = InitCut[0];\n _checkFacetCutValidity(facetCuts);\n }\n LibAppStorage.initiateSignerMigration();\n address verificationFacet = address(\n bytes20(\n LibDiamond.diamondStorage().facets[\n s.validateOwnerSignatureSelector\n ]\n )\n );\n bytes memory uninitCall = abi.encodeWithSignature(\n \"uninitializeSigner()\"\n );\n (bool success, bytes memory result) = verificationFacet\n .delegatecall(uninitCall);\n require(success, \"MigrationFacet: uninitialize not successful\");\n uint256 validationData = uint256(bytes32(result));\n if (validationData == 0)\n revert SignatureMigrationFacet__SignerUninitializationFailure();\n\n LibDiamond.diamondCut(UninitCut, address(0), \"\");\n }\n {\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n newPublicKey\n );\n\n // Every Verification Facet should comply with initializeSigner(bytes)\n // to be compatible with the Barz contract(for initialization)\n LibDiamond.diamondCut(InitCut, newVerificationFacet, initCall);\n LibAppStorage.finalizeSignerMigration();\n emit SignatureSchemeMigration(\n prevVerificationFacet,\n newVerificationFacet,\n newPublicKey,\n newVerificationFuncSelectors\n );\n }\n }\n\n /**\n * @notice Approve cancellation of signature migration. If cancellation approval passes guardian threshold with owner approval\n * it automatically cancels the migration.\n * @dev This method checks if the caller is one of guardian or owner and sets true for the cancellation hash in the approval config.\n * It internally calls _cancelSignatureMigration for canceling the migration\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function approveCancelSignatureMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n external\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"CancelSignatureMigration\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit SignatureMigrationCancellationApproved(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n if (\n getMigrationApprovalCountWithTimeValidity(migrationPublicKeyHash) >=\n LibGuardian.majorityOfGuardians() &&\n getMigrationOwnerApprovalWithTimeValidity(migrationPublicKeyHash)\n )\n _cancelSignatureMigration(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Verifies the signature of guardians/owner and cancels the signature migration.\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _approvers List of approvers. This could include owner\n */\n function cancelSignatureMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n )\n external\n override\n validateKeyType(_newPublicKey, _newVerificationFacet)\n onlyWhenUnlocked\n {\n uint256 approversLength = _approvers.length;\n if (approversLength != _signatures.length)\n revert SignatureMigrationFacet__InvalidArrayLength();\n\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"CancelSignatureMigration\"\n );\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(migrationPublicKeyHash, _approvers);\n\n bool onChainOwnerApproval = getMigrationOwnerApprovalWithTimeValidity(\n migrationPublicKeyHash\n );\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n if (\n approversLength +\n getMigrationApprovalCountWithTimeValidity(\n migrationPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert SignatureMigrationFacet__InsufficientApprovers();\n {\n // To prevent stack too deep\n bool ownerApproved;\n for (uint256 i; i < approversLength; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n address(this) != _approvers[i]\n ) revert SignatureMigrationFacet__NonExistentApprover();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert SignatureMigrationFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n migrationPublicKeyHash,\n _signatures[i]\n )\n ) revert SignatureMigrationFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n if (!ownerApproved && !onChainOwnerApproval)\n revert SignatureMigrationFacet__LackOfOwnerApproval();\n }\n _cancelSignatureMigration(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Internal function that cancels signature migration.\n * @dev This method increments migration nonce and deletes the migration from the migration config. Emits events for migration cancellation\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _cancelSignatureMigration(\n address _newVerificationFacet,\n bytes memory _newPublicKey,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal {\n if (!isMigrationPending())\n revert SignatureMigrationFacet__NonexistentMigration();\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n ++ms.nonce;\n delete ms.migrationConfigs[INNER_STRUCT];\n emit SignatureMigrationCanceled(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Checks if the facets to be added from new verification facet is registered to facet registry\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _checkMigrationCutValidity(\n address _newVerificationFacet,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal view {\n IDiamondCut.FacetCut[] memory facetCuts = new IDiamondCut.FacetCut[](1);\n facetCuts[0] = IDiamondCut.FacetCut({\n facetAddress: _newVerificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: _newVerificationFuncSelectors\n });\n _checkFacetCutValidity(facetCuts);\n }\n\n /**\n * @notice Returns if the migration is pending of not\n * @dev This method fetches the migration storage and checks if the migrate after is above 0 value\n * @return isPending Bool value that shows if the migration is pending\n */\n function isMigrationPending()\n public\n view\n override\n returns (bool isPending)\n {\n SignatureMigrationStorage storage rs = LibFacetStorage\n .migrationStorage();\n isPending = rs.migrationConfigs[INNER_STRUCT].migrateAfter > 0;\n }\n\n /**\n * @notice Returns the migration hash. This function ensures that this hash is safe from replay attack by including\n * public key, verification facet, function selectors, salt, address, chainId, and nonce.\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _saltString Salt value for generating the migration hash\n * @return migrationKeyHash Bytes32 string of the migration key hash\n */\n function getApprovalMigrationKeyHash(\n bytes memory _newPublicKey,\n address _newVerificationFacet,\n bytes4[] memory _newVerificationFuncSelectors,\n string memory _saltString\n ) public view override returns (bytes32 migrationKeyHash) {\n migrationKeyHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n _newPublicKey,\n _newVerificationFacet,\n keccak256(abi.encode(_newVerificationFuncSelectors)),\n _saltString,\n address(this),\n block.chainid,\n LibFacetStorage.migrationStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Checks if the owner approved the hash for migration\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @return isApprovedByOwner Bool value of showing if the owner approved it or not\n */\n function getMigrationOwnerApprovalWithTimeValidity(\n bytes32 _migrationPublicKeyHash\n ) public view override returns (bool isApprovedByOwner) {\n isApprovedByOwner = isMigrationApproved(\n _migrationPublicKeyHash,\n address(this)\n );\n }\n\n /**\n * @notice Checks how many of the guardians approved the migration hash\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @return approvalCount Number of approvals\n */\n function getMigrationApprovalCountWithTimeValidity(\n bytes32 _migrationPublicKeyHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardiansLength = guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n if (isMigrationApproved(_migrationPublicKeyHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n return approvalCount;\n }\n\n /**\n * @notice Checks if the migration is approved by the given approver\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @param _approver Address of approver\n * @return isApproved Bool value if migration hash is approved\n */\n function isMigrationApproved(\n bytes32 _migrationPublicKeyHash,\n address _approver\n ) public view override returns (bool isApproved) {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n isApproved = (ms\n .isMigrationApproved[_migrationPublicKeyHash][_approver].isApproved &&\n block.timestamp <\n ms\n .isMigrationApproved[_migrationPublicKeyHash][_approver]\n .validUntil);\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _migrationPublicKeyHash Hash of migration information\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _migrationPublicKeyHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isMigrationApproved(_migrationPublicKeyHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert SignatureMigrationFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the migration period of this wallet\n * @dev This method fetches the migration period from the security manager\n * @return migrationPeriod Migration period of Barz contract fetched from security manager\n */\n function getMigrationPeriod()\n internal\n view\n returns (uint128 migrationPeriod)\n {\n migrationPeriod = securityManager.migrationPeriodOf(address(this));\n if (migrationPeriod == 0)\n revert SignatureMigrationFacet__InvalidMigrationPeriod();\n }\n\n /**\n * @notice Returns the validation period of this wallet\n * @dev This method fetches the validation period from the security manager\n * @return approvalValidationPeriod Validation period of Barz contract fetched from security manager\n */\n function getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod == 0)\n revert SignatureMigrationFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the migration nonce of this wallet\n * @dev This method fetches the nonce from migration storage\n * @return migrationNonce Nonce of migration to protect from reply attacks\n */\n function getMigrationNonce()\n public\n view\n override\n returns (uint128 migrationNonce)\n {\n migrationNonce = LibFacetStorage.migrationStorage().nonce;\n }\n\n /**\n * @notice Returns the migration configuration of this wallet\n * @dev This method fetches the migration config from the migration storage\n * @return pendingMigrationConfig Migration config currently pending for signature migration\n */\n function getPendingMigration()\n external\n view\n override\n returns (SignatureMigrationConfig memory pendingMigrationConfig)\n {\n pendingMigrationConfig = LibFacetStorage\n .migrationStorage()\n .migrationConfigs[INNER_STRUCT];\n }\n}\n" + }, + "contracts/facets/TokenReceiverFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {IERC1155Receiver} from \"../interfaces/ERC/IERC1155Receiver.sol\";\nimport {IERC677Receiver} from \"../interfaces/ERC/IERC677Receiver.sol\";\n\n/**\n * @title TokenReceiver Facet\n * @dev Contract that enables receiving ERC721/ERC1155/ERC777/ERC677 Tokens with safe transfer\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract TokenReceiverFacet is\n IERC721Receiver,\n IERC1155Receiver,\n IERC777Recipient,\n IERC677Receiver\n{\n /**\n * @notice Handles ERC721 Token callback.\n * return Standardized onERC721Received return value.\n */\n function onERC721Received(\n address,\n address,\n uint256,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC721Receiver.onERC721Received.selector;\n }\n\n /**\n * @notice Handles ERC1155 Token callback.\n * return Standardized onERC1155Received return value.\n */\n function onERC1155Received(\n address,\n address,\n uint256,\n uint256,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC1155Receiver.onERC1155Received.selector;\n }\n\n /**\n * @notice Handles ERC1155 Token batch callback.\n * return Standardized onERC1155BatchReceived return value.\n */\n function onERC1155BatchReceived(\n address,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC1155Receiver.onERC1155BatchReceived.selector;\n }\n\n /**\n * @notice Handles ERC777 Token callback.\n * Does not return value, empty implementation.\n */\n function tokensReceived(\n address,\n address,\n address,\n uint256,\n bytes calldata,\n bytes calldata\n ) external pure override {}\n\n /**\n * @notice Handles ERC677 Token callback.\n * return true.\n */\n function onTokenTransfer(\n address,\n uint256,\n bytes calldata\n ) external pure override returns (bool) {\n return true;\n }\n}\n" + }, + "contracts/facets/verification/MultiSigFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {UserOperation} from \"../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../../libraries/LibLoupe.sol\";\nimport {LibAppStorage} from \"../../libraries/LibAppStorage.sol\";\nimport {LibMultiSigStorage, MultiSigStorage} from \"../../libraries/LibMultiSigStorage.sol\";\nimport {IERC1271} from \"../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../interfaces/IVerificationFacet.sol\";\nimport {IMultiSigFacet} from \"../interfaces/IMultiSigFacet.sol\";\n\n/**\n * @title Multi-sig facet\n * @dev Multi-signature Facet with custom threshold.\n * Wallet that adds this facet becomes a multi-sig wallet.\n * Reference signature_format.md documentation for Multi-sig facet details\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract MultiSigFacet is IMultiSigFacet, IVerificationFacet, IERC1271 {\n using ECDSA for bytes32;\n\n address public immutable self;\n\n address internal constant SENTINEL_OWNERS = address(0x1);\n uint256 internal constant ADDRESS = 20;\n uint256 internal constant SIG_TYPE = 1;\n uint256 internal constant SIG_LEN = 4;\n uint256 internal constant THRESHOLD = 4;\n uint256 internal constant INVALID_SIG = 1;\n uint256 internal constant VALID_SIG = 0;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in Multisig Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the right format and initializes signer storage in k1 storage.\n * @param _owners Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _owners\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n\n if (!isValidKeyType(_owners)) revert MultiSigFacet__InvalidInitData();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n uint256 threshold = uint256(uint32(bytes4(_owners)));\n uint256 ownerCount = (_owners.length - THRESHOLD) / ADDRESS;\n\n if (threshold == 0) revert MultiSigFacet__InvalidThreshold();\n if (ownerCount == 0) revert MultisigFacet__InvalidOwnerCount();\n\n address currentOwner = SENTINEL_OWNERS;\n uint256 ptr = THRESHOLD;\n address owner_;\n for (uint256 i; i < ownerCount; ) {\n owner_ = address(bytes20(_owners[ptr:ptr + ADDRESS]));\n ptr += ADDRESS;\n if (\n owner_ == address(0) ||\n owner_ == SENTINEL_OWNERS ||\n owner_ == address(this) ||\n owner_ == currentOwner\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[owner_] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n\n ms.owners[currentOwner] = owner_;\n currentOwner = owner_;\n\n unchecked {\n ++i;\n }\n }\n ms.owners[currentOwner] = SENTINEL_OWNERS;\n ms.ownerCount = ownerCount;\n ms.threshold = threshold;\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_owners);\n }\n\n /**\n * @notice Uninitialize signer in K1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n ++ms.counter;\n address[] memory ownerlist = getOwners();\n uint256 ownerlistLength = ownerlist.length;\n for (uint256 i; i < ownerlistLength; ) {\n ms.owners[ownerlist[i]] = address(0);\n unchecked {\n ++i;\n }\n }\n ms.owners[SENTINEL_OWNERS] = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls checkSignatures with\n * user operation hash and signature together with the threshold.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n // Data 1 is invalid, Data 0 is valid\n validationData = checkSignatures(\n userOpHash,\n userOp.signature,\n LibMultiSigStorage.multisigStorage().threshold\n );\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n return this.validateOwnerSignature.selector;\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n uint totalLength = ms.ownerCount * ADDRESS;\n bytes memory result = new bytes(totalLength);\n\n // populate return array\n uint256 index;\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n while (currentOwner != SENTINEL_OWNERS) {\n assembly {\n mstore(\n add(result, add(32, mul(index, ADDRESS))),\n shl(96, currentOwner)\n )\n }\n currentOwner = ms.owners[currentOwner];\n index++;\n }\n\n return result;\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key should comply with the format in the signature_format.md doc\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n uint256 publicKeyLength = _publicKey.length;\n if (\n publicKeyLength < ADDRESS + THRESHOLD ||\n (publicKeyLength - THRESHOLD) % ADDRESS != 0\n ) return false;\n\n uint256 threshold = uint256(uint32(bytes4(_publicKey)));\n uint256 ownerCount = (publicKeyLength - THRESHOLD) / ADDRESS;\n\n isValid = !(ownerCount < threshold || threshold == 0);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes calldata _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (checkSignatures(\n _hash,\n _signature,\n LibMultiSigStorage.multisigStorage().threshold\n ) == VALID_SIG)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n\n /**\n * @notice Validates the format of the signature and verifies if the signature is signed by the expected key.\n * Reference signature_format.md doc for details about signature format and signature types\n * @param _dataHash Bytes value of data hash signed by the owners\n * @param _signatures Bytes value of signature which should comply with signature format\n * @param _threshold Uint256 value of current Multi-sig Barz's threshold\n */\n function checkSignatures(\n bytes32 _dataHash,\n bytes calldata _signatures,\n uint256 _threshold\n ) public view returns (uint256) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n address lastOwner = address(0);\n address currentOwner;\n bytes memory signature;\n uint256 signatureType;\n uint256 nextOffset;\n uint256 i;\n for (i; i < _threshold; ) {\n (\n currentOwner,\n signature,\n signatureType,\n nextOffset\n ) = splitSignatures(_signatures, nextOffset);\n if (nextOffset == 0 && i + 1 < _threshold) return INVALID_SIG;\n if (signatureType == 1) {\n // If signatureType is 1 then it is default dataHash signed.\n // This also includes the contract signature\n if (\n !SignatureChecker.isValidSignatureNow(\n currentOwner,\n _dataHash,\n signature\n )\n ) return INVALID_SIG;\n } else if (signatureType == 2) {\n // If signatureType is 2 then it is an approved hash\n if (ms.approvedHashes[ms.counter][currentOwner][_dataHash] == 0)\n return INVALID_SIG;\n } else if (signatureType == 3) {\n // If signatureType is 3 then it is a signed message hash\n // This also includes the contract signature\n bytes32 msgHash = _dataHash.toEthSignedMessageHash();\n if (\n !SignatureChecker.isValidSignatureNow(\n currentOwner,\n msgHash,\n signature\n )\n ) return INVALID_SIG;\n } else revert MultiSigFacet__InvalidRoute();\n if (\n currentOwner <= lastOwner ||\n ms.owners[currentOwner] == address(0) ||\n currentOwner == SENTINEL_OWNERS\n ) return INVALID_SIG;\n lastOwner = currentOwner;\n\n unchecked {\n ++i;\n }\n }\n return VALID_SIG;\n }\n\n /**\n * @notice Split signatures into each individual signatures. Should comply with signature format to be split\n * @param _signatures Bytes value of signature\n * @param _nextOffset Uint256 value of next offset to start splitting the signature\n */\n function splitSignatures(\n bytes calldata _signatures,\n uint256 _nextOffset\n )\n public\n pure\n returns (\n address owner_,\n bytes memory signature,\n uint256 signatureType,\n uint256 nextOffset\n )\n {\n uint256 signaturesLength = _signatures.length;\n\n if (signaturesLength <= _nextOffset + ADDRESS + SIG_LEN)\n revert MultiSigFacet__InsufficientSignerLength();\n\n owner_ = address(\n bytes20(_signatures[_nextOffset:_nextOffset + ADDRESS])\n );\n\n signatureType = uint256(\n uint8(\n bytes1(\n _signatures[_nextOffset + ADDRESS:_nextOffset +\n ADDRESS +\n SIG_TYPE]\n )\n )\n );\n\n if (signatureType > 3 || signatureType == 0)\n revert MultiSigFacet__InvalidSignatureType();\n uint256 offSet = _nextOffset + ADDRESS + SIG_TYPE;\n uint256 siglen = uint256(\n uint32(bytes4(_signatures[offSet:offSet + SIG_LEN]))\n );\n if (offSet + siglen > signaturesLength)\n revert MultiSigFacet__InvalidSignatureLength();\n\n offSet += SIG_LEN;\n if (offSet + siglen == signaturesLength) nextOffset = 0;\n else nextOffset = offSet + siglen;\n\n signature = _signatures[offSet:offSet + siglen];\n }\n\n /**\n * @notice Approves the hash of userOperation on-chain. This can only be called by owners.\n * @param _hashToApprove Bytes value of UserOperation hash to approve\n */\n function approveHash(bytes32 _hashToApprove) external {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (ms.owners[msg.sender] == address(0))\n revert MultiSigFacet__OnlyOwner();\n\n ms.approvedHashes[ms.counter][msg.sender][_hashToApprove] = 1;\n emit HashApproved(_hashToApprove, msg.sender);\n }\n\n /**\n * @notice Add owner to Barz. Update thresold if threshold is given different from current threshold\n * @dev This can only be done via a Self call.\n * @param _newOwner Address of new owner to be added\n * @param _threshold Uint256 value of threshold\n */\n function addOwner(address _newOwner, uint256 _threshold) external {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (\n _newOwner == address(0) ||\n _newOwner == SENTINEL_OWNERS ||\n _newOwner == address(this)\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_newOwner] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n\n ms.owners[_newOwner] = ms.owners[SENTINEL_OWNERS];\n ms.owners[SENTINEL_OWNERS] = _newOwner;\n ++ms.ownerCount;\n emit OwnerAdded(_newOwner);\n\n if (ms.threshold != _threshold) changeThreshold(_threshold);\n }\n\n /**\n * @notice Remove owner from Barz. Update thresold if threshold is given different from current threshold\n * @dev This can only be done via a Self call.\n * @param _prevOwner Address of owner located right behind the removed owner address in the linked list\n * @param _removedOwner Address of owner to be removed\n * @param _threshold Uint256 value of threshold\n */\n function removeOwner(\n address _prevOwner,\n address _removedOwner,\n uint256 _threshold\n ) external {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (ms.ownerCount - 1 < _threshold)\n revert MultiSigFacet__InvalidThreshold();\n if (_removedOwner == address(0) || _removedOwner == SENTINEL_OWNERS)\n revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_prevOwner] != _removedOwner)\n revert MultiSigFacet__InvalidOwnerPair();\n\n ms.owners[_prevOwner] = ms.owners[_removedOwner];\n ms.owners[_removedOwner] = address(0);\n --ms.ownerCount;\n emit OwnerRemoved(_removedOwner);\n\n if (ms.threshold != _threshold) changeThreshold(_threshold);\n }\n\n /**\n * @notice Swap owner in Barz.\n * @dev This can only be done via a Self call.\n * @param _prevOwner Address of owner located right behind the removed owner address in the linked list\n * @param _oldOwner Address of owner to be removed\n * @param _newOwner Address of owner to be added\n */\n function swapOwner(\n address _prevOwner,\n address _oldOwner,\n address _newOwner\n ) public {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (\n _newOwner == address(0) ||\n _newOwner == SENTINEL_OWNERS ||\n _newOwner == address(this)\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_newOwner] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n if (_oldOwner == address(0) || _oldOwner == SENTINEL_OWNERS)\n revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_prevOwner] != _oldOwner)\n revert MultiSigFacet__InvalidOwnerPair();\n\n ms.owners[_newOwner] = ms.owners[_oldOwner];\n ms.owners[_prevOwner] = _newOwner;\n ms.owners[_oldOwner] = address(0);\n emit OwnerRemoved(_oldOwner);\n emit OwnerAdded(_newOwner);\n }\n\n /**\n * @notice Changes the threshold of the Barz to `_threshold`.\n * @dev This can only be done via a Self call.\n * @param _threshold New threshold\n */\n function changeThreshold(uint256 _threshold) public {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (_threshold > ms.ownerCount || _threshold == 0)\n revert MultiSigFacet__InvalidThreshold();\n\n ms.threshold = _threshold;\n emit ThresholdChanged(_threshold);\n }\n\n /**\n * @notice Checks if the given address is owner\n * @param _owner Address to be checked if it's owner\n * @return isOwner_ Bool value showing if it's owner address\n */\n function isOwner(address _owner) public view returns (bool isOwner_) {\n isOwner_ = (_owner != SENTINEL_OWNERS &&\n LibMultiSigStorage.multisigStorage().owners[_owner] != address(0));\n }\n\n /**\n * @notice Returns the threshold of Barz\n * @return threshold Threshold of the Barz account\n */\n function getThreshold() public view returns (uint256 threshold) {\n threshold = LibMultiSigStorage.multisigStorage().threshold;\n }\n\n /**\n * @notice Returns the list of owner addresses\n * @return owners List of owners\n */\n function getOwners() public view returns (address[] memory owners) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n owners = new address[](ms.ownerCount);\n\n uint256 index;\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n while (currentOwner != SENTINEL_OWNERS) {\n owners[index] = currentOwner;\n currentOwner = ms.owners[currentOwner];\n index++;\n }\n }\n\n /**\n * @notice Returns the previous owner in the linked list\n * @param _owner Address of owner\n * @return prevOwner Address of previous owner\n */\n function getPrevOwner(\n address _owner\n ) public view returns (address prevOwner) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n if (currentOwner == _owner) return SENTINEL_OWNERS;\n while (currentOwner != SENTINEL_OWNERS) {\n if (ms.owners[currentOwner] == _owner) return currentOwner;\n\n currentOwner = ms.owners[currentOwner];\n }\n return address(0);\n }\n\n /**\n * @notice Returns of the owner is approved by given owner address\n * @param _owner Address of owner\n * @param _hash Hash of UserOperation\n * @return isApproved Bool value showing if the hash is approved by owner\n */\n function isApprovedHash(\n address _owner,\n bytes32 _hash\n ) public view returns (bool isApproved) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n isApproved = (ms.approvedHashes[ms.counter][_owner][_hash] == 1);\n }\n}\n" + }, + "contracts/facets/verification/secp256k1/Secp256k1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {UserOperation} from \"../../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibAppStorage} from \"../../../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, Secp256k1VerificationStorage} from \"../../../libraries/LibFacetStorage.sol\";\nimport {LibLoupe} from \"../../../libraries/LibLoupe.sol\";\nimport {IERC1271} from \"../../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../../interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Secp256k1 verification facet\n * @dev Default Ethereum's elliptic curve\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract Secp256k1VerificationFacet is IVerificationFacet, IERC1271 {\n using ECDSA for bytes32;\n error Secp256k1VerificationFacet__InvalidSignerLength();\n address public immutable self;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in K1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\n * @param _publicKey Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _publicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n if (!isValidKeyType(_publicKey))\n revert Secp256k1VerificationFacet__InvalidSignerLength();\n\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(uint160(uint256(keccak256(_publicKey[1:]))));\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_publicKey);\n }\n\n /**\n * @notice Uninitialize signer in K1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\n * signer public key.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n validationData = validateSignature(\n userOp,\n userOpHash,\n k1Storage.signer\n );\n }\n\n /**\n * @notice Validates if the signature of UserOperation is signed by the given signer\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @param signer Address of signer who signed the contract, to be validated\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n address signer\n ) public pure returns (uint256 isValid) {\n bytes32 hash = userOpHash.toEthSignedMessageHash();\n isValid = (signer != hash.recover(userOp.signature)) ? 1 : 0;\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n ownerSignatureValidatorSelector = this.validateOwnerSignature.selector;\n // NOTE: The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory signer) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n signer = abi.encodePacked(k1Storage.signer);\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key length should be 65 in an uncompressed public key format\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (_hash.recover(_signature) ==\n LibFacetStorage.k1Storage().signer)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/Secp256r1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {UserOperation} from \"../../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibAppStorage} from \"../../../libraries/LibAppStorage.sol\";\nimport {LibLoupe} from \"../../../libraries/LibLoupe.sol\";\nimport {LibFacetStorage, Secp256r1VerificationStorage} from \"../../../libraries/LibFacetStorage.sol\";\nimport {Base64} from \"./utils/Base64.sol\";\nimport {LibSecp256r1} from \"./utils/LibSecp256r1.sol\";\nimport {IERC1271} from \"../../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../../interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Secp256r1 verification facet\n * @dev Primarily used to verify user ops signed with passkeys\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract Secp256r1VerificationFacet is IVerificationFacet, IERC1271 {\n error Secp256r1VerificationFacet__InvalidSignerLength();\n address public immutable self;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in R1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\n * @param _publicKey Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _publicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n\n if (!isValidKeyType(_publicKey))\n revert Secp256r1VerificationFacet__InvalidSignerLength();\n\n bytes memory publicKeyCoordinates = _publicKey[1:];\n uint256[2] memory q;\n assembly {\n // Copy the bytes from the input data into the uint256 array\n mstore(q, mload(add(publicKeyCoordinates, 32)))\n mstore(add(q, 32), mload(add(publicKeyCoordinates, 64)))\n }\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n r1Storage.q = q;\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_publicKey);\n }\n\n /**\n * @notice Uninitialize signer in R1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n r1Storage.q = [0, 0];\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\n * signer public key.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n validationData = validateSignature(userOp, userOpHash, r1Storage.q);\n }\n\n /**\n * @notice Validates if the signature of UserOperation is signed by the given signer\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @param q Public Key of signer who signed the contract, to be validated\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256[2] memory q\n ) public view returns (uint256 isValid) {\n isValid = (_validateSignature(q, userOpHash, userOp.signature)) ? 0 : 1;\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n return this.validateOwnerSignature.selector; // validateOwnerSignature(UserOperation calldata userOp,bytes32 userOpHash)\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory signer) {\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n signer = abi.encodePacked(r1Storage.q);\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key should in an uncompressed public key format\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = _validateSignature(\n LibFacetStorage.r1Storage().q,\n _hash,\n _signature\n )\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n\n function _validateSignature(\n uint256[2] memory q,\n bytes32 _hash,\n bytes memory _signature\n ) internal view returns (bool) {\n (\n uint256 rValue,\n uint256 sValue,\n bytes memory authenticatorData,\n string memory clientDataJSONPre,\n string memory clientDataJSONPost\n ) = abi.decode(_signature, (uint256, uint256, bytes, string, string));\n bytes32 clientHash;\n {\n string memory opHashBase64 = Base64.encode(bytes.concat(_hash));\n string memory clientDataJSON = string.concat(\n clientDataJSONPre,\n opHashBase64,\n clientDataJSONPost\n );\n clientHash = sha256(bytes(clientDataJSON));\n }\n bytes32 sigHash = sha256(bytes.concat(authenticatorData, clientHash));\n return LibSecp256r1.Verify(q, rValue, sValue, uint256(sigHash));\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/utils/Base64.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @dev Provides a set of functions to operate with Base64 strings.\n * modified for base64url https://datatracker.ietf.org/doc/html/rfc4648#section-5\n * _Available since v4.5._\n */\nlibrary Base64 {\n /**\n * @dev Base64 Encoding/Decoding Table\n */\n string internal constant _TABLE =\n \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_\";\n\n /**\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\n */\n function encode(bytes memory data) internal pure returns (string memory) {\n /**\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\n */\n if (data.length == 0) return \"\";\n\n // Loads the table into memory\n string memory table = _TABLE;\n\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\n // and split into 4 numbers of 6 bits.\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\n // - `data.length + 2` -> Round up\n // - `/ 3` -> Number of 3-bytes chunks\n // - `4 *` -> 4 characters for each chunk\n uint256 newlength = (data.length * 8) / 6;\n if (data.length % 6 > 0) {\n newlength++;\n }\n string memory result = new string(newlength);\n\n /// @solidity memory-safe-assembly\n assembly {\n // Prepare the lookup table (skip the first \"length\" byte)\n let tablePtr := add(table, 1)\n\n // Prepare result pointer, jump over length\n let resultPtr := add(result, 32)\n\n // Run over the input, 3 bytes at a time\n for {\n let dataPtr := data\n let endPtr := add(data, mload(data))\n } lt(dataPtr, endPtr) {\n\n } {\n // Advance 3 bytes\n dataPtr := add(dataPtr, 3)\n let input := mload(dataPtr)\n\n // To write each character, shift the 3 bytes (18 bits) chunk\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\n // and apply logical AND with 0x3F which is the number of\n // the previous character in the ASCII table prior to the Base64 Table\n // The result is then added to the table to get the character to write,\n // and finally write it in the result pointer but with a left shift\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(18, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(12, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(6, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n }\n }\n\n return result;\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/utils/LibSecp256r1.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n// Heavily inspired from\n// https://github.com/maxrobot/elliptic-solidity/blob/master/contracts/Secp256r1.sol\n// https://github.com/tdrerup/elliptic-curve-solidity/blob/master/contracts/curves/EllipticCurve.sol\n// modified to use precompile 0x05 modexp\n// and modified jacobian double\n// optimisations to avoid to an from from affine and jacobian coordinates\n\n// Additional Elliptic curve Public key / Signature validation added by\n// David Yonjun Kim (@Powerstream3604)\n\nstruct JPoint {\n uint256 x;\n uint256 y;\n uint256 z;\n}\n\nlibrary LibSecp256r1 {\n uint256 constant gx =\n 0x6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296;\n uint256 constant gy =\n 0x4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5;\n uint256 public constant pp =\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF;\n\n uint256 public constant nn =\n 0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551;\n uint256 constant a =\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC;\n uint256 constant b =\n 0x5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B;\n uint256 constant MOST_SIGNIFICANT =\n 0xc000000000000000000000000000000000000000000000000000000000000000;\n\n /*\n * Verify\n * @description - verifies that a public key has signed a given message\n * @param Q - public key coordinates X & Y\n * @param R - signature half R\n * @param S - signature half S\n * @param input - hashed message\n */\n function Verify(\n uint256[2] memory q,\n uint r,\n uint s,\n uint e\n ) internal view returns (bool) {\n if (q[0] > pp - 1 || q[1] > pp - 1) {\n return false;\n }\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\n return false;\n }\n if (\n mulmod(q[1], q[1], pp) !=\n addmod(\n addmod(\n mulmod(q[0], mulmod(q[0], q[0], pp), pp),\n mulmod(a, q[0], pp),\n pp\n ),\n b,\n pp\n )\n ) {\n return false;\n }\n\n JPoint[16] memory points = _preComputeJacobianPoints(q);\n return VerifyWithPrecompute(points, r, s, e);\n }\n\n function VerifyWithPrecompute(\n JPoint[16] memory points,\n uint r,\n uint s,\n uint e\n ) internal view returns (bool) {\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\n return false;\n }\n\n uint w = _primemod(s, nn);\n\n uint u1 = mulmod(e, w, nn);\n uint u2 = mulmod(r, w, nn);\n\n uint x;\n uint y;\n\n (x, y) = ShamirMultJacobian(points, u1, u2);\n return (x == r);\n }\n\n /*\n * Strauss Shamir trick for EC multiplication\n * https://stackoverflow.com/questions/50993471/ec-scalar-multiplication-with-strauss-shamir-method\n * we optimise on this a bit to do with 2 bits at a time rather than a single bit\n * the individual points for a single pass are precomputed\n * overall this reduces the number of additions while keeping the same number of doublings\n */\n function ShamirMultJacobian(\n JPoint[16] memory points,\n uint u1,\n uint u2\n ) internal view returns (uint, uint) {\n uint x = 0;\n uint y = 0;\n uint z = 0;\n uint bits = 128;\n uint index = 0;\n\n while (bits > 0) {\n if (z > 0) {\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\n }\n index =\n ((u1 & MOST_SIGNIFICANT) >> 252) |\n ((u2 & MOST_SIGNIFICANT) >> 254);\n if (index > 0) {\n (x, y, z) = _jAdd(\n x,\n y,\n z,\n points[index].x,\n points[index].y,\n points[index].z\n );\n }\n u1 <<= 2;\n u2 <<= 2;\n bits--;\n }\n (x, y) = _affineFromJacobian(x, y, z);\n return (x, y);\n }\n\n function _preComputeJacobianPoints(\n uint256[2] memory q\n ) internal pure returns (JPoint[16] memory points) {\n points[0] = JPoint(0, 0, 0);\n points[1] = JPoint(q[0], q[1], 1); // u2\n points[2] = _jPointDouble(points[1]);\n points[3] = _jPointAdd(points[1], points[2]);\n\n points[4] = JPoint(gx, gy, 1); // u1Points[1]\n points[5] = _jPointAdd(points[4], points[1]);\n points[6] = _jPointAdd(points[4], points[2]);\n points[7] = _jPointAdd(points[4], points[3]);\n\n points[8] = _jPointDouble(points[4]); // u1Points[2]\n points[9] = _jPointAdd(points[8], points[1]);\n points[10] = _jPointAdd(points[8], points[2]);\n points[11] = _jPointAdd(points[8], points[3]);\n\n points[12] = _jPointAdd(points[4], points[8]); // u1Points[3]\n points[13] = _jPointAdd(points[12], points[1]);\n points[14] = _jPointAdd(points[12], points[2]);\n points[15] = _jPointAdd(points[12], points[3]);\n }\n\n function _jPointAdd(\n JPoint memory p1,\n JPoint memory p2\n ) internal pure returns (JPoint memory) {\n uint x;\n uint y;\n uint z;\n (x, y, z) = _jAdd(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z);\n return JPoint(x, y, z);\n }\n\n function _jPointDouble(\n JPoint memory p\n ) internal pure returns (JPoint memory) {\n uint x;\n uint y;\n uint z;\n (x, y, z) = _modifiedJacobianDouble(p.x, p.y, p.z);\n return JPoint(x, y, z);\n }\n\n /* _affineFromJacobian\n * @desription returns affine coordinates from a jacobian input follows\n * golang elliptic/crypto library\n */\n function _affineFromJacobian(\n uint x,\n uint y,\n uint z\n ) internal view returns (uint ax, uint ay) {\n if (z == 0) {\n return (0, 0);\n }\n\n uint zinv = _primemod(z, pp);\n uint zinvsq = mulmod(zinv, zinv, pp);\n\n ax = mulmod(x, zinvsq, pp);\n ay = mulmod(y, mulmod(zinvsq, zinv, pp), pp);\n }\n\n /*\n * _jAdd\n * @description performs Jacobian addition as defined below:\n * http://www.hyperelliptic.org/EFD/g1p/data/shortw/jacobian/addition/add-2007-bl\n */\n function _jAdd(\n uint p1,\n uint p2,\n uint p3,\n uint q1,\n uint q2,\n uint q3\n ) internal pure returns (uint r1, uint r2, uint r3) {\n if (p3 == 0) {\n r1 = q1;\n r2 = q2;\n r3 = q3;\n\n return (r1, r2, r3);\n } else if (q3 == 0) {\n r1 = p1;\n r2 = p2;\n r3 = p3;\n\n return (r1, r2, r3);\n }\n\n assembly {\n let\n pd\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\n let z1z1 := mulmod(p3, p3, pd) // Z1Z1 = Z1^2\n let z2z2 := mulmod(q3, q3, pd) // Z2Z2 = Z2^2\n\n let u1 := mulmod(p1, z2z2, pd) // U1 = X1*Z2Z2\n let u2 := mulmod(q1, z1z1, pd) // U2 = X2*Z1Z1\n\n let s1 := mulmod(p2, mulmod(z2z2, q3, pd), pd) // S1 = Y1*Z2*Z2Z2\n let s2 := mulmod(q2, mulmod(z1z1, p3, pd), pd) // S2 = Y2*Z1*Z1Z1\n\n let p3q3 := addmod(p3, q3, pd)\n\n if lt(u2, u1) {\n u2 := add(pd, u2) // u2 = u2+pd\n }\n let h := sub(u2, u1) // H = U2-U1\n\n let i := mulmod(0x02, h, pd)\n i := mulmod(i, i, pd) // I = (2*H)^2\n\n let j := mulmod(h, i, pd) // J = H*I\n if lt(s2, s1) {\n s2 := add(pd, s2) // u2 = u2+pd\n }\n let rr := mulmod(0x02, sub(s2, s1), pd) // r = 2*(S2-S1)\n r1 := mulmod(rr, rr, pd) // X3 = R^2\n\n let v := mulmod(u1, i, pd) // V = U1*I\n let j2v := addmod(j, mulmod(0x02, v, pd), pd)\n if lt(r1, j2v) {\n r1 := add(pd, r1) // X3 = X3+pd\n }\n r1 := sub(r1, j2v)\n\n // Y3 = r*(V-X3)-2*S1*J\n let s12j := mulmod(mulmod(0x02, s1, pd), j, pd)\n\n if lt(v, r1) {\n v := add(pd, v)\n }\n r2 := mulmod(rr, sub(v, r1), pd)\n\n if lt(r2, s12j) {\n r2 := add(pd, r2)\n }\n r2 := sub(r2, s12j)\n\n // Z3 = ((Z1+Z2)^2-Z1Z1-Z2Z2)*H\n z1z1 := addmod(z1z1, z2z2, pd)\n j2v := mulmod(p3q3, p3q3, pd)\n if lt(j2v, z1z1) {\n j2v := add(pd, j2v)\n }\n r3 := mulmod(sub(j2v, z1z1), h, pd)\n }\n return (r1, r2, r3);\n }\n\n // Point doubling on the modified jacobian coordinates\n // http://point-at-infinity.org/ecc/Prime_Curve_Modified_Jacobian_Coordinates.html\n function _modifiedJacobianDouble(\n uint x,\n uint y,\n uint z\n ) internal pure returns (uint x3, uint y3, uint z3) {\n if (y == 0) return (0, 0, 0);\n assembly {\n let\n pd\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\n let z2 := mulmod(z, z, pd)\n let az4 := mulmod(\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC,\n mulmod(z2, z2, pd),\n pd\n )\n let y2 := mulmod(y, y, pd)\n let s := mulmod(0x04, mulmod(x, y2, pd), pd)\n let u := mulmod(0x08, mulmod(y2, y2, pd), pd)\n let m := addmod(mulmod(0x03, mulmod(x, x, pd), pd), az4, pd)\n let twos := mulmod(0x02, s, pd)\n let m2 := mulmod(m, m, pd)\n if lt(m2, twos) {\n m2 := add(pd, m2)\n }\n x3 := sub(m2, twos)\n if lt(s, x3) {\n s := add(pd, s)\n }\n y3 := mulmod(m, sub(s, x3), pd)\n if lt(y3, u) {\n y3 := add(pd, y3)\n }\n y3 := sub(y3, u)\n z3 := mulmod(0x02, mulmod(y, z, pd), pd)\n }\n }\n\n // Fermats little theorem https://en.wikipedia.org/wiki/Fermat%27s_little_theorem\n // a^(p-1) = 1 mod p\n // a^(-1) ≅ a^(p-2) (mod p)\n // we then use the precompile bigModExp to compute a^(-1)\n function _primemod(uint value, uint p) internal view returns (uint ret) {\n ret = modexp(value, p - 2, p);\n return ret;\n }\n\n // Wrapper for built-in BigNumber_modexp (contract 0x5) as described here. https://github.com/ethereum/EIPs/pull/198\n function modexp(\n uint _base,\n uint _exp,\n uint _mod\n ) internal view returns (uint ret) {\n // bigModExp(_base, _exp, _mod);\n assembly {\n if gt(_base, _mod) {\n _base := mod(_base, _mod)\n }\n // Free memory pointer is always stored at 0x40\n let freemem := mload(0x40)\n\n mstore(freemem, 0x20)\n mstore(add(freemem, 0x20), 0x20)\n mstore(add(freemem, 0x40), 0x20)\n\n mstore(add(freemem, 0x60), _base)\n mstore(add(freemem, 0x80), _exp)\n mstore(add(freemem, 0xa0), _mod)\n\n let success := staticcall(14000, 0x5, freemem, 0xc0, freemem, 0x20)\n switch success\n case 0 {\n revert(0x0, 0x0)\n }\n default {\n ret := mload(freemem)\n }\n }\n }\n}\n" + }, + "contracts/infrastructure/DefaultFallbackHandler.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC1155Receiver} from \"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\";\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {BaseAccount} from \"../aa-4337/core/BaseAccount.sol\";\nimport {DefaultLibDiamond} from \"../libraries/DefaultLibDiamond.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IAccountFacet} from \"../facets/interfaces/IAccountFacet.sol\";\nimport {IStorageLoupe} from \"../facets/base/interfaces/IStorageLoupe.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IERC677Receiver} from \"../interfaces/ERC/IERC677Receiver.sol\";\nimport {IERC165} from \"../interfaces/ERC/IERC165.sol\";\n\n/**\n * @title DefaultFallbackHandler\n * @dev A default fallback handler for Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DefaultFallbackHandler is IDiamondLoupe {\n /**\n * @notice Sets the middleware diamond for Barz wallet as a fallback handler\n * @dev This contract is also a diamond that holds the default facets to reduce gas cost for wallet activation.\n * Within the constructor this conducts diamond cut to initially setup the diamond. This is a non-upgradeable contract\n * @param _diamondCutFacet Address if diamond cut facet\n * @param _accountFacet Address account facet\n * @param _tokenReceiverFacet Address of token receiver facet\n * @param _diamondLoupeFacet Address of diamond loupe facet\n */\n constructor(\n address _diamondCutFacet,\n address _accountFacet,\n address _tokenReceiverFacet,\n address _diamondLoupeFacet\n ) payable {\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](4);\n bytes4[] memory functionSelectors = new bytes4[](1);\n functionSelectors[0] = IDiamondCut.diamondCut.selector;\n\n bytes4[] memory accountFunctionSelectors = new bytes4[](5);\n accountFunctionSelectors[0] = IAccountFacet.execute.selector;\n accountFunctionSelectors[1] = IAccountFacet.executeBatch.selector;\n accountFunctionSelectors[2] = BaseAccount.validateUserOp.selector;\n accountFunctionSelectors[3] = BaseAccount.getNonce.selector;\n accountFunctionSelectors[4] = BaseAccount.entryPoint.selector;\n\n bytes4[] memory receiverFacetSelectors = new bytes4[](5);\n receiverFacetSelectors[0] = IERC721Receiver.onERC721Received.selector;\n receiverFacetSelectors[1] = IERC1155Receiver.onERC1155Received.selector;\n receiverFacetSelectors[2] = IERC1155Receiver\n .onERC1155BatchReceived\n .selector;\n receiverFacetSelectors[3] = IERC777Recipient.tokensReceived.selector;\n receiverFacetSelectors[4] = IERC677Receiver.onTokenTransfer.selector;\n\n bytes4[] memory loupeFacetSelectors = new bytes4[](9);\n loupeFacetSelectors[0] = IDiamondLoupe.facets.selector;\n loupeFacetSelectors[1] = IDiamondLoupe.facetFunctionSelectors.selector;\n loupeFacetSelectors[2] = IDiamondLoupe.facetAddresses.selector;\n loupeFacetSelectors[3] = IDiamondLoupe.facetAddress.selector;\n loupeFacetSelectors[4] = IERC165.supportsInterface.selector;\n loupeFacetSelectors[5] = IStorageLoupe.facetsFromStorage.selector;\n loupeFacetSelectors[6] = IStorageLoupe\n .facetFunctionSelectorsFromStorage\n .selector;\n loupeFacetSelectors[7] = IStorageLoupe\n .facetAddressesFromStorage\n .selector;\n loupeFacetSelectors[8] = IStorageLoupe.facetAddressFromStorage.selector;\n\n {\n cut[0] = IDiamondCut.FacetCut({\n facetAddress: _diamondCutFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: functionSelectors\n });\n cut[1] = IDiamondCut.FacetCut({\n facetAddress: _accountFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: accountFunctionSelectors\n });\n cut[2] = IDiamondCut.FacetCut({\n facetAddress: _tokenReceiverFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: receiverFacetSelectors\n });\n cut[3] = IDiamondCut.FacetCut({\n facetAddress: _diamondLoupeFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: loupeFacetSelectors\n });\n\n DefaultLibDiamond.diamondCut(cut, address(0), \"\");\n }\n }\n\n /**\n * @notice Returns the facet information of call facets registered to this diamond.\n * @return facets_ The facet struct array including all facet information\n */\n function facets() external view override returns (Facet[] memory facets_) {\n DefaultLibDiamond.DiamondStorage storage ds = DefaultLibDiamond\n .diamondStorage();\n uint256 numFacets = ds.facetAddresses.length;\n facets_ = new Facet[](numFacets);\n for (uint256 i; i < numFacets; ) {\n address facetAddress_ = ds.facetAddresses[i];\n facets_[i].facetAddress = facetAddress_;\n facets_[i].functionSelectors = ds\n .facetFunctionSelectors[facetAddress_]\n .functionSelectors;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Gets all the function selectors provided by a facet.\n * @param _facet The facet address.\n * @return facetFunctionSelectors_\n */\n function facetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n facetFunctionSelectors_ = DefaultLibDiamond\n .diamondStorage()\n .facetFunctionSelectors[_facet]\n .functionSelectors;\n }\n\n /**\n * @notice Get all the facet addresses used by a diamond.\n * @return facetAddresses_\n */\n function facetAddresses()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n facetAddresses_ = DefaultLibDiamond.diamondStorage().facetAddresses;\n }\n\n /** @notice Gets the facet that supports the given selector.\n * @dev If facet is not found return address(0).\n * @param _functionSelector The function selector.\n * @return facetAddress_ The facet address.\n */\n function facetAddress(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n facetAddress_ = DefaultLibDiamond\n .diamondStorage()\n .selectorToFacetAndPosition[_functionSelector]\n .facetAddress;\n }\n}\n" + }, + "contracts/infrastructure/FacetRegistry.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport {IFacetRegistry} from \"./interfaces/IFacetRegistry.sol\";\n\n/**\n * @title Facet Registry\n * @dev Contract to keep track of facets & function selectors addable to user wallets\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract FacetRegistry is IFacetRegistry, Ownable2Step {\n mapping(address => FacetRegistryConfig) private facets;\n\n /**\n * @notice Transfers the ownership of the contract to the given owner\n * @param _owner Address of owner who has access to initialize the default security variables for security manager\n */\n constructor(address _owner) {\n transferOwnership(_owner);\n _transferOwnership(_owner);\n }\n\n /**\n * @dev Registers a facet and it's function selectors to registry\n * @param _facet address of facet\n * @param _facetSelectors list of function selectors of the facet\n */\n function registerFacetFunctionSelectors(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external override onlyOwner {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n uint256 facetSelectorsLength = _facetSelectors.length;\n for (uint256 i; i < facetSelectorsLength; ) {\n if (facetConfig.info[_facetSelectors[i]].exists)\n revert FacetRegistry__FacetSelectorAlreadyRegistered();\n\n facetConfig.info[_facetSelectors[i]].exists = true;\n facetConfig.info[_facetSelectors[i]].index = uint128(\n facetConfig.selectors.length\n );\n facetConfig.selectors.push(_facetSelectors[i]);\n unchecked {\n ++i;\n }\n }\n emit FacetFunctionSelectorsRegistered(_facet, _facetSelectors);\n }\n\n /**\n * @dev Removes a registered facet and it's corresponding selectors from registry\n * @param _facet address of facet\n * @param _facetSelectors list of function selectors of the facet\n */\n function removeFacetFunctionSelectors(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external override onlyOwner {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n uint256 facetSelectorsLength = _facetSelectors.length;\n for (uint256 i; i < facetSelectorsLength; ) {\n if (!facetConfig.info[_facetSelectors[i]].exists)\n revert FacetRegistry__UnregisteredFacetSelector();\n\n bytes4 lastSelector = facetConfig.selectors[\n facetConfig.selectors.length - 1\n ];\n if (_facetSelectors[i] != lastSelector) {\n uint128 targetIndex = facetConfig\n .info[_facetSelectors[i]]\n .index;\n facetConfig.selectors[targetIndex] = lastSelector;\n facetConfig.info[lastSelector].index = targetIndex;\n }\n facetConfig.selectors.pop();\n delete facetConfig.info[_facetSelectors[i]];\n\n unchecked {\n ++i;\n }\n }\n emit FacetFunctionSelectorsRemoved(_facet, _facetSelectors);\n }\n\n /**\n * @dev Checks if a facet and it's selectors given is registered to facet registry\n * @param _facet Address of facet\n * @param _facetSelectors List of function selectors of the facet\n */\n function areFacetFunctionSelectorsRegistered(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external view override returns (bool) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n uint256 facetSelectorsLength = _facetSelectors.length;\n if (facetSelectorsLength == 0) return false;\n for (uint256 i; i < facetSelectorsLength; ) {\n if (!facetConfig.info[_facetSelectors[i]].exists) return false;\n unchecked {\n ++i;\n }\n }\n return true;\n }\n\n /**\n * @dev Checks if a facet and it's selector given is registered to facet registry\n * @param _facet Address of facet\n * @param _facetSelector List of function selectors of the facet\n * @return isRegistered Bool value showing if the selector is registered\n */\n function isFacetFunctionSelectorRegistered(\n address _facet,\n bytes4 _facetSelector\n ) external view override returns (bool isRegistered) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n isRegistered = facetConfig.info[_facetSelector].exists;\n }\n\n /**\n * @dev Get the registered selectors of facet from registry\n * @param _facet Address of facet\n * @return selectors Selectors registered to facet\n */\n function getFacetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory selectors) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n selectors = facetConfig.selectors;\n }\n}\n" + }, + "contracts/infrastructure/interfaces/IFacetRegistry.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Registry Interface\n * @dev Interface for Facet Registry contract to keep track of facets & function selectors addable to user wallets\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IFacetRegistry {\n struct FacetRegistryConfig {\n bytes4[] selectors;\n mapping(bytes4 => FacetInfo) info;\n }\n struct FacetInfo {\n bool exists;\n uint128 index;\n }\n\n event FacetFunctionSelectorsRegistered(\n address facet,\n bytes4[] facetSelectors\n );\n event FacetFunctionSelectorsRemoved(address facet, bytes4[] facetSelectors);\n\n error FacetRegistry__FacetSelectorAlreadyRegistered();\n error FacetRegistry__UnregisteredFacetSelector();\n\n function registerFacetFunctionSelectors(\n address facet,\n bytes4[] calldata facetSelectors\n ) external;\n\n function removeFacetFunctionSelectors(\n address facet,\n bytes4[] calldata facetSelectors\n ) external;\n\n function areFacetFunctionSelectorsRegistered(\n address facet,\n bytes4[] calldata facetSelectors\n ) external view returns (bool);\n\n function isFacetFunctionSelectorRegistered(\n address facet,\n bytes4 facetSelector\n ) external view returns (bool);\n\n function getFacetFunctionSelectors(\n address facet\n ) external view returns (bytes4[] memory);\n}\n" + }, + "contracts/infrastructure/interfaces/ISecurityManager.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Registry Interface\n * @dev Infrastructure contract to manage security parameters of users\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface ISecurityManager {\n error SecurityManager__OutOfBoundary();\n error SecurityManager__CallerNotWallet();\n error SecurityManager__AlreadyIntialized();\n\n function initializeAdditionSecurityPeriod(\n uint128 defaultAdditionSecurityPeriod,\n uint128 minAdditionSecurityPeriod,\n uint128 maxAdditionSecurityPeriod\n ) external;\n\n function initializeRemovalSecurityPeriod(\n uint128 defaultRemovalSecurityPeriod,\n uint128 minRemovalSecurityPeriod,\n uint128 maxRemovalSecurityPeriod\n ) external;\n\n function initializeApprovalValidationPeriod(\n uint128 defaultApprovalValidationPeriod,\n uint128 minApprovalValidationPeriod,\n uint128 maxApprovalValidationPeriod\n ) external;\n\n function initializeMigrationPeriod(\n uint128 defaultMigrationPeriod,\n uint128 minMigrationPeriod,\n uint128 maxMigrationPeriod\n ) external;\n\n function initializeLockPeriod(\n uint128 defaultLockPeriod,\n uint128 minLockPeriod,\n uint128 maxLockPeriod\n ) external;\n\n function initializeRecoveryPeriod(\n uint128 defaultRecoveryPeriod,\n uint128 minRecoveryPeriod,\n uint128 maxRecoveryPeriod\n ) external;\n\n function initializeSecurityWindow(\n uint128 defaultSecurityWindow,\n uint128 minSecurityWindow,\n uint128 maxSecurityWindow\n ) external;\n\n function setAdditionSecurityPeriod(\n address wallet,\n uint128 additionSecurityPeriod\n ) external;\n\n function setRemovalSecurityPeriod(\n address wallet,\n uint128 removalSecurityPeriod\n ) external;\n\n function setSecurityWindow(address wallet, uint128 securityWindow) external;\n\n function setRecoveryPeriod(address wallet, uint128 recoveryPeriod) external;\n\n function setLockPeriod(address wallet, uint128 lockPeriod) external;\n\n function setApprovalValidationPeriod(\n address wallet,\n uint128 approvalValidationPeriod\n ) external;\n\n function setMigrationPeriod(\n address wallet,\n uint128 migrationPeriod\n ) external;\n\n function additionSecurityPeriodOf(\n address wallet\n ) external view returns (uint128);\n\n function removalSecurityPeriodOf(\n address wallet\n ) external view returns (uint128);\n\n function securityWindowOf(address wallet) external view returns (uint128);\n\n function recoveryPeriodOf(address wallet) external view returns (uint128);\n\n function lockPeriodOf(address wallet) external view returns (uint128);\n\n function migrationPeriodOf(address wallet) external view returns (uint128);\n\n function approvalValidationPeriodOf(\n address wallet\n ) external view returns (uint128);\n}\n" + }, + "contracts/infrastructure/RemoteStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IGuardianFacet} from \"../facets/interfaces/IGuardianFacet.sol\";\n\n/**\n * @title Remote Storage\n * @dev Remote storage allows you to associate addresses with an array of addresses on a standalone smart contract.\n * This could be useful when you don't want to use the local diamond storage for some purpose.\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\nabstract contract RemoteStorage {\n struct StorageConfig {\n address[] addresses;\n mapping(address => Info) info;\n }\n\n struct Info {\n bool exists;\n uint128 index;\n }\n\n mapping(address => StorageConfig) internal configs;\n\n event Added(address _address);\n event Removed(address _address);\n\n error RemoteStorage__CallerNotOwner();\n error RemoteStorage__CallerNotGuardianOrOwner();\n error RemoteStorage__AlreadyExists();\n error RemoteStorage__NotFound();\n error RemoteStorage__CallerNotGuardian();\n\n bytes4 constant IS_GUARDIAN_SELECTOR =\n bytes4(keccak256(\"isGuardian(address)\"));\n bytes4 constant GUARDIAN_COUNT = bytes4(keccak256(\"guardianCount()\"));\n\n /**\n * @notice Modifier to only allow the self to call. Reverts otherwise\n */\n modifier onlyWallet(address _wallet) {\n if (msg.sender != _wallet) revert RemoteStorage__CallerNotOwner();\n _;\n }\n\n /**\n * @notice Enfore the callet to be wallet of guardian of the wallet\n * @param _wallet Address of wallet\n */\n function enforceGuardianOrWallet(address _wallet) internal view {\n if (msg.sender == _wallet) return;\n address facetAddress = IDiamondLoupe(_wallet).facetAddress(\n IS_GUARDIAN_SELECTOR\n );\n if (facetAddress != address(0))\n if (IGuardianFacet(_wallet).isGuardian(msg.sender)) return;\n revert RemoteStorage__CallerNotGuardianOrOwner();\n }\n\n /**\n * @notice Enforce the caller to be wallet IF guardians doesn't exists and only guardian when guardians exists\n * @param _wallet Target wallet address to be handled by infrastructure contracts\n */\n function enforceWalletOrGuardianIfExists(address _wallet) internal view {\n address facetAddress;\n if (msg.sender == _wallet) {\n facetAddress = IDiamondLoupe(_wallet).facetAddress(GUARDIAN_COUNT);\n if (facetAddress == address(0)) return;\n uint256 guardianCount = IGuardianFacet(_wallet).guardianCount();\n if (guardianCount != 0) revert RemoteStorage__CallerNotGuardian();\n return;\n }\n facetAddress = IDiamondLoupe(_wallet).facetAddress(\n IS_GUARDIAN_SELECTOR\n );\n if (facetAddress != address(0))\n if (IGuardianFacet(_wallet).isGuardian(msg.sender)) return;\n\n revert RemoteStorage__CallerNotGuardianOrOwner();\n }\n\n /**\n * @notice Add address to storage and reverts if the address already exists.\n * This is an internal function callable from contracts that inherit this abstract contract\n * @param _wallet Address of wallet to add the address\n * @param _address Address to be added to wallet\n */\n function addAddress(address _wallet, address _address) internal {\n StorageConfig storage config = configs[_wallet];\n if (config.info[_address].exists) revert RemoteStorage__AlreadyExists();\n\n config.info[_address].exists = true;\n config.info[_address].index = uint128(config.addresses.length);\n config.addresses.push(_address);\n\n emit Added(_address);\n }\n\n /**\n * @notice Remove address from storage and reverts if the address already exists.\n * This is an internal function callable from contracts that inherit this abstract contract\n * @param _wallet Address of wallet to remove the address\n * @param _address Address to be removed from wallet\n */\n function removeAddress(address _wallet, address _address) internal {\n StorageConfig storage config = configs[_wallet];\n if (!config.info[_address].exists) revert RemoteStorage__NotFound();\n\n address lastAddress = config.addresses[config.addresses.length - 1];\n if (_address != lastAddress) {\n uint128 targetIndex = config.info[_address].index;\n config.addresses[targetIndex] = lastAddress;\n config.info[lastAddress].index = targetIndex;\n }\n config.addresses.pop();\n delete config.info[_address];\n\n emit Removed(_address);\n }\n\n /**\n * @notice Returns the address added to the given wallet\n * @param _wallet Address of wallet to fetch the addresses added to it\n * @return addresses List of addresses added to the wallet\n */\n function getAddresses(\n address _wallet\n ) internal view returns (address[] memory addresses) {\n StorageConfig storage config = configs[_wallet];\n addresses = new address[](config.addresses.length);\n uint addressesLen = config.addresses.length;\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns bool value checking if the address exists in the given wallet address\n * @param _wallet Wallet address to check\n * @param _address Address to fetch if the address if added to given wallet\n * @return exists_ Bool value showing if the address exists in wallet\n */\n function exists(\n address _wallet,\n address _address\n ) internal view returns (bool exists_) {\n exists_ = configs[_wallet].info[_address].exists;\n }\n\n /**\n * @notice Returns the number of addresses added to the wallet\n * @param _wallet Address of wallet to check\n * @return count_ Number of addresses added to wallet\n */\n function count(address _wallet) internal view returns (uint256 count_) {\n count_ = configs[_wallet].addresses.length;\n }\n}\n" + }, + "contracts/infrastructure/SecurityManager.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport {ISecurityManager} from \"./interfaces/ISecurityManager.sol\";\n\n/**\n * @title Security Manager\n * @dev Infrastructure contract to manage security parameters of users\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract SecurityManager is ISecurityManager, Ownable2Step {\n uint128 public minAdditionSecurityPeriod;\n uint128 public maxAdditionSecurityPeriod;\n uint128 private defaultAdditionSecurityPeriod;\n\n uint128 public minRemovalSecurityPeriod;\n uint128 public maxRemovalSecurityPeriod;\n uint128 private defaultRemovalSecurityPeriod;\n\n uint128 public minSecurityWindow;\n uint128 public maxSecurityWindow;\n uint128 private defaultSecurityWindow;\n\n uint128 public minRecoveryPeriod;\n uint128 public maxRecoveryPeriod;\n uint128 private defaultRecoveryPeriod;\n\n uint128 public minLockPeriod;\n uint128 public maxLockPeriod;\n uint128 private defaultLockPeriod;\n\n uint128 public minApprovalValidationPeriod;\n uint128 public maxApprovalValidationPeriod;\n uint128 private defaultApprovalValidationPeriod;\n\n uint128 public minMigrationPeriod;\n uint128 public maxMigrationPeriod;\n uint128 private defaultMigrationPeriod;\n\n bool public _isAdditionSecurityPeriodInitialized;\n bool public _isRemovalSecurityPeriodInitialized;\n bool public _isSecurityWindowInitialized;\n bool public _isRecoveryPeriodInitialized;\n bool public _isLockPeriodInitialized;\n bool public _isApprovalValidationPeriodInitialized;\n bool public _isMigrationPeriodInitialized;\n\n mapping(address => CustomSecurityConfig) securityConfigs;\n\n struct CustomSecurityConfig {\n uint128 additionSecurityPeriod;\n uint128 removalSecurityPeriod;\n uint128 securityWindow;\n uint128 recoveryPeriod;\n uint128 lockPeriod;\n uint128 approvalValidationPeriod;\n uint128 migrationPeriod;\n }\n\n /**\n * @notice Modifier to only allow wallet itself to make a call to wallet\n */\n modifier onlyWallet(address _wallet) {\n if (msg.sender != _wallet) revert SecurityManager__CallerNotWallet();\n _;\n }\n\n /**\n * @notice Modifier to revert if the variable is already initialized\n */\n modifier initializer(bool _isInitialized) {\n if (_isInitialized) revert SecurityManager__AlreadyIntialized();\n _;\n }\n\n /**\n * @notice Transfers the ownership of the contract to the given owner\n * @param _owner Address of owner who has access to initialize the default security variables for security manager\n */\n constructor(address _owner) {\n transferOwnership(_owner);\n _transferOwnership(_owner);\n }\n\n /**\n * @notice Sets the initial default/min/max addition security period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultAdditionSecurityPeriod Default Addition Security Period for all Barz contracts\n * @param _minAdditionSecurityPeriod Minimum Addition Security Period for all Barz contracts\n * @param _maxAdditionSecurityPeriod Maximum Addition Security Period for all Barz contracts\n */\n function initializeAdditionSecurityPeriod(\n uint128 _defaultAdditionSecurityPeriod,\n uint128 _minAdditionSecurityPeriod,\n uint128 _maxAdditionSecurityPeriod\n )\n external\n override\n onlyOwner\n initializer(_isAdditionSecurityPeriodInitialized)\n {\n _isAdditionSecurityPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultAdditionSecurityPeriod,\n _minAdditionSecurityPeriod,\n _maxAdditionSecurityPeriod\n );\n defaultAdditionSecurityPeriod = _defaultAdditionSecurityPeriod;\n minAdditionSecurityPeriod = _minAdditionSecurityPeriod;\n maxAdditionSecurityPeriod = _maxAdditionSecurityPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max removal security period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultRemovalSecurityPeriod Default Removal Security Period for all Barz contracts\n * @param _minRemovalSecurityPeriod Minimum Removal Security Period for all Barz contracts\n * @param _maxRemovalSecurityPeriod Maximum Removal Security Period for all Barz contracts\n */\n function initializeRemovalSecurityPeriod(\n uint128 _defaultRemovalSecurityPeriod,\n uint128 _minRemovalSecurityPeriod,\n uint128 _maxRemovalSecurityPeriod\n )\n external\n override\n onlyOwner\n initializer(_isRemovalSecurityPeriodInitialized)\n {\n _isRemovalSecurityPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultRemovalSecurityPeriod,\n _minRemovalSecurityPeriod,\n _maxRemovalSecurityPeriod\n );\n defaultRemovalSecurityPeriod = _defaultRemovalSecurityPeriod;\n minRemovalSecurityPeriod = _minRemovalSecurityPeriod;\n maxRemovalSecurityPeriod = _maxRemovalSecurityPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/maxd security window for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultSecurityWindow Default Security Window for all Barz contracts\n * @param _minSecurityWindow Minimum Security Window for all Barz contracts\n * @param _maxSecurityWindow Maximum Security Window for all Barz contracts\n */\n function initializeSecurityWindow(\n uint128 _defaultSecurityWindow,\n uint128 _minSecurityWindow,\n uint128 _maxSecurityWindow\n ) external override onlyOwner initializer(_isSecurityWindowInitialized) {\n _isSecurityWindowInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultSecurityWindow,\n _minSecurityWindow,\n _maxSecurityWindow\n );\n defaultSecurityWindow = _defaultSecurityWindow;\n minSecurityWindow = _minSecurityWindow;\n maxSecurityWindow = _maxSecurityWindow;\n }\n\n /**\n * @notice Sets the initial default/min/max recovery period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultRecoveryPeriod Default Recovery Period for all Barz contracts\n * @param _minRecoveryPeriod Minimum Recovery Period for all Barz contracts\n * @param _maxRecoveryPeriod Maximum Recovery Period for all Barz contracts\n */\n function initializeRecoveryPeriod(\n uint128 _defaultRecoveryPeriod,\n uint128 _minRecoveryPeriod,\n uint128 _maxRecoveryPeriod\n ) external override onlyOwner initializer(_isRecoveryPeriodInitialized) {\n _isRecoveryPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultRecoveryPeriod,\n _minRecoveryPeriod,\n _maxRecoveryPeriod\n );\n defaultRecoveryPeriod = _defaultRecoveryPeriod;\n minRecoveryPeriod = _minRecoveryPeriod;\n maxRecoveryPeriod = _maxRecoveryPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max lock period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultLockPeriod Default Lock Period for all Barz contracts\n * @param _minLockPeriod Minimum Lock Period for all Barz contracts\n * @param _maxLockPeriod Maximum Lock Period for all Barz contracts\n */\n function initializeLockPeriod(\n uint128 _defaultLockPeriod,\n uint128 _minLockPeriod,\n uint128 _maxLockPeriod\n ) external override onlyOwner initializer(_isLockPeriodInitialized) {\n _isLockPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultLockPeriod,\n _minLockPeriod,\n _maxLockPeriod\n );\n defaultLockPeriod = _defaultLockPeriod;\n minLockPeriod = _minLockPeriod;\n maxLockPeriod = _maxLockPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max approval validation period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultApprovalValidationPeriod Default Approval Validation Period for all Barz contracts\n * @param _minApprovalValidationPeriod Minimum Approval Validation Period for all Barz contracts\n * @param _maxApprovalValidationPeriod Maximum Approval Validation Period for all Barz contracts\n */\n function initializeApprovalValidationPeriod(\n uint128 _defaultApprovalValidationPeriod,\n uint128 _minApprovalValidationPeriod,\n uint128 _maxApprovalValidationPeriod\n )\n external\n override\n onlyOwner\n initializer(_isApprovalValidationPeriodInitialized)\n {\n _isApprovalValidationPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultApprovalValidationPeriod,\n _minApprovalValidationPeriod,\n _maxApprovalValidationPeriod\n );\n defaultApprovalValidationPeriod = _defaultApprovalValidationPeriod;\n minApprovalValidationPeriod = _minApprovalValidationPeriod;\n maxApprovalValidationPeriod = _maxApprovalValidationPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max migration period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultMigrationPeriod Default Migration Period for all Barz contracts\n * @param _minMigrationPeriod Minimum Migration Period for all Barz contracts\n * @param _maxMigrationPeriod Maximum Migration Period for all Barz contracts\n */\n function initializeMigrationPeriod(\n uint128 _defaultMigrationPeriod,\n uint128 _minMigrationPeriod,\n uint128 _maxMigrationPeriod\n ) external override onlyOwner initializer(_isMigrationPeriodInitialized) {\n _isMigrationPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultMigrationPeriod,\n _minMigrationPeriod,\n _maxMigrationPeriod\n );\n defaultMigrationPeriod = _defaultMigrationPeriod;\n minMigrationPeriod = _minMigrationPeriod;\n maxMigrationPeriod = _maxMigrationPeriod;\n }\n\n /**\n * @notice Wallet owner sets the addition security period for the wallet. Only the owner of wallet can call this function.\n * The addition security period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _additionSecurityPeriod Custom Addition Security Period for the wallet\n */\n function setAdditionSecurityPeriod(\n address _wallet,\n uint128 _additionSecurityPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _additionSecurityPeriod,\n minAdditionSecurityPeriod,\n maxAdditionSecurityPeriod\n );\n securityConfigs[_wallet]\n .additionSecurityPeriod = _additionSecurityPeriod;\n }\n\n /**\n * @notice Wallet owner sets the removal security period for the wallet. Only the owner of wallet can call this function.\n * The removal security period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _removalSecurityPeriod Custom Removal Security Period for the wallet\n */\n function setRemovalSecurityPeriod(\n address _wallet,\n uint128 _removalSecurityPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _removalSecurityPeriod,\n minRemovalSecurityPeriod,\n maxRemovalSecurityPeriod\n );\n securityConfigs[_wallet].removalSecurityPeriod = _removalSecurityPeriod;\n }\n\n /**\n * @notice Wallet owner sets the security window for the wallet. Only the owner of wallet can call this function.\n * The security window should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _securityWindow Custom Security Window for the wallet\n */\n function setSecurityWindow(\n address _wallet,\n uint128 _securityWindow\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _securityWindow,\n minSecurityWindow,\n maxSecurityWindow\n );\n securityConfigs[_wallet].securityWindow = _securityWindow;\n }\n\n /**\n * @notice Wallet owner sets the recovery period for the wallet. Only the owner of wallet can call this function.\n * The recovery period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _recoveryPeriod Custom recovery period for the wallet\n */\n function setRecoveryPeriod(\n address _wallet,\n uint128 _recoveryPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _recoveryPeriod,\n minRecoveryPeriod,\n maxRecoveryPeriod\n );\n securityConfigs[_wallet].recoveryPeriod = _recoveryPeriod;\n }\n\n /**\n * @notice Wallet owner sets the lock period for the wallet. Only the owner of wallet can call this function.\n * The lock period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _lockPeriod Custom Lock period for the wallet\n */\n function setLockPeriod(\n address _wallet,\n uint128 _lockPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(_lockPeriod, minLockPeriod, maxLockPeriod);\n securityConfigs[_wallet].lockPeriod = _lockPeriod;\n }\n\n /**\n * @notice Wallet owner sets the approval validation period for the wallet. Only the owner of wallet can call this function.\n * The approval validation period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _approvalValidationPeriod Custom approval validation period for the wallet\n */\n function setApprovalValidationPeriod(\n address _wallet,\n uint128 _approvalValidationPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _approvalValidationPeriod,\n minApprovalValidationPeriod,\n maxApprovalValidationPeriod\n );\n securityConfigs[_wallet]\n .approvalValidationPeriod = _approvalValidationPeriod;\n }\n\n /**\n * @notice Wallet owner sets the migration period for the wallet. Only the owner of wallet can call this function.\n * The migration period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _migrationPeriod Custom migration period for the wallet\n */\n\n function setMigrationPeriod(\n address _wallet,\n uint128 _migrationPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _migrationPeriod,\n minMigrationPeriod,\n maxMigrationPeriod\n );\n securityConfigs[_wallet].migrationPeriod = _migrationPeriod;\n }\n\n /**\n * @notice Returns the addition security period. Returns default value when custom addition security period is not set\n * @param _wallet Address of wallet\n * @return additionSecurityPeriod Addition Security Period of the given Barz account or wallet\n */\n function additionSecurityPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 additionSecurityPeriod)\n {\n additionSecurityPeriod = securityConfigs[_wallet]\n .additionSecurityPeriod;\n additionSecurityPeriod = (additionSecurityPeriod == 0)\n ? defaultAdditionSecurityPeriod\n : additionSecurityPeriod;\n }\n\n /**\n * @notice Returns the removal security period. Returns default value when custom removal security period is not set\n * @param _wallet Address of wallet\n * @return removalSecurityPeriod Removal Security Period of the given Barz account or wallet\n */\n function removalSecurityPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 removalSecurityPeriod)\n {\n removalSecurityPeriod = securityConfigs[_wallet].removalSecurityPeriod;\n removalSecurityPeriod = (removalSecurityPeriod == 0)\n ? defaultRemovalSecurityPeriod\n : removalSecurityPeriod;\n }\n\n /**\n * @notice Returns the security window. Returns default value when custom security window is not set\n * @param _wallet Address of wallet\n * @return securityWindow Security window of the given Barz account or wallet\n */\n function securityWindowOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 securityWindow)\n {\n securityWindow = securityConfigs[_wallet].securityWindow;\n securityWindow = (securityWindow == 0)\n ? defaultSecurityWindow\n : securityWindow;\n }\n\n /**\n * @notice Returns the recovery period. Returns default value when custom recovery period is not set\n * @param _wallet Address of wallet\n * @return recoveryPeriod Recovery Period of the given Barz account or wallet\n */\n function recoveryPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 recoveryPeriod)\n {\n recoveryPeriod = securityConfigs[_wallet].recoveryPeriod;\n recoveryPeriod = (recoveryPeriod == 0)\n ? defaultRecoveryPeriod\n : recoveryPeriod;\n }\n\n /**\n * @notice Returns the lock period. Returns default value when custom lock period is not set\n * @param _wallet Address of wallet\n * @return lockPeriod Lock Period of the given Barz account or wallet\n */\n function lockPeriodOf(\n address _wallet\n ) public view override onlyWallet(_wallet) returns (uint128 lockPeriod) {\n lockPeriod = securityConfigs[_wallet].lockPeriod;\n lockPeriod = (lockPeriod == 0) ? defaultLockPeriod : lockPeriod;\n }\n\n /**\n * @notice Returns the approval validation period. Returns default value when custom approval validation period is not set\n * @param _wallet Address of wallet\n * @return approvalValidationPeriod Approval Validation Period of the given Barz account or wallet\n */\n function approvalValidationPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityConfigs[_wallet]\n .approvalValidationPeriod;\n approvalValidationPeriod = (approvalValidationPeriod == 0)\n ? defaultApprovalValidationPeriod\n : approvalValidationPeriod;\n }\n\n /**\n * @notice Returns the migration period. Returns default value when custom migration period is not set\n * @param _wallet Address of wallet\n * @return migrationPeriod Migration Period of the given Barz account or wallet\n */\n function migrationPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 migrationPeriod)\n {\n migrationPeriod = securityConfigs[_wallet].migrationPeriod;\n migrationPeriod = (migrationPeriod == 0)\n ? defaultMigrationPeriod\n : migrationPeriod;\n }\n\n /**\n * @notice Validates if the period is smaller than the max period or bigger than the min period\n * @param _period Period to be checked\n * @param _minPeriod Minimum period\n * @param _maxPeriod Maximum period\n */\n function _validatePeriodBoundaries(\n uint128 _period,\n uint128 _minPeriod,\n uint128 _maxPeriod\n ) internal pure {\n if (_period >= _maxPeriod || _period <= _minPeriod)\n revert SecurityManager__OutOfBoundary();\n }\n}\n" + }, + "contracts/infrastructure/WhitelistStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {RemoteStorage} from \"./RemoteStorage.sol\";\n\n/**\n * @title Whitelist storage\n * @dev Maps addresses to the corresponsing array of whitelisted addresses for each of them.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract WhitelistStorage is RemoteStorage {\n /**\n * @dev Add the address to the whitelist storage\n * @param _wallet User wallet\n * @param _address Address to be whitelisted\n */\n function whitelistAddress(address _wallet, address _address) external {\n enforceWalletOrGuardianIfExists(_wallet);\n addAddress(_wallet, _address);\n }\n\n /**\n * @dev Removes the address from the whitelist storage\n * @param _wallet User wallet\n * @param _address Address to be removed from the whitelist\n */\n function blacklistAddress(address _wallet, address _address) external {\n enforceGuardianOrWallet(_wallet);\n removeAddress(_wallet, _address);\n }\n\n /**\n * @dev Returns whether the address exists in the whitelist storage, associated with the wallet\n * @param _wallet User wallet\n * @param _address Address to be whitelisted\n */\n function isWhitelisted(\n address _wallet,\n address _address\n ) external view returns (bool) {\n return exists(_wallet, _address);\n }\n\n /**\n * @dev Returns all whitelisted addresses associated with the wallet\n * @param _wallet User wallet\n */\n function getWhitelistedAddresses(\n address _wallet\n ) external view returns (address[] memory) {\n return getAddresses(_wallet);\n }\n}\n" + }, + "contracts/interfaces/ERC/IERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\n\npragma solidity 0.8.21;\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155Receiver {\n /**\n * @dev Handles the receipt of a single ERC1155 token type. This function is\n * called at the end of a `safeTransferFrom` after the balance has been updated.\n *\n * NOTE: To accept the transfer, this must return\n * `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n * (i.e. 0xf23a6e61, or its own function selector).\n *\n * @param operator The address which initiated the transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param id The ID of the token being transferred\n * @param value The amount of tokens being transferred\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n ) external returns (bytes4);\n\n /**\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\n * is called at the end of a `safeBatchTransferFrom` after the balances have\n * been updated.\n *\n * NOTE: To accept the transfer(s), this must return\n * `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n * (i.e. 0xbc197c81, or its own function selector).\n *\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "contracts/interfaces/ERC/IERC1271.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\ninterface IERC1271 {\n function isValidSignature(\n bytes32 hash,\n bytes memory signature\n ) external view returns (bytes4);\n}\n" + }, + "contracts/interfaces/ERC/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\ninterface IERC165 {\n /// @notice Query if a contract implements an interface\n /// @param interfaceId The interface identifier, as specified in ERC-165\n /// @dev Interface identification is specified in ERC-165. This function\n /// uses less than 30,000 gas.\n /// @return `true` if the contract implements `interfaceID` and\n /// `interfaceID` is not 0xffffffff, `false` otherwise\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/IERC173.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\n/// @title ERC-173 Contract Ownership Standard\n/// Note: the ERC-165 identifier for this interface is 0x7f5828d0\n/* is ERC165 */\ninterface IERC173 {\n /// @dev This emits when ownership of a contract changes.\n event OwnershipTransferred(\n address indexed previousOwner,\n address indexed newOwner\n );\n\n /// @notice Get the address of the owner\n /// @return owner_ The address of the owner.\n function owner() external view returns (address owner_);\n\n /// @notice Set the address of the new owner of the contract\n /// @dev Set _newOwner to address(0) to renounce any ownership.\n /// @param _newOwner The address of the new owner of the contract\n function transferOwnership(address _newOwner) external;\n}\n" + }, + "contracts/interfaces/ERC/IERC677Receiver.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\ninterface IERC677Receiver {\n function onTokenTransfer(\n address sender,\n uint value,\n bytes calldata data\n ) external pure returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155 is IERC165 {\n /**\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n */\n event TransferSingle(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256 id,\n uint256 value\n );\n\n /**\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n * transfers.\n */\n event TransferBatch(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\n\n /**\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n * `approved`.\n */\n event ApprovalForAll(\n address indexed account,\n address indexed operator,\n bool approved\n );\n\n /**\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n *\n * If an {URI} event was emitted for `id`, the standard\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n * returned by {IERC1155MetadataURI-uri}.\n */\n event URI(string value, uint256 indexed id);\n\n /**\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(\n address account,\n uint256 id\n ) external view returns (uint256);\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] calldata accounts,\n uint256[] calldata ids\n ) external view returns (uint256[] memory);\n\n /**\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n *\n * Emits an {ApprovalForAll} event.\n *\n * Requirements:\n *\n * - `operator` cannot be the caller.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n *\n * See {setApprovalForAll}.\n */\n function isApprovedForAll(\n address account,\n address operator\n ) external view returns (bool);\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes calldata data\n ) external;\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(\n address indexed owner,\n address indexed spender,\n uint256 value\n );\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` 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 amount) 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(\n address owner,\n address spender\n ) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the 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 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` 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(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(\n address spender,\n uint256 addedValue\n ) external returns (bool);\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(\n address spender,\n uint256 subtractedValue\n ) external returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(\n address indexed from,\n address indexed to,\n uint256 indexed tokenId\n );\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(\n address indexed owner,\n address indexed approved,\n uint256 indexed tokenId\n );\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(\n address indexed owner,\n address indexed operator,\n bool approved\n );\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(\n uint256 tokenId\n ) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(\n address owner,\n address operator\n ) external view returns (bool);\n}\n" + }, + "contracts/interfaces/IBarz.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Barz Interface\n * @dev Interface of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IBarz {\n error Barz__InitializationFailure();\n}\n" + }, + "contracts/interfaces/IBarzFactory.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Barz} from \"../Barz.sol\";\n\n/**\n * @title Barz Factory Interface\n * @dev Interface of contract to easily deploy Barz to a pre-computed address with a single call\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IBarzFactory {\n function createAccount(\n address verificationFacet,\n bytes calldata owner,\n uint256 salt\n ) external returns (Barz);\n\n function getAddress(\n address verificationFacet,\n bytes calldata owner,\n uint256 salt\n ) external view returns (address);\n\n function getBytecode(\n address accountFacet,\n address verificationFacet,\n address entryPoint,\n address facetRegistry,\n address defaultFallback,\n bytes memory ownerPublicKey\n ) external pure returns (bytes memory);\n\n function getCreationCode() external pure returns (bytes memory);\n}\n" + }, + "contracts/libraries/DefaultLibDiamond.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\n\nerror InitializationFunctionReverted(\n address _initializationContractAddress,\n bytes _calldata\n);\n\nlibrary DefaultLibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION =\n keccak256(\"trustwallet.barz.diamond.storage\");\n\n struct FacetAddressAndPosition {\n address facetAddress;\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\n }\n\n struct FacetFunctionSelectors {\n bytes4[] functionSelectors;\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\n }\n\n struct DiamondStorage {\n // maps function selector to the facet address and\n // the position of the selector in the facetFunctionSelectors.selectors array\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\n // maps facet addresses to function selectors\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\n // facet addresses\n address[] facetAddresses;\n // Used to query if a contract implements an interface.\n // Used to implement ERC-165.\n mapping(bytes4 => bool) supportedInterfaces;\n }\n\n function diamondStorage()\n internal\n pure\n returns (DiamondStorage storage ds)\n {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n event DiamondCut(\n IDiamondCut.FacetCut[] _diamondCut,\n address _init,\n bytes _calldata\n );\n\n // Internal function version of diamondCut\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n for (\n uint256 facetIndex;\n facetIndex < _diamondCut.length;\n facetIndex++\n ) {\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\n if (action == IDiamondCut.FacetCutAction.Add) {\n addFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\n replaceFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\n removeFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else {\n revert(\"LibDiamondCut: Incorrect FacetCutAction\");\n }\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Add facet can't be address(0)\"\n );\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n require(\n oldFacetAddress == address(0),\n \"LibDiamondCut: Can't add function that already exists\"\n );\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function replaceFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Replace facet can't be address(0)\"\n );\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n require(\n oldFacetAddress != _facetAddress,\n \"LibDiamondCut: Can't replace function with same facet\"\n );\n removeFunction(ds, oldFacetAddress, selector);\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function removeFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n // if function does not exist then do nothing and return\n require(\n _facetAddress == address(0),\n \"LibDiamondCut: Remove facet address must be address(0)\"\n );\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n removeFunction(ds, oldFacetAddress, selector);\n }\n }\n\n function addFacet(\n DiamondStorage storage ds,\n address _facetAddress\n ) internal {\n enforceHasContractCode(\n _facetAddress,\n \"LibDiamondCut: New facet has no code\"\n );\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds\n .facetAddresses\n .length;\n ds.facetAddresses.push(_facetAddress);\n }\n\n function addFunction(\n DiamondStorage storage ds,\n bytes4 _selector,\n uint96 _selectorPosition,\n address _facetAddress\n ) internal {\n ds\n .selectorToFacetAndPosition[_selector]\n .functionSelectorPosition = _selectorPosition;\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(\n _selector\n );\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\n }\n\n function removeFunction(\n DiamondStorage storage ds,\n address _facetAddress,\n bytes4 _selector\n ) internal {\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Can't remove function that doesn't exist\"\n );\n // an immutable function is a function defined directly in a diamond\n require(\n _facetAddress != address(this),\n \"LibDiamondCut: Can't remove immutable function\"\n );\n // replace selector with last selector, then delete last selector\n uint256 selectorPosition = ds\n .selectorToFacetAndPosition[_selector]\n .functionSelectorPosition;\n uint256 lastSelectorPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors\n .length - 1;\n // if not the same then replace _selector with lastSelector\n if (selectorPosition != lastSelectorPosition) {\n bytes4 lastSelector = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors[lastSelectorPosition];\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[\n selectorPosition\n ] = lastSelector;\n ds\n .selectorToFacetAndPosition[lastSelector]\n .functionSelectorPosition = uint96(selectorPosition);\n }\n // delete the last selector\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\n delete ds.selectorToFacetAndPosition[_selector];\n\n // if no more selectors for facet address then delete the facet address\n if (lastSelectorPosition == 0) {\n // replace facet address with last facet address and delete last facet address\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\n uint256 facetAddressPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .facetAddressPosition;\n if (facetAddressPosition != lastFacetAddressPosition) {\n address lastFacetAddress = ds.facetAddresses[\n lastFacetAddressPosition\n ];\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\n ds\n .facetFunctionSelectors[lastFacetAddress]\n .facetAddressPosition = facetAddressPosition;\n }\n ds.facetAddresses.pop();\n delete ds\n .facetFunctionSelectors[_facetAddress]\n .facetAddressPosition;\n }\n }\n\n function initializeDiamondCut(\n address _init,\n bytes memory _calldata\n ) internal {\n if (_init == address(0)) {\n return;\n }\n enforceHasContractCode(\n _init,\n \"LibDiamondCut: _init address has no code\"\n );\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length > 0) {\n // bubble up error\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(error)\n revert(add(32, error), returndata_size)\n }\n } else {\n revert InitializationFunctionReverted(_init, _calldata);\n }\n }\n }\n\n function enforceHasContractCode(\n address _contract,\n string memory _errorMessage\n ) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize > 0, _errorMessage);\n }\n}\n" + }, + "contracts/libraries/LibAppStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SafeCast} from \"@openzeppelin/contracts/utils/math/SafeCast.sol\";\nimport {IEntryPoint} from \"../aa-4337/interfaces/IEntryPoint.sol\";\nimport {IFacetRegistry} from \"../infrastructure/interfaces/IFacetRegistry.sol\";\n\n/*\n * @title App Storage\n * @dev App storage for Barz contract to prevent storage collision\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\n\nstruct Lock {\n uint64 release;\n bytes4 locker;\n}\n\nstruct InitializersStorage {\n // NOTE: initialized is a variable to make sure the initialization is only done once.\n uint8 signerInitialized;\n uint8 accountInitialized;\n uint8 restrictionsInitialized;\n}\n\nstruct AppStorage {\n mapping(uint256 => InitializersStorage) initStorage;\n uint8 signerMigration;\n bytes4 validateOwnerSignatureSelector;\n IEntryPoint entryPoint;\n IFacetRegistry facetRegistry;\n mapping(uint256 => Lock) locks;\n}\n\nlibrary LibAppStorage {\n error LibAppStorage__AccountAlreadyUninitialized();\n error LibAppStorage__AccountMustBeUninitialized();\n error LibAppStorage__SignerAlreadyUninitialized();\n error LibAppStorage__SignerMustBeUninitialized();\n\n function appStorage() internal pure returns (AppStorage storage ds) {\n assembly {\n ds.slot := 0\n }\n }\n\n function setSignerUninitialized() internal {\n AppStorage storage s = appStorage();\n if (1 != s.initStorage[0].signerInitialized) {\n revert LibAppStorage__SignerAlreadyUninitialized();\n }\n s.initStorage[0].signerInitialized = 0;\n }\n\n function getValidateOwnerSignatureSelector()\n internal\n view\n returns (bytes4 selector)\n {\n selector = appStorage().validateOwnerSignatureSelector;\n }\n\n function setValidateOwnerSignatureSelector(\n bytes4 _validateOwnerSignatureSelector\n ) internal {\n appStorage()\n .validateOwnerSignatureSelector = _validateOwnerSignatureSelector;\n }\n\n function enforceSignerInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].signerInitialized) {\n revert LibAppStorage__SignerMustBeUninitialized();\n }\n s.initStorage[0].signerInitialized = 1;\n }\n\n function enforceAccountInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].accountInitialized) {\n revert LibAppStorage__AccountMustBeUninitialized();\n }\n s.initStorage[0].accountInitialized = 1;\n }\n\n function initiateSignerMigration() internal {\n appStorage().signerMigration = 1;\n }\n\n function enforceSignerMigration() internal view {\n if (1 != appStorage().signerMigration) {\n revert LibAppStorage__AccountMustBeUninitialized();\n }\n }\n\n function finalizeSignerMigration() internal {\n appStorage().signerMigration = 0;\n }\n\n function setLock(uint256 _releaseAfter, bytes4 _locker) internal {\n appStorage().locks[0] = Lock(SafeCast.toUint64(_releaseAfter), _locker);\n }\n\n function enforceRestrictionsInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].restrictionsInitialized)\n revert LibAppStorage__SignerMustBeUninitialized();\n s.initStorage[0].restrictionsInitialized = 1;\n }\n\n function setRestrictionsUninitialized() internal {\n AppStorage storage s = appStorage();\n if (1 != s.initStorage[0].restrictionsInitialized)\n revert LibAppStorage__AccountAlreadyUninitialized();\n s.initStorage[0].restrictionsInitialized = 0;\n }\n}\n\ncontract BarzStorage {\n AppStorage internal s;\n modifier onlyWhenUnlocked() {\n require(\n uint64(block.timestamp) >= s.locks[0].release,\n \"Account Locked\"\n );\n _;\n }\n modifier onlyWhenLocked() {\n require(\n uint64(block.timestamp) < s.locks[0].release,\n \"Account Unlocked\"\n );\n _;\n }\n}\n" + }, + "contracts/libraries/LibDiamond.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\n\nerror InitializationFunctionReverted(\n address _initializationContractAddress,\n bytes _calldata\n);\n\nlibrary LibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION =\n keccak256(\"trustwallet.barz.diamond.storage\");\n\n struct DiamondStorage {\n // maps function selectors to the facets that execute the functions.\n // and maps the selectors to their position in the selectorSlots array.\n // func selector => address facet, selector position\n mapping(bytes4 => bytes32) facets;\n // array of slots of function selectors.\n // each slot holds 8 function selectors.\n mapping(uint256 => bytes32) selectorSlots;\n // The number of function selectors in selectorSlots\n uint16 selectorCount;\n // Used to query if a contract implements an interface.\n // Used to implement ERC-165.\n mapping(bytes4 => bool) supportedInterfaces;\n // Default Fallback Handler of the barz.\n IDiamondLoupe defaultFallbackHandler;\n }\n\n function diamondStorage()\n internal\n pure\n returns (DiamondStorage storage ds)\n {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n function enforceIsSelf() internal view {\n require(msg.sender == address(this), \"LibDiamond: Caller not self\");\n }\n\n event DiamondCut(\n IDiamondCut.FacetCut[] _diamondCut,\n address _init,\n bytes _calldata\n );\n\n bytes32 constant CLEAR_ADDRESS_MASK =\n bytes32(uint256(0xffffffffffffffffffffffff));\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\n\n // Internal function version of diamondCut\n // This code is almost the same as the external diamondCut,\n // except it is using 'Facet[] memory _diamondCut' instead of\n // 'Facet[] calldata _diamondCut'.\n // The code is duplicated to prevent copying calldata to memory which\n // causes an error for a two dimensional array.\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n DiamondStorage storage ds = diamondStorage();\n uint256 originalSelectorCount = ds.selectorCount;\n uint256 selectorCount = originalSelectorCount;\n bytes32 selectorSlot;\n // Check if last selector slot is not full\n // \"selectorCount & 7\" is a gas efficient modulo by eight \"selectorCount % 8\"\n if (selectorCount & 7 > 0) {\n // get last selectorSlot\n // \"selectorSlot >> 3\" is a gas efficient division by 8 \"selectorSlot / 8\"\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\n }\n // loop through diamond cut\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\n selectorCount,\n selectorSlot,\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].action,\n _diamondCut[facetIndex].functionSelectors\n );\n\n unchecked {\n facetIndex++;\n }\n }\n if (selectorCount != originalSelectorCount) {\n ds.selectorCount = uint16(selectorCount);\n }\n // If last selector slot is not full\n // \"selectorCount & 7\" is a gas efficient modulo by eight \"selectorCount % 8\"\n if (selectorCount & 7 > 0) {\n // \"selectorSlot >> 3\" is a gas efficient division by 8 \"selectorSlot / 8\"\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addReplaceRemoveFacetSelectors(\n uint256 _selectorCount,\n bytes32 _selectorSlot,\n address _newFacetAddress,\n IDiamondCut.FacetCutAction _action,\n bytes4[] memory _selectors\n ) internal returns (uint256, bytes32) {\n DiamondStorage storage ds = diamondStorage();\n require(\n _selectors.length > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n if (_action == IDiamondCut.FacetCutAction.Add) {\n enforceHasContractCode(\n _newFacetAddress,\n \"LibDiamondCut: Add facet has no code\"\n );\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n require(\n address(bytes20(oldFacet)) == address(0),\n \"LibDiamondCut: Can't add function that already exists\"\n );\n // add facet for selector\n ds.facets[selector] =\n bytes20(_newFacetAddress) |\n bytes32(_selectorCount);\n // \"_selectorCount & 7\" is a gas efficient modulo by eight \"_selectorCount % 8\"\n // \" << 5 is the same as multiplying by 32 ( * 32)\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\n // clear selector position in slot and add selector\n _selectorSlot =\n (_selectorSlot &\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\n (bytes32(selector) >> selectorInSlotPosition);\n // if slot is full then write it to storage\n if (selectorInSlotPosition == 224) {\n // \"_selectorSlot >> 3\" is a gas efficient division by 8 \"_selectorSlot / 8\"\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\n _selectorSlot = 0;\n }\n _selectorCount++;\n\n unchecked {\n selectorIndex++;\n }\n }\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\n enforceHasContractCode(\n _newFacetAddress,\n \"LibDiamondCut: Replace facet has no code\"\n );\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n address oldFacetAddress = address(bytes20(oldFacet));\n // only useful if immutable functions exist\n require(\n oldFacetAddress != address(this),\n \"LibDiamondCut: Can't replace immutable function\"\n );\n require(\n oldFacetAddress != _newFacetAddress,\n \"LibDiamondCut: Can't replace function with same function\"\n );\n require(\n oldFacetAddress != address(0),\n \"LibDiamondCut: Can't replace function that doesn't exist\"\n );\n // replace old facet address\n ds.facets[selector] =\n (oldFacet & CLEAR_ADDRESS_MASK) |\n bytes20(_newFacetAddress);\n\n unchecked {\n selectorIndex++;\n }\n }\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\n require(\n _newFacetAddress == address(0),\n \"LibDiamondCut: Remove facet address must be address(0)\"\n );\n // \"_selectorCount >> 3\" is a gas efficient division by 8 \"_selectorCount / 8\"\n uint256 selectorSlotCount = _selectorCount >> 3;\n // \"_selectorCount & 7\" is a gas efficient modulo by eight \"_selectorCount % 8\"\n uint256 selectorInSlotIndex = _selectorCount & 7;\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n if (_selectorSlot == 0) {\n // get last selectorSlot\n selectorSlotCount--;\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\n selectorInSlotIndex = 7;\n } else {\n selectorInSlotIndex--;\n }\n bytes4 lastSelector;\n uint256 oldSelectorsSlotCount;\n uint256 oldSelectorInSlotPosition;\n // adding a block here prevents stack too deep error\n {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n require(\n address(bytes20(oldFacet)) != address(0),\n \"LibDiamondCut: Can't remove function that doesn't exist\"\n );\n // only useful if immutable functions exist\n require(\n address(bytes20(oldFacet)) != address(this),\n \"LibDiamondCut: Can't remove immutable function\"\n );\n // replace selector with last selector in ds.facets\n // gets the last selector\n // \" << 5 is the same as multiplying by 32 ( * 32)\n lastSelector = bytes4(\n _selectorSlot << (selectorInSlotIndex << 5)\n );\n if (lastSelector != selector) {\n // update last selector slot position info\n ds.facets[lastSelector] =\n (oldFacet & CLEAR_ADDRESS_MASK) |\n bytes20(ds.facets[lastSelector]);\n }\n delete ds.facets[selector];\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\n // \"oldSelectorCount >> 3\" is a gas efficient division by 8 \"oldSelectorCount / 8\"\n oldSelectorsSlotCount = oldSelectorCount >> 3;\n // \"oldSelectorCount & 7\" is a gas efficient modulo by eight \"oldSelectorCount % 8\"\n // \" << 5 is the same as multiplying by 32 ( * 32)\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\n }\n if (oldSelectorsSlotCount != selectorSlotCount) {\n bytes32 oldSelectorSlot = ds.selectorSlots[\n oldSelectorsSlotCount\n ];\n // clears the selector we are deleting and puts the last selector in its place.\n oldSelectorSlot =\n (oldSelectorSlot &\n ~(CLEAR_SELECTOR_MASK >>\n oldSelectorInSlotPosition)) |\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\n // update storage with the modified slot\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\n } else {\n // clears the selector we are deleting and puts the last selector in its place.\n _selectorSlot =\n (_selectorSlot &\n ~(CLEAR_SELECTOR_MASK >>\n oldSelectorInSlotPosition)) |\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\n }\n if (selectorInSlotIndex == 0) {\n delete ds.selectorSlots[selectorSlotCount];\n _selectorSlot = 0;\n }\n\n unchecked {\n selectorIndex++;\n }\n }\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\n } else {\n revert(\"LibDiamondCut: Incorrect FacetCutAction\");\n }\n return (_selectorCount, _selectorSlot);\n }\n\n function initializeDiamondCut(\n address _init,\n bytes memory _calldata\n ) internal {\n if (_init == address(0)) {\n return;\n }\n enforceHasContractCode(\n _init,\n \"LibDiamondCut: _init address has no code\"\n );\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length > 0) {\n // bubble up error\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(error)\n revert(add(32, error), returndata_size)\n }\n } else {\n revert InitializationFunctionReverted(_init, _calldata);\n }\n }\n }\n\n function enforceHasContractCode(\n address _contract,\n string memory _errorMessage\n ) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize > 0, _errorMessage);\n }\n\n function restrictionsFacet() internal view returns (address facetAddress_) {\n bytes4 selector = bytes4(\n keccak256(\"verifyRestrictions(address,address,uint256,bytes)\")\n );\n facetAddress_ = address(\n bytes20(LibDiamond.diamondStorage().facets[selector])\n );\n }\n}\n" + }, + "contracts/libraries/LibFacetStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Storage\n * @dev Storage contract to store each facets variables with diamond storage\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\n\nstruct Secp256k1VerificationStorage {\n address signer;\n}\n\nstruct Secp256r1VerificationStorage {\n uint256[2] q;\n}\n\nstruct GuardianStorage {\n mapping(bytes32 => uint256) pending;\n mapping(uint8 => StorageConfig) configs;\n}\n\nstruct Info {\n bool exists;\n uint128 index;\n}\n\nstruct StorageConfig {\n address[] addresses;\n mapping(address => Info) info;\n}\n\nstruct RecoveryConfig {\n bytes recoveryPublicKey;\n uint64 executeAfter;\n}\n\nstruct ApprovalConfig {\n bool isApproved;\n uint64 validUntil;\n}\n\nstruct RecoveryApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isNewOwnerApproved;\n}\n\nstruct RecoveryStorage {\n mapping(uint8 => RecoveryConfig) recoveryConfigs;\n mapping(uint8 => RecoveryApprovalConfig) recoveryApprovalConfigs;\n uint128 nonce;\n}\n\nstruct RestrictionsStorage {\n address[] restrictions;\n mapping(address => bool) exists;\n}\n\nstruct SignatureMigrationConfig {\n bytes migrationPublicKey;\n address migrationVerificationFacet;\n bytes4[] migrationSelectors;\n uint64 migrateAfter;\n}\n\nstruct SignatureMigrationApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isMigrationApproved;\n}\n\nstruct SignatureMigrationStorage {\n mapping(uint8 => SignatureMigrationConfig) migrationConfigs;\n mapping(uint8 => SignatureMigrationApprovalConfig) migrationApprovalConfigs;\n uint128 nonce;\n}\n\nstruct DiamondCutApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isDiamondCutApproved;\n}\n\nstruct DiamondCutStorage {\n mapping(uint8 => DiamondCutApprovalConfig) diamondCutApprovalConfigs;\n uint128 nonce;\n}\n\nstruct LockStorage {\n uint128 nonce;\n}\n\nlibrary LibFacetStorage {\n function k1Storage()\n internal\n pure\n returns (Secp256k1VerificationStorage storage ds)\n {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.Secp256k1VerificationStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function r1Storage()\n internal\n pure\n returns (Secp256r1VerificationStorage storage ds)\n {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.Secp256r1VerificationStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function guardianStorage()\n internal\n pure\n returns (GuardianStorage storage ds)\n {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.GuardianStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function recoveryStorage()\n internal\n pure\n returns (RecoveryStorage storage ds)\n {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.RecoveryStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function restrictionsStorage()\n internal\n pure\n returns (RestrictionsStorage storage ds)\n {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.RestrictionsStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function migrationStorage()\n internal\n pure\n returns (SignatureMigrationStorage storage ds)\n {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.SignatureMigrationStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function diamondCutStorage()\n internal\n pure\n returns (DiamondCutStorage storage ds)\n {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.DiamondCutStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function lockStorage() internal pure returns (LockStorage storage ds) {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.LockStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n}\n" + }, + "contracts/libraries/LibGuardian.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibFacetStorage, StorageConfig} from \"./LibFacetStorage.sol\";\n\n/**\n * @title LibGuardian\n * @dev Internal Library to provide utility feature for Guardians stored in Guardian Facet Storage\n * @author David Yongjun Kim (@Powerstream3604)\n */\nlibrary LibGuardian {\n function majorityOfGuardians()\n internal\n view\n returns (uint256 guardianNumber)\n {\n uint256 guardianLength = guardianCount();\n guardianNumber = (guardianLength == 0) ? 0 : guardianLength / 2 + 1;\n }\n\n function isGuardian(address _guardian) internal view returns (bool) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n return config.info[_guardian].exists;\n }\n\n function guardianCount() internal view returns (uint256) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n return config.addresses.length;\n }\n\n function getGuardians() internal view returns (address[] memory) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n address[] memory addresses = new address[](config.addresses.length);\n uint256 addressesLen = config.addresses.length;\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n return addresses;\n }\n}\n" + }, + "contracts/libraries/LibLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {LibDiamond} from \"./LibDiamond.sol\";\n\n/**\n * @title LibLoupe\n * @dev Internal Library to provide utility feature for reading the state of diamond facets\n * @author David Yongjun Kim (@Powerstream3604)\n */\nlibrary LibLoupe {\n /// @notice Gets all facets and their selectors.\n /// @return facets_ Facet\n function facets()\n internal\n view\n returns (IDiamondLoupe.Facet[] memory facets_)\n {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facets_ = new IDiamondLoupe.Facet[](ds.selectorCount);\n uint16[] memory numFacetSelectors = new uint16[](ds.selectorCount);\n uint256 numFacets;\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facetAddress_ = address(bytes20(ds.facets[selector]));\n bool continueLoop;\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n if (facets_[facetIndex].facetAddress == facetAddress_) {\n facets_[facetIndex].functionSelectors[\n numFacetSelectors[facetIndex]\n ] = selector;\n // probably will never have more than 256 functions from one facet contract\n require(numFacetSelectors[facetIndex] < 255);\n numFacetSelectors[facetIndex]++;\n continueLoop = true;\n break;\n }\n }\n if (continueLoop) {\n continue;\n }\n facets_[numFacets].facetAddress = facetAddress_;\n facets_[numFacets].functionSelectors = new bytes4[](\n ds.selectorCount\n );\n facets_[numFacets].functionSelectors[0] = selector;\n numFacetSelectors[numFacets] = 1;\n numFacets++;\n }\n }\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n uint256 numSelectors = numFacetSelectors[facetIndex];\n bytes4[] memory selectors = facets_[facetIndex].functionSelectors;\n // setting the number of selectors\n assembly {\n mstore(selectors, numSelectors)\n }\n }\n // setting the number of facets\n assembly {\n mstore(facets_, numFacets)\n }\n }\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n /// @return _facetFunctionSelectors The selectors associated with a facet address.\n function facetFunctionSelectors(\n address _facet\n ) internal view returns (bytes4[] memory _facetFunctionSelectors) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n uint256 numSelectors;\n _facetFunctionSelectors = new bytes4[](ds.selectorCount);\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facet = address(bytes20(ds.facets[selector]));\n if (_facet == facet) {\n _facetFunctionSelectors[numSelectors] = selector;\n numSelectors++;\n }\n }\n }\n // Set the number of selectors in the array\n assembly {\n mstore(_facetFunctionSelectors, numSelectors)\n }\n }\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses()\n internal\n view\n returns (address[] memory facetAddresses_)\n {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facetAddresses_ = new address[](ds.selectorCount);\n uint256 numFacets;\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facetAddress_ = address(bytes20(ds.facets[selector]));\n bool continueLoop;\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n if (facetAddress_ == facetAddresses_[facetIndex]) {\n continueLoop = true;\n break;\n }\n }\n if (continueLoop) {\n continue;\n }\n facetAddresses_[numFacets] = facetAddress_;\n numFacets++;\n }\n }\n // Set the number of facet addresses in the array\n assembly {\n mstore(facetAddresses_, numFacets)\n }\n }\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(\n bytes4 _functionSelector\n ) internal view returns (address facetAddress_) {\n facetAddress_ = address(\n bytes20(LibDiamond.diamondStorage().facets[_functionSelector])\n );\n }\n}\n" + }, + "contracts/libraries/LibMultiSigStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Multi-sig Storage\n * @dev Storage contract for storing Multi-sig Facet variables in diamond storage pattern\n * @author David Yongjun Kim (@Powerstream3604)\n */\n\nstruct MultiSigStorage {\n mapping(address => address) owners;\n mapping(uint256 => mapping(address => mapping(bytes32 => uint256))) approvedHashes;\n uint256 ownerCount;\n uint256 threshold;\n uint256 counter;\n}\n\nlibrary LibMultiSigStorage {\n function multisigStorage()\n internal\n pure\n returns (MultiSigStorage storage ds)\n {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.MultiSigStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n}\n" + }, + "contracts/libraries/LibRecoverSpender.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title RecoverSpender\n * @dev Library to determine the action and spender of calldata\n * @author Ruslan Serebriakov (@rsrbk)\n */\nlibrary LibRecoverSpender {\n // ERC20, ERC721 & ERC1155 transfers & approvals\n bytes4 private constant ERC20_TRANSFER =\n bytes4(keccak256(\"transfer(address,uint256)\"));\n bytes4 private constant ERC20_APPROVE =\n bytes4(keccak256(\"approve(address,uint256)\"));\n bytes4 private constant ERC20_INCREASE_ALLOWANCE =\n bytes4(keccak256(\"increaseAllowance(address,uint256)\"));\n bytes4 private constant ERC20_DECREASE_ALLOWANCE =\n bytes4(keccak256(\"decreaseAllowance(address,uint256)\"));\n bytes4 private constant ERC721_SET_APPROVAL_FOR_ALL =\n bytes4(keccak256(\"setApprovalForAll(address,bool)\"));\n bytes4 private constant ERC721_TRANSFER_FROM =\n bytes4(keccak256(\"transferFrom(address,address,uint256)\"));\n bytes4 private constant ERC721_SAFE_TRANSFER_FROM =\n bytes4(keccak256(\"safeTransferFrom(address,address,uint256)\"));\n bytes4 private constant ERC721_SAFE_TRANSFER_FROM_BYTES =\n bytes4(keccak256(\"safeTransferFrom(address,address,uint256,bytes)\"));\n bytes4 private constant ERC1155_SAFE_TRANSFER_FROM =\n bytes4(\n keccak256(\"safeTransferFrom(address,address,uint256,uint256,bytes)\")\n );\n bytes4 private constant ERC1155_SAFE_BATCH_TRANSFER_FROM =\n bytes4(\n keccak256(\n \"safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)\"\n )\n );\n\n /**\n * @notice Helper method to recover the spender from a contract call.\n * The method returns the contract unless the call is to a standard method of a ERC20/ERC721/ERC1155 token\n * in which case the spender is recovered from the data.\n * @param _to The target contract.\n * @param _data The data payload.\n */\n function _recover(\n address _to,\n bytes memory _data\n ) internal pure returns (address spender) {\n if (_data.length >= 68) {\n bytes4 methodId;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n methodId := mload(add(_data, 0x20))\n }\n if (\n methodId == ERC20_TRANSFER ||\n methodId == ERC20_APPROVE ||\n methodId == ERC20_INCREASE_ALLOWANCE ||\n methodId == ERC20_DECREASE_ALLOWANCE ||\n methodId == ERC721_SET_APPROVAL_FOR_ALL\n ) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n spender := mload(add(_data, 0x24))\n }\n return spender;\n }\n if (\n methodId == ERC721_TRANSFER_FROM ||\n methodId == ERC721_SAFE_TRANSFER_FROM ||\n methodId == ERC721_SAFE_TRANSFER_FROM_BYTES ||\n methodId == ERC1155_SAFE_TRANSFER_FROM ||\n methodId == ERC1155_SAFE_BATCH_TRANSFER_FROM\n ) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n spender := mload(add(_data, 0x44))\n }\n return spender;\n }\n }\n\n spender = _to;\n }\n}\n" + }, + "contracts/libraries/LibUtils.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\n\nlibrary LibUtils {\n // Internal utility functions\n function mergeArrays(\n bytes4[] memory _array1,\n bytes4[] memory _array2\n ) internal pure returns (bytes4[] memory) {\n uint256 length1 = _array1.length;\n uint256 length2 = _array2.length;\n bytes4[] memory mergedArray = new bytes4[](length1 + length2);\n\n for (uint256 i; i < length1; ) {\n mergedArray[i] = _array1[i];\n unchecked {\n ++i;\n }\n }\n\n for (uint256 i; i < length2; ) {\n mergedArray[length1 + i] = _array2[i];\n unchecked {\n ++i;\n }\n }\n\n return mergedArray;\n }\n\n function removeFacetElement(\n IDiamondLoupe.Facet[] memory _facets,\n uint256 _index\n ) internal pure returns (IDiamondLoupe.Facet[] memory) {\n require(_index < _facets.length, \"Invalid index\");\n require(_facets.length != 0, \"Invalid array\");\n\n // Create a new array with a length of `_facets.length - 1`\n IDiamondLoupe.Facet[] memory newArray = new IDiamondLoupe.Facet[](\n _facets.length - 1\n );\n uint256 newArrayLength = newArray.length;\n // Iterate over the original array, skipping the element at the specified `index`\n for (uint256 i; i < newArrayLength; ) {\n if (i < _index) {\n newArray[i] = _facets[i];\n } else {\n newArray[i] = _facets[i + 1];\n }\n unchecked {\n ++i;\n }\n }\n\n return newArray;\n }\n\n function removeElement(\n bytes4[] memory _array,\n uint256 _index\n ) internal pure returns (bytes4[] memory) {\n require(_index < _array.length, \"Invalid index\");\n require(_array.length != 0, \"Invalid array\");\n\n bytes4[] memory newArray = new bytes4[](_array.length - 1);\n uint256 newArrayLength = newArray.length;\n for (uint256 i; i < newArrayLength; ) {\n if (i < _index) {\n newArray[i] = _array[i];\n } else {\n newArray[i] = _array[i + 1];\n }\n unchecked {\n ++i;\n }\n }\n\n return newArray;\n }\n\n function setValue(\n bytes4[] memory _keys,\n address[] memory _values,\n bytes4 _key,\n address _value\n ) internal pure returns (bytes4[] memory, address[] memory) {\n uint256 index = findIndex(_keys, _key);\n uint256 keysLength = _keys.length;\n if (index < keysLength) {\n _values[index] = _value;\n } else {\n // Create new storage arrays\n bytes4[] memory newKeys = new bytes4[](keysLength + 1);\n address[] memory newValues = new address[](_values.length + 1);\n\n // Copy values to the new storage arrays\n for (uint256 i; i < keysLength; ) {\n newKeys[i] = _keys[i];\n newValues[i] = _values[i];\n\n unchecked {\n ++i;\n }\n }\n\n // Add the new key-value pair\n newKeys[keysLength] = _key;\n newValues[_values.length] = _value;\n\n return (newKeys, newValues);\n }\n\n // If the key already exists, return the original arrays\n return (_keys, _values);\n }\n\n function getValue(\n bytes4[] memory _keys,\n address[] memory _values,\n bytes4 _key\n ) internal pure returns (address) {\n uint256 index = findIndex(_keys, _key);\n if (index >= _keys.length) return address(0);\n\n return _values[index];\n }\n\n function findIndex(\n bytes4[] memory _keys,\n bytes4 _key\n ) internal pure returns (uint256) {\n uint256 keysLength = _keys.length;\n for (uint256 i; i < keysLength; ) {\n if (_keys[i] == _key) {\n return i;\n }\n unchecked {\n ++i;\n }\n }\n return keysLength;\n }\n}\n" + }, + "contracts/restrictions/IRestriction.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Interface for restrictions\n * @dev Restriction is a contract which decides whether to approve a certain kind of transaction, based on its internal logic.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface IRestriction {\n /**\n * @dev Based on restriction's internal logic, it should accept or reject a certain transaction.\n * @param from The address of the sender, that will be signing the transaction.\n * @param to The receiving address.\n * @param value Amount of ETH to transfer from sender to recipient.\n * @param _calldata Optional field to include arbitrary data.\n * @return bool value for whether the check is passed\n */\n function check(\n address from,\n address to,\n uint256 value,\n bytes calldata _calldata\n ) external returns (bool);\n}\n" + }, + "contracts/restrictions/WhitelistRestriction.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibRecoverSpender} from \"../libraries/LibRecoverSpender.sol\";\nimport {WhitelistStorage} from \"../infrastructure/WhitelistStorage.sol\";\nimport {IRestriction} from \"./IRestriction.sol\";\n\n/**\n * @title Whitelist Restriction\n * @dev This restriction defines a list of accepted addresses and denies any interaction with addresses outside of it.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract WhitelistRestriction is IRestriction {\n WhitelistStorage public immutable whitelistStorage;\n\n constructor(WhitelistStorage _whitelistStorage) {\n whitelistStorage = _whitelistStorage;\n }\n\n /**\n * @notice Helper method to recover the spender from a contract call.\n * The method returns the contract unless the call is to a standard method of a ERC20/ERC721/ERC1155 token\n * in which case the spender is recovered from the data.\n * @param _to The target contract.\n * @param _data The data payload.\n */\n function recoverSpender(\n address _to,\n bytes memory _data\n ) public pure returns (address spender) {\n return LibRecoverSpender._recover(_to, _data);\n }\n\n /*\n * @dev IRestriction's implementation. It will allow transaction if the sender is whitelisted, or user, or the whitelist storage.\n * @param _from The address of the sender, that will be signing the transaction.\n * @param _to The receiving address.\n * @param _calldata Optional field to include arbitrary data.\n * @return result value for whether the check is passed\n */\n function check(\n address _from,\n address _to,\n uint256 /*_value*/,\n bytes calldata _calldata\n ) external view override returns (bool result) {\n return\n whitelistStorage.isWhitelisted(\n _from,\n LibRecoverSpender._recover(_to, _calldata)\n ) ||\n _to == address(whitelistStorage) ||\n _to == msg.sender;\n }\n}\n" + }, + "contracts/test/Counter.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\ncontract TestCounter {\n int private count = 0;\n\n function incrementCounter() public {\n count += 1;\n }\n\n function decrementCounter() public {\n count -= 1;\n }\n\n function getCount() public view returns (int) {\n return count;\n }\n}\n" + }, + "contracts/test/TestERC1155.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC1155/ERC1155.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\n\ncontract TestERC1155 is ERC1155 {\n using Counters for Counters.Counter;\n\n Counters.Counter private _tokenIds;\n\n constructor() ERC1155(\"\") {}\n\n function mint(address account, uint256 amount) external {\n uint256 tokenId = _getNextTokenId();\n _mint(account, tokenId, amount, \"\");\n }\n\n function mintBatch(\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes memory data\n ) external {\n require(\n ids.length == amounts.length,\n \"TestERC1155: arrays length mismatch\"\n );\n\n _mintBatch(to, ids, amounts, data);\n }\n\n function _getNextTokenId() private returns (uint256) {\n _tokenIds.increment();\n return _tokenIds.current();\n }\n}\n" + }, + "contracts/test/TestERC777.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC777/ERC777.sol\";\n\ncontract TestERC777 is ERC777 {\n constructor(\n address[] memory _operators\n ) ERC777(\"TestERC777\", \"TERC777\", _operators) {}\n\n function mint(address account, uint256 amount) external {\n _mint(account, amount, \"\", \"\");\n }\n}\n" + }, + "contracts/test/TestInvalidSecp256k1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IVerificationFacet} from \"../facets/interfaces/IVerificationFacet.sol\";\nimport {IERC1271} from \"../interfaces/ERC/IERC1271.sol\";\nimport {AppStorage, LibAppStorage, BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {LibFacetStorage, Secp256k1VerificationStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {UserOperation} from \"../aa-4337/interfaces/UserOperation.sol\";\n\n/**\n * @title Test Secp256k1 verification facet\n * @dev Default Ethereum's elliptic curve\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract TestInvalidSecp256k1VerificationFacet is BarzStorage, IERC1271 {\n using ECDSA for bytes32;\n error Secp256k1VerificationFacet__InvalidSignerLength();\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n\n event SignerUninitialized();\n\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n }\n\n // THIS INVALID FACET DOES NOT INCLUDE initializeSigner()\n // THIS FACET IS USED TO TEST WHEN initializeSigner() DOESN'T EXIST IN FACET\n\n function uninitializeSigner() external returns (uint256 uninitSuccess) {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view returns (uint256 validationData) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n return validateSignature(userOp, userOpHash, k1Storage.signer);\n }\n\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n address signer\n ) public pure returns (uint256) {\n bytes32 hash = userOpHash.toEthSignedMessageHash();\n if (signer != hash.recover(userOp.signature)) return 1;\n return 0;\n }\n\n // This is REMOVED for testing purpose\n function validateOwnerSignatureSelector() public pure returns (bytes4) {\n // return this.validateOwnerSignature.selector;\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n function owner() public view returns (bytes memory) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n return abi.encodePacked(k1Storage.signer);\n }\n\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure returns (bool) {\n return (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (_hash.recover(_signature) ==\n LibFacetStorage.k1Storage().signer)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n}\n" + }, + "contracts/test/TestNFT.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\n\ncontract TestNFT is ERC721 {\n using Counters for Counters.Counter;\n Counters.Counter private currentTokenId;\n\n constructor() ERC721(\"TestNFT\", \"TNFT\") {}\n\n function mint(address recipient) public returns (uint256) {\n currentTokenId.increment();\n uint256 newItemId = currentTokenId.current();\n _safeMint(recipient, newItemId);\n return newItemId;\n }\n}\n" + }, + "contracts/test/TestToken.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract TestToken is ERC20 {\n constructor()\n // solhint-disable-next-line no-empty-blocks\n ERC20(\"TST\", \"TestToken\")\n {}\n\n function mint(address sender, uint256 amount) external {\n _mint(sender, amount);\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 999999 + }, + "evmVersion": "paris", + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/deployments/bsc/solcInputs/167a830377988095f5f829bf03425fb0.json b/deployments/bsc/solcInputs/167a830377988095f5f829bf03425fb0.json new file mode 100644 index 0000000..2833a16 --- /dev/null +++ b/deployments/bsc/solcInputs/167a830377988095f5f829bf03425fb0.json @@ -0,0 +1,354 @@ +{ + "language": "Solidity", + "sources": { + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby disabling any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable2Step.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./Ownable.sol\";\n\n/**\n * @dev Contract module which provides access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership} and {acceptOwnership}.\n *\n * This module is used through inheritance. It will make available all functions\n * from parent (Ownable).\n */\nabstract contract Ownable2Step is Ownable {\n address private _pendingOwner;\n\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Returns the address of the pending owner.\n */\n function pendingOwner() public view virtual returns (address) {\n return _pendingOwner;\n }\n\n /**\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual override onlyOwner {\n _pendingOwner = newOwner;\n emit OwnershipTransferStarted(owner(), newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual override {\n delete _pendingOwner;\n super._transferOwnership(newOwner);\n }\n\n /**\n * @dev The new owner accepts the ownership transfer.\n */\n function acceptOwnership() public virtual {\n address sender = _msgSender();\n require(pendingOwner() == sender, \"Ownable2Step: caller is not the new owner\");\n _transferOwnership(sender);\n }\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC1271.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC1271 standard signature validation method for\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\n *\n * _Available since v4.1._\n */\ninterface IERC1271 {\n /**\n * @dev Should return whether the signature provided is valid for the provided data\n * @param hash Hash of the data to be signed\n * @param signature Signature byte array associated with _data\n */\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\n}\n" + }, + "@openzeppelin/contracts/security/ReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor() {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n _nonReentrantBefore();\n _;\n _nonReentrantAfter();\n }\n\n function _nonReentrantBefore() private {\n // On the first call to nonReentrant, _status will be _NOT_ENTERED\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n }\n\n function _nonReentrantAfter() private {\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Returns true if the reentrancy guard is currently set to \"entered\", which indicates there is a\n * `nonReentrant` function in the call stack.\n */\n function _reentrancyGuardEntered() internal view returns (bool) {\n return _status == _ENTERED;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/ERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/ERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC1155.sol\";\nimport \"./IERC1155Receiver.sol\";\nimport \"./extensions/IERC1155MetadataURI.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of the basic standard multi-token.\n * See https://eips.ethereum.org/EIPS/eip-1155\n * Originally based on code by Enjin: https://github.com/enjin/erc-1155\n *\n * _Available since v3.1._\n */\ncontract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {\n using Address for address;\n\n // Mapping from token ID to account balances\n mapping(uint256 => mapping(address => uint256)) private _balances;\n\n // Mapping from account to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json\n string private _uri;\n\n /**\n * @dev See {_setURI}.\n */\n constructor(string memory uri_) {\n _setURI(uri_);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return\n interfaceId == type(IERC1155).interfaceId ||\n interfaceId == type(IERC1155MetadataURI).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC1155MetadataURI-uri}.\n *\n * This implementation returns the same URI for *all* token types. It relies\n * on the token type ID substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * Clients calling this function must replace the `\\{id\\}` substring with the\n * actual token type ID.\n */\n function uri(uint256) public view virtual override returns (string memory) {\n return _uri;\n }\n\n /**\n * @dev See {IERC1155-balanceOf}.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {\n require(account != address(0), \"ERC1155: address zero is not a valid owner\");\n return _balances[id][account];\n }\n\n /**\n * @dev See {IERC1155-balanceOfBatch}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] memory accounts,\n uint256[] memory ids\n ) public view virtual override returns (uint256[] memory) {\n require(accounts.length == ids.length, \"ERC1155: accounts and ids length mismatch\");\n\n uint256[] memory batchBalances = new uint256[](accounts.length);\n\n for (uint256 i = 0; i < accounts.length; ++i) {\n batchBalances[i] = balanceOf(accounts[i], ids[i]);\n }\n\n return batchBalances;\n }\n\n /**\n * @dev See {IERC1155-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC1155-isApprovedForAll}.\n */\n function isApprovedForAll(address account, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[account][operator];\n }\n\n /**\n * @dev See {IERC1155-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n _safeTransferFrom(from, to, id, amount, data);\n }\n\n /**\n * @dev See {IERC1155-safeBatchTransferFrom}.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n _safeBatchTransferFrom(from, to, ids, amounts, data);\n }\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n\n emit TransferSingle(operator, from, to, id, amount);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n for (uint256 i = 0; i < ids.length; ++i) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n }\n\n emit TransferBatch(operator, from, to, ids, amounts);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\n\n _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);\n }\n\n /**\n * @dev Sets a new URI for all token types, by relying on the token type ID\n * substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * By this mechanism, any occurrence of the `\\{id\\}` substring in either the\n * URI or any of the amounts in the JSON file at said URI will be replaced by\n * clients with the token type ID.\n *\n * For example, the `https://token-cdn-domain/\\{id\\}.json` URI would be\n * interpreted by clients as\n * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`\n * for token type ID 0x4cce0.\n *\n * See {uri}.\n *\n * Because these URIs cannot be meaningfully represented by the {URI} event,\n * this function emits no events.\n */\n function _setURI(string memory newuri) internal virtual {\n _uri = newuri;\n }\n\n /**\n * @dev Creates `amount` tokens of token type `id`, and assigns them to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _mint(address to, uint256 id, uint256 amount, bytes memory data) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _balances[id][to] += amount;\n emit TransferSingle(operator, address(0), to, id, amount);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n for (uint256 i = 0; i < ids.length; i++) {\n _balances[ids[i]][to] += amounts[i];\n }\n\n emit TransferBatch(operator, address(0), to, ids, amounts);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);\n }\n\n /**\n * @dev Destroys `amount` tokens of token type `id` from `from`\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `from` must have at least `amount` tokens of token type `id`.\n */\n function _burn(address from, uint256 id, uint256 amount) internal virtual {\n require(from != address(0), \"ERC1155: burn from the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n\n emit TransferSingle(operator, from, address(0), id, amount);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n */\n function _burnBatch(address from, uint256[] memory ids, uint256[] memory amounts) internal virtual {\n require(from != address(0), \"ERC1155: burn from the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n\n for (uint256 i = 0; i < ids.length; i++) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n }\n\n emit TransferBatch(operator, from, address(0), ids, amounts);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {\n require(owner != operator, \"ERC1155: setting approval status for self\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning, as well as batched variants.\n *\n * The same hook is called on both single and batched variants. For single\n * transfers, the length of the `ids` and `amounts` arrays will be 1.\n *\n * Calling conditions (for each `id` and `amount` pair):\n *\n * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * of token type `id` will be transferred to `to`.\n * - When `from` is zero, `amount` tokens of token type `id` will be minted\n * for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n * will be burned.\n * - `from` and `to` are never both zero.\n * - `ids` and `amounts` have the same, non-zero length.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any token transfer. This includes minting\n * and burning, as well as batched variants.\n *\n * The same hook is called on both single and batched variants. For single\n * transfers, the length of the `id` and `amount` arrays will be 1.\n *\n * Calling conditions (for each `id` and `amount` pair):\n *\n * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * of token type `id` will be transferred to `to`.\n * - When `from` is zero, `amount` tokens of token type `id` will be minted\n * for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n * will be burned.\n * - `from` and `to` are never both zero.\n * - `ids` and `amounts` have the same, non-zero length.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {}\n\n function _doSafeTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155Receiver.onERC1155Received.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non-ERC1155Receiver implementer\");\n }\n }\n }\n\n function _doSafeBatchTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (\n bytes4 response\n ) {\n if (response != IERC1155Receiver.onERC1155BatchReceived.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non-ERC1155Receiver implementer\");\n }\n }\n }\n\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {\n uint256[] memory array = new uint256[](1);\n array[0] = element;\n\n return array;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC1155.sol\";\n\n/**\n * @dev Interface of the optional ERC1155MetadataExtension interface, as defined\n * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155MetadataURI is IERC1155 {\n /**\n * @dev Returns the URI for token type `id`.\n *\n * If the `\\{id\\}` substring is present in the URI, it must be replaced by\n * clients with the actual token type ID.\n */\n function uri(uint256 id) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155 is IERC165 {\n /**\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n */\n event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);\n\n /**\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n * transfers.\n */\n event TransferBatch(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\n\n /**\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n * `approved`.\n */\n event ApprovalForAll(address indexed account, address indexed operator, bool approved);\n\n /**\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n *\n * If an {URI} event was emitted for `id`, the standard\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n * returned by {IERC1155MetadataURI-uri}.\n */\n event URI(string value, uint256 indexed id);\n\n /**\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) external view returns (uint256);\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] calldata accounts,\n uint256[] calldata ids\n ) external view returns (uint256[] memory);\n\n /**\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n *\n * Emits an {ApprovalForAll} event.\n *\n * Requirements:\n *\n * - `operator` cannot be the caller.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n *\n * See {setApprovalForAll}.\n */\n function isApprovedForAll(address account, address operator) external view returns (bool);\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155Receiver is IERC165 {\n /**\n * @dev Handles the receipt of a single ERC1155 token type. This function is\n * called at the end of a `safeTransferFrom` after the balance has been updated.\n *\n * NOTE: To accept the transfer, this must return\n * `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n * (i.e. 0xf23a6e61, or its own function selector).\n *\n * @param operator The address which initiated the transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param id The ID of the token being transferred\n * @param value The amount of tokens being transferred\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n ) external returns (bytes4);\n\n /**\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\n * is called at the end of a `safeBatchTransferFrom` after the balances have\n * been updated.\n *\n * NOTE: To accept the transfer(s), this must return\n * `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n * (i.e. 0xbc197c81, or its own function selector).\n *\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the default value returned by this function, unless\n * it's overridden.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(address from, address to, uint256 amount) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\n // decrementing then incrementing.\n _balances[to] += amount;\n }\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n unchecked {\n // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\n _balances[account] += amount;\n }\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n // Overflow not possible: amount <= accountBalance <= totalSupply.\n _totalSupply -= amount;\n }\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\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" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` 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 amount) 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 `amount` as the allowance of `spender` over the 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 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` 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 amount) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/ERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721.sol\";\nimport \"./IERC721Receiver.sol\";\nimport \"./extensions/IERC721Metadata.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/Strings.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\n using Address for address;\n using Strings for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\n\n // Mapping from token ID to approved address\n mapping(uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return\n interfaceId == type(IERC721).interfaceId ||\n interfaceId == type(IERC721Metadata).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _ownerOf(tokenId);\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token owner or approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n _requireMinted(tokenId);\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n _safeTransfer(from, to, tokenId, data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(address from, address to, uint256 tokenId, bytes memory data) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist\n */\n function _ownerOf(uint256 tokenId) internal view virtual returns (address) {\n return _owners[tokenId];\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _ownerOf(tokenId) != address(0);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n address owner = ERC721.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(address to, uint256 tokenId, bytes memory data) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId, 1);\n\n // Check that tokenId was not minted by `_beforeTokenTransfer` hook\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n unchecked {\n // Will not overflow unless all 2**256 token ids are minted to the same owner.\n // Given that tokens are minted one by one, it is impossible in practice that\n // this ever happens. Might change if we allow batch minting.\n // The ERC fails to describe this case.\n _balances[to] += 1;\n }\n\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(address(0), to, tokenId, 1);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n * This is an internal function that does not check if the sender is authorized to operate on the token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId, 1);\n\n // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook\n owner = ERC721.ownerOf(tokenId);\n\n // Clear approvals\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // Cannot overflow, as that would require more tokens to be burned/transferred\n // out than the owner initially received through minting and transferring in.\n _balances[owner] -= 1;\n }\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(owner, address(0), tokenId, 1);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(address from, address to, uint256 tokenId) internal virtual {\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId, 1);\n\n // Check that tokenId was not transferred by `_beforeTokenTransfer` hook\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n\n // Clear approvals from the previous owner\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // `_balances[from]` cannot overflow for the same reason as described in `_burn`:\n // `from`'s balance is the number of token held, which is at least one before the current\n // transfer.\n // `_balances[to]` could overflow in the conditions described in `_mint`. That would require\n // all 2**256 token ids to be minted, which in practice is impossible.\n _balances[from] -= 1;\n _balances[to] += 1;\n }\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId, 1);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721Receiver.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`.\n * - When `from` is zero, the tokens will be minted for `to`.\n * - When `to` is zero, ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}\n\n /**\n * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`.\n * - When `from` is zero, the tokens were minted for `to`.\n * - When `to` is zero, ``from``'s tokens were burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}\n\n /**\n * @dev Unsafe write access to the balances, used by extensions that \"mint\" tokens using an {ownerOf} override.\n *\n * WARNING: Anyone calling this MUST ensure that the balances remain consistent with the ownership. The invariant\n * being that for any address `a` the value returned by `balanceOf(a)` must be equal to the number of tokens such\n * that `ownerOf(tokenId)` is `a`.\n */\n // solhint-disable-next-line func-name-mixedcase\n function __unsafe_increaseBalance(address account, uint256 amount) internal {\n _balances[account] += amount;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721Receiver {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/ERC777.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC777/ERC777.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC777.sol\";\nimport \"./IERC777Recipient.sol\";\nimport \"./IERC777Sender.sol\";\nimport \"../ERC20/IERC20.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/introspection/IERC1820Registry.sol\";\n\n/**\n * @dev Implementation of the {IERC777} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n *\n * Support for ERC20 is included in this contract, as specified by the EIP: both\n * the ERC777 and ERC20 interfaces can be safely used when interacting with it.\n * Both {IERC777-Sent} and {IERC20-Transfer} events are emitted on token\n * movements.\n *\n * Additionally, the {IERC777-granularity} value is hard-coded to `1`, meaning that there\n * are no special restrictions in the amount of tokens that created, moved, or\n * destroyed. This makes integration with ERC20 applications seamless.\n *\n * CAUTION: This file is deprecated as of v4.9 and will be removed in the next major release.\n */\ncontract ERC777 is Context, IERC777, IERC20 {\n using Address for address;\n\n IERC1820Registry internal constant _ERC1820_REGISTRY = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n mapping(address => uint256) private _balances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n bytes32 private constant _TOKENS_SENDER_INTERFACE_HASH = keccak256(\"ERC777TokensSender\");\n bytes32 private constant _TOKENS_RECIPIENT_INTERFACE_HASH = keccak256(\"ERC777TokensRecipient\");\n\n // This isn't ever read from - it's only used to respond to the defaultOperators query.\n address[] private _defaultOperatorsArray;\n\n // Immutable, but accounts may revoke them (tracked in __revokedDefaultOperators).\n mapping(address => bool) private _defaultOperators;\n\n // For each account, a mapping of its operators and revoked default operators.\n mapping(address => mapping(address => bool)) private _operators;\n mapping(address => mapping(address => bool)) private _revokedDefaultOperators;\n\n // ERC20-allowances\n mapping(address => mapping(address => uint256)) private _allowances;\n\n /**\n * @dev `defaultOperators` may be an empty array.\n */\n constructor(string memory name_, string memory symbol_, address[] memory defaultOperators_) {\n _name = name_;\n _symbol = symbol_;\n\n _defaultOperatorsArray = defaultOperators_;\n for (uint256 i = 0; i < defaultOperators_.length; i++) {\n _defaultOperators[defaultOperators_[i]] = true;\n }\n\n // register interfaces\n _ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256(\"ERC777Token\"), address(this));\n _ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256(\"ERC20Token\"), address(this));\n }\n\n /**\n * @dev See {IERC777-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC777-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {ERC20-decimals}.\n *\n * Always returns 18, as per the\n * [ERC777 EIP](https://eips.ethereum.org/EIPS/eip-777#backward-compatibility).\n */\n function decimals() public pure virtual returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC777-granularity}.\n *\n * This implementation always returns `1`.\n */\n function granularity() public view virtual override returns (uint256) {\n return 1;\n }\n\n /**\n * @dev See {IERC777-totalSupply}.\n */\n function totalSupply() public view virtual override(IERC20, IERC777) returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev Returns the amount of tokens owned by an account (`tokenHolder`).\n */\n function balanceOf(address tokenHolder) public view virtual override(IERC20, IERC777) returns (uint256) {\n return _balances[tokenHolder];\n }\n\n /**\n * @dev See {IERC777-send}.\n *\n * Also emits a {IERC20-Transfer} event for ERC20 compatibility.\n */\n function send(address recipient, uint256 amount, bytes memory data) public virtual override {\n _send(_msgSender(), recipient, amount, data, \"\", true);\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Unlike `send`, `recipient` is _not_ required to implement the {IERC777Recipient}\n * interface if it is a contract.\n *\n * Also emits a {Sent} event.\n */\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n _send(_msgSender(), recipient, amount, \"\", \"\", false);\n return true;\n }\n\n /**\n * @dev See {IERC777-burn}.\n *\n * Also emits a {IERC20-Transfer} event for ERC20 compatibility.\n */\n function burn(uint256 amount, bytes memory data) public virtual override {\n _burn(_msgSender(), amount, data, \"\");\n }\n\n /**\n * @dev See {IERC777-isOperatorFor}.\n */\n function isOperatorFor(address operator, address tokenHolder) public view virtual override returns (bool) {\n return\n operator == tokenHolder ||\n (_defaultOperators[operator] && !_revokedDefaultOperators[tokenHolder][operator]) ||\n _operators[tokenHolder][operator];\n }\n\n /**\n * @dev See {IERC777-authorizeOperator}.\n */\n function authorizeOperator(address operator) public virtual override {\n require(_msgSender() != operator, \"ERC777: authorizing self as operator\");\n\n if (_defaultOperators[operator]) {\n delete _revokedDefaultOperators[_msgSender()][operator];\n } else {\n _operators[_msgSender()][operator] = true;\n }\n\n emit AuthorizedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-revokeOperator}.\n */\n function revokeOperator(address operator) public virtual override {\n require(operator != _msgSender(), \"ERC777: revoking self as operator\");\n\n if (_defaultOperators[operator]) {\n _revokedDefaultOperators[_msgSender()][operator] = true;\n } else {\n delete _operators[_msgSender()][operator];\n }\n\n emit RevokedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-defaultOperators}.\n */\n function defaultOperators() public view virtual override returns (address[] memory) {\n return _defaultOperatorsArray;\n }\n\n /**\n * @dev See {IERC777-operatorSend}.\n *\n * Emits {Sent} and {IERC20-Transfer} events.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes memory data,\n bytes memory operatorData\n ) public virtual override {\n require(isOperatorFor(_msgSender(), sender), \"ERC777: caller is not an operator for holder\");\n _send(sender, recipient, amount, data, operatorData, true);\n }\n\n /**\n * @dev See {IERC777-operatorBurn}.\n *\n * Emits {Burned} and {IERC20-Transfer} events.\n */\n function operatorBurn(\n address account,\n uint256 amount,\n bytes memory data,\n bytes memory operatorData\n ) public virtual override {\n require(isOperatorFor(_msgSender(), account), \"ERC777: caller is not an operator for holder\");\n _burn(account, amount, data, operatorData);\n }\n\n /**\n * @dev See {IERC20-allowance}.\n *\n * Note that operator and allowance concepts are orthogonal: operators may\n * not have allowance, and accounts with allowance may not be operators\n * themselves.\n */\n function allowance(address holder, address spender) public view virtual override returns (uint256) {\n return _allowances[holder][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Note that accounts cannot have allowance issued by their operators.\n */\n function approve(address spender, uint256 value) public virtual override returns (bool) {\n address holder = _msgSender();\n _approve(holder, spender, value);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Note that operator and allowance concepts are orthogonal: operators cannot\n * call `transferFrom` (unless they have allowance), and accounts with\n * allowance cannot call `operatorSend` (unless they are operators).\n *\n * Emits {Sent}, {IERC20-Transfer} and {IERC20-Approval} events.\n */\n function transferFrom(address holder, address recipient, uint256 amount) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(holder, spender, amount);\n _send(holder, recipient, amount, \"\", \"\", false);\n return true;\n }\n\n /**\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with the caller address as the `operator` and with\n * `userData` and `operatorData`.\n *\n * See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits {Minted} and {IERC20-Transfer} events.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - if `account` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function _mint(address account, uint256 amount, bytes memory userData, bytes memory operatorData) internal virtual {\n _mint(account, amount, userData, operatorData, true);\n }\n\n /**\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * If `requireReceptionAck` is set to true, and if a send hook is\n * registered for `account`, the corresponding function will be called with\n * `operator`, `data` and `operatorData`.\n *\n * See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits {Minted} and {IERC20-Transfer} events.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - if `account` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function _mint(\n address account,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) internal virtual {\n require(account != address(0), \"ERC777: mint to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), account, amount);\n\n // Update state variables\n _totalSupply += amount;\n _balances[account] += amount;\n\n _callTokensReceived(operator, address(0), account, amount, userData, operatorData, requireReceptionAck);\n\n emit Minted(operator, account, amount, userData, operatorData);\n emit Transfer(address(0), account, amount);\n }\n\n /**\n * @dev Send tokens\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _send(\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) internal virtual {\n require(from != address(0), \"ERC777: transfer from the zero address\");\n require(to != address(0), \"ERC777: transfer to the zero address\");\n\n address operator = _msgSender();\n\n _callTokensToSend(operator, from, to, amount, userData, operatorData);\n\n _move(operator, from, to, amount, userData, operatorData);\n\n _callTokensReceived(operator, from, to, amount, userData, operatorData, requireReceptionAck);\n }\n\n /**\n * @dev Burn tokens\n * @param from address token holder address\n * @param amount uint256 amount of tokens to burn\n * @param data bytes extra information provided by the token holder\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _burn(address from, uint256 amount, bytes memory data, bytes memory operatorData) internal virtual {\n require(from != address(0), \"ERC777: burn from the zero address\");\n\n address operator = _msgSender();\n\n _callTokensToSend(operator, from, address(0), amount, data, operatorData);\n\n _beforeTokenTransfer(operator, from, address(0), amount);\n\n // Update state variables\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC777: burn amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Burned(operator, from, amount, data, operatorData);\n emit Transfer(from, address(0), amount);\n }\n\n function _move(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n ) private {\n _beforeTokenTransfer(operator, from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC777: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Sent(operator, from, to, amount, userData, operatorData);\n emit Transfer(from, to, amount);\n }\n\n /**\n * @dev See {ERC20-_approve}.\n *\n * Note that accounts cannot have allowance issued by their operators.\n */\n function _approve(address holder, address spender, uint256 value) internal virtual {\n require(holder != address(0), \"ERC777: approve from the zero address\");\n require(spender != address(0), \"ERC777: approve to the zero address\");\n\n _allowances[holder][spender] = value;\n emit Approval(holder, spender, value);\n }\n\n /**\n * @dev Call from.tokensToSend() if the interface is registered\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _callTokensToSend(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n ) private {\n address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(from, _TOKENS_SENDER_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Sender(implementer).tokensToSend(operator, from, to, amount, userData, operatorData);\n }\n }\n\n /**\n * @dev Call to.tokensReceived() if the interface is registered. Reverts if the recipient is a contract but\n * tokensReceived() was not registered for the recipient\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _callTokensReceived(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) private {\n address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(to, _TOKENS_RECIPIENT_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Recipient(implementer).tokensReceived(operator, from, to, amount, userData, operatorData);\n } else if (requireReceptionAck) {\n require(!to.isContract(), \"ERC777: token recipient contract has no implementer for ERC777TokensRecipient\");\n }\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {IERC20-Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC777: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes\n * calls to {send}, {transfer}, {operatorSend}, {transferFrom}, minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be to transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address operator, address from, address to, uint256 amount) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC777/IERC777.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777Token standard as defined in the EIP.\n *\n * This contract uses the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 registry standard] to let\n * token holders and recipients react to token movements by using setting implementers\n * for the associated interfaces in said registry. See {IERC1820Registry} and\n * {ERC1820Implementer}.\n */\ninterface IERC777 {\n /**\n * @dev Emitted when `amount` tokens are created by `operator` and assigned to `to`.\n *\n * Note that some additional user `data` and `operatorData` can be logged in the event.\n */\n event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);\n\n /**\n * @dev Emitted when `operator` destroys `amount` tokens from `account`.\n *\n * Note that some additional user `data` and `operatorData` can be logged in the event.\n */\n event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);\n\n /**\n * @dev Emitted when `operator` is made operator for `tokenHolder`.\n */\n event AuthorizedOperator(address indexed operator, address indexed tokenHolder);\n\n /**\n * @dev Emitted when `operator` is revoked its operator status for `tokenHolder`.\n */\n event RevokedOperator(address indexed operator, address indexed tokenHolder);\n\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, usually a shorter version of the\n * name.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the smallest part of the token that is not divisible. This\n * means all token operations (creation, movement and destruction) must have\n * amounts that are a multiple of this number.\n *\n * For most token contracts, this value will equal 1.\n */\n function granularity() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by an account (`owner`).\n */\n function balanceOf(address owner) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * If send or receive hooks are registered for the caller and `recipient`,\n * the corresponding functions will be called with `data` and empty\n * `operatorData`. See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits a {Sent} event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function send(address recipient, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Destroys `amount` tokens from the caller's account, reducing the\n * total supply.\n *\n * If a send hook is registered for the caller, the corresponding function\n * will be called with `data` and empty `operatorData`. See {IERC777Sender}.\n *\n * Emits a {Burned} event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n */\n function burn(uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Returns true if an account is an operator of `tokenHolder`.\n * Operators can send and burn tokens on behalf of their owners. All\n * accounts are their own operator.\n *\n * See {operatorSend} and {operatorBurn}.\n */\n function isOperatorFor(address operator, address tokenHolder) external view returns (bool);\n\n /**\n * @dev Make an account an operator of the caller.\n *\n * See {isOperatorFor}.\n *\n * Emits an {AuthorizedOperator} event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function authorizeOperator(address operator) external;\n\n /**\n * @dev Revoke an account's operator status for the caller.\n *\n * See {isOperatorFor} and {defaultOperators}.\n *\n * Emits a {RevokedOperator} event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function revokeOperator(address operator) external;\n\n /**\n * @dev Returns the list of default operators. These accounts are operators\n * for all token holders, even if {authorizeOperator} was never called on\n * them.\n *\n * This list is immutable, but individual holders may revoke these via\n * {revokeOperator}, in which case {isOperatorFor} will return false.\n */\n function defaultOperators() external view returns (address[] memory);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must\n * be an operator of `sender`.\n *\n * If send or receive hooks are registered for `sender` and `recipient`,\n * the corresponding functions will be called with `data` and\n * `operatorData`. See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits a {Sent} event.\n *\n * Requirements\n *\n * - `sender` cannot be the zero address.\n * - `sender` must have at least `amount` tokens.\n * - the caller must be an operator for `sender`.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes calldata data,\n bytes calldata operatorData\n ) external;\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the total supply.\n * The caller must be an operator of `account`.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with `data` and `operatorData`. See {IERC777Sender}.\n *\n * Emits a {Burned} event.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n * - the caller must be an operator for `account`.\n */\n function operatorBurn(address account, uint256 amount, bytes calldata data, bytes calldata operatorData) external;\n\n event Sent(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes data,\n bytes operatorData\n );\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\n *\n * Accounts can be notified of {IERC777} tokens being sent to them by having a\n * contract implement this interface (contract holders can be their own\n * implementer) and registering it on the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\n *\n * See {IERC1820Registry} and {ERC1820Implementer}.\n */\ninterface IERC777Recipient {\n /**\n * @dev Called by an {IERC777} token contract whenever tokens are being\n * moved or created into a registered account (`to`). The type of operation\n * is conveyed by `from` being the zero address or not.\n *\n * This call occurs _after_ the token contract's state is updated, so\n * {IERC777-balanceOf}, etc., can be used to query the post-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensReceived(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777Sender.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Sender.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777TokensSender standard as defined in the EIP.\n *\n * {IERC777} Token holders can be notified of operations performed on their\n * tokens by having a contract implement this interface (contract holders can be\n * their own implementer) and registering it on the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\n *\n * See {IERC1820Registry} and {ERC1820Implementer}.\n */\ninterface IERC777Sender {\n /**\n * @dev Called by an {IERC777} token contract whenever a registered holder's\n * (`from`) tokens are about to be moved or destroyed. The type of operation\n * is conveyed by `to` being the zero address or not.\n *\n * This call occurs _before_ the token contract's state is updated, so\n * {IERC777-balanceOf}, etc., can be used to query the pre-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensToSend(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n *\n * Furthermore, `isContract` will also return true if the target contract within\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n * which only has an effect at the end of a transaction.\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Counters.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary Counters {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/ECDSA.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Strings.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV // Deprecated in v4.8\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n /// @solidity memory-safe-assembly\n assembly {\n mstore(0x00, \"\\x19Ethereum Signed Message:\\n32\")\n mstore(0x1c, hash)\n message := keccak256(0x00, 0x3c)\n }\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\n /// @solidity memory-safe-assembly\n assembly {\n let ptr := mload(0x40)\n mstore(ptr, \"\\x19\\x01\")\n mstore(add(ptr, 0x02), domainSeparator)\n mstore(add(ptr, 0x22), structHash)\n data := keccak256(ptr, 0x42)\n }\n }\n\n /**\n * @dev Returns an Ethereum Signed Data with intended validator, created from a\n * `validator` and `data` according to the version 0 of EIP-191.\n *\n * See {recover}.\n */\n function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x00\", validator, data));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/SignatureChecker.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSA.sol\";\nimport \"../../interfaces/IERC1271.sol\";\n\n/**\n * @dev Signature verification helper that can be used instead of `ECDSA.recover` to seamlessly support both ECDSA\n * signatures from externally owned accounts (EOAs) as well as ERC1271 signatures from smart contract wallets like\n * Argent and Gnosis Safe.\n *\n * _Available since v4.1._\n */\nlibrary SignatureChecker {\n /**\n * @dev Checks if a signature is valid for a given signer and data hash. If the signer is a smart contract, the\n * signature is validated against that smart contract using ERC1271, otherwise it's validated using `ECDSA.recover`.\n *\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\n */\n function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature) internal view returns (bool) {\n (address recovered, ECDSA.RecoverError error) = ECDSA.tryRecover(hash, signature);\n return\n (error == ECDSA.RecoverError.NoError && recovered == signer) ||\n isValidERC1271SignatureNow(signer, hash, signature);\n }\n\n /**\n * @dev Checks if a signature is valid for a given signer and data hash. The signature is validated\n * against the signer smart contract using ERC1271.\n *\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\n */\n function isValidERC1271SignatureNow(\n address signer,\n bytes32 hash,\n bytes memory signature\n ) internal view returns (bool) {\n (bool success, bytes memory result) = signer.staticcall(\n abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, signature)\n );\n return (success &&\n result.length >= 32 &&\n abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/ERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165 is IERC165 {\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165).interfaceId;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC1820Registry.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/introspection/IERC1820Registry.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the global ERC1820 Registry, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register\n * implementers for interfaces in this registry, as well as query support.\n *\n * Implementers may be shared by multiple accounts, and can also implement more\n * than a single interface for each account. Contracts can implement interfaces\n * for themselves, but externally-owned accounts (EOA) must delegate this to a\n * contract.\n *\n * {IERC165} interfaces can also be queried via the registry.\n *\n * For an in-depth explanation and source code analysis, see the EIP text.\n */\ninterface IERC1820Registry {\n event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer);\n\n event ManagerChanged(address indexed account, address indexed newManager);\n\n /**\n * @dev Sets `newManager` as the manager for `account`. A manager of an\n * account is able to set interface implementers for it.\n *\n * By default, each account is its own manager. Passing a value of `0x0` in\n * `newManager` will reset the manager to this initial state.\n *\n * Emits a {ManagerChanged} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `account`.\n */\n function setManager(address account, address newManager) external;\n\n /**\n * @dev Returns the manager for `account`.\n *\n * See {setManager}.\n */\n function getManager(address account) external view returns (address);\n\n /**\n * @dev Sets the `implementer` contract as ``account``'s implementer for\n * `interfaceHash`.\n *\n * `account` being the zero address is an alias for the caller's address.\n * The zero address can also be used in `implementer` to remove an old one.\n *\n * See {interfaceHash} to learn how these are created.\n *\n * Emits an {InterfaceImplementerSet} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `account`.\n * - `interfaceHash` must not be an {IERC165} interface id (i.e. it must not\n * end in 28 zeroes).\n * - `implementer` must implement {IERC1820Implementer} and return true when\n * queried for support, unless `implementer` is the caller. See\n * {IERC1820Implementer-canImplementInterfaceForAddress}.\n */\n function setInterfaceImplementer(address account, bytes32 _interfaceHash, address implementer) external;\n\n /**\n * @dev Returns the implementer of `interfaceHash` for `account`. If no such\n * implementer is registered, returns the zero address.\n *\n * If `interfaceHash` is an {IERC165} interface id (i.e. it ends with 28\n * zeroes), `account` will be queried for support of it.\n *\n * `account` being the zero address is an alias for the caller's address.\n */\n function getInterfaceImplementer(address account, bytes32 _interfaceHash) external view returns (address);\n\n /**\n * @dev Returns the interface hash for an `interfaceName`, as defined in the\n * corresponding\n * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP].\n */\n function interfaceHash(string calldata interfaceName) external pure returns (bytes32);\n\n /**\n * @notice Updates the cache with whether the contract implements an ERC165 interface or not.\n * @param account Address of the contract for which to update the cache.\n * @param interfaceId ERC165 interface for which to update the cache.\n */\n function updateERC165Cache(address account, bytes4 interfaceId) external;\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not.\n * If the result is not cached a direct lookup on the contract address is performed.\n * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling\n * {updateERC165Cache} with the contract address.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool);\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not without using or updating the cache.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/math/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\n // The surrounding unchecked block does not change this fact.\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1, \"Math: mulDiv overflow\");\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n //\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n //\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n //\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1 << (log2(a) >> 1);\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = sqrt(a);\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 2, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 128;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 64;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 32;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 16;\n }\n if (value >> 8 > 0) {\n value >>= 8;\n result += 8;\n }\n if (value >> 4 > 0) {\n value >>= 4;\n result += 4;\n }\n if (value >> 2 > 0) {\n value >>= 2;\n result += 2;\n }\n if (value >> 1 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log2(value);\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 10, rounded down, of a positive value.\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 + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 256, rounded down, of a positive value.\n * Returns 0 if given 0.\n *\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n */\n function log256(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 16;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 8;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 4;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 2;\n }\n if (value >> 8 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log256(value);\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/SafeCast.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCast {\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 * _Available since v4.7._\n */\n function toUint248(uint256 value) internal pure returns (uint248) {\n require(value <= type(uint248).max, \"SafeCast: value doesn't fit in 248 bits\");\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 * _Available since v4.7._\n */\n function toUint240(uint256 value) internal pure returns (uint240) {\n require(value <= type(uint240).max, \"SafeCast: value doesn't fit in 240 bits\");\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 * _Available since v4.7._\n */\n function toUint232(uint256 value) internal pure returns (uint232) {\n require(value <= type(uint232).max, \"SafeCast: value doesn't fit in 232 bits\");\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 * _Available since v4.2._\n */\n function toUint224(uint256 value) internal pure returns (uint224) {\n require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\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 * _Available since v4.7._\n */\n function toUint216(uint256 value) internal pure returns (uint216) {\n require(value <= type(uint216).max, \"SafeCast: value doesn't fit in 216 bits\");\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 * _Available since v4.7._\n */\n function toUint208(uint256 value) internal pure returns (uint208) {\n require(value <= type(uint208).max, \"SafeCast: value doesn't fit in 208 bits\");\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 * _Available since v4.7._\n */\n function toUint200(uint256 value) internal pure returns (uint200) {\n require(value <= type(uint200).max, \"SafeCast: value doesn't fit in 200 bits\");\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 * _Available since v4.7._\n */\n function toUint192(uint256 value) internal pure returns (uint192) {\n require(value <= type(uint192).max, \"SafeCast: value doesn't fit in 192 bits\");\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 * _Available since v4.7._\n */\n function toUint184(uint256 value) internal pure returns (uint184) {\n require(value <= type(uint184).max, \"SafeCast: value doesn't fit in 184 bits\");\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 * _Available since v4.7._\n */\n function toUint176(uint256 value) internal pure returns (uint176) {\n require(value <= type(uint176).max, \"SafeCast: value doesn't fit in 176 bits\");\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 * _Available since v4.7._\n */\n function toUint168(uint256 value) internal pure returns (uint168) {\n require(value <= type(uint168).max, \"SafeCast: value doesn't fit in 168 bits\");\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 * _Available since v4.7._\n */\n function toUint160(uint256 value) internal pure returns (uint160) {\n require(value <= type(uint160).max, \"SafeCast: value doesn't fit in 160 bits\");\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 * _Available since v4.7._\n */\n function toUint152(uint256 value) internal pure returns (uint152) {\n require(value <= type(uint152).max, \"SafeCast: value doesn't fit in 152 bits\");\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 * _Available since v4.7._\n */\n function toUint144(uint256 value) internal pure returns (uint144) {\n require(value <= type(uint144).max, \"SafeCast: value doesn't fit in 144 bits\");\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 * _Available since v4.7._\n */\n function toUint136(uint256 value) internal pure returns (uint136) {\n require(value <= type(uint136).max, \"SafeCast: value doesn't fit in 136 bits\");\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 * _Available since v2.5._\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\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 * _Available since v4.7._\n */\n function toUint120(uint256 value) internal pure returns (uint120) {\n require(value <= type(uint120).max, \"SafeCast: value doesn't fit in 120 bits\");\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 * _Available since v4.7._\n */\n function toUint112(uint256 value) internal pure returns (uint112) {\n require(value <= type(uint112).max, \"SafeCast: value doesn't fit in 112 bits\");\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 * _Available since v4.7._\n */\n function toUint104(uint256 value) internal pure returns (uint104) {\n require(value <= type(uint104).max, \"SafeCast: value doesn't fit in 104 bits\");\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 * _Available since v4.2._\n */\n function toUint96(uint256 value) internal pure returns (uint96) {\n require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\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 * _Available since v4.7._\n */\n function toUint88(uint256 value) internal pure returns (uint88) {\n require(value <= type(uint88).max, \"SafeCast: value doesn't fit in 88 bits\");\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 * _Available since v4.7._\n */\n function toUint80(uint256 value) internal pure returns (uint80) {\n require(value <= type(uint80).max, \"SafeCast: value doesn't fit in 80 bits\");\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 * _Available since v4.7._\n */\n function toUint72(uint256 value) internal pure returns (uint72) {\n require(value <= type(uint72).max, \"SafeCast: value doesn't fit in 72 bits\");\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 * _Available since v2.5._\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\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 * _Available since v4.7._\n */\n function toUint56(uint256 value) internal pure returns (uint56) {\n require(value <= type(uint56).max, \"SafeCast: value doesn't fit in 56 bits\");\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 * _Available since v4.7._\n */\n function toUint48(uint256 value) internal pure returns (uint48) {\n require(value <= type(uint48).max, \"SafeCast: value doesn't fit in 48 bits\");\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 * _Available since v4.7._\n */\n function toUint40(uint256 value) internal pure returns (uint40) {\n require(value <= type(uint40).max, \"SafeCast: value doesn't fit in 40 bits\");\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 * _Available since v2.5._\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\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 * _Available since v4.7._\n */\n function toUint24(uint256 value) internal pure returns (uint24) {\n require(value <= type(uint24).max, \"SafeCast: value doesn't fit in 24 bits\");\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 * _Available since v2.5._\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\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 * _Available since v2.5._\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\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 * _Available since v3.0._\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\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 * _Available since v4.7._\n */\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\n downcasted = int248(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 248 bits\");\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 * _Available since v4.7._\n */\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\n downcasted = int240(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 240 bits\");\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 * _Available since v4.7._\n */\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\n downcasted = int232(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 232 bits\");\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 * _Available since v4.7._\n */\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\n downcasted = int224(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 224 bits\");\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 * _Available since v4.7._\n */\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\n downcasted = int216(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 216 bits\");\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 * _Available since v4.7._\n */\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\n downcasted = int208(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 208 bits\");\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 * _Available since v4.7._\n */\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\n downcasted = int200(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 200 bits\");\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 * _Available since v4.7._\n */\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\n downcasted = int192(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 192 bits\");\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 * _Available since v4.7._\n */\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\n downcasted = int184(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 184 bits\");\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 * _Available since v4.7._\n */\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\n downcasted = int176(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 176 bits\");\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 * _Available since v4.7._\n */\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\n downcasted = int168(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 168 bits\");\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 * _Available since v4.7._\n */\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\n downcasted = int160(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 160 bits\");\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 * _Available since v4.7._\n */\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\n downcasted = int152(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 152 bits\");\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 * _Available since v4.7._\n */\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\n downcasted = int144(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 144 bits\");\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 * _Available since v4.7._\n */\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\n downcasted = int136(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 136 bits\");\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 * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\n downcasted = int128(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 128 bits\");\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 * _Available since v4.7._\n */\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\n downcasted = int120(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 120 bits\");\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 * _Available since v4.7._\n */\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\n downcasted = int112(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 112 bits\");\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 * _Available since v4.7._\n */\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\n downcasted = int104(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 104 bits\");\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 * _Available since v4.7._\n */\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\n downcasted = int96(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 96 bits\");\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 * _Available since v4.7._\n */\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\n downcasted = int88(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 88 bits\");\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 * _Available since v4.7._\n */\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\n downcasted = int80(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 80 bits\");\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 * _Available since v4.7._\n */\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\n downcasted = int72(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 72 bits\");\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 * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\n downcasted = int64(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 64 bits\");\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 * _Available since v4.7._\n */\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\n downcasted = int56(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 56 bits\");\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 * _Available since v4.7._\n */\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\n downcasted = int48(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 48 bits\");\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 * _Available since v4.7._\n */\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\n downcasted = int40(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 40 bits\");\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 * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\n downcasted = int32(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 32 bits\");\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 * _Available since v4.7._\n */\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\n downcasted = int24(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 24 bits\");\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 * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\n downcasted = int16(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 16 bits\");\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 * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\n downcasted = int8(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 8 bits\");\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 * _Available since v3.0._\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 require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/SignedMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard signed math utilities missing in the Solidity language.\n */\nlibrary SignedMath {\n /**\n * @dev Returns the largest of two signed numbers.\n */\n function max(int256 a, int256 b) internal pure returns (int256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two signed numbers.\n */\n function min(int256 a, int256 b) internal pure returns (int256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two signed numbers without overflow.\n * The result is rounded towards zero.\n */\n function average(int256 a, int256 b) internal pure returns (int256) {\n // Formula from the book \"Hacker's Delight\"\n int256 x = (a & b) + ((a ^ b) >> 1);\n return x + (int256(uint256(x) >> 255) & (a ^ b));\n }\n\n /**\n * @dev Returns the absolute unsigned value of a signed value.\n */\n function abs(int256 n) internal pure returns (uint256) {\n unchecked {\n // must be unchecked in order to support `n = type(int256).min`\n return uint256(n >= 0 ? n : -n);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/Math.sol\";\nimport \"./math/SignedMath.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n unchecked {\n uint256 length = Math.log10(value) + 1;\n string memory buffer = new string(length);\n uint256 ptr;\n /// @solidity memory-safe-assembly\n assembly {\n ptr := add(buffer, add(32, length))\n }\n while (true) {\n ptr--;\n /// @solidity memory-safe-assembly\n assembly {\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n }\n value /= 10;\n if (value == 0) break;\n }\n return buffer;\n }\n }\n\n /**\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\n */\n function toString(int256 value) internal pure returns (string memory) {\n return string(abi.encodePacked(value < 0 ? \"-\" : \"\", toString(SignedMath.abs(value))));\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n unchecked {\n return toHexString(value, Math.log256(value) + 1);\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n\n /**\n * @dev Returns true if the two strings are equal.\n */\n function equal(string memory a, string memory b) internal pure returns (bool) {\n return keccak256(bytes(a)) == keccak256(bytes(b));\n }\n}\n" + }, + "contracts/aa-4337/core/BaseAccount.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-empty-blocks */\n\nimport \"../interfaces/IAccount.sol\";\nimport \"../interfaces/IEntryPoint.sol\";\nimport \"./Helpers.sol\";\n\n/**\n * Basic account implementation.\n * this contract provides the basic logic for implementing the IAccount interface - validateUserOp\n * specific account implementation should inherit it and provide the account-specific logic\n */\nabstract contract BaseAccount is IAccount {\n using UserOperationLib for UserOperation;\n\n //return value in case of signature failure, with no time-range.\n // equivalent to _packValidationData(true,0,0);\n uint256 internal constant SIG_VALIDATION_FAILED = 1;\n\n /**\n * Return the account nonce.\n * This method returns the next sequential nonce.\n * For a nonce of a specific key, use `entrypoint.getNonce(account, key)`\n */\n function getNonce() public view virtual returns (uint256) {\n return entryPoint().getNonce(address(this), 0);\n }\n\n /**\n * return the entryPoint used by this account.\n * subclass should return the current entryPoint used by this account.\n */\n function entryPoint() public view virtual returns (IEntryPoint);\n\n /**\n * Validate user's signature and nonce.\n * subclass doesn't need to override this method. Instead, it should override the specific internal validation methods.\n */\n function validateUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 missingAccountFunds\n ) external virtual override returns (uint256 validationData) {\n _requireFromEntryPoint();\n validationData = _validateSignature(userOp, userOpHash);\n _validateNonce(userOp.nonce);\n _payPrefund(missingAccountFunds);\n }\n\n /**\n * ensure the request comes from the known entrypoint.\n */\n function _requireFromEntryPoint() internal view virtual {\n require(\n msg.sender == address(entryPoint()),\n \"account: not from EntryPoint\"\n );\n }\n\n /**\n * validate the signature is valid for this message.\n * @param userOp validate the userOp.signature field\n * @param userOpHash convenient field: the hash of the request, to check the signature against\n * (also hashes the entrypoint and chain id)\n * @return validationData signature and time-range of this operation\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * If the account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function _validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) internal virtual returns (uint256 validationData);\n\n /**\n * Validate the nonce of the UserOperation.\n * This method may validate the nonce requirement of this account.\n * e.g.\n * To limit the nonce to use sequenced UserOps only (no \"out of order\" UserOps):\n * `require(nonce < type(uint64).max)`\n * For a hypothetical account that *requires* the nonce to be out-of-order:\n * `require(nonce & type(uint64).max == 0)`\n *\n * The actual nonce uniqueness is managed by the EntryPoint, and thus no other\n * action is needed by the account itself.\n *\n * @param nonce to validate\n *\n * solhint-disable-next-line no-empty-blocks\n */\n function _validateNonce(uint256 nonce) internal view virtual {}\n\n /**\n * sends to the entrypoint (msg.sender) the missing funds for this transaction.\n * subclass MAY override this method for better funds management\n * (e.g. send to the entryPoint more than the minimum required, so that in future transactions\n * it will not be required to send again)\n * @param missingAccountFunds the minimum value this method should send the entrypoint.\n * this value MAY be zero, in case there is enough deposit, or the userOp has a paymaster.\n */\n function _payPrefund(uint256 missingAccountFunds) internal virtual {\n if (missingAccountFunds != 0) {\n (bool success, ) = payable(msg.sender).call{\n value: missingAccountFunds,\n gas: type(uint256).max\n }(\"\");\n (success);\n //ignore failure (its EntryPoint's job to verify, not account.)\n }\n }\n}\n" + }, + "contracts/aa-4337/core/EntryPoint.sol": { + "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n\nimport \"../interfaces/IAccount.sol\";\nimport \"../interfaces/IPaymaster.sol\";\nimport \"../interfaces/IEntryPoint.sol\";\n\nimport \"../utils/Exec.sol\";\nimport \"./StakeManager.sol\";\nimport \"./SenderCreator.sol\";\nimport \"./Helpers.sol\";\nimport \"./NonceManager.sol\";\nimport \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\n\ncontract EntryPoint is\n IEntryPoint,\n StakeManager,\n NonceManager,\n ReentrancyGuard\n{\n using UserOperationLib for UserOperation;\n\n SenderCreator private immutable senderCreator = new SenderCreator();\n\n // internal value used during simulation: need to query aggregator.\n address private constant SIMULATE_FIND_AGGREGATOR = address(1);\n\n // marker for inner call revert on out of gas\n bytes32 private constant INNER_OUT_OF_GAS = hex\"deaddead\";\n\n uint256 private constant REVERT_REASON_MAX_LEN = 2048;\n\n /**\n * for simulation purposes, validateUserOp (and validatePaymasterUserOp) must return this value\n * in case of signature failure, instead of revert.\n */\n uint256 public constant SIG_VALIDATION_FAILED = 1;\n\n /**\n * compensate the caller's beneficiary address with the collected fees of all UserOperations.\n * @param beneficiary the address to receive the fees\n * @param amount amount to transfer.\n */\n function _compensate(address payable beneficiary, uint256 amount) internal {\n require(beneficiary != address(0), \"AA90 invalid beneficiary\");\n (bool success, ) = beneficiary.call{value: amount}(\"\");\n require(success, \"AA91 failed send to beneficiary\");\n }\n\n /**\n * execute a user op\n * @param opIndex index into the opInfo array\n * @param userOp the userOp to execute\n * @param opInfo the opInfo filled by validatePrepayment for this userOp.\n * @return collected the total amount this userOp paid.\n */\n function _executeUserOp(\n uint256 opIndex,\n UserOperation calldata userOp,\n UserOpInfo memory opInfo\n ) private returns (uint256 collected) {\n uint256 preGas = gasleft();\n bytes memory context = getMemoryBytesFromOffset(opInfo.contextOffset);\n\n try this.innerHandleOp(userOp.callData, opInfo, context) returns (\n uint256 _actualGasCost\n ) {\n collected = _actualGasCost;\n } catch {\n bytes32 innerRevertCode;\n assembly {\n returndatacopy(0, 0, 32)\n innerRevertCode := mload(0)\n }\n // handleOps was called with gas limit too low. abort entire bundle.\n if (innerRevertCode == INNER_OUT_OF_GAS) {\n //report paymaster, since if it is not deliberately caused by the bundler,\n // it must be a revert caused by paymaster.\n revert FailedOp(opIndex, \"AA95 out of gas\");\n }\n\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n collected = _handlePostOp(\n opIndex,\n IPaymaster.PostOpMode.postOpReverted,\n opInfo,\n context,\n actualGas\n );\n }\n }\n\n /**\n * Execute a batch of UserOperations.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(\n UserOperation[] calldata ops,\n address payable beneficiary\n ) public nonReentrant {\n uint256 opslen = ops.length;\n UserOpInfo[] memory opInfos = new UserOpInfo[](opslen);\n\n unchecked {\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[i];\n (\n uint256 validationData,\n uint256 pmValidationData\n ) = _validatePrepayment(i, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(\n i,\n validationData,\n pmValidationData,\n address(0)\n );\n }\n\n uint256 collected = 0;\n emit BeforeExecution();\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(i, ops[i], opInfos[i]);\n }\n\n _compensate(beneficiary, collected);\n } //unchecked\n }\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) public nonReentrant {\n uint256 opasLen = opsPerAggregator.length;\n uint256 totalOps = 0;\n for (uint256 i = 0; i < opasLen; i++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[i];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n //address(1) is special marker of \"signature error\"\n require(\n address(aggregator) != address(1),\n \"AA96 invalid aggregator\"\n );\n\n if (address(aggregator) != address(0)) {\n // solhint-disable-next-line no-empty-blocks\n try aggregator.validateSignatures(ops, opa.signature) {} catch {\n revert SignatureValidationFailed(address(aggregator));\n }\n }\n\n totalOps += ops.length;\n }\n\n UserOpInfo[] memory opInfos = new UserOpInfo[](totalOps);\n\n emit BeforeExecution();\n\n uint256 opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n uint256 opslen = ops.length;\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[opIndex];\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(opIndex, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(\n i,\n validationData,\n paymasterValidationData,\n address(aggregator)\n );\n opIndex++;\n }\n }\n\n uint256 collected = 0;\n opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n emit SignatureAggregatorChanged(address(opa.aggregator));\n UserOperation[] calldata ops = opa.userOps;\n uint256 opslen = ops.length;\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(opIndex, ops[i], opInfos[opIndex]);\n opIndex++;\n }\n }\n emit SignatureAggregatorChanged(address(0));\n\n _compensate(beneficiary, collected);\n }\n\n /// @inheritdoc IEntryPoint\n function simulateHandleOp(\n UserOperation calldata op,\n address target,\n bytes calldata targetCallData\n ) external override {\n UserOpInfo memory opInfo;\n _simulationOnlyValidations(op);\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(0, op, opInfo);\n ValidationData memory data = _intersectTimeRange(\n validationData,\n paymasterValidationData\n );\n\n numberMarker();\n uint256 paid = _executeUserOp(0, op, opInfo);\n numberMarker();\n bool targetSuccess;\n bytes memory targetResult;\n if (target != address(0)) {\n (targetSuccess, targetResult) = target.call(targetCallData);\n }\n revert ExecutionResult(\n opInfo.preOpGas,\n paid,\n data.validAfter,\n data.validUntil,\n targetSuccess,\n targetResult\n );\n }\n\n // A memory copy of UserOp static fields only.\n // Excluding: callData, initCode and signature. Replacing paymasterAndData with paymaster.\n struct MemoryUserOp {\n address sender;\n uint256 nonce;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n address paymaster;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n }\n\n struct UserOpInfo {\n MemoryUserOp mUserOp;\n bytes32 userOpHash;\n uint256 prefund;\n uint256 contextOffset;\n uint256 preOpGas;\n }\n\n /**\n * inner function to handle a UserOperation.\n * Must be declared \"external\" to open a call context, but it can only be called by handleOps.\n */\n function innerHandleOp(\n bytes memory callData,\n UserOpInfo memory opInfo,\n bytes calldata context\n ) external returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n require(msg.sender == address(this), \"AA92 internal call only\");\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n\n uint callGasLimit = mUserOp.callGasLimit;\n unchecked {\n // handleOps was called with gas limit too low. abort entire bundle.\n if (\n gasleft() < callGasLimit + mUserOp.verificationGasLimit + 5000\n ) {\n assembly {\n mstore(0, INNER_OUT_OF_GAS)\n revert(0, 32)\n }\n }\n }\n\n IPaymaster.PostOpMode mode = IPaymaster.PostOpMode.opSucceeded;\n if (callData.length > 0) {\n bool success = Exec.call(mUserOp.sender, 0, callData, callGasLimit);\n if (!success) {\n bytes memory result = Exec.getReturnData(REVERT_REASON_MAX_LEN);\n if (result.length > 0) {\n emit UserOperationRevertReason(\n opInfo.userOpHash,\n mUserOp.sender,\n mUserOp.nonce,\n result\n );\n }\n mode = IPaymaster.PostOpMode.opReverted;\n }\n }\n\n unchecked {\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n //note: opIndex is ignored (relevant only if mode==postOpReverted, which is only possible outside of innerHandleOp)\n return _handlePostOp(0, mode, opInfo, context, actualGas);\n }\n }\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(\n UserOperation calldata userOp\n ) public view returns (bytes32) {\n return\n keccak256(abi.encode(userOp.hash(), address(this), block.chainid));\n }\n\n /**\n * copy general fields from userOp into the memory opInfo structure.\n */\n function _copyUserOpToMemory(\n UserOperation calldata userOp,\n MemoryUserOp memory mUserOp\n ) internal pure {\n mUserOp.sender = userOp.sender;\n mUserOp.nonce = userOp.nonce;\n mUserOp.callGasLimit = userOp.callGasLimit;\n mUserOp.verificationGasLimit = userOp.verificationGasLimit;\n mUserOp.preVerificationGas = userOp.preVerificationGas;\n mUserOp.maxFeePerGas = userOp.maxFeePerGas;\n mUserOp.maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes calldata paymasterAndData = userOp.paymasterAndData;\n if (paymasterAndData.length > 0) {\n require(\n paymasterAndData.length >= 20,\n \"AA93 invalid paymasterAndData\"\n );\n mUserOp.paymaster = address(bytes20(paymasterAndData[:20]));\n } else {\n mUserOp.paymaster = address(0);\n }\n }\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external {\n UserOpInfo memory outOpInfo;\n\n _simulationOnlyValidations(userOp);\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(0, userOp, outOpInfo);\n StakeInfo memory paymasterInfo = _getStakeInfo(\n outOpInfo.mUserOp.paymaster\n );\n StakeInfo memory senderInfo = _getStakeInfo(outOpInfo.mUserOp.sender);\n StakeInfo memory factoryInfo;\n {\n bytes calldata initCode = userOp.initCode;\n address factory = initCode.length >= 20\n ? address(bytes20(initCode[0:20]))\n : address(0);\n factoryInfo = _getStakeInfo(factory);\n }\n\n ValidationData memory data = _intersectTimeRange(\n validationData,\n paymasterValidationData\n );\n address aggregator = data.aggregator;\n bool sigFailed = aggregator == address(1);\n ReturnInfo memory returnInfo = ReturnInfo(\n outOpInfo.preOpGas,\n outOpInfo.prefund,\n sigFailed,\n data.validAfter,\n data.validUntil,\n getMemoryBytesFromOffset(outOpInfo.contextOffset)\n );\n\n if (aggregator != address(0) && aggregator != address(1)) {\n AggregatorStakeInfo memory aggregatorInfo = AggregatorStakeInfo(\n aggregator,\n _getStakeInfo(aggregator)\n );\n revert ValidationResultWithAggregation(\n returnInfo,\n senderInfo,\n factoryInfo,\n paymasterInfo,\n aggregatorInfo\n );\n }\n revert ValidationResult(\n returnInfo,\n senderInfo,\n factoryInfo,\n paymasterInfo\n );\n }\n\n function _getRequiredPrefund(\n MemoryUserOp memory mUserOp\n ) internal pure returns (uint256 requiredPrefund) {\n unchecked {\n //when using a Paymaster, the verificationGasLimit is used also to as a limit for the postOp call.\n // our security model might call postOp eventually twice\n uint256 mul = mUserOp.paymaster != address(0) ? 3 : 1;\n uint256 requiredGas = mUserOp.callGasLimit +\n mUserOp.verificationGasLimit *\n mul +\n mUserOp.preVerificationGas;\n\n requiredPrefund = requiredGas * mUserOp.maxFeePerGas;\n }\n }\n\n // create the sender's contract if needed.\n function _createSenderIfNeeded(\n uint256 opIndex,\n UserOpInfo memory opInfo,\n bytes calldata initCode\n ) internal {\n if (initCode.length != 0) {\n address sender = opInfo.mUserOp.sender;\n if (sender.code.length != 0)\n revert FailedOp(opIndex, \"AA10 sender already constructed\");\n address sender1 = senderCreator.createSender{\n gas: opInfo.mUserOp.verificationGasLimit\n }(initCode);\n if (sender1 == address(0))\n revert FailedOp(opIndex, \"AA13 initCode failed or OOG\");\n if (sender1 != sender)\n revert FailedOp(opIndex, \"AA14 initCode must return sender\");\n if (sender1.code.length == 0)\n revert FailedOp(opIndex, \"AA15 initCode must create sender\");\n address factory = address(bytes20(initCode[0:20]));\n emit AccountDeployed(\n opInfo.userOpHash,\n sender,\n factory,\n opInfo.mUserOp.paymaster\n );\n }\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes calldata initCode) public {\n address sender = senderCreator.createSender(initCode);\n revert SenderAddressResult(sender);\n }\n\n function _simulationOnlyValidations(\n UserOperation calldata userOp\n ) internal view {\n // solhint-disable-next-line no-empty-blocks\n try\n this._validateSenderAndPaymaster(\n userOp.initCode,\n userOp.sender,\n userOp.paymasterAndData\n )\n {} catch Error(string memory revertReason) {\n if (bytes(revertReason).length != 0) {\n revert FailedOp(0, revertReason);\n }\n }\n }\n\n /**\n * Called only during simulation.\n * This function always reverts to prevent warm/cold storage differentiation in simulation vs execution.\n */\n function _validateSenderAndPaymaster(\n bytes calldata initCode,\n address sender,\n bytes calldata paymasterAndData\n ) external view {\n if (initCode.length == 0 && sender.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA20 account not deployed\");\n }\n if (paymasterAndData.length >= 20) {\n address paymaster = address(bytes20(paymasterAndData[0:20]));\n if (paymaster.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA30 paymaster not deployed\");\n }\n }\n // always revert\n revert(\"\");\n }\n\n /**\n * call account.validateUserOp.\n * revert (with FailedOp) in case validateUserOp reverts, or account didn't send required prefund.\n * decrement account's deposit if needed\n */\n function _validateAccountPrepayment(\n uint256 opIndex,\n UserOperation calldata op,\n UserOpInfo memory opInfo,\n uint256 requiredPrefund\n )\n internal\n returns (\n uint256 gasUsedByValidateAccountPrepayment,\n uint256 validationData\n )\n {\n unchecked {\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n address sender = mUserOp.sender;\n _createSenderIfNeeded(opIndex, opInfo, op.initCode);\n address paymaster = mUserOp.paymaster;\n numberMarker();\n uint256 missingAccountFunds = 0;\n if (paymaster == address(0)) {\n uint256 bal = balanceOf(sender);\n missingAccountFunds = bal > requiredPrefund\n ? 0\n : requiredPrefund - bal;\n }\n try\n IAccount(sender).validateUserOp{\n gas: mUserOp.verificationGasLimit\n }(op, opInfo.userOpHash, missingAccountFunds)\n returns (uint256 _validationData) {\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA23 reverted: \", revertReason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA23 reverted (or OOG)\");\n }\n if (paymaster == address(0)) {\n DepositInfo storage senderInfo = deposits[sender];\n uint256 deposit = senderInfo.deposit;\n if (requiredPrefund > deposit) {\n revert FailedOp(opIndex, \"AA21 didn't pay prefund\");\n }\n senderInfo.deposit = uint112(deposit - requiredPrefund);\n }\n gasUsedByValidateAccountPrepayment = preGas - gasleft();\n }\n }\n\n /**\n * In case the request has a paymaster:\n * Validate paymaster has enough deposit.\n * Call paymaster.validatePaymasterUserOp.\n * Revert with proper FailedOp in case paymaster reverts.\n * Decrement paymaster's deposit\n */\n function _validatePaymasterPrepayment(\n uint256 opIndex,\n UserOperation calldata op,\n UserOpInfo memory opInfo,\n uint256 requiredPreFund,\n uint256 gasUsedByValidateAccountPrepayment\n ) internal returns (bytes memory context, uint256 validationData) {\n unchecked {\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 verificationGasLimit = mUserOp.verificationGasLimit;\n require(\n verificationGasLimit > gasUsedByValidateAccountPrepayment,\n \"AA41 too little verificationGas\"\n );\n uint256 gas = verificationGasLimit -\n gasUsedByValidateAccountPrepayment;\n\n address paymaster = mUserOp.paymaster;\n DepositInfo storage paymasterInfo = deposits[paymaster];\n uint256 deposit = paymasterInfo.deposit;\n if (deposit < requiredPreFund) {\n revert FailedOp(opIndex, \"AA31 paymaster deposit too low\");\n }\n paymasterInfo.deposit = uint112(deposit - requiredPreFund);\n try\n IPaymaster(paymaster).validatePaymasterUserOp{gas: gas}(\n op,\n opInfo.userOpHash,\n requiredPreFund\n )\n returns (bytes memory _context, uint256 _validationData) {\n context = _context;\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA33 reverted: \", revertReason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA33 reverted (or OOG)\");\n }\n }\n }\n\n /**\n * revert if either account validationData or paymaster validationData is expired\n */\n function _validateAccountAndPaymasterValidationData(\n uint256 opIndex,\n uint256 validationData,\n uint256 paymasterValidationData,\n address expectedAggregator\n ) internal view {\n (address aggregator, bool outOfTimeRange) = _getValidationData(\n validationData\n );\n if (expectedAggregator != aggregator) {\n revert FailedOp(opIndex, \"AA24 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA22 expired or not due\");\n }\n //pmAggregator is not a real signature aggregator: we don't have logic to handle it as address.\n // non-zero address means that the paymaster fails due to some signature check (which is ok only during estimation)\n address pmAggregator;\n (pmAggregator, outOfTimeRange) = _getValidationData(\n paymasterValidationData\n );\n if (pmAggregator != address(0)) {\n revert FailedOp(opIndex, \"AA34 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA32 paymaster expired or not due\");\n }\n }\n\n function _getValidationData(\n uint256 validationData\n ) internal view returns (address aggregator, bool outOfTimeRange) {\n if (validationData == 0) {\n return (address(0), false);\n }\n ValidationData memory data = _parseValidationData(validationData);\n // solhint-disable-next-line not-rely-on-time\n outOfTimeRange =\n block.timestamp > data.validUntil ||\n block.timestamp < data.validAfter;\n aggregator = data.aggregator;\n }\n\n /**\n * validate account and paymaster (if defined).\n * also make sure total validation doesn't exceed verificationGasLimit\n * this method is called off-chain (simulateValidation()) and on-chain (from handleOps)\n * @param opIndex the index of this userOp into the \"opInfos\" array\n * @param userOp the userOp to validate\n */\n function _validatePrepayment(\n uint256 opIndex,\n UserOperation calldata userOp,\n UserOpInfo memory outOpInfo\n )\n private\n returns (uint256 validationData, uint256 paymasterValidationData)\n {\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = outOpInfo.mUserOp;\n _copyUserOpToMemory(userOp, mUserOp);\n outOpInfo.userOpHash = getUserOpHash(userOp);\n\n // validate all numeric values in userOp are well below 128 bit, so they can safely be added\n // and multiplied without causing overflow\n uint256 maxGasValues = mUserOp.preVerificationGas |\n mUserOp.verificationGasLimit |\n mUserOp.callGasLimit |\n userOp.maxFeePerGas |\n userOp.maxPriorityFeePerGas;\n require(maxGasValues <= type(uint120).max, \"AA94 gas values overflow\");\n\n uint256 gasUsedByValidateAccountPrepayment;\n uint256 requiredPreFund = _getRequiredPrefund(mUserOp);\n (\n gasUsedByValidateAccountPrepayment,\n validationData\n ) = _validateAccountPrepayment(\n opIndex,\n userOp,\n outOpInfo,\n requiredPreFund\n );\n\n if (!_validateAndUpdateNonce(mUserOp.sender, mUserOp.nonce)) {\n revert FailedOp(opIndex, \"AA25 invalid account nonce\");\n }\n\n //a \"marker\" where account opcode validation is done and paymaster opcode validation is about to start\n // (used only by off-chain simulateValidation)\n numberMarker();\n\n bytes memory context;\n if (mUserOp.paymaster != address(0)) {\n (context, paymasterValidationData) = _validatePaymasterPrepayment(\n opIndex,\n userOp,\n outOpInfo,\n requiredPreFund,\n gasUsedByValidateAccountPrepayment\n );\n }\n unchecked {\n uint256 gasUsed = preGas - gasleft();\n\n if (userOp.verificationGasLimit < gasUsed) {\n revert FailedOp(opIndex, \"AA40 over verificationGasLimit\");\n }\n outOpInfo.prefund = requiredPreFund;\n outOpInfo.contextOffset = getOffsetOfMemoryBytes(context);\n outOpInfo.preOpGas = preGas - gasleft() + userOp.preVerificationGas;\n }\n }\n\n /**\n * process post-operation.\n * called just after the callData is executed.\n * if a paymaster is defined and its validation returned a non-empty context, its postOp is called.\n * the excess amount is refunded to the account (or paymaster - if it was used in the request)\n * @param opIndex index in the batch\n * @param mode - whether is called from innerHandleOp, or outside (postOpReverted)\n * @param opInfo userOp fields and info collected during validation\n * @param context the context returned in validatePaymasterUserOp\n * @param actualGas the gas used so far by this user operation\n */\n function _handlePostOp(\n uint256 opIndex,\n IPaymaster.PostOpMode mode,\n UserOpInfo memory opInfo,\n bytes memory context,\n uint256 actualGas\n ) private returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n unchecked {\n address refundAddress;\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 gasPrice = getUserOpGasPrice(mUserOp);\n\n address paymaster = mUserOp.paymaster;\n if (paymaster == address(0)) {\n refundAddress = mUserOp.sender;\n } else {\n refundAddress = paymaster;\n if (context.length > 0) {\n actualGasCost = actualGas * gasPrice;\n if (mode != IPaymaster.PostOpMode.postOpReverted) {\n IPaymaster(paymaster).postOp{\n gas: mUserOp.verificationGasLimit\n }(mode, context, actualGasCost);\n } else {\n // solhint-disable-next-line no-empty-blocks\n try\n IPaymaster(paymaster).postOp{\n gas: mUserOp.verificationGasLimit\n }(mode, context, actualGasCost)\n {} catch Error(string memory reason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA50 postOp reverted: \", reason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA50 postOp revert\");\n }\n }\n }\n }\n actualGas += preGas - gasleft();\n actualGasCost = actualGas * gasPrice;\n if (opInfo.prefund < actualGasCost) {\n revert FailedOp(opIndex, \"AA51 prefund below actualGasCost\");\n }\n uint256 refund = opInfo.prefund - actualGasCost;\n _incrementDeposit(refundAddress, refund);\n bool success = mode == IPaymaster.PostOpMode.opSucceeded;\n emit UserOperationEvent(\n opInfo.userOpHash,\n mUserOp.sender,\n mUserOp.paymaster,\n mUserOp.nonce,\n success,\n actualGasCost,\n actualGas\n );\n } // unchecked\n }\n\n /**\n * the gas price this UserOp agrees to pay.\n * relayer/block builder might submit the TX with higher priorityFee, but the user should not\n */\n function getUserOpGasPrice(\n MemoryUserOp memory mUserOp\n ) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = mUserOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = mUserOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n function getOffsetOfMemoryBytes(\n bytes memory data\n ) internal pure returns (uint256 offset) {\n assembly {\n offset := data\n }\n }\n\n function getMemoryBytesFromOffset(\n uint256 offset\n ) internal pure returns (bytes memory data) {\n assembly {\n data := offset\n }\n }\n\n //place the NUMBER opcode in the code.\n // this is used as a marker during simulation, as this OP is completely banned from the simulated code of the\n // account and paymaster.\n function numberMarker() internal view {\n assembly {\n mstore(0, number())\n }\n }\n}\n" + }, + "contracts/aa-4337/core/Helpers.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable no-inline-assembly */\n\n/**\n * returned data from validateUserOp.\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\n * @param aggregator - address(0) - the account validated the signature by itself.\n * address(1) - the account failed to validate the signature.\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\n * @param validAfter - this UserOp is valid only after this timestamp.\n * @param validaUntil - this UserOp is valid only up to this timestamp.\n */\nstruct ValidationData {\n address aggregator;\n uint48 validAfter;\n uint48 validUntil;\n}\n\n//extract sigFailed, validAfter, validUntil.\n// also convert zero validUntil to type(uint48).max\nfunction _parseValidationData(\n uint validationData\n) pure returns (ValidationData memory data) {\n address aggregator = address(uint160(validationData));\n uint48 validUntil = uint48(validationData >> 160);\n if (validUntil == 0) {\n validUntil = type(uint48).max;\n }\n uint48 validAfter = uint48(validationData >> (48 + 160));\n return ValidationData(aggregator, validAfter, validUntil);\n}\n\n// intersect account and paymaster ranges.\nfunction _intersectTimeRange(\n uint256 validationData,\n uint256 paymasterValidationData\n) pure returns (ValidationData memory) {\n ValidationData memory accountValidationData = _parseValidationData(\n validationData\n );\n ValidationData memory pmValidationData = _parseValidationData(\n paymasterValidationData\n );\n address aggregator = accountValidationData.aggregator;\n if (aggregator == address(0)) {\n aggregator = pmValidationData.aggregator;\n }\n uint48 validAfter = accountValidationData.validAfter;\n uint48 validUntil = accountValidationData.validUntil;\n uint48 pmValidAfter = pmValidationData.validAfter;\n uint48 pmValidUntil = pmValidationData.validUntil;\n\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\n return ValidationData(aggregator, validAfter, validUntil);\n}\n\n/**\n * helper to pack the return value for validateUserOp\n * @param data - the ValidationData to pack\n */\nfunction _packValidationData(\n ValidationData memory data\n) pure returns (uint256) {\n return\n uint160(data.aggregator) |\n (uint256(data.validUntil) << 160) |\n (uint256(data.validAfter) << (160 + 48));\n}\n\n/**\n * helper to pack the return value for validateUserOp, when not using an aggregator\n * @param sigFailed - true for signature failure, false for success\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\n * @param validAfter first timestamp this UserOperation is valid\n */\nfunction _packValidationData(\n bool sigFailed,\n uint48 validUntil,\n uint48 validAfter\n) pure returns (uint256) {\n return\n (sigFailed ? 1 : 0) |\n (uint256(validUntil) << 160) |\n (uint256(validAfter) << (160 + 48));\n}\n\n/**\n * keccak function over calldata.\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\n */\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\n assembly {\n let mem := mload(0x40)\n let len := data.length\n calldatacopy(mem, data.offset, len)\n ret := keccak256(mem, len)\n }\n}\n" + }, + "contracts/aa-4337/core/NonceManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\nimport \"../interfaces/IEntryPoint.sol\";\n\n/**\n * nonce management functionality\n */\ncontract NonceManager is INonceManager {\n /**\n * The next valid sequence number for a given nonce key.\n */\n mapping(address => mapping(uint192 => uint256)) public nonceSequenceNumber;\n\n function getNonce(\n address sender,\n uint192 key\n ) public view override returns (uint256 nonce) {\n return nonceSequenceNumber[sender][key] | (uint256(key) << 64);\n }\n\n // allow an account to manually increment its own nonce.\n // (mainly so that during construction nonce can be made non-zero,\n // to \"absorb\" the gas cost of first nonce increment to 1st transaction (construction),\n // not to 2nd transaction)\n function incrementNonce(uint192 key) public override {\n nonceSequenceNumber[msg.sender][key]++;\n }\n\n /**\n * validate nonce uniqueness for this account.\n * called just after validateUserOp()\n */\n function _validateAndUpdateNonce(\n address sender,\n uint256 nonce\n ) internal returns (bool) {\n uint192 key = uint192(nonce >> 64);\n uint64 seq = uint64(nonce);\n return nonceSequenceNumber[sender][key]++ == seq;\n }\n}\n" + }, + "contracts/aa-4337/core/SenderCreator.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/**\n * helper contract for EntryPoint, to call userOp.initCode from a \"neutral\" address,\n * which is explicitly not the entryPoint itself.\n */\ncontract SenderCreator {\n /**\n * call the \"initCode\" factory to create and return the sender account address\n * @param initCode the initCode value from a UserOp. contains 20 bytes of factory address, followed by calldata\n * @return sender the returned address of the created account, or zero address on failure.\n */\n function createSender(\n bytes calldata initCode\n ) external returns (address sender) {\n address factory = address(bytes20(initCode[0:20]));\n bytes memory initCallData = initCode[20:];\n bool success;\n /* solhint-disable no-inline-assembly */\n assembly {\n success := call(\n gas(),\n factory,\n 0,\n add(initCallData, 0x20),\n mload(initCallData),\n 0,\n 32\n )\n sender := mload(0)\n }\n if (!success) {\n sender = address(0);\n }\n }\n}\n" + }, + "contracts/aa-4337/core/StakeManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity 0.8.21;\n\nimport \"../interfaces/IStakeManager.sol\";\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable not-rely-on-time */\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by a paymaster.\n */\nabstract contract StakeManager is IStakeManager {\n /// maps paymaster to their deposits and stakes\n mapping(address => DepositInfo) public deposits;\n\n /// @inheritdoc IStakeManager\n function getDepositInfo(\n address account\n ) public view returns (DepositInfo memory info) {\n return deposits[account];\n }\n\n // internal method to return just the stake info\n function _getStakeInfo(\n address addr\n ) internal view returns (StakeInfo memory info) {\n DepositInfo storage depositInfo = deposits[addr];\n info.stake = depositInfo.stake;\n info.unstakeDelaySec = depositInfo.unstakeDelaySec;\n }\n\n /// return the deposit (for gas payment) of the account\n function balanceOf(address account) public view returns (uint256) {\n return deposits[account].deposit;\n }\n\n receive() external payable {\n depositTo(msg.sender);\n }\n\n function _incrementDeposit(address account, uint256 amount) internal {\n DepositInfo storage info = deposits[account];\n uint256 newAmount = info.deposit + amount;\n require(newAmount <= type(uint112).max, \"deposit overflow\");\n info.deposit = uint112(newAmount);\n }\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) public payable {\n _incrementDeposit(account, msg.value);\n DepositInfo storage info = deposits[account];\n emit Deposited(account, info.deposit);\n }\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 unstakeDelaySec) public payable {\n DepositInfo storage info = deposits[msg.sender];\n require(unstakeDelaySec > 0, \"must specify unstake delay\");\n require(\n unstakeDelaySec >= info.unstakeDelaySec,\n \"cannot decrease unstake time\"\n );\n uint256 stake = info.stake + msg.value;\n require(stake > 0, \"no stake specified\");\n require(stake <= type(uint112).max, \"stake overflow\");\n deposits[msg.sender] = DepositInfo(\n info.deposit,\n true,\n uint112(stake),\n unstakeDelaySec,\n 0\n );\n emit StakeLocked(msg.sender, stake, unstakeDelaySec);\n }\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external {\n DepositInfo storage info = deposits[msg.sender];\n require(info.unstakeDelaySec != 0, \"not staked\");\n require(info.staked, \"already unstaking\");\n uint48 withdrawTime = uint48(block.timestamp) + info.unstakeDelaySec;\n info.withdrawTime = withdrawTime;\n info.staked = false;\n emit StakeUnlocked(msg.sender, withdrawTime);\n }\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external {\n DepositInfo storage info = deposits[msg.sender];\n uint256 stake = info.stake;\n require(stake > 0, \"No stake to withdraw\");\n require(info.withdrawTime > 0, \"must call unlockStake() first\");\n require(\n info.withdrawTime <= block.timestamp,\n \"Stake withdrawal is not due\"\n );\n info.unstakeDelaySec = 0;\n info.withdrawTime = 0;\n info.stake = 0;\n emit StakeWithdrawn(msg.sender, withdrawAddress, stake);\n (bool success, ) = withdrawAddress.call{value: stake}(\"\");\n require(success, \"failed to withdraw stake\");\n }\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(\n address payable withdrawAddress,\n uint256 withdrawAmount\n ) external {\n DepositInfo storage info = deposits[msg.sender];\n require(withdrawAmount <= info.deposit, \"Withdraw amount too large\");\n info.deposit = uint112(info.deposit - withdrawAmount);\n emit Withdrawn(msg.sender, withdrawAddress, withdrawAmount);\n (bool success, ) = withdrawAddress.call{value: withdrawAmount}(\"\");\n require(success, \"failed to withdraw\");\n }\n}\n" + }, + "contracts/aa-4337/interfaces/IAccount.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\ninterface IAccount {\n /**\n * Validate user's signature and nonce\n * the entryPoint will make the call to the recipient only if this validation call returns successfully.\n * signature failure should be reported by returning SIG_VALIDATION_FAILED (1).\n * This allows making a \"simulation call\" without a valid signature\n * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure.\n *\n * @dev Must validate caller is the entryPoint.\n * Must validate the signature and nonce\n * @param userOp the operation that is about to be executed.\n * @param userOpHash hash of the user's request data. can be used as the basis for signature.\n * @param missingAccountFunds missing funds on the account's deposit in the entrypoint.\n * This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call.\n * The excess is left as a deposit in the entrypoint, for future calls.\n * can be withdrawn anytime using \"entryPoint.withdrawTo()\"\n * In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero.\n * @return validationData packaged ValidationData structure. use `_packValidationData` and `_unpackValidationData` to encode and decode\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * If an account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validateUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 missingAccountFunds\n ) external returns (uint256 validationData);\n}\n" + }, + "contracts/aa-4337/interfaces/IAggregator.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * Aggregated Signatures validator.\n */\ninterface IAggregator {\n /**\n * validate aggregated signature.\n * revert if the aggregated signature does not match the given list of operations.\n */\n function validateSignatures(\n UserOperation[] calldata userOps,\n bytes calldata signature\n ) external view;\n\n /**\n * validate signature of a single userOp\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\n * @param userOp the userOperation received from the user.\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\n * (usually empty, unless account and aggregator support some kind of \"multisig\"\n */\n function validateUserOpSignature(\n UserOperation calldata userOp\n ) external view returns (bytes memory sigForUserOp);\n\n /**\n * aggregate multiple signatures into a single value.\n * This method is called off-chain to calculate the signature to pass with handleOps()\n * bundler MAY use optimized custom code perform this aggregation\n * @param userOps array of UserOperations to collect the signatures from.\n * @return aggregatedSignature the aggregated signature\n */\n function aggregateSignatures(\n UserOperation[] calldata userOps\n ) external view returns (bytes memory aggregatedSignature);\n}\n" + }, + "contracts/aa-4337/interfaces/IEntryPoint.sol": { + "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n/* solhint-disable reason-string */\n\nimport \"./UserOperation.sol\";\nimport \"./IStakeManager.sol\";\nimport \"./IAggregator.sol\";\nimport \"./INonceManager.sol\";\n\ninterface IEntryPoint is IStakeManager, INonceManager {\n /***\n * An event emitted after each successful request\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\n * @param sender - the account that generates this request.\n * @param paymaster - if non-null, the paymaster that pays for this request.\n * @param nonce - the nonce value from the request.\n * @param success - true if the sender transaction succeeded, false if reverted.\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\n */\n event UserOperationEvent(\n bytes32 indexed userOpHash,\n address indexed sender,\n address indexed paymaster,\n uint256 nonce,\n bool success,\n uint256 actualGasCost,\n uint256 actualGasUsed\n );\n\n /**\n * account \"sender\" was deployed.\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\n * @param sender the account that is deployed\n * @param factory the factory used to deploy this account (in the initCode)\n * @param paymaster the paymaster used by this UserOp\n */\n event AccountDeployed(\n bytes32 indexed userOpHash,\n address indexed sender,\n address factory,\n address paymaster\n );\n\n /**\n * An event emitted if the UserOperation \"callData\" reverted with non-zero length\n * @param userOpHash the request unique identifier.\n * @param sender the sender of this request\n * @param nonce the nonce used in the request\n * @param revertReason - the return bytes from the (reverted) call to \"callData\".\n */\n event UserOperationRevertReason(\n bytes32 indexed userOpHash,\n address indexed sender,\n uint256 nonce,\n bytes revertReason\n );\n\n /**\n * an event emitted by handleOps(), before starting the execution loop.\n * any event emitted before this event, is part of the validation.\n */\n event BeforeExecution();\n\n /**\n * signature aggregator used by the following UserOperationEvents within this bundle.\n */\n event SignatureAggregatorChanged(address indexed aggregator);\n\n /**\n * a custom revert error of handleOps, to identify the offending op.\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\n * @param reason - revert reason\n * The string starts with a unique code \"AAmn\", where \"m\" is \"1\" for factory, \"2\" for account and \"3\" for paymaster issues,\n * so a failure can be attributed to the correct entity.\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\n */\n error FailedOp(uint256 opIndex, string reason);\n\n /**\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\n */\n error SignatureValidationFailed(address aggregator);\n\n /**\n * Successful result from simulateValidation.\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n */\n error ValidationResult(\n ReturnInfo returnInfo,\n StakeInfo senderInfo,\n StakeInfo factoryInfo,\n StakeInfo paymasterInfo\n );\n\n /**\n * Successful result from simulateValidation, if the account returns a signature aggregator\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\n * bundler MUST use it to verify the signature, or reject the UserOperation\n */\n error ValidationResultWithAggregation(\n ReturnInfo returnInfo,\n StakeInfo senderInfo,\n StakeInfo factoryInfo,\n StakeInfo paymasterInfo,\n AggregatorStakeInfo aggregatorInfo\n );\n\n /**\n * return value of getSenderAddress\n */\n error SenderAddressResult(address sender);\n\n /**\n * return value of simulateHandleOp\n */\n error ExecutionResult(\n uint256 preOpGas,\n uint256 paid,\n uint48 validAfter,\n uint48 validUntil,\n bool targetSuccess,\n bytes targetResult\n );\n\n //UserOps handled, per aggregator\n struct UserOpsPerAggregator {\n UserOperation[] userOps;\n // aggregator address\n IAggregator aggregator;\n // aggregated signature\n bytes signature;\n }\n\n /**\n * Execute a batch of UserOperation.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(\n UserOperation[] calldata ops,\n address payable beneficiary\n ) external;\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) external;\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(\n UserOperation calldata userOp\n ) external view returns (bytes32);\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external;\n\n /**\n * gas and return values during simulation\n * @param preOpGas the gas used for validation (including preValidationGas)\n * @param prefund the required prefund for this operation\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\n */\n struct ReturnInfo {\n uint256 preOpGas;\n uint256 prefund;\n bool sigFailed;\n uint48 validAfter;\n uint48 validUntil;\n bytes paymasterContext;\n }\n\n /**\n * returned aggregated signature info.\n * the aggregator returned by the account, and its current stake.\n */\n struct AggregatorStakeInfo {\n address aggregator;\n StakeInfo stakeInfo;\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes memory initCode) external;\n\n /**\n * simulate full execution of a UserOperation (including both validation and target execution)\n * this method will always revert with \"ExecutionResult\".\n * it performs full validation of the UserOperation, but ignores signature error.\n * an optional target address is called after the userop succeeds, and its value is returned\n * (before the entire call is reverted)\n * Note that in order to collect the the success/failure of the target call, it must be executed\n * with trace enabled to track the emitted events.\n * @param op the UserOperation to simulate\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\n * are set to the return from that call.\n * @param targetCallData callData to pass to target address\n */\n function simulateHandleOp(\n UserOperation calldata op,\n address target,\n bytes calldata targetCallData\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/INonceManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\ninterface INonceManager {\n /**\n * Return the next nonce for this sender.\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\n * But UserOp with different keys can come with arbitrary order.\n *\n * @param sender the account address\n * @param key the high 192 bit of the nonce\n * @return nonce a full nonce to pass for next UserOp with this sender.\n */\n function getNonce(\n address sender,\n uint192 key\n ) external view returns (uint256 nonce);\n\n /**\n * Manually increment the nonce of the sender.\n * This method is exposed just for completeness..\n * Account does NOT need to call it, neither during validation, nor elsewhere,\n * as the EntryPoint will update the nonce regardless.\n * Possible use-case is call it with various keys to \"initialize\" their nonces to one, so that future\n * UserOperations will not pay extra for the first transaction with a given key.\n */\n function incrementNonce(uint192 key) external;\n}\n" + }, + "contracts/aa-4337/interfaces/IPaymaster.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * the interface exposed by a paymaster contract, who agrees to pay the gas for user's operations.\n * a paymaster must hold a stake to cover the required entrypoint stake and also the gas for the transaction.\n */\ninterface IPaymaster {\n enum PostOpMode {\n opSucceeded, // user op succeeded\n opReverted, // user op reverted. still has to pay for gas.\n postOpReverted //user op succeeded, but caused postOp to revert. Now it's a 2nd call, after user's op was deliberately reverted.\n }\n\n /**\n * payment validation: check if paymaster agrees to pay.\n * Must verify sender is the entryPoint.\n * Revert to reject this request.\n * Note that bundlers will reject this method if it changes the state, unless the paymaster is trusted (whitelisted)\n * The paymaster pre-pays using its deposit, and receive back a refund after the postOp method returns.\n * @param userOp the user operation\n * @param userOpHash hash of the user's request data.\n * @param maxCost the maximum cost of this transaction (based on maximum gas and gas price from userOp)\n * @return context value to send to a postOp\n * zero length to signify postOp is not required.\n * @return validationData signature and time-range of this operation, encoded the same as the return value of validateUserOperation\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validatePaymasterUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 maxCost\n ) external returns (bytes memory context, uint256 validationData);\n\n /**\n * post-operation handler.\n * Must verify sender is the entryPoint\n * @param mode enum with the following options:\n * opSucceeded - user operation succeeded.\n * opReverted - user op reverted. still has to pay for gas.\n * postOpReverted - user op succeeded, but caused postOp (in mode=opSucceeded) to revert.\n * Now this is the 2nd call, after user's op was deliberately reverted.\n * @param context - the context value returned by validatePaymasterUserOp\n * @param actualGasCost - actual gas used so far (without this postOp call).\n */\n function postOp(\n PostOpMode mode,\n bytes calldata context,\n uint256 actualGasCost\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/IStakeManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.12;\n\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by the staked entity.\n */\ninterface IStakeManager {\n event Deposited(address indexed account, uint256 totalDeposit);\n\n event Withdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /// Emitted when stake or unstake delay are modified\n event StakeLocked(\n address indexed account,\n uint256 totalStaked,\n uint256 unstakeDelaySec\n );\n\n /// Emitted once a stake is scheduled for withdrawal\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\n\n event StakeWithdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /**\n * @param deposit the entity's deposit\n * @param staked true if this entity is staked.\n * @param stake actual amount of ether staked for this entity.\n * @param unstakeDelaySec minimum delay to withdraw the stake.\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\n * and the rest fit into a 2nd cell.\n * 112 bit allows for 10^15 eth\n * 48 bit for full timestamp\n * 32 bit allows 150 years for unstake delay\n */\n struct DepositInfo {\n uint112 deposit;\n bool staked;\n uint112 stake;\n uint32 unstakeDelaySec;\n uint48 withdrawTime;\n }\n\n //API struct used by getStakeInfo and simulateValidation\n struct StakeInfo {\n uint256 stake;\n uint256 unstakeDelaySec;\n }\n\n /// @return info - full deposit information of given account\n function getDepositInfo(\n address account\n ) external view returns (DepositInfo memory info);\n\n /// @return the deposit (for gas payment) of the account\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) external payable;\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 _unstakeDelaySec) external payable;\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external;\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external;\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(\n address payable withdrawAddress,\n uint256 withdrawAmount\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/UserOperation.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable no-inline-assembly */\n\nimport {calldataKeccak} from \"../core/Helpers.sol\";\n\n/**\n * User Operation struct\n * @param sender the sender account of this request.\n * @param nonce unique value the sender uses to verify it is not a replay.\n * @param initCode if set, the account contract will be created by this constructor/\n * @param callData the method call to execute on this account.\n * @param callGasLimit the gas limit passed to the callData method call.\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\n * @param maxFeePerGas same as EIP-1559 gas parameter.\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\n */\nstruct UserOperation {\n address sender;\n uint256 nonce;\n bytes initCode;\n bytes callData;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n bytes paymasterAndData;\n bytes signature;\n}\n\n/**\n * Utility functions helpful when working with UserOperation structs.\n */\nlibrary UserOperationLib {\n function getSender(\n UserOperation calldata userOp\n ) internal pure returns (address) {\n address data;\n //read sender from userOp, which is first userOp member (saves 800 gas...)\n assembly {\n data := calldataload(userOp)\n }\n return address(uint160(data));\n }\n\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\n // pay above what he signed for.\n function gasPrice(\n UserOperation calldata userOp\n ) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function pack(\n UserOperation calldata userOp\n ) internal pure returns (bytes memory ret) {\n address sender = getSender(userOp);\n uint256 nonce = userOp.nonce;\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\n bytes32 hashCallData = calldataKeccak(userOp.callData);\n uint256 callGasLimit = userOp.callGasLimit;\n uint256 verificationGasLimit = userOp.verificationGasLimit;\n uint256 preVerificationGas = userOp.preVerificationGas;\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\n\n return\n abi.encode(\n sender,\n nonce,\n hashInitCode,\n hashCallData,\n callGasLimit,\n verificationGasLimit,\n preVerificationGas,\n maxFeePerGas,\n maxPriorityFeePerGas,\n hashPaymasterAndData\n );\n }\n\n function hash(\n UserOperation calldata userOp\n ) internal pure returns (bytes32) {\n return keccak256(pack(userOp));\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n}\n" + }, + "contracts/aa-4337/utils/Exec.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.5 <0.9.0;\n\n// solhint-disable no-inline-assembly\n\n/**\n * Utility functions helpful when making different kinds of contract calls in Solidity.\n */\nlibrary Exec {\n function call(\n address to,\n uint256 value,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := call(\n txGas,\n to,\n value,\n add(data, 0x20),\n mload(data),\n 0,\n 0\n )\n }\n }\n\n function staticcall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal view returns (bool success) {\n assembly {\n success := staticcall(txGas, to, add(data, 0x20), mload(data), 0, 0)\n }\n }\n\n function delegateCall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := delegatecall(\n txGas,\n to,\n add(data, 0x20),\n mload(data),\n 0,\n 0\n )\n }\n }\n\n // get returned data from last call or calldelegate\n function getReturnData(\n uint256 maxLen\n ) internal pure returns (bytes memory returnData) {\n assembly {\n let len := returndatasize()\n if gt(len, maxLen) {\n len := maxLen\n }\n let ptr := mload(0x40)\n mstore(0x40, add(ptr, add(len, 0x20)))\n mstore(ptr, len)\n returndatacopy(add(ptr, 0x20), 0, len)\n returnData := ptr\n }\n }\n\n // revert with explicit byte array (probably reverted info from call)\n function revertWithData(bytes memory returnData) internal pure {\n assembly {\n revert(add(returnData, 32), mload(returnData))\n }\n }\n\n function callAndRevert(\n address to,\n bytes memory data,\n uint256 maxLen\n ) internal {\n bool success = call(to, 0, data, gasleft());\n if (!success) {\n revertWithData(getReturnData(maxLen));\n }\n }\n}\n" + }, + "contracts/Barz.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"./libraries/LibDiamond.sol\";\nimport {IBarz} from \"./interfaces/IBarz.sol\";\n\n/**\n * @title Barz\n * @dev A diamond proxy wallet with a modular & upgradeable architecture\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract Barz is IBarz {\n /**\n * @notice Initializes Barz with the given parameters. Barz account is intended to be created from Barz Factory for stable deployment.\n * @dev This method makes a delegate call to account facet and account facet handles the initialization.\n * With modular architecture, Barz encompasses wide spectrum of architecture and logic.\n * The only requirement is account facet to comply with initialize() interface.\n * Barz doesn't include built-in functions and is a full proxy, for maximum extensibility and modularity.\n * @param _accountFacet Address of Account Facet in charge of the Barz initialization\n * @param _verificationFacet Address of Verification Facet for verifying the signature. Could be any signature scheme\n * @param _entryPoint Address of Entry Point contract\n * @param _facetRegistry Address of Facet Registry. Facet Registry is a registry holding trusted facets that could be added to user's wallet\n * @param _defaultFallBack Address of Default FallBack Handler. Middleware contract for more efficient deployment\n * @param _ownerPublicKey Bytes of Owner Public Key using for initialization\n */\n constructor(\n address _accountFacet,\n address _verificationFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallBack,\n bytes memory _ownerPublicKey\n ) payable {\n bytes memory initCall = abi.encodeWithSignature(\n \"initialize(address,address,address,address,bytes)\",\n _verificationFacet,\n _entryPoint,\n _facetRegistry,\n _defaultFallBack,\n _ownerPublicKey\n );\n (bool success, bytes memory result) = _accountFacet.delegatecall(\n initCall\n );\n if (!success || uint256(bytes32(result)) != 1) {\n revert Barz__InitializationFailure();\n }\n }\n\n /**\n * @notice Fallback function for Barz complying with Diamond Standard with customization of adding Default Fallback Handler\n * @dev Find facet for function that is called and execute the function if a facet is found and return any value.\n */\n fallback() external payable {\n LibDiamond.DiamondStorage storage ds;\n bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION;\n // get diamond storage\n assembly {\n ds.slot := position\n }\n // get facet from function selector\n address facet = address(bytes20(ds.facets[msg.sig]));\n if (facet == address(0))\n facet = ds.defaultFallbackHandler.facetAddress(msg.sig);\n require(facet != address(0), \"Barz: Function does not exist\");\n // Execute external function from facet using delegatecall and return any value.\n assembly {\n // copy function selector and any arguments\n calldatacopy(0, 0, calldatasize())\n // execute function call using the facet\n let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)\n // get any return value\n returndatacopy(0, 0, returndatasize())\n // return any return value or error back to the caller\n switch result\n case 0 {\n revert(0, returndatasize())\n }\n default {\n return(0, returndatasize())\n }\n }\n }\n\n /**\n * @notice Receive function to receive native token without data\n */\n receive() external payable {}\n}\n" + }, + "contracts/BarzFactory.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Barz} from \"./Barz.sol\";\nimport {IBarzFactory} from \"./interfaces/IBarzFactory.sol\";\n\n/**\n * @title Barz Factory\n * @dev Contract to easily deploy Barz to a pre-computed address with a single call\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract BarzFactory is IBarzFactory {\n event BarzDeployed(address);\n\n address public immutable accountFacet;\n address public immutable entryPoint;\n address public immutable facetRegistry;\n address public immutable defaultFallback;\n\n /**\n * @notice Sets the initialization data for Barz contract initialization\n * @param _accountFacet Account Facet to be used to create Barz\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\n * @param _facetRegistry Facet Registry to be used to create Barz\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\n */\n constructor(\n address _accountFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallback\n ) {\n accountFacet = _accountFacet;\n entryPoint = _entryPoint;\n facetRegistry = _facetRegistry;\n defaultFallback = _defaultFallback;\n }\n\n /**\n * @notice Creates the Barz with a single call. It creates the Barz contract with the givent verification facet\n * @param _verificationFacet Address of verification facet used for creating the barz account\n * @param _owner Public Key of the owner to initialize barz account\n * @param _salt Salt used for deploying barz with create2\n * @return barz Instance of Barz contract deployed with the given parameters\n */\n function createAccount(\n address _verificationFacet,\n bytes calldata _owner,\n uint256 _salt\n ) external override returns (Barz barz) {\n address addr = getAddress(_verificationFacet, _owner, _salt);\n uint codeSize = addr.code.length;\n if (codeSize > 0) {\n return Barz(payable(addr));\n }\n barz = new Barz{salt: bytes32(_salt)}(\n accountFacet,\n _verificationFacet,\n entryPoint,\n facetRegistry,\n defaultFallback,\n _owner\n );\n emit BarzDeployed(address(barz));\n }\n\n /**\n * @notice Calculates the address of Barz with the given parameters\n * @param _verificationFacet Address of verification facet used for creating the barz account\n * @param _owner Public Key of the owner to initialize barz account\n * @param _salt Salt used for deploying barz with create2\n * @return barzAddress Precalculated Barz address\n */\n function getAddress(\n address _verificationFacet,\n bytes calldata _owner,\n uint256 _salt\n ) public view override returns (address barzAddress) {\n bytes memory bytecode = getBytecode(\n accountFacet,\n _verificationFacet,\n entryPoint,\n facetRegistry,\n defaultFallback,\n _owner\n );\n bytes32 hash = keccak256(\n abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(bytecode)\n )\n );\n barzAddress = address(uint160(uint256(hash)));\n }\n\n /**\n * @notice Returns the bytecode of Barz with the given parameter\n * @param _accountFacet Account Facet to be used to create Barz\n * @param _verificationFacet Verification Facet to be used to create Barz\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\n * @param _facetRegistry Facet Registry to be used to create Barz\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\n * @param _ownerPublicKey Public Key of owner to be used to initialize Barz ownership\n * @return barzBytecode Bytecode of Barz\n */\n function getBytecode(\n address _accountFacet,\n address _verificationFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallback,\n bytes calldata _ownerPublicKey\n ) public pure override returns (bytes memory barzBytecode) {\n bytes memory bytecode = type(Barz).creationCode;\n barzBytecode = abi.encodePacked(\n bytecode,\n abi.encode(\n _accountFacet,\n _verificationFacet,\n _entryPoint,\n _facetRegistry,\n _defaultFallback,\n _ownerPublicKey\n )\n );\n }\n\n /**\n * @notice Returns the creation code of the Barz contract\n * @return creationCode Creation code of Barz\n */\n function getCreationCode()\n public\n pure\n override\n returns (bytes memory creationCode)\n {\n creationCode = type(Barz).creationCode;\n }\n}\n" + }, + "contracts/facets/AccountFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {UserOperation} from \"../aa-4337/interfaces/UserOperation.sol\";\nimport {IEntryPoint} from \"../aa-4337/interfaces/IEntryPoint.sol\";\nimport {BaseAccount} from \"../aa-4337/core/BaseAccount.sol\";\nimport {LibAppStorage, BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {IFacetRegistry} from \"../infrastructure/interfaces/IFacetRegistry.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {IERC1271} from \"../interfaces/ERC/IERC1271.sol\";\nimport {IAccountFacet} from \"./interfaces/IAccountFacet.sol\";\n\n/**\n * @title Account Facet\n * @dev Account module contract that provides the account features and initialization of signer\n * compatible with EIP-1271 & EIP-4337\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract AccountFacet is BarzStorage, BaseAccount, IAccountFacet {\n using ECDSA for bytes32;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceAccountInitialize();\n }\n\n /**\n * @notice Returns the address of EntryPoint contract registered to Barz account\n */\n function entryPoint() public view override returns (IEntryPoint) {\n return s.entryPoint;\n }\n\n /**\n * @notice Initializes the initial storage of the Barz contract.\n * @dev This method can only be called during the initialization or signature migration.\n * If the proxy contract was created without initialization, anyone can call initialize.\n * Barz calls initialize in constructor in an atomic transaction during deployment\n * @param _verificationFacet Facet contract handling the verificationi\n * @param _anEntryPoint Entrypoint contract defined in EIP-4337 handling the flow of UserOp\n * @param _facetRegistry Registry of Facets that hold all facet information\n * @param _defaultFallBackHandler Middleware contract for default facets\n * @param _ownerPublicKey Bytes of owner public key\n */\n function initialize(\n address _verificationFacet,\n address _anEntryPoint,\n address _facetRegistry,\n address _defaultFallBackHandler,\n bytes calldata _ownerPublicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceAccountInitialize();\n s.entryPoint = IEntryPoint(_anEntryPoint);\n s.facetRegistry = IFacetRegistry(_facetRegistry);\n LibDiamond.diamondStorage().defaultFallbackHandler = IDiamondLoupe(\n _defaultFallBackHandler\n );\n\n _cutDiamondAccountFacet(_verificationFacet);\n\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n _ownerPublicKey\n );\n // Every Verification Facet should comply with initializeSigner(bytes)\n // to be compatible with the Barz contract(for initialization)\n (bool success, bytes memory result) = _verificationFacet.delegatecall(\n initCall\n );\n if (!success || uint256(bytes32(result)) != 1) {\n revert AccountFacet__InitializationFailure();\n }\n\n initSuccess = 1;\n emit AccountInitialized(s.entryPoint, _ownerPublicKey);\n }\n\n function _cutDiamondAccountFacet(address _verificationFacet) internal {\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](1);\n\n bytes4 ownerVerificationFuncSelector = IVerificationFacet(\n _verificationFacet\n ).validateOwnerSignatureSelector();\n\n bytes4[] memory verificationFunctionSelectors = new bytes4[](3);\n verificationFunctionSelectors[0] = IERC1271.isValidSignature.selector;\n verificationFunctionSelectors[1] = ownerVerificationFuncSelector;\n verificationFunctionSelectors[2] = IVerificationFacet.owner.selector;\n cut[0] = IDiamondCut.FacetCut({\n facetAddress: _verificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: verificationFunctionSelectors\n });\n\n LibDiamond.diamondCut(cut, address(0), \"\");\n }\n\n /**\n * @notice Calls the destination with inputted calldata and value from EntryPoint\n * @dev This method executes the calldata coming from the EntryPoint.\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\n * @param _dest Address of destination where the call will be forwarded to\n * @param _value Amount of native coin the owner is willing to send(e.g. ETH, BNB)\n * @param _func Bytes of calldata to execute in the destination address\n */\n function execute(\n address _dest,\n uint256 _value,\n bytes calldata _func\n ) external override onlyWhenUnlocked {\n _requireFromEntryPoint();\n _call(_dest, _value, _func);\n }\n\n /**\n * @notice Batch calls the destination with inputted calldata and value from EntryPoint\n * @dev This method batch executes the calldata coming from the EntryPoint.\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\n * @param _dest Array of addresses of destination where the call will be forwarded to\n * @param _value Array of amount of native coin the owner is willing to send(e.g. ETH, BNB)\n * @param _func Array of bytes of calldata to execute in the destination address\n */\n function executeBatch(\n address[] calldata _dest,\n uint256[] calldata _value,\n bytes[] calldata _func\n ) external override onlyWhenUnlocked {\n _requireFromEntryPoint();\n require(\n _dest.length == _func.length && _dest.length == _value.length,\n \"wrong array lengths\"\n );\n for (uint256 i; i < _dest.length; ) {\n _call(_dest[i], _value[i], _func[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Validates the signature field of UserOperation\n * @dev This method validates if the signature of UserOp is indeed valid by delegating the call to Verification Facet\n * Barz makes a call to the pre-registered Verification Facet address in App Storage\n * @param _userOp UserOperation from owner to be validated\n * @param _userOpHash Hash of UserOperation given from the EntryPoint contract\n */\n function _validateSignature(\n UserOperation calldata _userOp,\n bytes32 _userOpHash\n ) internal override returns (uint256 validationData) {\n // Get Facet with Function Selector\n address facet = LibLoupe.facetAddress(s.validateOwnerSignatureSelector);\n if (facet == address(0))\n revert AccountFacet__NonExistentVerificationFacet();\n\n // Make function call to VerificationFacet\n bytes memory validateCall = abi.encodeWithSelector(\n s.validateOwnerSignatureSelector,\n _userOp,\n _userOpHash\n );\n (bool success, bytes memory result) = facet.delegatecall(validateCall);\n if (!success) revert AccountFacet__CallNotSuccessful();\n validationData = uint256(bytes32(result));\n if (validationData == 0) emit VerificationSuccess(_userOpHash);\n else emit VerificationFailure(_userOpHash);\n }\n\n /**\n * @notice Calls the target with the inputted value and calldata\n * @dev This method is the actual function in Barz that makes a call with an arbitrary owner-given data\n * @param _target Address of the destination contract which the call is getting forwarded to\n * @param _value Amount of Native coin the owner is wanting to make in this call\n * @param _data Calldata the owner is forwarding together in the call e.g. Swap/Token Transfer\n */\n function _call(\n address _target,\n uint256 _value,\n bytes memory _data\n ) internal {\n address facet = LibDiamond.restrictionsFacet();\n // NOTE: No restrictions facet, so restriction validation passes\n if (facet != address(0)) {\n if (_checkRestrictions(facet, _target, _value, _data) == 1)\n revert AccountFacet__RestrictionsFailure();\n }\n\n (bool success, bytes memory result) = _target.call{value: _value}(\n _data\n );\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n }\n\n /**\n * @notice Checks restrictions if the restrictions facet exists\n * @dev This method checks if the restrictions facet exists and makes a verification call to an array of restrictions facet\n * @param _facet Address that holds the restrictions logic\n * @param _target Address the call is getting forwarded to\n * @param _value Amount of native coin the call is sending together with the call\n * @param _data Calldata to trigger execution in target address\n */\n function _checkRestrictions(\n address _facet,\n address _target,\n uint256 _value,\n bytes memory _data\n ) internal returns (uint256 result) {\n bytes memory call = abi.encodeWithSignature(\n \"verifyRestrictions(address,address,uint256,bytes)\",\n address(this),\n _target,\n _value,\n _data\n );\n (bool success, bytes memory response) = _facet.delegatecall(call);\n if (!success) revert AccountFacet__RestrictionsFailure();\n result = uint256(bytes32(response));\n }\n}\n" + }, + "contracts/facets/AccountRecoveryFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibFacetStorage, RecoveryStorage, RecoveryConfig, RecoveryApprovalConfig, ApprovalConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {IAccountRecoveryFacet} from \"./interfaces/IAccountRecoveryFacet.sol\";\n\n/**\n * @title Account Recovery Facet\n * @dev Contract that enables recovery of accounts when owner key is unavailable\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract AccountRecoveryFacet is IAccountRecoveryFacet, Modifiers {\n bytes constant UNINIT_CALL =\n abi.encodeWithSignature(\"uninitializeSigner()\");\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Approve recovery of account as guardian\n * @dev This method can only be called by guardian and guardian inputs the public key of the new owner\n * When the threshold(majority of guardians) passes, it automatically executes account recovery\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function approveAccountRecovery(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + _getApprovalValidationPeriod()\n );\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit RecoveryApproved(\n _recoveryPublicKey,\n msg.sender,\n approvalValidUntil\n );\n if (\n getRecoveryApprovalCountWithTimeValidity(recoveryPublicKeyHash) >=\n LibGuardian.majorityOfGuardians()\n ) _executeRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Revoke recovery of account as guardian\n * @dev This method can only be called by guardian and guardian inputs the public key of the new owner\n When the threshold(majority of guardians) passes, it automatically revokes account recovery when recovery is pending\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function revokeAccountRecoveryApproval(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n if (\n !rs\n .isNewOwnerApproved[recoveryPublicKeyHash][msg.sender].isApproved ||\n !(block.timestamp <\n rs\n .isNewOwnerApproved[recoveryPublicKeyHash][msg.sender]\n .validUntil)\n ) revert AccountRecoveryFacet__NonExistentApproval();\n\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(false, 0);\n emit RecoveryApprovalRevoked(_recoveryPublicKey, msg.sender);\n }\n\n /**\n * @notice Executes recovery with signatures or on-chain pre-approvals\n * @dev This method validates the signatures of guardians or checks the on-chain pre-approved calls to check if the threshold passes\n * When the threshold passes, account recovery is executed and revert otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _guardians Array of guardians address that are approving the recovery of Account\n * @param _signatures Array of signature bytes that signed the approval hash\n */\n function executeRecovery(\n bytes calldata _recoveryPublicKey,\n address[] calldata _guardians,\n bytes[] calldata _signatures\n ) external override {\n if (_isRecoveryPending())\n revert AccountRecoveryFacet__RecoveryAlreadyOngoing();\n if (_guardians.length != _signatures.length)\n revert AccountRecoveryFacet__InvalidArrayLength();\n validateNewOwner(_recoveryPublicKey);\n\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n\n _checkApprover(_guardians);\n _checkDuplicateOnChainApprover(recoveryPublicKeyHash, _guardians);\n\n if (\n _guardians.length +\n getRecoveryApprovalCountWithTimeValidity(\n recoveryPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians()\n ) revert AccountRecoveryFacet__InsufficientGuardians();\n for (uint256 i; i < _guardians.length; ) {\n if (!LibGuardian.isGuardian(_guardians[i]))\n revert AccountRecoveryFacet__InvalidGuardian();\n if (\n !SignatureChecker.isValidSignatureNow(\n _guardians[i],\n recoveryPublicKeyHash,\n _signatures[i]\n )\n ) revert AccountRecoveryFacet__InvalidGuardianSignature();\n unchecked {\n ++i;\n }\n }\n _executeRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Executes recovery of the account. Note that execution and finalization is a different process\n * @dev Executes the recovery and adds recovery data to recovery configuration. Locks the account\n * @param _recoveryPublicKey Public Key of the account for recovery\n */\n function _executeRecovery(bytes memory _recoveryPublicKey) internal {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n ++rs.nonce;\n uint64 executeAfter = uint64(block.timestamp + _getRecoveryPeriod());\n rs.recoveryConfigs[INNER_STRUCT] = RecoveryConfig(\n _recoveryPublicKey,\n executeAfter // NOTE: Remove guardian Count\n );\n LibAppStorage.setLock(\n block.timestamp + _getLockPeriod(),\n AccountRecoveryFacet.executeRecovery.selector\n );\n emit RecoveryExecuted(_recoveryPublicKey, executeAfter);\n }\n\n /**\n * @notice Finalize recovery after recovery pending period. Recovery pending period can be set by user beforehand in SecurityManager\n * @dev This method finalizes recovery and fully changes the ownership of the account to the newly inputted recovery public key\n */\n function finalizeRecovery() external override {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n if (\n uint64(block.timestamp) <=\n rs.recoveryConfigs[INNER_STRUCT].executeAfter\n ) revert AccountRecoveryFacet__RecoveryPeriodNotOver();\n bytes memory recoveryOwner = rs\n .recoveryConfigs[INNER_STRUCT]\n .recoveryPublicKey;\n\n delete rs.recoveryConfigs[INNER_STRUCT];\n\n LibAppStorage.setLock(0, bytes4(0));\n\n LibAppStorage.initiateSignerMigration();\n address verificationFacet = address(\n bytes20(\n LibDiamond.diamondStorage().facets[\n s.validateOwnerSignatureSelector\n ]\n )\n );\n (bool success, bytes memory result) = verificationFacet.delegatecall(\n UNINIT_CALL\n );\n if (!success) revert AccountRecoveryFacet__CallNotSuccesful();\n uint256 validationData = uint256(bytes32(result));\n if (validationData != 1)\n revert AccountRecoveryFacet__SignerUninitializationFailure();\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n recoveryOwner\n );\n (success, result) = verificationFacet.delegatecall(initCall);\n if (!success) revert AccountRecoveryFacet__CallNotSuccesful();\n validationData = uint256(bytes32(result));\n if (validationData != 1)\n revert AccountRecoveryFacet__SignerInitializationFailure();\n LibAppStorage.finalizeSignerMigration();\n emit RecoveryFinalized(recoveryOwner);\n }\n\n /**\n * @notice Approves the cancellation of recovery\n * @dev This method approves the cancellation of recovery when recovery is still pending - waiting for finalization\n * @param _recoveryPublicKey Bytes of public key which is pending for recovery\n */\n function approveCancelRecovery(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"CancelRecovery\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + _getApprovalValidationPeriod()\n );\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit RecoveryCancellationApproved(_recoveryPublicKey, msg.sender);\n if (\n getRecoveryApprovalCountWithTimeValidity(recoveryPublicKeyHash) >=\n LibGuardian.majorityOfGuardians()\n ) {\n _cancelRecovery(_recoveryPublicKey);\n }\n }\n\n /**\n * @notice Hardstops an ongoing recovery\n * @dev This method provides a safety mechanism to protect owners of malicious guardians.\n * Owners can hardstop recovery when an malicious guardians starts the recovery process.\n * @param _signature Signature of the owner that signs the hash to hardstop recovery\n */\n function hardstopRecovery(bytes calldata _signature) external override {\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n \"0\",\n \"HardstopRecovery\"\n );\n if (\n !SignatureChecker.isValidSignatureNow(\n address(this),\n recoveryPublicKeyHash,\n _signature\n )\n ) revert AccountRecoveryFacet__InvalidOwnerSignature();\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n ++rs.nonce;\n delete rs.recoveryConfigs[INNER_STRUCT];\n LibAppStorage.setLock(0, bytes4(0));\n emit RecoveryHardstopped();\n }\n\n /**\n * @notice Cancels recovery with signatures or on-chain pre-approvals\n * @dev This method validates the signatures of guardians or checks the on-chain pre-approved calls to check if the threshold passes\n * When the threshold passes, account recovery is canceled and revert otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _guardians Array of guardians address that are approving the recovery of Account\n * @param _signatures Array of signature bytes that signed the cancellation approval hash\n */\n function cancelRecovery(\n bytes calldata _recoveryPublicKey,\n address[] calldata _guardians,\n bytes[] calldata _signatures\n ) external override {\n if (_guardians.length != _signatures.length)\n revert AccountRecoveryFacet__InvalidArrayLength();\n validateNewOwner(_recoveryPublicKey);\n\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"CancelRecovery\"\n );\n\n _checkApprover(_guardians);\n _checkDuplicateOnChainApprover(recoveryPublicKeyHash, _guardians);\n\n if (\n _guardians.length +\n getRecoveryApprovalCountWithTimeValidity(\n recoveryPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians()\n ) revert AccountRecoveryFacet__InsufficientGuardians();\n for (uint256 i; i < _guardians.length; ) {\n if (!LibGuardian.isGuardian(_guardians[i]))\n revert AccountRecoveryFacet__CallerNotGuardian();\n if (\n !SignatureChecker.isValidSignatureNow(\n _guardians[i],\n recoveryPublicKeyHash,\n _signatures[i]\n )\n ) revert AccountRecoveryFacet__InvalidGuardianSignature();\n unchecked {\n ++i;\n }\n }\n _cancelRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Cancel recovery when the recovery is pending. Unlock the account as well\n * @dev This method checks if the recovery is pending and reverts if not pending.\n * It increases the recovery nonce and deletes the recovery information and gets a small portion of gas in return\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function _cancelRecovery(bytes memory _recoveryPublicKey) internal {\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n LibAppStorage.setLock(0, bytes4(0));\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n ++rs.nonce;\n delete rs.recoveryConfigs[INNER_STRUCT];\n emit RecoveryCanceled(_recoveryPublicKey);\n }\n\n /**\n * @notice Validates the format of public key to be used for recovery\n * @dev This method checks if the public key format is correct and reverts otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function validateNewOwner(bytes memory _recoveryPublicKey) public view {\n if (\n !IVerificationFacet(\n LibLoupe.facetAddress(s.validateOwnerSignatureSelector)\n ).isValidKeyType(_recoveryPublicKey)\n ) revert AccountRecoveryFacet__InvalidRecoveryPublicKey();\n }\n\n /**\n * @notice Checks if recovery is currently pending\n * @return isPending Boolean indicating if recovery is pending\n */\n function _isRecoveryPending() internal view returns (bool isPending) {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n isPending = (rs.recoveryConfigs[INNER_STRUCT].executeAfter > 0);\n }\n\n /**\n * @notice Calculate the recovery hash dependent on chain, wallet address, nonce with EIP-191 prefix for safety\n * @dev Returns the keccak256 hash of EIP-191 msg hash packed with public key, salt, nonce, wallet address, etc\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _saltString Salt string to uniquely identify each recovery hash and for security\n * @return recoveryKeyHash Bytes32 string of the recovery hash\n */\n function getApprovalRecoveryKeyHash(\n bytes memory _recoveryPublicKey,\n string memory _saltString\n ) public view override returns (bytes32 recoveryKeyHash) {\n recoveryKeyHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n _recoveryPublicKey,\n _saltString,\n address(this),\n block.chainid,\n LibFacetStorage.recoveryStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Check the onchain approval of guardians and returns the number of guardians that approved\n * @dev Loop through the guardian addresses and returns the number of guardians that approved this recovery hash\n * @param _recoveryPublicKeyHash Bytes hash of newly recovered public key and recovery value of the account\n * @return approvalCount Number of guardians that approved\n */\n function getRecoveryApprovalCountWithTimeValidity(\n bytes32 _recoveryPublicKeyHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n for (uint256 i; i < guardianLength; ) {\n if (isRecoveryApproved(_recoveryPublicKeyHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Checks if the recovery is approved by the given approver\n * @param _recoveryPublicKeyHash Hash of the public key and configuration for recovery\n * @param _approver Address of approver\n * @return isApproved Bool value if recovery hash is approved\n */\n function isRecoveryApproved(\n bytes32 _recoveryPublicKeyHash,\n address _approver\n ) public view override returns (bool isApproved) {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n if (\n rs\n .isNewOwnerApproved[_recoveryPublicKeyHash][_approver].isApproved &&\n block.timestamp <\n rs.isNewOwnerApproved[_recoveryPublicKeyHash][_approver].validUntil\n ) {\n isApproved = true;\n }\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _recoveryPublicKeyHash Hash of recovery information\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _recoveryPublicKeyHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isRecoveryApproved(_recoveryPublicKeyHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert AccountRecoveryFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the lock period of this wallet address from security manager\n * @return lockPeriod value of lock period\n */\n function _getLockPeriod() internal view returns (uint256 lockPeriod) {\n lockPeriod = securityManager.lockPeriodOf(address(this));\n if (lockPeriod == 0) revert AccountRecoveryFacet__InvalidLockPeriod();\n }\n\n /**\n * @notice Returns the lock period of this wallet address from security manager\n * @return recoveryPeriod value of recovery period\n */\n function _getRecoveryPeriod()\n internal\n view\n returns (uint256 recoveryPeriod)\n {\n recoveryPeriod = securityManager.recoveryPeriodOf(address(this));\n if (recoveryPeriod == 0)\n revert AccountRecoveryFacet__InvalidRecoveryPeriod();\n }\n\n /**\n * @notice Returns the approval validation period of this wallet address from security manager\n * @return approvalValidationPeriod value of approval validation period\n */\n function _getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod == 0)\n revert AccountRecoveryFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the recovery nonce of this wallet address from security manager\n * @return nonce value of recovery nonce\n */\n function getRecoveryNonce() public view override returns (uint128 nonce) {\n nonce = LibFacetStorage.recoveryStorage().nonce;\n }\n\n /**\n * @notice Returns the recovery information of the pending recovery\n * @return recoveryConfig value struct of pending recovery\n */\n function getPendingRecovery()\n public\n view\n override\n returns (RecoveryConfig memory recoveryConfig)\n {\n recoveryConfig = LibFacetStorage.recoveryStorage().recoveryConfigs[\n INNER_STRUCT\n ];\n }\n}\n" + }, + "contracts/facets/base/DiamondCutFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibGuardian} from \"../../libraries/LibGuardian.sol\";\nimport {ISecurityManager} from \"../../infrastructure/interfaces/ISecurityManager.sol\";\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibFacetStorage, DiamondCutApprovalConfig, ApprovalConfig} from \"../../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"../Modifiers.sol\";\nimport {IDiamondCut} from \"./interfaces/IDiamondCut.sol\";\n\n/**\n * @title DiamondCut Facet\n * @dev Responsible for adding/removing/replace facets in Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DiamondCutFacet is Modifiers, IDiamondCut {\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Updates the flag for the interfaceId\n * @param _interfaceId InterfaceID to update the mapping\n * @param _flag Bool value to update the mapping of the given interface ID\n */\n function updateSupportsInterface(\n bytes4 _interfaceId,\n bool _flag\n ) external override onlyWhenUnlocked {\n LibDiamond.enforceIsSelf();\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId] = _flag;\n emit SupportsInterfaceUpdated(_interfaceId, _flag);\n }\n\n /**\n * @notice Add/replace/remove any number of functions and optionally execute\n * a function with delegatecall when guardians don't exist\n * @param _diamondCut Contains the facet addresses and function selectors\n * @param _init The address of the contract or facet to execute _calldata. It's prohibited in Barz\n */\n function diamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata\n ) external override onlyWhenUnlocked {\n LibDiamond.enforceIsSelf();\n\n _checkFacetCutValidity(_diamondCut);\n // require approval from guardian if guardian exists\n if (0 != LibGuardian.guardianCount())\n revert DiamondCutFacet__InvalidRouteWithGuardian();\n if (address(0) != _init) revert DiamondCutFacet__InvalidInitAddress();\n\n ++LibFacetStorage.diamondCutStorage().nonce;\n LibDiamond.diamondCut(_diamondCut, address(0), \"\");\n }\n\n /**\n * @notice Add/replace/remove any number of functions and optionally execute\n * a function with delegatecall when guardians exist\n * @param _diamondCut Contains the facet addresses and function selectors\n * @param _approvers Guardian or owner address that approves the diamond cut\n * @param _signatures Signature of Guardians or owner that approves the diamond cut\n */\n function diamondCutWithGuardian(\n FacetCut[] calldata _diamondCut,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n ) external override onlyWhenUnlocked {\n if (_approvers.length != _signatures.length)\n revert DiamondCutFacet__InvalidArrayLength();\n _checkFacetCutValidity(_diamondCut);\n if (0 == LibGuardian.guardianCount())\n revert DiamondCutFacet__InvalidRouteWithGuardian();\n\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(cutHash, _approvers);\n\n bool onChainOwnerApproval = getOwnerCutApprovalWithTimeValidity(\n cutHash\n );\n\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n if (\n _approvers.length +\n getDiamondCutApprovalCountWithTimeValidity(cutHash) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert DiamondCutFacet__InsufficientApprovers();\n\n bool ownerApproved;\n for (uint256 i; i < _approvers.length; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n _approvers[i] != address(this)\n ) revert DiamondCutFacet__InvalidApprover();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert DiamondCutFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n cutHash,\n _signatures[i]\n )\n ) revert DiamondCutFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n if (!ownerApproved && !onChainOwnerApproval)\n revert DiamondCutFacet__LackOfOwnerApproval();\n\n ++LibFacetStorage.diamondCutStorage().nonce;\n LibDiamond.diamondCut(_diamondCut, address(0), \"\");\n }\n\n /**\n * @notice Approves diamond cut. This can only be called directly from guardian or owner\n * @param _diamondCut Contains the facet addresses and function selectors\n */\n function approveDiamondCut(\n FacetCut[] calldata _diamondCut\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\n if (LibGuardian.guardianCount() == 0)\n revert DiamondCutFacet__InvalidRouteWithoutGuardian();\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n _checkFacetCutValidity(_diamondCut);\n\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(\n true,\n approvalValidUntil\n );\n emit DiamondCutApproved(_diamondCut);\n if (\n (getDiamondCutApprovalCountWithTimeValidity(cutHash) >=\n LibGuardian.majorityOfGuardians()) &&\n getOwnerCutApprovalWithTimeValidity(cutHash)\n ) {\n ++LibFacetStorage.diamondCutStorage().nonce;\n LibDiamond.diamondCut(_diamondCut, address(0), \"\");\n }\n }\n\n /**\n * @notice Revokes the approval of diamond cut. This can only be called directly from guardian or owner\n * @param _diamondCut Contains the facet addresses and function selectors\n */\n function revokeDiamondCutApproval(\n FacetCut[] calldata _diamondCut\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\n if (!ds.isDiamondCutApproved[cutHash][msg.sender].isApproved)\n revert DiamondCutFacet__CannotRevokeUnapproved();\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(false, 0);\n emit DiamondCutApprovalRevoked(_diamondCut);\n }\n\n /**\n * @notice Gets the number of approvals of diamond cut from guardians\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n */\n function getDiamondCutApprovalCountWithTimeValidity(\n bytes32 _diamondCutHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardiansLength = guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n if (isCutApproved(_diamondCutHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n return approvalCount;\n }\n\n /**\n * @notice Returns if the owner has approved the diamond cut\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @return isApprovedByOwner Bool value showing if the owner approved the cut\n */\n function getOwnerCutApprovalWithTimeValidity(\n bytes32 _diamondCutHash\n ) public view override returns (bool isApprovedByOwner) {\n isApprovedByOwner = isCutApproved(_diamondCutHash, address(this));\n }\n\n /**\n * @notice Returns if the given approver has approved the diamond cut\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @param _approver Address of approver\n * @return isApproved Bool value showing if the approver approved the cut\n */\n function isCutApproved(\n bytes32 _diamondCutHash,\n address _approver\n ) public view override returns (bool isApproved) {\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n isApproved = (ds\n .isDiamondCutApproved[_diamondCutHash][_approver].isApproved &&\n block.timestamp <\n ds.isDiamondCutApproved[_diamondCutHash][_approver].validUntil);\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _diamondCutHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isCutApproved(_diamondCutHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert DiamondCutFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the diamond cut hash. This function ensures that this hash is safe from replay attack by including\n * salt, address, chainId, and nonce, etc.\n * @param _diamondCut Contains the facet addresses and function selectors\n * @return cutHash Diamond Cut Hash\n */\n function getDiamondCutHash(\n FacetCut[] calldata _diamondCut\n ) public view override returns (bytes32 cutHash) {\n cutHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n keccak256(abi.encode(_diamondCut)),\n address(this),\n block.chainid,\n LibFacetStorage.diamondCutStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Returns the approval validation Period\n * @dev This method fetches the validation period from the security manager\n * @return approvalValidationPeriod Approval validation period of Barz contract fetched from security manager\n */\n function getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod <= 0)\n revert DiamondCutFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the diamond cut nonce of this wallet\n * @dev This method fetches the nonce from diamond cut storage\n * @return cutNonce Nonce of diamond cut to protect from reply attacks\n */\n function getDiamondCutNonce()\n public\n view\n override\n returns (uint128 cutNonce)\n {\n cutNonce = LibFacetStorage.diamondCutStorage().nonce;\n }\n}\n" + }, + "contracts/facets/base/DiamondLoupeFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {IERC165} from \"../../interfaces/ERC/IERC165.sol\";\nimport {IERC1271} from \"../../interfaces/ERC/IERC1271.sol\";\nimport {IERC677Receiver} from \"../../interfaces/ERC/IERC677Receiver.sol\";\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC1155Receiver} from \"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\";\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../../libraries/LibLoupe.sol\";\nimport {LibUtils} from \"../../libraries/LibUtils.sol\";\nimport {IDiamondCut} from \"../../facets/base/interfaces/IDiamondCut.sol\";\nimport {IStorageLoupe} from \"./interfaces/IStorageLoupe.sol\";\nimport {IDiamondLoupe} from \"./interfaces/IDiamondLoupe.sol\";\n\n/**\n * @title DiamondLoupe Facet\n * @dev DiamondLoupe contract compatible with EIP-2535\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DiamondLoupeFacet is IDiamondLoupe, IStorageLoupe, IERC165 {\n // Diamond Loupe Functions\n ////////////////////////////////////////////////////////////////////\n /// These functions are expected to be called frequently by tools off-chain.\n\n /**\n * @notice Gets all facets and their selectors.\n * @dev Barz uses a special architecture called default fallback handler. Default Fallback handler is used as a middleware\n * that holds the mapping of facet function selector and facet address that Barz uses. This helps Barz to reduce\n * significant amount of gas during the initialization process.\n * Hence, this method aggregates both the facet information from DefaulFallbackHandler and in diamond storage and shows the data to users.\n * @return facets_ Facet\n */\n function facets() public view override returns (Facet[] memory facets_) {\n Facet[] memory defaultFacet = LibDiamond\n .diamondStorage()\n .defaultFallbackHandler\n .facets();\n Facet[] memory _facets = LibLoupe.facets();\n uint256 numFacets = _facets.length;\n bytes4[] memory keys;\n address[] memory values;\n for (uint256 i; i < numFacets; ) {\n uint256 selectorsLength = _facets[i].functionSelectors.length;\n for (uint256 j; j < selectorsLength; ) {\n (keys, values) = LibUtils.setValue(\n keys,\n values,\n _facets[i].functionSelectors[j],\n _facets[i].facetAddress\n );\n unchecked {\n ++j;\n }\n }\n unchecked {\n ++i;\n }\n }\n {\n bool iIncrement;\n for (uint256 i; i < defaultFacet.length; ) {\n bool jIncrement;\n for (\n uint256 j;\n j < defaultFacet[i].functionSelectors.length;\n\n ) {\n if (\n LibUtils.getValue(\n keys,\n values,\n defaultFacet[i].functionSelectors[j]\n ) != address(0)\n ) {\n if (defaultFacet[i].functionSelectors.length == 1) {\n defaultFacet = LibUtils.removeFacetElement(\n defaultFacet,\n i\n );\n iIncrement = true;\n break;\n }\n defaultFacet[i].functionSelectors = LibUtils\n .removeElement(\n defaultFacet[i].functionSelectors,\n j\n );\n jIncrement = true;\n }\n if (!jIncrement) {\n unchecked {\n ++j;\n }\n } else {\n jIncrement = false;\n }\n }\n if (!iIncrement) {\n unchecked {\n ++i;\n }\n } else {\n iIncrement = false;\n }\n }\n }\n {\n uint256 facetLength = numFacets + defaultFacet.length;\n facets_ = new Facet[](facetLength);\n uint256 defaultFacetIndex;\n for (uint256 i; i < facetLength; ) {\n if (i < numFacets) {\n facets_[i] = _facets[i];\n bool jIncrementor;\n for (uint256 j; j < defaultFacet.length; ) {\n if (\n facets_[i].facetAddress ==\n defaultFacet[j].facetAddress\n ) {\n facets_[i].functionSelectors = LibUtils.mergeArrays(\n _facets[i].functionSelectors,\n defaultFacet[j].functionSelectors\n );\n defaultFacet = LibUtils.removeFacetElement(\n defaultFacet,\n j\n );\n jIncrementor = true;\n {\n facets_ = LibUtils.removeFacetElement(\n facets_,\n facets_.length - 1\n );\n }\n --facetLength;\n }\n if (!jIncrementor) {\n unchecked {\n ++j;\n }\n } else {\n jIncrementor = false;\n }\n }\n } else {\n facets_[i] = defaultFacet[defaultFacetIndex];\n ++defaultFacetIndex;\n }\n unchecked {\n ++i;\n }\n }\n }\n }\n\n /**\n * @notice Gets all the function selectors provided by a facet.\n * @param _facet The facet address.\n * @return facetFunctionSelectors_\n */\n function facetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n Facet[] memory facet = facets();\n uint256 facetLength = facet.length;\n for (uint256 i; i < facetLength; ) {\n if (facet[i].facetAddress == _facet)\n return facet[i].functionSelectors;\n unchecked {\n ++i;\n }\n }\n return facetFunctionSelectors_;\n }\n\n /**\n * @notice Get all the facet addresses used by Barz.\n * @return facetAddresses_\n */\n function facetAddresses()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n Facet[] memory facet = facets();\n uint256 facetLength = facet.length;\n facetAddresses_ = new address[](facetLength);\n for (uint256 i; i < facetLength; ) {\n facetAddresses_[i] = facet[i].facetAddress;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Gets the facet that supports the given selector.\n * @dev If facet is not found return address(0).\n * @param _functionSelector The function selector.\n * @return facetAddress_ The facet address.\n */\n function facetAddress(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n\n facetAddress_ = address(bytes20(ds.facets[_functionSelector]));\n if (facetAddress_ == address(0)) {\n facetAddress_ = IDiamondLoupe(ds.defaultFallbackHandler)\n .facetAddress(_functionSelector);\n }\n }\n\n /**\n * @notice SupportInterface to be compatible with EIP 165\n * @param _interfaceId Interface ID for detecting the interface\n * @return isSupported Bool value showing if the standard is supported in the contract\n */\n function supportsInterface(\n bytes4 _interfaceId\n ) external view override returns (bool isSupported) {\n isSupported =\n _interfaceId == type(IERC165).interfaceId ||\n _interfaceId == IDiamondCut.diamondCut.selector ||\n _interfaceId == type(IDiamondLoupe).interfaceId ||\n _interfaceId == type(IERC1155Receiver).interfaceId ||\n _interfaceId == type(IERC721Receiver).interfaceId ||\n _interfaceId == type(IERC777Recipient).interfaceId ||\n _interfaceId == IERC1271.isValidSignature.selector ||\n _interfaceId == type(IERC677Receiver).interfaceId ||\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId];\n }\n\n /**\n * @notice Returns the facet from the diamond storage. This excludes the facets from the default fallback handler\n * @return facets_ Facet information attached directly to diamond storage\n */\n function facetsFromStorage()\n external\n view\n override\n returns (Facet[] memory facets_)\n {\n facets_ = LibLoupe.facets();\n }\n\n /**\n * @notice Returns the facet address attached to the given function selector. This excludes the facets from the default fallback handler\n * @param _functionSelector Function selector to fetch the facet address from diamond storage\n * @return facetAddress_ Facet address mapped with the function selector\n */\n function facetAddressFromStorage(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n facetAddress_ = LibLoupe.facetAddress(_functionSelector);\n }\n\n /**\n * @notice Returns all facet addresses attached directly to diamond storage. This excludes the facets from the default fallback handler\n * @return facetAddresses_ All facet addresses attached directly to diamond storage\n */\n function facetAddressesFromStorage()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n facetAddresses_ = LibLoupe.facetAddresses();\n }\n\n /**\n * @notice Returns function selectors of given facet address attached directly to diamond storage. This excludes the facets from the default fallback handler\n * @param _facet Facet address to fetch the facet function selectors from diamond storage\n * @return facetFunctionSelectors_ Facet function selectors of the given facet address\n */\n function facetFunctionSelectorsFromStorage(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n facetFunctionSelectors_ = LibLoupe.facetFunctionSelectors(_facet);\n }\n}\n" + }, + "contracts/facets/base/interfaces/IDiamondCut.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title DiamondCut Facet Interface\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IDiamondCut {\n error DiamondCutFacet__InvalidRouteWithGuardian();\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\n error DiamondCutFacet__InvalidArrayLength();\n error DiamondCutFacet__InsufficientApprovers();\n error DiamondCutFacet__InvalidApprover();\n error DiamondCutFacet__InvalidApproverSignature();\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\n error DiamondCutFacet__CannotRevokeUnapproved();\n error DiamondCutFacet__LackOfOwnerApproval();\n error DiamondCutFacet__OwnerAlreadyApproved();\n error DiamondCutFacet__DuplicateApproval();\n error DiamondCutFacet__InvalidInitAddress();\n\n event DiamondCutApproved(FacetCut[] diamondCut);\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\n\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\n\n enum FacetCutAction {\n Add,\n Replace,\n Remove\n }\n // Add=0, Replace=1, Remove=2\n\n struct FacetCut {\n address facetAddress;\n FacetCutAction action;\n bytes4[] functionSelectors;\n }\n\n /// @notice Add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param diamondCut Contains the facet addresses and function selectors\n /// @param init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function diamondCut(\n FacetCut[] calldata diamondCut,\n address init,\n bytes calldata _calldata\n ) external;\n\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\n\n function diamondCutWithGuardian(\n FacetCut[] calldata diamondCut,\n address[] calldata approvers,\n bytes[] calldata signatures\n ) external;\n\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\n\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\n\n function getDiamondCutApprovalCountWithTimeValidity(\n bytes32 diamondCutHash\n ) external view returns (uint256);\n\n function getOwnerCutApprovalWithTimeValidity(\n bytes32 diamondCutHash\n ) external view returns (bool);\n\n function isCutApproved(\n bytes32 diamondCutHash,\n address approver\n ) external view returns (bool);\n\n function getDiamondCutHash(\n FacetCut[] calldata diamondCut\n ) external view returns (bytes32);\n\n function getDiamondCutNonce() external view returns (uint128);\n}\n" + }, + "contracts/facets/base/interfaces/IDiamondLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n// A loupe is a small magnifying glass used to look at diamonds.\n// These functions look at diamonds\ninterface IDiamondLoupe {\n /// These functions are expected to be called frequently\n /// by tools.\n\n struct Facet {\n address facetAddress;\n bytes4[] functionSelectors;\n }\n\n /// @notice Gets all facet addresses and their four byte function selectors.\n /// @return facets_ Facet\n function facets() external view returns (Facet[] memory facets_);\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n /// @return facetFunctionSelectors_\n function facetFunctionSelectors(\n address _facet\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses()\n external\n view\n returns (address[] memory facetAddresses_);\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(\n bytes4 _functionSelector\n ) external view returns (address facetAddress_);\n}\n" + }, + "contracts/facets/base/interfaces/IStorageLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"./IDiamondLoupe.sol\";\n\n/**\n * @title LoupeFromStorage Interface\n * @dev Interface contract to function as a loupe facet directly attached to diamond storage of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IStorageLoupe {\n /// These functions are expected to be called frequently\n /// by tools.\n\n /// @notice Gets all facet addresses and their four byte function selectors.\n /// @return facets_ Facet\n function facetsFromStorage()\n external\n view\n returns (IDiamondLoupe.Facet[] memory);\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n function facetFunctionSelectorsFromStorage(\n address _facet\n ) external view returns (bytes4[] memory);\n\n /// @notice Get all the facet addresses used by a diamond.\n function facetAddressesFromStorage()\n external\n view\n returns (address[] memory);\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n function facetAddressFromStorage(\n bytes4 _functionSelector\n ) external view returns (address);\n}\n" + }, + "contracts/facets/GuardianFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibFacetStorage, GuardianStorage, StorageConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IGuardianFacet} from \"./interfaces/IGuardianFacet.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Guardian Facet\n * @dev Contract that enables addition/removal of guardians from Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract GuardianFacet is IGuardianFacet {\n ISecurityManager public immutable securityManager;\n uint8 public constant INNER_STRUCT = 0;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Add guardians to Barz.\n * @dev This method internally calls addGuardian which checks the validity of guardian address and adds\n * as guardian if valid\n * @param _guardians Array of addresses to add as guardian\n */\n function addGuardians(address[] calldata _guardians) external override {\n LibDiamond.enforceIsSelf();\n for (uint256 i; i < _guardians.length; ) {\n addGuardian(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Add a guardian to Barz.\n * @dev This method checks if the function is called by the owner and validates the address of guardian\n * When the validation passes, guardian address is added to the pending state waiting for confirmation\n * @param _guardian Address to add as guardian\n */\n function addGuardian(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (_guardian == address(this))\n revert GuardianFacet__GuardianCannotBeSelf();\n if (isGuardian(_guardian)) revert GuardianFacet__DuplicateGuardian();\n if (_guardian == address(0))\n revert GuardianFacet__ZeroAddressGuardian();\n if (\n keccak256(abi.encodePacked(_guardian)) ==\n keccak256(IVerificationFacet(address(this)).owner())\n ) revert GuardianFacet__OwnerCannotBeGuardian();\n\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n if (\n gs.pending[id] != 0 ||\n block.timestamp <= gs.pending[id] + getSecurityWindow()\n ) revert GuardianFacet__DuplicateGuardianAddition();\n\n uint256 securityPeriod = getAdditionSecurityPeriod();\n gs.pending[id] = block.timestamp + securityPeriod;\n emit GuardianAdditionRequested(\n _guardian,\n block.timestamp + securityPeriod\n );\n }\n\n /**\n * @notice Remove guardians from Barz.\n * @dev This method internally calls removeGuardian which checks the validity of guardian and removes\n * guardian when the request is valid\n * @param _guardians Array of addresses to be removed\n */\n function removeGuardians(address[] calldata _guardians) external override {\n LibDiamond.enforceIsSelf();\n for (uint256 i; i < _guardians.length; ) {\n removeGuardian(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Remove a guardian from Barz.\n * @dev This method validates if the guardian to be removed is a guardian and puts the guardian removal\n * to a pending state waiting to be confirmed.\n * @param _guardian Address of guardian to be removed\n */\n function removeGuardian(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n if (!isGuardian(_guardian)) revert GuardianFacet__NonExistentGuardian();\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n if (\n gs.pending[id] != 0 ||\n block.timestamp <= gs.pending[id] + getSecurityWindow()\n ) revert GuardianFacet__DuplicateGuardianRemoval();\n\n uint256 securityPeriod = getRemovalSecurityPeriod();\n gs.pending[id] = block.timestamp + securityPeriod;\n emit GuardianRemovalRequested(\n _guardian,\n block.timestamp + securityPeriod\n );\n }\n\n /**\n * @notice Confirm addition of guardians\n * @dev This method internally calls confirmGuardianAddition which checks the validity of pending request.\n * Guardians are fully added when they pass the validation. Anyone can call this function.\n * @param _guardians Array of guardian addresses to be added\n */\n function confirmGuardianAdditions(\n address[] calldata _guardians\n ) external override {\n for (uint256 i; i < _guardians.length; ) {\n confirmGuardianAddition(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Confirm addition of a guardian\n * @dev This method checks the validity of pending request.\n * Guardians are fully added when they pass the validation. Anyone can call this function.\n * @param _guardian Guardian address to be added\n */\n function confirmGuardianAddition(address _guardian) public override {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingAddition();\n if (gs.pending[id] >= block.timestamp)\n revert GuardianFacet__PendingAdditionNotOver();\n if (block.timestamp >= gs.pending[id] + getSecurityWindow())\n revert GuardianFacet__PendingAdditionExpired();\n\n _addGuardian(_guardian);\n\n delete gs.pending[id];\n emit GuardianAdded(_guardian);\n }\n\n /**\n * @notice Confirm removal of guardians\n * @dev This method internally calls confirmGuardianRemoval to check the validity guardian removal confirmation.\n * Guardians are fully removed when they pass the validation. Anyone can call this function.\n * @param _guardians Array of guardian addresses to be removed\n */\n function confirmGuardianRemovals(\n address[] calldata _guardians\n ) external override {\n for (uint256 i; i < _guardians.length; ) {\n confirmGuardianRemoval(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Confirm removal of a guardian\n * @dev This method checks the validity guardian removal confirmation.\n * Guardian is fully removed when they pass the validation. Anyone can call this function.\n * @param _guardian Guardian address to be removed\n */\n function confirmGuardianRemoval(address _guardian) public override {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingRemoval();\n if (gs.pending[id] >= block.timestamp)\n revert GuardianFacet__PendingRemovalNotOver();\n if (block.timestamp >= gs.pending[id] + getSecurityWindow())\n revert GuardianFacet__PendingAdditionExpired();\n\n _removeGuardian(_guardian);\n delete gs.pending[id];\n emit GuardianRemoved(_guardian);\n }\n\n /**\n * @notice Cancel pending guardian addition\n * @dev This method checks if the previous request for guardian request exists.\n * It reverts if previous request is not pending and cancels the addition otherwise.\n * @param _guardian Guardian address to be canceled from addition\n */\n function cancelGuardianAddition(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingAddition();\n delete gs.pending[id];\n emit GuardianAdditionCancelled(_guardian);\n }\n\n /**\n * @notice Cancel pending guardian removal\n * @dev This method checks if the previous request for guardian request exists.\n * It reverts if previous request is not pending and cancels the removal otherwise.\n * @param _guardian Guardian address to be canceled from removal\n */\n function cancelGuardianRemoval(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingRemoval();\n delete gs.pending[id];\n emit GuardianRemovalCancelled(_guardian);\n }\n\n /**\n * @notice Get the addition security period of current account from security manager\n * @dev This method returns the uint value if addition security period\n * @return additionSecurityPeriod Uint256 value of addition security period\n */\n function getAdditionSecurityPeriod()\n public\n view\n override\n returns (uint256 additionSecurityPeriod)\n {\n additionSecurityPeriod = securityManager.additionSecurityPeriodOf(\n address(this)\n );\n if (additionSecurityPeriod == 0)\n revert GuardianFacet__InvalidAdditionSecurityPeriod();\n }\n\n /**\n * @notice Get the removal security period of current account from security manager\n * @dev This method returns the uint value if removal security period\n * @return removalSecurityPeriod Uint256 value of removal security period\n */\n function getRemovalSecurityPeriod()\n public\n view\n override\n returns (uint256 removalSecurityPeriod)\n {\n removalSecurityPeriod = securityManager.removalSecurityPeriodOf(\n address(this)\n );\n if (removalSecurityPeriod == 0)\n revert GuardianFacet__InvalidRemovalSecurityPeriod();\n }\n\n /**\n * @notice Get the security window of current account from security manager\n * @dev This method returns the uint value if security window\n * @return securityWindow Uint256 value of removal security period\n */\n function getSecurityWindow()\n public\n view\n override\n returns (uint256 securityWindow)\n {\n securityWindow = securityManager.securityWindowOf(address(this));\n if (securityWindow == 0) revert GuardianFacet__InvalidSecurityWindow();\n }\n\n /**\n * @notice Checks if the addition of the given guardian address is pending\n * @dev This method returns the bool value of whether the guardian address is pending addition\n * @return isPending Bool value of representing the pending of guardian addition\n */\n function isAdditionPending(\n address _guardian\n ) public view override returns (bool isPending) {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n isPending = _isPending(id);\n }\n\n /**\n * @notice Checks if the removal of the given guardian address is pending\n * @dev This method returns the bool value of whether the guardian address is pending removal\n * @return isPending Bool value of representing the pending of guardian removal\n */\n function isRemovalPending(\n address _guardian\n ) public view override returns (bool isPending) {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n isPending = _isPending(id);\n }\n\n /**\n * @notice Checks if the given hash is pending\n * @dev This method returns the bool value whether the hash is pending\n * @return isPending Bool value of representing the pending of guardian operation\n */\n function _isPending(\n bytes32 _idHash\n ) internal view returns (bool isPending) {\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n isPending = ((gs.pending[_idHash] > 0 &&\n gs.pending[_idHash] < block.timestamp) &&\n block.timestamp < gs.pending[_idHash] + getSecurityWindow());\n }\n\n /**\n * @notice Adds guardian to storage config. This is called when guardian is fully added.\n * @dev This method add guardian address and config information to Facet Storage dedicated for guardian\n * When this function is called, guardian is fully added to this Barz Smart Account\n * @param _guardian Address of guardian to be added\n */\n function _addGuardian(address _guardian) internal {\n if (!isAdditionPending(_guardian))\n revert GuardianFacet__InvalidGuardianAddition();\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n if (config.info[_guardian].exists)\n revert GuardianFacet__AlreadyExists();\n\n config.info[_guardian].exists = true;\n config.info[_guardian].index = uint128(config.addresses.length);\n config.addresses.push(_guardian);\n }\n\n /**\n * @notice Removes guardian to storage config. This is called when guardian is fully removed.\n * @dev This method remove guardian address and config information to Facet Storage dedicated for guardian\n * When this function is called, guardian is fully removed from this Barz Smart Account\n * @param _guardian Address of guardian to be removed\n */\n function _removeGuardian(address _guardian) internal {\n if (!isRemovalPending(_guardian))\n revert GuardianFacet__InvalidGuardianRemoval();\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n if (!config.info[_guardian].exists)\n revert GuardianFacet__NonExistentGuardian();\n\n address lastAddress = config.addresses[config.addresses.length - 1];\n if (_guardian != lastAddress) {\n uint128 targetIndex = config.info[_guardian].index;\n config.addresses[targetIndex] = lastAddress;\n config.info[lastAddress].index = targetIndex;\n }\n config.addresses.pop();\n delete config.info[_guardian];\n\n emit GuardianRemoved(_guardian);\n }\n\n /**\n * @notice Reads guardian storage and fetches the addresses into an array from the storage\n * @dev This method fetches the guardian storage and returns the list of guardian addresses\n * @return addresses Array of addresses comprised of guardian\n */\n function getGuardians()\n public\n view\n override\n returns (address[] memory addresses)\n {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n addresses = new address[](config.addresses.length);\n uint256 addressesLen = config.addresses.length;\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the number of majority of guardians\n * @return majorityOfGuardians_ Number of majority of guardians e.g., 2 if 3 guardians / 3 if 5 guardians\n */\n function majorityOfGuardians()\n public\n view\n override\n returns (uint256 majorityOfGuardians_)\n {\n majorityOfGuardians_ = LibGuardian.majorityOfGuardians();\n }\n\n /**\n * @notice Reads guardian storage and fetches the addresses into an array from the storage\n * @dev This method fetches the guardian storage and returns the list of guardian addresses\n * @return guardianNumber Array of guardians in the account\n */\n function guardianCount()\n public\n view\n override\n returns (uint256 guardianNumber)\n {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n guardianNumber = config.addresses.length;\n }\n\n /**\n * @notice Reads guardian storage and checks if the given address is a guardian\n * @return isGuardian_ Bool value representing if the given address is guardian\n */\n function isGuardian(\n address _guardian\n ) public view override returns (bool isGuardian_) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n isGuardian_ = config.info[_guardian].exists;\n }\n\n /**\n * @notice Checks if the guardian number is zero and returns of guardian facet is okay to be removed\n * @return isRemovable Bool value representing if guardian facet is removable\n */\n function isGuardianFacetRemovable()\n external\n view\n override\n returns (bool isRemovable)\n {\n isRemovable = (0 == guardianCount());\n }\n}\n" + }, + "contracts/facets/interfaces/IAccountFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IEntryPoint} from \"../../aa-4337/interfaces/IEntryPoint.sol\";\n\n/**\n * @title Account Facet Interface\n * @dev Interface of module contract that provides the account features and init/unitialization of signer\n * compatible with EIP-1271 & EIP-4337\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IAccountFacet {\n event AccountInitialized(\n IEntryPoint indexed entryPoint,\n bytes indexed ownerPublicKey\n );\n // NOTE: Added Below Event\n event VerificationSuccess(bytes32);\n event VerificationFailure(bytes32);\n\n error AccountFacet__InitializationFailure();\n error AccountFacet__RestrictionsFailure();\n error AccountFacet__NonExistentVerificationFacet();\n error AccountFacet__CallNotSuccessful();\n\n function initialize(\n address verificationFacet,\n address anEntryPoint,\n address facetRegistry,\n address _defaultFallBack,\n bytes calldata _ownerPublicKey\n ) external returns (uint256);\n\n function execute(address dest, uint256 value, bytes calldata func) external;\n\n function executeBatch(\n address[] calldata dest,\n uint256[] calldata value,\n bytes[] calldata func\n ) external;\n}\n" + }, + "contracts/facets/interfaces/IAccountRecoveryFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {RecoveryConfig} from \"../../libraries/LibFacetStorage.sol\";\n\n/**\n * @title Account Recovery Facet Interface\n * @dev Interface of contract that enables recovery of accounts when owner key is unavailable\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IAccountRecoveryFacet {\n event RecoveryExecuted(\n bytes indexed recoveryPublicKey,\n uint64 executeAfter\n );\n event RecoveryFinalized(bytes indexed recoveryPublicKey);\n event RecoveryCanceled(bytes indexed recoveryPublicKey);\n event RecoveryApproved(\n bytes indexed recoveryPublicKey,\n address indexed guardian,\n uint64 validUntil\n );\n event RecoveryApprovalRevoked(\n bytes indexed recoveryPublicKey,\n address indexed guardian\n );\n event RecoveryCancellationApproved(\n bytes indexed recoveryPublicKey,\n address indexed guardian\n );\n event RecoveryHardstopped();\n\n error AccountRecoveryFacet__CallerNotGuardian();\n error AccountRecoveryFacet__InvalidRecoveryPublicKey();\n error AccountRecoveryFacet__SignerInitializationFailure();\n error AccountRecoveryFacet__SignerUninitializationFailure();\n error AccountRecoveryFacet__InvalidArrayLength();\n error AccountRecoveryFacet__InsufficientGuardians();\n error AccountRecoveryFacet__RecoveryAlreadyOngoing();\n error AccountRecoveryFacet__NonexistentRecovery();\n error AccountRecoveryFacet__NonExistentApproval();\n error AccountRecoveryFacet__RecoveryPeriodNotOver();\n error AccountRecoveryFacet__InvalidLockPeriod();\n error AccountRecoveryFacet__InvalidRecoveryPeriod();\n error AccountRecoveryFacet__InvalidApprovalValidationPeriod();\n error AccountRecoveryFacet__InvalidGuardian();\n error AccountRecoveryFacet__InvalidGuardianSignature();\n error AccountRecoveryFacet__InvalidOwnerSignature();\n error AccountRecoveryFacet__CallNotSuccesful();\n error AccountRecoveryFacet__DuplicateApproval();\n\n function approveAccountRecovery(bytes calldata recoveryPublicKey) external;\n\n function revokeAccountRecoveryApproval(\n bytes calldata recoveryPublicKey\n ) external;\n\n function executeRecovery(\n bytes calldata recoveryPublicKey,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function finalizeRecovery() external;\n\n function approveCancelRecovery(bytes calldata recoveryPublicKey) external;\n\n function cancelRecovery(\n bytes calldata recoveryPublicKey,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function hardstopRecovery(bytes calldata signature) external;\n\n function getApprovalRecoveryKeyHash(\n bytes memory recoveryPublicKey,\n string memory saltString\n ) external view returns (bytes32);\n\n function getRecoveryApprovalCountWithTimeValidity(\n bytes32 recoveryPublicKeyHash\n ) external view returns (uint256);\n\n function isRecoveryApproved(\n bytes32 recoveryPublicKeyHash,\n address approver\n ) external view returns (bool);\n\n function getRecoveryNonce() external view returns (uint128);\n\n function getPendingRecovery() external view returns (RecoveryConfig memory);\n}\n" + }, + "contracts/facets/interfaces/IGuardianFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Guardian Facet Interface\n * @dev Interface of guaridna contract that enables addition/removal of guardians from Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IGuardianFacet {\n event GuardianAdditionRequested(\n address indexed guardian,\n uint256 executeAfter\n );\n event GuardianRemovalRequested(\n address indexed guardian,\n uint256 executeAfter\n );\n event GuardianAdditionCancelled(address indexed guardian);\n event GuardianRemovalCancelled(address indexed guardian);\n event GuardianAdded(address indexed guardian);\n event GuardianRemoved(address indexed guardian);\n\n error GuardianFacet__GuardianCannotBeSelf();\n error GuardianFacet__DuplicateGuardian();\n error GuardianFacet__OwnerCannotBeGuardian();\n error GuardianFacet__DuplicateGuardianAddition();\n error GuardianFacet__DuplicateGuardianRemoval();\n error GuardianFacet__UnknownPendingAddition();\n error GuardianFacet__PendingAdditionNotOver();\n error GuardianFacet__UnknownPendingRemoval();\n error GuardianFacet__PendingRemovalNotOver();\n error GuardianFacet__PendingAdditionExpired();\n error GuardianFacet__InvalidAdditionSecurityPeriod();\n error GuardianFacet__InvalidRemovalSecurityPeriod();\n error GuardianFacet__InvalidSecurityWindow();\n error GuardianFacet__NonExistentGuardian();\n error GuardianFacet__AlreadyExists();\n error GuardianFacet__InvalidGuardianAddition();\n error GuardianFacet__InvalidGuardianRemoval();\n error GuardianFacet__ZeroAddressGuardian();\n\n function addGuardian(address guardian) external;\n\n function addGuardians(address[] calldata guardians) external;\n\n function removeGuardian(address guardian) external;\n\n function removeGuardians(address[] calldata guardians) external;\n\n function confirmGuardianAddition(address guardian) external;\n\n function confirmGuardianAdditions(address[] calldata guardian) external;\n\n function confirmGuardianRemoval(address guardian) external;\n\n function confirmGuardianRemovals(address[] calldata guardian) external;\n\n function cancelGuardianAddition(address guardian) external;\n\n function cancelGuardianRemoval(address guardian) external;\n\n function isGuardian(address guardian) external view returns (bool);\n\n function isAdditionPending(address guardian) external view returns (bool);\n\n function isRemovalPending(address guardian) external view returns (bool);\n\n function isGuardianFacetRemovable() external view returns (bool);\n\n function getAdditionSecurityPeriod() external view returns (uint256);\n\n function getRemovalSecurityPeriod() external view returns (uint256);\n\n function getSecurityWindow() external view returns (uint256);\n\n function getGuardians() external view returns (address[] memory);\n\n function majorityOfGuardians() external view returns (uint256);\n\n function guardianCount() external view returns (uint256);\n}\n" + }, + "contracts/facets/interfaces/ILockFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Lock} from \"../../libraries/LibAppStorage.sol\";\n\n/**\n * @title Lock Facet Interface\n * @dev Interface of Lock contract that enables full lock/unlock of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface ILockFacet {\n event Locked(uint64 releaseAfter);\n event Unlocked();\n\n error LockFacet__InvalidRecoveryPeriod();\n error LockFacet__CannotUnlock();\n error LockFacet__InvalidSignature();\n error LockFacet__InvalidApprover();\n\n function lock() external;\n\n function unlock(address approver, bytes calldata signature) external;\n\n function getLockPeriod() external view returns (uint256);\n\n function isLocked() external view returns (bool);\n\n function getUnlockHash() external view returns (bytes32);\n\n function lockNonce() external view returns (uint128);\n\n function getPendingLock() external view returns (Lock memory);\n}\n" + }, + "contracts/facets/interfaces/IMultiSigFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Multi-sig facet Interface\n * @dev Interface of Multi-signature Facet with custom threshold.\n Wallet that adds this facet becomes a multi-sig wallet\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IMultiSigFacet {\n event ThresholdChanged(uint256 threshold);\n event OwnerAdded(address indexed newOwner);\n event OwnerRemoved(address indexed prevOwner);\n event HashApproved(bytes32 hashToApprove, address indexed owner);\n\n error MultiSigFacet__InvalidThreshold();\n error MultisigFacet__InvalidOwnerCount();\n error MultiSigFacet__InvalidRoute();\n error MultiSigFacet__InsufficientSignerLength();\n error MultiSigFacet__InvalidInitData();\n error MultiSigFacet__InvalidOwnerAddress();\n error MultiSigFacet__InvalidOwnerPair();\n error MultiSigFacet__InvalidSignatureLength();\n error MultiSigFacet__InvalidSignatureType();\n error MultiSigFacet__DuplicateOwner();\n error MultiSigFacet__OnlyOwner();\n\n function checkSignatures(\n bytes32 _dataHash,\n bytes calldata _signatures,\n uint256 _threshold\n ) external view returns (uint256);\n\n function splitSignatures(\n bytes calldata _signatures,\n uint256 _nextOffset\n )\n external\n pure\n returns (\n address owner,\n bytes memory signature,\n uint256 signatureType,\n uint256 nextOffset\n );\n\n function approveHash(bytes32 hashToApprove) external;\n\n function addOwner(address newOwner, uint256 threshold) external;\n\n function removeOwner(\n address prevOwner,\n address removedOwner,\n uint256 threshold\n ) external;\n\n function swapOwner(\n address prevOwner,\n address oldOwner,\n address newOwner\n ) external;\n\n function changeThreshold(uint256 _threshold) external;\n\n function isOwner(address owner) external view returns (bool);\n\n function getThreshold() external view returns (uint256);\n\n function getOwners() external view returns (address[] memory);\n}\n" + }, + "contracts/facets/interfaces/IRestrictionsFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Restrictions Facet Interface\n * @dev Interface of Restrictions contract that enables modular restrictions in Barz\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IRestrictionsFacet {\n event RestrictionAdded(address indexed restriction);\n event RestrictionRemoved(address indexed restriction);\n\n error RestrictionsFacet__EmptyRestrictionsList();\n error RestrictionsFacet__RestrictionNotFound();\n error RestrictionsFacet__RestrictionAlreadyExists();\n error RestrictionsFacet__ZeroAddressRestrictions();\n error RestrictionsFacet__ZeroAddressRestrictionsFacet();\n error RestrictionsFacet__RemainingRestrictionsCantBeEmpty();\n\n function initializeRestrictions(\n address[] memory _restrictions\n ) external returns (uint256);\n\n function uninitializeRestrictions() external returns (uint256);\n\n function getRestrictions() external view returns (address[] memory);\n\n function addRestriction(address restriction) external;\n\n function removeRestriction(address restriction) external;\n\n function verifyRestrictions(\n address from,\n address to,\n uint256 value,\n bytes calldata _calldata\n ) external returns (uint256);\n}\n" + }, + "contracts/facets/interfaces/ISignatureMigrationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureMigrationConfig} from \"../../libraries/LibFacetStorage.sol\";\n\n/**\n * @title Signature Migration Facet Interface\n * @dev Interface of Signature Migration contract for migrating user signature scheme to a new scheme user sets\n * Which could include\n * - ECDSA on Secp256K1 Curve\n * - ECDSA on Secp256R1 Curve\n * - BLS, Schnorr, etc\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface ISignatureMigrationFacet {\n event SignatureSchemeMigration(\n address indexed prevVerificationFacet,\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n event SignatureMigrationApproved(\n bytes newPublicKey,\n address indexed newVerificationFacet,\n bytes4[] verificationFuncSelectors,\n address indexed guardian,\n uint128 approvalValidUntil\n );\n event SignatureMigrationApprovalRevoked(\n bytes newPublicKey,\n address indexed newVerificationFacet,\n bytes4[] verificationFuncSelectors,\n address indexed guardian\n );\n event SignatureMigrationExecuted(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors,\n uint128 migrateAfter\n );\n event SignatureMigrationCanceled(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n event SignatureMigrationCancellationApproved(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n\n error SignatureMigrationFacet__SignerUninitializationFailure();\n error SignatureMigrationFacet__InvalidRouteWithGuardian();\n error SignatureMigrationFacet__InvalidKeyType();\n error SignatureMigrationFacet__InsufficientApprovers();\n error SignatureMigrationFacet__InvalidApproverSignature();\n error SignatureMigrationFacet__InvalidGuardian();\n error SignatureMigrationFacet__NonExistentApprover();\n error SignatureMigrationFacet__InvalidMigrationPeriod();\n error SignatureMigrationFacet__NonexistentMigration();\n error SignatureMigrationFacet__MigrationPeriodNotOver();\n error SignatureMigrationFacet__InvalidArrayLength();\n error SignatureMigrationFacet__InvalidApprovalValidationPeriod();\n error SignatureMigrationFacet__CannotRevokeUnapproved();\n error SignatureMigrationFacet__LackOfOwnerApproval();\n error SignatureMigrationFacet__OwnerAlreadyApproved();\n error SignatureMigrationFacet__NonExistentVerificationFacet();\n error SignatureMigrationFacet__DuplicateApproval();\n\n function migrateSignatureScheme(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function migrateSignatureSchemeWithGuardian(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors,\n address[] calldata approvers,\n bytes[] calldata signatures\n ) external;\n\n function approveSignatureSchemeMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function revokeSignatureMigrationApproval(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function finalizeSignatureMigration() external;\n\n function approveCancelSignatureMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function cancelSignatureMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function getApprovalMigrationKeyHash(\n bytes memory recoveryPublicKey,\n address newVerificationFacet,\n bytes4[] memory newVerificationFuncSelectors,\n string memory saltString\n ) external view returns (bytes32);\n\n function getMigrationOwnerApprovalWithTimeValidity(\n bytes32 publicKeyHash\n ) external view returns (bool);\n\n function getMigrationApprovalCountWithTimeValidity(\n bytes32 publicKeyHash\n ) external view returns (uint256);\n\n function isMigrationApproved(\n bytes32 migrationPublicKeyHash,\n address approver\n ) external view returns (bool);\n\n function getMigrationNonce() external view returns (uint128);\n\n function isMigrationPending() external view returns (bool);\n\n function getPendingMigration()\n external\n view\n returns (SignatureMigrationConfig memory);\n}\n" + }, + "contracts/facets/interfaces/IVerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {UserOperation} from \"../../aa-4337/interfaces/UserOperation.sol\";\n\n/**\n * @title Verification Facet Interface\n * @dev Implements logic for user ops signature verification\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface IVerificationFacet {\n event SignerInitialized(bytes);\n event SignerUninitialized();\n\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n error VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n error VerificationFacet__InitializationFailure();\n error VerificationFacet__InvalidFacetMapping();\n\n function initializeSigner(bytes memory) external returns (uint256);\n\n function uninitializeSigner() external returns (uint256);\n\n function validateOwnerSignatureSelector() external view returns (bytes4);\n\n function owner() external view returns (bytes memory);\n\n function isValidKeyType(bytes calldata) external view returns (bool);\n\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) external view returns (uint256);\n}\n" + }, + "contracts/facets/LockFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage, Lock} from \"../libraries/LibAppStorage.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibFacetStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {ILockFacet} from \"./interfaces/ILockFacet.sol\";\n\n/**\n * @title Lock Facet\n * @dev Contract that enables full lock/unlock of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract LockFacet is ILockFacet, Modifiers {\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Locks the account for the lock period. Lock period is defined in the security manager and it's customizable\n * This function can only be called when account is unlocked by owner or guardians\n * @dev This method checks the caller and if the account is currently locked and locks the account after fetching the\n * Lock period from the owner.\n */\n function lock() external override onlyGuardianOrOwner onlyWhenUnlocked {\n uint256 unlockTime = block.timestamp + getLockPeriod();\n ++LibFacetStorage.lockStorage().nonce;\n LibAppStorage.setLock(unlockTime, LockFacet.lock.selector);\n emit Locked(uint64(unlockTime));\n }\n\n /**\n * @notice Locks the account when the account is locked. This function can be called by anyone but must provide the approver address and signature.\n * The approver should be one of the guardians or owner.\n * @dev This method takes the approver address and the signature. After validating the address and the signature, it unlocks the account immediately.\n * Only one of the guardian or owner is required to lock and unlock the account.\n * @param _approver Address of approver approving the unlock of Barz account\n * @param _signature Signature of the approver that signed the msg hash for unlocking the account\n */\n function unlock(\n address _approver,\n bytes calldata _signature\n ) external override onlyWhenLocked {\n if (_approver != address(this) && !LibGuardian.isGuardian(_approver))\n revert LockFacet__InvalidApprover();\n if (\n !SignatureChecker.isValidSignatureNow(\n _approver,\n getUnlockHash(),\n _signature\n )\n ) revert LockFacet__InvalidSignature();\n _unlock();\n }\n\n /**\n * @notice Unlocks the account and increments the lock nonce\n */\n function _unlock() private {\n if (s.locks[INNER_STRUCT].locker != LockFacet.lock.selector)\n revert LockFacet__CannotUnlock();\n ++LibFacetStorage.lockStorage().nonce;\n LibAppStorage.setLock(0, bytes4(0));\n emit Unlocked();\n }\n\n /**\n * @notice Returns the lock period of current Barz account. Lock period information is held by Security Manager\n * @return lockPeriod Uint value of lock period in seconds\n */\n function getLockPeriod() public view override returns (uint256 lockPeriod) {\n lockPeriod = securityManager.lockPeriodOf(address(this));\n if (lockPeriod == 0) revert LockFacet__InvalidRecoveryPeriod();\n }\n\n /**\n * @notice Returns if the account is locked or not\n * @dev This method fetches the current block timestamp and compares that with release time.\n * After checking the timestamp and release time, it returns if the account is still locked or not.\n * @return isLocked_ Uint value of lock period in seconds\n */\n function isLocked() public view override returns (bool isLocked_) {\n isLocked_ = uint64(block.timestamp) < s.locks[INNER_STRUCT].release;\n }\n\n /**\n * @notice Calculates the unlock hash and returns the unlock hash safe from signature reply attack\n * @dev This method calculates the unlock hash with EIP-191 prefix, wallet address, chainID, and nonce\n * It packs the result and packs them and hashes it.\n * @return unlockHash Bytes32 unlock hash\n */\n function getUnlockHash() public view override returns (bytes32 unlockHash) {\n unlockHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n \"Unlock\",\n address(this),\n block.chainid,\n lockNonce()\n )\n )\n )\n );\n }\n\n /**\n * @notice Returns lock nonce of account. Reads nonce from lock storage within facet storage\n * @return lockNonce_ Uint128 value of lock nonce. This is incremented whenever the account is lock/unlocked\n */\n function lockNonce() public view override returns (uint128 lockNonce_) {\n lockNonce_ = LibFacetStorage.lockStorage().nonce;\n }\n\n /**\n * @notice Returns the overall information of current lock\n * @return pendingLock Struct value including all information of pending lock\n */\n function getPendingLock()\n public\n view\n override\n returns (Lock memory pendingLock)\n {\n pendingLock = s.locks[INNER_STRUCT];\n }\n}\n" + }, + "contracts/facets/Modifiers.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {IFacetRegistry} from \"../infrastructure/interfaces/IFacetRegistry.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\n\n/**\n * @title Modifiers\n * @dev Responsible for providing modifiers/util functions to Facet contracts\n * @author David Yongjun Kim (@Powerstream3604)\n */\nabstract contract Modifiers is BarzStorage {\n uint8 constant INNER_STRUCT = 0;\n\n error CallerNotGuardian();\n error CallerNotGuardianOrOwner();\n error DuplicateApprover();\n error ZeroApproverLength();\n error UnregisteredFacetAndSelectors();\n\n /**\n * @notice Modifier to only allow guardian to make a call, reverts if any other entity is the caller\n */\n modifier onlyGuardian() {\n if (!LibGuardian.isGuardian(msg.sender)) revert CallerNotGuardian();\n _;\n }\n\n /**\n * @notice Modifier to only allow guardian or owner to make a call, reverts if any other entity is the caller\n */\n modifier onlyGuardianOrOwner() {\n if (!LibGuardian.isGuardian(msg.sender) && address(this) != msg.sender)\n revert CallerNotGuardianOrOwner();\n _;\n }\n\n /**\n * @notice Checks if the approver address is the array is unique with no duplicate\n * @dev This method loops through the array and checks if a duplicate address exists, it reverts if duplicate address exists\n * @param approvers Array of address\n */\n function _checkApprover(\n address[] memory approvers\n ) internal pure returns (bool) {\n uint256 approverLength = approvers.length;\n if (0 == approverLength) revert ZeroApproverLength();\n for (uint256 i; i < approverLength - 1; ) {\n for (uint256 j = i + 1; j < approverLength; ) {\n if (approvers[i] == approvers[j]) {\n revert DuplicateApprover(); // Found a duplicate\n }\n unchecked {\n ++j;\n }\n }\n unchecked {\n ++i;\n }\n }\n return false; // No duplicates found\n }\n\n /**\n * @notice Checks if the facet getting added or replaced is registered to facet registry\n * @dev This method loops through the cut and checks if the facet getting added/replaced is registered to facet registry\n * @param _diamondCut Array of FacetCut, data for diamondCut defined in EIP-2535\n */\n function _checkFacetCutValidity(\n IDiamondCut.FacetCut[] memory _diamondCut\n ) internal view {\n uint256 diamondCutLength = _diamondCut.length;\n for (uint256 i; i < diamondCutLength; ) {\n if (\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Add ||\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Replace\n ) {\n if (\n !s.facetRegistry.areFacetFunctionSelectorsRegistered(\n _diamondCut[i].facetAddress,\n _diamondCut[i].functionSelectors\n )\n ) revert UnregisteredFacetAndSelectors();\n }\n unchecked {\n ++i;\n }\n }\n }\n}\n" + }, + "contracts/facets/RestrictionsFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, RestrictionsStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {IRestriction} from \"../restrictions/IRestriction.sol\";\nimport {IRestrictionsFacet} from \"./interfaces/IRestrictionsFacet.sol\";\n\n/**\n * @title Restrictions facet\n * @dev Responsible for storing and verifying different kinds of restrictions, for example:\n * - Whitelist / Blacklist\n * - Daily limits\n * - Trading time restrictions\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract RestrictionsFacet is IRestrictionsFacet {\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceRestrictionsInitialize();\n }\n\n /**\n * @notice Intialize restrictions of Barz. Restrictions facet call restriction contracts for restriction validation\n * before each call\n * @param _restrictions The initial array of restrictions.\n * @return initSuccess Int value showing if the initialization of restriction is successful\n */\n function initializeRestrictions(\n address[] calldata _restrictions\n ) public override returns (uint256 initSuccess) {\n LibDiamond.enforceIsSelf();\n LibAppStorage.enforceRestrictionsInitialize();\n\n if (_restrictions.length == 0) {\n // You can't initialize RestrictionsFacet with an empty list of restrictions\n revert RestrictionsFacet__EmptyRestrictionsList();\n }\n for (uint256 i; i < _restrictions.length; ) {\n if (_restrictions[i] == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictions();\n unchecked {\n ++i;\n }\n }\n\n LibFacetStorage.restrictionsStorage().restrictions = _restrictions;\n _updateRestrictionsMap(_restrictions, true);\n initSuccess = 1;\n }\n\n /**\n * @notice Unitialize restrictions of Barz\n * @return uninitSuccess Int value showing if the initialization of restriction is successful\n */\n function uninitializeRestrictions()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibDiamond.enforceIsSelf();\n LibAppStorage.setRestrictionsUninitialized();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n _updateRestrictionsMap(restrictionsStorage.restrictions, false);\n restrictionsStorage.restrictions = new address[](0);\n uninitSuccess = 1;\n }\n\n /**\n * @notice Returns the list of Restrictions contract address\n * @return restrictions Addresses of IRestriction which are currently active\n */\n function getRestrictions()\n public\n view\n override\n returns (address[] memory restrictions)\n {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n restrictions = restrictionsStorage.restrictions;\n }\n\n /**\n * @notice Adds restrictions to Barz with validation on the restriction contract address.\n * This method is only callable by the owner(self).\n * @param _restriction The address of the restriction to be added.\n */\n function addRestriction(address _restriction) external override {\n LibDiamond.enforceIsSelf();\n if (LibDiamond.restrictionsFacet() == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictionsFacet();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n if (_restriction == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictions();\n if (restrictionsStorage.exists[_restriction])\n revert RestrictionsFacet__RestrictionAlreadyExists();\n\n restrictionsStorage.restrictions.push(_restriction);\n restrictionsStorage.exists[_restriction] = true;\n\n emit RestrictionAdded(_restriction);\n }\n\n /**\n * @notice Remove restrictions from Barz if it existed. This method is only callable by the owner(self).\n * @param _restriction The address of the restriction to be removed.\n */\n function removeRestriction(address _restriction) external override {\n LibDiamond.enforceIsSelf();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n if (!restrictionsStorage.exists[_restriction])\n revert RestrictionsFacet__RestrictionNotFound();\n\n address[] storage restrictions = restrictionsStorage.restrictions;\n\n uint256 indexToDelete = restrictions.length;\n uint256 restrictionsLen = restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n if (restrictions[i] == _restriction) {\n indexToDelete = i;\n break;\n }\n unchecked {\n ++i;\n }\n }\n\n if (indexToDelete == 0 && restrictionsLen == 1) {\n revert RestrictionsFacet__RemainingRestrictionsCantBeEmpty();\n } else if (indexToDelete == restrictionsLen) {\n revert RestrictionsFacet__RestrictionNotFound();\n } else {\n restrictions[indexToDelete] = restrictions[restrictionsLen - 1];\n restrictions.pop();\n }\n\n restrictionsStorage.exists[_restriction] = false;\n emit RestrictionRemoved(_restriction);\n }\n\n /**\n * @notice Sets the restrictions address value mapping to true or false when adding/removing restriction contracts\n * @param _restrictions List of restriction contracts address\n * @param _newValue Bool value to flag to the list of restrictions contracts\n */\n function _updateRestrictionsMap(\n address[] memory _restrictions,\n bool _newValue\n ) internal {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n uint restrictionsLen = _restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n restrictionsStorage.exists[_restrictions[i]] = _newValue;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @dev Iterates over all restrictions and verifies each of them with the transaction parameters.\n * @param _from The address of the sender, that will be signing the transaction.\n * @param _to The receiving address.\n * @param _value Amount of ETH to transfer from sender to recipient.\n * @param _calldata Optional field to include arbitrary data.\n * @return 0 if all the checks passed, 1 otherwise.\n */\n function verifyRestrictions(\n address _from,\n address _to,\n uint256 _value,\n bytes calldata _calldata\n ) external returns (uint256) {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n uint restrictionsLen = restrictionsStorage.restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n IRestriction restriction = IRestriction(\n restrictionsStorage.restrictions[i]\n );\n bool checkPassed = restriction.check(_from, _to, _value, _calldata);\n if (!checkPassed) {\n return 1;\n }\n unchecked {\n ++i;\n }\n }\n\n return 0;\n }\n}\n" + }, + "contracts/facets/SignatureMigrationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, SignatureMigrationStorage, SignatureMigrationConfig, SignatureMigrationApprovalConfig, ApprovalConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IDiamondCut} from \"./base/interfaces/IDiamondCut.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {ISignatureMigrationFacet} from \"./interfaces/ISignatureMigrationFacet.sol\";\n\n/**\n * @title Signature Migration Facet\n * @dev Responsible for migrating user signature scheme to a new scheme user sets\n * Which could include\n * - ECDSA on Secp256K1 Curve\n * - ECDSA on Secp256R1 Curve\n * - BLS, Schnorr, etc\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract SignatureMigrationFacet is ISignatureMigrationFacet, Modifiers {\n bytes constant UNINIT_CALL =\n abi.encodeWithSignature(\"uninitializeSigner()\");\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This modifier verifies if the public key format matches with the new verification facet\n * @param _publicKey Bytes of public key to be validated for the new verification facet\n * @param _newVerificationFacet Address of new verification facet\n */\n modifier validateKeyType(\n bytes memory _publicKey,\n address _newVerificationFacet\n ) {\n if (\n !IVerificationFacet(_newVerificationFacet).isValidKeyType(\n _publicKey\n )\n ) revert SignatureMigrationFacet__InvalidKeyType();\n _;\n }\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n // IMPORTANT NOTE: In the client side when they call this function, the func selectors should be sorted in ascending order\n // to prevent different hash with same items in the array\n /**\n * @notice Moves the state of migration to a pending state. When pending state is over after pending period time,\n * Migration can be finalized. This function can only be called by self and when the account is unlocked.\n * @dev This method checks if the caller is self and if guardians exists. It migrates signature request to a pending state\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function migrateSignatureScheme(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n public\n override\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n // Only self contract can call this function\n LibDiamond.enforceIsSelf();\n // Should revert if guardian exist\n if (0 != LibGuardian.guardianCount())\n revert SignatureMigrationFacet__InvalidRouteWithGuardian();\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n // NOTE: Migration requires a pending period & confirmation from owner to prevent a\n // single call changing the ownership of the wallet\n /**\n * @notice Migrate signature scheme when guardians exists. Verifies the signature of guardians and moves migration to pending state.\n * Which can then be finalized when pending period is over. Owner's approval is mandatory for migration to happen\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _approvers List of approvers. This could include owner\n */\n function migrateSignatureSchemeWithGuardian(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n )\n public\n override\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n // Should revert if does not guardian exist\n if (0 == LibGuardian.guardianCount())\n revert SignatureMigrationFacet__InvalidRouteWithGuardian();\n if (_approvers.length != _signatures.length)\n revert SignatureMigrationFacet__InvalidArrayLength();\n\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(migrationPublicKeyHash, _approvers);\n\n bool onChainOwnerApproval = getMigrationOwnerApprovalWithTimeValidity(\n migrationPublicKeyHash\n );\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n\n if (\n _approvers.length +\n getMigrationApprovalCountWithTimeValidity(\n migrationPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert SignatureMigrationFacet__InsufficientApprovers();\n {\n // To prevent Stack too deep\n bool ownerApproved;\n for (uint256 i; i < _approvers.length; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n address(this) != _approvers[i]\n ) revert SignatureMigrationFacet__InvalidGuardian();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert SignatureMigrationFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n migrationPublicKeyHash,\n _signatures[i]\n )\n ) revert SignatureMigrationFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n\n if (!ownerApproved && !onChainOwnerApproval)\n revert SignatureMigrationFacet__LackOfOwnerApproval();\n }\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Internal function that moves signature mgiration to a pending state.\n * @dev This method increments migration nonce and sets the migration in the migration config. Emits events for migration execution\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _migrateSignatureScheme(\n address _newVerificationFacet,\n bytes memory _newPublicKey,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal {\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n\n ++ms.nonce;\n uint64 migrateAfter = uint64(block.timestamp + getMigrationPeriod());\n\n ms.migrationConfigs[INNER_STRUCT] = SignatureMigrationConfig(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n migrateAfter\n );\n\n emit SignatureMigrationExecuted(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors,\n migrateAfter\n );\n }\n\n /**\n * @notice Approves signature scheme migration on-chain. This can be called by owner or guardian only when the account is unlocked.\n * When the threshold of the migration approval passed and owner approval is granted, it automatically moves migration to a pending state\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function approveSignatureSchemeMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n public\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit SignatureMigrationApproved(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n msg.sender,\n approvalValidUntil\n );\n if (\n getMigrationApprovalCountWithTimeValidity(migrationPublicKeyHash) >=\n LibGuardian.majorityOfGuardians() &&\n getMigrationOwnerApprovalWithTimeValidity(migrationPublicKeyHash)\n )\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Revokes the approval of signature migration done on-chain. Emits revoke event when revoked.\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function revokeSignatureMigrationApproval(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n external\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n if (!isMigrationApproved(migrationPublicKeyHash, msg.sender))\n revert SignatureMigrationFacet__CannotRevokeUnapproved();\n\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(false, 0);\n emit SignatureMigrationApprovalRevoked(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n msg.sender\n );\n }\n\n /**\n * @notice Finalizes the pending signature scheme migration. This function can only be called by owner.\n * It removes the facets of the previous verification facet and adds the new verification facet.\n * After finalizing migration, it emits migration event which shows the change of the verification facet\n */\n function finalizeSignatureMigration() external override {\n // NOTE: Only owner can call this function\n LibDiamond.enforceIsSelf();\n\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n\n if (!isMigrationPending())\n revert SignatureMigrationFacet__NonexistentMigration();\n\n if (\n uint64(block.timestamp) <=\n ms.migrationConfigs[INNER_STRUCT].migrateAfter\n ) revert SignatureMigrationFacet__MigrationPeriodNotOver();\n address newVerificationFacet = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationVerificationFacet;\n bytes4[] memory newVerificationFuncSelectors = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationSelectors;\n bytes memory newPublicKey = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationPublicKey;\n\n address prevVerificationFacet = LibLoupe.facetAddress(\n s.validateOwnerSignatureSelector\n );\n if (prevVerificationFacet == address(0))\n revert SignatureMigrationFacet__NonExistentVerificationFacet();\n\n IDiamondCut.FacetCut[] memory UninitCut;\n IDiamondCut.FacetCut[] memory InitCut;\n {\n bytes4[] memory prevVerificationFuncSelectors = LibLoupe\n .facetFunctionSelectors(prevVerificationFacet);\n\n UninitCut = new IDiamondCut.FacetCut[](1);\n InitCut = new IDiamondCut.FacetCut[](1);\n UninitCut[0] = IDiamondCut.FacetCut({\n facetAddress: address(0),\n action: IDiamondCut.FacetCutAction.Remove,\n functionSelectors: prevVerificationFuncSelectors\n });\n InitCut[0] = IDiamondCut.FacetCut({\n facetAddress: newVerificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: newVerificationFuncSelectors\n });\n {\n IDiamondCut.FacetCut[]\n memory facetCuts = new IDiamondCut.FacetCut[](2);\n facetCuts[0] = UninitCut[0];\n facetCuts[1] = InitCut[0];\n _checkFacetCutValidity(facetCuts);\n }\n LibAppStorage.initiateSignerMigration();\n address verificationFacet = address(\n bytes20(\n LibDiamond.diamondStorage().facets[\n s.validateOwnerSignatureSelector\n ]\n )\n );\n\n (bool success, bytes memory result) = verificationFacet\n .delegatecall(UNINIT_CALL);\n require(success, \"MigrationFacet: uninitialize not successful\");\n uint256 validationData = uint256(bytes32(result));\n if (validationData == 0)\n revert SignatureMigrationFacet__SignerUninitializationFailure();\n\n LibDiamond.diamondCut(UninitCut, address(0), \"\");\n }\n {\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n newPublicKey\n );\n\n // Every Verification Facet should comply with initializeSigner(bytes)\n // to be compatible with the Barz contract(for initialization)\n LibDiamond.diamondCut(InitCut, newVerificationFacet, initCall);\n LibAppStorage.finalizeSignerMigration();\n emit SignatureSchemeMigration(\n prevVerificationFacet,\n newVerificationFacet,\n newPublicKey,\n newVerificationFuncSelectors\n );\n }\n }\n\n /**\n * @notice Approve cancellation of signature migration. If cancellation approval passes guardian threshold with owner approval\n * it automatically cancels the migration.\n * @dev This method checks if the caller is one of guardian or owner and sets true for the cancellation hash in the approval config.\n * It internally calls _cancelSignatureMigration for canceling the migration\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function approveCancelSignatureMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n external\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"CancelSignatureMigration\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit SignatureMigrationCancellationApproved(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n if (\n getMigrationApprovalCountWithTimeValidity(migrationPublicKeyHash) >=\n LibGuardian.majorityOfGuardians() &&\n getMigrationOwnerApprovalWithTimeValidity(migrationPublicKeyHash)\n )\n _cancelSignatureMigration(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Verifies the signature of guardians/owner and cancels the signature migration.\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _approvers List of approvers. This could include owner\n */\n function cancelSignatureMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n )\n external\n override\n validateKeyType(_newPublicKey, _newVerificationFacet)\n onlyWhenUnlocked\n {\n if (_approvers.length != _signatures.length)\n revert SignatureMigrationFacet__InvalidArrayLength();\n\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"CancelSignatureMigration\"\n );\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(migrationPublicKeyHash, _approvers);\n\n bool onChainOwnerApproval = getMigrationOwnerApprovalWithTimeValidity(\n migrationPublicKeyHash\n );\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n if (\n _approvers.length +\n getMigrationApprovalCountWithTimeValidity(\n migrationPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert SignatureMigrationFacet__InsufficientApprovers();\n {\n // To prevent stack too deep\n bool ownerApproved;\n for (uint256 i; i < _approvers.length; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n address(this) != _approvers[i]\n ) revert SignatureMigrationFacet__NonExistentApprover();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert SignatureMigrationFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n migrationPublicKeyHash,\n _signatures[i]\n )\n ) revert SignatureMigrationFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n if (!ownerApproved && !onChainOwnerApproval)\n revert SignatureMigrationFacet__LackOfOwnerApproval();\n }\n _cancelSignatureMigration(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Internal function that cancels signature migration.\n * @dev This method increments migration nonce and deletes the migration from the migration config. Emits events for migration cancellation\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _cancelSignatureMigration(\n address _newVerificationFacet,\n bytes memory _newPublicKey,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal {\n if (!isMigrationPending())\n revert SignatureMigrationFacet__NonexistentMigration();\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n ++ms.nonce;\n delete ms.migrationConfigs[INNER_STRUCT];\n emit SignatureMigrationCanceled(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Checks if the facets to be added from new verification facet is registered to facet registry\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _checkMigrationCutValidity(\n address _newVerificationFacet,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal view {\n IDiamondCut.FacetCut[] memory facetCuts = new IDiamondCut.FacetCut[](1);\n facetCuts[0] = IDiamondCut.FacetCut({\n facetAddress: _newVerificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: _newVerificationFuncSelectors\n });\n _checkFacetCutValidity(facetCuts);\n }\n\n /**\n * @notice Returns if the migration is pending of not\n * @dev This method fetches the migration storage and checks if the migrate after is above 0 value\n * @return isPending Bool value that shows if the migration is pending\n */\n function isMigrationPending()\n public\n view\n override\n returns (bool isPending)\n {\n SignatureMigrationStorage storage rs = LibFacetStorage\n .migrationStorage();\n isPending = rs.migrationConfigs[INNER_STRUCT].migrateAfter > 0;\n }\n\n /**\n * @notice Returns the migration hash. This function ensures that this hash is safe from replay attack by including\n * public key, verification facet, function selectors, salt, address, chainId, and nonce.\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _saltString Salt value for generating the migration hash\n * @return migrationKeyHash Bytes32 string of the migration key hash\n */\n function getApprovalMigrationKeyHash(\n bytes memory _newPublicKey,\n address _newVerificationFacet,\n bytes4[] memory _newVerificationFuncSelectors,\n string memory _saltString\n ) public view override returns (bytes32 migrationKeyHash) {\n migrationKeyHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n _newPublicKey,\n _newVerificationFacet,\n keccak256(abi.encode(_newVerificationFuncSelectors)),\n _saltString,\n address(this),\n block.chainid,\n LibFacetStorage.migrationStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Checks if the owner approved the hash for migration\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @return isApprovedByOwner Bool value of showing if the owner approved it or not\n */\n function getMigrationOwnerApprovalWithTimeValidity(\n bytes32 _migrationPublicKeyHash\n ) public view override returns (bool isApprovedByOwner) {\n isApprovedByOwner = isMigrationApproved(\n _migrationPublicKeyHash,\n address(this)\n );\n }\n\n /**\n * @notice Checks how many of the guardians approved the migration hash\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @return approvalCount Number of approvals\n */\n function getMigrationApprovalCountWithTimeValidity(\n bytes32 _migrationPublicKeyHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardiansLength = guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n if (isMigrationApproved(_migrationPublicKeyHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n return approvalCount;\n }\n\n /**\n * @notice Checks if the migration is approved by the given approver\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @param _approver Address of approver\n * @return isApproved Bool value if migration hash is approved\n */\n function isMigrationApproved(\n bytes32 _migrationPublicKeyHash,\n address _approver\n ) public view override returns (bool isApproved) {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n isApproved = (ms\n .isMigrationApproved[_migrationPublicKeyHash][_approver].isApproved &&\n block.timestamp <\n ms\n .isMigrationApproved[_migrationPublicKeyHash][_approver]\n .validUntil);\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _migrationPublicKeyHash Hash of migration information\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _migrationPublicKeyHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isMigrationApproved(_migrationPublicKeyHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert SignatureMigrationFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the migration period of this wallet\n * @dev This method fetches the migration period from the security manager\n * @return migrationPeriod Migration period of Barz contract fetched from security manager\n */\n function getMigrationPeriod()\n internal\n view\n returns (uint128 migrationPeriod)\n {\n migrationPeriod = securityManager.migrationPeriodOf(address(this));\n if (migrationPeriod == 0)\n revert SignatureMigrationFacet__InvalidMigrationPeriod();\n }\n\n /**\n * @notice Returns the validation period of this wallet\n * @dev This method fetches the validation period from the security manager\n * @return approvalValidationPeriod Validation period of Barz contract fetched from security manager\n */\n function getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod == 0)\n revert SignatureMigrationFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the migration nonce of this wallet\n * @dev This method fetches the nonce from migration storage\n * @return migrationNonce Nonce of migration to protect from reply attacks\n */\n function getMigrationNonce()\n public\n view\n override\n returns (uint128 migrationNonce)\n {\n migrationNonce = LibFacetStorage.migrationStorage().nonce;\n }\n\n /**\n * @notice Returns the migration configuration of this wallet\n * @dev This method fetches the migration config from the migration storage\n * @return pendingMigrationConfig Migration config currently pending for signature migration\n */\n function getPendingMigration()\n external\n view\n override\n returns (SignatureMigrationConfig memory pendingMigrationConfig)\n {\n pendingMigrationConfig = LibFacetStorage\n .migrationStorage()\n .migrationConfigs[INNER_STRUCT];\n }\n}\n" + }, + "contracts/facets/TokenReceiverFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {IERC1155Receiver} from \"../interfaces/ERC/IERC1155Receiver.sol\";\nimport {IERC677Receiver} from \"../interfaces/ERC/IERC677Receiver.sol\";\n\n/**\n * @title TokenReceiver Facet\n * @dev Contract that enables receiving ERC721/ERC1155/ERC777/ERC677 Tokens with safe transfer\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract TokenReceiverFacet is\n IERC721Receiver,\n IERC1155Receiver,\n IERC777Recipient,\n IERC677Receiver\n{\n /**\n * @notice Handles ERC721 Token callback.\n * return Standardized onERC721Received return value.\n */\n function onERC721Received(\n address,\n address,\n uint256,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC721Receiver.onERC721Received.selector;\n }\n\n /**\n * @notice Handles ERC1155 Token callback.\n * return Standardized onERC1155Received return value.\n */\n function onERC1155Received(\n address,\n address,\n uint256,\n uint256,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC1155Receiver.onERC1155Received.selector;\n }\n\n /**\n * @notice Handles ERC1155 Token batch callback.\n * return Standardized onERC1155BatchReceived return value.\n */\n function onERC1155BatchReceived(\n address,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC1155Receiver.onERC1155BatchReceived.selector;\n }\n\n /**\n * @notice Handles ERC777 Token callback.\n * Does not return value, empty implementation.\n */\n function tokensReceived(\n address,\n address,\n address,\n uint256,\n bytes calldata,\n bytes calldata\n ) external pure override {}\n\n /**\n * @notice Handles ERC677 Token callback.\n * return true.\n */\n function onTokenTransfer(\n address,\n uint256,\n bytes calldata\n ) external pure override returns (bool) {\n return true;\n }\n}\n" + }, + "contracts/facets/verification/MultiSigFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {UserOperation} from \"../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../../libraries/LibLoupe.sol\";\nimport {LibAppStorage} from \"../../libraries/LibAppStorage.sol\";\nimport {LibMultiSigStorage, MultiSigStorage} from \"../../libraries/LibMultiSigStorage.sol\";\nimport {IERC1271} from \"../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../interfaces/IVerificationFacet.sol\";\nimport {IMultiSigFacet} from \"../interfaces/IMultiSigFacet.sol\";\n\n/**\n * @title Multi-sig facet\n * @dev Multi-signature Facet with custom threshold.\n * Wallet that adds this facet becomes a multi-sig wallet.\n * Reference signature_format.md documentation for Multi-sig facet details\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract MultiSigFacet is IMultiSigFacet, IVerificationFacet, IERC1271 {\n using ECDSA for bytes32;\n\n address public immutable self;\n\n address internal constant SENTINEL_OWNERS = address(0x1);\n uint256 internal constant ADDRESS = 20;\n uint256 internal constant SIG_TYPE = 1;\n uint256 internal constant SIG_LEN = 4;\n uint256 internal constant THRESHOLD = 4;\n uint256 internal constant INVALID_SIG = 1;\n uint256 internal constant VALID_SIG = 0;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in Multisig Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the right format and initializes signer storage in k1 storage.\n * @param _owners Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _owners\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n\n if (!isValidKeyType(_owners)) revert MultiSigFacet__InvalidInitData();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n uint256 threshold = uint256(uint32(bytes4(_owners)));\n uint256 ownerCount = (_owners.length - THRESHOLD) / ADDRESS;\n\n if (threshold == 0) revert MultiSigFacet__InvalidThreshold();\n if (ownerCount == 0) revert MultisigFacet__InvalidOwnerCount();\n\n address currentOwner = SENTINEL_OWNERS;\n uint256 ptr = THRESHOLD;\n address owner_;\n for (uint256 i; i < ownerCount; ) {\n owner_ = address(bytes20(_owners[ptr:ptr + ADDRESS]));\n ptr += ADDRESS;\n if (\n owner_ == address(0) ||\n owner_ == SENTINEL_OWNERS ||\n owner_ == address(this) ||\n owner_ == currentOwner\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[owner_] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n\n ms.owners[currentOwner] = owner_;\n currentOwner = owner_;\n\n unchecked {\n ++i;\n }\n }\n ms.owners[currentOwner] = SENTINEL_OWNERS;\n ms.ownerCount = ownerCount;\n ms.threshold = threshold;\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_owners);\n }\n\n /**\n * @notice Uninitialize signer in K1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n ++ms.counter;\n address[] memory ownerlist = getOwners();\n uint256 ownerlistLength = ownerlist.length;\n for (uint256 i; i < ownerlistLength; ) {\n ms.owners[ownerlist[i]] = address(0);\n unchecked {\n ++i;\n }\n }\n ms.owners[SENTINEL_OWNERS] = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls checkSignatures with\n * user operation hash and signature together with the threshold.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n // Data 1 is invalid, Data 0 is valid\n validationData = checkSignatures(\n userOpHash,\n userOp.signature,\n LibMultiSigStorage.multisigStorage().threshold\n );\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n return this.validateOwnerSignature.selector;\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n uint totalLength = ms.ownerCount * ADDRESS;\n bytes memory result = new bytes(totalLength);\n\n // populate return array\n uint256 index;\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n while (currentOwner != SENTINEL_OWNERS) {\n assembly {\n mstore(\n add(result, add(32, mul(index, ADDRESS))),\n shl(96, currentOwner)\n )\n }\n currentOwner = ms.owners[currentOwner];\n index++;\n }\n\n return result;\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key should comply with the format in the signature_format.md doc\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n uint256 publicKeyLength = _publicKey.length;\n if (\n publicKeyLength < ADDRESS + THRESHOLD ||\n (publicKeyLength - THRESHOLD) % ADDRESS != 0\n ) return false;\n\n uint256 threshold = uint256(uint32(bytes4(_publicKey)));\n uint256 ownerCount = (publicKeyLength - THRESHOLD) / ADDRESS;\n\n isValid = !(ownerCount < threshold || threshold == 0);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes calldata _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (checkSignatures(\n _hash,\n _signature,\n LibMultiSigStorage.multisigStorage().threshold\n ) == VALID_SIG)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n\n /**\n * @notice Validates the format of the signature and verifies if the signature is signed by the expected key.\n * Reference signature_format.md doc for details about signature format and signature types\n * @param _dataHash Bytes value of data hash signed by the owners\n * @param _signatures Bytes value of signature which should comply with signature format\n * @param _threshold Uint256 value of current Multi-sig Barz's threshold\n */\n function checkSignatures(\n bytes32 _dataHash,\n bytes calldata _signatures,\n uint256 _threshold\n ) public view returns (uint256) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n address lastOwner = address(0);\n address currentOwner;\n bytes memory signature;\n uint256 signatureType;\n uint256 nextOffset;\n uint256 i;\n for (i; i < _threshold; ) {\n (\n currentOwner,\n signature,\n signatureType,\n nextOffset\n ) = splitSignatures(_signatures, nextOffset);\n if (nextOffset == 0 && i + 1 < _threshold) return INVALID_SIG;\n if (signatureType == 1) {\n // If signatureType is 1 then it is default dataHash signed.\n // This also includes the contract signature\n if (\n !SignatureChecker.isValidSignatureNow(\n currentOwner,\n _dataHash,\n signature\n )\n ) return INVALID_SIG;\n } else if (signatureType == 2) {\n // If signatureType is 2 then it is an approved hash\n if (ms.approvedHashes[ms.counter][currentOwner][_dataHash] == 0)\n return INVALID_SIG;\n } else if (signatureType == 3) {\n // If signatureType is 3 then it is a signed message hash\n // This also includes the contract signature\n bytes32 msgHash = _dataHash.toEthSignedMessageHash();\n if (\n !SignatureChecker.isValidSignatureNow(\n currentOwner,\n msgHash,\n signature\n )\n ) return INVALID_SIG;\n } else revert MultiSigFacet__InvalidRoute();\n if (\n currentOwner <= lastOwner ||\n ms.owners[currentOwner] == address(0) ||\n currentOwner == SENTINEL_OWNERS\n ) return INVALID_SIG;\n lastOwner = currentOwner;\n\n unchecked {\n ++i;\n }\n }\n return VALID_SIG;\n }\n\n /**\n * @notice Split signatures into each individual signatures. Should comply with signature format to be split\n * @param _signatures Bytes value of signature\n * @param _nextOffset Uint256 value of next offset to start splitting the signature\n */\n function splitSignatures(\n bytes calldata _signatures,\n uint256 _nextOffset\n )\n public\n pure\n returns (\n address owner_,\n bytes memory signature,\n uint256 signatureType,\n uint256 nextOffset\n )\n {\n uint256 signaturesLength = _signatures.length;\n\n if (signaturesLength <= _nextOffset + ADDRESS + SIG_LEN)\n revert MultiSigFacet__InsufficientSignerLength();\n\n owner_ = address(\n bytes20(_signatures[_nextOffset:_nextOffset + ADDRESS])\n );\n\n signatureType = uint256(\n uint8(\n bytes1(\n _signatures[_nextOffset + ADDRESS:_nextOffset +\n ADDRESS +\n SIG_TYPE]\n )\n )\n );\n\n if (signatureType > 3 || signatureType == 0)\n revert MultiSigFacet__InvalidSignatureType();\n uint256 offSet = _nextOffset + ADDRESS + SIG_TYPE;\n uint256 siglen = uint256(\n uint32(bytes4(_signatures[offSet:offSet + SIG_LEN]))\n );\n if (offSet + siglen > signaturesLength)\n revert MultiSigFacet__InvalidSignatureLength();\n\n offSet += SIG_LEN;\n if (offSet + siglen == signaturesLength) nextOffset = 0;\n else nextOffset = offSet + siglen;\n\n signature = _signatures[offSet:offSet + siglen];\n }\n\n /**\n * @notice Approves the hash of userOperation on-chain. This can only be called by owners.\n * @param _hashToApprove Bytes value of UserOperation hash to approve\n */\n function approveHash(bytes32 _hashToApprove) external {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (ms.owners[msg.sender] == address(0))\n revert MultiSigFacet__OnlyOwner();\n\n ms.approvedHashes[ms.counter][msg.sender][_hashToApprove] = 1;\n emit HashApproved(_hashToApprove, msg.sender);\n }\n\n /**\n * @notice Add owner to Barz. Update thresold if threshold is given different from current threshold\n * @dev This can only be done via a Self call.\n * @param _newOwner Address of new owner to be added\n * @param _threshold Uint256 value of threshold\n */\n function addOwner(address _newOwner, uint256 _threshold) external {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (\n _newOwner == address(0) ||\n _newOwner == SENTINEL_OWNERS ||\n _newOwner == address(this)\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_newOwner] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n\n ms.owners[_newOwner] = ms.owners[SENTINEL_OWNERS];\n ms.owners[SENTINEL_OWNERS] = _newOwner;\n ++ms.ownerCount;\n emit OwnerAdded(_newOwner);\n\n if (ms.threshold != _threshold) changeThreshold(_threshold);\n }\n\n /**\n * @notice Remove owner from Barz. Update thresold if threshold is given different from current threshold\n * @dev This can only be done via a Self call.\n * @param _prevOwner Address of owner located right behind the removed owner address in the linked list\n * @param _removedOwner Address of owner to be removed\n * @param _threshold Uint256 value of threshold\n */\n function removeOwner(\n address _prevOwner,\n address _removedOwner,\n uint256 _threshold\n ) external {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (ms.ownerCount - 1 < _threshold)\n revert MultiSigFacet__InvalidThreshold();\n if (_removedOwner == address(0) || _removedOwner == SENTINEL_OWNERS)\n revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_prevOwner] != _removedOwner)\n revert MultiSigFacet__InvalidOwnerPair();\n\n ms.owners[_prevOwner] = ms.owners[_removedOwner];\n ms.owners[_removedOwner] = address(0);\n --ms.ownerCount;\n emit OwnerRemoved(_removedOwner);\n\n if (ms.threshold != _threshold) changeThreshold(_threshold);\n }\n\n /**\n * @notice Swap owner in Barz.\n * @dev This can only be done via a Self call.\n * @param _prevOwner Address of owner located right behind the removed owner address in the linked list\n * @param _oldOwner Address of owner to be removed\n * @param _newOwner Address of owner to be added\n */\n function swapOwner(\n address _prevOwner,\n address _oldOwner,\n address _newOwner\n ) public {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (\n _newOwner == address(0) ||\n _newOwner == SENTINEL_OWNERS ||\n _newOwner == address(this)\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_newOwner] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n if (_oldOwner == address(0) || _oldOwner == SENTINEL_OWNERS)\n revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_prevOwner] != _oldOwner)\n revert MultiSigFacet__InvalidOwnerPair();\n\n ms.owners[_newOwner] = ms.owners[_oldOwner];\n ms.owners[_prevOwner] = _newOwner;\n ms.owners[_oldOwner] = address(0);\n emit OwnerRemoved(_oldOwner);\n emit OwnerAdded(_newOwner);\n }\n\n /**\n * @notice Changes the threshold of the Barz to `_threshold`.\n * @dev This can only be done via a Self call.\n * @param _threshold New threshold\n */\n function changeThreshold(uint256 _threshold) public {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (_threshold > ms.ownerCount || _threshold == 0)\n revert MultiSigFacet__InvalidThreshold();\n\n ms.threshold = _threshold;\n emit ThresholdChanged(_threshold);\n }\n\n /**\n * @notice Checks if the given address is owner\n * @param _owner Address to be checked if it's owner\n * @return isOwner_ Bool value showing if it's owner address\n */\n function isOwner(address _owner) public view returns (bool isOwner_) {\n isOwner_ = (_owner != SENTINEL_OWNERS &&\n LibMultiSigStorage.multisigStorage().owners[_owner] != address(0));\n }\n\n /**\n * @notice Returns the threshold of Barz\n * @return threshold Threshold of the Barz account\n */\n function getThreshold() public view returns (uint256 threshold) {\n threshold = LibMultiSigStorage.multisigStorage().threshold;\n }\n\n /**\n * @notice Returns the list of owner addresses\n * @return owners List of owners\n */\n function getOwners() public view returns (address[] memory owners) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n owners = new address[](ms.ownerCount);\n\n uint256 index;\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n while (currentOwner != SENTINEL_OWNERS) {\n owners[index] = currentOwner;\n currentOwner = ms.owners[currentOwner];\n index++;\n }\n }\n\n /**\n * @notice Returns the previous owner in the linked list\n * @param _owner Address of owner\n * @return prevOwner Address of previous owner\n */\n function getPrevOwner(\n address _owner\n ) public view returns (address prevOwner) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n if (currentOwner == _owner) return SENTINEL_OWNERS;\n while (currentOwner != SENTINEL_OWNERS) {\n if (ms.owners[currentOwner] == _owner) return currentOwner;\n\n currentOwner = ms.owners[currentOwner];\n }\n return address(0);\n }\n\n /**\n * @notice Returns of the owner is approved by given owner address\n * @param _owner Address of owner\n * @param _hash Hash of UserOperation\n * @return isApproved Bool value showing if the hash is approved by owner\n */\n function isApprovedHash(\n address _owner,\n bytes32 _hash\n ) public view returns (bool isApproved) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n isApproved = (ms.approvedHashes[ms.counter][_owner][_hash] == 1);\n }\n}\n" + }, + "contracts/facets/verification/secp256k1/Secp256k1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {UserOperation} from \"../../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibAppStorage} from \"../../../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, Secp256k1VerificationStorage} from \"../../../libraries/LibFacetStorage.sol\";\nimport {LibLoupe} from \"../../../libraries/LibLoupe.sol\";\nimport {IERC1271} from \"../../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../../interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Secp256k1 verification facet\n * @dev Default Ethereum's elliptic curve\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract Secp256k1VerificationFacet is IVerificationFacet, IERC1271 {\n using ECDSA for bytes32;\n error Secp256k1VerificationFacet__InvalidSignerLength();\n address public immutable self;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in K1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\n * @param _publicKey Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _publicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n if (!isValidKeyType(_publicKey))\n revert Secp256k1VerificationFacet__InvalidSignerLength();\n\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(uint160(uint256(keccak256(_publicKey[1:]))));\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_publicKey);\n }\n\n /**\n * @notice Uninitialize signer in K1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\n * signer public key.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n validationData = validateSignature(\n userOp,\n userOpHash,\n k1Storage.signer\n );\n }\n\n /**\n * @notice Validates if the signature of UserOperation is signed by the given signer\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @param signer Address of signer who signed the contract, to be validated\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n address signer\n ) public pure returns (uint256 isValid) {\n bytes32 hash = userOpHash.toEthSignedMessageHash();\n isValid = (signer != hash.recover(userOp.signature)) ? 1 : 0;\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n ownerSignatureValidatorSelector = this.validateOwnerSignature.selector;\n // NOTE: The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory signer) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n signer = abi.encodePacked(k1Storage.signer);\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key length should be 65 in an uncompressed public key format\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (_hash.recover(_signature) ==\n LibFacetStorage.k1Storage().signer)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/Secp256r1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {UserOperation} from \"../../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibAppStorage} from \"../../../libraries/LibAppStorage.sol\";\nimport {LibLoupe} from \"../../../libraries/LibLoupe.sol\";\nimport {LibFacetStorage, Secp256r1VerificationStorage} from \"../../../libraries/LibFacetStorage.sol\";\nimport {Base64} from \"./utils/Base64.sol\";\nimport {LibSecp256r1} from \"./utils/LibSecp256r1.sol\";\nimport {IERC1271} from \"../../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../../interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Secp256r1 verification facet\n * @dev Primarily used to verify user ops signed with passkeys\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract Secp256r1VerificationFacet is IVerificationFacet, IERC1271 {\n error Secp256r1VerificationFacet__InvalidSignerLength();\n address public immutable self;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in R1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\n * @param _publicKey Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _publicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n\n if (!isValidKeyType(_publicKey))\n revert Secp256r1VerificationFacet__InvalidSignerLength();\n\n bytes memory publicKeyCoordinates = _publicKey[1:];\n uint256[2] memory q;\n assembly {\n // Copy the bytes from the input data into the uint256 array\n mstore(q, mload(add(publicKeyCoordinates, 32)))\n mstore(add(q, 32), mload(add(publicKeyCoordinates, 64)))\n }\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n r1Storage.q = q;\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_publicKey);\n }\n\n /**\n * @notice Uninitialize signer in R1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n r1Storage.q = [0, 0];\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\n * signer public key.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n validationData = validateSignature(userOp, userOpHash, r1Storage.q);\n }\n\n /**\n * @notice Validates if the signature of UserOperation is signed by the given signer\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @param q Public Key of signer who signed the contract, to be validated\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256[2] memory q\n ) public view returns (uint256 isValid) {\n isValid = (_validateSignature(q, userOpHash, userOp.signature)) ? 0 : 1;\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n return this.validateOwnerSignature.selector; // validateOwnerSignature(UserOperation calldata userOp,bytes32 userOpHash)\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory signer) {\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n signer = abi.encodePacked(r1Storage.q);\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key should in an uncompressed public key format\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = _validateSignature(\n LibFacetStorage.r1Storage().q,\n _hash,\n _signature\n )\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n\n function _validateSignature(\n uint256[2] memory q,\n bytes32 _hash,\n bytes memory _signature\n ) internal view returns (bool) {\n (\n uint256 rValue,\n uint256 sValue,\n bytes memory authenticatorData,\n string memory clientDataJSONPre,\n string memory clientDataJSONPost\n ) = abi.decode(_signature, (uint256, uint256, bytes, string, string));\n bytes32 clientHash;\n {\n string memory opHashBase64 = Base64.encode(bytes.concat(_hash));\n string memory clientDataJSON = string.concat(\n clientDataJSONPre,\n opHashBase64,\n clientDataJSONPost\n );\n clientHash = sha256(bytes(clientDataJSON));\n }\n bytes32 sigHash = sha256(bytes.concat(authenticatorData, clientHash));\n return LibSecp256r1.Verify(q, rValue, sValue, uint256(sigHash));\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/utils/Base64.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @dev Provides a set of functions to operate with Base64 strings.\n * modified for base64url https://datatracker.ietf.org/doc/html/rfc4648#section-5\n * _Available since v4.5._\n */\nlibrary Base64 {\n /**\n * @dev Base64 Encoding/Decoding Table\n */\n string internal constant _TABLE =\n \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_\";\n\n /**\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\n */\n function encode(bytes memory data) internal pure returns (string memory) {\n /**\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\n */\n if (data.length == 0) return \"\";\n\n // Loads the table into memory\n string memory table = _TABLE;\n\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\n // and split into 4 numbers of 6 bits.\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\n // - `data.length + 2` -> Round up\n // - `/ 3` -> Number of 3-bytes chunks\n // - `4 *` -> 4 characters for each chunk\n uint256 newlength = (data.length * 8) / 6;\n if (data.length % 6 > 0) {\n newlength++;\n }\n string memory result = new string(newlength);\n\n /// @solidity memory-safe-assembly\n assembly {\n // Prepare the lookup table (skip the first \"length\" byte)\n let tablePtr := add(table, 1)\n\n // Prepare result pointer, jump over length\n let resultPtr := add(result, 32)\n\n // Run over the input, 3 bytes at a time\n for {\n let dataPtr := data\n let endPtr := add(data, mload(data))\n } lt(dataPtr, endPtr) {\n\n } {\n // Advance 3 bytes\n dataPtr := add(dataPtr, 3)\n let input := mload(dataPtr)\n\n // To write each character, shift the 3 bytes (18 bits) chunk\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\n // and apply logical AND with 0x3F which is the number of\n // the previous character in the ASCII table prior to the Base64 Table\n // The result is then added to the table to get the character to write,\n // and finally write it in the result pointer but with a left shift\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(18, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(12, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(6, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n }\n }\n\n return result;\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/utils/LibSecp256r1.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n// Heavily inspired from\n// https://github.com/maxrobot/elliptic-solidity/blob/master/contracts/Secp256r1.sol\n// https://github.com/tdrerup/elliptic-curve-solidity/blob/master/contracts/curves/EllipticCurve.sol\n// modified to use precompile 0x05 modexp\n// and modified jacobian double\n// optimisations to avoid to an from from affine and jacobian coordinates\n\n// Additional Elliptic curve Public key / Signature validation added by\n// David Yonjun Kim (@Powerstream3604)\n\nstruct JPoint {\n uint256 x;\n uint256 y;\n uint256 z;\n}\n\nlibrary LibSecp256r1 {\n uint256 constant gx =\n 0x6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296;\n uint256 constant gy =\n 0x4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5;\n uint256 public constant pp =\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF;\n\n uint256 public constant nn =\n 0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551;\n uint256 constant a =\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC;\n uint256 constant b =\n 0x5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B;\n uint256 constant MOST_SIGNIFICANT =\n 0xc000000000000000000000000000000000000000000000000000000000000000;\n\n /*\n * Verify\n * @description - verifies that a public key has signed a given message\n * @param Q - public key coordinates X & Y\n * @param R - signature half R\n * @param S - signature half S\n * @param input - hashed message\n */\n function Verify(\n uint256[2] memory q,\n uint r,\n uint s,\n uint e\n ) internal view returns (bool) {\n if (q[0] > pp - 1 || q[1] > pp - 1) {\n return false;\n }\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\n return false;\n }\n if (\n mulmod(q[1], q[1], pp) !=\n addmod(\n addmod(\n mulmod(q[0], mulmod(q[0], q[0], pp), pp),\n mulmod(a, q[0], pp),\n pp\n ),\n b,\n pp\n )\n ) {\n return false;\n }\n\n JPoint[16] memory points = _preComputeJacobianPoints(q);\n return VerifyWithPrecompute(points, r, s, e);\n }\n\n function VerifyWithPrecompute(\n JPoint[16] memory points,\n uint r,\n uint s,\n uint e\n ) internal view returns (bool) {\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\n return false;\n }\n\n uint w = _primemod(s, nn);\n\n uint u1 = mulmod(e, w, nn);\n uint u2 = mulmod(r, w, nn);\n\n uint x;\n uint y;\n\n (x, y) = ShamirMultJacobian(points, u1, u2);\n return (x == r);\n }\n\n /*\n * Strauss Shamir trick for EC multiplication\n * https://stackoverflow.com/questions/50993471/ec-scalar-multiplication-with-strauss-shamir-method\n * we optimise on this a bit to do with 2 bits at a time rather than a single bit\n * the individual points for a single pass are precomputed\n * overall this reduces the number of additions while keeping the same number of doublings\n */\n function ShamirMultJacobian(\n JPoint[16] memory points,\n uint u1,\n uint u2\n ) internal view returns (uint, uint) {\n uint x = 0;\n uint y = 0;\n uint z = 0;\n uint bits = 128;\n uint index = 0;\n\n while (bits > 0) {\n if (z > 0) {\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\n }\n index =\n ((u1 & MOST_SIGNIFICANT) >> 252) |\n ((u2 & MOST_SIGNIFICANT) >> 254);\n if (index > 0) {\n (x, y, z) = _jAdd(\n x,\n y,\n z,\n points[index].x,\n points[index].y,\n points[index].z\n );\n }\n u1 <<= 2;\n u2 <<= 2;\n bits--;\n }\n (x, y) = _affineFromJacobian(x, y, z);\n return (x, y);\n }\n\n function _preComputeJacobianPoints(\n uint256[2] memory q\n ) internal pure returns (JPoint[16] memory points) {\n points[0] = JPoint(0, 0, 0);\n points[1] = JPoint(q[0], q[1], 1); // u2\n points[2] = _jPointDouble(points[1]);\n points[3] = _jPointAdd(points[1], points[2]);\n\n points[4] = JPoint(gx, gy, 1); // u1Points[1]\n points[5] = _jPointAdd(points[4], points[1]);\n points[6] = _jPointAdd(points[4], points[2]);\n points[7] = _jPointAdd(points[4], points[3]);\n\n points[8] = _jPointDouble(points[4]); // u1Points[2]\n points[9] = _jPointAdd(points[8], points[1]);\n points[10] = _jPointAdd(points[8], points[2]);\n points[11] = _jPointAdd(points[8], points[3]);\n\n points[12] = _jPointAdd(points[4], points[8]); // u1Points[3]\n points[13] = _jPointAdd(points[12], points[1]);\n points[14] = _jPointAdd(points[12], points[2]);\n points[15] = _jPointAdd(points[12], points[3]);\n }\n\n function _jPointAdd(\n JPoint memory p1,\n JPoint memory p2\n ) internal pure returns (JPoint memory) {\n uint x;\n uint y;\n uint z;\n (x, y, z) = _jAdd(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z);\n return JPoint(x, y, z);\n }\n\n function _jPointDouble(\n JPoint memory p\n ) internal pure returns (JPoint memory) {\n uint x;\n uint y;\n uint z;\n (x, y, z) = _modifiedJacobianDouble(p.x, p.y, p.z);\n return JPoint(x, y, z);\n }\n\n /* _affineFromJacobian\n * @desription returns affine coordinates from a jacobian input follows\n * golang elliptic/crypto library\n */\n function _affineFromJacobian(\n uint x,\n uint y,\n uint z\n ) internal view returns (uint ax, uint ay) {\n if (z == 0) {\n return (0, 0);\n }\n\n uint zinv = _primemod(z, pp);\n uint zinvsq = mulmod(zinv, zinv, pp);\n\n ax = mulmod(x, zinvsq, pp);\n ay = mulmod(y, mulmod(zinvsq, zinv, pp), pp);\n }\n\n /*\n * _jAdd\n * @description performs Jacobian addition as defined below:\n * http://www.hyperelliptic.org/EFD/g1p/data/shortw/jacobian/addition/add-2007-bl\n */\n function _jAdd(\n uint p1,\n uint p2,\n uint p3,\n uint q1,\n uint q2,\n uint q3\n ) internal pure returns (uint r1, uint r2, uint r3) {\n if (p3 == 0) {\n r1 = q1;\n r2 = q2;\n r3 = q3;\n\n return (r1, r2, r3);\n } else if (q3 == 0) {\n r1 = p1;\n r2 = p2;\n r3 = p3;\n\n return (r1, r2, r3);\n }\n\n assembly {\n let\n pd\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\n let z1z1 := mulmod(p3, p3, pd) // Z1Z1 = Z1^2\n let z2z2 := mulmod(q3, q3, pd) // Z2Z2 = Z2^2\n\n let u1 := mulmod(p1, z2z2, pd) // U1 = X1*Z2Z2\n let u2 := mulmod(q1, z1z1, pd) // U2 = X2*Z1Z1\n\n let s1 := mulmod(p2, mulmod(z2z2, q3, pd), pd) // S1 = Y1*Z2*Z2Z2\n let s2 := mulmod(q2, mulmod(z1z1, p3, pd), pd) // S2 = Y2*Z1*Z1Z1\n\n let p3q3 := addmod(p3, q3, pd)\n\n if lt(u2, u1) {\n u2 := add(pd, u2) // u2 = u2+pd\n }\n let h := sub(u2, u1) // H = U2-U1\n\n let i := mulmod(0x02, h, pd)\n i := mulmod(i, i, pd) // I = (2*H)^2\n\n let j := mulmod(h, i, pd) // J = H*I\n if lt(s2, s1) {\n s2 := add(pd, s2) // u2 = u2+pd\n }\n let rr := mulmod(0x02, sub(s2, s1), pd) // r = 2*(S2-S1)\n r1 := mulmod(rr, rr, pd) // X3 = R^2\n\n let v := mulmod(u1, i, pd) // V = U1*I\n let j2v := addmod(j, mulmod(0x02, v, pd), pd)\n if lt(r1, j2v) {\n r1 := add(pd, r1) // X3 = X3+pd\n }\n r1 := sub(r1, j2v)\n\n // Y3 = r*(V-X3)-2*S1*J\n let s12j := mulmod(mulmod(0x02, s1, pd), j, pd)\n\n if lt(v, r1) {\n v := add(pd, v)\n }\n r2 := mulmod(rr, sub(v, r1), pd)\n\n if lt(r2, s12j) {\n r2 := add(pd, r2)\n }\n r2 := sub(r2, s12j)\n\n // Z3 = ((Z1+Z2)^2-Z1Z1-Z2Z2)*H\n z1z1 := addmod(z1z1, z2z2, pd)\n j2v := mulmod(p3q3, p3q3, pd)\n if lt(j2v, z1z1) {\n j2v := add(pd, j2v)\n }\n r3 := mulmod(sub(j2v, z1z1), h, pd)\n }\n return (r1, r2, r3);\n }\n\n // Point doubling on the modified jacobian coordinates\n // http://point-at-infinity.org/ecc/Prime_Curve_Modified_Jacobian_Coordinates.html\n function _modifiedJacobianDouble(\n uint x,\n uint y,\n uint z\n ) internal pure returns (uint x3, uint y3, uint z3) {\n if (y == 0) return (0, 0, 0);\n assembly {\n let\n pd\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\n let z2 := mulmod(z, z, pd)\n let az4 := mulmod(\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC,\n mulmod(z2, z2, pd),\n pd\n )\n let y2 := mulmod(y, y, pd)\n let s := mulmod(0x04, mulmod(x, y2, pd), pd)\n let u := mulmod(0x08, mulmod(y2, y2, pd), pd)\n let m := addmod(mulmod(0x03, mulmod(x, x, pd), pd), az4, pd)\n let twos := mulmod(0x02, s, pd)\n let m2 := mulmod(m, m, pd)\n if lt(m2, twos) {\n m2 := add(pd, m2)\n }\n x3 := sub(m2, twos)\n if lt(s, x3) {\n s := add(pd, s)\n }\n y3 := mulmod(m, sub(s, x3), pd)\n if lt(y3, u) {\n y3 := add(pd, y3)\n }\n y3 := sub(y3, u)\n z3 := mulmod(0x02, mulmod(y, z, pd), pd)\n }\n }\n\n // Fermats little theorem https://en.wikipedia.org/wiki/Fermat%27s_little_theorem\n // a^(p-1) = 1 mod p\n // a^(-1) ≅ a^(p-2) (mod p)\n // we then use the precompile bigModExp to compute a^(-1)\n function _primemod(uint value, uint p) internal view returns (uint ret) {\n ret = modexp(value, p - 2, p);\n return ret;\n }\n\n // Wrapper for built-in BigNumber_modexp (contract 0x5) as described here. https://github.com/ethereum/EIPs/pull/198\n function modexp(\n uint _base,\n uint _exp,\n uint _mod\n ) internal view returns (uint ret) {\n // bigModExp(_base, _exp, _mod);\n assembly {\n if gt(_base, _mod) {\n _base := mod(_base, _mod)\n }\n // Free memory pointer is always stored at 0x40\n let freemem := mload(0x40)\n\n mstore(freemem, 0x20)\n mstore(add(freemem, 0x20), 0x20)\n mstore(add(freemem, 0x40), 0x20)\n\n mstore(add(freemem, 0x60), _base)\n mstore(add(freemem, 0x80), _exp)\n mstore(add(freemem, 0xa0), _mod)\n\n let success := staticcall(14000, 0x5, freemem, 0xc0, freemem, 0x20)\n switch success\n case 0 {\n revert(0x0, 0x0)\n }\n default {\n ret := mload(freemem)\n }\n }\n }\n}\n" + }, + "contracts/infrastructure/DefaultFallbackHandler.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC1155Receiver} from \"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\";\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {BaseAccount} from \"../aa-4337/core/BaseAccount.sol\";\nimport {DefaultLibDiamond} from \"../libraries/DefaultLibDiamond.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IAccountFacet} from \"../facets/interfaces/IAccountFacet.sol\";\nimport {IStorageLoupe} from \"../facets/base/interfaces/IStorageLoupe.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IERC677Receiver} from \"../interfaces/ERC/IERC677Receiver.sol\";\nimport {IERC165} from \"../interfaces/ERC/IERC165.sol\";\n\n/**\n * @title DefaultFallbackHandler\n * @dev A default fallback handler for Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DefaultFallbackHandler is IDiamondLoupe {\n /**\n * @notice Sets the middleware diamond for Barz wallet as a fallback handler\n * @dev This contract is also a diamond that holds the default facets to reduce gas cost for wallet activation.\n * Within the constructor this conducts diamond cut to initially setup the diamond. This is a non-upgradeable contract\n * @param _diamondCutFacet Address if diamond cut facet\n * @param _accountFacet Address account facet\n * @param _tokenReceiverFacet Address of token receiver facet\n * @param _diamondLoupeFacet Address of diamond loupe facet\n */\n constructor(\n address _diamondCutFacet,\n address _accountFacet,\n address _tokenReceiverFacet,\n address _diamondLoupeFacet\n ) payable {\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](4);\n bytes4[] memory functionSelectors = new bytes4[](1);\n functionSelectors[0] = IDiamondCut.diamondCut.selector;\n\n bytes4[] memory accountFunctionSelectors = new bytes4[](5);\n accountFunctionSelectors[0] = IAccountFacet.execute.selector;\n accountFunctionSelectors[1] = IAccountFacet.executeBatch.selector;\n accountFunctionSelectors[2] = BaseAccount.validateUserOp.selector;\n accountFunctionSelectors[3] = BaseAccount.getNonce.selector;\n accountFunctionSelectors[4] = BaseAccount.entryPoint.selector;\n\n bytes4[] memory receiverFacetSelectors = new bytes4[](5);\n receiverFacetSelectors[0] = IERC721Receiver.onERC721Received.selector;\n receiverFacetSelectors[1] = IERC1155Receiver.onERC1155Received.selector;\n receiverFacetSelectors[2] = IERC1155Receiver\n .onERC1155BatchReceived\n .selector;\n receiverFacetSelectors[3] = IERC777Recipient.tokensReceived.selector;\n receiverFacetSelectors[4] = IERC677Receiver.onTokenTransfer.selector;\n\n bytes4[] memory loupeFacetSelectors = new bytes4[](9);\n loupeFacetSelectors[0] = IDiamondLoupe.facets.selector;\n loupeFacetSelectors[1] = IDiamondLoupe.facetFunctionSelectors.selector;\n loupeFacetSelectors[2] = IDiamondLoupe.facetAddresses.selector;\n loupeFacetSelectors[3] = IDiamondLoupe.facetAddress.selector;\n loupeFacetSelectors[4] = IERC165.supportsInterface.selector;\n loupeFacetSelectors[5] = IStorageLoupe.facetsFromStorage.selector;\n loupeFacetSelectors[6] = IStorageLoupe\n .facetFunctionSelectorsFromStorage\n .selector;\n loupeFacetSelectors[7] = IStorageLoupe\n .facetAddressesFromStorage\n .selector;\n loupeFacetSelectors[8] = IStorageLoupe.facetAddressFromStorage.selector;\n\n {\n cut[0] = IDiamondCut.FacetCut({\n facetAddress: _diamondCutFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: functionSelectors\n });\n cut[1] = IDiamondCut.FacetCut({\n facetAddress: _accountFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: accountFunctionSelectors\n });\n cut[2] = IDiamondCut.FacetCut({\n facetAddress: _tokenReceiverFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: receiverFacetSelectors\n });\n cut[3] = IDiamondCut.FacetCut({\n facetAddress: _diamondLoupeFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: loupeFacetSelectors\n });\n\n DefaultLibDiamond.diamondCut(cut, address(0), \"\");\n }\n }\n\n /**\n * @notice Returns the facet information of call facets registered to this diamond.\n * @return facets_ The facet struct array including all facet information\n */\n function facets() external view override returns (Facet[] memory facets_) {\n DefaultLibDiamond.DiamondStorage storage ds = DefaultLibDiamond\n .diamondStorage();\n uint256 numFacets = ds.facetAddresses.length;\n facets_ = new Facet[](numFacets);\n for (uint256 i; i < numFacets; ) {\n address facetAddress_ = ds.facetAddresses[i];\n facets_[i].facetAddress = facetAddress_;\n facets_[i].functionSelectors = ds\n .facetFunctionSelectors[facetAddress_]\n .functionSelectors;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Gets all the function selectors provided by a facet.\n * @param _facet The facet address.\n * @return facetFunctionSelectors_\n */\n function facetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n facetFunctionSelectors_ = DefaultLibDiamond\n .diamondStorage()\n .facetFunctionSelectors[_facet]\n .functionSelectors;\n }\n\n /**\n * @notice Get all the facet addresses used by a diamond.\n * @return facetAddresses_\n */\n function facetAddresses()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n facetAddresses_ = DefaultLibDiamond.diamondStorage().facetAddresses;\n }\n\n /** @notice Gets the facet that supports the given selector.\n * @dev If facet is not found return address(0).\n * @param _functionSelector The function selector.\n * @return facetAddress_ The facet address.\n */\n function facetAddress(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n facetAddress_ = DefaultLibDiamond\n .diamondStorage()\n .selectorToFacetAndPosition[_functionSelector]\n .facetAddress;\n }\n}\n" + }, + "contracts/infrastructure/FacetRegistry.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport {IFacetRegistry} from \"./interfaces/IFacetRegistry.sol\";\n\n/**\n * @title Facet Registry\n * @dev Contract to keep track of facets & function selectors addable to user wallets\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract FacetRegistry is IFacetRegistry, Ownable2Step {\n mapping(address => FacetRegistryConfig) private facets;\n\n /**\n * @notice Transfers the ownership of the contract to the given owner\n * @param _owner Address of owner who has access to initialize the default security variables for security manager\n */\n constructor(address _owner) {\n transferOwnership(_owner);\n _transferOwnership(_owner);\n }\n\n /**\n * @dev Registers a facet and it's function selectors to registry\n * @param _facet address of facet\n * @param _facetSelectors list of function selectors of the facet\n */\n function registerFacetFunctionSelectors(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external override onlyOwner {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n for (uint256 i; i < _facetSelectors.length; ) {\n if (facetConfig.info[_facetSelectors[i]].exists)\n revert FacetRegistry__FacetSelectorAlreadyRegistered();\n\n facetConfig.info[_facetSelectors[i]].exists = true;\n facetConfig.info[_facetSelectors[i]].index = uint128(\n facetConfig.selectors.length\n );\n facetConfig.selectors.push(_facetSelectors[i]);\n unchecked {\n ++i;\n }\n }\n emit FacetFunctionSelectorsRegistered(_facet, _facetSelectors);\n }\n\n /**\n * @dev Removes a registered facet and it's corresponding selectors from registry\n * @param _facet address of facet\n * @param _facetSelectors list of function selectors of the facet\n */\n function removeFacetFunctionSelectors(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external override onlyOwner {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n for (uint256 i; i < _facetSelectors.length; ) {\n if (!facetConfig.info[_facetSelectors[i]].exists)\n revert FacetRegistry__UnregisteredFacetSelector();\n\n bytes4 lastSelector = facetConfig.selectors[\n facetConfig.selectors.length - 1\n ];\n if (_facetSelectors[i] != lastSelector) {\n uint128 targetIndex = facetConfig\n .info[_facetSelectors[i]]\n .index;\n facetConfig.selectors[targetIndex] = lastSelector;\n facetConfig.info[lastSelector].index = targetIndex;\n }\n facetConfig.selectors.pop();\n delete facetConfig.info[_facetSelectors[i]];\n\n unchecked {\n ++i;\n }\n }\n emit FacetFunctionSelectorsRemoved(_facet, _facetSelectors);\n }\n\n /**\n * @dev Checks if a facet and it's selectors given is registered to facet registry\n * @param _facet Address of facet\n * @param _facetSelectors List of function selectors of the facet\n */\n function areFacetFunctionSelectorsRegistered(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external view override returns (bool) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n if (_facetSelectors.length == 0) return false;\n for (uint256 i; i < _facetSelectors.length; ) {\n if (!facetConfig.info[_facetSelectors[i]].exists) return false;\n unchecked {\n ++i;\n }\n }\n return true;\n }\n\n /**\n * @dev Checks if a facet and it's selector given is registered to facet registry\n * @param _facet Address of facet\n * @param _facetSelector List of function selectors of the facet\n * @return isRegistered Bool value showing if the selector is registered\n */\n function isFacetFunctionSelectorRegistered(\n address _facet,\n bytes4 _facetSelector\n ) external view override returns (bool isRegistered) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n isRegistered = facetConfig.info[_facetSelector].exists;\n }\n\n /**\n * @dev Get the registered selectors of facet from registry\n * @param _facet Address of facet\n * @return selectors Selectors registered to facet\n */\n function getFacetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory selectors) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n selectors = facetConfig.selectors;\n }\n}\n" + }, + "contracts/infrastructure/interfaces/IFacetRegistry.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Registry Interface\n * @dev Interface for Facet Registry contract to keep track of facets & function selectors addable to user wallets\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IFacetRegistry {\n struct FacetRegistryConfig {\n bytes4[] selectors;\n mapping(bytes4 => FacetInfo) info;\n }\n struct FacetInfo {\n bool exists;\n uint128 index;\n }\n\n event FacetFunctionSelectorsRegistered(\n address facet,\n bytes4[] facetSelectors\n );\n event FacetFunctionSelectorsRemoved(address facet, bytes4[] facetSelectors);\n\n error FacetRegistry__FacetSelectorAlreadyRegistered();\n error FacetRegistry__UnregisteredFacetSelector();\n\n function registerFacetFunctionSelectors(\n address facet,\n bytes4[] calldata facetSelectors\n ) external;\n\n function removeFacetFunctionSelectors(\n address facet,\n bytes4[] calldata facetSelectors\n ) external;\n\n function areFacetFunctionSelectorsRegistered(\n address facet,\n bytes4[] calldata facetSelectors\n ) external view returns (bool);\n\n function isFacetFunctionSelectorRegistered(\n address facet,\n bytes4 facetSelector\n ) external view returns (bool);\n\n function getFacetFunctionSelectors(\n address facet\n ) external view returns (bytes4[] memory);\n}\n" + }, + "contracts/infrastructure/interfaces/ISecurityManager.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Registry Interface\n * @dev Infrastructure contract to manage security parameters of users\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface ISecurityManager {\n error SecurityManager__OutOfBoundary();\n error SecurityManager__CallerNotWallet();\n error SecurityManager__AlreadyIntialized();\n\n function initializeAdditionSecurityPeriod(\n uint128 defaultAdditionSecurityPeriod,\n uint128 minAdditionSecurityPeriod,\n uint128 maxAdditionSecurityPeriod\n ) external;\n\n function initializeRemovalSecurityPeriod(\n uint128 defaultRemovalSecurityPeriod,\n uint128 minRemovalSecurityPeriod,\n uint128 maxRemovalSecurityPeriod\n ) external;\n\n function initializeApprovalValidationPeriod(\n uint128 defaultApprovalValidationPeriod,\n uint128 minApprovalValidationPeriod,\n uint128 maxApprovalValidationPeriod\n ) external;\n\n function initializeMigrationPeriod(\n uint128 defaultMigrationPeriod,\n uint128 minMigrationPeriod,\n uint128 maxMigrationPeriod\n ) external;\n\n function initializeLockPeriod(\n uint128 defaultLockPeriod,\n uint128 minLockPeriod,\n uint128 maxLockPeriod\n ) external;\n\n function initializeRecoveryPeriod(\n uint128 defaultRecoveryPeriod,\n uint128 minRecoveryPeriod,\n uint128 maxRecoveryPeriod\n ) external;\n\n function initializeSecurityWindow(\n uint128 defaultSecurityWindow,\n uint128 minSecurityWindow,\n uint128 maxSecurityWindow\n ) external;\n\n function setAdditionSecurityPeriod(\n address wallet,\n uint128 additionSecurityPeriod\n ) external;\n\n function setRemovalSecurityPeriod(\n address wallet,\n uint128 removalSecurityPeriod\n ) external;\n\n function setSecurityWindow(address wallet, uint128 securityWindow) external;\n\n function setRecoveryPeriod(address wallet, uint128 recoveryPeriod) external;\n\n function setLockPeriod(address wallet, uint128 lockPeriod) external;\n\n function setApprovalValidationPeriod(\n address wallet,\n uint128 approvalValidationPeriod\n ) external;\n\n function setMigrationPeriod(\n address wallet,\n uint128 migrationPeriod\n ) external;\n\n function additionSecurityPeriodOf(\n address wallet\n ) external view returns (uint128);\n\n function removalSecurityPeriodOf(\n address wallet\n ) external view returns (uint128);\n\n function securityWindowOf(address wallet) external view returns (uint128);\n\n function recoveryPeriodOf(address wallet) external view returns (uint128);\n\n function lockPeriodOf(address wallet) external view returns (uint128);\n\n function migrationPeriodOf(address wallet) external view returns (uint128);\n\n function approvalValidationPeriodOf(\n address wallet\n ) external view returns (uint128);\n}\n" + }, + "contracts/infrastructure/RemoteStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IGuardianFacet} from \"../facets/interfaces/IGuardianFacet.sol\";\n\n/**\n * @title Remote Storage\n * @dev Remote storage allows you to associate addresses with an array of addresses on a standalone smart contract.\n * This could be useful when you don't want to use the local diamond storage for some purpose.\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\nabstract contract RemoteStorage {\n struct StorageConfig {\n address[] addresses;\n mapping(address => Info) info;\n }\n\n struct Info {\n bool exists;\n uint128 index;\n }\n\n mapping(address => StorageConfig) internal configs;\n\n event Added(address _address);\n event Removed(address _address);\n\n error RemoteStorage__CallerNotOwner();\n error RemoteStorage__CallerNotGuardianOrOwner();\n error RemoteStorage__AlreadyExists();\n error RemoteStorage__NotFound();\n error RemoteStorage__CallerNotGuardian();\n\n bytes4 constant IS_GUARDIAN_SELECTOR =\n bytes4(keccak256(\"isGuardian(address)\"));\n bytes4 constant GUARDIAN_COUNT = bytes4(keccak256(\"guardianCount()\"));\n\n /**\n * @notice Modifier to only allow the self to call. Reverts otherwise\n */\n modifier onlyWallet(address _wallet) {\n if (msg.sender != _wallet) revert RemoteStorage__CallerNotOwner();\n _;\n }\n\n /**\n * @notice Enfore the callet to be wallet of guardian of the wallet\n * @param _wallet Address of wallet\n */\n function enforceGuardianOrWallet(address _wallet) internal view {\n if (msg.sender == _wallet) return;\n address facetAddress = IDiamondLoupe(_wallet).facetAddress(\n IS_GUARDIAN_SELECTOR\n );\n if (facetAddress != address(0))\n if (IGuardianFacet(_wallet).isGuardian(msg.sender)) return;\n revert RemoteStorage__CallerNotGuardianOrOwner();\n }\n\n /**\n * @notice Enforce the caller to be wallet IF guardians doesn't exists and only guardian when guardians exists\n * @param _wallet Target wallet address to be handled by infrastructure contracts\n */\n function enforceWalletOrGuardianIfExists(address _wallet) internal view {\n address facetAddress;\n if (msg.sender == _wallet) {\n facetAddress = IDiamondLoupe(_wallet).facetAddress(GUARDIAN_COUNT);\n if (facetAddress == address(0)) return;\n uint256 guardianCount = IGuardianFacet(_wallet).guardianCount();\n if (guardianCount != 0) revert RemoteStorage__CallerNotGuardian();\n return;\n }\n facetAddress = IDiamondLoupe(_wallet).facetAddress(\n IS_GUARDIAN_SELECTOR\n );\n if (facetAddress != address(0))\n if (IGuardianFacet(_wallet).isGuardian(msg.sender)) return;\n\n revert RemoteStorage__CallerNotGuardianOrOwner();\n }\n\n /**\n * @notice Add address to storage and reverts if the address already exists.\n * This is an internal function callable from contracts that inherit this abstract contract\n * @param _wallet Address of wallet to add the address\n * @param _address Address to be added to wallet\n */\n function addAddress(address _wallet, address _address) internal {\n StorageConfig storage config = configs[_wallet];\n if (config.info[_address].exists) revert RemoteStorage__AlreadyExists();\n\n config.info[_address].exists = true;\n config.info[_address].index = uint128(config.addresses.length);\n config.addresses.push(_address);\n\n emit Added(_address);\n }\n\n /**\n * @notice Remove address from storage and reverts if the address already exists.\n * This is an internal function callable from contracts that inherit this abstract contract\n * @param _wallet Address of wallet to remove the address\n * @param _address Address to be removed from wallet\n */\n function removeAddress(address _wallet, address _address) internal {\n StorageConfig storage config = configs[_wallet];\n if (!config.info[_address].exists) revert RemoteStorage__NotFound();\n\n address lastAddress = config.addresses[config.addresses.length - 1];\n if (_address != lastAddress) {\n uint128 targetIndex = config.info[_address].index;\n config.addresses[targetIndex] = lastAddress;\n config.info[lastAddress].index = targetIndex;\n }\n config.addresses.pop();\n delete config.info[_address];\n\n emit Removed(_address);\n }\n\n /**\n * @notice Returns the address added to the given wallet\n * @param _wallet Address of wallet to fetch the addresses added to it\n * @return addresses List of addresses added to the wallet\n */\n function getAddresses(\n address _wallet\n ) internal view returns (address[] memory addresses) {\n StorageConfig storage config = configs[_wallet];\n addresses = new address[](config.addresses.length);\n uint addressesLen = config.addresses.length;\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns bool value checking if the address exists in the given wallet address\n * @param _wallet Wallet address to check\n * @param _address Address to fetch if the address if added to given wallet\n * @return exists_ Bool value showing if the address exists in wallet\n */\n function exists(\n address _wallet,\n address _address\n ) internal view returns (bool exists_) {\n exists_ = configs[_wallet].info[_address].exists;\n }\n\n /**\n * @notice Returns the number of addresses added to the wallet\n * @param _wallet Address of wallet to check\n * @return count_ Number of addresses added to wallet\n */\n function count(address _wallet) internal view returns (uint256 count_) {\n count_ = configs[_wallet].addresses.length;\n }\n}\n" + }, + "contracts/infrastructure/SecurityManager.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport {ISecurityManager} from \"./interfaces/ISecurityManager.sol\";\n\n/**\n * @title Security Manager\n * @dev Infrastructure contract to manage security parameters of users\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract SecurityManager is ISecurityManager, Ownable2Step {\n uint128 public minAdditionSecurityPeriod;\n uint128 public maxAdditionSecurityPeriod;\n uint128 private defaultAdditionSecurityPeriod;\n\n uint128 public minRemovalSecurityPeriod;\n uint128 public maxRemovalSecurityPeriod;\n uint128 private defaultRemovalSecurityPeriod;\n\n uint128 public minSecurityWindow;\n uint128 public maxSecurityWindow;\n uint128 private defaultSecurityWindow;\n\n uint128 public minRecoveryPeriod;\n uint128 public maxRecoveryPeriod;\n uint128 private defaultRecoveryPeriod;\n\n uint128 public minLockPeriod;\n uint128 public maxLockPeriod;\n uint128 private defaultLockPeriod;\n\n uint128 public minApprovalValidationPeriod;\n uint128 public maxApprovalValidationPeriod;\n uint128 private defaultApprovalValidationPeriod;\n\n uint128 public minMigrationPeriod;\n uint128 public maxMigrationPeriod;\n uint128 private defaultMigrationPeriod;\n\n bool public _isAdditionSecurityPeriodInitialized;\n bool public _isRemovalSecurityPeriodInitialized;\n bool public _isSecurityWindowInitialized;\n bool public _isRecoveryPeriodInitialized;\n bool public _isLockPeriodInitialized;\n bool public _isApprovalValidationPeriodInitialized;\n bool public _isMigrationPeriodInitialized;\n\n mapping(address => CustomSecurityConfig) securityConfigs;\n\n struct CustomSecurityConfig {\n uint128 additionSecurityPeriod;\n uint128 removalSecurityPeriod;\n uint128 securityWindow;\n uint128 recoveryPeriod;\n uint128 lockPeriod;\n uint128 approvalValidationPeriod;\n uint128 migrationPeriod;\n }\n\n /**\n * @notice Modifier to only allow wallet itself to make a call to wallet\n */\n modifier onlyWallet(address _wallet) {\n if (msg.sender != _wallet) revert SecurityManager__CallerNotWallet();\n _;\n }\n\n /**\n * @notice Modifier to revert if the variable is already initialized\n */\n modifier initializer(bool _isInitialized) {\n if (_isInitialized) revert SecurityManager__AlreadyIntialized();\n _;\n }\n\n /**\n * @notice Transfers the ownership of the contract to the given owner\n * @param _owner Address of owner who has access to initialize the default security variables for security manager\n */\n constructor(address _owner) {\n transferOwnership(_owner);\n _transferOwnership(_owner);\n }\n\n /**\n * @notice Sets the initial default/min/max addition security period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultAdditionSecurityPeriod Default Addition Security Period for all Barz contracts\n * @param _minAdditionSecurityPeriod Minimum Addition Security Period for all Barz contracts\n * @param _maxAdditionSecurityPeriod Maximum Addition Security Period for all Barz contracts\n */\n function initializeAdditionSecurityPeriod(\n uint128 _defaultAdditionSecurityPeriod,\n uint128 _minAdditionSecurityPeriod,\n uint128 _maxAdditionSecurityPeriod\n )\n external\n override\n onlyOwner\n initializer(_isAdditionSecurityPeriodInitialized)\n {\n _isAdditionSecurityPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultAdditionSecurityPeriod,\n _minAdditionSecurityPeriod,\n _maxAdditionSecurityPeriod\n );\n defaultAdditionSecurityPeriod = _defaultAdditionSecurityPeriod;\n minAdditionSecurityPeriod = _minAdditionSecurityPeriod;\n maxAdditionSecurityPeriod = _maxAdditionSecurityPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max removal security period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultRemovalSecurityPeriod Default Removal Security Period for all Barz contracts\n * @param _minRemovalSecurityPeriod Minimum Removal Security Period for all Barz contracts\n * @param _maxRemovalSecurityPeriod Maximum Removal Security Period for all Barz contracts\n */\n function initializeRemovalSecurityPeriod(\n uint128 _defaultRemovalSecurityPeriod,\n uint128 _minRemovalSecurityPeriod,\n uint128 _maxRemovalSecurityPeriod\n )\n external\n override\n onlyOwner\n initializer(_isRemovalSecurityPeriodInitialized)\n {\n _isRemovalSecurityPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultRemovalSecurityPeriod,\n _minRemovalSecurityPeriod,\n _maxRemovalSecurityPeriod\n );\n defaultRemovalSecurityPeriod = _defaultRemovalSecurityPeriod;\n minRemovalSecurityPeriod = _minRemovalSecurityPeriod;\n maxRemovalSecurityPeriod = _maxRemovalSecurityPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/maxd security window for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultSecurityWindow Default Security Window for all Barz contracts\n * @param _minSecurityWindow Minimum Security Window for all Barz contracts\n * @param _maxSecurityWindow Maximum Security Window for all Barz contracts\n */\n function initializeSecurityWindow(\n uint128 _defaultSecurityWindow,\n uint128 _minSecurityWindow,\n uint128 _maxSecurityWindow\n ) external override onlyOwner initializer(_isSecurityWindowInitialized) {\n _isSecurityWindowInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultSecurityWindow,\n _minSecurityWindow,\n _maxSecurityWindow\n );\n defaultSecurityWindow = _defaultSecurityWindow;\n minSecurityWindow = _minSecurityWindow;\n maxSecurityWindow = _maxSecurityWindow;\n }\n\n /**\n * @notice Sets the initial default/min/max recovery period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultRecoveryPeriod Default Recovery Period for all Barz contracts\n * @param _minRecoveryPeriod Minimum Recovery Period for all Barz contracts\n * @param _maxRecoveryPeriod Maximum Recovery Period for all Barz contracts\n */\n function initializeRecoveryPeriod(\n uint128 _defaultRecoveryPeriod,\n uint128 _minRecoveryPeriod,\n uint128 _maxRecoveryPeriod\n ) external override onlyOwner initializer(_isRecoveryPeriodInitialized) {\n _isRecoveryPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultRecoveryPeriod,\n _minRecoveryPeriod,\n _maxRecoveryPeriod\n );\n defaultRecoveryPeriod = _defaultRecoveryPeriod;\n minRecoveryPeriod = _minRecoveryPeriod;\n maxRecoveryPeriod = _maxRecoveryPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max lock period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultLockPeriod Default Lock Period for all Barz contracts\n * @param _minLockPeriod Minimum Lock Period for all Barz contracts\n * @param _maxLockPeriod Maximum Lock Period for all Barz contracts\n */\n function initializeLockPeriod(\n uint128 _defaultLockPeriod,\n uint128 _minLockPeriod,\n uint128 _maxLockPeriod\n ) external override onlyOwner initializer(_isLockPeriodInitialized) {\n _isLockPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultLockPeriod,\n _minLockPeriod,\n _maxLockPeriod\n );\n defaultLockPeriod = _defaultLockPeriod;\n minLockPeriod = _minLockPeriod;\n maxLockPeriod = _maxLockPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max approval validation period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultApprovalValidationPeriod Default Approval Validation Period for all Barz contracts\n * @param _minApprovalValidationPeriod Minimum Approval Validation Period for all Barz contracts\n * @param _maxApprovalValidationPeriod Maximum Approval Validation Period for all Barz contracts\n */\n function initializeApprovalValidationPeriod(\n uint128 _defaultApprovalValidationPeriod,\n uint128 _minApprovalValidationPeriod,\n uint128 _maxApprovalValidationPeriod\n )\n external\n override\n onlyOwner\n initializer(_isApprovalValidationPeriodInitialized)\n {\n _isApprovalValidationPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultApprovalValidationPeriod,\n _minApprovalValidationPeriod,\n _maxApprovalValidationPeriod\n );\n defaultApprovalValidationPeriod = _defaultApprovalValidationPeriod;\n minApprovalValidationPeriod = _minApprovalValidationPeriod;\n maxApprovalValidationPeriod = _maxApprovalValidationPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max migration period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultMigrationPeriod Default Migration Period for all Barz contracts\n * @param _minMigrationPeriod Minimum Migration Period for all Barz contracts\n * @param _maxMigrationPeriod Maximum Migration Period for all Barz contracts\n */\n function initializeMigrationPeriod(\n uint128 _defaultMigrationPeriod,\n uint128 _minMigrationPeriod,\n uint128 _maxMigrationPeriod\n ) external override onlyOwner initializer(_isMigrationPeriodInitialized) {\n _isMigrationPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultMigrationPeriod,\n _minMigrationPeriod,\n _maxMigrationPeriod\n );\n defaultMigrationPeriod = _defaultMigrationPeriod;\n minMigrationPeriod = _minMigrationPeriod;\n maxMigrationPeriod = _maxMigrationPeriod;\n }\n\n /**\n * @notice Wallet owner sets the addition security period for the wallet. Only the owner of wallet can call this function.\n * The addition security period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _additionSecurityPeriod Custom Addition Security Period for the wallet\n */\n function setAdditionSecurityPeriod(\n address _wallet,\n uint128 _additionSecurityPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _additionSecurityPeriod,\n minAdditionSecurityPeriod,\n maxAdditionSecurityPeriod\n );\n securityConfigs[_wallet]\n .additionSecurityPeriod = _additionSecurityPeriod;\n }\n\n /**\n * @notice Wallet owner sets the removal security period for the wallet. Only the owner of wallet can call this function.\n * The removal security period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _removalSecurityPeriod Custom Removal Security Period for the wallet\n */\n function setRemovalSecurityPeriod(\n address _wallet,\n uint128 _removalSecurityPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _removalSecurityPeriod,\n minRemovalSecurityPeriod,\n maxRemovalSecurityPeriod\n );\n securityConfigs[_wallet].removalSecurityPeriod = _removalSecurityPeriod;\n }\n\n /**\n * @notice Wallet owner sets the security window for the wallet. Only the owner of wallet can call this function.\n * The security window should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _securityWindow Custom Security Window for the wallet\n */\n function setSecurityWindow(\n address _wallet,\n uint128 _securityWindow\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _securityWindow,\n minSecurityWindow,\n maxSecurityWindow\n );\n securityConfigs[_wallet].securityWindow = _securityWindow;\n }\n\n /**\n * @notice Wallet owner sets the recovery period for the wallet. Only the owner of wallet can call this function.\n * The recovery period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _recoveryPeriod Custom recovery period for the wallet\n */\n function setRecoveryPeriod(\n address _wallet,\n uint128 _recoveryPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _recoveryPeriod,\n minRecoveryPeriod,\n maxRecoveryPeriod\n );\n securityConfigs[_wallet].recoveryPeriod = _recoveryPeriod;\n }\n\n /**\n * @notice Wallet owner sets the lock period for the wallet. Only the owner of wallet can call this function.\n * The lock period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _lockPeriod Custom Lock period for the wallet\n */\n function setLockPeriod(\n address _wallet,\n uint128 _lockPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(_lockPeriod, minLockPeriod, maxLockPeriod);\n securityConfigs[_wallet].lockPeriod = _lockPeriod;\n }\n\n /**\n * @notice Wallet owner sets the approval validation period for the wallet. Only the owner of wallet can call this function.\n * The approval validation period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _approvalValidationPeriod Custom approval validation period for the wallet\n */\n function setApprovalValidationPeriod(\n address _wallet,\n uint128 _approvalValidationPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _approvalValidationPeriod,\n minApprovalValidationPeriod,\n maxApprovalValidationPeriod\n );\n securityConfigs[_wallet]\n .approvalValidationPeriod = _approvalValidationPeriod;\n }\n\n /**\n * @notice Wallet owner sets the migration period for the wallet. Only the owner of wallet can call this function.\n * The migration period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _migrationPeriod Custom migration period for the wallet\n */\n\n function setMigrationPeriod(\n address _wallet,\n uint128 _migrationPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _migrationPeriod,\n minMigrationPeriod,\n maxMigrationPeriod\n );\n securityConfigs[_wallet].migrationPeriod = _migrationPeriod;\n }\n\n /**\n * @notice Returns the addition security period. Returns default value when custom addition security period is not set\n * @param _wallet Address of wallet\n * @return additionSecurityPeriod Addition Security Period of the given Barz account or wallet\n */\n function additionSecurityPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 additionSecurityPeriod)\n {\n additionSecurityPeriod = securityConfigs[_wallet]\n .additionSecurityPeriod;\n additionSecurityPeriod = (additionSecurityPeriod == 0)\n ? defaultAdditionSecurityPeriod\n : additionSecurityPeriod;\n }\n\n /**\n * @notice Returns the removal security period. Returns default value when custom removal security period is not set\n * @param _wallet Address of wallet\n * @return removalSecurityPeriod Removal Security Period of the given Barz account or wallet\n */\n function removalSecurityPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 removalSecurityPeriod)\n {\n removalSecurityPeriod = securityConfigs[_wallet].removalSecurityPeriod;\n removalSecurityPeriod = (removalSecurityPeriod == 0)\n ? defaultRemovalSecurityPeriod\n : removalSecurityPeriod;\n }\n\n /**\n * @notice Returns the security window. Returns default value when custom security window is not set\n * @param _wallet Address of wallet\n * @return securityWindow Security window of the given Barz account or wallet\n */\n function securityWindowOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 securityWindow)\n {\n securityWindow = securityConfigs[_wallet].securityWindow;\n securityWindow = (securityWindow == 0)\n ? defaultSecurityWindow\n : securityWindow;\n }\n\n /**\n * @notice Returns the recovery period. Returns default value when custom recovery period is not set\n * @param _wallet Address of wallet\n * @return recoveryPeriod Recovery Period of the given Barz account or wallet\n */\n function recoveryPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 recoveryPeriod)\n {\n recoveryPeriod = securityConfigs[_wallet].recoveryPeriod;\n recoveryPeriod = (recoveryPeriod == 0)\n ? defaultRecoveryPeriod\n : recoveryPeriod;\n }\n\n /**\n * @notice Returns the lock period. Returns default value when custom lock period is not set\n * @param _wallet Address of wallet\n * @return lockPeriod Lock Period of the given Barz account or wallet\n */\n function lockPeriodOf(\n address _wallet\n ) public view override onlyWallet(_wallet) returns (uint128 lockPeriod) {\n lockPeriod = securityConfigs[_wallet].lockPeriod;\n lockPeriod = (lockPeriod == 0) ? defaultLockPeriod : lockPeriod;\n }\n\n /**\n * @notice Returns the approval validation period. Returns default value when custom approval validation period is not set\n * @param _wallet Address of wallet\n * @return approvalValidationPeriod Approval Validation Period of the given Barz account or wallet\n */\n function approvalValidationPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityConfigs[_wallet]\n .approvalValidationPeriod;\n approvalValidationPeriod = (approvalValidationPeriod == 0)\n ? defaultApprovalValidationPeriod\n : approvalValidationPeriod;\n }\n\n /**\n * @notice Returns the migration period. Returns default value when custom migration period is not set\n * @param _wallet Address of wallet\n * @return migrationPeriod Migration Period of the given Barz account or wallet\n */\n function migrationPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 migrationPeriod)\n {\n migrationPeriod = securityConfigs[_wallet].migrationPeriod;\n migrationPeriod = (migrationPeriod == 0)\n ? defaultMigrationPeriod\n : migrationPeriod;\n }\n\n /**\n * @notice Validates if the period is smaller than the max period or bigger than the min period\n * @param _period Period to be checked\n * @param _minPeriod Minimum period\n * @param _maxPeriod Maximum period\n */\n function _validatePeriodBoundaries(\n uint128 _period,\n uint128 _minPeriod,\n uint128 _maxPeriod\n ) internal pure {\n if (_period >= _maxPeriod || _period <= _minPeriod)\n revert SecurityManager__OutOfBoundary();\n }\n}\n" + }, + "contracts/infrastructure/WhitelistStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {RemoteStorage} from \"./RemoteStorage.sol\";\n\n/**\n * @title Whitelist storage\n * @dev Maps addresses to the corresponsing array of whitelisted addresses for each of them.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract WhitelistStorage is RemoteStorage {\n /**\n * @dev Add the address to the whitelist storage\n * @param _wallet User wallet\n * @param _address Address to be whitelisted\n */\n function whitelistAddress(address _wallet, address _address) external {\n enforceWalletOrGuardianIfExists(_wallet);\n addAddress(_wallet, _address);\n }\n\n /**\n * @dev Removes the address from the whitelist storage\n * @param _wallet User wallet\n * @param _address Address to be removed from the whitelist\n */\n function blacklistAddress(address _wallet, address _address) external {\n enforceGuardianOrWallet(_wallet);\n removeAddress(_wallet, _address);\n }\n\n /**\n * @dev Returns whether the address exists in the whitelist storage, associated with the wallet\n * @param _wallet User wallet\n * @param _address Address to be whitelisted\n */\n function isWhitelisted(\n address _wallet,\n address _address\n ) external view returns (bool) {\n return exists(_wallet, _address);\n }\n\n /**\n * @dev Returns all whitelisted addresses associated with the wallet\n * @param _wallet User wallet\n */\n function getWhitelistedAddresses(\n address _wallet\n ) external view returns (address[] memory) {\n return getAddresses(_wallet);\n }\n}\n" + }, + "contracts/interfaces/ERC/IERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\n\npragma solidity 0.8.21;\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155Receiver {\n /**\n * @dev Handles the receipt of a single ERC1155 token type. This function is\n * called at the end of a `safeTransferFrom` after the balance has been updated.\n *\n * NOTE: To accept the transfer, this must return\n * `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n * (i.e. 0xf23a6e61, or its own function selector).\n *\n * @param operator The address which initiated the transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param id The ID of the token being transferred\n * @param value The amount of tokens being transferred\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n ) external returns (bytes4);\n\n /**\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\n * is called at the end of a `safeBatchTransferFrom` after the balances have\n * been updated.\n *\n * NOTE: To accept the transfer(s), this must return\n * `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n * (i.e. 0xbc197c81, or its own function selector).\n *\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "contracts/interfaces/ERC/IERC1271.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\ninterface IERC1271 {\n function isValidSignature(\n bytes32 hash,\n bytes memory signature\n ) external view returns (bytes4);\n}\n" + }, + "contracts/interfaces/ERC/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\ninterface IERC165 {\n /// @notice Query if a contract implements an interface\n /// @param interfaceId The interface identifier, as specified in ERC-165\n /// @dev Interface identification is specified in ERC-165. This function\n /// uses less than 30,000 gas.\n /// @return `true` if the contract implements `interfaceID` and\n /// `interfaceID` is not 0xffffffff, `false` otherwise\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/IERC173.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\n/// @title ERC-173 Contract Ownership Standard\n/// Note: the ERC-165 identifier for this interface is 0x7f5828d0\n/* is ERC165 */\ninterface IERC173 {\n /// @dev This emits when ownership of a contract changes.\n event OwnershipTransferred(\n address indexed previousOwner,\n address indexed newOwner\n );\n\n /// @notice Get the address of the owner\n /// @return owner_ The address of the owner.\n function owner() external view returns (address owner_);\n\n /// @notice Set the address of the new owner of the contract\n /// @dev Set _newOwner to address(0) to renounce any ownership.\n /// @param _newOwner The address of the new owner of the contract\n function transferOwnership(address _newOwner) external;\n}\n" + }, + "contracts/interfaces/ERC/IERC677Receiver.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\ninterface IERC677Receiver {\n function onTokenTransfer(\n address sender,\n uint value,\n bytes calldata data\n ) external pure returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155 is IERC165 {\n /**\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n */\n event TransferSingle(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256 id,\n uint256 value\n );\n\n /**\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n * transfers.\n */\n event TransferBatch(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\n\n /**\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n * `approved`.\n */\n event ApprovalForAll(\n address indexed account,\n address indexed operator,\n bool approved\n );\n\n /**\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n *\n * If an {URI} event was emitted for `id`, the standard\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n * returned by {IERC1155MetadataURI-uri}.\n */\n event URI(string value, uint256 indexed id);\n\n /**\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(\n address account,\n uint256 id\n ) external view returns (uint256);\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] calldata accounts,\n uint256[] calldata ids\n ) external view returns (uint256[] memory);\n\n /**\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n *\n * Emits an {ApprovalForAll} event.\n *\n * Requirements:\n *\n * - `operator` cannot be the caller.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n *\n * See {setApprovalForAll}.\n */\n function isApprovedForAll(\n address account,\n address operator\n ) external view returns (bool);\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes calldata data\n ) external;\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(\n address indexed owner,\n address indexed spender,\n uint256 value\n );\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` 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 amount) 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(\n address owner,\n address spender\n ) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the 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 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` 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(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(\n address spender,\n uint256 addedValue\n ) external returns (bool);\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(\n address spender,\n uint256 subtractedValue\n ) external returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(\n address indexed from,\n address indexed to,\n uint256 indexed tokenId\n );\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(\n address indexed owner,\n address indexed approved,\n uint256 indexed tokenId\n );\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(\n address indexed owner,\n address indexed operator,\n bool approved\n );\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(\n uint256 tokenId\n ) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(\n address owner,\n address operator\n ) external view returns (bool);\n}\n" + }, + "contracts/interfaces/IBarz.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Barz Interface\n * @dev Interface of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IBarz {\n error Barz__InitializationFailure();\n}\n" + }, + "contracts/interfaces/IBarzFactory.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Barz} from \"../Barz.sol\";\n\n/**\n * @title Barz Factory Interface\n * @dev Interface of contract to easily deploy Barz to a pre-computed address with a single call\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IBarzFactory {\n function createAccount(\n address verificationFacet,\n bytes calldata owner,\n uint256 salt\n ) external returns (Barz);\n\n function getAddress(\n address verificationFacet,\n bytes calldata owner,\n uint256 salt\n ) external view returns (address);\n\n function getBytecode(\n address accountFacet,\n address verificationFacet,\n address entryPoint,\n address facetRegistry,\n address defaultFallback,\n bytes memory ownerPublicKey\n ) external pure returns (bytes memory);\n\n function getCreationCode() external pure returns (bytes memory);\n}\n" + }, + "contracts/libraries/DefaultLibDiamond.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\n\nerror InitializationFunctionReverted(\n address _initializationContractAddress,\n bytes _calldata\n);\n\nlibrary DefaultLibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION =\n keccak256(\"trustwallet.barz.diamond.storage\");\n\n struct FacetAddressAndPosition {\n address facetAddress;\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\n }\n\n struct FacetFunctionSelectors {\n bytes4[] functionSelectors;\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\n }\n\n struct DiamondStorage {\n // maps function selector to the facet address and\n // the position of the selector in the facetFunctionSelectors.selectors array\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\n // maps facet addresses to function selectors\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\n // facet addresses\n address[] facetAddresses;\n // Used to query if a contract implements an interface.\n // Used to implement ERC-165.\n mapping(bytes4 => bool) supportedInterfaces;\n }\n\n function diamondStorage()\n internal\n pure\n returns (DiamondStorage storage ds)\n {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n event DiamondCut(\n IDiamondCut.FacetCut[] _diamondCut,\n address _init,\n bytes _calldata\n );\n\n // Internal function version of diamondCut\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n for (\n uint256 facetIndex;\n facetIndex < _diamondCut.length;\n facetIndex++\n ) {\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\n if (action == IDiamondCut.FacetCutAction.Add) {\n addFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\n replaceFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\n removeFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else {\n revert(\"LibDiamondCut: Incorrect FacetCutAction\");\n }\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Add facet can't be address(0)\"\n );\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n require(\n oldFacetAddress == address(0),\n \"LibDiamondCut: Can't add function that already exists\"\n );\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function replaceFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Replace facet can't be address(0)\"\n );\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n require(\n oldFacetAddress != _facetAddress,\n \"LibDiamondCut: Can't replace function with same facet\"\n );\n removeFunction(ds, oldFacetAddress, selector);\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function removeFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n // if function does not exist then do nothing and return\n require(\n _facetAddress == address(0),\n \"LibDiamondCut: Remove facet address must be address(0)\"\n );\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n removeFunction(ds, oldFacetAddress, selector);\n }\n }\n\n function addFacet(\n DiamondStorage storage ds,\n address _facetAddress\n ) internal {\n enforceHasContractCode(\n _facetAddress,\n \"LibDiamondCut: New facet has no code\"\n );\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds\n .facetAddresses\n .length;\n ds.facetAddresses.push(_facetAddress);\n }\n\n function addFunction(\n DiamondStorage storage ds,\n bytes4 _selector,\n uint96 _selectorPosition,\n address _facetAddress\n ) internal {\n ds\n .selectorToFacetAndPosition[_selector]\n .functionSelectorPosition = _selectorPosition;\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(\n _selector\n );\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\n }\n\n function removeFunction(\n DiamondStorage storage ds,\n address _facetAddress,\n bytes4 _selector\n ) internal {\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Can't remove function that doesn't exist\"\n );\n // an immutable function is a function defined directly in a diamond\n require(\n _facetAddress != address(this),\n \"LibDiamondCut: Can't remove immutable function\"\n );\n // replace selector with last selector, then delete last selector\n uint256 selectorPosition = ds\n .selectorToFacetAndPosition[_selector]\n .functionSelectorPosition;\n uint256 lastSelectorPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors\n .length - 1;\n // if not the same then replace _selector with lastSelector\n if (selectorPosition != lastSelectorPosition) {\n bytes4 lastSelector = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors[lastSelectorPosition];\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[\n selectorPosition\n ] = lastSelector;\n ds\n .selectorToFacetAndPosition[lastSelector]\n .functionSelectorPosition = uint96(selectorPosition);\n }\n // delete the last selector\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\n delete ds.selectorToFacetAndPosition[_selector];\n\n // if no more selectors for facet address then delete the facet address\n if (lastSelectorPosition == 0) {\n // replace facet address with last facet address and delete last facet address\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\n uint256 facetAddressPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .facetAddressPosition;\n if (facetAddressPosition != lastFacetAddressPosition) {\n address lastFacetAddress = ds.facetAddresses[\n lastFacetAddressPosition\n ];\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\n ds\n .facetFunctionSelectors[lastFacetAddress]\n .facetAddressPosition = facetAddressPosition;\n }\n ds.facetAddresses.pop();\n delete ds\n .facetFunctionSelectors[_facetAddress]\n .facetAddressPosition;\n }\n }\n\n function initializeDiamondCut(\n address _init,\n bytes memory _calldata\n ) internal {\n if (_init == address(0)) {\n return;\n }\n enforceHasContractCode(\n _init,\n \"LibDiamondCut: _init address has no code\"\n );\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length > 0) {\n // bubble up error\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(error)\n revert(add(32, error), returndata_size)\n }\n } else {\n revert InitializationFunctionReverted(_init, _calldata);\n }\n }\n }\n\n function enforceHasContractCode(\n address _contract,\n string memory _errorMessage\n ) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize > 0, _errorMessage);\n }\n}\n" + }, + "contracts/libraries/LibAppStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SafeCast} from \"@openzeppelin/contracts/utils/math/SafeCast.sol\";\nimport {IEntryPoint} from \"../aa-4337/interfaces/IEntryPoint.sol\";\nimport {IFacetRegistry} from \"../infrastructure/interfaces/IFacetRegistry.sol\";\n\n/*\n * @title App Storage\n * @dev App storage for Barz contract to prevent storage collision\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\n\nstruct Lock {\n uint64 release;\n bytes4 locker;\n}\n\nstruct InitializersStorage {\n // NOTE: initialized is a variable to make sure the initialization is only done once.\n uint8 signerInitialized;\n uint8 accountInitialized;\n uint8 restrictionsInitialized;\n}\n\nstruct AppStorage {\n mapping(uint256 => InitializersStorage) initStorage;\n uint8 signerMigration;\n bytes4 validateOwnerSignatureSelector;\n IEntryPoint entryPoint;\n IFacetRegistry facetRegistry;\n mapping(uint256 => Lock) locks;\n}\n\nlibrary LibAppStorage {\n error LibAppStorage__AccountAlreadyUninitialized();\n error LibAppStorage__AccountMustBeUninitialized();\n error LibAppStorage__SignerAlreadyUninitialized();\n error LibAppStorage__SignerMustBeUninitialized();\n\n function appStorage() internal pure returns (AppStorage storage ds) {\n assembly {\n ds.slot := 0\n }\n }\n\n function setSignerUninitialized() internal {\n AppStorage storage s = appStorage();\n if (1 != s.initStorage[0].signerInitialized) {\n revert LibAppStorage__SignerAlreadyUninitialized();\n }\n s.initStorage[0].signerInitialized = 0;\n }\n\n function getValidateOwnerSignatureSelector()\n internal\n view\n returns (bytes4 selector)\n {\n selector = appStorage().validateOwnerSignatureSelector;\n }\n\n function setValidateOwnerSignatureSelector(\n bytes4 _validateOwnerSignatureSelector\n ) internal {\n appStorage()\n .validateOwnerSignatureSelector = _validateOwnerSignatureSelector;\n }\n\n function enforceSignerInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].signerInitialized) {\n revert LibAppStorage__SignerMustBeUninitialized();\n }\n s.initStorage[0].signerInitialized = 1;\n }\n\n function enforceAccountInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].accountInitialized) {\n revert LibAppStorage__AccountMustBeUninitialized();\n }\n s.initStorage[0].accountInitialized = 1;\n }\n\n function initiateSignerMigration() internal {\n appStorage().signerMigration = 1;\n }\n\n function enforceSignerMigration() internal view {\n if (1 != appStorage().signerMigration) {\n revert LibAppStorage__AccountMustBeUninitialized();\n }\n }\n\n function finalizeSignerMigration() internal {\n appStorage().signerMigration = 0;\n }\n\n function setLock(uint256 _releaseAfter, bytes4 _locker) internal {\n appStorage().locks[0] = Lock(SafeCast.toUint64(_releaseAfter), _locker);\n }\n\n function enforceRestrictionsInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].restrictionsInitialized)\n revert LibAppStorage__SignerMustBeUninitialized();\n s.initStorage[0].restrictionsInitialized = 1;\n }\n\n function setRestrictionsUninitialized() internal {\n AppStorage storage s = appStorage();\n if (1 != s.initStorage[0].restrictionsInitialized)\n revert LibAppStorage__AccountAlreadyUninitialized();\n s.initStorage[0].restrictionsInitialized = 0;\n }\n}\n\ncontract BarzStorage {\n AppStorage internal s;\n modifier onlyWhenUnlocked() {\n require(\n uint64(block.timestamp) >= s.locks[0].release,\n \"Account Locked\"\n );\n _;\n }\n modifier onlyWhenLocked() {\n require(\n uint64(block.timestamp) < s.locks[0].release,\n \"Account Unlocked\"\n );\n _;\n }\n}\n" + }, + "contracts/libraries/LibDiamond.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\n\nerror InitializationFunctionReverted(\n address _initializationContractAddress,\n bytes _calldata\n);\n\nlibrary LibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION =\n keccak256(\"trustwallet.barz.diamond.storage\");\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\n bytes4(keccak256(\"verifyRestrictions(address,address,uint256,bytes)\"));\n struct DiamondStorage {\n // maps function selectors to the facets that execute the functions.\n // and maps the selectors to their position in the selectorSlots array.\n // func selector => address facet, selector position\n mapping(bytes4 => bytes32) facets;\n // array of slots of function selectors.\n // each slot holds 8 function selectors.\n mapping(uint256 => bytes32) selectorSlots;\n // The number of function selectors in selectorSlots\n uint16 selectorCount;\n // Used to query if a contract implements an interface.\n // Used to implement ERC-165.\n mapping(bytes4 => bool) supportedInterfaces;\n // Default Fallback Handler of the barz.\n IDiamondLoupe defaultFallbackHandler;\n }\n\n function diamondStorage()\n internal\n pure\n returns (DiamondStorage storage ds)\n {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n function enforceIsSelf() internal view {\n require(msg.sender == address(this), \"LibDiamond: Caller not self\");\n }\n\n event DiamondCut(\n IDiamondCut.FacetCut[] _diamondCut,\n address _init,\n bytes _calldata\n );\n\n bytes32 constant CLEAR_ADDRESS_MASK =\n bytes32(uint256(0xffffffffffffffffffffffff));\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\n\n // Internal function version of diamondCut\n // This code is almost the same as the external diamondCut,\n // except it is using 'Facet[] memory _diamondCut' instead of\n // 'Facet[] calldata _diamondCut'.\n // The code is duplicated to prevent copying calldata to memory which\n // causes an error for a two dimensional array.\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n DiamondStorage storage ds = diamondStorage();\n uint256 originalSelectorCount = ds.selectorCount;\n uint256 selectorCount = originalSelectorCount;\n bytes32 selectorSlot;\n // Check if last selector slot is not full\n // \"selectorCount & 7\" is a gas efficient modulo by eight \"selectorCount % 8\"\n if (selectorCount & 7 > 0) {\n // get last selectorSlot\n // \"selectorSlot >> 3\" is a gas efficient division by 8 \"selectorSlot / 8\"\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\n }\n // loop through diamond cut\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\n selectorCount,\n selectorSlot,\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].action,\n _diamondCut[facetIndex].functionSelectors\n );\n\n unchecked {\n facetIndex++;\n }\n }\n if (selectorCount != originalSelectorCount) {\n ds.selectorCount = uint16(selectorCount);\n }\n // If last selector slot is not full\n // \"selectorCount & 7\" is a gas efficient modulo by eight \"selectorCount % 8\"\n if (selectorCount & 7 > 0) {\n // \"selectorSlot >> 3\" is a gas efficient division by 8 \"selectorSlot / 8\"\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addReplaceRemoveFacetSelectors(\n uint256 _selectorCount,\n bytes32 _selectorSlot,\n address _newFacetAddress,\n IDiamondCut.FacetCutAction _action,\n bytes4[] memory _selectors\n ) internal returns (uint256, bytes32) {\n DiamondStorage storage ds = diamondStorage();\n require(\n _selectors.length > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n if (_action == IDiamondCut.FacetCutAction.Add) {\n enforceHasContractCode(\n _newFacetAddress,\n \"LibDiamondCut: Add facet has no code\"\n );\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n require(\n address(bytes20(oldFacet)) == address(0),\n \"LibDiamondCut: Can't add function that already exists\"\n );\n // add facet for selector\n ds.facets[selector] =\n bytes20(_newFacetAddress) |\n bytes32(_selectorCount);\n // \"_selectorCount & 7\" is a gas efficient modulo by eight \"_selectorCount % 8\"\n // \" << 5 is the same as multiplying by 32 ( * 32)\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\n // clear selector position in slot and add selector\n _selectorSlot =\n (_selectorSlot &\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\n (bytes32(selector) >> selectorInSlotPosition);\n // if slot is full then write it to storage\n if (selectorInSlotPosition == 224) {\n // \"_selectorSlot >> 3\" is a gas efficient division by 8 \"_selectorSlot / 8\"\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\n _selectorSlot = 0;\n }\n _selectorCount++;\n\n unchecked {\n selectorIndex++;\n }\n }\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\n enforceHasContractCode(\n _newFacetAddress,\n \"LibDiamondCut: Replace facet has no code\"\n );\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n address oldFacetAddress = address(bytes20(oldFacet));\n // only useful if immutable functions exist\n require(\n oldFacetAddress != address(this),\n \"LibDiamondCut: Can't replace immutable function\"\n );\n require(\n oldFacetAddress != _newFacetAddress,\n \"LibDiamondCut: Can't replace function with same function\"\n );\n require(\n oldFacetAddress != address(0),\n \"LibDiamondCut: Can't replace function that doesn't exist\"\n );\n // replace old facet address\n ds.facets[selector] =\n (oldFacet & CLEAR_ADDRESS_MASK) |\n bytes20(_newFacetAddress);\n\n unchecked {\n selectorIndex++;\n }\n }\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\n require(\n _newFacetAddress == address(0),\n \"LibDiamondCut: Remove facet address must be address(0)\"\n );\n // \"_selectorCount >> 3\" is a gas efficient division by 8 \"_selectorCount / 8\"\n uint256 selectorSlotCount = _selectorCount >> 3;\n // \"_selectorCount & 7\" is a gas efficient modulo by eight \"_selectorCount % 8\"\n uint256 selectorInSlotIndex = _selectorCount & 7;\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n if (_selectorSlot == 0) {\n // get last selectorSlot\n selectorSlotCount--;\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\n selectorInSlotIndex = 7;\n } else {\n selectorInSlotIndex--;\n }\n bytes4 lastSelector;\n uint256 oldSelectorsSlotCount;\n uint256 oldSelectorInSlotPosition;\n // adding a block here prevents stack too deep error\n {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n require(\n address(bytes20(oldFacet)) != address(0),\n \"LibDiamondCut: Can't remove function that doesn't exist\"\n );\n // only useful if immutable functions exist\n require(\n address(bytes20(oldFacet)) != address(this),\n \"LibDiamondCut: Can't remove immutable function\"\n );\n // replace selector with last selector in ds.facets\n // gets the last selector\n // \" << 5 is the same as multiplying by 32 ( * 32)\n lastSelector = bytes4(\n _selectorSlot << (selectorInSlotIndex << 5)\n );\n if (lastSelector != selector) {\n // update last selector slot position info\n ds.facets[lastSelector] =\n (oldFacet & CLEAR_ADDRESS_MASK) |\n bytes20(ds.facets[lastSelector]);\n }\n delete ds.facets[selector];\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\n // \"oldSelectorCount >> 3\" is a gas efficient division by 8 \"oldSelectorCount / 8\"\n oldSelectorsSlotCount = oldSelectorCount >> 3;\n // \"oldSelectorCount & 7\" is a gas efficient modulo by eight \"oldSelectorCount % 8\"\n // \" << 5 is the same as multiplying by 32 ( * 32)\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\n }\n if (oldSelectorsSlotCount != selectorSlotCount) {\n bytes32 oldSelectorSlot = ds.selectorSlots[\n oldSelectorsSlotCount\n ];\n // clears the selector we are deleting and puts the last selector in its place.\n oldSelectorSlot =\n (oldSelectorSlot &\n ~(CLEAR_SELECTOR_MASK >>\n oldSelectorInSlotPosition)) |\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\n // update storage with the modified slot\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\n } else {\n // clears the selector we are deleting and puts the last selector in its place.\n _selectorSlot =\n (_selectorSlot &\n ~(CLEAR_SELECTOR_MASK >>\n oldSelectorInSlotPosition)) |\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\n }\n if (selectorInSlotIndex == 0) {\n delete ds.selectorSlots[selectorSlotCount];\n _selectorSlot = 0;\n }\n\n unchecked {\n selectorIndex++;\n }\n }\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\n } else {\n revert(\"LibDiamondCut: Incorrect FacetCutAction\");\n }\n return (_selectorCount, _selectorSlot);\n }\n\n function initializeDiamondCut(\n address _init,\n bytes memory _calldata\n ) internal {\n if (_init == address(0)) {\n return;\n }\n enforceHasContractCode(\n _init,\n \"LibDiamondCut: _init address has no code\"\n );\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length > 0) {\n // bubble up error\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(error)\n revert(add(32, error), returndata_size)\n }\n } else {\n revert InitializationFunctionReverted(_init, _calldata);\n }\n }\n }\n\n function enforceHasContractCode(\n address _contract,\n string memory _errorMessage\n ) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize > 0, _errorMessage);\n }\n\n function restrictionsFacet() internal view returns (address facetAddress_) {\n facetAddress_ = address(\n bytes20(\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\n )\n );\n }\n}\n" + }, + "contracts/libraries/LibFacetStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Storage\n * @dev Storage contract to store each facets variables with diamond storage\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\n\nstruct Secp256k1VerificationStorage {\n address signer;\n}\n\nstruct Secp256r1VerificationStorage {\n uint256[2] q;\n}\n\nstruct GuardianStorage {\n mapping(bytes32 => uint256) pending;\n mapping(uint8 => StorageConfig) configs;\n}\n\nstruct Info {\n bool exists;\n uint128 index;\n}\n\nstruct StorageConfig {\n address[] addresses;\n mapping(address => Info) info;\n}\n\nstruct RecoveryConfig {\n bytes recoveryPublicKey;\n uint64 executeAfter;\n}\n\nstruct ApprovalConfig {\n bool isApproved;\n uint64 validUntil;\n}\n\nstruct RecoveryApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isNewOwnerApproved;\n}\n\nstruct RecoveryStorage {\n mapping(uint8 => RecoveryConfig) recoveryConfigs;\n mapping(uint8 => RecoveryApprovalConfig) recoveryApprovalConfigs;\n uint128 nonce;\n}\n\nstruct RestrictionsStorage {\n address[] restrictions;\n mapping(address => bool) exists;\n}\n\nstruct SignatureMigrationConfig {\n bytes migrationPublicKey;\n address migrationVerificationFacet;\n bytes4[] migrationSelectors;\n uint64 migrateAfter;\n}\n\nstruct SignatureMigrationApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isMigrationApproved;\n}\n\nstruct SignatureMigrationStorage {\n mapping(uint8 => SignatureMigrationConfig) migrationConfigs;\n mapping(uint8 => SignatureMigrationApprovalConfig) migrationApprovalConfigs;\n uint128 nonce;\n}\n\nstruct DiamondCutApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isDiamondCutApproved;\n}\n\nstruct DiamondCutStorage {\n mapping(uint8 => DiamondCutApprovalConfig) diamondCutApprovalConfigs;\n uint128 nonce;\n}\n\nstruct LockStorage {\n uint128 nonce;\n}\n\nlibrary LibFacetStorage {\n bytes32 constant K1_STORAGE_POSITION =\n keccak256(\n \"v0.trustwallet.diamond.storage.Secp256k1VerificationStorage\"\n );\n bytes32 constant R1_STORAGE_POSITION =\n keccak256(\n \"v0.trustwallet.diamond.storage.Secp256r1VerificationStorage\"\n );\n bytes32 constant GUARDIAN_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.GuardianStorage\");\n bytes32 constant RECOVERY_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.RecoveryStorage\");\n bytes32 constant RESTRICTION_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.RestrictionsStorage\");\n bytes32 constant MIGRATION_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.SignatureMigrationStorage\");\n bytes32 constant DIAMONDCUT_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.DiamondCutStorage\");\n bytes32 constant LOCK_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.LockStorage\");\n\n function k1Storage()\n internal\n pure\n returns (Secp256k1VerificationStorage storage ds)\n {\n bytes32 storagePosition = K1_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function r1Storage()\n internal\n pure\n returns (Secp256r1VerificationStorage storage ds)\n {\n bytes32 storagePosition = R1_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function guardianStorage()\n internal\n pure\n returns (GuardianStorage storage ds)\n {\n bytes32 storagePosition = GUARDIAN_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function recoveryStorage()\n internal\n pure\n returns (RecoveryStorage storage ds)\n {\n bytes32 storagePosition = RECOVERY_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function restrictionsStorage()\n internal\n pure\n returns (RestrictionsStorage storage ds)\n {\n bytes32 storagePosition = RESTRICTION_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function migrationStorage()\n internal\n pure\n returns (SignatureMigrationStorage storage ds)\n {\n bytes32 storagePosition = MIGRATION_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function diamondCutStorage()\n internal\n pure\n returns (DiamondCutStorage storage ds)\n {\n bytes32 storagePosition = DIAMONDCUT_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function lockStorage() internal pure returns (LockStorage storage ds) {\n bytes32 storagePosition = LOCK_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n}\n" + }, + "contracts/libraries/LibGuardian.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibFacetStorage, StorageConfig} from \"./LibFacetStorage.sol\";\n\n/**\n * @title LibGuardian\n * @dev Internal Library to provide utility feature for Guardians stored in Guardian Facet Storage\n * @author David Yongjun Kim (@Powerstream3604)\n */\nlibrary LibGuardian {\n function majorityOfGuardians()\n internal\n view\n returns (uint256 guardianNumber)\n {\n uint256 guardianLength = guardianCount();\n guardianNumber = (guardianLength == 0) ? 0 : guardianLength / 2 + 1;\n }\n\n function isGuardian(address _guardian) internal view returns (bool) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n return config.info[_guardian].exists;\n }\n\n function guardianCount() internal view returns (uint256) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n return config.addresses.length;\n }\n\n function getGuardians() internal view returns (address[] memory) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n address[] memory addresses = new address[](config.addresses.length);\n uint256 addressesLen = config.addresses.length;\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n return addresses;\n }\n}\n" + }, + "contracts/libraries/LibLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {LibDiamond} from \"./LibDiamond.sol\";\n\n/**\n * @title LibLoupe\n * @dev Internal Library to provide utility feature for reading the state of diamond facets\n * @author David Yongjun Kim (@Powerstream3604)\n */\nlibrary LibLoupe {\n /// @notice Gets all facets and their selectors.\n /// @return facets_ Facet\n function facets()\n internal\n view\n returns (IDiamondLoupe.Facet[] memory facets_)\n {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facets_ = new IDiamondLoupe.Facet[](ds.selectorCount);\n uint16[] memory numFacetSelectors = new uint16[](ds.selectorCount);\n uint256 numFacets;\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facetAddress_ = address(bytes20(ds.facets[selector]));\n bool continueLoop;\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n if (facets_[facetIndex].facetAddress == facetAddress_) {\n facets_[facetIndex].functionSelectors[\n numFacetSelectors[facetIndex]\n ] = selector;\n // probably will never have more than 256 functions from one facet contract\n require(numFacetSelectors[facetIndex] < 255);\n numFacetSelectors[facetIndex]++;\n continueLoop = true;\n break;\n }\n }\n if (continueLoop) {\n continue;\n }\n facets_[numFacets].facetAddress = facetAddress_;\n facets_[numFacets].functionSelectors = new bytes4[](\n ds.selectorCount\n );\n facets_[numFacets].functionSelectors[0] = selector;\n numFacetSelectors[numFacets] = 1;\n numFacets++;\n }\n }\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n uint256 numSelectors = numFacetSelectors[facetIndex];\n bytes4[] memory selectors = facets_[facetIndex].functionSelectors;\n // setting the number of selectors\n assembly {\n mstore(selectors, numSelectors)\n }\n }\n // setting the number of facets\n assembly {\n mstore(facets_, numFacets)\n }\n }\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n /// @return _facetFunctionSelectors The selectors associated with a facet address.\n function facetFunctionSelectors(\n address _facet\n ) internal view returns (bytes4[] memory _facetFunctionSelectors) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n uint256 numSelectors;\n _facetFunctionSelectors = new bytes4[](ds.selectorCount);\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facet = address(bytes20(ds.facets[selector]));\n if (_facet == facet) {\n _facetFunctionSelectors[numSelectors] = selector;\n numSelectors++;\n }\n }\n }\n // Set the number of selectors in the array\n assembly {\n mstore(_facetFunctionSelectors, numSelectors)\n }\n }\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses()\n internal\n view\n returns (address[] memory facetAddresses_)\n {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facetAddresses_ = new address[](ds.selectorCount);\n uint256 numFacets;\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facetAddress_ = address(bytes20(ds.facets[selector]));\n bool continueLoop;\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n if (facetAddress_ == facetAddresses_[facetIndex]) {\n continueLoop = true;\n break;\n }\n }\n if (continueLoop) {\n continue;\n }\n facetAddresses_[numFacets] = facetAddress_;\n numFacets++;\n }\n }\n // Set the number of facet addresses in the array\n assembly {\n mstore(facetAddresses_, numFacets)\n }\n }\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(\n bytes4 _functionSelector\n ) internal view returns (address facetAddress_) {\n facetAddress_ = address(\n bytes20(LibDiamond.diamondStorage().facets[_functionSelector])\n );\n }\n}\n" + }, + "contracts/libraries/LibMultiSigStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Multi-sig Storage\n * @dev Storage contract for storing Multi-sig Facet variables in diamond storage pattern\n * @author David Yongjun Kim (@Powerstream3604)\n */\n\nstruct MultiSigStorage {\n mapping(address => address) owners;\n mapping(uint256 => mapping(address => mapping(bytes32 => uint256))) approvedHashes;\n uint256 ownerCount;\n uint256 threshold;\n uint256 counter;\n}\n\nlibrary LibMultiSigStorage {\n function multisigStorage()\n internal\n pure\n returns (MultiSigStorage storage ds)\n {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.MultiSigStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n}\n" + }, + "contracts/libraries/LibRecoverSpender.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title RecoverSpender\n * @dev Library to determine the action and spender of calldata\n * @author Ruslan Serebriakov (@rsrbk)\n */\nlibrary LibRecoverSpender {\n // ERC20, ERC721 & ERC1155 transfers & approvals\n bytes4 private constant ERC20_TRANSFER =\n bytes4(keccak256(\"transfer(address,uint256)\"));\n bytes4 private constant ERC20_APPROVE =\n bytes4(keccak256(\"approve(address,uint256)\"));\n bytes4 private constant ERC20_INCREASE_ALLOWANCE =\n bytes4(keccak256(\"increaseAllowance(address,uint256)\"));\n bytes4 private constant ERC20_DECREASE_ALLOWANCE =\n bytes4(keccak256(\"decreaseAllowance(address,uint256)\"));\n bytes4 private constant ERC721_SET_APPROVAL_FOR_ALL =\n bytes4(keccak256(\"setApprovalForAll(address,bool)\"));\n bytes4 private constant ERC721_TRANSFER_FROM =\n bytes4(keccak256(\"transferFrom(address,address,uint256)\"));\n bytes4 private constant ERC721_SAFE_TRANSFER_FROM =\n bytes4(keccak256(\"safeTransferFrom(address,address,uint256)\"));\n bytes4 private constant ERC721_SAFE_TRANSFER_FROM_BYTES =\n bytes4(keccak256(\"safeTransferFrom(address,address,uint256,bytes)\"));\n bytes4 private constant ERC1155_SAFE_TRANSFER_FROM =\n bytes4(\n keccak256(\"safeTransferFrom(address,address,uint256,uint256,bytes)\")\n );\n bytes4 private constant ERC1155_SAFE_BATCH_TRANSFER_FROM =\n bytes4(\n keccak256(\n \"safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)\"\n )\n );\n\n /**\n * @notice Helper method to recover the spender from a contract call.\n * The method returns the contract unless the call is to a standard method of a ERC20/ERC721/ERC1155 token\n * in which case the spender is recovered from the data.\n * @param _to The target contract.\n * @param _data The data payload.\n */\n function _recover(\n address _to,\n bytes memory _data\n ) internal pure returns (address spender) {\n if (_data.length >= 68) {\n bytes4 methodId;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n methodId := mload(add(_data, 0x20))\n }\n if (\n methodId == ERC20_TRANSFER ||\n methodId == ERC20_APPROVE ||\n methodId == ERC20_INCREASE_ALLOWANCE ||\n methodId == ERC20_DECREASE_ALLOWANCE ||\n methodId == ERC721_SET_APPROVAL_FOR_ALL\n ) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n spender := mload(add(_data, 0x24))\n }\n return spender;\n }\n if (\n methodId == ERC721_TRANSFER_FROM ||\n methodId == ERC721_SAFE_TRANSFER_FROM ||\n methodId == ERC721_SAFE_TRANSFER_FROM_BYTES ||\n methodId == ERC1155_SAFE_TRANSFER_FROM ||\n methodId == ERC1155_SAFE_BATCH_TRANSFER_FROM\n ) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n spender := mload(add(_data, 0x44))\n }\n return spender;\n }\n }\n\n spender = _to;\n }\n}\n" + }, + "contracts/libraries/LibUtils.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\n\nlibrary LibUtils {\n // Internal utility functions\n function mergeArrays(\n bytes4[] memory _array1,\n bytes4[] memory _array2\n ) internal pure returns (bytes4[] memory) {\n uint256 length1 = _array1.length;\n uint256 length2 = _array2.length;\n bytes4[] memory mergedArray = new bytes4[](length1 + length2);\n\n for (uint256 i; i < length1; ) {\n mergedArray[i] = _array1[i];\n unchecked {\n ++i;\n }\n }\n\n for (uint256 i; i < length2; ) {\n mergedArray[length1 + i] = _array2[i];\n unchecked {\n ++i;\n }\n }\n\n return mergedArray;\n }\n\n function removeFacetElement(\n IDiamondLoupe.Facet[] memory _facets,\n uint256 _index\n ) internal pure returns (IDiamondLoupe.Facet[] memory) {\n require(_index < _facets.length, \"Invalid index\");\n require(_facets.length != 0, \"Invalid array\");\n\n // Create a new array with a length of `_facets.length - 1`\n IDiamondLoupe.Facet[] memory newArray = new IDiamondLoupe.Facet[](\n _facets.length - 1\n );\n uint256 newArrayLength = newArray.length;\n // Iterate over the original array, skipping the element at the specified `index`\n for (uint256 i; i < newArrayLength; ) {\n if (i < _index) {\n newArray[i] = _facets[i];\n } else {\n newArray[i] = _facets[i + 1];\n }\n unchecked {\n ++i;\n }\n }\n\n return newArray;\n }\n\n function removeElement(\n bytes4[] memory _array,\n uint256 _index\n ) internal pure returns (bytes4[] memory) {\n require(_index < _array.length, \"Invalid index\");\n require(_array.length != 0, \"Invalid array\");\n\n bytes4[] memory newArray = new bytes4[](_array.length - 1);\n uint256 newArrayLength = newArray.length;\n for (uint256 i; i < newArrayLength; ) {\n if (i < _index) {\n newArray[i] = _array[i];\n } else {\n newArray[i] = _array[i + 1];\n }\n unchecked {\n ++i;\n }\n }\n\n return newArray;\n }\n\n function setValue(\n bytes4[] memory _keys,\n address[] memory _values,\n bytes4 _key,\n address _value\n ) internal pure returns (bytes4[] memory, address[] memory) {\n uint256 index = findIndex(_keys, _key);\n uint256 keysLength = _keys.length;\n if (index < keysLength) {\n _values[index] = _value;\n } else {\n // Create new storage arrays\n bytes4[] memory newKeys = new bytes4[](keysLength + 1);\n address[] memory newValues = new address[](_values.length + 1);\n\n // Copy values to the new storage arrays\n for (uint256 i; i < keysLength; ) {\n newKeys[i] = _keys[i];\n newValues[i] = _values[i];\n\n unchecked {\n ++i;\n }\n }\n\n // Add the new key-value pair\n newKeys[keysLength] = _key;\n newValues[_values.length] = _value;\n\n return (newKeys, newValues);\n }\n\n // If the key already exists, return the original arrays\n return (_keys, _values);\n }\n\n function getValue(\n bytes4[] memory _keys,\n address[] memory _values,\n bytes4 _key\n ) internal pure returns (address) {\n uint256 index = findIndex(_keys, _key);\n if (index >= _keys.length) return address(0);\n\n return _values[index];\n }\n\n function findIndex(\n bytes4[] memory _keys,\n bytes4 _key\n ) internal pure returns (uint256) {\n uint256 keysLength = _keys.length;\n for (uint256 i; i < keysLength; ) {\n if (_keys[i] == _key) {\n return i;\n }\n unchecked {\n ++i;\n }\n }\n return keysLength;\n }\n}\n" + }, + "contracts/restrictions/IRestriction.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Interface for restrictions\n * @dev Restriction is a contract which decides whether to approve a certain kind of transaction, based on its internal logic.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface IRestriction {\n /**\n * @dev Based on restriction's internal logic, it should accept or reject a certain transaction.\n * @param from The address of the sender, that will be signing the transaction.\n * @param to The receiving address.\n * @param value Amount of ETH to transfer from sender to recipient.\n * @param _calldata Optional field to include arbitrary data.\n * @return bool value for whether the check is passed\n */\n function check(\n address from,\n address to,\n uint256 value,\n bytes calldata _calldata\n ) external returns (bool);\n}\n" + }, + "contracts/restrictions/WhitelistRestriction.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibRecoverSpender} from \"../libraries/LibRecoverSpender.sol\";\nimport {WhitelistStorage} from \"../infrastructure/WhitelistStorage.sol\";\nimport {IRestriction} from \"./IRestriction.sol\";\n\n/**\n * @title Whitelist Restriction\n * @dev This restriction defines a list of accepted addresses and denies any interaction with addresses outside of it.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract WhitelistRestriction is IRestriction {\n WhitelistStorage public immutable whitelistStorage;\n\n constructor(WhitelistStorage _whitelistStorage) {\n whitelistStorage = _whitelistStorage;\n }\n\n /**\n * @notice Helper method to recover the spender from a contract call.\n * The method returns the contract unless the call is to a standard method of a ERC20/ERC721/ERC1155 token\n * in which case the spender is recovered from the data.\n * @param _to The target contract.\n * @param _data The data payload.\n */\n function recoverSpender(\n address _to,\n bytes memory _data\n ) public pure returns (address spender) {\n return LibRecoverSpender._recover(_to, _data);\n }\n\n /*\n * @dev IRestriction's implementation. It will allow transaction if the sender is whitelisted, or user, or the whitelist storage.\n * @param _from The address of the sender, that will be signing the transaction.\n * @param _to The receiving address.\n * @param _calldata Optional field to include arbitrary data.\n * @return result value for whether the check is passed\n */\n function check(\n address _from,\n address _to,\n uint256 /*_value*/,\n bytes calldata _calldata\n ) external view override returns (bool result) {\n return\n whitelistStorage.isWhitelisted(\n _from,\n LibRecoverSpender._recover(_to, _calldata)\n ) ||\n _to == address(whitelistStorage) ||\n _to == msg.sender;\n }\n}\n" + }, + "contracts/test/Counter.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\ncontract TestCounter {\n int private count = 0;\n\n function incrementCounter() public {\n count += 1;\n }\n\n function decrementCounter() public {\n count -= 1;\n }\n\n function getCount() public view returns (int) {\n return count;\n }\n}\n" + }, + "contracts/test/TestERC1155.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC1155/ERC1155.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\n\ncontract TestERC1155 is ERC1155 {\n using Counters for Counters.Counter;\n\n Counters.Counter private _tokenIds;\n\n constructor() ERC1155(\"\") {}\n\n function mint(address account, uint256 amount) external {\n uint256 tokenId = _getNextTokenId();\n _mint(account, tokenId, amount, \"\");\n }\n\n function mintBatch(\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes memory data\n ) external {\n require(\n ids.length == amounts.length,\n \"TestERC1155: arrays length mismatch\"\n );\n\n _mintBatch(to, ids, amounts, data);\n }\n\n function _getNextTokenId() private returns (uint256) {\n _tokenIds.increment();\n return _tokenIds.current();\n }\n}\n" + }, + "contracts/test/TestERC777.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC777/ERC777.sol\";\n\ncontract TestERC777 is ERC777 {\n constructor(\n address[] memory _operators\n ) ERC777(\"TestERC777\", \"TERC777\", _operators) {}\n\n function mint(address account, uint256 amount) external {\n _mint(account, amount, \"\", \"\");\n }\n}\n" + }, + "contracts/test/TestInvalidSecp256k1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IVerificationFacet} from \"../facets/interfaces/IVerificationFacet.sol\";\nimport {IERC1271} from \"../interfaces/ERC/IERC1271.sol\";\nimport {AppStorage, LibAppStorage, BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {LibFacetStorage, Secp256k1VerificationStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {UserOperation} from \"../aa-4337/interfaces/UserOperation.sol\";\n\n/**\n * @title Test Secp256k1 verification facet\n * @dev Default Ethereum's elliptic curve\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract TestInvalidSecp256k1VerificationFacet is BarzStorage, IERC1271 {\n using ECDSA for bytes32;\n error Secp256k1VerificationFacet__InvalidSignerLength();\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n\n event SignerUninitialized();\n\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n }\n\n // THIS INVALID FACET DOES NOT INCLUDE initializeSigner()\n // THIS FACET IS USED TO TEST WHEN initializeSigner() DOESN'T EXIST IN FACET\n\n function uninitializeSigner() external returns (uint256 uninitSuccess) {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view returns (uint256 validationData) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n return validateSignature(userOp, userOpHash, k1Storage.signer);\n }\n\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n address signer\n ) public pure returns (uint256) {\n bytes32 hash = userOpHash.toEthSignedMessageHash();\n if (signer != hash.recover(userOp.signature)) return 1;\n return 0;\n }\n\n // This is REMOVED for testing purpose\n function validateOwnerSignatureSelector() public pure returns (bytes4) {\n // return this.validateOwnerSignature.selector;\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n function owner() public view returns (bytes memory) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n return abi.encodePacked(k1Storage.signer);\n }\n\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure returns (bool) {\n return (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (_hash.recover(_signature) ==\n LibFacetStorage.k1Storage().signer)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n}\n" + }, + "contracts/test/TestNFT.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\n\ncontract TestNFT is ERC721 {\n using Counters for Counters.Counter;\n Counters.Counter private currentTokenId;\n\n constructor() ERC721(\"TestNFT\", \"TNFT\") {}\n\n function mint(address recipient) public returns (uint256) {\n currentTokenId.increment();\n uint256 newItemId = currentTokenId.current();\n _safeMint(recipient, newItemId);\n return newItemId;\n }\n}\n" + }, + "contracts/test/TestToken.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract TestToken is ERC20 {\n constructor()\n // solhint-disable-next-line no-empty-blocks\n ERC20(\"TST\", \"TestToken\")\n {}\n\n function mint(address sender, uint256 amount) external {\n _mint(sender, amount);\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 999999 + }, + "evmVersion": "paris", + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/deployments/bsc/solcInputs/2f185433b714faaafa8fa6ac18fda049.json b/deployments/bsc/solcInputs/2f185433b714faaafa8fa6ac18fda049.json new file mode 100644 index 0000000..ad7f259 --- /dev/null +++ b/deployments/bsc/solcInputs/2f185433b714faaafa8fa6ac18fda049.json @@ -0,0 +1,180 @@ +{ + "language": "Solidity", + "sources": { + "@openzeppelin/contracts/interfaces/IERC1271.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC1271 standard signature validation method for\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\n *\n * _Available since v4.1._\n */\ninterface IERC1271 {\n /**\n * @dev Should return whether the signature provided is valid for the provided data\n * @param hash Hash of the data to be signed\n * @param signature Signature byte array associated with _data\n */\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155Receiver is IERC165 {\n /**\n * @dev Handles the receipt of a single ERC1155 token type. This function is\n * called at the end of a `safeTransferFrom` after the balance has been updated.\n *\n * NOTE: To accept the transfer, this must return\n * `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n * (i.e. 0xf23a6e61, or its own function selector).\n *\n * @param operator The address which initiated the transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param id The ID of the token being transferred\n * @param value The amount of tokens being transferred\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n ) external returns (bytes4);\n\n /**\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\n * is called at the end of a `safeBatchTransferFrom` after the balances have\n * been updated.\n *\n * NOTE: To accept the transfer(s), this must return\n * `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n * (i.e. 0xbc197c81, or its own function selector).\n *\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721Receiver {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\n *\n * Accounts can be notified of {IERC777} tokens being sent to them by having a\n * contract implement this interface (contract holders can be their own\n * implementer) and registering it on the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\n *\n * See {IERC1820Registry} and {ERC1820Implementer}.\n */\ninterface IERC777Recipient {\n /**\n * @dev Called by an {IERC777} token contract whenever tokens are being\n * moved or created into a registered account (`to`). The type of operation\n * is conveyed by `from` being the zero address or not.\n *\n * This call occurs _after_ the token contract's state is updated, so\n * {IERC777-balanceOf}, etc., can be used to query the post-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensReceived(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/ECDSA.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Strings.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV // Deprecated in v4.8\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n /// @solidity memory-safe-assembly\n assembly {\n mstore(0x00, \"\\x19Ethereum Signed Message:\\n32\")\n mstore(0x1c, hash)\n message := keccak256(0x00, 0x3c)\n }\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\n /// @solidity memory-safe-assembly\n assembly {\n let ptr := mload(0x40)\n mstore(ptr, \"\\x19\\x01\")\n mstore(add(ptr, 0x02), domainSeparator)\n mstore(add(ptr, 0x22), structHash)\n data := keccak256(ptr, 0x42)\n }\n }\n\n /**\n * @dev Returns an Ethereum Signed Data with intended validator, created from a\n * `validator` and `data` according to the version 0 of EIP-191.\n *\n * See {recover}.\n */\n function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x00\", validator, data));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/SignatureChecker.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSA.sol\";\nimport \"../../interfaces/IERC1271.sol\";\n\n/**\n * @dev Signature verification helper that can be used instead of `ECDSA.recover` to seamlessly support both ECDSA\n * signatures from externally owned accounts (EOAs) as well as ERC1271 signatures from smart contract wallets like\n * Argent and Gnosis Safe.\n *\n * _Available since v4.1._\n */\nlibrary SignatureChecker {\n /**\n * @dev Checks if a signature is valid for a given signer and data hash. If the signer is a smart contract, the\n * signature is validated against that smart contract using ERC1271, otherwise it's validated using `ECDSA.recover`.\n *\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\n */\n function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature) internal view returns (bool) {\n (address recovered, ECDSA.RecoverError error) = ECDSA.tryRecover(hash, signature);\n return\n (error == ECDSA.RecoverError.NoError && recovered == signer) ||\n isValidERC1271SignatureNow(signer, hash, signature);\n }\n\n /**\n * @dev Checks if a signature is valid for a given signer and data hash. The signature is validated\n * against the signer smart contract using ERC1271.\n *\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\n */\n function isValidERC1271SignatureNow(\n address signer,\n bytes32 hash,\n bytes memory signature\n ) internal view returns (bool) {\n (bool success, bytes memory result) = signer.staticcall(\n abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, signature)\n );\n return (success &&\n result.length >= 32 &&\n abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/math/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\n // The surrounding unchecked block does not change this fact.\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1, \"Math: mulDiv overflow\");\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n //\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n //\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n //\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1 << (log2(a) >> 1);\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = sqrt(a);\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 2, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 128;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 64;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 32;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 16;\n }\n if (value >> 8 > 0) {\n value >>= 8;\n result += 8;\n }\n if (value >> 4 > 0) {\n value >>= 4;\n result += 4;\n }\n if (value >> 2 > 0) {\n value >>= 2;\n result += 2;\n }\n if (value >> 1 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log2(value);\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 10, rounded down, of a positive value.\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 + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 256, rounded down, of a positive value.\n * Returns 0 if given 0.\n *\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n */\n function log256(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 16;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 8;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 4;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 2;\n }\n if (value >> 8 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log256(value);\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/SafeCast.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCast {\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 * _Available since v4.7._\n */\n function toUint248(uint256 value) internal pure returns (uint248) {\n require(value <= type(uint248).max, \"SafeCast: value doesn't fit in 248 bits\");\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 * _Available since v4.7._\n */\n function toUint240(uint256 value) internal pure returns (uint240) {\n require(value <= type(uint240).max, \"SafeCast: value doesn't fit in 240 bits\");\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 * _Available since v4.7._\n */\n function toUint232(uint256 value) internal pure returns (uint232) {\n require(value <= type(uint232).max, \"SafeCast: value doesn't fit in 232 bits\");\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 * _Available since v4.2._\n */\n function toUint224(uint256 value) internal pure returns (uint224) {\n require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\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 * _Available since v4.7._\n */\n function toUint216(uint256 value) internal pure returns (uint216) {\n require(value <= type(uint216).max, \"SafeCast: value doesn't fit in 216 bits\");\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 * _Available since v4.7._\n */\n function toUint208(uint256 value) internal pure returns (uint208) {\n require(value <= type(uint208).max, \"SafeCast: value doesn't fit in 208 bits\");\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 * _Available since v4.7._\n */\n function toUint200(uint256 value) internal pure returns (uint200) {\n require(value <= type(uint200).max, \"SafeCast: value doesn't fit in 200 bits\");\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 * _Available since v4.7._\n */\n function toUint192(uint256 value) internal pure returns (uint192) {\n require(value <= type(uint192).max, \"SafeCast: value doesn't fit in 192 bits\");\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 * _Available since v4.7._\n */\n function toUint184(uint256 value) internal pure returns (uint184) {\n require(value <= type(uint184).max, \"SafeCast: value doesn't fit in 184 bits\");\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 * _Available since v4.7._\n */\n function toUint176(uint256 value) internal pure returns (uint176) {\n require(value <= type(uint176).max, \"SafeCast: value doesn't fit in 176 bits\");\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 * _Available since v4.7._\n */\n function toUint168(uint256 value) internal pure returns (uint168) {\n require(value <= type(uint168).max, \"SafeCast: value doesn't fit in 168 bits\");\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 * _Available since v4.7._\n */\n function toUint160(uint256 value) internal pure returns (uint160) {\n require(value <= type(uint160).max, \"SafeCast: value doesn't fit in 160 bits\");\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 * _Available since v4.7._\n */\n function toUint152(uint256 value) internal pure returns (uint152) {\n require(value <= type(uint152).max, \"SafeCast: value doesn't fit in 152 bits\");\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 * _Available since v4.7._\n */\n function toUint144(uint256 value) internal pure returns (uint144) {\n require(value <= type(uint144).max, \"SafeCast: value doesn't fit in 144 bits\");\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 * _Available since v4.7._\n */\n function toUint136(uint256 value) internal pure returns (uint136) {\n require(value <= type(uint136).max, \"SafeCast: value doesn't fit in 136 bits\");\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 * _Available since v2.5._\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\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 * _Available since v4.7._\n */\n function toUint120(uint256 value) internal pure returns (uint120) {\n require(value <= type(uint120).max, \"SafeCast: value doesn't fit in 120 bits\");\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 * _Available since v4.7._\n */\n function toUint112(uint256 value) internal pure returns (uint112) {\n require(value <= type(uint112).max, \"SafeCast: value doesn't fit in 112 bits\");\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 * _Available since v4.7._\n */\n function toUint104(uint256 value) internal pure returns (uint104) {\n require(value <= type(uint104).max, \"SafeCast: value doesn't fit in 104 bits\");\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 * _Available since v4.2._\n */\n function toUint96(uint256 value) internal pure returns (uint96) {\n require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\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 * _Available since v4.7._\n */\n function toUint88(uint256 value) internal pure returns (uint88) {\n require(value <= type(uint88).max, \"SafeCast: value doesn't fit in 88 bits\");\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 * _Available since v4.7._\n */\n function toUint80(uint256 value) internal pure returns (uint80) {\n require(value <= type(uint80).max, \"SafeCast: value doesn't fit in 80 bits\");\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 * _Available since v4.7._\n */\n function toUint72(uint256 value) internal pure returns (uint72) {\n require(value <= type(uint72).max, \"SafeCast: value doesn't fit in 72 bits\");\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 * _Available since v2.5._\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\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 * _Available since v4.7._\n */\n function toUint56(uint256 value) internal pure returns (uint56) {\n require(value <= type(uint56).max, \"SafeCast: value doesn't fit in 56 bits\");\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 * _Available since v4.7._\n */\n function toUint48(uint256 value) internal pure returns (uint48) {\n require(value <= type(uint48).max, \"SafeCast: value doesn't fit in 48 bits\");\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 * _Available since v4.7._\n */\n function toUint40(uint256 value) internal pure returns (uint40) {\n require(value <= type(uint40).max, \"SafeCast: value doesn't fit in 40 bits\");\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 * _Available since v2.5._\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\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 * _Available since v4.7._\n */\n function toUint24(uint256 value) internal pure returns (uint24) {\n require(value <= type(uint24).max, \"SafeCast: value doesn't fit in 24 bits\");\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 * _Available since v2.5._\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\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 * _Available since v2.5._\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\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 * _Available since v3.0._\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\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 * _Available since v4.7._\n */\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\n downcasted = int248(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 248 bits\");\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 * _Available since v4.7._\n */\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\n downcasted = int240(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 240 bits\");\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 * _Available since v4.7._\n */\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\n downcasted = int232(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 232 bits\");\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 * _Available since v4.7._\n */\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\n downcasted = int224(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 224 bits\");\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 * _Available since v4.7._\n */\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\n downcasted = int216(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 216 bits\");\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 * _Available since v4.7._\n */\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\n downcasted = int208(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 208 bits\");\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 * _Available since v4.7._\n */\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\n downcasted = int200(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 200 bits\");\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 * _Available since v4.7._\n */\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\n downcasted = int192(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 192 bits\");\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 * _Available since v4.7._\n */\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\n downcasted = int184(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 184 bits\");\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 * _Available since v4.7._\n */\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\n downcasted = int176(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 176 bits\");\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 * _Available since v4.7._\n */\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\n downcasted = int168(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 168 bits\");\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 * _Available since v4.7._\n */\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\n downcasted = int160(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 160 bits\");\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 * _Available since v4.7._\n */\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\n downcasted = int152(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 152 bits\");\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 * _Available since v4.7._\n */\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\n downcasted = int144(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 144 bits\");\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 * _Available since v4.7._\n */\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\n downcasted = int136(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 136 bits\");\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 * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\n downcasted = int128(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 128 bits\");\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 * _Available since v4.7._\n */\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\n downcasted = int120(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 120 bits\");\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 * _Available since v4.7._\n */\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\n downcasted = int112(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 112 bits\");\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 * _Available since v4.7._\n */\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\n downcasted = int104(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 104 bits\");\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 * _Available since v4.7._\n */\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\n downcasted = int96(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 96 bits\");\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 * _Available since v4.7._\n */\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\n downcasted = int88(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 88 bits\");\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 * _Available since v4.7._\n */\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\n downcasted = int80(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 80 bits\");\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 * _Available since v4.7._\n */\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\n downcasted = int72(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 72 bits\");\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 * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\n downcasted = int64(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 64 bits\");\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 * _Available since v4.7._\n */\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\n downcasted = int56(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 56 bits\");\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 * _Available since v4.7._\n */\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\n downcasted = int48(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 48 bits\");\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 * _Available since v4.7._\n */\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\n downcasted = int40(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 40 bits\");\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 * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\n downcasted = int32(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 32 bits\");\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 * _Available since v4.7._\n */\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\n downcasted = int24(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 24 bits\");\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 * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\n downcasted = int16(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 16 bits\");\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 * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\n downcasted = int8(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 8 bits\");\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 * _Available since v3.0._\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 require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/SignedMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard signed math utilities missing in the Solidity language.\n */\nlibrary SignedMath {\n /**\n * @dev Returns the largest of two signed numbers.\n */\n function max(int256 a, int256 b) internal pure returns (int256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two signed numbers.\n */\n function min(int256 a, int256 b) internal pure returns (int256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two signed numbers without overflow.\n * The result is rounded towards zero.\n */\n function average(int256 a, int256 b) internal pure returns (int256) {\n // Formula from the book \"Hacker's Delight\"\n int256 x = (a & b) + ((a ^ b) >> 1);\n return x + (int256(uint256(x) >> 255) & (a ^ b));\n }\n\n /**\n * @dev Returns the absolute unsigned value of a signed value.\n */\n function abs(int256 n) internal pure returns (uint256) {\n unchecked {\n // must be unchecked in order to support `n = type(int256).min`\n return uint256(n >= 0 ? n : -n);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/Math.sol\";\nimport \"./math/SignedMath.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n unchecked {\n uint256 length = Math.log10(value) + 1;\n string memory buffer = new string(length);\n uint256 ptr;\n /// @solidity memory-safe-assembly\n assembly {\n ptr := add(buffer, add(32, length))\n }\n while (true) {\n ptr--;\n /// @solidity memory-safe-assembly\n assembly {\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n }\n value /= 10;\n if (value == 0) break;\n }\n return buffer;\n }\n }\n\n /**\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\n */\n function toString(int256 value) internal pure returns (string memory) {\n return string(abi.encodePacked(value < 0 ? \"-\" : \"\", toString(SignedMath.abs(value))));\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n unchecked {\n return toHexString(value, Math.log256(value) + 1);\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n\n /**\n * @dev Returns true if the two strings are equal.\n */\n function equal(string memory a, string memory b) internal pure returns (bool) {\n return keccak256(bytes(a)) == keccak256(bytes(b));\n }\n}\n" + }, + "contracts/aa-4337/core/BaseAccount.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-empty-blocks */\n\nimport \"../interfaces/IAccount.sol\";\nimport \"../interfaces/IEntryPoint.sol\";\nimport \"./Helpers.sol\";\n\n/**\n * Basic account implementation.\n * this contract provides the basic logic for implementing the IAccount interface - validateUserOp\n * specific account implementation should inherit it and provide the account-specific logic\n */\nabstract contract BaseAccount is IAccount {\n using UserOperationLib for UserOperation;\n\n //return value in case of signature failure, with no time-range.\n // equivalent to _packValidationData(true,0,0);\n uint256 internal constant SIG_VALIDATION_FAILED = 1;\n\n /**\n * Return the account nonce.\n * This method returns the next sequential nonce.\n * For a nonce of a specific key, use `entrypoint.getNonce(account, key)`\n */\n function getNonce() public view virtual returns (uint256) {\n return entryPoint().getNonce(address(this), 0);\n }\n\n /**\n * return the entryPoint used by this account.\n * subclass should return the current entryPoint used by this account.\n */\n function entryPoint() public view virtual returns (IEntryPoint);\n\n /**\n * Validate user's signature and nonce.\n * subclass doesn't need to override this method. Instead, it should override the specific internal validation methods.\n */\n function validateUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 missingAccountFunds\n ) external virtual override returns (uint256 validationData) {\n _requireFromEntryPoint();\n validationData = _validateSignature(userOp, userOpHash);\n _validateNonce(userOp.nonce);\n _payPrefund(missingAccountFunds);\n }\n\n /**\n * ensure the request comes from the known entrypoint.\n */\n function _requireFromEntryPoint() internal view virtual {\n require(\n msg.sender == address(entryPoint()),\n \"account: not from EntryPoint\"\n );\n }\n\n /**\n * validate the signature is valid for this message.\n * @param userOp validate the userOp.signature field\n * @param userOpHash convenient field: the hash of the request, to check the signature against\n * (also hashes the entrypoint and chain id)\n * @return validationData signature and time-range of this operation\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * If the account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function _validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) internal virtual returns (uint256 validationData);\n\n /**\n * Validate the nonce of the UserOperation.\n * This method may validate the nonce requirement of this account.\n * e.g.\n * To limit the nonce to use sequenced UserOps only (no \"out of order\" UserOps):\n * `require(nonce < type(uint64).max)`\n * For a hypothetical account that *requires* the nonce to be out-of-order:\n * `require(nonce & type(uint64).max == 0)`\n *\n * The actual nonce uniqueness is managed by the EntryPoint, and thus no other\n * action is needed by the account itself.\n *\n * @param nonce to validate\n *\n * solhint-disable-next-line no-empty-blocks\n */\n function _validateNonce(uint256 nonce) internal view virtual {}\n\n /**\n * sends to the entrypoint (msg.sender) the missing funds for this transaction.\n * subclass MAY override this method for better funds management\n * (e.g. send to the entryPoint more than the minimum required, so that in future transactions\n * it will not be required to send again)\n * @param missingAccountFunds the minimum value this method should send the entrypoint.\n * this value MAY be zero, in case there is enough deposit, or the userOp has a paymaster.\n */\n function _payPrefund(uint256 missingAccountFunds) internal virtual {\n if (missingAccountFunds != 0) {\n (bool success, ) = payable(msg.sender).call{\n value: missingAccountFunds,\n gas: type(uint256).max\n }(\"\");\n (success);\n //ignore failure (its EntryPoint's job to verify, not account.)\n }\n }\n}\n" + }, + "contracts/aa-4337/core/Helpers.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable no-inline-assembly */\n\n/**\n * returned data from validateUserOp.\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\n * @param aggregator - address(0) - the account validated the signature by itself.\n * address(1) - the account failed to validate the signature.\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\n * @param validAfter - this UserOp is valid only after this timestamp.\n * @param validaUntil - this UserOp is valid only up to this timestamp.\n */\nstruct ValidationData {\n address aggregator;\n uint48 validAfter;\n uint48 validUntil;\n}\n\n//extract sigFailed, validAfter, validUntil.\n// also convert zero validUntil to type(uint48).max\nfunction _parseValidationData(\n uint validationData\n) pure returns (ValidationData memory data) {\n address aggregator = address(uint160(validationData));\n uint48 validUntil = uint48(validationData >> 160);\n if (validUntil == 0) {\n validUntil = type(uint48).max;\n }\n uint48 validAfter = uint48(validationData >> (48 + 160));\n return ValidationData(aggregator, validAfter, validUntil);\n}\n\n// intersect account and paymaster ranges.\nfunction _intersectTimeRange(\n uint256 validationData,\n uint256 paymasterValidationData\n) pure returns (ValidationData memory) {\n ValidationData memory accountValidationData = _parseValidationData(\n validationData\n );\n ValidationData memory pmValidationData = _parseValidationData(\n paymasterValidationData\n );\n address aggregator = accountValidationData.aggregator;\n if (aggregator == address(0)) {\n aggregator = pmValidationData.aggregator;\n }\n uint48 validAfter = accountValidationData.validAfter;\n uint48 validUntil = accountValidationData.validUntil;\n uint48 pmValidAfter = pmValidationData.validAfter;\n uint48 pmValidUntil = pmValidationData.validUntil;\n\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\n return ValidationData(aggregator, validAfter, validUntil);\n}\n\n/**\n * helper to pack the return value for validateUserOp\n * @param data - the ValidationData to pack\n */\nfunction _packValidationData(\n ValidationData memory data\n) pure returns (uint256) {\n return\n uint160(data.aggregator) |\n (uint256(data.validUntil) << 160) |\n (uint256(data.validAfter) << (160 + 48));\n}\n\n/**\n * helper to pack the return value for validateUserOp, when not using an aggregator\n * @param sigFailed - true for signature failure, false for success\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\n * @param validAfter first timestamp this UserOperation is valid\n */\nfunction _packValidationData(\n bool sigFailed,\n uint48 validUntil,\n uint48 validAfter\n) pure returns (uint256) {\n return\n (sigFailed ? 1 : 0) |\n (uint256(validUntil) << 160) |\n (uint256(validAfter) << (160 + 48));\n}\n\n/**\n * keccak function over calldata.\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\n */\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\n assembly {\n let mem := mload(0x40)\n let len := data.length\n calldatacopy(mem, data.offset, len)\n ret := keccak256(mem, len)\n }\n}\n" + }, + "contracts/aa-4337/interfaces/IAccount.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\ninterface IAccount {\n /**\n * Validate user's signature and nonce\n * the entryPoint will make the call to the recipient only if this validation call returns successfully.\n * signature failure should be reported by returning SIG_VALIDATION_FAILED (1).\n * This allows making a \"simulation call\" without a valid signature\n * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure.\n *\n * @dev Must validate caller is the entryPoint.\n * Must validate the signature and nonce\n * @param userOp the operation that is about to be executed.\n * @param userOpHash hash of the user's request data. can be used as the basis for signature.\n * @param missingAccountFunds missing funds on the account's deposit in the entrypoint.\n * This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call.\n * The excess is left as a deposit in the entrypoint, for future calls.\n * can be withdrawn anytime using \"entryPoint.withdrawTo()\"\n * In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero.\n * @return validationData packaged ValidationData structure. use `_packValidationData` and `_unpackValidationData` to encode and decode\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * If an account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validateUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 missingAccountFunds\n ) external returns (uint256 validationData);\n}\n" + }, + "contracts/aa-4337/interfaces/IAggregator.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * Aggregated Signatures validator.\n */\ninterface IAggregator {\n /**\n * validate aggregated signature.\n * revert if the aggregated signature does not match the given list of operations.\n */\n function validateSignatures(\n UserOperation[] calldata userOps,\n bytes calldata signature\n ) external view;\n\n /**\n * validate signature of a single userOp\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\n * @param userOp the userOperation received from the user.\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\n * (usually empty, unless account and aggregator support some kind of \"multisig\"\n */\n function validateUserOpSignature(\n UserOperation calldata userOp\n ) external view returns (bytes memory sigForUserOp);\n\n /**\n * aggregate multiple signatures into a single value.\n * This method is called off-chain to calculate the signature to pass with handleOps()\n * bundler MAY use optimized custom code perform this aggregation\n * @param userOps array of UserOperations to collect the signatures from.\n * @return aggregatedSignature the aggregated signature\n */\n function aggregateSignatures(\n UserOperation[] calldata userOps\n ) external view returns (bytes memory aggregatedSignature);\n}\n" + }, + "contracts/aa-4337/interfaces/IEntryPoint.sol": { + "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n/* solhint-disable reason-string */\n\nimport \"./UserOperation.sol\";\nimport \"./IStakeManager.sol\";\nimport \"./IAggregator.sol\";\nimport \"./INonceManager.sol\";\n\ninterface IEntryPoint is IStakeManager, INonceManager {\n /***\n * An event emitted after each successful request\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\n * @param sender - the account that generates this request.\n * @param paymaster - if non-null, the paymaster that pays for this request.\n * @param nonce - the nonce value from the request.\n * @param success - true if the sender transaction succeeded, false if reverted.\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\n */\n event UserOperationEvent(\n bytes32 indexed userOpHash,\n address indexed sender,\n address indexed paymaster,\n uint256 nonce,\n bool success,\n uint256 actualGasCost,\n uint256 actualGasUsed\n );\n\n /**\n * account \"sender\" was deployed.\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\n * @param sender the account that is deployed\n * @param factory the factory used to deploy this account (in the initCode)\n * @param paymaster the paymaster used by this UserOp\n */\n event AccountDeployed(\n bytes32 indexed userOpHash,\n address indexed sender,\n address factory,\n address paymaster\n );\n\n /**\n * An event emitted if the UserOperation \"callData\" reverted with non-zero length\n * @param userOpHash the request unique identifier.\n * @param sender the sender of this request\n * @param nonce the nonce used in the request\n * @param revertReason - the return bytes from the (reverted) call to \"callData\".\n */\n event UserOperationRevertReason(\n bytes32 indexed userOpHash,\n address indexed sender,\n uint256 nonce,\n bytes revertReason\n );\n\n /**\n * an event emitted by handleOps(), before starting the execution loop.\n * any event emitted before this event, is part of the validation.\n */\n event BeforeExecution();\n\n /**\n * signature aggregator used by the following UserOperationEvents within this bundle.\n */\n event SignatureAggregatorChanged(address indexed aggregator);\n\n /**\n * a custom revert error of handleOps, to identify the offending op.\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\n * @param reason - revert reason\n * The string starts with a unique code \"AAmn\", where \"m\" is \"1\" for factory, \"2\" for account and \"3\" for paymaster issues,\n * so a failure can be attributed to the correct entity.\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\n */\n error FailedOp(uint256 opIndex, string reason);\n\n /**\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\n */\n error SignatureValidationFailed(address aggregator);\n\n /**\n * Successful result from simulateValidation.\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n */\n error ValidationResult(\n ReturnInfo returnInfo,\n StakeInfo senderInfo,\n StakeInfo factoryInfo,\n StakeInfo paymasterInfo\n );\n\n /**\n * Successful result from simulateValidation, if the account returns a signature aggregator\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\n * bundler MUST use it to verify the signature, or reject the UserOperation\n */\n error ValidationResultWithAggregation(\n ReturnInfo returnInfo,\n StakeInfo senderInfo,\n StakeInfo factoryInfo,\n StakeInfo paymasterInfo,\n AggregatorStakeInfo aggregatorInfo\n );\n\n /**\n * return value of getSenderAddress\n */\n error SenderAddressResult(address sender);\n\n /**\n * return value of simulateHandleOp\n */\n error ExecutionResult(\n uint256 preOpGas,\n uint256 paid,\n uint48 validAfter,\n uint48 validUntil,\n bool targetSuccess,\n bytes targetResult\n );\n\n //UserOps handled, per aggregator\n struct UserOpsPerAggregator {\n UserOperation[] userOps;\n // aggregator address\n IAggregator aggregator;\n // aggregated signature\n bytes signature;\n }\n\n /**\n * Execute a batch of UserOperation.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(\n UserOperation[] calldata ops,\n address payable beneficiary\n ) external;\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) external;\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(\n UserOperation calldata userOp\n ) external view returns (bytes32);\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external;\n\n /**\n * gas and return values during simulation\n * @param preOpGas the gas used for validation (including preValidationGas)\n * @param prefund the required prefund for this operation\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\n */\n struct ReturnInfo {\n uint256 preOpGas;\n uint256 prefund;\n bool sigFailed;\n uint48 validAfter;\n uint48 validUntil;\n bytes paymasterContext;\n }\n\n /**\n * returned aggregated signature info.\n * the aggregator returned by the account, and its current stake.\n */\n struct AggregatorStakeInfo {\n address aggregator;\n StakeInfo stakeInfo;\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes memory initCode) external;\n\n /**\n * simulate full execution of a UserOperation (including both validation and target execution)\n * this method will always revert with \"ExecutionResult\".\n * it performs full validation of the UserOperation, but ignores signature error.\n * an optional target address is called after the userop succeeds, and its value is returned\n * (before the entire call is reverted)\n * Note that in order to collect the the success/failure of the target call, it must be executed\n * with trace enabled to track the emitted events.\n * @param op the UserOperation to simulate\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\n * are set to the return from that call.\n * @param targetCallData callData to pass to target address\n */\n function simulateHandleOp(\n UserOperation calldata op,\n address target,\n bytes calldata targetCallData\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/INonceManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\ninterface INonceManager {\n /**\n * Return the next nonce for this sender.\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\n * But UserOp with different keys can come with arbitrary order.\n *\n * @param sender the account address\n * @param key the high 192 bit of the nonce\n * @return nonce a full nonce to pass for next UserOp with this sender.\n */\n function getNonce(\n address sender,\n uint192 key\n ) external view returns (uint256 nonce);\n\n /**\n * Manually increment the nonce of the sender.\n * This method is exposed just for completeness..\n * Account does NOT need to call it, neither during validation, nor elsewhere,\n * as the EntryPoint will update the nonce regardless.\n * Possible use-case is call it with various keys to \"initialize\" their nonces to one, so that future\n * UserOperations will not pay extra for the first transaction with a given key.\n */\n function incrementNonce(uint192 key) external;\n}\n" + }, + "contracts/aa-4337/interfaces/IStakeManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.12;\n\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by the staked entity.\n */\ninterface IStakeManager {\n event Deposited(address indexed account, uint256 totalDeposit);\n\n event Withdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /// Emitted when stake or unstake delay are modified\n event StakeLocked(\n address indexed account,\n uint256 totalStaked,\n uint256 unstakeDelaySec\n );\n\n /// Emitted once a stake is scheduled for withdrawal\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\n\n event StakeWithdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /**\n * @param deposit the entity's deposit\n * @param staked true if this entity is staked.\n * @param stake actual amount of ether staked for this entity.\n * @param unstakeDelaySec minimum delay to withdraw the stake.\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\n * and the rest fit into a 2nd cell.\n * 112 bit allows for 10^15 eth\n * 48 bit for full timestamp\n * 32 bit allows 150 years for unstake delay\n */\n struct DepositInfo {\n uint112 deposit;\n bool staked;\n uint112 stake;\n uint32 unstakeDelaySec;\n uint48 withdrawTime;\n }\n\n //API struct used by getStakeInfo and simulateValidation\n struct StakeInfo {\n uint256 stake;\n uint256 unstakeDelaySec;\n }\n\n /// @return info - full deposit information of given account\n function getDepositInfo(\n address account\n ) external view returns (DepositInfo memory info);\n\n /// @return the deposit (for gas payment) of the account\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) external payable;\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 _unstakeDelaySec) external payable;\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external;\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external;\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(\n address payable withdrawAddress,\n uint256 withdrawAmount\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/UserOperation.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable no-inline-assembly */\n\nimport {calldataKeccak} from \"../core/Helpers.sol\";\n\n/**\n * User Operation struct\n * @param sender the sender account of this request.\n * @param nonce unique value the sender uses to verify it is not a replay.\n * @param initCode if set, the account contract will be created by this constructor/\n * @param callData the method call to execute on this account.\n * @param callGasLimit the gas limit passed to the callData method call.\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\n * @param maxFeePerGas same as EIP-1559 gas parameter.\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\n */\nstruct UserOperation {\n address sender;\n uint256 nonce;\n bytes initCode;\n bytes callData;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n bytes paymasterAndData;\n bytes signature;\n}\n\n/**\n * Utility functions helpful when working with UserOperation structs.\n */\nlibrary UserOperationLib {\n function getSender(\n UserOperation calldata userOp\n ) internal pure returns (address) {\n address data;\n //read sender from userOp, which is first userOp member (saves 800 gas...)\n assembly {\n data := calldataload(userOp)\n }\n return address(uint160(data));\n }\n\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\n // pay above what he signed for.\n function gasPrice(\n UserOperation calldata userOp\n ) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function pack(\n UserOperation calldata userOp\n ) internal pure returns (bytes memory ret) {\n address sender = getSender(userOp);\n uint256 nonce = userOp.nonce;\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\n bytes32 hashCallData = calldataKeccak(userOp.callData);\n uint256 callGasLimit = userOp.callGasLimit;\n uint256 verificationGasLimit = userOp.verificationGasLimit;\n uint256 preVerificationGas = userOp.preVerificationGas;\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\n\n return\n abi.encode(\n sender,\n nonce,\n hashInitCode,\n hashCallData,\n callGasLimit,\n verificationGasLimit,\n preVerificationGas,\n maxFeePerGas,\n maxPriorityFeePerGas,\n hashPaymasterAndData\n );\n }\n\n function hash(\n UserOperation calldata userOp\n ) internal pure returns (bytes32) {\n return keccak256(pack(userOp));\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n}\n" + }, + "contracts/facets/AccountFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {UserOperation} from \"../aa-4337/interfaces/UserOperation.sol\";\nimport {IEntryPoint} from \"../aa-4337/interfaces/IEntryPoint.sol\";\nimport {BaseAccount} from \"../aa-4337/core/BaseAccount.sol\";\nimport {LibAppStorage, BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {IFacetRegistry} from \"../infrastructure/interfaces/IFacetRegistry.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {IERC1271} from \"../interfaces/ERC/IERC1271.sol\";\nimport {IAccountFacet} from \"./interfaces/IAccountFacet.sol\";\n\n/**\n * @title Account Facet\n * @dev Account module contract that provides the account features and initialization of signer\n * compatible with EIP-1271 & EIP-4337\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract AccountFacet is BarzStorage, BaseAccount, IAccountFacet {\n using ECDSA for bytes32;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceAccountInitialize();\n }\n\n /**\n * @notice Returns the address of EntryPoint contract registered to Barz account\n */\n function entryPoint() public view override returns (IEntryPoint) {\n return s.entryPoint;\n }\n\n /**\n * @notice Initializes the initial storage of the Barz contract.\n * @dev This method can only be called during the initialization or signature migration.\n * If the proxy contract was created without initialization, anyone can call initialize.\n * Barz calls initialize in constructor in an atomic transaction during deployment\n * @param _verificationFacet Facet contract handling the verificationi\n * @param _anEntryPoint Entrypoint contract defined in EIP-4337 handling the flow of UserOp\n * @param _facetRegistry Registry of Facets that hold all facet information\n * @param _defaultFallBackHandler Middleware contract for default facets\n * @param _ownerPublicKey Bytes of owner public key\n */\n function initialize(\n address _verificationFacet,\n address _anEntryPoint,\n address _facetRegistry,\n address _defaultFallBackHandler,\n bytes calldata _ownerPublicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceAccountInitialize();\n s.entryPoint = IEntryPoint(_anEntryPoint);\n s.facetRegistry = IFacetRegistry(_facetRegistry);\n LibDiamond.diamondStorage().defaultFallbackHandler = IDiamondLoupe(\n _defaultFallBackHandler\n );\n\n _cutDiamondAccountFacet(_verificationFacet);\n\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n _ownerPublicKey\n );\n // Every Verification Facet should comply with initializeSigner(bytes)\n // to be compatible with the Barz contract(for initialization)\n (bool success, bytes memory result) = _verificationFacet.delegatecall(\n initCall\n );\n if (!success || uint256(bytes32(result)) != 1) {\n revert AccountFacet__InitializationFailure();\n }\n\n initSuccess = 1;\n emit AccountInitialized(s.entryPoint, _ownerPublicKey);\n }\n\n function _cutDiamondAccountFacet(address _verificationFacet) internal {\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](1);\n\n bytes4 ownerVerificationFuncSelector = IVerificationFacet(\n _verificationFacet\n ).validateOwnerSignatureSelector();\n\n bytes4[] memory verificationFunctionSelectors = new bytes4[](3);\n verificationFunctionSelectors[0] = IERC1271.isValidSignature.selector;\n verificationFunctionSelectors[1] = ownerVerificationFuncSelector;\n verificationFunctionSelectors[2] = IVerificationFacet.owner.selector;\n cut[0] = IDiamondCut.FacetCut({\n facetAddress: _verificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: verificationFunctionSelectors\n });\n\n LibDiamond.diamondCut(cut, address(0), \"\");\n }\n\n /**\n * @notice Calls the destination with inputted calldata and value from EntryPoint\n * @dev This method executes the calldata coming from the EntryPoint.\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\n * @param _dest Address of destination where the call will be forwarded to\n * @param _value Amount of native coin the owner is willing to send(e.g. ETH, BNB)\n * @param _func Bytes of calldata to execute in the destination address\n */\n function execute(\n address _dest,\n uint256 _value,\n bytes calldata _func\n ) external override onlyWhenUnlocked {\n _requireFromEntryPoint();\n _call(_dest, _value, _func);\n }\n\n /**\n * @notice Batch calls the destination with inputted calldata and value from EntryPoint\n * @dev This method batch executes the calldata coming from the EntryPoint.\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\n * @param _dest Array of addresses of destination where the call will be forwarded to\n * @param _value Array of amount of native coin the owner is willing to send(e.g. ETH, BNB)\n * @param _func Array of bytes of calldata to execute in the destination address\n */\n function executeBatch(\n address[] calldata _dest,\n uint256[] calldata _value,\n bytes[] calldata _func\n ) external override onlyWhenUnlocked {\n _requireFromEntryPoint();\n require(\n _dest.length == _func.length && _dest.length == _value.length,\n \"wrong array lengths\"\n );\n for (uint256 i; i < _dest.length; ) {\n _call(_dest[i], _value[i], _func[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Validates the signature field of UserOperation\n * @dev This method validates if the signature of UserOp is indeed valid by delegating the call to Verification Facet\n * Barz makes a call to the pre-registered Verification Facet address in App Storage\n * @param _userOp UserOperation from owner to be validated\n * @param _userOpHash Hash of UserOperation given from the EntryPoint contract\n */\n function _validateSignature(\n UserOperation calldata _userOp,\n bytes32 _userOpHash\n ) internal override returns (uint256 validationData) {\n // Get Facet with Function Selector\n address facet = LibLoupe.facetAddress(s.validateOwnerSignatureSelector);\n if (facet == address(0))\n revert AccountFacet__NonExistentVerificationFacet();\n\n // Make function call to VerificationFacet\n bytes memory validateCall = abi.encodeWithSelector(\n s.validateOwnerSignatureSelector,\n _userOp,\n _userOpHash\n );\n (bool success, bytes memory result) = facet.delegatecall(validateCall);\n if (!success) revert AccountFacet__CallNotSuccessful();\n validationData = uint256(bytes32(result));\n if (validationData == 0) emit VerificationSuccess(_userOpHash);\n else emit VerificationFailure(_userOpHash);\n }\n\n /**\n * @notice Calls the target with the inputted value and calldata\n * @dev This method is the actual function in Barz that makes a call with an arbitrary owner-given data\n * @param _target Address of the destination contract which the call is getting forwarded to\n * @param _value Amount of Native coin the owner is wanting to make in this call\n * @param _data Calldata the owner is forwarding together in the call e.g. Swap/Token Transfer\n */\n function _call(\n address _target,\n uint256 _value,\n bytes memory _data\n ) internal {\n address facet = LibDiamond.restrictionsFacet();\n // NOTE: No restrictions facet, so restriction validation passes\n if (facet != address(0)) {\n if (_checkRestrictions(facet, _target, _value, _data) == 1)\n revert AccountFacet__RestrictionsFailure();\n }\n\n (bool success, bytes memory result) = _target.call{value: _value}(\n _data\n );\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n }\n\n /**\n * @notice Checks restrictions if the restrictions facet exists\n * @dev This method checks if the restrictions facet exists and makes a verification call to an array of restrictions facet\n * @param _facet Address that holds the restrictions logic\n * @param _target Address the call is getting forwarded to\n * @param _value Amount of native coin the call is sending together with the call\n * @param _data Calldata to trigger execution in target address\n */\n function _checkRestrictions(\n address _facet,\n address _target,\n uint256 _value,\n bytes memory _data\n ) internal returns (uint256 result) {\n bytes memory call = abi.encodeWithSignature(\n \"verifyRestrictions(address,address,uint256,bytes)\",\n address(this),\n _target,\n _value,\n _data\n );\n (bool success, bytes memory response) = _facet.delegatecall(call);\n if (!success) revert AccountFacet__RestrictionsFailure();\n result = uint256(bytes32(response));\n }\n}\n" + }, + "contracts/facets/AccountRecoveryFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibFacetStorage, RecoveryStorage, RecoveryConfig, RecoveryApprovalConfig, ApprovalConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {IAccountRecoveryFacet} from \"./interfaces/IAccountRecoveryFacet.sol\";\n\n/**\n * @title Account Recovery Facet\n * @dev Contract that enables recovery of accounts when owner key is unavailable\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract AccountRecoveryFacet is IAccountRecoveryFacet, Modifiers {\n bytes constant UNINIT_CALL =\n abi.encodeWithSignature(\"uninitializeSigner()\");\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Approve recovery of account as guardian\n * @dev This method can only be called by guardian and guardian inputs the public key of the new owner\n * When the threshold(majority of guardians) passes, it automatically executes account recovery\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function approveAccountRecovery(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + _getApprovalValidationPeriod()\n );\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit RecoveryApproved(\n _recoveryPublicKey,\n msg.sender,\n approvalValidUntil\n );\n if (\n getRecoveryApprovalCountWithTimeValidity(recoveryPublicKeyHash) >=\n LibGuardian.majorityOfGuardians()\n ) _executeRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Revoke recovery of account as guardian\n * @dev This method can only be called by guardian and guardian inputs the public key of the new owner\n When the threshold(majority of guardians) passes, it automatically revokes account recovery when recovery is pending\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function revokeAccountRecoveryApproval(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n if (\n !rs\n .isNewOwnerApproved[recoveryPublicKeyHash][msg.sender].isApproved ||\n !(block.timestamp <\n rs\n .isNewOwnerApproved[recoveryPublicKeyHash][msg.sender]\n .validUntil)\n ) revert AccountRecoveryFacet__NonExistentApproval();\n\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(false, 0);\n emit RecoveryApprovalRevoked(_recoveryPublicKey, msg.sender);\n }\n\n /**\n * @notice Executes recovery with signatures or on-chain pre-approvals\n * @dev This method validates the signatures of guardians or checks the on-chain pre-approved calls to check if the threshold passes\n * When the threshold passes, account recovery is executed and revert otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _guardians Array of guardians address that are approving the recovery of Account\n * @param _signatures Array of signature bytes that signed the approval hash\n */\n function executeRecovery(\n bytes calldata _recoveryPublicKey,\n address[] calldata _guardians,\n bytes[] calldata _signatures\n ) external override {\n if (_isRecoveryPending())\n revert AccountRecoveryFacet__RecoveryAlreadyOngoing();\n if (_guardians.length != _signatures.length)\n revert AccountRecoveryFacet__InvalidArrayLength();\n validateNewOwner(_recoveryPublicKey);\n\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n\n _checkApprover(_guardians);\n _checkDuplicateOnChainApprover(recoveryPublicKeyHash, _guardians);\n\n if (\n _guardians.length +\n getRecoveryApprovalCountWithTimeValidity(\n recoveryPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians()\n ) revert AccountRecoveryFacet__InsufficientGuardians();\n for (uint256 i; i < _guardians.length; ) {\n if (!LibGuardian.isGuardian(_guardians[i]))\n revert AccountRecoveryFacet__InvalidGuardian();\n if (\n !SignatureChecker.isValidSignatureNow(\n _guardians[i],\n recoveryPublicKeyHash,\n _signatures[i]\n )\n ) revert AccountRecoveryFacet__InvalidGuardianSignature();\n unchecked {\n ++i;\n }\n }\n _executeRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Executes recovery of the account. Note that execution and finalization is a different process\n * @dev Executes the recovery and adds recovery data to recovery configuration. Locks the account\n * @param _recoveryPublicKey Public Key of the account for recovery\n */\n function _executeRecovery(bytes memory _recoveryPublicKey) internal {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n ++rs.nonce;\n uint64 executeAfter = uint64(block.timestamp + _getRecoveryPeriod());\n rs.recoveryConfigs[INNER_STRUCT] = RecoveryConfig(\n _recoveryPublicKey,\n executeAfter // NOTE: Remove guardian Count\n );\n LibAppStorage.setLock(\n block.timestamp + _getLockPeriod(),\n AccountRecoveryFacet.executeRecovery.selector\n );\n emit RecoveryExecuted(_recoveryPublicKey, executeAfter);\n }\n\n /**\n * @notice Finalize recovery after recovery pending period. Recovery pending period can be set by user beforehand in SecurityManager\n * @dev This method finalizes recovery and fully changes the ownership of the account to the newly inputted recovery public key\n */\n function finalizeRecovery() external override {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n if (\n uint64(block.timestamp) <=\n rs.recoveryConfigs[INNER_STRUCT].executeAfter\n ) revert AccountRecoveryFacet__RecoveryPeriodNotOver();\n bytes memory recoveryOwner = rs\n .recoveryConfigs[INNER_STRUCT]\n .recoveryPublicKey;\n\n delete rs.recoveryConfigs[INNER_STRUCT];\n\n LibAppStorage.setLock(0, bytes4(0));\n\n LibAppStorage.initiateSignerMigration();\n address verificationFacet = address(\n bytes20(\n LibDiamond.diamondStorage().facets[\n s.validateOwnerSignatureSelector\n ]\n )\n );\n (bool success, bytes memory result) = verificationFacet.delegatecall(\n UNINIT_CALL\n );\n if (!success) revert AccountRecoveryFacet__CallNotSuccesful();\n uint256 validationData = uint256(bytes32(result));\n if (validationData != 1)\n revert AccountRecoveryFacet__SignerUninitializationFailure();\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n recoveryOwner\n );\n (success, result) = verificationFacet.delegatecall(initCall);\n if (!success) revert AccountRecoveryFacet__CallNotSuccesful();\n validationData = uint256(bytes32(result));\n if (validationData != 1)\n revert AccountRecoveryFacet__SignerInitializationFailure();\n LibAppStorage.finalizeSignerMigration();\n emit RecoveryFinalized(recoveryOwner);\n }\n\n /**\n * @notice Approves the cancellation of recovery\n * @dev This method approves the cancellation of recovery when recovery is still pending - waiting for finalization\n * @param _recoveryPublicKey Bytes of public key which is pending for recovery\n */\n function approveCancelRecovery(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"CancelRecovery\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + _getApprovalValidationPeriod()\n );\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit RecoveryCancellationApproved(_recoveryPublicKey, msg.sender);\n if (\n getRecoveryApprovalCountWithTimeValidity(recoveryPublicKeyHash) >=\n LibGuardian.majorityOfGuardians()\n ) {\n _cancelRecovery(_recoveryPublicKey);\n }\n }\n\n /**\n * @notice Hardstops an ongoing recovery\n * @dev This method provides a safety mechanism to protect owners of malicious guardians.\n * Owners can hardstop recovery when an malicious guardians starts the recovery process.\n * @param _signature Signature of the owner that signs the hash to hardstop recovery\n */\n function hardstopRecovery(bytes calldata _signature) external override {\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n \"0\",\n \"HardstopRecovery\"\n );\n if (\n !SignatureChecker.isValidSignatureNow(\n address(this),\n recoveryPublicKeyHash,\n _signature\n )\n ) revert AccountRecoveryFacet__InvalidOwnerSignature();\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n ++rs.nonce;\n delete rs.recoveryConfigs[INNER_STRUCT];\n LibAppStorage.setLock(0, bytes4(0));\n emit RecoveryHardstopped();\n }\n\n /**\n * @notice Cancels recovery with signatures or on-chain pre-approvals\n * @dev This method validates the signatures of guardians or checks the on-chain pre-approved calls to check if the threshold passes\n * When the threshold passes, account recovery is canceled and revert otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _guardians Array of guardians address that are approving the recovery of Account\n * @param _signatures Array of signature bytes that signed the cancellation approval hash\n */\n function cancelRecovery(\n bytes calldata _recoveryPublicKey,\n address[] calldata _guardians,\n bytes[] calldata _signatures\n ) external override {\n if (_guardians.length != _signatures.length)\n revert AccountRecoveryFacet__InvalidArrayLength();\n validateNewOwner(_recoveryPublicKey);\n\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"CancelRecovery\"\n );\n\n _checkApprover(_guardians);\n _checkDuplicateOnChainApprover(recoveryPublicKeyHash, _guardians);\n\n if (\n _guardians.length +\n getRecoveryApprovalCountWithTimeValidity(\n recoveryPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians()\n ) revert AccountRecoveryFacet__InsufficientGuardians();\n for (uint256 i; i < _guardians.length; ) {\n if (!LibGuardian.isGuardian(_guardians[i]))\n revert AccountRecoveryFacet__CallerNotGuardian();\n if (\n !SignatureChecker.isValidSignatureNow(\n _guardians[i],\n recoveryPublicKeyHash,\n _signatures[i]\n )\n ) revert AccountRecoveryFacet__InvalidGuardianSignature();\n unchecked {\n ++i;\n }\n }\n _cancelRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Cancel recovery when the recovery is pending. Unlock the account as well\n * @dev This method checks if the recovery is pending and reverts if not pending.\n * It increases the recovery nonce and deletes the recovery information and gets a small portion of gas in return\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function _cancelRecovery(bytes memory _recoveryPublicKey) internal {\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n LibAppStorage.setLock(0, bytes4(0));\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n ++rs.nonce;\n delete rs.recoveryConfigs[INNER_STRUCT];\n emit RecoveryCanceled(_recoveryPublicKey);\n }\n\n /**\n * @notice Validates the format of public key to be used for recovery\n * @dev This method checks if the public key format is correct and reverts otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function validateNewOwner(bytes memory _recoveryPublicKey) public view {\n if (\n !IVerificationFacet(\n LibLoupe.facetAddress(s.validateOwnerSignatureSelector)\n ).isValidKeyType(_recoveryPublicKey)\n ) revert AccountRecoveryFacet__InvalidRecoveryPublicKey();\n }\n\n /**\n * @notice Checks if recovery is currently pending\n * @return isPending Boolean indicating if recovery is pending\n */\n function _isRecoveryPending() internal view returns (bool isPending) {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n isPending = (rs.recoveryConfigs[INNER_STRUCT].executeAfter > 0);\n }\n\n /**\n * @notice Calculate the recovery hash dependent on chain, wallet address, nonce with EIP-191 prefix for safety\n * @dev Returns the keccak256 hash of EIP-191 msg hash packed with public key, salt, nonce, wallet address, etc\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _saltString Salt string to uniquely identify each recovery hash and for security\n * @return recoveryKeyHash Bytes32 string of the recovery hash\n */\n function getApprovalRecoveryKeyHash(\n bytes memory _recoveryPublicKey,\n string memory _saltString\n ) public view override returns (bytes32 recoveryKeyHash) {\n recoveryKeyHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n _recoveryPublicKey,\n _saltString,\n address(this),\n block.chainid,\n LibFacetStorage.recoveryStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Check the onchain approval of guardians and returns the number of guardians that approved\n * @dev Loop through the guardian addresses and returns the number of guardians that approved this recovery hash\n * @param _recoveryPublicKeyHash Bytes hash of newly recovered public key and recovery value of the account\n * @return approvalCount Number of guardians that approved\n */\n function getRecoveryApprovalCountWithTimeValidity(\n bytes32 _recoveryPublicKeyHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n for (uint256 i; i < guardianLength; ) {\n if (isRecoveryApproved(_recoveryPublicKeyHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Checks if the recovery is approved by the given approver\n * @param _recoveryPublicKeyHash Hash of the public key and configuration for recovery\n * @param _approver Address of approver\n * @return isApproved Bool value if recovery hash is approved\n */\n function isRecoveryApproved(\n bytes32 _recoveryPublicKeyHash,\n address _approver\n ) public view override returns (bool isApproved) {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n if (\n rs\n .isNewOwnerApproved[_recoveryPublicKeyHash][_approver].isApproved &&\n block.timestamp <\n rs.isNewOwnerApproved[_recoveryPublicKeyHash][_approver].validUntil\n ) {\n isApproved = true;\n }\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _recoveryPublicKeyHash Hash of recovery information\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _recoveryPublicKeyHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isRecoveryApproved(_recoveryPublicKeyHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert AccountRecoveryFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the lock period of this wallet address from security manager\n * @return lockPeriod value of lock period\n */\n function _getLockPeriod() internal view returns (uint256 lockPeriod) {\n lockPeriod = securityManager.lockPeriodOf(address(this));\n if (lockPeriod == 0) revert AccountRecoveryFacet__InvalidLockPeriod();\n }\n\n /**\n * @notice Returns the lock period of this wallet address from security manager\n * @return recoveryPeriod value of recovery period\n */\n function _getRecoveryPeriod()\n internal\n view\n returns (uint256 recoveryPeriod)\n {\n recoveryPeriod = securityManager.recoveryPeriodOf(address(this));\n if (recoveryPeriod == 0)\n revert AccountRecoveryFacet__InvalidRecoveryPeriod();\n }\n\n /**\n * @notice Returns the approval validation period of this wallet address from security manager\n * @return approvalValidationPeriod value of approval validation period\n */\n function _getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod == 0)\n revert AccountRecoveryFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the recovery nonce of this wallet address from security manager\n * @return nonce value of recovery nonce\n */\n function getRecoveryNonce() public view override returns (uint128 nonce) {\n nonce = LibFacetStorage.recoveryStorage().nonce;\n }\n\n /**\n * @notice Returns the recovery information of the pending recovery\n * @return recoveryConfig value struct of pending recovery\n */\n function getPendingRecovery()\n public\n view\n override\n returns (RecoveryConfig memory recoveryConfig)\n {\n recoveryConfig = LibFacetStorage.recoveryStorage().recoveryConfigs[\n INNER_STRUCT\n ];\n }\n}\n" + }, + "contracts/facets/base/DiamondLoupeFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {IERC165} from \"../../interfaces/ERC/IERC165.sol\";\nimport {IERC1271} from \"../../interfaces/ERC/IERC1271.sol\";\nimport {IERC677Receiver} from \"../../interfaces/ERC/IERC677Receiver.sol\";\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC1155Receiver} from \"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\";\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../../libraries/LibLoupe.sol\";\nimport {LibUtils} from \"../../libraries/LibUtils.sol\";\nimport {IDiamondCut} from \"../../facets/base/interfaces/IDiamondCut.sol\";\nimport {IStorageLoupe} from \"./interfaces/IStorageLoupe.sol\";\nimport {IDiamondLoupe} from \"./interfaces/IDiamondLoupe.sol\";\n\n/**\n * @title DiamondLoupe Facet\n * @dev DiamondLoupe contract compatible with EIP-2535\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DiamondLoupeFacet is IDiamondLoupe, IStorageLoupe, IERC165 {\n // Diamond Loupe Functions\n ////////////////////////////////////////////////////////////////////\n /// These functions are expected to be called frequently by tools off-chain.\n\n /**\n * @notice Gets all facets and their selectors.\n * @dev Barz uses a special architecture called default fallback handler. Default Fallback handler is used as a middleware\n * that holds the mapping of facet function selector and facet address that Barz uses. This helps Barz to reduce\n * significant amount of gas during the initialization process.\n * Hence, this method aggregates both the facet information from DefaulFallbackHandler and in diamond storage and shows the data to users.\n * @return facets_ Facet\n */\n function facets() public view override returns (Facet[] memory facets_) {\n Facet[] memory defaultFacet = LibDiamond\n .diamondStorage()\n .defaultFallbackHandler\n .facets();\n Facet[] memory _facets = LibLoupe.facets();\n uint256 numFacets = _facets.length;\n bytes4[] memory keys;\n address[] memory values;\n for (uint256 i; i < numFacets; ) {\n uint256 selectorsLength = _facets[i].functionSelectors.length;\n for (uint256 j; j < selectorsLength; ) {\n (keys, values) = LibUtils.setValue(\n keys,\n values,\n _facets[i].functionSelectors[j],\n _facets[i].facetAddress\n );\n unchecked {\n ++j;\n }\n }\n unchecked {\n ++i;\n }\n }\n {\n bool iIncrement;\n for (uint256 i; i < defaultFacet.length; ) {\n bool jIncrement;\n for (\n uint256 j;\n j < defaultFacet[i].functionSelectors.length;\n\n ) {\n if (\n LibUtils.getValue(\n keys,\n values,\n defaultFacet[i].functionSelectors[j]\n ) != address(0)\n ) {\n if (defaultFacet[i].functionSelectors.length == 1) {\n defaultFacet = LibUtils.removeFacetElement(\n defaultFacet,\n i\n );\n iIncrement = true;\n break;\n }\n defaultFacet[i].functionSelectors = LibUtils\n .removeElement(\n defaultFacet[i].functionSelectors,\n j\n );\n jIncrement = true;\n }\n if (!jIncrement) {\n unchecked {\n ++j;\n }\n } else {\n jIncrement = false;\n }\n }\n if (!iIncrement) {\n unchecked {\n ++i;\n }\n } else {\n iIncrement = false;\n }\n }\n }\n {\n uint256 facetLength = numFacets + defaultFacet.length;\n facets_ = new Facet[](facetLength);\n uint256 defaultFacetIndex;\n for (uint256 i; i < facetLength; ) {\n if (i < numFacets) {\n facets_[i] = _facets[i];\n bool jIncrementor;\n for (uint256 j; j < defaultFacet.length; ) {\n if (\n facets_[i].facetAddress ==\n defaultFacet[j].facetAddress\n ) {\n facets_[i].functionSelectors = LibUtils.mergeArrays(\n _facets[i].functionSelectors,\n defaultFacet[j].functionSelectors\n );\n defaultFacet = LibUtils.removeFacetElement(\n defaultFacet,\n j\n );\n jIncrementor = true;\n {\n facets_ = LibUtils.removeFacetElement(\n facets_,\n facets_.length - 1\n );\n }\n --facetLength;\n }\n if (!jIncrementor) {\n unchecked {\n ++j;\n }\n } else {\n jIncrementor = false;\n }\n }\n } else {\n facets_[i] = defaultFacet[defaultFacetIndex];\n ++defaultFacetIndex;\n }\n unchecked {\n ++i;\n }\n }\n }\n }\n\n /**\n * @notice Gets all the function selectors provided by a facet.\n * @param _facet The facet address.\n * @return facetFunctionSelectors_\n */\n function facetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n Facet[] memory facet = facets();\n uint256 facetLength = facet.length;\n for (uint256 i; i < facetLength; ) {\n if (facet[i].facetAddress == _facet)\n return facet[i].functionSelectors;\n unchecked {\n ++i;\n }\n }\n return facetFunctionSelectors_;\n }\n\n /**\n * @notice Get all the facet addresses used by Barz.\n * @return facetAddresses_\n */\n function facetAddresses()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n Facet[] memory facet = facets();\n uint256 facetLength = facet.length;\n facetAddresses_ = new address[](facetLength);\n for (uint256 i; i < facetLength; ) {\n facetAddresses_[i] = facet[i].facetAddress;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Gets the facet that supports the given selector.\n * @dev If facet is not found return address(0).\n * @param _functionSelector The function selector.\n * @return facetAddress_ The facet address.\n */\n function facetAddress(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n\n facetAddress_ = address(bytes20(ds.facets[_functionSelector]));\n if (facetAddress_ == address(0)) {\n facetAddress_ = IDiamondLoupe(ds.defaultFallbackHandler)\n .facetAddress(_functionSelector);\n }\n }\n\n /**\n * @notice SupportInterface to be compatible with EIP 165\n * @param _interfaceId Interface ID for detecting the interface\n * @return isSupported Bool value showing if the standard is supported in the contract\n */\n function supportsInterface(\n bytes4 _interfaceId\n ) external view override returns (bool isSupported) {\n isSupported =\n _interfaceId == type(IERC165).interfaceId ||\n _interfaceId == IDiamondCut.diamondCut.selector ||\n _interfaceId == type(IDiamondLoupe).interfaceId ||\n _interfaceId == type(IERC1155Receiver).interfaceId ||\n _interfaceId == type(IERC721Receiver).interfaceId ||\n _interfaceId == type(IERC777Recipient).interfaceId ||\n _interfaceId == IERC1271.isValidSignature.selector ||\n _interfaceId == type(IERC677Receiver).interfaceId ||\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId];\n }\n\n /**\n * @notice Returns the facet from the diamond storage. This excludes the facets from the default fallback handler\n * @return facets_ Facet information attached directly to diamond storage\n */\n function facetsFromStorage()\n external\n view\n override\n returns (Facet[] memory facets_)\n {\n facets_ = LibLoupe.facets();\n }\n\n /**\n * @notice Returns the facet address attached to the given function selector. This excludes the facets from the default fallback handler\n * @param _functionSelector Function selector to fetch the facet address from diamond storage\n * @return facetAddress_ Facet address mapped with the function selector\n */\n function facetAddressFromStorage(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n facetAddress_ = LibLoupe.facetAddress(_functionSelector);\n }\n\n /**\n * @notice Returns all facet addresses attached directly to diamond storage. This excludes the facets from the default fallback handler\n * @return facetAddresses_ All facet addresses attached directly to diamond storage\n */\n function facetAddressesFromStorage()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n facetAddresses_ = LibLoupe.facetAddresses();\n }\n\n /**\n * @notice Returns function selectors of given facet address attached directly to diamond storage. This excludes the facets from the default fallback handler\n * @param _facet Facet address to fetch the facet function selectors from diamond storage\n * @return facetFunctionSelectors_ Facet function selectors of the given facet address\n */\n function facetFunctionSelectorsFromStorage(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n facetFunctionSelectors_ = LibLoupe.facetFunctionSelectors(_facet);\n }\n}\n" + }, + "contracts/facets/base/interfaces/IDiamondCut.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title DiamondCut Facet Interface\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IDiamondCut {\n error DiamondCutFacet__InvalidRouteWithGuardian();\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\n error DiamondCutFacet__InvalidArrayLength();\n error DiamondCutFacet__InsufficientApprovers();\n error DiamondCutFacet__InvalidApprover();\n error DiamondCutFacet__InvalidApproverSignature();\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\n error DiamondCutFacet__CannotRevokeUnapproved();\n error DiamondCutFacet__LackOfOwnerApproval();\n error DiamondCutFacet__OwnerAlreadyApproved();\n error DiamondCutFacet__DuplicateApproval();\n error DiamondCutFacet__InvalidInitAddress();\n\n event DiamondCutApproved(FacetCut[] diamondCut);\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\n\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\n\n enum FacetCutAction {\n Add,\n Replace,\n Remove\n }\n // Add=0, Replace=1, Remove=2\n\n struct FacetCut {\n address facetAddress;\n FacetCutAction action;\n bytes4[] functionSelectors;\n }\n\n /// @notice Add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param diamondCut Contains the facet addresses and function selectors\n /// @param init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function diamondCut(\n FacetCut[] calldata diamondCut,\n address init,\n bytes calldata _calldata\n ) external;\n\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\n\n function diamondCutWithGuardian(\n FacetCut[] calldata diamondCut,\n address[] calldata approvers,\n bytes[] calldata signatures\n ) external;\n\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\n\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\n\n function getDiamondCutApprovalCountWithTimeValidity(\n bytes32 diamondCutHash\n ) external view returns (uint256);\n\n function getOwnerCutApprovalWithTimeValidity(\n bytes32 diamondCutHash\n ) external view returns (bool);\n\n function isCutApproved(\n bytes32 diamondCutHash,\n address approver\n ) external view returns (bool);\n\n function getDiamondCutHash(\n FacetCut[] calldata diamondCut\n ) external view returns (bytes32);\n\n function getDiamondCutNonce() external view returns (uint128);\n}\n" + }, + "contracts/facets/base/interfaces/IDiamondLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n// A loupe is a small magnifying glass used to look at diamonds.\n// These functions look at diamonds\ninterface IDiamondLoupe {\n /// These functions are expected to be called frequently\n /// by tools.\n\n struct Facet {\n address facetAddress;\n bytes4[] functionSelectors;\n }\n\n /// @notice Gets all facet addresses and their four byte function selectors.\n /// @return facets_ Facet\n function facets() external view returns (Facet[] memory facets_);\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n /// @return facetFunctionSelectors_\n function facetFunctionSelectors(\n address _facet\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses()\n external\n view\n returns (address[] memory facetAddresses_);\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(\n bytes4 _functionSelector\n ) external view returns (address facetAddress_);\n}\n" + }, + "contracts/facets/base/interfaces/IStorageLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"./IDiamondLoupe.sol\";\n\n/**\n * @title LoupeFromStorage Interface\n * @dev Interface contract to function as a loupe facet directly attached to diamond storage of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IStorageLoupe {\n /// These functions are expected to be called frequently\n /// by tools.\n\n /// @notice Gets all facet addresses and their four byte function selectors.\n /// @return facets_ Facet\n function facetsFromStorage()\n external\n view\n returns (IDiamondLoupe.Facet[] memory);\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n function facetFunctionSelectorsFromStorage(\n address _facet\n ) external view returns (bytes4[] memory);\n\n /// @notice Get all the facet addresses used by a diamond.\n function facetAddressesFromStorage()\n external\n view\n returns (address[] memory);\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n function facetAddressFromStorage(\n bytes4 _functionSelector\n ) external view returns (address);\n}\n" + }, + "contracts/facets/interfaces/IAccountFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IEntryPoint} from \"../../aa-4337/interfaces/IEntryPoint.sol\";\n\n/**\n * @title Account Facet Interface\n * @dev Interface of module contract that provides the account features and init/unitialization of signer\n * compatible with EIP-1271 & EIP-4337\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IAccountFacet {\n event AccountInitialized(\n IEntryPoint indexed entryPoint,\n bytes indexed ownerPublicKey\n );\n // NOTE: Added Below Event\n event VerificationSuccess(bytes32);\n event VerificationFailure(bytes32);\n\n error AccountFacet__InitializationFailure();\n error AccountFacet__RestrictionsFailure();\n error AccountFacet__NonExistentVerificationFacet();\n error AccountFacet__CallNotSuccessful();\n\n function initialize(\n address verificationFacet,\n address anEntryPoint,\n address facetRegistry,\n address _defaultFallBack,\n bytes calldata _ownerPublicKey\n ) external returns (uint256);\n\n function execute(address dest, uint256 value, bytes calldata func) external;\n\n function executeBatch(\n address[] calldata dest,\n uint256[] calldata value,\n bytes[] calldata func\n ) external;\n}\n" + }, + "contracts/facets/interfaces/IAccountRecoveryFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {RecoveryConfig} from \"../../libraries/LibFacetStorage.sol\";\n\n/**\n * @title Account Recovery Facet Interface\n * @dev Interface of contract that enables recovery of accounts when owner key is unavailable\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IAccountRecoveryFacet {\n event RecoveryExecuted(\n bytes indexed recoveryPublicKey,\n uint64 executeAfter\n );\n event RecoveryFinalized(bytes indexed recoveryPublicKey);\n event RecoveryCanceled(bytes indexed recoveryPublicKey);\n event RecoveryApproved(\n bytes indexed recoveryPublicKey,\n address indexed guardian,\n uint64 validUntil\n );\n event RecoveryApprovalRevoked(\n bytes indexed recoveryPublicKey,\n address indexed guardian\n );\n event RecoveryCancellationApproved(\n bytes indexed recoveryPublicKey,\n address indexed guardian\n );\n event RecoveryHardstopped();\n\n error AccountRecoveryFacet__CallerNotGuardian();\n error AccountRecoveryFacet__InvalidRecoveryPublicKey();\n error AccountRecoveryFacet__SignerInitializationFailure();\n error AccountRecoveryFacet__SignerUninitializationFailure();\n error AccountRecoveryFacet__InvalidArrayLength();\n error AccountRecoveryFacet__InsufficientGuardians();\n error AccountRecoveryFacet__RecoveryAlreadyOngoing();\n error AccountRecoveryFacet__NonexistentRecovery();\n error AccountRecoveryFacet__NonExistentApproval();\n error AccountRecoveryFacet__RecoveryPeriodNotOver();\n error AccountRecoveryFacet__InvalidLockPeriod();\n error AccountRecoveryFacet__InvalidRecoveryPeriod();\n error AccountRecoveryFacet__InvalidApprovalValidationPeriod();\n error AccountRecoveryFacet__InvalidGuardian();\n error AccountRecoveryFacet__InvalidGuardianSignature();\n error AccountRecoveryFacet__InvalidOwnerSignature();\n error AccountRecoveryFacet__CallNotSuccesful();\n error AccountRecoveryFacet__DuplicateApproval();\n\n function approveAccountRecovery(bytes calldata recoveryPublicKey) external;\n\n function revokeAccountRecoveryApproval(\n bytes calldata recoveryPublicKey\n ) external;\n\n function executeRecovery(\n bytes calldata recoveryPublicKey,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function finalizeRecovery() external;\n\n function approveCancelRecovery(bytes calldata recoveryPublicKey) external;\n\n function cancelRecovery(\n bytes calldata recoveryPublicKey,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function hardstopRecovery(bytes calldata signature) external;\n\n function getApprovalRecoveryKeyHash(\n bytes memory recoveryPublicKey,\n string memory saltString\n ) external view returns (bytes32);\n\n function getRecoveryApprovalCountWithTimeValidity(\n bytes32 recoveryPublicKeyHash\n ) external view returns (uint256);\n\n function isRecoveryApproved(\n bytes32 recoveryPublicKeyHash,\n address approver\n ) external view returns (bool);\n\n function getRecoveryNonce() external view returns (uint128);\n\n function getPendingRecovery() external view returns (RecoveryConfig memory);\n}\n" + }, + "contracts/facets/interfaces/IMultiSigFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Multi-sig facet Interface\n * @dev Interface of Multi-signature Facet with custom threshold.\n Wallet that adds this facet becomes a multi-sig wallet\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IMultiSigFacet {\n event ThresholdChanged(uint256 threshold);\n event OwnerAdded(address indexed newOwner);\n event OwnerRemoved(address indexed prevOwner);\n event HashApproved(bytes32 hashToApprove, address indexed owner);\n\n error MultiSigFacet__InvalidThreshold();\n error MultisigFacet__InvalidOwnerCount();\n error MultiSigFacet__InvalidRoute();\n error MultiSigFacet__InsufficientSignerLength();\n error MultiSigFacet__InvalidInitData();\n error MultiSigFacet__InvalidOwnerAddress();\n error MultiSigFacet__InvalidOwnerPair();\n error MultiSigFacet__InvalidSignatureLength();\n error MultiSigFacet__InvalidSignatureType();\n error MultiSigFacet__DuplicateOwner();\n error MultiSigFacet__OnlyOwner();\n\n function checkSignatures(\n bytes32 _dataHash,\n bytes calldata _signatures,\n uint256 _threshold\n ) external view returns (uint256);\n\n function splitSignatures(\n bytes calldata _signatures,\n uint256 _nextOffset\n )\n external\n pure\n returns (\n address owner,\n bytes memory signature,\n uint256 signatureType,\n uint256 nextOffset\n );\n\n function approveHash(bytes32 hashToApprove) external;\n\n function addOwner(address newOwner, uint256 threshold) external;\n\n function removeOwner(\n address prevOwner,\n address removedOwner,\n uint256 threshold\n ) external;\n\n function swapOwner(\n address prevOwner,\n address oldOwner,\n address newOwner\n ) external;\n\n function changeThreshold(uint256 _threshold) external;\n\n function isOwner(address owner) external view returns (bool);\n\n function getThreshold() external view returns (uint256);\n\n function getOwners() external view returns (address[] memory);\n}\n" + }, + "contracts/facets/interfaces/ISignatureMigrationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureMigrationConfig} from \"../../libraries/LibFacetStorage.sol\";\n\n/**\n * @title Signature Migration Facet Interface\n * @dev Interface of Signature Migration contract for migrating user signature scheme to a new scheme user sets\n * Which could include\n * - ECDSA on Secp256K1 Curve\n * - ECDSA on Secp256R1 Curve\n * - BLS, Schnorr, etc\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface ISignatureMigrationFacet {\n event SignatureSchemeMigration(\n address indexed prevVerificationFacet,\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n event SignatureMigrationApproved(\n bytes newPublicKey,\n address indexed newVerificationFacet,\n bytes4[] verificationFuncSelectors,\n address indexed guardian,\n uint128 approvalValidUntil\n );\n event SignatureMigrationApprovalRevoked(\n bytes newPublicKey,\n address indexed newVerificationFacet,\n bytes4[] verificationFuncSelectors,\n address indexed guardian\n );\n event SignatureMigrationExecuted(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors,\n uint128 migrateAfter\n );\n event SignatureMigrationCanceled(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n event SignatureMigrationCancellationApproved(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n\n error SignatureMigrationFacet__SignerUninitializationFailure();\n error SignatureMigrationFacet__InvalidRouteWithGuardian();\n error SignatureMigrationFacet__InvalidKeyType();\n error SignatureMigrationFacet__InsufficientApprovers();\n error SignatureMigrationFacet__InvalidApproverSignature();\n error SignatureMigrationFacet__InvalidGuardian();\n error SignatureMigrationFacet__NonExistentApprover();\n error SignatureMigrationFacet__InvalidMigrationPeriod();\n error SignatureMigrationFacet__NonexistentMigration();\n error SignatureMigrationFacet__MigrationPeriodNotOver();\n error SignatureMigrationFacet__InvalidArrayLength();\n error SignatureMigrationFacet__InvalidApprovalValidationPeriod();\n error SignatureMigrationFacet__CannotRevokeUnapproved();\n error SignatureMigrationFacet__LackOfOwnerApproval();\n error SignatureMigrationFacet__OwnerAlreadyApproved();\n error SignatureMigrationFacet__NonExistentVerificationFacet();\n error SignatureMigrationFacet__DuplicateApproval();\n\n function migrateSignatureScheme(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function migrateSignatureSchemeWithGuardian(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors,\n address[] calldata approvers,\n bytes[] calldata signatures\n ) external;\n\n function approveSignatureSchemeMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function revokeSignatureMigrationApproval(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function finalizeSignatureMigration() external;\n\n function approveCancelSignatureMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function cancelSignatureMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function getApprovalMigrationKeyHash(\n bytes memory recoveryPublicKey,\n address newVerificationFacet,\n bytes4[] memory newVerificationFuncSelectors,\n string memory saltString\n ) external view returns (bytes32);\n\n function getMigrationOwnerApprovalWithTimeValidity(\n bytes32 publicKeyHash\n ) external view returns (bool);\n\n function getMigrationApprovalCountWithTimeValidity(\n bytes32 publicKeyHash\n ) external view returns (uint256);\n\n function isMigrationApproved(\n bytes32 migrationPublicKeyHash,\n address approver\n ) external view returns (bool);\n\n function getMigrationNonce() external view returns (uint128);\n\n function isMigrationPending() external view returns (bool);\n\n function getPendingMigration()\n external\n view\n returns (SignatureMigrationConfig memory);\n}\n" + }, + "contracts/facets/interfaces/IVerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {UserOperation} from \"../../aa-4337/interfaces/UserOperation.sol\";\n\n/**\n * @title Verification Facet Interface\n * @dev Implements logic for user ops signature verification\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface IVerificationFacet {\n event SignerInitialized(bytes);\n event SignerUninitialized();\n\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n error VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n error VerificationFacet__InitializationFailure();\n error VerificationFacet__InvalidFacetMapping();\n\n function initializeSigner(bytes memory) external returns (uint256);\n\n function uninitializeSigner() external returns (uint256);\n\n function validateOwnerSignatureSelector() external view returns (bytes4);\n\n function owner() external view returns (bytes memory);\n\n function isValidKeyType(bytes calldata) external view returns (bool);\n\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) external view returns (uint256);\n}\n" + }, + "contracts/facets/Modifiers.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {IFacetRegistry} from \"../infrastructure/interfaces/IFacetRegistry.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\n\n/**\n * @title Modifiers\n * @dev Responsible for providing modifiers/util functions to Facet contracts\n * @author David Yongjun Kim (@Powerstream3604)\n */\nabstract contract Modifiers is BarzStorage {\n uint8 constant INNER_STRUCT = 0;\n\n error CallerNotGuardian();\n error CallerNotGuardianOrOwner();\n error DuplicateApprover();\n error ZeroApproverLength();\n error UnregisteredFacetAndSelectors();\n\n /**\n * @notice Modifier to only allow guardian to make a call, reverts if any other entity is the caller\n */\n modifier onlyGuardian() {\n if (!LibGuardian.isGuardian(msg.sender)) revert CallerNotGuardian();\n _;\n }\n\n /**\n * @notice Modifier to only allow guardian or owner to make a call, reverts if any other entity is the caller\n */\n modifier onlyGuardianOrOwner() {\n if (!LibGuardian.isGuardian(msg.sender) && address(this) != msg.sender)\n revert CallerNotGuardianOrOwner();\n _;\n }\n\n /**\n * @notice Checks if the approver address is the array is unique with no duplicate\n * @dev This method loops through the array and checks if a duplicate address exists, it reverts if duplicate address exists\n * @param approvers Array of address\n */\n function _checkApprover(\n address[] memory approvers\n ) internal pure returns (bool) {\n uint256 approverLength = approvers.length;\n if (0 == approverLength) revert ZeroApproverLength();\n for (uint256 i; i < approverLength - 1; ) {\n for (uint256 j = i + 1; j < approverLength; ) {\n if (approvers[i] == approvers[j]) {\n revert DuplicateApprover(); // Found a duplicate\n }\n unchecked {\n ++j;\n }\n }\n unchecked {\n ++i;\n }\n }\n return false; // No duplicates found\n }\n\n /**\n * @notice Checks if the facet getting added or replaced is registered to facet registry\n * @dev This method loops through the cut and checks if the facet getting added/replaced is registered to facet registry\n * @param _diamondCut Array of FacetCut, data for diamondCut defined in EIP-2535\n */\n function _checkFacetCutValidity(\n IDiamondCut.FacetCut[] memory _diamondCut\n ) internal view {\n uint256 diamondCutLength = _diamondCut.length;\n for (uint256 i; i < diamondCutLength; ) {\n if (\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Add ||\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Replace\n ) {\n if (\n !s.facetRegistry.areFacetFunctionSelectorsRegistered(\n _diamondCut[i].facetAddress,\n _diamondCut[i].functionSelectors\n )\n ) revert UnregisteredFacetAndSelectors();\n }\n unchecked {\n ++i;\n }\n }\n }\n}\n" + }, + "contracts/facets/SignatureMigrationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, SignatureMigrationStorage, SignatureMigrationConfig, SignatureMigrationApprovalConfig, ApprovalConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IDiamondCut} from \"./base/interfaces/IDiamondCut.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {ISignatureMigrationFacet} from \"./interfaces/ISignatureMigrationFacet.sol\";\n\n/**\n * @title Signature Migration Facet\n * @dev Responsible for migrating user signature scheme to a new scheme user sets\n * Which could include\n * - ECDSA on Secp256K1 Curve\n * - ECDSA on Secp256R1 Curve\n * - BLS, Schnorr, etc\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract SignatureMigrationFacet is ISignatureMigrationFacet, Modifiers {\n bytes constant UNINIT_CALL =\n abi.encodeWithSignature(\"uninitializeSigner()\");\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This modifier verifies if the public key format matches with the new verification facet\n * @param _publicKey Bytes of public key to be validated for the new verification facet\n * @param _newVerificationFacet Address of new verification facet\n */\n modifier validateKeyType(\n bytes memory _publicKey,\n address _newVerificationFacet\n ) {\n if (\n !IVerificationFacet(_newVerificationFacet).isValidKeyType(\n _publicKey\n )\n ) revert SignatureMigrationFacet__InvalidKeyType();\n _;\n }\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n // IMPORTANT NOTE: In the client side when they call this function, the func selectors should be sorted in ascending order\n // to prevent different hash with same items in the array\n /**\n * @notice Moves the state of migration to a pending state. When pending state is over after pending period time,\n * Migration can be finalized. This function can only be called by self and when the account is unlocked.\n * @dev This method checks if the caller is self and if guardians exists. It migrates signature request to a pending state\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function migrateSignatureScheme(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n public\n override\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n // Only self contract can call this function\n LibDiamond.enforceIsSelf();\n // Should revert if guardian exist\n if (0 != LibGuardian.guardianCount())\n revert SignatureMigrationFacet__InvalidRouteWithGuardian();\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n // NOTE: Migration requires a pending period & confirmation from owner to prevent a\n // single call changing the ownership of the wallet\n /**\n * @notice Migrate signature scheme when guardians exists. Verifies the signature of guardians and moves migration to pending state.\n * Which can then be finalized when pending period is over. Owner's approval is mandatory for migration to happen\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _approvers List of approvers. This could include owner\n */\n function migrateSignatureSchemeWithGuardian(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n )\n public\n override\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n // Should revert if does not guardian exist\n if (0 == LibGuardian.guardianCount())\n revert SignatureMigrationFacet__InvalidRouteWithGuardian();\n if (_approvers.length != _signatures.length)\n revert SignatureMigrationFacet__InvalidArrayLength();\n\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(migrationPublicKeyHash, _approvers);\n\n bool onChainOwnerApproval = getMigrationOwnerApprovalWithTimeValidity(\n migrationPublicKeyHash\n );\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n\n if (\n _approvers.length +\n getMigrationApprovalCountWithTimeValidity(\n migrationPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert SignatureMigrationFacet__InsufficientApprovers();\n {\n // To prevent Stack too deep\n bool ownerApproved;\n for (uint256 i; i < _approvers.length; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n address(this) != _approvers[i]\n ) revert SignatureMigrationFacet__InvalidGuardian();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert SignatureMigrationFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n migrationPublicKeyHash,\n _signatures[i]\n )\n ) revert SignatureMigrationFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n\n if (!ownerApproved && !onChainOwnerApproval)\n revert SignatureMigrationFacet__LackOfOwnerApproval();\n }\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Internal function that moves signature mgiration to a pending state.\n * @dev This method increments migration nonce and sets the migration in the migration config. Emits events for migration execution\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _migrateSignatureScheme(\n address _newVerificationFacet,\n bytes memory _newPublicKey,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal {\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n\n ++ms.nonce;\n uint64 migrateAfter = uint64(block.timestamp + getMigrationPeriod());\n\n ms.migrationConfigs[INNER_STRUCT] = SignatureMigrationConfig(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n migrateAfter\n );\n\n emit SignatureMigrationExecuted(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors,\n migrateAfter\n );\n }\n\n /**\n * @notice Approves signature scheme migration on-chain. This can be called by owner or guardian only when the account is unlocked.\n * When the threshold of the migration approval passed and owner approval is granted, it automatically moves migration to a pending state\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function approveSignatureSchemeMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n public\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit SignatureMigrationApproved(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n msg.sender,\n approvalValidUntil\n );\n if (\n getMigrationApprovalCountWithTimeValidity(migrationPublicKeyHash) >=\n LibGuardian.majorityOfGuardians() &&\n getMigrationOwnerApprovalWithTimeValidity(migrationPublicKeyHash)\n )\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Revokes the approval of signature migration done on-chain. Emits revoke event when revoked.\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function revokeSignatureMigrationApproval(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n external\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n if (!isMigrationApproved(migrationPublicKeyHash, msg.sender))\n revert SignatureMigrationFacet__CannotRevokeUnapproved();\n\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(false, 0);\n emit SignatureMigrationApprovalRevoked(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n msg.sender\n );\n }\n\n /**\n * @notice Finalizes the pending signature scheme migration. This function can only be called by owner.\n * It removes the facets of the previous verification facet and adds the new verification facet.\n * After finalizing migration, it emits migration event which shows the change of the verification facet\n */\n function finalizeSignatureMigration() external override {\n // NOTE: Only owner can call this function\n LibDiamond.enforceIsSelf();\n\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n\n if (!isMigrationPending())\n revert SignatureMigrationFacet__NonexistentMigration();\n\n if (\n uint64(block.timestamp) <=\n ms.migrationConfigs[INNER_STRUCT].migrateAfter\n ) revert SignatureMigrationFacet__MigrationPeriodNotOver();\n address newVerificationFacet = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationVerificationFacet;\n bytes4[] memory newVerificationFuncSelectors = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationSelectors;\n bytes memory newPublicKey = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationPublicKey;\n\n address prevVerificationFacet = LibLoupe.facetAddress(\n s.validateOwnerSignatureSelector\n );\n if (prevVerificationFacet == address(0))\n revert SignatureMigrationFacet__NonExistentVerificationFacet();\n\n IDiamondCut.FacetCut[] memory UninitCut;\n IDiamondCut.FacetCut[] memory InitCut;\n {\n bytes4[] memory prevVerificationFuncSelectors = LibLoupe\n .facetFunctionSelectors(prevVerificationFacet);\n\n UninitCut = new IDiamondCut.FacetCut[](1);\n InitCut = new IDiamondCut.FacetCut[](1);\n UninitCut[0] = IDiamondCut.FacetCut({\n facetAddress: address(0),\n action: IDiamondCut.FacetCutAction.Remove,\n functionSelectors: prevVerificationFuncSelectors\n });\n InitCut[0] = IDiamondCut.FacetCut({\n facetAddress: newVerificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: newVerificationFuncSelectors\n });\n {\n IDiamondCut.FacetCut[]\n memory facetCuts = new IDiamondCut.FacetCut[](2);\n facetCuts[0] = UninitCut[0];\n facetCuts[1] = InitCut[0];\n _checkFacetCutValidity(facetCuts);\n }\n LibAppStorage.initiateSignerMigration();\n address verificationFacet = address(\n bytes20(\n LibDiamond.diamondStorage().facets[\n s.validateOwnerSignatureSelector\n ]\n )\n );\n\n (bool success, bytes memory result) = verificationFacet\n .delegatecall(UNINIT_CALL);\n require(success, \"MigrationFacet: uninitialize not successful\");\n uint256 validationData = uint256(bytes32(result));\n if (validationData == 0)\n revert SignatureMigrationFacet__SignerUninitializationFailure();\n\n LibDiamond.diamondCut(UninitCut, address(0), \"\");\n }\n {\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n newPublicKey\n );\n\n // Every Verification Facet should comply with initializeSigner(bytes)\n // to be compatible with the Barz contract(for initialization)\n LibDiamond.diamondCut(InitCut, newVerificationFacet, initCall);\n LibAppStorage.finalizeSignerMigration();\n emit SignatureSchemeMigration(\n prevVerificationFacet,\n newVerificationFacet,\n newPublicKey,\n newVerificationFuncSelectors\n );\n }\n }\n\n /**\n * @notice Approve cancellation of signature migration. If cancellation approval passes guardian threshold with owner approval\n * it automatically cancels the migration.\n * @dev This method checks if the caller is one of guardian or owner and sets true for the cancellation hash in the approval config.\n * It internally calls _cancelSignatureMigration for canceling the migration\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function approveCancelSignatureMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n external\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"CancelSignatureMigration\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit SignatureMigrationCancellationApproved(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n if (\n getMigrationApprovalCountWithTimeValidity(migrationPublicKeyHash) >=\n LibGuardian.majorityOfGuardians() &&\n getMigrationOwnerApprovalWithTimeValidity(migrationPublicKeyHash)\n )\n _cancelSignatureMigration(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Verifies the signature of guardians/owner and cancels the signature migration.\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _approvers List of approvers. This could include owner\n */\n function cancelSignatureMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n )\n external\n override\n validateKeyType(_newPublicKey, _newVerificationFacet)\n onlyWhenUnlocked\n {\n if (_approvers.length != _signatures.length)\n revert SignatureMigrationFacet__InvalidArrayLength();\n\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"CancelSignatureMigration\"\n );\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(migrationPublicKeyHash, _approvers);\n\n bool onChainOwnerApproval = getMigrationOwnerApprovalWithTimeValidity(\n migrationPublicKeyHash\n );\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n if (\n _approvers.length +\n getMigrationApprovalCountWithTimeValidity(\n migrationPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert SignatureMigrationFacet__InsufficientApprovers();\n {\n // To prevent stack too deep\n bool ownerApproved;\n for (uint256 i; i < _approvers.length; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n address(this) != _approvers[i]\n ) revert SignatureMigrationFacet__NonExistentApprover();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert SignatureMigrationFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n migrationPublicKeyHash,\n _signatures[i]\n )\n ) revert SignatureMigrationFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n if (!ownerApproved && !onChainOwnerApproval)\n revert SignatureMigrationFacet__LackOfOwnerApproval();\n }\n _cancelSignatureMigration(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Internal function that cancels signature migration.\n * @dev This method increments migration nonce and deletes the migration from the migration config. Emits events for migration cancellation\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _cancelSignatureMigration(\n address _newVerificationFacet,\n bytes memory _newPublicKey,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal {\n if (!isMigrationPending())\n revert SignatureMigrationFacet__NonexistentMigration();\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n ++ms.nonce;\n delete ms.migrationConfigs[INNER_STRUCT];\n emit SignatureMigrationCanceled(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Checks if the facets to be added from new verification facet is registered to facet registry\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _checkMigrationCutValidity(\n address _newVerificationFacet,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal view {\n IDiamondCut.FacetCut[] memory facetCuts = new IDiamondCut.FacetCut[](1);\n facetCuts[0] = IDiamondCut.FacetCut({\n facetAddress: _newVerificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: _newVerificationFuncSelectors\n });\n _checkFacetCutValidity(facetCuts);\n }\n\n /**\n * @notice Returns if the migration is pending of not\n * @dev This method fetches the migration storage and checks if the migrate after is above 0 value\n * @return isPending Bool value that shows if the migration is pending\n */\n function isMigrationPending()\n public\n view\n override\n returns (bool isPending)\n {\n SignatureMigrationStorage storage rs = LibFacetStorage\n .migrationStorage();\n isPending = rs.migrationConfigs[INNER_STRUCT].migrateAfter > 0;\n }\n\n /**\n * @notice Returns the migration hash. This function ensures that this hash is safe from replay attack by including\n * public key, verification facet, function selectors, salt, address, chainId, and nonce.\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _saltString Salt value for generating the migration hash\n * @return migrationKeyHash Bytes32 string of the migration key hash\n */\n function getApprovalMigrationKeyHash(\n bytes memory _newPublicKey,\n address _newVerificationFacet,\n bytes4[] memory _newVerificationFuncSelectors,\n string memory _saltString\n ) public view override returns (bytes32 migrationKeyHash) {\n migrationKeyHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n _newPublicKey,\n _newVerificationFacet,\n keccak256(abi.encode(_newVerificationFuncSelectors)),\n _saltString,\n address(this),\n block.chainid,\n LibFacetStorage.migrationStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Checks if the owner approved the hash for migration\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @return isApprovedByOwner Bool value of showing if the owner approved it or not\n */\n function getMigrationOwnerApprovalWithTimeValidity(\n bytes32 _migrationPublicKeyHash\n ) public view override returns (bool isApprovedByOwner) {\n isApprovedByOwner = isMigrationApproved(\n _migrationPublicKeyHash,\n address(this)\n );\n }\n\n /**\n * @notice Checks how many of the guardians approved the migration hash\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @return approvalCount Number of approvals\n */\n function getMigrationApprovalCountWithTimeValidity(\n bytes32 _migrationPublicKeyHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardiansLength = guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n if (isMigrationApproved(_migrationPublicKeyHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n return approvalCount;\n }\n\n /**\n * @notice Checks if the migration is approved by the given approver\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @param _approver Address of approver\n * @return isApproved Bool value if migration hash is approved\n */\n function isMigrationApproved(\n bytes32 _migrationPublicKeyHash,\n address _approver\n ) public view override returns (bool isApproved) {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n isApproved = (ms\n .isMigrationApproved[_migrationPublicKeyHash][_approver].isApproved &&\n block.timestamp <\n ms\n .isMigrationApproved[_migrationPublicKeyHash][_approver]\n .validUntil);\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _migrationPublicKeyHash Hash of migration information\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _migrationPublicKeyHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isMigrationApproved(_migrationPublicKeyHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert SignatureMigrationFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the migration period of this wallet\n * @dev This method fetches the migration period from the security manager\n * @return migrationPeriod Migration period of Barz contract fetched from security manager\n */\n function getMigrationPeriod()\n internal\n view\n returns (uint128 migrationPeriod)\n {\n migrationPeriod = securityManager.migrationPeriodOf(address(this));\n if (migrationPeriod == 0)\n revert SignatureMigrationFacet__InvalidMigrationPeriod();\n }\n\n /**\n * @notice Returns the validation period of this wallet\n * @dev This method fetches the validation period from the security manager\n * @return approvalValidationPeriod Validation period of Barz contract fetched from security manager\n */\n function getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod == 0)\n revert SignatureMigrationFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the migration nonce of this wallet\n * @dev This method fetches the nonce from migration storage\n * @return migrationNonce Nonce of migration to protect from reply attacks\n */\n function getMigrationNonce()\n public\n view\n override\n returns (uint128 migrationNonce)\n {\n migrationNonce = LibFacetStorage.migrationStorage().nonce;\n }\n\n /**\n * @notice Returns the migration configuration of this wallet\n * @dev This method fetches the migration config from the migration storage\n * @return pendingMigrationConfig Migration config currently pending for signature migration\n */\n function getPendingMigration()\n external\n view\n override\n returns (SignatureMigrationConfig memory pendingMigrationConfig)\n {\n pendingMigrationConfig = LibFacetStorage\n .migrationStorage()\n .migrationConfigs[INNER_STRUCT];\n }\n}\n" + }, + "contracts/facets/verification/MultiSigFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {UserOperation} from \"../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../../libraries/LibLoupe.sol\";\nimport {LibAppStorage} from \"../../libraries/LibAppStorage.sol\";\nimport {LibMultiSigStorage, MultiSigStorage} from \"../../libraries/LibMultiSigStorage.sol\";\nimport {IERC1271} from \"../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../interfaces/IVerificationFacet.sol\";\nimport {IMultiSigFacet} from \"../interfaces/IMultiSigFacet.sol\";\n\n/**\n * @title Multi-sig facet\n * @dev Multi-signature Facet with custom threshold.\n * Wallet that adds this facet becomes a multi-sig wallet.\n * Reference signature_format.md documentation for Multi-sig facet details\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract MultiSigFacet is IMultiSigFacet, IVerificationFacet, IERC1271 {\n using ECDSA for bytes32;\n\n address public immutable self;\n\n address internal constant SENTINEL_OWNERS = address(0x1);\n uint256 internal constant ADDRESS = 20;\n uint256 internal constant SIG_TYPE = 1;\n uint256 internal constant SIG_LEN = 4;\n uint256 internal constant THRESHOLD = 4;\n uint256 internal constant INVALID_SIG = 1;\n uint256 internal constant VALID_SIG = 0;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in Multisig Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the right format and initializes signer storage in k1 storage.\n * @param _owners Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _owners\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n\n if (!isValidKeyType(_owners)) revert MultiSigFacet__InvalidInitData();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n uint256 threshold = uint256(uint32(bytes4(_owners)));\n uint256 ownerCount = (_owners.length - THRESHOLD) / ADDRESS;\n\n if (threshold == 0) revert MultiSigFacet__InvalidThreshold();\n if (ownerCount == 0) revert MultisigFacet__InvalidOwnerCount();\n\n address currentOwner = SENTINEL_OWNERS;\n uint256 ptr = THRESHOLD;\n address owner_;\n for (uint256 i; i < ownerCount; ) {\n owner_ = address(bytes20(_owners[ptr:ptr + ADDRESS]));\n ptr += ADDRESS;\n if (\n owner_ == address(0) ||\n owner_ == SENTINEL_OWNERS ||\n owner_ == address(this) ||\n owner_ == currentOwner\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[owner_] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n\n ms.owners[currentOwner] = owner_;\n currentOwner = owner_;\n\n unchecked {\n ++i;\n }\n }\n ms.owners[currentOwner] = SENTINEL_OWNERS;\n ms.ownerCount = ownerCount;\n ms.threshold = threshold;\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_owners);\n }\n\n /**\n * @notice Uninitialize signer in K1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n ++ms.counter;\n address[] memory ownerlist = getOwners();\n uint256 ownerlistLength = ownerlist.length;\n for (uint256 i; i < ownerlistLength; ) {\n ms.owners[ownerlist[i]] = address(0);\n unchecked {\n ++i;\n }\n }\n ms.owners[SENTINEL_OWNERS] = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls checkSignatures with\n * user operation hash and signature together with the threshold.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n // Data 1 is invalid, Data 0 is valid\n validationData = checkSignatures(\n userOpHash,\n userOp.signature,\n LibMultiSigStorage.multisigStorage().threshold\n );\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n return this.validateOwnerSignature.selector;\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n uint totalLength = ms.ownerCount * ADDRESS;\n bytes memory result = new bytes(totalLength);\n\n // populate return array\n uint256 index;\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n while (currentOwner != SENTINEL_OWNERS) {\n assembly {\n mstore(\n add(result, add(32, mul(index, ADDRESS))),\n shl(96, currentOwner)\n )\n }\n currentOwner = ms.owners[currentOwner];\n index++;\n }\n\n return result;\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key should comply with the format in the signature_format.md doc\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n uint256 publicKeyLength = _publicKey.length;\n if (\n publicKeyLength < ADDRESS + THRESHOLD ||\n (publicKeyLength - THRESHOLD) % ADDRESS != 0\n ) return false;\n\n uint256 threshold = uint256(uint32(bytes4(_publicKey)));\n uint256 ownerCount = (publicKeyLength - THRESHOLD) / ADDRESS;\n\n isValid = !(ownerCount < threshold || threshold == 0);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes calldata _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (checkSignatures(\n _hash,\n _signature,\n LibMultiSigStorage.multisigStorage().threshold\n ) == VALID_SIG)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n\n /**\n * @notice Validates the format of the signature and verifies if the signature is signed by the expected key.\n * Reference signature_format.md doc for details about signature format and signature types\n * @param _dataHash Bytes value of data hash signed by the owners\n * @param _signatures Bytes value of signature which should comply with signature format\n * @param _threshold Uint256 value of current Multi-sig Barz's threshold\n */\n function checkSignatures(\n bytes32 _dataHash,\n bytes calldata _signatures,\n uint256 _threshold\n ) public view returns (uint256) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n address lastOwner = address(0);\n address currentOwner;\n bytes memory signature;\n uint256 signatureType;\n uint256 nextOffset;\n uint256 i;\n for (i; i < _threshold; ) {\n (\n currentOwner,\n signature,\n signatureType,\n nextOffset\n ) = splitSignatures(_signatures, nextOffset);\n if (nextOffset == 0 && i + 1 < _threshold) return INVALID_SIG;\n if (signatureType == 1) {\n // If signatureType is 1 then it is default dataHash signed.\n // This also includes the contract signature\n if (\n !SignatureChecker.isValidSignatureNow(\n currentOwner,\n _dataHash,\n signature\n )\n ) return INVALID_SIG;\n } else if (signatureType == 2) {\n // If signatureType is 2 then it is an approved hash\n if (ms.approvedHashes[ms.counter][currentOwner][_dataHash] == 0)\n return INVALID_SIG;\n } else if (signatureType == 3) {\n // If signatureType is 3 then it is a signed message hash\n // This also includes the contract signature\n bytes32 msgHash = _dataHash.toEthSignedMessageHash();\n if (\n !SignatureChecker.isValidSignatureNow(\n currentOwner,\n msgHash,\n signature\n )\n ) return INVALID_SIG;\n } else revert MultiSigFacet__InvalidRoute();\n if (\n currentOwner <= lastOwner ||\n ms.owners[currentOwner] == address(0) ||\n currentOwner == SENTINEL_OWNERS\n ) return INVALID_SIG;\n lastOwner = currentOwner;\n\n unchecked {\n ++i;\n }\n }\n return VALID_SIG;\n }\n\n /**\n * @notice Split signatures into each individual signatures. Should comply with signature format to be split\n * @param _signatures Bytes value of signature\n * @param _nextOffset Uint256 value of next offset to start splitting the signature\n */\n function splitSignatures(\n bytes calldata _signatures,\n uint256 _nextOffset\n )\n public\n pure\n returns (\n address owner_,\n bytes memory signature,\n uint256 signatureType,\n uint256 nextOffset\n )\n {\n uint256 signaturesLength = _signatures.length;\n\n if (signaturesLength <= _nextOffset + ADDRESS + SIG_LEN)\n revert MultiSigFacet__InsufficientSignerLength();\n\n owner_ = address(\n bytes20(_signatures[_nextOffset:_nextOffset + ADDRESS])\n );\n\n signatureType = uint256(\n uint8(\n bytes1(\n _signatures[_nextOffset + ADDRESS:_nextOffset +\n ADDRESS +\n SIG_TYPE]\n )\n )\n );\n\n if (signatureType > 3 || signatureType == 0)\n revert MultiSigFacet__InvalidSignatureType();\n uint256 offSet = _nextOffset + ADDRESS + SIG_TYPE;\n uint256 siglen = uint256(\n uint32(bytes4(_signatures[offSet:offSet + SIG_LEN]))\n );\n if (offSet + siglen > signaturesLength)\n revert MultiSigFacet__InvalidSignatureLength();\n\n offSet += SIG_LEN;\n if (offSet + siglen == signaturesLength) nextOffset = 0;\n else nextOffset = offSet + siglen;\n\n signature = _signatures[offSet:offSet + siglen];\n }\n\n /**\n * @notice Approves the hash of userOperation on-chain. This can only be called by owners.\n * @param _hashToApprove Bytes value of UserOperation hash to approve\n */\n function approveHash(bytes32 _hashToApprove) external {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (ms.owners[msg.sender] == address(0))\n revert MultiSigFacet__OnlyOwner();\n\n ms.approvedHashes[ms.counter][msg.sender][_hashToApprove] = 1;\n emit HashApproved(_hashToApprove, msg.sender);\n }\n\n /**\n * @notice Add owner to Barz. Update thresold if threshold is given different from current threshold\n * @dev This can only be done via a Self call.\n * @param _newOwner Address of new owner to be added\n * @param _threshold Uint256 value of threshold\n */\n function addOwner(address _newOwner, uint256 _threshold) external {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (\n _newOwner == address(0) ||\n _newOwner == SENTINEL_OWNERS ||\n _newOwner == address(this)\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_newOwner] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n\n ms.owners[_newOwner] = ms.owners[SENTINEL_OWNERS];\n ms.owners[SENTINEL_OWNERS] = _newOwner;\n ++ms.ownerCount;\n emit OwnerAdded(_newOwner);\n\n if (ms.threshold != _threshold) changeThreshold(_threshold);\n }\n\n /**\n * @notice Remove owner from Barz. Update thresold if threshold is given different from current threshold\n * @dev This can only be done via a Self call.\n * @param _prevOwner Address of owner located right behind the removed owner address in the linked list\n * @param _removedOwner Address of owner to be removed\n * @param _threshold Uint256 value of threshold\n */\n function removeOwner(\n address _prevOwner,\n address _removedOwner,\n uint256 _threshold\n ) external {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (ms.ownerCount - 1 < _threshold)\n revert MultiSigFacet__InvalidThreshold();\n if (_removedOwner == address(0) || _removedOwner == SENTINEL_OWNERS)\n revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_prevOwner] != _removedOwner)\n revert MultiSigFacet__InvalidOwnerPair();\n\n ms.owners[_prevOwner] = ms.owners[_removedOwner];\n ms.owners[_removedOwner] = address(0);\n --ms.ownerCount;\n emit OwnerRemoved(_removedOwner);\n\n if (ms.threshold != _threshold) changeThreshold(_threshold);\n }\n\n /**\n * @notice Swap owner in Barz.\n * @dev This can only be done via a Self call.\n * @param _prevOwner Address of owner located right behind the removed owner address in the linked list\n * @param _oldOwner Address of owner to be removed\n * @param _newOwner Address of owner to be added\n */\n function swapOwner(\n address _prevOwner,\n address _oldOwner,\n address _newOwner\n ) public {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (\n _newOwner == address(0) ||\n _newOwner == SENTINEL_OWNERS ||\n _newOwner == address(this)\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_newOwner] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n if (_oldOwner == address(0) || _oldOwner == SENTINEL_OWNERS)\n revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_prevOwner] != _oldOwner)\n revert MultiSigFacet__InvalidOwnerPair();\n\n ms.owners[_newOwner] = ms.owners[_oldOwner];\n ms.owners[_prevOwner] = _newOwner;\n ms.owners[_oldOwner] = address(0);\n emit OwnerRemoved(_oldOwner);\n emit OwnerAdded(_newOwner);\n }\n\n /**\n * @notice Changes the threshold of the Barz to `_threshold`.\n * @dev This can only be done via a Self call.\n * @param _threshold New threshold\n */\n function changeThreshold(uint256 _threshold) public {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (_threshold > ms.ownerCount || _threshold == 0)\n revert MultiSigFacet__InvalidThreshold();\n\n ms.threshold = _threshold;\n emit ThresholdChanged(_threshold);\n }\n\n /**\n * @notice Checks if the given address is owner\n * @param _owner Address to be checked if it's owner\n * @return isOwner_ Bool value showing if it's owner address\n */\n function isOwner(address _owner) public view returns (bool isOwner_) {\n isOwner_ = (_owner != SENTINEL_OWNERS &&\n LibMultiSigStorage.multisigStorage().owners[_owner] != address(0));\n }\n\n /**\n * @notice Returns the threshold of Barz\n * @return threshold Threshold of the Barz account\n */\n function getThreshold() public view returns (uint256 threshold) {\n threshold = LibMultiSigStorage.multisigStorage().threshold;\n }\n\n /**\n * @notice Returns the list of owner addresses\n * @return owners List of owners\n */\n function getOwners() public view returns (address[] memory owners) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n owners = new address[](ms.ownerCount);\n\n uint256 index;\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n while (currentOwner != SENTINEL_OWNERS) {\n owners[index] = currentOwner;\n currentOwner = ms.owners[currentOwner];\n index++;\n }\n }\n\n /**\n * @notice Returns the previous owner in the linked list\n * @param _owner Address of owner\n * @return prevOwner Address of previous owner\n */\n function getPrevOwner(\n address _owner\n ) public view returns (address prevOwner) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n if (currentOwner == _owner) return SENTINEL_OWNERS;\n while (currentOwner != SENTINEL_OWNERS) {\n if (ms.owners[currentOwner] == _owner) return currentOwner;\n\n currentOwner = ms.owners[currentOwner];\n }\n return address(0);\n }\n\n /**\n * @notice Returns of the owner is approved by given owner address\n * @param _owner Address of owner\n * @param _hash Hash of UserOperation\n * @return isApproved Bool value showing if the hash is approved by owner\n */\n function isApprovedHash(\n address _owner,\n bytes32 _hash\n ) public view returns (bool isApproved) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n isApproved = (ms.approvedHashes[ms.counter][_owner][_hash] == 1);\n }\n}\n" + }, + "contracts/facets/verification/secp256k1/Secp256k1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {UserOperation} from \"../../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibAppStorage} from \"../../../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, Secp256k1VerificationStorage} from \"../../../libraries/LibFacetStorage.sol\";\nimport {LibLoupe} from \"../../../libraries/LibLoupe.sol\";\nimport {IERC1271} from \"../../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../../interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Secp256k1 verification facet\n * @dev Default Ethereum's elliptic curve\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract Secp256k1VerificationFacet is IVerificationFacet, IERC1271 {\n using ECDSA for bytes32;\n error Secp256k1VerificationFacet__InvalidSignerLength();\n address public immutable self;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in K1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\n * @param _publicKey Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _publicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n if (!isValidKeyType(_publicKey))\n revert Secp256k1VerificationFacet__InvalidSignerLength();\n\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(uint160(uint256(keccak256(_publicKey[1:]))));\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_publicKey);\n }\n\n /**\n * @notice Uninitialize signer in K1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\n * signer public key.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n validationData = validateSignature(\n userOp,\n userOpHash,\n k1Storage.signer\n );\n }\n\n /**\n * @notice Validates if the signature of UserOperation is signed by the given signer\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @param signer Address of signer who signed the contract, to be validated\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n address signer\n ) public pure returns (uint256 isValid) {\n bytes32 hash = userOpHash.toEthSignedMessageHash();\n isValid = (signer != hash.recover(userOp.signature)) ? 1 : 0;\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n ownerSignatureValidatorSelector = this.validateOwnerSignature.selector;\n // NOTE: The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory signer) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n signer = abi.encodePacked(k1Storage.signer);\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key length should be 65 in an uncompressed public key format\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (_hash.recover(_signature) ==\n LibFacetStorage.k1Storage().signer)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/Secp256r1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {UserOperation} from \"../../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibAppStorage} from \"../../../libraries/LibAppStorage.sol\";\nimport {LibLoupe} from \"../../../libraries/LibLoupe.sol\";\nimport {LibFacetStorage, Secp256r1VerificationStorage} from \"../../../libraries/LibFacetStorage.sol\";\nimport {Base64} from \"./utils/Base64.sol\";\nimport {LibSecp256r1} from \"./utils/LibSecp256r1.sol\";\nimport {IERC1271} from \"../../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../../interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Secp256r1 verification facet\n * @dev Primarily used to verify user ops signed with passkeys\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract Secp256r1VerificationFacet is IVerificationFacet, IERC1271 {\n error Secp256r1VerificationFacet__InvalidSignerLength();\n address public immutable self;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in R1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\n * @param _publicKey Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _publicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n\n if (!isValidKeyType(_publicKey))\n revert Secp256r1VerificationFacet__InvalidSignerLength();\n\n bytes memory publicKeyCoordinates = _publicKey[1:];\n uint256[2] memory q;\n assembly {\n // Copy the bytes from the input data into the uint256 array\n mstore(q, mload(add(publicKeyCoordinates, 32)))\n mstore(add(q, 32), mload(add(publicKeyCoordinates, 64)))\n }\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n r1Storage.q = q;\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_publicKey);\n }\n\n /**\n * @notice Uninitialize signer in R1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n r1Storage.q = [0, 0];\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\n * signer public key.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n validationData = validateSignature(userOp, userOpHash, r1Storage.q);\n }\n\n /**\n * @notice Validates if the signature of UserOperation is signed by the given signer\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @param q Public Key of signer who signed the contract, to be validated\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256[2] memory q\n ) public view returns (uint256 isValid) {\n isValid = (_validateSignature(q, userOpHash, userOp.signature)) ? 0 : 1;\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n return this.validateOwnerSignature.selector; // validateOwnerSignature(UserOperation calldata userOp,bytes32 userOpHash)\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory signer) {\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n signer = abi.encodePacked(r1Storage.q);\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key should in an uncompressed public key format\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = _validateSignature(\n LibFacetStorage.r1Storage().q,\n _hash,\n _signature\n )\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n\n function _validateSignature(\n uint256[2] memory q,\n bytes32 _hash,\n bytes memory _signature\n ) internal view returns (bool) {\n (\n uint256 rValue,\n uint256 sValue,\n bytes memory authenticatorData,\n string memory clientDataJSONPre,\n string memory clientDataJSONPost\n ) = abi.decode(_signature, (uint256, uint256, bytes, string, string));\n bytes32 clientHash;\n {\n string memory opHashBase64 = Base64.encode(bytes.concat(_hash));\n string memory clientDataJSON = string.concat(\n clientDataJSONPre,\n opHashBase64,\n clientDataJSONPost\n );\n clientHash = sha256(bytes(clientDataJSON));\n }\n bytes32 sigHash = sha256(bytes.concat(authenticatorData, clientHash));\n return LibSecp256r1.Verify(q, rValue, sValue, uint256(sigHash));\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/utils/Base64.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @dev Provides a set of functions to operate with Base64 strings.\n * modified for base64url https://datatracker.ietf.org/doc/html/rfc4648#section-5\n * _Available since v4.5._\n */\nlibrary Base64 {\n /**\n * @dev Base64 Encoding/Decoding Table\n */\n string internal constant _TABLE =\n \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_\";\n\n /**\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\n */\n function encode(bytes memory data) internal pure returns (string memory) {\n /**\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\n */\n if (data.length == 0) return \"\";\n\n // Loads the table into memory\n string memory table = _TABLE;\n\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\n // and split into 4 numbers of 6 bits.\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\n // - `data.length + 2` -> Round up\n // - `/ 3` -> Number of 3-bytes chunks\n // - `4 *` -> 4 characters for each chunk\n uint256 newlength = (data.length * 8) / 6;\n if (data.length % 6 > 0) {\n newlength++;\n }\n string memory result = new string(newlength);\n\n /// @solidity memory-safe-assembly\n assembly {\n // Prepare the lookup table (skip the first \"length\" byte)\n let tablePtr := add(table, 1)\n\n // Prepare result pointer, jump over length\n let resultPtr := add(result, 32)\n\n // Run over the input, 3 bytes at a time\n for {\n let dataPtr := data\n let endPtr := add(data, mload(data))\n } lt(dataPtr, endPtr) {\n\n } {\n // Advance 3 bytes\n dataPtr := add(dataPtr, 3)\n let input := mload(dataPtr)\n\n // To write each character, shift the 3 bytes (18 bits) chunk\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\n // and apply logical AND with 0x3F which is the number of\n // the previous character in the ASCII table prior to the Base64 Table\n // The result is then added to the table to get the character to write,\n // and finally write it in the result pointer but with a left shift\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(18, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(12, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(6, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n }\n }\n\n return result;\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/utils/LibSecp256r1.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n// Heavily inspired from\n// https://github.com/maxrobot/elliptic-solidity/blob/master/contracts/Secp256r1.sol\n// https://github.com/tdrerup/elliptic-curve-solidity/blob/master/contracts/curves/EllipticCurve.sol\n// modified to use precompile 0x05 modexp\n// and modified jacobian double\n// optimisations to avoid to an from from affine and jacobian coordinates\n\n// Additional Elliptic curve Public key / Signature validation added by\n// David Yonjun Kim (@Powerstream3604)\n\nstruct JPoint {\n uint256 x;\n uint256 y;\n uint256 z;\n}\n\nlibrary LibSecp256r1 {\n uint256 constant gx =\n 0x6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296;\n uint256 constant gy =\n 0x4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5;\n uint256 public constant pp =\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF;\n\n uint256 public constant nn =\n 0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551;\n uint256 constant a =\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC;\n uint256 constant b =\n 0x5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B;\n uint256 constant MOST_SIGNIFICANT =\n 0xc000000000000000000000000000000000000000000000000000000000000000;\n\n /*\n * Verify\n * @description - verifies that a public key has signed a given message\n * @param Q - public key coordinates X & Y\n * @param R - signature half R\n * @param S - signature half S\n * @param input - hashed message\n */\n function Verify(\n uint256[2] memory q,\n uint r,\n uint s,\n uint e\n ) internal view returns (bool) {\n if (q[0] > pp - 1 || q[1] > pp - 1) {\n return false;\n }\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\n return false;\n }\n if (\n mulmod(q[1], q[1], pp) !=\n addmod(\n addmod(\n mulmod(q[0], mulmod(q[0], q[0], pp), pp),\n mulmod(a, q[0], pp),\n pp\n ),\n b,\n pp\n )\n ) {\n return false;\n }\n\n JPoint[16] memory points = _preComputeJacobianPoints(q);\n return VerifyWithPrecompute(points, r, s, e);\n }\n\n function VerifyWithPrecompute(\n JPoint[16] memory points,\n uint r,\n uint s,\n uint e\n ) internal view returns (bool) {\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\n return false;\n }\n\n uint w = _primemod(s, nn);\n\n uint u1 = mulmod(e, w, nn);\n uint u2 = mulmod(r, w, nn);\n\n uint x;\n uint y;\n\n (x, y) = ShamirMultJacobian(points, u1, u2);\n return (x == r);\n }\n\n /*\n * Strauss Shamir trick for EC multiplication\n * https://stackoverflow.com/questions/50993471/ec-scalar-multiplication-with-strauss-shamir-method\n * we optimise on this a bit to do with 2 bits at a time rather than a single bit\n * the individual points for a single pass are precomputed\n * overall this reduces the number of additions while keeping the same number of doublings\n */\n function ShamirMultJacobian(\n JPoint[16] memory points,\n uint u1,\n uint u2\n ) internal view returns (uint, uint) {\n uint x = 0;\n uint y = 0;\n uint z = 0;\n uint bits = 128;\n uint index = 0;\n\n while (bits > 0) {\n if (z > 0) {\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\n }\n index =\n ((u1 & MOST_SIGNIFICANT) >> 252) |\n ((u2 & MOST_SIGNIFICANT) >> 254);\n if (index > 0) {\n (x, y, z) = _jAdd(\n x,\n y,\n z,\n points[index].x,\n points[index].y,\n points[index].z\n );\n }\n u1 <<= 2;\n u2 <<= 2;\n bits--;\n }\n (x, y) = _affineFromJacobian(x, y, z);\n return (x, y);\n }\n\n function _preComputeJacobianPoints(\n uint256[2] memory q\n ) internal pure returns (JPoint[16] memory points) {\n points[0] = JPoint(0, 0, 0);\n points[1] = JPoint(q[0], q[1], 1); // u2\n points[2] = _jPointDouble(points[1]);\n points[3] = _jPointAdd(points[1], points[2]);\n\n points[4] = JPoint(gx, gy, 1); // u1Points[1]\n points[5] = _jPointAdd(points[4], points[1]);\n points[6] = _jPointAdd(points[4], points[2]);\n points[7] = _jPointAdd(points[4], points[3]);\n\n points[8] = _jPointDouble(points[4]); // u1Points[2]\n points[9] = _jPointAdd(points[8], points[1]);\n points[10] = _jPointAdd(points[8], points[2]);\n points[11] = _jPointAdd(points[8], points[3]);\n\n points[12] = _jPointAdd(points[4], points[8]); // u1Points[3]\n points[13] = _jPointAdd(points[12], points[1]);\n points[14] = _jPointAdd(points[12], points[2]);\n points[15] = _jPointAdd(points[12], points[3]);\n }\n\n function _jPointAdd(\n JPoint memory p1,\n JPoint memory p2\n ) internal pure returns (JPoint memory) {\n uint x;\n uint y;\n uint z;\n (x, y, z) = _jAdd(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z);\n return JPoint(x, y, z);\n }\n\n function _jPointDouble(\n JPoint memory p\n ) internal pure returns (JPoint memory) {\n uint x;\n uint y;\n uint z;\n (x, y, z) = _modifiedJacobianDouble(p.x, p.y, p.z);\n return JPoint(x, y, z);\n }\n\n /* _affineFromJacobian\n * @desription returns affine coordinates from a jacobian input follows\n * golang elliptic/crypto library\n */\n function _affineFromJacobian(\n uint x,\n uint y,\n uint z\n ) internal view returns (uint ax, uint ay) {\n if (z == 0) {\n return (0, 0);\n }\n\n uint zinv = _primemod(z, pp);\n uint zinvsq = mulmod(zinv, zinv, pp);\n\n ax = mulmod(x, zinvsq, pp);\n ay = mulmod(y, mulmod(zinvsq, zinv, pp), pp);\n }\n\n /*\n * _jAdd\n * @description performs Jacobian addition as defined below:\n * http://www.hyperelliptic.org/EFD/g1p/data/shortw/jacobian/addition/add-2007-bl\n */\n function _jAdd(\n uint p1,\n uint p2,\n uint p3,\n uint q1,\n uint q2,\n uint q3\n ) internal pure returns (uint r1, uint r2, uint r3) {\n if (p3 == 0) {\n r1 = q1;\n r2 = q2;\n r3 = q3;\n\n return (r1, r2, r3);\n } else if (q3 == 0) {\n r1 = p1;\n r2 = p2;\n r3 = p3;\n\n return (r1, r2, r3);\n }\n\n assembly {\n let\n pd\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\n let z1z1 := mulmod(p3, p3, pd) // Z1Z1 = Z1^2\n let z2z2 := mulmod(q3, q3, pd) // Z2Z2 = Z2^2\n\n let u1 := mulmod(p1, z2z2, pd) // U1 = X1*Z2Z2\n let u2 := mulmod(q1, z1z1, pd) // U2 = X2*Z1Z1\n\n let s1 := mulmod(p2, mulmod(z2z2, q3, pd), pd) // S1 = Y1*Z2*Z2Z2\n let s2 := mulmod(q2, mulmod(z1z1, p3, pd), pd) // S2 = Y2*Z1*Z1Z1\n\n let p3q3 := addmod(p3, q3, pd)\n\n if lt(u2, u1) {\n u2 := add(pd, u2) // u2 = u2+pd\n }\n let h := sub(u2, u1) // H = U2-U1\n\n let i := mulmod(0x02, h, pd)\n i := mulmod(i, i, pd) // I = (2*H)^2\n\n let j := mulmod(h, i, pd) // J = H*I\n if lt(s2, s1) {\n s2 := add(pd, s2) // u2 = u2+pd\n }\n let rr := mulmod(0x02, sub(s2, s1), pd) // r = 2*(S2-S1)\n r1 := mulmod(rr, rr, pd) // X3 = R^2\n\n let v := mulmod(u1, i, pd) // V = U1*I\n let j2v := addmod(j, mulmod(0x02, v, pd), pd)\n if lt(r1, j2v) {\n r1 := add(pd, r1) // X3 = X3+pd\n }\n r1 := sub(r1, j2v)\n\n // Y3 = r*(V-X3)-2*S1*J\n let s12j := mulmod(mulmod(0x02, s1, pd), j, pd)\n\n if lt(v, r1) {\n v := add(pd, v)\n }\n r2 := mulmod(rr, sub(v, r1), pd)\n\n if lt(r2, s12j) {\n r2 := add(pd, r2)\n }\n r2 := sub(r2, s12j)\n\n // Z3 = ((Z1+Z2)^2-Z1Z1-Z2Z2)*H\n z1z1 := addmod(z1z1, z2z2, pd)\n j2v := mulmod(p3q3, p3q3, pd)\n if lt(j2v, z1z1) {\n j2v := add(pd, j2v)\n }\n r3 := mulmod(sub(j2v, z1z1), h, pd)\n }\n return (r1, r2, r3);\n }\n\n // Point doubling on the modified jacobian coordinates\n // http://point-at-infinity.org/ecc/Prime_Curve_Modified_Jacobian_Coordinates.html\n function _modifiedJacobianDouble(\n uint x,\n uint y,\n uint z\n ) internal pure returns (uint x3, uint y3, uint z3) {\n if (y == 0) return (0, 0, 0);\n assembly {\n let\n pd\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\n let z2 := mulmod(z, z, pd)\n let az4 := mulmod(\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC,\n mulmod(z2, z2, pd),\n pd\n )\n let y2 := mulmod(y, y, pd)\n let s := mulmod(0x04, mulmod(x, y2, pd), pd)\n let u := mulmod(0x08, mulmod(y2, y2, pd), pd)\n let m := addmod(mulmod(0x03, mulmod(x, x, pd), pd), az4, pd)\n let twos := mulmod(0x02, s, pd)\n let m2 := mulmod(m, m, pd)\n if lt(m2, twos) {\n m2 := add(pd, m2)\n }\n x3 := sub(m2, twos)\n if lt(s, x3) {\n s := add(pd, s)\n }\n y3 := mulmod(m, sub(s, x3), pd)\n if lt(y3, u) {\n y3 := add(pd, y3)\n }\n y3 := sub(y3, u)\n z3 := mulmod(0x02, mulmod(y, z, pd), pd)\n }\n }\n\n // Fermats little theorem https://en.wikipedia.org/wiki/Fermat%27s_little_theorem\n // a^(p-1) = 1 mod p\n // a^(-1) ≅ a^(p-2) (mod p)\n // we then use the precompile bigModExp to compute a^(-1)\n function _primemod(uint value, uint p) internal view returns (uint ret) {\n ret = modexp(value, p - 2, p);\n return ret;\n }\n\n // Wrapper for built-in BigNumber_modexp (contract 0x5) as described here. https://github.com/ethereum/EIPs/pull/198\n function modexp(\n uint _base,\n uint _exp,\n uint _mod\n ) internal view returns (uint ret) {\n // bigModExp(_base, _exp, _mod);\n assembly {\n if gt(_base, _mod) {\n _base := mod(_base, _mod)\n }\n // Free memory pointer is always stored at 0x40\n let freemem := mload(0x40)\n\n mstore(freemem, 0x20)\n mstore(add(freemem, 0x20), 0x20)\n mstore(add(freemem, 0x40), 0x20)\n\n mstore(add(freemem, 0x60), _base)\n mstore(add(freemem, 0x80), _exp)\n mstore(add(freemem, 0xa0), _mod)\n\n let success := staticcall(14000, 0x5, freemem, 0xc0, freemem, 0x20)\n switch success\n case 0 {\n revert(0x0, 0x0)\n }\n default {\n ret := mload(freemem)\n }\n }\n }\n}\n" + }, + "contracts/infrastructure/interfaces/IFacetRegistry.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Registry Interface\n * @dev Interface for Facet Registry contract to keep track of facets & function selectors addable to user wallets\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IFacetRegistry {\n struct FacetRegistryConfig {\n bytes4[] selectors;\n mapping(bytes4 => FacetInfo) info;\n }\n struct FacetInfo {\n bool exists;\n uint128 index;\n }\n\n event FacetFunctionSelectorsRegistered(\n address facet,\n bytes4[] facetSelectors\n );\n event FacetFunctionSelectorsRemoved(address facet, bytes4[] facetSelectors);\n\n error FacetRegistry__FacetSelectorAlreadyRegistered();\n error FacetRegistry__UnregisteredFacetSelector();\n\n function registerFacetFunctionSelectors(\n address facet,\n bytes4[] calldata facetSelectors\n ) external;\n\n function removeFacetFunctionSelectors(\n address facet,\n bytes4[] calldata facetSelectors\n ) external;\n\n function areFacetFunctionSelectorsRegistered(\n address facet,\n bytes4[] calldata facetSelectors\n ) external view returns (bool);\n\n function isFacetFunctionSelectorRegistered(\n address facet,\n bytes4 facetSelector\n ) external view returns (bool);\n\n function getFacetFunctionSelectors(\n address facet\n ) external view returns (bytes4[] memory);\n}\n" + }, + "contracts/infrastructure/interfaces/ISecurityManager.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Registry Interface\n * @dev Infrastructure contract to manage security parameters of users\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface ISecurityManager {\n error SecurityManager__OutOfBoundary();\n error SecurityManager__CallerNotWallet();\n error SecurityManager__AlreadyIntialized();\n\n function initializeAdditionSecurityPeriod(\n uint128 defaultAdditionSecurityPeriod,\n uint128 minAdditionSecurityPeriod,\n uint128 maxAdditionSecurityPeriod\n ) external;\n\n function initializeRemovalSecurityPeriod(\n uint128 defaultRemovalSecurityPeriod,\n uint128 minRemovalSecurityPeriod,\n uint128 maxRemovalSecurityPeriod\n ) external;\n\n function initializeApprovalValidationPeriod(\n uint128 defaultApprovalValidationPeriod,\n uint128 minApprovalValidationPeriod,\n uint128 maxApprovalValidationPeriod\n ) external;\n\n function initializeMigrationPeriod(\n uint128 defaultMigrationPeriod,\n uint128 minMigrationPeriod,\n uint128 maxMigrationPeriod\n ) external;\n\n function initializeLockPeriod(\n uint128 defaultLockPeriod,\n uint128 minLockPeriod,\n uint128 maxLockPeriod\n ) external;\n\n function initializeRecoveryPeriod(\n uint128 defaultRecoveryPeriod,\n uint128 minRecoveryPeriod,\n uint128 maxRecoveryPeriod\n ) external;\n\n function initializeSecurityWindow(\n uint128 defaultSecurityWindow,\n uint128 minSecurityWindow,\n uint128 maxSecurityWindow\n ) external;\n\n function setAdditionSecurityPeriod(\n address wallet,\n uint128 additionSecurityPeriod\n ) external;\n\n function setRemovalSecurityPeriod(\n address wallet,\n uint128 removalSecurityPeriod\n ) external;\n\n function setSecurityWindow(address wallet, uint128 securityWindow) external;\n\n function setRecoveryPeriod(address wallet, uint128 recoveryPeriod) external;\n\n function setLockPeriod(address wallet, uint128 lockPeriod) external;\n\n function setApprovalValidationPeriod(\n address wallet,\n uint128 approvalValidationPeriod\n ) external;\n\n function setMigrationPeriod(\n address wallet,\n uint128 migrationPeriod\n ) external;\n\n function additionSecurityPeriodOf(\n address wallet\n ) external view returns (uint128);\n\n function removalSecurityPeriodOf(\n address wallet\n ) external view returns (uint128);\n\n function securityWindowOf(address wallet) external view returns (uint128);\n\n function recoveryPeriodOf(address wallet) external view returns (uint128);\n\n function lockPeriodOf(address wallet) external view returns (uint128);\n\n function migrationPeriodOf(address wallet) external view returns (uint128);\n\n function approvalValidationPeriodOf(\n address wallet\n ) external view returns (uint128);\n}\n" + }, + "contracts/interfaces/ERC/IERC1271.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\ninterface IERC1271 {\n function isValidSignature(\n bytes32 hash,\n bytes memory signature\n ) external view returns (bytes4);\n}\n" + }, + "contracts/interfaces/ERC/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\ninterface IERC165 {\n /// @notice Query if a contract implements an interface\n /// @param interfaceId The interface identifier, as specified in ERC-165\n /// @dev Interface identification is specified in ERC-165. This function\n /// uses less than 30,000 gas.\n /// @return `true` if the contract implements `interfaceID` and\n /// `interfaceID` is not 0xffffffff, `false` otherwise\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/IERC677Receiver.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\ninterface IERC677Receiver {\n function onTokenTransfer(\n address sender,\n uint value,\n bytes calldata data\n ) external pure returns (bool);\n}\n" + }, + "contracts/libraries/LibAppStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SafeCast} from \"@openzeppelin/contracts/utils/math/SafeCast.sol\";\nimport {IEntryPoint} from \"../aa-4337/interfaces/IEntryPoint.sol\";\nimport {IFacetRegistry} from \"../infrastructure/interfaces/IFacetRegistry.sol\";\n\n/*\n * @title App Storage\n * @dev App storage for Barz contract to prevent storage collision\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\n\nstruct Lock {\n uint64 release;\n bytes4 locker;\n}\n\nstruct InitializersStorage {\n // NOTE: initialized is a variable to make sure the initialization is only done once.\n uint8 signerInitialized;\n uint8 accountInitialized;\n uint8 restrictionsInitialized;\n}\n\nstruct AppStorage {\n mapping(uint256 => InitializersStorage) initStorage;\n uint8 signerMigration;\n bytes4 validateOwnerSignatureSelector;\n IEntryPoint entryPoint;\n IFacetRegistry facetRegistry;\n mapping(uint256 => Lock) locks;\n}\n\nlibrary LibAppStorage {\n error LibAppStorage__AccountAlreadyUninitialized();\n error LibAppStorage__AccountMustBeUninitialized();\n error LibAppStorage__SignerAlreadyUninitialized();\n error LibAppStorage__SignerMustBeUninitialized();\n\n function appStorage() internal pure returns (AppStorage storage ds) {\n assembly {\n ds.slot := 0\n }\n }\n\n function setSignerUninitialized() internal {\n AppStorage storage s = appStorage();\n if (1 != s.initStorage[0].signerInitialized) {\n revert LibAppStorage__SignerAlreadyUninitialized();\n }\n s.initStorage[0].signerInitialized = 0;\n }\n\n function getValidateOwnerSignatureSelector()\n internal\n view\n returns (bytes4 selector)\n {\n selector = appStorage().validateOwnerSignatureSelector;\n }\n\n function setValidateOwnerSignatureSelector(\n bytes4 _validateOwnerSignatureSelector\n ) internal {\n appStorage()\n .validateOwnerSignatureSelector = _validateOwnerSignatureSelector;\n }\n\n function enforceSignerInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].signerInitialized) {\n revert LibAppStorage__SignerMustBeUninitialized();\n }\n s.initStorage[0].signerInitialized = 1;\n }\n\n function enforceAccountInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].accountInitialized) {\n revert LibAppStorage__AccountMustBeUninitialized();\n }\n s.initStorage[0].accountInitialized = 1;\n }\n\n function initiateSignerMigration() internal {\n appStorage().signerMigration = 1;\n }\n\n function enforceSignerMigration() internal view {\n if (1 != appStorage().signerMigration) {\n revert LibAppStorage__AccountMustBeUninitialized();\n }\n }\n\n function finalizeSignerMigration() internal {\n appStorage().signerMigration = 0;\n }\n\n function setLock(uint256 _releaseAfter, bytes4 _locker) internal {\n appStorage().locks[0] = Lock(SafeCast.toUint64(_releaseAfter), _locker);\n }\n\n function enforceRestrictionsInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].restrictionsInitialized)\n revert LibAppStorage__SignerMustBeUninitialized();\n s.initStorage[0].restrictionsInitialized = 1;\n }\n\n function setRestrictionsUninitialized() internal {\n AppStorage storage s = appStorage();\n if (1 != s.initStorage[0].restrictionsInitialized)\n revert LibAppStorage__AccountAlreadyUninitialized();\n s.initStorage[0].restrictionsInitialized = 0;\n }\n}\n\ncontract BarzStorage {\n AppStorage internal s;\n modifier onlyWhenUnlocked() {\n require(\n uint64(block.timestamp) >= s.locks[0].release,\n \"Account Locked\"\n );\n _;\n }\n modifier onlyWhenLocked() {\n require(\n uint64(block.timestamp) < s.locks[0].release,\n \"Account Unlocked\"\n );\n _;\n }\n}\n" + }, + "contracts/libraries/LibDiamond.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\n\nerror InitializationFunctionReverted(\n address _initializationContractAddress,\n bytes _calldata\n);\n\nlibrary LibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION =\n keccak256(\"trustwallet.barz.diamond.storage\");\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\n bytes4(keccak256(\"verifyRestrictions(address,address,uint256,bytes)\"));\n struct DiamondStorage {\n // maps function selectors to the facets that execute the functions.\n // and maps the selectors to their position in the selectorSlots array.\n // func selector => address facet, selector position\n mapping(bytes4 => bytes32) facets;\n // array of slots of function selectors.\n // each slot holds 8 function selectors.\n mapping(uint256 => bytes32) selectorSlots;\n // The number of function selectors in selectorSlots\n uint16 selectorCount;\n // Used to query if a contract implements an interface.\n // Used to implement ERC-165.\n mapping(bytes4 => bool) supportedInterfaces;\n // Default Fallback Handler of the barz.\n IDiamondLoupe defaultFallbackHandler;\n }\n\n function diamondStorage()\n internal\n pure\n returns (DiamondStorage storage ds)\n {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n function enforceIsSelf() internal view {\n require(msg.sender == address(this), \"LibDiamond: Caller not self\");\n }\n\n event DiamondCut(\n IDiamondCut.FacetCut[] _diamondCut,\n address _init,\n bytes _calldata\n );\n\n bytes32 constant CLEAR_ADDRESS_MASK =\n bytes32(uint256(0xffffffffffffffffffffffff));\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\n\n // Internal function version of diamondCut\n // This code is almost the same as the external diamondCut,\n // except it is using 'Facet[] memory _diamondCut' instead of\n // 'Facet[] calldata _diamondCut'.\n // The code is duplicated to prevent copying calldata to memory which\n // causes an error for a two dimensional array.\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n DiamondStorage storage ds = diamondStorage();\n uint256 originalSelectorCount = ds.selectorCount;\n uint256 selectorCount = originalSelectorCount;\n bytes32 selectorSlot;\n // Check if last selector slot is not full\n // \"selectorCount & 7\" is a gas efficient modulo by eight \"selectorCount % 8\"\n if (selectorCount & 7 > 0) {\n // get last selectorSlot\n // \"selectorSlot >> 3\" is a gas efficient division by 8 \"selectorSlot / 8\"\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\n }\n // loop through diamond cut\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\n selectorCount,\n selectorSlot,\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].action,\n _diamondCut[facetIndex].functionSelectors\n );\n\n unchecked {\n facetIndex++;\n }\n }\n if (selectorCount != originalSelectorCount) {\n ds.selectorCount = uint16(selectorCount);\n }\n // If last selector slot is not full\n // \"selectorCount & 7\" is a gas efficient modulo by eight \"selectorCount % 8\"\n if (selectorCount & 7 > 0) {\n // \"selectorSlot >> 3\" is a gas efficient division by 8 \"selectorSlot / 8\"\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addReplaceRemoveFacetSelectors(\n uint256 _selectorCount,\n bytes32 _selectorSlot,\n address _newFacetAddress,\n IDiamondCut.FacetCutAction _action,\n bytes4[] memory _selectors\n ) internal returns (uint256, bytes32) {\n DiamondStorage storage ds = diamondStorage();\n require(\n _selectors.length > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n if (_action == IDiamondCut.FacetCutAction.Add) {\n enforceHasContractCode(\n _newFacetAddress,\n \"LibDiamondCut: Add facet has no code\"\n );\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n require(\n address(bytes20(oldFacet)) == address(0),\n \"LibDiamondCut: Can't add function that already exists\"\n );\n // add facet for selector\n ds.facets[selector] =\n bytes20(_newFacetAddress) |\n bytes32(_selectorCount);\n // \"_selectorCount & 7\" is a gas efficient modulo by eight \"_selectorCount % 8\"\n // \" << 5 is the same as multiplying by 32 ( * 32)\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\n // clear selector position in slot and add selector\n _selectorSlot =\n (_selectorSlot &\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\n (bytes32(selector) >> selectorInSlotPosition);\n // if slot is full then write it to storage\n if (selectorInSlotPosition == 224) {\n // \"_selectorSlot >> 3\" is a gas efficient division by 8 \"_selectorSlot / 8\"\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\n _selectorSlot = 0;\n }\n _selectorCount++;\n\n unchecked {\n selectorIndex++;\n }\n }\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\n enforceHasContractCode(\n _newFacetAddress,\n \"LibDiamondCut: Replace facet has no code\"\n );\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n address oldFacetAddress = address(bytes20(oldFacet));\n // only useful if immutable functions exist\n require(\n oldFacetAddress != address(this),\n \"LibDiamondCut: Can't replace immutable function\"\n );\n require(\n oldFacetAddress != _newFacetAddress,\n \"LibDiamondCut: Can't replace function with same function\"\n );\n require(\n oldFacetAddress != address(0),\n \"LibDiamondCut: Can't replace function that doesn't exist\"\n );\n // replace old facet address\n ds.facets[selector] =\n (oldFacet & CLEAR_ADDRESS_MASK) |\n bytes20(_newFacetAddress);\n\n unchecked {\n selectorIndex++;\n }\n }\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\n require(\n _newFacetAddress == address(0),\n \"LibDiamondCut: Remove facet address must be address(0)\"\n );\n // \"_selectorCount >> 3\" is a gas efficient division by 8 \"_selectorCount / 8\"\n uint256 selectorSlotCount = _selectorCount >> 3;\n // \"_selectorCount & 7\" is a gas efficient modulo by eight \"_selectorCount % 8\"\n uint256 selectorInSlotIndex = _selectorCount & 7;\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n if (_selectorSlot == 0) {\n // get last selectorSlot\n selectorSlotCount--;\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\n selectorInSlotIndex = 7;\n } else {\n selectorInSlotIndex--;\n }\n bytes4 lastSelector;\n uint256 oldSelectorsSlotCount;\n uint256 oldSelectorInSlotPosition;\n // adding a block here prevents stack too deep error\n {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n require(\n address(bytes20(oldFacet)) != address(0),\n \"LibDiamondCut: Can't remove function that doesn't exist\"\n );\n // only useful if immutable functions exist\n require(\n address(bytes20(oldFacet)) != address(this),\n \"LibDiamondCut: Can't remove immutable function\"\n );\n // replace selector with last selector in ds.facets\n // gets the last selector\n // \" << 5 is the same as multiplying by 32 ( * 32)\n lastSelector = bytes4(\n _selectorSlot << (selectorInSlotIndex << 5)\n );\n if (lastSelector != selector) {\n // update last selector slot position info\n ds.facets[lastSelector] =\n (oldFacet & CLEAR_ADDRESS_MASK) |\n bytes20(ds.facets[lastSelector]);\n }\n delete ds.facets[selector];\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\n // \"oldSelectorCount >> 3\" is a gas efficient division by 8 \"oldSelectorCount / 8\"\n oldSelectorsSlotCount = oldSelectorCount >> 3;\n // \"oldSelectorCount & 7\" is a gas efficient modulo by eight \"oldSelectorCount % 8\"\n // \" << 5 is the same as multiplying by 32 ( * 32)\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\n }\n if (oldSelectorsSlotCount != selectorSlotCount) {\n bytes32 oldSelectorSlot = ds.selectorSlots[\n oldSelectorsSlotCount\n ];\n // clears the selector we are deleting and puts the last selector in its place.\n oldSelectorSlot =\n (oldSelectorSlot &\n ~(CLEAR_SELECTOR_MASK >>\n oldSelectorInSlotPosition)) |\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\n // update storage with the modified slot\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\n } else {\n // clears the selector we are deleting and puts the last selector in its place.\n _selectorSlot =\n (_selectorSlot &\n ~(CLEAR_SELECTOR_MASK >>\n oldSelectorInSlotPosition)) |\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\n }\n if (selectorInSlotIndex == 0) {\n delete ds.selectorSlots[selectorSlotCount];\n _selectorSlot = 0;\n }\n\n unchecked {\n selectorIndex++;\n }\n }\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\n } else {\n revert(\"LibDiamondCut: Incorrect FacetCutAction\");\n }\n return (_selectorCount, _selectorSlot);\n }\n\n function initializeDiamondCut(\n address _init,\n bytes memory _calldata\n ) internal {\n if (_init == address(0)) {\n return;\n }\n enforceHasContractCode(\n _init,\n \"LibDiamondCut: _init address has no code\"\n );\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length > 0) {\n // bubble up error\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(error)\n revert(add(32, error), returndata_size)\n }\n } else {\n revert InitializationFunctionReverted(_init, _calldata);\n }\n }\n }\n\n function enforceHasContractCode(\n address _contract,\n string memory _errorMessage\n ) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize > 0, _errorMessage);\n }\n\n function restrictionsFacet() internal view returns (address facetAddress_) {\n facetAddress_ = address(\n bytes20(\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\n )\n );\n }\n}\n" + }, + "contracts/libraries/LibFacetStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Storage\n * @dev Storage contract to store each facets variables with diamond storage\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\n\nstruct Secp256k1VerificationStorage {\n address signer;\n}\n\nstruct Secp256r1VerificationStorage {\n uint256[2] q;\n}\n\nstruct GuardianStorage {\n mapping(bytes32 => uint256) pending;\n mapping(uint8 => StorageConfig) configs;\n}\n\nstruct Info {\n bool exists;\n uint128 index;\n}\n\nstruct StorageConfig {\n address[] addresses;\n mapping(address => Info) info;\n}\n\nstruct RecoveryConfig {\n bytes recoveryPublicKey;\n uint64 executeAfter;\n}\n\nstruct ApprovalConfig {\n bool isApproved;\n uint64 validUntil;\n}\n\nstruct RecoveryApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isNewOwnerApproved;\n}\n\nstruct RecoveryStorage {\n mapping(uint8 => RecoveryConfig) recoveryConfigs;\n mapping(uint8 => RecoveryApprovalConfig) recoveryApprovalConfigs;\n uint128 nonce;\n}\n\nstruct RestrictionsStorage {\n address[] restrictions;\n mapping(address => bool) exists;\n}\n\nstruct SignatureMigrationConfig {\n bytes migrationPublicKey;\n address migrationVerificationFacet;\n bytes4[] migrationSelectors;\n uint64 migrateAfter;\n}\n\nstruct SignatureMigrationApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isMigrationApproved;\n}\n\nstruct SignatureMigrationStorage {\n mapping(uint8 => SignatureMigrationConfig) migrationConfigs;\n mapping(uint8 => SignatureMigrationApprovalConfig) migrationApprovalConfigs;\n uint128 nonce;\n}\n\nstruct DiamondCutApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isDiamondCutApproved;\n}\n\nstruct DiamondCutStorage {\n mapping(uint8 => DiamondCutApprovalConfig) diamondCutApprovalConfigs;\n uint128 nonce;\n}\n\nstruct LockStorage {\n uint128 nonce;\n}\n\nlibrary LibFacetStorage {\n bytes32 constant K1_STORAGE_POSITION =\n keccak256(\n \"v0.trustwallet.diamond.storage.Secp256k1VerificationStorage\"\n );\n bytes32 constant R1_STORAGE_POSITION =\n keccak256(\n \"v0.trustwallet.diamond.storage.Secp256r1VerificationStorage\"\n );\n bytes32 constant GUARDIAN_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.GuardianStorage\");\n bytes32 constant RECOVERY_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.RecoveryStorage\");\n bytes32 constant RESTRICTION_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.RestrictionsStorage\");\n bytes32 constant MIGRATION_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.SignatureMigrationStorage\");\n bytes32 constant DIAMONDCUT_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.DiamondCutStorage\");\n bytes32 constant LOCK_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.LockStorage\");\n\n function k1Storage()\n internal\n pure\n returns (Secp256k1VerificationStorage storage ds)\n {\n bytes32 storagePosition = K1_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function r1Storage()\n internal\n pure\n returns (Secp256r1VerificationStorage storage ds)\n {\n bytes32 storagePosition = R1_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function guardianStorage()\n internal\n pure\n returns (GuardianStorage storage ds)\n {\n bytes32 storagePosition = GUARDIAN_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function recoveryStorage()\n internal\n pure\n returns (RecoveryStorage storage ds)\n {\n bytes32 storagePosition = RECOVERY_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function restrictionsStorage()\n internal\n pure\n returns (RestrictionsStorage storage ds)\n {\n bytes32 storagePosition = RESTRICTION_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function migrationStorage()\n internal\n pure\n returns (SignatureMigrationStorage storage ds)\n {\n bytes32 storagePosition = MIGRATION_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function diamondCutStorage()\n internal\n pure\n returns (DiamondCutStorage storage ds)\n {\n bytes32 storagePosition = DIAMONDCUT_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function lockStorage() internal pure returns (LockStorage storage ds) {\n bytes32 storagePosition = LOCK_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n}\n" + }, + "contracts/libraries/LibGuardian.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibFacetStorage, StorageConfig} from \"./LibFacetStorage.sol\";\n\n/**\n * @title LibGuardian\n * @dev Internal Library to provide utility feature for Guardians stored in Guardian Facet Storage\n * @author David Yongjun Kim (@Powerstream3604)\n */\nlibrary LibGuardian {\n function majorityOfGuardians()\n internal\n view\n returns (uint256 guardianNumber)\n {\n uint256 guardianLength = guardianCount();\n guardianNumber = (guardianLength == 0) ? 0 : guardianLength / 2 + 1;\n }\n\n function isGuardian(address _guardian) internal view returns (bool) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n return config.info[_guardian].exists;\n }\n\n function guardianCount() internal view returns (uint256) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n return config.addresses.length;\n }\n\n function getGuardians() internal view returns (address[] memory) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n address[] memory addresses = new address[](config.addresses.length);\n uint256 addressesLen = config.addresses.length;\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n return addresses;\n }\n}\n" + }, + "contracts/libraries/LibLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {LibDiamond} from \"./LibDiamond.sol\";\n\n/**\n * @title LibLoupe\n * @dev Internal Library to provide utility feature for reading the state of diamond facets\n */\nlibrary LibLoupe {\n /// @notice Gets all facets and their selectors.\n /// @return facets_ Facet\n function facets()\n internal\n view\n returns (IDiamondLoupe.Facet[] memory facets_)\n {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facets_ = new IDiamondLoupe.Facet[](ds.selectorCount);\n uint16[] memory numFacetSelectors = new uint16[](ds.selectorCount);\n uint256 numFacets;\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facetAddress_ = address(bytes20(ds.facets[selector]));\n bool continueLoop;\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n if (facets_[facetIndex].facetAddress == facetAddress_) {\n facets_[facetIndex].functionSelectors[\n numFacetSelectors[facetIndex]\n ] = selector;\n // probably will never have more than 256 functions from one facet contract\n require(numFacetSelectors[facetIndex] < 255);\n numFacetSelectors[facetIndex]++;\n continueLoop = true;\n break;\n }\n }\n if (continueLoop) {\n continue;\n }\n facets_[numFacets].facetAddress = facetAddress_;\n facets_[numFacets].functionSelectors = new bytes4[](\n ds.selectorCount\n );\n facets_[numFacets].functionSelectors[0] = selector;\n numFacetSelectors[numFacets] = 1;\n numFacets++;\n }\n }\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n uint256 numSelectors = numFacetSelectors[facetIndex];\n bytes4[] memory selectors = facets_[facetIndex].functionSelectors;\n // setting the number of selectors\n assembly {\n mstore(selectors, numSelectors)\n }\n }\n // setting the number of facets\n assembly {\n mstore(facets_, numFacets)\n }\n }\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n /// @return _facetFunctionSelectors The selectors associated with a facet address.\n function facetFunctionSelectors(\n address _facet\n ) internal view returns (bytes4[] memory _facetFunctionSelectors) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n uint256 numSelectors;\n _facetFunctionSelectors = new bytes4[](ds.selectorCount);\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facet = address(bytes20(ds.facets[selector]));\n if (_facet == facet) {\n _facetFunctionSelectors[numSelectors] = selector;\n numSelectors++;\n }\n }\n }\n // Set the number of selectors in the array\n assembly {\n mstore(_facetFunctionSelectors, numSelectors)\n }\n }\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses()\n internal\n view\n returns (address[] memory facetAddresses_)\n {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facetAddresses_ = new address[](ds.selectorCount);\n uint256 numFacets;\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facetAddress_ = address(bytes20(ds.facets[selector]));\n bool continueLoop;\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n if (facetAddress_ == facetAddresses_[facetIndex]) {\n continueLoop = true;\n break;\n }\n }\n if (continueLoop) {\n continue;\n }\n facetAddresses_[numFacets] = facetAddress_;\n numFacets++;\n }\n }\n // Set the number of facet addresses in the array\n assembly {\n mstore(facetAddresses_, numFacets)\n }\n }\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(\n bytes4 _functionSelector\n ) internal view returns (address facetAddress_) {\n facetAddress_ = address(\n bytes20(LibDiamond.diamondStorage().facets[_functionSelector])\n );\n }\n}\n" + }, + "contracts/libraries/LibMultiSigStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Multi-sig Storage\n * @dev Storage contract for storing Multi-sig Facet variables in diamond storage pattern\n * @author David Yongjun Kim (@Powerstream3604)\n */\n\nstruct MultiSigStorage {\n mapping(address => address) owners;\n mapping(uint256 => mapping(address => mapping(bytes32 => uint256))) approvedHashes;\n uint256 ownerCount;\n uint256 threshold;\n uint256 counter;\n}\n\nlibrary LibMultiSigStorage {\n function multisigStorage()\n internal\n pure\n returns (MultiSigStorage storage ds)\n {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.MultiSigStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n}\n" + }, + "contracts/libraries/LibUtils.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\n\nlibrary LibUtils {\n // Internal utility functions\n function mergeArrays(\n bytes4[] memory _array1,\n bytes4[] memory _array2\n ) internal pure returns (bytes4[] memory) {\n uint256 length1 = _array1.length;\n uint256 length2 = _array2.length;\n bytes4[] memory mergedArray = new bytes4[](length1 + length2);\n\n for (uint256 i; i < length1; ) {\n mergedArray[i] = _array1[i];\n unchecked {\n ++i;\n }\n }\n\n for (uint256 i; i < length2; ) {\n mergedArray[length1 + i] = _array2[i];\n unchecked {\n ++i;\n }\n }\n\n return mergedArray;\n }\n\n function removeFacetElement(\n IDiamondLoupe.Facet[] memory _facets,\n uint256 _index\n ) internal pure returns (IDiamondLoupe.Facet[] memory) {\n require(_index < _facets.length, \"Invalid index\");\n require(_facets.length != 0, \"Invalid array\");\n\n // Create a new array with a length of `_facets.length - 1`\n IDiamondLoupe.Facet[] memory newArray = new IDiamondLoupe.Facet[](\n _facets.length - 1\n );\n uint256 newArrayLength = newArray.length;\n // Iterate over the original array, skipping the element at the specified `index`\n for (uint256 i; i < newArrayLength; ) {\n if (i < _index) {\n newArray[i] = _facets[i];\n } else {\n newArray[i] = _facets[i + 1];\n }\n unchecked {\n ++i;\n }\n }\n\n return newArray;\n }\n\n function removeElement(\n bytes4[] memory _array,\n uint256 _index\n ) internal pure returns (bytes4[] memory) {\n require(_index < _array.length, \"Invalid index\");\n require(_array.length != 0, \"Invalid array\");\n\n bytes4[] memory newArray = new bytes4[](_array.length - 1);\n uint256 newArrayLength = newArray.length;\n for (uint256 i; i < newArrayLength; ) {\n if (i < _index) {\n newArray[i] = _array[i];\n } else {\n newArray[i] = _array[i + 1];\n }\n unchecked {\n ++i;\n }\n }\n\n return newArray;\n }\n\n function setValue(\n bytes4[] memory _keys,\n address[] memory _values,\n bytes4 _key,\n address _value\n ) internal pure returns (bytes4[] memory, address[] memory) {\n uint256 index = findIndex(_keys, _key);\n uint256 keysLength = _keys.length;\n if (index < keysLength) {\n _values[index] = _value;\n } else {\n // Create new storage arrays\n bytes4[] memory newKeys = new bytes4[](keysLength + 1);\n address[] memory newValues = new address[](_values.length + 1);\n\n // Copy values to the new storage arrays\n for (uint256 i; i < keysLength; ) {\n newKeys[i] = _keys[i];\n newValues[i] = _values[i];\n\n unchecked {\n ++i;\n }\n }\n\n // Add the new key-value pair\n newKeys[keysLength] = _key;\n newValues[_values.length] = _value;\n\n return (newKeys, newValues);\n }\n\n // If the key already exists, return the original arrays\n return (_keys, _values);\n }\n\n function getValue(\n bytes4[] memory _keys,\n address[] memory _values,\n bytes4 _key\n ) internal pure returns (address) {\n uint256 index = findIndex(_keys, _key);\n if (index >= _keys.length) return address(0);\n\n return _values[index];\n }\n\n function findIndex(\n bytes4[] memory _keys,\n bytes4 _key\n ) internal pure returns (uint256) {\n uint256 keysLength = _keys.length;\n for (uint256 i; i < keysLength; ) {\n if (_keys[i] == _key) {\n return i;\n }\n unchecked {\n ++i;\n }\n }\n return keysLength;\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 999999 + }, + "evmVersion": "paris", + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/deployments/bsc/solcInputs/4356503edd8ae34e73cb6dd1c8e2fc8a.json b/deployments/bsc/solcInputs/4356503edd8ae34e73cb6dd1c8e2fc8a.json new file mode 100644 index 0000000..db88715 --- /dev/null +++ b/deployments/bsc/solcInputs/4356503edd8ae34e73cb6dd1c8e2fc8a.json @@ -0,0 +1,354 @@ +{ + "language": "Solidity", + "sources": { + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby disabling any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable2Step.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./Ownable.sol\";\n\n/**\n * @dev Contract module which provides access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership} and {acceptOwnership}.\n *\n * This module is used through inheritance. It will make available all functions\n * from parent (Ownable).\n */\nabstract contract Ownable2Step is Ownable {\n address private _pendingOwner;\n\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Returns the address of the pending owner.\n */\n function pendingOwner() public view virtual returns (address) {\n return _pendingOwner;\n }\n\n /**\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual override onlyOwner {\n _pendingOwner = newOwner;\n emit OwnershipTransferStarted(owner(), newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual override {\n delete _pendingOwner;\n super._transferOwnership(newOwner);\n }\n\n /**\n * @dev The new owner accepts the ownership transfer.\n */\n function acceptOwnership() public virtual {\n address sender = _msgSender();\n require(pendingOwner() == sender, \"Ownable2Step: caller is not the new owner\");\n _transferOwnership(sender);\n }\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC1271.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC1271 standard signature validation method for\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\n *\n * _Available since v4.1._\n */\ninterface IERC1271 {\n /**\n * @dev Should return whether the signature provided is valid for the provided data\n * @param hash Hash of the data to be signed\n * @param signature Signature byte array associated with _data\n */\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\n}\n" + }, + "@openzeppelin/contracts/security/ReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor() {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n _nonReentrantBefore();\n _;\n _nonReentrantAfter();\n }\n\n function _nonReentrantBefore() private {\n // On the first call to nonReentrant, _status will be _NOT_ENTERED\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n }\n\n function _nonReentrantAfter() private {\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Returns true if the reentrancy guard is currently set to \"entered\", which indicates there is a\n * `nonReentrant` function in the call stack.\n */\n function _reentrancyGuardEntered() internal view returns (bool) {\n return _status == _ENTERED;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/ERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/ERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC1155.sol\";\nimport \"./IERC1155Receiver.sol\";\nimport \"./extensions/IERC1155MetadataURI.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of the basic standard multi-token.\n * See https://eips.ethereum.org/EIPS/eip-1155\n * Originally based on code by Enjin: https://github.com/enjin/erc-1155\n *\n * _Available since v3.1._\n */\ncontract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {\n using Address for address;\n\n // Mapping from token ID to account balances\n mapping(uint256 => mapping(address => uint256)) private _balances;\n\n // Mapping from account to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json\n string private _uri;\n\n /**\n * @dev See {_setURI}.\n */\n constructor(string memory uri_) {\n _setURI(uri_);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return\n interfaceId == type(IERC1155).interfaceId ||\n interfaceId == type(IERC1155MetadataURI).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC1155MetadataURI-uri}.\n *\n * This implementation returns the same URI for *all* token types. It relies\n * on the token type ID substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * Clients calling this function must replace the `\\{id\\}` substring with the\n * actual token type ID.\n */\n function uri(uint256) public view virtual override returns (string memory) {\n return _uri;\n }\n\n /**\n * @dev See {IERC1155-balanceOf}.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {\n require(account != address(0), \"ERC1155: address zero is not a valid owner\");\n return _balances[id][account];\n }\n\n /**\n * @dev See {IERC1155-balanceOfBatch}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] memory accounts,\n uint256[] memory ids\n ) public view virtual override returns (uint256[] memory) {\n require(accounts.length == ids.length, \"ERC1155: accounts and ids length mismatch\");\n\n uint256[] memory batchBalances = new uint256[](accounts.length);\n\n for (uint256 i = 0; i < accounts.length; ++i) {\n batchBalances[i] = balanceOf(accounts[i], ids[i]);\n }\n\n return batchBalances;\n }\n\n /**\n * @dev See {IERC1155-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC1155-isApprovedForAll}.\n */\n function isApprovedForAll(address account, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[account][operator];\n }\n\n /**\n * @dev See {IERC1155-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n _safeTransferFrom(from, to, id, amount, data);\n }\n\n /**\n * @dev See {IERC1155-safeBatchTransferFrom}.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n _safeBatchTransferFrom(from, to, ids, amounts, data);\n }\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n\n emit TransferSingle(operator, from, to, id, amount);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n for (uint256 i = 0; i < ids.length; ++i) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n }\n\n emit TransferBatch(operator, from, to, ids, amounts);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\n\n _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);\n }\n\n /**\n * @dev Sets a new URI for all token types, by relying on the token type ID\n * substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * By this mechanism, any occurrence of the `\\{id\\}` substring in either the\n * URI or any of the amounts in the JSON file at said URI will be replaced by\n * clients with the token type ID.\n *\n * For example, the `https://token-cdn-domain/\\{id\\}.json` URI would be\n * interpreted by clients as\n * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`\n * for token type ID 0x4cce0.\n *\n * See {uri}.\n *\n * Because these URIs cannot be meaningfully represented by the {URI} event,\n * this function emits no events.\n */\n function _setURI(string memory newuri) internal virtual {\n _uri = newuri;\n }\n\n /**\n * @dev Creates `amount` tokens of token type `id`, and assigns them to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _mint(address to, uint256 id, uint256 amount, bytes memory data) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _balances[id][to] += amount;\n emit TransferSingle(operator, address(0), to, id, amount);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n for (uint256 i = 0; i < ids.length; i++) {\n _balances[ids[i]][to] += amounts[i];\n }\n\n emit TransferBatch(operator, address(0), to, ids, amounts);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);\n }\n\n /**\n * @dev Destroys `amount` tokens of token type `id` from `from`\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `from` must have at least `amount` tokens of token type `id`.\n */\n function _burn(address from, uint256 id, uint256 amount) internal virtual {\n require(from != address(0), \"ERC1155: burn from the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n\n emit TransferSingle(operator, from, address(0), id, amount);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n */\n function _burnBatch(address from, uint256[] memory ids, uint256[] memory amounts) internal virtual {\n require(from != address(0), \"ERC1155: burn from the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n\n for (uint256 i = 0; i < ids.length; i++) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n }\n\n emit TransferBatch(operator, from, address(0), ids, amounts);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {\n require(owner != operator, \"ERC1155: setting approval status for self\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning, as well as batched variants.\n *\n * The same hook is called on both single and batched variants. For single\n * transfers, the length of the `ids` and `amounts` arrays will be 1.\n *\n * Calling conditions (for each `id` and `amount` pair):\n *\n * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * of token type `id` will be transferred to `to`.\n * - When `from` is zero, `amount` tokens of token type `id` will be minted\n * for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n * will be burned.\n * - `from` and `to` are never both zero.\n * - `ids` and `amounts` have the same, non-zero length.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any token transfer. This includes minting\n * and burning, as well as batched variants.\n *\n * The same hook is called on both single and batched variants. For single\n * transfers, the length of the `id` and `amount` arrays will be 1.\n *\n * Calling conditions (for each `id` and `amount` pair):\n *\n * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * of token type `id` will be transferred to `to`.\n * - When `from` is zero, `amount` tokens of token type `id` will be minted\n * for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n * will be burned.\n * - `from` and `to` are never both zero.\n * - `ids` and `amounts` have the same, non-zero length.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {}\n\n function _doSafeTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155Receiver.onERC1155Received.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non-ERC1155Receiver implementer\");\n }\n }\n }\n\n function _doSafeBatchTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (\n bytes4 response\n ) {\n if (response != IERC1155Receiver.onERC1155BatchReceived.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non-ERC1155Receiver implementer\");\n }\n }\n }\n\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {\n uint256[] memory array = new uint256[](1);\n array[0] = element;\n\n return array;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC1155.sol\";\n\n/**\n * @dev Interface of the optional ERC1155MetadataExtension interface, as defined\n * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155MetadataURI is IERC1155 {\n /**\n * @dev Returns the URI for token type `id`.\n *\n * If the `\\{id\\}` substring is present in the URI, it must be replaced by\n * clients with the actual token type ID.\n */\n function uri(uint256 id) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155 is IERC165 {\n /**\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n */\n event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);\n\n /**\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n * transfers.\n */\n event TransferBatch(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\n\n /**\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n * `approved`.\n */\n event ApprovalForAll(address indexed account, address indexed operator, bool approved);\n\n /**\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n *\n * If an {URI} event was emitted for `id`, the standard\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n * returned by {IERC1155MetadataURI-uri}.\n */\n event URI(string value, uint256 indexed id);\n\n /**\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) external view returns (uint256);\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] calldata accounts,\n uint256[] calldata ids\n ) external view returns (uint256[] memory);\n\n /**\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n *\n * Emits an {ApprovalForAll} event.\n *\n * Requirements:\n *\n * - `operator` cannot be the caller.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n *\n * See {setApprovalForAll}.\n */\n function isApprovedForAll(address account, address operator) external view returns (bool);\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155Receiver is IERC165 {\n /**\n * @dev Handles the receipt of a single ERC1155 token type. This function is\n * called at the end of a `safeTransferFrom` after the balance has been updated.\n *\n * NOTE: To accept the transfer, this must return\n * `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n * (i.e. 0xf23a6e61, or its own function selector).\n *\n * @param operator The address which initiated the transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param id The ID of the token being transferred\n * @param value The amount of tokens being transferred\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n ) external returns (bytes4);\n\n /**\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\n * is called at the end of a `safeBatchTransferFrom` after the balances have\n * been updated.\n *\n * NOTE: To accept the transfer(s), this must return\n * `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n * (i.e. 0xbc197c81, or its own function selector).\n *\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the default value returned by this function, unless\n * it's overridden.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(address from, address to, uint256 amount) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\n // decrementing then incrementing.\n _balances[to] += amount;\n }\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n unchecked {\n // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\n _balances[account] += amount;\n }\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n // Overflow not possible: amount <= accountBalance <= totalSupply.\n _totalSupply -= amount;\n }\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\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" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` 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 amount) 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 `amount` as the allowance of `spender` over the 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 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` 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 amount) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/ERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721.sol\";\nimport \"./IERC721Receiver.sol\";\nimport \"./extensions/IERC721Metadata.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/Strings.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\n using Address for address;\n using Strings for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\n\n // Mapping from token ID to approved address\n mapping(uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return\n interfaceId == type(IERC721).interfaceId ||\n interfaceId == type(IERC721Metadata).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _ownerOf(tokenId);\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token owner or approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n _requireMinted(tokenId);\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n _safeTransfer(from, to, tokenId, data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(address from, address to, uint256 tokenId, bytes memory data) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist\n */\n function _ownerOf(uint256 tokenId) internal view virtual returns (address) {\n return _owners[tokenId];\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _ownerOf(tokenId) != address(0);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n address owner = ERC721.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(address to, uint256 tokenId, bytes memory data) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId, 1);\n\n // Check that tokenId was not minted by `_beforeTokenTransfer` hook\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n unchecked {\n // Will not overflow unless all 2**256 token ids are minted to the same owner.\n // Given that tokens are minted one by one, it is impossible in practice that\n // this ever happens. Might change if we allow batch minting.\n // The ERC fails to describe this case.\n _balances[to] += 1;\n }\n\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(address(0), to, tokenId, 1);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n * This is an internal function that does not check if the sender is authorized to operate on the token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId, 1);\n\n // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook\n owner = ERC721.ownerOf(tokenId);\n\n // Clear approvals\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // Cannot overflow, as that would require more tokens to be burned/transferred\n // out than the owner initially received through minting and transferring in.\n _balances[owner] -= 1;\n }\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(owner, address(0), tokenId, 1);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(address from, address to, uint256 tokenId) internal virtual {\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId, 1);\n\n // Check that tokenId was not transferred by `_beforeTokenTransfer` hook\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n\n // Clear approvals from the previous owner\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // `_balances[from]` cannot overflow for the same reason as described in `_burn`:\n // `from`'s balance is the number of token held, which is at least one before the current\n // transfer.\n // `_balances[to]` could overflow in the conditions described in `_mint`. That would require\n // all 2**256 token ids to be minted, which in practice is impossible.\n _balances[from] -= 1;\n _balances[to] += 1;\n }\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId, 1);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721Receiver.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`.\n * - When `from` is zero, the tokens will be minted for `to`.\n * - When `to` is zero, ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}\n\n /**\n * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`.\n * - When `from` is zero, the tokens were minted for `to`.\n * - When `to` is zero, ``from``'s tokens were burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}\n\n /**\n * @dev Unsafe write access to the balances, used by extensions that \"mint\" tokens using an {ownerOf} override.\n *\n * WARNING: Anyone calling this MUST ensure that the balances remain consistent with the ownership. The invariant\n * being that for any address `a` the value returned by `balanceOf(a)` must be equal to the number of tokens such\n * that `ownerOf(tokenId)` is `a`.\n */\n // solhint-disable-next-line func-name-mixedcase\n function __unsafe_increaseBalance(address account, uint256 amount) internal {\n _balances[account] += amount;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721Receiver {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/ERC777.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC777/ERC777.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC777.sol\";\nimport \"./IERC777Recipient.sol\";\nimport \"./IERC777Sender.sol\";\nimport \"../ERC20/IERC20.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/introspection/IERC1820Registry.sol\";\n\n/**\n * @dev Implementation of the {IERC777} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n *\n * Support for ERC20 is included in this contract, as specified by the EIP: both\n * the ERC777 and ERC20 interfaces can be safely used when interacting with it.\n * Both {IERC777-Sent} and {IERC20-Transfer} events are emitted on token\n * movements.\n *\n * Additionally, the {IERC777-granularity} value is hard-coded to `1`, meaning that there\n * are no special restrictions in the amount of tokens that created, moved, or\n * destroyed. This makes integration with ERC20 applications seamless.\n *\n * CAUTION: This file is deprecated as of v4.9 and will be removed in the next major release.\n */\ncontract ERC777 is Context, IERC777, IERC20 {\n using Address for address;\n\n IERC1820Registry internal constant _ERC1820_REGISTRY = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n mapping(address => uint256) private _balances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n bytes32 private constant _TOKENS_SENDER_INTERFACE_HASH = keccak256(\"ERC777TokensSender\");\n bytes32 private constant _TOKENS_RECIPIENT_INTERFACE_HASH = keccak256(\"ERC777TokensRecipient\");\n\n // This isn't ever read from - it's only used to respond to the defaultOperators query.\n address[] private _defaultOperatorsArray;\n\n // Immutable, but accounts may revoke them (tracked in __revokedDefaultOperators).\n mapping(address => bool) private _defaultOperators;\n\n // For each account, a mapping of its operators and revoked default operators.\n mapping(address => mapping(address => bool)) private _operators;\n mapping(address => mapping(address => bool)) private _revokedDefaultOperators;\n\n // ERC20-allowances\n mapping(address => mapping(address => uint256)) private _allowances;\n\n /**\n * @dev `defaultOperators` may be an empty array.\n */\n constructor(string memory name_, string memory symbol_, address[] memory defaultOperators_) {\n _name = name_;\n _symbol = symbol_;\n\n _defaultOperatorsArray = defaultOperators_;\n for (uint256 i = 0; i < defaultOperators_.length; i++) {\n _defaultOperators[defaultOperators_[i]] = true;\n }\n\n // register interfaces\n _ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256(\"ERC777Token\"), address(this));\n _ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256(\"ERC20Token\"), address(this));\n }\n\n /**\n * @dev See {IERC777-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC777-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {ERC20-decimals}.\n *\n * Always returns 18, as per the\n * [ERC777 EIP](https://eips.ethereum.org/EIPS/eip-777#backward-compatibility).\n */\n function decimals() public pure virtual returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC777-granularity}.\n *\n * This implementation always returns `1`.\n */\n function granularity() public view virtual override returns (uint256) {\n return 1;\n }\n\n /**\n * @dev See {IERC777-totalSupply}.\n */\n function totalSupply() public view virtual override(IERC20, IERC777) returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev Returns the amount of tokens owned by an account (`tokenHolder`).\n */\n function balanceOf(address tokenHolder) public view virtual override(IERC20, IERC777) returns (uint256) {\n return _balances[tokenHolder];\n }\n\n /**\n * @dev See {IERC777-send}.\n *\n * Also emits a {IERC20-Transfer} event for ERC20 compatibility.\n */\n function send(address recipient, uint256 amount, bytes memory data) public virtual override {\n _send(_msgSender(), recipient, amount, data, \"\", true);\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Unlike `send`, `recipient` is _not_ required to implement the {IERC777Recipient}\n * interface if it is a contract.\n *\n * Also emits a {Sent} event.\n */\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n _send(_msgSender(), recipient, amount, \"\", \"\", false);\n return true;\n }\n\n /**\n * @dev See {IERC777-burn}.\n *\n * Also emits a {IERC20-Transfer} event for ERC20 compatibility.\n */\n function burn(uint256 amount, bytes memory data) public virtual override {\n _burn(_msgSender(), amount, data, \"\");\n }\n\n /**\n * @dev See {IERC777-isOperatorFor}.\n */\n function isOperatorFor(address operator, address tokenHolder) public view virtual override returns (bool) {\n return\n operator == tokenHolder ||\n (_defaultOperators[operator] && !_revokedDefaultOperators[tokenHolder][operator]) ||\n _operators[tokenHolder][operator];\n }\n\n /**\n * @dev See {IERC777-authorizeOperator}.\n */\n function authorizeOperator(address operator) public virtual override {\n require(_msgSender() != operator, \"ERC777: authorizing self as operator\");\n\n if (_defaultOperators[operator]) {\n delete _revokedDefaultOperators[_msgSender()][operator];\n } else {\n _operators[_msgSender()][operator] = true;\n }\n\n emit AuthorizedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-revokeOperator}.\n */\n function revokeOperator(address operator) public virtual override {\n require(operator != _msgSender(), \"ERC777: revoking self as operator\");\n\n if (_defaultOperators[operator]) {\n _revokedDefaultOperators[_msgSender()][operator] = true;\n } else {\n delete _operators[_msgSender()][operator];\n }\n\n emit RevokedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-defaultOperators}.\n */\n function defaultOperators() public view virtual override returns (address[] memory) {\n return _defaultOperatorsArray;\n }\n\n /**\n * @dev See {IERC777-operatorSend}.\n *\n * Emits {Sent} and {IERC20-Transfer} events.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes memory data,\n bytes memory operatorData\n ) public virtual override {\n require(isOperatorFor(_msgSender(), sender), \"ERC777: caller is not an operator for holder\");\n _send(sender, recipient, amount, data, operatorData, true);\n }\n\n /**\n * @dev See {IERC777-operatorBurn}.\n *\n * Emits {Burned} and {IERC20-Transfer} events.\n */\n function operatorBurn(\n address account,\n uint256 amount,\n bytes memory data,\n bytes memory operatorData\n ) public virtual override {\n require(isOperatorFor(_msgSender(), account), \"ERC777: caller is not an operator for holder\");\n _burn(account, amount, data, operatorData);\n }\n\n /**\n * @dev See {IERC20-allowance}.\n *\n * Note that operator and allowance concepts are orthogonal: operators may\n * not have allowance, and accounts with allowance may not be operators\n * themselves.\n */\n function allowance(address holder, address spender) public view virtual override returns (uint256) {\n return _allowances[holder][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Note that accounts cannot have allowance issued by their operators.\n */\n function approve(address spender, uint256 value) public virtual override returns (bool) {\n address holder = _msgSender();\n _approve(holder, spender, value);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Note that operator and allowance concepts are orthogonal: operators cannot\n * call `transferFrom` (unless they have allowance), and accounts with\n * allowance cannot call `operatorSend` (unless they are operators).\n *\n * Emits {Sent}, {IERC20-Transfer} and {IERC20-Approval} events.\n */\n function transferFrom(address holder, address recipient, uint256 amount) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(holder, spender, amount);\n _send(holder, recipient, amount, \"\", \"\", false);\n return true;\n }\n\n /**\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with the caller address as the `operator` and with\n * `userData` and `operatorData`.\n *\n * See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits {Minted} and {IERC20-Transfer} events.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - if `account` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function _mint(address account, uint256 amount, bytes memory userData, bytes memory operatorData) internal virtual {\n _mint(account, amount, userData, operatorData, true);\n }\n\n /**\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * If `requireReceptionAck` is set to true, and if a send hook is\n * registered for `account`, the corresponding function will be called with\n * `operator`, `data` and `operatorData`.\n *\n * See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits {Minted} and {IERC20-Transfer} events.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - if `account` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function _mint(\n address account,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) internal virtual {\n require(account != address(0), \"ERC777: mint to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), account, amount);\n\n // Update state variables\n _totalSupply += amount;\n _balances[account] += amount;\n\n _callTokensReceived(operator, address(0), account, amount, userData, operatorData, requireReceptionAck);\n\n emit Minted(operator, account, amount, userData, operatorData);\n emit Transfer(address(0), account, amount);\n }\n\n /**\n * @dev Send tokens\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _send(\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) internal virtual {\n require(from != address(0), \"ERC777: transfer from the zero address\");\n require(to != address(0), \"ERC777: transfer to the zero address\");\n\n address operator = _msgSender();\n\n _callTokensToSend(operator, from, to, amount, userData, operatorData);\n\n _move(operator, from, to, amount, userData, operatorData);\n\n _callTokensReceived(operator, from, to, amount, userData, operatorData, requireReceptionAck);\n }\n\n /**\n * @dev Burn tokens\n * @param from address token holder address\n * @param amount uint256 amount of tokens to burn\n * @param data bytes extra information provided by the token holder\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _burn(address from, uint256 amount, bytes memory data, bytes memory operatorData) internal virtual {\n require(from != address(0), \"ERC777: burn from the zero address\");\n\n address operator = _msgSender();\n\n _callTokensToSend(operator, from, address(0), amount, data, operatorData);\n\n _beforeTokenTransfer(operator, from, address(0), amount);\n\n // Update state variables\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC777: burn amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Burned(operator, from, amount, data, operatorData);\n emit Transfer(from, address(0), amount);\n }\n\n function _move(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n ) private {\n _beforeTokenTransfer(operator, from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC777: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Sent(operator, from, to, amount, userData, operatorData);\n emit Transfer(from, to, amount);\n }\n\n /**\n * @dev See {ERC20-_approve}.\n *\n * Note that accounts cannot have allowance issued by their operators.\n */\n function _approve(address holder, address spender, uint256 value) internal virtual {\n require(holder != address(0), \"ERC777: approve from the zero address\");\n require(spender != address(0), \"ERC777: approve to the zero address\");\n\n _allowances[holder][spender] = value;\n emit Approval(holder, spender, value);\n }\n\n /**\n * @dev Call from.tokensToSend() if the interface is registered\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _callTokensToSend(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n ) private {\n address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(from, _TOKENS_SENDER_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Sender(implementer).tokensToSend(operator, from, to, amount, userData, operatorData);\n }\n }\n\n /**\n * @dev Call to.tokensReceived() if the interface is registered. Reverts if the recipient is a contract but\n * tokensReceived() was not registered for the recipient\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _callTokensReceived(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) private {\n address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(to, _TOKENS_RECIPIENT_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Recipient(implementer).tokensReceived(operator, from, to, amount, userData, operatorData);\n } else if (requireReceptionAck) {\n require(!to.isContract(), \"ERC777: token recipient contract has no implementer for ERC777TokensRecipient\");\n }\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {IERC20-Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC777: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes\n * calls to {send}, {transfer}, {operatorSend}, {transferFrom}, minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be to transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address operator, address from, address to, uint256 amount) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC777/IERC777.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777Token standard as defined in the EIP.\n *\n * This contract uses the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 registry standard] to let\n * token holders and recipients react to token movements by using setting implementers\n * for the associated interfaces in said registry. See {IERC1820Registry} and\n * {ERC1820Implementer}.\n */\ninterface IERC777 {\n /**\n * @dev Emitted when `amount` tokens are created by `operator` and assigned to `to`.\n *\n * Note that some additional user `data` and `operatorData` can be logged in the event.\n */\n event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);\n\n /**\n * @dev Emitted when `operator` destroys `amount` tokens from `account`.\n *\n * Note that some additional user `data` and `operatorData` can be logged in the event.\n */\n event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);\n\n /**\n * @dev Emitted when `operator` is made operator for `tokenHolder`.\n */\n event AuthorizedOperator(address indexed operator, address indexed tokenHolder);\n\n /**\n * @dev Emitted when `operator` is revoked its operator status for `tokenHolder`.\n */\n event RevokedOperator(address indexed operator, address indexed tokenHolder);\n\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, usually a shorter version of the\n * name.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the smallest part of the token that is not divisible. This\n * means all token operations (creation, movement and destruction) must have\n * amounts that are a multiple of this number.\n *\n * For most token contracts, this value will equal 1.\n */\n function granularity() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by an account (`owner`).\n */\n function balanceOf(address owner) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * If send or receive hooks are registered for the caller and `recipient`,\n * the corresponding functions will be called with `data` and empty\n * `operatorData`. See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits a {Sent} event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function send(address recipient, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Destroys `amount` tokens from the caller's account, reducing the\n * total supply.\n *\n * If a send hook is registered for the caller, the corresponding function\n * will be called with `data` and empty `operatorData`. See {IERC777Sender}.\n *\n * Emits a {Burned} event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n */\n function burn(uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Returns true if an account is an operator of `tokenHolder`.\n * Operators can send and burn tokens on behalf of their owners. All\n * accounts are their own operator.\n *\n * See {operatorSend} and {operatorBurn}.\n */\n function isOperatorFor(address operator, address tokenHolder) external view returns (bool);\n\n /**\n * @dev Make an account an operator of the caller.\n *\n * See {isOperatorFor}.\n *\n * Emits an {AuthorizedOperator} event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function authorizeOperator(address operator) external;\n\n /**\n * @dev Revoke an account's operator status for the caller.\n *\n * See {isOperatorFor} and {defaultOperators}.\n *\n * Emits a {RevokedOperator} event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function revokeOperator(address operator) external;\n\n /**\n * @dev Returns the list of default operators. These accounts are operators\n * for all token holders, even if {authorizeOperator} was never called on\n * them.\n *\n * This list is immutable, but individual holders may revoke these via\n * {revokeOperator}, in which case {isOperatorFor} will return false.\n */\n function defaultOperators() external view returns (address[] memory);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must\n * be an operator of `sender`.\n *\n * If send or receive hooks are registered for `sender` and `recipient`,\n * the corresponding functions will be called with `data` and\n * `operatorData`. See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits a {Sent} event.\n *\n * Requirements\n *\n * - `sender` cannot be the zero address.\n * - `sender` must have at least `amount` tokens.\n * - the caller must be an operator for `sender`.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes calldata data,\n bytes calldata operatorData\n ) external;\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the total supply.\n * The caller must be an operator of `account`.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with `data` and `operatorData`. See {IERC777Sender}.\n *\n * Emits a {Burned} event.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n * - the caller must be an operator for `account`.\n */\n function operatorBurn(address account, uint256 amount, bytes calldata data, bytes calldata operatorData) external;\n\n event Sent(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes data,\n bytes operatorData\n );\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\n *\n * Accounts can be notified of {IERC777} tokens being sent to them by having a\n * contract implement this interface (contract holders can be their own\n * implementer) and registering it on the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\n *\n * See {IERC1820Registry} and {ERC1820Implementer}.\n */\ninterface IERC777Recipient {\n /**\n * @dev Called by an {IERC777} token contract whenever tokens are being\n * moved or created into a registered account (`to`). The type of operation\n * is conveyed by `from` being the zero address or not.\n *\n * This call occurs _after_ the token contract's state is updated, so\n * {IERC777-balanceOf}, etc., can be used to query the post-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensReceived(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777Sender.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Sender.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777TokensSender standard as defined in the EIP.\n *\n * {IERC777} Token holders can be notified of operations performed on their\n * tokens by having a contract implement this interface (contract holders can be\n * their own implementer) and registering it on the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\n *\n * See {IERC1820Registry} and {ERC1820Implementer}.\n */\ninterface IERC777Sender {\n /**\n * @dev Called by an {IERC777} token contract whenever a registered holder's\n * (`from`) tokens are about to be moved or destroyed. The type of operation\n * is conveyed by `to` being the zero address or not.\n *\n * This call occurs _before_ the token contract's state is updated, so\n * {IERC777-balanceOf}, etc., can be used to query the pre-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensToSend(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n *\n * Furthermore, `isContract` will also return true if the target contract within\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n * which only has an effect at the end of a transaction.\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Counters.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary Counters {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/ECDSA.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Strings.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV // Deprecated in v4.8\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n /// @solidity memory-safe-assembly\n assembly {\n mstore(0x00, \"\\x19Ethereum Signed Message:\\n32\")\n mstore(0x1c, hash)\n message := keccak256(0x00, 0x3c)\n }\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\n /// @solidity memory-safe-assembly\n assembly {\n let ptr := mload(0x40)\n mstore(ptr, \"\\x19\\x01\")\n mstore(add(ptr, 0x02), domainSeparator)\n mstore(add(ptr, 0x22), structHash)\n data := keccak256(ptr, 0x42)\n }\n }\n\n /**\n * @dev Returns an Ethereum Signed Data with intended validator, created from a\n * `validator` and `data` according to the version 0 of EIP-191.\n *\n * See {recover}.\n */\n function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x00\", validator, data));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/SignatureChecker.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSA.sol\";\nimport \"../../interfaces/IERC1271.sol\";\n\n/**\n * @dev Signature verification helper that can be used instead of `ECDSA.recover` to seamlessly support both ECDSA\n * signatures from externally owned accounts (EOAs) as well as ERC1271 signatures from smart contract wallets like\n * Argent and Gnosis Safe.\n *\n * _Available since v4.1._\n */\nlibrary SignatureChecker {\n /**\n * @dev Checks if a signature is valid for a given signer and data hash. If the signer is a smart contract, the\n * signature is validated against that smart contract using ERC1271, otherwise it's validated using `ECDSA.recover`.\n *\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\n */\n function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature) internal view returns (bool) {\n (address recovered, ECDSA.RecoverError error) = ECDSA.tryRecover(hash, signature);\n return\n (error == ECDSA.RecoverError.NoError && recovered == signer) ||\n isValidERC1271SignatureNow(signer, hash, signature);\n }\n\n /**\n * @dev Checks if a signature is valid for a given signer and data hash. The signature is validated\n * against the signer smart contract using ERC1271.\n *\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\n */\n function isValidERC1271SignatureNow(\n address signer,\n bytes32 hash,\n bytes memory signature\n ) internal view returns (bool) {\n (bool success, bytes memory result) = signer.staticcall(\n abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, signature)\n );\n return (success &&\n result.length >= 32 &&\n abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/ERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165 is IERC165 {\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165).interfaceId;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC1820Registry.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/introspection/IERC1820Registry.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the global ERC1820 Registry, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register\n * implementers for interfaces in this registry, as well as query support.\n *\n * Implementers may be shared by multiple accounts, and can also implement more\n * than a single interface for each account. Contracts can implement interfaces\n * for themselves, but externally-owned accounts (EOA) must delegate this to a\n * contract.\n *\n * {IERC165} interfaces can also be queried via the registry.\n *\n * For an in-depth explanation and source code analysis, see the EIP text.\n */\ninterface IERC1820Registry {\n event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer);\n\n event ManagerChanged(address indexed account, address indexed newManager);\n\n /**\n * @dev Sets `newManager` as the manager for `account`. A manager of an\n * account is able to set interface implementers for it.\n *\n * By default, each account is its own manager. Passing a value of `0x0` in\n * `newManager` will reset the manager to this initial state.\n *\n * Emits a {ManagerChanged} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `account`.\n */\n function setManager(address account, address newManager) external;\n\n /**\n * @dev Returns the manager for `account`.\n *\n * See {setManager}.\n */\n function getManager(address account) external view returns (address);\n\n /**\n * @dev Sets the `implementer` contract as ``account``'s implementer for\n * `interfaceHash`.\n *\n * `account` being the zero address is an alias for the caller's address.\n * The zero address can also be used in `implementer` to remove an old one.\n *\n * See {interfaceHash} to learn how these are created.\n *\n * Emits an {InterfaceImplementerSet} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `account`.\n * - `interfaceHash` must not be an {IERC165} interface id (i.e. it must not\n * end in 28 zeroes).\n * - `implementer` must implement {IERC1820Implementer} and return true when\n * queried for support, unless `implementer` is the caller. See\n * {IERC1820Implementer-canImplementInterfaceForAddress}.\n */\n function setInterfaceImplementer(address account, bytes32 _interfaceHash, address implementer) external;\n\n /**\n * @dev Returns the implementer of `interfaceHash` for `account`. If no such\n * implementer is registered, returns the zero address.\n *\n * If `interfaceHash` is an {IERC165} interface id (i.e. it ends with 28\n * zeroes), `account` will be queried for support of it.\n *\n * `account` being the zero address is an alias for the caller's address.\n */\n function getInterfaceImplementer(address account, bytes32 _interfaceHash) external view returns (address);\n\n /**\n * @dev Returns the interface hash for an `interfaceName`, as defined in the\n * corresponding\n * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP].\n */\n function interfaceHash(string calldata interfaceName) external pure returns (bytes32);\n\n /**\n * @notice Updates the cache with whether the contract implements an ERC165 interface or not.\n * @param account Address of the contract for which to update the cache.\n * @param interfaceId ERC165 interface for which to update the cache.\n */\n function updateERC165Cache(address account, bytes4 interfaceId) external;\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not.\n * If the result is not cached a direct lookup on the contract address is performed.\n * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling\n * {updateERC165Cache} with the contract address.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool);\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not without using or updating the cache.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/math/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\n // The surrounding unchecked block does not change this fact.\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1, \"Math: mulDiv overflow\");\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n //\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n //\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n //\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1 << (log2(a) >> 1);\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = sqrt(a);\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 2, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 128;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 64;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 32;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 16;\n }\n if (value >> 8 > 0) {\n value >>= 8;\n result += 8;\n }\n if (value >> 4 > 0) {\n value >>= 4;\n result += 4;\n }\n if (value >> 2 > 0) {\n value >>= 2;\n result += 2;\n }\n if (value >> 1 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log2(value);\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 10, rounded down, of a positive value.\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 + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 256, rounded down, of a positive value.\n * Returns 0 if given 0.\n *\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n */\n function log256(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 16;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 8;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 4;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 2;\n }\n if (value >> 8 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log256(value);\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/SafeCast.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCast {\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 * _Available since v4.7._\n */\n function toUint248(uint256 value) internal pure returns (uint248) {\n require(value <= type(uint248).max, \"SafeCast: value doesn't fit in 248 bits\");\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 * _Available since v4.7._\n */\n function toUint240(uint256 value) internal pure returns (uint240) {\n require(value <= type(uint240).max, \"SafeCast: value doesn't fit in 240 bits\");\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 * _Available since v4.7._\n */\n function toUint232(uint256 value) internal pure returns (uint232) {\n require(value <= type(uint232).max, \"SafeCast: value doesn't fit in 232 bits\");\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 * _Available since v4.2._\n */\n function toUint224(uint256 value) internal pure returns (uint224) {\n require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\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 * _Available since v4.7._\n */\n function toUint216(uint256 value) internal pure returns (uint216) {\n require(value <= type(uint216).max, \"SafeCast: value doesn't fit in 216 bits\");\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 * _Available since v4.7._\n */\n function toUint208(uint256 value) internal pure returns (uint208) {\n require(value <= type(uint208).max, \"SafeCast: value doesn't fit in 208 bits\");\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 * _Available since v4.7._\n */\n function toUint200(uint256 value) internal pure returns (uint200) {\n require(value <= type(uint200).max, \"SafeCast: value doesn't fit in 200 bits\");\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 * _Available since v4.7._\n */\n function toUint192(uint256 value) internal pure returns (uint192) {\n require(value <= type(uint192).max, \"SafeCast: value doesn't fit in 192 bits\");\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 * _Available since v4.7._\n */\n function toUint184(uint256 value) internal pure returns (uint184) {\n require(value <= type(uint184).max, \"SafeCast: value doesn't fit in 184 bits\");\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 * _Available since v4.7._\n */\n function toUint176(uint256 value) internal pure returns (uint176) {\n require(value <= type(uint176).max, \"SafeCast: value doesn't fit in 176 bits\");\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 * _Available since v4.7._\n */\n function toUint168(uint256 value) internal pure returns (uint168) {\n require(value <= type(uint168).max, \"SafeCast: value doesn't fit in 168 bits\");\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 * _Available since v4.7._\n */\n function toUint160(uint256 value) internal pure returns (uint160) {\n require(value <= type(uint160).max, \"SafeCast: value doesn't fit in 160 bits\");\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 * _Available since v4.7._\n */\n function toUint152(uint256 value) internal pure returns (uint152) {\n require(value <= type(uint152).max, \"SafeCast: value doesn't fit in 152 bits\");\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 * _Available since v4.7._\n */\n function toUint144(uint256 value) internal pure returns (uint144) {\n require(value <= type(uint144).max, \"SafeCast: value doesn't fit in 144 bits\");\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 * _Available since v4.7._\n */\n function toUint136(uint256 value) internal pure returns (uint136) {\n require(value <= type(uint136).max, \"SafeCast: value doesn't fit in 136 bits\");\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 * _Available since v2.5._\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\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 * _Available since v4.7._\n */\n function toUint120(uint256 value) internal pure returns (uint120) {\n require(value <= type(uint120).max, \"SafeCast: value doesn't fit in 120 bits\");\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 * _Available since v4.7._\n */\n function toUint112(uint256 value) internal pure returns (uint112) {\n require(value <= type(uint112).max, \"SafeCast: value doesn't fit in 112 bits\");\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 * _Available since v4.7._\n */\n function toUint104(uint256 value) internal pure returns (uint104) {\n require(value <= type(uint104).max, \"SafeCast: value doesn't fit in 104 bits\");\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 * _Available since v4.2._\n */\n function toUint96(uint256 value) internal pure returns (uint96) {\n require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\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 * _Available since v4.7._\n */\n function toUint88(uint256 value) internal pure returns (uint88) {\n require(value <= type(uint88).max, \"SafeCast: value doesn't fit in 88 bits\");\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 * _Available since v4.7._\n */\n function toUint80(uint256 value) internal pure returns (uint80) {\n require(value <= type(uint80).max, \"SafeCast: value doesn't fit in 80 bits\");\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 * _Available since v4.7._\n */\n function toUint72(uint256 value) internal pure returns (uint72) {\n require(value <= type(uint72).max, \"SafeCast: value doesn't fit in 72 bits\");\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 * _Available since v2.5._\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\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 * _Available since v4.7._\n */\n function toUint56(uint256 value) internal pure returns (uint56) {\n require(value <= type(uint56).max, \"SafeCast: value doesn't fit in 56 bits\");\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 * _Available since v4.7._\n */\n function toUint48(uint256 value) internal pure returns (uint48) {\n require(value <= type(uint48).max, \"SafeCast: value doesn't fit in 48 bits\");\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 * _Available since v4.7._\n */\n function toUint40(uint256 value) internal pure returns (uint40) {\n require(value <= type(uint40).max, \"SafeCast: value doesn't fit in 40 bits\");\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 * _Available since v2.5._\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\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 * _Available since v4.7._\n */\n function toUint24(uint256 value) internal pure returns (uint24) {\n require(value <= type(uint24).max, \"SafeCast: value doesn't fit in 24 bits\");\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 * _Available since v2.5._\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\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 * _Available since v2.5._\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\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 * _Available since v3.0._\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\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 * _Available since v4.7._\n */\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\n downcasted = int248(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 248 bits\");\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 * _Available since v4.7._\n */\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\n downcasted = int240(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 240 bits\");\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 * _Available since v4.7._\n */\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\n downcasted = int232(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 232 bits\");\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 * _Available since v4.7._\n */\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\n downcasted = int224(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 224 bits\");\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 * _Available since v4.7._\n */\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\n downcasted = int216(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 216 bits\");\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 * _Available since v4.7._\n */\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\n downcasted = int208(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 208 bits\");\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 * _Available since v4.7._\n */\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\n downcasted = int200(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 200 bits\");\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 * _Available since v4.7._\n */\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\n downcasted = int192(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 192 bits\");\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 * _Available since v4.7._\n */\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\n downcasted = int184(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 184 bits\");\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 * _Available since v4.7._\n */\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\n downcasted = int176(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 176 bits\");\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 * _Available since v4.7._\n */\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\n downcasted = int168(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 168 bits\");\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 * _Available since v4.7._\n */\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\n downcasted = int160(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 160 bits\");\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 * _Available since v4.7._\n */\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\n downcasted = int152(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 152 bits\");\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 * _Available since v4.7._\n */\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\n downcasted = int144(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 144 bits\");\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 * _Available since v4.7._\n */\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\n downcasted = int136(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 136 bits\");\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 * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\n downcasted = int128(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 128 bits\");\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 * _Available since v4.7._\n */\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\n downcasted = int120(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 120 bits\");\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 * _Available since v4.7._\n */\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\n downcasted = int112(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 112 bits\");\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 * _Available since v4.7._\n */\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\n downcasted = int104(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 104 bits\");\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 * _Available since v4.7._\n */\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\n downcasted = int96(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 96 bits\");\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 * _Available since v4.7._\n */\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\n downcasted = int88(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 88 bits\");\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 * _Available since v4.7._\n */\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\n downcasted = int80(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 80 bits\");\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 * _Available since v4.7._\n */\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\n downcasted = int72(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 72 bits\");\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 * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\n downcasted = int64(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 64 bits\");\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 * _Available since v4.7._\n */\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\n downcasted = int56(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 56 bits\");\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 * _Available since v4.7._\n */\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\n downcasted = int48(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 48 bits\");\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 * _Available since v4.7._\n */\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\n downcasted = int40(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 40 bits\");\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 * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\n downcasted = int32(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 32 bits\");\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 * _Available since v4.7._\n */\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\n downcasted = int24(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 24 bits\");\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 * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\n downcasted = int16(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 16 bits\");\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 * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\n downcasted = int8(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 8 bits\");\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 * _Available since v3.0._\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 require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/SignedMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard signed math utilities missing in the Solidity language.\n */\nlibrary SignedMath {\n /**\n * @dev Returns the largest of two signed numbers.\n */\n function max(int256 a, int256 b) internal pure returns (int256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two signed numbers.\n */\n function min(int256 a, int256 b) internal pure returns (int256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two signed numbers without overflow.\n * The result is rounded towards zero.\n */\n function average(int256 a, int256 b) internal pure returns (int256) {\n // Formula from the book \"Hacker's Delight\"\n int256 x = (a & b) + ((a ^ b) >> 1);\n return x + (int256(uint256(x) >> 255) & (a ^ b));\n }\n\n /**\n * @dev Returns the absolute unsigned value of a signed value.\n */\n function abs(int256 n) internal pure returns (uint256) {\n unchecked {\n // must be unchecked in order to support `n = type(int256).min`\n return uint256(n >= 0 ? n : -n);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/Math.sol\";\nimport \"./math/SignedMath.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n unchecked {\n uint256 length = Math.log10(value) + 1;\n string memory buffer = new string(length);\n uint256 ptr;\n /// @solidity memory-safe-assembly\n assembly {\n ptr := add(buffer, add(32, length))\n }\n while (true) {\n ptr--;\n /// @solidity memory-safe-assembly\n assembly {\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n }\n value /= 10;\n if (value == 0) break;\n }\n return buffer;\n }\n }\n\n /**\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\n */\n function toString(int256 value) internal pure returns (string memory) {\n return string(abi.encodePacked(value < 0 ? \"-\" : \"\", toString(SignedMath.abs(value))));\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n unchecked {\n return toHexString(value, Math.log256(value) + 1);\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n\n /**\n * @dev Returns true if the two strings are equal.\n */\n function equal(string memory a, string memory b) internal pure returns (bool) {\n return keccak256(bytes(a)) == keccak256(bytes(b));\n }\n}\n" + }, + "contracts/aa-4337/core/BaseAccount.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-empty-blocks */\n\nimport \"../interfaces/IAccount.sol\";\nimport \"../interfaces/IEntryPoint.sol\";\nimport \"./Helpers.sol\";\n\n/**\n * Basic account implementation.\n * this contract provides the basic logic for implementing the IAccount interface - validateUserOp\n * specific account implementation should inherit it and provide the account-specific logic\n */\nabstract contract BaseAccount is IAccount {\n using UserOperationLib for UserOperation;\n\n //return value in case of signature failure, with no time-range.\n // equivalent to _packValidationData(true,0,0);\n uint256 internal constant SIG_VALIDATION_FAILED = 1;\n\n /**\n * Return the account nonce.\n * This method returns the next sequential nonce.\n * For a nonce of a specific key, use `entrypoint.getNonce(account, key)`\n */\n function getNonce() public view virtual returns (uint256) {\n return entryPoint().getNonce(address(this), 0);\n }\n\n /**\n * return the entryPoint used by this account.\n * subclass should return the current entryPoint used by this account.\n */\n function entryPoint() public view virtual returns (IEntryPoint);\n\n /**\n * Validate user's signature and nonce.\n * subclass doesn't need to override this method. Instead, it should override the specific internal validation methods.\n */\n function validateUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 missingAccountFunds\n ) external virtual override returns (uint256 validationData) {\n _requireFromEntryPoint();\n validationData = _validateSignature(userOp, userOpHash);\n _validateNonce(userOp.nonce);\n _payPrefund(missingAccountFunds);\n }\n\n /**\n * ensure the request comes from the known entrypoint.\n */\n function _requireFromEntryPoint() internal view virtual {\n require(\n msg.sender == address(entryPoint()),\n \"account: not from EntryPoint\"\n );\n }\n\n /**\n * validate the signature is valid for this message.\n * @param userOp validate the userOp.signature field\n * @param userOpHash convenient field: the hash of the request, to check the signature against\n * (also hashes the entrypoint and chain id)\n * @return validationData signature and time-range of this operation\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * If the account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function _validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) internal virtual returns (uint256 validationData);\n\n /**\n * Validate the nonce of the UserOperation.\n * This method may validate the nonce requirement of this account.\n * e.g.\n * To limit the nonce to use sequenced UserOps only (no \"out of order\" UserOps):\n * `require(nonce < type(uint64).max)`\n * For a hypothetical account that *requires* the nonce to be out-of-order:\n * `require(nonce & type(uint64).max == 0)`\n *\n * The actual nonce uniqueness is managed by the EntryPoint, and thus no other\n * action is needed by the account itself.\n *\n * @param nonce to validate\n *\n * solhint-disable-next-line no-empty-blocks\n */\n function _validateNonce(uint256 nonce) internal view virtual {}\n\n /**\n * sends to the entrypoint (msg.sender) the missing funds for this transaction.\n * subclass MAY override this method for better funds management\n * (e.g. send to the entryPoint more than the minimum required, so that in future transactions\n * it will not be required to send again)\n * @param missingAccountFunds the minimum value this method should send the entrypoint.\n * this value MAY be zero, in case there is enough deposit, or the userOp has a paymaster.\n */\n function _payPrefund(uint256 missingAccountFunds) internal virtual {\n if (missingAccountFunds != 0) {\n (bool success, ) = payable(msg.sender).call{\n value: missingAccountFunds,\n gas: type(uint256).max\n }(\"\");\n (success);\n //ignore failure (its EntryPoint's job to verify, not account.)\n }\n }\n}\n" + }, + "contracts/aa-4337/core/EntryPoint.sol": { + "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n\nimport \"../interfaces/IAccount.sol\";\nimport \"../interfaces/IPaymaster.sol\";\nimport \"../interfaces/IEntryPoint.sol\";\n\nimport \"../utils/Exec.sol\";\nimport \"./StakeManager.sol\";\nimport \"./SenderCreator.sol\";\nimport \"./Helpers.sol\";\nimport \"./NonceManager.sol\";\nimport \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\n\ncontract EntryPoint is\n IEntryPoint,\n StakeManager,\n NonceManager,\n ReentrancyGuard\n{\n using UserOperationLib for UserOperation;\n\n SenderCreator private immutable senderCreator = new SenderCreator();\n\n // internal value used during simulation: need to query aggregator.\n address private constant SIMULATE_FIND_AGGREGATOR = address(1);\n\n // marker for inner call revert on out of gas\n bytes32 private constant INNER_OUT_OF_GAS = hex\"deaddead\";\n\n uint256 private constant REVERT_REASON_MAX_LEN = 2048;\n\n /**\n * for simulation purposes, validateUserOp (and validatePaymasterUserOp) must return this value\n * in case of signature failure, instead of revert.\n */\n uint256 public constant SIG_VALIDATION_FAILED = 1;\n\n /**\n * compensate the caller's beneficiary address with the collected fees of all UserOperations.\n * @param beneficiary the address to receive the fees\n * @param amount amount to transfer.\n */\n function _compensate(address payable beneficiary, uint256 amount) internal {\n require(beneficiary != address(0), \"AA90 invalid beneficiary\");\n (bool success, ) = beneficiary.call{value: amount}(\"\");\n require(success, \"AA91 failed send to beneficiary\");\n }\n\n /**\n * execute a user op\n * @param opIndex index into the opInfo array\n * @param userOp the userOp to execute\n * @param opInfo the opInfo filled by validatePrepayment for this userOp.\n * @return collected the total amount this userOp paid.\n */\n function _executeUserOp(\n uint256 opIndex,\n UserOperation calldata userOp,\n UserOpInfo memory opInfo\n ) private returns (uint256 collected) {\n uint256 preGas = gasleft();\n bytes memory context = getMemoryBytesFromOffset(opInfo.contextOffset);\n\n try this.innerHandleOp(userOp.callData, opInfo, context) returns (\n uint256 _actualGasCost\n ) {\n collected = _actualGasCost;\n } catch {\n bytes32 innerRevertCode;\n assembly {\n returndatacopy(0, 0, 32)\n innerRevertCode := mload(0)\n }\n // handleOps was called with gas limit too low. abort entire bundle.\n if (innerRevertCode == INNER_OUT_OF_GAS) {\n //report paymaster, since if it is not deliberately caused by the bundler,\n // it must be a revert caused by paymaster.\n revert FailedOp(opIndex, \"AA95 out of gas\");\n }\n\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n collected = _handlePostOp(\n opIndex,\n IPaymaster.PostOpMode.postOpReverted,\n opInfo,\n context,\n actualGas\n );\n }\n }\n\n /**\n * Execute a batch of UserOperations.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(\n UserOperation[] calldata ops,\n address payable beneficiary\n ) public nonReentrant {\n uint256 opslen = ops.length;\n UserOpInfo[] memory opInfos = new UserOpInfo[](opslen);\n\n unchecked {\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[i];\n (\n uint256 validationData,\n uint256 pmValidationData\n ) = _validatePrepayment(i, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(\n i,\n validationData,\n pmValidationData,\n address(0)\n );\n }\n\n uint256 collected = 0;\n emit BeforeExecution();\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(i, ops[i], opInfos[i]);\n }\n\n _compensate(beneficiary, collected);\n } //unchecked\n }\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) public nonReentrant {\n uint256 opasLen = opsPerAggregator.length;\n uint256 totalOps = 0;\n for (uint256 i = 0; i < opasLen; i++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[i];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n //address(1) is special marker of \"signature error\"\n require(\n address(aggregator) != address(1),\n \"AA96 invalid aggregator\"\n );\n\n if (address(aggregator) != address(0)) {\n // solhint-disable-next-line no-empty-blocks\n try aggregator.validateSignatures(ops, opa.signature) {} catch {\n revert SignatureValidationFailed(address(aggregator));\n }\n }\n\n totalOps += ops.length;\n }\n\n UserOpInfo[] memory opInfos = new UserOpInfo[](totalOps);\n\n emit BeforeExecution();\n\n uint256 opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n uint256 opslen = ops.length;\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[opIndex];\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(opIndex, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(\n i,\n validationData,\n paymasterValidationData,\n address(aggregator)\n );\n opIndex++;\n }\n }\n\n uint256 collected = 0;\n opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n emit SignatureAggregatorChanged(address(opa.aggregator));\n UserOperation[] calldata ops = opa.userOps;\n uint256 opslen = ops.length;\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(opIndex, ops[i], opInfos[opIndex]);\n opIndex++;\n }\n }\n emit SignatureAggregatorChanged(address(0));\n\n _compensate(beneficiary, collected);\n }\n\n /// @inheritdoc IEntryPoint\n function simulateHandleOp(\n UserOperation calldata op,\n address target,\n bytes calldata targetCallData\n ) external override {\n UserOpInfo memory opInfo;\n _simulationOnlyValidations(op);\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(0, op, opInfo);\n ValidationData memory data = _intersectTimeRange(\n validationData,\n paymasterValidationData\n );\n\n numberMarker();\n uint256 paid = _executeUserOp(0, op, opInfo);\n numberMarker();\n bool targetSuccess;\n bytes memory targetResult;\n if (target != address(0)) {\n (targetSuccess, targetResult) = target.call(targetCallData);\n }\n revert ExecutionResult(\n opInfo.preOpGas,\n paid,\n data.validAfter,\n data.validUntil,\n targetSuccess,\n targetResult\n );\n }\n\n // A memory copy of UserOp static fields only.\n // Excluding: callData, initCode and signature. Replacing paymasterAndData with paymaster.\n struct MemoryUserOp {\n address sender;\n uint256 nonce;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n address paymaster;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n }\n\n struct UserOpInfo {\n MemoryUserOp mUserOp;\n bytes32 userOpHash;\n uint256 prefund;\n uint256 contextOffset;\n uint256 preOpGas;\n }\n\n /**\n * inner function to handle a UserOperation.\n * Must be declared \"external\" to open a call context, but it can only be called by handleOps.\n */\n function innerHandleOp(\n bytes memory callData,\n UserOpInfo memory opInfo,\n bytes calldata context\n ) external returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n require(msg.sender == address(this), \"AA92 internal call only\");\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n\n uint callGasLimit = mUserOp.callGasLimit;\n unchecked {\n // handleOps was called with gas limit too low. abort entire bundle.\n if (\n gasleft() < callGasLimit + mUserOp.verificationGasLimit + 5000\n ) {\n assembly {\n mstore(0, INNER_OUT_OF_GAS)\n revert(0, 32)\n }\n }\n }\n\n IPaymaster.PostOpMode mode = IPaymaster.PostOpMode.opSucceeded;\n if (callData.length > 0) {\n bool success = Exec.call(mUserOp.sender, 0, callData, callGasLimit);\n if (!success) {\n bytes memory result = Exec.getReturnData(REVERT_REASON_MAX_LEN);\n if (result.length > 0) {\n emit UserOperationRevertReason(\n opInfo.userOpHash,\n mUserOp.sender,\n mUserOp.nonce,\n result\n );\n }\n mode = IPaymaster.PostOpMode.opReverted;\n }\n }\n\n unchecked {\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n //note: opIndex is ignored (relevant only if mode==postOpReverted, which is only possible outside of innerHandleOp)\n return _handlePostOp(0, mode, opInfo, context, actualGas);\n }\n }\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(\n UserOperation calldata userOp\n ) public view returns (bytes32) {\n return\n keccak256(abi.encode(userOp.hash(), address(this), block.chainid));\n }\n\n /**\n * copy general fields from userOp into the memory opInfo structure.\n */\n function _copyUserOpToMemory(\n UserOperation calldata userOp,\n MemoryUserOp memory mUserOp\n ) internal pure {\n mUserOp.sender = userOp.sender;\n mUserOp.nonce = userOp.nonce;\n mUserOp.callGasLimit = userOp.callGasLimit;\n mUserOp.verificationGasLimit = userOp.verificationGasLimit;\n mUserOp.preVerificationGas = userOp.preVerificationGas;\n mUserOp.maxFeePerGas = userOp.maxFeePerGas;\n mUserOp.maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes calldata paymasterAndData = userOp.paymasterAndData;\n if (paymasterAndData.length > 0) {\n require(\n paymasterAndData.length >= 20,\n \"AA93 invalid paymasterAndData\"\n );\n mUserOp.paymaster = address(bytes20(paymasterAndData[:20]));\n } else {\n mUserOp.paymaster = address(0);\n }\n }\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external {\n UserOpInfo memory outOpInfo;\n\n _simulationOnlyValidations(userOp);\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(0, userOp, outOpInfo);\n StakeInfo memory paymasterInfo = _getStakeInfo(\n outOpInfo.mUserOp.paymaster\n );\n StakeInfo memory senderInfo = _getStakeInfo(outOpInfo.mUserOp.sender);\n StakeInfo memory factoryInfo;\n {\n bytes calldata initCode = userOp.initCode;\n address factory = initCode.length >= 20\n ? address(bytes20(initCode[0:20]))\n : address(0);\n factoryInfo = _getStakeInfo(factory);\n }\n\n ValidationData memory data = _intersectTimeRange(\n validationData,\n paymasterValidationData\n );\n address aggregator = data.aggregator;\n bool sigFailed = aggregator == address(1);\n ReturnInfo memory returnInfo = ReturnInfo(\n outOpInfo.preOpGas,\n outOpInfo.prefund,\n sigFailed,\n data.validAfter,\n data.validUntil,\n getMemoryBytesFromOffset(outOpInfo.contextOffset)\n );\n\n if (aggregator != address(0) && aggregator != address(1)) {\n AggregatorStakeInfo memory aggregatorInfo = AggregatorStakeInfo(\n aggregator,\n _getStakeInfo(aggregator)\n );\n revert ValidationResultWithAggregation(\n returnInfo,\n senderInfo,\n factoryInfo,\n paymasterInfo,\n aggregatorInfo\n );\n }\n revert ValidationResult(\n returnInfo,\n senderInfo,\n factoryInfo,\n paymasterInfo\n );\n }\n\n function _getRequiredPrefund(\n MemoryUserOp memory mUserOp\n ) internal pure returns (uint256 requiredPrefund) {\n unchecked {\n //when using a Paymaster, the verificationGasLimit is used also to as a limit for the postOp call.\n // our security model might call postOp eventually twice\n uint256 mul = mUserOp.paymaster != address(0) ? 3 : 1;\n uint256 requiredGas = mUserOp.callGasLimit +\n mUserOp.verificationGasLimit *\n mul +\n mUserOp.preVerificationGas;\n\n requiredPrefund = requiredGas * mUserOp.maxFeePerGas;\n }\n }\n\n // create the sender's contract if needed.\n function _createSenderIfNeeded(\n uint256 opIndex,\n UserOpInfo memory opInfo,\n bytes calldata initCode\n ) internal {\n if (initCode.length != 0) {\n address sender = opInfo.mUserOp.sender;\n if (sender.code.length != 0)\n revert FailedOp(opIndex, \"AA10 sender already constructed\");\n address sender1 = senderCreator.createSender{\n gas: opInfo.mUserOp.verificationGasLimit\n }(initCode);\n if (sender1 == address(0))\n revert FailedOp(opIndex, \"AA13 initCode failed or OOG\");\n if (sender1 != sender)\n revert FailedOp(opIndex, \"AA14 initCode must return sender\");\n if (sender1.code.length == 0)\n revert FailedOp(opIndex, \"AA15 initCode must create sender\");\n address factory = address(bytes20(initCode[0:20]));\n emit AccountDeployed(\n opInfo.userOpHash,\n sender,\n factory,\n opInfo.mUserOp.paymaster\n );\n }\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes calldata initCode) public {\n address sender = senderCreator.createSender(initCode);\n revert SenderAddressResult(sender);\n }\n\n function _simulationOnlyValidations(\n UserOperation calldata userOp\n ) internal view {\n // solhint-disable-next-line no-empty-blocks\n try\n this._validateSenderAndPaymaster(\n userOp.initCode,\n userOp.sender,\n userOp.paymasterAndData\n )\n {} catch Error(string memory revertReason) {\n if (bytes(revertReason).length != 0) {\n revert FailedOp(0, revertReason);\n }\n }\n }\n\n /**\n * Called only during simulation.\n * This function always reverts to prevent warm/cold storage differentiation in simulation vs execution.\n */\n function _validateSenderAndPaymaster(\n bytes calldata initCode,\n address sender,\n bytes calldata paymasterAndData\n ) external view {\n if (initCode.length == 0 && sender.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA20 account not deployed\");\n }\n if (paymasterAndData.length >= 20) {\n address paymaster = address(bytes20(paymasterAndData[0:20]));\n if (paymaster.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA30 paymaster not deployed\");\n }\n }\n // always revert\n revert(\"\");\n }\n\n /**\n * call account.validateUserOp.\n * revert (with FailedOp) in case validateUserOp reverts, or account didn't send required prefund.\n * decrement account's deposit if needed\n */\n function _validateAccountPrepayment(\n uint256 opIndex,\n UserOperation calldata op,\n UserOpInfo memory opInfo,\n uint256 requiredPrefund\n )\n internal\n returns (\n uint256 gasUsedByValidateAccountPrepayment,\n uint256 validationData\n )\n {\n unchecked {\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n address sender = mUserOp.sender;\n _createSenderIfNeeded(opIndex, opInfo, op.initCode);\n address paymaster = mUserOp.paymaster;\n numberMarker();\n uint256 missingAccountFunds = 0;\n if (paymaster == address(0)) {\n uint256 bal = balanceOf(sender);\n missingAccountFunds = bal > requiredPrefund\n ? 0\n : requiredPrefund - bal;\n }\n try\n IAccount(sender).validateUserOp{\n gas: mUserOp.verificationGasLimit\n }(op, opInfo.userOpHash, missingAccountFunds)\n returns (uint256 _validationData) {\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA23 reverted: \", revertReason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA23 reverted (or OOG)\");\n }\n if (paymaster == address(0)) {\n DepositInfo storage senderInfo = deposits[sender];\n uint256 deposit = senderInfo.deposit;\n if (requiredPrefund > deposit) {\n revert FailedOp(opIndex, \"AA21 didn't pay prefund\");\n }\n senderInfo.deposit = uint112(deposit - requiredPrefund);\n }\n gasUsedByValidateAccountPrepayment = preGas - gasleft();\n }\n }\n\n /**\n * In case the request has a paymaster:\n * Validate paymaster has enough deposit.\n * Call paymaster.validatePaymasterUserOp.\n * Revert with proper FailedOp in case paymaster reverts.\n * Decrement paymaster's deposit\n */\n function _validatePaymasterPrepayment(\n uint256 opIndex,\n UserOperation calldata op,\n UserOpInfo memory opInfo,\n uint256 requiredPreFund,\n uint256 gasUsedByValidateAccountPrepayment\n ) internal returns (bytes memory context, uint256 validationData) {\n unchecked {\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 verificationGasLimit = mUserOp.verificationGasLimit;\n require(\n verificationGasLimit > gasUsedByValidateAccountPrepayment,\n \"AA41 too little verificationGas\"\n );\n uint256 gas = verificationGasLimit -\n gasUsedByValidateAccountPrepayment;\n\n address paymaster = mUserOp.paymaster;\n DepositInfo storage paymasterInfo = deposits[paymaster];\n uint256 deposit = paymasterInfo.deposit;\n if (deposit < requiredPreFund) {\n revert FailedOp(opIndex, \"AA31 paymaster deposit too low\");\n }\n paymasterInfo.deposit = uint112(deposit - requiredPreFund);\n try\n IPaymaster(paymaster).validatePaymasterUserOp{gas: gas}(\n op,\n opInfo.userOpHash,\n requiredPreFund\n )\n returns (bytes memory _context, uint256 _validationData) {\n context = _context;\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA33 reverted: \", revertReason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA33 reverted (or OOG)\");\n }\n }\n }\n\n /**\n * revert if either account validationData or paymaster validationData is expired\n */\n function _validateAccountAndPaymasterValidationData(\n uint256 opIndex,\n uint256 validationData,\n uint256 paymasterValidationData,\n address expectedAggregator\n ) internal view {\n (address aggregator, bool outOfTimeRange) = _getValidationData(\n validationData\n );\n if (expectedAggregator != aggregator) {\n revert FailedOp(opIndex, \"AA24 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA22 expired or not due\");\n }\n //pmAggregator is not a real signature aggregator: we don't have logic to handle it as address.\n // non-zero address means that the paymaster fails due to some signature check (which is ok only during estimation)\n address pmAggregator;\n (pmAggregator, outOfTimeRange) = _getValidationData(\n paymasterValidationData\n );\n if (pmAggregator != address(0)) {\n revert FailedOp(opIndex, \"AA34 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA32 paymaster expired or not due\");\n }\n }\n\n function _getValidationData(\n uint256 validationData\n ) internal view returns (address aggregator, bool outOfTimeRange) {\n if (validationData == 0) {\n return (address(0), false);\n }\n ValidationData memory data = _parseValidationData(validationData);\n // solhint-disable-next-line not-rely-on-time\n outOfTimeRange =\n block.timestamp > data.validUntil ||\n block.timestamp < data.validAfter;\n aggregator = data.aggregator;\n }\n\n /**\n * validate account and paymaster (if defined).\n * also make sure total validation doesn't exceed verificationGasLimit\n * this method is called off-chain (simulateValidation()) and on-chain (from handleOps)\n * @param opIndex the index of this userOp into the \"opInfos\" array\n * @param userOp the userOp to validate\n */\n function _validatePrepayment(\n uint256 opIndex,\n UserOperation calldata userOp,\n UserOpInfo memory outOpInfo\n )\n private\n returns (uint256 validationData, uint256 paymasterValidationData)\n {\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = outOpInfo.mUserOp;\n _copyUserOpToMemory(userOp, mUserOp);\n outOpInfo.userOpHash = getUserOpHash(userOp);\n\n // validate all numeric values in userOp are well below 128 bit, so they can safely be added\n // and multiplied without causing overflow\n uint256 maxGasValues = mUserOp.preVerificationGas |\n mUserOp.verificationGasLimit |\n mUserOp.callGasLimit |\n userOp.maxFeePerGas |\n userOp.maxPriorityFeePerGas;\n require(maxGasValues <= type(uint120).max, \"AA94 gas values overflow\");\n\n uint256 gasUsedByValidateAccountPrepayment;\n uint256 requiredPreFund = _getRequiredPrefund(mUserOp);\n (\n gasUsedByValidateAccountPrepayment,\n validationData\n ) = _validateAccountPrepayment(\n opIndex,\n userOp,\n outOpInfo,\n requiredPreFund\n );\n\n if (!_validateAndUpdateNonce(mUserOp.sender, mUserOp.nonce)) {\n revert FailedOp(opIndex, \"AA25 invalid account nonce\");\n }\n\n //a \"marker\" where account opcode validation is done and paymaster opcode validation is about to start\n // (used only by off-chain simulateValidation)\n numberMarker();\n\n bytes memory context;\n if (mUserOp.paymaster != address(0)) {\n (context, paymasterValidationData) = _validatePaymasterPrepayment(\n opIndex,\n userOp,\n outOpInfo,\n requiredPreFund,\n gasUsedByValidateAccountPrepayment\n );\n }\n unchecked {\n uint256 gasUsed = preGas - gasleft();\n\n if (userOp.verificationGasLimit < gasUsed) {\n revert FailedOp(opIndex, \"AA40 over verificationGasLimit\");\n }\n outOpInfo.prefund = requiredPreFund;\n outOpInfo.contextOffset = getOffsetOfMemoryBytes(context);\n outOpInfo.preOpGas = preGas - gasleft() + userOp.preVerificationGas;\n }\n }\n\n /**\n * process post-operation.\n * called just after the callData is executed.\n * if a paymaster is defined and its validation returned a non-empty context, its postOp is called.\n * the excess amount is refunded to the account (or paymaster - if it was used in the request)\n * @param opIndex index in the batch\n * @param mode - whether is called from innerHandleOp, or outside (postOpReverted)\n * @param opInfo userOp fields and info collected during validation\n * @param context the context returned in validatePaymasterUserOp\n * @param actualGas the gas used so far by this user operation\n */\n function _handlePostOp(\n uint256 opIndex,\n IPaymaster.PostOpMode mode,\n UserOpInfo memory opInfo,\n bytes memory context,\n uint256 actualGas\n ) private returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n unchecked {\n address refundAddress;\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 gasPrice = getUserOpGasPrice(mUserOp);\n\n address paymaster = mUserOp.paymaster;\n if (paymaster == address(0)) {\n refundAddress = mUserOp.sender;\n } else {\n refundAddress = paymaster;\n if (context.length > 0) {\n actualGasCost = actualGas * gasPrice;\n if (mode != IPaymaster.PostOpMode.postOpReverted) {\n IPaymaster(paymaster).postOp{\n gas: mUserOp.verificationGasLimit\n }(mode, context, actualGasCost);\n } else {\n // solhint-disable-next-line no-empty-blocks\n try\n IPaymaster(paymaster).postOp{\n gas: mUserOp.verificationGasLimit\n }(mode, context, actualGasCost)\n {} catch Error(string memory reason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA50 postOp reverted: \", reason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA50 postOp revert\");\n }\n }\n }\n }\n actualGas += preGas - gasleft();\n actualGasCost = actualGas * gasPrice;\n if (opInfo.prefund < actualGasCost) {\n revert FailedOp(opIndex, \"AA51 prefund below actualGasCost\");\n }\n uint256 refund = opInfo.prefund - actualGasCost;\n _incrementDeposit(refundAddress, refund);\n bool success = mode == IPaymaster.PostOpMode.opSucceeded;\n emit UserOperationEvent(\n opInfo.userOpHash,\n mUserOp.sender,\n mUserOp.paymaster,\n mUserOp.nonce,\n success,\n actualGasCost,\n actualGas\n );\n } // unchecked\n }\n\n /**\n * the gas price this UserOp agrees to pay.\n * relayer/block builder might submit the TX with higher priorityFee, but the user should not\n */\n function getUserOpGasPrice(\n MemoryUserOp memory mUserOp\n ) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = mUserOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = mUserOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n function getOffsetOfMemoryBytes(\n bytes memory data\n ) internal pure returns (uint256 offset) {\n assembly {\n offset := data\n }\n }\n\n function getMemoryBytesFromOffset(\n uint256 offset\n ) internal pure returns (bytes memory data) {\n assembly {\n data := offset\n }\n }\n\n //place the NUMBER opcode in the code.\n // this is used as a marker during simulation, as this OP is completely banned from the simulated code of the\n // account and paymaster.\n function numberMarker() internal view {\n assembly {\n mstore(0, number())\n }\n }\n}\n" + }, + "contracts/aa-4337/core/Helpers.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable no-inline-assembly */\n\n/**\n * returned data from validateUserOp.\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\n * @param aggregator - address(0) - the account validated the signature by itself.\n * address(1) - the account failed to validate the signature.\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\n * @param validAfter - this UserOp is valid only after this timestamp.\n * @param validaUntil - this UserOp is valid only up to this timestamp.\n */\nstruct ValidationData {\n address aggregator;\n uint48 validAfter;\n uint48 validUntil;\n}\n\n//extract sigFailed, validAfter, validUntil.\n// also convert zero validUntil to type(uint48).max\nfunction _parseValidationData(\n uint validationData\n) pure returns (ValidationData memory data) {\n address aggregator = address(uint160(validationData));\n uint48 validUntil = uint48(validationData >> 160);\n if (validUntil == 0) {\n validUntil = type(uint48).max;\n }\n uint48 validAfter = uint48(validationData >> (48 + 160));\n return ValidationData(aggregator, validAfter, validUntil);\n}\n\n// intersect account and paymaster ranges.\nfunction _intersectTimeRange(\n uint256 validationData,\n uint256 paymasterValidationData\n) pure returns (ValidationData memory) {\n ValidationData memory accountValidationData = _parseValidationData(\n validationData\n );\n ValidationData memory pmValidationData = _parseValidationData(\n paymasterValidationData\n );\n address aggregator = accountValidationData.aggregator;\n if (aggregator == address(0)) {\n aggregator = pmValidationData.aggregator;\n }\n uint48 validAfter = accountValidationData.validAfter;\n uint48 validUntil = accountValidationData.validUntil;\n uint48 pmValidAfter = pmValidationData.validAfter;\n uint48 pmValidUntil = pmValidationData.validUntil;\n\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\n return ValidationData(aggregator, validAfter, validUntil);\n}\n\n/**\n * helper to pack the return value for validateUserOp\n * @param data - the ValidationData to pack\n */\nfunction _packValidationData(\n ValidationData memory data\n) pure returns (uint256) {\n return\n uint160(data.aggregator) |\n (uint256(data.validUntil) << 160) |\n (uint256(data.validAfter) << (160 + 48));\n}\n\n/**\n * helper to pack the return value for validateUserOp, when not using an aggregator\n * @param sigFailed - true for signature failure, false for success\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\n * @param validAfter first timestamp this UserOperation is valid\n */\nfunction _packValidationData(\n bool sigFailed,\n uint48 validUntil,\n uint48 validAfter\n) pure returns (uint256) {\n return\n (sigFailed ? 1 : 0) |\n (uint256(validUntil) << 160) |\n (uint256(validAfter) << (160 + 48));\n}\n\n/**\n * keccak function over calldata.\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\n */\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\n assembly {\n let mem := mload(0x40)\n let len := data.length\n calldatacopy(mem, data.offset, len)\n ret := keccak256(mem, len)\n }\n}\n" + }, + "contracts/aa-4337/core/NonceManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\nimport \"../interfaces/IEntryPoint.sol\";\n\n/**\n * nonce management functionality\n */\ncontract NonceManager is INonceManager {\n /**\n * The next valid sequence number for a given nonce key.\n */\n mapping(address => mapping(uint192 => uint256)) public nonceSequenceNumber;\n\n function getNonce(\n address sender,\n uint192 key\n ) public view override returns (uint256 nonce) {\n return nonceSequenceNumber[sender][key] | (uint256(key) << 64);\n }\n\n // allow an account to manually increment its own nonce.\n // (mainly so that during construction nonce can be made non-zero,\n // to \"absorb\" the gas cost of first nonce increment to 1st transaction (construction),\n // not to 2nd transaction)\n function incrementNonce(uint192 key) public override {\n nonceSequenceNumber[msg.sender][key]++;\n }\n\n /**\n * validate nonce uniqueness for this account.\n * called just after validateUserOp()\n */\n function _validateAndUpdateNonce(\n address sender,\n uint256 nonce\n ) internal returns (bool) {\n uint192 key = uint192(nonce >> 64);\n uint64 seq = uint64(nonce);\n return nonceSequenceNumber[sender][key]++ == seq;\n }\n}\n" + }, + "contracts/aa-4337/core/SenderCreator.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/**\n * helper contract for EntryPoint, to call userOp.initCode from a \"neutral\" address,\n * which is explicitly not the entryPoint itself.\n */\ncontract SenderCreator {\n /**\n * call the \"initCode\" factory to create and return the sender account address\n * @param initCode the initCode value from a UserOp. contains 20 bytes of factory address, followed by calldata\n * @return sender the returned address of the created account, or zero address on failure.\n */\n function createSender(\n bytes calldata initCode\n ) external returns (address sender) {\n address factory = address(bytes20(initCode[0:20]));\n bytes memory initCallData = initCode[20:];\n bool success;\n /* solhint-disable no-inline-assembly */\n assembly {\n success := call(\n gas(),\n factory,\n 0,\n add(initCallData, 0x20),\n mload(initCallData),\n 0,\n 32\n )\n sender := mload(0)\n }\n if (!success) {\n sender = address(0);\n }\n }\n}\n" + }, + "contracts/aa-4337/core/StakeManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity 0.8.21;\n\nimport \"../interfaces/IStakeManager.sol\";\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable not-rely-on-time */\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by a paymaster.\n */\nabstract contract StakeManager is IStakeManager {\n /// maps paymaster to their deposits and stakes\n mapping(address => DepositInfo) public deposits;\n\n /// @inheritdoc IStakeManager\n function getDepositInfo(\n address account\n ) public view returns (DepositInfo memory info) {\n return deposits[account];\n }\n\n // internal method to return just the stake info\n function _getStakeInfo(\n address addr\n ) internal view returns (StakeInfo memory info) {\n DepositInfo storage depositInfo = deposits[addr];\n info.stake = depositInfo.stake;\n info.unstakeDelaySec = depositInfo.unstakeDelaySec;\n }\n\n /// return the deposit (for gas payment) of the account\n function balanceOf(address account) public view returns (uint256) {\n return deposits[account].deposit;\n }\n\n receive() external payable {\n depositTo(msg.sender);\n }\n\n function _incrementDeposit(address account, uint256 amount) internal {\n DepositInfo storage info = deposits[account];\n uint256 newAmount = info.deposit + amount;\n require(newAmount <= type(uint112).max, \"deposit overflow\");\n info.deposit = uint112(newAmount);\n }\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) public payable {\n _incrementDeposit(account, msg.value);\n DepositInfo storage info = deposits[account];\n emit Deposited(account, info.deposit);\n }\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 unstakeDelaySec) public payable {\n DepositInfo storage info = deposits[msg.sender];\n require(unstakeDelaySec > 0, \"must specify unstake delay\");\n require(\n unstakeDelaySec >= info.unstakeDelaySec,\n \"cannot decrease unstake time\"\n );\n uint256 stake = info.stake + msg.value;\n require(stake > 0, \"no stake specified\");\n require(stake <= type(uint112).max, \"stake overflow\");\n deposits[msg.sender] = DepositInfo(\n info.deposit,\n true,\n uint112(stake),\n unstakeDelaySec,\n 0\n );\n emit StakeLocked(msg.sender, stake, unstakeDelaySec);\n }\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external {\n DepositInfo storage info = deposits[msg.sender];\n require(info.unstakeDelaySec != 0, \"not staked\");\n require(info.staked, \"already unstaking\");\n uint48 withdrawTime = uint48(block.timestamp) + info.unstakeDelaySec;\n info.withdrawTime = withdrawTime;\n info.staked = false;\n emit StakeUnlocked(msg.sender, withdrawTime);\n }\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external {\n DepositInfo storage info = deposits[msg.sender];\n uint256 stake = info.stake;\n require(stake > 0, \"No stake to withdraw\");\n require(info.withdrawTime > 0, \"must call unlockStake() first\");\n require(\n info.withdrawTime <= block.timestamp,\n \"Stake withdrawal is not due\"\n );\n info.unstakeDelaySec = 0;\n info.withdrawTime = 0;\n info.stake = 0;\n emit StakeWithdrawn(msg.sender, withdrawAddress, stake);\n (bool success, ) = withdrawAddress.call{value: stake}(\"\");\n require(success, \"failed to withdraw stake\");\n }\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(\n address payable withdrawAddress,\n uint256 withdrawAmount\n ) external {\n DepositInfo storage info = deposits[msg.sender];\n require(withdrawAmount <= info.deposit, \"Withdraw amount too large\");\n info.deposit = uint112(info.deposit - withdrawAmount);\n emit Withdrawn(msg.sender, withdrawAddress, withdrawAmount);\n (bool success, ) = withdrawAddress.call{value: withdrawAmount}(\"\");\n require(success, \"failed to withdraw\");\n }\n}\n" + }, + "contracts/aa-4337/interfaces/IAccount.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\ninterface IAccount {\n /**\n * Validate user's signature and nonce\n * the entryPoint will make the call to the recipient only if this validation call returns successfully.\n * signature failure should be reported by returning SIG_VALIDATION_FAILED (1).\n * This allows making a \"simulation call\" without a valid signature\n * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure.\n *\n * @dev Must validate caller is the entryPoint.\n * Must validate the signature and nonce\n * @param userOp the operation that is about to be executed.\n * @param userOpHash hash of the user's request data. can be used as the basis for signature.\n * @param missingAccountFunds missing funds on the account's deposit in the entrypoint.\n * This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call.\n * The excess is left as a deposit in the entrypoint, for future calls.\n * can be withdrawn anytime using \"entryPoint.withdrawTo()\"\n * In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero.\n * @return validationData packaged ValidationData structure. use `_packValidationData` and `_unpackValidationData` to encode and decode\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * If an account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validateUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 missingAccountFunds\n ) external returns (uint256 validationData);\n}\n" + }, + "contracts/aa-4337/interfaces/IAggregator.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * Aggregated Signatures validator.\n */\ninterface IAggregator {\n /**\n * validate aggregated signature.\n * revert if the aggregated signature does not match the given list of operations.\n */\n function validateSignatures(\n UserOperation[] calldata userOps,\n bytes calldata signature\n ) external view;\n\n /**\n * validate signature of a single userOp\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\n * @param userOp the userOperation received from the user.\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\n * (usually empty, unless account and aggregator support some kind of \"multisig\"\n */\n function validateUserOpSignature(\n UserOperation calldata userOp\n ) external view returns (bytes memory sigForUserOp);\n\n /**\n * aggregate multiple signatures into a single value.\n * This method is called off-chain to calculate the signature to pass with handleOps()\n * bundler MAY use optimized custom code perform this aggregation\n * @param userOps array of UserOperations to collect the signatures from.\n * @return aggregatedSignature the aggregated signature\n */\n function aggregateSignatures(\n UserOperation[] calldata userOps\n ) external view returns (bytes memory aggregatedSignature);\n}\n" + }, + "contracts/aa-4337/interfaces/IEntryPoint.sol": { + "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n/* solhint-disable reason-string */\n\nimport \"./UserOperation.sol\";\nimport \"./IStakeManager.sol\";\nimport \"./IAggregator.sol\";\nimport \"./INonceManager.sol\";\n\ninterface IEntryPoint is IStakeManager, INonceManager {\n /***\n * An event emitted after each successful request\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\n * @param sender - the account that generates this request.\n * @param paymaster - if non-null, the paymaster that pays for this request.\n * @param nonce - the nonce value from the request.\n * @param success - true if the sender transaction succeeded, false if reverted.\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\n */\n event UserOperationEvent(\n bytes32 indexed userOpHash,\n address indexed sender,\n address indexed paymaster,\n uint256 nonce,\n bool success,\n uint256 actualGasCost,\n uint256 actualGasUsed\n );\n\n /**\n * account \"sender\" was deployed.\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\n * @param sender the account that is deployed\n * @param factory the factory used to deploy this account (in the initCode)\n * @param paymaster the paymaster used by this UserOp\n */\n event AccountDeployed(\n bytes32 indexed userOpHash,\n address indexed sender,\n address factory,\n address paymaster\n );\n\n /**\n * An event emitted if the UserOperation \"callData\" reverted with non-zero length\n * @param userOpHash the request unique identifier.\n * @param sender the sender of this request\n * @param nonce the nonce used in the request\n * @param revertReason - the return bytes from the (reverted) call to \"callData\".\n */\n event UserOperationRevertReason(\n bytes32 indexed userOpHash,\n address indexed sender,\n uint256 nonce,\n bytes revertReason\n );\n\n /**\n * an event emitted by handleOps(), before starting the execution loop.\n * any event emitted before this event, is part of the validation.\n */\n event BeforeExecution();\n\n /**\n * signature aggregator used by the following UserOperationEvents within this bundle.\n */\n event SignatureAggregatorChanged(address indexed aggregator);\n\n /**\n * a custom revert error of handleOps, to identify the offending op.\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\n * @param reason - revert reason\n * The string starts with a unique code \"AAmn\", where \"m\" is \"1\" for factory, \"2\" for account and \"3\" for paymaster issues,\n * so a failure can be attributed to the correct entity.\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\n */\n error FailedOp(uint256 opIndex, string reason);\n\n /**\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\n */\n error SignatureValidationFailed(address aggregator);\n\n /**\n * Successful result from simulateValidation.\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n */\n error ValidationResult(\n ReturnInfo returnInfo,\n StakeInfo senderInfo,\n StakeInfo factoryInfo,\n StakeInfo paymasterInfo\n );\n\n /**\n * Successful result from simulateValidation, if the account returns a signature aggregator\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\n * bundler MUST use it to verify the signature, or reject the UserOperation\n */\n error ValidationResultWithAggregation(\n ReturnInfo returnInfo,\n StakeInfo senderInfo,\n StakeInfo factoryInfo,\n StakeInfo paymasterInfo,\n AggregatorStakeInfo aggregatorInfo\n );\n\n /**\n * return value of getSenderAddress\n */\n error SenderAddressResult(address sender);\n\n /**\n * return value of simulateHandleOp\n */\n error ExecutionResult(\n uint256 preOpGas,\n uint256 paid,\n uint48 validAfter,\n uint48 validUntil,\n bool targetSuccess,\n bytes targetResult\n );\n\n //UserOps handled, per aggregator\n struct UserOpsPerAggregator {\n UserOperation[] userOps;\n // aggregator address\n IAggregator aggregator;\n // aggregated signature\n bytes signature;\n }\n\n /**\n * Execute a batch of UserOperation.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(\n UserOperation[] calldata ops,\n address payable beneficiary\n ) external;\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) external;\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(\n UserOperation calldata userOp\n ) external view returns (bytes32);\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external;\n\n /**\n * gas and return values during simulation\n * @param preOpGas the gas used for validation (including preValidationGas)\n * @param prefund the required prefund for this operation\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\n */\n struct ReturnInfo {\n uint256 preOpGas;\n uint256 prefund;\n bool sigFailed;\n uint48 validAfter;\n uint48 validUntil;\n bytes paymasterContext;\n }\n\n /**\n * returned aggregated signature info.\n * the aggregator returned by the account, and its current stake.\n */\n struct AggregatorStakeInfo {\n address aggregator;\n StakeInfo stakeInfo;\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes memory initCode) external;\n\n /**\n * simulate full execution of a UserOperation (including both validation and target execution)\n * this method will always revert with \"ExecutionResult\".\n * it performs full validation of the UserOperation, but ignores signature error.\n * an optional target address is called after the userop succeeds, and its value is returned\n * (before the entire call is reverted)\n * Note that in order to collect the the success/failure of the target call, it must be executed\n * with trace enabled to track the emitted events.\n * @param op the UserOperation to simulate\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\n * are set to the return from that call.\n * @param targetCallData callData to pass to target address\n */\n function simulateHandleOp(\n UserOperation calldata op,\n address target,\n bytes calldata targetCallData\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/INonceManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\ninterface INonceManager {\n /**\n * Return the next nonce for this sender.\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\n * But UserOp with different keys can come with arbitrary order.\n *\n * @param sender the account address\n * @param key the high 192 bit of the nonce\n * @return nonce a full nonce to pass for next UserOp with this sender.\n */\n function getNonce(\n address sender,\n uint192 key\n ) external view returns (uint256 nonce);\n\n /**\n * Manually increment the nonce of the sender.\n * This method is exposed just for completeness..\n * Account does NOT need to call it, neither during validation, nor elsewhere,\n * as the EntryPoint will update the nonce regardless.\n * Possible use-case is call it with various keys to \"initialize\" their nonces to one, so that future\n * UserOperations will not pay extra for the first transaction with a given key.\n */\n function incrementNonce(uint192 key) external;\n}\n" + }, + "contracts/aa-4337/interfaces/IPaymaster.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * the interface exposed by a paymaster contract, who agrees to pay the gas for user's operations.\n * a paymaster must hold a stake to cover the required entrypoint stake and also the gas for the transaction.\n */\ninterface IPaymaster {\n enum PostOpMode {\n opSucceeded, // user op succeeded\n opReverted, // user op reverted. still has to pay for gas.\n postOpReverted //user op succeeded, but caused postOp to revert. Now it's a 2nd call, after user's op was deliberately reverted.\n }\n\n /**\n * payment validation: check if paymaster agrees to pay.\n * Must verify sender is the entryPoint.\n * Revert to reject this request.\n * Note that bundlers will reject this method if it changes the state, unless the paymaster is trusted (whitelisted)\n * The paymaster pre-pays using its deposit, and receive back a refund after the postOp method returns.\n * @param userOp the user operation\n * @param userOpHash hash of the user's request data.\n * @param maxCost the maximum cost of this transaction (based on maximum gas and gas price from userOp)\n * @return context value to send to a postOp\n * zero length to signify postOp is not required.\n * @return validationData signature and time-range of this operation, encoded the same as the return value of validateUserOperation\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validatePaymasterUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 maxCost\n ) external returns (bytes memory context, uint256 validationData);\n\n /**\n * post-operation handler.\n * Must verify sender is the entryPoint\n * @param mode enum with the following options:\n * opSucceeded - user operation succeeded.\n * opReverted - user op reverted. still has to pay for gas.\n * postOpReverted - user op succeeded, but caused postOp (in mode=opSucceeded) to revert.\n * Now this is the 2nd call, after user's op was deliberately reverted.\n * @param context - the context value returned by validatePaymasterUserOp\n * @param actualGasCost - actual gas used so far (without this postOp call).\n */\n function postOp(\n PostOpMode mode,\n bytes calldata context,\n uint256 actualGasCost\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/IStakeManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.12;\n\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by the staked entity.\n */\ninterface IStakeManager {\n event Deposited(address indexed account, uint256 totalDeposit);\n\n event Withdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /// Emitted when stake or unstake delay are modified\n event StakeLocked(\n address indexed account,\n uint256 totalStaked,\n uint256 unstakeDelaySec\n );\n\n /// Emitted once a stake is scheduled for withdrawal\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\n\n event StakeWithdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /**\n * @param deposit the entity's deposit\n * @param staked true if this entity is staked.\n * @param stake actual amount of ether staked for this entity.\n * @param unstakeDelaySec minimum delay to withdraw the stake.\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\n * and the rest fit into a 2nd cell.\n * 112 bit allows for 10^15 eth\n * 48 bit for full timestamp\n * 32 bit allows 150 years for unstake delay\n */\n struct DepositInfo {\n uint112 deposit;\n bool staked;\n uint112 stake;\n uint32 unstakeDelaySec;\n uint48 withdrawTime;\n }\n\n //API struct used by getStakeInfo and simulateValidation\n struct StakeInfo {\n uint256 stake;\n uint256 unstakeDelaySec;\n }\n\n /// @return info - full deposit information of given account\n function getDepositInfo(\n address account\n ) external view returns (DepositInfo memory info);\n\n /// @return the deposit (for gas payment) of the account\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) external payable;\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 _unstakeDelaySec) external payable;\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external;\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external;\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(\n address payable withdrawAddress,\n uint256 withdrawAmount\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/UserOperation.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable no-inline-assembly */\n\nimport {calldataKeccak} from \"../core/Helpers.sol\";\n\n/**\n * User Operation struct\n * @param sender the sender account of this request.\n * @param nonce unique value the sender uses to verify it is not a replay.\n * @param initCode if set, the account contract will be created by this constructor/\n * @param callData the method call to execute on this account.\n * @param callGasLimit the gas limit passed to the callData method call.\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\n * @param maxFeePerGas same as EIP-1559 gas parameter.\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\n */\nstruct UserOperation {\n address sender;\n uint256 nonce;\n bytes initCode;\n bytes callData;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n bytes paymasterAndData;\n bytes signature;\n}\n\n/**\n * Utility functions helpful when working with UserOperation structs.\n */\nlibrary UserOperationLib {\n function getSender(\n UserOperation calldata userOp\n ) internal pure returns (address) {\n address data;\n //read sender from userOp, which is first userOp member (saves 800 gas...)\n assembly {\n data := calldataload(userOp)\n }\n return address(uint160(data));\n }\n\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\n // pay above what he signed for.\n function gasPrice(\n UserOperation calldata userOp\n ) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function pack(\n UserOperation calldata userOp\n ) internal pure returns (bytes memory ret) {\n address sender = getSender(userOp);\n uint256 nonce = userOp.nonce;\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\n bytes32 hashCallData = calldataKeccak(userOp.callData);\n uint256 callGasLimit = userOp.callGasLimit;\n uint256 verificationGasLimit = userOp.verificationGasLimit;\n uint256 preVerificationGas = userOp.preVerificationGas;\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\n\n return\n abi.encode(\n sender,\n nonce,\n hashInitCode,\n hashCallData,\n callGasLimit,\n verificationGasLimit,\n preVerificationGas,\n maxFeePerGas,\n maxPriorityFeePerGas,\n hashPaymasterAndData\n );\n }\n\n function hash(\n UserOperation calldata userOp\n ) internal pure returns (bytes32) {\n return keccak256(pack(userOp));\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n}\n" + }, + "contracts/aa-4337/utils/Exec.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.5 <0.9.0;\n\n// solhint-disable no-inline-assembly\n\n/**\n * Utility functions helpful when making different kinds of contract calls in Solidity.\n */\nlibrary Exec {\n function call(\n address to,\n uint256 value,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := call(\n txGas,\n to,\n value,\n add(data, 0x20),\n mload(data),\n 0,\n 0\n )\n }\n }\n\n function staticcall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal view returns (bool success) {\n assembly {\n success := staticcall(txGas, to, add(data, 0x20), mload(data), 0, 0)\n }\n }\n\n function delegateCall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := delegatecall(\n txGas,\n to,\n add(data, 0x20),\n mload(data),\n 0,\n 0\n )\n }\n }\n\n // get returned data from last call or calldelegate\n function getReturnData(\n uint256 maxLen\n ) internal pure returns (bytes memory returnData) {\n assembly {\n let len := returndatasize()\n if gt(len, maxLen) {\n len := maxLen\n }\n let ptr := mload(0x40)\n mstore(0x40, add(ptr, add(len, 0x20)))\n mstore(ptr, len)\n returndatacopy(add(ptr, 0x20), 0, len)\n returnData := ptr\n }\n }\n\n // revert with explicit byte array (probably reverted info from call)\n function revertWithData(bytes memory returnData) internal pure {\n assembly {\n revert(add(returnData, 32), mload(returnData))\n }\n }\n\n function callAndRevert(\n address to,\n bytes memory data,\n uint256 maxLen\n ) internal {\n bool success = call(to, 0, data, gasleft());\n if (!success) {\n revertWithData(getReturnData(maxLen));\n }\n }\n}\n" + }, + "contracts/Barz.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"./libraries/LibDiamond.sol\";\nimport {IBarz} from \"./interfaces/IBarz.sol\";\n\n/**\n * @title Barz\n * @dev A diamond proxy wallet with a modular & upgradeable architecture\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract Barz is IBarz {\n /**\n * @notice Initializes Barz with the given parameters. Barz account is intended to be created from Barz Factory for stable deployment.\n * @dev This method makes a delegate call to account facet and account facet handles the initialization.\n * With modular architecture, Barz encompasses wide spectrum of architecture and logic.\n * The only requirement is account facet to comply with initialize() interface.\n * Barz doesn't include built-in functions and is a full proxy, for maximum extensibility and modularity.\n * @param _accountFacet Address of Account Facet in charge of the Barz initialization\n * @param _verificationFacet Address of Verification Facet for verifying the signature. Could be any signature scheme\n * @param _entryPoint Address of Entry Point contract\n * @param _facetRegistry Address of Facet Registry. Facet Registry is a registry holding trusted facets that could be added to user's wallet\n * @param _defaultFallBack Address of Default FallBack Handler. Middleware contract for more efficient deployment\n * @param _ownerPublicKey Bytes of Owner Public Key using for initialization\n */\n constructor(\n address _accountFacet,\n address _verificationFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallBack,\n bytes memory _ownerPublicKey\n ) payable {\n bytes memory initCall = abi.encodeWithSignature(\n \"initialize(address,address,address,address,bytes)\",\n _verificationFacet,\n _entryPoint,\n _facetRegistry,\n _defaultFallBack,\n _ownerPublicKey\n );\n (bool success, bytes memory result) = _accountFacet.delegatecall(\n initCall\n );\n if (!success || uint256(bytes32(result)) != 1) {\n revert Barz__InitializationFailure();\n }\n }\n\n /**\n * @notice Fallback function for Barz complying with Diamond Standard with customization of adding Default Fallback Handler\n * @dev Find facet for function that is called and execute the function if a facet is found and return any value.\n */\n fallback() external payable {\n LibDiamond.DiamondStorage storage ds;\n bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION;\n // get diamond storage\n assembly {\n ds.slot := position\n }\n // get facet from function selector\n address facet = address(bytes20(ds.facets[msg.sig]));\n if (facet == address(0))\n facet = ds.defaultFallbackHandler.facetAddress(msg.sig);\n require(facet != address(0), \"Barz: Function does not exist\");\n // Execute external function from facet using delegatecall and return any value.\n assembly {\n // copy function selector and any arguments\n calldatacopy(0, 0, calldatasize())\n // execute function call using the facet\n let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)\n // get any return value\n returndatacopy(0, 0, returndatasize())\n // return any return value or error back to the caller\n switch result\n case 0 {\n revert(0, returndatasize())\n }\n default {\n return(0, returndatasize())\n }\n }\n }\n\n /**\n * @notice Receive function to receive native token without data\n */\n receive() external payable {}\n}\n" + }, + "contracts/BarzFactory.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Barz} from \"./Barz.sol\";\nimport {IBarzFactory} from \"./interfaces/IBarzFactory.sol\";\n\n/**\n * @title Barz Factory\n * @dev Contract to easily deploy Barz to a pre-computed address with a single call\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract BarzFactory is IBarzFactory {\n address public immutable accountFacet;\n address public immutable entryPoint;\n address public immutable facetRegistry;\n address public immutable defaultFallback;\n\n /**\n * @notice Sets the initialization data for Barz contract initialization\n * @param _accountFacet Account Facet to be used to create Barz\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\n * @param _facetRegistry Facet Registry to be used to create Barz\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\n */\n constructor(\n address _accountFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallback\n ) {\n accountFacet = _accountFacet;\n entryPoint = _entryPoint;\n facetRegistry = _facetRegistry;\n defaultFallback = _defaultFallback;\n }\n\n /**\n * @notice Creates the Barz with a single call. It creates the Barz contract with the givent verification facet\n * @param _verificationFacet Address of verification facet used for creating the barz account\n * @param _owner Public Key of the owner to initialize barz account\n * @param _salt Salt used for deploying barz with create2\n * @return barz Instance of Barz contract deployed with the given parameters\n */\n function createAccount(\n address _verificationFacet,\n bytes calldata _owner,\n uint256 _salt\n ) external override returns (Barz barz) {\n address addr = getAddress(_verificationFacet, _owner, _salt);\n uint codeSize = addr.code.length;\n if (codeSize > 0) {\n return Barz(payable(addr));\n }\n barz = new Barz{salt: bytes32(_salt)}(\n accountFacet,\n _verificationFacet,\n entryPoint,\n facetRegistry,\n defaultFallback,\n _owner\n );\n emit BarzDeployed(address(barz));\n }\n\n /**\n * @notice Calculates the address of Barz with the given parameters\n * @param _verificationFacet Address of verification facet used for creating the barz account\n * @param _owner Public Key of the owner to initialize barz account\n * @param _salt Salt used for deploying barz with create2\n * @return barzAddress Precalculated Barz address\n */\n function getAddress(\n address _verificationFacet,\n bytes calldata _owner,\n uint256 _salt\n ) public view override returns (address barzAddress) {\n bytes memory bytecode = getBytecode(\n accountFacet,\n _verificationFacet,\n entryPoint,\n facetRegistry,\n defaultFallback,\n _owner\n );\n bytes32 hash = keccak256(\n abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(bytecode)\n )\n );\n barzAddress = address(uint160(uint256(hash)));\n }\n\n /**\n * @notice Returns the bytecode of Barz with the given parameter\n * @param _accountFacet Account Facet to be used to create Barz\n * @param _verificationFacet Verification Facet to be used to create Barz\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\n * @param _facetRegistry Facet Registry to be used to create Barz\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\n * @param _ownerPublicKey Public Key of owner to be used to initialize Barz ownership\n * @return barzBytecode Bytecode of Barz\n */\n function getBytecode(\n address _accountFacet,\n address _verificationFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallback,\n bytes calldata _ownerPublicKey\n ) public pure override returns (bytes memory barzBytecode) {\n bytes memory bytecode = type(Barz).creationCode;\n barzBytecode = abi.encodePacked(\n bytecode,\n abi.encode(\n _accountFacet,\n _verificationFacet,\n _entryPoint,\n _facetRegistry,\n _defaultFallback,\n _ownerPublicKey\n )\n );\n }\n\n /**\n * @notice Returns the creation code of the Barz contract\n * @return creationCode Creation code of Barz\n */\n function getCreationCode()\n public\n pure\n override\n returns (bytes memory creationCode)\n {\n creationCode = type(Barz).creationCode;\n }\n}\n" + }, + "contracts/facets/AccountFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {UserOperation} from \"../aa-4337/interfaces/UserOperation.sol\";\nimport {IEntryPoint} from \"../aa-4337/interfaces/IEntryPoint.sol\";\nimport {BaseAccount} from \"../aa-4337/core/BaseAccount.sol\";\nimport {LibAppStorage, BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {IFacetRegistry} from \"../infrastructure/interfaces/IFacetRegistry.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {IERC1271} from \"../interfaces/ERC/IERC1271.sol\";\nimport {IAccountFacet} from \"./interfaces/IAccountFacet.sol\";\n\n/**\n * @title Account Facet\n * @dev Account module contract that provides the account features and initialization of signer\n * compatible with EIP-1271 & EIP-4337\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract AccountFacet is IAccountFacet, BarzStorage, BaseAccount {\n using ECDSA for bytes32;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceAccountInitialize();\n }\n\n /**\n * @notice Returns the address of EntryPoint contract registered to Barz account\n */\n function entryPoint() public view override returns (IEntryPoint) {\n return s.entryPoint;\n }\n\n /**\n * @notice Initializes the initial storage of the Barz contract.\n * @dev This method can only be called during the initialization or signature migration.\n * If the proxy contract was created without initialization, anyone can call initialize.\n * Barz calls initialize in constructor in an atomic transaction during deployment\n * @param _verificationFacet Facet contract handling the verificationi\n * @param _anEntryPoint Entrypoint contract defined in EIP-4337 handling the flow of UserOp\n * @param _facetRegistry Registry of Facets that hold all facet information\n * @param _defaultFallBackHandler Middleware contract for default facets\n * @param _ownerPublicKey Bytes of owner public key\n */\n function initialize(\n address _verificationFacet,\n address _anEntryPoint,\n address _facetRegistry,\n address _defaultFallBackHandler,\n bytes calldata _ownerPublicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceAccountInitialize();\n s.entryPoint = IEntryPoint(_anEntryPoint);\n s.facetRegistry = IFacetRegistry(_facetRegistry);\n LibDiamond.diamondStorage().defaultFallbackHandler = IDiamondLoupe(\n _defaultFallBackHandler\n );\n\n _cutDiamondAccountFacet(_verificationFacet);\n\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n _ownerPublicKey\n );\n // Every Verification Facet should comply with initializeSigner(bytes)\n // to be compatible with the Barz contract(for initialization)\n (bool success, bytes memory result) = _verificationFacet.delegatecall(\n initCall\n );\n if (!success || uint256(bytes32(result)) != 1) {\n revert AccountFacet__InitializationFailure();\n }\n\n initSuccess = 1;\n emit AccountInitialized(s.entryPoint, _ownerPublicKey);\n }\n\n function _cutDiamondAccountFacet(address _verificationFacet) internal {\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](1);\n\n bytes4 ownerVerificationFuncSelector = IVerificationFacet(\n _verificationFacet\n ).validateOwnerSignatureSelector();\n\n bytes4[] memory verificationFunctionSelectors = new bytes4[](3);\n verificationFunctionSelectors[0] = IERC1271.isValidSignature.selector;\n verificationFunctionSelectors[1] = ownerVerificationFuncSelector;\n verificationFunctionSelectors[2] = IVerificationFacet.owner.selector;\n cut[0] = IDiamondCut.FacetCut({\n facetAddress: _verificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: verificationFunctionSelectors\n });\n\n LibDiamond.diamondCut(cut, address(0), \"\");\n }\n\n /**\n * @notice Calls the destination with inputted calldata and value from EntryPoint\n * @dev This method executes the calldata coming from the EntryPoint.\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\n * @param _dest Address of destination where the call will be forwarded to\n * @param _value Amount of native coin the owner is willing to send(e.g. ETH, BNB)\n * @param _func Bytes of calldata to execute in the destination address\n */\n function execute(\n address _dest,\n uint256 _value,\n bytes calldata _func\n ) external override onlyWhenUnlocked {\n _requireFromEntryPoint();\n address restrictionsFacet = LibDiamond.restrictionsFacet();\n if (restrictionsFacet == address(0)) _call(_dest, _value, _func);\n else _callWithRestrictions(_dest, _value, _func, restrictionsFacet);\n }\n\n /**\n * @notice Batch calls the destination with inputted calldata and value from EntryPoint\n * @dev This method batch executes the calldata coming from the EntryPoint.\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\n * @param _dest Array of addresses of destination where the call will be forwarded to\n * @param _value Array of amount of native coin the owner is willing to send(e.g. ETH, BNB)\n * @param _func Array of bytes of calldata to execute in the destination address\n */\n function executeBatch(\n address[] calldata _dest,\n uint256[] calldata _value,\n bytes[] calldata _func\n ) external override onlyWhenUnlocked {\n _requireFromEntryPoint();\n if (_dest.length != _func.length || _dest.length != _value.length)\n revert AccountFacet__InvalidArrayLength();\n address restrictionsFacet = LibDiamond.restrictionsFacet();\n if (restrictionsFacet == address(0)) {\n for (uint256 i; i < _dest.length; ) {\n _call(_dest[i], _value[i], _func[i]);\n unchecked {\n ++i;\n }\n }\n } else {\n for (uint256 i; i < _dest.length; ) {\n _callWithRestrictions(\n _dest[i],\n _value[i],\n _func[i],\n restrictionsFacet\n );\n unchecked {\n ++i;\n }\n }\n }\n }\n\n /**\n * @notice Validates the signature field of UserOperation\n * @dev This method validates if the signature of UserOp is indeed valid by delegating the call to Verification Facet\n * Barz makes a call to the pre-registered Verification Facet address in App Storage\n * @param _userOp UserOperation from owner to be validated\n * @param _userOpHash Hash of UserOperation given from the EntryPoint contract\n */\n function _validateSignature(\n UserOperation calldata _userOp,\n bytes32 _userOpHash\n ) internal override returns (uint256 validationData) {\n // Get Facet with Function Selector\n address facet = LibLoupe.facetAddress(s.validateOwnerSignatureSelector);\n if (facet == address(0))\n revert AccountFacet__NonExistentVerificationFacet();\n\n // Make function call to VerificationFacet\n bytes memory validateCall = abi.encodeWithSelector(\n s.validateOwnerSignatureSelector,\n _userOp,\n _userOpHash\n );\n (bool success, bytes memory result) = facet.delegatecall(validateCall);\n if (!success) revert AccountFacet__CallNotSuccessful();\n validationData = uint256(bytes32(result));\n if (validationData == 0) emit VerificationSuccess(_userOpHash);\n else emit VerificationFailure(_userOpHash);\n }\n\n /**\n * @notice Calls the target with the inputted value and calldata\n * @dev This method is the actual function in Barz that makes a call with an arbitrary owner-given data\n * @param _target Address of the destination contract which the call is getting forwarded to\n * @param _value Amount of Native coin the owner is wanting to make in this call\n * @param _data Calldata the owner is forwarding together in the call e.g. Swap/Token Transfer\n */\n function _call(\n address _target,\n uint256 _value,\n bytes memory _data\n ) internal {\n (bool success, bytes memory result) = _target.call{value: _value}(\n _data\n );\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n }\n\n /**\n * @notice Calls the target with the inputted value and calldata together with restrictions check\n * @dev This method is the actual function in Barz that makes a call with an arbitrary owner-given data\n * @param _target Address of the destination contract which the call is getting forwarded to\n * @param _value Amount of Native coin the owner is wanting to make in this call\n * @param _data Calldata the owner is forwarding together in the call e.g. Swap/Token Transfer\n * @param _restrictionsFacet Address of Facet to validate restrictions\n */\n function _callWithRestrictions(\n address _target,\n uint256 _value,\n bytes memory _data,\n address _restrictionsFacet\n ) internal {\n // NOTE: No restrictions facet, so restriction validation passes\n if (_checkRestrictions(_restrictionsFacet, _target, _value, _data) != 0)\n revert AccountFacet__RestrictionsFailure();\n\n (bool success, bytes memory result) = _target.call{value: _value}(\n _data\n );\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n }\n\n /**\n * @notice Checks restrictions if the restrictions facet exists\n * @dev This method checks if the restrictions facet exists and makes a verification call to an array of restrictions facet\n * @param _facet Address that holds the restrictions logic\n * @param _target Address the call is getting forwarded to\n * @param _value Amount of native coin the call is sending together with the call\n * @param _data Calldata to trigger execution in target address\n */\n function _checkRestrictions(\n address _facet,\n address _target,\n uint256 _value,\n bytes memory _data\n ) internal returns (uint256 result) {\n bytes memory call = abi.encodeWithSignature(\n \"verifyRestrictions(address,address,uint256,bytes)\",\n address(this),\n _target,\n _value,\n _data\n );\n (bool success, bytes memory response) = _facet.delegatecall(call);\n if (!success) revert AccountFacet__RestrictionsFailure();\n result = uint256(bytes32(response));\n }\n}\n" + }, + "contracts/facets/AccountRecoveryFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibFacetStorage, RecoveryStorage, RecoveryConfig, RecoveryApprovalConfig, ApprovalConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {IAccountRecoveryFacet} from \"./interfaces/IAccountRecoveryFacet.sol\";\n\n/**\n * @title Account Recovery Facet\n * @dev Contract that enables recovery of accounts when owner key is unavailable\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract AccountRecoveryFacet is IAccountRecoveryFacet, Modifiers {\n bytes constant UNINIT_CALL =\n abi.encodeWithSignature(\"uninitializeSigner()\");\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Approve recovery of account as guardian\n * @dev This method can only be called by guardian and guardian inputs the public key of the new owner\n * When the threshold(majority of guardians) passes, it automatically executes account recovery\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function approveAccountRecovery(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + _getApprovalValidationPeriod()\n );\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit RecoveryApproved(\n _recoveryPublicKey,\n msg.sender,\n approvalValidUntil\n );\n if (\n getRecoveryApprovalCountWithTimeValidity(recoveryPublicKeyHash) >=\n LibGuardian.majorityOfGuardians()\n ) _executeRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Revoke recovery of account as guardian\n * @dev This method can only be called by guardian and guardian inputs the public key of the new owner\n When the threshold(majority of guardians) passes, it automatically revokes account recovery when recovery is pending\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function revokeAccountRecoveryApproval(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n if (\n !rs\n .isNewOwnerApproved[recoveryPublicKeyHash][msg.sender].isApproved ||\n !(block.timestamp <\n rs\n .isNewOwnerApproved[recoveryPublicKeyHash][msg.sender]\n .validUntil)\n ) revert AccountRecoveryFacet__NonExistentApproval();\n\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(false, 0);\n emit RecoveryApprovalRevoked(_recoveryPublicKey, msg.sender);\n }\n\n /**\n * @notice Executes recovery with signatures or on-chain pre-approvals\n * @dev This method validates the signatures of guardians or checks the on-chain pre-approved calls to check if the threshold passes\n * When the threshold passes, account recovery is executed and revert otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _guardians Array of guardians address that are approving the recovery of Account\n * @param _signatures Array of signature bytes that signed the approval hash\n */\n function executeRecovery(\n bytes calldata _recoveryPublicKey,\n address[] calldata _guardians,\n bytes[] calldata _signatures\n ) external override {\n if (_isRecoveryPending())\n revert AccountRecoveryFacet__RecoveryAlreadyOngoing();\n if (_guardians.length != _signatures.length)\n revert AccountRecoveryFacet__InvalidArrayLength();\n validateNewOwner(_recoveryPublicKey);\n\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n\n _checkApprover(_guardians);\n _checkDuplicateOnChainApprover(recoveryPublicKeyHash, _guardians);\n\n if (\n _guardians.length +\n getRecoveryApprovalCountWithTimeValidity(\n recoveryPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians()\n ) revert AccountRecoveryFacet__InsufficientGuardians();\n for (uint256 i; i < _guardians.length; ) {\n if (!LibGuardian.isGuardian(_guardians[i]))\n revert AccountRecoveryFacet__InvalidGuardian();\n if (\n !SignatureChecker.isValidSignatureNow(\n _guardians[i],\n recoveryPublicKeyHash,\n _signatures[i]\n )\n ) revert AccountRecoveryFacet__InvalidGuardianSignature();\n unchecked {\n ++i;\n }\n }\n _executeRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Executes recovery of the account. Note that execution and finalization is a different process\n * @dev Executes the recovery and adds recovery data to recovery configuration. Locks the account\n * @param _recoveryPublicKey Public Key of the account for recovery\n */\n function _executeRecovery(bytes memory _recoveryPublicKey) internal {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n unchecked {\n ++rs.nonce;\n }\n uint64 executeAfter = uint64(block.timestamp + _getRecoveryPeriod());\n rs.recoveryConfigs[INNER_STRUCT] = RecoveryConfig(\n _recoveryPublicKey,\n executeAfter // NOTE: Remove guardian Count\n );\n LibAppStorage.setLock(\n block.timestamp + _getLockPeriod(),\n AccountRecoveryFacet.executeRecovery.selector\n );\n emit RecoveryExecuted(_recoveryPublicKey, executeAfter);\n }\n\n /**\n * @notice Finalize recovery after recovery pending period. Recovery pending period can be set by user beforehand in SecurityManager\n * @dev This method finalizes recovery and fully changes the ownership of the account to the newly inputted recovery public key\n */\n function finalizeRecovery() external override {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n if (\n uint64(block.timestamp) <=\n rs.recoveryConfigs[INNER_STRUCT].executeAfter\n ) revert AccountRecoveryFacet__RecoveryPeriodNotOver();\n bytes memory recoveryOwner = rs\n .recoveryConfigs[INNER_STRUCT]\n .recoveryPublicKey;\n\n delete rs.recoveryConfigs[INNER_STRUCT];\n\n LibAppStorage.setLock(0, bytes4(0));\n\n LibAppStorage.initiateSignerMigration();\n address verificationFacet = address(\n bytes20(\n LibDiamond.diamondStorage().facets[\n s.validateOwnerSignatureSelector\n ]\n )\n );\n (bool success, bytes memory result) = verificationFacet.delegatecall(\n UNINIT_CALL\n );\n if (!success) revert AccountRecoveryFacet__CallNotSuccesful();\n uint256 validationData = uint256(bytes32(result));\n if (validationData != 1)\n revert AccountRecoveryFacet__SignerUninitializationFailure();\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n recoveryOwner\n );\n (success, result) = verificationFacet.delegatecall(initCall);\n if (!success) revert AccountRecoveryFacet__CallNotSuccesful();\n validationData = uint256(bytes32(result));\n if (validationData != 1)\n revert AccountRecoveryFacet__SignerInitializationFailure();\n LibAppStorage.finalizeSignerMigration();\n emit RecoveryFinalized(recoveryOwner);\n }\n\n /**\n * @notice Approves the cancellation of recovery\n * @dev This method approves the cancellation of recovery when recovery is still pending - waiting for finalization\n * @param _recoveryPublicKey Bytes of public key which is pending for recovery\n */\n function approveCancelRecovery(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"CancelRecovery\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + _getApprovalValidationPeriod()\n );\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit RecoveryCancellationApproved(_recoveryPublicKey, msg.sender);\n if (\n getRecoveryApprovalCountWithTimeValidity(recoveryPublicKeyHash) >=\n LibGuardian.majorityOfGuardians()\n ) {\n _cancelRecovery(_recoveryPublicKey);\n }\n }\n\n /**\n * @notice Hardstops an ongoing recovery\n * @dev This method provides a safety mechanism to protect owners of malicious guardians.\n * Owners can hardstop recovery when an malicious guardians starts the recovery process.\n * @param _signature Signature of the owner that signs the hash to hardstop recovery\n */\n function hardstopRecovery(bytes calldata _signature) external override {\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n \"0\",\n \"HardstopRecovery\"\n );\n if (\n !SignatureChecker.isValidSignatureNow(\n address(this),\n recoveryPublicKeyHash,\n _signature\n )\n ) revert AccountRecoveryFacet__InvalidOwnerSignature();\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n unchecked {\n ++rs.nonce;\n }\n delete rs.recoveryConfigs[INNER_STRUCT];\n LibAppStorage.setLock(0, bytes4(0));\n emit RecoveryHardstopped();\n }\n\n /**\n * @notice Cancels recovery with signatures or on-chain pre-approvals\n * @dev This method validates the signatures of guardians or checks the on-chain pre-approved calls to check if the threshold passes\n * When the threshold passes, account recovery is canceled and revert otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _guardians Array of guardians address that are approving the recovery of Account\n * @param _signatures Array of signature bytes that signed the cancellation approval hash\n */\n function cancelRecovery(\n bytes calldata _recoveryPublicKey,\n address[] calldata _guardians,\n bytes[] calldata _signatures\n ) external override {\n if (_guardians.length != _signatures.length)\n revert AccountRecoveryFacet__InvalidArrayLength();\n validateNewOwner(_recoveryPublicKey);\n\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"CancelRecovery\"\n );\n\n _checkApprover(_guardians);\n _checkDuplicateOnChainApprover(recoveryPublicKeyHash, _guardians);\n\n if (\n _guardians.length +\n getRecoveryApprovalCountWithTimeValidity(\n recoveryPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians()\n ) revert AccountRecoveryFacet__InsufficientGuardians();\n for (uint256 i; i < _guardians.length; ) {\n if (!LibGuardian.isGuardian(_guardians[i]))\n revert AccountRecoveryFacet__CallerNotGuardian();\n if (\n !SignatureChecker.isValidSignatureNow(\n _guardians[i],\n recoveryPublicKeyHash,\n _signatures[i]\n )\n ) revert AccountRecoveryFacet__InvalidGuardianSignature();\n unchecked {\n ++i;\n }\n }\n _cancelRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Cancel recovery when the recovery is pending. Unlock the account as well\n * @dev This method checks if the recovery is pending and reverts if not pending.\n * It increases the recovery nonce and deletes the recovery information and gets a small portion of gas in return\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function _cancelRecovery(bytes memory _recoveryPublicKey) internal {\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n LibAppStorage.setLock(0, bytes4(0));\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n unchecked {\n ++rs.nonce;\n }\n delete rs.recoveryConfigs[INNER_STRUCT];\n emit RecoveryCanceled(_recoveryPublicKey);\n }\n\n /**\n * @notice Validates the format of public key to be used for recovery\n * @dev This method checks if the public key format is correct and reverts otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function validateNewOwner(bytes memory _recoveryPublicKey) public view {\n if (\n !IVerificationFacet(\n LibLoupe.facetAddress(s.validateOwnerSignatureSelector)\n ).isValidKeyType(_recoveryPublicKey)\n ) revert AccountRecoveryFacet__InvalidRecoveryPublicKey();\n }\n\n /**\n * @notice Checks if recovery is currently pending\n * @return isPending Boolean indicating if recovery is pending\n */\n function _isRecoveryPending() internal view returns (bool isPending) {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n isPending = (rs.recoveryConfigs[INNER_STRUCT].executeAfter > 0);\n }\n\n /**\n * @notice Calculate the recovery hash dependent on chain, wallet address, nonce with EIP-191 prefix for safety\n * @dev Returns the keccak256 hash of EIP-191 msg hash packed with public key, salt, nonce, wallet address, etc\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _saltString Salt string to uniquely identify each recovery hash and for security\n * @return recoveryKeyHash Bytes32 string of the recovery hash\n */\n function getApprovalRecoveryKeyHash(\n bytes memory _recoveryPublicKey,\n string memory _saltString\n ) public view override returns (bytes32 recoveryKeyHash) {\n recoveryKeyHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n _recoveryPublicKey,\n _saltString,\n address(this),\n block.chainid,\n LibFacetStorage.recoveryStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Check the onchain approval of guardians and returns the number of guardians that approved\n * @dev Loop through the guardian addresses and returns the number of guardians that approved this recovery hash\n * @param _recoveryPublicKeyHash Bytes hash of newly recovered public key and recovery value of the account\n * @return approvalCount Number of guardians that approved\n */\n function getRecoveryApprovalCountWithTimeValidity(\n bytes32 _recoveryPublicKeyHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n for (uint256 i; i < guardianLength; ) {\n if (isRecoveryApproved(_recoveryPublicKeyHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Checks if the recovery is approved by the given approver\n * @param _recoveryPublicKeyHash Hash of the public key and configuration for recovery\n * @param _approver Address of approver\n * @return isApproved Bool value if recovery hash is approved\n */\n function isRecoveryApproved(\n bytes32 _recoveryPublicKeyHash,\n address _approver\n ) public view override returns (bool isApproved) {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n if (\n rs\n .isNewOwnerApproved[_recoveryPublicKeyHash][_approver].isApproved &&\n block.timestamp <\n rs.isNewOwnerApproved[_recoveryPublicKeyHash][_approver].validUntil\n ) {\n isApproved = true;\n }\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _recoveryPublicKeyHash Hash of recovery information\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _recoveryPublicKeyHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isRecoveryApproved(_recoveryPublicKeyHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert AccountRecoveryFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the lock period of this wallet address from security manager\n * @return lockPeriod value of lock period\n */\n function _getLockPeriod() internal view returns (uint256 lockPeriod) {\n lockPeriod = securityManager.lockPeriodOf(address(this));\n if (lockPeriod == 0) revert AccountRecoveryFacet__InvalidLockPeriod();\n }\n\n /**\n * @notice Returns the lock period of this wallet address from security manager\n * @return recoveryPeriod value of recovery period\n */\n function _getRecoveryPeriod()\n internal\n view\n returns (uint256 recoveryPeriod)\n {\n recoveryPeriod = securityManager.recoveryPeriodOf(address(this));\n if (recoveryPeriod == 0)\n revert AccountRecoveryFacet__InvalidRecoveryPeriod();\n }\n\n /**\n * @notice Returns the approval validation period of this wallet address from security manager\n * @return approvalValidationPeriod value of approval validation period\n */\n function _getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod == 0)\n revert AccountRecoveryFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the recovery nonce of this wallet address from security manager\n * @return nonce value of recovery nonce\n */\n function getRecoveryNonce() public view override returns (uint128 nonce) {\n nonce = LibFacetStorage.recoveryStorage().nonce;\n }\n\n /**\n * @notice Returns the recovery information of the pending recovery\n * @return recoveryConfig value struct of pending recovery\n */\n function getPendingRecovery()\n public\n view\n override\n returns (RecoveryConfig memory recoveryConfig)\n {\n recoveryConfig = LibFacetStorage.recoveryStorage().recoveryConfigs[\n INNER_STRUCT\n ];\n }\n}\n" + }, + "contracts/facets/base/DiamondCutFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibGuardian} from \"../../libraries/LibGuardian.sol\";\nimport {ISecurityManager} from \"../../infrastructure/interfaces/ISecurityManager.sol\";\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibFacetStorage, DiamondCutApprovalConfig, ApprovalConfig} from \"../../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"../Modifiers.sol\";\nimport {IDiamondCut} from \"./interfaces/IDiamondCut.sol\";\n\n/**\n * @title DiamondCut Facet\n * @dev Responsible for adding/removing/replace facets in Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DiamondCutFacet is Modifiers, IDiamondCut {\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Updates the flag for the interfaceId\n * @param _interfaceId InterfaceID to update the mapping\n * @param _flag Bool value to update the mapping of the given interface ID\n */\n function updateSupportsInterface(\n bytes4 _interfaceId,\n bool _flag\n ) external override onlyWhenUnlocked {\n LibDiamond.enforceIsSelf();\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId] = _flag;\n emit SupportsInterfaceUpdated(_interfaceId, _flag);\n }\n\n /**\n * @notice Add/replace/remove any number of functions and optionally execute\n * a function with delegatecall when guardians don't exist\n * @param _diamondCut Contains the facet addresses and function selectors\n * @param _init The address of the contract or facet to execute _calldata. It's prohibited in Barz\n */\n function diamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata\n ) external override onlyWhenUnlocked {\n LibDiamond.enforceIsSelf();\n\n _checkFacetCutValidity(_diamondCut);\n // require approval from guardian if guardian exists\n if (0 != LibGuardian.guardianCount())\n revert DiamondCutFacet__InvalidRouteWithGuardian();\n if (address(0) != _init) revert DiamondCutFacet__InvalidInitAddress();\n\n unchecked {\n ++LibFacetStorage.diamondCutStorage().nonce;\n }\n LibDiamond.diamondCut(_diamondCut, address(0), \"\");\n }\n\n /**\n * @notice Add/replace/remove any number of functions and optionally execute\n * a function with delegatecall when guardians exist\n * @param _diamondCut Contains the facet addresses and function selectors\n * @param _approvers Guardian or owner address that approves the diamond cut\n * @param _signatures Signature of Guardians or owner that approves the diamond cut\n */\n function diamondCutWithGuardian(\n FacetCut[] calldata _diamondCut,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n ) external override onlyWhenUnlocked {\n if (_approvers.length != _signatures.length)\n revert DiamondCutFacet__InvalidArrayLength();\n _checkFacetCutValidity(_diamondCut);\n if (0 == LibGuardian.guardianCount())\n revert DiamondCutFacet__InvalidRouteWithGuardian();\n\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(cutHash, _approvers);\n\n bool onChainOwnerApproval = getOwnerCutApprovalWithTimeValidity(\n cutHash\n );\n\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n if (\n _approvers.length +\n getDiamondCutApprovalCountWithTimeValidity(cutHash) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert DiamondCutFacet__InsufficientApprovers();\n\n bool ownerApproved;\n for (uint256 i; i < _approvers.length; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n _approvers[i] != address(this)\n ) revert DiamondCutFacet__InvalidApprover();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert DiamondCutFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n cutHash,\n _signatures[i]\n )\n ) revert DiamondCutFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n if (!ownerApproved && !onChainOwnerApproval)\n revert DiamondCutFacet__LackOfOwnerApproval();\n\n unchecked {\n ++LibFacetStorage.diamondCutStorage().nonce;\n }\n LibDiamond.diamondCut(_diamondCut, address(0), \"\");\n }\n\n /**\n * @notice Approves diamond cut. This can only be called directly from guardian or owner\n * @param _diamondCut Contains the facet addresses and function selectors\n */\n function approveDiamondCut(\n FacetCut[] calldata _diamondCut\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\n if (LibGuardian.guardianCount() == 0)\n revert DiamondCutFacet__InvalidRouteWithoutGuardian();\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n _checkFacetCutValidity(_diamondCut);\n\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(\n true,\n approvalValidUntil\n );\n emit DiamondCutApproved(_diamondCut);\n if (\n (getDiamondCutApprovalCountWithTimeValidity(cutHash) >=\n LibGuardian.majorityOfGuardians()) &&\n getOwnerCutApprovalWithTimeValidity(cutHash)\n ) {\n unchecked {\n ++LibFacetStorage.diamondCutStorage().nonce;\n }\n LibDiamond.diamondCut(_diamondCut, address(0), \"\");\n }\n }\n\n /**\n * @notice Revokes the approval of diamond cut. This can only be called directly from guardian or owner\n * @param _diamondCut Contains the facet addresses and function selectors\n */\n function revokeDiamondCutApproval(\n FacetCut[] calldata _diamondCut\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\n if (!ds.isDiamondCutApproved[cutHash][msg.sender].isApproved)\n revert DiamondCutFacet__CannotRevokeUnapproved();\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(false, 0);\n emit DiamondCutApprovalRevoked(_diamondCut);\n }\n\n /**\n * @notice Gets the number of approvals of diamond cut from guardians\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n */\n function getDiamondCutApprovalCountWithTimeValidity(\n bytes32 _diamondCutHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardiansLength = guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n if (isCutApproved(_diamondCutHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n return approvalCount;\n }\n\n /**\n * @notice Returns if the owner has approved the diamond cut\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @return isApprovedByOwner Bool value showing if the owner approved the cut\n */\n function getOwnerCutApprovalWithTimeValidity(\n bytes32 _diamondCutHash\n ) public view override returns (bool isApprovedByOwner) {\n isApprovedByOwner = isCutApproved(_diamondCutHash, address(this));\n }\n\n /**\n * @notice Returns if the given approver has approved the diamond cut\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @param _approver Address of approver\n * @return isApproved Bool value showing if the approver approved the cut\n */\n function isCutApproved(\n bytes32 _diamondCutHash,\n address _approver\n ) public view override returns (bool isApproved) {\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n isApproved = (ds\n .isDiamondCutApproved[_diamondCutHash][_approver].isApproved &&\n block.timestamp <\n ds.isDiamondCutApproved[_diamondCutHash][_approver].validUntil);\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _diamondCutHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isCutApproved(_diamondCutHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert DiamondCutFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the diamond cut hash. This function ensures that this hash is safe from replay attack by including\n * salt, address, chainId, and nonce, etc.\n * @param _diamondCut Contains the facet addresses and function selectors\n * @return cutHash Diamond Cut Hash\n */\n function getDiamondCutHash(\n FacetCut[] calldata _diamondCut\n ) public view override returns (bytes32 cutHash) {\n cutHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n keccak256(abi.encode(_diamondCut)),\n address(this),\n block.chainid,\n LibFacetStorage.diamondCutStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Returns the approval validation Period\n * @dev This method fetches the validation period from the security manager\n * @return approvalValidationPeriod Approval validation period of Barz contract fetched from security manager\n */\n function getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod <= 0)\n revert DiamondCutFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the diamond cut nonce of this wallet\n * @dev This method fetches the nonce from diamond cut storage\n * @return cutNonce Nonce of diamond cut to protect from reply attacks\n */\n function getDiamondCutNonce()\n public\n view\n override\n returns (uint128 cutNonce)\n {\n cutNonce = LibFacetStorage.diamondCutStorage().nonce;\n }\n}\n" + }, + "contracts/facets/base/DiamondLoupeFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {IERC165} from \"../../interfaces/ERC/IERC165.sol\";\nimport {IERC1271} from \"../../interfaces/ERC/IERC1271.sol\";\nimport {IERC677Receiver} from \"../../interfaces/ERC/IERC677Receiver.sol\";\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC1155Receiver} from \"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\";\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../../libraries/LibLoupe.sol\";\nimport {LibUtils} from \"../../libraries/LibUtils.sol\";\nimport {IDiamondCut} from \"../../facets/base/interfaces/IDiamondCut.sol\";\nimport {IStorageLoupe} from \"./interfaces/IStorageLoupe.sol\";\nimport {IDiamondLoupe} from \"./interfaces/IDiamondLoupe.sol\";\n\n/**\n * @title DiamondLoupe Facet\n * @dev DiamondLoupe contract compatible with EIP-2535\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DiamondLoupeFacet is IDiamondLoupe, IStorageLoupe, IERC165 {\n // Diamond Loupe Functions\n ////////////////////////////////////////////////////////////////////\n /// These functions are expected to be called frequently by tools off-chain.\n\n /**\n * @notice Gets all facets and their selectors.\n * @dev Barz uses a special architecture called default fallback handler. Default Fallback handler is used as a middleware\n * that holds the mapping of facet function selector and facet address that Barz uses. This helps Barz to reduce\n * significant amount of gas during the initialization process.\n * Hence, this method aggregates both the facet information from DefaulFallbackHandler and in diamond storage and shows the data to users.\n * @return facets_ Facet\n */\n function facets() public view override returns (Facet[] memory facets_) {\n Facet[] memory defaultFacet = LibDiamond\n .diamondStorage()\n .defaultFallbackHandler\n .facets();\n Facet[] memory _facets = LibLoupe.facets();\n uint256 numFacets = _facets.length;\n bytes4[] memory keys;\n address[] memory values;\n for (uint256 i; i < numFacets; ) {\n uint256 selectorsLength = _facets[i].functionSelectors.length;\n for (uint256 j; j < selectorsLength; ) {\n (keys, values) = LibUtils.setValue(\n keys,\n values,\n _facets[i].functionSelectors[j],\n _facets[i].facetAddress\n );\n unchecked {\n ++j;\n }\n }\n unchecked {\n ++i;\n }\n }\n {\n bool iIncrement;\n for (uint256 i; i < defaultFacet.length; ) {\n bool jIncrement;\n for (\n uint256 j;\n j < defaultFacet[i].functionSelectors.length;\n\n ) {\n if (\n LibUtils.getValue(\n keys,\n values,\n defaultFacet[i].functionSelectors[j]\n ) != address(0)\n ) {\n if (defaultFacet[i].functionSelectors.length == 1) {\n defaultFacet = LibUtils.removeFacetElement(\n defaultFacet,\n i\n );\n iIncrement = true;\n break;\n }\n defaultFacet[i].functionSelectors = LibUtils\n .removeElement(\n defaultFacet[i].functionSelectors,\n j\n );\n jIncrement = true;\n }\n if (!jIncrement) {\n unchecked {\n ++j;\n }\n } else {\n jIncrement = false;\n }\n }\n if (!iIncrement) {\n unchecked {\n ++i;\n }\n } else {\n iIncrement = false;\n }\n }\n }\n {\n uint256 facetLength = numFacets + defaultFacet.length;\n facets_ = new Facet[](facetLength);\n uint256 defaultFacetIndex;\n for (uint256 i; i < facetLength; ) {\n if (i < numFacets) {\n facets_[i] = _facets[i];\n bool jIncrementor;\n for (uint256 j; j < defaultFacet.length; ) {\n if (\n facets_[i].facetAddress ==\n defaultFacet[j].facetAddress\n ) {\n facets_[i].functionSelectors = LibUtils.mergeArrays(\n _facets[i].functionSelectors,\n defaultFacet[j].functionSelectors\n );\n defaultFacet = LibUtils.removeFacetElement(\n defaultFacet,\n j\n );\n jIncrementor = true;\n {\n facets_ = LibUtils.removeFacetElement(\n facets_,\n facets_.length - 1\n );\n }\n --facetLength;\n }\n if (!jIncrementor) {\n unchecked {\n ++j;\n }\n } else {\n jIncrementor = false;\n }\n }\n } else {\n facets_[i] = defaultFacet[defaultFacetIndex];\n ++defaultFacetIndex;\n }\n unchecked {\n ++i;\n }\n }\n }\n }\n\n /**\n * @notice Gets all the function selectors provided by a facet.\n * @param _facet The facet address.\n * @return facetFunctionSelectors_\n */\n function facetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n Facet[] memory facet = facets();\n uint256 facetLength = facet.length;\n for (uint256 i; i < facetLength; ) {\n if (facet[i].facetAddress == _facet)\n return facet[i].functionSelectors;\n unchecked {\n ++i;\n }\n }\n return facetFunctionSelectors_;\n }\n\n /**\n * @notice Get all the facet addresses used by Barz.\n * @return facetAddresses_\n */\n function facetAddresses()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n Facet[] memory facet = facets();\n uint256 facetLength = facet.length;\n facetAddresses_ = new address[](facetLength);\n for (uint256 i; i < facetLength; ) {\n facetAddresses_[i] = facet[i].facetAddress;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Gets the facet that supports the given selector.\n * @dev If facet is not found return address(0).\n * @param _functionSelector The function selector.\n * @return facetAddress_ The facet address.\n */\n function facetAddress(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n\n facetAddress_ = address(bytes20(ds.facets[_functionSelector]));\n if (facetAddress_ == address(0)) {\n facetAddress_ = IDiamondLoupe(ds.defaultFallbackHandler)\n .facetAddress(_functionSelector);\n }\n }\n\n /**\n * @notice SupportInterface to be compatible with EIP 165\n * @param _interfaceId Interface ID for detecting the interface\n * @return isSupported Bool value showing if the standard is supported in the contract\n */\n function supportsInterface(\n bytes4 _interfaceId\n ) external view override returns (bool isSupported) {\n isSupported =\n _interfaceId == type(IERC165).interfaceId ||\n _interfaceId == IDiamondCut.diamondCut.selector ||\n _interfaceId == type(IDiamondLoupe).interfaceId ||\n _interfaceId == type(IERC1155Receiver).interfaceId ||\n _interfaceId == type(IERC721Receiver).interfaceId ||\n _interfaceId == type(IERC777Recipient).interfaceId ||\n _interfaceId == IERC1271.isValidSignature.selector ||\n _interfaceId == type(IERC677Receiver).interfaceId ||\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId];\n }\n\n /**\n * @notice Returns the facet from the diamond storage. This excludes the facets from the default fallback handler\n * @return facets_ Facet information attached directly to diamond storage\n */\n function facetsFromStorage()\n external\n view\n override\n returns (Facet[] memory facets_)\n {\n facets_ = LibLoupe.facets();\n }\n\n /**\n * @notice Returns the facet address attached to the given function selector. This excludes the facets from the default fallback handler\n * @param _functionSelector Function selector to fetch the facet address from diamond storage\n * @return facetAddress_ Facet address mapped with the function selector\n */\n function facetAddressFromStorage(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n facetAddress_ = LibLoupe.facetAddress(_functionSelector);\n }\n\n /**\n * @notice Returns all facet addresses attached directly to diamond storage. This excludes the facets from the default fallback handler\n * @return facetAddresses_ All facet addresses attached directly to diamond storage\n */\n function facetAddressesFromStorage()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n facetAddresses_ = LibLoupe.facetAddresses();\n }\n\n /**\n * @notice Returns function selectors of given facet address attached directly to diamond storage. This excludes the facets from the default fallback handler\n * @param _facet Facet address to fetch the facet function selectors from diamond storage\n * @return facetFunctionSelectors_ Facet function selectors of the given facet address\n */\n function facetFunctionSelectorsFromStorage(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n facetFunctionSelectors_ = LibLoupe.facetFunctionSelectors(_facet);\n }\n}\n" + }, + "contracts/facets/base/interfaces/IDiamondCut.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title DiamondCut Facet Interface\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IDiamondCut {\n error DiamondCutFacet__InvalidRouteWithGuardian();\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\n error DiamondCutFacet__InvalidArrayLength();\n error DiamondCutFacet__InsufficientApprovers();\n error DiamondCutFacet__InvalidApprover();\n error DiamondCutFacet__InvalidApproverSignature();\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\n error DiamondCutFacet__CannotRevokeUnapproved();\n error DiamondCutFacet__LackOfOwnerApproval();\n error DiamondCutFacet__OwnerAlreadyApproved();\n error DiamondCutFacet__DuplicateApproval();\n error DiamondCutFacet__InvalidInitAddress();\n\n event DiamondCutApproved(FacetCut[] diamondCut);\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\n\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\n\n enum FacetCutAction {\n Add,\n Replace,\n Remove\n }\n // Add=0, Replace=1, Remove=2\n\n struct FacetCut {\n address facetAddress;\n FacetCutAction action;\n bytes4[] functionSelectors;\n }\n\n /// @notice Add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param diamondCut Contains the facet addresses and function selectors\n /// @param init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function diamondCut(\n FacetCut[] calldata diamondCut,\n address init,\n bytes calldata _calldata\n ) external;\n\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\n\n function diamondCutWithGuardian(\n FacetCut[] calldata diamondCut,\n address[] calldata approvers,\n bytes[] calldata signatures\n ) external;\n\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\n\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\n\n function getDiamondCutApprovalCountWithTimeValidity(\n bytes32 diamondCutHash\n ) external view returns (uint256);\n\n function getOwnerCutApprovalWithTimeValidity(\n bytes32 diamondCutHash\n ) external view returns (bool);\n\n function isCutApproved(\n bytes32 diamondCutHash,\n address approver\n ) external view returns (bool);\n\n function getDiamondCutHash(\n FacetCut[] calldata diamondCut\n ) external view returns (bytes32);\n\n function getDiamondCutNonce() external view returns (uint128);\n}\n" + }, + "contracts/facets/base/interfaces/IDiamondLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n// A loupe is a small magnifying glass used to look at diamonds.\n// These functions look at diamonds\ninterface IDiamondLoupe {\n /// These functions are expected to be called frequently\n /// by tools.\n\n struct Facet {\n address facetAddress;\n bytes4[] functionSelectors;\n }\n\n /// @notice Gets all facet addresses and their four byte function selectors.\n /// @return facets_ Facet\n function facets() external view returns (Facet[] memory facets_);\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n /// @return facetFunctionSelectors_\n function facetFunctionSelectors(\n address _facet\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses()\n external\n view\n returns (address[] memory facetAddresses_);\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(\n bytes4 _functionSelector\n ) external view returns (address facetAddress_);\n}\n" + }, + "contracts/facets/base/interfaces/IStorageLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"./IDiamondLoupe.sol\";\n\n/**\n * @title LoupeFromStorage Interface\n * @dev Interface contract to function as a loupe facet directly attached to diamond storage of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IStorageLoupe {\n /// These functions are expected to be called frequently\n /// by tools.\n\n /// @notice Gets all facet addresses and their four byte function selectors.\n /// @return facets_ Facet\n function facetsFromStorage()\n external\n view\n returns (IDiamondLoupe.Facet[] memory);\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n function facetFunctionSelectorsFromStorage(\n address _facet\n ) external view returns (bytes4[] memory);\n\n /// @notice Get all the facet addresses used by a diamond.\n function facetAddressesFromStorage()\n external\n view\n returns (address[] memory);\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n function facetAddressFromStorage(\n bytes4 _functionSelector\n ) external view returns (address);\n}\n" + }, + "contracts/facets/GuardianFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibFacetStorage, GuardianStorage, StorageConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IGuardianFacet} from \"./interfaces/IGuardianFacet.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Guardian Facet\n * @dev Contract that enables addition/removal of guardians from Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract GuardianFacet is IGuardianFacet {\n ISecurityManager public immutable securityManager;\n uint8 public constant INNER_STRUCT = 0;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Add guardians to Barz.\n * @dev This method internally calls addGuardian which checks the validity of guardian address and adds\n * as guardian if valid\n * @param _guardians Array of addresses to add as guardian\n */\n function addGuardians(address[] calldata _guardians) external override {\n LibDiamond.enforceIsSelf();\n for (uint256 i; i < _guardians.length; ) {\n addGuardian(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Add a guardian to Barz.\n * @dev This method checks if the function is called by the owner and validates the address of guardian\n * When the validation passes, guardian address is added to the pending state waiting for confirmation\n * @param _guardian Address to add as guardian\n */\n function addGuardian(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (_guardian == address(this))\n revert GuardianFacet__GuardianCannotBeSelf();\n if (isGuardian(_guardian)) revert GuardianFacet__DuplicateGuardian();\n if (_guardian == address(0))\n revert GuardianFacet__ZeroAddressGuardian();\n if (\n keccak256(abi.encodePacked(_guardian)) ==\n keccak256(IVerificationFacet(address(this)).owner())\n ) revert GuardianFacet__OwnerCannotBeGuardian();\n\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n if (\n gs.pending[id] != 0 ||\n block.timestamp <= gs.pending[id] + getSecurityWindow()\n ) revert GuardianFacet__DuplicateGuardianAddition();\n\n uint256 securityPeriod = getAdditionSecurityPeriod();\n gs.pending[id] = block.timestamp + securityPeriod;\n emit GuardianAdditionRequested(\n _guardian,\n block.timestamp + securityPeriod\n );\n }\n\n /**\n * @notice Remove guardians from Barz.\n * @dev This method internally calls removeGuardian which checks the validity of guardian and removes\n * guardian when the request is valid\n * @param _guardians Array of addresses to be removed\n */\n function removeGuardians(address[] calldata _guardians) external override {\n LibDiamond.enforceIsSelf();\n for (uint256 i; i < _guardians.length; ) {\n removeGuardian(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Remove a guardian from Barz.\n * @dev This method validates if the guardian to be removed is a guardian and puts the guardian removal\n * to a pending state waiting to be confirmed.\n * @param _guardian Address of guardian to be removed\n */\n function removeGuardian(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n if (!isGuardian(_guardian)) revert GuardianFacet__NonExistentGuardian();\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n if (\n gs.pending[id] != 0 ||\n block.timestamp <= gs.pending[id] + getSecurityWindow()\n ) revert GuardianFacet__DuplicateGuardianRemoval();\n\n uint256 securityPeriod = getRemovalSecurityPeriod();\n gs.pending[id] = block.timestamp + securityPeriod;\n emit GuardianRemovalRequested(\n _guardian,\n block.timestamp + securityPeriod\n );\n }\n\n /**\n * @notice Confirm addition of guardians\n * @dev This method internally calls confirmGuardianAddition which checks the validity of pending request.\n * Guardians are fully added when they pass the validation. Anyone can call this function.\n * @param _guardians Array of guardian addresses to be added\n */\n function confirmGuardianAdditions(\n address[] calldata _guardians\n ) external override {\n for (uint256 i; i < _guardians.length; ) {\n confirmGuardianAddition(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Confirm addition of a guardian\n * @dev This method checks the validity of pending request.\n * Guardians are fully added when they pass the validation. Anyone can call this function.\n * @param _guardian Guardian address to be added\n */\n function confirmGuardianAddition(address _guardian) public override {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingAddition();\n if (gs.pending[id] >= block.timestamp)\n revert GuardianFacet__PendingAdditionNotOver();\n if (block.timestamp >= gs.pending[id] + getSecurityWindow())\n revert GuardianFacet__PendingAdditionExpired();\n\n _addGuardian(_guardian);\n\n delete gs.pending[id];\n emit GuardianAdded(_guardian);\n }\n\n /**\n * @notice Confirm removal of guardians\n * @dev This method internally calls confirmGuardianRemoval to check the validity guardian removal confirmation.\n * Guardians are fully removed when they pass the validation. Anyone can call this function.\n * @param _guardians Array of guardian addresses to be removed\n */\n function confirmGuardianRemovals(\n address[] calldata _guardians\n ) external override {\n for (uint256 i; i < _guardians.length; ) {\n confirmGuardianRemoval(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Confirm removal of a guardian\n * @dev This method checks the validity guardian removal confirmation.\n * Guardian is fully removed when they pass the validation. Anyone can call this function.\n * @param _guardian Guardian address to be removed\n */\n function confirmGuardianRemoval(address _guardian) public override {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingRemoval();\n if (gs.pending[id] >= block.timestamp)\n revert GuardianFacet__PendingRemovalNotOver();\n if (block.timestamp >= gs.pending[id] + getSecurityWindow())\n revert GuardianFacet__PendingAdditionExpired();\n\n _removeGuardian(_guardian);\n delete gs.pending[id];\n emit GuardianRemoved(_guardian);\n }\n\n /**\n * @notice Cancel pending guardian addition\n * @dev This method checks if the previous request for guardian request exists.\n * It reverts if previous request is not pending and cancels the addition otherwise.\n * @param _guardian Guardian address to be canceled from addition\n */\n function cancelGuardianAddition(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingAddition();\n delete gs.pending[id];\n emit GuardianAdditionCancelled(_guardian);\n }\n\n /**\n * @notice Cancel pending guardian removal\n * @dev This method checks if the previous request for guardian request exists.\n * It reverts if previous request is not pending and cancels the removal otherwise.\n * @param _guardian Guardian address to be canceled from removal\n */\n function cancelGuardianRemoval(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingRemoval();\n delete gs.pending[id];\n emit GuardianRemovalCancelled(_guardian);\n }\n\n /**\n * @notice Get the addition security period of current account from security manager\n * @dev This method returns the uint value if addition security period\n * @return additionSecurityPeriod Uint256 value of addition security period\n */\n function getAdditionSecurityPeriod()\n public\n view\n override\n returns (uint256 additionSecurityPeriod)\n {\n additionSecurityPeriod = securityManager.additionSecurityPeriodOf(\n address(this)\n );\n if (additionSecurityPeriod == 0)\n revert GuardianFacet__InvalidAdditionSecurityPeriod();\n }\n\n /**\n * @notice Get the removal security period of current account from security manager\n * @dev This method returns the uint value if removal security period\n * @return removalSecurityPeriod Uint256 value of removal security period\n */\n function getRemovalSecurityPeriod()\n public\n view\n override\n returns (uint256 removalSecurityPeriod)\n {\n removalSecurityPeriod = securityManager.removalSecurityPeriodOf(\n address(this)\n );\n if (removalSecurityPeriod == 0)\n revert GuardianFacet__InvalidRemovalSecurityPeriod();\n }\n\n /**\n * @notice Get the security window of current account from security manager\n * @dev This method returns the uint value if security window\n * @return securityWindow Uint256 value of removal security period\n */\n function getSecurityWindow()\n public\n view\n override\n returns (uint256 securityWindow)\n {\n securityWindow = securityManager.securityWindowOf(address(this));\n if (securityWindow == 0) revert GuardianFacet__InvalidSecurityWindow();\n }\n\n /**\n * @notice Checks if the addition of the given guardian address is pending\n * @dev This method returns the bool value of whether the guardian address is pending addition\n * @return isPending Bool value of representing the pending of guardian addition\n */\n function isAdditionPending(\n address _guardian\n ) public view override returns (bool isPending) {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n isPending = _isPending(id);\n }\n\n /**\n * @notice Checks if the removal of the given guardian address is pending\n * @dev This method returns the bool value of whether the guardian address is pending removal\n * @return isPending Bool value of representing the pending of guardian removal\n */\n function isRemovalPending(\n address _guardian\n ) public view override returns (bool isPending) {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n isPending = _isPending(id);\n }\n\n /**\n * @notice Checks if the given hash is pending\n * @dev This method returns the bool value whether the hash is pending\n * @return isPending Bool value of representing the pending of guardian operation\n */\n function _isPending(\n bytes32 _idHash\n ) internal view returns (bool isPending) {\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n isPending = ((gs.pending[_idHash] > 0 &&\n gs.pending[_idHash] < block.timestamp) &&\n block.timestamp < gs.pending[_idHash] + getSecurityWindow());\n }\n\n /**\n * @notice Adds guardian to storage config. This is called when guardian is fully added.\n * @dev This method add guardian address and config information to Facet Storage dedicated for guardian\n * When this function is called, guardian is fully added to this Barz Smart Account\n * @param _guardian Address of guardian to be added\n */\n function _addGuardian(address _guardian) internal {\n if (!isAdditionPending(_guardian))\n revert GuardianFacet__InvalidGuardianAddition();\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n if (config.info[_guardian].exists)\n revert GuardianFacet__AlreadyExists();\n\n config.info[_guardian].exists = true;\n config.info[_guardian].index = uint128(config.addresses.length);\n config.addresses.push(_guardian);\n }\n\n /**\n * @notice Removes guardian to storage config. This is called when guardian is fully removed.\n * @dev This method remove guardian address and config information to Facet Storage dedicated for guardian\n * When this function is called, guardian is fully removed from this Barz Smart Account\n * @param _guardian Address of guardian to be removed\n */\n function _removeGuardian(address _guardian) internal {\n if (!isRemovalPending(_guardian))\n revert GuardianFacet__InvalidGuardianRemoval();\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n if (!config.info[_guardian].exists)\n revert GuardianFacet__NonExistentGuardian();\n\n address lastAddress = config.addresses[config.addresses.length - 1];\n if (_guardian != lastAddress) {\n uint128 targetIndex = config.info[_guardian].index;\n config.addresses[targetIndex] = lastAddress;\n config.info[lastAddress].index = targetIndex;\n }\n config.addresses.pop();\n delete config.info[_guardian];\n\n emit GuardianRemoved(_guardian);\n }\n\n /**\n * @notice Reads guardian storage and fetches the addresses into an array from the storage\n * @dev This method fetches the guardian storage and returns the list of guardian addresses\n * @return addresses Array of addresses comprised of guardian\n */\n function getGuardians()\n public\n view\n override\n returns (address[] memory addresses)\n {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n uint256 addressesLen = config.addresses.length;\n addresses = new address[](addressesLen);\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the number of majority of guardians\n * @return majorityOfGuardians_ Number of majority of guardians e.g., 2 if 3 guardians / 3 if 5 guardians\n */\n function majorityOfGuardians()\n public\n view\n override\n returns (uint256 majorityOfGuardians_)\n {\n majorityOfGuardians_ = LibGuardian.majorityOfGuardians();\n }\n\n /**\n * @notice Reads guardian storage and fetches the addresses into an array from the storage\n * @dev This method fetches the guardian storage and returns the list of guardian addresses\n * @return guardianNumber Array of guardians in the account\n */\n function guardianCount()\n public\n view\n override\n returns (uint256 guardianNumber)\n {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n guardianNumber = config.addresses.length;\n }\n\n /**\n * @notice Reads guardian storage and checks if the given address is a guardian\n * @return isGuardian_ Bool value representing if the given address is guardian\n */\n function isGuardian(\n address _guardian\n ) public view override returns (bool isGuardian_) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n isGuardian_ = config.info[_guardian].exists;\n }\n\n /**\n * @notice Checks if the guardian number is zero and returns of guardian facet is okay to be removed\n * @return isRemovable Bool value representing if guardian facet is removable\n */\n function isGuardianFacetRemovable()\n external\n view\n override\n returns (bool isRemovable)\n {\n isRemovable = (0 == guardianCount());\n }\n}\n" + }, + "contracts/facets/interfaces/IAccountFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IEntryPoint} from \"../../aa-4337/interfaces/IEntryPoint.sol\";\n\n/**\n * @title Account Facet Interface\n * @dev Interface of module contract that provides the account features and init/unitialization of signer\n * compatible with EIP-1271 & EIP-4337\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IAccountFacet {\n event AccountInitialized(\n IEntryPoint indexed entryPoint,\n bytes indexed ownerPublicKey\n );\n // NOTE: Added Below Event\n event VerificationSuccess(bytes32);\n event VerificationFailure(bytes32);\n\n error AccountFacet__InitializationFailure();\n error AccountFacet__RestrictionsFailure();\n error AccountFacet__NonExistentVerificationFacet();\n error AccountFacet__CallNotSuccessful();\n error AccountFacet__InvalidArrayLength();\n\n function initialize(\n address verificationFacet,\n address anEntryPoint,\n address facetRegistry,\n address _defaultFallBack,\n bytes calldata _ownerPublicKey\n ) external returns (uint256);\n\n function execute(address dest, uint256 value, bytes calldata func) external;\n\n function executeBatch(\n address[] calldata dest,\n uint256[] calldata value,\n bytes[] calldata func\n ) external;\n}\n" + }, + "contracts/facets/interfaces/IAccountRecoveryFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {RecoveryConfig} from \"../../libraries/LibFacetStorage.sol\";\n\n/**\n * @title Account Recovery Facet Interface\n * @dev Interface of contract that enables recovery of accounts when owner key is unavailable\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IAccountRecoveryFacet {\n event RecoveryExecuted(\n bytes indexed recoveryPublicKey,\n uint64 executeAfter\n );\n event RecoveryFinalized(bytes indexed recoveryPublicKey);\n event RecoveryCanceled(bytes indexed recoveryPublicKey);\n event RecoveryApproved(\n bytes indexed recoveryPublicKey,\n address indexed guardian,\n uint64 validUntil\n );\n event RecoveryApprovalRevoked(\n bytes indexed recoveryPublicKey,\n address indexed guardian\n );\n event RecoveryCancellationApproved(\n bytes indexed recoveryPublicKey,\n address indexed guardian\n );\n event RecoveryHardstopped();\n\n error AccountRecoveryFacet__CallerNotGuardian();\n error AccountRecoveryFacet__InvalidRecoveryPublicKey();\n error AccountRecoveryFacet__SignerInitializationFailure();\n error AccountRecoveryFacet__SignerUninitializationFailure();\n error AccountRecoveryFacet__InvalidArrayLength();\n error AccountRecoveryFacet__InsufficientGuardians();\n error AccountRecoveryFacet__RecoveryAlreadyOngoing();\n error AccountRecoveryFacet__NonexistentRecovery();\n error AccountRecoveryFacet__NonExistentApproval();\n error AccountRecoveryFacet__RecoveryPeriodNotOver();\n error AccountRecoveryFacet__InvalidLockPeriod();\n error AccountRecoveryFacet__InvalidRecoveryPeriod();\n error AccountRecoveryFacet__InvalidApprovalValidationPeriod();\n error AccountRecoveryFacet__InvalidGuardian();\n error AccountRecoveryFacet__InvalidGuardianSignature();\n error AccountRecoveryFacet__InvalidOwnerSignature();\n error AccountRecoveryFacet__CallNotSuccesful();\n error AccountRecoveryFacet__DuplicateApproval();\n\n function approveAccountRecovery(bytes calldata recoveryPublicKey) external;\n\n function revokeAccountRecoveryApproval(\n bytes calldata recoveryPublicKey\n ) external;\n\n function executeRecovery(\n bytes calldata recoveryPublicKey,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function finalizeRecovery() external;\n\n function approveCancelRecovery(bytes calldata recoveryPublicKey) external;\n\n function cancelRecovery(\n bytes calldata recoveryPublicKey,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function hardstopRecovery(bytes calldata signature) external;\n\n function getApprovalRecoveryKeyHash(\n bytes memory recoveryPublicKey,\n string memory saltString\n ) external view returns (bytes32);\n\n function getRecoveryApprovalCountWithTimeValidity(\n bytes32 recoveryPublicKeyHash\n ) external view returns (uint256);\n\n function isRecoveryApproved(\n bytes32 recoveryPublicKeyHash,\n address approver\n ) external view returns (bool);\n\n function getRecoveryNonce() external view returns (uint128);\n\n function getPendingRecovery() external view returns (RecoveryConfig memory);\n}\n" + }, + "contracts/facets/interfaces/IGuardianFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Guardian Facet Interface\n * @dev Interface of guaridna contract that enables addition/removal of guardians from Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IGuardianFacet {\n event GuardianAdditionRequested(\n address indexed guardian,\n uint256 executeAfter\n );\n event GuardianRemovalRequested(\n address indexed guardian,\n uint256 executeAfter\n );\n event GuardianAdditionCancelled(address indexed guardian);\n event GuardianRemovalCancelled(address indexed guardian);\n event GuardianAdded(address indexed guardian);\n event GuardianRemoved(address indexed guardian);\n\n error GuardianFacet__GuardianCannotBeSelf();\n error GuardianFacet__DuplicateGuardian();\n error GuardianFacet__OwnerCannotBeGuardian();\n error GuardianFacet__DuplicateGuardianAddition();\n error GuardianFacet__DuplicateGuardianRemoval();\n error GuardianFacet__UnknownPendingAddition();\n error GuardianFacet__PendingAdditionNotOver();\n error GuardianFacet__UnknownPendingRemoval();\n error GuardianFacet__PendingRemovalNotOver();\n error GuardianFacet__PendingAdditionExpired();\n error GuardianFacet__InvalidAdditionSecurityPeriod();\n error GuardianFacet__InvalidRemovalSecurityPeriod();\n error GuardianFacet__InvalidSecurityWindow();\n error GuardianFacet__NonExistentGuardian();\n error GuardianFacet__AlreadyExists();\n error GuardianFacet__InvalidGuardianAddition();\n error GuardianFacet__InvalidGuardianRemoval();\n error GuardianFacet__ZeroAddressGuardian();\n\n function addGuardian(address guardian) external;\n\n function addGuardians(address[] calldata guardians) external;\n\n function removeGuardian(address guardian) external;\n\n function removeGuardians(address[] calldata guardians) external;\n\n function confirmGuardianAddition(address guardian) external;\n\n function confirmGuardianAdditions(address[] calldata guardian) external;\n\n function confirmGuardianRemoval(address guardian) external;\n\n function confirmGuardianRemovals(address[] calldata guardian) external;\n\n function cancelGuardianAddition(address guardian) external;\n\n function cancelGuardianRemoval(address guardian) external;\n\n function isGuardian(address guardian) external view returns (bool);\n\n function isAdditionPending(address guardian) external view returns (bool);\n\n function isRemovalPending(address guardian) external view returns (bool);\n\n function isGuardianFacetRemovable() external view returns (bool);\n\n function getAdditionSecurityPeriod() external view returns (uint256);\n\n function getRemovalSecurityPeriod() external view returns (uint256);\n\n function getSecurityWindow() external view returns (uint256);\n\n function getGuardians() external view returns (address[] memory);\n\n function majorityOfGuardians() external view returns (uint256);\n\n function guardianCount() external view returns (uint256);\n}\n" + }, + "contracts/facets/interfaces/ILockFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Lock} from \"../../libraries/LibAppStorage.sol\";\n\n/**\n * @title Lock Facet Interface\n * @dev Interface of Lock contract that enables full lock/unlock of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface ILockFacet {\n event Locked(uint64 releaseAfter);\n event Unlocked();\n\n error LockFacet__InvalidRecoveryPeriod();\n error LockFacet__CannotUnlock();\n error LockFacet__InvalidSignature();\n error LockFacet__InvalidApprover();\n\n function lock() external;\n\n function unlock(address approver, bytes calldata signature) external;\n\n function getLockPeriod() external view returns (uint256);\n\n function isLocked() external view returns (bool);\n\n function getUnlockHash() external view returns (bytes32);\n\n function lockNonce() external view returns (uint128);\n\n function getPendingLock() external view returns (Lock memory);\n}\n" + }, + "contracts/facets/interfaces/IMultiSigFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Multi-sig facet Interface\n * @dev Interface of Multi-signature Facet with custom threshold.\n Wallet that adds this facet becomes a multi-sig wallet\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IMultiSigFacet {\n event ThresholdChanged(uint256 threshold);\n event OwnerAdded(address indexed newOwner);\n event OwnerRemoved(address indexed prevOwner);\n event HashApproved(bytes32 hashToApprove, address indexed owner);\n\n error MultiSigFacet__InvalidThreshold();\n error MultisigFacet__InvalidOwnerCount();\n error MultiSigFacet__InvalidRoute();\n error MultiSigFacet__InsufficientSignerLength();\n error MultiSigFacet__InvalidInitData();\n error MultiSigFacet__InvalidOwnerAddress();\n error MultiSigFacet__InvalidOwnerPair();\n error MultiSigFacet__InvalidSignatureLength();\n error MultiSigFacet__InvalidSignatureType();\n error MultiSigFacet__DuplicateOwner();\n error MultiSigFacet__OnlyOwner();\n\n function checkSignatures(\n bytes32 _dataHash,\n bytes calldata _signatures,\n uint256 _threshold\n ) external view returns (uint256);\n\n function splitSignatures(\n bytes calldata _signatures,\n uint256 _nextOffset\n )\n external\n pure\n returns (\n address owner,\n bytes memory signature,\n uint256 signatureType,\n uint256 nextOffset\n );\n\n function approveHash(bytes32 hashToApprove) external;\n\n function addOwner(address newOwner, uint256 threshold) external;\n\n function removeOwner(\n address prevOwner,\n address removedOwner,\n uint256 threshold\n ) external;\n\n function swapOwner(\n address prevOwner,\n address oldOwner,\n address newOwner\n ) external;\n\n function changeThreshold(uint256 _threshold) external;\n\n function isOwner(address owner) external view returns (bool);\n\n function getThreshold() external view returns (uint256);\n\n function getOwners() external view returns (address[] memory);\n}\n" + }, + "contracts/facets/interfaces/IRestrictionsFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Restrictions Facet Interface\n * @dev Interface of Restrictions contract that enables modular restrictions in Barz\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IRestrictionsFacet {\n event RestrictionAdded(address indexed restriction);\n event RestrictionRemoved(address indexed restriction);\n\n error RestrictionsFacet__EmptyRestrictionsList();\n error RestrictionsFacet__RestrictionNotFound();\n error RestrictionsFacet__RestrictionAlreadyExists();\n error RestrictionsFacet__ZeroAddressRestrictions();\n error RestrictionsFacet__ZeroAddressRestrictionsFacet();\n error RestrictionsFacet__RemainingRestrictionsCantBeEmpty();\n\n function initializeRestrictions(\n address[] memory _restrictions\n ) external returns (uint256);\n\n function uninitializeRestrictions() external returns (uint256);\n\n function getRestrictions() external view returns (address[] memory);\n\n function addRestriction(address restriction) external;\n\n function removeRestriction(address restriction) external;\n\n function verifyRestrictions(\n address from,\n address to,\n uint256 value,\n bytes calldata _calldata\n ) external returns (uint256);\n}\n" + }, + "contracts/facets/interfaces/ISignatureMigrationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureMigrationConfig} from \"../../libraries/LibFacetStorage.sol\";\n\n/**\n * @title Signature Migration Facet Interface\n * @dev Interface of Signature Migration contract for migrating user signature scheme to a new scheme user sets\n * Which could include\n * - ECDSA on Secp256K1 Curve\n * - ECDSA on Secp256R1 Curve\n * - BLS, Schnorr, etc\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface ISignatureMigrationFacet {\n event SignatureSchemeMigration(\n address indexed prevVerificationFacet,\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n event SignatureMigrationApproved(\n bytes newPublicKey,\n address indexed newVerificationFacet,\n bytes4[] verificationFuncSelectors,\n address indexed guardian,\n uint128 approvalValidUntil\n );\n event SignatureMigrationApprovalRevoked(\n bytes newPublicKey,\n address indexed newVerificationFacet,\n bytes4[] verificationFuncSelectors,\n address indexed guardian\n );\n event SignatureMigrationExecuted(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors,\n uint128 migrateAfter\n );\n event SignatureMigrationCanceled(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n event SignatureMigrationCancellationApproved(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n\n error SignatureMigrationFacet__SignerUninitializationFailure();\n error SignatureMigrationFacet__SignerInitializationFailure();\n error SignatureMigrationFacet__InvalidRouteWithGuardian();\n error SignatureMigrationFacet__InvalidKeyType();\n error SignatureMigrationFacet__InsufficientApprovers();\n error SignatureMigrationFacet__InvalidApproverSignature();\n error SignatureMigrationFacet__InvalidGuardian();\n error SignatureMigrationFacet__NonExistentApprover();\n error SignatureMigrationFacet__InvalidMigrationPeriod();\n error SignatureMigrationFacet__NonexistentMigration();\n error SignatureMigrationFacet__MigrationPeriodNotOver();\n error SignatureMigrationFacet__InvalidArrayLength();\n error SignatureMigrationFacet__InvalidApprovalValidationPeriod();\n error SignatureMigrationFacet__CannotRevokeUnapproved();\n error SignatureMigrationFacet__LackOfOwnerApproval();\n error SignatureMigrationFacet__OwnerAlreadyApproved();\n error SignatureMigrationFacet__NonExistentVerificationFacet();\n error SignatureMigrationFacet__DuplicateApproval();\n\n function migrateSignatureScheme(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function migrateSignatureSchemeWithGuardian(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors,\n address[] calldata approvers,\n bytes[] calldata signatures\n ) external;\n\n function approveSignatureSchemeMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function revokeSignatureMigrationApproval(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function finalizeSignatureMigration() external;\n\n function approveCancelSignatureMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function cancelSignatureMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function getApprovalMigrationKeyHash(\n bytes memory recoveryPublicKey,\n address newVerificationFacet,\n bytes4[] memory newVerificationFuncSelectors,\n string memory saltString\n ) external view returns (bytes32);\n\n function getMigrationOwnerApprovalWithTimeValidity(\n bytes32 publicKeyHash\n ) external view returns (bool);\n\n function getMigrationApprovalCountWithTimeValidity(\n bytes32 publicKeyHash\n ) external view returns (uint256);\n\n function isMigrationApproved(\n bytes32 migrationPublicKeyHash,\n address approver\n ) external view returns (bool);\n\n function getMigrationNonce() external view returns (uint128);\n\n function isMigrationPending() external view returns (bool);\n\n function getPendingMigration()\n external\n view\n returns (SignatureMigrationConfig memory);\n}\n" + }, + "contracts/facets/interfaces/IVerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {UserOperation} from \"../../aa-4337/interfaces/UserOperation.sol\";\n\n/**\n * @title Verification Facet Interface\n * @dev Implements logic for user ops signature verification\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface IVerificationFacet {\n event SignerInitialized(bytes);\n event SignerUninitialized();\n\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n error VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n error VerificationFacet__InitializationFailure();\n error VerificationFacet__InvalidFacetMapping();\n\n function initializeSigner(bytes memory) external returns (uint256);\n\n function uninitializeSigner() external returns (uint256);\n\n function validateOwnerSignatureSelector() external view returns (bytes4);\n\n function owner() external view returns (bytes memory);\n\n function isValidKeyType(bytes calldata) external view returns (bool);\n\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) external view returns (uint256);\n}\n" + }, + "contracts/facets/LockFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage, Lock} from \"../libraries/LibAppStorage.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibFacetStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {ILockFacet} from \"./interfaces/ILockFacet.sol\";\n\n/**\n * @title Lock Facet\n * @dev Contract that enables full lock/unlock of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract LockFacet is ILockFacet, Modifiers {\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Locks the account for the lock period. Lock period is defined in the security manager and it's customizable\n * This function can only be called when account is unlocked by owner or guardians\n * @dev This method checks the caller and if the account is currently locked and locks the account after fetching the\n * Lock period from the owner.\n */\n function lock() external override onlyGuardianOrOwner onlyWhenUnlocked {\n uint256 unlockTime = block.timestamp + getLockPeriod();\n unchecked {\n ++LibFacetStorage.lockStorage().nonce;\n }\n LibAppStorage.setLock(unlockTime, LockFacet.lock.selector);\n emit Locked(uint64(unlockTime));\n }\n\n /**\n * @notice Locks the account when the account is locked. This function can be called by anyone but must provide the approver address and signature.\n * The approver should be one of the guardians or owner.\n * @dev This method takes the approver address and the signature. After validating the address and the signature, it unlocks the account immediately.\n * Only one of the guardian or owner is required to lock and unlock the account.\n * @param _approver Address of approver approving the unlock of Barz account\n * @param _signature Signature of the approver that signed the msg hash for unlocking the account\n */\n function unlock(\n address _approver,\n bytes calldata _signature\n ) external override onlyWhenLocked {\n if (_approver != address(this) && !LibGuardian.isGuardian(_approver))\n revert LockFacet__InvalidApprover();\n if (\n !SignatureChecker.isValidSignatureNow(\n _approver,\n getUnlockHash(),\n _signature\n )\n ) revert LockFacet__InvalidSignature();\n _unlock();\n }\n\n /**\n * @notice Unlocks the account and increments the lock nonce\n */\n function _unlock() private {\n if (s.locks[INNER_STRUCT].locker != LockFacet.lock.selector)\n revert LockFacet__CannotUnlock();\n unchecked {\n ++LibFacetStorage.lockStorage().nonce;\n }\n LibAppStorage.setLock(0, bytes4(0));\n emit Unlocked();\n }\n\n /**\n * @notice Returns the lock period of current Barz account. Lock period information is held by Security Manager\n * @return lockPeriod Uint value of lock period in seconds\n */\n function getLockPeriod() public view override returns (uint256 lockPeriod) {\n lockPeriod = securityManager.lockPeriodOf(address(this));\n if (lockPeriod == 0) revert LockFacet__InvalidRecoveryPeriod();\n }\n\n /**\n * @notice Returns if the account is locked or not\n * @dev This method fetches the current block timestamp and compares that with release time.\n * After checking the timestamp and release time, it returns if the account is still locked or not.\n * @return isLocked_ Uint value of lock period in seconds\n */\n function isLocked() public view override returns (bool isLocked_) {\n isLocked_ = uint64(block.timestamp) < s.locks[INNER_STRUCT].release;\n }\n\n /**\n * @notice Calculates the unlock hash and returns the unlock hash safe from signature reply attack\n * @dev This method calculates the unlock hash with EIP-191 prefix, wallet address, chainID, and nonce\n * It packs the result and packs them and hashes it.\n * @return unlockHash Bytes32 unlock hash\n */\n function getUnlockHash() public view override returns (bytes32 unlockHash) {\n unlockHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n \"Unlock\",\n address(this),\n block.chainid,\n lockNonce()\n )\n )\n )\n );\n }\n\n /**\n * @notice Returns lock nonce of account. Reads nonce from lock storage within facet storage\n * @return lockNonce_ Uint128 value of lock nonce. This is incremented whenever the account is lock/unlocked\n */\n function lockNonce() public view override returns (uint128 lockNonce_) {\n lockNonce_ = LibFacetStorage.lockStorage().nonce;\n }\n\n /**\n * @notice Returns the overall information of current lock\n * @return pendingLock Struct value including all information of pending lock\n */\n function getPendingLock()\n public\n view\n override\n returns (Lock memory pendingLock)\n {\n pendingLock = s.locks[INNER_STRUCT];\n }\n}\n" + }, + "contracts/facets/Modifiers.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\n\n/**\n * @title Modifiers\n * @dev Responsible for providing modifiers/util functions to Facet contracts\n * @author David Yongjun Kim (@Powerstream3604)\n */\nabstract contract Modifiers is BarzStorage {\n uint8 constant INNER_STRUCT = 0;\n\n error CallerNotGuardian();\n error CallerNotGuardianOrOwner();\n error DuplicateApprover();\n error ZeroApproverLength();\n error UnregisteredFacetAndSelectors();\n\n /**\n * @notice Modifier to only allow guardian to make a call, reverts if any other entity is the caller\n */\n modifier onlyGuardian() {\n if (!LibGuardian.isGuardian(msg.sender)) revert CallerNotGuardian();\n _;\n }\n\n /**\n * @notice Modifier to only allow guardian or owner to make a call, reverts if any other entity is the caller\n */\n modifier onlyGuardianOrOwner() {\n if (!LibGuardian.isGuardian(msg.sender) && address(this) != msg.sender)\n revert CallerNotGuardianOrOwner();\n _;\n }\n\n /**\n * @notice Checks if the approver address is the array is unique with no duplicate\n * @dev This method loops through the array and checks if a duplicate address exists, it reverts if duplicate address exists\n * @param approvers Array of address\n */\n function _checkApprover(\n address[] memory approvers\n ) internal pure returns (bool) {\n uint256 approverLength = approvers.length;\n if (0 == approverLength) revert ZeroApproverLength();\n for (uint256 i; i < approverLength - 1; ) {\n for (uint256 j = i + 1; j < approverLength; ) {\n if (approvers[i] == approvers[j]) {\n revert DuplicateApprover(); // Found a duplicate\n }\n unchecked {\n ++j;\n }\n }\n unchecked {\n ++i;\n }\n }\n return false; // No duplicates found\n }\n\n /**\n * @notice Checks if the facet getting added or replaced is registered to facet registry\n * @dev This method loops through the cut and checks if the facet getting added/replaced is registered to facet registry\n * @param _diamondCut Array of FacetCut, data for diamondCut defined in EIP-2535\n */\n function _checkFacetCutValidity(\n IDiamondCut.FacetCut[] memory _diamondCut\n ) internal view {\n uint256 diamondCutLength = _diamondCut.length;\n for (uint256 i; i < diamondCutLength; ) {\n if (\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Add ||\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Replace\n ) {\n if (\n !s.facetRegistry.areFacetFunctionSelectorsRegistered(\n _diamondCut[i].facetAddress,\n _diamondCut[i].functionSelectors\n )\n ) revert UnregisteredFacetAndSelectors();\n }\n unchecked {\n ++i;\n }\n }\n }\n}\n" + }, + "contracts/facets/RestrictionsFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ReentrancyGuard} from \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, RestrictionsStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {IRestriction} from \"../restrictions/IRestriction.sol\";\nimport {IRestrictionsFacet} from \"./interfaces/IRestrictionsFacet.sol\";\n\n/**\n * @title Restrictions facet\n * @dev Responsible for storing and verifying different kinds of restrictions, for example:\n * - Whitelist / Blacklist\n * - Daily limits\n * - Trading time restrictions\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract RestrictionsFacet is IRestrictionsFacet, ReentrancyGuard {\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceRestrictionsInitialize();\n }\n\n /**\n * @notice Intialize restrictions of Barz. Restrictions facet call restriction contracts for restriction validation\n * before each call\n * @param _restrictions The initial array of restrictions.\n * @return initSuccess Int value showing if the initialization of restriction is successful\n */\n function initializeRestrictions(\n address[] calldata _restrictions\n ) public override returns (uint256 initSuccess) {\n LibDiamond.enforceIsSelf();\n LibAppStorage.enforceRestrictionsInitialize();\n\n if (_restrictions.length == 0) {\n // You can't initialize RestrictionsFacet with an empty list of restrictions\n revert RestrictionsFacet__EmptyRestrictionsList();\n }\n for (uint256 i; i < _restrictions.length; ) {\n if (_restrictions[i] == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictions();\n unchecked {\n ++i;\n }\n }\n\n LibFacetStorage.restrictionsStorage().restrictions = _restrictions;\n _updateRestrictionsMap(_restrictions, true);\n initSuccess = 1;\n }\n\n /**\n * @notice Unitialize restrictions of Barz\n * @return uninitSuccess Int value showing if the initialization of restriction is successful\n */\n function uninitializeRestrictions()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibDiamond.enforceIsSelf();\n LibAppStorage.setRestrictionsUninitialized();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n _updateRestrictionsMap(restrictionsStorage.restrictions, false);\n restrictionsStorage.restrictions = new address[](0);\n uninitSuccess = 1;\n }\n\n /**\n * @notice Returns the list of Restrictions contract address\n * @return restrictions Addresses of IRestriction which are currently active\n */\n function getRestrictions()\n public\n view\n override\n returns (address[] memory restrictions)\n {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n restrictions = restrictionsStorage.restrictions;\n }\n\n /**\n * @notice Adds restrictions to Barz with validation on the restriction contract address.\n * This method is only callable by the owner(self).\n * @param _restriction The address of the restriction to be added.\n */\n function addRestriction(address _restriction) external override {\n LibDiamond.enforceIsSelf();\n if (LibDiamond.restrictionsFacet() == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictionsFacet();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n if (_restriction == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictions();\n if (restrictionsStorage.exists[_restriction])\n revert RestrictionsFacet__RestrictionAlreadyExists();\n\n restrictionsStorage.restrictions.push(_restriction);\n restrictionsStorage.exists[_restriction] = true;\n\n emit RestrictionAdded(_restriction);\n }\n\n /**\n * @notice Remove restrictions from Barz if it existed. This method is only callable by the owner(self).\n * @param _restriction The address of the restriction to be removed.\n */\n function removeRestriction(address _restriction) external override {\n LibDiamond.enforceIsSelf();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n if (!restrictionsStorage.exists[_restriction])\n revert RestrictionsFacet__RestrictionNotFound();\n\n address[] storage restrictions = restrictionsStorage.restrictions;\n\n uint256 indexToDelete = restrictions.length;\n uint256 restrictionsLen = restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n if (restrictions[i] == _restriction) {\n indexToDelete = i;\n break;\n }\n unchecked {\n ++i;\n }\n }\n\n if (indexToDelete == 0 && restrictionsLen == 1) {\n revert RestrictionsFacet__RemainingRestrictionsCantBeEmpty();\n } else if (indexToDelete == restrictionsLen) {\n revert RestrictionsFacet__RestrictionNotFound();\n } else {\n restrictions[indexToDelete] = restrictions[restrictionsLen - 1];\n restrictions.pop();\n }\n\n restrictionsStorage.exists[_restriction] = false;\n emit RestrictionRemoved(_restriction);\n }\n\n /**\n * @notice Sets the restrictions address value mapping to true or false when adding/removing restriction contracts\n * @param _restrictions List of restriction contracts address\n * @param _newValue Bool value to flag to the list of restrictions contracts\n */\n function _updateRestrictionsMap(\n address[] memory _restrictions,\n bool _newValue\n ) internal {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n uint restrictionsLen = _restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n restrictionsStorage.exists[_restrictions[i]] = _newValue;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @dev Iterates over all restrictions and verifies each of them with the transaction parameters.\n * @param _from The address of the sender, that will be signing the transaction.\n * @param _to The receiving address.\n * @param _value Amount of ETH to transfer from sender to recipient.\n * @param _calldata Optional field to include arbitrary data.\n * @return 0 if all the checks passed, 1 otherwise.\n */\n function verifyRestrictions(\n address _from,\n address _to,\n uint256 _value,\n bytes calldata _calldata\n ) external nonReentrant returns (uint256) {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n uint restrictionsLen = restrictionsStorage.restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n IRestriction restriction = IRestriction(\n restrictionsStorage.restrictions[i]\n );\n bool checkPassed = restriction.check(_from, _to, _value, _calldata);\n if (!checkPassed) {\n return 1;\n }\n unchecked {\n ++i;\n }\n }\n\n return 0;\n }\n}\n" + }, + "contracts/facets/SignatureMigrationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, SignatureMigrationStorage, SignatureMigrationConfig, SignatureMigrationApprovalConfig, ApprovalConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IDiamondCut} from \"./base/interfaces/IDiamondCut.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {ISignatureMigrationFacet} from \"./interfaces/ISignatureMigrationFacet.sol\";\n\n/**\n * @title Signature Migration Facet\n * @dev Responsible for migrating user signature scheme to a new scheme user sets\n * Which could include\n * - ECDSA on Secp256K1 Curve\n * - ECDSA on Secp256R1 Curve\n * - BLS, Schnorr, etc\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract SignatureMigrationFacet is ISignatureMigrationFacet, Modifiers {\n bytes constant UNINIT_CALL =\n abi.encodeWithSignature(\"uninitializeSigner()\");\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This modifier verifies if the public key format matches with the new verification facet\n * @param _publicKey Bytes of public key to be validated for the new verification facet\n * @param _newVerificationFacet Address of new verification facet\n */\n modifier validateKeyType(\n bytes memory _publicKey,\n address _newVerificationFacet\n ) {\n if (\n !IVerificationFacet(_newVerificationFacet).isValidKeyType(\n _publicKey\n )\n ) revert SignatureMigrationFacet__InvalidKeyType();\n _;\n }\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n // IMPORTANT NOTE: In the client side when they call this function, the func selectors should be sorted in ascending order\n // to prevent different hash with same items in the array\n /**\n * @notice Moves the state of migration to a pending state. When pending state is over after pending period time,\n * Migration can be finalized. This function can only be called by self and when the account is unlocked.\n * @dev This method checks if the caller is self and if guardians exists. It migrates signature request to a pending state\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function migrateSignatureScheme(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n public\n override\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n // Only self contract can call this function\n LibDiamond.enforceIsSelf();\n // Should revert if guardian exist\n if (0 != LibGuardian.guardianCount())\n revert SignatureMigrationFacet__InvalidRouteWithGuardian();\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n // NOTE: Migration requires a pending period & confirmation from owner to prevent a\n // single call changing the ownership of the wallet\n /**\n * @notice Migrate signature scheme when guardians exists. Verifies the signature of guardians and moves migration to pending state.\n * Which can then be finalized when pending period is over. Owner's approval is mandatory for migration to happen\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _approvers List of approvers. This could include owner\n */\n function migrateSignatureSchemeWithGuardian(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n )\n public\n override\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n // Should revert if does not guardian exist\n if (0 == LibGuardian.guardianCount())\n revert SignatureMigrationFacet__InvalidRouteWithGuardian();\n if (_approvers.length != _signatures.length)\n revert SignatureMigrationFacet__InvalidArrayLength();\n\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(migrationPublicKeyHash, _approvers);\n\n bool onChainOwnerApproval = getMigrationOwnerApprovalWithTimeValidity(\n migrationPublicKeyHash\n );\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n\n if (\n _approvers.length +\n getMigrationApprovalCountWithTimeValidity(\n migrationPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert SignatureMigrationFacet__InsufficientApprovers();\n {\n // To prevent Stack too deep\n bool ownerApproved;\n for (uint256 i; i < _approvers.length; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n address(this) != _approvers[i]\n ) revert SignatureMigrationFacet__InvalidGuardian();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert SignatureMigrationFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n migrationPublicKeyHash,\n _signatures[i]\n )\n ) revert SignatureMigrationFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n\n if (!ownerApproved && !onChainOwnerApproval)\n revert SignatureMigrationFacet__LackOfOwnerApproval();\n }\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Internal function that moves signature mgiration to a pending state.\n * @dev This method increments migration nonce and sets the migration in the migration config. Emits events for migration execution\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _migrateSignatureScheme(\n address _newVerificationFacet,\n bytes memory _newPublicKey,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal {\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n unchecked {\n ++ms.nonce;\n }\n uint64 migrateAfter = uint64(block.timestamp + getMigrationPeriod());\n\n ms.migrationConfigs[INNER_STRUCT] = SignatureMigrationConfig(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n migrateAfter\n );\n\n emit SignatureMigrationExecuted(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors,\n migrateAfter\n );\n }\n\n /**\n * @notice Approves signature scheme migration on-chain. This can be called by owner or guardian only when the account is unlocked.\n * When the threshold of the migration approval passed and owner approval is granted, it automatically moves migration to a pending state\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function approveSignatureSchemeMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n public\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit SignatureMigrationApproved(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n msg.sender,\n approvalValidUntil\n );\n if (\n getMigrationApprovalCountWithTimeValidity(migrationPublicKeyHash) >=\n LibGuardian.majorityOfGuardians() &&\n getMigrationOwnerApprovalWithTimeValidity(migrationPublicKeyHash)\n )\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Revokes the approval of signature migration done on-chain. Emits revoke event when revoked.\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function revokeSignatureMigrationApproval(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n external\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n if (!isMigrationApproved(migrationPublicKeyHash, msg.sender))\n revert SignatureMigrationFacet__CannotRevokeUnapproved();\n\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(false, 0);\n emit SignatureMigrationApprovalRevoked(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n msg.sender\n );\n }\n\n /**\n * @notice Finalizes the pending signature scheme migration. This function can only be called by owner.\n * It removes the facets of the previous verification facet and adds the new verification facet.\n * After finalizing migration, it emits migration event which shows the change of the verification facet\n */\n function finalizeSignatureMigration() external override {\n // NOTE: Only owner can call this function\n LibDiamond.enforceIsSelf();\n\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n\n if (!isMigrationPending())\n revert SignatureMigrationFacet__NonexistentMigration();\n\n if (\n uint64(block.timestamp) <=\n ms.migrationConfigs[INNER_STRUCT].migrateAfter\n ) revert SignatureMigrationFacet__MigrationPeriodNotOver();\n address newVerificationFacet = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationVerificationFacet;\n bytes4[] memory newVerificationFuncSelectors = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationSelectors;\n bytes memory newPublicKey = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationPublicKey;\n\n address prevVerificationFacet = LibLoupe.facetAddress(\n s.validateOwnerSignatureSelector\n );\n if (prevVerificationFacet == address(0))\n revert SignatureMigrationFacet__NonExistentVerificationFacet();\n\n IDiamondCut.FacetCut[] memory UninitCut;\n IDiamondCut.FacetCut[] memory InitCut;\n {\n bytes4[] memory prevVerificationFuncSelectors = LibLoupe\n .facetFunctionSelectors(prevVerificationFacet);\n\n UninitCut = new IDiamondCut.FacetCut[](1);\n InitCut = new IDiamondCut.FacetCut[](1);\n UninitCut[0] = IDiamondCut.FacetCut({\n facetAddress: address(0),\n action: IDiamondCut.FacetCutAction.Remove,\n functionSelectors: prevVerificationFuncSelectors\n });\n InitCut[0] = IDiamondCut.FacetCut({\n facetAddress: newVerificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: newVerificationFuncSelectors\n });\n {\n IDiamondCut.FacetCut[]\n memory facetCuts = new IDiamondCut.FacetCut[](2);\n facetCuts[0] = UninitCut[0];\n facetCuts[1] = InitCut[0];\n _checkFacetCutValidity(facetCuts);\n }\n LibAppStorage.initiateSignerMigration();\n address verificationFacet = address(\n bytes20(\n LibDiamond.diamondStorage().facets[\n s.validateOwnerSignatureSelector\n ]\n )\n );\n\n (bool uninitSuccess, bytes memory uninitResult) = verificationFacet\n .delegatecall(UNINIT_CALL);\n if (!uninitSuccess || uint256(bytes32(uninitResult)) != 1)\n revert SignatureMigrationFacet__SignerUninitializationFailure();\n LibAppStorage.finalizeSignerMigration();\n\n LibDiamond.diamondCut(UninitCut, address(0), \"\");\n }\n {\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n newPublicKey\n );\n\n // Every Verification Facet should comply with initializeSigner(bytes)\n // to be compatible with the Barz contract(for initialization)\n LibDiamond.diamondCut(InitCut, address(0), \"\");\n (bool initSuccess, bytes memory initResult) = newVerificationFacet\n .delegatecall(initCall);\n if (!initSuccess || uint256(bytes32(initResult)) != 1)\n revert SignatureMigrationFacet__SignerInitializationFailure();\n\n emit SignatureSchemeMigration(\n prevVerificationFacet,\n newVerificationFacet,\n newPublicKey,\n newVerificationFuncSelectors\n );\n }\n }\n\n /**\n * @notice Approve cancellation of signature migration. If cancellation approval passes guardian threshold with owner approval\n * it automatically cancels the migration.\n * @dev This method checks if the caller is one of guardian or owner and sets true for the cancellation hash in the approval config.\n * It internally calls _cancelSignatureMigration for canceling the migration\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function approveCancelSignatureMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n external\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"CancelSignatureMigration\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit SignatureMigrationCancellationApproved(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n if (\n getMigrationApprovalCountWithTimeValidity(migrationPublicKeyHash) >=\n LibGuardian.majorityOfGuardians() &&\n getMigrationOwnerApprovalWithTimeValidity(migrationPublicKeyHash)\n )\n _cancelSignatureMigration(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Verifies the signature of guardians/owner and cancels the signature migration.\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _approvers List of approvers. This could include owner\n */\n function cancelSignatureMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n )\n external\n override\n validateKeyType(_newPublicKey, _newVerificationFacet)\n onlyWhenUnlocked\n {\n if (_approvers.length != _signatures.length)\n revert SignatureMigrationFacet__InvalidArrayLength();\n\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"CancelSignatureMigration\"\n );\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(migrationPublicKeyHash, _approvers);\n\n bool onChainOwnerApproval = getMigrationOwnerApprovalWithTimeValidity(\n migrationPublicKeyHash\n );\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n if (\n _approvers.length +\n getMigrationApprovalCountWithTimeValidity(\n migrationPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert SignatureMigrationFacet__InsufficientApprovers();\n {\n // To prevent stack too deep\n bool ownerApproved;\n for (uint256 i; i < _approvers.length; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n address(this) != _approvers[i]\n ) revert SignatureMigrationFacet__NonExistentApprover();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert SignatureMigrationFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n migrationPublicKeyHash,\n _signatures[i]\n )\n ) revert SignatureMigrationFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n if (!ownerApproved && !onChainOwnerApproval)\n revert SignatureMigrationFacet__LackOfOwnerApproval();\n }\n _cancelSignatureMigration(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Internal function that cancels signature migration.\n * @dev This method increments migration nonce and deletes the migration from the migration config. Emits events for migration cancellation\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _cancelSignatureMigration(\n address _newVerificationFacet,\n bytes memory _newPublicKey,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal {\n if (!isMigrationPending())\n revert SignatureMigrationFacet__NonexistentMigration();\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n unchecked {\n ++ms.nonce;\n }\n delete ms.migrationConfigs[INNER_STRUCT];\n emit SignatureMigrationCanceled(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Checks if the facets to be added from new verification facet is registered to facet registry\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _checkMigrationCutValidity(\n address _newVerificationFacet,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal view {\n IDiamondCut.FacetCut[] memory facetCuts = new IDiamondCut.FacetCut[](1);\n facetCuts[0] = IDiamondCut.FacetCut({\n facetAddress: _newVerificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: _newVerificationFuncSelectors\n });\n _checkFacetCutValidity(facetCuts);\n }\n\n /**\n * @notice Returns if the migration is pending of not\n * @dev This method fetches the migration storage and checks if the migrate after is above 0 value\n * @return isPending Bool value that shows if the migration is pending\n */\n function isMigrationPending()\n public\n view\n override\n returns (bool isPending)\n {\n SignatureMigrationStorage storage rs = LibFacetStorage\n .migrationStorage();\n isPending = rs.migrationConfigs[INNER_STRUCT].migrateAfter > 0;\n }\n\n /**\n * @notice Returns the migration hash. This function ensures that this hash is safe from replay attack by including\n * public key, verification facet, function selectors, salt, address, chainId, and nonce.\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _saltString Salt value for generating the migration hash\n * @return migrationKeyHash Bytes32 string of the migration key hash\n */\n function getApprovalMigrationKeyHash(\n bytes memory _newPublicKey,\n address _newVerificationFacet,\n bytes4[] memory _newVerificationFuncSelectors,\n string memory _saltString\n ) public view override returns (bytes32 migrationKeyHash) {\n migrationKeyHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n _newPublicKey,\n _newVerificationFacet,\n keccak256(abi.encode(_newVerificationFuncSelectors)),\n _saltString,\n address(this),\n block.chainid,\n LibFacetStorage.migrationStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Checks if the owner approved the hash for migration\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @return isApprovedByOwner Bool value of showing if the owner approved it or not\n */\n function getMigrationOwnerApprovalWithTimeValidity(\n bytes32 _migrationPublicKeyHash\n ) public view override returns (bool isApprovedByOwner) {\n isApprovedByOwner = isMigrationApproved(\n _migrationPublicKeyHash,\n address(this)\n );\n }\n\n /**\n * @notice Checks how many of the guardians approved the migration hash\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @return approvalCount Number of approvals\n */\n function getMigrationApprovalCountWithTimeValidity(\n bytes32 _migrationPublicKeyHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardiansLength = guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n if (isMigrationApproved(_migrationPublicKeyHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n return approvalCount;\n }\n\n /**\n * @notice Checks if the migration is approved by the given approver\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @param _approver Address of approver\n * @return isApproved Bool value if migration hash is approved\n */\n function isMigrationApproved(\n bytes32 _migrationPublicKeyHash,\n address _approver\n ) public view override returns (bool isApproved) {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n isApproved = (ms\n .isMigrationApproved[_migrationPublicKeyHash][_approver].isApproved &&\n block.timestamp <\n ms\n .isMigrationApproved[_migrationPublicKeyHash][_approver]\n .validUntil);\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _migrationPublicKeyHash Hash of migration information\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _migrationPublicKeyHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isMigrationApproved(_migrationPublicKeyHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert SignatureMigrationFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the migration period of this wallet\n * @dev This method fetches the migration period from the security manager\n * @return migrationPeriod Migration period of Barz contract fetched from security manager\n */\n function getMigrationPeriod()\n internal\n view\n returns (uint128 migrationPeriod)\n {\n migrationPeriod = securityManager.migrationPeriodOf(address(this));\n if (migrationPeriod == 0)\n revert SignatureMigrationFacet__InvalidMigrationPeriod();\n }\n\n /**\n * @notice Returns the validation period of this wallet\n * @dev This method fetches the validation period from the security manager\n * @return approvalValidationPeriod Validation period of Barz contract fetched from security manager\n */\n function getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod == 0)\n revert SignatureMigrationFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the migration nonce of this wallet\n * @dev This method fetches the nonce from migration storage\n * @return migrationNonce Nonce of migration to protect from reply attacks\n */\n function getMigrationNonce()\n public\n view\n override\n returns (uint128 migrationNonce)\n {\n migrationNonce = LibFacetStorage.migrationStorage().nonce;\n }\n\n /**\n * @notice Returns the migration configuration of this wallet\n * @dev This method fetches the migration config from the migration storage\n * @return pendingMigrationConfig Migration config currently pending for signature migration\n */\n function getPendingMigration()\n external\n view\n override\n returns (SignatureMigrationConfig memory pendingMigrationConfig)\n {\n pendingMigrationConfig = LibFacetStorage\n .migrationStorage()\n .migrationConfigs[INNER_STRUCT];\n }\n}\n" + }, + "contracts/facets/TokenReceiverFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {IERC1155Receiver} from \"../interfaces/ERC/IERC1155Receiver.sol\";\nimport {IERC677Receiver} from \"../interfaces/ERC/IERC677Receiver.sol\";\n\n/**\n * @title TokenReceiver Facet\n * @dev Contract that enables receiving ERC721/ERC1155/ERC777/ERC677 Tokens with safe transfer\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract TokenReceiverFacet is\n IERC721Receiver,\n IERC1155Receiver,\n IERC777Recipient,\n IERC677Receiver\n{\n /**\n * @notice Handles ERC721 Token callback.\n * return Standardized onERC721Received return value.\n */\n function onERC721Received(\n address,\n address,\n uint256,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC721Receiver.onERC721Received.selector;\n }\n\n /**\n * @notice Handles ERC1155 Token callback.\n * return Standardized onERC1155Received return value.\n */\n function onERC1155Received(\n address,\n address,\n uint256,\n uint256,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC1155Receiver.onERC1155Received.selector;\n }\n\n /**\n * @notice Handles ERC1155 Token batch callback.\n * return Standardized onERC1155BatchReceived return value.\n */\n function onERC1155BatchReceived(\n address,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC1155Receiver.onERC1155BatchReceived.selector;\n }\n\n /**\n * @notice Handles ERC777 Token callback.\n * Does not return value, empty implementation.\n */\n function tokensReceived(\n address,\n address,\n address,\n uint256,\n bytes calldata,\n bytes calldata\n ) external pure override {}\n\n /**\n * @notice Handles ERC677 Token callback.\n * return true.\n */\n function onTokenTransfer(\n address,\n uint256,\n bytes calldata\n ) external pure override returns (bool) {\n return true;\n }\n}\n" + }, + "contracts/facets/verification/MultiSigFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {UserOperation} from \"../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../../libraries/LibLoupe.sol\";\nimport {LibAppStorage} from \"../../libraries/LibAppStorage.sol\";\nimport {LibMultiSigStorage, MultiSigStorage} from \"../../libraries/LibMultiSigStorage.sol\";\nimport {IERC1271} from \"../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../interfaces/IVerificationFacet.sol\";\nimport {IMultiSigFacet} from \"../interfaces/IMultiSigFacet.sol\";\n\n/**\n * @title Multi-sig facet\n * @dev Multi-signature Facet with custom threshold.\n * Wallet that adds this facet becomes a multi-sig wallet.\n * Reference signature_format.md documentation for Multi-sig facet details\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract MultiSigFacet is IMultiSigFacet, IVerificationFacet, IERC1271 {\n using ECDSA for bytes32;\n\n address public immutable self;\n\n address internal constant SENTINEL_OWNERS = address(0x1);\n uint256 internal constant ADDRESS = 20;\n uint256 internal constant SIG_TYPE = 1;\n uint256 internal constant SIG_LEN = 4;\n uint256 internal constant THRESHOLD = 4;\n uint256 internal constant INVALID_SIG = 1;\n uint256 internal constant VALID_SIG = 0;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in Multisig Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the right format and initializes signer storage in k1 storage.\n * @param _owners Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _owners\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n\n if (!isValidKeyType(_owners)) revert MultiSigFacet__InvalidInitData();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n uint256 threshold = uint256(uint32(bytes4(_owners)));\n uint256 ownerCount = (_owners.length - THRESHOLD) / ADDRESS;\n\n if (threshold == 0) revert MultiSigFacet__InvalidThreshold();\n if (ownerCount == 0) revert MultisigFacet__InvalidOwnerCount();\n\n address currentOwner = SENTINEL_OWNERS;\n uint256 ptr = THRESHOLD;\n address owner_;\n for (uint256 i; i < ownerCount; ) {\n owner_ = address(bytes20(_owners[ptr:ptr + ADDRESS]));\n ptr += ADDRESS;\n if (\n owner_ == address(0) ||\n owner_ == SENTINEL_OWNERS ||\n owner_ == address(this) ||\n owner_ == currentOwner\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[owner_] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n\n ms.owners[currentOwner] = owner_;\n currentOwner = owner_;\n\n unchecked {\n ++i;\n }\n }\n ms.owners[currentOwner] = SENTINEL_OWNERS;\n ms.ownerCount = ownerCount;\n ms.threshold = threshold;\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_owners);\n }\n\n /**\n * @notice Uninitialize signer in K1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n ++ms.counter;\n address[] memory ownerlist = getOwners();\n uint256 ownerlistLength = ownerlist.length;\n for (uint256 i; i < ownerlistLength; ) {\n ms.owners[ownerlist[i]] = address(0);\n unchecked {\n ++i;\n }\n }\n ms.owners[SENTINEL_OWNERS] = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls checkSignatures with\n * user operation hash and signature together with the threshold.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n // Data 1 is invalid, Data 0 is valid\n validationData = checkSignatures(\n userOpHash,\n userOp.signature,\n LibMultiSigStorage.multisigStorage().threshold\n );\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n return this.validateOwnerSignature.selector;\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n uint totalLength = ms.ownerCount * ADDRESS;\n bytes memory result = new bytes(totalLength);\n\n // populate return array\n uint256 index;\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n while (currentOwner != SENTINEL_OWNERS) {\n assembly {\n mstore(\n add(result, add(32, mul(index, ADDRESS))),\n shl(96, currentOwner)\n )\n }\n currentOwner = ms.owners[currentOwner];\n index++;\n }\n\n return result;\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key should comply with the format in the signature_format.md doc\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n uint256 publicKeyLength = _publicKey.length;\n if (\n publicKeyLength < ADDRESS + THRESHOLD ||\n (publicKeyLength - THRESHOLD) % ADDRESS != 0\n ) return false;\n\n uint256 threshold = uint256(uint32(bytes4(_publicKey)));\n uint256 ownerCount = (publicKeyLength - THRESHOLD) / ADDRESS;\n\n isValid = !(ownerCount < threshold || threshold == 0);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes calldata _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (checkSignatures(\n _hash,\n _signature,\n LibMultiSigStorage.multisigStorage().threshold\n ) == VALID_SIG)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n\n /**\n * @notice Validates the format of the signature and verifies if the signature is signed by the expected key.\n * Reference signature_format.md doc for details about signature format and signature types\n * @param _dataHash Bytes value of data hash signed by the owners\n * @param _signatures Bytes value of signature which should comply with signature format\n * @param _threshold Uint256 value of current Multi-sig Barz's threshold\n */\n function checkSignatures(\n bytes32 _dataHash,\n bytes calldata _signatures,\n uint256 _threshold\n ) public view returns (uint256) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n address lastOwner = address(0);\n address currentOwner;\n bytes memory signature;\n uint256 signatureType;\n uint256 nextOffset;\n uint256 i;\n for (i; i < _threshold; ) {\n (\n currentOwner,\n signature,\n signatureType,\n nextOffset\n ) = splitSignatures(_signatures, nextOffset);\n if (nextOffset == 0 && i + 1 < _threshold) return INVALID_SIG;\n if (signatureType == 1) {\n // If signatureType is 1 then it is default dataHash signed.\n // This also includes the contract signature\n if (\n !SignatureChecker.isValidSignatureNow(\n currentOwner,\n _dataHash,\n signature\n )\n ) return INVALID_SIG;\n } else if (signatureType == 2) {\n // If signatureType is 2 then it is an approved hash\n if (ms.approvedHashes[ms.counter][currentOwner][_dataHash] == 0)\n return INVALID_SIG;\n } else if (signatureType == 3) {\n // If signatureType is 3 then it is a signed message hash\n // This also includes the contract signature\n bytes32 msgHash = _dataHash.toEthSignedMessageHash();\n if (\n !SignatureChecker.isValidSignatureNow(\n currentOwner,\n msgHash,\n signature\n )\n ) return INVALID_SIG;\n } else revert MultiSigFacet__InvalidRoute();\n if (\n currentOwner <= lastOwner ||\n ms.owners[currentOwner] == address(0) ||\n currentOwner == SENTINEL_OWNERS\n ) return INVALID_SIG;\n lastOwner = currentOwner;\n\n unchecked {\n ++i;\n }\n }\n return VALID_SIG;\n }\n\n /**\n * @notice Split signatures into each individual signatures. Should comply with signature format to be split\n * @param _signatures Bytes value of signature\n * @param _nextOffset Uint256 value of next offset to start splitting the signature\n */\n function splitSignatures(\n bytes calldata _signatures,\n uint256 _nextOffset\n )\n public\n pure\n returns (\n address owner_,\n bytes memory signature,\n uint256 signatureType,\n uint256 nextOffset\n )\n {\n uint256 signaturesLength = _signatures.length;\n\n if (signaturesLength <= _nextOffset + ADDRESS + SIG_LEN)\n revert MultiSigFacet__InsufficientSignerLength();\n\n owner_ = address(\n bytes20(_signatures[_nextOffset:_nextOffset + ADDRESS])\n );\n\n signatureType = uint256(\n uint8(\n bytes1(\n _signatures[_nextOffset + ADDRESS:_nextOffset +\n ADDRESS +\n SIG_TYPE]\n )\n )\n );\n\n if (signatureType > 3 || signatureType == 0)\n revert MultiSigFacet__InvalidSignatureType();\n uint256 offSet = _nextOffset + ADDRESS + SIG_TYPE;\n uint256 siglen = uint256(\n uint32(bytes4(_signatures[offSet:offSet + SIG_LEN]))\n );\n if (offSet + siglen > signaturesLength)\n revert MultiSigFacet__InvalidSignatureLength();\n\n offSet += SIG_LEN;\n if (offSet + siglen == signaturesLength) nextOffset = 0;\n else nextOffset = offSet + siglen;\n\n signature = _signatures[offSet:offSet + siglen];\n }\n\n /**\n * @notice Approves the hash of userOperation on-chain. This can only be called by owners.\n * @param _hashToApprove Bytes value of UserOperation hash to approve\n */\n function approveHash(bytes32 _hashToApprove) external {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (ms.owners[msg.sender] == address(0))\n revert MultiSigFacet__OnlyOwner();\n\n ms.approvedHashes[ms.counter][msg.sender][_hashToApprove] = 1;\n emit HashApproved(_hashToApprove, msg.sender);\n }\n\n /**\n * @notice Add owner to Barz. Update thresold if threshold is given different from current threshold\n * @dev This can only be done via a Self call.\n * @param _newOwner Address of new owner to be added\n * @param _threshold Uint256 value of threshold\n */\n function addOwner(address _newOwner, uint256 _threshold) external {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (\n _newOwner == address(0) ||\n _newOwner == SENTINEL_OWNERS ||\n _newOwner == address(this)\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_newOwner] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n\n ms.owners[_newOwner] = ms.owners[SENTINEL_OWNERS];\n ms.owners[SENTINEL_OWNERS] = _newOwner;\n ++ms.ownerCount;\n emit OwnerAdded(_newOwner);\n\n if (ms.threshold != _threshold) changeThreshold(_threshold);\n }\n\n /**\n * @notice Remove owner from Barz. Update thresold if threshold is given different from current threshold\n * @dev This can only be done via a Self call.\n * @param _prevOwner Address of owner located right behind the removed owner address in the linked list\n * @param _removedOwner Address of owner to be removed\n * @param _threshold Uint256 value of threshold\n */\n function removeOwner(\n address _prevOwner,\n address _removedOwner,\n uint256 _threshold\n ) external {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (ms.ownerCount - 1 < _threshold)\n revert MultiSigFacet__InvalidThreshold();\n if (_removedOwner == address(0) || _removedOwner == SENTINEL_OWNERS)\n revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_prevOwner] != _removedOwner)\n revert MultiSigFacet__InvalidOwnerPair();\n\n ms.owners[_prevOwner] = ms.owners[_removedOwner];\n ms.owners[_removedOwner] = address(0);\n --ms.ownerCount;\n emit OwnerRemoved(_removedOwner);\n\n if (ms.threshold != _threshold) changeThreshold(_threshold);\n }\n\n /**\n * @notice Swap owner in Barz.\n * @dev This can only be done via a Self call.\n * @param _prevOwner Address of owner located right behind the removed owner address in the linked list\n * @param _oldOwner Address of owner to be removed\n * @param _newOwner Address of owner to be added\n */\n function swapOwner(\n address _prevOwner,\n address _oldOwner,\n address _newOwner\n ) public {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (\n _newOwner == address(0) ||\n _newOwner == SENTINEL_OWNERS ||\n _newOwner == address(this)\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_newOwner] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n if (_oldOwner == address(0) || _oldOwner == SENTINEL_OWNERS)\n revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_prevOwner] != _oldOwner)\n revert MultiSigFacet__InvalidOwnerPair();\n\n ms.owners[_newOwner] = ms.owners[_oldOwner];\n ms.owners[_prevOwner] = _newOwner;\n ms.owners[_oldOwner] = address(0);\n emit OwnerRemoved(_oldOwner);\n emit OwnerAdded(_newOwner);\n }\n\n /**\n * @notice Changes the threshold of the Barz to `_threshold`.\n * @dev This can only be done via a Self call.\n * @param _threshold New threshold\n */\n function changeThreshold(uint256 _threshold) public {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (_threshold > ms.ownerCount || _threshold == 0)\n revert MultiSigFacet__InvalidThreshold();\n\n ms.threshold = _threshold;\n emit ThresholdChanged(_threshold);\n }\n\n /**\n * @notice Checks if the given address is owner\n * @param _owner Address to be checked if it's owner\n * @return isOwner_ Bool value showing if it's owner address\n */\n function isOwner(address _owner) public view returns (bool isOwner_) {\n isOwner_ = (_owner != SENTINEL_OWNERS &&\n LibMultiSigStorage.multisigStorage().owners[_owner] != address(0));\n }\n\n /**\n * @notice Returns the threshold of Barz\n * @return threshold Threshold of the Barz account\n */\n function getThreshold() public view returns (uint256 threshold) {\n threshold = LibMultiSigStorage.multisigStorage().threshold;\n }\n\n /**\n * @notice Returns the list of owner addresses\n * @return owners List of owners\n */\n function getOwners() public view returns (address[] memory owners) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n owners = new address[](ms.ownerCount);\n\n uint256 index;\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n while (currentOwner != SENTINEL_OWNERS) {\n owners[index] = currentOwner;\n currentOwner = ms.owners[currentOwner];\n index++;\n }\n }\n\n /**\n * @notice Returns the previous owner in the linked list\n * @param _owner Address of owner\n * @return prevOwner Address of previous owner\n */\n function getPrevOwner(\n address _owner\n ) public view returns (address prevOwner) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n if (currentOwner == _owner) return SENTINEL_OWNERS;\n while (currentOwner != SENTINEL_OWNERS) {\n if (ms.owners[currentOwner] == _owner) return currentOwner;\n\n currentOwner = ms.owners[currentOwner];\n }\n return address(0);\n }\n\n /**\n * @notice Returns of the owner is approved by given owner address\n * @param _owner Address of owner\n * @param _hash Hash of UserOperation\n * @return isApproved Bool value showing if the hash is approved by owner\n */\n function isApprovedHash(\n address _owner,\n bytes32 _hash\n ) public view returns (bool isApproved) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n isApproved = (ms.approvedHashes[ms.counter][_owner][_hash] == 1);\n }\n}\n" + }, + "contracts/facets/verification/secp256k1/Secp256k1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {UserOperation} from \"../../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibAppStorage} from \"../../../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, Secp256k1VerificationStorage} from \"../../../libraries/LibFacetStorage.sol\";\nimport {LibLoupe} from \"../../../libraries/LibLoupe.sol\";\nimport {IERC1271} from \"../../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../../interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Secp256k1 verification facet\n * @dev Default Ethereum's elliptic curve\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract Secp256k1VerificationFacet is IVerificationFacet, IERC1271 {\n using ECDSA for bytes32;\n error Secp256k1VerificationFacet__InvalidSignerLength();\n address public immutable self;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in K1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\n * @param _publicKey Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _publicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n if (!isValidKeyType(_publicKey))\n revert Secp256k1VerificationFacet__InvalidSignerLength();\n\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(uint160(uint256(keccak256(_publicKey[1:]))));\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_publicKey);\n }\n\n /**\n * @notice Uninitialize signer in K1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\n * signer public key.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n validationData = validateSignature(\n userOp,\n userOpHash,\n k1Storage.signer\n );\n }\n\n /**\n * @notice Validates if the signature of UserOperation is signed by the given signer\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @param signer Address of signer who signed the contract, to be validated\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n address signer\n ) public pure returns (uint256 isValid) {\n bytes32 hash = userOpHash.toEthSignedMessageHash();\n isValid = (signer != hash.recover(userOp.signature)) ? 1 : 0;\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n ownerSignatureValidatorSelector = this.validateOwnerSignature.selector;\n // NOTE: The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory signer) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n signer = abi.encodePacked(k1Storage.signer);\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key length should be 65 in an uncompressed public key format\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (_hash.recover(_signature) ==\n LibFacetStorage.k1Storage().signer)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/Secp256r1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {UserOperation} from \"../../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibAppStorage} from \"../../../libraries/LibAppStorage.sol\";\nimport {LibLoupe} from \"../../../libraries/LibLoupe.sol\";\nimport {LibFacetStorage, Secp256r1VerificationStorage} from \"../../../libraries/LibFacetStorage.sol\";\nimport {Base64} from \"./utils/Base64.sol\";\nimport {LibSecp256r1} from \"./utils/LibSecp256r1.sol\";\nimport {IERC1271} from \"../../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../../interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Secp256r1 verification facet\n * @dev Primarily used to verify user ops signed with passkeys\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract Secp256r1VerificationFacet is IVerificationFacet, IERC1271 {\n error Secp256r1VerificationFacet__InvalidSignerLength();\n address public immutable self;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in R1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\n * @param _publicKey Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _publicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n\n if (!isValidKeyType(_publicKey))\n revert Secp256r1VerificationFacet__InvalidSignerLength();\n\n bytes memory publicKeyCoordinates = _publicKey[1:];\n uint256[2] memory q;\n assembly {\n // Copy the bytes from the input data into the uint256 array\n mstore(q, mload(add(publicKeyCoordinates, 32)))\n mstore(add(q, 32), mload(add(publicKeyCoordinates, 64)))\n }\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n r1Storage.q = q;\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_publicKey);\n }\n\n /**\n * @notice Uninitialize signer in R1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n r1Storage.q = [0, 0];\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\n * signer public key.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n validationData = validateSignature(userOp, userOpHash, r1Storage.q);\n }\n\n /**\n * @notice Validates if the signature of UserOperation is signed by the given signer\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @param q Public Key of signer who signed the contract, to be validated\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256[2] memory q\n ) public view returns (uint256 isValid) {\n isValid = (_validateSignature(q, userOpHash, userOp.signature)) ? 0 : 1;\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n return this.validateOwnerSignature.selector; // validateOwnerSignature(UserOperation calldata userOp,bytes32 userOpHash)\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory signer) {\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n signer = abi.encodePacked(r1Storage.q);\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key should in an uncompressed public key format\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = _validateSignature(\n LibFacetStorage.r1Storage().q,\n _hash,\n _signature\n )\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n\n function _validateSignature(\n uint256[2] memory q,\n bytes32 _hash,\n bytes memory _signature\n ) internal view returns (bool) {\n (\n uint256 rValue,\n uint256 sValue,\n bytes memory authenticatorData,\n string memory clientDataJSONPre,\n string memory clientDataJSONPost\n ) = abi.decode(_signature, (uint256, uint256, bytes, string, string));\n bytes32 clientHash;\n {\n string memory opHashBase64 = Base64.encode(bytes.concat(_hash));\n string memory clientDataJSON = string.concat(\n clientDataJSONPre,\n opHashBase64,\n clientDataJSONPost\n );\n clientHash = sha256(bytes(clientDataJSON));\n }\n bytes32 sigHash = sha256(bytes.concat(authenticatorData, clientHash));\n return LibSecp256r1.Verify(q, rValue, sValue, uint256(sigHash));\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/utils/Base64.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @dev Provides a set of functions to operate with Base64 strings.\n * modified for base64url https://datatracker.ietf.org/doc/html/rfc4648#section-5\n * _Available since v4.5._\n */\nlibrary Base64 {\n /**\n * @dev Base64 Encoding/Decoding Table\n */\n string internal constant _TABLE =\n \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_\";\n\n /**\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\n */\n function encode(bytes memory data) internal pure returns (string memory) {\n /**\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\n */\n if (data.length == 0) return \"\";\n\n // Loads the table into memory\n string memory table = _TABLE;\n\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\n // and split into 4 numbers of 6 bits.\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\n // - `data.length + 2` -> Round up\n // - `/ 3` -> Number of 3-bytes chunks\n // - `4 *` -> 4 characters for each chunk\n uint256 newlength = (data.length * 8) / 6;\n if (data.length % 6 > 0) {\n newlength++;\n }\n string memory result = new string(newlength);\n\n /// @solidity memory-safe-assembly\n assembly {\n // Prepare the lookup table (skip the first \"length\" byte)\n let tablePtr := add(table, 1)\n\n // Prepare result pointer, jump over length\n let resultPtr := add(result, 32)\n\n // Run over the input, 3 bytes at a time\n for {\n let dataPtr := data\n let endPtr := add(data, mload(data))\n } lt(dataPtr, endPtr) {\n\n } {\n // Advance 3 bytes\n dataPtr := add(dataPtr, 3)\n let input := mload(dataPtr)\n\n // To write each character, shift the 3 bytes (18 bits) chunk\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\n // and apply logical AND with 0x3F which is the number of\n // the previous character in the ASCII table prior to the Base64 Table\n // The result is then added to the table to get the character to write,\n // and finally write it in the result pointer but with a left shift\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(18, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(12, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(6, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n }\n }\n\n return result;\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/utils/LibSecp256r1.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n// Heavily inspired from\n// https://github.com/maxrobot/elliptic-solidity/blob/master/contracts/Secp256r1.sol\n// https://github.com/tdrerup/elliptic-curve-solidity/blob/master/contracts/curves/EllipticCurve.sol\n// modified to use precompile 0x05 modexp\n// and modified jacobian double\n// optimisations to avoid to an from from affine and jacobian coordinates\n\n// Additional Elliptic curve Public key / Signature validation added by\n// David Yonjun Kim (@Powerstream3604)\n\nstruct JPoint {\n uint256 x;\n uint256 y;\n uint256 z;\n}\n\nlibrary LibSecp256r1 {\n uint256 constant gx =\n 0x6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296;\n uint256 constant gy =\n 0x4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5;\n uint256 public constant pp =\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF;\n\n uint256 public constant nn =\n 0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551;\n uint256 constant a =\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC;\n uint256 constant b =\n 0x5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B;\n uint256 constant MOST_SIGNIFICANT =\n 0xc000000000000000000000000000000000000000000000000000000000000000;\n\n /*\n * Verify\n * @description - verifies that a public key has signed a given message\n * @param Q - public key coordinates X & Y\n * @param R - signature half R\n * @param S - signature half S\n * @param input - hashed message\n */\n function Verify(\n uint256[2] memory q,\n uint r,\n uint s,\n uint e\n ) internal view returns (bool) {\n if (q[0] > pp - 1 || q[1] > pp - 1) {\n return false;\n }\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\n return false;\n }\n if (\n mulmod(q[1], q[1], pp) !=\n addmod(\n addmod(\n mulmod(q[0], mulmod(q[0], q[0], pp), pp),\n mulmod(a, q[0], pp),\n pp\n ),\n b,\n pp\n )\n ) {\n return false;\n }\n\n JPoint[16] memory points = _preComputeJacobianPoints(q);\n return VerifyWithPrecompute(points, r, s, e);\n }\n\n function VerifyWithPrecompute(\n JPoint[16] memory points,\n uint r,\n uint s,\n uint e\n ) internal view returns (bool) {\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\n return false;\n }\n\n uint w = _primemod(s, nn);\n\n uint u1 = mulmod(e, w, nn);\n uint u2 = mulmod(r, w, nn);\n\n uint x;\n uint y;\n\n (x, y) = ShamirMultJacobian(points, u1, u2);\n return (x == r);\n }\n\n /*\n * Strauss Shamir trick for EC multiplication\n * https://stackoverflow.com/questions/50993471/ec-scalar-multiplication-with-strauss-shamir-method\n * we optimise on this a bit to do with 2 bits at a time rather than a single bit\n * the individual points for a single pass are precomputed\n * overall this reduces the number of additions while keeping the same number of doublings\n */\n function ShamirMultJacobian(\n JPoint[16] memory points,\n uint u1,\n uint u2\n ) internal view returns (uint, uint) {\n uint x = 0;\n uint y = 0;\n uint z = 0;\n uint bits = 128;\n uint index = 0;\n\n while (bits > 0) {\n if (z > 0) {\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\n }\n index =\n ((u1 & MOST_SIGNIFICANT) >> 252) |\n ((u2 & MOST_SIGNIFICANT) >> 254);\n if (index > 0) {\n (x, y, z) = _jAdd(\n x,\n y,\n z,\n points[index].x,\n points[index].y,\n points[index].z\n );\n }\n u1 <<= 2;\n u2 <<= 2;\n bits--;\n }\n (x, y) = _affineFromJacobian(x, y, z);\n return (x, y);\n }\n\n function _preComputeJacobianPoints(\n uint256[2] memory q\n ) internal pure returns (JPoint[16] memory points) {\n points[0] = JPoint(0, 0, 0);\n points[1] = JPoint(q[0], q[1], 1); // u2\n points[2] = _jPointDouble(points[1]);\n points[3] = _jPointAdd(points[1], points[2]);\n\n points[4] = JPoint(gx, gy, 1); // u1Points[1]\n points[5] = _jPointAdd(points[4], points[1]);\n points[6] = _jPointAdd(points[4], points[2]);\n points[7] = _jPointAdd(points[4], points[3]);\n\n points[8] = _jPointDouble(points[4]); // u1Points[2]\n points[9] = _jPointAdd(points[8], points[1]);\n points[10] = _jPointAdd(points[8], points[2]);\n points[11] = _jPointAdd(points[8], points[3]);\n\n points[12] = _jPointAdd(points[4], points[8]); // u1Points[3]\n points[13] = _jPointAdd(points[12], points[1]);\n points[14] = _jPointAdd(points[12], points[2]);\n points[15] = _jPointAdd(points[12], points[3]);\n }\n\n function _jPointAdd(\n JPoint memory p1,\n JPoint memory p2\n ) internal pure returns (JPoint memory) {\n uint x;\n uint y;\n uint z;\n (x, y, z) = _jAdd(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z);\n return JPoint(x, y, z);\n }\n\n function _jPointDouble(\n JPoint memory p\n ) internal pure returns (JPoint memory) {\n uint x;\n uint y;\n uint z;\n (x, y, z) = _modifiedJacobianDouble(p.x, p.y, p.z);\n return JPoint(x, y, z);\n }\n\n /* _affineFromJacobian\n * @desription returns affine coordinates from a jacobian input follows\n * golang elliptic/crypto library\n */\n function _affineFromJacobian(\n uint x,\n uint y,\n uint z\n ) internal view returns (uint ax, uint ay) {\n if (z == 0) {\n return (0, 0);\n }\n\n uint zinv = _primemod(z, pp);\n uint zinvsq = mulmod(zinv, zinv, pp);\n\n ax = mulmod(x, zinvsq, pp);\n ay = mulmod(y, mulmod(zinvsq, zinv, pp), pp);\n }\n\n /*\n * _jAdd\n * @description performs Jacobian addition as defined below:\n * http://www.hyperelliptic.org/EFD/g1p/data/shortw/jacobian/addition/add-2007-bl\n */\n function _jAdd(\n uint p1,\n uint p2,\n uint p3,\n uint q1,\n uint q2,\n uint q3\n ) internal pure returns (uint r1, uint r2, uint r3) {\n if (p3 == 0) {\n r1 = q1;\n r2 = q2;\n r3 = q3;\n\n return (r1, r2, r3);\n } else if (q3 == 0) {\n r1 = p1;\n r2 = p2;\n r3 = p3;\n\n return (r1, r2, r3);\n }\n\n assembly {\n let\n pd\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\n let z1z1 := mulmod(p3, p3, pd) // Z1Z1 = Z1^2\n let z2z2 := mulmod(q3, q3, pd) // Z2Z2 = Z2^2\n\n let u1 := mulmod(p1, z2z2, pd) // U1 = X1*Z2Z2\n let u2 := mulmod(q1, z1z1, pd) // U2 = X2*Z1Z1\n\n let s1 := mulmod(p2, mulmod(z2z2, q3, pd), pd) // S1 = Y1*Z2*Z2Z2\n let s2 := mulmod(q2, mulmod(z1z1, p3, pd), pd) // S2 = Y2*Z1*Z1Z1\n\n let p3q3 := addmod(p3, q3, pd)\n\n if lt(u2, u1) {\n u2 := add(pd, u2) // u2 = u2+pd\n }\n let h := sub(u2, u1) // H = U2-U1\n\n let i := mulmod(0x02, h, pd)\n i := mulmod(i, i, pd) // I = (2*H)^2\n\n let j := mulmod(h, i, pd) // J = H*I\n if lt(s2, s1) {\n s2 := add(pd, s2) // u2 = u2+pd\n }\n let rr := mulmod(0x02, sub(s2, s1), pd) // r = 2*(S2-S1)\n r1 := mulmod(rr, rr, pd) // X3 = R^2\n\n let v := mulmod(u1, i, pd) // V = U1*I\n let j2v := addmod(j, mulmod(0x02, v, pd), pd)\n if lt(r1, j2v) {\n r1 := add(pd, r1) // X3 = X3+pd\n }\n r1 := sub(r1, j2v)\n\n // Y3 = r*(V-X3)-2*S1*J\n let s12j := mulmod(mulmod(0x02, s1, pd), j, pd)\n\n if lt(v, r1) {\n v := add(pd, v)\n }\n r2 := mulmod(rr, sub(v, r1), pd)\n\n if lt(r2, s12j) {\n r2 := add(pd, r2)\n }\n r2 := sub(r2, s12j)\n\n // Z3 = ((Z1+Z2)^2-Z1Z1-Z2Z2)*H\n z1z1 := addmod(z1z1, z2z2, pd)\n j2v := mulmod(p3q3, p3q3, pd)\n if lt(j2v, z1z1) {\n j2v := add(pd, j2v)\n }\n r3 := mulmod(sub(j2v, z1z1), h, pd)\n }\n return (r1, r2, r3);\n }\n\n // Point doubling on the modified jacobian coordinates\n // http://point-at-infinity.org/ecc/Prime_Curve_Modified_Jacobian_Coordinates.html\n function _modifiedJacobianDouble(\n uint x,\n uint y,\n uint z\n ) internal pure returns (uint x3, uint y3, uint z3) {\n if (y == 0) return (0, 0, 0);\n assembly {\n let\n pd\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\n let z2 := mulmod(z, z, pd)\n let az4 := mulmod(\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC,\n mulmod(z2, z2, pd),\n pd\n )\n let y2 := mulmod(y, y, pd)\n let s := mulmod(0x04, mulmod(x, y2, pd), pd)\n let u := mulmod(0x08, mulmod(y2, y2, pd), pd)\n let m := addmod(mulmod(0x03, mulmod(x, x, pd), pd), az4, pd)\n let twos := mulmod(0x02, s, pd)\n let m2 := mulmod(m, m, pd)\n if lt(m2, twos) {\n m2 := add(pd, m2)\n }\n x3 := sub(m2, twos)\n if lt(s, x3) {\n s := add(pd, s)\n }\n y3 := mulmod(m, sub(s, x3), pd)\n if lt(y3, u) {\n y3 := add(pd, y3)\n }\n y3 := sub(y3, u)\n z3 := mulmod(0x02, mulmod(y, z, pd), pd)\n }\n }\n\n // Fermats little theorem https://en.wikipedia.org/wiki/Fermat%27s_little_theorem\n // a^(p-1) = 1 mod p\n // a^(-1) ≅ a^(p-2) (mod p)\n // we then use the precompile bigModExp to compute a^(-1)\n function _primemod(uint value, uint p) internal view returns (uint ret) {\n ret = modexp(value, p - 2, p);\n return ret;\n }\n\n // Wrapper for built-in BigNumber_modexp (contract 0x5) as described here. https://github.com/ethereum/EIPs/pull/198\n function modexp(\n uint _base,\n uint _exp,\n uint _mod\n ) internal view returns (uint ret) {\n // bigModExp(_base, _exp, _mod);\n assembly {\n if gt(_base, _mod) {\n _base := mod(_base, _mod)\n }\n // Free memory pointer is always stored at 0x40\n let freemem := mload(0x40)\n\n mstore(freemem, 0x20)\n mstore(add(freemem, 0x20), 0x20)\n mstore(add(freemem, 0x40), 0x20)\n\n mstore(add(freemem, 0x60), _base)\n mstore(add(freemem, 0x80), _exp)\n mstore(add(freemem, 0xa0), _mod)\n\n let success := staticcall(14000, 0x5, freemem, 0xc0, freemem, 0x20)\n switch success\n case 0 {\n revert(0x0, 0x0)\n }\n default {\n ret := mload(freemem)\n }\n }\n }\n}\n" + }, + "contracts/infrastructure/DefaultFallbackHandler.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC1155Receiver} from \"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\";\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {BaseAccount} from \"../aa-4337/core/BaseAccount.sol\";\nimport {DefaultLibDiamond} from \"../libraries/DefaultLibDiamond.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IAccountFacet} from \"../facets/interfaces/IAccountFacet.sol\";\nimport {IStorageLoupe} from \"../facets/base/interfaces/IStorageLoupe.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IERC677Receiver} from \"../interfaces/ERC/IERC677Receiver.sol\";\nimport {IERC165} from \"../interfaces/ERC/IERC165.sol\";\n\n/**\n * @title DefaultFallbackHandler\n * @dev A default fallback handler for Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DefaultFallbackHandler is IDiamondLoupe {\n /**\n * @notice Sets the middleware diamond for Barz wallet as a fallback handler\n * @dev This contract is also a diamond that holds the default facets to reduce gas cost for wallet activation.\n * Within the constructor this conducts diamond cut to initially setup the diamond. This is a non-upgradeable contract\n * @param _diamondCutFacet Address if diamond cut facet\n * @param _accountFacet Address account facet\n * @param _tokenReceiverFacet Address of token receiver facet\n * @param _diamondLoupeFacet Address of diamond loupe facet\n */\n constructor(\n address _diamondCutFacet,\n address _accountFacet,\n address _tokenReceiverFacet,\n address _diamondLoupeFacet\n ) payable {\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](4);\n bytes4[] memory functionSelectors = new bytes4[](1);\n functionSelectors[0] = IDiamondCut.diamondCut.selector;\n\n bytes4[] memory accountFunctionSelectors = new bytes4[](5);\n accountFunctionSelectors[0] = IAccountFacet.execute.selector;\n accountFunctionSelectors[1] = IAccountFacet.executeBatch.selector;\n accountFunctionSelectors[2] = BaseAccount.validateUserOp.selector;\n accountFunctionSelectors[3] = BaseAccount.getNonce.selector;\n accountFunctionSelectors[4] = BaseAccount.entryPoint.selector;\n\n bytes4[] memory receiverFacetSelectors = new bytes4[](5);\n receiverFacetSelectors[0] = IERC721Receiver.onERC721Received.selector;\n receiverFacetSelectors[1] = IERC1155Receiver.onERC1155Received.selector;\n receiverFacetSelectors[2] = IERC1155Receiver\n .onERC1155BatchReceived\n .selector;\n receiverFacetSelectors[3] = IERC777Recipient.tokensReceived.selector;\n receiverFacetSelectors[4] = IERC677Receiver.onTokenTransfer.selector;\n\n bytes4[] memory loupeFacetSelectors = new bytes4[](9);\n loupeFacetSelectors[0] = IDiamondLoupe.facets.selector;\n loupeFacetSelectors[1] = IDiamondLoupe.facetFunctionSelectors.selector;\n loupeFacetSelectors[2] = IDiamondLoupe.facetAddresses.selector;\n loupeFacetSelectors[3] = IDiamondLoupe.facetAddress.selector;\n loupeFacetSelectors[4] = IERC165.supportsInterface.selector;\n loupeFacetSelectors[5] = IStorageLoupe.facetsFromStorage.selector;\n loupeFacetSelectors[6] = IStorageLoupe\n .facetFunctionSelectorsFromStorage\n .selector;\n loupeFacetSelectors[7] = IStorageLoupe\n .facetAddressesFromStorage\n .selector;\n loupeFacetSelectors[8] = IStorageLoupe.facetAddressFromStorage.selector;\n\n {\n cut[0] = IDiamondCut.FacetCut({\n facetAddress: _diamondCutFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: functionSelectors\n });\n cut[1] = IDiamondCut.FacetCut({\n facetAddress: _accountFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: accountFunctionSelectors\n });\n cut[2] = IDiamondCut.FacetCut({\n facetAddress: _tokenReceiverFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: receiverFacetSelectors\n });\n cut[3] = IDiamondCut.FacetCut({\n facetAddress: _diamondLoupeFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: loupeFacetSelectors\n });\n\n DefaultLibDiamond.diamondCut(cut, address(0), \"\");\n }\n }\n\n /**\n * @notice Returns the facet information of call facets registered to this diamond.\n * @return facets_ The facet struct array including all facet information\n */\n function facets() external view override returns (Facet[] memory facets_) {\n DefaultLibDiamond.DiamondStorage storage ds = DefaultLibDiamond\n .diamondStorage();\n uint256 numFacets = ds.facetAddresses.length;\n facets_ = new Facet[](numFacets);\n for (uint256 i; i < numFacets; ) {\n address facetAddress_ = ds.facetAddresses[i];\n facets_[i].facetAddress = facetAddress_;\n facets_[i].functionSelectors = ds\n .facetFunctionSelectors[facetAddress_]\n .functionSelectors;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Gets all the function selectors provided by a facet.\n * @param _facet The facet address.\n * @return facetFunctionSelectors_\n */\n function facetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n facetFunctionSelectors_ = DefaultLibDiamond\n .diamondStorage()\n .facetFunctionSelectors[_facet]\n .functionSelectors;\n }\n\n /**\n * @notice Get all the facet addresses used by a diamond.\n * @return facetAddresses_\n */\n function facetAddresses()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n facetAddresses_ = DefaultLibDiamond.diamondStorage().facetAddresses;\n }\n\n /** @notice Gets the facet that supports the given selector.\n * @dev If facet is not found return address(0).\n * @param _functionSelector The function selector.\n * @return facetAddress_ The facet address.\n */\n function facetAddress(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n facetAddress_ = DefaultLibDiamond\n .diamondStorage()\n .selectorToFacetAndPosition[_functionSelector]\n .facetAddress;\n }\n}\n" + }, + "contracts/infrastructure/FacetRegistry.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport {IFacetRegistry} from \"./interfaces/IFacetRegistry.sol\";\n\n/**\n * @title Facet Registry\n * @dev Contract to keep track of facets & function selectors addable to user wallets\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract FacetRegistry is IFacetRegistry, Ownable2Step {\n mapping(address => FacetRegistryConfig) private facets;\n\n /**\n * @notice Transfers the ownership of the contract to the given owner\n * @param _owner Address of owner who has access to initialize the default security variables for security manager\n */\n constructor(address _owner) {\n transferOwnership(_owner);\n _transferOwnership(_owner);\n }\n\n /**\n * @dev Registers a facet and it's function selectors to registry\n * @param _facet address of facet\n * @param _facetSelectors list of function selectors of the facet\n */\n function registerFacetFunctionSelectors(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external override onlyOwner {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n for (uint256 i; i < _facetSelectors.length; ) {\n if (facetConfig.info[_facetSelectors[i]].exists)\n revert FacetRegistry__FacetSelectorAlreadyRegistered();\n\n facetConfig.info[_facetSelectors[i]].exists = true;\n facetConfig.info[_facetSelectors[i]].index = uint128(\n facetConfig.selectors.length\n );\n facetConfig.selectors.push(_facetSelectors[i]);\n unchecked {\n ++i;\n }\n }\n emit FacetFunctionSelectorsRegistered(_facet, _facetSelectors);\n }\n\n /**\n * @dev Removes a registered facet and it's corresponding selectors from registry\n * @param _facet address of facet\n * @param _facetSelectors list of function selectors of the facet\n */\n function removeFacetFunctionSelectors(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external override onlyOwner {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n for (uint256 i; i < _facetSelectors.length; ) {\n if (!facetConfig.info[_facetSelectors[i]].exists)\n revert FacetRegistry__UnregisteredFacetSelector();\n\n bytes4 lastSelector = facetConfig.selectors[\n facetConfig.selectors.length - 1\n ];\n if (_facetSelectors[i] != lastSelector) {\n uint128 targetIndex = facetConfig\n .info[_facetSelectors[i]]\n .index;\n facetConfig.selectors[targetIndex] = lastSelector;\n facetConfig.info[lastSelector].index = targetIndex;\n }\n facetConfig.selectors.pop();\n delete facetConfig.info[_facetSelectors[i]];\n\n unchecked {\n ++i;\n }\n }\n emit FacetFunctionSelectorsRemoved(_facet, _facetSelectors);\n }\n\n /**\n * @dev Checks if a facet and it's selectors given is registered to facet registry\n * @param _facet Address of facet\n * @param _facetSelectors List of function selectors of the facet\n */\n function areFacetFunctionSelectorsRegistered(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external view override returns (bool) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n if (_facetSelectors.length == 0) return false;\n for (uint256 i; i < _facetSelectors.length; ) {\n if (!facetConfig.info[_facetSelectors[i]].exists) return false;\n unchecked {\n ++i;\n }\n }\n return true;\n }\n\n /**\n * @dev Checks if a facet and it's selector given is registered to facet registry\n * @param _facet Address of facet\n * @param _facetSelector List of function selectors of the facet\n * @return isRegistered Bool value showing if the selector is registered\n */\n function isFacetFunctionSelectorRegistered(\n address _facet,\n bytes4 _facetSelector\n ) external view override returns (bool isRegistered) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n isRegistered = facetConfig.info[_facetSelector].exists;\n }\n\n /**\n * @dev Get the registered selectors of facet from registry\n * @param _facet Address of facet\n * @return selectors Selectors registered to facet\n */\n function getFacetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory selectors) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n selectors = facetConfig.selectors;\n }\n}\n" + }, + "contracts/infrastructure/interfaces/IFacetRegistry.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Registry Interface\n * @dev Interface for Facet Registry contract to keep track of facets & function selectors addable to user wallets\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IFacetRegistry {\n struct FacetRegistryConfig {\n bytes4[] selectors;\n mapping(bytes4 => FacetInfo) info;\n }\n struct FacetInfo {\n bool exists;\n uint128 index;\n }\n\n event FacetFunctionSelectorsRegistered(\n address facet,\n bytes4[] facetSelectors\n );\n event FacetFunctionSelectorsRemoved(address facet, bytes4[] facetSelectors);\n\n error FacetRegistry__FacetSelectorAlreadyRegistered();\n error FacetRegistry__UnregisteredFacetSelector();\n\n function registerFacetFunctionSelectors(\n address facet,\n bytes4[] calldata facetSelectors\n ) external;\n\n function removeFacetFunctionSelectors(\n address facet,\n bytes4[] calldata facetSelectors\n ) external;\n\n function areFacetFunctionSelectorsRegistered(\n address facet,\n bytes4[] calldata facetSelectors\n ) external view returns (bool);\n\n function isFacetFunctionSelectorRegistered(\n address facet,\n bytes4 facetSelector\n ) external view returns (bool);\n\n function getFacetFunctionSelectors(\n address facet\n ) external view returns (bytes4[] memory);\n}\n" + }, + "contracts/infrastructure/interfaces/ISecurityManager.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Registry Interface\n * @dev Infrastructure contract to manage security parameters of users\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface ISecurityManager {\n error SecurityManager__OutOfBoundary();\n error SecurityManager__CallerNotWallet();\n error SecurityManager__AlreadyIntialized();\n\n function initializeAdditionSecurityPeriod(\n uint128 defaultAdditionSecurityPeriod,\n uint128 minAdditionSecurityPeriod,\n uint128 maxAdditionSecurityPeriod\n ) external;\n\n function initializeRemovalSecurityPeriod(\n uint128 defaultRemovalSecurityPeriod,\n uint128 minRemovalSecurityPeriod,\n uint128 maxRemovalSecurityPeriod\n ) external;\n\n function initializeApprovalValidationPeriod(\n uint128 defaultApprovalValidationPeriod,\n uint128 minApprovalValidationPeriod,\n uint128 maxApprovalValidationPeriod\n ) external;\n\n function initializeMigrationPeriod(\n uint128 defaultMigrationPeriod,\n uint128 minMigrationPeriod,\n uint128 maxMigrationPeriod\n ) external;\n\n function initializeLockPeriod(\n uint128 defaultLockPeriod,\n uint128 minLockPeriod,\n uint128 maxLockPeriod\n ) external;\n\n function initializeRecoveryPeriod(\n uint128 defaultRecoveryPeriod,\n uint128 minRecoveryPeriod,\n uint128 maxRecoveryPeriod\n ) external;\n\n function initializeSecurityWindow(\n uint128 defaultSecurityWindow,\n uint128 minSecurityWindow,\n uint128 maxSecurityWindow\n ) external;\n\n function setAdditionSecurityPeriod(\n address wallet,\n uint128 additionSecurityPeriod\n ) external;\n\n function setRemovalSecurityPeriod(\n address wallet,\n uint128 removalSecurityPeriod\n ) external;\n\n function setSecurityWindow(address wallet, uint128 securityWindow) external;\n\n function setRecoveryPeriod(address wallet, uint128 recoveryPeriod) external;\n\n function setLockPeriod(address wallet, uint128 lockPeriod) external;\n\n function setApprovalValidationPeriod(\n address wallet,\n uint128 approvalValidationPeriod\n ) external;\n\n function setMigrationPeriod(\n address wallet,\n uint128 migrationPeriod\n ) external;\n\n function additionSecurityPeriodOf(\n address wallet\n ) external view returns (uint128);\n\n function removalSecurityPeriodOf(\n address wallet\n ) external view returns (uint128);\n\n function securityWindowOf(address wallet) external view returns (uint128);\n\n function recoveryPeriodOf(address wallet) external view returns (uint128);\n\n function lockPeriodOf(address wallet) external view returns (uint128);\n\n function migrationPeriodOf(address wallet) external view returns (uint128);\n\n function approvalValidationPeriodOf(\n address wallet\n ) external view returns (uint128);\n}\n" + }, + "contracts/infrastructure/RemoteStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IGuardianFacet} from \"../facets/interfaces/IGuardianFacet.sol\";\n\n/**\n * @title Remote Storage\n * @dev Remote storage allows you to associate addresses with an array of addresses on a standalone smart contract.\n * This could be useful when you don't want to use the local diamond storage for some purpose.\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\nabstract contract RemoteStorage {\n struct StorageConfig {\n address[] addresses;\n mapping(address => Info) info;\n }\n\n struct Info {\n bool exists;\n uint128 index;\n }\n\n mapping(address => StorageConfig) internal configs;\n\n event Added(address _address);\n event Removed(address _address);\n\n error RemoteStorage__CallerNotOwner();\n error RemoteStorage__CallerNotGuardianOrOwner();\n error RemoteStorage__AlreadyExists();\n error RemoteStorage__NotFound();\n error RemoteStorage__CallerNotGuardian();\n\n bytes4 constant IS_GUARDIAN_SELECTOR =\n bytes4(keccak256(\"isGuardian(address)\"));\n bytes4 constant GUARDIAN_COUNT = bytes4(keccak256(\"guardianCount()\"));\n\n /**\n * @notice Modifier to only allow the self to call. Reverts otherwise\n */\n modifier onlyWallet(address _wallet) {\n if (msg.sender != _wallet) revert RemoteStorage__CallerNotOwner();\n _;\n }\n\n /**\n * @notice Enfore the callet to be wallet of guardian of the wallet\n * @param _wallet Address of wallet\n */\n function enforceGuardianOrWallet(address _wallet) internal view {\n if (msg.sender == _wallet) return;\n address facetAddress = IDiamondLoupe(_wallet).facetAddress(\n IS_GUARDIAN_SELECTOR\n );\n if (facetAddress != address(0))\n if (IGuardianFacet(_wallet).isGuardian(msg.sender)) return;\n revert RemoteStorage__CallerNotGuardianOrOwner();\n }\n\n /**\n * @notice Enforce the caller to be wallet IF guardians doesn't exists and only guardian when guardians exists\n * @param _wallet Target wallet address to be handled by infrastructure contracts\n */\n function enforceWalletOrGuardianIfExists(address _wallet) internal view {\n address facetAddress;\n if (msg.sender == _wallet) {\n facetAddress = IDiamondLoupe(_wallet).facetAddress(GUARDIAN_COUNT);\n if (facetAddress == address(0)) return;\n uint256 guardianCount = IGuardianFacet(_wallet).guardianCount();\n if (guardianCount != 0) revert RemoteStorage__CallerNotGuardian();\n return;\n }\n facetAddress = IDiamondLoupe(_wallet).facetAddress(\n IS_GUARDIAN_SELECTOR\n );\n if (facetAddress != address(0))\n if (IGuardianFacet(_wallet).isGuardian(msg.sender)) return;\n\n revert RemoteStorage__CallerNotGuardianOrOwner();\n }\n\n /**\n * @notice Add address to storage and reverts if the address already exists.\n * This is an internal function callable from contracts that inherit this abstract contract\n * @param _wallet Address of wallet to add the address\n * @param _address Address to be added to wallet\n */\n function addAddress(address _wallet, address _address) internal {\n StorageConfig storage config = configs[_wallet];\n if (config.info[_address].exists) revert RemoteStorage__AlreadyExists();\n\n config.info[_address].exists = true;\n config.info[_address].index = uint128(config.addresses.length);\n config.addresses.push(_address);\n\n emit Added(_address);\n }\n\n /**\n * @notice Remove address from storage and reverts if the address already exists.\n * This is an internal function callable from contracts that inherit this abstract contract\n * @param _wallet Address of wallet to remove the address\n * @param _address Address to be removed from wallet\n */\n function removeAddress(address _wallet, address _address) internal {\n StorageConfig storage config = configs[_wallet];\n if (!config.info[_address].exists) revert RemoteStorage__NotFound();\n\n address lastAddress = config.addresses[config.addresses.length - 1];\n if (_address != lastAddress) {\n uint128 targetIndex = config.info[_address].index;\n config.addresses[targetIndex] = lastAddress;\n config.info[lastAddress].index = targetIndex;\n }\n config.addresses.pop();\n delete config.info[_address];\n\n emit Removed(_address);\n }\n\n /**\n * @notice Returns the address added to the given wallet\n * @param _wallet Address of wallet to fetch the addresses added to it\n * @return addresses List of addresses added to the wallet\n */\n function getAddresses(\n address _wallet\n ) internal view returns (address[] memory addresses) {\n StorageConfig storage config = configs[_wallet];\n addresses = new address[](config.addresses.length);\n uint addressesLen = config.addresses.length;\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns bool value checking if the address exists in the given wallet address\n * @param _wallet Wallet address to check\n * @param _address Address to fetch if the address if added to given wallet\n * @return exists_ Bool value showing if the address exists in wallet\n */\n function exists(\n address _wallet,\n address _address\n ) internal view returns (bool exists_) {\n exists_ = configs[_wallet].info[_address].exists;\n }\n\n /**\n * @notice Returns the number of addresses added to the wallet\n * @param _wallet Address of wallet to check\n * @return count_ Number of addresses added to wallet\n */\n function count(address _wallet) internal view returns (uint256 count_) {\n count_ = configs[_wallet].addresses.length;\n }\n}\n" + }, + "contracts/infrastructure/SecurityManager.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport {ISecurityManager} from \"./interfaces/ISecurityManager.sol\";\n\n/**\n * @title Security Manager\n * @dev Infrastructure contract to manage security parameters of users\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract SecurityManager is ISecurityManager, Ownable2Step {\n uint128 public minAdditionSecurityPeriod;\n uint128 public maxAdditionSecurityPeriod;\n uint128 private defaultAdditionSecurityPeriod;\n\n uint128 public minRemovalSecurityPeriod;\n uint128 public maxRemovalSecurityPeriod;\n uint128 private defaultRemovalSecurityPeriod;\n\n uint128 public minSecurityWindow;\n uint128 public maxSecurityWindow;\n uint128 private defaultSecurityWindow;\n\n uint128 public minRecoveryPeriod;\n uint128 public maxRecoveryPeriod;\n uint128 private defaultRecoveryPeriod;\n\n uint128 public minLockPeriod;\n uint128 public maxLockPeriod;\n uint128 private defaultLockPeriod;\n\n uint128 public minApprovalValidationPeriod;\n uint128 public maxApprovalValidationPeriod;\n uint128 private defaultApprovalValidationPeriod;\n\n uint128 public minMigrationPeriod;\n uint128 public maxMigrationPeriod;\n uint128 private defaultMigrationPeriod;\n\n bool public _isAdditionSecurityPeriodInitialized;\n bool public _isRemovalSecurityPeriodInitialized;\n bool public _isSecurityWindowInitialized;\n bool public _isRecoveryPeriodInitialized;\n bool public _isLockPeriodInitialized;\n bool public _isApprovalValidationPeriodInitialized;\n bool public _isMigrationPeriodInitialized;\n\n mapping(address => CustomSecurityConfig) securityConfigs;\n\n struct CustomSecurityConfig {\n uint128 additionSecurityPeriod;\n uint128 removalSecurityPeriod;\n uint128 securityWindow;\n uint128 recoveryPeriod;\n uint128 lockPeriod;\n uint128 approvalValidationPeriod;\n uint128 migrationPeriod;\n }\n\n /**\n * @notice Modifier to only allow wallet itself to make a call to wallet\n */\n modifier onlyWallet(address _wallet) {\n if (msg.sender != _wallet) revert SecurityManager__CallerNotWallet();\n _;\n }\n\n /**\n * @notice Modifier to revert if the variable is already initialized\n */\n modifier initializer(bool _isInitialized) {\n if (_isInitialized) revert SecurityManager__AlreadyIntialized();\n _;\n }\n\n /**\n * @notice Transfers the ownership of the contract to the given owner\n * @param _owner Address of owner who has access to initialize the default security variables for security manager\n */\n constructor(address _owner) {\n transferOwnership(_owner);\n _transferOwnership(_owner);\n }\n\n /**\n * @notice Sets the initial default/min/max addition security period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultAdditionSecurityPeriod Default Addition Security Period for all Barz contracts\n * @param _minAdditionSecurityPeriod Minimum Addition Security Period for all Barz contracts\n * @param _maxAdditionSecurityPeriod Maximum Addition Security Period for all Barz contracts\n */\n function initializeAdditionSecurityPeriod(\n uint128 _defaultAdditionSecurityPeriod,\n uint128 _minAdditionSecurityPeriod,\n uint128 _maxAdditionSecurityPeriod\n )\n external\n override\n onlyOwner\n initializer(_isAdditionSecurityPeriodInitialized)\n {\n _isAdditionSecurityPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultAdditionSecurityPeriod,\n _minAdditionSecurityPeriod,\n _maxAdditionSecurityPeriod\n );\n defaultAdditionSecurityPeriod = _defaultAdditionSecurityPeriod;\n minAdditionSecurityPeriod = _minAdditionSecurityPeriod;\n maxAdditionSecurityPeriod = _maxAdditionSecurityPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max removal security period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultRemovalSecurityPeriod Default Removal Security Period for all Barz contracts\n * @param _minRemovalSecurityPeriod Minimum Removal Security Period for all Barz contracts\n * @param _maxRemovalSecurityPeriod Maximum Removal Security Period for all Barz contracts\n */\n function initializeRemovalSecurityPeriod(\n uint128 _defaultRemovalSecurityPeriod,\n uint128 _minRemovalSecurityPeriod,\n uint128 _maxRemovalSecurityPeriod\n )\n external\n override\n onlyOwner\n initializer(_isRemovalSecurityPeriodInitialized)\n {\n _isRemovalSecurityPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultRemovalSecurityPeriod,\n _minRemovalSecurityPeriod,\n _maxRemovalSecurityPeriod\n );\n defaultRemovalSecurityPeriod = _defaultRemovalSecurityPeriod;\n minRemovalSecurityPeriod = _minRemovalSecurityPeriod;\n maxRemovalSecurityPeriod = _maxRemovalSecurityPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/maxd security window for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultSecurityWindow Default Security Window for all Barz contracts\n * @param _minSecurityWindow Minimum Security Window for all Barz contracts\n * @param _maxSecurityWindow Maximum Security Window for all Barz contracts\n */\n function initializeSecurityWindow(\n uint128 _defaultSecurityWindow,\n uint128 _minSecurityWindow,\n uint128 _maxSecurityWindow\n ) external override onlyOwner initializer(_isSecurityWindowInitialized) {\n _isSecurityWindowInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultSecurityWindow,\n _minSecurityWindow,\n _maxSecurityWindow\n );\n defaultSecurityWindow = _defaultSecurityWindow;\n minSecurityWindow = _minSecurityWindow;\n maxSecurityWindow = _maxSecurityWindow;\n }\n\n /**\n * @notice Sets the initial default/min/max recovery period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultRecoveryPeriod Default Recovery Period for all Barz contracts\n * @param _minRecoveryPeriod Minimum Recovery Period for all Barz contracts\n * @param _maxRecoveryPeriod Maximum Recovery Period for all Barz contracts\n */\n function initializeRecoveryPeriod(\n uint128 _defaultRecoveryPeriod,\n uint128 _minRecoveryPeriod,\n uint128 _maxRecoveryPeriod\n ) external override onlyOwner initializer(_isRecoveryPeriodInitialized) {\n _isRecoveryPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultRecoveryPeriod,\n _minRecoveryPeriod,\n _maxRecoveryPeriod\n );\n defaultRecoveryPeriod = _defaultRecoveryPeriod;\n minRecoveryPeriod = _minRecoveryPeriod;\n maxRecoveryPeriod = _maxRecoveryPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max lock period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultLockPeriod Default Lock Period for all Barz contracts\n * @param _minLockPeriod Minimum Lock Period for all Barz contracts\n * @param _maxLockPeriod Maximum Lock Period for all Barz contracts\n */\n function initializeLockPeriod(\n uint128 _defaultLockPeriod,\n uint128 _minLockPeriod,\n uint128 _maxLockPeriod\n ) external override onlyOwner initializer(_isLockPeriodInitialized) {\n _isLockPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultLockPeriod,\n _minLockPeriod,\n _maxLockPeriod\n );\n defaultLockPeriod = _defaultLockPeriod;\n minLockPeriod = _minLockPeriod;\n maxLockPeriod = _maxLockPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max approval validation period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultApprovalValidationPeriod Default Approval Validation Period for all Barz contracts\n * @param _minApprovalValidationPeriod Minimum Approval Validation Period for all Barz contracts\n * @param _maxApprovalValidationPeriod Maximum Approval Validation Period for all Barz contracts\n */\n function initializeApprovalValidationPeriod(\n uint128 _defaultApprovalValidationPeriod,\n uint128 _minApprovalValidationPeriod,\n uint128 _maxApprovalValidationPeriod\n )\n external\n override\n onlyOwner\n initializer(_isApprovalValidationPeriodInitialized)\n {\n _isApprovalValidationPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultApprovalValidationPeriod,\n _minApprovalValidationPeriod,\n _maxApprovalValidationPeriod\n );\n defaultApprovalValidationPeriod = _defaultApprovalValidationPeriod;\n minApprovalValidationPeriod = _minApprovalValidationPeriod;\n maxApprovalValidationPeriod = _maxApprovalValidationPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max migration period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultMigrationPeriod Default Migration Period for all Barz contracts\n * @param _minMigrationPeriod Minimum Migration Period for all Barz contracts\n * @param _maxMigrationPeriod Maximum Migration Period for all Barz contracts\n */\n function initializeMigrationPeriod(\n uint128 _defaultMigrationPeriod,\n uint128 _minMigrationPeriod,\n uint128 _maxMigrationPeriod\n ) external override onlyOwner initializer(_isMigrationPeriodInitialized) {\n _isMigrationPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultMigrationPeriod,\n _minMigrationPeriod,\n _maxMigrationPeriod\n );\n defaultMigrationPeriod = _defaultMigrationPeriod;\n minMigrationPeriod = _minMigrationPeriod;\n maxMigrationPeriod = _maxMigrationPeriod;\n }\n\n /**\n * @notice Wallet owner sets the addition security period for the wallet. Only the owner of wallet can call this function.\n * The addition security period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _additionSecurityPeriod Custom Addition Security Period for the wallet\n */\n function setAdditionSecurityPeriod(\n address _wallet,\n uint128 _additionSecurityPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _additionSecurityPeriod,\n minAdditionSecurityPeriod,\n maxAdditionSecurityPeriod\n );\n securityConfigs[_wallet]\n .additionSecurityPeriod = _additionSecurityPeriod;\n }\n\n /**\n * @notice Wallet owner sets the removal security period for the wallet. Only the owner of wallet can call this function.\n * The removal security period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _removalSecurityPeriod Custom Removal Security Period for the wallet\n */\n function setRemovalSecurityPeriod(\n address _wallet,\n uint128 _removalSecurityPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _removalSecurityPeriod,\n minRemovalSecurityPeriod,\n maxRemovalSecurityPeriod\n );\n securityConfigs[_wallet].removalSecurityPeriod = _removalSecurityPeriod;\n }\n\n /**\n * @notice Wallet owner sets the security window for the wallet. Only the owner of wallet can call this function.\n * The security window should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _securityWindow Custom Security Window for the wallet\n */\n function setSecurityWindow(\n address _wallet,\n uint128 _securityWindow\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _securityWindow,\n minSecurityWindow,\n maxSecurityWindow\n );\n securityConfigs[_wallet].securityWindow = _securityWindow;\n }\n\n /**\n * @notice Wallet owner sets the recovery period for the wallet. Only the owner of wallet can call this function.\n * The recovery period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _recoveryPeriod Custom recovery period for the wallet\n */\n function setRecoveryPeriod(\n address _wallet,\n uint128 _recoveryPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _recoveryPeriod,\n minRecoveryPeriod,\n maxRecoveryPeriod\n );\n securityConfigs[_wallet].recoveryPeriod = _recoveryPeriod;\n }\n\n /**\n * @notice Wallet owner sets the lock period for the wallet. Only the owner of wallet can call this function.\n * The lock period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _lockPeriod Custom Lock period for the wallet\n */\n function setLockPeriod(\n address _wallet,\n uint128 _lockPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(_lockPeriod, minLockPeriod, maxLockPeriod);\n securityConfigs[_wallet].lockPeriod = _lockPeriod;\n }\n\n /**\n * @notice Wallet owner sets the approval validation period for the wallet. Only the owner of wallet can call this function.\n * The approval validation period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _approvalValidationPeriod Custom approval validation period for the wallet\n */\n function setApprovalValidationPeriod(\n address _wallet,\n uint128 _approvalValidationPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _approvalValidationPeriod,\n minApprovalValidationPeriod,\n maxApprovalValidationPeriod\n );\n securityConfigs[_wallet]\n .approvalValidationPeriod = _approvalValidationPeriod;\n }\n\n /**\n * @notice Wallet owner sets the migration period for the wallet. Only the owner of wallet can call this function.\n * The migration period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _migrationPeriod Custom migration period for the wallet\n */\n\n function setMigrationPeriod(\n address _wallet,\n uint128 _migrationPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _migrationPeriod,\n minMigrationPeriod,\n maxMigrationPeriod\n );\n securityConfigs[_wallet].migrationPeriod = _migrationPeriod;\n }\n\n /**\n * @notice Returns the addition security period. Returns default value when custom addition security period is not set\n * @param _wallet Address of wallet\n * @return additionSecurityPeriod Addition Security Period of the given Barz account or wallet\n */\n function additionSecurityPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 additionSecurityPeriod)\n {\n additionSecurityPeriod = securityConfigs[_wallet]\n .additionSecurityPeriod;\n additionSecurityPeriod = (additionSecurityPeriod == 0)\n ? defaultAdditionSecurityPeriod\n : additionSecurityPeriod;\n }\n\n /**\n * @notice Returns the removal security period. Returns default value when custom removal security period is not set\n * @param _wallet Address of wallet\n * @return removalSecurityPeriod Removal Security Period of the given Barz account or wallet\n */\n function removalSecurityPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 removalSecurityPeriod)\n {\n removalSecurityPeriod = securityConfigs[_wallet].removalSecurityPeriod;\n removalSecurityPeriod = (removalSecurityPeriod == 0)\n ? defaultRemovalSecurityPeriod\n : removalSecurityPeriod;\n }\n\n /**\n * @notice Returns the security window. Returns default value when custom security window is not set\n * @param _wallet Address of wallet\n * @return securityWindow Security window of the given Barz account or wallet\n */\n function securityWindowOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 securityWindow)\n {\n securityWindow = securityConfigs[_wallet].securityWindow;\n securityWindow = (securityWindow == 0)\n ? defaultSecurityWindow\n : securityWindow;\n }\n\n /**\n * @notice Returns the recovery period. Returns default value when custom recovery period is not set\n * @param _wallet Address of wallet\n * @return recoveryPeriod Recovery Period of the given Barz account or wallet\n */\n function recoveryPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 recoveryPeriod)\n {\n recoveryPeriod = securityConfigs[_wallet].recoveryPeriod;\n recoveryPeriod = (recoveryPeriod == 0)\n ? defaultRecoveryPeriod\n : recoveryPeriod;\n }\n\n /**\n * @notice Returns the lock period. Returns default value when custom lock period is not set\n * @param _wallet Address of wallet\n * @return lockPeriod Lock Period of the given Barz account or wallet\n */\n function lockPeriodOf(\n address _wallet\n ) public view override onlyWallet(_wallet) returns (uint128 lockPeriod) {\n lockPeriod = securityConfigs[_wallet].lockPeriod;\n lockPeriod = (lockPeriod == 0) ? defaultLockPeriod : lockPeriod;\n }\n\n /**\n * @notice Returns the approval validation period. Returns default value when custom approval validation period is not set\n * @param _wallet Address of wallet\n * @return approvalValidationPeriod Approval Validation Period of the given Barz account or wallet\n */\n function approvalValidationPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityConfigs[_wallet]\n .approvalValidationPeriod;\n approvalValidationPeriod = (approvalValidationPeriod == 0)\n ? defaultApprovalValidationPeriod\n : approvalValidationPeriod;\n }\n\n /**\n * @notice Returns the migration period. Returns default value when custom migration period is not set\n * @param _wallet Address of wallet\n * @return migrationPeriod Migration Period of the given Barz account or wallet\n */\n function migrationPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 migrationPeriod)\n {\n migrationPeriod = securityConfigs[_wallet].migrationPeriod;\n migrationPeriod = (migrationPeriod == 0)\n ? defaultMigrationPeriod\n : migrationPeriod;\n }\n\n /**\n * @notice Validates if the period is smaller than the max period or bigger than the min period\n * @param _period Period to be checked\n * @param _minPeriod Minimum period\n * @param _maxPeriod Maximum period\n */\n function _validatePeriodBoundaries(\n uint128 _period,\n uint128 _minPeriod,\n uint128 _maxPeriod\n ) internal pure {\n if (_period >= _maxPeriod || _period <= _minPeriod)\n revert SecurityManager__OutOfBoundary();\n }\n}\n" + }, + "contracts/infrastructure/WhitelistStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {RemoteStorage} from \"./RemoteStorage.sol\";\n\n/**\n * @title Whitelist storage\n * @dev Maps addresses to the corresponsing array of whitelisted addresses for each of them.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract WhitelistStorage is RemoteStorage {\n /**\n * @dev Add the address to the whitelist storage\n * @param _wallet User wallet\n * @param _address Address to be whitelisted\n */\n function whitelistAddress(address _wallet, address _address) external {\n enforceWalletOrGuardianIfExists(_wallet);\n addAddress(_wallet, _address);\n }\n\n /**\n * @dev Removes the address from the whitelist storage\n * @param _wallet User wallet\n * @param _address Address to be removed from the whitelist\n */\n function blacklistAddress(address _wallet, address _address) external {\n enforceGuardianOrWallet(_wallet);\n removeAddress(_wallet, _address);\n }\n\n /**\n * @dev Returns whether the address exists in the whitelist storage, associated with the wallet\n * @param _wallet User wallet\n * @param _address Address to be whitelisted\n */\n function isWhitelisted(\n address _wallet,\n address _address\n ) external view returns (bool) {\n return exists(_wallet, _address);\n }\n\n /**\n * @dev Returns all whitelisted addresses associated with the wallet\n * @param _wallet User wallet\n */\n function getWhitelistedAddresses(\n address _wallet\n ) external view returns (address[] memory) {\n return getAddresses(_wallet);\n }\n}\n" + }, + "contracts/interfaces/ERC/IERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\n\npragma solidity 0.8.21;\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155Receiver {\n /**\n * @dev Handles the receipt of a single ERC1155 token type. This function is\n * called at the end of a `safeTransferFrom` after the balance has been updated.\n *\n * NOTE: To accept the transfer, this must return\n * `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n * (i.e. 0xf23a6e61, or its own function selector).\n *\n * @param operator The address which initiated the transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param id The ID of the token being transferred\n * @param value The amount of tokens being transferred\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n ) external returns (bytes4);\n\n /**\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\n * is called at the end of a `safeBatchTransferFrom` after the balances have\n * been updated.\n *\n * NOTE: To accept the transfer(s), this must return\n * `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n * (i.e. 0xbc197c81, or its own function selector).\n *\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "contracts/interfaces/ERC/IERC1271.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\ninterface IERC1271 {\n function isValidSignature(\n bytes32 hash,\n bytes memory signature\n ) external view returns (bytes4);\n}\n" + }, + "contracts/interfaces/ERC/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\ninterface IERC165 {\n /// @notice Query if a contract implements an interface\n /// @param interfaceId The interface identifier, as specified in ERC-165\n /// @dev Interface identification is specified in ERC-165. This function\n /// uses less than 30,000 gas.\n /// @return `true` if the contract implements `interfaceID` and\n /// `interfaceID` is not 0xffffffff, `false` otherwise\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/IERC173.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\n/// @title ERC-173 Contract Ownership Standard\n/// Note: the ERC-165 identifier for this interface is 0x7f5828d0\n/* is ERC165 */\ninterface IERC173 {\n /// @dev This emits when ownership of a contract changes.\n event OwnershipTransferred(\n address indexed previousOwner,\n address indexed newOwner\n );\n\n /// @notice Get the address of the owner\n /// @return owner_ The address of the owner.\n function owner() external view returns (address owner_);\n\n /// @notice Set the address of the new owner of the contract\n /// @dev Set _newOwner to address(0) to renounce any ownership.\n /// @param _newOwner The address of the new owner of the contract\n function transferOwnership(address _newOwner) external;\n}\n" + }, + "contracts/interfaces/ERC/IERC677Receiver.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\ninterface IERC677Receiver {\n function onTokenTransfer(\n address sender,\n uint value,\n bytes calldata data\n ) external pure returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155 is IERC165 {\n /**\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n */\n event TransferSingle(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256 id,\n uint256 value\n );\n\n /**\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n * transfers.\n */\n event TransferBatch(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\n\n /**\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n * `approved`.\n */\n event ApprovalForAll(\n address indexed account,\n address indexed operator,\n bool approved\n );\n\n /**\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n *\n * If an {URI} event was emitted for `id`, the standard\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n * returned by {IERC1155MetadataURI-uri}.\n */\n event URI(string value, uint256 indexed id);\n\n /**\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(\n address account,\n uint256 id\n ) external view returns (uint256);\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] calldata accounts,\n uint256[] calldata ids\n ) external view returns (uint256[] memory);\n\n /**\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n *\n * Emits an {ApprovalForAll} event.\n *\n * Requirements:\n *\n * - `operator` cannot be the caller.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n *\n * See {setApprovalForAll}.\n */\n function isApprovedForAll(\n address account,\n address operator\n ) external view returns (bool);\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes calldata data\n ) external;\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(\n address indexed owner,\n address indexed spender,\n uint256 value\n );\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` 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 amount) 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(\n address owner,\n address spender\n ) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the 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 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` 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(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(\n address spender,\n uint256 addedValue\n ) external returns (bool);\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(\n address spender,\n uint256 subtractedValue\n ) external returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(\n address indexed from,\n address indexed to,\n uint256 indexed tokenId\n );\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(\n address indexed owner,\n address indexed approved,\n uint256 indexed tokenId\n );\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(\n address indexed owner,\n address indexed operator,\n bool approved\n );\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(\n uint256 tokenId\n ) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(\n address owner,\n address operator\n ) external view returns (bool);\n}\n" + }, + "contracts/interfaces/IBarz.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Barz Interface\n * @dev Interface of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IBarz {\n error Barz__InitializationFailure();\n}\n" + }, + "contracts/interfaces/IBarzFactory.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Barz} from \"../Barz.sol\";\n\n/**\n * @title Barz Factory Interface\n * @dev Interface of contract to easily deploy Barz to a pre-computed address with a single call\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IBarzFactory {\n event BarzDeployed(address);\n\n function createAccount(\n address verificationFacet,\n bytes calldata owner,\n uint256 salt\n ) external returns (Barz);\n\n function getAddress(\n address verificationFacet,\n bytes calldata owner,\n uint256 salt\n ) external view returns (address);\n\n function getBytecode(\n address accountFacet,\n address verificationFacet,\n address entryPoint,\n address facetRegistry,\n address defaultFallback,\n bytes memory ownerPublicKey\n ) external pure returns (bytes memory);\n\n function getCreationCode() external pure returns (bytes memory);\n}\n" + }, + "contracts/libraries/DefaultLibDiamond.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\n\nerror InitializationFunctionReverted(\n address _initializationContractAddress,\n bytes _calldata\n);\n\nlibrary DefaultLibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION =\n keccak256(\"trustwallet.barz.diamond.storage\");\n\n struct FacetAddressAndPosition {\n address facetAddress;\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\n }\n\n struct FacetFunctionSelectors {\n bytes4[] functionSelectors;\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\n }\n\n struct DiamondStorage {\n // maps function selector to the facet address and\n // the position of the selector in the facetFunctionSelectors.selectors array\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\n // maps facet addresses to function selectors\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\n // facet addresses\n address[] facetAddresses;\n // Used to query if a contract implements an interface.\n // Used to implement ERC-165.\n mapping(bytes4 => bool) supportedInterfaces;\n }\n\n function diamondStorage()\n internal\n pure\n returns (DiamondStorage storage ds)\n {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n event DiamondCut(\n IDiamondCut.FacetCut[] _diamondCut,\n address _init,\n bytes _calldata\n );\n\n // Internal function version of diamondCut\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n for (\n uint256 facetIndex;\n facetIndex < _diamondCut.length;\n facetIndex++\n ) {\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\n if (action == IDiamondCut.FacetCutAction.Add) {\n addFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\n replaceFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\n removeFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else {\n revert(\"LibDiamondCut: Incorrect FacetCutAction\");\n }\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Add facet can't be address(0)\"\n );\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n require(\n oldFacetAddress == address(0),\n \"LibDiamondCut: Can't add function that already exists\"\n );\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function replaceFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Replace facet can't be address(0)\"\n );\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n require(\n oldFacetAddress != _facetAddress,\n \"LibDiamondCut: Can't replace function with same facet\"\n );\n removeFunction(ds, oldFacetAddress, selector);\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function removeFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n // if function does not exist then do nothing and return\n require(\n _facetAddress == address(0),\n \"LibDiamondCut: Remove facet address must be address(0)\"\n );\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n removeFunction(ds, oldFacetAddress, selector);\n }\n }\n\n function addFacet(\n DiamondStorage storage ds,\n address _facetAddress\n ) internal {\n enforceHasContractCode(\n _facetAddress,\n \"LibDiamondCut: New facet has no code\"\n );\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds\n .facetAddresses\n .length;\n ds.facetAddresses.push(_facetAddress);\n }\n\n function addFunction(\n DiamondStorage storage ds,\n bytes4 _selector,\n uint96 _selectorPosition,\n address _facetAddress\n ) internal {\n ds\n .selectorToFacetAndPosition[_selector]\n .functionSelectorPosition = _selectorPosition;\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(\n _selector\n );\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\n }\n\n function removeFunction(\n DiamondStorage storage ds,\n address _facetAddress,\n bytes4 _selector\n ) internal {\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Can't remove function that doesn't exist\"\n );\n // an immutable function is a function defined directly in a diamond\n require(\n _facetAddress != address(this),\n \"LibDiamondCut: Can't remove immutable function\"\n );\n // replace selector with last selector, then delete last selector\n uint256 selectorPosition = ds\n .selectorToFacetAndPosition[_selector]\n .functionSelectorPosition;\n uint256 lastSelectorPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors\n .length - 1;\n // if not the same then replace _selector with lastSelector\n if (selectorPosition != lastSelectorPosition) {\n bytes4 lastSelector = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors[lastSelectorPosition];\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[\n selectorPosition\n ] = lastSelector;\n ds\n .selectorToFacetAndPosition[lastSelector]\n .functionSelectorPosition = uint96(selectorPosition);\n }\n // delete the last selector\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\n delete ds.selectorToFacetAndPosition[_selector];\n\n // if no more selectors for facet address then delete the facet address\n if (lastSelectorPosition == 0) {\n // replace facet address with last facet address and delete last facet address\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\n uint256 facetAddressPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .facetAddressPosition;\n if (facetAddressPosition != lastFacetAddressPosition) {\n address lastFacetAddress = ds.facetAddresses[\n lastFacetAddressPosition\n ];\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\n ds\n .facetFunctionSelectors[lastFacetAddress]\n .facetAddressPosition = facetAddressPosition;\n }\n ds.facetAddresses.pop();\n delete ds\n .facetFunctionSelectors[_facetAddress]\n .facetAddressPosition;\n }\n }\n\n function initializeDiamondCut(\n address _init,\n bytes memory _calldata\n ) internal {\n if (_init == address(0)) {\n return;\n }\n enforceHasContractCode(\n _init,\n \"LibDiamondCut: _init address has no code\"\n );\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length > 0) {\n // bubble up error\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(error)\n revert(add(32, error), returndata_size)\n }\n } else {\n revert InitializationFunctionReverted(_init, _calldata);\n }\n }\n }\n\n function enforceHasContractCode(\n address _contract,\n string memory _errorMessage\n ) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize > 0, _errorMessage);\n }\n}\n" + }, + "contracts/libraries/LibAppStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SafeCast} from \"@openzeppelin/contracts/utils/math/SafeCast.sol\";\nimport {IEntryPoint} from \"../aa-4337/interfaces/IEntryPoint.sol\";\nimport {IFacetRegistry} from \"../infrastructure/interfaces/IFacetRegistry.sol\";\n\n/*\n * @title App Storage\n * @dev App storage for Barz contract to prevent storage collision\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\n\nstruct Lock {\n uint64 release;\n bytes4 locker;\n}\n\nstruct InitializersStorage {\n // NOTE: initialized is a variable to make sure the initialization is only done once.\n uint8 signerInitialized;\n uint8 accountInitialized;\n uint8 restrictionsInitialized;\n}\n\nstruct AppStorage {\n mapping(uint256 => InitializersStorage) initStorage;\n uint8 signerMigration;\n bytes4 validateOwnerSignatureSelector;\n IEntryPoint entryPoint;\n IFacetRegistry facetRegistry;\n mapping(uint256 => Lock) locks;\n}\n\nlibrary LibAppStorage {\n error LibAppStorage__AccountAlreadyUninitialized();\n error LibAppStorage__AccountMustBeUninitialized();\n error LibAppStorage__SignerAlreadyUninitialized();\n error LibAppStorage__SignerMustBeUninitialized();\n\n function appStorage() internal pure returns (AppStorage storage ds) {\n assembly {\n ds.slot := 0\n }\n }\n\n function setSignerUninitialized() internal {\n AppStorage storage s = appStorage();\n if (1 != s.initStorage[0].signerInitialized) {\n revert LibAppStorage__SignerAlreadyUninitialized();\n }\n s.initStorage[0].signerInitialized = 0;\n }\n\n function getValidateOwnerSignatureSelector()\n internal\n view\n returns (bytes4 selector)\n {\n selector = appStorage().validateOwnerSignatureSelector;\n }\n\n function setValidateOwnerSignatureSelector(\n bytes4 _validateOwnerSignatureSelector\n ) internal {\n appStorage()\n .validateOwnerSignatureSelector = _validateOwnerSignatureSelector;\n }\n\n function enforceSignerInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].signerInitialized) {\n revert LibAppStorage__SignerMustBeUninitialized();\n }\n s.initStorage[0].signerInitialized = 1;\n }\n\n function enforceAccountInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].accountInitialized) {\n revert LibAppStorage__AccountMustBeUninitialized();\n }\n s.initStorage[0].accountInitialized = 1;\n }\n\n function initiateSignerMigration() internal {\n appStorage().signerMigration = 1;\n }\n\n function enforceSignerMigration() internal view {\n if (1 != appStorage().signerMigration) {\n revert LibAppStorage__AccountMustBeUninitialized();\n }\n }\n\n function finalizeSignerMigration() internal {\n appStorage().signerMigration = 0;\n }\n\n function setLock(uint256 _releaseAfter, bytes4 _locker) internal {\n appStorage().locks[0] = Lock(SafeCast.toUint64(_releaseAfter), _locker);\n }\n\n function enforceRestrictionsInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].restrictionsInitialized)\n revert LibAppStorage__SignerMustBeUninitialized();\n s.initStorage[0].restrictionsInitialized = 1;\n }\n\n function setRestrictionsUninitialized() internal {\n AppStorage storage s = appStorage();\n if (1 != s.initStorage[0].restrictionsInitialized)\n revert LibAppStorage__AccountAlreadyUninitialized();\n s.initStorage[0].restrictionsInitialized = 0;\n }\n}\n\ncontract BarzStorage {\n AppStorage internal s;\n modifier onlyWhenUnlocked() {\n require(\n uint64(block.timestamp) >= s.locks[0].release,\n \"Account Locked\"\n );\n _;\n }\n modifier onlyWhenLocked() {\n require(\n uint64(block.timestamp) < s.locks[0].release,\n \"Account Unlocked\"\n );\n _;\n }\n}\n" + }, + "contracts/libraries/LibDiamond.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\n\nerror InitializationFunctionReverted(\n address _initializationContractAddress,\n bytes _calldata\n);\n\nlibrary LibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION =\n keccak256(\"trustwallet.barz.diamond.storage\");\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\n bytes4(keccak256(\"verifyRestrictions(address,address,uint256,bytes)\"));\n struct DiamondStorage {\n // maps function selectors to the facets that execute the functions.\n // and maps the selectors to their position in the selectorSlots array.\n // func selector => address facet, selector position\n mapping(bytes4 => bytes32) facets;\n // array of slots of function selectors.\n // each slot holds 8 function selectors.\n mapping(uint256 => bytes32) selectorSlots;\n // The number of function selectors in selectorSlots\n uint16 selectorCount;\n // Used to query if a contract implements an interface.\n // Used to implement ERC-165.\n mapping(bytes4 => bool) supportedInterfaces;\n // Default Fallback Handler of the barz.\n IDiamondLoupe defaultFallbackHandler;\n }\n\n function diamondStorage()\n internal\n pure\n returns (DiamondStorage storage ds)\n {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n function enforceIsSelf() internal view {\n require(msg.sender == address(this), \"LibDiamond: Caller not self\");\n }\n\n event DiamondCut(\n IDiamondCut.FacetCut[] _diamondCut,\n address _init,\n bytes _calldata\n );\n\n bytes32 constant CLEAR_ADDRESS_MASK =\n bytes32(uint256(0xffffffffffffffffffffffff));\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\n\n // Internal function version of diamondCut\n // This code is almost the same as the external diamondCut,\n // except it is using 'Facet[] memory _diamondCut' instead of\n // 'Facet[] calldata _diamondCut'.\n // The code is duplicated to prevent copying calldata to memory which\n // causes an error for a two dimensional array.\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n DiamondStorage storage ds = diamondStorage();\n uint256 originalSelectorCount = ds.selectorCount;\n uint256 selectorCount = originalSelectorCount;\n bytes32 selectorSlot;\n // Check if last selector slot is not full\n // \"selectorCount & 7\" is a gas efficient modulo by eight \"selectorCount % 8\"\n if (selectorCount & 7 > 0) {\n // get last selectorSlot\n // \"selectorSlot >> 3\" is a gas efficient division by 8 \"selectorSlot / 8\"\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\n }\n // loop through diamond cut\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\n selectorCount,\n selectorSlot,\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].action,\n _diamondCut[facetIndex].functionSelectors\n );\n\n unchecked {\n facetIndex++;\n }\n }\n if (selectorCount != originalSelectorCount) {\n ds.selectorCount = uint16(selectorCount);\n }\n // If last selector slot is not full\n // \"selectorCount & 7\" is a gas efficient modulo by eight \"selectorCount % 8\"\n if (selectorCount & 7 > 0) {\n // \"selectorSlot >> 3\" is a gas efficient division by 8 \"selectorSlot / 8\"\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addReplaceRemoveFacetSelectors(\n uint256 _selectorCount,\n bytes32 _selectorSlot,\n address _newFacetAddress,\n IDiamondCut.FacetCutAction _action,\n bytes4[] memory _selectors\n ) internal returns (uint256, bytes32) {\n DiamondStorage storage ds = diamondStorage();\n require(\n _selectors.length > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n if (_action == IDiamondCut.FacetCutAction.Add) {\n enforceHasContractCode(\n _newFacetAddress,\n \"LibDiamondCut: Add facet has no code\"\n );\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n require(\n address(bytes20(oldFacet)) == address(0),\n \"LibDiamondCut: Can't add function that already exists\"\n );\n // add facet for selector\n ds.facets[selector] =\n bytes20(_newFacetAddress) |\n bytes32(_selectorCount);\n // \"_selectorCount & 7\" is a gas efficient modulo by eight \"_selectorCount % 8\"\n // \" << 5 is the same as multiplying by 32 ( * 32)\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\n // clear selector position in slot and add selector\n _selectorSlot =\n (_selectorSlot &\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\n (bytes32(selector) >> selectorInSlotPosition);\n // if slot is full then write it to storage\n if (selectorInSlotPosition == 224) {\n // \"_selectorSlot >> 3\" is a gas efficient division by 8 \"_selectorSlot / 8\"\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\n _selectorSlot = 0;\n }\n _selectorCount++;\n\n unchecked {\n selectorIndex++;\n }\n }\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\n enforceHasContractCode(\n _newFacetAddress,\n \"LibDiamondCut: Replace facet has no code\"\n );\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n address oldFacetAddress = address(bytes20(oldFacet));\n // only useful if immutable functions exist\n require(\n oldFacetAddress != address(this),\n \"LibDiamondCut: Can't replace immutable function\"\n );\n require(\n oldFacetAddress != _newFacetAddress,\n \"LibDiamondCut: Can't replace function with same function\"\n );\n require(\n oldFacetAddress != address(0),\n \"LibDiamondCut: Can't replace function that doesn't exist\"\n );\n // replace old facet address\n ds.facets[selector] =\n (oldFacet & CLEAR_ADDRESS_MASK) |\n bytes20(_newFacetAddress);\n\n unchecked {\n selectorIndex++;\n }\n }\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\n require(\n _newFacetAddress == address(0),\n \"LibDiamondCut: Remove facet address must be address(0)\"\n );\n // \"_selectorCount >> 3\" is a gas efficient division by 8 \"_selectorCount / 8\"\n uint256 selectorSlotCount = _selectorCount >> 3;\n // \"_selectorCount & 7\" is a gas efficient modulo by eight \"_selectorCount % 8\"\n uint256 selectorInSlotIndex = _selectorCount & 7;\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n if (_selectorSlot == 0) {\n // get last selectorSlot\n selectorSlotCount--;\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\n selectorInSlotIndex = 7;\n } else {\n selectorInSlotIndex--;\n }\n bytes4 lastSelector;\n uint256 oldSelectorsSlotCount;\n uint256 oldSelectorInSlotPosition;\n // adding a block here prevents stack too deep error\n {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n require(\n address(bytes20(oldFacet)) != address(0),\n \"LibDiamondCut: Can't remove function that doesn't exist\"\n );\n // only useful if immutable functions exist\n require(\n address(bytes20(oldFacet)) != address(this),\n \"LibDiamondCut: Can't remove immutable function\"\n );\n // replace selector with last selector in ds.facets\n // gets the last selector\n // \" << 5 is the same as multiplying by 32 ( * 32)\n lastSelector = bytes4(\n _selectorSlot << (selectorInSlotIndex << 5)\n );\n if (lastSelector != selector) {\n // update last selector slot position info\n ds.facets[lastSelector] =\n (oldFacet & CLEAR_ADDRESS_MASK) |\n bytes20(ds.facets[lastSelector]);\n }\n delete ds.facets[selector];\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\n // \"oldSelectorCount >> 3\" is a gas efficient division by 8 \"oldSelectorCount / 8\"\n oldSelectorsSlotCount = oldSelectorCount >> 3;\n // \"oldSelectorCount & 7\" is a gas efficient modulo by eight \"oldSelectorCount % 8\"\n // \" << 5 is the same as multiplying by 32 ( * 32)\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\n }\n if (oldSelectorsSlotCount != selectorSlotCount) {\n bytes32 oldSelectorSlot = ds.selectorSlots[\n oldSelectorsSlotCount\n ];\n // clears the selector we are deleting and puts the last selector in its place.\n oldSelectorSlot =\n (oldSelectorSlot &\n ~(CLEAR_SELECTOR_MASK >>\n oldSelectorInSlotPosition)) |\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\n // update storage with the modified slot\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\n } else {\n // clears the selector we are deleting and puts the last selector in its place.\n _selectorSlot =\n (_selectorSlot &\n ~(CLEAR_SELECTOR_MASK >>\n oldSelectorInSlotPosition)) |\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\n }\n if (selectorInSlotIndex == 0) {\n delete ds.selectorSlots[selectorSlotCount];\n _selectorSlot = 0;\n }\n\n unchecked {\n selectorIndex++;\n }\n }\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\n } else {\n revert(\"LibDiamondCut: Incorrect FacetCutAction\");\n }\n return (_selectorCount, _selectorSlot);\n }\n\n function initializeDiamondCut(\n address _init,\n bytes memory _calldata\n ) internal {\n if (_init == address(0)) {\n return;\n }\n enforceHasContractCode(\n _init,\n \"LibDiamondCut: _init address has no code\"\n );\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length > 0) {\n // bubble up error\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(error)\n revert(add(32, error), returndata_size)\n }\n } else {\n revert InitializationFunctionReverted(_init, _calldata);\n }\n }\n }\n\n function enforceHasContractCode(\n address _contract,\n string memory _errorMessage\n ) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize > 0, _errorMessage);\n }\n\n function restrictionsFacet() internal view returns (address facetAddress_) {\n facetAddress_ = address(\n bytes20(\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\n )\n );\n }\n}\n" + }, + "contracts/libraries/LibFacetStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Storage\n * @dev Storage contract to store each facets variables with diamond storage\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\n\nstruct Secp256k1VerificationStorage {\n address signer;\n}\n\nstruct Secp256r1VerificationStorage {\n uint256[2] q;\n}\n\nstruct GuardianStorage {\n mapping(bytes32 => uint256) pending;\n mapping(uint8 => StorageConfig) configs;\n}\n\nstruct Info {\n bool exists;\n uint128 index;\n}\n\nstruct StorageConfig {\n address[] addresses;\n mapping(address => Info) info;\n}\n\nstruct RecoveryConfig {\n bytes recoveryPublicKey;\n uint64 executeAfter;\n}\n\nstruct ApprovalConfig {\n bool isApproved;\n uint64 validUntil;\n}\n\nstruct RecoveryApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isNewOwnerApproved;\n}\n\nstruct RecoveryStorage {\n mapping(uint8 => RecoveryConfig) recoveryConfigs;\n mapping(uint8 => RecoveryApprovalConfig) recoveryApprovalConfigs;\n uint128 nonce;\n}\n\nstruct RestrictionsStorage {\n address[] restrictions;\n mapping(address => bool) exists;\n}\n\nstruct SignatureMigrationConfig {\n bytes migrationPublicKey;\n address migrationVerificationFacet;\n bytes4[] migrationSelectors;\n uint64 migrateAfter;\n}\n\nstruct SignatureMigrationApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isMigrationApproved;\n}\n\nstruct SignatureMigrationStorage {\n mapping(uint8 => SignatureMigrationConfig) migrationConfigs;\n mapping(uint8 => SignatureMigrationApprovalConfig) migrationApprovalConfigs;\n uint128 nonce;\n}\n\nstruct DiamondCutApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isDiamondCutApproved;\n}\n\nstruct DiamondCutStorage {\n mapping(uint8 => DiamondCutApprovalConfig) diamondCutApprovalConfigs;\n uint128 nonce;\n}\n\nstruct LockStorage {\n uint128 nonce;\n}\n\nlibrary LibFacetStorage {\n bytes32 constant K1_STORAGE_POSITION =\n keccak256(\n \"v0.trustwallet.diamond.storage.Secp256k1VerificationStorage\"\n );\n bytes32 constant R1_STORAGE_POSITION =\n keccak256(\n \"v0.trustwallet.diamond.storage.Secp256r1VerificationStorage\"\n );\n bytes32 constant GUARDIAN_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.GuardianStorage\");\n bytes32 constant RECOVERY_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.RecoveryStorage\");\n bytes32 constant RESTRICTION_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.RestrictionsStorage\");\n bytes32 constant MIGRATION_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.SignatureMigrationStorage\");\n bytes32 constant DIAMONDCUT_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.DiamondCutStorage\");\n bytes32 constant LOCK_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.LockStorage\");\n\n function k1Storage()\n internal\n pure\n returns (Secp256k1VerificationStorage storage ds)\n {\n bytes32 storagePosition = K1_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function r1Storage()\n internal\n pure\n returns (Secp256r1VerificationStorage storage ds)\n {\n bytes32 storagePosition = R1_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function guardianStorage()\n internal\n pure\n returns (GuardianStorage storage ds)\n {\n bytes32 storagePosition = GUARDIAN_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function recoveryStorage()\n internal\n pure\n returns (RecoveryStorage storage ds)\n {\n bytes32 storagePosition = RECOVERY_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function restrictionsStorage()\n internal\n pure\n returns (RestrictionsStorage storage ds)\n {\n bytes32 storagePosition = RESTRICTION_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function migrationStorage()\n internal\n pure\n returns (SignatureMigrationStorage storage ds)\n {\n bytes32 storagePosition = MIGRATION_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function diamondCutStorage()\n internal\n pure\n returns (DiamondCutStorage storage ds)\n {\n bytes32 storagePosition = DIAMONDCUT_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function lockStorage() internal pure returns (LockStorage storage ds) {\n bytes32 storagePosition = LOCK_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n}\n" + }, + "contracts/libraries/LibGuardian.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibFacetStorage, StorageConfig} from \"./LibFacetStorage.sol\";\n\n/**\n * @title LibGuardian\n * @dev Internal Library to provide utility feature for Guardians stored in Guardian Facet Storage\n * @author David Yongjun Kim (@Powerstream3604)\n */\nlibrary LibGuardian {\n function majorityOfGuardians()\n internal\n view\n returns (uint256 guardianNumber)\n {\n uint256 guardianLength = guardianCount();\n guardianNumber = (guardianLength == 0) ? 0 : guardianLength / 2 + 1;\n }\n\n function isGuardian(address _guardian) internal view returns (bool) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n return config.info[_guardian].exists;\n }\n\n function guardianCount() internal view returns (uint256) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n return config.addresses.length;\n }\n\n function getGuardians() internal view returns (address[] memory) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n address[] memory addresses = new address[](config.addresses.length);\n uint256 addressesLen = config.addresses.length;\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n return addresses;\n }\n}\n" + }, + "contracts/libraries/LibLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {LibDiamond} from \"./LibDiamond.sol\";\n\n/**\n * @title LibLoupe\n * @dev Internal Library to provide utility feature for reading the state of diamond facets\n * Originally from Diamond's implementation of Mudgen(author of EIP-2535)\n */\nlibrary LibLoupe {\n /// @notice Gets all facets and their selectors.\n /// @return facets_ Facet\n function facets()\n internal\n view\n returns (IDiamondLoupe.Facet[] memory facets_)\n {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facets_ = new IDiamondLoupe.Facet[](ds.selectorCount);\n uint16[] memory numFacetSelectors = new uint16[](ds.selectorCount);\n uint256 numFacets;\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facetAddress_ = address(bytes20(ds.facets[selector]));\n bool continueLoop;\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n if (facets_[facetIndex].facetAddress == facetAddress_) {\n facets_[facetIndex].functionSelectors[\n numFacetSelectors[facetIndex]\n ] = selector;\n // probably will never have more than 256 functions from one facet contract\n require(numFacetSelectors[facetIndex] < 255);\n numFacetSelectors[facetIndex]++;\n continueLoop = true;\n break;\n }\n }\n if (continueLoop) {\n continue;\n }\n facets_[numFacets].facetAddress = facetAddress_;\n facets_[numFacets].functionSelectors = new bytes4[](\n ds.selectorCount\n );\n facets_[numFacets].functionSelectors[0] = selector;\n numFacetSelectors[numFacets] = 1;\n numFacets++;\n }\n }\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n uint256 numSelectors = numFacetSelectors[facetIndex];\n bytes4[] memory selectors = facets_[facetIndex].functionSelectors;\n // setting the number of selectors\n assembly {\n mstore(selectors, numSelectors)\n }\n }\n // setting the number of facets\n assembly {\n mstore(facets_, numFacets)\n }\n }\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n /// @return _facetFunctionSelectors The selectors associated with a facet address.\n function facetFunctionSelectors(\n address _facet\n ) internal view returns (bytes4[] memory _facetFunctionSelectors) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n uint256 numSelectors;\n _facetFunctionSelectors = new bytes4[](ds.selectorCount);\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facet = address(bytes20(ds.facets[selector]));\n if (_facet == facet) {\n _facetFunctionSelectors[numSelectors] = selector;\n numSelectors++;\n }\n }\n }\n // Set the number of selectors in the array\n assembly {\n mstore(_facetFunctionSelectors, numSelectors)\n }\n }\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses()\n internal\n view\n returns (address[] memory facetAddresses_)\n {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facetAddresses_ = new address[](ds.selectorCount);\n uint256 numFacets;\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facetAddress_ = address(bytes20(ds.facets[selector]));\n bool continueLoop;\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n if (facetAddress_ == facetAddresses_[facetIndex]) {\n continueLoop = true;\n break;\n }\n }\n if (continueLoop) {\n continue;\n }\n facetAddresses_[numFacets] = facetAddress_;\n numFacets++;\n }\n }\n // Set the number of facet addresses in the array\n assembly {\n mstore(facetAddresses_, numFacets)\n }\n }\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(\n bytes4 _functionSelector\n ) internal view returns (address facetAddress_) {\n facetAddress_ = address(\n bytes20(LibDiamond.diamondStorage().facets[_functionSelector])\n );\n }\n}\n" + }, + "contracts/libraries/LibMultiSigStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Multi-sig Storage\n * @dev Storage contract for storing Multi-sig Facet variables in diamond storage pattern\n * @author David Yongjun Kim (@Powerstream3604)\n */\n\nstruct MultiSigStorage {\n mapping(address => address) owners;\n mapping(uint256 => mapping(address => mapping(bytes32 => uint256))) approvedHashes;\n uint256 ownerCount;\n uint256 threshold;\n uint256 counter;\n}\n\nlibrary LibMultiSigStorage {\n function multisigStorage()\n internal\n pure\n returns (MultiSigStorage storage ds)\n {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.MultiSigStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n}\n" + }, + "contracts/libraries/LibRecoverSpender.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title RecoverSpender\n * @dev Library to determine the action and spender of calldata\n * @author Ruslan Serebriakov (@rsrbk)\n */\nlibrary LibRecoverSpender {\n // ERC20, ERC721 & ERC1155 transfers & approvals\n bytes4 private constant ERC20_TRANSFER =\n bytes4(keccak256(\"transfer(address,uint256)\"));\n bytes4 private constant ERC20_APPROVE =\n bytes4(keccak256(\"approve(address,uint256)\"));\n bytes4 private constant ERC20_INCREASE_ALLOWANCE =\n bytes4(keccak256(\"increaseAllowance(address,uint256)\"));\n bytes4 private constant ERC20_DECREASE_ALLOWANCE =\n bytes4(keccak256(\"decreaseAllowance(address,uint256)\"));\n bytes4 private constant ERC721_SET_APPROVAL_FOR_ALL =\n bytes4(keccak256(\"setApprovalForAll(address,bool)\"));\n bytes4 private constant ERC721_TRANSFER_FROM =\n bytes4(keccak256(\"transferFrom(address,address,uint256)\"));\n bytes4 private constant ERC721_SAFE_TRANSFER_FROM =\n bytes4(keccak256(\"safeTransferFrom(address,address,uint256)\"));\n bytes4 private constant ERC721_SAFE_TRANSFER_FROM_BYTES =\n bytes4(keccak256(\"safeTransferFrom(address,address,uint256,bytes)\"));\n bytes4 private constant ERC1155_SAFE_TRANSFER_FROM =\n bytes4(\n keccak256(\"safeTransferFrom(address,address,uint256,uint256,bytes)\")\n );\n bytes4 private constant ERC1155_SAFE_BATCH_TRANSFER_FROM =\n bytes4(\n keccak256(\n \"safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)\"\n )\n );\n\n /**\n * @notice Helper method to recover the spender from a contract call.\n * The method returns the contract unless the call is to a standard method of a ERC20/ERC721/ERC1155 token\n * in which case the spender is recovered from the data.\n * @param _to The target contract.\n * @param _data The data payload.\n */\n function _recover(\n address _to,\n bytes memory _data\n ) internal pure returns (address spender) {\n if (_data.length >= 68) {\n bytes4 methodId;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n methodId := mload(add(_data, 0x20))\n }\n if (\n methodId == ERC20_TRANSFER ||\n methodId == ERC20_APPROVE ||\n methodId == ERC20_INCREASE_ALLOWANCE ||\n methodId == ERC20_DECREASE_ALLOWANCE ||\n methodId == ERC721_SET_APPROVAL_FOR_ALL\n ) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n spender := mload(add(_data, 0x24))\n }\n return spender;\n }\n if (\n methodId == ERC721_TRANSFER_FROM ||\n methodId == ERC721_SAFE_TRANSFER_FROM ||\n methodId == ERC721_SAFE_TRANSFER_FROM_BYTES ||\n methodId == ERC1155_SAFE_TRANSFER_FROM ||\n methodId == ERC1155_SAFE_BATCH_TRANSFER_FROM\n ) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n spender := mload(add(_data, 0x44))\n }\n return spender;\n }\n }\n\n spender = _to;\n }\n}\n" + }, + "contracts/libraries/LibUtils.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\n\nlibrary LibUtils {\n // Internal utility functions\n function mergeArrays(\n bytes4[] memory _array1,\n bytes4[] memory _array2\n ) internal pure returns (bytes4[] memory) {\n uint256 length1 = _array1.length;\n uint256 length2 = _array2.length;\n bytes4[] memory mergedArray = new bytes4[](length1 + length2);\n\n for (uint256 i; i < length1; ) {\n mergedArray[i] = _array1[i];\n unchecked {\n ++i;\n }\n }\n\n for (uint256 i; i < length2; ) {\n mergedArray[length1 + i] = _array2[i];\n unchecked {\n ++i;\n }\n }\n\n return mergedArray;\n }\n\n function removeFacetElement(\n IDiamondLoupe.Facet[] memory _facets,\n uint256 _index\n ) internal pure returns (IDiamondLoupe.Facet[] memory) {\n require(_index < _facets.length, \"Invalid index\");\n require(_facets.length != 0, \"Invalid array\");\n\n // Create a new array with a length of `_facets.length - 1`\n IDiamondLoupe.Facet[] memory newArray = new IDiamondLoupe.Facet[](\n _facets.length - 1\n );\n uint256 newArrayLength = newArray.length;\n // Iterate over the original array, skipping the element at the specified `index`\n for (uint256 i; i < newArrayLength; ) {\n if (i < _index) {\n newArray[i] = _facets[i];\n } else {\n newArray[i] = _facets[i + 1];\n }\n unchecked {\n ++i;\n }\n }\n\n return newArray;\n }\n\n function removeElement(\n bytes4[] memory _array,\n uint256 _index\n ) internal pure returns (bytes4[] memory) {\n require(_index < _array.length, \"Invalid index\");\n require(_array.length != 0, \"Invalid array\");\n\n bytes4[] memory newArray = new bytes4[](_array.length - 1);\n uint256 newArrayLength = newArray.length;\n for (uint256 i; i < newArrayLength; ) {\n if (i < _index) {\n newArray[i] = _array[i];\n } else {\n newArray[i] = _array[i + 1];\n }\n unchecked {\n ++i;\n }\n }\n\n return newArray;\n }\n\n function setValue(\n bytes4[] memory _keys,\n address[] memory _values,\n bytes4 _key,\n address _value\n ) internal pure returns (bytes4[] memory, address[] memory) {\n uint256 index = findIndex(_keys, _key);\n uint256 keysLength = _keys.length;\n if (index < keysLength) {\n _values[index] = _value;\n } else {\n // Create new storage arrays\n bytes4[] memory newKeys = new bytes4[](keysLength + 1);\n address[] memory newValues = new address[](_values.length + 1);\n\n // Copy values to the new storage arrays\n for (uint256 i; i < keysLength; ) {\n newKeys[i] = _keys[i];\n newValues[i] = _values[i];\n\n unchecked {\n ++i;\n }\n }\n\n // Add the new key-value pair\n newKeys[keysLength] = _key;\n newValues[_values.length] = _value;\n\n return (newKeys, newValues);\n }\n\n // If the key already exists, return the original arrays\n return (_keys, _values);\n }\n\n function getValue(\n bytes4[] memory _keys,\n address[] memory _values,\n bytes4 _key\n ) internal pure returns (address) {\n uint256 index = findIndex(_keys, _key);\n if (index >= _keys.length) return address(0);\n\n return _values[index];\n }\n\n function findIndex(\n bytes4[] memory _keys,\n bytes4 _key\n ) internal pure returns (uint256) {\n uint256 keysLength = _keys.length;\n for (uint256 i; i < keysLength; ) {\n if (_keys[i] == _key) {\n return i;\n }\n unchecked {\n ++i;\n }\n }\n return keysLength;\n }\n}\n" + }, + "contracts/restrictions/IRestriction.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Interface for restrictions\n * @dev Restriction is a contract which decides whether to approve a certain kind of transaction, based on its internal logic.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface IRestriction {\n /**\n * @dev Based on restriction's internal logic, it should accept or reject a certain transaction.\n * @param from The address of the sender, that will be signing the transaction.\n * @param to The receiving address.\n * @param value Amount of ETH to transfer from sender to recipient.\n * @param _calldata Optional field to include arbitrary data.\n * @return bool value for whether the check is passed\n */\n function check(\n address from,\n address to,\n uint256 value,\n bytes calldata _calldata\n ) external returns (bool);\n}\n" + }, + "contracts/restrictions/WhitelistRestriction.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibRecoverSpender} from \"../libraries/LibRecoverSpender.sol\";\nimport {WhitelistStorage} from \"../infrastructure/WhitelistStorage.sol\";\nimport {IRestriction} from \"./IRestriction.sol\";\n\n/**\n * @title Whitelist Restriction\n * @dev This restriction defines a list of accepted addresses and denies any interaction with addresses outside of it.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract WhitelistRestriction is IRestriction {\n WhitelistStorage public immutable whitelistStorage;\n\n constructor(WhitelistStorage _whitelistStorage) {\n whitelistStorage = _whitelistStorage;\n }\n\n /**\n * @notice Helper method to recover the spender from a contract call.\n * The method returns the contract unless the call is to a standard method of a ERC20/ERC721/ERC1155 token\n * in which case the spender is recovered from the data.\n * @param _to The target contract.\n * @param _data The data payload.\n */\n function recoverSpender(\n address _to,\n bytes memory _data\n ) public pure returns (address spender) {\n return LibRecoverSpender._recover(_to, _data);\n }\n\n /*\n * @dev IRestriction's implementation. It will allow transaction if the sender is whitelisted, or user, or the whitelist storage.\n * @param _from The address of the sender, that will be signing the transaction.\n * @param _to The receiving address.\n * @param _calldata Optional field to include arbitrary data.\n * @return result value for whether the check is passed\n */\n function check(\n address _from,\n address _to,\n uint256 /*_value*/,\n bytes calldata _calldata\n ) external view override returns (bool result) {\n return\n whitelistStorage.isWhitelisted(\n _from,\n LibRecoverSpender._recover(_to, _calldata)\n ) ||\n _to == address(whitelistStorage) ||\n _to == msg.sender;\n }\n}\n" + }, + "contracts/test/Counter.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\ncontract TestCounter {\n int private count = 0;\n\n function incrementCounter() public {\n count += 1;\n }\n\n function decrementCounter() public {\n count -= 1;\n }\n\n function getCount() public view returns (int) {\n return count;\n }\n}\n" + }, + "contracts/test/TestERC1155.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC1155/ERC1155.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\n\ncontract TestERC1155 is ERC1155 {\n using Counters for Counters.Counter;\n\n Counters.Counter private _tokenIds;\n\n constructor() ERC1155(\"\") {}\n\n function mint(address account, uint256 amount) external {\n uint256 tokenId = _getNextTokenId();\n _mint(account, tokenId, amount, \"\");\n }\n\n function mintBatch(\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes memory data\n ) external {\n require(\n ids.length == amounts.length,\n \"TestERC1155: arrays length mismatch\"\n );\n\n _mintBatch(to, ids, amounts, data);\n }\n\n function _getNextTokenId() private returns (uint256) {\n _tokenIds.increment();\n return _tokenIds.current();\n }\n}\n" + }, + "contracts/test/TestERC777.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC777/ERC777.sol\";\n\ncontract TestERC777 is ERC777 {\n constructor(\n address[] memory _operators\n ) ERC777(\"TestERC777\", \"TERC777\", _operators) {}\n\n function mint(address account, uint256 amount) external {\n _mint(account, amount, \"\", \"\");\n }\n}\n" + }, + "contracts/test/TestInvalidSecp256k1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IVerificationFacet} from \"../facets/interfaces/IVerificationFacet.sol\";\nimport {IERC1271} from \"../interfaces/ERC/IERC1271.sol\";\nimport {AppStorage, LibAppStorage, BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {LibFacetStorage, Secp256k1VerificationStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {UserOperation} from \"../aa-4337/interfaces/UserOperation.sol\";\n\n/**\n * @title Test Secp256k1 verification facet\n * @dev Default Ethereum's elliptic curve\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract TestInvalidSecp256k1VerificationFacet is BarzStorage, IERC1271 {\n using ECDSA for bytes32;\n error Secp256k1VerificationFacet__InvalidSignerLength();\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n\n event SignerUninitialized();\n\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n }\n\n // THIS INVALID FACET DOES NOT INCLUDE initializeSigner()\n // THIS FACET IS USED TO TEST WHEN initializeSigner() DOESN'T EXIST IN FACET\n\n function uninitializeSigner() external returns (uint256 uninitSuccess) {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view returns (uint256 validationData) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n return validateSignature(userOp, userOpHash, k1Storage.signer);\n }\n\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n address signer\n ) public pure returns (uint256) {\n bytes32 hash = userOpHash.toEthSignedMessageHash();\n if (signer != hash.recover(userOp.signature)) return 1;\n return 0;\n }\n\n // This is REMOVED for testing purpose\n function validateOwnerSignatureSelector() public pure returns (bytes4) {\n // return this.validateOwnerSignature.selector;\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n function owner() public view returns (bytes memory) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n return abi.encodePacked(k1Storage.signer);\n }\n\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure returns (bool) {\n return (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (_hash.recover(_signature) ==\n LibFacetStorage.k1Storage().signer)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n}\n" + }, + "contracts/test/TestNFT.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\n\ncontract TestNFT is ERC721 {\n using Counters for Counters.Counter;\n Counters.Counter private currentTokenId;\n\n constructor() ERC721(\"TestNFT\", \"TNFT\") {}\n\n function mint(address recipient) public returns (uint256) {\n currentTokenId.increment();\n uint256 newItemId = currentTokenId.current();\n _safeMint(recipient, newItemId);\n return newItemId;\n }\n}\n" + }, + "contracts/test/TestToken.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract TestToken is ERC20 {\n constructor()\n // solhint-disable-next-line no-empty-blocks\n ERC20(\"TST\", \"TestToken\")\n {}\n\n function mint(address sender, uint256 amount) external {\n _mint(sender, amount);\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 999999 + }, + "evmVersion": "paris", + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/deployments/lightLink/.chainId b/deployments/lightLink/.chainId new file mode 100644 index 0000000..d7e6ae9 --- /dev/null +++ b/deployments/lightLink/.chainId @@ -0,0 +1 @@ +1890 \ No newline at end of file diff --git a/deployments/lightLink/AccountFacet.json b/deployments/lightLink/AccountFacet.json new file mode 100644 index 0000000..e5337e4 --- /dev/null +++ b/deployments/lightLink/AccountFacet.json @@ -0,0 +1,591 @@ +{ + "address": "0xFde53272dcd7938d16E031A6989753c321728332", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "AccountFacet__CallNotSuccessful", + "type": "error" + }, + { + "inputs": [], + "name": "AccountFacet__InitializationFailure", + "type": "error" + }, + { + "inputs": [], + "name": "AccountFacet__InvalidArrayLength", + "type": "error" + }, + { + "inputs": [], + "name": "AccountFacet__NonExistentVerificationFacet", + "type": "error" + }, + { + "inputs": [], + "name": "AccountFacet__RestrictionsFailure", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_initializationContractAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "InitializationFunctionReverted", + "type": "error" + }, + { + "inputs": [], + "name": "LibAppStorage__AccountMustBeUninitialized", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract IEntryPoint", + "name": "entryPoint", + "type": "address" + }, + { + "indexed": true, + "internalType": "bytes", + "name": "ownerPublicKey", + "type": "bytes" + } + ], + "name": "AccountInitialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "indexed": false, + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "DiamondCut", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "VerificationFailure", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "VerificationSuccess", + "type": "event" + }, + { + "inputs": [], + "name": "entryPoint", + "outputs": [ + { + "internalType": "contract IEntryPoint", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_dest", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_func", + "type": "bytes" + } + ], + "name": "execute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_dest", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "_value", + "type": "uint256[]" + }, + { + "internalType": "bytes[]", + "name": "_func", + "type": "bytes[]" + } + ], + "name": "executeBatch", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getNonce", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_verificationFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_anEntryPoint", + "type": "address" + }, + { + "internalType": "address", + "name": "_facetRegistry", + "type": "address" + }, + { + "internalType": "address", + "name": "_defaultFallBackHandler", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_ownerPublicKey", + "type": "bytes" + } + ], + "name": "initialize", + "outputs": [ + { + "internalType": "uint256", + "name": "initSuccess", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "initCode", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "callGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "verificationGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "preVerificationGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxFeePerGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPriorityFeePerGas", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "paymasterAndData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "internalType": "struct UserOperation", + "name": "userOp", + "type": "tuple" + }, + { + "internalType": "bytes32", + "name": "userOpHash", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "missingAccountFunds", + "type": "uint256" + } + ], + "name": "validateUserOp", + "outputs": [ + { + "internalType": "uint256", + "name": "validationData", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0x9976cce066816a0077462d0bd62d4085ab53bc5093aca054e63f91c7de263ee5", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": "0x0000000000000000000000000000000000000000", + "transactionIndex": 1, + "gasUsed": "2370628", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x168b6cd943609d5eca4e931d50aa16e99e6af3e9f92d4e8b2bd6f06f2888d150", + "transactionHash": "0x9976cce066816a0077462d0bd62d4085ab53bc5093aca054e63f91c7de263ee5", + "logs": [], + "blockNumber": 72701535, + "cumulativeGasUsed": "2370628", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "ad34345aa73d96f52b3e14df983b6b29", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AccountFacet__CallNotSuccessful\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AccountFacet__InitializationFailure\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AccountFacet__InvalidArrayLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AccountFacet__NonExistentVerificationFacet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AccountFacet__RestrictionsFailure\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_initializationContractAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"InitializationFunctionReverted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LibAppStorage__AccountMustBeUninitialized\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract IEntryPoint\",\"name\":\"entryPoint\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes\",\"name\":\"ownerPublicKey\",\"type\":\"bytes\"}],\"name\":\"AccountInitialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"DiamondCut\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"VerificationFailure\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"VerificationSuccess\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"entryPoint\",\"outputs\":[{\"internalType\":\"contract IEntryPoint\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_dest\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_func\",\"type\":\"bytes\"}],\"name\":\"execute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_dest\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"_value\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes[]\",\"name\":\"_func\",\"type\":\"bytes[]\"}],\"name\":\"executeBatch\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_verificationFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_anEntryPoint\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_facetRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_defaultFallBackHandler\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_ownerPublicKey\",\"type\":\"bytes\"}],\"name\":\"initialize\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"initSuccess\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"userOp\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"missingAccountFunds\",\"type\":\"uint256\"}],\"name\":\"validateUserOp\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"validationData\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"Account module contract that provides the account features and initialization of signer compatible with EIP-1271 & EIP-4337\",\"kind\":\"dev\",\"methods\":{\"execute(address,uint256,bytes)\":{\"details\":\"This method executes the calldata coming from the EntryPoint. Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\",\"params\":{\"_dest\":\"Address of destination where the call will be forwarded to\",\"_func\":\"Bytes of calldata to execute in the destination address\",\"_value\":\"Amount of native coin the owner is willing to send(e.g. ETH, BNB)\"}},\"executeBatch(address[],uint256[],bytes[])\":{\"details\":\"This method batch executes the calldata coming from the EntryPoint. Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\",\"params\":{\"_dest\":\"Array of addresses of destination where the call will be forwarded to\",\"_func\":\"Array of bytes of calldata to execute in the destination address\",\"_value\":\"Array of amount of native coin the owner is willing to send(e.g. ETH, BNB)\"}},\"initialize(address,address,address,address,bytes)\":{\"details\":\"This method can only be called during the initialization or signature migration. If the proxy contract was created without initialization, anyone can call initialize. Barz calls initialize in constructor in an atomic transaction during deployment\",\"params\":{\"_anEntryPoint\":\"Entrypoint contract defined in EIP-4337 handling the flow of UserOp\",\"_defaultFallBackHandler\":\"Middleware contract for default facets\",\"_facetRegistry\":\"Registry of Facets that hold all facet information\",\"_ownerPublicKey\":\"Bytes of owner public key\",\"_verificationFacet\":\"Facet contract handling the verificationi\"}}},\"title\":\"Account Facet\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"This constructor ensures that this contract can only be used as singleton for Proxy contracts\"},\"entryPoint()\":{\"notice\":\"Returns the address of EntryPoint contract registered to Barz account\"},\"execute(address,uint256,bytes)\":{\"notice\":\"Calls the destination with inputted calldata and value from EntryPoint\"},\"executeBatch(address[],uint256[],bytes[])\":{\"notice\":\"Batch calls the destination with inputted calldata and value from EntryPoint\"},\"getNonce()\":{\"notice\":\"Return the account nonce. This method returns the next sequential nonce. For a nonce of a specific key, use `entrypoint.getNonce(account, key)`\"},\"initialize(address,address,address,address,bytes)\":{\"notice\":\"Initializes the initial storage of the Barz contract.\"},\"validateUserOp((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256)\":{\"notice\":\"Validate user's signature and nonce. subclass doesn't need to override this method. Instead, it should override the specific internal validation methods.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/AccountFacet.sol\":\"AccountFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./math/Math.sol\\\";\\nimport \\\"./math/SignedMath.sol\\\";\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n uint256 length = Math.log10(value) + 1;\\n string memory buffer = new string(length);\\n uint256 ptr;\\n /// @solidity memory-safe-assembly\\n assembly {\\n ptr := add(buffer, add(32, length))\\n }\\n while (true) {\\n ptr--;\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\\n }\\n value /= 10;\\n if (value == 0) break;\\n }\\n return buffer;\\n }\\n }\\n\\n /**\\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\\n */\\n function toString(int256 value) internal pure returns (string memory) {\\n return string(abi.encodePacked(value < 0 ? \\\"-\\\" : \\\"\\\", toString(SignedMath.abs(value))));\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n return toHexString(value, Math.log256(value) + 1);\\n }\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n\\n /**\\n * @dev Returns true if the two strings are equal.\\n */\\n function equal(string memory a, string memory b) internal pure returns (bool) {\\n return keccak256(bytes(a)) == keccak256(bytes(b));\\n }\\n}\\n\",\"keccak256\":\"0x3088eb2868e8d13d89d16670b5f8612c4ab9ff8956272837d8e90106c59c14a0\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Strings.sol\\\";\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSA {\\n enum RecoverError {\\n NoError,\\n InvalidSignature,\\n InvalidSignatureLength,\\n InvalidSignatureS,\\n InvalidSignatureV // Deprecated in v4.8\\n }\\n\\n function _throwError(RecoverError error) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert(\\\"ECDSA: invalid signature\\\");\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert(\\\"ECDSA: invalid signature length\\\");\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert(\\\"ECDSA: invalid signature 's' value\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature` or error string. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n *\\n * Documentation for signature generation:\\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n return tryRecover(hash, v, r, s);\\n } else {\\n return (address(0), RecoverError.InvalidSignatureLength);\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature`. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, signature);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\\n uint8 v = uint8((uint256(vs) >> 255) + 27);\\n return tryRecover(hash, v, r, s);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n *\\n * _Available since v4.2._\\n */\\n function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\\n // the valid range for s in (301): 0 < s < secp256k1n \\u00f7 2 + 1, and for v in (302): v \\u2208 {27, 28}. Most\\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\\n //\\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\\n // these malleable signatures as well.\\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n return (address(0), RecoverError.InvalidSignatureS);\\n }\\n\\n // If the signature is valid (and not malleable), return the signer address\\n address signer = ecrecover(hash, v, r, s);\\n if (signer == address(0)) {\\n return (address(0), RecoverError.InvalidSignature);\\n }\\n\\n return (signer, RecoverError.NoError);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore(0x00, \\\"\\\\x19Ethereum Signed Message:\\\\n32\\\")\\n mstore(0x1c, hash)\\n message := keccak256(0x00, 0x3c)\\n }\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from `s`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n\\\", Strings.toString(s.length), s));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Typed Data, created from a\\n * `domainSeparator` and a `structHash`. This produces hash corresponding\\n * to the one signed with the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n * JSON-RPC method as part of EIP-712.\\n *\\n * See {recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n let ptr := mload(0x40)\\n mstore(ptr, \\\"\\\\x19\\\\x01\\\")\\n mstore(add(ptr, 0x02), domainSeparator)\\n mstore(add(ptr, 0x22), structHash)\\n data := keccak256(ptr, 0x42)\\n }\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Data with intended validator, created from a\\n * `validator` and `data` according to the version 0 of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x00\\\", validator, data));\\n }\\n}\\n\",\"keccak256\":\"0x809bc3edb4bcbef8263fa616c1b60ee0004b50a8a1bfa164d8f57fd31f520c58\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n enum Rounding {\\n Down, // Toward negative infinity\\n Up, // Toward infinity\\n Zero // Toward zero\\n }\\n\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow.\\n return (a & b) + (a ^ b) / 2;\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a == 0 ? 0 : (a - 1) / b + 1;\\n }\\n\\n /**\\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\\n * with further edits by Uniswap Labs also under MIT license.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\\n unchecked {\\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2^256 + prod0.\\n uint256 prod0; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division.\\n if (prod1 == 0) {\\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\\n // The surrounding unchecked block does not change this fact.\\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\\n return prod0 / denominator;\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n require(denominator > prod1, \\\"Math: mulDiv overflow\\\");\\n\\n ///////////////////////////////////////////////\\n // 512 by 256 division.\\n ///////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0].\\n uint256 remainder;\\n assembly {\\n // Compute remainder using mulmod.\\n remainder := mulmod(x, y, denominator)\\n\\n // Subtract 256 bit number from 512 bit number.\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\\n // See https://cs.stackexchange.com/q/138556/92363.\\n\\n // Does not overflow because the denominator cannot be zero at this stage in the function.\\n uint256 twos = denominator & (~denominator + 1);\\n assembly {\\n // Divide denominator by twos.\\n denominator := div(denominator, twos)\\n\\n // Divide [prod1 prod0] by twos.\\n prod0 := div(prod0, twos)\\n\\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\\n twos := add(div(sub(0, twos), twos), 1)\\n }\\n\\n // Shift in bits from prod1 into prod0.\\n prod0 |= prod1 * twos;\\n\\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\\n // four bits. That is, denominator * inv = 1 mod 2^4.\\n uint256 inverse = (3 * denominator) ^ 2;\\n\\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\\n // in modular arithmetic, doubling the correct bits in each step.\\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\\n\\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inverse;\\n return result;\\n }\\n }\\n\\n /**\\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\\n uint256 result = mulDiv(x, y, denominator);\\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\\n result += 1;\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\\n *\\n * Inspired by Henry S. Warren, Jr.'s \\\"Hacker's Delight\\\" (Chapter 11).\\n */\\n function sqrt(uint256 a) internal pure returns (uint256) {\\n if (a == 0) {\\n return 0;\\n }\\n\\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\\n //\\n // We know that the \\\"msb\\\" (most significant bit) of our target number `a` is a power of 2 such that we have\\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\\n //\\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\\n // \\u2192 `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\\n // \\u2192 `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\\n //\\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\\n uint256 result = 1 << (log2(a) >> 1);\\n\\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\\n // into the expected uint128 result.\\n unchecked {\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n return min(result, a / result);\\n }\\n }\\n\\n /**\\n * @notice Calculates sqrt(a), following the selected rounding direction.\\n */\\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = sqrt(a);\\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 2, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 128;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 64;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 32;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 16;\\n }\\n if (value >> 8 > 0) {\\n value >>= 8;\\n result += 8;\\n }\\n if (value >> 4 > 0) {\\n value >>= 4;\\n result += 4;\\n }\\n if (value >> 2 > 0) {\\n value >>= 2;\\n result += 2;\\n }\\n if (value >> 1 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log2(value);\\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 10, rounded down, of a positive value.\\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 + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 256, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n *\\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\\n */\\n function log256(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 16;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 8;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 4;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 2;\\n }\\n if (value >> 8 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log256(value);\\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe4455ac1eb7fc497bb7402579e7b4d64d928b846fce7d2b6fde06d366f21c2b3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\\n * checks.\\n *\\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\\n * easily result in undesired exploitation or bugs, since developers usually\\n * assume that overflows raise errors. `SafeCast` restores this intuition by\\n * reverting the transaction when such an operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n *\\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\\n * all math on `uint256` and `int256` and then downcasting.\\n */\\nlibrary SafeCast {\\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 * _Available since v4.7._\\n */\\n function toUint248(uint256 value) internal pure returns (uint248) {\\n require(value <= type(uint248).max, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint240(uint256 value) internal pure returns (uint240) {\\n require(value <= type(uint240).max, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint232(uint256 value) internal pure returns (uint232) {\\n require(value <= type(uint232).max, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint224(uint256 value) internal pure returns (uint224) {\\n require(value <= type(uint224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint216(uint256 value) internal pure returns (uint216) {\\n require(value <= type(uint216).max, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint208(uint256 value) internal pure returns (uint208) {\\n require(value <= type(uint208).max, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint200(uint256 value) internal pure returns (uint200) {\\n require(value <= type(uint200).max, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint192(uint256 value) internal pure returns (uint192) {\\n require(value <= type(uint192).max, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint184(uint256 value) internal pure returns (uint184) {\\n require(value <= type(uint184).max, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint176(uint256 value) internal pure returns (uint176) {\\n require(value <= type(uint176).max, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint168(uint256 value) internal pure returns (uint168) {\\n require(value <= type(uint168).max, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint160(uint256 value) internal pure returns (uint160) {\\n require(value <= type(uint160).max, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint152(uint256 value) internal pure returns (uint152) {\\n require(value <= type(uint152).max, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint144(uint256 value) internal pure returns (uint144) {\\n require(value <= type(uint144).max, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint136(uint256 value) internal pure returns (uint136) {\\n require(value <= type(uint136).max, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint128(uint256 value) internal pure returns (uint128) {\\n require(value <= type(uint128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint120(uint256 value) internal pure returns (uint120) {\\n require(value <= type(uint120).max, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint112(uint256 value) internal pure returns (uint112) {\\n require(value <= type(uint112).max, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint104(uint256 value) internal pure returns (uint104) {\\n require(value <= type(uint104).max, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint96(uint256 value) internal pure returns (uint96) {\\n require(value <= type(uint96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint88(uint256 value) internal pure returns (uint88) {\\n require(value <= type(uint88).max, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint80(uint256 value) internal pure returns (uint80) {\\n require(value <= type(uint80).max, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint72(uint256 value) internal pure returns (uint72) {\\n require(value <= type(uint72).max, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint64(uint256 value) internal pure returns (uint64) {\\n require(value <= type(uint64).max, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint56(uint256 value) internal pure returns (uint56) {\\n require(value <= type(uint56).max, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint48(uint256 value) internal pure returns (uint48) {\\n require(value <= type(uint48).max, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint40(uint256 value) internal pure returns (uint40) {\\n require(value <= type(uint40).max, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint32(uint256 value) internal pure returns (uint32) {\\n require(value <= type(uint32).max, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint24(uint256 value) internal pure returns (uint24) {\\n require(value <= type(uint24).max, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint16(uint256 value) internal pure returns (uint16) {\\n require(value <= type(uint16).max, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint8(uint256 value) internal pure returns (uint8) {\\n require(value <= type(uint8).max, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\n */\\n function toUint256(int256 value) internal pure returns (uint256) {\\n require(value >= 0, \\\"SafeCast: value must be positive\\\");\\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 * _Available since v4.7._\\n */\\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\\n downcasted = int248(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\\n downcasted = int240(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\\n downcasted = int232(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\\n downcasted = int224(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\\n downcasted = int216(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\\n downcasted = int208(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\\n downcasted = int200(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\\n downcasted = int192(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\\n downcasted = int184(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\\n downcasted = int176(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\\n downcasted = int168(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\\n downcasted = int160(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\\n downcasted = int152(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\\n downcasted = int144(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\\n downcasted = int136(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\\n downcasted = int128(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\\n downcasted = int120(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\\n downcasted = int112(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\\n downcasted = int104(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\\n downcasted = int96(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\\n downcasted = int88(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\\n downcasted = int80(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\\n downcasted = int72(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\\n downcasted = int64(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\\n downcasted = int56(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\\n downcasted = int48(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\\n downcasted = int40(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\\n downcasted = int32(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\\n downcasted = int24(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\\n downcasted = int16(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\\n downcasted = int8(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\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 require(value <= uint256(type(int256).max), \\\"SafeCast: value doesn't fit in an int256\\\");\\n return int256(value);\\n }\\n}\\n\",\"keccak256\":\"0x52a8cfb0f5239d11b457dcdd1b326992ef672714ca8da71a157255bddd13f3ad\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SignedMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard signed math utilities missing in the Solidity language.\\n */\\nlibrary SignedMath {\\n /**\\n * @dev Returns the largest of two signed numbers.\\n */\\n function max(int256 a, int256 b) internal pure returns (int256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two signed numbers.\\n */\\n function min(int256 a, int256 b) internal pure returns (int256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two signed numbers without overflow.\\n * The result is rounded towards zero.\\n */\\n function average(int256 a, int256 b) internal pure returns (int256) {\\n // Formula from the book \\\"Hacker's Delight\\\"\\n int256 x = (a & b) + ((a ^ b) >> 1);\\n return x + (int256(uint256(x) >> 255) & (a ^ b));\\n }\\n\\n /**\\n * @dev Returns the absolute unsigned value of a signed value.\\n */\\n function abs(int256 n) internal pure returns (uint256) {\\n unchecked {\\n // must be unchecked in order to support `n = type(int256).min`\\n return uint256(n >= 0 ? n : -n);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf92515413956f529d95977adc9b0567d583c6203fc31ab1c23824c35187e3ddc\",\"license\":\"MIT\"},\"contracts/aa-4337/core/BaseAccount.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-empty-blocks */\\n\\nimport \\\"../interfaces/IAccount.sol\\\";\\nimport \\\"../interfaces/IEntryPoint.sol\\\";\\nimport \\\"./Helpers.sol\\\";\\n\\n/**\\n * Basic account implementation.\\n * this contract provides the basic logic for implementing the IAccount interface - validateUserOp\\n * specific account implementation should inherit it and provide the account-specific logic\\n */\\nabstract contract BaseAccount is IAccount {\\n using UserOperationLib for UserOperation;\\n\\n //return value in case of signature failure, with no time-range.\\n // equivalent to _packValidationData(true,0,0);\\n uint256 internal constant SIG_VALIDATION_FAILED = 1;\\n\\n /**\\n * Return the account nonce.\\n * This method returns the next sequential nonce.\\n * For a nonce of a specific key, use `entrypoint.getNonce(account, key)`\\n */\\n function getNonce() public view virtual returns (uint256) {\\n return entryPoint().getNonce(address(this), 0);\\n }\\n\\n /**\\n * return the entryPoint used by this account.\\n * subclass should return the current entryPoint used by this account.\\n */\\n function entryPoint() public view virtual returns (IEntryPoint);\\n\\n /**\\n * Validate user's signature and nonce.\\n * subclass doesn't need to override this method. Instead, it should override the specific internal validation methods.\\n */\\n function validateUserOp(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n uint256 missingAccountFunds\\n ) external virtual override returns (uint256 validationData) {\\n _requireFromEntryPoint();\\n validationData = _validateSignature(userOp, userOpHash);\\n _validateNonce(userOp.nonce);\\n _payPrefund(missingAccountFunds);\\n }\\n\\n /**\\n * ensure the request comes from the known entrypoint.\\n */\\n function _requireFromEntryPoint() internal view virtual {\\n require(\\n msg.sender == address(entryPoint()),\\n \\\"account: not from EntryPoint\\\"\\n );\\n }\\n\\n /**\\n * validate the signature is valid for this message.\\n * @param userOp validate the userOp.signature field\\n * @param userOpHash convenient field: the hash of the request, to check the signature against\\n * (also hashes the entrypoint and chain id)\\n * @return validationData signature and time-range of this operation\\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\\n * otherwise, an address of an \\\"authorizer\\\" contract.\\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \\\"indefinite\\\"\\n * <6-byte> validAfter - first timestamp this operation is valid\\n * If the account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\\n */\\n function _validateSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) internal virtual returns (uint256 validationData);\\n\\n /**\\n * Validate the nonce of the UserOperation.\\n * This method may validate the nonce requirement of this account.\\n * e.g.\\n * To limit the nonce to use sequenced UserOps only (no \\\"out of order\\\" UserOps):\\n * `require(nonce < type(uint64).max)`\\n * For a hypothetical account that *requires* the nonce to be out-of-order:\\n * `require(nonce & type(uint64).max == 0)`\\n *\\n * The actual nonce uniqueness is managed by the EntryPoint, and thus no other\\n * action is needed by the account itself.\\n *\\n * @param nonce to validate\\n *\\n * solhint-disable-next-line no-empty-blocks\\n */\\n function _validateNonce(uint256 nonce) internal view virtual {}\\n\\n /**\\n * sends to the entrypoint (msg.sender) the missing funds for this transaction.\\n * subclass MAY override this method for better funds management\\n * (e.g. send to the entryPoint more than the minimum required, so that in future transactions\\n * it will not be required to send again)\\n * @param missingAccountFunds the minimum value this method should send the entrypoint.\\n * this value MAY be zero, in case there is enough deposit, or the userOp has a paymaster.\\n */\\n function _payPrefund(uint256 missingAccountFunds) internal virtual {\\n if (missingAccountFunds != 0) {\\n (bool success, ) = payable(msg.sender).call{\\n value: missingAccountFunds,\\n gas: type(uint256).max\\n }(\\\"\\\");\\n (success);\\n //ignore failure (its EntryPoint's job to verify, not account.)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa0dcc386b0f04711db3e394fb50e55a3b3b1a4d19fac1f10895844e1aa4e3d5c\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/core/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable no-inline-assembly */\\n\\n/**\\n * returned data from validateUserOp.\\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\\n * @param aggregator - address(0) - the account validated the signature by itself.\\n * address(1) - the account failed to validate the signature.\\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\\n * @param validAfter - this UserOp is valid only after this timestamp.\\n * @param validaUntil - this UserOp is valid only up to this timestamp.\\n */\\nstruct ValidationData {\\n address aggregator;\\n uint48 validAfter;\\n uint48 validUntil;\\n}\\n\\n//extract sigFailed, validAfter, validUntil.\\n// also convert zero validUntil to type(uint48).max\\nfunction _parseValidationData(\\n uint validationData\\n) pure returns (ValidationData memory data) {\\n address aggregator = address(uint160(validationData));\\n uint48 validUntil = uint48(validationData >> 160);\\n if (validUntil == 0) {\\n validUntil = type(uint48).max;\\n }\\n uint48 validAfter = uint48(validationData >> (48 + 160));\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n// intersect account and paymaster ranges.\\nfunction _intersectTimeRange(\\n uint256 validationData,\\n uint256 paymasterValidationData\\n) pure returns (ValidationData memory) {\\n ValidationData memory accountValidationData = _parseValidationData(\\n validationData\\n );\\n ValidationData memory pmValidationData = _parseValidationData(\\n paymasterValidationData\\n );\\n address aggregator = accountValidationData.aggregator;\\n if (aggregator == address(0)) {\\n aggregator = pmValidationData.aggregator;\\n }\\n uint48 validAfter = accountValidationData.validAfter;\\n uint48 validUntil = accountValidationData.validUntil;\\n uint48 pmValidAfter = pmValidationData.validAfter;\\n uint48 pmValidUntil = pmValidationData.validUntil;\\n\\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp\\n * @param data - the ValidationData to pack\\n */\\nfunction _packValidationData(\\n ValidationData memory data\\n) pure returns (uint256) {\\n return\\n uint160(data.aggregator) |\\n (uint256(data.validUntil) << 160) |\\n (uint256(data.validAfter) << (160 + 48));\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp, when not using an aggregator\\n * @param sigFailed - true for signature failure, false for success\\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\\n * @param validAfter first timestamp this UserOperation is valid\\n */\\nfunction _packValidationData(\\n bool sigFailed,\\n uint48 validUntil,\\n uint48 validAfter\\n) pure returns (uint256) {\\n return\\n (sigFailed ? 1 : 0) |\\n (uint256(validUntil) << 160) |\\n (uint256(validAfter) << (160 + 48));\\n}\\n\\n/**\\n * keccak function over calldata.\\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\\n */\\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\\n assembly {\\n let mem := mload(0x40)\\n let len := data.length\\n calldatacopy(mem, data.offset, len)\\n ret := keccak256(mem, len)\\n }\\n}\\n\",\"keccak256\":\"0xa79f06cd158ecb8c0da95493a2f348933b8627a63e228b99738bff3aa107942d\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAccount.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\ninterface IAccount {\\n /**\\n * Validate user's signature and nonce\\n * the entryPoint will make the call to the recipient only if this validation call returns successfully.\\n * signature failure should be reported by returning SIG_VALIDATION_FAILED (1).\\n * This allows making a \\\"simulation call\\\" without a valid signature\\n * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure.\\n *\\n * @dev Must validate caller is the entryPoint.\\n * Must validate the signature and nonce\\n * @param userOp the operation that is about to be executed.\\n * @param userOpHash hash of the user's request data. can be used as the basis for signature.\\n * @param missingAccountFunds missing funds on the account's deposit in the entrypoint.\\n * This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call.\\n * The excess is left as a deposit in the entrypoint, for future calls.\\n * can be withdrawn anytime using \\\"entryPoint.withdrawTo()\\\"\\n * In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero.\\n * @return validationData packaged ValidationData structure. use `_packValidationData` and `_unpackValidationData` to encode and decode\\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\\n * otherwise, an address of an \\\"authorizer\\\" contract.\\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \\\"indefinite\\\"\\n * <6-byte> validAfter - first timestamp this operation is valid\\n * If an account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\\n */\\n function validateUserOp(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n uint256 missingAccountFunds\\n ) external returns (uint256 validationData);\\n}\\n\",\"keccak256\":\"0xcbc4b0973cf954c5895b7796335f651fbfcfb55f67dfa789a3d354f8e23c4f2b\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAggregator.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\n/**\\n * Aggregated Signatures validator.\\n */\\ninterface IAggregator {\\n /**\\n * validate aggregated signature.\\n * revert if the aggregated signature does not match the given list of operations.\\n */\\n function validateSignatures(\\n UserOperation[] calldata userOps,\\n bytes calldata signature\\n ) external view;\\n\\n /**\\n * validate signature of a single userOp\\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\\n * @param userOp the userOperation received from the user.\\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\\n * (usually empty, unless account and aggregator support some kind of \\\"multisig\\\"\\n */\\n function validateUserOpSignature(\\n UserOperation calldata userOp\\n ) external view returns (bytes memory sigForUserOp);\\n\\n /**\\n * aggregate multiple signatures into a single value.\\n * This method is called off-chain to calculate the signature to pass with handleOps()\\n * bundler MAY use optimized custom code perform this aggregation\\n * @param userOps array of UserOperations to collect the signatures from.\\n * @return aggregatedSignature the aggregated signature\\n */\\n function aggregateSignatures(\\n UserOperation[] calldata userOps\\n ) external view returns (bytes memory aggregatedSignature);\\n}\\n\",\"keccak256\":\"0xdfdcd80568f037716674619b31be630fcd8316262f05a815b41d1e81782c966a\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IEntryPoint.sol\":{\"content\":\"/**\\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\\n ** Only one instance required on each chain.\\n **/\\n// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-inline-assembly */\\n/* solhint-disable reason-string */\\n\\nimport \\\"./UserOperation.sol\\\";\\nimport \\\"./IStakeManager.sol\\\";\\nimport \\\"./IAggregator.sol\\\";\\nimport \\\"./INonceManager.sol\\\";\\n\\ninterface IEntryPoint is IStakeManager, INonceManager {\\n /***\\n * An event emitted after each successful request\\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\\n * @param sender - the account that generates this request.\\n * @param paymaster - if non-null, the paymaster that pays for this request.\\n * @param nonce - the nonce value from the request.\\n * @param success - true if the sender transaction succeeded, false if reverted.\\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\\n */\\n event UserOperationEvent(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address indexed paymaster,\\n uint256 nonce,\\n bool success,\\n uint256 actualGasCost,\\n uint256 actualGasUsed\\n );\\n\\n /**\\n * account \\\"sender\\\" was deployed.\\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\\n * @param sender the account that is deployed\\n * @param factory the factory used to deploy this account (in the initCode)\\n * @param paymaster the paymaster used by this UserOp\\n */\\n event AccountDeployed(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address factory,\\n address paymaster\\n );\\n\\n /**\\n * An event emitted if the UserOperation \\\"callData\\\" reverted with non-zero length\\n * @param userOpHash the request unique identifier.\\n * @param sender the sender of this request\\n * @param nonce the nonce used in the request\\n * @param revertReason - the return bytes from the (reverted) call to \\\"callData\\\".\\n */\\n event UserOperationRevertReason(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n uint256 nonce,\\n bytes revertReason\\n );\\n\\n /**\\n * an event emitted by handleOps(), before starting the execution loop.\\n * any event emitted before this event, is part of the validation.\\n */\\n event BeforeExecution();\\n\\n /**\\n * signature aggregator used by the following UserOperationEvents within this bundle.\\n */\\n event SignatureAggregatorChanged(address indexed aggregator);\\n\\n /**\\n * a custom revert error of handleOps, to identify the offending op.\\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\\n * @param reason - revert reason\\n * The string starts with a unique code \\\"AAmn\\\", where \\\"m\\\" is \\\"1\\\" for factory, \\\"2\\\" for account and \\\"3\\\" for paymaster issues,\\n * so a failure can be attributed to the correct entity.\\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\\n */\\n error FailedOp(uint256 opIndex, string reason);\\n\\n /**\\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\\n */\\n error SignatureValidationFailed(address aggregator);\\n\\n /**\\n * Successful result from simulateValidation.\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n */\\n error ValidationResult(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo\\n );\\n\\n /**\\n * Successful result from simulateValidation, if the account returns a signature aggregator\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\\n * bundler MUST use it to verify the signature, or reject the UserOperation\\n */\\n error ValidationResultWithAggregation(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo,\\n AggregatorStakeInfo aggregatorInfo\\n );\\n\\n /**\\n * return value of getSenderAddress\\n */\\n error SenderAddressResult(address sender);\\n\\n /**\\n * return value of simulateHandleOp\\n */\\n error ExecutionResult(\\n uint256 preOpGas,\\n uint256 paid,\\n uint48 validAfter,\\n uint48 validUntil,\\n bool targetSuccess,\\n bytes targetResult\\n );\\n\\n //UserOps handled, per aggregator\\n struct UserOpsPerAggregator {\\n UserOperation[] userOps;\\n // aggregator address\\n IAggregator aggregator;\\n // aggregated signature\\n bytes signature;\\n }\\n\\n /**\\n * Execute a batch of UserOperation.\\n * no signature aggregator is used.\\n * if any account requires an aggregator (that is, it returned an aggregator when\\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\\n * @param ops the operations to execute\\n * @param beneficiary the address to receive the fees\\n */\\n function handleOps(\\n UserOperation[] calldata ops,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * Execute a batch of UserOperation with Aggregators\\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\\n * @param beneficiary the address to receive the fees\\n */\\n function handleAggregatedOps(\\n UserOpsPerAggregator[] calldata opsPerAggregator,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * generate a request Id - unique identifier for this request.\\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\\n */\\n function getUserOpHash(\\n UserOperation calldata userOp\\n ) external view returns (bytes32);\\n\\n /**\\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\\n * @param userOp the user operation to validate.\\n */\\n function simulateValidation(UserOperation calldata userOp) external;\\n\\n /**\\n * gas and return values during simulation\\n * @param preOpGas the gas used for validation (including preValidationGas)\\n * @param prefund the required prefund for this operation\\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\\n */\\n struct ReturnInfo {\\n uint256 preOpGas;\\n uint256 prefund;\\n bool sigFailed;\\n uint48 validAfter;\\n uint48 validUntil;\\n bytes paymasterContext;\\n }\\n\\n /**\\n * returned aggregated signature info.\\n * the aggregator returned by the account, and its current stake.\\n */\\n struct AggregatorStakeInfo {\\n address aggregator;\\n StakeInfo stakeInfo;\\n }\\n\\n /**\\n * Get counterfactual sender address.\\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\\n * this method always revert, and returns the address in SenderAddressResult error\\n * @param initCode the constructor code to be passed into the UserOperation.\\n */\\n function getSenderAddress(bytes memory initCode) external;\\n\\n /**\\n * simulate full execution of a UserOperation (including both validation and target execution)\\n * this method will always revert with \\\"ExecutionResult\\\".\\n * it performs full validation of the UserOperation, but ignores signature error.\\n * an optional target address is called after the userop succeeds, and its value is returned\\n * (before the entire call is reverted)\\n * Note that in order to collect the the success/failure of the target call, it must be executed\\n * with trace enabled to track the emitted events.\\n * @param op the UserOperation to simulate\\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\\n * are set to the return from that call.\\n * @param targetCallData callData to pass to target address\\n */\\n function simulateHandleOp(\\n UserOperation calldata op,\\n address target,\\n bytes calldata targetCallData\\n ) external;\\n}\\n\",\"keccak256\":\"0x9ccb1b188eda8bbf5f6c2d01bd83c3d8b2b04fcf745283051d31fe96d1d8e40f\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/INonceManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\ninterface INonceManager {\\n /**\\n * Return the next nonce for this sender.\\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\\n * But UserOp with different keys can come with arbitrary order.\\n *\\n * @param sender the account address\\n * @param key the high 192 bit of the nonce\\n * @return nonce a full nonce to pass for next UserOp with this sender.\\n */\\n function getNonce(\\n address sender,\\n uint192 key\\n ) external view returns (uint256 nonce);\\n\\n /**\\n * Manually increment the nonce of the sender.\\n * This method is exposed just for completeness..\\n * Account does NOT need to call it, neither during validation, nor elsewhere,\\n * as the EntryPoint will update the nonce regardless.\\n * Possible use-case is call it with various keys to \\\"initialize\\\" their nonces to one, so that future\\n * UserOperations will not pay extra for the first transaction with a given key.\\n */\\n function incrementNonce(uint192 key) external;\\n}\\n\",\"keccak256\":\"0xce478ad0fa0d18a3b785ac854623029e7ab463d05873dfaa365abfa1bf100912\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IStakeManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8.12;\\n\\n/**\\n * manage deposits and stakes.\\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\\n * stake is value locked for at least \\\"unstakeDelay\\\" by the staked entity.\\n */\\ninterface IStakeManager {\\n event Deposited(address indexed account, uint256 totalDeposit);\\n\\n event Withdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /// Emitted when stake or unstake delay are modified\\n event StakeLocked(\\n address indexed account,\\n uint256 totalStaked,\\n uint256 unstakeDelaySec\\n );\\n\\n /// Emitted once a stake is scheduled for withdrawal\\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\\n\\n event StakeWithdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /**\\n * @param deposit the entity's deposit\\n * @param staked true if this entity is staked.\\n * @param stake actual amount of ether staked for this entity.\\n * @param unstakeDelaySec minimum delay to withdraw the stake.\\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\\n * and the rest fit into a 2nd cell.\\n * 112 bit allows for 10^15 eth\\n * 48 bit for full timestamp\\n * 32 bit allows 150 years for unstake delay\\n */\\n struct DepositInfo {\\n uint112 deposit;\\n bool staked;\\n uint112 stake;\\n uint32 unstakeDelaySec;\\n uint48 withdrawTime;\\n }\\n\\n //API struct used by getStakeInfo and simulateValidation\\n struct StakeInfo {\\n uint256 stake;\\n uint256 unstakeDelaySec;\\n }\\n\\n /// @return info - full deposit information of given account\\n function getDepositInfo(\\n address account\\n ) external view returns (DepositInfo memory info);\\n\\n /// @return the deposit (for gas payment) of the account\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * add to the deposit of the given account\\n */\\n function depositTo(address account) external payable;\\n\\n /**\\n * add to the account's stake - amount and delay\\n * any pending unstake is first cancelled.\\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\\n */\\n function addStake(uint32 _unstakeDelaySec) external payable;\\n\\n /**\\n * attempt to unlock the stake.\\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\\n */\\n function unlockStake() external;\\n\\n /**\\n * withdraw from the (unlocked) stake.\\n * must first call unlockStake and wait for the unstakeDelay to pass\\n * @param withdrawAddress the address to send withdrawn value.\\n */\\n function withdrawStake(address payable withdrawAddress) external;\\n\\n /**\\n * withdraw from the deposit.\\n * @param withdrawAddress the address to send withdrawn value.\\n * @param withdrawAmount the amount to withdraw.\\n */\\n function withdrawTo(\\n address payable withdrawAddress,\\n uint256 withdrawAmount\\n ) external;\\n}\\n\",\"keccak256\":\"0xadcea606c9b7aafe6645441f2154a60f271330b0eee5292a632aa71c1672d546\",\"license\":\"GPL-3.0-only\"},\"contracts/aa-4337/interfaces/UserOperation.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable no-inline-assembly */\\n\\nimport {calldataKeccak} from \\\"../core/Helpers.sol\\\";\\n\\n/**\\n * User Operation struct\\n * @param sender the sender account of this request.\\n * @param nonce unique value the sender uses to verify it is not a replay.\\n * @param initCode if set, the account contract will be created by this constructor/\\n * @param callData the method call to execute on this account.\\n * @param callGasLimit the gas limit passed to the callData method call.\\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\\n * @param maxFeePerGas same as EIP-1559 gas parameter.\\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\\n */\\nstruct UserOperation {\\n address sender;\\n uint256 nonce;\\n bytes initCode;\\n bytes callData;\\n uint256 callGasLimit;\\n uint256 verificationGasLimit;\\n uint256 preVerificationGas;\\n uint256 maxFeePerGas;\\n uint256 maxPriorityFeePerGas;\\n bytes paymasterAndData;\\n bytes signature;\\n}\\n\\n/**\\n * Utility functions helpful when working with UserOperation structs.\\n */\\nlibrary UserOperationLib {\\n function getSender(\\n UserOperation calldata userOp\\n ) internal pure returns (address) {\\n address data;\\n //read sender from userOp, which is first userOp member (saves 800 gas...)\\n assembly {\\n data := calldataload(userOp)\\n }\\n return address(uint160(data));\\n }\\n\\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\\n // pay above what he signed for.\\n function gasPrice(\\n UserOperation calldata userOp\\n ) internal view returns (uint256) {\\n unchecked {\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n if (maxFeePerGas == maxPriorityFeePerGas) {\\n //legacy mode (for networks that don't support basefee opcode)\\n return maxFeePerGas;\\n }\\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\\n }\\n }\\n\\n function pack(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes memory ret) {\\n address sender = getSender(userOp);\\n uint256 nonce = userOp.nonce;\\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\\n bytes32 hashCallData = calldataKeccak(userOp.callData);\\n uint256 callGasLimit = userOp.callGasLimit;\\n uint256 verificationGasLimit = userOp.verificationGasLimit;\\n uint256 preVerificationGas = userOp.preVerificationGas;\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\\n\\n return\\n abi.encode(\\n sender,\\n nonce,\\n hashInitCode,\\n hashCallData,\\n callGasLimit,\\n verificationGasLimit,\\n preVerificationGas,\\n maxFeePerGas,\\n maxPriorityFeePerGas,\\n hashPaymasterAndData\\n );\\n }\\n\\n function hash(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes32) {\\n return keccak256(pack(userOp));\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n}\\n\",\"keccak256\":\"0x2429f5cc546bdee08c7e63858d0dda8491eaa3ab5194df884dc948c1154d2834\",\"license\":\"GPL-3.0\"},\"contracts/facets/AccountFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {ECDSA} from \\\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\\\";\\nimport {UserOperation} from \\\"../aa-4337/interfaces/UserOperation.sol\\\";\\nimport {IEntryPoint} from \\\"../aa-4337/interfaces/IEntryPoint.sol\\\";\\nimport {BaseAccount} from \\\"../aa-4337/core/BaseAccount.sol\\\";\\nimport {LibAppStorage, BarzStorage} from \\\"../libraries/LibAppStorage.sol\\\";\\nimport {LibDiamond} from \\\"../libraries/LibDiamond.sol\\\";\\nimport {LibLoupe} from \\\"../libraries/LibLoupe.sol\\\";\\nimport {IFacetRegistry} from \\\"../infrastructure/interfaces/IFacetRegistry.sol\\\";\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\nimport {IVerificationFacet} from \\\"./interfaces/IVerificationFacet.sol\\\";\\nimport {IERC1271} from \\\"../interfaces/ERC/IERC1271.sol\\\";\\nimport {IAccountFacet} from \\\"./interfaces/IAccountFacet.sol\\\";\\n\\n/**\\n * @title Account Facet\\n * @dev Account module contract that provides the account features and initialization of signer\\n * compatible with EIP-1271 & EIP-4337\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract AccountFacet is IAccountFacet, BarzStorage, BaseAccount {\\n using ECDSA for bytes32;\\n\\n /**\\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\\n */\\n constructor() {\\n LibAppStorage.enforceAccountInitialize();\\n }\\n\\n /**\\n * @notice Returns the address of EntryPoint contract registered to Barz account\\n */\\n function entryPoint() public view override returns (IEntryPoint) {\\n return s.entryPoint;\\n }\\n\\n /**\\n * @notice Initializes the initial storage of the Barz contract.\\n * @dev This method can only be called during the initialization or signature migration.\\n * If the proxy contract was created without initialization, anyone can call initialize.\\n * Barz calls initialize in constructor in an atomic transaction during deployment\\n * @param _verificationFacet Facet contract handling the verificationi\\n * @param _anEntryPoint Entrypoint contract defined in EIP-4337 handling the flow of UserOp\\n * @param _facetRegistry Registry of Facets that hold all facet information\\n * @param _defaultFallBackHandler Middleware contract for default facets\\n * @param _ownerPublicKey Bytes of owner public key\\n */\\n function initialize(\\n address _verificationFacet,\\n address _anEntryPoint,\\n address _facetRegistry,\\n address _defaultFallBackHandler,\\n bytes calldata _ownerPublicKey\\n ) public override returns (uint256 initSuccess) {\\n LibAppStorage.enforceAccountInitialize();\\n s.entryPoint = IEntryPoint(_anEntryPoint);\\n s.facetRegistry = IFacetRegistry(_facetRegistry);\\n LibDiamond.diamondStorage().defaultFallbackHandler = IDiamondLoupe(\\n _defaultFallBackHandler\\n );\\n\\n _cutDiamondAccountFacet(_verificationFacet);\\n\\n bytes memory initCall = abi.encodeWithSignature(\\n \\\"initializeSigner(bytes)\\\",\\n _ownerPublicKey\\n );\\n // Every Verification Facet should comply with initializeSigner(bytes)\\n // to be compatible with the Barz contract(for initialization)\\n (bool success, bytes memory result) = _verificationFacet.delegatecall(\\n initCall\\n );\\n if (!success || uint256(bytes32(result)) != 1) {\\n revert AccountFacet__InitializationFailure();\\n }\\n\\n initSuccess = 1;\\n emit AccountInitialized(s.entryPoint, _ownerPublicKey);\\n }\\n\\n function _cutDiamondAccountFacet(address _verificationFacet) internal {\\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](1);\\n\\n bytes4 ownerVerificationFuncSelector = IVerificationFacet(\\n _verificationFacet\\n ).validateOwnerSignatureSelector();\\n\\n bytes4[] memory verificationFunctionSelectors = new bytes4[](3);\\n verificationFunctionSelectors[0] = IERC1271.isValidSignature.selector;\\n verificationFunctionSelectors[1] = ownerVerificationFuncSelector;\\n verificationFunctionSelectors[2] = IVerificationFacet.owner.selector;\\n cut[0] = IDiamondCut.FacetCut({\\n facetAddress: _verificationFacet,\\n action: IDiamondCut.FacetCutAction.Add,\\n functionSelectors: verificationFunctionSelectors\\n });\\n\\n LibDiamond.diamondCut(cut, address(0), \\\"\\\");\\n }\\n\\n /**\\n * @notice Calls the destination with inputted calldata and value from EntryPoint\\n * @dev This method executes the calldata coming from the EntryPoint.\\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\\n * @param _dest Address of destination where the call will be forwarded to\\n * @param _value Amount of native coin the owner is willing to send(e.g. ETH, BNB)\\n * @param _func Bytes of calldata to execute in the destination address\\n */\\n function execute(\\n address _dest,\\n uint256 _value,\\n bytes calldata _func\\n ) external override onlyWhenUnlocked {\\n _requireFromEntryPoint();\\n address restrictionsFacet = LibDiamond.restrictionsFacet();\\n if (restrictionsFacet == address(0)) _call(_dest, _value, _func);\\n else _callWithRestrictions(_dest, _value, _func, restrictionsFacet);\\n }\\n\\n /**\\n * @notice Batch calls the destination with inputted calldata and value from EntryPoint\\n * @dev This method batch executes the calldata coming from the EntryPoint.\\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\\n * @param _dest Array of addresses of destination where the call will be forwarded to\\n * @param _value Array of amount of native coin the owner is willing to send(e.g. ETH, BNB)\\n * @param _func Array of bytes of calldata to execute in the destination address\\n */\\n function executeBatch(\\n address[] calldata _dest,\\n uint256[] calldata _value,\\n bytes[] calldata _func\\n ) external override onlyWhenUnlocked {\\n _requireFromEntryPoint();\\n if (_dest.length != _func.length || _dest.length != _value.length)\\n revert AccountFacet__InvalidArrayLength();\\n address restrictionsFacet = LibDiamond.restrictionsFacet();\\n if (restrictionsFacet == address(0)) {\\n for (uint256 i; i < _dest.length; ) {\\n _call(_dest[i], _value[i], _func[i]);\\n unchecked {\\n ++i;\\n }\\n }\\n } else {\\n for (uint256 i; i < _dest.length; ) {\\n _callWithRestrictions(\\n _dest[i],\\n _value[i],\\n _func[i],\\n restrictionsFacet\\n );\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n }\\n\\n /**\\n * @notice Validates the signature field of UserOperation\\n * @dev This method validates if the signature of UserOp is indeed valid by delegating the call to Verification Facet\\n * Barz makes a call to the pre-registered Verification Facet address in App Storage\\n * @param _userOp UserOperation from owner to be validated\\n * @param _userOpHash Hash of UserOperation given from the EntryPoint contract\\n */\\n function _validateSignature(\\n UserOperation calldata _userOp,\\n bytes32 _userOpHash\\n ) internal override returns (uint256 validationData) {\\n // Get Facet with Function Selector\\n address facet = LibLoupe.facetAddress(s.validateOwnerSignatureSelector);\\n if (facet == address(0))\\n revert AccountFacet__NonExistentVerificationFacet();\\n\\n // Make function call to VerificationFacet\\n bytes memory validateCall = abi.encodeWithSelector(\\n s.validateOwnerSignatureSelector,\\n _userOp,\\n _userOpHash\\n );\\n (bool success, bytes memory result) = facet.delegatecall(validateCall);\\n if (!success) revert AccountFacet__CallNotSuccessful();\\n validationData = uint256(bytes32(result));\\n if (validationData == 0) emit VerificationSuccess(_userOpHash);\\n else emit VerificationFailure(_userOpHash);\\n }\\n\\n /**\\n * @notice Calls the target with the inputted value and calldata\\n * @dev This method is the actual function in Barz that makes a call with an arbitrary owner-given data\\n * @param _target Address of the destination contract which the call is getting forwarded to\\n * @param _value Amount of Native coin the owner is wanting to make in this call\\n * @param _data Calldata the owner is forwarding together in the call e.g. Swap/Token Transfer\\n */\\n function _call(\\n address _target,\\n uint256 _value,\\n bytes memory _data\\n ) internal {\\n (bool success, bytes memory result) = _target.call{value: _value}(\\n _data\\n );\\n if (!success) {\\n assembly {\\n revert(add(result, 32), mload(result))\\n }\\n }\\n }\\n\\n /**\\n * @notice Calls the target with the inputted value and calldata together with restrictions check\\n * @dev This method is the actual function in Barz that makes a call with an arbitrary owner-given data\\n * @param _target Address of the destination contract which the call is getting forwarded to\\n * @param _value Amount of Native coin the owner is wanting to make in this call\\n * @param _data Calldata the owner is forwarding together in the call e.g. Swap/Token Transfer\\n * @param _restrictionsFacet Address of Facet to validate restrictions\\n */\\n function _callWithRestrictions(\\n address _target,\\n uint256 _value,\\n bytes memory _data,\\n address _restrictionsFacet\\n ) internal {\\n // NOTE: No restrictions facet, so restriction validation passes\\n if (_checkRestrictions(_restrictionsFacet, _target, _value, _data) != 0)\\n revert AccountFacet__RestrictionsFailure();\\n\\n (bool success, bytes memory result) = _target.call{value: _value}(\\n _data\\n );\\n if (!success) {\\n assembly {\\n revert(add(result, 32), mload(result))\\n }\\n }\\n }\\n\\n /**\\n * @notice Checks restrictions if the restrictions facet exists\\n * @dev This method checks if the restrictions facet exists and makes a verification call to an array of restrictions facet\\n * @param _facet Address that holds the restrictions logic\\n * @param _target Address the call is getting forwarded to\\n * @param _value Amount of native coin the call is sending together with the call\\n * @param _data Calldata to trigger execution in target address\\n */\\n function _checkRestrictions(\\n address _facet,\\n address _target,\\n uint256 _value,\\n bytes memory _data\\n ) internal returns (uint256 result) {\\n bytes memory call = abi.encodeWithSignature(\\n \\\"verifyRestrictions(address,address,uint256,bytes)\\\",\\n address(this),\\n _target,\\n _value,\\n _data\\n );\\n (bool success, bytes memory response) = _facet.delegatecall(call);\\n if (!success) revert AccountFacet__RestrictionsFailure();\\n result = uint256(bytes32(response));\\n }\\n}\\n\",\"keccak256\":\"0xcd92bcdd447010880f78e57e213123269c9e023adfc0a540608daa127d8649ca\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/facets/interfaces/IAccountFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IEntryPoint} from \\\"../../aa-4337/interfaces/IEntryPoint.sol\\\";\\n\\n/**\\n * @title Account Facet Interface\\n * @dev Interface of module contract that provides the account features and init/unitialization of signer\\n * compatible with EIP-1271 & EIP-4337\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IAccountFacet {\\n event AccountInitialized(\\n IEntryPoint indexed entryPoint,\\n bytes indexed ownerPublicKey\\n );\\n // NOTE: Added Below Event\\n event VerificationSuccess(bytes32);\\n event VerificationFailure(bytes32);\\n\\n error AccountFacet__InitializationFailure();\\n error AccountFacet__RestrictionsFailure();\\n error AccountFacet__NonExistentVerificationFacet();\\n error AccountFacet__CallNotSuccessful();\\n error AccountFacet__InvalidArrayLength();\\n\\n function initialize(\\n address verificationFacet,\\n address anEntryPoint,\\n address facetRegistry,\\n address _defaultFallBack,\\n bytes calldata _ownerPublicKey\\n ) external returns (uint256);\\n\\n function execute(address dest, uint256 value, bytes calldata func) external;\\n\\n function executeBatch(\\n address[] calldata dest,\\n uint256[] calldata value,\\n bytes[] calldata func\\n ) external;\\n}\\n\",\"keccak256\":\"0x74a9cb0b8f2f4a5148e366a401a0354426c536c012c025025d07cc25a4cd5382\",\"license\":\"Apache-2.0\"},\"contracts/facets/interfaces/IVerificationFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {UserOperation} from \\\"../../aa-4337/interfaces/UserOperation.sol\\\";\\n\\n/**\\n * @title Verification Facet Interface\\n * @dev Implements logic for user ops signature verification\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\ninterface IVerificationFacet {\\n event SignerInitialized(bytes);\\n event SignerUninitialized();\\n\\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\\n error VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\\n error VerificationFacet__InitializationFailure();\\n error VerificationFacet__InvalidFacetMapping();\\n\\n function initializeSigner(bytes memory) external returns (uint256);\\n\\n function uninitializeSigner() external returns (uint256);\\n\\n function validateOwnerSignatureSelector() external view returns (bytes4);\\n\\n function owner() external view returns (bytes memory);\\n\\n function isValidKeyType(bytes calldata) external view returns (bool);\\n\\n function validateOwnerSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x72bc370a1d1b5a6d6bde67f5026733fd8f6ba434bb90e73b0bd8627fb1579928\",\"license\":\"Apache-2.0\"},\"contracts/infrastructure/interfaces/IFacetRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Registry Interface\\n * @dev Interface for Facet Registry contract to keep track of facets & function selectors addable to user wallets\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IFacetRegistry {\\n struct FacetRegistryConfig {\\n bytes4[] selectors;\\n mapping(bytes4 => FacetInfo) info;\\n }\\n struct FacetInfo {\\n bool exists;\\n uint128 index;\\n }\\n\\n event FacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] facetSelectors\\n );\\n event FacetFunctionSelectorsRemoved(address facet, bytes4[] facetSelectors);\\n\\n error FacetRegistry__FacetSelectorAlreadyRegistered();\\n error FacetRegistry__UnregisteredFacetSelector();\\n\\n function registerFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function removeFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function areFacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external view returns (bool);\\n\\n function isFacetFunctionSelectorRegistered(\\n address facet,\\n bytes4 facetSelector\\n ) external view returns (bool);\\n\\n function getFacetFunctionSelectors(\\n address facet\\n ) external view returns (bytes4[] memory);\\n}\\n\",\"keccak256\":\"0x6e6dd2cab346ef7c31230740ec48d2925e4a9ab24c2f2fb268baaf408dcf02ef\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC1271 {\\n function isValidSignature(\\n bytes32 hash,\\n bytes memory signature\\n ) external view returns (bytes4);\\n}\\n\",\"keccak256\":\"0xcdddb7d5641c9d3f2432dec7fd13fddb9ae1480f25c76c21511e2fa16b8bd422\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibAppStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {SafeCast} from \\\"@openzeppelin/contracts/utils/math/SafeCast.sol\\\";\\nimport {IEntryPoint} from \\\"../aa-4337/interfaces/IEntryPoint.sol\\\";\\nimport {IFacetRegistry} from \\\"../infrastructure/interfaces/IFacetRegistry.sol\\\";\\n\\n/*\\n * @title App Storage\\n * @dev App storage for Barz contract to prevent storage collision\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Lock {\\n uint64 release;\\n bytes4 locker;\\n}\\n\\nstruct InitializersStorage {\\n // NOTE: initialized is a variable to make sure the initialization is only done once.\\n uint8 signerInitialized;\\n uint8 accountInitialized;\\n uint8 restrictionsInitialized;\\n}\\n\\nstruct AppStorage {\\n mapping(uint256 => InitializersStorage) initStorage;\\n uint8 signerMigration;\\n bytes4 validateOwnerSignatureSelector;\\n IEntryPoint entryPoint;\\n IFacetRegistry facetRegistry;\\n mapping(uint256 => Lock) locks;\\n}\\n\\nlibrary LibAppStorage {\\n error LibAppStorage__AccountAlreadyUninitialized();\\n error LibAppStorage__AccountMustBeUninitialized();\\n error LibAppStorage__SignerAlreadyUninitialized();\\n error LibAppStorage__SignerMustBeUninitialized();\\n\\n function appStorage() internal pure returns (AppStorage storage ds) {\\n assembly {\\n ds.slot := 0\\n }\\n }\\n\\n function setSignerUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerAlreadyUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 0;\\n }\\n\\n function getValidateOwnerSignatureSelector()\\n internal\\n view\\n returns (bytes4 selector)\\n {\\n selector = appStorage().validateOwnerSignatureSelector;\\n }\\n\\n function setValidateOwnerSignatureSelector(\\n bytes4 _validateOwnerSignatureSelector\\n ) internal {\\n appStorage()\\n .validateOwnerSignatureSelector = _validateOwnerSignatureSelector;\\n }\\n\\n function enforceSignerInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerMustBeUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 1;\\n }\\n\\n function enforceAccountInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].accountInitialized) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n s.initStorage[0].accountInitialized = 1;\\n }\\n\\n function initiateSignerMigration() internal {\\n appStorage().signerMigration = 1;\\n }\\n\\n function enforceSignerMigration() internal view {\\n if (1 != appStorage().signerMigration) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n }\\n\\n function finalizeSignerMigration() internal {\\n appStorage().signerMigration = 0;\\n }\\n\\n function setLock(uint256 _releaseAfter, bytes4 _locker) internal {\\n appStorage().locks[0] = Lock(SafeCast.toUint64(_releaseAfter), _locker);\\n }\\n\\n function enforceRestrictionsInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__SignerMustBeUninitialized();\\n s.initStorage[0].restrictionsInitialized = 1;\\n }\\n\\n function setRestrictionsUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__AccountAlreadyUninitialized();\\n s.initStorage[0].restrictionsInitialized = 0;\\n }\\n}\\n\\ncontract BarzStorage {\\n AppStorage internal s;\\n modifier onlyWhenUnlocked() {\\n require(\\n uint64(block.timestamp) >= s.locks[0].release,\\n \\\"Account Locked\\\"\\n );\\n _;\\n }\\n modifier onlyWhenLocked() {\\n require(\\n uint64(block.timestamp) < s.locks[0].release,\\n \\\"Account Unlocked\\\"\\n );\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x48524007862a6ce0e07f645950613ce6513ce073c37a109c75019683d42bae27\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\\n bytes4(keccak256(\\\"verifyRestrictions(address,address,uint256,bytes)\\\"));\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // Default Fallback Handler of the barz.\\n IDiamondLoupe defaultFallbackHandler;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function enforceIsSelf() internal view {\\n require(msg.sender == address(this), \\\"LibDiamond: Caller not self\\\");\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n\\n unchecked {\\n facetIndex++;\\n }\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n\\n function restrictionsFacet() internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(\\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2cabdc00de859c3a3170ce3bda5d0e5fd3933d47ce904fd1585f9818b02572f8\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\nimport {LibDiamond} from \\\"./LibDiamond.sol\\\";\\n\\n/**\\n * @title LibLoupe\\n * @dev Internal Library to provide utility feature for reading the state of diamond facets\\n * Originally from Diamond's implementation of Mudgen(author of EIP-2535)\\n */\\nlibrary LibLoupe {\\n /// @notice Gets all facets and their selectors.\\n /// @return facets_ Facet\\n function facets()\\n internal\\n view\\n returns (IDiamondLoupe.Facet[] memory facets_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facets_ = new IDiamondLoupe.Facet[](ds.selectorCount);\\n uint16[] memory numFacetSelectors = new uint16[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facets_[facetIndex].facetAddress == facetAddress_) {\\n facets_[facetIndex].functionSelectors[\\n numFacetSelectors[facetIndex]\\n ] = selector;\\n // probably will never have more than 256 functions from one facet contract\\n require(numFacetSelectors[facetIndex] < 255);\\n numFacetSelectors[facetIndex]++;\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facets_[numFacets].facetAddress = facetAddress_;\\n facets_[numFacets].functionSelectors = new bytes4[](\\n ds.selectorCount\\n );\\n facets_[numFacets].functionSelectors[0] = selector;\\n numFacetSelectors[numFacets] = 1;\\n numFacets++;\\n }\\n }\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n uint256 numSelectors = numFacetSelectors[facetIndex];\\n bytes4[] memory selectors = facets_[facetIndex].functionSelectors;\\n // setting the number of selectors\\n assembly {\\n mstore(selectors, numSelectors)\\n }\\n }\\n // setting the number of facets\\n assembly {\\n mstore(facets_, numFacets)\\n }\\n }\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return _facetFunctionSelectors The selectors associated with a facet address.\\n function facetFunctionSelectors(\\n address _facet\\n ) internal view returns (bytes4[] memory _facetFunctionSelectors) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n uint256 numSelectors;\\n _facetFunctionSelectors = new bytes4[](ds.selectorCount);\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facet = address(bytes20(ds.facets[selector]));\\n if (_facet == facet) {\\n _facetFunctionSelectors[numSelectors] = selector;\\n numSelectors++;\\n }\\n }\\n }\\n // Set the number of selectors in the array\\n assembly {\\n mstore(_facetFunctionSelectors, numSelectors)\\n }\\n }\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n internal\\n view\\n returns (address[] memory facetAddresses_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetAddresses_ = new address[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facetAddress_ == facetAddresses_[facetIndex]) {\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facetAddresses_[numFacets] = facetAddress_;\\n numFacets++;\\n }\\n }\\n // Set the number of facet addresses in the array\\n assembly {\\n mstore(facetAddresses_, numFacets)\\n }\\n }\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(LibDiamond.diamondStorage().facets[_functionSelector])\\n );\\n }\\n}\\n\",\"keccak256\":\"0x0b11439c3cc657095e15ec2241fdcf67204b14001357b612fc5db4ff9e760a5a\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5061001961001e565b61008e565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb554610100900460ff1615610070576040516338fc28cb60e01b815260040160405180910390fd5b600080805260209190915260409020805461ff001916610100179055565b6129b6806200009e6000396000f3fe608060405234801561001057600080fd5b50600436106100725760003560e01c8063b0d691fe11610050578063b0d691fe146100c5578063b61d27f61461010c578063d087d2881461011f57600080fd5b80633a871cdd1461007757806347e1da2a1461009d5780634a936417146100b2575b600080fd5b61008a610085366004611fb5565b610127565b6040519081526020015b60405180910390f35b6100b06100ab366004612055565b61014d565b005b61008a6100c036600461215a565b610450565b60015465010000000000900473ffffffffffffffffffffffffffffffffffffffff1660405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610094565b6100b061011a3660046121ce565b6106d0565b61008a61089d565b600061013161095e565b61013b8484610a16565b905061014682610c5d565b9392505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff9081164290911610156101f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064015b60405180910390fd5b6101fd61095e565b848114158061020c5750848314155b15610243576040517fdde5716100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006102b87fac87185d000000000000000000000000000000000000000000000000000000006000527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020527f6d9f2463c8c0d8cb8be556a773ab21d4321328909a1725f2ef7cae0c320e95da5460601c90565b905073ffffffffffffffffffffffffffffffffffffffff811661038f5760005b86811015610389576103818888838181106102f5576102f5612228565b905060200201602081019061030a9190612257565b87878481811061031c5761031c612228565b9050602002013586868581811061033557610335612228565b90506020028101906103479190612272565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610cc892505050565b6001016102d8565b50610447565b60005b868110156104455761043d8888838181106103af576103af612228565b90506020020160208101906103c49190612257565b8787848181106103d6576103d6612228565b905060200201358686858181106103ef576103ef612228565b90506020028101906104019190612272565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250889250610d45915050565b600101610392565b505b50505050505050565b600061045a610e0d565b6001805473ffffffffffffffffffffffffffffffffffffffff88811665010000000000027fffffffffffffff0000000000000000000000000000000000000000ffffffffff90921691909117909155600280548783167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216179091557f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd492380549287169290911691909117905561051187610eb3565b60008383604051602401610526929190612320565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fcd9b47e40000000000000000000000000000000000000000000000000000000017905251909150600090819073ffffffffffffffffffffffffffffffffffffffff8b16906105c8908590612360565b600060405180830381855af49150503d8060008114610603576040519150601f19603f3d011682016040523d82523d6000602084013e610608565b606091505b5091509150811580610623575061061e8161237c565b600114155b1561065a576040517f1602372100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60019350858560405161066e9291906123c1565b60405190819003812060015490916501000000000090910473ffffffffffffffffffffffffffffffffffffffff16907fd429ff0b972be4ae725700a373d05007287994e4c86cb83315b43ffa85b595fd90600090a35050509695505050505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610773576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064016101ec565b61077b61095e565b60006107f07fac87185d000000000000000000000000000000000000000000000000000000006000527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020527f6d9f2463c8c0d8cb8be556a773ab21d4321328909a1725f2ef7cae0c320e95da5460601c90565b905073ffffffffffffffffffffffffffffffffffffffff81166108535761084e858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610cc892505050565b610896565b610896858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250879250610d45915050565b5050505050565b60015460009065010000000000900473ffffffffffffffffffffffffffffffffffffffff166040517f35567e1a0000000000000000000000000000000000000000000000000000000081523060048201526000602482015273ffffffffffffffffffffffffffffffffffffffff91909116906335567e1a90604401602060405180830381865afa158015610935573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061095991906123d1565b905090565b60015465010000000000900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a14576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f6163636f756e743a206e6f742066726f6d20456e747279506f696e740000000060448201526064016101ec565b565b600154610100900460e01b7fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604081205460601c80610aab576040517f6eb2360200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600154604051600091610100900460e01b90610acd908790879060240161244e565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090506000808373ffffffffffffffffffffffffffffffffffffffff1683604051610b549190612360565b600060405180830381855af49150503d8060008114610b8f576040519150601f19603f3d011682016040523d82523d6000602084013e610b94565b606091505b509150915081610bd0576040517f3cbbb65000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610bd98161237c565b94506000859003610c1c576040518681527f19e781916118c373dadcb7776fae0a2dbb6bbdeedae143ce68031e22801ef8659060200160405180910390a1610c50565b6040518681527fbbfee2df7f28b899771f1015dc85d7840ff9f6162f23f6aa99686e8fbd2ce1319060200160405180910390a15b5050505092915050565b50565b8015610c5a5760405160009033907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90849084818181858888f193505050503d8060008114610896576040519150601f19603f3d011682016040523d82523d6000602084013e610896565b6000808473ffffffffffffffffffffffffffffffffffffffff168484604051610cf19190612360565b60006040518083038185875af1925050503d8060008114610d2e576040519150601f19603f3d011682016040523d82523d6000602084013e610d33565b606091505b50915091508161089657805160208201fd5b610d5181858585611117565b15610d88576040517f01f595e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000808573ffffffffffffffffffffffffffffffffffffffff168585604051610db19190612360565b60006040518083038185875af1925050503d8060008114610dee576040519150601f19603f3d011682016040523d82523d6000602084013e610df3565b606091505b509150915081610e0557805160208201fd5b505050505050565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb554610100900460ff1615610e78576040517f38fc28cb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100179055565b604080516001808252818301909252600091816020015b60408051606080820183526000808352602083015291810191909152815260200190600190039081610eca57905050905060008273ffffffffffffffffffffffffffffffffffffffff16633253960f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f6c9190612592565b604080516003808252608082019092529192506000919060208201606080368337019050509050631626ba7e60e01b81600081518110610fae57610fae612228565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681525050818160018151811061100e5761100e612228565b7fffffffff000000000000000000000000000000000000000000000000000000009092166020928302919091019091015280517f8da5cb5b00000000000000000000000000000000000000000000000000000000908290600290811061107657611076612228565b7fffffffff00000000000000000000000000000000000000000000000000000000909216602092830291909101820152604080516060810190915273ffffffffffffffffffffffffffffffffffffffff861681529081016000815260200182815250836000815181106110eb576110eb612228565b602002602001018190525061111183600060405180602001604052806000815250611264565b50505050565b60008030858585604051602401611131949392919061264d565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fac87185d0000000000000000000000000000000000000000000000000000000017905251909150600090819073ffffffffffffffffffffffffffffffffffffffff8916906111d3908590612360565b600060405180830381855af49150503d806000811461120e576040519150601f19603f3d011682016040523d82523d6000602084013e611213565b606091505b50915091508161124f576040517f01f595e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6112588161237c565b98975050505050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921547f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff8116908190600090600716156112d35750600381901c60009081526001840160205260409020545b60005b87518110156113505761134383838a84815181106112f6576112f6612228565b6020026020010151600001518b858151811061131457611314612228565b6020026020010151602001518c868151811061133257611332612228565b6020026020010151604001516113f0565b90935091506001016112d6565b50828214611389576002840180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff84161790555b60078216156113ab57600382901c600090815260018501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb6738787876040516113de93929190612696565b60405180910390a16104478686611e81565b600080807f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f905060008451116114a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f2063757400000000000000000000000000000000000000000060648201526084016101ec565b60008560028111156114bc576114bc6125d4565b0361168c576114e38660405180606001604052806024815260200161290d60249139611f7a565b60005b845181101561168657600085828151811061150357611503612228565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c156115d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c726561647920657869737473000000000000000000000060648201526084016101ec565b7fffffffff0000000000000000000000000000000000000000000000000000000080831660008181526020879052604090207fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608d901b168e17905560e060058e901b811692831c199c909c1690821c179a81900361166a5760038c901c600090815260018601602052604081209b909b555b8b6116748161282d565b9c5050600190930192506114e6915050565b50611e75565b60018560028111156116a0576116a06125d4565b03611990576116c78660405180606001604052806028815260200161295960289139611f7a565b60005b84518110156116865760008582815181106116e7576116e7612228565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c3081036117bc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4c69624469616d6f6e644375743a2043616e2774207265706c61636520696d6d60448201527f757461626c652066756e6374696f6e000000000000000000000000000000000060648201526084016101ec565b8973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611877576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e000000000000000060648201526084016101ec565b73ffffffffffffffffffffffffffffffffffffffff811661191a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e207468617420646f65736e2774206578697374000000000000000060648201526084016101ec565b507fffffffff0000000000000000000000000000000000000000000000000000000090911660009081526020849052604090206bffffffffffffffffffffffff919091167fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608a901b161790556001016116ca565b60028560028111156119a4576119a46125d4565b03611ded5773ffffffffffffffffffffffffffffffffffffffff861615611a4d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d75737420626520616464726573732830290000000000000000000060648201526084016101ec565b600388901c6007891660005b8651811015611dcd5760008a9003611a955782611a7581612865565b60008181526001870160205260409020549b50935060079250611aa39050565b81611a9f81612865565b9250505b6000806000808a8581518110611abb57611abb612228565b6020908102919091018101517fffffffff0000000000000000000000000000000000000000000000000000000081166000908152918a9052604090912054909150606081901c611b8d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e277420657869737400000000000000000060648201526084016101ec565b30606082901c03611c20576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e00000000000000000000000000000000000060648201526084016101ec565b600587901b8f901b94507fffffffff0000000000000000000000000000000000000000000000000000000080861690831614611cbe577fffffffff000000000000000000000000000000000000000000000000000000008516600090815260208a90526040902080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff83161790555b7fffffffff0000000000000000000000000000000000000000000000000000000091909116600090815260208990526040812055600381901c611fff16925060051b60e0169050858214611d53576000828152600188016020526040902080547fffffffff0000000000000000000000000000000000000000000000000000000080841c19909116908516831c179055611da4565b80837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c817fffffffff0000000000000000000000000000000000000000000000000000000060001b901c198e16179c505b84600003611dc257600086815260018801602052604081208190559c505b505050600101611a59565b5080611dda83600861289a565b611de491906128b7565b99505050611e75565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560448201527f74416374696f6e0000000000000000000000000000000000000000000000000060648201526084016101ec565b50959694955050505050565b73ffffffffffffffffffffffffffffffffffffffff8216611ea0575050565b611ec28260405180606001604052806028815260200161293160289139611f7a565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051611eea9190612360565b600060405180830381855af49150503d8060008114611f25576040519150601f19603f3d011682016040523d82523d6000602084013e611f2a565b606091505b50915091508161111157805115611f445780518082602001fd5b83836040517f192105d70000000000000000000000000000000000000000000000000000000081526004016101ec9291906128ca565b813b8181611111576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101ec91906128f9565b600080600060608486031215611fca57600080fd5b833567ffffffffffffffff811115611fe157600080fd5b84016101608187031215611ff457600080fd5b95602085013595506040909401359392505050565b60008083601f84011261201b57600080fd5b50813567ffffffffffffffff81111561203357600080fd5b6020830191508360208260051b850101111561204e57600080fd5b9250929050565b6000806000806000806060878903121561206e57600080fd5b863567ffffffffffffffff8082111561208657600080fd5b6120928a838b01612009565b909850965060208901359150808211156120ab57600080fd5b6120b78a838b01612009565b909650945060408901359150808211156120d057600080fd5b506120dd89828a01612009565b979a9699509497509295939492505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461211357600080fd5b919050565b60008083601f84011261212a57600080fd5b50813567ffffffffffffffff81111561214257600080fd5b60208301915083602082850101111561204e57600080fd5b60008060008060008060a0878903121561217357600080fd5b61217c876120ef565b955061218a602088016120ef565b9450612198604088016120ef565b93506121a6606088016120ef565b9250608087013567ffffffffffffffff8111156121c257600080fd5b6120dd89828a01612118565b600080600080606085870312156121e457600080fd5b6121ed856120ef565b935060208501359250604085013567ffffffffffffffff81111561221057600080fd5b61221c87828801612118565b95989497509550505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561226957600080fd5b610146826120ef565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126122a757600080fd5b83018035915067ffffffffffffffff8211156122c257600080fd5b60200191503681900382131561204e57600080fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b6020815260006123346020830184866122d7565b949350505050565b60005b8381101561235757818101518382015260200161233f565b50506000910152565b6000825161237281846020870161233c565b9190910192915050565b805160208083015191908110156123bb577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8160200360031b1b821691505b50919050565b8183823760009101908152919050565b6000602082840312156123e357600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261241f57600080fd5b830160208101925035905067ffffffffffffffff81111561243f57600080fd5b80360382131561204e57600080fd5b6040815261247c60408201612462856120ef565b73ffffffffffffffffffffffffffffffffffffffff169052565b60208301356060820152600061249560408501856123ea565b6101608060808601526124ad6101a0860183856122d7565b92506124bc60608801886123ea565b92507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0808786030160a08801526124f48585846122d7565b9450608089013560c088015260a089013560e0880152610100935060c089013584880152610120915060e089013582880152610140848a01358189015261253d838b018b6123ea565b955092508188870301848901526125558686856122d7565b9550612563818b018b6123ea565b9550935050808786030161018088015250506125808383836122d7565b93505050508260208301529392505050565b6000602082840312156125a457600080fd5b81517fffffffff000000000000000000000000000000000000000000000000000000008116811461014657600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6000815180845261261b81602086016020860161233c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600073ffffffffffffffffffffffffffffffffffffffff80871683528086166020840152508360408301526080606083015261268c6080830184612603565b9695505050505050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b848110156127c1577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808a8503018652815188850173ffffffffffffffffffffffffffffffffffffffff82511686528482015160038110612748577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b808310156127ac5783517fffffffff0000000000000000000000000000000000000000000000000000000016825292860192600192909201919086019061276a565b509785019795505050908201906001016126bf565b505073ffffffffffffffffffffffffffffffffffffffff8a169088015286810360408801526127f08189612603565b9a9950505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361285e5761285e6127fe565b5060010190565b600081612874576128746127fe565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b80820281158282048414176128b1576128b16127fe565b92915050565b808201808211156128b1576128b16127fe565b73ffffffffffffffffffffffffffffffffffffffff831681526040602082015260006123346040830184612603565b602081526000610146602083018461260356fe4c69624469616d6f6e644375743a2041646420666163657420686173206e6f20636f64654c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a205265706c61636520666163657420686173206e6f20636f6465a2646970667358221220a952f19990a20474450919a2df9ddff4430a71350892e0954f2bb073575ad64864736f6c63430008150033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100725760003560e01c8063b0d691fe11610050578063b0d691fe146100c5578063b61d27f61461010c578063d087d2881461011f57600080fd5b80633a871cdd1461007757806347e1da2a1461009d5780634a936417146100b2575b600080fd5b61008a610085366004611fb5565b610127565b6040519081526020015b60405180910390f35b6100b06100ab366004612055565b61014d565b005b61008a6100c036600461215a565b610450565b60015465010000000000900473ffffffffffffffffffffffffffffffffffffffff1660405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610094565b6100b061011a3660046121ce565b6106d0565b61008a61089d565b600061013161095e565b61013b8484610a16565b905061014682610c5d565b9392505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff9081164290911610156101f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064015b60405180910390fd5b6101fd61095e565b848114158061020c5750848314155b15610243576040517fdde5716100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006102b87fac87185d000000000000000000000000000000000000000000000000000000006000527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020527f6d9f2463c8c0d8cb8be556a773ab21d4321328909a1725f2ef7cae0c320e95da5460601c90565b905073ffffffffffffffffffffffffffffffffffffffff811661038f5760005b86811015610389576103818888838181106102f5576102f5612228565b905060200201602081019061030a9190612257565b87878481811061031c5761031c612228565b9050602002013586868581811061033557610335612228565b90506020028101906103479190612272565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610cc892505050565b6001016102d8565b50610447565b60005b868110156104455761043d8888838181106103af576103af612228565b90506020020160208101906103c49190612257565b8787848181106103d6576103d6612228565b905060200201358686858181106103ef576103ef612228565b90506020028101906104019190612272565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250889250610d45915050565b600101610392565b505b50505050505050565b600061045a610e0d565b6001805473ffffffffffffffffffffffffffffffffffffffff88811665010000000000027fffffffffffffff0000000000000000000000000000000000000000ffffffffff90921691909117909155600280548783167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216179091557f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd492380549287169290911691909117905561051187610eb3565b60008383604051602401610526929190612320565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fcd9b47e40000000000000000000000000000000000000000000000000000000017905251909150600090819073ffffffffffffffffffffffffffffffffffffffff8b16906105c8908590612360565b600060405180830381855af49150503d8060008114610603576040519150601f19603f3d011682016040523d82523d6000602084013e610608565b606091505b5091509150811580610623575061061e8161237c565b600114155b1561065a576040517f1602372100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60019350858560405161066e9291906123c1565b60405190819003812060015490916501000000000090910473ffffffffffffffffffffffffffffffffffffffff16907fd429ff0b972be4ae725700a373d05007287994e4c86cb83315b43ffa85b595fd90600090a35050509695505050505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610773576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064016101ec565b61077b61095e565b60006107f07fac87185d000000000000000000000000000000000000000000000000000000006000527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020527f6d9f2463c8c0d8cb8be556a773ab21d4321328909a1725f2ef7cae0c320e95da5460601c90565b905073ffffffffffffffffffffffffffffffffffffffff81166108535761084e858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610cc892505050565b610896565b610896858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250879250610d45915050565b5050505050565b60015460009065010000000000900473ffffffffffffffffffffffffffffffffffffffff166040517f35567e1a0000000000000000000000000000000000000000000000000000000081523060048201526000602482015273ffffffffffffffffffffffffffffffffffffffff91909116906335567e1a90604401602060405180830381865afa158015610935573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061095991906123d1565b905090565b60015465010000000000900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a14576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f6163636f756e743a206e6f742066726f6d20456e747279506f696e740000000060448201526064016101ec565b565b600154610100900460e01b7fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604081205460601c80610aab576040517f6eb2360200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600154604051600091610100900460e01b90610acd908790879060240161244e565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090506000808373ffffffffffffffffffffffffffffffffffffffff1683604051610b549190612360565b600060405180830381855af49150503d8060008114610b8f576040519150601f19603f3d011682016040523d82523d6000602084013e610b94565b606091505b509150915081610bd0576040517f3cbbb65000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610bd98161237c565b94506000859003610c1c576040518681527f19e781916118c373dadcb7776fae0a2dbb6bbdeedae143ce68031e22801ef8659060200160405180910390a1610c50565b6040518681527fbbfee2df7f28b899771f1015dc85d7840ff9f6162f23f6aa99686e8fbd2ce1319060200160405180910390a15b5050505092915050565b50565b8015610c5a5760405160009033907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90849084818181858888f193505050503d8060008114610896576040519150601f19603f3d011682016040523d82523d6000602084013e610896565b6000808473ffffffffffffffffffffffffffffffffffffffff168484604051610cf19190612360565b60006040518083038185875af1925050503d8060008114610d2e576040519150601f19603f3d011682016040523d82523d6000602084013e610d33565b606091505b50915091508161089657805160208201fd5b610d5181858585611117565b15610d88576040517f01f595e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000808573ffffffffffffffffffffffffffffffffffffffff168585604051610db19190612360565b60006040518083038185875af1925050503d8060008114610dee576040519150601f19603f3d011682016040523d82523d6000602084013e610df3565b606091505b509150915081610e0557805160208201fd5b505050505050565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb554610100900460ff1615610e78576040517f38fc28cb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100179055565b604080516001808252818301909252600091816020015b60408051606080820183526000808352602083015291810191909152815260200190600190039081610eca57905050905060008273ffffffffffffffffffffffffffffffffffffffff16633253960f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f6c9190612592565b604080516003808252608082019092529192506000919060208201606080368337019050509050631626ba7e60e01b81600081518110610fae57610fae612228565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681525050818160018151811061100e5761100e612228565b7fffffffff000000000000000000000000000000000000000000000000000000009092166020928302919091019091015280517f8da5cb5b00000000000000000000000000000000000000000000000000000000908290600290811061107657611076612228565b7fffffffff00000000000000000000000000000000000000000000000000000000909216602092830291909101820152604080516060810190915273ffffffffffffffffffffffffffffffffffffffff861681529081016000815260200182815250836000815181106110eb576110eb612228565b602002602001018190525061111183600060405180602001604052806000815250611264565b50505050565b60008030858585604051602401611131949392919061264d565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fac87185d0000000000000000000000000000000000000000000000000000000017905251909150600090819073ffffffffffffffffffffffffffffffffffffffff8916906111d3908590612360565b600060405180830381855af49150503d806000811461120e576040519150601f19603f3d011682016040523d82523d6000602084013e611213565b606091505b50915091508161124f576040517f01f595e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6112588161237c565b98975050505050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921547f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff8116908190600090600716156112d35750600381901c60009081526001840160205260409020545b60005b87518110156113505761134383838a84815181106112f6576112f6612228565b6020026020010151600001518b858151811061131457611314612228565b6020026020010151602001518c868151811061133257611332612228565b6020026020010151604001516113f0565b90935091506001016112d6565b50828214611389576002840180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff84161790555b60078216156113ab57600382901c600090815260018501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb6738787876040516113de93929190612696565b60405180910390a16104478686611e81565b600080807f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f905060008451116114a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f2063757400000000000000000000000000000000000000000060648201526084016101ec565b60008560028111156114bc576114bc6125d4565b0361168c576114e38660405180606001604052806024815260200161290d60249139611f7a565b60005b845181101561168657600085828151811061150357611503612228565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c156115d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c726561647920657869737473000000000000000000000060648201526084016101ec565b7fffffffff0000000000000000000000000000000000000000000000000000000080831660008181526020879052604090207fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608d901b168e17905560e060058e901b811692831c199c909c1690821c179a81900361166a5760038c901c600090815260018601602052604081209b909b555b8b6116748161282d565b9c5050600190930192506114e6915050565b50611e75565b60018560028111156116a0576116a06125d4565b03611990576116c78660405180606001604052806028815260200161295960289139611f7a565b60005b84518110156116865760008582815181106116e7576116e7612228565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c3081036117bc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4c69624469616d6f6e644375743a2043616e2774207265706c61636520696d6d60448201527f757461626c652066756e6374696f6e000000000000000000000000000000000060648201526084016101ec565b8973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611877576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e000000000000000060648201526084016101ec565b73ffffffffffffffffffffffffffffffffffffffff811661191a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e207468617420646f65736e2774206578697374000000000000000060648201526084016101ec565b507fffffffff0000000000000000000000000000000000000000000000000000000090911660009081526020849052604090206bffffffffffffffffffffffff919091167fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608a901b161790556001016116ca565b60028560028111156119a4576119a46125d4565b03611ded5773ffffffffffffffffffffffffffffffffffffffff861615611a4d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d75737420626520616464726573732830290000000000000000000060648201526084016101ec565b600388901c6007891660005b8651811015611dcd5760008a9003611a955782611a7581612865565b60008181526001870160205260409020549b50935060079250611aa39050565b81611a9f81612865565b9250505b6000806000808a8581518110611abb57611abb612228565b6020908102919091018101517fffffffff0000000000000000000000000000000000000000000000000000000081166000908152918a9052604090912054909150606081901c611b8d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e277420657869737400000000000000000060648201526084016101ec565b30606082901c03611c20576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e00000000000000000000000000000000000060648201526084016101ec565b600587901b8f901b94507fffffffff0000000000000000000000000000000000000000000000000000000080861690831614611cbe577fffffffff000000000000000000000000000000000000000000000000000000008516600090815260208a90526040902080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff83161790555b7fffffffff0000000000000000000000000000000000000000000000000000000091909116600090815260208990526040812055600381901c611fff16925060051b60e0169050858214611d53576000828152600188016020526040902080547fffffffff0000000000000000000000000000000000000000000000000000000080841c19909116908516831c179055611da4565b80837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c817fffffffff0000000000000000000000000000000000000000000000000000000060001b901c198e16179c505b84600003611dc257600086815260018801602052604081208190559c505b505050600101611a59565b5080611dda83600861289a565b611de491906128b7565b99505050611e75565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560448201527f74416374696f6e0000000000000000000000000000000000000000000000000060648201526084016101ec565b50959694955050505050565b73ffffffffffffffffffffffffffffffffffffffff8216611ea0575050565b611ec28260405180606001604052806028815260200161293160289139611f7a565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051611eea9190612360565b600060405180830381855af49150503d8060008114611f25576040519150601f19603f3d011682016040523d82523d6000602084013e611f2a565b606091505b50915091508161111157805115611f445780518082602001fd5b83836040517f192105d70000000000000000000000000000000000000000000000000000000081526004016101ec9291906128ca565b813b8181611111576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101ec91906128f9565b600080600060608486031215611fca57600080fd5b833567ffffffffffffffff811115611fe157600080fd5b84016101608187031215611ff457600080fd5b95602085013595506040909401359392505050565b60008083601f84011261201b57600080fd5b50813567ffffffffffffffff81111561203357600080fd5b6020830191508360208260051b850101111561204e57600080fd5b9250929050565b6000806000806000806060878903121561206e57600080fd5b863567ffffffffffffffff8082111561208657600080fd5b6120928a838b01612009565b909850965060208901359150808211156120ab57600080fd5b6120b78a838b01612009565b909650945060408901359150808211156120d057600080fd5b506120dd89828a01612009565b979a9699509497509295939492505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461211357600080fd5b919050565b60008083601f84011261212a57600080fd5b50813567ffffffffffffffff81111561214257600080fd5b60208301915083602082850101111561204e57600080fd5b60008060008060008060a0878903121561217357600080fd5b61217c876120ef565b955061218a602088016120ef565b9450612198604088016120ef565b93506121a6606088016120ef565b9250608087013567ffffffffffffffff8111156121c257600080fd5b6120dd89828a01612118565b600080600080606085870312156121e457600080fd5b6121ed856120ef565b935060208501359250604085013567ffffffffffffffff81111561221057600080fd5b61221c87828801612118565b95989497509550505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561226957600080fd5b610146826120ef565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126122a757600080fd5b83018035915067ffffffffffffffff8211156122c257600080fd5b60200191503681900382131561204e57600080fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b6020815260006123346020830184866122d7565b949350505050565b60005b8381101561235757818101518382015260200161233f565b50506000910152565b6000825161237281846020870161233c565b9190910192915050565b805160208083015191908110156123bb577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8160200360031b1b821691505b50919050565b8183823760009101908152919050565b6000602082840312156123e357600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261241f57600080fd5b830160208101925035905067ffffffffffffffff81111561243f57600080fd5b80360382131561204e57600080fd5b6040815261247c60408201612462856120ef565b73ffffffffffffffffffffffffffffffffffffffff169052565b60208301356060820152600061249560408501856123ea565b6101608060808601526124ad6101a0860183856122d7565b92506124bc60608801886123ea565b92507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0808786030160a08801526124f48585846122d7565b9450608089013560c088015260a089013560e0880152610100935060c089013584880152610120915060e089013582880152610140848a01358189015261253d838b018b6123ea565b955092508188870301848901526125558686856122d7565b9550612563818b018b6123ea565b9550935050808786030161018088015250506125808383836122d7565b93505050508260208301529392505050565b6000602082840312156125a457600080fd5b81517fffffffff000000000000000000000000000000000000000000000000000000008116811461014657600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6000815180845261261b81602086016020860161233c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600073ffffffffffffffffffffffffffffffffffffffff80871683528086166020840152508360408301526080606083015261268c6080830184612603565b9695505050505050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b848110156127c1577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808a8503018652815188850173ffffffffffffffffffffffffffffffffffffffff82511686528482015160038110612748577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b808310156127ac5783517fffffffff0000000000000000000000000000000000000000000000000000000016825292860192600192909201919086019061276a565b509785019795505050908201906001016126bf565b505073ffffffffffffffffffffffffffffffffffffffff8a169088015286810360408801526127f08189612603565b9a9950505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361285e5761285e6127fe565b5060010190565b600081612874576128746127fe565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b80820281158282048414176128b1576128b16127fe565b92915050565b808201808211156128b1576128b16127fe565b73ffffffffffffffffffffffffffffffffffffffff831681526040602082015260006123346040830184612603565b602081526000610146602083018461260356fe4c69624469616d6f6e644375743a2041646420666163657420686173206e6f20636f64654c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a205265706c61636520666163657420686173206e6f20636f6465a2646970667358221220a952f19990a20474450919a2df9ddff4430a71350892e0954f2bb073575ad64864736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "Account module contract that provides the account features and initialization of signer compatible with EIP-1271 & EIP-4337", + "kind": "dev", + "methods": { + "execute(address,uint256,bytes)": { + "details": "This method executes the calldata coming from the EntryPoint. Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)", + "params": { + "_dest": "Address of destination where the call will be forwarded to", + "_func": "Bytes of calldata to execute in the destination address", + "_value": "Amount of native coin the owner is willing to send(e.g. ETH, BNB)" + } + }, + "executeBatch(address[],uint256[],bytes[])": { + "details": "This method batch executes the calldata coming from the EntryPoint. Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)", + "params": { + "_dest": "Array of addresses of destination where the call will be forwarded to", + "_func": "Array of bytes of calldata to execute in the destination address", + "_value": "Array of amount of native coin the owner is willing to send(e.g. ETH, BNB)" + } + }, + "initialize(address,address,address,address,bytes)": { + "details": "This method can only be called during the initialization or signature migration. If the proxy contract was created without initialization, anyone can call initialize. Barz calls initialize in constructor in an atomic transaction during deployment", + "params": { + "_anEntryPoint": "Entrypoint contract defined in EIP-4337 handling the flow of UserOp", + "_defaultFallBackHandler": "Middleware contract for default facets", + "_facetRegistry": "Registry of Facets that hold all facet information", + "_ownerPublicKey": "Bytes of owner public key", + "_verificationFacet": "Facet contract handling the verificationi" + } + } + }, + "title": "Account Facet", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "constructor": { + "notice": "This constructor ensures that this contract can only be used as singleton for Proxy contracts" + }, + "entryPoint()": { + "notice": "Returns the address of EntryPoint contract registered to Barz account" + }, + "execute(address,uint256,bytes)": { + "notice": "Calls the destination with inputted calldata and value from EntryPoint" + }, + "executeBatch(address[],uint256[],bytes[])": { + "notice": "Batch calls the destination with inputted calldata and value from EntryPoint" + }, + "getNonce()": { + "notice": "Return the account nonce. This method returns the next sequential nonce. For a nonce of a specific key, use `entrypoint.getNonce(account, key)`" + }, + "initialize(address,address,address,address,bytes)": { + "notice": "Initializes the initial storage of the Barz contract." + }, + "validateUserOp((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256)": { + "notice": "Validate user's signature and nonce. subclass doesn't need to override this method. Instead, it should override the specific internal validation methods." + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 27866, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "s", + "offset": 0, + "slot": "0", + "type": "t_struct(AppStorage)27613_storage" + } + ], + "types": { + "t_bytes4": { + "encoding": "inplace", + "label": "bytes4", + "numberOfBytes": "4" + }, + "t_contract(IEntryPoint)12286": { + "encoding": "inplace", + "label": "contract IEntryPoint", + "numberOfBytes": "20" + }, + "t_contract(IFacetRegistry)26148": { + "encoding": "inplace", + "label": "contract IFacetRegistry", + "numberOfBytes": "20" + }, + "t_mapping(t_uint256,t_struct(InitializersStorage)27592_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => struct InitializersStorage)", + "numberOfBytes": "32", + "value": "t_struct(InitializersStorage)27592_storage" + }, + "t_mapping(t_uint256,t_struct(Lock)27585_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => struct Lock)", + "numberOfBytes": "32", + "value": "t_struct(Lock)27585_storage" + }, + "t_struct(AppStorage)27613_storage": { + "encoding": "inplace", + "label": "struct AppStorage", + "members": [ + { + "astId": 27597, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "initStorage", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_uint256,t_struct(InitializersStorage)27592_storage)" + }, + { + "astId": 27599, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "signerMigration", + "offset": 0, + "slot": "1", + "type": "t_uint8" + }, + { + "astId": 27601, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "validateOwnerSignatureSelector", + "offset": 1, + "slot": "1", + "type": "t_bytes4" + }, + { + "astId": 27604, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "entryPoint", + "offset": 5, + "slot": "1", + "type": "t_contract(IEntryPoint)12286" + }, + { + "astId": 27607, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "facetRegistry", + "offset": 0, + "slot": "2", + "type": "t_contract(IFacetRegistry)26148" + }, + { + "astId": 27612, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "locks", + "offset": 0, + "slot": "3", + "type": "t_mapping(t_uint256,t_struct(Lock)27585_storage)" + } + ], + "numberOfBytes": "128" + }, + "t_struct(InitializersStorage)27592_storage": { + "encoding": "inplace", + "label": "struct InitializersStorage", + "members": [ + { + "astId": 27587, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "signerInitialized", + "offset": 0, + "slot": "0", + "type": "t_uint8" + }, + { + "astId": 27589, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "accountInitialized", + "offset": 1, + "slot": "0", + "type": "t_uint8" + }, + { + "astId": 27591, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "restrictionsInitialized", + "offset": 2, + "slot": "0", + "type": "t_uint8" + } + ], + "numberOfBytes": "32" + }, + "t_struct(Lock)27585_storage": { + "encoding": "inplace", + "label": "struct Lock", + "members": [ + { + "astId": 27582, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "release", + "offset": 0, + "slot": "0", + "type": "t_uint64" + }, + { + "astId": 27584, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "locker", + "offset": 8, + "slot": "0", + "type": "t_bytes4" + } + ], + "numberOfBytes": "32" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint64": { + "encoding": "inplace", + "label": "uint64", + "numberOfBytes": "8" + }, + "t_uint8": { + "encoding": "inplace", + "label": "uint8", + "numberOfBytes": "1" + } + } + } +} \ No newline at end of file diff --git a/deployments/lightLink/BarzFactory.json b/deployments/lightLink/BarzFactory.json new file mode 100644 index 0000000..2f71649 --- /dev/null +++ b/deployments/lightLink/BarzFactory.json @@ -0,0 +1,318 @@ +{ + "address": "0x729c310186a57833f622630a16d13f710b83272a", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_accountFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_entryPoint", + "type": "address" + }, + { + "internalType": "address", + "name": "_facetRegistry", + "type": "address" + }, + { + "internalType": "address", + "name": "_defaultFallback", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "BarzDeployed", + "type": "event" + }, + { + "inputs": [], + "name": "accountFacet", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_verificationFacet", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_owner", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "_salt", + "type": "uint256" + } + ], + "name": "createAccount", + "outputs": [ + { + "internalType": "contract Barz", + "name": "barz", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "defaultFallback", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "entryPoint", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetRegistry", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_verificationFacet", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_owner", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "_salt", + "type": "uint256" + } + ], + "name": "getAddress", + "outputs": [ + { + "internalType": "address", + "name": "barzAddress", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_accountFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_verificationFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_entryPoint", + "type": "address" + }, + { + "internalType": "address", + "name": "_facetRegistry", + "type": "address" + }, + { + "internalType": "address", + "name": "_defaultFallback", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_ownerPublicKey", + "type": "bytes" + } + ], + "name": "getBytecode", + "outputs": [ + { + "internalType": "bytes", + "name": "barzBytecode", + "type": "bytes" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "getCreationCode", + "outputs": [ + { + "internalType": "bytes", + "name": "creationCode", + "type": "bytes" + } + ], + "stateMutability": "pure", + "type": "function" + } + ], + "transactionHash": "0x932a0163b14f1f145de780fe3957ad7ae350997e9219aaa703f7aa242e576320", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": "0x0000000000000000000000000000000000000000", + "transactionIndex": 0, + "gasUsed": "802000", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x2c9e0f3f8472347cc5a1185d81b4616e60377515341bcf3f971c5631f37f8586", + "transactionHash": "0x932a0163b14f1f145de780fe3957ad7ae350997e9219aaa703f7aa242e576320", + "logs": [], + "blockNumber": 72701609, + "cumulativeGasUsed": "802000", + "status": 1, + "byzantium": true + }, + "args": [ + "0xFde53272dcd7938d16E031A6989753c321728332", + "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789", + "0xAfCb70e6e9514E2A15B23A01d2a9b9f7A34f2c33", + "0x2e7f1dAe1F3799d20f5c31bEFdc7A620f664728D" + ], + "numDeployments": 1, + "solcInputHash": "ad34345aa73d96f52b3e14df983b6b29", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_accountFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_entryPoint\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_facetRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_defaultFallback\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"BarzDeployed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"accountFacet\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_verificationFacet\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_owner\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_salt\",\"type\":\"uint256\"}],\"name\":\"createAccount\",\"outputs\":[{\"internalType\":\"contract Barz\",\"name\":\"barz\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"defaultFallback\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"entryPoint\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetRegistry\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_verificationFacet\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_owner\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_salt\",\"type\":\"uint256\"}],\"name\":\"getAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"barzAddress\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_accountFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_verificationFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_entryPoint\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_facetRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_defaultFallback\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_ownerPublicKey\",\"type\":\"bytes\"}],\"name\":\"getBytecode\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"barzBytecode\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCreationCode\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"creationCode\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"Contract to easily deploy Barz to a pre-computed address with a single call\",\"kind\":\"dev\",\"methods\":{\"constructor\":{\"params\":{\"_accountFacet\":\"Account Facet to be used to create Barz\",\"_defaultFallback\":\"Default Fallback Handler to be used to create Barz\",\"_entryPoint\":\"Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\",\"_facetRegistry\":\"Facet Registry to be used to create Barz\"}},\"createAccount(address,bytes,uint256)\":{\"params\":{\"_owner\":\"Public Key of the owner to initialize barz account\",\"_salt\":\"Salt used for deploying barz with create2\",\"_verificationFacet\":\"Address of verification facet used for creating the barz account\"},\"returns\":{\"barz\":\"Instance of Barz contract deployed with the given parameters\"}},\"getAddress(address,bytes,uint256)\":{\"params\":{\"_owner\":\"Public Key of the owner to initialize barz account\",\"_salt\":\"Salt used for deploying barz with create2\",\"_verificationFacet\":\"Address of verification facet used for creating the barz account\"},\"returns\":{\"barzAddress\":\"Precalculated Barz address\"}},\"getBytecode(address,address,address,address,address,bytes)\":{\"params\":{\"_accountFacet\":\"Account Facet to be used to create Barz\",\"_defaultFallback\":\"Default Fallback Handler to be used to create Barz\",\"_entryPoint\":\"Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\",\"_facetRegistry\":\"Facet Registry to be used to create Barz\",\"_ownerPublicKey\":\"Public Key of owner to be used to initialize Barz ownership\",\"_verificationFacet\":\"Verification Facet to be used to create Barz\"},\"returns\":{\"barzBytecode\":\"Bytecode of Barz\"}},\"getCreationCode()\":{\"returns\":{\"creationCode\":\"Creation code of Barz\"}}},\"title\":\"Barz Factory\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"Sets the initialization data for Barz contract initialization\"},\"createAccount(address,bytes,uint256)\":{\"notice\":\"Creates the Barz with a single call. It creates the Barz contract with the givent verification facet\"},\"getAddress(address,bytes,uint256)\":{\"notice\":\"Calculates the address of Barz with the given parameters\"},\"getBytecode(address,address,address,address,address,bytes)\":{\"notice\":\"Returns the bytecode of Barz with the given parameter\"},\"getCreationCode()\":{\"notice\":\"Returns the creation code of the Barz contract\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/BarzFactory.sol\":\"BarzFactory\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"contracts/Barz.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {LibDiamond} from \\\"./libraries/LibDiamond.sol\\\";\\nimport {IBarz} from \\\"./interfaces/IBarz.sol\\\";\\n\\n/**\\n * @title Barz\\n * @dev A diamond proxy wallet with a modular & upgradeable architecture\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract Barz is IBarz {\\n /**\\n * @notice Initializes Barz with the given parameters. Barz account is intended to be created from Barz Factory for stable deployment.\\n * @dev This method makes a delegate call to account facet and account facet handles the initialization.\\n * With modular architecture, Barz encompasses wide spectrum of architecture and logic.\\n * The only requirement is account facet to comply with initialize() interface.\\n * Barz doesn't include built-in functions and is a full proxy, for maximum extensibility and modularity.\\n * @param _accountFacet Address of Account Facet in charge of the Barz initialization\\n * @param _verificationFacet Address of Verification Facet for verifying the signature. Could be any signature scheme\\n * @param _entryPoint Address of Entry Point contract\\n * @param _facetRegistry Address of Facet Registry. Facet Registry is a registry holding trusted facets that could be added to user's wallet\\n * @param _defaultFallBack Address of Default FallBack Handler. Middleware contract for more efficient deployment\\n * @param _ownerPublicKey Bytes of Owner Public Key using for initialization\\n */\\n constructor(\\n address _accountFacet,\\n address _verificationFacet,\\n address _entryPoint,\\n address _facetRegistry,\\n address _defaultFallBack,\\n bytes memory _ownerPublicKey\\n ) payable {\\n bytes memory initCall = abi.encodeWithSignature(\\n \\\"initialize(address,address,address,address,bytes)\\\",\\n _verificationFacet,\\n _entryPoint,\\n _facetRegistry,\\n _defaultFallBack,\\n _ownerPublicKey\\n );\\n (bool success, bytes memory result) = _accountFacet.delegatecall(\\n initCall\\n );\\n if (!success || uint256(bytes32(result)) != 1) {\\n revert Barz__InitializationFailure();\\n }\\n }\\n\\n /**\\n * @notice Fallback function for Barz complying with Diamond Standard with customization of adding Default Fallback Handler\\n * @dev Find facet for function that is called and execute the function if a facet is found and return any value.\\n */\\n fallback() external payable {\\n LibDiamond.DiamondStorage storage ds;\\n bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION;\\n // get diamond storage\\n assembly {\\n ds.slot := position\\n }\\n // get facet from function selector\\n address facet = address(bytes20(ds.facets[msg.sig]));\\n if (facet == address(0))\\n facet = ds.defaultFallbackHandler.facetAddress(msg.sig);\\n require(facet != address(0), \\\"Barz: Function does not exist\\\");\\n // Execute external function from facet using delegatecall and return any value.\\n assembly {\\n // copy function selector and any arguments\\n calldatacopy(0, 0, calldatasize())\\n // execute function call using the facet\\n let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)\\n // get any return value\\n returndatacopy(0, 0, returndatasize())\\n // return any return value or error back to the caller\\n switch result\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @notice Receive function to receive native token without data\\n */\\n receive() external payable {}\\n}\\n\",\"keccak256\":\"0xd1c773409a4b3d1ca0316445d9ea1d686bab9cd5f6731fbdb0766a93edfd7bdb\",\"license\":\"Apache-2.0\"},\"contracts/BarzFactory.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {Barz} from \\\"./Barz.sol\\\";\\nimport {IBarzFactory} from \\\"./interfaces/IBarzFactory.sol\\\";\\n\\n/**\\n * @title Barz Factory\\n * @dev Contract to easily deploy Barz to a pre-computed address with a single call\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract BarzFactory is IBarzFactory {\\n address public immutable accountFacet;\\n address public immutable entryPoint;\\n address public immutable facetRegistry;\\n address public immutable defaultFallback;\\n\\n /**\\n * @notice Sets the initialization data for Barz contract initialization\\n * @param _accountFacet Account Facet to be used to create Barz\\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\\n * @param _facetRegistry Facet Registry to be used to create Barz\\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\\n */\\n constructor(\\n address _accountFacet,\\n address _entryPoint,\\n address _facetRegistry,\\n address _defaultFallback\\n ) {\\n accountFacet = _accountFacet;\\n entryPoint = _entryPoint;\\n facetRegistry = _facetRegistry;\\n defaultFallback = _defaultFallback;\\n }\\n\\n /**\\n * @notice Creates the Barz with a single call. It creates the Barz contract with the givent verification facet\\n * @param _verificationFacet Address of verification facet used for creating the barz account\\n * @param _owner Public Key of the owner to initialize barz account\\n * @param _salt Salt used for deploying barz with create2\\n * @return barz Instance of Barz contract deployed with the given parameters\\n */\\n function createAccount(\\n address _verificationFacet,\\n bytes calldata _owner,\\n uint256 _salt\\n ) external override returns (Barz barz) {\\n address addr = getAddress(_verificationFacet, _owner, _salt);\\n uint codeSize = addr.code.length;\\n if (codeSize > 0) {\\n return Barz(payable(addr));\\n }\\n barz = new Barz{salt: bytes32(_salt)}(\\n accountFacet,\\n _verificationFacet,\\n entryPoint,\\n facetRegistry,\\n defaultFallback,\\n _owner\\n );\\n emit BarzDeployed(address(barz));\\n }\\n\\n /**\\n * @notice Calculates the address of Barz with the given parameters\\n * @param _verificationFacet Address of verification facet used for creating the barz account\\n * @param _owner Public Key of the owner to initialize barz account\\n * @param _salt Salt used for deploying barz with create2\\n * @return barzAddress Precalculated Barz address\\n */\\n function getAddress(\\n address _verificationFacet,\\n bytes calldata _owner,\\n uint256 _salt\\n ) public view override returns (address barzAddress) {\\n bytes memory bytecode = getBytecode(\\n accountFacet,\\n _verificationFacet,\\n entryPoint,\\n facetRegistry,\\n defaultFallback,\\n _owner\\n );\\n bytes32 hash = keccak256(\\n abi.encodePacked(\\n bytes1(0xff),\\n address(this),\\n _salt,\\n keccak256(bytecode)\\n )\\n );\\n barzAddress = address(uint160(uint256(hash)));\\n }\\n\\n /**\\n * @notice Returns the bytecode of Barz with the given parameter\\n * @param _accountFacet Account Facet to be used to create Barz\\n * @param _verificationFacet Verification Facet to be used to create Barz\\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\\n * @param _facetRegistry Facet Registry to be used to create Barz\\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\\n * @param _ownerPublicKey Public Key of owner to be used to initialize Barz ownership\\n * @return barzBytecode Bytecode of Barz\\n */\\n function getBytecode(\\n address _accountFacet,\\n address _verificationFacet,\\n address _entryPoint,\\n address _facetRegistry,\\n address _defaultFallback,\\n bytes calldata _ownerPublicKey\\n ) public pure override returns (bytes memory barzBytecode) {\\n bytes memory bytecode = type(Barz).creationCode;\\n barzBytecode = abi.encodePacked(\\n bytecode,\\n abi.encode(\\n _accountFacet,\\n _verificationFacet,\\n _entryPoint,\\n _facetRegistry,\\n _defaultFallback,\\n _ownerPublicKey\\n )\\n );\\n }\\n\\n /**\\n * @notice Returns the creation code of the Barz contract\\n * @return creationCode Creation code of Barz\\n */\\n function getCreationCode()\\n public\\n pure\\n override\\n returns (bytes memory creationCode)\\n {\\n creationCode = type(Barz).creationCode;\\n }\\n}\\n\",\"keccak256\":\"0x76d6058fa4714f5ef87b876e49ce7e21f581164901eea906ec743e82362b1df6\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IBarz.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Barz Interface\\n * @dev Interface of Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IBarz {\\n error Barz__InitializationFailure();\\n}\\n\",\"keccak256\":\"0xca9f0c2c1ad7d06088fa16ae92d587416f2d10d8f999d7afe8ca5c4d73410aba\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IBarzFactory.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {Barz} from \\\"../Barz.sol\\\";\\n\\n/**\\n * @title Barz Factory Interface\\n * @dev Interface of contract to easily deploy Barz to a pre-computed address with a single call\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IBarzFactory {\\n event BarzDeployed(address);\\n\\n function createAccount(\\n address verificationFacet,\\n bytes calldata owner,\\n uint256 salt\\n ) external returns (Barz);\\n\\n function getAddress(\\n address verificationFacet,\\n bytes calldata owner,\\n uint256 salt\\n ) external view returns (address);\\n\\n function getBytecode(\\n address accountFacet,\\n address verificationFacet,\\n address entryPoint,\\n address facetRegistry,\\n address defaultFallback,\\n bytes memory ownerPublicKey\\n ) external pure returns (bytes memory);\\n\\n function getCreationCode() external pure returns (bytes memory);\\n}\\n\",\"keccak256\":\"0xadb48a6f3025f6395e26ffd5f9319da73ad2383906c8223e8455f41f420fba26\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\\n bytes4(keccak256(\\\"verifyRestrictions(address,address,uint256,bytes)\\\"));\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // Default Fallback Handler of the barz.\\n IDiamondLoupe defaultFallbackHandler;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function enforceIsSelf() internal view {\\n require(msg.sender == address(this), \\\"LibDiamond: Caller not self\\\");\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n\\n unchecked {\\n facetIndex++;\\n }\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n\\n function restrictionsFacet() internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(\\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2cabdc00de859c3a3170ce3bda5d0e5fd3933d47ce904fd1585f9818b02572f8\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x61010060405234801561001157600080fd5b50604051610eba380380610eba8339810160408190526100309161006e565b6001600160a01b0393841660805291831660a052821660c0521660e0526100c2565b80516001600160a01b038116811461006957600080fd5b919050565b6000806000806080858703121561008457600080fd5b61008d85610052565b935061009b60208601610052565b92506100a960408601610052565b91506100b760608601610052565b905092959194509250565b60805160a05160c05160e051610d886101326000396000818161013b015281816102b3015261048101526000818160bf01528181610292015261046001526000818161016301528181610271015261043f01526000818161018b0152818161024f015261041d0152610d886000f3fe60806040523480156200001157600080fd5b5060043610620000925760003560e01c806344409a82116200006257806344409a821462000135578063b0d691fe146200015d578063b0f5d4641462000185578063c8a7adf514620001ad57600080fd5b8062c194db14620000975780630a1acd7314620000b9578063296601cd146200010757806333bb64a7146200011e575b600080fd5b620000a1620001c4565b604051620000b091906200056c565b60405180910390f35b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001620000b0565b620000e16200011836600462000635565b6200020e565b620000a16200012f36600462000695565b6200036d565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e1620001be36600462000635565b62000414565b606060405180602001620001d89062000538565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082820381018352601f90910116604052919050565b6000806200021f8686868662000414565b905073ffffffffffffffffffffffffffffffffffffffff81163b8015620002495750905062000365565b8360001b7f0000000000000000000000000000000000000000000000000000000000000000887f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008b8b604051620002e29062000538565b620002f497969594939291906200073a565b8190604051809103906000f590508015801562000315573d6000803e3d6000fd5b5060405173ffffffffffffffffffffffffffffffffffffffff821681529093507f9e6e326008e68f57877e2bae766a5745c162e42359e34834a7f0661fa82d31b19060200160405180910390a150505b949350505050565b6060600060405180602001620003839062000538565b6020820181038252601f19601f8201166040525090508089898989898989604051602001620003b997969594939291906200073a565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052620003f79291602001620007cd565b604051602081830303815290604052915050979650505050505050565b600080620004a87f0000000000000000000000000000000000000000000000000000000000000000877f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008a8a6200036d565b8051602091820120604080517fff00000000000000000000000000000000000000000000000000000000000000818501523060601b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001660218201526035810196909652605580870192909252805180870390920182526075909501909452835193019290922095945050505050565b610552806200080183390190565b60005b838110156200056357818101518382015260200162000549565b50506000910152565b60208152600082518060208401526200058d81604085016020870162000546565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b803573ffffffffffffffffffffffffffffffffffffffff81168114620005e457600080fd5b919050565b60008083601f840112620005fc57600080fd5b50813567ffffffffffffffff8111156200061557600080fd5b6020830191508360208285010111156200062e57600080fd5b9250929050565b600080600080606085870312156200064c57600080fd5b6200065785620005bf565b9350602085013567ffffffffffffffff8111156200067457600080fd5b6200068287828801620005e9565b9598909750949560400135949350505050565b600080600080600080600060c0888a031215620006b157600080fd5b620006bc88620005bf565b9650620006cc60208901620005bf565b9550620006dc60408901620005bf565b9450620006ec60608901620005bf565b9350620006fc60808901620005bf565b925060a088013567ffffffffffffffff8111156200071957600080fd5b620007278a828b01620005e9565b989b979a50959850939692959293505050565b600073ffffffffffffffffffffffffffffffffffffffff808a16835280891660208401528088166040840152808716606084015280861660808401525060c060a08301528260c0830152828460e0840137600060e0848401015260e07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f850116830101905098975050505050505050565b60008351620007e181846020880162000546565b835190830190620007f781836020880162000546565b0194935050505056fe608060405260405161055238038061055283398101604081905261002291610163565b6000858585858560405160240161003d959493929190610264565b60408051601f198184030181529181526020820180516001600160e01b0316634a93641760e01b1790525190915060009081906001600160a01b038a16906100869085906102c3565b600060405180830381855af49150503d80600081146100c1576040519150601f19603f3d011682016040523d82523d6000602084013e6100c6565b606091505b50915091508115806100e157506100dc816102df565b600114155b156100ff57604051636ff35f8960e01b815260040160405180910390fd5b505050505050505050610306565b80516001600160a01b038116811461012457600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101561015a578181015183820152602001610142565b50506000910152565b60008060008060008060c0878903121561017c57600080fd5b6101858761010d565b95506101936020880161010d565b94506101a16040880161010d565b93506101af6060880161010d565b92506101bd6080880161010d565b60a08801519092506001600160401b03808211156101da57600080fd5b818901915089601f8301126101ee57600080fd5b81518181111561020057610200610129565b604051601f8201601f19908116603f0116810190838211818310171561022857610228610129565b816040528281528c602084870101111561024157600080fd5b61025283602083016020880161013f565b80955050505050509295509295509295565b600060018060a01b0380881683528087166020840152808616604084015280851660608401525060a0608083015282518060a08401526102ab8160c085016020870161013f565b601f01601f19169190910160c0019695505050505050565b600082516102d581846020870161013f565b9190910192915050565b80516020808301519190811015610300576000198160200360031b1b821691505b50919050565b61023d806103156000396000f3fe60806040523661000b57005b600080357fffffffff000000000000000000000000000000000000000000000000000000001681527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020819052604090912054819060601c80610125576004838101546040517fcdffacc60000000000000000000000000000000000000000000000000000000081526000357fffffffff00000000000000000000000000000000000000000000000000000000169281019290925273ffffffffffffffffffffffffffffffffffffffff169063cdffacc690602401602060405180830381865afa1580156100fe573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061012291906101ca565b90505b73ffffffffffffffffffffffffffffffffffffffff81166101a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4261727a3a2046756e6374696f6e20646f6573206e6f74206578697374000000604482015260640160405180910390fd5b3660008037600080366000845af43d6000803e8080156101c5573d6000f35b3d6000fd5b6000602082840312156101dc57600080fd5b815173ffffffffffffffffffffffffffffffffffffffff8116811461020057600080fd5b939250505056fea26469706673582212200f3fa76ace3be8675d8b4c0d6c210a922fff2c2f1444023b817d1f6c908cd56a64736f6c63430008150033a2646970667358221220329ad45a4ef4915180001cb1fc90a5f97ad94a0b280426a580cba65fce28c0f164736f6c63430008150033", + "deployedBytecode": "0x60806040523480156200001157600080fd5b5060043610620000925760003560e01c806344409a82116200006257806344409a821462000135578063b0d691fe146200015d578063b0f5d4641462000185578063c8a7adf514620001ad57600080fd5b8062c194db14620000975780630a1acd7314620000b9578063296601cd146200010757806333bb64a7146200011e575b600080fd5b620000a1620001c4565b604051620000b091906200056c565b60405180910390f35b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001620000b0565b620000e16200011836600462000635565b6200020e565b620000a16200012f36600462000695565b6200036d565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e1620001be36600462000635565b62000414565b606060405180602001620001d89062000538565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082820381018352601f90910116604052919050565b6000806200021f8686868662000414565b905073ffffffffffffffffffffffffffffffffffffffff81163b8015620002495750905062000365565b8360001b7f0000000000000000000000000000000000000000000000000000000000000000887f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008b8b604051620002e29062000538565b620002f497969594939291906200073a565b8190604051809103906000f590508015801562000315573d6000803e3d6000fd5b5060405173ffffffffffffffffffffffffffffffffffffffff821681529093507f9e6e326008e68f57877e2bae766a5745c162e42359e34834a7f0661fa82d31b19060200160405180910390a150505b949350505050565b6060600060405180602001620003839062000538565b6020820181038252601f19601f8201166040525090508089898989898989604051602001620003b997969594939291906200073a565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052620003f79291602001620007cd565b604051602081830303815290604052915050979650505050505050565b600080620004a87f0000000000000000000000000000000000000000000000000000000000000000877f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008a8a6200036d565b8051602091820120604080517fff00000000000000000000000000000000000000000000000000000000000000818501523060601b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001660218201526035810196909652605580870192909252805180870390920182526075909501909452835193019290922095945050505050565b610552806200080183390190565b60005b838110156200056357818101518382015260200162000549565b50506000910152565b60208152600082518060208401526200058d81604085016020870162000546565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b803573ffffffffffffffffffffffffffffffffffffffff81168114620005e457600080fd5b919050565b60008083601f840112620005fc57600080fd5b50813567ffffffffffffffff8111156200061557600080fd5b6020830191508360208285010111156200062e57600080fd5b9250929050565b600080600080606085870312156200064c57600080fd5b6200065785620005bf565b9350602085013567ffffffffffffffff8111156200067457600080fd5b6200068287828801620005e9565b9598909750949560400135949350505050565b600080600080600080600060c0888a031215620006b157600080fd5b620006bc88620005bf565b9650620006cc60208901620005bf565b9550620006dc60408901620005bf565b9450620006ec60608901620005bf565b9350620006fc60808901620005bf565b925060a088013567ffffffffffffffff8111156200071957600080fd5b620007278a828b01620005e9565b989b979a50959850939692959293505050565b600073ffffffffffffffffffffffffffffffffffffffff808a16835280891660208401528088166040840152808716606084015280861660808401525060c060a08301528260c0830152828460e0840137600060e0848401015260e07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f850116830101905098975050505050505050565b60008351620007e181846020880162000546565b835190830190620007f781836020880162000546565b0194935050505056fe608060405260405161055238038061055283398101604081905261002291610163565b6000858585858560405160240161003d959493929190610264565b60408051601f198184030181529181526020820180516001600160e01b0316634a93641760e01b1790525190915060009081906001600160a01b038a16906100869085906102c3565b600060405180830381855af49150503d80600081146100c1576040519150601f19603f3d011682016040523d82523d6000602084013e6100c6565b606091505b50915091508115806100e157506100dc816102df565b600114155b156100ff57604051636ff35f8960e01b815260040160405180910390fd5b505050505050505050610306565b80516001600160a01b038116811461012457600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101561015a578181015183820152602001610142565b50506000910152565b60008060008060008060c0878903121561017c57600080fd5b6101858761010d565b95506101936020880161010d565b94506101a16040880161010d565b93506101af6060880161010d565b92506101bd6080880161010d565b60a08801519092506001600160401b03808211156101da57600080fd5b818901915089601f8301126101ee57600080fd5b81518181111561020057610200610129565b604051601f8201601f19908116603f0116810190838211818310171561022857610228610129565b816040528281528c602084870101111561024157600080fd5b61025283602083016020880161013f565b80955050505050509295509295509295565b600060018060a01b0380881683528087166020840152808616604084015280851660608401525060a0608083015282518060a08401526102ab8160c085016020870161013f565b601f01601f19169190910160c0019695505050505050565b600082516102d581846020870161013f565b9190910192915050565b80516020808301519190811015610300576000198160200360031b1b821691505b50919050565b61023d806103156000396000f3fe60806040523661000b57005b600080357fffffffff000000000000000000000000000000000000000000000000000000001681527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020819052604090912054819060601c80610125576004838101546040517fcdffacc60000000000000000000000000000000000000000000000000000000081526000357fffffffff00000000000000000000000000000000000000000000000000000000169281019290925273ffffffffffffffffffffffffffffffffffffffff169063cdffacc690602401602060405180830381865afa1580156100fe573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061012291906101ca565b90505b73ffffffffffffffffffffffffffffffffffffffff81166101a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4261727a3a2046756e6374696f6e20646f6573206e6f74206578697374000000604482015260640160405180910390fd5b3660008037600080366000845af43d6000803e8080156101c5573d6000f35b3d6000fd5b6000602082840312156101dc57600080fd5b815173ffffffffffffffffffffffffffffffffffffffff8116811461020057600080fd5b939250505056fea26469706673582212200f3fa76ace3be8675d8b4c0d6c210a922fff2c2f1444023b817d1f6c908cd56a64736f6c63430008150033a2646970667358221220329ad45a4ef4915180001cb1fc90a5f97ad94a0b280426a580cba65fce28c0f164736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "Contract to easily deploy Barz to a pre-computed address with a single call", + "kind": "dev", + "methods": { + "constructor": { + "params": { + "_accountFacet": "Account Facet to be used to create Barz", + "_defaultFallback": "Default Fallback Handler to be used to create Barz", + "_entryPoint": "Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF", + "_facetRegistry": "Facet Registry to be used to create Barz" + } + }, + "createAccount(address,bytes,uint256)": { + "params": { + "_owner": "Public Key of the owner to initialize barz account", + "_salt": "Salt used for deploying barz with create2", + "_verificationFacet": "Address of verification facet used for creating the barz account" + }, + "returns": { + "barz": "Instance of Barz contract deployed with the given parameters" + } + }, + "getAddress(address,bytes,uint256)": { + "params": { + "_owner": "Public Key of the owner to initialize barz account", + "_salt": "Salt used for deploying barz with create2", + "_verificationFacet": "Address of verification facet used for creating the barz account" + }, + "returns": { + "barzAddress": "Precalculated Barz address" + } + }, + "getBytecode(address,address,address,address,address,bytes)": { + "params": { + "_accountFacet": "Account Facet to be used to create Barz", + "_defaultFallback": "Default Fallback Handler to be used to create Barz", + "_entryPoint": "Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF", + "_facetRegistry": "Facet Registry to be used to create Barz", + "_ownerPublicKey": "Public Key of owner to be used to initialize Barz ownership", + "_verificationFacet": "Verification Facet to be used to create Barz" + }, + "returns": { + "barzBytecode": "Bytecode of Barz" + } + }, + "getCreationCode()": { + "returns": { + "creationCode": "Creation code of Barz" + } + } + }, + "title": "Barz Factory", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "constructor": { + "notice": "Sets the initialization data for Barz contract initialization" + }, + "createAccount(address,bytes,uint256)": { + "notice": "Creates the Barz with a single call. It creates the Barz contract with the givent verification facet" + }, + "getAddress(address,bytes,uint256)": { + "notice": "Calculates the address of Barz with the given parameters" + }, + "getBytecode(address,address,address,address,address,bytes)": { + "notice": "Returns the bytecode of Barz with the given parameter" + }, + "getCreationCode()": { + "notice": "Returns the creation code of the Barz contract" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/lightLink/DefaultFallbackHandler.json b/deployments/lightLink/DefaultFallbackHandler.json new file mode 100644 index 0000000..788789d --- /dev/null +++ b/deployments/lightLink/DefaultFallbackHandler.json @@ -0,0 +1,275 @@ +{ + "address": "0x2e7f1dAe1F3799d20f5c31bEFdc7A620f664728D", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_diamondCutFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_accountFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_tokenReceiverFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_diamondLoupeFacet", + "type": "address" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_initializationContractAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "InitializationFunctionReverted", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "indexed": false, + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "DiamondCut", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_functionSelector", + "type": "bytes4" + } + ], + "name": "facetAddress", + "outputs": [ + { + "internalType": "address", + "name": "facetAddress_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetAddresses", + "outputs": [ + { + "internalType": "address[]", + "name": "facetAddresses_", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_facet", + "type": "address" + } + ], + "name": "facetFunctionSelectors", + "outputs": [ + { + "internalType": "bytes4[]", + "name": "facetFunctionSelectors_", + "type": "bytes4[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facets", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondLoupe.Facet[]", + "name": "facets_", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0x2cd753de68ffe2ee2fc93f278f26a9fd637b910fa1afdfca3da08efc8643d326", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": "0x0000000000000000000000000000000000000000", + "transactionIndex": 0, + "gasUsed": "1439057", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000001000000000800002000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000", + "blockHash": "0x5351fa44b84a8ed92af48cff8c96bbeb6eb76eb98606302b568f4687fd57e54b", + "transactionHash": "0x2cd753de68ffe2ee2fc93f278f26a9fd637b910fa1afdfca3da08efc8643d326", + "logs": [ + { + "transactionIndex": 0, + "blockNumber": 72701577, + "transactionHash": "0x2cd753de68ffe2ee2fc93f278f26a9fd637b910fa1afdfca3da08efc8643d326", + "address": "0x2e7f1dAe1F3799d20f5c31bEFdc7A620f664728D", + "topics": [ + "0x8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb673" + ], + "data": "0x000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000580000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000000000000000000000000000000000003600000000000000000000000000b9504140771c3688ff041917192277d2f52e1e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000011f931c1c00000000000000000000000000000000000000000000000000000000000000000000000000000000fde53272dcd7938d16e031a6989753c321728332000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000005b61d27f60000000000000000000000000000000000000000000000000000000047e1da2a000000000000000000000000000000000000000000000000000000003a871cdd00000000000000000000000000000000000000000000000000000000d087d28800000000000000000000000000000000000000000000000000000000b0d691fe000000000000000000000000000000000000000000000000000000000000000000000000000000003143e1c0af0cdc153423863923cf4e3818e34daa000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000005150b7a0200000000000000000000000000000000000000000000000000000000f23a6e6100000000000000000000000000000000000000000000000000000000bc197c81000000000000000000000000000000000000000000000000000000000023de2900000000000000000000000000000000000000000000000000000000a4c0ed3600000000000000000000000000000000000000000000000000000000000000000000000000000000ce36b85d12d81cd619c745c7717f3396e184ac7c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000097a0ed62700000000000000000000000000000000000000000000000000000000adfca15e0000000000000000000000000000000000000000000000000000000052ef6b2c00000000000000000000000000000000000000000000000000000000cdffacc60000000000000000000000000000000000000000000000000000000001ffc9a700000000000000000000000000000000000000000000000000000000f9796ccf0000000000000000000000000000000000000000000000000000000001a5502200000000000000000000000000000000000000000000000000000000d42139a900000000000000000000000000000000000000000000000000000000e3a2f6fe000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "logIndex": 0, + "blockHash": "0x5351fa44b84a8ed92af48cff8c96bbeb6eb76eb98606302b568f4687fd57e54b" + } + ], + "blockNumber": 72701577, + "cumulativeGasUsed": "1439057", + "status": 1, + "byzantium": true + }, + "args": [ + "0x0B9504140771C3688Ff041917192277D2f52E1e0", + "0xFde53272dcd7938d16E031A6989753c321728332", + "0x3143E1C0Af0Cdc153423863923Cf4e3818e34Daa", + "0xCe36b85d12D81cd619C745c7717f3396E184Ac7C" + ], + "numDeployments": 1, + "solcInputHash": "ad34345aa73d96f52b3e14df983b6b29", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_diamondCutFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_accountFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_tokenReceiverFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_diamondLoupeFacet\",\"type\":\"address\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_initializationContractAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"InitializationFunctionReverted\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"DiamondCut\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_functionSelector\",\"type\":\"bytes4\"}],\"name\":\"facetAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"facetAddress_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetAddresses\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"facetAddresses_\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_facet\",\"type\":\"address\"}],\"name\":\"facetFunctionSelectors\",\"outputs\":[{\"internalType\":\"bytes4[]\",\"name\":\"facetFunctionSelectors_\",\"type\":\"bytes4[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facets\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondLoupe.Facet[]\",\"name\":\"facets_\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"A default fallback handler for Barz\",\"kind\":\"dev\",\"methods\":{\"constructor\":{\"details\":\"This contract is also a diamond that holds the default facets to reduce gas cost for wallet activation. Within the constructor this conducts diamond cut to initially setup the diamond. This is a non-upgradeable contract\",\"params\":{\"_accountFacet\":\"Address account facet\",\"_diamondCutFacet\":\"Address if diamond cut facet\",\"_diamondLoupeFacet\":\"Address of diamond loupe facet\",\"_tokenReceiverFacet\":\"Address of token receiver facet\"}},\"facetAddress(bytes4)\":{\"details\":\"If facet is not found return address(0).\",\"params\":{\"_functionSelector\":\"The function selector.\"},\"returns\":{\"facetAddress_\":\"The facet address.\"}},\"facetAddresses()\":{\"returns\":{\"facetAddresses_\":\"facetAddresses_\"}},\"facetFunctionSelectors(address)\":{\"params\":{\"_facet\":\"The facet address.\"},\"returns\":{\"facetFunctionSelectors_\":\"facetFunctionSelectors_\"}},\"facets()\":{\"returns\":{\"facets_\":\"The facet struct array including all facet information\"}}},\"title\":\"DefaultFallbackHandler\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"Sets the middleware diamond for Barz wallet as a fallback handler\"},\"facetAddress(bytes4)\":{\"notice\":\"Gets the facet that supports the given selector.\"},\"facetAddresses()\":{\"notice\":\"Get all the facet addresses used by a diamond.\"},\"facetFunctionSelectors(address)\":{\"notice\":\"Gets all the function selectors provided by a facet.\"},\"facets()\":{\"notice\":\"Returns the facet information of call facets registered to this diamond.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/infrastructure/DefaultFallbackHandler.sol\":\"DefaultFallbackHandler\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/introspection/IERC165.sol\\\";\\n\\n/**\\n * @dev _Available since v3.1._\\n */\\ninterface IERC1155Receiver is IERC165 {\\n /**\\n * @dev Handles the receipt of a single ERC1155 token type. This function is\\n * called at the end of a `safeTransferFrom` after the balance has been updated.\\n *\\n * NOTE: To accept the transfer, this must return\\n * `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))`\\n * (i.e. 0xf23a6e61, or its own function selector).\\n *\\n * @param operator The address which initiated the transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param id The ID of the token being transferred\\n * @param value The amount of tokens being transferred\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155Received(\\n address operator,\\n address from,\\n uint256 id,\\n uint256 value,\\n bytes calldata data\\n ) external returns (bytes4);\\n\\n /**\\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\\n * is called at the end of a `safeBatchTransferFrom` after the balances have\\n * been updated.\\n *\\n * NOTE: To accept the transfer(s), this must return\\n * `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))`\\n * (i.e. 0xbc197c81, or its own function selector).\\n *\\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155BatchReceived(\\n address operator,\\n address from,\\n uint256[] calldata ids,\\n uint256[] calldata values,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xeb373f1fdc7b755c6a750123a9b9e3a8a02c1470042fd6505d875000a80bde0b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title ERC721 token receiver interface\\n * @dev Interface for any contract that wants to support safeTransfers\\n * from ERC721 asset contracts.\\n */\\ninterface IERC721Receiver {\\n /**\\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\\n * by `operator` from `from`, this function is called.\\n *\\n * It must return its Solidity selector to confirm the token transfer.\\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\\n *\\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\\n */\\n function onERC721Received(\\n address operator,\\n address from,\\n uint256 tokenId,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\\n *\\n * Accounts can be notified of {IERC777} tokens being sent to them by having a\\n * contract implement this interface (contract holders can be their own\\n * implementer) and registering it on the\\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\\n *\\n * See {IERC1820Registry} and {ERC1820Implementer}.\\n */\\ninterface IERC777Recipient {\\n /**\\n * @dev Called by an {IERC777} token contract whenever tokens are being\\n * moved or created into a registered account (`to`). The type of operation\\n * is conveyed by `from` being the zero address or not.\\n *\\n * This call occurs _after_ the token contract's state is updated, so\\n * {IERC777-balanceOf}, etc., can be used to query the post-operation state.\\n *\\n * This function may revert to prevent the operation from being executed.\\n */\\n function tokensReceived(\\n address operator,\\n address from,\\n address to,\\n uint256 amount,\\n bytes calldata userData,\\n bytes calldata operatorData\\n ) external;\\n}\\n\",\"keccak256\":\"0x1a5d61db2733202ba361e6d6741cd2e662380e22b80e987eacfc91973f2267dc\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"contracts/aa-4337/core/BaseAccount.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-empty-blocks */\\n\\nimport \\\"../interfaces/IAccount.sol\\\";\\nimport \\\"../interfaces/IEntryPoint.sol\\\";\\nimport \\\"./Helpers.sol\\\";\\n\\n/**\\n * Basic account implementation.\\n * this contract provides the basic logic for implementing the IAccount interface - validateUserOp\\n * specific account implementation should inherit it and provide the account-specific logic\\n */\\nabstract contract BaseAccount is IAccount {\\n using UserOperationLib for UserOperation;\\n\\n //return value in case of signature failure, with no time-range.\\n // equivalent to _packValidationData(true,0,0);\\n uint256 internal constant SIG_VALIDATION_FAILED = 1;\\n\\n /**\\n * Return the account nonce.\\n * This method returns the next sequential nonce.\\n * For a nonce of a specific key, use `entrypoint.getNonce(account, key)`\\n */\\n function getNonce() public view virtual returns (uint256) {\\n return entryPoint().getNonce(address(this), 0);\\n }\\n\\n /**\\n * return the entryPoint used by this account.\\n * subclass should return the current entryPoint used by this account.\\n */\\n function entryPoint() public view virtual returns (IEntryPoint);\\n\\n /**\\n * Validate user's signature and nonce.\\n * subclass doesn't need to override this method. Instead, it should override the specific internal validation methods.\\n */\\n function validateUserOp(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n uint256 missingAccountFunds\\n ) external virtual override returns (uint256 validationData) {\\n _requireFromEntryPoint();\\n validationData = _validateSignature(userOp, userOpHash);\\n _validateNonce(userOp.nonce);\\n _payPrefund(missingAccountFunds);\\n }\\n\\n /**\\n * ensure the request comes from the known entrypoint.\\n */\\n function _requireFromEntryPoint() internal view virtual {\\n require(\\n msg.sender == address(entryPoint()),\\n \\\"account: not from EntryPoint\\\"\\n );\\n }\\n\\n /**\\n * validate the signature is valid for this message.\\n * @param userOp validate the userOp.signature field\\n * @param userOpHash convenient field: the hash of the request, to check the signature against\\n * (also hashes the entrypoint and chain id)\\n * @return validationData signature and time-range of this operation\\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\\n * otherwise, an address of an \\\"authorizer\\\" contract.\\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \\\"indefinite\\\"\\n * <6-byte> validAfter - first timestamp this operation is valid\\n * If the account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\\n */\\n function _validateSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) internal virtual returns (uint256 validationData);\\n\\n /**\\n * Validate the nonce of the UserOperation.\\n * This method may validate the nonce requirement of this account.\\n * e.g.\\n * To limit the nonce to use sequenced UserOps only (no \\\"out of order\\\" UserOps):\\n * `require(nonce < type(uint64).max)`\\n * For a hypothetical account that *requires* the nonce to be out-of-order:\\n * `require(nonce & type(uint64).max == 0)`\\n *\\n * The actual nonce uniqueness is managed by the EntryPoint, and thus no other\\n * action is needed by the account itself.\\n *\\n * @param nonce to validate\\n *\\n * solhint-disable-next-line no-empty-blocks\\n */\\n function _validateNonce(uint256 nonce) internal view virtual {}\\n\\n /**\\n * sends to the entrypoint (msg.sender) the missing funds for this transaction.\\n * subclass MAY override this method for better funds management\\n * (e.g. send to the entryPoint more than the minimum required, so that in future transactions\\n * it will not be required to send again)\\n * @param missingAccountFunds the minimum value this method should send the entrypoint.\\n * this value MAY be zero, in case there is enough deposit, or the userOp has a paymaster.\\n */\\n function _payPrefund(uint256 missingAccountFunds) internal virtual {\\n if (missingAccountFunds != 0) {\\n (bool success, ) = payable(msg.sender).call{\\n value: missingAccountFunds,\\n gas: type(uint256).max\\n }(\\\"\\\");\\n (success);\\n //ignore failure (its EntryPoint's job to verify, not account.)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa0dcc386b0f04711db3e394fb50e55a3b3b1a4d19fac1f10895844e1aa4e3d5c\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/core/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable no-inline-assembly */\\n\\n/**\\n * returned data from validateUserOp.\\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\\n * @param aggregator - address(0) - the account validated the signature by itself.\\n * address(1) - the account failed to validate the signature.\\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\\n * @param validAfter - this UserOp is valid only after this timestamp.\\n * @param validaUntil - this UserOp is valid only up to this timestamp.\\n */\\nstruct ValidationData {\\n address aggregator;\\n uint48 validAfter;\\n uint48 validUntil;\\n}\\n\\n//extract sigFailed, validAfter, validUntil.\\n// also convert zero validUntil to type(uint48).max\\nfunction _parseValidationData(\\n uint validationData\\n) pure returns (ValidationData memory data) {\\n address aggregator = address(uint160(validationData));\\n uint48 validUntil = uint48(validationData >> 160);\\n if (validUntil == 0) {\\n validUntil = type(uint48).max;\\n }\\n uint48 validAfter = uint48(validationData >> (48 + 160));\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n// intersect account and paymaster ranges.\\nfunction _intersectTimeRange(\\n uint256 validationData,\\n uint256 paymasterValidationData\\n) pure returns (ValidationData memory) {\\n ValidationData memory accountValidationData = _parseValidationData(\\n validationData\\n );\\n ValidationData memory pmValidationData = _parseValidationData(\\n paymasterValidationData\\n );\\n address aggregator = accountValidationData.aggregator;\\n if (aggregator == address(0)) {\\n aggregator = pmValidationData.aggregator;\\n }\\n uint48 validAfter = accountValidationData.validAfter;\\n uint48 validUntil = accountValidationData.validUntil;\\n uint48 pmValidAfter = pmValidationData.validAfter;\\n uint48 pmValidUntil = pmValidationData.validUntil;\\n\\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp\\n * @param data - the ValidationData to pack\\n */\\nfunction _packValidationData(\\n ValidationData memory data\\n) pure returns (uint256) {\\n return\\n uint160(data.aggregator) |\\n (uint256(data.validUntil) << 160) |\\n (uint256(data.validAfter) << (160 + 48));\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp, when not using an aggregator\\n * @param sigFailed - true for signature failure, false for success\\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\\n * @param validAfter first timestamp this UserOperation is valid\\n */\\nfunction _packValidationData(\\n bool sigFailed,\\n uint48 validUntil,\\n uint48 validAfter\\n) pure returns (uint256) {\\n return\\n (sigFailed ? 1 : 0) |\\n (uint256(validUntil) << 160) |\\n (uint256(validAfter) << (160 + 48));\\n}\\n\\n/**\\n * keccak function over calldata.\\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\\n */\\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\\n assembly {\\n let mem := mload(0x40)\\n let len := data.length\\n calldatacopy(mem, data.offset, len)\\n ret := keccak256(mem, len)\\n }\\n}\\n\",\"keccak256\":\"0xa79f06cd158ecb8c0da95493a2f348933b8627a63e228b99738bff3aa107942d\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAccount.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\ninterface IAccount {\\n /**\\n * Validate user's signature and nonce\\n * the entryPoint will make the call to the recipient only if this validation call returns successfully.\\n * signature failure should be reported by returning SIG_VALIDATION_FAILED (1).\\n * This allows making a \\\"simulation call\\\" without a valid signature\\n * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure.\\n *\\n * @dev Must validate caller is the entryPoint.\\n * Must validate the signature and nonce\\n * @param userOp the operation that is about to be executed.\\n * @param userOpHash hash of the user's request data. can be used as the basis for signature.\\n * @param missingAccountFunds missing funds on the account's deposit in the entrypoint.\\n * This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call.\\n * The excess is left as a deposit in the entrypoint, for future calls.\\n * can be withdrawn anytime using \\\"entryPoint.withdrawTo()\\\"\\n * In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero.\\n * @return validationData packaged ValidationData structure. use `_packValidationData` and `_unpackValidationData` to encode and decode\\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\\n * otherwise, an address of an \\\"authorizer\\\" contract.\\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \\\"indefinite\\\"\\n * <6-byte> validAfter - first timestamp this operation is valid\\n * If an account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\\n */\\n function validateUserOp(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n uint256 missingAccountFunds\\n ) external returns (uint256 validationData);\\n}\\n\",\"keccak256\":\"0xcbc4b0973cf954c5895b7796335f651fbfcfb55f67dfa789a3d354f8e23c4f2b\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAggregator.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\n/**\\n * Aggregated Signatures validator.\\n */\\ninterface IAggregator {\\n /**\\n * validate aggregated signature.\\n * revert if the aggregated signature does not match the given list of operations.\\n */\\n function validateSignatures(\\n UserOperation[] calldata userOps,\\n bytes calldata signature\\n ) external view;\\n\\n /**\\n * validate signature of a single userOp\\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\\n * @param userOp the userOperation received from the user.\\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\\n * (usually empty, unless account and aggregator support some kind of \\\"multisig\\\"\\n */\\n function validateUserOpSignature(\\n UserOperation calldata userOp\\n ) external view returns (bytes memory sigForUserOp);\\n\\n /**\\n * aggregate multiple signatures into a single value.\\n * This method is called off-chain to calculate the signature to pass with handleOps()\\n * bundler MAY use optimized custom code perform this aggregation\\n * @param userOps array of UserOperations to collect the signatures from.\\n * @return aggregatedSignature the aggregated signature\\n */\\n function aggregateSignatures(\\n UserOperation[] calldata userOps\\n ) external view returns (bytes memory aggregatedSignature);\\n}\\n\",\"keccak256\":\"0xdfdcd80568f037716674619b31be630fcd8316262f05a815b41d1e81782c966a\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IEntryPoint.sol\":{\"content\":\"/**\\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\\n ** Only one instance required on each chain.\\n **/\\n// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-inline-assembly */\\n/* solhint-disable reason-string */\\n\\nimport \\\"./UserOperation.sol\\\";\\nimport \\\"./IStakeManager.sol\\\";\\nimport \\\"./IAggregator.sol\\\";\\nimport \\\"./INonceManager.sol\\\";\\n\\ninterface IEntryPoint is IStakeManager, INonceManager {\\n /***\\n * An event emitted after each successful request\\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\\n * @param sender - the account that generates this request.\\n * @param paymaster - if non-null, the paymaster that pays for this request.\\n * @param nonce - the nonce value from the request.\\n * @param success - true if the sender transaction succeeded, false if reverted.\\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\\n */\\n event UserOperationEvent(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address indexed paymaster,\\n uint256 nonce,\\n bool success,\\n uint256 actualGasCost,\\n uint256 actualGasUsed\\n );\\n\\n /**\\n * account \\\"sender\\\" was deployed.\\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\\n * @param sender the account that is deployed\\n * @param factory the factory used to deploy this account (in the initCode)\\n * @param paymaster the paymaster used by this UserOp\\n */\\n event AccountDeployed(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address factory,\\n address paymaster\\n );\\n\\n /**\\n * An event emitted if the UserOperation \\\"callData\\\" reverted with non-zero length\\n * @param userOpHash the request unique identifier.\\n * @param sender the sender of this request\\n * @param nonce the nonce used in the request\\n * @param revertReason - the return bytes from the (reverted) call to \\\"callData\\\".\\n */\\n event UserOperationRevertReason(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n uint256 nonce,\\n bytes revertReason\\n );\\n\\n /**\\n * an event emitted by handleOps(), before starting the execution loop.\\n * any event emitted before this event, is part of the validation.\\n */\\n event BeforeExecution();\\n\\n /**\\n * signature aggregator used by the following UserOperationEvents within this bundle.\\n */\\n event SignatureAggregatorChanged(address indexed aggregator);\\n\\n /**\\n * a custom revert error of handleOps, to identify the offending op.\\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\\n * @param reason - revert reason\\n * The string starts with a unique code \\\"AAmn\\\", where \\\"m\\\" is \\\"1\\\" for factory, \\\"2\\\" for account and \\\"3\\\" for paymaster issues,\\n * so a failure can be attributed to the correct entity.\\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\\n */\\n error FailedOp(uint256 opIndex, string reason);\\n\\n /**\\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\\n */\\n error SignatureValidationFailed(address aggregator);\\n\\n /**\\n * Successful result from simulateValidation.\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n */\\n error ValidationResult(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo\\n );\\n\\n /**\\n * Successful result from simulateValidation, if the account returns a signature aggregator\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\\n * bundler MUST use it to verify the signature, or reject the UserOperation\\n */\\n error ValidationResultWithAggregation(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo,\\n AggregatorStakeInfo aggregatorInfo\\n );\\n\\n /**\\n * return value of getSenderAddress\\n */\\n error SenderAddressResult(address sender);\\n\\n /**\\n * return value of simulateHandleOp\\n */\\n error ExecutionResult(\\n uint256 preOpGas,\\n uint256 paid,\\n uint48 validAfter,\\n uint48 validUntil,\\n bool targetSuccess,\\n bytes targetResult\\n );\\n\\n //UserOps handled, per aggregator\\n struct UserOpsPerAggregator {\\n UserOperation[] userOps;\\n // aggregator address\\n IAggregator aggregator;\\n // aggregated signature\\n bytes signature;\\n }\\n\\n /**\\n * Execute a batch of UserOperation.\\n * no signature aggregator is used.\\n * if any account requires an aggregator (that is, it returned an aggregator when\\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\\n * @param ops the operations to execute\\n * @param beneficiary the address to receive the fees\\n */\\n function handleOps(\\n UserOperation[] calldata ops,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * Execute a batch of UserOperation with Aggregators\\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\\n * @param beneficiary the address to receive the fees\\n */\\n function handleAggregatedOps(\\n UserOpsPerAggregator[] calldata opsPerAggregator,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * generate a request Id - unique identifier for this request.\\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\\n */\\n function getUserOpHash(\\n UserOperation calldata userOp\\n ) external view returns (bytes32);\\n\\n /**\\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\\n * @param userOp the user operation to validate.\\n */\\n function simulateValidation(UserOperation calldata userOp) external;\\n\\n /**\\n * gas and return values during simulation\\n * @param preOpGas the gas used for validation (including preValidationGas)\\n * @param prefund the required prefund for this operation\\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\\n */\\n struct ReturnInfo {\\n uint256 preOpGas;\\n uint256 prefund;\\n bool sigFailed;\\n uint48 validAfter;\\n uint48 validUntil;\\n bytes paymasterContext;\\n }\\n\\n /**\\n * returned aggregated signature info.\\n * the aggregator returned by the account, and its current stake.\\n */\\n struct AggregatorStakeInfo {\\n address aggregator;\\n StakeInfo stakeInfo;\\n }\\n\\n /**\\n * Get counterfactual sender address.\\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\\n * this method always revert, and returns the address in SenderAddressResult error\\n * @param initCode the constructor code to be passed into the UserOperation.\\n */\\n function getSenderAddress(bytes memory initCode) external;\\n\\n /**\\n * simulate full execution of a UserOperation (including both validation and target execution)\\n * this method will always revert with \\\"ExecutionResult\\\".\\n * it performs full validation of the UserOperation, but ignores signature error.\\n * an optional target address is called after the userop succeeds, and its value is returned\\n * (before the entire call is reverted)\\n * Note that in order to collect the the success/failure of the target call, it must be executed\\n * with trace enabled to track the emitted events.\\n * @param op the UserOperation to simulate\\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\\n * are set to the return from that call.\\n * @param targetCallData callData to pass to target address\\n */\\n function simulateHandleOp(\\n UserOperation calldata op,\\n address target,\\n bytes calldata targetCallData\\n ) external;\\n}\\n\",\"keccak256\":\"0x9ccb1b188eda8bbf5f6c2d01bd83c3d8b2b04fcf745283051d31fe96d1d8e40f\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/INonceManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\ninterface INonceManager {\\n /**\\n * Return the next nonce for this sender.\\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\\n * But UserOp with different keys can come with arbitrary order.\\n *\\n * @param sender the account address\\n * @param key the high 192 bit of the nonce\\n * @return nonce a full nonce to pass for next UserOp with this sender.\\n */\\n function getNonce(\\n address sender,\\n uint192 key\\n ) external view returns (uint256 nonce);\\n\\n /**\\n * Manually increment the nonce of the sender.\\n * This method is exposed just for completeness..\\n * Account does NOT need to call it, neither during validation, nor elsewhere,\\n * as the EntryPoint will update the nonce regardless.\\n * Possible use-case is call it with various keys to \\\"initialize\\\" their nonces to one, so that future\\n * UserOperations will not pay extra for the first transaction with a given key.\\n */\\n function incrementNonce(uint192 key) external;\\n}\\n\",\"keccak256\":\"0xce478ad0fa0d18a3b785ac854623029e7ab463d05873dfaa365abfa1bf100912\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IStakeManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8.12;\\n\\n/**\\n * manage deposits and stakes.\\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\\n * stake is value locked for at least \\\"unstakeDelay\\\" by the staked entity.\\n */\\ninterface IStakeManager {\\n event Deposited(address indexed account, uint256 totalDeposit);\\n\\n event Withdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /// Emitted when stake or unstake delay are modified\\n event StakeLocked(\\n address indexed account,\\n uint256 totalStaked,\\n uint256 unstakeDelaySec\\n );\\n\\n /// Emitted once a stake is scheduled for withdrawal\\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\\n\\n event StakeWithdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /**\\n * @param deposit the entity's deposit\\n * @param staked true if this entity is staked.\\n * @param stake actual amount of ether staked for this entity.\\n * @param unstakeDelaySec minimum delay to withdraw the stake.\\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\\n * and the rest fit into a 2nd cell.\\n * 112 bit allows for 10^15 eth\\n * 48 bit for full timestamp\\n * 32 bit allows 150 years for unstake delay\\n */\\n struct DepositInfo {\\n uint112 deposit;\\n bool staked;\\n uint112 stake;\\n uint32 unstakeDelaySec;\\n uint48 withdrawTime;\\n }\\n\\n //API struct used by getStakeInfo and simulateValidation\\n struct StakeInfo {\\n uint256 stake;\\n uint256 unstakeDelaySec;\\n }\\n\\n /// @return info - full deposit information of given account\\n function getDepositInfo(\\n address account\\n ) external view returns (DepositInfo memory info);\\n\\n /// @return the deposit (for gas payment) of the account\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * add to the deposit of the given account\\n */\\n function depositTo(address account) external payable;\\n\\n /**\\n * add to the account's stake - amount and delay\\n * any pending unstake is first cancelled.\\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\\n */\\n function addStake(uint32 _unstakeDelaySec) external payable;\\n\\n /**\\n * attempt to unlock the stake.\\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\\n */\\n function unlockStake() external;\\n\\n /**\\n * withdraw from the (unlocked) stake.\\n * must first call unlockStake and wait for the unstakeDelay to pass\\n * @param withdrawAddress the address to send withdrawn value.\\n */\\n function withdrawStake(address payable withdrawAddress) external;\\n\\n /**\\n * withdraw from the deposit.\\n * @param withdrawAddress the address to send withdrawn value.\\n * @param withdrawAmount the amount to withdraw.\\n */\\n function withdrawTo(\\n address payable withdrawAddress,\\n uint256 withdrawAmount\\n ) external;\\n}\\n\",\"keccak256\":\"0xadcea606c9b7aafe6645441f2154a60f271330b0eee5292a632aa71c1672d546\",\"license\":\"GPL-3.0-only\"},\"contracts/aa-4337/interfaces/UserOperation.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable no-inline-assembly */\\n\\nimport {calldataKeccak} from \\\"../core/Helpers.sol\\\";\\n\\n/**\\n * User Operation struct\\n * @param sender the sender account of this request.\\n * @param nonce unique value the sender uses to verify it is not a replay.\\n * @param initCode if set, the account contract will be created by this constructor/\\n * @param callData the method call to execute on this account.\\n * @param callGasLimit the gas limit passed to the callData method call.\\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\\n * @param maxFeePerGas same as EIP-1559 gas parameter.\\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\\n */\\nstruct UserOperation {\\n address sender;\\n uint256 nonce;\\n bytes initCode;\\n bytes callData;\\n uint256 callGasLimit;\\n uint256 verificationGasLimit;\\n uint256 preVerificationGas;\\n uint256 maxFeePerGas;\\n uint256 maxPriorityFeePerGas;\\n bytes paymasterAndData;\\n bytes signature;\\n}\\n\\n/**\\n * Utility functions helpful when working with UserOperation structs.\\n */\\nlibrary UserOperationLib {\\n function getSender(\\n UserOperation calldata userOp\\n ) internal pure returns (address) {\\n address data;\\n //read sender from userOp, which is first userOp member (saves 800 gas...)\\n assembly {\\n data := calldataload(userOp)\\n }\\n return address(uint160(data));\\n }\\n\\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\\n // pay above what he signed for.\\n function gasPrice(\\n UserOperation calldata userOp\\n ) internal view returns (uint256) {\\n unchecked {\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n if (maxFeePerGas == maxPriorityFeePerGas) {\\n //legacy mode (for networks that don't support basefee opcode)\\n return maxFeePerGas;\\n }\\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\\n }\\n }\\n\\n function pack(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes memory ret) {\\n address sender = getSender(userOp);\\n uint256 nonce = userOp.nonce;\\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\\n bytes32 hashCallData = calldataKeccak(userOp.callData);\\n uint256 callGasLimit = userOp.callGasLimit;\\n uint256 verificationGasLimit = userOp.verificationGasLimit;\\n uint256 preVerificationGas = userOp.preVerificationGas;\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\\n\\n return\\n abi.encode(\\n sender,\\n nonce,\\n hashInitCode,\\n hashCallData,\\n callGasLimit,\\n verificationGasLimit,\\n preVerificationGas,\\n maxFeePerGas,\\n maxPriorityFeePerGas,\\n hashPaymasterAndData\\n );\\n }\\n\\n function hash(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes32) {\\n return keccak256(pack(userOp));\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n}\\n\",\"keccak256\":\"0x2429f5cc546bdee08c7e63858d0dda8491eaa3ab5194df884dc948c1154d2834\",\"license\":\"GPL-3.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IStorageLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"./IDiamondLoupe.sol\\\";\\n\\n/**\\n * @title LoupeFromStorage Interface\\n * @dev Interface contract to function as a loupe facet directly attached to diamond storage of Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IStorageLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facetsFromStorage()\\n external\\n view\\n returns (IDiamondLoupe.Facet[] memory);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n function facetFunctionSelectorsFromStorage(\\n address _facet\\n ) external view returns (bytes4[] memory);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n function facetAddressesFromStorage()\\n external\\n view\\n returns (address[] memory);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n function facetAddressFromStorage(\\n bytes4 _functionSelector\\n ) external view returns (address);\\n}\\n\",\"keccak256\":\"0xdf5dc9c57319e9087628c9cf9404b4f75585b76d1c2f4f59ee796c933967ea5c\",\"license\":\"Apache-2.0\"},\"contracts/facets/interfaces/IAccountFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IEntryPoint} from \\\"../../aa-4337/interfaces/IEntryPoint.sol\\\";\\n\\n/**\\n * @title Account Facet Interface\\n * @dev Interface of module contract that provides the account features and init/unitialization of signer\\n * compatible with EIP-1271 & EIP-4337\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IAccountFacet {\\n event AccountInitialized(\\n IEntryPoint indexed entryPoint,\\n bytes indexed ownerPublicKey\\n );\\n // NOTE: Added Below Event\\n event VerificationSuccess(bytes32);\\n event VerificationFailure(bytes32);\\n\\n error AccountFacet__InitializationFailure();\\n error AccountFacet__RestrictionsFailure();\\n error AccountFacet__NonExistentVerificationFacet();\\n error AccountFacet__CallNotSuccessful();\\n error AccountFacet__InvalidArrayLength();\\n\\n function initialize(\\n address verificationFacet,\\n address anEntryPoint,\\n address facetRegistry,\\n address _defaultFallBack,\\n bytes calldata _ownerPublicKey\\n ) external returns (uint256);\\n\\n function execute(address dest, uint256 value, bytes calldata func) external;\\n\\n function executeBatch(\\n address[] calldata dest,\\n uint256[] calldata value,\\n bytes[] calldata func\\n ) external;\\n}\\n\",\"keccak256\":\"0x74a9cb0b8f2f4a5148e366a401a0354426c536c012c025025d07cc25a4cd5382\",\"license\":\"Apache-2.0\"},\"contracts/infrastructure/DefaultFallbackHandler.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IERC721Receiver} from \\\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\\\";\\nimport {IERC1155Receiver} from \\\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\\\";\\nimport {IERC777Recipient} from \\\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\\\";\\nimport {BaseAccount} from \\\"../aa-4337/core/BaseAccount.sol\\\";\\nimport {DefaultLibDiamond} from \\\"../libraries/DefaultLibDiamond.sol\\\";\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IAccountFacet} from \\\"../facets/interfaces/IAccountFacet.sol\\\";\\nimport {IStorageLoupe} from \\\"../facets/base/interfaces/IStorageLoupe.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\nimport {IERC677Receiver} from \\\"../interfaces/ERC/IERC677Receiver.sol\\\";\\nimport {IERC165} from \\\"../interfaces/ERC/IERC165.sol\\\";\\n\\n/**\\n * @title DefaultFallbackHandler\\n * @dev A default fallback handler for Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract DefaultFallbackHandler is IDiamondLoupe {\\n /**\\n * @notice Sets the middleware diamond for Barz wallet as a fallback handler\\n * @dev This contract is also a diamond that holds the default facets to reduce gas cost for wallet activation.\\n * Within the constructor this conducts diamond cut to initially setup the diamond. This is a non-upgradeable contract\\n * @param _diamondCutFacet Address if diamond cut facet\\n * @param _accountFacet Address account facet\\n * @param _tokenReceiverFacet Address of token receiver facet\\n * @param _diamondLoupeFacet Address of diamond loupe facet\\n */\\n constructor(\\n address _diamondCutFacet,\\n address _accountFacet,\\n address _tokenReceiverFacet,\\n address _diamondLoupeFacet\\n ) payable {\\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](4);\\n bytes4[] memory functionSelectors = new bytes4[](1);\\n functionSelectors[0] = IDiamondCut.diamondCut.selector;\\n\\n bytes4[] memory accountFunctionSelectors = new bytes4[](5);\\n accountFunctionSelectors[0] = IAccountFacet.execute.selector;\\n accountFunctionSelectors[1] = IAccountFacet.executeBatch.selector;\\n accountFunctionSelectors[2] = BaseAccount.validateUserOp.selector;\\n accountFunctionSelectors[3] = BaseAccount.getNonce.selector;\\n accountFunctionSelectors[4] = BaseAccount.entryPoint.selector;\\n\\n bytes4[] memory receiverFacetSelectors = new bytes4[](5);\\n receiverFacetSelectors[0] = IERC721Receiver.onERC721Received.selector;\\n receiverFacetSelectors[1] = IERC1155Receiver.onERC1155Received.selector;\\n receiverFacetSelectors[2] = IERC1155Receiver\\n .onERC1155BatchReceived\\n .selector;\\n receiverFacetSelectors[3] = IERC777Recipient.tokensReceived.selector;\\n receiverFacetSelectors[4] = IERC677Receiver.onTokenTransfer.selector;\\n\\n bytes4[] memory loupeFacetSelectors = new bytes4[](9);\\n loupeFacetSelectors[0] = IDiamondLoupe.facets.selector;\\n loupeFacetSelectors[1] = IDiamondLoupe.facetFunctionSelectors.selector;\\n loupeFacetSelectors[2] = IDiamondLoupe.facetAddresses.selector;\\n loupeFacetSelectors[3] = IDiamondLoupe.facetAddress.selector;\\n loupeFacetSelectors[4] = IERC165.supportsInterface.selector;\\n loupeFacetSelectors[5] = IStorageLoupe.facetsFromStorage.selector;\\n loupeFacetSelectors[6] = IStorageLoupe\\n .facetFunctionSelectorsFromStorage\\n .selector;\\n loupeFacetSelectors[7] = IStorageLoupe\\n .facetAddressesFromStorage\\n .selector;\\n loupeFacetSelectors[8] = IStorageLoupe.facetAddressFromStorage.selector;\\n\\n {\\n cut[0] = IDiamondCut.FacetCut({\\n facetAddress: _diamondCutFacet,\\n action: IDiamondCut.FacetCutAction.Add,\\n functionSelectors: functionSelectors\\n });\\n cut[1] = IDiamondCut.FacetCut({\\n facetAddress: _accountFacet,\\n action: IDiamondCut.FacetCutAction.Add,\\n functionSelectors: accountFunctionSelectors\\n });\\n cut[2] = IDiamondCut.FacetCut({\\n facetAddress: _tokenReceiverFacet,\\n action: IDiamondCut.FacetCutAction.Add,\\n functionSelectors: receiverFacetSelectors\\n });\\n cut[3] = IDiamondCut.FacetCut({\\n facetAddress: _diamondLoupeFacet,\\n action: IDiamondCut.FacetCutAction.Add,\\n functionSelectors: loupeFacetSelectors\\n });\\n\\n DefaultLibDiamond.diamondCut(cut, address(0), \\\"\\\");\\n }\\n }\\n\\n /**\\n * @notice Returns the facet information of call facets registered to this diamond.\\n * @return facets_ The facet struct array including all facet information\\n */\\n function facets() external view override returns (Facet[] memory facets_) {\\n DefaultLibDiamond.DiamondStorage storage ds = DefaultLibDiamond\\n .diamondStorage();\\n uint256 numFacets = ds.facetAddresses.length;\\n facets_ = new Facet[](numFacets);\\n for (uint256 i; i < numFacets; ) {\\n address facetAddress_ = ds.facetAddresses[i];\\n facets_[i].facetAddress = facetAddress_;\\n facets_[i].functionSelectors = ds\\n .facetFunctionSelectors[facetAddress_]\\n .functionSelectors;\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * @notice Gets all the function selectors provided by a facet.\\n * @param _facet The facet address.\\n * @return facetFunctionSelectors_\\n */\\n function facetFunctionSelectors(\\n address _facet\\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\\n facetFunctionSelectors_ = DefaultLibDiamond\\n .diamondStorage()\\n .facetFunctionSelectors[_facet]\\n .functionSelectors;\\n }\\n\\n /**\\n * @notice Get all the facet addresses used by a diamond.\\n * @return facetAddresses_\\n */\\n function facetAddresses()\\n external\\n view\\n override\\n returns (address[] memory facetAddresses_)\\n {\\n facetAddresses_ = DefaultLibDiamond.diamondStorage().facetAddresses;\\n }\\n\\n /** @notice Gets the facet that supports the given selector.\\n * @dev If facet is not found return address(0).\\n * @param _functionSelector The function selector.\\n * @return facetAddress_ The facet address.\\n */\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view override returns (address facetAddress_) {\\n facetAddress_ = DefaultLibDiamond\\n .diamondStorage()\\n .selectorToFacetAndPosition[_functionSelector]\\n .facetAddress;\\n }\\n}\\n\",\"keccak256\":\"0xa482fe778481e34e9fb3c4074231f8048437e934c0ca9a0c78e8e61d3a24470a\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.21;\\n\\ninterface IERC165 {\\n /// @notice Query if a contract implements an interface\\n /// @param interfaceId The interface identifier, as specified in ERC-165\\n /// @dev Interface identification is specified in ERC-165. This function\\n /// uses less than 30,000 gas.\\n /// @return `true` if the contract implements `interfaceID` and\\n /// `interfaceID` is not 0xffffffff, `false` otherwise\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xbb7f07e170898793c5535cc4b7e8944c4b990a631ac806d0b788e794abc788a3\",\"license\":\"MIT\"},\"contracts/interfaces/ERC/IERC677Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC677Receiver {\\n function onTokenTransfer(\\n address sender,\\n uint value,\\n bytes calldata data\\n ) external pure returns (bool);\\n}\\n\",\"keccak256\":\"0x4c1631cf45ea6daac0ec158c3edb9453099130b6b64f697004b83f95aa1f7350\",\"license\":\"Apache-2.0\"},\"contracts/libraries/DefaultLibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary DefaultLibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (\\n uint256 facetIndex;\\n facetIndex < _diamondCut.length;\\n facetIndex++\\n ) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(\\n address _facetAddress,\\n bytes4[] memory _functionSelectors\\n ) internal {\\n uint256 funcSelectorsLength = _functionSelectors.length;\\n require(\\n funcSelectorsLength > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _facetAddress != address(0),\\n \\\"LibDiamondCut: Add facet can't be address(0)\\\"\\n );\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (\\n uint256 selectorIndex;\\n selectorIndex < funcSelectorsLength;\\n selectorIndex++\\n ) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds\\n .selectorToFacetAndPosition[selector]\\n .facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(\\n address _facetAddress,\\n bytes4[] memory _functionSelectors\\n ) internal {\\n uint256 funcSelectorsLength = _functionSelectors.length;\\n require(\\n funcSelectorsLength > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _facetAddress != address(0),\\n \\\"LibDiamondCut: Replace facet can't be address(0)\\\"\\n );\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (\\n uint256 selectorIndex;\\n selectorIndex < funcSelectorsLength;\\n selectorIndex++\\n ) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds\\n .selectorToFacetAndPosition[selector]\\n .facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same facet\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(\\n address _facetAddress,\\n bytes4[] memory _functionSelectors\\n ) internal {\\n uint256 funcSelectorsLength = _functionSelectors.length;\\n require(\\n funcSelectorsLength > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(\\n _facetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n for (\\n uint256 selectorIndex;\\n selectorIndex < funcSelectorsLength;\\n selectorIndex++\\n ) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds\\n .selectorToFacetAndPosition[selector]\\n .facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(\\n DiamondStorage storage ds,\\n address _facetAddress\\n ) internal {\\n enforceHasContractCode(\\n _facetAddress,\\n \\\"LibDiamondCut: New facet has no code\\\"\\n );\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds\\n .facetAddresses\\n .length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds\\n .selectorToFacetAndPosition[_selector]\\n .functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(\\n _selector\\n );\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(\\n _facetAddress != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // an immutable function is a function defined directly in a diamond\\n require(\\n _facetAddress != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds\\n .selectorToFacetAndPosition[_selector]\\n .functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors[lastSelectorPosition];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n selectorPosition\\n ] = lastSelector;\\n ds\\n .selectorToFacetAndPosition[lastSelector]\\n .functionSelectorPosition = uint96(selectorPosition);\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[\\n lastFacetAddressPosition\\n ];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds\\n .facetFunctionSelectors[lastFacetAddress]\\n .facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds\\n .facetFunctionSelectors[_facetAddress]\\n .facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x1b08f332d62919288bb1f0d154ca4b85f4e167d2a06e680f8ec93dba65be3be1\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x6080604052604051620020183803806200201883398101604081905262000026916200156b565b60408051600480825260a08201909252600091816020015b604080516060808201835260008083526020830152918101919091528152602001906001900390816200003e5750506040805160018082528183019092529192506000919060208083019080368337019050509050631f931c1c60e01b81600081518110620000b157620000b1620015c8565b6001600160e01b03199290921660209283029190910182015260408051600580825260c08201909252600092909190820160a08036833701905050905063b61d27f660e01b816000815181106200010c576200010c620015c8565b6001600160e01b03199092166020928302919091019091015280516323f0ed1560e11b9082906001908110620001465762000146620015c8565b6001600160e01b0319909216602092830291909101909101528051633a871cdd60e01b9082906002908110620001805762000180620015c8565b6001600160e01b0319909216602092830291909101909101528051631a10fa5160e31b9082906003908110620001ba57620001ba620015c8565b6001600160e01b031990921660209283029190910190910152805163586b48ff60e11b9082906004908110620001f457620001f4620015c8565b6001600160e01b03199290921660209283029190910182015260408051600580825260c08201909252600092909190820160a08036833701905050905063150b7a0260e01b816000815181106200024f576200024f620015c8565b6001600160e01b031990921660209283029190910190910152805163f23a6e6160e01b9082906001908110620002895762000289620015c8565b6001600160e01b031990921660209283029190910190910152805163bc197c8160e01b9082906002908110620002c357620002c3620015c8565b6001600160e01b03199092166020928302919091019091015280516223de2960e01b9082906003908110620002fc57620002fc620015c8565b6001600160e01b0319909216602092830291909101909101528051635260769b60e11b9082906004908110620003365762000336620015c8565b6001600160e01b0319929092166020928302919091018201526040805160098082526101408201909252600092909190820161012080368337019050509050637a0ed62760e01b81600081518110620003935762000393620015c8565b6001600160e01b03199092166020928302919091019091015280516356fe50af60e11b9082906001908110620003cd57620003cd620015c8565b6001600160e01b03199092166020928302919091019091015280516314bbdacb60e21b9082906002908110620004075762000407620015c8565b6001600160e01b03199092166020928302919091019091015280516366ffd66360e11b9082906003908110620004415762000441620015c8565b6001600160e01b03199092166020928302919091019091015280516301ffc9a760e01b90829060049081106200047b576200047b620015c8565b6001600160e01b031990921660209283029190910190910152805163f9796ccf60e01b9082906005908110620004b557620004b5620015c8565b6001600160e01b031990921660209283029190910190910152805162d2a81160e11b9082906006908110620004ee57620004ee620015c8565b6001600160e01b031990921660209283029190910190910152805163d42139a960e01b9082906007908110620005285762000528620015c8565b6001600160e01b03199092166020928302919091019091015280516371d17b7f60e11b9082906008908110620005625762000562620015c8565b6001600160e01b031990921660209283029190910182015260408051606081019091526001600160a01b038b168152908101600081526020018581525085600081518110620005b557620005b5620015c8565b60200260200101819052506040518060600160405280896001600160a01b0316815260200160006002811115620005f057620005f0620015de565b815260200184815250856001815181106200060f576200060f620015c8565b60200260200101819052506040518060600160405280886001600160a01b03168152602001600060028111156200064a576200064a620015de565b81526020018381525085600281518110620006695762000669620015c8565b60200260200101819052506040518060600160405280876001600160a01b0316815260200160006002811115620006a457620006a4620015de565b81526020018281525085600381518110620006c357620006c3620015c8565b6020026020010181905250620006f1856000604051806020016040528060008152506200070060201b60201c565b5050505050505050506200184c565b60005b83518110156200090c576000848281518110620007245762000724620015c8565b602002602001015160200151905060006002811115620007485762000748620015de565b8160028111156200075d576200075d620015de565b03620007bb57620007b58583815181106200077c576200077c620015c8565b6020026020010151600001518684815181106200079d576200079d620015c8565b6020026020010151604001516200095b60201b60201c565b620008f6565b6001816002811115620007d257620007d2620015de565b036200082a57620007b5858381518110620007f157620007f1620015c8565b602002602001015160000151868481518110620008125762000812620015c8565b60200260200101516040015162000bf760201b60201c565b6002816002811115620008415762000841620015de565b036200089957620007b5858381518110620008605762000860620015c8565b602002602001015160000151868481518110620008815762000881620015c8565b60200260200101516040015162000ea160201b60201c565b60405162461bcd60e51b815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f727265637420466163657443756044820152663a20b1ba34b7b760c91b60648201526084015b60405180910390fd5b508062000903816200160a565b91505062000703565b507f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb67383838360405162000942939291906200167a565b60405180910390a162000956828262001005565b505050565b805180620009af5760405162461bcd60e51b815260206004820152602b602482015260008051602062001ff883398151915260448201526a1858d95d081d1bc818dd5d60aa1b6064820152608401620008ed565b60008051602062001f8c8339815191526001600160a01b03841662000a2c5760405162461bcd60e51b815260206004820152602c60248201527f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260448201526b65206164647265737328302960a01b6064820152608401620008ed565b6001600160a01b0384166000908152600182016020526040812054906001600160601b038216900362000a655762000a658286620010dd565b60005b8381101562000bef57600085828151811062000a885762000a88620015c8565b6020908102919091018101516001600160e01b031981166000908152918690526040909120549091506001600160a01b0316801562000b305760405162461bcd60e51b815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c72656164792065786973747300000000000000000000006064820152608401620008ed565b6001600160e01b0319821660008181526020878152604080832080546001600160a01b03908116600160a01b6001600160601b038c16021782558d168085526001808c0185529285208054938401815585528385206008840401805463ffffffff60079095166004026101000a948502191660e08a901c94909402939093179092559390925287905281546001600160a01b0319161790558362000bd48162001781565b9450505050808062000be6906200160a565b91505062000a68565b505050505050565b80518062000c4b5760405162461bcd60e51b815260206004820152602b602482015260008051602062001ff883398151915260448201526a1858d95d081d1bc818dd5d60aa1b6064820152608401620008ed565b60008051602062001f8c8339815191526001600160a01b03841662000ccc5760405162461bcd60e51b815260206004820152603060248201527f4c69624469616d6f6e644375743a205265706c6163652066616365742063616e60448201526f2774206265206164647265737328302960801b6064820152608401620008ed565b6001600160a01b0384166000908152600182016020526040812054906001600160601b038216900362000d055762000d058286620010dd565b60005b8381101562000bef57600085828151811062000d285762000d28620015c8565b6020908102919091018101516001600160e01b031981166000908152918690526040909120549091506001600160a01b03908116908816810362000dd55760405162461bcd60e51b815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d6520666163657400000000000000000000006064820152608401620008ed565b62000de28582846200114a565b6001600160e01b0319821660008181526020878152604080832080546001600160a01b03908116600160a01b6001600160601b038c16021782558d168085526001808c0185529285208054938401815585528385206008840401805463ffffffff60079095166004026101000a948502191660e08a901c94909402939093179092559390925287905281546001600160a01b0319161790558362000e868162001781565b9450505050808062000e98906200160a565b91505062000d08565b80518062000ef55760405162461bcd60e51b815260206004820152602b602482015260008051602062001ff883398151915260448201526a1858d95d081d1bc818dd5d60aa1b6064820152608401620008ed565b60008051602062001f8c8339815191526001600160a01b0384161562000f845760405162461bcd60e51b815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d7573742062652061646472657373283029000000000000000000006064820152608401620008ed565b60005b8281101562000ffe57600084828151811062000fa75762000fa7620015c8565b6020908102919091018101516001600160e01b031981166000908152918590526040909120549091506001600160a01b031662000fe68482846200114a565b5050808062000ff5906200160a565b91505062000f87565b5050505050565b6001600160a01b03821662001018575050565b6200103d8260405180606001604052806028815260200162001fac602891396200152a565b600080836001600160a01b0316836040516200105a9190620017b2565b600060405180830381855af49150503d806000811462001097576040519150601f19603f3d011682016040523d82523d6000602084013e6200109c565b606091505b509150915081620010d757805115620010b85780518082602001fd5b838360405163192105d760e01b8152600401620008ed929190620017d0565b50505050565b620011028160405180606001604052806024815260200162001fd4602491396200152a565b6002820180546001600160a01b0390921660008181526001948501602090815260408220860185905594840183559182529290200180546001600160a01b0319169091179055565b6001600160a01b038216620011c85760405162461bcd60e51b815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608401620008ed565b306001600160a01b03831603620012395760405162461bcd60e51b815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201526d3a30b1363290333ab731ba34b7b760911b6064820152608401620008ed565b6001600160e01b03198116600090815260208481526040808320546001600160a01b0386168452600180880190935290832054600160a01b9091046001600160601b031692916200128a91620017fe565b905080821462001383576001600160a01b03841660009081526001860160205260408120805483908110620012c357620012c3620015c8565b600091825260208083206008830401546001600160a01b038916845260018a019091526040909220805460079092166004026101000a90920460e01b925082919085908110620013175762001317620015c8565b600091825260208083206008830401805463ffffffff60079094166004026101000a938402191660e09590951c929092029390931790556001600160e01b03199290921682528690526040902080546001600160a01b0316600160a01b6001600160601b038516021790555b6001600160a01b03841660009081526001860160205260409020805480620013af57620013af6200181a565b60008281526020808220600860001990940193840401805463ffffffff600460078716026101000a0219169055919092556001600160e01b0319851682528690526040812081905581900362000ffe5760028501546000906200141590600190620017fe565b6001600160a01b0386166000908152600180890160205260409091200154909150808214620014cb576000876002018381548110620014585762001458620015c8565b6000918252602090912001546002890180546001600160a01b0390921692508291849081106200148c576200148c620015c8565b600091825260208083209190910180546001600160a01b0319166001600160a01b03948516179055929091168152600189810190925260409020018190555b86600201805480620014e157620014e16200181a565b60008281526020808220830160001990810180546001600160a01b03191690559092019092556001600160a01b0388168252600189810190915260408220015550505050505050565b813b8181620010d75760405162461bcd60e51b8152600401620008ed919062001830565b80516001600160a01b03811681146200156657600080fd5b919050565b600080600080608085870312156200158257600080fd5b6200158d856200154e565b93506200159d602086016200154e565b9250620015ad604086016200154e565b9150620015bd606086016200154e565b905092959194509250565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016200161f576200161f620015f4565b5060010190565b60005b838110156200164357818101518382015260200162001629565b50506000910152565b600081518084526200166681602086016020860162001626565b601f01601f19169290920160200192915050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b848110156200174f57898403607f19018652815180516001600160a01b03168552838101518986019060038110620016eb57634e487b7160e01b600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b80831015620017395783516001600160e01b03191682529286019260019290920191908601906200170d565b50978501979550505090820190600101620016a3565b50506001600160a01b038a169088015286810360408801526200177381896200164c565b9a9950505050505050505050565b60006001600160601b038281166002600160601b03198101620017a857620017a8620015f4565b6001019392505050565b60008251620017c681846020870162001626565b9190910192915050565b6001600160a01b0383168152604060208201819052600090620017f6908301846200164c565b949350505050565b81810381811115620018145762001814620015f4565b92915050565b634e487b7160e01b600052603160045260246000fd5b6020815260006200184560208301846200164c565b9392505050565b610730806200185c6000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806352ef6b2c146100515780637a0ed6271461006f578063adfca15e14610084578063cdffacc6146100a4575b600080fd5b610059610140565b60405161006691906104ab565b60405180910390f35b6100776101d1565b6040516100669190610562565b61009761009236600461060a565b6103d1565b6040516100669190610647565b61011b6100b236600461065a565b7fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610066565b60607f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6002018054806020026020016040519081016040528092919081815260200182805480156101c757602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161019c575b5050505050905090565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f908067ffffffffffffffff8111156102315761023161069c565b60405190808252806020026020018201604052801561027757816020015b60408051808201909152600081526060602082015281526020019060019003908161024f5790505b50925060005b818110156103cb57600083600201828154811061029c5761029c6106cb565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050808583815181106102dc576102dc6106cb565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff928316905290821660009081526001860182526040908190208054825181850281018501909352808352919290919083018282801561039d57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161034a5790505b50505050508583815181106103b4576103b46106cb565b60209081029190910181015101525060010161027d565b50505090565b73ffffffffffffffffffffffffffffffffffffffff811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4920602090815260409182902080548351818402810184019094528084526060939283018282801561049f57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161044c5790505b50505050509050919050565b6020808252825182820181905260009190848201906040850190845b818110156104f957835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016104c7565b50909695505050505050565b600081518084526020808501945080840160005b838110156105575781517fffffffff000000000000000000000000000000000000000000000000000000001687529582019590820190600101610519565b509495945050505050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b838110156105fc578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00185528151805173ffffffffffffffffffffffffffffffffffffffff1684528701518784018790526105e987850182610505565b9588019593505090860190600101610589565b509098975050505050505050565b60006020828403121561061c57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461064057600080fd5b9392505050565b6020815260006106406020830184610505565b60006020828403121561066c57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461064057600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea264697066735822122024a872696a5ad50024326567061c50adea63ff0d49edf0ac60339459d33d571664736f6c63430008150033183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f4c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a204e657720666163657420686173206e6f20636f64654c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e2066", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806352ef6b2c146100515780637a0ed6271461006f578063adfca15e14610084578063cdffacc6146100a4575b600080fd5b610059610140565b60405161006691906104ab565b60405180910390f35b6100776101d1565b6040516100669190610562565b61009761009236600461060a565b6103d1565b6040516100669190610647565b61011b6100b236600461065a565b7fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610066565b60607f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6002018054806020026020016040519081016040528092919081815260200182805480156101c757602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161019c575b5050505050905090565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f908067ffffffffffffffff8111156102315761023161069c565b60405190808252806020026020018201604052801561027757816020015b60408051808201909152600081526060602082015281526020019060019003908161024f5790505b50925060005b818110156103cb57600083600201828154811061029c5761029c6106cb565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050808583815181106102dc576102dc6106cb565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff928316905290821660009081526001860182526040908190208054825181850281018501909352808352919290919083018282801561039d57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161034a5790505b50505050508583815181106103b4576103b46106cb565b60209081029190910181015101525060010161027d565b50505090565b73ffffffffffffffffffffffffffffffffffffffff811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4920602090815260409182902080548351818402810184019094528084526060939283018282801561049f57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161044c5790505b50505050509050919050565b6020808252825182820181905260009190848201906040850190845b818110156104f957835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016104c7565b50909695505050505050565b600081518084526020808501945080840160005b838110156105575781517fffffffff000000000000000000000000000000000000000000000000000000001687529582019590820190600101610519565b509495945050505050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b838110156105fc578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00185528151805173ffffffffffffffffffffffffffffffffffffffff1684528701518784018790526105e987850182610505565b9588019593505090860190600101610589565b509098975050505050505050565b60006020828403121561061c57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461064057600080fd5b9392505050565b6020815260006106406020830184610505565b60006020828403121561066c57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461064057600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea264697066735822122024a872696a5ad50024326567061c50adea63ff0d49edf0ac60339459d33d571664736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "A default fallback handler for Barz", + "kind": "dev", + "methods": { + "constructor": { + "details": "This contract is also a diamond that holds the default facets to reduce gas cost for wallet activation. Within the constructor this conducts diamond cut to initially setup the diamond. This is a non-upgradeable contract", + "params": { + "_accountFacet": "Address account facet", + "_diamondCutFacet": "Address if diamond cut facet", + "_diamondLoupeFacet": "Address of diamond loupe facet", + "_tokenReceiverFacet": "Address of token receiver facet" + } + }, + "facetAddress(bytes4)": { + "details": "If facet is not found return address(0).", + "params": { + "_functionSelector": "The function selector." + }, + "returns": { + "facetAddress_": "The facet address." + } + }, + "facetAddresses()": { + "returns": { + "facetAddresses_": "facetAddresses_" + } + }, + "facetFunctionSelectors(address)": { + "params": { + "_facet": "The facet address." + }, + "returns": { + "facetFunctionSelectors_": "facetFunctionSelectors_" + } + }, + "facets()": { + "returns": { + "facets_": "The facet struct array including all facet information" + } + } + }, + "title": "DefaultFallbackHandler", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "constructor": { + "notice": "Sets the middleware diamond for Barz wallet as a fallback handler" + }, + "facetAddress(bytes4)": { + "notice": "Gets the facet that supports the given selector." + }, + "facetAddresses()": { + "notice": "Get all the facet addresses used by a diamond." + }, + "facetFunctionSelectors(address)": { + "notice": "Gets all the function selectors provided by a facet." + }, + "facets()": { + "notice": "Returns the facet information of call facets registered to this diamond." + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/lightLink/DiamondCutFacet.json b/deployments/lightLink/DiamondCutFacet.json new file mode 100644 index 0000000..fbc77b2 --- /dev/null +++ b/deployments/lightLink/DiamondCutFacet.json @@ -0,0 +1,856 @@ +{ + "address": "0x0B9504140771C3688Ff041917192277D2f52E1e0", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_securityManager", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "CallerNotGuardian", + "type": "error" + }, + { + "inputs": [], + "name": "CallerNotGuardianOrOwner", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__CannotRevokeUnapproved", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__DuplicateApproval", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InsufficientApprovers", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidApprovalValidationPeriod", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidApprover", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidApproverSignature", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidArrayLength", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidInitAddress", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidRouteWithGuardian", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidRouteWithoutGuardian", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__LackOfOwnerApproval", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__OwnerAlreadyApproved", + "type": "error" + }, + { + "inputs": [], + "name": "DuplicateApprover", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_initializationContractAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "InitializationFunctionReverted", + "type": "error" + }, + { + "inputs": [], + "name": "UnregisteredFacetAndSelectors", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroApproverLength", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "indexed": false, + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "DiamondCut", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "diamondCut", + "type": "tuple[]" + } + ], + "name": "DiamondCutApprovalRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "diamondCut", + "type": "tuple[]" + } + ], + "name": "DiamondCutApproved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + }, + { + "indexed": false, + "internalType": "bool", + "name": "_lag", + "type": "bool" + } + ], + "name": "SupportsInterfaceUpdated", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_diamondCutHash", + "type": "bytes32" + }, + { + "internalType": "address[]", + "name": "_approvers", + "type": "address[]" + } + ], + "name": "_checkDuplicateOnChainApprover", + "outputs": [], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + } + ], + "name": "approveDiamondCut", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "diamondCut", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "internalType": "address[]", + "name": "_approvers", + "type": "address[]" + }, + { + "internalType": "bytes[]", + "name": "_signatures", + "type": "bytes[]" + } + ], + "name": "diamondCutWithGuardian", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_diamondCutHash", + "type": "bytes32" + } + ], + "name": "getDiamondCutApprovalCountWithTimeValidity", + "outputs": [ + { + "internalType": "uint256", + "name": "approvalCount", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + } + ], + "name": "getDiamondCutHash", + "outputs": [ + { + "internalType": "bytes32", + "name": "cutHash", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getDiamondCutNonce", + "outputs": [ + { + "internalType": "uint128", + "name": "cutNonce", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_diamondCutHash", + "type": "bytes32" + } + ], + "name": "getOwnerCutApprovalWithTimeValidity", + "outputs": [ + { + "internalType": "bool", + "name": "isApprovedByOwner", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_diamondCutHash", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "_approver", + "type": "address" + } + ], + "name": "isCutApproved", + "outputs": [ + { + "internalType": "bool", + "name": "isApproved", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + } + ], + "name": "revokeDiamondCutApproval", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "securityManager", + "outputs": [ + { + "internalType": "contract ISecurityManager", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_interfaceId", + "type": "bytes4" + }, + { + "internalType": "bool", + "name": "_flag", + "type": "bool" + } + ], + "name": "updateSupportsInterface", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0x92edb207a339fd9c2f0a64d8a5da33fa654f197dce74ad6741453cb2d5e5d72d", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": "0x0000000000000000000000000000000000000000", + "transactionIndex": 0, + "gasUsed": "3079879", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0xc4d5d53800df6ac3642981702048bdee736f33fc9cf2a0fec92c90f7b5ecb66b", + "transactionHash": "0x92edb207a339fd9c2f0a64d8a5da33fa654f197dce74ad6741453cb2d5e5d72d", + "logs": [], + "blockNumber": 72701513, + "cumulativeGasUsed": "3079879", + "status": 1, + "byzantium": true + }, + "args": [ + "0xcBe266adbfd7CB32988128e7f37b7c8b3C5521A8" + ], + "numDeployments": 1, + "solcInputHash": "ad34345aa73d96f52b3e14df983b6b29", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_securityManager\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"CallerNotGuardian\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallerNotGuardianOrOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__CannotRevokeUnapproved\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__DuplicateApproval\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InsufficientApprovers\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidApprovalValidationPeriod\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidApprover\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidApproverSignature\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidArrayLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidInitAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidRouteWithGuardian\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidRouteWithoutGuardian\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__LackOfOwnerApproval\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__OwnerAlreadyApproved\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateApprover\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_initializationContractAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"InitializationFunctionReverted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnregisteredFacetAndSelectors\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroApproverLength\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"DiamondCut\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"diamondCut\",\"type\":\"tuple[]\"}],\"name\":\"DiamondCutApprovalRevoked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"diamondCut\",\"type\":\"tuple[]\"}],\"name\":\"DiamondCutApproved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"_lag\",\"type\":\"bool\"}],\"name\":\"SupportsInterfaceUpdated\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_diamondCutHash\",\"type\":\"bytes32\"},{\"internalType\":\"address[]\",\"name\":\"_approvers\",\"type\":\"address[]\"}],\"name\":\"_checkDuplicateOnChainApprover\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"}],\"name\":\"approveDiamondCut\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"diamondCut\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"internalType\":\"address[]\",\"name\":\"_approvers\",\"type\":\"address[]\"},{\"internalType\":\"bytes[]\",\"name\":\"_signatures\",\"type\":\"bytes[]\"}],\"name\":\"diamondCutWithGuardian\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_diamondCutHash\",\"type\":\"bytes32\"}],\"name\":\"getDiamondCutApprovalCountWithTimeValidity\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"approvalCount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"}],\"name\":\"getDiamondCutHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"cutHash\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDiamondCutNonce\",\"outputs\":[{\"internalType\":\"uint128\",\"name\":\"cutNonce\",\"type\":\"uint128\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_diamondCutHash\",\"type\":\"bytes32\"}],\"name\":\"getOwnerCutApprovalWithTimeValidity\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isApprovedByOwner\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_diamondCutHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"_approver\",\"type\":\"address\"}],\"name\":\"isCutApproved\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isApproved\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"}],\"name\":\"revokeDiamondCutApproval\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"securityManager\",\"outputs\":[{\"internalType\":\"contract ISecurityManager\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_interfaceId\",\"type\":\"bytes4\"},{\"internalType\":\"bool\",\"name\":\"_flag\",\"type\":\"bool\"}],\"name\":\"updateSupportsInterface\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"Responsible for adding/removing/replace facets in Barz\",\"kind\":\"dev\",\"methods\":{\"_checkDuplicateOnChainApprover(bytes32,address[])\":{\"params\":{\"_approvers\":\"List of approver addresses\",\"_diamondCutHash\":\"Hash of diamondCut information including the facet addresses and function selectors\"}},\"approveDiamondCut((address,uint8,bytes4[])[])\":{\"params\":{\"_diamondCut\":\"Contains the facet addresses and function selectors\"}},\"constructor\":{\"params\":{\"_securityManager\":\"Security Manager contract that holds the security related variables for all wallets\"}},\"diamondCut((address,uint8,bytes4[])[],address,bytes)\":{\"params\":{\"_diamondCut\":\"Contains the facet addresses and function selectors\",\"_init\":\"The address of the contract or facet to execute _calldata. It's prohibited in Barz\"}},\"diamondCutWithGuardian((address,uint8,bytes4[])[],address[],bytes[])\":{\"params\":{\"_approvers\":\"Guardian or owner address that approves the diamond cut\",\"_diamondCut\":\"Contains the facet addresses and function selectors\",\"_signatures\":\"Signature of Guardians or owner that approves the diamond cut\"}},\"getDiamondCutApprovalCountWithTimeValidity(bytes32)\":{\"params\":{\"_diamondCutHash\":\"Hash of diamondCut information including the facet addresses and function selectors\"}},\"getDiamondCutHash((address,uint8,bytes4[])[])\":{\"params\":{\"_diamondCut\":\"Contains the facet addresses and function selectors\"},\"returns\":{\"cutHash\":\"Diamond Cut Hash\"}},\"getDiamondCutNonce()\":{\"details\":\"This method fetches the nonce from diamond cut storage\",\"returns\":{\"cutNonce\":\"Nonce of diamond cut to protect from reply attacks\"}},\"getOwnerCutApprovalWithTimeValidity(bytes32)\":{\"params\":{\"_diamondCutHash\":\"Hash of diamondCut information including the facet addresses and function selectors\"},\"returns\":{\"isApprovedByOwner\":\"Bool value showing if the owner approved the cut\"}},\"isCutApproved(bytes32,address)\":{\"params\":{\"_approver\":\"Address of approver\",\"_diamondCutHash\":\"Hash of diamondCut information including the facet addresses and function selectors\"},\"returns\":{\"isApproved\":\"Bool value showing if the approver approved the cut\"}},\"revokeDiamondCutApproval((address,uint8,bytes4[])[])\":{\"params\":{\"_diamondCut\":\"Contains the facet addresses and function selectors\"}},\"updateSupportsInterface(bytes4,bool)\":{\"params\":{\"_flag\":\"Bool value to update the mapping of the given interface ID\",\"_interfaceId\":\"InterfaceID to update the mapping\"}}},\"title\":\"DiamondCut Facet\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"_checkDuplicateOnChainApprover(bytes32,address[])\":{\"notice\":\"Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval Approvers who approved on-chain should not be included in the off-chain approval\"},\"approveDiamondCut((address,uint8,bytes4[])[])\":{\"notice\":\"Approves diamond cut. This can only be called directly from guardian or owner\"},\"constructor\":{\"notice\":\"This constructor sets the Security Manager address which is an immutable variable. Immutable variables do not impact the storage of diamond\"},\"diamondCut((address,uint8,bytes4[])[],address,bytes)\":{\"notice\":\"Add/replace/remove any number of functions and optionally execute a function with delegatecall when guardians don't exist\"},\"diamondCutWithGuardian((address,uint8,bytes4[])[],address[],bytes[])\":{\"notice\":\"Add/replace/remove any number of functions and optionally execute a function with delegatecall when guardians exist\"},\"getDiamondCutApprovalCountWithTimeValidity(bytes32)\":{\"notice\":\"Gets the number of approvals of diamond cut from guardians\"},\"getDiamondCutHash((address,uint8,bytes4[])[])\":{\"notice\":\"Returns the diamond cut hash. This function ensures that this hash is safe from replay attack by including salt, address, chainId, and nonce, etc.\"},\"getDiamondCutNonce()\":{\"notice\":\"Returns the diamond cut nonce of this wallet\"},\"getOwnerCutApprovalWithTimeValidity(bytes32)\":{\"notice\":\"Returns if the owner has approved the diamond cut\"},\"isCutApproved(bytes32,address)\":{\"notice\":\"Returns if the given approver has approved the diamond cut\"},\"revokeDiamondCutApproval((address,uint8,bytes4[])[])\":{\"notice\":\"Revokes the approval of diamond cut. This can only be called directly from guardian or owner\"},\"updateSupportsInterface(bytes4,bool)\":{\"notice\":\"Updates the flag for the interfaceId\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/base/DiamondCutFacet.sol\":\"DiamondCutFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/interfaces/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC1271 standard signature validation method for\\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC1271 {\\n /**\\n * @dev Should return whether the signature provided is valid for the provided data\\n * @param hash Hash of the data to be signed\\n * @param signature Signature byte array associated with _data\\n */\\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\\n}\\n\",\"keccak256\":\"0x0705a4b1b86d7b0bd8432118f226ba139c44b9dcaba0a6eafba2dd7d0639c544\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./math/Math.sol\\\";\\nimport \\\"./math/SignedMath.sol\\\";\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n uint256 length = Math.log10(value) + 1;\\n string memory buffer = new string(length);\\n uint256 ptr;\\n /// @solidity memory-safe-assembly\\n assembly {\\n ptr := add(buffer, add(32, length))\\n }\\n while (true) {\\n ptr--;\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\\n }\\n value /= 10;\\n if (value == 0) break;\\n }\\n return buffer;\\n }\\n }\\n\\n /**\\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\\n */\\n function toString(int256 value) internal pure returns (string memory) {\\n return string(abi.encodePacked(value < 0 ? \\\"-\\\" : \\\"\\\", toString(SignedMath.abs(value))));\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n return toHexString(value, Math.log256(value) + 1);\\n }\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n\\n /**\\n * @dev Returns true if the two strings are equal.\\n */\\n function equal(string memory a, string memory b) internal pure returns (bool) {\\n return keccak256(bytes(a)) == keccak256(bytes(b));\\n }\\n}\\n\",\"keccak256\":\"0x3088eb2868e8d13d89d16670b5f8612c4ab9ff8956272837d8e90106c59c14a0\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Strings.sol\\\";\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSA {\\n enum RecoverError {\\n NoError,\\n InvalidSignature,\\n InvalidSignatureLength,\\n InvalidSignatureS,\\n InvalidSignatureV // Deprecated in v4.8\\n }\\n\\n function _throwError(RecoverError error) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert(\\\"ECDSA: invalid signature\\\");\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert(\\\"ECDSA: invalid signature length\\\");\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert(\\\"ECDSA: invalid signature 's' value\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature` or error string. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n *\\n * Documentation for signature generation:\\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n return tryRecover(hash, v, r, s);\\n } else {\\n return (address(0), RecoverError.InvalidSignatureLength);\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature`. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, signature);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\\n uint8 v = uint8((uint256(vs) >> 255) + 27);\\n return tryRecover(hash, v, r, s);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n *\\n * _Available since v4.2._\\n */\\n function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\\n // the valid range for s in (301): 0 < s < secp256k1n \\u00f7 2 + 1, and for v in (302): v \\u2208 {27, 28}. Most\\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\\n //\\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\\n // these malleable signatures as well.\\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n return (address(0), RecoverError.InvalidSignatureS);\\n }\\n\\n // If the signature is valid (and not malleable), return the signer address\\n address signer = ecrecover(hash, v, r, s);\\n if (signer == address(0)) {\\n return (address(0), RecoverError.InvalidSignature);\\n }\\n\\n return (signer, RecoverError.NoError);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore(0x00, \\\"\\\\x19Ethereum Signed Message:\\\\n32\\\")\\n mstore(0x1c, hash)\\n message := keccak256(0x00, 0x3c)\\n }\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from `s`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n\\\", Strings.toString(s.length), s));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Typed Data, created from a\\n * `domainSeparator` and a `structHash`. This produces hash corresponding\\n * to the one signed with the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n * JSON-RPC method as part of EIP-712.\\n *\\n * See {recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n let ptr := mload(0x40)\\n mstore(ptr, \\\"\\\\x19\\\\x01\\\")\\n mstore(add(ptr, 0x02), domainSeparator)\\n mstore(add(ptr, 0x22), structHash)\\n data := keccak256(ptr, 0x42)\\n }\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Data with intended validator, created from a\\n * `validator` and `data` according to the version 0 of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x00\\\", validator, data));\\n }\\n}\\n\",\"keccak256\":\"0x809bc3edb4bcbef8263fa616c1b60ee0004b50a8a1bfa164d8f57fd31f520c58\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/SignatureChecker.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./ECDSA.sol\\\";\\nimport \\\"../../interfaces/IERC1271.sol\\\";\\n\\n/**\\n * @dev Signature verification helper that can be used instead of `ECDSA.recover` to seamlessly support both ECDSA\\n * signatures from externally owned accounts (EOAs) as well as ERC1271 signatures from smart contract wallets like\\n * Argent and Gnosis Safe.\\n *\\n * _Available since v4.1._\\n */\\nlibrary SignatureChecker {\\n /**\\n * @dev Checks if a signature is valid for a given signer and data hash. If the signer is a smart contract, the\\n * signature is validated against that smart contract using ERC1271, otherwise it's validated using `ECDSA.recover`.\\n *\\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\\n */\\n function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature) internal view returns (bool) {\\n (address recovered, ECDSA.RecoverError error) = ECDSA.tryRecover(hash, signature);\\n return\\n (error == ECDSA.RecoverError.NoError && recovered == signer) ||\\n isValidERC1271SignatureNow(signer, hash, signature);\\n }\\n\\n /**\\n * @dev Checks if a signature is valid for a given signer and data hash. The signature is validated\\n * against the signer smart contract using ERC1271.\\n *\\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\\n */\\n function isValidERC1271SignatureNow(\\n address signer,\\n bytes32 hash,\\n bytes memory signature\\n ) internal view returns (bool) {\\n (bool success, bytes memory result) = signer.staticcall(\\n abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, signature)\\n );\\n return (success &&\\n result.length >= 32 &&\\n abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector));\\n }\\n}\\n\",\"keccak256\":\"0x3af3ca86df39aac39a0514c84459d691434a108d2151c8ce9d69f32e315cab80\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n enum Rounding {\\n Down, // Toward negative infinity\\n Up, // Toward infinity\\n Zero // Toward zero\\n }\\n\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow.\\n return (a & b) + (a ^ b) / 2;\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a == 0 ? 0 : (a - 1) / b + 1;\\n }\\n\\n /**\\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\\n * with further edits by Uniswap Labs also under MIT license.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\\n unchecked {\\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2^256 + prod0.\\n uint256 prod0; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division.\\n if (prod1 == 0) {\\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\\n // The surrounding unchecked block does not change this fact.\\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\\n return prod0 / denominator;\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n require(denominator > prod1, \\\"Math: mulDiv overflow\\\");\\n\\n ///////////////////////////////////////////////\\n // 512 by 256 division.\\n ///////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0].\\n uint256 remainder;\\n assembly {\\n // Compute remainder using mulmod.\\n remainder := mulmod(x, y, denominator)\\n\\n // Subtract 256 bit number from 512 bit number.\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\\n // See https://cs.stackexchange.com/q/138556/92363.\\n\\n // Does not overflow because the denominator cannot be zero at this stage in the function.\\n uint256 twos = denominator & (~denominator + 1);\\n assembly {\\n // Divide denominator by twos.\\n denominator := div(denominator, twos)\\n\\n // Divide [prod1 prod0] by twos.\\n prod0 := div(prod0, twos)\\n\\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\\n twos := add(div(sub(0, twos), twos), 1)\\n }\\n\\n // Shift in bits from prod1 into prod0.\\n prod0 |= prod1 * twos;\\n\\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\\n // four bits. That is, denominator * inv = 1 mod 2^4.\\n uint256 inverse = (3 * denominator) ^ 2;\\n\\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\\n // in modular arithmetic, doubling the correct bits in each step.\\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\\n\\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inverse;\\n return result;\\n }\\n }\\n\\n /**\\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\\n uint256 result = mulDiv(x, y, denominator);\\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\\n result += 1;\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\\n *\\n * Inspired by Henry S. Warren, Jr.'s \\\"Hacker's Delight\\\" (Chapter 11).\\n */\\n function sqrt(uint256 a) internal pure returns (uint256) {\\n if (a == 0) {\\n return 0;\\n }\\n\\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\\n //\\n // We know that the \\\"msb\\\" (most significant bit) of our target number `a` is a power of 2 such that we have\\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\\n //\\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\\n // \\u2192 `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\\n // \\u2192 `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\\n //\\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\\n uint256 result = 1 << (log2(a) >> 1);\\n\\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\\n // into the expected uint128 result.\\n unchecked {\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n return min(result, a / result);\\n }\\n }\\n\\n /**\\n * @notice Calculates sqrt(a), following the selected rounding direction.\\n */\\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = sqrt(a);\\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 2, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 128;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 64;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 32;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 16;\\n }\\n if (value >> 8 > 0) {\\n value >>= 8;\\n result += 8;\\n }\\n if (value >> 4 > 0) {\\n value >>= 4;\\n result += 4;\\n }\\n if (value >> 2 > 0) {\\n value >>= 2;\\n result += 2;\\n }\\n if (value >> 1 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log2(value);\\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 10, rounded down, of a positive value.\\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 + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 256, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n *\\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\\n */\\n function log256(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 16;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 8;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 4;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 2;\\n }\\n if (value >> 8 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log256(value);\\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe4455ac1eb7fc497bb7402579e7b4d64d928b846fce7d2b6fde06d366f21c2b3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\\n * checks.\\n *\\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\\n * easily result in undesired exploitation or bugs, since developers usually\\n * assume that overflows raise errors. `SafeCast` restores this intuition by\\n * reverting the transaction when such an operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n *\\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\\n * all math on `uint256` and `int256` and then downcasting.\\n */\\nlibrary SafeCast {\\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 * _Available since v4.7._\\n */\\n function toUint248(uint256 value) internal pure returns (uint248) {\\n require(value <= type(uint248).max, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint240(uint256 value) internal pure returns (uint240) {\\n require(value <= type(uint240).max, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint232(uint256 value) internal pure returns (uint232) {\\n require(value <= type(uint232).max, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint224(uint256 value) internal pure returns (uint224) {\\n require(value <= type(uint224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint216(uint256 value) internal pure returns (uint216) {\\n require(value <= type(uint216).max, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint208(uint256 value) internal pure returns (uint208) {\\n require(value <= type(uint208).max, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint200(uint256 value) internal pure returns (uint200) {\\n require(value <= type(uint200).max, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint192(uint256 value) internal pure returns (uint192) {\\n require(value <= type(uint192).max, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint184(uint256 value) internal pure returns (uint184) {\\n require(value <= type(uint184).max, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint176(uint256 value) internal pure returns (uint176) {\\n require(value <= type(uint176).max, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint168(uint256 value) internal pure returns (uint168) {\\n require(value <= type(uint168).max, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint160(uint256 value) internal pure returns (uint160) {\\n require(value <= type(uint160).max, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint152(uint256 value) internal pure returns (uint152) {\\n require(value <= type(uint152).max, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint144(uint256 value) internal pure returns (uint144) {\\n require(value <= type(uint144).max, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint136(uint256 value) internal pure returns (uint136) {\\n require(value <= type(uint136).max, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint128(uint256 value) internal pure returns (uint128) {\\n require(value <= type(uint128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint120(uint256 value) internal pure returns (uint120) {\\n require(value <= type(uint120).max, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint112(uint256 value) internal pure returns (uint112) {\\n require(value <= type(uint112).max, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint104(uint256 value) internal pure returns (uint104) {\\n require(value <= type(uint104).max, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint96(uint256 value) internal pure returns (uint96) {\\n require(value <= type(uint96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint88(uint256 value) internal pure returns (uint88) {\\n require(value <= type(uint88).max, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint80(uint256 value) internal pure returns (uint80) {\\n require(value <= type(uint80).max, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint72(uint256 value) internal pure returns (uint72) {\\n require(value <= type(uint72).max, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint64(uint256 value) internal pure returns (uint64) {\\n require(value <= type(uint64).max, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint56(uint256 value) internal pure returns (uint56) {\\n require(value <= type(uint56).max, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint48(uint256 value) internal pure returns (uint48) {\\n require(value <= type(uint48).max, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint40(uint256 value) internal pure returns (uint40) {\\n require(value <= type(uint40).max, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint32(uint256 value) internal pure returns (uint32) {\\n require(value <= type(uint32).max, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint24(uint256 value) internal pure returns (uint24) {\\n require(value <= type(uint24).max, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint16(uint256 value) internal pure returns (uint16) {\\n require(value <= type(uint16).max, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint8(uint256 value) internal pure returns (uint8) {\\n require(value <= type(uint8).max, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\n */\\n function toUint256(int256 value) internal pure returns (uint256) {\\n require(value >= 0, \\\"SafeCast: value must be positive\\\");\\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 * _Available since v4.7._\\n */\\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\\n downcasted = int248(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\\n downcasted = int240(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\\n downcasted = int232(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\\n downcasted = int224(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\\n downcasted = int216(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\\n downcasted = int208(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\\n downcasted = int200(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\\n downcasted = int192(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\\n downcasted = int184(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\\n downcasted = int176(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\\n downcasted = int168(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\\n downcasted = int160(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\\n downcasted = int152(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\\n downcasted = int144(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\\n downcasted = int136(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\\n downcasted = int128(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\\n downcasted = int120(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\\n downcasted = int112(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\\n downcasted = int104(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\\n downcasted = int96(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\\n downcasted = int88(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\\n downcasted = int80(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\\n downcasted = int72(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\\n downcasted = int64(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\\n downcasted = int56(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\\n downcasted = int48(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\\n downcasted = int40(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\\n downcasted = int32(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\\n downcasted = int24(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\\n downcasted = int16(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\\n downcasted = int8(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\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 require(value <= uint256(type(int256).max), \\\"SafeCast: value doesn't fit in an int256\\\");\\n return int256(value);\\n }\\n}\\n\",\"keccak256\":\"0x52a8cfb0f5239d11b457dcdd1b326992ef672714ca8da71a157255bddd13f3ad\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SignedMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard signed math utilities missing in the Solidity language.\\n */\\nlibrary SignedMath {\\n /**\\n * @dev Returns the largest of two signed numbers.\\n */\\n function max(int256 a, int256 b) internal pure returns (int256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two signed numbers.\\n */\\n function min(int256 a, int256 b) internal pure returns (int256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two signed numbers without overflow.\\n * The result is rounded towards zero.\\n */\\n function average(int256 a, int256 b) internal pure returns (int256) {\\n // Formula from the book \\\"Hacker's Delight\\\"\\n int256 x = (a & b) + ((a ^ b) >> 1);\\n return x + (int256(uint256(x) >> 255) & (a ^ b));\\n }\\n\\n /**\\n * @dev Returns the absolute unsigned value of a signed value.\\n */\\n function abs(int256 n) internal pure returns (uint256) {\\n unchecked {\\n // must be unchecked in order to support `n = type(int256).min`\\n return uint256(n >= 0 ? n : -n);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf92515413956f529d95977adc9b0567d583c6203fc31ab1c23824c35187e3ddc\",\"license\":\"MIT\"},\"contracts/aa-4337/core/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable no-inline-assembly */\\n\\n/**\\n * returned data from validateUserOp.\\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\\n * @param aggregator - address(0) - the account validated the signature by itself.\\n * address(1) - the account failed to validate the signature.\\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\\n * @param validAfter - this UserOp is valid only after this timestamp.\\n * @param validaUntil - this UserOp is valid only up to this timestamp.\\n */\\nstruct ValidationData {\\n address aggregator;\\n uint48 validAfter;\\n uint48 validUntil;\\n}\\n\\n//extract sigFailed, validAfter, validUntil.\\n// also convert zero validUntil to type(uint48).max\\nfunction _parseValidationData(\\n uint validationData\\n) pure returns (ValidationData memory data) {\\n address aggregator = address(uint160(validationData));\\n uint48 validUntil = uint48(validationData >> 160);\\n if (validUntil == 0) {\\n validUntil = type(uint48).max;\\n }\\n uint48 validAfter = uint48(validationData >> (48 + 160));\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n// intersect account and paymaster ranges.\\nfunction _intersectTimeRange(\\n uint256 validationData,\\n uint256 paymasterValidationData\\n) pure returns (ValidationData memory) {\\n ValidationData memory accountValidationData = _parseValidationData(\\n validationData\\n );\\n ValidationData memory pmValidationData = _parseValidationData(\\n paymasterValidationData\\n );\\n address aggregator = accountValidationData.aggregator;\\n if (aggregator == address(0)) {\\n aggregator = pmValidationData.aggregator;\\n }\\n uint48 validAfter = accountValidationData.validAfter;\\n uint48 validUntil = accountValidationData.validUntil;\\n uint48 pmValidAfter = pmValidationData.validAfter;\\n uint48 pmValidUntil = pmValidationData.validUntil;\\n\\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp\\n * @param data - the ValidationData to pack\\n */\\nfunction _packValidationData(\\n ValidationData memory data\\n) pure returns (uint256) {\\n return\\n uint160(data.aggregator) |\\n (uint256(data.validUntil) << 160) |\\n (uint256(data.validAfter) << (160 + 48));\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp, when not using an aggregator\\n * @param sigFailed - true for signature failure, false for success\\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\\n * @param validAfter first timestamp this UserOperation is valid\\n */\\nfunction _packValidationData(\\n bool sigFailed,\\n uint48 validUntil,\\n uint48 validAfter\\n) pure returns (uint256) {\\n return\\n (sigFailed ? 1 : 0) |\\n (uint256(validUntil) << 160) |\\n (uint256(validAfter) << (160 + 48));\\n}\\n\\n/**\\n * keccak function over calldata.\\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\\n */\\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\\n assembly {\\n let mem := mload(0x40)\\n let len := data.length\\n calldatacopy(mem, data.offset, len)\\n ret := keccak256(mem, len)\\n }\\n}\\n\",\"keccak256\":\"0xa79f06cd158ecb8c0da95493a2f348933b8627a63e228b99738bff3aa107942d\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAggregator.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\n/**\\n * Aggregated Signatures validator.\\n */\\ninterface IAggregator {\\n /**\\n * validate aggregated signature.\\n * revert if the aggregated signature does not match the given list of operations.\\n */\\n function validateSignatures(\\n UserOperation[] calldata userOps,\\n bytes calldata signature\\n ) external view;\\n\\n /**\\n * validate signature of a single userOp\\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\\n * @param userOp the userOperation received from the user.\\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\\n * (usually empty, unless account and aggregator support some kind of \\\"multisig\\\"\\n */\\n function validateUserOpSignature(\\n UserOperation calldata userOp\\n ) external view returns (bytes memory sigForUserOp);\\n\\n /**\\n * aggregate multiple signatures into a single value.\\n * This method is called off-chain to calculate the signature to pass with handleOps()\\n * bundler MAY use optimized custom code perform this aggregation\\n * @param userOps array of UserOperations to collect the signatures from.\\n * @return aggregatedSignature the aggregated signature\\n */\\n function aggregateSignatures(\\n UserOperation[] calldata userOps\\n ) external view returns (bytes memory aggregatedSignature);\\n}\\n\",\"keccak256\":\"0xdfdcd80568f037716674619b31be630fcd8316262f05a815b41d1e81782c966a\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IEntryPoint.sol\":{\"content\":\"/**\\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\\n ** Only one instance required on each chain.\\n **/\\n// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-inline-assembly */\\n/* solhint-disable reason-string */\\n\\nimport \\\"./UserOperation.sol\\\";\\nimport \\\"./IStakeManager.sol\\\";\\nimport \\\"./IAggregator.sol\\\";\\nimport \\\"./INonceManager.sol\\\";\\n\\ninterface IEntryPoint is IStakeManager, INonceManager {\\n /***\\n * An event emitted after each successful request\\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\\n * @param sender - the account that generates this request.\\n * @param paymaster - if non-null, the paymaster that pays for this request.\\n * @param nonce - the nonce value from the request.\\n * @param success - true if the sender transaction succeeded, false if reverted.\\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\\n */\\n event UserOperationEvent(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address indexed paymaster,\\n uint256 nonce,\\n bool success,\\n uint256 actualGasCost,\\n uint256 actualGasUsed\\n );\\n\\n /**\\n * account \\\"sender\\\" was deployed.\\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\\n * @param sender the account that is deployed\\n * @param factory the factory used to deploy this account (in the initCode)\\n * @param paymaster the paymaster used by this UserOp\\n */\\n event AccountDeployed(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address factory,\\n address paymaster\\n );\\n\\n /**\\n * An event emitted if the UserOperation \\\"callData\\\" reverted with non-zero length\\n * @param userOpHash the request unique identifier.\\n * @param sender the sender of this request\\n * @param nonce the nonce used in the request\\n * @param revertReason - the return bytes from the (reverted) call to \\\"callData\\\".\\n */\\n event UserOperationRevertReason(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n uint256 nonce,\\n bytes revertReason\\n );\\n\\n /**\\n * an event emitted by handleOps(), before starting the execution loop.\\n * any event emitted before this event, is part of the validation.\\n */\\n event BeforeExecution();\\n\\n /**\\n * signature aggregator used by the following UserOperationEvents within this bundle.\\n */\\n event SignatureAggregatorChanged(address indexed aggregator);\\n\\n /**\\n * a custom revert error of handleOps, to identify the offending op.\\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\\n * @param reason - revert reason\\n * The string starts with a unique code \\\"AAmn\\\", where \\\"m\\\" is \\\"1\\\" for factory, \\\"2\\\" for account and \\\"3\\\" for paymaster issues,\\n * so a failure can be attributed to the correct entity.\\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\\n */\\n error FailedOp(uint256 opIndex, string reason);\\n\\n /**\\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\\n */\\n error SignatureValidationFailed(address aggregator);\\n\\n /**\\n * Successful result from simulateValidation.\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n */\\n error ValidationResult(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo\\n );\\n\\n /**\\n * Successful result from simulateValidation, if the account returns a signature aggregator\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\\n * bundler MUST use it to verify the signature, or reject the UserOperation\\n */\\n error ValidationResultWithAggregation(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo,\\n AggregatorStakeInfo aggregatorInfo\\n );\\n\\n /**\\n * return value of getSenderAddress\\n */\\n error SenderAddressResult(address sender);\\n\\n /**\\n * return value of simulateHandleOp\\n */\\n error ExecutionResult(\\n uint256 preOpGas,\\n uint256 paid,\\n uint48 validAfter,\\n uint48 validUntil,\\n bool targetSuccess,\\n bytes targetResult\\n );\\n\\n //UserOps handled, per aggregator\\n struct UserOpsPerAggregator {\\n UserOperation[] userOps;\\n // aggregator address\\n IAggregator aggregator;\\n // aggregated signature\\n bytes signature;\\n }\\n\\n /**\\n * Execute a batch of UserOperation.\\n * no signature aggregator is used.\\n * if any account requires an aggregator (that is, it returned an aggregator when\\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\\n * @param ops the operations to execute\\n * @param beneficiary the address to receive the fees\\n */\\n function handleOps(\\n UserOperation[] calldata ops,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * Execute a batch of UserOperation with Aggregators\\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\\n * @param beneficiary the address to receive the fees\\n */\\n function handleAggregatedOps(\\n UserOpsPerAggregator[] calldata opsPerAggregator,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * generate a request Id - unique identifier for this request.\\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\\n */\\n function getUserOpHash(\\n UserOperation calldata userOp\\n ) external view returns (bytes32);\\n\\n /**\\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\\n * @param userOp the user operation to validate.\\n */\\n function simulateValidation(UserOperation calldata userOp) external;\\n\\n /**\\n * gas and return values during simulation\\n * @param preOpGas the gas used for validation (including preValidationGas)\\n * @param prefund the required prefund for this operation\\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\\n */\\n struct ReturnInfo {\\n uint256 preOpGas;\\n uint256 prefund;\\n bool sigFailed;\\n uint48 validAfter;\\n uint48 validUntil;\\n bytes paymasterContext;\\n }\\n\\n /**\\n * returned aggregated signature info.\\n * the aggregator returned by the account, and its current stake.\\n */\\n struct AggregatorStakeInfo {\\n address aggregator;\\n StakeInfo stakeInfo;\\n }\\n\\n /**\\n * Get counterfactual sender address.\\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\\n * this method always revert, and returns the address in SenderAddressResult error\\n * @param initCode the constructor code to be passed into the UserOperation.\\n */\\n function getSenderAddress(bytes memory initCode) external;\\n\\n /**\\n * simulate full execution of a UserOperation (including both validation and target execution)\\n * this method will always revert with \\\"ExecutionResult\\\".\\n * it performs full validation of the UserOperation, but ignores signature error.\\n * an optional target address is called after the userop succeeds, and its value is returned\\n * (before the entire call is reverted)\\n * Note that in order to collect the the success/failure of the target call, it must be executed\\n * with trace enabled to track the emitted events.\\n * @param op the UserOperation to simulate\\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\\n * are set to the return from that call.\\n * @param targetCallData callData to pass to target address\\n */\\n function simulateHandleOp(\\n UserOperation calldata op,\\n address target,\\n bytes calldata targetCallData\\n ) external;\\n}\\n\",\"keccak256\":\"0x9ccb1b188eda8bbf5f6c2d01bd83c3d8b2b04fcf745283051d31fe96d1d8e40f\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/INonceManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\ninterface INonceManager {\\n /**\\n * Return the next nonce for this sender.\\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\\n * But UserOp with different keys can come with arbitrary order.\\n *\\n * @param sender the account address\\n * @param key the high 192 bit of the nonce\\n * @return nonce a full nonce to pass for next UserOp with this sender.\\n */\\n function getNonce(\\n address sender,\\n uint192 key\\n ) external view returns (uint256 nonce);\\n\\n /**\\n * Manually increment the nonce of the sender.\\n * This method is exposed just for completeness..\\n * Account does NOT need to call it, neither during validation, nor elsewhere,\\n * as the EntryPoint will update the nonce regardless.\\n * Possible use-case is call it with various keys to \\\"initialize\\\" their nonces to one, so that future\\n * UserOperations will not pay extra for the first transaction with a given key.\\n */\\n function incrementNonce(uint192 key) external;\\n}\\n\",\"keccak256\":\"0xce478ad0fa0d18a3b785ac854623029e7ab463d05873dfaa365abfa1bf100912\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IStakeManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8.12;\\n\\n/**\\n * manage deposits and stakes.\\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\\n * stake is value locked for at least \\\"unstakeDelay\\\" by the staked entity.\\n */\\ninterface IStakeManager {\\n event Deposited(address indexed account, uint256 totalDeposit);\\n\\n event Withdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /// Emitted when stake or unstake delay are modified\\n event StakeLocked(\\n address indexed account,\\n uint256 totalStaked,\\n uint256 unstakeDelaySec\\n );\\n\\n /// Emitted once a stake is scheduled for withdrawal\\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\\n\\n event StakeWithdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /**\\n * @param deposit the entity's deposit\\n * @param staked true if this entity is staked.\\n * @param stake actual amount of ether staked for this entity.\\n * @param unstakeDelaySec minimum delay to withdraw the stake.\\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\\n * and the rest fit into a 2nd cell.\\n * 112 bit allows for 10^15 eth\\n * 48 bit for full timestamp\\n * 32 bit allows 150 years for unstake delay\\n */\\n struct DepositInfo {\\n uint112 deposit;\\n bool staked;\\n uint112 stake;\\n uint32 unstakeDelaySec;\\n uint48 withdrawTime;\\n }\\n\\n //API struct used by getStakeInfo and simulateValidation\\n struct StakeInfo {\\n uint256 stake;\\n uint256 unstakeDelaySec;\\n }\\n\\n /// @return info - full deposit information of given account\\n function getDepositInfo(\\n address account\\n ) external view returns (DepositInfo memory info);\\n\\n /// @return the deposit (for gas payment) of the account\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * add to the deposit of the given account\\n */\\n function depositTo(address account) external payable;\\n\\n /**\\n * add to the account's stake - amount and delay\\n * any pending unstake is first cancelled.\\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\\n */\\n function addStake(uint32 _unstakeDelaySec) external payable;\\n\\n /**\\n * attempt to unlock the stake.\\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\\n */\\n function unlockStake() external;\\n\\n /**\\n * withdraw from the (unlocked) stake.\\n * must first call unlockStake and wait for the unstakeDelay to pass\\n * @param withdrawAddress the address to send withdrawn value.\\n */\\n function withdrawStake(address payable withdrawAddress) external;\\n\\n /**\\n * withdraw from the deposit.\\n * @param withdrawAddress the address to send withdrawn value.\\n * @param withdrawAmount the amount to withdraw.\\n */\\n function withdrawTo(\\n address payable withdrawAddress,\\n uint256 withdrawAmount\\n ) external;\\n}\\n\",\"keccak256\":\"0xadcea606c9b7aafe6645441f2154a60f271330b0eee5292a632aa71c1672d546\",\"license\":\"GPL-3.0-only\"},\"contracts/aa-4337/interfaces/UserOperation.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable no-inline-assembly */\\n\\nimport {calldataKeccak} from \\\"../core/Helpers.sol\\\";\\n\\n/**\\n * User Operation struct\\n * @param sender the sender account of this request.\\n * @param nonce unique value the sender uses to verify it is not a replay.\\n * @param initCode if set, the account contract will be created by this constructor/\\n * @param callData the method call to execute on this account.\\n * @param callGasLimit the gas limit passed to the callData method call.\\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\\n * @param maxFeePerGas same as EIP-1559 gas parameter.\\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\\n */\\nstruct UserOperation {\\n address sender;\\n uint256 nonce;\\n bytes initCode;\\n bytes callData;\\n uint256 callGasLimit;\\n uint256 verificationGasLimit;\\n uint256 preVerificationGas;\\n uint256 maxFeePerGas;\\n uint256 maxPriorityFeePerGas;\\n bytes paymasterAndData;\\n bytes signature;\\n}\\n\\n/**\\n * Utility functions helpful when working with UserOperation structs.\\n */\\nlibrary UserOperationLib {\\n function getSender(\\n UserOperation calldata userOp\\n ) internal pure returns (address) {\\n address data;\\n //read sender from userOp, which is first userOp member (saves 800 gas...)\\n assembly {\\n data := calldataload(userOp)\\n }\\n return address(uint160(data));\\n }\\n\\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\\n // pay above what he signed for.\\n function gasPrice(\\n UserOperation calldata userOp\\n ) internal view returns (uint256) {\\n unchecked {\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n if (maxFeePerGas == maxPriorityFeePerGas) {\\n //legacy mode (for networks that don't support basefee opcode)\\n return maxFeePerGas;\\n }\\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\\n }\\n }\\n\\n function pack(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes memory ret) {\\n address sender = getSender(userOp);\\n uint256 nonce = userOp.nonce;\\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\\n bytes32 hashCallData = calldataKeccak(userOp.callData);\\n uint256 callGasLimit = userOp.callGasLimit;\\n uint256 verificationGasLimit = userOp.verificationGasLimit;\\n uint256 preVerificationGas = userOp.preVerificationGas;\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\\n\\n return\\n abi.encode(\\n sender,\\n nonce,\\n hashInitCode,\\n hashCallData,\\n callGasLimit,\\n verificationGasLimit,\\n preVerificationGas,\\n maxFeePerGas,\\n maxPriorityFeePerGas,\\n hashPaymasterAndData\\n );\\n }\\n\\n function hash(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes32) {\\n return keccak256(pack(userOp));\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n}\\n\",\"keccak256\":\"0x2429f5cc546bdee08c7e63858d0dda8491eaa3ab5194df884dc948c1154d2834\",\"license\":\"GPL-3.0\"},\"contracts/facets/Modifiers.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {LibGuardian} from \\\"../libraries/LibGuardian.sol\\\";\\nimport {BarzStorage} from \\\"../libraries/LibAppStorage.sol\\\";\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\n\\n/**\\n * @title Modifiers\\n * @dev Responsible for providing modifiers/util functions to Facet contracts\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\nabstract contract Modifiers is BarzStorage {\\n uint8 constant INNER_STRUCT = 0;\\n\\n error CallerNotGuardian();\\n error CallerNotGuardianOrOwner();\\n error DuplicateApprover();\\n error ZeroApproverLength();\\n error UnregisteredFacetAndSelectors();\\n\\n /**\\n * @notice Modifier to only allow guardian to make a call, reverts if any other entity is the caller\\n */\\n modifier onlyGuardian() {\\n if (!LibGuardian.isGuardian(msg.sender)) revert CallerNotGuardian();\\n _;\\n }\\n\\n /**\\n * @notice Modifier to only allow guardian or owner to make a call, reverts if any other entity is the caller\\n */\\n modifier onlyGuardianOrOwner() {\\n if (!LibGuardian.isGuardian(msg.sender) && address(this) != msg.sender)\\n revert CallerNotGuardianOrOwner();\\n _;\\n }\\n\\n /**\\n * @notice Checks if the approver address is the array is unique with no duplicate\\n * @dev This method loops through the array and checks if a duplicate address exists, it reverts if duplicate address exists\\n * @param approvers Array of address\\n */\\n function _checkApprover(\\n address[] memory approvers\\n ) internal pure returns (bool) {\\n uint256 approverLength = approvers.length;\\n if (0 == approverLength) revert ZeroApproverLength();\\n for (uint256 i; i < approverLength - 1; ) {\\n for (uint256 j = i + 1; j < approverLength; ) {\\n if (approvers[i] == approvers[j]) {\\n revert DuplicateApprover(); // Found a duplicate\\n }\\n unchecked {\\n ++j;\\n }\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n return false; // No duplicates found\\n }\\n\\n /**\\n * @notice Checks if the facet getting added or replaced is registered to facet registry\\n * @dev This method loops through the cut and checks if the facet getting added/replaced is registered to facet registry\\n * @param _diamondCut Array of FacetCut, data for diamondCut defined in EIP-2535\\n */\\n function _checkFacetCutValidity(\\n IDiamondCut.FacetCut[] memory _diamondCut\\n ) internal view {\\n uint256 diamondCutLength = _diamondCut.length;\\n for (uint256 i; i < diamondCutLength; ) {\\n if (\\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Add ||\\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Replace\\n ) {\\n if (\\n !s.facetRegistry.areFacetFunctionSelectorsRegistered(\\n _diamondCut[i].facetAddress,\\n _diamondCut[i].functionSelectors\\n )\\n ) revert UnregisteredFacetAndSelectors();\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb42956323d199bdec243a5f9859439aae057fbfdd1d79e3a96afc857ecb3115f\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/DiamondCutFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {LibDiamond} from \\\"../../libraries/LibDiamond.sol\\\";\\nimport {LibGuardian} from \\\"../../libraries/LibGuardian.sol\\\";\\nimport {ISecurityManager} from \\\"../../infrastructure/interfaces/ISecurityManager.sol\\\";\\nimport {SignatureChecker} from \\\"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\\\";\\nimport {LibFacetStorage, DiamondCutApprovalConfig, ApprovalConfig} from \\\"../../libraries/LibFacetStorage.sol\\\";\\nimport {Modifiers} from \\\"../Modifiers.sol\\\";\\nimport {IDiamondCut} from \\\"./interfaces/IDiamondCut.sol\\\";\\n\\n/**\\n * @title DiamondCut Facet\\n * @dev Responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract DiamondCutFacet is Modifiers, IDiamondCut {\\n ISecurityManager public immutable securityManager;\\n\\n /**\\n * @notice This constructor sets the Security Manager address which is an immutable variable.\\n * Immutable variables do not impact the storage of diamond\\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\\n */\\n constructor(address _securityManager) {\\n securityManager = ISecurityManager(_securityManager);\\n }\\n\\n /**\\n * @notice Updates the flag for the interfaceId\\n * @param _interfaceId InterfaceID to update the mapping\\n * @param _flag Bool value to update the mapping of the given interface ID\\n */\\n function updateSupportsInterface(\\n bytes4 _interfaceId,\\n bool _flag\\n ) external override onlyWhenUnlocked {\\n LibDiamond.enforceIsSelf();\\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId] = _flag;\\n emit SupportsInterfaceUpdated(_interfaceId, _flag);\\n }\\n\\n /**\\n * @notice Add/replace/remove any number of functions and optionally execute\\n * a function with delegatecall when guardians don't exist\\n * @param _diamondCut Contains the facet addresses and function selectors\\n * @param _init The address of the contract or facet to execute _calldata. It's prohibited in Barz\\n */\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata\\n ) external override onlyWhenUnlocked {\\n LibDiamond.enforceIsSelf();\\n\\n _checkFacetCutValidity(_diamondCut);\\n // require approval from guardian if guardian exists\\n if (0 != LibGuardian.guardianCount())\\n revert DiamondCutFacet__InvalidRouteWithGuardian();\\n if (address(0) != _init) revert DiamondCutFacet__InvalidInitAddress();\\n\\n unchecked {\\n ++LibFacetStorage.diamondCutStorage().nonce;\\n }\\n LibDiamond.diamondCut(_diamondCut, address(0), \\\"\\\");\\n }\\n\\n /**\\n * @notice Add/replace/remove any number of functions and optionally execute\\n * a function with delegatecall when guardians exist\\n * @param _diamondCut Contains the facet addresses and function selectors\\n * @param _approvers Guardian or owner address that approves the diamond cut\\n * @param _signatures Signature of Guardians or owner that approves the diamond cut\\n */\\n function diamondCutWithGuardian(\\n FacetCut[] calldata _diamondCut,\\n address[] calldata _approvers,\\n bytes[] calldata _signatures\\n ) external override onlyWhenUnlocked {\\n if (_approvers.length != _signatures.length)\\n revert DiamondCutFacet__InvalidArrayLength();\\n _checkFacetCutValidity(_diamondCut);\\n if (0 == LibGuardian.guardianCount())\\n revert DiamondCutFacet__InvalidRouteWithGuardian();\\n\\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\\n\\n _checkApprover(_approvers);\\n _checkDuplicateOnChainApprover(cutHash, _approvers);\\n\\n bool onChainOwnerApproval = getOwnerCutApprovalWithTimeValidity(\\n cutHash\\n );\\n\\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\\n if (\\n _approvers.length +\\n getDiamondCutApprovalCountWithTimeValidity(cutHash) <\\n LibGuardian.majorityOfGuardians() + threshold\\n ) revert DiamondCutFacet__InsufficientApprovers();\\n\\n bool ownerApproved;\\n for (uint256 i; i < _approvers.length; ) {\\n if (\\n !LibGuardian.isGuardian(_approvers[i]) &&\\n _approvers[i] != address(this)\\n ) revert DiamondCutFacet__InvalidApprover();\\n if (_approvers[i] == address(this)) {\\n if (onChainOwnerApproval)\\n revert DiamondCutFacet__OwnerAlreadyApproved();\\n ownerApproved = true;\\n }\\n if (\\n !SignatureChecker.isValidSignatureNow(\\n _approvers[i],\\n cutHash,\\n _signatures[i]\\n )\\n ) revert DiamondCutFacet__InvalidApproverSignature();\\n unchecked {\\n ++i;\\n }\\n }\\n if (!ownerApproved && !onChainOwnerApproval)\\n revert DiamondCutFacet__LackOfOwnerApproval();\\n\\n unchecked {\\n ++LibFacetStorage.diamondCutStorage().nonce;\\n }\\n LibDiamond.diamondCut(_diamondCut, address(0), \\\"\\\");\\n }\\n\\n /**\\n * @notice Approves diamond cut. This can only be called directly from guardian or owner\\n * @param _diamondCut Contains the facet addresses and function selectors\\n */\\n function approveDiamondCut(\\n FacetCut[] calldata _diamondCut\\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\\n if (LibGuardian.guardianCount() == 0)\\n revert DiamondCutFacet__InvalidRouteWithoutGuardian();\\n DiamondCutApprovalConfig storage ds = LibFacetStorage\\n .diamondCutStorage()\\n .diamondCutApprovalConfigs[INNER_STRUCT];\\n _checkFacetCutValidity(_diamondCut);\\n\\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\\n uint64 approvalValidUntil = uint64(\\n block.timestamp + getApprovalValidationPeriod()\\n );\\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(\\n true,\\n approvalValidUntil\\n );\\n emit DiamondCutApproved(_diamondCut);\\n if (\\n (getDiamondCutApprovalCountWithTimeValidity(cutHash) >=\\n LibGuardian.majorityOfGuardians()) &&\\n getOwnerCutApprovalWithTimeValidity(cutHash)\\n ) {\\n unchecked {\\n ++LibFacetStorage.diamondCutStorage().nonce;\\n }\\n LibDiamond.diamondCut(_diamondCut, address(0), \\\"\\\");\\n }\\n }\\n\\n /**\\n * @notice Revokes the approval of diamond cut. This can only be called directly from guardian or owner\\n * @param _diamondCut Contains the facet addresses and function selectors\\n */\\n function revokeDiamondCutApproval(\\n FacetCut[] calldata _diamondCut\\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\\n DiamondCutApprovalConfig storage ds = LibFacetStorage\\n .diamondCutStorage()\\n .diamondCutApprovalConfigs[INNER_STRUCT];\\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\\n if (!ds.isDiamondCutApproved[cutHash][msg.sender].isApproved)\\n revert DiamondCutFacet__CannotRevokeUnapproved();\\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(false, 0);\\n emit DiamondCutApprovalRevoked(_diamondCut);\\n }\\n\\n /**\\n * @notice Gets the number of approvals of diamond cut from guardians\\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\\n */\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 _diamondCutHash\\n ) public view override returns (uint256 approvalCount) {\\n address[] memory guardians = LibGuardian.getGuardians();\\n uint256 guardiansLength = guardians.length;\\n for (uint256 i; i < guardiansLength; ) {\\n if (isCutApproved(_diamondCutHash, guardians[i])) {\\n unchecked {\\n ++approvalCount;\\n }\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n return approvalCount;\\n }\\n\\n /**\\n * @notice Returns if the owner has approved the diamond cut\\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\\n * @return isApprovedByOwner Bool value showing if the owner approved the cut\\n */\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 _diamondCutHash\\n ) public view override returns (bool isApprovedByOwner) {\\n isApprovedByOwner = isCutApproved(_diamondCutHash, address(this));\\n }\\n\\n /**\\n * @notice Returns if the given approver has approved the diamond cut\\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\\n * @param _approver Address of approver\\n * @return isApproved Bool value showing if the approver approved the cut\\n */\\n function isCutApproved(\\n bytes32 _diamondCutHash,\\n address _approver\\n ) public view override returns (bool isApproved) {\\n DiamondCutApprovalConfig storage ds = LibFacetStorage\\n .diamondCutStorage()\\n .diamondCutApprovalConfigs[INNER_STRUCT];\\n isApproved = (ds\\n .isDiamondCutApproved[_diamondCutHash][_approver].isApproved &&\\n block.timestamp <\\n ds.isDiamondCutApproved[_diamondCutHash][_approver].validUntil);\\n }\\n\\n /**\\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\\n * Approvers who approved on-chain should not be included in the off-chain approval\\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\\n * @param _approvers List of approver addresses\\n */\\n function _checkDuplicateOnChainApprover(\\n bytes32 _diamondCutHash,\\n address[] memory _approvers\\n ) public view {\\n address[] memory guardians = LibGuardian.getGuardians();\\n uint256 guardianLength = guardians.length;\\n uint256 approversLength = _approvers.length;\\n for (uint256 i; i < guardianLength; ) {\\n if (isCutApproved(_diamondCutHash, guardians[i])) {\\n for (uint256 j; j < approversLength; ) {\\n if (_approvers[j] == guardians[i])\\n revert DiamondCutFacet__DuplicateApproval();\\n unchecked {\\n ++j;\\n }\\n }\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * @notice Returns the diamond cut hash. This function ensures that this hash is safe from replay attack by including\\n * salt, address, chainId, and nonce, etc.\\n * @param _diamondCut Contains the facet addresses and function selectors\\n * @return cutHash Diamond Cut Hash\\n */\\n function getDiamondCutHash(\\n FacetCut[] calldata _diamondCut\\n ) public view override returns (bytes32 cutHash) {\\n cutHash = keccak256(\\n abi.encodePacked(\\n \\\"\\\\x19Ethereum Signed Message:\\\\n32\\\",\\n keccak256(\\n abi.encode(\\n keccak256(abi.encode(_diamondCut)),\\n address(this),\\n block.chainid,\\n LibFacetStorage.diamondCutStorage().nonce\\n )\\n )\\n )\\n );\\n }\\n\\n /**\\n * @notice Returns the approval validation Period\\n * @dev This method fetches the validation period from the security manager\\n * @return approvalValidationPeriod Approval validation period of Barz contract fetched from security manager\\n */\\n function getApprovalValidationPeriod()\\n internal\\n view\\n returns (uint256 approvalValidationPeriod)\\n {\\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\\n address(this)\\n );\\n if (approvalValidationPeriod <= 0)\\n revert DiamondCutFacet__InvalidApprovalValidationPeriod();\\n }\\n\\n /**\\n * @notice Returns the diamond cut nonce of this wallet\\n * @dev This method fetches the nonce from diamond cut storage\\n * @return cutNonce Nonce of diamond cut to protect from reply attacks\\n */\\n function getDiamondCutNonce()\\n public\\n view\\n override\\n returns (uint128 cutNonce)\\n {\\n cutNonce = LibFacetStorage.diamondCutStorage().nonce;\\n }\\n}\\n\",\"keccak256\":\"0xe91a7dd2daabf2e989c94089f4f1eb0da94276c3070559ac8988838e10dd1f5d\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/infrastructure/interfaces/IFacetRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Registry Interface\\n * @dev Interface for Facet Registry contract to keep track of facets & function selectors addable to user wallets\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IFacetRegistry {\\n struct FacetRegistryConfig {\\n bytes4[] selectors;\\n mapping(bytes4 => FacetInfo) info;\\n }\\n struct FacetInfo {\\n bool exists;\\n uint128 index;\\n }\\n\\n event FacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] facetSelectors\\n );\\n event FacetFunctionSelectorsRemoved(address facet, bytes4[] facetSelectors);\\n\\n error FacetRegistry__FacetSelectorAlreadyRegistered();\\n error FacetRegistry__UnregisteredFacetSelector();\\n\\n function registerFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function removeFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function areFacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external view returns (bool);\\n\\n function isFacetFunctionSelectorRegistered(\\n address facet,\\n bytes4 facetSelector\\n ) external view returns (bool);\\n\\n function getFacetFunctionSelectors(\\n address facet\\n ) external view returns (bytes4[] memory);\\n}\\n\",\"keccak256\":\"0x6e6dd2cab346ef7c31230740ec48d2925e4a9ab24c2f2fb268baaf408dcf02ef\",\"license\":\"Apache-2.0\"},\"contracts/infrastructure/interfaces/ISecurityManager.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Registry Interface\\n * @dev Infrastructure contract to manage security parameters of users\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\ninterface ISecurityManager {\\n error SecurityManager__OutOfBoundary();\\n error SecurityManager__CallerNotWallet();\\n error SecurityManager__AlreadyIntialized();\\n\\n function initializeAdditionSecurityPeriod(\\n uint128 defaultAdditionSecurityPeriod,\\n uint128 minAdditionSecurityPeriod,\\n uint128 maxAdditionSecurityPeriod\\n ) external;\\n\\n function initializeRemovalSecurityPeriod(\\n uint128 defaultRemovalSecurityPeriod,\\n uint128 minRemovalSecurityPeriod,\\n uint128 maxRemovalSecurityPeriod\\n ) external;\\n\\n function initializeApprovalValidationPeriod(\\n uint128 defaultApprovalValidationPeriod,\\n uint128 minApprovalValidationPeriod,\\n uint128 maxApprovalValidationPeriod\\n ) external;\\n\\n function initializeMigrationPeriod(\\n uint128 defaultMigrationPeriod,\\n uint128 minMigrationPeriod,\\n uint128 maxMigrationPeriod\\n ) external;\\n\\n function initializeLockPeriod(\\n uint128 defaultLockPeriod,\\n uint128 minLockPeriod,\\n uint128 maxLockPeriod\\n ) external;\\n\\n function initializeRecoveryPeriod(\\n uint128 defaultRecoveryPeriod,\\n uint128 minRecoveryPeriod,\\n uint128 maxRecoveryPeriod\\n ) external;\\n\\n function initializeSecurityWindow(\\n uint128 defaultSecurityWindow,\\n uint128 minSecurityWindow,\\n uint128 maxSecurityWindow\\n ) external;\\n\\n function setAdditionSecurityPeriod(\\n address wallet,\\n uint128 additionSecurityPeriod\\n ) external;\\n\\n function setRemovalSecurityPeriod(\\n address wallet,\\n uint128 removalSecurityPeriod\\n ) external;\\n\\n function setSecurityWindow(address wallet, uint128 securityWindow) external;\\n\\n function setRecoveryPeriod(address wallet, uint128 recoveryPeriod) external;\\n\\n function setLockPeriod(address wallet, uint128 lockPeriod) external;\\n\\n function setApprovalValidationPeriod(\\n address wallet,\\n uint128 approvalValidationPeriod\\n ) external;\\n\\n function setMigrationPeriod(\\n address wallet,\\n uint128 migrationPeriod\\n ) external;\\n\\n function additionSecurityPeriodOf(\\n address wallet\\n ) external view returns (uint128);\\n\\n function removalSecurityPeriodOf(\\n address wallet\\n ) external view returns (uint128);\\n\\n function securityWindowOf(address wallet) external view returns (uint128);\\n\\n function recoveryPeriodOf(address wallet) external view returns (uint128);\\n\\n function lockPeriodOf(address wallet) external view returns (uint128);\\n\\n function migrationPeriodOf(address wallet) external view returns (uint128);\\n\\n function approvalValidationPeriodOf(\\n address wallet\\n ) external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x9ac6566033ef81ba5744c8ed2b08f130b781b498ab9245bcca87567669549552\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibAppStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {SafeCast} from \\\"@openzeppelin/contracts/utils/math/SafeCast.sol\\\";\\nimport {IEntryPoint} from \\\"../aa-4337/interfaces/IEntryPoint.sol\\\";\\nimport {IFacetRegistry} from \\\"../infrastructure/interfaces/IFacetRegistry.sol\\\";\\n\\n/*\\n * @title App Storage\\n * @dev App storage for Barz contract to prevent storage collision\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Lock {\\n uint64 release;\\n bytes4 locker;\\n}\\n\\nstruct InitializersStorage {\\n // NOTE: initialized is a variable to make sure the initialization is only done once.\\n uint8 signerInitialized;\\n uint8 accountInitialized;\\n uint8 restrictionsInitialized;\\n}\\n\\nstruct AppStorage {\\n mapping(uint256 => InitializersStorage) initStorage;\\n uint8 signerMigration;\\n bytes4 validateOwnerSignatureSelector;\\n IEntryPoint entryPoint;\\n IFacetRegistry facetRegistry;\\n mapping(uint256 => Lock) locks;\\n}\\n\\nlibrary LibAppStorage {\\n error LibAppStorage__AccountAlreadyUninitialized();\\n error LibAppStorage__AccountMustBeUninitialized();\\n error LibAppStorage__SignerAlreadyUninitialized();\\n error LibAppStorage__SignerMustBeUninitialized();\\n\\n function appStorage() internal pure returns (AppStorage storage ds) {\\n assembly {\\n ds.slot := 0\\n }\\n }\\n\\n function setSignerUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerAlreadyUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 0;\\n }\\n\\n function getValidateOwnerSignatureSelector()\\n internal\\n view\\n returns (bytes4 selector)\\n {\\n selector = appStorage().validateOwnerSignatureSelector;\\n }\\n\\n function setValidateOwnerSignatureSelector(\\n bytes4 _validateOwnerSignatureSelector\\n ) internal {\\n appStorage()\\n .validateOwnerSignatureSelector = _validateOwnerSignatureSelector;\\n }\\n\\n function enforceSignerInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerMustBeUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 1;\\n }\\n\\n function enforceAccountInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].accountInitialized) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n s.initStorage[0].accountInitialized = 1;\\n }\\n\\n function initiateSignerMigration() internal {\\n appStorage().signerMigration = 1;\\n }\\n\\n function enforceSignerMigration() internal view {\\n if (1 != appStorage().signerMigration) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n }\\n\\n function finalizeSignerMigration() internal {\\n appStorage().signerMigration = 0;\\n }\\n\\n function setLock(uint256 _releaseAfter, bytes4 _locker) internal {\\n appStorage().locks[0] = Lock(SafeCast.toUint64(_releaseAfter), _locker);\\n }\\n\\n function enforceRestrictionsInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__SignerMustBeUninitialized();\\n s.initStorage[0].restrictionsInitialized = 1;\\n }\\n\\n function setRestrictionsUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__AccountAlreadyUninitialized();\\n s.initStorage[0].restrictionsInitialized = 0;\\n }\\n}\\n\\ncontract BarzStorage {\\n AppStorage internal s;\\n modifier onlyWhenUnlocked() {\\n require(\\n uint64(block.timestamp) >= s.locks[0].release,\\n \\\"Account Locked\\\"\\n );\\n _;\\n }\\n modifier onlyWhenLocked() {\\n require(\\n uint64(block.timestamp) < s.locks[0].release,\\n \\\"Account Unlocked\\\"\\n );\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x48524007862a6ce0e07f645950613ce6513ce073c37a109c75019683d42bae27\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\\n bytes4(keccak256(\\\"verifyRestrictions(address,address,uint256,bytes)\\\"));\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // Default Fallback Handler of the barz.\\n IDiamondLoupe defaultFallbackHandler;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function enforceIsSelf() internal view {\\n require(msg.sender == address(this), \\\"LibDiamond: Caller not self\\\");\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n\\n unchecked {\\n facetIndex++;\\n }\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n\\n function restrictionsFacet() internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(\\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2cabdc00de859c3a3170ce3bda5d0e5fd3933d47ce904fd1585f9818b02572f8\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibFacetStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Storage\\n * @dev Storage contract to store each facets variables with diamond storage\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Secp256k1VerificationStorage {\\n address signer;\\n}\\n\\nstruct Secp256r1VerificationStorage {\\n uint256[2] q;\\n}\\n\\nstruct GuardianStorage {\\n mapping(bytes32 => uint256) pending;\\n mapping(uint8 => StorageConfig) configs;\\n}\\n\\nstruct Info {\\n bool exists;\\n uint128 index;\\n}\\n\\nstruct StorageConfig {\\n address[] addresses;\\n mapping(address => Info) info;\\n}\\n\\nstruct RecoveryConfig {\\n bytes recoveryPublicKey;\\n uint64 executeAfter;\\n}\\n\\nstruct ApprovalConfig {\\n bool isApproved;\\n uint64 validUntil;\\n}\\n\\nstruct RecoveryApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isNewOwnerApproved;\\n}\\n\\nstruct RecoveryStorage {\\n mapping(uint8 => RecoveryConfig) recoveryConfigs;\\n mapping(uint8 => RecoveryApprovalConfig) recoveryApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct RestrictionsStorage {\\n address[] restrictions;\\n mapping(address => bool) exists;\\n}\\n\\nstruct SignatureMigrationConfig {\\n bytes migrationPublicKey;\\n address migrationVerificationFacet;\\n bytes4[] migrationSelectors;\\n uint64 migrateAfter;\\n}\\n\\nstruct SignatureMigrationApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isMigrationApproved;\\n}\\n\\nstruct SignatureMigrationStorage {\\n mapping(uint8 => SignatureMigrationConfig) migrationConfigs;\\n mapping(uint8 => SignatureMigrationApprovalConfig) migrationApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct DiamondCutApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isDiamondCutApproved;\\n}\\n\\nstruct DiamondCutStorage {\\n mapping(uint8 => DiamondCutApprovalConfig) diamondCutApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct LockStorage {\\n uint128 nonce;\\n}\\n\\nlibrary LibFacetStorage {\\n bytes32 constant K1_STORAGE_POSITION =\\n keccak256(\\n \\\"v0.trustwallet.diamond.storage.Secp256k1VerificationStorage\\\"\\n );\\n bytes32 constant R1_STORAGE_POSITION =\\n keccak256(\\n \\\"v0.trustwallet.diamond.storage.Secp256r1VerificationStorage\\\"\\n );\\n bytes32 constant GUARDIAN_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.GuardianStorage\\\");\\n bytes32 constant RECOVERY_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.RecoveryStorage\\\");\\n bytes32 constant RESTRICTION_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.RestrictionsStorage\\\");\\n bytes32 constant MIGRATION_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.SignatureMigrationStorage\\\");\\n bytes32 constant DIAMONDCUT_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.DiamondCutStorage\\\");\\n bytes32 constant LOCK_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.LockStorage\\\");\\n\\n function k1Storage()\\n internal\\n pure\\n returns (Secp256k1VerificationStorage storage ds)\\n {\\n bytes32 storagePosition = K1_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function r1Storage()\\n internal\\n pure\\n returns (Secp256r1VerificationStorage storage ds)\\n {\\n bytes32 storagePosition = R1_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function guardianStorage()\\n internal\\n pure\\n returns (GuardianStorage storage ds)\\n {\\n bytes32 storagePosition = GUARDIAN_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function recoveryStorage()\\n internal\\n pure\\n returns (RecoveryStorage storage ds)\\n {\\n bytes32 storagePosition = RECOVERY_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function restrictionsStorage()\\n internal\\n pure\\n returns (RestrictionsStorage storage ds)\\n {\\n bytes32 storagePosition = RESTRICTION_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function migrationStorage()\\n internal\\n pure\\n returns (SignatureMigrationStorage storage ds)\\n {\\n bytes32 storagePosition = MIGRATION_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function diamondCutStorage()\\n internal\\n pure\\n returns (DiamondCutStorage storage ds)\\n {\\n bytes32 storagePosition = DIAMONDCUT_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function lockStorage() internal pure returns (LockStorage storage ds) {\\n bytes32 storagePosition = LOCK_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n}\\n\",\"keccak256\":\"0x87c85decfd943deda9540733e464cb1a92eba735a301e89ce6f798016e359761\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibGuardian.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {LibFacetStorage, StorageConfig} from \\\"./LibFacetStorage.sol\\\";\\n\\n/**\\n * @title LibGuardian\\n * @dev Internal Library to provide utility feature for Guardians stored in Guardian Facet Storage\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\nlibrary LibGuardian {\\n function majorityOfGuardians()\\n internal\\n view\\n returns (uint256 guardianNumber)\\n {\\n uint256 guardianLength = guardianCount();\\n guardianNumber = (guardianLength == 0) ? 0 : guardianLength / 2 + 1;\\n }\\n\\n function isGuardian(address _guardian) internal view returns (bool) {\\n StorageConfig storage config = LibFacetStorage\\n .guardianStorage()\\n .configs[0];\\n return config.info[_guardian].exists;\\n }\\n\\n function guardianCount() internal view returns (uint256) {\\n StorageConfig storage config = LibFacetStorage\\n .guardianStorage()\\n .configs[0];\\n return config.addresses.length;\\n }\\n\\n function getGuardians() internal view returns (address[] memory) {\\n StorageConfig storage config = LibFacetStorage\\n .guardianStorage()\\n .configs[0];\\n address[] memory addresses = new address[](config.addresses.length);\\n uint256 addressesLen = config.addresses.length;\\n for (uint256 i; i < addressesLen; ) {\\n addresses[i] = config.addresses[i];\\n unchecked {\\n ++i;\\n }\\n }\\n return addresses;\\n }\\n}\\n\",\"keccak256\":\"0x6a620992d5535878fc03d1a27a6675f4c1509adfb3ddbbca1c52b546c25392dc\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x60a06040523480156200001157600080fd5b506040516200379b3803806200379b833981016040819052620000349162000046565b6001600160a01b031660805262000078565b6000602082840312156200005957600080fd5b81516001600160a01b03811681146200007157600080fd5b9392505050565b6080516137006200009b600039600081816101f10152611b2501526137006000f3fe608060405234801561001057600080fd5b50600436106100d45760003560e01c806379c0d58d11610081578063afb877bb1161005b578063afb877bb146101d9578063de675a6d146101ec578063e33ecf0a1461023857600080fd5b806379c0d58d14610192578063836d6bfb146101b35780638824a0bb146101c657600080fd5b806326fc3ef4116100b257806326fc3ef4146101145780632f4d98ea1461015c5780633c0985681461017f57600080fd5b806313c34f4b146100d95780631c776dd5146100ee5780631f931c1c14610101575b600080fd5b6100ec6100e7366004612a97565b61024b565b005b6100ec6100fc366004612ad9565b6104df565b6100ec61010f366004612b9c565b610a76565b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9bf546040516fffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b61016f61016a366004612c4a565b610c7b565b6040519015158152602001610153565b6100ec61018d366004612ca4565b610c8d565b6101a56101a0366004612c4a565b610df2565b604051908152602001610153565b61016f6101c1366004612cdb565b610e4c565b6100ec6101d4366004612dd2565b610eed565b6100ec6101e7366004612a97565b610fe1565b6102137f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610153565b6101a5610246366004612a97565b61130e565b3360009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff1615801561028a5750303314155b156102c1576040517f6238ee3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610369576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064015b60405180910390fd5b60008080527f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be6020527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d3906103be848461130e565b60008181526020848152604080832033845290915290205490915060ff16610412576040517fedc5708300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051808201825260008082526020808301828152858352868252848320338452909152908390209151825491517fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000009092169015157fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff161761010067ffffffffffffffff90921691909102179055517f3c3d8c1f0b0faff6fe0ace6b485d0595a0106dce9e303f956fd941ebdbe9a98e906104d19086908690612f54565b60405180910390a150505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610582576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b8281146105bb576040517fe854148500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6105cd6105c886886130aa565b611435565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b754600003610650576040517fa788861700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061065c878761130e565b905061069a8585808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506115b392505050565b506106d881868680806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250610eed92505050565b60006106e382610c7b565b90506000816106f35760016106f6565b60005b60ff169050806107046116d0565b61070e9190613201565b61071784610df2565b6107219088613201565b1015610759576040517f709fb08000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805b878110156109a0576107d989898381811061077a5761077a613214565b905060200201602081019061078f9190613243565b73ffffffffffffffffffffffffffffffffffffffff1660009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff1690565b1580156108225750308989838181106107f4576107f4613214565b90506020020160208101906108099190613243565b73ffffffffffffffffffffffffffffffffffffffff1614155b15610859576040517f7b2cbbb400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3089898381811061086c5761086c613214565b90506020020160208101906108819190613243565b73ffffffffffffffffffffffffffffffffffffffff16036108d95783156108d4576040517fee21708000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600191505b6109628989838181106108ee576108ee613214565b90506020020160208101906109039190613243565b8689898581811061091657610916613214565b90506020028101906109289190613265565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061174f92505050565b610998576040517fac3d341600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60010161075d565b50801580156109ad575082155b156109e4576040517f6d21730400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9bf80546fffffffffffffffffffffffffffffffff808216600101167fffffffffffffffffffffffffffffffff00000000000000000000000000000000909116179055610a6a610a538a8c6130aa565b6000604051806020016040528060008152506117ca565b50505050505050505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610b19576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b610b2161195f565b610b2e6105c885876130aa565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75415610baf576040517fa788861700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff831615610bfd576040517f871cb76100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be5b600190810180547fffffffffffffffffffffffffffffffff0000000000000000000000000000000081166fffffffffffffffffffffffffffffffff91821690930116919091179055610c74610a5385876130aa565b5050505050565b6000610c878230610e4c565b92915050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610d30576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b610d3861195f565b7fffffffff00000000000000000000000000000000000000000000000000000000821660008181527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4922602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001685151590811790915582519384529083015280517f4e6bd17989efa6d6a9607ccaac1bba27b29f99622bc830d99a3a9883b21a19c79281900390910190a15050565b600080610dfd6119ca565b805190915060005b81811015610e4457610e3085848381518110610e2357610e23613214565b6020026020010151610e4c565b15610e3c578360010193505b600101610e05565b505050919050565b60008281527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d36020818152604080842073ffffffffffffffffffffffffffffffffffffffff8616855290915282205460ff168015610ee5575060008481526020828152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152902054610100900467ffffffffffffffff1642105b949350505050565b6000610ef76119ca565b805183519192509060005b82811015610fd957610f2086858381518110610e2357610e23613214565b15610fd15760005b82811015610fcf57848281518110610f4257610f42613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16868281518110610f7257610f72613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603610fc7576040517f50f5729f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600101610f28565b505b600101610f02565b505050505050565b3360009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff161580156110205750303314155b15611057576040517f6238ee3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff9081164290911610156110fa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75460000361117d576040517f3a76e1f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080527f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be6020527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d36111d36105c883856130aa565b60006111df848461130e565b905060006111eb611af4565b6111f59042613201565b6040805180820182526001815267ffffffffffffffff838116602080840191825260008881528982528581203382529091528490209251835491517fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000009092169015157fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff16176101009190921602179055519091507f6248ff757895beed7d43d135bccf59a26b7fbdf0fe8233487c44e82c0f266ba3906112b89087908790612f54565b60405180910390a16112c86116d0565b6112d183610df2565b101580156112e357506112e382610c7b565b15610c74577f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be610c1f565b60008282604051602001611323929190612f54565b6040516020818303038152906040528051906020012030466113627f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be90565b6001015460408051602081019590955273ffffffffffffffffffffffffffffffffffffffff9093169284019290925260608301526fffffffffffffffffffffffffffffffff16608082015260a001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905280516020918201207f19457468657265756d205369676e6564204d6573736167653a0a33320000000091830191909152603c820152605c0160405160208183030381529060405280519060200120905092915050565b805160005b818110156115ae57600083828151811061145657611456613214565b602002602001015160200151600281111561147357611473612e8a565b14806114ad5750600183828151811061148e5761148e613214565b60200260200101516020015160028111156114ab576114ab612e8a565b145b156115a657600254835173ffffffffffffffffffffffffffffffffffffffff9091169063df871f72908590849081106114e8576114e8613214565b60200260200101516000015185848151811061150657611506613214565b6020026020010151604001516040518363ffffffff1660e01b815260040161152f92919061331c565b602060405180830381865afa15801561154c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611570919061334b565b6115a6576040517ff41a931c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60010161143a565b505050565b80516000908082036115f1576040517f3aee2eec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b6115ff600183613368565b8110156116c6576000611613826001613201565b90505b828110156116bd5784818151811061163057611630613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1685838151811061166057611660613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16036116b5576040517f8dd19e7d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600101611616565b506001016115f4565b5060009392505050565b600080611723600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75490565b905080156117465761173660028261337b565b611741906001613201565b611749565b60005b91505090565b600080600061175e8585611bf6565b9092509050600081600481111561177757611777612e8a565b1480156117af57508573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b806117c057506117c0868686611c3b565b9695505050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921547f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff8116908190600090600716156118395750600381901c60009081526001840160205260409020545b60005b87518110156118b6576118a983838a848151811061185c5761185c613214565b6020026020010151600001518b858151811061187a5761187a613214565b6020026020010151602001518c868151811061189857611898613214565b602002602001015160400151611d98565b909350915060010161183c565b508282146118ef576002840180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff84161790555b600782161561191157600382901c600090815260018501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb67387878760405161194493929190613424565b60405180910390a16119568686612829565b50505050505050565b3330146119c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4c69624469616d6f6e643a2043616c6c6572206e6f742073656c6600000000006044820152606401610360565b565b60008080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b780546060929067ffffffffffffffff811115611a3257611a32612d07565b604051908082528060200260200182016040528015611a5b578160200160208202803683370190505b50825490915060005b81811015611aeb57836000018181548110611a8157611a81613214565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16838281518110611abe57611abe613214565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101611a64565b50909392505050565b6040517f52430c8d0000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906352430c8d90602401602060405180830381865afa158015611b81573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ba59190613510565b6fffffffffffffffffffffffffffffffff16905060008111611bf3576040517fdac5ec8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b90565b6000808251604103611c2c5760208301516040840151606085015160001a611c2087828585612928565b94509450505050611c34565b506000905060025b9250929050565b60008060008573ffffffffffffffffffffffffffffffffffffffff16631626ba7e60e01b8686604051602401611c72929190613542565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909416939093179092529051611cfb919061355b565b600060405180830381855afa9150503d8060008114611d36576040519150601f19603f3d011682016040523d82523d6000602084013e611d3b565b606091505b5091509150818015611d4f57506020815110155b80156117c0575080517f1626ba7e0000000000000000000000000000000000000000000000000000000090611d8d9083016020908101908401613577565b149695505050505050565b600080807f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f90506000845111611e50576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610360565b6000856002811115611e6457611e64612e8a565b0361203457611e8b8660405180606001604052806024815260200161365760249139612a17565b60005b845181101561202e576000858281518110611eab57611eab613214565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c15611f7e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c72656164792065786973747300000000000000000000006064820152608401610360565b7fffffffff0000000000000000000000000000000000000000000000000000000080831660008181526020879052604090207fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608d901b168e17905560e060058e901b811692831c199c909c1690821c179a8190036120125760038c901c600090815260018601602052604081209b909b555b8b61201c81613590565b9c505060019093019250611e8e915050565b5061281d565b600185600281111561204857612048612e8a565b036123385761206f866040518060600160405280602881526020016136a360289139612a17565b60005b845181101561202e57600085828151811061208f5761208f613214565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c308103612164576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4c69624469616d6f6e644375743a2043616e2774207265706c61636520696d6d60448201527f757461626c652066756e6374696f6e00000000000000000000000000000000006064820152608401610360565b8973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361221f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e00000000000000006064820152608401610360565b73ffffffffffffffffffffffffffffffffffffffff81166122c2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e207468617420646f65736e277420657869737400000000000000006064820152608401610360565b507fffffffff0000000000000000000000000000000000000000000000000000000090911660009081526020849052604090206bffffffffffffffffffffffff919091167fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608a901b16179055600101612072565b600285600281111561234c5761234c612e8a565b036127955773ffffffffffffffffffffffffffffffffffffffff8616156123f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d7573742062652061646472657373283029000000000000000000006064820152608401610360565b600388901c6007891660005b86518110156127755760008a900361243d578261241d816135c8565b60008181526001870160205260409020549b5093506007925061244b9050565b81612447816135c8565b9250505b6000806000808a858151811061246357612463613214565b6020908102919091018101517fffffffff0000000000000000000000000000000000000000000000000000000081166000908152918a9052604090912054909150606081901c612535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608401610360565b30606082901c036125c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e0000000000000000000000000000000000006064820152608401610360565b600587901b8f901b94507fffffffff0000000000000000000000000000000000000000000000000000000080861690831614612666577fffffffff000000000000000000000000000000000000000000000000000000008516600090815260208a90526040902080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff83161790555b7fffffffff0000000000000000000000000000000000000000000000000000000091909116600090815260208990526040812055600381901c611fff16925060051b60e01690508582146126fb576000828152600188016020526040902080547fffffffff0000000000000000000000000000000000000000000000000000000080841c19909116908516831c17905561274c565b80837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c817fffffffff0000000000000000000000000000000000000000000000000000000060001b901c198e16179c505b8460000361276a57600086815260018801602052604081208190559c505b505050600101612401565b50806127828360086135fd565b61278c9190613201565b9950505061281d565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560448201527f74416374696f6e000000000000000000000000000000000000000000000000006064820152608401610360565b50959694955050505050565b73ffffffffffffffffffffffffffffffffffffffff8216612848575050565b61286a8260405180606001604052806028815260200161367b60289139612a17565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051612892919061355b565b600060405180830381855af49150503d80600081146128cd576040519150601f19603f3d011682016040523d82523d6000602084013e6128d2565b606091505b509150915081612922578051156128ec5780518082602001fd5b83836040517f192105d7000000000000000000000000000000000000000000000000000000008152600401610360929190613614565b50505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561295f5750600090506003612a0e565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156129b3573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116612a0757600060019250925050612a0e565b9150600090505b94509492505050565b813b8181612922576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103609190613643565b60008083601f840112612a6457600080fd5b50813567ffffffffffffffff811115612a7c57600080fd5b6020830191508360208260051b8501011115611c3457600080fd5b60008060208385031215612aaa57600080fd5b823567ffffffffffffffff811115612ac157600080fd5b612acd85828601612a52565b90969095509350505050565b60008060008060008060608789031215612af257600080fd5b863567ffffffffffffffff80821115612b0a57600080fd5b612b168a838b01612a52565b90985096506020890135915080821115612b2f57600080fd5b612b3b8a838b01612a52565b90965094506040890135915080821115612b5457600080fd5b50612b6189828a01612a52565b979a9699509497509295939492505050565b803573ffffffffffffffffffffffffffffffffffffffff81168114612b9757600080fd5b919050565b600080600080600060608688031215612bb457600080fd5b853567ffffffffffffffff80821115612bcc57600080fd5b612bd889838a01612a52565b9097509550859150612bec60208901612b73565b94506040880135915080821115612c0257600080fd5b818801915088601f830112612c1657600080fd5b813581811115612c2557600080fd5b896020828501011115612c3757600080fd5b9699959850939650602001949392505050565b600060208284031215612c5c57600080fd5b5035919050565b80357fffffffff0000000000000000000000000000000000000000000000000000000081168114612b9757600080fd5b8015158114612ca157600080fd5b50565b60008060408385031215612cb757600080fd5b612cc083612c63565b91506020830135612cd081612c93565b809150509250929050565b60008060408385031215612cee57600080fd5b82359150612cfe60208401612b73565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff81118282101715612d5957612d59612d07565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715612da657612da6612d07565b604052919050565b600067ffffffffffffffff821115612dc857612dc8612d07565b5060051b60200190565b60008060408385031215612de557600080fd5b8235915060208084013567ffffffffffffffff811115612e0457600080fd5b8401601f81018613612e1557600080fd5b8035612e28612e2382612dae565b612d5f565b81815260059190911b82018301908381019088831115612e4757600080fd5b928401925b82841015612e6c57612e5d84612b73565b82529284019290840190612e4c565b80955050505050509250929050565b803560038110612b9757600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60038110612ef0577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b8183526000602080850194508260005b85811015612f49577fffffffff00000000000000000000000000000000000000000000000000000000612f3683612c63565b1687529582019590820190600101612f04565b509495945050505050565b60208082528181018390526000906040808401600586811b8601830188865b8981101561309b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc089840301855281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa18c3603018112612fd457600080fd5b8b01606073ffffffffffffffffffffffffffffffffffffffff612ff683612b73565b168552613004898301612e7b565b6130108a870182612eb9565b50878201357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe183360301811261304557600080fd5b90910188810191903567ffffffffffffffff81111561306357600080fd5b80871b360383131561307457600080fd5b81898701526130868287018285612ef4565b978a0197955050509187019150600101612f73565b50909998505050505050505050565b60006130b8612e2384612dae565b83815260208082019190600586811b8601368111156130d657600080fd5b865b818110156131c557803567ffffffffffffffff808211156130f95760008081fd5b818a0191506060823603121561310f5760008081fd5b613117612d36565b61312083612b73565b815261312d878401612e7b565b87820152604080840135838111156131455760008081fd5b939093019236601f85011261315c57600092508283fd5b8335925061316c612e2384612dae565b83815292871b840188019288810190368511156131895760008081fd5b948901945b848610156131ae5761319f86612c63565b8252948901949089019061318e565b9183019190915250885250509483019483016130d8565b5092979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610c8757610c876131d2565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561325557600080fd5b61325e82612b73565b9392505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261329a57600080fd5b83018035915067ffffffffffffffff8211156132b557600080fd5b602001915036819003821315611c3457600080fd5b600081518084526020808501945080840160005b83811015612f495781517fffffffff0000000000000000000000000000000000000000000000000000000016875295820195908201906001016132de565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000610ee560408301846132ca565b60006020828403121561335d57600080fd5b815161325e81612c93565b81810381811115610c8757610c876131d2565b6000826133b1577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60005b838110156133d15781810151838201526020016133b9565b50506000910152565b600081518084526133f28160208601602086016133b6565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6000606080830181845280875180835260808601915060808160051b87010192506020808a0160005b838110156134d4577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80898703018552815173ffffffffffffffffffffffffffffffffffffffff8151168752838101516134a885890182612eb9565b506040908101519087018890526134c1878901826132ca565b965050938201939082019060010161344d565b505073ffffffffffffffffffffffffffffffffffffffff8916908701525050838103604085015261350581866133da565b979650505050505050565b60006020828403121561352257600080fd5b81516fffffffffffffffffffffffffffffffff8116811461325e57600080fd5b828152604060208201526000610ee560408301846133da565b6000825161356d8184602087016133b6565b9190910192915050565b60006020828403121561358957600080fd5b5051919050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036135c1576135c16131d2565b5060010190565b6000816135d7576135d76131d2565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b8082028115828204841417610c8757610c876131d2565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000610ee560408301846133da565b60208152600061325e60208301846133da56fe4c69624469616d6f6e644375743a2041646420666163657420686173206e6f20636f64654c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a205265706c61636520666163657420686173206e6f20636f6465a2646970667358221220c5a8c10b22f20cde3fe0431ff57305237423677a60888f5b349fc6751336ae1464736f6c63430008150033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100d45760003560e01c806379c0d58d11610081578063afb877bb1161005b578063afb877bb146101d9578063de675a6d146101ec578063e33ecf0a1461023857600080fd5b806379c0d58d14610192578063836d6bfb146101b35780638824a0bb146101c657600080fd5b806326fc3ef4116100b257806326fc3ef4146101145780632f4d98ea1461015c5780633c0985681461017f57600080fd5b806313c34f4b146100d95780631c776dd5146100ee5780631f931c1c14610101575b600080fd5b6100ec6100e7366004612a97565b61024b565b005b6100ec6100fc366004612ad9565b6104df565b6100ec61010f366004612b9c565b610a76565b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9bf546040516fffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b61016f61016a366004612c4a565b610c7b565b6040519015158152602001610153565b6100ec61018d366004612ca4565b610c8d565b6101a56101a0366004612c4a565b610df2565b604051908152602001610153565b61016f6101c1366004612cdb565b610e4c565b6100ec6101d4366004612dd2565b610eed565b6100ec6101e7366004612a97565b610fe1565b6102137f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610153565b6101a5610246366004612a97565b61130e565b3360009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff1615801561028a5750303314155b156102c1576040517f6238ee3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610369576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064015b60405180910390fd5b60008080527f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be6020527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d3906103be848461130e565b60008181526020848152604080832033845290915290205490915060ff16610412576040517fedc5708300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051808201825260008082526020808301828152858352868252848320338452909152908390209151825491517fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000009092169015157fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff161761010067ffffffffffffffff90921691909102179055517f3c3d8c1f0b0faff6fe0ace6b485d0595a0106dce9e303f956fd941ebdbe9a98e906104d19086908690612f54565b60405180910390a150505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610582576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b8281146105bb576040517fe854148500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6105cd6105c886886130aa565b611435565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b754600003610650576040517fa788861700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061065c878761130e565b905061069a8585808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506115b392505050565b506106d881868680806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250610eed92505050565b60006106e382610c7b565b90506000816106f35760016106f6565b60005b60ff169050806107046116d0565b61070e9190613201565b61071784610df2565b6107219088613201565b1015610759576040517f709fb08000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805b878110156109a0576107d989898381811061077a5761077a613214565b905060200201602081019061078f9190613243565b73ffffffffffffffffffffffffffffffffffffffff1660009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff1690565b1580156108225750308989838181106107f4576107f4613214565b90506020020160208101906108099190613243565b73ffffffffffffffffffffffffffffffffffffffff1614155b15610859576040517f7b2cbbb400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3089898381811061086c5761086c613214565b90506020020160208101906108819190613243565b73ffffffffffffffffffffffffffffffffffffffff16036108d95783156108d4576040517fee21708000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600191505b6109628989838181106108ee576108ee613214565b90506020020160208101906109039190613243565b8689898581811061091657610916613214565b90506020028101906109289190613265565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061174f92505050565b610998576040517fac3d341600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60010161075d565b50801580156109ad575082155b156109e4576040517f6d21730400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9bf80546fffffffffffffffffffffffffffffffff808216600101167fffffffffffffffffffffffffffffffff00000000000000000000000000000000909116179055610a6a610a538a8c6130aa565b6000604051806020016040528060008152506117ca565b50505050505050505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610b19576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b610b2161195f565b610b2e6105c885876130aa565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75415610baf576040517fa788861700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff831615610bfd576040517f871cb76100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be5b600190810180547fffffffffffffffffffffffffffffffff0000000000000000000000000000000081166fffffffffffffffffffffffffffffffff91821690930116919091179055610c74610a5385876130aa565b5050505050565b6000610c878230610e4c565b92915050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610d30576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b610d3861195f565b7fffffffff00000000000000000000000000000000000000000000000000000000821660008181527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4922602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001685151590811790915582519384529083015280517f4e6bd17989efa6d6a9607ccaac1bba27b29f99622bc830d99a3a9883b21a19c79281900390910190a15050565b600080610dfd6119ca565b805190915060005b81811015610e4457610e3085848381518110610e2357610e23613214565b6020026020010151610e4c565b15610e3c578360010193505b600101610e05565b505050919050565b60008281527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d36020818152604080842073ffffffffffffffffffffffffffffffffffffffff8616855290915282205460ff168015610ee5575060008481526020828152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152902054610100900467ffffffffffffffff1642105b949350505050565b6000610ef76119ca565b805183519192509060005b82811015610fd957610f2086858381518110610e2357610e23613214565b15610fd15760005b82811015610fcf57848281518110610f4257610f42613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16868281518110610f7257610f72613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603610fc7576040517f50f5729f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600101610f28565b505b600101610f02565b505050505050565b3360009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff161580156110205750303314155b15611057576040517f6238ee3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff9081164290911610156110fa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75460000361117d576040517f3a76e1f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080527f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be6020527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d36111d36105c883856130aa565b60006111df848461130e565b905060006111eb611af4565b6111f59042613201565b6040805180820182526001815267ffffffffffffffff838116602080840191825260008881528982528581203382529091528490209251835491517fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000009092169015157fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff16176101009190921602179055519091507f6248ff757895beed7d43d135bccf59a26b7fbdf0fe8233487c44e82c0f266ba3906112b89087908790612f54565b60405180910390a16112c86116d0565b6112d183610df2565b101580156112e357506112e382610c7b565b15610c74577f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be610c1f565b60008282604051602001611323929190612f54565b6040516020818303038152906040528051906020012030466113627f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be90565b6001015460408051602081019590955273ffffffffffffffffffffffffffffffffffffffff9093169284019290925260608301526fffffffffffffffffffffffffffffffff16608082015260a001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905280516020918201207f19457468657265756d205369676e6564204d6573736167653a0a33320000000091830191909152603c820152605c0160405160208183030381529060405280519060200120905092915050565b805160005b818110156115ae57600083828151811061145657611456613214565b602002602001015160200151600281111561147357611473612e8a565b14806114ad5750600183828151811061148e5761148e613214565b60200260200101516020015160028111156114ab576114ab612e8a565b145b156115a657600254835173ffffffffffffffffffffffffffffffffffffffff9091169063df871f72908590849081106114e8576114e8613214565b60200260200101516000015185848151811061150657611506613214565b6020026020010151604001516040518363ffffffff1660e01b815260040161152f92919061331c565b602060405180830381865afa15801561154c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611570919061334b565b6115a6576040517ff41a931c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60010161143a565b505050565b80516000908082036115f1576040517f3aee2eec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b6115ff600183613368565b8110156116c6576000611613826001613201565b90505b828110156116bd5784818151811061163057611630613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1685838151811061166057611660613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16036116b5576040517f8dd19e7d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600101611616565b506001016115f4565b5060009392505050565b600080611723600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75490565b905080156117465761173660028261337b565b611741906001613201565b611749565b60005b91505090565b600080600061175e8585611bf6565b9092509050600081600481111561177757611777612e8a565b1480156117af57508573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b806117c057506117c0868686611c3b565b9695505050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921547f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff8116908190600090600716156118395750600381901c60009081526001840160205260409020545b60005b87518110156118b6576118a983838a848151811061185c5761185c613214565b6020026020010151600001518b858151811061187a5761187a613214565b6020026020010151602001518c868151811061189857611898613214565b602002602001015160400151611d98565b909350915060010161183c565b508282146118ef576002840180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff84161790555b600782161561191157600382901c600090815260018501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb67387878760405161194493929190613424565b60405180910390a16119568686612829565b50505050505050565b3330146119c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4c69624469616d6f6e643a2043616c6c6572206e6f742073656c6600000000006044820152606401610360565b565b60008080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b780546060929067ffffffffffffffff811115611a3257611a32612d07565b604051908082528060200260200182016040528015611a5b578160200160208202803683370190505b50825490915060005b81811015611aeb57836000018181548110611a8157611a81613214565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16838281518110611abe57611abe613214565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101611a64565b50909392505050565b6040517f52430c8d0000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906352430c8d90602401602060405180830381865afa158015611b81573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ba59190613510565b6fffffffffffffffffffffffffffffffff16905060008111611bf3576040517fdac5ec8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b90565b6000808251604103611c2c5760208301516040840151606085015160001a611c2087828585612928565b94509450505050611c34565b506000905060025b9250929050565b60008060008573ffffffffffffffffffffffffffffffffffffffff16631626ba7e60e01b8686604051602401611c72929190613542565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909416939093179092529051611cfb919061355b565b600060405180830381855afa9150503d8060008114611d36576040519150601f19603f3d011682016040523d82523d6000602084013e611d3b565b606091505b5091509150818015611d4f57506020815110155b80156117c0575080517f1626ba7e0000000000000000000000000000000000000000000000000000000090611d8d9083016020908101908401613577565b149695505050505050565b600080807f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f90506000845111611e50576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610360565b6000856002811115611e6457611e64612e8a565b0361203457611e8b8660405180606001604052806024815260200161365760249139612a17565b60005b845181101561202e576000858281518110611eab57611eab613214565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c15611f7e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c72656164792065786973747300000000000000000000006064820152608401610360565b7fffffffff0000000000000000000000000000000000000000000000000000000080831660008181526020879052604090207fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608d901b168e17905560e060058e901b811692831c199c909c1690821c179a8190036120125760038c901c600090815260018601602052604081209b909b555b8b61201c81613590565b9c505060019093019250611e8e915050565b5061281d565b600185600281111561204857612048612e8a565b036123385761206f866040518060600160405280602881526020016136a360289139612a17565b60005b845181101561202e57600085828151811061208f5761208f613214565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c308103612164576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4c69624469616d6f6e644375743a2043616e2774207265706c61636520696d6d60448201527f757461626c652066756e6374696f6e00000000000000000000000000000000006064820152608401610360565b8973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361221f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e00000000000000006064820152608401610360565b73ffffffffffffffffffffffffffffffffffffffff81166122c2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e207468617420646f65736e277420657869737400000000000000006064820152608401610360565b507fffffffff0000000000000000000000000000000000000000000000000000000090911660009081526020849052604090206bffffffffffffffffffffffff919091167fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608a901b16179055600101612072565b600285600281111561234c5761234c612e8a565b036127955773ffffffffffffffffffffffffffffffffffffffff8616156123f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d7573742062652061646472657373283029000000000000000000006064820152608401610360565b600388901c6007891660005b86518110156127755760008a900361243d578261241d816135c8565b60008181526001870160205260409020549b5093506007925061244b9050565b81612447816135c8565b9250505b6000806000808a858151811061246357612463613214565b6020908102919091018101517fffffffff0000000000000000000000000000000000000000000000000000000081166000908152918a9052604090912054909150606081901c612535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608401610360565b30606082901c036125c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e0000000000000000000000000000000000006064820152608401610360565b600587901b8f901b94507fffffffff0000000000000000000000000000000000000000000000000000000080861690831614612666577fffffffff000000000000000000000000000000000000000000000000000000008516600090815260208a90526040902080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff83161790555b7fffffffff0000000000000000000000000000000000000000000000000000000091909116600090815260208990526040812055600381901c611fff16925060051b60e01690508582146126fb576000828152600188016020526040902080547fffffffff0000000000000000000000000000000000000000000000000000000080841c19909116908516831c17905561274c565b80837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c817fffffffff0000000000000000000000000000000000000000000000000000000060001b901c198e16179c505b8460000361276a57600086815260018801602052604081208190559c505b505050600101612401565b50806127828360086135fd565b61278c9190613201565b9950505061281d565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560448201527f74416374696f6e000000000000000000000000000000000000000000000000006064820152608401610360565b50959694955050505050565b73ffffffffffffffffffffffffffffffffffffffff8216612848575050565b61286a8260405180606001604052806028815260200161367b60289139612a17565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051612892919061355b565b600060405180830381855af49150503d80600081146128cd576040519150601f19603f3d011682016040523d82523d6000602084013e6128d2565b606091505b509150915081612922578051156128ec5780518082602001fd5b83836040517f192105d7000000000000000000000000000000000000000000000000000000008152600401610360929190613614565b50505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561295f5750600090506003612a0e565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156129b3573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116612a0757600060019250925050612a0e565b9150600090505b94509492505050565b813b8181612922576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103609190613643565b60008083601f840112612a6457600080fd5b50813567ffffffffffffffff811115612a7c57600080fd5b6020830191508360208260051b8501011115611c3457600080fd5b60008060208385031215612aaa57600080fd5b823567ffffffffffffffff811115612ac157600080fd5b612acd85828601612a52565b90969095509350505050565b60008060008060008060608789031215612af257600080fd5b863567ffffffffffffffff80821115612b0a57600080fd5b612b168a838b01612a52565b90985096506020890135915080821115612b2f57600080fd5b612b3b8a838b01612a52565b90965094506040890135915080821115612b5457600080fd5b50612b6189828a01612a52565b979a9699509497509295939492505050565b803573ffffffffffffffffffffffffffffffffffffffff81168114612b9757600080fd5b919050565b600080600080600060608688031215612bb457600080fd5b853567ffffffffffffffff80821115612bcc57600080fd5b612bd889838a01612a52565b9097509550859150612bec60208901612b73565b94506040880135915080821115612c0257600080fd5b818801915088601f830112612c1657600080fd5b813581811115612c2557600080fd5b896020828501011115612c3757600080fd5b9699959850939650602001949392505050565b600060208284031215612c5c57600080fd5b5035919050565b80357fffffffff0000000000000000000000000000000000000000000000000000000081168114612b9757600080fd5b8015158114612ca157600080fd5b50565b60008060408385031215612cb757600080fd5b612cc083612c63565b91506020830135612cd081612c93565b809150509250929050565b60008060408385031215612cee57600080fd5b82359150612cfe60208401612b73565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff81118282101715612d5957612d59612d07565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715612da657612da6612d07565b604052919050565b600067ffffffffffffffff821115612dc857612dc8612d07565b5060051b60200190565b60008060408385031215612de557600080fd5b8235915060208084013567ffffffffffffffff811115612e0457600080fd5b8401601f81018613612e1557600080fd5b8035612e28612e2382612dae565b612d5f565b81815260059190911b82018301908381019088831115612e4757600080fd5b928401925b82841015612e6c57612e5d84612b73565b82529284019290840190612e4c565b80955050505050509250929050565b803560038110612b9757600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60038110612ef0577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b8183526000602080850194508260005b85811015612f49577fffffffff00000000000000000000000000000000000000000000000000000000612f3683612c63565b1687529582019590820190600101612f04565b509495945050505050565b60208082528181018390526000906040808401600586811b8601830188865b8981101561309b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc089840301855281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa18c3603018112612fd457600080fd5b8b01606073ffffffffffffffffffffffffffffffffffffffff612ff683612b73565b168552613004898301612e7b565b6130108a870182612eb9565b50878201357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe183360301811261304557600080fd5b90910188810191903567ffffffffffffffff81111561306357600080fd5b80871b360383131561307457600080fd5b81898701526130868287018285612ef4565b978a0197955050509187019150600101612f73565b50909998505050505050505050565b60006130b8612e2384612dae565b83815260208082019190600586811b8601368111156130d657600080fd5b865b818110156131c557803567ffffffffffffffff808211156130f95760008081fd5b818a0191506060823603121561310f5760008081fd5b613117612d36565b61312083612b73565b815261312d878401612e7b565b87820152604080840135838111156131455760008081fd5b939093019236601f85011261315c57600092508283fd5b8335925061316c612e2384612dae565b83815292871b840188019288810190368511156131895760008081fd5b948901945b848610156131ae5761319f86612c63565b8252948901949089019061318e565b9183019190915250885250509483019483016130d8565b5092979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610c8757610c876131d2565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561325557600080fd5b61325e82612b73565b9392505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261329a57600080fd5b83018035915067ffffffffffffffff8211156132b557600080fd5b602001915036819003821315611c3457600080fd5b600081518084526020808501945080840160005b83811015612f495781517fffffffff0000000000000000000000000000000000000000000000000000000016875295820195908201906001016132de565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000610ee560408301846132ca565b60006020828403121561335d57600080fd5b815161325e81612c93565b81810381811115610c8757610c876131d2565b6000826133b1577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60005b838110156133d15781810151838201526020016133b9565b50506000910152565b600081518084526133f28160208601602086016133b6565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6000606080830181845280875180835260808601915060808160051b87010192506020808a0160005b838110156134d4577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80898703018552815173ffffffffffffffffffffffffffffffffffffffff8151168752838101516134a885890182612eb9565b506040908101519087018890526134c1878901826132ca565b965050938201939082019060010161344d565b505073ffffffffffffffffffffffffffffffffffffffff8916908701525050838103604085015261350581866133da565b979650505050505050565b60006020828403121561352257600080fd5b81516fffffffffffffffffffffffffffffffff8116811461325e57600080fd5b828152604060208201526000610ee560408301846133da565b6000825161356d8184602087016133b6565b9190910192915050565b60006020828403121561358957600080fd5b5051919050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036135c1576135c16131d2565b5060010190565b6000816135d7576135d76131d2565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b8082028115828204841417610c8757610c876131d2565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000610ee560408301846133da565b60208152600061325e60208301846133da56fe4c69624469616d6f6e644375743a2041646420666163657420686173206e6f20636f64654c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a205265706c61636520666163657420686173206e6f20636f6465a2646970667358221220c5a8c10b22f20cde3fe0431ff57305237423677a60888f5b349fc6751336ae1464736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "Responsible for adding/removing/replace facets in Barz", + "kind": "dev", + "methods": { + "_checkDuplicateOnChainApprover(bytes32,address[])": { + "params": { + "_approvers": "List of approver addresses", + "_diamondCutHash": "Hash of diamondCut information including the facet addresses and function selectors" + } + }, + "approveDiamondCut((address,uint8,bytes4[])[])": { + "params": { + "_diamondCut": "Contains the facet addresses and function selectors" + } + }, + "constructor": { + "params": { + "_securityManager": "Security Manager contract that holds the security related variables for all wallets" + } + }, + "diamondCut((address,uint8,bytes4[])[],address,bytes)": { + "params": { + "_diamondCut": "Contains the facet addresses and function selectors", + "_init": "The address of the contract or facet to execute _calldata. It's prohibited in Barz" + } + }, + "diamondCutWithGuardian((address,uint8,bytes4[])[],address[],bytes[])": { + "params": { + "_approvers": "Guardian or owner address that approves the diamond cut", + "_diamondCut": "Contains the facet addresses and function selectors", + "_signatures": "Signature of Guardians or owner that approves the diamond cut" + } + }, + "getDiamondCutApprovalCountWithTimeValidity(bytes32)": { + "params": { + "_diamondCutHash": "Hash of diamondCut information including the facet addresses and function selectors" + } + }, + "getDiamondCutHash((address,uint8,bytes4[])[])": { + "params": { + "_diamondCut": "Contains the facet addresses and function selectors" + }, + "returns": { + "cutHash": "Diamond Cut Hash" + } + }, + "getDiamondCutNonce()": { + "details": "This method fetches the nonce from diamond cut storage", + "returns": { + "cutNonce": "Nonce of diamond cut to protect from reply attacks" + } + }, + "getOwnerCutApprovalWithTimeValidity(bytes32)": { + "params": { + "_diamondCutHash": "Hash of diamondCut information including the facet addresses and function selectors" + }, + "returns": { + "isApprovedByOwner": "Bool value showing if the owner approved the cut" + } + }, + "isCutApproved(bytes32,address)": { + "params": { + "_approver": "Address of approver", + "_diamondCutHash": "Hash of diamondCut information including the facet addresses and function selectors" + }, + "returns": { + "isApproved": "Bool value showing if the approver approved the cut" + } + }, + "revokeDiamondCutApproval((address,uint8,bytes4[])[])": { + "params": { + "_diamondCut": "Contains the facet addresses and function selectors" + } + }, + "updateSupportsInterface(bytes4,bool)": { + "params": { + "_flag": "Bool value to update the mapping of the given interface ID", + "_interfaceId": "InterfaceID to update the mapping" + } + } + }, + "title": "DiamondCut Facet", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "_checkDuplicateOnChainApprover(bytes32,address[])": { + "notice": "Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval Approvers who approved on-chain should not be included in the off-chain approval" + }, + "approveDiamondCut((address,uint8,bytes4[])[])": { + "notice": "Approves diamond cut. This can only be called directly from guardian or owner" + }, + "constructor": { + "notice": "This constructor sets the Security Manager address which is an immutable variable. Immutable variables do not impact the storage of diamond" + }, + "diamondCut((address,uint8,bytes4[])[],address,bytes)": { + "notice": "Add/replace/remove any number of functions and optionally execute a function with delegatecall when guardians don't exist" + }, + "diamondCutWithGuardian((address,uint8,bytes4[])[],address[],bytes[])": { + "notice": "Add/replace/remove any number of functions and optionally execute a function with delegatecall when guardians exist" + }, + "getDiamondCutApprovalCountWithTimeValidity(bytes32)": { + "notice": "Gets the number of approvals of diamond cut from guardians" + }, + "getDiamondCutHash((address,uint8,bytes4[])[])": { + "notice": "Returns the diamond cut hash. This function ensures that this hash is safe from replay attack by including salt, address, chainId, and nonce, etc." + }, + "getDiamondCutNonce()": { + "notice": "Returns the diamond cut nonce of this wallet" + }, + "getOwnerCutApprovalWithTimeValidity(bytes32)": { + "notice": "Returns if the owner has approved the diamond cut" + }, + "isCutApproved(bytes32,address)": { + "notice": "Returns if the given approver has approved the diamond cut" + }, + "revokeDiamondCutApproval((address,uint8,bytes4[])[])": { + "notice": "Revokes the approval of diamond cut. This can only be called directly from guardian or owner" + }, + "updateSupportsInterface(bytes4,bool)": { + "notice": "Updates the flag for the interfaceId" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 27866, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "s", + "offset": 0, + "slot": "0", + "type": "t_struct(AppStorage)27613_storage" + } + ], + "types": { + "t_bytes4": { + "encoding": "inplace", + "label": "bytes4", + "numberOfBytes": "4" + }, + "t_contract(IEntryPoint)12286": { + "encoding": "inplace", + "label": "contract IEntryPoint", + "numberOfBytes": "20" + }, + "t_contract(IFacetRegistry)26148": { + "encoding": "inplace", + "label": "contract IFacetRegistry", + "numberOfBytes": "20" + }, + "t_mapping(t_uint256,t_struct(InitializersStorage)27592_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => struct InitializersStorage)", + "numberOfBytes": "32", + "value": "t_struct(InitializersStorage)27592_storage" + }, + "t_mapping(t_uint256,t_struct(Lock)27585_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => struct Lock)", + "numberOfBytes": "32", + "value": "t_struct(Lock)27585_storage" + }, + "t_struct(AppStorage)27613_storage": { + "encoding": "inplace", + "label": "struct AppStorage", + "members": [ + { + "astId": 27597, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "initStorage", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_uint256,t_struct(InitializersStorage)27592_storage)" + }, + { + "astId": 27599, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "signerMigration", + "offset": 0, + "slot": "1", + "type": "t_uint8" + }, + { + "astId": 27601, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "validateOwnerSignatureSelector", + "offset": 1, + "slot": "1", + "type": "t_bytes4" + }, + { + "astId": 27604, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "entryPoint", + "offset": 5, + "slot": "1", + "type": "t_contract(IEntryPoint)12286" + }, + { + "astId": 27607, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "facetRegistry", + "offset": 0, + "slot": "2", + "type": "t_contract(IFacetRegistry)26148" + }, + { + "astId": 27612, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "locks", + "offset": 0, + "slot": "3", + "type": "t_mapping(t_uint256,t_struct(Lock)27585_storage)" + } + ], + "numberOfBytes": "128" + }, + "t_struct(InitializersStorage)27592_storage": { + "encoding": "inplace", + "label": "struct InitializersStorage", + "members": [ + { + "astId": 27587, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "signerInitialized", + "offset": 0, + "slot": "0", + "type": "t_uint8" + }, + { + "astId": 27589, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "accountInitialized", + "offset": 1, + "slot": "0", + "type": "t_uint8" + }, + { + "astId": 27591, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "restrictionsInitialized", + "offset": 2, + "slot": "0", + "type": "t_uint8" + } + ], + "numberOfBytes": "32" + }, + "t_struct(Lock)27585_storage": { + "encoding": "inplace", + "label": "struct Lock", + "members": [ + { + "astId": 27582, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "release", + "offset": 0, + "slot": "0", + "type": "t_uint64" + }, + { + "astId": 27584, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "locker", + "offset": 8, + "slot": "0", + "type": "t_bytes4" + } + ], + "numberOfBytes": "32" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint64": { + "encoding": "inplace", + "label": "uint64", + "numberOfBytes": "8" + }, + "t_uint8": { + "encoding": "inplace", + "label": "uint8", + "numberOfBytes": "1" + } + } + } +} \ No newline at end of file diff --git a/deployments/lightLink/DiamondLoupeFacet.json b/deployments/lightLink/DiamondLoupeFacet.json new file mode 100644 index 0000000..9816043 --- /dev/null +++ b/deployments/lightLink/DiamondLoupeFacet.json @@ -0,0 +1,306 @@ +{ + "address": "0xCe36b85d12D81cd619C745c7717f3396E184Ac7C", + "abi": [ + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_functionSelector", + "type": "bytes4" + } + ], + "name": "facetAddress", + "outputs": [ + { + "internalType": "address", + "name": "facetAddress_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_functionSelector", + "type": "bytes4" + } + ], + "name": "facetAddressFromStorage", + "outputs": [ + { + "internalType": "address", + "name": "facetAddress_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetAddresses", + "outputs": [ + { + "internalType": "address[]", + "name": "facetAddresses_", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetAddressesFromStorage", + "outputs": [ + { + "internalType": "address[]", + "name": "facetAddresses_", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_facet", + "type": "address" + } + ], + "name": "facetFunctionSelectors", + "outputs": [ + { + "internalType": "bytes4[]", + "name": "facetFunctionSelectors_", + "type": "bytes4[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_facet", + "type": "address" + } + ], + "name": "facetFunctionSelectorsFromStorage", + "outputs": [ + { + "internalType": "bytes4[]", + "name": "facetFunctionSelectors_", + "type": "bytes4[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facets", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondLoupe.Facet[]", + "name": "facets_", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetsFromStorage", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondLoupe.Facet[]", + "name": "facets_", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "isSupported", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0xa6450d36b8b06587f007245c24c979e6908c06985d4185bcd0af186ab6c0fe57", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": "0x0000000000000000000000000000000000000000", + "transactionIndex": 0, + "gasUsed": "2036953", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x5598006257a0dbd56a150ae7a8930885e45c679c09c892119376408d0d55d2a4", + "transactionHash": "0xa6450d36b8b06587f007245c24c979e6908c06985d4185bcd0af186ab6c0fe57", + "logs": [], + "blockNumber": 72701517, + "cumulativeGasUsed": "2036953", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "ad34345aa73d96f52b3e14df983b6b29", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_functionSelector\",\"type\":\"bytes4\"}],\"name\":\"facetAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"facetAddress_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_functionSelector\",\"type\":\"bytes4\"}],\"name\":\"facetAddressFromStorage\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"facetAddress_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetAddresses\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"facetAddresses_\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetAddressesFromStorage\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"facetAddresses_\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_facet\",\"type\":\"address\"}],\"name\":\"facetFunctionSelectors\",\"outputs\":[{\"internalType\":\"bytes4[]\",\"name\":\"facetFunctionSelectors_\",\"type\":\"bytes4[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_facet\",\"type\":\"address\"}],\"name\":\"facetFunctionSelectorsFromStorage\",\"outputs\":[{\"internalType\":\"bytes4[]\",\"name\":\"facetFunctionSelectors_\",\"type\":\"bytes4[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facets\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondLoupe.Facet[]\",\"name\":\"facets_\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetsFromStorage\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondLoupe.Facet[]\",\"name\":\"facets_\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isSupported\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"DiamondLoupe contract compatible with EIP-2535\",\"kind\":\"dev\",\"methods\":{\"facetAddress(bytes4)\":{\"details\":\"If facet is not found return address(0).\",\"params\":{\"_functionSelector\":\"The function selector.\"},\"returns\":{\"facetAddress_\":\"The facet address.\"}},\"facetAddressFromStorage(bytes4)\":{\"params\":{\"_functionSelector\":\"Function selector to fetch the facet address from diamond storage\"},\"returns\":{\"facetAddress_\":\"Facet address mapped with the function selector\"}},\"facetAddresses()\":{\"returns\":{\"facetAddresses_\":\"facetAddresses_\"}},\"facetAddressesFromStorage()\":{\"returns\":{\"facetAddresses_\":\"All facet addresses attached directly to diamond storage\"}},\"facetFunctionSelectors(address)\":{\"params\":{\"_facet\":\"The facet address.\"},\"returns\":{\"facetFunctionSelectors_\":\"facetFunctionSelectors_\"}},\"facetFunctionSelectorsFromStorage(address)\":{\"params\":{\"_facet\":\"Facet address to fetch the facet function selectors from diamond storage\"},\"returns\":{\"facetFunctionSelectors_\":\"Facet function selectors of the given facet address\"}},\"facets()\":{\"details\":\"Barz uses a special architecture called default fallback handler. Default Fallback handler is used as a middleware that holds the mapping of facet function selector and facet address that Barz uses. This helps Barz to reduce significant amount of gas during the initialization process. Hence, this method aggregates both the facet information from DefaulFallbackHandler and in diamond storage and shows the data to users.\",\"returns\":{\"facets_\":\"Facet\"}},\"facetsFromStorage()\":{\"returns\":{\"facets_\":\"Facet information attached directly to diamond storage\"}},\"supportsInterface(bytes4)\":{\"params\":{\"_interfaceId\":\"Interface ID for detecting the interface\"},\"returns\":{\"isSupported\":\"Bool value showing if the standard is supported in the contract\"}}},\"title\":\"DiamondLoupe Facet\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"facetAddress(bytes4)\":{\"notice\":\"Gets the facet that supports the given selector.\"},\"facetAddressFromStorage(bytes4)\":{\"notice\":\"Returns the facet address attached to the given function selector. This excludes the facets from the default fallback handler\"},\"facetAddresses()\":{\"notice\":\"Get all the facet addresses used by Barz.\"},\"facetAddressesFromStorage()\":{\"notice\":\"Returns all facet addresses attached directly to diamond storage. This excludes the facets from the default fallback handler\"},\"facetFunctionSelectors(address)\":{\"notice\":\"Gets all the function selectors provided by a facet.\"},\"facetFunctionSelectorsFromStorage(address)\":{\"notice\":\"Returns function selectors of given facet address attached directly to diamond storage. This excludes the facets from the default fallback handler\"},\"facets()\":{\"notice\":\"Gets all facets and their selectors.\"},\"facetsFromStorage()\":{\"notice\":\"Returns the facet from the diamond storage. This excludes the facets from the default fallback handler\"},\"supportsInterface(bytes4)\":{\"notice\":\"SupportInterface to be compatible with EIP 165\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/base/DiamondLoupeFacet.sol\":\"DiamondLoupeFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/introspection/IERC165.sol\\\";\\n\\n/**\\n * @dev _Available since v3.1._\\n */\\ninterface IERC1155Receiver is IERC165 {\\n /**\\n * @dev Handles the receipt of a single ERC1155 token type. This function is\\n * called at the end of a `safeTransferFrom` after the balance has been updated.\\n *\\n * NOTE: To accept the transfer, this must return\\n * `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))`\\n * (i.e. 0xf23a6e61, or its own function selector).\\n *\\n * @param operator The address which initiated the transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param id The ID of the token being transferred\\n * @param value The amount of tokens being transferred\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155Received(\\n address operator,\\n address from,\\n uint256 id,\\n uint256 value,\\n bytes calldata data\\n ) external returns (bytes4);\\n\\n /**\\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\\n * is called at the end of a `safeBatchTransferFrom` after the balances have\\n * been updated.\\n *\\n * NOTE: To accept the transfer(s), this must return\\n * `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))`\\n * (i.e. 0xbc197c81, or its own function selector).\\n *\\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155BatchReceived(\\n address operator,\\n address from,\\n uint256[] calldata ids,\\n uint256[] calldata values,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xeb373f1fdc7b755c6a750123a9b9e3a8a02c1470042fd6505d875000a80bde0b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title ERC721 token receiver interface\\n * @dev Interface for any contract that wants to support safeTransfers\\n * from ERC721 asset contracts.\\n */\\ninterface IERC721Receiver {\\n /**\\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\\n * by `operator` from `from`, this function is called.\\n *\\n * It must return its Solidity selector to confirm the token transfer.\\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\\n *\\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\\n */\\n function onERC721Received(\\n address operator,\\n address from,\\n uint256 tokenId,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\\n *\\n * Accounts can be notified of {IERC777} tokens being sent to them by having a\\n * contract implement this interface (contract holders can be their own\\n * implementer) and registering it on the\\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\\n *\\n * See {IERC1820Registry} and {ERC1820Implementer}.\\n */\\ninterface IERC777Recipient {\\n /**\\n * @dev Called by an {IERC777} token contract whenever tokens are being\\n * moved or created into a registered account (`to`). The type of operation\\n * is conveyed by `from` being the zero address or not.\\n *\\n * This call occurs _after_ the token contract's state is updated, so\\n * {IERC777-balanceOf}, etc., can be used to query the post-operation state.\\n *\\n * This function may revert to prevent the operation from being executed.\\n */\\n function tokensReceived(\\n address operator,\\n address from,\\n address to,\\n uint256 amount,\\n bytes calldata userData,\\n bytes calldata operatorData\\n ) external;\\n}\\n\",\"keccak256\":\"0x1a5d61db2733202ba361e6d6741cd2e662380e22b80e987eacfc91973f2267dc\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"contracts/facets/base/DiamondLoupeFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IERC777Recipient} from \\\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\\\";\\nimport {IERC165} from \\\"../../interfaces/ERC/IERC165.sol\\\";\\nimport {IERC1271} from \\\"../../interfaces/ERC/IERC1271.sol\\\";\\nimport {IERC677Receiver} from \\\"../../interfaces/ERC/IERC677Receiver.sol\\\";\\nimport {IERC721Receiver} from \\\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\\\";\\nimport {IERC1155Receiver} from \\\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\\\";\\nimport {LibDiamond} from \\\"../../libraries/LibDiamond.sol\\\";\\nimport {LibLoupe} from \\\"../../libraries/LibLoupe.sol\\\";\\nimport {LibUtils} from \\\"../../libraries/LibUtils.sol\\\";\\nimport {IDiamondCut} from \\\"../../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IStorageLoupe} from \\\"./interfaces/IStorageLoupe.sol\\\";\\nimport {IDiamondLoupe} from \\\"./interfaces/IDiamondLoupe.sol\\\";\\n\\n/**\\n * @title DiamondLoupe Facet\\n * @dev DiamondLoupe contract compatible with EIP-2535\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract DiamondLoupeFacet is IDiamondLoupe, IStorageLoupe, IERC165 {\\n // Diamond Loupe Functions\\n ////////////////////////////////////////////////////////////////////\\n /// These functions are expected to be called frequently by tools off-chain.\\n\\n /**\\n * @notice Gets all facets and their selectors.\\n * @dev Barz uses a special architecture called default fallback handler. Default Fallback handler is used as a middleware\\n * that holds the mapping of facet function selector and facet address that Barz uses. This helps Barz to reduce\\n * significant amount of gas during the initialization process.\\n * Hence, this method aggregates both the facet information from DefaulFallbackHandler and in diamond storage and shows the data to users.\\n * @return facets_ Facet\\n */\\n function facets() public view override returns (Facet[] memory facets_) {\\n Facet[] memory defaultFacet = LibDiamond\\n .diamondStorage()\\n .defaultFallbackHandler\\n .facets();\\n Facet[] memory _facets = LibLoupe.facets();\\n uint256 numFacets = _facets.length;\\n bytes4[] memory keys;\\n address[] memory values;\\n for (uint256 i; i < numFacets; ) {\\n uint256 selectorsLength = _facets[i].functionSelectors.length;\\n for (uint256 j; j < selectorsLength; ) {\\n (keys, values) = LibUtils.setValue(\\n keys,\\n values,\\n _facets[i].functionSelectors[j],\\n _facets[i].facetAddress\\n );\\n unchecked {\\n ++j;\\n }\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n {\\n bool iIncrement;\\n for (uint256 i; i < defaultFacet.length; ) {\\n bool jIncrement;\\n for (\\n uint256 j;\\n j < defaultFacet[i].functionSelectors.length;\\n\\n ) {\\n if (\\n LibUtils.getValue(\\n keys,\\n values,\\n defaultFacet[i].functionSelectors[j]\\n ) != address(0)\\n ) {\\n if (defaultFacet[i].functionSelectors.length == 1) {\\n defaultFacet = LibUtils.removeFacetElement(\\n defaultFacet,\\n i\\n );\\n iIncrement = true;\\n break;\\n }\\n defaultFacet[i].functionSelectors = LibUtils\\n .removeElement(\\n defaultFacet[i].functionSelectors,\\n j\\n );\\n jIncrement = true;\\n }\\n if (!jIncrement) {\\n unchecked {\\n ++j;\\n }\\n } else {\\n jIncrement = false;\\n }\\n }\\n if (!iIncrement) {\\n unchecked {\\n ++i;\\n }\\n } else {\\n iIncrement = false;\\n }\\n }\\n }\\n {\\n uint256 facetLength = numFacets + defaultFacet.length;\\n facets_ = new Facet[](facetLength);\\n uint256 defaultFacetIndex;\\n for (uint256 i; i < facetLength; ) {\\n if (i < numFacets) {\\n facets_[i] = _facets[i];\\n bool jIncrementor;\\n for (uint256 j; j < defaultFacet.length; ) {\\n if (\\n facets_[i].facetAddress ==\\n defaultFacet[j].facetAddress\\n ) {\\n facets_[i].functionSelectors = LibUtils.mergeArrays(\\n _facets[i].functionSelectors,\\n defaultFacet[j].functionSelectors\\n );\\n defaultFacet = LibUtils.removeFacetElement(\\n defaultFacet,\\n j\\n );\\n jIncrementor = true;\\n {\\n facets_ = LibUtils.removeFacetElement(\\n facets_,\\n facets_.length - 1\\n );\\n }\\n --facetLength;\\n }\\n if (!jIncrementor) {\\n unchecked {\\n ++j;\\n }\\n } else {\\n jIncrementor = false;\\n }\\n }\\n } else {\\n facets_[i] = defaultFacet[defaultFacetIndex];\\n ++defaultFacetIndex;\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n }\\n\\n /**\\n * @notice Gets all the function selectors provided by a facet.\\n * @param _facet The facet address.\\n * @return facetFunctionSelectors_\\n */\\n function facetFunctionSelectors(\\n address _facet\\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\\n Facet[] memory facet = facets();\\n uint256 facetLength = facet.length;\\n for (uint256 i; i < facetLength; ) {\\n if (facet[i].facetAddress == _facet)\\n return facet[i].functionSelectors;\\n unchecked {\\n ++i;\\n }\\n }\\n return facetFunctionSelectors_;\\n }\\n\\n /**\\n * @notice Get all the facet addresses used by Barz.\\n * @return facetAddresses_\\n */\\n function facetAddresses()\\n external\\n view\\n override\\n returns (address[] memory facetAddresses_)\\n {\\n Facet[] memory facet = facets();\\n uint256 facetLength = facet.length;\\n facetAddresses_ = new address[](facetLength);\\n for (uint256 i; i < facetLength; ) {\\n facetAddresses_[i] = facet[i].facetAddress;\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * @notice Gets the facet that supports the given selector.\\n * @dev If facet is not found return address(0).\\n * @param _functionSelector The function selector.\\n * @return facetAddress_ The facet address.\\n */\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view override returns (address facetAddress_) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n\\n facetAddress_ = address(bytes20(ds.facets[_functionSelector]));\\n if (facetAddress_ == address(0)) {\\n facetAddress_ = IDiamondLoupe(ds.defaultFallbackHandler)\\n .facetAddress(_functionSelector);\\n }\\n }\\n\\n /**\\n * @notice SupportInterface to be compatible with EIP 165\\n * @param _interfaceId Interface ID for detecting the interface\\n * @return isSupported Bool value showing if the standard is supported in the contract\\n */\\n function supportsInterface(\\n bytes4 _interfaceId\\n ) external view override returns (bool isSupported) {\\n isSupported =\\n _interfaceId == type(IERC165).interfaceId ||\\n _interfaceId == IDiamondCut.diamondCut.selector ||\\n _interfaceId == type(IDiamondLoupe).interfaceId ||\\n _interfaceId == type(IERC1155Receiver).interfaceId ||\\n _interfaceId == type(IERC721Receiver).interfaceId ||\\n _interfaceId == type(IERC777Recipient).interfaceId ||\\n _interfaceId == IERC1271.isValidSignature.selector ||\\n _interfaceId == type(IERC677Receiver).interfaceId ||\\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId];\\n }\\n\\n /**\\n * @notice Returns the facet from the diamond storage. This excludes the facets from the default fallback handler\\n * @return facets_ Facet information attached directly to diamond storage\\n */\\n function facetsFromStorage()\\n external\\n view\\n override\\n returns (Facet[] memory facets_)\\n {\\n facets_ = LibLoupe.facets();\\n }\\n\\n /**\\n * @notice Returns the facet address attached to the given function selector. This excludes the facets from the default fallback handler\\n * @param _functionSelector Function selector to fetch the facet address from diamond storage\\n * @return facetAddress_ Facet address mapped with the function selector\\n */\\n function facetAddressFromStorage(\\n bytes4 _functionSelector\\n ) external view override returns (address facetAddress_) {\\n facetAddress_ = LibLoupe.facetAddress(_functionSelector);\\n }\\n\\n /**\\n * @notice Returns all facet addresses attached directly to diamond storage. This excludes the facets from the default fallback handler\\n * @return facetAddresses_ All facet addresses attached directly to diamond storage\\n */\\n function facetAddressesFromStorage()\\n external\\n view\\n override\\n returns (address[] memory facetAddresses_)\\n {\\n facetAddresses_ = LibLoupe.facetAddresses();\\n }\\n\\n /**\\n * @notice Returns function selectors of given facet address attached directly to diamond storage. This excludes the facets from the default fallback handler\\n * @param _facet Facet address to fetch the facet function selectors from diamond storage\\n * @return facetFunctionSelectors_ Facet function selectors of the given facet address\\n */\\n function facetFunctionSelectorsFromStorage(\\n address _facet\\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\\n facetFunctionSelectors_ = LibLoupe.facetFunctionSelectors(_facet);\\n }\\n}\\n\",\"keccak256\":\"0xf392fde159eec6483fc15fa323ecd6d764028f5b8734a66662c4116292363794\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IStorageLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"./IDiamondLoupe.sol\\\";\\n\\n/**\\n * @title LoupeFromStorage Interface\\n * @dev Interface contract to function as a loupe facet directly attached to diamond storage of Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IStorageLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facetsFromStorage()\\n external\\n view\\n returns (IDiamondLoupe.Facet[] memory);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n function facetFunctionSelectorsFromStorage(\\n address _facet\\n ) external view returns (bytes4[] memory);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n function facetAddressesFromStorage()\\n external\\n view\\n returns (address[] memory);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n function facetAddressFromStorage(\\n bytes4 _functionSelector\\n ) external view returns (address);\\n}\\n\",\"keccak256\":\"0xdf5dc9c57319e9087628c9cf9404b4f75585b76d1c2f4f59ee796c933967ea5c\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC1271 {\\n function isValidSignature(\\n bytes32 hash,\\n bytes memory signature\\n ) external view returns (bytes4);\\n}\\n\",\"keccak256\":\"0xcdddb7d5641c9d3f2432dec7fd13fddb9ae1480f25c76c21511e2fa16b8bd422\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.21;\\n\\ninterface IERC165 {\\n /// @notice Query if a contract implements an interface\\n /// @param interfaceId The interface identifier, as specified in ERC-165\\n /// @dev Interface identification is specified in ERC-165. This function\\n /// uses less than 30,000 gas.\\n /// @return `true` if the contract implements `interfaceID` and\\n /// `interfaceID` is not 0xffffffff, `false` otherwise\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xbb7f07e170898793c5535cc4b7e8944c4b990a631ac806d0b788e794abc788a3\",\"license\":\"MIT\"},\"contracts/interfaces/ERC/IERC677Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC677Receiver {\\n function onTokenTransfer(\\n address sender,\\n uint value,\\n bytes calldata data\\n ) external pure returns (bool);\\n}\\n\",\"keccak256\":\"0x4c1631cf45ea6daac0ec158c3edb9453099130b6b64f697004b83f95aa1f7350\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\\n bytes4(keccak256(\\\"verifyRestrictions(address,address,uint256,bytes)\\\"));\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // Default Fallback Handler of the barz.\\n IDiamondLoupe defaultFallbackHandler;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function enforceIsSelf() internal view {\\n require(msg.sender == address(this), \\\"LibDiamond: Caller not self\\\");\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n\\n unchecked {\\n facetIndex++;\\n }\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n\\n function restrictionsFacet() internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(\\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2cabdc00de859c3a3170ce3bda5d0e5fd3933d47ce904fd1585f9818b02572f8\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\nimport {LibDiamond} from \\\"./LibDiamond.sol\\\";\\n\\n/**\\n * @title LibLoupe\\n * @dev Internal Library to provide utility feature for reading the state of diamond facets\\n * Originally from Diamond's implementation of Mudgen(author of EIP-2535)\\n */\\nlibrary LibLoupe {\\n /// @notice Gets all facets and their selectors.\\n /// @return facets_ Facet\\n function facets()\\n internal\\n view\\n returns (IDiamondLoupe.Facet[] memory facets_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facets_ = new IDiamondLoupe.Facet[](ds.selectorCount);\\n uint16[] memory numFacetSelectors = new uint16[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facets_[facetIndex].facetAddress == facetAddress_) {\\n facets_[facetIndex].functionSelectors[\\n numFacetSelectors[facetIndex]\\n ] = selector;\\n // probably will never have more than 256 functions from one facet contract\\n require(numFacetSelectors[facetIndex] < 255);\\n numFacetSelectors[facetIndex]++;\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facets_[numFacets].facetAddress = facetAddress_;\\n facets_[numFacets].functionSelectors = new bytes4[](\\n ds.selectorCount\\n );\\n facets_[numFacets].functionSelectors[0] = selector;\\n numFacetSelectors[numFacets] = 1;\\n numFacets++;\\n }\\n }\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n uint256 numSelectors = numFacetSelectors[facetIndex];\\n bytes4[] memory selectors = facets_[facetIndex].functionSelectors;\\n // setting the number of selectors\\n assembly {\\n mstore(selectors, numSelectors)\\n }\\n }\\n // setting the number of facets\\n assembly {\\n mstore(facets_, numFacets)\\n }\\n }\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return _facetFunctionSelectors The selectors associated with a facet address.\\n function facetFunctionSelectors(\\n address _facet\\n ) internal view returns (bytes4[] memory _facetFunctionSelectors) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n uint256 numSelectors;\\n _facetFunctionSelectors = new bytes4[](ds.selectorCount);\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facet = address(bytes20(ds.facets[selector]));\\n if (_facet == facet) {\\n _facetFunctionSelectors[numSelectors] = selector;\\n numSelectors++;\\n }\\n }\\n }\\n // Set the number of selectors in the array\\n assembly {\\n mstore(_facetFunctionSelectors, numSelectors)\\n }\\n }\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n internal\\n view\\n returns (address[] memory facetAddresses_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetAddresses_ = new address[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facetAddress_ == facetAddresses_[facetIndex]) {\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facetAddresses_[numFacets] = facetAddress_;\\n numFacets++;\\n }\\n }\\n // Set the number of facet addresses in the array\\n assembly {\\n mstore(facetAddresses_, numFacets)\\n }\\n }\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(LibDiamond.diamondStorage().facets[_functionSelector])\\n );\\n }\\n}\\n\",\"keccak256\":\"0x0b11439c3cc657095e15ec2241fdcf67204b14001357b612fc5db4ff9e760a5a\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibUtils.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nlibrary LibUtils {\\n // Internal utility functions\\n function mergeArrays(\\n bytes4[] memory _array1,\\n bytes4[] memory _array2\\n ) internal pure returns (bytes4[] memory) {\\n uint256 length1 = _array1.length;\\n uint256 length2 = _array2.length;\\n bytes4[] memory mergedArray = new bytes4[](length1 + length2);\\n\\n for (uint256 i; i < length1; ) {\\n mergedArray[i] = _array1[i];\\n unchecked {\\n ++i;\\n }\\n }\\n\\n for (uint256 i; i < length2; ) {\\n mergedArray[length1 + i] = _array2[i];\\n unchecked {\\n ++i;\\n }\\n }\\n\\n return mergedArray;\\n }\\n\\n function removeFacetElement(\\n IDiamondLoupe.Facet[] memory _facets,\\n uint256 _index\\n ) internal pure returns (IDiamondLoupe.Facet[] memory) {\\n require(_index < _facets.length, \\\"Invalid index\\\");\\n require(_facets.length != 0, \\\"Invalid array\\\");\\n\\n // Create a new array with a length of `_facets.length - 1`\\n IDiamondLoupe.Facet[] memory newArray = new IDiamondLoupe.Facet[](\\n _facets.length - 1\\n );\\n uint256 newArrayLength = newArray.length;\\n // Iterate over the original array, skipping the element at the specified `index`\\n for (uint256 i; i < newArrayLength; ) {\\n if (i < _index) {\\n newArray[i] = _facets[i];\\n } else {\\n newArray[i] = _facets[i + 1];\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n\\n return newArray;\\n }\\n\\n function removeElement(\\n bytes4[] memory _array,\\n uint256 _index\\n ) internal pure returns (bytes4[] memory) {\\n require(_index < _array.length, \\\"Invalid index\\\");\\n require(_array.length != 0, \\\"Invalid array\\\");\\n\\n bytes4[] memory newArray = new bytes4[](_array.length - 1);\\n uint256 newArrayLength = newArray.length;\\n for (uint256 i; i < newArrayLength; ) {\\n if (i < _index) {\\n newArray[i] = _array[i];\\n } else {\\n newArray[i] = _array[i + 1];\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n\\n return newArray;\\n }\\n\\n function setValue(\\n bytes4[] memory _keys,\\n address[] memory _values,\\n bytes4 _key,\\n address _value\\n ) internal pure returns (bytes4[] memory, address[] memory) {\\n uint256 index = findIndex(_keys, _key);\\n uint256 keysLength = _keys.length;\\n if (index < keysLength) {\\n _values[index] = _value;\\n } else {\\n // Create new storage arrays\\n bytes4[] memory newKeys = new bytes4[](keysLength + 1);\\n address[] memory newValues = new address[](_values.length + 1);\\n\\n // Copy values to the new storage arrays\\n for (uint256 i; i < keysLength; ) {\\n newKeys[i] = _keys[i];\\n newValues[i] = _values[i];\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n // Add the new key-value pair\\n newKeys[keysLength] = _key;\\n newValues[_values.length] = _value;\\n\\n return (newKeys, newValues);\\n }\\n\\n // If the key already exists, return the original arrays\\n return (_keys, _values);\\n }\\n\\n function getValue(\\n bytes4[] memory _keys,\\n address[] memory _values,\\n bytes4 _key\\n ) internal pure returns (address) {\\n uint256 index = findIndex(_keys, _key);\\n if (index >= _keys.length) return address(0);\\n\\n return _values[index];\\n }\\n\\n function findIndex(\\n bytes4[] memory _keys,\\n bytes4 _key\\n ) internal pure returns (uint256) {\\n uint256 keysLength = _keys.length;\\n for (uint256 i; i < keysLength; ) {\\n if (_keys[i] == _key) {\\n return i;\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n return keysLength;\\n }\\n}\\n\",\"keccak256\":\"0xde8aeefe54c4be483f2b2c055aca11e2830f7094c0586a82e10ec544933b5714\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5061240b806100206000396000f3fe608060405234801561001057600080fd5b50600436106100a35760003560e01c8063adfca15e11610076578063d42139a91161005b578063d42139a914610169578063e3a2f6fe14610171578063f9796ccf1461018457600080fd5b8063adfca15e1461011e578063cdffacc61461013157600080fd5b806301a55022146100a857806301ffc9a7146100d157806352ef6b2c146100f45780637a0ed62714610109575b600080fd5b6100bb6100b6366004611e4b565b61018c565b6040516100c89190611e68565b60405180910390f35b6100e46100df366004611efc565b61019d565b60405190151581526020016100c8565b6100fc610454565b6040516100c89190611f19565b610111610518565b6040516100c89190611f67565b6100bb61012c366004611e4b565b610a63565b61014461013f366004611efc565b610b07565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100c8565b6100fc610c24565b61014461017f366004611efc565b610c33565b610111610c8c565b606061019782610c96565b92915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000148061023057507fffffffff0000000000000000000000000000000000000000000000000000000082167f1f931c1c00000000000000000000000000000000000000000000000000000000145b8061027c57507fffffffff0000000000000000000000000000000000000000000000000000000082167f48e2b09300000000000000000000000000000000000000000000000000000000145b806102c857507fffffffff0000000000000000000000000000000000000000000000000000000082167f4e2312e000000000000000000000000000000000000000000000000000000000145b8061031457507fffffffff0000000000000000000000000000000000000000000000000000000082167f150b7a0200000000000000000000000000000000000000000000000000000000145b8061035f57507fffffffff0000000000000000000000000000000000000000000000000000000082167e23de2900000000000000000000000000000000000000000000000000000000145b806103ab57507fffffffff0000000000000000000000000000000000000000000000000000000082167f1626ba7e00000000000000000000000000000000000000000000000000000000145b806103f757507fffffffff0000000000000000000000000000000000000000000000000000000082167fa4c0ed3600000000000000000000000000000000000000000000000000000000145b806101975750507fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4922602052604090205460ff1690565b60606000610460610518565b80519091508067ffffffffffffffff81111561047e5761047e61205d565b6040519080825280602002602001820160405280156104a7578160200160208202803683370190505b50925060005b81811015610512578281815181106104c7576104c761208c565b6020026020010151600001518482815181106104e5576104e561208c565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526001016104ad565b50505090565b606060007f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f600490810154604080517f7a0ed627000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff90921692637a0ed6279282820192600092908290030181865afa1580156105ac573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526105f29190810190612157565b905060006105fe610e57565b805190915060608060005b838110156106b55760008582815181106106255761062561208c565b60200260200101516020015151905060005b818110156106ab5761069e85858986815181106106565761065661208c565b60200260200101516020015184815181106106735761067361208c565b60200260200101518a878151811061068d5761068d61208c565b60200260200101516000015161134a565b9095509350600101610637565b5050600101610609565b506000805b865181101561081b576000805b8883815181106106d9576106d961208c565b602002602001015160200151518110156107ff57600073ffffffffffffffffffffffffffffffffffffffff1661074687878c878151811061071c5761071c61208c565b60200260200101516020015185815181106107395761073961208c565b60200260200101516115f1565b73ffffffffffffffffffffffffffffffffffffffff16146107e9578883815181106107735761077361208c565b6020026020010151602001515160010361079c576107918984611637565b9850600193506107ff565b6107c38984815181106107b1576107b161208c565b6020026020010151602001518261182a565b8984815181106107d5576107d561208c565b602002602001015160200181905250600191505b816107f6576001016106c7565b600091506106c7565b508261081057816001019150610815565b600092505b506106ba565b5050600085518461082c9190612304565b90508067ffffffffffffffff8111156108475761084761205d565b60405190808252806020026020018201604052801561088d57816020015b6040805180820190915260008152606060208201528152602001906001900390816108655790505b5096506000805b82811015610a585785811015610a0c578681815181106108b6576108b661208c565b60200260200101518982815181106108d0576108d061208c565b60200260200101819052506000805b8951811015610a05578981815181106108fa576108fa61208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff168b848151811061092e5761092e61208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff16036109ef5761099989848151811061096a5761096a61208c565b6020026020010151602001518b83815181106109885761098861208c565b602002602001015160200151611a3d565b8b84815181106109ab576109ab61208c565b6020026020010151602001819052506109c48a82611637565b9950600191506109e18b60018d516109dc9190612317565b611637565b9a506109ec8561232a565b94505b816109fc576001016108df565b600091506108df565b5050610a50565b878281518110610a1e57610a1e61208c565b6020026020010151898281518110610a3857610a3861208c565b602002602001018190525081610a4d9061235f565b91505b600101610894565b505050505050505090565b60606000610a6f610518565b805190915060005b81811015610aff578473ffffffffffffffffffffffffffffffffffffffff16838281518110610aa857610aa861208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1603610af757828181518110610ae157610ae161208c565b6020026020010151602001519350505050919050565b600101610a77565b505050919050565b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602081905260409091205460601c9081610c1e576004818101546040517fcdffacc60000000000000000000000000000000000000000000000000000000081527fffffffff0000000000000000000000000000000000000000000000000000000086169281019290925273ffffffffffffffffffffffffffffffffffffffff169063cdffacc690602401602060405180830381865afa158015610bf7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c1b9190612397565b91505b50919050565b6060610c2e611b8b565b905090565b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604081205460601c610197565b6060610c2e610e57565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9060009061ffff1667ffffffffffffffff811115610cfc57610cfc61205d565b604051908082528060200260200182016040528015610d25578160200160208202803683370190505b5092506000805b600284015461ffff16821015610e4d576000818152600185016020526040812054905b6008811015610e385783610d628161235f565b600288015490955061ffff1685119050610e3857600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020889052604090205460601c73ffffffffffffffffffffffffffffffffffffffff8a16819003610e235781898881518110610de457610de461208c565b7fffffffff000000000000000000000000000000000000000000000000000000009092166020928302919091019091015286610e1f8161235f565b9750505b50508080610e309061235f565b915050610d4f565b50508080610e459061235f565b915050610d2c565b5050825250919050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff1667ffffffffffffffff811115610eba57610eba61205d565b604051908082528060200260200182016040528015610f0057816020015b604080518082019091526000815260606020820152815260200190600190039081610ed85790505b50600282015490925060009061ffff1667ffffffffffffffff811115610f2857610f2861205d565b604051908082528060200260200182016040528015610f51578160200160208202803683370190505b50905060008060005b600285015461ffff168210156112d7576000818152600186016020526040812054905b60088110156112c25783610f908161235f565b600289015490955061ffff16851190506112c257600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020899052604081205460601c90805b88811015611148578273ffffffffffffffffffffffffffffffffffffffff168c82815181106110155761101561208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff160361113657838c828151811061104f5761104f61208c565b6020026020010151602001518b838151811061106d5761106d61208c565b602002602001015161ffff16815181106110895761108961208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152505060ff8a82815181106110e9576110e961208c565b602002602001015161ffff16106110ff57600080fd5b8981815181106111115761111161208c565b602002602001018051809190611126906123b4565b61ffff1690525060019150611148565b806111408161235f565b915050610fe4565b508015611157575050506112b0565b818b898151811061116a5761116a61208c565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff909116905260028a015461ffff1667ffffffffffffffff8111156111b0576111b061205d565b6040519080825280602002602001820160405280156111d9578160200160208202803683370190505b508b89815181106111ec576111ec61208c565b602002602001015160200181905250828b898151811061120e5761120e61208c565b60200260200101516020015160008151811061122c5761122c61208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681525050600189898151811061128c5761128c61208c565b61ffff90921660209283029190910190910152876112a98161235f565b9850505050505b806112ba8161235f565b915050610f7d565b505080806112cf9061235f565b915050610f5a565b5060005b8281101561133f5760008482815181106112f7576112f761208c565b602002602001015161ffff16905060008783815181106113195761131961208c565b6020026020010151602001519050818152505080806113379061235f565b9150506112db565b508185525050505090565b60608060006113598786611da0565b8751909150808210156113b857848783815181106113795761137961208c565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250506115df565b60006113c5826001612304565b67ffffffffffffffff8111156113dd576113dd61205d565b604051908082528060200260200182016040528015611406578160200160208202803683370190505b5090506000885160016114199190612304565b67ffffffffffffffff8111156114315761143161205d565b60405190808252806020026020018201604052801561145a578160200160208202803683370190505b50905060005b83811015611539578a818151811061147a5761147a61208c565b60200260200101518382815181106114945761149461208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815250508981815181106114f2576114f261208c565b602002602001015182828151811061150c5761150c61208c565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101611460565b508782848151811061154d5761154d61208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152505086818a51815181106115ad576115ad61208c565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015290945092506115e8915050565b87879350935050505b94509492505050565b6000806115fe8584611da0565b905084518110611612576000915050611630565b8381815181106116245761162461208c565b60200260200101519150505b9392505050565b6060825182106116a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420696e6465780000000000000000000000000000000000000060448201526064015b60405180910390fd5b8251600003611713576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420617272617900000000000000000000000000000000000000604482015260640161169f565b6000600184516117239190612317565b67ffffffffffffffff81111561173b5761173b61205d565b60405190808252806020026020018201604052801561178157816020015b6040805180820190915260008152606060208201528152602001906001900390816117595790505b50805190915060005b8181101561182057848110156117d6578581815181106117ac576117ac61208c565b60200260200101518382815181106117c6576117c661208c565b6020026020010181905250611818565b856117e2826001612304565b815181106117f2576117f261208c565b602002602001015183828151811061180c5761180c61208c565b60200260200101819052505b60010161178a565b5090949350505050565b606082518210611896576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420696e64657800000000000000000000000000000000000000604482015260640161169f565b8251600003611901576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420617272617900000000000000000000000000000000000000604482015260640161169f565b6000600184516119119190612317565b67ffffffffffffffff8111156119295761192961205d565b604051908082528060200260200182016040528015611952578160200160208202803683370190505b50805190915060005b8181101561182057848110156119cd5785818151811061197d5761197d61208c565b60200260200101518382815181106119975761199761208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152611a35565b856119d9826001612304565b815181106119e9576119e961208c565b6020026020010151838281518110611a0357611a0361208c565b7fffffffff00000000000000000000000000000000000000000000000000000000909216602092830291909101909101525b60010161195b565b81518151606091906000611a518284612304565b67ffffffffffffffff811115611a6957611a6961205d565b604051908082528060200260200182016040528015611a92578160200160208202803683370190505b50905060005b83811015611b0557868181518110611ab257611ab261208c565b6020026020010151828281518110611acc57611acc61208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152600101611a98565b5060005b82811015611b8157858181518110611b2357611b2361208c565b6020026020010151828286611b389190612304565b81518110611b4857611b4861208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152600101611b09565b5095945050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff1667ffffffffffffffff811115611bee57611bee61205d565b604051908082528060200260200182016040528015611c17578160200160208202803683370190505b50915060008060005b600284015461ffff16821015611d98576000818152600185016020526040812054905b6008811015611d835783611c568161235f565b600288015490955061ffff1685119050611d8357600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020889052604081205460601c90805b88811015611d19578a8181518110611cc457611cc461208c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611d075760019150611d19565b80611d118161235f565b915050611caa565b508015611d2857505050611d71565b818a8981518110611d3b57611d3b61208c565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015287611d6a8161235f565b9850505050505b80611d7b8161235f565b915050611c43565b50508080611d909061235f565b915050611c20565b505082525090565b8151600090815b81811015611e1e57837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916858281518110611de157611de161208c565b60200260200101517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603611e165791506101979050565b600101611da7565b509392505050565b73ffffffffffffffffffffffffffffffffffffffff81168114611e4857600080fd5b50565b600060208284031215611e5d57600080fd5b813561163081611e26565b6020808252825182820181905260009190848201906040850190845b81811015611ec25783517fffffffff000000000000000000000000000000000000000000000000000000001683529284019291840191600101611e84565b50909695505050505050565b7fffffffff0000000000000000000000000000000000000000000000000000000081168114611e4857600080fd5b600060208284031215611f0e57600080fd5b813561163081611ece565b6020808252825182820181905260009190848201906040850190845b81811015611ec257835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101611f35565b60006020808301818452808551808352604092508286019150828160051b8701018488016000805b8481101561204e578984037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00186528251805173ffffffffffffffffffffffffffffffffffffffff168552880151888501889052805188860181905290890190839060608701905b808310156120395783517fffffffff00000000000000000000000000000000000000000000000000000000168252928b019260019290920191908b0190611ff7565b50978a01979550505091870191600101611f8f565b50919998505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6040805190810167ffffffffffffffff811182821017156120de576120de61205d565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561212b5761212b61205d565b604052919050565b600067ffffffffffffffff82111561214d5761214d61205d565b5060051b60200190565b6000602080838503121561216a57600080fd5b825167ffffffffffffffff8082111561218257600080fd5b818501915085601f83011261219657600080fd5b81516121a96121a482612133565b6120e4565b81815260059190911b830184019084810190888311156121c857600080fd5b8585015b838110156122c8578051858111156121e45760008081fd5b86016040818c037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00181131561221a5760008081fd5b6122226120bb565b8983015161222f81611e26565b815282820151888111156122435760008081fd5b8084019350508c603f8401126122595760008081fd5b898301516122696121a482612133565b81815260059190911b84018301908b8101908f8311156122895760008081fd5b948401945b828610156122b357855194506122a385611ece565b848252948c0194908c019061228e565b838d01525050855250509186019186016121cc565b5098975050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610197576101976122d5565b81810381811115610197576101976122d5565b600081612339576123396122d5565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612390576123906122d5565b5060010190565b6000602082840312156123a957600080fd5b815161163081611e26565b600061ffff8083168181036123cb576123cb6122d5565b600101939250505056fea26469706673582212205959d8d85aad6f29d5fc37d5a52c404c25392cec49195c3b761da0e863e99b0f64736f6c63430008150033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100a35760003560e01c8063adfca15e11610076578063d42139a91161005b578063d42139a914610169578063e3a2f6fe14610171578063f9796ccf1461018457600080fd5b8063adfca15e1461011e578063cdffacc61461013157600080fd5b806301a55022146100a857806301ffc9a7146100d157806352ef6b2c146100f45780637a0ed62714610109575b600080fd5b6100bb6100b6366004611e4b565b61018c565b6040516100c89190611e68565b60405180910390f35b6100e46100df366004611efc565b61019d565b60405190151581526020016100c8565b6100fc610454565b6040516100c89190611f19565b610111610518565b6040516100c89190611f67565b6100bb61012c366004611e4b565b610a63565b61014461013f366004611efc565b610b07565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100c8565b6100fc610c24565b61014461017f366004611efc565b610c33565b610111610c8c565b606061019782610c96565b92915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000148061023057507fffffffff0000000000000000000000000000000000000000000000000000000082167f1f931c1c00000000000000000000000000000000000000000000000000000000145b8061027c57507fffffffff0000000000000000000000000000000000000000000000000000000082167f48e2b09300000000000000000000000000000000000000000000000000000000145b806102c857507fffffffff0000000000000000000000000000000000000000000000000000000082167f4e2312e000000000000000000000000000000000000000000000000000000000145b8061031457507fffffffff0000000000000000000000000000000000000000000000000000000082167f150b7a0200000000000000000000000000000000000000000000000000000000145b8061035f57507fffffffff0000000000000000000000000000000000000000000000000000000082167e23de2900000000000000000000000000000000000000000000000000000000145b806103ab57507fffffffff0000000000000000000000000000000000000000000000000000000082167f1626ba7e00000000000000000000000000000000000000000000000000000000145b806103f757507fffffffff0000000000000000000000000000000000000000000000000000000082167fa4c0ed3600000000000000000000000000000000000000000000000000000000145b806101975750507fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4922602052604090205460ff1690565b60606000610460610518565b80519091508067ffffffffffffffff81111561047e5761047e61205d565b6040519080825280602002602001820160405280156104a7578160200160208202803683370190505b50925060005b81811015610512578281815181106104c7576104c761208c565b6020026020010151600001518482815181106104e5576104e561208c565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526001016104ad565b50505090565b606060007f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f600490810154604080517f7a0ed627000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff90921692637a0ed6279282820192600092908290030181865afa1580156105ac573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526105f29190810190612157565b905060006105fe610e57565b805190915060608060005b838110156106b55760008582815181106106255761062561208c565b60200260200101516020015151905060005b818110156106ab5761069e85858986815181106106565761065661208c565b60200260200101516020015184815181106106735761067361208c565b60200260200101518a878151811061068d5761068d61208c565b60200260200101516000015161134a565b9095509350600101610637565b5050600101610609565b506000805b865181101561081b576000805b8883815181106106d9576106d961208c565b602002602001015160200151518110156107ff57600073ffffffffffffffffffffffffffffffffffffffff1661074687878c878151811061071c5761071c61208c565b60200260200101516020015185815181106107395761073961208c565b60200260200101516115f1565b73ffffffffffffffffffffffffffffffffffffffff16146107e9578883815181106107735761077361208c565b6020026020010151602001515160010361079c576107918984611637565b9850600193506107ff565b6107c38984815181106107b1576107b161208c565b6020026020010151602001518261182a565b8984815181106107d5576107d561208c565b602002602001015160200181905250600191505b816107f6576001016106c7565b600091506106c7565b508261081057816001019150610815565b600092505b506106ba565b5050600085518461082c9190612304565b90508067ffffffffffffffff8111156108475761084761205d565b60405190808252806020026020018201604052801561088d57816020015b6040805180820190915260008152606060208201528152602001906001900390816108655790505b5096506000805b82811015610a585785811015610a0c578681815181106108b6576108b661208c565b60200260200101518982815181106108d0576108d061208c565b60200260200101819052506000805b8951811015610a05578981815181106108fa576108fa61208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff168b848151811061092e5761092e61208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff16036109ef5761099989848151811061096a5761096a61208c565b6020026020010151602001518b83815181106109885761098861208c565b602002602001015160200151611a3d565b8b84815181106109ab576109ab61208c565b6020026020010151602001819052506109c48a82611637565b9950600191506109e18b60018d516109dc9190612317565b611637565b9a506109ec8561232a565b94505b816109fc576001016108df565b600091506108df565b5050610a50565b878281518110610a1e57610a1e61208c565b6020026020010151898281518110610a3857610a3861208c565b602002602001018190525081610a4d9061235f565b91505b600101610894565b505050505050505090565b60606000610a6f610518565b805190915060005b81811015610aff578473ffffffffffffffffffffffffffffffffffffffff16838281518110610aa857610aa861208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1603610af757828181518110610ae157610ae161208c565b6020026020010151602001519350505050919050565b600101610a77565b505050919050565b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602081905260409091205460601c9081610c1e576004818101546040517fcdffacc60000000000000000000000000000000000000000000000000000000081527fffffffff0000000000000000000000000000000000000000000000000000000086169281019290925273ffffffffffffffffffffffffffffffffffffffff169063cdffacc690602401602060405180830381865afa158015610bf7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c1b9190612397565b91505b50919050565b6060610c2e611b8b565b905090565b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604081205460601c610197565b6060610c2e610e57565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9060009061ffff1667ffffffffffffffff811115610cfc57610cfc61205d565b604051908082528060200260200182016040528015610d25578160200160208202803683370190505b5092506000805b600284015461ffff16821015610e4d576000818152600185016020526040812054905b6008811015610e385783610d628161235f565b600288015490955061ffff1685119050610e3857600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020889052604090205460601c73ffffffffffffffffffffffffffffffffffffffff8a16819003610e235781898881518110610de457610de461208c565b7fffffffff000000000000000000000000000000000000000000000000000000009092166020928302919091019091015286610e1f8161235f565b9750505b50508080610e309061235f565b915050610d4f565b50508080610e459061235f565b915050610d2c565b5050825250919050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff1667ffffffffffffffff811115610eba57610eba61205d565b604051908082528060200260200182016040528015610f0057816020015b604080518082019091526000815260606020820152815260200190600190039081610ed85790505b50600282015490925060009061ffff1667ffffffffffffffff811115610f2857610f2861205d565b604051908082528060200260200182016040528015610f51578160200160208202803683370190505b50905060008060005b600285015461ffff168210156112d7576000818152600186016020526040812054905b60088110156112c25783610f908161235f565b600289015490955061ffff16851190506112c257600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020899052604081205460601c90805b88811015611148578273ffffffffffffffffffffffffffffffffffffffff168c82815181106110155761101561208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff160361113657838c828151811061104f5761104f61208c565b6020026020010151602001518b838151811061106d5761106d61208c565b602002602001015161ffff16815181106110895761108961208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152505060ff8a82815181106110e9576110e961208c565b602002602001015161ffff16106110ff57600080fd5b8981815181106111115761111161208c565b602002602001018051809190611126906123b4565b61ffff1690525060019150611148565b806111408161235f565b915050610fe4565b508015611157575050506112b0565b818b898151811061116a5761116a61208c565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff909116905260028a015461ffff1667ffffffffffffffff8111156111b0576111b061205d565b6040519080825280602002602001820160405280156111d9578160200160208202803683370190505b508b89815181106111ec576111ec61208c565b602002602001015160200181905250828b898151811061120e5761120e61208c565b60200260200101516020015160008151811061122c5761122c61208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681525050600189898151811061128c5761128c61208c565b61ffff90921660209283029190910190910152876112a98161235f565b9850505050505b806112ba8161235f565b915050610f7d565b505080806112cf9061235f565b915050610f5a565b5060005b8281101561133f5760008482815181106112f7576112f761208c565b602002602001015161ffff16905060008783815181106113195761131961208c565b6020026020010151602001519050818152505080806113379061235f565b9150506112db565b508185525050505090565b60608060006113598786611da0565b8751909150808210156113b857848783815181106113795761137961208c565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250506115df565b60006113c5826001612304565b67ffffffffffffffff8111156113dd576113dd61205d565b604051908082528060200260200182016040528015611406578160200160208202803683370190505b5090506000885160016114199190612304565b67ffffffffffffffff8111156114315761143161205d565b60405190808252806020026020018201604052801561145a578160200160208202803683370190505b50905060005b83811015611539578a818151811061147a5761147a61208c565b60200260200101518382815181106114945761149461208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815250508981815181106114f2576114f261208c565b602002602001015182828151811061150c5761150c61208c565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101611460565b508782848151811061154d5761154d61208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152505086818a51815181106115ad576115ad61208c565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015290945092506115e8915050565b87879350935050505b94509492505050565b6000806115fe8584611da0565b905084518110611612576000915050611630565b8381815181106116245761162461208c565b60200260200101519150505b9392505050565b6060825182106116a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420696e6465780000000000000000000000000000000000000060448201526064015b60405180910390fd5b8251600003611713576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420617272617900000000000000000000000000000000000000604482015260640161169f565b6000600184516117239190612317565b67ffffffffffffffff81111561173b5761173b61205d565b60405190808252806020026020018201604052801561178157816020015b6040805180820190915260008152606060208201528152602001906001900390816117595790505b50805190915060005b8181101561182057848110156117d6578581815181106117ac576117ac61208c565b60200260200101518382815181106117c6576117c661208c565b6020026020010181905250611818565b856117e2826001612304565b815181106117f2576117f261208c565b602002602001015183828151811061180c5761180c61208c565b60200260200101819052505b60010161178a565b5090949350505050565b606082518210611896576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420696e64657800000000000000000000000000000000000000604482015260640161169f565b8251600003611901576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420617272617900000000000000000000000000000000000000604482015260640161169f565b6000600184516119119190612317565b67ffffffffffffffff8111156119295761192961205d565b604051908082528060200260200182016040528015611952578160200160208202803683370190505b50805190915060005b8181101561182057848110156119cd5785818151811061197d5761197d61208c565b60200260200101518382815181106119975761199761208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152611a35565b856119d9826001612304565b815181106119e9576119e961208c565b6020026020010151838281518110611a0357611a0361208c565b7fffffffff00000000000000000000000000000000000000000000000000000000909216602092830291909101909101525b60010161195b565b81518151606091906000611a518284612304565b67ffffffffffffffff811115611a6957611a6961205d565b604051908082528060200260200182016040528015611a92578160200160208202803683370190505b50905060005b83811015611b0557868181518110611ab257611ab261208c565b6020026020010151828281518110611acc57611acc61208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152600101611a98565b5060005b82811015611b8157858181518110611b2357611b2361208c565b6020026020010151828286611b389190612304565b81518110611b4857611b4861208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152600101611b09565b5095945050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff1667ffffffffffffffff811115611bee57611bee61205d565b604051908082528060200260200182016040528015611c17578160200160208202803683370190505b50915060008060005b600284015461ffff16821015611d98576000818152600185016020526040812054905b6008811015611d835783611c568161235f565b600288015490955061ffff1685119050611d8357600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020889052604081205460601c90805b88811015611d19578a8181518110611cc457611cc461208c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611d075760019150611d19565b80611d118161235f565b915050611caa565b508015611d2857505050611d71565b818a8981518110611d3b57611d3b61208c565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015287611d6a8161235f565b9850505050505b80611d7b8161235f565b915050611c43565b50508080611d909061235f565b915050611c20565b505082525090565b8151600090815b81811015611e1e57837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916858281518110611de157611de161208c565b60200260200101517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603611e165791506101979050565b600101611da7565b509392505050565b73ffffffffffffffffffffffffffffffffffffffff81168114611e4857600080fd5b50565b600060208284031215611e5d57600080fd5b813561163081611e26565b6020808252825182820181905260009190848201906040850190845b81811015611ec25783517fffffffff000000000000000000000000000000000000000000000000000000001683529284019291840191600101611e84565b50909695505050505050565b7fffffffff0000000000000000000000000000000000000000000000000000000081168114611e4857600080fd5b600060208284031215611f0e57600080fd5b813561163081611ece565b6020808252825182820181905260009190848201906040850190845b81811015611ec257835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101611f35565b60006020808301818452808551808352604092508286019150828160051b8701018488016000805b8481101561204e578984037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00186528251805173ffffffffffffffffffffffffffffffffffffffff168552880151888501889052805188860181905290890190839060608701905b808310156120395783517fffffffff00000000000000000000000000000000000000000000000000000000168252928b019260019290920191908b0190611ff7565b50978a01979550505091870191600101611f8f565b50919998505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6040805190810167ffffffffffffffff811182821017156120de576120de61205d565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561212b5761212b61205d565b604052919050565b600067ffffffffffffffff82111561214d5761214d61205d565b5060051b60200190565b6000602080838503121561216a57600080fd5b825167ffffffffffffffff8082111561218257600080fd5b818501915085601f83011261219657600080fd5b81516121a96121a482612133565b6120e4565b81815260059190911b830184019084810190888311156121c857600080fd5b8585015b838110156122c8578051858111156121e45760008081fd5b86016040818c037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00181131561221a5760008081fd5b6122226120bb565b8983015161222f81611e26565b815282820151888111156122435760008081fd5b8084019350508c603f8401126122595760008081fd5b898301516122696121a482612133565b81815260059190911b84018301908b8101908f8311156122895760008081fd5b948401945b828610156122b357855194506122a385611ece565b848252948c0194908c019061228e565b838d01525050855250509186019186016121cc565b5098975050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610197576101976122d5565b81810381811115610197576101976122d5565b600081612339576123396122d5565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612390576123906122d5565b5060010190565b6000602082840312156123a957600080fd5b815161163081611e26565b600061ffff8083168181036123cb576123cb6122d5565b600101939250505056fea26469706673582212205959d8d85aad6f29d5fc37d5a52c404c25392cec49195c3b761da0e863e99b0f64736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "DiamondLoupe contract compatible with EIP-2535", + "kind": "dev", + "methods": { + "facetAddress(bytes4)": { + "details": "If facet is not found return address(0).", + "params": { + "_functionSelector": "The function selector." + }, + "returns": { + "facetAddress_": "The facet address." + } + }, + "facetAddressFromStorage(bytes4)": { + "params": { + "_functionSelector": "Function selector to fetch the facet address from diamond storage" + }, + "returns": { + "facetAddress_": "Facet address mapped with the function selector" + } + }, + "facetAddresses()": { + "returns": { + "facetAddresses_": "facetAddresses_" + } + }, + "facetAddressesFromStorage()": { + "returns": { + "facetAddresses_": "All facet addresses attached directly to diamond storage" + } + }, + "facetFunctionSelectors(address)": { + "params": { + "_facet": "The facet address." + }, + "returns": { + "facetFunctionSelectors_": "facetFunctionSelectors_" + } + }, + "facetFunctionSelectorsFromStorage(address)": { + "params": { + "_facet": "Facet address to fetch the facet function selectors from diamond storage" + }, + "returns": { + "facetFunctionSelectors_": "Facet function selectors of the given facet address" + } + }, + "facets()": { + "details": "Barz uses a special architecture called default fallback handler. Default Fallback handler is used as a middleware that holds the mapping of facet function selector and facet address that Barz uses. This helps Barz to reduce significant amount of gas during the initialization process. Hence, this method aggregates both the facet information from DefaulFallbackHandler and in diamond storage and shows the data to users.", + "returns": { + "facets_": "Facet" + } + }, + "facetsFromStorage()": { + "returns": { + "facets_": "Facet information attached directly to diamond storage" + } + }, + "supportsInterface(bytes4)": { + "params": { + "_interfaceId": "Interface ID for detecting the interface" + }, + "returns": { + "isSupported": "Bool value showing if the standard is supported in the contract" + } + } + }, + "title": "DiamondLoupe Facet", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "facetAddress(bytes4)": { + "notice": "Gets the facet that supports the given selector." + }, + "facetAddressFromStorage(bytes4)": { + "notice": "Returns the facet address attached to the given function selector. This excludes the facets from the default fallback handler" + }, + "facetAddresses()": { + "notice": "Get all the facet addresses used by Barz." + }, + "facetAddressesFromStorage()": { + "notice": "Returns all facet addresses attached directly to diamond storage. This excludes the facets from the default fallback handler" + }, + "facetFunctionSelectors(address)": { + "notice": "Gets all the function selectors provided by a facet." + }, + "facetFunctionSelectorsFromStorage(address)": { + "notice": "Returns function selectors of given facet address attached directly to diamond storage. This excludes the facets from the default fallback handler" + }, + "facets()": { + "notice": "Gets all facets and their selectors." + }, + "facetsFromStorage()": { + "notice": "Returns the facet from the diamond storage. This excludes the facets from the default fallback handler" + }, + "supportsInterface(bytes4)": { + "notice": "SupportInterface to be compatible with EIP 165" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/lightLink/Secp256k1VerificationFacet.json b/deployments/lightLink/Secp256k1VerificationFacet.json new file mode 100644 index 0000000..8b06032 --- /dev/null +++ b/deployments/lightLink/Secp256k1VerificationFacet.json @@ -0,0 +1,483 @@ +{ + "address": "0x58Cb9Abe27fcd6f72354E98Cf5cc46BEAA2182DF", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "LibAppStorage__AccountMustBeUninitialized", + "type": "error" + }, + { + "inputs": [], + "name": "LibAppStorage__SignerAlreadyUninitialized", + "type": "error" + }, + { + "inputs": [], + "name": "LibAppStorage__SignerMustBeUninitialized", + "type": "error" + }, + { + "inputs": [], + "name": "Secp256k1VerificationFacet__InvalidSignerLength", + "type": "error" + }, + { + "inputs": [], + "name": "VerificationFacet__InitializationFailure", + "type": "error" + }, + { + "inputs": [], + "name": "VerificationFacet__InvalidFacetMapping", + "type": "error" + }, + { + "inputs": [], + "name": "VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet", + "type": "error" + }, + { + "inputs": [], + "name": "VerificationFacet__ValidateOwnerSignatureSelectorNotSet", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "SignerInitialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "SignerUninitialized", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_publicKey", + "type": "bytes" + } + ], + "name": "initializeSigner", + "outputs": [ + { + "internalType": "uint256", + "name": "initSuccess", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_publicKey", + "type": "bytes" + } + ], + "name": "isValidKeyType", + "outputs": [ + { + "internalType": "bool", + "name": "isValid", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_hash", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "_signature", + "type": "bytes" + } + ], + "name": "isValidSignature", + "outputs": [ + { + "internalType": "bytes4", + "name": "magicValue", + "type": "bytes4" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "bytes", + "name": "signer", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "self", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "uninitializeSigner", + "outputs": [ + { + "internalType": "uint256", + "name": "uninitSuccess", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "initCode", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "callGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "verificationGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "preVerificationGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxFeePerGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPriorityFeePerGas", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "paymasterAndData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "internalType": "struct UserOperation", + "name": "userOp", + "type": "tuple" + }, + { + "internalType": "bytes32", + "name": "userOpHash", + "type": "bytes32" + } + ], + "name": "validateOwnerSignature", + "outputs": [ + { + "internalType": "uint256", + "name": "validationData", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "validateOwnerSignatureSelector", + "outputs": [ + { + "internalType": "bytes4", + "name": "ownerSignatureValidatorSelector", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "initCode", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "callGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "verificationGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "preVerificationGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxFeePerGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPriorityFeePerGas", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "paymasterAndData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "internalType": "struct UserOperation", + "name": "userOp", + "type": "tuple" + }, + { + "internalType": "bytes32", + "name": "userOpHash", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "signer", + "type": "address" + } + ], + "name": "validateSignature", + "outputs": [ + { + "internalType": "uint256", + "name": "isValid", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + } + ], + "transactionHash": "0xf4bd12ab073ace805cd854b8cb036dc81ec4849770ad98e2e06e5c05f290f196", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": "0x0000000000000000000000000000000000000000", + "transactionIndex": 0, + "gasUsed": "1042239", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x984d29b803331ad21427a0ea08c414b48f33af1608d89aa4ff22280b81718b7a", + "transactionHash": "0xf4bd12ab073ace805cd854b8cb036dc81ec4849770ad98e2e06e5c05f290f196", + "logs": [], + "blockNumber": 72701613, + "cumulativeGasUsed": "1042239", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "ad34345aa73d96f52b3e14df983b6b29", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"LibAppStorage__AccountMustBeUninitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LibAppStorage__SignerAlreadyUninitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LibAppStorage__SignerMustBeUninitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Secp256k1VerificationFacet__InvalidSignerLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerificationFacet__InitializationFailure\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerificationFacet__InvalidFacetMapping\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerificationFacet__ValidateOwnerSignatureSelectorNotSet\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"SignerInitialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"SignerUninitialized\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_publicKey\",\"type\":\"bytes\"}],\"name\":\"initializeSigner\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"initSuccess\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_publicKey\",\"type\":\"bytes\"}],\"name\":\"isValidKeyType\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isValid\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_hash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"_signature\",\"type\":\"bytes\"}],\"name\":\"isValidSignature\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"magicValue\",\"type\":\"bytes4\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"signer\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"self\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"uninitializeSigner\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"uninitSuccess\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"userOp\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"}],\"name\":\"validateOwnerSignature\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"validationData\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"validateOwnerSignatureSelector\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"ownerSignatureValidatorSelector\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"userOp\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"}],\"name\":\"validateSignature\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"isValid\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)Ruslan Serebriakov (@rsrbk)\",\"details\":\"Default Ethereum's elliptic curve\",\"kind\":\"dev\",\"methods\":{\"initializeSigner(bytes)\":{\"details\":\"This method checks if the signer has already been initialized. If already initialized, it reverts. It checks if the public key is in the light format and initializes signer storage in k1 storage.\",\"params\":{\"_publicKey\":\"Bytes of owner public key\"},\"returns\":{\"initSuccess\":\"Uint value representing the success of init operation\"}},\"isValidKeyType(bytes)\":{\"details\":\"For this Secp256k1Verification Facet, the public key length should be 65 in an uncompressed public key format\",\"params\":{\"_publicKey\":\"Bytes of public key for format check\"},\"returns\":{\"isValid\":\"Boolean variable representing if the format of public key is valid\"}},\"isValidSignature(bytes32,bytes)\":{\"details\":\"This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\",\"params\":{\"_hash\":\"Hash value the owner signed\",\"_signature\":\"Signature that signed the above hash\"},\"returns\":{\"magicValue\":\"Bytes4 value representing the success/failure of validation\"}},\"owner()\":{\"returns\":{\"signer\":\"Bytes of owner address\"}},\"uninitializeSigner()\":{\"details\":\"This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\",\"returns\":{\"uninitSuccess\":\"Uint value representing the success of uninit operation\"}},\"validateOwnerSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32)\":{\"details\":\"This method validates if the user operation is signed by the owner. It internally calls validateSignature with signer public key.\",\"params\":{\"userOp\":\"UserOperation including all information for execution\",\"userOpHash\":\"Hash of UserOperation given from EntryPoint. This hash is used for signature validation\"},\"returns\":{\"validationData\":\"Uint value representing whether the validation is successful. 0 for success, 1 for failure\"}},\"validateOwnerSignatureSelector()\":{\"returns\":{\"ownerSignatureValidatorSelector\":\"Bytes4 selector of function signature to validate account owner's UserOperation signature\"}},\"validateSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,address)\":{\"details\":\"This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\",\"params\":{\"signer\":\"Address of signer who signed the contract, to be validated\",\"userOp\":\"UserOperation including all information for execution\",\"userOpHash\":\"Hash of UserOperation given from EntryPoint. This hash is used for signature validation\"},\"returns\":{\"isValid\":\"Uint value representing whether the validation is successful. 0 for success, 1 for failure\"}}},\"title\":\"Secp256k1 verification facet\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"This constructor ensures that this contract can only be used as singleton for Proxy contracts\"},\"initializeSigner(bytes)\":{\"notice\":\"Initializes the signer in K1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\"},\"isValidKeyType(bytes)\":{\"notice\":\"Validates if the format of public key is valid for this verification facet\"},\"isValidSignature(bytes32,bytes)\":{\"notice\":\"Validates if the signature is valid. Function to be compatible with EIP-1271\"},\"owner()\":{\"notice\":\"Returns the owner of the account\"},\"uninitializeSigner()\":{\"notice\":\"Uninitialize signer in K1 Facet Storage. This can only be called when the account is undergoing signature migration and has already been initialized.\"},\"validateOwnerSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32)\":{\"notice\":\"Validates if the user operation is signed by the owner.\"},\"validateOwnerSignatureSelector()\":{\"notice\":\"Returns the selector of function to validate the signature of UserOperation\"},\"validateSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,address)\":{\"notice\":\"Validates if the signature of UserOperation is signed by the given signer\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/verification/secp256k1/Secp256k1VerificationFacet.sol\":\"Secp256k1VerificationFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./math/Math.sol\\\";\\nimport \\\"./math/SignedMath.sol\\\";\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n uint256 length = Math.log10(value) + 1;\\n string memory buffer = new string(length);\\n uint256 ptr;\\n /// @solidity memory-safe-assembly\\n assembly {\\n ptr := add(buffer, add(32, length))\\n }\\n while (true) {\\n ptr--;\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\\n }\\n value /= 10;\\n if (value == 0) break;\\n }\\n return buffer;\\n }\\n }\\n\\n /**\\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\\n */\\n function toString(int256 value) internal pure returns (string memory) {\\n return string(abi.encodePacked(value < 0 ? \\\"-\\\" : \\\"\\\", toString(SignedMath.abs(value))));\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n return toHexString(value, Math.log256(value) + 1);\\n }\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n\\n /**\\n * @dev Returns true if the two strings are equal.\\n */\\n function equal(string memory a, string memory b) internal pure returns (bool) {\\n return keccak256(bytes(a)) == keccak256(bytes(b));\\n }\\n}\\n\",\"keccak256\":\"0x3088eb2868e8d13d89d16670b5f8612c4ab9ff8956272837d8e90106c59c14a0\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Strings.sol\\\";\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSA {\\n enum RecoverError {\\n NoError,\\n InvalidSignature,\\n InvalidSignatureLength,\\n InvalidSignatureS,\\n InvalidSignatureV // Deprecated in v4.8\\n }\\n\\n function _throwError(RecoverError error) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert(\\\"ECDSA: invalid signature\\\");\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert(\\\"ECDSA: invalid signature length\\\");\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert(\\\"ECDSA: invalid signature 's' value\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature` or error string. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n *\\n * Documentation for signature generation:\\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n return tryRecover(hash, v, r, s);\\n } else {\\n return (address(0), RecoverError.InvalidSignatureLength);\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature`. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, signature);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\\n uint8 v = uint8((uint256(vs) >> 255) + 27);\\n return tryRecover(hash, v, r, s);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n *\\n * _Available since v4.2._\\n */\\n function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\\n // the valid range for s in (301): 0 < s < secp256k1n \\u00f7 2 + 1, and for v in (302): v \\u2208 {27, 28}. Most\\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\\n //\\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\\n // these malleable signatures as well.\\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n return (address(0), RecoverError.InvalidSignatureS);\\n }\\n\\n // If the signature is valid (and not malleable), return the signer address\\n address signer = ecrecover(hash, v, r, s);\\n if (signer == address(0)) {\\n return (address(0), RecoverError.InvalidSignature);\\n }\\n\\n return (signer, RecoverError.NoError);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore(0x00, \\\"\\\\x19Ethereum Signed Message:\\\\n32\\\")\\n mstore(0x1c, hash)\\n message := keccak256(0x00, 0x3c)\\n }\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from `s`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n\\\", Strings.toString(s.length), s));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Typed Data, created from a\\n * `domainSeparator` and a `structHash`. This produces hash corresponding\\n * to the one signed with the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n * JSON-RPC method as part of EIP-712.\\n *\\n * See {recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n let ptr := mload(0x40)\\n mstore(ptr, \\\"\\\\x19\\\\x01\\\")\\n mstore(add(ptr, 0x02), domainSeparator)\\n mstore(add(ptr, 0x22), structHash)\\n data := keccak256(ptr, 0x42)\\n }\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Data with intended validator, created from a\\n * `validator` and `data` according to the version 0 of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x00\\\", validator, data));\\n }\\n}\\n\",\"keccak256\":\"0x809bc3edb4bcbef8263fa616c1b60ee0004b50a8a1bfa164d8f57fd31f520c58\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n enum Rounding {\\n Down, // Toward negative infinity\\n Up, // Toward infinity\\n Zero // Toward zero\\n }\\n\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow.\\n return (a & b) + (a ^ b) / 2;\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a == 0 ? 0 : (a - 1) / b + 1;\\n }\\n\\n /**\\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\\n * with further edits by Uniswap Labs also under MIT license.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\\n unchecked {\\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2^256 + prod0.\\n uint256 prod0; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division.\\n if (prod1 == 0) {\\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\\n // The surrounding unchecked block does not change this fact.\\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\\n return prod0 / denominator;\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n require(denominator > prod1, \\\"Math: mulDiv overflow\\\");\\n\\n ///////////////////////////////////////////////\\n // 512 by 256 division.\\n ///////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0].\\n uint256 remainder;\\n assembly {\\n // Compute remainder using mulmod.\\n remainder := mulmod(x, y, denominator)\\n\\n // Subtract 256 bit number from 512 bit number.\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\\n // See https://cs.stackexchange.com/q/138556/92363.\\n\\n // Does not overflow because the denominator cannot be zero at this stage in the function.\\n uint256 twos = denominator & (~denominator + 1);\\n assembly {\\n // Divide denominator by twos.\\n denominator := div(denominator, twos)\\n\\n // Divide [prod1 prod0] by twos.\\n prod0 := div(prod0, twos)\\n\\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\\n twos := add(div(sub(0, twos), twos), 1)\\n }\\n\\n // Shift in bits from prod1 into prod0.\\n prod0 |= prod1 * twos;\\n\\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\\n // four bits. That is, denominator * inv = 1 mod 2^4.\\n uint256 inverse = (3 * denominator) ^ 2;\\n\\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\\n // in modular arithmetic, doubling the correct bits in each step.\\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\\n\\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inverse;\\n return result;\\n }\\n }\\n\\n /**\\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\\n uint256 result = mulDiv(x, y, denominator);\\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\\n result += 1;\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\\n *\\n * Inspired by Henry S. Warren, Jr.'s \\\"Hacker's Delight\\\" (Chapter 11).\\n */\\n function sqrt(uint256 a) internal pure returns (uint256) {\\n if (a == 0) {\\n return 0;\\n }\\n\\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\\n //\\n // We know that the \\\"msb\\\" (most significant bit) of our target number `a` is a power of 2 such that we have\\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\\n //\\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\\n // \\u2192 `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\\n // \\u2192 `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\\n //\\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\\n uint256 result = 1 << (log2(a) >> 1);\\n\\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\\n // into the expected uint128 result.\\n unchecked {\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n return min(result, a / result);\\n }\\n }\\n\\n /**\\n * @notice Calculates sqrt(a), following the selected rounding direction.\\n */\\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = sqrt(a);\\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 2, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 128;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 64;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 32;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 16;\\n }\\n if (value >> 8 > 0) {\\n value >>= 8;\\n result += 8;\\n }\\n if (value >> 4 > 0) {\\n value >>= 4;\\n result += 4;\\n }\\n if (value >> 2 > 0) {\\n value >>= 2;\\n result += 2;\\n }\\n if (value >> 1 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log2(value);\\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 10, rounded down, of a positive value.\\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 + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 256, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n *\\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\\n */\\n function log256(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 16;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 8;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 4;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 2;\\n }\\n if (value >> 8 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log256(value);\\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe4455ac1eb7fc497bb7402579e7b4d64d928b846fce7d2b6fde06d366f21c2b3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\\n * checks.\\n *\\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\\n * easily result in undesired exploitation or bugs, since developers usually\\n * assume that overflows raise errors. `SafeCast` restores this intuition by\\n * reverting the transaction when such an operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n *\\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\\n * all math on `uint256` and `int256` and then downcasting.\\n */\\nlibrary SafeCast {\\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 * _Available since v4.7._\\n */\\n function toUint248(uint256 value) internal pure returns (uint248) {\\n require(value <= type(uint248).max, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint240(uint256 value) internal pure returns (uint240) {\\n require(value <= type(uint240).max, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint232(uint256 value) internal pure returns (uint232) {\\n require(value <= type(uint232).max, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint224(uint256 value) internal pure returns (uint224) {\\n require(value <= type(uint224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint216(uint256 value) internal pure returns (uint216) {\\n require(value <= type(uint216).max, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint208(uint256 value) internal pure returns (uint208) {\\n require(value <= type(uint208).max, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint200(uint256 value) internal pure returns (uint200) {\\n require(value <= type(uint200).max, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint192(uint256 value) internal pure returns (uint192) {\\n require(value <= type(uint192).max, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint184(uint256 value) internal pure returns (uint184) {\\n require(value <= type(uint184).max, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint176(uint256 value) internal pure returns (uint176) {\\n require(value <= type(uint176).max, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint168(uint256 value) internal pure returns (uint168) {\\n require(value <= type(uint168).max, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint160(uint256 value) internal pure returns (uint160) {\\n require(value <= type(uint160).max, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint152(uint256 value) internal pure returns (uint152) {\\n require(value <= type(uint152).max, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint144(uint256 value) internal pure returns (uint144) {\\n require(value <= type(uint144).max, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint136(uint256 value) internal pure returns (uint136) {\\n require(value <= type(uint136).max, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint128(uint256 value) internal pure returns (uint128) {\\n require(value <= type(uint128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint120(uint256 value) internal pure returns (uint120) {\\n require(value <= type(uint120).max, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint112(uint256 value) internal pure returns (uint112) {\\n require(value <= type(uint112).max, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint104(uint256 value) internal pure returns (uint104) {\\n require(value <= type(uint104).max, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint96(uint256 value) internal pure returns (uint96) {\\n require(value <= type(uint96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint88(uint256 value) internal pure returns (uint88) {\\n require(value <= type(uint88).max, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint80(uint256 value) internal pure returns (uint80) {\\n require(value <= type(uint80).max, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint72(uint256 value) internal pure returns (uint72) {\\n require(value <= type(uint72).max, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint64(uint256 value) internal pure returns (uint64) {\\n require(value <= type(uint64).max, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint56(uint256 value) internal pure returns (uint56) {\\n require(value <= type(uint56).max, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint48(uint256 value) internal pure returns (uint48) {\\n require(value <= type(uint48).max, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint40(uint256 value) internal pure returns (uint40) {\\n require(value <= type(uint40).max, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint32(uint256 value) internal pure returns (uint32) {\\n require(value <= type(uint32).max, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint24(uint256 value) internal pure returns (uint24) {\\n require(value <= type(uint24).max, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint16(uint256 value) internal pure returns (uint16) {\\n require(value <= type(uint16).max, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint8(uint256 value) internal pure returns (uint8) {\\n require(value <= type(uint8).max, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\n */\\n function toUint256(int256 value) internal pure returns (uint256) {\\n require(value >= 0, \\\"SafeCast: value must be positive\\\");\\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 * _Available since v4.7._\\n */\\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\\n downcasted = int248(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\\n downcasted = int240(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\\n downcasted = int232(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\\n downcasted = int224(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\\n downcasted = int216(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\\n downcasted = int208(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\\n downcasted = int200(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\\n downcasted = int192(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\\n downcasted = int184(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\\n downcasted = int176(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\\n downcasted = int168(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\\n downcasted = int160(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\\n downcasted = int152(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\\n downcasted = int144(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\\n downcasted = int136(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\\n downcasted = int128(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\\n downcasted = int120(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\\n downcasted = int112(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\\n downcasted = int104(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\\n downcasted = int96(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\\n downcasted = int88(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\\n downcasted = int80(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\\n downcasted = int72(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\\n downcasted = int64(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\\n downcasted = int56(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\\n downcasted = int48(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\\n downcasted = int40(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\\n downcasted = int32(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\\n downcasted = int24(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\\n downcasted = int16(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\\n downcasted = int8(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\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 require(value <= uint256(type(int256).max), \\\"SafeCast: value doesn't fit in an int256\\\");\\n return int256(value);\\n }\\n}\\n\",\"keccak256\":\"0x52a8cfb0f5239d11b457dcdd1b326992ef672714ca8da71a157255bddd13f3ad\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SignedMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard signed math utilities missing in the Solidity language.\\n */\\nlibrary SignedMath {\\n /**\\n * @dev Returns the largest of two signed numbers.\\n */\\n function max(int256 a, int256 b) internal pure returns (int256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two signed numbers.\\n */\\n function min(int256 a, int256 b) internal pure returns (int256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two signed numbers without overflow.\\n * The result is rounded towards zero.\\n */\\n function average(int256 a, int256 b) internal pure returns (int256) {\\n // Formula from the book \\\"Hacker's Delight\\\"\\n int256 x = (a & b) + ((a ^ b) >> 1);\\n return x + (int256(uint256(x) >> 255) & (a ^ b));\\n }\\n\\n /**\\n * @dev Returns the absolute unsigned value of a signed value.\\n */\\n function abs(int256 n) internal pure returns (uint256) {\\n unchecked {\\n // must be unchecked in order to support `n = type(int256).min`\\n return uint256(n >= 0 ? n : -n);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf92515413956f529d95977adc9b0567d583c6203fc31ab1c23824c35187e3ddc\",\"license\":\"MIT\"},\"contracts/aa-4337/core/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable no-inline-assembly */\\n\\n/**\\n * returned data from validateUserOp.\\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\\n * @param aggregator - address(0) - the account validated the signature by itself.\\n * address(1) - the account failed to validate the signature.\\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\\n * @param validAfter - this UserOp is valid only after this timestamp.\\n * @param validaUntil - this UserOp is valid only up to this timestamp.\\n */\\nstruct ValidationData {\\n address aggregator;\\n uint48 validAfter;\\n uint48 validUntil;\\n}\\n\\n//extract sigFailed, validAfter, validUntil.\\n// also convert zero validUntil to type(uint48).max\\nfunction _parseValidationData(\\n uint validationData\\n) pure returns (ValidationData memory data) {\\n address aggregator = address(uint160(validationData));\\n uint48 validUntil = uint48(validationData >> 160);\\n if (validUntil == 0) {\\n validUntil = type(uint48).max;\\n }\\n uint48 validAfter = uint48(validationData >> (48 + 160));\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n// intersect account and paymaster ranges.\\nfunction _intersectTimeRange(\\n uint256 validationData,\\n uint256 paymasterValidationData\\n) pure returns (ValidationData memory) {\\n ValidationData memory accountValidationData = _parseValidationData(\\n validationData\\n );\\n ValidationData memory pmValidationData = _parseValidationData(\\n paymasterValidationData\\n );\\n address aggregator = accountValidationData.aggregator;\\n if (aggregator == address(0)) {\\n aggregator = pmValidationData.aggregator;\\n }\\n uint48 validAfter = accountValidationData.validAfter;\\n uint48 validUntil = accountValidationData.validUntil;\\n uint48 pmValidAfter = pmValidationData.validAfter;\\n uint48 pmValidUntil = pmValidationData.validUntil;\\n\\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp\\n * @param data - the ValidationData to pack\\n */\\nfunction _packValidationData(\\n ValidationData memory data\\n) pure returns (uint256) {\\n return\\n uint160(data.aggregator) |\\n (uint256(data.validUntil) << 160) |\\n (uint256(data.validAfter) << (160 + 48));\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp, when not using an aggregator\\n * @param sigFailed - true for signature failure, false for success\\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\\n * @param validAfter first timestamp this UserOperation is valid\\n */\\nfunction _packValidationData(\\n bool sigFailed,\\n uint48 validUntil,\\n uint48 validAfter\\n) pure returns (uint256) {\\n return\\n (sigFailed ? 1 : 0) |\\n (uint256(validUntil) << 160) |\\n (uint256(validAfter) << (160 + 48));\\n}\\n\\n/**\\n * keccak function over calldata.\\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\\n */\\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\\n assembly {\\n let mem := mload(0x40)\\n let len := data.length\\n calldatacopy(mem, data.offset, len)\\n ret := keccak256(mem, len)\\n }\\n}\\n\",\"keccak256\":\"0xa79f06cd158ecb8c0da95493a2f348933b8627a63e228b99738bff3aa107942d\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAggregator.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\n/**\\n * Aggregated Signatures validator.\\n */\\ninterface IAggregator {\\n /**\\n * validate aggregated signature.\\n * revert if the aggregated signature does not match the given list of operations.\\n */\\n function validateSignatures(\\n UserOperation[] calldata userOps,\\n bytes calldata signature\\n ) external view;\\n\\n /**\\n * validate signature of a single userOp\\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\\n * @param userOp the userOperation received from the user.\\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\\n * (usually empty, unless account and aggregator support some kind of \\\"multisig\\\"\\n */\\n function validateUserOpSignature(\\n UserOperation calldata userOp\\n ) external view returns (bytes memory sigForUserOp);\\n\\n /**\\n * aggregate multiple signatures into a single value.\\n * This method is called off-chain to calculate the signature to pass with handleOps()\\n * bundler MAY use optimized custom code perform this aggregation\\n * @param userOps array of UserOperations to collect the signatures from.\\n * @return aggregatedSignature the aggregated signature\\n */\\n function aggregateSignatures(\\n UserOperation[] calldata userOps\\n ) external view returns (bytes memory aggregatedSignature);\\n}\\n\",\"keccak256\":\"0xdfdcd80568f037716674619b31be630fcd8316262f05a815b41d1e81782c966a\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IEntryPoint.sol\":{\"content\":\"/**\\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\\n ** Only one instance required on each chain.\\n **/\\n// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-inline-assembly */\\n/* solhint-disable reason-string */\\n\\nimport \\\"./UserOperation.sol\\\";\\nimport \\\"./IStakeManager.sol\\\";\\nimport \\\"./IAggregator.sol\\\";\\nimport \\\"./INonceManager.sol\\\";\\n\\ninterface IEntryPoint is IStakeManager, INonceManager {\\n /***\\n * An event emitted after each successful request\\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\\n * @param sender - the account that generates this request.\\n * @param paymaster - if non-null, the paymaster that pays for this request.\\n * @param nonce - the nonce value from the request.\\n * @param success - true if the sender transaction succeeded, false if reverted.\\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\\n */\\n event UserOperationEvent(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address indexed paymaster,\\n uint256 nonce,\\n bool success,\\n uint256 actualGasCost,\\n uint256 actualGasUsed\\n );\\n\\n /**\\n * account \\\"sender\\\" was deployed.\\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\\n * @param sender the account that is deployed\\n * @param factory the factory used to deploy this account (in the initCode)\\n * @param paymaster the paymaster used by this UserOp\\n */\\n event AccountDeployed(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address factory,\\n address paymaster\\n );\\n\\n /**\\n * An event emitted if the UserOperation \\\"callData\\\" reverted with non-zero length\\n * @param userOpHash the request unique identifier.\\n * @param sender the sender of this request\\n * @param nonce the nonce used in the request\\n * @param revertReason - the return bytes from the (reverted) call to \\\"callData\\\".\\n */\\n event UserOperationRevertReason(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n uint256 nonce,\\n bytes revertReason\\n );\\n\\n /**\\n * an event emitted by handleOps(), before starting the execution loop.\\n * any event emitted before this event, is part of the validation.\\n */\\n event BeforeExecution();\\n\\n /**\\n * signature aggregator used by the following UserOperationEvents within this bundle.\\n */\\n event SignatureAggregatorChanged(address indexed aggregator);\\n\\n /**\\n * a custom revert error of handleOps, to identify the offending op.\\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\\n * @param reason - revert reason\\n * The string starts with a unique code \\\"AAmn\\\", where \\\"m\\\" is \\\"1\\\" for factory, \\\"2\\\" for account and \\\"3\\\" for paymaster issues,\\n * so a failure can be attributed to the correct entity.\\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\\n */\\n error FailedOp(uint256 opIndex, string reason);\\n\\n /**\\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\\n */\\n error SignatureValidationFailed(address aggregator);\\n\\n /**\\n * Successful result from simulateValidation.\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n */\\n error ValidationResult(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo\\n );\\n\\n /**\\n * Successful result from simulateValidation, if the account returns a signature aggregator\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\\n * bundler MUST use it to verify the signature, or reject the UserOperation\\n */\\n error ValidationResultWithAggregation(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo,\\n AggregatorStakeInfo aggregatorInfo\\n );\\n\\n /**\\n * return value of getSenderAddress\\n */\\n error SenderAddressResult(address sender);\\n\\n /**\\n * return value of simulateHandleOp\\n */\\n error ExecutionResult(\\n uint256 preOpGas,\\n uint256 paid,\\n uint48 validAfter,\\n uint48 validUntil,\\n bool targetSuccess,\\n bytes targetResult\\n );\\n\\n //UserOps handled, per aggregator\\n struct UserOpsPerAggregator {\\n UserOperation[] userOps;\\n // aggregator address\\n IAggregator aggregator;\\n // aggregated signature\\n bytes signature;\\n }\\n\\n /**\\n * Execute a batch of UserOperation.\\n * no signature aggregator is used.\\n * if any account requires an aggregator (that is, it returned an aggregator when\\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\\n * @param ops the operations to execute\\n * @param beneficiary the address to receive the fees\\n */\\n function handleOps(\\n UserOperation[] calldata ops,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * Execute a batch of UserOperation with Aggregators\\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\\n * @param beneficiary the address to receive the fees\\n */\\n function handleAggregatedOps(\\n UserOpsPerAggregator[] calldata opsPerAggregator,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * generate a request Id - unique identifier for this request.\\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\\n */\\n function getUserOpHash(\\n UserOperation calldata userOp\\n ) external view returns (bytes32);\\n\\n /**\\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\\n * @param userOp the user operation to validate.\\n */\\n function simulateValidation(UserOperation calldata userOp) external;\\n\\n /**\\n * gas and return values during simulation\\n * @param preOpGas the gas used for validation (including preValidationGas)\\n * @param prefund the required prefund for this operation\\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\\n */\\n struct ReturnInfo {\\n uint256 preOpGas;\\n uint256 prefund;\\n bool sigFailed;\\n uint48 validAfter;\\n uint48 validUntil;\\n bytes paymasterContext;\\n }\\n\\n /**\\n * returned aggregated signature info.\\n * the aggregator returned by the account, and its current stake.\\n */\\n struct AggregatorStakeInfo {\\n address aggregator;\\n StakeInfo stakeInfo;\\n }\\n\\n /**\\n * Get counterfactual sender address.\\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\\n * this method always revert, and returns the address in SenderAddressResult error\\n * @param initCode the constructor code to be passed into the UserOperation.\\n */\\n function getSenderAddress(bytes memory initCode) external;\\n\\n /**\\n * simulate full execution of a UserOperation (including both validation and target execution)\\n * this method will always revert with \\\"ExecutionResult\\\".\\n * it performs full validation of the UserOperation, but ignores signature error.\\n * an optional target address is called after the userop succeeds, and its value is returned\\n * (before the entire call is reverted)\\n * Note that in order to collect the the success/failure of the target call, it must be executed\\n * with trace enabled to track the emitted events.\\n * @param op the UserOperation to simulate\\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\\n * are set to the return from that call.\\n * @param targetCallData callData to pass to target address\\n */\\n function simulateHandleOp(\\n UserOperation calldata op,\\n address target,\\n bytes calldata targetCallData\\n ) external;\\n}\\n\",\"keccak256\":\"0x9ccb1b188eda8bbf5f6c2d01bd83c3d8b2b04fcf745283051d31fe96d1d8e40f\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/INonceManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\ninterface INonceManager {\\n /**\\n * Return the next nonce for this sender.\\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\\n * But UserOp with different keys can come with arbitrary order.\\n *\\n * @param sender the account address\\n * @param key the high 192 bit of the nonce\\n * @return nonce a full nonce to pass for next UserOp with this sender.\\n */\\n function getNonce(\\n address sender,\\n uint192 key\\n ) external view returns (uint256 nonce);\\n\\n /**\\n * Manually increment the nonce of the sender.\\n * This method is exposed just for completeness..\\n * Account does NOT need to call it, neither during validation, nor elsewhere,\\n * as the EntryPoint will update the nonce regardless.\\n * Possible use-case is call it with various keys to \\\"initialize\\\" their nonces to one, so that future\\n * UserOperations will not pay extra for the first transaction with a given key.\\n */\\n function incrementNonce(uint192 key) external;\\n}\\n\",\"keccak256\":\"0xce478ad0fa0d18a3b785ac854623029e7ab463d05873dfaa365abfa1bf100912\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IStakeManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8.12;\\n\\n/**\\n * manage deposits and stakes.\\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\\n * stake is value locked for at least \\\"unstakeDelay\\\" by the staked entity.\\n */\\ninterface IStakeManager {\\n event Deposited(address indexed account, uint256 totalDeposit);\\n\\n event Withdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /// Emitted when stake or unstake delay are modified\\n event StakeLocked(\\n address indexed account,\\n uint256 totalStaked,\\n uint256 unstakeDelaySec\\n );\\n\\n /// Emitted once a stake is scheduled for withdrawal\\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\\n\\n event StakeWithdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /**\\n * @param deposit the entity's deposit\\n * @param staked true if this entity is staked.\\n * @param stake actual amount of ether staked for this entity.\\n * @param unstakeDelaySec minimum delay to withdraw the stake.\\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\\n * and the rest fit into a 2nd cell.\\n * 112 bit allows for 10^15 eth\\n * 48 bit for full timestamp\\n * 32 bit allows 150 years for unstake delay\\n */\\n struct DepositInfo {\\n uint112 deposit;\\n bool staked;\\n uint112 stake;\\n uint32 unstakeDelaySec;\\n uint48 withdrawTime;\\n }\\n\\n //API struct used by getStakeInfo and simulateValidation\\n struct StakeInfo {\\n uint256 stake;\\n uint256 unstakeDelaySec;\\n }\\n\\n /// @return info - full deposit information of given account\\n function getDepositInfo(\\n address account\\n ) external view returns (DepositInfo memory info);\\n\\n /// @return the deposit (for gas payment) of the account\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * add to the deposit of the given account\\n */\\n function depositTo(address account) external payable;\\n\\n /**\\n * add to the account's stake - amount and delay\\n * any pending unstake is first cancelled.\\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\\n */\\n function addStake(uint32 _unstakeDelaySec) external payable;\\n\\n /**\\n * attempt to unlock the stake.\\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\\n */\\n function unlockStake() external;\\n\\n /**\\n * withdraw from the (unlocked) stake.\\n * must first call unlockStake and wait for the unstakeDelay to pass\\n * @param withdrawAddress the address to send withdrawn value.\\n */\\n function withdrawStake(address payable withdrawAddress) external;\\n\\n /**\\n * withdraw from the deposit.\\n * @param withdrawAddress the address to send withdrawn value.\\n * @param withdrawAmount the amount to withdraw.\\n */\\n function withdrawTo(\\n address payable withdrawAddress,\\n uint256 withdrawAmount\\n ) external;\\n}\\n\",\"keccak256\":\"0xadcea606c9b7aafe6645441f2154a60f271330b0eee5292a632aa71c1672d546\",\"license\":\"GPL-3.0-only\"},\"contracts/aa-4337/interfaces/UserOperation.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable no-inline-assembly */\\n\\nimport {calldataKeccak} from \\\"../core/Helpers.sol\\\";\\n\\n/**\\n * User Operation struct\\n * @param sender the sender account of this request.\\n * @param nonce unique value the sender uses to verify it is not a replay.\\n * @param initCode if set, the account contract will be created by this constructor/\\n * @param callData the method call to execute on this account.\\n * @param callGasLimit the gas limit passed to the callData method call.\\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\\n * @param maxFeePerGas same as EIP-1559 gas parameter.\\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\\n */\\nstruct UserOperation {\\n address sender;\\n uint256 nonce;\\n bytes initCode;\\n bytes callData;\\n uint256 callGasLimit;\\n uint256 verificationGasLimit;\\n uint256 preVerificationGas;\\n uint256 maxFeePerGas;\\n uint256 maxPriorityFeePerGas;\\n bytes paymasterAndData;\\n bytes signature;\\n}\\n\\n/**\\n * Utility functions helpful when working with UserOperation structs.\\n */\\nlibrary UserOperationLib {\\n function getSender(\\n UserOperation calldata userOp\\n ) internal pure returns (address) {\\n address data;\\n //read sender from userOp, which is first userOp member (saves 800 gas...)\\n assembly {\\n data := calldataload(userOp)\\n }\\n return address(uint160(data));\\n }\\n\\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\\n // pay above what he signed for.\\n function gasPrice(\\n UserOperation calldata userOp\\n ) internal view returns (uint256) {\\n unchecked {\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n if (maxFeePerGas == maxPriorityFeePerGas) {\\n //legacy mode (for networks that don't support basefee opcode)\\n return maxFeePerGas;\\n }\\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\\n }\\n }\\n\\n function pack(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes memory ret) {\\n address sender = getSender(userOp);\\n uint256 nonce = userOp.nonce;\\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\\n bytes32 hashCallData = calldataKeccak(userOp.callData);\\n uint256 callGasLimit = userOp.callGasLimit;\\n uint256 verificationGasLimit = userOp.verificationGasLimit;\\n uint256 preVerificationGas = userOp.preVerificationGas;\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\\n\\n return\\n abi.encode(\\n sender,\\n nonce,\\n hashInitCode,\\n hashCallData,\\n callGasLimit,\\n verificationGasLimit,\\n preVerificationGas,\\n maxFeePerGas,\\n maxPriorityFeePerGas,\\n hashPaymasterAndData\\n );\\n }\\n\\n function hash(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes32) {\\n return keccak256(pack(userOp));\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n}\\n\",\"keccak256\":\"0x2429f5cc546bdee08c7e63858d0dda8491eaa3ab5194df884dc948c1154d2834\",\"license\":\"GPL-3.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/facets/interfaces/IVerificationFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {UserOperation} from \\\"../../aa-4337/interfaces/UserOperation.sol\\\";\\n\\n/**\\n * @title Verification Facet Interface\\n * @dev Implements logic for user ops signature verification\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\ninterface IVerificationFacet {\\n event SignerInitialized(bytes);\\n event SignerUninitialized();\\n\\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\\n error VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\\n error VerificationFacet__InitializationFailure();\\n error VerificationFacet__InvalidFacetMapping();\\n\\n function initializeSigner(bytes memory) external returns (uint256);\\n\\n function uninitializeSigner() external returns (uint256);\\n\\n function validateOwnerSignatureSelector() external view returns (bytes4);\\n\\n function owner() external view returns (bytes memory);\\n\\n function isValidKeyType(bytes calldata) external view returns (bool);\\n\\n function validateOwnerSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x72bc370a1d1b5a6d6bde67f5026733fd8f6ba434bb90e73b0bd8627fb1579928\",\"license\":\"Apache-2.0\"},\"contracts/facets/verification/secp256k1/Secp256k1VerificationFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {ECDSA} from \\\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\\\";\\nimport {UserOperation} from \\\"../../../aa-4337/interfaces/UserOperation.sol\\\";\\nimport {LibAppStorage} from \\\"../../../libraries/LibAppStorage.sol\\\";\\nimport {LibFacetStorage, Secp256k1VerificationStorage} from \\\"../../../libraries/LibFacetStorage.sol\\\";\\nimport {LibLoupe} from \\\"../../../libraries/LibLoupe.sol\\\";\\nimport {IERC1271} from \\\"../../../interfaces/ERC/IERC1271.sol\\\";\\nimport {IVerificationFacet} from \\\"../../interfaces/IVerificationFacet.sol\\\";\\n\\n/**\\n * @title Secp256k1 verification facet\\n * @dev Default Ethereum's elliptic curve\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\ncontract Secp256k1VerificationFacet is IVerificationFacet, IERC1271 {\\n using ECDSA for bytes32;\\n error Secp256k1VerificationFacet__InvalidSignerLength();\\n address public immutable self;\\n\\n /**\\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\\n */\\n constructor() {\\n LibAppStorage.enforceSignerInitialize();\\n self = address(this);\\n }\\n\\n /**\\n * @notice Initializes the signer in K1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\\n * @param _publicKey Bytes of owner public key\\n * @return initSuccess Uint value representing the success of init operation\\n */\\n function initializeSigner(\\n bytes calldata _publicKey\\n ) public override returns (uint256 initSuccess) {\\n LibAppStorage.enforceSignerInitialize();\\n if (!isValidKeyType(_publicKey))\\n revert Secp256k1VerificationFacet__InvalidSignerLength();\\n\\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\\n .k1Storage();\\n k1Storage.signer = address(uint160(uint256(keccak256(_publicKey[1:]))));\\n\\n bytes4 validateSelector = validateOwnerSignatureSelector();\\n\\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\\n if (LibLoupe.facetAddress(validateSelector) != self)\\n revert VerificationFacet__InvalidFacetMapping();\\n\\n // initialize verification function selector\\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\\n\\n initSuccess = 1;\\n\\n emit SignerInitialized(_publicKey);\\n }\\n\\n /**\\n * @notice Uninitialize signer in K1 Facet Storage. This can only be called when the account is undergoing signature migration\\n * and has already been initialized.\\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\\n * @return uninitSuccess Uint value representing the success of uninit operation\\n */\\n function uninitializeSigner()\\n external\\n override\\n returns (uint256 uninitSuccess)\\n {\\n LibAppStorage.enforceSignerMigration();\\n LibAppStorage.setSignerUninitialized();\\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\\n .k1Storage();\\n k1Storage.signer = address(0);\\n\\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\\n\\n uninitSuccess = 1;\\n\\n emit SignerUninitialized();\\n }\\n\\n /**\\n * @notice Validates if the user operation is signed by the owner.\\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\\n * signer public key.\\n * @param userOp UserOperation including all information for execution\\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\\n */\\n function validateOwnerSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) public view override returns (uint256 validationData) {\\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\\n .k1Storage();\\n validationData = validateSignature(\\n userOp,\\n userOpHash,\\n k1Storage.signer\\n );\\n }\\n\\n /**\\n * @notice Validates if the signature of UserOperation is signed by the given signer\\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\\n * @param userOp UserOperation including all information for execution\\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\\n * @param signer Address of signer who signed the contract, to be validated\\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\\n */\\n function validateSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n address signer\\n ) public pure returns (uint256 isValid) {\\n bytes32 hash = userOpHash.toEthSignedMessageHash();\\n isValid = (signer != hash.recover(userOp.signature)) ? 1 : 0;\\n }\\n\\n /**\\n * @notice Returns the selector of function to validate the signature of UserOperation\\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\\n */\\n function validateOwnerSignatureSelector()\\n public\\n pure\\n override\\n returns (bytes4 ownerSignatureValidatorSelector)\\n {\\n ownerSignatureValidatorSelector = this.validateOwnerSignature.selector;\\n // NOTE: The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\\n }\\n\\n /**\\n * @notice Returns the owner of the account\\n * @return signer Bytes of owner address\\n */\\n function owner() public view override returns (bytes memory signer) {\\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\\n .k1Storage();\\n signer = abi.encodePacked(k1Storage.signer);\\n }\\n\\n /**\\n * @notice Validates if the format of public key is valid for this verification facet\\n * @dev For this Secp256k1Verification Facet, the public key length should be 65 in an uncompressed public key format\\n * @param _publicKey Bytes of public key for format check\\n * @return isValid Boolean variable representing if the format of public key is valid\\n */\\n function isValidKeyType(\\n bytes memory _publicKey\\n ) public pure override returns (bool isValid) {\\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\\n }\\n\\n /**\\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\\n * @param _hash Hash value the owner signed\\n * @param _signature Signature that signed the above hash\\n * @return magicValue Bytes4 value representing the success/failure of validation\\n */\\n function isValidSignature(\\n bytes32 _hash,\\n bytes memory _signature\\n ) public view override returns (bytes4 magicValue) {\\n magicValue = (_hash.recover(_signature) ==\\n LibFacetStorage.k1Storage().signer)\\n ? this.isValidSignature.selector\\n : bytes4(0xffffffff);\\n }\\n}\\n\",\"keccak256\":\"0x293ca694d0bad996df8b6d83a4bfdc4e5c3b3bc2e3f19e046c280e0233dbd806\",\"license\":\"Apache-2.0\"},\"contracts/infrastructure/interfaces/IFacetRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Registry Interface\\n * @dev Interface for Facet Registry contract to keep track of facets & function selectors addable to user wallets\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IFacetRegistry {\\n struct FacetRegistryConfig {\\n bytes4[] selectors;\\n mapping(bytes4 => FacetInfo) info;\\n }\\n struct FacetInfo {\\n bool exists;\\n uint128 index;\\n }\\n\\n event FacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] facetSelectors\\n );\\n event FacetFunctionSelectorsRemoved(address facet, bytes4[] facetSelectors);\\n\\n error FacetRegistry__FacetSelectorAlreadyRegistered();\\n error FacetRegistry__UnregisteredFacetSelector();\\n\\n function registerFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function removeFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function areFacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external view returns (bool);\\n\\n function isFacetFunctionSelectorRegistered(\\n address facet,\\n bytes4 facetSelector\\n ) external view returns (bool);\\n\\n function getFacetFunctionSelectors(\\n address facet\\n ) external view returns (bytes4[] memory);\\n}\\n\",\"keccak256\":\"0x6e6dd2cab346ef7c31230740ec48d2925e4a9ab24c2f2fb268baaf408dcf02ef\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC1271 {\\n function isValidSignature(\\n bytes32 hash,\\n bytes memory signature\\n ) external view returns (bytes4);\\n}\\n\",\"keccak256\":\"0xcdddb7d5641c9d3f2432dec7fd13fddb9ae1480f25c76c21511e2fa16b8bd422\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibAppStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {SafeCast} from \\\"@openzeppelin/contracts/utils/math/SafeCast.sol\\\";\\nimport {IEntryPoint} from \\\"../aa-4337/interfaces/IEntryPoint.sol\\\";\\nimport {IFacetRegistry} from \\\"../infrastructure/interfaces/IFacetRegistry.sol\\\";\\n\\n/*\\n * @title App Storage\\n * @dev App storage for Barz contract to prevent storage collision\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Lock {\\n uint64 release;\\n bytes4 locker;\\n}\\n\\nstruct InitializersStorage {\\n // NOTE: initialized is a variable to make sure the initialization is only done once.\\n uint8 signerInitialized;\\n uint8 accountInitialized;\\n uint8 restrictionsInitialized;\\n}\\n\\nstruct AppStorage {\\n mapping(uint256 => InitializersStorage) initStorage;\\n uint8 signerMigration;\\n bytes4 validateOwnerSignatureSelector;\\n IEntryPoint entryPoint;\\n IFacetRegistry facetRegistry;\\n mapping(uint256 => Lock) locks;\\n}\\n\\nlibrary LibAppStorage {\\n error LibAppStorage__AccountAlreadyUninitialized();\\n error LibAppStorage__AccountMustBeUninitialized();\\n error LibAppStorage__SignerAlreadyUninitialized();\\n error LibAppStorage__SignerMustBeUninitialized();\\n\\n function appStorage() internal pure returns (AppStorage storage ds) {\\n assembly {\\n ds.slot := 0\\n }\\n }\\n\\n function setSignerUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerAlreadyUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 0;\\n }\\n\\n function getValidateOwnerSignatureSelector()\\n internal\\n view\\n returns (bytes4 selector)\\n {\\n selector = appStorage().validateOwnerSignatureSelector;\\n }\\n\\n function setValidateOwnerSignatureSelector(\\n bytes4 _validateOwnerSignatureSelector\\n ) internal {\\n appStorage()\\n .validateOwnerSignatureSelector = _validateOwnerSignatureSelector;\\n }\\n\\n function enforceSignerInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerMustBeUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 1;\\n }\\n\\n function enforceAccountInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].accountInitialized) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n s.initStorage[0].accountInitialized = 1;\\n }\\n\\n function initiateSignerMigration() internal {\\n appStorage().signerMigration = 1;\\n }\\n\\n function enforceSignerMigration() internal view {\\n if (1 != appStorage().signerMigration) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n }\\n\\n function finalizeSignerMigration() internal {\\n appStorage().signerMigration = 0;\\n }\\n\\n function setLock(uint256 _releaseAfter, bytes4 _locker) internal {\\n appStorage().locks[0] = Lock(SafeCast.toUint64(_releaseAfter), _locker);\\n }\\n\\n function enforceRestrictionsInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__SignerMustBeUninitialized();\\n s.initStorage[0].restrictionsInitialized = 1;\\n }\\n\\n function setRestrictionsUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__AccountAlreadyUninitialized();\\n s.initStorage[0].restrictionsInitialized = 0;\\n }\\n}\\n\\ncontract BarzStorage {\\n AppStorage internal s;\\n modifier onlyWhenUnlocked() {\\n require(\\n uint64(block.timestamp) >= s.locks[0].release,\\n \\\"Account Locked\\\"\\n );\\n _;\\n }\\n modifier onlyWhenLocked() {\\n require(\\n uint64(block.timestamp) < s.locks[0].release,\\n \\\"Account Unlocked\\\"\\n );\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x48524007862a6ce0e07f645950613ce6513ce073c37a109c75019683d42bae27\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\\n bytes4(keccak256(\\\"verifyRestrictions(address,address,uint256,bytes)\\\"));\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // Default Fallback Handler of the barz.\\n IDiamondLoupe defaultFallbackHandler;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function enforceIsSelf() internal view {\\n require(msg.sender == address(this), \\\"LibDiamond: Caller not self\\\");\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n\\n unchecked {\\n facetIndex++;\\n }\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n\\n function restrictionsFacet() internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(\\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2cabdc00de859c3a3170ce3bda5d0e5fd3933d47ce904fd1585f9818b02572f8\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibFacetStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Storage\\n * @dev Storage contract to store each facets variables with diamond storage\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Secp256k1VerificationStorage {\\n address signer;\\n}\\n\\nstruct Secp256r1VerificationStorage {\\n uint256[2] q;\\n}\\n\\nstruct GuardianStorage {\\n mapping(bytes32 => uint256) pending;\\n mapping(uint8 => StorageConfig) configs;\\n}\\n\\nstruct Info {\\n bool exists;\\n uint128 index;\\n}\\n\\nstruct StorageConfig {\\n address[] addresses;\\n mapping(address => Info) info;\\n}\\n\\nstruct RecoveryConfig {\\n bytes recoveryPublicKey;\\n uint64 executeAfter;\\n}\\n\\nstruct ApprovalConfig {\\n bool isApproved;\\n uint64 validUntil;\\n}\\n\\nstruct RecoveryApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isNewOwnerApproved;\\n}\\n\\nstruct RecoveryStorage {\\n mapping(uint8 => RecoveryConfig) recoveryConfigs;\\n mapping(uint8 => RecoveryApprovalConfig) recoveryApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct RestrictionsStorage {\\n address[] restrictions;\\n mapping(address => bool) exists;\\n}\\n\\nstruct SignatureMigrationConfig {\\n bytes migrationPublicKey;\\n address migrationVerificationFacet;\\n bytes4[] migrationSelectors;\\n uint64 migrateAfter;\\n}\\n\\nstruct SignatureMigrationApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isMigrationApproved;\\n}\\n\\nstruct SignatureMigrationStorage {\\n mapping(uint8 => SignatureMigrationConfig) migrationConfigs;\\n mapping(uint8 => SignatureMigrationApprovalConfig) migrationApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct DiamondCutApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isDiamondCutApproved;\\n}\\n\\nstruct DiamondCutStorage {\\n mapping(uint8 => DiamondCutApprovalConfig) diamondCutApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct LockStorage {\\n uint128 nonce;\\n}\\n\\nlibrary LibFacetStorage {\\n bytes32 constant K1_STORAGE_POSITION =\\n keccak256(\\n \\\"v0.trustwallet.diamond.storage.Secp256k1VerificationStorage\\\"\\n );\\n bytes32 constant R1_STORAGE_POSITION =\\n keccak256(\\n \\\"v0.trustwallet.diamond.storage.Secp256r1VerificationStorage\\\"\\n );\\n bytes32 constant GUARDIAN_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.GuardianStorage\\\");\\n bytes32 constant RECOVERY_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.RecoveryStorage\\\");\\n bytes32 constant RESTRICTION_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.RestrictionsStorage\\\");\\n bytes32 constant MIGRATION_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.SignatureMigrationStorage\\\");\\n bytes32 constant DIAMONDCUT_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.DiamondCutStorage\\\");\\n bytes32 constant LOCK_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.LockStorage\\\");\\n\\n function k1Storage()\\n internal\\n pure\\n returns (Secp256k1VerificationStorage storage ds)\\n {\\n bytes32 storagePosition = K1_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function r1Storage()\\n internal\\n pure\\n returns (Secp256r1VerificationStorage storage ds)\\n {\\n bytes32 storagePosition = R1_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function guardianStorage()\\n internal\\n pure\\n returns (GuardianStorage storage ds)\\n {\\n bytes32 storagePosition = GUARDIAN_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function recoveryStorage()\\n internal\\n pure\\n returns (RecoveryStorage storage ds)\\n {\\n bytes32 storagePosition = RECOVERY_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function restrictionsStorage()\\n internal\\n pure\\n returns (RestrictionsStorage storage ds)\\n {\\n bytes32 storagePosition = RESTRICTION_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function migrationStorage()\\n internal\\n pure\\n returns (SignatureMigrationStorage storage ds)\\n {\\n bytes32 storagePosition = MIGRATION_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function diamondCutStorage()\\n internal\\n pure\\n returns (DiamondCutStorage storage ds)\\n {\\n bytes32 storagePosition = DIAMONDCUT_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function lockStorage() internal pure returns (LockStorage storage ds) {\\n bytes32 storagePosition = LOCK_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n}\\n\",\"keccak256\":\"0x87c85decfd943deda9540733e464cb1a92eba735a301e89ce6f798016e359761\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\nimport {LibDiamond} from \\\"./LibDiamond.sol\\\";\\n\\n/**\\n * @title LibLoupe\\n * @dev Internal Library to provide utility feature for reading the state of diamond facets\\n * Originally from Diamond's implementation of Mudgen(author of EIP-2535)\\n */\\nlibrary LibLoupe {\\n /// @notice Gets all facets and their selectors.\\n /// @return facets_ Facet\\n function facets()\\n internal\\n view\\n returns (IDiamondLoupe.Facet[] memory facets_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facets_ = new IDiamondLoupe.Facet[](ds.selectorCount);\\n uint16[] memory numFacetSelectors = new uint16[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facets_[facetIndex].facetAddress == facetAddress_) {\\n facets_[facetIndex].functionSelectors[\\n numFacetSelectors[facetIndex]\\n ] = selector;\\n // probably will never have more than 256 functions from one facet contract\\n require(numFacetSelectors[facetIndex] < 255);\\n numFacetSelectors[facetIndex]++;\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facets_[numFacets].facetAddress = facetAddress_;\\n facets_[numFacets].functionSelectors = new bytes4[](\\n ds.selectorCount\\n );\\n facets_[numFacets].functionSelectors[0] = selector;\\n numFacetSelectors[numFacets] = 1;\\n numFacets++;\\n }\\n }\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n uint256 numSelectors = numFacetSelectors[facetIndex];\\n bytes4[] memory selectors = facets_[facetIndex].functionSelectors;\\n // setting the number of selectors\\n assembly {\\n mstore(selectors, numSelectors)\\n }\\n }\\n // setting the number of facets\\n assembly {\\n mstore(facets_, numFacets)\\n }\\n }\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return _facetFunctionSelectors The selectors associated with a facet address.\\n function facetFunctionSelectors(\\n address _facet\\n ) internal view returns (bytes4[] memory _facetFunctionSelectors) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n uint256 numSelectors;\\n _facetFunctionSelectors = new bytes4[](ds.selectorCount);\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facet = address(bytes20(ds.facets[selector]));\\n if (_facet == facet) {\\n _facetFunctionSelectors[numSelectors] = selector;\\n numSelectors++;\\n }\\n }\\n }\\n // Set the number of selectors in the array\\n assembly {\\n mstore(_facetFunctionSelectors, numSelectors)\\n }\\n }\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n internal\\n view\\n returns (address[] memory facetAddresses_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetAddresses_ = new address[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facetAddress_ == facetAddresses_[facetIndex]) {\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facetAddresses_[numFacets] = facetAddress_;\\n numFacets++;\\n }\\n }\\n // Set the number of facet addresses in the array\\n assembly {\\n mstore(facetAddresses_, numFacets)\\n }\\n }\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(LibDiamond.diamondStorage().facets[_functionSelector])\\n );\\n }\\n}\\n\",\"keccak256\":\"0x0b11439c3cc657095e15ec2241fdcf67204b14001357b612fc5db4ff9e760a5a\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x60a060405234801561001057600080fd5b50610019610022565b3060805261008b565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff161561006f57604051637c2cde8b60e01b815260040160405180910390fd5b600080805260209190915260409020805460ff19166001179055565b6080516111946100ad6000396000818161013f015261066401526111946000f3fe608060405234801561001057600080fd5b50600436106100a35760003560e01c80638da5cb5b11610076578063cd00e50a1161005b578063cd00e50a14610218578063cd9b47e414610220578063f45007c31461023357600080fd5b80638da5cb5b146101865780638dd50121146101f757600080fd5b80631626ba7e146100a85780633253960f146100f1578063392dd6d9146101175780637104ddb21461013a575b600080fd5b6100bb6100b6366004610de8565b610246565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020015b60405180910390f35b7f8dd50121000000000000000000000000000000000000000000000000000000006100bb565b61012a610125366004610e2f565b6102f4565b60405190151581526020016100e8565b6101617f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100e8565b7f9d0217145d12a316adea26b4f622aec07fb71e6638d613bb415476f4c179eecc546040805160609290921b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016602083015280518083036014018152603490920190526040516100e89190610e64565b61020a610205366004610ee9565b610366565b6040519081526020016100e8565b61020a6103b8565b61020a61022e366004610f2e565b6104d6565b61020a610241366004610fa0565b6107b7565b60007f9d0217145d12a316adea26b4f622aec07fb71e6638d613bb415476f4c179eecc5473ffffffffffffffffffffffffffffffffffffffff1661028a848461087c565b73ffffffffffffffffffffffffffffffffffffffff16146102cb577fffffffff000000000000000000000000000000000000000000000000000000006102ed565b7f1626ba7e000000000000000000000000000000000000000000000000000000005b9392505050565b60008151604114801561036057508160008151811061031557610315611014565b6020910101517fff00000000000000000000000000000000000000000000000000000000000000167f0400000000000000000000000000000000000000000000000000000000000000145b92915050565b7f9d0217145d12a316adea26b4f622aec07fb71e6638d613bb415476f4c179eecc8054600091906103b0908590859073ffffffffffffffffffffffffffffffffffffffff166107b7565b949350505050565b60006103c26108a0565b6103ca6108e0565b7f9d0217145d12a316adea26b4f622aec07fb71e6638d613bb415476f4c179eecc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001681556000610424600154610100900460e01b90565b7fffffffff00000000000000000000000000000000000000000000000000000000160361047d576040517f127c609a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff169055604051600192507fcccd30db6bc000b8bb8d11162228d2d69e3c361983ca3ae8c1365ce64b0fae9e90600090a15090565b60006104e061097f565b61051f83838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102f492505050565b610555576040517f22281e8500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f9d0217145d12a316adea26b4f622aec07fb71e6638d613bb415476f4c179eecc6105838360018187611043565b60405161059192919061106d565b60405190819003902081547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9091161781556001547f8dd501210000000000000000000000000000000000000000000000000000000090600090610100900460e01b7fffffffff000000000000000000000000000000000000000000000000000000001614610662576040517f5f95a63c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166106f3827fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604090205460601c90565b73ffffffffffffffffffffffffffffffffffffffff1614610740576040517fbb4752b700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff1661010060e084901c02179055600192507f6d54821a69ec281ed7ba1bf2729c700768c47df1d80fad646b0a14cc1d5c39ed85856040516107a792919061107d565b60405180910390a1505092915050565b7f19457468657265756d205369676e6564204d6573736167653a0a3332000000006000908152601c839052603c81206108346107f76101408701876110ca565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250859392505061087c9050565b73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361086d576000610870565b60015b60ff1695945050505050565b600080600061088b8585610a1f565b9150915061089881610a64565b509392505050565b6001805460ff16146108de576040517f38fc28cb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff16600114610948576040517fe00d7c7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff16156109e5576040517f7c2cde8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b6000808251604103610a555760208301516040840151606085015160001a610a4987828585610c1f565b94509450505050610a5d565b506000905060025b9250929050565b6000816004811115610a7857610a7861112f565b03610a805750565b6001816004811115610a9457610a9461112f565b03610b00576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064015b60405180910390fd5b6002816004811115610b1457610b1461112f565b03610b7b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610af7565b6003816004811115610b8f57610b8f61112f565b03610c1c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610af7565b50565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115610c565750600090506003610d05565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015610caa573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116610cfe57600060019250925050610d05565b9150600090505b94509492505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112610d4e57600080fd5b813567ffffffffffffffff80821115610d6957610d69610d0e565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715610daf57610daf610d0e565b81604052838152866020858801011115610dc857600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060408385031215610dfb57600080fd5b82359150602083013567ffffffffffffffff811115610e1957600080fd5b610e2585828601610d3d565b9150509250929050565b600060208284031215610e4157600080fd5b813567ffffffffffffffff811115610e5857600080fd5b6103b084828501610d3d565b600060208083528351808285015260005b81811015610e9157858101830151858201604001528201610e75565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b60006101608284031215610ee357600080fd5b50919050565b60008060408385031215610efc57600080fd5b823567ffffffffffffffff811115610f1357600080fd5b610f1f85828601610ed0565b95602094909401359450505050565b60008060208385031215610f4157600080fd5b823567ffffffffffffffff80821115610f5957600080fd5b818501915085601f830112610f6d57600080fd5b813581811115610f7c57600080fd5b866020828501011115610f8e57600080fd5b60209290920196919550909350505050565b600080600060608486031215610fb557600080fd5b833567ffffffffffffffff811115610fcc57600080fd5b610fd886828701610ed0565b93505060208401359150604084013573ffffffffffffffffffffffffffffffffffffffff8116811461100957600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000808585111561105357600080fd5b8386111561106057600080fd5b5050820193919092039150565b8183823760009101908152919050565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126110ff57600080fd5b83018035915067ffffffffffffffff82111561111a57600080fd5b602001915036819003821315610a5d57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea2646970667358221220de3368e3f3953432149ec8ab61e8db05409a34e6f3f223f6bc0a20072fa01cf364736f6c63430008150033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100a35760003560e01c80638da5cb5b11610076578063cd00e50a1161005b578063cd00e50a14610218578063cd9b47e414610220578063f45007c31461023357600080fd5b80638da5cb5b146101865780638dd50121146101f757600080fd5b80631626ba7e146100a85780633253960f146100f1578063392dd6d9146101175780637104ddb21461013a575b600080fd5b6100bb6100b6366004610de8565b610246565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020015b60405180910390f35b7f8dd50121000000000000000000000000000000000000000000000000000000006100bb565b61012a610125366004610e2f565b6102f4565b60405190151581526020016100e8565b6101617f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100e8565b7f9d0217145d12a316adea26b4f622aec07fb71e6638d613bb415476f4c179eecc546040805160609290921b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016602083015280518083036014018152603490920190526040516100e89190610e64565b61020a610205366004610ee9565b610366565b6040519081526020016100e8565b61020a6103b8565b61020a61022e366004610f2e565b6104d6565b61020a610241366004610fa0565b6107b7565b60007f9d0217145d12a316adea26b4f622aec07fb71e6638d613bb415476f4c179eecc5473ffffffffffffffffffffffffffffffffffffffff1661028a848461087c565b73ffffffffffffffffffffffffffffffffffffffff16146102cb577fffffffff000000000000000000000000000000000000000000000000000000006102ed565b7f1626ba7e000000000000000000000000000000000000000000000000000000005b9392505050565b60008151604114801561036057508160008151811061031557610315611014565b6020910101517fff00000000000000000000000000000000000000000000000000000000000000167f0400000000000000000000000000000000000000000000000000000000000000145b92915050565b7f9d0217145d12a316adea26b4f622aec07fb71e6638d613bb415476f4c179eecc8054600091906103b0908590859073ffffffffffffffffffffffffffffffffffffffff166107b7565b949350505050565b60006103c26108a0565b6103ca6108e0565b7f9d0217145d12a316adea26b4f622aec07fb71e6638d613bb415476f4c179eecc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001681556000610424600154610100900460e01b90565b7fffffffff00000000000000000000000000000000000000000000000000000000160361047d576040517f127c609a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff169055604051600192507fcccd30db6bc000b8bb8d11162228d2d69e3c361983ca3ae8c1365ce64b0fae9e90600090a15090565b60006104e061097f565b61051f83838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102f492505050565b610555576040517f22281e8500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f9d0217145d12a316adea26b4f622aec07fb71e6638d613bb415476f4c179eecc6105838360018187611043565b60405161059192919061106d565b60405190819003902081547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9091161781556001547f8dd501210000000000000000000000000000000000000000000000000000000090600090610100900460e01b7fffffffff000000000000000000000000000000000000000000000000000000001614610662576040517f5f95a63c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166106f3827fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604090205460601c90565b73ffffffffffffffffffffffffffffffffffffffff1614610740576040517fbb4752b700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff1661010060e084901c02179055600192507f6d54821a69ec281ed7ba1bf2729c700768c47df1d80fad646b0a14cc1d5c39ed85856040516107a792919061107d565b60405180910390a1505092915050565b7f19457468657265756d205369676e6564204d6573736167653a0a3332000000006000908152601c839052603c81206108346107f76101408701876110ca565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250859392505061087c9050565b73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361086d576000610870565b60015b60ff1695945050505050565b600080600061088b8585610a1f565b9150915061089881610a64565b509392505050565b6001805460ff16146108de576040517f38fc28cb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff16600114610948576040517fe00d7c7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff16156109e5576040517f7c2cde8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b6000808251604103610a555760208301516040840151606085015160001a610a4987828585610c1f565b94509450505050610a5d565b506000905060025b9250929050565b6000816004811115610a7857610a7861112f565b03610a805750565b6001816004811115610a9457610a9461112f565b03610b00576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064015b60405180910390fd5b6002816004811115610b1457610b1461112f565b03610b7b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610af7565b6003816004811115610b8f57610b8f61112f565b03610c1c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610af7565b50565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115610c565750600090506003610d05565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015610caa573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116610cfe57600060019250925050610d05565b9150600090505b94509492505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112610d4e57600080fd5b813567ffffffffffffffff80821115610d6957610d69610d0e565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715610daf57610daf610d0e565b81604052838152866020858801011115610dc857600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060408385031215610dfb57600080fd5b82359150602083013567ffffffffffffffff811115610e1957600080fd5b610e2585828601610d3d565b9150509250929050565b600060208284031215610e4157600080fd5b813567ffffffffffffffff811115610e5857600080fd5b6103b084828501610d3d565b600060208083528351808285015260005b81811015610e9157858101830151858201604001528201610e75565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b60006101608284031215610ee357600080fd5b50919050565b60008060408385031215610efc57600080fd5b823567ffffffffffffffff811115610f1357600080fd5b610f1f85828601610ed0565b95602094909401359450505050565b60008060208385031215610f4157600080fd5b823567ffffffffffffffff80821115610f5957600080fd5b818501915085601f830112610f6d57600080fd5b813581811115610f7c57600080fd5b866020828501011115610f8e57600080fd5b60209290920196919550909350505050565b600080600060608486031215610fb557600080fd5b833567ffffffffffffffff811115610fcc57600080fd5b610fd886828701610ed0565b93505060208401359150604084013573ffffffffffffffffffffffffffffffffffffffff8116811461100957600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000808585111561105357600080fd5b8386111561106057600080fd5b5050820193919092039150565b8183823760009101908152919050565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126110ff57600080fd5b83018035915067ffffffffffffffff82111561111a57600080fd5b602001915036819003821315610a5d57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea2646970667358221220de3368e3f3953432149ec8ab61e8db05409a34e6f3f223f6bc0a20072fa01cf364736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)Ruslan Serebriakov (@rsrbk)", + "details": "Default Ethereum's elliptic curve", + "kind": "dev", + "methods": { + "initializeSigner(bytes)": { + "details": "This method checks if the signer has already been initialized. If already initialized, it reverts. It checks if the public key is in the light format and initializes signer storage in k1 storage.", + "params": { + "_publicKey": "Bytes of owner public key" + }, + "returns": { + "initSuccess": "Uint value representing the success of init operation" + } + }, + "isValidKeyType(bytes)": { + "details": "For this Secp256k1Verification Facet, the public key length should be 65 in an uncompressed public key format", + "params": { + "_publicKey": "Bytes of public key for format check" + }, + "returns": { + "isValid": "Boolean variable representing if the format of public key is valid" + } + }, + "isValidSignature(bytes32,bytes)": { + "details": "This method verifies the signature if the owner indeed signed the hash. Returns magic value if true", + "params": { + "_hash": "Hash value the owner signed", + "_signature": "Signature that signed the above hash" + }, + "returns": { + "magicValue": "Bytes4 value representing the success/failure of validation" + } + }, + "owner()": { + "returns": { + "signer": "Bytes of owner address" + } + }, + "uninitializeSigner()": { + "details": "This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.", + "returns": { + "uninitSuccess": "Uint value representing the success of uninit operation" + } + }, + "validateOwnerSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32)": { + "details": "This method validates if the user operation is signed by the owner. It internally calls validateSignature with signer public key.", + "params": { + "userOp": "UserOperation including all information for execution", + "userOpHash": "Hash of UserOperation given from EntryPoint. This hash is used for signature validation" + }, + "returns": { + "validationData": "Uint value representing whether the validation is successful. 0 for success, 1 for failure" + } + }, + "validateOwnerSignatureSelector()": { + "returns": { + "ownerSignatureValidatorSelector": "Bytes4 selector of function signature to validate account owner's UserOperation signature" + } + }, + "validateSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,address)": { + "details": "This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address", + "params": { + "signer": "Address of signer who signed the contract, to be validated", + "userOp": "UserOperation including all information for execution", + "userOpHash": "Hash of UserOperation given from EntryPoint. This hash is used for signature validation" + }, + "returns": { + "isValid": "Uint value representing whether the validation is successful. 0 for success, 1 for failure" + } + } + }, + "title": "Secp256k1 verification facet", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "constructor": { + "notice": "This constructor ensures that this contract can only be used as singleton for Proxy contracts" + }, + "initializeSigner(bytes)": { + "notice": "Initializes the signer in K1 Facet Storage. This can only be called when the account is uninitialized or during signature migration." + }, + "isValidKeyType(bytes)": { + "notice": "Validates if the format of public key is valid for this verification facet" + }, + "isValidSignature(bytes32,bytes)": { + "notice": "Validates if the signature is valid. Function to be compatible with EIP-1271" + }, + "owner()": { + "notice": "Returns the owner of the account" + }, + "uninitializeSigner()": { + "notice": "Uninitialize signer in K1 Facet Storage. This can only be called when the account is undergoing signature migration and has already been initialized." + }, + "validateOwnerSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32)": { + "notice": "Validates if the user operation is signed by the owner." + }, + "validateOwnerSignatureSelector()": { + "notice": "Returns the selector of function to validate the signature of UserOperation" + }, + "validateSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,address)": { + "notice": "Validates if the signature of UserOperation is signed by the given signer" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/lightLink/Secp256r1VerificationFacet.json b/deployments/lightLink/Secp256r1VerificationFacet.json new file mode 100644 index 0000000..addf42c --- /dev/null +++ b/deployments/lightLink/Secp256r1VerificationFacet.json @@ -0,0 +1,483 @@ +{ + "address": "0xeE1AF8E967eC04C84711842796A5E714D2FD33e6", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "LibAppStorage__AccountMustBeUninitialized", + "type": "error" + }, + { + "inputs": [], + "name": "LibAppStorage__SignerAlreadyUninitialized", + "type": "error" + }, + { + "inputs": [], + "name": "LibAppStorage__SignerMustBeUninitialized", + "type": "error" + }, + { + "inputs": [], + "name": "Secp256r1VerificationFacet__InvalidSignerLength", + "type": "error" + }, + { + "inputs": [], + "name": "VerificationFacet__InitializationFailure", + "type": "error" + }, + { + "inputs": [], + "name": "VerificationFacet__InvalidFacetMapping", + "type": "error" + }, + { + "inputs": [], + "name": "VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet", + "type": "error" + }, + { + "inputs": [], + "name": "VerificationFacet__ValidateOwnerSignatureSelectorNotSet", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "SignerInitialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "SignerUninitialized", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_publicKey", + "type": "bytes" + } + ], + "name": "initializeSigner", + "outputs": [ + { + "internalType": "uint256", + "name": "initSuccess", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_publicKey", + "type": "bytes" + } + ], + "name": "isValidKeyType", + "outputs": [ + { + "internalType": "bool", + "name": "isValid", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_hash", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "_signature", + "type": "bytes" + } + ], + "name": "isValidSignature", + "outputs": [ + { + "internalType": "bytes4", + "name": "magicValue", + "type": "bytes4" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "bytes", + "name": "signer", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "self", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "uninitializeSigner", + "outputs": [ + { + "internalType": "uint256", + "name": "uninitSuccess", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "initCode", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "callGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "verificationGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "preVerificationGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxFeePerGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPriorityFeePerGas", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "paymasterAndData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "internalType": "struct UserOperation", + "name": "userOp", + "type": "tuple" + }, + { + "internalType": "bytes32", + "name": "userOpHash", + "type": "bytes32" + } + ], + "name": "validateOwnerSignature", + "outputs": [ + { + "internalType": "uint256", + "name": "validationData", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "validateOwnerSignatureSelector", + "outputs": [ + { + "internalType": "bytes4", + "name": "ownerSignatureValidatorSelector", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "initCode", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "callGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "verificationGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "preVerificationGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxFeePerGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPriorityFeePerGas", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "paymasterAndData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "internalType": "struct UserOperation", + "name": "userOp", + "type": "tuple" + }, + { + "internalType": "bytes32", + "name": "userOpHash", + "type": "bytes32" + }, + { + "internalType": "uint256[2]", + "name": "q", + "type": "uint256[2]" + } + ], + "name": "validateSignature", + "outputs": [ + { + "internalType": "uint256", + "name": "isValid", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0xdeb978652c068d1e0e11c050b83ace297c8121e60db04e3610412fdc0eb3b723", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": "0x0000000000000000000000000000000000000000", + "transactionIndex": 0, + "gasUsed": "1809741", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x8f4353d2a4ebbdc960f012dccb8245014ff37985ec573f4ebac57a557b87a35f", + "transactionHash": "0xdeb978652c068d1e0e11c050b83ace297c8121e60db04e3610412fdc0eb3b723", + "logs": [], + "blockNumber": 72701530, + "cumulativeGasUsed": "1809741", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "ad34345aa73d96f52b3e14df983b6b29", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"LibAppStorage__AccountMustBeUninitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LibAppStorage__SignerAlreadyUninitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LibAppStorage__SignerMustBeUninitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Secp256r1VerificationFacet__InvalidSignerLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerificationFacet__InitializationFailure\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerificationFacet__InvalidFacetMapping\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerificationFacet__ValidateOwnerSignatureSelectorNotSet\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"SignerInitialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"SignerUninitialized\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_publicKey\",\"type\":\"bytes\"}],\"name\":\"initializeSigner\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"initSuccess\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_publicKey\",\"type\":\"bytes\"}],\"name\":\"isValidKeyType\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isValid\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_hash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"_signature\",\"type\":\"bytes\"}],\"name\":\"isValidSignature\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"magicValue\",\"type\":\"bytes4\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"signer\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"self\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"uninitializeSigner\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"uninitSuccess\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"userOp\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"}],\"name\":\"validateOwnerSignature\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"validationData\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"validateOwnerSignatureSelector\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"ownerSignatureValidatorSelector\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"userOp\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256[2]\",\"name\":\"q\",\"type\":\"uint256[2]\"}],\"name\":\"validateSignature\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"isValid\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Ruslan Serebriakov (@rsrbk)David Yongjun Kim (@Powerstream3604)\",\"details\":\"Primarily used to verify user ops signed with passkeys\",\"kind\":\"dev\",\"methods\":{\"initializeSigner(bytes)\":{\"details\":\"This method checks if the signer has already been initialized. If already initialized, it reverts. It checks if the public key is in the light format and initializes signer storage in k1 storage.\",\"params\":{\"_publicKey\":\"Bytes of owner public key\"},\"returns\":{\"initSuccess\":\"Uint value representing the success of init operation\"}},\"isValidKeyType(bytes)\":{\"details\":\"For this Secp256k1Verification Facet, the public key should in an uncompressed public key format\",\"params\":{\"_publicKey\":\"Bytes of public key for format check\"},\"returns\":{\"isValid\":\"Boolean variable representing if the format of public key is valid\"}},\"isValidSignature(bytes32,bytes)\":{\"details\":\"This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\",\"params\":{\"_hash\":\"Hash value the owner signed\",\"_signature\":\"Signature that signed the above hash\"},\"returns\":{\"magicValue\":\"Bytes4 value representing the success/failure of validation\"}},\"owner()\":{\"returns\":{\"signer\":\"Bytes of owner address\"}},\"uninitializeSigner()\":{\"details\":\"This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\",\"returns\":{\"uninitSuccess\":\"Uint value representing the success of uninit operation\"}},\"validateOwnerSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32)\":{\"details\":\"This method validates if the user operation is signed by the owner. It internally calls validateSignature with signer public key.\",\"params\":{\"userOp\":\"UserOperation including all information for execution\",\"userOpHash\":\"Hash of UserOperation given from EntryPoint. This hash is used for signature validation\"},\"returns\":{\"validationData\":\"Uint value representing whether the validation is successful. 0 for success, 1 for failure\"}},\"validateOwnerSignatureSelector()\":{\"returns\":{\"ownerSignatureValidatorSelector\":\"Bytes4 selector of function signature to validate account owner's UserOperation signature\"}},\"validateSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256[2])\":{\"details\":\"This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\",\"params\":{\"q\":\"Public Key of signer who signed the contract, to be validated\",\"userOp\":\"UserOperation including all information for execution\",\"userOpHash\":\"Hash of UserOperation given from EntryPoint. This hash is used for signature validation\"},\"returns\":{\"isValid\":\"Uint value representing whether the validation is successful. 0 for success, 1 for failure\"}}},\"title\":\"Secp256r1 verification facet\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"This constructor ensures that this contract can only be used as singleton for Proxy contracts\"},\"initializeSigner(bytes)\":{\"notice\":\"Initializes the signer in R1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\"},\"isValidKeyType(bytes)\":{\"notice\":\"Validates if the format of public key is valid for this verification facet\"},\"isValidSignature(bytes32,bytes)\":{\"notice\":\"Validates if the signature is valid. Function to be compatible with EIP-1271\"},\"owner()\":{\"notice\":\"Returns the owner of the account\"},\"uninitializeSigner()\":{\"notice\":\"Uninitialize signer in R1 Facet Storage. This can only be called when the account is undergoing signature migration and has already been initialized.\"},\"validateOwnerSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32)\":{\"notice\":\"Validates if the user operation is signed by the owner.\"},\"validateOwnerSignatureSelector()\":{\"notice\":\"Returns the selector of function to validate the signature of UserOperation\"},\"validateSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256[2])\":{\"notice\":\"Validates if the signature of UserOperation is signed by the given signer\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/verification/secp256r1/Secp256r1VerificationFacet.sol\":\"Secp256r1VerificationFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/utils/math/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\\n * checks.\\n *\\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\\n * easily result in undesired exploitation or bugs, since developers usually\\n * assume that overflows raise errors. `SafeCast` restores this intuition by\\n * reverting the transaction when such an operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n *\\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\\n * all math on `uint256` and `int256` and then downcasting.\\n */\\nlibrary SafeCast {\\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 * _Available since v4.7._\\n */\\n function toUint248(uint256 value) internal pure returns (uint248) {\\n require(value <= type(uint248).max, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint240(uint256 value) internal pure returns (uint240) {\\n require(value <= type(uint240).max, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint232(uint256 value) internal pure returns (uint232) {\\n require(value <= type(uint232).max, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint224(uint256 value) internal pure returns (uint224) {\\n require(value <= type(uint224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint216(uint256 value) internal pure returns (uint216) {\\n require(value <= type(uint216).max, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint208(uint256 value) internal pure returns (uint208) {\\n require(value <= type(uint208).max, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint200(uint256 value) internal pure returns (uint200) {\\n require(value <= type(uint200).max, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint192(uint256 value) internal pure returns (uint192) {\\n require(value <= type(uint192).max, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint184(uint256 value) internal pure returns (uint184) {\\n require(value <= type(uint184).max, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint176(uint256 value) internal pure returns (uint176) {\\n require(value <= type(uint176).max, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint168(uint256 value) internal pure returns (uint168) {\\n require(value <= type(uint168).max, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint160(uint256 value) internal pure returns (uint160) {\\n require(value <= type(uint160).max, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint152(uint256 value) internal pure returns (uint152) {\\n require(value <= type(uint152).max, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint144(uint256 value) internal pure returns (uint144) {\\n require(value <= type(uint144).max, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint136(uint256 value) internal pure returns (uint136) {\\n require(value <= type(uint136).max, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint128(uint256 value) internal pure returns (uint128) {\\n require(value <= type(uint128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint120(uint256 value) internal pure returns (uint120) {\\n require(value <= type(uint120).max, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint112(uint256 value) internal pure returns (uint112) {\\n require(value <= type(uint112).max, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint104(uint256 value) internal pure returns (uint104) {\\n require(value <= type(uint104).max, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint96(uint256 value) internal pure returns (uint96) {\\n require(value <= type(uint96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint88(uint256 value) internal pure returns (uint88) {\\n require(value <= type(uint88).max, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint80(uint256 value) internal pure returns (uint80) {\\n require(value <= type(uint80).max, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint72(uint256 value) internal pure returns (uint72) {\\n require(value <= type(uint72).max, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint64(uint256 value) internal pure returns (uint64) {\\n require(value <= type(uint64).max, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint56(uint256 value) internal pure returns (uint56) {\\n require(value <= type(uint56).max, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint48(uint256 value) internal pure returns (uint48) {\\n require(value <= type(uint48).max, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint40(uint256 value) internal pure returns (uint40) {\\n require(value <= type(uint40).max, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint32(uint256 value) internal pure returns (uint32) {\\n require(value <= type(uint32).max, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint24(uint256 value) internal pure returns (uint24) {\\n require(value <= type(uint24).max, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint16(uint256 value) internal pure returns (uint16) {\\n require(value <= type(uint16).max, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint8(uint256 value) internal pure returns (uint8) {\\n require(value <= type(uint8).max, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\n */\\n function toUint256(int256 value) internal pure returns (uint256) {\\n require(value >= 0, \\\"SafeCast: value must be positive\\\");\\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 * _Available since v4.7._\\n */\\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\\n downcasted = int248(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\\n downcasted = int240(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\\n downcasted = int232(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\\n downcasted = int224(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\\n downcasted = int216(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\\n downcasted = int208(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\\n downcasted = int200(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\\n downcasted = int192(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\\n downcasted = int184(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\\n downcasted = int176(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\\n downcasted = int168(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\\n downcasted = int160(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\\n downcasted = int152(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\\n downcasted = int144(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\\n downcasted = int136(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\\n downcasted = int128(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\\n downcasted = int120(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\\n downcasted = int112(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\\n downcasted = int104(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\\n downcasted = int96(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\\n downcasted = int88(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\\n downcasted = int80(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\\n downcasted = int72(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\\n downcasted = int64(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\\n downcasted = int56(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\\n downcasted = int48(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\\n downcasted = int40(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\\n downcasted = int32(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\\n downcasted = int24(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\\n downcasted = int16(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\\n downcasted = int8(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\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 require(value <= uint256(type(int256).max), \\\"SafeCast: value doesn't fit in an int256\\\");\\n return int256(value);\\n }\\n}\\n\",\"keccak256\":\"0x52a8cfb0f5239d11b457dcdd1b326992ef672714ca8da71a157255bddd13f3ad\",\"license\":\"MIT\"},\"contracts/aa-4337/core/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable no-inline-assembly */\\n\\n/**\\n * returned data from validateUserOp.\\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\\n * @param aggregator - address(0) - the account validated the signature by itself.\\n * address(1) - the account failed to validate the signature.\\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\\n * @param validAfter - this UserOp is valid only after this timestamp.\\n * @param validaUntil - this UserOp is valid only up to this timestamp.\\n */\\nstruct ValidationData {\\n address aggregator;\\n uint48 validAfter;\\n uint48 validUntil;\\n}\\n\\n//extract sigFailed, validAfter, validUntil.\\n// also convert zero validUntil to type(uint48).max\\nfunction _parseValidationData(\\n uint validationData\\n) pure returns (ValidationData memory data) {\\n address aggregator = address(uint160(validationData));\\n uint48 validUntil = uint48(validationData >> 160);\\n if (validUntil == 0) {\\n validUntil = type(uint48).max;\\n }\\n uint48 validAfter = uint48(validationData >> (48 + 160));\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n// intersect account and paymaster ranges.\\nfunction _intersectTimeRange(\\n uint256 validationData,\\n uint256 paymasterValidationData\\n) pure returns (ValidationData memory) {\\n ValidationData memory accountValidationData = _parseValidationData(\\n validationData\\n );\\n ValidationData memory pmValidationData = _parseValidationData(\\n paymasterValidationData\\n );\\n address aggregator = accountValidationData.aggregator;\\n if (aggregator == address(0)) {\\n aggregator = pmValidationData.aggregator;\\n }\\n uint48 validAfter = accountValidationData.validAfter;\\n uint48 validUntil = accountValidationData.validUntil;\\n uint48 pmValidAfter = pmValidationData.validAfter;\\n uint48 pmValidUntil = pmValidationData.validUntil;\\n\\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp\\n * @param data - the ValidationData to pack\\n */\\nfunction _packValidationData(\\n ValidationData memory data\\n) pure returns (uint256) {\\n return\\n uint160(data.aggregator) |\\n (uint256(data.validUntil) << 160) |\\n (uint256(data.validAfter) << (160 + 48));\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp, when not using an aggregator\\n * @param sigFailed - true for signature failure, false for success\\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\\n * @param validAfter first timestamp this UserOperation is valid\\n */\\nfunction _packValidationData(\\n bool sigFailed,\\n uint48 validUntil,\\n uint48 validAfter\\n) pure returns (uint256) {\\n return\\n (sigFailed ? 1 : 0) |\\n (uint256(validUntil) << 160) |\\n (uint256(validAfter) << (160 + 48));\\n}\\n\\n/**\\n * keccak function over calldata.\\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\\n */\\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\\n assembly {\\n let mem := mload(0x40)\\n let len := data.length\\n calldatacopy(mem, data.offset, len)\\n ret := keccak256(mem, len)\\n }\\n}\\n\",\"keccak256\":\"0xa79f06cd158ecb8c0da95493a2f348933b8627a63e228b99738bff3aa107942d\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAggregator.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\n/**\\n * Aggregated Signatures validator.\\n */\\ninterface IAggregator {\\n /**\\n * validate aggregated signature.\\n * revert if the aggregated signature does not match the given list of operations.\\n */\\n function validateSignatures(\\n UserOperation[] calldata userOps,\\n bytes calldata signature\\n ) external view;\\n\\n /**\\n * validate signature of a single userOp\\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\\n * @param userOp the userOperation received from the user.\\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\\n * (usually empty, unless account and aggregator support some kind of \\\"multisig\\\"\\n */\\n function validateUserOpSignature(\\n UserOperation calldata userOp\\n ) external view returns (bytes memory sigForUserOp);\\n\\n /**\\n * aggregate multiple signatures into a single value.\\n * This method is called off-chain to calculate the signature to pass with handleOps()\\n * bundler MAY use optimized custom code perform this aggregation\\n * @param userOps array of UserOperations to collect the signatures from.\\n * @return aggregatedSignature the aggregated signature\\n */\\n function aggregateSignatures(\\n UserOperation[] calldata userOps\\n ) external view returns (bytes memory aggregatedSignature);\\n}\\n\",\"keccak256\":\"0xdfdcd80568f037716674619b31be630fcd8316262f05a815b41d1e81782c966a\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IEntryPoint.sol\":{\"content\":\"/**\\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\\n ** Only one instance required on each chain.\\n **/\\n// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-inline-assembly */\\n/* solhint-disable reason-string */\\n\\nimport \\\"./UserOperation.sol\\\";\\nimport \\\"./IStakeManager.sol\\\";\\nimport \\\"./IAggregator.sol\\\";\\nimport \\\"./INonceManager.sol\\\";\\n\\ninterface IEntryPoint is IStakeManager, INonceManager {\\n /***\\n * An event emitted after each successful request\\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\\n * @param sender - the account that generates this request.\\n * @param paymaster - if non-null, the paymaster that pays for this request.\\n * @param nonce - the nonce value from the request.\\n * @param success - true if the sender transaction succeeded, false if reverted.\\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\\n */\\n event UserOperationEvent(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address indexed paymaster,\\n uint256 nonce,\\n bool success,\\n uint256 actualGasCost,\\n uint256 actualGasUsed\\n );\\n\\n /**\\n * account \\\"sender\\\" was deployed.\\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\\n * @param sender the account that is deployed\\n * @param factory the factory used to deploy this account (in the initCode)\\n * @param paymaster the paymaster used by this UserOp\\n */\\n event AccountDeployed(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address factory,\\n address paymaster\\n );\\n\\n /**\\n * An event emitted if the UserOperation \\\"callData\\\" reverted with non-zero length\\n * @param userOpHash the request unique identifier.\\n * @param sender the sender of this request\\n * @param nonce the nonce used in the request\\n * @param revertReason - the return bytes from the (reverted) call to \\\"callData\\\".\\n */\\n event UserOperationRevertReason(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n uint256 nonce,\\n bytes revertReason\\n );\\n\\n /**\\n * an event emitted by handleOps(), before starting the execution loop.\\n * any event emitted before this event, is part of the validation.\\n */\\n event BeforeExecution();\\n\\n /**\\n * signature aggregator used by the following UserOperationEvents within this bundle.\\n */\\n event SignatureAggregatorChanged(address indexed aggregator);\\n\\n /**\\n * a custom revert error of handleOps, to identify the offending op.\\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\\n * @param reason - revert reason\\n * The string starts with a unique code \\\"AAmn\\\", where \\\"m\\\" is \\\"1\\\" for factory, \\\"2\\\" for account and \\\"3\\\" for paymaster issues,\\n * so a failure can be attributed to the correct entity.\\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\\n */\\n error FailedOp(uint256 opIndex, string reason);\\n\\n /**\\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\\n */\\n error SignatureValidationFailed(address aggregator);\\n\\n /**\\n * Successful result from simulateValidation.\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n */\\n error ValidationResult(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo\\n );\\n\\n /**\\n * Successful result from simulateValidation, if the account returns a signature aggregator\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\\n * bundler MUST use it to verify the signature, or reject the UserOperation\\n */\\n error ValidationResultWithAggregation(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo,\\n AggregatorStakeInfo aggregatorInfo\\n );\\n\\n /**\\n * return value of getSenderAddress\\n */\\n error SenderAddressResult(address sender);\\n\\n /**\\n * return value of simulateHandleOp\\n */\\n error ExecutionResult(\\n uint256 preOpGas,\\n uint256 paid,\\n uint48 validAfter,\\n uint48 validUntil,\\n bool targetSuccess,\\n bytes targetResult\\n );\\n\\n //UserOps handled, per aggregator\\n struct UserOpsPerAggregator {\\n UserOperation[] userOps;\\n // aggregator address\\n IAggregator aggregator;\\n // aggregated signature\\n bytes signature;\\n }\\n\\n /**\\n * Execute a batch of UserOperation.\\n * no signature aggregator is used.\\n * if any account requires an aggregator (that is, it returned an aggregator when\\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\\n * @param ops the operations to execute\\n * @param beneficiary the address to receive the fees\\n */\\n function handleOps(\\n UserOperation[] calldata ops,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * Execute a batch of UserOperation with Aggregators\\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\\n * @param beneficiary the address to receive the fees\\n */\\n function handleAggregatedOps(\\n UserOpsPerAggregator[] calldata opsPerAggregator,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * generate a request Id - unique identifier for this request.\\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\\n */\\n function getUserOpHash(\\n UserOperation calldata userOp\\n ) external view returns (bytes32);\\n\\n /**\\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\\n * @param userOp the user operation to validate.\\n */\\n function simulateValidation(UserOperation calldata userOp) external;\\n\\n /**\\n * gas and return values during simulation\\n * @param preOpGas the gas used for validation (including preValidationGas)\\n * @param prefund the required prefund for this operation\\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\\n */\\n struct ReturnInfo {\\n uint256 preOpGas;\\n uint256 prefund;\\n bool sigFailed;\\n uint48 validAfter;\\n uint48 validUntil;\\n bytes paymasterContext;\\n }\\n\\n /**\\n * returned aggregated signature info.\\n * the aggregator returned by the account, and its current stake.\\n */\\n struct AggregatorStakeInfo {\\n address aggregator;\\n StakeInfo stakeInfo;\\n }\\n\\n /**\\n * Get counterfactual sender address.\\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\\n * this method always revert, and returns the address in SenderAddressResult error\\n * @param initCode the constructor code to be passed into the UserOperation.\\n */\\n function getSenderAddress(bytes memory initCode) external;\\n\\n /**\\n * simulate full execution of a UserOperation (including both validation and target execution)\\n * this method will always revert with \\\"ExecutionResult\\\".\\n * it performs full validation of the UserOperation, but ignores signature error.\\n * an optional target address is called after the userop succeeds, and its value is returned\\n * (before the entire call is reverted)\\n * Note that in order to collect the the success/failure of the target call, it must be executed\\n * with trace enabled to track the emitted events.\\n * @param op the UserOperation to simulate\\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\\n * are set to the return from that call.\\n * @param targetCallData callData to pass to target address\\n */\\n function simulateHandleOp(\\n UserOperation calldata op,\\n address target,\\n bytes calldata targetCallData\\n ) external;\\n}\\n\",\"keccak256\":\"0x9ccb1b188eda8bbf5f6c2d01bd83c3d8b2b04fcf745283051d31fe96d1d8e40f\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/INonceManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\ninterface INonceManager {\\n /**\\n * Return the next nonce for this sender.\\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\\n * But UserOp with different keys can come with arbitrary order.\\n *\\n * @param sender the account address\\n * @param key the high 192 bit of the nonce\\n * @return nonce a full nonce to pass for next UserOp with this sender.\\n */\\n function getNonce(\\n address sender,\\n uint192 key\\n ) external view returns (uint256 nonce);\\n\\n /**\\n * Manually increment the nonce of the sender.\\n * This method is exposed just for completeness..\\n * Account does NOT need to call it, neither during validation, nor elsewhere,\\n * as the EntryPoint will update the nonce regardless.\\n * Possible use-case is call it with various keys to \\\"initialize\\\" their nonces to one, so that future\\n * UserOperations will not pay extra for the first transaction with a given key.\\n */\\n function incrementNonce(uint192 key) external;\\n}\\n\",\"keccak256\":\"0xce478ad0fa0d18a3b785ac854623029e7ab463d05873dfaa365abfa1bf100912\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IStakeManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8.12;\\n\\n/**\\n * manage deposits and stakes.\\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\\n * stake is value locked for at least \\\"unstakeDelay\\\" by the staked entity.\\n */\\ninterface IStakeManager {\\n event Deposited(address indexed account, uint256 totalDeposit);\\n\\n event Withdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /// Emitted when stake or unstake delay are modified\\n event StakeLocked(\\n address indexed account,\\n uint256 totalStaked,\\n uint256 unstakeDelaySec\\n );\\n\\n /// Emitted once a stake is scheduled for withdrawal\\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\\n\\n event StakeWithdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /**\\n * @param deposit the entity's deposit\\n * @param staked true if this entity is staked.\\n * @param stake actual amount of ether staked for this entity.\\n * @param unstakeDelaySec minimum delay to withdraw the stake.\\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\\n * and the rest fit into a 2nd cell.\\n * 112 bit allows for 10^15 eth\\n * 48 bit for full timestamp\\n * 32 bit allows 150 years for unstake delay\\n */\\n struct DepositInfo {\\n uint112 deposit;\\n bool staked;\\n uint112 stake;\\n uint32 unstakeDelaySec;\\n uint48 withdrawTime;\\n }\\n\\n //API struct used by getStakeInfo and simulateValidation\\n struct StakeInfo {\\n uint256 stake;\\n uint256 unstakeDelaySec;\\n }\\n\\n /// @return info - full deposit information of given account\\n function getDepositInfo(\\n address account\\n ) external view returns (DepositInfo memory info);\\n\\n /// @return the deposit (for gas payment) of the account\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * add to the deposit of the given account\\n */\\n function depositTo(address account) external payable;\\n\\n /**\\n * add to the account's stake - amount and delay\\n * any pending unstake is first cancelled.\\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\\n */\\n function addStake(uint32 _unstakeDelaySec) external payable;\\n\\n /**\\n * attempt to unlock the stake.\\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\\n */\\n function unlockStake() external;\\n\\n /**\\n * withdraw from the (unlocked) stake.\\n * must first call unlockStake and wait for the unstakeDelay to pass\\n * @param withdrawAddress the address to send withdrawn value.\\n */\\n function withdrawStake(address payable withdrawAddress) external;\\n\\n /**\\n * withdraw from the deposit.\\n * @param withdrawAddress the address to send withdrawn value.\\n * @param withdrawAmount the amount to withdraw.\\n */\\n function withdrawTo(\\n address payable withdrawAddress,\\n uint256 withdrawAmount\\n ) external;\\n}\\n\",\"keccak256\":\"0xadcea606c9b7aafe6645441f2154a60f271330b0eee5292a632aa71c1672d546\",\"license\":\"GPL-3.0-only\"},\"contracts/aa-4337/interfaces/UserOperation.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable no-inline-assembly */\\n\\nimport {calldataKeccak} from \\\"../core/Helpers.sol\\\";\\n\\n/**\\n * User Operation struct\\n * @param sender the sender account of this request.\\n * @param nonce unique value the sender uses to verify it is not a replay.\\n * @param initCode if set, the account contract will be created by this constructor/\\n * @param callData the method call to execute on this account.\\n * @param callGasLimit the gas limit passed to the callData method call.\\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\\n * @param maxFeePerGas same as EIP-1559 gas parameter.\\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\\n */\\nstruct UserOperation {\\n address sender;\\n uint256 nonce;\\n bytes initCode;\\n bytes callData;\\n uint256 callGasLimit;\\n uint256 verificationGasLimit;\\n uint256 preVerificationGas;\\n uint256 maxFeePerGas;\\n uint256 maxPriorityFeePerGas;\\n bytes paymasterAndData;\\n bytes signature;\\n}\\n\\n/**\\n * Utility functions helpful when working with UserOperation structs.\\n */\\nlibrary UserOperationLib {\\n function getSender(\\n UserOperation calldata userOp\\n ) internal pure returns (address) {\\n address data;\\n //read sender from userOp, which is first userOp member (saves 800 gas...)\\n assembly {\\n data := calldataload(userOp)\\n }\\n return address(uint160(data));\\n }\\n\\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\\n // pay above what he signed for.\\n function gasPrice(\\n UserOperation calldata userOp\\n ) internal view returns (uint256) {\\n unchecked {\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n if (maxFeePerGas == maxPriorityFeePerGas) {\\n //legacy mode (for networks that don't support basefee opcode)\\n return maxFeePerGas;\\n }\\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\\n }\\n }\\n\\n function pack(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes memory ret) {\\n address sender = getSender(userOp);\\n uint256 nonce = userOp.nonce;\\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\\n bytes32 hashCallData = calldataKeccak(userOp.callData);\\n uint256 callGasLimit = userOp.callGasLimit;\\n uint256 verificationGasLimit = userOp.verificationGasLimit;\\n uint256 preVerificationGas = userOp.preVerificationGas;\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\\n\\n return\\n abi.encode(\\n sender,\\n nonce,\\n hashInitCode,\\n hashCallData,\\n callGasLimit,\\n verificationGasLimit,\\n preVerificationGas,\\n maxFeePerGas,\\n maxPriorityFeePerGas,\\n hashPaymasterAndData\\n );\\n }\\n\\n function hash(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes32) {\\n return keccak256(pack(userOp));\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n}\\n\",\"keccak256\":\"0x2429f5cc546bdee08c7e63858d0dda8491eaa3ab5194df884dc948c1154d2834\",\"license\":\"GPL-3.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/facets/interfaces/IVerificationFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {UserOperation} from \\\"../../aa-4337/interfaces/UserOperation.sol\\\";\\n\\n/**\\n * @title Verification Facet Interface\\n * @dev Implements logic for user ops signature verification\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\ninterface IVerificationFacet {\\n event SignerInitialized(bytes);\\n event SignerUninitialized();\\n\\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\\n error VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\\n error VerificationFacet__InitializationFailure();\\n error VerificationFacet__InvalidFacetMapping();\\n\\n function initializeSigner(bytes memory) external returns (uint256);\\n\\n function uninitializeSigner() external returns (uint256);\\n\\n function validateOwnerSignatureSelector() external view returns (bytes4);\\n\\n function owner() external view returns (bytes memory);\\n\\n function isValidKeyType(bytes calldata) external view returns (bool);\\n\\n function validateOwnerSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x72bc370a1d1b5a6d6bde67f5026733fd8f6ba434bb90e73b0bd8627fb1579928\",\"license\":\"Apache-2.0\"},\"contracts/facets/verification/secp256r1/Secp256r1VerificationFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {UserOperation} from \\\"../../../aa-4337/interfaces/UserOperation.sol\\\";\\nimport {LibAppStorage} from \\\"../../../libraries/LibAppStorage.sol\\\";\\nimport {LibLoupe} from \\\"../../../libraries/LibLoupe.sol\\\";\\nimport {LibFacetStorage, Secp256r1VerificationStorage} from \\\"../../../libraries/LibFacetStorage.sol\\\";\\nimport {Base64} from \\\"./utils/Base64.sol\\\";\\nimport {LibSecp256r1} from \\\"./utils/LibSecp256r1.sol\\\";\\nimport {IERC1271} from \\\"../../../interfaces/ERC/IERC1271.sol\\\";\\nimport {IVerificationFacet} from \\\"../../interfaces/IVerificationFacet.sol\\\";\\n\\n/**\\n * @title Secp256r1 verification facet\\n * @dev Primarily used to verify user ops signed with passkeys\\n * @author Ruslan Serebriakov (@rsrbk)\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract Secp256r1VerificationFacet is IVerificationFacet, IERC1271 {\\n error Secp256r1VerificationFacet__InvalidSignerLength();\\n address public immutable self;\\n\\n /**\\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\\n */\\n constructor() {\\n LibAppStorage.enforceSignerInitialize();\\n self = address(this);\\n }\\n\\n /**\\n * @notice Initializes the signer in R1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\\n * @param _publicKey Bytes of owner public key\\n * @return initSuccess Uint value representing the success of init operation\\n */\\n function initializeSigner(\\n bytes calldata _publicKey\\n ) public override returns (uint256 initSuccess) {\\n LibAppStorage.enforceSignerInitialize();\\n\\n if (!isValidKeyType(_publicKey))\\n revert Secp256r1VerificationFacet__InvalidSignerLength();\\n\\n bytes memory publicKeyCoordinates = _publicKey[1:];\\n uint256[2] memory q;\\n assembly {\\n // Copy the bytes from the input data into the uint256 array\\n mstore(q, mload(add(publicKeyCoordinates, 32)))\\n mstore(add(q, 32), mload(add(publicKeyCoordinates, 64)))\\n }\\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\\n .r1Storage();\\n r1Storage.q = q;\\n\\n bytes4 validateSelector = validateOwnerSignatureSelector();\\n\\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\\n if (LibLoupe.facetAddress(validateSelector) != self)\\n revert VerificationFacet__InvalidFacetMapping();\\n\\n // initialize verification function selector\\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\\n\\n initSuccess = 1;\\n\\n emit SignerInitialized(_publicKey);\\n }\\n\\n /**\\n * @notice Uninitialize signer in R1 Facet Storage. This can only be called when the account is undergoing signature migration\\n * and has already been initialized.\\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\\n * @return uninitSuccess Uint value representing the success of uninit operation\\n */\\n function uninitializeSigner()\\n external\\n override\\n returns (uint256 uninitSuccess)\\n {\\n LibAppStorage.enforceSignerMigration();\\n LibAppStorage.setSignerUninitialized();\\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\\n .r1Storage();\\n r1Storage.q = [0, 0];\\n\\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\\n\\n uninitSuccess = 1;\\n\\n emit SignerUninitialized();\\n }\\n\\n /**\\n * @notice Validates if the user operation is signed by the owner.\\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\\n * signer public key.\\n * @param userOp UserOperation including all information for execution\\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\\n */\\n function validateOwnerSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) public view override returns (uint256 validationData) {\\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\\n .r1Storage();\\n validationData = validateSignature(userOp, userOpHash, r1Storage.q);\\n }\\n\\n /**\\n * @notice Validates if the signature of UserOperation is signed by the given signer\\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\\n * @param userOp UserOperation including all information for execution\\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\\n * @param q Public Key of signer who signed the contract, to be validated\\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\\n */\\n function validateSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n uint256[2] memory q\\n ) public view returns (uint256 isValid) {\\n isValid = (_validateSignature(q, userOpHash, userOp.signature)) ? 0 : 1;\\n }\\n\\n /**\\n * @notice Returns the selector of function to validate the signature of UserOperation\\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\\n */\\n function validateOwnerSignatureSelector()\\n public\\n pure\\n override\\n returns (bytes4 ownerSignatureValidatorSelector)\\n {\\n return this.validateOwnerSignature.selector; // validateOwnerSignature(UserOperation calldata userOp,bytes32 userOpHash)\\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\\n }\\n\\n /**\\n * @notice Returns the owner of the account\\n * @return signer Bytes of owner address\\n */\\n function owner() public view override returns (bytes memory signer) {\\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\\n .r1Storage();\\n signer = abi.encodePacked(r1Storage.q);\\n }\\n\\n /**\\n * @notice Validates if the format of public key is valid for this verification facet\\n * @dev For this Secp256k1Verification Facet, the public key should in an uncompressed public key format\\n * @param _publicKey Bytes of public key for format check\\n * @return isValid Boolean variable representing if the format of public key is valid\\n */\\n function isValidKeyType(\\n bytes memory _publicKey\\n ) public pure override returns (bool isValid) {\\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\\n }\\n\\n /**\\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\\n * @param _hash Hash value the owner signed\\n * @param _signature Signature that signed the above hash\\n * @return magicValue Bytes4 value representing the success/failure of validation\\n */\\n function isValidSignature(\\n bytes32 _hash,\\n bytes memory _signature\\n ) public view override returns (bytes4 magicValue) {\\n magicValue = _validateSignature(\\n LibFacetStorage.r1Storage().q,\\n _hash,\\n _signature\\n )\\n ? this.isValidSignature.selector\\n : bytes4(0xffffffff);\\n }\\n\\n function _validateSignature(\\n uint256[2] memory q,\\n bytes32 _hash,\\n bytes memory _signature\\n ) internal view returns (bool) {\\n (\\n uint256 rValue,\\n uint256 sValue,\\n bytes memory authenticatorData,\\n string memory clientDataJSONPre,\\n string memory clientDataJSONPost\\n ) = abi.decode(_signature, (uint256, uint256, bytes, string, string));\\n bytes32 clientHash;\\n {\\n string memory opHashBase64 = Base64.encode(bytes.concat(_hash));\\n string memory clientDataJSON = string.concat(\\n clientDataJSONPre,\\n opHashBase64,\\n clientDataJSONPost\\n );\\n clientHash = sha256(bytes(clientDataJSON));\\n }\\n bytes32 sigHash = sha256(bytes.concat(authenticatorData, clientHash));\\n return LibSecp256r1.Verify(q, rValue, sValue, uint256(sigHash));\\n }\\n}\\n\",\"keccak256\":\"0xdb3bae77323eef4e16ef5a5342f548527c9e82b44e8e9dab90906dc2c00082ff\",\"license\":\"Apache-2.0\"},\"contracts/facets/verification/secp256r1/utils/Base64.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @dev Provides a set of functions to operate with Base64 strings.\\n * modified for base64url https://datatracker.ietf.org/doc/html/rfc4648#section-5\\n * _Available since v4.5._\\n */\\nlibrary Base64 {\\n /**\\n * @dev Base64 Encoding/Decoding Table\\n */\\n string internal constant _TABLE =\\n \\\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_\\\";\\n\\n /**\\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\\n */\\n function encode(bytes memory data) internal pure returns (string memory) {\\n /**\\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\\n */\\n if (data.length == 0) return \\\"\\\";\\n\\n // Loads the table into memory\\n string memory table = _TABLE;\\n\\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\\n // and split into 4 numbers of 6 bits.\\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\\n // - `data.length + 2` -> Round up\\n // - `/ 3` -> Number of 3-bytes chunks\\n // - `4 *` -> 4 characters for each chunk\\n uint256 newlength = (data.length * 8) / 6;\\n if (data.length % 6 > 0) {\\n newlength++;\\n }\\n string memory result = new string(newlength);\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n // Prepare the lookup table (skip the first \\\"length\\\" byte)\\n let tablePtr := add(table, 1)\\n\\n // Prepare result pointer, jump over length\\n let resultPtr := add(result, 32)\\n\\n // Run over the input, 3 bytes at a time\\n for {\\n let dataPtr := data\\n let endPtr := add(data, mload(data))\\n } lt(dataPtr, endPtr) {\\n\\n } {\\n // Advance 3 bytes\\n dataPtr := add(dataPtr, 3)\\n let input := mload(dataPtr)\\n\\n // To write each character, shift the 3 bytes (18 bits) chunk\\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\\n // and apply logical AND with 0x3F which is the number of\\n // the previous character in the ASCII table prior to the Base64 Table\\n // The result is then added to the table to get the character to write,\\n // and finally write it in the result pointer but with a left shift\\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\\n\\n mstore8(\\n resultPtr,\\n mload(add(tablePtr, and(shr(18, input), 0x3F)))\\n )\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(\\n resultPtr,\\n mload(add(tablePtr, and(shr(12, input), 0x3F)))\\n )\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(\\n resultPtr,\\n mload(add(tablePtr, and(shr(6, input), 0x3F)))\\n )\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n }\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0xbf0afa21e5a128f260c1a8d4333dc0b0e8755a50d37dfa9b5d362d36ef9cdc14\",\"license\":\"Apache-2.0\"},\"contracts/facets/verification/secp256r1/utils/LibSecp256r1.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n// Heavily inspired from\\n// https://github.com/maxrobot/elliptic-solidity/blob/master/contracts/Secp256r1.sol\\n// https://github.com/tdrerup/elliptic-curve-solidity/blob/master/contracts/curves/EllipticCurve.sol\\n// modified to use precompile 0x05 modexp\\n// and modified jacobian double\\n// optimisations to avoid to an from from affine and jacobian coordinates\\n\\n// Additional Elliptic curve Public key / Signature validation added by\\n// David Yonjun Kim (@Powerstream3604)\\n\\nstruct JPoint {\\n uint256 x;\\n uint256 y;\\n uint256 z;\\n}\\n\\nlibrary LibSecp256r1 {\\n uint256 constant gx =\\n 0x6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296;\\n uint256 constant gy =\\n 0x4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5;\\n uint256 public constant pp =\\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF;\\n\\n uint256 public constant nn =\\n 0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551;\\n uint256 constant a =\\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC;\\n uint256 constant b =\\n 0x5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B;\\n uint256 constant MOST_SIGNIFICANT =\\n 0xc000000000000000000000000000000000000000000000000000000000000000;\\n\\n /*\\n * Verify\\n * @description - verifies that a public key has signed a given message\\n * @param Q - public key coordinates X & Y\\n * @param R - signature half R\\n * @param S - signature half S\\n * @param input - hashed message\\n */\\n function Verify(\\n uint256[2] memory q,\\n uint r,\\n uint s,\\n uint e\\n ) internal view returns (bool) {\\n if (q[0] > pp - 1 || q[1] > pp - 1) {\\n return false;\\n }\\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\\n return false;\\n }\\n if (\\n mulmod(q[1], q[1], pp) !=\\n addmod(\\n addmod(\\n mulmod(q[0], mulmod(q[0], q[0], pp), pp),\\n mulmod(a, q[0], pp),\\n pp\\n ),\\n b,\\n pp\\n )\\n ) {\\n return false;\\n }\\n\\n JPoint[16] memory points = _preComputeJacobianPoints(q);\\n return VerifyWithPrecompute(points, r, s, e);\\n }\\n\\n function VerifyWithPrecompute(\\n JPoint[16] memory points,\\n uint r,\\n uint s,\\n uint e\\n ) internal view returns (bool) {\\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\\n return false;\\n }\\n\\n uint w = _primemod(s, nn);\\n\\n uint u1 = mulmod(e, w, nn);\\n uint u2 = mulmod(r, w, nn);\\n\\n uint x;\\n uint y;\\n\\n (x, y) = ShamirMultJacobian(points, u1, u2);\\n return (x == r);\\n }\\n\\n /*\\n * Strauss Shamir trick for EC multiplication\\n * https://stackoverflow.com/questions/50993471/ec-scalar-multiplication-with-strauss-shamir-method\\n * we optimise on this a bit to do with 2 bits at a time rather than a single bit\\n * the individual points for a single pass are precomputed\\n * overall this reduces the number of additions while keeping the same number of doublings\\n */\\n function ShamirMultJacobian(\\n JPoint[16] memory points,\\n uint u1,\\n uint u2\\n ) internal view returns (uint, uint) {\\n uint x = 0;\\n uint y = 0;\\n uint z = 0;\\n uint bits = 128;\\n uint index = 0;\\n\\n while (bits > 0) {\\n if (z > 0) {\\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\\n }\\n index =\\n ((u1 & MOST_SIGNIFICANT) >> 252) |\\n ((u2 & MOST_SIGNIFICANT) >> 254);\\n if (index > 0) {\\n (x, y, z) = _jAdd(\\n x,\\n y,\\n z,\\n points[index].x,\\n points[index].y,\\n points[index].z\\n );\\n }\\n u1 <<= 2;\\n u2 <<= 2;\\n bits--;\\n }\\n (x, y) = _affineFromJacobian(x, y, z);\\n return (x, y);\\n }\\n\\n function _preComputeJacobianPoints(\\n uint256[2] memory q\\n ) internal pure returns (JPoint[16] memory points) {\\n points[0] = JPoint(0, 0, 0);\\n points[1] = JPoint(q[0], q[1], 1); // u2\\n points[2] = _jPointDouble(points[1]);\\n points[3] = _jPointAdd(points[1], points[2]);\\n\\n points[4] = JPoint(gx, gy, 1); // u1Points[1]\\n points[5] = _jPointAdd(points[4], points[1]);\\n points[6] = _jPointAdd(points[4], points[2]);\\n points[7] = _jPointAdd(points[4], points[3]);\\n\\n points[8] = _jPointDouble(points[4]); // u1Points[2]\\n points[9] = _jPointAdd(points[8], points[1]);\\n points[10] = _jPointAdd(points[8], points[2]);\\n points[11] = _jPointAdd(points[8], points[3]);\\n\\n points[12] = _jPointAdd(points[4], points[8]); // u1Points[3]\\n points[13] = _jPointAdd(points[12], points[1]);\\n points[14] = _jPointAdd(points[12], points[2]);\\n points[15] = _jPointAdd(points[12], points[3]);\\n }\\n\\n function _jPointAdd(\\n JPoint memory p1,\\n JPoint memory p2\\n ) internal pure returns (JPoint memory) {\\n uint x;\\n uint y;\\n uint z;\\n (x, y, z) = _jAdd(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z);\\n return JPoint(x, y, z);\\n }\\n\\n function _jPointDouble(\\n JPoint memory p\\n ) internal pure returns (JPoint memory) {\\n uint x;\\n uint y;\\n uint z;\\n (x, y, z) = _modifiedJacobianDouble(p.x, p.y, p.z);\\n return JPoint(x, y, z);\\n }\\n\\n /* _affineFromJacobian\\n * @desription returns affine coordinates from a jacobian input follows\\n * golang elliptic/crypto library\\n */\\n function _affineFromJacobian(\\n uint x,\\n uint y,\\n uint z\\n ) internal view returns (uint ax, uint ay) {\\n if (z == 0) {\\n return (0, 0);\\n }\\n\\n uint zinv = _primemod(z, pp);\\n uint zinvsq = mulmod(zinv, zinv, pp);\\n\\n ax = mulmod(x, zinvsq, pp);\\n ay = mulmod(y, mulmod(zinvsq, zinv, pp), pp);\\n }\\n\\n /*\\n * _jAdd\\n * @description performs Jacobian addition as defined below:\\n * http://www.hyperelliptic.org/EFD/g1p/data/shortw/jacobian/addition/add-2007-bl\\n */\\n function _jAdd(\\n uint p1,\\n uint p2,\\n uint p3,\\n uint q1,\\n uint q2,\\n uint q3\\n ) internal pure returns (uint r1, uint r2, uint r3) {\\n if (p3 == 0) {\\n r1 = q1;\\n r2 = q2;\\n r3 = q3;\\n\\n return (r1, r2, r3);\\n } else if (q3 == 0) {\\n r1 = p1;\\n r2 = p2;\\n r3 = p3;\\n\\n return (r1, r2, r3);\\n }\\n\\n assembly {\\n let\\n pd\\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\\n let z1z1 := mulmod(p3, p3, pd) // Z1Z1 = Z1^2\\n let z2z2 := mulmod(q3, q3, pd) // Z2Z2 = Z2^2\\n\\n let u1 := mulmod(p1, z2z2, pd) // U1 = X1*Z2Z2\\n let u2 := mulmod(q1, z1z1, pd) // U2 = X2*Z1Z1\\n\\n let s1 := mulmod(p2, mulmod(z2z2, q3, pd), pd) // S1 = Y1*Z2*Z2Z2\\n let s2 := mulmod(q2, mulmod(z1z1, p3, pd), pd) // S2 = Y2*Z1*Z1Z1\\n\\n let p3q3 := addmod(p3, q3, pd)\\n\\n if lt(u2, u1) {\\n u2 := add(pd, u2) // u2 = u2+pd\\n }\\n let h := sub(u2, u1) // H = U2-U1\\n\\n let i := mulmod(0x02, h, pd)\\n i := mulmod(i, i, pd) // I = (2*H)^2\\n\\n let j := mulmod(h, i, pd) // J = H*I\\n if lt(s2, s1) {\\n s2 := add(pd, s2) // u2 = u2+pd\\n }\\n let rr := mulmod(0x02, sub(s2, s1), pd) // r = 2*(S2-S1)\\n r1 := mulmod(rr, rr, pd) // X3 = R^2\\n\\n let v := mulmod(u1, i, pd) // V = U1*I\\n let j2v := addmod(j, mulmod(0x02, v, pd), pd)\\n if lt(r1, j2v) {\\n r1 := add(pd, r1) // X3 = X3+pd\\n }\\n r1 := sub(r1, j2v)\\n\\n // Y3 = r*(V-X3)-2*S1*J\\n let s12j := mulmod(mulmod(0x02, s1, pd), j, pd)\\n\\n if lt(v, r1) {\\n v := add(pd, v)\\n }\\n r2 := mulmod(rr, sub(v, r1), pd)\\n\\n if lt(r2, s12j) {\\n r2 := add(pd, r2)\\n }\\n r2 := sub(r2, s12j)\\n\\n // Z3 = ((Z1+Z2)^2-Z1Z1-Z2Z2)*H\\n z1z1 := addmod(z1z1, z2z2, pd)\\n j2v := mulmod(p3q3, p3q3, pd)\\n if lt(j2v, z1z1) {\\n j2v := add(pd, j2v)\\n }\\n r3 := mulmod(sub(j2v, z1z1), h, pd)\\n }\\n return (r1, r2, r3);\\n }\\n\\n // Point doubling on the modified jacobian coordinates\\n // http://point-at-infinity.org/ecc/Prime_Curve_Modified_Jacobian_Coordinates.html\\n function _modifiedJacobianDouble(\\n uint x,\\n uint y,\\n uint z\\n ) internal pure returns (uint x3, uint y3, uint z3) {\\n if (y == 0) return (0, 0, 0);\\n assembly {\\n let\\n pd\\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\\n let z2 := mulmod(z, z, pd)\\n let az4 := mulmod(\\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC,\\n mulmod(z2, z2, pd),\\n pd\\n )\\n let y2 := mulmod(y, y, pd)\\n let s := mulmod(0x04, mulmod(x, y2, pd), pd)\\n let u := mulmod(0x08, mulmod(y2, y2, pd), pd)\\n let m := addmod(mulmod(0x03, mulmod(x, x, pd), pd), az4, pd)\\n let twos := mulmod(0x02, s, pd)\\n let m2 := mulmod(m, m, pd)\\n if lt(m2, twos) {\\n m2 := add(pd, m2)\\n }\\n x3 := sub(m2, twos)\\n if lt(s, x3) {\\n s := add(pd, s)\\n }\\n y3 := mulmod(m, sub(s, x3), pd)\\n if lt(y3, u) {\\n y3 := add(pd, y3)\\n }\\n y3 := sub(y3, u)\\n z3 := mulmod(0x02, mulmod(y, z, pd), pd)\\n }\\n }\\n\\n // Fermats little theorem https://en.wikipedia.org/wiki/Fermat%27s_little_theorem\\n // a^(p-1) = 1 mod p\\n // a^(-1) \\u2245 a^(p-2) (mod p)\\n // we then use the precompile bigModExp to compute a^(-1)\\n function _primemod(uint value, uint p) internal view returns (uint ret) {\\n ret = modexp(value, p - 2, p);\\n return ret;\\n }\\n\\n // Wrapper for built-in BigNumber_modexp (contract 0x5) as described here. https://github.com/ethereum/EIPs/pull/198\\n function modexp(\\n uint _base,\\n uint _exp,\\n uint _mod\\n ) internal view returns (uint ret) {\\n // bigModExp(_base, _exp, _mod);\\n assembly {\\n if gt(_base, _mod) {\\n _base := mod(_base, _mod)\\n }\\n // Free memory pointer is always stored at 0x40\\n let freemem := mload(0x40)\\n\\n mstore(freemem, 0x20)\\n mstore(add(freemem, 0x20), 0x20)\\n mstore(add(freemem, 0x40), 0x20)\\n\\n mstore(add(freemem, 0x60), _base)\\n mstore(add(freemem, 0x80), _exp)\\n mstore(add(freemem, 0xa0), _mod)\\n\\n let success := staticcall(14000, 0x5, freemem, 0xc0, freemem, 0x20)\\n switch success\\n case 0 {\\n revert(0x0, 0x0)\\n }\\n default {\\n ret := mload(freemem)\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb53714ba63cddb379ba312c1e7f6a423f4d7a7e34fa1364ec8295cd57d544024\",\"license\":\"GPL-3.0\"},\"contracts/infrastructure/interfaces/IFacetRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Registry Interface\\n * @dev Interface for Facet Registry contract to keep track of facets & function selectors addable to user wallets\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IFacetRegistry {\\n struct FacetRegistryConfig {\\n bytes4[] selectors;\\n mapping(bytes4 => FacetInfo) info;\\n }\\n struct FacetInfo {\\n bool exists;\\n uint128 index;\\n }\\n\\n event FacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] facetSelectors\\n );\\n event FacetFunctionSelectorsRemoved(address facet, bytes4[] facetSelectors);\\n\\n error FacetRegistry__FacetSelectorAlreadyRegistered();\\n error FacetRegistry__UnregisteredFacetSelector();\\n\\n function registerFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function removeFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function areFacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external view returns (bool);\\n\\n function isFacetFunctionSelectorRegistered(\\n address facet,\\n bytes4 facetSelector\\n ) external view returns (bool);\\n\\n function getFacetFunctionSelectors(\\n address facet\\n ) external view returns (bytes4[] memory);\\n}\\n\",\"keccak256\":\"0x6e6dd2cab346ef7c31230740ec48d2925e4a9ab24c2f2fb268baaf408dcf02ef\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC1271 {\\n function isValidSignature(\\n bytes32 hash,\\n bytes memory signature\\n ) external view returns (bytes4);\\n}\\n\",\"keccak256\":\"0xcdddb7d5641c9d3f2432dec7fd13fddb9ae1480f25c76c21511e2fa16b8bd422\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibAppStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {SafeCast} from \\\"@openzeppelin/contracts/utils/math/SafeCast.sol\\\";\\nimport {IEntryPoint} from \\\"../aa-4337/interfaces/IEntryPoint.sol\\\";\\nimport {IFacetRegistry} from \\\"../infrastructure/interfaces/IFacetRegistry.sol\\\";\\n\\n/*\\n * @title App Storage\\n * @dev App storage for Barz contract to prevent storage collision\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Lock {\\n uint64 release;\\n bytes4 locker;\\n}\\n\\nstruct InitializersStorage {\\n // NOTE: initialized is a variable to make sure the initialization is only done once.\\n uint8 signerInitialized;\\n uint8 accountInitialized;\\n uint8 restrictionsInitialized;\\n}\\n\\nstruct AppStorage {\\n mapping(uint256 => InitializersStorage) initStorage;\\n uint8 signerMigration;\\n bytes4 validateOwnerSignatureSelector;\\n IEntryPoint entryPoint;\\n IFacetRegistry facetRegistry;\\n mapping(uint256 => Lock) locks;\\n}\\n\\nlibrary LibAppStorage {\\n error LibAppStorage__AccountAlreadyUninitialized();\\n error LibAppStorage__AccountMustBeUninitialized();\\n error LibAppStorage__SignerAlreadyUninitialized();\\n error LibAppStorage__SignerMustBeUninitialized();\\n\\n function appStorage() internal pure returns (AppStorage storage ds) {\\n assembly {\\n ds.slot := 0\\n }\\n }\\n\\n function setSignerUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerAlreadyUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 0;\\n }\\n\\n function getValidateOwnerSignatureSelector()\\n internal\\n view\\n returns (bytes4 selector)\\n {\\n selector = appStorage().validateOwnerSignatureSelector;\\n }\\n\\n function setValidateOwnerSignatureSelector(\\n bytes4 _validateOwnerSignatureSelector\\n ) internal {\\n appStorage()\\n .validateOwnerSignatureSelector = _validateOwnerSignatureSelector;\\n }\\n\\n function enforceSignerInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerMustBeUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 1;\\n }\\n\\n function enforceAccountInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].accountInitialized) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n s.initStorage[0].accountInitialized = 1;\\n }\\n\\n function initiateSignerMigration() internal {\\n appStorage().signerMigration = 1;\\n }\\n\\n function enforceSignerMigration() internal view {\\n if (1 != appStorage().signerMigration) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n }\\n\\n function finalizeSignerMigration() internal {\\n appStorage().signerMigration = 0;\\n }\\n\\n function setLock(uint256 _releaseAfter, bytes4 _locker) internal {\\n appStorage().locks[0] = Lock(SafeCast.toUint64(_releaseAfter), _locker);\\n }\\n\\n function enforceRestrictionsInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__SignerMustBeUninitialized();\\n s.initStorage[0].restrictionsInitialized = 1;\\n }\\n\\n function setRestrictionsUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__AccountAlreadyUninitialized();\\n s.initStorage[0].restrictionsInitialized = 0;\\n }\\n}\\n\\ncontract BarzStorage {\\n AppStorage internal s;\\n modifier onlyWhenUnlocked() {\\n require(\\n uint64(block.timestamp) >= s.locks[0].release,\\n \\\"Account Locked\\\"\\n );\\n _;\\n }\\n modifier onlyWhenLocked() {\\n require(\\n uint64(block.timestamp) < s.locks[0].release,\\n \\\"Account Unlocked\\\"\\n );\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x48524007862a6ce0e07f645950613ce6513ce073c37a109c75019683d42bae27\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\\n bytes4(keccak256(\\\"verifyRestrictions(address,address,uint256,bytes)\\\"));\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // Default Fallback Handler of the barz.\\n IDiamondLoupe defaultFallbackHandler;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function enforceIsSelf() internal view {\\n require(msg.sender == address(this), \\\"LibDiamond: Caller not self\\\");\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n\\n unchecked {\\n facetIndex++;\\n }\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n\\n function restrictionsFacet() internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(\\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2cabdc00de859c3a3170ce3bda5d0e5fd3933d47ce904fd1585f9818b02572f8\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibFacetStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Storage\\n * @dev Storage contract to store each facets variables with diamond storage\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Secp256k1VerificationStorage {\\n address signer;\\n}\\n\\nstruct Secp256r1VerificationStorage {\\n uint256[2] q;\\n}\\n\\nstruct GuardianStorage {\\n mapping(bytes32 => uint256) pending;\\n mapping(uint8 => StorageConfig) configs;\\n}\\n\\nstruct Info {\\n bool exists;\\n uint128 index;\\n}\\n\\nstruct StorageConfig {\\n address[] addresses;\\n mapping(address => Info) info;\\n}\\n\\nstruct RecoveryConfig {\\n bytes recoveryPublicKey;\\n uint64 executeAfter;\\n}\\n\\nstruct ApprovalConfig {\\n bool isApproved;\\n uint64 validUntil;\\n}\\n\\nstruct RecoveryApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isNewOwnerApproved;\\n}\\n\\nstruct RecoveryStorage {\\n mapping(uint8 => RecoveryConfig) recoveryConfigs;\\n mapping(uint8 => RecoveryApprovalConfig) recoveryApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct RestrictionsStorage {\\n address[] restrictions;\\n mapping(address => bool) exists;\\n}\\n\\nstruct SignatureMigrationConfig {\\n bytes migrationPublicKey;\\n address migrationVerificationFacet;\\n bytes4[] migrationSelectors;\\n uint64 migrateAfter;\\n}\\n\\nstruct SignatureMigrationApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isMigrationApproved;\\n}\\n\\nstruct SignatureMigrationStorage {\\n mapping(uint8 => SignatureMigrationConfig) migrationConfigs;\\n mapping(uint8 => SignatureMigrationApprovalConfig) migrationApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct DiamondCutApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isDiamondCutApproved;\\n}\\n\\nstruct DiamondCutStorage {\\n mapping(uint8 => DiamondCutApprovalConfig) diamondCutApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct LockStorage {\\n uint128 nonce;\\n}\\n\\nlibrary LibFacetStorage {\\n bytes32 constant K1_STORAGE_POSITION =\\n keccak256(\\n \\\"v0.trustwallet.diamond.storage.Secp256k1VerificationStorage\\\"\\n );\\n bytes32 constant R1_STORAGE_POSITION =\\n keccak256(\\n \\\"v0.trustwallet.diamond.storage.Secp256r1VerificationStorage\\\"\\n );\\n bytes32 constant GUARDIAN_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.GuardianStorage\\\");\\n bytes32 constant RECOVERY_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.RecoveryStorage\\\");\\n bytes32 constant RESTRICTION_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.RestrictionsStorage\\\");\\n bytes32 constant MIGRATION_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.SignatureMigrationStorage\\\");\\n bytes32 constant DIAMONDCUT_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.DiamondCutStorage\\\");\\n bytes32 constant LOCK_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.LockStorage\\\");\\n\\n function k1Storage()\\n internal\\n pure\\n returns (Secp256k1VerificationStorage storage ds)\\n {\\n bytes32 storagePosition = K1_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function r1Storage()\\n internal\\n pure\\n returns (Secp256r1VerificationStorage storage ds)\\n {\\n bytes32 storagePosition = R1_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function guardianStorage()\\n internal\\n pure\\n returns (GuardianStorage storage ds)\\n {\\n bytes32 storagePosition = GUARDIAN_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function recoveryStorage()\\n internal\\n pure\\n returns (RecoveryStorage storage ds)\\n {\\n bytes32 storagePosition = RECOVERY_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function restrictionsStorage()\\n internal\\n pure\\n returns (RestrictionsStorage storage ds)\\n {\\n bytes32 storagePosition = RESTRICTION_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function migrationStorage()\\n internal\\n pure\\n returns (SignatureMigrationStorage storage ds)\\n {\\n bytes32 storagePosition = MIGRATION_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function diamondCutStorage()\\n internal\\n pure\\n returns (DiamondCutStorage storage ds)\\n {\\n bytes32 storagePosition = DIAMONDCUT_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function lockStorage() internal pure returns (LockStorage storage ds) {\\n bytes32 storagePosition = LOCK_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n}\\n\",\"keccak256\":\"0x87c85decfd943deda9540733e464cb1a92eba735a301e89ce6f798016e359761\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\nimport {LibDiamond} from \\\"./LibDiamond.sol\\\";\\n\\n/**\\n * @title LibLoupe\\n * @dev Internal Library to provide utility feature for reading the state of diamond facets\\n * Originally from Diamond's implementation of Mudgen(author of EIP-2535)\\n */\\nlibrary LibLoupe {\\n /// @notice Gets all facets and their selectors.\\n /// @return facets_ Facet\\n function facets()\\n internal\\n view\\n returns (IDiamondLoupe.Facet[] memory facets_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facets_ = new IDiamondLoupe.Facet[](ds.selectorCount);\\n uint16[] memory numFacetSelectors = new uint16[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facets_[facetIndex].facetAddress == facetAddress_) {\\n facets_[facetIndex].functionSelectors[\\n numFacetSelectors[facetIndex]\\n ] = selector;\\n // probably will never have more than 256 functions from one facet contract\\n require(numFacetSelectors[facetIndex] < 255);\\n numFacetSelectors[facetIndex]++;\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facets_[numFacets].facetAddress = facetAddress_;\\n facets_[numFacets].functionSelectors = new bytes4[](\\n ds.selectorCount\\n );\\n facets_[numFacets].functionSelectors[0] = selector;\\n numFacetSelectors[numFacets] = 1;\\n numFacets++;\\n }\\n }\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n uint256 numSelectors = numFacetSelectors[facetIndex];\\n bytes4[] memory selectors = facets_[facetIndex].functionSelectors;\\n // setting the number of selectors\\n assembly {\\n mstore(selectors, numSelectors)\\n }\\n }\\n // setting the number of facets\\n assembly {\\n mstore(facets_, numFacets)\\n }\\n }\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return _facetFunctionSelectors The selectors associated with a facet address.\\n function facetFunctionSelectors(\\n address _facet\\n ) internal view returns (bytes4[] memory _facetFunctionSelectors) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n uint256 numSelectors;\\n _facetFunctionSelectors = new bytes4[](ds.selectorCount);\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facet = address(bytes20(ds.facets[selector]));\\n if (_facet == facet) {\\n _facetFunctionSelectors[numSelectors] = selector;\\n numSelectors++;\\n }\\n }\\n }\\n // Set the number of selectors in the array\\n assembly {\\n mstore(_facetFunctionSelectors, numSelectors)\\n }\\n }\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n internal\\n view\\n returns (address[] memory facetAddresses_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetAddresses_ = new address[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facetAddress_ == facetAddresses_[facetIndex]) {\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facetAddresses_[numFacets] = facetAddress_;\\n numFacets++;\\n }\\n }\\n // Set the number of facet addresses in the array\\n assembly {\\n mstore(facetAddresses_, numFacets)\\n }\\n }\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(LibDiamond.diamondStorage().facets[_functionSelector])\\n );\\n }\\n}\\n\",\"keccak256\":\"0x0b11439c3cc657095e15ec2241fdcf67204b14001357b612fc5db4ff9e760a5a\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x60a060405234801561001057600080fd5b50610019610022565b3060805261008b565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff161561006f57604051637c2cde8b60e01b815260040160405180910390fd5b600080805260209190915260409020805460ff19166001179055565b608051611f746100ad6000396000818161016001526106e10152611f746000f3fe608060405234801561001057600080fd5b50600436106100a35760003560e01c80637104ddb2116100765780638dd501211161005b5780638dd50121146101bc578063cd00e50a146101cf578063cd9b47e4146101d757600080fd5b80637104ddb21461015b5780638da5cb5b146101a757600080fd5b806311cfe388146100a85780631626ba7e146100ce5780633253960f14610112578063392dd6d914610138575b600080fd5b6100bb6100b6366004611823565b6101ea565b6040519081526020015b60405180910390f35b6100e16100dc366004611956565b610252565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020016100c5565b7f8dd50121000000000000000000000000000000000000000000000000000000006100e1565b61014b61014636600461199d565b6102fd565b60405190151581526020016100c5565b6101827f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100c5565b6101af61036f565b6040516100c591906119f6565b6100bb6101ca366004611a47565b6103ba565b6100bb61041f565b6100bb6101e5366004611a8c565b61053a565b600061023982846101ff610140880188611afe565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061083692505050565b610244576001610247565b60005b60ff16949350505050565b60006102aa7f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b1653646040805180820191829052919060029082845b81548152602001906001019080831161028b5750505050508484610836565b6102d4577fffffffff000000000000000000000000000000000000000000000000000000006102f6565b7f1626ba7e000000000000000000000000000000000000000000000000000000005b9392505050565b60008151604114801561036957508160008151811061031e5761031e611b6a565b6020910101517fff00000000000000000000000000000000000000000000000000000000000000167f0400000000000000000000000000000000000000000000000000000000000000145b92915050565b6040516060907f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364906103a5908290602001611b99565b60405160208183030381529060405291505090565b60408051808201918290526000917f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364916104179186918691859060029082845b8154815260200190600101908083116103fa5750505050506101ea565b949350505050565b60006104296109b4565b6104316109f4565b60408051808201909152600080825260208201527f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364906104749082906002611675565b506000610488600154610100900460e01b90565b7fffffffff0000000000000000000000000000000000000000000000000000000016036104e1576040517f127c609a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff169055604051600192507fcccd30db6bc000b8bb8d11162228d2d69e3c361983ca3ae8c1365ce64b0fae9e90600090a15090565b6000610544610a93565b61058383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102fd92505050565b6105b9576040517f6c334d2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006105c88360018187611bcd565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092935061060992506116b8915050565b602082015181526040820151602082015260006106437f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b16536490565b9050610651818360026116d6565b507f8dd50121000000000000000000000000000000000000000000000000000000006000610686600154610100900460e01b90565b7fffffffff0000000000000000000000000000000000000000000000000000000016146106df576040517f5f95a63c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16610770827fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604090205460601c90565b73ffffffffffffffffffffffffffffffffffffffff16146107bd576040517fbb4752b700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff1661010060e084901c02179055600194507f6d54821a69ec281ed7ba1bf2729c700768c47df1d80fad646b0a14cc1d5c39ed8787604051610824929190611bf7565b60405180910390a15050505092915050565b600080600080600080868060200190518101906108539190611c94565b9450945094509450945060008061088a8a60405160200161087691815260200190565b604051602081830303815290604052610b33565b905060008482856040516020016108a393929190611d47565b60405160208183030381529060405290506002816040516108c49190611d8a565b602060405180830381855afa1580156108e1573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906109049190611da6565b9250505060006002858360405160200161091f929190611dbf565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905261095791611d8a565b602060405180830381855afa158015610974573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906109979190611da6565b90506109a58b888884610c6f565b9b9a5050505050505050505050565b6001805460ff16146109f2576040517f38fc28cb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff16600114610a5c576040517fe00d7c7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff1615610af9576040517f7c2cde8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b60608151600003610b5257505060408051602081019091526000815290565b6000604051806060016040528060408152602001611eff6040913990506000600684516008610b819190611e10565b610b8b9190611e56565b9050600060068551610b9d9190611e6a565b1115610bb15780610bad81611e7e565b9150505b60008167ffffffffffffffff811115610bcc57610bcc61177c565b6040519080825280601f01601f191660200182016040528015610bf6576020820181803683370190505b509050600183016020820186875188015b80821015610c62576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f8116850151845350600183019250610c07565b5092979650505050505050565b6000610c9c60017fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611eb6565b85511180610cd75750610cd060017fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611eb6565b6020860151115b15610ce457506000610417565b831580610cef575082155b80610d1a57507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518410155b80610d4557507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518310155b15610d5257506000610417565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff7f5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff8088600060200201517fffffffff00000001000000000000000000000000fffffffffffffffffffffffc0988517fffffffff00000001000000000000000000000000ffffffffffffffffffffffff90819080098a5109080860208601517fffffffff00000001000000000000000000000000ffffffffffffffffffffffff90800914610e4357506000610417565b6000610e4e86610e66565b9050610e5c81868686611062565b9695505050505050565b610e6e611704565b60405180606001604052806000815260200160008152602001600081525081600060108110610e9f57610e9f611b6a565b60200201526040805160608101909152808360006020020151815260200183600160028110610ed057610ed0611b6a565b60200201518152602001600181525081600160108110610ef257610ef2611b6a565b6020020152610f088160015b602002015161116f565b6040820152610f278160015b60200201518260025b60200201516111d1565b6060828101919091526040805191820181527f6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c29682527f4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f560208301526001908201526080820152610fa18160045b6020020151826001610f1d565b60a0820152610fb1816004610f14565b60c0820152610fca8160045b6020020151826003610f1d565b60e0820152610fda816004610efe565b610100820152610feb816008610f94565b610120820152610ffc816008610f14565b61014082015261100d816008610fbd565b610160820152608081015161102490826008610f1d565b61018082015261103581600c610f94565b6101a082015261104681600c610f14565b6101c082015261105781600c610fbd565b6101e0820152919050565b600083158061106f575082155b8061109a57507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518410155b806110c557507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518310155b156110d257506000610417565b60006110fe847fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551611243565b905060007fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551828509905060007fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551838809905060008061115e8a858561125a565b509098149998505050505050505050565b61119360405180606001604052806000815260200160008152602001600081525090565b60008060006111af856000015186602001518760400151611346565b6040805160608101825293845260208401929092529082015295945050505050565b6111f560405180606001604052806000815260200160008152602001600081525090565b6000806000611220866000015187602001518860400151886000015189602001518a60400151611424565b604080516060810182529384526020840192909252908201529695505050505050565b60006102f683611254600285611eb6565b8461155c565b6000808080806080815b81156113285782156112955761127b858585611346565b9196509450925061128d858585611346565b919650945092505b50600c60fc89901c1660fe88901c17801561130b576113038585858d85601081106112c2576112c2611b6a565b6020020151518e86601081106112da576112da611b6a565b6020020151602001518f87601081106112f5576112f5611b6a565b602002015160400151611424565b919650945092505b600298891b989790971b968161132081611ec9565b925050611264565b6113338585856115b0565b909750955050505050505b935093915050565b6000806000846000036113615750600091508190508061141b565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff8085860981828283097fffffffff00000001000000000000000000000000fffffffffffffffffffffffc099050818788098283828b0960040983848384096008099150838385868d8e09600309089250838160020984848509818110156113e65785015b039650868110156113f45783015b8387820384099550508085101561140a57938201935b909303925080808688096002099150505b93509350939050565b60008060008660000361143e575084915083905082611550565b83600003611453575087915086905085611550565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff808889098186870982818d0983838b0984858a85098e0985868e87098c09868b8f08848410156114a357928701925b8484039350878460020988818209905088818609848410156114c457928901925b898585036002099350898485099c50898288099650898a8860020982089150818d10156114f0579b89019b5b818d039c5089818b87600209099450508b86101561150d57948801945b888c870384099a50838b101561152257998801995b838b039a508887890897508882830990508781101561153e5788015b88858983030999505050505050505050505b96509650969350505050565b60008184111561156c5781840693505b60405160208152602080820152602060408201528460608201528360808201528260a082015260208160c08360056136b0fa8080156100a357505051949350505050565b600080826000036115c65750600090508061133e565b60006115f2847fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611243565b905060007fffffffff00000001000000000000000000000000ffffffffffffffffffffffff82830990507fffffffff00000001000000000000000000000000ffffffffffffffffffffffff81880993507fffffffff00000001000000000000000000000000ffffffffffffffffffffffff80838309870992505050935093915050565b82600281019282156116a8579160200282015b828111156116a8578251829060ff16905591602001919060010190611688565b506116b492915061174e565b5090565b60405180604001604052806002906020820280368337509192915050565b82600281019282156116a8579160200282015b828111156116a85782518255916020019190600101906116e9565b6040518061020001604052806010905b61173860405180606001604052806000815260200160008152602001600081525090565b8152602001906001900390816117145790505090565b5b808211156116b4576000815560010161174f565b6000610160828403121561177657600080fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156117ce576117ce61177c565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561181b5761181b61177c565b604052919050565b60008060006080848603121561183857600080fd5b833567ffffffffffffffff81111561184f57600080fd5b61185b86828701611763565b935050602080850135925085605f86011261187557600080fd5b61187d6117ab565b80608087018881111561188f57600080fd5b604088015b818110156118ab5780358452928401928401611894565b50508093505050509250925092565b600067ffffffffffffffff8211156118d4576118d461177c565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261191157600080fd5b813561192461191f826118ba565b6117d4565b81815284602083860101111561193957600080fd5b816020850160208301376000918101602001919091529392505050565b6000806040838503121561196957600080fd5b82359150602083013567ffffffffffffffff81111561198757600080fd5b61199385828601611900565b9150509250929050565b6000602082840312156119af57600080fd5b813567ffffffffffffffff8111156119c657600080fd5b61041784828501611900565b60005b838110156119ed5781810151838201526020016119d5565b50506000910152565b6020815260008251806020840152611a158160408501602087016119d2565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b60008060408385031215611a5a57600080fd5b823567ffffffffffffffff811115611a7157600080fd5b611a7d85828601611763565b95602094909401359450505050565b60008060208385031215611a9f57600080fd5b823567ffffffffffffffff80821115611ab757600080fd5b818501915085601f830112611acb57600080fd5b813581811115611ada57600080fd5b866020828501011115611aec57600080fd5b60209290920196919550909350505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112611b3357600080fd5b83018035915067ffffffffffffffff821115611b4e57600080fd5b602001915036819003821315611b6357600080fd5b9250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008183825b6002811015611bbe578154835260209092019160019182019101611b9f565b50505060408201905092915050565b60008085851115611bdd57600080fd5b83861115611bea57600080fd5b5050820193919092039150565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b6000611c5261191f846118ba565b9050828152838383011115611c6657600080fd5b6102f68360208301846119d2565b600082601f830112611c8557600080fd5b6102f683835160208501611c44565b600080600080600060a08688031215611cac57600080fd5b8551945060208601519350604086015167ffffffffffffffff80821115611cd257600080fd5b818801915088601f830112611ce657600080fd5b611cf589835160208501611c44565b94506060880151915080821115611d0b57600080fd5b611d1789838a01611c74565b93506080880151915080821115611d2d57600080fd5b50611d3a88828901611c74565b9150509295509295909350565b60008451611d598184602089016119d2565b845190830190611d6d8183602089016119d2565b8451910190611d808183602088016119d2565b0195945050505050565b60008251611d9c8184602087016119d2565b9190910192915050565b600060208284031215611db857600080fd5b5051919050565b60008351611dd18184602088016119d2565b9190910191825250602001919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808202811582820484141761036957610369611de1565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082611e6557611e65611e27565b500490565b600082611e7957611e79611e27565b500690565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611eaf57611eaf611de1565b5060010190565b8181038181111561036957610369611de1565b600081611ed857611ed8611de1565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392d5fa2646970667358221220d4142da7b16effb6b95f41adeff2bc8ce0d59d3b70ca8d55e6e83224bbfbec0a64736f6c63430008150033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100a35760003560e01c80637104ddb2116100765780638dd501211161005b5780638dd50121146101bc578063cd00e50a146101cf578063cd9b47e4146101d757600080fd5b80637104ddb21461015b5780638da5cb5b146101a757600080fd5b806311cfe388146100a85780631626ba7e146100ce5780633253960f14610112578063392dd6d914610138575b600080fd5b6100bb6100b6366004611823565b6101ea565b6040519081526020015b60405180910390f35b6100e16100dc366004611956565b610252565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020016100c5565b7f8dd50121000000000000000000000000000000000000000000000000000000006100e1565b61014b61014636600461199d565b6102fd565b60405190151581526020016100c5565b6101827f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100c5565b6101af61036f565b6040516100c591906119f6565b6100bb6101ca366004611a47565b6103ba565b6100bb61041f565b6100bb6101e5366004611a8c565b61053a565b600061023982846101ff610140880188611afe565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061083692505050565b610244576001610247565b60005b60ff16949350505050565b60006102aa7f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b1653646040805180820191829052919060029082845b81548152602001906001019080831161028b5750505050508484610836565b6102d4577fffffffff000000000000000000000000000000000000000000000000000000006102f6565b7f1626ba7e000000000000000000000000000000000000000000000000000000005b9392505050565b60008151604114801561036957508160008151811061031e5761031e611b6a565b6020910101517fff00000000000000000000000000000000000000000000000000000000000000167f0400000000000000000000000000000000000000000000000000000000000000145b92915050565b6040516060907f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364906103a5908290602001611b99565b60405160208183030381529060405291505090565b60408051808201918290526000917f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364916104179186918691859060029082845b8154815260200190600101908083116103fa5750505050506101ea565b949350505050565b60006104296109b4565b6104316109f4565b60408051808201909152600080825260208201527f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364906104749082906002611675565b506000610488600154610100900460e01b90565b7fffffffff0000000000000000000000000000000000000000000000000000000016036104e1576040517f127c609a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff169055604051600192507fcccd30db6bc000b8bb8d11162228d2d69e3c361983ca3ae8c1365ce64b0fae9e90600090a15090565b6000610544610a93565b61058383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102fd92505050565b6105b9576040517f6c334d2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006105c88360018187611bcd565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092935061060992506116b8915050565b602082015181526040820151602082015260006106437f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b16536490565b9050610651818360026116d6565b507f8dd50121000000000000000000000000000000000000000000000000000000006000610686600154610100900460e01b90565b7fffffffff0000000000000000000000000000000000000000000000000000000016146106df576040517f5f95a63c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16610770827fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604090205460601c90565b73ffffffffffffffffffffffffffffffffffffffff16146107bd576040517fbb4752b700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff1661010060e084901c02179055600194507f6d54821a69ec281ed7ba1bf2729c700768c47df1d80fad646b0a14cc1d5c39ed8787604051610824929190611bf7565b60405180910390a15050505092915050565b600080600080600080868060200190518101906108539190611c94565b9450945094509450945060008061088a8a60405160200161087691815260200190565b604051602081830303815290604052610b33565b905060008482856040516020016108a393929190611d47565b60405160208183030381529060405290506002816040516108c49190611d8a565b602060405180830381855afa1580156108e1573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906109049190611da6565b9250505060006002858360405160200161091f929190611dbf565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905261095791611d8a565b602060405180830381855afa158015610974573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906109979190611da6565b90506109a58b888884610c6f565b9b9a5050505050505050505050565b6001805460ff16146109f2576040517f38fc28cb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff16600114610a5c576040517fe00d7c7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff1615610af9576040517f7c2cde8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b60608151600003610b5257505060408051602081019091526000815290565b6000604051806060016040528060408152602001611eff6040913990506000600684516008610b819190611e10565b610b8b9190611e56565b9050600060068551610b9d9190611e6a565b1115610bb15780610bad81611e7e565b9150505b60008167ffffffffffffffff811115610bcc57610bcc61177c565b6040519080825280601f01601f191660200182016040528015610bf6576020820181803683370190505b509050600183016020820186875188015b80821015610c62576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f8116850151845350600183019250610c07565b5092979650505050505050565b6000610c9c60017fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611eb6565b85511180610cd75750610cd060017fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611eb6565b6020860151115b15610ce457506000610417565b831580610cef575082155b80610d1a57507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518410155b80610d4557507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518310155b15610d5257506000610417565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff7f5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff8088600060200201517fffffffff00000001000000000000000000000000fffffffffffffffffffffffc0988517fffffffff00000001000000000000000000000000ffffffffffffffffffffffff90819080098a5109080860208601517fffffffff00000001000000000000000000000000ffffffffffffffffffffffff90800914610e4357506000610417565b6000610e4e86610e66565b9050610e5c81868686611062565b9695505050505050565b610e6e611704565b60405180606001604052806000815260200160008152602001600081525081600060108110610e9f57610e9f611b6a565b60200201526040805160608101909152808360006020020151815260200183600160028110610ed057610ed0611b6a565b60200201518152602001600181525081600160108110610ef257610ef2611b6a565b6020020152610f088160015b602002015161116f565b6040820152610f278160015b60200201518260025b60200201516111d1565b6060828101919091526040805191820181527f6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c29682527f4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f560208301526001908201526080820152610fa18160045b6020020151826001610f1d565b60a0820152610fb1816004610f14565b60c0820152610fca8160045b6020020151826003610f1d565b60e0820152610fda816004610efe565b610100820152610feb816008610f94565b610120820152610ffc816008610f14565b61014082015261100d816008610fbd565b610160820152608081015161102490826008610f1d565b61018082015261103581600c610f94565b6101a082015261104681600c610f14565b6101c082015261105781600c610fbd565b6101e0820152919050565b600083158061106f575082155b8061109a57507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518410155b806110c557507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518310155b156110d257506000610417565b60006110fe847fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551611243565b905060007fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551828509905060007fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551838809905060008061115e8a858561125a565b509098149998505050505050505050565b61119360405180606001604052806000815260200160008152602001600081525090565b60008060006111af856000015186602001518760400151611346565b6040805160608101825293845260208401929092529082015295945050505050565b6111f560405180606001604052806000815260200160008152602001600081525090565b6000806000611220866000015187602001518860400151886000015189602001518a60400151611424565b604080516060810182529384526020840192909252908201529695505050505050565b60006102f683611254600285611eb6565b8461155c565b6000808080806080815b81156113285782156112955761127b858585611346565b9196509450925061128d858585611346565b919650945092505b50600c60fc89901c1660fe88901c17801561130b576113038585858d85601081106112c2576112c2611b6a565b6020020151518e86601081106112da576112da611b6a565b6020020151602001518f87601081106112f5576112f5611b6a565b602002015160400151611424565b919650945092505b600298891b989790971b968161132081611ec9565b925050611264565b6113338585856115b0565b909750955050505050505b935093915050565b6000806000846000036113615750600091508190508061141b565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff8085860981828283097fffffffff00000001000000000000000000000000fffffffffffffffffffffffc099050818788098283828b0960040983848384096008099150838385868d8e09600309089250838160020984848509818110156113e65785015b039650868110156113f45783015b8387820384099550508085101561140a57938201935b909303925080808688096002099150505b93509350939050565b60008060008660000361143e575084915083905082611550565b83600003611453575087915086905085611550565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff808889098186870982818d0983838b0984858a85098e0985868e87098c09868b8f08848410156114a357928701925b8484039350878460020988818209905088818609848410156114c457928901925b898585036002099350898485099c50898288099650898a8860020982089150818d10156114f0579b89019b5b818d039c5089818b87600209099450508b86101561150d57948801945b888c870384099a50838b101561152257998801995b838b039a508887890897508882830990508781101561153e5788015b88858983030999505050505050505050505b96509650969350505050565b60008184111561156c5781840693505b60405160208152602080820152602060408201528460608201528360808201528260a082015260208160c08360056136b0fa8080156100a357505051949350505050565b600080826000036115c65750600090508061133e565b60006115f2847fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611243565b905060007fffffffff00000001000000000000000000000000ffffffffffffffffffffffff82830990507fffffffff00000001000000000000000000000000ffffffffffffffffffffffff81880993507fffffffff00000001000000000000000000000000ffffffffffffffffffffffff80838309870992505050935093915050565b82600281019282156116a8579160200282015b828111156116a8578251829060ff16905591602001919060010190611688565b506116b492915061174e565b5090565b60405180604001604052806002906020820280368337509192915050565b82600281019282156116a8579160200282015b828111156116a85782518255916020019190600101906116e9565b6040518061020001604052806010905b61173860405180606001604052806000815260200160008152602001600081525090565b8152602001906001900390816117145790505090565b5b808211156116b4576000815560010161174f565b6000610160828403121561177657600080fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156117ce576117ce61177c565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561181b5761181b61177c565b604052919050565b60008060006080848603121561183857600080fd5b833567ffffffffffffffff81111561184f57600080fd5b61185b86828701611763565b935050602080850135925085605f86011261187557600080fd5b61187d6117ab565b80608087018881111561188f57600080fd5b604088015b818110156118ab5780358452928401928401611894565b50508093505050509250925092565b600067ffffffffffffffff8211156118d4576118d461177c565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261191157600080fd5b813561192461191f826118ba565b6117d4565b81815284602083860101111561193957600080fd5b816020850160208301376000918101602001919091529392505050565b6000806040838503121561196957600080fd5b82359150602083013567ffffffffffffffff81111561198757600080fd5b61199385828601611900565b9150509250929050565b6000602082840312156119af57600080fd5b813567ffffffffffffffff8111156119c657600080fd5b61041784828501611900565b60005b838110156119ed5781810151838201526020016119d5565b50506000910152565b6020815260008251806020840152611a158160408501602087016119d2565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b60008060408385031215611a5a57600080fd5b823567ffffffffffffffff811115611a7157600080fd5b611a7d85828601611763565b95602094909401359450505050565b60008060208385031215611a9f57600080fd5b823567ffffffffffffffff80821115611ab757600080fd5b818501915085601f830112611acb57600080fd5b813581811115611ada57600080fd5b866020828501011115611aec57600080fd5b60209290920196919550909350505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112611b3357600080fd5b83018035915067ffffffffffffffff821115611b4e57600080fd5b602001915036819003821315611b6357600080fd5b9250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008183825b6002811015611bbe578154835260209092019160019182019101611b9f565b50505060408201905092915050565b60008085851115611bdd57600080fd5b83861115611bea57600080fd5b5050820193919092039150565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b6000611c5261191f846118ba565b9050828152838383011115611c6657600080fd5b6102f68360208301846119d2565b600082601f830112611c8557600080fd5b6102f683835160208501611c44565b600080600080600060a08688031215611cac57600080fd5b8551945060208601519350604086015167ffffffffffffffff80821115611cd257600080fd5b818801915088601f830112611ce657600080fd5b611cf589835160208501611c44565b94506060880151915080821115611d0b57600080fd5b611d1789838a01611c74565b93506080880151915080821115611d2d57600080fd5b50611d3a88828901611c74565b9150509295509295909350565b60008451611d598184602089016119d2565b845190830190611d6d8183602089016119d2565b8451910190611d808183602088016119d2565b0195945050505050565b60008251611d9c8184602087016119d2565b9190910192915050565b600060208284031215611db857600080fd5b5051919050565b60008351611dd18184602088016119d2565b9190910191825250602001919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808202811582820484141761036957610369611de1565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082611e6557611e65611e27565b500490565b600082611e7957611e79611e27565b500690565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611eaf57611eaf611de1565b5060010190565b8181038181111561036957610369611de1565b600081611ed857611ed8611de1565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392d5fa2646970667358221220d4142da7b16effb6b95f41adeff2bc8ce0d59d3b70ca8d55e6e83224bbfbec0a64736f6c63430008150033", + "devdoc": { + "author": "Ruslan Serebriakov (@rsrbk)David Yongjun Kim (@Powerstream3604)", + "details": "Primarily used to verify user ops signed with passkeys", + "kind": "dev", + "methods": { + "initializeSigner(bytes)": { + "details": "This method checks if the signer has already been initialized. If already initialized, it reverts. It checks if the public key is in the light format and initializes signer storage in k1 storage.", + "params": { + "_publicKey": "Bytes of owner public key" + }, + "returns": { + "initSuccess": "Uint value representing the success of init operation" + } + }, + "isValidKeyType(bytes)": { + "details": "For this Secp256k1Verification Facet, the public key should in an uncompressed public key format", + "params": { + "_publicKey": "Bytes of public key for format check" + }, + "returns": { + "isValid": "Boolean variable representing if the format of public key is valid" + } + }, + "isValidSignature(bytes32,bytes)": { + "details": "This method verifies the signature if the owner indeed signed the hash. Returns magic value if true", + "params": { + "_hash": "Hash value the owner signed", + "_signature": "Signature that signed the above hash" + }, + "returns": { + "magicValue": "Bytes4 value representing the success/failure of validation" + } + }, + "owner()": { + "returns": { + "signer": "Bytes of owner address" + } + }, + "uninitializeSigner()": { + "details": "This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.", + "returns": { + "uninitSuccess": "Uint value representing the success of uninit operation" + } + }, + "validateOwnerSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32)": { + "details": "This method validates if the user operation is signed by the owner. It internally calls validateSignature with signer public key.", + "params": { + "userOp": "UserOperation including all information for execution", + "userOpHash": "Hash of UserOperation given from EntryPoint. This hash is used for signature validation" + }, + "returns": { + "validationData": "Uint value representing whether the validation is successful. 0 for success, 1 for failure" + } + }, + "validateOwnerSignatureSelector()": { + "returns": { + "ownerSignatureValidatorSelector": "Bytes4 selector of function signature to validate account owner's UserOperation signature" + } + }, + "validateSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256[2])": { + "details": "This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address", + "params": { + "q": "Public Key of signer who signed the contract, to be validated", + "userOp": "UserOperation including all information for execution", + "userOpHash": "Hash of UserOperation given from EntryPoint. This hash is used for signature validation" + }, + "returns": { + "isValid": "Uint value representing whether the validation is successful. 0 for success, 1 for failure" + } + } + }, + "title": "Secp256r1 verification facet", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "constructor": { + "notice": "This constructor ensures that this contract can only be used as singleton for Proxy contracts" + }, + "initializeSigner(bytes)": { + "notice": "Initializes the signer in R1 Facet Storage. This can only be called when the account is uninitialized or during signature migration." + }, + "isValidKeyType(bytes)": { + "notice": "Validates if the format of public key is valid for this verification facet" + }, + "isValidSignature(bytes32,bytes)": { + "notice": "Validates if the signature is valid. Function to be compatible with EIP-1271" + }, + "owner()": { + "notice": "Returns the owner of the account" + }, + "uninitializeSigner()": { + "notice": "Uninitialize signer in R1 Facet Storage. This can only be called when the account is undergoing signature migration and has already been initialized." + }, + "validateOwnerSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32)": { + "notice": "Validates if the user operation is signed by the owner." + }, + "validateOwnerSignatureSelector()": { + "notice": "Returns the selector of function to validate the signature of UserOperation" + }, + "validateSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256[2])": { + "notice": "Validates if the signature of UserOperation is signed by the given signer" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/lightLink/TokenReceiverFacet.json b/deployments/lightLink/TokenReceiverFacet.json new file mode 100644 index 0000000..85a4a93 --- /dev/null +++ b/deployments/lightLink/TokenReceiverFacet.json @@ -0,0 +1,239 @@ +{ + "address": "0x3143E1C0Af0Cdc153423863923Cf4e3818e34Daa", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onERC1155BatchReceived", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onERC1155Received", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onERC721Received", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onTokenTransfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "tokensReceived", + "outputs": [], + "stateMutability": "pure", + "type": "function" + } + ], + "transactionHash": "0x60d5268ac3841e1c52f8b0acbcc4a181433c8cdf5ffea8867af0ba841b0302c4", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": "0x0000000000000000000000000000000000000000", + "transactionIndex": 0, + "gasUsed": "329424", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x6cbd3dec02d050be97768cd53fbef6e8617a5f93dcafdc8888f08df85a622fdb", + "transactionHash": "0x60d5268ac3841e1c52f8b0acbcc4a181433c8cdf5ffea8867af0ba841b0302c4", + "logs": [], + "blockNumber": 72701548, + "cumulativeGasUsed": "329424", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "ad34345aa73d96f52b3e14df983b6b29", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onERC1155BatchReceived\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onERC1155Received\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onERC721Received\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"tokensReceived\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"Contract that enables receiving ERC721/ERC1155/ERC777/ERC677 Tokens with safe transfer\",\"kind\":\"dev\",\"methods\":{},\"title\":\"TokenReceiver Facet\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\":{\"notice\":\"Handles ERC1155 Token batch callback. return Standardized onERC1155BatchReceived return value.\"},\"onERC1155Received(address,address,uint256,uint256,bytes)\":{\"notice\":\"Handles ERC1155 Token callback. return Standardized onERC1155Received return value.\"},\"onERC721Received(address,address,uint256,bytes)\":{\"notice\":\"Handles ERC721 Token callback. return Standardized onERC721Received return value.\"},\"onTokenTransfer(address,uint256,bytes)\":{\"notice\":\"Handles ERC677 Token callback. return true.\"},\"tokensReceived(address,address,address,uint256,bytes,bytes)\":{\"notice\":\"Handles ERC777 Token callback. Does not return value, empty implementation.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/TokenReceiverFacet.sol\":\"TokenReceiverFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title ERC721 token receiver interface\\n * @dev Interface for any contract that wants to support safeTransfers\\n * from ERC721 asset contracts.\\n */\\ninterface IERC721Receiver {\\n /**\\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\\n * by `operator` from `from`, this function is called.\\n *\\n * It must return its Solidity selector to confirm the token transfer.\\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\\n *\\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\\n */\\n function onERC721Received(\\n address operator,\\n address from,\\n uint256 tokenId,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\\n *\\n * Accounts can be notified of {IERC777} tokens being sent to them by having a\\n * contract implement this interface (contract holders can be their own\\n * implementer) and registering it on the\\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\\n *\\n * See {IERC1820Registry} and {ERC1820Implementer}.\\n */\\ninterface IERC777Recipient {\\n /**\\n * @dev Called by an {IERC777} token contract whenever tokens are being\\n * moved or created into a registered account (`to`). The type of operation\\n * is conveyed by `from` being the zero address or not.\\n *\\n * This call occurs _after_ the token contract's state is updated, so\\n * {IERC777-balanceOf}, etc., can be used to query the post-operation state.\\n *\\n * This function may revert to prevent the operation from being executed.\\n */\\n function tokensReceived(\\n address operator,\\n address from,\\n address to,\\n uint256 amount,\\n bytes calldata userData,\\n bytes calldata operatorData\\n ) external;\\n}\\n\",\"keccak256\":\"0x1a5d61db2733202ba361e6d6741cd2e662380e22b80e987eacfc91973f2267dc\",\"license\":\"MIT\"},\"contracts/facets/TokenReceiverFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IERC721Receiver} from \\\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\\\";\\nimport {IERC777Recipient} from \\\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\\\";\\nimport {IERC1155Receiver} from \\\"../interfaces/ERC/IERC1155Receiver.sol\\\";\\nimport {IERC677Receiver} from \\\"../interfaces/ERC/IERC677Receiver.sol\\\";\\n\\n/**\\n * @title TokenReceiver Facet\\n * @dev Contract that enables receiving ERC721/ERC1155/ERC777/ERC677 Tokens with safe transfer\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract TokenReceiverFacet is\\n IERC721Receiver,\\n IERC1155Receiver,\\n IERC777Recipient,\\n IERC677Receiver\\n{\\n /**\\n * @notice Handles ERC721 Token callback.\\n * return Standardized onERC721Received return value.\\n */\\n function onERC721Received(\\n address,\\n address,\\n uint256,\\n bytes calldata\\n ) external pure override returns (bytes4) {\\n return IERC721Receiver.onERC721Received.selector;\\n }\\n\\n /**\\n * @notice Handles ERC1155 Token callback.\\n * return Standardized onERC1155Received return value.\\n */\\n function onERC1155Received(\\n address,\\n address,\\n uint256,\\n uint256,\\n bytes calldata\\n ) external pure override returns (bytes4) {\\n return IERC1155Receiver.onERC1155Received.selector;\\n }\\n\\n /**\\n * @notice Handles ERC1155 Token batch callback.\\n * return Standardized onERC1155BatchReceived return value.\\n */\\n function onERC1155BatchReceived(\\n address,\\n address,\\n uint256[] calldata,\\n uint256[] calldata,\\n bytes calldata\\n ) external pure override returns (bytes4) {\\n return IERC1155Receiver.onERC1155BatchReceived.selector;\\n }\\n\\n /**\\n * @notice Handles ERC777 Token callback.\\n * Does not return value, empty implementation.\\n */\\n function tokensReceived(\\n address,\\n address,\\n address,\\n uint256,\\n bytes calldata,\\n bytes calldata\\n ) external pure override {}\\n\\n /**\\n * @notice Handles ERC677 Token callback.\\n * return true.\\n */\\n function onTokenTransfer(\\n address,\\n uint256,\\n bytes calldata\\n ) external pure override returns (bool) {\\n return true;\\n }\\n}\\n\",\"keccak256\":\"0xdfe483d05ef4056bb464c34ade19ab527687aff3ed0b6303b447a68b5ff7abb4\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC1155Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\n\\npragma solidity 0.8.21;\\n\\n/**\\n * @dev _Available since v3.1._\\n */\\ninterface IERC1155Receiver {\\n /**\\n * @dev Handles the receipt of a single ERC1155 token type. This function is\\n * called at the end of a `safeTransferFrom` after the balance has been updated.\\n *\\n * NOTE: To accept the transfer, this must return\\n * `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))`\\n * (i.e. 0xf23a6e61, or its own function selector).\\n *\\n * @param operator The address which initiated the transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param id The ID of the token being transferred\\n * @param value The amount of tokens being transferred\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155Received(\\n address operator,\\n address from,\\n uint256 id,\\n uint256 value,\\n bytes calldata data\\n ) external returns (bytes4);\\n\\n /**\\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\\n * is called at the end of a `safeBatchTransferFrom` after the balances have\\n * been updated.\\n *\\n * NOTE: To accept the transfer(s), this must return\\n * `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))`\\n * (i.e. 0xbc197c81, or its own function selector).\\n *\\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155BatchReceived(\\n address operator,\\n address from,\\n uint256[] calldata ids,\\n uint256[] calldata values,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0x3729c6757bae3aba03ac1c5064d67ad13b94e2a9428bf44b9be510373406da0c\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC677Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC677Receiver {\\n function onTokenTransfer(\\n address sender,\\n uint value,\\n bytes calldata data\\n ) external pure returns (bool);\\n}\\n\",\"keccak256\":\"0x4c1631cf45ea6daac0ec158c3edb9453099130b6b64f697004b83f95aa1f7350\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50610502806100206000396000f3fe608060405234801561001057600080fd5b50600436106100665760003560e01c8063a4c0ed3611610050578063a4c0ed36146100f3578063bc197c811461011b578063f23a6e611461015657600080fd5b806223de291461006b578063150b7a0214610085575b600080fd5b610083610079366004610201565b5050505050505050565b005b6100bd6100933660046102ac565b7f150b7a020000000000000000000000000000000000000000000000000000000095945050505050565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020015b60405180910390f35b61010b61010136600461031b565b6001949350505050565b60405190151581526020016100ea565b6100bd6101293660046103ba565b7fbc197c810000000000000000000000000000000000000000000000000000000098975050505050505050565b6100bd610164366004610454565b7ff23a6e61000000000000000000000000000000000000000000000000000000009695505050505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146101b357600080fd5b919050565b60008083601f8401126101ca57600080fd5b50813567ffffffffffffffff8111156101e257600080fd5b6020830191508360208285010111156101fa57600080fd5b9250929050565b60008060008060008060008060c0898b03121561021d57600080fd5b6102268961018f565b975061023460208a0161018f565b965061024260408a0161018f565b955060608901359450608089013567ffffffffffffffff8082111561026657600080fd5b6102728c838d016101b8565b909650945060a08b013591508082111561028b57600080fd5b506102988b828c016101b8565b999c989b5096995094979396929594505050565b6000806000806000608086880312156102c457600080fd5b6102cd8661018f565b94506102db6020870161018f565b935060408601359250606086013567ffffffffffffffff8111156102fe57600080fd5b61030a888289016101b8565b969995985093965092949392505050565b6000806000806060858703121561033157600080fd5b61033a8561018f565b935060208501359250604085013567ffffffffffffffff81111561035d57600080fd5b610369878288016101b8565b95989497509550505050565b60008083601f84011261038757600080fd5b50813567ffffffffffffffff81111561039f57600080fd5b6020830191508360208260051b85010111156101fa57600080fd5b60008060008060008060008060a0898b0312156103d657600080fd5b6103df8961018f565b97506103ed60208a0161018f565b9650604089013567ffffffffffffffff8082111561040a57600080fd5b6104168c838d01610375565b909850965060608b013591508082111561042f57600080fd5b61043b8c838d01610375565b909650945060808b013591508082111561028b57600080fd5b60008060008060008060a0878903121561046d57600080fd5b6104768761018f565b95506104846020880161018f565b94506040870135935060608701359250608087013567ffffffffffffffff8111156104ae57600080fd5b6104ba89828a016101b8565b979a969950949750929593949250505056fea2646970667358221220ae9a97061ae9e1485161ca9c8d3228a23e47b18755fa935f51b40e927816ca2964736f6c63430008150033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100665760003560e01c8063a4c0ed3611610050578063a4c0ed36146100f3578063bc197c811461011b578063f23a6e611461015657600080fd5b806223de291461006b578063150b7a0214610085575b600080fd5b610083610079366004610201565b5050505050505050565b005b6100bd6100933660046102ac565b7f150b7a020000000000000000000000000000000000000000000000000000000095945050505050565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020015b60405180910390f35b61010b61010136600461031b565b6001949350505050565b60405190151581526020016100ea565b6100bd6101293660046103ba565b7fbc197c810000000000000000000000000000000000000000000000000000000098975050505050505050565b6100bd610164366004610454565b7ff23a6e61000000000000000000000000000000000000000000000000000000009695505050505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146101b357600080fd5b919050565b60008083601f8401126101ca57600080fd5b50813567ffffffffffffffff8111156101e257600080fd5b6020830191508360208285010111156101fa57600080fd5b9250929050565b60008060008060008060008060c0898b03121561021d57600080fd5b6102268961018f565b975061023460208a0161018f565b965061024260408a0161018f565b955060608901359450608089013567ffffffffffffffff8082111561026657600080fd5b6102728c838d016101b8565b909650945060a08b013591508082111561028b57600080fd5b506102988b828c016101b8565b999c989b5096995094979396929594505050565b6000806000806000608086880312156102c457600080fd5b6102cd8661018f565b94506102db6020870161018f565b935060408601359250606086013567ffffffffffffffff8111156102fe57600080fd5b61030a888289016101b8565b969995985093965092949392505050565b6000806000806060858703121561033157600080fd5b61033a8561018f565b935060208501359250604085013567ffffffffffffffff81111561035d57600080fd5b610369878288016101b8565b95989497509550505050565b60008083601f84011261038757600080fd5b50813567ffffffffffffffff81111561039f57600080fd5b6020830191508360208260051b85010111156101fa57600080fd5b60008060008060008060008060a0898b0312156103d657600080fd5b6103df8961018f565b97506103ed60208a0161018f565b9650604089013567ffffffffffffffff8082111561040a57600080fd5b6104168c838d01610375565b909850965060608b013591508082111561042f57600080fd5b61043b8c838d01610375565b909650945060808b013591508082111561028b57600080fd5b60008060008060008060a0878903121561046d57600080fd5b6104768761018f565b95506104846020880161018f565b94506040870135935060608701359250608087013567ffffffffffffffff8111156104ae57600080fd5b6104ba89828a016101b8565b979a969950949750929593949250505056fea2646970667358221220ae9a97061ae9e1485161ca9c8d3228a23e47b18755fa935f51b40e927816ca2964736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "Contract that enables receiving ERC721/ERC1155/ERC777/ERC677 Tokens with safe transfer", + "kind": "dev", + "methods": {}, + "title": "TokenReceiver Facet", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)": { + "notice": "Handles ERC1155 Token batch callback. return Standardized onERC1155BatchReceived return value." + }, + "onERC1155Received(address,address,uint256,uint256,bytes)": { + "notice": "Handles ERC1155 Token callback. return Standardized onERC1155Received return value." + }, + "onERC721Received(address,address,uint256,bytes)": { + "notice": "Handles ERC721 Token callback. return Standardized onERC721Received return value." + }, + "onTokenTransfer(address,uint256,bytes)": { + "notice": "Handles ERC677 Token callback. return true." + }, + "tokensReceived(address,address,address,uint256,bytes,bytes)": { + "notice": "Handles ERC777 Token callback. Does not return value, empty implementation." + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/lightLink/solcInputs/ad34345aa73d96f52b3e14df983b6b29.json b/deployments/lightLink/solcInputs/ad34345aa73d96f52b3e14df983b6b29.json new file mode 100644 index 0000000..c2bd4dc --- /dev/null +++ b/deployments/lightLink/solcInputs/ad34345aa73d96f52b3e14df983b6b29.json @@ -0,0 +1,360 @@ +{ + "language": "Solidity", + "sources": { + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby disabling any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable2Step.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./Ownable.sol\";\n\n/**\n * @dev Contract module which provides access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership} and {acceptOwnership}.\n *\n * This module is used through inheritance. It will make available all functions\n * from parent (Ownable).\n */\nabstract contract Ownable2Step is Ownable {\n address private _pendingOwner;\n\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Returns the address of the pending owner.\n */\n function pendingOwner() public view virtual returns (address) {\n return _pendingOwner;\n }\n\n /**\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual override onlyOwner {\n _pendingOwner = newOwner;\n emit OwnershipTransferStarted(owner(), newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual override {\n delete _pendingOwner;\n super._transferOwnership(newOwner);\n }\n\n /**\n * @dev The new owner accepts the ownership transfer.\n */\n function acceptOwnership() public virtual {\n address sender = _msgSender();\n require(pendingOwner() == sender, \"Ownable2Step: caller is not the new owner\");\n _transferOwnership(sender);\n }\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC1271.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC1271 standard signature validation method for\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\n *\n * _Available since v4.1._\n */\ninterface IERC1271 {\n /**\n * @dev Should return whether the signature provided is valid for the provided data\n * @param hash Hash of the data to be signed\n * @param signature Signature byte array associated with _data\n */\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\n}\n" + }, + "@openzeppelin/contracts/security/ReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor() {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n _nonReentrantBefore();\n _;\n _nonReentrantAfter();\n }\n\n function _nonReentrantBefore() private {\n // On the first call to nonReentrant, _status will be _NOT_ENTERED\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n }\n\n function _nonReentrantAfter() private {\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Returns true if the reentrancy guard is currently set to \"entered\", which indicates there is a\n * `nonReentrant` function in the call stack.\n */\n function _reentrancyGuardEntered() internal view returns (bool) {\n return _status == _ENTERED;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/ERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/ERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC1155.sol\";\nimport \"./IERC1155Receiver.sol\";\nimport \"./extensions/IERC1155MetadataURI.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of the basic standard multi-token.\n * See https://eips.ethereum.org/EIPS/eip-1155\n * Originally based on code by Enjin: https://github.com/enjin/erc-1155\n *\n * _Available since v3.1._\n */\ncontract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {\n using Address for address;\n\n // Mapping from token ID to account balances\n mapping(uint256 => mapping(address => uint256)) private _balances;\n\n // Mapping from account to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json\n string private _uri;\n\n /**\n * @dev See {_setURI}.\n */\n constructor(string memory uri_) {\n _setURI(uri_);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return\n interfaceId == type(IERC1155).interfaceId ||\n interfaceId == type(IERC1155MetadataURI).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC1155MetadataURI-uri}.\n *\n * This implementation returns the same URI for *all* token types. It relies\n * on the token type ID substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * Clients calling this function must replace the `\\{id\\}` substring with the\n * actual token type ID.\n */\n function uri(uint256) public view virtual override returns (string memory) {\n return _uri;\n }\n\n /**\n * @dev See {IERC1155-balanceOf}.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {\n require(account != address(0), \"ERC1155: address zero is not a valid owner\");\n return _balances[id][account];\n }\n\n /**\n * @dev See {IERC1155-balanceOfBatch}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] memory accounts,\n uint256[] memory ids\n ) public view virtual override returns (uint256[] memory) {\n require(accounts.length == ids.length, \"ERC1155: accounts and ids length mismatch\");\n\n uint256[] memory batchBalances = new uint256[](accounts.length);\n\n for (uint256 i = 0; i < accounts.length; ++i) {\n batchBalances[i] = balanceOf(accounts[i], ids[i]);\n }\n\n return batchBalances;\n }\n\n /**\n * @dev See {IERC1155-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC1155-isApprovedForAll}.\n */\n function isApprovedForAll(address account, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[account][operator];\n }\n\n /**\n * @dev See {IERC1155-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n _safeTransferFrom(from, to, id, amount, data);\n }\n\n /**\n * @dev See {IERC1155-safeBatchTransferFrom}.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n _safeBatchTransferFrom(from, to, ids, amounts, data);\n }\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n\n emit TransferSingle(operator, from, to, id, amount);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n for (uint256 i = 0; i < ids.length; ++i) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n }\n\n emit TransferBatch(operator, from, to, ids, amounts);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\n\n _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);\n }\n\n /**\n * @dev Sets a new URI for all token types, by relying on the token type ID\n * substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * By this mechanism, any occurrence of the `\\{id\\}` substring in either the\n * URI or any of the amounts in the JSON file at said URI will be replaced by\n * clients with the token type ID.\n *\n * For example, the `https://token-cdn-domain/\\{id\\}.json` URI would be\n * interpreted by clients as\n * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`\n * for token type ID 0x4cce0.\n *\n * See {uri}.\n *\n * Because these URIs cannot be meaningfully represented by the {URI} event,\n * this function emits no events.\n */\n function _setURI(string memory newuri) internal virtual {\n _uri = newuri;\n }\n\n /**\n * @dev Creates `amount` tokens of token type `id`, and assigns them to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _mint(address to, uint256 id, uint256 amount, bytes memory data) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _balances[id][to] += amount;\n emit TransferSingle(operator, address(0), to, id, amount);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n for (uint256 i = 0; i < ids.length; i++) {\n _balances[ids[i]][to] += amounts[i];\n }\n\n emit TransferBatch(operator, address(0), to, ids, amounts);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);\n }\n\n /**\n * @dev Destroys `amount` tokens of token type `id` from `from`\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `from` must have at least `amount` tokens of token type `id`.\n */\n function _burn(address from, uint256 id, uint256 amount) internal virtual {\n require(from != address(0), \"ERC1155: burn from the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n\n emit TransferSingle(operator, from, address(0), id, amount);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n */\n function _burnBatch(address from, uint256[] memory ids, uint256[] memory amounts) internal virtual {\n require(from != address(0), \"ERC1155: burn from the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n\n for (uint256 i = 0; i < ids.length; i++) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n }\n\n emit TransferBatch(operator, from, address(0), ids, amounts);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {\n require(owner != operator, \"ERC1155: setting approval status for self\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning, as well as batched variants.\n *\n * The same hook is called on both single and batched variants. For single\n * transfers, the length of the `ids` and `amounts` arrays will be 1.\n *\n * Calling conditions (for each `id` and `amount` pair):\n *\n * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * of token type `id` will be transferred to `to`.\n * - When `from` is zero, `amount` tokens of token type `id` will be minted\n * for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n * will be burned.\n * - `from` and `to` are never both zero.\n * - `ids` and `amounts` have the same, non-zero length.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any token transfer. This includes minting\n * and burning, as well as batched variants.\n *\n * The same hook is called on both single and batched variants. For single\n * transfers, the length of the `id` and `amount` arrays will be 1.\n *\n * Calling conditions (for each `id` and `amount` pair):\n *\n * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * of token type `id` will be transferred to `to`.\n * - When `from` is zero, `amount` tokens of token type `id` will be minted\n * for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n * will be burned.\n * - `from` and `to` are never both zero.\n * - `ids` and `amounts` have the same, non-zero length.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {}\n\n function _doSafeTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155Receiver.onERC1155Received.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non-ERC1155Receiver implementer\");\n }\n }\n }\n\n function _doSafeBatchTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (\n bytes4 response\n ) {\n if (response != IERC1155Receiver.onERC1155BatchReceived.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non-ERC1155Receiver implementer\");\n }\n }\n }\n\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {\n uint256[] memory array = new uint256[](1);\n array[0] = element;\n\n return array;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC1155.sol\";\n\n/**\n * @dev Interface of the optional ERC1155MetadataExtension interface, as defined\n * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155MetadataURI is IERC1155 {\n /**\n * @dev Returns the URI for token type `id`.\n *\n * If the `\\{id\\}` substring is present in the URI, it must be replaced by\n * clients with the actual token type ID.\n */\n function uri(uint256 id) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155 is IERC165 {\n /**\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n */\n event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);\n\n /**\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n * transfers.\n */\n event TransferBatch(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\n\n /**\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n * `approved`.\n */\n event ApprovalForAll(address indexed account, address indexed operator, bool approved);\n\n /**\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n *\n * If an {URI} event was emitted for `id`, the standard\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n * returned by {IERC1155MetadataURI-uri}.\n */\n event URI(string value, uint256 indexed id);\n\n /**\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) external view returns (uint256);\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] calldata accounts,\n uint256[] calldata ids\n ) external view returns (uint256[] memory);\n\n /**\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n *\n * Emits an {ApprovalForAll} event.\n *\n * Requirements:\n *\n * - `operator` cannot be the caller.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n *\n * See {setApprovalForAll}.\n */\n function isApprovedForAll(address account, address operator) external view returns (bool);\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155Receiver is IERC165 {\n /**\n * @dev Handles the receipt of a single ERC1155 token type. This function is\n * called at the end of a `safeTransferFrom` after the balance has been updated.\n *\n * NOTE: To accept the transfer, this must return\n * `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n * (i.e. 0xf23a6e61, or its own function selector).\n *\n * @param operator The address which initiated the transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param id The ID of the token being transferred\n * @param value The amount of tokens being transferred\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n ) external returns (bytes4);\n\n /**\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\n * is called at the end of a `safeBatchTransferFrom` after the balances have\n * been updated.\n *\n * NOTE: To accept the transfer(s), this must return\n * `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n * (i.e. 0xbc197c81, or its own function selector).\n *\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the default value returned by this function, unless\n * it's overridden.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(address from, address to, uint256 amount) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\n // decrementing then incrementing.\n _balances[to] += amount;\n }\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n unchecked {\n // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\n _balances[account] += amount;\n }\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n // Overflow not possible: amount <= accountBalance <= totalSupply.\n _totalSupply -= amount;\n }\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\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" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` 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 amount) 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 `amount` as the allowance of `spender` over the 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 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` 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 amount) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/ERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721.sol\";\nimport \"./IERC721Receiver.sol\";\nimport \"./extensions/IERC721Metadata.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/Strings.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\n using Address for address;\n using Strings for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\n\n // Mapping from token ID to approved address\n mapping(uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return\n interfaceId == type(IERC721).interfaceId ||\n interfaceId == type(IERC721Metadata).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _ownerOf(tokenId);\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token owner or approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n _requireMinted(tokenId);\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n _safeTransfer(from, to, tokenId, data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(address from, address to, uint256 tokenId, bytes memory data) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist\n */\n function _ownerOf(uint256 tokenId) internal view virtual returns (address) {\n return _owners[tokenId];\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _ownerOf(tokenId) != address(0);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n address owner = ERC721.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(address to, uint256 tokenId, bytes memory data) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId, 1);\n\n // Check that tokenId was not minted by `_beforeTokenTransfer` hook\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n unchecked {\n // Will not overflow unless all 2**256 token ids are minted to the same owner.\n // Given that tokens are minted one by one, it is impossible in practice that\n // this ever happens. Might change if we allow batch minting.\n // The ERC fails to describe this case.\n _balances[to] += 1;\n }\n\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(address(0), to, tokenId, 1);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n * This is an internal function that does not check if the sender is authorized to operate on the token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId, 1);\n\n // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook\n owner = ERC721.ownerOf(tokenId);\n\n // Clear approvals\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // Cannot overflow, as that would require more tokens to be burned/transferred\n // out than the owner initially received through minting and transferring in.\n _balances[owner] -= 1;\n }\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(owner, address(0), tokenId, 1);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(address from, address to, uint256 tokenId) internal virtual {\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId, 1);\n\n // Check that tokenId was not transferred by `_beforeTokenTransfer` hook\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n\n // Clear approvals from the previous owner\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // `_balances[from]` cannot overflow for the same reason as described in `_burn`:\n // `from`'s balance is the number of token held, which is at least one before the current\n // transfer.\n // `_balances[to]` could overflow in the conditions described in `_mint`. That would require\n // all 2**256 token ids to be minted, which in practice is impossible.\n _balances[from] -= 1;\n _balances[to] += 1;\n }\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId, 1);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721Receiver.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`.\n * - When `from` is zero, the tokens will be minted for `to`.\n * - When `to` is zero, ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}\n\n /**\n * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`.\n * - When `from` is zero, the tokens were minted for `to`.\n * - When `to` is zero, ``from``'s tokens were burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}\n\n /**\n * @dev Unsafe write access to the balances, used by extensions that \"mint\" tokens using an {ownerOf} override.\n *\n * WARNING: Anyone calling this MUST ensure that the balances remain consistent with the ownership. The invariant\n * being that for any address `a` the value returned by `balanceOf(a)` must be equal to the number of tokens such\n * that `ownerOf(tokenId)` is `a`.\n */\n // solhint-disable-next-line func-name-mixedcase\n function __unsafe_increaseBalance(address account, uint256 amount) internal {\n _balances[account] += amount;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721Receiver {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/ERC777.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC777/ERC777.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC777.sol\";\nimport \"./IERC777Recipient.sol\";\nimport \"./IERC777Sender.sol\";\nimport \"../ERC20/IERC20.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/introspection/IERC1820Registry.sol\";\n\n/**\n * @dev Implementation of the {IERC777} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n *\n * Support for ERC20 is included in this contract, as specified by the EIP: both\n * the ERC777 and ERC20 interfaces can be safely used when interacting with it.\n * Both {IERC777-Sent} and {IERC20-Transfer} events are emitted on token\n * movements.\n *\n * Additionally, the {IERC777-granularity} value is hard-coded to `1`, meaning that there\n * are no special restrictions in the amount of tokens that created, moved, or\n * destroyed. This makes integration with ERC20 applications seamless.\n *\n * CAUTION: This file is deprecated as of v4.9 and will be removed in the next major release.\n */\ncontract ERC777 is Context, IERC777, IERC20 {\n using Address for address;\n\n IERC1820Registry internal constant _ERC1820_REGISTRY = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n mapping(address => uint256) private _balances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n bytes32 private constant _TOKENS_SENDER_INTERFACE_HASH = keccak256(\"ERC777TokensSender\");\n bytes32 private constant _TOKENS_RECIPIENT_INTERFACE_HASH = keccak256(\"ERC777TokensRecipient\");\n\n // This isn't ever read from - it's only used to respond to the defaultOperators query.\n address[] private _defaultOperatorsArray;\n\n // Immutable, but accounts may revoke them (tracked in __revokedDefaultOperators).\n mapping(address => bool) private _defaultOperators;\n\n // For each account, a mapping of its operators and revoked default operators.\n mapping(address => mapping(address => bool)) private _operators;\n mapping(address => mapping(address => bool)) private _revokedDefaultOperators;\n\n // ERC20-allowances\n mapping(address => mapping(address => uint256)) private _allowances;\n\n /**\n * @dev `defaultOperators` may be an empty array.\n */\n constructor(string memory name_, string memory symbol_, address[] memory defaultOperators_) {\n _name = name_;\n _symbol = symbol_;\n\n _defaultOperatorsArray = defaultOperators_;\n for (uint256 i = 0; i < defaultOperators_.length; i++) {\n _defaultOperators[defaultOperators_[i]] = true;\n }\n\n // register interfaces\n _ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256(\"ERC777Token\"), address(this));\n _ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256(\"ERC20Token\"), address(this));\n }\n\n /**\n * @dev See {IERC777-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC777-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {ERC20-decimals}.\n *\n * Always returns 18, as per the\n * [ERC777 EIP](https://eips.ethereum.org/EIPS/eip-777#backward-compatibility).\n */\n function decimals() public pure virtual returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC777-granularity}.\n *\n * This implementation always returns `1`.\n */\n function granularity() public view virtual override returns (uint256) {\n return 1;\n }\n\n /**\n * @dev See {IERC777-totalSupply}.\n */\n function totalSupply() public view virtual override(IERC20, IERC777) returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev Returns the amount of tokens owned by an account (`tokenHolder`).\n */\n function balanceOf(address tokenHolder) public view virtual override(IERC20, IERC777) returns (uint256) {\n return _balances[tokenHolder];\n }\n\n /**\n * @dev See {IERC777-send}.\n *\n * Also emits a {IERC20-Transfer} event for ERC20 compatibility.\n */\n function send(address recipient, uint256 amount, bytes memory data) public virtual override {\n _send(_msgSender(), recipient, amount, data, \"\", true);\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Unlike `send`, `recipient` is _not_ required to implement the {IERC777Recipient}\n * interface if it is a contract.\n *\n * Also emits a {Sent} event.\n */\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n _send(_msgSender(), recipient, amount, \"\", \"\", false);\n return true;\n }\n\n /**\n * @dev See {IERC777-burn}.\n *\n * Also emits a {IERC20-Transfer} event for ERC20 compatibility.\n */\n function burn(uint256 amount, bytes memory data) public virtual override {\n _burn(_msgSender(), amount, data, \"\");\n }\n\n /**\n * @dev See {IERC777-isOperatorFor}.\n */\n function isOperatorFor(address operator, address tokenHolder) public view virtual override returns (bool) {\n return\n operator == tokenHolder ||\n (_defaultOperators[operator] && !_revokedDefaultOperators[tokenHolder][operator]) ||\n _operators[tokenHolder][operator];\n }\n\n /**\n * @dev See {IERC777-authorizeOperator}.\n */\n function authorizeOperator(address operator) public virtual override {\n require(_msgSender() != operator, \"ERC777: authorizing self as operator\");\n\n if (_defaultOperators[operator]) {\n delete _revokedDefaultOperators[_msgSender()][operator];\n } else {\n _operators[_msgSender()][operator] = true;\n }\n\n emit AuthorizedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-revokeOperator}.\n */\n function revokeOperator(address operator) public virtual override {\n require(operator != _msgSender(), \"ERC777: revoking self as operator\");\n\n if (_defaultOperators[operator]) {\n _revokedDefaultOperators[_msgSender()][operator] = true;\n } else {\n delete _operators[_msgSender()][operator];\n }\n\n emit RevokedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-defaultOperators}.\n */\n function defaultOperators() public view virtual override returns (address[] memory) {\n return _defaultOperatorsArray;\n }\n\n /**\n * @dev See {IERC777-operatorSend}.\n *\n * Emits {Sent} and {IERC20-Transfer} events.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes memory data,\n bytes memory operatorData\n ) public virtual override {\n require(isOperatorFor(_msgSender(), sender), \"ERC777: caller is not an operator for holder\");\n _send(sender, recipient, amount, data, operatorData, true);\n }\n\n /**\n * @dev See {IERC777-operatorBurn}.\n *\n * Emits {Burned} and {IERC20-Transfer} events.\n */\n function operatorBurn(\n address account,\n uint256 amount,\n bytes memory data,\n bytes memory operatorData\n ) public virtual override {\n require(isOperatorFor(_msgSender(), account), \"ERC777: caller is not an operator for holder\");\n _burn(account, amount, data, operatorData);\n }\n\n /**\n * @dev See {IERC20-allowance}.\n *\n * Note that operator and allowance concepts are orthogonal: operators may\n * not have allowance, and accounts with allowance may not be operators\n * themselves.\n */\n function allowance(address holder, address spender) public view virtual override returns (uint256) {\n return _allowances[holder][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Note that accounts cannot have allowance issued by their operators.\n */\n function approve(address spender, uint256 value) public virtual override returns (bool) {\n address holder = _msgSender();\n _approve(holder, spender, value);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Note that operator and allowance concepts are orthogonal: operators cannot\n * call `transferFrom` (unless they have allowance), and accounts with\n * allowance cannot call `operatorSend` (unless they are operators).\n *\n * Emits {Sent}, {IERC20-Transfer} and {IERC20-Approval} events.\n */\n function transferFrom(address holder, address recipient, uint256 amount) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(holder, spender, amount);\n _send(holder, recipient, amount, \"\", \"\", false);\n return true;\n }\n\n /**\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with the caller address as the `operator` and with\n * `userData` and `operatorData`.\n *\n * See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits {Minted} and {IERC20-Transfer} events.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - if `account` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function _mint(address account, uint256 amount, bytes memory userData, bytes memory operatorData) internal virtual {\n _mint(account, amount, userData, operatorData, true);\n }\n\n /**\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * If `requireReceptionAck` is set to true, and if a send hook is\n * registered for `account`, the corresponding function will be called with\n * `operator`, `data` and `operatorData`.\n *\n * See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits {Minted} and {IERC20-Transfer} events.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - if `account` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function _mint(\n address account,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) internal virtual {\n require(account != address(0), \"ERC777: mint to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), account, amount);\n\n // Update state variables\n _totalSupply += amount;\n _balances[account] += amount;\n\n _callTokensReceived(operator, address(0), account, amount, userData, operatorData, requireReceptionAck);\n\n emit Minted(operator, account, amount, userData, operatorData);\n emit Transfer(address(0), account, amount);\n }\n\n /**\n * @dev Send tokens\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _send(\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) internal virtual {\n require(from != address(0), \"ERC777: transfer from the zero address\");\n require(to != address(0), \"ERC777: transfer to the zero address\");\n\n address operator = _msgSender();\n\n _callTokensToSend(operator, from, to, amount, userData, operatorData);\n\n _move(operator, from, to, amount, userData, operatorData);\n\n _callTokensReceived(operator, from, to, amount, userData, operatorData, requireReceptionAck);\n }\n\n /**\n * @dev Burn tokens\n * @param from address token holder address\n * @param amount uint256 amount of tokens to burn\n * @param data bytes extra information provided by the token holder\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _burn(address from, uint256 amount, bytes memory data, bytes memory operatorData) internal virtual {\n require(from != address(0), \"ERC777: burn from the zero address\");\n\n address operator = _msgSender();\n\n _callTokensToSend(operator, from, address(0), amount, data, operatorData);\n\n _beforeTokenTransfer(operator, from, address(0), amount);\n\n // Update state variables\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC777: burn amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Burned(operator, from, amount, data, operatorData);\n emit Transfer(from, address(0), amount);\n }\n\n function _move(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n ) private {\n _beforeTokenTransfer(operator, from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC777: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Sent(operator, from, to, amount, userData, operatorData);\n emit Transfer(from, to, amount);\n }\n\n /**\n * @dev See {ERC20-_approve}.\n *\n * Note that accounts cannot have allowance issued by their operators.\n */\n function _approve(address holder, address spender, uint256 value) internal virtual {\n require(holder != address(0), \"ERC777: approve from the zero address\");\n require(spender != address(0), \"ERC777: approve to the zero address\");\n\n _allowances[holder][spender] = value;\n emit Approval(holder, spender, value);\n }\n\n /**\n * @dev Call from.tokensToSend() if the interface is registered\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _callTokensToSend(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n ) private {\n address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(from, _TOKENS_SENDER_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Sender(implementer).tokensToSend(operator, from, to, amount, userData, operatorData);\n }\n }\n\n /**\n * @dev Call to.tokensReceived() if the interface is registered. Reverts if the recipient is a contract but\n * tokensReceived() was not registered for the recipient\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _callTokensReceived(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) private {\n address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(to, _TOKENS_RECIPIENT_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Recipient(implementer).tokensReceived(operator, from, to, amount, userData, operatorData);\n } else if (requireReceptionAck) {\n require(!to.isContract(), \"ERC777: token recipient contract has no implementer for ERC777TokensRecipient\");\n }\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {IERC20-Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC777: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes\n * calls to {send}, {transfer}, {operatorSend}, {transferFrom}, minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be to transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address operator, address from, address to, uint256 amount) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC777/IERC777.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777Token standard as defined in the EIP.\n *\n * This contract uses the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 registry standard] to let\n * token holders and recipients react to token movements by using setting implementers\n * for the associated interfaces in said registry. See {IERC1820Registry} and\n * {ERC1820Implementer}.\n */\ninterface IERC777 {\n /**\n * @dev Emitted when `amount` tokens are created by `operator` and assigned to `to`.\n *\n * Note that some additional user `data` and `operatorData` can be logged in the event.\n */\n event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);\n\n /**\n * @dev Emitted when `operator` destroys `amount` tokens from `account`.\n *\n * Note that some additional user `data` and `operatorData` can be logged in the event.\n */\n event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);\n\n /**\n * @dev Emitted when `operator` is made operator for `tokenHolder`.\n */\n event AuthorizedOperator(address indexed operator, address indexed tokenHolder);\n\n /**\n * @dev Emitted when `operator` is revoked its operator status for `tokenHolder`.\n */\n event RevokedOperator(address indexed operator, address indexed tokenHolder);\n\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, usually a shorter version of the\n * name.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the smallest part of the token that is not divisible. This\n * means all token operations (creation, movement and destruction) must have\n * amounts that are a multiple of this number.\n *\n * For most token contracts, this value will equal 1.\n */\n function granularity() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by an account (`owner`).\n */\n function balanceOf(address owner) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * If send or receive hooks are registered for the caller and `recipient`,\n * the corresponding functions will be called with `data` and empty\n * `operatorData`. See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits a {Sent} event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function send(address recipient, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Destroys `amount` tokens from the caller's account, reducing the\n * total supply.\n *\n * If a send hook is registered for the caller, the corresponding function\n * will be called with `data` and empty `operatorData`. See {IERC777Sender}.\n *\n * Emits a {Burned} event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n */\n function burn(uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Returns true if an account is an operator of `tokenHolder`.\n * Operators can send and burn tokens on behalf of their owners. All\n * accounts are their own operator.\n *\n * See {operatorSend} and {operatorBurn}.\n */\n function isOperatorFor(address operator, address tokenHolder) external view returns (bool);\n\n /**\n * @dev Make an account an operator of the caller.\n *\n * See {isOperatorFor}.\n *\n * Emits an {AuthorizedOperator} event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function authorizeOperator(address operator) external;\n\n /**\n * @dev Revoke an account's operator status for the caller.\n *\n * See {isOperatorFor} and {defaultOperators}.\n *\n * Emits a {RevokedOperator} event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function revokeOperator(address operator) external;\n\n /**\n * @dev Returns the list of default operators. These accounts are operators\n * for all token holders, even if {authorizeOperator} was never called on\n * them.\n *\n * This list is immutable, but individual holders may revoke these via\n * {revokeOperator}, in which case {isOperatorFor} will return false.\n */\n function defaultOperators() external view returns (address[] memory);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must\n * be an operator of `sender`.\n *\n * If send or receive hooks are registered for `sender` and `recipient`,\n * the corresponding functions will be called with `data` and\n * `operatorData`. See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits a {Sent} event.\n *\n * Requirements\n *\n * - `sender` cannot be the zero address.\n * - `sender` must have at least `amount` tokens.\n * - the caller must be an operator for `sender`.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes calldata data,\n bytes calldata operatorData\n ) external;\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the total supply.\n * The caller must be an operator of `account`.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with `data` and `operatorData`. See {IERC777Sender}.\n *\n * Emits a {Burned} event.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n * - the caller must be an operator for `account`.\n */\n function operatorBurn(address account, uint256 amount, bytes calldata data, bytes calldata operatorData) external;\n\n event Sent(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes data,\n bytes operatorData\n );\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\n *\n * Accounts can be notified of {IERC777} tokens being sent to them by having a\n * contract implement this interface (contract holders can be their own\n * implementer) and registering it on the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\n *\n * See {IERC1820Registry} and {ERC1820Implementer}.\n */\ninterface IERC777Recipient {\n /**\n * @dev Called by an {IERC777} token contract whenever tokens are being\n * moved or created into a registered account (`to`). The type of operation\n * is conveyed by `from` being the zero address or not.\n *\n * This call occurs _after_ the token contract's state is updated, so\n * {IERC777-balanceOf}, etc., can be used to query the post-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensReceived(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777Sender.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Sender.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777TokensSender standard as defined in the EIP.\n *\n * {IERC777} Token holders can be notified of operations performed on their\n * tokens by having a contract implement this interface (contract holders can be\n * their own implementer) and registering it on the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\n *\n * See {IERC1820Registry} and {ERC1820Implementer}.\n */\ninterface IERC777Sender {\n /**\n * @dev Called by an {IERC777} token contract whenever a registered holder's\n * (`from`) tokens are about to be moved or destroyed. The type of operation\n * is conveyed by `to` being the zero address or not.\n *\n * This call occurs _before_ the token contract's state is updated, so\n * {IERC777-balanceOf}, etc., can be used to query the pre-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensToSend(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n *\n * Furthermore, `isContract` will also return true if the target contract within\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n * which only has an effect at the end of a transaction.\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Counters.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary Counters {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/ECDSA.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Strings.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV // Deprecated in v4.8\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n /// @solidity memory-safe-assembly\n assembly {\n mstore(0x00, \"\\x19Ethereum Signed Message:\\n32\")\n mstore(0x1c, hash)\n message := keccak256(0x00, 0x3c)\n }\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\n /// @solidity memory-safe-assembly\n assembly {\n let ptr := mload(0x40)\n mstore(ptr, \"\\x19\\x01\")\n mstore(add(ptr, 0x02), domainSeparator)\n mstore(add(ptr, 0x22), structHash)\n data := keccak256(ptr, 0x42)\n }\n }\n\n /**\n * @dev Returns an Ethereum Signed Data with intended validator, created from a\n * `validator` and `data` according to the version 0 of EIP-191.\n *\n * See {recover}.\n */\n function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x00\", validator, data));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/SignatureChecker.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSA.sol\";\nimport \"../../interfaces/IERC1271.sol\";\n\n/**\n * @dev Signature verification helper that can be used instead of `ECDSA.recover` to seamlessly support both ECDSA\n * signatures from externally owned accounts (EOAs) as well as ERC1271 signatures from smart contract wallets like\n * Argent and Gnosis Safe.\n *\n * _Available since v4.1._\n */\nlibrary SignatureChecker {\n /**\n * @dev Checks if a signature is valid for a given signer and data hash. If the signer is a smart contract, the\n * signature is validated against that smart contract using ERC1271, otherwise it's validated using `ECDSA.recover`.\n *\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\n */\n function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature) internal view returns (bool) {\n (address recovered, ECDSA.RecoverError error) = ECDSA.tryRecover(hash, signature);\n return\n (error == ECDSA.RecoverError.NoError && recovered == signer) ||\n isValidERC1271SignatureNow(signer, hash, signature);\n }\n\n /**\n * @dev Checks if a signature is valid for a given signer and data hash. The signature is validated\n * against the signer smart contract using ERC1271.\n *\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\n */\n function isValidERC1271SignatureNow(\n address signer,\n bytes32 hash,\n bytes memory signature\n ) internal view returns (bool) {\n (bool success, bytes memory result) = signer.staticcall(\n abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, signature)\n );\n return (success &&\n result.length >= 32 &&\n abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/ERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165 is IERC165 {\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165).interfaceId;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC1820Registry.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/introspection/IERC1820Registry.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the global ERC1820 Registry, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register\n * implementers for interfaces in this registry, as well as query support.\n *\n * Implementers may be shared by multiple accounts, and can also implement more\n * than a single interface for each account. Contracts can implement interfaces\n * for themselves, but externally-owned accounts (EOA) must delegate this to a\n * contract.\n *\n * {IERC165} interfaces can also be queried via the registry.\n *\n * For an in-depth explanation and source code analysis, see the EIP text.\n */\ninterface IERC1820Registry {\n event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer);\n\n event ManagerChanged(address indexed account, address indexed newManager);\n\n /**\n * @dev Sets `newManager` as the manager for `account`. A manager of an\n * account is able to set interface implementers for it.\n *\n * By default, each account is its own manager. Passing a value of `0x0` in\n * `newManager` will reset the manager to this initial state.\n *\n * Emits a {ManagerChanged} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `account`.\n */\n function setManager(address account, address newManager) external;\n\n /**\n * @dev Returns the manager for `account`.\n *\n * See {setManager}.\n */\n function getManager(address account) external view returns (address);\n\n /**\n * @dev Sets the `implementer` contract as ``account``'s implementer for\n * `interfaceHash`.\n *\n * `account` being the zero address is an alias for the caller's address.\n * The zero address can also be used in `implementer` to remove an old one.\n *\n * See {interfaceHash} to learn how these are created.\n *\n * Emits an {InterfaceImplementerSet} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `account`.\n * - `interfaceHash` must not be an {IERC165} interface id (i.e. it must not\n * end in 28 zeroes).\n * - `implementer` must implement {IERC1820Implementer} and return true when\n * queried for support, unless `implementer` is the caller. See\n * {IERC1820Implementer-canImplementInterfaceForAddress}.\n */\n function setInterfaceImplementer(address account, bytes32 _interfaceHash, address implementer) external;\n\n /**\n * @dev Returns the implementer of `interfaceHash` for `account`. If no such\n * implementer is registered, returns the zero address.\n *\n * If `interfaceHash` is an {IERC165} interface id (i.e. it ends with 28\n * zeroes), `account` will be queried for support of it.\n *\n * `account` being the zero address is an alias for the caller's address.\n */\n function getInterfaceImplementer(address account, bytes32 _interfaceHash) external view returns (address);\n\n /**\n * @dev Returns the interface hash for an `interfaceName`, as defined in the\n * corresponding\n * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP].\n */\n function interfaceHash(string calldata interfaceName) external pure returns (bytes32);\n\n /**\n * @notice Updates the cache with whether the contract implements an ERC165 interface or not.\n * @param account Address of the contract for which to update the cache.\n * @param interfaceId ERC165 interface for which to update the cache.\n */\n function updateERC165Cache(address account, bytes4 interfaceId) external;\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not.\n * If the result is not cached a direct lookup on the contract address is performed.\n * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling\n * {updateERC165Cache} with the contract address.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool);\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not without using or updating the cache.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/math/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\n // The surrounding unchecked block does not change this fact.\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1, \"Math: mulDiv overflow\");\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n //\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n //\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n //\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1 << (log2(a) >> 1);\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = sqrt(a);\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 2, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 128;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 64;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 32;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 16;\n }\n if (value >> 8 > 0) {\n value >>= 8;\n result += 8;\n }\n if (value >> 4 > 0) {\n value >>= 4;\n result += 4;\n }\n if (value >> 2 > 0) {\n value >>= 2;\n result += 2;\n }\n if (value >> 1 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log2(value);\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 10, rounded down, of a positive value.\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 + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 256, rounded down, of a positive value.\n * Returns 0 if given 0.\n *\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n */\n function log256(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 16;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 8;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 4;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 2;\n }\n if (value >> 8 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log256(value);\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/SafeCast.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCast {\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 * _Available since v4.7._\n */\n function toUint248(uint256 value) internal pure returns (uint248) {\n require(value <= type(uint248).max, \"SafeCast: value doesn't fit in 248 bits\");\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 * _Available since v4.7._\n */\n function toUint240(uint256 value) internal pure returns (uint240) {\n require(value <= type(uint240).max, \"SafeCast: value doesn't fit in 240 bits\");\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 * _Available since v4.7._\n */\n function toUint232(uint256 value) internal pure returns (uint232) {\n require(value <= type(uint232).max, \"SafeCast: value doesn't fit in 232 bits\");\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 * _Available since v4.2._\n */\n function toUint224(uint256 value) internal pure returns (uint224) {\n require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\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 * _Available since v4.7._\n */\n function toUint216(uint256 value) internal pure returns (uint216) {\n require(value <= type(uint216).max, \"SafeCast: value doesn't fit in 216 bits\");\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 * _Available since v4.7._\n */\n function toUint208(uint256 value) internal pure returns (uint208) {\n require(value <= type(uint208).max, \"SafeCast: value doesn't fit in 208 bits\");\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 * _Available since v4.7._\n */\n function toUint200(uint256 value) internal pure returns (uint200) {\n require(value <= type(uint200).max, \"SafeCast: value doesn't fit in 200 bits\");\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 * _Available since v4.7._\n */\n function toUint192(uint256 value) internal pure returns (uint192) {\n require(value <= type(uint192).max, \"SafeCast: value doesn't fit in 192 bits\");\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 * _Available since v4.7._\n */\n function toUint184(uint256 value) internal pure returns (uint184) {\n require(value <= type(uint184).max, \"SafeCast: value doesn't fit in 184 bits\");\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 * _Available since v4.7._\n */\n function toUint176(uint256 value) internal pure returns (uint176) {\n require(value <= type(uint176).max, \"SafeCast: value doesn't fit in 176 bits\");\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 * _Available since v4.7._\n */\n function toUint168(uint256 value) internal pure returns (uint168) {\n require(value <= type(uint168).max, \"SafeCast: value doesn't fit in 168 bits\");\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 * _Available since v4.7._\n */\n function toUint160(uint256 value) internal pure returns (uint160) {\n require(value <= type(uint160).max, \"SafeCast: value doesn't fit in 160 bits\");\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 * _Available since v4.7._\n */\n function toUint152(uint256 value) internal pure returns (uint152) {\n require(value <= type(uint152).max, \"SafeCast: value doesn't fit in 152 bits\");\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 * _Available since v4.7._\n */\n function toUint144(uint256 value) internal pure returns (uint144) {\n require(value <= type(uint144).max, \"SafeCast: value doesn't fit in 144 bits\");\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 * _Available since v4.7._\n */\n function toUint136(uint256 value) internal pure returns (uint136) {\n require(value <= type(uint136).max, \"SafeCast: value doesn't fit in 136 bits\");\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 * _Available since v2.5._\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\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 * _Available since v4.7._\n */\n function toUint120(uint256 value) internal pure returns (uint120) {\n require(value <= type(uint120).max, \"SafeCast: value doesn't fit in 120 bits\");\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 * _Available since v4.7._\n */\n function toUint112(uint256 value) internal pure returns (uint112) {\n require(value <= type(uint112).max, \"SafeCast: value doesn't fit in 112 bits\");\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 * _Available since v4.7._\n */\n function toUint104(uint256 value) internal pure returns (uint104) {\n require(value <= type(uint104).max, \"SafeCast: value doesn't fit in 104 bits\");\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 * _Available since v4.2._\n */\n function toUint96(uint256 value) internal pure returns (uint96) {\n require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\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 * _Available since v4.7._\n */\n function toUint88(uint256 value) internal pure returns (uint88) {\n require(value <= type(uint88).max, \"SafeCast: value doesn't fit in 88 bits\");\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 * _Available since v4.7._\n */\n function toUint80(uint256 value) internal pure returns (uint80) {\n require(value <= type(uint80).max, \"SafeCast: value doesn't fit in 80 bits\");\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 * _Available since v4.7._\n */\n function toUint72(uint256 value) internal pure returns (uint72) {\n require(value <= type(uint72).max, \"SafeCast: value doesn't fit in 72 bits\");\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 * _Available since v2.5._\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\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 * _Available since v4.7._\n */\n function toUint56(uint256 value) internal pure returns (uint56) {\n require(value <= type(uint56).max, \"SafeCast: value doesn't fit in 56 bits\");\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 * _Available since v4.7._\n */\n function toUint48(uint256 value) internal pure returns (uint48) {\n require(value <= type(uint48).max, \"SafeCast: value doesn't fit in 48 bits\");\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 * _Available since v4.7._\n */\n function toUint40(uint256 value) internal pure returns (uint40) {\n require(value <= type(uint40).max, \"SafeCast: value doesn't fit in 40 bits\");\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 * _Available since v2.5._\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\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 * _Available since v4.7._\n */\n function toUint24(uint256 value) internal pure returns (uint24) {\n require(value <= type(uint24).max, \"SafeCast: value doesn't fit in 24 bits\");\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 * _Available since v2.5._\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\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 * _Available since v2.5._\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\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 * _Available since v3.0._\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\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 * _Available since v4.7._\n */\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\n downcasted = int248(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 248 bits\");\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 * _Available since v4.7._\n */\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\n downcasted = int240(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 240 bits\");\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 * _Available since v4.7._\n */\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\n downcasted = int232(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 232 bits\");\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 * _Available since v4.7._\n */\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\n downcasted = int224(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 224 bits\");\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 * _Available since v4.7._\n */\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\n downcasted = int216(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 216 bits\");\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 * _Available since v4.7._\n */\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\n downcasted = int208(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 208 bits\");\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 * _Available since v4.7._\n */\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\n downcasted = int200(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 200 bits\");\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 * _Available since v4.7._\n */\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\n downcasted = int192(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 192 bits\");\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 * _Available since v4.7._\n */\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\n downcasted = int184(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 184 bits\");\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 * _Available since v4.7._\n */\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\n downcasted = int176(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 176 bits\");\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 * _Available since v4.7._\n */\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\n downcasted = int168(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 168 bits\");\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 * _Available since v4.7._\n */\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\n downcasted = int160(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 160 bits\");\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 * _Available since v4.7._\n */\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\n downcasted = int152(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 152 bits\");\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 * _Available since v4.7._\n */\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\n downcasted = int144(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 144 bits\");\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 * _Available since v4.7._\n */\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\n downcasted = int136(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 136 bits\");\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 * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\n downcasted = int128(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 128 bits\");\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 * _Available since v4.7._\n */\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\n downcasted = int120(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 120 bits\");\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 * _Available since v4.7._\n */\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\n downcasted = int112(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 112 bits\");\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 * _Available since v4.7._\n */\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\n downcasted = int104(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 104 bits\");\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 * _Available since v4.7._\n */\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\n downcasted = int96(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 96 bits\");\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 * _Available since v4.7._\n */\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\n downcasted = int88(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 88 bits\");\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 * _Available since v4.7._\n */\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\n downcasted = int80(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 80 bits\");\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 * _Available since v4.7._\n */\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\n downcasted = int72(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 72 bits\");\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 * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\n downcasted = int64(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 64 bits\");\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 * _Available since v4.7._\n */\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\n downcasted = int56(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 56 bits\");\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 * _Available since v4.7._\n */\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\n downcasted = int48(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 48 bits\");\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 * _Available since v4.7._\n */\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\n downcasted = int40(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 40 bits\");\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 * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\n downcasted = int32(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 32 bits\");\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 * _Available since v4.7._\n */\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\n downcasted = int24(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 24 bits\");\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 * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\n downcasted = int16(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 16 bits\");\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 * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\n downcasted = int8(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 8 bits\");\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 * _Available since v3.0._\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 require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/SignedMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard signed math utilities missing in the Solidity language.\n */\nlibrary SignedMath {\n /**\n * @dev Returns the largest of two signed numbers.\n */\n function max(int256 a, int256 b) internal pure returns (int256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two signed numbers.\n */\n function min(int256 a, int256 b) internal pure returns (int256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two signed numbers without overflow.\n * The result is rounded towards zero.\n */\n function average(int256 a, int256 b) internal pure returns (int256) {\n // Formula from the book \"Hacker's Delight\"\n int256 x = (a & b) + ((a ^ b) >> 1);\n return x + (int256(uint256(x) >> 255) & (a ^ b));\n }\n\n /**\n * @dev Returns the absolute unsigned value of a signed value.\n */\n function abs(int256 n) internal pure returns (uint256) {\n unchecked {\n // must be unchecked in order to support `n = type(int256).min`\n return uint256(n >= 0 ? n : -n);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/Math.sol\";\nimport \"./math/SignedMath.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n unchecked {\n uint256 length = Math.log10(value) + 1;\n string memory buffer = new string(length);\n uint256 ptr;\n /// @solidity memory-safe-assembly\n assembly {\n ptr := add(buffer, add(32, length))\n }\n while (true) {\n ptr--;\n /// @solidity memory-safe-assembly\n assembly {\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n }\n value /= 10;\n if (value == 0) break;\n }\n return buffer;\n }\n }\n\n /**\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\n */\n function toString(int256 value) internal pure returns (string memory) {\n return string(abi.encodePacked(value < 0 ? \"-\" : \"\", toString(SignedMath.abs(value))));\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n unchecked {\n return toHexString(value, Math.log256(value) + 1);\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n\n /**\n * @dev Returns true if the two strings are equal.\n */\n function equal(string memory a, string memory b) internal pure returns (bool) {\n return keccak256(bytes(a)) == keccak256(bytes(b));\n }\n}\n" + }, + "contracts/aa-4337/core/BaseAccount.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-empty-blocks */\n\nimport \"../interfaces/IAccount.sol\";\nimport \"../interfaces/IEntryPoint.sol\";\nimport \"./Helpers.sol\";\n\n/**\n * Basic account implementation.\n * this contract provides the basic logic for implementing the IAccount interface - validateUserOp\n * specific account implementation should inherit it and provide the account-specific logic\n */\nabstract contract BaseAccount is IAccount {\n using UserOperationLib for UserOperation;\n\n //return value in case of signature failure, with no time-range.\n // equivalent to _packValidationData(true,0,0);\n uint256 internal constant SIG_VALIDATION_FAILED = 1;\n\n /**\n * Return the account nonce.\n * This method returns the next sequential nonce.\n * For a nonce of a specific key, use `entrypoint.getNonce(account, key)`\n */\n function getNonce() public view virtual returns (uint256) {\n return entryPoint().getNonce(address(this), 0);\n }\n\n /**\n * return the entryPoint used by this account.\n * subclass should return the current entryPoint used by this account.\n */\n function entryPoint() public view virtual returns (IEntryPoint);\n\n /**\n * Validate user's signature and nonce.\n * subclass doesn't need to override this method. Instead, it should override the specific internal validation methods.\n */\n function validateUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 missingAccountFunds\n ) external virtual override returns (uint256 validationData) {\n _requireFromEntryPoint();\n validationData = _validateSignature(userOp, userOpHash);\n _validateNonce(userOp.nonce);\n _payPrefund(missingAccountFunds);\n }\n\n /**\n * ensure the request comes from the known entrypoint.\n */\n function _requireFromEntryPoint() internal view virtual {\n require(\n msg.sender == address(entryPoint()),\n \"account: not from EntryPoint\"\n );\n }\n\n /**\n * validate the signature is valid for this message.\n * @param userOp validate the userOp.signature field\n * @param userOpHash convenient field: the hash of the request, to check the signature against\n * (also hashes the entrypoint and chain id)\n * @return validationData signature and time-range of this operation\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * If the account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function _validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) internal virtual returns (uint256 validationData);\n\n /**\n * Validate the nonce of the UserOperation.\n * This method may validate the nonce requirement of this account.\n * e.g.\n * To limit the nonce to use sequenced UserOps only (no \"out of order\" UserOps):\n * `require(nonce < type(uint64).max)`\n * For a hypothetical account that *requires* the nonce to be out-of-order:\n * `require(nonce & type(uint64).max == 0)`\n *\n * The actual nonce uniqueness is managed by the EntryPoint, and thus no other\n * action is needed by the account itself.\n *\n * @param nonce to validate\n *\n * solhint-disable-next-line no-empty-blocks\n */\n function _validateNonce(uint256 nonce) internal view virtual {}\n\n /**\n * sends to the entrypoint (msg.sender) the missing funds for this transaction.\n * subclass MAY override this method for better funds management\n * (e.g. send to the entryPoint more than the minimum required, so that in future transactions\n * it will not be required to send again)\n * @param missingAccountFunds the minimum value this method should send the entrypoint.\n * this value MAY be zero, in case there is enough deposit, or the userOp has a paymaster.\n */\n function _payPrefund(uint256 missingAccountFunds) internal virtual {\n if (missingAccountFunds != 0) {\n (bool success, ) = payable(msg.sender).call{\n value: missingAccountFunds,\n gas: type(uint256).max\n }(\"\");\n (success);\n //ignore failure (its EntryPoint's job to verify, not account.)\n }\n }\n}\n" + }, + "contracts/aa-4337/core/EntryPoint.sol": { + "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n\nimport \"../interfaces/IAccount.sol\";\nimport \"../interfaces/IPaymaster.sol\";\nimport \"../interfaces/IEntryPoint.sol\";\n\nimport \"../utils/Exec.sol\";\nimport \"./StakeManager.sol\";\nimport \"./SenderCreator.sol\";\nimport \"./Helpers.sol\";\nimport \"./NonceManager.sol\";\nimport \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\n\ncontract EntryPoint is\n IEntryPoint,\n StakeManager,\n NonceManager,\n ReentrancyGuard\n{\n using UserOperationLib for UserOperation;\n\n SenderCreator private immutable senderCreator = new SenderCreator();\n\n // internal value used during simulation: need to query aggregator.\n address private constant SIMULATE_FIND_AGGREGATOR = address(1);\n\n // marker for inner call revert on out of gas\n bytes32 private constant INNER_OUT_OF_GAS = hex\"deaddead\";\n\n uint256 private constant REVERT_REASON_MAX_LEN = 2048;\n\n /**\n * for simulation purposes, validateUserOp (and validatePaymasterUserOp) must return this value\n * in case of signature failure, instead of revert.\n */\n uint256 public constant SIG_VALIDATION_FAILED = 1;\n\n /**\n * compensate the caller's beneficiary address with the collected fees of all UserOperations.\n * @param beneficiary the address to receive the fees\n * @param amount amount to transfer.\n */\n function _compensate(address payable beneficiary, uint256 amount) internal {\n require(beneficiary != address(0), \"AA90 invalid beneficiary\");\n (bool success, ) = beneficiary.call{value: amount}(\"\");\n require(success, \"AA91 failed send to beneficiary\");\n }\n\n /**\n * execute a user op\n * @param opIndex index into the opInfo array\n * @param userOp the userOp to execute\n * @param opInfo the opInfo filled by validatePrepayment for this userOp.\n * @return collected the total amount this userOp paid.\n */\n function _executeUserOp(\n uint256 opIndex,\n UserOperation calldata userOp,\n UserOpInfo memory opInfo\n ) private returns (uint256 collected) {\n uint256 preGas = gasleft();\n bytes memory context = getMemoryBytesFromOffset(opInfo.contextOffset);\n\n try this.innerHandleOp(userOp.callData, opInfo, context) returns (\n uint256 _actualGasCost\n ) {\n collected = _actualGasCost;\n } catch {\n bytes32 innerRevertCode;\n assembly {\n returndatacopy(0, 0, 32)\n innerRevertCode := mload(0)\n }\n // handleOps was called with gas limit too low. abort entire bundle.\n if (innerRevertCode == INNER_OUT_OF_GAS) {\n //report paymaster, since if it is not deliberately caused by the bundler,\n // it must be a revert caused by paymaster.\n revert FailedOp(opIndex, \"AA95 out of gas\");\n }\n\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n collected = _handlePostOp(\n opIndex,\n IPaymaster.PostOpMode.postOpReverted,\n opInfo,\n context,\n actualGas\n );\n }\n }\n\n /**\n * Execute a batch of UserOperations.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(\n UserOperation[] calldata ops,\n address payable beneficiary\n ) public nonReentrant {\n uint256 opslen = ops.length;\n UserOpInfo[] memory opInfos = new UserOpInfo[](opslen);\n\n unchecked {\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[i];\n (\n uint256 validationData,\n uint256 pmValidationData\n ) = _validatePrepayment(i, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(\n i,\n validationData,\n pmValidationData,\n address(0)\n );\n }\n\n uint256 collected = 0;\n emit BeforeExecution();\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(i, ops[i], opInfos[i]);\n }\n\n _compensate(beneficiary, collected);\n } //unchecked\n }\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) public nonReentrant {\n uint256 opasLen = opsPerAggregator.length;\n uint256 totalOps = 0;\n for (uint256 i = 0; i < opasLen; i++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[i];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n //address(1) is special marker of \"signature error\"\n require(\n address(aggregator) != address(1),\n \"AA96 invalid aggregator\"\n );\n\n if (address(aggregator) != address(0)) {\n // solhint-disable-next-line no-empty-blocks\n try aggregator.validateSignatures(ops, opa.signature) {} catch {\n revert SignatureValidationFailed(address(aggregator));\n }\n }\n\n totalOps += ops.length;\n }\n\n UserOpInfo[] memory opInfos = new UserOpInfo[](totalOps);\n\n emit BeforeExecution();\n\n uint256 opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n uint256 opslen = ops.length;\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[opIndex];\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(opIndex, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(\n i,\n validationData,\n paymasterValidationData,\n address(aggregator)\n );\n opIndex++;\n }\n }\n\n uint256 collected = 0;\n opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n emit SignatureAggregatorChanged(address(opa.aggregator));\n UserOperation[] calldata ops = opa.userOps;\n uint256 opslen = ops.length;\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(opIndex, ops[i], opInfos[opIndex]);\n opIndex++;\n }\n }\n emit SignatureAggregatorChanged(address(0));\n\n _compensate(beneficiary, collected);\n }\n\n /// @inheritdoc IEntryPoint\n function simulateHandleOp(\n UserOperation calldata op,\n address target,\n bytes calldata targetCallData\n ) external override {\n UserOpInfo memory opInfo;\n _simulationOnlyValidations(op);\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(0, op, opInfo);\n ValidationData memory data = _intersectTimeRange(\n validationData,\n paymasterValidationData\n );\n\n numberMarker();\n uint256 paid = _executeUserOp(0, op, opInfo);\n numberMarker();\n bool targetSuccess;\n bytes memory targetResult;\n if (target != address(0)) {\n (targetSuccess, targetResult) = target.call(targetCallData);\n }\n revert ExecutionResult(\n opInfo.preOpGas,\n paid,\n data.validAfter,\n data.validUntil,\n targetSuccess,\n targetResult\n );\n }\n\n // A memory copy of UserOp static fields only.\n // Excluding: callData, initCode and signature. Replacing paymasterAndData with paymaster.\n struct MemoryUserOp {\n address sender;\n uint256 nonce;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n address paymaster;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n }\n\n struct UserOpInfo {\n MemoryUserOp mUserOp;\n bytes32 userOpHash;\n uint256 prefund;\n uint256 contextOffset;\n uint256 preOpGas;\n }\n\n /**\n * inner function to handle a UserOperation.\n * Must be declared \"external\" to open a call context, but it can only be called by handleOps.\n */\n function innerHandleOp(\n bytes memory callData,\n UserOpInfo memory opInfo,\n bytes calldata context\n ) external returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n require(msg.sender == address(this), \"AA92 internal call only\");\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n\n uint callGasLimit = mUserOp.callGasLimit;\n unchecked {\n // handleOps was called with gas limit too low. abort entire bundle.\n if (\n gasleft() < callGasLimit + mUserOp.verificationGasLimit + 5000\n ) {\n assembly {\n mstore(0, INNER_OUT_OF_GAS)\n revert(0, 32)\n }\n }\n }\n\n IPaymaster.PostOpMode mode = IPaymaster.PostOpMode.opSucceeded;\n if (callData.length > 0) {\n bool success = Exec.call(mUserOp.sender, 0, callData, callGasLimit);\n if (!success) {\n bytes memory result = Exec.getReturnData(REVERT_REASON_MAX_LEN);\n if (result.length > 0) {\n emit UserOperationRevertReason(\n opInfo.userOpHash,\n mUserOp.sender,\n mUserOp.nonce,\n result\n );\n }\n mode = IPaymaster.PostOpMode.opReverted;\n }\n }\n\n unchecked {\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n //note: opIndex is ignored (relevant only if mode==postOpReverted, which is only possible outside of innerHandleOp)\n return _handlePostOp(0, mode, opInfo, context, actualGas);\n }\n }\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(\n UserOperation calldata userOp\n ) public view returns (bytes32) {\n return\n keccak256(abi.encode(userOp.hash(), address(this), block.chainid));\n }\n\n /**\n * copy general fields from userOp into the memory opInfo structure.\n */\n function _copyUserOpToMemory(\n UserOperation calldata userOp,\n MemoryUserOp memory mUserOp\n ) internal pure {\n mUserOp.sender = userOp.sender;\n mUserOp.nonce = userOp.nonce;\n mUserOp.callGasLimit = userOp.callGasLimit;\n mUserOp.verificationGasLimit = userOp.verificationGasLimit;\n mUserOp.preVerificationGas = userOp.preVerificationGas;\n mUserOp.maxFeePerGas = userOp.maxFeePerGas;\n mUserOp.maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes calldata paymasterAndData = userOp.paymasterAndData;\n if (paymasterAndData.length > 0) {\n require(\n paymasterAndData.length >= 20,\n \"AA93 invalid paymasterAndData\"\n );\n mUserOp.paymaster = address(bytes20(paymasterAndData[:20]));\n } else {\n mUserOp.paymaster = address(0);\n }\n }\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external {\n UserOpInfo memory outOpInfo;\n\n _simulationOnlyValidations(userOp);\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(0, userOp, outOpInfo);\n StakeInfo memory paymasterInfo = _getStakeInfo(\n outOpInfo.mUserOp.paymaster\n );\n StakeInfo memory senderInfo = _getStakeInfo(outOpInfo.mUserOp.sender);\n StakeInfo memory factoryInfo;\n {\n bytes calldata initCode = userOp.initCode;\n address factory = initCode.length >= 20\n ? address(bytes20(initCode[0:20]))\n : address(0);\n factoryInfo = _getStakeInfo(factory);\n }\n\n ValidationData memory data = _intersectTimeRange(\n validationData,\n paymasterValidationData\n );\n address aggregator = data.aggregator;\n bool sigFailed = aggregator == address(1);\n ReturnInfo memory returnInfo = ReturnInfo(\n outOpInfo.preOpGas,\n outOpInfo.prefund,\n sigFailed,\n data.validAfter,\n data.validUntil,\n getMemoryBytesFromOffset(outOpInfo.contextOffset)\n );\n\n if (aggregator != address(0) && aggregator != address(1)) {\n AggregatorStakeInfo memory aggregatorInfo = AggregatorStakeInfo(\n aggregator,\n _getStakeInfo(aggregator)\n );\n revert ValidationResultWithAggregation(\n returnInfo,\n senderInfo,\n factoryInfo,\n paymasterInfo,\n aggregatorInfo\n );\n }\n revert ValidationResult(\n returnInfo,\n senderInfo,\n factoryInfo,\n paymasterInfo\n );\n }\n\n function _getRequiredPrefund(\n MemoryUserOp memory mUserOp\n ) internal pure returns (uint256 requiredPrefund) {\n unchecked {\n //when using a Paymaster, the verificationGasLimit is used also to as a limit for the postOp call.\n // our security model might call postOp eventually twice\n uint256 mul = mUserOp.paymaster != address(0) ? 3 : 1;\n uint256 requiredGas = mUserOp.callGasLimit +\n mUserOp.verificationGasLimit *\n mul +\n mUserOp.preVerificationGas;\n\n requiredPrefund = requiredGas * mUserOp.maxFeePerGas;\n }\n }\n\n // create the sender's contract if needed.\n function _createSenderIfNeeded(\n uint256 opIndex,\n UserOpInfo memory opInfo,\n bytes calldata initCode\n ) internal {\n if (initCode.length != 0) {\n address sender = opInfo.mUserOp.sender;\n if (sender.code.length != 0)\n revert FailedOp(opIndex, \"AA10 sender already constructed\");\n address sender1 = senderCreator.createSender{\n gas: opInfo.mUserOp.verificationGasLimit\n }(initCode);\n if (sender1 == address(0))\n revert FailedOp(opIndex, \"AA13 initCode failed or OOG\");\n if (sender1 != sender)\n revert FailedOp(opIndex, \"AA14 initCode must return sender\");\n if (sender1.code.length == 0)\n revert FailedOp(opIndex, \"AA15 initCode must create sender\");\n address factory = address(bytes20(initCode[0:20]));\n emit AccountDeployed(\n opInfo.userOpHash,\n sender,\n factory,\n opInfo.mUserOp.paymaster\n );\n }\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes calldata initCode) public {\n address sender = senderCreator.createSender(initCode);\n revert SenderAddressResult(sender);\n }\n\n function _simulationOnlyValidations(\n UserOperation calldata userOp\n ) internal view {\n // solhint-disable-next-line no-empty-blocks\n try\n this._validateSenderAndPaymaster(\n userOp.initCode,\n userOp.sender,\n userOp.paymasterAndData\n )\n {} catch Error(string memory revertReason) {\n if (bytes(revertReason).length != 0) {\n revert FailedOp(0, revertReason);\n }\n }\n }\n\n /**\n * Called only during simulation.\n * This function always reverts to prevent warm/cold storage differentiation in simulation vs execution.\n */\n function _validateSenderAndPaymaster(\n bytes calldata initCode,\n address sender,\n bytes calldata paymasterAndData\n ) external view {\n if (initCode.length == 0 && sender.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA20 account not deployed\");\n }\n if (paymasterAndData.length >= 20) {\n address paymaster = address(bytes20(paymasterAndData[0:20]));\n if (paymaster.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA30 paymaster not deployed\");\n }\n }\n // always revert\n revert(\"\");\n }\n\n /**\n * call account.validateUserOp.\n * revert (with FailedOp) in case validateUserOp reverts, or account didn't send required prefund.\n * decrement account's deposit if needed\n */\n function _validateAccountPrepayment(\n uint256 opIndex,\n UserOperation calldata op,\n UserOpInfo memory opInfo,\n uint256 requiredPrefund\n )\n internal\n returns (\n uint256 gasUsedByValidateAccountPrepayment,\n uint256 validationData\n )\n {\n unchecked {\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n address sender = mUserOp.sender;\n _createSenderIfNeeded(opIndex, opInfo, op.initCode);\n address paymaster = mUserOp.paymaster;\n numberMarker();\n uint256 missingAccountFunds = 0;\n if (paymaster == address(0)) {\n uint256 bal = balanceOf(sender);\n missingAccountFunds = bal > requiredPrefund\n ? 0\n : requiredPrefund - bal;\n }\n try\n IAccount(sender).validateUserOp{\n gas: mUserOp.verificationGasLimit\n }(op, opInfo.userOpHash, missingAccountFunds)\n returns (uint256 _validationData) {\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA23 reverted: \", revertReason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA23 reverted (or OOG)\");\n }\n if (paymaster == address(0)) {\n DepositInfo storage senderInfo = deposits[sender];\n uint256 deposit = senderInfo.deposit;\n if (requiredPrefund > deposit) {\n revert FailedOp(opIndex, \"AA21 didn't pay prefund\");\n }\n senderInfo.deposit = uint112(deposit - requiredPrefund);\n }\n gasUsedByValidateAccountPrepayment = preGas - gasleft();\n }\n }\n\n /**\n * In case the request has a paymaster:\n * Validate paymaster has enough deposit.\n * Call paymaster.validatePaymasterUserOp.\n * Revert with proper FailedOp in case paymaster reverts.\n * Decrement paymaster's deposit\n */\n function _validatePaymasterPrepayment(\n uint256 opIndex,\n UserOperation calldata op,\n UserOpInfo memory opInfo,\n uint256 requiredPreFund,\n uint256 gasUsedByValidateAccountPrepayment\n ) internal returns (bytes memory context, uint256 validationData) {\n unchecked {\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 verificationGasLimit = mUserOp.verificationGasLimit;\n require(\n verificationGasLimit > gasUsedByValidateAccountPrepayment,\n \"AA41 too little verificationGas\"\n );\n uint256 gas = verificationGasLimit -\n gasUsedByValidateAccountPrepayment;\n\n address paymaster = mUserOp.paymaster;\n DepositInfo storage paymasterInfo = deposits[paymaster];\n uint256 deposit = paymasterInfo.deposit;\n if (deposit < requiredPreFund) {\n revert FailedOp(opIndex, \"AA31 paymaster deposit too low\");\n }\n paymasterInfo.deposit = uint112(deposit - requiredPreFund);\n try\n IPaymaster(paymaster).validatePaymasterUserOp{gas: gas}(\n op,\n opInfo.userOpHash,\n requiredPreFund\n )\n returns (bytes memory _context, uint256 _validationData) {\n context = _context;\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA33 reverted: \", revertReason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA33 reverted (or OOG)\");\n }\n }\n }\n\n /**\n * revert if either account validationData or paymaster validationData is expired\n */\n function _validateAccountAndPaymasterValidationData(\n uint256 opIndex,\n uint256 validationData,\n uint256 paymasterValidationData,\n address expectedAggregator\n ) internal view {\n (address aggregator, bool outOfTimeRange) = _getValidationData(\n validationData\n );\n if (expectedAggregator != aggregator) {\n revert FailedOp(opIndex, \"AA24 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA22 expired or not due\");\n }\n //pmAggregator is not a real signature aggregator: we don't have logic to handle it as address.\n // non-zero address means that the paymaster fails due to some signature check (which is ok only during estimation)\n address pmAggregator;\n (pmAggregator, outOfTimeRange) = _getValidationData(\n paymasterValidationData\n );\n if (pmAggregator != address(0)) {\n revert FailedOp(opIndex, \"AA34 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA32 paymaster expired or not due\");\n }\n }\n\n function _getValidationData(\n uint256 validationData\n ) internal view returns (address aggregator, bool outOfTimeRange) {\n if (validationData == 0) {\n return (address(0), false);\n }\n ValidationData memory data = _parseValidationData(validationData);\n // solhint-disable-next-line not-rely-on-time\n outOfTimeRange =\n block.timestamp > data.validUntil ||\n block.timestamp < data.validAfter;\n aggregator = data.aggregator;\n }\n\n /**\n * validate account and paymaster (if defined).\n * also make sure total validation doesn't exceed verificationGasLimit\n * this method is called off-chain (simulateValidation()) and on-chain (from handleOps)\n * @param opIndex the index of this userOp into the \"opInfos\" array\n * @param userOp the userOp to validate\n */\n function _validatePrepayment(\n uint256 opIndex,\n UserOperation calldata userOp,\n UserOpInfo memory outOpInfo\n )\n private\n returns (uint256 validationData, uint256 paymasterValidationData)\n {\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = outOpInfo.mUserOp;\n _copyUserOpToMemory(userOp, mUserOp);\n outOpInfo.userOpHash = getUserOpHash(userOp);\n\n // validate all numeric values in userOp are well below 128 bit, so they can safely be added\n // and multiplied without causing overflow\n uint256 maxGasValues = mUserOp.preVerificationGas |\n mUserOp.verificationGasLimit |\n mUserOp.callGasLimit |\n userOp.maxFeePerGas |\n userOp.maxPriorityFeePerGas;\n require(maxGasValues <= type(uint120).max, \"AA94 gas values overflow\");\n\n uint256 gasUsedByValidateAccountPrepayment;\n uint256 requiredPreFund = _getRequiredPrefund(mUserOp);\n (\n gasUsedByValidateAccountPrepayment,\n validationData\n ) = _validateAccountPrepayment(\n opIndex,\n userOp,\n outOpInfo,\n requiredPreFund\n );\n\n if (!_validateAndUpdateNonce(mUserOp.sender, mUserOp.nonce)) {\n revert FailedOp(opIndex, \"AA25 invalid account nonce\");\n }\n\n //a \"marker\" where account opcode validation is done and paymaster opcode validation is about to start\n // (used only by off-chain simulateValidation)\n numberMarker();\n\n bytes memory context;\n if (mUserOp.paymaster != address(0)) {\n (context, paymasterValidationData) = _validatePaymasterPrepayment(\n opIndex,\n userOp,\n outOpInfo,\n requiredPreFund,\n gasUsedByValidateAccountPrepayment\n );\n }\n unchecked {\n uint256 gasUsed = preGas - gasleft();\n\n if (userOp.verificationGasLimit < gasUsed) {\n revert FailedOp(opIndex, \"AA40 over verificationGasLimit\");\n }\n outOpInfo.prefund = requiredPreFund;\n outOpInfo.contextOffset = getOffsetOfMemoryBytes(context);\n outOpInfo.preOpGas = preGas - gasleft() + userOp.preVerificationGas;\n }\n }\n\n /**\n * process post-operation.\n * called just after the callData is executed.\n * if a paymaster is defined and its validation returned a non-empty context, its postOp is called.\n * the excess amount is refunded to the account (or paymaster - if it was used in the request)\n * @param opIndex index in the batch\n * @param mode - whether is called from innerHandleOp, or outside (postOpReverted)\n * @param opInfo userOp fields and info collected during validation\n * @param context the context returned in validatePaymasterUserOp\n * @param actualGas the gas used so far by this user operation\n */\n function _handlePostOp(\n uint256 opIndex,\n IPaymaster.PostOpMode mode,\n UserOpInfo memory opInfo,\n bytes memory context,\n uint256 actualGas\n ) private returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n unchecked {\n address refundAddress;\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 gasPrice = getUserOpGasPrice(mUserOp);\n\n address paymaster = mUserOp.paymaster;\n if (paymaster == address(0)) {\n refundAddress = mUserOp.sender;\n } else {\n refundAddress = paymaster;\n if (context.length > 0) {\n actualGasCost = actualGas * gasPrice;\n if (mode != IPaymaster.PostOpMode.postOpReverted) {\n IPaymaster(paymaster).postOp{\n gas: mUserOp.verificationGasLimit\n }(mode, context, actualGasCost);\n } else {\n // solhint-disable-next-line no-empty-blocks\n try\n IPaymaster(paymaster).postOp{\n gas: mUserOp.verificationGasLimit\n }(mode, context, actualGasCost)\n {} catch Error(string memory reason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA50 postOp reverted: \", reason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA50 postOp revert\");\n }\n }\n }\n }\n actualGas += preGas - gasleft();\n actualGasCost = actualGas * gasPrice;\n if (opInfo.prefund < actualGasCost) {\n revert FailedOp(opIndex, \"AA51 prefund below actualGasCost\");\n }\n uint256 refund = opInfo.prefund - actualGasCost;\n _incrementDeposit(refundAddress, refund);\n bool success = mode == IPaymaster.PostOpMode.opSucceeded;\n emit UserOperationEvent(\n opInfo.userOpHash,\n mUserOp.sender,\n mUserOp.paymaster,\n mUserOp.nonce,\n success,\n actualGasCost,\n actualGas\n );\n } // unchecked\n }\n\n /**\n * the gas price this UserOp agrees to pay.\n * relayer/block builder might submit the TX with higher priorityFee, but the user should not\n */\n function getUserOpGasPrice(\n MemoryUserOp memory mUserOp\n ) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = mUserOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = mUserOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n function getOffsetOfMemoryBytes(\n bytes memory data\n ) internal pure returns (uint256 offset) {\n assembly {\n offset := data\n }\n }\n\n function getMemoryBytesFromOffset(\n uint256 offset\n ) internal pure returns (bytes memory data) {\n assembly {\n data := offset\n }\n }\n\n //place the NUMBER opcode in the code.\n // this is used as a marker during simulation, as this OP is completely banned from the simulated code of the\n // account and paymaster.\n function numberMarker() internal view {\n assembly {\n mstore(0, number())\n }\n }\n}\n" + }, + "contracts/aa-4337/core/Helpers.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable no-inline-assembly */\n\n/**\n * returned data from validateUserOp.\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\n * @param aggregator - address(0) - the account validated the signature by itself.\n * address(1) - the account failed to validate the signature.\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\n * @param validAfter - this UserOp is valid only after this timestamp.\n * @param validaUntil - this UserOp is valid only up to this timestamp.\n */\nstruct ValidationData {\n address aggregator;\n uint48 validAfter;\n uint48 validUntil;\n}\n\n//extract sigFailed, validAfter, validUntil.\n// also convert zero validUntil to type(uint48).max\nfunction _parseValidationData(\n uint validationData\n) pure returns (ValidationData memory data) {\n address aggregator = address(uint160(validationData));\n uint48 validUntil = uint48(validationData >> 160);\n if (validUntil == 0) {\n validUntil = type(uint48).max;\n }\n uint48 validAfter = uint48(validationData >> (48 + 160));\n return ValidationData(aggregator, validAfter, validUntil);\n}\n\n// intersect account and paymaster ranges.\nfunction _intersectTimeRange(\n uint256 validationData,\n uint256 paymasterValidationData\n) pure returns (ValidationData memory) {\n ValidationData memory accountValidationData = _parseValidationData(\n validationData\n );\n ValidationData memory pmValidationData = _parseValidationData(\n paymasterValidationData\n );\n address aggregator = accountValidationData.aggregator;\n if (aggregator == address(0)) {\n aggregator = pmValidationData.aggregator;\n }\n uint48 validAfter = accountValidationData.validAfter;\n uint48 validUntil = accountValidationData.validUntil;\n uint48 pmValidAfter = pmValidationData.validAfter;\n uint48 pmValidUntil = pmValidationData.validUntil;\n\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\n return ValidationData(aggregator, validAfter, validUntil);\n}\n\n/**\n * helper to pack the return value for validateUserOp\n * @param data - the ValidationData to pack\n */\nfunction _packValidationData(\n ValidationData memory data\n) pure returns (uint256) {\n return\n uint160(data.aggregator) |\n (uint256(data.validUntil) << 160) |\n (uint256(data.validAfter) << (160 + 48));\n}\n\n/**\n * helper to pack the return value for validateUserOp, when not using an aggregator\n * @param sigFailed - true for signature failure, false for success\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\n * @param validAfter first timestamp this UserOperation is valid\n */\nfunction _packValidationData(\n bool sigFailed,\n uint48 validUntil,\n uint48 validAfter\n) pure returns (uint256) {\n return\n (sigFailed ? 1 : 0) |\n (uint256(validUntil) << 160) |\n (uint256(validAfter) << (160 + 48));\n}\n\n/**\n * keccak function over calldata.\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\n */\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\n assembly {\n let mem := mload(0x40)\n let len := data.length\n calldatacopy(mem, data.offset, len)\n ret := keccak256(mem, len)\n }\n}\n" + }, + "contracts/aa-4337/core/NonceManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\nimport \"../interfaces/IEntryPoint.sol\";\n\n/**\n * nonce management functionality\n */\ncontract NonceManager is INonceManager {\n /**\n * The next valid sequence number for a given nonce key.\n */\n mapping(address => mapping(uint192 => uint256)) public nonceSequenceNumber;\n\n function getNonce(\n address sender,\n uint192 key\n ) public view override returns (uint256 nonce) {\n return nonceSequenceNumber[sender][key] | (uint256(key) << 64);\n }\n\n // allow an account to manually increment its own nonce.\n // (mainly so that during construction nonce can be made non-zero,\n // to \"absorb\" the gas cost of first nonce increment to 1st transaction (construction),\n // not to 2nd transaction)\n function incrementNonce(uint192 key) public override {\n nonceSequenceNumber[msg.sender][key]++;\n }\n\n /**\n * validate nonce uniqueness for this account.\n * called just after validateUserOp()\n */\n function _validateAndUpdateNonce(\n address sender,\n uint256 nonce\n ) internal returns (bool) {\n uint192 key = uint192(nonce >> 64);\n uint64 seq = uint64(nonce);\n return nonceSequenceNumber[sender][key]++ == seq;\n }\n}\n" + }, + "contracts/aa-4337/core/SenderCreator.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/**\n * helper contract for EntryPoint, to call userOp.initCode from a \"neutral\" address,\n * which is explicitly not the entryPoint itself.\n */\ncontract SenderCreator {\n /**\n * call the \"initCode\" factory to create and return the sender account address\n * @param initCode the initCode value from a UserOp. contains 20 bytes of factory address, followed by calldata\n * @return sender the returned address of the created account, or zero address on failure.\n */\n function createSender(\n bytes calldata initCode\n ) external returns (address sender) {\n address factory = address(bytes20(initCode[0:20]));\n bytes memory initCallData = initCode[20:];\n bool success;\n /* solhint-disable no-inline-assembly */\n assembly {\n success := call(\n gas(),\n factory,\n 0,\n add(initCallData, 0x20),\n mload(initCallData),\n 0,\n 32\n )\n sender := mload(0)\n }\n if (!success) {\n sender = address(0);\n }\n }\n}\n" + }, + "contracts/aa-4337/core/StakeManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity 0.8.21;\n\nimport \"../interfaces/IStakeManager.sol\";\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable not-rely-on-time */\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by a paymaster.\n */\nabstract contract StakeManager is IStakeManager {\n /// maps paymaster to their deposits and stakes\n mapping(address => DepositInfo) public deposits;\n\n /// @inheritdoc IStakeManager\n function getDepositInfo(\n address account\n ) public view returns (DepositInfo memory info) {\n return deposits[account];\n }\n\n // internal method to return just the stake info\n function _getStakeInfo(\n address addr\n ) internal view returns (StakeInfo memory info) {\n DepositInfo storage depositInfo = deposits[addr];\n info.stake = depositInfo.stake;\n info.unstakeDelaySec = depositInfo.unstakeDelaySec;\n }\n\n /// return the deposit (for gas payment) of the account\n function balanceOf(address account) public view returns (uint256) {\n return deposits[account].deposit;\n }\n\n receive() external payable {\n depositTo(msg.sender);\n }\n\n function _incrementDeposit(address account, uint256 amount) internal {\n DepositInfo storage info = deposits[account];\n uint256 newAmount = info.deposit + amount;\n require(newAmount <= type(uint112).max, \"deposit overflow\");\n info.deposit = uint112(newAmount);\n }\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) public payable {\n _incrementDeposit(account, msg.value);\n DepositInfo storage info = deposits[account];\n emit Deposited(account, info.deposit);\n }\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 unstakeDelaySec) public payable {\n DepositInfo storage info = deposits[msg.sender];\n require(unstakeDelaySec > 0, \"must specify unstake delay\");\n require(\n unstakeDelaySec >= info.unstakeDelaySec,\n \"cannot decrease unstake time\"\n );\n uint256 stake = info.stake + msg.value;\n require(stake > 0, \"no stake specified\");\n require(stake <= type(uint112).max, \"stake overflow\");\n deposits[msg.sender] = DepositInfo(\n info.deposit,\n true,\n uint112(stake),\n unstakeDelaySec,\n 0\n );\n emit StakeLocked(msg.sender, stake, unstakeDelaySec);\n }\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external {\n DepositInfo storage info = deposits[msg.sender];\n require(info.unstakeDelaySec != 0, \"not staked\");\n require(info.staked, \"already unstaking\");\n uint48 withdrawTime = uint48(block.timestamp) + info.unstakeDelaySec;\n info.withdrawTime = withdrawTime;\n info.staked = false;\n emit StakeUnlocked(msg.sender, withdrawTime);\n }\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external {\n DepositInfo storage info = deposits[msg.sender];\n uint256 stake = info.stake;\n require(stake > 0, \"No stake to withdraw\");\n require(info.withdrawTime > 0, \"must call unlockStake() first\");\n require(\n info.withdrawTime <= block.timestamp,\n \"Stake withdrawal is not due\"\n );\n info.unstakeDelaySec = 0;\n info.withdrawTime = 0;\n info.stake = 0;\n emit StakeWithdrawn(msg.sender, withdrawAddress, stake);\n (bool success, ) = withdrawAddress.call{value: stake}(\"\");\n require(success, \"failed to withdraw stake\");\n }\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(\n address payable withdrawAddress,\n uint256 withdrawAmount\n ) external {\n DepositInfo storage info = deposits[msg.sender];\n require(withdrawAmount <= info.deposit, \"Withdraw amount too large\");\n info.deposit = uint112(info.deposit - withdrawAmount);\n emit Withdrawn(msg.sender, withdrawAddress, withdrawAmount);\n (bool success, ) = withdrawAddress.call{value: withdrawAmount}(\"\");\n require(success, \"failed to withdraw\");\n }\n}\n" + }, + "contracts/aa-4337/interfaces/IAccount.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\ninterface IAccount {\n /**\n * Validate user's signature and nonce\n * the entryPoint will make the call to the recipient only if this validation call returns successfully.\n * signature failure should be reported by returning SIG_VALIDATION_FAILED (1).\n * This allows making a \"simulation call\" without a valid signature\n * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure.\n *\n * @dev Must validate caller is the entryPoint.\n * Must validate the signature and nonce\n * @param userOp the operation that is about to be executed.\n * @param userOpHash hash of the user's request data. can be used as the basis for signature.\n * @param missingAccountFunds missing funds on the account's deposit in the entrypoint.\n * This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call.\n * The excess is left as a deposit in the entrypoint, for future calls.\n * can be withdrawn anytime using \"entryPoint.withdrawTo()\"\n * In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero.\n * @return validationData packaged ValidationData structure. use `_packValidationData` and `_unpackValidationData` to encode and decode\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * If an account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validateUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 missingAccountFunds\n ) external returns (uint256 validationData);\n}\n" + }, + "contracts/aa-4337/interfaces/IAggregator.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * Aggregated Signatures validator.\n */\ninterface IAggregator {\n /**\n * validate aggregated signature.\n * revert if the aggregated signature does not match the given list of operations.\n */\n function validateSignatures(\n UserOperation[] calldata userOps,\n bytes calldata signature\n ) external view;\n\n /**\n * validate signature of a single userOp\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\n * @param userOp the userOperation received from the user.\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\n * (usually empty, unless account and aggregator support some kind of \"multisig\"\n */\n function validateUserOpSignature(\n UserOperation calldata userOp\n ) external view returns (bytes memory sigForUserOp);\n\n /**\n * aggregate multiple signatures into a single value.\n * This method is called off-chain to calculate the signature to pass with handleOps()\n * bundler MAY use optimized custom code perform this aggregation\n * @param userOps array of UserOperations to collect the signatures from.\n * @return aggregatedSignature the aggregated signature\n */\n function aggregateSignatures(\n UserOperation[] calldata userOps\n ) external view returns (bytes memory aggregatedSignature);\n}\n" + }, + "contracts/aa-4337/interfaces/IEntryPoint.sol": { + "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n/* solhint-disable reason-string */\n\nimport \"./UserOperation.sol\";\nimport \"./IStakeManager.sol\";\nimport \"./IAggregator.sol\";\nimport \"./INonceManager.sol\";\n\ninterface IEntryPoint is IStakeManager, INonceManager {\n /***\n * An event emitted after each successful request\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\n * @param sender - the account that generates this request.\n * @param paymaster - if non-null, the paymaster that pays for this request.\n * @param nonce - the nonce value from the request.\n * @param success - true if the sender transaction succeeded, false if reverted.\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\n */\n event UserOperationEvent(\n bytes32 indexed userOpHash,\n address indexed sender,\n address indexed paymaster,\n uint256 nonce,\n bool success,\n uint256 actualGasCost,\n uint256 actualGasUsed\n );\n\n /**\n * account \"sender\" was deployed.\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\n * @param sender the account that is deployed\n * @param factory the factory used to deploy this account (in the initCode)\n * @param paymaster the paymaster used by this UserOp\n */\n event AccountDeployed(\n bytes32 indexed userOpHash,\n address indexed sender,\n address factory,\n address paymaster\n );\n\n /**\n * An event emitted if the UserOperation \"callData\" reverted with non-zero length\n * @param userOpHash the request unique identifier.\n * @param sender the sender of this request\n * @param nonce the nonce used in the request\n * @param revertReason - the return bytes from the (reverted) call to \"callData\".\n */\n event UserOperationRevertReason(\n bytes32 indexed userOpHash,\n address indexed sender,\n uint256 nonce,\n bytes revertReason\n );\n\n /**\n * an event emitted by handleOps(), before starting the execution loop.\n * any event emitted before this event, is part of the validation.\n */\n event BeforeExecution();\n\n /**\n * signature aggregator used by the following UserOperationEvents within this bundle.\n */\n event SignatureAggregatorChanged(address indexed aggregator);\n\n /**\n * a custom revert error of handleOps, to identify the offending op.\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\n * @param reason - revert reason\n * The string starts with a unique code \"AAmn\", where \"m\" is \"1\" for factory, \"2\" for account and \"3\" for paymaster issues,\n * so a failure can be attributed to the correct entity.\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\n */\n error FailedOp(uint256 opIndex, string reason);\n\n /**\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\n */\n error SignatureValidationFailed(address aggregator);\n\n /**\n * Successful result from simulateValidation.\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n */\n error ValidationResult(\n ReturnInfo returnInfo,\n StakeInfo senderInfo,\n StakeInfo factoryInfo,\n StakeInfo paymasterInfo\n );\n\n /**\n * Successful result from simulateValidation, if the account returns a signature aggregator\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\n * bundler MUST use it to verify the signature, or reject the UserOperation\n */\n error ValidationResultWithAggregation(\n ReturnInfo returnInfo,\n StakeInfo senderInfo,\n StakeInfo factoryInfo,\n StakeInfo paymasterInfo,\n AggregatorStakeInfo aggregatorInfo\n );\n\n /**\n * return value of getSenderAddress\n */\n error SenderAddressResult(address sender);\n\n /**\n * return value of simulateHandleOp\n */\n error ExecutionResult(\n uint256 preOpGas,\n uint256 paid,\n uint48 validAfter,\n uint48 validUntil,\n bool targetSuccess,\n bytes targetResult\n );\n\n //UserOps handled, per aggregator\n struct UserOpsPerAggregator {\n UserOperation[] userOps;\n // aggregator address\n IAggregator aggregator;\n // aggregated signature\n bytes signature;\n }\n\n /**\n * Execute a batch of UserOperation.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(\n UserOperation[] calldata ops,\n address payable beneficiary\n ) external;\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) external;\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(\n UserOperation calldata userOp\n ) external view returns (bytes32);\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external;\n\n /**\n * gas and return values during simulation\n * @param preOpGas the gas used for validation (including preValidationGas)\n * @param prefund the required prefund for this operation\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\n */\n struct ReturnInfo {\n uint256 preOpGas;\n uint256 prefund;\n bool sigFailed;\n uint48 validAfter;\n uint48 validUntil;\n bytes paymasterContext;\n }\n\n /**\n * returned aggregated signature info.\n * the aggregator returned by the account, and its current stake.\n */\n struct AggregatorStakeInfo {\n address aggregator;\n StakeInfo stakeInfo;\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes memory initCode) external;\n\n /**\n * simulate full execution of a UserOperation (including both validation and target execution)\n * this method will always revert with \"ExecutionResult\".\n * it performs full validation of the UserOperation, but ignores signature error.\n * an optional target address is called after the userop succeeds, and its value is returned\n * (before the entire call is reverted)\n * Note that in order to collect the the success/failure of the target call, it must be executed\n * with trace enabled to track the emitted events.\n * @param op the UserOperation to simulate\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\n * are set to the return from that call.\n * @param targetCallData callData to pass to target address\n */\n function simulateHandleOp(\n UserOperation calldata op,\n address target,\n bytes calldata targetCallData\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/INonceManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\ninterface INonceManager {\n /**\n * Return the next nonce for this sender.\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\n * But UserOp with different keys can come with arbitrary order.\n *\n * @param sender the account address\n * @param key the high 192 bit of the nonce\n * @return nonce a full nonce to pass for next UserOp with this sender.\n */\n function getNonce(\n address sender,\n uint192 key\n ) external view returns (uint256 nonce);\n\n /**\n * Manually increment the nonce of the sender.\n * This method is exposed just for completeness..\n * Account does NOT need to call it, neither during validation, nor elsewhere,\n * as the EntryPoint will update the nonce regardless.\n * Possible use-case is call it with various keys to \"initialize\" their nonces to one, so that future\n * UserOperations will not pay extra for the first transaction with a given key.\n */\n function incrementNonce(uint192 key) external;\n}\n" + }, + "contracts/aa-4337/interfaces/IPaymaster.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * the interface exposed by a paymaster contract, who agrees to pay the gas for user's operations.\n * a paymaster must hold a stake to cover the required entrypoint stake and also the gas for the transaction.\n */\ninterface IPaymaster {\n enum PostOpMode {\n opSucceeded, // user op succeeded\n opReverted, // user op reverted. still has to pay for gas.\n postOpReverted //user op succeeded, but caused postOp to revert. Now it's a 2nd call, after user's op was deliberately reverted.\n }\n\n /**\n * payment validation: check if paymaster agrees to pay.\n * Must verify sender is the entryPoint.\n * Revert to reject this request.\n * Note that bundlers will reject this method if it changes the state, unless the paymaster is trusted (whitelisted)\n * The paymaster pre-pays using its deposit, and receive back a refund after the postOp method returns.\n * @param userOp the user operation\n * @param userOpHash hash of the user's request data.\n * @param maxCost the maximum cost of this transaction (based on maximum gas and gas price from userOp)\n * @return context value to send to a postOp\n * zero length to signify postOp is not required.\n * @return validationData signature and time-range of this operation, encoded the same as the return value of validateUserOperation\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validatePaymasterUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 maxCost\n ) external returns (bytes memory context, uint256 validationData);\n\n /**\n * post-operation handler.\n * Must verify sender is the entryPoint\n * @param mode enum with the following options:\n * opSucceeded - user operation succeeded.\n * opReverted - user op reverted. still has to pay for gas.\n * postOpReverted - user op succeeded, but caused postOp (in mode=opSucceeded) to revert.\n * Now this is the 2nd call, after user's op was deliberately reverted.\n * @param context - the context value returned by validatePaymasterUserOp\n * @param actualGasCost - actual gas used so far (without this postOp call).\n */\n function postOp(\n PostOpMode mode,\n bytes calldata context,\n uint256 actualGasCost\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/IStakeManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.12;\n\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by the staked entity.\n */\ninterface IStakeManager {\n event Deposited(address indexed account, uint256 totalDeposit);\n\n event Withdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /// Emitted when stake or unstake delay are modified\n event StakeLocked(\n address indexed account,\n uint256 totalStaked,\n uint256 unstakeDelaySec\n );\n\n /// Emitted once a stake is scheduled for withdrawal\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\n\n event StakeWithdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /**\n * @param deposit the entity's deposit\n * @param staked true if this entity is staked.\n * @param stake actual amount of ether staked for this entity.\n * @param unstakeDelaySec minimum delay to withdraw the stake.\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\n * and the rest fit into a 2nd cell.\n * 112 bit allows for 10^15 eth\n * 48 bit for full timestamp\n * 32 bit allows 150 years for unstake delay\n */\n struct DepositInfo {\n uint112 deposit;\n bool staked;\n uint112 stake;\n uint32 unstakeDelaySec;\n uint48 withdrawTime;\n }\n\n //API struct used by getStakeInfo and simulateValidation\n struct StakeInfo {\n uint256 stake;\n uint256 unstakeDelaySec;\n }\n\n /// @return info - full deposit information of given account\n function getDepositInfo(\n address account\n ) external view returns (DepositInfo memory info);\n\n /// @return the deposit (for gas payment) of the account\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) external payable;\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 _unstakeDelaySec) external payable;\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external;\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external;\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(\n address payable withdrawAddress,\n uint256 withdrawAmount\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/UserOperation.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable no-inline-assembly */\n\nimport {calldataKeccak} from \"../core/Helpers.sol\";\n\n/**\n * User Operation struct\n * @param sender the sender account of this request.\n * @param nonce unique value the sender uses to verify it is not a replay.\n * @param initCode if set, the account contract will be created by this constructor/\n * @param callData the method call to execute on this account.\n * @param callGasLimit the gas limit passed to the callData method call.\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\n * @param maxFeePerGas same as EIP-1559 gas parameter.\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\n */\nstruct UserOperation {\n address sender;\n uint256 nonce;\n bytes initCode;\n bytes callData;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n bytes paymasterAndData;\n bytes signature;\n}\n\n/**\n * Utility functions helpful when working with UserOperation structs.\n */\nlibrary UserOperationLib {\n function getSender(\n UserOperation calldata userOp\n ) internal pure returns (address) {\n address data;\n //read sender from userOp, which is first userOp member (saves 800 gas...)\n assembly {\n data := calldataload(userOp)\n }\n return address(uint160(data));\n }\n\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\n // pay above what he signed for.\n function gasPrice(\n UserOperation calldata userOp\n ) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function pack(\n UserOperation calldata userOp\n ) internal pure returns (bytes memory ret) {\n address sender = getSender(userOp);\n uint256 nonce = userOp.nonce;\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\n bytes32 hashCallData = calldataKeccak(userOp.callData);\n uint256 callGasLimit = userOp.callGasLimit;\n uint256 verificationGasLimit = userOp.verificationGasLimit;\n uint256 preVerificationGas = userOp.preVerificationGas;\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\n\n return\n abi.encode(\n sender,\n nonce,\n hashInitCode,\n hashCallData,\n callGasLimit,\n verificationGasLimit,\n preVerificationGas,\n maxFeePerGas,\n maxPriorityFeePerGas,\n hashPaymasterAndData\n );\n }\n\n function hash(\n UserOperation calldata userOp\n ) internal pure returns (bytes32) {\n return keccak256(pack(userOp));\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n}\n" + }, + "contracts/aa-4337/utils/Exec.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.5 <0.9.0;\n\n// solhint-disable no-inline-assembly\n\n/**\n * Utility functions helpful when making different kinds of contract calls in Solidity.\n */\nlibrary Exec {\n function call(\n address to,\n uint256 value,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := call(\n txGas,\n to,\n value,\n add(data, 0x20),\n mload(data),\n 0,\n 0\n )\n }\n }\n\n function staticcall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal view returns (bool success) {\n assembly {\n success := staticcall(txGas, to, add(data, 0x20), mload(data), 0, 0)\n }\n }\n\n function delegateCall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := delegatecall(\n txGas,\n to,\n add(data, 0x20),\n mload(data),\n 0,\n 0\n )\n }\n }\n\n // get returned data from last call or calldelegate\n function getReturnData(\n uint256 maxLen\n ) internal pure returns (bytes memory returnData) {\n assembly {\n let len := returndatasize()\n if gt(len, maxLen) {\n len := maxLen\n }\n let ptr := mload(0x40)\n mstore(0x40, add(ptr, add(len, 0x20)))\n mstore(ptr, len)\n returndatacopy(add(ptr, 0x20), 0, len)\n returnData := ptr\n }\n }\n\n // revert with explicit byte array (probably reverted info from call)\n function revertWithData(bytes memory returnData) internal pure {\n assembly {\n revert(add(returnData, 32), mload(returnData))\n }\n }\n\n function callAndRevert(\n address to,\n bytes memory data,\n uint256 maxLen\n ) internal {\n bool success = call(to, 0, data, gasleft());\n if (!success) {\n revertWithData(getReturnData(maxLen));\n }\n }\n}\n" + }, + "contracts/Barz.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"./libraries/LibDiamond.sol\";\nimport {IBarz} from \"./interfaces/IBarz.sol\";\n\n/**\n * @title Barz\n * @dev A diamond proxy wallet with a modular & upgradeable architecture\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract Barz is IBarz {\n /**\n * @notice Initializes Barz with the given parameters. Barz account is intended to be created from Barz Factory for stable deployment.\n * @dev This method makes a delegate call to account facet and account facet handles the initialization.\n * With modular architecture, Barz encompasses wide spectrum of architecture and logic.\n * The only requirement is account facet to comply with initialize() interface.\n * Barz doesn't include built-in functions and is a full proxy, for maximum extensibility and modularity.\n * @param _accountFacet Address of Account Facet in charge of the Barz initialization\n * @param _verificationFacet Address of Verification Facet for verifying the signature. Could be any signature scheme\n * @param _entryPoint Address of Entry Point contract\n * @param _facetRegistry Address of Facet Registry. Facet Registry is a registry holding trusted facets that could be added to user's wallet\n * @param _defaultFallBack Address of Default FallBack Handler. Middleware contract for more efficient deployment\n * @param _ownerPublicKey Bytes of Owner Public Key using for initialization\n */\n constructor(\n address _accountFacet,\n address _verificationFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallBack,\n bytes memory _ownerPublicKey\n ) payable {\n bytes memory initCall = abi.encodeWithSignature(\n \"initialize(address,address,address,address,bytes)\",\n _verificationFacet,\n _entryPoint,\n _facetRegistry,\n _defaultFallBack,\n _ownerPublicKey\n );\n (bool success, bytes memory result) = _accountFacet.delegatecall(\n initCall\n );\n if (!success || uint256(bytes32(result)) != 1) {\n revert Barz__InitializationFailure();\n }\n }\n\n /**\n * @notice Fallback function for Barz complying with Diamond Standard with customization of adding Default Fallback Handler\n * @dev Find facet for function that is called and execute the function if a facet is found and return any value.\n */\n fallback() external payable {\n LibDiamond.DiamondStorage storage ds;\n bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION;\n // get diamond storage\n assembly {\n ds.slot := position\n }\n // get facet from function selector\n address facet = address(bytes20(ds.facets[msg.sig]));\n if (facet == address(0))\n facet = ds.defaultFallbackHandler.facetAddress(msg.sig);\n require(facet != address(0), \"Barz: Function does not exist\");\n // Execute external function from facet using delegatecall and return any value.\n assembly {\n // copy function selector and any arguments\n calldatacopy(0, 0, calldatasize())\n // execute function call using the facet\n let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)\n // get any return value\n returndatacopy(0, 0, returndatasize())\n // return any return value or error back to the caller\n switch result\n case 0 {\n revert(0, returndatasize())\n }\n default {\n return(0, returndatasize())\n }\n }\n }\n\n /**\n * @notice Receive function to receive native token without data\n */\n receive() external payable {}\n}\n" + }, + "contracts/BarzFactory.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Barz} from \"./Barz.sol\";\nimport {IBarzFactory} from \"./interfaces/IBarzFactory.sol\";\n\n/**\n * @title Barz Factory\n * @dev Contract to easily deploy Barz to a pre-computed address with a single call\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract BarzFactory is IBarzFactory {\n address public immutable accountFacet;\n address public immutable entryPoint;\n address public immutable facetRegistry;\n address public immutable defaultFallback;\n\n /**\n * @notice Sets the initialization data for Barz contract initialization\n * @param _accountFacet Account Facet to be used to create Barz\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\n * @param _facetRegistry Facet Registry to be used to create Barz\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\n */\n constructor(\n address _accountFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallback\n ) {\n accountFacet = _accountFacet;\n entryPoint = _entryPoint;\n facetRegistry = _facetRegistry;\n defaultFallback = _defaultFallback;\n }\n\n /**\n * @notice Creates the Barz with a single call. It creates the Barz contract with the givent verification facet\n * @param _verificationFacet Address of verification facet used for creating the barz account\n * @param _owner Public Key of the owner to initialize barz account\n * @param _salt Salt used for deploying barz with create2\n * @return barz Instance of Barz contract deployed with the given parameters\n */\n function createAccount(\n address _verificationFacet,\n bytes calldata _owner,\n uint256 _salt\n ) external override returns (Barz barz) {\n address addr = getAddress(_verificationFacet, _owner, _salt);\n uint codeSize = addr.code.length;\n if (codeSize > 0) {\n return Barz(payable(addr));\n }\n barz = new Barz{salt: bytes32(_salt)}(\n accountFacet,\n _verificationFacet,\n entryPoint,\n facetRegistry,\n defaultFallback,\n _owner\n );\n emit BarzDeployed(address(barz));\n }\n\n /**\n * @notice Calculates the address of Barz with the given parameters\n * @param _verificationFacet Address of verification facet used for creating the barz account\n * @param _owner Public Key of the owner to initialize barz account\n * @param _salt Salt used for deploying barz with create2\n * @return barzAddress Precalculated Barz address\n */\n function getAddress(\n address _verificationFacet,\n bytes calldata _owner,\n uint256 _salt\n ) public view override returns (address barzAddress) {\n bytes memory bytecode = getBytecode(\n accountFacet,\n _verificationFacet,\n entryPoint,\n facetRegistry,\n defaultFallback,\n _owner\n );\n bytes32 hash = keccak256(\n abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(bytecode)\n )\n );\n barzAddress = address(uint160(uint256(hash)));\n }\n\n /**\n * @notice Returns the bytecode of Barz with the given parameter\n * @param _accountFacet Account Facet to be used to create Barz\n * @param _verificationFacet Verification Facet to be used to create Barz\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\n * @param _facetRegistry Facet Registry to be used to create Barz\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\n * @param _ownerPublicKey Public Key of owner to be used to initialize Barz ownership\n * @return barzBytecode Bytecode of Barz\n */\n function getBytecode(\n address _accountFacet,\n address _verificationFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallback,\n bytes calldata _ownerPublicKey\n ) public pure override returns (bytes memory barzBytecode) {\n bytes memory bytecode = type(Barz).creationCode;\n barzBytecode = abi.encodePacked(\n bytecode,\n abi.encode(\n _accountFacet,\n _verificationFacet,\n _entryPoint,\n _facetRegistry,\n _defaultFallback,\n _ownerPublicKey\n )\n );\n }\n\n /**\n * @notice Returns the creation code of the Barz contract\n * @return creationCode Creation code of Barz\n */\n function getCreationCode()\n public\n pure\n override\n returns (bytes memory creationCode)\n {\n creationCode = type(Barz).creationCode;\n }\n}\n" + }, + "contracts/facets/AccountFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {UserOperation} from \"../aa-4337/interfaces/UserOperation.sol\";\nimport {IEntryPoint} from \"../aa-4337/interfaces/IEntryPoint.sol\";\nimport {BaseAccount} from \"../aa-4337/core/BaseAccount.sol\";\nimport {LibAppStorage, BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {IFacetRegistry} from \"../infrastructure/interfaces/IFacetRegistry.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {IERC1271} from \"../interfaces/ERC/IERC1271.sol\";\nimport {IAccountFacet} from \"./interfaces/IAccountFacet.sol\";\n\n/**\n * @title Account Facet\n * @dev Account module contract that provides the account features and initialization of signer\n * compatible with EIP-1271 & EIP-4337\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract AccountFacet is IAccountFacet, BarzStorage, BaseAccount {\n using ECDSA for bytes32;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceAccountInitialize();\n }\n\n /**\n * @notice Returns the address of EntryPoint contract registered to Barz account\n */\n function entryPoint() public view override returns (IEntryPoint) {\n return s.entryPoint;\n }\n\n /**\n * @notice Initializes the initial storage of the Barz contract.\n * @dev This method can only be called during the initialization or signature migration.\n * If the proxy contract was created without initialization, anyone can call initialize.\n * Barz calls initialize in constructor in an atomic transaction during deployment\n * @param _verificationFacet Facet contract handling the verificationi\n * @param _anEntryPoint Entrypoint contract defined in EIP-4337 handling the flow of UserOp\n * @param _facetRegistry Registry of Facets that hold all facet information\n * @param _defaultFallBackHandler Middleware contract for default facets\n * @param _ownerPublicKey Bytes of owner public key\n */\n function initialize(\n address _verificationFacet,\n address _anEntryPoint,\n address _facetRegistry,\n address _defaultFallBackHandler,\n bytes calldata _ownerPublicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceAccountInitialize();\n s.entryPoint = IEntryPoint(_anEntryPoint);\n s.facetRegistry = IFacetRegistry(_facetRegistry);\n LibDiamond.diamondStorage().defaultFallbackHandler = IDiamondLoupe(\n _defaultFallBackHandler\n );\n\n _cutDiamondAccountFacet(_verificationFacet);\n\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n _ownerPublicKey\n );\n // Every Verification Facet should comply with initializeSigner(bytes)\n // to be compatible with the Barz contract(for initialization)\n (bool success, bytes memory result) = _verificationFacet.delegatecall(\n initCall\n );\n if (!success || uint256(bytes32(result)) != 1) {\n revert AccountFacet__InitializationFailure();\n }\n\n initSuccess = 1;\n emit AccountInitialized(s.entryPoint, _ownerPublicKey);\n }\n\n function _cutDiamondAccountFacet(address _verificationFacet) internal {\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](1);\n\n bytes4 ownerVerificationFuncSelector = IVerificationFacet(\n _verificationFacet\n ).validateOwnerSignatureSelector();\n\n bytes4[] memory verificationFunctionSelectors = new bytes4[](3);\n verificationFunctionSelectors[0] = IERC1271.isValidSignature.selector;\n verificationFunctionSelectors[1] = ownerVerificationFuncSelector;\n verificationFunctionSelectors[2] = IVerificationFacet.owner.selector;\n cut[0] = IDiamondCut.FacetCut({\n facetAddress: _verificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: verificationFunctionSelectors\n });\n\n LibDiamond.diamondCut(cut, address(0), \"\");\n }\n\n /**\n * @notice Calls the destination with inputted calldata and value from EntryPoint\n * @dev This method executes the calldata coming from the EntryPoint.\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\n * @param _dest Address of destination where the call will be forwarded to\n * @param _value Amount of native coin the owner is willing to send(e.g. ETH, BNB)\n * @param _func Bytes of calldata to execute in the destination address\n */\n function execute(\n address _dest,\n uint256 _value,\n bytes calldata _func\n ) external override onlyWhenUnlocked {\n _requireFromEntryPoint();\n address restrictionsFacet = LibDiamond.restrictionsFacet();\n if (restrictionsFacet == address(0)) _call(_dest, _value, _func);\n else _callWithRestrictions(_dest, _value, _func, restrictionsFacet);\n }\n\n /**\n * @notice Batch calls the destination with inputted calldata and value from EntryPoint\n * @dev This method batch executes the calldata coming from the EntryPoint.\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\n * @param _dest Array of addresses of destination where the call will be forwarded to\n * @param _value Array of amount of native coin the owner is willing to send(e.g. ETH, BNB)\n * @param _func Array of bytes of calldata to execute in the destination address\n */\n function executeBatch(\n address[] calldata _dest,\n uint256[] calldata _value,\n bytes[] calldata _func\n ) external override onlyWhenUnlocked {\n _requireFromEntryPoint();\n if (_dest.length != _func.length || _dest.length != _value.length)\n revert AccountFacet__InvalidArrayLength();\n address restrictionsFacet = LibDiamond.restrictionsFacet();\n if (restrictionsFacet == address(0)) {\n for (uint256 i; i < _dest.length; ) {\n _call(_dest[i], _value[i], _func[i]);\n unchecked {\n ++i;\n }\n }\n } else {\n for (uint256 i; i < _dest.length; ) {\n _callWithRestrictions(\n _dest[i],\n _value[i],\n _func[i],\n restrictionsFacet\n );\n unchecked {\n ++i;\n }\n }\n }\n }\n\n /**\n * @notice Validates the signature field of UserOperation\n * @dev This method validates if the signature of UserOp is indeed valid by delegating the call to Verification Facet\n * Barz makes a call to the pre-registered Verification Facet address in App Storage\n * @param _userOp UserOperation from owner to be validated\n * @param _userOpHash Hash of UserOperation given from the EntryPoint contract\n */\n function _validateSignature(\n UserOperation calldata _userOp,\n bytes32 _userOpHash\n ) internal override returns (uint256 validationData) {\n // Get Facet with Function Selector\n address facet = LibLoupe.facetAddress(s.validateOwnerSignatureSelector);\n if (facet == address(0))\n revert AccountFacet__NonExistentVerificationFacet();\n\n // Make function call to VerificationFacet\n bytes memory validateCall = abi.encodeWithSelector(\n s.validateOwnerSignatureSelector,\n _userOp,\n _userOpHash\n );\n (bool success, bytes memory result) = facet.delegatecall(validateCall);\n if (!success) revert AccountFacet__CallNotSuccessful();\n validationData = uint256(bytes32(result));\n if (validationData == 0) emit VerificationSuccess(_userOpHash);\n else emit VerificationFailure(_userOpHash);\n }\n\n /**\n * @notice Calls the target with the inputted value and calldata\n * @dev This method is the actual function in Barz that makes a call with an arbitrary owner-given data\n * @param _target Address of the destination contract which the call is getting forwarded to\n * @param _value Amount of Native coin the owner is wanting to make in this call\n * @param _data Calldata the owner is forwarding together in the call e.g. Swap/Token Transfer\n */\n function _call(\n address _target,\n uint256 _value,\n bytes memory _data\n ) internal {\n (bool success, bytes memory result) = _target.call{value: _value}(\n _data\n );\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n }\n\n /**\n * @notice Calls the target with the inputted value and calldata together with restrictions check\n * @dev This method is the actual function in Barz that makes a call with an arbitrary owner-given data\n * @param _target Address of the destination contract which the call is getting forwarded to\n * @param _value Amount of Native coin the owner is wanting to make in this call\n * @param _data Calldata the owner is forwarding together in the call e.g. Swap/Token Transfer\n * @param _restrictionsFacet Address of Facet to validate restrictions\n */\n function _callWithRestrictions(\n address _target,\n uint256 _value,\n bytes memory _data,\n address _restrictionsFacet\n ) internal {\n // NOTE: No restrictions facet, so restriction validation passes\n if (_checkRestrictions(_restrictionsFacet, _target, _value, _data) != 0)\n revert AccountFacet__RestrictionsFailure();\n\n (bool success, bytes memory result) = _target.call{value: _value}(\n _data\n );\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n }\n\n /**\n * @notice Checks restrictions if the restrictions facet exists\n * @dev This method checks if the restrictions facet exists and makes a verification call to an array of restrictions facet\n * @param _facet Address that holds the restrictions logic\n * @param _target Address the call is getting forwarded to\n * @param _value Amount of native coin the call is sending together with the call\n * @param _data Calldata to trigger execution in target address\n */\n function _checkRestrictions(\n address _facet,\n address _target,\n uint256 _value,\n bytes memory _data\n ) internal returns (uint256 result) {\n bytes memory call = abi.encodeWithSignature(\n \"verifyRestrictions(address,address,uint256,bytes)\",\n address(this),\n _target,\n _value,\n _data\n );\n (bool success, bytes memory response) = _facet.delegatecall(call);\n if (!success) revert AccountFacet__RestrictionsFailure();\n result = uint256(bytes32(response));\n }\n}\n" + }, + "contracts/facets/AccountRecoveryFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibFacetStorage, RecoveryStorage, RecoveryConfig, RecoveryApprovalConfig, ApprovalConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {IAccountRecoveryFacet} from \"./interfaces/IAccountRecoveryFacet.sol\";\n\n/**\n * @title Account Recovery Facet\n * @dev Contract that enables recovery of accounts when owner key is unavailable\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract AccountRecoveryFacet is IAccountRecoveryFacet, Modifiers {\n bytes constant UNINIT_CALL =\n abi.encodeWithSignature(\"uninitializeSigner()\");\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Approve recovery of account as guardian\n * @dev This method can only be called by guardian and guardian inputs the public key of the new owner\n * When the threshold(majority of guardians) passes, it automatically executes account recovery\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function approveAccountRecovery(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + _getApprovalValidationPeriod()\n );\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit RecoveryApproved(\n _recoveryPublicKey,\n msg.sender,\n approvalValidUntil\n );\n if (\n getRecoveryApprovalCountWithTimeValidity(recoveryPublicKeyHash) >=\n LibGuardian.majorityOfGuardians()\n ) _executeRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Revoke recovery of account as guardian\n * @dev This method can only be called by guardian and guardian inputs the public key of the new owner\n When the threshold(majority of guardians) passes, it automatically revokes account recovery when recovery is pending\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function revokeAccountRecoveryApproval(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n if (\n !rs\n .isNewOwnerApproved[recoveryPublicKeyHash][msg.sender].isApproved ||\n !(block.timestamp <\n rs\n .isNewOwnerApproved[recoveryPublicKeyHash][msg.sender]\n .validUntil)\n ) revert AccountRecoveryFacet__NonExistentApproval();\n\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(false, 0);\n emit RecoveryApprovalRevoked(_recoveryPublicKey, msg.sender);\n }\n\n /**\n * @notice Executes recovery with signatures or on-chain pre-approvals\n * @dev This method validates the signatures of guardians or checks the on-chain pre-approved calls to check if the threshold passes\n * When the threshold passes, account recovery is executed and revert otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _guardians Array of guardians address that are approving the recovery of Account\n * @param _signatures Array of signature bytes that signed the approval hash\n */\n function executeRecovery(\n bytes calldata _recoveryPublicKey,\n address[] calldata _guardians,\n bytes[] calldata _signatures\n ) external override {\n if (_isRecoveryPending())\n revert AccountRecoveryFacet__RecoveryAlreadyOngoing();\n if (_guardians.length != _signatures.length)\n revert AccountRecoveryFacet__InvalidArrayLength();\n validateNewOwner(_recoveryPublicKey);\n\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n\n _checkApprover(_guardians);\n _checkDuplicateOnChainApprover(recoveryPublicKeyHash, _guardians);\n\n if (\n _guardians.length +\n getRecoveryApprovalCountWithTimeValidity(\n recoveryPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians()\n ) revert AccountRecoveryFacet__InsufficientGuardians();\n for (uint256 i; i < _guardians.length; ) {\n if (!LibGuardian.isGuardian(_guardians[i]))\n revert AccountRecoveryFacet__InvalidGuardian();\n if (\n !SignatureChecker.isValidSignatureNow(\n _guardians[i],\n recoveryPublicKeyHash,\n _signatures[i]\n )\n ) revert AccountRecoveryFacet__InvalidGuardianSignature();\n unchecked {\n ++i;\n }\n }\n _executeRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Executes recovery of the account. Note that execution and finalization is a different process\n * @dev Executes the recovery and adds recovery data to recovery configuration. Locks the account\n * @param _recoveryPublicKey Public Key of the account for recovery\n */\n function _executeRecovery(bytes memory _recoveryPublicKey) internal {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n unchecked {\n ++rs.nonce;\n }\n uint64 executeAfter = uint64(block.timestamp + _getRecoveryPeriod());\n rs.recoveryConfigs[INNER_STRUCT] = RecoveryConfig(\n _recoveryPublicKey,\n executeAfter // NOTE: Remove guardian Count\n );\n LibAppStorage.setLock(\n block.timestamp + _getLockPeriod(),\n AccountRecoveryFacet.executeRecovery.selector\n );\n emit RecoveryExecuted(_recoveryPublicKey, executeAfter);\n }\n\n /**\n * @notice Finalize recovery after recovery pending period. Recovery pending period can be set by user beforehand in SecurityManager\n * @dev This method finalizes recovery and fully changes the ownership of the account to the newly inputted recovery public key\n */\n function finalizeRecovery() external override {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n if (\n uint64(block.timestamp) <=\n rs.recoveryConfigs[INNER_STRUCT].executeAfter\n ) revert AccountRecoveryFacet__RecoveryPeriodNotOver();\n bytes memory recoveryOwner = rs\n .recoveryConfigs[INNER_STRUCT]\n .recoveryPublicKey;\n\n delete rs.recoveryConfigs[INNER_STRUCT];\n\n LibAppStorage.setLock(0, bytes4(0));\n\n LibAppStorage.initiateSignerMigration();\n address verificationFacet = address(\n bytes20(\n LibDiamond.diamondStorage().facets[\n s.validateOwnerSignatureSelector\n ]\n )\n );\n (bool uninitSuccess, bytes memory uninitResult) = verificationFacet\n .delegatecall(UNINIT_CALL);\n if (!uninitSuccess) revert AccountRecoveryFacet__CallNotSuccesful();\n if (uint256(bytes32(uninitResult)) != 1)\n revert AccountRecoveryFacet__SignerUninitializationFailure();\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n recoveryOwner\n );\n (bool initSuccess, bytes memory initResult) = verificationFacet\n .delegatecall(initCall);\n if (!initSuccess) revert AccountRecoveryFacet__CallNotSuccesful();\n if (uint256(bytes32(initResult)) != 1)\n revert AccountRecoveryFacet__SignerInitializationFailure();\n LibAppStorage.finalizeSignerMigration();\n emit RecoveryFinalized(recoveryOwner);\n }\n\n /**\n * @notice Approves the cancellation of recovery\n * @dev This method approves the cancellation of recovery when recovery is still pending - waiting for finalization\n * @param _recoveryPublicKey Bytes of public key which is pending for recovery\n */\n function approveCancelRecovery(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"CancelRecovery\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + _getApprovalValidationPeriod()\n );\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit RecoveryCancellationApproved(_recoveryPublicKey, msg.sender);\n if (\n getRecoveryApprovalCountWithTimeValidity(recoveryPublicKeyHash) >=\n LibGuardian.majorityOfGuardians()\n ) {\n _cancelRecovery(_recoveryPublicKey);\n }\n }\n\n /**\n * @notice Hardstops an ongoing recovery\n * @dev This method provides a safety mechanism to protect owners of malicious guardians.\n * Owners can hardstop recovery when an malicious guardians starts the recovery process.\n * @param _signature Signature of the owner that signs the hash to hardstop recovery\n */\n function hardstopRecovery(bytes calldata _signature) external override {\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n \"0\",\n \"HardstopRecovery\"\n );\n if (\n !SignatureChecker.isValidSignatureNow(\n address(this),\n recoveryPublicKeyHash,\n _signature\n )\n ) revert AccountRecoveryFacet__InvalidOwnerSignature();\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n unchecked {\n ++rs.nonce;\n }\n delete rs.recoveryConfigs[INNER_STRUCT];\n LibAppStorage.setLock(0, bytes4(0));\n emit RecoveryHardstopped();\n }\n\n /**\n * @notice Cancels recovery with signatures or on-chain pre-approvals\n * @dev This method validates the signatures of guardians or checks the on-chain pre-approved calls to check if the threshold passes\n * When the threshold passes, account recovery is canceled and revert otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _guardians Array of guardians address that are approving the recovery of Account\n * @param _signatures Array of signature bytes that signed the cancellation approval hash\n */\n function cancelRecovery(\n bytes calldata _recoveryPublicKey,\n address[] calldata _guardians,\n bytes[] calldata _signatures\n ) external override {\n if (_guardians.length != _signatures.length)\n revert AccountRecoveryFacet__InvalidArrayLength();\n validateNewOwner(_recoveryPublicKey);\n\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"CancelRecovery\"\n );\n\n _checkApprover(_guardians);\n _checkDuplicateOnChainApprover(recoveryPublicKeyHash, _guardians);\n\n if (\n _guardians.length +\n getRecoveryApprovalCountWithTimeValidity(\n recoveryPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians()\n ) revert AccountRecoveryFacet__InsufficientGuardians();\n for (uint256 i; i < _guardians.length; ) {\n if (!LibGuardian.isGuardian(_guardians[i]))\n revert AccountRecoveryFacet__CallerNotGuardian();\n if (\n !SignatureChecker.isValidSignatureNow(\n _guardians[i],\n recoveryPublicKeyHash,\n _signatures[i]\n )\n ) revert AccountRecoveryFacet__InvalidGuardianSignature();\n unchecked {\n ++i;\n }\n }\n _cancelRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Cancel recovery when the recovery is pending. Unlock the account as well\n * @dev This method checks if the recovery is pending and reverts if not pending.\n * It increases the recovery nonce and deletes the recovery information and gets a small portion of gas in return\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function _cancelRecovery(bytes memory _recoveryPublicKey) internal {\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n LibAppStorage.setLock(0, bytes4(0));\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n unchecked {\n ++rs.nonce;\n }\n delete rs.recoveryConfigs[INNER_STRUCT];\n emit RecoveryCanceled(_recoveryPublicKey);\n }\n\n /**\n * @notice Validates the format of public key to be used for recovery\n * @dev This method checks if the public key format is correct and reverts otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function validateNewOwner(\n bytes calldata _recoveryPublicKey\n ) public view override {\n if (\n !IVerificationFacet(\n LibLoupe.facetAddress(s.validateOwnerSignatureSelector)\n ).isValidKeyType(_recoveryPublicKey)\n ) revert AccountRecoveryFacet__InvalidRecoveryPublicKey();\n }\n\n /**\n * @notice Checks if recovery is currently pending\n * @return isPending Boolean indicating if recovery is pending\n */\n function _isRecoveryPending() internal view returns (bool isPending) {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n isPending = (rs.recoveryConfigs[INNER_STRUCT].executeAfter > 0);\n }\n\n /**\n * @notice Calculate the recovery hash dependent on chain, wallet address, nonce with EIP-191 prefix for safety\n * @dev Returns the keccak256 hash of EIP-191 msg hash packed with public key, salt, nonce, wallet address, etc\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _saltString Salt string to uniquely identify each recovery hash and for security\n * @return recoveryKeyHash Bytes32 string of the recovery hash\n */\n function getApprovalRecoveryKeyHash(\n bytes memory _recoveryPublicKey,\n string memory _saltString\n ) public view override returns (bytes32 recoveryKeyHash) {\n recoveryKeyHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n _recoveryPublicKey,\n _saltString,\n address(this),\n block.chainid,\n LibFacetStorage.recoveryStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Check the onchain approval of guardians and returns the number of guardians that approved\n * @dev Loop through the guardian addresses and returns the number of guardians that approved this recovery hash\n * @param _recoveryPublicKeyHash Bytes hash of newly recovered public key and recovery value of the account\n * @return approvalCount Number of guardians that approved\n */\n function getRecoveryApprovalCountWithTimeValidity(\n bytes32 _recoveryPublicKeyHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n for (uint256 i; i < guardianLength; ) {\n if (isRecoveryApproved(_recoveryPublicKeyHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Checks if the recovery is approved by the given approver\n * @param _recoveryPublicKeyHash Hash of the public key and configuration for recovery\n * @param _approver Address of approver\n * @return isApproved Bool value if recovery hash is approved\n */\n function isRecoveryApproved(\n bytes32 _recoveryPublicKeyHash,\n address _approver\n ) public view override returns (bool isApproved) {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n if (\n rs\n .isNewOwnerApproved[_recoveryPublicKeyHash][_approver].isApproved &&\n block.timestamp <\n rs.isNewOwnerApproved[_recoveryPublicKeyHash][_approver].validUntil\n ) {\n isApproved = true;\n }\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _recoveryPublicKeyHash Hash of recovery information\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _recoveryPublicKeyHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isRecoveryApproved(_recoveryPublicKeyHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert AccountRecoveryFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the lock period of this wallet address from security manager\n * @return lockPeriod value of lock period\n */\n function _getLockPeriod() internal view returns (uint256 lockPeriod) {\n lockPeriod = securityManager.lockPeriodOf(address(this));\n if (lockPeriod == 0) revert AccountRecoveryFacet__InvalidLockPeriod();\n }\n\n /**\n * @notice Returns the lock period of this wallet address from security manager\n * @return recoveryPeriod value of recovery period\n */\n function _getRecoveryPeriod()\n internal\n view\n returns (uint256 recoveryPeriod)\n {\n recoveryPeriod = securityManager.recoveryPeriodOf(address(this));\n if (recoveryPeriod == 0)\n revert AccountRecoveryFacet__InvalidRecoveryPeriod();\n }\n\n /**\n * @notice Returns the approval validation period of this wallet address from security manager\n * @return approvalValidationPeriod value of approval validation period\n */\n function _getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod == 0)\n revert AccountRecoveryFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the recovery nonce of this wallet address from security manager\n * @return nonce value of recovery nonce\n */\n function getRecoveryNonce() public view override returns (uint128 nonce) {\n nonce = LibFacetStorage.recoveryStorage().nonce;\n }\n\n /**\n * @notice Returns the recovery information of the pending recovery\n * @return recoveryConfig value struct of pending recovery\n */\n function getPendingRecovery()\n public\n view\n override\n returns (RecoveryConfig memory recoveryConfig)\n {\n recoveryConfig = LibFacetStorage.recoveryStorage().recoveryConfigs[\n INNER_STRUCT\n ];\n }\n}\n" + }, + "contracts/facets/base/DiamondCutFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibGuardian} from \"../../libraries/LibGuardian.sol\";\nimport {ISecurityManager} from \"../../infrastructure/interfaces/ISecurityManager.sol\";\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibFacetStorage, DiamondCutApprovalConfig, ApprovalConfig} from \"../../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"../Modifiers.sol\";\nimport {IDiamondCut} from \"./interfaces/IDiamondCut.sol\";\n\n/**\n * @title DiamondCut Facet\n * @dev Responsible for adding/removing/replace facets in Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DiamondCutFacet is Modifiers, IDiamondCut {\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Updates the flag for the interfaceId\n * @param _interfaceId InterfaceID to update the mapping\n * @param _flag Bool value to update the mapping of the given interface ID\n */\n function updateSupportsInterface(\n bytes4 _interfaceId,\n bool _flag\n ) external override onlyWhenUnlocked {\n LibDiamond.enforceIsSelf();\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId] = _flag;\n emit SupportsInterfaceUpdated(_interfaceId, _flag);\n }\n\n /**\n * @notice Add/replace/remove any number of functions and optionally execute\n * a function with delegatecall when guardians don't exist\n * @param _diamondCut Contains the facet addresses and function selectors\n * @param _init The address of the contract or facet to execute _calldata. It's prohibited in Barz\n */\n function diamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata\n ) external override onlyWhenUnlocked {\n LibDiamond.enforceIsSelf();\n\n _checkFacetCutValidity(_diamondCut);\n // require approval from guardian if guardian exists\n if (0 != LibGuardian.guardianCount())\n revert DiamondCutFacet__InvalidRouteWithGuardian();\n if (address(0) != _init) revert DiamondCutFacet__InvalidInitAddress();\n\n unchecked {\n ++LibFacetStorage.diamondCutStorage().nonce;\n }\n LibDiamond.diamondCut(_diamondCut, address(0), \"\");\n }\n\n /**\n * @notice Add/replace/remove any number of functions and optionally execute\n * a function with delegatecall when guardians exist\n * @param _diamondCut Contains the facet addresses and function selectors\n * @param _approvers Guardian or owner address that approves the diamond cut\n * @param _signatures Signature of Guardians or owner that approves the diamond cut\n */\n function diamondCutWithGuardian(\n FacetCut[] calldata _diamondCut,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n ) external override onlyWhenUnlocked {\n if (_approvers.length != _signatures.length)\n revert DiamondCutFacet__InvalidArrayLength();\n _checkFacetCutValidity(_diamondCut);\n if (0 == LibGuardian.guardianCount())\n revert DiamondCutFacet__InvalidRouteWithGuardian();\n\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(cutHash, _approvers);\n\n bool onChainOwnerApproval = getOwnerCutApprovalWithTimeValidity(\n cutHash\n );\n\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n if (\n _approvers.length +\n getDiamondCutApprovalCountWithTimeValidity(cutHash) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert DiamondCutFacet__InsufficientApprovers();\n\n bool ownerApproved;\n for (uint256 i; i < _approvers.length; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n _approvers[i] != address(this)\n ) revert DiamondCutFacet__InvalidApprover();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert DiamondCutFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n cutHash,\n _signatures[i]\n )\n ) revert DiamondCutFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n if (!ownerApproved && !onChainOwnerApproval)\n revert DiamondCutFacet__LackOfOwnerApproval();\n\n unchecked {\n ++LibFacetStorage.diamondCutStorage().nonce;\n }\n LibDiamond.diamondCut(_diamondCut, address(0), \"\");\n }\n\n /**\n * @notice Approves diamond cut. This can only be called directly from guardian or owner\n * @param _diamondCut Contains the facet addresses and function selectors\n */\n function approveDiamondCut(\n FacetCut[] calldata _diamondCut\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\n if (LibGuardian.guardianCount() == 0)\n revert DiamondCutFacet__InvalidRouteWithoutGuardian();\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n _checkFacetCutValidity(_diamondCut);\n\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(\n true,\n approvalValidUntil\n );\n emit DiamondCutApproved(_diamondCut);\n if (\n (getDiamondCutApprovalCountWithTimeValidity(cutHash) >=\n LibGuardian.majorityOfGuardians()) &&\n getOwnerCutApprovalWithTimeValidity(cutHash)\n ) {\n unchecked {\n ++LibFacetStorage.diamondCutStorage().nonce;\n }\n LibDiamond.diamondCut(_diamondCut, address(0), \"\");\n }\n }\n\n /**\n * @notice Revokes the approval of diamond cut. This can only be called directly from guardian or owner\n * @param _diamondCut Contains the facet addresses and function selectors\n */\n function revokeDiamondCutApproval(\n FacetCut[] calldata _diamondCut\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\n if (!ds.isDiamondCutApproved[cutHash][msg.sender].isApproved)\n revert DiamondCutFacet__CannotRevokeUnapproved();\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(false, 0);\n emit DiamondCutApprovalRevoked(_diamondCut);\n }\n\n /**\n * @notice Gets the number of approvals of diamond cut from guardians\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n */\n function getDiamondCutApprovalCountWithTimeValidity(\n bytes32 _diamondCutHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardiansLength = guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n if (isCutApproved(_diamondCutHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n return approvalCount;\n }\n\n /**\n * @notice Returns if the owner has approved the diamond cut\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @return isApprovedByOwner Bool value showing if the owner approved the cut\n */\n function getOwnerCutApprovalWithTimeValidity(\n bytes32 _diamondCutHash\n ) public view override returns (bool isApprovedByOwner) {\n isApprovedByOwner = isCutApproved(_diamondCutHash, address(this));\n }\n\n /**\n * @notice Returns if the given approver has approved the diamond cut\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @param _approver Address of approver\n * @return isApproved Bool value showing if the approver approved the cut\n */\n function isCutApproved(\n bytes32 _diamondCutHash,\n address _approver\n ) public view override returns (bool isApproved) {\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n isApproved = (ds\n .isDiamondCutApproved[_diamondCutHash][_approver].isApproved &&\n block.timestamp <\n ds.isDiamondCutApproved[_diamondCutHash][_approver].validUntil);\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _diamondCutHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isCutApproved(_diamondCutHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert DiamondCutFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the diamond cut hash. This function ensures that this hash is safe from replay attack by including\n * salt, address, chainId, and nonce, etc.\n * @param _diamondCut Contains the facet addresses and function selectors\n * @return cutHash Diamond Cut Hash\n */\n function getDiamondCutHash(\n FacetCut[] calldata _diamondCut\n ) public view override returns (bytes32 cutHash) {\n cutHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n keccak256(abi.encode(_diamondCut)),\n address(this),\n block.chainid,\n LibFacetStorage.diamondCutStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Returns the approval validation Period\n * @dev This method fetches the validation period from the security manager\n * @return approvalValidationPeriod Approval validation period of Barz contract fetched from security manager\n */\n function getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod <= 0)\n revert DiamondCutFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the diamond cut nonce of this wallet\n * @dev This method fetches the nonce from diamond cut storage\n * @return cutNonce Nonce of diamond cut to protect from reply attacks\n */\n function getDiamondCutNonce()\n public\n view\n override\n returns (uint128 cutNonce)\n {\n cutNonce = LibFacetStorage.diamondCutStorage().nonce;\n }\n}\n" + }, + "contracts/facets/base/DiamondLoupeFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {IERC165} from \"../../interfaces/ERC/IERC165.sol\";\nimport {IERC1271} from \"../../interfaces/ERC/IERC1271.sol\";\nimport {IERC677Receiver} from \"../../interfaces/ERC/IERC677Receiver.sol\";\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC1155Receiver} from \"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\";\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../../libraries/LibLoupe.sol\";\nimport {LibUtils} from \"../../libraries/LibUtils.sol\";\nimport {IDiamondCut} from \"../../facets/base/interfaces/IDiamondCut.sol\";\nimport {IStorageLoupe} from \"./interfaces/IStorageLoupe.sol\";\nimport {IDiamondLoupe} from \"./interfaces/IDiamondLoupe.sol\";\n\n/**\n * @title DiamondLoupe Facet\n * @dev DiamondLoupe contract compatible with EIP-2535\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DiamondLoupeFacet is IDiamondLoupe, IStorageLoupe, IERC165 {\n // Diamond Loupe Functions\n ////////////////////////////////////////////////////////////////////\n /// These functions are expected to be called frequently by tools off-chain.\n\n /**\n * @notice Gets all facets and their selectors.\n * @dev Barz uses a special architecture called default fallback handler. Default Fallback handler is used as a middleware\n * that holds the mapping of facet function selector and facet address that Barz uses. This helps Barz to reduce\n * significant amount of gas during the initialization process.\n * Hence, this method aggregates both the facet information from DefaulFallbackHandler and in diamond storage and shows the data to users.\n * @return facets_ Facet\n */\n function facets() public view override returns (Facet[] memory facets_) {\n Facet[] memory defaultFacet = LibDiamond\n .diamondStorage()\n .defaultFallbackHandler\n .facets();\n Facet[] memory _facets = LibLoupe.facets();\n uint256 numFacets = _facets.length;\n bytes4[] memory keys;\n address[] memory values;\n for (uint256 i; i < numFacets; ) {\n uint256 selectorsLength = _facets[i].functionSelectors.length;\n for (uint256 j; j < selectorsLength; ) {\n (keys, values) = LibUtils.setValue(\n keys,\n values,\n _facets[i].functionSelectors[j],\n _facets[i].facetAddress\n );\n unchecked {\n ++j;\n }\n }\n unchecked {\n ++i;\n }\n }\n {\n bool iIncrement;\n for (uint256 i; i < defaultFacet.length; ) {\n bool jIncrement;\n for (\n uint256 j;\n j < defaultFacet[i].functionSelectors.length;\n\n ) {\n if (\n LibUtils.getValue(\n keys,\n values,\n defaultFacet[i].functionSelectors[j]\n ) != address(0)\n ) {\n if (defaultFacet[i].functionSelectors.length == 1) {\n defaultFacet = LibUtils.removeFacetElement(\n defaultFacet,\n i\n );\n iIncrement = true;\n break;\n }\n defaultFacet[i].functionSelectors = LibUtils\n .removeElement(\n defaultFacet[i].functionSelectors,\n j\n );\n jIncrement = true;\n }\n if (!jIncrement) {\n unchecked {\n ++j;\n }\n } else {\n jIncrement = false;\n }\n }\n if (!iIncrement) {\n unchecked {\n ++i;\n }\n } else {\n iIncrement = false;\n }\n }\n }\n {\n uint256 facetLength = numFacets + defaultFacet.length;\n facets_ = new Facet[](facetLength);\n uint256 defaultFacetIndex;\n for (uint256 i; i < facetLength; ) {\n if (i < numFacets) {\n facets_[i] = _facets[i];\n bool jIncrementor;\n for (uint256 j; j < defaultFacet.length; ) {\n if (\n facets_[i].facetAddress ==\n defaultFacet[j].facetAddress\n ) {\n facets_[i].functionSelectors = LibUtils.mergeArrays(\n _facets[i].functionSelectors,\n defaultFacet[j].functionSelectors\n );\n defaultFacet = LibUtils.removeFacetElement(\n defaultFacet,\n j\n );\n jIncrementor = true;\n {\n facets_ = LibUtils.removeFacetElement(\n facets_,\n facets_.length - 1\n );\n }\n --facetLength;\n }\n if (!jIncrementor) {\n unchecked {\n ++j;\n }\n } else {\n jIncrementor = false;\n }\n }\n } else {\n facets_[i] = defaultFacet[defaultFacetIndex];\n ++defaultFacetIndex;\n }\n unchecked {\n ++i;\n }\n }\n }\n }\n\n /**\n * @notice Gets all the function selectors provided by a facet.\n * @param _facet The facet address.\n * @return facetFunctionSelectors_\n */\n function facetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n Facet[] memory facet = facets();\n uint256 facetLength = facet.length;\n for (uint256 i; i < facetLength; ) {\n if (facet[i].facetAddress == _facet)\n return facet[i].functionSelectors;\n unchecked {\n ++i;\n }\n }\n return facetFunctionSelectors_;\n }\n\n /**\n * @notice Get all the facet addresses used by Barz.\n * @return facetAddresses_\n */\n function facetAddresses()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n Facet[] memory facet = facets();\n uint256 facetLength = facet.length;\n facetAddresses_ = new address[](facetLength);\n for (uint256 i; i < facetLength; ) {\n facetAddresses_[i] = facet[i].facetAddress;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Gets the facet that supports the given selector.\n * @dev If facet is not found return address(0).\n * @param _functionSelector The function selector.\n * @return facetAddress_ The facet address.\n */\n function facetAddress(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n\n facetAddress_ = address(bytes20(ds.facets[_functionSelector]));\n if (facetAddress_ == address(0)) {\n facetAddress_ = IDiamondLoupe(ds.defaultFallbackHandler)\n .facetAddress(_functionSelector);\n }\n }\n\n /**\n * @notice SupportInterface to be compatible with EIP 165\n * @param _interfaceId Interface ID for detecting the interface\n * @return isSupported Bool value showing if the standard is supported in the contract\n */\n function supportsInterface(\n bytes4 _interfaceId\n ) external view override returns (bool isSupported) {\n isSupported =\n _interfaceId == type(IERC165).interfaceId ||\n _interfaceId == IDiamondCut.diamondCut.selector ||\n _interfaceId == type(IDiamondLoupe).interfaceId ||\n _interfaceId == type(IERC1155Receiver).interfaceId ||\n _interfaceId == type(IERC721Receiver).interfaceId ||\n _interfaceId == type(IERC777Recipient).interfaceId ||\n _interfaceId == IERC1271.isValidSignature.selector ||\n _interfaceId == type(IERC677Receiver).interfaceId ||\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId];\n }\n\n /**\n * @notice Returns the facet from the diamond storage. This excludes the facets from the default fallback handler\n * @return facets_ Facet information attached directly to diamond storage\n */\n function facetsFromStorage()\n external\n view\n override\n returns (Facet[] memory facets_)\n {\n facets_ = LibLoupe.facets();\n }\n\n /**\n * @notice Returns the facet address attached to the given function selector. This excludes the facets from the default fallback handler\n * @param _functionSelector Function selector to fetch the facet address from diamond storage\n * @return facetAddress_ Facet address mapped with the function selector\n */\n function facetAddressFromStorage(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n facetAddress_ = LibLoupe.facetAddress(_functionSelector);\n }\n\n /**\n * @notice Returns all facet addresses attached directly to diamond storage. This excludes the facets from the default fallback handler\n * @return facetAddresses_ All facet addresses attached directly to diamond storage\n */\n function facetAddressesFromStorage()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n facetAddresses_ = LibLoupe.facetAddresses();\n }\n\n /**\n * @notice Returns function selectors of given facet address attached directly to diamond storage. This excludes the facets from the default fallback handler\n * @param _facet Facet address to fetch the facet function selectors from diamond storage\n * @return facetFunctionSelectors_ Facet function selectors of the given facet address\n */\n function facetFunctionSelectorsFromStorage(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n facetFunctionSelectors_ = LibLoupe.facetFunctionSelectors(_facet);\n }\n}\n" + }, + "contracts/facets/base/interfaces/IDiamondCut.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title DiamondCut Facet Interface\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IDiamondCut {\n error DiamondCutFacet__InvalidRouteWithGuardian();\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\n error DiamondCutFacet__InvalidArrayLength();\n error DiamondCutFacet__InsufficientApprovers();\n error DiamondCutFacet__InvalidApprover();\n error DiamondCutFacet__InvalidApproverSignature();\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\n error DiamondCutFacet__CannotRevokeUnapproved();\n error DiamondCutFacet__LackOfOwnerApproval();\n error DiamondCutFacet__OwnerAlreadyApproved();\n error DiamondCutFacet__DuplicateApproval();\n error DiamondCutFacet__InvalidInitAddress();\n\n event DiamondCutApproved(FacetCut[] diamondCut);\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\n\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\n\n enum FacetCutAction {\n Add,\n Replace,\n Remove\n }\n // Add=0, Replace=1, Remove=2\n\n struct FacetCut {\n address facetAddress;\n FacetCutAction action;\n bytes4[] functionSelectors;\n }\n\n /// @notice Add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param diamondCut Contains the facet addresses and function selectors\n /// @param init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function diamondCut(\n FacetCut[] calldata diamondCut,\n address init,\n bytes calldata _calldata\n ) external;\n\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\n\n function diamondCutWithGuardian(\n FacetCut[] calldata diamondCut,\n address[] calldata approvers,\n bytes[] calldata signatures\n ) external;\n\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\n\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\n\n function getDiamondCutApprovalCountWithTimeValidity(\n bytes32 diamondCutHash\n ) external view returns (uint256);\n\n function getOwnerCutApprovalWithTimeValidity(\n bytes32 diamondCutHash\n ) external view returns (bool);\n\n function isCutApproved(\n bytes32 diamondCutHash,\n address approver\n ) external view returns (bool);\n\n function getDiamondCutHash(\n FacetCut[] calldata diamondCut\n ) external view returns (bytes32);\n\n function getDiamondCutNonce() external view returns (uint128);\n}\n" + }, + "contracts/facets/base/interfaces/IDiamondLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n// A loupe is a small magnifying glass used to look at diamonds.\n// These functions look at diamonds\ninterface IDiamondLoupe {\n /// These functions are expected to be called frequently\n /// by tools.\n\n struct Facet {\n address facetAddress;\n bytes4[] functionSelectors;\n }\n\n /// @notice Gets all facet addresses and their four byte function selectors.\n /// @return facets_ Facet\n function facets() external view returns (Facet[] memory facets_);\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n /// @return facetFunctionSelectors_\n function facetFunctionSelectors(\n address _facet\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses()\n external\n view\n returns (address[] memory facetAddresses_);\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(\n bytes4 _functionSelector\n ) external view returns (address facetAddress_);\n}\n" + }, + "contracts/facets/base/interfaces/IStorageLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"./IDiamondLoupe.sol\";\n\n/**\n * @title LoupeFromStorage Interface\n * @dev Interface contract to function as a loupe facet directly attached to diamond storage of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IStorageLoupe {\n /// These functions are expected to be called frequently\n /// by tools.\n\n /// @notice Gets all facet addresses and their four byte function selectors.\n /// @return facets_ Facet\n function facetsFromStorage()\n external\n view\n returns (IDiamondLoupe.Facet[] memory);\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n function facetFunctionSelectorsFromStorage(\n address _facet\n ) external view returns (bytes4[] memory);\n\n /// @notice Get all the facet addresses used by a diamond.\n function facetAddressesFromStorage()\n external\n view\n returns (address[] memory);\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n function facetAddressFromStorage(\n bytes4 _functionSelector\n ) external view returns (address);\n}\n" + }, + "contracts/facets/GuardianFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibFacetStorage, GuardianStorage, StorageConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IGuardianFacet} from \"./interfaces/IGuardianFacet.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Guardian Facet\n * @dev Contract that enables addition/removal of guardians from Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract GuardianFacet is IGuardianFacet {\n ISecurityManager public immutable securityManager;\n uint8 public constant INNER_STRUCT = 0;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Add guardians to Barz.\n * @dev This method internally calls addGuardian which checks the validity of guardian address and adds\n * as guardian if valid\n * @param _guardians Array of addresses to add as guardian\n */\n function addGuardians(address[] calldata _guardians) external override {\n LibDiamond.enforceIsSelf();\n for (uint256 i; i < _guardians.length; ) {\n addGuardian(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Add a guardian to Barz.\n * @dev This method checks if the function is called by the owner and validates the address of guardian\n * When the validation passes, guardian address is added to the pending state waiting for confirmation\n * @param _guardian Address to add as guardian\n */\n function addGuardian(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (_guardian == address(this))\n revert GuardianFacet__GuardianCannotBeSelf();\n if (isGuardian(_guardian)) revert GuardianFacet__DuplicateGuardian();\n if (_guardian == address(0))\n revert GuardianFacet__ZeroAddressGuardian();\n if (\n keccak256(abi.encodePacked(_guardian)) ==\n keccak256(IVerificationFacet(address(this)).owner())\n ) revert GuardianFacet__OwnerCannotBeGuardian();\n\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n if (\n gs.pending[id] != 0 ||\n block.timestamp <= gs.pending[id] + getSecurityWindow()\n ) revert GuardianFacet__DuplicateGuardianAddition();\n\n uint256 securityPeriod = getAdditionSecurityPeriod();\n gs.pending[id] = block.timestamp + securityPeriod;\n emit GuardianAdditionRequested(\n _guardian,\n block.timestamp + securityPeriod\n );\n }\n\n /**\n * @notice Remove guardians from Barz.\n * @dev This method internally calls removeGuardian which checks the validity of guardian and removes\n * guardian when the request is valid\n * @param _guardians Array of addresses to be removed\n */\n function removeGuardians(address[] calldata _guardians) external override {\n LibDiamond.enforceIsSelf();\n for (uint256 i; i < _guardians.length; ) {\n removeGuardian(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Remove a guardian from Barz.\n * @dev This method validates if the guardian to be removed is a guardian and puts the guardian removal\n * to a pending state waiting to be confirmed.\n * @param _guardian Address of guardian to be removed\n */\n function removeGuardian(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n if (!isGuardian(_guardian)) revert GuardianFacet__NonExistentGuardian();\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n if (\n gs.pending[id] != 0 ||\n block.timestamp <= gs.pending[id] + getSecurityWindow()\n ) revert GuardianFacet__DuplicateGuardianRemoval();\n\n uint256 securityPeriod = getRemovalSecurityPeriod();\n gs.pending[id] = block.timestamp + securityPeriod;\n emit GuardianRemovalRequested(\n _guardian,\n block.timestamp + securityPeriod\n );\n }\n\n /**\n * @notice Confirm addition of guardians\n * @dev This method internally calls confirmGuardianAddition which checks the validity of pending request.\n * Guardians are fully added when they pass the validation. Anyone can call this function.\n * @param _guardians Array of guardian addresses to be added\n */\n function confirmGuardianAdditions(\n address[] calldata _guardians\n ) external override {\n for (uint256 i; i < _guardians.length; ) {\n confirmGuardianAddition(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Confirm addition of a guardian\n * @dev This method checks the validity of pending request.\n * Guardians are fully added when they pass the validation. Anyone can call this function.\n * @param _guardian Guardian address to be added\n */\n function confirmGuardianAddition(address _guardian) public override {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingAddition();\n if (gs.pending[id] >= block.timestamp)\n revert GuardianFacet__PendingAdditionNotOver();\n if (block.timestamp >= gs.pending[id] + getSecurityWindow())\n revert GuardianFacet__PendingAdditionExpired();\n\n _addGuardian(_guardian);\n\n delete gs.pending[id];\n emit GuardianAdded(_guardian);\n }\n\n /**\n * @notice Confirm removal of guardians\n * @dev This method internally calls confirmGuardianRemoval to check the validity guardian removal confirmation.\n * Guardians are fully removed when they pass the validation. Anyone can call this function.\n * @param _guardians Array of guardian addresses to be removed\n */\n function confirmGuardianRemovals(\n address[] calldata _guardians\n ) external override {\n for (uint256 i; i < _guardians.length; ) {\n confirmGuardianRemoval(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Confirm removal of a guardian\n * @dev This method checks the validity guardian removal confirmation.\n * Guardian is fully removed when they pass the validation. Anyone can call this function.\n * @param _guardian Guardian address to be removed\n */\n function confirmGuardianRemoval(address _guardian) public override {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingRemoval();\n if (gs.pending[id] >= block.timestamp)\n revert GuardianFacet__PendingRemovalNotOver();\n if (block.timestamp >= gs.pending[id] + getSecurityWindow())\n revert GuardianFacet__PendingAdditionExpired();\n\n _removeGuardian(_guardian);\n delete gs.pending[id];\n emit GuardianRemoved(_guardian);\n }\n\n /**\n * @notice Cancel pending guardian addition\n * @dev This method checks if the previous request for guardian request exists.\n * It reverts if previous request is not pending and cancels the addition otherwise.\n * @param _guardian Guardian address to be canceled from addition\n */\n function cancelGuardianAddition(address _guardian) external override {\n LibDiamond.enforceIsSelf();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingAddition();\n delete gs.pending[id];\n emit GuardianAdditionCancelled(_guardian);\n }\n\n /**\n * @notice Cancel pending guardian removal\n * @dev This method checks if the previous request for guardian request exists.\n * It reverts if previous request is not pending and cancels the removal otherwise.\n * @param _guardian Guardian address to be canceled from removal\n */\n function cancelGuardianRemoval(address _guardian) external override {\n LibDiamond.enforceIsSelf();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingRemoval();\n delete gs.pending[id];\n emit GuardianRemovalCancelled(_guardian);\n }\n\n /**\n * @notice Get the addition security period of current account from security manager\n * @dev This method returns the uint value if addition security period\n * @return additionSecurityPeriod Uint256 value of addition security period\n */\n function getAdditionSecurityPeriod()\n public\n view\n override\n returns (uint256 additionSecurityPeriod)\n {\n additionSecurityPeriod = securityManager.additionSecurityPeriodOf(\n address(this)\n );\n if (additionSecurityPeriod == 0)\n revert GuardianFacet__InvalidAdditionSecurityPeriod();\n }\n\n /**\n * @notice Get the removal security period of current account from security manager\n * @dev This method returns the uint value if removal security period\n * @return removalSecurityPeriod Uint256 value of removal security period\n */\n function getRemovalSecurityPeriod()\n public\n view\n override\n returns (uint256 removalSecurityPeriod)\n {\n removalSecurityPeriod = securityManager.removalSecurityPeriodOf(\n address(this)\n );\n if (removalSecurityPeriod == 0)\n revert GuardianFacet__InvalidRemovalSecurityPeriod();\n }\n\n /**\n * @notice Get the security window of current account from security manager\n * @dev This method returns the uint value if security window\n * @return securityWindow Uint256 value of removal security period\n */\n function getSecurityWindow()\n public\n view\n override\n returns (uint256 securityWindow)\n {\n securityWindow = securityManager.securityWindowOf(address(this));\n if (securityWindow == 0) revert GuardianFacet__InvalidSecurityWindow();\n }\n\n /**\n * @notice Checks if the addition of the given guardian address is pending\n * @dev This method returns the bool value of whether the guardian address is pending addition\n * @return isPending Bool value of representing the pending of guardian addition\n */\n function isAdditionPending(\n address _guardian\n ) public view override returns (bool isPending) {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n isPending = _isPending(id);\n }\n\n /**\n * @notice Checks if the removal of the given guardian address is pending\n * @dev This method returns the bool value of whether the guardian address is pending removal\n * @return isPending Bool value of representing the pending of guardian removal\n */\n function isRemovalPending(\n address _guardian\n ) public view override returns (bool isPending) {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n isPending = _isPending(id);\n }\n\n /**\n * @notice Checks if the given hash is pending\n * @dev This method returns the bool value whether the hash is pending\n * @return isPending Bool value of representing the pending of guardian operation\n */\n function _isPending(\n bytes32 _idHash\n ) internal view returns (bool isPending) {\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n isPending = ((gs.pending[_idHash] > 0 &&\n gs.pending[_idHash] < block.timestamp) &&\n block.timestamp < gs.pending[_idHash] + getSecurityWindow());\n }\n\n /**\n * @notice Adds guardian to storage config. This is called when guardian is fully added.\n * @dev This method add guardian address and config information to Facet Storage dedicated for guardian\n * When this function is called, guardian is fully added to this Barz Smart Account\n * @param _guardian Address of guardian to be added\n */\n function _addGuardian(address _guardian) internal {\n if (!isAdditionPending(_guardian))\n revert GuardianFacet__InvalidGuardianAddition();\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n if (config.info[_guardian].exists)\n revert GuardianFacet__AlreadyExists();\n\n config.info[_guardian].exists = true;\n config.info[_guardian].index = uint128(config.addresses.length);\n config.addresses.push(_guardian);\n }\n\n /**\n * @notice Removes guardian to storage config. This is called when guardian is fully removed.\n * @dev This method remove guardian address and config information to Facet Storage dedicated for guardian\n * When this function is called, guardian is fully removed from this Barz Smart Account\n * @param _guardian Address of guardian to be removed\n */\n function _removeGuardian(address _guardian) internal {\n if (!isRemovalPending(_guardian))\n revert GuardianFacet__InvalidGuardianRemoval();\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n if (!config.info[_guardian].exists)\n revert GuardianFacet__NonExistentGuardian();\n\n address lastAddress = config.addresses[config.addresses.length - 1];\n if (_guardian != lastAddress) {\n uint128 targetIndex = config.info[_guardian].index;\n config.addresses[targetIndex] = lastAddress;\n config.info[lastAddress].index = targetIndex;\n }\n config.addresses.pop();\n delete config.info[_guardian];\n\n emit GuardianRemoved(_guardian);\n }\n\n /**\n * @notice Reads guardian storage and fetches the addresses into an array from the storage\n * @dev This method fetches the guardian storage and returns the list of guardian addresses\n * @return guardians Array of addresses comprised of guardian\n */\n function getGuardians()\n public\n view\n override\n returns (address[] memory guardians)\n {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n uint256 guardiansLen = config.addresses.length;\n guardians = new address[](guardiansLen);\n for (uint256 i; i < guardiansLen; ) {\n guardians[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the number of majority of guardians\n * @return majorityOfGuardians_ Number of majority of guardians e.g., 2 if 3 guardians / 3 if 5 guardians\n */\n function majorityOfGuardians()\n public\n view\n override\n returns (uint256 majorityOfGuardians_)\n {\n majorityOfGuardians_ = LibGuardian.majorityOfGuardians();\n }\n\n /**\n * @notice Reads guardian storage and fetches the addresses into an array from the storage\n * @dev This method fetches the guardian storage and returns the list of guardian addresses\n * @return guardianNumber Array of guardians in the account\n */\n function guardianCount()\n public\n view\n override\n returns (uint256 guardianNumber)\n {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n guardianNumber = config.addresses.length;\n }\n\n /**\n * @notice Reads guardian storage and checks if the given address is a guardian\n * @return isGuardian_ Bool value representing if the given address is guardian\n */\n function isGuardian(\n address _guardian\n ) public view override returns (bool isGuardian_) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n isGuardian_ = config.info[_guardian].exists;\n }\n\n /**\n * @notice Checks if the guardian number is zero and returns of guardian facet is okay to be removed\n * @return isRemovable Bool value representing if guardian facet is removable\n */\n function isGuardianFacetRemovable()\n external\n view\n override\n returns (bool isRemovable)\n {\n isRemovable = (0 == guardianCount());\n }\n}\n" + }, + "contracts/facets/interfaces/IAccountFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IEntryPoint} from \"../../aa-4337/interfaces/IEntryPoint.sol\";\n\n/**\n * @title Account Facet Interface\n * @dev Interface of module contract that provides the account features and init/unitialization of signer\n * compatible with EIP-1271 & EIP-4337\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IAccountFacet {\n event AccountInitialized(\n IEntryPoint indexed entryPoint,\n bytes indexed ownerPublicKey\n );\n // NOTE: Added Below Event\n event VerificationSuccess(bytes32);\n event VerificationFailure(bytes32);\n\n error AccountFacet__InitializationFailure();\n error AccountFacet__RestrictionsFailure();\n error AccountFacet__NonExistentVerificationFacet();\n error AccountFacet__CallNotSuccessful();\n error AccountFacet__InvalidArrayLength();\n\n function initialize(\n address verificationFacet,\n address anEntryPoint,\n address facetRegistry,\n address _defaultFallBack,\n bytes calldata _ownerPublicKey\n ) external returns (uint256);\n\n function execute(address dest, uint256 value, bytes calldata func) external;\n\n function executeBatch(\n address[] calldata dest,\n uint256[] calldata value,\n bytes[] calldata func\n ) external;\n}\n" + }, + "contracts/facets/interfaces/IAccountRecoveryFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {RecoveryConfig} from \"../../libraries/LibFacetStorage.sol\";\n\n/**\n * @title Account Recovery Facet Interface\n * @dev Interface of contract that enables recovery of accounts when owner key is unavailable\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IAccountRecoveryFacet {\n event RecoveryExecuted(\n bytes indexed recoveryPublicKey,\n uint64 executeAfter\n );\n event RecoveryFinalized(bytes indexed recoveryPublicKey);\n event RecoveryCanceled(bytes indexed recoveryPublicKey);\n event RecoveryApproved(\n bytes indexed recoveryPublicKey,\n address indexed guardian,\n uint64 validUntil\n );\n event RecoveryApprovalRevoked(\n bytes indexed recoveryPublicKey,\n address indexed guardian\n );\n event RecoveryCancellationApproved(\n bytes indexed recoveryPublicKey,\n address indexed guardian\n );\n event RecoveryHardstopped();\n\n error AccountRecoveryFacet__CallerNotGuardian();\n error AccountRecoveryFacet__InvalidRecoveryPublicKey();\n error AccountRecoveryFacet__SignerInitializationFailure();\n error AccountRecoveryFacet__SignerUninitializationFailure();\n error AccountRecoveryFacet__InvalidArrayLength();\n error AccountRecoveryFacet__InsufficientGuardians();\n error AccountRecoveryFacet__RecoveryAlreadyOngoing();\n error AccountRecoveryFacet__NonexistentRecovery();\n error AccountRecoveryFacet__NonExistentApproval();\n error AccountRecoveryFacet__RecoveryPeriodNotOver();\n error AccountRecoveryFacet__InvalidLockPeriod();\n error AccountRecoveryFacet__InvalidRecoveryPeriod();\n error AccountRecoveryFacet__InvalidApprovalValidationPeriod();\n error AccountRecoveryFacet__InvalidGuardian();\n error AccountRecoveryFacet__InvalidGuardianSignature();\n error AccountRecoveryFacet__InvalidOwnerSignature();\n error AccountRecoveryFacet__CallNotSuccesful();\n error AccountRecoveryFacet__DuplicateApproval();\n\n function approveAccountRecovery(bytes calldata recoveryPublicKey) external;\n\n function revokeAccountRecoveryApproval(\n bytes calldata recoveryPublicKey\n ) external;\n\n function executeRecovery(\n bytes calldata recoveryPublicKey,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function finalizeRecovery() external;\n\n function approveCancelRecovery(bytes calldata recoveryPublicKey) external;\n\n function cancelRecovery(\n bytes calldata recoveryPublicKey,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function hardstopRecovery(bytes calldata signature) external;\n\n function validateNewOwner(bytes calldata recoveryPublicKey) external view;\n\n function getApprovalRecoveryKeyHash(\n bytes memory recoveryPublicKey,\n string memory saltString\n ) external view returns (bytes32);\n\n function getRecoveryApprovalCountWithTimeValidity(\n bytes32 recoveryPublicKeyHash\n ) external view returns (uint256);\n\n function isRecoveryApproved(\n bytes32 recoveryPublicKeyHash,\n address approver\n ) external view returns (bool);\n\n function getRecoveryNonce() external view returns (uint128);\n\n function getPendingRecovery() external view returns (RecoveryConfig memory);\n}\n" + }, + "contracts/facets/interfaces/IGuardianFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Guardian Facet Interface\n * @dev Interface of guaridna contract that enables addition/removal of guardians from Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IGuardianFacet {\n event GuardianAdditionRequested(\n address indexed guardian,\n uint256 executeAfter\n );\n event GuardianRemovalRequested(\n address indexed guardian,\n uint256 executeAfter\n );\n event GuardianAdditionCancelled(address indexed guardian);\n event GuardianRemovalCancelled(address indexed guardian);\n event GuardianAdded(address indexed guardian);\n event GuardianRemoved(address indexed guardian);\n\n error GuardianFacet__GuardianCannotBeSelf();\n error GuardianFacet__DuplicateGuardian();\n error GuardianFacet__OwnerCannotBeGuardian();\n error GuardianFacet__DuplicateGuardianAddition();\n error GuardianFacet__DuplicateGuardianRemoval();\n error GuardianFacet__UnknownPendingAddition();\n error GuardianFacet__PendingAdditionNotOver();\n error GuardianFacet__UnknownPendingRemoval();\n error GuardianFacet__PendingRemovalNotOver();\n error GuardianFacet__PendingAdditionExpired();\n error GuardianFacet__InvalidAdditionSecurityPeriod();\n error GuardianFacet__InvalidRemovalSecurityPeriod();\n error GuardianFacet__InvalidSecurityWindow();\n error GuardianFacet__NonExistentGuardian();\n error GuardianFacet__AlreadyExists();\n error GuardianFacet__InvalidGuardianAddition();\n error GuardianFacet__InvalidGuardianRemoval();\n error GuardianFacet__ZeroAddressGuardian();\n\n function addGuardian(address guardian) external;\n\n function addGuardians(address[] calldata guardians) external;\n\n function removeGuardian(address guardian) external;\n\n function removeGuardians(address[] calldata guardians) external;\n\n function confirmGuardianAddition(address guardian) external;\n\n function confirmGuardianAdditions(address[] calldata guardian) external;\n\n function confirmGuardianRemoval(address guardian) external;\n\n function confirmGuardianRemovals(address[] calldata guardian) external;\n\n function cancelGuardianAddition(address guardian) external;\n\n function cancelGuardianRemoval(address guardian) external;\n\n function isGuardian(address guardian) external view returns (bool);\n\n function isAdditionPending(address guardian) external view returns (bool);\n\n function isRemovalPending(address guardian) external view returns (bool);\n\n function isGuardianFacetRemovable() external view returns (bool);\n\n function getAdditionSecurityPeriod() external view returns (uint256);\n\n function getRemovalSecurityPeriod() external view returns (uint256);\n\n function getSecurityWindow() external view returns (uint256);\n\n function getGuardians() external view returns (address[] memory);\n\n function majorityOfGuardians() external view returns (uint256);\n\n function guardianCount() external view returns (uint256);\n}\n" + }, + "contracts/facets/interfaces/ILockFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Lock} from \"../../libraries/LibAppStorage.sol\";\n\n/**\n * @title Lock Facet Interface\n * @dev Interface of Lock contract that enables full lock/unlock of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface ILockFacet {\n event Locked(uint64 releaseAfter);\n event Unlocked();\n\n error LockFacet__InvalidRecoveryPeriod();\n error LockFacet__CannotUnlock();\n error LockFacet__InvalidSignature();\n error LockFacet__InvalidApprover();\n\n function lock() external;\n\n function unlock(address approver, bytes calldata signature) external;\n\n function getLockPeriod() external view returns (uint256);\n\n function isLocked() external view returns (bool);\n\n function getUnlockHash() external view returns (bytes32);\n\n function lockNonce() external view returns (uint128);\n\n function getPendingLock() external view returns (Lock memory);\n}\n" + }, + "contracts/facets/interfaces/IMultiSigFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Multi-sig facet Interface\n * @dev Interface of Multi-signature Facet with custom threshold.\n Wallet that adds this facet becomes a multi-sig wallet\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IMultiSigFacet {\n event ThresholdChanged(uint256 threshold);\n event OwnerAdded(address indexed newOwner);\n event OwnerRemoved(address indexed prevOwner);\n event HashApproved(bytes32 hashToApprove, address indexed owner);\n\n error MultiSigFacet__InvalidThreshold();\n error MultisigFacet__InvalidOwnerCount();\n error MultiSigFacet__InvalidRoute();\n error MultiSigFacet__InsufficientSignerLength();\n error MultiSigFacet__InvalidInitData();\n error MultiSigFacet__InvalidOwnerAddress();\n error MultiSigFacet__InvalidOwnerPair();\n error MultiSigFacet__InvalidSignatureLength();\n error MultiSigFacet__InvalidSignatureType();\n error MultiSigFacet__DuplicateOwner();\n error MultiSigFacet__OnlyOwner();\n\n function checkSignatures(\n bytes32 _dataHash,\n bytes calldata _signatures,\n uint256 _threshold\n ) external view returns (uint256);\n\n function splitSignatures(\n bytes calldata _signatures,\n uint256 _nextOffset\n )\n external\n pure\n returns (\n address owner,\n bytes memory signature,\n uint256 signatureType,\n uint256 nextOffset\n );\n\n function approveHash(bytes32 hashToApprove) external;\n\n function addOwner(address newOwner, uint256 threshold) external;\n\n function removeOwner(\n address prevOwner,\n address removedOwner,\n uint256 threshold\n ) external;\n\n function swapOwner(\n address prevOwner,\n address oldOwner,\n address newOwner\n ) external;\n\n function changeThreshold(uint256 _threshold) external;\n\n function isOwner(address owner) external view returns (bool);\n\n function getThreshold() external view returns (uint256);\n\n function getOwners() external view returns (address[] memory);\n}\n" + }, + "contracts/facets/interfaces/IRestrictionsFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Restrictions Facet Interface\n * @dev Interface of Restrictions contract that enables modular restrictions in Barz\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IRestrictionsFacet {\n event RestrictionAdded(address indexed restriction);\n event RestrictionRemoved(address indexed restriction);\n\n error RestrictionsFacet__EmptyRestrictionsList();\n error RestrictionsFacet__RestrictionNotFound();\n error RestrictionsFacet__RestrictionAlreadyExists();\n error RestrictionsFacet__ZeroAddressRestrictions();\n error RestrictionsFacet__ZeroAddressRestrictionsFacet();\n error RestrictionsFacet__RemainingRestrictionsCantBeEmpty();\n\n function initializeRestrictions(\n address[] memory _restrictions\n ) external returns (uint256);\n\n function uninitializeRestrictions() external returns (uint256);\n\n function getRestrictions() external view returns (address[] memory);\n\n function addRestriction(address restriction) external;\n\n function removeRestriction(address restriction) external;\n\n function verifyRestrictions(\n address from,\n address to,\n uint256 value,\n bytes calldata _calldata\n ) external returns (uint256);\n}\n" + }, + "contracts/facets/interfaces/ISignatureMigrationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureMigrationConfig} from \"../../libraries/LibFacetStorage.sol\";\n\n/**\n * @title Signature Migration Facet Interface\n * @dev Interface of Signature Migration contract for migrating user signature scheme to a new scheme user sets\n * Which could include\n * - ECDSA on Secp256K1 Curve\n * - ECDSA on Secp256R1 Curve\n * - BLS, Schnorr, etc\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface ISignatureMigrationFacet {\n event SignatureSchemeMigration(\n address indexed prevVerificationFacet,\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n event SignatureMigrationApproved(\n bytes newPublicKey,\n address indexed newVerificationFacet,\n bytes4[] verificationFuncSelectors,\n address indexed guardian,\n uint128 approvalValidUntil\n );\n event SignatureMigrationApprovalRevoked(\n bytes newPublicKey,\n address indexed newVerificationFacet,\n bytes4[] verificationFuncSelectors,\n address indexed guardian\n );\n event SignatureMigrationExecuted(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors,\n uint128 migrateAfter\n );\n event SignatureMigrationCanceled(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n event SignatureMigrationCancellationApproved(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n\n error SignatureMigrationFacet__SignerUninitializationFailure();\n error SignatureMigrationFacet__SignerInitializationFailure();\n error SignatureMigrationFacet__InvalidRouteWithGuardian();\n error SignatureMigrationFacet__InvalidKeyType();\n error SignatureMigrationFacet__InsufficientApprovers();\n error SignatureMigrationFacet__InvalidApproverSignature();\n error SignatureMigrationFacet__InvalidGuardian();\n error SignatureMigrationFacet__NonExistentApprover();\n error SignatureMigrationFacet__InvalidMigrationPeriod();\n error SignatureMigrationFacet__NonexistentMigration();\n error SignatureMigrationFacet__MigrationPeriodNotOver();\n error SignatureMigrationFacet__InvalidArrayLength();\n error SignatureMigrationFacet__InvalidApprovalValidationPeriod();\n error SignatureMigrationFacet__CannotRevokeUnapproved();\n error SignatureMigrationFacet__LackOfOwnerApproval();\n error SignatureMigrationFacet__OwnerAlreadyApproved();\n error SignatureMigrationFacet__NonExistentVerificationFacet();\n error SignatureMigrationFacet__DuplicateApproval();\n\n function migrateSignatureScheme(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function migrateSignatureSchemeWithGuardian(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors,\n address[] calldata approvers,\n bytes[] calldata signatures\n ) external;\n\n function approveSignatureSchemeMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function revokeSignatureMigrationApproval(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function finalizeSignatureMigration() external;\n\n function approveCancelSignatureMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function cancelSignatureMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function getApprovalMigrationKeyHash(\n bytes memory recoveryPublicKey,\n address newVerificationFacet,\n bytes4[] memory newVerificationFuncSelectors,\n string memory saltString\n ) external view returns (bytes32);\n\n function getMigrationOwnerApprovalWithTimeValidity(\n bytes32 publicKeyHash\n ) external view returns (bool);\n\n function getMigrationApprovalCountWithTimeValidity(\n bytes32 publicKeyHash\n ) external view returns (uint256);\n\n function isMigrationApproved(\n bytes32 migrationPublicKeyHash,\n address approver\n ) external view returns (bool);\n\n function getMigrationNonce() external view returns (uint128);\n\n function isMigrationPending() external view returns (bool);\n\n function getPendingMigration()\n external\n view\n returns (SignatureMigrationConfig memory);\n}\n" + }, + "contracts/facets/interfaces/IVerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {UserOperation} from \"../../aa-4337/interfaces/UserOperation.sol\";\n\n/**\n * @title Verification Facet Interface\n * @dev Implements logic for user ops signature verification\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface IVerificationFacet {\n event SignerInitialized(bytes);\n event SignerUninitialized();\n\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n error VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n error VerificationFacet__InitializationFailure();\n error VerificationFacet__InvalidFacetMapping();\n\n function initializeSigner(bytes memory) external returns (uint256);\n\n function uninitializeSigner() external returns (uint256);\n\n function validateOwnerSignatureSelector() external view returns (bytes4);\n\n function owner() external view returns (bytes memory);\n\n function isValidKeyType(bytes calldata) external view returns (bool);\n\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) external view returns (uint256);\n}\n" + }, + "contracts/facets/LockFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage, Lock} from \"../libraries/LibAppStorage.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibFacetStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {ILockFacet} from \"./interfaces/ILockFacet.sol\";\n\n/**\n * @title Lock Facet\n * @dev Contract that enables full lock/unlock of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract LockFacet is ILockFacet, Modifiers {\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Locks the account for the lock period. Lock period is defined in the security manager and it's customizable\n * This function can only be called when account is unlocked by owner or guardians\n * @dev This method checks the caller and if the account is currently locked and locks the account after fetching the\n * Lock period from the owner.\n */\n function lock() external override onlyGuardianOrOwner onlyWhenUnlocked {\n uint256 unlockTime = block.timestamp + getLockPeriod();\n unchecked {\n ++LibFacetStorage.lockStorage().nonce;\n }\n LibAppStorage.setLock(unlockTime, LockFacet.lock.selector);\n emit Locked(uint64(unlockTime));\n }\n\n /**\n * @notice Locks the account when the account is locked. This function can be called by anyone but must provide the approver address and signature.\n * The approver should be one of the guardians or owner.\n * @dev This method takes the approver address and the signature. After validating the address and the signature, it unlocks the account immediately.\n * Only one of the guardian or owner is required to lock and unlock the account.\n * @param _approver Address of approver approving the unlock of Barz account\n * @param _signature Signature of the approver that signed the msg hash for unlocking the account\n */\n function unlock(\n address _approver,\n bytes calldata _signature\n ) external override onlyWhenLocked {\n if (_approver != address(this) && !LibGuardian.isGuardian(_approver))\n revert LockFacet__InvalidApprover();\n if (\n !SignatureChecker.isValidSignatureNow(\n _approver,\n getUnlockHash(),\n _signature\n )\n ) revert LockFacet__InvalidSignature();\n _unlock();\n }\n\n /**\n * @notice Unlocks the account and increments the lock nonce\n */\n function _unlock() private {\n if (s.locks[INNER_STRUCT].locker != LockFacet.lock.selector)\n revert LockFacet__CannotUnlock();\n unchecked {\n ++LibFacetStorage.lockStorage().nonce;\n }\n LibAppStorage.setLock(0, bytes4(0));\n emit Unlocked();\n }\n\n /**\n * @notice Returns the lock period of current Barz account. Lock period information is held by Security Manager\n * @return lockPeriod Uint value of lock period in seconds\n */\n function getLockPeriod() public view override returns (uint256 lockPeriod) {\n lockPeriod = securityManager.lockPeriodOf(address(this));\n if (lockPeriod == 0) revert LockFacet__InvalidRecoveryPeriod();\n }\n\n /**\n * @notice Returns if the account is locked or not\n * @dev This method fetches the current block timestamp and compares that with release time.\n * After checking the timestamp and release time, it returns if the account is still locked or not.\n * @return isLocked_ Uint value of lock period in seconds\n */\n function isLocked() public view override returns (bool isLocked_) {\n isLocked_ = uint64(block.timestamp) < s.locks[INNER_STRUCT].release;\n }\n\n /**\n * @notice Calculates the unlock hash and returns the unlock hash safe from signature reply attack\n * @dev This method calculates the unlock hash with EIP-191 prefix, wallet address, chainID, and nonce\n * It packs the result and packs them and hashes it.\n * @return unlockHash Bytes32 unlock hash\n */\n function getUnlockHash() public view override returns (bytes32 unlockHash) {\n unlockHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n \"Unlock\",\n address(this),\n block.chainid,\n lockNonce()\n )\n )\n )\n );\n }\n\n /**\n * @notice Returns lock nonce of account. Reads nonce from lock storage within facet storage\n * @return lockNonce_ Uint128 value of lock nonce. This is incremented whenever the account is lock/unlocked\n */\n function lockNonce() public view override returns (uint128 lockNonce_) {\n lockNonce_ = LibFacetStorage.lockStorage().nonce;\n }\n\n /**\n * @notice Returns the overall information of current lock\n * @return pendingLock Struct value including all information of pending lock\n */\n function getPendingLock()\n public\n view\n override\n returns (Lock memory pendingLock)\n {\n pendingLock = s.locks[INNER_STRUCT];\n }\n}\n" + }, + "contracts/facets/Modifiers.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\n\n/**\n * @title Modifiers\n * @dev Responsible for providing modifiers/util functions to Facet contracts\n * @author David Yongjun Kim (@Powerstream3604)\n */\nabstract contract Modifiers is BarzStorage {\n uint8 constant INNER_STRUCT = 0;\n\n error CallerNotGuardian();\n error CallerNotGuardianOrOwner();\n error DuplicateApprover();\n error ZeroApproverLength();\n error UnregisteredFacetAndSelectors();\n\n /**\n * @notice Modifier to only allow guardian to make a call, reverts if any other entity is the caller\n */\n modifier onlyGuardian() {\n if (!LibGuardian.isGuardian(msg.sender)) revert CallerNotGuardian();\n _;\n }\n\n /**\n * @notice Modifier to only allow guardian or owner to make a call, reverts if any other entity is the caller\n */\n modifier onlyGuardianOrOwner() {\n if (!LibGuardian.isGuardian(msg.sender) && address(this) != msg.sender)\n revert CallerNotGuardianOrOwner();\n _;\n }\n\n /**\n * @notice Checks if the approver address is the array is unique with no duplicate\n * @dev This method loops through the array and checks if a duplicate address exists, it reverts if duplicate address exists\n * @param approvers Array of address\n */\n function _checkApprover(\n address[] memory approvers\n ) internal pure returns (bool) {\n uint256 approverLength = approvers.length;\n if (0 == approverLength) revert ZeroApproverLength();\n for (uint256 i; i < approverLength - 1; ) {\n for (uint256 j = i + 1; j < approverLength; ) {\n if (approvers[i] == approvers[j]) {\n revert DuplicateApprover(); // Found a duplicate\n }\n unchecked {\n ++j;\n }\n }\n unchecked {\n ++i;\n }\n }\n return false; // No duplicates found\n }\n\n /**\n * @notice Checks if the facet getting added or replaced is registered to facet registry\n * @dev This method loops through the cut and checks if the facet getting added/replaced is registered to facet registry\n * @param _diamondCut Array of FacetCut, data for diamondCut defined in EIP-2535\n */\n function _checkFacetCutValidity(\n IDiamondCut.FacetCut[] memory _diamondCut\n ) internal view {\n uint256 diamondCutLength = _diamondCut.length;\n for (uint256 i; i < diamondCutLength; ) {\n if (\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Add ||\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Replace\n ) {\n if (\n !s.facetRegistry.areFacetFunctionSelectorsRegistered(\n _diamondCut[i].facetAddress,\n _diamondCut[i].functionSelectors\n )\n ) revert UnregisteredFacetAndSelectors();\n }\n unchecked {\n ++i;\n }\n }\n }\n}\n" + }, + "contracts/facets/ReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibReentrancyGuardStorage, ReentrancyGuardStorage} from \"../libraries/LibReentrancyGuardStorage.sol\";\n\nabstract contract ReentrancyGuard {\n\n uint256 private constant _NOT_ENTERED = 0;\n uint256 private constant _ENTERED = 1;\n\n error ReentrancyGuard__ReentrantCall();\n\n modifier nonReentrant() {\n ReentrancyGuardStorage storage rgs = LibReentrancyGuardStorage.reentrancyguardStorage();\n\n if (rgs.status == _ENTERED) revert ReentrancyGuard__ReentrantCall();\n\n rgs.status = _ENTERED;\n\n _; // Execute function\n\n rgs.status = _NOT_ENTERED;\n }\n}\n" + }, + "contracts/facets/RestrictionsFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ReentrancyGuard} from \"./ReentrancyGuard.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, RestrictionsStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {IRestriction} from \"../restrictions/IRestriction.sol\";\nimport {IRestrictionsFacet} from \"./interfaces/IRestrictionsFacet.sol\";\n\n/**\n * @title Restrictions facet\n * @dev Responsible for storing and verifying different kinds of restrictions, for example:\n * - Whitelist / Blacklist\n * - Daily limits\n * - Trading time restrictions\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract RestrictionsFacet is IRestrictionsFacet, ReentrancyGuard {\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceRestrictionsInitialize();\n }\n\n /**\n * @notice Intialize restrictions of Barz. Restrictions facet call restriction contracts for restriction validation\n * before each call\n * @param _restrictions The initial array of restrictions.\n * @return initSuccess Int value showing if the initialization of restriction is successful\n */\n function initializeRestrictions(\n address[] calldata _restrictions\n ) public override returns (uint256 initSuccess) {\n LibDiamond.enforceIsSelf();\n LibAppStorage.enforceRestrictionsInitialize();\n\n if (_restrictions.length == 0) {\n // You can't initialize RestrictionsFacet with an empty list of restrictions\n revert RestrictionsFacet__EmptyRestrictionsList();\n }\n for (uint256 i; i < _restrictions.length; ) {\n if (_restrictions[i] == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictions();\n unchecked {\n ++i;\n }\n }\n\n LibFacetStorage.restrictionsStorage().restrictions = _restrictions;\n _updateRestrictionsMap(_restrictions, true);\n initSuccess = 1;\n }\n\n /**\n * @notice Unitialize restrictions of Barz\n * @return uninitSuccess Int value showing if the initialization of restriction is successful\n */\n function uninitializeRestrictions()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibDiamond.enforceIsSelf();\n LibAppStorage.setRestrictionsUninitialized();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n _updateRestrictionsMap(restrictionsStorage.restrictions, false);\n restrictionsStorage.restrictions = new address[](0);\n uninitSuccess = 1;\n }\n\n /**\n * @notice Returns the list of Restrictions contract address\n * @return restrictions Addresses of IRestriction which are currently active\n */\n function getRestrictions()\n public\n view\n override\n returns (address[] memory restrictions)\n {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n restrictions = restrictionsStorage.restrictions;\n }\n\n /**\n * @notice Adds restrictions to Barz with validation on the restriction contract address.\n * This method is only callable by the owner(self).\n * @param _restriction The address of the restriction to be added.\n */\n function addRestriction(address _restriction) external override {\n LibDiamond.enforceIsSelf();\n if (LibDiamond.restrictionsFacet() == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictionsFacet();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n if (_restriction == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictions();\n if (restrictionsStorage.exists[_restriction])\n revert RestrictionsFacet__RestrictionAlreadyExists();\n\n restrictionsStorage.restrictions.push(_restriction);\n restrictionsStorage.exists[_restriction] = true;\n\n emit RestrictionAdded(_restriction);\n }\n\n /**\n * @notice Remove restrictions from Barz if it existed. This method is only callable by the owner(self).\n * @param _restriction The address of the restriction to be removed.\n */\n function removeRestriction(address _restriction) external override {\n LibDiamond.enforceIsSelf();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n if (!restrictionsStorage.exists[_restriction])\n revert RestrictionsFacet__RestrictionNotFound();\n\n address[] storage restrictions = restrictionsStorage.restrictions;\n\n uint256 indexToDelete = restrictions.length;\n uint256 restrictionsLen = restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n if (restrictions[i] == _restriction) {\n indexToDelete = i;\n break;\n }\n unchecked {\n ++i;\n }\n }\n\n if (indexToDelete == 0 && restrictionsLen == 1) {\n revert RestrictionsFacet__RemainingRestrictionsCantBeEmpty();\n } else if (indexToDelete == restrictionsLen) {\n revert RestrictionsFacet__RestrictionNotFound();\n } else {\n restrictions[indexToDelete] = restrictions[restrictionsLen - 1];\n restrictions.pop();\n }\n\n restrictionsStorage.exists[_restriction] = false;\n emit RestrictionRemoved(_restriction);\n }\n\n /**\n * @notice Sets the restrictions address value mapping to true or false when adding/removing restriction contracts\n * @param _restrictions List of restriction contracts address\n * @param _newValue Bool value to flag to the list of restrictions contracts\n */\n function _updateRestrictionsMap(\n address[] memory _restrictions,\n bool _newValue\n ) internal {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n uint restrictionsLen = _restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n restrictionsStorage.exists[_restrictions[i]] = _newValue;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @dev Iterates over all restrictions and verifies each of them with the transaction parameters.\n * @param _from The address of the sender, that will be signing the transaction.\n * @param _to The receiving address.\n * @param _value Amount of ETH to transfer from sender to recipient.\n * @param _calldata Optional field to include arbitrary data.\n * @return 0 if all the checks passed, 1 otherwise.\n */\n function verifyRestrictions(\n address _from,\n address _to,\n uint256 _value,\n bytes calldata _calldata\n ) external nonReentrant returns (uint256) {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n uint restrictionsLen = restrictionsStorage.restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n IRestriction restriction = IRestriction(\n restrictionsStorage.restrictions[i]\n );\n bool checkPassed = restriction.check(_from, _to, _value, _calldata);\n if (!checkPassed) {\n return 1;\n }\n unchecked {\n ++i;\n }\n }\n\n return 0;\n }\n}\n" + }, + "contracts/facets/SignatureMigrationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, SignatureMigrationStorage, SignatureMigrationConfig, SignatureMigrationApprovalConfig, ApprovalConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IDiamondCut} from \"./base/interfaces/IDiamondCut.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {ISignatureMigrationFacet} from \"./interfaces/ISignatureMigrationFacet.sol\";\n\n/**\n * @title Signature Migration Facet\n * @dev Responsible for migrating user signature scheme to a new scheme user sets\n * Which could include\n * - ECDSA on Secp256K1 Curve\n * - ECDSA on Secp256R1 Curve\n * - BLS, Schnorr, etc\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract SignatureMigrationFacet is ISignatureMigrationFacet, Modifiers {\n bytes constant UNINIT_CALL =\n abi.encodeWithSignature(\"uninitializeSigner()\");\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This modifier verifies if the public key format matches with the new verification facet\n * @param _publicKey Bytes of public key to be validated for the new verification facet\n * @param _newVerificationFacet Address of new verification facet\n */\n modifier validateKeyType(\n bytes memory _publicKey,\n address _newVerificationFacet\n ) {\n if (\n !IVerificationFacet(_newVerificationFacet).isValidKeyType(\n _publicKey\n )\n ) revert SignatureMigrationFacet__InvalidKeyType();\n _;\n }\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n // IMPORTANT NOTE: In the client side when they call this function, the func selectors should be sorted in ascending order\n // to prevent different hash with same items in the array\n /**\n * @notice Moves the state of migration to a pending state. When pending state is over after pending period time,\n * Migration can be finalized. This function can only be called by self and when the account is unlocked.\n * @dev This method checks if the caller is self and if guardians exists. It migrates signature request to a pending state\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function migrateSignatureScheme(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n public\n override\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n // Only self contract can call this function\n LibDiamond.enforceIsSelf();\n // Should revert if guardian exist\n if (0 != LibGuardian.guardianCount())\n revert SignatureMigrationFacet__InvalidRouteWithGuardian();\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n // NOTE: Migration requires a pending period & confirmation from owner to prevent a\n // single call changing the ownership of the wallet\n /**\n * @notice Migrate signature scheme when guardians exists. Verifies the signature of guardians and moves migration to pending state.\n * Which can then be finalized when pending period is over. Owner's approval is mandatory for migration to happen\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _approvers List of approvers. This could include owner\n */\n function migrateSignatureSchemeWithGuardian(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n )\n public\n override\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n // Should revert if does not guardian exist\n if (0 == LibGuardian.guardianCount())\n revert SignatureMigrationFacet__InvalidRouteWithGuardian();\n if (_approvers.length != _signatures.length)\n revert SignatureMigrationFacet__InvalidArrayLength();\n\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(migrationPublicKeyHash, _approvers);\n\n bool onChainOwnerApproval = getMigrationOwnerApprovalWithTimeValidity(\n migrationPublicKeyHash\n );\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n\n if (\n _approvers.length +\n getMigrationApprovalCountWithTimeValidity(\n migrationPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert SignatureMigrationFacet__InsufficientApprovers();\n {\n // To prevent Stack too deep\n bool ownerApproved;\n for (uint256 i; i < _approvers.length; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n address(this) != _approvers[i]\n ) revert SignatureMigrationFacet__InvalidGuardian();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert SignatureMigrationFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n migrationPublicKeyHash,\n _signatures[i]\n )\n ) revert SignatureMigrationFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n\n if (!ownerApproved && !onChainOwnerApproval)\n revert SignatureMigrationFacet__LackOfOwnerApproval();\n }\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Internal function that moves signature mgiration to a pending state.\n * @dev This method increments migration nonce and sets the migration in the migration config. Emits events for migration execution\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _migrateSignatureScheme(\n address _newVerificationFacet,\n bytes memory _newPublicKey,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal {\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n unchecked {\n ++ms.nonce;\n }\n uint64 migrateAfter = uint64(block.timestamp + getMigrationPeriod());\n\n ms.migrationConfigs[INNER_STRUCT] = SignatureMigrationConfig(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n migrateAfter\n );\n\n emit SignatureMigrationExecuted(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors,\n migrateAfter\n );\n }\n\n /**\n * @notice Approves signature scheme migration on-chain. This can be called by owner or guardian only when the account is unlocked.\n * When the threshold of the migration approval passed and owner approval is granted, it automatically moves migration to a pending state\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function approveSignatureSchemeMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n public\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit SignatureMigrationApproved(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n msg.sender,\n approvalValidUntil\n );\n if (\n getMigrationApprovalCountWithTimeValidity(migrationPublicKeyHash) >=\n LibGuardian.majorityOfGuardians() &&\n getMigrationOwnerApprovalWithTimeValidity(migrationPublicKeyHash)\n )\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Revokes the approval of signature migration done on-chain. Emits revoke event when revoked.\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function revokeSignatureMigrationApproval(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n external\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n if (!isMigrationApproved(migrationPublicKeyHash, msg.sender))\n revert SignatureMigrationFacet__CannotRevokeUnapproved();\n\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(false, 0);\n emit SignatureMigrationApprovalRevoked(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n msg.sender\n );\n }\n\n /**\n * @notice Finalizes the pending signature scheme migration. This function can only be called by owner.\n * It removes the facets of the previous verification facet and adds the new verification facet.\n * After finalizing migration, it emits migration event which shows the change of the verification facet\n */\n function finalizeSignatureMigration() external override {\n // NOTE: Only owner can call this function\n LibDiamond.enforceIsSelf();\n\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n\n if (!isMigrationPending())\n revert SignatureMigrationFacet__NonexistentMigration();\n\n if (\n uint64(block.timestamp) <=\n ms.migrationConfigs[INNER_STRUCT].migrateAfter\n ) revert SignatureMigrationFacet__MigrationPeriodNotOver();\n address newVerificationFacet = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationVerificationFacet;\n bytes4[] memory newVerificationFuncSelectors = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationSelectors;\n bytes memory newPublicKey = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationPublicKey;\n\n address prevVerificationFacet = LibLoupe.facetAddress(\n s.validateOwnerSignatureSelector\n );\n if (prevVerificationFacet == address(0))\n revert SignatureMigrationFacet__NonExistentVerificationFacet();\n\n IDiamondCut.FacetCut[] memory UninitCut;\n IDiamondCut.FacetCut[] memory InitCut;\n {\n bytes4[] memory prevVerificationFuncSelectors = LibLoupe\n .facetFunctionSelectors(prevVerificationFacet);\n\n UninitCut = new IDiamondCut.FacetCut[](1);\n InitCut = new IDiamondCut.FacetCut[](1);\n UninitCut[0] = IDiamondCut.FacetCut({\n facetAddress: address(0),\n action: IDiamondCut.FacetCutAction.Remove,\n functionSelectors: prevVerificationFuncSelectors\n });\n InitCut[0] = IDiamondCut.FacetCut({\n facetAddress: newVerificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: newVerificationFuncSelectors\n });\n {\n IDiamondCut.FacetCut[]\n memory facetCuts = new IDiamondCut.FacetCut[](2);\n facetCuts[0] = UninitCut[0];\n facetCuts[1] = InitCut[0];\n _checkFacetCutValidity(facetCuts);\n }\n LibAppStorage.initiateSignerMigration();\n address verificationFacet = address(\n bytes20(\n LibDiamond.diamondStorage().facets[\n s.validateOwnerSignatureSelector\n ]\n )\n );\n\n (bool uninitSuccess, bytes memory uninitResult) = verificationFacet\n .delegatecall(UNINIT_CALL);\n if (!uninitSuccess || uint256(bytes32(uninitResult)) != 1)\n revert SignatureMigrationFacet__SignerUninitializationFailure();\n LibAppStorage.finalizeSignerMigration();\n\n LibDiamond.diamondCut(UninitCut, address(0), \"\");\n }\n {\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n newPublicKey\n );\n\n // Every Verification Facet should comply with initializeSigner(bytes)\n // to be compatible with the Barz contract(for initialization)\n LibDiamond.diamondCut(InitCut, address(0), \"\");\n (bool initSuccess, bytes memory initResult) = newVerificationFacet\n .delegatecall(initCall);\n if (!initSuccess || uint256(bytes32(initResult)) != 1)\n revert SignatureMigrationFacet__SignerInitializationFailure();\n\n emit SignatureSchemeMigration(\n prevVerificationFacet,\n newVerificationFacet,\n newPublicKey,\n newVerificationFuncSelectors\n );\n }\n }\n\n /**\n * @notice Approve cancellation of signature migration. If cancellation approval passes guardian threshold with owner approval\n * it automatically cancels the migration.\n * @dev This method checks if the caller is one of guardian or owner and sets true for the cancellation hash in the approval config.\n * It internally calls _cancelSignatureMigration for canceling the migration\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function approveCancelSignatureMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n external\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"CancelSignatureMigration\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit SignatureMigrationCancellationApproved(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n if (\n getMigrationApprovalCountWithTimeValidity(migrationPublicKeyHash) >=\n LibGuardian.majorityOfGuardians() &&\n getMigrationOwnerApprovalWithTimeValidity(migrationPublicKeyHash)\n )\n _cancelSignatureMigration(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Verifies the signature of guardians/owner and cancels the signature migration.\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _approvers List of approvers. This could include owner\n */\n function cancelSignatureMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n )\n external\n override\n validateKeyType(_newPublicKey, _newVerificationFacet)\n onlyWhenUnlocked\n {\n if (_approvers.length != _signatures.length)\n revert SignatureMigrationFacet__InvalidArrayLength();\n\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"CancelSignatureMigration\"\n );\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(migrationPublicKeyHash, _approvers);\n\n bool onChainOwnerApproval = getMigrationOwnerApprovalWithTimeValidity(\n migrationPublicKeyHash\n );\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n if (\n _approvers.length +\n getMigrationApprovalCountWithTimeValidity(\n migrationPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert SignatureMigrationFacet__InsufficientApprovers();\n {\n // To prevent stack too deep\n bool ownerApproved;\n for (uint256 i; i < _approvers.length; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n address(this) != _approvers[i]\n ) revert SignatureMigrationFacet__NonExistentApprover();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert SignatureMigrationFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n migrationPublicKeyHash,\n _signatures[i]\n )\n ) revert SignatureMigrationFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n if (!ownerApproved && !onChainOwnerApproval)\n revert SignatureMigrationFacet__LackOfOwnerApproval();\n }\n _cancelSignatureMigration(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Internal function that cancels signature migration.\n * @dev This method increments migration nonce and deletes the migration from the migration config. Emits events for migration cancellation\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _cancelSignatureMigration(\n address _newVerificationFacet,\n bytes memory _newPublicKey,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal {\n if (!isMigrationPending())\n revert SignatureMigrationFacet__NonexistentMigration();\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n unchecked {\n ++ms.nonce;\n }\n delete ms.migrationConfigs[INNER_STRUCT];\n emit SignatureMigrationCanceled(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Checks if the facets to be added from new verification facet is registered to facet registry\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _checkMigrationCutValidity(\n address _newVerificationFacet,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal view {\n IDiamondCut.FacetCut[] memory facetCuts = new IDiamondCut.FacetCut[](1);\n facetCuts[0] = IDiamondCut.FacetCut({\n facetAddress: _newVerificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: _newVerificationFuncSelectors\n });\n _checkFacetCutValidity(facetCuts);\n }\n\n /**\n * @notice Returns if the migration is pending of not\n * @dev This method fetches the migration storage and checks if the migrate after is above 0 value\n * @return isPending Bool value that shows if the migration is pending\n */\n function isMigrationPending()\n public\n view\n override\n returns (bool isPending)\n {\n SignatureMigrationStorage storage rs = LibFacetStorage\n .migrationStorage();\n isPending = rs.migrationConfigs[INNER_STRUCT].migrateAfter > 0;\n }\n\n /**\n * @notice Returns the migration hash. This function ensures that this hash is safe from replay attack by including\n * public key, verification facet, function selectors, salt, address, chainId, and nonce.\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _saltString Salt value for generating the migration hash\n * @return migrationKeyHash Bytes32 string of the migration key hash\n */\n function getApprovalMigrationKeyHash(\n bytes memory _newPublicKey,\n address _newVerificationFacet,\n bytes4[] memory _newVerificationFuncSelectors,\n string memory _saltString\n ) public view override returns (bytes32 migrationKeyHash) {\n migrationKeyHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n _newPublicKey,\n _newVerificationFacet,\n keccak256(abi.encode(_newVerificationFuncSelectors)),\n _saltString,\n address(this),\n block.chainid,\n LibFacetStorage.migrationStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Checks if the owner approved the hash for migration\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @return isApprovedByOwner Bool value of showing if the owner approved it or not\n */\n function getMigrationOwnerApprovalWithTimeValidity(\n bytes32 _migrationPublicKeyHash\n ) public view override returns (bool isApprovedByOwner) {\n isApprovedByOwner = isMigrationApproved(\n _migrationPublicKeyHash,\n address(this)\n );\n }\n\n /**\n * @notice Checks how many of the guardians approved the migration hash\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @return approvalCount Number of approvals\n */\n function getMigrationApprovalCountWithTimeValidity(\n bytes32 _migrationPublicKeyHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardiansLength = guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n if (isMigrationApproved(_migrationPublicKeyHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n return approvalCount;\n }\n\n /**\n * @notice Checks if the migration is approved by the given approver\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @param _approver Address of approver\n * @return isApproved Bool value if migration hash is approved\n */\n function isMigrationApproved(\n bytes32 _migrationPublicKeyHash,\n address _approver\n ) public view override returns (bool isApproved) {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n isApproved = (ms\n .isMigrationApproved[_migrationPublicKeyHash][_approver].isApproved &&\n block.timestamp <\n ms\n .isMigrationApproved[_migrationPublicKeyHash][_approver]\n .validUntil);\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _migrationPublicKeyHash Hash of migration information\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _migrationPublicKeyHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isMigrationApproved(_migrationPublicKeyHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert SignatureMigrationFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the migration period of this wallet\n * @dev This method fetches the migration period from the security manager\n * @return migrationPeriod Migration period of Barz contract fetched from security manager\n */\n function getMigrationPeriod()\n internal\n view\n returns (uint128 migrationPeriod)\n {\n migrationPeriod = securityManager.migrationPeriodOf(address(this));\n if (migrationPeriod == 0)\n revert SignatureMigrationFacet__InvalidMigrationPeriod();\n }\n\n /**\n * @notice Returns the validation period of this wallet\n * @dev This method fetches the validation period from the security manager\n * @return approvalValidationPeriod Validation period of Barz contract fetched from security manager\n */\n function getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod == 0)\n revert SignatureMigrationFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the migration nonce of this wallet\n * @dev This method fetches the nonce from migration storage\n * @return migrationNonce Nonce of migration to protect from reply attacks\n */\n function getMigrationNonce()\n public\n view\n override\n returns (uint128 migrationNonce)\n {\n migrationNonce = LibFacetStorage.migrationStorage().nonce;\n }\n\n /**\n * @notice Returns the migration configuration of this wallet\n * @dev This method fetches the migration config from the migration storage\n * @return pendingMigrationConfig Migration config currently pending for signature migration\n */\n function getPendingMigration()\n external\n view\n override\n returns (SignatureMigrationConfig memory pendingMigrationConfig)\n {\n pendingMigrationConfig = LibFacetStorage\n .migrationStorage()\n .migrationConfigs[INNER_STRUCT];\n }\n}\n" + }, + "contracts/facets/TokenReceiverFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {IERC1155Receiver} from \"../interfaces/ERC/IERC1155Receiver.sol\";\nimport {IERC677Receiver} from \"../interfaces/ERC/IERC677Receiver.sol\";\n\n/**\n * @title TokenReceiver Facet\n * @dev Contract that enables receiving ERC721/ERC1155/ERC777/ERC677 Tokens with safe transfer\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract TokenReceiverFacet is\n IERC721Receiver,\n IERC1155Receiver,\n IERC777Recipient,\n IERC677Receiver\n{\n /**\n * @notice Handles ERC721 Token callback.\n * return Standardized onERC721Received return value.\n */\n function onERC721Received(\n address,\n address,\n uint256,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC721Receiver.onERC721Received.selector;\n }\n\n /**\n * @notice Handles ERC1155 Token callback.\n * return Standardized onERC1155Received return value.\n */\n function onERC1155Received(\n address,\n address,\n uint256,\n uint256,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC1155Receiver.onERC1155Received.selector;\n }\n\n /**\n * @notice Handles ERC1155 Token batch callback.\n * return Standardized onERC1155BatchReceived return value.\n */\n function onERC1155BatchReceived(\n address,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC1155Receiver.onERC1155BatchReceived.selector;\n }\n\n /**\n * @notice Handles ERC777 Token callback.\n * Does not return value, empty implementation.\n */\n function tokensReceived(\n address,\n address,\n address,\n uint256,\n bytes calldata,\n bytes calldata\n ) external pure override {}\n\n /**\n * @notice Handles ERC677 Token callback.\n * return true.\n */\n function onTokenTransfer(\n address,\n uint256,\n bytes calldata\n ) external pure override returns (bool) {\n return true;\n }\n}\n" + }, + "contracts/facets/verification/MultiSigFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {UserOperation} from \"../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../../libraries/LibLoupe.sol\";\nimport {LibAppStorage} from \"../../libraries/LibAppStorage.sol\";\nimport {LibMultiSigStorage, MultiSigStorage} from \"../../libraries/LibMultiSigStorage.sol\";\nimport {IERC1271} from \"../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../interfaces/IVerificationFacet.sol\";\nimport {IMultiSigFacet} from \"../interfaces/IMultiSigFacet.sol\";\n\n/**\n * @title Multi-sig facet\n * @dev Multi-signature Facet with custom threshold.\n * Wallet that adds this facet becomes a multi-sig wallet.\n * Reference signature_format.md documentation for Multi-sig facet details\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract MultiSigFacet is IMultiSigFacet, IVerificationFacet, IERC1271 {\n using ECDSA for bytes32;\n\n address public immutable self;\n\n address internal constant SENTINEL_OWNERS = address(0x1);\n uint256 internal constant ADDRESS = 20;\n uint256 internal constant SIG_TYPE = 1;\n uint256 internal constant SIG_LEN = 4;\n uint256 internal constant THRESHOLD = 4;\n uint256 internal constant INVALID_SIG = 1;\n uint256 internal constant VALID_SIG = 0;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in Multisig Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the right format and initializes signer storage in k1 storage.\n * @param _owners Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _owners\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n\n if (!isValidKeyType(_owners)) revert MultiSigFacet__InvalidInitData();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n uint256 threshold = uint256(uint32(bytes4(_owners)));\n uint256 ownerCount = (_owners.length - THRESHOLD) / ADDRESS;\n\n if (threshold == 0) revert MultiSigFacet__InvalidThreshold();\n if (ownerCount == 0) revert MultisigFacet__InvalidOwnerCount();\n\n address currentOwner = SENTINEL_OWNERS;\n uint256 ptr = THRESHOLD;\n address owner_;\n for (uint256 i; i < ownerCount; ) {\n owner_ = address(bytes20(_owners[ptr:ptr + ADDRESS]));\n ptr += ADDRESS;\n if (\n owner_ == address(0) ||\n owner_ == SENTINEL_OWNERS ||\n owner_ == address(this) ||\n owner_ == currentOwner\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[owner_] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n\n ms.owners[currentOwner] = owner_;\n currentOwner = owner_;\n\n unchecked {\n ++i;\n }\n }\n ms.owners[currentOwner] = SENTINEL_OWNERS;\n ms.ownerCount = ownerCount;\n ms.threshold = threshold;\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_owners);\n }\n\n /**\n * @notice Uninitialize signer in K1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n ++ms.counter;\n address[] memory ownerlist = getOwners();\n uint256 ownerlistLength = ownerlist.length;\n for (uint256 i; i < ownerlistLength; ) {\n ms.owners[ownerlist[i]] = address(0);\n unchecked {\n ++i;\n }\n }\n ms.owners[SENTINEL_OWNERS] = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls checkSignatures with\n * user operation hash and signature together with the threshold.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n // Data 1 is invalid, Data 0 is valid\n validationData = checkSignatures(\n userOpHash,\n userOp.signature,\n LibMultiSigStorage.multisigStorage().threshold\n );\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n return this.validateOwnerSignature.selector;\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n uint totalLength = ms.ownerCount * ADDRESS;\n bytes memory result = new bytes(totalLength);\n\n // populate return array\n uint256 index;\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n while (currentOwner != SENTINEL_OWNERS) {\n assembly {\n mstore(\n add(result, add(32, mul(index, ADDRESS))),\n shl(96, currentOwner)\n )\n }\n currentOwner = ms.owners[currentOwner];\n index++;\n }\n\n return result;\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key should comply with the format in the signature_format.md doc\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n uint256 publicKeyLength = _publicKey.length;\n if (\n publicKeyLength < ADDRESS + THRESHOLD ||\n (publicKeyLength - THRESHOLD) % ADDRESS != 0\n ) return false;\n\n uint256 threshold = uint256(uint32(bytes4(_publicKey)));\n uint256 ownerCount = (publicKeyLength - THRESHOLD) / ADDRESS;\n\n isValid = !(ownerCount < threshold || threshold == 0);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes calldata _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (checkSignatures(\n _hash,\n _signature,\n LibMultiSigStorage.multisigStorage().threshold\n ) == VALID_SIG)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n\n /**\n * @notice Validates the format of the signature and verifies if the signature is signed by the expected key.\n * Reference signature_format.md doc for details about signature format and signature types\n * @param _dataHash Bytes value of data hash signed by the owners\n * @param _signatures Bytes value of signature which should comply with signature format\n * @param _threshold Uint256 value of current Multi-sig Barz's threshold\n */\n function checkSignatures(\n bytes32 _dataHash,\n bytes calldata _signatures,\n uint256 _threshold\n ) public view returns (uint256) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n address lastOwner = address(0);\n address currentOwner;\n bytes memory signature;\n uint256 signatureType;\n uint256 nextOffset;\n uint256 i;\n for (i; i < _threshold; ) {\n (\n currentOwner,\n signature,\n signatureType,\n nextOffset\n ) = splitSignatures(_signatures, nextOffset);\n if (nextOffset == 0 && i + 1 < _threshold) return INVALID_SIG;\n if (signatureType == 1) {\n // If signatureType is 1 then it is default dataHash signed.\n // This also includes the contract signature\n if (\n !SignatureChecker.isValidSignatureNow(\n currentOwner,\n _dataHash,\n signature\n )\n ) return INVALID_SIG;\n } else if (signatureType == 2) {\n // If signatureType is 2 then it is an approved hash\n if (ms.approvedHashes[ms.counter][currentOwner][_dataHash] == 0)\n return INVALID_SIG;\n } else if (signatureType == 3) {\n // If signatureType is 3 then it is a signed message hash\n // This also includes the contract signature\n bytes32 msgHash = _dataHash.toEthSignedMessageHash();\n if (\n !SignatureChecker.isValidSignatureNow(\n currentOwner,\n msgHash,\n signature\n )\n ) return INVALID_SIG;\n } else revert MultiSigFacet__InvalidRoute();\n if (\n currentOwner <= lastOwner ||\n ms.owners[currentOwner] == address(0) ||\n currentOwner == SENTINEL_OWNERS\n ) return INVALID_SIG;\n lastOwner = currentOwner;\n\n unchecked {\n ++i;\n }\n }\n return VALID_SIG;\n }\n\n /**\n * @notice Split signatures into each individual signatures. Should comply with signature format to be split\n * @param _signatures Bytes value of signature\n * @param _nextOffset Uint256 value of next offset to start splitting the signature\n */\n function splitSignatures(\n bytes calldata _signatures,\n uint256 _nextOffset\n )\n public\n pure\n returns (\n address owner_,\n bytes memory signature,\n uint256 signatureType,\n uint256 nextOffset\n )\n {\n uint256 signaturesLength = _signatures.length;\n\n if (signaturesLength <= _nextOffset + ADDRESS + SIG_LEN)\n revert MultiSigFacet__InsufficientSignerLength();\n\n owner_ = address(\n bytes20(_signatures[_nextOffset:_nextOffset + ADDRESS])\n );\n\n signatureType = uint256(\n uint8(\n bytes1(\n _signatures[_nextOffset + ADDRESS:_nextOffset +\n ADDRESS +\n SIG_TYPE]\n )\n )\n );\n\n if (signatureType > 3 || signatureType == 0)\n revert MultiSigFacet__InvalidSignatureType();\n uint256 offSet = _nextOffset + ADDRESS + SIG_TYPE;\n uint256 siglen = uint256(\n uint32(bytes4(_signatures[offSet:offSet + SIG_LEN]))\n );\n if (offSet + siglen > signaturesLength)\n revert MultiSigFacet__InvalidSignatureLength();\n\n offSet += SIG_LEN;\n if (offSet + siglen == signaturesLength) nextOffset = 0;\n else nextOffset = offSet + siglen;\n\n signature = _signatures[offSet:offSet + siglen];\n }\n\n /**\n * @notice Approves the hash of userOperation on-chain. This can only be called by owners.\n * @param _hashToApprove Bytes value of UserOperation hash to approve\n */\n function approveHash(bytes32 _hashToApprove) external {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (ms.owners[msg.sender] == address(0))\n revert MultiSigFacet__OnlyOwner();\n\n ms.approvedHashes[ms.counter][msg.sender][_hashToApprove] = 1;\n emit HashApproved(_hashToApprove, msg.sender);\n }\n\n /**\n * @notice Add owner to Barz. Update thresold if threshold is given different from current threshold\n * @dev This can only be done via a Self call.\n * @param _newOwner Address of new owner to be added\n * @param _threshold Uint256 value of threshold\n */\n function addOwner(address _newOwner, uint256 _threshold) external {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (\n _newOwner == address(0) ||\n _newOwner == SENTINEL_OWNERS ||\n _newOwner == address(this)\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_newOwner] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n\n ms.owners[_newOwner] = ms.owners[SENTINEL_OWNERS];\n ms.owners[SENTINEL_OWNERS] = _newOwner;\n ++ms.ownerCount;\n emit OwnerAdded(_newOwner);\n\n if (ms.threshold != _threshold) changeThreshold(_threshold);\n }\n\n /**\n * @notice Remove owner from Barz. Update thresold if threshold is given different from current threshold\n * @dev This can only be done via a Self call.\n * @param _prevOwner Address of owner located right behind the removed owner address in the linked list\n * @param _removedOwner Address of owner to be removed\n * @param _threshold Uint256 value of threshold\n */\n function removeOwner(\n address _prevOwner,\n address _removedOwner,\n uint256 _threshold\n ) external {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (ms.ownerCount - 1 < _threshold)\n revert MultiSigFacet__InvalidThreshold();\n if (_removedOwner == address(0) || _removedOwner == SENTINEL_OWNERS)\n revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_prevOwner] != _removedOwner)\n revert MultiSigFacet__InvalidOwnerPair();\n\n ms.owners[_prevOwner] = ms.owners[_removedOwner];\n ms.owners[_removedOwner] = address(0);\n --ms.ownerCount;\n emit OwnerRemoved(_removedOwner);\n\n if (ms.threshold != _threshold) changeThreshold(_threshold);\n }\n\n /**\n * @notice Swap owner in Barz.\n * @dev This can only be done via a Self call.\n * @param _prevOwner Address of owner located right behind the removed owner address in the linked list\n * @param _oldOwner Address of owner to be removed\n * @param _newOwner Address of owner to be added\n */\n function swapOwner(\n address _prevOwner,\n address _oldOwner,\n address _newOwner\n ) public {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (\n _newOwner == address(0) ||\n _newOwner == SENTINEL_OWNERS ||\n _newOwner == address(this)\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_newOwner] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n if (_oldOwner == address(0) || _oldOwner == SENTINEL_OWNERS)\n revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_prevOwner] != _oldOwner)\n revert MultiSigFacet__InvalidOwnerPair();\n\n ms.owners[_newOwner] = ms.owners[_oldOwner];\n ms.owners[_prevOwner] = _newOwner;\n ms.owners[_oldOwner] = address(0);\n emit OwnerRemoved(_oldOwner);\n emit OwnerAdded(_newOwner);\n }\n\n /**\n * @notice Changes the threshold of the Barz to `_threshold`.\n * @dev This can only be done via a Self call.\n * @param _threshold New threshold\n */\n function changeThreshold(uint256 _threshold) public {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (_threshold > ms.ownerCount || _threshold == 0)\n revert MultiSigFacet__InvalidThreshold();\n\n ms.threshold = _threshold;\n emit ThresholdChanged(_threshold);\n }\n\n /**\n * @notice Checks if the given address is owner\n * @param _owner Address to be checked if it's owner\n * @return isOwner_ Bool value showing if it's owner address\n */\n function isOwner(address _owner) public view returns (bool isOwner_) {\n isOwner_ = (_owner != SENTINEL_OWNERS &&\n LibMultiSigStorage.multisigStorage().owners[_owner] != address(0));\n }\n\n /**\n * @notice Returns the threshold of Barz\n * @return threshold Threshold of the Barz account\n */\n function getThreshold() public view returns (uint256 threshold) {\n threshold = LibMultiSigStorage.multisigStorage().threshold;\n }\n\n /**\n * @notice Returns the list of owner addresses\n * @return owners List of owners\n */\n function getOwners() public view returns (address[] memory owners) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n owners = new address[](ms.ownerCount);\n\n uint256 index;\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n while (currentOwner != SENTINEL_OWNERS) {\n owners[index] = currentOwner;\n currentOwner = ms.owners[currentOwner];\n index++;\n }\n }\n\n /**\n * @notice Returns the previous owner in the linked list\n * @param _owner Address of owner\n * @return prevOwner Address of previous owner\n */\n function getPrevOwner(\n address _owner\n ) public view returns (address prevOwner) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n if (currentOwner == _owner) return SENTINEL_OWNERS;\n while (currentOwner != SENTINEL_OWNERS) {\n if (ms.owners[currentOwner] == _owner) return currentOwner;\n\n currentOwner = ms.owners[currentOwner];\n }\n return address(0);\n }\n\n /**\n * @notice Returns of the owner is approved by given owner address\n * @param _owner Address of owner\n * @param _hash Hash of UserOperation\n * @return isApproved Bool value showing if the hash is approved by owner\n */\n function isApprovedHash(\n address _owner,\n bytes32 _hash\n ) public view returns (bool isApproved) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n isApproved = (ms.approvedHashes[ms.counter][_owner][_hash] == 1);\n }\n}\n" + }, + "contracts/facets/verification/secp256k1/Secp256k1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {UserOperation} from \"../../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibAppStorage} from \"../../../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, Secp256k1VerificationStorage} from \"../../../libraries/LibFacetStorage.sol\";\nimport {LibLoupe} from \"../../../libraries/LibLoupe.sol\";\nimport {IERC1271} from \"../../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../../interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Secp256k1 verification facet\n * @dev Default Ethereum's elliptic curve\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract Secp256k1VerificationFacet is IVerificationFacet, IERC1271 {\n using ECDSA for bytes32;\n error Secp256k1VerificationFacet__InvalidSignerLength();\n address public immutable self;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in K1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\n * @param _publicKey Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _publicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n if (!isValidKeyType(_publicKey))\n revert Secp256k1VerificationFacet__InvalidSignerLength();\n\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(uint160(uint256(keccak256(_publicKey[1:]))));\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_publicKey);\n }\n\n /**\n * @notice Uninitialize signer in K1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\n * signer public key.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n validationData = validateSignature(\n userOp,\n userOpHash,\n k1Storage.signer\n );\n }\n\n /**\n * @notice Validates if the signature of UserOperation is signed by the given signer\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @param signer Address of signer who signed the contract, to be validated\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n address signer\n ) public pure returns (uint256 isValid) {\n bytes32 hash = userOpHash.toEthSignedMessageHash();\n isValid = (signer != hash.recover(userOp.signature)) ? 1 : 0;\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n ownerSignatureValidatorSelector = this.validateOwnerSignature.selector;\n // NOTE: The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory signer) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n signer = abi.encodePacked(k1Storage.signer);\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key length should be 65 in an uncompressed public key format\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (_hash.recover(_signature) ==\n LibFacetStorage.k1Storage().signer)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/Secp256r1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {UserOperation} from \"../../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibAppStorage} from \"../../../libraries/LibAppStorage.sol\";\nimport {LibLoupe} from \"../../../libraries/LibLoupe.sol\";\nimport {LibFacetStorage, Secp256r1VerificationStorage} from \"../../../libraries/LibFacetStorage.sol\";\nimport {Base64} from \"./utils/Base64.sol\";\nimport {LibSecp256r1} from \"./utils/LibSecp256r1.sol\";\nimport {IERC1271} from \"../../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../../interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Secp256r1 verification facet\n * @dev Primarily used to verify user ops signed with passkeys\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract Secp256r1VerificationFacet is IVerificationFacet, IERC1271 {\n error Secp256r1VerificationFacet__InvalidSignerLength();\n address public immutable self;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in R1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\n * @param _publicKey Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _publicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n\n if (!isValidKeyType(_publicKey))\n revert Secp256r1VerificationFacet__InvalidSignerLength();\n\n bytes memory publicKeyCoordinates = _publicKey[1:];\n uint256[2] memory q;\n assembly {\n // Copy the bytes from the input data into the uint256 array\n mstore(q, mload(add(publicKeyCoordinates, 32)))\n mstore(add(q, 32), mload(add(publicKeyCoordinates, 64)))\n }\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n r1Storage.q = q;\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_publicKey);\n }\n\n /**\n * @notice Uninitialize signer in R1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n r1Storage.q = [0, 0];\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\n * signer public key.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n validationData = validateSignature(userOp, userOpHash, r1Storage.q);\n }\n\n /**\n * @notice Validates if the signature of UserOperation is signed by the given signer\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @param q Public Key of signer who signed the contract, to be validated\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256[2] memory q\n ) public view returns (uint256 isValid) {\n isValid = (_validateSignature(q, userOpHash, userOp.signature)) ? 0 : 1;\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n return this.validateOwnerSignature.selector; // validateOwnerSignature(UserOperation calldata userOp,bytes32 userOpHash)\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory signer) {\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n signer = abi.encodePacked(r1Storage.q);\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key should in an uncompressed public key format\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = _validateSignature(\n LibFacetStorage.r1Storage().q,\n _hash,\n _signature\n )\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n\n function _validateSignature(\n uint256[2] memory q,\n bytes32 _hash,\n bytes memory _signature\n ) internal view returns (bool) {\n (\n uint256 rValue,\n uint256 sValue,\n bytes memory authenticatorData,\n string memory clientDataJSONPre,\n string memory clientDataJSONPost\n ) = abi.decode(_signature, (uint256, uint256, bytes, string, string));\n bytes32 clientHash;\n {\n string memory opHashBase64 = Base64.encode(bytes.concat(_hash));\n string memory clientDataJSON = string.concat(\n clientDataJSONPre,\n opHashBase64,\n clientDataJSONPost\n );\n clientHash = sha256(bytes(clientDataJSON));\n }\n bytes32 sigHash = sha256(bytes.concat(authenticatorData, clientHash));\n return LibSecp256r1.Verify(q, rValue, sValue, uint256(sigHash));\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/utils/Base64.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @dev Provides a set of functions to operate with Base64 strings.\n * modified for base64url https://datatracker.ietf.org/doc/html/rfc4648#section-5\n * _Available since v4.5._\n */\nlibrary Base64 {\n /**\n * @dev Base64 Encoding/Decoding Table\n */\n string internal constant _TABLE =\n \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_\";\n\n /**\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\n */\n function encode(bytes memory data) internal pure returns (string memory) {\n /**\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\n */\n if (data.length == 0) return \"\";\n\n // Loads the table into memory\n string memory table = _TABLE;\n\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\n // and split into 4 numbers of 6 bits.\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\n // - `data.length + 2` -> Round up\n // - `/ 3` -> Number of 3-bytes chunks\n // - `4 *` -> 4 characters for each chunk\n uint256 newlength = (data.length * 8) / 6;\n if (data.length % 6 > 0) {\n newlength++;\n }\n string memory result = new string(newlength);\n\n /// @solidity memory-safe-assembly\n assembly {\n // Prepare the lookup table (skip the first \"length\" byte)\n let tablePtr := add(table, 1)\n\n // Prepare result pointer, jump over length\n let resultPtr := add(result, 32)\n\n // Run over the input, 3 bytes at a time\n for {\n let dataPtr := data\n let endPtr := add(data, mload(data))\n } lt(dataPtr, endPtr) {\n\n } {\n // Advance 3 bytes\n dataPtr := add(dataPtr, 3)\n let input := mload(dataPtr)\n\n // To write each character, shift the 3 bytes (18 bits) chunk\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\n // and apply logical AND with 0x3F which is the number of\n // the previous character in the ASCII table prior to the Base64 Table\n // The result is then added to the table to get the character to write,\n // and finally write it in the result pointer but with a left shift\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(18, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(12, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(6, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n }\n }\n\n return result;\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/utils/LibSecp256r1.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n// Heavily inspired from\n// https://github.com/maxrobot/elliptic-solidity/blob/master/contracts/Secp256r1.sol\n// https://github.com/tdrerup/elliptic-curve-solidity/blob/master/contracts/curves/EllipticCurve.sol\n// modified to use precompile 0x05 modexp\n// and modified jacobian double\n// optimisations to avoid to an from from affine and jacobian coordinates\n\n// Additional Elliptic curve Public key / Signature validation added by\n// David Yonjun Kim (@Powerstream3604)\n\nstruct JPoint {\n uint256 x;\n uint256 y;\n uint256 z;\n}\n\nlibrary LibSecp256r1 {\n uint256 constant gx =\n 0x6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296;\n uint256 constant gy =\n 0x4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5;\n uint256 public constant pp =\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF;\n\n uint256 public constant nn =\n 0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551;\n uint256 constant a =\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC;\n uint256 constant b =\n 0x5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B;\n uint256 constant MOST_SIGNIFICANT =\n 0xc000000000000000000000000000000000000000000000000000000000000000;\n\n /*\n * Verify\n * @description - verifies that a public key has signed a given message\n * @param Q - public key coordinates X & Y\n * @param R - signature half R\n * @param S - signature half S\n * @param input - hashed message\n */\n function Verify(\n uint256[2] memory q,\n uint r,\n uint s,\n uint e\n ) internal view returns (bool) {\n if (q[0] > pp - 1 || q[1] > pp - 1) {\n return false;\n }\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\n return false;\n }\n if (\n mulmod(q[1], q[1], pp) !=\n addmod(\n addmod(\n mulmod(q[0], mulmod(q[0], q[0], pp), pp),\n mulmod(a, q[0], pp),\n pp\n ),\n b,\n pp\n )\n ) {\n return false;\n }\n\n JPoint[16] memory points = _preComputeJacobianPoints(q);\n return VerifyWithPrecompute(points, r, s, e);\n }\n\n function VerifyWithPrecompute(\n JPoint[16] memory points,\n uint r,\n uint s,\n uint e\n ) internal view returns (bool) {\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\n return false;\n }\n\n uint w = _primemod(s, nn);\n\n uint u1 = mulmod(e, w, nn);\n uint u2 = mulmod(r, w, nn);\n\n uint x;\n uint y;\n\n (x, y) = ShamirMultJacobian(points, u1, u2);\n return (x == r);\n }\n\n /*\n * Strauss Shamir trick for EC multiplication\n * https://stackoverflow.com/questions/50993471/ec-scalar-multiplication-with-strauss-shamir-method\n * we optimise on this a bit to do with 2 bits at a time rather than a single bit\n * the individual points for a single pass are precomputed\n * overall this reduces the number of additions while keeping the same number of doublings\n */\n function ShamirMultJacobian(\n JPoint[16] memory points,\n uint u1,\n uint u2\n ) internal view returns (uint, uint) {\n uint x = 0;\n uint y = 0;\n uint z = 0;\n uint bits = 128;\n uint index = 0;\n\n while (bits > 0) {\n if (z > 0) {\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\n }\n index =\n ((u1 & MOST_SIGNIFICANT) >> 252) |\n ((u2 & MOST_SIGNIFICANT) >> 254);\n if (index > 0) {\n (x, y, z) = _jAdd(\n x,\n y,\n z,\n points[index].x,\n points[index].y,\n points[index].z\n );\n }\n u1 <<= 2;\n u2 <<= 2;\n bits--;\n }\n (x, y) = _affineFromJacobian(x, y, z);\n return (x, y);\n }\n\n function _preComputeJacobianPoints(\n uint256[2] memory q\n ) internal pure returns (JPoint[16] memory points) {\n points[0] = JPoint(0, 0, 0);\n points[1] = JPoint(q[0], q[1], 1); // u2\n points[2] = _jPointDouble(points[1]);\n points[3] = _jPointAdd(points[1], points[2]);\n\n points[4] = JPoint(gx, gy, 1); // u1Points[1]\n points[5] = _jPointAdd(points[4], points[1]);\n points[6] = _jPointAdd(points[4], points[2]);\n points[7] = _jPointAdd(points[4], points[3]);\n\n points[8] = _jPointDouble(points[4]); // u1Points[2]\n points[9] = _jPointAdd(points[8], points[1]);\n points[10] = _jPointAdd(points[8], points[2]);\n points[11] = _jPointAdd(points[8], points[3]);\n\n points[12] = _jPointAdd(points[4], points[8]); // u1Points[3]\n points[13] = _jPointAdd(points[12], points[1]);\n points[14] = _jPointAdd(points[12], points[2]);\n points[15] = _jPointAdd(points[12], points[3]);\n }\n\n function _jPointAdd(\n JPoint memory p1,\n JPoint memory p2\n ) internal pure returns (JPoint memory) {\n uint x;\n uint y;\n uint z;\n (x, y, z) = _jAdd(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z);\n return JPoint(x, y, z);\n }\n\n function _jPointDouble(\n JPoint memory p\n ) internal pure returns (JPoint memory) {\n uint x;\n uint y;\n uint z;\n (x, y, z) = _modifiedJacobianDouble(p.x, p.y, p.z);\n return JPoint(x, y, z);\n }\n\n /* _affineFromJacobian\n * @desription returns affine coordinates from a jacobian input follows\n * golang elliptic/crypto library\n */\n function _affineFromJacobian(\n uint x,\n uint y,\n uint z\n ) internal view returns (uint ax, uint ay) {\n if (z == 0) {\n return (0, 0);\n }\n\n uint zinv = _primemod(z, pp);\n uint zinvsq = mulmod(zinv, zinv, pp);\n\n ax = mulmod(x, zinvsq, pp);\n ay = mulmod(y, mulmod(zinvsq, zinv, pp), pp);\n }\n\n /*\n * _jAdd\n * @description performs Jacobian addition as defined below:\n * http://www.hyperelliptic.org/EFD/g1p/data/shortw/jacobian/addition/add-2007-bl\n */\n function _jAdd(\n uint p1,\n uint p2,\n uint p3,\n uint q1,\n uint q2,\n uint q3\n ) internal pure returns (uint r1, uint r2, uint r3) {\n if (p3 == 0) {\n r1 = q1;\n r2 = q2;\n r3 = q3;\n\n return (r1, r2, r3);\n } else if (q3 == 0) {\n r1 = p1;\n r2 = p2;\n r3 = p3;\n\n return (r1, r2, r3);\n }\n\n assembly {\n let\n pd\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\n let z1z1 := mulmod(p3, p3, pd) // Z1Z1 = Z1^2\n let z2z2 := mulmod(q3, q3, pd) // Z2Z2 = Z2^2\n\n let u1 := mulmod(p1, z2z2, pd) // U1 = X1*Z2Z2\n let u2 := mulmod(q1, z1z1, pd) // U2 = X2*Z1Z1\n\n let s1 := mulmod(p2, mulmod(z2z2, q3, pd), pd) // S1 = Y1*Z2*Z2Z2\n let s2 := mulmod(q2, mulmod(z1z1, p3, pd), pd) // S2 = Y2*Z1*Z1Z1\n\n let p3q3 := addmod(p3, q3, pd)\n\n if lt(u2, u1) {\n u2 := add(pd, u2) // u2 = u2+pd\n }\n let h := sub(u2, u1) // H = U2-U1\n\n let i := mulmod(0x02, h, pd)\n i := mulmod(i, i, pd) // I = (2*H)^2\n\n let j := mulmod(h, i, pd) // J = H*I\n if lt(s2, s1) {\n s2 := add(pd, s2) // u2 = u2+pd\n }\n let rr := mulmod(0x02, sub(s2, s1), pd) // r = 2*(S2-S1)\n r1 := mulmod(rr, rr, pd) // X3 = R^2\n\n let v := mulmod(u1, i, pd) // V = U1*I\n let j2v := addmod(j, mulmod(0x02, v, pd), pd)\n if lt(r1, j2v) {\n r1 := add(pd, r1) // X3 = X3+pd\n }\n r1 := sub(r1, j2v)\n\n // Y3 = r*(V-X3)-2*S1*J\n let s12j := mulmod(mulmod(0x02, s1, pd), j, pd)\n\n if lt(v, r1) {\n v := add(pd, v)\n }\n r2 := mulmod(rr, sub(v, r1), pd)\n\n if lt(r2, s12j) {\n r2 := add(pd, r2)\n }\n r2 := sub(r2, s12j)\n\n // Z3 = ((Z1+Z2)^2-Z1Z1-Z2Z2)*H\n z1z1 := addmod(z1z1, z2z2, pd)\n j2v := mulmod(p3q3, p3q3, pd)\n if lt(j2v, z1z1) {\n j2v := add(pd, j2v)\n }\n r3 := mulmod(sub(j2v, z1z1), h, pd)\n }\n return (r1, r2, r3);\n }\n\n // Point doubling on the modified jacobian coordinates\n // http://point-at-infinity.org/ecc/Prime_Curve_Modified_Jacobian_Coordinates.html\n function _modifiedJacobianDouble(\n uint x,\n uint y,\n uint z\n ) internal pure returns (uint x3, uint y3, uint z3) {\n if (y == 0) return (0, 0, 0);\n assembly {\n let\n pd\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\n let z2 := mulmod(z, z, pd)\n let az4 := mulmod(\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC,\n mulmod(z2, z2, pd),\n pd\n )\n let y2 := mulmod(y, y, pd)\n let s := mulmod(0x04, mulmod(x, y2, pd), pd)\n let u := mulmod(0x08, mulmod(y2, y2, pd), pd)\n let m := addmod(mulmod(0x03, mulmod(x, x, pd), pd), az4, pd)\n let twos := mulmod(0x02, s, pd)\n let m2 := mulmod(m, m, pd)\n if lt(m2, twos) {\n m2 := add(pd, m2)\n }\n x3 := sub(m2, twos)\n if lt(s, x3) {\n s := add(pd, s)\n }\n y3 := mulmod(m, sub(s, x3), pd)\n if lt(y3, u) {\n y3 := add(pd, y3)\n }\n y3 := sub(y3, u)\n z3 := mulmod(0x02, mulmod(y, z, pd), pd)\n }\n }\n\n // Fermats little theorem https://en.wikipedia.org/wiki/Fermat%27s_little_theorem\n // a^(p-1) = 1 mod p\n // a^(-1) ≅ a^(p-2) (mod p)\n // we then use the precompile bigModExp to compute a^(-1)\n function _primemod(uint value, uint p) internal view returns (uint ret) {\n ret = modexp(value, p - 2, p);\n return ret;\n }\n\n // Wrapper for built-in BigNumber_modexp (contract 0x5) as described here. https://github.com/ethereum/EIPs/pull/198\n function modexp(\n uint _base,\n uint _exp,\n uint _mod\n ) internal view returns (uint ret) {\n // bigModExp(_base, _exp, _mod);\n assembly {\n if gt(_base, _mod) {\n _base := mod(_base, _mod)\n }\n // Free memory pointer is always stored at 0x40\n let freemem := mload(0x40)\n\n mstore(freemem, 0x20)\n mstore(add(freemem, 0x20), 0x20)\n mstore(add(freemem, 0x40), 0x20)\n\n mstore(add(freemem, 0x60), _base)\n mstore(add(freemem, 0x80), _exp)\n mstore(add(freemem, 0xa0), _mod)\n\n let success := staticcall(14000, 0x5, freemem, 0xc0, freemem, 0x20)\n switch success\n case 0 {\n revert(0x0, 0x0)\n }\n default {\n ret := mload(freemem)\n }\n }\n }\n}\n" + }, + "contracts/infrastructure/DefaultFallbackHandler.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC1155Receiver} from \"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\";\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {BaseAccount} from \"../aa-4337/core/BaseAccount.sol\";\nimport {DefaultLibDiamond} from \"../libraries/DefaultLibDiamond.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IAccountFacet} from \"../facets/interfaces/IAccountFacet.sol\";\nimport {IStorageLoupe} from \"../facets/base/interfaces/IStorageLoupe.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IERC677Receiver} from \"../interfaces/ERC/IERC677Receiver.sol\";\nimport {IERC165} from \"../interfaces/ERC/IERC165.sol\";\n\n/**\n * @title DefaultFallbackHandler\n * @dev A default fallback handler for Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DefaultFallbackHandler is IDiamondLoupe {\n /**\n * @notice Sets the middleware diamond for Barz wallet as a fallback handler\n * @dev This contract is also a diamond that holds the default facets to reduce gas cost for wallet activation.\n * Within the constructor this conducts diamond cut to initially setup the diamond. This is a non-upgradeable contract\n * @param _diamondCutFacet Address if diamond cut facet\n * @param _accountFacet Address account facet\n * @param _tokenReceiverFacet Address of token receiver facet\n * @param _diamondLoupeFacet Address of diamond loupe facet\n */\n constructor(\n address _diamondCutFacet,\n address _accountFacet,\n address _tokenReceiverFacet,\n address _diamondLoupeFacet\n ) payable {\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](4);\n bytes4[] memory functionSelectors = new bytes4[](1);\n functionSelectors[0] = IDiamondCut.diamondCut.selector;\n\n bytes4[] memory accountFunctionSelectors = new bytes4[](5);\n accountFunctionSelectors[0] = IAccountFacet.execute.selector;\n accountFunctionSelectors[1] = IAccountFacet.executeBatch.selector;\n accountFunctionSelectors[2] = BaseAccount.validateUserOp.selector;\n accountFunctionSelectors[3] = BaseAccount.getNonce.selector;\n accountFunctionSelectors[4] = BaseAccount.entryPoint.selector;\n\n bytes4[] memory receiverFacetSelectors = new bytes4[](5);\n receiverFacetSelectors[0] = IERC721Receiver.onERC721Received.selector;\n receiverFacetSelectors[1] = IERC1155Receiver.onERC1155Received.selector;\n receiverFacetSelectors[2] = IERC1155Receiver\n .onERC1155BatchReceived\n .selector;\n receiverFacetSelectors[3] = IERC777Recipient.tokensReceived.selector;\n receiverFacetSelectors[4] = IERC677Receiver.onTokenTransfer.selector;\n\n bytes4[] memory loupeFacetSelectors = new bytes4[](9);\n loupeFacetSelectors[0] = IDiamondLoupe.facets.selector;\n loupeFacetSelectors[1] = IDiamondLoupe.facetFunctionSelectors.selector;\n loupeFacetSelectors[2] = IDiamondLoupe.facetAddresses.selector;\n loupeFacetSelectors[3] = IDiamondLoupe.facetAddress.selector;\n loupeFacetSelectors[4] = IERC165.supportsInterface.selector;\n loupeFacetSelectors[5] = IStorageLoupe.facetsFromStorage.selector;\n loupeFacetSelectors[6] = IStorageLoupe\n .facetFunctionSelectorsFromStorage\n .selector;\n loupeFacetSelectors[7] = IStorageLoupe\n .facetAddressesFromStorage\n .selector;\n loupeFacetSelectors[8] = IStorageLoupe.facetAddressFromStorage.selector;\n\n {\n cut[0] = IDiamondCut.FacetCut({\n facetAddress: _diamondCutFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: functionSelectors\n });\n cut[1] = IDiamondCut.FacetCut({\n facetAddress: _accountFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: accountFunctionSelectors\n });\n cut[2] = IDiamondCut.FacetCut({\n facetAddress: _tokenReceiverFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: receiverFacetSelectors\n });\n cut[3] = IDiamondCut.FacetCut({\n facetAddress: _diamondLoupeFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: loupeFacetSelectors\n });\n\n DefaultLibDiamond.diamondCut(cut, address(0), \"\");\n }\n }\n\n /**\n * @notice Returns the facet information of call facets registered to this diamond.\n * @return facets_ The facet struct array including all facet information\n */\n function facets() external view override returns (Facet[] memory facets_) {\n DefaultLibDiamond.DiamondStorage storage ds = DefaultLibDiamond\n .diamondStorage();\n uint256 numFacets = ds.facetAddresses.length;\n facets_ = new Facet[](numFacets);\n for (uint256 i; i < numFacets; ) {\n address facetAddress_ = ds.facetAddresses[i];\n facets_[i].facetAddress = facetAddress_;\n facets_[i].functionSelectors = ds\n .facetFunctionSelectors[facetAddress_]\n .functionSelectors;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Gets all the function selectors provided by a facet.\n * @param _facet The facet address.\n * @return facetFunctionSelectors_\n */\n function facetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n facetFunctionSelectors_ = DefaultLibDiamond\n .diamondStorage()\n .facetFunctionSelectors[_facet]\n .functionSelectors;\n }\n\n /**\n * @notice Get all the facet addresses used by a diamond.\n * @return facetAddresses_\n */\n function facetAddresses()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n facetAddresses_ = DefaultLibDiamond.diamondStorage().facetAddresses;\n }\n\n /** @notice Gets the facet that supports the given selector.\n * @dev If facet is not found return address(0).\n * @param _functionSelector The function selector.\n * @return facetAddress_ The facet address.\n */\n function facetAddress(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n facetAddress_ = DefaultLibDiamond\n .diamondStorage()\n .selectorToFacetAndPosition[_functionSelector]\n .facetAddress;\n }\n}\n" + }, + "contracts/infrastructure/FacetRegistry.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport {IFacetRegistry} from \"./interfaces/IFacetRegistry.sol\";\n\n/**\n * @title Facet Registry\n * @dev Contract to keep track of facets & function selectors addable to user wallets\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract FacetRegistry is IFacetRegistry, Ownable2Step {\n mapping(address => FacetRegistryConfig) private facets;\n\n /**\n * @notice Transfers the ownership of the contract to the given owner\n * @param _owner Address of owner who has access to initialize the default security variables for security manager\n */\n constructor(address _owner) {\n transferOwnership(_owner);\n _transferOwnership(_owner);\n }\n\n /**\n * @dev Registers a facet and it's function selectors to registry\n * @param _facet address of facet\n * @param _facetSelectors list of function selectors of the facet\n */\n function registerFacetFunctionSelectors(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external override onlyOwner {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n for (uint256 i; i < _facetSelectors.length; ) {\n if (facetConfig.info[_facetSelectors[i]].exists)\n revert FacetRegistry__FacetSelectorAlreadyRegistered();\n\n facetConfig.info[_facetSelectors[i]].exists = true;\n facetConfig.info[_facetSelectors[i]].index = uint128(\n facetConfig.selectors.length\n );\n facetConfig.selectors.push(_facetSelectors[i]);\n unchecked {\n ++i;\n }\n }\n emit FacetFunctionSelectorsRegistered(_facet, _facetSelectors);\n }\n\n /**\n * @dev Removes a registered facet and it's corresponding selectors from registry\n * @param _facet address of facet\n * @param _facetSelectors list of function selectors of the facet\n */\n function removeFacetFunctionSelectors(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external override onlyOwner {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n for (uint256 i; i < _facetSelectors.length; ) {\n if (!facetConfig.info[_facetSelectors[i]].exists)\n revert FacetRegistry__UnregisteredFacetSelector();\n\n bytes4 lastSelector = facetConfig.selectors[\n facetConfig.selectors.length - 1\n ];\n if (_facetSelectors[i] != lastSelector) {\n uint128 targetIndex = facetConfig\n .info[_facetSelectors[i]]\n .index;\n facetConfig.selectors[targetIndex] = lastSelector;\n facetConfig.info[lastSelector].index = targetIndex;\n }\n facetConfig.selectors.pop();\n delete facetConfig.info[_facetSelectors[i]];\n\n unchecked {\n ++i;\n }\n }\n emit FacetFunctionSelectorsRemoved(_facet, _facetSelectors);\n }\n\n /**\n * @dev Checks if a facet and it's selectors given is registered to facet registry\n * @param _facet Address of facet\n * @param _facetSelectors List of function selectors of the facet\n */\n function areFacetFunctionSelectorsRegistered(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external view override returns (bool) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n if (_facetSelectors.length == 0) return false;\n for (uint256 i; i < _facetSelectors.length; ) {\n if (!facetConfig.info[_facetSelectors[i]].exists) return false;\n unchecked {\n ++i;\n }\n }\n return true;\n }\n\n /**\n * @dev Checks if a facet and it's selector given is registered to facet registry\n * @param _facet Address of facet\n * @param _facetSelector List of function selectors of the facet\n * @return isRegistered Bool value showing if the selector is registered\n */\n function isFacetFunctionSelectorRegistered(\n address _facet,\n bytes4 _facetSelector\n ) external view override returns (bool isRegistered) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n isRegistered = facetConfig.info[_facetSelector].exists;\n }\n\n /**\n * @dev Get the registered selectors of facet from registry\n * @param _facet Address of facet\n * @return selectors Selectors registered to facet\n */\n function getFacetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory selectors) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n selectors = facetConfig.selectors;\n }\n}\n" + }, + "contracts/infrastructure/interfaces/IFacetRegistry.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Registry Interface\n * @dev Interface for Facet Registry contract to keep track of facets & function selectors addable to user wallets\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IFacetRegistry {\n struct FacetRegistryConfig {\n bytes4[] selectors;\n mapping(bytes4 => FacetInfo) info;\n }\n struct FacetInfo {\n bool exists;\n uint128 index;\n }\n\n event FacetFunctionSelectorsRegistered(\n address facet,\n bytes4[] facetSelectors\n );\n event FacetFunctionSelectorsRemoved(address facet, bytes4[] facetSelectors);\n\n error FacetRegistry__FacetSelectorAlreadyRegistered();\n error FacetRegistry__UnregisteredFacetSelector();\n\n function registerFacetFunctionSelectors(\n address facet,\n bytes4[] calldata facetSelectors\n ) external;\n\n function removeFacetFunctionSelectors(\n address facet,\n bytes4[] calldata facetSelectors\n ) external;\n\n function areFacetFunctionSelectorsRegistered(\n address facet,\n bytes4[] calldata facetSelectors\n ) external view returns (bool);\n\n function isFacetFunctionSelectorRegistered(\n address facet,\n bytes4 facetSelector\n ) external view returns (bool);\n\n function getFacetFunctionSelectors(\n address facet\n ) external view returns (bytes4[] memory);\n}\n" + }, + "contracts/infrastructure/interfaces/ISecurityManager.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Registry Interface\n * @dev Infrastructure contract to manage security parameters of users\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface ISecurityManager {\n error SecurityManager__OutOfBoundary();\n error SecurityManager__CallerNotWallet();\n error SecurityManager__AlreadyIntialized();\n\n function initializeAdditionSecurityPeriod(\n uint128 defaultAdditionSecurityPeriod,\n uint128 minAdditionSecurityPeriod,\n uint128 maxAdditionSecurityPeriod\n ) external;\n\n function initializeRemovalSecurityPeriod(\n uint128 defaultRemovalSecurityPeriod,\n uint128 minRemovalSecurityPeriod,\n uint128 maxRemovalSecurityPeriod\n ) external;\n\n function initializeApprovalValidationPeriod(\n uint128 defaultApprovalValidationPeriod,\n uint128 minApprovalValidationPeriod,\n uint128 maxApprovalValidationPeriod\n ) external;\n\n function initializeMigrationPeriod(\n uint128 defaultMigrationPeriod,\n uint128 minMigrationPeriod,\n uint128 maxMigrationPeriod\n ) external;\n\n function initializeLockPeriod(\n uint128 defaultLockPeriod,\n uint128 minLockPeriod,\n uint128 maxLockPeriod\n ) external;\n\n function initializeRecoveryPeriod(\n uint128 defaultRecoveryPeriod,\n uint128 minRecoveryPeriod,\n uint128 maxRecoveryPeriod\n ) external;\n\n function initializeSecurityWindow(\n uint128 defaultSecurityWindow,\n uint128 minSecurityWindow,\n uint128 maxSecurityWindow\n ) external;\n\n function setAdditionSecurityPeriod(\n address wallet,\n uint128 additionSecurityPeriod\n ) external;\n\n function setRemovalSecurityPeriod(\n address wallet,\n uint128 removalSecurityPeriod\n ) external;\n\n function setSecurityWindow(address wallet, uint128 securityWindow) external;\n\n function setRecoveryPeriod(address wallet, uint128 recoveryPeriod) external;\n\n function setLockPeriod(address wallet, uint128 lockPeriod) external;\n\n function setApprovalValidationPeriod(\n address wallet,\n uint128 approvalValidationPeriod\n ) external;\n\n function setMigrationPeriod(\n address wallet,\n uint128 migrationPeriod\n ) external;\n\n function additionSecurityPeriodOf(\n address wallet\n ) external view returns (uint128);\n\n function removalSecurityPeriodOf(\n address wallet\n ) external view returns (uint128);\n\n function securityWindowOf(address wallet) external view returns (uint128);\n\n function recoveryPeriodOf(address wallet) external view returns (uint128);\n\n function lockPeriodOf(address wallet) external view returns (uint128);\n\n function migrationPeriodOf(address wallet) external view returns (uint128);\n\n function approvalValidationPeriodOf(\n address wallet\n ) external view returns (uint128);\n}\n" + }, + "contracts/infrastructure/RemoteStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IGuardianFacet} from \"../facets/interfaces/IGuardianFacet.sol\";\n\n/**\n * @title Remote Storage\n * @dev Remote storage allows you to associate addresses with an array of addresses on a standalone smart contract.\n * This could be useful when you don't want to use the local diamond storage for some purpose.\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\nabstract contract RemoteStorage {\n struct StorageConfig {\n address[] addresses;\n mapping(address => Info) info;\n }\n\n struct Info {\n bool exists;\n uint128 index;\n }\n\n mapping(address => StorageConfig) internal configs;\n\n event Added(address _address);\n event Removed(address _address);\n\n error RemoteStorage__CallerNotOwner();\n error RemoteStorage__CallerNotGuardianOrOwner();\n error RemoteStorage__AlreadyExists();\n error RemoteStorage__NotFound();\n error RemoteStorage__CallerNotGuardian();\n\n bytes4 constant IS_GUARDIAN_SELECTOR =\n bytes4(keccak256(\"isGuardian(address)\"));\n bytes4 constant GUARDIAN_COUNT = bytes4(keccak256(\"guardianCount()\"));\n\n /**\n * @notice Modifier to only allow the self to call. Reverts otherwise\n */\n modifier onlyWallet(address _wallet) {\n if (msg.sender != _wallet) revert RemoteStorage__CallerNotOwner();\n _;\n }\n\n /**\n * @notice Enfore the callet to be wallet of guardian of the wallet\n * @param _wallet Address of wallet\n */\n function enforceGuardianOrWallet(address _wallet) internal view {\n if (msg.sender == _wallet) return;\n address facetAddress = IDiamondLoupe(_wallet).facetAddress(\n IS_GUARDIAN_SELECTOR\n );\n if (facetAddress != address(0))\n if (IGuardianFacet(_wallet).isGuardian(msg.sender)) return;\n revert RemoteStorage__CallerNotGuardianOrOwner();\n }\n\n /**\n * @notice Enforce the caller to be wallet IF guardians doesn't exists and only guardian when guardians exists\n * @param _wallet Target wallet address to be handled by infrastructure contracts\n */\n function enforceWalletOrGuardianIfExists(address _wallet) internal view {\n address facetAddress;\n if (msg.sender == _wallet) {\n facetAddress = IDiamondLoupe(_wallet).facetAddress(GUARDIAN_COUNT);\n if (facetAddress == address(0)) return;\n uint256 guardianCount = IGuardianFacet(_wallet).guardianCount();\n if (guardianCount != 0) revert RemoteStorage__CallerNotGuardian();\n return;\n }\n facetAddress = IDiamondLoupe(_wallet).facetAddress(\n IS_GUARDIAN_SELECTOR\n );\n if (facetAddress != address(0))\n if (IGuardianFacet(_wallet).isGuardian(msg.sender)) return;\n\n revert RemoteStorage__CallerNotGuardianOrOwner();\n }\n\n /**\n * @notice Add address to storage and reverts if the address already exists.\n * This is an internal function callable from contracts that inherit this abstract contract\n * @param _wallet Address of wallet to add the address\n * @param _address Address to be added to wallet\n */\n function addAddress(address _wallet, address _address) internal {\n StorageConfig storage config = configs[_wallet];\n if (config.info[_address].exists) revert RemoteStorage__AlreadyExists();\n\n config.info[_address].exists = true;\n config.info[_address].index = uint128(config.addresses.length);\n config.addresses.push(_address);\n\n emit Added(_address);\n }\n\n /**\n * @notice Remove address from storage and reverts if the address already exists.\n * This is an internal function callable from contracts that inherit this abstract contract\n * @param _wallet Address of wallet to remove the address\n * @param _address Address to be removed from wallet\n */\n function removeAddress(address _wallet, address _address) internal {\n StorageConfig storage config = configs[_wallet];\n if (!config.info[_address].exists) revert RemoteStorage__NotFound();\n\n address lastAddress = config.addresses[config.addresses.length - 1];\n if (_address != lastAddress) {\n uint128 targetIndex = config.info[_address].index;\n config.addresses[targetIndex] = lastAddress;\n config.info[lastAddress].index = targetIndex;\n }\n config.addresses.pop();\n delete config.info[_address];\n\n emit Removed(_address);\n }\n\n /**\n * @notice Returns the address added to the given wallet\n * @param _wallet Address of wallet to fetch the addresses added to it\n * @return addresses List of addresses added to the wallet\n */\n function getAddresses(\n address _wallet\n ) internal view returns (address[] memory addresses) {\n StorageConfig storage config = configs[_wallet];\n addresses = new address[](config.addresses.length);\n uint addressesLen = config.addresses.length;\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns bool value checking if the address exists in the given wallet address\n * @param _wallet Wallet address to check\n * @param _address Address to fetch if the address if added to given wallet\n * @return exists_ Bool value showing if the address exists in wallet\n */\n function exists(\n address _wallet,\n address _address\n ) internal view returns (bool exists_) {\n exists_ = configs[_wallet].info[_address].exists;\n }\n\n /**\n * @notice Returns the number of addresses added to the wallet\n * @param _wallet Address of wallet to check\n * @return count_ Number of addresses added to wallet\n */\n function count(address _wallet) internal view returns (uint256 count_) {\n count_ = configs[_wallet].addresses.length;\n }\n}\n" + }, + "contracts/infrastructure/SecurityManager.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport {ISecurityManager} from \"./interfaces/ISecurityManager.sol\";\n\n/**\n * @title Security Manager\n * @dev Infrastructure contract to manage security parameters of users\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract SecurityManager is ISecurityManager, Ownable2Step {\n uint128 public minAdditionSecurityPeriod;\n uint128 public maxAdditionSecurityPeriod;\n uint128 private defaultAdditionSecurityPeriod;\n\n uint128 public minRemovalSecurityPeriod;\n uint128 public maxRemovalSecurityPeriod;\n uint128 private defaultRemovalSecurityPeriod;\n\n uint128 public minSecurityWindow;\n uint128 public maxSecurityWindow;\n uint128 private defaultSecurityWindow;\n\n uint128 public minRecoveryPeriod;\n uint128 public maxRecoveryPeriod;\n uint128 private defaultRecoveryPeriod;\n\n uint128 public minLockPeriod;\n uint128 public maxLockPeriod;\n uint128 private defaultLockPeriod;\n\n uint128 public minApprovalValidationPeriod;\n uint128 public maxApprovalValidationPeriod;\n uint128 private defaultApprovalValidationPeriod;\n\n uint128 public minMigrationPeriod;\n uint128 public maxMigrationPeriod;\n uint128 private defaultMigrationPeriod;\n\n bool public _isAdditionSecurityPeriodInitialized;\n bool public _isRemovalSecurityPeriodInitialized;\n bool public _isSecurityWindowInitialized;\n bool public _isRecoveryPeriodInitialized;\n bool public _isLockPeriodInitialized;\n bool public _isApprovalValidationPeriodInitialized;\n bool public _isMigrationPeriodInitialized;\n\n mapping(address => CustomSecurityConfig) securityConfigs;\n\n struct CustomSecurityConfig {\n uint128 additionSecurityPeriod;\n uint128 removalSecurityPeriod;\n uint128 securityWindow;\n uint128 recoveryPeriod;\n uint128 lockPeriod;\n uint128 approvalValidationPeriod;\n uint128 migrationPeriod;\n }\n\n /**\n * @notice Modifier to only allow wallet itself to make a call to wallet\n */\n modifier onlyWallet(address _wallet) {\n if (msg.sender != _wallet) revert SecurityManager__CallerNotWallet();\n _;\n }\n\n /**\n * @notice Modifier to revert if the variable is already initialized\n */\n modifier initializer(bool _isInitialized) {\n if (_isInitialized) revert SecurityManager__AlreadyIntialized();\n _;\n }\n\n /**\n * @notice Transfers the ownership of the contract to the given owner\n * @param _owner Address of owner who has access to initialize the default security variables for security manager\n */\n constructor(address _owner) {\n transferOwnership(_owner);\n _transferOwnership(_owner);\n }\n\n /**\n * @notice Sets the initial default/min/max addition security period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultAdditionSecurityPeriod Default Addition Security Period for all Barz contracts\n * @param _minAdditionSecurityPeriod Minimum Addition Security Period for all Barz contracts\n * @param _maxAdditionSecurityPeriod Maximum Addition Security Period for all Barz contracts\n */\n function initializeAdditionSecurityPeriod(\n uint128 _defaultAdditionSecurityPeriod,\n uint128 _minAdditionSecurityPeriod,\n uint128 _maxAdditionSecurityPeriod\n )\n external\n override\n onlyOwner\n initializer(_isAdditionSecurityPeriodInitialized)\n {\n _isAdditionSecurityPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultAdditionSecurityPeriod,\n _minAdditionSecurityPeriod,\n _maxAdditionSecurityPeriod\n );\n defaultAdditionSecurityPeriod = _defaultAdditionSecurityPeriod;\n minAdditionSecurityPeriod = _minAdditionSecurityPeriod;\n maxAdditionSecurityPeriod = _maxAdditionSecurityPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max removal security period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultRemovalSecurityPeriod Default Removal Security Period for all Barz contracts\n * @param _minRemovalSecurityPeriod Minimum Removal Security Period for all Barz contracts\n * @param _maxRemovalSecurityPeriod Maximum Removal Security Period for all Barz contracts\n */\n function initializeRemovalSecurityPeriod(\n uint128 _defaultRemovalSecurityPeriod,\n uint128 _minRemovalSecurityPeriod,\n uint128 _maxRemovalSecurityPeriod\n )\n external\n override\n onlyOwner\n initializer(_isRemovalSecurityPeriodInitialized)\n {\n _isRemovalSecurityPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultRemovalSecurityPeriod,\n _minRemovalSecurityPeriod,\n _maxRemovalSecurityPeriod\n );\n defaultRemovalSecurityPeriod = _defaultRemovalSecurityPeriod;\n minRemovalSecurityPeriod = _minRemovalSecurityPeriod;\n maxRemovalSecurityPeriod = _maxRemovalSecurityPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/maxd security window for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultSecurityWindow Default Security Window for all Barz contracts\n * @param _minSecurityWindow Minimum Security Window for all Barz contracts\n * @param _maxSecurityWindow Maximum Security Window for all Barz contracts\n */\n function initializeSecurityWindow(\n uint128 _defaultSecurityWindow,\n uint128 _minSecurityWindow,\n uint128 _maxSecurityWindow\n ) external override onlyOwner initializer(_isSecurityWindowInitialized) {\n _isSecurityWindowInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultSecurityWindow,\n _minSecurityWindow,\n _maxSecurityWindow\n );\n defaultSecurityWindow = _defaultSecurityWindow;\n minSecurityWindow = _minSecurityWindow;\n maxSecurityWindow = _maxSecurityWindow;\n }\n\n /**\n * @notice Sets the initial default/min/max recovery period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultRecoveryPeriod Default Recovery Period for all Barz contracts\n * @param _minRecoveryPeriod Minimum Recovery Period for all Barz contracts\n * @param _maxRecoveryPeriod Maximum Recovery Period for all Barz contracts\n */\n function initializeRecoveryPeriod(\n uint128 _defaultRecoveryPeriod,\n uint128 _minRecoveryPeriod,\n uint128 _maxRecoveryPeriod\n ) external override onlyOwner initializer(_isRecoveryPeriodInitialized) {\n _isRecoveryPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultRecoveryPeriod,\n _minRecoveryPeriod,\n _maxRecoveryPeriod\n );\n defaultRecoveryPeriod = _defaultRecoveryPeriod;\n minRecoveryPeriod = _minRecoveryPeriod;\n maxRecoveryPeriod = _maxRecoveryPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max lock period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultLockPeriod Default Lock Period for all Barz contracts\n * @param _minLockPeriod Minimum Lock Period for all Barz contracts\n * @param _maxLockPeriod Maximum Lock Period for all Barz contracts\n */\n function initializeLockPeriod(\n uint128 _defaultLockPeriod,\n uint128 _minLockPeriod,\n uint128 _maxLockPeriod\n ) external override onlyOwner initializer(_isLockPeriodInitialized) {\n _isLockPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultLockPeriod,\n _minLockPeriod,\n _maxLockPeriod\n );\n defaultLockPeriod = _defaultLockPeriod;\n minLockPeriod = _minLockPeriod;\n maxLockPeriod = _maxLockPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max approval validation period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultApprovalValidationPeriod Default Approval Validation Period for all Barz contracts\n * @param _minApprovalValidationPeriod Minimum Approval Validation Period for all Barz contracts\n * @param _maxApprovalValidationPeriod Maximum Approval Validation Period for all Barz contracts\n */\n function initializeApprovalValidationPeriod(\n uint128 _defaultApprovalValidationPeriod,\n uint128 _minApprovalValidationPeriod,\n uint128 _maxApprovalValidationPeriod\n )\n external\n override\n onlyOwner\n initializer(_isApprovalValidationPeriodInitialized)\n {\n _isApprovalValidationPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultApprovalValidationPeriod,\n _minApprovalValidationPeriod,\n _maxApprovalValidationPeriod\n );\n defaultApprovalValidationPeriod = _defaultApprovalValidationPeriod;\n minApprovalValidationPeriod = _minApprovalValidationPeriod;\n maxApprovalValidationPeriod = _maxApprovalValidationPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max migration period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultMigrationPeriod Default Migration Period for all Barz contracts\n * @param _minMigrationPeriod Minimum Migration Period for all Barz contracts\n * @param _maxMigrationPeriod Maximum Migration Period for all Barz contracts\n */\n function initializeMigrationPeriod(\n uint128 _defaultMigrationPeriod,\n uint128 _minMigrationPeriod,\n uint128 _maxMigrationPeriod\n ) external override onlyOwner initializer(_isMigrationPeriodInitialized) {\n _isMigrationPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultMigrationPeriod,\n _minMigrationPeriod,\n _maxMigrationPeriod\n );\n defaultMigrationPeriod = _defaultMigrationPeriod;\n minMigrationPeriod = _minMigrationPeriod;\n maxMigrationPeriod = _maxMigrationPeriod;\n }\n\n /**\n * @notice Wallet owner sets the addition security period for the wallet. Only the owner of wallet can call this function.\n * The addition security period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _additionSecurityPeriod Custom Addition Security Period for the wallet\n */\n function setAdditionSecurityPeriod(\n address _wallet,\n uint128 _additionSecurityPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _additionSecurityPeriod,\n minAdditionSecurityPeriod,\n maxAdditionSecurityPeriod\n );\n securityConfigs[_wallet]\n .additionSecurityPeriod = _additionSecurityPeriod;\n }\n\n /**\n * @notice Wallet owner sets the removal security period for the wallet. Only the owner of wallet can call this function.\n * The removal security period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _removalSecurityPeriod Custom Removal Security Period for the wallet\n */\n function setRemovalSecurityPeriod(\n address _wallet,\n uint128 _removalSecurityPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _removalSecurityPeriod,\n minRemovalSecurityPeriod,\n maxRemovalSecurityPeriod\n );\n securityConfigs[_wallet].removalSecurityPeriod = _removalSecurityPeriod;\n }\n\n /**\n * @notice Wallet owner sets the security window for the wallet. Only the owner of wallet can call this function.\n * The security window should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _securityWindow Custom Security Window for the wallet\n */\n function setSecurityWindow(\n address _wallet,\n uint128 _securityWindow\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _securityWindow,\n minSecurityWindow,\n maxSecurityWindow\n );\n securityConfigs[_wallet].securityWindow = _securityWindow;\n }\n\n /**\n * @notice Wallet owner sets the recovery period for the wallet. Only the owner of wallet can call this function.\n * The recovery period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _recoveryPeriod Custom recovery period for the wallet\n */\n function setRecoveryPeriod(\n address _wallet,\n uint128 _recoveryPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _recoveryPeriod,\n minRecoveryPeriod,\n maxRecoveryPeriod\n );\n securityConfigs[_wallet].recoveryPeriod = _recoveryPeriod;\n }\n\n /**\n * @notice Wallet owner sets the lock period for the wallet. Only the owner of wallet can call this function.\n * The lock period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _lockPeriod Custom Lock period for the wallet\n */\n function setLockPeriod(\n address _wallet,\n uint128 _lockPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(_lockPeriod, minLockPeriod, maxLockPeriod);\n securityConfigs[_wallet].lockPeriod = _lockPeriod;\n }\n\n /**\n * @notice Wallet owner sets the approval validation period for the wallet. Only the owner of wallet can call this function.\n * The approval validation period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _approvalValidationPeriod Custom approval validation period for the wallet\n */\n function setApprovalValidationPeriod(\n address _wallet,\n uint128 _approvalValidationPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _approvalValidationPeriod,\n minApprovalValidationPeriod,\n maxApprovalValidationPeriod\n );\n securityConfigs[_wallet]\n .approvalValidationPeriod = _approvalValidationPeriod;\n }\n\n /**\n * @notice Wallet owner sets the migration period for the wallet. Only the owner of wallet can call this function.\n * The migration period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _migrationPeriod Custom migration period for the wallet\n */\n\n function setMigrationPeriod(\n address _wallet,\n uint128 _migrationPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _migrationPeriod,\n minMigrationPeriod,\n maxMigrationPeriod\n );\n securityConfigs[_wallet].migrationPeriod = _migrationPeriod;\n }\n\n /**\n * @notice Returns the addition security period. Returns default value when custom addition security period is not set\n * @param _wallet Address of wallet\n * @return additionSecurityPeriod Addition Security Period of the given Barz account or wallet\n */\n function additionSecurityPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 additionSecurityPeriod)\n {\n additionSecurityPeriod = securityConfigs[_wallet]\n .additionSecurityPeriod;\n additionSecurityPeriod = (additionSecurityPeriod == 0)\n ? defaultAdditionSecurityPeriod\n : additionSecurityPeriod;\n }\n\n /**\n * @notice Returns the removal security period. Returns default value when custom removal security period is not set\n * @param _wallet Address of wallet\n * @return removalSecurityPeriod Removal Security Period of the given Barz account or wallet\n */\n function removalSecurityPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 removalSecurityPeriod)\n {\n removalSecurityPeriod = securityConfigs[_wallet].removalSecurityPeriod;\n removalSecurityPeriod = (removalSecurityPeriod == 0)\n ? defaultRemovalSecurityPeriod\n : removalSecurityPeriod;\n }\n\n /**\n * @notice Returns the security window. Returns default value when custom security window is not set\n * @param _wallet Address of wallet\n * @return securityWindow Security window of the given Barz account or wallet\n */\n function securityWindowOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 securityWindow)\n {\n securityWindow = securityConfigs[_wallet].securityWindow;\n securityWindow = (securityWindow == 0)\n ? defaultSecurityWindow\n : securityWindow;\n }\n\n /**\n * @notice Returns the recovery period. Returns default value when custom recovery period is not set\n * @param _wallet Address of wallet\n * @return recoveryPeriod Recovery Period of the given Barz account or wallet\n */\n function recoveryPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 recoveryPeriod)\n {\n recoveryPeriod = securityConfigs[_wallet].recoveryPeriod;\n recoveryPeriod = (recoveryPeriod == 0)\n ? defaultRecoveryPeriod\n : recoveryPeriod;\n }\n\n /**\n * @notice Returns the lock period. Returns default value when custom lock period is not set\n * @param _wallet Address of wallet\n * @return lockPeriod Lock Period of the given Barz account or wallet\n */\n function lockPeriodOf(\n address _wallet\n ) public view override onlyWallet(_wallet) returns (uint128 lockPeriod) {\n lockPeriod = securityConfigs[_wallet].lockPeriod;\n lockPeriod = (lockPeriod == 0) ? defaultLockPeriod : lockPeriod;\n }\n\n /**\n * @notice Returns the approval validation period. Returns default value when custom approval validation period is not set\n * @param _wallet Address of wallet\n * @return approvalValidationPeriod Approval Validation Period of the given Barz account or wallet\n */\n function approvalValidationPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityConfigs[_wallet]\n .approvalValidationPeriod;\n approvalValidationPeriod = (approvalValidationPeriod == 0)\n ? defaultApprovalValidationPeriod\n : approvalValidationPeriod;\n }\n\n /**\n * @notice Returns the migration period. Returns default value when custom migration period is not set\n * @param _wallet Address of wallet\n * @return migrationPeriod Migration Period of the given Barz account or wallet\n */\n function migrationPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 migrationPeriod)\n {\n migrationPeriod = securityConfigs[_wallet].migrationPeriod;\n migrationPeriod = (migrationPeriod == 0)\n ? defaultMigrationPeriod\n : migrationPeriod;\n }\n\n /**\n * @notice Validates if the period is smaller than the max period or bigger than the min period\n * @param _period Period to be checked\n * @param _minPeriod Minimum period\n * @param _maxPeriod Maximum period\n */\n function _validatePeriodBoundaries(\n uint128 _period,\n uint128 _minPeriod,\n uint128 _maxPeriod\n ) internal pure {\n if (_period >= _maxPeriod || _period <= _minPeriod)\n revert SecurityManager__OutOfBoundary();\n }\n}\n" + }, + "contracts/infrastructure/WhitelistStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {RemoteStorage} from \"./RemoteStorage.sol\";\n\n/**\n * @title Whitelist storage\n * @dev Maps addresses to the corresponsing array of whitelisted addresses for each of them.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract WhitelistStorage is RemoteStorage {\n /**\n * @dev Add the address to the whitelist storage\n * @param _wallet User wallet\n * @param _address Address to be whitelisted\n */\n function whitelistAddress(address _wallet, address _address) external {\n enforceWalletOrGuardianIfExists(_wallet);\n addAddress(_wallet, _address);\n }\n\n /**\n * @dev Removes the address from the whitelist storage\n * @param _wallet User wallet\n * @param _address Address to be removed from the whitelist\n */\n function blacklistAddress(address _wallet, address _address) external {\n enforceGuardianOrWallet(_wallet);\n removeAddress(_wallet, _address);\n }\n\n /**\n * @dev Returns whether the address exists in the whitelist storage, associated with the wallet\n * @param _wallet User wallet\n * @param _address Address to be whitelisted\n */\n function isWhitelisted(\n address _wallet,\n address _address\n ) external view returns (bool) {\n return exists(_wallet, _address);\n }\n\n /**\n * @dev Returns all whitelisted addresses associated with the wallet\n * @param _wallet User wallet\n */\n function getWhitelistedAddresses(\n address _wallet\n ) external view returns (address[] memory) {\n return getAddresses(_wallet);\n }\n}\n" + }, + "contracts/interfaces/ERC/IERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\n\npragma solidity 0.8.21;\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155Receiver {\n /**\n * @dev Handles the receipt of a single ERC1155 token type. This function is\n * called at the end of a `safeTransferFrom` after the balance has been updated.\n *\n * NOTE: To accept the transfer, this must return\n * `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n * (i.e. 0xf23a6e61, or its own function selector).\n *\n * @param operator The address which initiated the transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param id The ID of the token being transferred\n * @param value The amount of tokens being transferred\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n ) external returns (bytes4);\n\n /**\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\n * is called at the end of a `safeBatchTransferFrom` after the balances have\n * been updated.\n *\n * NOTE: To accept the transfer(s), this must return\n * `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n * (i.e. 0xbc197c81, or its own function selector).\n *\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "contracts/interfaces/ERC/IERC1271.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\ninterface IERC1271 {\n function isValidSignature(\n bytes32 hash,\n bytes memory signature\n ) external view returns (bytes4);\n}\n" + }, + "contracts/interfaces/ERC/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\ninterface IERC165 {\n /// @notice Query if a contract implements an interface\n /// @param interfaceId The interface identifier, as specified in ERC-165\n /// @dev Interface identification is specified in ERC-165. This function\n /// uses less than 30,000 gas.\n /// @return `true` if the contract implements `interfaceID` and\n /// `interfaceID` is not 0xffffffff, `false` otherwise\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/IERC173.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\n/// @title ERC-173 Contract Ownership Standard\n/// Note: the ERC-165 identifier for this interface is 0x7f5828d0\n/* is ERC165 */\ninterface IERC173 {\n /// @dev This emits when ownership of a contract changes.\n event OwnershipTransferred(\n address indexed previousOwner,\n address indexed newOwner\n );\n\n /// @notice Get the address of the owner\n /// @return owner_ The address of the owner.\n function owner() external view returns (address owner_);\n\n /// @notice Set the address of the new owner of the contract\n /// @dev Set _newOwner to address(0) to renounce any ownership.\n /// @param _newOwner The address of the new owner of the contract\n function transferOwnership(address _newOwner) external;\n}\n" + }, + "contracts/interfaces/ERC/IERC677Receiver.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\ninterface IERC677Receiver {\n function onTokenTransfer(\n address sender,\n uint value,\n bytes calldata data\n ) external pure returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155 is IERC165 {\n /**\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n */\n event TransferSingle(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256 id,\n uint256 value\n );\n\n /**\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n * transfers.\n */\n event TransferBatch(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\n\n /**\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n * `approved`.\n */\n event ApprovalForAll(\n address indexed account,\n address indexed operator,\n bool approved\n );\n\n /**\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n *\n * If an {URI} event was emitted for `id`, the standard\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n * returned by {IERC1155MetadataURI-uri}.\n */\n event URI(string value, uint256 indexed id);\n\n /**\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(\n address account,\n uint256 id\n ) external view returns (uint256);\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] calldata accounts,\n uint256[] calldata ids\n ) external view returns (uint256[] memory);\n\n /**\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n *\n * Emits an {ApprovalForAll} event.\n *\n * Requirements:\n *\n * - `operator` cannot be the caller.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n *\n * See {setApprovalForAll}.\n */\n function isApprovedForAll(\n address account,\n address operator\n ) external view returns (bool);\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes calldata data\n ) external;\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(\n address indexed owner,\n address indexed spender,\n uint256 value\n );\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` 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 amount) 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(\n address owner,\n address spender\n ) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the 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 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` 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(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(\n address spender,\n uint256 addedValue\n ) external returns (bool);\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(\n address spender,\n uint256 subtractedValue\n ) external returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(\n address indexed from,\n address indexed to,\n uint256 indexed tokenId\n );\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(\n address indexed owner,\n address indexed approved,\n uint256 indexed tokenId\n );\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(\n address indexed owner,\n address indexed operator,\n bool approved\n );\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(\n uint256 tokenId\n ) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(\n address owner,\n address operator\n ) external view returns (bool);\n}\n" + }, + "contracts/interfaces/IBarz.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Barz Interface\n * @dev Interface of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IBarz {\n error Barz__InitializationFailure();\n}\n" + }, + "contracts/interfaces/IBarzFactory.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Barz} from \"../Barz.sol\";\n\n/**\n * @title Barz Factory Interface\n * @dev Interface of contract to easily deploy Barz to a pre-computed address with a single call\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IBarzFactory {\n event BarzDeployed(address);\n\n function createAccount(\n address verificationFacet,\n bytes calldata owner,\n uint256 salt\n ) external returns (Barz);\n\n function getAddress(\n address verificationFacet,\n bytes calldata owner,\n uint256 salt\n ) external view returns (address);\n\n function getBytecode(\n address accountFacet,\n address verificationFacet,\n address entryPoint,\n address facetRegistry,\n address defaultFallback,\n bytes memory ownerPublicKey\n ) external pure returns (bytes memory);\n\n function getCreationCode() external pure returns (bytes memory);\n}\n" + }, + "contracts/libraries/DefaultLibDiamond.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\n\nerror InitializationFunctionReverted(\n address _initializationContractAddress,\n bytes _calldata\n);\n\nlibrary DefaultLibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION =\n keccak256(\"trustwallet.barz.diamond.storage\");\n\n struct FacetAddressAndPosition {\n address facetAddress;\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\n }\n\n struct FacetFunctionSelectors {\n bytes4[] functionSelectors;\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\n }\n\n struct DiamondStorage {\n // maps function selector to the facet address and\n // the position of the selector in the facetFunctionSelectors.selectors array\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\n // maps facet addresses to function selectors\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\n // facet addresses\n address[] facetAddresses;\n // Used to query if a contract implements an interface.\n // Used to implement ERC-165.\n mapping(bytes4 => bool) supportedInterfaces;\n }\n\n function diamondStorage()\n internal\n pure\n returns (DiamondStorage storage ds)\n {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n event DiamondCut(\n IDiamondCut.FacetCut[] _diamondCut,\n address _init,\n bytes _calldata\n );\n\n // Internal function version of diamondCut\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n for (\n uint256 facetIndex;\n facetIndex < _diamondCut.length;\n facetIndex++\n ) {\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\n if (action == IDiamondCut.FacetCutAction.Add) {\n addFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\n replaceFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\n removeFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else {\n revert(\"LibDiamondCut: Incorrect FacetCutAction\");\n }\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Add facet can't be address(0)\"\n );\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n require(\n oldFacetAddress == address(0),\n \"LibDiamondCut: Can't add function that already exists\"\n );\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function replaceFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Replace facet can't be address(0)\"\n );\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n require(\n oldFacetAddress != _facetAddress,\n \"LibDiamondCut: Can't replace function with same facet\"\n );\n removeFunction(ds, oldFacetAddress, selector);\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function removeFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n // if function does not exist then do nothing and return\n require(\n _facetAddress == address(0),\n \"LibDiamondCut: Remove facet address must be address(0)\"\n );\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n removeFunction(ds, oldFacetAddress, selector);\n }\n }\n\n function addFacet(\n DiamondStorage storage ds,\n address _facetAddress\n ) internal {\n enforceHasContractCode(\n _facetAddress,\n \"LibDiamondCut: New facet has no code\"\n );\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds\n .facetAddresses\n .length;\n ds.facetAddresses.push(_facetAddress);\n }\n\n function addFunction(\n DiamondStorage storage ds,\n bytes4 _selector,\n uint96 _selectorPosition,\n address _facetAddress\n ) internal {\n ds\n .selectorToFacetAndPosition[_selector]\n .functionSelectorPosition = _selectorPosition;\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(\n _selector\n );\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\n }\n\n function removeFunction(\n DiamondStorage storage ds,\n address _facetAddress,\n bytes4 _selector\n ) internal {\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Can't remove function that doesn't exist\"\n );\n // an immutable function is a function defined directly in a diamond\n require(\n _facetAddress != address(this),\n \"LibDiamondCut: Can't remove immutable function\"\n );\n // replace selector with last selector, then delete last selector\n uint256 selectorPosition = ds\n .selectorToFacetAndPosition[_selector]\n .functionSelectorPosition;\n uint256 lastSelectorPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors\n .length - 1;\n // if not the same then replace _selector with lastSelector\n if (selectorPosition != lastSelectorPosition) {\n bytes4 lastSelector = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors[lastSelectorPosition];\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[\n selectorPosition\n ] = lastSelector;\n ds\n .selectorToFacetAndPosition[lastSelector]\n .functionSelectorPosition = uint96(selectorPosition);\n }\n // delete the last selector\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\n delete ds.selectorToFacetAndPosition[_selector];\n\n // if no more selectors for facet address then delete the facet address\n if (lastSelectorPosition == 0) {\n // replace facet address with last facet address and delete last facet address\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\n uint256 facetAddressPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .facetAddressPosition;\n if (facetAddressPosition != lastFacetAddressPosition) {\n address lastFacetAddress = ds.facetAddresses[\n lastFacetAddressPosition\n ];\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\n ds\n .facetFunctionSelectors[lastFacetAddress]\n .facetAddressPosition = facetAddressPosition;\n }\n ds.facetAddresses.pop();\n delete ds\n .facetFunctionSelectors[_facetAddress]\n .facetAddressPosition;\n }\n }\n\n function initializeDiamondCut(\n address _init,\n bytes memory _calldata\n ) internal {\n if (_init == address(0)) {\n return;\n }\n enforceHasContractCode(\n _init,\n \"LibDiamondCut: _init address has no code\"\n );\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length > 0) {\n // bubble up error\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(error)\n revert(add(32, error), returndata_size)\n }\n } else {\n revert InitializationFunctionReverted(_init, _calldata);\n }\n }\n }\n\n function enforceHasContractCode(\n address _contract,\n string memory _errorMessage\n ) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize > 0, _errorMessage);\n }\n}\n" + }, + "contracts/libraries/LibAppStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SafeCast} from \"@openzeppelin/contracts/utils/math/SafeCast.sol\";\nimport {IEntryPoint} from \"../aa-4337/interfaces/IEntryPoint.sol\";\nimport {IFacetRegistry} from \"../infrastructure/interfaces/IFacetRegistry.sol\";\n\n/*\n * @title App Storage\n * @dev App storage for Barz contract to prevent storage collision\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\n\nstruct Lock {\n uint64 release;\n bytes4 locker;\n}\n\nstruct InitializersStorage {\n // NOTE: initialized is a variable to make sure the initialization is only done once.\n uint8 signerInitialized;\n uint8 accountInitialized;\n uint8 restrictionsInitialized;\n}\n\nstruct AppStorage {\n mapping(uint256 => InitializersStorage) initStorage;\n uint8 signerMigration;\n bytes4 validateOwnerSignatureSelector;\n IEntryPoint entryPoint;\n IFacetRegistry facetRegistry;\n mapping(uint256 => Lock) locks;\n}\n\nlibrary LibAppStorage {\n error LibAppStorage__AccountAlreadyUninitialized();\n error LibAppStorage__AccountMustBeUninitialized();\n error LibAppStorage__SignerAlreadyUninitialized();\n error LibAppStorage__SignerMustBeUninitialized();\n\n function appStorage() internal pure returns (AppStorage storage ds) {\n assembly {\n ds.slot := 0\n }\n }\n\n function setSignerUninitialized() internal {\n AppStorage storage s = appStorage();\n if (1 != s.initStorage[0].signerInitialized) {\n revert LibAppStorage__SignerAlreadyUninitialized();\n }\n s.initStorage[0].signerInitialized = 0;\n }\n\n function getValidateOwnerSignatureSelector()\n internal\n view\n returns (bytes4 selector)\n {\n selector = appStorage().validateOwnerSignatureSelector;\n }\n\n function setValidateOwnerSignatureSelector(\n bytes4 _validateOwnerSignatureSelector\n ) internal {\n appStorage()\n .validateOwnerSignatureSelector = _validateOwnerSignatureSelector;\n }\n\n function enforceSignerInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].signerInitialized) {\n revert LibAppStorage__SignerMustBeUninitialized();\n }\n s.initStorage[0].signerInitialized = 1;\n }\n\n function enforceAccountInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].accountInitialized) {\n revert LibAppStorage__AccountMustBeUninitialized();\n }\n s.initStorage[0].accountInitialized = 1;\n }\n\n function initiateSignerMigration() internal {\n appStorage().signerMigration = 1;\n }\n\n function enforceSignerMigration() internal view {\n if (1 != appStorage().signerMigration) {\n revert LibAppStorage__AccountMustBeUninitialized();\n }\n }\n\n function finalizeSignerMigration() internal {\n appStorage().signerMigration = 0;\n }\n\n function setLock(uint256 _releaseAfter, bytes4 _locker) internal {\n appStorage().locks[0] = Lock(SafeCast.toUint64(_releaseAfter), _locker);\n }\n\n function enforceRestrictionsInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].restrictionsInitialized)\n revert LibAppStorage__SignerMustBeUninitialized();\n s.initStorage[0].restrictionsInitialized = 1;\n }\n\n function setRestrictionsUninitialized() internal {\n AppStorage storage s = appStorage();\n if (1 != s.initStorage[0].restrictionsInitialized)\n revert LibAppStorage__AccountAlreadyUninitialized();\n s.initStorage[0].restrictionsInitialized = 0;\n }\n}\n\ncontract BarzStorage {\n AppStorage internal s;\n modifier onlyWhenUnlocked() {\n require(\n uint64(block.timestamp) >= s.locks[0].release,\n \"Account Locked\"\n );\n _;\n }\n modifier onlyWhenLocked() {\n require(\n uint64(block.timestamp) < s.locks[0].release,\n \"Account Unlocked\"\n );\n _;\n }\n}\n" + }, + "contracts/libraries/LibDiamond.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\n\nerror InitializationFunctionReverted(\n address _initializationContractAddress,\n bytes _calldata\n);\n\nlibrary LibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION =\n keccak256(\"trustwallet.barz.diamond.storage\");\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\n bytes4(keccak256(\"verifyRestrictions(address,address,uint256,bytes)\"));\n struct DiamondStorage {\n // maps function selectors to the facets that execute the functions.\n // and maps the selectors to their position in the selectorSlots array.\n // func selector => address facet, selector position\n mapping(bytes4 => bytes32) facets;\n // array of slots of function selectors.\n // each slot holds 8 function selectors.\n mapping(uint256 => bytes32) selectorSlots;\n // The number of function selectors in selectorSlots\n uint16 selectorCount;\n // Used to query if a contract implements an interface.\n // Used to implement ERC-165.\n mapping(bytes4 => bool) supportedInterfaces;\n // Default Fallback Handler of the barz.\n IDiamondLoupe defaultFallbackHandler;\n }\n\n function diamondStorage()\n internal\n pure\n returns (DiamondStorage storage ds)\n {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n function enforceIsSelf() internal view {\n require(msg.sender == address(this), \"LibDiamond: Caller not self\");\n }\n\n event DiamondCut(\n IDiamondCut.FacetCut[] _diamondCut,\n address _init,\n bytes _calldata\n );\n\n bytes32 constant CLEAR_ADDRESS_MASK =\n bytes32(uint256(0xffffffffffffffffffffffff));\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\n\n // Internal function version of diamondCut\n // This code is almost the same as the external diamondCut,\n // except it is using 'Facet[] memory _diamondCut' instead of\n // 'Facet[] calldata _diamondCut'.\n // The code is duplicated to prevent copying calldata to memory which\n // causes an error for a two dimensional array.\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n DiamondStorage storage ds = diamondStorage();\n uint256 originalSelectorCount = ds.selectorCount;\n uint256 selectorCount = originalSelectorCount;\n bytes32 selectorSlot;\n // Check if last selector slot is not full\n // \"selectorCount & 7\" is a gas efficient modulo by eight \"selectorCount % 8\"\n if (selectorCount & 7 > 0) {\n // get last selectorSlot\n // \"selectorSlot >> 3\" is a gas efficient division by 8 \"selectorSlot / 8\"\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\n }\n // loop through diamond cut\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\n selectorCount,\n selectorSlot,\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].action,\n _diamondCut[facetIndex].functionSelectors\n );\n\n unchecked {\n facetIndex++;\n }\n }\n if (selectorCount != originalSelectorCount) {\n ds.selectorCount = uint16(selectorCount);\n }\n // If last selector slot is not full\n // \"selectorCount & 7\" is a gas efficient modulo by eight \"selectorCount % 8\"\n if (selectorCount & 7 > 0) {\n // \"selectorSlot >> 3\" is a gas efficient division by 8 \"selectorSlot / 8\"\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addReplaceRemoveFacetSelectors(\n uint256 _selectorCount,\n bytes32 _selectorSlot,\n address _newFacetAddress,\n IDiamondCut.FacetCutAction _action,\n bytes4[] memory _selectors\n ) internal returns (uint256, bytes32) {\n DiamondStorage storage ds = diamondStorage();\n require(\n _selectors.length > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n if (_action == IDiamondCut.FacetCutAction.Add) {\n enforceHasContractCode(\n _newFacetAddress,\n \"LibDiamondCut: Add facet has no code\"\n );\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n require(\n address(bytes20(oldFacet)) == address(0),\n \"LibDiamondCut: Can't add function that already exists\"\n );\n // add facet for selector\n ds.facets[selector] =\n bytes20(_newFacetAddress) |\n bytes32(_selectorCount);\n // \"_selectorCount & 7\" is a gas efficient modulo by eight \"_selectorCount % 8\"\n // \" << 5 is the same as multiplying by 32 ( * 32)\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\n // clear selector position in slot and add selector\n _selectorSlot =\n (_selectorSlot &\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\n (bytes32(selector) >> selectorInSlotPosition);\n // if slot is full then write it to storage\n if (selectorInSlotPosition == 224) {\n // \"_selectorSlot >> 3\" is a gas efficient division by 8 \"_selectorSlot / 8\"\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\n _selectorSlot = 0;\n }\n _selectorCount++;\n\n unchecked {\n selectorIndex++;\n }\n }\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\n enforceHasContractCode(\n _newFacetAddress,\n \"LibDiamondCut: Replace facet has no code\"\n );\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n address oldFacetAddress = address(bytes20(oldFacet));\n // only useful if immutable functions exist\n require(\n oldFacetAddress != address(this),\n \"LibDiamondCut: Can't replace immutable function\"\n );\n require(\n oldFacetAddress != _newFacetAddress,\n \"LibDiamondCut: Can't replace function with same function\"\n );\n require(\n oldFacetAddress != address(0),\n \"LibDiamondCut: Can't replace function that doesn't exist\"\n );\n // replace old facet address\n ds.facets[selector] =\n (oldFacet & CLEAR_ADDRESS_MASK) |\n bytes20(_newFacetAddress);\n\n unchecked {\n selectorIndex++;\n }\n }\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\n require(\n _newFacetAddress == address(0),\n \"LibDiamondCut: Remove facet address must be address(0)\"\n );\n // \"_selectorCount >> 3\" is a gas efficient division by 8 \"_selectorCount / 8\"\n uint256 selectorSlotCount = _selectorCount >> 3;\n // \"_selectorCount & 7\" is a gas efficient modulo by eight \"_selectorCount % 8\"\n uint256 selectorInSlotIndex = _selectorCount & 7;\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n if (_selectorSlot == 0) {\n // get last selectorSlot\n selectorSlotCount--;\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\n selectorInSlotIndex = 7;\n } else {\n selectorInSlotIndex--;\n }\n bytes4 lastSelector;\n uint256 oldSelectorsSlotCount;\n uint256 oldSelectorInSlotPosition;\n // adding a block here prevents stack too deep error\n {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n require(\n address(bytes20(oldFacet)) != address(0),\n \"LibDiamondCut: Can't remove function that doesn't exist\"\n );\n // only useful if immutable functions exist\n require(\n address(bytes20(oldFacet)) != address(this),\n \"LibDiamondCut: Can't remove immutable function\"\n );\n // replace selector with last selector in ds.facets\n // gets the last selector\n // \" << 5 is the same as multiplying by 32 ( * 32)\n lastSelector = bytes4(\n _selectorSlot << (selectorInSlotIndex << 5)\n );\n if (lastSelector != selector) {\n // update last selector slot position info\n ds.facets[lastSelector] =\n (oldFacet & CLEAR_ADDRESS_MASK) |\n bytes20(ds.facets[lastSelector]);\n }\n delete ds.facets[selector];\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\n // \"oldSelectorCount >> 3\" is a gas efficient division by 8 \"oldSelectorCount / 8\"\n oldSelectorsSlotCount = oldSelectorCount >> 3;\n // \"oldSelectorCount & 7\" is a gas efficient modulo by eight \"oldSelectorCount % 8\"\n // \" << 5 is the same as multiplying by 32 ( * 32)\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\n }\n if (oldSelectorsSlotCount != selectorSlotCount) {\n bytes32 oldSelectorSlot = ds.selectorSlots[\n oldSelectorsSlotCount\n ];\n // clears the selector we are deleting and puts the last selector in its place.\n oldSelectorSlot =\n (oldSelectorSlot &\n ~(CLEAR_SELECTOR_MASK >>\n oldSelectorInSlotPosition)) |\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\n // update storage with the modified slot\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\n } else {\n // clears the selector we are deleting and puts the last selector in its place.\n _selectorSlot =\n (_selectorSlot &\n ~(CLEAR_SELECTOR_MASK >>\n oldSelectorInSlotPosition)) |\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\n }\n if (selectorInSlotIndex == 0) {\n delete ds.selectorSlots[selectorSlotCount];\n _selectorSlot = 0;\n }\n\n unchecked {\n selectorIndex++;\n }\n }\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\n } else {\n revert(\"LibDiamondCut: Incorrect FacetCutAction\");\n }\n return (_selectorCount, _selectorSlot);\n }\n\n function initializeDiamondCut(\n address _init,\n bytes memory _calldata\n ) internal {\n if (_init == address(0)) {\n return;\n }\n enforceHasContractCode(\n _init,\n \"LibDiamondCut: _init address has no code\"\n );\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length > 0) {\n // bubble up error\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(error)\n revert(add(32, error), returndata_size)\n }\n } else {\n revert InitializationFunctionReverted(_init, _calldata);\n }\n }\n }\n\n function enforceHasContractCode(\n address _contract,\n string memory _errorMessage\n ) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize > 0, _errorMessage);\n }\n\n function restrictionsFacet() internal view returns (address facetAddress_) {\n facetAddress_ = address(\n bytes20(\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\n )\n );\n }\n}\n" + }, + "contracts/libraries/LibFacetStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Storage\n * @dev Storage contract to store each facets variables with diamond storage\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\n\nstruct Secp256k1VerificationStorage {\n address signer;\n}\n\nstruct Secp256r1VerificationStorage {\n uint256[2] q;\n}\n\nstruct GuardianStorage {\n mapping(bytes32 => uint256) pending;\n mapping(uint8 => StorageConfig) configs;\n}\n\nstruct Info {\n bool exists;\n uint128 index;\n}\n\nstruct StorageConfig {\n address[] addresses;\n mapping(address => Info) info;\n}\n\nstruct RecoveryConfig {\n bytes recoveryPublicKey;\n uint64 executeAfter;\n}\n\nstruct ApprovalConfig {\n bool isApproved;\n uint64 validUntil;\n}\n\nstruct RecoveryApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isNewOwnerApproved;\n}\n\nstruct RecoveryStorage {\n mapping(uint8 => RecoveryConfig) recoveryConfigs;\n mapping(uint8 => RecoveryApprovalConfig) recoveryApprovalConfigs;\n uint128 nonce;\n}\n\nstruct RestrictionsStorage {\n address[] restrictions;\n mapping(address => bool) exists;\n}\n\nstruct SignatureMigrationConfig {\n bytes migrationPublicKey;\n address migrationVerificationFacet;\n bytes4[] migrationSelectors;\n uint64 migrateAfter;\n}\n\nstruct SignatureMigrationApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isMigrationApproved;\n}\n\nstruct SignatureMigrationStorage {\n mapping(uint8 => SignatureMigrationConfig) migrationConfigs;\n mapping(uint8 => SignatureMigrationApprovalConfig) migrationApprovalConfigs;\n uint128 nonce;\n}\n\nstruct DiamondCutApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isDiamondCutApproved;\n}\n\nstruct DiamondCutStorage {\n mapping(uint8 => DiamondCutApprovalConfig) diamondCutApprovalConfigs;\n uint128 nonce;\n}\n\nstruct LockStorage {\n uint128 nonce;\n}\n\nlibrary LibFacetStorage {\n bytes32 constant K1_STORAGE_POSITION =\n keccak256(\n \"v0.trustwallet.diamond.storage.Secp256k1VerificationStorage\"\n );\n bytes32 constant R1_STORAGE_POSITION =\n keccak256(\n \"v0.trustwallet.diamond.storage.Secp256r1VerificationStorage\"\n );\n bytes32 constant GUARDIAN_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.GuardianStorage\");\n bytes32 constant RECOVERY_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.RecoveryStorage\");\n bytes32 constant RESTRICTION_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.RestrictionsStorage\");\n bytes32 constant MIGRATION_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.SignatureMigrationStorage\");\n bytes32 constant DIAMONDCUT_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.DiamondCutStorage\");\n bytes32 constant LOCK_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.LockStorage\");\n\n function k1Storage()\n internal\n pure\n returns (Secp256k1VerificationStorage storage ds)\n {\n bytes32 storagePosition = K1_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function r1Storage()\n internal\n pure\n returns (Secp256r1VerificationStorage storage ds)\n {\n bytes32 storagePosition = R1_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function guardianStorage()\n internal\n pure\n returns (GuardianStorage storage ds)\n {\n bytes32 storagePosition = GUARDIAN_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function recoveryStorage()\n internal\n pure\n returns (RecoveryStorage storage ds)\n {\n bytes32 storagePosition = RECOVERY_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function restrictionsStorage()\n internal\n pure\n returns (RestrictionsStorage storage ds)\n {\n bytes32 storagePosition = RESTRICTION_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function migrationStorage()\n internal\n pure\n returns (SignatureMigrationStorage storage ds)\n {\n bytes32 storagePosition = MIGRATION_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function diamondCutStorage()\n internal\n pure\n returns (DiamondCutStorage storage ds)\n {\n bytes32 storagePosition = DIAMONDCUT_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function lockStorage() internal pure returns (LockStorage storage ds) {\n bytes32 storagePosition = LOCK_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n}\n" + }, + "contracts/libraries/LibGuardian.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibFacetStorage, StorageConfig} from \"./LibFacetStorage.sol\";\n\n/**\n * @title LibGuardian\n * @dev Internal Library to provide utility feature for Guardians stored in Guardian Facet Storage\n * @author David Yongjun Kim (@Powerstream3604)\n */\nlibrary LibGuardian {\n function majorityOfGuardians()\n internal\n view\n returns (uint256 guardianNumber)\n {\n uint256 guardianLength = guardianCount();\n guardianNumber = (guardianLength == 0) ? 0 : guardianLength / 2 + 1;\n }\n\n function isGuardian(address _guardian) internal view returns (bool) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n return config.info[_guardian].exists;\n }\n\n function guardianCount() internal view returns (uint256) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n return config.addresses.length;\n }\n\n function getGuardians() internal view returns (address[] memory) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n address[] memory addresses = new address[](config.addresses.length);\n uint256 addressesLen = config.addresses.length;\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n return addresses;\n }\n}\n" + }, + "contracts/libraries/LibLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {LibDiamond} from \"./LibDiamond.sol\";\n\n/**\n * @title LibLoupe\n * @dev Internal Library to provide utility feature for reading the state of diamond facets\n * Originally from Diamond's implementation of Mudgen(author of EIP-2535)\n */\nlibrary LibLoupe {\n /// @notice Gets all facets and their selectors.\n /// @return facets_ Facet\n function facets()\n internal\n view\n returns (IDiamondLoupe.Facet[] memory facets_)\n {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facets_ = new IDiamondLoupe.Facet[](ds.selectorCount);\n uint16[] memory numFacetSelectors = new uint16[](ds.selectorCount);\n uint256 numFacets;\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facetAddress_ = address(bytes20(ds.facets[selector]));\n bool continueLoop;\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n if (facets_[facetIndex].facetAddress == facetAddress_) {\n facets_[facetIndex].functionSelectors[\n numFacetSelectors[facetIndex]\n ] = selector;\n // probably will never have more than 256 functions from one facet contract\n require(numFacetSelectors[facetIndex] < 255);\n numFacetSelectors[facetIndex]++;\n continueLoop = true;\n break;\n }\n }\n if (continueLoop) {\n continue;\n }\n facets_[numFacets].facetAddress = facetAddress_;\n facets_[numFacets].functionSelectors = new bytes4[](\n ds.selectorCount\n );\n facets_[numFacets].functionSelectors[0] = selector;\n numFacetSelectors[numFacets] = 1;\n numFacets++;\n }\n }\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n uint256 numSelectors = numFacetSelectors[facetIndex];\n bytes4[] memory selectors = facets_[facetIndex].functionSelectors;\n // setting the number of selectors\n assembly {\n mstore(selectors, numSelectors)\n }\n }\n // setting the number of facets\n assembly {\n mstore(facets_, numFacets)\n }\n }\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n /// @return _facetFunctionSelectors The selectors associated with a facet address.\n function facetFunctionSelectors(\n address _facet\n ) internal view returns (bytes4[] memory _facetFunctionSelectors) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n uint256 numSelectors;\n _facetFunctionSelectors = new bytes4[](ds.selectorCount);\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facet = address(bytes20(ds.facets[selector]));\n if (_facet == facet) {\n _facetFunctionSelectors[numSelectors] = selector;\n numSelectors++;\n }\n }\n }\n // Set the number of selectors in the array\n assembly {\n mstore(_facetFunctionSelectors, numSelectors)\n }\n }\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses()\n internal\n view\n returns (address[] memory facetAddresses_)\n {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facetAddresses_ = new address[](ds.selectorCount);\n uint256 numFacets;\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facetAddress_ = address(bytes20(ds.facets[selector]));\n bool continueLoop;\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n if (facetAddress_ == facetAddresses_[facetIndex]) {\n continueLoop = true;\n break;\n }\n }\n if (continueLoop) {\n continue;\n }\n facetAddresses_[numFacets] = facetAddress_;\n numFacets++;\n }\n }\n // Set the number of facet addresses in the array\n assembly {\n mstore(facetAddresses_, numFacets)\n }\n }\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(\n bytes4 _functionSelector\n ) internal view returns (address facetAddress_) {\n facetAddress_ = address(\n bytes20(LibDiamond.diamondStorage().facets[_functionSelector])\n );\n }\n}\n" + }, + "contracts/libraries/LibMultiSigStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Multi-sig Storage\n * @dev Storage contract for storing Multi-sig Facet variables in diamond storage pattern\n * @author David Yongjun Kim (@Powerstream3604)\n */\n\nstruct MultiSigStorage {\n mapping(address => address) owners;\n mapping(uint256 => mapping(address => mapping(bytes32 => uint256))) approvedHashes;\n uint256 ownerCount;\n uint256 threshold;\n uint256 counter;\n}\n\nlibrary LibMultiSigStorage {\n function multisigStorage()\n internal\n pure\n returns (MultiSigStorage storage ds)\n {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.MultiSigStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n}\n" + }, + "contracts/libraries/LibRecoverSpender.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title RecoverSpender\n * @dev Library to determine the action and spender of calldata\n * @author Ruslan Serebriakov (@rsrbk)\n */\nlibrary LibRecoverSpender {\n // ERC20, ERC721 & ERC1155 transfers & approvals\n bytes4 private constant ERC20_TRANSFER =\n bytes4(keccak256(\"transfer(address,uint256)\"));\n bytes4 private constant ERC20_APPROVE =\n bytes4(keccak256(\"approve(address,uint256)\"));\n bytes4 private constant ERC20_INCREASE_ALLOWANCE =\n bytes4(keccak256(\"increaseAllowance(address,uint256)\"));\n bytes4 private constant ERC20_DECREASE_ALLOWANCE =\n bytes4(keccak256(\"decreaseAllowance(address,uint256)\"));\n bytes4 private constant ERC721_SET_APPROVAL_FOR_ALL =\n bytes4(keccak256(\"setApprovalForAll(address,bool)\"));\n bytes4 private constant ERC721_TRANSFER_FROM =\n bytes4(keccak256(\"transferFrom(address,address,uint256)\"));\n bytes4 private constant ERC721_SAFE_TRANSFER_FROM =\n bytes4(keccak256(\"safeTransferFrom(address,address,uint256)\"));\n bytes4 private constant ERC721_SAFE_TRANSFER_FROM_BYTES =\n bytes4(keccak256(\"safeTransferFrom(address,address,uint256,bytes)\"));\n bytes4 private constant ERC1155_SAFE_TRANSFER_FROM =\n bytes4(\n keccak256(\"safeTransferFrom(address,address,uint256,uint256,bytes)\")\n );\n bytes4 private constant ERC1155_SAFE_BATCH_TRANSFER_FROM =\n bytes4(\n keccak256(\n \"safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)\"\n )\n );\n\n /**\n * @notice Helper method to recover the spender from a contract call.\n * The method returns the contract unless the call is to a standard method of a ERC20/ERC721/ERC1155 token\n * in which case the spender is recovered from the data.\n * @param _to The target contract.\n * @param _data The data payload.\n */\n function _recover(\n address _to,\n bytes memory _data\n ) internal pure returns (address spender) {\n if (_data.length >= 68) {\n bytes4 methodId;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n methodId := mload(add(_data, 0x20))\n }\n if (\n methodId == ERC20_TRANSFER ||\n methodId == ERC20_APPROVE ||\n methodId == ERC20_INCREASE_ALLOWANCE ||\n methodId == ERC20_DECREASE_ALLOWANCE ||\n methodId == ERC721_SET_APPROVAL_FOR_ALL\n ) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n spender := mload(add(_data, 0x24))\n }\n return spender;\n }\n if (\n methodId == ERC721_TRANSFER_FROM ||\n methodId == ERC721_SAFE_TRANSFER_FROM ||\n methodId == ERC721_SAFE_TRANSFER_FROM_BYTES ||\n methodId == ERC1155_SAFE_TRANSFER_FROM ||\n methodId == ERC1155_SAFE_BATCH_TRANSFER_FROM\n ) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n spender := mload(add(_data, 0x44))\n }\n return spender;\n }\n }\n\n spender = _to;\n }\n}\n" + }, + "contracts/libraries/LibReentrancyGuardStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nstruct ReentrancyGuardStorage {\n uint256 status;\n}\n\nlibrary LibReentrancyGuardStorage {\n bytes32 private constant REENTRANCY_GUARD_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.ReentrancyGuardStorage\");\n\n function reentrancyguardStorage()\n internal\n pure\n returns (ReentrancyGuardStorage storage ds)\n {\n bytes32 storagePosition = REENTRANCY_GUARD_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n}" + }, + "contracts/libraries/LibUtils.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\n\nlibrary LibUtils {\n // Internal utility functions\n function mergeArrays(\n bytes4[] memory _array1,\n bytes4[] memory _array2\n ) internal pure returns (bytes4[] memory) {\n uint256 length1 = _array1.length;\n uint256 length2 = _array2.length;\n bytes4[] memory mergedArray = new bytes4[](length1 + length2);\n\n for (uint256 i; i < length1; ) {\n mergedArray[i] = _array1[i];\n unchecked {\n ++i;\n }\n }\n\n for (uint256 i; i < length2; ) {\n mergedArray[length1 + i] = _array2[i];\n unchecked {\n ++i;\n }\n }\n\n return mergedArray;\n }\n\n function removeFacetElement(\n IDiamondLoupe.Facet[] memory _facets,\n uint256 _index\n ) internal pure returns (IDiamondLoupe.Facet[] memory) {\n require(_index < _facets.length, \"Invalid index\");\n require(_facets.length != 0, \"Invalid array\");\n\n // Create a new array with a length of `_facets.length - 1`\n IDiamondLoupe.Facet[] memory newArray = new IDiamondLoupe.Facet[](\n _facets.length - 1\n );\n uint256 newArrayLength = newArray.length;\n // Iterate over the original array, skipping the element at the specified `index`\n for (uint256 i; i < newArrayLength; ) {\n if (i < _index) {\n newArray[i] = _facets[i];\n } else {\n newArray[i] = _facets[i + 1];\n }\n unchecked {\n ++i;\n }\n }\n\n return newArray;\n }\n\n function removeElement(\n bytes4[] memory _array,\n uint256 _index\n ) internal pure returns (bytes4[] memory) {\n require(_index < _array.length, \"Invalid index\");\n require(_array.length != 0, \"Invalid array\");\n\n bytes4[] memory newArray = new bytes4[](_array.length - 1);\n uint256 newArrayLength = newArray.length;\n for (uint256 i; i < newArrayLength; ) {\n if (i < _index) {\n newArray[i] = _array[i];\n } else {\n newArray[i] = _array[i + 1];\n }\n unchecked {\n ++i;\n }\n }\n\n return newArray;\n }\n\n function setValue(\n bytes4[] memory _keys,\n address[] memory _values,\n bytes4 _key,\n address _value\n ) internal pure returns (bytes4[] memory, address[] memory) {\n uint256 index = findIndex(_keys, _key);\n uint256 keysLength = _keys.length;\n if (index < keysLength) {\n _values[index] = _value;\n } else {\n // Create new storage arrays\n bytes4[] memory newKeys = new bytes4[](keysLength + 1);\n address[] memory newValues = new address[](_values.length + 1);\n\n // Copy values to the new storage arrays\n for (uint256 i; i < keysLength; ) {\n newKeys[i] = _keys[i];\n newValues[i] = _values[i];\n\n unchecked {\n ++i;\n }\n }\n\n // Add the new key-value pair\n newKeys[keysLength] = _key;\n newValues[_values.length] = _value;\n\n return (newKeys, newValues);\n }\n\n // If the key already exists, return the original arrays\n return (_keys, _values);\n }\n\n function getValue(\n bytes4[] memory _keys,\n address[] memory _values,\n bytes4 _key\n ) internal pure returns (address) {\n uint256 index = findIndex(_keys, _key);\n if (index >= _keys.length) return address(0);\n\n return _values[index];\n }\n\n function findIndex(\n bytes4[] memory _keys,\n bytes4 _key\n ) internal pure returns (uint256) {\n uint256 keysLength = _keys.length;\n for (uint256 i; i < keysLength; ) {\n if (_keys[i] == _key) {\n return i;\n }\n unchecked {\n ++i;\n }\n }\n return keysLength;\n }\n}\n" + }, + "contracts/restrictions/IRestriction.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Interface for restrictions\n * @dev Restriction is a contract which decides whether to approve a certain kind of transaction, based on its internal logic.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface IRestriction {\n /**\n * @dev Based on restriction's internal logic, it should accept or reject a certain transaction.\n * @param from The address of the sender, that will be signing the transaction.\n * @param to The receiving address.\n * @param value Amount of ETH to transfer from sender to recipient.\n * @param _calldata Optional field to include arbitrary data.\n * @return bool value for whether the check is passed\n */\n function check(\n address from,\n address to,\n uint256 value,\n bytes calldata _calldata\n ) external returns (bool);\n}\n" + }, + "contracts/restrictions/WhitelistRestriction.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibRecoverSpender} from \"../libraries/LibRecoverSpender.sol\";\nimport {WhitelistStorage} from \"../infrastructure/WhitelistStorage.sol\";\nimport {IRestriction} from \"./IRestriction.sol\";\n\n/**\n * @title Whitelist Restriction\n * @dev This restriction defines a list of accepted addresses and denies any interaction with addresses outside of it.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract WhitelistRestriction is IRestriction {\n WhitelistStorage public immutable whitelistStorage;\n\n constructor(WhitelistStorage _whitelistStorage) {\n whitelistStorage = _whitelistStorage;\n }\n\n /**\n * @notice Helper method to recover the spender from a contract call.\n * The method returns the contract unless the call is to a standard method of a ERC20/ERC721/ERC1155 token\n * in which case the spender is recovered from the data.\n * @param _to The target contract.\n * @param _data The data payload.\n */\n function recoverSpender(\n address _to,\n bytes memory _data\n ) public pure returns (address spender) {\n return LibRecoverSpender._recover(_to, _data);\n }\n\n /*\n * @dev IRestriction's implementation. It will allow transaction if the sender is whitelisted, or user, or the whitelist storage.\n * @param _from The address of the sender, that will be signing the transaction.\n * @param _to The receiving address.\n * @param _calldata Optional field to include arbitrary data.\n * @return result value for whether the check is passed\n */\n function check(\n address _from,\n address _to,\n uint256 /*_value*/,\n bytes calldata _calldata\n ) external view override returns (bool result) {\n return\n whitelistStorage.isWhitelisted(\n _from,\n LibRecoverSpender._recover(_to, _calldata)\n ) ||\n _to == address(whitelistStorage) ||\n _to == msg.sender;\n }\n}\n" + }, + "contracts/test/TestCounter.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\ncontract TestCounter {\n int private count = 0;\n\n event CounterIncremented(int count);\n event CounterDecremented(int count);\n\n function incrementCounter() public {\n count += 1;\n emit CounterIncremented(count);\n }\n\n function decrementCounter() public {\n count -= 1;\n emit CounterIncremented(count);\n }\n\n function getCount() public view returns (int) {\n return count;\n }\n}\n" + }, + "contracts/test/TestERC1155.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC1155/ERC1155.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\n\ncontract TestERC1155 is ERC1155 {\n using Counters for Counters.Counter;\n\n Counters.Counter private _tokenIds;\n\n constructor() ERC1155(\"\") {}\n\n function mint(address account, uint256 amount) external {\n uint256 tokenId = _getNextTokenId();\n _mint(account, tokenId, amount, \"\");\n }\n\n function mintBatch(\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes memory data\n ) external {\n require(\n ids.length == amounts.length,\n \"TestERC1155: arrays length mismatch\"\n );\n\n _mintBatch(to, ids, amounts, data);\n }\n\n function _getNextTokenId() private returns (uint256) {\n _tokenIds.increment();\n return _tokenIds.current();\n }\n}\n" + }, + "contracts/test/TestERC777.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC777/ERC777.sol\";\n\ncontract TestERC777 is ERC777 {\n constructor(\n address[] memory _operators\n ) ERC777(\"TestERC777\", \"TERC777\", _operators) {}\n\n function mint(address account, uint256 amount) external {\n _mint(account, amount, \"\", \"\");\n }\n}\n" + }, + "contracts/test/TestInvalidSecp256k1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IVerificationFacet} from \"../facets/interfaces/IVerificationFacet.sol\";\nimport {IERC1271} from \"../interfaces/ERC/IERC1271.sol\";\nimport {AppStorage, LibAppStorage, BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {LibFacetStorage, Secp256k1VerificationStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {UserOperation} from \"../aa-4337/interfaces/UserOperation.sol\";\n\n/**\n * @title Test Secp256k1 verification facet\n * @dev Default Ethereum's elliptic curve\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract TestInvalidSecp256k1VerificationFacet is BarzStorage, IERC1271 {\n using ECDSA for bytes32;\n error Secp256k1VerificationFacet__InvalidSignerLength();\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n\n event SignerUninitialized();\n\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n }\n\n // THIS INVALID FACET DOES NOT INCLUDE initializeSigner()\n // THIS FACET IS USED TO TEST WHEN initializeSigner() DOESN'T EXIST IN FACET\n\n function uninitializeSigner() external returns (uint256 uninitSuccess) {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view returns (uint256 validationData) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n return validateSignature(userOp, userOpHash, k1Storage.signer);\n }\n\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n address signer\n ) public pure returns (uint256) {\n bytes32 hash = userOpHash.toEthSignedMessageHash();\n if (signer != hash.recover(userOp.signature)) return 1;\n return 0;\n }\n\n // This is REMOVED for testing purpose\n function validateOwnerSignatureSelector() public pure returns (bytes4) {\n // return this.validateOwnerSignature.selector;\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n function owner() public view returns (bytes memory) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n return abi.encodePacked(k1Storage.signer);\n }\n\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure returns (bool) {\n return (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (_hash.recover(_signature) ==\n LibFacetStorage.k1Storage().signer)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n}\n" + }, + "contracts/test/TestNFT.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\n\ncontract TestNFT is ERC721 {\n using Counters for Counters.Counter;\n Counters.Counter private currentTokenId;\n\n constructor() ERC721(\"TestNFT\", \"TNFT\") {}\n\n function mint(address recipient) public returns (uint256) {\n currentTokenId.increment();\n uint256 newItemId = currentTokenId.current();\n _safeMint(recipient, newItemId);\n return newItemId;\n }\n}\n" + }, + "contracts/test/TestToken.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract TestToken is ERC20 {\n constructor()\n // solhint-disable-next-line no-empty-blocks\n ERC20(\"TST\", \"TestToken\")\n {}\n\n function mint(address sender, uint256 amount) external {\n _mint(sender, amount);\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 999999 + }, + "evmVersion": "paris", + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/deployments/linea/.chainId b/deployments/linea/.chainId new file mode 100644 index 0000000..c9e6af4 --- /dev/null +++ b/deployments/linea/.chainId @@ -0,0 +1 @@ +59144 \ No newline at end of file diff --git a/deployments/linea/AccountFacet.json b/deployments/linea/AccountFacet.json new file mode 100644 index 0000000..d96ea5b --- /dev/null +++ b/deployments/linea/AccountFacet.json @@ -0,0 +1,591 @@ +{ + "address": "0xFde53272dcd7938d16E031A6989753c321728332", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "AccountFacet__CallNotSuccessful", + "type": "error" + }, + { + "inputs": [], + "name": "AccountFacet__InitializationFailure", + "type": "error" + }, + { + "inputs": [], + "name": "AccountFacet__InvalidArrayLength", + "type": "error" + }, + { + "inputs": [], + "name": "AccountFacet__NonExistentVerificationFacet", + "type": "error" + }, + { + "inputs": [], + "name": "AccountFacet__RestrictionsFailure", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_initializationContractAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "InitializationFunctionReverted", + "type": "error" + }, + { + "inputs": [], + "name": "LibAppStorage__AccountMustBeUninitialized", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract IEntryPoint", + "name": "entryPoint", + "type": "address" + }, + { + "indexed": true, + "internalType": "bytes", + "name": "ownerPublicKey", + "type": "bytes" + } + ], + "name": "AccountInitialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "indexed": false, + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "DiamondCut", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "VerificationFailure", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "VerificationSuccess", + "type": "event" + }, + { + "inputs": [], + "name": "entryPoint", + "outputs": [ + { + "internalType": "contract IEntryPoint", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_dest", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_func", + "type": "bytes" + } + ], + "name": "execute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_dest", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "_value", + "type": "uint256[]" + }, + { + "internalType": "bytes[]", + "name": "_func", + "type": "bytes[]" + } + ], + "name": "executeBatch", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getNonce", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_verificationFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_anEntryPoint", + "type": "address" + }, + { + "internalType": "address", + "name": "_facetRegistry", + "type": "address" + }, + { + "internalType": "address", + "name": "_defaultFallBackHandler", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_ownerPublicKey", + "type": "bytes" + } + ], + "name": "initialize", + "outputs": [ + { + "internalType": "uint256", + "name": "initSuccess", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "initCode", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "callGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "verificationGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "preVerificationGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxFeePerGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPriorityFeePerGas", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "paymasterAndData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "internalType": "struct UserOperation", + "name": "userOp", + "type": "tuple" + }, + { + "internalType": "bytes32", + "name": "userOpHash", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "missingAccountFunds", + "type": "uint256" + } + ], + "name": "validateUserOp", + "outputs": [ + { + "internalType": "uint256", + "name": "validationData", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0xb9c7821f8b6a8eeeb38274ddd92df281f8068251a1fcc4c5377841ed1b7db837", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 6, + "gasUsed": "2369950", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0xe05853e302aad5342883f4c3a435c05f2aa4c82120c03ccfccf4204fc1dfe003", + "transactionHash": "0xb9c7821f8b6a8eeeb38274ddd92df281f8068251a1fcc4c5377841ed1b7db837", + "logs": [], + "blockNumber": 2720886, + "cumulativeGasUsed": "3424709", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "ad34345aa73d96f52b3e14df983b6b29", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AccountFacet__CallNotSuccessful\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AccountFacet__InitializationFailure\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AccountFacet__InvalidArrayLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AccountFacet__NonExistentVerificationFacet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AccountFacet__RestrictionsFailure\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_initializationContractAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"InitializationFunctionReverted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LibAppStorage__AccountMustBeUninitialized\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract IEntryPoint\",\"name\":\"entryPoint\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes\",\"name\":\"ownerPublicKey\",\"type\":\"bytes\"}],\"name\":\"AccountInitialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"DiamondCut\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"VerificationFailure\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"VerificationSuccess\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"entryPoint\",\"outputs\":[{\"internalType\":\"contract IEntryPoint\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_dest\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_func\",\"type\":\"bytes\"}],\"name\":\"execute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_dest\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"_value\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes[]\",\"name\":\"_func\",\"type\":\"bytes[]\"}],\"name\":\"executeBatch\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_verificationFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_anEntryPoint\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_facetRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_defaultFallBackHandler\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_ownerPublicKey\",\"type\":\"bytes\"}],\"name\":\"initialize\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"initSuccess\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"userOp\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"missingAccountFunds\",\"type\":\"uint256\"}],\"name\":\"validateUserOp\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"validationData\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"Account module contract that provides the account features and initialization of signer compatible with EIP-1271 & EIP-4337\",\"kind\":\"dev\",\"methods\":{\"execute(address,uint256,bytes)\":{\"details\":\"This method executes the calldata coming from the EntryPoint. Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\",\"params\":{\"_dest\":\"Address of destination where the call will be forwarded to\",\"_func\":\"Bytes of calldata to execute in the destination address\",\"_value\":\"Amount of native coin the owner is willing to send(e.g. ETH, BNB)\"}},\"executeBatch(address[],uint256[],bytes[])\":{\"details\":\"This method batch executes the calldata coming from the EntryPoint. Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\",\"params\":{\"_dest\":\"Array of addresses of destination where the call will be forwarded to\",\"_func\":\"Array of bytes of calldata to execute in the destination address\",\"_value\":\"Array of amount of native coin the owner is willing to send(e.g. ETH, BNB)\"}},\"initialize(address,address,address,address,bytes)\":{\"details\":\"This method can only be called during the initialization or signature migration. If the proxy contract was created without initialization, anyone can call initialize. Barz calls initialize in constructor in an atomic transaction during deployment\",\"params\":{\"_anEntryPoint\":\"Entrypoint contract defined in EIP-4337 handling the flow of UserOp\",\"_defaultFallBackHandler\":\"Middleware contract for default facets\",\"_facetRegistry\":\"Registry of Facets that hold all facet information\",\"_ownerPublicKey\":\"Bytes of owner public key\",\"_verificationFacet\":\"Facet contract handling the verificationi\"}}},\"title\":\"Account Facet\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"This constructor ensures that this contract can only be used as singleton for Proxy contracts\"},\"entryPoint()\":{\"notice\":\"Returns the address of EntryPoint contract registered to Barz account\"},\"execute(address,uint256,bytes)\":{\"notice\":\"Calls the destination with inputted calldata and value from EntryPoint\"},\"executeBatch(address[],uint256[],bytes[])\":{\"notice\":\"Batch calls the destination with inputted calldata and value from EntryPoint\"},\"getNonce()\":{\"notice\":\"Return the account nonce. This method returns the next sequential nonce. For a nonce of a specific key, use `entrypoint.getNonce(account, key)`\"},\"initialize(address,address,address,address,bytes)\":{\"notice\":\"Initializes the initial storage of the Barz contract.\"},\"validateUserOp((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256)\":{\"notice\":\"Validate user's signature and nonce. subclass doesn't need to override this method. Instead, it should override the specific internal validation methods.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/AccountFacet.sol\":\"AccountFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./math/Math.sol\\\";\\nimport \\\"./math/SignedMath.sol\\\";\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n uint256 length = Math.log10(value) + 1;\\n string memory buffer = new string(length);\\n uint256 ptr;\\n /// @solidity memory-safe-assembly\\n assembly {\\n ptr := add(buffer, add(32, length))\\n }\\n while (true) {\\n ptr--;\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\\n }\\n value /= 10;\\n if (value == 0) break;\\n }\\n return buffer;\\n }\\n }\\n\\n /**\\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\\n */\\n function toString(int256 value) internal pure returns (string memory) {\\n return string(abi.encodePacked(value < 0 ? \\\"-\\\" : \\\"\\\", toString(SignedMath.abs(value))));\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n return toHexString(value, Math.log256(value) + 1);\\n }\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n\\n /**\\n * @dev Returns true if the two strings are equal.\\n */\\n function equal(string memory a, string memory b) internal pure returns (bool) {\\n return keccak256(bytes(a)) == keccak256(bytes(b));\\n }\\n}\\n\",\"keccak256\":\"0x3088eb2868e8d13d89d16670b5f8612c4ab9ff8956272837d8e90106c59c14a0\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Strings.sol\\\";\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSA {\\n enum RecoverError {\\n NoError,\\n InvalidSignature,\\n InvalidSignatureLength,\\n InvalidSignatureS,\\n InvalidSignatureV // Deprecated in v4.8\\n }\\n\\n function _throwError(RecoverError error) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert(\\\"ECDSA: invalid signature\\\");\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert(\\\"ECDSA: invalid signature length\\\");\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert(\\\"ECDSA: invalid signature 's' value\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature` or error string. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n *\\n * Documentation for signature generation:\\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n return tryRecover(hash, v, r, s);\\n } else {\\n return (address(0), RecoverError.InvalidSignatureLength);\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature`. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, signature);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\\n uint8 v = uint8((uint256(vs) >> 255) + 27);\\n return tryRecover(hash, v, r, s);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n *\\n * _Available since v4.2._\\n */\\n function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\\n // the valid range for s in (301): 0 < s < secp256k1n \\u00f7 2 + 1, and for v in (302): v \\u2208 {27, 28}. Most\\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\\n //\\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\\n // these malleable signatures as well.\\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n return (address(0), RecoverError.InvalidSignatureS);\\n }\\n\\n // If the signature is valid (and not malleable), return the signer address\\n address signer = ecrecover(hash, v, r, s);\\n if (signer == address(0)) {\\n return (address(0), RecoverError.InvalidSignature);\\n }\\n\\n return (signer, RecoverError.NoError);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore(0x00, \\\"\\\\x19Ethereum Signed Message:\\\\n32\\\")\\n mstore(0x1c, hash)\\n message := keccak256(0x00, 0x3c)\\n }\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from `s`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n\\\", Strings.toString(s.length), s));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Typed Data, created from a\\n * `domainSeparator` and a `structHash`. This produces hash corresponding\\n * to the one signed with the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n * JSON-RPC method as part of EIP-712.\\n *\\n * See {recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n let ptr := mload(0x40)\\n mstore(ptr, \\\"\\\\x19\\\\x01\\\")\\n mstore(add(ptr, 0x02), domainSeparator)\\n mstore(add(ptr, 0x22), structHash)\\n data := keccak256(ptr, 0x42)\\n }\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Data with intended validator, created from a\\n * `validator` and `data` according to the version 0 of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x00\\\", validator, data));\\n }\\n}\\n\",\"keccak256\":\"0x809bc3edb4bcbef8263fa616c1b60ee0004b50a8a1bfa164d8f57fd31f520c58\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n enum Rounding {\\n Down, // Toward negative infinity\\n Up, // Toward infinity\\n Zero // Toward zero\\n }\\n\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow.\\n return (a & b) + (a ^ b) / 2;\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a == 0 ? 0 : (a - 1) / b + 1;\\n }\\n\\n /**\\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\\n * with further edits by Uniswap Labs also under MIT license.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\\n unchecked {\\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2^256 + prod0.\\n uint256 prod0; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division.\\n if (prod1 == 0) {\\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\\n // The surrounding unchecked block does not change this fact.\\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\\n return prod0 / denominator;\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n require(denominator > prod1, \\\"Math: mulDiv overflow\\\");\\n\\n ///////////////////////////////////////////////\\n // 512 by 256 division.\\n ///////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0].\\n uint256 remainder;\\n assembly {\\n // Compute remainder using mulmod.\\n remainder := mulmod(x, y, denominator)\\n\\n // Subtract 256 bit number from 512 bit number.\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\\n // See https://cs.stackexchange.com/q/138556/92363.\\n\\n // Does not overflow because the denominator cannot be zero at this stage in the function.\\n uint256 twos = denominator & (~denominator + 1);\\n assembly {\\n // Divide denominator by twos.\\n denominator := div(denominator, twos)\\n\\n // Divide [prod1 prod0] by twos.\\n prod0 := div(prod0, twos)\\n\\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\\n twos := add(div(sub(0, twos), twos), 1)\\n }\\n\\n // Shift in bits from prod1 into prod0.\\n prod0 |= prod1 * twos;\\n\\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\\n // four bits. That is, denominator * inv = 1 mod 2^4.\\n uint256 inverse = (3 * denominator) ^ 2;\\n\\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\\n // in modular arithmetic, doubling the correct bits in each step.\\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\\n\\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inverse;\\n return result;\\n }\\n }\\n\\n /**\\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\\n uint256 result = mulDiv(x, y, denominator);\\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\\n result += 1;\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\\n *\\n * Inspired by Henry S. Warren, Jr.'s \\\"Hacker's Delight\\\" (Chapter 11).\\n */\\n function sqrt(uint256 a) internal pure returns (uint256) {\\n if (a == 0) {\\n return 0;\\n }\\n\\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\\n //\\n // We know that the \\\"msb\\\" (most significant bit) of our target number `a` is a power of 2 such that we have\\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\\n //\\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\\n // \\u2192 `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\\n // \\u2192 `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\\n //\\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\\n uint256 result = 1 << (log2(a) >> 1);\\n\\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\\n // into the expected uint128 result.\\n unchecked {\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n return min(result, a / result);\\n }\\n }\\n\\n /**\\n * @notice Calculates sqrt(a), following the selected rounding direction.\\n */\\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = sqrt(a);\\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 2, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 128;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 64;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 32;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 16;\\n }\\n if (value >> 8 > 0) {\\n value >>= 8;\\n result += 8;\\n }\\n if (value >> 4 > 0) {\\n value >>= 4;\\n result += 4;\\n }\\n if (value >> 2 > 0) {\\n value >>= 2;\\n result += 2;\\n }\\n if (value >> 1 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log2(value);\\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 10, rounded down, of a positive value.\\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 + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 256, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n *\\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\\n */\\n function log256(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 16;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 8;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 4;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 2;\\n }\\n if (value >> 8 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log256(value);\\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe4455ac1eb7fc497bb7402579e7b4d64d928b846fce7d2b6fde06d366f21c2b3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\\n * checks.\\n *\\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\\n * easily result in undesired exploitation or bugs, since developers usually\\n * assume that overflows raise errors. `SafeCast` restores this intuition by\\n * reverting the transaction when such an operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n *\\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\\n * all math on `uint256` and `int256` and then downcasting.\\n */\\nlibrary SafeCast {\\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 * _Available since v4.7._\\n */\\n function toUint248(uint256 value) internal pure returns (uint248) {\\n require(value <= type(uint248).max, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint240(uint256 value) internal pure returns (uint240) {\\n require(value <= type(uint240).max, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint232(uint256 value) internal pure returns (uint232) {\\n require(value <= type(uint232).max, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint224(uint256 value) internal pure returns (uint224) {\\n require(value <= type(uint224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint216(uint256 value) internal pure returns (uint216) {\\n require(value <= type(uint216).max, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint208(uint256 value) internal pure returns (uint208) {\\n require(value <= type(uint208).max, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint200(uint256 value) internal pure returns (uint200) {\\n require(value <= type(uint200).max, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint192(uint256 value) internal pure returns (uint192) {\\n require(value <= type(uint192).max, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint184(uint256 value) internal pure returns (uint184) {\\n require(value <= type(uint184).max, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint176(uint256 value) internal pure returns (uint176) {\\n require(value <= type(uint176).max, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint168(uint256 value) internal pure returns (uint168) {\\n require(value <= type(uint168).max, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint160(uint256 value) internal pure returns (uint160) {\\n require(value <= type(uint160).max, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint152(uint256 value) internal pure returns (uint152) {\\n require(value <= type(uint152).max, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint144(uint256 value) internal pure returns (uint144) {\\n require(value <= type(uint144).max, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint136(uint256 value) internal pure returns (uint136) {\\n require(value <= type(uint136).max, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint128(uint256 value) internal pure returns (uint128) {\\n require(value <= type(uint128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint120(uint256 value) internal pure returns (uint120) {\\n require(value <= type(uint120).max, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint112(uint256 value) internal pure returns (uint112) {\\n require(value <= type(uint112).max, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint104(uint256 value) internal pure returns (uint104) {\\n require(value <= type(uint104).max, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint96(uint256 value) internal pure returns (uint96) {\\n require(value <= type(uint96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint88(uint256 value) internal pure returns (uint88) {\\n require(value <= type(uint88).max, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint80(uint256 value) internal pure returns (uint80) {\\n require(value <= type(uint80).max, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint72(uint256 value) internal pure returns (uint72) {\\n require(value <= type(uint72).max, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint64(uint256 value) internal pure returns (uint64) {\\n require(value <= type(uint64).max, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint56(uint256 value) internal pure returns (uint56) {\\n require(value <= type(uint56).max, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint48(uint256 value) internal pure returns (uint48) {\\n require(value <= type(uint48).max, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint40(uint256 value) internal pure returns (uint40) {\\n require(value <= type(uint40).max, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint32(uint256 value) internal pure returns (uint32) {\\n require(value <= type(uint32).max, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint24(uint256 value) internal pure returns (uint24) {\\n require(value <= type(uint24).max, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint16(uint256 value) internal pure returns (uint16) {\\n require(value <= type(uint16).max, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint8(uint256 value) internal pure returns (uint8) {\\n require(value <= type(uint8).max, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\n */\\n function toUint256(int256 value) internal pure returns (uint256) {\\n require(value >= 0, \\\"SafeCast: value must be positive\\\");\\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 * _Available since v4.7._\\n */\\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\\n downcasted = int248(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\\n downcasted = int240(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\\n downcasted = int232(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\\n downcasted = int224(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\\n downcasted = int216(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\\n downcasted = int208(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\\n downcasted = int200(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\\n downcasted = int192(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\\n downcasted = int184(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\\n downcasted = int176(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\\n downcasted = int168(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\\n downcasted = int160(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\\n downcasted = int152(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\\n downcasted = int144(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\\n downcasted = int136(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\\n downcasted = int128(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\\n downcasted = int120(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\\n downcasted = int112(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\\n downcasted = int104(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\\n downcasted = int96(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\\n downcasted = int88(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\\n downcasted = int80(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\\n downcasted = int72(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\\n downcasted = int64(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\\n downcasted = int56(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\\n downcasted = int48(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\\n downcasted = int40(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\\n downcasted = int32(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\\n downcasted = int24(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\\n downcasted = int16(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\\n downcasted = int8(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\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 require(value <= uint256(type(int256).max), \\\"SafeCast: value doesn't fit in an int256\\\");\\n return int256(value);\\n }\\n}\\n\",\"keccak256\":\"0x52a8cfb0f5239d11b457dcdd1b326992ef672714ca8da71a157255bddd13f3ad\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SignedMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard signed math utilities missing in the Solidity language.\\n */\\nlibrary SignedMath {\\n /**\\n * @dev Returns the largest of two signed numbers.\\n */\\n function max(int256 a, int256 b) internal pure returns (int256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two signed numbers.\\n */\\n function min(int256 a, int256 b) internal pure returns (int256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two signed numbers without overflow.\\n * The result is rounded towards zero.\\n */\\n function average(int256 a, int256 b) internal pure returns (int256) {\\n // Formula from the book \\\"Hacker's Delight\\\"\\n int256 x = (a & b) + ((a ^ b) >> 1);\\n return x + (int256(uint256(x) >> 255) & (a ^ b));\\n }\\n\\n /**\\n * @dev Returns the absolute unsigned value of a signed value.\\n */\\n function abs(int256 n) internal pure returns (uint256) {\\n unchecked {\\n // must be unchecked in order to support `n = type(int256).min`\\n return uint256(n >= 0 ? n : -n);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf92515413956f529d95977adc9b0567d583c6203fc31ab1c23824c35187e3ddc\",\"license\":\"MIT\"},\"contracts/aa-4337/core/BaseAccount.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-empty-blocks */\\n\\nimport \\\"../interfaces/IAccount.sol\\\";\\nimport \\\"../interfaces/IEntryPoint.sol\\\";\\nimport \\\"./Helpers.sol\\\";\\n\\n/**\\n * Basic account implementation.\\n * this contract provides the basic logic for implementing the IAccount interface - validateUserOp\\n * specific account implementation should inherit it and provide the account-specific logic\\n */\\nabstract contract BaseAccount is IAccount {\\n using UserOperationLib for UserOperation;\\n\\n //return value in case of signature failure, with no time-range.\\n // equivalent to _packValidationData(true,0,0);\\n uint256 internal constant SIG_VALIDATION_FAILED = 1;\\n\\n /**\\n * Return the account nonce.\\n * This method returns the next sequential nonce.\\n * For a nonce of a specific key, use `entrypoint.getNonce(account, key)`\\n */\\n function getNonce() public view virtual returns (uint256) {\\n return entryPoint().getNonce(address(this), 0);\\n }\\n\\n /**\\n * return the entryPoint used by this account.\\n * subclass should return the current entryPoint used by this account.\\n */\\n function entryPoint() public view virtual returns (IEntryPoint);\\n\\n /**\\n * Validate user's signature and nonce.\\n * subclass doesn't need to override this method. Instead, it should override the specific internal validation methods.\\n */\\n function validateUserOp(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n uint256 missingAccountFunds\\n ) external virtual override returns (uint256 validationData) {\\n _requireFromEntryPoint();\\n validationData = _validateSignature(userOp, userOpHash);\\n _validateNonce(userOp.nonce);\\n _payPrefund(missingAccountFunds);\\n }\\n\\n /**\\n * ensure the request comes from the known entrypoint.\\n */\\n function _requireFromEntryPoint() internal view virtual {\\n require(\\n msg.sender == address(entryPoint()),\\n \\\"account: not from EntryPoint\\\"\\n );\\n }\\n\\n /**\\n * validate the signature is valid for this message.\\n * @param userOp validate the userOp.signature field\\n * @param userOpHash convenient field: the hash of the request, to check the signature against\\n * (also hashes the entrypoint and chain id)\\n * @return validationData signature and time-range of this operation\\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\\n * otherwise, an address of an \\\"authorizer\\\" contract.\\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \\\"indefinite\\\"\\n * <6-byte> validAfter - first timestamp this operation is valid\\n * If the account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\\n */\\n function _validateSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) internal virtual returns (uint256 validationData);\\n\\n /**\\n * Validate the nonce of the UserOperation.\\n * This method may validate the nonce requirement of this account.\\n * e.g.\\n * To limit the nonce to use sequenced UserOps only (no \\\"out of order\\\" UserOps):\\n * `require(nonce < type(uint64).max)`\\n * For a hypothetical account that *requires* the nonce to be out-of-order:\\n * `require(nonce & type(uint64).max == 0)`\\n *\\n * The actual nonce uniqueness is managed by the EntryPoint, and thus no other\\n * action is needed by the account itself.\\n *\\n * @param nonce to validate\\n *\\n * solhint-disable-next-line no-empty-blocks\\n */\\n function _validateNonce(uint256 nonce) internal view virtual {}\\n\\n /**\\n * sends to the entrypoint (msg.sender) the missing funds for this transaction.\\n * subclass MAY override this method for better funds management\\n * (e.g. send to the entryPoint more than the minimum required, so that in future transactions\\n * it will not be required to send again)\\n * @param missingAccountFunds the minimum value this method should send the entrypoint.\\n * this value MAY be zero, in case there is enough deposit, or the userOp has a paymaster.\\n */\\n function _payPrefund(uint256 missingAccountFunds) internal virtual {\\n if (missingAccountFunds != 0) {\\n (bool success, ) = payable(msg.sender).call{\\n value: missingAccountFunds,\\n gas: type(uint256).max\\n }(\\\"\\\");\\n (success);\\n //ignore failure (its EntryPoint's job to verify, not account.)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa0dcc386b0f04711db3e394fb50e55a3b3b1a4d19fac1f10895844e1aa4e3d5c\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/core/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable no-inline-assembly */\\n\\n/**\\n * returned data from validateUserOp.\\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\\n * @param aggregator - address(0) - the account validated the signature by itself.\\n * address(1) - the account failed to validate the signature.\\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\\n * @param validAfter - this UserOp is valid only after this timestamp.\\n * @param validaUntil - this UserOp is valid only up to this timestamp.\\n */\\nstruct ValidationData {\\n address aggregator;\\n uint48 validAfter;\\n uint48 validUntil;\\n}\\n\\n//extract sigFailed, validAfter, validUntil.\\n// also convert zero validUntil to type(uint48).max\\nfunction _parseValidationData(\\n uint validationData\\n) pure returns (ValidationData memory data) {\\n address aggregator = address(uint160(validationData));\\n uint48 validUntil = uint48(validationData >> 160);\\n if (validUntil == 0) {\\n validUntil = type(uint48).max;\\n }\\n uint48 validAfter = uint48(validationData >> (48 + 160));\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n// intersect account and paymaster ranges.\\nfunction _intersectTimeRange(\\n uint256 validationData,\\n uint256 paymasterValidationData\\n) pure returns (ValidationData memory) {\\n ValidationData memory accountValidationData = _parseValidationData(\\n validationData\\n );\\n ValidationData memory pmValidationData = _parseValidationData(\\n paymasterValidationData\\n );\\n address aggregator = accountValidationData.aggregator;\\n if (aggregator == address(0)) {\\n aggregator = pmValidationData.aggregator;\\n }\\n uint48 validAfter = accountValidationData.validAfter;\\n uint48 validUntil = accountValidationData.validUntil;\\n uint48 pmValidAfter = pmValidationData.validAfter;\\n uint48 pmValidUntil = pmValidationData.validUntil;\\n\\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp\\n * @param data - the ValidationData to pack\\n */\\nfunction _packValidationData(\\n ValidationData memory data\\n) pure returns (uint256) {\\n return\\n uint160(data.aggregator) |\\n (uint256(data.validUntil) << 160) |\\n (uint256(data.validAfter) << (160 + 48));\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp, when not using an aggregator\\n * @param sigFailed - true for signature failure, false for success\\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\\n * @param validAfter first timestamp this UserOperation is valid\\n */\\nfunction _packValidationData(\\n bool sigFailed,\\n uint48 validUntil,\\n uint48 validAfter\\n) pure returns (uint256) {\\n return\\n (sigFailed ? 1 : 0) |\\n (uint256(validUntil) << 160) |\\n (uint256(validAfter) << (160 + 48));\\n}\\n\\n/**\\n * keccak function over calldata.\\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\\n */\\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\\n assembly {\\n let mem := mload(0x40)\\n let len := data.length\\n calldatacopy(mem, data.offset, len)\\n ret := keccak256(mem, len)\\n }\\n}\\n\",\"keccak256\":\"0xa79f06cd158ecb8c0da95493a2f348933b8627a63e228b99738bff3aa107942d\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAccount.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\ninterface IAccount {\\n /**\\n * Validate user's signature and nonce\\n * the entryPoint will make the call to the recipient only if this validation call returns successfully.\\n * signature failure should be reported by returning SIG_VALIDATION_FAILED (1).\\n * This allows making a \\\"simulation call\\\" without a valid signature\\n * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure.\\n *\\n * @dev Must validate caller is the entryPoint.\\n * Must validate the signature and nonce\\n * @param userOp the operation that is about to be executed.\\n * @param userOpHash hash of the user's request data. can be used as the basis for signature.\\n * @param missingAccountFunds missing funds on the account's deposit in the entrypoint.\\n * This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call.\\n * The excess is left as a deposit in the entrypoint, for future calls.\\n * can be withdrawn anytime using \\\"entryPoint.withdrawTo()\\\"\\n * In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero.\\n * @return validationData packaged ValidationData structure. use `_packValidationData` and `_unpackValidationData` to encode and decode\\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\\n * otherwise, an address of an \\\"authorizer\\\" contract.\\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \\\"indefinite\\\"\\n * <6-byte> validAfter - first timestamp this operation is valid\\n * If an account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\\n */\\n function validateUserOp(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n uint256 missingAccountFunds\\n ) external returns (uint256 validationData);\\n}\\n\",\"keccak256\":\"0xcbc4b0973cf954c5895b7796335f651fbfcfb55f67dfa789a3d354f8e23c4f2b\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAggregator.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\n/**\\n * Aggregated Signatures validator.\\n */\\ninterface IAggregator {\\n /**\\n * validate aggregated signature.\\n * revert if the aggregated signature does not match the given list of operations.\\n */\\n function validateSignatures(\\n UserOperation[] calldata userOps,\\n bytes calldata signature\\n ) external view;\\n\\n /**\\n * validate signature of a single userOp\\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\\n * @param userOp the userOperation received from the user.\\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\\n * (usually empty, unless account and aggregator support some kind of \\\"multisig\\\"\\n */\\n function validateUserOpSignature(\\n UserOperation calldata userOp\\n ) external view returns (bytes memory sigForUserOp);\\n\\n /**\\n * aggregate multiple signatures into a single value.\\n * This method is called off-chain to calculate the signature to pass with handleOps()\\n * bundler MAY use optimized custom code perform this aggregation\\n * @param userOps array of UserOperations to collect the signatures from.\\n * @return aggregatedSignature the aggregated signature\\n */\\n function aggregateSignatures(\\n UserOperation[] calldata userOps\\n ) external view returns (bytes memory aggregatedSignature);\\n}\\n\",\"keccak256\":\"0xdfdcd80568f037716674619b31be630fcd8316262f05a815b41d1e81782c966a\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IEntryPoint.sol\":{\"content\":\"/**\\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\\n ** Only one instance required on each chain.\\n **/\\n// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-inline-assembly */\\n/* solhint-disable reason-string */\\n\\nimport \\\"./UserOperation.sol\\\";\\nimport \\\"./IStakeManager.sol\\\";\\nimport \\\"./IAggregator.sol\\\";\\nimport \\\"./INonceManager.sol\\\";\\n\\ninterface IEntryPoint is IStakeManager, INonceManager {\\n /***\\n * An event emitted after each successful request\\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\\n * @param sender - the account that generates this request.\\n * @param paymaster - if non-null, the paymaster that pays for this request.\\n * @param nonce - the nonce value from the request.\\n * @param success - true if the sender transaction succeeded, false if reverted.\\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\\n */\\n event UserOperationEvent(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address indexed paymaster,\\n uint256 nonce,\\n bool success,\\n uint256 actualGasCost,\\n uint256 actualGasUsed\\n );\\n\\n /**\\n * account \\\"sender\\\" was deployed.\\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\\n * @param sender the account that is deployed\\n * @param factory the factory used to deploy this account (in the initCode)\\n * @param paymaster the paymaster used by this UserOp\\n */\\n event AccountDeployed(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address factory,\\n address paymaster\\n );\\n\\n /**\\n * An event emitted if the UserOperation \\\"callData\\\" reverted with non-zero length\\n * @param userOpHash the request unique identifier.\\n * @param sender the sender of this request\\n * @param nonce the nonce used in the request\\n * @param revertReason - the return bytes from the (reverted) call to \\\"callData\\\".\\n */\\n event UserOperationRevertReason(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n uint256 nonce,\\n bytes revertReason\\n );\\n\\n /**\\n * an event emitted by handleOps(), before starting the execution loop.\\n * any event emitted before this event, is part of the validation.\\n */\\n event BeforeExecution();\\n\\n /**\\n * signature aggregator used by the following UserOperationEvents within this bundle.\\n */\\n event SignatureAggregatorChanged(address indexed aggregator);\\n\\n /**\\n * a custom revert error of handleOps, to identify the offending op.\\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\\n * @param reason - revert reason\\n * The string starts with a unique code \\\"AAmn\\\", where \\\"m\\\" is \\\"1\\\" for factory, \\\"2\\\" for account and \\\"3\\\" for paymaster issues,\\n * so a failure can be attributed to the correct entity.\\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\\n */\\n error FailedOp(uint256 opIndex, string reason);\\n\\n /**\\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\\n */\\n error SignatureValidationFailed(address aggregator);\\n\\n /**\\n * Successful result from simulateValidation.\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n */\\n error ValidationResult(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo\\n );\\n\\n /**\\n * Successful result from simulateValidation, if the account returns a signature aggregator\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\\n * bundler MUST use it to verify the signature, or reject the UserOperation\\n */\\n error ValidationResultWithAggregation(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo,\\n AggregatorStakeInfo aggregatorInfo\\n );\\n\\n /**\\n * return value of getSenderAddress\\n */\\n error SenderAddressResult(address sender);\\n\\n /**\\n * return value of simulateHandleOp\\n */\\n error ExecutionResult(\\n uint256 preOpGas,\\n uint256 paid,\\n uint48 validAfter,\\n uint48 validUntil,\\n bool targetSuccess,\\n bytes targetResult\\n );\\n\\n //UserOps handled, per aggregator\\n struct UserOpsPerAggregator {\\n UserOperation[] userOps;\\n // aggregator address\\n IAggregator aggregator;\\n // aggregated signature\\n bytes signature;\\n }\\n\\n /**\\n * Execute a batch of UserOperation.\\n * no signature aggregator is used.\\n * if any account requires an aggregator (that is, it returned an aggregator when\\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\\n * @param ops the operations to execute\\n * @param beneficiary the address to receive the fees\\n */\\n function handleOps(\\n UserOperation[] calldata ops,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * Execute a batch of UserOperation with Aggregators\\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\\n * @param beneficiary the address to receive the fees\\n */\\n function handleAggregatedOps(\\n UserOpsPerAggregator[] calldata opsPerAggregator,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * generate a request Id - unique identifier for this request.\\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\\n */\\n function getUserOpHash(\\n UserOperation calldata userOp\\n ) external view returns (bytes32);\\n\\n /**\\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\\n * @param userOp the user operation to validate.\\n */\\n function simulateValidation(UserOperation calldata userOp) external;\\n\\n /**\\n * gas and return values during simulation\\n * @param preOpGas the gas used for validation (including preValidationGas)\\n * @param prefund the required prefund for this operation\\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\\n */\\n struct ReturnInfo {\\n uint256 preOpGas;\\n uint256 prefund;\\n bool sigFailed;\\n uint48 validAfter;\\n uint48 validUntil;\\n bytes paymasterContext;\\n }\\n\\n /**\\n * returned aggregated signature info.\\n * the aggregator returned by the account, and its current stake.\\n */\\n struct AggregatorStakeInfo {\\n address aggregator;\\n StakeInfo stakeInfo;\\n }\\n\\n /**\\n * Get counterfactual sender address.\\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\\n * this method always revert, and returns the address in SenderAddressResult error\\n * @param initCode the constructor code to be passed into the UserOperation.\\n */\\n function getSenderAddress(bytes memory initCode) external;\\n\\n /**\\n * simulate full execution of a UserOperation (including both validation and target execution)\\n * this method will always revert with \\\"ExecutionResult\\\".\\n * it performs full validation of the UserOperation, but ignores signature error.\\n * an optional target address is called after the userop succeeds, and its value is returned\\n * (before the entire call is reverted)\\n * Note that in order to collect the the success/failure of the target call, it must be executed\\n * with trace enabled to track the emitted events.\\n * @param op the UserOperation to simulate\\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\\n * are set to the return from that call.\\n * @param targetCallData callData to pass to target address\\n */\\n function simulateHandleOp(\\n UserOperation calldata op,\\n address target,\\n bytes calldata targetCallData\\n ) external;\\n}\\n\",\"keccak256\":\"0x9ccb1b188eda8bbf5f6c2d01bd83c3d8b2b04fcf745283051d31fe96d1d8e40f\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/INonceManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\ninterface INonceManager {\\n /**\\n * Return the next nonce for this sender.\\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\\n * But UserOp with different keys can come with arbitrary order.\\n *\\n * @param sender the account address\\n * @param key the high 192 bit of the nonce\\n * @return nonce a full nonce to pass for next UserOp with this sender.\\n */\\n function getNonce(\\n address sender,\\n uint192 key\\n ) external view returns (uint256 nonce);\\n\\n /**\\n * Manually increment the nonce of the sender.\\n * This method is exposed just for completeness..\\n * Account does NOT need to call it, neither during validation, nor elsewhere,\\n * as the EntryPoint will update the nonce regardless.\\n * Possible use-case is call it with various keys to \\\"initialize\\\" their nonces to one, so that future\\n * UserOperations will not pay extra for the first transaction with a given key.\\n */\\n function incrementNonce(uint192 key) external;\\n}\\n\",\"keccak256\":\"0xce478ad0fa0d18a3b785ac854623029e7ab463d05873dfaa365abfa1bf100912\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IStakeManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8.12;\\n\\n/**\\n * manage deposits and stakes.\\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\\n * stake is value locked for at least \\\"unstakeDelay\\\" by the staked entity.\\n */\\ninterface IStakeManager {\\n event Deposited(address indexed account, uint256 totalDeposit);\\n\\n event Withdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /// Emitted when stake or unstake delay are modified\\n event StakeLocked(\\n address indexed account,\\n uint256 totalStaked,\\n uint256 unstakeDelaySec\\n );\\n\\n /// Emitted once a stake is scheduled for withdrawal\\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\\n\\n event StakeWithdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /**\\n * @param deposit the entity's deposit\\n * @param staked true if this entity is staked.\\n * @param stake actual amount of ether staked for this entity.\\n * @param unstakeDelaySec minimum delay to withdraw the stake.\\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\\n * and the rest fit into a 2nd cell.\\n * 112 bit allows for 10^15 eth\\n * 48 bit for full timestamp\\n * 32 bit allows 150 years for unstake delay\\n */\\n struct DepositInfo {\\n uint112 deposit;\\n bool staked;\\n uint112 stake;\\n uint32 unstakeDelaySec;\\n uint48 withdrawTime;\\n }\\n\\n //API struct used by getStakeInfo and simulateValidation\\n struct StakeInfo {\\n uint256 stake;\\n uint256 unstakeDelaySec;\\n }\\n\\n /// @return info - full deposit information of given account\\n function getDepositInfo(\\n address account\\n ) external view returns (DepositInfo memory info);\\n\\n /// @return the deposit (for gas payment) of the account\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * add to the deposit of the given account\\n */\\n function depositTo(address account) external payable;\\n\\n /**\\n * add to the account's stake - amount and delay\\n * any pending unstake is first cancelled.\\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\\n */\\n function addStake(uint32 _unstakeDelaySec) external payable;\\n\\n /**\\n * attempt to unlock the stake.\\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\\n */\\n function unlockStake() external;\\n\\n /**\\n * withdraw from the (unlocked) stake.\\n * must first call unlockStake and wait for the unstakeDelay to pass\\n * @param withdrawAddress the address to send withdrawn value.\\n */\\n function withdrawStake(address payable withdrawAddress) external;\\n\\n /**\\n * withdraw from the deposit.\\n * @param withdrawAddress the address to send withdrawn value.\\n * @param withdrawAmount the amount to withdraw.\\n */\\n function withdrawTo(\\n address payable withdrawAddress,\\n uint256 withdrawAmount\\n ) external;\\n}\\n\",\"keccak256\":\"0xadcea606c9b7aafe6645441f2154a60f271330b0eee5292a632aa71c1672d546\",\"license\":\"GPL-3.0-only\"},\"contracts/aa-4337/interfaces/UserOperation.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable no-inline-assembly */\\n\\nimport {calldataKeccak} from \\\"../core/Helpers.sol\\\";\\n\\n/**\\n * User Operation struct\\n * @param sender the sender account of this request.\\n * @param nonce unique value the sender uses to verify it is not a replay.\\n * @param initCode if set, the account contract will be created by this constructor/\\n * @param callData the method call to execute on this account.\\n * @param callGasLimit the gas limit passed to the callData method call.\\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\\n * @param maxFeePerGas same as EIP-1559 gas parameter.\\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\\n */\\nstruct UserOperation {\\n address sender;\\n uint256 nonce;\\n bytes initCode;\\n bytes callData;\\n uint256 callGasLimit;\\n uint256 verificationGasLimit;\\n uint256 preVerificationGas;\\n uint256 maxFeePerGas;\\n uint256 maxPriorityFeePerGas;\\n bytes paymasterAndData;\\n bytes signature;\\n}\\n\\n/**\\n * Utility functions helpful when working with UserOperation structs.\\n */\\nlibrary UserOperationLib {\\n function getSender(\\n UserOperation calldata userOp\\n ) internal pure returns (address) {\\n address data;\\n //read sender from userOp, which is first userOp member (saves 800 gas...)\\n assembly {\\n data := calldataload(userOp)\\n }\\n return address(uint160(data));\\n }\\n\\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\\n // pay above what he signed for.\\n function gasPrice(\\n UserOperation calldata userOp\\n ) internal view returns (uint256) {\\n unchecked {\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n if (maxFeePerGas == maxPriorityFeePerGas) {\\n //legacy mode (for networks that don't support basefee opcode)\\n return maxFeePerGas;\\n }\\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\\n }\\n }\\n\\n function pack(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes memory ret) {\\n address sender = getSender(userOp);\\n uint256 nonce = userOp.nonce;\\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\\n bytes32 hashCallData = calldataKeccak(userOp.callData);\\n uint256 callGasLimit = userOp.callGasLimit;\\n uint256 verificationGasLimit = userOp.verificationGasLimit;\\n uint256 preVerificationGas = userOp.preVerificationGas;\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\\n\\n return\\n abi.encode(\\n sender,\\n nonce,\\n hashInitCode,\\n hashCallData,\\n callGasLimit,\\n verificationGasLimit,\\n preVerificationGas,\\n maxFeePerGas,\\n maxPriorityFeePerGas,\\n hashPaymasterAndData\\n );\\n }\\n\\n function hash(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes32) {\\n return keccak256(pack(userOp));\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n}\\n\",\"keccak256\":\"0x2429f5cc546bdee08c7e63858d0dda8491eaa3ab5194df884dc948c1154d2834\",\"license\":\"GPL-3.0\"},\"contracts/facets/AccountFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {ECDSA} from \\\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\\\";\\nimport {UserOperation} from \\\"../aa-4337/interfaces/UserOperation.sol\\\";\\nimport {IEntryPoint} from \\\"../aa-4337/interfaces/IEntryPoint.sol\\\";\\nimport {BaseAccount} from \\\"../aa-4337/core/BaseAccount.sol\\\";\\nimport {LibAppStorage, BarzStorage} from \\\"../libraries/LibAppStorage.sol\\\";\\nimport {LibDiamond} from \\\"../libraries/LibDiamond.sol\\\";\\nimport {LibLoupe} from \\\"../libraries/LibLoupe.sol\\\";\\nimport {IFacetRegistry} from \\\"../infrastructure/interfaces/IFacetRegistry.sol\\\";\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\nimport {IVerificationFacet} from \\\"./interfaces/IVerificationFacet.sol\\\";\\nimport {IERC1271} from \\\"../interfaces/ERC/IERC1271.sol\\\";\\nimport {IAccountFacet} from \\\"./interfaces/IAccountFacet.sol\\\";\\n\\n/**\\n * @title Account Facet\\n * @dev Account module contract that provides the account features and initialization of signer\\n * compatible with EIP-1271 & EIP-4337\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract AccountFacet is IAccountFacet, BarzStorage, BaseAccount {\\n using ECDSA for bytes32;\\n\\n /**\\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\\n */\\n constructor() {\\n LibAppStorage.enforceAccountInitialize();\\n }\\n\\n /**\\n * @notice Returns the address of EntryPoint contract registered to Barz account\\n */\\n function entryPoint() public view override returns (IEntryPoint) {\\n return s.entryPoint;\\n }\\n\\n /**\\n * @notice Initializes the initial storage of the Barz contract.\\n * @dev This method can only be called during the initialization or signature migration.\\n * If the proxy contract was created without initialization, anyone can call initialize.\\n * Barz calls initialize in constructor in an atomic transaction during deployment\\n * @param _verificationFacet Facet contract handling the verificationi\\n * @param _anEntryPoint Entrypoint contract defined in EIP-4337 handling the flow of UserOp\\n * @param _facetRegistry Registry of Facets that hold all facet information\\n * @param _defaultFallBackHandler Middleware contract for default facets\\n * @param _ownerPublicKey Bytes of owner public key\\n */\\n function initialize(\\n address _verificationFacet,\\n address _anEntryPoint,\\n address _facetRegistry,\\n address _defaultFallBackHandler,\\n bytes calldata _ownerPublicKey\\n ) public override returns (uint256 initSuccess) {\\n LibAppStorage.enforceAccountInitialize();\\n s.entryPoint = IEntryPoint(_anEntryPoint);\\n s.facetRegistry = IFacetRegistry(_facetRegistry);\\n LibDiamond.diamondStorage().defaultFallbackHandler = IDiamondLoupe(\\n _defaultFallBackHandler\\n );\\n\\n _cutDiamondAccountFacet(_verificationFacet);\\n\\n bytes memory initCall = abi.encodeWithSignature(\\n \\\"initializeSigner(bytes)\\\",\\n _ownerPublicKey\\n );\\n // Every Verification Facet should comply with initializeSigner(bytes)\\n // to be compatible with the Barz contract(for initialization)\\n (bool success, bytes memory result) = _verificationFacet.delegatecall(\\n initCall\\n );\\n if (!success || uint256(bytes32(result)) != 1) {\\n revert AccountFacet__InitializationFailure();\\n }\\n\\n initSuccess = 1;\\n emit AccountInitialized(s.entryPoint, _ownerPublicKey);\\n }\\n\\n function _cutDiamondAccountFacet(address _verificationFacet) internal {\\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](1);\\n\\n bytes4 ownerVerificationFuncSelector = IVerificationFacet(\\n _verificationFacet\\n ).validateOwnerSignatureSelector();\\n\\n bytes4[] memory verificationFunctionSelectors = new bytes4[](3);\\n verificationFunctionSelectors[0] = IERC1271.isValidSignature.selector;\\n verificationFunctionSelectors[1] = ownerVerificationFuncSelector;\\n verificationFunctionSelectors[2] = IVerificationFacet.owner.selector;\\n cut[0] = IDiamondCut.FacetCut({\\n facetAddress: _verificationFacet,\\n action: IDiamondCut.FacetCutAction.Add,\\n functionSelectors: verificationFunctionSelectors\\n });\\n\\n LibDiamond.diamondCut(cut, address(0), \\\"\\\");\\n }\\n\\n /**\\n * @notice Calls the destination with inputted calldata and value from EntryPoint\\n * @dev This method executes the calldata coming from the EntryPoint.\\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\\n * @param _dest Address of destination where the call will be forwarded to\\n * @param _value Amount of native coin the owner is willing to send(e.g. ETH, BNB)\\n * @param _func Bytes of calldata to execute in the destination address\\n */\\n function execute(\\n address _dest,\\n uint256 _value,\\n bytes calldata _func\\n ) external override onlyWhenUnlocked {\\n _requireFromEntryPoint();\\n address restrictionsFacet = LibDiamond.restrictionsFacet();\\n if (restrictionsFacet == address(0)) _call(_dest, _value, _func);\\n else _callWithRestrictions(_dest, _value, _func, restrictionsFacet);\\n }\\n\\n /**\\n * @notice Batch calls the destination with inputted calldata and value from EntryPoint\\n * @dev This method batch executes the calldata coming from the EntryPoint.\\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\\n * @param _dest Array of addresses of destination where the call will be forwarded to\\n * @param _value Array of amount of native coin the owner is willing to send(e.g. ETH, BNB)\\n * @param _func Array of bytes of calldata to execute in the destination address\\n */\\n function executeBatch(\\n address[] calldata _dest,\\n uint256[] calldata _value,\\n bytes[] calldata _func\\n ) external override onlyWhenUnlocked {\\n _requireFromEntryPoint();\\n if (_dest.length != _func.length || _dest.length != _value.length)\\n revert AccountFacet__InvalidArrayLength();\\n address restrictionsFacet = LibDiamond.restrictionsFacet();\\n if (restrictionsFacet == address(0)) {\\n for (uint256 i; i < _dest.length; ) {\\n _call(_dest[i], _value[i], _func[i]);\\n unchecked {\\n ++i;\\n }\\n }\\n } else {\\n for (uint256 i; i < _dest.length; ) {\\n _callWithRestrictions(\\n _dest[i],\\n _value[i],\\n _func[i],\\n restrictionsFacet\\n );\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n }\\n\\n /**\\n * @notice Validates the signature field of UserOperation\\n * @dev This method validates if the signature of UserOp is indeed valid by delegating the call to Verification Facet\\n * Barz makes a call to the pre-registered Verification Facet address in App Storage\\n * @param _userOp UserOperation from owner to be validated\\n * @param _userOpHash Hash of UserOperation given from the EntryPoint contract\\n */\\n function _validateSignature(\\n UserOperation calldata _userOp,\\n bytes32 _userOpHash\\n ) internal override returns (uint256 validationData) {\\n // Get Facet with Function Selector\\n address facet = LibLoupe.facetAddress(s.validateOwnerSignatureSelector);\\n if (facet == address(0))\\n revert AccountFacet__NonExistentVerificationFacet();\\n\\n // Make function call to VerificationFacet\\n bytes memory validateCall = abi.encodeWithSelector(\\n s.validateOwnerSignatureSelector,\\n _userOp,\\n _userOpHash\\n );\\n (bool success, bytes memory result) = facet.delegatecall(validateCall);\\n if (!success) revert AccountFacet__CallNotSuccessful();\\n validationData = uint256(bytes32(result));\\n if (validationData == 0) emit VerificationSuccess(_userOpHash);\\n else emit VerificationFailure(_userOpHash);\\n }\\n\\n /**\\n * @notice Calls the target with the inputted value and calldata\\n * @dev This method is the actual function in Barz that makes a call with an arbitrary owner-given data\\n * @param _target Address of the destination contract which the call is getting forwarded to\\n * @param _value Amount of Native coin the owner is wanting to make in this call\\n * @param _data Calldata the owner is forwarding together in the call e.g. Swap/Token Transfer\\n */\\n function _call(\\n address _target,\\n uint256 _value,\\n bytes memory _data\\n ) internal {\\n (bool success, bytes memory result) = _target.call{value: _value}(\\n _data\\n );\\n if (!success) {\\n assembly {\\n revert(add(result, 32), mload(result))\\n }\\n }\\n }\\n\\n /**\\n * @notice Calls the target with the inputted value and calldata together with restrictions check\\n * @dev This method is the actual function in Barz that makes a call with an arbitrary owner-given data\\n * @param _target Address of the destination contract which the call is getting forwarded to\\n * @param _value Amount of Native coin the owner is wanting to make in this call\\n * @param _data Calldata the owner is forwarding together in the call e.g. Swap/Token Transfer\\n * @param _restrictionsFacet Address of Facet to validate restrictions\\n */\\n function _callWithRestrictions(\\n address _target,\\n uint256 _value,\\n bytes memory _data,\\n address _restrictionsFacet\\n ) internal {\\n // NOTE: No restrictions facet, so restriction validation passes\\n if (_checkRestrictions(_restrictionsFacet, _target, _value, _data) != 0)\\n revert AccountFacet__RestrictionsFailure();\\n\\n (bool success, bytes memory result) = _target.call{value: _value}(\\n _data\\n );\\n if (!success) {\\n assembly {\\n revert(add(result, 32), mload(result))\\n }\\n }\\n }\\n\\n /**\\n * @notice Checks restrictions if the restrictions facet exists\\n * @dev This method checks if the restrictions facet exists and makes a verification call to an array of restrictions facet\\n * @param _facet Address that holds the restrictions logic\\n * @param _target Address the call is getting forwarded to\\n * @param _value Amount of native coin the call is sending together with the call\\n * @param _data Calldata to trigger execution in target address\\n */\\n function _checkRestrictions(\\n address _facet,\\n address _target,\\n uint256 _value,\\n bytes memory _data\\n ) internal returns (uint256 result) {\\n bytes memory call = abi.encodeWithSignature(\\n \\\"verifyRestrictions(address,address,uint256,bytes)\\\",\\n address(this),\\n _target,\\n _value,\\n _data\\n );\\n (bool success, bytes memory response) = _facet.delegatecall(call);\\n if (!success) revert AccountFacet__RestrictionsFailure();\\n result = uint256(bytes32(response));\\n }\\n}\\n\",\"keccak256\":\"0xcd92bcdd447010880f78e57e213123269c9e023adfc0a540608daa127d8649ca\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/facets/interfaces/IAccountFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IEntryPoint} from \\\"../../aa-4337/interfaces/IEntryPoint.sol\\\";\\n\\n/**\\n * @title Account Facet Interface\\n * @dev Interface of module contract that provides the account features and init/unitialization of signer\\n * compatible with EIP-1271 & EIP-4337\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IAccountFacet {\\n event AccountInitialized(\\n IEntryPoint indexed entryPoint,\\n bytes indexed ownerPublicKey\\n );\\n // NOTE: Added Below Event\\n event VerificationSuccess(bytes32);\\n event VerificationFailure(bytes32);\\n\\n error AccountFacet__InitializationFailure();\\n error AccountFacet__RestrictionsFailure();\\n error AccountFacet__NonExistentVerificationFacet();\\n error AccountFacet__CallNotSuccessful();\\n error AccountFacet__InvalidArrayLength();\\n\\n function initialize(\\n address verificationFacet,\\n address anEntryPoint,\\n address facetRegistry,\\n address _defaultFallBack,\\n bytes calldata _ownerPublicKey\\n ) external returns (uint256);\\n\\n function execute(address dest, uint256 value, bytes calldata func) external;\\n\\n function executeBatch(\\n address[] calldata dest,\\n uint256[] calldata value,\\n bytes[] calldata func\\n ) external;\\n}\\n\",\"keccak256\":\"0x74a9cb0b8f2f4a5148e366a401a0354426c536c012c025025d07cc25a4cd5382\",\"license\":\"Apache-2.0\"},\"contracts/facets/interfaces/IVerificationFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {UserOperation} from \\\"../../aa-4337/interfaces/UserOperation.sol\\\";\\n\\n/**\\n * @title Verification Facet Interface\\n * @dev Implements logic for user ops signature verification\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\ninterface IVerificationFacet {\\n event SignerInitialized(bytes);\\n event SignerUninitialized();\\n\\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\\n error VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\\n error VerificationFacet__InitializationFailure();\\n error VerificationFacet__InvalidFacetMapping();\\n\\n function initializeSigner(bytes memory) external returns (uint256);\\n\\n function uninitializeSigner() external returns (uint256);\\n\\n function validateOwnerSignatureSelector() external view returns (bytes4);\\n\\n function owner() external view returns (bytes memory);\\n\\n function isValidKeyType(bytes calldata) external view returns (bool);\\n\\n function validateOwnerSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x72bc370a1d1b5a6d6bde67f5026733fd8f6ba434bb90e73b0bd8627fb1579928\",\"license\":\"Apache-2.0\"},\"contracts/infrastructure/interfaces/IFacetRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Registry Interface\\n * @dev Interface for Facet Registry contract to keep track of facets & function selectors addable to user wallets\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IFacetRegistry {\\n struct FacetRegistryConfig {\\n bytes4[] selectors;\\n mapping(bytes4 => FacetInfo) info;\\n }\\n struct FacetInfo {\\n bool exists;\\n uint128 index;\\n }\\n\\n event FacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] facetSelectors\\n );\\n event FacetFunctionSelectorsRemoved(address facet, bytes4[] facetSelectors);\\n\\n error FacetRegistry__FacetSelectorAlreadyRegistered();\\n error FacetRegistry__UnregisteredFacetSelector();\\n\\n function registerFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function removeFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function areFacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external view returns (bool);\\n\\n function isFacetFunctionSelectorRegistered(\\n address facet,\\n bytes4 facetSelector\\n ) external view returns (bool);\\n\\n function getFacetFunctionSelectors(\\n address facet\\n ) external view returns (bytes4[] memory);\\n}\\n\",\"keccak256\":\"0x6e6dd2cab346ef7c31230740ec48d2925e4a9ab24c2f2fb268baaf408dcf02ef\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC1271 {\\n function isValidSignature(\\n bytes32 hash,\\n bytes memory signature\\n ) external view returns (bytes4);\\n}\\n\",\"keccak256\":\"0xcdddb7d5641c9d3f2432dec7fd13fddb9ae1480f25c76c21511e2fa16b8bd422\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibAppStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {SafeCast} from \\\"@openzeppelin/contracts/utils/math/SafeCast.sol\\\";\\nimport {IEntryPoint} from \\\"../aa-4337/interfaces/IEntryPoint.sol\\\";\\nimport {IFacetRegistry} from \\\"../infrastructure/interfaces/IFacetRegistry.sol\\\";\\n\\n/*\\n * @title App Storage\\n * @dev App storage for Barz contract to prevent storage collision\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Lock {\\n uint64 release;\\n bytes4 locker;\\n}\\n\\nstruct InitializersStorage {\\n // NOTE: initialized is a variable to make sure the initialization is only done once.\\n uint8 signerInitialized;\\n uint8 accountInitialized;\\n uint8 restrictionsInitialized;\\n}\\n\\nstruct AppStorage {\\n mapping(uint256 => InitializersStorage) initStorage;\\n uint8 signerMigration;\\n bytes4 validateOwnerSignatureSelector;\\n IEntryPoint entryPoint;\\n IFacetRegistry facetRegistry;\\n mapping(uint256 => Lock) locks;\\n}\\n\\nlibrary LibAppStorage {\\n error LibAppStorage__AccountAlreadyUninitialized();\\n error LibAppStorage__AccountMustBeUninitialized();\\n error LibAppStorage__SignerAlreadyUninitialized();\\n error LibAppStorage__SignerMustBeUninitialized();\\n\\n function appStorage() internal pure returns (AppStorage storage ds) {\\n assembly {\\n ds.slot := 0\\n }\\n }\\n\\n function setSignerUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerAlreadyUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 0;\\n }\\n\\n function getValidateOwnerSignatureSelector()\\n internal\\n view\\n returns (bytes4 selector)\\n {\\n selector = appStorage().validateOwnerSignatureSelector;\\n }\\n\\n function setValidateOwnerSignatureSelector(\\n bytes4 _validateOwnerSignatureSelector\\n ) internal {\\n appStorage()\\n .validateOwnerSignatureSelector = _validateOwnerSignatureSelector;\\n }\\n\\n function enforceSignerInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerMustBeUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 1;\\n }\\n\\n function enforceAccountInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].accountInitialized) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n s.initStorage[0].accountInitialized = 1;\\n }\\n\\n function initiateSignerMigration() internal {\\n appStorage().signerMigration = 1;\\n }\\n\\n function enforceSignerMigration() internal view {\\n if (1 != appStorage().signerMigration) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n }\\n\\n function finalizeSignerMigration() internal {\\n appStorage().signerMigration = 0;\\n }\\n\\n function setLock(uint256 _releaseAfter, bytes4 _locker) internal {\\n appStorage().locks[0] = Lock(SafeCast.toUint64(_releaseAfter), _locker);\\n }\\n\\n function enforceRestrictionsInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__SignerMustBeUninitialized();\\n s.initStorage[0].restrictionsInitialized = 1;\\n }\\n\\n function setRestrictionsUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__AccountAlreadyUninitialized();\\n s.initStorage[0].restrictionsInitialized = 0;\\n }\\n}\\n\\ncontract BarzStorage {\\n AppStorage internal s;\\n modifier onlyWhenUnlocked() {\\n require(\\n uint64(block.timestamp) >= s.locks[0].release,\\n \\\"Account Locked\\\"\\n );\\n _;\\n }\\n modifier onlyWhenLocked() {\\n require(\\n uint64(block.timestamp) < s.locks[0].release,\\n \\\"Account Unlocked\\\"\\n );\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x48524007862a6ce0e07f645950613ce6513ce073c37a109c75019683d42bae27\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\\n bytes4(keccak256(\\\"verifyRestrictions(address,address,uint256,bytes)\\\"));\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // Default Fallback Handler of the barz.\\n IDiamondLoupe defaultFallbackHandler;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function enforceIsSelf() internal view {\\n require(msg.sender == address(this), \\\"LibDiamond: Caller not self\\\");\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n\\n unchecked {\\n facetIndex++;\\n }\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n\\n function restrictionsFacet() internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(\\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2cabdc00de859c3a3170ce3bda5d0e5fd3933d47ce904fd1585f9818b02572f8\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\nimport {LibDiamond} from \\\"./LibDiamond.sol\\\";\\n\\n/**\\n * @title LibLoupe\\n * @dev Internal Library to provide utility feature for reading the state of diamond facets\\n * Originally from Diamond's implementation of Mudgen(author of EIP-2535)\\n */\\nlibrary LibLoupe {\\n /// @notice Gets all facets and their selectors.\\n /// @return facets_ Facet\\n function facets()\\n internal\\n view\\n returns (IDiamondLoupe.Facet[] memory facets_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facets_ = new IDiamondLoupe.Facet[](ds.selectorCount);\\n uint16[] memory numFacetSelectors = new uint16[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facets_[facetIndex].facetAddress == facetAddress_) {\\n facets_[facetIndex].functionSelectors[\\n numFacetSelectors[facetIndex]\\n ] = selector;\\n // probably will never have more than 256 functions from one facet contract\\n require(numFacetSelectors[facetIndex] < 255);\\n numFacetSelectors[facetIndex]++;\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facets_[numFacets].facetAddress = facetAddress_;\\n facets_[numFacets].functionSelectors = new bytes4[](\\n ds.selectorCount\\n );\\n facets_[numFacets].functionSelectors[0] = selector;\\n numFacetSelectors[numFacets] = 1;\\n numFacets++;\\n }\\n }\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n uint256 numSelectors = numFacetSelectors[facetIndex];\\n bytes4[] memory selectors = facets_[facetIndex].functionSelectors;\\n // setting the number of selectors\\n assembly {\\n mstore(selectors, numSelectors)\\n }\\n }\\n // setting the number of facets\\n assembly {\\n mstore(facets_, numFacets)\\n }\\n }\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return _facetFunctionSelectors The selectors associated with a facet address.\\n function facetFunctionSelectors(\\n address _facet\\n ) internal view returns (bytes4[] memory _facetFunctionSelectors) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n uint256 numSelectors;\\n _facetFunctionSelectors = new bytes4[](ds.selectorCount);\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facet = address(bytes20(ds.facets[selector]));\\n if (_facet == facet) {\\n _facetFunctionSelectors[numSelectors] = selector;\\n numSelectors++;\\n }\\n }\\n }\\n // Set the number of selectors in the array\\n assembly {\\n mstore(_facetFunctionSelectors, numSelectors)\\n }\\n }\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n internal\\n view\\n returns (address[] memory facetAddresses_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetAddresses_ = new address[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facetAddress_ == facetAddresses_[facetIndex]) {\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facetAddresses_[numFacets] = facetAddress_;\\n numFacets++;\\n }\\n }\\n // Set the number of facet addresses in the array\\n assembly {\\n mstore(facetAddresses_, numFacets)\\n }\\n }\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(LibDiamond.diamondStorage().facets[_functionSelector])\\n );\\n }\\n}\\n\",\"keccak256\":\"0x0b11439c3cc657095e15ec2241fdcf67204b14001357b612fc5db4ff9e760a5a\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5061001961001e565b61008e565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb554610100900460ff1615610070576040516338fc28cb60e01b815260040160405180910390fd5b600080805260209190915260409020805461ff001916610100179055565b6129b6806200009e6000396000f3fe608060405234801561001057600080fd5b50600436106100725760003560e01c8063b0d691fe11610050578063b0d691fe146100c5578063b61d27f61461010c578063d087d2881461011f57600080fd5b80633a871cdd1461007757806347e1da2a1461009d5780634a936417146100b2575b600080fd5b61008a610085366004611fb5565b610127565b6040519081526020015b60405180910390f35b6100b06100ab366004612055565b61014d565b005b61008a6100c036600461215a565b610450565b60015465010000000000900473ffffffffffffffffffffffffffffffffffffffff1660405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610094565b6100b061011a3660046121ce565b6106d0565b61008a61089d565b600061013161095e565b61013b8484610a16565b905061014682610c5d565b9392505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff9081164290911610156101f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064015b60405180910390fd5b6101fd61095e565b848114158061020c5750848314155b15610243576040517fdde5716100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006102b87fac87185d000000000000000000000000000000000000000000000000000000006000527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020527f6d9f2463c8c0d8cb8be556a773ab21d4321328909a1725f2ef7cae0c320e95da5460601c90565b905073ffffffffffffffffffffffffffffffffffffffff811661038f5760005b86811015610389576103818888838181106102f5576102f5612228565b905060200201602081019061030a9190612257565b87878481811061031c5761031c612228565b9050602002013586868581811061033557610335612228565b90506020028101906103479190612272565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610cc892505050565b6001016102d8565b50610447565b60005b868110156104455761043d8888838181106103af576103af612228565b90506020020160208101906103c49190612257565b8787848181106103d6576103d6612228565b905060200201358686858181106103ef576103ef612228565b90506020028101906104019190612272565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250889250610d45915050565b600101610392565b505b50505050505050565b600061045a610e0d565b6001805473ffffffffffffffffffffffffffffffffffffffff88811665010000000000027fffffffffffffff0000000000000000000000000000000000000000ffffffffff90921691909117909155600280548783167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216179091557f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd492380549287169290911691909117905561051187610eb3565b60008383604051602401610526929190612320565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fcd9b47e40000000000000000000000000000000000000000000000000000000017905251909150600090819073ffffffffffffffffffffffffffffffffffffffff8b16906105c8908590612360565b600060405180830381855af49150503d8060008114610603576040519150601f19603f3d011682016040523d82523d6000602084013e610608565b606091505b5091509150811580610623575061061e8161237c565b600114155b1561065a576040517f1602372100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60019350858560405161066e9291906123c1565b60405190819003812060015490916501000000000090910473ffffffffffffffffffffffffffffffffffffffff16907fd429ff0b972be4ae725700a373d05007287994e4c86cb83315b43ffa85b595fd90600090a35050509695505050505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610773576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064016101ec565b61077b61095e565b60006107f07fac87185d000000000000000000000000000000000000000000000000000000006000527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020527f6d9f2463c8c0d8cb8be556a773ab21d4321328909a1725f2ef7cae0c320e95da5460601c90565b905073ffffffffffffffffffffffffffffffffffffffff81166108535761084e858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610cc892505050565b610896565b610896858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250879250610d45915050565b5050505050565b60015460009065010000000000900473ffffffffffffffffffffffffffffffffffffffff166040517f35567e1a0000000000000000000000000000000000000000000000000000000081523060048201526000602482015273ffffffffffffffffffffffffffffffffffffffff91909116906335567e1a90604401602060405180830381865afa158015610935573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061095991906123d1565b905090565b60015465010000000000900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a14576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f6163636f756e743a206e6f742066726f6d20456e747279506f696e740000000060448201526064016101ec565b565b600154610100900460e01b7fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604081205460601c80610aab576040517f6eb2360200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600154604051600091610100900460e01b90610acd908790879060240161244e565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090506000808373ffffffffffffffffffffffffffffffffffffffff1683604051610b549190612360565b600060405180830381855af49150503d8060008114610b8f576040519150601f19603f3d011682016040523d82523d6000602084013e610b94565b606091505b509150915081610bd0576040517f3cbbb65000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610bd98161237c565b94506000859003610c1c576040518681527f19e781916118c373dadcb7776fae0a2dbb6bbdeedae143ce68031e22801ef8659060200160405180910390a1610c50565b6040518681527fbbfee2df7f28b899771f1015dc85d7840ff9f6162f23f6aa99686e8fbd2ce1319060200160405180910390a15b5050505092915050565b50565b8015610c5a5760405160009033907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90849084818181858888f193505050503d8060008114610896576040519150601f19603f3d011682016040523d82523d6000602084013e610896565b6000808473ffffffffffffffffffffffffffffffffffffffff168484604051610cf19190612360565b60006040518083038185875af1925050503d8060008114610d2e576040519150601f19603f3d011682016040523d82523d6000602084013e610d33565b606091505b50915091508161089657805160208201fd5b610d5181858585611117565b15610d88576040517f01f595e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000808573ffffffffffffffffffffffffffffffffffffffff168585604051610db19190612360565b60006040518083038185875af1925050503d8060008114610dee576040519150601f19603f3d011682016040523d82523d6000602084013e610df3565b606091505b509150915081610e0557805160208201fd5b505050505050565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb554610100900460ff1615610e78576040517f38fc28cb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100179055565b604080516001808252818301909252600091816020015b60408051606080820183526000808352602083015291810191909152815260200190600190039081610eca57905050905060008273ffffffffffffffffffffffffffffffffffffffff16633253960f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f6c9190612592565b604080516003808252608082019092529192506000919060208201606080368337019050509050631626ba7e60e01b81600081518110610fae57610fae612228565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681525050818160018151811061100e5761100e612228565b7fffffffff000000000000000000000000000000000000000000000000000000009092166020928302919091019091015280517f8da5cb5b00000000000000000000000000000000000000000000000000000000908290600290811061107657611076612228565b7fffffffff00000000000000000000000000000000000000000000000000000000909216602092830291909101820152604080516060810190915273ffffffffffffffffffffffffffffffffffffffff861681529081016000815260200182815250836000815181106110eb576110eb612228565b602002602001018190525061111183600060405180602001604052806000815250611264565b50505050565b60008030858585604051602401611131949392919061264d565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fac87185d0000000000000000000000000000000000000000000000000000000017905251909150600090819073ffffffffffffffffffffffffffffffffffffffff8916906111d3908590612360565b600060405180830381855af49150503d806000811461120e576040519150601f19603f3d011682016040523d82523d6000602084013e611213565b606091505b50915091508161124f576040517f01f595e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6112588161237c565b98975050505050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921547f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff8116908190600090600716156112d35750600381901c60009081526001840160205260409020545b60005b87518110156113505761134383838a84815181106112f6576112f6612228565b6020026020010151600001518b858151811061131457611314612228565b6020026020010151602001518c868151811061133257611332612228565b6020026020010151604001516113f0565b90935091506001016112d6565b50828214611389576002840180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff84161790555b60078216156113ab57600382901c600090815260018501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb6738787876040516113de93929190612696565b60405180910390a16104478686611e81565b600080807f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f905060008451116114a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f2063757400000000000000000000000000000000000000000060648201526084016101ec565b60008560028111156114bc576114bc6125d4565b0361168c576114e38660405180606001604052806024815260200161290d60249139611f7a565b60005b845181101561168657600085828151811061150357611503612228565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c156115d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c726561647920657869737473000000000000000000000060648201526084016101ec565b7fffffffff0000000000000000000000000000000000000000000000000000000080831660008181526020879052604090207fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608d901b168e17905560e060058e901b811692831c199c909c1690821c179a81900361166a5760038c901c600090815260018601602052604081209b909b555b8b6116748161282d565b9c5050600190930192506114e6915050565b50611e75565b60018560028111156116a0576116a06125d4565b03611990576116c78660405180606001604052806028815260200161295960289139611f7a565b60005b84518110156116865760008582815181106116e7576116e7612228565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c3081036117bc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4c69624469616d6f6e644375743a2043616e2774207265706c61636520696d6d60448201527f757461626c652066756e6374696f6e000000000000000000000000000000000060648201526084016101ec565b8973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611877576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e000000000000000060648201526084016101ec565b73ffffffffffffffffffffffffffffffffffffffff811661191a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e207468617420646f65736e2774206578697374000000000000000060648201526084016101ec565b507fffffffff0000000000000000000000000000000000000000000000000000000090911660009081526020849052604090206bffffffffffffffffffffffff919091167fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608a901b161790556001016116ca565b60028560028111156119a4576119a46125d4565b03611ded5773ffffffffffffffffffffffffffffffffffffffff861615611a4d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d75737420626520616464726573732830290000000000000000000060648201526084016101ec565b600388901c6007891660005b8651811015611dcd5760008a9003611a955782611a7581612865565b60008181526001870160205260409020549b50935060079250611aa39050565b81611a9f81612865565b9250505b6000806000808a8581518110611abb57611abb612228565b6020908102919091018101517fffffffff0000000000000000000000000000000000000000000000000000000081166000908152918a9052604090912054909150606081901c611b8d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e277420657869737400000000000000000060648201526084016101ec565b30606082901c03611c20576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e00000000000000000000000000000000000060648201526084016101ec565b600587901b8f901b94507fffffffff0000000000000000000000000000000000000000000000000000000080861690831614611cbe577fffffffff000000000000000000000000000000000000000000000000000000008516600090815260208a90526040902080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff83161790555b7fffffffff0000000000000000000000000000000000000000000000000000000091909116600090815260208990526040812055600381901c611fff16925060051b60e0169050858214611d53576000828152600188016020526040902080547fffffffff0000000000000000000000000000000000000000000000000000000080841c19909116908516831c179055611da4565b80837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c817fffffffff0000000000000000000000000000000000000000000000000000000060001b901c198e16179c505b84600003611dc257600086815260018801602052604081208190559c505b505050600101611a59565b5080611dda83600861289a565b611de491906128b7565b99505050611e75565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560448201527f74416374696f6e0000000000000000000000000000000000000000000000000060648201526084016101ec565b50959694955050505050565b73ffffffffffffffffffffffffffffffffffffffff8216611ea0575050565b611ec28260405180606001604052806028815260200161293160289139611f7a565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051611eea9190612360565b600060405180830381855af49150503d8060008114611f25576040519150601f19603f3d011682016040523d82523d6000602084013e611f2a565b606091505b50915091508161111157805115611f445780518082602001fd5b83836040517f192105d70000000000000000000000000000000000000000000000000000000081526004016101ec9291906128ca565b813b8181611111576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101ec91906128f9565b600080600060608486031215611fca57600080fd5b833567ffffffffffffffff811115611fe157600080fd5b84016101608187031215611ff457600080fd5b95602085013595506040909401359392505050565b60008083601f84011261201b57600080fd5b50813567ffffffffffffffff81111561203357600080fd5b6020830191508360208260051b850101111561204e57600080fd5b9250929050565b6000806000806000806060878903121561206e57600080fd5b863567ffffffffffffffff8082111561208657600080fd5b6120928a838b01612009565b909850965060208901359150808211156120ab57600080fd5b6120b78a838b01612009565b909650945060408901359150808211156120d057600080fd5b506120dd89828a01612009565b979a9699509497509295939492505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461211357600080fd5b919050565b60008083601f84011261212a57600080fd5b50813567ffffffffffffffff81111561214257600080fd5b60208301915083602082850101111561204e57600080fd5b60008060008060008060a0878903121561217357600080fd5b61217c876120ef565b955061218a602088016120ef565b9450612198604088016120ef565b93506121a6606088016120ef565b9250608087013567ffffffffffffffff8111156121c257600080fd5b6120dd89828a01612118565b600080600080606085870312156121e457600080fd5b6121ed856120ef565b935060208501359250604085013567ffffffffffffffff81111561221057600080fd5b61221c87828801612118565b95989497509550505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561226957600080fd5b610146826120ef565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126122a757600080fd5b83018035915067ffffffffffffffff8211156122c257600080fd5b60200191503681900382131561204e57600080fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b6020815260006123346020830184866122d7565b949350505050565b60005b8381101561235757818101518382015260200161233f565b50506000910152565b6000825161237281846020870161233c565b9190910192915050565b805160208083015191908110156123bb577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8160200360031b1b821691505b50919050565b8183823760009101908152919050565b6000602082840312156123e357600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261241f57600080fd5b830160208101925035905067ffffffffffffffff81111561243f57600080fd5b80360382131561204e57600080fd5b6040815261247c60408201612462856120ef565b73ffffffffffffffffffffffffffffffffffffffff169052565b60208301356060820152600061249560408501856123ea565b6101608060808601526124ad6101a0860183856122d7565b92506124bc60608801886123ea565b92507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0808786030160a08801526124f48585846122d7565b9450608089013560c088015260a089013560e0880152610100935060c089013584880152610120915060e089013582880152610140848a01358189015261253d838b018b6123ea565b955092508188870301848901526125558686856122d7565b9550612563818b018b6123ea565b9550935050808786030161018088015250506125808383836122d7565b93505050508260208301529392505050565b6000602082840312156125a457600080fd5b81517fffffffff000000000000000000000000000000000000000000000000000000008116811461014657600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6000815180845261261b81602086016020860161233c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600073ffffffffffffffffffffffffffffffffffffffff80871683528086166020840152508360408301526080606083015261268c6080830184612603565b9695505050505050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b848110156127c1577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808a8503018652815188850173ffffffffffffffffffffffffffffffffffffffff82511686528482015160038110612748577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b808310156127ac5783517fffffffff0000000000000000000000000000000000000000000000000000000016825292860192600192909201919086019061276a565b509785019795505050908201906001016126bf565b505073ffffffffffffffffffffffffffffffffffffffff8a169088015286810360408801526127f08189612603565b9a9950505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361285e5761285e6127fe565b5060010190565b600081612874576128746127fe565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b80820281158282048414176128b1576128b16127fe565b92915050565b808201808211156128b1576128b16127fe565b73ffffffffffffffffffffffffffffffffffffffff831681526040602082015260006123346040830184612603565b602081526000610146602083018461260356fe4c69624469616d6f6e644375743a2041646420666163657420686173206e6f20636f64654c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a205265706c61636520666163657420686173206e6f20636f6465a2646970667358221220a952f19990a20474450919a2df9ddff4430a71350892e0954f2bb073575ad64864736f6c63430008150033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100725760003560e01c8063b0d691fe11610050578063b0d691fe146100c5578063b61d27f61461010c578063d087d2881461011f57600080fd5b80633a871cdd1461007757806347e1da2a1461009d5780634a936417146100b2575b600080fd5b61008a610085366004611fb5565b610127565b6040519081526020015b60405180910390f35b6100b06100ab366004612055565b61014d565b005b61008a6100c036600461215a565b610450565b60015465010000000000900473ffffffffffffffffffffffffffffffffffffffff1660405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610094565b6100b061011a3660046121ce565b6106d0565b61008a61089d565b600061013161095e565b61013b8484610a16565b905061014682610c5d565b9392505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff9081164290911610156101f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064015b60405180910390fd5b6101fd61095e565b848114158061020c5750848314155b15610243576040517fdde5716100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006102b87fac87185d000000000000000000000000000000000000000000000000000000006000527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020527f6d9f2463c8c0d8cb8be556a773ab21d4321328909a1725f2ef7cae0c320e95da5460601c90565b905073ffffffffffffffffffffffffffffffffffffffff811661038f5760005b86811015610389576103818888838181106102f5576102f5612228565b905060200201602081019061030a9190612257565b87878481811061031c5761031c612228565b9050602002013586868581811061033557610335612228565b90506020028101906103479190612272565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610cc892505050565b6001016102d8565b50610447565b60005b868110156104455761043d8888838181106103af576103af612228565b90506020020160208101906103c49190612257565b8787848181106103d6576103d6612228565b905060200201358686858181106103ef576103ef612228565b90506020028101906104019190612272565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250889250610d45915050565b600101610392565b505b50505050505050565b600061045a610e0d565b6001805473ffffffffffffffffffffffffffffffffffffffff88811665010000000000027fffffffffffffff0000000000000000000000000000000000000000ffffffffff90921691909117909155600280548783167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216179091557f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd492380549287169290911691909117905561051187610eb3565b60008383604051602401610526929190612320565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fcd9b47e40000000000000000000000000000000000000000000000000000000017905251909150600090819073ffffffffffffffffffffffffffffffffffffffff8b16906105c8908590612360565b600060405180830381855af49150503d8060008114610603576040519150601f19603f3d011682016040523d82523d6000602084013e610608565b606091505b5091509150811580610623575061061e8161237c565b600114155b1561065a576040517f1602372100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60019350858560405161066e9291906123c1565b60405190819003812060015490916501000000000090910473ffffffffffffffffffffffffffffffffffffffff16907fd429ff0b972be4ae725700a373d05007287994e4c86cb83315b43ffa85b595fd90600090a35050509695505050505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610773576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064016101ec565b61077b61095e565b60006107f07fac87185d000000000000000000000000000000000000000000000000000000006000527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020527f6d9f2463c8c0d8cb8be556a773ab21d4321328909a1725f2ef7cae0c320e95da5460601c90565b905073ffffffffffffffffffffffffffffffffffffffff81166108535761084e858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610cc892505050565b610896565b610896858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250879250610d45915050565b5050505050565b60015460009065010000000000900473ffffffffffffffffffffffffffffffffffffffff166040517f35567e1a0000000000000000000000000000000000000000000000000000000081523060048201526000602482015273ffffffffffffffffffffffffffffffffffffffff91909116906335567e1a90604401602060405180830381865afa158015610935573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061095991906123d1565b905090565b60015465010000000000900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a14576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f6163636f756e743a206e6f742066726f6d20456e747279506f696e740000000060448201526064016101ec565b565b600154610100900460e01b7fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604081205460601c80610aab576040517f6eb2360200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600154604051600091610100900460e01b90610acd908790879060240161244e565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090506000808373ffffffffffffffffffffffffffffffffffffffff1683604051610b549190612360565b600060405180830381855af49150503d8060008114610b8f576040519150601f19603f3d011682016040523d82523d6000602084013e610b94565b606091505b509150915081610bd0576040517f3cbbb65000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610bd98161237c565b94506000859003610c1c576040518681527f19e781916118c373dadcb7776fae0a2dbb6bbdeedae143ce68031e22801ef8659060200160405180910390a1610c50565b6040518681527fbbfee2df7f28b899771f1015dc85d7840ff9f6162f23f6aa99686e8fbd2ce1319060200160405180910390a15b5050505092915050565b50565b8015610c5a5760405160009033907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90849084818181858888f193505050503d8060008114610896576040519150601f19603f3d011682016040523d82523d6000602084013e610896565b6000808473ffffffffffffffffffffffffffffffffffffffff168484604051610cf19190612360565b60006040518083038185875af1925050503d8060008114610d2e576040519150601f19603f3d011682016040523d82523d6000602084013e610d33565b606091505b50915091508161089657805160208201fd5b610d5181858585611117565b15610d88576040517f01f595e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000808573ffffffffffffffffffffffffffffffffffffffff168585604051610db19190612360565b60006040518083038185875af1925050503d8060008114610dee576040519150601f19603f3d011682016040523d82523d6000602084013e610df3565b606091505b509150915081610e0557805160208201fd5b505050505050565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb554610100900460ff1615610e78576040517f38fc28cb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100179055565b604080516001808252818301909252600091816020015b60408051606080820183526000808352602083015291810191909152815260200190600190039081610eca57905050905060008273ffffffffffffffffffffffffffffffffffffffff16633253960f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f6c9190612592565b604080516003808252608082019092529192506000919060208201606080368337019050509050631626ba7e60e01b81600081518110610fae57610fae612228565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681525050818160018151811061100e5761100e612228565b7fffffffff000000000000000000000000000000000000000000000000000000009092166020928302919091019091015280517f8da5cb5b00000000000000000000000000000000000000000000000000000000908290600290811061107657611076612228565b7fffffffff00000000000000000000000000000000000000000000000000000000909216602092830291909101820152604080516060810190915273ffffffffffffffffffffffffffffffffffffffff861681529081016000815260200182815250836000815181106110eb576110eb612228565b602002602001018190525061111183600060405180602001604052806000815250611264565b50505050565b60008030858585604051602401611131949392919061264d565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fac87185d0000000000000000000000000000000000000000000000000000000017905251909150600090819073ffffffffffffffffffffffffffffffffffffffff8916906111d3908590612360565b600060405180830381855af49150503d806000811461120e576040519150601f19603f3d011682016040523d82523d6000602084013e611213565b606091505b50915091508161124f576040517f01f595e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6112588161237c565b98975050505050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921547f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff8116908190600090600716156112d35750600381901c60009081526001840160205260409020545b60005b87518110156113505761134383838a84815181106112f6576112f6612228565b6020026020010151600001518b858151811061131457611314612228565b6020026020010151602001518c868151811061133257611332612228565b6020026020010151604001516113f0565b90935091506001016112d6565b50828214611389576002840180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff84161790555b60078216156113ab57600382901c600090815260018501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb6738787876040516113de93929190612696565b60405180910390a16104478686611e81565b600080807f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f905060008451116114a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f2063757400000000000000000000000000000000000000000060648201526084016101ec565b60008560028111156114bc576114bc6125d4565b0361168c576114e38660405180606001604052806024815260200161290d60249139611f7a565b60005b845181101561168657600085828151811061150357611503612228565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c156115d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c726561647920657869737473000000000000000000000060648201526084016101ec565b7fffffffff0000000000000000000000000000000000000000000000000000000080831660008181526020879052604090207fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608d901b168e17905560e060058e901b811692831c199c909c1690821c179a81900361166a5760038c901c600090815260018601602052604081209b909b555b8b6116748161282d565b9c5050600190930192506114e6915050565b50611e75565b60018560028111156116a0576116a06125d4565b03611990576116c78660405180606001604052806028815260200161295960289139611f7a565b60005b84518110156116865760008582815181106116e7576116e7612228565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c3081036117bc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4c69624469616d6f6e644375743a2043616e2774207265706c61636520696d6d60448201527f757461626c652066756e6374696f6e000000000000000000000000000000000060648201526084016101ec565b8973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611877576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e000000000000000060648201526084016101ec565b73ffffffffffffffffffffffffffffffffffffffff811661191a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e207468617420646f65736e2774206578697374000000000000000060648201526084016101ec565b507fffffffff0000000000000000000000000000000000000000000000000000000090911660009081526020849052604090206bffffffffffffffffffffffff919091167fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608a901b161790556001016116ca565b60028560028111156119a4576119a46125d4565b03611ded5773ffffffffffffffffffffffffffffffffffffffff861615611a4d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d75737420626520616464726573732830290000000000000000000060648201526084016101ec565b600388901c6007891660005b8651811015611dcd5760008a9003611a955782611a7581612865565b60008181526001870160205260409020549b50935060079250611aa39050565b81611a9f81612865565b9250505b6000806000808a8581518110611abb57611abb612228565b6020908102919091018101517fffffffff0000000000000000000000000000000000000000000000000000000081166000908152918a9052604090912054909150606081901c611b8d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e277420657869737400000000000000000060648201526084016101ec565b30606082901c03611c20576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e00000000000000000000000000000000000060648201526084016101ec565b600587901b8f901b94507fffffffff0000000000000000000000000000000000000000000000000000000080861690831614611cbe577fffffffff000000000000000000000000000000000000000000000000000000008516600090815260208a90526040902080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff83161790555b7fffffffff0000000000000000000000000000000000000000000000000000000091909116600090815260208990526040812055600381901c611fff16925060051b60e0169050858214611d53576000828152600188016020526040902080547fffffffff0000000000000000000000000000000000000000000000000000000080841c19909116908516831c179055611da4565b80837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c817fffffffff0000000000000000000000000000000000000000000000000000000060001b901c198e16179c505b84600003611dc257600086815260018801602052604081208190559c505b505050600101611a59565b5080611dda83600861289a565b611de491906128b7565b99505050611e75565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560448201527f74416374696f6e0000000000000000000000000000000000000000000000000060648201526084016101ec565b50959694955050505050565b73ffffffffffffffffffffffffffffffffffffffff8216611ea0575050565b611ec28260405180606001604052806028815260200161293160289139611f7a565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051611eea9190612360565b600060405180830381855af49150503d8060008114611f25576040519150601f19603f3d011682016040523d82523d6000602084013e611f2a565b606091505b50915091508161111157805115611f445780518082602001fd5b83836040517f192105d70000000000000000000000000000000000000000000000000000000081526004016101ec9291906128ca565b813b8181611111576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101ec91906128f9565b600080600060608486031215611fca57600080fd5b833567ffffffffffffffff811115611fe157600080fd5b84016101608187031215611ff457600080fd5b95602085013595506040909401359392505050565b60008083601f84011261201b57600080fd5b50813567ffffffffffffffff81111561203357600080fd5b6020830191508360208260051b850101111561204e57600080fd5b9250929050565b6000806000806000806060878903121561206e57600080fd5b863567ffffffffffffffff8082111561208657600080fd5b6120928a838b01612009565b909850965060208901359150808211156120ab57600080fd5b6120b78a838b01612009565b909650945060408901359150808211156120d057600080fd5b506120dd89828a01612009565b979a9699509497509295939492505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461211357600080fd5b919050565b60008083601f84011261212a57600080fd5b50813567ffffffffffffffff81111561214257600080fd5b60208301915083602082850101111561204e57600080fd5b60008060008060008060a0878903121561217357600080fd5b61217c876120ef565b955061218a602088016120ef565b9450612198604088016120ef565b93506121a6606088016120ef565b9250608087013567ffffffffffffffff8111156121c257600080fd5b6120dd89828a01612118565b600080600080606085870312156121e457600080fd5b6121ed856120ef565b935060208501359250604085013567ffffffffffffffff81111561221057600080fd5b61221c87828801612118565b95989497509550505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561226957600080fd5b610146826120ef565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126122a757600080fd5b83018035915067ffffffffffffffff8211156122c257600080fd5b60200191503681900382131561204e57600080fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b6020815260006123346020830184866122d7565b949350505050565b60005b8381101561235757818101518382015260200161233f565b50506000910152565b6000825161237281846020870161233c565b9190910192915050565b805160208083015191908110156123bb577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8160200360031b1b821691505b50919050565b8183823760009101908152919050565b6000602082840312156123e357600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261241f57600080fd5b830160208101925035905067ffffffffffffffff81111561243f57600080fd5b80360382131561204e57600080fd5b6040815261247c60408201612462856120ef565b73ffffffffffffffffffffffffffffffffffffffff169052565b60208301356060820152600061249560408501856123ea565b6101608060808601526124ad6101a0860183856122d7565b92506124bc60608801886123ea565b92507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0808786030160a08801526124f48585846122d7565b9450608089013560c088015260a089013560e0880152610100935060c089013584880152610120915060e089013582880152610140848a01358189015261253d838b018b6123ea565b955092508188870301848901526125558686856122d7565b9550612563818b018b6123ea565b9550935050808786030161018088015250506125808383836122d7565b93505050508260208301529392505050565b6000602082840312156125a457600080fd5b81517fffffffff000000000000000000000000000000000000000000000000000000008116811461014657600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6000815180845261261b81602086016020860161233c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600073ffffffffffffffffffffffffffffffffffffffff80871683528086166020840152508360408301526080606083015261268c6080830184612603565b9695505050505050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b848110156127c1577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808a8503018652815188850173ffffffffffffffffffffffffffffffffffffffff82511686528482015160038110612748577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b808310156127ac5783517fffffffff0000000000000000000000000000000000000000000000000000000016825292860192600192909201919086019061276a565b509785019795505050908201906001016126bf565b505073ffffffffffffffffffffffffffffffffffffffff8a169088015286810360408801526127f08189612603565b9a9950505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361285e5761285e6127fe565b5060010190565b600081612874576128746127fe565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b80820281158282048414176128b1576128b16127fe565b92915050565b808201808211156128b1576128b16127fe565b73ffffffffffffffffffffffffffffffffffffffff831681526040602082015260006123346040830184612603565b602081526000610146602083018461260356fe4c69624469616d6f6e644375743a2041646420666163657420686173206e6f20636f64654c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a205265706c61636520666163657420686173206e6f20636f6465a2646970667358221220a952f19990a20474450919a2df9ddff4430a71350892e0954f2bb073575ad64864736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "Account module contract that provides the account features and initialization of signer compatible with EIP-1271 & EIP-4337", + "kind": "dev", + "methods": { + "execute(address,uint256,bytes)": { + "details": "This method executes the calldata coming from the EntryPoint. Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)", + "params": { + "_dest": "Address of destination where the call will be forwarded to", + "_func": "Bytes of calldata to execute in the destination address", + "_value": "Amount of native coin the owner is willing to send(e.g. ETH, BNB)" + } + }, + "executeBatch(address[],uint256[],bytes[])": { + "details": "This method batch executes the calldata coming from the EntryPoint. Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)", + "params": { + "_dest": "Array of addresses of destination where the call will be forwarded to", + "_func": "Array of bytes of calldata to execute in the destination address", + "_value": "Array of amount of native coin the owner is willing to send(e.g. ETH, BNB)" + } + }, + "initialize(address,address,address,address,bytes)": { + "details": "This method can only be called during the initialization or signature migration. If the proxy contract was created without initialization, anyone can call initialize. Barz calls initialize in constructor in an atomic transaction during deployment", + "params": { + "_anEntryPoint": "Entrypoint contract defined in EIP-4337 handling the flow of UserOp", + "_defaultFallBackHandler": "Middleware contract for default facets", + "_facetRegistry": "Registry of Facets that hold all facet information", + "_ownerPublicKey": "Bytes of owner public key", + "_verificationFacet": "Facet contract handling the verificationi" + } + } + }, + "title": "Account Facet", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "constructor": { + "notice": "This constructor ensures that this contract can only be used as singleton for Proxy contracts" + }, + "entryPoint()": { + "notice": "Returns the address of EntryPoint contract registered to Barz account" + }, + "execute(address,uint256,bytes)": { + "notice": "Calls the destination with inputted calldata and value from EntryPoint" + }, + "executeBatch(address[],uint256[],bytes[])": { + "notice": "Batch calls the destination with inputted calldata and value from EntryPoint" + }, + "getNonce()": { + "notice": "Return the account nonce. This method returns the next sequential nonce. For a nonce of a specific key, use `entrypoint.getNonce(account, key)`" + }, + "initialize(address,address,address,address,bytes)": { + "notice": "Initializes the initial storage of the Barz contract." + }, + "validateUserOp((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256)": { + "notice": "Validate user's signature and nonce. subclass doesn't need to override this method. Instead, it should override the specific internal validation methods." + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 27866, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "s", + "offset": 0, + "slot": "0", + "type": "t_struct(AppStorage)27613_storage" + } + ], + "types": { + "t_bytes4": { + "encoding": "inplace", + "label": "bytes4", + "numberOfBytes": "4" + }, + "t_contract(IEntryPoint)12286": { + "encoding": "inplace", + "label": "contract IEntryPoint", + "numberOfBytes": "20" + }, + "t_contract(IFacetRegistry)26148": { + "encoding": "inplace", + "label": "contract IFacetRegistry", + "numberOfBytes": "20" + }, + "t_mapping(t_uint256,t_struct(InitializersStorage)27592_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => struct InitializersStorage)", + "numberOfBytes": "32", + "value": "t_struct(InitializersStorage)27592_storage" + }, + "t_mapping(t_uint256,t_struct(Lock)27585_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => struct Lock)", + "numberOfBytes": "32", + "value": "t_struct(Lock)27585_storage" + }, + "t_struct(AppStorage)27613_storage": { + "encoding": "inplace", + "label": "struct AppStorage", + "members": [ + { + "astId": 27597, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "initStorage", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_uint256,t_struct(InitializersStorage)27592_storage)" + }, + { + "astId": 27599, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "signerMigration", + "offset": 0, + "slot": "1", + "type": "t_uint8" + }, + { + "astId": 27601, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "validateOwnerSignatureSelector", + "offset": 1, + "slot": "1", + "type": "t_bytes4" + }, + { + "astId": 27604, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "entryPoint", + "offset": 5, + "slot": "1", + "type": "t_contract(IEntryPoint)12286" + }, + { + "astId": 27607, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "facetRegistry", + "offset": 0, + "slot": "2", + "type": "t_contract(IFacetRegistry)26148" + }, + { + "astId": 27612, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "locks", + "offset": 0, + "slot": "3", + "type": "t_mapping(t_uint256,t_struct(Lock)27585_storage)" + } + ], + "numberOfBytes": "128" + }, + "t_struct(InitializersStorage)27592_storage": { + "encoding": "inplace", + "label": "struct InitializersStorage", + "members": [ + { + "astId": 27587, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "signerInitialized", + "offset": 0, + "slot": "0", + "type": "t_uint8" + }, + { + "astId": 27589, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "accountInitialized", + "offset": 1, + "slot": "0", + "type": "t_uint8" + }, + { + "astId": 27591, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "restrictionsInitialized", + "offset": 2, + "slot": "0", + "type": "t_uint8" + } + ], + "numberOfBytes": "32" + }, + "t_struct(Lock)27585_storage": { + "encoding": "inplace", + "label": "struct Lock", + "members": [ + { + "astId": 27582, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "release", + "offset": 0, + "slot": "0", + "type": "t_uint64" + }, + { + "astId": 27584, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "locker", + "offset": 8, + "slot": "0", + "type": "t_bytes4" + } + ], + "numberOfBytes": "32" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint64": { + "encoding": "inplace", + "label": "uint64", + "numberOfBytes": "8" + }, + "t_uint8": { + "encoding": "inplace", + "label": "uint8", + "numberOfBytes": "1" + } + } + } +} \ No newline at end of file diff --git a/deployments/linea/BarzFactory.json b/deployments/linea/BarzFactory.json new file mode 100644 index 0000000..1a48c0f --- /dev/null +++ b/deployments/linea/BarzFactory.json @@ -0,0 +1,318 @@ +{ + "address": "0x729c310186a57833f622630a16d13f710b83272a", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_accountFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_entryPoint", + "type": "address" + }, + { + "internalType": "address", + "name": "_facetRegistry", + "type": "address" + }, + { + "internalType": "address", + "name": "_defaultFallback", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "BarzDeployed", + "type": "event" + }, + { + "inputs": [], + "name": "accountFacet", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_verificationFacet", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_owner", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "_salt", + "type": "uint256" + } + ], + "name": "createAccount", + "outputs": [ + { + "internalType": "contract Barz", + "name": "barz", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "defaultFallback", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "entryPoint", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetRegistry", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_verificationFacet", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_owner", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "_salt", + "type": "uint256" + } + ], + "name": "getAddress", + "outputs": [ + { + "internalType": "address", + "name": "barzAddress", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_accountFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_verificationFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_entryPoint", + "type": "address" + }, + { + "internalType": "address", + "name": "_facetRegistry", + "type": "address" + }, + { + "internalType": "address", + "name": "_defaultFallback", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_ownerPublicKey", + "type": "bytes" + } + ], + "name": "getBytecode", + "outputs": [ + { + "internalType": "bytes", + "name": "barzBytecode", + "type": "bytes" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "getCreationCode", + "outputs": [ + { + "internalType": "bytes", + "name": "creationCode", + "type": "bytes" + } + ], + "stateMutability": "pure", + "type": "function" + } + ], + "transactionHash": "0x4c31714d46c26c3895a4f4b9daadbd51e46bf72eaa82b329a3fa68861890f91b", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 4, + "gasUsed": "801756", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x8d6205c5ea5db57696d187ea702be4798111f49d3036e5a40ef886c735a13075", + "transactionHash": "0x4c31714d46c26c3895a4f4b9daadbd51e46bf72eaa82b329a3fa68861890f91b", + "logs": [], + "blockNumber": 2720992, + "cumulativeGasUsed": "909295", + "status": 1, + "byzantium": true + }, + "args": [ + "0xFde53272dcd7938d16E031A6989753c321728332", + "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789", + "0xAfCb70e6e9514E2A15B23A01d2a9b9f7A34f2c33", + "0x2e7f1dAe1F3799d20f5c31bEFdc7A620f664728D" + ], + "numDeployments": 1, + "solcInputHash": "ad34345aa73d96f52b3e14df983b6b29", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_accountFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_entryPoint\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_facetRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_defaultFallback\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"BarzDeployed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"accountFacet\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_verificationFacet\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_owner\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_salt\",\"type\":\"uint256\"}],\"name\":\"createAccount\",\"outputs\":[{\"internalType\":\"contract Barz\",\"name\":\"barz\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"defaultFallback\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"entryPoint\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetRegistry\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_verificationFacet\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_owner\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_salt\",\"type\":\"uint256\"}],\"name\":\"getAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"barzAddress\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_accountFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_verificationFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_entryPoint\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_facetRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_defaultFallback\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_ownerPublicKey\",\"type\":\"bytes\"}],\"name\":\"getBytecode\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"barzBytecode\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCreationCode\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"creationCode\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"Contract to easily deploy Barz to a pre-computed address with a single call\",\"kind\":\"dev\",\"methods\":{\"constructor\":{\"params\":{\"_accountFacet\":\"Account Facet to be used to create Barz\",\"_defaultFallback\":\"Default Fallback Handler to be used to create Barz\",\"_entryPoint\":\"Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\",\"_facetRegistry\":\"Facet Registry to be used to create Barz\"}},\"createAccount(address,bytes,uint256)\":{\"params\":{\"_owner\":\"Public Key of the owner to initialize barz account\",\"_salt\":\"Salt used for deploying barz with create2\",\"_verificationFacet\":\"Address of verification facet used for creating the barz account\"},\"returns\":{\"barz\":\"Instance of Barz contract deployed with the given parameters\"}},\"getAddress(address,bytes,uint256)\":{\"params\":{\"_owner\":\"Public Key of the owner to initialize barz account\",\"_salt\":\"Salt used for deploying barz with create2\",\"_verificationFacet\":\"Address of verification facet used for creating the barz account\"},\"returns\":{\"barzAddress\":\"Precalculated Barz address\"}},\"getBytecode(address,address,address,address,address,bytes)\":{\"params\":{\"_accountFacet\":\"Account Facet to be used to create Barz\",\"_defaultFallback\":\"Default Fallback Handler to be used to create Barz\",\"_entryPoint\":\"Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\",\"_facetRegistry\":\"Facet Registry to be used to create Barz\",\"_ownerPublicKey\":\"Public Key of owner to be used to initialize Barz ownership\",\"_verificationFacet\":\"Verification Facet to be used to create Barz\"},\"returns\":{\"barzBytecode\":\"Bytecode of Barz\"}},\"getCreationCode()\":{\"returns\":{\"creationCode\":\"Creation code of Barz\"}}},\"title\":\"Barz Factory\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"Sets the initialization data for Barz contract initialization\"},\"createAccount(address,bytes,uint256)\":{\"notice\":\"Creates the Barz with a single call. It creates the Barz contract with the givent verification facet\"},\"getAddress(address,bytes,uint256)\":{\"notice\":\"Calculates the address of Barz with the given parameters\"},\"getBytecode(address,address,address,address,address,bytes)\":{\"notice\":\"Returns the bytecode of Barz with the given parameter\"},\"getCreationCode()\":{\"notice\":\"Returns the creation code of the Barz contract\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/BarzFactory.sol\":\"BarzFactory\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"contracts/Barz.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {LibDiamond} from \\\"./libraries/LibDiamond.sol\\\";\\nimport {IBarz} from \\\"./interfaces/IBarz.sol\\\";\\n\\n/**\\n * @title Barz\\n * @dev A diamond proxy wallet with a modular & upgradeable architecture\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract Barz is IBarz {\\n /**\\n * @notice Initializes Barz with the given parameters. Barz account is intended to be created from Barz Factory for stable deployment.\\n * @dev This method makes a delegate call to account facet and account facet handles the initialization.\\n * With modular architecture, Barz encompasses wide spectrum of architecture and logic.\\n * The only requirement is account facet to comply with initialize() interface.\\n * Barz doesn't include built-in functions and is a full proxy, for maximum extensibility and modularity.\\n * @param _accountFacet Address of Account Facet in charge of the Barz initialization\\n * @param _verificationFacet Address of Verification Facet for verifying the signature. Could be any signature scheme\\n * @param _entryPoint Address of Entry Point contract\\n * @param _facetRegistry Address of Facet Registry. Facet Registry is a registry holding trusted facets that could be added to user's wallet\\n * @param _defaultFallBack Address of Default FallBack Handler. Middleware contract for more efficient deployment\\n * @param _ownerPublicKey Bytes of Owner Public Key using for initialization\\n */\\n constructor(\\n address _accountFacet,\\n address _verificationFacet,\\n address _entryPoint,\\n address _facetRegistry,\\n address _defaultFallBack,\\n bytes memory _ownerPublicKey\\n ) payable {\\n bytes memory initCall = abi.encodeWithSignature(\\n \\\"initialize(address,address,address,address,bytes)\\\",\\n _verificationFacet,\\n _entryPoint,\\n _facetRegistry,\\n _defaultFallBack,\\n _ownerPublicKey\\n );\\n (bool success, bytes memory result) = _accountFacet.delegatecall(\\n initCall\\n );\\n if (!success || uint256(bytes32(result)) != 1) {\\n revert Barz__InitializationFailure();\\n }\\n }\\n\\n /**\\n * @notice Fallback function for Barz complying with Diamond Standard with customization of adding Default Fallback Handler\\n * @dev Find facet for function that is called and execute the function if a facet is found and return any value.\\n */\\n fallback() external payable {\\n LibDiamond.DiamondStorage storage ds;\\n bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION;\\n // get diamond storage\\n assembly {\\n ds.slot := position\\n }\\n // get facet from function selector\\n address facet = address(bytes20(ds.facets[msg.sig]));\\n if (facet == address(0))\\n facet = ds.defaultFallbackHandler.facetAddress(msg.sig);\\n require(facet != address(0), \\\"Barz: Function does not exist\\\");\\n // Execute external function from facet using delegatecall and return any value.\\n assembly {\\n // copy function selector and any arguments\\n calldatacopy(0, 0, calldatasize())\\n // execute function call using the facet\\n let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)\\n // get any return value\\n returndatacopy(0, 0, returndatasize())\\n // return any return value or error back to the caller\\n switch result\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @notice Receive function to receive native token without data\\n */\\n receive() external payable {}\\n}\\n\",\"keccak256\":\"0xd1c773409a4b3d1ca0316445d9ea1d686bab9cd5f6731fbdb0766a93edfd7bdb\",\"license\":\"Apache-2.0\"},\"contracts/BarzFactory.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {Barz} from \\\"./Barz.sol\\\";\\nimport {IBarzFactory} from \\\"./interfaces/IBarzFactory.sol\\\";\\n\\n/**\\n * @title Barz Factory\\n * @dev Contract to easily deploy Barz to a pre-computed address with a single call\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract BarzFactory is IBarzFactory {\\n address public immutable accountFacet;\\n address public immutable entryPoint;\\n address public immutable facetRegistry;\\n address public immutable defaultFallback;\\n\\n /**\\n * @notice Sets the initialization data for Barz contract initialization\\n * @param _accountFacet Account Facet to be used to create Barz\\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\\n * @param _facetRegistry Facet Registry to be used to create Barz\\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\\n */\\n constructor(\\n address _accountFacet,\\n address _entryPoint,\\n address _facetRegistry,\\n address _defaultFallback\\n ) {\\n accountFacet = _accountFacet;\\n entryPoint = _entryPoint;\\n facetRegistry = _facetRegistry;\\n defaultFallback = _defaultFallback;\\n }\\n\\n /**\\n * @notice Creates the Barz with a single call. It creates the Barz contract with the givent verification facet\\n * @param _verificationFacet Address of verification facet used for creating the barz account\\n * @param _owner Public Key of the owner to initialize barz account\\n * @param _salt Salt used for deploying barz with create2\\n * @return barz Instance of Barz contract deployed with the given parameters\\n */\\n function createAccount(\\n address _verificationFacet,\\n bytes calldata _owner,\\n uint256 _salt\\n ) external override returns (Barz barz) {\\n address addr = getAddress(_verificationFacet, _owner, _salt);\\n uint codeSize = addr.code.length;\\n if (codeSize > 0) {\\n return Barz(payable(addr));\\n }\\n barz = new Barz{salt: bytes32(_salt)}(\\n accountFacet,\\n _verificationFacet,\\n entryPoint,\\n facetRegistry,\\n defaultFallback,\\n _owner\\n );\\n emit BarzDeployed(address(barz));\\n }\\n\\n /**\\n * @notice Calculates the address of Barz with the given parameters\\n * @param _verificationFacet Address of verification facet used for creating the barz account\\n * @param _owner Public Key of the owner to initialize barz account\\n * @param _salt Salt used for deploying barz with create2\\n * @return barzAddress Precalculated Barz address\\n */\\n function getAddress(\\n address _verificationFacet,\\n bytes calldata _owner,\\n uint256 _salt\\n ) public view override returns (address barzAddress) {\\n bytes memory bytecode = getBytecode(\\n accountFacet,\\n _verificationFacet,\\n entryPoint,\\n facetRegistry,\\n defaultFallback,\\n _owner\\n );\\n bytes32 hash = keccak256(\\n abi.encodePacked(\\n bytes1(0xff),\\n address(this),\\n _salt,\\n keccak256(bytecode)\\n )\\n );\\n barzAddress = address(uint160(uint256(hash)));\\n }\\n\\n /**\\n * @notice Returns the bytecode of Barz with the given parameter\\n * @param _accountFacet Account Facet to be used to create Barz\\n * @param _verificationFacet Verification Facet to be used to create Barz\\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\\n * @param _facetRegistry Facet Registry to be used to create Barz\\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\\n * @param _ownerPublicKey Public Key of owner to be used to initialize Barz ownership\\n * @return barzBytecode Bytecode of Barz\\n */\\n function getBytecode(\\n address _accountFacet,\\n address _verificationFacet,\\n address _entryPoint,\\n address _facetRegistry,\\n address _defaultFallback,\\n bytes calldata _ownerPublicKey\\n ) public pure override returns (bytes memory barzBytecode) {\\n bytes memory bytecode = type(Barz).creationCode;\\n barzBytecode = abi.encodePacked(\\n bytecode,\\n abi.encode(\\n _accountFacet,\\n _verificationFacet,\\n _entryPoint,\\n _facetRegistry,\\n _defaultFallback,\\n _ownerPublicKey\\n )\\n );\\n }\\n\\n /**\\n * @notice Returns the creation code of the Barz contract\\n * @return creationCode Creation code of Barz\\n */\\n function getCreationCode()\\n public\\n pure\\n override\\n returns (bytes memory creationCode)\\n {\\n creationCode = type(Barz).creationCode;\\n }\\n}\\n\",\"keccak256\":\"0x76d6058fa4714f5ef87b876e49ce7e21f581164901eea906ec743e82362b1df6\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IBarz.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Barz Interface\\n * @dev Interface of Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IBarz {\\n error Barz__InitializationFailure();\\n}\\n\",\"keccak256\":\"0xca9f0c2c1ad7d06088fa16ae92d587416f2d10d8f999d7afe8ca5c4d73410aba\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IBarzFactory.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {Barz} from \\\"../Barz.sol\\\";\\n\\n/**\\n * @title Barz Factory Interface\\n * @dev Interface of contract to easily deploy Barz to a pre-computed address with a single call\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IBarzFactory {\\n event BarzDeployed(address);\\n\\n function createAccount(\\n address verificationFacet,\\n bytes calldata owner,\\n uint256 salt\\n ) external returns (Barz);\\n\\n function getAddress(\\n address verificationFacet,\\n bytes calldata owner,\\n uint256 salt\\n ) external view returns (address);\\n\\n function getBytecode(\\n address accountFacet,\\n address verificationFacet,\\n address entryPoint,\\n address facetRegistry,\\n address defaultFallback,\\n bytes memory ownerPublicKey\\n ) external pure returns (bytes memory);\\n\\n function getCreationCode() external pure returns (bytes memory);\\n}\\n\",\"keccak256\":\"0xadb48a6f3025f6395e26ffd5f9319da73ad2383906c8223e8455f41f420fba26\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\\n bytes4(keccak256(\\\"verifyRestrictions(address,address,uint256,bytes)\\\"));\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // Default Fallback Handler of the barz.\\n IDiamondLoupe defaultFallbackHandler;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function enforceIsSelf() internal view {\\n require(msg.sender == address(this), \\\"LibDiamond: Caller not self\\\");\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n\\n unchecked {\\n facetIndex++;\\n }\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n\\n function restrictionsFacet() internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(\\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2cabdc00de859c3a3170ce3bda5d0e5fd3933d47ce904fd1585f9818b02572f8\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x61010060405234801561001157600080fd5b50604051610eba380380610eba8339810160408190526100309161006e565b6001600160a01b0393841660805291831660a052821660c0521660e0526100c2565b80516001600160a01b038116811461006957600080fd5b919050565b6000806000806080858703121561008457600080fd5b61008d85610052565b935061009b60208601610052565b92506100a960408601610052565b91506100b760608601610052565b905092959194509250565b60805160a05160c05160e051610d886101326000396000818161013b015281816102b3015261048101526000818160bf01528181610292015261046001526000818161016301528181610271015261043f01526000818161018b0152818161024f015261041d0152610d886000f3fe60806040523480156200001157600080fd5b5060043610620000925760003560e01c806344409a82116200006257806344409a821462000135578063b0d691fe146200015d578063b0f5d4641462000185578063c8a7adf514620001ad57600080fd5b8062c194db14620000975780630a1acd7314620000b9578063296601cd146200010757806333bb64a7146200011e575b600080fd5b620000a1620001c4565b604051620000b091906200056c565b60405180910390f35b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001620000b0565b620000e16200011836600462000635565b6200020e565b620000a16200012f36600462000695565b6200036d565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e1620001be36600462000635565b62000414565b606060405180602001620001d89062000538565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082820381018352601f90910116604052919050565b6000806200021f8686868662000414565b905073ffffffffffffffffffffffffffffffffffffffff81163b8015620002495750905062000365565b8360001b7f0000000000000000000000000000000000000000000000000000000000000000887f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008b8b604051620002e29062000538565b620002f497969594939291906200073a565b8190604051809103906000f590508015801562000315573d6000803e3d6000fd5b5060405173ffffffffffffffffffffffffffffffffffffffff821681529093507f9e6e326008e68f57877e2bae766a5745c162e42359e34834a7f0661fa82d31b19060200160405180910390a150505b949350505050565b6060600060405180602001620003839062000538565b6020820181038252601f19601f8201166040525090508089898989898989604051602001620003b997969594939291906200073a565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052620003f79291602001620007cd565b604051602081830303815290604052915050979650505050505050565b600080620004a87f0000000000000000000000000000000000000000000000000000000000000000877f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008a8a6200036d565b8051602091820120604080517fff00000000000000000000000000000000000000000000000000000000000000818501523060601b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001660218201526035810196909652605580870192909252805180870390920182526075909501909452835193019290922095945050505050565b610552806200080183390190565b60005b838110156200056357818101518382015260200162000549565b50506000910152565b60208152600082518060208401526200058d81604085016020870162000546565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b803573ffffffffffffffffffffffffffffffffffffffff81168114620005e457600080fd5b919050565b60008083601f840112620005fc57600080fd5b50813567ffffffffffffffff8111156200061557600080fd5b6020830191508360208285010111156200062e57600080fd5b9250929050565b600080600080606085870312156200064c57600080fd5b6200065785620005bf565b9350602085013567ffffffffffffffff8111156200067457600080fd5b6200068287828801620005e9565b9598909750949560400135949350505050565b600080600080600080600060c0888a031215620006b157600080fd5b620006bc88620005bf565b9650620006cc60208901620005bf565b9550620006dc60408901620005bf565b9450620006ec60608901620005bf565b9350620006fc60808901620005bf565b925060a088013567ffffffffffffffff8111156200071957600080fd5b620007278a828b01620005e9565b989b979a50959850939692959293505050565b600073ffffffffffffffffffffffffffffffffffffffff808a16835280891660208401528088166040840152808716606084015280861660808401525060c060a08301528260c0830152828460e0840137600060e0848401015260e07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f850116830101905098975050505050505050565b60008351620007e181846020880162000546565b835190830190620007f781836020880162000546565b0194935050505056fe608060405260405161055238038061055283398101604081905261002291610163565b6000858585858560405160240161003d959493929190610264565b60408051601f198184030181529181526020820180516001600160e01b0316634a93641760e01b1790525190915060009081906001600160a01b038a16906100869085906102c3565b600060405180830381855af49150503d80600081146100c1576040519150601f19603f3d011682016040523d82523d6000602084013e6100c6565b606091505b50915091508115806100e157506100dc816102df565b600114155b156100ff57604051636ff35f8960e01b815260040160405180910390fd5b505050505050505050610306565b80516001600160a01b038116811461012457600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101561015a578181015183820152602001610142565b50506000910152565b60008060008060008060c0878903121561017c57600080fd5b6101858761010d565b95506101936020880161010d565b94506101a16040880161010d565b93506101af6060880161010d565b92506101bd6080880161010d565b60a08801519092506001600160401b03808211156101da57600080fd5b818901915089601f8301126101ee57600080fd5b81518181111561020057610200610129565b604051601f8201601f19908116603f0116810190838211818310171561022857610228610129565b816040528281528c602084870101111561024157600080fd5b61025283602083016020880161013f565b80955050505050509295509295509295565b600060018060a01b0380881683528087166020840152808616604084015280851660608401525060a0608083015282518060a08401526102ab8160c085016020870161013f565b601f01601f19169190910160c0019695505050505050565b600082516102d581846020870161013f565b9190910192915050565b80516020808301519190811015610300576000198160200360031b1b821691505b50919050565b61023d806103156000396000f3fe60806040523661000b57005b600080357fffffffff000000000000000000000000000000000000000000000000000000001681527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020819052604090912054819060601c80610125576004838101546040517fcdffacc60000000000000000000000000000000000000000000000000000000081526000357fffffffff00000000000000000000000000000000000000000000000000000000169281019290925273ffffffffffffffffffffffffffffffffffffffff169063cdffacc690602401602060405180830381865afa1580156100fe573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061012291906101ca565b90505b73ffffffffffffffffffffffffffffffffffffffff81166101a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4261727a3a2046756e6374696f6e20646f6573206e6f74206578697374000000604482015260640160405180910390fd5b3660008037600080366000845af43d6000803e8080156101c5573d6000f35b3d6000fd5b6000602082840312156101dc57600080fd5b815173ffffffffffffffffffffffffffffffffffffffff8116811461020057600080fd5b939250505056fea26469706673582212200f3fa76ace3be8675d8b4c0d6c210a922fff2c2f1444023b817d1f6c908cd56a64736f6c63430008150033a2646970667358221220329ad45a4ef4915180001cb1fc90a5f97ad94a0b280426a580cba65fce28c0f164736f6c63430008150033", + "deployedBytecode": "0x60806040523480156200001157600080fd5b5060043610620000925760003560e01c806344409a82116200006257806344409a821462000135578063b0d691fe146200015d578063b0f5d4641462000185578063c8a7adf514620001ad57600080fd5b8062c194db14620000975780630a1acd7314620000b9578063296601cd146200010757806333bb64a7146200011e575b600080fd5b620000a1620001c4565b604051620000b091906200056c565b60405180910390f35b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001620000b0565b620000e16200011836600462000635565b6200020e565b620000a16200012f36600462000695565b6200036d565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e1620001be36600462000635565b62000414565b606060405180602001620001d89062000538565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082820381018352601f90910116604052919050565b6000806200021f8686868662000414565b905073ffffffffffffffffffffffffffffffffffffffff81163b8015620002495750905062000365565b8360001b7f0000000000000000000000000000000000000000000000000000000000000000887f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008b8b604051620002e29062000538565b620002f497969594939291906200073a565b8190604051809103906000f590508015801562000315573d6000803e3d6000fd5b5060405173ffffffffffffffffffffffffffffffffffffffff821681529093507f9e6e326008e68f57877e2bae766a5745c162e42359e34834a7f0661fa82d31b19060200160405180910390a150505b949350505050565b6060600060405180602001620003839062000538565b6020820181038252601f19601f8201166040525090508089898989898989604051602001620003b997969594939291906200073a565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052620003f79291602001620007cd565b604051602081830303815290604052915050979650505050505050565b600080620004a87f0000000000000000000000000000000000000000000000000000000000000000877f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008a8a6200036d565b8051602091820120604080517fff00000000000000000000000000000000000000000000000000000000000000818501523060601b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001660218201526035810196909652605580870192909252805180870390920182526075909501909452835193019290922095945050505050565b610552806200080183390190565b60005b838110156200056357818101518382015260200162000549565b50506000910152565b60208152600082518060208401526200058d81604085016020870162000546565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b803573ffffffffffffffffffffffffffffffffffffffff81168114620005e457600080fd5b919050565b60008083601f840112620005fc57600080fd5b50813567ffffffffffffffff8111156200061557600080fd5b6020830191508360208285010111156200062e57600080fd5b9250929050565b600080600080606085870312156200064c57600080fd5b6200065785620005bf565b9350602085013567ffffffffffffffff8111156200067457600080fd5b6200068287828801620005e9565b9598909750949560400135949350505050565b600080600080600080600060c0888a031215620006b157600080fd5b620006bc88620005bf565b9650620006cc60208901620005bf565b9550620006dc60408901620005bf565b9450620006ec60608901620005bf565b9350620006fc60808901620005bf565b925060a088013567ffffffffffffffff8111156200071957600080fd5b620007278a828b01620005e9565b989b979a50959850939692959293505050565b600073ffffffffffffffffffffffffffffffffffffffff808a16835280891660208401528088166040840152808716606084015280861660808401525060c060a08301528260c0830152828460e0840137600060e0848401015260e07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f850116830101905098975050505050505050565b60008351620007e181846020880162000546565b835190830190620007f781836020880162000546565b0194935050505056fe608060405260405161055238038061055283398101604081905261002291610163565b6000858585858560405160240161003d959493929190610264565b60408051601f198184030181529181526020820180516001600160e01b0316634a93641760e01b1790525190915060009081906001600160a01b038a16906100869085906102c3565b600060405180830381855af49150503d80600081146100c1576040519150601f19603f3d011682016040523d82523d6000602084013e6100c6565b606091505b50915091508115806100e157506100dc816102df565b600114155b156100ff57604051636ff35f8960e01b815260040160405180910390fd5b505050505050505050610306565b80516001600160a01b038116811461012457600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101561015a578181015183820152602001610142565b50506000910152565b60008060008060008060c0878903121561017c57600080fd5b6101858761010d565b95506101936020880161010d565b94506101a16040880161010d565b93506101af6060880161010d565b92506101bd6080880161010d565b60a08801519092506001600160401b03808211156101da57600080fd5b818901915089601f8301126101ee57600080fd5b81518181111561020057610200610129565b604051601f8201601f19908116603f0116810190838211818310171561022857610228610129565b816040528281528c602084870101111561024157600080fd5b61025283602083016020880161013f565b80955050505050509295509295509295565b600060018060a01b0380881683528087166020840152808616604084015280851660608401525060a0608083015282518060a08401526102ab8160c085016020870161013f565b601f01601f19169190910160c0019695505050505050565b600082516102d581846020870161013f565b9190910192915050565b80516020808301519190811015610300576000198160200360031b1b821691505b50919050565b61023d806103156000396000f3fe60806040523661000b57005b600080357fffffffff000000000000000000000000000000000000000000000000000000001681527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020819052604090912054819060601c80610125576004838101546040517fcdffacc60000000000000000000000000000000000000000000000000000000081526000357fffffffff00000000000000000000000000000000000000000000000000000000169281019290925273ffffffffffffffffffffffffffffffffffffffff169063cdffacc690602401602060405180830381865afa1580156100fe573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061012291906101ca565b90505b73ffffffffffffffffffffffffffffffffffffffff81166101a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4261727a3a2046756e6374696f6e20646f6573206e6f74206578697374000000604482015260640160405180910390fd5b3660008037600080366000845af43d6000803e8080156101c5573d6000f35b3d6000fd5b6000602082840312156101dc57600080fd5b815173ffffffffffffffffffffffffffffffffffffffff8116811461020057600080fd5b939250505056fea26469706673582212200f3fa76ace3be8675d8b4c0d6c210a922fff2c2f1444023b817d1f6c908cd56a64736f6c63430008150033a2646970667358221220329ad45a4ef4915180001cb1fc90a5f97ad94a0b280426a580cba65fce28c0f164736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "Contract to easily deploy Barz to a pre-computed address with a single call", + "kind": "dev", + "methods": { + "constructor": { + "params": { + "_accountFacet": "Account Facet to be used to create Barz", + "_defaultFallback": "Default Fallback Handler to be used to create Barz", + "_entryPoint": "Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF", + "_facetRegistry": "Facet Registry to be used to create Barz" + } + }, + "createAccount(address,bytes,uint256)": { + "params": { + "_owner": "Public Key of the owner to initialize barz account", + "_salt": "Salt used for deploying barz with create2", + "_verificationFacet": "Address of verification facet used for creating the barz account" + }, + "returns": { + "barz": "Instance of Barz contract deployed with the given parameters" + } + }, + "getAddress(address,bytes,uint256)": { + "params": { + "_owner": "Public Key of the owner to initialize barz account", + "_salt": "Salt used for deploying barz with create2", + "_verificationFacet": "Address of verification facet used for creating the barz account" + }, + "returns": { + "barzAddress": "Precalculated Barz address" + } + }, + "getBytecode(address,address,address,address,address,bytes)": { + "params": { + "_accountFacet": "Account Facet to be used to create Barz", + "_defaultFallback": "Default Fallback Handler to be used to create Barz", + "_entryPoint": "Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF", + "_facetRegistry": "Facet Registry to be used to create Barz", + "_ownerPublicKey": "Public Key of owner to be used to initialize Barz ownership", + "_verificationFacet": "Verification Facet to be used to create Barz" + }, + "returns": { + "barzBytecode": "Bytecode of Barz" + } + }, + "getCreationCode()": { + "returns": { + "creationCode": "Creation code of Barz" + } + } + }, + "title": "Barz Factory", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "constructor": { + "notice": "Sets the initialization data for Barz contract initialization" + }, + "createAccount(address,bytes,uint256)": { + "notice": "Creates the Barz with a single call. It creates the Barz contract with the givent verification facet" + }, + "getAddress(address,bytes,uint256)": { + "notice": "Calculates the address of Barz with the given parameters" + }, + "getBytecode(address,address,address,address,address,bytes)": { + "notice": "Returns the bytecode of Barz with the given parameter" + }, + "getCreationCode()": { + "notice": "Returns the creation code of the Barz contract" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/linea/DefaultFallbackHandler.json b/deployments/linea/DefaultFallbackHandler.json new file mode 100644 index 0000000..59d59c5 --- /dev/null +++ b/deployments/linea/DefaultFallbackHandler.json @@ -0,0 +1,275 @@ +{ + "address": "0x2e7f1dAe1F3799d20f5c31bEFdc7A620f664728D", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_diamondCutFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_accountFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_tokenReceiverFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_diamondLoupeFacet", + "type": "address" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_initializationContractAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "InitializationFunctionReverted", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "indexed": false, + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "DiamondCut", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_functionSelector", + "type": "bytes4" + } + ], + "name": "facetAddress", + "outputs": [ + { + "internalType": "address", + "name": "facetAddress_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetAddresses", + "outputs": [ + { + "internalType": "address[]", + "name": "facetAddresses_", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_facet", + "type": "address" + } + ], + "name": "facetFunctionSelectors", + "outputs": [ + { + "internalType": "bytes4[]", + "name": "facetFunctionSelectors_", + "type": "bytes4[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facets", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondLoupe.Facet[]", + "name": "facets_", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0x7598a37c0eb58c0e018de85495022f85deee87c191c6d3cbe1ef57222c01b42f", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 2, + "gasUsed": "1438535", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000001000000000800002000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000", + "blockHash": "0x8f378d8edab19b19c2454eb7597d79a2d4fb027f83a23b297b658abd12417ead", + "transactionHash": "0x7598a37c0eb58c0e018de85495022f85deee87c191c6d3cbe1ef57222c01b42f", + "logs": [ + { + "transactionIndex": 2, + "blockNumber": 2720940, + "transactionHash": "0x7598a37c0eb58c0e018de85495022f85deee87c191c6d3cbe1ef57222c01b42f", + "address": "0x2e7f1dAe1F3799d20f5c31bEFdc7A620f664728D", + "topics": [ + "0x8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb673" + ], + "data": "0x000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000580000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000000000000000000000000000000000003600000000000000000000000000b9504140771c3688ff041917192277d2f52e1e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000011f931c1c00000000000000000000000000000000000000000000000000000000000000000000000000000000fde53272dcd7938d16e031a6989753c321728332000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000005b61d27f60000000000000000000000000000000000000000000000000000000047e1da2a000000000000000000000000000000000000000000000000000000003a871cdd00000000000000000000000000000000000000000000000000000000d087d28800000000000000000000000000000000000000000000000000000000b0d691fe000000000000000000000000000000000000000000000000000000000000000000000000000000003143e1c0af0cdc153423863923cf4e3818e34daa000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000005150b7a0200000000000000000000000000000000000000000000000000000000f23a6e6100000000000000000000000000000000000000000000000000000000bc197c81000000000000000000000000000000000000000000000000000000000023de2900000000000000000000000000000000000000000000000000000000a4c0ed3600000000000000000000000000000000000000000000000000000000000000000000000000000000ce36b85d12d81cd619c745c7717f3396e184ac7c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000097a0ed62700000000000000000000000000000000000000000000000000000000adfca15e0000000000000000000000000000000000000000000000000000000052ef6b2c00000000000000000000000000000000000000000000000000000000cdffacc60000000000000000000000000000000000000000000000000000000001ffc9a700000000000000000000000000000000000000000000000000000000f9796ccf0000000000000000000000000000000000000000000000000000000001a5502200000000000000000000000000000000000000000000000000000000d42139a900000000000000000000000000000000000000000000000000000000e3a2f6fe000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "logIndex": 0, + "blockHash": "0x8f378d8edab19b19c2454eb7597d79a2d4fb027f83a23b297b658abd12417ead" + } + ], + "blockNumber": 2720940, + "cumulativeGasUsed": "1480535", + "status": 1, + "byzantium": true + }, + "args": [ + "0x0B9504140771C3688Ff041917192277D2f52E1e0", + "0xFde53272dcd7938d16E031A6989753c321728332", + "0x3143E1C0Af0Cdc153423863923Cf4e3818e34Daa", + "0xCe36b85d12D81cd619C745c7717f3396E184Ac7C" + ], + "numDeployments": 1, + "solcInputHash": "ad34345aa73d96f52b3e14df983b6b29", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_diamondCutFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_accountFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_tokenReceiverFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_diamondLoupeFacet\",\"type\":\"address\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_initializationContractAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"InitializationFunctionReverted\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"DiamondCut\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_functionSelector\",\"type\":\"bytes4\"}],\"name\":\"facetAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"facetAddress_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetAddresses\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"facetAddresses_\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_facet\",\"type\":\"address\"}],\"name\":\"facetFunctionSelectors\",\"outputs\":[{\"internalType\":\"bytes4[]\",\"name\":\"facetFunctionSelectors_\",\"type\":\"bytes4[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facets\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondLoupe.Facet[]\",\"name\":\"facets_\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"A default fallback handler for Barz\",\"kind\":\"dev\",\"methods\":{\"constructor\":{\"details\":\"This contract is also a diamond that holds the default facets to reduce gas cost for wallet activation. Within the constructor this conducts diamond cut to initially setup the diamond. This is a non-upgradeable contract\",\"params\":{\"_accountFacet\":\"Address account facet\",\"_diamondCutFacet\":\"Address if diamond cut facet\",\"_diamondLoupeFacet\":\"Address of diamond loupe facet\",\"_tokenReceiverFacet\":\"Address of token receiver facet\"}},\"facetAddress(bytes4)\":{\"details\":\"If facet is not found return address(0).\",\"params\":{\"_functionSelector\":\"The function selector.\"},\"returns\":{\"facetAddress_\":\"The facet address.\"}},\"facetAddresses()\":{\"returns\":{\"facetAddresses_\":\"facetAddresses_\"}},\"facetFunctionSelectors(address)\":{\"params\":{\"_facet\":\"The facet address.\"},\"returns\":{\"facetFunctionSelectors_\":\"facetFunctionSelectors_\"}},\"facets()\":{\"returns\":{\"facets_\":\"The facet struct array including all facet information\"}}},\"title\":\"DefaultFallbackHandler\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"Sets the middleware diamond for Barz wallet as a fallback handler\"},\"facetAddress(bytes4)\":{\"notice\":\"Gets the facet that supports the given selector.\"},\"facetAddresses()\":{\"notice\":\"Get all the facet addresses used by a diamond.\"},\"facetFunctionSelectors(address)\":{\"notice\":\"Gets all the function selectors provided by a facet.\"},\"facets()\":{\"notice\":\"Returns the facet information of call facets registered to this diamond.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/infrastructure/DefaultFallbackHandler.sol\":\"DefaultFallbackHandler\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/introspection/IERC165.sol\\\";\\n\\n/**\\n * @dev _Available since v3.1._\\n */\\ninterface IERC1155Receiver is IERC165 {\\n /**\\n * @dev Handles the receipt of a single ERC1155 token type. This function is\\n * called at the end of a `safeTransferFrom` after the balance has been updated.\\n *\\n * NOTE: To accept the transfer, this must return\\n * `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))`\\n * (i.e. 0xf23a6e61, or its own function selector).\\n *\\n * @param operator The address which initiated the transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param id The ID of the token being transferred\\n * @param value The amount of tokens being transferred\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155Received(\\n address operator,\\n address from,\\n uint256 id,\\n uint256 value,\\n bytes calldata data\\n ) external returns (bytes4);\\n\\n /**\\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\\n * is called at the end of a `safeBatchTransferFrom` after the balances have\\n * been updated.\\n *\\n * NOTE: To accept the transfer(s), this must return\\n * `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))`\\n * (i.e. 0xbc197c81, or its own function selector).\\n *\\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155BatchReceived(\\n address operator,\\n address from,\\n uint256[] calldata ids,\\n uint256[] calldata values,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xeb373f1fdc7b755c6a750123a9b9e3a8a02c1470042fd6505d875000a80bde0b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title ERC721 token receiver interface\\n * @dev Interface for any contract that wants to support safeTransfers\\n * from ERC721 asset contracts.\\n */\\ninterface IERC721Receiver {\\n /**\\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\\n * by `operator` from `from`, this function is called.\\n *\\n * It must return its Solidity selector to confirm the token transfer.\\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\\n *\\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\\n */\\n function onERC721Received(\\n address operator,\\n address from,\\n uint256 tokenId,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\\n *\\n * Accounts can be notified of {IERC777} tokens being sent to them by having a\\n * contract implement this interface (contract holders can be their own\\n * implementer) and registering it on the\\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\\n *\\n * See {IERC1820Registry} and {ERC1820Implementer}.\\n */\\ninterface IERC777Recipient {\\n /**\\n * @dev Called by an {IERC777} token contract whenever tokens are being\\n * moved or created into a registered account (`to`). The type of operation\\n * is conveyed by `from` being the zero address or not.\\n *\\n * This call occurs _after_ the token contract's state is updated, so\\n * {IERC777-balanceOf}, etc., can be used to query the post-operation state.\\n *\\n * This function may revert to prevent the operation from being executed.\\n */\\n function tokensReceived(\\n address operator,\\n address from,\\n address to,\\n uint256 amount,\\n bytes calldata userData,\\n bytes calldata operatorData\\n ) external;\\n}\\n\",\"keccak256\":\"0x1a5d61db2733202ba361e6d6741cd2e662380e22b80e987eacfc91973f2267dc\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"contracts/aa-4337/core/BaseAccount.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-empty-blocks */\\n\\nimport \\\"../interfaces/IAccount.sol\\\";\\nimport \\\"../interfaces/IEntryPoint.sol\\\";\\nimport \\\"./Helpers.sol\\\";\\n\\n/**\\n * Basic account implementation.\\n * this contract provides the basic logic for implementing the IAccount interface - validateUserOp\\n * specific account implementation should inherit it and provide the account-specific logic\\n */\\nabstract contract BaseAccount is IAccount {\\n using UserOperationLib for UserOperation;\\n\\n //return value in case of signature failure, with no time-range.\\n // equivalent to _packValidationData(true,0,0);\\n uint256 internal constant SIG_VALIDATION_FAILED = 1;\\n\\n /**\\n * Return the account nonce.\\n * This method returns the next sequential nonce.\\n * For a nonce of a specific key, use `entrypoint.getNonce(account, key)`\\n */\\n function getNonce() public view virtual returns (uint256) {\\n return entryPoint().getNonce(address(this), 0);\\n }\\n\\n /**\\n * return the entryPoint used by this account.\\n * subclass should return the current entryPoint used by this account.\\n */\\n function entryPoint() public view virtual returns (IEntryPoint);\\n\\n /**\\n * Validate user's signature and nonce.\\n * subclass doesn't need to override this method. Instead, it should override the specific internal validation methods.\\n */\\n function validateUserOp(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n uint256 missingAccountFunds\\n ) external virtual override returns (uint256 validationData) {\\n _requireFromEntryPoint();\\n validationData = _validateSignature(userOp, userOpHash);\\n _validateNonce(userOp.nonce);\\n _payPrefund(missingAccountFunds);\\n }\\n\\n /**\\n * ensure the request comes from the known entrypoint.\\n */\\n function _requireFromEntryPoint() internal view virtual {\\n require(\\n msg.sender == address(entryPoint()),\\n \\\"account: not from EntryPoint\\\"\\n );\\n }\\n\\n /**\\n * validate the signature is valid for this message.\\n * @param userOp validate the userOp.signature field\\n * @param userOpHash convenient field: the hash of the request, to check the signature against\\n * (also hashes the entrypoint and chain id)\\n * @return validationData signature and time-range of this operation\\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\\n * otherwise, an address of an \\\"authorizer\\\" contract.\\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \\\"indefinite\\\"\\n * <6-byte> validAfter - first timestamp this operation is valid\\n * If the account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\\n */\\n function _validateSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) internal virtual returns (uint256 validationData);\\n\\n /**\\n * Validate the nonce of the UserOperation.\\n * This method may validate the nonce requirement of this account.\\n * e.g.\\n * To limit the nonce to use sequenced UserOps only (no \\\"out of order\\\" UserOps):\\n * `require(nonce < type(uint64).max)`\\n * For a hypothetical account that *requires* the nonce to be out-of-order:\\n * `require(nonce & type(uint64).max == 0)`\\n *\\n * The actual nonce uniqueness is managed by the EntryPoint, and thus no other\\n * action is needed by the account itself.\\n *\\n * @param nonce to validate\\n *\\n * solhint-disable-next-line no-empty-blocks\\n */\\n function _validateNonce(uint256 nonce) internal view virtual {}\\n\\n /**\\n * sends to the entrypoint (msg.sender) the missing funds for this transaction.\\n * subclass MAY override this method for better funds management\\n * (e.g. send to the entryPoint more than the minimum required, so that in future transactions\\n * it will not be required to send again)\\n * @param missingAccountFunds the minimum value this method should send the entrypoint.\\n * this value MAY be zero, in case there is enough deposit, or the userOp has a paymaster.\\n */\\n function _payPrefund(uint256 missingAccountFunds) internal virtual {\\n if (missingAccountFunds != 0) {\\n (bool success, ) = payable(msg.sender).call{\\n value: missingAccountFunds,\\n gas: type(uint256).max\\n }(\\\"\\\");\\n (success);\\n //ignore failure (its EntryPoint's job to verify, not account.)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa0dcc386b0f04711db3e394fb50e55a3b3b1a4d19fac1f10895844e1aa4e3d5c\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/core/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable no-inline-assembly */\\n\\n/**\\n * returned data from validateUserOp.\\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\\n * @param aggregator - address(0) - the account validated the signature by itself.\\n * address(1) - the account failed to validate the signature.\\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\\n * @param validAfter - this UserOp is valid only after this timestamp.\\n * @param validaUntil - this UserOp is valid only up to this timestamp.\\n */\\nstruct ValidationData {\\n address aggregator;\\n uint48 validAfter;\\n uint48 validUntil;\\n}\\n\\n//extract sigFailed, validAfter, validUntil.\\n// also convert zero validUntil to type(uint48).max\\nfunction _parseValidationData(\\n uint validationData\\n) pure returns (ValidationData memory data) {\\n address aggregator = address(uint160(validationData));\\n uint48 validUntil = uint48(validationData >> 160);\\n if (validUntil == 0) {\\n validUntil = type(uint48).max;\\n }\\n uint48 validAfter = uint48(validationData >> (48 + 160));\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n// intersect account and paymaster ranges.\\nfunction _intersectTimeRange(\\n uint256 validationData,\\n uint256 paymasterValidationData\\n) pure returns (ValidationData memory) {\\n ValidationData memory accountValidationData = _parseValidationData(\\n validationData\\n );\\n ValidationData memory pmValidationData = _parseValidationData(\\n paymasterValidationData\\n );\\n address aggregator = accountValidationData.aggregator;\\n if (aggregator == address(0)) {\\n aggregator = pmValidationData.aggregator;\\n }\\n uint48 validAfter = accountValidationData.validAfter;\\n uint48 validUntil = accountValidationData.validUntil;\\n uint48 pmValidAfter = pmValidationData.validAfter;\\n uint48 pmValidUntil = pmValidationData.validUntil;\\n\\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp\\n * @param data - the ValidationData to pack\\n */\\nfunction _packValidationData(\\n ValidationData memory data\\n) pure returns (uint256) {\\n return\\n uint160(data.aggregator) |\\n (uint256(data.validUntil) << 160) |\\n (uint256(data.validAfter) << (160 + 48));\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp, when not using an aggregator\\n * @param sigFailed - true for signature failure, false for success\\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\\n * @param validAfter first timestamp this UserOperation is valid\\n */\\nfunction _packValidationData(\\n bool sigFailed,\\n uint48 validUntil,\\n uint48 validAfter\\n) pure returns (uint256) {\\n return\\n (sigFailed ? 1 : 0) |\\n (uint256(validUntil) << 160) |\\n (uint256(validAfter) << (160 + 48));\\n}\\n\\n/**\\n * keccak function over calldata.\\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\\n */\\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\\n assembly {\\n let mem := mload(0x40)\\n let len := data.length\\n calldatacopy(mem, data.offset, len)\\n ret := keccak256(mem, len)\\n }\\n}\\n\",\"keccak256\":\"0xa79f06cd158ecb8c0da95493a2f348933b8627a63e228b99738bff3aa107942d\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAccount.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\ninterface IAccount {\\n /**\\n * Validate user's signature and nonce\\n * the entryPoint will make the call to the recipient only if this validation call returns successfully.\\n * signature failure should be reported by returning SIG_VALIDATION_FAILED (1).\\n * This allows making a \\\"simulation call\\\" without a valid signature\\n * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure.\\n *\\n * @dev Must validate caller is the entryPoint.\\n * Must validate the signature and nonce\\n * @param userOp the operation that is about to be executed.\\n * @param userOpHash hash of the user's request data. can be used as the basis for signature.\\n * @param missingAccountFunds missing funds on the account's deposit in the entrypoint.\\n * This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call.\\n * The excess is left as a deposit in the entrypoint, for future calls.\\n * can be withdrawn anytime using \\\"entryPoint.withdrawTo()\\\"\\n * In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero.\\n * @return validationData packaged ValidationData structure. use `_packValidationData` and `_unpackValidationData` to encode and decode\\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\\n * otherwise, an address of an \\\"authorizer\\\" contract.\\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \\\"indefinite\\\"\\n * <6-byte> validAfter - first timestamp this operation is valid\\n * If an account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\\n */\\n function validateUserOp(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n uint256 missingAccountFunds\\n ) external returns (uint256 validationData);\\n}\\n\",\"keccak256\":\"0xcbc4b0973cf954c5895b7796335f651fbfcfb55f67dfa789a3d354f8e23c4f2b\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAggregator.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\n/**\\n * Aggregated Signatures validator.\\n */\\ninterface IAggregator {\\n /**\\n * validate aggregated signature.\\n * revert if the aggregated signature does not match the given list of operations.\\n */\\n function validateSignatures(\\n UserOperation[] calldata userOps,\\n bytes calldata signature\\n ) external view;\\n\\n /**\\n * validate signature of a single userOp\\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\\n * @param userOp the userOperation received from the user.\\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\\n * (usually empty, unless account and aggregator support some kind of \\\"multisig\\\"\\n */\\n function validateUserOpSignature(\\n UserOperation calldata userOp\\n ) external view returns (bytes memory sigForUserOp);\\n\\n /**\\n * aggregate multiple signatures into a single value.\\n * This method is called off-chain to calculate the signature to pass with handleOps()\\n * bundler MAY use optimized custom code perform this aggregation\\n * @param userOps array of UserOperations to collect the signatures from.\\n * @return aggregatedSignature the aggregated signature\\n */\\n function aggregateSignatures(\\n UserOperation[] calldata userOps\\n ) external view returns (bytes memory aggregatedSignature);\\n}\\n\",\"keccak256\":\"0xdfdcd80568f037716674619b31be630fcd8316262f05a815b41d1e81782c966a\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IEntryPoint.sol\":{\"content\":\"/**\\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\\n ** Only one instance required on each chain.\\n **/\\n// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-inline-assembly */\\n/* solhint-disable reason-string */\\n\\nimport \\\"./UserOperation.sol\\\";\\nimport \\\"./IStakeManager.sol\\\";\\nimport \\\"./IAggregator.sol\\\";\\nimport \\\"./INonceManager.sol\\\";\\n\\ninterface IEntryPoint is IStakeManager, INonceManager {\\n /***\\n * An event emitted after each successful request\\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\\n * @param sender - the account that generates this request.\\n * @param paymaster - if non-null, the paymaster that pays for this request.\\n * @param nonce - the nonce value from the request.\\n * @param success - true if the sender transaction succeeded, false if reverted.\\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\\n */\\n event UserOperationEvent(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address indexed paymaster,\\n uint256 nonce,\\n bool success,\\n uint256 actualGasCost,\\n uint256 actualGasUsed\\n );\\n\\n /**\\n * account \\\"sender\\\" was deployed.\\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\\n * @param sender the account that is deployed\\n * @param factory the factory used to deploy this account (in the initCode)\\n * @param paymaster the paymaster used by this UserOp\\n */\\n event AccountDeployed(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address factory,\\n address paymaster\\n );\\n\\n /**\\n * An event emitted if the UserOperation \\\"callData\\\" reverted with non-zero length\\n * @param userOpHash the request unique identifier.\\n * @param sender the sender of this request\\n * @param nonce the nonce used in the request\\n * @param revertReason - the return bytes from the (reverted) call to \\\"callData\\\".\\n */\\n event UserOperationRevertReason(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n uint256 nonce,\\n bytes revertReason\\n );\\n\\n /**\\n * an event emitted by handleOps(), before starting the execution loop.\\n * any event emitted before this event, is part of the validation.\\n */\\n event BeforeExecution();\\n\\n /**\\n * signature aggregator used by the following UserOperationEvents within this bundle.\\n */\\n event SignatureAggregatorChanged(address indexed aggregator);\\n\\n /**\\n * a custom revert error of handleOps, to identify the offending op.\\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\\n * @param reason - revert reason\\n * The string starts with a unique code \\\"AAmn\\\", where \\\"m\\\" is \\\"1\\\" for factory, \\\"2\\\" for account and \\\"3\\\" for paymaster issues,\\n * so a failure can be attributed to the correct entity.\\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\\n */\\n error FailedOp(uint256 opIndex, string reason);\\n\\n /**\\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\\n */\\n error SignatureValidationFailed(address aggregator);\\n\\n /**\\n * Successful result from simulateValidation.\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n */\\n error ValidationResult(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo\\n );\\n\\n /**\\n * Successful result from simulateValidation, if the account returns a signature aggregator\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\\n * bundler MUST use it to verify the signature, or reject the UserOperation\\n */\\n error ValidationResultWithAggregation(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo,\\n AggregatorStakeInfo aggregatorInfo\\n );\\n\\n /**\\n * return value of getSenderAddress\\n */\\n error SenderAddressResult(address sender);\\n\\n /**\\n * return value of simulateHandleOp\\n */\\n error ExecutionResult(\\n uint256 preOpGas,\\n uint256 paid,\\n uint48 validAfter,\\n uint48 validUntil,\\n bool targetSuccess,\\n bytes targetResult\\n );\\n\\n //UserOps handled, per aggregator\\n struct UserOpsPerAggregator {\\n UserOperation[] userOps;\\n // aggregator address\\n IAggregator aggregator;\\n // aggregated signature\\n bytes signature;\\n }\\n\\n /**\\n * Execute a batch of UserOperation.\\n * no signature aggregator is used.\\n * if any account requires an aggregator (that is, it returned an aggregator when\\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\\n * @param ops the operations to execute\\n * @param beneficiary the address to receive the fees\\n */\\n function handleOps(\\n UserOperation[] calldata ops,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * Execute a batch of UserOperation with Aggregators\\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\\n * @param beneficiary the address to receive the fees\\n */\\n function handleAggregatedOps(\\n UserOpsPerAggregator[] calldata opsPerAggregator,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * generate a request Id - unique identifier for this request.\\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\\n */\\n function getUserOpHash(\\n UserOperation calldata userOp\\n ) external view returns (bytes32);\\n\\n /**\\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\\n * @param userOp the user operation to validate.\\n */\\n function simulateValidation(UserOperation calldata userOp) external;\\n\\n /**\\n * gas and return values during simulation\\n * @param preOpGas the gas used for validation (including preValidationGas)\\n * @param prefund the required prefund for this operation\\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\\n */\\n struct ReturnInfo {\\n uint256 preOpGas;\\n uint256 prefund;\\n bool sigFailed;\\n uint48 validAfter;\\n uint48 validUntil;\\n bytes paymasterContext;\\n }\\n\\n /**\\n * returned aggregated signature info.\\n * the aggregator returned by the account, and its current stake.\\n */\\n struct AggregatorStakeInfo {\\n address aggregator;\\n StakeInfo stakeInfo;\\n }\\n\\n /**\\n * Get counterfactual sender address.\\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\\n * this method always revert, and returns the address in SenderAddressResult error\\n * @param initCode the constructor code to be passed into the UserOperation.\\n */\\n function getSenderAddress(bytes memory initCode) external;\\n\\n /**\\n * simulate full execution of a UserOperation (including both validation and target execution)\\n * this method will always revert with \\\"ExecutionResult\\\".\\n * it performs full validation of the UserOperation, but ignores signature error.\\n * an optional target address is called after the userop succeeds, and its value is returned\\n * (before the entire call is reverted)\\n * Note that in order to collect the the success/failure of the target call, it must be executed\\n * with trace enabled to track the emitted events.\\n * @param op the UserOperation to simulate\\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\\n * are set to the return from that call.\\n * @param targetCallData callData to pass to target address\\n */\\n function simulateHandleOp(\\n UserOperation calldata op,\\n address target,\\n bytes calldata targetCallData\\n ) external;\\n}\\n\",\"keccak256\":\"0x9ccb1b188eda8bbf5f6c2d01bd83c3d8b2b04fcf745283051d31fe96d1d8e40f\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/INonceManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\ninterface INonceManager {\\n /**\\n * Return the next nonce for this sender.\\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\\n * But UserOp with different keys can come with arbitrary order.\\n *\\n * @param sender the account address\\n * @param key the high 192 bit of the nonce\\n * @return nonce a full nonce to pass for next UserOp with this sender.\\n */\\n function getNonce(\\n address sender,\\n uint192 key\\n ) external view returns (uint256 nonce);\\n\\n /**\\n * Manually increment the nonce of the sender.\\n * This method is exposed just for completeness..\\n * Account does NOT need to call it, neither during validation, nor elsewhere,\\n * as the EntryPoint will update the nonce regardless.\\n * Possible use-case is call it with various keys to \\\"initialize\\\" their nonces to one, so that future\\n * UserOperations will not pay extra for the first transaction with a given key.\\n */\\n function incrementNonce(uint192 key) external;\\n}\\n\",\"keccak256\":\"0xce478ad0fa0d18a3b785ac854623029e7ab463d05873dfaa365abfa1bf100912\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IStakeManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8.12;\\n\\n/**\\n * manage deposits and stakes.\\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\\n * stake is value locked for at least \\\"unstakeDelay\\\" by the staked entity.\\n */\\ninterface IStakeManager {\\n event Deposited(address indexed account, uint256 totalDeposit);\\n\\n event Withdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /// Emitted when stake or unstake delay are modified\\n event StakeLocked(\\n address indexed account,\\n uint256 totalStaked,\\n uint256 unstakeDelaySec\\n );\\n\\n /// Emitted once a stake is scheduled for withdrawal\\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\\n\\n event StakeWithdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /**\\n * @param deposit the entity's deposit\\n * @param staked true if this entity is staked.\\n * @param stake actual amount of ether staked for this entity.\\n * @param unstakeDelaySec minimum delay to withdraw the stake.\\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\\n * and the rest fit into a 2nd cell.\\n * 112 bit allows for 10^15 eth\\n * 48 bit for full timestamp\\n * 32 bit allows 150 years for unstake delay\\n */\\n struct DepositInfo {\\n uint112 deposit;\\n bool staked;\\n uint112 stake;\\n uint32 unstakeDelaySec;\\n uint48 withdrawTime;\\n }\\n\\n //API struct used by getStakeInfo and simulateValidation\\n struct StakeInfo {\\n uint256 stake;\\n uint256 unstakeDelaySec;\\n }\\n\\n /// @return info - full deposit information of given account\\n function getDepositInfo(\\n address account\\n ) external view returns (DepositInfo memory info);\\n\\n /// @return the deposit (for gas payment) of the account\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * add to the deposit of the given account\\n */\\n function depositTo(address account) external payable;\\n\\n /**\\n * add to the account's stake - amount and delay\\n * any pending unstake is first cancelled.\\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\\n */\\n function addStake(uint32 _unstakeDelaySec) external payable;\\n\\n /**\\n * attempt to unlock the stake.\\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\\n */\\n function unlockStake() external;\\n\\n /**\\n * withdraw from the (unlocked) stake.\\n * must first call unlockStake and wait for the unstakeDelay to pass\\n * @param withdrawAddress the address to send withdrawn value.\\n */\\n function withdrawStake(address payable withdrawAddress) external;\\n\\n /**\\n * withdraw from the deposit.\\n * @param withdrawAddress the address to send withdrawn value.\\n * @param withdrawAmount the amount to withdraw.\\n */\\n function withdrawTo(\\n address payable withdrawAddress,\\n uint256 withdrawAmount\\n ) external;\\n}\\n\",\"keccak256\":\"0xadcea606c9b7aafe6645441f2154a60f271330b0eee5292a632aa71c1672d546\",\"license\":\"GPL-3.0-only\"},\"contracts/aa-4337/interfaces/UserOperation.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable no-inline-assembly */\\n\\nimport {calldataKeccak} from \\\"../core/Helpers.sol\\\";\\n\\n/**\\n * User Operation struct\\n * @param sender the sender account of this request.\\n * @param nonce unique value the sender uses to verify it is not a replay.\\n * @param initCode if set, the account contract will be created by this constructor/\\n * @param callData the method call to execute on this account.\\n * @param callGasLimit the gas limit passed to the callData method call.\\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\\n * @param maxFeePerGas same as EIP-1559 gas parameter.\\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\\n */\\nstruct UserOperation {\\n address sender;\\n uint256 nonce;\\n bytes initCode;\\n bytes callData;\\n uint256 callGasLimit;\\n uint256 verificationGasLimit;\\n uint256 preVerificationGas;\\n uint256 maxFeePerGas;\\n uint256 maxPriorityFeePerGas;\\n bytes paymasterAndData;\\n bytes signature;\\n}\\n\\n/**\\n * Utility functions helpful when working with UserOperation structs.\\n */\\nlibrary UserOperationLib {\\n function getSender(\\n UserOperation calldata userOp\\n ) internal pure returns (address) {\\n address data;\\n //read sender from userOp, which is first userOp member (saves 800 gas...)\\n assembly {\\n data := calldataload(userOp)\\n }\\n return address(uint160(data));\\n }\\n\\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\\n // pay above what he signed for.\\n function gasPrice(\\n UserOperation calldata userOp\\n ) internal view returns (uint256) {\\n unchecked {\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n if (maxFeePerGas == maxPriorityFeePerGas) {\\n //legacy mode (for networks that don't support basefee opcode)\\n return maxFeePerGas;\\n }\\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\\n }\\n }\\n\\n function pack(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes memory ret) {\\n address sender = getSender(userOp);\\n uint256 nonce = userOp.nonce;\\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\\n bytes32 hashCallData = calldataKeccak(userOp.callData);\\n uint256 callGasLimit = userOp.callGasLimit;\\n uint256 verificationGasLimit = userOp.verificationGasLimit;\\n uint256 preVerificationGas = userOp.preVerificationGas;\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\\n\\n return\\n abi.encode(\\n sender,\\n nonce,\\n hashInitCode,\\n hashCallData,\\n callGasLimit,\\n verificationGasLimit,\\n preVerificationGas,\\n maxFeePerGas,\\n maxPriorityFeePerGas,\\n hashPaymasterAndData\\n );\\n }\\n\\n function hash(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes32) {\\n return keccak256(pack(userOp));\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n}\\n\",\"keccak256\":\"0x2429f5cc546bdee08c7e63858d0dda8491eaa3ab5194df884dc948c1154d2834\",\"license\":\"GPL-3.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IStorageLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"./IDiamondLoupe.sol\\\";\\n\\n/**\\n * @title LoupeFromStorage Interface\\n * @dev Interface contract to function as a loupe facet directly attached to diamond storage of Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IStorageLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facetsFromStorage()\\n external\\n view\\n returns (IDiamondLoupe.Facet[] memory);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n function facetFunctionSelectorsFromStorage(\\n address _facet\\n ) external view returns (bytes4[] memory);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n function facetAddressesFromStorage()\\n external\\n view\\n returns (address[] memory);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n function facetAddressFromStorage(\\n bytes4 _functionSelector\\n ) external view returns (address);\\n}\\n\",\"keccak256\":\"0xdf5dc9c57319e9087628c9cf9404b4f75585b76d1c2f4f59ee796c933967ea5c\",\"license\":\"Apache-2.0\"},\"contracts/facets/interfaces/IAccountFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IEntryPoint} from \\\"../../aa-4337/interfaces/IEntryPoint.sol\\\";\\n\\n/**\\n * @title Account Facet Interface\\n * @dev Interface of module contract that provides the account features and init/unitialization of signer\\n * compatible with EIP-1271 & EIP-4337\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IAccountFacet {\\n event AccountInitialized(\\n IEntryPoint indexed entryPoint,\\n bytes indexed ownerPublicKey\\n );\\n // NOTE: Added Below Event\\n event VerificationSuccess(bytes32);\\n event VerificationFailure(bytes32);\\n\\n error AccountFacet__InitializationFailure();\\n error AccountFacet__RestrictionsFailure();\\n error AccountFacet__NonExistentVerificationFacet();\\n error AccountFacet__CallNotSuccessful();\\n error AccountFacet__InvalidArrayLength();\\n\\n function initialize(\\n address verificationFacet,\\n address anEntryPoint,\\n address facetRegistry,\\n address _defaultFallBack,\\n bytes calldata _ownerPublicKey\\n ) external returns (uint256);\\n\\n function execute(address dest, uint256 value, bytes calldata func) external;\\n\\n function executeBatch(\\n address[] calldata dest,\\n uint256[] calldata value,\\n bytes[] calldata func\\n ) external;\\n}\\n\",\"keccak256\":\"0x74a9cb0b8f2f4a5148e366a401a0354426c536c012c025025d07cc25a4cd5382\",\"license\":\"Apache-2.0\"},\"contracts/infrastructure/DefaultFallbackHandler.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IERC721Receiver} from \\\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\\\";\\nimport {IERC1155Receiver} from \\\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\\\";\\nimport {IERC777Recipient} from \\\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\\\";\\nimport {BaseAccount} from \\\"../aa-4337/core/BaseAccount.sol\\\";\\nimport {DefaultLibDiamond} from \\\"../libraries/DefaultLibDiamond.sol\\\";\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IAccountFacet} from \\\"../facets/interfaces/IAccountFacet.sol\\\";\\nimport {IStorageLoupe} from \\\"../facets/base/interfaces/IStorageLoupe.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\nimport {IERC677Receiver} from \\\"../interfaces/ERC/IERC677Receiver.sol\\\";\\nimport {IERC165} from \\\"../interfaces/ERC/IERC165.sol\\\";\\n\\n/**\\n * @title DefaultFallbackHandler\\n * @dev A default fallback handler for Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract DefaultFallbackHandler is IDiamondLoupe {\\n /**\\n * @notice Sets the middleware diamond for Barz wallet as a fallback handler\\n * @dev This contract is also a diamond that holds the default facets to reduce gas cost for wallet activation.\\n * Within the constructor this conducts diamond cut to initially setup the diamond. This is a non-upgradeable contract\\n * @param _diamondCutFacet Address if diamond cut facet\\n * @param _accountFacet Address account facet\\n * @param _tokenReceiverFacet Address of token receiver facet\\n * @param _diamondLoupeFacet Address of diamond loupe facet\\n */\\n constructor(\\n address _diamondCutFacet,\\n address _accountFacet,\\n address _tokenReceiverFacet,\\n address _diamondLoupeFacet\\n ) payable {\\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](4);\\n bytes4[] memory functionSelectors = new bytes4[](1);\\n functionSelectors[0] = IDiamondCut.diamondCut.selector;\\n\\n bytes4[] memory accountFunctionSelectors = new bytes4[](5);\\n accountFunctionSelectors[0] = IAccountFacet.execute.selector;\\n accountFunctionSelectors[1] = IAccountFacet.executeBatch.selector;\\n accountFunctionSelectors[2] = BaseAccount.validateUserOp.selector;\\n accountFunctionSelectors[3] = BaseAccount.getNonce.selector;\\n accountFunctionSelectors[4] = BaseAccount.entryPoint.selector;\\n\\n bytes4[] memory receiverFacetSelectors = new bytes4[](5);\\n receiverFacetSelectors[0] = IERC721Receiver.onERC721Received.selector;\\n receiverFacetSelectors[1] = IERC1155Receiver.onERC1155Received.selector;\\n receiverFacetSelectors[2] = IERC1155Receiver\\n .onERC1155BatchReceived\\n .selector;\\n receiverFacetSelectors[3] = IERC777Recipient.tokensReceived.selector;\\n receiverFacetSelectors[4] = IERC677Receiver.onTokenTransfer.selector;\\n\\n bytes4[] memory loupeFacetSelectors = new bytes4[](9);\\n loupeFacetSelectors[0] = IDiamondLoupe.facets.selector;\\n loupeFacetSelectors[1] = IDiamondLoupe.facetFunctionSelectors.selector;\\n loupeFacetSelectors[2] = IDiamondLoupe.facetAddresses.selector;\\n loupeFacetSelectors[3] = IDiamondLoupe.facetAddress.selector;\\n loupeFacetSelectors[4] = IERC165.supportsInterface.selector;\\n loupeFacetSelectors[5] = IStorageLoupe.facetsFromStorage.selector;\\n loupeFacetSelectors[6] = IStorageLoupe\\n .facetFunctionSelectorsFromStorage\\n .selector;\\n loupeFacetSelectors[7] = IStorageLoupe\\n .facetAddressesFromStorage\\n .selector;\\n loupeFacetSelectors[8] = IStorageLoupe.facetAddressFromStorage.selector;\\n\\n {\\n cut[0] = IDiamondCut.FacetCut({\\n facetAddress: _diamondCutFacet,\\n action: IDiamondCut.FacetCutAction.Add,\\n functionSelectors: functionSelectors\\n });\\n cut[1] = IDiamondCut.FacetCut({\\n facetAddress: _accountFacet,\\n action: IDiamondCut.FacetCutAction.Add,\\n functionSelectors: accountFunctionSelectors\\n });\\n cut[2] = IDiamondCut.FacetCut({\\n facetAddress: _tokenReceiverFacet,\\n action: IDiamondCut.FacetCutAction.Add,\\n functionSelectors: receiverFacetSelectors\\n });\\n cut[3] = IDiamondCut.FacetCut({\\n facetAddress: _diamondLoupeFacet,\\n action: IDiamondCut.FacetCutAction.Add,\\n functionSelectors: loupeFacetSelectors\\n });\\n\\n DefaultLibDiamond.diamondCut(cut, address(0), \\\"\\\");\\n }\\n }\\n\\n /**\\n * @notice Returns the facet information of call facets registered to this diamond.\\n * @return facets_ The facet struct array including all facet information\\n */\\n function facets() external view override returns (Facet[] memory facets_) {\\n DefaultLibDiamond.DiamondStorage storage ds = DefaultLibDiamond\\n .diamondStorage();\\n uint256 numFacets = ds.facetAddresses.length;\\n facets_ = new Facet[](numFacets);\\n for (uint256 i; i < numFacets; ) {\\n address facetAddress_ = ds.facetAddresses[i];\\n facets_[i].facetAddress = facetAddress_;\\n facets_[i].functionSelectors = ds\\n .facetFunctionSelectors[facetAddress_]\\n .functionSelectors;\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * @notice Gets all the function selectors provided by a facet.\\n * @param _facet The facet address.\\n * @return facetFunctionSelectors_\\n */\\n function facetFunctionSelectors(\\n address _facet\\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\\n facetFunctionSelectors_ = DefaultLibDiamond\\n .diamondStorage()\\n .facetFunctionSelectors[_facet]\\n .functionSelectors;\\n }\\n\\n /**\\n * @notice Get all the facet addresses used by a diamond.\\n * @return facetAddresses_\\n */\\n function facetAddresses()\\n external\\n view\\n override\\n returns (address[] memory facetAddresses_)\\n {\\n facetAddresses_ = DefaultLibDiamond.diamondStorage().facetAddresses;\\n }\\n\\n /** @notice Gets the facet that supports the given selector.\\n * @dev If facet is not found return address(0).\\n * @param _functionSelector The function selector.\\n * @return facetAddress_ The facet address.\\n */\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view override returns (address facetAddress_) {\\n facetAddress_ = DefaultLibDiamond\\n .diamondStorage()\\n .selectorToFacetAndPosition[_functionSelector]\\n .facetAddress;\\n }\\n}\\n\",\"keccak256\":\"0xa482fe778481e34e9fb3c4074231f8048437e934c0ca9a0c78e8e61d3a24470a\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.21;\\n\\ninterface IERC165 {\\n /// @notice Query if a contract implements an interface\\n /// @param interfaceId The interface identifier, as specified in ERC-165\\n /// @dev Interface identification is specified in ERC-165. This function\\n /// uses less than 30,000 gas.\\n /// @return `true` if the contract implements `interfaceID` and\\n /// `interfaceID` is not 0xffffffff, `false` otherwise\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xbb7f07e170898793c5535cc4b7e8944c4b990a631ac806d0b788e794abc788a3\",\"license\":\"MIT\"},\"contracts/interfaces/ERC/IERC677Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC677Receiver {\\n function onTokenTransfer(\\n address sender,\\n uint value,\\n bytes calldata data\\n ) external pure returns (bool);\\n}\\n\",\"keccak256\":\"0x4c1631cf45ea6daac0ec158c3edb9453099130b6b64f697004b83f95aa1f7350\",\"license\":\"Apache-2.0\"},\"contracts/libraries/DefaultLibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary DefaultLibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (\\n uint256 facetIndex;\\n facetIndex < _diamondCut.length;\\n facetIndex++\\n ) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(\\n address _facetAddress,\\n bytes4[] memory _functionSelectors\\n ) internal {\\n uint256 funcSelectorsLength = _functionSelectors.length;\\n require(\\n funcSelectorsLength > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _facetAddress != address(0),\\n \\\"LibDiamondCut: Add facet can't be address(0)\\\"\\n );\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (\\n uint256 selectorIndex;\\n selectorIndex < funcSelectorsLength;\\n selectorIndex++\\n ) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds\\n .selectorToFacetAndPosition[selector]\\n .facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(\\n address _facetAddress,\\n bytes4[] memory _functionSelectors\\n ) internal {\\n uint256 funcSelectorsLength = _functionSelectors.length;\\n require(\\n funcSelectorsLength > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _facetAddress != address(0),\\n \\\"LibDiamondCut: Replace facet can't be address(0)\\\"\\n );\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (\\n uint256 selectorIndex;\\n selectorIndex < funcSelectorsLength;\\n selectorIndex++\\n ) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds\\n .selectorToFacetAndPosition[selector]\\n .facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same facet\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(\\n address _facetAddress,\\n bytes4[] memory _functionSelectors\\n ) internal {\\n uint256 funcSelectorsLength = _functionSelectors.length;\\n require(\\n funcSelectorsLength > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(\\n _facetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n for (\\n uint256 selectorIndex;\\n selectorIndex < funcSelectorsLength;\\n selectorIndex++\\n ) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds\\n .selectorToFacetAndPosition[selector]\\n .facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(\\n DiamondStorage storage ds,\\n address _facetAddress\\n ) internal {\\n enforceHasContractCode(\\n _facetAddress,\\n \\\"LibDiamondCut: New facet has no code\\\"\\n );\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds\\n .facetAddresses\\n .length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds\\n .selectorToFacetAndPosition[_selector]\\n .functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(\\n _selector\\n );\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(\\n _facetAddress != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // an immutable function is a function defined directly in a diamond\\n require(\\n _facetAddress != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds\\n .selectorToFacetAndPosition[_selector]\\n .functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors[lastSelectorPosition];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n selectorPosition\\n ] = lastSelector;\\n ds\\n .selectorToFacetAndPosition[lastSelector]\\n .functionSelectorPosition = uint96(selectorPosition);\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[\\n lastFacetAddressPosition\\n ];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds\\n .facetFunctionSelectors[lastFacetAddress]\\n .facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds\\n .facetFunctionSelectors[_facetAddress]\\n .facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x1b08f332d62919288bb1f0d154ca4b85f4e167d2a06e680f8ec93dba65be3be1\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x6080604052604051620020183803806200201883398101604081905262000026916200156b565b60408051600480825260a08201909252600091816020015b604080516060808201835260008083526020830152918101919091528152602001906001900390816200003e5750506040805160018082528183019092529192506000919060208083019080368337019050509050631f931c1c60e01b81600081518110620000b157620000b1620015c8565b6001600160e01b03199290921660209283029190910182015260408051600580825260c08201909252600092909190820160a08036833701905050905063b61d27f660e01b816000815181106200010c576200010c620015c8565b6001600160e01b03199092166020928302919091019091015280516323f0ed1560e11b9082906001908110620001465762000146620015c8565b6001600160e01b0319909216602092830291909101909101528051633a871cdd60e01b9082906002908110620001805762000180620015c8565b6001600160e01b0319909216602092830291909101909101528051631a10fa5160e31b9082906003908110620001ba57620001ba620015c8565b6001600160e01b031990921660209283029190910190910152805163586b48ff60e11b9082906004908110620001f457620001f4620015c8565b6001600160e01b03199290921660209283029190910182015260408051600580825260c08201909252600092909190820160a08036833701905050905063150b7a0260e01b816000815181106200024f576200024f620015c8565b6001600160e01b031990921660209283029190910190910152805163f23a6e6160e01b9082906001908110620002895762000289620015c8565b6001600160e01b031990921660209283029190910190910152805163bc197c8160e01b9082906002908110620002c357620002c3620015c8565b6001600160e01b03199092166020928302919091019091015280516223de2960e01b9082906003908110620002fc57620002fc620015c8565b6001600160e01b0319909216602092830291909101909101528051635260769b60e11b9082906004908110620003365762000336620015c8565b6001600160e01b0319929092166020928302919091018201526040805160098082526101408201909252600092909190820161012080368337019050509050637a0ed62760e01b81600081518110620003935762000393620015c8565b6001600160e01b03199092166020928302919091019091015280516356fe50af60e11b9082906001908110620003cd57620003cd620015c8565b6001600160e01b03199092166020928302919091019091015280516314bbdacb60e21b9082906002908110620004075762000407620015c8565b6001600160e01b03199092166020928302919091019091015280516366ffd66360e11b9082906003908110620004415762000441620015c8565b6001600160e01b03199092166020928302919091019091015280516301ffc9a760e01b90829060049081106200047b576200047b620015c8565b6001600160e01b031990921660209283029190910190910152805163f9796ccf60e01b9082906005908110620004b557620004b5620015c8565b6001600160e01b031990921660209283029190910190910152805162d2a81160e11b9082906006908110620004ee57620004ee620015c8565b6001600160e01b031990921660209283029190910190910152805163d42139a960e01b9082906007908110620005285762000528620015c8565b6001600160e01b03199092166020928302919091019091015280516371d17b7f60e11b9082906008908110620005625762000562620015c8565b6001600160e01b031990921660209283029190910182015260408051606081019091526001600160a01b038b168152908101600081526020018581525085600081518110620005b557620005b5620015c8565b60200260200101819052506040518060600160405280896001600160a01b0316815260200160006002811115620005f057620005f0620015de565b815260200184815250856001815181106200060f576200060f620015c8565b60200260200101819052506040518060600160405280886001600160a01b03168152602001600060028111156200064a576200064a620015de565b81526020018381525085600281518110620006695762000669620015c8565b60200260200101819052506040518060600160405280876001600160a01b0316815260200160006002811115620006a457620006a4620015de565b81526020018281525085600381518110620006c357620006c3620015c8565b6020026020010181905250620006f1856000604051806020016040528060008152506200070060201b60201c565b5050505050505050506200184c565b60005b83518110156200090c576000848281518110620007245762000724620015c8565b602002602001015160200151905060006002811115620007485762000748620015de565b8160028111156200075d576200075d620015de565b03620007bb57620007b58583815181106200077c576200077c620015c8565b6020026020010151600001518684815181106200079d576200079d620015c8565b6020026020010151604001516200095b60201b60201c565b620008f6565b6001816002811115620007d257620007d2620015de565b036200082a57620007b5858381518110620007f157620007f1620015c8565b602002602001015160000151868481518110620008125762000812620015c8565b60200260200101516040015162000bf760201b60201c565b6002816002811115620008415762000841620015de565b036200089957620007b5858381518110620008605762000860620015c8565b602002602001015160000151868481518110620008815762000881620015c8565b60200260200101516040015162000ea160201b60201c565b60405162461bcd60e51b815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f727265637420466163657443756044820152663a20b1ba34b7b760c91b60648201526084015b60405180910390fd5b508062000903816200160a565b91505062000703565b507f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb67383838360405162000942939291906200167a565b60405180910390a162000956828262001005565b505050565b805180620009af5760405162461bcd60e51b815260206004820152602b602482015260008051602062001ff883398151915260448201526a1858d95d081d1bc818dd5d60aa1b6064820152608401620008ed565b60008051602062001f8c8339815191526001600160a01b03841662000a2c5760405162461bcd60e51b815260206004820152602c60248201527f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260448201526b65206164647265737328302960a01b6064820152608401620008ed565b6001600160a01b0384166000908152600182016020526040812054906001600160601b038216900362000a655762000a658286620010dd565b60005b8381101562000bef57600085828151811062000a885762000a88620015c8565b6020908102919091018101516001600160e01b031981166000908152918690526040909120549091506001600160a01b0316801562000b305760405162461bcd60e51b815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c72656164792065786973747300000000000000000000006064820152608401620008ed565b6001600160e01b0319821660008181526020878152604080832080546001600160a01b03908116600160a01b6001600160601b038c16021782558d168085526001808c0185529285208054938401815585528385206008840401805463ffffffff60079095166004026101000a948502191660e08a901c94909402939093179092559390925287905281546001600160a01b0319161790558362000bd48162001781565b9450505050808062000be6906200160a565b91505062000a68565b505050505050565b80518062000c4b5760405162461bcd60e51b815260206004820152602b602482015260008051602062001ff883398151915260448201526a1858d95d081d1bc818dd5d60aa1b6064820152608401620008ed565b60008051602062001f8c8339815191526001600160a01b03841662000ccc5760405162461bcd60e51b815260206004820152603060248201527f4c69624469616d6f6e644375743a205265706c6163652066616365742063616e60448201526f2774206265206164647265737328302960801b6064820152608401620008ed565b6001600160a01b0384166000908152600182016020526040812054906001600160601b038216900362000d055762000d058286620010dd565b60005b8381101562000bef57600085828151811062000d285762000d28620015c8565b6020908102919091018101516001600160e01b031981166000908152918690526040909120549091506001600160a01b03908116908816810362000dd55760405162461bcd60e51b815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d6520666163657400000000000000000000006064820152608401620008ed565b62000de28582846200114a565b6001600160e01b0319821660008181526020878152604080832080546001600160a01b03908116600160a01b6001600160601b038c16021782558d168085526001808c0185529285208054938401815585528385206008840401805463ffffffff60079095166004026101000a948502191660e08a901c94909402939093179092559390925287905281546001600160a01b0319161790558362000e868162001781565b9450505050808062000e98906200160a565b91505062000d08565b80518062000ef55760405162461bcd60e51b815260206004820152602b602482015260008051602062001ff883398151915260448201526a1858d95d081d1bc818dd5d60aa1b6064820152608401620008ed565b60008051602062001f8c8339815191526001600160a01b0384161562000f845760405162461bcd60e51b815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d7573742062652061646472657373283029000000000000000000006064820152608401620008ed565b60005b8281101562000ffe57600084828151811062000fa75762000fa7620015c8565b6020908102919091018101516001600160e01b031981166000908152918590526040909120549091506001600160a01b031662000fe68482846200114a565b5050808062000ff5906200160a565b91505062000f87565b5050505050565b6001600160a01b03821662001018575050565b6200103d8260405180606001604052806028815260200162001fac602891396200152a565b600080836001600160a01b0316836040516200105a9190620017b2565b600060405180830381855af49150503d806000811462001097576040519150601f19603f3d011682016040523d82523d6000602084013e6200109c565b606091505b509150915081620010d757805115620010b85780518082602001fd5b838360405163192105d760e01b8152600401620008ed929190620017d0565b50505050565b620011028160405180606001604052806024815260200162001fd4602491396200152a565b6002820180546001600160a01b0390921660008181526001948501602090815260408220860185905594840183559182529290200180546001600160a01b0319169091179055565b6001600160a01b038216620011c85760405162461bcd60e51b815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608401620008ed565b306001600160a01b03831603620012395760405162461bcd60e51b815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201526d3a30b1363290333ab731ba34b7b760911b6064820152608401620008ed565b6001600160e01b03198116600090815260208481526040808320546001600160a01b0386168452600180880190935290832054600160a01b9091046001600160601b031692916200128a91620017fe565b905080821462001383576001600160a01b03841660009081526001860160205260408120805483908110620012c357620012c3620015c8565b600091825260208083206008830401546001600160a01b038916845260018a019091526040909220805460079092166004026101000a90920460e01b925082919085908110620013175762001317620015c8565b600091825260208083206008830401805463ffffffff60079094166004026101000a938402191660e09590951c929092029390931790556001600160e01b03199290921682528690526040902080546001600160a01b0316600160a01b6001600160601b038516021790555b6001600160a01b03841660009081526001860160205260409020805480620013af57620013af6200181a565b60008281526020808220600860001990940193840401805463ffffffff600460078716026101000a0219169055919092556001600160e01b0319851682528690526040812081905581900362000ffe5760028501546000906200141590600190620017fe565b6001600160a01b0386166000908152600180890160205260409091200154909150808214620014cb576000876002018381548110620014585762001458620015c8565b6000918252602090912001546002890180546001600160a01b0390921692508291849081106200148c576200148c620015c8565b600091825260208083209190910180546001600160a01b0319166001600160a01b03948516179055929091168152600189810190925260409020018190555b86600201805480620014e157620014e16200181a565b60008281526020808220830160001990810180546001600160a01b03191690559092019092556001600160a01b0388168252600189810190915260408220015550505050505050565b813b8181620010d75760405162461bcd60e51b8152600401620008ed919062001830565b80516001600160a01b03811681146200156657600080fd5b919050565b600080600080608085870312156200158257600080fd5b6200158d856200154e565b93506200159d602086016200154e565b9250620015ad604086016200154e565b9150620015bd606086016200154e565b905092959194509250565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016200161f576200161f620015f4565b5060010190565b60005b838110156200164357818101518382015260200162001629565b50506000910152565b600081518084526200166681602086016020860162001626565b601f01601f19169290920160200192915050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b848110156200174f57898403607f19018652815180516001600160a01b03168552838101518986019060038110620016eb57634e487b7160e01b600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b80831015620017395783516001600160e01b03191682529286019260019290920191908601906200170d565b50978501979550505090820190600101620016a3565b50506001600160a01b038a169088015286810360408801526200177381896200164c565b9a9950505050505050505050565b60006001600160601b038281166002600160601b03198101620017a857620017a8620015f4565b6001019392505050565b60008251620017c681846020870162001626565b9190910192915050565b6001600160a01b0383168152604060208201819052600090620017f6908301846200164c565b949350505050565b81810381811115620018145762001814620015f4565b92915050565b634e487b7160e01b600052603160045260246000fd5b6020815260006200184560208301846200164c565b9392505050565b610730806200185c6000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806352ef6b2c146100515780637a0ed6271461006f578063adfca15e14610084578063cdffacc6146100a4575b600080fd5b610059610140565b60405161006691906104ab565b60405180910390f35b6100776101d1565b6040516100669190610562565b61009761009236600461060a565b6103d1565b6040516100669190610647565b61011b6100b236600461065a565b7fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610066565b60607f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6002018054806020026020016040519081016040528092919081815260200182805480156101c757602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161019c575b5050505050905090565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f908067ffffffffffffffff8111156102315761023161069c565b60405190808252806020026020018201604052801561027757816020015b60408051808201909152600081526060602082015281526020019060019003908161024f5790505b50925060005b818110156103cb57600083600201828154811061029c5761029c6106cb565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050808583815181106102dc576102dc6106cb565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff928316905290821660009081526001860182526040908190208054825181850281018501909352808352919290919083018282801561039d57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161034a5790505b50505050508583815181106103b4576103b46106cb565b60209081029190910181015101525060010161027d565b50505090565b73ffffffffffffffffffffffffffffffffffffffff811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4920602090815260409182902080548351818402810184019094528084526060939283018282801561049f57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161044c5790505b50505050509050919050565b6020808252825182820181905260009190848201906040850190845b818110156104f957835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016104c7565b50909695505050505050565b600081518084526020808501945080840160005b838110156105575781517fffffffff000000000000000000000000000000000000000000000000000000001687529582019590820190600101610519565b509495945050505050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b838110156105fc578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00185528151805173ffffffffffffffffffffffffffffffffffffffff1684528701518784018790526105e987850182610505565b9588019593505090860190600101610589565b509098975050505050505050565b60006020828403121561061c57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461064057600080fd5b9392505050565b6020815260006106406020830184610505565b60006020828403121561066c57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461064057600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea264697066735822122024a872696a5ad50024326567061c50adea63ff0d49edf0ac60339459d33d571664736f6c63430008150033183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f4c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a204e657720666163657420686173206e6f20636f64654c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e2066", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806352ef6b2c146100515780637a0ed6271461006f578063adfca15e14610084578063cdffacc6146100a4575b600080fd5b610059610140565b60405161006691906104ab565b60405180910390f35b6100776101d1565b6040516100669190610562565b61009761009236600461060a565b6103d1565b6040516100669190610647565b61011b6100b236600461065a565b7fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610066565b60607f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6002018054806020026020016040519081016040528092919081815260200182805480156101c757602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161019c575b5050505050905090565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f908067ffffffffffffffff8111156102315761023161069c565b60405190808252806020026020018201604052801561027757816020015b60408051808201909152600081526060602082015281526020019060019003908161024f5790505b50925060005b818110156103cb57600083600201828154811061029c5761029c6106cb565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050808583815181106102dc576102dc6106cb565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff928316905290821660009081526001860182526040908190208054825181850281018501909352808352919290919083018282801561039d57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161034a5790505b50505050508583815181106103b4576103b46106cb565b60209081029190910181015101525060010161027d565b50505090565b73ffffffffffffffffffffffffffffffffffffffff811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4920602090815260409182902080548351818402810184019094528084526060939283018282801561049f57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161044c5790505b50505050509050919050565b6020808252825182820181905260009190848201906040850190845b818110156104f957835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016104c7565b50909695505050505050565b600081518084526020808501945080840160005b838110156105575781517fffffffff000000000000000000000000000000000000000000000000000000001687529582019590820190600101610519565b509495945050505050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b838110156105fc578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00185528151805173ffffffffffffffffffffffffffffffffffffffff1684528701518784018790526105e987850182610505565b9588019593505090860190600101610589565b509098975050505050505050565b60006020828403121561061c57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461064057600080fd5b9392505050565b6020815260006106406020830184610505565b60006020828403121561066c57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461064057600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea264697066735822122024a872696a5ad50024326567061c50adea63ff0d49edf0ac60339459d33d571664736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "A default fallback handler for Barz", + "kind": "dev", + "methods": { + "constructor": { + "details": "This contract is also a diamond that holds the default facets to reduce gas cost for wallet activation. Within the constructor this conducts diamond cut to initially setup the diamond. This is a non-upgradeable contract", + "params": { + "_accountFacet": "Address account facet", + "_diamondCutFacet": "Address if diamond cut facet", + "_diamondLoupeFacet": "Address of diamond loupe facet", + "_tokenReceiverFacet": "Address of token receiver facet" + } + }, + "facetAddress(bytes4)": { + "details": "If facet is not found return address(0).", + "params": { + "_functionSelector": "The function selector." + }, + "returns": { + "facetAddress_": "The facet address." + } + }, + "facetAddresses()": { + "returns": { + "facetAddresses_": "facetAddresses_" + } + }, + "facetFunctionSelectors(address)": { + "params": { + "_facet": "The facet address." + }, + "returns": { + "facetFunctionSelectors_": "facetFunctionSelectors_" + } + }, + "facets()": { + "returns": { + "facets_": "The facet struct array including all facet information" + } + } + }, + "title": "DefaultFallbackHandler", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "constructor": { + "notice": "Sets the middleware diamond for Barz wallet as a fallback handler" + }, + "facetAddress(bytes4)": { + "notice": "Gets the facet that supports the given selector." + }, + "facetAddresses()": { + "notice": "Get all the facet addresses used by a diamond." + }, + "facetFunctionSelectors(address)": { + "notice": "Gets all the function selectors provided by a facet." + }, + "facets()": { + "notice": "Returns the facet information of call facets registered to this diamond." + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/linea/DiamondCutFacet.json b/deployments/linea/DiamondCutFacet.json new file mode 100644 index 0000000..20be094 --- /dev/null +++ b/deployments/linea/DiamondCutFacet.json @@ -0,0 +1,856 @@ +{ + "address": "0x0B9504140771C3688Ff041917192277D2f52E1e0", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_securityManager", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "CallerNotGuardian", + "type": "error" + }, + { + "inputs": [], + "name": "CallerNotGuardianOrOwner", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__CannotRevokeUnapproved", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__DuplicateApproval", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InsufficientApprovers", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidApprovalValidationPeriod", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidApprover", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidApproverSignature", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidArrayLength", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidInitAddress", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidRouteWithGuardian", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidRouteWithoutGuardian", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__LackOfOwnerApproval", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__OwnerAlreadyApproved", + "type": "error" + }, + { + "inputs": [], + "name": "DuplicateApprover", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_initializationContractAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "InitializationFunctionReverted", + "type": "error" + }, + { + "inputs": [], + "name": "UnregisteredFacetAndSelectors", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroApproverLength", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "indexed": false, + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "DiamondCut", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "diamondCut", + "type": "tuple[]" + } + ], + "name": "DiamondCutApprovalRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "diamondCut", + "type": "tuple[]" + } + ], + "name": "DiamondCutApproved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + }, + { + "indexed": false, + "internalType": "bool", + "name": "_lag", + "type": "bool" + } + ], + "name": "SupportsInterfaceUpdated", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_diamondCutHash", + "type": "bytes32" + }, + { + "internalType": "address[]", + "name": "_approvers", + "type": "address[]" + } + ], + "name": "_checkDuplicateOnChainApprover", + "outputs": [], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + } + ], + "name": "approveDiamondCut", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "diamondCut", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "internalType": "address[]", + "name": "_approvers", + "type": "address[]" + }, + { + "internalType": "bytes[]", + "name": "_signatures", + "type": "bytes[]" + } + ], + "name": "diamondCutWithGuardian", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_diamondCutHash", + "type": "bytes32" + } + ], + "name": "getDiamondCutApprovalCountWithTimeValidity", + "outputs": [ + { + "internalType": "uint256", + "name": "approvalCount", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + } + ], + "name": "getDiamondCutHash", + "outputs": [ + { + "internalType": "bytes32", + "name": "cutHash", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getDiamondCutNonce", + "outputs": [ + { + "internalType": "uint128", + "name": "cutNonce", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_diamondCutHash", + "type": "bytes32" + } + ], + "name": "getOwnerCutApprovalWithTimeValidity", + "outputs": [ + { + "internalType": "bool", + "name": "isApprovedByOwner", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_diamondCutHash", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "_approver", + "type": "address" + } + ], + "name": "isCutApproved", + "outputs": [ + { + "internalType": "bool", + "name": "isApproved", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + } + ], + "name": "revokeDiamondCutApproval", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "securityManager", + "outputs": [ + { + "internalType": "contract ISecurityManager", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_interfaceId", + "type": "bytes4" + }, + { + "internalType": "bool", + "name": "_flag", + "type": "bool" + } + ], + "name": "updateSupportsInterface", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0x33a3921707ed3d14138fe67bf885f1e815c298737eea76fe71073b068f39414c", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 5, + "gasUsed": "3078987", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0xab83f232c42f6e4871f93d8ac0dd8c592b5ea43da815b04819c5592baab59fe1", + "transactionHash": "0x33a3921707ed3d14138fe67bf885f1e815c298737eea76fe71073b068f39414c", + "logs": [], + "blockNumber": 2720821, + "cumulativeGasUsed": "3442976", + "status": 1, + "byzantium": true + }, + "args": [ + "0xcBe266adbfd7CB32988128e7f37b7c8b3C5521A8" + ], + "numDeployments": 1, + "solcInputHash": "ad34345aa73d96f52b3e14df983b6b29", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_securityManager\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"CallerNotGuardian\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallerNotGuardianOrOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__CannotRevokeUnapproved\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__DuplicateApproval\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InsufficientApprovers\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidApprovalValidationPeriod\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidApprover\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidApproverSignature\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidArrayLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidInitAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidRouteWithGuardian\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidRouteWithoutGuardian\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__LackOfOwnerApproval\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__OwnerAlreadyApproved\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateApprover\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_initializationContractAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"InitializationFunctionReverted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnregisteredFacetAndSelectors\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroApproverLength\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"DiamondCut\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"diamondCut\",\"type\":\"tuple[]\"}],\"name\":\"DiamondCutApprovalRevoked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"diamondCut\",\"type\":\"tuple[]\"}],\"name\":\"DiamondCutApproved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"_lag\",\"type\":\"bool\"}],\"name\":\"SupportsInterfaceUpdated\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_diamondCutHash\",\"type\":\"bytes32\"},{\"internalType\":\"address[]\",\"name\":\"_approvers\",\"type\":\"address[]\"}],\"name\":\"_checkDuplicateOnChainApprover\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"}],\"name\":\"approveDiamondCut\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"diamondCut\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"internalType\":\"address[]\",\"name\":\"_approvers\",\"type\":\"address[]\"},{\"internalType\":\"bytes[]\",\"name\":\"_signatures\",\"type\":\"bytes[]\"}],\"name\":\"diamondCutWithGuardian\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_diamondCutHash\",\"type\":\"bytes32\"}],\"name\":\"getDiamondCutApprovalCountWithTimeValidity\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"approvalCount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"}],\"name\":\"getDiamondCutHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"cutHash\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDiamondCutNonce\",\"outputs\":[{\"internalType\":\"uint128\",\"name\":\"cutNonce\",\"type\":\"uint128\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_diamondCutHash\",\"type\":\"bytes32\"}],\"name\":\"getOwnerCutApprovalWithTimeValidity\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isApprovedByOwner\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_diamondCutHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"_approver\",\"type\":\"address\"}],\"name\":\"isCutApproved\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isApproved\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"}],\"name\":\"revokeDiamondCutApproval\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"securityManager\",\"outputs\":[{\"internalType\":\"contract ISecurityManager\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_interfaceId\",\"type\":\"bytes4\"},{\"internalType\":\"bool\",\"name\":\"_flag\",\"type\":\"bool\"}],\"name\":\"updateSupportsInterface\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"Responsible for adding/removing/replace facets in Barz\",\"kind\":\"dev\",\"methods\":{\"_checkDuplicateOnChainApprover(bytes32,address[])\":{\"params\":{\"_approvers\":\"List of approver addresses\",\"_diamondCutHash\":\"Hash of diamondCut information including the facet addresses and function selectors\"}},\"approveDiamondCut((address,uint8,bytes4[])[])\":{\"params\":{\"_diamondCut\":\"Contains the facet addresses and function selectors\"}},\"constructor\":{\"params\":{\"_securityManager\":\"Security Manager contract that holds the security related variables for all wallets\"}},\"diamondCut((address,uint8,bytes4[])[],address,bytes)\":{\"params\":{\"_diamondCut\":\"Contains the facet addresses and function selectors\",\"_init\":\"The address of the contract or facet to execute _calldata. It's prohibited in Barz\"}},\"diamondCutWithGuardian((address,uint8,bytes4[])[],address[],bytes[])\":{\"params\":{\"_approvers\":\"Guardian or owner address that approves the diamond cut\",\"_diamondCut\":\"Contains the facet addresses and function selectors\",\"_signatures\":\"Signature of Guardians or owner that approves the diamond cut\"}},\"getDiamondCutApprovalCountWithTimeValidity(bytes32)\":{\"params\":{\"_diamondCutHash\":\"Hash of diamondCut information including the facet addresses and function selectors\"}},\"getDiamondCutHash((address,uint8,bytes4[])[])\":{\"params\":{\"_diamondCut\":\"Contains the facet addresses and function selectors\"},\"returns\":{\"cutHash\":\"Diamond Cut Hash\"}},\"getDiamondCutNonce()\":{\"details\":\"This method fetches the nonce from diamond cut storage\",\"returns\":{\"cutNonce\":\"Nonce of diamond cut to protect from reply attacks\"}},\"getOwnerCutApprovalWithTimeValidity(bytes32)\":{\"params\":{\"_diamondCutHash\":\"Hash of diamondCut information including the facet addresses and function selectors\"},\"returns\":{\"isApprovedByOwner\":\"Bool value showing if the owner approved the cut\"}},\"isCutApproved(bytes32,address)\":{\"params\":{\"_approver\":\"Address of approver\",\"_diamondCutHash\":\"Hash of diamondCut information including the facet addresses and function selectors\"},\"returns\":{\"isApproved\":\"Bool value showing if the approver approved the cut\"}},\"revokeDiamondCutApproval((address,uint8,bytes4[])[])\":{\"params\":{\"_diamondCut\":\"Contains the facet addresses and function selectors\"}},\"updateSupportsInterface(bytes4,bool)\":{\"params\":{\"_flag\":\"Bool value to update the mapping of the given interface ID\",\"_interfaceId\":\"InterfaceID to update the mapping\"}}},\"title\":\"DiamondCut Facet\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"_checkDuplicateOnChainApprover(bytes32,address[])\":{\"notice\":\"Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval Approvers who approved on-chain should not be included in the off-chain approval\"},\"approveDiamondCut((address,uint8,bytes4[])[])\":{\"notice\":\"Approves diamond cut. This can only be called directly from guardian or owner\"},\"constructor\":{\"notice\":\"This constructor sets the Security Manager address which is an immutable variable. Immutable variables do not impact the storage of diamond\"},\"diamondCut((address,uint8,bytes4[])[],address,bytes)\":{\"notice\":\"Add/replace/remove any number of functions and optionally execute a function with delegatecall when guardians don't exist\"},\"diamondCutWithGuardian((address,uint8,bytes4[])[],address[],bytes[])\":{\"notice\":\"Add/replace/remove any number of functions and optionally execute a function with delegatecall when guardians exist\"},\"getDiamondCutApprovalCountWithTimeValidity(bytes32)\":{\"notice\":\"Gets the number of approvals of diamond cut from guardians\"},\"getDiamondCutHash((address,uint8,bytes4[])[])\":{\"notice\":\"Returns the diamond cut hash. This function ensures that this hash is safe from replay attack by including salt, address, chainId, and nonce, etc.\"},\"getDiamondCutNonce()\":{\"notice\":\"Returns the diamond cut nonce of this wallet\"},\"getOwnerCutApprovalWithTimeValidity(bytes32)\":{\"notice\":\"Returns if the owner has approved the diamond cut\"},\"isCutApproved(bytes32,address)\":{\"notice\":\"Returns if the given approver has approved the diamond cut\"},\"revokeDiamondCutApproval((address,uint8,bytes4[])[])\":{\"notice\":\"Revokes the approval of diamond cut. This can only be called directly from guardian or owner\"},\"updateSupportsInterface(bytes4,bool)\":{\"notice\":\"Updates the flag for the interfaceId\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/base/DiamondCutFacet.sol\":\"DiamondCutFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/interfaces/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC1271 standard signature validation method for\\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC1271 {\\n /**\\n * @dev Should return whether the signature provided is valid for the provided data\\n * @param hash Hash of the data to be signed\\n * @param signature Signature byte array associated with _data\\n */\\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\\n}\\n\",\"keccak256\":\"0x0705a4b1b86d7b0bd8432118f226ba139c44b9dcaba0a6eafba2dd7d0639c544\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./math/Math.sol\\\";\\nimport \\\"./math/SignedMath.sol\\\";\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n uint256 length = Math.log10(value) + 1;\\n string memory buffer = new string(length);\\n uint256 ptr;\\n /// @solidity memory-safe-assembly\\n assembly {\\n ptr := add(buffer, add(32, length))\\n }\\n while (true) {\\n ptr--;\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\\n }\\n value /= 10;\\n if (value == 0) break;\\n }\\n return buffer;\\n }\\n }\\n\\n /**\\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\\n */\\n function toString(int256 value) internal pure returns (string memory) {\\n return string(abi.encodePacked(value < 0 ? \\\"-\\\" : \\\"\\\", toString(SignedMath.abs(value))));\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n return toHexString(value, Math.log256(value) + 1);\\n }\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n\\n /**\\n * @dev Returns true if the two strings are equal.\\n */\\n function equal(string memory a, string memory b) internal pure returns (bool) {\\n return keccak256(bytes(a)) == keccak256(bytes(b));\\n }\\n}\\n\",\"keccak256\":\"0x3088eb2868e8d13d89d16670b5f8612c4ab9ff8956272837d8e90106c59c14a0\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Strings.sol\\\";\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSA {\\n enum RecoverError {\\n NoError,\\n InvalidSignature,\\n InvalidSignatureLength,\\n InvalidSignatureS,\\n InvalidSignatureV // Deprecated in v4.8\\n }\\n\\n function _throwError(RecoverError error) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert(\\\"ECDSA: invalid signature\\\");\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert(\\\"ECDSA: invalid signature length\\\");\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert(\\\"ECDSA: invalid signature 's' value\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature` or error string. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n *\\n * Documentation for signature generation:\\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n return tryRecover(hash, v, r, s);\\n } else {\\n return (address(0), RecoverError.InvalidSignatureLength);\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature`. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, signature);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\\n uint8 v = uint8((uint256(vs) >> 255) + 27);\\n return tryRecover(hash, v, r, s);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n *\\n * _Available since v4.2._\\n */\\n function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\\n // the valid range for s in (301): 0 < s < secp256k1n \\u00f7 2 + 1, and for v in (302): v \\u2208 {27, 28}. Most\\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\\n //\\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\\n // these malleable signatures as well.\\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n return (address(0), RecoverError.InvalidSignatureS);\\n }\\n\\n // If the signature is valid (and not malleable), return the signer address\\n address signer = ecrecover(hash, v, r, s);\\n if (signer == address(0)) {\\n return (address(0), RecoverError.InvalidSignature);\\n }\\n\\n return (signer, RecoverError.NoError);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore(0x00, \\\"\\\\x19Ethereum Signed Message:\\\\n32\\\")\\n mstore(0x1c, hash)\\n message := keccak256(0x00, 0x3c)\\n }\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from `s`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n\\\", Strings.toString(s.length), s));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Typed Data, created from a\\n * `domainSeparator` and a `structHash`. This produces hash corresponding\\n * to the one signed with the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n * JSON-RPC method as part of EIP-712.\\n *\\n * See {recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n let ptr := mload(0x40)\\n mstore(ptr, \\\"\\\\x19\\\\x01\\\")\\n mstore(add(ptr, 0x02), domainSeparator)\\n mstore(add(ptr, 0x22), structHash)\\n data := keccak256(ptr, 0x42)\\n }\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Data with intended validator, created from a\\n * `validator` and `data` according to the version 0 of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x00\\\", validator, data));\\n }\\n}\\n\",\"keccak256\":\"0x809bc3edb4bcbef8263fa616c1b60ee0004b50a8a1bfa164d8f57fd31f520c58\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/SignatureChecker.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./ECDSA.sol\\\";\\nimport \\\"../../interfaces/IERC1271.sol\\\";\\n\\n/**\\n * @dev Signature verification helper that can be used instead of `ECDSA.recover` to seamlessly support both ECDSA\\n * signatures from externally owned accounts (EOAs) as well as ERC1271 signatures from smart contract wallets like\\n * Argent and Gnosis Safe.\\n *\\n * _Available since v4.1._\\n */\\nlibrary SignatureChecker {\\n /**\\n * @dev Checks if a signature is valid for a given signer and data hash. If the signer is a smart contract, the\\n * signature is validated against that smart contract using ERC1271, otherwise it's validated using `ECDSA.recover`.\\n *\\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\\n */\\n function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature) internal view returns (bool) {\\n (address recovered, ECDSA.RecoverError error) = ECDSA.tryRecover(hash, signature);\\n return\\n (error == ECDSA.RecoverError.NoError && recovered == signer) ||\\n isValidERC1271SignatureNow(signer, hash, signature);\\n }\\n\\n /**\\n * @dev Checks if a signature is valid for a given signer and data hash. The signature is validated\\n * against the signer smart contract using ERC1271.\\n *\\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\\n */\\n function isValidERC1271SignatureNow(\\n address signer,\\n bytes32 hash,\\n bytes memory signature\\n ) internal view returns (bool) {\\n (bool success, bytes memory result) = signer.staticcall(\\n abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, signature)\\n );\\n return (success &&\\n result.length >= 32 &&\\n abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector));\\n }\\n}\\n\",\"keccak256\":\"0x3af3ca86df39aac39a0514c84459d691434a108d2151c8ce9d69f32e315cab80\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n enum Rounding {\\n Down, // Toward negative infinity\\n Up, // Toward infinity\\n Zero // Toward zero\\n }\\n\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow.\\n return (a & b) + (a ^ b) / 2;\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a == 0 ? 0 : (a - 1) / b + 1;\\n }\\n\\n /**\\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\\n * with further edits by Uniswap Labs also under MIT license.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\\n unchecked {\\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2^256 + prod0.\\n uint256 prod0; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division.\\n if (prod1 == 0) {\\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\\n // The surrounding unchecked block does not change this fact.\\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\\n return prod0 / denominator;\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n require(denominator > prod1, \\\"Math: mulDiv overflow\\\");\\n\\n ///////////////////////////////////////////////\\n // 512 by 256 division.\\n ///////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0].\\n uint256 remainder;\\n assembly {\\n // Compute remainder using mulmod.\\n remainder := mulmod(x, y, denominator)\\n\\n // Subtract 256 bit number from 512 bit number.\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\\n // See https://cs.stackexchange.com/q/138556/92363.\\n\\n // Does not overflow because the denominator cannot be zero at this stage in the function.\\n uint256 twos = denominator & (~denominator + 1);\\n assembly {\\n // Divide denominator by twos.\\n denominator := div(denominator, twos)\\n\\n // Divide [prod1 prod0] by twos.\\n prod0 := div(prod0, twos)\\n\\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\\n twos := add(div(sub(0, twos), twos), 1)\\n }\\n\\n // Shift in bits from prod1 into prod0.\\n prod0 |= prod1 * twos;\\n\\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\\n // four bits. That is, denominator * inv = 1 mod 2^4.\\n uint256 inverse = (3 * denominator) ^ 2;\\n\\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\\n // in modular arithmetic, doubling the correct bits in each step.\\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\\n\\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inverse;\\n return result;\\n }\\n }\\n\\n /**\\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\\n uint256 result = mulDiv(x, y, denominator);\\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\\n result += 1;\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\\n *\\n * Inspired by Henry S. Warren, Jr.'s \\\"Hacker's Delight\\\" (Chapter 11).\\n */\\n function sqrt(uint256 a) internal pure returns (uint256) {\\n if (a == 0) {\\n return 0;\\n }\\n\\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\\n //\\n // We know that the \\\"msb\\\" (most significant bit) of our target number `a` is a power of 2 such that we have\\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\\n //\\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\\n // \\u2192 `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\\n // \\u2192 `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\\n //\\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\\n uint256 result = 1 << (log2(a) >> 1);\\n\\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\\n // into the expected uint128 result.\\n unchecked {\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n return min(result, a / result);\\n }\\n }\\n\\n /**\\n * @notice Calculates sqrt(a), following the selected rounding direction.\\n */\\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = sqrt(a);\\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 2, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 128;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 64;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 32;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 16;\\n }\\n if (value >> 8 > 0) {\\n value >>= 8;\\n result += 8;\\n }\\n if (value >> 4 > 0) {\\n value >>= 4;\\n result += 4;\\n }\\n if (value >> 2 > 0) {\\n value >>= 2;\\n result += 2;\\n }\\n if (value >> 1 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log2(value);\\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 10, rounded down, of a positive value.\\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 + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 256, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n *\\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\\n */\\n function log256(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 16;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 8;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 4;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 2;\\n }\\n if (value >> 8 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log256(value);\\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe4455ac1eb7fc497bb7402579e7b4d64d928b846fce7d2b6fde06d366f21c2b3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\\n * checks.\\n *\\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\\n * easily result in undesired exploitation or bugs, since developers usually\\n * assume that overflows raise errors. `SafeCast` restores this intuition by\\n * reverting the transaction when such an operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n *\\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\\n * all math on `uint256` and `int256` and then downcasting.\\n */\\nlibrary SafeCast {\\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 * _Available since v4.7._\\n */\\n function toUint248(uint256 value) internal pure returns (uint248) {\\n require(value <= type(uint248).max, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint240(uint256 value) internal pure returns (uint240) {\\n require(value <= type(uint240).max, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint232(uint256 value) internal pure returns (uint232) {\\n require(value <= type(uint232).max, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint224(uint256 value) internal pure returns (uint224) {\\n require(value <= type(uint224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint216(uint256 value) internal pure returns (uint216) {\\n require(value <= type(uint216).max, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint208(uint256 value) internal pure returns (uint208) {\\n require(value <= type(uint208).max, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint200(uint256 value) internal pure returns (uint200) {\\n require(value <= type(uint200).max, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint192(uint256 value) internal pure returns (uint192) {\\n require(value <= type(uint192).max, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint184(uint256 value) internal pure returns (uint184) {\\n require(value <= type(uint184).max, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint176(uint256 value) internal pure returns (uint176) {\\n require(value <= type(uint176).max, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint168(uint256 value) internal pure returns (uint168) {\\n require(value <= type(uint168).max, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint160(uint256 value) internal pure returns (uint160) {\\n require(value <= type(uint160).max, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint152(uint256 value) internal pure returns (uint152) {\\n require(value <= type(uint152).max, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint144(uint256 value) internal pure returns (uint144) {\\n require(value <= type(uint144).max, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint136(uint256 value) internal pure returns (uint136) {\\n require(value <= type(uint136).max, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint128(uint256 value) internal pure returns (uint128) {\\n require(value <= type(uint128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint120(uint256 value) internal pure returns (uint120) {\\n require(value <= type(uint120).max, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint112(uint256 value) internal pure returns (uint112) {\\n require(value <= type(uint112).max, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint104(uint256 value) internal pure returns (uint104) {\\n require(value <= type(uint104).max, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint96(uint256 value) internal pure returns (uint96) {\\n require(value <= type(uint96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint88(uint256 value) internal pure returns (uint88) {\\n require(value <= type(uint88).max, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint80(uint256 value) internal pure returns (uint80) {\\n require(value <= type(uint80).max, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint72(uint256 value) internal pure returns (uint72) {\\n require(value <= type(uint72).max, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint64(uint256 value) internal pure returns (uint64) {\\n require(value <= type(uint64).max, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint56(uint256 value) internal pure returns (uint56) {\\n require(value <= type(uint56).max, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint48(uint256 value) internal pure returns (uint48) {\\n require(value <= type(uint48).max, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint40(uint256 value) internal pure returns (uint40) {\\n require(value <= type(uint40).max, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint32(uint256 value) internal pure returns (uint32) {\\n require(value <= type(uint32).max, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint24(uint256 value) internal pure returns (uint24) {\\n require(value <= type(uint24).max, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint16(uint256 value) internal pure returns (uint16) {\\n require(value <= type(uint16).max, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint8(uint256 value) internal pure returns (uint8) {\\n require(value <= type(uint8).max, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\n */\\n function toUint256(int256 value) internal pure returns (uint256) {\\n require(value >= 0, \\\"SafeCast: value must be positive\\\");\\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 * _Available since v4.7._\\n */\\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\\n downcasted = int248(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\\n downcasted = int240(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\\n downcasted = int232(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\\n downcasted = int224(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\\n downcasted = int216(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\\n downcasted = int208(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\\n downcasted = int200(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\\n downcasted = int192(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\\n downcasted = int184(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\\n downcasted = int176(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\\n downcasted = int168(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\\n downcasted = int160(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\\n downcasted = int152(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\\n downcasted = int144(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\\n downcasted = int136(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\\n downcasted = int128(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\\n downcasted = int120(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\\n downcasted = int112(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\\n downcasted = int104(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\\n downcasted = int96(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\\n downcasted = int88(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\\n downcasted = int80(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\\n downcasted = int72(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\\n downcasted = int64(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\\n downcasted = int56(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\\n downcasted = int48(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\\n downcasted = int40(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\\n downcasted = int32(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\\n downcasted = int24(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\\n downcasted = int16(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\\n downcasted = int8(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\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 require(value <= uint256(type(int256).max), \\\"SafeCast: value doesn't fit in an int256\\\");\\n return int256(value);\\n }\\n}\\n\",\"keccak256\":\"0x52a8cfb0f5239d11b457dcdd1b326992ef672714ca8da71a157255bddd13f3ad\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SignedMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard signed math utilities missing in the Solidity language.\\n */\\nlibrary SignedMath {\\n /**\\n * @dev Returns the largest of two signed numbers.\\n */\\n function max(int256 a, int256 b) internal pure returns (int256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two signed numbers.\\n */\\n function min(int256 a, int256 b) internal pure returns (int256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two signed numbers without overflow.\\n * The result is rounded towards zero.\\n */\\n function average(int256 a, int256 b) internal pure returns (int256) {\\n // Formula from the book \\\"Hacker's Delight\\\"\\n int256 x = (a & b) + ((a ^ b) >> 1);\\n return x + (int256(uint256(x) >> 255) & (a ^ b));\\n }\\n\\n /**\\n * @dev Returns the absolute unsigned value of a signed value.\\n */\\n function abs(int256 n) internal pure returns (uint256) {\\n unchecked {\\n // must be unchecked in order to support `n = type(int256).min`\\n return uint256(n >= 0 ? n : -n);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf92515413956f529d95977adc9b0567d583c6203fc31ab1c23824c35187e3ddc\",\"license\":\"MIT\"},\"contracts/aa-4337/core/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable no-inline-assembly */\\n\\n/**\\n * returned data from validateUserOp.\\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\\n * @param aggregator - address(0) - the account validated the signature by itself.\\n * address(1) - the account failed to validate the signature.\\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\\n * @param validAfter - this UserOp is valid only after this timestamp.\\n * @param validaUntil - this UserOp is valid only up to this timestamp.\\n */\\nstruct ValidationData {\\n address aggregator;\\n uint48 validAfter;\\n uint48 validUntil;\\n}\\n\\n//extract sigFailed, validAfter, validUntil.\\n// also convert zero validUntil to type(uint48).max\\nfunction _parseValidationData(\\n uint validationData\\n) pure returns (ValidationData memory data) {\\n address aggregator = address(uint160(validationData));\\n uint48 validUntil = uint48(validationData >> 160);\\n if (validUntil == 0) {\\n validUntil = type(uint48).max;\\n }\\n uint48 validAfter = uint48(validationData >> (48 + 160));\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n// intersect account and paymaster ranges.\\nfunction _intersectTimeRange(\\n uint256 validationData,\\n uint256 paymasterValidationData\\n) pure returns (ValidationData memory) {\\n ValidationData memory accountValidationData = _parseValidationData(\\n validationData\\n );\\n ValidationData memory pmValidationData = _parseValidationData(\\n paymasterValidationData\\n );\\n address aggregator = accountValidationData.aggregator;\\n if (aggregator == address(0)) {\\n aggregator = pmValidationData.aggregator;\\n }\\n uint48 validAfter = accountValidationData.validAfter;\\n uint48 validUntil = accountValidationData.validUntil;\\n uint48 pmValidAfter = pmValidationData.validAfter;\\n uint48 pmValidUntil = pmValidationData.validUntil;\\n\\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp\\n * @param data - the ValidationData to pack\\n */\\nfunction _packValidationData(\\n ValidationData memory data\\n) pure returns (uint256) {\\n return\\n uint160(data.aggregator) |\\n (uint256(data.validUntil) << 160) |\\n (uint256(data.validAfter) << (160 + 48));\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp, when not using an aggregator\\n * @param sigFailed - true for signature failure, false for success\\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\\n * @param validAfter first timestamp this UserOperation is valid\\n */\\nfunction _packValidationData(\\n bool sigFailed,\\n uint48 validUntil,\\n uint48 validAfter\\n) pure returns (uint256) {\\n return\\n (sigFailed ? 1 : 0) |\\n (uint256(validUntil) << 160) |\\n (uint256(validAfter) << (160 + 48));\\n}\\n\\n/**\\n * keccak function over calldata.\\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\\n */\\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\\n assembly {\\n let mem := mload(0x40)\\n let len := data.length\\n calldatacopy(mem, data.offset, len)\\n ret := keccak256(mem, len)\\n }\\n}\\n\",\"keccak256\":\"0xa79f06cd158ecb8c0da95493a2f348933b8627a63e228b99738bff3aa107942d\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAggregator.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\n/**\\n * Aggregated Signatures validator.\\n */\\ninterface IAggregator {\\n /**\\n * validate aggregated signature.\\n * revert if the aggregated signature does not match the given list of operations.\\n */\\n function validateSignatures(\\n UserOperation[] calldata userOps,\\n bytes calldata signature\\n ) external view;\\n\\n /**\\n * validate signature of a single userOp\\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\\n * @param userOp the userOperation received from the user.\\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\\n * (usually empty, unless account and aggregator support some kind of \\\"multisig\\\"\\n */\\n function validateUserOpSignature(\\n UserOperation calldata userOp\\n ) external view returns (bytes memory sigForUserOp);\\n\\n /**\\n * aggregate multiple signatures into a single value.\\n * This method is called off-chain to calculate the signature to pass with handleOps()\\n * bundler MAY use optimized custom code perform this aggregation\\n * @param userOps array of UserOperations to collect the signatures from.\\n * @return aggregatedSignature the aggregated signature\\n */\\n function aggregateSignatures(\\n UserOperation[] calldata userOps\\n ) external view returns (bytes memory aggregatedSignature);\\n}\\n\",\"keccak256\":\"0xdfdcd80568f037716674619b31be630fcd8316262f05a815b41d1e81782c966a\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IEntryPoint.sol\":{\"content\":\"/**\\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\\n ** Only one instance required on each chain.\\n **/\\n// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-inline-assembly */\\n/* solhint-disable reason-string */\\n\\nimport \\\"./UserOperation.sol\\\";\\nimport \\\"./IStakeManager.sol\\\";\\nimport \\\"./IAggregator.sol\\\";\\nimport \\\"./INonceManager.sol\\\";\\n\\ninterface IEntryPoint is IStakeManager, INonceManager {\\n /***\\n * An event emitted after each successful request\\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\\n * @param sender - the account that generates this request.\\n * @param paymaster - if non-null, the paymaster that pays for this request.\\n * @param nonce - the nonce value from the request.\\n * @param success - true if the sender transaction succeeded, false if reverted.\\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\\n */\\n event UserOperationEvent(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address indexed paymaster,\\n uint256 nonce,\\n bool success,\\n uint256 actualGasCost,\\n uint256 actualGasUsed\\n );\\n\\n /**\\n * account \\\"sender\\\" was deployed.\\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\\n * @param sender the account that is deployed\\n * @param factory the factory used to deploy this account (in the initCode)\\n * @param paymaster the paymaster used by this UserOp\\n */\\n event AccountDeployed(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address factory,\\n address paymaster\\n );\\n\\n /**\\n * An event emitted if the UserOperation \\\"callData\\\" reverted with non-zero length\\n * @param userOpHash the request unique identifier.\\n * @param sender the sender of this request\\n * @param nonce the nonce used in the request\\n * @param revertReason - the return bytes from the (reverted) call to \\\"callData\\\".\\n */\\n event UserOperationRevertReason(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n uint256 nonce,\\n bytes revertReason\\n );\\n\\n /**\\n * an event emitted by handleOps(), before starting the execution loop.\\n * any event emitted before this event, is part of the validation.\\n */\\n event BeforeExecution();\\n\\n /**\\n * signature aggregator used by the following UserOperationEvents within this bundle.\\n */\\n event SignatureAggregatorChanged(address indexed aggregator);\\n\\n /**\\n * a custom revert error of handleOps, to identify the offending op.\\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\\n * @param reason - revert reason\\n * The string starts with a unique code \\\"AAmn\\\", where \\\"m\\\" is \\\"1\\\" for factory, \\\"2\\\" for account and \\\"3\\\" for paymaster issues,\\n * so a failure can be attributed to the correct entity.\\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\\n */\\n error FailedOp(uint256 opIndex, string reason);\\n\\n /**\\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\\n */\\n error SignatureValidationFailed(address aggregator);\\n\\n /**\\n * Successful result from simulateValidation.\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n */\\n error ValidationResult(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo\\n );\\n\\n /**\\n * Successful result from simulateValidation, if the account returns a signature aggregator\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\\n * bundler MUST use it to verify the signature, or reject the UserOperation\\n */\\n error ValidationResultWithAggregation(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo,\\n AggregatorStakeInfo aggregatorInfo\\n );\\n\\n /**\\n * return value of getSenderAddress\\n */\\n error SenderAddressResult(address sender);\\n\\n /**\\n * return value of simulateHandleOp\\n */\\n error ExecutionResult(\\n uint256 preOpGas,\\n uint256 paid,\\n uint48 validAfter,\\n uint48 validUntil,\\n bool targetSuccess,\\n bytes targetResult\\n );\\n\\n //UserOps handled, per aggregator\\n struct UserOpsPerAggregator {\\n UserOperation[] userOps;\\n // aggregator address\\n IAggregator aggregator;\\n // aggregated signature\\n bytes signature;\\n }\\n\\n /**\\n * Execute a batch of UserOperation.\\n * no signature aggregator is used.\\n * if any account requires an aggregator (that is, it returned an aggregator when\\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\\n * @param ops the operations to execute\\n * @param beneficiary the address to receive the fees\\n */\\n function handleOps(\\n UserOperation[] calldata ops,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * Execute a batch of UserOperation with Aggregators\\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\\n * @param beneficiary the address to receive the fees\\n */\\n function handleAggregatedOps(\\n UserOpsPerAggregator[] calldata opsPerAggregator,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * generate a request Id - unique identifier for this request.\\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\\n */\\n function getUserOpHash(\\n UserOperation calldata userOp\\n ) external view returns (bytes32);\\n\\n /**\\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\\n * @param userOp the user operation to validate.\\n */\\n function simulateValidation(UserOperation calldata userOp) external;\\n\\n /**\\n * gas and return values during simulation\\n * @param preOpGas the gas used for validation (including preValidationGas)\\n * @param prefund the required prefund for this operation\\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\\n */\\n struct ReturnInfo {\\n uint256 preOpGas;\\n uint256 prefund;\\n bool sigFailed;\\n uint48 validAfter;\\n uint48 validUntil;\\n bytes paymasterContext;\\n }\\n\\n /**\\n * returned aggregated signature info.\\n * the aggregator returned by the account, and its current stake.\\n */\\n struct AggregatorStakeInfo {\\n address aggregator;\\n StakeInfo stakeInfo;\\n }\\n\\n /**\\n * Get counterfactual sender address.\\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\\n * this method always revert, and returns the address in SenderAddressResult error\\n * @param initCode the constructor code to be passed into the UserOperation.\\n */\\n function getSenderAddress(bytes memory initCode) external;\\n\\n /**\\n * simulate full execution of a UserOperation (including both validation and target execution)\\n * this method will always revert with \\\"ExecutionResult\\\".\\n * it performs full validation of the UserOperation, but ignores signature error.\\n * an optional target address is called after the userop succeeds, and its value is returned\\n * (before the entire call is reverted)\\n * Note that in order to collect the the success/failure of the target call, it must be executed\\n * with trace enabled to track the emitted events.\\n * @param op the UserOperation to simulate\\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\\n * are set to the return from that call.\\n * @param targetCallData callData to pass to target address\\n */\\n function simulateHandleOp(\\n UserOperation calldata op,\\n address target,\\n bytes calldata targetCallData\\n ) external;\\n}\\n\",\"keccak256\":\"0x9ccb1b188eda8bbf5f6c2d01bd83c3d8b2b04fcf745283051d31fe96d1d8e40f\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/INonceManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\ninterface INonceManager {\\n /**\\n * Return the next nonce for this sender.\\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\\n * But UserOp with different keys can come with arbitrary order.\\n *\\n * @param sender the account address\\n * @param key the high 192 bit of the nonce\\n * @return nonce a full nonce to pass for next UserOp with this sender.\\n */\\n function getNonce(\\n address sender,\\n uint192 key\\n ) external view returns (uint256 nonce);\\n\\n /**\\n * Manually increment the nonce of the sender.\\n * This method is exposed just for completeness..\\n * Account does NOT need to call it, neither during validation, nor elsewhere,\\n * as the EntryPoint will update the nonce regardless.\\n * Possible use-case is call it with various keys to \\\"initialize\\\" their nonces to one, so that future\\n * UserOperations will not pay extra for the first transaction with a given key.\\n */\\n function incrementNonce(uint192 key) external;\\n}\\n\",\"keccak256\":\"0xce478ad0fa0d18a3b785ac854623029e7ab463d05873dfaa365abfa1bf100912\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IStakeManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8.12;\\n\\n/**\\n * manage deposits and stakes.\\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\\n * stake is value locked for at least \\\"unstakeDelay\\\" by the staked entity.\\n */\\ninterface IStakeManager {\\n event Deposited(address indexed account, uint256 totalDeposit);\\n\\n event Withdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /// Emitted when stake or unstake delay are modified\\n event StakeLocked(\\n address indexed account,\\n uint256 totalStaked,\\n uint256 unstakeDelaySec\\n );\\n\\n /// Emitted once a stake is scheduled for withdrawal\\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\\n\\n event StakeWithdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /**\\n * @param deposit the entity's deposit\\n * @param staked true if this entity is staked.\\n * @param stake actual amount of ether staked for this entity.\\n * @param unstakeDelaySec minimum delay to withdraw the stake.\\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\\n * and the rest fit into a 2nd cell.\\n * 112 bit allows for 10^15 eth\\n * 48 bit for full timestamp\\n * 32 bit allows 150 years for unstake delay\\n */\\n struct DepositInfo {\\n uint112 deposit;\\n bool staked;\\n uint112 stake;\\n uint32 unstakeDelaySec;\\n uint48 withdrawTime;\\n }\\n\\n //API struct used by getStakeInfo and simulateValidation\\n struct StakeInfo {\\n uint256 stake;\\n uint256 unstakeDelaySec;\\n }\\n\\n /// @return info - full deposit information of given account\\n function getDepositInfo(\\n address account\\n ) external view returns (DepositInfo memory info);\\n\\n /// @return the deposit (for gas payment) of the account\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * add to the deposit of the given account\\n */\\n function depositTo(address account) external payable;\\n\\n /**\\n * add to the account's stake - amount and delay\\n * any pending unstake is first cancelled.\\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\\n */\\n function addStake(uint32 _unstakeDelaySec) external payable;\\n\\n /**\\n * attempt to unlock the stake.\\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\\n */\\n function unlockStake() external;\\n\\n /**\\n * withdraw from the (unlocked) stake.\\n * must first call unlockStake and wait for the unstakeDelay to pass\\n * @param withdrawAddress the address to send withdrawn value.\\n */\\n function withdrawStake(address payable withdrawAddress) external;\\n\\n /**\\n * withdraw from the deposit.\\n * @param withdrawAddress the address to send withdrawn value.\\n * @param withdrawAmount the amount to withdraw.\\n */\\n function withdrawTo(\\n address payable withdrawAddress,\\n uint256 withdrawAmount\\n ) external;\\n}\\n\",\"keccak256\":\"0xadcea606c9b7aafe6645441f2154a60f271330b0eee5292a632aa71c1672d546\",\"license\":\"GPL-3.0-only\"},\"contracts/aa-4337/interfaces/UserOperation.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable no-inline-assembly */\\n\\nimport {calldataKeccak} from \\\"../core/Helpers.sol\\\";\\n\\n/**\\n * User Operation struct\\n * @param sender the sender account of this request.\\n * @param nonce unique value the sender uses to verify it is not a replay.\\n * @param initCode if set, the account contract will be created by this constructor/\\n * @param callData the method call to execute on this account.\\n * @param callGasLimit the gas limit passed to the callData method call.\\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\\n * @param maxFeePerGas same as EIP-1559 gas parameter.\\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\\n */\\nstruct UserOperation {\\n address sender;\\n uint256 nonce;\\n bytes initCode;\\n bytes callData;\\n uint256 callGasLimit;\\n uint256 verificationGasLimit;\\n uint256 preVerificationGas;\\n uint256 maxFeePerGas;\\n uint256 maxPriorityFeePerGas;\\n bytes paymasterAndData;\\n bytes signature;\\n}\\n\\n/**\\n * Utility functions helpful when working with UserOperation structs.\\n */\\nlibrary UserOperationLib {\\n function getSender(\\n UserOperation calldata userOp\\n ) internal pure returns (address) {\\n address data;\\n //read sender from userOp, which is first userOp member (saves 800 gas...)\\n assembly {\\n data := calldataload(userOp)\\n }\\n return address(uint160(data));\\n }\\n\\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\\n // pay above what he signed for.\\n function gasPrice(\\n UserOperation calldata userOp\\n ) internal view returns (uint256) {\\n unchecked {\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n if (maxFeePerGas == maxPriorityFeePerGas) {\\n //legacy mode (for networks that don't support basefee opcode)\\n return maxFeePerGas;\\n }\\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\\n }\\n }\\n\\n function pack(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes memory ret) {\\n address sender = getSender(userOp);\\n uint256 nonce = userOp.nonce;\\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\\n bytes32 hashCallData = calldataKeccak(userOp.callData);\\n uint256 callGasLimit = userOp.callGasLimit;\\n uint256 verificationGasLimit = userOp.verificationGasLimit;\\n uint256 preVerificationGas = userOp.preVerificationGas;\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\\n\\n return\\n abi.encode(\\n sender,\\n nonce,\\n hashInitCode,\\n hashCallData,\\n callGasLimit,\\n verificationGasLimit,\\n preVerificationGas,\\n maxFeePerGas,\\n maxPriorityFeePerGas,\\n hashPaymasterAndData\\n );\\n }\\n\\n function hash(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes32) {\\n return keccak256(pack(userOp));\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n}\\n\",\"keccak256\":\"0x2429f5cc546bdee08c7e63858d0dda8491eaa3ab5194df884dc948c1154d2834\",\"license\":\"GPL-3.0\"},\"contracts/facets/Modifiers.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {LibGuardian} from \\\"../libraries/LibGuardian.sol\\\";\\nimport {BarzStorage} from \\\"../libraries/LibAppStorage.sol\\\";\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\n\\n/**\\n * @title Modifiers\\n * @dev Responsible for providing modifiers/util functions to Facet contracts\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\nabstract contract Modifiers is BarzStorage {\\n uint8 constant INNER_STRUCT = 0;\\n\\n error CallerNotGuardian();\\n error CallerNotGuardianOrOwner();\\n error DuplicateApprover();\\n error ZeroApproverLength();\\n error UnregisteredFacetAndSelectors();\\n\\n /**\\n * @notice Modifier to only allow guardian to make a call, reverts if any other entity is the caller\\n */\\n modifier onlyGuardian() {\\n if (!LibGuardian.isGuardian(msg.sender)) revert CallerNotGuardian();\\n _;\\n }\\n\\n /**\\n * @notice Modifier to only allow guardian or owner to make a call, reverts if any other entity is the caller\\n */\\n modifier onlyGuardianOrOwner() {\\n if (!LibGuardian.isGuardian(msg.sender) && address(this) != msg.sender)\\n revert CallerNotGuardianOrOwner();\\n _;\\n }\\n\\n /**\\n * @notice Checks if the approver address is the array is unique with no duplicate\\n * @dev This method loops through the array and checks if a duplicate address exists, it reverts if duplicate address exists\\n * @param approvers Array of address\\n */\\n function _checkApprover(\\n address[] memory approvers\\n ) internal pure returns (bool) {\\n uint256 approverLength = approvers.length;\\n if (0 == approverLength) revert ZeroApproverLength();\\n for (uint256 i; i < approverLength - 1; ) {\\n for (uint256 j = i + 1; j < approverLength; ) {\\n if (approvers[i] == approvers[j]) {\\n revert DuplicateApprover(); // Found a duplicate\\n }\\n unchecked {\\n ++j;\\n }\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n return false; // No duplicates found\\n }\\n\\n /**\\n * @notice Checks if the facet getting added or replaced is registered to facet registry\\n * @dev This method loops through the cut and checks if the facet getting added/replaced is registered to facet registry\\n * @param _diamondCut Array of FacetCut, data for diamondCut defined in EIP-2535\\n */\\n function _checkFacetCutValidity(\\n IDiamondCut.FacetCut[] memory _diamondCut\\n ) internal view {\\n uint256 diamondCutLength = _diamondCut.length;\\n for (uint256 i; i < diamondCutLength; ) {\\n if (\\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Add ||\\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Replace\\n ) {\\n if (\\n !s.facetRegistry.areFacetFunctionSelectorsRegistered(\\n _diamondCut[i].facetAddress,\\n _diamondCut[i].functionSelectors\\n )\\n ) revert UnregisteredFacetAndSelectors();\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb42956323d199bdec243a5f9859439aae057fbfdd1d79e3a96afc857ecb3115f\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/DiamondCutFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {LibDiamond} from \\\"../../libraries/LibDiamond.sol\\\";\\nimport {LibGuardian} from \\\"../../libraries/LibGuardian.sol\\\";\\nimport {ISecurityManager} from \\\"../../infrastructure/interfaces/ISecurityManager.sol\\\";\\nimport {SignatureChecker} from \\\"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\\\";\\nimport {LibFacetStorage, DiamondCutApprovalConfig, ApprovalConfig} from \\\"../../libraries/LibFacetStorage.sol\\\";\\nimport {Modifiers} from \\\"../Modifiers.sol\\\";\\nimport {IDiamondCut} from \\\"./interfaces/IDiamondCut.sol\\\";\\n\\n/**\\n * @title DiamondCut Facet\\n * @dev Responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract DiamondCutFacet is Modifiers, IDiamondCut {\\n ISecurityManager public immutable securityManager;\\n\\n /**\\n * @notice This constructor sets the Security Manager address which is an immutable variable.\\n * Immutable variables do not impact the storage of diamond\\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\\n */\\n constructor(address _securityManager) {\\n securityManager = ISecurityManager(_securityManager);\\n }\\n\\n /**\\n * @notice Updates the flag for the interfaceId\\n * @param _interfaceId InterfaceID to update the mapping\\n * @param _flag Bool value to update the mapping of the given interface ID\\n */\\n function updateSupportsInterface(\\n bytes4 _interfaceId,\\n bool _flag\\n ) external override onlyWhenUnlocked {\\n LibDiamond.enforceIsSelf();\\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId] = _flag;\\n emit SupportsInterfaceUpdated(_interfaceId, _flag);\\n }\\n\\n /**\\n * @notice Add/replace/remove any number of functions and optionally execute\\n * a function with delegatecall when guardians don't exist\\n * @param _diamondCut Contains the facet addresses and function selectors\\n * @param _init The address of the contract or facet to execute _calldata. It's prohibited in Barz\\n */\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata\\n ) external override onlyWhenUnlocked {\\n LibDiamond.enforceIsSelf();\\n\\n _checkFacetCutValidity(_diamondCut);\\n // require approval from guardian if guardian exists\\n if (0 != LibGuardian.guardianCount())\\n revert DiamondCutFacet__InvalidRouteWithGuardian();\\n if (address(0) != _init) revert DiamondCutFacet__InvalidInitAddress();\\n\\n unchecked {\\n ++LibFacetStorage.diamondCutStorage().nonce;\\n }\\n LibDiamond.diamondCut(_diamondCut, address(0), \\\"\\\");\\n }\\n\\n /**\\n * @notice Add/replace/remove any number of functions and optionally execute\\n * a function with delegatecall when guardians exist\\n * @param _diamondCut Contains the facet addresses and function selectors\\n * @param _approvers Guardian or owner address that approves the diamond cut\\n * @param _signatures Signature of Guardians or owner that approves the diamond cut\\n */\\n function diamondCutWithGuardian(\\n FacetCut[] calldata _diamondCut,\\n address[] calldata _approvers,\\n bytes[] calldata _signatures\\n ) external override onlyWhenUnlocked {\\n if (_approvers.length != _signatures.length)\\n revert DiamondCutFacet__InvalidArrayLength();\\n _checkFacetCutValidity(_diamondCut);\\n if (0 == LibGuardian.guardianCount())\\n revert DiamondCutFacet__InvalidRouteWithGuardian();\\n\\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\\n\\n _checkApprover(_approvers);\\n _checkDuplicateOnChainApprover(cutHash, _approvers);\\n\\n bool onChainOwnerApproval = getOwnerCutApprovalWithTimeValidity(\\n cutHash\\n );\\n\\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\\n if (\\n _approvers.length +\\n getDiamondCutApprovalCountWithTimeValidity(cutHash) <\\n LibGuardian.majorityOfGuardians() + threshold\\n ) revert DiamondCutFacet__InsufficientApprovers();\\n\\n bool ownerApproved;\\n for (uint256 i; i < _approvers.length; ) {\\n if (\\n !LibGuardian.isGuardian(_approvers[i]) &&\\n _approvers[i] != address(this)\\n ) revert DiamondCutFacet__InvalidApprover();\\n if (_approvers[i] == address(this)) {\\n if (onChainOwnerApproval)\\n revert DiamondCutFacet__OwnerAlreadyApproved();\\n ownerApproved = true;\\n }\\n if (\\n !SignatureChecker.isValidSignatureNow(\\n _approvers[i],\\n cutHash,\\n _signatures[i]\\n )\\n ) revert DiamondCutFacet__InvalidApproverSignature();\\n unchecked {\\n ++i;\\n }\\n }\\n if (!ownerApproved && !onChainOwnerApproval)\\n revert DiamondCutFacet__LackOfOwnerApproval();\\n\\n unchecked {\\n ++LibFacetStorage.diamondCutStorage().nonce;\\n }\\n LibDiamond.diamondCut(_diamondCut, address(0), \\\"\\\");\\n }\\n\\n /**\\n * @notice Approves diamond cut. This can only be called directly from guardian or owner\\n * @param _diamondCut Contains the facet addresses and function selectors\\n */\\n function approveDiamondCut(\\n FacetCut[] calldata _diamondCut\\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\\n if (LibGuardian.guardianCount() == 0)\\n revert DiamondCutFacet__InvalidRouteWithoutGuardian();\\n DiamondCutApprovalConfig storage ds = LibFacetStorage\\n .diamondCutStorage()\\n .diamondCutApprovalConfigs[INNER_STRUCT];\\n _checkFacetCutValidity(_diamondCut);\\n\\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\\n uint64 approvalValidUntil = uint64(\\n block.timestamp + getApprovalValidationPeriod()\\n );\\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(\\n true,\\n approvalValidUntil\\n );\\n emit DiamondCutApproved(_diamondCut);\\n if (\\n (getDiamondCutApprovalCountWithTimeValidity(cutHash) >=\\n LibGuardian.majorityOfGuardians()) &&\\n getOwnerCutApprovalWithTimeValidity(cutHash)\\n ) {\\n unchecked {\\n ++LibFacetStorage.diamondCutStorage().nonce;\\n }\\n LibDiamond.diamondCut(_diamondCut, address(0), \\\"\\\");\\n }\\n }\\n\\n /**\\n * @notice Revokes the approval of diamond cut. This can only be called directly from guardian or owner\\n * @param _diamondCut Contains the facet addresses and function selectors\\n */\\n function revokeDiamondCutApproval(\\n FacetCut[] calldata _diamondCut\\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\\n DiamondCutApprovalConfig storage ds = LibFacetStorage\\n .diamondCutStorage()\\n .diamondCutApprovalConfigs[INNER_STRUCT];\\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\\n if (!ds.isDiamondCutApproved[cutHash][msg.sender].isApproved)\\n revert DiamondCutFacet__CannotRevokeUnapproved();\\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(false, 0);\\n emit DiamondCutApprovalRevoked(_diamondCut);\\n }\\n\\n /**\\n * @notice Gets the number of approvals of diamond cut from guardians\\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\\n */\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 _diamondCutHash\\n ) public view override returns (uint256 approvalCount) {\\n address[] memory guardians = LibGuardian.getGuardians();\\n uint256 guardiansLength = guardians.length;\\n for (uint256 i; i < guardiansLength; ) {\\n if (isCutApproved(_diamondCutHash, guardians[i])) {\\n unchecked {\\n ++approvalCount;\\n }\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n return approvalCount;\\n }\\n\\n /**\\n * @notice Returns if the owner has approved the diamond cut\\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\\n * @return isApprovedByOwner Bool value showing if the owner approved the cut\\n */\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 _diamondCutHash\\n ) public view override returns (bool isApprovedByOwner) {\\n isApprovedByOwner = isCutApproved(_diamondCutHash, address(this));\\n }\\n\\n /**\\n * @notice Returns if the given approver has approved the diamond cut\\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\\n * @param _approver Address of approver\\n * @return isApproved Bool value showing if the approver approved the cut\\n */\\n function isCutApproved(\\n bytes32 _diamondCutHash,\\n address _approver\\n ) public view override returns (bool isApproved) {\\n DiamondCutApprovalConfig storage ds = LibFacetStorage\\n .diamondCutStorage()\\n .diamondCutApprovalConfigs[INNER_STRUCT];\\n isApproved = (ds\\n .isDiamondCutApproved[_diamondCutHash][_approver].isApproved &&\\n block.timestamp <\\n ds.isDiamondCutApproved[_diamondCutHash][_approver].validUntil);\\n }\\n\\n /**\\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\\n * Approvers who approved on-chain should not be included in the off-chain approval\\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\\n * @param _approvers List of approver addresses\\n */\\n function _checkDuplicateOnChainApprover(\\n bytes32 _diamondCutHash,\\n address[] memory _approvers\\n ) public view {\\n address[] memory guardians = LibGuardian.getGuardians();\\n uint256 guardianLength = guardians.length;\\n uint256 approversLength = _approvers.length;\\n for (uint256 i; i < guardianLength; ) {\\n if (isCutApproved(_diamondCutHash, guardians[i])) {\\n for (uint256 j; j < approversLength; ) {\\n if (_approvers[j] == guardians[i])\\n revert DiamondCutFacet__DuplicateApproval();\\n unchecked {\\n ++j;\\n }\\n }\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * @notice Returns the diamond cut hash. This function ensures that this hash is safe from replay attack by including\\n * salt, address, chainId, and nonce, etc.\\n * @param _diamondCut Contains the facet addresses and function selectors\\n * @return cutHash Diamond Cut Hash\\n */\\n function getDiamondCutHash(\\n FacetCut[] calldata _diamondCut\\n ) public view override returns (bytes32 cutHash) {\\n cutHash = keccak256(\\n abi.encodePacked(\\n \\\"\\\\x19Ethereum Signed Message:\\\\n32\\\",\\n keccak256(\\n abi.encode(\\n keccak256(abi.encode(_diamondCut)),\\n address(this),\\n block.chainid,\\n LibFacetStorage.diamondCutStorage().nonce\\n )\\n )\\n )\\n );\\n }\\n\\n /**\\n * @notice Returns the approval validation Period\\n * @dev This method fetches the validation period from the security manager\\n * @return approvalValidationPeriod Approval validation period of Barz contract fetched from security manager\\n */\\n function getApprovalValidationPeriod()\\n internal\\n view\\n returns (uint256 approvalValidationPeriod)\\n {\\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\\n address(this)\\n );\\n if (approvalValidationPeriod <= 0)\\n revert DiamondCutFacet__InvalidApprovalValidationPeriod();\\n }\\n\\n /**\\n * @notice Returns the diamond cut nonce of this wallet\\n * @dev This method fetches the nonce from diamond cut storage\\n * @return cutNonce Nonce of diamond cut to protect from reply attacks\\n */\\n function getDiamondCutNonce()\\n public\\n view\\n override\\n returns (uint128 cutNonce)\\n {\\n cutNonce = LibFacetStorage.diamondCutStorage().nonce;\\n }\\n}\\n\",\"keccak256\":\"0xe91a7dd2daabf2e989c94089f4f1eb0da94276c3070559ac8988838e10dd1f5d\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/infrastructure/interfaces/IFacetRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Registry Interface\\n * @dev Interface for Facet Registry contract to keep track of facets & function selectors addable to user wallets\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IFacetRegistry {\\n struct FacetRegistryConfig {\\n bytes4[] selectors;\\n mapping(bytes4 => FacetInfo) info;\\n }\\n struct FacetInfo {\\n bool exists;\\n uint128 index;\\n }\\n\\n event FacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] facetSelectors\\n );\\n event FacetFunctionSelectorsRemoved(address facet, bytes4[] facetSelectors);\\n\\n error FacetRegistry__FacetSelectorAlreadyRegistered();\\n error FacetRegistry__UnregisteredFacetSelector();\\n\\n function registerFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function removeFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function areFacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external view returns (bool);\\n\\n function isFacetFunctionSelectorRegistered(\\n address facet,\\n bytes4 facetSelector\\n ) external view returns (bool);\\n\\n function getFacetFunctionSelectors(\\n address facet\\n ) external view returns (bytes4[] memory);\\n}\\n\",\"keccak256\":\"0x6e6dd2cab346ef7c31230740ec48d2925e4a9ab24c2f2fb268baaf408dcf02ef\",\"license\":\"Apache-2.0\"},\"contracts/infrastructure/interfaces/ISecurityManager.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Registry Interface\\n * @dev Infrastructure contract to manage security parameters of users\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\ninterface ISecurityManager {\\n error SecurityManager__OutOfBoundary();\\n error SecurityManager__CallerNotWallet();\\n error SecurityManager__AlreadyIntialized();\\n\\n function initializeAdditionSecurityPeriod(\\n uint128 defaultAdditionSecurityPeriod,\\n uint128 minAdditionSecurityPeriod,\\n uint128 maxAdditionSecurityPeriod\\n ) external;\\n\\n function initializeRemovalSecurityPeriod(\\n uint128 defaultRemovalSecurityPeriod,\\n uint128 minRemovalSecurityPeriod,\\n uint128 maxRemovalSecurityPeriod\\n ) external;\\n\\n function initializeApprovalValidationPeriod(\\n uint128 defaultApprovalValidationPeriod,\\n uint128 minApprovalValidationPeriod,\\n uint128 maxApprovalValidationPeriod\\n ) external;\\n\\n function initializeMigrationPeriod(\\n uint128 defaultMigrationPeriod,\\n uint128 minMigrationPeriod,\\n uint128 maxMigrationPeriod\\n ) external;\\n\\n function initializeLockPeriod(\\n uint128 defaultLockPeriod,\\n uint128 minLockPeriod,\\n uint128 maxLockPeriod\\n ) external;\\n\\n function initializeRecoveryPeriod(\\n uint128 defaultRecoveryPeriod,\\n uint128 minRecoveryPeriod,\\n uint128 maxRecoveryPeriod\\n ) external;\\n\\n function initializeSecurityWindow(\\n uint128 defaultSecurityWindow,\\n uint128 minSecurityWindow,\\n uint128 maxSecurityWindow\\n ) external;\\n\\n function setAdditionSecurityPeriod(\\n address wallet,\\n uint128 additionSecurityPeriod\\n ) external;\\n\\n function setRemovalSecurityPeriod(\\n address wallet,\\n uint128 removalSecurityPeriod\\n ) external;\\n\\n function setSecurityWindow(address wallet, uint128 securityWindow) external;\\n\\n function setRecoveryPeriod(address wallet, uint128 recoveryPeriod) external;\\n\\n function setLockPeriod(address wallet, uint128 lockPeriod) external;\\n\\n function setApprovalValidationPeriod(\\n address wallet,\\n uint128 approvalValidationPeriod\\n ) external;\\n\\n function setMigrationPeriod(\\n address wallet,\\n uint128 migrationPeriod\\n ) external;\\n\\n function additionSecurityPeriodOf(\\n address wallet\\n ) external view returns (uint128);\\n\\n function removalSecurityPeriodOf(\\n address wallet\\n ) external view returns (uint128);\\n\\n function securityWindowOf(address wallet) external view returns (uint128);\\n\\n function recoveryPeriodOf(address wallet) external view returns (uint128);\\n\\n function lockPeriodOf(address wallet) external view returns (uint128);\\n\\n function migrationPeriodOf(address wallet) external view returns (uint128);\\n\\n function approvalValidationPeriodOf(\\n address wallet\\n ) external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x9ac6566033ef81ba5744c8ed2b08f130b781b498ab9245bcca87567669549552\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibAppStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {SafeCast} from \\\"@openzeppelin/contracts/utils/math/SafeCast.sol\\\";\\nimport {IEntryPoint} from \\\"../aa-4337/interfaces/IEntryPoint.sol\\\";\\nimport {IFacetRegistry} from \\\"../infrastructure/interfaces/IFacetRegistry.sol\\\";\\n\\n/*\\n * @title App Storage\\n * @dev App storage for Barz contract to prevent storage collision\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Lock {\\n uint64 release;\\n bytes4 locker;\\n}\\n\\nstruct InitializersStorage {\\n // NOTE: initialized is a variable to make sure the initialization is only done once.\\n uint8 signerInitialized;\\n uint8 accountInitialized;\\n uint8 restrictionsInitialized;\\n}\\n\\nstruct AppStorage {\\n mapping(uint256 => InitializersStorage) initStorage;\\n uint8 signerMigration;\\n bytes4 validateOwnerSignatureSelector;\\n IEntryPoint entryPoint;\\n IFacetRegistry facetRegistry;\\n mapping(uint256 => Lock) locks;\\n}\\n\\nlibrary LibAppStorage {\\n error LibAppStorage__AccountAlreadyUninitialized();\\n error LibAppStorage__AccountMustBeUninitialized();\\n error LibAppStorage__SignerAlreadyUninitialized();\\n error LibAppStorage__SignerMustBeUninitialized();\\n\\n function appStorage() internal pure returns (AppStorage storage ds) {\\n assembly {\\n ds.slot := 0\\n }\\n }\\n\\n function setSignerUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerAlreadyUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 0;\\n }\\n\\n function getValidateOwnerSignatureSelector()\\n internal\\n view\\n returns (bytes4 selector)\\n {\\n selector = appStorage().validateOwnerSignatureSelector;\\n }\\n\\n function setValidateOwnerSignatureSelector(\\n bytes4 _validateOwnerSignatureSelector\\n ) internal {\\n appStorage()\\n .validateOwnerSignatureSelector = _validateOwnerSignatureSelector;\\n }\\n\\n function enforceSignerInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerMustBeUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 1;\\n }\\n\\n function enforceAccountInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].accountInitialized) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n s.initStorage[0].accountInitialized = 1;\\n }\\n\\n function initiateSignerMigration() internal {\\n appStorage().signerMigration = 1;\\n }\\n\\n function enforceSignerMigration() internal view {\\n if (1 != appStorage().signerMigration) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n }\\n\\n function finalizeSignerMigration() internal {\\n appStorage().signerMigration = 0;\\n }\\n\\n function setLock(uint256 _releaseAfter, bytes4 _locker) internal {\\n appStorage().locks[0] = Lock(SafeCast.toUint64(_releaseAfter), _locker);\\n }\\n\\n function enforceRestrictionsInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__SignerMustBeUninitialized();\\n s.initStorage[0].restrictionsInitialized = 1;\\n }\\n\\n function setRestrictionsUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__AccountAlreadyUninitialized();\\n s.initStorage[0].restrictionsInitialized = 0;\\n }\\n}\\n\\ncontract BarzStorage {\\n AppStorage internal s;\\n modifier onlyWhenUnlocked() {\\n require(\\n uint64(block.timestamp) >= s.locks[0].release,\\n \\\"Account Locked\\\"\\n );\\n _;\\n }\\n modifier onlyWhenLocked() {\\n require(\\n uint64(block.timestamp) < s.locks[0].release,\\n \\\"Account Unlocked\\\"\\n );\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x48524007862a6ce0e07f645950613ce6513ce073c37a109c75019683d42bae27\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\\n bytes4(keccak256(\\\"verifyRestrictions(address,address,uint256,bytes)\\\"));\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // Default Fallback Handler of the barz.\\n IDiamondLoupe defaultFallbackHandler;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function enforceIsSelf() internal view {\\n require(msg.sender == address(this), \\\"LibDiamond: Caller not self\\\");\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n\\n unchecked {\\n facetIndex++;\\n }\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n\\n function restrictionsFacet() internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(\\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2cabdc00de859c3a3170ce3bda5d0e5fd3933d47ce904fd1585f9818b02572f8\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibFacetStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Storage\\n * @dev Storage contract to store each facets variables with diamond storage\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Secp256k1VerificationStorage {\\n address signer;\\n}\\n\\nstruct Secp256r1VerificationStorage {\\n uint256[2] q;\\n}\\n\\nstruct GuardianStorage {\\n mapping(bytes32 => uint256) pending;\\n mapping(uint8 => StorageConfig) configs;\\n}\\n\\nstruct Info {\\n bool exists;\\n uint128 index;\\n}\\n\\nstruct StorageConfig {\\n address[] addresses;\\n mapping(address => Info) info;\\n}\\n\\nstruct RecoveryConfig {\\n bytes recoveryPublicKey;\\n uint64 executeAfter;\\n}\\n\\nstruct ApprovalConfig {\\n bool isApproved;\\n uint64 validUntil;\\n}\\n\\nstruct RecoveryApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isNewOwnerApproved;\\n}\\n\\nstruct RecoveryStorage {\\n mapping(uint8 => RecoveryConfig) recoveryConfigs;\\n mapping(uint8 => RecoveryApprovalConfig) recoveryApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct RestrictionsStorage {\\n address[] restrictions;\\n mapping(address => bool) exists;\\n}\\n\\nstruct SignatureMigrationConfig {\\n bytes migrationPublicKey;\\n address migrationVerificationFacet;\\n bytes4[] migrationSelectors;\\n uint64 migrateAfter;\\n}\\n\\nstruct SignatureMigrationApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isMigrationApproved;\\n}\\n\\nstruct SignatureMigrationStorage {\\n mapping(uint8 => SignatureMigrationConfig) migrationConfigs;\\n mapping(uint8 => SignatureMigrationApprovalConfig) migrationApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct DiamondCutApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isDiamondCutApproved;\\n}\\n\\nstruct DiamondCutStorage {\\n mapping(uint8 => DiamondCutApprovalConfig) diamondCutApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct LockStorage {\\n uint128 nonce;\\n}\\n\\nlibrary LibFacetStorage {\\n bytes32 constant K1_STORAGE_POSITION =\\n keccak256(\\n \\\"v0.trustwallet.diamond.storage.Secp256k1VerificationStorage\\\"\\n );\\n bytes32 constant R1_STORAGE_POSITION =\\n keccak256(\\n \\\"v0.trustwallet.diamond.storage.Secp256r1VerificationStorage\\\"\\n );\\n bytes32 constant GUARDIAN_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.GuardianStorage\\\");\\n bytes32 constant RECOVERY_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.RecoveryStorage\\\");\\n bytes32 constant RESTRICTION_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.RestrictionsStorage\\\");\\n bytes32 constant MIGRATION_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.SignatureMigrationStorage\\\");\\n bytes32 constant DIAMONDCUT_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.DiamondCutStorage\\\");\\n bytes32 constant LOCK_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.LockStorage\\\");\\n\\n function k1Storage()\\n internal\\n pure\\n returns (Secp256k1VerificationStorage storage ds)\\n {\\n bytes32 storagePosition = K1_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function r1Storage()\\n internal\\n pure\\n returns (Secp256r1VerificationStorage storage ds)\\n {\\n bytes32 storagePosition = R1_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function guardianStorage()\\n internal\\n pure\\n returns (GuardianStorage storage ds)\\n {\\n bytes32 storagePosition = GUARDIAN_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function recoveryStorage()\\n internal\\n pure\\n returns (RecoveryStorage storage ds)\\n {\\n bytes32 storagePosition = RECOVERY_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function restrictionsStorage()\\n internal\\n pure\\n returns (RestrictionsStorage storage ds)\\n {\\n bytes32 storagePosition = RESTRICTION_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function migrationStorage()\\n internal\\n pure\\n returns (SignatureMigrationStorage storage ds)\\n {\\n bytes32 storagePosition = MIGRATION_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function diamondCutStorage()\\n internal\\n pure\\n returns (DiamondCutStorage storage ds)\\n {\\n bytes32 storagePosition = DIAMONDCUT_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function lockStorage() internal pure returns (LockStorage storage ds) {\\n bytes32 storagePosition = LOCK_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n}\\n\",\"keccak256\":\"0x87c85decfd943deda9540733e464cb1a92eba735a301e89ce6f798016e359761\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibGuardian.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {LibFacetStorage, StorageConfig} from \\\"./LibFacetStorage.sol\\\";\\n\\n/**\\n * @title LibGuardian\\n * @dev Internal Library to provide utility feature for Guardians stored in Guardian Facet Storage\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\nlibrary LibGuardian {\\n function majorityOfGuardians()\\n internal\\n view\\n returns (uint256 guardianNumber)\\n {\\n uint256 guardianLength = guardianCount();\\n guardianNumber = (guardianLength == 0) ? 0 : guardianLength / 2 + 1;\\n }\\n\\n function isGuardian(address _guardian) internal view returns (bool) {\\n StorageConfig storage config = LibFacetStorage\\n .guardianStorage()\\n .configs[0];\\n return config.info[_guardian].exists;\\n }\\n\\n function guardianCount() internal view returns (uint256) {\\n StorageConfig storage config = LibFacetStorage\\n .guardianStorage()\\n .configs[0];\\n return config.addresses.length;\\n }\\n\\n function getGuardians() internal view returns (address[] memory) {\\n StorageConfig storage config = LibFacetStorage\\n .guardianStorage()\\n .configs[0];\\n address[] memory addresses = new address[](config.addresses.length);\\n uint256 addressesLen = config.addresses.length;\\n for (uint256 i; i < addressesLen; ) {\\n addresses[i] = config.addresses[i];\\n unchecked {\\n ++i;\\n }\\n }\\n return addresses;\\n }\\n}\\n\",\"keccak256\":\"0x6a620992d5535878fc03d1a27a6675f4c1509adfb3ddbbca1c52b546c25392dc\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x60a06040523480156200001157600080fd5b506040516200379b3803806200379b833981016040819052620000349162000046565b6001600160a01b031660805262000078565b6000602082840312156200005957600080fd5b81516001600160a01b03811681146200007157600080fd5b9392505050565b6080516137006200009b600039600081816101f10152611b2501526137006000f3fe608060405234801561001057600080fd5b50600436106100d45760003560e01c806379c0d58d11610081578063afb877bb1161005b578063afb877bb146101d9578063de675a6d146101ec578063e33ecf0a1461023857600080fd5b806379c0d58d14610192578063836d6bfb146101b35780638824a0bb146101c657600080fd5b806326fc3ef4116100b257806326fc3ef4146101145780632f4d98ea1461015c5780633c0985681461017f57600080fd5b806313c34f4b146100d95780631c776dd5146100ee5780631f931c1c14610101575b600080fd5b6100ec6100e7366004612a97565b61024b565b005b6100ec6100fc366004612ad9565b6104df565b6100ec61010f366004612b9c565b610a76565b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9bf546040516fffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b61016f61016a366004612c4a565b610c7b565b6040519015158152602001610153565b6100ec61018d366004612ca4565b610c8d565b6101a56101a0366004612c4a565b610df2565b604051908152602001610153565b61016f6101c1366004612cdb565b610e4c565b6100ec6101d4366004612dd2565b610eed565b6100ec6101e7366004612a97565b610fe1565b6102137f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610153565b6101a5610246366004612a97565b61130e565b3360009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff1615801561028a5750303314155b156102c1576040517f6238ee3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610369576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064015b60405180910390fd5b60008080527f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be6020527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d3906103be848461130e565b60008181526020848152604080832033845290915290205490915060ff16610412576040517fedc5708300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051808201825260008082526020808301828152858352868252848320338452909152908390209151825491517fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000009092169015157fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff161761010067ffffffffffffffff90921691909102179055517f3c3d8c1f0b0faff6fe0ace6b485d0595a0106dce9e303f956fd941ebdbe9a98e906104d19086908690612f54565b60405180910390a150505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610582576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b8281146105bb576040517fe854148500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6105cd6105c886886130aa565b611435565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b754600003610650576040517fa788861700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061065c878761130e565b905061069a8585808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506115b392505050565b506106d881868680806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250610eed92505050565b60006106e382610c7b565b90506000816106f35760016106f6565b60005b60ff169050806107046116d0565b61070e9190613201565b61071784610df2565b6107219088613201565b1015610759576040517f709fb08000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805b878110156109a0576107d989898381811061077a5761077a613214565b905060200201602081019061078f9190613243565b73ffffffffffffffffffffffffffffffffffffffff1660009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff1690565b1580156108225750308989838181106107f4576107f4613214565b90506020020160208101906108099190613243565b73ffffffffffffffffffffffffffffffffffffffff1614155b15610859576040517f7b2cbbb400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3089898381811061086c5761086c613214565b90506020020160208101906108819190613243565b73ffffffffffffffffffffffffffffffffffffffff16036108d95783156108d4576040517fee21708000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600191505b6109628989838181106108ee576108ee613214565b90506020020160208101906109039190613243565b8689898581811061091657610916613214565b90506020028101906109289190613265565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061174f92505050565b610998576040517fac3d341600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60010161075d565b50801580156109ad575082155b156109e4576040517f6d21730400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9bf80546fffffffffffffffffffffffffffffffff808216600101167fffffffffffffffffffffffffffffffff00000000000000000000000000000000909116179055610a6a610a538a8c6130aa565b6000604051806020016040528060008152506117ca565b50505050505050505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610b19576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b610b2161195f565b610b2e6105c885876130aa565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75415610baf576040517fa788861700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff831615610bfd576040517f871cb76100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be5b600190810180547fffffffffffffffffffffffffffffffff0000000000000000000000000000000081166fffffffffffffffffffffffffffffffff91821690930116919091179055610c74610a5385876130aa565b5050505050565b6000610c878230610e4c565b92915050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610d30576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b610d3861195f565b7fffffffff00000000000000000000000000000000000000000000000000000000821660008181527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4922602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001685151590811790915582519384529083015280517f4e6bd17989efa6d6a9607ccaac1bba27b29f99622bc830d99a3a9883b21a19c79281900390910190a15050565b600080610dfd6119ca565b805190915060005b81811015610e4457610e3085848381518110610e2357610e23613214565b6020026020010151610e4c565b15610e3c578360010193505b600101610e05565b505050919050565b60008281527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d36020818152604080842073ffffffffffffffffffffffffffffffffffffffff8616855290915282205460ff168015610ee5575060008481526020828152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152902054610100900467ffffffffffffffff1642105b949350505050565b6000610ef76119ca565b805183519192509060005b82811015610fd957610f2086858381518110610e2357610e23613214565b15610fd15760005b82811015610fcf57848281518110610f4257610f42613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16868281518110610f7257610f72613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603610fc7576040517f50f5729f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600101610f28565b505b600101610f02565b505050505050565b3360009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff161580156110205750303314155b15611057576040517f6238ee3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff9081164290911610156110fa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75460000361117d576040517f3a76e1f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080527f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be6020527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d36111d36105c883856130aa565b60006111df848461130e565b905060006111eb611af4565b6111f59042613201565b6040805180820182526001815267ffffffffffffffff838116602080840191825260008881528982528581203382529091528490209251835491517fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000009092169015157fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff16176101009190921602179055519091507f6248ff757895beed7d43d135bccf59a26b7fbdf0fe8233487c44e82c0f266ba3906112b89087908790612f54565b60405180910390a16112c86116d0565b6112d183610df2565b101580156112e357506112e382610c7b565b15610c74577f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be610c1f565b60008282604051602001611323929190612f54565b6040516020818303038152906040528051906020012030466113627f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be90565b6001015460408051602081019590955273ffffffffffffffffffffffffffffffffffffffff9093169284019290925260608301526fffffffffffffffffffffffffffffffff16608082015260a001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905280516020918201207f19457468657265756d205369676e6564204d6573736167653a0a33320000000091830191909152603c820152605c0160405160208183030381529060405280519060200120905092915050565b805160005b818110156115ae57600083828151811061145657611456613214565b602002602001015160200151600281111561147357611473612e8a565b14806114ad5750600183828151811061148e5761148e613214565b60200260200101516020015160028111156114ab576114ab612e8a565b145b156115a657600254835173ffffffffffffffffffffffffffffffffffffffff9091169063df871f72908590849081106114e8576114e8613214565b60200260200101516000015185848151811061150657611506613214565b6020026020010151604001516040518363ffffffff1660e01b815260040161152f92919061331c565b602060405180830381865afa15801561154c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611570919061334b565b6115a6576040517ff41a931c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60010161143a565b505050565b80516000908082036115f1576040517f3aee2eec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b6115ff600183613368565b8110156116c6576000611613826001613201565b90505b828110156116bd5784818151811061163057611630613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1685838151811061166057611660613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16036116b5576040517f8dd19e7d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600101611616565b506001016115f4565b5060009392505050565b600080611723600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75490565b905080156117465761173660028261337b565b611741906001613201565b611749565b60005b91505090565b600080600061175e8585611bf6565b9092509050600081600481111561177757611777612e8a565b1480156117af57508573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b806117c057506117c0868686611c3b565b9695505050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921547f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff8116908190600090600716156118395750600381901c60009081526001840160205260409020545b60005b87518110156118b6576118a983838a848151811061185c5761185c613214565b6020026020010151600001518b858151811061187a5761187a613214565b6020026020010151602001518c868151811061189857611898613214565b602002602001015160400151611d98565b909350915060010161183c565b508282146118ef576002840180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff84161790555b600782161561191157600382901c600090815260018501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb67387878760405161194493929190613424565b60405180910390a16119568686612829565b50505050505050565b3330146119c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4c69624469616d6f6e643a2043616c6c6572206e6f742073656c6600000000006044820152606401610360565b565b60008080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b780546060929067ffffffffffffffff811115611a3257611a32612d07565b604051908082528060200260200182016040528015611a5b578160200160208202803683370190505b50825490915060005b81811015611aeb57836000018181548110611a8157611a81613214565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16838281518110611abe57611abe613214565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101611a64565b50909392505050565b6040517f52430c8d0000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906352430c8d90602401602060405180830381865afa158015611b81573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ba59190613510565b6fffffffffffffffffffffffffffffffff16905060008111611bf3576040517fdac5ec8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b90565b6000808251604103611c2c5760208301516040840151606085015160001a611c2087828585612928565b94509450505050611c34565b506000905060025b9250929050565b60008060008573ffffffffffffffffffffffffffffffffffffffff16631626ba7e60e01b8686604051602401611c72929190613542565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909416939093179092529051611cfb919061355b565b600060405180830381855afa9150503d8060008114611d36576040519150601f19603f3d011682016040523d82523d6000602084013e611d3b565b606091505b5091509150818015611d4f57506020815110155b80156117c0575080517f1626ba7e0000000000000000000000000000000000000000000000000000000090611d8d9083016020908101908401613577565b149695505050505050565b600080807f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f90506000845111611e50576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610360565b6000856002811115611e6457611e64612e8a565b0361203457611e8b8660405180606001604052806024815260200161365760249139612a17565b60005b845181101561202e576000858281518110611eab57611eab613214565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c15611f7e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c72656164792065786973747300000000000000000000006064820152608401610360565b7fffffffff0000000000000000000000000000000000000000000000000000000080831660008181526020879052604090207fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608d901b168e17905560e060058e901b811692831c199c909c1690821c179a8190036120125760038c901c600090815260018601602052604081209b909b555b8b61201c81613590565b9c505060019093019250611e8e915050565b5061281d565b600185600281111561204857612048612e8a565b036123385761206f866040518060600160405280602881526020016136a360289139612a17565b60005b845181101561202e57600085828151811061208f5761208f613214565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c308103612164576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4c69624469616d6f6e644375743a2043616e2774207265706c61636520696d6d60448201527f757461626c652066756e6374696f6e00000000000000000000000000000000006064820152608401610360565b8973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361221f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e00000000000000006064820152608401610360565b73ffffffffffffffffffffffffffffffffffffffff81166122c2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e207468617420646f65736e277420657869737400000000000000006064820152608401610360565b507fffffffff0000000000000000000000000000000000000000000000000000000090911660009081526020849052604090206bffffffffffffffffffffffff919091167fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608a901b16179055600101612072565b600285600281111561234c5761234c612e8a565b036127955773ffffffffffffffffffffffffffffffffffffffff8616156123f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d7573742062652061646472657373283029000000000000000000006064820152608401610360565b600388901c6007891660005b86518110156127755760008a900361243d578261241d816135c8565b60008181526001870160205260409020549b5093506007925061244b9050565b81612447816135c8565b9250505b6000806000808a858151811061246357612463613214565b6020908102919091018101517fffffffff0000000000000000000000000000000000000000000000000000000081166000908152918a9052604090912054909150606081901c612535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608401610360565b30606082901c036125c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e0000000000000000000000000000000000006064820152608401610360565b600587901b8f901b94507fffffffff0000000000000000000000000000000000000000000000000000000080861690831614612666577fffffffff000000000000000000000000000000000000000000000000000000008516600090815260208a90526040902080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff83161790555b7fffffffff0000000000000000000000000000000000000000000000000000000091909116600090815260208990526040812055600381901c611fff16925060051b60e01690508582146126fb576000828152600188016020526040902080547fffffffff0000000000000000000000000000000000000000000000000000000080841c19909116908516831c17905561274c565b80837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c817fffffffff0000000000000000000000000000000000000000000000000000000060001b901c198e16179c505b8460000361276a57600086815260018801602052604081208190559c505b505050600101612401565b50806127828360086135fd565b61278c9190613201565b9950505061281d565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560448201527f74416374696f6e000000000000000000000000000000000000000000000000006064820152608401610360565b50959694955050505050565b73ffffffffffffffffffffffffffffffffffffffff8216612848575050565b61286a8260405180606001604052806028815260200161367b60289139612a17565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051612892919061355b565b600060405180830381855af49150503d80600081146128cd576040519150601f19603f3d011682016040523d82523d6000602084013e6128d2565b606091505b509150915081612922578051156128ec5780518082602001fd5b83836040517f192105d7000000000000000000000000000000000000000000000000000000008152600401610360929190613614565b50505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561295f5750600090506003612a0e565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156129b3573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116612a0757600060019250925050612a0e565b9150600090505b94509492505050565b813b8181612922576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103609190613643565b60008083601f840112612a6457600080fd5b50813567ffffffffffffffff811115612a7c57600080fd5b6020830191508360208260051b8501011115611c3457600080fd5b60008060208385031215612aaa57600080fd5b823567ffffffffffffffff811115612ac157600080fd5b612acd85828601612a52565b90969095509350505050565b60008060008060008060608789031215612af257600080fd5b863567ffffffffffffffff80821115612b0a57600080fd5b612b168a838b01612a52565b90985096506020890135915080821115612b2f57600080fd5b612b3b8a838b01612a52565b90965094506040890135915080821115612b5457600080fd5b50612b6189828a01612a52565b979a9699509497509295939492505050565b803573ffffffffffffffffffffffffffffffffffffffff81168114612b9757600080fd5b919050565b600080600080600060608688031215612bb457600080fd5b853567ffffffffffffffff80821115612bcc57600080fd5b612bd889838a01612a52565b9097509550859150612bec60208901612b73565b94506040880135915080821115612c0257600080fd5b818801915088601f830112612c1657600080fd5b813581811115612c2557600080fd5b896020828501011115612c3757600080fd5b9699959850939650602001949392505050565b600060208284031215612c5c57600080fd5b5035919050565b80357fffffffff0000000000000000000000000000000000000000000000000000000081168114612b9757600080fd5b8015158114612ca157600080fd5b50565b60008060408385031215612cb757600080fd5b612cc083612c63565b91506020830135612cd081612c93565b809150509250929050565b60008060408385031215612cee57600080fd5b82359150612cfe60208401612b73565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff81118282101715612d5957612d59612d07565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715612da657612da6612d07565b604052919050565b600067ffffffffffffffff821115612dc857612dc8612d07565b5060051b60200190565b60008060408385031215612de557600080fd5b8235915060208084013567ffffffffffffffff811115612e0457600080fd5b8401601f81018613612e1557600080fd5b8035612e28612e2382612dae565b612d5f565b81815260059190911b82018301908381019088831115612e4757600080fd5b928401925b82841015612e6c57612e5d84612b73565b82529284019290840190612e4c565b80955050505050509250929050565b803560038110612b9757600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60038110612ef0577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b8183526000602080850194508260005b85811015612f49577fffffffff00000000000000000000000000000000000000000000000000000000612f3683612c63565b1687529582019590820190600101612f04565b509495945050505050565b60208082528181018390526000906040808401600586811b8601830188865b8981101561309b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc089840301855281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa18c3603018112612fd457600080fd5b8b01606073ffffffffffffffffffffffffffffffffffffffff612ff683612b73565b168552613004898301612e7b565b6130108a870182612eb9565b50878201357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe183360301811261304557600080fd5b90910188810191903567ffffffffffffffff81111561306357600080fd5b80871b360383131561307457600080fd5b81898701526130868287018285612ef4565b978a0197955050509187019150600101612f73565b50909998505050505050505050565b60006130b8612e2384612dae565b83815260208082019190600586811b8601368111156130d657600080fd5b865b818110156131c557803567ffffffffffffffff808211156130f95760008081fd5b818a0191506060823603121561310f5760008081fd5b613117612d36565b61312083612b73565b815261312d878401612e7b565b87820152604080840135838111156131455760008081fd5b939093019236601f85011261315c57600092508283fd5b8335925061316c612e2384612dae565b83815292871b840188019288810190368511156131895760008081fd5b948901945b848610156131ae5761319f86612c63565b8252948901949089019061318e565b9183019190915250885250509483019483016130d8565b5092979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610c8757610c876131d2565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561325557600080fd5b61325e82612b73565b9392505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261329a57600080fd5b83018035915067ffffffffffffffff8211156132b557600080fd5b602001915036819003821315611c3457600080fd5b600081518084526020808501945080840160005b83811015612f495781517fffffffff0000000000000000000000000000000000000000000000000000000016875295820195908201906001016132de565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000610ee560408301846132ca565b60006020828403121561335d57600080fd5b815161325e81612c93565b81810381811115610c8757610c876131d2565b6000826133b1577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60005b838110156133d15781810151838201526020016133b9565b50506000910152565b600081518084526133f28160208601602086016133b6565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6000606080830181845280875180835260808601915060808160051b87010192506020808a0160005b838110156134d4577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80898703018552815173ffffffffffffffffffffffffffffffffffffffff8151168752838101516134a885890182612eb9565b506040908101519087018890526134c1878901826132ca565b965050938201939082019060010161344d565b505073ffffffffffffffffffffffffffffffffffffffff8916908701525050838103604085015261350581866133da565b979650505050505050565b60006020828403121561352257600080fd5b81516fffffffffffffffffffffffffffffffff8116811461325e57600080fd5b828152604060208201526000610ee560408301846133da565b6000825161356d8184602087016133b6565b9190910192915050565b60006020828403121561358957600080fd5b5051919050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036135c1576135c16131d2565b5060010190565b6000816135d7576135d76131d2565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b8082028115828204841417610c8757610c876131d2565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000610ee560408301846133da565b60208152600061325e60208301846133da56fe4c69624469616d6f6e644375743a2041646420666163657420686173206e6f20636f64654c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a205265706c61636520666163657420686173206e6f20636f6465a2646970667358221220c5a8c10b22f20cde3fe0431ff57305237423677a60888f5b349fc6751336ae1464736f6c63430008150033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100d45760003560e01c806379c0d58d11610081578063afb877bb1161005b578063afb877bb146101d9578063de675a6d146101ec578063e33ecf0a1461023857600080fd5b806379c0d58d14610192578063836d6bfb146101b35780638824a0bb146101c657600080fd5b806326fc3ef4116100b257806326fc3ef4146101145780632f4d98ea1461015c5780633c0985681461017f57600080fd5b806313c34f4b146100d95780631c776dd5146100ee5780631f931c1c14610101575b600080fd5b6100ec6100e7366004612a97565b61024b565b005b6100ec6100fc366004612ad9565b6104df565b6100ec61010f366004612b9c565b610a76565b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9bf546040516fffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b61016f61016a366004612c4a565b610c7b565b6040519015158152602001610153565b6100ec61018d366004612ca4565b610c8d565b6101a56101a0366004612c4a565b610df2565b604051908152602001610153565b61016f6101c1366004612cdb565b610e4c565b6100ec6101d4366004612dd2565b610eed565b6100ec6101e7366004612a97565b610fe1565b6102137f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610153565b6101a5610246366004612a97565b61130e565b3360009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff1615801561028a5750303314155b156102c1576040517f6238ee3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610369576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064015b60405180910390fd5b60008080527f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be6020527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d3906103be848461130e565b60008181526020848152604080832033845290915290205490915060ff16610412576040517fedc5708300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051808201825260008082526020808301828152858352868252848320338452909152908390209151825491517fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000009092169015157fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff161761010067ffffffffffffffff90921691909102179055517f3c3d8c1f0b0faff6fe0ace6b485d0595a0106dce9e303f956fd941ebdbe9a98e906104d19086908690612f54565b60405180910390a150505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610582576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b8281146105bb576040517fe854148500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6105cd6105c886886130aa565b611435565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b754600003610650576040517fa788861700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061065c878761130e565b905061069a8585808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506115b392505050565b506106d881868680806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250610eed92505050565b60006106e382610c7b565b90506000816106f35760016106f6565b60005b60ff169050806107046116d0565b61070e9190613201565b61071784610df2565b6107219088613201565b1015610759576040517f709fb08000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805b878110156109a0576107d989898381811061077a5761077a613214565b905060200201602081019061078f9190613243565b73ffffffffffffffffffffffffffffffffffffffff1660009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff1690565b1580156108225750308989838181106107f4576107f4613214565b90506020020160208101906108099190613243565b73ffffffffffffffffffffffffffffffffffffffff1614155b15610859576040517f7b2cbbb400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3089898381811061086c5761086c613214565b90506020020160208101906108819190613243565b73ffffffffffffffffffffffffffffffffffffffff16036108d95783156108d4576040517fee21708000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600191505b6109628989838181106108ee576108ee613214565b90506020020160208101906109039190613243565b8689898581811061091657610916613214565b90506020028101906109289190613265565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061174f92505050565b610998576040517fac3d341600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60010161075d565b50801580156109ad575082155b156109e4576040517f6d21730400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9bf80546fffffffffffffffffffffffffffffffff808216600101167fffffffffffffffffffffffffffffffff00000000000000000000000000000000909116179055610a6a610a538a8c6130aa565b6000604051806020016040528060008152506117ca565b50505050505050505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610b19576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b610b2161195f565b610b2e6105c885876130aa565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75415610baf576040517fa788861700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff831615610bfd576040517f871cb76100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be5b600190810180547fffffffffffffffffffffffffffffffff0000000000000000000000000000000081166fffffffffffffffffffffffffffffffff91821690930116919091179055610c74610a5385876130aa565b5050505050565b6000610c878230610e4c565b92915050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610d30576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b610d3861195f565b7fffffffff00000000000000000000000000000000000000000000000000000000821660008181527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4922602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001685151590811790915582519384529083015280517f4e6bd17989efa6d6a9607ccaac1bba27b29f99622bc830d99a3a9883b21a19c79281900390910190a15050565b600080610dfd6119ca565b805190915060005b81811015610e4457610e3085848381518110610e2357610e23613214565b6020026020010151610e4c565b15610e3c578360010193505b600101610e05565b505050919050565b60008281527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d36020818152604080842073ffffffffffffffffffffffffffffffffffffffff8616855290915282205460ff168015610ee5575060008481526020828152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152902054610100900467ffffffffffffffff1642105b949350505050565b6000610ef76119ca565b805183519192509060005b82811015610fd957610f2086858381518110610e2357610e23613214565b15610fd15760005b82811015610fcf57848281518110610f4257610f42613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16868281518110610f7257610f72613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603610fc7576040517f50f5729f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600101610f28565b505b600101610f02565b505050505050565b3360009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff161580156110205750303314155b15611057576040517f6238ee3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff9081164290911610156110fa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75460000361117d576040517f3a76e1f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080527f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be6020527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d36111d36105c883856130aa565b60006111df848461130e565b905060006111eb611af4565b6111f59042613201565b6040805180820182526001815267ffffffffffffffff838116602080840191825260008881528982528581203382529091528490209251835491517fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000009092169015157fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff16176101009190921602179055519091507f6248ff757895beed7d43d135bccf59a26b7fbdf0fe8233487c44e82c0f266ba3906112b89087908790612f54565b60405180910390a16112c86116d0565b6112d183610df2565b101580156112e357506112e382610c7b565b15610c74577f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be610c1f565b60008282604051602001611323929190612f54565b6040516020818303038152906040528051906020012030466113627f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be90565b6001015460408051602081019590955273ffffffffffffffffffffffffffffffffffffffff9093169284019290925260608301526fffffffffffffffffffffffffffffffff16608082015260a001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905280516020918201207f19457468657265756d205369676e6564204d6573736167653a0a33320000000091830191909152603c820152605c0160405160208183030381529060405280519060200120905092915050565b805160005b818110156115ae57600083828151811061145657611456613214565b602002602001015160200151600281111561147357611473612e8a565b14806114ad5750600183828151811061148e5761148e613214565b60200260200101516020015160028111156114ab576114ab612e8a565b145b156115a657600254835173ffffffffffffffffffffffffffffffffffffffff9091169063df871f72908590849081106114e8576114e8613214565b60200260200101516000015185848151811061150657611506613214565b6020026020010151604001516040518363ffffffff1660e01b815260040161152f92919061331c565b602060405180830381865afa15801561154c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611570919061334b565b6115a6576040517ff41a931c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60010161143a565b505050565b80516000908082036115f1576040517f3aee2eec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b6115ff600183613368565b8110156116c6576000611613826001613201565b90505b828110156116bd5784818151811061163057611630613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1685838151811061166057611660613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16036116b5576040517f8dd19e7d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600101611616565b506001016115f4565b5060009392505050565b600080611723600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75490565b905080156117465761173660028261337b565b611741906001613201565b611749565b60005b91505090565b600080600061175e8585611bf6565b9092509050600081600481111561177757611777612e8a565b1480156117af57508573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b806117c057506117c0868686611c3b565b9695505050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921547f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff8116908190600090600716156118395750600381901c60009081526001840160205260409020545b60005b87518110156118b6576118a983838a848151811061185c5761185c613214565b6020026020010151600001518b858151811061187a5761187a613214565b6020026020010151602001518c868151811061189857611898613214565b602002602001015160400151611d98565b909350915060010161183c565b508282146118ef576002840180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff84161790555b600782161561191157600382901c600090815260018501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb67387878760405161194493929190613424565b60405180910390a16119568686612829565b50505050505050565b3330146119c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4c69624469616d6f6e643a2043616c6c6572206e6f742073656c6600000000006044820152606401610360565b565b60008080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b780546060929067ffffffffffffffff811115611a3257611a32612d07565b604051908082528060200260200182016040528015611a5b578160200160208202803683370190505b50825490915060005b81811015611aeb57836000018181548110611a8157611a81613214565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16838281518110611abe57611abe613214565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101611a64565b50909392505050565b6040517f52430c8d0000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906352430c8d90602401602060405180830381865afa158015611b81573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ba59190613510565b6fffffffffffffffffffffffffffffffff16905060008111611bf3576040517fdac5ec8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b90565b6000808251604103611c2c5760208301516040840151606085015160001a611c2087828585612928565b94509450505050611c34565b506000905060025b9250929050565b60008060008573ffffffffffffffffffffffffffffffffffffffff16631626ba7e60e01b8686604051602401611c72929190613542565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909416939093179092529051611cfb919061355b565b600060405180830381855afa9150503d8060008114611d36576040519150601f19603f3d011682016040523d82523d6000602084013e611d3b565b606091505b5091509150818015611d4f57506020815110155b80156117c0575080517f1626ba7e0000000000000000000000000000000000000000000000000000000090611d8d9083016020908101908401613577565b149695505050505050565b600080807f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f90506000845111611e50576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610360565b6000856002811115611e6457611e64612e8a565b0361203457611e8b8660405180606001604052806024815260200161365760249139612a17565b60005b845181101561202e576000858281518110611eab57611eab613214565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c15611f7e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c72656164792065786973747300000000000000000000006064820152608401610360565b7fffffffff0000000000000000000000000000000000000000000000000000000080831660008181526020879052604090207fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608d901b168e17905560e060058e901b811692831c199c909c1690821c179a8190036120125760038c901c600090815260018601602052604081209b909b555b8b61201c81613590565b9c505060019093019250611e8e915050565b5061281d565b600185600281111561204857612048612e8a565b036123385761206f866040518060600160405280602881526020016136a360289139612a17565b60005b845181101561202e57600085828151811061208f5761208f613214565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c308103612164576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4c69624469616d6f6e644375743a2043616e2774207265706c61636520696d6d60448201527f757461626c652066756e6374696f6e00000000000000000000000000000000006064820152608401610360565b8973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361221f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e00000000000000006064820152608401610360565b73ffffffffffffffffffffffffffffffffffffffff81166122c2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e207468617420646f65736e277420657869737400000000000000006064820152608401610360565b507fffffffff0000000000000000000000000000000000000000000000000000000090911660009081526020849052604090206bffffffffffffffffffffffff919091167fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608a901b16179055600101612072565b600285600281111561234c5761234c612e8a565b036127955773ffffffffffffffffffffffffffffffffffffffff8616156123f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d7573742062652061646472657373283029000000000000000000006064820152608401610360565b600388901c6007891660005b86518110156127755760008a900361243d578261241d816135c8565b60008181526001870160205260409020549b5093506007925061244b9050565b81612447816135c8565b9250505b6000806000808a858151811061246357612463613214565b6020908102919091018101517fffffffff0000000000000000000000000000000000000000000000000000000081166000908152918a9052604090912054909150606081901c612535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608401610360565b30606082901c036125c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e0000000000000000000000000000000000006064820152608401610360565b600587901b8f901b94507fffffffff0000000000000000000000000000000000000000000000000000000080861690831614612666577fffffffff000000000000000000000000000000000000000000000000000000008516600090815260208a90526040902080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff83161790555b7fffffffff0000000000000000000000000000000000000000000000000000000091909116600090815260208990526040812055600381901c611fff16925060051b60e01690508582146126fb576000828152600188016020526040902080547fffffffff0000000000000000000000000000000000000000000000000000000080841c19909116908516831c17905561274c565b80837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c817fffffffff0000000000000000000000000000000000000000000000000000000060001b901c198e16179c505b8460000361276a57600086815260018801602052604081208190559c505b505050600101612401565b50806127828360086135fd565b61278c9190613201565b9950505061281d565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560448201527f74416374696f6e000000000000000000000000000000000000000000000000006064820152608401610360565b50959694955050505050565b73ffffffffffffffffffffffffffffffffffffffff8216612848575050565b61286a8260405180606001604052806028815260200161367b60289139612a17565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051612892919061355b565b600060405180830381855af49150503d80600081146128cd576040519150601f19603f3d011682016040523d82523d6000602084013e6128d2565b606091505b509150915081612922578051156128ec5780518082602001fd5b83836040517f192105d7000000000000000000000000000000000000000000000000000000008152600401610360929190613614565b50505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561295f5750600090506003612a0e565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156129b3573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116612a0757600060019250925050612a0e565b9150600090505b94509492505050565b813b8181612922576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103609190613643565b60008083601f840112612a6457600080fd5b50813567ffffffffffffffff811115612a7c57600080fd5b6020830191508360208260051b8501011115611c3457600080fd5b60008060208385031215612aaa57600080fd5b823567ffffffffffffffff811115612ac157600080fd5b612acd85828601612a52565b90969095509350505050565b60008060008060008060608789031215612af257600080fd5b863567ffffffffffffffff80821115612b0a57600080fd5b612b168a838b01612a52565b90985096506020890135915080821115612b2f57600080fd5b612b3b8a838b01612a52565b90965094506040890135915080821115612b5457600080fd5b50612b6189828a01612a52565b979a9699509497509295939492505050565b803573ffffffffffffffffffffffffffffffffffffffff81168114612b9757600080fd5b919050565b600080600080600060608688031215612bb457600080fd5b853567ffffffffffffffff80821115612bcc57600080fd5b612bd889838a01612a52565b9097509550859150612bec60208901612b73565b94506040880135915080821115612c0257600080fd5b818801915088601f830112612c1657600080fd5b813581811115612c2557600080fd5b896020828501011115612c3757600080fd5b9699959850939650602001949392505050565b600060208284031215612c5c57600080fd5b5035919050565b80357fffffffff0000000000000000000000000000000000000000000000000000000081168114612b9757600080fd5b8015158114612ca157600080fd5b50565b60008060408385031215612cb757600080fd5b612cc083612c63565b91506020830135612cd081612c93565b809150509250929050565b60008060408385031215612cee57600080fd5b82359150612cfe60208401612b73565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff81118282101715612d5957612d59612d07565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715612da657612da6612d07565b604052919050565b600067ffffffffffffffff821115612dc857612dc8612d07565b5060051b60200190565b60008060408385031215612de557600080fd5b8235915060208084013567ffffffffffffffff811115612e0457600080fd5b8401601f81018613612e1557600080fd5b8035612e28612e2382612dae565b612d5f565b81815260059190911b82018301908381019088831115612e4757600080fd5b928401925b82841015612e6c57612e5d84612b73565b82529284019290840190612e4c565b80955050505050509250929050565b803560038110612b9757600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60038110612ef0577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b8183526000602080850194508260005b85811015612f49577fffffffff00000000000000000000000000000000000000000000000000000000612f3683612c63565b1687529582019590820190600101612f04565b509495945050505050565b60208082528181018390526000906040808401600586811b8601830188865b8981101561309b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc089840301855281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa18c3603018112612fd457600080fd5b8b01606073ffffffffffffffffffffffffffffffffffffffff612ff683612b73565b168552613004898301612e7b565b6130108a870182612eb9565b50878201357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe183360301811261304557600080fd5b90910188810191903567ffffffffffffffff81111561306357600080fd5b80871b360383131561307457600080fd5b81898701526130868287018285612ef4565b978a0197955050509187019150600101612f73565b50909998505050505050505050565b60006130b8612e2384612dae565b83815260208082019190600586811b8601368111156130d657600080fd5b865b818110156131c557803567ffffffffffffffff808211156130f95760008081fd5b818a0191506060823603121561310f5760008081fd5b613117612d36565b61312083612b73565b815261312d878401612e7b565b87820152604080840135838111156131455760008081fd5b939093019236601f85011261315c57600092508283fd5b8335925061316c612e2384612dae565b83815292871b840188019288810190368511156131895760008081fd5b948901945b848610156131ae5761319f86612c63565b8252948901949089019061318e565b9183019190915250885250509483019483016130d8565b5092979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610c8757610c876131d2565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561325557600080fd5b61325e82612b73565b9392505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261329a57600080fd5b83018035915067ffffffffffffffff8211156132b557600080fd5b602001915036819003821315611c3457600080fd5b600081518084526020808501945080840160005b83811015612f495781517fffffffff0000000000000000000000000000000000000000000000000000000016875295820195908201906001016132de565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000610ee560408301846132ca565b60006020828403121561335d57600080fd5b815161325e81612c93565b81810381811115610c8757610c876131d2565b6000826133b1577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60005b838110156133d15781810151838201526020016133b9565b50506000910152565b600081518084526133f28160208601602086016133b6565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6000606080830181845280875180835260808601915060808160051b87010192506020808a0160005b838110156134d4577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80898703018552815173ffffffffffffffffffffffffffffffffffffffff8151168752838101516134a885890182612eb9565b506040908101519087018890526134c1878901826132ca565b965050938201939082019060010161344d565b505073ffffffffffffffffffffffffffffffffffffffff8916908701525050838103604085015261350581866133da565b979650505050505050565b60006020828403121561352257600080fd5b81516fffffffffffffffffffffffffffffffff8116811461325e57600080fd5b828152604060208201526000610ee560408301846133da565b6000825161356d8184602087016133b6565b9190910192915050565b60006020828403121561358957600080fd5b5051919050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036135c1576135c16131d2565b5060010190565b6000816135d7576135d76131d2565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b8082028115828204841417610c8757610c876131d2565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000610ee560408301846133da565b60208152600061325e60208301846133da56fe4c69624469616d6f6e644375743a2041646420666163657420686173206e6f20636f64654c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a205265706c61636520666163657420686173206e6f20636f6465a2646970667358221220c5a8c10b22f20cde3fe0431ff57305237423677a60888f5b349fc6751336ae1464736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "Responsible for adding/removing/replace facets in Barz", + "kind": "dev", + "methods": { + "_checkDuplicateOnChainApprover(bytes32,address[])": { + "params": { + "_approvers": "List of approver addresses", + "_diamondCutHash": "Hash of diamondCut information including the facet addresses and function selectors" + } + }, + "approveDiamondCut((address,uint8,bytes4[])[])": { + "params": { + "_diamondCut": "Contains the facet addresses and function selectors" + } + }, + "constructor": { + "params": { + "_securityManager": "Security Manager contract that holds the security related variables for all wallets" + } + }, + "diamondCut((address,uint8,bytes4[])[],address,bytes)": { + "params": { + "_diamondCut": "Contains the facet addresses and function selectors", + "_init": "The address of the contract or facet to execute _calldata. It's prohibited in Barz" + } + }, + "diamondCutWithGuardian((address,uint8,bytes4[])[],address[],bytes[])": { + "params": { + "_approvers": "Guardian or owner address that approves the diamond cut", + "_diamondCut": "Contains the facet addresses and function selectors", + "_signatures": "Signature of Guardians or owner that approves the diamond cut" + } + }, + "getDiamondCutApprovalCountWithTimeValidity(bytes32)": { + "params": { + "_diamondCutHash": "Hash of diamondCut information including the facet addresses and function selectors" + } + }, + "getDiamondCutHash((address,uint8,bytes4[])[])": { + "params": { + "_diamondCut": "Contains the facet addresses and function selectors" + }, + "returns": { + "cutHash": "Diamond Cut Hash" + } + }, + "getDiamondCutNonce()": { + "details": "This method fetches the nonce from diamond cut storage", + "returns": { + "cutNonce": "Nonce of diamond cut to protect from reply attacks" + } + }, + "getOwnerCutApprovalWithTimeValidity(bytes32)": { + "params": { + "_diamondCutHash": "Hash of diamondCut information including the facet addresses and function selectors" + }, + "returns": { + "isApprovedByOwner": "Bool value showing if the owner approved the cut" + } + }, + "isCutApproved(bytes32,address)": { + "params": { + "_approver": "Address of approver", + "_diamondCutHash": "Hash of diamondCut information including the facet addresses and function selectors" + }, + "returns": { + "isApproved": "Bool value showing if the approver approved the cut" + } + }, + "revokeDiamondCutApproval((address,uint8,bytes4[])[])": { + "params": { + "_diamondCut": "Contains the facet addresses and function selectors" + } + }, + "updateSupportsInterface(bytes4,bool)": { + "params": { + "_flag": "Bool value to update the mapping of the given interface ID", + "_interfaceId": "InterfaceID to update the mapping" + } + } + }, + "title": "DiamondCut Facet", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "_checkDuplicateOnChainApprover(bytes32,address[])": { + "notice": "Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval Approvers who approved on-chain should not be included in the off-chain approval" + }, + "approveDiamondCut((address,uint8,bytes4[])[])": { + "notice": "Approves diamond cut. This can only be called directly from guardian or owner" + }, + "constructor": { + "notice": "This constructor sets the Security Manager address which is an immutable variable. Immutable variables do not impact the storage of diamond" + }, + "diamondCut((address,uint8,bytes4[])[],address,bytes)": { + "notice": "Add/replace/remove any number of functions and optionally execute a function with delegatecall when guardians don't exist" + }, + "diamondCutWithGuardian((address,uint8,bytes4[])[],address[],bytes[])": { + "notice": "Add/replace/remove any number of functions and optionally execute a function with delegatecall when guardians exist" + }, + "getDiamondCutApprovalCountWithTimeValidity(bytes32)": { + "notice": "Gets the number of approvals of diamond cut from guardians" + }, + "getDiamondCutHash((address,uint8,bytes4[])[])": { + "notice": "Returns the diamond cut hash. This function ensures that this hash is safe from replay attack by including salt, address, chainId, and nonce, etc." + }, + "getDiamondCutNonce()": { + "notice": "Returns the diamond cut nonce of this wallet" + }, + "getOwnerCutApprovalWithTimeValidity(bytes32)": { + "notice": "Returns if the owner has approved the diamond cut" + }, + "isCutApproved(bytes32,address)": { + "notice": "Returns if the given approver has approved the diamond cut" + }, + "revokeDiamondCutApproval((address,uint8,bytes4[])[])": { + "notice": "Revokes the approval of diamond cut. This can only be called directly from guardian or owner" + }, + "updateSupportsInterface(bytes4,bool)": { + "notice": "Updates the flag for the interfaceId" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 27866, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "s", + "offset": 0, + "slot": "0", + "type": "t_struct(AppStorage)27613_storage" + } + ], + "types": { + "t_bytes4": { + "encoding": "inplace", + "label": "bytes4", + "numberOfBytes": "4" + }, + "t_contract(IEntryPoint)12286": { + "encoding": "inplace", + "label": "contract IEntryPoint", + "numberOfBytes": "20" + }, + "t_contract(IFacetRegistry)26148": { + "encoding": "inplace", + "label": "contract IFacetRegistry", + "numberOfBytes": "20" + }, + "t_mapping(t_uint256,t_struct(InitializersStorage)27592_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => struct InitializersStorage)", + "numberOfBytes": "32", + "value": "t_struct(InitializersStorage)27592_storage" + }, + "t_mapping(t_uint256,t_struct(Lock)27585_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => struct Lock)", + "numberOfBytes": "32", + "value": "t_struct(Lock)27585_storage" + }, + "t_struct(AppStorage)27613_storage": { + "encoding": "inplace", + "label": "struct AppStorage", + "members": [ + { + "astId": 27597, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "initStorage", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_uint256,t_struct(InitializersStorage)27592_storage)" + }, + { + "astId": 27599, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "signerMigration", + "offset": 0, + "slot": "1", + "type": "t_uint8" + }, + { + "astId": 27601, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "validateOwnerSignatureSelector", + "offset": 1, + "slot": "1", + "type": "t_bytes4" + }, + { + "astId": 27604, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "entryPoint", + "offset": 5, + "slot": "1", + "type": "t_contract(IEntryPoint)12286" + }, + { + "astId": 27607, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "facetRegistry", + "offset": 0, + "slot": "2", + "type": "t_contract(IFacetRegistry)26148" + }, + { + "astId": 27612, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "locks", + "offset": 0, + "slot": "3", + "type": "t_mapping(t_uint256,t_struct(Lock)27585_storage)" + } + ], + "numberOfBytes": "128" + }, + "t_struct(InitializersStorage)27592_storage": { + "encoding": "inplace", + "label": "struct InitializersStorage", + "members": [ + { + "astId": 27587, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "signerInitialized", + "offset": 0, + "slot": "0", + "type": "t_uint8" + }, + { + "astId": 27589, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "accountInitialized", + "offset": 1, + "slot": "0", + "type": "t_uint8" + }, + { + "astId": 27591, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "restrictionsInitialized", + "offset": 2, + "slot": "0", + "type": "t_uint8" + } + ], + "numberOfBytes": "32" + }, + "t_struct(Lock)27585_storage": { + "encoding": "inplace", + "label": "struct Lock", + "members": [ + { + "astId": 27582, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "release", + "offset": 0, + "slot": "0", + "type": "t_uint64" + }, + { + "astId": 27584, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "locker", + "offset": 8, + "slot": "0", + "type": "t_bytes4" + } + ], + "numberOfBytes": "32" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint64": { + "encoding": "inplace", + "label": "uint64", + "numberOfBytes": "8" + }, + "t_uint8": { + "encoding": "inplace", + "label": "uint8", + "numberOfBytes": "1" + } + } + } +} \ No newline at end of file diff --git a/deployments/linea/DiamondLoupeFacet.json b/deployments/linea/DiamondLoupeFacet.json new file mode 100644 index 0000000..9ad1feb --- /dev/null +++ b/deployments/linea/DiamondLoupeFacet.json @@ -0,0 +1,306 @@ +{ + "address": "0xCe36b85d12D81cd619C745c7717f3396E184Ac7C", + "abi": [ + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_functionSelector", + "type": "bytes4" + } + ], + "name": "facetAddress", + "outputs": [ + { + "internalType": "address", + "name": "facetAddress_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_functionSelector", + "type": "bytes4" + } + ], + "name": "facetAddressFromStorage", + "outputs": [ + { + "internalType": "address", + "name": "facetAddress_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetAddresses", + "outputs": [ + { + "internalType": "address[]", + "name": "facetAddresses_", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetAddressesFromStorage", + "outputs": [ + { + "internalType": "address[]", + "name": "facetAddresses_", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_facet", + "type": "address" + } + ], + "name": "facetFunctionSelectors", + "outputs": [ + { + "internalType": "bytes4[]", + "name": "facetFunctionSelectors_", + "type": "bytes4[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_facet", + "type": "address" + } + ], + "name": "facetFunctionSelectorsFromStorage", + "outputs": [ + { + "internalType": "bytes4[]", + "name": "facetFunctionSelectors_", + "type": "bytes4[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facets", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondLoupe.Facet[]", + "name": "facets_", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetsFromStorage", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondLoupe.Facet[]", + "name": "facets_", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "isSupported", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0x4341c1764859631df3198d4d1a38771e2b443997681251d6b3562617a4bc7580", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 3, + "gasUsed": "2036373", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x9b1f2e9bf5d18f319a383ca03bdc89315da709c07c45f143dd33c849f31a379a", + "transactionHash": "0x4341c1764859631df3198d4d1a38771e2b443997681251d6b3562617a4bc7580", + "logs": [], + "blockNumber": 2720823, + "cumulativeGasUsed": "3319264", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "ad34345aa73d96f52b3e14df983b6b29", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_functionSelector\",\"type\":\"bytes4\"}],\"name\":\"facetAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"facetAddress_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_functionSelector\",\"type\":\"bytes4\"}],\"name\":\"facetAddressFromStorage\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"facetAddress_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetAddresses\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"facetAddresses_\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetAddressesFromStorage\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"facetAddresses_\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_facet\",\"type\":\"address\"}],\"name\":\"facetFunctionSelectors\",\"outputs\":[{\"internalType\":\"bytes4[]\",\"name\":\"facetFunctionSelectors_\",\"type\":\"bytes4[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_facet\",\"type\":\"address\"}],\"name\":\"facetFunctionSelectorsFromStorage\",\"outputs\":[{\"internalType\":\"bytes4[]\",\"name\":\"facetFunctionSelectors_\",\"type\":\"bytes4[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facets\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondLoupe.Facet[]\",\"name\":\"facets_\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetsFromStorage\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondLoupe.Facet[]\",\"name\":\"facets_\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isSupported\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"DiamondLoupe contract compatible with EIP-2535\",\"kind\":\"dev\",\"methods\":{\"facetAddress(bytes4)\":{\"details\":\"If facet is not found return address(0).\",\"params\":{\"_functionSelector\":\"The function selector.\"},\"returns\":{\"facetAddress_\":\"The facet address.\"}},\"facetAddressFromStorage(bytes4)\":{\"params\":{\"_functionSelector\":\"Function selector to fetch the facet address from diamond storage\"},\"returns\":{\"facetAddress_\":\"Facet address mapped with the function selector\"}},\"facetAddresses()\":{\"returns\":{\"facetAddresses_\":\"facetAddresses_\"}},\"facetAddressesFromStorage()\":{\"returns\":{\"facetAddresses_\":\"All facet addresses attached directly to diamond storage\"}},\"facetFunctionSelectors(address)\":{\"params\":{\"_facet\":\"The facet address.\"},\"returns\":{\"facetFunctionSelectors_\":\"facetFunctionSelectors_\"}},\"facetFunctionSelectorsFromStorage(address)\":{\"params\":{\"_facet\":\"Facet address to fetch the facet function selectors from diamond storage\"},\"returns\":{\"facetFunctionSelectors_\":\"Facet function selectors of the given facet address\"}},\"facets()\":{\"details\":\"Barz uses a special architecture called default fallback handler. Default Fallback handler is used as a middleware that holds the mapping of facet function selector and facet address that Barz uses. This helps Barz to reduce significant amount of gas during the initialization process. Hence, this method aggregates both the facet information from DefaulFallbackHandler and in diamond storage and shows the data to users.\",\"returns\":{\"facets_\":\"Facet\"}},\"facetsFromStorage()\":{\"returns\":{\"facets_\":\"Facet information attached directly to diamond storage\"}},\"supportsInterface(bytes4)\":{\"params\":{\"_interfaceId\":\"Interface ID for detecting the interface\"},\"returns\":{\"isSupported\":\"Bool value showing if the standard is supported in the contract\"}}},\"title\":\"DiamondLoupe Facet\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"facetAddress(bytes4)\":{\"notice\":\"Gets the facet that supports the given selector.\"},\"facetAddressFromStorage(bytes4)\":{\"notice\":\"Returns the facet address attached to the given function selector. This excludes the facets from the default fallback handler\"},\"facetAddresses()\":{\"notice\":\"Get all the facet addresses used by Barz.\"},\"facetAddressesFromStorage()\":{\"notice\":\"Returns all facet addresses attached directly to diamond storage. This excludes the facets from the default fallback handler\"},\"facetFunctionSelectors(address)\":{\"notice\":\"Gets all the function selectors provided by a facet.\"},\"facetFunctionSelectorsFromStorage(address)\":{\"notice\":\"Returns function selectors of given facet address attached directly to diamond storage. This excludes the facets from the default fallback handler\"},\"facets()\":{\"notice\":\"Gets all facets and their selectors.\"},\"facetsFromStorage()\":{\"notice\":\"Returns the facet from the diamond storage. This excludes the facets from the default fallback handler\"},\"supportsInterface(bytes4)\":{\"notice\":\"SupportInterface to be compatible with EIP 165\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/base/DiamondLoupeFacet.sol\":\"DiamondLoupeFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/introspection/IERC165.sol\\\";\\n\\n/**\\n * @dev _Available since v3.1._\\n */\\ninterface IERC1155Receiver is IERC165 {\\n /**\\n * @dev Handles the receipt of a single ERC1155 token type. This function is\\n * called at the end of a `safeTransferFrom` after the balance has been updated.\\n *\\n * NOTE: To accept the transfer, this must return\\n * `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))`\\n * (i.e. 0xf23a6e61, or its own function selector).\\n *\\n * @param operator The address which initiated the transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param id The ID of the token being transferred\\n * @param value The amount of tokens being transferred\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155Received(\\n address operator,\\n address from,\\n uint256 id,\\n uint256 value,\\n bytes calldata data\\n ) external returns (bytes4);\\n\\n /**\\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\\n * is called at the end of a `safeBatchTransferFrom` after the balances have\\n * been updated.\\n *\\n * NOTE: To accept the transfer(s), this must return\\n * `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))`\\n * (i.e. 0xbc197c81, or its own function selector).\\n *\\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155BatchReceived(\\n address operator,\\n address from,\\n uint256[] calldata ids,\\n uint256[] calldata values,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xeb373f1fdc7b755c6a750123a9b9e3a8a02c1470042fd6505d875000a80bde0b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title ERC721 token receiver interface\\n * @dev Interface for any contract that wants to support safeTransfers\\n * from ERC721 asset contracts.\\n */\\ninterface IERC721Receiver {\\n /**\\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\\n * by `operator` from `from`, this function is called.\\n *\\n * It must return its Solidity selector to confirm the token transfer.\\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\\n *\\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\\n */\\n function onERC721Received(\\n address operator,\\n address from,\\n uint256 tokenId,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\\n *\\n * Accounts can be notified of {IERC777} tokens being sent to them by having a\\n * contract implement this interface (contract holders can be their own\\n * implementer) and registering it on the\\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\\n *\\n * See {IERC1820Registry} and {ERC1820Implementer}.\\n */\\ninterface IERC777Recipient {\\n /**\\n * @dev Called by an {IERC777} token contract whenever tokens are being\\n * moved or created into a registered account (`to`). The type of operation\\n * is conveyed by `from` being the zero address or not.\\n *\\n * This call occurs _after_ the token contract's state is updated, so\\n * {IERC777-balanceOf}, etc., can be used to query the post-operation state.\\n *\\n * This function may revert to prevent the operation from being executed.\\n */\\n function tokensReceived(\\n address operator,\\n address from,\\n address to,\\n uint256 amount,\\n bytes calldata userData,\\n bytes calldata operatorData\\n ) external;\\n}\\n\",\"keccak256\":\"0x1a5d61db2733202ba361e6d6741cd2e662380e22b80e987eacfc91973f2267dc\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"contracts/facets/base/DiamondLoupeFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IERC777Recipient} from \\\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\\\";\\nimport {IERC165} from \\\"../../interfaces/ERC/IERC165.sol\\\";\\nimport {IERC1271} from \\\"../../interfaces/ERC/IERC1271.sol\\\";\\nimport {IERC677Receiver} from \\\"../../interfaces/ERC/IERC677Receiver.sol\\\";\\nimport {IERC721Receiver} from \\\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\\\";\\nimport {IERC1155Receiver} from \\\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\\\";\\nimport {LibDiamond} from \\\"../../libraries/LibDiamond.sol\\\";\\nimport {LibLoupe} from \\\"../../libraries/LibLoupe.sol\\\";\\nimport {LibUtils} from \\\"../../libraries/LibUtils.sol\\\";\\nimport {IDiamondCut} from \\\"../../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IStorageLoupe} from \\\"./interfaces/IStorageLoupe.sol\\\";\\nimport {IDiamondLoupe} from \\\"./interfaces/IDiamondLoupe.sol\\\";\\n\\n/**\\n * @title DiamondLoupe Facet\\n * @dev DiamondLoupe contract compatible with EIP-2535\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract DiamondLoupeFacet is IDiamondLoupe, IStorageLoupe, IERC165 {\\n // Diamond Loupe Functions\\n ////////////////////////////////////////////////////////////////////\\n /// These functions are expected to be called frequently by tools off-chain.\\n\\n /**\\n * @notice Gets all facets and their selectors.\\n * @dev Barz uses a special architecture called default fallback handler. Default Fallback handler is used as a middleware\\n * that holds the mapping of facet function selector and facet address that Barz uses. This helps Barz to reduce\\n * significant amount of gas during the initialization process.\\n * Hence, this method aggregates both the facet information from DefaulFallbackHandler and in diamond storage and shows the data to users.\\n * @return facets_ Facet\\n */\\n function facets() public view override returns (Facet[] memory facets_) {\\n Facet[] memory defaultFacet = LibDiamond\\n .diamondStorage()\\n .defaultFallbackHandler\\n .facets();\\n Facet[] memory _facets = LibLoupe.facets();\\n uint256 numFacets = _facets.length;\\n bytes4[] memory keys;\\n address[] memory values;\\n for (uint256 i; i < numFacets; ) {\\n uint256 selectorsLength = _facets[i].functionSelectors.length;\\n for (uint256 j; j < selectorsLength; ) {\\n (keys, values) = LibUtils.setValue(\\n keys,\\n values,\\n _facets[i].functionSelectors[j],\\n _facets[i].facetAddress\\n );\\n unchecked {\\n ++j;\\n }\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n {\\n bool iIncrement;\\n for (uint256 i; i < defaultFacet.length; ) {\\n bool jIncrement;\\n for (\\n uint256 j;\\n j < defaultFacet[i].functionSelectors.length;\\n\\n ) {\\n if (\\n LibUtils.getValue(\\n keys,\\n values,\\n defaultFacet[i].functionSelectors[j]\\n ) != address(0)\\n ) {\\n if (defaultFacet[i].functionSelectors.length == 1) {\\n defaultFacet = LibUtils.removeFacetElement(\\n defaultFacet,\\n i\\n );\\n iIncrement = true;\\n break;\\n }\\n defaultFacet[i].functionSelectors = LibUtils\\n .removeElement(\\n defaultFacet[i].functionSelectors,\\n j\\n );\\n jIncrement = true;\\n }\\n if (!jIncrement) {\\n unchecked {\\n ++j;\\n }\\n } else {\\n jIncrement = false;\\n }\\n }\\n if (!iIncrement) {\\n unchecked {\\n ++i;\\n }\\n } else {\\n iIncrement = false;\\n }\\n }\\n }\\n {\\n uint256 facetLength = numFacets + defaultFacet.length;\\n facets_ = new Facet[](facetLength);\\n uint256 defaultFacetIndex;\\n for (uint256 i; i < facetLength; ) {\\n if (i < numFacets) {\\n facets_[i] = _facets[i];\\n bool jIncrementor;\\n for (uint256 j; j < defaultFacet.length; ) {\\n if (\\n facets_[i].facetAddress ==\\n defaultFacet[j].facetAddress\\n ) {\\n facets_[i].functionSelectors = LibUtils.mergeArrays(\\n _facets[i].functionSelectors,\\n defaultFacet[j].functionSelectors\\n );\\n defaultFacet = LibUtils.removeFacetElement(\\n defaultFacet,\\n j\\n );\\n jIncrementor = true;\\n {\\n facets_ = LibUtils.removeFacetElement(\\n facets_,\\n facets_.length - 1\\n );\\n }\\n --facetLength;\\n }\\n if (!jIncrementor) {\\n unchecked {\\n ++j;\\n }\\n } else {\\n jIncrementor = false;\\n }\\n }\\n } else {\\n facets_[i] = defaultFacet[defaultFacetIndex];\\n ++defaultFacetIndex;\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n }\\n\\n /**\\n * @notice Gets all the function selectors provided by a facet.\\n * @param _facet The facet address.\\n * @return facetFunctionSelectors_\\n */\\n function facetFunctionSelectors(\\n address _facet\\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\\n Facet[] memory facet = facets();\\n uint256 facetLength = facet.length;\\n for (uint256 i; i < facetLength; ) {\\n if (facet[i].facetAddress == _facet)\\n return facet[i].functionSelectors;\\n unchecked {\\n ++i;\\n }\\n }\\n return facetFunctionSelectors_;\\n }\\n\\n /**\\n * @notice Get all the facet addresses used by Barz.\\n * @return facetAddresses_\\n */\\n function facetAddresses()\\n external\\n view\\n override\\n returns (address[] memory facetAddresses_)\\n {\\n Facet[] memory facet = facets();\\n uint256 facetLength = facet.length;\\n facetAddresses_ = new address[](facetLength);\\n for (uint256 i; i < facetLength; ) {\\n facetAddresses_[i] = facet[i].facetAddress;\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * @notice Gets the facet that supports the given selector.\\n * @dev If facet is not found return address(0).\\n * @param _functionSelector The function selector.\\n * @return facetAddress_ The facet address.\\n */\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view override returns (address facetAddress_) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n\\n facetAddress_ = address(bytes20(ds.facets[_functionSelector]));\\n if (facetAddress_ == address(0)) {\\n facetAddress_ = IDiamondLoupe(ds.defaultFallbackHandler)\\n .facetAddress(_functionSelector);\\n }\\n }\\n\\n /**\\n * @notice SupportInterface to be compatible with EIP 165\\n * @param _interfaceId Interface ID for detecting the interface\\n * @return isSupported Bool value showing if the standard is supported in the contract\\n */\\n function supportsInterface(\\n bytes4 _interfaceId\\n ) external view override returns (bool isSupported) {\\n isSupported =\\n _interfaceId == type(IERC165).interfaceId ||\\n _interfaceId == IDiamondCut.diamondCut.selector ||\\n _interfaceId == type(IDiamondLoupe).interfaceId ||\\n _interfaceId == type(IERC1155Receiver).interfaceId ||\\n _interfaceId == type(IERC721Receiver).interfaceId ||\\n _interfaceId == type(IERC777Recipient).interfaceId ||\\n _interfaceId == IERC1271.isValidSignature.selector ||\\n _interfaceId == type(IERC677Receiver).interfaceId ||\\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId];\\n }\\n\\n /**\\n * @notice Returns the facet from the diamond storage. This excludes the facets from the default fallback handler\\n * @return facets_ Facet information attached directly to diamond storage\\n */\\n function facetsFromStorage()\\n external\\n view\\n override\\n returns (Facet[] memory facets_)\\n {\\n facets_ = LibLoupe.facets();\\n }\\n\\n /**\\n * @notice Returns the facet address attached to the given function selector. This excludes the facets from the default fallback handler\\n * @param _functionSelector Function selector to fetch the facet address from diamond storage\\n * @return facetAddress_ Facet address mapped with the function selector\\n */\\n function facetAddressFromStorage(\\n bytes4 _functionSelector\\n ) external view override returns (address facetAddress_) {\\n facetAddress_ = LibLoupe.facetAddress(_functionSelector);\\n }\\n\\n /**\\n * @notice Returns all facet addresses attached directly to diamond storage. This excludes the facets from the default fallback handler\\n * @return facetAddresses_ All facet addresses attached directly to diamond storage\\n */\\n function facetAddressesFromStorage()\\n external\\n view\\n override\\n returns (address[] memory facetAddresses_)\\n {\\n facetAddresses_ = LibLoupe.facetAddresses();\\n }\\n\\n /**\\n * @notice Returns function selectors of given facet address attached directly to diamond storage. This excludes the facets from the default fallback handler\\n * @param _facet Facet address to fetch the facet function selectors from diamond storage\\n * @return facetFunctionSelectors_ Facet function selectors of the given facet address\\n */\\n function facetFunctionSelectorsFromStorage(\\n address _facet\\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\\n facetFunctionSelectors_ = LibLoupe.facetFunctionSelectors(_facet);\\n }\\n}\\n\",\"keccak256\":\"0xf392fde159eec6483fc15fa323ecd6d764028f5b8734a66662c4116292363794\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IStorageLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"./IDiamondLoupe.sol\\\";\\n\\n/**\\n * @title LoupeFromStorage Interface\\n * @dev Interface contract to function as a loupe facet directly attached to diamond storage of Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IStorageLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facetsFromStorage()\\n external\\n view\\n returns (IDiamondLoupe.Facet[] memory);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n function facetFunctionSelectorsFromStorage(\\n address _facet\\n ) external view returns (bytes4[] memory);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n function facetAddressesFromStorage()\\n external\\n view\\n returns (address[] memory);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n function facetAddressFromStorage(\\n bytes4 _functionSelector\\n ) external view returns (address);\\n}\\n\",\"keccak256\":\"0xdf5dc9c57319e9087628c9cf9404b4f75585b76d1c2f4f59ee796c933967ea5c\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC1271 {\\n function isValidSignature(\\n bytes32 hash,\\n bytes memory signature\\n ) external view returns (bytes4);\\n}\\n\",\"keccak256\":\"0xcdddb7d5641c9d3f2432dec7fd13fddb9ae1480f25c76c21511e2fa16b8bd422\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.21;\\n\\ninterface IERC165 {\\n /// @notice Query if a contract implements an interface\\n /// @param interfaceId The interface identifier, as specified in ERC-165\\n /// @dev Interface identification is specified in ERC-165. This function\\n /// uses less than 30,000 gas.\\n /// @return `true` if the contract implements `interfaceID` and\\n /// `interfaceID` is not 0xffffffff, `false` otherwise\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xbb7f07e170898793c5535cc4b7e8944c4b990a631ac806d0b788e794abc788a3\",\"license\":\"MIT\"},\"contracts/interfaces/ERC/IERC677Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC677Receiver {\\n function onTokenTransfer(\\n address sender,\\n uint value,\\n bytes calldata data\\n ) external pure returns (bool);\\n}\\n\",\"keccak256\":\"0x4c1631cf45ea6daac0ec158c3edb9453099130b6b64f697004b83f95aa1f7350\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\\n bytes4(keccak256(\\\"verifyRestrictions(address,address,uint256,bytes)\\\"));\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // Default Fallback Handler of the barz.\\n IDiamondLoupe defaultFallbackHandler;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function enforceIsSelf() internal view {\\n require(msg.sender == address(this), \\\"LibDiamond: Caller not self\\\");\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n\\n unchecked {\\n facetIndex++;\\n }\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n\\n function restrictionsFacet() internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(\\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2cabdc00de859c3a3170ce3bda5d0e5fd3933d47ce904fd1585f9818b02572f8\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\nimport {LibDiamond} from \\\"./LibDiamond.sol\\\";\\n\\n/**\\n * @title LibLoupe\\n * @dev Internal Library to provide utility feature for reading the state of diamond facets\\n * Originally from Diamond's implementation of Mudgen(author of EIP-2535)\\n */\\nlibrary LibLoupe {\\n /// @notice Gets all facets and their selectors.\\n /// @return facets_ Facet\\n function facets()\\n internal\\n view\\n returns (IDiamondLoupe.Facet[] memory facets_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facets_ = new IDiamondLoupe.Facet[](ds.selectorCount);\\n uint16[] memory numFacetSelectors = new uint16[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facets_[facetIndex].facetAddress == facetAddress_) {\\n facets_[facetIndex].functionSelectors[\\n numFacetSelectors[facetIndex]\\n ] = selector;\\n // probably will never have more than 256 functions from one facet contract\\n require(numFacetSelectors[facetIndex] < 255);\\n numFacetSelectors[facetIndex]++;\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facets_[numFacets].facetAddress = facetAddress_;\\n facets_[numFacets].functionSelectors = new bytes4[](\\n ds.selectorCount\\n );\\n facets_[numFacets].functionSelectors[0] = selector;\\n numFacetSelectors[numFacets] = 1;\\n numFacets++;\\n }\\n }\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n uint256 numSelectors = numFacetSelectors[facetIndex];\\n bytes4[] memory selectors = facets_[facetIndex].functionSelectors;\\n // setting the number of selectors\\n assembly {\\n mstore(selectors, numSelectors)\\n }\\n }\\n // setting the number of facets\\n assembly {\\n mstore(facets_, numFacets)\\n }\\n }\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return _facetFunctionSelectors The selectors associated with a facet address.\\n function facetFunctionSelectors(\\n address _facet\\n ) internal view returns (bytes4[] memory _facetFunctionSelectors) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n uint256 numSelectors;\\n _facetFunctionSelectors = new bytes4[](ds.selectorCount);\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facet = address(bytes20(ds.facets[selector]));\\n if (_facet == facet) {\\n _facetFunctionSelectors[numSelectors] = selector;\\n numSelectors++;\\n }\\n }\\n }\\n // Set the number of selectors in the array\\n assembly {\\n mstore(_facetFunctionSelectors, numSelectors)\\n }\\n }\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n internal\\n view\\n returns (address[] memory facetAddresses_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetAddresses_ = new address[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facetAddress_ == facetAddresses_[facetIndex]) {\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facetAddresses_[numFacets] = facetAddress_;\\n numFacets++;\\n }\\n }\\n // Set the number of facet addresses in the array\\n assembly {\\n mstore(facetAddresses_, numFacets)\\n }\\n }\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(LibDiamond.diamondStorage().facets[_functionSelector])\\n );\\n }\\n}\\n\",\"keccak256\":\"0x0b11439c3cc657095e15ec2241fdcf67204b14001357b612fc5db4ff9e760a5a\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibUtils.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nlibrary LibUtils {\\n // Internal utility functions\\n function mergeArrays(\\n bytes4[] memory _array1,\\n bytes4[] memory _array2\\n ) internal pure returns (bytes4[] memory) {\\n uint256 length1 = _array1.length;\\n uint256 length2 = _array2.length;\\n bytes4[] memory mergedArray = new bytes4[](length1 + length2);\\n\\n for (uint256 i; i < length1; ) {\\n mergedArray[i] = _array1[i];\\n unchecked {\\n ++i;\\n }\\n }\\n\\n for (uint256 i; i < length2; ) {\\n mergedArray[length1 + i] = _array2[i];\\n unchecked {\\n ++i;\\n }\\n }\\n\\n return mergedArray;\\n }\\n\\n function removeFacetElement(\\n IDiamondLoupe.Facet[] memory _facets,\\n uint256 _index\\n ) internal pure returns (IDiamondLoupe.Facet[] memory) {\\n require(_index < _facets.length, \\\"Invalid index\\\");\\n require(_facets.length != 0, \\\"Invalid array\\\");\\n\\n // Create a new array with a length of `_facets.length - 1`\\n IDiamondLoupe.Facet[] memory newArray = new IDiamondLoupe.Facet[](\\n _facets.length - 1\\n );\\n uint256 newArrayLength = newArray.length;\\n // Iterate over the original array, skipping the element at the specified `index`\\n for (uint256 i; i < newArrayLength; ) {\\n if (i < _index) {\\n newArray[i] = _facets[i];\\n } else {\\n newArray[i] = _facets[i + 1];\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n\\n return newArray;\\n }\\n\\n function removeElement(\\n bytes4[] memory _array,\\n uint256 _index\\n ) internal pure returns (bytes4[] memory) {\\n require(_index < _array.length, \\\"Invalid index\\\");\\n require(_array.length != 0, \\\"Invalid array\\\");\\n\\n bytes4[] memory newArray = new bytes4[](_array.length - 1);\\n uint256 newArrayLength = newArray.length;\\n for (uint256 i; i < newArrayLength; ) {\\n if (i < _index) {\\n newArray[i] = _array[i];\\n } else {\\n newArray[i] = _array[i + 1];\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n\\n return newArray;\\n }\\n\\n function setValue(\\n bytes4[] memory _keys,\\n address[] memory _values,\\n bytes4 _key,\\n address _value\\n ) internal pure returns (bytes4[] memory, address[] memory) {\\n uint256 index = findIndex(_keys, _key);\\n uint256 keysLength = _keys.length;\\n if (index < keysLength) {\\n _values[index] = _value;\\n } else {\\n // Create new storage arrays\\n bytes4[] memory newKeys = new bytes4[](keysLength + 1);\\n address[] memory newValues = new address[](_values.length + 1);\\n\\n // Copy values to the new storage arrays\\n for (uint256 i; i < keysLength; ) {\\n newKeys[i] = _keys[i];\\n newValues[i] = _values[i];\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n // Add the new key-value pair\\n newKeys[keysLength] = _key;\\n newValues[_values.length] = _value;\\n\\n return (newKeys, newValues);\\n }\\n\\n // If the key already exists, return the original arrays\\n return (_keys, _values);\\n }\\n\\n function getValue(\\n bytes4[] memory _keys,\\n address[] memory _values,\\n bytes4 _key\\n ) internal pure returns (address) {\\n uint256 index = findIndex(_keys, _key);\\n if (index >= _keys.length) return address(0);\\n\\n return _values[index];\\n }\\n\\n function findIndex(\\n bytes4[] memory _keys,\\n bytes4 _key\\n ) internal pure returns (uint256) {\\n uint256 keysLength = _keys.length;\\n for (uint256 i; i < keysLength; ) {\\n if (_keys[i] == _key) {\\n return i;\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n return keysLength;\\n }\\n}\\n\",\"keccak256\":\"0xde8aeefe54c4be483f2b2c055aca11e2830f7094c0586a82e10ec544933b5714\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5061240b806100206000396000f3fe608060405234801561001057600080fd5b50600436106100a35760003560e01c8063adfca15e11610076578063d42139a91161005b578063d42139a914610169578063e3a2f6fe14610171578063f9796ccf1461018457600080fd5b8063adfca15e1461011e578063cdffacc61461013157600080fd5b806301a55022146100a857806301ffc9a7146100d157806352ef6b2c146100f45780637a0ed62714610109575b600080fd5b6100bb6100b6366004611e4b565b61018c565b6040516100c89190611e68565b60405180910390f35b6100e46100df366004611efc565b61019d565b60405190151581526020016100c8565b6100fc610454565b6040516100c89190611f19565b610111610518565b6040516100c89190611f67565b6100bb61012c366004611e4b565b610a63565b61014461013f366004611efc565b610b07565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100c8565b6100fc610c24565b61014461017f366004611efc565b610c33565b610111610c8c565b606061019782610c96565b92915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000148061023057507fffffffff0000000000000000000000000000000000000000000000000000000082167f1f931c1c00000000000000000000000000000000000000000000000000000000145b8061027c57507fffffffff0000000000000000000000000000000000000000000000000000000082167f48e2b09300000000000000000000000000000000000000000000000000000000145b806102c857507fffffffff0000000000000000000000000000000000000000000000000000000082167f4e2312e000000000000000000000000000000000000000000000000000000000145b8061031457507fffffffff0000000000000000000000000000000000000000000000000000000082167f150b7a0200000000000000000000000000000000000000000000000000000000145b8061035f57507fffffffff0000000000000000000000000000000000000000000000000000000082167e23de2900000000000000000000000000000000000000000000000000000000145b806103ab57507fffffffff0000000000000000000000000000000000000000000000000000000082167f1626ba7e00000000000000000000000000000000000000000000000000000000145b806103f757507fffffffff0000000000000000000000000000000000000000000000000000000082167fa4c0ed3600000000000000000000000000000000000000000000000000000000145b806101975750507fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4922602052604090205460ff1690565b60606000610460610518565b80519091508067ffffffffffffffff81111561047e5761047e61205d565b6040519080825280602002602001820160405280156104a7578160200160208202803683370190505b50925060005b81811015610512578281815181106104c7576104c761208c565b6020026020010151600001518482815181106104e5576104e561208c565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526001016104ad565b50505090565b606060007f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f600490810154604080517f7a0ed627000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff90921692637a0ed6279282820192600092908290030181865afa1580156105ac573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526105f29190810190612157565b905060006105fe610e57565b805190915060608060005b838110156106b55760008582815181106106255761062561208c565b60200260200101516020015151905060005b818110156106ab5761069e85858986815181106106565761065661208c565b60200260200101516020015184815181106106735761067361208c565b60200260200101518a878151811061068d5761068d61208c565b60200260200101516000015161134a565b9095509350600101610637565b5050600101610609565b506000805b865181101561081b576000805b8883815181106106d9576106d961208c565b602002602001015160200151518110156107ff57600073ffffffffffffffffffffffffffffffffffffffff1661074687878c878151811061071c5761071c61208c565b60200260200101516020015185815181106107395761073961208c565b60200260200101516115f1565b73ffffffffffffffffffffffffffffffffffffffff16146107e9578883815181106107735761077361208c565b6020026020010151602001515160010361079c576107918984611637565b9850600193506107ff565b6107c38984815181106107b1576107b161208c565b6020026020010151602001518261182a565b8984815181106107d5576107d561208c565b602002602001015160200181905250600191505b816107f6576001016106c7565b600091506106c7565b508261081057816001019150610815565b600092505b506106ba565b5050600085518461082c9190612304565b90508067ffffffffffffffff8111156108475761084761205d565b60405190808252806020026020018201604052801561088d57816020015b6040805180820190915260008152606060208201528152602001906001900390816108655790505b5096506000805b82811015610a585785811015610a0c578681815181106108b6576108b661208c565b60200260200101518982815181106108d0576108d061208c565b60200260200101819052506000805b8951811015610a05578981815181106108fa576108fa61208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff168b848151811061092e5761092e61208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff16036109ef5761099989848151811061096a5761096a61208c565b6020026020010151602001518b83815181106109885761098861208c565b602002602001015160200151611a3d565b8b84815181106109ab576109ab61208c565b6020026020010151602001819052506109c48a82611637565b9950600191506109e18b60018d516109dc9190612317565b611637565b9a506109ec8561232a565b94505b816109fc576001016108df565b600091506108df565b5050610a50565b878281518110610a1e57610a1e61208c565b6020026020010151898281518110610a3857610a3861208c565b602002602001018190525081610a4d9061235f565b91505b600101610894565b505050505050505090565b60606000610a6f610518565b805190915060005b81811015610aff578473ffffffffffffffffffffffffffffffffffffffff16838281518110610aa857610aa861208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1603610af757828181518110610ae157610ae161208c565b6020026020010151602001519350505050919050565b600101610a77565b505050919050565b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602081905260409091205460601c9081610c1e576004818101546040517fcdffacc60000000000000000000000000000000000000000000000000000000081527fffffffff0000000000000000000000000000000000000000000000000000000086169281019290925273ffffffffffffffffffffffffffffffffffffffff169063cdffacc690602401602060405180830381865afa158015610bf7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c1b9190612397565b91505b50919050565b6060610c2e611b8b565b905090565b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604081205460601c610197565b6060610c2e610e57565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9060009061ffff1667ffffffffffffffff811115610cfc57610cfc61205d565b604051908082528060200260200182016040528015610d25578160200160208202803683370190505b5092506000805b600284015461ffff16821015610e4d576000818152600185016020526040812054905b6008811015610e385783610d628161235f565b600288015490955061ffff1685119050610e3857600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020889052604090205460601c73ffffffffffffffffffffffffffffffffffffffff8a16819003610e235781898881518110610de457610de461208c565b7fffffffff000000000000000000000000000000000000000000000000000000009092166020928302919091019091015286610e1f8161235f565b9750505b50508080610e309061235f565b915050610d4f565b50508080610e459061235f565b915050610d2c565b5050825250919050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff1667ffffffffffffffff811115610eba57610eba61205d565b604051908082528060200260200182016040528015610f0057816020015b604080518082019091526000815260606020820152815260200190600190039081610ed85790505b50600282015490925060009061ffff1667ffffffffffffffff811115610f2857610f2861205d565b604051908082528060200260200182016040528015610f51578160200160208202803683370190505b50905060008060005b600285015461ffff168210156112d7576000818152600186016020526040812054905b60088110156112c25783610f908161235f565b600289015490955061ffff16851190506112c257600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020899052604081205460601c90805b88811015611148578273ffffffffffffffffffffffffffffffffffffffff168c82815181106110155761101561208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff160361113657838c828151811061104f5761104f61208c565b6020026020010151602001518b838151811061106d5761106d61208c565b602002602001015161ffff16815181106110895761108961208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152505060ff8a82815181106110e9576110e961208c565b602002602001015161ffff16106110ff57600080fd5b8981815181106111115761111161208c565b602002602001018051809190611126906123b4565b61ffff1690525060019150611148565b806111408161235f565b915050610fe4565b508015611157575050506112b0565b818b898151811061116a5761116a61208c565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff909116905260028a015461ffff1667ffffffffffffffff8111156111b0576111b061205d565b6040519080825280602002602001820160405280156111d9578160200160208202803683370190505b508b89815181106111ec576111ec61208c565b602002602001015160200181905250828b898151811061120e5761120e61208c565b60200260200101516020015160008151811061122c5761122c61208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681525050600189898151811061128c5761128c61208c565b61ffff90921660209283029190910190910152876112a98161235f565b9850505050505b806112ba8161235f565b915050610f7d565b505080806112cf9061235f565b915050610f5a565b5060005b8281101561133f5760008482815181106112f7576112f761208c565b602002602001015161ffff16905060008783815181106113195761131961208c565b6020026020010151602001519050818152505080806113379061235f565b9150506112db565b508185525050505090565b60608060006113598786611da0565b8751909150808210156113b857848783815181106113795761137961208c565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250506115df565b60006113c5826001612304565b67ffffffffffffffff8111156113dd576113dd61205d565b604051908082528060200260200182016040528015611406578160200160208202803683370190505b5090506000885160016114199190612304565b67ffffffffffffffff8111156114315761143161205d565b60405190808252806020026020018201604052801561145a578160200160208202803683370190505b50905060005b83811015611539578a818151811061147a5761147a61208c565b60200260200101518382815181106114945761149461208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815250508981815181106114f2576114f261208c565b602002602001015182828151811061150c5761150c61208c565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101611460565b508782848151811061154d5761154d61208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152505086818a51815181106115ad576115ad61208c565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015290945092506115e8915050565b87879350935050505b94509492505050565b6000806115fe8584611da0565b905084518110611612576000915050611630565b8381815181106116245761162461208c565b60200260200101519150505b9392505050565b6060825182106116a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420696e6465780000000000000000000000000000000000000060448201526064015b60405180910390fd5b8251600003611713576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420617272617900000000000000000000000000000000000000604482015260640161169f565b6000600184516117239190612317565b67ffffffffffffffff81111561173b5761173b61205d565b60405190808252806020026020018201604052801561178157816020015b6040805180820190915260008152606060208201528152602001906001900390816117595790505b50805190915060005b8181101561182057848110156117d6578581815181106117ac576117ac61208c565b60200260200101518382815181106117c6576117c661208c565b6020026020010181905250611818565b856117e2826001612304565b815181106117f2576117f261208c565b602002602001015183828151811061180c5761180c61208c565b60200260200101819052505b60010161178a565b5090949350505050565b606082518210611896576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420696e64657800000000000000000000000000000000000000604482015260640161169f565b8251600003611901576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420617272617900000000000000000000000000000000000000604482015260640161169f565b6000600184516119119190612317565b67ffffffffffffffff8111156119295761192961205d565b604051908082528060200260200182016040528015611952578160200160208202803683370190505b50805190915060005b8181101561182057848110156119cd5785818151811061197d5761197d61208c565b60200260200101518382815181106119975761199761208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152611a35565b856119d9826001612304565b815181106119e9576119e961208c565b6020026020010151838281518110611a0357611a0361208c565b7fffffffff00000000000000000000000000000000000000000000000000000000909216602092830291909101909101525b60010161195b565b81518151606091906000611a518284612304565b67ffffffffffffffff811115611a6957611a6961205d565b604051908082528060200260200182016040528015611a92578160200160208202803683370190505b50905060005b83811015611b0557868181518110611ab257611ab261208c565b6020026020010151828281518110611acc57611acc61208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152600101611a98565b5060005b82811015611b8157858181518110611b2357611b2361208c565b6020026020010151828286611b389190612304565b81518110611b4857611b4861208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152600101611b09565b5095945050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff1667ffffffffffffffff811115611bee57611bee61205d565b604051908082528060200260200182016040528015611c17578160200160208202803683370190505b50915060008060005b600284015461ffff16821015611d98576000818152600185016020526040812054905b6008811015611d835783611c568161235f565b600288015490955061ffff1685119050611d8357600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020889052604081205460601c90805b88811015611d19578a8181518110611cc457611cc461208c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611d075760019150611d19565b80611d118161235f565b915050611caa565b508015611d2857505050611d71565b818a8981518110611d3b57611d3b61208c565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015287611d6a8161235f565b9850505050505b80611d7b8161235f565b915050611c43565b50508080611d909061235f565b915050611c20565b505082525090565b8151600090815b81811015611e1e57837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916858281518110611de157611de161208c565b60200260200101517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603611e165791506101979050565b600101611da7565b509392505050565b73ffffffffffffffffffffffffffffffffffffffff81168114611e4857600080fd5b50565b600060208284031215611e5d57600080fd5b813561163081611e26565b6020808252825182820181905260009190848201906040850190845b81811015611ec25783517fffffffff000000000000000000000000000000000000000000000000000000001683529284019291840191600101611e84565b50909695505050505050565b7fffffffff0000000000000000000000000000000000000000000000000000000081168114611e4857600080fd5b600060208284031215611f0e57600080fd5b813561163081611ece565b6020808252825182820181905260009190848201906040850190845b81811015611ec257835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101611f35565b60006020808301818452808551808352604092508286019150828160051b8701018488016000805b8481101561204e578984037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00186528251805173ffffffffffffffffffffffffffffffffffffffff168552880151888501889052805188860181905290890190839060608701905b808310156120395783517fffffffff00000000000000000000000000000000000000000000000000000000168252928b019260019290920191908b0190611ff7565b50978a01979550505091870191600101611f8f565b50919998505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6040805190810167ffffffffffffffff811182821017156120de576120de61205d565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561212b5761212b61205d565b604052919050565b600067ffffffffffffffff82111561214d5761214d61205d565b5060051b60200190565b6000602080838503121561216a57600080fd5b825167ffffffffffffffff8082111561218257600080fd5b818501915085601f83011261219657600080fd5b81516121a96121a482612133565b6120e4565b81815260059190911b830184019084810190888311156121c857600080fd5b8585015b838110156122c8578051858111156121e45760008081fd5b86016040818c037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00181131561221a5760008081fd5b6122226120bb565b8983015161222f81611e26565b815282820151888111156122435760008081fd5b8084019350508c603f8401126122595760008081fd5b898301516122696121a482612133565b81815260059190911b84018301908b8101908f8311156122895760008081fd5b948401945b828610156122b357855194506122a385611ece565b848252948c0194908c019061228e565b838d01525050855250509186019186016121cc565b5098975050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610197576101976122d5565b81810381811115610197576101976122d5565b600081612339576123396122d5565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612390576123906122d5565b5060010190565b6000602082840312156123a957600080fd5b815161163081611e26565b600061ffff8083168181036123cb576123cb6122d5565b600101939250505056fea26469706673582212205959d8d85aad6f29d5fc37d5a52c404c25392cec49195c3b761da0e863e99b0f64736f6c63430008150033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100a35760003560e01c8063adfca15e11610076578063d42139a91161005b578063d42139a914610169578063e3a2f6fe14610171578063f9796ccf1461018457600080fd5b8063adfca15e1461011e578063cdffacc61461013157600080fd5b806301a55022146100a857806301ffc9a7146100d157806352ef6b2c146100f45780637a0ed62714610109575b600080fd5b6100bb6100b6366004611e4b565b61018c565b6040516100c89190611e68565b60405180910390f35b6100e46100df366004611efc565b61019d565b60405190151581526020016100c8565b6100fc610454565b6040516100c89190611f19565b610111610518565b6040516100c89190611f67565b6100bb61012c366004611e4b565b610a63565b61014461013f366004611efc565b610b07565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100c8565b6100fc610c24565b61014461017f366004611efc565b610c33565b610111610c8c565b606061019782610c96565b92915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000148061023057507fffffffff0000000000000000000000000000000000000000000000000000000082167f1f931c1c00000000000000000000000000000000000000000000000000000000145b8061027c57507fffffffff0000000000000000000000000000000000000000000000000000000082167f48e2b09300000000000000000000000000000000000000000000000000000000145b806102c857507fffffffff0000000000000000000000000000000000000000000000000000000082167f4e2312e000000000000000000000000000000000000000000000000000000000145b8061031457507fffffffff0000000000000000000000000000000000000000000000000000000082167f150b7a0200000000000000000000000000000000000000000000000000000000145b8061035f57507fffffffff0000000000000000000000000000000000000000000000000000000082167e23de2900000000000000000000000000000000000000000000000000000000145b806103ab57507fffffffff0000000000000000000000000000000000000000000000000000000082167f1626ba7e00000000000000000000000000000000000000000000000000000000145b806103f757507fffffffff0000000000000000000000000000000000000000000000000000000082167fa4c0ed3600000000000000000000000000000000000000000000000000000000145b806101975750507fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4922602052604090205460ff1690565b60606000610460610518565b80519091508067ffffffffffffffff81111561047e5761047e61205d565b6040519080825280602002602001820160405280156104a7578160200160208202803683370190505b50925060005b81811015610512578281815181106104c7576104c761208c565b6020026020010151600001518482815181106104e5576104e561208c565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526001016104ad565b50505090565b606060007f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f600490810154604080517f7a0ed627000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff90921692637a0ed6279282820192600092908290030181865afa1580156105ac573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526105f29190810190612157565b905060006105fe610e57565b805190915060608060005b838110156106b55760008582815181106106255761062561208c565b60200260200101516020015151905060005b818110156106ab5761069e85858986815181106106565761065661208c565b60200260200101516020015184815181106106735761067361208c565b60200260200101518a878151811061068d5761068d61208c565b60200260200101516000015161134a565b9095509350600101610637565b5050600101610609565b506000805b865181101561081b576000805b8883815181106106d9576106d961208c565b602002602001015160200151518110156107ff57600073ffffffffffffffffffffffffffffffffffffffff1661074687878c878151811061071c5761071c61208c565b60200260200101516020015185815181106107395761073961208c565b60200260200101516115f1565b73ffffffffffffffffffffffffffffffffffffffff16146107e9578883815181106107735761077361208c565b6020026020010151602001515160010361079c576107918984611637565b9850600193506107ff565b6107c38984815181106107b1576107b161208c565b6020026020010151602001518261182a565b8984815181106107d5576107d561208c565b602002602001015160200181905250600191505b816107f6576001016106c7565b600091506106c7565b508261081057816001019150610815565b600092505b506106ba565b5050600085518461082c9190612304565b90508067ffffffffffffffff8111156108475761084761205d565b60405190808252806020026020018201604052801561088d57816020015b6040805180820190915260008152606060208201528152602001906001900390816108655790505b5096506000805b82811015610a585785811015610a0c578681815181106108b6576108b661208c565b60200260200101518982815181106108d0576108d061208c565b60200260200101819052506000805b8951811015610a05578981815181106108fa576108fa61208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff168b848151811061092e5761092e61208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff16036109ef5761099989848151811061096a5761096a61208c565b6020026020010151602001518b83815181106109885761098861208c565b602002602001015160200151611a3d565b8b84815181106109ab576109ab61208c565b6020026020010151602001819052506109c48a82611637565b9950600191506109e18b60018d516109dc9190612317565b611637565b9a506109ec8561232a565b94505b816109fc576001016108df565b600091506108df565b5050610a50565b878281518110610a1e57610a1e61208c565b6020026020010151898281518110610a3857610a3861208c565b602002602001018190525081610a4d9061235f565b91505b600101610894565b505050505050505090565b60606000610a6f610518565b805190915060005b81811015610aff578473ffffffffffffffffffffffffffffffffffffffff16838281518110610aa857610aa861208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1603610af757828181518110610ae157610ae161208c565b6020026020010151602001519350505050919050565b600101610a77565b505050919050565b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602081905260409091205460601c9081610c1e576004818101546040517fcdffacc60000000000000000000000000000000000000000000000000000000081527fffffffff0000000000000000000000000000000000000000000000000000000086169281019290925273ffffffffffffffffffffffffffffffffffffffff169063cdffacc690602401602060405180830381865afa158015610bf7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c1b9190612397565b91505b50919050565b6060610c2e611b8b565b905090565b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604081205460601c610197565b6060610c2e610e57565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9060009061ffff1667ffffffffffffffff811115610cfc57610cfc61205d565b604051908082528060200260200182016040528015610d25578160200160208202803683370190505b5092506000805b600284015461ffff16821015610e4d576000818152600185016020526040812054905b6008811015610e385783610d628161235f565b600288015490955061ffff1685119050610e3857600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020889052604090205460601c73ffffffffffffffffffffffffffffffffffffffff8a16819003610e235781898881518110610de457610de461208c565b7fffffffff000000000000000000000000000000000000000000000000000000009092166020928302919091019091015286610e1f8161235f565b9750505b50508080610e309061235f565b915050610d4f565b50508080610e459061235f565b915050610d2c565b5050825250919050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff1667ffffffffffffffff811115610eba57610eba61205d565b604051908082528060200260200182016040528015610f0057816020015b604080518082019091526000815260606020820152815260200190600190039081610ed85790505b50600282015490925060009061ffff1667ffffffffffffffff811115610f2857610f2861205d565b604051908082528060200260200182016040528015610f51578160200160208202803683370190505b50905060008060005b600285015461ffff168210156112d7576000818152600186016020526040812054905b60088110156112c25783610f908161235f565b600289015490955061ffff16851190506112c257600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020899052604081205460601c90805b88811015611148578273ffffffffffffffffffffffffffffffffffffffff168c82815181106110155761101561208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff160361113657838c828151811061104f5761104f61208c565b6020026020010151602001518b838151811061106d5761106d61208c565b602002602001015161ffff16815181106110895761108961208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152505060ff8a82815181106110e9576110e961208c565b602002602001015161ffff16106110ff57600080fd5b8981815181106111115761111161208c565b602002602001018051809190611126906123b4565b61ffff1690525060019150611148565b806111408161235f565b915050610fe4565b508015611157575050506112b0565b818b898151811061116a5761116a61208c565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff909116905260028a015461ffff1667ffffffffffffffff8111156111b0576111b061205d565b6040519080825280602002602001820160405280156111d9578160200160208202803683370190505b508b89815181106111ec576111ec61208c565b602002602001015160200181905250828b898151811061120e5761120e61208c565b60200260200101516020015160008151811061122c5761122c61208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681525050600189898151811061128c5761128c61208c565b61ffff90921660209283029190910190910152876112a98161235f565b9850505050505b806112ba8161235f565b915050610f7d565b505080806112cf9061235f565b915050610f5a565b5060005b8281101561133f5760008482815181106112f7576112f761208c565b602002602001015161ffff16905060008783815181106113195761131961208c565b6020026020010151602001519050818152505080806113379061235f565b9150506112db565b508185525050505090565b60608060006113598786611da0565b8751909150808210156113b857848783815181106113795761137961208c565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250506115df565b60006113c5826001612304565b67ffffffffffffffff8111156113dd576113dd61205d565b604051908082528060200260200182016040528015611406578160200160208202803683370190505b5090506000885160016114199190612304565b67ffffffffffffffff8111156114315761143161205d565b60405190808252806020026020018201604052801561145a578160200160208202803683370190505b50905060005b83811015611539578a818151811061147a5761147a61208c565b60200260200101518382815181106114945761149461208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815250508981815181106114f2576114f261208c565b602002602001015182828151811061150c5761150c61208c565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101611460565b508782848151811061154d5761154d61208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152505086818a51815181106115ad576115ad61208c565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015290945092506115e8915050565b87879350935050505b94509492505050565b6000806115fe8584611da0565b905084518110611612576000915050611630565b8381815181106116245761162461208c565b60200260200101519150505b9392505050565b6060825182106116a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420696e6465780000000000000000000000000000000000000060448201526064015b60405180910390fd5b8251600003611713576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420617272617900000000000000000000000000000000000000604482015260640161169f565b6000600184516117239190612317565b67ffffffffffffffff81111561173b5761173b61205d565b60405190808252806020026020018201604052801561178157816020015b6040805180820190915260008152606060208201528152602001906001900390816117595790505b50805190915060005b8181101561182057848110156117d6578581815181106117ac576117ac61208c565b60200260200101518382815181106117c6576117c661208c565b6020026020010181905250611818565b856117e2826001612304565b815181106117f2576117f261208c565b602002602001015183828151811061180c5761180c61208c565b60200260200101819052505b60010161178a565b5090949350505050565b606082518210611896576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420696e64657800000000000000000000000000000000000000604482015260640161169f565b8251600003611901576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420617272617900000000000000000000000000000000000000604482015260640161169f565b6000600184516119119190612317565b67ffffffffffffffff8111156119295761192961205d565b604051908082528060200260200182016040528015611952578160200160208202803683370190505b50805190915060005b8181101561182057848110156119cd5785818151811061197d5761197d61208c565b60200260200101518382815181106119975761199761208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152611a35565b856119d9826001612304565b815181106119e9576119e961208c565b6020026020010151838281518110611a0357611a0361208c565b7fffffffff00000000000000000000000000000000000000000000000000000000909216602092830291909101909101525b60010161195b565b81518151606091906000611a518284612304565b67ffffffffffffffff811115611a6957611a6961205d565b604051908082528060200260200182016040528015611a92578160200160208202803683370190505b50905060005b83811015611b0557868181518110611ab257611ab261208c565b6020026020010151828281518110611acc57611acc61208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152600101611a98565b5060005b82811015611b8157858181518110611b2357611b2361208c565b6020026020010151828286611b389190612304565b81518110611b4857611b4861208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152600101611b09565b5095945050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff1667ffffffffffffffff811115611bee57611bee61205d565b604051908082528060200260200182016040528015611c17578160200160208202803683370190505b50915060008060005b600284015461ffff16821015611d98576000818152600185016020526040812054905b6008811015611d835783611c568161235f565b600288015490955061ffff1685119050611d8357600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020889052604081205460601c90805b88811015611d19578a8181518110611cc457611cc461208c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611d075760019150611d19565b80611d118161235f565b915050611caa565b508015611d2857505050611d71565b818a8981518110611d3b57611d3b61208c565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015287611d6a8161235f565b9850505050505b80611d7b8161235f565b915050611c43565b50508080611d909061235f565b915050611c20565b505082525090565b8151600090815b81811015611e1e57837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916858281518110611de157611de161208c565b60200260200101517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603611e165791506101979050565b600101611da7565b509392505050565b73ffffffffffffffffffffffffffffffffffffffff81168114611e4857600080fd5b50565b600060208284031215611e5d57600080fd5b813561163081611e26565b6020808252825182820181905260009190848201906040850190845b81811015611ec25783517fffffffff000000000000000000000000000000000000000000000000000000001683529284019291840191600101611e84565b50909695505050505050565b7fffffffff0000000000000000000000000000000000000000000000000000000081168114611e4857600080fd5b600060208284031215611f0e57600080fd5b813561163081611ece565b6020808252825182820181905260009190848201906040850190845b81811015611ec257835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101611f35565b60006020808301818452808551808352604092508286019150828160051b8701018488016000805b8481101561204e578984037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00186528251805173ffffffffffffffffffffffffffffffffffffffff168552880151888501889052805188860181905290890190839060608701905b808310156120395783517fffffffff00000000000000000000000000000000000000000000000000000000168252928b019260019290920191908b0190611ff7565b50978a01979550505091870191600101611f8f565b50919998505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6040805190810167ffffffffffffffff811182821017156120de576120de61205d565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561212b5761212b61205d565b604052919050565b600067ffffffffffffffff82111561214d5761214d61205d565b5060051b60200190565b6000602080838503121561216a57600080fd5b825167ffffffffffffffff8082111561218257600080fd5b818501915085601f83011261219657600080fd5b81516121a96121a482612133565b6120e4565b81815260059190911b830184019084810190888311156121c857600080fd5b8585015b838110156122c8578051858111156121e45760008081fd5b86016040818c037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00181131561221a5760008081fd5b6122226120bb565b8983015161222f81611e26565b815282820151888111156122435760008081fd5b8084019350508c603f8401126122595760008081fd5b898301516122696121a482612133565b81815260059190911b84018301908b8101908f8311156122895760008081fd5b948401945b828610156122b357855194506122a385611ece565b848252948c0194908c019061228e565b838d01525050855250509186019186016121cc565b5098975050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610197576101976122d5565b81810381811115610197576101976122d5565b600081612339576123396122d5565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612390576123906122d5565b5060010190565b6000602082840312156123a957600080fd5b815161163081611e26565b600061ffff8083168181036123cb576123cb6122d5565b600101939250505056fea26469706673582212205959d8d85aad6f29d5fc37d5a52c404c25392cec49195c3b761da0e863e99b0f64736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "DiamondLoupe contract compatible with EIP-2535", + "kind": "dev", + "methods": { + "facetAddress(bytes4)": { + "details": "If facet is not found return address(0).", + "params": { + "_functionSelector": "The function selector." + }, + "returns": { + "facetAddress_": "The facet address." + } + }, + "facetAddressFromStorage(bytes4)": { + "params": { + "_functionSelector": "Function selector to fetch the facet address from diamond storage" + }, + "returns": { + "facetAddress_": "Facet address mapped with the function selector" + } + }, + "facetAddresses()": { + "returns": { + "facetAddresses_": "facetAddresses_" + } + }, + "facetAddressesFromStorage()": { + "returns": { + "facetAddresses_": "All facet addresses attached directly to diamond storage" + } + }, + "facetFunctionSelectors(address)": { + "params": { + "_facet": "The facet address." + }, + "returns": { + "facetFunctionSelectors_": "facetFunctionSelectors_" + } + }, + "facetFunctionSelectorsFromStorage(address)": { + "params": { + "_facet": "Facet address to fetch the facet function selectors from diamond storage" + }, + "returns": { + "facetFunctionSelectors_": "Facet function selectors of the given facet address" + } + }, + "facets()": { + "details": "Barz uses a special architecture called default fallback handler. Default Fallback handler is used as a middleware that holds the mapping of facet function selector and facet address that Barz uses. This helps Barz to reduce significant amount of gas during the initialization process. Hence, this method aggregates both the facet information from DefaulFallbackHandler and in diamond storage and shows the data to users.", + "returns": { + "facets_": "Facet" + } + }, + "facetsFromStorage()": { + "returns": { + "facets_": "Facet information attached directly to diamond storage" + } + }, + "supportsInterface(bytes4)": { + "params": { + "_interfaceId": "Interface ID for detecting the interface" + }, + "returns": { + "isSupported": "Bool value showing if the standard is supported in the contract" + } + } + }, + "title": "DiamondLoupe Facet", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "facetAddress(bytes4)": { + "notice": "Gets the facet that supports the given selector." + }, + "facetAddressFromStorage(bytes4)": { + "notice": "Returns the facet address attached to the given function selector. This excludes the facets from the default fallback handler" + }, + "facetAddresses()": { + "notice": "Get all the facet addresses used by Barz." + }, + "facetAddressesFromStorage()": { + "notice": "Returns all facet addresses attached directly to diamond storage. This excludes the facets from the default fallback handler" + }, + "facetFunctionSelectors(address)": { + "notice": "Gets all the function selectors provided by a facet." + }, + "facetFunctionSelectorsFromStorage(address)": { + "notice": "Returns function selectors of given facet address attached directly to diamond storage. This excludes the facets from the default fallback handler" + }, + "facets()": { + "notice": "Gets all facets and their selectors." + }, + "facetsFromStorage()": { + "notice": "Returns the facet from the diamond storage. This excludes the facets from the default fallback handler" + }, + "supportsInterface(bytes4)": { + "notice": "SupportInterface to be compatible with EIP 165" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/linea/Secp256k1VerificationFacet.json b/deployments/linea/Secp256k1VerificationFacet.json new file mode 100644 index 0000000..ed61789 --- /dev/null +++ b/deployments/linea/Secp256k1VerificationFacet.json @@ -0,0 +1,483 @@ +{ + "address": "0x58Cb9Abe27fcd6f72354E98Cf5cc46BEAA2182DF", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "LibAppStorage__AccountMustBeUninitialized", + "type": "error" + }, + { + "inputs": [], + "name": "LibAppStorage__SignerAlreadyUninitialized", + "type": "error" + }, + { + "inputs": [], + "name": "LibAppStorage__SignerMustBeUninitialized", + "type": "error" + }, + { + "inputs": [], + "name": "Secp256k1VerificationFacet__InvalidSignerLength", + "type": "error" + }, + { + "inputs": [], + "name": "VerificationFacet__InitializationFailure", + "type": "error" + }, + { + "inputs": [], + "name": "VerificationFacet__InvalidFacetMapping", + "type": "error" + }, + { + "inputs": [], + "name": "VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet", + "type": "error" + }, + { + "inputs": [], + "name": "VerificationFacet__ValidateOwnerSignatureSelectorNotSet", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "SignerInitialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "SignerUninitialized", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_publicKey", + "type": "bytes" + } + ], + "name": "initializeSigner", + "outputs": [ + { + "internalType": "uint256", + "name": "initSuccess", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_publicKey", + "type": "bytes" + } + ], + "name": "isValidKeyType", + "outputs": [ + { + "internalType": "bool", + "name": "isValid", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_hash", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "_signature", + "type": "bytes" + } + ], + "name": "isValidSignature", + "outputs": [ + { + "internalType": "bytes4", + "name": "magicValue", + "type": "bytes4" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "bytes", + "name": "signer", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "self", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "uninitializeSigner", + "outputs": [ + { + "internalType": "uint256", + "name": "uninitSuccess", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "initCode", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "callGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "verificationGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "preVerificationGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxFeePerGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPriorityFeePerGas", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "paymasterAndData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "internalType": "struct UserOperation", + "name": "userOp", + "type": "tuple" + }, + { + "internalType": "bytes32", + "name": "userOpHash", + "type": "bytes32" + } + ], + "name": "validateOwnerSignature", + "outputs": [ + { + "internalType": "uint256", + "name": "validationData", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "validateOwnerSignatureSelector", + "outputs": [ + { + "internalType": "bytes4", + "name": "ownerSignatureValidatorSelector", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "initCode", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "callGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "verificationGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "preVerificationGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxFeePerGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPriorityFeePerGas", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "paymasterAndData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "internalType": "struct UserOperation", + "name": "userOp", + "type": "tuple" + }, + { + "internalType": "bytes32", + "name": "userOpHash", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "signer", + "type": "address" + } + ], + "name": "validateSignature", + "outputs": [ + { + "internalType": "uint256", + "name": "isValid", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + } + ], + "transactionHash": "0x34b18a44cdb80cf29d9d6f78845ee640bc4daaf6143ba6e12691028d17428c81", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 7, + "gasUsed": "1041945", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x96202d6a32e9a14a1f55341b5fc714642fe297b4df3b97c7212e41da977cb731", + "transactionHash": "0x34b18a44cdb80cf29d9d6f78845ee640bc4daaf6143ba6e12691028d17428c81", + "logs": [], + "blockNumber": 2754007, + "cumulativeGasUsed": "1855070", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "ad34345aa73d96f52b3e14df983b6b29", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"LibAppStorage__AccountMustBeUninitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LibAppStorage__SignerAlreadyUninitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LibAppStorage__SignerMustBeUninitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Secp256k1VerificationFacet__InvalidSignerLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerificationFacet__InitializationFailure\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerificationFacet__InvalidFacetMapping\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerificationFacet__ValidateOwnerSignatureSelectorNotSet\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"SignerInitialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"SignerUninitialized\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_publicKey\",\"type\":\"bytes\"}],\"name\":\"initializeSigner\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"initSuccess\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_publicKey\",\"type\":\"bytes\"}],\"name\":\"isValidKeyType\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isValid\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_hash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"_signature\",\"type\":\"bytes\"}],\"name\":\"isValidSignature\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"magicValue\",\"type\":\"bytes4\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"signer\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"self\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"uninitializeSigner\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"uninitSuccess\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"userOp\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"}],\"name\":\"validateOwnerSignature\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"validationData\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"validateOwnerSignatureSelector\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"ownerSignatureValidatorSelector\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"userOp\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"}],\"name\":\"validateSignature\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"isValid\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)Ruslan Serebriakov (@rsrbk)\",\"details\":\"Default Ethereum's elliptic curve\",\"kind\":\"dev\",\"methods\":{\"initializeSigner(bytes)\":{\"details\":\"This method checks if the signer has already been initialized. If already initialized, it reverts. It checks if the public key is in the light format and initializes signer storage in k1 storage.\",\"params\":{\"_publicKey\":\"Bytes of owner public key\"},\"returns\":{\"initSuccess\":\"Uint value representing the success of init operation\"}},\"isValidKeyType(bytes)\":{\"details\":\"For this Secp256k1Verification Facet, the public key length should be 65 in an uncompressed public key format\",\"params\":{\"_publicKey\":\"Bytes of public key for format check\"},\"returns\":{\"isValid\":\"Boolean variable representing if the format of public key is valid\"}},\"isValidSignature(bytes32,bytes)\":{\"details\":\"This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\",\"params\":{\"_hash\":\"Hash value the owner signed\",\"_signature\":\"Signature that signed the above hash\"},\"returns\":{\"magicValue\":\"Bytes4 value representing the success/failure of validation\"}},\"owner()\":{\"returns\":{\"signer\":\"Bytes of owner address\"}},\"uninitializeSigner()\":{\"details\":\"This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\",\"returns\":{\"uninitSuccess\":\"Uint value representing the success of uninit operation\"}},\"validateOwnerSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32)\":{\"details\":\"This method validates if the user operation is signed by the owner. It internally calls validateSignature with signer public key.\",\"params\":{\"userOp\":\"UserOperation including all information for execution\",\"userOpHash\":\"Hash of UserOperation given from EntryPoint. This hash is used for signature validation\"},\"returns\":{\"validationData\":\"Uint value representing whether the validation is successful. 0 for success, 1 for failure\"}},\"validateOwnerSignatureSelector()\":{\"returns\":{\"ownerSignatureValidatorSelector\":\"Bytes4 selector of function signature to validate account owner's UserOperation signature\"}},\"validateSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,address)\":{\"details\":\"This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\",\"params\":{\"signer\":\"Address of signer who signed the contract, to be validated\",\"userOp\":\"UserOperation including all information for execution\",\"userOpHash\":\"Hash of UserOperation given from EntryPoint. This hash is used for signature validation\"},\"returns\":{\"isValid\":\"Uint value representing whether the validation is successful. 0 for success, 1 for failure\"}}},\"title\":\"Secp256k1 verification facet\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"This constructor ensures that this contract can only be used as singleton for Proxy contracts\"},\"initializeSigner(bytes)\":{\"notice\":\"Initializes the signer in K1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\"},\"isValidKeyType(bytes)\":{\"notice\":\"Validates if the format of public key is valid for this verification facet\"},\"isValidSignature(bytes32,bytes)\":{\"notice\":\"Validates if the signature is valid. Function to be compatible with EIP-1271\"},\"owner()\":{\"notice\":\"Returns the owner of the account\"},\"uninitializeSigner()\":{\"notice\":\"Uninitialize signer in K1 Facet Storage. This can only be called when the account is undergoing signature migration and has already been initialized.\"},\"validateOwnerSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32)\":{\"notice\":\"Validates if the user operation is signed by the owner.\"},\"validateOwnerSignatureSelector()\":{\"notice\":\"Returns the selector of function to validate the signature of UserOperation\"},\"validateSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,address)\":{\"notice\":\"Validates if the signature of UserOperation is signed by the given signer\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/verification/secp256k1/Secp256k1VerificationFacet.sol\":\"Secp256k1VerificationFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./math/Math.sol\\\";\\nimport \\\"./math/SignedMath.sol\\\";\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n uint256 length = Math.log10(value) + 1;\\n string memory buffer = new string(length);\\n uint256 ptr;\\n /// @solidity memory-safe-assembly\\n assembly {\\n ptr := add(buffer, add(32, length))\\n }\\n while (true) {\\n ptr--;\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\\n }\\n value /= 10;\\n if (value == 0) break;\\n }\\n return buffer;\\n }\\n }\\n\\n /**\\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\\n */\\n function toString(int256 value) internal pure returns (string memory) {\\n return string(abi.encodePacked(value < 0 ? \\\"-\\\" : \\\"\\\", toString(SignedMath.abs(value))));\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n return toHexString(value, Math.log256(value) + 1);\\n }\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n\\n /**\\n * @dev Returns true if the two strings are equal.\\n */\\n function equal(string memory a, string memory b) internal pure returns (bool) {\\n return keccak256(bytes(a)) == keccak256(bytes(b));\\n }\\n}\\n\",\"keccak256\":\"0x3088eb2868e8d13d89d16670b5f8612c4ab9ff8956272837d8e90106c59c14a0\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Strings.sol\\\";\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSA {\\n enum RecoverError {\\n NoError,\\n InvalidSignature,\\n InvalidSignatureLength,\\n InvalidSignatureS,\\n InvalidSignatureV // Deprecated in v4.8\\n }\\n\\n function _throwError(RecoverError error) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert(\\\"ECDSA: invalid signature\\\");\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert(\\\"ECDSA: invalid signature length\\\");\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert(\\\"ECDSA: invalid signature 's' value\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature` or error string. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n *\\n * Documentation for signature generation:\\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n return tryRecover(hash, v, r, s);\\n } else {\\n return (address(0), RecoverError.InvalidSignatureLength);\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature`. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, signature);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\\n uint8 v = uint8((uint256(vs) >> 255) + 27);\\n return tryRecover(hash, v, r, s);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n *\\n * _Available since v4.2._\\n */\\n function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\\n // the valid range for s in (301): 0 < s < secp256k1n \\u00f7 2 + 1, and for v in (302): v \\u2208 {27, 28}. Most\\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\\n //\\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\\n // these malleable signatures as well.\\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n return (address(0), RecoverError.InvalidSignatureS);\\n }\\n\\n // If the signature is valid (and not malleable), return the signer address\\n address signer = ecrecover(hash, v, r, s);\\n if (signer == address(0)) {\\n return (address(0), RecoverError.InvalidSignature);\\n }\\n\\n return (signer, RecoverError.NoError);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore(0x00, \\\"\\\\x19Ethereum Signed Message:\\\\n32\\\")\\n mstore(0x1c, hash)\\n message := keccak256(0x00, 0x3c)\\n }\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from `s`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n\\\", Strings.toString(s.length), s));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Typed Data, created from a\\n * `domainSeparator` and a `structHash`. This produces hash corresponding\\n * to the one signed with the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n * JSON-RPC method as part of EIP-712.\\n *\\n * See {recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n let ptr := mload(0x40)\\n mstore(ptr, \\\"\\\\x19\\\\x01\\\")\\n mstore(add(ptr, 0x02), domainSeparator)\\n mstore(add(ptr, 0x22), structHash)\\n data := keccak256(ptr, 0x42)\\n }\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Data with intended validator, created from a\\n * `validator` and `data` according to the version 0 of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x00\\\", validator, data));\\n }\\n}\\n\",\"keccak256\":\"0x809bc3edb4bcbef8263fa616c1b60ee0004b50a8a1bfa164d8f57fd31f520c58\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n enum Rounding {\\n Down, // Toward negative infinity\\n Up, // Toward infinity\\n Zero // Toward zero\\n }\\n\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow.\\n return (a & b) + (a ^ b) / 2;\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a == 0 ? 0 : (a - 1) / b + 1;\\n }\\n\\n /**\\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\\n * with further edits by Uniswap Labs also under MIT license.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\\n unchecked {\\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2^256 + prod0.\\n uint256 prod0; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division.\\n if (prod1 == 0) {\\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\\n // The surrounding unchecked block does not change this fact.\\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\\n return prod0 / denominator;\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n require(denominator > prod1, \\\"Math: mulDiv overflow\\\");\\n\\n ///////////////////////////////////////////////\\n // 512 by 256 division.\\n ///////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0].\\n uint256 remainder;\\n assembly {\\n // Compute remainder using mulmod.\\n remainder := mulmod(x, y, denominator)\\n\\n // Subtract 256 bit number from 512 bit number.\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\\n // See https://cs.stackexchange.com/q/138556/92363.\\n\\n // Does not overflow because the denominator cannot be zero at this stage in the function.\\n uint256 twos = denominator & (~denominator + 1);\\n assembly {\\n // Divide denominator by twos.\\n denominator := div(denominator, twos)\\n\\n // Divide [prod1 prod0] by twos.\\n prod0 := div(prod0, twos)\\n\\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\\n twos := add(div(sub(0, twos), twos), 1)\\n }\\n\\n // Shift in bits from prod1 into prod0.\\n prod0 |= prod1 * twos;\\n\\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\\n // four bits. That is, denominator * inv = 1 mod 2^4.\\n uint256 inverse = (3 * denominator) ^ 2;\\n\\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\\n // in modular arithmetic, doubling the correct bits in each step.\\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\\n\\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inverse;\\n return result;\\n }\\n }\\n\\n /**\\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\\n uint256 result = mulDiv(x, y, denominator);\\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\\n result += 1;\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\\n *\\n * Inspired by Henry S. Warren, Jr.'s \\\"Hacker's Delight\\\" (Chapter 11).\\n */\\n function sqrt(uint256 a) internal pure returns (uint256) {\\n if (a == 0) {\\n return 0;\\n }\\n\\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\\n //\\n // We know that the \\\"msb\\\" (most significant bit) of our target number `a` is a power of 2 such that we have\\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\\n //\\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\\n // \\u2192 `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\\n // \\u2192 `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\\n //\\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\\n uint256 result = 1 << (log2(a) >> 1);\\n\\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\\n // into the expected uint128 result.\\n unchecked {\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n return min(result, a / result);\\n }\\n }\\n\\n /**\\n * @notice Calculates sqrt(a), following the selected rounding direction.\\n */\\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = sqrt(a);\\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 2, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 128;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 64;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 32;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 16;\\n }\\n if (value >> 8 > 0) {\\n value >>= 8;\\n result += 8;\\n }\\n if (value >> 4 > 0) {\\n value >>= 4;\\n result += 4;\\n }\\n if (value >> 2 > 0) {\\n value >>= 2;\\n result += 2;\\n }\\n if (value >> 1 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log2(value);\\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 10, rounded down, of a positive value.\\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 + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 256, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n *\\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\\n */\\n function log256(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 16;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 8;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 4;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 2;\\n }\\n if (value >> 8 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log256(value);\\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe4455ac1eb7fc497bb7402579e7b4d64d928b846fce7d2b6fde06d366f21c2b3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\\n * checks.\\n *\\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\\n * easily result in undesired exploitation or bugs, since developers usually\\n * assume that overflows raise errors. `SafeCast` restores this intuition by\\n * reverting the transaction when such an operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n *\\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\\n * all math on `uint256` and `int256` and then downcasting.\\n */\\nlibrary SafeCast {\\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 * _Available since v4.7._\\n */\\n function toUint248(uint256 value) internal pure returns (uint248) {\\n require(value <= type(uint248).max, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint240(uint256 value) internal pure returns (uint240) {\\n require(value <= type(uint240).max, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint232(uint256 value) internal pure returns (uint232) {\\n require(value <= type(uint232).max, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint224(uint256 value) internal pure returns (uint224) {\\n require(value <= type(uint224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint216(uint256 value) internal pure returns (uint216) {\\n require(value <= type(uint216).max, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint208(uint256 value) internal pure returns (uint208) {\\n require(value <= type(uint208).max, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint200(uint256 value) internal pure returns (uint200) {\\n require(value <= type(uint200).max, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint192(uint256 value) internal pure returns (uint192) {\\n require(value <= type(uint192).max, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint184(uint256 value) internal pure returns (uint184) {\\n require(value <= type(uint184).max, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint176(uint256 value) internal pure returns (uint176) {\\n require(value <= type(uint176).max, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint168(uint256 value) internal pure returns (uint168) {\\n require(value <= type(uint168).max, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint160(uint256 value) internal pure returns (uint160) {\\n require(value <= type(uint160).max, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint152(uint256 value) internal pure returns (uint152) {\\n require(value <= type(uint152).max, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint144(uint256 value) internal pure returns (uint144) {\\n require(value <= type(uint144).max, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint136(uint256 value) internal pure returns (uint136) {\\n require(value <= type(uint136).max, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint128(uint256 value) internal pure returns (uint128) {\\n require(value <= type(uint128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint120(uint256 value) internal pure returns (uint120) {\\n require(value <= type(uint120).max, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint112(uint256 value) internal pure returns (uint112) {\\n require(value <= type(uint112).max, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint104(uint256 value) internal pure returns (uint104) {\\n require(value <= type(uint104).max, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint96(uint256 value) internal pure returns (uint96) {\\n require(value <= type(uint96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint88(uint256 value) internal pure returns (uint88) {\\n require(value <= type(uint88).max, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint80(uint256 value) internal pure returns (uint80) {\\n require(value <= type(uint80).max, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint72(uint256 value) internal pure returns (uint72) {\\n require(value <= type(uint72).max, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint64(uint256 value) internal pure returns (uint64) {\\n require(value <= type(uint64).max, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint56(uint256 value) internal pure returns (uint56) {\\n require(value <= type(uint56).max, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint48(uint256 value) internal pure returns (uint48) {\\n require(value <= type(uint48).max, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint40(uint256 value) internal pure returns (uint40) {\\n require(value <= type(uint40).max, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint32(uint256 value) internal pure returns (uint32) {\\n require(value <= type(uint32).max, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint24(uint256 value) internal pure returns (uint24) {\\n require(value <= type(uint24).max, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint16(uint256 value) internal pure returns (uint16) {\\n require(value <= type(uint16).max, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint8(uint256 value) internal pure returns (uint8) {\\n require(value <= type(uint8).max, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\n */\\n function toUint256(int256 value) internal pure returns (uint256) {\\n require(value >= 0, \\\"SafeCast: value must be positive\\\");\\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 * _Available since v4.7._\\n */\\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\\n downcasted = int248(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\\n downcasted = int240(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\\n downcasted = int232(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\\n downcasted = int224(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\\n downcasted = int216(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\\n downcasted = int208(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\\n downcasted = int200(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\\n downcasted = int192(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\\n downcasted = int184(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\\n downcasted = int176(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\\n downcasted = int168(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\\n downcasted = int160(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\\n downcasted = int152(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\\n downcasted = int144(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\\n downcasted = int136(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\\n downcasted = int128(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\\n downcasted = int120(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\\n downcasted = int112(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\\n downcasted = int104(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\\n downcasted = int96(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\\n downcasted = int88(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\\n downcasted = int80(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\\n downcasted = int72(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\\n downcasted = int64(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\\n downcasted = int56(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\\n downcasted = int48(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\\n downcasted = int40(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\\n downcasted = int32(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\\n downcasted = int24(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\\n downcasted = int16(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\\n downcasted = int8(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\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 require(value <= uint256(type(int256).max), \\\"SafeCast: value doesn't fit in an int256\\\");\\n return int256(value);\\n }\\n}\\n\",\"keccak256\":\"0x52a8cfb0f5239d11b457dcdd1b326992ef672714ca8da71a157255bddd13f3ad\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SignedMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard signed math utilities missing in the Solidity language.\\n */\\nlibrary SignedMath {\\n /**\\n * @dev Returns the largest of two signed numbers.\\n */\\n function max(int256 a, int256 b) internal pure returns (int256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two signed numbers.\\n */\\n function min(int256 a, int256 b) internal pure returns (int256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two signed numbers without overflow.\\n * The result is rounded towards zero.\\n */\\n function average(int256 a, int256 b) internal pure returns (int256) {\\n // Formula from the book \\\"Hacker's Delight\\\"\\n int256 x = (a & b) + ((a ^ b) >> 1);\\n return x + (int256(uint256(x) >> 255) & (a ^ b));\\n }\\n\\n /**\\n * @dev Returns the absolute unsigned value of a signed value.\\n */\\n function abs(int256 n) internal pure returns (uint256) {\\n unchecked {\\n // must be unchecked in order to support `n = type(int256).min`\\n return uint256(n >= 0 ? n : -n);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf92515413956f529d95977adc9b0567d583c6203fc31ab1c23824c35187e3ddc\",\"license\":\"MIT\"},\"contracts/aa-4337/core/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable no-inline-assembly */\\n\\n/**\\n * returned data from validateUserOp.\\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\\n * @param aggregator - address(0) - the account validated the signature by itself.\\n * address(1) - the account failed to validate the signature.\\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\\n * @param validAfter - this UserOp is valid only after this timestamp.\\n * @param validaUntil - this UserOp is valid only up to this timestamp.\\n */\\nstruct ValidationData {\\n address aggregator;\\n uint48 validAfter;\\n uint48 validUntil;\\n}\\n\\n//extract sigFailed, validAfter, validUntil.\\n// also convert zero validUntil to type(uint48).max\\nfunction _parseValidationData(\\n uint validationData\\n) pure returns (ValidationData memory data) {\\n address aggregator = address(uint160(validationData));\\n uint48 validUntil = uint48(validationData >> 160);\\n if (validUntil == 0) {\\n validUntil = type(uint48).max;\\n }\\n uint48 validAfter = uint48(validationData >> (48 + 160));\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n// intersect account and paymaster ranges.\\nfunction _intersectTimeRange(\\n uint256 validationData,\\n uint256 paymasterValidationData\\n) pure returns (ValidationData memory) {\\n ValidationData memory accountValidationData = _parseValidationData(\\n validationData\\n );\\n ValidationData memory pmValidationData = _parseValidationData(\\n paymasterValidationData\\n );\\n address aggregator = accountValidationData.aggregator;\\n if (aggregator == address(0)) {\\n aggregator = pmValidationData.aggregator;\\n }\\n uint48 validAfter = accountValidationData.validAfter;\\n uint48 validUntil = accountValidationData.validUntil;\\n uint48 pmValidAfter = pmValidationData.validAfter;\\n uint48 pmValidUntil = pmValidationData.validUntil;\\n\\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp\\n * @param data - the ValidationData to pack\\n */\\nfunction _packValidationData(\\n ValidationData memory data\\n) pure returns (uint256) {\\n return\\n uint160(data.aggregator) |\\n (uint256(data.validUntil) << 160) |\\n (uint256(data.validAfter) << (160 + 48));\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp, when not using an aggregator\\n * @param sigFailed - true for signature failure, false for success\\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\\n * @param validAfter first timestamp this UserOperation is valid\\n */\\nfunction _packValidationData(\\n bool sigFailed,\\n uint48 validUntil,\\n uint48 validAfter\\n) pure returns (uint256) {\\n return\\n (sigFailed ? 1 : 0) |\\n (uint256(validUntil) << 160) |\\n (uint256(validAfter) << (160 + 48));\\n}\\n\\n/**\\n * keccak function over calldata.\\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\\n */\\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\\n assembly {\\n let mem := mload(0x40)\\n let len := data.length\\n calldatacopy(mem, data.offset, len)\\n ret := keccak256(mem, len)\\n }\\n}\\n\",\"keccak256\":\"0xa79f06cd158ecb8c0da95493a2f348933b8627a63e228b99738bff3aa107942d\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAggregator.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\n/**\\n * Aggregated Signatures validator.\\n */\\ninterface IAggregator {\\n /**\\n * validate aggregated signature.\\n * revert if the aggregated signature does not match the given list of operations.\\n */\\n function validateSignatures(\\n UserOperation[] calldata userOps,\\n bytes calldata signature\\n ) external view;\\n\\n /**\\n * validate signature of a single userOp\\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\\n * @param userOp the userOperation received from the user.\\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\\n * (usually empty, unless account and aggregator support some kind of \\\"multisig\\\"\\n */\\n function validateUserOpSignature(\\n UserOperation calldata userOp\\n ) external view returns (bytes memory sigForUserOp);\\n\\n /**\\n * aggregate multiple signatures into a single value.\\n * This method is called off-chain to calculate the signature to pass with handleOps()\\n * bundler MAY use optimized custom code perform this aggregation\\n * @param userOps array of UserOperations to collect the signatures from.\\n * @return aggregatedSignature the aggregated signature\\n */\\n function aggregateSignatures(\\n UserOperation[] calldata userOps\\n ) external view returns (bytes memory aggregatedSignature);\\n}\\n\",\"keccak256\":\"0xdfdcd80568f037716674619b31be630fcd8316262f05a815b41d1e81782c966a\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IEntryPoint.sol\":{\"content\":\"/**\\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\\n ** Only one instance required on each chain.\\n **/\\n// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-inline-assembly */\\n/* solhint-disable reason-string */\\n\\nimport \\\"./UserOperation.sol\\\";\\nimport \\\"./IStakeManager.sol\\\";\\nimport \\\"./IAggregator.sol\\\";\\nimport \\\"./INonceManager.sol\\\";\\n\\ninterface IEntryPoint is IStakeManager, INonceManager {\\n /***\\n * An event emitted after each successful request\\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\\n * @param sender - the account that generates this request.\\n * @param paymaster - if non-null, the paymaster that pays for this request.\\n * @param nonce - the nonce value from the request.\\n * @param success - true if the sender transaction succeeded, false if reverted.\\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\\n */\\n event UserOperationEvent(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address indexed paymaster,\\n uint256 nonce,\\n bool success,\\n uint256 actualGasCost,\\n uint256 actualGasUsed\\n );\\n\\n /**\\n * account \\\"sender\\\" was deployed.\\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\\n * @param sender the account that is deployed\\n * @param factory the factory used to deploy this account (in the initCode)\\n * @param paymaster the paymaster used by this UserOp\\n */\\n event AccountDeployed(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address factory,\\n address paymaster\\n );\\n\\n /**\\n * An event emitted if the UserOperation \\\"callData\\\" reverted with non-zero length\\n * @param userOpHash the request unique identifier.\\n * @param sender the sender of this request\\n * @param nonce the nonce used in the request\\n * @param revertReason - the return bytes from the (reverted) call to \\\"callData\\\".\\n */\\n event UserOperationRevertReason(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n uint256 nonce,\\n bytes revertReason\\n );\\n\\n /**\\n * an event emitted by handleOps(), before starting the execution loop.\\n * any event emitted before this event, is part of the validation.\\n */\\n event BeforeExecution();\\n\\n /**\\n * signature aggregator used by the following UserOperationEvents within this bundle.\\n */\\n event SignatureAggregatorChanged(address indexed aggregator);\\n\\n /**\\n * a custom revert error of handleOps, to identify the offending op.\\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\\n * @param reason - revert reason\\n * The string starts with a unique code \\\"AAmn\\\", where \\\"m\\\" is \\\"1\\\" for factory, \\\"2\\\" for account and \\\"3\\\" for paymaster issues,\\n * so a failure can be attributed to the correct entity.\\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\\n */\\n error FailedOp(uint256 opIndex, string reason);\\n\\n /**\\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\\n */\\n error SignatureValidationFailed(address aggregator);\\n\\n /**\\n * Successful result from simulateValidation.\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n */\\n error ValidationResult(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo\\n );\\n\\n /**\\n * Successful result from simulateValidation, if the account returns a signature aggregator\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\\n * bundler MUST use it to verify the signature, or reject the UserOperation\\n */\\n error ValidationResultWithAggregation(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo,\\n AggregatorStakeInfo aggregatorInfo\\n );\\n\\n /**\\n * return value of getSenderAddress\\n */\\n error SenderAddressResult(address sender);\\n\\n /**\\n * return value of simulateHandleOp\\n */\\n error ExecutionResult(\\n uint256 preOpGas,\\n uint256 paid,\\n uint48 validAfter,\\n uint48 validUntil,\\n bool targetSuccess,\\n bytes targetResult\\n );\\n\\n //UserOps handled, per aggregator\\n struct UserOpsPerAggregator {\\n UserOperation[] userOps;\\n // aggregator address\\n IAggregator aggregator;\\n // aggregated signature\\n bytes signature;\\n }\\n\\n /**\\n * Execute a batch of UserOperation.\\n * no signature aggregator is used.\\n * if any account requires an aggregator (that is, it returned an aggregator when\\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\\n * @param ops the operations to execute\\n * @param beneficiary the address to receive the fees\\n */\\n function handleOps(\\n UserOperation[] calldata ops,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * Execute a batch of UserOperation with Aggregators\\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\\n * @param beneficiary the address to receive the fees\\n */\\n function handleAggregatedOps(\\n UserOpsPerAggregator[] calldata opsPerAggregator,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * generate a request Id - unique identifier for this request.\\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\\n */\\n function getUserOpHash(\\n UserOperation calldata userOp\\n ) external view returns (bytes32);\\n\\n /**\\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\\n * @param userOp the user operation to validate.\\n */\\n function simulateValidation(UserOperation calldata userOp) external;\\n\\n /**\\n * gas and return values during simulation\\n * @param preOpGas the gas used for validation (including preValidationGas)\\n * @param prefund the required prefund for this operation\\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\\n */\\n struct ReturnInfo {\\n uint256 preOpGas;\\n uint256 prefund;\\n bool sigFailed;\\n uint48 validAfter;\\n uint48 validUntil;\\n bytes paymasterContext;\\n }\\n\\n /**\\n * returned aggregated signature info.\\n * the aggregator returned by the account, and its current stake.\\n */\\n struct AggregatorStakeInfo {\\n address aggregator;\\n StakeInfo stakeInfo;\\n }\\n\\n /**\\n * Get counterfactual sender address.\\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\\n * this method always revert, and returns the address in SenderAddressResult error\\n * @param initCode the constructor code to be passed into the UserOperation.\\n */\\n function getSenderAddress(bytes memory initCode) external;\\n\\n /**\\n * simulate full execution of a UserOperation (including both validation and target execution)\\n * this method will always revert with \\\"ExecutionResult\\\".\\n * it performs full validation of the UserOperation, but ignores signature error.\\n * an optional target address is called after the userop succeeds, and its value is returned\\n * (before the entire call is reverted)\\n * Note that in order to collect the the success/failure of the target call, it must be executed\\n * with trace enabled to track the emitted events.\\n * @param op the UserOperation to simulate\\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\\n * are set to the return from that call.\\n * @param targetCallData callData to pass to target address\\n */\\n function simulateHandleOp(\\n UserOperation calldata op,\\n address target,\\n bytes calldata targetCallData\\n ) external;\\n}\\n\",\"keccak256\":\"0x9ccb1b188eda8bbf5f6c2d01bd83c3d8b2b04fcf745283051d31fe96d1d8e40f\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/INonceManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\ninterface INonceManager {\\n /**\\n * Return the next nonce for this sender.\\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\\n * But UserOp with different keys can come with arbitrary order.\\n *\\n * @param sender the account address\\n * @param key the high 192 bit of the nonce\\n * @return nonce a full nonce to pass for next UserOp with this sender.\\n */\\n function getNonce(\\n address sender,\\n uint192 key\\n ) external view returns (uint256 nonce);\\n\\n /**\\n * Manually increment the nonce of the sender.\\n * This method is exposed just for completeness..\\n * Account does NOT need to call it, neither during validation, nor elsewhere,\\n * as the EntryPoint will update the nonce regardless.\\n * Possible use-case is call it with various keys to \\\"initialize\\\" their nonces to one, so that future\\n * UserOperations will not pay extra for the first transaction with a given key.\\n */\\n function incrementNonce(uint192 key) external;\\n}\\n\",\"keccak256\":\"0xce478ad0fa0d18a3b785ac854623029e7ab463d05873dfaa365abfa1bf100912\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IStakeManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8.12;\\n\\n/**\\n * manage deposits and stakes.\\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\\n * stake is value locked for at least \\\"unstakeDelay\\\" by the staked entity.\\n */\\ninterface IStakeManager {\\n event Deposited(address indexed account, uint256 totalDeposit);\\n\\n event Withdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /// Emitted when stake or unstake delay are modified\\n event StakeLocked(\\n address indexed account,\\n uint256 totalStaked,\\n uint256 unstakeDelaySec\\n );\\n\\n /// Emitted once a stake is scheduled for withdrawal\\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\\n\\n event StakeWithdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /**\\n * @param deposit the entity's deposit\\n * @param staked true if this entity is staked.\\n * @param stake actual amount of ether staked for this entity.\\n * @param unstakeDelaySec minimum delay to withdraw the stake.\\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\\n * and the rest fit into a 2nd cell.\\n * 112 bit allows for 10^15 eth\\n * 48 bit for full timestamp\\n * 32 bit allows 150 years for unstake delay\\n */\\n struct DepositInfo {\\n uint112 deposit;\\n bool staked;\\n uint112 stake;\\n uint32 unstakeDelaySec;\\n uint48 withdrawTime;\\n }\\n\\n //API struct used by getStakeInfo and simulateValidation\\n struct StakeInfo {\\n uint256 stake;\\n uint256 unstakeDelaySec;\\n }\\n\\n /// @return info - full deposit information of given account\\n function getDepositInfo(\\n address account\\n ) external view returns (DepositInfo memory info);\\n\\n /// @return the deposit (for gas payment) of the account\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * add to the deposit of the given account\\n */\\n function depositTo(address account) external payable;\\n\\n /**\\n * add to the account's stake - amount and delay\\n * any pending unstake is first cancelled.\\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\\n */\\n function addStake(uint32 _unstakeDelaySec) external payable;\\n\\n /**\\n * attempt to unlock the stake.\\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\\n */\\n function unlockStake() external;\\n\\n /**\\n * withdraw from the (unlocked) stake.\\n * must first call unlockStake and wait for the unstakeDelay to pass\\n * @param withdrawAddress the address to send withdrawn value.\\n */\\n function withdrawStake(address payable withdrawAddress) external;\\n\\n /**\\n * withdraw from the deposit.\\n * @param withdrawAddress the address to send withdrawn value.\\n * @param withdrawAmount the amount to withdraw.\\n */\\n function withdrawTo(\\n address payable withdrawAddress,\\n uint256 withdrawAmount\\n ) external;\\n}\\n\",\"keccak256\":\"0xadcea606c9b7aafe6645441f2154a60f271330b0eee5292a632aa71c1672d546\",\"license\":\"GPL-3.0-only\"},\"contracts/aa-4337/interfaces/UserOperation.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable no-inline-assembly */\\n\\nimport {calldataKeccak} from \\\"../core/Helpers.sol\\\";\\n\\n/**\\n * User Operation struct\\n * @param sender the sender account of this request.\\n * @param nonce unique value the sender uses to verify it is not a replay.\\n * @param initCode if set, the account contract will be created by this constructor/\\n * @param callData the method call to execute on this account.\\n * @param callGasLimit the gas limit passed to the callData method call.\\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\\n * @param maxFeePerGas same as EIP-1559 gas parameter.\\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\\n */\\nstruct UserOperation {\\n address sender;\\n uint256 nonce;\\n bytes initCode;\\n bytes callData;\\n uint256 callGasLimit;\\n uint256 verificationGasLimit;\\n uint256 preVerificationGas;\\n uint256 maxFeePerGas;\\n uint256 maxPriorityFeePerGas;\\n bytes paymasterAndData;\\n bytes signature;\\n}\\n\\n/**\\n * Utility functions helpful when working with UserOperation structs.\\n */\\nlibrary UserOperationLib {\\n function getSender(\\n UserOperation calldata userOp\\n ) internal pure returns (address) {\\n address data;\\n //read sender from userOp, which is first userOp member (saves 800 gas...)\\n assembly {\\n data := calldataload(userOp)\\n }\\n return address(uint160(data));\\n }\\n\\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\\n // pay above what he signed for.\\n function gasPrice(\\n UserOperation calldata userOp\\n ) internal view returns (uint256) {\\n unchecked {\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n if (maxFeePerGas == maxPriorityFeePerGas) {\\n //legacy mode (for networks that don't support basefee opcode)\\n return maxFeePerGas;\\n }\\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\\n }\\n }\\n\\n function pack(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes memory ret) {\\n address sender = getSender(userOp);\\n uint256 nonce = userOp.nonce;\\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\\n bytes32 hashCallData = calldataKeccak(userOp.callData);\\n uint256 callGasLimit = userOp.callGasLimit;\\n uint256 verificationGasLimit = userOp.verificationGasLimit;\\n uint256 preVerificationGas = userOp.preVerificationGas;\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\\n\\n return\\n abi.encode(\\n sender,\\n nonce,\\n hashInitCode,\\n hashCallData,\\n callGasLimit,\\n verificationGasLimit,\\n preVerificationGas,\\n maxFeePerGas,\\n maxPriorityFeePerGas,\\n hashPaymasterAndData\\n );\\n }\\n\\n function hash(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes32) {\\n return keccak256(pack(userOp));\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n}\\n\",\"keccak256\":\"0x2429f5cc546bdee08c7e63858d0dda8491eaa3ab5194df884dc948c1154d2834\",\"license\":\"GPL-3.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/facets/interfaces/IVerificationFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {UserOperation} from \\\"../../aa-4337/interfaces/UserOperation.sol\\\";\\n\\n/**\\n * @title Verification Facet Interface\\n * @dev Implements logic for user ops signature verification\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\ninterface IVerificationFacet {\\n event SignerInitialized(bytes);\\n event SignerUninitialized();\\n\\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\\n error VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\\n error VerificationFacet__InitializationFailure();\\n error VerificationFacet__InvalidFacetMapping();\\n\\n function initializeSigner(bytes memory) external returns (uint256);\\n\\n function uninitializeSigner() external returns (uint256);\\n\\n function validateOwnerSignatureSelector() external view returns (bytes4);\\n\\n function owner() external view returns (bytes memory);\\n\\n function isValidKeyType(bytes calldata) external view returns (bool);\\n\\n function validateOwnerSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x72bc370a1d1b5a6d6bde67f5026733fd8f6ba434bb90e73b0bd8627fb1579928\",\"license\":\"Apache-2.0\"},\"contracts/facets/verification/secp256k1/Secp256k1VerificationFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {ECDSA} from \\\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\\\";\\nimport {UserOperation} from \\\"../../../aa-4337/interfaces/UserOperation.sol\\\";\\nimport {LibAppStorage} from \\\"../../../libraries/LibAppStorage.sol\\\";\\nimport {LibFacetStorage, Secp256k1VerificationStorage} from \\\"../../../libraries/LibFacetStorage.sol\\\";\\nimport {LibLoupe} from \\\"../../../libraries/LibLoupe.sol\\\";\\nimport {IERC1271} from \\\"../../../interfaces/ERC/IERC1271.sol\\\";\\nimport {IVerificationFacet} from \\\"../../interfaces/IVerificationFacet.sol\\\";\\n\\n/**\\n * @title Secp256k1 verification facet\\n * @dev Default Ethereum's elliptic curve\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\ncontract Secp256k1VerificationFacet is IVerificationFacet, IERC1271 {\\n using ECDSA for bytes32;\\n error Secp256k1VerificationFacet__InvalidSignerLength();\\n address public immutable self;\\n\\n /**\\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\\n */\\n constructor() {\\n LibAppStorage.enforceSignerInitialize();\\n self = address(this);\\n }\\n\\n /**\\n * @notice Initializes the signer in K1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\\n * @param _publicKey Bytes of owner public key\\n * @return initSuccess Uint value representing the success of init operation\\n */\\n function initializeSigner(\\n bytes calldata _publicKey\\n ) public override returns (uint256 initSuccess) {\\n LibAppStorage.enforceSignerInitialize();\\n if (!isValidKeyType(_publicKey))\\n revert Secp256k1VerificationFacet__InvalidSignerLength();\\n\\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\\n .k1Storage();\\n k1Storage.signer = address(uint160(uint256(keccak256(_publicKey[1:]))));\\n\\n bytes4 validateSelector = validateOwnerSignatureSelector();\\n\\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\\n if (LibLoupe.facetAddress(validateSelector) != self)\\n revert VerificationFacet__InvalidFacetMapping();\\n\\n // initialize verification function selector\\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\\n\\n initSuccess = 1;\\n\\n emit SignerInitialized(_publicKey);\\n }\\n\\n /**\\n * @notice Uninitialize signer in K1 Facet Storage. This can only be called when the account is undergoing signature migration\\n * and has already been initialized.\\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\\n * @return uninitSuccess Uint value representing the success of uninit operation\\n */\\n function uninitializeSigner()\\n external\\n override\\n returns (uint256 uninitSuccess)\\n {\\n LibAppStorage.enforceSignerMigration();\\n LibAppStorage.setSignerUninitialized();\\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\\n .k1Storage();\\n k1Storage.signer = address(0);\\n\\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\\n\\n uninitSuccess = 1;\\n\\n emit SignerUninitialized();\\n }\\n\\n /**\\n * @notice Validates if the user operation is signed by the owner.\\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\\n * signer public key.\\n * @param userOp UserOperation including all information for execution\\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\\n */\\n function validateOwnerSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) public view override returns (uint256 validationData) {\\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\\n .k1Storage();\\n validationData = validateSignature(\\n userOp,\\n userOpHash,\\n k1Storage.signer\\n );\\n }\\n\\n /**\\n * @notice Validates if the signature of UserOperation is signed by the given signer\\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\\n * @param userOp UserOperation including all information for execution\\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\\n * @param signer Address of signer who signed the contract, to be validated\\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\\n */\\n function validateSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n address signer\\n ) public pure returns (uint256 isValid) {\\n bytes32 hash = userOpHash.toEthSignedMessageHash();\\n isValid = (signer != hash.recover(userOp.signature)) ? 1 : 0;\\n }\\n\\n /**\\n * @notice Returns the selector of function to validate the signature of UserOperation\\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\\n */\\n function validateOwnerSignatureSelector()\\n public\\n pure\\n override\\n returns (bytes4 ownerSignatureValidatorSelector)\\n {\\n ownerSignatureValidatorSelector = this.validateOwnerSignature.selector;\\n // NOTE: The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\\n }\\n\\n /**\\n * @notice Returns the owner of the account\\n * @return signer Bytes of owner address\\n */\\n function owner() public view override returns (bytes memory signer) {\\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\\n .k1Storage();\\n signer = abi.encodePacked(k1Storage.signer);\\n }\\n\\n /**\\n * @notice Validates if the format of public key is valid for this verification facet\\n * @dev For this Secp256k1Verification Facet, the public key length should be 65 in an uncompressed public key format\\n * @param _publicKey Bytes of public key for format check\\n * @return isValid Boolean variable representing if the format of public key is valid\\n */\\n function isValidKeyType(\\n bytes memory _publicKey\\n ) public pure override returns (bool isValid) {\\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\\n }\\n\\n /**\\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\\n * @param _hash Hash value the owner signed\\n * @param _signature Signature that signed the above hash\\n * @return magicValue Bytes4 value representing the success/failure of validation\\n */\\n function isValidSignature(\\n bytes32 _hash,\\n bytes memory _signature\\n ) public view override returns (bytes4 magicValue) {\\n magicValue = (_hash.recover(_signature) ==\\n LibFacetStorage.k1Storage().signer)\\n ? this.isValidSignature.selector\\n : bytes4(0xffffffff);\\n }\\n}\\n\",\"keccak256\":\"0x293ca694d0bad996df8b6d83a4bfdc4e5c3b3bc2e3f19e046c280e0233dbd806\",\"license\":\"Apache-2.0\"},\"contracts/infrastructure/interfaces/IFacetRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Registry Interface\\n * @dev Interface for Facet Registry contract to keep track of facets & function selectors addable to user wallets\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IFacetRegistry {\\n struct FacetRegistryConfig {\\n bytes4[] selectors;\\n mapping(bytes4 => FacetInfo) info;\\n }\\n struct FacetInfo {\\n bool exists;\\n uint128 index;\\n }\\n\\n event FacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] facetSelectors\\n );\\n event FacetFunctionSelectorsRemoved(address facet, bytes4[] facetSelectors);\\n\\n error FacetRegistry__FacetSelectorAlreadyRegistered();\\n error FacetRegistry__UnregisteredFacetSelector();\\n\\n function registerFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function removeFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function areFacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external view returns (bool);\\n\\n function isFacetFunctionSelectorRegistered(\\n address facet,\\n bytes4 facetSelector\\n ) external view returns (bool);\\n\\n function getFacetFunctionSelectors(\\n address facet\\n ) external view returns (bytes4[] memory);\\n}\\n\",\"keccak256\":\"0x6e6dd2cab346ef7c31230740ec48d2925e4a9ab24c2f2fb268baaf408dcf02ef\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC1271 {\\n function isValidSignature(\\n bytes32 hash,\\n bytes memory signature\\n ) external view returns (bytes4);\\n}\\n\",\"keccak256\":\"0xcdddb7d5641c9d3f2432dec7fd13fddb9ae1480f25c76c21511e2fa16b8bd422\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibAppStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {SafeCast} from \\\"@openzeppelin/contracts/utils/math/SafeCast.sol\\\";\\nimport {IEntryPoint} from \\\"../aa-4337/interfaces/IEntryPoint.sol\\\";\\nimport {IFacetRegistry} from \\\"../infrastructure/interfaces/IFacetRegistry.sol\\\";\\n\\n/*\\n * @title App Storage\\n * @dev App storage for Barz contract to prevent storage collision\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Lock {\\n uint64 release;\\n bytes4 locker;\\n}\\n\\nstruct InitializersStorage {\\n // NOTE: initialized is a variable to make sure the initialization is only done once.\\n uint8 signerInitialized;\\n uint8 accountInitialized;\\n uint8 restrictionsInitialized;\\n}\\n\\nstruct AppStorage {\\n mapping(uint256 => InitializersStorage) initStorage;\\n uint8 signerMigration;\\n bytes4 validateOwnerSignatureSelector;\\n IEntryPoint entryPoint;\\n IFacetRegistry facetRegistry;\\n mapping(uint256 => Lock) locks;\\n}\\n\\nlibrary LibAppStorage {\\n error LibAppStorage__AccountAlreadyUninitialized();\\n error LibAppStorage__AccountMustBeUninitialized();\\n error LibAppStorage__SignerAlreadyUninitialized();\\n error LibAppStorage__SignerMustBeUninitialized();\\n\\n function appStorage() internal pure returns (AppStorage storage ds) {\\n assembly {\\n ds.slot := 0\\n }\\n }\\n\\n function setSignerUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerAlreadyUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 0;\\n }\\n\\n function getValidateOwnerSignatureSelector()\\n internal\\n view\\n returns (bytes4 selector)\\n {\\n selector = appStorage().validateOwnerSignatureSelector;\\n }\\n\\n function setValidateOwnerSignatureSelector(\\n bytes4 _validateOwnerSignatureSelector\\n ) internal {\\n appStorage()\\n .validateOwnerSignatureSelector = _validateOwnerSignatureSelector;\\n }\\n\\n function enforceSignerInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerMustBeUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 1;\\n }\\n\\n function enforceAccountInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].accountInitialized) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n s.initStorage[0].accountInitialized = 1;\\n }\\n\\n function initiateSignerMigration() internal {\\n appStorage().signerMigration = 1;\\n }\\n\\n function enforceSignerMigration() internal view {\\n if (1 != appStorage().signerMigration) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n }\\n\\n function finalizeSignerMigration() internal {\\n appStorage().signerMigration = 0;\\n }\\n\\n function setLock(uint256 _releaseAfter, bytes4 _locker) internal {\\n appStorage().locks[0] = Lock(SafeCast.toUint64(_releaseAfter), _locker);\\n }\\n\\n function enforceRestrictionsInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__SignerMustBeUninitialized();\\n s.initStorage[0].restrictionsInitialized = 1;\\n }\\n\\n function setRestrictionsUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__AccountAlreadyUninitialized();\\n s.initStorage[0].restrictionsInitialized = 0;\\n }\\n}\\n\\ncontract BarzStorage {\\n AppStorage internal s;\\n modifier onlyWhenUnlocked() {\\n require(\\n uint64(block.timestamp) >= s.locks[0].release,\\n \\\"Account Locked\\\"\\n );\\n _;\\n }\\n modifier onlyWhenLocked() {\\n require(\\n uint64(block.timestamp) < s.locks[0].release,\\n \\\"Account Unlocked\\\"\\n );\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x48524007862a6ce0e07f645950613ce6513ce073c37a109c75019683d42bae27\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\\n bytes4(keccak256(\\\"verifyRestrictions(address,address,uint256,bytes)\\\"));\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // Default Fallback Handler of the barz.\\n IDiamondLoupe defaultFallbackHandler;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function enforceIsSelf() internal view {\\n require(msg.sender == address(this), \\\"LibDiamond: Caller not self\\\");\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n\\n unchecked {\\n facetIndex++;\\n }\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n\\n function restrictionsFacet() internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(\\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2cabdc00de859c3a3170ce3bda5d0e5fd3933d47ce904fd1585f9818b02572f8\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibFacetStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Storage\\n * @dev Storage contract to store each facets variables with diamond storage\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Secp256k1VerificationStorage {\\n address signer;\\n}\\n\\nstruct Secp256r1VerificationStorage {\\n uint256[2] q;\\n}\\n\\nstruct GuardianStorage {\\n mapping(bytes32 => uint256) pending;\\n mapping(uint8 => StorageConfig) configs;\\n}\\n\\nstruct Info {\\n bool exists;\\n uint128 index;\\n}\\n\\nstruct StorageConfig {\\n address[] addresses;\\n mapping(address => Info) info;\\n}\\n\\nstruct RecoveryConfig {\\n bytes recoveryPublicKey;\\n uint64 executeAfter;\\n}\\n\\nstruct ApprovalConfig {\\n bool isApproved;\\n uint64 validUntil;\\n}\\n\\nstruct RecoveryApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isNewOwnerApproved;\\n}\\n\\nstruct RecoveryStorage {\\n mapping(uint8 => RecoveryConfig) recoveryConfigs;\\n mapping(uint8 => RecoveryApprovalConfig) recoveryApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct RestrictionsStorage {\\n address[] restrictions;\\n mapping(address => bool) exists;\\n}\\n\\nstruct SignatureMigrationConfig {\\n bytes migrationPublicKey;\\n address migrationVerificationFacet;\\n bytes4[] migrationSelectors;\\n uint64 migrateAfter;\\n}\\n\\nstruct SignatureMigrationApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isMigrationApproved;\\n}\\n\\nstruct SignatureMigrationStorage {\\n mapping(uint8 => SignatureMigrationConfig) migrationConfigs;\\n mapping(uint8 => SignatureMigrationApprovalConfig) migrationApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct DiamondCutApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isDiamondCutApproved;\\n}\\n\\nstruct DiamondCutStorage {\\n mapping(uint8 => DiamondCutApprovalConfig) diamondCutApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct LockStorage {\\n uint128 nonce;\\n}\\n\\nlibrary LibFacetStorage {\\n bytes32 constant K1_STORAGE_POSITION =\\n keccak256(\\n \\\"v0.trustwallet.diamond.storage.Secp256k1VerificationStorage\\\"\\n );\\n bytes32 constant R1_STORAGE_POSITION =\\n keccak256(\\n \\\"v0.trustwallet.diamond.storage.Secp256r1VerificationStorage\\\"\\n );\\n bytes32 constant GUARDIAN_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.GuardianStorage\\\");\\n bytes32 constant RECOVERY_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.RecoveryStorage\\\");\\n bytes32 constant RESTRICTION_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.RestrictionsStorage\\\");\\n bytes32 constant MIGRATION_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.SignatureMigrationStorage\\\");\\n bytes32 constant DIAMONDCUT_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.DiamondCutStorage\\\");\\n bytes32 constant LOCK_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.LockStorage\\\");\\n\\n function k1Storage()\\n internal\\n pure\\n returns (Secp256k1VerificationStorage storage ds)\\n {\\n bytes32 storagePosition = K1_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function r1Storage()\\n internal\\n pure\\n returns (Secp256r1VerificationStorage storage ds)\\n {\\n bytes32 storagePosition = R1_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function guardianStorage()\\n internal\\n pure\\n returns (GuardianStorage storage ds)\\n {\\n bytes32 storagePosition = GUARDIAN_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function recoveryStorage()\\n internal\\n pure\\n returns (RecoveryStorage storage ds)\\n {\\n bytes32 storagePosition = RECOVERY_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function restrictionsStorage()\\n internal\\n pure\\n returns (RestrictionsStorage storage ds)\\n {\\n bytes32 storagePosition = RESTRICTION_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function migrationStorage()\\n internal\\n pure\\n returns (SignatureMigrationStorage storage ds)\\n {\\n bytes32 storagePosition = MIGRATION_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function diamondCutStorage()\\n internal\\n pure\\n returns (DiamondCutStorage storage ds)\\n {\\n bytes32 storagePosition = DIAMONDCUT_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function lockStorage() internal pure returns (LockStorage storage ds) {\\n bytes32 storagePosition = LOCK_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n}\\n\",\"keccak256\":\"0x87c85decfd943deda9540733e464cb1a92eba735a301e89ce6f798016e359761\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\nimport {LibDiamond} from \\\"./LibDiamond.sol\\\";\\n\\n/**\\n * @title LibLoupe\\n * @dev Internal Library to provide utility feature for reading the state of diamond facets\\n * Originally from Diamond's implementation of Mudgen(author of EIP-2535)\\n */\\nlibrary LibLoupe {\\n /// @notice Gets all facets and their selectors.\\n /// @return facets_ Facet\\n function facets()\\n internal\\n view\\n returns (IDiamondLoupe.Facet[] memory facets_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facets_ = new IDiamondLoupe.Facet[](ds.selectorCount);\\n uint16[] memory numFacetSelectors = new uint16[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facets_[facetIndex].facetAddress == facetAddress_) {\\n facets_[facetIndex].functionSelectors[\\n numFacetSelectors[facetIndex]\\n ] = selector;\\n // probably will never have more than 256 functions from one facet contract\\n require(numFacetSelectors[facetIndex] < 255);\\n numFacetSelectors[facetIndex]++;\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facets_[numFacets].facetAddress = facetAddress_;\\n facets_[numFacets].functionSelectors = new bytes4[](\\n ds.selectorCount\\n );\\n facets_[numFacets].functionSelectors[0] = selector;\\n numFacetSelectors[numFacets] = 1;\\n numFacets++;\\n }\\n }\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n uint256 numSelectors = numFacetSelectors[facetIndex];\\n bytes4[] memory selectors = facets_[facetIndex].functionSelectors;\\n // setting the number of selectors\\n assembly {\\n mstore(selectors, numSelectors)\\n }\\n }\\n // setting the number of facets\\n assembly {\\n mstore(facets_, numFacets)\\n }\\n }\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return _facetFunctionSelectors The selectors associated with a facet address.\\n function facetFunctionSelectors(\\n address _facet\\n ) internal view returns (bytes4[] memory _facetFunctionSelectors) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n uint256 numSelectors;\\n _facetFunctionSelectors = new bytes4[](ds.selectorCount);\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facet = address(bytes20(ds.facets[selector]));\\n if (_facet == facet) {\\n _facetFunctionSelectors[numSelectors] = selector;\\n numSelectors++;\\n }\\n }\\n }\\n // Set the number of selectors in the array\\n assembly {\\n mstore(_facetFunctionSelectors, numSelectors)\\n }\\n }\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n internal\\n view\\n returns (address[] memory facetAddresses_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetAddresses_ = new address[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facetAddress_ == facetAddresses_[facetIndex]) {\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facetAddresses_[numFacets] = facetAddress_;\\n numFacets++;\\n }\\n }\\n // Set the number of facet addresses in the array\\n assembly {\\n mstore(facetAddresses_, numFacets)\\n }\\n }\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(LibDiamond.diamondStorage().facets[_functionSelector])\\n );\\n }\\n}\\n\",\"keccak256\":\"0x0b11439c3cc657095e15ec2241fdcf67204b14001357b612fc5db4ff9e760a5a\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x60a060405234801561001057600080fd5b50610019610022565b3060805261008b565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff161561006f57604051637c2cde8b60e01b815260040160405180910390fd5b600080805260209190915260409020805460ff19166001179055565b6080516111946100ad6000396000818161013f015261066401526111946000f3fe608060405234801561001057600080fd5b50600436106100a35760003560e01c80638da5cb5b11610076578063cd00e50a1161005b578063cd00e50a14610218578063cd9b47e414610220578063f45007c31461023357600080fd5b80638da5cb5b146101865780638dd50121146101f757600080fd5b80631626ba7e146100a85780633253960f146100f1578063392dd6d9146101175780637104ddb21461013a575b600080fd5b6100bb6100b6366004610de8565b610246565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020015b60405180910390f35b7f8dd50121000000000000000000000000000000000000000000000000000000006100bb565b61012a610125366004610e2f565b6102f4565b60405190151581526020016100e8565b6101617f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100e8565b7f9d0217145d12a316adea26b4f622aec07fb71e6638d613bb415476f4c179eecc546040805160609290921b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016602083015280518083036014018152603490920190526040516100e89190610e64565b61020a610205366004610ee9565b610366565b6040519081526020016100e8565b61020a6103b8565b61020a61022e366004610f2e565b6104d6565b61020a610241366004610fa0565b6107b7565b60007f9d0217145d12a316adea26b4f622aec07fb71e6638d613bb415476f4c179eecc5473ffffffffffffffffffffffffffffffffffffffff1661028a848461087c565b73ffffffffffffffffffffffffffffffffffffffff16146102cb577fffffffff000000000000000000000000000000000000000000000000000000006102ed565b7f1626ba7e000000000000000000000000000000000000000000000000000000005b9392505050565b60008151604114801561036057508160008151811061031557610315611014565b6020910101517fff00000000000000000000000000000000000000000000000000000000000000167f0400000000000000000000000000000000000000000000000000000000000000145b92915050565b7f9d0217145d12a316adea26b4f622aec07fb71e6638d613bb415476f4c179eecc8054600091906103b0908590859073ffffffffffffffffffffffffffffffffffffffff166107b7565b949350505050565b60006103c26108a0565b6103ca6108e0565b7f9d0217145d12a316adea26b4f622aec07fb71e6638d613bb415476f4c179eecc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001681556000610424600154610100900460e01b90565b7fffffffff00000000000000000000000000000000000000000000000000000000160361047d576040517f127c609a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff169055604051600192507fcccd30db6bc000b8bb8d11162228d2d69e3c361983ca3ae8c1365ce64b0fae9e90600090a15090565b60006104e061097f565b61051f83838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102f492505050565b610555576040517f22281e8500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f9d0217145d12a316adea26b4f622aec07fb71e6638d613bb415476f4c179eecc6105838360018187611043565b60405161059192919061106d565b60405190819003902081547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9091161781556001547f8dd501210000000000000000000000000000000000000000000000000000000090600090610100900460e01b7fffffffff000000000000000000000000000000000000000000000000000000001614610662576040517f5f95a63c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166106f3827fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604090205460601c90565b73ffffffffffffffffffffffffffffffffffffffff1614610740576040517fbb4752b700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff1661010060e084901c02179055600192507f6d54821a69ec281ed7ba1bf2729c700768c47df1d80fad646b0a14cc1d5c39ed85856040516107a792919061107d565b60405180910390a1505092915050565b7f19457468657265756d205369676e6564204d6573736167653a0a3332000000006000908152601c839052603c81206108346107f76101408701876110ca565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250859392505061087c9050565b73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361086d576000610870565b60015b60ff1695945050505050565b600080600061088b8585610a1f565b9150915061089881610a64565b509392505050565b6001805460ff16146108de576040517f38fc28cb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff16600114610948576040517fe00d7c7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff16156109e5576040517f7c2cde8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b6000808251604103610a555760208301516040840151606085015160001a610a4987828585610c1f565b94509450505050610a5d565b506000905060025b9250929050565b6000816004811115610a7857610a7861112f565b03610a805750565b6001816004811115610a9457610a9461112f565b03610b00576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064015b60405180910390fd5b6002816004811115610b1457610b1461112f565b03610b7b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610af7565b6003816004811115610b8f57610b8f61112f565b03610c1c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610af7565b50565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115610c565750600090506003610d05565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015610caa573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116610cfe57600060019250925050610d05565b9150600090505b94509492505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112610d4e57600080fd5b813567ffffffffffffffff80821115610d6957610d69610d0e565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715610daf57610daf610d0e565b81604052838152866020858801011115610dc857600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060408385031215610dfb57600080fd5b82359150602083013567ffffffffffffffff811115610e1957600080fd5b610e2585828601610d3d565b9150509250929050565b600060208284031215610e4157600080fd5b813567ffffffffffffffff811115610e5857600080fd5b6103b084828501610d3d565b600060208083528351808285015260005b81811015610e9157858101830151858201604001528201610e75565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b60006101608284031215610ee357600080fd5b50919050565b60008060408385031215610efc57600080fd5b823567ffffffffffffffff811115610f1357600080fd5b610f1f85828601610ed0565b95602094909401359450505050565b60008060208385031215610f4157600080fd5b823567ffffffffffffffff80821115610f5957600080fd5b818501915085601f830112610f6d57600080fd5b813581811115610f7c57600080fd5b866020828501011115610f8e57600080fd5b60209290920196919550909350505050565b600080600060608486031215610fb557600080fd5b833567ffffffffffffffff811115610fcc57600080fd5b610fd886828701610ed0565b93505060208401359150604084013573ffffffffffffffffffffffffffffffffffffffff8116811461100957600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000808585111561105357600080fd5b8386111561106057600080fd5b5050820193919092039150565b8183823760009101908152919050565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126110ff57600080fd5b83018035915067ffffffffffffffff82111561111a57600080fd5b602001915036819003821315610a5d57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea2646970667358221220de3368e3f3953432149ec8ab61e8db05409a34e6f3f223f6bc0a20072fa01cf364736f6c63430008150033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100a35760003560e01c80638da5cb5b11610076578063cd00e50a1161005b578063cd00e50a14610218578063cd9b47e414610220578063f45007c31461023357600080fd5b80638da5cb5b146101865780638dd50121146101f757600080fd5b80631626ba7e146100a85780633253960f146100f1578063392dd6d9146101175780637104ddb21461013a575b600080fd5b6100bb6100b6366004610de8565b610246565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020015b60405180910390f35b7f8dd50121000000000000000000000000000000000000000000000000000000006100bb565b61012a610125366004610e2f565b6102f4565b60405190151581526020016100e8565b6101617f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100e8565b7f9d0217145d12a316adea26b4f622aec07fb71e6638d613bb415476f4c179eecc546040805160609290921b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016602083015280518083036014018152603490920190526040516100e89190610e64565b61020a610205366004610ee9565b610366565b6040519081526020016100e8565b61020a6103b8565b61020a61022e366004610f2e565b6104d6565b61020a610241366004610fa0565b6107b7565b60007f9d0217145d12a316adea26b4f622aec07fb71e6638d613bb415476f4c179eecc5473ffffffffffffffffffffffffffffffffffffffff1661028a848461087c565b73ffffffffffffffffffffffffffffffffffffffff16146102cb577fffffffff000000000000000000000000000000000000000000000000000000006102ed565b7f1626ba7e000000000000000000000000000000000000000000000000000000005b9392505050565b60008151604114801561036057508160008151811061031557610315611014565b6020910101517fff00000000000000000000000000000000000000000000000000000000000000167f0400000000000000000000000000000000000000000000000000000000000000145b92915050565b7f9d0217145d12a316adea26b4f622aec07fb71e6638d613bb415476f4c179eecc8054600091906103b0908590859073ffffffffffffffffffffffffffffffffffffffff166107b7565b949350505050565b60006103c26108a0565b6103ca6108e0565b7f9d0217145d12a316adea26b4f622aec07fb71e6638d613bb415476f4c179eecc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001681556000610424600154610100900460e01b90565b7fffffffff00000000000000000000000000000000000000000000000000000000160361047d576040517f127c609a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff169055604051600192507fcccd30db6bc000b8bb8d11162228d2d69e3c361983ca3ae8c1365ce64b0fae9e90600090a15090565b60006104e061097f565b61051f83838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102f492505050565b610555576040517f22281e8500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f9d0217145d12a316adea26b4f622aec07fb71e6638d613bb415476f4c179eecc6105838360018187611043565b60405161059192919061106d565b60405190819003902081547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9091161781556001547f8dd501210000000000000000000000000000000000000000000000000000000090600090610100900460e01b7fffffffff000000000000000000000000000000000000000000000000000000001614610662576040517f5f95a63c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166106f3827fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604090205460601c90565b73ffffffffffffffffffffffffffffffffffffffff1614610740576040517fbb4752b700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff1661010060e084901c02179055600192507f6d54821a69ec281ed7ba1bf2729c700768c47df1d80fad646b0a14cc1d5c39ed85856040516107a792919061107d565b60405180910390a1505092915050565b7f19457468657265756d205369676e6564204d6573736167653a0a3332000000006000908152601c839052603c81206108346107f76101408701876110ca565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250859392505061087c9050565b73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361086d576000610870565b60015b60ff1695945050505050565b600080600061088b8585610a1f565b9150915061089881610a64565b509392505050565b6001805460ff16146108de576040517f38fc28cb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff16600114610948576040517fe00d7c7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff16156109e5576040517f7c2cde8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b6000808251604103610a555760208301516040840151606085015160001a610a4987828585610c1f565b94509450505050610a5d565b506000905060025b9250929050565b6000816004811115610a7857610a7861112f565b03610a805750565b6001816004811115610a9457610a9461112f565b03610b00576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064015b60405180910390fd5b6002816004811115610b1457610b1461112f565b03610b7b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610af7565b6003816004811115610b8f57610b8f61112f565b03610c1c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610af7565b50565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115610c565750600090506003610d05565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015610caa573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116610cfe57600060019250925050610d05565b9150600090505b94509492505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112610d4e57600080fd5b813567ffffffffffffffff80821115610d6957610d69610d0e565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715610daf57610daf610d0e565b81604052838152866020858801011115610dc857600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060408385031215610dfb57600080fd5b82359150602083013567ffffffffffffffff811115610e1957600080fd5b610e2585828601610d3d565b9150509250929050565b600060208284031215610e4157600080fd5b813567ffffffffffffffff811115610e5857600080fd5b6103b084828501610d3d565b600060208083528351808285015260005b81811015610e9157858101830151858201604001528201610e75565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b60006101608284031215610ee357600080fd5b50919050565b60008060408385031215610efc57600080fd5b823567ffffffffffffffff811115610f1357600080fd5b610f1f85828601610ed0565b95602094909401359450505050565b60008060208385031215610f4157600080fd5b823567ffffffffffffffff80821115610f5957600080fd5b818501915085601f830112610f6d57600080fd5b813581811115610f7c57600080fd5b866020828501011115610f8e57600080fd5b60209290920196919550909350505050565b600080600060608486031215610fb557600080fd5b833567ffffffffffffffff811115610fcc57600080fd5b610fd886828701610ed0565b93505060208401359150604084013573ffffffffffffffffffffffffffffffffffffffff8116811461100957600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000808585111561105357600080fd5b8386111561106057600080fd5b5050820193919092039150565b8183823760009101908152919050565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126110ff57600080fd5b83018035915067ffffffffffffffff82111561111a57600080fd5b602001915036819003821315610a5d57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea2646970667358221220de3368e3f3953432149ec8ab61e8db05409a34e6f3f223f6bc0a20072fa01cf364736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)Ruslan Serebriakov (@rsrbk)", + "details": "Default Ethereum's elliptic curve", + "kind": "dev", + "methods": { + "initializeSigner(bytes)": { + "details": "This method checks if the signer has already been initialized. If already initialized, it reverts. It checks if the public key is in the light format and initializes signer storage in k1 storage.", + "params": { + "_publicKey": "Bytes of owner public key" + }, + "returns": { + "initSuccess": "Uint value representing the success of init operation" + } + }, + "isValidKeyType(bytes)": { + "details": "For this Secp256k1Verification Facet, the public key length should be 65 in an uncompressed public key format", + "params": { + "_publicKey": "Bytes of public key for format check" + }, + "returns": { + "isValid": "Boolean variable representing if the format of public key is valid" + } + }, + "isValidSignature(bytes32,bytes)": { + "details": "This method verifies the signature if the owner indeed signed the hash. Returns magic value if true", + "params": { + "_hash": "Hash value the owner signed", + "_signature": "Signature that signed the above hash" + }, + "returns": { + "magicValue": "Bytes4 value representing the success/failure of validation" + } + }, + "owner()": { + "returns": { + "signer": "Bytes of owner address" + } + }, + "uninitializeSigner()": { + "details": "This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.", + "returns": { + "uninitSuccess": "Uint value representing the success of uninit operation" + } + }, + "validateOwnerSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32)": { + "details": "This method validates if the user operation is signed by the owner. It internally calls validateSignature with signer public key.", + "params": { + "userOp": "UserOperation including all information for execution", + "userOpHash": "Hash of UserOperation given from EntryPoint. This hash is used for signature validation" + }, + "returns": { + "validationData": "Uint value representing whether the validation is successful. 0 for success, 1 for failure" + } + }, + "validateOwnerSignatureSelector()": { + "returns": { + "ownerSignatureValidatorSelector": "Bytes4 selector of function signature to validate account owner's UserOperation signature" + } + }, + "validateSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,address)": { + "details": "This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address", + "params": { + "signer": "Address of signer who signed the contract, to be validated", + "userOp": "UserOperation including all information for execution", + "userOpHash": "Hash of UserOperation given from EntryPoint. This hash is used for signature validation" + }, + "returns": { + "isValid": "Uint value representing whether the validation is successful. 0 for success, 1 for failure" + } + } + }, + "title": "Secp256k1 verification facet", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "constructor": { + "notice": "This constructor ensures that this contract can only be used as singleton for Proxy contracts" + }, + "initializeSigner(bytes)": { + "notice": "Initializes the signer in K1 Facet Storage. This can only be called when the account is uninitialized or during signature migration." + }, + "isValidKeyType(bytes)": { + "notice": "Validates if the format of public key is valid for this verification facet" + }, + "isValidSignature(bytes32,bytes)": { + "notice": "Validates if the signature is valid. Function to be compatible with EIP-1271" + }, + "owner()": { + "notice": "Returns the owner of the account" + }, + "uninitializeSigner()": { + "notice": "Uninitialize signer in K1 Facet Storage. This can only be called when the account is undergoing signature migration and has already been initialized." + }, + "validateOwnerSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32)": { + "notice": "Validates if the user operation is signed by the owner." + }, + "validateOwnerSignatureSelector()": { + "notice": "Returns the selector of function to validate the signature of UserOperation" + }, + "validateSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,address)": { + "notice": "Validates if the signature of UserOperation is signed by the given signer" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/linea/Secp256r1VerificationFacet.json b/deployments/linea/Secp256r1VerificationFacet.json new file mode 100644 index 0000000..296b4ad --- /dev/null +++ b/deployments/linea/Secp256r1VerificationFacet.json @@ -0,0 +1,483 @@ +{ + "address": "0xeE1AF8E967eC04C84711842796A5E714D2FD33e6", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "LibAppStorage__AccountMustBeUninitialized", + "type": "error" + }, + { + "inputs": [], + "name": "LibAppStorage__SignerAlreadyUninitialized", + "type": "error" + }, + { + "inputs": [], + "name": "LibAppStorage__SignerMustBeUninitialized", + "type": "error" + }, + { + "inputs": [], + "name": "Secp256r1VerificationFacet__InvalidSignerLength", + "type": "error" + }, + { + "inputs": [], + "name": "VerificationFacet__InitializationFailure", + "type": "error" + }, + { + "inputs": [], + "name": "VerificationFacet__InvalidFacetMapping", + "type": "error" + }, + { + "inputs": [], + "name": "VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet", + "type": "error" + }, + { + "inputs": [], + "name": "VerificationFacet__ValidateOwnerSignatureSelectorNotSet", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "SignerInitialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "SignerUninitialized", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_publicKey", + "type": "bytes" + } + ], + "name": "initializeSigner", + "outputs": [ + { + "internalType": "uint256", + "name": "initSuccess", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_publicKey", + "type": "bytes" + } + ], + "name": "isValidKeyType", + "outputs": [ + { + "internalType": "bool", + "name": "isValid", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_hash", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "_signature", + "type": "bytes" + } + ], + "name": "isValidSignature", + "outputs": [ + { + "internalType": "bytes4", + "name": "magicValue", + "type": "bytes4" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "bytes", + "name": "signer", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "self", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "uninitializeSigner", + "outputs": [ + { + "internalType": "uint256", + "name": "uninitSuccess", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "initCode", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "callGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "verificationGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "preVerificationGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxFeePerGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPriorityFeePerGas", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "paymasterAndData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "internalType": "struct UserOperation", + "name": "userOp", + "type": "tuple" + }, + { + "internalType": "bytes32", + "name": "userOpHash", + "type": "bytes32" + } + ], + "name": "validateOwnerSignature", + "outputs": [ + { + "internalType": "uint256", + "name": "validationData", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "validateOwnerSignatureSelector", + "outputs": [ + { + "internalType": "bytes4", + "name": "ownerSignatureValidatorSelector", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "initCode", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "callGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "verificationGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "preVerificationGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxFeePerGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPriorityFeePerGas", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "paymasterAndData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "internalType": "struct UserOperation", + "name": "userOp", + "type": "tuple" + }, + { + "internalType": "bytes32", + "name": "userOpHash", + "type": "bytes32" + }, + { + "internalType": "uint256[2]", + "name": "q", + "type": "uint256[2]" + } + ], + "name": "validateSignature", + "outputs": [ + { + "internalType": "uint256", + "name": "isValid", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0x96c58e8057abea424b82d0a38e574cd6be0d4a7a499534d8bf12c530de2fceb1", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 3, + "gasUsed": "1809225", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x19ec1c001d77eb680c3388606d886335f19fb7e05985f9679f4b175a67daf12a", + "transactionHash": "0x96c58e8057abea424b82d0a38e574cd6be0d4a7a499534d8bf12c530de2fceb1", + "logs": [], + "blockNumber": 2720885, + "cumulativeGasUsed": "2507227", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "ad34345aa73d96f52b3e14df983b6b29", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"LibAppStorage__AccountMustBeUninitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LibAppStorage__SignerAlreadyUninitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LibAppStorage__SignerMustBeUninitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Secp256r1VerificationFacet__InvalidSignerLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerificationFacet__InitializationFailure\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerificationFacet__InvalidFacetMapping\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerificationFacet__ValidateOwnerSignatureSelectorNotSet\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"SignerInitialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"SignerUninitialized\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_publicKey\",\"type\":\"bytes\"}],\"name\":\"initializeSigner\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"initSuccess\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_publicKey\",\"type\":\"bytes\"}],\"name\":\"isValidKeyType\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isValid\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_hash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"_signature\",\"type\":\"bytes\"}],\"name\":\"isValidSignature\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"magicValue\",\"type\":\"bytes4\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"signer\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"self\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"uninitializeSigner\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"uninitSuccess\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"userOp\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"}],\"name\":\"validateOwnerSignature\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"validationData\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"validateOwnerSignatureSelector\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"ownerSignatureValidatorSelector\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"userOp\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256[2]\",\"name\":\"q\",\"type\":\"uint256[2]\"}],\"name\":\"validateSignature\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"isValid\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Ruslan Serebriakov (@rsrbk)David Yongjun Kim (@Powerstream3604)\",\"details\":\"Primarily used to verify user ops signed with passkeys\",\"kind\":\"dev\",\"methods\":{\"initializeSigner(bytes)\":{\"details\":\"This method checks if the signer has already been initialized. If already initialized, it reverts. It checks if the public key is in the light format and initializes signer storage in k1 storage.\",\"params\":{\"_publicKey\":\"Bytes of owner public key\"},\"returns\":{\"initSuccess\":\"Uint value representing the success of init operation\"}},\"isValidKeyType(bytes)\":{\"details\":\"For this Secp256k1Verification Facet, the public key should in an uncompressed public key format\",\"params\":{\"_publicKey\":\"Bytes of public key for format check\"},\"returns\":{\"isValid\":\"Boolean variable representing if the format of public key is valid\"}},\"isValidSignature(bytes32,bytes)\":{\"details\":\"This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\",\"params\":{\"_hash\":\"Hash value the owner signed\",\"_signature\":\"Signature that signed the above hash\"},\"returns\":{\"magicValue\":\"Bytes4 value representing the success/failure of validation\"}},\"owner()\":{\"returns\":{\"signer\":\"Bytes of owner address\"}},\"uninitializeSigner()\":{\"details\":\"This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\",\"returns\":{\"uninitSuccess\":\"Uint value representing the success of uninit operation\"}},\"validateOwnerSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32)\":{\"details\":\"This method validates if the user operation is signed by the owner. It internally calls validateSignature with signer public key.\",\"params\":{\"userOp\":\"UserOperation including all information for execution\",\"userOpHash\":\"Hash of UserOperation given from EntryPoint. This hash is used for signature validation\"},\"returns\":{\"validationData\":\"Uint value representing whether the validation is successful. 0 for success, 1 for failure\"}},\"validateOwnerSignatureSelector()\":{\"returns\":{\"ownerSignatureValidatorSelector\":\"Bytes4 selector of function signature to validate account owner's UserOperation signature\"}},\"validateSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256[2])\":{\"details\":\"This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\",\"params\":{\"q\":\"Public Key of signer who signed the contract, to be validated\",\"userOp\":\"UserOperation including all information for execution\",\"userOpHash\":\"Hash of UserOperation given from EntryPoint. This hash is used for signature validation\"},\"returns\":{\"isValid\":\"Uint value representing whether the validation is successful. 0 for success, 1 for failure\"}}},\"title\":\"Secp256r1 verification facet\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"This constructor ensures that this contract can only be used as singleton for Proxy contracts\"},\"initializeSigner(bytes)\":{\"notice\":\"Initializes the signer in R1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\"},\"isValidKeyType(bytes)\":{\"notice\":\"Validates if the format of public key is valid for this verification facet\"},\"isValidSignature(bytes32,bytes)\":{\"notice\":\"Validates if the signature is valid. Function to be compatible with EIP-1271\"},\"owner()\":{\"notice\":\"Returns the owner of the account\"},\"uninitializeSigner()\":{\"notice\":\"Uninitialize signer in R1 Facet Storage. This can only be called when the account is undergoing signature migration and has already been initialized.\"},\"validateOwnerSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32)\":{\"notice\":\"Validates if the user operation is signed by the owner.\"},\"validateOwnerSignatureSelector()\":{\"notice\":\"Returns the selector of function to validate the signature of UserOperation\"},\"validateSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256[2])\":{\"notice\":\"Validates if the signature of UserOperation is signed by the given signer\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/verification/secp256r1/Secp256r1VerificationFacet.sol\":\"Secp256r1VerificationFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/utils/math/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\\n * checks.\\n *\\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\\n * easily result in undesired exploitation or bugs, since developers usually\\n * assume that overflows raise errors. `SafeCast` restores this intuition by\\n * reverting the transaction when such an operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n *\\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\\n * all math on `uint256` and `int256` and then downcasting.\\n */\\nlibrary SafeCast {\\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 * _Available since v4.7._\\n */\\n function toUint248(uint256 value) internal pure returns (uint248) {\\n require(value <= type(uint248).max, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint240(uint256 value) internal pure returns (uint240) {\\n require(value <= type(uint240).max, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint232(uint256 value) internal pure returns (uint232) {\\n require(value <= type(uint232).max, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint224(uint256 value) internal pure returns (uint224) {\\n require(value <= type(uint224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint216(uint256 value) internal pure returns (uint216) {\\n require(value <= type(uint216).max, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint208(uint256 value) internal pure returns (uint208) {\\n require(value <= type(uint208).max, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint200(uint256 value) internal pure returns (uint200) {\\n require(value <= type(uint200).max, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint192(uint256 value) internal pure returns (uint192) {\\n require(value <= type(uint192).max, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint184(uint256 value) internal pure returns (uint184) {\\n require(value <= type(uint184).max, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint176(uint256 value) internal pure returns (uint176) {\\n require(value <= type(uint176).max, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint168(uint256 value) internal pure returns (uint168) {\\n require(value <= type(uint168).max, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint160(uint256 value) internal pure returns (uint160) {\\n require(value <= type(uint160).max, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint152(uint256 value) internal pure returns (uint152) {\\n require(value <= type(uint152).max, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint144(uint256 value) internal pure returns (uint144) {\\n require(value <= type(uint144).max, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint136(uint256 value) internal pure returns (uint136) {\\n require(value <= type(uint136).max, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint128(uint256 value) internal pure returns (uint128) {\\n require(value <= type(uint128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint120(uint256 value) internal pure returns (uint120) {\\n require(value <= type(uint120).max, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint112(uint256 value) internal pure returns (uint112) {\\n require(value <= type(uint112).max, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint104(uint256 value) internal pure returns (uint104) {\\n require(value <= type(uint104).max, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint96(uint256 value) internal pure returns (uint96) {\\n require(value <= type(uint96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint88(uint256 value) internal pure returns (uint88) {\\n require(value <= type(uint88).max, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint80(uint256 value) internal pure returns (uint80) {\\n require(value <= type(uint80).max, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint72(uint256 value) internal pure returns (uint72) {\\n require(value <= type(uint72).max, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint64(uint256 value) internal pure returns (uint64) {\\n require(value <= type(uint64).max, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint56(uint256 value) internal pure returns (uint56) {\\n require(value <= type(uint56).max, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint48(uint256 value) internal pure returns (uint48) {\\n require(value <= type(uint48).max, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint40(uint256 value) internal pure returns (uint40) {\\n require(value <= type(uint40).max, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint32(uint256 value) internal pure returns (uint32) {\\n require(value <= type(uint32).max, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint24(uint256 value) internal pure returns (uint24) {\\n require(value <= type(uint24).max, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint16(uint256 value) internal pure returns (uint16) {\\n require(value <= type(uint16).max, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint8(uint256 value) internal pure returns (uint8) {\\n require(value <= type(uint8).max, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\n */\\n function toUint256(int256 value) internal pure returns (uint256) {\\n require(value >= 0, \\\"SafeCast: value must be positive\\\");\\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 * _Available since v4.7._\\n */\\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\\n downcasted = int248(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\\n downcasted = int240(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\\n downcasted = int232(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\\n downcasted = int224(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\\n downcasted = int216(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\\n downcasted = int208(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\\n downcasted = int200(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\\n downcasted = int192(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\\n downcasted = int184(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\\n downcasted = int176(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\\n downcasted = int168(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\\n downcasted = int160(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\\n downcasted = int152(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\\n downcasted = int144(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\\n downcasted = int136(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\\n downcasted = int128(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\\n downcasted = int120(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\\n downcasted = int112(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\\n downcasted = int104(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\\n downcasted = int96(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\\n downcasted = int88(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\\n downcasted = int80(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\\n downcasted = int72(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\\n downcasted = int64(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\\n downcasted = int56(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\\n downcasted = int48(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\\n downcasted = int40(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\\n downcasted = int32(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\\n downcasted = int24(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\\n downcasted = int16(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\\n downcasted = int8(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\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 require(value <= uint256(type(int256).max), \\\"SafeCast: value doesn't fit in an int256\\\");\\n return int256(value);\\n }\\n}\\n\",\"keccak256\":\"0x52a8cfb0f5239d11b457dcdd1b326992ef672714ca8da71a157255bddd13f3ad\",\"license\":\"MIT\"},\"contracts/aa-4337/core/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable no-inline-assembly */\\n\\n/**\\n * returned data from validateUserOp.\\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\\n * @param aggregator - address(0) - the account validated the signature by itself.\\n * address(1) - the account failed to validate the signature.\\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\\n * @param validAfter - this UserOp is valid only after this timestamp.\\n * @param validaUntil - this UserOp is valid only up to this timestamp.\\n */\\nstruct ValidationData {\\n address aggregator;\\n uint48 validAfter;\\n uint48 validUntil;\\n}\\n\\n//extract sigFailed, validAfter, validUntil.\\n// also convert zero validUntil to type(uint48).max\\nfunction _parseValidationData(\\n uint validationData\\n) pure returns (ValidationData memory data) {\\n address aggregator = address(uint160(validationData));\\n uint48 validUntil = uint48(validationData >> 160);\\n if (validUntil == 0) {\\n validUntil = type(uint48).max;\\n }\\n uint48 validAfter = uint48(validationData >> (48 + 160));\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n// intersect account and paymaster ranges.\\nfunction _intersectTimeRange(\\n uint256 validationData,\\n uint256 paymasterValidationData\\n) pure returns (ValidationData memory) {\\n ValidationData memory accountValidationData = _parseValidationData(\\n validationData\\n );\\n ValidationData memory pmValidationData = _parseValidationData(\\n paymasterValidationData\\n );\\n address aggregator = accountValidationData.aggregator;\\n if (aggregator == address(0)) {\\n aggregator = pmValidationData.aggregator;\\n }\\n uint48 validAfter = accountValidationData.validAfter;\\n uint48 validUntil = accountValidationData.validUntil;\\n uint48 pmValidAfter = pmValidationData.validAfter;\\n uint48 pmValidUntil = pmValidationData.validUntil;\\n\\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp\\n * @param data - the ValidationData to pack\\n */\\nfunction _packValidationData(\\n ValidationData memory data\\n) pure returns (uint256) {\\n return\\n uint160(data.aggregator) |\\n (uint256(data.validUntil) << 160) |\\n (uint256(data.validAfter) << (160 + 48));\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp, when not using an aggregator\\n * @param sigFailed - true for signature failure, false for success\\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\\n * @param validAfter first timestamp this UserOperation is valid\\n */\\nfunction _packValidationData(\\n bool sigFailed,\\n uint48 validUntil,\\n uint48 validAfter\\n) pure returns (uint256) {\\n return\\n (sigFailed ? 1 : 0) |\\n (uint256(validUntil) << 160) |\\n (uint256(validAfter) << (160 + 48));\\n}\\n\\n/**\\n * keccak function over calldata.\\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\\n */\\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\\n assembly {\\n let mem := mload(0x40)\\n let len := data.length\\n calldatacopy(mem, data.offset, len)\\n ret := keccak256(mem, len)\\n }\\n}\\n\",\"keccak256\":\"0xa79f06cd158ecb8c0da95493a2f348933b8627a63e228b99738bff3aa107942d\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAggregator.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\n/**\\n * Aggregated Signatures validator.\\n */\\ninterface IAggregator {\\n /**\\n * validate aggregated signature.\\n * revert if the aggregated signature does not match the given list of operations.\\n */\\n function validateSignatures(\\n UserOperation[] calldata userOps,\\n bytes calldata signature\\n ) external view;\\n\\n /**\\n * validate signature of a single userOp\\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\\n * @param userOp the userOperation received from the user.\\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\\n * (usually empty, unless account and aggregator support some kind of \\\"multisig\\\"\\n */\\n function validateUserOpSignature(\\n UserOperation calldata userOp\\n ) external view returns (bytes memory sigForUserOp);\\n\\n /**\\n * aggregate multiple signatures into a single value.\\n * This method is called off-chain to calculate the signature to pass with handleOps()\\n * bundler MAY use optimized custom code perform this aggregation\\n * @param userOps array of UserOperations to collect the signatures from.\\n * @return aggregatedSignature the aggregated signature\\n */\\n function aggregateSignatures(\\n UserOperation[] calldata userOps\\n ) external view returns (bytes memory aggregatedSignature);\\n}\\n\",\"keccak256\":\"0xdfdcd80568f037716674619b31be630fcd8316262f05a815b41d1e81782c966a\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IEntryPoint.sol\":{\"content\":\"/**\\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\\n ** Only one instance required on each chain.\\n **/\\n// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-inline-assembly */\\n/* solhint-disable reason-string */\\n\\nimport \\\"./UserOperation.sol\\\";\\nimport \\\"./IStakeManager.sol\\\";\\nimport \\\"./IAggregator.sol\\\";\\nimport \\\"./INonceManager.sol\\\";\\n\\ninterface IEntryPoint is IStakeManager, INonceManager {\\n /***\\n * An event emitted after each successful request\\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\\n * @param sender - the account that generates this request.\\n * @param paymaster - if non-null, the paymaster that pays for this request.\\n * @param nonce - the nonce value from the request.\\n * @param success - true if the sender transaction succeeded, false if reverted.\\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\\n */\\n event UserOperationEvent(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address indexed paymaster,\\n uint256 nonce,\\n bool success,\\n uint256 actualGasCost,\\n uint256 actualGasUsed\\n );\\n\\n /**\\n * account \\\"sender\\\" was deployed.\\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\\n * @param sender the account that is deployed\\n * @param factory the factory used to deploy this account (in the initCode)\\n * @param paymaster the paymaster used by this UserOp\\n */\\n event AccountDeployed(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address factory,\\n address paymaster\\n );\\n\\n /**\\n * An event emitted if the UserOperation \\\"callData\\\" reverted with non-zero length\\n * @param userOpHash the request unique identifier.\\n * @param sender the sender of this request\\n * @param nonce the nonce used in the request\\n * @param revertReason - the return bytes from the (reverted) call to \\\"callData\\\".\\n */\\n event UserOperationRevertReason(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n uint256 nonce,\\n bytes revertReason\\n );\\n\\n /**\\n * an event emitted by handleOps(), before starting the execution loop.\\n * any event emitted before this event, is part of the validation.\\n */\\n event BeforeExecution();\\n\\n /**\\n * signature aggregator used by the following UserOperationEvents within this bundle.\\n */\\n event SignatureAggregatorChanged(address indexed aggregator);\\n\\n /**\\n * a custom revert error of handleOps, to identify the offending op.\\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\\n * @param reason - revert reason\\n * The string starts with a unique code \\\"AAmn\\\", where \\\"m\\\" is \\\"1\\\" for factory, \\\"2\\\" for account and \\\"3\\\" for paymaster issues,\\n * so a failure can be attributed to the correct entity.\\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\\n */\\n error FailedOp(uint256 opIndex, string reason);\\n\\n /**\\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\\n */\\n error SignatureValidationFailed(address aggregator);\\n\\n /**\\n * Successful result from simulateValidation.\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n */\\n error ValidationResult(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo\\n );\\n\\n /**\\n * Successful result from simulateValidation, if the account returns a signature aggregator\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\\n * bundler MUST use it to verify the signature, or reject the UserOperation\\n */\\n error ValidationResultWithAggregation(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo,\\n AggregatorStakeInfo aggregatorInfo\\n );\\n\\n /**\\n * return value of getSenderAddress\\n */\\n error SenderAddressResult(address sender);\\n\\n /**\\n * return value of simulateHandleOp\\n */\\n error ExecutionResult(\\n uint256 preOpGas,\\n uint256 paid,\\n uint48 validAfter,\\n uint48 validUntil,\\n bool targetSuccess,\\n bytes targetResult\\n );\\n\\n //UserOps handled, per aggregator\\n struct UserOpsPerAggregator {\\n UserOperation[] userOps;\\n // aggregator address\\n IAggregator aggregator;\\n // aggregated signature\\n bytes signature;\\n }\\n\\n /**\\n * Execute a batch of UserOperation.\\n * no signature aggregator is used.\\n * if any account requires an aggregator (that is, it returned an aggregator when\\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\\n * @param ops the operations to execute\\n * @param beneficiary the address to receive the fees\\n */\\n function handleOps(\\n UserOperation[] calldata ops,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * Execute a batch of UserOperation with Aggregators\\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\\n * @param beneficiary the address to receive the fees\\n */\\n function handleAggregatedOps(\\n UserOpsPerAggregator[] calldata opsPerAggregator,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * generate a request Id - unique identifier for this request.\\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\\n */\\n function getUserOpHash(\\n UserOperation calldata userOp\\n ) external view returns (bytes32);\\n\\n /**\\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\\n * @param userOp the user operation to validate.\\n */\\n function simulateValidation(UserOperation calldata userOp) external;\\n\\n /**\\n * gas and return values during simulation\\n * @param preOpGas the gas used for validation (including preValidationGas)\\n * @param prefund the required prefund for this operation\\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\\n */\\n struct ReturnInfo {\\n uint256 preOpGas;\\n uint256 prefund;\\n bool sigFailed;\\n uint48 validAfter;\\n uint48 validUntil;\\n bytes paymasterContext;\\n }\\n\\n /**\\n * returned aggregated signature info.\\n * the aggregator returned by the account, and its current stake.\\n */\\n struct AggregatorStakeInfo {\\n address aggregator;\\n StakeInfo stakeInfo;\\n }\\n\\n /**\\n * Get counterfactual sender address.\\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\\n * this method always revert, and returns the address in SenderAddressResult error\\n * @param initCode the constructor code to be passed into the UserOperation.\\n */\\n function getSenderAddress(bytes memory initCode) external;\\n\\n /**\\n * simulate full execution of a UserOperation (including both validation and target execution)\\n * this method will always revert with \\\"ExecutionResult\\\".\\n * it performs full validation of the UserOperation, but ignores signature error.\\n * an optional target address is called after the userop succeeds, and its value is returned\\n * (before the entire call is reverted)\\n * Note that in order to collect the the success/failure of the target call, it must be executed\\n * with trace enabled to track the emitted events.\\n * @param op the UserOperation to simulate\\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\\n * are set to the return from that call.\\n * @param targetCallData callData to pass to target address\\n */\\n function simulateHandleOp(\\n UserOperation calldata op,\\n address target,\\n bytes calldata targetCallData\\n ) external;\\n}\\n\",\"keccak256\":\"0x9ccb1b188eda8bbf5f6c2d01bd83c3d8b2b04fcf745283051d31fe96d1d8e40f\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/INonceManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\ninterface INonceManager {\\n /**\\n * Return the next nonce for this sender.\\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\\n * But UserOp with different keys can come with arbitrary order.\\n *\\n * @param sender the account address\\n * @param key the high 192 bit of the nonce\\n * @return nonce a full nonce to pass for next UserOp with this sender.\\n */\\n function getNonce(\\n address sender,\\n uint192 key\\n ) external view returns (uint256 nonce);\\n\\n /**\\n * Manually increment the nonce of the sender.\\n * This method is exposed just for completeness..\\n * Account does NOT need to call it, neither during validation, nor elsewhere,\\n * as the EntryPoint will update the nonce regardless.\\n * Possible use-case is call it with various keys to \\\"initialize\\\" their nonces to one, so that future\\n * UserOperations will not pay extra for the first transaction with a given key.\\n */\\n function incrementNonce(uint192 key) external;\\n}\\n\",\"keccak256\":\"0xce478ad0fa0d18a3b785ac854623029e7ab463d05873dfaa365abfa1bf100912\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IStakeManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8.12;\\n\\n/**\\n * manage deposits and stakes.\\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\\n * stake is value locked for at least \\\"unstakeDelay\\\" by the staked entity.\\n */\\ninterface IStakeManager {\\n event Deposited(address indexed account, uint256 totalDeposit);\\n\\n event Withdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /// Emitted when stake or unstake delay are modified\\n event StakeLocked(\\n address indexed account,\\n uint256 totalStaked,\\n uint256 unstakeDelaySec\\n );\\n\\n /// Emitted once a stake is scheduled for withdrawal\\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\\n\\n event StakeWithdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /**\\n * @param deposit the entity's deposit\\n * @param staked true if this entity is staked.\\n * @param stake actual amount of ether staked for this entity.\\n * @param unstakeDelaySec minimum delay to withdraw the stake.\\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\\n * and the rest fit into a 2nd cell.\\n * 112 bit allows for 10^15 eth\\n * 48 bit for full timestamp\\n * 32 bit allows 150 years for unstake delay\\n */\\n struct DepositInfo {\\n uint112 deposit;\\n bool staked;\\n uint112 stake;\\n uint32 unstakeDelaySec;\\n uint48 withdrawTime;\\n }\\n\\n //API struct used by getStakeInfo and simulateValidation\\n struct StakeInfo {\\n uint256 stake;\\n uint256 unstakeDelaySec;\\n }\\n\\n /// @return info - full deposit information of given account\\n function getDepositInfo(\\n address account\\n ) external view returns (DepositInfo memory info);\\n\\n /// @return the deposit (for gas payment) of the account\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * add to the deposit of the given account\\n */\\n function depositTo(address account) external payable;\\n\\n /**\\n * add to the account's stake - amount and delay\\n * any pending unstake is first cancelled.\\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\\n */\\n function addStake(uint32 _unstakeDelaySec) external payable;\\n\\n /**\\n * attempt to unlock the stake.\\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\\n */\\n function unlockStake() external;\\n\\n /**\\n * withdraw from the (unlocked) stake.\\n * must first call unlockStake and wait for the unstakeDelay to pass\\n * @param withdrawAddress the address to send withdrawn value.\\n */\\n function withdrawStake(address payable withdrawAddress) external;\\n\\n /**\\n * withdraw from the deposit.\\n * @param withdrawAddress the address to send withdrawn value.\\n * @param withdrawAmount the amount to withdraw.\\n */\\n function withdrawTo(\\n address payable withdrawAddress,\\n uint256 withdrawAmount\\n ) external;\\n}\\n\",\"keccak256\":\"0xadcea606c9b7aafe6645441f2154a60f271330b0eee5292a632aa71c1672d546\",\"license\":\"GPL-3.0-only\"},\"contracts/aa-4337/interfaces/UserOperation.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable no-inline-assembly */\\n\\nimport {calldataKeccak} from \\\"../core/Helpers.sol\\\";\\n\\n/**\\n * User Operation struct\\n * @param sender the sender account of this request.\\n * @param nonce unique value the sender uses to verify it is not a replay.\\n * @param initCode if set, the account contract will be created by this constructor/\\n * @param callData the method call to execute on this account.\\n * @param callGasLimit the gas limit passed to the callData method call.\\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\\n * @param maxFeePerGas same as EIP-1559 gas parameter.\\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\\n */\\nstruct UserOperation {\\n address sender;\\n uint256 nonce;\\n bytes initCode;\\n bytes callData;\\n uint256 callGasLimit;\\n uint256 verificationGasLimit;\\n uint256 preVerificationGas;\\n uint256 maxFeePerGas;\\n uint256 maxPriorityFeePerGas;\\n bytes paymasterAndData;\\n bytes signature;\\n}\\n\\n/**\\n * Utility functions helpful when working with UserOperation structs.\\n */\\nlibrary UserOperationLib {\\n function getSender(\\n UserOperation calldata userOp\\n ) internal pure returns (address) {\\n address data;\\n //read sender from userOp, which is first userOp member (saves 800 gas...)\\n assembly {\\n data := calldataload(userOp)\\n }\\n return address(uint160(data));\\n }\\n\\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\\n // pay above what he signed for.\\n function gasPrice(\\n UserOperation calldata userOp\\n ) internal view returns (uint256) {\\n unchecked {\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n if (maxFeePerGas == maxPriorityFeePerGas) {\\n //legacy mode (for networks that don't support basefee opcode)\\n return maxFeePerGas;\\n }\\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\\n }\\n }\\n\\n function pack(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes memory ret) {\\n address sender = getSender(userOp);\\n uint256 nonce = userOp.nonce;\\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\\n bytes32 hashCallData = calldataKeccak(userOp.callData);\\n uint256 callGasLimit = userOp.callGasLimit;\\n uint256 verificationGasLimit = userOp.verificationGasLimit;\\n uint256 preVerificationGas = userOp.preVerificationGas;\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\\n\\n return\\n abi.encode(\\n sender,\\n nonce,\\n hashInitCode,\\n hashCallData,\\n callGasLimit,\\n verificationGasLimit,\\n preVerificationGas,\\n maxFeePerGas,\\n maxPriorityFeePerGas,\\n hashPaymasterAndData\\n );\\n }\\n\\n function hash(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes32) {\\n return keccak256(pack(userOp));\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n}\\n\",\"keccak256\":\"0x2429f5cc546bdee08c7e63858d0dda8491eaa3ab5194df884dc948c1154d2834\",\"license\":\"GPL-3.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/facets/interfaces/IVerificationFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {UserOperation} from \\\"../../aa-4337/interfaces/UserOperation.sol\\\";\\n\\n/**\\n * @title Verification Facet Interface\\n * @dev Implements logic for user ops signature verification\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\ninterface IVerificationFacet {\\n event SignerInitialized(bytes);\\n event SignerUninitialized();\\n\\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\\n error VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\\n error VerificationFacet__InitializationFailure();\\n error VerificationFacet__InvalidFacetMapping();\\n\\n function initializeSigner(bytes memory) external returns (uint256);\\n\\n function uninitializeSigner() external returns (uint256);\\n\\n function validateOwnerSignatureSelector() external view returns (bytes4);\\n\\n function owner() external view returns (bytes memory);\\n\\n function isValidKeyType(bytes calldata) external view returns (bool);\\n\\n function validateOwnerSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x72bc370a1d1b5a6d6bde67f5026733fd8f6ba434bb90e73b0bd8627fb1579928\",\"license\":\"Apache-2.0\"},\"contracts/facets/verification/secp256r1/Secp256r1VerificationFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {UserOperation} from \\\"../../../aa-4337/interfaces/UserOperation.sol\\\";\\nimport {LibAppStorage} from \\\"../../../libraries/LibAppStorage.sol\\\";\\nimport {LibLoupe} from \\\"../../../libraries/LibLoupe.sol\\\";\\nimport {LibFacetStorage, Secp256r1VerificationStorage} from \\\"../../../libraries/LibFacetStorage.sol\\\";\\nimport {Base64} from \\\"./utils/Base64.sol\\\";\\nimport {LibSecp256r1} from \\\"./utils/LibSecp256r1.sol\\\";\\nimport {IERC1271} from \\\"../../../interfaces/ERC/IERC1271.sol\\\";\\nimport {IVerificationFacet} from \\\"../../interfaces/IVerificationFacet.sol\\\";\\n\\n/**\\n * @title Secp256r1 verification facet\\n * @dev Primarily used to verify user ops signed with passkeys\\n * @author Ruslan Serebriakov (@rsrbk)\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract Secp256r1VerificationFacet is IVerificationFacet, IERC1271 {\\n error Secp256r1VerificationFacet__InvalidSignerLength();\\n address public immutable self;\\n\\n /**\\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\\n */\\n constructor() {\\n LibAppStorage.enforceSignerInitialize();\\n self = address(this);\\n }\\n\\n /**\\n * @notice Initializes the signer in R1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\\n * @param _publicKey Bytes of owner public key\\n * @return initSuccess Uint value representing the success of init operation\\n */\\n function initializeSigner(\\n bytes calldata _publicKey\\n ) public override returns (uint256 initSuccess) {\\n LibAppStorage.enforceSignerInitialize();\\n\\n if (!isValidKeyType(_publicKey))\\n revert Secp256r1VerificationFacet__InvalidSignerLength();\\n\\n bytes memory publicKeyCoordinates = _publicKey[1:];\\n uint256[2] memory q;\\n assembly {\\n // Copy the bytes from the input data into the uint256 array\\n mstore(q, mload(add(publicKeyCoordinates, 32)))\\n mstore(add(q, 32), mload(add(publicKeyCoordinates, 64)))\\n }\\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\\n .r1Storage();\\n r1Storage.q = q;\\n\\n bytes4 validateSelector = validateOwnerSignatureSelector();\\n\\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\\n if (LibLoupe.facetAddress(validateSelector) != self)\\n revert VerificationFacet__InvalidFacetMapping();\\n\\n // initialize verification function selector\\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\\n\\n initSuccess = 1;\\n\\n emit SignerInitialized(_publicKey);\\n }\\n\\n /**\\n * @notice Uninitialize signer in R1 Facet Storage. This can only be called when the account is undergoing signature migration\\n * and has already been initialized.\\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\\n * @return uninitSuccess Uint value representing the success of uninit operation\\n */\\n function uninitializeSigner()\\n external\\n override\\n returns (uint256 uninitSuccess)\\n {\\n LibAppStorage.enforceSignerMigration();\\n LibAppStorage.setSignerUninitialized();\\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\\n .r1Storage();\\n r1Storage.q = [0, 0];\\n\\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\\n\\n uninitSuccess = 1;\\n\\n emit SignerUninitialized();\\n }\\n\\n /**\\n * @notice Validates if the user operation is signed by the owner.\\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\\n * signer public key.\\n * @param userOp UserOperation including all information for execution\\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\\n */\\n function validateOwnerSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) public view override returns (uint256 validationData) {\\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\\n .r1Storage();\\n validationData = validateSignature(userOp, userOpHash, r1Storage.q);\\n }\\n\\n /**\\n * @notice Validates if the signature of UserOperation is signed by the given signer\\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\\n * @param userOp UserOperation including all information for execution\\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\\n * @param q Public Key of signer who signed the contract, to be validated\\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\\n */\\n function validateSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n uint256[2] memory q\\n ) public view returns (uint256 isValid) {\\n isValid = (_validateSignature(q, userOpHash, userOp.signature)) ? 0 : 1;\\n }\\n\\n /**\\n * @notice Returns the selector of function to validate the signature of UserOperation\\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\\n */\\n function validateOwnerSignatureSelector()\\n public\\n pure\\n override\\n returns (bytes4 ownerSignatureValidatorSelector)\\n {\\n return this.validateOwnerSignature.selector; // validateOwnerSignature(UserOperation calldata userOp,bytes32 userOpHash)\\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\\n }\\n\\n /**\\n * @notice Returns the owner of the account\\n * @return signer Bytes of owner address\\n */\\n function owner() public view override returns (bytes memory signer) {\\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\\n .r1Storage();\\n signer = abi.encodePacked(r1Storage.q);\\n }\\n\\n /**\\n * @notice Validates if the format of public key is valid for this verification facet\\n * @dev For this Secp256k1Verification Facet, the public key should in an uncompressed public key format\\n * @param _publicKey Bytes of public key for format check\\n * @return isValid Boolean variable representing if the format of public key is valid\\n */\\n function isValidKeyType(\\n bytes memory _publicKey\\n ) public pure override returns (bool isValid) {\\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\\n }\\n\\n /**\\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\\n * @param _hash Hash value the owner signed\\n * @param _signature Signature that signed the above hash\\n * @return magicValue Bytes4 value representing the success/failure of validation\\n */\\n function isValidSignature(\\n bytes32 _hash,\\n bytes memory _signature\\n ) public view override returns (bytes4 magicValue) {\\n magicValue = _validateSignature(\\n LibFacetStorage.r1Storage().q,\\n _hash,\\n _signature\\n )\\n ? this.isValidSignature.selector\\n : bytes4(0xffffffff);\\n }\\n\\n function _validateSignature(\\n uint256[2] memory q,\\n bytes32 _hash,\\n bytes memory _signature\\n ) internal view returns (bool) {\\n (\\n uint256 rValue,\\n uint256 sValue,\\n bytes memory authenticatorData,\\n string memory clientDataJSONPre,\\n string memory clientDataJSONPost\\n ) = abi.decode(_signature, (uint256, uint256, bytes, string, string));\\n bytes32 clientHash;\\n {\\n string memory opHashBase64 = Base64.encode(bytes.concat(_hash));\\n string memory clientDataJSON = string.concat(\\n clientDataJSONPre,\\n opHashBase64,\\n clientDataJSONPost\\n );\\n clientHash = sha256(bytes(clientDataJSON));\\n }\\n bytes32 sigHash = sha256(bytes.concat(authenticatorData, clientHash));\\n return LibSecp256r1.Verify(q, rValue, sValue, uint256(sigHash));\\n }\\n}\\n\",\"keccak256\":\"0xdb3bae77323eef4e16ef5a5342f548527c9e82b44e8e9dab90906dc2c00082ff\",\"license\":\"Apache-2.0\"},\"contracts/facets/verification/secp256r1/utils/Base64.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @dev Provides a set of functions to operate with Base64 strings.\\n * modified for base64url https://datatracker.ietf.org/doc/html/rfc4648#section-5\\n * _Available since v4.5._\\n */\\nlibrary Base64 {\\n /**\\n * @dev Base64 Encoding/Decoding Table\\n */\\n string internal constant _TABLE =\\n \\\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_\\\";\\n\\n /**\\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\\n */\\n function encode(bytes memory data) internal pure returns (string memory) {\\n /**\\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\\n */\\n if (data.length == 0) return \\\"\\\";\\n\\n // Loads the table into memory\\n string memory table = _TABLE;\\n\\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\\n // and split into 4 numbers of 6 bits.\\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\\n // - `data.length + 2` -> Round up\\n // - `/ 3` -> Number of 3-bytes chunks\\n // - `4 *` -> 4 characters for each chunk\\n uint256 newlength = (data.length * 8) / 6;\\n if (data.length % 6 > 0) {\\n newlength++;\\n }\\n string memory result = new string(newlength);\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n // Prepare the lookup table (skip the first \\\"length\\\" byte)\\n let tablePtr := add(table, 1)\\n\\n // Prepare result pointer, jump over length\\n let resultPtr := add(result, 32)\\n\\n // Run over the input, 3 bytes at a time\\n for {\\n let dataPtr := data\\n let endPtr := add(data, mload(data))\\n } lt(dataPtr, endPtr) {\\n\\n } {\\n // Advance 3 bytes\\n dataPtr := add(dataPtr, 3)\\n let input := mload(dataPtr)\\n\\n // To write each character, shift the 3 bytes (18 bits) chunk\\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\\n // and apply logical AND with 0x3F which is the number of\\n // the previous character in the ASCII table prior to the Base64 Table\\n // The result is then added to the table to get the character to write,\\n // and finally write it in the result pointer but with a left shift\\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\\n\\n mstore8(\\n resultPtr,\\n mload(add(tablePtr, and(shr(18, input), 0x3F)))\\n )\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(\\n resultPtr,\\n mload(add(tablePtr, and(shr(12, input), 0x3F)))\\n )\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(\\n resultPtr,\\n mload(add(tablePtr, and(shr(6, input), 0x3F)))\\n )\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n }\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0xbf0afa21e5a128f260c1a8d4333dc0b0e8755a50d37dfa9b5d362d36ef9cdc14\",\"license\":\"Apache-2.0\"},\"contracts/facets/verification/secp256r1/utils/LibSecp256r1.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n// Heavily inspired from\\n// https://github.com/maxrobot/elliptic-solidity/blob/master/contracts/Secp256r1.sol\\n// https://github.com/tdrerup/elliptic-curve-solidity/blob/master/contracts/curves/EllipticCurve.sol\\n// modified to use precompile 0x05 modexp\\n// and modified jacobian double\\n// optimisations to avoid to an from from affine and jacobian coordinates\\n\\n// Additional Elliptic curve Public key / Signature validation added by\\n// David Yonjun Kim (@Powerstream3604)\\n\\nstruct JPoint {\\n uint256 x;\\n uint256 y;\\n uint256 z;\\n}\\n\\nlibrary LibSecp256r1 {\\n uint256 constant gx =\\n 0x6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296;\\n uint256 constant gy =\\n 0x4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5;\\n uint256 public constant pp =\\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF;\\n\\n uint256 public constant nn =\\n 0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551;\\n uint256 constant a =\\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC;\\n uint256 constant b =\\n 0x5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B;\\n uint256 constant MOST_SIGNIFICANT =\\n 0xc000000000000000000000000000000000000000000000000000000000000000;\\n\\n /*\\n * Verify\\n * @description - verifies that a public key has signed a given message\\n * @param Q - public key coordinates X & Y\\n * @param R - signature half R\\n * @param S - signature half S\\n * @param input - hashed message\\n */\\n function Verify(\\n uint256[2] memory q,\\n uint r,\\n uint s,\\n uint e\\n ) internal view returns (bool) {\\n if (q[0] > pp - 1 || q[1] > pp - 1) {\\n return false;\\n }\\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\\n return false;\\n }\\n if (\\n mulmod(q[1], q[1], pp) !=\\n addmod(\\n addmod(\\n mulmod(q[0], mulmod(q[0], q[0], pp), pp),\\n mulmod(a, q[0], pp),\\n pp\\n ),\\n b,\\n pp\\n )\\n ) {\\n return false;\\n }\\n\\n JPoint[16] memory points = _preComputeJacobianPoints(q);\\n return VerifyWithPrecompute(points, r, s, e);\\n }\\n\\n function VerifyWithPrecompute(\\n JPoint[16] memory points,\\n uint r,\\n uint s,\\n uint e\\n ) internal view returns (bool) {\\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\\n return false;\\n }\\n\\n uint w = _primemod(s, nn);\\n\\n uint u1 = mulmod(e, w, nn);\\n uint u2 = mulmod(r, w, nn);\\n\\n uint x;\\n uint y;\\n\\n (x, y) = ShamirMultJacobian(points, u1, u2);\\n return (x == r);\\n }\\n\\n /*\\n * Strauss Shamir trick for EC multiplication\\n * https://stackoverflow.com/questions/50993471/ec-scalar-multiplication-with-strauss-shamir-method\\n * we optimise on this a bit to do with 2 bits at a time rather than a single bit\\n * the individual points for a single pass are precomputed\\n * overall this reduces the number of additions while keeping the same number of doublings\\n */\\n function ShamirMultJacobian(\\n JPoint[16] memory points,\\n uint u1,\\n uint u2\\n ) internal view returns (uint, uint) {\\n uint x = 0;\\n uint y = 0;\\n uint z = 0;\\n uint bits = 128;\\n uint index = 0;\\n\\n while (bits > 0) {\\n if (z > 0) {\\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\\n }\\n index =\\n ((u1 & MOST_SIGNIFICANT) >> 252) |\\n ((u2 & MOST_SIGNIFICANT) >> 254);\\n if (index > 0) {\\n (x, y, z) = _jAdd(\\n x,\\n y,\\n z,\\n points[index].x,\\n points[index].y,\\n points[index].z\\n );\\n }\\n u1 <<= 2;\\n u2 <<= 2;\\n bits--;\\n }\\n (x, y) = _affineFromJacobian(x, y, z);\\n return (x, y);\\n }\\n\\n function _preComputeJacobianPoints(\\n uint256[2] memory q\\n ) internal pure returns (JPoint[16] memory points) {\\n points[0] = JPoint(0, 0, 0);\\n points[1] = JPoint(q[0], q[1], 1); // u2\\n points[2] = _jPointDouble(points[1]);\\n points[3] = _jPointAdd(points[1], points[2]);\\n\\n points[4] = JPoint(gx, gy, 1); // u1Points[1]\\n points[5] = _jPointAdd(points[4], points[1]);\\n points[6] = _jPointAdd(points[4], points[2]);\\n points[7] = _jPointAdd(points[4], points[3]);\\n\\n points[8] = _jPointDouble(points[4]); // u1Points[2]\\n points[9] = _jPointAdd(points[8], points[1]);\\n points[10] = _jPointAdd(points[8], points[2]);\\n points[11] = _jPointAdd(points[8], points[3]);\\n\\n points[12] = _jPointAdd(points[4], points[8]); // u1Points[3]\\n points[13] = _jPointAdd(points[12], points[1]);\\n points[14] = _jPointAdd(points[12], points[2]);\\n points[15] = _jPointAdd(points[12], points[3]);\\n }\\n\\n function _jPointAdd(\\n JPoint memory p1,\\n JPoint memory p2\\n ) internal pure returns (JPoint memory) {\\n uint x;\\n uint y;\\n uint z;\\n (x, y, z) = _jAdd(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z);\\n return JPoint(x, y, z);\\n }\\n\\n function _jPointDouble(\\n JPoint memory p\\n ) internal pure returns (JPoint memory) {\\n uint x;\\n uint y;\\n uint z;\\n (x, y, z) = _modifiedJacobianDouble(p.x, p.y, p.z);\\n return JPoint(x, y, z);\\n }\\n\\n /* _affineFromJacobian\\n * @desription returns affine coordinates from a jacobian input follows\\n * golang elliptic/crypto library\\n */\\n function _affineFromJacobian(\\n uint x,\\n uint y,\\n uint z\\n ) internal view returns (uint ax, uint ay) {\\n if (z == 0) {\\n return (0, 0);\\n }\\n\\n uint zinv = _primemod(z, pp);\\n uint zinvsq = mulmod(zinv, zinv, pp);\\n\\n ax = mulmod(x, zinvsq, pp);\\n ay = mulmod(y, mulmod(zinvsq, zinv, pp), pp);\\n }\\n\\n /*\\n * _jAdd\\n * @description performs Jacobian addition as defined below:\\n * http://www.hyperelliptic.org/EFD/g1p/data/shortw/jacobian/addition/add-2007-bl\\n */\\n function _jAdd(\\n uint p1,\\n uint p2,\\n uint p3,\\n uint q1,\\n uint q2,\\n uint q3\\n ) internal pure returns (uint r1, uint r2, uint r3) {\\n if (p3 == 0) {\\n r1 = q1;\\n r2 = q2;\\n r3 = q3;\\n\\n return (r1, r2, r3);\\n } else if (q3 == 0) {\\n r1 = p1;\\n r2 = p2;\\n r3 = p3;\\n\\n return (r1, r2, r3);\\n }\\n\\n assembly {\\n let\\n pd\\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\\n let z1z1 := mulmod(p3, p3, pd) // Z1Z1 = Z1^2\\n let z2z2 := mulmod(q3, q3, pd) // Z2Z2 = Z2^2\\n\\n let u1 := mulmod(p1, z2z2, pd) // U1 = X1*Z2Z2\\n let u2 := mulmod(q1, z1z1, pd) // U2 = X2*Z1Z1\\n\\n let s1 := mulmod(p2, mulmod(z2z2, q3, pd), pd) // S1 = Y1*Z2*Z2Z2\\n let s2 := mulmod(q2, mulmod(z1z1, p3, pd), pd) // S2 = Y2*Z1*Z1Z1\\n\\n let p3q3 := addmod(p3, q3, pd)\\n\\n if lt(u2, u1) {\\n u2 := add(pd, u2) // u2 = u2+pd\\n }\\n let h := sub(u2, u1) // H = U2-U1\\n\\n let i := mulmod(0x02, h, pd)\\n i := mulmod(i, i, pd) // I = (2*H)^2\\n\\n let j := mulmod(h, i, pd) // J = H*I\\n if lt(s2, s1) {\\n s2 := add(pd, s2) // u2 = u2+pd\\n }\\n let rr := mulmod(0x02, sub(s2, s1), pd) // r = 2*(S2-S1)\\n r1 := mulmod(rr, rr, pd) // X3 = R^2\\n\\n let v := mulmod(u1, i, pd) // V = U1*I\\n let j2v := addmod(j, mulmod(0x02, v, pd), pd)\\n if lt(r1, j2v) {\\n r1 := add(pd, r1) // X3 = X3+pd\\n }\\n r1 := sub(r1, j2v)\\n\\n // Y3 = r*(V-X3)-2*S1*J\\n let s12j := mulmod(mulmod(0x02, s1, pd), j, pd)\\n\\n if lt(v, r1) {\\n v := add(pd, v)\\n }\\n r2 := mulmod(rr, sub(v, r1), pd)\\n\\n if lt(r2, s12j) {\\n r2 := add(pd, r2)\\n }\\n r2 := sub(r2, s12j)\\n\\n // Z3 = ((Z1+Z2)^2-Z1Z1-Z2Z2)*H\\n z1z1 := addmod(z1z1, z2z2, pd)\\n j2v := mulmod(p3q3, p3q3, pd)\\n if lt(j2v, z1z1) {\\n j2v := add(pd, j2v)\\n }\\n r3 := mulmod(sub(j2v, z1z1), h, pd)\\n }\\n return (r1, r2, r3);\\n }\\n\\n // Point doubling on the modified jacobian coordinates\\n // http://point-at-infinity.org/ecc/Prime_Curve_Modified_Jacobian_Coordinates.html\\n function _modifiedJacobianDouble(\\n uint x,\\n uint y,\\n uint z\\n ) internal pure returns (uint x3, uint y3, uint z3) {\\n if (y == 0) return (0, 0, 0);\\n assembly {\\n let\\n pd\\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\\n let z2 := mulmod(z, z, pd)\\n let az4 := mulmod(\\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC,\\n mulmod(z2, z2, pd),\\n pd\\n )\\n let y2 := mulmod(y, y, pd)\\n let s := mulmod(0x04, mulmod(x, y2, pd), pd)\\n let u := mulmod(0x08, mulmod(y2, y2, pd), pd)\\n let m := addmod(mulmod(0x03, mulmod(x, x, pd), pd), az4, pd)\\n let twos := mulmod(0x02, s, pd)\\n let m2 := mulmod(m, m, pd)\\n if lt(m2, twos) {\\n m2 := add(pd, m2)\\n }\\n x3 := sub(m2, twos)\\n if lt(s, x3) {\\n s := add(pd, s)\\n }\\n y3 := mulmod(m, sub(s, x3), pd)\\n if lt(y3, u) {\\n y3 := add(pd, y3)\\n }\\n y3 := sub(y3, u)\\n z3 := mulmod(0x02, mulmod(y, z, pd), pd)\\n }\\n }\\n\\n // Fermats little theorem https://en.wikipedia.org/wiki/Fermat%27s_little_theorem\\n // a^(p-1) = 1 mod p\\n // a^(-1) \\u2245 a^(p-2) (mod p)\\n // we then use the precompile bigModExp to compute a^(-1)\\n function _primemod(uint value, uint p) internal view returns (uint ret) {\\n ret = modexp(value, p - 2, p);\\n return ret;\\n }\\n\\n // Wrapper for built-in BigNumber_modexp (contract 0x5) as described here. https://github.com/ethereum/EIPs/pull/198\\n function modexp(\\n uint _base,\\n uint _exp,\\n uint _mod\\n ) internal view returns (uint ret) {\\n // bigModExp(_base, _exp, _mod);\\n assembly {\\n if gt(_base, _mod) {\\n _base := mod(_base, _mod)\\n }\\n // Free memory pointer is always stored at 0x40\\n let freemem := mload(0x40)\\n\\n mstore(freemem, 0x20)\\n mstore(add(freemem, 0x20), 0x20)\\n mstore(add(freemem, 0x40), 0x20)\\n\\n mstore(add(freemem, 0x60), _base)\\n mstore(add(freemem, 0x80), _exp)\\n mstore(add(freemem, 0xa0), _mod)\\n\\n let success := staticcall(14000, 0x5, freemem, 0xc0, freemem, 0x20)\\n switch success\\n case 0 {\\n revert(0x0, 0x0)\\n }\\n default {\\n ret := mload(freemem)\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb53714ba63cddb379ba312c1e7f6a423f4d7a7e34fa1364ec8295cd57d544024\",\"license\":\"GPL-3.0\"},\"contracts/infrastructure/interfaces/IFacetRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Registry Interface\\n * @dev Interface for Facet Registry contract to keep track of facets & function selectors addable to user wallets\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IFacetRegistry {\\n struct FacetRegistryConfig {\\n bytes4[] selectors;\\n mapping(bytes4 => FacetInfo) info;\\n }\\n struct FacetInfo {\\n bool exists;\\n uint128 index;\\n }\\n\\n event FacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] facetSelectors\\n );\\n event FacetFunctionSelectorsRemoved(address facet, bytes4[] facetSelectors);\\n\\n error FacetRegistry__FacetSelectorAlreadyRegistered();\\n error FacetRegistry__UnregisteredFacetSelector();\\n\\n function registerFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function removeFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function areFacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external view returns (bool);\\n\\n function isFacetFunctionSelectorRegistered(\\n address facet,\\n bytes4 facetSelector\\n ) external view returns (bool);\\n\\n function getFacetFunctionSelectors(\\n address facet\\n ) external view returns (bytes4[] memory);\\n}\\n\",\"keccak256\":\"0x6e6dd2cab346ef7c31230740ec48d2925e4a9ab24c2f2fb268baaf408dcf02ef\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC1271 {\\n function isValidSignature(\\n bytes32 hash,\\n bytes memory signature\\n ) external view returns (bytes4);\\n}\\n\",\"keccak256\":\"0xcdddb7d5641c9d3f2432dec7fd13fddb9ae1480f25c76c21511e2fa16b8bd422\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibAppStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {SafeCast} from \\\"@openzeppelin/contracts/utils/math/SafeCast.sol\\\";\\nimport {IEntryPoint} from \\\"../aa-4337/interfaces/IEntryPoint.sol\\\";\\nimport {IFacetRegistry} from \\\"../infrastructure/interfaces/IFacetRegistry.sol\\\";\\n\\n/*\\n * @title App Storage\\n * @dev App storage for Barz contract to prevent storage collision\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Lock {\\n uint64 release;\\n bytes4 locker;\\n}\\n\\nstruct InitializersStorage {\\n // NOTE: initialized is a variable to make sure the initialization is only done once.\\n uint8 signerInitialized;\\n uint8 accountInitialized;\\n uint8 restrictionsInitialized;\\n}\\n\\nstruct AppStorage {\\n mapping(uint256 => InitializersStorage) initStorage;\\n uint8 signerMigration;\\n bytes4 validateOwnerSignatureSelector;\\n IEntryPoint entryPoint;\\n IFacetRegistry facetRegistry;\\n mapping(uint256 => Lock) locks;\\n}\\n\\nlibrary LibAppStorage {\\n error LibAppStorage__AccountAlreadyUninitialized();\\n error LibAppStorage__AccountMustBeUninitialized();\\n error LibAppStorage__SignerAlreadyUninitialized();\\n error LibAppStorage__SignerMustBeUninitialized();\\n\\n function appStorage() internal pure returns (AppStorage storage ds) {\\n assembly {\\n ds.slot := 0\\n }\\n }\\n\\n function setSignerUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerAlreadyUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 0;\\n }\\n\\n function getValidateOwnerSignatureSelector()\\n internal\\n view\\n returns (bytes4 selector)\\n {\\n selector = appStorage().validateOwnerSignatureSelector;\\n }\\n\\n function setValidateOwnerSignatureSelector(\\n bytes4 _validateOwnerSignatureSelector\\n ) internal {\\n appStorage()\\n .validateOwnerSignatureSelector = _validateOwnerSignatureSelector;\\n }\\n\\n function enforceSignerInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerMustBeUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 1;\\n }\\n\\n function enforceAccountInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].accountInitialized) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n s.initStorage[0].accountInitialized = 1;\\n }\\n\\n function initiateSignerMigration() internal {\\n appStorage().signerMigration = 1;\\n }\\n\\n function enforceSignerMigration() internal view {\\n if (1 != appStorage().signerMigration) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n }\\n\\n function finalizeSignerMigration() internal {\\n appStorage().signerMigration = 0;\\n }\\n\\n function setLock(uint256 _releaseAfter, bytes4 _locker) internal {\\n appStorage().locks[0] = Lock(SafeCast.toUint64(_releaseAfter), _locker);\\n }\\n\\n function enforceRestrictionsInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__SignerMustBeUninitialized();\\n s.initStorage[0].restrictionsInitialized = 1;\\n }\\n\\n function setRestrictionsUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__AccountAlreadyUninitialized();\\n s.initStorage[0].restrictionsInitialized = 0;\\n }\\n}\\n\\ncontract BarzStorage {\\n AppStorage internal s;\\n modifier onlyWhenUnlocked() {\\n require(\\n uint64(block.timestamp) >= s.locks[0].release,\\n \\\"Account Locked\\\"\\n );\\n _;\\n }\\n modifier onlyWhenLocked() {\\n require(\\n uint64(block.timestamp) < s.locks[0].release,\\n \\\"Account Unlocked\\\"\\n );\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x48524007862a6ce0e07f645950613ce6513ce073c37a109c75019683d42bae27\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\\n bytes4(keccak256(\\\"verifyRestrictions(address,address,uint256,bytes)\\\"));\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // Default Fallback Handler of the barz.\\n IDiamondLoupe defaultFallbackHandler;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function enforceIsSelf() internal view {\\n require(msg.sender == address(this), \\\"LibDiamond: Caller not self\\\");\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n\\n unchecked {\\n facetIndex++;\\n }\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n\\n function restrictionsFacet() internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(\\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2cabdc00de859c3a3170ce3bda5d0e5fd3933d47ce904fd1585f9818b02572f8\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibFacetStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Storage\\n * @dev Storage contract to store each facets variables with diamond storage\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Secp256k1VerificationStorage {\\n address signer;\\n}\\n\\nstruct Secp256r1VerificationStorage {\\n uint256[2] q;\\n}\\n\\nstruct GuardianStorage {\\n mapping(bytes32 => uint256) pending;\\n mapping(uint8 => StorageConfig) configs;\\n}\\n\\nstruct Info {\\n bool exists;\\n uint128 index;\\n}\\n\\nstruct StorageConfig {\\n address[] addresses;\\n mapping(address => Info) info;\\n}\\n\\nstruct RecoveryConfig {\\n bytes recoveryPublicKey;\\n uint64 executeAfter;\\n}\\n\\nstruct ApprovalConfig {\\n bool isApproved;\\n uint64 validUntil;\\n}\\n\\nstruct RecoveryApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isNewOwnerApproved;\\n}\\n\\nstruct RecoveryStorage {\\n mapping(uint8 => RecoveryConfig) recoveryConfigs;\\n mapping(uint8 => RecoveryApprovalConfig) recoveryApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct RestrictionsStorage {\\n address[] restrictions;\\n mapping(address => bool) exists;\\n}\\n\\nstruct SignatureMigrationConfig {\\n bytes migrationPublicKey;\\n address migrationVerificationFacet;\\n bytes4[] migrationSelectors;\\n uint64 migrateAfter;\\n}\\n\\nstruct SignatureMigrationApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isMigrationApproved;\\n}\\n\\nstruct SignatureMigrationStorage {\\n mapping(uint8 => SignatureMigrationConfig) migrationConfigs;\\n mapping(uint8 => SignatureMigrationApprovalConfig) migrationApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct DiamondCutApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isDiamondCutApproved;\\n}\\n\\nstruct DiamondCutStorage {\\n mapping(uint8 => DiamondCutApprovalConfig) diamondCutApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct LockStorage {\\n uint128 nonce;\\n}\\n\\nlibrary LibFacetStorage {\\n bytes32 constant K1_STORAGE_POSITION =\\n keccak256(\\n \\\"v0.trustwallet.diamond.storage.Secp256k1VerificationStorage\\\"\\n );\\n bytes32 constant R1_STORAGE_POSITION =\\n keccak256(\\n \\\"v0.trustwallet.diamond.storage.Secp256r1VerificationStorage\\\"\\n );\\n bytes32 constant GUARDIAN_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.GuardianStorage\\\");\\n bytes32 constant RECOVERY_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.RecoveryStorage\\\");\\n bytes32 constant RESTRICTION_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.RestrictionsStorage\\\");\\n bytes32 constant MIGRATION_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.SignatureMigrationStorage\\\");\\n bytes32 constant DIAMONDCUT_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.DiamondCutStorage\\\");\\n bytes32 constant LOCK_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.LockStorage\\\");\\n\\n function k1Storage()\\n internal\\n pure\\n returns (Secp256k1VerificationStorage storage ds)\\n {\\n bytes32 storagePosition = K1_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function r1Storage()\\n internal\\n pure\\n returns (Secp256r1VerificationStorage storage ds)\\n {\\n bytes32 storagePosition = R1_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function guardianStorage()\\n internal\\n pure\\n returns (GuardianStorage storage ds)\\n {\\n bytes32 storagePosition = GUARDIAN_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function recoveryStorage()\\n internal\\n pure\\n returns (RecoveryStorage storage ds)\\n {\\n bytes32 storagePosition = RECOVERY_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function restrictionsStorage()\\n internal\\n pure\\n returns (RestrictionsStorage storage ds)\\n {\\n bytes32 storagePosition = RESTRICTION_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function migrationStorage()\\n internal\\n pure\\n returns (SignatureMigrationStorage storage ds)\\n {\\n bytes32 storagePosition = MIGRATION_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function diamondCutStorage()\\n internal\\n pure\\n returns (DiamondCutStorage storage ds)\\n {\\n bytes32 storagePosition = DIAMONDCUT_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function lockStorage() internal pure returns (LockStorage storage ds) {\\n bytes32 storagePosition = LOCK_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n}\\n\",\"keccak256\":\"0x87c85decfd943deda9540733e464cb1a92eba735a301e89ce6f798016e359761\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\nimport {LibDiamond} from \\\"./LibDiamond.sol\\\";\\n\\n/**\\n * @title LibLoupe\\n * @dev Internal Library to provide utility feature for reading the state of diamond facets\\n * Originally from Diamond's implementation of Mudgen(author of EIP-2535)\\n */\\nlibrary LibLoupe {\\n /// @notice Gets all facets and their selectors.\\n /// @return facets_ Facet\\n function facets()\\n internal\\n view\\n returns (IDiamondLoupe.Facet[] memory facets_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facets_ = new IDiamondLoupe.Facet[](ds.selectorCount);\\n uint16[] memory numFacetSelectors = new uint16[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facets_[facetIndex].facetAddress == facetAddress_) {\\n facets_[facetIndex].functionSelectors[\\n numFacetSelectors[facetIndex]\\n ] = selector;\\n // probably will never have more than 256 functions from one facet contract\\n require(numFacetSelectors[facetIndex] < 255);\\n numFacetSelectors[facetIndex]++;\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facets_[numFacets].facetAddress = facetAddress_;\\n facets_[numFacets].functionSelectors = new bytes4[](\\n ds.selectorCount\\n );\\n facets_[numFacets].functionSelectors[0] = selector;\\n numFacetSelectors[numFacets] = 1;\\n numFacets++;\\n }\\n }\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n uint256 numSelectors = numFacetSelectors[facetIndex];\\n bytes4[] memory selectors = facets_[facetIndex].functionSelectors;\\n // setting the number of selectors\\n assembly {\\n mstore(selectors, numSelectors)\\n }\\n }\\n // setting the number of facets\\n assembly {\\n mstore(facets_, numFacets)\\n }\\n }\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return _facetFunctionSelectors The selectors associated with a facet address.\\n function facetFunctionSelectors(\\n address _facet\\n ) internal view returns (bytes4[] memory _facetFunctionSelectors) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n uint256 numSelectors;\\n _facetFunctionSelectors = new bytes4[](ds.selectorCount);\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facet = address(bytes20(ds.facets[selector]));\\n if (_facet == facet) {\\n _facetFunctionSelectors[numSelectors] = selector;\\n numSelectors++;\\n }\\n }\\n }\\n // Set the number of selectors in the array\\n assembly {\\n mstore(_facetFunctionSelectors, numSelectors)\\n }\\n }\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n internal\\n view\\n returns (address[] memory facetAddresses_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetAddresses_ = new address[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facetAddress_ == facetAddresses_[facetIndex]) {\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facetAddresses_[numFacets] = facetAddress_;\\n numFacets++;\\n }\\n }\\n // Set the number of facet addresses in the array\\n assembly {\\n mstore(facetAddresses_, numFacets)\\n }\\n }\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(LibDiamond.diamondStorage().facets[_functionSelector])\\n );\\n }\\n}\\n\",\"keccak256\":\"0x0b11439c3cc657095e15ec2241fdcf67204b14001357b612fc5db4ff9e760a5a\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x60a060405234801561001057600080fd5b50610019610022565b3060805261008b565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff161561006f57604051637c2cde8b60e01b815260040160405180910390fd5b600080805260209190915260409020805460ff19166001179055565b608051611f746100ad6000396000818161016001526106e10152611f746000f3fe608060405234801561001057600080fd5b50600436106100a35760003560e01c80637104ddb2116100765780638dd501211161005b5780638dd50121146101bc578063cd00e50a146101cf578063cd9b47e4146101d757600080fd5b80637104ddb21461015b5780638da5cb5b146101a757600080fd5b806311cfe388146100a85780631626ba7e146100ce5780633253960f14610112578063392dd6d914610138575b600080fd5b6100bb6100b6366004611823565b6101ea565b6040519081526020015b60405180910390f35b6100e16100dc366004611956565b610252565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020016100c5565b7f8dd50121000000000000000000000000000000000000000000000000000000006100e1565b61014b61014636600461199d565b6102fd565b60405190151581526020016100c5565b6101827f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100c5565b6101af61036f565b6040516100c591906119f6565b6100bb6101ca366004611a47565b6103ba565b6100bb61041f565b6100bb6101e5366004611a8c565b61053a565b600061023982846101ff610140880188611afe565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061083692505050565b610244576001610247565b60005b60ff16949350505050565b60006102aa7f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b1653646040805180820191829052919060029082845b81548152602001906001019080831161028b5750505050508484610836565b6102d4577fffffffff000000000000000000000000000000000000000000000000000000006102f6565b7f1626ba7e000000000000000000000000000000000000000000000000000000005b9392505050565b60008151604114801561036957508160008151811061031e5761031e611b6a565b6020910101517fff00000000000000000000000000000000000000000000000000000000000000167f0400000000000000000000000000000000000000000000000000000000000000145b92915050565b6040516060907f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364906103a5908290602001611b99565b60405160208183030381529060405291505090565b60408051808201918290526000917f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364916104179186918691859060029082845b8154815260200190600101908083116103fa5750505050506101ea565b949350505050565b60006104296109b4565b6104316109f4565b60408051808201909152600080825260208201527f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364906104749082906002611675565b506000610488600154610100900460e01b90565b7fffffffff0000000000000000000000000000000000000000000000000000000016036104e1576040517f127c609a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff169055604051600192507fcccd30db6bc000b8bb8d11162228d2d69e3c361983ca3ae8c1365ce64b0fae9e90600090a15090565b6000610544610a93565b61058383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102fd92505050565b6105b9576040517f6c334d2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006105c88360018187611bcd565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092935061060992506116b8915050565b602082015181526040820151602082015260006106437f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b16536490565b9050610651818360026116d6565b507f8dd50121000000000000000000000000000000000000000000000000000000006000610686600154610100900460e01b90565b7fffffffff0000000000000000000000000000000000000000000000000000000016146106df576040517f5f95a63c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16610770827fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604090205460601c90565b73ffffffffffffffffffffffffffffffffffffffff16146107bd576040517fbb4752b700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff1661010060e084901c02179055600194507f6d54821a69ec281ed7ba1bf2729c700768c47df1d80fad646b0a14cc1d5c39ed8787604051610824929190611bf7565b60405180910390a15050505092915050565b600080600080600080868060200190518101906108539190611c94565b9450945094509450945060008061088a8a60405160200161087691815260200190565b604051602081830303815290604052610b33565b905060008482856040516020016108a393929190611d47565b60405160208183030381529060405290506002816040516108c49190611d8a565b602060405180830381855afa1580156108e1573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906109049190611da6565b9250505060006002858360405160200161091f929190611dbf565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905261095791611d8a565b602060405180830381855afa158015610974573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906109979190611da6565b90506109a58b888884610c6f565b9b9a5050505050505050505050565b6001805460ff16146109f2576040517f38fc28cb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff16600114610a5c576040517fe00d7c7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff1615610af9576040517f7c2cde8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b60608151600003610b5257505060408051602081019091526000815290565b6000604051806060016040528060408152602001611eff6040913990506000600684516008610b819190611e10565b610b8b9190611e56565b9050600060068551610b9d9190611e6a565b1115610bb15780610bad81611e7e565b9150505b60008167ffffffffffffffff811115610bcc57610bcc61177c565b6040519080825280601f01601f191660200182016040528015610bf6576020820181803683370190505b509050600183016020820186875188015b80821015610c62576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f8116850151845350600183019250610c07565b5092979650505050505050565b6000610c9c60017fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611eb6565b85511180610cd75750610cd060017fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611eb6565b6020860151115b15610ce457506000610417565b831580610cef575082155b80610d1a57507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518410155b80610d4557507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518310155b15610d5257506000610417565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff7f5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff8088600060200201517fffffffff00000001000000000000000000000000fffffffffffffffffffffffc0988517fffffffff00000001000000000000000000000000ffffffffffffffffffffffff90819080098a5109080860208601517fffffffff00000001000000000000000000000000ffffffffffffffffffffffff90800914610e4357506000610417565b6000610e4e86610e66565b9050610e5c81868686611062565b9695505050505050565b610e6e611704565b60405180606001604052806000815260200160008152602001600081525081600060108110610e9f57610e9f611b6a565b60200201526040805160608101909152808360006020020151815260200183600160028110610ed057610ed0611b6a565b60200201518152602001600181525081600160108110610ef257610ef2611b6a565b6020020152610f088160015b602002015161116f565b6040820152610f278160015b60200201518260025b60200201516111d1565b6060828101919091526040805191820181527f6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c29682527f4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f560208301526001908201526080820152610fa18160045b6020020151826001610f1d565b60a0820152610fb1816004610f14565b60c0820152610fca8160045b6020020151826003610f1d565b60e0820152610fda816004610efe565b610100820152610feb816008610f94565b610120820152610ffc816008610f14565b61014082015261100d816008610fbd565b610160820152608081015161102490826008610f1d565b61018082015261103581600c610f94565b6101a082015261104681600c610f14565b6101c082015261105781600c610fbd565b6101e0820152919050565b600083158061106f575082155b8061109a57507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518410155b806110c557507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518310155b156110d257506000610417565b60006110fe847fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551611243565b905060007fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551828509905060007fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551838809905060008061115e8a858561125a565b509098149998505050505050505050565b61119360405180606001604052806000815260200160008152602001600081525090565b60008060006111af856000015186602001518760400151611346565b6040805160608101825293845260208401929092529082015295945050505050565b6111f560405180606001604052806000815260200160008152602001600081525090565b6000806000611220866000015187602001518860400151886000015189602001518a60400151611424565b604080516060810182529384526020840192909252908201529695505050505050565b60006102f683611254600285611eb6565b8461155c565b6000808080806080815b81156113285782156112955761127b858585611346565b9196509450925061128d858585611346565b919650945092505b50600c60fc89901c1660fe88901c17801561130b576113038585858d85601081106112c2576112c2611b6a565b6020020151518e86601081106112da576112da611b6a565b6020020151602001518f87601081106112f5576112f5611b6a565b602002015160400151611424565b919650945092505b600298891b989790971b968161132081611ec9565b925050611264565b6113338585856115b0565b909750955050505050505b935093915050565b6000806000846000036113615750600091508190508061141b565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff8085860981828283097fffffffff00000001000000000000000000000000fffffffffffffffffffffffc099050818788098283828b0960040983848384096008099150838385868d8e09600309089250838160020984848509818110156113e65785015b039650868110156113f45783015b8387820384099550508085101561140a57938201935b909303925080808688096002099150505b93509350939050565b60008060008660000361143e575084915083905082611550565b83600003611453575087915086905085611550565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff808889098186870982818d0983838b0984858a85098e0985868e87098c09868b8f08848410156114a357928701925b8484039350878460020988818209905088818609848410156114c457928901925b898585036002099350898485099c50898288099650898a8860020982089150818d10156114f0579b89019b5b818d039c5089818b87600209099450508b86101561150d57948801945b888c870384099a50838b101561152257998801995b838b039a508887890897508882830990508781101561153e5788015b88858983030999505050505050505050505b96509650969350505050565b60008184111561156c5781840693505b60405160208152602080820152602060408201528460608201528360808201528260a082015260208160c08360056136b0fa8080156100a357505051949350505050565b600080826000036115c65750600090508061133e565b60006115f2847fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611243565b905060007fffffffff00000001000000000000000000000000ffffffffffffffffffffffff82830990507fffffffff00000001000000000000000000000000ffffffffffffffffffffffff81880993507fffffffff00000001000000000000000000000000ffffffffffffffffffffffff80838309870992505050935093915050565b82600281019282156116a8579160200282015b828111156116a8578251829060ff16905591602001919060010190611688565b506116b492915061174e565b5090565b60405180604001604052806002906020820280368337509192915050565b82600281019282156116a8579160200282015b828111156116a85782518255916020019190600101906116e9565b6040518061020001604052806010905b61173860405180606001604052806000815260200160008152602001600081525090565b8152602001906001900390816117145790505090565b5b808211156116b4576000815560010161174f565b6000610160828403121561177657600080fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156117ce576117ce61177c565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561181b5761181b61177c565b604052919050565b60008060006080848603121561183857600080fd5b833567ffffffffffffffff81111561184f57600080fd5b61185b86828701611763565b935050602080850135925085605f86011261187557600080fd5b61187d6117ab565b80608087018881111561188f57600080fd5b604088015b818110156118ab5780358452928401928401611894565b50508093505050509250925092565b600067ffffffffffffffff8211156118d4576118d461177c565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261191157600080fd5b813561192461191f826118ba565b6117d4565b81815284602083860101111561193957600080fd5b816020850160208301376000918101602001919091529392505050565b6000806040838503121561196957600080fd5b82359150602083013567ffffffffffffffff81111561198757600080fd5b61199385828601611900565b9150509250929050565b6000602082840312156119af57600080fd5b813567ffffffffffffffff8111156119c657600080fd5b61041784828501611900565b60005b838110156119ed5781810151838201526020016119d5565b50506000910152565b6020815260008251806020840152611a158160408501602087016119d2565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b60008060408385031215611a5a57600080fd5b823567ffffffffffffffff811115611a7157600080fd5b611a7d85828601611763565b95602094909401359450505050565b60008060208385031215611a9f57600080fd5b823567ffffffffffffffff80821115611ab757600080fd5b818501915085601f830112611acb57600080fd5b813581811115611ada57600080fd5b866020828501011115611aec57600080fd5b60209290920196919550909350505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112611b3357600080fd5b83018035915067ffffffffffffffff821115611b4e57600080fd5b602001915036819003821315611b6357600080fd5b9250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008183825b6002811015611bbe578154835260209092019160019182019101611b9f565b50505060408201905092915050565b60008085851115611bdd57600080fd5b83861115611bea57600080fd5b5050820193919092039150565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b6000611c5261191f846118ba565b9050828152838383011115611c6657600080fd5b6102f68360208301846119d2565b600082601f830112611c8557600080fd5b6102f683835160208501611c44565b600080600080600060a08688031215611cac57600080fd5b8551945060208601519350604086015167ffffffffffffffff80821115611cd257600080fd5b818801915088601f830112611ce657600080fd5b611cf589835160208501611c44565b94506060880151915080821115611d0b57600080fd5b611d1789838a01611c74565b93506080880151915080821115611d2d57600080fd5b50611d3a88828901611c74565b9150509295509295909350565b60008451611d598184602089016119d2565b845190830190611d6d8183602089016119d2565b8451910190611d808183602088016119d2565b0195945050505050565b60008251611d9c8184602087016119d2565b9190910192915050565b600060208284031215611db857600080fd5b5051919050565b60008351611dd18184602088016119d2565b9190910191825250602001919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808202811582820484141761036957610369611de1565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082611e6557611e65611e27565b500490565b600082611e7957611e79611e27565b500690565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611eaf57611eaf611de1565b5060010190565b8181038181111561036957610369611de1565b600081611ed857611ed8611de1565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392d5fa2646970667358221220d4142da7b16effb6b95f41adeff2bc8ce0d59d3b70ca8d55e6e83224bbfbec0a64736f6c63430008150033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100a35760003560e01c80637104ddb2116100765780638dd501211161005b5780638dd50121146101bc578063cd00e50a146101cf578063cd9b47e4146101d757600080fd5b80637104ddb21461015b5780638da5cb5b146101a757600080fd5b806311cfe388146100a85780631626ba7e146100ce5780633253960f14610112578063392dd6d914610138575b600080fd5b6100bb6100b6366004611823565b6101ea565b6040519081526020015b60405180910390f35b6100e16100dc366004611956565b610252565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020016100c5565b7f8dd50121000000000000000000000000000000000000000000000000000000006100e1565b61014b61014636600461199d565b6102fd565b60405190151581526020016100c5565b6101827f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100c5565b6101af61036f565b6040516100c591906119f6565b6100bb6101ca366004611a47565b6103ba565b6100bb61041f565b6100bb6101e5366004611a8c565b61053a565b600061023982846101ff610140880188611afe565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061083692505050565b610244576001610247565b60005b60ff16949350505050565b60006102aa7f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b1653646040805180820191829052919060029082845b81548152602001906001019080831161028b5750505050508484610836565b6102d4577fffffffff000000000000000000000000000000000000000000000000000000006102f6565b7f1626ba7e000000000000000000000000000000000000000000000000000000005b9392505050565b60008151604114801561036957508160008151811061031e5761031e611b6a565b6020910101517fff00000000000000000000000000000000000000000000000000000000000000167f0400000000000000000000000000000000000000000000000000000000000000145b92915050565b6040516060907f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364906103a5908290602001611b99565b60405160208183030381529060405291505090565b60408051808201918290526000917f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364916104179186918691859060029082845b8154815260200190600101908083116103fa5750505050506101ea565b949350505050565b60006104296109b4565b6104316109f4565b60408051808201909152600080825260208201527f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364906104749082906002611675565b506000610488600154610100900460e01b90565b7fffffffff0000000000000000000000000000000000000000000000000000000016036104e1576040517f127c609a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff169055604051600192507fcccd30db6bc000b8bb8d11162228d2d69e3c361983ca3ae8c1365ce64b0fae9e90600090a15090565b6000610544610a93565b61058383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102fd92505050565b6105b9576040517f6c334d2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006105c88360018187611bcd565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092935061060992506116b8915050565b602082015181526040820151602082015260006106437f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b16536490565b9050610651818360026116d6565b507f8dd50121000000000000000000000000000000000000000000000000000000006000610686600154610100900460e01b90565b7fffffffff0000000000000000000000000000000000000000000000000000000016146106df576040517f5f95a63c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16610770827fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604090205460601c90565b73ffffffffffffffffffffffffffffffffffffffff16146107bd576040517fbb4752b700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff1661010060e084901c02179055600194507f6d54821a69ec281ed7ba1bf2729c700768c47df1d80fad646b0a14cc1d5c39ed8787604051610824929190611bf7565b60405180910390a15050505092915050565b600080600080600080868060200190518101906108539190611c94565b9450945094509450945060008061088a8a60405160200161087691815260200190565b604051602081830303815290604052610b33565b905060008482856040516020016108a393929190611d47565b60405160208183030381529060405290506002816040516108c49190611d8a565b602060405180830381855afa1580156108e1573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906109049190611da6565b9250505060006002858360405160200161091f929190611dbf565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905261095791611d8a565b602060405180830381855afa158015610974573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906109979190611da6565b90506109a58b888884610c6f565b9b9a5050505050505050505050565b6001805460ff16146109f2576040517f38fc28cb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff16600114610a5c576040517fe00d7c7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff1615610af9576040517f7c2cde8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b60608151600003610b5257505060408051602081019091526000815290565b6000604051806060016040528060408152602001611eff6040913990506000600684516008610b819190611e10565b610b8b9190611e56565b9050600060068551610b9d9190611e6a565b1115610bb15780610bad81611e7e565b9150505b60008167ffffffffffffffff811115610bcc57610bcc61177c565b6040519080825280601f01601f191660200182016040528015610bf6576020820181803683370190505b509050600183016020820186875188015b80821015610c62576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f8116850151845350600183019250610c07565b5092979650505050505050565b6000610c9c60017fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611eb6565b85511180610cd75750610cd060017fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611eb6565b6020860151115b15610ce457506000610417565b831580610cef575082155b80610d1a57507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518410155b80610d4557507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518310155b15610d5257506000610417565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff7f5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff8088600060200201517fffffffff00000001000000000000000000000000fffffffffffffffffffffffc0988517fffffffff00000001000000000000000000000000ffffffffffffffffffffffff90819080098a5109080860208601517fffffffff00000001000000000000000000000000ffffffffffffffffffffffff90800914610e4357506000610417565b6000610e4e86610e66565b9050610e5c81868686611062565b9695505050505050565b610e6e611704565b60405180606001604052806000815260200160008152602001600081525081600060108110610e9f57610e9f611b6a565b60200201526040805160608101909152808360006020020151815260200183600160028110610ed057610ed0611b6a565b60200201518152602001600181525081600160108110610ef257610ef2611b6a565b6020020152610f088160015b602002015161116f565b6040820152610f278160015b60200201518260025b60200201516111d1565b6060828101919091526040805191820181527f6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c29682527f4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f560208301526001908201526080820152610fa18160045b6020020151826001610f1d565b60a0820152610fb1816004610f14565b60c0820152610fca8160045b6020020151826003610f1d565b60e0820152610fda816004610efe565b610100820152610feb816008610f94565b610120820152610ffc816008610f14565b61014082015261100d816008610fbd565b610160820152608081015161102490826008610f1d565b61018082015261103581600c610f94565b6101a082015261104681600c610f14565b6101c082015261105781600c610fbd565b6101e0820152919050565b600083158061106f575082155b8061109a57507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518410155b806110c557507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518310155b156110d257506000610417565b60006110fe847fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551611243565b905060007fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551828509905060007fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551838809905060008061115e8a858561125a565b509098149998505050505050505050565b61119360405180606001604052806000815260200160008152602001600081525090565b60008060006111af856000015186602001518760400151611346565b6040805160608101825293845260208401929092529082015295945050505050565b6111f560405180606001604052806000815260200160008152602001600081525090565b6000806000611220866000015187602001518860400151886000015189602001518a60400151611424565b604080516060810182529384526020840192909252908201529695505050505050565b60006102f683611254600285611eb6565b8461155c565b6000808080806080815b81156113285782156112955761127b858585611346565b9196509450925061128d858585611346565b919650945092505b50600c60fc89901c1660fe88901c17801561130b576113038585858d85601081106112c2576112c2611b6a565b6020020151518e86601081106112da576112da611b6a565b6020020151602001518f87601081106112f5576112f5611b6a565b602002015160400151611424565b919650945092505b600298891b989790971b968161132081611ec9565b925050611264565b6113338585856115b0565b909750955050505050505b935093915050565b6000806000846000036113615750600091508190508061141b565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff8085860981828283097fffffffff00000001000000000000000000000000fffffffffffffffffffffffc099050818788098283828b0960040983848384096008099150838385868d8e09600309089250838160020984848509818110156113e65785015b039650868110156113f45783015b8387820384099550508085101561140a57938201935b909303925080808688096002099150505b93509350939050565b60008060008660000361143e575084915083905082611550565b83600003611453575087915086905085611550565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff808889098186870982818d0983838b0984858a85098e0985868e87098c09868b8f08848410156114a357928701925b8484039350878460020988818209905088818609848410156114c457928901925b898585036002099350898485099c50898288099650898a8860020982089150818d10156114f0579b89019b5b818d039c5089818b87600209099450508b86101561150d57948801945b888c870384099a50838b101561152257998801995b838b039a508887890897508882830990508781101561153e5788015b88858983030999505050505050505050505b96509650969350505050565b60008184111561156c5781840693505b60405160208152602080820152602060408201528460608201528360808201528260a082015260208160c08360056136b0fa8080156100a357505051949350505050565b600080826000036115c65750600090508061133e565b60006115f2847fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611243565b905060007fffffffff00000001000000000000000000000000ffffffffffffffffffffffff82830990507fffffffff00000001000000000000000000000000ffffffffffffffffffffffff81880993507fffffffff00000001000000000000000000000000ffffffffffffffffffffffff80838309870992505050935093915050565b82600281019282156116a8579160200282015b828111156116a8578251829060ff16905591602001919060010190611688565b506116b492915061174e565b5090565b60405180604001604052806002906020820280368337509192915050565b82600281019282156116a8579160200282015b828111156116a85782518255916020019190600101906116e9565b6040518061020001604052806010905b61173860405180606001604052806000815260200160008152602001600081525090565b8152602001906001900390816117145790505090565b5b808211156116b4576000815560010161174f565b6000610160828403121561177657600080fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156117ce576117ce61177c565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561181b5761181b61177c565b604052919050565b60008060006080848603121561183857600080fd5b833567ffffffffffffffff81111561184f57600080fd5b61185b86828701611763565b935050602080850135925085605f86011261187557600080fd5b61187d6117ab565b80608087018881111561188f57600080fd5b604088015b818110156118ab5780358452928401928401611894565b50508093505050509250925092565b600067ffffffffffffffff8211156118d4576118d461177c565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261191157600080fd5b813561192461191f826118ba565b6117d4565b81815284602083860101111561193957600080fd5b816020850160208301376000918101602001919091529392505050565b6000806040838503121561196957600080fd5b82359150602083013567ffffffffffffffff81111561198757600080fd5b61199385828601611900565b9150509250929050565b6000602082840312156119af57600080fd5b813567ffffffffffffffff8111156119c657600080fd5b61041784828501611900565b60005b838110156119ed5781810151838201526020016119d5565b50506000910152565b6020815260008251806020840152611a158160408501602087016119d2565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b60008060408385031215611a5a57600080fd5b823567ffffffffffffffff811115611a7157600080fd5b611a7d85828601611763565b95602094909401359450505050565b60008060208385031215611a9f57600080fd5b823567ffffffffffffffff80821115611ab757600080fd5b818501915085601f830112611acb57600080fd5b813581811115611ada57600080fd5b866020828501011115611aec57600080fd5b60209290920196919550909350505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112611b3357600080fd5b83018035915067ffffffffffffffff821115611b4e57600080fd5b602001915036819003821315611b6357600080fd5b9250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008183825b6002811015611bbe578154835260209092019160019182019101611b9f565b50505060408201905092915050565b60008085851115611bdd57600080fd5b83861115611bea57600080fd5b5050820193919092039150565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b6000611c5261191f846118ba565b9050828152838383011115611c6657600080fd5b6102f68360208301846119d2565b600082601f830112611c8557600080fd5b6102f683835160208501611c44565b600080600080600060a08688031215611cac57600080fd5b8551945060208601519350604086015167ffffffffffffffff80821115611cd257600080fd5b818801915088601f830112611ce657600080fd5b611cf589835160208501611c44565b94506060880151915080821115611d0b57600080fd5b611d1789838a01611c74565b93506080880151915080821115611d2d57600080fd5b50611d3a88828901611c74565b9150509295509295909350565b60008451611d598184602089016119d2565b845190830190611d6d8183602089016119d2565b8451910190611d808183602088016119d2565b0195945050505050565b60008251611d9c8184602087016119d2565b9190910192915050565b600060208284031215611db857600080fd5b5051919050565b60008351611dd18184602088016119d2565b9190910191825250602001919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808202811582820484141761036957610369611de1565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082611e6557611e65611e27565b500490565b600082611e7957611e79611e27565b500690565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611eaf57611eaf611de1565b5060010190565b8181038181111561036957610369611de1565b600081611ed857611ed8611de1565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392d5fa2646970667358221220d4142da7b16effb6b95f41adeff2bc8ce0d59d3b70ca8d55e6e83224bbfbec0a64736f6c63430008150033", + "devdoc": { + "author": "Ruslan Serebriakov (@rsrbk)David Yongjun Kim (@Powerstream3604)", + "details": "Primarily used to verify user ops signed with passkeys", + "kind": "dev", + "methods": { + "initializeSigner(bytes)": { + "details": "This method checks if the signer has already been initialized. If already initialized, it reverts. It checks if the public key is in the light format and initializes signer storage in k1 storage.", + "params": { + "_publicKey": "Bytes of owner public key" + }, + "returns": { + "initSuccess": "Uint value representing the success of init operation" + } + }, + "isValidKeyType(bytes)": { + "details": "For this Secp256k1Verification Facet, the public key should in an uncompressed public key format", + "params": { + "_publicKey": "Bytes of public key for format check" + }, + "returns": { + "isValid": "Boolean variable representing if the format of public key is valid" + } + }, + "isValidSignature(bytes32,bytes)": { + "details": "This method verifies the signature if the owner indeed signed the hash. Returns magic value if true", + "params": { + "_hash": "Hash value the owner signed", + "_signature": "Signature that signed the above hash" + }, + "returns": { + "magicValue": "Bytes4 value representing the success/failure of validation" + } + }, + "owner()": { + "returns": { + "signer": "Bytes of owner address" + } + }, + "uninitializeSigner()": { + "details": "This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.", + "returns": { + "uninitSuccess": "Uint value representing the success of uninit operation" + } + }, + "validateOwnerSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32)": { + "details": "This method validates if the user operation is signed by the owner. It internally calls validateSignature with signer public key.", + "params": { + "userOp": "UserOperation including all information for execution", + "userOpHash": "Hash of UserOperation given from EntryPoint. This hash is used for signature validation" + }, + "returns": { + "validationData": "Uint value representing whether the validation is successful. 0 for success, 1 for failure" + } + }, + "validateOwnerSignatureSelector()": { + "returns": { + "ownerSignatureValidatorSelector": "Bytes4 selector of function signature to validate account owner's UserOperation signature" + } + }, + "validateSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256[2])": { + "details": "This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address", + "params": { + "q": "Public Key of signer who signed the contract, to be validated", + "userOp": "UserOperation including all information for execution", + "userOpHash": "Hash of UserOperation given from EntryPoint. This hash is used for signature validation" + }, + "returns": { + "isValid": "Uint value representing whether the validation is successful. 0 for success, 1 for failure" + } + } + }, + "title": "Secp256r1 verification facet", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "constructor": { + "notice": "This constructor ensures that this contract can only be used as singleton for Proxy contracts" + }, + "initializeSigner(bytes)": { + "notice": "Initializes the signer in R1 Facet Storage. This can only be called when the account is uninitialized or during signature migration." + }, + "isValidKeyType(bytes)": { + "notice": "Validates if the format of public key is valid for this verification facet" + }, + "isValidSignature(bytes32,bytes)": { + "notice": "Validates if the signature is valid. Function to be compatible with EIP-1271" + }, + "owner()": { + "notice": "Returns the owner of the account" + }, + "uninitializeSigner()": { + "notice": "Uninitialize signer in R1 Facet Storage. This can only be called when the account is undergoing signature migration and has already been initialized." + }, + "validateOwnerSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32)": { + "notice": "Validates if the user operation is signed by the owner." + }, + "validateOwnerSignatureSelector()": { + "notice": "Returns the selector of function to validate the signature of UserOperation" + }, + "validateSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256[2])": { + "notice": "Validates if the signature of UserOperation is signed by the given signer" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/linea/TokenReceiverFacet.json b/deployments/linea/TokenReceiverFacet.json new file mode 100644 index 0000000..be6ac82 --- /dev/null +++ b/deployments/linea/TokenReceiverFacet.json @@ -0,0 +1,239 @@ +{ + "address": "0x3143E1C0Af0Cdc153423863923Cf4e3818e34Daa", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onERC1155BatchReceived", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onERC1155Received", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onERC721Received", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onTokenTransfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "tokensReceived", + "outputs": [], + "stateMutability": "pure", + "type": "function" + } + ], + "transactionHash": "0x8697c4c68ce769198592cc0a61f48d5f97b2941fb16dfe4f887ee8ffbe676203", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 4, + "gasUsed": "329340", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x4ab25600b6d3eb46b33f84eac63142f272d786e6d02d686f2ee94ec3df1ac489", + "transactionHash": "0x8697c4c68ce769198592cc0a61f48d5f97b2941fb16dfe4f887ee8ffbe676203", + "logs": [], + "blockNumber": 2720888, + "cumulativeGasUsed": "1182429", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "ad34345aa73d96f52b3e14df983b6b29", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onERC1155BatchReceived\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onERC1155Received\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onERC721Received\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"tokensReceived\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"Contract that enables receiving ERC721/ERC1155/ERC777/ERC677 Tokens with safe transfer\",\"kind\":\"dev\",\"methods\":{},\"title\":\"TokenReceiver Facet\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\":{\"notice\":\"Handles ERC1155 Token batch callback. return Standardized onERC1155BatchReceived return value.\"},\"onERC1155Received(address,address,uint256,uint256,bytes)\":{\"notice\":\"Handles ERC1155 Token callback. return Standardized onERC1155Received return value.\"},\"onERC721Received(address,address,uint256,bytes)\":{\"notice\":\"Handles ERC721 Token callback. return Standardized onERC721Received return value.\"},\"onTokenTransfer(address,uint256,bytes)\":{\"notice\":\"Handles ERC677 Token callback. return true.\"},\"tokensReceived(address,address,address,uint256,bytes,bytes)\":{\"notice\":\"Handles ERC777 Token callback. Does not return value, empty implementation.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/TokenReceiverFacet.sol\":\"TokenReceiverFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title ERC721 token receiver interface\\n * @dev Interface for any contract that wants to support safeTransfers\\n * from ERC721 asset contracts.\\n */\\ninterface IERC721Receiver {\\n /**\\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\\n * by `operator` from `from`, this function is called.\\n *\\n * It must return its Solidity selector to confirm the token transfer.\\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\\n *\\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\\n */\\n function onERC721Received(\\n address operator,\\n address from,\\n uint256 tokenId,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\\n *\\n * Accounts can be notified of {IERC777} tokens being sent to them by having a\\n * contract implement this interface (contract holders can be their own\\n * implementer) and registering it on the\\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\\n *\\n * See {IERC1820Registry} and {ERC1820Implementer}.\\n */\\ninterface IERC777Recipient {\\n /**\\n * @dev Called by an {IERC777} token contract whenever tokens are being\\n * moved or created into a registered account (`to`). The type of operation\\n * is conveyed by `from` being the zero address or not.\\n *\\n * This call occurs _after_ the token contract's state is updated, so\\n * {IERC777-balanceOf}, etc., can be used to query the post-operation state.\\n *\\n * This function may revert to prevent the operation from being executed.\\n */\\n function tokensReceived(\\n address operator,\\n address from,\\n address to,\\n uint256 amount,\\n bytes calldata userData,\\n bytes calldata operatorData\\n ) external;\\n}\\n\",\"keccak256\":\"0x1a5d61db2733202ba361e6d6741cd2e662380e22b80e987eacfc91973f2267dc\",\"license\":\"MIT\"},\"contracts/facets/TokenReceiverFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IERC721Receiver} from \\\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\\\";\\nimport {IERC777Recipient} from \\\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\\\";\\nimport {IERC1155Receiver} from \\\"../interfaces/ERC/IERC1155Receiver.sol\\\";\\nimport {IERC677Receiver} from \\\"../interfaces/ERC/IERC677Receiver.sol\\\";\\n\\n/**\\n * @title TokenReceiver Facet\\n * @dev Contract that enables receiving ERC721/ERC1155/ERC777/ERC677 Tokens with safe transfer\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract TokenReceiverFacet is\\n IERC721Receiver,\\n IERC1155Receiver,\\n IERC777Recipient,\\n IERC677Receiver\\n{\\n /**\\n * @notice Handles ERC721 Token callback.\\n * return Standardized onERC721Received return value.\\n */\\n function onERC721Received(\\n address,\\n address,\\n uint256,\\n bytes calldata\\n ) external pure override returns (bytes4) {\\n return IERC721Receiver.onERC721Received.selector;\\n }\\n\\n /**\\n * @notice Handles ERC1155 Token callback.\\n * return Standardized onERC1155Received return value.\\n */\\n function onERC1155Received(\\n address,\\n address,\\n uint256,\\n uint256,\\n bytes calldata\\n ) external pure override returns (bytes4) {\\n return IERC1155Receiver.onERC1155Received.selector;\\n }\\n\\n /**\\n * @notice Handles ERC1155 Token batch callback.\\n * return Standardized onERC1155BatchReceived return value.\\n */\\n function onERC1155BatchReceived(\\n address,\\n address,\\n uint256[] calldata,\\n uint256[] calldata,\\n bytes calldata\\n ) external pure override returns (bytes4) {\\n return IERC1155Receiver.onERC1155BatchReceived.selector;\\n }\\n\\n /**\\n * @notice Handles ERC777 Token callback.\\n * Does not return value, empty implementation.\\n */\\n function tokensReceived(\\n address,\\n address,\\n address,\\n uint256,\\n bytes calldata,\\n bytes calldata\\n ) external pure override {}\\n\\n /**\\n * @notice Handles ERC677 Token callback.\\n * return true.\\n */\\n function onTokenTransfer(\\n address,\\n uint256,\\n bytes calldata\\n ) external pure override returns (bool) {\\n return true;\\n }\\n}\\n\",\"keccak256\":\"0xdfe483d05ef4056bb464c34ade19ab527687aff3ed0b6303b447a68b5ff7abb4\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC1155Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\n\\npragma solidity 0.8.21;\\n\\n/**\\n * @dev _Available since v3.1._\\n */\\ninterface IERC1155Receiver {\\n /**\\n * @dev Handles the receipt of a single ERC1155 token type. This function is\\n * called at the end of a `safeTransferFrom` after the balance has been updated.\\n *\\n * NOTE: To accept the transfer, this must return\\n * `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))`\\n * (i.e. 0xf23a6e61, or its own function selector).\\n *\\n * @param operator The address which initiated the transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param id The ID of the token being transferred\\n * @param value The amount of tokens being transferred\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155Received(\\n address operator,\\n address from,\\n uint256 id,\\n uint256 value,\\n bytes calldata data\\n ) external returns (bytes4);\\n\\n /**\\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\\n * is called at the end of a `safeBatchTransferFrom` after the balances have\\n * been updated.\\n *\\n * NOTE: To accept the transfer(s), this must return\\n * `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))`\\n * (i.e. 0xbc197c81, or its own function selector).\\n *\\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155BatchReceived(\\n address operator,\\n address from,\\n uint256[] calldata ids,\\n uint256[] calldata values,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0x3729c6757bae3aba03ac1c5064d67ad13b94e2a9428bf44b9be510373406da0c\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC677Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC677Receiver {\\n function onTokenTransfer(\\n address sender,\\n uint value,\\n bytes calldata data\\n ) external pure returns (bool);\\n}\\n\",\"keccak256\":\"0x4c1631cf45ea6daac0ec158c3edb9453099130b6b64f697004b83f95aa1f7350\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50610502806100206000396000f3fe608060405234801561001057600080fd5b50600436106100665760003560e01c8063a4c0ed3611610050578063a4c0ed36146100f3578063bc197c811461011b578063f23a6e611461015657600080fd5b806223de291461006b578063150b7a0214610085575b600080fd5b610083610079366004610201565b5050505050505050565b005b6100bd6100933660046102ac565b7f150b7a020000000000000000000000000000000000000000000000000000000095945050505050565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020015b60405180910390f35b61010b61010136600461031b565b6001949350505050565b60405190151581526020016100ea565b6100bd6101293660046103ba565b7fbc197c810000000000000000000000000000000000000000000000000000000098975050505050505050565b6100bd610164366004610454565b7ff23a6e61000000000000000000000000000000000000000000000000000000009695505050505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146101b357600080fd5b919050565b60008083601f8401126101ca57600080fd5b50813567ffffffffffffffff8111156101e257600080fd5b6020830191508360208285010111156101fa57600080fd5b9250929050565b60008060008060008060008060c0898b03121561021d57600080fd5b6102268961018f565b975061023460208a0161018f565b965061024260408a0161018f565b955060608901359450608089013567ffffffffffffffff8082111561026657600080fd5b6102728c838d016101b8565b909650945060a08b013591508082111561028b57600080fd5b506102988b828c016101b8565b999c989b5096995094979396929594505050565b6000806000806000608086880312156102c457600080fd5b6102cd8661018f565b94506102db6020870161018f565b935060408601359250606086013567ffffffffffffffff8111156102fe57600080fd5b61030a888289016101b8565b969995985093965092949392505050565b6000806000806060858703121561033157600080fd5b61033a8561018f565b935060208501359250604085013567ffffffffffffffff81111561035d57600080fd5b610369878288016101b8565b95989497509550505050565b60008083601f84011261038757600080fd5b50813567ffffffffffffffff81111561039f57600080fd5b6020830191508360208260051b85010111156101fa57600080fd5b60008060008060008060008060a0898b0312156103d657600080fd5b6103df8961018f565b97506103ed60208a0161018f565b9650604089013567ffffffffffffffff8082111561040a57600080fd5b6104168c838d01610375565b909850965060608b013591508082111561042f57600080fd5b61043b8c838d01610375565b909650945060808b013591508082111561028b57600080fd5b60008060008060008060a0878903121561046d57600080fd5b6104768761018f565b95506104846020880161018f565b94506040870135935060608701359250608087013567ffffffffffffffff8111156104ae57600080fd5b6104ba89828a016101b8565b979a969950949750929593949250505056fea2646970667358221220ae9a97061ae9e1485161ca9c8d3228a23e47b18755fa935f51b40e927816ca2964736f6c63430008150033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100665760003560e01c8063a4c0ed3611610050578063a4c0ed36146100f3578063bc197c811461011b578063f23a6e611461015657600080fd5b806223de291461006b578063150b7a0214610085575b600080fd5b610083610079366004610201565b5050505050505050565b005b6100bd6100933660046102ac565b7f150b7a020000000000000000000000000000000000000000000000000000000095945050505050565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020015b60405180910390f35b61010b61010136600461031b565b6001949350505050565b60405190151581526020016100ea565b6100bd6101293660046103ba565b7fbc197c810000000000000000000000000000000000000000000000000000000098975050505050505050565b6100bd610164366004610454565b7ff23a6e61000000000000000000000000000000000000000000000000000000009695505050505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146101b357600080fd5b919050565b60008083601f8401126101ca57600080fd5b50813567ffffffffffffffff8111156101e257600080fd5b6020830191508360208285010111156101fa57600080fd5b9250929050565b60008060008060008060008060c0898b03121561021d57600080fd5b6102268961018f565b975061023460208a0161018f565b965061024260408a0161018f565b955060608901359450608089013567ffffffffffffffff8082111561026657600080fd5b6102728c838d016101b8565b909650945060a08b013591508082111561028b57600080fd5b506102988b828c016101b8565b999c989b5096995094979396929594505050565b6000806000806000608086880312156102c457600080fd5b6102cd8661018f565b94506102db6020870161018f565b935060408601359250606086013567ffffffffffffffff8111156102fe57600080fd5b61030a888289016101b8565b969995985093965092949392505050565b6000806000806060858703121561033157600080fd5b61033a8561018f565b935060208501359250604085013567ffffffffffffffff81111561035d57600080fd5b610369878288016101b8565b95989497509550505050565b60008083601f84011261038757600080fd5b50813567ffffffffffffffff81111561039f57600080fd5b6020830191508360208260051b85010111156101fa57600080fd5b60008060008060008060008060a0898b0312156103d657600080fd5b6103df8961018f565b97506103ed60208a0161018f565b9650604089013567ffffffffffffffff8082111561040a57600080fd5b6104168c838d01610375565b909850965060608b013591508082111561042f57600080fd5b61043b8c838d01610375565b909650945060808b013591508082111561028b57600080fd5b60008060008060008060a0878903121561046d57600080fd5b6104768761018f565b95506104846020880161018f565b94506040870135935060608701359250608087013567ffffffffffffffff8111156104ae57600080fd5b6104ba89828a016101b8565b979a969950949750929593949250505056fea2646970667358221220ae9a97061ae9e1485161ca9c8d3228a23e47b18755fa935f51b40e927816ca2964736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "Contract that enables receiving ERC721/ERC1155/ERC777/ERC677 Tokens with safe transfer", + "kind": "dev", + "methods": {}, + "title": "TokenReceiver Facet", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)": { + "notice": "Handles ERC1155 Token batch callback. return Standardized onERC1155BatchReceived return value." + }, + "onERC1155Received(address,address,uint256,uint256,bytes)": { + "notice": "Handles ERC1155 Token callback. return Standardized onERC1155Received return value." + }, + "onERC721Received(address,address,uint256,bytes)": { + "notice": "Handles ERC721 Token callback. return Standardized onERC721Received return value." + }, + "onTokenTransfer(address,uint256,bytes)": { + "notice": "Handles ERC677 Token callback. return true." + }, + "tokensReceived(address,address,address,uint256,bytes,bytes)": { + "notice": "Handles ERC777 Token callback. Does not return value, empty implementation." + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/linea/solcInputs/ad34345aa73d96f52b3e14df983b6b29.json b/deployments/linea/solcInputs/ad34345aa73d96f52b3e14df983b6b29.json new file mode 100644 index 0000000..c2bd4dc --- /dev/null +++ b/deployments/linea/solcInputs/ad34345aa73d96f52b3e14df983b6b29.json @@ -0,0 +1,360 @@ +{ + "language": "Solidity", + "sources": { + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby disabling any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable2Step.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./Ownable.sol\";\n\n/**\n * @dev Contract module which provides access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership} and {acceptOwnership}.\n *\n * This module is used through inheritance. It will make available all functions\n * from parent (Ownable).\n */\nabstract contract Ownable2Step is Ownable {\n address private _pendingOwner;\n\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Returns the address of the pending owner.\n */\n function pendingOwner() public view virtual returns (address) {\n return _pendingOwner;\n }\n\n /**\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual override onlyOwner {\n _pendingOwner = newOwner;\n emit OwnershipTransferStarted(owner(), newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual override {\n delete _pendingOwner;\n super._transferOwnership(newOwner);\n }\n\n /**\n * @dev The new owner accepts the ownership transfer.\n */\n function acceptOwnership() public virtual {\n address sender = _msgSender();\n require(pendingOwner() == sender, \"Ownable2Step: caller is not the new owner\");\n _transferOwnership(sender);\n }\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC1271.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC1271 standard signature validation method for\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\n *\n * _Available since v4.1._\n */\ninterface IERC1271 {\n /**\n * @dev Should return whether the signature provided is valid for the provided data\n * @param hash Hash of the data to be signed\n * @param signature Signature byte array associated with _data\n */\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\n}\n" + }, + "@openzeppelin/contracts/security/ReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor() {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n _nonReentrantBefore();\n _;\n _nonReentrantAfter();\n }\n\n function _nonReentrantBefore() private {\n // On the first call to nonReentrant, _status will be _NOT_ENTERED\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n }\n\n function _nonReentrantAfter() private {\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Returns true if the reentrancy guard is currently set to \"entered\", which indicates there is a\n * `nonReentrant` function in the call stack.\n */\n function _reentrancyGuardEntered() internal view returns (bool) {\n return _status == _ENTERED;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/ERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/ERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC1155.sol\";\nimport \"./IERC1155Receiver.sol\";\nimport \"./extensions/IERC1155MetadataURI.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of the basic standard multi-token.\n * See https://eips.ethereum.org/EIPS/eip-1155\n * Originally based on code by Enjin: https://github.com/enjin/erc-1155\n *\n * _Available since v3.1._\n */\ncontract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {\n using Address for address;\n\n // Mapping from token ID to account balances\n mapping(uint256 => mapping(address => uint256)) private _balances;\n\n // Mapping from account to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json\n string private _uri;\n\n /**\n * @dev See {_setURI}.\n */\n constructor(string memory uri_) {\n _setURI(uri_);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return\n interfaceId == type(IERC1155).interfaceId ||\n interfaceId == type(IERC1155MetadataURI).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC1155MetadataURI-uri}.\n *\n * This implementation returns the same URI for *all* token types. It relies\n * on the token type ID substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * Clients calling this function must replace the `\\{id\\}` substring with the\n * actual token type ID.\n */\n function uri(uint256) public view virtual override returns (string memory) {\n return _uri;\n }\n\n /**\n * @dev See {IERC1155-balanceOf}.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {\n require(account != address(0), \"ERC1155: address zero is not a valid owner\");\n return _balances[id][account];\n }\n\n /**\n * @dev See {IERC1155-balanceOfBatch}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] memory accounts,\n uint256[] memory ids\n ) public view virtual override returns (uint256[] memory) {\n require(accounts.length == ids.length, \"ERC1155: accounts and ids length mismatch\");\n\n uint256[] memory batchBalances = new uint256[](accounts.length);\n\n for (uint256 i = 0; i < accounts.length; ++i) {\n batchBalances[i] = balanceOf(accounts[i], ids[i]);\n }\n\n return batchBalances;\n }\n\n /**\n * @dev See {IERC1155-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC1155-isApprovedForAll}.\n */\n function isApprovedForAll(address account, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[account][operator];\n }\n\n /**\n * @dev See {IERC1155-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n _safeTransferFrom(from, to, id, amount, data);\n }\n\n /**\n * @dev See {IERC1155-safeBatchTransferFrom}.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n _safeBatchTransferFrom(from, to, ids, amounts, data);\n }\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n\n emit TransferSingle(operator, from, to, id, amount);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n for (uint256 i = 0; i < ids.length; ++i) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n }\n\n emit TransferBatch(operator, from, to, ids, amounts);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\n\n _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);\n }\n\n /**\n * @dev Sets a new URI for all token types, by relying on the token type ID\n * substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * By this mechanism, any occurrence of the `\\{id\\}` substring in either the\n * URI or any of the amounts in the JSON file at said URI will be replaced by\n * clients with the token type ID.\n *\n * For example, the `https://token-cdn-domain/\\{id\\}.json` URI would be\n * interpreted by clients as\n * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`\n * for token type ID 0x4cce0.\n *\n * See {uri}.\n *\n * Because these URIs cannot be meaningfully represented by the {URI} event,\n * this function emits no events.\n */\n function _setURI(string memory newuri) internal virtual {\n _uri = newuri;\n }\n\n /**\n * @dev Creates `amount` tokens of token type `id`, and assigns them to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _mint(address to, uint256 id, uint256 amount, bytes memory data) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _balances[id][to] += amount;\n emit TransferSingle(operator, address(0), to, id, amount);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n for (uint256 i = 0; i < ids.length; i++) {\n _balances[ids[i]][to] += amounts[i];\n }\n\n emit TransferBatch(operator, address(0), to, ids, amounts);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);\n }\n\n /**\n * @dev Destroys `amount` tokens of token type `id` from `from`\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `from` must have at least `amount` tokens of token type `id`.\n */\n function _burn(address from, uint256 id, uint256 amount) internal virtual {\n require(from != address(0), \"ERC1155: burn from the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n\n emit TransferSingle(operator, from, address(0), id, amount);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n */\n function _burnBatch(address from, uint256[] memory ids, uint256[] memory amounts) internal virtual {\n require(from != address(0), \"ERC1155: burn from the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n\n for (uint256 i = 0; i < ids.length; i++) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n }\n\n emit TransferBatch(operator, from, address(0), ids, amounts);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {\n require(owner != operator, \"ERC1155: setting approval status for self\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning, as well as batched variants.\n *\n * The same hook is called on both single and batched variants. For single\n * transfers, the length of the `ids` and `amounts` arrays will be 1.\n *\n * Calling conditions (for each `id` and `amount` pair):\n *\n * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * of token type `id` will be transferred to `to`.\n * - When `from` is zero, `amount` tokens of token type `id` will be minted\n * for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n * will be burned.\n * - `from` and `to` are never both zero.\n * - `ids` and `amounts` have the same, non-zero length.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any token transfer. This includes minting\n * and burning, as well as batched variants.\n *\n * The same hook is called on both single and batched variants. For single\n * transfers, the length of the `id` and `amount` arrays will be 1.\n *\n * Calling conditions (for each `id` and `amount` pair):\n *\n * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * of token type `id` will be transferred to `to`.\n * - When `from` is zero, `amount` tokens of token type `id` will be minted\n * for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n * will be burned.\n * - `from` and `to` are never both zero.\n * - `ids` and `amounts` have the same, non-zero length.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {}\n\n function _doSafeTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155Receiver.onERC1155Received.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non-ERC1155Receiver implementer\");\n }\n }\n }\n\n function _doSafeBatchTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (\n bytes4 response\n ) {\n if (response != IERC1155Receiver.onERC1155BatchReceived.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non-ERC1155Receiver implementer\");\n }\n }\n }\n\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {\n uint256[] memory array = new uint256[](1);\n array[0] = element;\n\n return array;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC1155.sol\";\n\n/**\n * @dev Interface of the optional ERC1155MetadataExtension interface, as defined\n * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155MetadataURI is IERC1155 {\n /**\n * @dev Returns the URI for token type `id`.\n *\n * If the `\\{id\\}` substring is present in the URI, it must be replaced by\n * clients with the actual token type ID.\n */\n function uri(uint256 id) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155 is IERC165 {\n /**\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n */\n event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);\n\n /**\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n * transfers.\n */\n event TransferBatch(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\n\n /**\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n * `approved`.\n */\n event ApprovalForAll(address indexed account, address indexed operator, bool approved);\n\n /**\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n *\n * If an {URI} event was emitted for `id`, the standard\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n * returned by {IERC1155MetadataURI-uri}.\n */\n event URI(string value, uint256 indexed id);\n\n /**\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) external view returns (uint256);\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] calldata accounts,\n uint256[] calldata ids\n ) external view returns (uint256[] memory);\n\n /**\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n *\n * Emits an {ApprovalForAll} event.\n *\n * Requirements:\n *\n * - `operator` cannot be the caller.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n *\n * See {setApprovalForAll}.\n */\n function isApprovedForAll(address account, address operator) external view returns (bool);\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155Receiver is IERC165 {\n /**\n * @dev Handles the receipt of a single ERC1155 token type. This function is\n * called at the end of a `safeTransferFrom` after the balance has been updated.\n *\n * NOTE: To accept the transfer, this must return\n * `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n * (i.e. 0xf23a6e61, or its own function selector).\n *\n * @param operator The address which initiated the transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param id The ID of the token being transferred\n * @param value The amount of tokens being transferred\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n ) external returns (bytes4);\n\n /**\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\n * is called at the end of a `safeBatchTransferFrom` after the balances have\n * been updated.\n *\n * NOTE: To accept the transfer(s), this must return\n * `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n * (i.e. 0xbc197c81, or its own function selector).\n *\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the default value returned by this function, unless\n * it's overridden.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(address from, address to, uint256 amount) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\n // decrementing then incrementing.\n _balances[to] += amount;\n }\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n unchecked {\n // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\n _balances[account] += amount;\n }\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n // Overflow not possible: amount <= accountBalance <= totalSupply.\n _totalSupply -= amount;\n }\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\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" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` 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 amount) 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 `amount` as the allowance of `spender` over the 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 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` 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 amount) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/ERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721.sol\";\nimport \"./IERC721Receiver.sol\";\nimport \"./extensions/IERC721Metadata.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/Strings.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\n using Address for address;\n using Strings for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\n\n // Mapping from token ID to approved address\n mapping(uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return\n interfaceId == type(IERC721).interfaceId ||\n interfaceId == type(IERC721Metadata).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _ownerOf(tokenId);\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token owner or approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n _requireMinted(tokenId);\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n _safeTransfer(from, to, tokenId, data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(address from, address to, uint256 tokenId, bytes memory data) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist\n */\n function _ownerOf(uint256 tokenId) internal view virtual returns (address) {\n return _owners[tokenId];\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _ownerOf(tokenId) != address(0);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n address owner = ERC721.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(address to, uint256 tokenId, bytes memory data) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId, 1);\n\n // Check that tokenId was not minted by `_beforeTokenTransfer` hook\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n unchecked {\n // Will not overflow unless all 2**256 token ids are minted to the same owner.\n // Given that tokens are minted one by one, it is impossible in practice that\n // this ever happens. Might change if we allow batch minting.\n // The ERC fails to describe this case.\n _balances[to] += 1;\n }\n\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(address(0), to, tokenId, 1);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n * This is an internal function that does not check if the sender is authorized to operate on the token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId, 1);\n\n // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook\n owner = ERC721.ownerOf(tokenId);\n\n // Clear approvals\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // Cannot overflow, as that would require more tokens to be burned/transferred\n // out than the owner initially received through minting and transferring in.\n _balances[owner] -= 1;\n }\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(owner, address(0), tokenId, 1);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(address from, address to, uint256 tokenId) internal virtual {\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId, 1);\n\n // Check that tokenId was not transferred by `_beforeTokenTransfer` hook\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n\n // Clear approvals from the previous owner\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // `_balances[from]` cannot overflow for the same reason as described in `_burn`:\n // `from`'s balance is the number of token held, which is at least one before the current\n // transfer.\n // `_balances[to]` could overflow in the conditions described in `_mint`. That would require\n // all 2**256 token ids to be minted, which in practice is impossible.\n _balances[from] -= 1;\n _balances[to] += 1;\n }\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId, 1);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721Receiver.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`.\n * - When `from` is zero, the tokens will be minted for `to`.\n * - When `to` is zero, ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}\n\n /**\n * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`.\n * - When `from` is zero, the tokens were minted for `to`.\n * - When `to` is zero, ``from``'s tokens were burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}\n\n /**\n * @dev Unsafe write access to the balances, used by extensions that \"mint\" tokens using an {ownerOf} override.\n *\n * WARNING: Anyone calling this MUST ensure that the balances remain consistent with the ownership. The invariant\n * being that for any address `a` the value returned by `balanceOf(a)` must be equal to the number of tokens such\n * that `ownerOf(tokenId)` is `a`.\n */\n // solhint-disable-next-line func-name-mixedcase\n function __unsafe_increaseBalance(address account, uint256 amount) internal {\n _balances[account] += amount;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721Receiver {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/ERC777.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC777/ERC777.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC777.sol\";\nimport \"./IERC777Recipient.sol\";\nimport \"./IERC777Sender.sol\";\nimport \"../ERC20/IERC20.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/introspection/IERC1820Registry.sol\";\n\n/**\n * @dev Implementation of the {IERC777} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n *\n * Support for ERC20 is included in this contract, as specified by the EIP: both\n * the ERC777 and ERC20 interfaces can be safely used when interacting with it.\n * Both {IERC777-Sent} and {IERC20-Transfer} events are emitted on token\n * movements.\n *\n * Additionally, the {IERC777-granularity} value is hard-coded to `1`, meaning that there\n * are no special restrictions in the amount of tokens that created, moved, or\n * destroyed. This makes integration with ERC20 applications seamless.\n *\n * CAUTION: This file is deprecated as of v4.9 and will be removed in the next major release.\n */\ncontract ERC777 is Context, IERC777, IERC20 {\n using Address for address;\n\n IERC1820Registry internal constant _ERC1820_REGISTRY = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n mapping(address => uint256) private _balances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n bytes32 private constant _TOKENS_SENDER_INTERFACE_HASH = keccak256(\"ERC777TokensSender\");\n bytes32 private constant _TOKENS_RECIPIENT_INTERFACE_HASH = keccak256(\"ERC777TokensRecipient\");\n\n // This isn't ever read from - it's only used to respond to the defaultOperators query.\n address[] private _defaultOperatorsArray;\n\n // Immutable, but accounts may revoke them (tracked in __revokedDefaultOperators).\n mapping(address => bool) private _defaultOperators;\n\n // For each account, a mapping of its operators and revoked default operators.\n mapping(address => mapping(address => bool)) private _operators;\n mapping(address => mapping(address => bool)) private _revokedDefaultOperators;\n\n // ERC20-allowances\n mapping(address => mapping(address => uint256)) private _allowances;\n\n /**\n * @dev `defaultOperators` may be an empty array.\n */\n constructor(string memory name_, string memory symbol_, address[] memory defaultOperators_) {\n _name = name_;\n _symbol = symbol_;\n\n _defaultOperatorsArray = defaultOperators_;\n for (uint256 i = 0; i < defaultOperators_.length; i++) {\n _defaultOperators[defaultOperators_[i]] = true;\n }\n\n // register interfaces\n _ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256(\"ERC777Token\"), address(this));\n _ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256(\"ERC20Token\"), address(this));\n }\n\n /**\n * @dev See {IERC777-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC777-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {ERC20-decimals}.\n *\n * Always returns 18, as per the\n * [ERC777 EIP](https://eips.ethereum.org/EIPS/eip-777#backward-compatibility).\n */\n function decimals() public pure virtual returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC777-granularity}.\n *\n * This implementation always returns `1`.\n */\n function granularity() public view virtual override returns (uint256) {\n return 1;\n }\n\n /**\n * @dev See {IERC777-totalSupply}.\n */\n function totalSupply() public view virtual override(IERC20, IERC777) returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev Returns the amount of tokens owned by an account (`tokenHolder`).\n */\n function balanceOf(address tokenHolder) public view virtual override(IERC20, IERC777) returns (uint256) {\n return _balances[tokenHolder];\n }\n\n /**\n * @dev See {IERC777-send}.\n *\n * Also emits a {IERC20-Transfer} event for ERC20 compatibility.\n */\n function send(address recipient, uint256 amount, bytes memory data) public virtual override {\n _send(_msgSender(), recipient, amount, data, \"\", true);\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Unlike `send`, `recipient` is _not_ required to implement the {IERC777Recipient}\n * interface if it is a contract.\n *\n * Also emits a {Sent} event.\n */\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n _send(_msgSender(), recipient, amount, \"\", \"\", false);\n return true;\n }\n\n /**\n * @dev See {IERC777-burn}.\n *\n * Also emits a {IERC20-Transfer} event for ERC20 compatibility.\n */\n function burn(uint256 amount, bytes memory data) public virtual override {\n _burn(_msgSender(), amount, data, \"\");\n }\n\n /**\n * @dev See {IERC777-isOperatorFor}.\n */\n function isOperatorFor(address operator, address tokenHolder) public view virtual override returns (bool) {\n return\n operator == tokenHolder ||\n (_defaultOperators[operator] && !_revokedDefaultOperators[tokenHolder][operator]) ||\n _operators[tokenHolder][operator];\n }\n\n /**\n * @dev See {IERC777-authorizeOperator}.\n */\n function authorizeOperator(address operator) public virtual override {\n require(_msgSender() != operator, \"ERC777: authorizing self as operator\");\n\n if (_defaultOperators[operator]) {\n delete _revokedDefaultOperators[_msgSender()][operator];\n } else {\n _operators[_msgSender()][operator] = true;\n }\n\n emit AuthorizedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-revokeOperator}.\n */\n function revokeOperator(address operator) public virtual override {\n require(operator != _msgSender(), \"ERC777: revoking self as operator\");\n\n if (_defaultOperators[operator]) {\n _revokedDefaultOperators[_msgSender()][operator] = true;\n } else {\n delete _operators[_msgSender()][operator];\n }\n\n emit RevokedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-defaultOperators}.\n */\n function defaultOperators() public view virtual override returns (address[] memory) {\n return _defaultOperatorsArray;\n }\n\n /**\n * @dev See {IERC777-operatorSend}.\n *\n * Emits {Sent} and {IERC20-Transfer} events.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes memory data,\n bytes memory operatorData\n ) public virtual override {\n require(isOperatorFor(_msgSender(), sender), \"ERC777: caller is not an operator for holder\");\n _send(sender, recipient, amount, data, operatorData, true);\n }\n\n /**\n * @dev See {IERC777-operatorBurn}.\n *\n * Emits {Burned} and {IERC20-Transfer} events.\n */\n function operatorBurn(\n address account,\n uint256 amount,\n bytes memory data,\n bytes memory operatorData\n ) public virtual override {\n require(isOperatorFor(_msgSender(), account), \"ERC777: caller is not an operator for holder\");\n _burn(account, amount, data, operatorData);\n }\n\n /**\n * @dev See {IERC20-allowance}.\n *\n * Note that operator and allowance concepts are orthogonal: operators may\n * not have allowance, and accounts with allowance may not be operators\n * themselves.\n */\n function allowance(address holder, address spender) public view virtual override returns (uint256) {\n return _allowances[holder][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Note that accounts cannot have allowance issued by their operators.\n */\n function approve(address spender, uint256 value) public virtual override returns (bool) {\n address holder = _msgSender();\n _approve(holder, spender, value);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Note that operator and allowance concepts are orthogonal: operators cannot\n * call `transferFrom` (unless they have allowance), and accounts with\n * allowance cannot call `operatorSend` (unless they are operators).\n *\n * Emits {Sent}, {IERC20-Transfer} and {IERC20-Approval} events.\n */\n function transferFrom(address holder, address recipient, uint256 amount) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(holder, spender, amount);\n _send(holder, recipient, amount, \"\", \"\", false);\n return true;\n }\n\n /**\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with the caller address as the `operator` and with\n * `userData` and `operatorData`.\n *\n * See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits {Minted} and {IERC20-Transfer} events.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - if `account` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function _mint(address account, uint256 amount, bytes memory userData, bytes memory operatorData) internal virtual {\n _mint(account, amount, userData, operatorData, true);\n }\n\n /**\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * If `requireReceptionAck` is set to true, and if a send hook is\n * registered for `account`, the corresponding function will be called with\n * `operator`, `data` and `operatorData`.\n *\n * See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits {Minted} and {IERC20-Transfer} events.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - if `account` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function _mint(\n address account,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) internal virtual {\n require(account != address(0), \"ERC777: mint to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), account, amount);\n\n // Update state variables\n _totalSupply += amount;\n _balances[account] += amount;\n\n _callTokensReceived(operator, address(0), account, amount, userData, operatorData, requireReceptionAck);\n\n emit Minted(operator, account, amount, userData, operatorData);\n emit Transfer(address(0), account, amount);\n }\n\n /**\n * @dev Send tokens\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _send(\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) internal virtual {\n require(from != address(0), \"ERC777: transfer from the zero address\");\n require(to != address(0), \"ERC777: transfer to the zero address\");\n\n address operator = _msgSender();\n\n _callTokensToSend(operator, from, to, amount, userData, operatorData);\n\n _move(operator, from, to, amount, userData, operatorData);\n\n _callTokensReceived(operator, from, to, amount, userData, operatorData, requireReceptionAck);\n }\n\n /**\n * @dev Burn tokens\n * @param from address token holder address\n * @param amount uint256 amount of tokens to burn\n * @param data bytes extra information provided by the token holder\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _burn(address from, uint256 amount, bytes memory data, bytes memory operatorData) internal virtual {\n require(from != address(0), \"ERC777: burn from the zero address\");\n\n address operator = _msgSender();\n\n _callTokensToSend(operator, from, address(0), amount, data, operatorData);\n\n _beforeTokenTransfer(operator, from, address(0), amount);\n\n // Update state variables\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC777: burn amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Burned(operator, from, amount, data, operatorData);\n emit Transfer(from, address(0), amount);\n }\n\n function _move(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n ) private {\n _beforeTokenTransfer(operator, from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC777: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Sent(operator, from, to, amount, userData, operatorData);\n emit Transfer(from, to, amount);\n }\n\n /**\n * @dev See {ERC20-_approve}.\n *\n * Note that accounts cannot have allowance issued by their operators.\n */\n function _approve(address holder, address spender, uint256 value) internal virtual {\n require(holder != address(0), \"ERC777: approve from the zero address\");\n require(spender != address(0), \"ERC777: approve to the zero address\");\n\n _allowances[holder][spender] = value;\n emit Approval(holder, spender, value);\n }\n\n /**\n * @dev Call from.tokensToSend() if the interface is registered\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _callTokensToSend(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n ) private {\n address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(from, _TOKENS_SENDER_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Sender(implementer).tokensToSend(operator, from, to, amount, userData, operatorData);\n }\n }\n\n /**\n * @dev Call to.tokensReceived() if the interface is registered. Reverts if the recipient is a contract but\n * tokensReceived() was not registered for the recipient\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _callTokensReceived(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) private {\n address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(to, _TOKENS_RECIPIENT_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Recipient(implementer).tokensReceived(operator, from, to, amount, userData, operatorData);\n } else if (requireReceptionAck) {\n require(!to.isContract(), \"ERC777: token recipient contract has no implementer for ERC777TokensRecipient\");\n }\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {IERC20-Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC777: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes\n * calls to {send}, {transfer}, {operatorSend}, {transferFrom}, minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be to transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address operator, address from, address to, uint256 amount) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC777/IERC777.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777Token standard as defined in the EIP.\n *\n * This contract uses the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 registry standard] to let\n * token holders and recipients react to token movements by using setting implementers\n * for the associated interfaces in said registry. See {IERC1820Registry} and\n * {ERC1820Implementer}.\n */\ninterface IERC777 {\n /**\n * @dev Emitted when `amount` tokens are created by `operator` and assigned to `to`.\n *\n * Note that some additional user `data` and `operatorData` can be logged in the event.\n */\n event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);\n\n /**\n * @dev Emitted when `operator` destroys `amount` tokens from `account`.\n *\n * Note that some additional user `data` and `operatorData` can be logged in the event.\n */\n event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);\n\n /**\n * @dev Emitted when `operator` is made operator for `tokenHolder`.\n */\n event AuthorizedOperator(address indexed operator, address indexed tokenHolder);\n\n /**\n * @dev Emitted when `operator` is revoked its operator status for `tokenHolder`.\n */\n event RevokedOperator(address indexed operator, address indexed tokenHolder);\n\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, usually a shorter version of the\n * name.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the smallest part of the token that is not divisible. This\n * means all token operations (creation, movement and destruction) must have\n * amounts that are a multiple of this number.\n *\n * For most token contracts, this value will equal 1.\n */\n function granularity() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by an account (`owner`).\n */\n function balanceOf(address owner) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * If send or receive hooks are registered for the caller and `recipient`,\n * the corresponding functions will be called with `data` and empty\n * `operatorData`. See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits a {Sent} event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function send(address recipient, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Destroys `amount` tokens from the caller's account, reducing the\n * total supply.\n *\n * If a send hook is registered for the caller, the corresponding function\n * will be called with `data` and empty `operatorData`. See {IERC777Sender}.\n *\n * Emits a {Burned} event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n */\n function burn(uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Returns true if an account is an operator of `tokenHolder`.\n * Operators can send and burn tokens on behalf of their owners. All\n * accounts are their own operator.\n *\n * See {operatorSend} and {operatorBurn}.\n */\n function isOperatorFor(address operator, address tokenHolder) external view returns (bool);\n\n /**\n * @dev Make an account an operator of the caller.\n *\n * See {isOperatorFor}.\n *\n * Emits an {AuthorizedOperator} event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function authorizeOperator(address operator) external;\n\n /**\n * @dev Revoke an account's operator status for the caller.\n *\n * See {isOperatorFor} and {defaultOperators}.\n *\n * Emits a {RevokedOperator} event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function revokeOperator(address operator) external;\n\n /**\n * @dev Returns the list of default operators. These accounts are operators\n * for all token holders, even if {authorizeOperator} was never called on\n * them.\n *\n * This list is immutable, but individual holders may revoke these via\n * {revokeOperator}, in which case {isOperatorFor} will return false.\n */\n function defaultOperators() external view returns (address[] memory);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must\n * be an operator of `sender`.\n *\n * If send or receive hooks are registered for `sender` and `recipient`,\n * the corresponding functions will be called with `data` and\n * `operatorData`. See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits a {Sent} event.\n *\n * Requirements\n *\n * - `sender` cannot be the zero address.\n * - `sender` must have at least `amount` tokens.\n * - the caller must be an operator for `sender`.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes calldata data,\n bytes calldata operatorData\n ) external;\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the total supply.\n * The caller must be an operator of `account`.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with `data` and `operatorData`. See {IERC777Sender}.\n *\n * Emits a {Burned} event.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n * - the caller must be an operator for `account`.\n */\n function operatorBurn(address account, uint256 amount, bytes calldata data, bytes calldata operatorData) external;\n\n event Sent(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes data,\n bytes operatorData\n );\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\n *\n * Accounts can be notified of {IERC777} tokens being sent to them by having a\n * contract implement this interface (contract holders can be their own\n * implementer) and registering it on the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\n *\n * See {IERC1820Registry} and {ERC1820Implementer}.\n */\ninterface IERC777Recipient {\n /**\n * @dev Called by an {IERC777} token contract whenever tokens are being\n * moved or created into a registered account (`to`). The type of operation\n * is conveyed by `from` being the zero address or not.\n *\n * This call occurs _after_ the token contract's state is updated, so\n * {IERC777-balanceOf}, etc., can be used to query the post-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensReceived(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777Sender.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Sender.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777TokensSender standard as defined in the EIP.\n *\n * {IERC777} Token holders can be notified of operations performed on their\n * tokens by having a contract implement this interface (contract holders can be\n * their own implementer) and registering it on the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\n *\n * See {IERC1820Registry} and {ERC1820Implementer}.\n */\ninterface IERC777Sender {\n /**\n * @dev Called by an {IERC777} token contract whenever a registered holder's\n * (`from`) tokens are about to be moved or destroyed. The type of operation\n * is conveyed by `to` being the zero address or not.\n *\n * This call occurs _before_ the token contract's state is updated, so\n * {IERC777-balanceOf}, etc., can be used to query the pre-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensToSend(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n *\n * Furthermore, `isContract` will also return true if the target contract within\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n * which only has an effect at the end of a transaction.\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Counters.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary Counters {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/ECDSA.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Strings.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV // Deprecated in v4.8\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n /// @solidity memory-safe-assembly\n assembly {\n mstore(0x00, \"\\x19Ethereum Signed Message:\\n32\")\n mstore(0x1c, hash)\n message := keccak256(0x00, 0x3c)\n }\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\n /// @solidity memory-safe-assembly\n assembly {\n let ptr := mload(0x40)\n mstore(ptr, \"\\x19\\x01\")\n mstore(add(ptr, 0x02), domainSeparator)\n mstore(add(ptr, 0x22), structHash)\n data := keccak256(ptr, 0x42)\n }\n }\n\n /**\n * @dev Returns an Ethereum Signed Data with intended validator, created from a\n * `validator` and `data` according to the version 0 of EIP-191.\n *\n * See {recover}.\n */\n function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x00\", validator, data));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/SignatureChecker.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSA.sol\";\nimport \"../../interfaces/IERC1271.sol\";\n\n/**\n * @dev Signature verification helper that can be used instead of `ECDSA.recover` to seamlessly support both ECDSA\n * signatures from externally owned accounts (EOAs) as well as ERC1271 signatures from smart contract wallets like\n * Argent and Gnosis Safe.\n *\n * _Available since v4.1._\n */\nlibrary SignatureChecker {\n /**\n * @dev Checks if a signature is valid for a given signer and data hash. If the signer is a smart contract, the\n * signature is validated against that smart contract using ERC1271, otherwise it's validated using `ECDSA.recover`.\n *\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\n */\n function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature) internal view returns (bool) {\n (address recovered, ECDSA.RecoverError error) = ECDSA.tryRecover(hash, signature);\n return\n (error == ECDSA.RecoverError.NoError && recovered == signer) ||\n isValidERC1271SignatureNow(signer, hash, signature);\n }\n\n /**\n * @dev Checks if a signature is valid for a given signer and data hash. The signature is validated\n * against the signer smart contract using ERC1271.\n *\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\n */\n function isValidERC1271SignatureNow(\n address signer,\n bytes32 hash,\n bytes memory signature\n ) internal view returns (bool) {\n (bool success, bytes memory result) = signer.staticcall(\n abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, signature)\n );\n return (success &&\n result.length >= 32 &&\n abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/ERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165 is IERC165 {\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165).interfaceId;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC1820Registry.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/introspection/IERC1820Registry.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the global ERC1820 Registry, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register\n * implementers for interfaces in this registry, as well as query support.\n *\n * Implementers may be shared by multiple accounts, and can also implement more\n * than a single interface for each account. Contracts can implement interfaces\n * for themselves, but externally-owned accounts (EOA) must delegate this to a\n * contract.\n *\n * {IERC165} interfaces can also be queried via the registry.\n *\n * For an in-depth explanation and source code analysis, see the EIP text.\n */\ninterface IERC1820Registry {\n event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer);\n\n event ManagerChanged(address indexed account, address indexed newManager);\n\n /**\n * @dev Sets `newManager` as the manager for `account`. A manager of an\n * account is able to set interface implementers for it.\n *\n * By default, each account is its own manager. Passing a value of `0x0` in\n * `newManager` will reset the manager to this initial state.\n *\n * Emits a {ManagerChanged} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `account`.\n */\n function setManager(address account, address newManager) external;\n\n /**\n * @dev Returns the manager for `account`.\n *\n * See {setManager}.\n */\n function getManager(address account) external view returns (address);\n\n /**\n * @dev Sets the `implementer` contract as ``account``'s implementer for\n * `interfaceHash`.\n *\n * `account` being the zero address is an alias for the caller's address.\n * The zero address can also be used in `implementer` to remove an old one.\n *\n * See {interfaceHash} to learn how these are created.\n *\n * Emits an {InterfaceImplementerSet} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `account`.\n * - `interfaceHash` must not be an {IERC165} interface id (i.e. it must not\n * end in 28 zeroes).\n * - `implementer` must implement {IERC1820Implementer} and return true when\n * queried for support, unless `implementer` is the caller. See\n * {IERC1820Implementer-canImplementInterfaceForAddress}.\n */\n function setInterfaceImplementer(address account, bytes32 _interfaceHash, address implementer) external;\n\n /**\n * @dev Returns the implementer of `interfaceHash` for `account`. If no such\n * implementer is registered, returns the zero address.\n *\n * If `interfaceHash` is an {IERC165} interface id (i.e. it ends with 28\n * zeroes), `account` will be queried for support of it.\n *\n * `account` being the zero address is an alias for the caller's address.\n */\n function getInterfaceImplementer(address account, bytes32 _interfaceHash) external view returns (address);\n\n /**\n * @dev Returns the interface hash for an `interfaceName`, as defined in the\n * corresponding\n * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP].\n */\n function interfaceHash(string calldata interfaceName) external pure returns (bytes32);\n\n /**\n * @notice Updates the cache with whether the contract implements an ERC165 interface or not.\n * @param account Address of the contract for which to update the cache.\n * @param interfaceId ERC165 interface for which to update the cache.\n */\n function updateERC165Cache(address account, bytes4 interfaceId) external;\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not.\n * If the result is not cached a direct lookup on the contract address is performed.\n * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling\n * {updateERC165Cache} with the contract address.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool);\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not without using or updating the cache.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/math/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\n // The surrounding unchecked block does not change this fact.\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1, \"Math: mulDiv overflow\");\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n //\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n //\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n //\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1 << (log2(a) >> 1);\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = sqrt(a);\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 2, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 128;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 64;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 32;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 16;\n }\n if (value >> 8 > 0) {\n value >>= 8;\n result += 8;\n }\n if (value >> 4 > 0) {\n value >>= 4;\n result += 4;\n }\n if (value >> 2 > 0) {\n value >>= 2;\n result += 2;\n }\n if (value >> 1 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log2(value);\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 10, rounded down, of a positive value.\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 + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 256, rounded down, of a positive value.\n * Returns 0 if given 0.\n *\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n */\n function log256(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 16;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 8;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 4;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 2;\n }\n if (value >> 8 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log256(value);\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/SafeCast.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCast {\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 * _Available since v4.7._\n */\n function toUint248(uint256 value) internal pure returns (uint248) {\n require(value <= type(uint248).max, \"SafeCast: value doesn't fit in 248 bits\");\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 * _Available since v4.7._\n */\n function toUint240(uint256 value) internal pure returns (uint240) {\n require(value <= type(uint240).max, \"SafeCast: value doesn't fit in 240 bits\");\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 * _Available since v4.7._\n */\n function toUint232(uint256 value) internal pure returns (uint232) {\n require(value <= type(uint232).max, \"SafeCast: value doesn't fit in 232 bits\");\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 * _Available since v4.2._\n */\n function toUint224(uint256 value) internal pure returns (uint224) {\n require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\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 * _Available since v4.7._\n */\n function toUint216(uint256 value) internal pure returns (uint216) {\n require(value <= type(uint216).max, \"SafeCast: value doesn't fit in 216 bits\");\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 * _Available since v4.7._\n */\n function toUint208(uint256 value) internal pure returns (uint208) {\n require(value <= type(uint208).max, \"SafeCast: value doesn't fit in 208 bits\");\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 * _Available since v4.7._\n */\n function toUint200(uint256 value) internal pure returns (uint200) {\n require(value <= type(uint200).max, \"SafeCast: value doesn't fit in 200 bits\");\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 * _Available since v4.7._\n */\n function toUint192(uint256 value) internal pure returns (uint192) {\n require(value <= type(uint192).max, \"SafeCast: value doesn't fit in 192 bits\");\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 * _Available since v4.7._\n */\n function toUint184(uint256 value) internal pure returns (uint184) {\n require(value <= type(uint184).max, \"SafeCast: value doesn't fit in 184 bits\");\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 * _Available since v4.7._\n */\n function toUint176(uint256 value) internal pure returns (uint176) {\n require(value <= type(uint176).max, \"SafeCast: value doesn't fit in 176 bits\");\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 * _Available since v4.7._\n */\n function toUint168(uint256 value) internal pure returns (uint168) {\n require(value <= type(uint168).max, \"SafeCast: value doesn't fit in 168 bits\");\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 * _Available since v4.7._\n */\n function toUint160(uint256 value) internal pure returns (uint160) {\n require(value <= type(uint160).max, \"SafeCast: value doesn't fit in 160 bits\");\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 * _Available since v4.7._\n */\n function toUint152(uint256 value) internal pure returns (uint152) {\n require(value <= type(uint152).max, \"SafeCast: value doesn't fit in 152 bits\");\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 * _Available since v4.7._\n */\n function toUint144(uint256 value) internal pure returns (uint144) {\n require(value <= type(uint144).max, \"SafeCast: value doesn't fit in 144 bits\");\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 * _Available since v4.7._\n */\n function toUint136(uint256 value) internal pure returns (uint136) {\n require(value <= type(uint136).max, \"SafeCast: value doesn't fit in 136 bits\");\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 * _Available since v2.5._\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\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 * _Available since v4.7._\n */\n function toUint120(uint256 value) internal pure returns (uint120) {\n require(value <= type(uint120).max, \"SafeCast: value doesn't fit in 120 bits\");\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 * _Available since v4.7._\n */\n function toUint112(uint256 value) internal pure returns (uint112) {\n require(value <= type(uint112).max, \"SafeCast: value doesn't fit in 112 bits\");\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 * _Available since v4.7._\n */\n function toUint104(uint256 value) internal pure returns (uint104) {\n require(value <= type(uint104).max, \"SafeCast: value doesn't fit in 104 bits\");\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 * _Available since v4.2._\n */\n function toUint96(uint256 value) internal pure returns (uint96) {\n require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\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 * _Available since v4.7._\n */\n function toUint88(uint256 value) internal pure returns (uint88) {\n require(value <= type(uint88).max, \"SafeCast: value doesn't fit in 88 bits\");\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 * _Available since v4.7._\n */\n function toUint80(uint256 value) internal pure returns (uint80) {\n require(value <= type(uint80).max, \"SafeCast: value doesn't fit in 80 bits\");\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 * _Available since v4.7._\n */\n function toUint72(uint256 value) internal pure returns (uint72) {\n require(value <= type(uint72).max, \"SafeCast: value doesn't fit in 72 bits\");\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 * _Available since v2.5._\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\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 * _Available since v4.7._\n */\n function toUint56(uint256 value) internal pure returns (uint56) {\n require(value <= type(uint56).max, \"SafeCast: value doesn't fit in 56 bits\");\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 * _Available since v4.7._\n */\n function toUint48(uint256 value) internal pure returns (uint48) {\n require(value <= type(uint48).max, \"SafeCast: value doesn't fit in 48 bits\");\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 * _Available since v4.7._\n */\n function toUint40(uint256 value) internal pure returns (uint40) {\n require(value <= type(uint40).max, \"SafeCast: value doesn't fit in 40 bits\");\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 * _Available since v2.5._\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\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 * _Available since v4.7._\n */\n function toUint24(uint256 value) internal pure returns (uint24) {\n require(value <= type(uint24).max, \"SafeCast: value doesn't fit in 24 bits\");\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 * _Available since v2.5._\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\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 * _Available since v2.5._\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\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 * _Available since v3.0._\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\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 * _Available since v4.7._\n */\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\n downcasted = int248(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 248 bits\");\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 * _Available since v4.7._\n */\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\n downcasted = int240(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 240 bits\");\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 * _Available since v4.7._\n */\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\n downcasted = int232(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 232 bits\");\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 * _Available since v4.7._\n */\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\n downcasted = int224(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 224 bits\");\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 * _Available since v4.7._\n */\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\n downcasted = int216(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 216 bits\");\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 * _Available since v4.7._\n */\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\n downcasted = int208(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 208 bits\");\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 * _Available since v4.7._\n */\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\n downcasted = int200(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 200 bits\");\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 * _Available since v4.7._\n */\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\n downcasted = int192(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 192 bits\");\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 * _Available since v4.7._\n */\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\n downcasted = int184(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 184 bits\");\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 * _Available since v4.7._\n */\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\n downcasted = int176(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 176 bits\");\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 * _Available since v4.7._\n */\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\n downcasted = int168(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 168 bits\");\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 * _Available since v4.7._\n */\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\n downcasted = int160(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 160 bits\");\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 * _Available since v4.7._\n */\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\n downcasted = int152(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 152 bits\");\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 * _Available since v4.7._\n */\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\n downcasted = int144(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 144 bits\");\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 * _Available since v4.7._\n */\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\n downcasted = int136(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 136 bits\");\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 * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\n downcasted = int128(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 128 bits\");\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 * _Available since v4.7._\n */\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\n downcasted = int120(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 120 bits\");\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 * _Available since v4.7._\n */\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\n downcasted = int112(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 112 bits\");\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 * _Available since v4.7._\n */\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\n downcasted = int104(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 104 bits\");\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 * _Available since v4.7._\n */\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\n downcasted = int96(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 96 bits\");\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 * _Available since v4.7._\n */\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\n downcasted = int88(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 88 bits\");\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 * _Available since v4.7._\n */\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\n downcasted = int80(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 80 bits\");\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 * _Available since v4.7._\n */\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\n downcasted = int72(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 72 bits\");\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 * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\n downcasted = int64(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 64 bits\");\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 * _Available since v4.7._\n */\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\n downcasted = int56(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 56 bits\");\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 * _Available since v4.7._\n */\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\n downcasted = int48(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 48 bits\");\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 * _Available since v4.7._\n */\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\n downcasted = int40(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 40 bits\");\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 * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\n downcasted = int32(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 32 bits\");\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 * _Available since v4.7._\n */\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\n downcasted = int24(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 24 bits\");\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 * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\n downcasted = int16(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 16 bits\");\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 * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\n downcasted = int8(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 8 bits\");\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 * _Available since v3.0._\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 require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/SignedMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard signed math utilities missing in the Solidity language.\n */\nlibrary SignedMath {\n /**\n * @dev Returns the largest of two signed numbers.\n */\n function max(int256 a, int256 b) internal pure returns (int256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two signed numbers.\n */\n function min(int256 a, int256 b) internal pure returns (int256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two signed numbers without overflow.\n * The result is rounded towards zero.\n */\n function average(int256 a, int256 b) internal pure returns (int256) {\n // Formula from the book \"Hacker's Delight\"\n int256 x = (a & b) + ((a ^ b) >> 1);\n return x + (int256(uint256(x) >> 255) & (a ^ b));\n }\n\n /**\n * @dev Returns the absolute unsigned value of a signed value.\n */\n function abs(int256 n) internal pure returns (uint256) {\n unchecked {\n // must be unchecked in order to support `n = type(int256).min`\n return uint256(n >= 0 ? n : -n);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/Math.sol\";\nimport \"./math/SignedMath.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n unchecked {\n uint256 length = Math.log10(value) + 1;\n string memory buffer = new string(length);\n uint256 ptr;\n /// @solidity memory-safe-assembly\n assembly {\n ptr := add(buffer, add(32, length))\n }\n while (true) {\n ptr--;\n /// @solidity memory-safe-assembly\n assembly {\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n }\n value /= 10;\n if (value == 0) break;\n }\n return buffer;\n }\n }\n\n /**\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\n */\n function toString(int256 value) internal pure returns (string memory) {\n return string(abi.encodePacked(value < 0 ? \"-\" : \"\", toString(SignedMath.abs(value))));\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n unchecked {\n return toHexString(value, Math.log256(value) + 1);\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n\n /**\n * @dev Returns true if the two strings are equal.\n */\n function equal(string memory a, string memory b) internal pure returns (bool) {\n return keccak256(bytes(a)) == keccak256(bytes(b));\n }\n}\n" + }, + "contracts/aa-4337/core/BaseAccount.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-empty-blocks */\n\nimport \"../interfaces/IAccount.sol\";\nimport \"../interfaces/IEntryPoint.sol\";\nimport \"./Helpers.sol\";\n\n/**\n * Basic account implementation.\n * this contract provides the basic logic for implementing the IAccount interface - validateUserOp\n * specific account implementation should inherit it and provide the account-specific logic\n */\nabstract contract BaseAccount is IAccount {\n using UserOperationLib for UserOperation;\n\n //return value in case of signature failure, with no time-range.\n // equivalent to _packValidationData(true,0,0);\n uint256 internal constant SIG_VALIDATION_FAILED = 1;\n\n /**\n * Return the account nonce.\n * This method returns the next sequential nonce.\n * For a nonce of a specific key, use `entrypoint.getNonce(account, key)`\n */\n function getNonce() public view virtual returns (uint256) {\n return entryPoint().getNonce(address(this), 0);\n }\n\n /**\n * return the entryPoint used by this account.\n * subclass should return the current entryPoint used by this account.\n */\n function entryPoint() public view virtual returns (IEntryPoint);\n\n /**\n * Validate user's signature and nonce.\n * subclass doesn't need to override this method. Instead, it should override the specific internal validation methods.\n */\n function validateUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 missingAccountFunds\n ) external virtual override returns (uint256 validationData) {\n _requireFromEntryPoint();\n validationData = _validateSignature(userOp, userOpHash);\n _validateNonce(userOp.nonce);\n _payPrefund(missingAccountFunds);\n }\n\n /**\n * ensure the request comes from the known entrypoint.\n */\n function _requireFromEntryPoint() internal view virtual {\n require(\n msg.sender == address(entryPoint()),\n \"account: not from EntryPoint\"\n );\n }\n\n /**\n * validate the signature is valid for this message.\n * @param userOp validate the userOp.signature field\n * @param userOpHash convenient field: the hash of the request, to check the signature against\n * (also hashes the entrypoint and chain id)\n * @return validationData signature and time-range of this operation\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * If the account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function _validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) internal virtual returns (uint256 validationData);\n\n /**\n * Validate the nonce of the UserOperation.\n * This method may validate the nonce requirement of this account.\n * e.g.\n * To limit the nonce to use sequenced UserOps only (no \"out of order\" UserOps):\n * `require(nonce < type(uint64).max)`\n * For a hypothetical account that *requires* the nonce to be out-of-order:\n * `require(nonce & type(uint64).max == 0)`\n *\n * The actual nonce uniqueness is managed by the EntryPoint, and thus no other\n * action is needed by the account itself.\n *\n * @param nonce to validate\n *\n * solhint-disable-next-line no-empty-blocks\n */\n function _validateNonce(uint256 nonce) internal view virtual {}\n\n /**\n * sends to the entrypoint (msg.sender) the missing funds for this transaction.\n * subclass MAY override this method for better funds management\n * (e.g. send to the entryPoint more than the minimum required, so that in future transactions\n * it will not be required to send again)\n * @param missingAccountFunds the minimum value this method should send the entrypoint.\n * this value MAY be zero, in case there is enough deposit, or the userOp has a paymaster.\n */\n function _payPrefund(uint256 missingAccountFunds) internal virtual {\n if (missingAccountFunds != 0) {\n (bool success, ) = payable(msg.sender).call{\n value: missingAccountFunds,\n gas: type(uint256).max\n }(\"\");\n (success);\n //ignore failure (its EntryPoint's job to verify, not account.)\n }\n }\n}\n" + }, + "contracts/aa-4337/core/EntryPoint.sol": { + "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n\nimport \"../interfaces/IAccount.sol\";\nimport \"../interfaces/IPaymaster.sol\";\nimport \"../interfaces/IEntryPoint.sol\";\n\nimport \"../utils/Exec.sol\";\nimport \"./StakeManager.sol\";\nimport \"./SenderCreator.sol\";\nimport \"./Helpers.sol\";\nimport \"./NonceManager.sol\";\nimport \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\n\ncontract EntryPoint is\n IEntryPoint,\n StakeManager,\n NonceManager,\n ReentrancyGuard\n{\n using UserOperationLib for UserOperation;\n\n SenderCreator private immutable senderCreator = new SenderCreator();\n\n // internal value used during simulation: need to query aggregator.\n address private constant SIMULATE_FIND_AGGREGATOR = address(1);\n\n // marker for inner call revert on out of gas\n bytes32 private constant INNER_OUT_OF_GAS = hex\"deaddead\";\n\n uint256 private constant REVERT_REASON_MAX_LEN = 2048;\n\n /**\n * for simulation purposes, validateUserOp (and validatePaymasterUserOp) must return this value\n * in case of signature failure, instead of revert.\n */\n uint256 public constant SIG_VALIDATION_FAILED = 1;\n\n /**\n * compensate the caller's beneficiary address with the collected fees of all UserOperations.\n * @param beneficiary the address to receive the fees\n * @param amount amount to transfer.\n */\n function _compensate(address payable beneficiary, uint256 amount) internal {\n require(beneficiary != address(0), \"AA90 invalid beneficiary\");\n (bool success, ) = beneficiary.call{value: amount}(\"\");\n require(success, \"AA91 failed send to beneficiary\");\n }\n\n /**\n * execute a user op\n * @param opIndex index into the opInfo array\n * @param userOp the userOp to execute\n * @param opInfo the opInfo filled by validatePrepayment for this userOp.\n * @return collected the total amount this userOp paid.\n */\n function _executeUserOp(\n uint256 opIndex,\n UserOperation calldata userOp,\n UserOpInfo memory opInfo\n ) private returns (uint256 collected) {\n uint256 preGas = gasleft();\n bytes memory context = getMemoryBytesFromOffset(opInfo.contextOffset);\n\n try this.innerHandleOp(userOp.callData, opInfo, context) returns (\n uint256 _actualGasCost\n ) {\n collected = _actualGasCost;\n } catch {\n bytes32 innerRevertCode;\n assembly {\n returndatacopy(0, 0, 32)\n innerRevertCode := mload(0)\n }\n // handleOps was called with gas limit too low. abort entire bundle.\n if (innerRevertCode == INNER_OUT_OF_GAS) {\n //report paymaster, since if it is not deliberately caused by the bundler,\n // it must be a revert caused by paymaster.\n revert FailedOp(opIndex, \"AA95 out of gas\");\n }\n\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n collected = _handlePostOp(\n opIndex,\n IPaymaster.PostOpMode.postOpReverted,\n opInfo,\n context,\n actualGas\n );\n }\n }\n\n /**\n * Execute a batch of UserOperations.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(\n UserOperation[] calldata ops,\n address payable beneficiary\n ) public nonReentrant {\n uint256 opslen = ops.length;\n UserOpInfo[] memory opInfos = new UserOpInfo[](opslen);\n\n unchecked {\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[i];\n (\n uint256 validationData,\n uint256 pmValidationData\n ) = _validatePrepayment(i, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(\n i,\n validationData,\n pmValidationData,\n address(0)\n );\n }\n\n uint256 collected = 0;\n emit BeforeExecution();\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(i, ops[i], opInfos[i]);\n }\n\n _compensate(beneficiary, collected);\n } //unchecked\n }\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) public nonReentrant {\n uint256 opasLen = opsPerAggregator.length;\n uint256 totalOps = 0;\n for (uint256 i = 0; i < opasLen; i++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[i];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n //address(1) is special marker of \"signature error\"\n require(\n address(aggregator) != address(1),\n \"AA96 invalid aggregator\"\n );\n\n if (address(aggregator) != address(0)) {\n // solhint-disable-next-line no-empty-blocks\n try aggregator.validateSignatures(ops, opa.signature) {} catch {\n revert SignatureValidationFailed(address(aggregator));\n }\n }\n\n totalOps += ops.length;\n }\n\n UserOpInfo[] memory opInfos = new UserOpInfo[](totalOps);\n\n emit BeforeExecution();\n\n uint256 opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n uint256 opslen = ops.length;\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[opIndex];\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(opIndex, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(\n i,\n validationData,\n paymasterValidationData,\n address(aggregator)\n );\n opIndex++;\n }\n }\n\n uint256 collected = 0;\n opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n emit SignatureAggregatorChanged(address(opa.aggregator));\n UserOperation[] calldata ops = opa.userOps;\n uint256 opslen = ops.length;\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(opIndex, ops[i], opInfos[opIndex]);\n opIndex++;\n }\n }\n emit SignatureAggregatorChanged(address(0));\n\n _compensate(beneficiary, collected);\n }\n\n /// @inheritdoc IEntryPoint\n function simulateHandleOp(\n UserOperation calldata op,\n address target,\n bytes calldata targetCallData\n ) external override {\n UserOpInfo memory opInfo;\n _simulationOnlyValidations(op);\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(0, op, opInfo);\n ValidationData memory data = _intersectTimeRange(\n validationData,\n paymasterValidationData\n );\n\n numberMarker();\n uint256 paid = _executeUserOp(0, op, opInfo);\n numberMarker();\n bool targetSuccess;\n bytes memory targetResult;\n if (target != address(0)) {\n (targetSuccess, targetResult) = target.call(targetCallData);\n }\n revert ExecutionResult(\n opInfo.preOpGas,\n paid,\n data.validAfter,\n data.validUntil,\n targetSuccess,\n targetResult\n );\n }\n\n // A memory copy of UserOp static fields only.\n // Excluding: callData, initCode and signature. Replacing paymasterAndData with paymaster.\n struct MemoryUserOp {\n address sender;\n uint256 nonce;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n address paymaster;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n }\n\n struct UserOpInfo {\n MemoryUserOp mUserOp;\n bytes32 userOpHash;\n uint256 prefund;\n uint256 contextOffset;\n uint256 preOpGas;\n }\n\n /**\n * inner function to handle a UserOperation.\n * Must be declared \"external\" to open a call context, but it can only be called by handleOps.\n */\n function innerHandleOp(\n bytes memory callData,\n UserOpInfo memory opInfo,\n bytes calldata context\n ) external returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n require(msg.sender == address(this), \"AA92 internal call only\");\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n\n uint callGasLimit = mUserOp.callGasLimit;\n unchecked {\n // handleOps was called with gas limit too low. abort entire bundle.\n if (\n gasleft() < callGasLimit + mUserOp.verificationGasLimit + 5000\n ) {\n assembly {\n mstore(0, INNER_OUT_OF_GAS)\n revert(0, 32)\n }\n }\n }\n\n IPaymaster.PostOpMode mode = IPaymaster.PostOpMode.opSucceeded;\n if (callData.length > 0) {\n bool success = Exec.call(mUserOp.sender, 0, callData, callGasLimit);\n if (!success) {\n bytes memory result = Exec.getReturnData(REVERT_REASON_MAX_LEN);\n if (result.length > 0) {\n emit UserOperationRevertReason(\n opInfo.userOpHash,\n mUserOp.sender,\n mUserOp.nonce,\n result\n );\n }\n mode = IPaymaster.PostOpMode.opReverted;\n }\n }\n\n unchecked {\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n //note: opIndex is ignored (relevant only if mode==postOpReverted, which is only possible outside of innerHandleOp)\n return _handlePostOp(0, mode, opInfo, context, actualGas);\n }\n }\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(\n UserOperation calldata userOp\n ) public view returns (bytes32) {\n return\n keccak256(abi.encode(userOp.hash(), address(this), block.chainid));\n }\n\n /**\n * copy general fields from userOp into the memory opInfo structure.\n */\n function _copyUserOpToMemory(\n UserOperation calldata userOp,\n MemoryUserOp memory mUserOp\n ) internal pure {\n mUserOp.sender = userOp.sender;\n mUserOp.nonce = userOp.nonce;\n mUserOp.callGasLimit = userOp.callGasLimit;\n mUserOp.verificationGasLimit = userOp.verificationGasLimit;\n mUserOp.preVerificationGas = userOp.preVerificationGas;\n mUserOp.maxFeePerGas = userOp.maxFeePerGas;\n mUserOp.maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes calldata paymasterAndData = userOp.paymasterAndData;\n if (paymasterAndData.length > 0) {\n require(\n paymasterAndData.length >= 20,\n \"AA93 invalid paymasterAndData\"\n );\n mUserOp.paymaster = address(bytes20(paymasterAndData[:20]));\n } else {\n mUserOp.paymaster = address(0);\n }\n }\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external {\n UserOpInfo memory outOpInfo;\n\n _simulationOnlyValidations(userOp);\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(0, userOp, outOpInfo);\n StakeInfo memory paymasterInfo = _getStakeInfo(\n outOpInfo.mUserOp.paymaster\n );\n StakeInfo memory senderInfo = _getStakeInfo(outOpInfo.mUserOp.sender);\n StakeInfo memory factoryInfo;\n {\n bytes calldata initCode = userOp.initCode;\n address factory = initCode.length >= 20\n ? address(bytes20(initCode[0:20]))\n : address(0);\n factoryInfo = _getStakeInfo(factory);\n }\n\n ValidationData memory data = _intersectTimeRange(\n validationData,\n paymasterValidationData\n );\n address aggregator = data.aggregator;\n bool sigFailed = aggregator == address(1);\n ReturnInfo memory returnInfo = ReturnInfo(\n outOpInfo.preOpGas,\n outOpInfo.prefund,\n sigFailed,\n data.validAfter,\n data.validUntil,\n getMemoryBytesFromOffset(outOpInfo.contextOffset)\n );\n\n if (aggregator != address(0) && aggregator != address(1)) {\n AggregatorStakeInfo memory aggregatorInfo = AggregatorStakeInfo(\n aggregator,\n _getStakeInfo(aggregator)\n );\n revert ValidationResultWithAggregation(\n returnInfo,\n senderInfo,\n factoryInfo,\n paymasterInfo,\n aggregatorInfo\n );\n }\n revert ValidationResult(\n returnInfo,\n senderInfo,\n factoryInfo,\n paymasterInfo\n );\n }\n\n function _getRequiredPrefund(\n MemoryUserOp memory mUserOp\n ) internal pure returns (uint256 requiredPrefund) {\n unchecked {\n //when using a Paymaster, the verificationGasLimit is used also to as a limit for the postOp call.\n // our security model might call postOp eventually twice\n uint256 mul = mUserOp.paymaster != address(0) ? 3 : 1;\n uint256 requiredGas = mUserOp.callGasLimit +\n mUserOp.verificationGasLimit *\n mul +\n mUserOp.preVerificationGas;\n\n requiredPrefund = requiredGas * mUserOp.maxFeePerGas;\n }\n }\n\n // create the sender's contract if needed.\n function _createSenderIfNeeded(\n uint256 opIndex,\n UserOpInfo memory opInfo,\n bytes calldata initCode\n ) internal {\n if (initCode.length != 0) {\n address sender = opInfo.mUserOp.sender;\n if (sender.code.length != 0)\n revert FailedOp(opIndex, \"AA10 sender already constructed\");\n address sender1 = senderCreator.createSender{\n gas: opInfo.mUserOp.verificationGasLimit\n }(initCode);\n if (sender1 == address(0))\n revert FailedOp(opIndex, \"AA13 initCode failed or OOG\");\n if (sender1 != sender)\n revert FailedOp(opIndex, \"AA14 initCode must return sender\");\n if (sender1.code.length == 0)\n revert FailedOp(opIndex, \"AA15 initCode must create sender\");\n address factory = address(bytes20(initCode[0:20]));\n emit AccountDeployed(\n opInfo.userOpHash,\n sender,\n factory,\n opInfo.mUserOp.paymaster\n );\n }\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes calldata initCode) public {\n address sender = senderCreator.createSender(initCode);\n revert SenderAddressResult(sender);\n }\n\n function _simulationOnlyValidations(\n UserOperation calldata userOp\n ) internal view {\n // solhint-disable-next-line no-empty-blocks\n try\n this._validateSenderAndPaymaster(\n userOp.initCode,\n userOp.sender,\n userOp.paymasterAndData\n )\n {} catch Error(string memory revertReason) {\n if (bytes(revertReason).length != 0) {\n revert FailedOp(0, revertReason);\n }\n }\n }\n\n /**\n * Called only during simulation.\n * This function always reverts to prevent warm/cold storage differentiation in simulation vs execution.\n */\n function _validateSenderAndPaymaster(\n bytes calldata initCode,\n address sender,\n bytes calldata paymasterAndData\n ) external view {\n if (initCode.length == 0 && sender.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA20 account not deployed\");\n }\n if (paymasterAndData.length >= 20) {\n address paymaster = address(bytes20(paymasterAndData[0:20]));\n if (paymaster.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA30 paymaster not deployed\");\n }\n }\n // always revert\n revert(\"\");\n }\n\n /**\n * call account.validateUserOp.\n * revert (with FailedOp) in case validateUserOp reverts, or account didn't send required prefund.\n * decrement account's deposit if needed\n */\n function _validateAccountPrepayment(\n uint256 opIndex,\n UserOperation calldata op,\n UserOpInfo memory opInfo,\n uint256 requiredPrefund\n )\n internal\n returns (\n uint256 gasUsedByValidateAccountPrepayment,\n uint256 validationData\n )\n {\n unchecked {\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n address sender = mUserOp.sender;\n _createSenderIfNeeded(opIndex, opInfo, op.initCode);\n address paymaster = mUserOp.paymaster;\n numberMarker();\n uint256 missingAccountFunds = 0;\n if (paymaster == address(0)) {\n uint256 bal = balanceOf(sender);\n missingAccountFunds = bal > requiredPrefund\n ? 0\n : requiredPrefund - bal;\n }\n try\n IAccount(sender).validateUserOp{\n gas: mUserOp.verificationGasLimit\n }(op, opInfo.userOpHash, missingAccountFunds)\n returns (uint256 _validationData) {\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA23 reverted: \", revertReason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA23 reverted (or OOG)\");\n }\n if (paymaster == address(0)) {\n DepositInfo storage senderInfo = deposits[sender];\n uint256 deposit = senderInfo.deposit;\n if (requiredPrefund > deposit) {\n revert FailedOp(opIndex, \"AA21 didn't pay prefund\");\n }\n senderInfo.deposit = uint112(deposit - requiredPrefund);\n }\n gasUsedByValidateAccountPrepayment = preGas - gasleft();\n }\n }\n\n /**\n * In case the request has a paymaster:\n * Validate paymaster has enough deposit.\n * Call paymaster.validatePaymasterUserOp.\n * Revert with proper FailedOp in case paymaster reverts.\n * Decrement paymaster's deposit\n */\n function _validatePaymasterPrepayment(\n uint256 opIndex,\n UserOperation calldata op,\n UserOpInfo memory opInfo,\n uint256 requiredPreFund,\n uint256 gasUsedByValidateAccountPrepayment\n ) internal returns (bytes memory context, uint256 validationData) {\n unchecked {\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 verificationGasLimit = mUserOp.verificationGasLimit;\n require(\n verificationGasLimit > gasUsedByValidateAccountPrepayment,\n \"AA41 too little verificationGas\"\n );\n uint256 gas = verificationGasLimit -\n gasUsedByValidateAccountPrepayment;\n\n address paymaster = mUserOp.paymaster;\n DepositInfo storage paymasterInfo = deposits[paymaster];\n uint256 deposit = paymasterInfo.deposit;\n if (deposit < requiredPreFund) {\n revert FailedOp(opIndex, \"AA31 paymaster deposit too low\");\n }\n paymasterInfo.deposit = uint112(deposit - requiredPreFund);\n try\n IPaymaster(paymaster).validatePaymasterUserOp{gas: gas}(\n op,\n opInfo.userOpHash,\n requiredPreFund\n )\n returns (bytes memory _context, uint256 _validationData) {\n context = _context;\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA33 reverted: \", revertReason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA33 reverted (or OOG)\");\n }\n }\n }\n\n /**\n * revert if either account validationData or paymaster validationData is expired\n */\n function _validateAccountAndPaymasterValidationData(\n uint256 opIndex,\n uint256 validationData,\n uint256 paymasterValidationData,\n address expectedAggregator\n ) internal view {\n (address aggregator, bool outOfTimeRange) = _getValidationData(\n validationData\n );\n if (expectedAggregator != aggregator) {\n revert FailedOp(opIndex, \"AA24 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA22 expired or not due\");\n }\n //pmAggregator is not a real signature aggregator: we don't have logic to handle it as address.\n // non-zero address means that the paymaster fails due to some signature check (which is ok only during estimation)\n address pmAggregator;\n (pmAggregator, outOfTimeRange) = _getValidationData(\n paymasterValidationData\n );\n if (pmAggregator != address(0)) {\n revert FailedOp(opIndex, \"AA34 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA32 paymaster expired or not due\");\n }\n }\n\n function _getValidationData(\n uint256 validationData\n ) internal view returns (address aggregator, bool outOfTimeRange) {\n if (validationData == 0) {\n return (address(0), false);\n }\n ValidationData memory data = _parseValidationData(validationData);\n // solhint-disable-next-line not-rely-on-time\n outOfTimeRange =\n block.timestamp > data.validUntil ||\n block.timestamp < data.validAfter;\n aggregator = data.aggregator;\n }\n\n /**\n * validate account and paymaster (if defined).\n * also make sure total validation doesn't exceed verificationGasLimit\n * this method is called off-chain (simulateValidation()) and on-chain (from handleOps)\n * @param opIndex the index of this userOp into the \"opInfos\" array\n * @param userOp the userOp to validate\n */\n function _validatePrepayment(\n uint256 opIndex,\n UserOperation calldata userOp,\n UserOpInfo memory outOpInfo\n )\n private\n returns (uint256 validationData, uint256 paymasterValidationData)\n {\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = outOpInfo.mUserOp;\n _copyUserOpToMemory(userOp, mUserOp);\n outOpInfo.userOpHash = getUserOpHash(userOp);\n\n // validate all numeric values in userOp are well below 128 bit, so they can safely be added\n // and multiplied without causing overflow\n uint256 maxGasValues = mUserOp.preVerificationGas |\n mUserOp.verificationGasLimit |\n mUserOp.callGasLimit |\n userOp.maxFeePerGas |\n userOp.maxPriorityFeePerGas;\n require(maxGasValues <= type(uint120).max, \"AA94 gas values overflow\");\n\n uint256 gasUsedByValidateAccountPrepayment;\n uint256 requiredPreFund = _getRequiredPrefund(mUserOp);\n (\n gasUsedByValidateAccountPrepayment,\n validationData\n ) = _validateAccountPrepayment(\n opIndex,\n userOp,\n outOpInfo,\n requiredPreFund\n );\n\n if (!_validateAndUpdateNonce(mUserOp.sender, mUserOp.nonce)) {\n revert FailedOp(opIndex, \"AA25 invalid account nonce\");\n }\n\n //a \"marker\" where account opcode validation is done and paymaster opcode validation is about to start\n // (used only by off-chain simulateValidation)\n numberMarker();\n\n bytes memory context;\n if (mUserOp.paymaster != address(0)) {\n (context, paymasterValidationData) = _validatePaymasterPrepayment(\n opIndex,\n userOp,\n outOpInfo,\n requiredPreFund,\n gasUsedByValidateAccountPrepayment\n );\n }\n unchecked {\n uint256 gasUsed = preGas - gasleft();\n\n if (userOp.verificationGasLimit < gasUsed) {\n revert FailedOp(opIndex, \"AA40 over verificationGasLimit\");\n }\n outOpInfo.prefund = requiredPreFund;\n outOpInfo.contextOffset = getOffsetOfMemoryBytes(context);\n outOpInfo.preOpGas = preGas - gasleft() + userOp.preVerificationGas;\n }\n }\n\n /**\n * process post-operation.\n * called just after the callData is executed.\n * if a paymaster is defined and its validation returned a non-empty context, its postOp is called.\n * the excess amount is refunded to the account (or paymaster - if it was used in the request)\n * @param opIndex index in the batch\n * @param mode - whether is called from innerHandleOp, or outside (postOpReverted)\n * @param opInfo userOp fields and info collected during validation\n * @param context the context returned in validatePaymasterUserOp\n * @param actualGas the gas used so far by this user operation\n */\n function _handlePostOp(\n uint256 opIndex,\n IPaymaster.PostOpMode mode,\n UserOpInfo memory opInfo,\n bytes memory context,\n uint256 actualGas\n ) private returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n unchecked {\n address refundAddress;\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 gasPrice = getUserOpGasPrice(mUserOp);\n\n address paymaster = mUserOp.paymaster;\n if (paymaster == address(0)) {\n refundAddress = mUserOp.sender;\n } else {\n refundAddress = paymaster;\n if (context.length > 0) {\n actualGasCost = actualGas * gasPrice;\n if (mode != IPaymaster.PostOpMode.postOpReverted) {\n IPaymaster(paymaster).postOp{\n gas: mUserOp.verificationGasLimit\n }(mode, context, actualGasCost);\n } else {\n // solhint-disable-next-line no-empty-blocks\n try\n IPaymaster(paymaster).postOp{\n gas: mUserOp.verificationGasLimit\n }(mode, context, actualGasCost)\n {} catch Error(string memory reason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA50 postOp reverted: \", reason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA50 postOp revert\");\n }\n }\n }\n }\n actualGas += preGas - gasleft();\n actualGasCost = actualGas * gasPrice;\n if (opInfo.prefund < actualGasCost) {\n revert FailedOp(opIndex, \"AA51 prefund below actualGasCost\");\n }\n uint256 refund = opInfo.prefund - actualGasCost;\n _incrementDeposit(refundAddress, refund);\n bool success = mode == IPaymaster.PostOpMode.opSucceeded;\n emit UserOperationEvent(\n opInfo.userOpHash,\n mUserOp.sender,\n mUserOp.paymaster,\n mUserOp.nonce,\n success,\n actualGasCost,\n actualGas\n );\n } // unchecked\n }\n\n /**\n * the gas price this UserOp agrees to pay.\n * relayer/block builder might submit the TX with higher priorityFee, but the user should not\n */\n function getUserOpGasPrice(\n MemoryUserOp memory mUserOp\n ) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = mUserOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = mUserOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n function getOffsetOfMemoryBytes(\n bytes memory data\n ) internal pure returns (uint256 offset) {\n assembly {\n offset := data\n }\n }\n\n function getMemoryBytesFromOffset(\n uint256 offset\n ) internal pure returns (bytes memory data) {\n assembly {\n data := offset\n }\n }\n\n //place the NUMBER opcode in the code.\n // this is used as a marker during simulation, as this OP is completely banned from the simulated code of the\n // account and paymaster.\n function numberMarker() internal view {\n assembly {\n mstore(0, number())\n }\n }\n}\n" + }, + "contracts/aa-4337/core/Helpers.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable no-inline-assembly */\n\n/**\n * returned data from validateUserOp.\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\n * @param aggregator - address(0) - the account validated the signature by itself.\n * address(1) - the account failed to validate the signature.\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\n * @param validAfter - this UserOp is valid only after this timestamp.\n * @param validaUntil - this UserOp is valid only up to this timestamp.\n */\nstruct ValidationData {\n address aggregator;\n uint48 validAfter;\n uint48 validUntil;\n}\n\n//extract sigFailed, validAfter, validUntil.\n// also convert zero validUntil to type(uint48).max\nfunction _parseValidationData(\n uint validationData\n) pure returns (ValidationData memory data) {\n address aggregator = address(uint160(validationData));\n uint48 validUntil = uint48(validationData >> 160);\n if (validUntil == 0) {\n validUntil = type(uint48).max;\n }\n uint48 validAfter = uint48(validationData >> (48 + 160));\n return ValidationData(aggregator, validAfter, validUntil);\n}\n\n// intersect account and paymaster ranges.\nfunction _intersectTimeRange(\n uint256 validationData,\n uint256 paymasterValidationData\n) pure returns (ValidationData memory) {\n ValidationData memory accountValidationData = _parseValidationData(\n validationData\n );\n ValidationData memory pmValidationData = _parseValidationData(\n paymasterValidationData\n );\n address aggregator = accountValidationData.aggregator;\n if (aggregator == address(0)) {\n aggregator = pmValidationData.aggregator;\n }\n uint48 validAfter = accountValidationData.validAfter;\n uint48 validUntil = accountValidationData.validUntil;\n uint48 pmValidAfter = pmValidationData.validAfter;\n uint48 pmValidUntil = pmValidationData.validUntil;\n\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\n return ValidationData(aggregator, validAfter, validUntil);\n}\n\n/**\n * helper to pack the return value for validateUserOp\n * @param data - the ValidationData to pack\n */\nfunction _packValidationData(\n ValidationData memory data\n) pure returns (uint256) {\n return\n uint160(data.aggregator) |\n (uint256(data.validUntil) << 160) |\n (uint256(data.validAfter) << (160 + 48));\n}\n\n/**\n * helper to pack the return value for validateUserOp, when not using an aggregator\n * @param sigFailed - true for signature failure, false for success\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\n * @param validAfter first timestamp this UserOperation is valid\n */\nfunction _packValidationData(\n bool sigFailed,\n uint48 validUntil,\n uint48 validAfter\n) pure returns (uint256) {\n return\n (sigFailed ? 1 : 0) |\n (uint256(validUntil) << 160) |\n (uint256(validAfter) << (160 + 48));\n}\n\n/**\n * keccak function over calldata.\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\n */\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\n assembly {\n let mem := mload(0x40)\n let len := data.length\n calldatacopy(mem, data.offset, len)\n ret := keccak256(mem, len)\n }\n}\n" + }, + "contracts/aa-4337/core/NonceManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\nimport \"../interfaces/IEntryPoint.sol\";\n\n/**\n * nonce management functionality\n */\ncontract NonceManager is INonceManager {\n /**\n * The next valid sequence number for a given nonce key.\n */\n mapping(address => mapping(uint192 => uint256)) public nonceSequenceNumber;\n\n function getNonce(\n address sender,\n uint192 key\n ) public view override returns (uint256 nonce) {\n return nonceSequenceNumber[sender][key] | (uint256(key) << 64);\n }\n\n // allow an account to manually increment its own nonce.\n // (mainly so that during construction nonce can be made non-zero,\n // to \"absorb\" the gas cost of first nonce increment to 1st transaction (construction),\n // not to 2nd transaction)\n function incrementNonce(uint192 key) public override {\n nonceSequenceNumber[msg.sender][key]++;\n }\n\n /**\n * validate nonce uniqueness for this account.\n * called just after validateUserOp()\n */\n function _validateAndUpdateNonce(\n address sender,\n uint256 nonce\n ) internal returns (bool) {\n uint192 key = uint192(nonce >> 64);\n uint64 seq = uint64(nonce);\n return nonceSequenceNumber[sender][key]++ == seq;\n }\n}\n" + }, + "contracts/aa-4337/core/SenderCreator.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/**\n * helper contract for EntryPoint, to call userOp.initCode from a \"neutral\" address,\n * which is explicitly not the entryPoint itself.\n */\ncontract SenderCreator {\n /**\n * call the \"initCode\" factory to create and return the sender account address\n * @param initCode the initCode value from a UserOp. contains 20 bytes of factory address, followed by calldata\n * @return sender the returned address of the created account, or zero address on failure.\n */\n function createSender(\n bytes calldata initCode\n ) external returns (address sender) {\n address factory = address(bytes20(initCode[0:20]));\n bytes memory initCallData = initCode[20:];\n bool success;\n /* solhint-disable no-inline-assembly */\n assembly {\n success := call(\n gas(),\n factory,\n 0,\n add(initCallData, 0x20),\n mload(initCallData),\n 0,\n 32\n )\n sender := mload(0)\n }\n if (!success) {\n sender = address(0);\n }\n }\n}\n" + }, + "contracts/aa-4337/core/StakeManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity 0.8.21;\n\nimport \"../interfaces/IStakeManager.sol\";\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable not-rely-on-time */\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by a paymaster.\n */\nabstract contract StakeManager is IStakeManager {\n /// maps paymaster to their deposits and stakes\n mapping(address => DepositInfo) public deposits;\n\n /// @inheritdoc IStakeManager\n function getDepositInfo(\n address account\n ) public view returns (DepositInfo memory info) {\n return deposits[account];\n }\n\n // internal method to return just the stake info\n function _getStakeInfo(\n address addr\n ) internal view returns (StakeInfo memory info) {\n DepositInfo storage depositInfo = deposits[addr];\n info.stake = depositInfo.stake;\n info.unstakeDelaySec = depositInfo.unstakeDelaySec;\n }\n\n /// return the deposit (for gas payment) of the account\n function balanceOf(address account) public view returns (uint256) {\n return deposits[account].deposit;\n }\n\n receive() external payable {\n depositTo(msg.sender);\n }\n\n function _incrementDeposit(address account, uint256 amount) internal {\n DepositInfo storage info = deposits[account];\n uint256 newAmount = info.deposit + amount;\n require(newAmount <= type(uint112).max, \"deposit overflow\");\n info.deposit = uint112(newAmount);\n }\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) public payable {\n _incrementDeposit(account, msg.value);\n DepositInfo storage info = deposits[account];\n emit Deposited(account, info.deposit);\n }\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 unstakeDelaySec) public payable {\n DepositInfo storage info = deposits[msg.sender];\n require(unstakeDelaySec > 0, \"must specify unstake delay\");\n require(\n unstakeDelaySec >= info.unstakeDelaySec,\n \"cannot decrease unstake time\"\n );\n uint256 stake = info.stake + msg.value;\n require(stake > 0, \"no stake specified\");\n require(stake <= type(uint112).max, \"stake overflow\");\n deposits[msg.sender] = DepositInfo(\n info.deposit,\n true,\n uint112(stake),\n unstakeDelaySec,\n 0\n );\n emit StakeLocked(msg.sender, stake, unstakeDelaySec);\n }\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external {\n DepositInfo storage info = deposits[msg.sender];\n require(info.unstakeDelaySec != 0, \"not staked\");\n require(info.staked, \"already unstaking\");\n uint48 withdrawTime = uint48(block.timestamp) + info.unstakeDelaySec;\n info.withdrawTime = withdrawTime;\n info.staked = false;\n emit StakeUnlocked(msg.sender, withdrawTime);\n }\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external {\n DepositInfo storage info = deposits[msg.sender];\n uint256 stake = info.stake;\n require(stake > 0, \"No stake to withdraw\");\n require(info.withdrawTime > 0, \"must call unlockStake() first\");\n require(\n info.withdrawTime <= block.timestamp,\n \"Stake withdrawal is not due\"\n );\n info.unstakeDelaySec = 0;\n info.withdrawTime = 0;\n info.stake = 0;\n emit StakeWithdrawn(msg.sender, withdrawAddress, stake);\n (bool success, ) = withdrawAddress.call{value: stake}(\"\");\n require(success, \"failed to withdraw stake\");\n }\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(\n address payable withdrawAddress,\n uint256 withdrawAmount\n ) external {\n DepositInfo storage info = deposits[msg.sender];\n require(withdrawAmount <= info.deposit, \"Withdraw amount too large\");\n info.deposit = uint112(info.deposit - withdrawAmount);\n emit Withdrawn(msg.sender, withdrawAddress, withdrawAmount);\n (bool success, ) = withdrawAddress.call{value: withdrawAmount}(\"\");\n require(success, \"failed to withdraw\");\n }\n}\n" + }, + "contracts/aa-4337/interfaces/IAccount.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\ninterface IAccount {\n /**\n * Validate user's signature and nonce\n * the entryPoint will make the call to the recipient only if this validation call returns successfully.\n * signature failure should be reported by returning SIG_VALIDATION_FAILED (1).\n * This allows making a \"simulation call\" without a valid signature\n * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure.\n *\n * @dev Must validate caller is the entryPoint.\n * Must validate the signature and nonce\n * @param userOp the operation that is about to be executed.\n * @param userOpHash hash of the user's request data. can be used as the basis for signature.\n * @param missingAccountFunds missing funds on the account's deposit in the entrypoint.\n * This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call.\n * The excess is left as a deposit in the entrypoint, for future calls.\n * can be withdrawn anytime using \"entryPoint.withdrawTo()\"\n * In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero.\n * @return validationData packaged ValidationData structure. use `_packValidationData` and `_unpackValidationData` to encode and decode\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * If an account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validateUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 missingAccountFunds\n ) external returns (uint256 validationData);\n}\n" + }, + "contracts/aa-4337/interfaces/IAggregator.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * Aggregated Signatures validator.\n */\ninterface IAggregator {\n /**\n * validate aggregated signature.\n * revert if the aggregated signature does not match the given list of operations.\n */\n function validateSignatures(\n UserOperation[] calldata userOps,\n bytes calldata signature\n ) external view;\n\n /**\n * validate signature of a single userOp\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\n * @param userOp the userOperation received from the user.\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\n * (usually empty, unless account and aggregator support some kind of \"multisig\"\n */\n function validateUserOpSignature(\n UserOperation calldata userOp\n ) external view returns (bytes memory sigForUserOp);\n\n /**\n * aggregate multiple signatures into a single value.\n * This method is called off-chain to calculate the signature to pass with handleOps()\n * bundler MAY use optimized custom code perform this aggregation\n * @param userOps array of UserOperations to collect the signatures from.\n * @return aggregatedSignature the aggregated signature\n */\n function aggregateSignatures(\n UserOperation[] calldata userOps\n ) external view returns (bytes memory aggregatedSignature);\n}\n" + }, + "contracts/aa-4337/interfaces/IEntryPoint.sol": { + "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n/* solhint-disable reason-string */\n\nimport \"./UserOperation.sol\";\nimport \"./IStakeManager.sol\";\nimport \"./IAggregator.sol\";\nimport \"./INonceManager.sol\";\n\ninterface IEntryPoint is IStakeManager, INonceManager {\n /***\n * An event emitted after each successful request\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\n * @param sender - the account that generates this request.\n * @param paymaster - if non-null, the paymaster that pays for this request.\n * @param nonce - the nonce value from the request.\n * @param success - true if the sender transaction succeeded, false if reverted.\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\n */\n event UserOperationEvent(\n bytes32 indexed userOpHash,\n address indexed sender,\n address indexed paymaster,\n uint256 nonce,\n bool success,\n uint256 actualGasCost,\n uint256 actualGasUsed\n );\n\n /**\n * account \"sender\" was deployed.\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\n * @param sender the account that is deployed\n * @param factory the factory used to deploy this account (in the initCode)\n * @param paymaster the paymaster used by this UserOp\n */\n event AccountDeployed(\n bytes32 indexed userOpHash,\n address indexed sender,\n address factory,\n address paymaster\n );\n\n /**\n * An event emitted if the UserOperation \"callData\" reverted with non-zero length\n * @param userOpHash the request unique identifier.\n * @param sender the sender of this request\n * @param nonce the nonce used in the request\n * @param revertReason - the return bytes from the (reverted) call to \"callData\".\n */\n event UserOperationRevertReason(\n bytes32 indexed userOpHash,\n address indexed sender,\n uint256 nonce,\n bytes revertReason\n );\n\n /**\n * an event emitted by handleOps(), before starting the execution loop.\n * any event emitted before this event, is part of the validation.\n */\n event BeforeExecution();\n\n /**\n * signature aggregator used by the following UserOperationEvents within this bundle.\n */\n event SignatureAggregatorChanged(address indexed aggregator);\n\n /**\n * a custom revert error of handleOps, to identify the offending op.\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\n * @param reason - revert reason\n * The string starts with a unique code \"AAmn\", where \"m\" is \"1\" for factory, \"2\" for account and \"3\" for paymaster issues,\n * so a failure can be attributed to the correct entity.\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\n */\n error FailedOp(uint256 opIndex, string reason);\n\n /**\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\n */\n error SignatureValidationFailed(address aggregator);\n\n /**\n * Successful result from simulateValidation.\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n */\n error ValidationResult(\n ReturnInfo returnInfo,\n StakeInfo senderInfo,\n StakeInfo factoryInfo,\n StakeInfo paymasterInfo\n );\n\n /**\n * Successful result from simulateValidation, if the account returns a signature aggregator\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\n * bundler MUST use it to verify the signature, or reject the UserOperation\n */\n error ValidationResultWithAggregation(\n ReturnInfo returnInfo,\n StakeInfo senderInfo,\n StakeInfo factoryInfo,\n StakeInfo paymasterInfo,\n AggregatorStakeInfo aggregatorInfo\n );\n\n /**\n * return value of getSenderAddress\n */\n error SenderAddressResult(address sender);\n\n /**\n * return value of simulateHandleOp\n */\n error ExecutionResult(\n uint256 preOpGas,\n uint256 paid,\n uint48 validAfter,\n uint48 validUntil,\n bool targetSuccess,\n bytes targetResult\n );\n\n //UserOps handled, per aggregator\n struct UserOpsPerAggregator {\n UserOperation[] userOps;\n // aggregator address\n IAggregator aggregator;\n // aggregated signature\n bytes signature;\n }\n\n /**\n * Execute a batch of UserOperation.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(\n UserOperation[] calldata ops,\n address payable beneficiary\n ) external;\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) external;\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(\n UserOperation calldata userOp\n ) external view returns (bytes32);\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external;\n\n /**\n * gas and return values during simulation\n * @param preOpGas the gas used for validation (including preValidationGas)\n * @param prefund the required prefund for this operation\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\n */\n struct ReturnInfo {\n uint256 preOpGas;\n uint256 prefund;\n bool sigFailed;\n uint48 validAfter;\n uint48 validUntil;\n bytes paymasterContext;\n }\n\n /**\n * returned aggregated signature info.\n * the aggregator returned by the account, and its current stake.\n */\n struct AggregatorStakeInfo {\n address aggregator;\n StakeInfo stakeInfo;\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes memory initCode) external;\n\n /**\n * simulate full execution of a UserOperation (including both validation and target execution)\n * this method will always revert with \"ExecutionResult\".\n * it performs full validation of the UserOperation, but ignores signature error.\n * an optional target address is called after the userop succeeds, and its value is returned\n * (before the entire call is reverted)\n * Note that in order to collect the the success/failure of the target call, it must be executed\n * with trace enabled to track the emitted events.\n * @param op the UserOperation to simulate\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\n * are set to the return from that call.\n * @param targetCallData callData to pass to target address\n */\n function simulateHandleOp(\n UserOperation calldata op,\n address target,\n bytes calldata targetCallData\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/INonceManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\ninterface INonceManager {\n /**\n * Return the next nonce for this sender.\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\n * But UserOp with different keys can come with arbitrary order.\n *\n * @param sender the account address\n * @param key the high 192 bit of the nonce\n * @return nonce a full nonce to pass for next UserOp with this sender.\n */\n function getNonce(\n address sender,\n uint192 key\n ) external view returns (uint256 nonce);\n\n /**\n * Manually increment the nonce of the sender.\n * This method is exposed just for completeness..\n * Account does NOT need to call it, neither during validation, nor elsewhere,\n * as the EntryPoint will update the nonce regardless.\n * Possible use-case is call it with various keys to \"initialize\" their nonces to one, so that future\n * UserOperations will not pay extra for the first transaction with a given key.\n */\n function incrementNonce(uint192 key) external;\n}\n" + }, + "contracts/aa-4337/interfaces/IPaymaster.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * the interface exposed by a paymaster contract, who agrees to pay the gas for user's operations.\n * a paymaster must hold a stake to cover the required entrypoint stake and also the gas for the transaction.\n */\ninterface IPaymaster {\n enum PostOpMode {\n opSucceeded, // user op succeeded\n opReverted, // user op reverted. still has to pay for gas.\n postOpReverted //user op succeeded, but caused postOp to revert. Now it's a 2nd call, after user's op was deliberately reverted.\n }\n\n /**\n * payment validation: check if paymaster agrees to pay.\n * Must verify sender is the entryPoint.\n * Revert to reject this request.\n * Note that bundlers will reject this method if it changes the state, unless the paymaster is trusted (whitelisted)\n * The paymaster pre-pays using its deposit, and receive back a refund after the postOp method returns.\n * @param userOp the user operation\n * @param userOpHash hash of the user's request data.\n * @param maxCost the maximum cost of this transaction (based on maximum gas and gas price from userOp)\n * @return context value to send to a postOp\n * zero length to signify postOp is not required.\n * @return validationData signature and time-range of this operation, encoded the same as the return value of validateUserOperation\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validatePaymasterUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 maxCost\n ) external returns (bytes memory context, uint256 validationData);\n\n /**\n * post-operation handler.\n * Must verify sender is the entryPoint\n * @param mode enum with the following options:\n * opSucceeded - user operation succeeded.\n * opReverted - user op reverted. still has to pay for gas.\n * postOpReverted - user op succeeded, but caused postOp (in mode=opSucceeded) to revert.\n * Now this is the 2nd call, after user's op was deliberately reverted.\n * @param context - the context value returned by validatePaymasterUserOp\n * @param actualGasCost - actual gas used so far (without this postOp call).\n */\n function postOp(\n PostOpMode mode,\n bytes calldata context,\n uint256 actualGasCost\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/IStakeManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.12;\n\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by the staked entity.\n */\ninterface IStakeManager {\n event Deposited(address indexed account, uint256 totalDeposit);\n\n event Withdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /// Emitted when stake or unstake delay are modified\n event StakeLocked(\n address indexed account,\n uint256 totalStaked,\n uint256 unstakeDelaySec\n );\n\n /// Emitted once a stake is scheduled for withdrawal\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\n\n event StakeWithdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /**\n * @param deposit the entity's deposit\n * @param staked true if this entity is staked.\n * @param stake actual amount of ether staked for this entity.\n * @param unstakeDelaySec minimum delay to withdraw the stake.\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\n * and the rest fit into a 2nd cell.\n * 112 bit allows for 10^15 eth\n * 48 bit for full timestamp\n * 32 bit allows 150 years for unstake delay\n */\n struct DepositInfo {\n uint112 deposit;\n bool staked;\n uint112 stake;\n uint32 unstakeDelaySec;\n uint48 withdrawTime;\n }\n\n //API struct used by getStakeInfo and simulateValidation\n struct StakeInfo {\n uint256 stake;\n uint256 unstakeDelaySec;\n }\n\n /// @return info - full deposit information of given account\n function getDepositInfo(\n address account\n ) external view returns (DepositInfo memory info);\n\n /// @return the deposit (for gas payment) of the account\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) external payable;\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 _unstakeDelaySec) external payable;\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external;\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external;\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(\n address payable withdrawAddress,\n uint256 withdrawAmount\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/UserOperation.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable no-inline-assembly */\n\nimport {calldataKeccak} from \"../core/Helpers.sol\";\n\n/**\n * User Operation struct\n * @param sender the sender account of this request.\n * @param nonce unique value the sender uses to verify it is not a replay.\n * @param initCode if set, the account contract will be created by this constructor/\n * @param callData the method call to execute on this account.\n * @param callGasLimit the gas limit passed to the callData method call.\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\n * @param maxFeePerGas same as EIP-1559 gas parameter.\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\n */\nstruct UserOperation {\n address sender;\n uint256 nonce;\n bytes initCode;\n bytes callData;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n bytes paymasterAndData;\n bytes signature;\n}\n\n/**\n * Utility functions helpful when working with UserOperation structs.\n */\nlibrary UserOperationLib {\n function getSender(\n UserOperation calldata userOp\n ) internal pure returns (address) {\n address data;\n //read sender from userOp, which is first userOp member (saves 800 gas...)\n assembly {\n data := calldataload(userOp)\n }\n return address(uint160(data));\n }\n\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\n // pay above what he signed for.\n function gasPrice(\n UserOperation calldata userOp\n ) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function pack(\n UserOperation calldata userOp\n ) internal pure returns (bytes memory ret) {\n address sender = getSender(userOp);\n uint256 nonce = userOp.nonce;\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\n bytes32 hashCallData = calldataKeccak(userOp.callData);\n uint256 callGasLimit = userOp.callGasLimit;\n uint256 verificationGasLimit = userOp.verificationGasLimit;\n uint256 preVerificationGas = userOp.preVerificationGas;\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\n\n return\n abi.encode(\n sender,\n nonce,\n hashInitCode,\n hashCallData,\n callGasLimit,\n verificationGasLimit,\n preVerificationGas,\n maxFeePerGas,\n maxPriorityFeePerGas,\n hashPaymasterAndData\n );\n }\n\n function hash(\n UserOperation calldata userOp\n ) internal pure returns (bytes32) {\n return keccak256(pack(userOp));\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n}\n" + }, + "contracts/aa-4337/utils/Exec.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.5 <0.9.0;\n\n// solhint-disable no-inline-assembly\n\n/**\n * Utility functions helpful when making different kinds of contract calls in Solidity.\n */\nlibrary Exec {\n function call(\n address to,\n uint256 value,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := call(\n txGas,\n to,\n value,\n add(data, 0x20),\n mload(data),\n 0,\n 0\n )\n }\n }\n\n function staticcall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal view returns (bool success) {\n assembly {\n success := staticcall(txGas, to, add(data, 0x20), mload(data), 0, 0)\n }\n }\n\n function delegateCall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := delegatecall(\n txGas,\n to,\n add(data, 0x20),\n mload(data),\n 0,\n 0\n )\n }\n }\n\n // get returned data from last call or calldelegate\n function getReturnData(\n uint256 maxLen\n ) internal pure returns (bytes memory returnData) {\n assembly {\n let len := returndatasize()\n if gt(len, maxLen) {\n len := maxLen\n }\n let ptr := mload(0x40)\n mstore(0x40, add(ptr, add(len, 0x20)))\n mstore(ptr, len)\n returndatacopy(add(ptr, 0x20), 0, len)\n returnData := ptr\n }\n }\n\n // revert with explicit byte array (probably reverted info from call)\n function revertWithData(bytes memory returnData) internal pure {\n assembly {\n revert(add(returnData, 32), mload(returnData))\n }\n }\n\n function callAndRevert(\n address to,\n bytes memory data,\n uint256 maxLen\n ) internal {\n bool success = call(to, 0, data, gasleft());\n if (!success) {\n revertWithData(getReturnData(maxLen));\n }\n }\n}\n" + }, + "contracts/Barz.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"./libraries/LibDiamond.sol\";\nimport {IBarz} from \"./interfaces/IBarz.sol\";\n\n/**\n * @title Barz\n * @dev A diamond proxy wallet with a modular & upgradeable architecture\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract Barz is IBarz {\n /**\n * @notice Initializes Barz with the given parameters. Barz account is intended to be created from Barz Factory for stable deployment.\n * @dev This method makes a delegate call to account facet and account facet handles the initialization.\n * With modular architecture, Barz encompasses wide spectrum of architecture and logic.\n * The only requirement is account facet to comply with initialize() interface.\n * Barz doesn't include built-in functions and is a full proxy, for maximum extensibility and modularity.\n * @param _accountFacet Address of Account Facet in charge of the Barz initialization\n * @param _verificationFacet Address of Verification Facet for verifying the signature. Could be any signature scheme\n * @param _entryPoint Address of Entry Point contract\n * @param _facetRegistry Address of Facet Registry. Facet Registry is a registry holding trusted facets that could be added to user's wallet\n * @param _defaultFallBack Address of Default FallBack Handler. Middleware contract for more efficient deployment\n * @param _ownerPublicKey Bytes of Owner Public Key using for initialization\n */\n constructor(\n address _accountFacet,\n address _verificationFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallBack,\n bytes memory _ownerPublicKey\n ) payable {\n bytes memory initCall = abi.encodeWithSignature(\n \"initialize(address,address,address,address,bytes)\",\n _verificationFacet,\n _entryPoint,\n _facetRegistry,\n _defaultFallBack,\n _ownerPublicKey\n );\n (bool success, bytes memory result) = _accountFacet.delegatecall(\n initCall\n );\n if (!success || uint256(bytes32(result)) != 1) {\n revert Barz__InitializationFailure();\n }\n }\n\n /**\n * @notice Fallback function for Barz complying with Diamond Standard with customization of adding Default Fallback Handler\n * @dev Find facet for function that is called and execute the function if a facet is found and return any value.\n */\n fallback() external payable {\n LibDiamond.DiamondStorage storage ds;\n bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION;\n // get diamond storage\n assembly {\n ds.slot := position\n }\n // get facet from function selector\n address facet = address(bytes20(ds.facets[msg.sig]));\n if (facet == address(0))\n facet = ds.defaultFallbackHandler.facetAddress(msg.sig);\n require(facet != address(0), \"Barz: Function does not exist\");\n // Execute external function from facet using delegatecall and return any value.\n assembly {\n // copy function selector and any arguments\n calldatacopy(0, 0, calldatasize())\n // execute function call using the facet\n let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)\n // get any return value\n returndatacopy(0, 0, returndatasize())\n // return any return value or error back to the caller\n switch result\n case 0 {\n revert(0, returndatasize())\n }\n default {\n return(0, returndatasize())\n }\n }\n }\n\n /**\n * @notice Receive function to receive native token without data\n */\n receive() external payable {}\n}\n" + }, + "contracts/BarzFactory.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Barz} from \"./Barz.sol\";\nimport {IBarzFactory} from \"./interfaces/IBarzFactory.sol\";\n\n/**\n * @title Barz Factory\n * @dev Contract to easily deploy Barz to a pre-computed address with a single call\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract BarzFactory is IBarzFactory {\n address public immutable accountFacet;\n address public immutable entryPoint;\n address public immutable facetRegistry;\n address public immutable defaultFallback;\n\n /**\n * @notice Sets the initialization data for Barz contract initialization\n * @param _accountFacet Account Facet to be used to create Barz\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\n * @param _facetRegistry Facet Registry to be used to create Barz\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\n */\n constructor(\n address _accountFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallback\n ) {\n accountFacet = _accountFacet;\n entryPoint = _entryPoint;\n facetRegistry = _facetRegistry;\n defaultFallback = _defaultFallback;\n }\n\n /**\n * @notice Creates the Barz with a single call. It creates the Barz contract with the givent verification facet\n * @param _verificationFacet Address of verification facet used for creating the barz account\n * @param _owner Public Key of the owner to initialize barz account\n * @param _salt Salt used for deploying barz with create2\n * @return barz Instance of Barz contract deployed with the given parameters\n */\n function createAccount(\n address _verificationFacet,\n bytes calldata _owner,\n uint256 _salt\n ) external override returns (Barz barz) {\n address addr = getAddress(_verificationFacet, _owner, _salt);\n uint codeSize = addr.code.length;\n if (codeSize > 0) {\n return Barz(payable(addr));\n }\n barz = new Barz{salt: bytes32(_salt)}(\n accountFacet,\n _verificationFacet,\n entryPoint,\n facetRegistry,\n defaultFallback,\n _owner\n );\n emit BarzDeployed(address(barz));\n }\n\n /**\n * @notice Calculates the address of Barz with the given parameters\n * @param _verificationFacet Address of verification facet used for creating the barz account\n * @param _owner Public Key of the owner to initialize barz account\n * @param _salt Salt used for deploying barz with create2\n * @return barzAddress Precalculated Barz address\n */\n function getAddress(\n address _verificationFacet,\n bytes calldata _owner,\n uint256 _salt\n ) public view override returns (address barzAddress) {\n bytes memory bytecode = getBytecode(\n accountFacet,\n _verificationFacet,\n entryPoint,\n facetRegistry,\n defaultFallback,\n _owner\n );\n bytes32 hash = keccak256(\n abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(bytecode)\n )\n );\n barzAddress = address(uint160(uint256(hash)));\n }\n\n /**\n * @notice Returns the bytecode of Barz with the given parameter\n * @param _accountFacet Account Facet to be used to create Barz\n * @param _verificationFacet Verification Facet to be used to create Barz\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\n * @param _facetRegistry Facet Registry to be used to create Barz\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\n * @param _ownerPublicKey Public Key of owner to be used to initialize Barz ownership\n * @return barzBytecode Bytecode of Barz\n */\n function getBytecode(\n address _accountFacet,\n address _verificationFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallback,\n bytes calldata _ownerPublicKey\n ) public pure override returns (bytes memory barzBytecode) {\n bytes memory bytecode = type(Barz).creationCode;\n barzBytecode = abi.encodePacked(\n bytecode,\n abi.encode(\n _accountFacet,\n _verificationFacet,\n _entryPoint,\n _facetRegistry,\n _defaultFallback,\n _ownerPublicKey\n )\n );\n }\n\n /**\n * @notice Returns the creation code of the Barz contract\n * @return creationCode Creation code of Barz\n */\n function getCreationCode()\n public\n pure\n override\n returns (bytes memory creationCode)\n {\n creationCode = type(Barz).creationCode;\n }\n}\n" + }, + "contracts/facets/AccountFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {UserOperation} from \"../aa-4337/interfaces/UserOperation.sol\";\nimport {IEntryPoint} from \"../aa-4337/interfaces/IEntryPoint.sol\";\nimport {BaseAccount} from \"../aa-4337/core/BaseAccount.sol\";\nimport {LibAppStorage, BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {IFacetRegistry} from \"../infrastructure/interfaces/IFacetRegistry.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {IERC1271} from \"../interfaces/ERC/IERC1271.sol\";\nimport {IAccountFacet} from \"./interfaces/IAccountFacet.sol\";\n\n/**\n * @title Account Facet\n * @dev Account module contract that provides the account features and initialization of signer\n * compatible with EIP-1271 & EIP-4337\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract AccountFacet is IAccountFacet, BarzStorage, BaseAccount {\n using ECDSA for bytes32;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceAccountInitialize();\n }\n\n /**\n * @notice Returns the address of EntryPoint contract registered to Barz account\n */\n function entryPoint() public view override returns (IEntryPoint) {\n return s.entryPoint;\n }\n\n /**\n * @notice Initializes the initial storage of the Barz contract.\n * @dev This method can only be called during the initialization or signature migration.\n * If the proxy contract was created without initialization, anyone can call initialize.\n * Barz calls initialize in constructor in an atomic transaction during deployment\n * @param _verificationFacet Facet contract handling the verificationi\n * @param _anEntryPoint Entrypoint contract defined in EIP-4337 handling the flow of UserOp\n * @param _facetRegistry Registry of Facets that hold all facet information\n * @param _defaultFallBackHandler Middleware contract for default facets\n * @param _ownerPublicKey Bytes of owner public key\n */\n function initialize(\n address _verificationFacet,\n address _anEntryPoint,\n address _facetRegistry,\n address _defaultFallBackHandler,\n bytes calldata _ownerPublicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceAccountInitialize();\n s.entryPoint = IEntryPoint(_anEntryPoint);\n s.facetRegistry = IFacetRegistry(_facetRegistry);\n LibDiamond.diamondStorage().defaultFallbackHandler = IDiamondLoupe(\n _defaultFallBackHandler\n );\n\n _cutDiamondAccountFacet(_verificationFacet);\n\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n _ownerPublicKey\n );\n // Every Verification Facet should comply with initializeSigner(bytes)\n // to be compatible with the Barz contract(for initialization)\n (bool success, bytes memory result) = _verificationFacet.delegatecall(\n initCall\n );\n if (!success || uint256(bytes32(result)) != 1) {\n revert AccountFacet__InitializationFailure();\n }\n\n initSuccess = 1;\n emit AccountInitialized(s.entryPoint, _ownerPublicKey);\n }\n\n function _cutDiamondAccountFacet(address _verificationFacet) internal {\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](1);\n\n bytes4 ownerVerificationFuncSelector = IVerificationFacet(\n _verificationFacet\n ).validateOwnerSignatureSelector();\n\n bytes4[] memory verificationFunctionSelectors = new bytes4[](3);\n verificationFunctionSelectors[0] = IERC1271.isValidSignature.selector;\n verificationFunctionSelectors[1] = ownerVerificationFuncSelector;\n verificationFunctionSelectors[2] = IVerificationFacet.owner.selector;\n cut[0] = IDiamondCut.FacetCut({\n facetAddress: _verificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: verificationFunctionSelectors\n });\n\n LibDiamond.diamondCut(cut, address(0), \"\");\n }\n\n /**\n * @notice Calls the destination with inputted calldata and value from EntryPoint\n * @dev This method executes the calldata coming from the EntryPoint.\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\n * @param _dest Address of destination where the call will be forwarded to\n * @param _value Amount of native coin the owner is willing to send(e.g. ETH, BNB)\n * @param _func Bytes of calldata to execute in the destination address\n */\n function execute(\n address _dest,\n uint256 _value,\n bytes calldata _func\n ) external override onlyWhenUnlocked {\n _requireFromEntryPoint();\n address restrictionsFacet = LibDiamond.restrictionsFacet();\n if (restrictionsFacet == address(0)) _call(_dest, _value, _func);\n else _callWithRestrictions(_dest, _value, _func, restrictionsFacet);\n }\n\n /**\n * @notice Batch calls the destination with inputted calldata and value from EntryPoint\n * @dev This method batch executes the calldata coming from the EntryPoint.\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\n * @param _dest Array of addresses of destination where the call will be forwarded to\n * @param _value Array of amount of native coin the owner is willing to send(e.g. ETH, BNB)\n * @param _func Array of bytes of calldata to execute in the destination address\n */\n function executeBatch(\n address[] calldata _dest,\n uint256[] calldata _value,\n bytes[] calldata _func\n ) external override onlyWhenUnlocked {\n _requireFromEntryPoint();\n if (_dest.length != _func.length || _dest.length != _value.length)\n revert AccountFacet__InvalidArrayLength();\n address restrictionsFacet = LibDiamond.restrictionsFacet();\n if (restrictionsFacet == address(0)) {\n for (uint256 i; i < _dest.length; ) {\n _call(_dest[i], _value[i], _func[i]);\n unchecked {\n ++i;\n }\n }\n } else {\n for (uint256 i; i < _dest.length; ) {\n _callWithRestrictions(\n _dest[i],\n _value[i],\n _func[i],\n restrictionsFacet\n );\n unchecked {\n ++i;\n }\n }\n }\n }\n\n /**\n * @notice Validates the signature field of UserOperation\n * @dev This method validates if the signature of UserOp is indeed valid by delegating the call to Verification Facet\n * Barz makes a call to the pre-registered Verification Facet address in App Storage\n * @param _userOp UserOperation from owner to be validated\n * @param _userOpHash Hash of UserOperation given from the EntryPoint contract\n */\n function _validateSignature(\n UserOperation calldata _userOp,\n bytes32 _userOpHash\n ) internal override returns (uint256 validationData) {\n // Get Facet with Function Selector\n address facet = LibLoupe.facetAddress(s.validateOwnerSignatureSelector);\n if (facet == address(0))\n revert AccountFacet__NonExistentVerificationFacet();\n\n // Make function call to VerificationFacet\n bytes memory validateCall = abi.encodeWithSelector(\n s.validateOwnerSignatureSelector,\n _userOp,\n _userOpHash\n );\n (bool success, bytes memory result) = facet.delegatecall(validateCall);\n if (!success) revert AccountFacet__CallNotSuccessful();\n validationData = uint256(bytes32(result));\n if (validationData == 0) emit VerificationSuccess(_userOpHash);\n else emit VerificationFailure(_userOpHash);\n }\n\n /**\n * @notice Calls the target with the inputted value and calldata\n * @dev This method is the actual function in Barz that makes a call with an arbitrary owner-given data\n * @param _target Address of the destination contract which the call is getting forwarded to\n * @param _value Amount of Native coin the owner is wanting to make in this call\n * @param _data Calldata the owner is forwarding together in the call e.g. Swap/Token Transfer\n */\n function _call(\n address _target,\n uint256 _value,\n bytes memory _data\n ) internal {\n (bool success, bytes memory result) = _target.call{value: _value}(\n _data\n );\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n }\n\n /**\n * @notice Calls the target with the inputted value and calldata together with restrictions check\n * @dev This method is the actual function in Barz that makes a call with an arbitrary owner-given data\n * @param _target Address of the destination contract which the call is getting forwarded to\n * @param _value Amount of Native coin the owner is wanting to make in this call\n * @param _data Calldata the owner is forwarding together in the call e.g. Swap/Token Transfer\n * @param _restrictionsFacet Address of Facet to validate restrictions\n */\n function _callWithRestrictions(\n address _target,\n uint256 _value,\n bytes memory _data,\n address _restrictionsFacet\n ) internal {\n // NOTE: No restrictions facet, so restriction validation passes\n if (_checkRestrictions(_restrictionsFacet, _target, _value, _data) != 0)\n revert AccountFacet__RestrictionsFailure();\n\n (bool success, bytes memory result) = _target.call{value: _value}(\n _data\n );\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n }\n\n /**\n * @notice Checks restrictions if the restrictions facet exists\n * @dev This method checks if the restrictions facet exists and makes a verification call to an array of restrictions facet\n * @param _facet Address that holds the restrictions logic\n * @param _target Address the call is getting forwarded to\n * @param _value Amount of native coin the call is sending together with the call\n * @param _data Calldata to trigger execution in target address\n */\n function _checkRestrictions(\n address _facet,\n address _target,\n uint256 _value,\n bytes memory _data\n ) internal returns (uint256 result) {\n bytes memory call = abi.encodeWithSignature(\n \"verifyRestrictions(address,address,uint256,bytes)\",\n address(this),\n _target,\n _value,\n _data\n );\n (bool success, bytes memory response) = _facet.delegatecall(call);\n if (!success) revert AccountFacet__RestrictionsFailure();\n result = uint256(bytes32(response));\n }\n}\n" + }, + "contracts/facets/AccountRecoveryFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibFacetStorage, RecoveryStorage, RecoveryConfig, RecoveryApprovalConfig, ApprovalConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {IAccountRecoveryFacet} from \"./interfaces/IAccountRecoveryFacet.sol\";\n\n/**\n * @title Account Recovery Facet\n * @dev Contract that enables recovery of accounts when owner key is unavailable\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract AccountRecoveryFacet is IAccountRecoveryFacet, Modifiers {\n bytes constant UNINIT_CALL =\n abi.encodeWithSignature(\"uninitializeSigner()\");\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Approve recovery of account as guardian\n * @dev This method can only be called by guardian and guardian inputs the public key of the new owner\n * When the threshold(majority of guardians) passes, it automatically executes account recovery\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function approveAccountRecovery(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + _getApprovalValidationPeriod()\n );\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit RecoveryApproved(\n _recoveryPublicKey,\n msg.sender,\n approvalValidUntil\n );\n if (\n getRecoveryApprovalCountWithTimeValidity(recoveryPublicKeyHash) >=\n LibGuardian.majorityOfGuardians()\n ) _executeRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Revoke recovery of account as guardian\n * @dev This method can only be called by guardian and guardian inputs the public key of the new owner\n When the threshold(majority of guardians) passes, it automatically revokes account recovery when recovery is pending\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function revokeAccountRecoveryApproval(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n if (\n !rs\n .isNewOwnerApproved[recoveryPublicKeyHash][msg.sender].isApproved ||\n !(block.timestamp <\n rs\n .isNewOwnerApproved[recoveryPublicKeyHash][msg.sender]\n .validUntil)\n ) revert AccountRecoveryFacet__NonExistentApproval();\n\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(false, 0);\n emit RecoveryApprovalRevoked(_recoveryPublicKey, msg.sender);\n }\n\n /**\n * @notice Executes recovery with signatures or on-chain pre-approvals\n * @dev This method validates the signatures of guardians or checks the on-chain pre-approved calls to check if the threshold passes\n * When the threshold passes, account recovery is executed and revert otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _guardians Array of guardians address that are approving the recovery of Account\n * @param _signatures Array of signature bytes that signed the approval hash\n */\n function executeRecovery(\n bytes calldata _recoveryPublicKey,\n address[] calldata _guardians,\n bytes[] calldata _signatures\n ) external override {\n if (_isRecoveryPending())\n revert AccountRecoveryFacet__RecoveryAlreadyOngoing();\n if (_guardians.length != _signatures.length)\n revert AccountRecoveryFacet__InvalidArrayLength();\n validateNewOwner(_recoveryPublicKey);\n\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n\n _checkApprover(_guardians);\n _checkDuplicateOnChainApprover(recoveryPublicKeyHash, _guardians);\n\n if (\n _guardians.length +\n getRecoveryApprovalCountWithTimeValidity(\n recoveryPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians()\n ) revert AccountRecoveryFacet__InsufficientGuardians();\n for (uint256 i; i < _guardians.length; ) {\n if (!LibGuardian.isGuardian(_guardians[i]))\n revert AccountRecoveryFacet__InvalidGuardian();\n if (\n !SignatureChecker.isValidSignatureNow(\n _guardians[i],\n recoveryPublicKeyHash,\n _signatures[i]\n )\n ) revert AccountRecoveryFacet__InvalidGuardianSignature();\n unchecked {\n ++i;\n }\n }\n _executeRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Executes recovery of the account. Note that execution and finalization is a different process\n * @dev Executes the recovery and adds recovery data to recovery configuration. Locks the account\n * @param _recoveryPublicKey Public Key of the account for recovery\n */\n function _executeRecovery(bytes memory _recoveryPublicKey) internal {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n unchecked {\n ++rs.nonce;\n }\n uint64 executeAfter = uint64(block.timestamp + _getRecoveryPeriod());\n rs.recoveryConfigs[INNER_STRUCT] = RecoveryConfig(\n _recoveryPublicKey,\n executeAfter // NOTE: Remove guardian Count\n );\n LibAppStorage.setLock(\n block.timestamp + _getLockPeriod(),\n AccountRecoveryFacet.executeRecovery.selector\n );\n emit RecoveryExecuted(_recoveryPublicKey, executeAfter);\n }\n\n /**\n * @notice Finalize recovery after recovery pending period. Recovery pending period can be set by user beforehand in SecurityManager\n * @dev This method finalizes recovery and fully changes the ownership of the account to the newly inputted recovery public key\n */\n function finalizeRecovery() external override {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n if (\n uint64(block.timestamp) <=\n rs.recoveryConfigs[INNER_STRUCT].executeAfter\n ) revert AccountRecoveryFacet__RecoveryPeriodNotOver();\n bytes memory recoveryOwner = rs\n .recoveryConfigs[INNER_STRUCT]\n .recoveryPublicKey;\n\n delete rs.recoveryConfigs[INNER_STRUCT];\n\n LibAppStorage.setLock(0, bytes4(0));\n\n LibAppStorage.initiateSignerMigration();\n address verificationFacet = address(\n bytes20(\n LibDiamond.diamondStorage().facets[\n s.validateOwnerSignatureSelector\n ]\n )\n );\n (bool uninitSuccess, bytes memory uninitResult) = verificationFacet\n .delegatecall(UNINIT_CALL);\n if (!uninitSuccess) revert AccountRecoveryFacet__CallNotSuccesful();\n if (uint256(bytes32(uninitResult)) != 1)\n revert AccountRecoveryFacet__SignerUninitializationFailure();\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n recoveryOwner\n );\n (bool initSuccess, bytes memory initResult) = verificationFacet\n .delegatecall(initCall);\n if (!initSuccess) revert AccountRecoveryFacet__CallNotSuccesful();\n if (uint256(bytes32(initResult)) != 1)\n revert AccountRecoveryFacet__SignerInitializationFailure();\n LibAppStorage.finalizeSignerMigration();\n emit RecoveryFinalized(recoveryOwner);\n }\n\n /**\n * @notice Approves the cancellation of recovery\n * @dev This method approves the cancellation of recovery when recovery is still pending - waiting for finalization\n * @param _recoveryPublicKey Bytes of public key which is pending for recovery\n */\n function approveCancelRecovery(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"CancelRecovery\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + _getApprovalValidationPeriod()\n );\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit RecoveryCancellationApproved(_recoveryPublicKey, msg.sender);\n if (\n getRecoveryApprovalCountWithTimeValidity(recoveryPublicKeyHash) >=\n LibGuardian.majorityOfGuardians()\n ) {\n _cancelRecovery(_recoveryPublicKey);\n }\n }\n\n /**\n * @notice Hardstops an ongoing recovery\n * @dev This method provides a safety mechanism to protect owners of malicious guardians.\n * Owners can hardstop recovery when an malicious guardians starts the recovery process.\n * @param _signature Signature of the owner that signs the hash to hardstop recovery\n */\n function hardstopRecovery(bytes calldata _signature) external override {\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n \"0\",\n \"HardstopRecovery\"\n );\n if (\n !SignatureChecker.isValidSignatureNow(\n address(this),\n recoveryPublicKeyHash,\n _signature\n )\n ) revert AccountRecoveryFacet__InvalidOwnerSignature();\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n unchecked {\n ++rs.nonce;\n }\n delete rs.recoveryConfigs[INNER_STRUCT];\n LibAppStorage.setLock(0, bytes4(0));\n emit RecoveryHardstopped();\n }\n\n /**\n * @notice Cancels recovery with signatures or on-chain pre-approvals\n * @dev This method validates the signatures of guardians or checks the on-chain pre-approved calls to check if the threshold passes\n * When the threshold passes, account recovery is canceled and revert otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _guardians Array of guardians address that are approving the recovery of Account\n * @param _signatures Array of signature bytes that signed the cancellation approval hash\n */\n function cancelRecovery(\n bytes calldata _recoveryPublicKey,\n address[] calldata _guardians,\n bytes[] calldata _signatures\n ) external override {\n if (_guardians.length != _signatures.length)\n revert AccountRecoveryFacet__InvalidArrayLength();\n validateNewOwner(_recoveryPublicKey);\n\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"CancelRecovery\"\n );\n\n _checkApprover(_guardians);\n _checkDuplicateOnChainApprover(recoveryPublicKeyHash, _guardians);\n\n if (\n _guardians.length +\n getRecoveryApprovalCountWithTimeValidity(\n recoveryPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians()\n ) revert AccountRecoveryFacet__InsufficientGuardians();\n for (uint256 i; i < _guardians.length; ) {\n if (!LibGuardian.isGuardian(_guardians[i]))\n revert AccountRecoveryFacet__CallerNotGuardian();\n if (\n !SignatureChecker.isValidSignatureNow(\n _guardians[i],\n recoveryPublicKeyHash,\n _signatures[i]\n )\n ) revert AccountRecoveryFacet__InvalidGuardianSignature();\n unchecked {\n ++i;\n }\n }\n _cancelRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Cancel recovery when the recovery is pending. Unlock the account as well\n * @dev This method checks if the recovery is pending and reverts if not pending.\n * It increases the recovery nonce and deletes the recovery information and gets a small portion of gas in return\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function _cancelRecovery(bytes memory _recoveryPublicKey) internal {\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n LibAppStorage.setLock(0, bytes4(0));\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n unchecked {\n ++rs.nonce;\n }\n delete rs.recoveryConfigs[INNER_STRUCT];\n emit RecoveryCanceled(_recoveryPublicKey);\n }\n\n /**\n * @notice Validates the format of public key to be used for recovery\n * @dev This method checks if the public key format is correct and reverts otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function validateNewOwner(\n bytes calldata _recoveryPublicKey\n ) public view override {\n if (\n !IVerificationFacet(\n LibLoupe.facetAddress(s.validateOwnerSignatureSelector)\n ).isValidKeyType(_recoveryPublicKey)\n ) revert AccountRecoveryFacet__InvalidRecoveryPublicKey();\n }\n\n /**\n * @notice Checks if recovery is currently pending\n * @return isPending Boolean indicating if recovery is pending\n */\n function _isRecoveryPending() internal view returns (bool isPending) {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n isPending = (rs.recoveryConfigs[INNER_STRUCT].executeAfter > 0);\n }\n\n /**\n * @notice Calculate the recovery hash dependent on chain, wallet address, nonce with EIP-191 prefix for safety\n * @dev Returns the keccak256 hash of EIP-191 msg hash packed with public key, salt, nonce, wallet address, etc\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _saltString Salt string to uniquely identify each recovery hash and for security\n * @return recoveryKeyHash Bytes32 string of the recovery hash\n */\n function getApprovalRecoveryKeyHash(\n bytes memory _recoveryPublicKey,\n string memory _saltString\n ) public view override returns (bytes32 recoveryKeyHash) {\n recoveryKeyHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n _recoveryPublicKey,\n _saltString,\n address(this),\n block.chainid,\n LibFacetStorage.recoveryStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Check the onchain approval of guardians and returns the number of guardians that approved\n * @dev Loop through the guardian addresses and returns the number of guardians that approved this recovery hash\n * @param _recoveryPublicKeyHash Bytes hash of newly recovered public key and recovery value of the account\n * @return approvalCount Number of guardians that approved\n */\n function getRecoveryApprovalCountWithTimeValidity(\n bytes32 _recoveryPublicKeyHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n for (uint256 i; i < guardianLength; ) {\n if (isRecoveryApproved(_recoveryPublicKeyHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Checks if the recovery is approved by the given approver\n * @param _recoveryPublicKeyHash Hash of the public key and configuration for recovery\n * @param _approver Address of approver\n * @return isApproved Bool value if recovery hash is approved\n */\n function isRecoveryApproved(\n bytes32 _recoveryPublicKeyHash,\n address _approver\n ) public view override returns (bool isApproved) {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n if (\n rs\n .isNewOwnerApproved[_recoveryPublicKeyHash][_approver].isApproved &&\n block.timestamp <\n rs.isNewOwnerApproved[_recoveryPublicKeyHash][_approver].validUntil\n ) {\n isApproved = true;\n }\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _recoveryPublicKeyHash Hash of recovery information\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _recoveryPublicKeyHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isRecoveryApproved(_recoveryPublicKeyHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert AccountRecoveryFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the lock period of this wallet address from security manager\n * @return lockPeriod value of lock period\n */\n function _getLockPeriod() internal view returns (uint256 lockPeriod) {\n lockPeriod = securityManager.lockPeriodOf(address(this));\n if (lockPeriod == 0) revert AccountRecoveryFacet__InvalidLockPeriod();\n }\n\n /**\n * @notice Returns the lock period of this wallet address from security manager\n * @return recoveryPeriod value of recovery period\n */\n function _getRecoveryPeriod()\n internal\n view\n returns (uint256 recoveryPeriod)\n {\n recoveryPeriod = securityManager.recoveryPeriodOf(address(this));\n if (recoveryPeriod == 0)\n revert AccountRecoveryFacet__InvalidRecoveryPeriod();\n }\n\n /**\n * @notice Returns the approval validation period of this wallet address from security manager\n * @return approvalValidationPeriod value of approval validation period\n */\n function _getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod == 0)\n revert AccountRecoveryFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the recovery nonce of this wallet address from security manager\n * @return nonce value of recovery nonce\n */\n function getRecoveryNonce() public view override returns (uint128 nonce) {\n nonce = LibFacetStorage.recoveryStorage().nonce;\n }\n\n /**\n * @notice Returns the recovery information of the pending recovery\n * @return recoveryConfig value struct of pending recovery\n */\n function getPendingRecovery()\n public\n view\n override\n returns (RecoveryConfig memory recoveryConfig)\n {\n recoveryConfig = LibFacetStorage.recoveryStorage().recoveryConfigs[\n INNER_STRUCT\n ];\n }\n}\n" + }, + "contracts/facets/base/DiamondCutFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibGuardian} from \"../../libraries/LibGuardian.sol\";\nimport {ISecurityManager} from \"../../infrastructure/interfaces/ISecurityManager.sol\";\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibFacetStorage, DiamondCutApprovalConfig, ApprovalConfig} from \"../../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"../Modifiers.sol\";\nimport {IDiamondCut} from \"./interfaces/IDiamondCut.sol\";\n\n/**\n * @title DiamondCut Facet\n * @dev Responsible for adding/removing/replace facets in Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DiamondCutFacet is Modifiers, IDiamondCut {\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Updates the flag for the interfaceId\n * @param _interfaceId InterfaceID to update the mapping\n * @param _flag Bool value to update the mapping of the given interface ID\n */\n function updateSupportsInterface(\n bytes4 _interfaceId,\n bool _flag\n ) external override onlyWhenUnlocked {\n LibDiamond.enforceIsSelf();\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId] = _flag;\n emit SupportsInterfaceUpdated(_interfaceId, _flag);\n }\n\n /**\n * @notice Add/replace/remove any number of functions and optionally execute\n * a function with delegatecall when guardians don't exist\n * @param _diamondCut Contains the facet addresses and function selectors\n * @param _init The address of the contract or facet to execute _calldata. It's prohibited in Barz\n */\n function diamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata\n ) external override onlyWhenUnlocked {\n LibDiamond.enforceIsSelf();\n\n _checkFacetCutValidity(_diamondCut);\n // require approval from guardian if guardian exists\n if (0 != LibGuardian.guardianCount())\n revert DiamondCutFacet__InvalidRouteWithGuardian();\n if (address(0) != _init) revert DiamondCutFacet__InvalidInitAddress();\n\n unchecked {\n ++LibFacetStorage.diamondCutStorage().nonce;\n }\n LibDiamond.diamondCut(_diamondCut, address(0), \"\");\n }\n\n /**\n * @notice Add/replace/remove any number of functions and optionally execute\n * a function with delegatecall when guardians exist\n * @param _diamondCut Contains the facet addresses and function selectors\n * @param _approvers Guardian or owner address that approves the diamond cut\n * @param _signatures Signature of Guardians or owner that approves the diamond cut\n */\n function diamondCutWithGuardian(\n FacetCut[] calldata _diamondCut,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n ) external override onlyWhenUnlocked {\n if (_approvers.length != _signatures.length)\n revert DiamondCutFacet__InvalidArrayLength();\n _checkFacetCutValidity(_diamondCut);\n if (0 == LibGuardian.guardianCount())\n revert DiamondCutFacet__InvalidRouteWithGuardian();\n\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(cutHash, _approvers);\n\n bool onChainOwnerApproval = getOwnerCutApprovalWithTimeValidity(\n cutHash\n );\n\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n if (\n _approvers.length +\n getDiamondCutApprovalCountWithTimeValidity(cutHash) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert DiamondCutFacet__InsufficientApprovers();\n\n bool ownerApproved;\n for (uint256 i; i < _approvers.length; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n _approvers[i] != address(this)\n ) revert DiamondCutFacet__InvalidApprover();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert DiamondCutFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n cutHash,\n _signatures[i]\n )\n ) revert DiamondCutFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n if (!ownerApproved && !onChainOwnerApproval)\n revert DiamondCutFacet__LackOfOwnerApproval();\n\n unchecked {\n ++LibFacetStorage.diamondCutStorage().nonce;\n }\n LibDiamond.diamondCut(_diamondCut, address(0), \"\");\n }\n\n /**\n * @notice Approves diamond cut. This can only be called directly from guardian or owner\n * @param _diamondCut Contains the facet addresses and function selectors\n */\n function approveDiamondCut(\n FacetCut[] calldata _diamondCut\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\n if (LibGuardian.guardianCount() == 0)\n revert DiamondCutFacet__InvalidRouteWithoutGuardian();\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n _checkFacetCutValidity(_diamondCut);\n\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(\n true,\n approvalValidUntil\n );\n emit DiamondCutApproved(_diamondCut);\n if (\n (getDiamondCutApprovalCountWithTimeValidity(cutHash) >=\n LibGuardian.majorityOfGuardians()) &&\n getOwnerCutApprovalWithTimeValidity(cutHash)\n ) {\n unchecked {\n ++LibFacetStorage.diamondCutStorage().nonce;\n }\n LibDiamond.diamondCut(_diamondCut, address(0), \"\");\n }\n }\n\n /**\n * @notice Revokes the approval of diamond cut. This can only be called directly from guardian or owner\n * @param _diamondCut Contains the facet addresses and function selectors\n */\n function revokeDiamondCutApproval(\n FacetCut[] calldata _diamondCut\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\n if (!ds.isDiamondCutApproved[cutHash][msg.sender].isApproved)\n revert DiamondCutFacet__CannotRevokeUnapproved();\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(false, 0);\n emit DiamondCutApprovalRevoked(_diamondCut);\n }\n\n /**\n * @notice Gets the number of approvals of diamond cut from guardians\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n */\n function getDiamondCutApprovalCountWithTimeValidity(\n bytes32 _diamondCutHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardiansLength = guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n if (isCutApproved(_diamondCutHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n return approvalCount;\n }\n\n /**\n * @notice Returns if the owner has approved the diamond cut\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @return isApprovedByOwner Bool value showing if the owner approved the cut\n */\n function getOwnerCutApprovalWithTimeValidity(\n bytes32 _diamondCutHash\n ) public view override returns (bool isApprovedByOwner) {\n isApprovedByOwner = isCutApproved(_diamondCutHash, address(this));\n }\n\n /**\n * @notice Returns if the given approver has approved the diamond cut\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @param _approver Address of approver\n * @return isApproved Bool value showing if the approver approved the cut\n */\n function isCutApproved(\n bytes32 _diamondCutHash,\n address _approver\n ) public view override returns (bool isApproved) {\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n isApproved = (ds\n .isDiamondCutApproved[_diamondCutHash][_approver].isApproved &&\n block.timestamp <\n ds.isDiamondCutApproved[_diamondCutHash][_approver].validUntil);\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _diamondCutHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isCutApproved(_diamondCutHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert DiamondCutFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the diamond cut hash. This function ensures that this hash is safe from replay attack by including\n * salt, address, chainId, and nonce, etc.\n * @param _diamondCut Contains the facet addresses and function selectors\n * @return cutHash Diamond Cut Hash\n */\n function getDiamondCutHash(\n FacetCut[] calldata _diamondCut\n ) public view override returns (bytes32 cutHash) {\n cutHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n keccak256(abi.encode(_diamondCut)),\n address(this),\n block.chainid,\n LibFacetStorage.diamondCutStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Returns the approval validation Period\n * @dev This method fetches the validation period from the security manager\n * @return approvalValidationPeriod Approval validation period of Barz contract fetched from security manager\n */\n function getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod <= 0)\n revert DiamondCutFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the diamond cut nonce of this wallet\n * @dev This method fetches the nonce from diamond cut storage\n * @return cutNonce Nonce of diamond cut to protect from reply attacks\n */\n function getDiamondCutNonce()\n public\n view\n override\n returns (uint128 cutNonce)\n {\n cutNonce = LibFacetStorage.diamondCutStorage().nonce;\n }\n}\n" + }, + "contracts/facets/base/DiamondLoupeFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {IERC165} from \"../../interfaces/ERC/IERC165.sol\";\nimport {IERC1271} from \"../../interfaces/ERC/IERC1271.sol\";\nimport {IERC677Receiver} from \"../../interfaces/ERC/IERC677Receiver.sol\";\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC1155Receiver} from \"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\";\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../../libraries/LibLoupe.sol\";\nimport {LibUtils} from \"../../libraries/LibUtils.sol\";\nimport {IDiamondCut} from \"../../facets/base/interfaces/IDiamondCut.sol\";\nimport {IStorageLoupe} from \"./interfaces/IStorageLoupe.sol\";\nimport {IDiamondLoupe} from \"./interfaces/IDiamondLoupe.sol\";\n\n/**\n * @title DiamondLoupe Facet\n * @dev DiamondLoupe contract compatible with EIP-2535\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DiamondLoupeFacet is IDiamondLoupe, IStorageLoupe, IERC165 {\n // Diamond Loupe Functions\n ////////////////////////////////////////////////////////////////////\n /// These functions are expected to be called frequently by tools off-chain.\n\n /**\n * @notice Gets all facets and their selectors.\n * @dev Barz uses a special architecture called default fallback handler. Default Fallback handler is used as a middleware\n * that holds the mapping of facet function selector and facet address that Barz uses. This helps Barz to reduce\n * significant amount of gas during the initialization process.\n * Hence, this method aggregates both the facet information from DefaulFallbackHandler and in diamond storage and shows the data to users.\n * @return facets_ Facet\n */\n function facets() public view override returns (Facet[] memory facets_) {\n Facet[] memory defaultFacet = LibDiamond\n .diamondStorage()\n .defaultFallbackHandler\n .facets();\n Facet[] memory _facets = LibLoupe.facets();\n uint256 numFacets = _facets.length;\n bytes4[] memory keys;\n address[] memory values;\n for (uint256 i; i < numFacets; ) {\n uint256 selectorsLength = _facets[i].functionSelectors.length;\n for (uint256 j; j < selectorsLength; ) {\n (keys, values) = LibUtils.setValue(\n keys,\n values,\n _facets[i].functionSelectors[j],\n _facets[i].facetAddress\n );\n unchecked {\n ++j;\n }\n }\n unchecked {\n ++i;\n }\n }\n {\n bool iIncrement;\n for (uint256 i; i < defaultFacet.length; ) {\n bool jIncrement;\n for (\n uint256 j;\n j < defaultFacet[i].functionSelectors.length;\n\n ) {\n if (\n LibUtils.getValue(\n keys,\n values,\n defaultFacet[i].functionSelectors[j]\n ) != address(0)\n ) {\n if (defaultFacet[i].functionSelectors.length == 1) {\n defaultFacet = LibUtils.removeFacetElement(\n defaultFacet,\n i\n );\n iIncrement = true;\n break;\n }\n defaultFacet[i].functionSelectors = LibUtils\n .removeElement(\n defaultFacet[i].functionSelectors,\n j\n );\n jIncrement = true;\n }\n if (!jIncrement) {\n unchecked {\n ++j;\n }\n } else {\n jIncrement = false;\n }\n }\n if (!iIncrement) {\n unchecked {\n ++i;\n }\n } else {\n iIncrement = false;\n }\n }\n }\n {\n uint256 facetLength = numFacets + defaultFacet.length;\n facets_ = new Facet[](facetLength);\n uint256 defaultFacetIndex;\n for (uint256 i; i < facetLength; ) {\n if (i < numFacets) {\n facets_[i] = _facets[i];\n bool jIncrementor;\n for (uint256 j; j < defaultFacet.length; ) {\n if (\n facets_[i].facetAddress ==\n defaultFacet[j].facetAddress\n ) {\n facets_[i].functionSelectors = LibUtils.mergeArrays(\n _facets[i].functionSelectors,\n defaultFacet[j].functionSelectors\n );\n defaultFacet = LibUtils.removeFacetElement(\n defaultFacet,\n j\n );\n jIncrementor = true;\n {\n facets_ = LibUtils.removeFacetElement(\n facets_,\n facets_.length - 1\n );\n }\n --facetLength;\n }\n if (!jIncrementor) {\n unchecked {\n ++j;\n }\n } else {\n jIncrementor = false;\n }\n }\n } else {\n facets_[i] = defaultFacet[defaultFacetIndex];\n ++defaultFacetIndex;\n }\n unchecked {\n ++i;\n }\n }\n }\n }\n\n /**\n * @notice Gets all the function selectors provided by a facet.\n * @param _facet The facet address.\n * @return facetFunctionSelectors_\n */\n function facetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n Facet[] memory facet = facets();\n uint256 facetLength = facet.length;\n for (uint256 i; i < facetLength; ) {\n if (facet[i].facetAddress == _facet)\n return facet[i].functionSelectors;\n unchecked {\n ++i;\n }\n }\n return facetFunctionSelectors_;\n }\n\n /**\n * @notice Get all the facet addresses used by Barz.\n * @return facetAddresses_\n */\n function facetAddresses()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n Facet[] memory facet = facets();\n uint256 facetLength = facet.length;\n facetAddresses_ = new address[](facetLength);\n for (uint256 i; i < facetLength; ) {\n facetAddresses_[i] = facet[i].facetAddress;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Gets the facet that supports the given selector.\n * @dev If facet is not found return address(0).\n * @param _functionSelector The function selector.\n * @return facetAddress_ The facet address.\n */\n function facetAddress(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n\n facetAddress_ = address(bytes20(ds.facets[_functionSelector]));\n if (facetAddress_ == address(0)) {\n facetAddress_ = IDiamondLoupe(ds.defaultFallbackHandler)\n .facetAddress(_functionSelector);\n }\n }\n\n /**\n * @notice SupportInterface to be compatible with EIP 165\n * @param _interfaceId Interface ID for detecting the interface\n * @return isSupported Bool value showing if the standard is supported in the contract\n */\n function supportsInterface(\n bytes4 _interfaceId\n ) external view override returns (bool isSupported) {\n isSupported =\n _interfaceId == type(IERC165).interfaceId ||\n _interfaceId == IDiamondCut.diamondCut.selector ||\n _interfaceId == type(IDiamondLoupe).interfaceId ||\n _interfaceId == type(IERC1155Receiver).interfaceId ||\n _interfaceId == type(IERC721Receiver).interfaceId ||\n _interfaceId == type(IERC777Recipient).interfaceId ||\n _interfaceId == IERC1271.isValidSignature.selector ||\n _interfaceId == type(IERC677Receiver).interfaceId ||\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId];\n }\n\n /**\n * @notice Returns the facet from the diamond storage. This excludes the facets from the default fallback handler\n * @return facets_ Facet information attached directly to diamond storage\n */\n function facetsFromStorage()\n external\n view\n override\n returns (Facet[] memory facets_)\n {\n facets_ = LibLoupe.facets();\n }\n\n /**\n * @notice Returns the facet address attached to the given function selector. This excludes the facets from the default fallback handler\n * @param _functionSelector Function selector to fetch the facet address from diamond storage\n * @return facetAddress_ Facet address mapped with the function selector\n */\n function facetAddressFromStorage(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n facetAddress_ = LibLoupe.facetAddress(_functionSelector);\n }\n\n /**\n * @notice Returns all facet addresses attached directly to diamond storage. This excludes the facets from the default fallback handler\n * @return facetAddresses_ All facet addresses attached directly to diamond storage\n */\n function facetAddressesFromStorage()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n facetAddresses_ = LibLoupe.facetAddresses();\n }\n\n /**\n * @notice Returns function selectors of given facet address attached directly to diamond storage. This excludes the facets from the default fallback handler\n * @param _facet Facet address to fetch the facet function selectors from diamond storage\n * @return facetFunctionSelectors_ Facet function selectors of the given facet address\n */\n function facetFunctionSelectorsFromStorage(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n facetFunctionSelectors_ = LibLoupe.facetFunctionSelectors(_facet);\n }\n}\n" + }, + "contracts/facets/base/interfaces/IDiamondCut.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title DiamondCut Facet Interface\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IDiamondCut {\n error DiamondCutFacet__InvalidRouteWithGuardian();\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\n error DiamondCutFacet__InvalidArrayLength();\n error DiamondCutFacet__InsufficientApprovers();\n error DiamondCutFacet__InvalidApprover();\n error DiamondCutFacet__InvalidApproverSignature();\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\n error DiamondCutFacet__CannotRevokeUnapproved();\n error DiamondCutFacet__LackOfOwnerApproval();\n error DiamondCutFacet__OwnerAlreadyApproved();\n error DiamondCutFacet__DuplicateApproval();\n error DiamondCutFacet__InvalidInitAddress();\n\n event DiamondCutApproved(FacetCut[] diamondCut);\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\n\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\n\n enum FacetCutAction {\n Add,\n Replace,\n Remove\n }\n // Add=0, Replace=1, Remove=2\n\n struct FacetCut {\n address facetAddress;\n FacetCutAction action;\n bytes4[] functionSelectors;\n }\n\n /// @notice Add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param diamondCut Contains the facet addresses and function selectors\n /// @param init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function diamondCut(\n FacetCut[] calldata diamondCut,\n address init,\n bytes calldata _calldata\n ) external;\n\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\n\n function diamondCutWithGuardian(\n FacetCut[] calldata diamondCut,\n address[] calldata approvers,\n bytes[] calldata signatures\n ) external;\n\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\n\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\n\n function getDiamondCutApprovalCountWithTimeValidity(\n bytes32 diamondCutHash\n ) external view returns (uint256);\n\n function getOwnerCutApprovalWithTimeValidity(\n bytes32 diamondCutHash\n ) external view returns (bool);\n\n function isCutApproved(\n bytes32 diamondCutHash,\n address approver\n ) external view returns (bool);\n\n function getDiamondCutHash(\n FacetCut[] calldata diamondCut\n ) external view returns (bytes32);\n\n function getDiamondCutNonce() external view returns (uint128);\n}\n" + }, + "contracts/facets/base/interfaces/IDiamondLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n// A loupe is a small magnifying glass used to look at diamonds.\n// These functions look at diamonds\ninterface IDiamondLoupe {\n /// These functions are expected to be called frequently\n /// by tools.\n\n struct Facet {\n address facetAddress;\n bytes4[] functionSelectors;\n }\n\n /// @notice Gets all facet addresses and their four byte function selectors.\n /// @return facets_ Facet\n function facets() external view returns (Facet[] memory facets_);\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n /// @return facetFunctionSelectors_\n function facetFunctionSelectors(\n address _facet\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses()\n external\n view\n returns (address[] memory facetAddresses_);\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(\n bytes4 _functionSelector\n ) external view returns (address facetAddress_);\n}\n" + }, + "contracts/facets/base/interfaces/IStorageLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"./IDiamondLoupe.sol\";\n\n/**\n * @title LoupeFromStorage Interface\n * @dev Interface contract to function as a loupe facet directly attached to diamond storage of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IStorageLoupe {\n /// These functions are expected to be called frequently\n /// by tools.\n\n /// @notice Gets all facet addresses and their four byte function selectors.\n /// @return facets_ Facet\n function facetsFromStorage()\n external\n view\n returns (IDiamondLoupe.Facet[] memory);\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n function facetFunctionSelectorsFromStorage(\n address _facet\n ) external view returns (bytes4[] memory);\n\n /// @notice Get all the facet addresses used by a diamond.\n function facetAddressesFromStorage()\n external\n view\n returns (address[] memory);\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n function facetAddressFromStorage(\n bytes4 _functionSelector\n ) external view returns (address);\n}\n" + }, + "contracts/facets/GuardianFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibFacetStorage, GuardianStorage, StorageConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IGuardianFacet} from \"./interfaces/IGuardianFacet.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Guardian Facet\n * @dev Contract that enables addition/removal of guardians from Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract GuardianFacet is IGuardianFacet {\n ISecurityManager public immutable securityManager;\n uint8 public constant INNER_STRUCT = 0;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Add guardians to Barz.\n * @dev This method internally calls addGuardian which checks the validity of guardian address and adds\n * as guardian if valid\n * @param _guardians Array of addresses to add as guardian\n */\n function addGuardians(address[] calldata _guardians) external override {\n LibDiamond.enforceIsSelf();\n for (uint256 i; i < _guardians.length; ) {\n addGuardian(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Add a guardian to Barz.\n * @dev This method checks if the function is called by the owner and validates the address of guardian\n * When the validation passes, guardian address is added to the pending state waiting for confirmation\n * @param _guardian Address to add as guardian\n */\n function addGuardian(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (_guardian == address(this))\n revert GuardianFacet__GuardianCannotBeSelf();\n if (isGuardian(_guardian)) revert GuardianFacet__DuplicateGuardian();\n if (_guardian == address(0))\n revert GuardianFacet__ZeroAddressGuardian();\n if (\n keccak256(abi.encodePacked(_guardian)) ==\n keccak256(IVerificationFacet(address(this)).owner())\n ) revert GuardianFacet__OwnerCannotBeGuardian();\n\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n if (\n gs.pending[id] != 0 ||\n block.timestamp <= gs.pending[id] + getSecurityWindow()\n ) revert GuardianFacet__DuplicateGuardianAddition();\n\n uint256 securityPeriod = getAdditionSecurityPeriod();\n gs.pending[id] = block.timestamp + securityPeriod;\n emit GuardianAdditionRequested(\n _guardian,\n block.timestamp + securityPeriod\n );\n }\n\n /**\n * @notice Remove guardians from Barz.\n * @dev This method internally calls removeGuardian which checks the validity of guardian and removes\n * guardian when the request is valid\n * @param _guardians Array of addresses to be removed\n */\n function removeGuardians(address[] calldata _guardians) external override {\n LibDiamond.enforceIsSelf();\n for (uint256 i; i < _guardians.length; ) {\n removeGuardian(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Remove a guardian from Barz.\n * @dev This method validates if the guardian to be removed is a guardian and puts the guardian removal\n * to a pending state waiting to be confirmed.\n * @param _guardian Address of guardian to be removed\n */\n function removeGuardian(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n if (!isGuardian(_guardian)) revert GuardianFacet__NonExistentGuardian();\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n if (\n gs.pending[id] != 0 ||\n block.timestamp <= gs.pending[id] + getSecurityWindow()\n ) revert GuardianFacet__DuplicateGuardianRemoval();\n\n uint256 securityPeriod = getRemovalSecurityPeriod();\n gs.pending[id] = block.timestamp + securityPeriod;\n emit GuardianRemovalRequested(\n _guardian,\n block.timestamp + securityPeriod\n );\n }\n\n /**\n * @notice Confirm addition of guardians\n * @dev This method internally calls confirmGuardianAddition which checks the validity of pending request.\n * Guardians are fully added when they pass the validation. Anyone can call this function.\n * @param _guardians Array of guardian addresses to be added\n */\n function confirmGuardianAdditions(\n address[] calldata _guardians\n ) external override {\n for (uint256 i; i < _guardians.length; ) {\n confirmGuardianAddition(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Confirm addition of a guardian\n * @dev This method checks the validity of pending request.\n * Guardians are fully added when they pass the validation. Anyone can call this function.\n * @param _guardian Guardian address to be added\n */\n function confirmGuardianAddition(address _guardian) public override {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingAddition();\n if (gs.pending[id] >= block.timestamp)\n revert GuardianFacet__PendingAdditionNotOver();\n if (block.timestamp >= gs.pending[id] + getSecurityWindow())\n revert GuardianFacet__PendingAdditionExpired();\n\n _addGuardian(_guardian);\n\n delete gs.pending[id];\n emit GuardianAdded(_guardian);\n }\n\n /**\n * @notice Confirm removal of guardians\n * @dev This method internally calls confirmGuardianRemoval to check the validity guardian removal confirmation.\n * Guardians are fully removed when they pass the validation. Anyone can call this function.\n * @param _guardians Array of guardian addresses to be removed\n */\n function confirmGuardianRemovals(\n address[] calldata _guardians\n ) external override {\n for (uint256 i; i < _guardians.length; ) {\n confirmGuardianRemoval(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Confirm removal of a guardian\n * @dev This method checks the validity guardian removal confirmation.\n * Guardian is fully removed when they pass the validation. Anyone can call this function.\n * @param _guardian Guardian address to be removed\n */\n function confirmGuardianRemoval(address _guardian) public override {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingRemoval();\n if (gs.pending[id] >= block.timestamp)\n revert GuardianFacet__PendingRemovalNotOver();\n if (block.timestamp >= gs.pending[id] + getSecurityWindow())\n revert GuardianFacet__PendingAdditionExpired();\n\n _removeGuardian(_guardian);\n delete gs.pending[id];\n emit GuardianRemoved(_guardian);\n }\n\n /**\n * @notice Cancel pending guardian addition\n * @dev This method checks if the previous request for guardian request exists.\n * It reverts if previous request is not pending and cancels the addition otherwise.\n * @param _guardian Guardian address to be canceled from addition\n */\n function cancelGuardianAddition(address _guardian) external override {\n LibDiamond.enforceIsSelf();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingAddition();\n delete gs.pending[id];\n emit GuardianAdditionCancelled(_guardian);\n }\n\n /**\n * @notice Cancel pending guardian removal\n * @dev This method checks if the previous request for guardian request exists.\n * It reverts if previous request is not pending and cancels the removal otherwise.\n * @param _guardian Guardian address to be canceled from removal\n */\n function cancelGuardianRemoval(address _guardian) external override {\n LibDiamond.enforceIsSelf();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingRemoval();\n delete gs.pending[id];\n emit GuardianRemovalCancelled(_guardian);\n }\n\n /**\n * @notice Get the addition security period of current account from security manager\n * @dev This method returns the uint value if addition security period\n * @return additionSecurityPeriod Uint256 value of addition security period\n */\n function getAdditionSecurityPeriod()\n public\n view\n override\n returns (uint256 additionSecurityPeriod)\n {\n additionSecurityPeriod = securityManager.additionSecurityPeriodOf(\n address(this)\n );\n if (additionSecurityPeriod == 0)\n revert GuardianFacet__InvalidAdditionSecurityPeriod();\n }\n\n /**\n * @notice Get the removal security period of current account from security manager\n * @dev This method returns the uint value if removal security period\n * @return removalSecurityPeriod Uint256 value of removal security period\n */\n function getRemovalSecurityPeriod()\n public\n view\n override\n returns (uint256 removalSecurityPeriod)\n {\n removalSecurityPeriod = securityManager.removalSecurityPeriodOf(\n address(this)\n );\n if (removalSecurityPeriod == 0)\n revert GuardianFacet__InvalidRemovalSecurityPeriod();\n }\n\n /**\n * @notice Get the security window of current account from security manager\n * @dev This method returns the uint value if security window\n * @return securityWindow Uint256 value of removal security period\n */\n function getSecurityWindow()\n public\n view\n override\n returns (uint256 securityWindow)\n {\n securityWindow = securityManager.securityWindowOf(address(this));\n if (securityWindow == 0) revert GuardianFacet__InvalidSecurityWindow();\n }\n\n /**\n * @notice Checks if the addition of the given guardian address is pending\n * @dev This method returns the bool value of whether the guardian address is pending addition\n * @return isPending Bool value of representing the pending of guardian addition\n */\n function isAdditionPending(\n address _guardian\n ) public view override returns (bool isPending) {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n isPending = _isPending(id);\n }\n\n /**\n * @notice Checks if the removal of the given guardian address is pending\n * @dev This method returns the bool value of whether the guardian address is pending removal\n * @return isPending Bool value of representing the pending of guardian removal\n */\n function isRemovalPending(\n address _guardian\n ) public view override returns (bool isPending) {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n isPending = _isPending(id);\n }\n\n /**\n * @notice Checks if the given hash is pending\n * @dev This method returns the bool value whether the hash is pending\n * @return isPending Bool value of representing the pending of guardian operation\n */\n function _isPending(\n bytes32 _idHash\n ) internal view returns (bool isPending) {\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n isPending = ((gs.pending[_idHash] > 0 &&\n gs.pending[_idHash] < block.timestamp) &&\n block.timestamp < gs.pending[_idHash] + getSecurityWindow());\n }\n\n /**\n * @notice Adds guardian to storage config. This is called when guardian is fully added.\n * @dev This method add guardian address and config information to Facet Storage dedicated for guardian\n * When this function is called, guardian is fully added to this Barz Smart Account\n * @param _guardian Address of guardian to be added\n */\n function _addGuardian(address _guardian) internal {\n if (!isAdditionPending(_guardian))\n revert GuardianFacet__InvalidGuardianAddition();\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n if (config.info[_guardian].exists)\n revert GuardianFacet__AlreadyExists();\n\n config.info[_guardian].exists = true;\n config.info[_guardian].index = uint128(config.addresses.length);\n config.addresses.push(_guardian);\n }\n\n /**\n * @notice Removes guardian to storage config. This is called when guardian is fully removed.\n * @dev This method remove guardian address and config information to Facet Storage dedicated for guardian\n * When this function is called, guardian is fully removed from this Barz Smart Account\n * @param _guardian Address of guardian to be removed\n */\n function _removeGuardian(address _guardian) internal {\n if (!isRemovalPending(_guardian))\n revert GuardianFacet__InvalidGuardianRemoval();\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n if (!config.info[_guardian].exists)\n revert GuardianFacet__NonExistentGuardian();\n\n address lastAddress = config.addresses[config.addresses.length - 1];\n if (_guardian != lastAddress) {\n uint128 targetIndex = config.info[_guardian].index;\n config.addresses[targetIndex] = lastAddress;\n config.info[lastAddress].index = targetIndex;\n }\n config.addresses.pop();\n delete config.info[_guardian];\n\n emit GuardianRemoved(_guardian);\n }\n\n /**\n * @notice Reads guardian storage and fetches the addresses into an array from the storage\n * @dev This method fetches the guardian storage and returns the list of guardian addresses\n * @return guardians Array of addresses comprised of guardian\n */\n function getGuardians()\n public\n view\n override\n returns (address[] memory guardians)\n {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n uint256 guardiansLen = config.addresses.length;\n guardians = new address[](guardiansLen);\n for (uint256 i; i < guardiansLen; ) {\n guardians[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the number of majority of guardians\n * @return majorityOfGuardians_ Number of majority of guardians e.g., 2 if 3 guardians / 3 if 5 guardians\n */\n function majorityOfGuardians()\n public\n view\n override\n returns (uint256 majorityOfGuardians_)\n {\n majorityOfGuardians_ = LibGuardian.majorityOfGuardians();\n }\n\n /**\n * @notice Reads guardian storage and fetches the addresses into an array from the storage\n * @dev This method fetches the guardian storage and returns the list of guardian addresses\n * @return guardianNumber Array of guardians in the account\n */\n function guardianCount()\n public\n view\n override\n returns (uint256 guardianNumber)\n {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n guardianNumber = config.addresses.length;\n }\n\n /**\n * @notice Reads guardian storage and checks if the given address is a guardian\n * @return isGuardian_ Bool value representing if the given address is guardian\n */\n function isGuardian(\n address _guardian\n ) public view override returns (bool isGuardian_) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n isGuardian_ = config.info[_guardian].exists;\n }\n\n /**\n * @notice Checks if the guardian number is zero and returns of guardian facet is okay to be removed\n * @return isRemovable Bool value representing if guardian facet is removable\n */\n function isGuardianFacetRemovable()\n external\n view\n override\n returns (bool isRemovable)\n {\n isRemovable = (0 == guardianCount());\n }\n}\n" + }, + "contracts/facets/interfaces/IAccountFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IEntryPoint} from \"../../aa-4337/interfaces/IEntryPoint.sol\";\n\n/**\n * @title Account Facet Interface\n * @dev Interface of module contract that provides the account features and init/unitialization of signer\n * compatible with EIP-1271 & EIP-4337\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IAccountFacet {\n event AccountInitialized(\n IEntryPoint indexed entryPoint,\n bytes indexed ownerPublicKey\n );\n // NOTE: Added Below Event\n event VerificationSuccess(bytes32);\n event VerificationFailure(bytes32);\n\n error AccountFacet__InitializationFailure();\n error AccountFacet__RestrictionsFailure();\n error AccountFacet__NonExistentVerificationFacet();\n error AccountFacet__CallNotSuccessful();\n error AccountFacet__InvalidArrayLength();\n\n function initialize(\n address verificationFacet,\n address anEntryPoint,\n address facetRegistry,\n address _defaultFallBack,\n bytes calldata _ownerPublicKey\n ) external returns (uint256);\n\n function execute(address dest, uint256 value, bytes calldata func) external;\n\n function executeBatch(\n address[] calldata dest,\n uint256[] calldata value,\n bytes[] calldata func\n ) external;\n}\n" + }, + "contracts/facets/interfaces/IAccountRecoveryFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {RecoveryConfig} from \"../../libraries/LibFacetStorage.sol\";\n\n/**\n * @title Account Recovery Facet Interface\n * @dev Interface of contract that enables recovery of accounts when owner key is unavailable\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IAccountRecoveryFacet {\n event RecoveryExecuted(\n bytes indexed recoveryPublicKey,\n uint64 executeAfter\n );\n event RecoveryFinalized(bytes indexed recoveryPublicKey);\n event RecoveryCanceled(bytes indexed recoveryPublicKey);\n event RecoveryApproved(\n bytes indexed recoveryPublicKey,\n address indexed guardian,\n uint64 validUntil\n );\n event RecoveryApprovalRevoked(\n bytes indexed recoveryPublicKey,\n address indexed guardian\n );\n event RecoveryCancellationApproved(\n bytes indexed recoveryPublicKey,\n address indexed guardian\n );\n event RecoveryHardstopped();\n\n error AccountRecoveryFacet__CallerNotGuardian();\n error AccountRecoveryFacet__InvalidRecoveryPublicKey();\n error AccountRecoveryFacet__SignerInitializationFailure();\n error AccountRecoveryFacet__SignerUninitializationFailure();\n error AccountRecoveryFacet__InvalidArrayLength();\n error AccountRecoveryFacet__InsufficientGuardians();\n error AccountRecoveryFacet__RecoveryAlreadyOngoing();\n error AccountRecoveryFacet__NonexistentRecovery();\n error AccountRecoveryFacet__NonExistentApproval();\n error AccountRecoveryFacet__RecoveryPeriodNotOver();\n error AccountRecoveryFacet__InvalidLockPeriod();\n error AccountRecoveryFacet__InvalidRecoveryPeriod();\n error AccountRecoveryFacet__InvalidApprovalValidationPeriod();\n error AccountRecoveryFacet__InvalidGuardian();\n error AccountRecoveryFacet__InvalidGuardianSignature();\n error AccountRecoveryFacet__InvalidOwnerSignature();\n error AccountRecoveryFacet__CallNotSuccesful();\n error AccountRecoveryFacet__DuplicateApproval();\n\n function approveAccountRecovery(bytes calldata recoveryPublicKey) external;\n\n function revokeAccountRecoveryApproval(\n bytes calldata recoveryPublicKey\n ) external;\n\n function executeRecovery(\n bytes calldata recoveryPublicKey,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function finalizeRecovery() external;\n\n function approveCancelRecovery(bytes calldata recoveryPublicKey) external;\n\n function cancelRecovery(\n bytes calldata recoveryPublicKey,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function hardstopRecovery(bytes calldata signature) external;\n\n function validateNewOwner(bytes calldata recoveryPublicKey) external view;\n\n function getApprovalRecoveryKeyHash(\n bytes memory recoveryPublicKey,\n string memory saltString\n ) external view returns (bytes32);\n\n function getRecoveryApprovalCountWithTimeValidity(\n bytes32 recoveryPublicKeyHash\n ) external view returns (uint256);\n\n function isRecoveryApproved(\n bytes32 recoveryPublicKeyHash,\n address approver\n ) external view returns (bool);\n\n function getRecoveryNonce() external view returns (uint128);\n\n function getPendingRecovery() external view returns (RecoveryConfig memory);\n}\n" + }, + "contracts/facets/interfaces/IGuardianFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Guardian Facet Interface\n * @dev Interface of guaridna contract that enables addition/removal of guardians from Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IGuardianFacet {\n event GuardianAdditionRequested(\n address indexed guardian,\n uint256 executeAfter\n );\n event GuardianRemovalRequested(\n address indexed guardian,\n uint256 executeAfter\n );\n event GuardianAdditionCancelled(address indexed guardian);\n event GuardianRemovalCancelled(address indexed guardian);\n event GuardianAdded(address indexed guardian);\n event GuardianRemoved(address indexed guardian);\n\n error GuardianFacet__GuardianCannotBeSelf();\n error GuardianFacet__DuplicateGuardian();\n error GuardianFacet__OwnerCannotBeGuardian();\n error GuardianFacet__DuplicateGuardianAddition();\n error GuardianFacet__DuplicateGuardianRemoval();\n error GuardianFacet__UnknownPendingAddition();\n error GuardianFacet__PendingAdditionNotOver();\n error GuardianFacet__UnknownPendingRemoval();\n error GuardianFacet__PendingRemovalNotOver();\n error GuardianFacet__PendingAdditionExpired();\n error GuardianFacet__InvalidAdditionSecurityPeriod();\n error GuardianFacet__InvalidRemovalSecurityPeriod();\n error GuardianFacet__InvalidSecurityWindow();\n error GuardianFacet__NonExistentGuardian();\n error GuardianFacet__AlreadyExists();\n error GuardianFacet__InvalidGuardianAddition();\n error GuardianFacet__InvalidGuardianRemoval();\n error GuardianFacet__ZeroAddressGuardian();\n\n function addGuardian(address guardian) external;\n\n function addGuardians(address[] calldata guardians) external;\n\n function removeGuardian(address guardian) external;\n\n function removeGuardians(address[] calldata guardians) external;\n\n function confirmGuardianAddition(address guardian) external;\n\n function confirmGuardianAdditions(address[] calldata guardian) external;\n\n function confirmGuardianRemoval(address guardian) external;\n\n function confirmGuardianRemovals(address[] calldata guardian) external;\n\n function cancelGuardianAddition(address guardian) external;\n\n function cancelGuardianRemoval(address guardian) external;\n\n function isGuardian(address guardian) external view returns (bool);\n\n function isAdditionPending(address guardian) external view returns (bool);\n\n function isRemovalPending(address guardian) external view returns (bool);\n\n function isGuardianFacetRemovable() external view returns (bool);\n\n function getAdditionSecurityPeriod() external view returns (uint256);\n\n function getRemovalSecurityPeriod() external view returns (uint256);\n\n function getSecurityWindow() external view returns (uint256);\n\n function getGuardians() external view returns (address[] memory);\n\n function majorityOfGuardians() external view returns (uint256);\n\n function guardianCount() external view returns (uint256);\n}\n" + }, + "contracts/facets/interfaces/ILockFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Lock} from \"../../libraries/LibAppStorage.sol\";\n\n/**\n * @title Lock Facet Interface\n * @dev Interface of Lock contract that enables full lock/unlock of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface ILockFacet {\n event Locked(uint64 releaseAfter);\n event Unlocked();\n\n error LockFacet__InvalidRecoveryPeriod();\n error LockFacet__CannotUnlock();\n error LockFacet__InvalidSignature();\n error LockFacet__InvalidApprover();\n\n function lock() external;\n\n function unlock(address approver, bytes calldata signature) external;\n\n function getLockPeriod() external view returns (uint256);\n\n function isLocked() external view returns (bool);\n\n function getUnlockHash() external view returns (bytes32);\n\n function lockNonce() external view returns (uint128);\n\n function getPendingLock() external view returns (Lock memory);\n}\n" + }, + "contracts/facets/interfaces/IMultiSigFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Multi-sig facet Interface\n * @dev Interface of Multi-signature Facet with custom threshold.\n Wallet that adds this facet becomes a multi-sig wallet\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IMultiSigFacet {\n event ThresholdChanged(uint256 threshold);\n event OwnerAdded(address indexed newOwner);\n event OwnerRemoved(address indexed prevOwner);\n event HashApproved(bytes32 hashToApprove, address indexed owner);\n\n error MultiSigFacet__InvalidThreshold();\n error MultisigFacet__InvalidOwnerCount();\n error MultiSigFacet__InvalidRoute();\n error MultiSigFacet__InsufficientSignerLength();\n error MultiSigFacet__InvalidInitData();\n error MultiSigFacet__InvalidOwnerAddress();\n error MultiSigFacet__InvalidOwnerPair();\n error MultiSigFacet__InvalidSignatureLength();\n error MultiSigFacet__InvalidSignatureType();\n error MultiSigFacet__DuplicateOwner();\n error MultiSigFacet__OnlyOwner();\n\n function checkSignatures(\n bytes32 _dataHash,\n bytes calldata _signatures,\n uint256 _threshold\n ) external view returns (uint256);\n\n function splitSignatures(\n bytes calldata _signatures,\n uint256 _nextOffset\n )\n external\n pure\n returns (\n address owner,\n bytes memory signature,\n uint256 signatureType,\n uint256 nextOffset\n );\n\n function approveHash(bytes32 hashToApprove) external;\n\n function addOwner(address newOwner, uint256 threshold) external;\n\n function removeOwner(\n address prevOwner,\n address removedOwner,\n uint256 threshold\n ) external;\n\n function swapOwner(\n address prevOwner,\n address oldOwner,\n address newOwner\n ) external;\n\n function changeThreshold(uint256 _threshold) external;\n\n function isOwner(address owner) external view returns (bool);\n\n function getThreshold() external view returns (uint256);\n\n function getOwners() external view returns (address[] memory);\n}\n" + }, + "contracts/facets/interfaces/IRestrictionsFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Restrictions Facet Interface\n * @dev Interface of Restrictions contract that enables modular restrictions in Barz\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IRestrictionsFacet {\n event RestrictionAdded(address indexed restriction);\n event RestrictionRemoved(address indexed restriction);\n\n error RestrictionsFacet__EmptyRestrictionsList();\n error RestrictionsFacet__RestrictionNotFound();\n error RestrictionsFacet__RestrictionAlreadyExists();\n error RestrictionsFacet__ZeroAddressRestrictions();\n error RestrictionsFacet__ZeroAddressRestrictionsFacet();\n error RestrictionsFacet__RemainingRestrictionsCantBeEmpty();\n\n function initializeRestrictions(\n address[] memory _restrictions\n ) external returns (uint256);\n\n function uninitializeRestrictions() external returns (uint256);\n\n function getRestrictions() external view returns (address[] memory);\n\n function addRestriction(address restriction) external;\n\n function removeRestriction(address restriction) external;\n\n function verifyRestrictions(\n address from,\n address to,\n uint256 value,\n bytes calldata _calldata\n ) external returns (uint256);\n}\n" + }, + "contracts/facets/interfaces/ISignatureMigrationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureMigrationConfig} from \"../../libraries/LibFacetStorage.sol\";\n\n/**\n * @title Signature Migration Facet Interface\n * @dev Interface of Signature Migration contract for migrating user signature scheme to a new scheme user sets\n * Which could include\n * - ECDSA on Secp256K1 Curve\n * - ECDSA on Secp256R1 Curve\n * - BLS, Schnorr, etc\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface ISignatureMigrationFacet {\n event SignatureSchemeMigration(\n address indexed prevVerificationFacet,\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n event SignatureMigrationApproved(\n bytes newPublicKey,\n address indexed newVerificationFacet,\n bytes4[] verificationFuncSelectors,\n address indexed guardian,\n uint128 approvalValidUntil\n );\n event SignatureMigrationApprovalRevoked(\n bytes newPublicKey,\n address indexed newVerificationFacet,\n bytes4[] verificationFuncSelectors,\n address indexed guardian\n );\n event SignatureMigrationExecuted(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors,\n uint128 migrateAfter\n );\n event SignatureMigrationCanceled(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n event SignatureMigrationCancellationApproved(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n\n error SignatureMigrationFacet__SignerUninitializationFailure();\n error SignatureMigrationFacet__SignerInitializationFailure();\n error SignatureMigrationFacet__InvalidRouteWithGuardian();\n error SignatureMigrationFacet__InvalidKeyType();\n error SignatureMigrationFacet__InsufficientApprovers();\n error SignatureMigrationFacet__InvalidApproverSignature();\n error SignatureMigrationFacet__InvalidGuardian();\n error SignatureMigrationFacet__NonExistentApprover();\n error SignatureMigrationFacet__InvalidMigrationPeriod();\n error SignatureMigrationFacet__NonexistentMigration();\n error SignatureMigrationFacet__MigrationPeriodNotOver();\n error SignatureMigrationFacet__InvalidArrayLength();\n error SignatureMigrationFacet__InvalidApprovalValidationPeriod();\n error SignatureMigrationFacet__CannotRevokeUnapproved();\n error SignatureMigrationFacet__LackOfOwnerApproval();\n error SignatureMigrationFacet__OwnerAlreadyApproved();\n error SignatureMigrationFacet__NonExistentVerificationFacet();\n error SignatureMigrationFacet__DuplicateApproval();\n\n function migrateSignatureScheme(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function migrateSignatureSchemeWithGuardian(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors,\n address[] calldata approvers,\n bytes[] calldata signatures\n ) external;\n\n function approveSignatureSchemeMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function revokeSignatureMigrationApproval(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function finalizeSignatureMigration() external;\n\n function approveCancelSignatureMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function cancelSignatureMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function getApprovalMigrationKeyHash(\n bytes memory recoveryPublicKey,\n address newVerificationFacet,\n bytes4[] memory newVerificationFuncSelectors,\n string memory saltString\n ) external view returns (bytes32);\n\n function getMigrationOwnerApprovalWithTimeValidity(\n bytes32 publicKeyHash\n ) external view returns (bool);\n\n function getMigrationApprovalCountWithTimeValidity(\n bytes32 publicKeyHash\n ) external view returns (uint256);\n\n function isMigrationApproved(\n bytes32 migrationPublicKeyHash,\n address approver\n ) external view returns (bool);\n\n function getMigrationNonce() external view returns (uint128);\n\n function isMigrationPending() external view returns (bool);\n\n function getPendingMigration()\n external\n view\n returns (SignatureMigrationConfig memory);\n}\n" + }, + "contracts/facets/interfaces/IVerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {UserOperation} from \"../../aa-4337/interfaces/UserOperation.sol\";\n\n/**\n * @title Verification Facet Interface\n * @dev Implements logic for user ops signature verification\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface IVerificationFacet {\n event SignerInitialized(bytes);\n event SignerUninitialized();\n\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n error VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n error VerificationFacet__InitializationFailure();\n error VerificationFacet__InvalidFacetMapping();\n\n function initializeSigner(bytes memory) external returns (uint256);\n\n function uninitializeSigner() external returns (uint256);\n\n function validateOwnerSignatureSelector() external view returns (bytes4);\n\n function owner() external view returns (bytes memory);\n\n function isValidKeyType(bytes calldata) external view returns (bool);\n\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) external view returns (uint256);\n}\n" + }, + "contracts/facets/LockFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage, Lock} from \"../libraries/LibAppStorage.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibFacetStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {ILockFacet} from \"./interfaces/ILockFacet.sol\";\n\n/**\n * @title Lock Facet\n * @dev Contract that enables full lock/unlock of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract LockFacet is ILockFacet, Modifiers {\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Locks the account for the lock period. Lock period is defined in the security manager and it's customizable\n * This function can only be called when account is unlocked by owner or guardians\n * @dev This method checks the caller and if the account is currently locked and locks the account after fetching the\n * Lock period from the owner.\n */\n function lock() external override onlyGuardianOrOwner onlyWhenUnlocked {\n uint256 unlockTime = block.timestamp + getLockPeriod();\n unchecked {\n ++LibFacetStorage.lockStorage().nonce;\n }\n LibAppStorage.setLock(unlockTime, LockFacet.lock.selector);\n emit Locked(uint64(unlockTime));\n }\n\n /**\n * @notice Locks the account when the account is locked. This function can be called by anyone but must provide the approver address and signature.\n * The approver should be one of the guardians or owner.\n * @dev This method takes the approver address and the signature. After validating the address and the signature, it unlocks the account immediately.\n * Only one of the guardian or owner is required to lock and unlock the account.\n * @param _approver Address of approver approving the unlock of Barz account\n * @param _signature Signature of the approver that signed the msg hash for unlocking the account\n */\n function unlock(\n address _approver,\n bytes calldata _signature\n ) external override onlyWhenLocked {\n if (_approver != address(this) && !LibGuardian.isGuardian(_approver))\n revert LockFacet__InvalidApprover();\n if (\n !SignatureChecker.isValidSignatureNow(\n _approver,\n getUnlockHash(),\n _signature\n )\n ) revert LockFacet__InvalidSignature();\n _unlock();\n }\n\n /**\n * @notice Unlocks the account and increments the lock nonce\n */\n function _unlock() private {\n if (s.locks[INNER_STRUCT].locker != LockFacet.lock.selector)\n revert LockFacet__CannotUnlock();\n unchecked {\n ++LibFacetStorage.lockStorage().nonce;\n }\n LibAppStorage.setLock(0, bytes4(0));\n emit Unlocked();\n }\n\n /**\n * @notice Returns the lock period of current Barz account. Lock period information is held by Security Manager\n * @return lockPeriod Uint value of lock period in seconds\n */\n function getLockPeriod() public view override returns (uint256 lockPeriod) {\n lockPeriod = securityManager.lockPeriodOf(address(this));\n if (lockPeriod == 0) revert LockFacet__InvalidRecoveryPeriod();\n }\n\n /**\n * @notice Returns if the account is locked or not\n * @dev This method fetches the current block timestamp and compares that with release time.\n * After checking the timestamp and release time, it returns if the account is still locked or not.\n * @return isLocked_ Uint value of lock period in seconds\n */\n function isLocked() public view override returns (bool isLocked_) {\n isLocked_ = uint64(block.timestamp) < s.locks[INNER_STRUCT].release;\n }\n\n /**\n * @notice Calculates the unlock hash and returns the unlock hash safe from signature reply attack\n * @dev This method calculates the unlock hash with EIP-191 prefix, wallet address, chainID, and nonce\n * It packs the result and packs them and hashes it.\n * @return unlockHash Bytes32 unlock hash\n */\n function getUnlockHash() public view override returns (bytes32 unlockHash) {\n unlockHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n \"Unlock\",\n address(this),\n block.chainid,\n lockNonce()\n )\n )\n )\n );\n }\n\n /**\n * @notice Returns lock nonce of account. Reads nonce from lock storage within facet storage\n * @return lockNonce_ Uint128 value of lock nonce. This is incremented whenever the account is lock/unlocked\n */\n function lockNonce() public view override returns (uint128 lockNonce_) {\n lockNonce_ = LibFacetStorage.lockStorage().nonce;\n }\n\n /**\n * @notice Returns the overall information of current lock\n * @return pendingLock Struct value including all information of pending lock\n */\n function getPendingLock()\n public\n view\n override\n returns (Lock memory pendingLock)\n {\n pendingLock = s.locks[INNER_STRUCT];\n }\n}\n" + }, + "contracts/facets/Modifiers.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\n\n/**\n * @title Modifiers\n * @dev Responsible for providing modifiers/util functions to Facet contracts\n * @author David Yongjun Kim (@Powerstream3604)\n */\nabstract contract Modifiers is BarzStorage {\n uint8 constant INNER_STRUCT = 0;\n\n error CallerNotGuardian();\n error CallerNotGuardianOrOwner();\n error DuplicateApprover();\n error ZeroApproverLength();\n error UnregisteredFacetAndSelectors();\n\n /**\n * @notice Modifier to only allow guardian to make a call, reverts if any other entity is the caller\n */\n modifier onlyGuardian() {\n if (!LibGuardian.isGuardian(msg.sender)) revert CallerNotGuardian();\n _;\n }\n\n /**\n * @notice Modifier to only allow guardian or owner to make a call, reverts if any other entity is the caller\n */\n modifier onlyGuardianOrOwner() {\n if (!LibGuardian.isGuardian(msg.sender) && address(this) != msg.sender)\n revert CallerNotGuardianOrOwner();\n _;\n }\n\n /**\n * @notice Checks if the approver address is the array is unique with no duplicate\n * @dev This method loops through the array and checks if a duplicate address exists, it reverts if duplicate address exists\n * @param approvers Array of address\n */\n function _checkApprover(\n address[] memory approvers\n ) internal pure returns (bool) {\n uint256 approverLength = approvers.length;\n if (0 == approverLength) revert ZeroApproverLength();\n for (uint256 i; i < approverLength - 1; ) {\n for (uint256 j = i + 1; j < approverLength; ) {\n if (approvers[i] == approvers[j]) {\n revert DuplicateApprover(); // Found a duplicate\n }\n unchecked {\n ++j;\n }\n }\n unchecked {\n ++i;\n }\n }\n return false; // No duplicates found\n }\n\n /**\n * @notice Checks if the facet getting added or replaced is registered to facet registry\n * @dev This method loops through the cut and checks if the facet getting added/replaced is registered to facet registry\n * @param _diamondCut Array of FacetCut, data for diamondCut defined in EIP-2535\n */\n function _checkFacetCutValidity(\n IDiamondCut.FacetCut[] memory _diamondCut\n ) internal view {\n uint256 diamondCutLength = _diamondCut.length;\n for (uint256 i; i < diamondCutLength; ) {\n if (\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Add ||\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Replace\n ) {\n if (\n !s.facetRegistry.areFacetFunctionSelectorsRegistered(\n _diamondCut[i].facetAddress,\n _diamondCut[i].functionSelectors\n )\n ) revert UnregisteredFacetAndSelectors();\n }\n unchecked {\n ++i;\n }\n }\n }\n}\n" + }, + "contracts/facets/ReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibReentrancyGuardStorage, ReentrancyGuardStorage} from \"../libraries/LibReentrancyGuardStorage.sol\";\n\nabstract contract ReentrancyGuard {\n\n uint256 private constant _NOT_ENTERED = 0;\n uint256 private constant _ENTERED = 1;\n\n error ReentrancyGuard__ReentrantCall();\n\n modifier nonReentrant() {\n ReentrancyGuardStorage storage rgs = LibReentrancyGuardStorage.reentrancyguardStorage();\n\n if (rgs.status == _ENTERED) revert ReentrancyGuard__ReentrantCall();\n\n rgs.status = _ENTERED;\n\n _; // Execute function\n\n rgs.status = _NOT_ENTERED;\n }\n}\n" + }, + "contracts/facets/RestrictionsFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ReentrancyGuard} from \"./ReentrancyGuard.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, RestrictionsStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {IRestriction} from \"../restrictions/IRestriction.sol\";\nimport {IRestrictionsFacet} from \"./interfaces/IRestrictionsFacet.sol\";\n\n/**\n * @title Restrictions facet\n * @dev Responsible for storing and verifying different kinds of restrictions, for example:\n * - Whitelist / Blacklist\n * - Daily limits\n * - Trading time restrictions\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract RestrictionsFacet is IRestrictionsFacet, ReentrancyGuard {\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceRestrictionsInitialize();\n }\n\n /**\n * @notice Intialize restrictions of Barz. Restrictions facet call restriction contracts for restriction validation\n * before each call\n * @param _restrictions The initial array of restrictions.\n * @return initSuccess Int value showing if the initialization of restriction is successful\n */\n function initializeRestrictions(\n address[] calldata _restrictions\n ) public override returns (uint256 initSuccess) {\n LibDiamond.enforceIsSelf();\n LibAppStorage.enforceRestrictionsInitialize();\n\n if (_restrictions.length == 0) {\n // You can't initialize RestrictionsFacet with an empty list of restrictions\n revert RestrictionsFacet__EmptyRestrictionsList();\n }\n for (uint256 i; i < _restrictions.length; ) {\n if (_restrictions[i] == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictions();\n unchecked {\n ++i;\n }\n }\n\n LibFacetStorage.restrictionsStorage().restrictions = _restrictions;\n _updateRestrictionsMap(_restrictions, true);\n initSuccess = 1;\n }\n\n /**\n * @notice Unitialize restrictions of Barz\n * @return uninitSuccess Int value showing if the initialization of restriction is successful\n */\n function uninitializeRestrictions()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibDiamond.enforceIsSelf();\n LibAppStorage.setRestrictionsUninitialized();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n _updateRestrictionsMap(restrictionsStorage.restrictions, false);\n restrictionsStorage.restrictions = new address[](0);\n uninitSuccess = 1;\n }\n\n /**\n * @notice Returns the list of Restrictions contract address\n * @return restrictions Addresses of IRestriction which are currently active\n */\n function getRestrictions()\n public\n view\n override\n returns (address[] memory restrictions)\n {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n restrictions = restrictionsStorage.restrictions;\n }\n\n /**\n * @notice Adds restrictions to Barz with validation on the restriction contract address.\n * This method is only callable by the owner(self).\n * @param _restriction The address of the restriction to be added.\n */\n function addRestriction(address _restriction) external override {\n LibDiamond.enforceIsSelf();\n if (LibDiamond.restrictionsFacet() == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictionsFacet();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n if (_restriction == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictions();\n if (restrictionsStorage.exists[_restriction])\n revert RestrictionsFacet__RestrictionAlreadyExists();\n\n restrictionsStorage.restrictions.push(_restriction);\n restrictionsStorage.exists[_restriction] = true;\n\n emit RestrictionAdded(_restriction);\n }\n\n /**\n * @notice Remove restrictions from Barz if it existed. This method is only callable by the owner(self).\n * @param _restriction The address of the restriction to be removed.\n */\n function removeRestriction(address _restriction) external override {\n LibDiamond.enforceIsSelf();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n if (!restrictionsStorage.exists[_restriction])\n revert RestrictionsFacet__RestrictionNotFound();\n\n address[] storage restrictions = restrictionsStorage.restrictions;\n\n uint256 indexToDelete = restrictions.length;\n uint256 restrictionsLen = restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n if (restrictions[i] == _restriction) {\n indexToDelete = i;\n break;\n }\n unchecked {\n ++i;\n }\n }\n\n if (indexToDelete == 0 && restrictionsLen == 1) {\n revert RestrictionsFacet__RemainingRestrictionsCantBeEmpty();\n } else if (indexToDelete == restrictionsLen) {\n revert RestrictionsFacet__RestrictionNotFound();\n } else {\n restrictions[indexToDelete] = restrictions[restrictionsLen - 1];\n restrictions.pop();\n }\n\n restrictionsStorage.exists[_restriction] = false;\n emit RestrictionRemoved(_restriction);\n }\n\n /**\n * @notice Sets the restrictions address value mapping to true or false when adding/removing restriction contracts\n * @param _restrictions List of restriction contracts address\n * @param _newValue Bool value to flag to the list of restrictions contracts\n */\n function _updateRestrictionsMap(\n address[] memory _restrictions,\n bool _newValue\n ) internal {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n uint restrictionsLen = _restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n restrictionsStorage.exists[_restrictions[i]] = _newValue;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @dev Iterates over all restrictions and verifies each of them with the transaction parameters.\n * @param _from The address of the sender, that will be signing the transaction.\n * @param _to The receiving address.\n * @param _value Amount of ETH to transfer from sender to recipient.\n * @param _calldata Optional field to include arbitrary data.\n * @return 0 if all the checks passed, 1 otherwise.\n */\n function verifyRestrictions(\n address _from,\n address _to,\n uint256 _value,\n bytes calldata _calldata\n ) external nonReentrant returns (uint256) {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n uint restrictionsLen = restrictionsStorage.restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n IRestriction restriction = IRestriction(\n restrictionsStorage.restrictions[i]\n );\n bool checkPassed = restriction.check(_from, _to, _value, _calldata);\n if (!checkPassed) {\n return 1;\n }\n unchecked {\n ++i;\n }\n }\n\n return 0;\n }\n}\n" + }, + "contracts/facets/SignatureMigrationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, SignatureMigrationStorage, SignatureMigrationConfig, SignatureMigrationApprovalConfig, ApprovalConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IDiamondCut} from \"./base/interfaces/IDiamondCut.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {ISignatureMigrationFacet} from \"./interfaces/ISignatureMigrationFacet.sol\";\n\n/**\n * @title Signature Migration Facet\n * @dev Responsible for migrating user signature scheme to a new scheme user sets\n * Which could include\n * - ECDSA on Secp256K1 Curve\n * - ECDSA on Secp256R1 Curve\n * - BLS, Schnorr, etc\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract SignatureMigrationFacet is ISignatureMigrationFacet, Modifiers {\n bytes constant UNINIT_CALL =\n abi.encodeWithSignature(\"uninitializeSigner()\");\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This modifier verifies if the public key format matches with the new verification facet\n * @param _publicKey Bytes of public key to be validated for the new verification facet\n * @param _newVerificationFacet Address of new verification facet\n */\n modifier validateKeyType(\n bytes memory _publicKey,\n address _newVerificationFacet\n ) {\n if (\n !IVerificationFacet(_newVerificationFacet).isValidKeyType(\n _publicKey\n )\n ) revert SignatureMigrationFacet__InvalidKeyType();\n _;\n }\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n // IMPORTANT NOTE: In the client side when they call this function, the func selectors should be sorted in ascending order\n // to prevent different hash with same items in the array\n /**\n * @notice Moves the state of migration to a pending state. When pending state is over after pending period time,\n * Migration can be finalized. This function can only be called by self and when the account is unlocked.\n * @dev This method checks if the caller is self and if guardians exists. It migrates signature request to a pending state\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function migrateSignatureScheme(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n public\n override\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n // Only self contract can call this function\n LibDiamond.enforceIsSelf();\n // Should revert if guardian exist\n if (0 != LibGuardian.guardianCount())\n revert SignatureMigrationFacet__InvalidRouteWithGuardian();\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n // NOTE: Migration requires a pending period & confirmation from owner to prevent a\n // single call changing the ownership of the wallet\n /**\n * @notice Migrate signature scheme when guardians exists. Verifies the signature of guardians and moves migration to pending state.\n * Which can then be finalized when pending period is over. Owner's approval is mandatory for migration to happen\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _approvers List of approvers. This could include owner\n */\n function migrateSignatureSchemeWithGuardian(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n )\n public\n override\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n // Should revert if does not guardian exist\n if (0 == LibGuardian.guardianCount())\n revert SignatureMigrationFacet__InvalidRouteWithGuardian();\n if (_approvers.length != _signatures.length)\n revert SignatureMigrationFacet__InvalidArrayLength();\n\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(migrationPublicKeyHash, _approvers);\n\n bool onChainOwnerApproval = getMigrationOwnerApprovalWithTimeValidity(\n migrationPublicKeyHash\n );\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n\n if (\n _approvers.length +\n getMigrationApprovalCountWithTimeValidity(\n migrationPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert SignatureMigrationFacet__InsufficientApprovers();\n {\n // To prevent Stack too deep\n bool ownerApproved;\n for (uint256 i; i < _approvers.length; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n address(this) != _approvers[i]\n ) revert SignatureMigrationFacet__InvalidGuardian();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert SignatureMigrationFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n migrationPublicKeyHash,\n _signatures[i]\n )\n ) revert SignatureMigrationFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n\n if (!ownerApproved && !onChainOwnerApproval)\n revert SignatureMigrationFacet__LackOfOwnerApproval();\n }\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Internal function that moves signature mgiration to a pending state.\n * @dev This method increments migration nonce and sets the migration in the migration config. Emits events for migration execution\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _migrateSignatureScheme(\n address _newVerificationFacet,\n bytes memory _newPublicKey,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal {\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n unchecked {\n ++ms.nonce;\n }\n uint64 migrateAfter = uint64(block.timestamp + getMigrationPeriod());\n\n ms.migrationConfigs[INNER_STRUCT] = SignatureMigrationConfig(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n migrateAfter\n );\n\n emit SignatureMigrationExecuted(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors,\n migrateAfter\n );\n }\n\n /**\n * @notice Approves signature scheme migration on-chain. This can be called by owner or guardian only when the account is unlocked.\n * When the threshold of the migration approval passed and owner approval is granted, it automatically moves migration to a pending state\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function approveSignatureSchemeMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n public\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit SignatureMigrationApproved(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n msg.sender,\n approvalValidUntil\n );\n if (\n getMigrationApprovalCountWithTimeValidity(migrationPublicKeyHash) >=\n LibGuardian.majorityOfGuardians() &&\n getMigrationOwnerApprovalWithTimeValidity(migrationPublicKeyHash)\n )\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Revokes the approval of signature migration done on-chain. Emits revoke event when revoked.\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function revokeSignatureMigrationApproval(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n external\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n if (!isMigrationApproved(migrationPublicKeyHash, msg.sender))\n revert SignatureMigrationFacet__CannotRevokeUnapproved();\n\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(false, 0);\n emit SignatureMigrationApprovalRevoked(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n msg.sender\n );\n }\n\n /**\n * @notice Finalizes the pending signature scheme migration. This function can only be called by owner.\n * It removes the facets of the previous verification facet and adds the new verification facet.\n * After finalizing migration, it emits migration event which shows the change of the verification facet\n */\n function finalizeSignatureMigration() external override {\n // NOTE: Only owner can call this function\n LibDiamond.enforceIsSelf();\n\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n\n if (!isMigrationPending())\n revert SignatureMigrationFacet__NonexistentMigration();\n\n if (\n uint64(block.timestamp) <=\n ms.migrationConfigs[INNER_STRUCT].migrateAfter\n ) revert SignatureMigrationFacet__MigrationPeriodNotOver();\n address newVerificationFacet = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationVerificationFacet;\n bytes4[] memory newVerificationFuncSelectors = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationSelectors;\n bytes memory newPublicKey = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationPublicKey;\n\n address prevVerificationFacet = LibLoupe.facetAddress(\n s.validateOwnerSignatureSelector\n );\n if (prevVerificationFacet == address(0))\n revert SignatureMigrationFacet__NonExistentVerificationFacet();\n\n IDiamondCut.FacetCut[] memory UninitCut;\n IDiamondCut.FacetCut[] memory InitCut;\n {\n bytes4[] memory prevVerificationFuncSelectors = LibLoupe\n .facetFunctionSelectors(prevVerificationFacet);\n\n UninitCut = new IDiamondCut.FacetCut[](1);\n InitCut = new IDiamondCut.FacetCut[](1);\n UninitCut[0] = IDiamondCut.FacetCut({\n facetAddress: address(0),\n action: IDiamondCut.FacetCutAction.Remove,\n functionSelectors: prevVerificationFuncSelectors\n });\n InitCut[0] = IDiamondCut.FacetCut({\n facetAddress: newVerificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: newVerificationFuncSelectors\n });\n {\n IDiamondCut.FacetCut[]\n memory facetCuts = new IDiamondCut.FacetCut[](2);\n facetCuts[0] = UninitCut[0];\n facetCuts[1] = InitCut[0];\n _checkFacetCutValidity(facetCuts);\n }\n LibAppStorage.initiateSignerMigration();\n address verificationFacet = address(\n bytes20(\n LibDiamond.diamondStorage().facets[\n s.validateOwnerSignatureSelector\n ]\n )\n );\n\n (bool uninitSuccess, bytes memory uninitResult) = verificationFacet\n .delegatecall(UNINIT_CALL);\n if (!uninitSuccess || uint256(bytes32(uninitResult)) != 1)\n revert SignatureMigrationFacet__SignerUninitializationFailure();\n LibAppStorage.finalizeSignerMigration();\n\n LibDiamond.diamondCut(UninitCut, address(0), \"\");\n }\n {\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n newPublicKey\n );\n\n // Every Verification Facet should comply with initializeSigner(bytes)\n // to be compatible with the Barz contract(for initialization)\n LibDiamond.diamondCut(InitCut, address(0), \"\");\n (bool initSuccess, bytes memory initResult) = newVerificationFacet\n .delegatecall(initCall);\n if (!initSuccess || uint256(bytes32(initResult)) != 1)\n revert SignatureMigrationFacet__SignerInitializationFailure();\n\n emit SignatureSchemeMigration(\n prevVerificationFacet,\n newVerificationFacet,\n newPublicKey,\n newVerificationFuncSelectors\n );\n }\n }\n\n /**\n * @notice Approve cancellation of signature migration. If cancellation approval passes guardian threshold with owner approval\n * it automatically cancels the migration.\n * @dev This method checks if the caller is one of guardian or owner and sets true for the cancellation hash in the approval config.\n * It internally calls _cancelSignatureMigration for canceling the migration\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function approveCancelSignatureMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n external\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"CancelSignatureMigration\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit SignatureMigrationCancellationApproved(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n if (\n getMigrationApprovalCountWithTimeValidity(migrationPublicKeyHash) >=\n LibGuardian.majorityOfGuardians() &&\n getMigrationOwnerApprovalWithTimeValidity(migrationPublicKeyHash)\n )\n _cancelSignatureMigration(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Verifies the signature of guardians/owner and cancels the signature migration.\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _approvers List of approvers. This could include owner\n */\n function cancelSignatureMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n )\n external\n override\n validateKeyType(_newPublicKey, _newVerificationFacet)\n onlyWhenUnlocked\n {\n if (_approvers.length != _signatures.length)\n revert SignatureMigrationFacet__InvalidArrayLength();\n\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"CancelSignatureMigration\"\n );\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(migrationPublicKeyHash, _approvers);\n\n bool onChainOwnerApproval = getMigrationOwnerApprovalWithTimeValidity(\n migrationPublicKeyHash\n );\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n if (\n _approvers.length +\n getMigrationApprovalCountWithTimeValidity(\n migrationPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert SignatureMigrationFacet__InsufficientApprovers();\n {\n // To prevent stack too deep\n bool ownerApproved;\n for (uint256 i; i < _approvers.length; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n address(this) != _approvers[i]\n ) revert SignatureMigrationFacet__NonExistentApprover();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert SignatureMigrationFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n migrationPublicKeyHash,\n _signatures[i]\n )\n ) revert SignatureMigrationFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n if (!ownerApproved && !onChainOwnerApproval)\n revert SignatureMigrationFacet__LackOfOwnerApproval();\n }\n _cancelSignatureMigration(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Internal function that cancels signature migration.\n * @dev This method increments migration nonce and deletes the migration from the migration config. Emits events for migration cancellation\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _cancelSignatureMigration(\n address _newVerificationFacet,\n bytes memory _newPublicKey,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal {\n if (!isMigrationPending())\n revert SignatureMigrationFacet__NonexistentMigration();\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n unchecked {\n ++ms.nonce;\n }\n delete ms.migrationConfigs[INNER_STRUCT];\n emit SignatureMigrationCanceled(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Checks if the facets to be added from new verification facet is registered to facet registry\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _checkMigrationCutValidity(\n address _newVerificationFacet,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal view {\n IDiamondCut.FacetCut[] memory facetCuts = new IDiamondCut.FacetCut[](1);\n facetCuts[0] = IDiamondCut.FacetCut({\n facetAddress: _newVerificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: _newVerificationFuncSelectors\n });\n _checkFacetCutValidity(facetCuts);\n }\n\n /**\n * @notice Returns if the migration is pending of not\n * @dev This method fetches the migration storage and checks if the migrate after is above 0 value\n * @return isPending Bool value that shows if the migration is pending\n */\n function isMigrationPending()\n public\n view\n override\n returns (bool isPending)\n {\n SignatureMigrationStorage storage rs = LibFacetStorage\n .migrationStorage();\n isPending = rs.migrationConfigs[INNER_STRUCT].migrateAfter > 0;\n }\n\n /**\n * @notice Returns the migration hash. This function ensures that this hash is safe from replay attack by including\n * public key, verification facet, function selectors, salt, address, chainId, and nonce.\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _saltString Salt value for generating the migration hash\n * @return migrationKeyHash Bytes32 string of the migration key hash\n */\n function getApprovalMigrationKeyHash(\n bytes memory _newPublicKey,\n address _newVerificationFacet,\n bytes4[] memory _newVerificationFuncSelectors,\n string memory _saltString\n ) public view override returns (bytes32 migrationKeyHash) {\n migrationKeyHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n _newPublicKey,\n _newVerificationFacet,\n keccak256(abi.encode(_newVerificationFuncSelectors)),\n _saltString,\n address(this),\n block.chainid,\n LibFacetStorage.migrationStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Checks if the owner approved the hash for migration\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @return isApprovedByOwner Bool value of showing if the owner approved it or not\n */\n function getMigrationOwnerApprovalWithTimeValidity(\n bytes32 _migrationPublicKeyHash\n ) public view override returns (bool isApprovedByOwner) {\n isApprovedByOwner = isMigrationApproved(\n _migrationPublicKeyHash,\n address(this)\n );\n }\n\n /**\n * @notice Checks how many of the guardians approved the migration hash\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @return approvalCount Number of approvals\n */\n function getMigrationApprovalCountWithTimeValidity(\n bytes32 _migrationPublicKeyHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardiansLength = guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n if (isMigrationApproved(_migrationPublicKeyHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n return approvalCount;\n }\n\n /**\n * @notice Checks if the migration is approved by the given approver\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @param _approver Address of approver\n * @return isApproved Bool value if migration hash is approved\n */\n function isMigrationApproved(\n bytes32 _migrationPublicKeyHash,\n address _approver\n ) public view override returns (bool isApproved) {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n isApproved = (ms\n .isMigrationApproved[_migrationPublicKeyHash][_approver].isApproved &&\n block.timestamp <\n ms\n .isMigrationApproved[_migrationPublicKeyHash][_approver]\n .validUntil);\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _migrationPublicKeyHash Hash of migration information\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _migrationPublicKeyHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isMigrationApproved(_migrationPublicKeyHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert SignatureMigrationFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the migration period of this wallet\n * @dev This method fetches the migration period from the security manager\n * @return migrationPeriod Migration period of Barz contract fetched from security manager\n */\n function getMigrationPeriod()\n internal\n view\n returns (uint128 migrationPeriod)\n {\n migrationPeriod = securityManager.migrationPeriodOf(address(this));\n if (migrationPeriod == 0)\n revert SignatureMigrationFacet__InvalidMigrationPeriod();\n }\n\n /**\n * @notice Returns the validation period of this wallet\n * @dev This method fetches the validation period from the security manager\n * @return approvalValidationPeriod Validation period of Barz contract fetched from security manager\n */\n function getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod == 0)\n revert SignatureMigrationFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the migration nonce of this wallet\n * @dev This method fetches the nonce from migration storage\n * @return migrationNonce Nonce of migration to protect from reply attacks\n */\n function getMigrationNonce()\n public\n view\n override\n returns (uint128 migrationNonce)\n {\n migrationNonce = LibFacetStorage.migrationStorage().nonce;\n }\n\n /**\n * @notice Returns the migration configuration of this wallet\n * @dev This method fetches the migration config from the migration storage\n * @return pendingMigrationConfig Migration config currently pending for signature migration\n */\n function getPendingMigration()\n external\n view\n override\n returns (SignatureMigrationConfig memory pendingMigrationConfig)\n {\n pendingMigrationConfig = LibFacetStorage\n .migrationStorage()\n .migrationConfigs[INNER_STRUCT];\n }\n}\n" + }, + "contracts/facets/TokenReceiverFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {IERC1155Receiver} from \"../interfaces/ERC/IERC1155Receiver.sol\";\nimport {IERC677Receiver} from \"../interfaces/ERC/IERC677Receiver.sol\";\n\n/**\n * @title TokenReceiver Facet\n * @dev Contract that enables receiving ERC721/ERC1155/ERC777/ERC677 Tokens with safe transfer\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract TokenReceiverFacet is\n IERC721Receiver,\n IERC1155Receiver,\n IERC777Recipient,\n IERC677Receiver\n{\n /**\n * @notice Handles ERC721 Token callback.\n * return Standardized onERC721Received return value.\n */\n function onERC721Received(\n address,\n address,\n uint256,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC721Receiver.onERC721Received.selector;\n }\n\n /**\n * @notice Handles ERC1155 Token callback.\n * return Standardized onERC1155Received return value.\n */\n function onERC1155Received(\n address,\n address,\n uint256,\n uint256,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC1155Receiver.onERC1155Received.selector;\n }\n\n /**\n * @notice Handles ERC1155 Token batch callback.\n * return Standardized onERC1155BatchReceived return value.\n */\n function onERC1155BatchReceived(\n address,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC1155Receiver.onERC1155BatchReceived.selector;\n }\n\n /**\n * @notice Handles ERC777 Token callback.\n * Does not return value, empty implementation.\n */\n function tokensReceived(\n address,\n address,\n address,\n uint256,\n bytes calldata,\n bytes calldata\n ) external pure override {}\n\n /**\n * @notice Handles ERC677 Token callback.\n * return true.\n */\n function onTokenTransfer(\n address,\n uint256,\n bytes calldata\n ) external pure override returns (bool) {\n return true;\n }\n}\n" + }, + "contracts/facets/verification/MultiSigFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {UserOperation} from \"../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../../libraries/LibLoupe.sol\";\nimport {LibAppStorage} from \"../../libraries/LibAppStorage.sol\";\nimport {LibMultiSigStorage, MultiSigStorage} from \"../../libraries/LibMultiSigStorage.sol\";\nimport {IERC1271} from \"../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../interfaces/IVerificationFacet.sol\";\nimport {IMultiSigFacet} from \"../interfaces/IMultiSigFacet.sol\";\n\n/**\n * @title Multi-sig facet\n * @dev Multi-signature Facet with custom threshold.\n * Wallet that adds this facet becomes a multi-sig wallet.\n * Reference signature_format.md documentation for Multi-sig facet details\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract MultiSigFacet is IMultiSigFacet, IVerificationFacet, IERC1271 {\n using ECDSA for bytes32;\n\n address public immutable self;\n\n address internal constant SENTINEL_OWNERS = address(0x1);\n uint256 internal constant ADDRESS = 20;\n uint256 internal constant SIG_TYPE = 1;\n uint256 internal constant SIG_LEN = 4;\n uint256 internal constant THRESHOLD = 4;\n uint256 internal constant INVALID_SIG = 1;\n uint256 internal constant VALID_SIG = 0;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in Multisig Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the right format and initializes signer storage in k1 storage.\n * @param _owners Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _owners\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n\n if (!isValidKeyType(_owners)) revert MultiSigFacet__InvalidInitData();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n uint256 threshold = uint256(uint32(bytes4(_owners)));\n uint256 ownerCount = (_owners.length - THRESHOLD) / ADDRESS;\n\n if (threshold == 0) revert MultiSigFacet__InvalidThreshold();\n if (ownerCount == 0) revert MultisigFacet__InvalidOwnerCount();\n\n address currentOwner = SENTINEL_OWNERS;\n uint256 ptr = THRESHOLD;\n address owner_;\n for (uint256 i; i < ownerCount; ) {\n owner_ = address(bytes20(_owners[ptr:ptr + ADDRESS]));\n ptr += ADDRESS;\n if (\n owner_ == address(0) ||\n owner_ == SENTINEL_OWNERS ||\n owner_ == address(this) ||\n owner_ == currentOwner\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[owner_] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n\n ms.owners[currentOwner] = owner_;\n currentOwner = owner_;\n\n unchecked {\n ++i;\n }\n }\n ms.owners[currentOwner] = SENTINEL_OWNERS;\n ms.ownerCount = ownerCount;\n ms.threshold = threshold;\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_owners);\n }\n\n /**\n * @notice Uninitialize signer in K1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n ++ms.counter;\n address[] memory ownerlist = getOwners();\n uint256 ownerlistLength = ownerlist.length;\n for (uint256 i; i < ownerlistLength; ) {\n ms.owners[ownerlist[i]] = address(0);\n unchecked {\n ++i;\n }\n }\n ms.owners[SENTINEL_OWNERS] = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls checkSignatures with\n * user operation hash and signature together with the threshold.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n // Data 1 is invalid, Data 0 is valid\n validationData = checkSignatures(\n userOpHash,\n userOp.signature,\n LibMultiSigStorage.multisigStorage().threshold\n );\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n return this.validateOwnerSignature.selector;\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n uint totalLength = ms.ownerCount * ADDRESS;\n bytes memory result = new bytes(totalLength);\n\n // populate return array\n uint256 index;\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n while (currentOwner != SENTINEL_OWNERS) {\n assembly {\n mstore(\n add(result, add(32, mul(index, ADDRESS))),\n shl(96, currentOwner)\n )\n }\n currentOwner = ms.owners[currentOwner];\n index++;\n }\n\n return result;\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key should comply with the format in the signature_format.md doc\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n uint256 publicKeyLength = _publicKey.length;\n if (\n publicKeyLength < ADDRESS + THRESHOLD ||\n (publicKeyLength - THRESHOLD) % ADDRESS != 0\n ) return false;\n\n uint256 threshold = uint256(uint32(bytes4(_publicKey)));\n uint256 ownerCount = (publicKeyLength - THRESHOLD) / ADDRESS;\n\n isValid = !(ownerCount < threshold || threshold == 0);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes calldata _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (checkSignatures(\n _hash,\n _signature,\n LibMultiSigStorage.multisigStorage().threshold\n ) == VALID_SIG)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n\n /**\n * @notice Validates the format of the signature and verifies if the signature is signed by the expected key.\n * Reference signature_format.md doc for details about signature format and signature types\n * @param _dataHash Bytes value of data hash signed by the owners\n * @param _signatures Bytes value of signature which should comply with signature format\n * @param _threshold Uint256 value of current Multi-sig Barz's threshold\n */\n function checkSignatures(\n bytes32 _dataHash,\n bytes calldata _signatures,\n uint256 _threshold\n ) public view returns (uint256) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n address lastOwner = address(0);\n address currentOwner;\n bytes memory signature;\n uint256 signatureType;\n uint256 nextOffset;\n uint256 i;\n for (i; i < _threshold; ) {\n (\n currentOwner,\n signature,\n signatureType,\n nextOffset\n ) = splitSignatures(_signatures, nextOffset);\n if (nextOffset == 0 && i + 1 < _threshold) return INVALID_SIG;\n if (signatureType == 1) {\n // If signatureType is 1 then it is default dataHash signed.\n // This also includes the contract signature\n if (\n !SignatureChecker.isValidSignatureNow(\n currentOwner,\n _dataHash,\n signature\n )\n ) return INVALID_SIG;\n } else if (signatureType == 2) {\n // If signatureType is 2 then it is an approved hash\n if (ms.approvedHashes[ms.counter][currentOwner][_dataHash] == 0)\n return INVALID_SIG;\n } else if (signatureType == 3) {\n // If signatureType is 3 then it is a signed message hash\n // This also includes the contract signature\n bytes32 msgHash = _dataHash.toEthSignedMessageHash();\n if (\n !SignatureChecker.isValidSignatureNow(\n currentOwner,\n msgHash,\n signature\n )\n ) return INVALID_SIG;\n } else revert MultiSigFacet__InvalidRoute();\n if (\n currentOwner <= lastOwner ||\n ms.owners[currentOwner] == address(0) ||\n currentOwner == SENTINEL_OWNERS\n ) return INVALID_SIG;\n lastOwner = currentOwner;\n\n unchecked {\n ++i;\n }\n }\n return VALID_SIG;\n }\n\n /**\n * @notice Split signatures into each individual signatures. Should comply with signature format to be split\n * @param _signatures Bytes value of signature\n * @param _nextOffset Uint256 value of next offset to start splitting the signature\n */\n function splitSignatures(\n bytes calldata _signatures,\n uint256 _nextOffset\n )\n public\n pure\n returns (\n address owner_,\n bytes memory signature,\n uint256 signatureType,\n uint256 nextOffset\n )\n {\n uint256 signaturesLength = _signatures.length;\n\n if (signaturesLength <= _nextOffset + ADDRESS + SIG_LEN)\n revert MultiSigFacet__InsufficientSignerLength();\n\n owner_ = address(\n bytes20(_signatures[_nextOffset:_nextOffset + ADDRESS])\n );\n\n signatureType = uint256(\n uint8(\n bytes1(\n _signatures[_nextOffset + ADDRESS:_nextOffset +\n ADDRESS +\n SIG_TYPE]\n )\n )\n );\n\n if (signatureType > 3 || signatureType == 0)\n revert MultiSigFacet__InvalidSignatureType();\n uint256 offSet = _nextOffset + ADDRESS + SIG_TYPE;\n uint256 siglen = uint256(\n uint32(bytes4(_signatures[offSet:offSet + SIG_LEN]))\n );\n if (offSet + siglen > signaturesLength)\n revert MultiSigFacet__InvalidSignatureLength();\n\n offSet += SIG_LEN;\n if (offSet + siglen == signaturesLength) nextOffset = 0;\n else nextOffset = offSet + siglen;\n\n signature = _signatures[offSet:offSet + siglen];\n }\n\n /**\n * @notice Approves the hash of userOperation on-chain. This can only be called by owners.\n * @param _hashToApprove Bytes value of UserOperation hash to approve\n */\n function approveHash(bytes32 _hashToApprove) external {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (ms.owners[msg.sender] == address(0))\n revert MultiSigFacet__OnlyOwner();\n\n ms.approvedHashes[ms.counter][msg.sender][_hashToApprove] = 1;\n emit HashApproved(_hashToApprove, msg.sender);\n }\n\n /**\n * @notice Add owner to Barz. Update thresold if threshold is given different from current threshold\n * @dev This can only be done via a Self call.\n * @param _newOwner Address of new owner to be added\n * @param _threshold Uint256 value of threshold\n */\n function addOwner(address _newOwner, uint256 _threshold) external {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (\n _newOwner == address(0) ||\n _newOwner == SENTINEL_OWNERS ||\n _newOwner == address(this)\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_newOwner] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n\n ms.owners[_newOwner] = ms.owners[SENTINEL_OWNERS];\n ms.owners[SENTINEL_OWNERS] = _newOwner;\n ++ms.ownerCount;\n emit OwnerAdded(_newOwner);\n\n if (ms.threshold != _threshold) changeThreshold(_threshold);\n }\n\n /**\n * @notice Remove owner from Barz. Update thresold if threshold is given different from current threshold\n * @dev This can only be done via a Self call.\n * @param _prevOwner Address of owner located right behind the removed owner address in the linked list\n * @param _removedOwner Address of owner to be removed\n * @param _threshold Uint256 value of threshold\n */\n function removeOwner(\n address _prevOwner,\n address _removedOwner,\n uint256 _threshold\n ) external {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (ms.ownerCount - 1 < _threshold)\n revert MultiSigFacet__InvalidThreshold();\n if (_removedOwner == address(0) || _removedOwner == SENTINEL_OWNERS)\n revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_prevOwner] != _removedOwner)\n revert MultiSigFacet__InvalidOwnerPair();\n\n ms.owners[_prevOwner] = ms.owners[_removedOwner];\n ms.owners[_removedOwner] = address(0);\n --ms.ownerCount;\n emit OwnerRemoved(_removedOwner);\n\n if (ms.threshold != _threshold) changeThreshold(_threshold);\n }\n\n /**\n * @notice Swap owner in Barz.\n * @dev This can only be done via a Self call.\n * @param _prevOwner Address of owner located right behind the removed owner address in the linked list\n * @param _oldOwner Address of owner to be removed\n * @param _newOwner Address of owner to be added\n */\n function swapOwner(\n address _prevOwner,\n address _oldOwner,\n address _newOwner\n ) public {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (\n _newOwner == address(0) ||\n _newOwner == SENTINEL_OWNERS ||\n _newOwner == address(this)\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_newOwner] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n if (_oldOwner == address(0) || _oldOwner == SENTINEL_OWNERS)\n revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_prevOwner] != _oldOwner)\n revert MultiSigFacet__InvalidOwnerPair();\n\n ms.owners[_newOwner] = ms.owners[_oldOwner];\n ms.owners[_prevOwner] = _newOwner;\n ms.owners[_oldOwner] = address(0);\n emit OwnerRemoved(_oldOwner);\n emit OwnerAdded(_newOwner);\n }\n\n /**\n * @notice Changes the threshold of the Barz to `_threshold`.\n * @dev This can only be done via a Self call.\n * @param _threshold New threshold\n */\n function changeThreshold(uint256 _threshold) public {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (_threshold > ms.ownerCount || _threshold == 0)\n revert MultiSigFacet__InvalidThreshold();\n\n ms.threshold = _threshold;\n emit ThresholdChanged(_threshold);\n }\n\n /**\n * @notice Checks if the given address is owner\n * @param _owner Address to be checked if it's owner\n * @return isOwner_ Bool value showing if it's owner address\n */\n function isOwner(address _owner) public view returns (bool isOwner_) {\n isOwner_ = (_owner != SENTINEL_OWNERS &&\n LibMultiSigStorage.multisigStorage().owners[_owner] != address(0));\n }\n\n /**\n * @notice Returns the threshold of Barz\n * @return threshold Threshold of the Barz account\n */\n function getThreshold() public view returns (uint256 threshold) {\n threshold = LibMultiSigStorage.multisigStorage().threshold;\n }\n\n /**\n * @notice Returns the list of owner addresses\n * @return owners List of owners\n */\n function getOwners() public view returns (address[] memory owners) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n owners = new address[](ms.ownerCount);\n\n uint256 index;\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n while (currentOwner != SENTINEL_OWNERS) {\n owners[index] = currentOwner;\n currentOwner = ms.owners[currentOwner];\n index++;\n }\n }\n\n /**\n * @notice Returns the previous owner in the linked list\n * @param _owner Address of owner\n * @return prevOwner Address of previous owner\n */\n function getPrevOwner(\n address _owner\n ) public view returns (address prevOwner) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n if (currentOwner == _owner) return SENTINEL_OWNERS;\n while (currentOwner != SENTINEL_OWNERS) {\n if (ms.owners[currentOwner] == _owner) return currentOwner;\n\n currentOwner = ms.owners[currentOwner];\n }\n return address(0);\n }\n\n /**\n * @notice Returns of the owner is approved by given owner address\n * @param _owner Address of owner\n * @param _hash Hash of UserOperation\n * @return isApproved Bool value showing if the hash is approved by owner\n */\n function isApprovedHash(\n address _owner,\n bytes32 _hash\n ) public view returns (bool isApproved) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n isApproved = (ms.approvedHashes[ms.counter][_owner][_hash] == 1);\n }\n}\n" + }, + "contracts/facets/verification/secp256k1/Secp256k1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {UserOperation} from \"../../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibAppStorage} from \"../../../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, Secp256k1VerificationStorage} from \"../../../libraries/LibFacetStorage.sol\";\nimport {LibLoupe} from \"../../../libraries/LibLoupe.sol\";\nimport {IERC1271} from \"../../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../../interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Secp256k1 verification facet\n * @dev Default Ethereum's elliptic curve\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract Secp256k1VerificationFacet is IVerificationFacet, IERC1271 {\n using ECDSA for bytes32;\n error Secp256k1VerificationFacet__InvalidSignerLength();\n address public immutable self;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in K1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\n * @param _publicKey Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _publicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n if (!isValidKeyType(_publicKey))\n revert Secp256k1VerificationFacet__InvalidSignerLength();\n\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(uint160(uint256(keccak256(_publicKey[1:]))));\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_publicKey);\n }\n\n /**\n * @notice Uninitialize signer in K1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\n * signer public key.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n validationData = validateSignature(\n userOp,\n userOpHash,\n k1Storage.signer\n );\n }\n\n /**\n * @notice Validates if the signature of UserOperation is signed by the given signer\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @param signer Address of signer who signed the contract, to be validated\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n address signer\n ) public pure returns (uint256 isValid) {\n bytes32 hash = userOpHash.toEthSignedMessageHash();\n isValid = (signer != hash.recover(userOp.signature)) ? 1 : 0;\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n ownerSignatureValidatorSelector = this.validateOwnerSignature.selector;\n // NOTE: The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory signer) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n signer = abi.encodePacked(k1Storage.signer);\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key length should be 65 in an uncompressed public key format\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (_hash.recover(_signature) ==\n LibFacetStorage.k1Storage().signer)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/Secp256r1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {UserOperation} from \"../../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibAppStorage} from \"../../../libraries/LibAppStorage.sol\";\nimport {LibLoupe} from \"../../../libraries/LibLoupe.sol\";\nimport {LibFacetStorage, Secp256r1VerificationStorage} from \"../../../libraries/LibFacetStorage.sol\";\nimport {Base64} from \"./utils/Base64.sol\";\nimport {LibSecp256r1} from \"./utils/LibSecp256r1.sol\";\nimport {IERC1271} from \"../../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../../interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Secp256r1 verification facet\n * @dev Primarily used to verify user ops signed with passkeys\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract Secp256r1VerificationFacet is IVerificationFacet, IERC1271 {\n error Secp256r1VerificationFacet__InvalidSignerLength();\n address public immutable self;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in R1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\n * @param _publicKey Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _publicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n\n if (!isValidKeyType(_publicKey))\n revert Secp256r1VerificationFacet__InvalidSignerLength();\n\n bytes memory publicKeyCoordinates = _publicKey[1:];\n uint256[2] memory q;\n assembly {\n // Copy the bytes from the input data into the uint256 array\n mstore(q, mload(add(publicKeyCoordinates, 32)))\n mstore(add(q, 32), mload(add(publicKeyCoordinates, 64)))\n }\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n r1Storage.q = q;\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_publicKey);\n }\n\n /**\n * @notice Uninitialize signer in R1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n r1Storage.q = [0, 0];\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\n * signer public key.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n validationData = validateSignature(userOp, userOpHash, r1Storage.q);\n }\n\n /**\n * @notice Validates if the signature of UserOperation is signed by the given signer\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @param q Public Key of signer who signed the contract, to be validated\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256[2] memory q\n ) public view returns (uint256 isValid) {\n isValid = (_validateSignature(q, userOpHash, userOp.signature)) ? 0 : 1;\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n return this.validateOwnerSignature.selector; // validateOwnerSignature(UserOperation calldata userOp,bytes32 userOpHash)\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory signer) {\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n signer = abi.encodePacked(r1Storage.q);\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key should in an uncompressed public key format\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = _validateSignature(\n LibFacetStorage.r1Storage().q,\n _hash,\n _signature\n )\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n\n function _validateSignature(\n uint256[2] memory q,\n bytes32 _hash,\n bytes memory _signature\n ) internal view returns (bool) {\n (\n uint256 rValue,\n uint256 sValue,\n bytes memory authenticatorData,\n string memory clientDataJSONPre,\n string memory clientDataJSONPost\n ) = abi.decode(_signature, (uint256, uint256, bytes, string, string));\n bytes32 clientHash;\n {\n string memory opHashBase64 = Base64.encode(bytes.concat(_hash));\n string memory clientDataJSON = string.concat(\n clientDataJSONPre,\n opHashBase64,\n clientDataJSONPost\n );\n clientHash = sha256(bytes(clientDataJSON));\n }\n bytes32 sigHash = sha256(bytes.concat(authenticatorData, clientHash));\n return LibSecp256r1.Verify(q, rValue, sValue, uint256(sigHash));\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/utils/Base64.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @dev Provides a set of functions to operate with Base64 strings.\n * modified for base64url https://datatracker.ietf.org/doc/html/rfc4648#section-5\n * _Available since v4.5._\n */\nlibrary Base64 {\n /**\n * @dev Base64 Encoding/Decoding Table\n */\n string internal constant _TABLE =\n \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_\";\n\n /**\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\n */\n function encode(bytes memory data) internal pure returns (string memory) {\n /**\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\n */\n if (data.length == 0) return \"\";\n\n // Loads the table into memory\n string memory table = _TABLE;\n\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\n // and split into 4 numbers of 6 bits.\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\n // - `data.length + 2` -> Round up\n // - `/ 3` -> Number of 3-bytes chunks\n // - `4 *` -> 4 characters for each chunk\n uint256 newlength = (data.length * 8) / 6;\n if (data.length % 6 > 0) {\n newlength++;\n }\n string memory result = new string(newlength);\n\n /// @solidity memory-safe-assembly\n assembly {\n // Prepare the lookup table (skip the first \"length\" byte)\n let tablePtr := add(table, 1)\n\n // Prepare result pointer, jump over length\n let resultPtr := add(result, 32)\n\n // Run over the input, 3 bytes at a time\n for {\n let dataPtr := data\n let endPtr := add(data, mload(data))\n } lt(dataPtr, endPtr) {\n\n } {\n // Advance 3 bytes\n dataPtr := add(dataPtr, 3)\n let input := mload(dataPtr)\n\n // To write each character, shift the 3 bytes (18 bits) chunk\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\n // and apply logical AND with 0x3F which is the number of\n // the previous character in the ASCII table prior to the Base64 Table\n // The result is then added to the table to get the character to write,\n // and finally write it in the result pointer but with a left shift\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(18, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(12, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(6, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n }\n }\n\n return result;\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/utils/LibSecp256r1.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n// Heavily inspired from\n// https://github.com/maxrobot/elliptic-solidity/blob/master/contracts/Secp256r1.sol\n// https://github.com/tdrerup/elliptic-curve-solidity/blob/master/contracts/curves/EllipticCurve.sol\n// modified to use precompile 0x05 modexp\n// and modified jacobian double\n// optimisations to avoid to an from from affine and jacobian coordinates\n\n// Additional Elliptic curve Public key / Signature validation added by\n// David Yonjun Kim (@Powerstream3604)\n\nstruct JPoint {\n uint256 x;\n uint256 y;\n uint256 z;\n}\n\nlibrary LibSecp256r1 {\n uint256 constant gx =\n 0x6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296;\n uint256 constant gy =\n 0x4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5;\n uint256 public constant pp =\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF;\n\n uint256 public constant nn =\n 0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551;\n uint256 constant a =\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC;\n uint256 constant b =\n 0x5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B;\n uint256 constant MOST_SIGNIFICANT =\n 0xc000000000000000000000000000000000000000000000000000000000000000;\n\n /*\n * Verify\n * @description - verifies that a public key has signed a given message\n * @param Q - public key coordinates X & Y\n * @param R - signature half R\n * @param S - signature half S\n * @param input - hashed message\n */\n function Verify(\n uint256[2] memory q,\n uint r,\n uint s,\n uint e\n ) internal view returns (bool) {\n if (q[0] > pp - 1 || q[1] > pp - 1) {\n return false;\n }\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\n return false;\n }\n if (\n mulmod(q[1], q[1], pp) !=\n addmod(\n addmod(\n mulmod(q[0], mulmod(q[0], q[0], pp), pp),\n mulmod(a, q[0], pp),\n pp\n ),\n b,\n pp\n )\n ) {\n return false;\n }\n\n JPoint[16] memory points = _preComputeJacobianPoints(q);\n return VerifyWithPrecompute(points, r, s, e);\n }\n\n function VerifyWithPrecompute(\n JPoint[16] memory points,\n uint r,\n uint s,\n uint e\n ) internal view returns (bool) {\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\n return false;\n }\n\n uint w = _primemod(s, nn);\n\n uint u1 = mulmod(e, w, nn);\n uint u2 = mulmod(r, w, nn);\n\n uint x;\n uint y;\n\n (x, y) = ShamirMultJacobian(points, u1, u2);\n return (x == r);\n }\n\n /*\n * Strauss Shamir trick for EC multiplication\n * https://stackoverflow.com/questions/50993471/ec-scalar-multiplication-with-strauss-shamir-method\n * we optimise on this a bit to do with 2 bits at a time rather than a single bit\n * the individual points for a single pass are precomputed\n * overall this reduces the number of additions while keeping the same number of doublings\n */\n function ShamirMultJacobian(\n JPoint[16] memory points,\n uint u1,\n uint u2\n ) internal view returns (uint, uint) {\n uint x = 0;\n uint y = 0;\n uint z = 0;\n uint bits = 128;\n uint index = 0;\n\n while (bits > 0) {\n if (z > 0) {\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\n }\n index =\n ((u1 & MOST_SIGNIFICANT) >> 252) |\n ((u2 & MOST_SIGNIFICANT) >> 254);\n if (index > 0) {\n (x, y, z) = _jAdd(\n x,\n y,\n z,\n points[index].x,\n points[index].y,\n points[index].z\n );\n }\n u1 <<= 2;\n u2 <<= 2;\n bits--;\n }\n (x, y) = _affineFromJacobian(x, y, z);\n return (x, y);\n }\n\n function _preComputeJacobianPoints(\n uint256[2] memory q\n ) internal pure returns (JPoint[16] memory points) {\n points[0] = JPoint(0, 0, 0);\n points[1] = JPoint(q[0], q[1], 1); // u2\n points[2] = _jPointDouble(points[1]);\n points[3] = _jPointAdd(points[1], points[2]);\n\n points[4] = JPoint(gx, gy, 1); // u1Points[1]\n points[5] = _jPointAdd(points[4], points[1]);\n points[6] = _jPointAdd(points[4], points[2]);\n points[7] = _jPointAdd(points[4], points[3]);\n\n points[8] = _jPointDouble(points[4]); // u1Points[2]\n points[9] = _jPointAdd(points[8], points[1]);\n points[10] = _jPointAdd(points[8], points[2]);\n points[11] = _jPointAdd(points[8], points[3]);\n\n points[12] = _jPointAdd(points[4], points[8]); // u1Points[3]\n points[13] = _jPointAdd(points[12], points[1]);\n points[14] = _jPointAdd(points[12], points[2]);\n points[15] = _jPointAdd(points[12], points[3]);\n }\n\n function _jPointAdd(\n JPoint memory p1,\n JPoint memory p2\n ) internal pure returns (JPoint memory) {\n uint x;\n uint y;\n uint z;\n (x, y, z) = _jAdd(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z);\n return JPoint(x, y, z);\n }\n\n function _jPointDouble(\n JPoint memory p\n ) internal pure returns (JPoint memory) {\n uint x;\n uint y;\n uint z;\n (x, y, z) = _modifiedJacobianDouble(p.x, p.y, p.z);\n return JPoint(x, y, z);\n }\n\n /* _affineFromJacobian\n * @desription returns affine coordinates from a jacobian input follows\n * golang elliptic/crypto library\n */\n function _affineFromJacobian(\n uint x,\n uint y,\n uint z\n ) internal view returns (uint ax, uint ay) {\n if (z == 0) {\n return (0, 0);\n }\n\n uint zinv = _primemod(z, pp);\n uint zinvsq = mulmod(zinv, zinv, pp);\n\n ax = mulmod(x, zinvsq, pp);\n ay = mulmod(y, mulmod(zinvsq, zinv, pp), pp);\n }\n\n /*\n * _jAdd\n * @description performs Jacobian addition as defined below:\n * http://www.hyperelliptic.org/EFD/g1p/data/shortw/jacobian/addition/add-2007-bl\n */\n function _jAdd(\n uint p1,\n uint p2,\n uint p3,\n uint q1,\n uint q2,\n uint q3\n ) internal pure returns (uint r1, uint r2, uint r3) {\n if (p3 == 0) {\n r1 = q1;\n r2 = q2;\n r3 = q3;\n\n return (r1, r2, r3);\n } else if (q3 == 0) {\n r1 = p1;\n r2 = p2;\n r3 = p3;\n\n return (r1, r2, r3);\n }\n\n assembly {\n let\n pd\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\n let z1z1 := mulmod(p3, p3, pd) // Z1Z1 = Z1^2\n let z2z2 := mulmod(q3, q3, pd) // Z2Z2 = Z2^2\n\n let u1 := mulmod(p1, z2z2, pd) // U1 = X1*Z2Z2\n let u2 := mulmod(q1, z1z1, pd) // U2 = X2*Z1Z1\n\n let s1 := mulmod(p2, mulmod(z2z2, q3, pd), pd) // S1 = Y1*Z2*Z2Z2\n let s2 := mulmod(q2, mulmod(z1z1, p3, pd), pd) // S2 = Y2*Z1*Z1Z1\n\n let p3q3 := addmod(p3, q3, pd)\n\n if lt(u2, u1) {\n u2 := add(pd, u2) // u2 = u2+pd\n }\n let h := sub(u2, u1) // H = U2-U1\n\n let i := mulmod(0x02, h, pd)\n i := mulmod(i, i, pd) // I = (2*H)^2\n\n let j := mulmod(h, i, pd) // J = H*I\n if lt(s2, s1) {\n s2 := add(pd, s2) // u2 = u2+pd\n }\n let rr := mulmod(0x02, sub(s2, s1), pd) // r = 2*(S2-S1)\n r1 := mulmod(rr, rr, pd) // X3 = R^2\n\n let v := mulmod(u1, i, pd) // V = U1*I\n let j2v := addmod(j, mulmod(0x02, v, pd), pd)\n if lt(r1, j2v) {\n r1 := add(pd, r1) // X3 = X3+pd\n }\n r1 := sub(r1, j2v)\n\n // Y3 = r*(V-X3)-2*S1*J\n let s12j := mulmod(mulmod(0x02, s1, pd), j, pd)\n\n if lt(v, r1) {\n v := add(pd, v)\n }\n r2 := mulmod(rr, sub(v, r1), pd)\n\n if lt(r2, s12j) {\n r2 := add(pd, r2)\n }\n r2 := sub(r2, s12j)\n\n // Z3 = ((Z1+Z2)^2-Z1Z1-Z2Z2)*H\n z1z1 := addmod(z1z1, z2z2, pd)\n j2v := mulmod(p3q3, p3q3, pd)\n if lt(j2v, z1z1) {\n j2v := add(pd, j2v)\n }\n r3 := mulmod(sub(j2v, z1z1), h, pd)\n }\n return (r1, r2, r3);\n }\n\n // Point doubling on the modified jacobian coordinates\n // http://point-at-infinity.org/ecc/Prime_Curve_Modified_Jacobian_Coordinates.html\n function _modifiedJacobianDouble(\n uint x,\n uint y,\n uint z\n ) internal pure returns (uint x3, uint y3, uint z3) {\n if (y == 0) return (0, 0, 0);\n assembly {\n let\n pd\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\n let z2 := mulmod(z, z, pd)\n let az4 := mulmod(\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC,\n mulmod(z2, z2, pd),\n pd\n )\n let y2 := mulmod(y, y, pd)\n let s := mulmod(0x04, mulmod(x, y2, pd), pd)\n let u := mulmod(0x08, mulmod(y2, y2, pd), pd)\n let m := addmod(mulmod(0x03, mulmod(x, x, pd), pd), az4, pd)\n let twos := mulmod(0x02, s, pd)\n let m2 := mulmod(m, m, pd)\n if lt(m2, twos) {\n m2 := add(pd, m2)\n }\n x3 := sub(m2, twos)\n if lt(s, x3) {\n s := add(pd, s)\n }\n y3 := mulmod(m, sub(s, x3), pd)\n if lt(y3, u) {\n y3 := add(pd, y3)\n }\n y3 := sub(y3, u)\n z3 := mulmod(0x02, mulmod(y, z, pd), pd)\n }\n }\n\n // Fermats little theorem https://en.wikipedia.org/wiki/Fermat%27s_little_theorem\n // a^(p-1) = 1 mod p\n // a^(-1) ≅ a^(p-2) (mod p)\n // we then use the precompile bigModExp to compute a^(-1)\n function _primemod(uint value, uint p) internal view returns (uint ret) {\n ret = modexp(value, p - 2, p);\n return ret;\n }\n\n // Wrapper for built-in BigNumber_modexp (contract 0x5) as described here. https://github.com/ethereum/EIPs/pull/198\n function modexp(\n uint _base,\n uint _exp,\n uint _mod\n ) internal view returns (uint ret) {\n // bigModExp(_base, _exp, _mod);\n assembly {\n if gt(_base, _mod) {\n _base := mod(_base, _mod)\n }\n // Free memory pointer is always stored at 0x40\n let freemem := mload(0x40)\n\n mstore(freemem, 0x20)\n mstore(add(freemem, 0x20), 0x20)\n mstore(add(freemem, 0x40), 0x20)\n\n mstore(add(freemem, 0x60), _base)\n mstore(add(freemem, 0x80), _exp)\n mstore(add(freemem, 0xa0), _mod)\n\n let success := staticcall(14000, 0x5, freemem, 0xc0, freemem, 0x20)\n switch success\n case 0 {\n revert(0x0, 0x0)\n }\n default {\n ret := mload(freemem)\n }\n }\n }\n}\n" + }, + "contracts/infrastructure/DefaultFallbackHandler.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC1155Receiver} from \"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\";\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {BaseAccount} from \"../aa-4337/core/BaseAccount.sol\";\nimport {DefaultLibDiamond} from \"../libraries/DefaultLibDiamond.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IAccountFacet} from \"../facets/interfaces/IAccountFacet.sol\";\nimport {IStorageLoupe} from \"../facets/base/interfaces/IStorageLoupe.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IERC677Receiver} from \"../interfaces/ERC/IERC677Receiver.sol\";\nimport {IERC165} from \"../interfaces/ERC/IERC165.sol\";\n\n/**\n * @title DefaultFallbackHandler\n * @dev A default fallback handler for Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DefaultFallbackHandler is IDiamondLoupe {\n /**\n * @notice Sets the middleware diamond for Barz wallet as a fallback handler\n * @dev This contract is also a diamond that holds the default facets to reduce gas cost for wallet activation.\n * Within the constructor this conducts diamond cut to initially setup the diamond. This is a non-upgradeable contract\n * @param _diamondCutFacet Address if diamond cut facet\n * @param _accountFacet Address account facet\n * @param _tokenReceiverFacet Address of token receiver facet\n * @param _diamondLoupeFacet Address of diamond loupe facet\n */\n constructor(\n address _diamondCutFacet,\n address _accountFacet,\n address _tokenReceiverFacet,\n address _diamondLoupeFacet\n ) payable {\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](4);\n bytes4[] memory functionSelectors = new bytes4[](1);\n functionSelectors[0] = IDiamondCut.diamondCut.selector;\n\n bytes4[] memory accountFunctionSelectors = new bytes4[](5);\n accountFunctionSelectors[0] = IAccountFacet.execute.selector;\n accountFunctionSelectors[1] = IAccountFacet.executeBatch.selector;\n accountFunctionSelectors[2] = BaseAccount.validateUserOp.selector;\n accountFunctionSelectors[3] = BaseAccount.getNonce.selector;\n accountFunctionSelectors[4] = BaseAccount.entryPoint.selector;\n\n bytes4[] memory receiverFacetSelectors = new bytes4[](5);\n receiverFacetSelectors[0] = IERC721Receiver.onERC721Received.selector;\n receiverFacetSelectors[1] = IERC1155Receiver.onERC1155Received.selector;\n receiverFacetSelectors[2] = IERC1155Receiver\n .onERC1155BatchReceived\n .selector;\n receiverFacetSelectors[3] = IERC777Recipient.tokensReceived.selector;\n receiverFacetSelectors[4] = IERC677Receiver.onTokenTransfer.selector;\n\n bytes4[] memory loupeFacetSelectors = new bytes4[](9);\n loupeFacetSelectors[0] = IDiamondLoupe.facets.selector;\n loupeFacetSelectors[1] = IDiamondLoupe.facetFunctionSelectors.selector;\n loupeFacetSelectors[2] = IDiamondLoupe.facetAddresses.selector;\n loupeFacetSelectors[3] = IDiamondLoupe.facetAddress.selector;\n loupeFacetSelectors[4] = IERC165.supportsInterface.selector;\n loupeFacetSelectors[5] = IStorageLoupe.facetsFromStorage.selector;\n loupeFacetSelectors[6] = IStorageLoupe\n .facetFunctionSelectorsFromStorage\n .selector;\n loupeFacetSelectors[7] = IStorageLoupe\n .facetAddressesFromStorage\n .selector;\n loupeFacetSelectors[8] = IStorageLoupe.facetAddressFromStorage.selector;\n\n {\n cut[0] = IDiamondCut.FacetCut({\n facetAddress: _diamondCutFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: functionSelectors\n });\n cut[1] = IDiamondCut.FacetCut({\n facetAddress: _accountFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: accountFunctionSelectors\n });\n cut[2] = IDiamondCut.FacetCut({\n facetAddress: _tokenReceiverFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: receiverFacetSelectors\n });\n cut[3] = IDiamondCut.FacetCut({\n facetAddress: _diamondLoupeFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: loupeFacetSelectors\n });\n\n DefaultLibDiamond.diamondCut(cut, address(0), \"\");\n }\n }\n\n /**\n * @notice Returns the facet information of call facets registered to this diamond.\n * @return facets_ The facet struct array including all facet information\n */\n function facets() external view override returns (Facet[] memory facets_) {\n DefaultLibDiamond.DiamondStorage storage ds = DefaultLibDiamond\n .diamondStorage();\n uint256 numFacets = ds.facetAddresses.length;\n facets_ = new Facet[](numFacets);\n for (uint256 i; i < numFacets; ) {\n address facetAddress_ = ds.facetAddresses[i];\n facets_[i].facetAddress = facetAddress_;\n facets_[i].functionSelectors = ds\n .facetFunctionSelectors[facetAddress_]\n .functionSelectors;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Gets all the function selectors provided by a facet.\n * @param _facet The facet address.\n * @return facetFunctionSelectors_\n */\n function facetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n facetFunctionSelectors_ = DefaultLibDiamond\n .diamondStorage()\n .facetFunctionSelectors[_facet]\n .functionSelectors;\n }\n\n /**\n * @notice Get all the facet addresses used by a diamond.\n * @return facetAddresses_\n */\n function facetAddresses()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n facetAddresses_ = DefaultLibDiamond.diamondStorage().facetAddresses;\n }\n\n /** @notice Gets the facet that supports the given selector.\n * @dev If facet is not found return address(0).\n * @param _functionSelector The function selector.\n * @return facetAddress_ The facet address.\n */\n function facetAddress(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n facetAddress_ = DefaultLibDiamond\n .diamondStorage()\n .selectorToFacetAndPosition[_functionSelector]\n .facetAddress;\n }\n}\n" + }, + "contracts/infrastructure/FacetRegistry.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport {IFacetRegistry} from \"./interfaces/IFacetRegistry.sol\";\n\n/**\n * @title Facet Registry\n * @dev Contract to keep track of facets & function selectors addable to user wallets\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract FacetRegistry is IFacetRegistry, Ownable2Step {\n mapping(address => FacetRegistryConfig) private facets;\n\n /**\n * @notice Transfers the ownership of the contract to the given owner\n * @param _owner Address of owner who has access to initialize the default security variables for security manager\n */\n constructor(address _owner) {\n transferOwnership(_owner);\n _transferOwnership(_owner);\n }\n\n /**\n * @dev Registers a facet and it's function selectors to registry\n * @param _facet address of facet\n * @param _facetSelectors list of function selectors of the facet\n */\n function registerFacetFunctionSelectors(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external override onlyOwner {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n for (uint256 i; i < _facetSelectors.length; ) {\n if (facetConfig.info[_facetSelectors[i]].exists)\n revert FacetRegistry__FacetSelectorAlreadyRegistered();\n\n facetConfig.info[_facetSelectors[i]].exists = true;\n facetConfig.info[_facetSelectors[i]].index = uint128(\n facetConfig.selectors.length\n );\n facetConfig.selectors.push(_facetSelectors[i]);\n unchecked {\n ++i;\n }\n }\n emit FacetFunctionSelectorsRegistered(_facet, _facetSelectors);\n }\n\n /**\n * @dev Removes a registered facet and it's corresponding selectors from registry\n * @param _facet address of facet\n * @param _facetSelectors list of function selectors of the facet\n */\n function removeFacetFunctionSelectors(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external override onlyOwner {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n for (uint256 i; i < _facetSelectors.length; ) {\n if (!facetConfig.info[_facetSelectors[i]].exists)\n revert FacetRegistry__UnregisteredFacetSelector();\n\n bytes4 lastSelector = facetConfig.selectors[\n facetConfig.selectors.length - 1\n ];\n if (_facetSelectors[i] != lastSelector) {\n uint128 targetIndex = facetConfig\n .info[_facetSelectors[i]]\n .index;\n facetConfig.selectors[targetIndex] = lastSelector;\n facetConfig.info[lastSelector].index = targetIndex;\n }\n facetConfig.selectors.pop();\n delete facetConfig.info[_facetSelectors[i]];\n\n unchecked {\n ++i;\n }\n }\n emit FacetFunctionSelectorsRemoved(_facet, _facetSelectors);\n }\n\n /**\n * @dev Checks if a facet and it's selectors given is registered to facet registry\n * @param _facet Address of facet\n * @param _facetSelectors List of function selectors of the facet\n */\n function areFacetFunctionSelectorsRegistered(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external view override returns (bool) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n if (_facetSelectors.length == 0) return false;\n for (uint256 i; i < _facetSelectors.length; ) {\n if (!facetConfig.info[_facetSelectors[i]].exists) return false;\n unchecked {\n ++i;\n }\n }\n return true;\n }\n\n /**\n * @dev Checks if a facet and it's selector given is registered to facet registry\n * @param _facet Address of facet\n * @param _facetSelector List of function selectors of the facet\n * @return isRegistered Bool value showing if the selector is registered\n */\n function isFacetFunctionSelectorRegistered(\n address _facet,\n bytes4 _facetSelector\n ) external view override returns (bool isRegistered) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n isRegistered = facetConfig.info[_facetSelector].exists;\n }\n\n /**\n * @dev Get the registered selectors of facet from registry\n * @param _facet Address of facet\n * @return selectors Selectors registered to facet\n */\n function getFacetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory selectors) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n selectors = facetConfig.selectors;\n }\n}\n" + }, + "contracts/infrastructure/interfaces/IFacetRegistry.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Registry Interface\n * @dev Interface for Facet Registry contract to keep track of facets & function selectors addable to user wallets\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IFacetRegistry {\n struct FacetRegistryConfig {\n bytes4[] selectors;\n mapping(bytes4 => FacetInfo) info;\n }\n struct FacetInfo {\n bool exists;\n uint128 index;\n }\n\n event FacetFunctionSelectorsRegistered(\n address facet,\n bytes4[] facetSelectors\n );\n event FacetFunctionSelectorsRemoved(address facet, bytes4[] facetSelectors);\n\n error FacetRegistry__FacetSelectorAlreadyRegistered();\n error FacetRegistry__UnregisteredFacetSelector();\n\n function registerFacetFunctionSelectors(\n address facet,\n bytes4[] calldata facetSelectors\n ) external;\n\n function removeFacetFunctionSelectors(\n address facet,\n bytes4[] calldata facetSelectors\n ) external;\n\n function areFacetFunctionSelectorsRegistered(\n address facet,\n bytes4[] calldata facetSelectors\n ) external view returns (bool);\n\n function isFacetFunctionSelectorRegistered(\n address facet,\n bytes4 facetSelector\n ) external view returns (bool);\n\n function getFacetFunctionSelectors(\n address facet\n ) external view returns (bytes4[] memory);\n}\n" + }, + "contracts/infrastructure/interfaces/ISecurityManager.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Registry Interface\n * @dev Infrastructure contract to manage security parameters of users\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface ISecurityManager {\n error SecurityManager__OutOfBoundary();\n error SecurityManager__CallerNotWallet();\n error SecurityManager__AlreadyIntialized();\n\n function initializeAdditionSecurityPeriod(\n uint128 defaultAdditionSecurityPeriod,\n uint128 minAdditionSecurityPeriod,\n uint128 maxAdditionSecurityPeriod\n ) external;\n\n function initializeRemovalSecurityPeriod(\n uint128 defaultRemovalSecurityPeriod,\n uint128 minRemovalSecurityPeriod,\n uint128 maxRemovalSecurityPeriod\n ) external;\n\n function initializeApprovalValidationPeriod(\n uint128 defaultApprovalValidationPeriod,\n uint128 minApprovalValidationPeriod,\n uint128 maxApprovalValidationPeriod\n ) external;\n\n function initializeMigrationPeriod(\n uint128 defaultMigrationPeriod,\n uint128 minMigrationPeriod,\n uint128 maxMigrationPeriod\n ) external;\n\n function initializeLockPeriod(\n uint128 defaultLockPeriod,\n uint128 minLockPeriod,\n uint128 maxLockPeriod\n ) external;\n\n function initializeRecoveryPeriod(\n uint128 defaultRecoveryPeriod,\n uint128 minRecoveryPeriod,\n uint128 maxRecoveryPeriod\n ) external;\n\n function initializeSecurityWindow(\n uint128 defaultSecurityWindow,\n uint128 minSecurityWindow,\n uint128 maxSecurityWindow\n ) external;\n\n function setAdditionSecurityPeriod(\n address wallet,\n uint128 additionSecurityPeriod\n ) external;\n\n function setRemovalSecurityPeriod(\n address wallet,\n uint128 removalSecurityPeriod\n ) external;\n\n function setSecurityWindow(address wallet, uint128 securityWindow) external;\n\n function setRecoveryPeriod(address wallet, uint128 recoveryPeriod) external;\n\n function setLockPeriod(address wallet, uint128 lockPeriod) external;\n\n function setApprovalValidationPeriod(\n address wallet,\n uint128 approvalValidationPeriod\n ) external;\n\n function setMigrationPeriod(\n address wallet,\n uint128 migrationPeriod\n ) external;\n\n function additionSecurityPeriodOf(\n address wallet\n ) external view returns (uint128);\n\n function removalSecurityPeriodOf(\n address wallet\n ) external view returns (uint128);\n\n function securityWindowOf(address wallet) external view returns (uint128);\n\n function recoveryPeriodOf(address wallet) external view returns (uint128);\n\n function lockPeriodOf(address wallet) external view returns (uint128);\n\n function migrationPeriodOf(address wallet) external view returns (uint128);\n\n function approvalValidationPeriodOf(\n address wallet\n ) external view returns (uint128);\n}\n" + }, + "contracts/infrastructure/RemoteStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IGuardianFacet} from \"../facets/interfaces/IGuardianFacet.sol\";\n\n/**\n * @title Remote Storage\n * @dev Remote storage allows you to associate addresses with an array of addresses on a standalone smart contract.\n * This could be useful when you don't want to use the local diamond storage for some purpose.\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\nabstract contract RemoteStorage {\n struct StorageConfig {\n address[] addresses;\n mapping(address => Info) info;\n }\n\n struct Info {\n bool exists;\n uint128 index;\n }\n\n mapping(address => StorageConfig) internal configs;\n\n event Added(address _address);\n event Removed(address _address);\n\n error RemoteStorage__CallerNotOwner();\n error RemoteStorage__CallerNotGuardianOrOwner();\n error RemoteStorage__AlreadyExists();\n error RemoteStorage__NotFound();\n error RemoteStorage__CallerNotGuardian();\n\n bytes4 constant IS_GUARDIAN_SELECTOR =\n bytes4(keccak256(\"isGuardian(address)\"));\n bytes4 constant GUARDIAN_COUNT = bytes4(keccak256(\"guardianCount()\"));\n\n /**\n * @notice Modifier to only allow the self to call. Reverts otherwise\n */\n modifier onlyWallet(address _wallet) {\n if (msg.sender != _wallet) revert RemoteStorage__CallerNotOwner();\n _;\n }\n\n /**\n * @notice Enfore the callet to be wallet of guardian of the wallet\n * @param _wallet Address of wallet\n */\n function enforceGuardianOrWallet(address _wallet) internal view {\n if (msg.sender == _wallet) return;\n address facetAddress = IDiamondLoupe(_wallet).facetAddress(\n IS_GUARDIAN_SELECTOR\n );\n if (facetAddress != address(0))\n if (IGuardianFacet(_wallet).isGuardian(msg.sender)) return;\n revert RemoteStorage__CallerNotGuardianOrOwner();\n }\n\n /**\n * @notice Enforce the caller to be wallet IF guardians doesn't exists and only guardian when guardians exists\n * @param _wallet Target wallet address to be handled by infrastructure contracts\n */\n function enforceWalletOrGuardianIfExists(address _wallet) internal view {\n address facetAddress;\n if (msg.sender == _wallet) {\n facetAddress = IDiamondLoupe(_wallet).facetAddress(GUARDIAN_COUNT);\n if (facetAddress == address(0)) return;\n uint256 guardianCount = IGuardianFacet(_wallet).guardianCount();\n if (guardianCount != 0) revert RemoteStorage__CallerNotGuardian();\n return;\n }\n facetAddress = IDiamondLoupe(_wallet).facetAddress(\n IS_GUARDIAN_SELECTOR\n );\n if (facetAddress != address(0))\n if (IGuardianFacet(_wallet).isGuardian(msg.sender)) return;\n\n revert RemoteStorage__CallerNotGuardianOrOwner();\n }\n\n /**\n * @notice Add address to storage and reverts if the address already exists.\n * This is an internal function callable from contracts that inherit this abstract contract\n * @param _wallet Address of wallet to add the address\n * @param _address Address to be added to wallet\n */\n function addAddress(address _wallet, address _address) internal {\n StorageConfig storage config = configs[_wallet];\n if (config.info[_address].exists) revert RemoteStorage__AlreadyExists();\n\n config.info[_address].exists = true;\n config.info[_address].index = uint128(config.addresses.length);\n config.addresses.push(_address);\n\n emit Added(_address);\n }\n\n /**\n * @notice Remove address from storage and reverts if the address already exists.\n * This is an internal function callable from contracts that inherit this abstract contract\n * @param _wallet Address of wallet to remove the address\n * @param _address Address to be removed from wallet\n */\n function removeAddress(address _wallet, address _address) internal {\n StorageConfig storage config = configs[_wallet];\n if (!config.info[_address].exists) revert RemoteStorage__NotFound();\n\n address lastAddress = config.addresses[config.addresses.length - 1];\n if (_address != lastAddress) {\n uint128 targetIndex = config.info[_address].index;\n config.addresses[targetIndex] = lastAddress;\n config.info[lastAddress].index = targetIndex;\n }\n config.addresses.pop();\n delete config.info[_address];\n\n emit Removed(_address);\n }\n\n /**\n * @notice Returns the address added to the given wallet\n * @param _wallet Address of wallet to fetch the addresses added to it\n * @return addresses List of addresses added to the wallet\n */\n function getAddresses(\n address _wallet\n ) internal view returns (address[] memory addresses) {\n StorageConfig storage config = configs[_wallet];\n addresses = new address[](config.addresses.length);\n uint addressesLen = config.addresses.length;\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns bool value checking if the address exists in the given wallet address\n * @param _wallet Wallet address to check\n * @param _address Address to fetch if the address if added to given wallet\n * @return exists_ Bool value showing if the address exists in wallet\n */\n function exists(\n address _wallet,\n address _address\n ) internal view returns (bool exists_) {\n exists_ = configs[_wallet].info[_address].exists;\n }\n\n /**\n * @notice Returns the number of addresses added to the wallet\n * @param _wallet Address of wallet to check\n * @return count_ Number of addresses added to wallet\n */\n function count(address _wallet) internal view returns (uint256 count_) {\n count_ = configs[_wallet].addresses.length;\n }\n}\n" + }, + "contracts/infrastructure/SecurityManager.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport {ISecurityManager} from \"./interfaces/ISecurityManager.sol\";\n\n/**\n * @title Security Manager\n * @dev Infrastructure contract to manage security parameters of users\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract SecurityManager is ISecurityManager, Ownable2Step {\n uint128 public minAdditionSecurityPeriod;\n uint128 public maxAdditionSecurityPeriod;\n uint128 private defaultAdditionSecurityPeriod;\n\n uint128 public minRemovalSecurityPeriod;\n uint128 public maxRemovalSecurityPeriod;\n uint128 private defaultRemovalSecurityPeriod;\n\n uint128 public minSecurityWindow;\n uint128 public maxSecurityWindow;\n uint128 private defaultSecurityWindow;\n\n uint128 public minRecoveryPeriod;\n uint128 public maxRecoveryPeriod;\n uint128 private defaultRecoveryPeriod;\n\n uint128 public minLockPeriod;\n uint128 public maxLockPeriod;\n uint128 private defaultLockPeriod;\n\n uint128 public minApprovalValidationPeriod;\n uint128 public maxApprovalValidationPeriod;\n uint128 private defaultApprovalValidationPeriod;\n\n uint128 public minMigrationPeriod;\n uint128 public maxMigrationPeriod;\n uint128 private defaultMigrationPeriod;\n\n bool public _isAdditionSecurityPeriodInitialized;\n bool public _isRemovalSecurityPeriodInitialized;\n bool public _isSecurityWindowInitialized;\n bool public _isRecoveryPeriodInitialized;\n bool public _isLockPeriodInitialized;\n bool public _isApprovalValidationPeriodInitialized;\n bool public _isMigrationPeriodInitialized;\n\n mapping(address => CustomSecurityConfig) securityConfigs;\n\n struct CustomSecurityConfig {\n uint128 additionSecurityPeriod;\n uint128 removalSecurityPeriod;\n uint128 securityWindow;\n uint128 recoveryPeriod;\n uint128 lockPeriod;\n uint128 approvalValidationPeriod;\n uint128 migrationPeriod;\n }\n\n /**\n * @notice Modifier to only allow wallet itself to make a call to wallet\n */\n modifier onlyWallet(address _wallet) {\n if (msg.sender != _wallet) revert SecurityManager__CallerNotWallet();\n _;\n }\n\n /**\n * @notice Modifier to revert if the variable is already initialized\n */\n modifier initializer(bool _isInitialized) {\n if (_isInitialized) revert SecurityManager__AlreadyIntialized();\n _;\n }\n\n /**\n * @notice Transfers the ownership of the contract to the given owner\n * @param _owner Address of owner who has access to initialize the default security variables for security manager\n */\n constructor(address _owner) {\n transferOwnership(_owner);\n _transferOwnership(_owner);\n }\n\n /**\n * @notice Sets the initial default/min/max addition security period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultAdditionSecurityPeriod Default Addition Security Period for all Barz contracts\n * @param _minAdditionSecurityPeriod Minimum Addition Security Period for all Barz contracts\n * @param _maxAdditionSecurityPeriod Maximum Addition Security Period for all Barz contracts\n */\n function initializeAdditionSecurityPeriod(\n uint128 _defaultAdditionSecurityPeriod,\n uint128 _minAdditionSecurityPeriod,\n uint128 _maxAdditionSecurityPeriod\n )\n external\n override\n onlyOwner\n initializer(_isAdditionSecurityPeriodInitialized)\n {\n _isAdditionSecurityPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultAdditionSecurityPeriod,\n _minAdditionSecurityPeriod,\n _maxAdditionSecurityPeriod\n );\n defaultAdditionSecurityPeriod = _defaultAdditionSecurityPeriod;\n minAdditionSecurityPeriod = _minAdditionSecurityPeriod;\n maxAdditionSecurityPeriod = _maxAdditionSecurityPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max removal security period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultRemovalSecurityPeriod Default Removal Security Period for all Barz contracts\n * @param _minRemovalSecurityPeriod Minimum Removal Security Period for all Barz contracts\n * @param _maxRemovalSecurityPeriod Maximum Removal Security Period for all Barz contracts\n */\n function initializeRemovalSecurityPeriod(\n uint128 _defaultRemovalSecurityPeriod,\n uint128 _minRemovalSecurityPeriod,\n uint128 _maxRemovalSecurityPeriod\n )\n external\n override\n onlyOwner\n initializer(_isRemovalSecurityPeriodInitialized)\n {\n _isRemovalSecurityPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultRemovalSecurityPeriod,\n _minRemovalSecurityPeriod,\n _maxRemovalSecurityPeriod\n );\n defaultRemovalSecurityPeriod = _defaultRemovalSecurityPeriod;\n minRemovalSecurityPeriod = _minRemovalSecurityPeriod;\n maxRemovalSecurityPeriod = _maxRemovalSecurityPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/maxd security window for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultSecurityWindow Default Security Window for all Barz contracts\n * @param _minSecurityWindow Minimum Security Window for all Barz contracts\n * @param _maxSecurityWindow Maximum Security Window for all Barz contracts\n */\n function initializeSecurityWindow(\n uint128 _defaultSecurityWindow,\n uint128 _minSecurityWindow,\n uint128 _maxSecurityWindow\n ) external override onlyOwner initializer(_isSecurityWindowInitialized) {\n _isSecurityWindowInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultSecurityWindow,\n _minSecurityWindow,\n _maxSecurityWindow\n );\n defaultSecurityWindow = _defaultSecurityWindow;\n minSecurityWindow = _minSecurityWindow;\n maxSecurityWindow = _maxSecurityWindow;\n }\n\n /**\n * @notice Sets the initial default/min/max recovery period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultRecoveryPeriod Default Recovery Period for all Barz contracts\n * @param _minRecoveryPeriod Minimum Recovery Period for all Barz contracts\n * @param _maxRecoveryPeriod Maximum Recovery Period for all Barz contracts\n */\n function initializeRecoveryPeriod(\n uint128 _defaultRecoveryPeriod,\n uint128 _minRecoveryPeriod,\n uint128 _maxRecoveryPeriod\n ) external override onlyOwner initializer(_isRecoveryPeriodInitialized) {\n _isRecoveryPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultRecoveryPeriod,\n _minRecoveryPeriod,\n _maxRecoveryPeriod\n );\n defaultRecoveryPeriod = _defaultRecoveryPeriod;\n minRecoveryPeriod = _minRecoveryPeriod;\n maxRecoveryPeriod = _maxRecoveryPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max lock period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultLockPeriod Default Lock Period for all Barz contracts\n * @param _minLockPeriod Minimum Lock Period for all Barz contracts\n * @param _maxLockPeriod Maximum Lock Period for all Barz contracts\n */\n function initializeLockPeriod(\n uint128 _defaultLockPeriod,\n uint128 _minLockPeriod,\n uint128 _maxLockPeriod\n ) external override onlyOwner initializer(_isLockPeriodInitialized) {\n _isLockPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultLockPeriod,\n _minLockPeriod,\n _maxLockPeriod\n );\n defaultLockPeriod = _defaultLockPeriod;\n minLockPeriod = _minLockPeriod;\n maxLockPeriod = _maxLockPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max approval validation period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultApprovalValidationPeriod Default Approval Validation Period for all Barz contracts\n * @param _minApprovalValidationPeriod Minimum Approval Validation Period for all Barz contracts\n * @param _maxApprovalValidationPeriod Maximum Approval Validation Period for all Barz contracts\n */\n function initializeApprovalValidationPeriod(\n uint128 _defaultApprovalValidationPeriod,\n uint128 _minApprovalValidationPeriod,\n uint128 _maxApprovalValidationPeriod\n )\n external\n override\n onlyOwner\n initializer(_isApprovalValidationPeriodInitialized)\n {\n _isApprovalValidationPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultApprovalValidationPeriod,\n _minApprovalValidationPeriod,\n _maxApprovalValidationPeriod\n );\n defaultApprovalValidationPeriod = _defaultApprovalValidationPeriod;\n minApprovalValidationPeriod = _minApprovalValidationPeriod;\n maxApprovalValidationPeriod = _maxApprovalValidationPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max migration period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultMigrationPeriod Default Migration Period for all Barz contracts\n * @param _minMigrationPeriod Minimum Migration Period for all Barz contracts\n * @param _maxMigrationPeriod Maximum Migration Period for all Barz contracts\n */\n function initializeMigrationPeriod(\n uint128 _defaultMigrationPeriod,\n uint128 _minMigrationPeriod,\n uint128 _maxMigrationPeriod\n ) external override onlyOwner initializer(_isMigrationPeriodInitialized) {\n _isMigrationPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultMigrationPeriod,\n _minMigrationPeriod,\n _maxMigrationPeriod\n );\n defaultMigrationPeriod = _defaultMigrationPeriod;\n minMigrationPeriod = _minMigrationPeriod;\n maxMigrationPeriod = _maxMigrationPeriod;\n }\n\n /**\n * @notice Wallet owner sets the addition security period for the wallet. Only the owner of wallet can call this function.\n * The addition security period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _additionSecurityPeriod Custom Addition Security Period for the wallet\n */\n function setAdditionSecurityPeriod(\n address _wallet,\n uint128 _additionSecurityPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _additionSecurityPeriod,\n minAdditionSecurityPeriod,\n maxAdditionSecurityPeriod\n );\n securityConfigs[_wallet]\n .additionSecurityPeriod = _additionSecurityPeriod;\n }\n\n /**\n * @notice Wallet owner sets the removal security period for the wallet. Only the owner of wallet can call this function.\n * The removal security period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _removalSecurityPeriod Custom Removal Security Period for the wallet\n */\n function setRemovalSecurityPeriod(\n address _wallet,\n uint128 _removalSecurityPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _removalSecurityPeriod,\n minRemovalSecurityPeriod,\n maxRemovalSecurityPeriod\n );\n securityConfigs[_wallet].removalSecurityPeriod = _removalSecurityPeriod;\n }\n\n /**\n * @notice Wallet owner sets the security window for the wallet. Only the owner of wallet can call this function.\n * The security window should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _securityWindow Custom Security Window for the wallet\n */\n function setSecurityWindow(\n address _wallet,\n uint128 _securityWindow\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _securityWindow,\n minSecurityWindow,\n maxSecurityWindow\n );\n securityConfigs[_wallet].securityWindow = _securityWindow;\n }\n\n /**\n * @notice Wallet owner sets the recovery period for the wallet. Only the owner of wallet can call this function.\n * The recovery period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _recoveryPeriod Custom recovery period for the wallet\n */\n function setRecoveryPeriod(\n address _wallet,\n uint128 _recoveryPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _recoveryPeriod,\n minRecoveryPeriod,\n maxRecoveryPeriod\n );\n securityConfigs[_wallet].recoveryPeriod = _recoveryPeriod;\n }\n\n /**\n * @notice Wallet owner sets the lock period for the wallet. Only the owner of wallet can call this function.\n * The lock period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _lockPeriod Custom Lock period for the wallet\n */\n function setLockPeriod(\n address _wallet,\n uint128 _lockPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(_lockPeriod, minLockPeriod, maxLockPeriod);\n securityConfigs[_wallet].lockPeriod = _lockPeriod;\n }\n\n /**\n * @notice Wallet owner sets the approval validation period for the wallet. Only the owner of wallet can call this function.\n * The approval validation period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _approvalValidationPeriod Custom approval validation period for the wallet\n */\n function setApprovalValidationPeriod(\n address _wallet,\n uint128 _approvalValidationPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _approvalValidationPeriod,\n minApprovalValidationPeriod,\n maxApprovalValidationPeriod\n );\n securityConfigs[_wallet]\n .approvalValidationPeriod = _approvalValidationPeriod;\n }\n\n /**\n * @notice Wallet owner sets the migration period for the wallet. Only the owner of wallet can call this function.\n * The migration period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _migrationPeriod Custom migration period for the wallet\n */\n\n function setMigrationPeriod(\n address _wallet,\n uint128 _migrationPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _migrationPeriod,\n minMigrationPeriod,\n maxMigrationPeriod\n );\n securityConfigs[_wallet].migrationPeriod = _migrationPeriod;\n }\n\n /**\n * @notice Returns the addition security period. Returns default value when custom addition security period is not set\n * @param _wallet Address of wallet\n * @return additionSecurityPeriod Addition Security Period of the given Barz account or wallet\n */\n function additionSecurityPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 additionSecurityPeriod)\n {\n additionSecurityPeriod = securityConfigs[_wallet]\n .additionSecurityPeriod;\n additionSecurityPeriod = (additionSecurityPeriod == 0)\n ? defaultAdditionSecurityPeriod\n : additionSecurityPeriod;\n }\n\n /**\n * @notice Returns the removal security period. Returns default value when custom removal security period is not set\n * @param _wallet Address of wallet\n * @return removalSecurityPeriod Removal Security Period of the given Barz account or wallet\n */\n function removalSecurityPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 removalSecurityPeriod)\n {\n removalSecurityPeriod = securityConfigs[_wallet].removalSecurityPeriod;\n removalSecurityPeriod = (removalSecurityPeriod == 0)\n ? defaultRemovalSecurityPeriod\n : removalSecurityPeriod;\n }\n\n /**\n * @notice Returns the security window. Returns default value when custom security window is not set\n * @param _wallet Address of wallet\n * @return securityWindow Security window of the given Barz account or wallet\n */\n function securityWindowOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 securityWindow)\n {\n securityWindow = securityConfigs[_wallet].securityWindow;\n securityWindow = (securityWindow == 0)\n ? defaultSecurityWindow\n : securityWindow;\n }\n\n /**\n * @notice Returns the recovery period. Returns default value when custom recovery period is not set\n * @param _wallet Address of wallet\n * @return recoveryPeriod Recovery Period of the given Barz account or wallet\n */\n function recoveryPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 recoveryPeriod)\n {\n recoveryPeriod = securityConfigs[_wallet].recoveryPeriod;\n recoveryPeriod = (recoveryPeriod == 0)\n ? defaultRecoveryPeriod\n : recoveryPeriod;\n }\n\n /**\n * @notice Returns the lock period. Returns default value when custom lock period is not set\n * @param _wallet Address of wallet\n * @return lockPeriod Lock Period of the given Barz account or wallet\n */\n function lockPeriodOf(\n address _wallet\n ) public view override onlyWallet(_wallet) returns (uint128 lockPeriod) {\n lockPeriod = securityConfigs[_wallet].lockPeriod;\n lockPeriod = (lockPeriod == 0) ? defaultLockPeriod : lockPeriod;\n }\n\n /**\n * @notice Returns the approval validation period. Returns default value when custom approval validation period is not set\n * @param _wallet Address of wallet\n * @return approvalValidationPeriod Approval Validation Period of the given Barz account or wallet\n */\n function approvalValidationPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityConfigs[_wallet]\n .approvalValidationPeriod;\n approvalValidationPeriod = (approvalValidationPeriod == 0)\n ? defaultApprovalValidationPeriod\n : approvalValidationPeriod;\n }\n\n /**\n * @notice Returns the migration period. Returns default value when custom migration period is not set\n * @param _wallet Address of wallet\n * @return migrationPeriod Migration Period of the given Barz account or wallet\n */\n function migrationPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 migrationPeriod)\n {\n migrationPeriod = securityConfigs[_wallet].migrationPeriod;\n migrationPeriod = (migrationPeriod == 0)\n ? defaultMigrationPeriod\n : migrationPeriod;\n }\n\n /**\n * @notice Validates if the period is smaller than the max period or bigger than the min period\n * @param _period Period to be checked\n * @param _minPeriod Minimum period\n * @param _maxPeriod Maximum period\n */\n function _validatePeriodBoundaries(\n uint128 _period,\n uint128 _minPeriod,\n uint128 _maxPeriod\n ) internal pure {\n if (_period >= _maxPeriod || _period <= _minPeriod)\n revert SecurityManager__OutOfBoundary();\n }\n}\n" + }, + "contracts/infrastructure/WhitelistStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {RemoteStorage} from \"./RemoteStorage.sol\";\n\n/**\n * @title Whitelist storage\n * @dev Maps addresses to the corresponsing array of whitelisted addresses for each of them.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract WhitelistStorage is RemoteStorage {\n /**\n * @dev Add the address to the whitelist storage\n * @param _wallet User wallet\n * @param _address Address to be whitelisted\n */\n function whitelistAddress(address _wallet, address _address) external {\n enforceWalletOrGuardianIfExists(_wallet);\n addAddress(_wallet, _address);\n }\n\n /**\n * @dev Removes the address from the whitelist storage\n * @param _wallet User wallet\n * @param _address Address to be removed from the whitelist\n */\n function blacklistAddress(address _wallet, address _address) external {\n enforceGuardianOrWallet(_wallet);\n removeAddress(_wallet, _address);\n }\n\n /**\n * @dev Returns whether the address exists in the whitelist storage, associated with the wallet\n * @param _wallet User wallet\n * @param _address Address to be whitelisted\n */\n function isWhitelisted(\n address _wallet,\n address _address\n ) external view returns (bool) {\n return exists(_wallet, _address);\n }\n\n /**\n * @dev Returns all whitelisted addresses associated with the wallet\n * @param _wallet User wallet\n */\n function getWhitelistedAddresses(\n address _wallet\n ) external view returns (address[] memory) {\n return getAddresses(_wallet);\n }\n}\n" + }, + "contracts/interfaces/ERC/IERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\n\npragma solidity 0.8.21;\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155Receiver {\n /**\n * @dev Handles the receipt of a single ERC1155 token type. This function is\n * called at the end of a `safeTransferFrom` after the balance has been updated.\n *\n * NOTE: To accept the transfer, this must return\n * `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n * (i.e. 0xf23a6e61, or its own function selector).\n *\n * @param operator The address which initiated the transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param id The ID of the token being transferred\n * @param value The amount of tokens being transferred\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n ) external returns (bytes4);\n\n /**\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\n * is called at the end of a `safeBatchTransferFrom` after the balances have\n * been updated.\n *\n * NOTE: To accept the transfer(s), this must return\n * `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n * (i.e. 0xbc197c81, or its own function selector).\n *\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "contracts/interfaces/ERC/IERC1271.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\ninterface IERC1271 {\n function isValidSignature(\n bytes32 hash,\n bytes memory signature\n ) external view returns (bytes4);\n}\n" + }, + "contracts/interfaces/ERC/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\ninterface IERC165 {\n /// @notice Query if a contract implements an interface\n /// @param interfaceId The interface identifier, as specified in ERC-165\n /// @dev Interface identification is specified in ERC-165. This function\n /// uses less than 30,000 gas.\n /// @return `true` if the contract implements `interfaceID` and\n /// `interfaceID` is not 0xffffffff, `false` otherwise\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/IERC173.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\n/// @title ERC-173 Contract Ownership Standard\n/// Note: the ERC-165 identifier for this interface is 0x7f5828d0\n/* is ERC165 */\ninterface IERC173 {\n /// @dev This emits when ownership of a contract changes.\n event OwnershipTransferred(\n address indexed previousOwner,\n address indexed newOwner\n );\n\n /// @notice Get the address of the owner\n /// @return owner_ The address of the owner.\n function owner() external view returns (address owner_);\n\n /// @notice Set the address of the new owner of the contract\n /// @dev Set _newOwner to address(0) to renounce any ownership.\n /// @param _newOwner The address of the new owner of the contract\n function transferOwnership(address _newOwner) external;\n}\n" + }, + "contracts/interfaces/ERC/IERC677Receiver.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\ninterface IERC677Receiver {\n function onTokenTransfer(\n address sender,\n uint value,\n bytes calldata data\n ) external pure returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155 is IERC165 {\n /**\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n */\n event TransferSingle(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256 id,\n uint256 value\n );\n\n /**\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n * transfers.\n */\n event TransferBatch(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\n\n /**\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n * `approved`.\n */\n event ApprovalForAll(\n address indexed account,\n address indexed operator,\n bool approved\n );\n\n /**\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n *\n * If an {URI} event was emitted for `id`, the standard\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n * returned by {IERC1155MetadataURI-uri}.\n */\n event URI(string value, uint256 indexed id);\n\n /**\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(\n address account,\n uint256 id\n ) external view returns (uint256);\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] calldata accounts,\n uint256[] calldata ids\n ) external view returns (uint256[] memory);\n\n /**\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n *\n * Emits an {ApprovalForAll} event.\n *\n * Requirements:\n *\n * - `operator` cannot be the caller.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n *\n * See {setApprovalForAll}.\n */\n function isApprovedForAll(\n address account,\n address operator\n ) external view returns (bool);\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes calldata data\n ) external;\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(\n address indexed owner,\n address indexed spender,\n uint256 value\n );\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` 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 amount) 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(\n address owner,\n address spender\n ) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the 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 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` 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(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(\n address spender,\n uint256 addedValue\n ) external returns (bool);\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(\n address spender,\n uint256 subtractedValue\n ) external returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(\n address indexed from,\n address indexed to,\n uint256 indexed tokenId\n );\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(\n address indexed owner,\n address indexed approved,\n uint256 indexed tokenId\n );\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(\n address indexed owner,\n address indexed operator,\n bool approved\n );\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(\n uint256 tokenId\n ) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(\n address owner,\n address operator\n ) external view returns (bool);\n}\n" + }, + "contracts/interfaces/IBarz.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Barz Interface\n * @dev Interface of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IBarz {\n error Barz__InitializationFailure();\n}\n" + }, + "contracts/interfaces/IBarzFactory.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Barz} from \"../Barz.sol\";\n\n/**\n * @title Barz Factory Interface\n * @dev Interface of contract to easily deploy Barz to a pre-computed address with a single call\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IBarzFactory {\n event BarzDeployed(address);\n\n function createAccount(\n address verificationFacet,\n bytes calldata owner,\n uint256 salt\n ) external returns (Barz);\n\n function getAddress(\n address verificationFacet,\n bytes calldata owner,\n uint256 salt\n ) external view returns (address);\n\n function getBytecode(\n address accountFacet,\n address verificationFacet,\n address entryPoint,\n address facetRegistry,\n address defaultFallback,\n bytes memory ownerPublicKey\n ) external pure returns (bytes memory);\n\n function getCreationCode() external pure returns (bytes memory);\n}\n" + }, + "contracts/libraries/DefaultLibDiamond.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\n\nerror InitializationFunctionReverted(\n address _initializationContractAddress,\n bytes _calldata\n);\n\nlibrary DefaultLibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION =\n keccak256(\"trustwallet.barz.diamond.storage\");\n\n struct FacetAddressAndPosition {\n address facetAddress;\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\n }\n\n struct FacetFunctionSelectors {\n bytes4[] functionSelectors;\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\n }\n\n struct DiamondStorage {\n // maps function selector to the facet address and\n // the position of the selector in the facetFunctionSelectors.selectors array\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\n // maps facet addresses to function selectors\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\n // facet addresses\n address[] facetAddresses;\n // Used to query if a contract implements an interface.\n // Used to implement ERC-165.\n mapping(bytes4 => bool) supportedInterfaces;\n }\n\n function diamondStorage()\n internal\n pure\n returns (DiamondStorage storage ds)\n {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n event DiamondCut(\n IDiamondCut.FacetCut[] _diamondCut,\n address _init,\n bytes _calldata\n );\n\n // Internal function version of diamondCut\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n for (\n uint256 facetIndex;\n facetIndex < _diamondCut.length;\n facetIndex++\n ) {\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\n if (action == IDiamondCut.FacetCutAction.Add) {\n addFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\n replaceFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\n removeFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else {\n revert(\"LibDiamondCut: Incorrect FacetCutAction\");\n }\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Add facet can't be address(0)\"\n );\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n require(\n oldFacetAddress == address(0),\n \"LibDiamondCut: Can't add function that already exists\"\n );\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function replaceFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Replace facet can't be address(0)\"\n );\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n require(\n oldFacetAddress != _facetAddress,\n \"LibDiamondCut: Can't replace function with same facet\"\n );\n removeFunction(ds, oldFacetAddress, selector);\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function removeFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n // if function does not exist then do nothing and return\n require(\n _facetAddress == address(0),\n \"LibDiamondCut: Remove facet address must be address(0)\"\n );\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n removeFunction(ds, oldFacetAddress, selector);\n }\n }\n\n function addFacet(\n DiamondStorage storage ds,\n address _facetAddress\n ) internal {\n enforceHasContractCode(\n _facetAddress,\n \"LibDiamondCut: New facet has no code\"\n );\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds\n .facetAddresses\n .length;\n ds.facetAddresses.push(_facetAddress);\n }\n\n function addFunction(\n DiamondStorage storage ds,\n bytes4 _selector,\n uint96 _selectorPosition,\n address _facetAddress\n ) internal {\n ds\n .selectorToFacetAndPosition[_selector]\n .functionSelectorPosition = _selectorPosition;\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(\n _selector\n );\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\n }\n\n function removeFunction(\n DiamondStorage storage ds,\n address _facetAddress,\n bytes4 _selector\n ) internal {\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Can't remove function that doesn't exist\"\n );\n // an immutable function is a function defined directly in a diamond\n require(\n _facetAddress != address(this),\n \"LibDiamondCut: Can't remove immutable function\"\n );\n // replace selector with last selector, then delete last selector\n uint256 selectorPosition = ds\n .selectorToFacetAndPosition[_selector]\n .functionSelectorPosition;\n uint256 lastSelectorPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors\n .length - 1;\n // if not the same then replace _selector with lastSelector\n if (selectorPosition != lastSelectorPosition) {\n bytes4 lastSelector = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors[lastSelectorPosition];\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[\n selectorPosition\n ] = lastSelector;\n ds\n .selectorToFacetAndPosition[lastSelector]\n .functionSelectorPosition = uint96(selectorPosition);\n }\n // delete the last selector\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\n delete ds.selectorToFacetAndPosition[_selector];\n\n // if no more selectors for facet address then delete the facet address\n if (lastSelectorPosition == 0) {\n // replace facet address with last facet address and delete last facet address\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\n uint256 facetAddressPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .facetAddressPosition;\n if (facetAddressPosition != lastFacetAddressPosition) {\n address lastFacetAddress = ds.facetAddresses[\n lastFacetAddressPosition\n ];\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\n ds\n .facetFunctionSelectors[lastFacetAddress]\n .facetAddressPosition = facetAddressPosition;\n }\n ds.facetAddresses.pop();\n delete ds\n .facetFunctionSelectors[_facetAddress]\n .facetAddressPosition;\n }\n }\n\n function initializeDiamondCut(\n address _init,\n bytes memory _calldata\n ) internal {\n if (_init == address(0)) {\n return;\n }\n enforceHasContractCode(\n _init,\n \"LibDiamondCut: _init address has no code\"\n );\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length > 0) {\n // bubble up error\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(error)\n revert(add(32, error), returndata_size)\n }\n } else {\n revert InitializationFunctionReverted(_init, _calldata);\n }\n }\n }\n\n function enforceHasContractCode(\n address _contract,\n string memory _errorMessage\n ) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize > 0, _errorMessage);\n }\n}\n" + }, + "contracts/libraries/LibAppStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SafeCast} from \"@openzeppelin/contracts/utils/math/SafeCast.sol\";\nimport {IEntryPoint} from \"../aa-4337/interfaces/IEntryPoint.sol\";\nimport {IFacetRegistry} from \"../infrastructure/interfaces/IFacetRegistry.sol\";\n\n/*\n * @title App Storage\n * @dev App storage for Barz contract to prevent storage collision\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\n\nstruct Lock {\n uint64 release;\n bytes4 locker;\n}\n\nstruct InitializersStorage {\n // NOTE: initialized is a variable to make sure the initialization is only done once.\n uint8 signerInitialized;\n uint8 accountInitialized;\n uint8 restrictionsInitialized;\n}\n\nstruct AppStorage {\n mapping(uint256 => InitializersStorage) initStorage;\n uint8 signerMigration;\n bytes4 validateOwnerSignatureSelector;\n IEntryPoint entryPoint;\n IFacetRegistry facetRegistry;\n mapping(uint256 => Lock) locks;\n}\n\nlibrary LibAppStorage {\n error LibAppStorage__AccountAlreadyUninitialized();\n error LibAppStorage__AccountMustBeUninitialized();\n error LibAppStorage__SignerAlreadyUninitialized();\n error LibAppStorage__SignerMustBeUninitialized();\n\n function appStorage() internal pure returns (AppStorage storage ds) {\n assembly {\n ds.slot := 0\n }\n }\n\n function setSignerUninitialized() internal {\n AppStorage storage s = appStorage();\n if (1 != s.initStorage[0].signerInitialized) {\n revert LibAppStorage__SignerAlreadyUninitialized();\n }\n s.initStorage[0].signerInitialized = 0;\n }\n\n function getValidateOwnerSignatureSelector()\n internal\n view\n returns (bytes4 selector)\n {\n selector = appStorage().validateOwnerSignatureSelector;\n }\n\n function setValidateOwnerSignatureSelector(\n bytes4 _validateOwnerSignatureSelector\n ) internal {\n appStorage()\n .validateOwnerSignatureSelector = _validateOwnerSignatureSelector;\n }\n\n function enforceSignerInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].signerInitialized) {\n revert LibAppStorage__SignerMustBeUninitialized();\n }\n s.initStorage[0].signerInitialized = 1;\n }\n\n function enforceAccountInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].accountInitialized) {\n revert LibAppStorage__AccountMustBeUninitialized();\n }\n s.initStorage[0].accountInitialized = 1;\n }\n\n function initiateSignerMigration() internal {\n appStorage().signerMigration = 1;\n }\n\n function enforceSignerMigration() internal view {\n if (1 != appStorage().signerMigration) {\n revert LibAppStorage__AccountMustBeUninitialized();\n }\n }\n\n function finalizeSignerMigration() internal {\n appStorage().signerMigration = 0;\n }\n\n function setLock(uint256 _releaseAfter, bytes4 _locker) internal {\n appStorage().locks[0] = Lock(SafeCast.toUint64(_releaseAfter), _locker);\n }\n\n function enforceRestrictionsInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].restrictionsInitialized)\n revert LibAppStorage__SignerMustBeUninitialized();\n s.initStorage[0].restrictionsInitialized = 1;\n }\n\n function setRestrictionsUninitialized() internal {\n AppStorage storage s = appStorage();\n if (1 != s.initStorage[0].restrictionsInitialized)\n revert LibAppStorage__AccountAlreadyUninitialized();\n s.initStorage[0].restrictionsInitialized = 0;\n }\n}\n\ncontract BarzStorage {\n AppStorage internal s;\n modifier onlyWhenUnlocked() {\n require(\n uint64(block.timestamp) >= s.locks[0].release,\n \"Account Locked\"\n );\n _;\n }\n modifier onlyWhenLocked() {\n require(\n uint64(block.timestamp) < s.locks[0].release,\n \"Account Unlocked\"\n );\n _;\n }\n}\n" + }, + "contracts/libraries/LibDiamond.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\n\nerror InitializationFunctionReverted(\n address _initializationContractAddress,\n bytes _calldata\n);\n\nlibrary LibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION =\n keccak256(\"trustwallet.barz.diamond.storage\");\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\n bytes4(keccak256(\"verifyRestrictions(address,address,uint256,bytes)\"));\n struct DiamondStorage {\n // maps function selectors to the facets that execute the functions.\n // and maps the selectors to their position in the selectorSlots array.\n // func selector => address facet, selector position\n mapping(bytes4 => bytes32) facets;\n // array of slots of function selectors.\n // each slot holds 8 function selectors.\n mapping(uint256 => bytes32) selectorSlots;\n // The number of function selectors in selectorSlots\n uint16 selectorCount;\n // Used to query if a contract implements an interface.\n // Used to implement ERC-165.\n mapping(bytes4 => bool) supportedInterfaces;\n // Default Fallback Handler of the barz.\n IDiamondLoupe defaultFallbackHandler;\n }\n\n function diamondStorage()\n internal\n pure\n returns (DiamondStorage storage ds)\n {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n function enforceIsSelf() internal view {\n require(msg.sender == address(this), \"LibDiamond: Caller not self\");\n }\n\n event DiamondCut(\n IDiamondCut.FacetCut[] _diamondCut,\n address _init,\n bytes _calldata\n );\n\n bytes32 constant CLEAR_ADDRESS_MASK =\n bytes32(uint256(0xffffffffffffffffffffffff));\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\n\n // Internal function version of diamondCut\n // This code is almost the same as the external diamondCut,\n // except it is using 'Facet[] memory _diamondCut' instead of\n // 'Facet[] calldata _diamondCut'.\n // The code is duplicated to prevent copying calldata to memory which\n // causes an error for a two dimensional array.\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n DiamondStorage storage ds = diamondStorage();\n uint256 originalSelectorCount = ds.selectorCount;\n uint256 selectorCount = originalSelectorCount;\n bytes32 selectorSlot;\n // Check if last selector slot is not full\n // \"selectorCount & 7\" is a gas efficient modulo by eight \"selectorCount % 8\"\n if (selectorCount & 7 > 0) {\n // get last selectorSlot\n // \"selectorSlot >> 3\" is a gas efficient division by 8 \"selectorSlot / 8\"\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\n }\n // loop through diamond cut\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\n selectorCount,\n selectorSlot,\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].action,\n _diamondCut[facetIndex].functionSelectors\n );\n\n unchecked {\n facetIndex++;\n }\n }\n if (selectorCount != originalSelectorCount) {\n ds.selectorCount = uint16(selectorCount);\n }\n // If last selector slot is not full\n // \"selectorCount & 7\" is a gas efficient modulo by eight \"selectorCount % 8\"\n if (selectorCount & 7 > 0) {\n // \"selectorSlot >> 3\" is a gas efficient division by 8 \"selectorSlot / 8\"\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addReplaceRemoveFacetSelectors(\n uint256 _selectorCount,\n bytes32 _selectorSlot,\n address _newFacetAddress,\n IDiamondCut.FacetCutAction _action,\n bytes4[] memory _selectors\n ) internal returns (uint256, bytes32) {\n DiamondStorage storage ds = diamondStorage();\n require(\n _selectors.length > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n if (_action == IDiamondCut.FacetCutAction.Add) {\n enforceHasContractCode(\n _newFacetAddress,\n \"LibDiamondCut: Add facet has no code\"\n );\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n require(\n address(bytes20(oldFacet)) == address(0),\n \"LibDiamondCut: Can't add function that already exists\"\n );\n // add facet for selector\n ds.facets[selector] =\n bytes20(_newFacetAddress) |\n bytes32(_selectorCount);\n // \"_selectorCount & 7\" is a gas efficient modulo by eight \"_selectorCount % 8\"\n // \" << 5 is the same as multiplying by 32 ( * 32)\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\n // clear selector position in slot and add selector\n _selectorSlot =\n (_selectorSlot &\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\n (bytes32(selector) >> selectorInSlotPosition);\n // if slot is full then write it to storage\n if (selectorInSlotPosition == 224) {\n // \"_selectorSlot >> 3\" is a gas efficient division by 8 \"_selectorSlot / 8\"\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\n _selectorSlot = 0;\n }\n _selectorCount++;\n\n unchecked {\n selectorIndex++;\n }\n }\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\n enforceHasContractCode(\n _newFacetAddress,\n \"LibDiamondCut: Replace facet has no code\"\n );\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n address oldFacetAddress = address(bytes20(oldFacet));\n // only useful if immutable functions exist\n require(\n oldFacetAddress != address(this),\n \"LibDiamondCut: Can't replace immutable function\"\n );\n require(\n oldFacetAddress != _newFacetAddress,\n \"LibDiamondCut: Can't replace function with same function\"\n );\n require(\n oldFacetAddress != address(0),\n \"LibDiamondCut: Can't replace function that doesn't exist\"\n );\n // replace old facet address\n ds.facets[selector] =\n (oldFacet & CLEAR_ADDRESS_MASK) |\n bytes20(_newFacetAddress);\n\n unchecked {\n selectorIndex++;\n }\n }\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\n require(\n _newFacetAddress == address(0),\n \"LibDiamondCut: Remove facet address must be address(0)\"\n );\n // \"_selectorCount >> 3\" is a gas efficient division by 8 \"_selectorCount / 8\"\n uint256 selectorSlotCount = _selectorCount >> 3;\n // \"_selectorCount & 7\" is a gas efficient modulo by eight \"_selectorCount % 8\"\n uint256 selectorInSlotIndex = _selectorCount & 7;\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n if (_selectorSlot == 0) {\n // get last selectorSlot\n selectorSlotCount--;\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\n selectorInSlotIndex = 7;\n } else {\n selectorInSlotIndex--;\n }\n bytes4 lastSelector;\n uint256 oldSelectorsSlotCount;\n uint256 oldSelectorInSlotPosition;\n // adding a block here prevents stack too deep error\n {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n require(\n address(bytes20(oldFacet)) != address(0),\n \"LibDiamondCut: Can't remove function that doesn't exist\"\n );\n // only useful if immutable functions exist\n require(\n address(bytes20(oldFacet)) != address(this),\n \"LibDiamondCut: Can't remove immutable function\"\n );\n // replace selector with last selector in ds.facets\n // gets the last selector\n // \" << 5 is the same as multiplying by 32 ( * 32)\n lastSelector = bytes4(\n _selectorSlot << (selectorInSlotIndex << 5)\n );\n if (lastSelector != selector) {\n // update last selector slot position info\n ds.facets[lastSelector] =\n (oldFacet & CLEAR_ADDRESS_MASK) |\n bytes20(ds.facets[lastSelector]);\n }\n delete ds.facets[selector];\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\n // \"oldSelectorCount >> 3\" is a gas efficient division by 8 \"oldSelectorCount / 8\"\n oldSelectorsSlotCount = oldSelectorCount >> 3;\n // \"oldSelectorCount & 7\" is a gas efficient modulo by eight \"oldSelectorCount % 8\"\n // \" << 5 is the same as multiplying by 32 ( * 32)\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\n }\n if (oldSelectorsSlotCount != selectorSlotCount) {\n bytes32 oldSelectorSlot = ds.selectorSlots[\n oldSelectorsSlotCount\n ];\n // clears the selector we are deleting and puts the last selector in its place.\n oldSelectorSlot =\n (oldSelectorSlot &\n ~(CLEAR_SELECTOR_MASK >>\n oldSelectorInSlotPosition)) |\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\n // update storage with the modified slot\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\n } else {\n // clears the selector we are deleting and puts the last selector in its place.\n _selectorSlot =\n (_selectorSlot &\n ~(CLEAR_SELECTOR_MASK >>\n oldSelectorInSlotPosition)) |\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\n }\n if (selectorInSlotIndex == 0) {\n delete ds.selectorSlots[selectorSlotCount];\n _selectorSlot = 0;\n }\n\n unchecked {\n selectorIndex++;\n }\n }\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\n } else {\n revert(\"LibDiamondCut: Incorrect FacetCutAction\");\n }\n return (_selectorCount, _selectorSlot);\n }\n\n function initializeDiamondCut(\n address _init,\n bytes memory _calldata\n ) internal {\n if (_init == address(0)) {\n return;\n }\n enforceHasContractCode(\n _init,\n \"LibDiamondCut: _init address has no code\"\n );\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length > 0) {\n // bubble up error\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(error)\n revert(add(32, error), returndata_size)\n }\n } else {\n revert InitializationFunctionReverted(_init, _calldata);\n }\n }\n }\n\n function enforceHasContractCode(\n address _contract,\n string memory _errorMessage\n ) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize > 0, _errorMessage);\n }\n\n function restrictionsFacet() internal view returns (address facetAddress_) {\n facetAddress_ = address(\n bytes20(\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\n )\n );\n }\n}\n" + }, + "contracts/libraries/LibFacetStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Storage\n * @dev Storage contract to store each facets variables with diamond storage\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\n\nstruct Secp256k1VerificationStorage {\n address signer;\n}\n\nstruct Secp256r1VerificationStorage {\n uint256[2] q;\n}\n\nstruct GuardianStorage {\n mapping(bytes32 => uint256) pending;\n mapping(uint8 => StorageConfig) configs;\n}\n\nstruct Info {\n bool exists;\n uint128 index;\n}\n\nstruct StorageConfig {\n address[] addresses;\n mapping(address => Info) info;\n}\n\nstruct RecoveryConfig {\n bytes recoveryPublicKey;\n uint64 executeAfter;\n}\n\nstruct ApprovalConfig {\n bool isApproved;\n uint64 validUntil;\n}\n\nstruct RecoveryApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isNewOwnerApproved;\n}\n\nstruct RecoveryStorage {\n mapping(uint8 => RecoveryConfig) recoveryConfigs;\n mapping(uint8 => RecoveryApprovalConfig) recoveryApprovalConfigs;\n uint128 nonce;\n}\n\nstruct RestrictionsStorage {\n address[] restrictions;\n mapping(address => bool) exists;\n}\n\nstruct SignatureMigrationConfig {\n bytes migrationPublicKey;\n address migrationVerificationFacet;\n bytes4[] migrationSelectors;\n uint64 migrateAfter;\n}\n\nstruct SignatureMigrationApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isMigrationApproved;\n}\n\nstruct SignatureMigrationStorage {\n mapping(uint8 => SignatureMigrationConfig) migrationConfigs;\n mapping(uint8 => SignatureMigrationApprovalConfig) migrationApprovalConfigs;\n uint128 nonce;\n}\n\nstruct DiamondCutApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isDiamondCutApproved;\n}\n\nstruct DiamondCutStorage {\n mapping(uint8 => DiamondCutApprovalConfig) diamondCutApprovalConfigs;\n uint128 nonce;\n}\n\nstruct LockStorage {\n uint128 nonce;\n}\n\nlibrary LibFacetStorage {\n bytes32 constant K1_STORAGE_POSITION =\n keccak256(\n \"v0.trustwallet.diamond.storage.Secp256k1VerificationStorage\"\n );\n bytes32 constant R1_STORAGE_POSITION =\n keccak256(\n \"v0.trustwallet.diamond.storage.Secp256r1VerificationStorage\"\n );\n bytes32 constant GUARDIAN_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.GuardianStorage\");\n bytes32 constant RECOVERY_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.RecoveryStorage\");\n bytes32 constant RESTRICTION_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.RestrictionsStorage\");\n bytes32 constant MIGRATION_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.SignatureMigrationStorage\");\n bytes32 constant DIAMONDCUT_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.DiamondCutStorage\");\n bytes32 constant LOCK_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.LockStorage\");\n\n function k1Storage()\n internal\n pure\n returns (Secp256k1VerificationStorage storage ds)\n {\n bytes32 storagePosition = K1_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function r1Storage()\n internal\n pure\n returns (Secp256r1VerificationStorage storage ds)\n {\n bytes32 storagePosition = R1_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function guardianStorage()\n internal\n pure\n returns (GuardianStorage storage ds)\n {\n bytes32 storagePosition = GUARDIAN_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function recoveryStorage()\n internal\n pure\n returns (RecoveryStorage storage ds)\n {\n bytes32 storagePosition = RECOVERY_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function restrictionsStorage()\n internal\n pure\n returns (RestrictionsStorage storage ds)\n {\n bytes32 storagePosition = RESTRICTION_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function migrationStorage()\n internal\n pure\n returns (SignatureMigrationStorage storage ds)\n {\n bytes32 storagePosition = MIGRATION_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function diamondCutStorage()\n internal\n pure\n returns (DiamondCutStorage storage ds)\n {\n bytes32 storagePosition = DIAMONDCUT_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function lockStorage() internal pure returns (LockStorage storage ds) {\n bytes32 storagePosition = LOCK_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n}\n" + }, + "contracts/libraries/LibGuardian.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibFacetStorage, StorageConfig} from \"./LibFacetStorage.sol\";\n\n/**\n * @title LibGuardian\n * @dev Internal Library to provide utility feature for Guardians stored in Guardian Facet Storage\n * @author David Yongjun Kim (@Powerstream3604)\n */\nlibrary LibGuardian {\n function majorityOfGuardians()\n internal\n view\n returns (uint256 guardianNumber)\n {\n uint256 guardianLength = guardianCount();\n guardianNumber = (guardianLength == 0) ? 0 : guardianLength / 2 + 1;\n }\n\n function isGuardian(address _guardian) internal view returns (bool) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n return config.info[_guardian].exists;\n }\n\n function guardianCount() internal view returns (uint256) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n return config.addresses.length;\n }\n\n function getGuardians() internal view returns (address[] memory) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n address[] memory addresses = new address[](config.addresses.length);\n uint256 addressesLen = config.addresses.length;\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n return addresses;\n }\n}\n" + }, + "contracts/libraries/LibLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {LibDiamond} from \"./LibDiamond.sol\";\n\n/**\n * @title LibLoupe\n * @dev Internal Library to provide utility feature for reading the state of diamond facets\n * Originally from Diamond's implementation of Mudgen(author of EIP-2535)\n */\nlibrary LibLoupe {\n /// @notice Gets all facets and their selectors.\n /// @return facets_ Facet\n function facets()\n internal\n view\n returns (IDiamondLoupe.Facet[] memory facets_)\n {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facets_ = new IDiamondLoupe.Facet[](ds.selectorCount);\n uint16[] memory numFacetSelectors = new uint16[](ds.selectorCount);\n uint256 numFacets;\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facetAddress_ = address(bytes20(ds.facets[selector]));\n bool continueLoop;\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n if (facets_[facetIndex].facetAddress == facetAddress_) {\n facets_[facetIndex].functionSelectors[\n numFacetSelectors[facetIndex]\n ] = selector;\n // probably will never have more than 256 functions from one facet contract\n require(numFacetSelectors[facetIndex] < 255);\n numFacetSelectors[facetIndex]++;\n continueLoop = true;\n break;\n }\n }\n if (continueLoop) {\n continue;\n }\n facets_[numFacets].facetAddress = facetAddress_;\n facets_[numFacets].functionSelectors = new bytes4[](\n ds.selectorCount\n );\n facets_[numFacets].functionSelectors[0] = selector;\n numFacetSelectors[numFacets] = 1;\n numFacets++;\n }\n }\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n uint256 numSelectors = numFacetSelectors[facetIndex];\n bytes4[] memory selectors = facets_[facetIndex].functionSelectors;\n // setting the number of selectors\n assembly {\n mstore(selectors, numSelectors)\n }\n }\n // setting the number of facets\n assembly {\n mstore(facets_, numFacets)\n }\n }\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n /// @return _facetFunctionSelectors The selectors associated with a facet address.\n function facetFunctionSelectors(\n address _facet\n ) internal view returns (bytes4[] memory _facetFunctionSelectors) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n uint256 numSelectors;\n _facetFunctionSelectors = new bytes4[](ds.selectorCount);\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facet = address(bytes20(ds.facets[selector]));\n if (_facet == facet) {\n _facetFunctionSelectors[numSelectors] = selector;\n numSelectors++;\n }\n }\n }\n // Set the number of selectors in the array\n assembly {\n mstore(_facetFunctionSelectors, numSelectors)\n }\n }\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses()\n internal\n view\n returns (address[] memory facetAddresses_)\n {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facetAddresses_ = new address[](ds.selectorCount);\n uint256 numFacets;\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facetAddress_ = address(bytes20(ds.facets[selector]));\n bool continueLoop;\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n if (facetAddress_ == facetAddresses_[facetIndex]) {\n continueLoop = true;\n break;\n }\n }\n if (continueLoop) {\n continue;\n }\n facetAddresses_[numFacets] = facetAddress_;\n numFacets++;\n }\n }\n // Set the number of facet addresses in the array\n assembly {\n mstore(facetAddresses_, numFacets)\n }\n }\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(\n bytes4 _functionSelector\n ) internal view returns (address facetAddress_) {\n facetAddress_ = address(\n bytes20(LibDiamond.diamondStorage().facets[_functionSelector])\n );\n }\n}\n" + }, + "contracts/libraries/LibMultiSigStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Multi-sig Storage\n * @dev Storage contract for storing Multi-sig Facet variables in diamond storage pattern\n * @author David Yongjun Kim (@Powerstream3604)\n */\n\nstruct MultiSigStorage {\n mapping(address => address) owners;\n mapping(uint256 => mapping(address => mapping(bytes32 => uint256))) approvedHashes;\n uint256 ownerCount;\n uint256 threshold;\n uint256 counter;\n}\n\nlibrary LibMultiSigStorage {\n function multisigStorage()\n internal\n pure\n returns (MultiSigStorage storage ds)\n {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.MultiSigStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n}\n" + }, + "contracts/libraries/LibRecoverSpender.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title RecoverSpender\n * @dev Library to determine the action and spender of calldata\n * @author Ruslan Serebriakov (@rsrbk)\n */\nlibrary LibRecoverSpender {\n // ERC20, ERC721 & ERC1155 transfers & approvals\n bytes4 private constant ERC20_TRANSFER =\n bytes4(keccak256(\"transfer(address,uint256)\"));\n bytes4 private constant ERC20_APPROVE =\n bytes4(keccak256(\"approve(address,uint256)\"));\n bytes4 private constant ERC20_INCREASE_ALLOWANCE =\n bytes4(keccak256(\"increaseAllowance(address,uint256)\"));\n bytes4 private constant ERC20_DECREASE_ALLOWANCE =\n bytes4(keccak256(\"decreaseAllowance(address,uint256)\"));\n bytes4 private constant ERC721_SET_APPROVAL_FOR_ALL =\n bytes4(keccak256(\"setApprovalForAll(address,bool)\"));\n bytes4 private constant ERC721_TRANSFER_FROM =\n bytes4(keccak256(\"transferFrom(address,address,uint256)\"));\n bytes4 private constant ERC721_SAFE_TRANSFER_FROM =\n bytes4(keccak256(\"safeTransferFrom(address,address,uint256)\"));\n bytes4 private constant ERC721_SAFE_TRANSFER_FROM_BYTES =\n bytes4(keccak256(\"safeTransferFrom(address,address,uint256,bytes)\"));\n bytes4 private constant ERC1155_SAFE_TRANSFER_FROM =\n bytes4(\n keccak256(\"safeTransferFrom(address,address,uint256,uint256,bytes)\")\n );\n bytes4 private constant ERC1155_SAFE_BATCH_TRANSFER_FROM =\n bytes4(\n keccak256(\n \"safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)\"\n )\n );\n\n /**\n * @notice Helper method to recover the spender from a contract call.\n * The method returns the contract unless the call is to a standard method of a ERC20/ERC721/ERC1155 token\n * in which case the spender is recovered from the data.\n * @param _to The target contract.\n * @param _data The data payload.\n */\n function _recover(\n address _to,\n bytes memory _data\n ) internal pure returns (address spender) {\n if (_data.length >= 68) {\n bytes4 methodId;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n methodId := mload(add(_data, 0x20))\n }\n if (\n methodId == ERC20_TRANSFER ||\n methodId == ERC20_APPROVE ||\n methodId == ERC20_INCREASE_ALLOWANCE ||\n methodId == ERC20_DECREASE_ALLOWANCE ||\n methodId == ERC721_SET_APPROVAL_FOR_ALL\n ) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n spender := mload(add(_data, 0x24))\n }\n return spender;\n }\n if (\n methodId == ERC721_TRANSFER_FROM ||\n methodId == ERC721_SAFE_TRANSFER_FROM ||\n methodId == ERC721_SAFE_TRANSFER_FROM_BYTES ||\n methodId == ERC1155_SAFE_TRANSFER_FROM ||\n methodId == ERC1155_SAFE_BATCH_TRANSFER_FROM\n ) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n spender := mload(add(_data, 0x44))\n }\n return spender;\n }\n }\n\n spender = _to;\n }\n}\n" + }, + "contracts/libraries/LibReentrancyGuardStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nstruct ReentrancyGuardStorage {\n uint256 status;\n}\n\nlibrary LibReentrancyGuardStorage {\n bytes32 private constant REENTRANCY_GUARD_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.ReentrancyGuardStorage\");\n\n function reentrancyguardStorage()\n internal\n pure\n returns (ReentrancyGuardStorage storage ds)\n {\n bytes32 storagePosition = REENTRANCY_GUARD_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n}" + }, + "contracts/libraries/LibUtils.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\n\nlibrary LibUtils {\n // Internal utility functions\n function mergeArrays(\n bytes4[] memory _array1,\n bytes4[] memory _array2\n ) internal pure returns (bytes4[] memory) {\n uint256 length1 = _array1.length;\n uint256 length2 = _array2.length;\n bytes4[] memory mergedArray = new bytes4[](length1 + length2);\n\n for (uint256 i; i < length1; ) {\n mergedArray[i] = _array1[i];\n unchecked {\n ++i;\n }\n }\n\n for (uint256 i; i < length2; ) {\n mergedArray[length1 + i] = _array2[i];\n unchecked {\n ++i;\n }\n }\n\n return mergedArray;\n }\n\n function removeFacetElement(\n IDiamondLoupe.Facet[] memory _facets,\n uint256 _index\n ) internal pure returns (IDiamondLoupe.Facet[] memory) {\n require(_index < _facets.length, \"Invalid index\");\n require(_facets.length != 0, \"Invalid array\");\n\n // Create a new array with a length of `_facets.length - 1`\n IDiamondLoupe.Facet[] memory newArray = new IDiamondLoupe.Facet[](\n _facets.length - 1\n );\n uint256 newArrayLength = newArray.length;\n // Iterate over the original array, skipping the element at the specified `index`\n for (uint256 i; i < newArrayLength; ) {\n if (i < _index) {\n newArray[i] = _facets[i];\n } else {\n newArray[i] = _facets[i + 1];\n }\n unchecked {\n ++i;\n }\n }\n\n return newArray;\n }\n\n function removeElement(\n bytes4[] memory _array,\n uint256 _index\n ) internal pure returns (bytes4[] memory) {\n require(_index < _array.length, \"Invalid index\");\n require(_array.length != 0, \"Invalid array\");\n\n bytes4[] memory newArray = new bytes4[](_array.length - 1);\n uint256 newArrayLength = newArray.length;\n for (uint256 i; i < newArrayLength; ) {\n if (i < _index) {\n newArray[i] = _array[i];\n } else {\n newArray[i] = _array[i + 1];\n }\n unchecked {\n ++i;\n }\n }\n\n return newArray;\n }\n\n function setValue(\n bytes4[] memory _keys,\n address[] memory _values,\n bytes4 _key,\n address _value\n ) internal pure returns (bytes4[] memory, address[] memory) {\n uint256 index = findIndex(_keys, _key);\n uint256 keysLength = _keys.length;\n if (index < keysLength) {\n _values[index] = _value;\n } else {\n // Create new storage arrays\n bytes4[] memory newKeys = new bytes4[](keysLength + 1);\n address[] memory newValues = new address[](_values.length + 1);\n\n // Copy values to the new storage arrays\n for (uint256 i; i < keysLength; ) {\n newKeys[i] = _keys[i];\n newValues[i] = _values[i];\n\n unchecked {\n ++i;\n }\n }\n\n // Add the new key-value pair\n newKeys[keysLength] = _key;\n newValues[_values.length] = _value;\n\n return (newKeys, newValues);\n }\n\n // If the key already exists, return the original arrays\n return (_keys, _values);\n }\n\n function getValue(\n bytes4[] memory _keys,\n address[] memory _values,\n bytes4 _key\n ) internal pure returns (address) {\n uint256 index = findIndex(_keys, _key);\n if (index >= _keys.length) return address(0);\n\n return _values[index];\n }\n\n function findIndex(\n bytes4[] memory _keys,\n bytes4 _key\n ) internal pure returns (uint256) {\n uint256 keysLength = _keys.length;\n for (uint256 i; i < keysLength; ) {\n if (_keys[i] == _key) {\n return i;\n }\n unchecked {\n ++i;\n }\n }\n return keysLength;\n }\n}\n" + }, + "contracts/restrictions/IRestriction.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Interface for restrictions\n * @dev Restriction is a contract which decides whether to approve a certain kind of transaction, based on its internal logic.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface IRestriction {\n /**\n * @dev Based on restriction's internal logic, it should accept or reject a certain transaction.\n * @param from The address of the sender, that will be signing the transaction.\n * @param to The receiving address.\n * @param value Amount of ETH to transfer from sender to recipient.\n * @param _calldata Optional field to include arbitrary data.\n * @return bool value for whether the check is passed\n */\n function check(\n address from,\n address to,\n uint256 value,\n bytes calldata _calldata\n ) external returns (bool);\n}\n" + }, + "contracts/restrictions/WhitelistRestriction.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibRecoverSpender} from \"../libraries/LibRecoverSpender.sol\";\nimport {WhitelistStorage} from \"../infrastructure/WhitelistStorage.sol\";\nimport {IRestriction} from \"./IRestriction.sol\";\n\n/**\n * @title Whitelist Restriction\n * @dev This restriction defines a list of accepted addresses and denies any interaction with addresses outside of it.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract WhitelistRestriction is IRestriction {\n WhitelistStorage public immutable whitelistStorage;\n\n constructor(WhitelistStorage _whitelistStorage) {\n whitelistStorage = _whitelistStorage;\n }\n\n /**\n * @notice Helper method to recover the spender from a contract call.\n * The method returns the contract unless the call is to a standard method of a ERC20/ERC721/ERC1155 token\n * in which case the spender is recovered from the data.\n * @param _to The target contract.\n * @param _data The data payload.\n */\n function recoverSpender(\n address _to,\n bytes memory _data\n ) public pure returns (address spender) {\n return LibRecoverSpender._recover(_to, _data);\n }\n\n /*\n * @dev IRestriction's implementation. It will allow transaction if the sender is whitelisted, or user, or the whitelist storage.\n * @param _from The address of the sender, that will be signing the transaction.\n * @param _to The receiving address.\n * @param _calldata Optional field to include arbitrary data.\n * @return result value for whether the check is passed\n */\n function check(\n address _from,\n address _to,\n uint256 /*_value*/,\n bytes calldata _calldata\n ) external view override returns (bool result) {\n return\n whitelistStorage.isWhitelisted(\n _from,\n LibRecoverSpender._recover(_to, _calldata)\n ) ||\n _to == address(whitelistStorage) ||\n _to == msg.sender;\n }\n}\n" + }, + "contracts/test/TestCounter.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\ncontract TestCounter {\n int private count = 0;\n\n event CounterIncremented(int count);\n event CounterDecremented(int count);\n\n function incrementCounter() public {\n count += 1;\n emit CounterIncremented(count);\n }\n\n function decrementCounter() public {\n count -= 1;\n emit CounterIncremented(count);\n }\n\n function getCount() public view returns (int) {\n return count;\n }\n}\n" + }, + "contracts/test/TestERC1155.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC1155/ERC1155.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\n\ncontract TestERC1155 is ERC1155 {\n using Counters for Counters.Counter;\n\n Counters.Counter private _tokenIds;\n\n constructor() ERC1155(\"\") {}\n\n function mint(address account, uint256 amount) external {\n uint256 tokenId = _getNextTokenId();\n _mint(account, tokenId, amount, \"\");\n }\n\n function mintBatch(\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes memory data\n ) external {\n require(\n ids.length == amounts.length,\n \"TestERC1155: arrays length mismatch\"\n );\n\n _mintBatch(to, ids, amounts, data);\n }\n\n function _getNextTokenId() private returns (uint256) {\n _tokenIds.increment();\n return _tokenIds.current();\n }\n}\n" + }, + "contracts/test/TestERC777.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC777/ERC777.sol\";\n\ncontract TestERC777 is ERC777 {\n constructor(\n address[] memory _operators\n ) ERC777(\"TestERC777\", \"TERC777\", _operators) {}\n\n function mint(address account, uint256 amount) external {\n _mint(account, amount, \"\", \"\");\n }\n}\n" + }, + "contracts/test/TestInvalidSecp256k1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IVerificationFacet} from \"../facets/interfaces/IVerificationFacet.sol\";\nimport {IERC1271} from \"../interfaces/ERC/IERC1271.sol\";\nimport {AppStorage, LibAppStorage, BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {LibFacetStorage, Secp256k1VerificationStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {UserOperation} from \"../aa-4337/interfaces/UserOperation.sol\";\n\n/**\n * @title Test Secp256k1 verification facet\n * @dev Default Ethereum's elliptic curve\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract TestInvalidSecp256k1VerificationFacet is BarzStorage, IERC1271 {\n using ECDSA for bytes32;\n error Secp256k1VerificationFacet__InvalidSignerLength();\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n\n event SignerUninitialized();\n\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n }\n\n // THIS INVALID FACET DOES NOT INCLUDE initializeSigner()\n // THIS FACET IS USED TO TEST WHEN initializeSigner() DOESN'T EXIST IN FACET\n\n function uninitializeSigner() external returns (uint256 uninitSuccess) {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view returns (uint256 validationData) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n return validateSignature(userOp, userOpHash, k1Storage.signer);\n }\n\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n address signer\n ) public pure returns (uint256) {\n bytes32 hash = userOpHash.toEthSignedMessageHash();\n if (signer != hash.recover(userOp.signature)) return 1;\n return 0;\n }\n\n // This is REMOVED for testing purpose\n function validateOwnerSignatureSelector() public pure returns (bytes4) {\n // return this.validateOwnerSignature.selector;\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n function owner() public view returns (bytes memory) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n return abi.encodePacked(k1Storage.signer);\n }\n\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure returns (bool) {\n return (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (_hash.recover(_signature) ==\n LibFacetStorage.k1Storage().signer)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n}\n" + }, + "contracts/test/TestNFT.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\n\ncontract TestNFT is ERC721 {\n using Counters for Counters.Counter;\n Counters.Counter private currentTokenId;\n\n constructor() ERC721(\"TestNFT\", \"TNFT\") {}\n\n function mint(address recipient) public returns (uint256) {\n currentTokenId.increment();\n uint256 newItemId = currentTokenId.current();\n _safeMint(recipient, newItemId);\n return newItemId;\n }\n}\n" + }, + "contracts/test/TestToken.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract TestToken is ERC20 {\n constructor()\n // solhint-disable-next-line no-empty-blocks\n ERC20(\"TST\", \"TestToken\")\n {}\n\n function mint(address sender, uint256 amount) external {\n _mint(sender, amount);\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 999999 + }, + "evmVersion": "paris", + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/deployments/mainnet/.chainId b/deployments/mainnet/.chainId new file mode 100644 index 0000000..56a6051 --- /dev/null +++ b/deployments/mainnet/.chainId @@ -0,0 +1 @@ +1 \ No newline at end of file diff --git a/deployments/mainnet/AccountFacet.json b/deployments/mainnet/AccountFacet.json new file mode 100644 index 0000000..1058965 --- /dev/null +++ b/deployments/mainnet/AccountFacet.json @@ -0,0 +1,591 @@ +{ + "address": "0xFde53272dcd7938d16E031A6989753c321728332", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "AccountFacet__CallNotSuccessful", + "type": "error" + }, + { + "inputs": [], + "name": "AccountFacet__InitializationFailure", + "type": "error" + }, + { + "inputs": [], + "name": "AccountFacet__InvalidArrayLength", + "type": "error" + }, + { + "inputs": [], + "name": "AccountFacet__NonExistentVerificationFacet", + "type": "error" + }, + { + "inputs": [], + "name": "AccountFacet__RestrictionsFailure", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_initializationContractAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "InitializationFunctionReverted", + "type": "error" + }, + { + "inputs": [], + "name": "LibAppStorage__AccountMustBeUninitialized", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract IEntryPoint", + "name": "entryPoint", + "type": "address" + }, + { + "indexed": true, + "internalType": "bytes", + "name": "ownerPublicKey", + "type": "bytes" + } + ], + "name": "AccountInitialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "indexed": false, + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "DiamondCut", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "VerificationFailure", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "VerificationSuccess", + "type": "event" + }, + { + "inputs": [], + "name": "entryPoint", + "outputs": [ + { + "internalType": "contract IEntryPoint", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_dest", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_func", + "type": "bytes" + } + ], + "name": "execute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_dest", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "_value", + "type": "uint256[]" + }, + { + "internalType": "bytes[]", + "name": "_func", + "type": "bytes[]" + } + ], + "name": "executeBatch", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getNonce", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_verificationFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_anEntryPoint", + "type": "address" + }, + { + "internalType": "address", + "name": "_facetRegistry", + "type": "address" + }, + { + "internalType": "address", + "name": "_defaultFallBackHandler", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_ownerPublicKey", + "type": "bytes" + } + ], + "name": "initialize", + "outputs": [ + { + "internalType": "uint256", + "name": "initSuccess", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "initCode", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "callGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "verificationGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "preVerificationGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxFeePerGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPriorityFeePerGas", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "paymasterAndData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "internalType": "struct UserOperation", + "name": "userOp", + "type": "tuple" + }, + { + "internalType": "bytes32", + "name": "userOpHash", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "missingAccountFunds", + "type": "uint256" + } + ], + "name": "validateUserOp", + "outputs": [ + { + "internalType": "uint256", + "name": "validationData", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0xf27ce45f6236e6adb057e7e3c21b94857e7c8086f9272dec8d60e8817eb387b4", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 16, + "gasUsed": "2370628", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x91e9c5ce117517d433994510b25af3f20790c09ecee71d486a1790cd75f68568", + "transactionHash": "0xf27ce45f6236e6adb057e7e3c21b94857e7c8086f9272dec8d60e8817eb387b4", + "logs": [], + "blockNumber": 19517136, + "cumulativeGasUsed": "7220714", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "ad34345aa73d96f52b3e14df983b6b29", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AccountFacet__CallNotSuccessful\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AccountFacet__InitializationFailure\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AccountFacet__InvalidArrayLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AccountFacet__NonExistentVerificationFacet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AccountFacet__RestrictionsFailure\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_initializationContractAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"InitializationFunctionReverted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LibAppStorage__AccountMustBeUninitialized\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract IEntryPoint\",\"name\":\"entryPoint\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes\",\"name\":\"ownerPublicKey\",\"type\":\"bytes\"}],\"name\":\"AccountInitialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"DiamondCut\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"VerificationFailure\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"VerificationSuccess\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"entryPoint\",\"outputs\":[{\"internalType\":\"contract IEntryPoint\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_dest\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_func\",\"type\":\"bytes\"}],\"name\":\"execute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_dest\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"_value\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes[]\",\"name\":\"_func\",\"type\":\"bytes[]\"}],\"name\":\"executeBatch\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_verificationFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_anEntryPoint\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_facetRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_defaultFallBackHandler\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_ownerPublicKey\",\"type\":\"bytes\"}],\"name\":\"initialize\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"initSuccess\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"userOp\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"missingAccountFunds\",\"type\":\"uint256\"}],\"name\":\"validateUserOp\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"validationData\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"Account module contract that provides the account features and initialization of signer compatible with EIP-1271 & EIP-4337\",\"kind\":\"dev\",\"methods\":{\"execute(address,uint256,bytes)\":{\"details\":\"This method executes the calldata coming from the EntryPoint. Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\",\"params\":{\"_dest\":\"Address of destination where the call will be forwarded to\",\"_func\":\"Bytes of calldata to execute in the destination address\",\"_value\":\"Amount of native coin the owner is willing to send(e.g. ETH, BNB)\"}},\"executeBatch(address[],uint256[],bytes[])\":{\"details\":\"This method batch executes the calldata coming from the EntryPoint. Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\",\"params\":{\"_dest\":\"Array of addresses of destination where the call will be forwarded to\",\"_func\":\"Array of bytes of calldata to execute in the destination address\",\"_value\":\"Array of amount of native coin the owner is willing to send(e.g. ETH, BNB)\"}},\"initialize(address,address,address,address,bytes)\":{\"details\":\"This method can only be called during the initialization or signature migration. If the proxy contract was created without initialization, anyone can call initialize. Barz calls initialize in constructor in an atomic transaction during deployment\",\"params\":{\"_anEntryPoint\":\"Entrypoint contract defined in EIP-4337 handling the flow of UserOp\",\"_defaultFallBackHandler\":\"Middleware contract for default facets\",\"_facetRegistry\":\"Registry of Facets that hold all facet information\",\"_ownerPublicKey\":\"Bytes of owner public key\",\"_verificationFacet\":\"Facet contract handling the verificationi\"}}},\"title\":\"Account Facet\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"This constructor ensures that this contract can only be used as singleton for Proxy contracts\"},\"entryPoint()\":{\"notice\":\"Returns the address of EntryPoint contract registered to Barz account\"},\"execute(address,uint256,bytes)\":{\"notice\":\"Calls the destination with inputted calldata and value from EntryPoint\"},\"executeBatch(address[],uint256[],bytes[])\":{\"notice\":\"Batch calls the destination with inputted calldata and value from EntryPoint\"},\"getNonce()\":{\"notice\":\"Return the account nonce. This method returns the next sequential nonce. For a nonce of a specific key, use `entrypoint.getNonce(account, key)`\"},\"initialize(address,address,address,address,bytes)\":{\"notice\":\"Initializes the initial storage of the Barz contract.\"},\"validateUserOp((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256)\":{\"notice\":\"Validate user's signature and nonce. subclass doesn't need to override this method. Instead, it should override the specific internal validation methods.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/AccountFacet.sol\":\"AccountFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./math/Math.sol\\\";\\nimport \\\"./math/SignedMath.sol\\\";\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n uint256 length = Math.log10(value) + 1;\\n string memory buffer = new string(length);\\n uint256 ptr;\\n /// @solidity memory-safe-assembly\\n assembly {\\n ptr := add(buffer, add(32, length))\\n }\\n while (true) {\\n ptr--;\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\\n }\\n value /= 10;\\n if (value == 0) break;\\n }\\n return buffer;\\n }\\n }\\n\\n /**\\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\\n */\\n function toString(int256 value) internal pure returns (string memory) {\\n return string(abi.encodePacked(value < 0 ? \\\"-\\\" : \\\"\\\", toString(SignedMath.abs(value))));\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n return toHexString(value, Math.log256(value) + 1);\\n }\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n\\n /**\\n * @dev Returns true if the two strings are equal.\\n */\\n function equal(string memory a, string memory b) internal pure returns (bool) {\\n return keccak256(bytes(a)) == keccak256(bytes(b));\\n }\\n}\\n\",\"keccak256\":\"0x3088eb2868e8d13d89d16670b5f8612c4ab9ff8956272837d8e90106c59c14a0\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Strings.sol\\\";\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSA {\\n enum RecoverError {\\n NoError,\\n InvalidSignature,\\n InvalidSignatureLength,\\n InvalidSignatureS,\\n InvalidSignatureV // Deprecated in v4.8\\n }\\n\\n function _throwError(RecoverError error) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert(\\\"ECDSA: invalid signature\\\");\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert(\\\"ECDSA: invalid signature length\\\");\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert(\\\"ECDSA: invalid signature 's' value\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature` or error string. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n *\\n * Documentation for signature generation:\\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n return tryRecover(hash, v, r, s);\\n } else {\\n return (address(0), RecoverError.InvalidSignatureLength);\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature`. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, signature);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\\n uint8 v = uint8((uint256(vs) >> 255) + 27);\\n return tryRecover(hash, v, r, s);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n *\\n * _Available since v4.2._\\n */\\n function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\\n // the valid range for s in (301): 0 < s < secp256k1n \\u00f7 2 + 1, and for v in (302): v \\u2208 {27, 28}. Most\\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\\n //\\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\\n // these malleable signatures as well.\\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n return (address(0), RecoverError.InvalidSignatureS);\\n }\\n\\n // If the signature is valid (and not malleable), return the signer address\\n address signer = ecrecover(hash, v, r, s);\\n if (signer == address(0)) {\\n return (address(0), RecoverError.InvalidSignature);\\n }\\n\\n return (signer, RecoverError.NoError);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore(0x00, \\\"\\\\x19Ethereum Signed Message:\\\\n32\\\")\\n mstore(0x1c, hash)\\n message := keccak256(0x00, 0x3c)\\n }\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from `s`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n\\\", Strings.toString(s.length), s));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Typed Data, created from a\\n * `domainSeparator` and a `structHash`. This produces hash corresponding\\n * to the one signed with the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n * JSON-RPC method as part of EIP-712.\\n *\\n * See {recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n let ptr := mload(0x40)\\n mstore(ptr, \\\"\\\\x19\\\\x01\\\")\\n mstore(add(ptr, 0x02), domainSeparator)\\n mstore(add(ptr, 0x22), structHash)\\n data := keccak256(ptr, 0x42)\\n }\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Data with intended validator, created from a\\n * `validator` and `data` according to the version 0 of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x00\\\", validator, data));\\n }\\n}\\n\",\"keccak256\":\"0x809bc3edb4bcbef8263fa616c1b60ee0004b50a8a1bfa164d8f57fd31f520c58\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n enum Rounding {\\n Down, // Toward negative infinity\\n Up, // Toward infinity\\n Zero // Toward zero\\n }\\n\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow.\\n return (a & b) + (a ^ b) / 2;\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a == 0 ? 0 : (a - 1) / b + 1;\\n }\\n\\n /**\\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\\n * with further edits by Uniswap Labs also under MIT license.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\\n unchecked {\\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2^256 + prod0.\\n uint256 prod0; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division.\\n if (prod1 == 0) {\\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\\n // The surrounding unchecked block does not change this fact.\\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\\n return prod0 / denominator;\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n require(denominator > prod1, \\\"Math: mulDiv overflow\\\");\\n\\n ///////////////////////////////////////////////\\n // 512 by 256 division.\\n ///////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0].\\n uint256 remainder;\\n assembly {\\n // Compute remainder using mulmod.\\n remainder := mulmod(x, y, denominator)\\n\\n // Subtract 256 bit number from 512 bit number.\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\\n // See https://cs.stackexchange.com/q/138556/92363.\\n\\n // Does not overflow because the denominator cannot be zero at this stage in the function.\\n uint256 twos = denominator & (~denominator + 1);\\n assembly {\\n // Divide denominator by twos.\\n denominator := div(denominator, twos)\\n\\n // Divide [prod1 prod0] by twos.\\n prod0 := div(prod0, twos)\\n\\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\\n twos := add(div(sub(0, twos), twos), 1)\\n }\\n\\n // Shift in bits from prod1 into prod0.\\n prod0 |= prod1 * twos;\\n\\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\\n // four bits. That is, denominator * inv = 1 mod 2^4.\\n uint256 inverse = (3 * denominator) ^ 2;\\n\\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\\n // in modular arithmetic, doubling the correct bits in each step.\\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\\n\\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inverse;\\n return result;\\n }\\n }\\n\\n /**\\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\\n uint256 result = mulDiv(x, y, denominator);\\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\\n result += 1;\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\\n *\\n * Inspired by Henry S. Warren, Jr.'s \\\"Hacker's Delight\\\" (Chapter 11).\\n */\\n function sqrt(uint256 a) internal pure returns (uint256) {\\n if (a == 0) {\\n return 0;\\n }\\n\\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\\n //\\n // We know that the \\\"msb\\\" (most significant bit) of our target number `a` is a power of 2 such that we have\\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\\n //\\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\\n // \\u2192 `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\\n // \\u2192 `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\\n //\\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\\n uint256 result = 1 << (log2(a) >> 1);\\n\\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\\n // into the expected uint128 result.\\n unchecked {\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n return min(result, a / result);\\n }\\n }\\n\\n /**\\n * @notice Calculates sqrt(a), following the selected rounding direction.\\n */\\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = sqrt(a);\\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 2, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 128;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 64;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 32;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 16;\\n }\\n if (value >> 8 > 0) {\\n value >>= 8;\\n result += 8;\\n }\\n if (value >> 4 > 0) {\\n value >>= 4;\\n result += 4;\\n }\\n if (value >> 2 > 0) {\\n value >>= 2;\\n result += 2;\\n }\\n if (value >> 1 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log2(value);\\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 10, rounded down, of a positive value.\\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 + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 256, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n *\\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\\n */\\n function log256(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 16;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 8;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 4;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 2;\\n }\\n if (value >> 8 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log256(value);\\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe4455ac1eb7fc497bb7402579e7b4d64d928b846fce7d2b6fde06d366f21c2b3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\\n * checks.\\n *\\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\\n * easily result in undesired exploitation or bugs, since developers usually\\n * assume that overflows raise errors. `SafeCast` restores this intuition by\\n * reverting the transaction when such an operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n *\\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\\n * all math on `uint256` and `int256` and then downcasting.\\n */\\nlibrary SafeCast {\\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 * _Available since v4.7._\\n */\\n function toUint248(uint256 value) internal pure returns (uint248) {\\n require(value <= type(uint248).max, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint240(uint256 value) internal pure returns (uint240) {\\n require(value <= type(uint240).max, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint232(uint256 value) internal pure returns (uint232) {\\n require(value <= type(uint232).max, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint224(uint256 value) internal pure returns (uint224) {\\n require(value <= type(uint224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint216(uint256 value) internal pure returns (uint216) {\\n require(value <= type(uint216).max, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint208(uint256 value) internal pure returns (uint208) {\\n require(value <= type(uint208).max, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint200(uint256 value) internal pure returns (uint200) {\\n require(value <= type(uint200).max, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint192(uint256 value) internal pure returns (uint192) {\\n require(value <= type(uint192).max, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint184(uint256 value) internal pure returns (uint184) {\\n require(value <= type(uint184).max, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint176(uint256 value) internal pure returns (uint176) {\\n require(value <= type(uint176).max, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint168(uint256 value) internal pure returns (uint168) {\\n require(value <= type(uint168).max, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint160(uint256 value) internal pure returns (uint160) {\\n require(value <= type(uint160).max, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint152(uint256 value) internal pure returns (uint152) {\\n require(value <= type(uint152).max, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint144(uint256 value) internal pure returns (uint144) {\\n require(value <= type(uint144).max, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint136(uint256 value) internal pure returns (uint136) {\\n require(value <= type(uint136).max, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint128(uint256 value) internal pure returns (uint128) {\\n require(value <= type(uint128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint120(uint256 value) internal pure returns (uint120) {\\n require(value <= type(uint120).max, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint112(uint256 value) internal pure returns (uint112) {\\n require(value <= type(uint112).max, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint104(uint256 value) internal pure returns (uint104) {\\n require(value <= type(uint104).max, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint96(uint256 value) internal pure returns (uint96) {\\n require(value <= type(uint96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint88(uint256 value) internal pure returns (uint88) {\\n require(value <= type(uint88).max, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint80(uint256 value) internal pure returns (uint80) {\\n require(value <= type(uint80).max, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint72(uint256 value) internal pure returns (uint72) {\\n require(value <= type(uint72).max, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint64(uint256 value) internal pure returns (uint64) {\\n require(value <= type(uint64).max, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint56(uint256 value) internal pure returns (uint56) {\\n require(value <= type(uint56).max, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint48(uint256 value) internal pure returns (uint48) {\\n require(value <= type(uint48).max, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint40(uint256 value) internal pure returns (uint40) {\\n require(value <= type(uint40).max, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint32(uint256 value) internal pure returns (uint32) {\\n require(value <= type(uint32).max, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint24(uint256 value) internal pure returns (uint24) {\\n require(value <= type(uint24).max, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint16(uint256 value) internal pure returns (uint16) {\\n require(value <= type(uint16).max, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint8(uint256 value) internal pure returns (uint8) {\\n require(value <= type(uint8).max, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\n */\\n function toUint256(int256 value) internal pure returns (uint256) {\\n require(value >= 0, \\\"SafeCast: value must be positive\\\");\\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 * _Available since v4.7._\\n */\\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\\n downcasted = int248(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\\n downcasted = int240(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\\n downcasted = int232(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\\n downcasted = int224(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\\n downcasted = int216(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\\n downcasted = int208(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\\n downcasted = int200(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\\n downcasted = int192(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\\n downcasted = int184(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\\n downcasted = int176(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\\n downcasted = int168(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\\n downcasted = int160(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\\n downcasted = int152(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\\n downcasted = int144(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\\n downcasted = int136(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\\n downcasted = int128(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\\n downcasted = int120(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\\n downcasted = int112(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\\n downcasted = int104(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\\n downcasted = int96(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\\n downcasted = int88(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\\n downcasted = int80(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\\n downcasted = int72(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\\n downcasted = int64(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\\n downcasted = int56(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\\n downcasted = int48(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\\n downcasted = int40(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\\n downcasted = int32(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\\n downcasted = int24(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\\n downcasted = int16(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\\n downcasted = int8(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\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 require(value <= uint256(type(int256).max), \\\"SafeCast: value doesn't fit in an int256\\\");\\n return int256(value);\\n }\\n}\\n\",\"keccak256\":\"0x52a8cfb0f5239d11b457dcdd1b326992ef672714ca8da71a157255bddd13f3ad\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SignedMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard signed math utilities missing in the Solidity language.\\n */\\nlibrary SignedMath {\\n /**\\n * @dev Returns the largest of two signed numbers.\\n */\\n function max(int256 a, int256 b) internal pure returns (int256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two signed numbers.\\n */\\n function min(int256 a, int256 b) internal pure returns (int256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two signed numbers without overflow.\\n * The result is rounded towards zero.\\n */\\n function average(int256 a, int256 b) internal pure returns (int256) {\\n // Formula from the book \\\"Hacker's Delight\\\"\\n int256 x = (a & b) + ((a ^ b) >> 1);\\n return x + (int256(uint256(x) >> 255) & (a ^ b));\\n }\\n\\n /**\\n * @dev Returns the absolute unsigned value of a signed value.\\n */\\n function abs(int256 n) internal pure returns (uint256) {\\n unchecked {\\n // must be unchecked in order to support `n = type(int256).min`\\n return uint256(n >= 0 ? n : -n);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf92515413956f529d95977adc9b0567d583c6203fc31ab1c23824c35187e3ddc\",\"license\":\"MIT\"},\"contracts/aa-4337/core/BaseAccount.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-empty-blocks */\\n\\nimport \\\"../interfaces/IAccount.sol\\\";\\nimport \\\"../interfaces/IEntryPoint.sol\\\";\\nimport \\\"./Helpers.sol\\\";\\n\\n/**\\n * Basic account implementation.\\n * this contract provides the basic logic for implementing the IAccount interface - validateUserOp\\n * specific account implementation should inherit it and provide the account-specific logic\\n */\\nabstract contract BaseAccount is IAccount {\\n using UserOperationLib for UserOperation;\\n\\n //return value in case of signature failure, with no time-range.\\n // equivalent to _packValidationData(true,0,0);\\n uint256 internal constant SIG_VALIDATION_FAILED = 1;\\n\\n /**\\n * Return the account nonce.\\n * This method returns the next sequential nonce.\\n * For a nonce of a specific key, use `entrypoint.getNonce(account, key)`\\n */\\n function getNonce() public view virtual returns (uint256) {\\n return entryPoint().getNonce(address(this), 0);\\n }\\n\\n /**\\n * return the entryPoint used by this account.\\n * subclass should return the current entryPoint used by this account.\\n */\\n function entryPoint() public view virtual returns (IEntryPoint);\\n\\n /**\\n * Validate user's signature and nonce.\\n * subclass doesn't need to override this method. Instead, it should override the specific internal validation methods.\\n */\\n function validateUserOp(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n uint256 missingAccountFunds\\n ) external virtual override returns (uint256 validationData) {\\n _requireFromEntryPoint();\\n validationData = _validateSignature(userOp, userOpHash);\\n _validateNonce(userOp.nonce);\\n _payPrefund(missingAccountFunds);\\n }\\n\\n /**\\n * ensure the request comes from the known entrypoint.\\n */\\n function _requireFromEntryPoint() internal view virtual {\\n require(\\n msg.sender == address(entryPoint()),\\n \\\"account: not from EntryPoint\\\"\\n );\\n }\\n\\n /**\\n * validate the signature is valid for this message.\\n * @param userOp validate the userOp.signature field\\n * @param userOpHash convenient field: the hash of the request, to check the signature against\\n * (also hashes the entrypoint and chain id)\\n * @return validationData signature and time-range of this operation\\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\\n * otherwise, an address of an \\\"authorizer\\\" contract.\\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \\\"indefinite\\\"\\n * <6-byte> validAfter - first timestamp this operation is valid\\n * If the account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\\n */\\n function _validateSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) internal virtual returns (uint256 validationData);\\n\\n /**\\n * Validate the nonce of the UserOperation.\\n * This method may validate the nonce requirement of this account.\\n * e.g.\\n * To limit the nonce to use sequenced UserOps only (no \\\"out of order\\\" UserOps):\\n * `require(nonce < type(uint64).max)`\\n * For a hypothetical account that *requires* the nonce to be out-of-order:\\n * `require(nonce & type(uint64).max == 0)`\\n *\\n * The actual nonce uniqueness is managed by the EntryPoint, and thus no other\\n * action is needed by the account itself.\\n *\\n * @param nonce to validate\\n *\\n * solhint-disable-next-line no-empty-blocks\\n */\\n function _validateNonce(uint256 nonce) internal view virtual {}\\n\\n /**\\n * sends to the entrypoint (msg.sender) the missing funds for this transaction.\\n * subclass MAY override this method for better funds management\\n * (e.g. send to the entryPoint more than the minimum required, so that in future transactions\\n * it will not be required to send again)\\n * @param missingAccountFunds the minimum value this method should send the entrypoint.\\n * this value MAY be zero, in case there is enough deposit, or the userOp has a paymaster.\\n */\\n function _payPrefund(uint256 missingAccountFunds) internal virtual {\\n if (missingAccountFunds != 0) {\\n (bool success, ) = payable(msg.sender).call{\\n value: missingAccountFunds,\\n gas: type(uint256).max\\n }(\\\"\\\");\\n (success);\\n //ignore failure (its EntryPoint's job to verify, not account.)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa0dcc386b0f04711db3e394fb50e55a3b3b1a4d19fac1f10895844e1aa4e3d5c\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/core/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable no-inline-assembly */\\n\\n/**\\n * returned data from validateUserOp.\\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\\n * @param aggregator - address(0) - the account validated the signature by itself.\\n * address(1) - the account failed to validate the signature.\\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\\n * @param validAfter - this UserOp is valid only after this timestamp.\\n * @param validaUntil - this UserOp is valid only up to this timestamp.\\n */\\nstruct ValidationData {\\n address aggregator;\\n uint48 validAfter;\\n uint48 validUntil;\\n}\\n\\n//extract sigFailed, validAfter, validUntil.\\n// also convert zero validUntil to type(uint48).max\\nfunction _parseValidationData(\\n uint validationData\\n) pure returns (ValidationData memory data) {\\n address aggregator = address(uint160(validationData));\\n uint48 validUntil = uint48(validationData >> 160);\\n if (validUntil == 0) {\\n validUntil = type(uint48).max;\\n }\\n uint48 validAfter = uint48(validationData >> (48 + 160));\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n// intersect account and paymaster ranges.\\nfunction _intersectTimeRange(\\n uint256 validationData,\\n uint256 paymasterValidationData\\n) pure returns (ValidationData memory) {\\n ValidationData memory accountValidationData = _parseValidationData(\\n validationData\\n );\\n ValidationData memory pmValidationData = _parseValidationData(\\n paymasterValidationData\\n );\\n address aggregator = accountValidationData.aggregator;\\n if (aggregator == address(0)) {\\n aggregator = pmValidationData.aggregator;\\n }\\n uint48 validAfter = accountValidationData.validAfter;\\n uint48 validUntil = accountValidationData.validUntil;\\n uint48 pmValidAfter = pmValidationData.validAfter;\\n uint48 pmValidUntil = pmValidationData.validUntil;\\n\\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp\\n * @param data - the ValidationData to pack\\n */\\nfunction _packValidationData(\\n ValidationData memory data\\n) pure returns (uint256) {\\n return\\n uint160(data.aggregator) |\\n (uint256(data.validUntil) << 160) |\\n (uint256(data.validAfter) << (160 + 48));\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp, when not using an aggregator\\n * @param sigFailed - true for signature failure, false for success\\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\\n * @param validAfter first timestamp this UserOperation is valid\\n */\\nfunction _packValidationData(\\n bool sigFailed,\\n uint48 validUntil,\\n uint48 validAfter\\n) pure returns (uint256) {\\n return\\n (sigFailed ? 1 : 0) |\\n (uint256(validUntil) << 160) |\\n (uint256(validAfter) << (160 + 48));\\n}\\n\\n/**\\n * keccak function over calldata.\\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\\n */\\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\\n assembly {\\n let mem := mload(0x40)\\n let len := data.length\\n calldatacopy(mem, data.offset, len)\\n ret := keccak256(mem, len)\\n }\\n}\\n\",\"keccak256\":\"0xa79f06cd158ecb8c0da95493a2f348933b8627a63e228b99738bff3aa107942d\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAccount.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\ninterface IAccount {\\n /**\\n * Validate user's signature and nonce\\n * the entryPoint will make the call to the recipient only if this validation call returns successfully.\\n * signature failure should be reported by returning SIG_VALIDATION_FAILED (1).\\n * This allows making a \\\"simulation call\\\" without a valid signature\\n * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure.\\n *\\n * @dev Must validate caller is the entryPoint.\\n * Must validate the signature and nonce\\n * @param userOp the operation that is about to be executed.\\n * @param userOpHash hash of the user's request data. can be used as the basis for signature.\\n * @param missingAccountFunds missing funds on the account's deposit in the entrypoint.\\n * This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call.\\n * The excess is left as a deposit in the entrypoint, for future calls.\\n * can be withdrawn anytime using \\\"entryPoint.withdrawTo()\\\"\\n * In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero.\\n * @return validationData packaged ValidationData structure. use `_packValidationData` and `_unpackValidationData` to encode and decode\\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\\n * otherwise, an address of an \\\"authorizer\\\" contract.\\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \\\"indefinite\\\"\\n * <6-byte> validAfter - first timestamp this operation is valid\\n * If an account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\\n */\\n function validateUserOp(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n uint256 missingAccountFunds\\n ) external returns (uint256 validationData);\\n}\\n\",\"keccak256\":\"0xcbc4b0973cf954c5895b7796335f651fbfcfb55f67dfa789a3d354f8e23c4f2b\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAggregator.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\n/**\\n * Aggregated Signatures validator.\\n */\\ninterface IAggregator {\\n /**\\n * validate aggregated signature.\\n * revert if the aggregated signature does not match the given list of operations.\\n */\\n function validateSignatures(\\n UserOperation[] calldata userOps,\\n bytes calldata signature\\n ) external view;\\n\\n /**\\n * validate signature of a single userOp\\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\\n * @param userOp the userOperation received from the user.\\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\\n * (usually empty, unless account and aggregator support some kind of \\\"multisig\\\"\\n */\\n function validateUserOpSignature(\\n UserOperation calldata userOp\\n ) external view returns (bytes memory sigForUserOp);\\n\\n /**\\n * aggregate multiple signatures into a single value.\\n * This method is called off-chain to calculate the signature to pass with handleOps()\\n * bundler MAY use optimized custom code perform this aggregation\\n * @param userOps array of UserOperations to collect the signatures from.\\n * @return aggregatedSignature the aggregated signature\\n */\\n function aggregateSignatures(\\n UserOperation[] calldata userOps\\n ) external view returns (bytes memory aggregatedSignature);\\n}\\n\",\"keccak256\":\"0xdfdcd80568f037716674619b31be630fcd8316262f05a815b41d1e81782c966a\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IEntryPoint.sol\":{\"content\":\"/**\\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\\n ** Only one instance required on each chain.\\n **/\\n// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-inline-assembly */\\n/* solhint-disable reason-string */\\n\\nimport \\\"./UserOperation.sol\\\";\\nimport \\\"./IStakeManager.sol\\\";\\nimport \\\"./IAggregator.sol\\\";\\nimport \\\"./INonceManager.sol\\\";\\n\\ninterface IEntryPoint is IStakeManager, INonceManager {\\n /***\\n * An event emitted after each successful request\\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\\n * @param sender - the account that generates this request.\\n * @param paymaster - if non-null, the paymaster that pays for this request.\\n * @param nonce - the nonce value from the request.\\n * @param success - true if the sender transaction succeeded, false if reverted.\\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\\n */\\n event UserOperationEvent(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address indexed paymaster,\\n uint256 nonce,\\n bool success,\\n uint256 actualGasCost,\\n uint256 actualGasUsed\\n );\\n\\n /**\\n * account \\\"sender\\\" was deployed.\\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\\n * @param sender the account that is deployed\\n * @param factory the factory used to deploy this account (in the initCode)\\n * @param paymaster the paymaster used by this UserOp\\n */\\n event AccountDeployed(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address factory,\\n address paymaster\\n );\\n\\n /**\\n * An event emitted if the UserOperation \\\"callData\\\" reverted with non-zero length\\n * @param userOpHash the request unique identifier.\\n * @param sender the sender of this request\\n * @param nonce the nonce used in the request\\n * @param revertReason - the return bytes from the (reverted) call to \\\"callData\\\".\\n */\\n event UserOperationRevertReason(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n uint256 nonce,\\n bytes revertReason\\n );\\n\\n /**\\n * an event emitted by handleOps(), before starting the execution loop.\\n * any event emitted before this event, is part of the validation.\\n */\\n event BeforeExecution();\\n\\n /**\\n * signature aggregator used by the following UserOperationEvents within this bundle.\\n */\\n event SignatureAggregatorChanged(address indexed aggregator);\\n\\n /**\\n * a custom revert error of handleOps, to identify the offending op.\\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\\n * @param reason - revert reason\\n * The string starts with a unique code \\\"AAmn\\\", where \\\"m\\\" is \\\"1\\\" for factory, \\\"2\\\" for account and \\\"3\\\" for paymaster issues,\\n * so a failure can be attributed to the correct entity.\\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\\n */\\n error FailedOp(uint256 opIndex, string reason);\\n\\n /**\\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\\n */\\n error SignatureValidationFailed(address aggregator);\\n\\n /**\\n * Successful result from simulateValidation.\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n */\\n error ValidationResult(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo\\n );\\n\\n /**\\n * Successful result from simulateValidation, if the account returns a signature aggregator\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\\n * bundler MUST use it to verify the signature, or reject the UserOperation\\n */\\n error ValidationResultWithAggregation(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo,\\n AggregatorStakeInfo aggregatorInfo\\n );\\n\\n /**\\n * return value of getSenderAddress\\n */\\n error SenderAddressResult(address sender);\\n\\n /**\\n * return value of simulateHandleOp\\n */\\n error ExecutionResult(\\n uint256 preOpGas,\\n uint256 paid,\\n uint48 validAfter,\\n uint48 validUntil,\\n bool targetSuccess,\\n bytes targetResult\\n );\\n\\n //UserOps handled, per aggregator\\n struct UserOpsPerAggregator {\\n UserOperation[] userOps;\\n // aggregator address\\n IAggregator aggregator;\\n // aggregated signature\\n bytes signature;\\n }\\n\\n /**\\n * Execute a batch of UserOperation.\\n * no signature aggregator is used.\\n * if any account requires an aggregator (that is, it returned an aggregator when\\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\\n * @param ops the operations to execute\\n * @param beneficiary the address to receive the fees\\n */\\n function handleOps(\\n UserOperation[] calldata ops,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * Execute a batch of UserOperation with Aggregators\\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\\n * @param beneficiary the address to receive the fees\\n */\\n function handleAggregatedOps(\\n UserOpsPerAggregator[] calldata opsPerAggregator,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * generate a request Id - unique identifier for this request.\\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\\n */\\n function getUserOpHash(\\n UserOperation calldata userOp\\n ) external view returns (bytes32);\\n\\n /**\\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\\n * @param userOp the user operation to validate.\\n */\\n function simulateValidation(UserOperation calldata userOp) external;\\n\\n /**\\n * gas and return values during simulation\\n * @param preOpGas the gas used for validation (including preValidationGas)\\n * @param prefund the required prefund for this operation\\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\\n */\\n struct ReturnInfo {\\n uint256 preOpGas;\\n uint256 prefund;\\n bool sigFailed;\\n uint48 validAfter;\\n uint48 validUntil;\\n bytes paymasterContext;\\n }\\n\\n /**\\n * returned aggregated signature info.\\n * the aggregator returned by the account, and its current stake.\\n */\\n struct AggregatorStakeInfo {\\n address aggregator;\\n StakeInfo stakeInfo;\\n }\\n\\n /**\\n * Get counterfactual sender address.\\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\\n * this method always revert, and returns the address in SenderAddressResult error\\n * @param initCode the constructor code to be passed into the UserOperation.\\n */\\n function getSenderAddress(bytes memory initCode) external;\\n\\n /**\\n * simulate full execution of a UserOperation (including both validation and target execution)\\n * this method will always revert with \\\"ExecutionResult\\\".\\n * it performs full validation of the UserOperation, but ignores signature error.\\n * an optional target address is called after the userop succeeds, and its value is returned\\n * (before the entire call is reverted)\\n * Note that in order to collect the the success/failure of the target call, it must be executed\\n * with trace enabled to track the emitted events.\\n * @param op the UserOperation to simulate\\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\\n * are set to the return from that call.\\n * @param targetCallData callData to pass to target address\\n */\\n function simulateHandleOp(\\n UserOperation calldata op,\\n address target,\\n bytes calldata targetCallData\\n ) external;\\n}\\n\",\"keccak256\":\"0x9ccb1b188eda8bbf5f6c2d01bd83c3d8b2b04fcf745283051d31fe96d1d8e40f\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/INonceManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\ninterface INonceManager {\\n /**\\n * Return the next nonce for this sender.\\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\\n * But UserOp with different keys can come with arbitrary order.\\n *\\n * @param sender the account address\\n * @param key the high 192 bit of the nonce\\n * @return nonce a full nonce to pass for next UserOp with this sender.\\n */\\n function getNonce(\\n address sender,\\n uint192 key\\n ) external view returns (uint256 nonce);\\n\\n /**\\n * Manually increment the nonce of the sender.\\n * This method is exposed just for completeness..\\n * Account does NOT need to call it, neither during validation, nor elsewhere,\\n * as the EntryPoint will update the nonce regardless.\\n * Possible use-case is call it with various keys to \\\"initialize\\\" their nonces to one, so that future\\n * UserOperations will not pay extra for the first transaction with a given key.\\n */\\n function incrementNonce(uint192 key) external;\\n}\\n\",\"keccak256\":\"0xce478ad0fa0d18a3b785ac854623029e7ab463d05873dfaa365abfa1bf100912\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IStakeManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8.12;\\n\\n/**\\n * manage deposits and stakes.\\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\\n * stake is value locked for at least \\\"unstakeDelay\\\" by the staked entity.\\n */\\ninterface IStakeManager {\\n event Deposited(address indexed account, uint256 totalDeposit);\\n\\n event Withdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /// Emitted when stake or unstake delay are modified\\n event StakeLocked(\\n address indexed account,\\n uint256 totalStaked,\\n uint256 unstakeDelaySec\\n );\\n\\n /// Emitted once a stake is scheduled for withdrawal\\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\\n\\n event StakeWithdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /**\\n * @param deposit the entity's deposit\\n * @param staked true if this entity is staked.\\n * @param stake actual amount of ether staked for this entity.\\n * @param unstakeDelaySec minimum delay to withdraw the stake.\\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\\n * and the rest fit into a 2nd cell.\\n * 112 bit allows for 10^15 eth\\n * 48 bit for full timestamp\\n * 32 bit allows 150 years for unstake delay\\n */\\n struct DepositInfo {\\n uint112 deposit;\\n bool staked;\\n uint112 stake;\\n uint32 unstakeDelaySec;\\n uint48 withdrawTime;\\n }\\n\\n //API struct used by getStakeInfo and simulateValidation\\n struct StakeInfo {\\n uint256 stake;\\n uint256 unstakeDelaySec;\\n }\\n\\n /// @return info - full deposit information of given account\\n function getDepositInfo(\\n address account\\n ) external view returns (DepositInfo memory info);\\n\\n /// @return the deposit (for gas payment) of the account\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * add to the deposit of the given account\\n */\\n function depositTo(address account) external payable;\\n\\n /**\\n * add to the account's stake - amount and delay\\n * any pending unstake is first cancelled.\\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\\n */\\n function addStake(uint32 _unstakeDelaySec) external payable;\\n\\n /**\\n * attempt to unlock the stake.\\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\\n */\\n function unlockStake() external;\\n\\n /**\\n * withdraw from the (unlocked) stake.\\n * must first call unlockStake and wait for the unstakeDelay to pass\\n * @param withdrawAddress the address to send withdrawn value.\\n */\\n function withdrawStake(address payable withdrawAddress) external;\\n\\n /**\\n * withdraw from the deposit.\\n * @param withdrawAddress the address to send withdrawn value.\\n * @param withdrawAmount the amount to withdraw.\\n */\\n function withdrawTo(\\n address payable withdrawAddress,\\n uint256 withdrawAmount\\n ) external;\\n}\\n\",\"keccak256\":\"0xadcea606c9b7aafe6645441f2154a60f271330b0eee5292a632aa71c1672d546\",\"license\":\"GPL-3.0-only\"},\"contracts/aa-4337/interfaces/UserOperation.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable no-inline-assembly */\\n\\nimport {calldataKeccak} from \\\"../core/Helpers.sol\\\";\\n\\n/**\\n * User Operation struct\\n * @param sender the sender account of this request.\\n * @param nonce unique value the sender uses to verify it is not a replay.\\n * @param initCode if set, the account contract will be created by this constructor/\\n * @param callData the method call to execute on this account.\\n * @param callGasLimit the gas limit passed to the callData method call.\\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\\n * @param maxFeePerGas same as EIP-1559 gas parameter.\\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\\n */\\nstruct UserOperation {\\n address sender;\\n uint256 nonce;\\n bytes initCode;\\n bytes callData;\\n uint256 callGasLimit;\\n uint256 verificationGasLimit;\\n uint256 preVerificationGas;\\n uint256 maxFeePerGas;\\n uint256 maxPriorityFeePerGas;\\n bytes paymasterAndData;\\n bytes signature;\\n}\\n\\n/**\\n * Utility functions helpful when working with UserOperation structs.\\n */\\nlibrary UserOperationLib {\\n function getSender(\\n UserOperation calldata userOp\\n ) internal pure returns (address) {\\n address data;\\n //read sender from userOp, which is first userOp member (saves 800 gas...)\\n assembly {\\n data := calldataload(userOp)\\n }\\n return address(uint160(data));\\n }\\n\\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\\n // pay above what he signed for.\\n function gasPrice(\\n UserOperation calldata userOp\\n ) internal view returns (uint256) {\\n unchecked {\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n if (maxFeePerGas == maxPriorityFeePerGas) {\\n //legacy mode (for networks that don't support basefee opcode)\\n return maxFeePerGas;\\n }\\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\\n }\\n }\\n\\n function pack(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes memory ret) {\\n address sender = getSender(userOp);\\n uint256 nonce = userOp.nonce;\\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\\n bytes32 hashCallData = calldataKeccak(userOp.callData);\\n uint256 callGasLimit = userOp.callGasLimit;\\n uint256 verificationGasLimit = userOp.verificationGasLimit;\\n uint256 preVerificationGas = userOp.preVerificationGas;\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\\n\\n return\\n abi.encode(\\n sender,\\n nonce,\\n hashInitCode,\\n hashCallData,\\n callGasLimit,\\n verificationGasLimit,\\n preVerificationGas,\\n maxFeePerGas,\\n maxPriorityFeePerGas,\\n hashPaymasterAndData\\n );\\n }\\n\\n function hash(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes32) {\\n return keccak256(pack(userOp));\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n}\\n\",\"keccak256\":\"0x2429f5cc546bdee08c7e63858d0dda8491eaa3ab5194df884dc948c1154d2834\",\"license\":\"GPL-3.0\"},\"contracts/facets/AccountFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {ECDSA} from \\\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\\\";\\nimport {UserOperation} from \\\"../aa-4337/interfaces/UserOperation.sol\\\";\\nimport {IEntryPoint} from \\\"../aa-4337/interfaces/IEntryPoint.sol\\\";\\nimport {BaseAccount} from \\\"../aa-4337/core/BaseAccount.sol\\\";\\nimport {LibAppStorage, BarzStorage} from \\\"../libraries/LibAppStorage.sol\\\";\\nimport {LibDiamond} from \\\"../libraries/LibDiamond.sol\\\";\\nimport {LibLoupe} from \\\"../libraries/LibLoupe.sol\\\";\\nimport {IFacetRegistry} from \\\"../infrastructure/interfaces/IFacetRegistry.sol\\\";\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\nimport {IVerificationFacet} from \\\"./interfaces/IVerificationFacet.sol\\\";\\nimport {IERC1271} from \\\"../interfaces/ERC/IERC1271.sol\\\";\\nimport {IAccountFacet} from \\\"./interfaces/IAccountFacet.sol\\\";\\n\\n/**\\n * @title Account Facet\\n * @dev Account module contract that provides the account features and initialization of signer\\n * compatible with EIP-1271 & EIP-4337\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract AccountFacet is IAccountFacet, BarzStorage, BaseAccount {\\n using ECDSA for bytes32;\\n\\n /**\\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\\n */\\n constructor() {\\n LibAppStorage.enforceAccountInitialize();\\n }\\n\\n /**\\n * @notice Returns the address of EntryPoint contract registered to Barz account\\n */\\n function entryPoint() public view override returns (IEntryPoint) {\\n return s.entryPoint;\\n }\\n\\n /**\\n * @notice Initializes the initial storage of the Barz contract.\\n * @dev This method can only be called during the initialization or signature migration.\\n * If the proxy contract was created without initialization, anyone can call initialize.\\n * Barz calls initialize in constructor in an atomic transaction during deployment\\n * @param _verificationFacet Facet contract handling the verificationi\\n * @param _anEntryPoint Entrypoint contract defined in EIP-4337 handling the flow of UserOp\\n * @param _facetRegistry Registry of Facets that hold all facet information\\n * @param _defaultFallBackHandler Middleware contract for default facets\\n * @param _ownerPublicKey Bytes of owner public key\\n */\\n function initialize(\\n address _verificationFacet,\\n address _anEntryPoint,\\n address _facetRegistry,\\n address _defaultFallBackHandler,\\n bytes calldata _ownerPublicKey\\n ) public override returns (uint256 initSuccess) {\\n LibAppStorage.enforceAccountInitialize();\\n s.entryPoint = IEntryPoint(_anEntryPoint);\\n s.facetRegistry = IFacetRegistry(_facetRegistry);\\n LibDiamond.diamondStorage().defaultFallbackHandler = IDiamondLoupe(\\n _defaultFallBackHandler\\n );\\n\\n _cutDiamondAccountFacet(_verificationFacet);\\n\\n bytes memory initCall = abi.encodeWithSignature(\\n \\\"initializeSigner(bytes)\\\",\\n _ownerPublicKey\\n );\\n // Every Verification Facet should comply with initializeSigner(bytes)\\n // to be compatible with the Barz contract(for initialization)\\n (bool success, bytes memory result) = _verificationFacet.delegatecall(\\n initCall\\n );\\n if (!success || uint256(bytes32(result)) != 1) {\\n revert AccountFacet__InitializationFailure();\\n }\\n\\n initSuccess = 1;\\n emit AccountInitialized(s.entryPoint, _ownerPublicKey);\\n }\\n\\n function _cutDiamondAccountFacet(address _verificationFacet) internal {\\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](1);\\n\\n bytes4 ownerVerificationFuncSelector = IVerificationFacet(\\n _verificationFacet\\n ).validateOwnerSignatureSelector();\\n\\n bytes4[] memory verificationFunctionSelectors = new bytes4[](3);\\n verificationFunctionSelectors[0] = IERC1271.isValidSignature.selector;\\n verificationFunctionSelectors[1] = ownerVerificationFuncSelector;\\n verificationFunctionSelectors[2] = IVerificationFacet.owner.selector;\\n cut[0] = IDiamondCut.FacetCut({\\n facetAddress: _verificationFacet,\\n action: IDiamondCut.FacetCutAction.Add,\\n functionSelectors: verificationFunctionSelectors\\n });\\n\\n LibDiamond.diamondCut(cut, address(0), \\\"\\\");\\n }\\n\\n /**\\n * @notice Calls the destination with inputted calldata and value from EntryPoint\\n * @dev This method executes the calldata coming from the EntryPoint.\\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\\n * @param _dest Address of destination where the call will be forwarded to\\n * @param _value Amount of native coin the owner is willing to send(e.g. ETH, BNB)\\n * @param _func Bytes of calldata to execute in the destination address\\n */\\n function execute(\\n address _dest,\\n uint256 _value,\\n bytes calldata _func\\n ) external override onlyWhenUnlocked {\\n _requireFromEntryPoint();\\n address restrictionsFacet = LibDiamond.restrictionsFacet();\\n if (restrictionsFacet == address(0)) _call(_dest, _value, _func);\\n else _callWithRestrictions(_dest, _value, _func, restrictionsFacet);\\n }\\n\\n /**\\n * @notice Batch calls the destination with inputted calldata and value from EntryPoint\\n * @dev This method batch executes the calldata coming from the EntryPoint.\\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\\n * @param _dest Array of addresses of destination where the call will be forwarded to\\n * @param _value Array of amount of native coin the owner is willing to send(e.g. ETH, BNB)\\n * @param _func Array of bytes of calldata to execute in the destination address\\n */\\n function executeBatch(\\n address[] calldata _dest,\\n uint256[] calldata _value,\\n bytes[] calldata _func\\n ) external override onlyWhenUnlocked {\\n _requireFromEntryPoint();\\n if (_dest.length != _func.length || _dest.length != _value.length)\\n revert AccountFacet__InvalidArrayLength();\\n address restrictionsFacet = LibDiamond.restrictionsFacet();\\n if (restrictionsFacet == address(0)) {\\n for (uint256 i; i < _dest.length; ) {\\n _call(_dest[i], _value[i], _func[i]);\\n unchecked {\\n ++i;\\n }\\n }\\n } else {\\n for (uint256 i; i < _dest.length; ) {\\n _callWithRestrictions(\\n _dest[i],\\n _value[i],\\n _func[i],\\n restrictionsFacet\\n );\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n }\\n\\n /**\\n * @notice Validates the signature field of UserOperation\\n * @dev This method validates if the signature of UserOp is indeed valid by delegating the call to Verification Facet\\n * Barz makes a call to the pre-registered Verification Facet address in App Storage\\n * @param _userOp UserOperation from owner to be validated\\n * @param _userOpHash Hash of UserOperation given from the EntryPoint contract\\n */\\n function _validateSignature(\\n UserOperation calldata _userOp,\\n bytes32 _userOpHash\\n ) internal override returns (uint256 validationData) {\\n // Get Facet with Function Selector\\n address facet = LibLoupe.facetAddress(s.validateOwnerSignatureSelector);\\n if (facet == address(0))\\n revert AccountFacet__NonExistentVerificationFacet();\\n\\n // Make function call to VerificationFacet\\n bytes memory validateCall = abi.encodeWithSelector(\\n s.validateOwnerSignatureSelector,\\n _userOp,\\n _userOpHash\\n );\\n (bool success, bytes memory result) = facet.delegatecall(validateCall);\\n if (!success) revert AccountFacet__CallNotSuccessful();\\n validationData = uint256(bytes32(result));\\n if (validationData == 0) emit VerificationSuccess(_userOpHash);\\n else emit VerificationFailure(_userOpHash);\\n }\\n\\n /**\\n * @notice Calls the target with the inputted value and calldata\\n * @dev This method is the actual function in Barz that makes a call with an arbitrary owner-given data\\n * @param _target Address of the destination contract which the call is getting forwarded to\\n * @param _value Amount of Native coin the owner is wanting to make in this call\\n * @param _data Calldata the owner is forwarding together in the call e.g. Swap/Token Transfer\\n */\\n function _call(\\n address _target,\\n uint256 _value,\\n bytes memory _data\\n ) internal {\\n (bool success, bytes memory result) = _target.call{value: _value}(\\n _data\\n );\\n if (!success) {\\n assembly {\\n revert(add(result, 32), mload(result))\\n }\\n }\\n }\\n\\n /**\\n * @notice Calls the target with the inputted value and calldata together with restrictions check\\n * @dev This method is the actual function in Barz that makes a call with an arbitrary owner-given data\\n * @param _target Address of the destination contract which the call is getting forwarded to\\n * @param _value Amount of Native coin the owner is wanting to make in this call\\n * @param _data Calldata the owner is forwarding together in the call e.g. Swap/Token Transfer\\n * @param _restrictionsFacet Address of Facet to validate restrictions\\n */\\n function _callWithRestrictions(\\n address _target,\\n uint256 _value,\\n bytes memory _data,\\n address _restrictionsFacet\\n ) internal {\\n // NOTE: No restrictions facet, so restriction validation passes\\n if (_checkRestrictions(_restrictionsFacet, _target, _value, _data) != 0)\\n revert AccountFacet__RestrictionsFailure();\\n\\n (bool success, bytes memory result) = _target.call{value: _value}(\\n _data\\n );\\n if (!success) {\\n assembly {\\n revert(add(result, 32), mload(result))\\n }\\n }\\n }\\n\\n /**\\n * @notice Checks restrictions if the restrictions facet exists\\n * @dev This method checks if the restrictions facet exists and makes a verification call to an array of restrictions facet\\n * @param _facet Address that holds the restrictions logic\\n * @param _target Address the call is getting forwarded to\\n * @param _value Amount of native coin the call is sending together with the call\\n * @param _data Calldata to trigger execution in target address\\n */\\n function _checkRestrictions(\\n address _facet,\\n address _target,\\n uint256 _value,\\n bytes memory _data\\n ) internal returns (uint256 result) {\\n bytes memory call = abi.encodeWithSignature(\\n \\\"verifyRestrictions(address,address,uint256,bytes)\\\",\\n address(this),\\n _target,\\n _value,\\n _data\\n );\\n (bool success, bytes memory response) = _facet.delegatecall(call);\\n if (!success) revert AccountFacet__RestrictionsFailure();\\n result = uint256(bytes32(response));\\n }\\n}\\n\",\"keccak256\":\"0xcd92bcdd447010880f78e57e213123269c9e023adfc0a540608daa127d8649ca\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/facets/interfaces/IAccountFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IEntryPoint} from \\\"../../aa-4337/interfaces/IEntryPoint.sol\\\";\\n\\n/**\\n * @title Account Facet Interface\\n * @dev Interface of module contract that provides the account features and init/unitialization of signer\\n * compatible with EIP-1271 & EIP-4337\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IAccountFacet {\\n event AccountInitialized(\\n IEntryPoint indexed entryPoint,\\n bytes indexed ownerPublicKey\\n );\\n // NOTE: Added Below Event\\n event VerificationSuccess(bytes32);\\n event VerificationFailure(bytes32);\\n\\n error AccountFacet__InitializationFailure();\\n error AccountFacet__RestrictionsFailure();\\n error AccountFacet__NonExistentVerificationFacet();\\n error AccountFacet__CallNotSuccessful();\\n error AccountFacet__InvalidArrayLength();\\n\\n function initialize(\\n address verificationFacet,\\n address anEntryPoint,\\n address facetRegistry,\\n address _defaultFallBack,\\n bytes calldata _ownerPublicKey\\n ) external returns (uint256);\\n\\n function execute(address dest, uint256 value, bytes calldata func) external;\\n\\n function executeBatch(\\n address[] calldata dest,\\n uint256[] calldata value,\\n bytes[] calldata func\\n ) external;\\n}\\n\",\"keccak256\":\"0x74a9cb0b8f2f4a5148e366a401a0354426c536c012c025025d07cc25a4cd5382\",\"license\":\"Apache-2.0\"},\"contracts/facets/interfaces/IVerificationFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {UserOperation} from \\\"../../aa-4337/interfaces/UserOperation.sol\\\";\\n\\n/**\\n * @title Verification Facet Interface\\n * @dev Implements logic for user ops signature verification\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\ninterface IVerificationFacet {\\n event SignerInitialized(bytes);\\n event SignerUninitialized();\\n\\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\\n error VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\\n error VerificationFacet__InitializationFailure();\\n error VerificationFacet__InvalidFacetMapping();\\n\\n function initializeSigner(bytes memory) external returns (uint256);\\n\\n function uninitializeSigner() external returns (uint256);\\n\\n function validateOwnerSignatureSelector() external view returns (bytes4);\\n\\n function owner() external view returns (bytes memory);\\n\\n function isValidKeyType(bytes calldata) external view returns (bool);\\n\\n function validateOwnerSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x72bc370a1d1b5a6d6bde67f5026733fd8f6ba434bb90e73b0bd8627fb1579928\",\"license\":\"Apache-2.0\"},\"contracts/infrastructure/interfaces/IFacetRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Registry Interface\\n * @dev Interface for Facet Registry contract to keep track of facets & function selectors addable to user wallets\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IFacetRegistry {\\n struct FacetRegistryConfig {\\n bytes4[] selectors;\\n mapping(bytes4 => FacetInfo) info;\\n }\\n struct FacetInfo {\\n bool exists;\\n uint128 index;\\n }\\n\\n event FacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] facetSelectors\\n );\\n event FacetFunctionSelectorsRemoved(address facet, bytes4[] facetSelectors);\\n\\n error FacetRegistry__FacetSelectorAlreadyRegistered();\\n error FacetRegistry__UnregisteredFacetSelector();\\n\\n function registerFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function removeFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function areFacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external view returns (bool);\\n\\n function isFacetFunctionSelectorRegistered(\\n address facet,\\n bytes4 facetSelector\\n ) external view returns (bool);\\n\\n function getFacetFunctionSelectors(\\n address facet\\n ) external view returns (bytes4[] memory);\\n}\\n\",\"keccak256\":\"0x6e6dd2cab346ef7c31230740ec48d2925e4a9ab24c2f2fb268baaf408dcf02ef\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC1271 {\\n function isValidSignature(\\n bytes32 hash,\\n bytes memory signature\\n ) external view returns (bytes4);\\n}\\n\",\"keccak256\":\"0xcdddb7d5641c9d3f2432dec7fd13fddb9ae1480f25c76c21511e2fa16b8bd422\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibAppStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {SafeCast} from \\\"@openzeppelin/contracts/utils/math/SafeCast.sol\\\";\\nimport {IEntryPoint} from \\\"../aa-4337/interfaces/IEntryPoint.sol\\\";\\nimport {IFacetRegistry} from \\\"../infrastructure/interfaces/IFacetRegistry.sol\\\";\\n\\n/*\\n * @title App Storage\\n * @dev App storage for Barz contract to prevent storage collision\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Lock {\\n uint64 release;\\n bytes4 locker;\\n}\\n\\nstruct InitializersStorage {\\n // NOTE: initialized is a variable to make sure the initialization is only done once.\\n uint8 signerInitialized;\\n uint8 accountInitialized;\\n uint8 restrictionsInitialized;\\n}\\n\\nstruct AppStorage {\\n mapping(uint256 => InitializersStorage) initStorage;\\n uint8 signerMigration;\\n bytes4 validateOwnerSignatureSelector;\\n IEntryPoint entryPoint;\\n IFacetRegistry facetRegistry;\\n mapping(uint256 => Lock) locks;\\n}\\n\\nlibrary LibAppStorage {\\n error LibAppStorage__AccountAlreadyUninitialized();\\n error LibAppStorage__AccountMustBeUninitialized();\\n error LibAppStorage__SignerAlreadyUninitialized();\\n error LibAppStorage__SignerMustBeUninitialized();\\n\\n function appStorage() internal pure returns (AppStorage storage ds) {\\n assembly {\\n ds.slot := 0\\n }\\n }\\n\\n function setSignerUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerAlreadyUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 0;\\n }\\n\\n function getValidateOwnerSignatureSelector()\\n internal\\n view\\n returns (bytes4 selector)\\n {\\n selector = appStorage().validateOwnerSignatureSelector;\\n }\\n\\n function setValidateOwnerSignatureSelector(\\n bytes4 _validateOwnerSignatureSelector\\n ) internal {\\n appStorage()\\n .validateOwnerSignatureSelector = _validateOwnerSignatureSelector;\\n }\\n\\n function enforceSignerInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerMustBeUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 1;\\n }\\n\\n function enforceAccountInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].accountInitialized) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n s.initStorage[0].accountInitialized = 1;\\n }\\n\\n function initiateSignerMigration() internal {\\n appStorage().signerMigration = 1;\\n }\\n\\n function enforceSignerMigration() internal view {\\n if (1 != appStorage().signerMigration) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n }\\n\\n function finalizeSignerMigration() internal {\\n appStorage().signerMigration = 0;\\n }\\n\\n function setLock(uint256 _releaseAfter, bytes4 _locker) internal {\\n appStorage().locks[0] = Lock(SafeCast.toUint64(_releaseAfter), _locker);\\n }\\n\\n function enforceRestrictionsInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__SignerMustBeUninitialized();\\n s.initStorage[0].restrictionsInitialized = 1;\\n }\\n\\n function setRestrictionsUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__AccountAlreadyUninitialized();\\n s.initStorage[0].restrictionsInitialized = 0;\\n }\\n}\\n\\ncontract BarzStorage {\\n AppStorage internal s;\\n modifier onlyWhenUnlocked() {\\n require(\\n uint64(block.timestamp) >= s.locks[0].release,\\n \\\"Account Locked\\\"\\n );\\n _;\\n }\\n modifier onlyWhenLocked() {\\n require(\\n uint64(block.timestamp) < s.locks[0].release,\\n \\\"Account Unlocked\\\"\\n );\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x48524007862a6ce0e07f645950613ce6513ce073c37a109c75019683d42bae27\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\\n bytes4(keccak256(\\\"verifyRestrictions(address,address,uint256,bytes)\\\"));\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // Default Fallback Handler of the barz.\\n IDiamondLoupe defaultFallbackHandler;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function enforceIsSelf() internal view {\\n require(msg.sender == address(this), \\\"LibDiamond: Caller not self\\\");\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n\\n unchecked {\\n facetIndex++;\\n }\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n\\n function restrictionsFacet() internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(\\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2cabdc00de859c3a3170ce3bda5d0e5fd3933d47ce904fd1585f9818b02572f8\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\nimport {LibDiamond} from \\\"./LibDiamond.sol\\\";\\n\\n/**\\n * @title LibLoupe\\n * @dev Internal Library to provide utility feature for reading the state of diamond facets\\n * Originally from Diamond's implementation of Mudgen(author of EIP-2535)\\n */\\nlibrary LibLoupe {\\n /// @notice Gets all facets and their selectors.\\n /// @return facets_ Facet\\n function facets()\\n internal\\n view\\n returns (IDiamondLoupe.Facet[] memory facets_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facets_ = new IDiamondLoupe.Facet[](ds.selectorCount);\\n uint16[] memory numFacetSelectors = new uint16[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facets_[facetIndex].facetAddress == facetAddress_) {\\n facets_[facetIndex].functionSelectors[\\n numFacetSelectors[facetIndex]\\n ] = selector;\\n // probably will never have more than 256 functions from one facet contract\\n require(numFacetSelectors[facetIndex] < 255);\\n numFacetSelectors[facetIndex]++;\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facets_[numFacets].facetAddress = facetAddress_;\\n facets_[numFacets].functionSelectors = new bytes4[](\\n ds.selectorCount\\n );\\n facets_[numFacets].functionSelectors[0] = selector;\\n numFacetSelectors[numFacets] = 1;\\n numFacets++;\\n }\\n }\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n uint256 numSelectors = numFacetSelectors[facetIndex];\\n bytes4[] memory selectors = facets_[facetIndex].functionSelectors;\\n // setting the number of selectors\\n assembly {\\n mstore(selectors, numSelectors)\\n }\\n }\\n // setting the number of facets\\n assembly {\\n mstore(facets_, numFacets)\\n }\\n }\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return _facetFunctionSelectors The selectors associated with a facet address.\\n function facetFunctionSelectors(\\n address _facet\\n ) internal view returns (bytes4[] memory _facetFunctionSelectors) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n uint256 numSelectors;\\n _facetFunctionSelectors = new bytes4[](ds.selectorCount);\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facet = address(bytes20(ds.facets[selector]));\\n if (_facet == facet) {\\n _facetFunctionSelectors[numSelectors] = selector;\\n numSelectors++;\\n }\\n }\\n }\\n // Set the number of selectors in the array\\n assembly {\\n mstore(_facetFunctionSelectors, numSelectors)\\n }\\n }\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n internal\\n view\\n returns (address[] memory facetAddresses_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetAddresses_ = new address[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facetAddress_ == facetAddresses_[facetIndex]) {\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facetAddresses_[numFacets] = facetAddress_;\\n numFacets++;\\n }\\n }\\n // Set the number of facet addresses in the array\\n assembly {\\n mstore(facetAddresses_, numFacets)\\n }\\n }\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(LibDiamond.diamondStorage().facets[_functionSelector])\\n );\\n }\\n}\\n\",\"keccak256\":\"0x0b11439c3cc657095e15ec2241fdcf67204b14001357b612fc5db4ff9e760a5a\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5061001961001e565b61008e565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb554610100900460ff1615610070576040516338fc28cb60e01b815260040160405180910390fd5b600080805260209190915260409020805461ff001916610100179055565b6129b6806200009e6000396000f3fe608060405234801561001057600080fd5b50600436106100725760003560e01c8063b0d691fe11610050578063b0d691fe146100c5578063b61d27f61461010c578063d087d2881461011f57600080fd5b80633a871cdd1461007757806347e1da2a1461009d5780634a936417146100b2575b600080fd5b61008a610085366004611fb5565b610127565b6040519081526020015b60405180910390f35b6100b06100ab366004612055565b61014d565b005b61008a6100c036600461215a565b610450565b60015465010000000000900473ffffffffffffffffffffffffffffffffffffffff1660405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610094565b6100b061011a3660046121ce565b6106d0565b61008a61089d565b600061013161095e565b61013b8484610a16565b905061014682610c5d565b9392505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff9081164290911610156101f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064015b60405180910390fd5b6101fd61095e565b848114158061020c5750848314155b15610243576040517fdde5716100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006102b87fac87185d000000000000000000000000000000000000000000000000000000006000527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020527f6d9f2463c8c0d8cb8be556a773ab21d4321328909a1725f2ef7cae0c320e95da5460601c90565b905073ffffffffffffffffffffffffffffffffffffffff811661038f5760005b86811015610389576103818888838181106102f5576102f5612228565b905060200201602081019061030a9190612257565b87878481811061031c5761031c612228565b9050602002013586868581811061033557610335612228565b90506020028101906103479190612272565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610cc892505050565b6001016102d8565b50610447565b60005b868110156104455761043d8888838181106103af576103af612228565b90506020020160208101906103c49190612257565b8787848181106103d6576103d6612228565b905060200201358686858181106103ef576103ef612228565b90506020028101906104019190612272565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250889250610d45915050565b600101610392565b505b50505050505050565b600061045a610e0d565b6001805473ffffffffffffffffffffffffffffffffffffffff88811665010000000000027fffffffffffffff0000000000000000000000000000000000000000ffffffffff90921691909117909155600280548783167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216179091557f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd492380549287169290911691909117905561051187610eb3565b60008383604051602401610526929190612320565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fcd9b47e40000000000000000000000000000000000000000000000000000000017905251909150600090819073ffffffffffffffffffffffffffffffffffffffff8b16906105c8908590612360565b600060405180830381855af49150503d8060008114610603576040519150601f19603f3d011682016040523d82523d6000602084013e610608565b606091505b5091509150811580610623575061061e8161237c565b600114155b1561065a576040517f1602372100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60019350858560405161066e9291906123c1565b60405190819003812060015490916501000000000090910473ffffffffffffffffffffffffffffffffffffffff16907fd429ff0b972be4ae725700a373d05007287994e4c86cb83315b43ffa85b595fd90600090a35050509695505050505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610773576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064016101ec565b61077b61095e565b60006107f07fac87185d000000000000000000000000000000000000000000000000000000006000527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020527f6d9f2463c8c0d8cb8be556a773ab21d4321328909a1725f2ef7cae0c320e95da5460601c90565b905073ffffffffffffffffffffffffffffffffffffffff81166108535761084e858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610cc892505050565b610896565b610896858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250879250610d45915050565b5050505050565b60015460009065010000000000900473ffffffffffffffffffffffffffffffffffffffff166040517f35567e1a0000000000000000000000000000000000000000000000000000000081523060048201526000602482015273ffffffffffffffffffffffffffffffffffffffff91909116906335567e1a90604401602060405180830381865afa158015610935573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061095991906123d1565b905090565b60015465010000000000900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a14576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f6163636f756e743a206e6f742066726f6d20456e747279506f696e740000000060448201526064016101ec565b565b600154610100900460e01b7fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604081205460601c80610aab576040517f6eb2360200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600154604051600091610100900460e01b90610acd908790879060240161244e565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090506000808373ffffffffffffffffffffffffffffffffffffffff1683604051610b549190612360565b600060405180830381855af49150503d8060008114610b8f576040519150601f19603f3d011682016040523d82523d6000602084013e610b94565b606091505b509150915081610bd0576040517f3cbbb65000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610bd98161237c565b94506000859003610c1c576040518681527f19e781916118c373dadcb7776fae0a2dbb6bbdeedae143ce68031e22801ef8659060200160405180910390a1610c50565b6040518681527fbbfee2df7f28b899771f1015dc85d7840ff9f6162f23f6aa99686e8fbd2ce1319060200160405180910390a15b5050505092915050565b50565b8015610c5a5760405160009033907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90849084818181858888f193505050503d8060008114610896576040519150601f19603f3d011682016040523d82523d6000602084013e610896565b6000808473ffffffffffffffffffffffffffffffffffffffff168484604051610cf19190612360565b60006040518083038185875af1925050503d8060008114610d2e576040519150601f19603f3d011682016040523d82523d6000602084013e610d33565b606091505b50915091508161089657805160208201fd5b610d5181858585611117565b15610d88576040517f01f595e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000808573ffffffffffffffffffffffffffffffffffffffff168585604051610db19190612360565b60006040518083038185875af1925050503d8060008114610dee576040519150601f19603f3d011682016040523d82523d6000602084013e610df3565b606091505b509150915081610e0557805160208201fd5b505050505050565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb554610100900460ff1615610e78576040517f38fc28cb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100179055565b604080516001808252818301909252600091816020015b60408051606080820183526000808352602083015291810191909152815260200190600190039081610eca57905050905060008273ffffffffffffffffffffffffffffffffffffffff16633253960f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f6c9190612592565b604080516003808252608082019092529192506000919060208201606080368337019050509050631626ba7e60e01b81600081518110610fae57610fae612228565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681525050818160018151811061100e5761100e612228565b7fffffffff000000000000000000000000000000000000000000000000000000009092166020928302919091019091015280517f8da5cb5b00000000000000000000000000000000000000000000000000000000908290600290811061107657611076612228565b7fffffffff00000000000000000000000000000000000000000000000000000000909216602092830291909101820152604080516060810190915273ffffffffffffffffffffffffffffffffffffffff861681529081016000815260200182815250836000815181106110eb576110eb612228565b602002602001018190525061111183600060405180602001604052806000815250611264565b50505050565b60008030858585604051602401611131949392919061264d565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fac87185d0000000000000000000000000000000000000000000000000000000017905251909150600090819073ffffffffffffffffffffffffffffffffffffffff8916906111d3908590612360565b600060405180830381855af49150503d806000811461120e576040519150601f19603f3d011682016040523d82523d6000602084013e611213565b606091505b50915091508161124f576040517f01f595e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6112588161237c565b98975050505050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921547f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff8116908190600090600716156112d35750600381901c60009081526001840160205260409020545b60005b87518110156113505761134383838a84815181106112f6576112f6612228565b6020026020010151600001518b858151811061131457611314612228565b6020026020010151602001518c868151811061133257611332612228565b6020026020010151604001516113f0565b90935091506001016112d6565b50828214611389576002840180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff84161790555b60078216156113ab57600382901c600090815260018501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb6738787876040516113de93929190612696565b60405180910390a16104478686611e81565b600080807f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f905060008451116114a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f2063757400000000000000000000000000000000000000000060648201526084016101ec565b60008560028111156114bc576114bc6125d4565b0361168c576114e38660405180606001604052806024815260200161290d60249139611f7a565b60005b845181101561168657600085828151811061150357611503612228565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c156115d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c726561647920657869737473000000000000000000000060648201526084016101ec565b7fffffffff0000000000000000000000000000000000000000000000000000000080831660008181526020879052604090207fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608d901b168e17905560e060058e901b811692831c199c909c1690821c179a81900361166a5760038c901c600090815260018601602052604081209b909b555b8b6116748161282d565b9c5050600190930192506114e6915050565b50611e75565b60018560028111156116a0576116a06125d4565b03611990576116c78660405180606001604052806028815260200161295960289139611f7a565b60005b84518110156116865760008582815181106116e7576116e7612228565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c3081036117bc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4c69624469616d6f6e644375743a2043616e2774207265706c61636520696d6d60448201527f757461626c652066756e6374696f6e000000000000000000000000000000000060648201526084016101ec565b8973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611877576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e000000000000000060648201526084016101ec565b73ffffffffffffffffffffffffffffffffffffffff811661191a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e207468617420646f65736e2774206578697374000000000000000060648201526084016101ec565b507fffffffff0000000000000000000000000000000000000000000000000000000090911660009081526020849052604090206bffffffffffffffffffffffff919091167fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608a901b161790556001016116ca565b60028560028111156119a4576119a46125d4565b03611ded5773ffffffffffffffffffffffffffffffffffffffff861615611a4d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d75737420626520616464726573732830290000000000000000000060648201526084016101ec565b600388901c6007891660005b8651811015611dcd5760008a9003611a955782611a7581612865565b60008181526001870160205260409020549b50935060079250611aa39050565b81611a9f81612865565b9250505b6000806000808a8581518110611abb57611abb612228565b6020908102919091018101517fffffffff0000000000000000000000000000000000000000000000000000000081166000908152918a9052604090912054909150606081901c611b8d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e277420657869737400000000000000000060648201526084016101ec565b30606082901c03611c20576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e00000000000000000000000000000000000060648201526084016101ec565b600587901b8f901b94507fffffffff0000000000000000000000000000000000000000000000000000000080861690831614611cbe577fffffffff000000000000000000000000000000000000000000000000000000008516600090815260208a90526040902080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff83161790555b7fffffffff0000000000000000000000000000000000000000000000000000000091909116600090815260208990526040812055600381901c611fff16925060051b60e0169050858214611d53576000828152600188016020526040902080547fffffffff0000000000000000000000000000000000000000000000000000000080841c19909116908516831c179055611da4565b80837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c817fffffffff0000000000000000000000000000000000000000000000000000000060001b901c198e16179c505b84600003611dc257600086815260018801602052604081208190559c505b505050600101611a59565b5080611dda83600861289a565b611de491906128b7565b99505050611e75565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560448201527f74416374696f6e0000000000000000000000000000000000000000000000000060648201526084016101ec565b50959694955050505050565b73ffffffffffffffffffffffffffffffffffffffff8216611ea0575050565b611ec28260405180606001604052806028815260200161293160289139611f7a565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051611eea9190612360565b600060405180830381855af49150503d8060008114611f25576040519150601f19603f3d011682016040523d82523d6000602084013e611f2a565b606091505b50915091508161111157805115611f445780518082602001fd5b83836040517f192105d70000000000000000000000000000000000000000000000000000000081526004016101ec9291906128ca565b813b8181611111576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101ec91906128f9565b600080600060608486031215611fca57600080fd5b833567ffffffffffffffff811115611fe157600080fd5b84016101608187031215611ff457600080fd5b95602085013595506040909401359392505050565b60008083601f84011261201b57600080fd5b50813567ffffffffffffffff81111561203357600080fd5b6020830191508360208260051b850101111561204e57600080fd5b9250929050565b6000806000806000806060878903121561206e57600080fd5b863567ffffffffffffffff8082111561208657600080fd5b6120928a838b01612009565b909850965060208901359150808211156120ab57600080fd5b6120b78a838b01612009565b909650945060408901359150808211156120d057600080fd5b506120dd89828a01612009565b979a9699509497509295939492505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461211357600080fd5b919050565b60008083601f84011261212a57600080fd5b50813567ffffffffffffffff81111561214257600080fd5b60208301915083602082850101111561204e57600080fd5b60008060008060008060a0878903121561217357600080fd5b61217c876120ef565b955061218a602088016120ef565b9450612198604088016120ef565b93506121a6606088016120ef565b9250608087013567ffffffffffffffff8111156121c257600080fd5b6120dd89828a01612118565b600080600080606085870312156121e457600080fd5b6121ed856120ef565b935060208501359250604085013567ffffffffffffffff81111561221057600080fd5b61221c87828801612118565b95989497509550505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561226957600080fd5b610146826120ef565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126122a757600080fd5b83018035915067ffffffffffffffff8211156122c257600080fd5b60200191503681900382131561204e57600080fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b6020815260006123346020830184866122d7565b949350505050565b60005b8381101561235757818101518382015260200161233f565b50506000910152565b6000825161237281846020870161233c565b9190910192915050565b805160208083015191908110156123bb577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8160200360031b1b821691505b50919050565b8183823760009101908152919050565b6000602082840312156123e357600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261241f57600080fd5b830160208101925035905067ffffffffffffffff81111561243f57600080fd5b80360382131561204e57600080fd5b6040815261247c60408201612462856120ef565b73ffffffffffffffffffffffffffffffffffffffff169052565b60208301356060820152600061249560408501856123ea565b6101608060808601526124ad6101a0860183856122d7565b92506124bc60608801886123ea565b92507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0808786030160a08801526124f48585846122d7565b9450608089013560c088015260a089013560e0880152610100935060c089013584880152610120915060e089013582880152610140848a01358189015261253d838b018b6123ea565b955092508188870301848901526125558686856122d7565b9550612563818b018b6123ea565b9550935050808786030161018088015250506125808383836122d7565b93505050508260208301529392505050565b6000602082840312156125a457600080fd5b81517fffffffff000000000000000000000000000000000000000000000000000000008116811461014657600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6000815180845261261b81602086016020860161233c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600073ffffffffffffffffffffffffffffffffffffffff80871683528086166020840152508360408301526080606083015261268c6080830184612603565b9695505050505050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b848110156127c1577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808a8503018652815188850173ffffffffffffffffffffffffffffffffffffffff82511686528482015160038110612748577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b808310156127ac5783517fffffffff0000000000000000000000000000000000000000000000000000000016825292860192600192909201919086019061276a565b509785019795505050908201906001016126bf565b505073ffffffffffffffffffffffffffffffffffffffff8a169088015286810360408801526127f08189612603565b9a9950505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361285e5761285e6127fe565b5060010190565b600081612874576128746127fe565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b80820281158282048414176128b1576128b16127fe565b92915050565b808201808211156128b1576128b16127fe565b73ffffffffffffffffffffffffffffffffffffffff831681526040602082015260006123346040830184612603565b602081526000610146602083018461260356fe4c69624469616d6f6e644375743a2041646420666163657420686173206e6f20636f64654c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a205265706c61636520666163657420686173206e6f20636f6465a2646970667358221220a952f19990a20474450919a2df9ddff4430a71350892e0954f2bb073575ad64864736f6c63430008150033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100725760003560e01c8063b0d691fe11610050578063b0d691fe146100c5578063b61d27f61461010c578063d087d2881461011f57600080fd5b80633a871cdd1461007757806347e1da2a1461009d5780634a936417146100b2575b600080fd5b61008a610085366004611fb5565b610127565b6040519081526020015b60405180910390f35b6100b06100ab366004612055565b61014d565b005b61008a6100c036600461215a565b610450565b60015465010000000000900473ffffffffffffffffffffffffffffffffffffffff1660405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610094565b6100b061011a3660046121ce565b6106d0565b61008a61089d565b600061013161095e565b61013b8484610a16565b905061014682610c5d565b9392505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff9081164290911610156101f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064015b60405180910390fd5b6101fd61095e565b848114158061020c5750848314155b15610243576040517fdde5716100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006102b87fac87185d000000000000000000000000000000000000000000000000000000006000527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020527f6d9f2463c8c0d8cb8be556a773ab21d4321328909a1725f2ef7cae0c320e95da5460601c90565b905073ffffffffffffffffffffffffffffffffffffffff811661038f5760005b86811015610389576103818888838181106102f5576102f5612228565b905060200201602081019061030a9190612257565b87878481811061031c5761031c612228565b9050602002013586868581811061033557610335612228565b90506020028101906103479190612272565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610cc892505050565b6001016102d8565b50610447565b60005b868110156104455761043d8888838181106103af576103af612228565b90506020020160208101906103c49190612257565b8787848181106103d6576103d6612228565b905060200201358686858181106103ef576103ef612228565b90506020028101906104019190612272565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250889250610d45915050565b600101610392565b505b50505050505050565b600061045a610e0d565b6001805473ffffffffffffffffffffffffffffffffffffffff88811665010000000000027fffffffffffffff0000000000000000000000000000000000000000ffffffffff90921691909117909155600280548783167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216179091557f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd492380549287169290911691909117905561051187610eb3565b60008383604051602401610526929190612320565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fcd9b47e40000000000000000000000000000000000000000000000000000000017905251909150600090819073ffffffffffffffffffffffffffffffffffffffff8b16906105c8908590612360565b600060405180830381855af49150503d8060008114610603576040519150601f19603f3d011682016040523d82523d6000602084013e610608565b606091505b5091509150811580610623575061061e8161237c565b600114155b1561065a576040517f1602372100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60019350858560405161066e9291906123c1565b60405190819003812060015490916501000000000090910473ffffffffffffffffffffffffffffffffffffffff16907fd429ff0b972be4ae725700a373d05007287994e4c86cb83315b43ffa85b595fd90600090a35050509695505050505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610773576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064016101ec565b61077b61095e565b60006107f07fac87185d000000000000000000000000000000000000000000000000000000006000527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020527f6d9f2463c8c0d8cb8be556a773ab21d4321328909a1725f2ef7cae0c320e95da5460601c90565b905073ffffffffffffffffffffffffffffffffffffffff81166108535761084e858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610cc892505050565b610896565b610896858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250879250610d45915050565b5050505050565b60015460009065010000000000900473ffffffffffffffffffffffffffffffffffffffff166040517f35567e1a0000000000000000000000000000000000000000000000000000000081523060048201526000602482015273ffffffffffffffffffffffffffffffffffffffff91909116906335567e1a90604401602060405180830381865afa158015610935573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061095991906123d1565b905090565b60015465010000000000900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a14576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f6163636f756e743a206e6f742066726f6d20456e747279506f696e740000000060448201526064016101ec565b565b600154610100900460e01b7fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604081205460601c80610aab576040517f6eb2360200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600154604051600091610100900460e01b90610acd908790879060240161244e565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090506000808373ffffffffffffffffffffffffffffffffffffffff1683604051610b549190612360565b600060405180830381855af49150503d8060008114610b8f576040519150601f19603f3d011682016040523d82523d6000602084013e610b94565b606091505b509150915081610bd0576040517f3cbbb65000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610bd98161237c565b94506000859003610c1c576040518681527f19e781916118c373dadcb7776fae0a2dbb6bbdeedae143ce68031e22801ef8659060200160405180910390a1610c50565b6040518681527fbbfee2df7f28b899771f1015dc85d7840ff9f6162f23f6aa99686e8fbd2ce1319060200160405180910390a15b5050505092915050565b50565b8015610c5a5760405160009033907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90849084818181858888f193505050503d8060008114610896576040519150601f19603f3d011682016040523d82523d6000602084013e610896565b6000808473ffffffffffffffffffffffffffffffffffffffff168484604051610cf19190612360565b60006040518083038185875af1925050503d8060008114610d2e576040519150601f19603f3d011682016040523d82523d6000602084013e610d33565b606091505b50915091508161089657805160208201fd5b610d5181858585611117565b15610d88576040517f01f595e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000808573ffffffffffffffffffffffffffffffffffffffff168585604051610db19190612360565b60006040518083038185875af1925050503d8060008114610dee576040519150601f19603f3d011682016040523d82523d6000602084013e610df3565b606091505b509150915081610e0557805160208201fd5b505050505050565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb554610100900460ff1615610e78576040517f38fc28cb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100179055565b604080516001808252818301909252600091816020015b60408051606080820183526000808352602083015291810191909152815260200190600190039081610eca57905050905060008273ffffffffffffffffffffffffffffffffffffffff16633253960f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f6c9190612592565b604080516003808252608082019092529192506000919060208201606080368337019050509050631626ba7e60e01b81600081518110610fae57610fae612228565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681525050818160018151811061100e5761100e612228565b7fffffffff000000000000000000000000000000000000000000000000000000009092166020928302919091019091015280517f8da5cb5b00000000000000000000000000000000000000000000000000000000908290600290811061107657611076612228565b7fffffffff00000000000000000000000000000000000000000000000000000000909216602092830291909101820152604080516060810190915273ffffffffffffffffffffffffffffffffffffffff861681529081016000815260200182815250836000815181106110eb576110eb612228565b602002602001018190525061111183600060405180602001604052806000815250611264565b50505050565b60008030858585604051602401611131949392919061264d565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fac87185d0000000000000000000000000000000000000000000000000000000017905251909150600090819073ffffffffffffffffffffffffffffffffffffffff8916906111d3908590612360565b600060405180830381855af49150503d806000811461120e576040519150601f19603f3d011682016040523d82523d6000602084013e611213565b606091505b50915091508161124f576040517f01f595e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6112588161237c565b98975050505050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921547f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff8116908190600090600716156112d35750600381901c60009081526001840160205260409020545b60005b87518110156113505761134383838a84815181106112f6576112f6612228565b6020026020010151600001518b858151811061131457611314612228565b6020026020010151602001518c868151811061133257611332612228565b6020026020010151604001516113f0565b90935091506001016112d6565b50828214611389576002840180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff84161790555b60078216156113ab57600382901c600090815260018501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb6738787876040516113de93929190612696565b60405180910390a16104478686611e81565b600080807f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f905060008451116114a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f2063757400000000000000000000000000000000000000000060648201526084016101ec565b60008560028111156114bc576114bc6125d4565b0361168c576114e38660405180606001604052806024815260200161290d60249139611f7a565b60005b845181101561168657600085828151811061150357611503612228565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c156115d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c726561647920657869737473000000000000000000000060648201526084016101ec565b7fffffffff0000000000000000000000000000000000000000000000000000000080831660008181526020879052604090207fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608d901b168e17905560e060058e901b811692831c199c909c1690821c179a81900361166a5760038c901c600090815260018601602052604081209b909b555b8b6116748161282d565b9c5050600190930192506114e6915050565b50611e75565b60018560028111156116a0576116a06125d4565b03611990576116c78660405180606001604052806028815260200161295960289139611f7a565b60005b84518110156116865760008582815181106116e7576116e7612228565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c3081036117bc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4c69624469616d6f6e644375743a2043616e2774207265706c61636520696d6d60448201527f757461626c652066756e6374696f6e000000000000000000000000000000000060648201526084016101ec565b8973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611877576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e000000000000000060648201526084016101ec565b73ffffffffffffffffffffffffffffffffffffffff811661191a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e207468617420646f65736e2774206578697374000000000000000060648201526084016101ec565b507fffffffff0000000000000000000000000000000000000000000000000000000090911660009081526020849052604090206bffffffffffffffffffffffff919091167fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608a901b161790556001016116ca565b60028560028111156119a4576119a46125d4565b03611ded5773ffffffffffffffffffffffffffffffffffffffff861615611a4d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d75737420626520616464726573732830290000000000000000000060648201526084016101ec565b600388901c6007891660005b8651811015611dcd5760008a9003611a955782611a7581612865565b60008181526001870160205260409020549b50935060079250611aa39050565b81611a9f81612865565b9250505b6000806000808a8581518110611abb57611abb612228565b6020908102919091018101517fffffffff0000000000000000000000000000000000000000000000000000000081166000908152918a9052604090912054909150606081901c611b8d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e277420657869737400000000000000000060648201526084016101ec565b30606082901c03611c20576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e00000000000000000000000000000000000060648201526084016101ec565b600587901b8f901b94507fffffffff0000000000000000000000000000000000000000000000000000000080861690831614611cbe577fffffffff000000000000000000000000000000000000000000000000000000008516600090815260208a90526040902080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff83161790555b7fffffffff0000000000000000000000000000000000000000000000000000000091909116600090815260208990526040812055600381901c611fff16925060051b60e0169050858214611d53576000828152600188016020526040902080547fffffffff0000000000000000000000000000000000000000000000000000000080841c19909116908516831c179055611da4565b80837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c817fffffffff0000000000000000000000000000000000000000000000000000000060001b901c198e16179c505b84600003611dc257600086815260018801602052604081208190559c505b505050600101611a59565b5080611dda83600861289a565b611de491906128b7565b99505050611e75565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560448201527f74416374696f6e0000000000000000000000000000000000000000000000000060648201526084016101ec565b50959694955050505050565b73ffffffffffffffffffffffffffffffffffffffff8216611ea0575050565b611ec28260405180606001604052806028815260200161293160289139611f7a565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051611eea9190612360565b600060405180830381855af49150503d8060008114611f25576040519150601f19603f3d011682016040523d82523d6000602084013e611f2a565b606091505b50915091508161111157805115611f445780518082602001fd5b83836040517f192105d70000000000000000000000000000000000000000000000000000000081526004016101ec9291906128ca565b813b8181611111576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101ec91906128f9565b600080600060608486031215611fca57600080fd5b833567ffffffffffffffff811115611fe157600080fd5b84016101608187031215611ff457600080fd5b95602085013595506040909401359392505050565b60008083601f84011261201b57600080fd5b50813567ffffffffffffffff81111561203357600080fd5b6020830191508360208260051b850101111561204e57600080fd5b9250929050565b6000806000806000806060878903121561206e57600080fd5b863567ffffffffffffffff8082111561208657600080fd5b6120928a838b01612009565b909850965060208901359150808211156120ab57600080fd5b6120b78a838b01612009565b909650945060408901359150808211156120d057600080fd5b506120dd89828a01612009565b979a9699509497509295939492505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461211357600080fd5b919050565b60008083601f84011261212a57600080fd5b50813567ffffffffffffffff81111561214257600080fd5b60208301915083602082850101111561204e57600080fd5b60008060008060008060a0878903121561217357600080fd5b61217c876120ef565b955061218a602088016120ef565b9450612198604088016120ef565b93506121a6606088016120ef565b9250608087013567ffffffffffffffff8111156121c257600080fd5b6120dd89828a01612118565b600080600080606085870312156121e457600080fd5b6121ed856120ef565b935060208501359250604085013567ffffffffffffffff81111561221057600080fd5b61221c87828801612118565b95989497509550505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561226957600080fd5b610146826120ef565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126122a757600080fd5b83018035915067ffffffffffffffff8211156122c257600080fd5b60200191503681900382131561204e57600080fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b6020815260006123346020830184866122d7565b949350505050565b60005b8381101561235757818101518382015260200161233f565b50506000910152565b6000825161237281846020870161233c565b9190910192915050565b805160208083015191908110156123bb577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8160200360031b1b821691505b50919050565b8183823760009101908152919050565b6000602082840312156123e357600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261241f57600080fd5b830160208101925035905067ffffffffffffffff81111561243f57600080fd5b80360382131561204e57600080fd5b6040815261247c60408201612462856120ef565b73ffffffffffffffffffffffffffffffffffffffff169052565b60208301356060820152600061249560408501856123ea565b6101608060808601526124ad6101a0860183856122d7565b92506124bc60608801886123ea565b92507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0808786030160a08801526124f48585846122d7565b9450608089013560c088015260a089013560e0880152610100935060c089013584880152610120915060e089013582880152610140848a01358189015261253d838b018b6123ea565b955092508188870301848901526125558686856122d7565b9550612563818b018b6123ea565b9550935050808786030161018088015250506125808383836122d7565b93505050508260208301529392505050565b6000602082840312156125a457600080fd5b81517fffffffff000000000000000000000000000000000000000000000000000000008116811461014657600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6000815180845261261b81602086016020860161233c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600073ffffffffffffffffffffffffffffffffffffffff80871683528086166020840152508360408301526080606083015261268c6080830184612603565b9695505050505050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b848110156127c1577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808a8503018652815188850173ffffffffffffffffffffffffffffffffffffffff82511686528482015160038110612748577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b808310156127ac5783517fffffffff0000000000000000000000000000000000000000000000000000000016825292860192600192909201919086019061276a565b509785019795505050908201906001016126bf565b505073ffffffffffffffffffffffffffffffffffffffff8a169088015286810360408801526127f08189612603565b9a9950505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361285e5761285e6127fe565b5060010190565b600081612874576128746127fe565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b80820281158282048414176128b1576128b16127fe565b92915050565b808201808211156128b1576128b16127fe565b73ffffffffffffffffffffffffffffffffffffffff831681526040602082015260006123346040830184612603565b602081526000610146602083018461260356fe4c69624469616d6f6e644375743a2041646420666163657420686173206e6f20636f64654c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a205265706c61636520666163657420686173206e6f20636f6465a2646970667358221220a952f19990a20474450919a2df9ddff4430a71350892e0954f2bb073575ad64864736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "Account module contract that provides the account features and initialization of signer compatible with EIP-1271 & EIP-4337", + "kind": "dev", + "methods": { + "execute(address,uint256,bytes)": { + "details": "This method executes the calldata coming from the EntryPoint. Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)", + "params": { + "_dest": "Address of destination where the call will be forwarded to", + "_func": "Bytes of calldata to execute in the destination address", + "_value": "Amount of native coin the owner is willing to send(e.g. ETH, BNB)" + } + }, + "executeBatch(address[],uint256[],bytes[])": { + "details": "This method batch executes the calldata coming from the EntryPoint. Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)", + "params": { + "_dest": "Array of addresses of destination where the call will be forwarded to", + "_func": "Array of bytes of calldata to execute in the destination address", + "_value": "Array of amount of native coin the owner is willing to send(e.g. ETH, BNB)" + } + }, + "initialize(address,address,address,address,bytes)": { + "details": "This method can only be called during the initialization or signature migration. If the proxy contract was created without initialization, anyone can call initialize. Barz calls initialize in constructor in an atomic transaction during deployment", + "params": { + "_anEntryPoint": "Entrypoint contract defined in EIP-4337 handling the flow of UserOp", + "_defaultFallBackHandler": "Middleware contract for default facets", + "_facetRegistry": "Registry of Facets that hold all facet information", + "_ownerPublicKey": "Bytes of owner public key", + "_verificationFacet": "Facet contract handling the verificationi" + } + } + }, + "title": "Account Facet", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "constructor": { + "notice": "This constructor ensures that this contract can only be used as singleton for Proxy contracts" + }, + "entryPoint()": { + "notice": "Returns the address of EntryPoint contract registered to Barz account" + }, + "execute(address,uint256,bytes)": { + "notice": "Calls the destination with inputted calldata and value from EntryPoint" + }, + "executeBatch(address[],uint256[],bytes[])": { + "notice": "Batch calls the destination with inputted calldata and value from EntryPoint" + }, + "getNonce()": { + "notice": "Return the account nonce. This method returns the next sequential nonce. For a nonce of a specific key, use `entrypoint.getNonce(account, key)`" + }, + "initialize(address,address,address,address,bytes)": { + "notice": "Initializes the initial storage of the Barz contract." + }, + "validateUserOp((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256)": { + "notice": "Validate user's signature and nonce. subclass doesn't need to override this method. Instead, it should override the specific internal validation methods." + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 27866, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "s", + "offset": 0, + "slot": "0", + "type": "t_struct(AppStorage)27613_storage" + } + ], + "types": { + "t_bytes4": { + "encoding": "inplace", + "label": "bytes4", + "numberOfBytes": "4" + }, + "t_contract(IEntryPoint)12286": { + "encoding": "inplace", + "label": "contract IEntryPoint", + "numberOfBytes": "20" + }, + "t_contract(IFacetRegistry)26148": { + "encoding": "inplace", + "label": "contract IFacetRegistry", + "numberOfBytes": "20" + }, + "t_mapping(t_uint256,t_struct(InitializersStorage)27592_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => struct InitializersStorage)", + "numberOfBytes": "32", + "value": "t_struct(InitializersStorage)27592_storage" + }, + "t_mapping(t_uint256,t_struct(Lock)27585_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => struct Lock)", + "numberOfBytes": "32", + "value": "t_struct(Lock)27585_storage" + }, + "t_struct(AppStorage)27613_storage": { + "encoding": "inplace", + "label": "struct AppStorage", + "members": [ + { + "astId": 27597, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "initStorage", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_uint256,t_struct(InitializersStorage)27592_storage)" + }, + { + "astId": 27599, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "signerMigration", + "offset": 0, + "slot": "1", + "type": "t_uint8" + }, + { + "astId": 27601, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "validateOwnerSignatureSelector", + "offset": 1, + "slot": "1", + "type": "t_bytes4" + }, + { + "astId": 27604, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "entryPoint", + "offset": 5, + "slot": "1", + "type": "t_contract(IEntryPoint)12286" + }, + { + "astId": 27607, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "facetRegistry", + "offset": 0, + "slot": "2", + "type": "t_contract(IFacetRegistry)26148" + }, + { + "astId": 27612, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "locks", + "offset": 0, + "slot": "3", + "type": "t_mapping(t_uint256,t_struct(Lock)27585_storage)" + } + ], + "numberOfBytes": "128" + }, + "t_struct(InitializersStorage)27592_storage": { + "encoding": "inplace", + "label": "struct InitializersStorage", + "members": [ + { + "astId": 27587, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "signerInitialized", + "offset": 0, + "slot": "0", + "type": "t_uint8" + }, + { + "astId": 27589, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "accountInitialized", + "offset": 1, + "slot": "0", + "type": "t_uint8" + }, + { + "astId": 27591, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "restrictionsInitialized", + "offset": 2, + "slot": "0", + "type": "t_uint8" + } + ], + "numberOfBytes": "32" + }, + "t_struct(Lock)27585_storage": { + "encoding": "inplace", + "label": "struct Lock", + "members": [ + { + "astId": 27582, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "release", + "offset": 0, + "slot": "0", + "type": "t_uint64" + }, + { + "astId": 27584, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "locker", + "offset": 8, + "slot": "0", + "type": "t_bytes4" + } + ], + "numberOfBytes": "32" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint64": { + "encoding": "inplace", + "label": "uint64", + "numberOfBytes": "8" + }, + "t_uint8": { + "encoding": "inplace", + "label": "uint8", + "numberOfBytes": "1" + } + } + } +} \ No newline at end of file diff --git a/deployments/mainnet/BarzFactory.json b/deployments/mainnet/BarzFactory.json new file mode 100644 index 0000000..5a34037 --- /dev/null +++ b/deployments/mainnet/BarzFactory.json @@ -0,0 +1,318 @@ +{ + "address": "0x729c310186a57833f622630a16d13f710b83272a", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_accountFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_entryPoint", + "type": "address" + }, + { + "internalType": "address", + "name": "_facetRegistry", + "type": "address" + }, + { + "internalType": "address", + "name": "_defaultFallback", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "BarzDeployed", + "type": "event" + }, + { + "inputs": [], + "name": "accountFacet", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_verificationFacet", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_owner", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "_salt", + "type": "uint256" + } + ], + "name": "createAccount", + "outputs": [ + { + "internalType": "contract Barz", + "name": "barz", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "defaultFallback", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "entryPoint", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetRegistry", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_verificationFacet", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_owner", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "_salt", + "type": "uint256" + } + ], + "name": "getAddress", + "outputs": [ + { + "internalType": "address", + "name": "barzAddress", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_accountFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_verificationFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_entryPoint", + "type": "address" + }, + { + "internalType": "address", + "name": "_facetRegistry", + "type": "address" + }, + { + "internalType": "address", + "name": "_defaultFallback", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_ownerPublicKey", + "type": "bytes" + } + ], + "name": "getBytecode", + "outputs": [ + { + "internalType": "bytes", + "name": "barzBytecode", + "type": "bytes" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "getCreationCode", + "outputs": [ + { + "internalType": "bytes", + "name": "creationCode", + "type": "bytes" + } + ], + "stateMutability": "pure", + "type": "function" + } + ], + "transactionHash": "0x6a14ab46e9502b59f79296dfd164efbd45d049540b5d2fb4a323d53a17a76a67", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 167, + "gasUsed": "802000", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x8142924367f906e83a594a391046eeee926807541bae877c089a954d659a9100", + "transactionHash": "0x6a14ab46e9502b59f79296dfd164efbd45d049540b5d2fb4a323d53a17a76a67", + "logs": [], + "blockNumber": 19517150, + "cumulativeGasUsed": "12006466", + "status": 1, + "byzantium": true + }, + "args": [ + "0xFde53272dcd7938d16E031A6989753c321728332", + "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789", + "0xAfCb70e6e9514E2A15B23A01d2a9b9f7A34f2c33", + "0x2e7f1dAe1F3799d20f5c31bEFdc7A620f664728D" + ], + "numDeployments": 1, + "solcInputHash": "ad34345aa73d96f52b3e14df983b6b29", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_accountFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_entryPoint\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_facetRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_defaultFallback\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"BarzDeployed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"accountFacet\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_verificationFacet\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_owner\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_salt\",\"type\":\"uint256\"}],\"name\":\"createAccount\",\"outputs\":[{\"internalType\":\"contract Barz\",\"name\":\"barz\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"defaultFallback\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"entryPoint\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetRegistry\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_verificationFacet\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_owner\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_salt\",\"type\":\"uint256\"}],\"name\":\"getAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"barzAddress\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_accountFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_verificationFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_entryPoint\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_facetRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_defaultFallback\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_ownerPublicKey\",\"type\":\"bytes\"}],\"name\":\"getBytecode\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"barzBytecode\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCreationCode\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"creationCode\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"Contract to easily deploy Barz to a pre-computed address with a single call\",\"kind\":\"dev\",\"methods\":{\"constructor\":{\"params\":{\"_accountFacet\":\"Account Facet to be used to create Barz\",\"_defaultFallback\":\"Default Fallback Handler to be used to create Barz\",\"_entryPoint\":\"Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\",\"_facetRegistry\":\"Facet Registry to be used to create Barz\"}},\"createAccount(address,bytes,uint256)\":{\"params\":{\"_owner\":\"Public Key of the owner to initialize barz account\",\"_salt\":\"Salt used for deploying barz with create2\",\"_verificationFacet\":\"Address of verification facet used for creating the barz account\"},\"returns\":{\"barz\":\"Instance of Barz contract deployed with the given parameters\"}},\"getAddress(address,bytes,uint256)\":{\"params\":{\"_owner\":\"Public Key of the owner to initialize barz account\",\"_salt\":\"Salt used for deploying barz with create2\",\"_verificationFacet\":\"Address of verification facet used for creating the barz account\"},\"returns\":{\"barzAddress\":\"Precalculated Barz address\"}},\"getBytecode(address,address,address,address,address,bytes)\":{\"params\":{\"_accountFacet\":\"Account Facet to be used to create Barz\",\"_defaultFallback\":\"Default Fallback Handler to be used to create Barz\",\"_entryPoint\":\"Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\",\"_facetRegistry\":\"Facet Registry to be used to create Barz\",\"_ownerPublicKey\":\"Public Key of owner to be used to initialize Barz ownership\",\"_verificationFacet\":\"Verification Facet to be used to create Barz\"},\"returns\":{\"barzBytecode\":\"Bytecode of Barz\"}},\"getCreationCode()\":{\"returns\":{\"creationCode\":\"Creation code of Barz\"}}},\"title\":\"Barz Factory\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"Sets the initialization data for Barz contract initialization\"},\"createAccount(address,bytes,uint256)\":{\"notice\":\"Creates the Barz with a single call. It creates the Barz contract with the givent verification facet\"},\"getAddress(address,bytes,uint256)\":{\"notice\":\"Calculates the address of Barz with the given parameters\"},\"getBytecode(address,address,address,address,address,bytes)\":{\"notice\":\"Returns the bytecode of Barz with the given parameter\"},\"getCreationCode()\":{\"notice\":\"Returns the creation code of the Barz contract\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/BarzFactory.sol\":\"BarzFactory\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"contracts/Barz.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {LibDiamond} from \\\"./libraries/LibDiamond.sol\\\";\\nimport {IBarz} from \\\"./interfaces/IBarz.sol\\\";\\n\\n/**\\n * @title Barz\\n * @dev A diamond proxy wallet with a modular & upgradeable architecture\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract Barz is IBarz {\\n /**\\n * @notice Initializes Barz with the given parameters. Barz account is intended to be created from Barz Factory for stable deployment.\\n * @dev This method makes a delegate call to account facet and account facet handles the initialization.\\n * With modular architecture, Barz encompasses wide spectrum of architecture and logic.\\n * The only requirement is account facet to comply with initialize() interface.\\n * Barz doesn't include built-in functions and is a full proxy, for maximum extensibility and modularity.\\n * @param _accountFacet Address of Account Facet in charge of the Barz initialization\\n * @param _verificationFacet Address of Verification Facet for verifying the signature. Could be any signature scheme\\n * @param _entryPoint Address of Entry Point contract\\n * @param _facetRegistry Address of Facet Registry. Facet Registry is a registry holding trusted facets that could be added to user's wallet\\n * @param _defaultFallBack Address of Default FallBack Handler. Middleware contract for more efficient deployment\\n * @param _ownerPublicKey Bytes of Owner Public Key using for initialization\\n */\\n constructor(\\n address _accountFacet,\\n address _verificationFacet,\\n address _entryPoint,\\n address _facetRegistry,\\n address _defaultFallBack,\\n bytes memory _ownerPublicKey\\n ) payable {\\n bytes memory initCall = abi.encodeWithSignature(\\n \\\"initialize(address,address,address,address,bytes)\\\",\\n _verificationFacet,\\n _entryPoint,\\n _facetRegistry,\\n _defaultFallBack,\\n _ownerPublicKey\\n );\\n (bool success, bytes memory result) = _accountFacet.delegatecall(\\n initCall\\n );\\n if (!success || uint256(bytes32(result)) != 1) {\\n revert Barz__InitializationFailure();\\n }\\n }\\n\\n /**\\n * @notice Fallback function for Barz complying with Diamond Standard with customization of adding Default Fallback Handler\\n * @dev Find facet for function that is called and execute the function if a facet is found and return any value.\\n */\\n fallback() external payable {\\n LibDiamond.DiamondStorage storage ds;\\n bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION;\\n // get diamond storage\\n assembly {\\n ds.slot := position\\n }\\n // get facet from function selector\\n address facet = address(bytes20(ds.facets[msg.sig]));\\n if (facet == address(0))\\n facet = ds.defaultFallbackHandler.facetAddress(msg.sig);\\n require(facet != address(0), \\\"Barz: Function does not exist\\\");\\n // Execute external function from facet using delegatecall and return any value.\\n assembly {\\n // copy function selector and any arguments\\n calldatacopy(0, 0, calldatasize())\\n // execute function call using the facet\\n let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)\\n // get any return value\\n returndatacopy(0, 0, returndatasize())\\n // return any return value or error back to the caller\\n switch result\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @notice Receive function to receive native token without data\\n */\\n receive() external payable {}\\n}\\n\",\"keccak256\":\"0xd1c773409a4b3d1ca0316445d9ea1d686bab9cd5f6731fbdb0766a93edfd7bdb\",\"license\":\"Apache-2.0\"},\"contracts/BarzFactory.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {Barz} from \\\"./Barz.sol\\\";\\nimport {IBarzFactory} from \\\"./interfaces/IBarzFactory.sol\\\";\\n\\n/**\\n * @title Barz Factory\\n * @dev Contract to easily deploy Barz to a pre-computed address with a single call\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract BarzFactory is IBarzFactory {\\n address public immutable accountFacet;\\n address public immutable entryPoint;\\n address public immutable facetRegistry;\\n address public immutable defaultFallback;\\n\\n /**\\n * @notice Sets the initialization data for Barz contract initialization\\n * @param _accountFacet Account Facet to be used to create Barz\\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\\n * @param _facetRegistry Facet Registry to be used to create Barz\\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\\n */\\n constructor(\\n address _accountFacet,\\n address _entryPoint,\\n address _facetRegistry,\\n address _defaultFallback\\n ) {\\n accountFacet = _accountFacet;\\n entryPoint = _entryPoint;\\n facetRegistry = _facetRegistry;\\n defaultFallback = _defaultFallback;\\n }\\n\\n /**\\n * @notice Creates the Barz with a single call. It creates the Barz contract with the givent verification facet\\n * @param _verificationFacet Address of verification facet used for creating the barz account\\n * @param _owner Public Key of the owner to initialize barz account\\n * @param _salt Salt used for deploying barz with create2\\n * @return barz Instance of Barz contract deployed with the given parameters\\n */\\n function createAccount(\\n address _verificationFacet,\\n bytes calldata _owner,\\n uint256 _salt\\n ) external override returns (Barz barz) {\\n address addr = getAddress(_verificationFacet, _owner, _salt);\\n uint codeSize = addr.code.length;\\n if (codeSize > 0) {\\n return Barz(payable(addr));\\n }\\n barz = new Barz{salt: bytes32(_salt)}(\\n accountFacet,\\n _verificationFacet,\\n entryPoint,\\n facetRegistry,\\n defaultFallback,\\n _owner\\n );\\n emit BarzDeployed(address(barz));\\n }\\n\\n /**\\n * @notice Calculates the address of Barz with the given parameters\\n * @param _verificationFacet Address of verification facet used for creating the barz account\\n * @param _owner Public Key of the owner to initialize barz account\\n * @param _salt Salt used for deploying barz with create2\\n * @return barzAddress Precalculated Barz address\\n */\\n function getAddress(\\n address _verificationFacet,\\n bytes calldata _owner,\\n uint256 _salt\\n ) public view override returns (address barzAddress) {\\n bytes memory bytecode = getBytecode(\\n accountFacet,\\n _verificationFacet,\\n entryPoint,\\n facetRegistry,\\n defaultFallback,\\n _owner\\n );\\n bytes32 hash = keccak256(\\n abi.encodePacked(\\n bytes1(0xff),\\n address(this),\\n _salt,\\n keccak256(bytecode)\\n )\\n );\\n barzAddress = address(uint160(uint256(hash)));\\n }\\n\\n /**\\n * @notice Returns the bytecode of Barz with the given parameter\\n * @param _accountFacet Account Facet to be used to create Barz\\n * @param _verificationFacet Verification Facet to be used to create Barz\\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\\n * @param _facetRegistry Facet Registry to be used to create Barz\\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\\n * @param _ownerPublicKey Public Key of owner to be used to initialize Barz ownership\\n * @return barzBytecode Bytecode of Barz\\n */\\n function getBytecode(\\n address _accountFacet,\\n address _verificationFacet,\\n address _entryPoint,\\n address _facetRegistry,\\n address _defaultFallback,\\n bytes calldata _ownerPublicKey\\n ) public pure override returns (bytes memory barzBytecode) {\\n bytes memory bytecode = type(Barz).creationCode;\\n barzBytecode = abi.encodePacked(\\n bytecode,\\n abi.encode(\\n _accountFacet,\\n _verificationFacet,\\n _entryPoint,\\n _facetRegistry,\\n _defaultFallback,\\n _ownerPublicKey\\n )\\n );\\n }\\n\\n /**\\n * @notice Returns the creation code of the Barz contract\\n * @return creationCode Creation code of Barz\\n */\\n function getCreationCode()\\n public\\n pure\\n override\\n returns (bytes memory creationCode)\\n {\\n creationCode = type(Barz).creationCode;\\n }\\n}\\n\",\"keccak256\":\"0x76d6058fa4714f5ef87b876e49ce7e21f581164901eea906ec743e82362b1df6\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IBarz.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Barz Interface\\n * @dev Interface of Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IBarz {\\n error Barz__InitializationFailure();\\n}\\n\",\"keccak256\":\"0xca9f0c2c1ad7d06088fa16ae92d587416f2d10d8f999d7afe8ca5c4d73410aba\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IBarzFactory.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {Barz} from \\\"../Barz.sol\\\";\\n\\n/**\\n * @title Barz Factory Interface\\n * @dev Interface of contract to easily deploy Barz to a pre-computed address with a single call\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IBarzFactory {\\n event BarzDeployed(address);\\n\\n function createAccount(\\n address verificationFacet,\\n bytes calldata owner,\\n uint256 salt\\n ) external returns (Barz);\\n\\n function getAddress(\\n address verificationFacet,\\n bytes calldata owner,\\n uint256 salt\\n ) external view returns (address);\\n\\n function getBytecode(\\n address accountFacet,\\n address verificationFacet,\\n address entryPoint,\\n address facetRegistry,\\n address defaultFallback,\\n bytes memory ownerPublicKey\\n ) external pure returns (bytes memory);\\n\\n function getCreationCode() external pure returns (bytes memory);\\n}\\n\",\"keccak256\":\"0xadb48a6f3025f6395e26ffd5f9319da73ad2383906c8223e8455f41f420fba26\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\\n bytes4(keccak256(\\\"verifyRestrictions(address,address,uint256,bytes)\\\"));\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // Default Fallback Handler of the barz.\\n IDiamondLoupe defaultFallbackHandler;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function enforceIsSelf() internal view {\\n require(msg.sender == address(this), \\\"LibDiamond: Caller not self\\\");\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n\\n unchecked {\\n facetIndex++;\\n }\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n\\n function restrictionsFacet() internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(\\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2cabdc00de859c3a3170ce3bda5d0e5fd3933d47ce904fd1585f9818b02572f8\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x61010060405234801561001157600080fd5b50604051610eba380380610eba8339810160408190526100309161006e565b6001600160a01b0393841660805291831660a052821660c0521660e0526100c2565b80516001600160a01b038116811461006957600080fd5b919050565b6000806000806080858703121561008457600080fd5b61008d85610052565b935061009b60208601610052565b92506100a960408601610052565b91506100b760608601610052565b905092959194509250565b60805160a05160c05160e051610d886101326000396000818161013b015281816102b3015261048101526000818160bf01528181610292015261046001526000818161016301528181610271015261043f01526000818161018b0152818161024f015261041d0152610d886000f3fe60806040523480156200001157600080fd5b5060043610620000925760003560e01c806344409a82116200006257806344409a821462000135578063b0d691fe146200015d578063b0f5d4641462000185578063c8a7adf514620001ad57600080fd5b8062c194db14620000975780630a1acd7314620000b9578063296601cd146200010757806333bb64a7146200011e575b600080fd5b620000a1620001c4565b604051620000b091906200056c565b60405180910390f35b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001620000b0565b620000e16200011836600462000635565b6200020e565b620000a16200012f36600462000695565b6200036d565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e1620001be36600462000635565b62000414565b606060405180602001620001d89062000538565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082820381018352601f90910116604052919050565b6000806200021f8686868662000414565b905073ffffffffffffffffffffffffffffffffffffffff81163b8015620002495750905062000365565b8360001b7f0000000000000000000000000000000000000000000000000000000000000000887f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008b8b604051620002e29062000538565b620002f497969594939291906200073a565b8190604051809103906000f590508015801562000315573d6000803e3d6000fd5b5060405173ffffffffffffffffffffffffffffffffffffffff821681529093507f9e6e326008e68f57877e2bae766a5745c162e42359e34834a7f0661fa82d31b19060200160405180910390a150505b949350505050565b6060600060405180602001620003839062000538565b6020820181038252601f19601f8201166040525090508089898989898989604051602001620003b997969594939291906200073a565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052620003f79291602001620007cd565b604051602081830303815290604052915050979650505050505050565b600080620004a87f0000000000000000000000000000000000000000000000000000000000000000877f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008a8a6200036d565b8051602091820120604080517fff00000000000000000000000000000000000000000000000000000000000000818501523060601b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001660218201526035810196909652605580870192909252805180870390920182526075909501909452835193019290922095945050505050565b610552806200080183390190565b60005b838110156200056357818101518382015260200162000549565b50506000910152565b60208152600082518060208401526200058d81604085016020870162000546565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b803573ffffffffffffffffffffffffffffffffffffffff81168114620005e457600080fd5b919050565b60008083601f840112620005fc57600080fd5b50813567ffffffffffffffff8111156200061557600080fd5b6020830191508360208285010111156200062e57600080fd5b9250929050565b600080600080606085870312156200064c57600080fd5b6200065785620005bf565b9350602085013567ffffffffffffffff8111156200067457600080fd5b6200068287828801620005e9565b9598909750949560400135949350505050565b600080600080600080600060c0888a031215620006b157600080fd5b620006bc88620005bf565b9650620006cc60208901620005bf565b9550620006dc60408901620005bf565b9450620006ec60608901620005bf565b9350620006fc60808901620005bf565b925060a088013567ffffffffffffffff8111156200071957600080fd5b620007278a828b01620005e9565b989b979a50959850939692959293505050565b600073ffffffffffffffffffffffffffffffffffffffff808a16835280891660208401528088166040840152808716606084015280861660808401525060c060a08301528260c0830152828460e0840137600060e0848401015260e07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f850116830101905098975050505050505050565b60008351620007e181846020880162000546565b835190830190620007f781836020880162000546565b0194935050505056fe608060405260405161055238038061055283398101604081905261002291610163565b6000858585858560405160240161003d959493929190610264565b60408051601f198184030181529181526020820180516001600160e01b0316634a93641760e01b1790525190915060009081906001600160a01b038a16906100869085906102c3565b600060405180830381855af49150503d80600081146100c1576040519150601f19603f3d011682016040523d82523d6000602084013e6100c6565b606091505b50915091508115806100e157506100dc816102df565b600114155b156100ff57604051636ff35f8960e01b815260040160405180910390fd5b505050505050505050610306565b80516001600160a01b038116811461012457600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101561015a578181015183820152602001610142565b50506000910152565b60008060008060008060c0878903121561017c57600080fd5b6101858761010d565b95506101936020880161010d565b94506101a16040880161010d565b93506101af6060880161010d565b92506101bd6080880161010d565b60a08801519092506001600160401b03808211156101da57600080fd5b818901915089601f8301126101ee57600080fd5b81518181111561020057610200610129565b604051601f8201601f19908116603f0116810190838211818310171561022857610228610129565b816040528281528c602084870101111561024157600080fd5b61025283602083016020880161013f565b80955050505050509295509295509295565b600060018060a01b0380881683528087166020840152808616604084015280851660608401525060a0608083015282518060a08401526102ab8160c085016020870161013f565b601f01601f19169190910160c0019695505050505050565b600082516102d581846020870161013f565b9190910192915050565b80516020808301519190811015610300576000198160200360031b1b821691505b50919050565b61023d806103156000396000f3fe60806040523661000b57005b600080357fffffffff000000000000000000000000000000000000000000000000000000001681527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020819052604090912054819060601c80610125576004838101546040517fcdffacc60000000000000000000000000000000000000000000000000000000081526000357fffffffff00000000000000000000000000000000000000000000000000000000169281019290925273ffffffffffffffffffffffffffffffffffffffff169063cdffacc690602401602060405180830381865afa1580156100fe573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061012291906101ca565b90505b73ffffffffffffffffffffffffffffffffffffffff81166101a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4261727a3a2046756e6374696f6e20646f6573206e6f74206578697374000000604482015260640160405180910390fd5b3660008037600080366000845af43d6000803e8080156101c5573d6000f35b3d6000fd5b6000602082840312156101dc57600080fd5b815173ffffffffffffffffffffffffffffffffffffffff8116811461020057600080fd5b939250505056fea26469706673582212200f3fa76ace3be8675d8b4c0d6c210a922fff2c2f1444023b817d1f6c908cd56a64736f6c63430008150033a2646970667358221220329ad45a4ef4915180001cb1fc90a5f97ad94a0b280426a580cba65fce28c0f164736f6c63430008150033", + "deployedBytecode": "0x60806040523480156200001157600080fd5b5060043610620000925760003560e01c806344409a82116200006257806344409a821462000135578063b0d691fe146200015d578063b0f5d4641462000185578063c8a7adf514620001ad57600080fd5b8062c194db14620000975780630a1acd7314620000b9578063296601cd146200010757806333bb64a7146200011e575b600080fd5b620000a1620001c4565b604051620000b091906200056c565b60405180910390f35b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001620000b0565b620000e16200011836600462000635565b6200020e565b620000a16200012f36600462000695565b6200036d565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e1620001be36600462000635565b62000414565b606060405180602001620001d89062000538565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082820381018352601f90910116604052919050565b6000806200021f8686868662000414565b905073ffffffffffffffffffffffffffffffffffffffff81163b8015620002495750905062000365565b8360001b7f0000000000000000000000000000000000000000000000000000000000000000887f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008b8b604051620002e29062000538565b620002f497969594939291906200073a565b8190604051809103906000f590508015801562000315573d6000803e3d6000fd5b5060405173ffffffffffffffffffffffffffffffffffffffff821681529093507f9e6e326008e68f57877e2bae766a5745c162e42359e34834a7f0661fa82d31b19060200160405180910390a150505b949350505050565b6060600060405180602001620003839062000538565b6020820181038252601f19601f8201166040525090508089898989898989604051602001620003b997969594939291906200073a565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052620003f79291602001620007cd565b604051602081830303815290604052915050979650505050505050565b600080620004a87f0000000000000000000000000000000000000000000000000000000000000000877f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008a8a6200036d565b8051602091820120604080517fff00000000000000000000000000000000000000000000000000000000000000818501523060601b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001660218201526035810196909652605580870192909252805180870390920182526075909501909452835193019290922095945050505050565b610552806200080183390190565b60005b838110156200056357818101518382015260200162000549565b50506000910152565b60208152600082518060208401526200058d81604085016020870162000546565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b803573ffffffffffffffffffffffffffffffffffffffff81168114620005e457600080fd5b919050565b60008083601f840112620005fc57600080fd5b50813567ffffffffffffffff8111156200061557600080fd5b6020830191508360208285010111156200062e57600080fd5b9250929050565b600080600080606085870312156200064c57600080fd5b6200065785620005bf565b9350602085013567ffffffffffffffff8111156200067457600080fd5b6200068287828801620005e9565b9598909750949560400135949350505050565b600080600080600080600060c0888a031215620006b157600080fd5b620006bc88620005bf565b9650620006cc60208901620005bf565b9550620006dc60408901620005bf565b9450620006ec60608901620005bf565b9350620006fc60808901620005bf565b925060a088013567ffffffffffffffff8111156200071957600080fd5b620007278a828b01620005e9565b989b979a50959850939692959293505050565b600073ffffffffffffffffffffffffffffffffffffffff808a16835280891660208401528088166040840152808716606084015280861660808401525060c060a08301528260c0830152828460e0840137600060e0848401015260e07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f850116830101905098975050505050505050565b60008351620007e181846020880162000546565b835190830190620007f781836020880162000546565b0194935050505056fe608060405260405161055238038061055283398101604081905261002291610163565b6000858585858560405160240161003d959493929190610264565b60408051601f198184030181529181526020820180516001600160e01b0316634a93641760e01b1790525190915060009081906001600160a01b038a16906100869085906102c3565b600060405180830381855af49150503d80600081146100c1576040519150601f19603f3d011682016040523d82523d6000602084013e6100c6565b606091505b50915091508115806100e157506100dc816102df565b600114155b156100ff57604051636ff35f8960e01b815260040160405180910390fd5b505050505050505050610306565b80516001600160a01b038116811461012457600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101561015a578181015183820152602001610142565b50506000910152565b60008060008060008060c0878903121561017c57600080fd5b6101858761010d565b95506101936020880161010d565b94506101a16040880161010d565b93506101af6060880161010d565b92506101bd6080880161010d565b60a08801519092506001600160401b03808211156101da57600080fd5b818901915089601f8301126101ee57600080fd5b81518181111561020057610200610129565b604051601f8201601f19908116603f0116810190838211818310171561022857610228610129565b816040528281528c602084870101111561024157600080fd5b61025283602083016020880161013f565b80955050505050509295509295509295565b600060018060a01b0380881683528087166020840152808616604084015280851660608401525060a0608083015282518060a08401526102ab8160c085016020870161013f565b601f01601f19169190910160c0019695505050505050565b600082516102d581846020870161013f565b9190910192915050565b80516020808301519190811015610300576000198160200360031b1b821691505b50919050565b61023d806103156000396000f3fe60806040523661000b57005b600080357fffffffff000000000000000000000000000000000000000000000000000000001681527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020819052604090912054819060601c80610125576004838101546040517fcdffacc60000000000000000000000000000000000000000000000000000000081526000357fffffffff00000000000000000000000000000000000000000000000000000000169281019290925273ffffffffffffffffffffffffffffffffffffffff169063cdffacc690602401602060405180830381865afa1580156100fe573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061012291906101ca565b90505b73ffffffffffffffffffffffffffffffffffffffff81166101a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4261727a3a2046756e6374696f6e20646f6573206e6f74206578697374000000604482015260640160405180910390fd5b3660008037600080366000845af43d6000803e8080156101c5573d6000f35b3d6000fd5b6000602082840312156101dc57600080fd5b815173ffffffffffffffffffffffffffffffffffffffff8116811461020057600080fd5b939250505056fea26469706673582212200f3fa76ace3be8675d8b4c0d6c210a922fff2c2f1444023b817d1f6c908cd56a64736f6c63430008150033a2646970667358221220329ad45a4ef4915180001cb1fc90a5f97ad94a0b280426a580cba65fce28c0f164736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "Contract to easily deploy Barz to a pre-computed address with a single call", + "kind": "dev", + "methods": { + "constructor": { + "params": { + "_accountFacet": "Account Facet to be used to create Barz", + "_defaultFallback": "Default Fallback Handler to be used to create Barz", + "_entryPoint": "Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF", + "_facetRegistry": "Facet Registry to be used to create Barz" + } + }, + "createAccount(address,bytes,uint256)": { + "params": { + "_owner": "Public Key of the owner to initialize barz account", + "_salt": "Salt used for deploying barz with create2", + "_verificationFacet": "Address of verification facet used for creating the barz account" + }, + "returns": { + "barz": "Instance of Barz contract deployed with the given parameters" + } + }, + "getAddress(address,bytes,uint256)": { + "params": { + "_owner": "Public Key of the owner to initialize barz account", + "_salt": "Salt used for deploying barz with create2", + "_verificationFacet": "Address of verification facet used for creating the barz account" + }, + "returns": { + "barzAddress": "Precalculated Barz address" + } + }, + "getBytecode(address,address,address,address,address,bytes)": { + "params": { + "_accountFacet": "Account Facet to be used to create Barz", + "_defaultFallback": "Default Fallback Handler to be used to create Barz", + "_entryPoint": "Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF", + "_facetRegistry": "Facet Registry to be used to create Barz", + "_ownerPublicKey": "Public Key of owner to be used to initialize Barz ownership", + "_verificationFacet": "Verification Facet to be used to create Barz" + }, + "returns": { + "barzBytecode": "Bytecode of Barz" + } + }, + "getCreationCode()": { + "returns": { + "creationCode": "Creation code of Barz" + } + } + }, + "title": "Barz Factory", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "constructor": { + "notice": "Sets the initialization data for Barz contract initialization" + }, + "createAccount(address,bytes,uint256)": { + "notice": "Creates the Barz with a single call. It creates the Barz contract with the givent verification facet" + }, + "getAddress(address,bytes,uint256)": { + "notice": "Calculates the address of Barz with the given parameters" + }, + "getBytecode(address,address,address,address,address,bytes)": { + "notice": "Returns the bytecode of Barz with the given parameter" + }, + "getCreationCode()": { + "notice": "Returns the creation code of the Barz contract" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/mainnet/DefaultFallbackHandler.json b/deployments/mainnet/DefaultFallbackHandler.json new file mode 100644 index 0000000..e504996 --- /dev/null +++ b/deployments/mainnet/DefaultFallbackHandler.json @@ -0,0 +1,275 @@ +{ + "address": "0x2e7f1dAe1F3799d20f5c31bEFdc7A620f664728D", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_diamondCutFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_accountFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_tokenReceiverFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_diamondLoupeFacet", + "type": "address" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_initializationContractAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "InitializationFunctionReverted", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "indexed": false, + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "DiamondCut", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_functionSelector", + "type": "bytes4" + } + ], + "name": "facetAddress", + "outputs": [ + { + "internalType": "address", + "name": "facetAddress_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetAddresses", + "outputs": [ + { + "internalType": "address[]", + "name": "facetAddresses_", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_facet", + "type": "address" + } + ], + "name": "facetFunctionSelectors", + "outputs": [ + { + "internalType": "bytes4[]", + "name": "facetFunctionSelectors_", + "type": "bytes4[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facets", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondLoupe.Facet[]", + "name": "facets_", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0x3bf35c47ba1075fd65bf5664041eb1c18cd90b7a36ab09fe7c55c38e43033480", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 123, + "gasUsed": "1439057", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000001000000000800002000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000", + "blockHash": "0x0e185411a4334fd367ca79ac7d4b55dd00d3e5061a0eb3ef813f639916b628ed", + "transactionHash": "0x3bf35c47ba1075fd65bf5664041eb1c18cd90b7a36ab09fe7c55c38e43033480", + "logs": [ + { + "transactionIndex": 123, + "blockNumber": 19517142, + "transactionHash": "0x3bf35c47ba1075fd65bf5664041eb1c18cd90b7a36ab09fe7c55c38e43033480", + "address": "0x2e7f1dAe1F3799d20f5c31bEFdc7A620f664728D", + "topics": [ + "0x8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb673" + ], + "data": "0x000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000580000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000000000000000000000000000000000003600000000000000000000000000b9504140771c3688ff041917192277d2f52e1e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000011f931c1c00000000000000000000000000000000000000000000000000000000000000000000000000000000fde53272dcd7938d16e031a6989753c321728332000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000005b61d27f60000000000000000000000000000000000000000000000000000000047e1da2a000000000000000000000000000000000000000000000000000000003a871cdd00000000000000000000000000000000000000000000000000000000d087d28800000000000000000000000000000000000000000000000000000000b0d691fe000000000000000000000000000000000000000000000000000000000000000000000000000000003143e1c0af0cdc153423863923cf4e3818e34daa000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000005150b7a0200000000000000000000000000000000000000000000000000000000f23a6e6100000000000000000000000000000000000000000000000000000000bc197c81000000000000000000000000000000000000000000000000000000000023de2900000000000000000000000000000000000000000000000000000000a4c0ed3600000000000000000000000000000000000000000000000000000000000000000000000000000000ce36b85d12d81cd619c745c7717f3396e184ac7c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000097a0ed62700000000000000000000000000000000000000000000000000000000adfca15e0000000000000000000000000000000000000000000000000000000052ef6b2c00000000000000000000000000000000000000000000000000000000cdffacc60000000000000000000000000000000000000000000000000000000001ffc9a700000000000000000000000000000000000000000000000000000000f9796ccf0000000000000000000000000000000000000000000000000000000001a5502200000000000000000000000000000000000000000000000000000000d42139a900000000000000000000000000000000000000000000000000000000e3a2f6fe000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "logIndex": 248, + "blockHash": "0x0e185411a4334fd367ca79ac7d4b55dd00d3e5061a0eb3ef813f639916b628ed" + } + ], + "blockNumber": 19517142, + "cumulativeGasUsed": "10723872", + "status": 1, + "byzantium": true + }, + "args": [ + "0x0B9504140771C3688Ff041917192277D2f52E1e0", + "0xFde53272dcd7938d16E031A6989753c321728332", + "0x3143E1C0Af0Cdc153423863923Cf4e3818e34Daa", + "0xCe36b85d12D81cd619C745c7717f3396E184Ac7C" + ], + "numDeployments": 1, + "solcInputHash": "ad34345aa73d96f52b3e14df983b6b29", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_diamondCutFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_accountFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_tokenReceiverFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_diamondLoupeFacet\",\"type\":\"address\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_initializationContractAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"InitializationFunctionReverted\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"DiamondCut\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_functionSelector\",\"type\":\"bytes4\"}],\"name\":\"facetAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"facetAddress_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetAddresses\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"facetAddresses_\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_facet\",\"type\":\"address\"}],\"name\":\"facetFunctionSelectors\",\"outputs\":[{\"internalType\":\"bytes4[]\",\"name\":\"facetFunctionSelectors_\",\"type\":\"bytes4[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facets\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondLoupe.Facet[]\",\"name\":\"facets_\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"A default fallback handler for Barz\",\"kind\":\"dev\",\"methods\":{\"constructor\":{\"details\":\"This contract is also a diamond that holds the default facets to reduce gas cost for wallet activation. Within the constructor this conducts diamond cut to initially setup the diamond. This is a non-upgradeable contract\",\"params\":{\"_accountFacet\":\"Address account facet\",\"_diamondCutFacet\":\"Address if diamond cut facet\",\"_diamondLoupeFacet\":\"Address of diamond loupe facet\",\"_tokenReceiverFacet\":\"Address of token receiver facet\"}},\"facetAddress(bytes4)\":{\"details\":\"If facet is not found return address(0).\",\"params\":{\"_functionSelector\":\"The function selector.\"},\"returns\":{\"facetAddress_\":\"The facet address.\"}},\"facetAddresses()\":{\"returns\":{\"facetAddresses_\":\"facetAddresses_\"}},\"facetFunctionSelectors(address)\":{\"params\":{\"_facet\":\"The facet address.\"},\"returns\":{\"facetFunctionSelectors_\":\"facetFunctionSelectors_\"}},\"facets()\":{\"returns\":{\"facets_\":\"The facet struct array including all facet information\"}}},\"title\":\"DefaultFallbackHandler\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"Sets the middleware diamond for Barz wallet as a fallback handler\"},\"facetAddress(bytes4)\":{\"notice\":\"Gets the facet that supports the given selector.\"},\"facetAddresses()\":{\"notice\":\"Get all the facet addresses used by a diamond.\"},\"facetFunctionSelectors(address)\":{\"notice\":\"Gets all the function selectors provided by a facet.\"},\"facets()\":{\"notice\":\"Returns the facet information of call facets registered to this diamond.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/infrastructure/DefaultFallbackHandler.sol\":\"DefaultFallbackHandler\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/introspection/IERC165.sol\\\";\\n\\n/**\\n * @dev _Available since v3.1._\\n */\\ninterface IERC1155Receiver is IERC165 {\\n /**\\n * @dev Handles the receipt of a single ERC1155 token type. This function is\\n * called at the end of a `safeTransferFrom` after the balance has been updated.\\n *\\n * NOTE: To accept the transfer, this must return\\n * `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))`\\n * (i.e. 0xf23a6e61, or its own function selector).\\n *\\n * @param operator The address which initiated the transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param id The ID of the token being transferred\\n * @param value The amount of tokens being transferred\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155Received(\\n address operator,\\n address from,\\n uint256 id,\\n uint256 value,\\n bytes calldata data\\n ) external returns (bytes4);\\n\\n /**\\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\\n * is called at the end of a `safeBatchTransferFrom` after the balances have\\n * been updated.\\n *\\n * NOTE: To accept the transfer(s), this must return\\n * `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))`\\n * (i.e. 0xbc197c81, or its own function selector).\\n *\\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155BatchReceived(\\n address operator,\\n address from,\\n uint256[] calldata ids,\\n uint256[] calldata values,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xeb373f1fdc7b755c6a750123a9b9e3a8a02c1470042fd6505d875000a80bde0b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title ERC721 token receiver interface\\n * @dev Interface for any contract that wants to support safeTransfers\\n * from ERC721 asset contracts.\\n */\\ninterface IERC721Receiver {\\n /**\\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\\n * by `operator` from `from`, this function is called.\\n *\\n * It must return its Solidity selector to confirm the token transfer.\\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\\n *\\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\\n */\\n function onERC721Received(\\n address operator,\\n address from,\\n uint256 tokenId,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\\n *\\n * Accounts can be notified of {IERC777} tokens being sent to them by having a\\n * contract implement this interface (contract holders can be their own\\n * implementer) and registering it on the\\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\\n *\\n * See {IERC1820Registry} and {ERC1820Implementer}.\\n */\\ninterface IERC777Recipient {\\n /**\\n * @dev Called by an {IERC777} token contract whenever tokens are being\\n * moved or created into a registered account (`to`). The type of operation\\n * is conveyed by `from` being the zero address or not.\\n *\\n * This call occurs _after_ the token contract's state is updated, so\\n * {IERC777-balanceOf}, etc., can be used to query the post-operation state.\\n *\\n * This function may revert to prevent the operation from being executed.\\n */\\n function tokensReceived(\\n address operator,\\n address from,\\n address to,\\n uint256 amount,\\n bytes calldata userData,\\n bytes calldata operatorData\\n ) external;\\n}\\n\",\"keccak256\":\"0x1a5d61db2733202ba361e6d6741cd2e662380e22b80e987eacfc91973f2267dc\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"contracts/aa-4337/core/BaseAccount.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-empty-blocks */\\n\\nimport \\\"../interfaces/IAccount.sol\\\";\\nimport \\\"../interfaces/IEntryPoint.sol\\\";\\nimport \\\"./Helpers.sol\\\";\\n\\n/**\\n * Basic account implementation.\\n * this contract provides the basic logic for implementing the IAccount interface - validateUserOp\\n * specific account implementation should inherit it and provide the account-specific logic\\n */\\nabstract contract BaseAccount is IAccount {\\n using UserOperationLib for UserOperation;\\n\\n //return value in case of signature failure, with no time-range.\\n // equivalent to _packValidationData(true,0,0);\\n uint256 internal constant SIG_VALIDATION_FAILED = 1;\\n\\n /**\\n * Return the account nonce.\\n * This method returns the next sequential nonce.\\n * For a nonce of a specific key, use `entrypoint.getNonce(account, key)`\\n */\\n function getNonce() public view virtual returns (uint256) {\\n return entryPoint().getNonce(address(this), 0);\\n }\\n\\n /**\\n * return the entryPoint used by this account.\\n * subclass should return the current entryPoint used by this account.\\n */\\n function entryPoint() public view virtual returns (IEntryPoint);\\n\\n /**\\n * Validate user's signature and nonce.\\n * subclass doesn't need to override this method. Instead, it should override the specific internal validation methods.\\n */\\n function validateUserOp(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n uint256 missingAccountFunds\\n ) external virtual override returns (uint256 validationData) {\\n _requireFromEntryPoint();\\n validationData = _validateSignature(userOp, userOpHash);\\n _validateNonce(userOp.nonce);\\n _payPrefund(missingAccountFunds);\\n }\\n\\n /**\\n * ensure the request comes from the known entrypoint.\\n */\\n function _requireFromEntryPoint() internal view virtual {\\n require(\\n msg.sender == address(entryPoint()),\\n \\\"account: not from EntryPoint\\\"\\n );\\n }\\n\\n /**\\n * validate the signature is valid for this message.\\n * @param userOp validate the userOp.signature field\\n * @param userOpHash convenient field: the hash of the request, to check the signature against\\n * (also hashes the entrypoint and chain id)\\n * @return validationData signature and time-range of this operation\\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\\n * otherwise, an address of an \\\"authorizer\\\" contract.\\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \\\"indefinite\\\"\\n * <6-byte> validAfter - first timestamp this operation is valid\\n * If the account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\\n */\\n function _validateSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) internal virtual returns (uint256 validationData);\\n\\n /**\\n * Validate the nonce of the UserOperation.\\n * This method may validate the nonce requirement of this account.\\n * e.g.\\n * To limit the nonce to use sequenced UserOps only (no \\\"out of order\\\" UserOps):\\n * `require(nonce < type(uint64).max)`\\n * For a hypothetical account that *requires* the nonce to be out-of-order:\\n * `require(nonce & type(uint64).max == 0)`\\n *\\n * The actual nonce uniqueness is managed by the EntryPoint, and thus no other\\n * action is needed by the account itself.\\n *\\n * @param nonce to validate\\n *\\n * solhint-disable-next-line no-empty-blocks\\n */\\n function _validateNonce(uint256 nonce) internal view virtual {}\\n\\n /**\\n * sends to the entrypoint (msg.sender) the missing funds for this transaction.\\n * subclass MAY override this method for better funds management\\n * (e.g. send to the entryPoint more than the minimum required, so that in future transactions\\n * it will not be required to send again)\\n * @param missingAccountFunds the minimum value this method should send the entrypoint.\\n * this value MAY be zero, in case there is enough deposit, or the userOp has a paymaster.\\n */\\n function _payPrefund(uint256 missingAccountFunds) internal virtual {\\n if (missingAccountFunds != 0) {\\n (bool success, ) = payable(msg.sender).call{\\n value: missingAccountFunds,\\n gas: type(uint256).max\\n }(\\\"\\\");\\n (success);\\n //ignore failure (its EntryPoint's job to verify, not account.)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa0dcc386b0f04711db3e394fb50e55a3b3b1a4d19fac1f10895844e1aa4e3d5c\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/core/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable no-inline-assembly */\\n\\n/**\\n * returned data from validateUserOp.\\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\\n * @param aggregator - address(0) - the account validated the signature by itself.\\n * address(1) - the account failed to validate the signature.\\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\\n * @param validAfter - this UserOp is valid only after this timestamp.\\n * @param validaUntil - this UserOp is valid only up to this timestamp.\\n */\\nstruct ValidationData {\\n address aggregator;\\n uint48 validAfter;\\n uint48 validUntil;\\n}\\n\\n//extract sigFailed, validAfter, validUntil.\\n// also convert zero validUntil to type(uint48).max\\nfunction _parseValidationData(\\n uint validationData\\n) pure returns (ValidationData memory data) {\\n address aggregator = address(uint160(validationData));\\n uint48 validUntil = uint48(validationData >> 160);\\n if (validUntil == 0) {\\n validUntil = type(uint48).max;\\n }\\n uint48 validAfter = uint48(validationData >> (48 + 160));\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n// intersect account and paymaster ranges.\\nfunction _intersectTimeRange(\\n uint256 validationData,\\n uint256 paymasterValidationData\\n) pure returns (ValidationData memory) {\\n ValidationData memory accountValidationData = _parseValidationData(\\n validationData\\n );\\n ValidationData memory pmValidationData = _parseValidationData(\\n paymasterValidationData\\n );\\n address aggregator = accountValidationData.aggregator;\\n if (aggregator == address(0)) {\\n aggregator = pmValidationData.aggregator;\\n }\\n uint48 validAfter = accountValidationData.validAfter;\\n uint48 validUntil = accountValidationData.validUntil;\\n uint48 pmValidAfter = pmValidationData.validAfter;\\n uint48 pmValidUntil = pmValidationData.validUntil;\\n\\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp\\n * @param data - the ValidationData to pack\\n */\\nfunction _packValidationData(\\n ValidationData memory data\\n) pure returns (uint256) {\\n return\\n uint160(data.aggregator) |\\n (uint256(data.validUntil) << 160) |\\n (uint256(data.validAfter) << (160 + 48));\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp, when not using an aggregator\\n * @param sigFailed - true for signature failure, false for success\\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\\n * @param validAfter first timestamp this UserOperation is valid\\n */\\nfunction _packValidationData(\\n bool sigFailed,\\n uint48 validUntil,\\n uint48 validAfter\\n) pure returns (uint256) {\\n return\\n (sigFailed ? 1 : 0) |\\n (uint256(validUntil) << 160) |\\n (uint256(validAfter) << (160 + 48));\\n}\\n\\n/**\\n * keccak function over calldata.\\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\\n */\\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\\n assembly {\\n let mem := mload(0x40)\\n let len := data.length\\n calldatacopy(mem, data.offset, len)\\n ret := keccak256(mem, len)\\n }\\n}\\n\",\"keccak256\":\"0xa79f06cd158ecb8c0da95493a2f348933b8627a63e228b99738bff3aa107942d\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAccount.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\ninterface IAccount {\\n /**\\n * Validate user's signature and nonce\\n * the entryPoint will make the call to the recipient only if this validation call returns successfully.\\n * signature failure should be reported by returning SIG_VALIDATION_FAILED (1).\\n * This allows making a \\\"simulation call\\\" without a valid signature\\n * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure.\\n *\\n * @dev Must validate caller is the entryPoint.\\n * Must validate the signature and nonce\\n * @param userOp the operation that is about to be executed.\\n * @param userOpHash hash of the user's request data. can be used as the basis for signature.\\n * @param missingAccountFunds missing funds on the account's deposit in the entrypoint.\\n * This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call.\\n * The excess is left as a deposit in the entrypoint, for future calls.\\n * can be withdrawn anytime using \\\"entryPoint.withdrawTo()\\\"\\n * In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero.\\n * @return validationData packaged ValidationData structure. use `_packValidationData` and `_unpackValidationData` to encode and decode\\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\\n * otherwise, an address of an \\\"authorizer\\\" contract.\\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \\\"indefinite\\\"\\n * <6-byte> validAfter - first timestamp this operation is valid\\n * If an account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\\n */\\n function validateUserOp(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n uint256 missingAccountFunds\\n ) external returns (uint256 validationData);\\n}\\n\",\"keccak256\":\"0xcbc4b0973cf954c5895b7796335f651fbfcfb55f67dfa789a3d354f8e23c4f2b\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAggregator.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\n/**\\n * Aggregated Signatures validator.\\n */\\ninterface IAggregator {\\n /**\\n * validate aggregated signature.\\n * revert if the aggregated signature does not match the given list of operations.\\n */\\n function validateSignatures(\\n UserOperation[] calldata userOps,\\n bytes calldata signature\\n ) external view;\\n\\n /**\\n * validate signature of a single userOp\\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\\n * @param userOp the userOperation received from the user.\\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\\n * (usually empty, unless account and aggregator support some kind of \\\"multisig\\\"\\n */\\n function validateUserOpSignature(\\n UserOperation calldata userOp\\n ) external view returns (bytes memory sigForUserOp);\\n\\n /**\\n * aggregate multiple signatures into a single value.\\n * This method is called off-chain to calculate the signature to pass with handleOps()\\n * bundler MAY use optimized custom code perform this aggregation\\n * @param userOps array of UserOperations to collect the signatures from.\\n * @return aggregatedSignature the aggregated signature\\n */\\n function aggregateSignatures(\\n UserOperation[] calldata userOps\\n ) external view returns (bytes memory aggregatedSignature);\\n}\\n\",\"keccak256\":\"0xdfdcd80568f037716674619b31be630fcd8316262f05a815b41d1e81782c966a\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IEntryPoint.sol\":{\"content\":\"/**\\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\\n ** Only one instance required on each chain.\\n **/\\n// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-inline-assembly */\\n/* solhint-disable reason-string */\\n\\nimport \\\"./UserOperation.sol\\\";\\nimport \\\"./IStakeManager.sol\\\";\\nimport \\\"./IAggregator.sol\\\";\\nimport \\\"./INonceManager.sol\\\";\\n\\ninterface IEntryPoint is IStakeManager, INonceManager {\\n /***\\n * An event emitted after each successful request\\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\\n * @param sender - the account that generates this request.\\n * @param paymaster - if non-null, the paymaster that pays for this request.\\n * @param nonce - the nonce value from the request.\\n * @param success - true if the sender transaction succeeded, false if reverted.\\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\\n */\\n event UserOperationEvent(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address indexed paymaster,\\n uint256 nonce,\\n bool success,\\n uint256 actualGasCost,\\n uint256 actualGasUsed\\n );\\n\\n /**\\n * account \\\"sender\\\" was deployed.\\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\\n * @param sender the account that is deployed\\n * @param factory the factory used to deploy this account (in the initCode)\\n * @param paymaster the paymaster used by this UserOp\\n */\\n event AccountDeployed(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address factory,\\n address paymaster\\n );\\n\\n /**\\n * An event emitted if the UserOperation \\\"callData\\\" reverted with non-zero length\\n * @param userOpHash the request unique identifier.\\n * @param sender the sender of this request\\n * @param nonce the nonce used in the request\\n * @param revertReason - the return bytes from the (reverted) call to \\\"callData\\\".\\n */\\n event UserOperationRevertReason(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n uint256 nonce,\\n bytes revertReason\\n );\\n\\n /**\\n * an event emitted by handleOps(), before starting the execution loop.\\n * any event emitted before this event, is part of the validation.\\n */\\n event BeforeExecution();\\n\\n /**\\n * signature aggregator used by the following UserOperationEvents within this bundle.\\n */\\n event SignatureAggregatorChanged(address indexed aggregator);\\n\\n /**\\n * a custom revert error of handleOps, to identify the offending op.\\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\\n * @param reason - revert reason\\n * The string starts with a unique code \\\"AAmn\\\", where \\\"m\\\" is \\\"1\\\" for factory, \\\"2\\\" for account and \\\"3\\\" for paymaster issues,\\n * so a failure can be attributed to the correct entity.\\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\\n */\\n error FailedOp(uint256 opIndex, string reason);\\n\\n /**\\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\\n */\\n error SignatureValidationFailed(address aggregator);\\n\\n /**\\n * Successful result from simulateValidation.\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n */\\n error ValidationResult(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo\\n );\\n\\n /**\\n * Successful result from simulateValidation, if the account returns a signature aggregator\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\\n * bundler MUST use it to verify the signature, or reject the UserOperation\\n */\\n error ValidationResultWithAggregation(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo,\\n AggregatorStakeInfo aggregatorInfo\\n );\\n\\n /**\\n * return value of getSenderAddress\\n */\\n error SenderAddressResult(address sender);\\n\\n /**\\n * return value of simulateHandleOp\\n */\\n error ExecutionResult(\\n uint256 preOpGas,\\n uint256 paid,\\n uint48 validAfter,\\n uint48 validUntil,\\n bool targetSuccess,\\n bytes targetResult\\n );\\n\\n //UserOps handled, per aggregator\\n struct UserOpsPerAggregator {\\n UserOperation[] userOps;\\n // aggregator address\\n IAggregator aggregator;\\n // aggregated signature\\n bytes signature;\\n }\\n\\n /**\\n * Execute a batch of UserOperation.\\n * no signature aggregator is used.\\n * if any account requires an aggregator (that is, it returned an aggregator when\\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\\n * @param ops the operations to execute\\n * @param beneficiary the address to receive the fees\\n */\\n function handleOps(\\n UserOperation[] calldata ops,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * Execute a batch of UserOperation with Aggregators\\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\\n * @param beneficiary the address to receive the fees\\n */\\n function handleAggregatedOps(\\n UserOpsPerAggregator[] calldata opsPerAggregator,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * generate a request Id - unique identifier for this request.\\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\\n */\\n function getUserOpHash(\\n UserOperation calldata userOp\\n ) external view returns (bytes32);\\n\\n /**\\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\\n * @param userOp the user operation to validate.\\n */\\n function simulateValidation(UserOperation calldata userOp) external;\\n\\n /**\\n * gas and return values during simulation\\n * @param preOpGas the gas used for validation (including preValidationGas)\\n * @param prefund the required prefund for this operation\\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\\n */\\n struct ReturnInfo {\\n uint256 preOpGas;\\n uint256 prefund;\\n bool sigFailed;\\n uint48 validAfter;\\n uint48 validUntil;\\n bytes paymasterContext;\\n }\\n\\n /**\\n * returned aggregated signature info.\\n * the aggregator returned by the account, and its current stake.\\n */\\n struct AggregatorStakeInfo {\\n address aggregator;\\n StakeInfo stakeInfo;\\n }\\n\\n /**\\n * Get counterfactual sender address.\\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\\n * this method always revert, and returns the address in SenderAddressResult error\\n * @param initCode the constructor code to be passed into the UserOperation.\\n */\\n function getSenderAddress(bytes memory initCode) external;\\n\\n /**\\n * simulate full execution of a UserOperation (including both validation and target execution)\\n * this method will always revert with \\\"ExecutionResult\\\".\\n * it performs full validation of the UserOperation, but ignores signature error.\\n * an optional target address is called after the userop succeeds, and its value is returned\\n * (before the entire call is reverted)\\n * Note that in order to collect the the success/failure of the target call, it must be executed\\n * with trace enabled to track the emitted events.\\n * @param op the UserOperation to simulate\\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\\n * are set to the return from that call.\\n * @param targetCallData callData to pass to target address\\n */\\n function simulateHandleOp(\\n UserOperation calldata op,\\n address target,\\n bytes calldata targetCallData\\n ) external;\\n}\\n\",\"keccak256\":\"0x9ccb1b188eda8bbf5f6c2d01bd83c3d8b2b04fcf745283051d31fe96d1d8e40f\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/INonceManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\ninterface INonceManager {\\n /**\\n * Return the next nonce for this sender.\\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\\n * But UserOp with different keys can come with arbitrary order.\\n *\\n * @param sender the account address\\n * @param key the high 192 bit of the nonce\\n * @return nonce a full nonce to pass for next UserOp with this sender.\\n */\\n function getNonce(\\n address sender,\\n uint192 key\\n ) external view returns (uint256 nonce);\\n\\n /**\\n * Manually increment the nonce of the sender.\\n * This method is exposed just for completeness..\\n * Account does NOT need to call it, neither during validation, nor elsewhere,\\n * as the EntryPoint will update the nonce regardless.\\n * Possible use-case is call it with various keys to \\\"initialize\\\" their nonces to one, so that future\\n * UserOperations will not pay extra for the first transaction with a given key.\\n */\\n function incrementNonce(uint192 key) external;\\n}\\n\",\"keccak256\":\"0xce478ad0fa0d18a3b785ac854623029e7ab463d05873dfaa365abfa1bf100912\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IStakeManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8.12;\\n\\n/**\\n * manage deposits and stakes.\\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\\n * stake is value locked for at least \\\"unstakeDelay\\\" by the staked entity.\\n */\\ninterface IStakeManager {\\n event Deposited(address indexed account, uint256 totalDeposit);\\n\\n event Withdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /// Emitted when stake or unstake delay are modified\\n event StakeLocked(\\n address indexed account,\\n uint256 totalStaked,\\n uint256 unstakeDelaySec\\n );\\n\\n /// Emitted once a stake is scheduled for withdrawal\\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\\n\\n event StakeWithdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /**\\n * @param deposit the entity's deposit\\n * @param staked true if this entity is staked.\\n * @param stake actual amount of ether staked for this entity.\\n * @param unstakeDelaySec minimum delay to withdraw the stake.\\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\\n * and the rest fit into a 2nd cell.\\n * 112 bit allows for 10^15 eth\\n * 48 bit for full timestamp\\n * 32 bit allows 150 years for unstake delay\\n */\\n struct DepositInfo {\\n uint112 deposit;\\n bool staked;\\n uint112 stake;\\n uint32 unstakeDelaySec;\\n uint48 withdrawTime;\\n }\\n\\n //API struct used by getStakeInfo and simulateValidation\\n struct StakeInfo {\\n uint256 stake;\\n uint256 unstakeDelaySec;\\n }\\n\\n /// @return info - full deposit information of given account\\n function getDepositInfo(\\n address account\\n ) external view returns (DepositInfo memory info);\\n\\n /// @return the deposit (for gas payment) of the account\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * add to the deposit of the given account\\n */\\n function depositTo(address account) external payable;\\n\\n /**\\n * add to the account's stake - amount and delay\\n * any pending unstake is first cancelled.\\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\\n */\\n function addStake(uint32 _unstakeDelaySec) external payable;\\n\\n /**\\n * attempt to unlock the stake.\\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\\n */\\n function unlockStake() external;\\n\\n /**\\n * withdraw from the (unlocked) stake.\\n * must first call unlockStake and wait for the unstakeDelay to pass\\n * @param withdrawAddress the address to send withdrawn value.\\n */\\n function withdrawStake(address payable withdrawAddress) external;\\n\\n /**\\n * withdraw from the deposit.\\n * @param withdrawAddress the address to send withdrawn value.\\n * @param withdrawAmount the amount to withdraw.\\n */\\n function withdrawTo(\\n address payable withdrawAddress,\\n uint256 withdrawAmount\\n ) external;\\n}\\n\",\"keccak256\":\"0xadcea606c9b7aafe6645441f2154a60f271330b0eee5292a632aa71c1672d546\",\"license\":\"GPL-3.0-only\"},\"contracts/aa-4337/interfaces/UserOperation.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable no-inline-assembly */\\n\\nimport {calldataKeccak} from \\\"../core/Helpers.sol\\\";\\n\\n/**\\n * User Operation struct\\n * @param sender the sender account of this request.\\n * @param nonce unique value the sender uses to verify it is not a replay.\\n * @param initCode if set, the account contract will be created by this constructor/\\n * @param callData the method call to execute on this account.\\n * @param callGasLimit the gas limit passed to the callData method call.\\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\\n * @param maxFeePerGas same as EIP-1559 gas parameter.\\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\\n */\\nstruct UserOperation {\\n address sender;\\n uint256 nonce;\\n bytes initCode;\\n bytes callData;\\n uint256 callGasLimit;\\n uint256 verificationGasLimit;\\n uint256 preVerificationGas;\\n uint256 maxFeePerGas;\\n uint256 maxPriorityFeePerGas;\\n bytes paymasterAndData;\\n bytes signature;\\n}\\n\\n/**\\n * Utility functions helpful when working with UserOperation structs.\\n */\\nlibrary UserOperationLib {\\n function getSender(\\n UserOperation calldata userOp\\n ) internal pure returns (address) {\\n address data;\\n //read sender from userOp, which is first userOp member (saves 800 gas...)\\n assembly {\\n data := calldataload(userOp)\\n }\\n return address(uint160(data));\\n }\\n\\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\\n // pay above what he signed for.\\n function gasPrice(\\n UserOperation calldata userOp\\n ) internal view returns (uint256) {\\n unchecked {\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n if (maxFeePerGas == maxPriorityFeePerGas) {\\n //legacy mode (for networks that don't support basefee opcode)\\n return maxFeePerGas;\\n }\\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\\n }\\n }\\n\\n function pack(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes memory ret) {\\n address sender = getSender(userOp);\\n uint256 nonce = userOp.nonce;\\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\\n bytes32 hashCallData = calldataKeccak(userOp.callData);\\n uint256 callGasLimit = userOp.callGasLimit;\\n uint256 verificationGasLimit = userOp.verificationGasLimit;\\n uint256 preVerificationGas = userOp.preVerificationGas;\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\\n\\n return\\n abi.encode(\\n sender,\\n nonce,\\n hashInitCode,\\n hashCallData,\\n callGasLimit,\\n verificationGasLimit,\\n preVerificationGas,\\n maxFeePerGas,\\n maxPriorityFeePerGas,\\n hashPaymasterAndData\\n );\\n }\\n\\n function hash(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes32) {\\n return keccak256(pack(userOp));\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n}\\n\",\"keccak256\":\"0x2429f5cc546bdee08c7e63858d0dda8491eaa3ab5194df884dc948c1154d2834\",\"license\":\"GPL-3.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IStorageLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"./IDiamondLoupe.sol\\\";\\n\\n/**\\n * @title LoupeFromStorage Interface\\n * @dev Interface contract to function as a loupe facet directly attached to diamond storage of Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IStorageLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facetsFromStorage()\\n external\\n view\\n returns (IDiamondLoupe.Facet[] memory);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n function facetFunctionSelectorsFromStorage(\\n address _facet\\n ) external view returns (bytes4[] memory);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n function facetAddressesFromStorage()\\n external\\n view\\n returns (address[] memory);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n function facetAddressFromStorage(\\n bytes4 _functionSelector\\n ) external view returns (address);\\n}\\n\",\"keccak256\":\"0xdf5dc9c57319e9087628c9cf9404b4f75585b76d1c2f4f59ee796c933967ea5c\",\"license\":\"Apache-2.0\"},\"contracts/facets/interfaces/IAccountFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IEntryPoint} from \\\"../../aa-4337/interfaces/IEntryPoint.sol\\\";\\n\\n/**\\n * @title Account Facet Interface\\n * @dev Interface of module contract that provides the account features and init/unitialization of signer\\n * compatible with EIP-1271 & EIP-4337\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IAccountFacet {\\n event AccountInitialized(\\n IEntryPoint indexed entryPoint,\\n bytes indexed ownerPublicKey\\n );\\n // NOTE: Added Below Event\\n event VerificationSuccess(bytes32);\\n event VerificationFailure(bytes32);\\n\\n error AccountFacet__InitializationFailure();\\n error AccountFacet__RestrictionsFailure();\\n error AccountFacet__NonExistentVerificationFacet();\\n error AccountFacet__CallNotSuccessful();\\n error AccountFacet__InvalidArrayLength();\\n\\n function initialize(\\n address verificationFacet,\\n address anEntryPoint,\\n address facetRegistry,\\n address _defaultFallBack,\\n bytes calldata _ownerPublicKey\\n ) external returns (uint256);\\n\\n function execute(address dest, uint256 value, bytes calldata func) external;\\n\\n function executeBatch(\\n address[] calldata dest,\\n uint256[] calldata value,\\n bytes[] calldata func\\n ) external;\\n}\\n\",\"keccak256\":\"0x74a9cb0b8f2f4a5148e366a401a0354426c536c012c025025d07cc25a4cd5382\",\"license\":\"Apache-2.0\"},\"contracts/infrastructure/DefaultFallbackHandler.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IERC721Receiver} from \\\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\\\";\\nimport {IERC1155Receiver} from \\\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\\\";\\nimport {IERC777Recipient} from \\\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\\\";\\nimport {BaseAccount} from \\\"../aa-4337/core/BaseAccount.sol\\\";\\nimport {DefaultLibDiamond} from \\\"../libraries/DefaultLibDiamond.sol\\\";\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IAccountFacet} from \\\"../facets/interfaces/IAccountFacet.sol\\\";\\nimport {IStorageLoupe} from \\\"../facets/base/interfaces/IStorageLoupe.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\nimport {IERC677Receiver} from \\\"../interfaces/ERC/IERC677Receiver.sol\\\";\\nimport {IERC165} from \\\"../interfaces/ERC/IERC165.sol\\\";\\n\\n/**\\n * @title DefaultFallbackHandler\\n * @dev A default fallback handler for Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract DefaultFallbackHandler is IDiamondLoupe {\\n /**\\n * @notice Sets the middleware diamond for Barz wallet as a fallback handler\\n * @dev This contract is also a diamond that holds the default facets to reduce gas cost for wallet activation.\\n * Within the constructor this conducts diamond cut to initially setup the diamond. This is a non-upgradeable contract\\n * @param _diamondCutFacet Address if diamond cut facet\\n * @param _accountFacet Address account facet\\n * @param _tokenReceiverFacet Address of token receiver facet\\n * @param _diamondLoupeFacet Address of diamond loupe facet\\n */\\n constructor(\\n address _diamondCutFacet,\\n address _accountFacet,\\n address _tokenReceiverFacet,\\n address _diamondLoupeFacet\\n ) payable {\\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](4);\\n bytes4[] memory functionSelectors = new bytes4[](1);\\n functionSelectors[0] = IDiamondCut.diamondCut.selector;\\n\\n bytes4[] memory accountFunctionSelectors = new bytes4[](5);\\n accountFunctionSelectors[0] = IAccountFacet.execute.selector;\\n accountFunctionSelectors[1] = IAccountFacet.executeBatch.selector;\\n accountFunctionSelectors[2] = BaseAccount.validateUserOp.selector;\\n accountFunctionSelectors[3] = BaseAccount.getNonce.selector;\\n accountFunctionSelectors[4] = BaseAccount.entryPoint.selector;\\n\\n bytes4[] memory receiverFacetSelectors = new bytes4[](5);\\n receiverFacetSelectors[0] = IERC721Receiver.onERC721Received.selector;\\n receiverFacetSelectors[1] = IERC1155Receiver.onERC1155Received.selector;\\n receiverFacetSelectors[2] = IERC1155Receiver\\n .onERC1155BatchReceived\\n .selector;\\n receiverFacetSelectors[3] = IERC777Recipient.tokensReceived.selector;\\n receiverFacetSelectors[4] = IERC677Receiver.onTokenTransfer.selector;\\n\\n bytes4[] memory loupeFacetSelectors = new bytes4[](9);\\n loupeFacetSelectors[0] = IDiamondLoupe.facets.selector;\\n loupeFacetSelectors[1] = IDiamondLoupe.facetFunctionSelectors.selector;\\n loupeFacetSelectors[2] = IDiamondLoupe.facetAddresses.selector;\\n loupeFacetSelectors[3] = IDiamondLoupe.facetAddress.selector;\\n loupeFacetSelectors[4] = IERC165.supportsInterface.selector;\\n loupeFacetSelectors[5] = IStorageLoupe.facetsFromStorage.selector;\\n loupeFacetSelectors[6] = IStorageLoupe\\n .facetFunctionSelectorsFromStorage\\n .selector;\\n loupeFacetSelectors[7] = IStorageLoupe\\n .facetAddressesFromStorage\\n .selector;\\n loupeFacetSelectors[8] = IStorageLoupe.facetAddressFromStorage.selector;\\n\\n {\\n cut[0] = IDiamondCut.FacetCut({\\n facetAddress: _diamondCutFacet,\\n action: IDiamondCut.FacetCutAction.Add,\\n functionSelectors: functionSelectors\\n });\\n cut[1] = IDiamondCut.FacetCut({\\n facetAddress: _accountFacet,\\n action: IDiamondCut.FacetCutAction.Add,\\n functionSelectors: accountFunctionSelectors\\n });\\n cut[2] = IDiamondCut.FacetCut({\\n facetAddress: _tokenReceiverFacet,\\n action: IDiamondCut.FacetCutAction.Add,\\n functionSelectors: receiverFacetSelectors\\n });\\n cut[3] = IDiamondCut.FacetCut({\\n facetAddress: _diamondLoupeFacet,\\n action: IDiamondCut.FacetCutAction.Add,\\n functionSelectors: loupeFacetSelectors\\n });\\n\\n DefaultLibDiamond.diamondCut(cut, address(0), \\\"\\\");\\n }\\n }\\n\\n /**\\n * @notice Returns the facet information of call facets registered to this diamond.\\n * @return facets_ The facet struct array including all facet information\\n */\\n function facets() external view override returns (Facet[] memory facets_) {\\n DefaultLibDiamond.DiamondStorage storage ds = DefaultLibDiamond\\n .diamondStorage();\\n uint256 numFacets = ds.facetAddresses.length;\\n facets_ = new Facet[](numFacets);\\n for (uint256 i; i < numFacets; ) {\\n address facetAddress_ = ds.facetAddresses[i];\\n facets_[i].facetAddress = facetAddress_;\\n facets_[i].functionSelectors = ds\\n .facetFunctionSelectors[facetAddress_]\\n .functionSelectors;\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * @notice Gets all the function selectors provided by a facet.\\n * @param _facet The facet address.\\n * @return facetFunctionSelectors_\\n */\\n function facetFunctionSelectors(\\n address _facet\\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\\n facetFunctionSelectors_ = DefaultLibDiamond\\n .diamondStorage()\\n .facetFunctionSelectors[_facet]\\n .functionSelectors;\\n }\\n\\n /**\\n * @notice Get all the facet addresses used by a diamond.\\n * @return facetAddresses_\\n */\\n function facetAddresses()\\n external\\n view\\n override\\n returns (address[] memory facetAddresses_)\\n {\\n facetAddresses_ = DefaultLibDiamond.diamondStorage().facetAddresses;\\n }\\n\\n /** @notice Gets the facet that supports the given selector.\\n * @dev If facet is not found return address(0).\\n * @param _functionSelector The function selector.\\n * @return facetAddress_ The facet address.\\n */\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view override returns (address facetAddress_) {\\n facetAddress_ = DefaultLibDiamond\\n .diamondStorage()\\n .selectorToFacetAndPosition[_functionSelector]\\n .facetAddress;\\n }\\n}\\n\",\"keccak256\":\"0xa482fe778481e34e9fb3c4074231f8048437e934c0ca9a0c78e8e61d3a24470a\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.21;\\n\\ninterface IERC165 {\\n /// @notice Query if a contract implements an interface\\n /// @param interfaceId The interface identifier, as specified in ERC-165\\n /// @dev Interface identification is specified in ERC-165. This function\\n /// uses less than 30,000 gas.\\n /// @return `true` if the contract implements `interfaceID` and\\n /// `interfaceID` is not 0xffffffff, `false` otherwise\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xbb7f07e170898793c5535cc4b7e8944c4b990a631ac806d0b788e794abc788a3\",\"license\":\"MIT\"},\"contracts/interfaces/ERC/IERC677Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC677Receiver {\\n function onTokenTransfer(\\n address sender,\\n uint value,\\n bytes calldata data\\n ) external pure returns (bool);\\n}\\n\",\"keccak256\":\"0x4c1631cf45ea6daac0ec158c3edb9453099130b6b64f697004b83f95aa1f7350\",\"license\":\"Apache-2.0\"},\"contracts/libraries/DefaultLibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary DefaultLibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (\\n uint256 facetIndex;\\n facetIndex < _diamondCut.length;\\n facetIndex++\\n ) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(\\n address _facetAddress,\\n bytes4[] memory _functionSelectors\\n ) internal {\\n uint256 funcSelectorsLength = _functionSelectors.length;\\n require(\\n funcSelectorsLength > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _facetAddress != address(0),\\n \\\"LibDiamondCut: Add facet can't be address(0)\\\"\\n );\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (\\n uint256 selectorIndex;\\n selectorIndex < funcSelectorsLength;\\n selectorIndex++\\n ) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds\\n .selectorToFacetAndPosition[selector]\\n .facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(\\n address _facetAddress,\\n bytes4[] memory _functionSelectors\\n ) internal {\\n uint256 funcSelectorsLength = _functionSelectors.length;\\n require(\\n funcSelectorsLength > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _facetAddress != address(0),\\n \\\"LibDiamondCut: Replace facet can't be address(0)\\\"\\n );\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (\\n uint256 selectorIndex;\\n selectorIndex < funcSelectorsLength;\\n selectorIndex++\\n ) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds\\n .selectorToFacetAndPosition[selector]\\n .facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same facet\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(\\n address _facetAddress,\\n bytes4[] memory _functionSelectors\\n ) internal {\\n uint256 funcSelectorsLength = _functionSelectors.length;\\n require(\\n funcSelectorsLength > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(\\n _facetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n for (\\n uint256 selectorIndex;\\n selectorIndex < funcSelectorsLength;\\n selectorIndex++\\n ) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds\\n .selectorToFacetAndPosition[selector]\\n .facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(\\n DiamondStorage storage ds,\\n address _facetAddress\\n ) internal {\\n enforceHasContractCode(\\n _facetAddress,\\n \\\"LibDiamondCut: New facet has no code\\\"\\n );\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds\\n .facetAddresses\\n .length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds\\n .selectorToFacetAndPosition[_selector]\\n .functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(\\n _selector\\n );\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(\\n _facetAddress != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // an immutable function is a function defined directly in a diamond\\n require(\\n _facetAddress != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds\\n .selectorToFacetAndPosition[_selector]\\n .functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors[lastSelectorPosition];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n selectorPosition\\n ] = lastSelector;\\n ds\\n .selectorToFacetAndPosition[lastSelector]\\n .functionSelectorPosition = uint96(selectorPosition);\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[\\n lastFacetAddressPosition\\n ];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds\\n .facetFunctionSelectors[lastFacetAddress]\\n .facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds\\n .facetFunctionSelectors[_facetAddress]\\n .facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x1b08f332d62919288bb1f0d154ca4b85f4e167d2a06e680f8ec93dba65be3be1\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x6080604052604051620020183803806200201883398101604081905262000026916200156b565b60408051600480825260a08201909252600091816020015b604080516060808201835260008083526020830152918101919091528152602001906001900390816200003e5750506040805160018082528183019092529192506000919060208083019080368337019050509050631f931c1c60e01b81600081518110620000b157620000b1620015c8565b6001600160e01b03199290921660209283029190910182015260408051600580825260c08201909252600092909190820160a08036833701905050905063b61d27f660e01b816000815181106200010c576200010c620015c8565b6001600160e01b03199092166020928302919091019091015280516323f0ed1560e11b9082906001908110620001465762000146620015c8565b6001600160e01b0319909216602092830291909101909101528051633a871cdd60e01b9082906002908110620001805762000180620015c8565b6001600160e01b0319909216602092830291909101909101528051631a10fa5160e31b9082906003908110620001ba57620001ba620015c8565b6001600160e01b031990921660209283029190910190910152805163586b48ff60e11b9082906004908110620001f457620001f4620015c8565b6001600160e01b03199290921660209283029190910182015260408051600580825260c08201909252600092909190820160a08036833701905050905063150b7a0260e01b816000815181106200024f576200024f620015c8565b6001600160e01b031990921660209283029190910190910152805163f23a6e6160e01b9082906001908110620002895762000289620015c8565b6001600160e01b031990921660209283029190910190910152805163bc197c8160e01b9082906002908110620002c357620002c3620015c8565b6001600160e01b03199092166020928302919091019091015280516223de2960e01b9082906003908110620002fc57620002fc620015c8565b6001600160e01b0319909216602092830291909101909101528051635260769b60e11b9082906004908110620003365762000336620015c8565b6001600160e01b0319929092166020928302919091018201526040805160098082526101408201909252600092909190820161012080368337019050509050637a0ed62760e01b81600081518110620003935762000393620015c8565b6001600160e01b03199092166020928302919091019091015280516356fe50af60e11b9082906001908110620003cd57620003cd620015c8565b6001600160e01b03199092166020928302919091019091015280516314bbdacb60e21b9082906002908110620004075762000407620015c8565b6001600160e01b03199092166020928302919091019091015280516366ffd66360e11b9082906003908110620004415762000441620015c8565b6001600160e01b03199092166020928302919091019091015280516301ffc9a760e01b90829060049081106200047b576200047b620015c8565b6001600160e01b031990921660209283029190910190910152805163f9796ccf60e01b9082906005908110620004b557620004b5620015c8565b6001600160e01b031990921660209283029190910190910152805162d2a81160e11b9082906006908110620004ee57620004ee620015c8565b6001600160e01b031990921660209283029190910190910152805163d42139a960e01b9082906007908110620005285762000528620015c8565b6001600160e01b03199092166020928302919091019091015280516371d17b7f60e11b9082906008908110620005625762000562620015c8565b6001600160e01b031990921660209283029190910182015260408051606081019091526001600160a01b038b168152908101600081526020018581525085600081518110620005b557620005b5620015c8565b60200260200101819052506040518060600160405280896001600160a01b0316815260200160006002811115620005f057620005f0620015de565b815260200184815250856001815181106200060f576200060f620015c8565b60200260200101819052506040518060600160405280886001600160a01b03168152602001600060028111156200064a576200064a620015de565b81526020018381525085600281518110620006695762000669620015c8565b60200260200101819052506040518060600160405280876001600160a01b0316815260200160006002811115620006a457620006a4620015de565b81526020018281525085600381518110620006c357620006c3620015c8565b6020026020010181905250620006f1856000604051806020016040528060008152506200070060201b60201c565b5050505050505050506200184c565b60005b83518110156200090c576000848281518110620007245762000724620015c8565b602002602001015160200151905060006002811115620007485762000748620015de565b8160028111156200075d576200075d620015de565b03620007bb57620007b58583815181106200077c576200077c620015c8565b6020026020010151600001518684815181106200079d576200079d620015c8565b6020026020010151604001516200095b60201b60201c565b620008f6565b6001816002811115620007d257620007d2620015de565b036200082a57620007b5858381518110620007f157620007f1620015c8565b602002602001015160000151868481518110620008125762000812620015c8565b60200260200101516040015162000bf760201b60201c565b6002816002811115620008415762000841620015de565b036200089957620007b5858381518110620008605762000860620015c8565b602002602001015160000151868481518110620008815762000881620015c8565b60200260200101516040015162000ea160201b60201c565b60405162461bcd60e51b815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f727265637420466163657443756044820152663a20b1ba34b7b760c91b60648201526084015b60405180910390fd5b508062000903816200160a565b91505062000703565b507f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb67383838360405162000942939291906200167a565b60405180910390a162000956828262001005565b505050565b805180620009af5760405162461bcd60e51b815260206004820152602b602482015260008051602062001ff883398151915260448201526a1858d95d081d1bc818dd5d60aa1b6064820152608401620008ed565b60008051602062001f8c8339815191526001600160a01b03841662000a2c5760405162461bcd60e51b815260206004820152602c60248201527f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260448201526b65206164647265737328302960a01b6064820152608401620008ed565b6001600160a01b0384166000908152600182016020526040812054906001600160601b038216900362000a655762000a658286620010dd565b60005b8381101562000bef57600085828151811062000a885762000a88620015c8565b6020908102919091018101516001600160e01b031981166000908152918690526040909120549091506001600160a01b0316801562000b305760405162461bcd60e51b815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c72656164792065786973747300000000000000000000006064820152608401620008ed565b6001600160e01b0319821660008181526020878152604080832080546001600160a01b03908116600160a01b6001600160601b038c16021782558d168085526001808c0185529285208054938401815585528385206008840401805463ffffffff60079095166004026101000a948502191660e08a901c94909402939093179092559390925287905281546001600160a01b0319161790558362000bd48162001781565b9450505050808062000be6906200160a565b91505062000a68565b505050505050565b80518062000c4b5760405162461bcd60e51b815260206004820152602b602482015260008051602062001ff883398151915260448201526a1858d95d081d1bc818dd5d60aa1b6064820152608401620008ed565b60008051602062001f8c8339815191526001600160a01b03841662000ccc5760405162461bcd60e51b815260206004820152603060248201527f4c69624469616d6f6e644375743a205265706c6163652066616365742063616e60448201526f2774206265206164647265737328302960801b6064820152608401620008ed565b6001600160a01b0384166000908152600182016020526040812054906001600160601b038216900362000d055762000d058286620010dd565b60005b8381101562000bef57600085828151811062000d285762000d28620015c8565b6020908102919091018101516001600160e01b031981166000908152918690526040909120549091506001600160a01b03908116908816810362000dd55760405162461bcd60e51b815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d6520666163657400000000000000000000006064820152608401620008ed565b62000de28582846200114a565b6001600160e01b0319821660008181526020878152604080832080546001600160a01b03908116600160a01b6001600160601b038c16021782558d168085526001808c0185529285208054938401815585528385206008840401805463ffffffff60079095166004026101000a948502191660e08a901c94909402939093179092559390925287905281546001600160a01b0319161790558362000e868162001781565b9450505050808062000e98906200160a565b91505062000d08565b80518062000ef55760405162461bcd60e51b815260206004820152602b602482015260008051602062001ff883398151915260448201526a1858d95d081d1bc818dd5d60aa1b6064820152608401620008ed565b60008051602062001f8c8339815191526001600160a01b0384161562000f845760405162461bcd60e51b815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d7573742062652061646472657373283029000000000000000000006064820152608401620008ed565b60005b8281101562000ffe57600084828151811062000fa75762000fa7620015c8565b6020908102919091018101516001600160e01b031981166000908152918590526040909120549091506001600160a01b031662000fe68482846200114a565b5050808062000ff5906200160a565b91505062000f87565b5050505050565b6001600160a01b03821662001018575050565b6200103d8260405180606001604052806028815260200162001fac602891396200152a565b600080836001600160a01b0316836040516200105a9190620017b2565b600060405180830381855af49150503d806000811462001097576040519150601f19603f3d011682016040523d82523d6000602084013e6200109c565b606091505b509150915081620010d757805115620010b85780518082602001fd5b838360405163192105d760e01b8152600401620008ed929190620017d0565b50505050565b620011028160405180606001604052806024815260200162001fd4602491396200152a565b6002820180546001600160a01b0390921660008181526001948501602090815260408220860185905594840183559182529290200180546001600160a01b0319169091179055565b6001600160a01b038216620011c85760405162461bcd60e51b815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608401620008ed565b306001600160a01b03831603620012395760405162461bcd60e51b815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201526d3a30b1363290333ab731ba34b7b760911b6064820152608401620008ed565b6001600160e01b03198116600090815260208481526040808320546001600160a01b0386168452600180880190935290832054600160a01b9091046001600160601b031692916200128a91620017fe565b905080821462001383576001600160a01b03841660009081526001860160205260408120805483908110620012c357620012c3620015c8565b600091825260208083206008830401546001600160a01b038916845260018a019091526040909220805460079092166004026101000a90920460e01b925082919085908110620013175762001317620015c8565b600091825260208083206008830401805463ffffffff60079094166004026101000a938402191660e09590951c929092029390931790556001600160e01b03199290921682528690526040902080546001600160a01b0316600160a01b6001600160601b038516021790555b6001600160a01b03841660009081526001860160205260409020805480620013af57620013af6200181a565b60008281526020808220600860001990940193840401805463ffffffff600460078716026101000a0219169055919092556001600160e01b0319851682528690526040812081905581900362000ffe5760028501546000906200141590600190620017fe565b6001600160a01b0386166000908152600180890160205260409091200154909150808214620014cb576000876002018381548110620014585762001458620015c8565b6000918252602090912001546002890180546001600160a01b0390921692508291849081106200148c576200148c620015c8565b600091825260208083209190910180546001600160a01b0319166001600160a01b03948516179055929091168152600189810190925260409020018190555b86600201805480620014e157620014e16200181a565b60008281526020808220830160001990810180546001600160a01b03191690559092019092556001600160a01b0388168252600189810190915260408220015550505050505050565b813b8181620010d75760405162461bcd60e51b8152600401620008ed919062001830565b80516001600160a01b03811681146200156657600080fd5b919050565b600080600080608085870312156200158257600080fd5b6200158d856200154e565b93506200159d602086016200154e565b9250620015ad604086016200154e565b9150620015bd606086016200154e565b905092959194509250565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016200161f576200161f620015f4565b5060010190565b60005b838110156200164357818101518382015260200162001629565b50506000910152565b600081518084526200166681602086016020860162001626565b601f01601f19169290920160200192915050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b848110156200174f57898403607f19018652815180516001600160a01b03168552838101518986019060038110620016eb57634e487b7160e01b600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b80831015620017395783516001600160e01b03191682529286019260019290920191908601906200170d565b50978501979550505090820190600101620016a3565b50506001600160a01b038a169088015286810360408801526200177381896200164c565b9a9950505050505050505050565b60006001600160601b038281166002600160601b03198101620017a857620017a8620015f4565b6001019392505050565b60008251620017c681846020870162001626565b9190910192915050565b6001600160a01b0383168152604060208201819052600090620017f6908301846200164c565b949350505050565b81810381811115620018145762001814620015f4565b92915050565b634e487b7160e01b600052603160045260246000fd5b6020815260006200184560208301846200164c565b9392505050565b610730806200185c6000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806352ef6b2c146100515780637a0ed6271461006f578063adfca15e14610084578063cdffacc6146100a4575b600080fd5b610059610140565b60405161006691906104ab565b60405180910390f35b6100776101d1565b6040516100669190610562565b61009761009236600461060a565b6103d1565b6040516100669190610647565b61011b6100b236600461065a565b7fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610066565b60607f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6002018054806020026020016040519081016040528092919081815260200182805480156101c757602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161019c575b5050505050905090565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f908067ffffffffffffffff8111156102315761023161069c565b60405190808252806020026020018201604052801561027757816020015b60408051808201909152600081526060602082015281526020019060019003908161024f5790505b50925060005b818110156103cb57600083600201828154811061029c5761029c6106cb565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050808583815181106102dc576102dc6106cb565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff928316905290821660009081526001860182526040908190208054825181850281018501909352808352919290919083018282801561039d57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161034a5790505b50505050508583815181106103b4576103b46106cb565b60209081029190910181015101525060010161027d565b50505090565b73ffffffffffffffffffffffffffffffffffffffff811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4920602090815260409182902080548351818402810184019094528084526060939283018282801561049f57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161044c5790505b50505050509050919050565b6020808252825182820181905260009190848201906040850190845b818110156104f957835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016104c7565b50909695505050505050565b600081518084526020808501945080840160005b838110156105575781517fffffffff000000000000000000000000000000000000000000000000000000001687529582019590820190600101610519565b509495945050505050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b838110156105fc578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00185528151805173ffffffffffffffffffffffffffffffffffffffff1684528701518784018790526105e987850182610505565b9588019593505090860190600101610589565b509098975050505050505050565b60006020828403121561061c57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461064057600080fd5b9392505050565b6020815260006106406020830184610505565b60006020828403121561066c57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461064057600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea264697066735822122024a872696a5ad50024326567061c50adea63ff0d49edf0ac60339459d33d571664736f6c63430008150033183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f4c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a204e657720666163657420686173206e6f20636f64654c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e2066", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806352ef6b2c146100515780637a0ed6271461006f578063adfca15e14610084578063cdffacc6146100a4575b600080fd5b610059610140565b60405161006691906104ab565b60405180910390f35b6100776101d1565b6040516100669190610562565b61009761009236600461060a565b6103d1565b6040516100669190610647565b61011b6100b236600461065a565b7fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610066565b60607f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6002018054806020026020016040519081016040528092919081815260200182805480156101c757602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161019c575b5050505050905090565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f908067ffffffffffffffff8111156102315761023161069c565b60405190808252806020026020018201604052801561027757816020015b60408051808201909152600081526060602082015281526020019060019003908161024f5790505b50925060005b818110156103cb57600083600201828154811061029c5761029c6106cb565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050808583815181106102dc576102dc6106cb565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff928316905290821660009081526001860182526040908190208054825181850281018501909352808352919290919083018282801561039d57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161034a5790505b50505050508583815181106103b4576103b46106cb565b60209081029190910181015101525060010161027d565b50505090565b73ffffffffffffffffffffffffffffffffffffffff811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4920602090815260409182902080548351818402810184019094528084526060939283018282801561049f57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161044c5790505b50505050509050919050565b6020808252825182820181905260009190848201906040850190845b818110156104f957835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016104c7565b50909695505050505050565b600081518084526020808501945080840160005b838110156105575781517fffffffff000000000000000000000000000000000000000000000000000000001687529582019590820190600101610519565b509495945050505050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b838110156105fc578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00185528151805173ffffffffffffffffffffffffffffffffffffffff1684528701518784018790526105e987850182610505565b9588019593505090860190600101610589565b509098975050505050505050565b60006020828403121561061c57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461064057600080fd5b9392505050565b6020815260006106406020830184610505565b60006020828403121561066c57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461064057600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea264697066735822122024a872696a5ad50024326567061c50adea63ff0d49edf0ac60339459d33d571664736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "A default fallback handler for Barz", + "kind": "dev", + "methods": { + "constructor": { + "details": "This contract is also a diamond that holds the default facets to reduce gas cost for wallet activation. Within the constructor this conducts diamond cut to initially setup the diamond. This is a non-upgradeable contract", + "params": { + "_accountFacet": "Address account facet", + "_diamondCutFacet": "Address if diamond cut facet", + "_diamondLoupeFacet": "Address of diamond loupe facet", + "_tokenReceiverFacet": "Address of token receiver facet" + } + }, + "facetAddress(bytes4)": { + "details": "If facet is not found return address(0).", + "params": { + "_functionSelector": "The function selector." + }, + "returns": { + "facetAddress_": "The facet address." + } + }, + "facetAddresses()": { + "returns": { + "facetAddresses_": "facetAddresses_" + } + }, + "facetFunctionSelectors(address)": { + "params": { + "_facet": "The facet address." + }, + "returns": { + "facetFunctionSelectors_": "facetFunctionSelectors_" + } + }, + "facets()": { + "returns": { + "facets_": "The facet struct array including all facet information" + } + } + }, + "title": "DefaultFallbackHandler", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "constructor": { + "notice": "Sets the middleware diamond for Barz wallet as a fallback handler" + }, + "facetAddress(bytes4)": { + "notice": "Gets the facet that supports the given selector." + }, + "facetAddresses()": { + "notice": "Get all the facet addresses used by a diamond." + }, + "facetFunctionSelectors(address)": { + "notice": "Gets all the function selectors provided by a facet." + }, + "facets()": { + "notice": "Returns the facet information of call facets registered to this diamond." + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/mainnet/DiamondCutFacet.json b/deployments/mainnet/DiamondCutFacet.json new file mode 100644 index 0000000..5c13c97 --- /dev/null +++ b/deployments/mainnet/DiamondCutFacet.json @@ -0,0 +1,856 @@ +{ + "address": "0x0B9504140771C3688Ff041917192277D2f52E1e0", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_securityManager", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "CallerNotGuardian", + "type": "error" + }, + { + "inputs": [], + "name": "CallerNotGuardianOrOwner", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__CannotRevokeUnapproved", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__DuplicateApproval", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InsufficientApprovers", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidApprovalValidationPeriod", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidApprover", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidApproverSignature", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidArrayLength", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidInitAddress", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidRouteWithGuardian", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidRouteWithoutGuardian", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__LackOfOwnerApproval", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__OwnerAlreadyApproved", + "type": "error" + }, + { + "inputs": [], + "name": "DuplicateApprover", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_initializationContractAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "InitializationFunctionReverted", + "type": "error" + }, + { + "inputs": [], + "name": "UnregisteredFacetAndSelectors", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroApproverLength", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "indexed": false, + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "DiamondCut", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "diamondCut", + "type": "tuple[]" + } + ], + "name": "DiamondCutApprovalRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "diamondCut", + "type": "tuple[]" + } + ], + "name": "DiamondCutApproved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + }, + { + "indexed": false, + "internalType": "bool", + "name": "_lag", + "type": "bool" + } + ], + "name": "SupportsInterfaceUpdated", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_diamondCutHash", + "type": "bytes32" + }, + { + "internalType": "address[]", + "name": "_approvers", + "type": "address[]" + } + ], + "name": "_checkDuplicateOnChainApprover", + "outputs": [], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + } + ], + "name": "approveDiamondCut", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "diamondCut", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "internalType": "address[]", + "name": "_approvers", + "type": "address[]" + }, + { + "internalType": "bytes[]", + "name": "_signatures", + "type": "bytes[]" + } + ], + "name": "diamondCutWithGuardian", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_diamondCutHash", + "type": "bytes32" + } + ], + "name": "getDiamondCutApprovalCountWithTimeValidity", + "outputs": [ + { + "internalType": "uint256", + "name": "approvalCount", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + } + ], + "name": "getDiamondCutHash", + "outputs": [ + { + "internalType": "bytes32", + "name": "cutHash", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getDiamondCutNonce", + "outputs": [ + { + "internalType": "uint128", + "name": "cutNonce", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_diamondCutHash", + "type": "bytes32" + } + ], + "name": "getOwnerCutApprovalWithTimeValidity", + "outputs": [ + { + "internalType": "bool", + "name": "isApprovedByOwner", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_diamondCutHash", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "_approver", + "type": "address" + } + ], + "name": "isCutApproved", + "outputs": [ + { + "internalType": "bool", + "name": "isApproved", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + } + ], + "name": "revokeDiamondCutApproval", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "securityManager", + "outputs": [ + { + "internalType": "contract ISecurityManager", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_interfaceId", + "type": "bytes4" + }, + { + "internalType": "bool", + "name": "_flag", + "type": "bool" + } + ], + "name": "updateSupportsInterface", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0x079e8c8c7c50724507b1e55159b29b915aabe3727561ff1172da76e018bedae6", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 211, + "gasUsed": "3079879", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x261997df08a5d156aed98f9cf76977437c8997658167cc4e7fce9bb2aeead461", + "transactionHash": "0x079e8c8c7c50724507b1e55159b29b915aabe3727561ff1172da76e018bedae6", + "logs": [], + "blockNumber": 19517133, + "cumulativeGasUsed": "16551536", + "status": 1, + "byzantium": true + }, + "args": [ + "0xcBe266adbfd7CB32988128e7f37b7c8b3C5521A8" + ], + "numDeployments": 1, + "solcInputHash": "ad34345aa73d96f52b3e14df983b6b29", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_securityManager\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"CallerNotGuardian\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallerNotGuardianOrOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__CannotRevokeUnapproved\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__DuplicateApproval\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InsufficientApprovers\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidApprovalValidationPeriod\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidApprover\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidApproverSignature\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidArrayLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidInitAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidRouteWithGuardian\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidRouteWithoutGuardian\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__LackOfOwnerApproval\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__OwnerAlreadyApproved\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateApprover\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_initializationContractAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"InitializationFunctionReverted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnregisteredFacetAndSelectors\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroApproverLength\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"DiamondCut\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"diamondCut\",\"type\":\"tuple[]\"}],\"name\":\"DiamondCutApprovalRevoked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"diamondCut\",\"type\":\"tuple[]\"}],\"name\":\"DiamondCutApproved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"_lag\",\"type\":\"bool\"}],\"name\":\"SupportsInterfaceUpdated\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_diamondCutHash\",\"type\":\"bytes32\"},{\"internalType\":\"address[]\",\"name\":\"_approvers\",\"type\":\"address[]\"}],\"name\":\"_checkDuplicateOnChainApprover\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"}],\"name\":\"approveDiamondCut\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"diamondCut\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"internalType\":\"address[]\",\"name\":\"_approvers\",\"type\":\"address[]\"},{\"internalType\":\"bytes[]\",\"name\":\"_signatures\",\"type\":\"bytes[]\"}],\"name\":\"diamondCutWithGuardian\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_diamondCutHash\",\"type\":\"bytes32\"}],\"name\":\"getDiamondCutApprovalCountWithTimeValidity\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"approvalCount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"}],\"name\":\"getDiamondCutHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"cutHash\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDiamondCutNonce\",\"outputs\":[{\"internalType\":\"uint128\",\"name\":\"cutNonce\",\"type\":\"uint128\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_diamondCutHash\",\"type\":\"bytes32\"}],\"name\":\"getOwnerCutApprovalWithTimeValidity\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isApprovedByOwner\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_diamondCutHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"_approver\",\"type\":\"address\"}],\"name\":\"isCutApproved\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isApproved\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"}],\"name\":\"revokeDiamondCutApproval\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"securityManager\",\"outputs\":[{\"internalType\":\"contract ISecurityManager\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_interfaceId\",\"type\":\"bytes4\"},{\"internalType\":\"bool\",\"name\":\"_flag\",\"type\":\"bool\"}],\"name\":\"updateSupportsInterface\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"Responsible for adding/removing/replace facets in Barz\",\"kind\":\"dev\",\"methods\":{\"_checkDuplicateOnChainApprover(bytes32,address[])\":{\"params\":{\"_approvers\":\"List of approver addresses\",\"_diamondCutHash\":\"Hash of diamondCut information including the facet addresses and function selectors\"}},\"approveDiamondCut((address,uint8,bytes4[])[])\":{\"params\":{\"_diamondCut\":\"Contains the facet addresses and function selectors\"}},\"constructor\":{\"params\":{\"_securityManager\":\"Security Manager contract that holds the security related variables for all wallets\"}},\"diamondCut((address,uint8,bytes4[])[],address,bytes)\":{\"params\":{\"_diamondCut\":\"Contains the facet addresses and function selectors\",\"_init\":\"The address of the contract or facet to execute _calldata. It's prohibited in Barz\"}},\"diamondCutWithGuardian((address,uint8,bytes4[])[],address[],bytes[])\":{\"params\":{\"_approvers\":\"Guardian or owner address that approves the diamond cut\",\"_diamondCut\":\"Contains the facet addresses and function selectors\",\"_signatures\":\"Signature of Guardians or owner that approves the diamond cut\"}},\"getDiamondCutApprovalCountWithTimeValidity(bytes32)\":{\"params\":{\"_diamondCutHash\":\"Hash of diamondCut information including the facet addresses and function selectors\"}},\"getDiamondCutHash((address,uint8,bytes4[])[])\":{\"params\":{\"_diamondCut\":\"Contains the facet addresses and function selectors\"},\"returns\":{\"cutHash\":\"Diamond Cut Hash\"}},\"getDiamondCutNonce()\":{\"details\":\"This method fetches the nonce from diamond cut storage\",\"returns\":{\"cutNonce\":\"Nonce of diamond cut to protect from reply attacks\"}},\"getOwnerCutApprovalWithTimeValidity(bytes32)\":{\"params\":{\"_diamondCutHash\":\"Hash of diamondCut information including the facet addresses and function selectors\"},\"returns\":{\"isApprovedByOwner\":\"Bool value showing if the owner approved the cut\"}},\"isCutApproved(bytes32,address)\":{\"params\":{\"_approver\":\"Address of approver\",\"_diamondCutHash\":\"Hash of diamondCut information including the facet addresses and function selectors\"},\"returns\":{\"isApproved\":\"Bool value showing if the approver approved the cut\"}},\"revokeDiamondCutApproval((address,uint8,bytes4[])[])\":{\"params\":{\"_diamondCut\":\"Contains the facet addresses and function selectors\"}},\"updateSupportsInterface(bytes4,bool)\":{\"params\":{\"_flag\":\"Bool value to update the mapping of the given interface ID\",\"_interfaceId\":\"InterfaceID to update the mapping\"}}},\"title\":\"DiamondCut Facet\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"_checkDuplicateOnChainApprover(bytes32,address[])\":{\"notice\":\"Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval Approvers who approved on-chain should not be included in the off-chain approval\"},\"approveDiamondCut((address,uint8,bytes4[])[])\":{\"notice\":\"Approves diamond cut. This can only be called directly from guardian or owner\"},\"constructor\":{\"notice\":\"This constructor sets the Security Manager address which is an immutable variable. Immutable variables do not impact the storage of diamond\"},\"diamondCut((address,uint8,bytes4[])[],address,bytes)\":{\"notice\":\"Add/replace/remove any number of functions and optionally execute a function with delegatecall when guardians don't exist\"},\"diamondCutWithGuardian((address,uint8,bytes4[])[],address[],bytes[])\":{\"notice\":\"Add/replace/remove any number of functions and optionally execute a function with delegatecall when guardians exist\"},\"getDiamondCutApprovalCountWithTimeValidity(bytes32)\":{\"notice\":\"Gets the number of approvals of diamond cut from guardians\"},\"getDiamondCutHash((address,uint8,bytes4[])[])\":{\"notice\":\"Returns the diamond cut hash. This function ensures that this hash is safe from replay attack by including salt, address, chainId, and nonce, etc.\"},\"getDiamondCutNonce()\":{\"notice\":\"Returns the diamond cut nonce of this wallet\"},\"getOwnerCutApprovalWithTimeValidity(bytes32)\":{\"notice\":\"Returns if the owner has approved the diamond cut\"},\"isCutApproved(bytes32,address)\":{\"notice\":\"Returns if the given approver has approved the diamond cut\"},\"revokeDiamondCutApproval((address,uint8,bytes4[])[])\":{\"notice\":\"Revokes the approval of diamond cut. This can only be called directly from guardian or owner\"},\"updateSupportsInterface(bytes4,bool)\":{\"notice\":\"Updates the flag for the interfaceId\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/base/DiamondCutFacet.sol\":\"DiamondCutFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/interfaces/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC1271 standard signature validation method for\\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC1271 {\\n /**\\n * @dev Should return whether the signature provided is valid for the provided data\\n * @param hash Hash of the data to be signed\\n * @param signature Signature byte array associated with _data\\n */\\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\\n}\\n\",\"keccak256\":\"0x0705a4b1b86d7b0bd8432118f226ba139c44b9dcaba0a6eafba2dd7d0639c544\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./math/Math.sol\\\";\\nimport \\\"./math/SignedMath.sol\\\";\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n uint256 length = Math.log10(value) + 1;\\n string memory buffer = new string(length);\\n uint256 ptr;\\n /// @solidity memory-safe-assembly\\n assembly {\\n ptr := add(buffer, add(32, length))\\n }\\n while (true) {\\n ptr--;\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\\n }\\n value /= 10;\\n if (value == 0) break;\\n }\\n return buffer;\\n }\\n }\\n\\n /**\\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\\n */\\n function toString(int256 value) internal pure returns (string memory) {\\n return string(abi.encodePacked(value < 0 ? \\\"-\\\" : \\\"\\\", toString(SignedMath.abs(value))));\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n return toHexString(value, Math.log256(value) + 1);\\n }\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n\\n /**\\n * @dev Returns true if the two strings are equal.\\n */\\n function equal(string memory a, string memory b) internal pure returns (bool) {\\n return keccak256(bytes(a)) == keccak256(bytes(b));\\n }\\n}\\n\",\"keccak256\":\"0x3088eb2868e8d13d89d16670b5f8612c4ab9ff8956272837d8e90106c59c14a0\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Strings.sol\\\";\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSA {\\n enum RecoverError {\\n NoError,\\n InvalidSignature,\\n InvalidSignatureLength,\\n InvalidSignatureS,\\n InvalidSignatureV // Deprecated in v4.8\\n }\\n\\n function _throwError(RecoverError error) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert(\\\"ECDSA: invalid signature\\\");\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert(\\\"ECDSA: invalid signature length\\\");\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert(\\\"ECDSA: invalid signature 's' value\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature` or error string. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n *\\n * Documentation for signature generation:\\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n return tryRecover(hash, v, r, s);\\n } else {\\n return (address(0), RecoverError.InvalidSignatureLength);\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature`. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, signature);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\\n uint8 v = uint8((uint256(vs) >> 255) + 27);\\n return tryRecover(hash, v, r, s);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n *\\n * _Available since v4.2._\\n */\\n function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\\n // the valid range for s in (301): 0 < s < secp256k1n \\u00f7 2 + 1, and for v in (302): v \\u2208 {27, 28}. Most\\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\\n //\\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\\n // these malleable signatures as well.\\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n return (address(0), RecoverError.InvalidSignatureS);\\n }\\n\\n // If the signature is valid (and not malleable), return the signer address\\n address signer = ecrecover(hash, v, r, s);\\n if (signer == address(0)) {\\n return (address(0), RecoverError.InvalidSignature);\\n }\\n\\n return (signer, RecoverError.NoError);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore(0x00, \\\"\\\\x19Ethereum Signed Message:\\\\n32\\\")\\n mstore(0x1c, hash)\\n message := keccak256(0x00, 0x3c)\\n }\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from `s`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n\\\", Strings.toString(s.length), s));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Typed Data, created from a\\n * `domainSeparator` and a `structHash`. This produces hash corresponding\\n * to the one signed with the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n * JSON-RPC method as part of EIP-712.\\n *\\n * See {recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n let ptr := mload(0x40)\\n mstore(ptr, \\\"\\\\x19\\\\x01\\\")\\n mstore(add(ptr, 0x02), domainSeparator)\\n mstore(add(ptr, 0x22), structHash)\\n data := keccak256(ptr, 0x42)\\n }\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Data with intended validator, created from a\\n * `validator` and `data` according to the version 0 of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x00\\\", validator, data));\\n }\\n}\\n\",\"keccak256\":\"0x809bc3edb4bcbef8263fa616c1b60ee0004b50a8a1bfa164d8f57fd31f520c58\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/SignatureChecker.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./ECDSA.sol\\\";\\nimport \\\"../../interfaces/IERC1271.sol\\\";\\n\\n/**\\n * @dev Signature verification helper that can be used instead of `ECDSA.recover` to seamlessly support both ECDSA\\n * signatures from externally owned accounts (EOAs) as well as ERC1271 signatures from smart contract wallets like\\n * Argent and Gnosis Safe.\\n *\\n * _Available since v4.1._\\n */\\nlibrary SignatureChecker {\\n /**\\n * @dev Checks if a signature is valid for a given signer and data hash. If the signer is a smart contract, the\\n * signature is validated against that smart contract using ERC1271, otherwise it's validated using `ECDSA.recover`.\\n *\\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\\n */\\n function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature) internal view returns (bool) {\\n (address recovered, ECDSA.RecoverError error) = ECDSA.tryRecover(hash, signature);\\n return\\n (error == ECDSA.RecoverError.NoError && recovered == signer) ||\\n isValidERC1271SignatureNow(signer, hash, signature);\\n }\\n\\n /**\\n * @dev Checks if a signature is valid for a given signer and data hash. The signature is validated\\n * against the signer smart contract using ERC1271.\\n *\\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\\n */\\n function isValidERC1271SignatureNow(\\n address signer,\\n bytes32 hash,\\n bytes memory signature\\n ) internal view returns (bool) {\\n (bool success, bytes memory result) = signer.staticcall(\\n abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, signature)\\n );\\n return (success &&\\n result.length >= 32 &&\\n abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector));\\n }\\n}\\n\",\"keccak256\":\"0x3af3ca86df39aac39a0514c84459d691434a108d2151c8ce9d69f32e315cab80\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n enum Rounding {\\n Down, // Toward negative infinity\\n Up, // Toward infinity\\n Zero // Toward zero\\n }\\n\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow.\\n return (a & b) + (a ^ b) / 2;\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a == 0 ? 0 : (a - 1) / b + 1;\\n }\\n\\n /**\\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\\n * with further edits by Uniswap Labs also under MIT license.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\\n unchecked {\\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2^256 + prod0.\\n uint256 prod0; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division.\\n if (prod1 == 0) {\\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\\n // The surrounding unchecked block does not change this fact.\\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\\n return prod0 / denominator;\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n require(denominator > prod1, \\\"Math: mulDiv overflow\\\");\\n\\n ///////////////////////////////////////////////\\n // 512 by 256 division.\\n ///////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0].\\n uint256 remainder;\\n assembly {\\n // Compute remainder using mulmod.\\n remainder := mulmod(x, y, denominator)\\n\\n // Subtract 256 bit number from 512 bit number.\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\\n // See https://cs.stackexchange.com/q/138556/92363.\\n\\n // Does not overflow because the denominator cannot be zero at this stage in the function.\\n uint256 twos = denominator & (~denominator + 1);\\n assembly {\\n // Divide denominator by twos.\\n denominator := div(denominator, twos)\\n\\n // Divide [prod1 prod0] by twos.\\n prod0 := div(prod0, twos)\\n\\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\\n twos := add(div(sub(0, twos), twos), 1)\\n }\\n\\n // Shift in bits from prod1 into prod0.\\n prod0 |= prod1 * twos;\\n\\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\\n // four bits. That is, denominator * inv = 1 mod 2^4.\\n uint256 inverse = (3 * denominator) ^ 2;\\n\\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\\n // in modular arithmetic, doubling the correct bits in each step.\\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\\n\\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inverse;\\n return result;\\n }\\n }\\n\\n /**\\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\\n uint256 result = mulDiv(x, y, denominator);\\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\\n result += 1;\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\\n *\\n * Inspired by Henry S. Warren, Jr.'s \\\"Hacker's Delight\\\" (Chapter 11).\\n */\\n function sqrt(uint256 a) internal pure returns (uint256) {\\n if (a == 0) {\\n return 0;\\n }\\n\\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\\n //\\n // We know that the \\\"msb\\\" (most significant bit) of our target number `a` is a power of 2 such that we have\\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\\n //\\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\\n // \\u2192 `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\\n // \\u2192 `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\\n //\\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\\n uint256 result = 1 << (log2(a) >> 1);\\n\\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\\n // into the expected uint128 result.\\n unchecked {\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n return min(result, a / result);\\n }\\n }\\n\\n /**\\n * @notice Calculates sqrt(a), following the selected rounding direction.\\n */\\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = sqrt(a);\\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 2, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 128;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 64;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 32;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 16;\\n }\\n if (value >> 8 > 0) {\\n value >>= 8;\\n result += 8;\\n }\\n if (value >> 4 > 0) {\\n value >>= 4;\\n result += 4;\\n }\\n if (value >> 2 > 0) {\\n value >>= 2;\\n result += 2;\\n }\\n if (value >> 1 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log2(value);\\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 10, rounded down, of a positive value.\\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 + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 256, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n *\\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\\n */\\n function log256(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 16;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 8;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 4;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 2;\\n }\\n if (value >> 8 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log256(value);\\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe4455ac1eb7fc497bb7402579e7b4d64d928b846fce7d2b6fde06d366f21c2b3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\\n * checks.\\n *\\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\\n * easily result in undesired exploitation or bugs, since developers usually\\n * assume that overflows raise errors. `SafeCast` restores this intuition by\\n * reverting the transaction when such an operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n *\\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\\n * all math on `uint256` and `int256` and then downcasting.\\n */\\nlibrary SafeCast {\\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 * _Available since v4.7._\\n */\\n function toUint248(uint256 value) internal pure returns (uint248) {\\n require(value <= type(uint248).max, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint240(uint256 value) internal pure returns (uint240) {\\n require(value <= type(uint240).max, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint232(uint256 value) internal pure returns (uint232) {\\n require(value <= type(uint232).max, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint224(uint256 value) internal pure returns (uint224) {\\n require(value <= type(uint224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint216(uint256 value) internal pure returns (uint216) {\\n require(value <= type(uint216).max, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint208(uint256 value) internal pure returns (uint208) {\\n require(value <= type(uint208).max, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint200(uint256 value) internal pure returns (uint200) {\\n require(value <= type(uint200).max, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint192(uint256 value) internal pure returns (uint192) {\\n require(value <= type(uint192).max, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint184(uint256 value) internal pure returns (uint184) {\\n require(value <= type(uint184).max, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint176(uint256 value) internal pure returns (uint176) {\\n require(value <= type(uint176).max, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint168(uint256 value) internal pure returns (uint168) {\\n require(value <= type(uint168).max, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint160(uint256 value) internal pure returns (uint160) {\\n require(value <= type(uint160).max, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint152(uint256 value) internal pure returns (uint152) {\\n require(value <= type(uint152).max, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint144(uint256 value) internal pure returns (uint144) {\\n require(value <= type(uint144).max, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint136(uint256 value) internal pure returns (uint136) {\\n require(value <= type(uint136).max, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint128(uint256 value) internal pure returns (uint128) {\\n require(value <= type(uint128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint120(uint256 value) internal pure returns (uint120) {\\n require(value <= type(uint120).max, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint112(uint256 value) internal pure returns (uint112) {\\n require(value <= type(uint112).max, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint104(uint256 value) internal pure returns (uint104) {\\n require(value <= type(uint104).max, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint96(uint256 value) internal pure returns (uint96) {\\n require(value <= type(uint96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint88(uint256 value) internal pure returns (uint88) {\\n require(value <= type(uint88).max, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint80(uint256 value) internal pure returns (uint80) {\\n require(value <= type(uint80).max, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint72(uint256 value) internal pure returns (uint72) {\\n require(value <= type(uint72).max, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint64(uint256 value) internal pure returns (uint64) {\\n require(value <= type(uint64).max, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint56(uint256 value) internal pure returns (uint56) {\\n require(value <= type(uint56).max, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint48(uint256 value) internal pure returns (uint48) {\\n require(value <= type(uint48).max, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint40(uint256 value) internal pure returns (uint40) {\\n require(value <= type(uint40).max, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint32(uint256 value) internal pure returns (uint32) {\\n require(value <= type(uint32).max, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint24(uint256 value) internal pure returns (uint24) {\\n require(value <= type(uint24).max, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint16(uint256 value) internal pure returns (uint16) {\\n require(value <= type(uint16).max, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint8(uint256 value) internal pure returns (uint8) {\\n require(value <= type(uint8).max, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\n */\\n function toUint256(int256 value) internal pure returns (uint256) {\\n require(value >= 0, \\\"SafeCast: value must be positive\\\");\\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 * _Available since v4.7._\\n */\\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\\n downcasted = int248(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\\n downcasted = int240(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\\n downcasted = int232(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\\n downcasted = int224(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\\n downcasted = int216(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\\n downcasted = int208(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\\n downcasted = int200(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\\n downcasted = int192(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\\n downcasted = int184(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\\n downcasted = int176(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\\n downcasted = int168(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\\n downcasted = int160(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\\n downcasted = int152(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\\n downcasted = int144(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\\n downcasted = int136(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\\n downcasted = int128(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\\n downcasted = int120(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\\n downcasted = int112(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\\n downcasted = int104(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\\n downcasted = int96(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\\n downcasted = int88(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\\n downcasted = int80(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\\n downcasted = int72(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\\n downcasted = int64(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\\n downcasted = int56(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\\n downcasted = int48(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\\n downcasted = int40(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\\n downcasted = int32(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\\n downcasted = int24(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\\n downcasted = int16(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\\n downcasted = int8(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\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 require(value <= uint256(type(int256).max), \\\"SafeCast: value doesn't fit in an int256\\\");\\n return int256(value);\\n }\\n}\\n\",\"keccak256\":\"0x52a8cfb0f5239d11b457dcdd1b326992ef672714ca8da71a157255bddd13f3ad\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SignedMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard signed math utilities missing in the Solidity language.\\n */\\nlibrary SignedMath {\\n /**\\n * @dev Returns the largest of two signed numbers.\\n */\\n function max(int256 a, int256 b) internal pure returns (int256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two signed numbers.\\n */\\n function min(int256 a, int256 b) internal pure returns (int256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two signed numbers without overflow.\\n * The result is rounded towards zero.\\n */\\n function average(int256 a, int256 b) internal pure returns (int256) {\\n // Formula from the book \\\"Hacker's Delight\\\"\\n int256 x = (a & b) + ((a ^ b) >> 1);\\n return x + (int256(uint256(x) >> 255) & (a ^ b));\\n }\\n\\n /**\\n * @dev Returns the absolute unsigned value of a signed value.\\n */\\n function abs(int256 n) internal pure returns (uint256) {\\n unchecked {\\n // must be unchecked in order to support `n = type(int256).min`\\n return uint256(n >= 0 ? n : -n);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf92515413956f529d95977adc9b0567d583c6203fc31ab1c23824c35187e3ddc\",\"license\":\"MIT\"},\"contracts/aa-4337/core/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable no-inline-assembly */\\n\\n/**\\n * returned data from validateUserOp.\\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\\n * @param aggregator - address(0) - the account validated the signature by itself.\\n * address(1) - the account failed to validate the signature.\\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\\n * @param validAfter - this UserOp is valid only after this timestamp.\\n * @param validaUntil - this UserOp is valid only up to this timestamp.\\n */\\nstruct ValidationData {\\n address aggregator;\\n uint48 validAfter;\\n uint48 validUntil;\\n}\\n\\n//extract sigFailed, validAfter, validUntil.\\n// also convert zero validUntil to type(uint48).max\\nfunction _parseValidationData(\\n uint validationData\\n) pure returns (ValidationData memory data) {\\n address aggregator = address(uint160(validationData));\\n uint48 validUntil = uint48(validationData >> 160);\\n if (validUntil == 0) {\\n validUntil = type(uint48).max;\\n }\\n uint48 validAfter = uint48(validationData >> (48 + 160));\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n// intersect account and paymaster ranges.\\nfunction _intersectTimeRange(\\n uint256 validationData,\\n uint256 paymasterValidationData\\n) pure returns (ValidationData memory) {\\n ValidationData memory accountValidationData = _parseValidationData(\\n validationData\\n );\\n ValidationData memory pmValidationData = _parseValidationData(\\n paymasterValidationData\\n );\\n address aggregator = accountValidationData.aggregator;\\n if (aggregator == address(0)) {\\n aggregator = pmValidationData.aggregator;\\n }\\n uint48 validAfter = accountValidationData.validAfter;\\n uint48 validUntil = accountValidationData.validUntil;\\n uint48 pmValidAfter = pmValidationData.validAfter;\\n uint48 pmValidUntil = pmValidationData.validUntil;\\n\\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp\\n * @param data - the ValidationData to pack\\n */\\nfunction _packValidationData(\\n ValidationData memory data\\n) pure returns (uint256) {\\n return\\n uint160(data.aggregator) |\\n (uint256(data.validUntil) << 160) |\\n (uint256(data.validAfter) << (160 + 48));\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp, when not using an aggregator\\n * @param sigFailed - true for signature failure, false for success\\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\\n * @param validAfter first timestamp this UserOperation is valid\\n */\\nfunction _packValidationData(\\n bool sigFailed,\\n uint48 validUntil,\\n uint48 validAfter\\n) pure returns (uint256) {\\n return\\n (sigFailed ? 1 : 0) |\\n (uint256(validUntil) << 160) |\\n (uint256(validAfter) << (160 + 48));\\n}\\n\\n/**\\n * keccak function over calldata.\\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\\n */\\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\\n assembly {\\n let mem := mload(0x40)\\n let len := data.length\\n calldatacopy(mem, data.offset, len)\\n ret := keccak256(mem, len)\\n }\\n}\\n\",\"keccak256\":\"0xa79f06cd158ecb8c0da95493a2f348933b8627a63e228b99738bff3aa107942d\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAggregator.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\n/**\\n * Aggregated Signatures validator.\\n */\\ninterface IAggregator {\\n /**\\n * validate aggregated signature.\\n * revert if the aggregated signature does not match the given list of operations.\\n */\\n function validateSignatures(\\n UserOperation[] calldata userOps,\\n bytes calldata signature\\n ) external view;\\n\\n /**\\n * validate signature of a single userOp\\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\\n * @param userOp the userOperation received from the user.\\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\\n * (usually empty, unless account and aggregator support some kind of \\\"multisig\\\"\\n */\\n function validateUserOpSignature(\\n UserOperation calldata userOp\\n ) external view returns (bytes memory sigForUserOp);\\n\\n /**\\n * aggregate multiple signatures into a single value.\\n * This method is called off-chain to calculate the signature to pass with handleOps()\\n * bundler MAY use optimized custom code perform this aggregation\\n * @param userOps array of UserOperations to collect the signatures from.\\n * @return aggregatedSignature the aggregated signature\\n */\\n function aggregateSignatures(\\n UserOperation[] calldata userOps\\n ) external view returns (bytes memory aggregatedSignature);\\n}\\n\",\"keccak256\":\"0xdfdcd80568f037716674619b31be630fcd8316262f05a815b41d1e81782c966a\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IEntryPoint.sol\":{\"content\":\"/**\\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\\n ** Only one instance required on each chain.\\n **/\\n// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-inline-assembly */\\n/* solhint-disable reason-string */\\n\\nimport \\\"./UserOperation.sol\\\";\\nimport \\\"./IStakeManager.sol\\\";\\nimport \\\"./IAggregator.sol\\\";\\nimport \\\"./INonceManager.sol\\\";\\n\\ninterface IEntryPoint is IStakeManager, INonceManager {\\n /***\\n * An event emitted after each successful request\\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\\n * @param sender - the account that generates this request.\\n * @param paymaster - if non-null, the paymaster that pays for this request.\\n * @param nonce - the nonce value from the request.\\n * @param success - true if the sender transaction succeeded, false if reverted.\\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\\n */\\n event UserOperationEvent(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address indexed paymaster,\\n uint256 nonce,\\n bool success,\\n uint256 actualGasCost,\\n uint256 actualGasUsed\\n );\\n\\n /**\\n * account \\\"sender\\\" was deployed.\\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\\n * @param sender the account that is deployed\\n * @param factory the factory used to deploy this account (in the initCode)\\n * @param paymaster the paymaster used by this UserOp\\n */\\n event AccountDeployed(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address factory,\\n address paymaster\\n );\\n\\n /**\\n * An event emitted if the UserOperation \\\"callData\\\" reverted with non-zero length\\n * @param userOpHash the request unique identifier.\\n * @param sender the sender of this request\\n * @param nonce the nonce used in the request\\n * @param revertReason - the return bytes from the (reverted) call to \\\"callData\\\".\\n */\\n event UserOperationRevertReason(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n uint256 nonce,\\n bytes revertReason\\n );\\n\\n /**\\n * an event emitted by handleOps(), before starting the execution loop.\\n * any event emitted before this event, is part of the validation.\\n */\\n event BeforeExecution();\\n\\n /**\\n * signature aggregator used by the following UserOperationEvents within this bundle.\\n */\\n event SignatureAggregatorChanged(address indexed aggregator);\\n\\n /**\\n * a custom revert error of handleOps, to identify the offending op.\\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\\n * @param reason - revert reason\\n * The string starts with a unique code \\\"AAmn\\\", where \\\"m\\\" is \\\"1\\\" for factory, \\\"2\\\" for account and \\\"3\\\" for paymaster issues,\\n * so a failure can be attributed to the correct entity.\\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\\n */\\n error FailedOp(uint256 opIndex, string reason);\\n\\n /**\\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\\n */\\n error SignatureValidationFailed(address aggregator);\\n\\n /**\\n * Successful result from simulateValidation.\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n */\\n error ValidationResult(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo\\n );\\n\\n /**\\n * Successful result from simulateValidation, if the account returns a signature aggregator\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\\n * bundler MUST use it to verify the signature, or reject the UserOperation\\n */\\n error ValidationResultWithAggregation(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo,\\n AggregatorStakeInfo aggregatorInfo\\n );\\n\\n /**\\n * return value of getSenderAddress\\n */\\n error SenderAddressResult(address sender);\\n\\n /**\\n * return value of simulateHandleOp\\n */\\n error ExecutionResult(\\n uint256 preOpGas,\\n uint256 paid,\\n uint48 validAfter,\\n uint48 validUntil,\\n bool targetSuccess,\\n bytes targetResult\\n );\\n\\n //UserOps handled, per aggregator\\n struct UserOpsPerAggregator {\\n UserOperation[] userOps;\\n // aggregator address\\n IAggregator aggregator;\\n // aggregated signature\\n bytes signature;\\n }\\n\\n /**\\n * Execute a batch of UserOperation.\\n * no signature aggregator is used.\\n * if any account requires an aggregator (that is, it returned an aggregator when\\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\\n * @param ops the operations to execute\\n * @param beneficiary the address to receive the fees\\n */\\n function handleOps(\\n UserOperation[] calldata ops,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * Execute a batch of UserOperation with Aggregators\\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\\n * @param beneficiary the address to receive the fees\\n */\\n function handleAggregatedOps(\\n UserOpsPerAggregator[] calldata opsPerAggregator,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * generate a request Id - unique identifier for this request.\\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\\n */\\n function getUserOpHash(\\n UserOperation calldata userOp\\n ) external view returns (bytes32);\\n\\n /**\\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\\n * @param userOp the user operation to validate.\\n */\\n function simulateValidation(UserOperation calldata userOp) external;\\n\\n /**\\n * gas and return values during simulation\\n * @param preOpGas the gas used for validation (including preValidationGas)\\n * @param prefund the required prefund for this operation\\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\\n */\\n struct ReturnInfo {\\n uint256 preOpGas;\\n uint256 prefund;\\n bool sigFailed;\\n uint48 validAfter;\\n uint48 validUntil;\\n bytes paymasterContext;\\n }\\n\\n /**\\n * returned aggregated signature info.\\n * the aggregator returned by the account, and its current stake.\\n */\\n struct AggregatorStakeInfo {\\n address aggregator;\\n StakeInfo stakeInfo;\\n }\\n\\n /**\\n * Get counterfactual sender address.\\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\\n * this method always revert, and returns the address in SenderAddressResult error\\n * @param initCode the constructor code to be passed into the UserOperation.\\n */\\n function getSenderAddress(bytes memory initCode) external;\\n\\n /**\\n * simulate full execution of a UserOperation (including both validation and target execution)\\n * this method will always revert with \\\"ExecutionResult\\\".\\n * it performs full validation of the UserOperation, but ignores signature error.\\n * an optional target address is called after the userop succeeds, and its value is returned\\n * (before the entire call is reverted)\\n * Note that in order to collect the the success/failure of the target call, it must be executed\\n * with trace enabled to track the emitted events.\\n * @param op the UserOperation to simulate\\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\\n * are set to the return from that call.\\n * @param targetCallData callData to pass to target address\\n */\\n function simulateHandleOp(\\n UserOperation calldata op,\\n address target,\\n bytes calldata targetCallData\\n ) external;\\n}\\n\",\"keccak256\":\"0x9ccb1b188eda8bbf5f6c2d01bd83c3d8b2b04fcf745283051d31fe96d1d8e40f\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/INonceManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\ninterface INonceManager {\\n /**\\n * Return the next nonce for this sender.\\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\\n * But UserOp with different keys can come with arbitrary order.\\n *\\n * @param sender the account address\\n * @param key the high 192 bit of the nonce\\n * @return nonce a full nonce to pass for next UserOp with this sender.\\n */\\n function getNonce(\\n address sender,\\n uint192 key\\n ) external view returns (uint256 nonce);\\n\\n /**\\n * Manually increment the nonce of the sender.\\n * This method is exposed just for completeness..\\n * Account does NOT need to call it, neither during validation, nor elsewhere,\\n * as the EntryPoint will update the nonce regardless.\\n * Possible use-case is call it with various keys to \\\"initialize\\\" their nonces to one, so that future\\n * UserOperations will not pay extra for the first transaction with a given key.\\n */\\n function incrementNonce(uint192 key) external;\\n}\\n\",\"keccak256\":\"0xce478ad0fa0d18a3b785ac854623029e7ab463d05873dfaa365abfa1bf100912\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IStakeManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8.12;\\n\\n/**\\n * manage deposits and stakes.\\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\\n * stake is value locked for at least \\\"unstakeDelay\\\" by the staked entity.\\n */\\ninterface IStakeManager {\\n event Deposited(address indexed account, uint256 totalDeposit);\\n\\n event Withdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /// Emitted when stake or unstake delay are modified\\n event StakeLocked(\\n address indexed account,\\n uint256 totalStaked,\\n uint256 unstakeDelaySec\\n );\\n\\n /// Emitted once a stake is scheduled for withdrawal\\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\\n\\n event StakeWithdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /**\\n * @param deposit the entity's deposit\\n * @param staked true if this entity is staked.\\n * @param stake actual amount of ether staked for this entity.\\n * @param unstakeDelaySec minimum delay to withdraw the stake.\\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\\n * and the rest fit into a 2nd cell.\\n * 112 bit allows for 10^15 eth\\n * 48 bit for full timestamp\\n * 32 bit allows 150 years for unstake delay\\n */\\n struct DepositInfo {\\n uint112 deposit;\\n bool staked;\\n uint112 stake;\\n uint32 unstakeDelaySec;\\n uint48 withdrawTime;\\n }\\n\\n //API struct used by getStakeInfo and simulateValidation\\n struct StakeInfo {\\n uint256 stake;\\n uint256 unstakeDelaySec;\\n }\\n\\n /// @return info - full deposit information of given account\\n function getDepositInfo(\\n address account\\n ) external view returns (DepositInfo memory info);\\n\\n /// @return the deposit (for gas payment) of the account\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * add to the deposit of the given account\\n */\\n function depositTo(address account) external payable;\\n\\n /**\\n * add to the account's stake - amount and delay\\n * any pending unstake is first cancelled.\\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\\n */\\n function addStake(uint32 _unstakeDelaySec) external payable;\\n\\n /**\\n * attempt to unlock the stake.\\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\\n */\\n function unlockStake() external;\\n\\n /**\\n * withdraw from the (unlocked) stake.\\n * must first call unlockStake and wait for the unstakeDelay to pass\\n * @param withdrawAddress the address to send withdrawn value.\\n */\\n function withdrawStake(address payable withdrawAddress) external;\\n\\n /**\\n * withdraw from the deposit.\\n * @param withdrawAddress the address to send withdrawn value.\\n * @param withdrawAmount the amount to withdraw.\\n */\\n function withdrawTo(\\n address payable withdrawAddress,\\n uint256 withdrawAmount\\n ) external;\\n}\\n\",\"keccak256\":\"0xadcea606c9b7aafe6645441f2154a60f271330b0eee5292a632aa71c1672d546\",\"license\":\"GPL-3.0-only\"},\"contracts/aa-4337/interfaces/UserOperation.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable no-inline-assembly */\\n\\nimport {calldataKeccak} from \\\"../core/Helpers.sol\\\";\\n\\n/**\\n * User Operation struct\\n * @param sender the sender account of this request.\\n * @param nonce unique value the sender uses to verify it is not a replay.\\n * @param initCode if set, the account contract will be created by this constructor/\\n * @param callData the method call to execute on this account.\\n * @param callGasLimit the gas limit passed to the callData method call.\\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\\n * @param maxFeePerGas same as EIP-1559 gas parameter.\\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\\n */\\nstruct UserOperation {\\n address sender;\\n uint256 nonce;\\n bytes initCode;\\n bytes callData;\\n uint256 callGasLimit;\\n uint256 verificationGasLimit;\\n uint256 preVerificationGas;\\n uint256 maxFeePerGas;\\n uint256 maxPriorityFeePerGas;\\n bytes paymasterAndData;\\n bytes signature;\\n}\\n\\n/**\\n * Utility functions helpful when working with UserOperation structs.\\n */\\nlibrary UserOperationLib {\\n function getSender(\\n UserOperation calldata userOp\\n ) internal pure returns (address) {\\n address data;\\n //read sender from userOp, which is first userOp member (saves 800 gas...)\\n assembly {\\n data := calldataload(userOp)\\n }\\n return address(uint160(data));\\n }\\n\\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\\n // pay above what he signed for.\\n function gasPrice(\\n UserOperation calldata userOp\\n ) internal view returns (uint256) {\\n unchecked {\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n if (maxFeePerGas == maxPriorityFeePerGas) {\\n //legacy mode (for networks that don't support basefee opcode)\\n return maxFeePerGas;\\n }\\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\\n }\\n }\\n\\n function pack(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes memory ret) {\\n address sender = getSender(userOp);\\n uint256 nonce = userOp.nonce;\\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\\n bytes32 hashCallData = calldataKeccak(userOp.callData);\\n uint256 callGasLimit = userOp.callGasLimit;\\n uint256 verificationGasLimit = userOp.verificationGasLimit;\\n uint256 preVerificationGas = userOp.preVerificationGas;\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\\n\\n return\\n abi.encode(\\n sender,\\n nonce,\\n hashInitCode,\\n hashCallData,\\n callGasLimit,\\n verificationGasLimit,\\n preVerificationGas,\\n maxFeePerGas,\\n maxPriorityFeePerGas,\\n hashPaymasterAndData\\n );\\n }\\n\\n function hash(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes32) {\\n return keccak256(pack(userOp));\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n}\\n\",\"keccak256\":\"0x2429f5cc546bdee08c7e63858d0dda8491eaa3ab5194df884dc948c1154d2834\",\"license\":\"GPL-3.0\"},\"contracts/facets/Modifiers.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {LibGuardian} from \\\"../libraries/LibGuardian.sol\\\";\\nimport {BarzStorage} from \\\"../libraries/LibAppStorage.sol\\\";\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\n\\n/**\\n * @title Modifiers\\n * @dev Responsible for providing modifiers/util functions to Facet contracts\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\nabstract contract Modifiers is BarzStorage {\\n uint8 constant INNER_STRUCT = 0;\\n\\n error CallerNotGuardian();\\n error CallerNotGuardianOrOwner();\\n error DuplicateApprover();\\n error ZeroApproverLength();\\n error UnregisteredFacetAndSelectors();\\n\\n /**\\n * @notice Modifier to only allow guardian to make a call, reverts if any other entity is the caller\\n */\\n modifier onlyGuardian() {\\n if (!LibGuardian.isGuardian(msg.sender)) revert CallerNotGuardian();\\n _;\\n }\\n\\n /**\\n * @notice Modifier to only allow guardian or owner to make a call, reverts if any other entity is the caller\\n */\\n modifier onlyGuardianOrOwner() {\\n if (!LibGuardian.isGuardian(msg.sender) && address(this) != msg.sender)\\n revert CallerNotGuardianOrOwner();\\n _;\\n }\\n\\n /**\\n * @notice Checks if the approver address is the array is unique with no duplicate\\n * @dev This method loops through the array and checks if a duplicate address exists, it reverts if duplicate address exists\\n * @param approvers Array of address\\n */\\n function _checkApprover(\\n address[] memory approvers\\n ) internal pure returns (bool) {\\n uint256 approverLength = approvers.length;\\n if (0 == approverLength) revert ZeroApproverLength();\\n for (uint256 i; i < approverLength - 1; ) {\\n for (uint256 j = i + 1; j < approverLength; ) {\\n if (approvers[i] == approvers[j]) {\\n revert DuplicateApprover(); // Found a duplicate\\n }\\n unchecked {\\n ++j;\\n }\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n return false; // No duplicates found\\n }\\n\\n /**\\n * @notice Checks if the facet getting added or replaced is registered to facet registry\\n * @dev This method loops through the cut and checks if the facet getting added/replaced is registered to facet registry\\n * @param _diamondCut Array of FacetCut, data for diamondCut defined in EIP-2535\\n */\\n function _checkFacetCutValidity(\\n IDiamondCut.FacetCut[] memory _diamondCut\\n ) internal view {\\n uint256 diamondCutLength = _diamondCut.length;\\n for (uint256 i; i < diamondCutLength; ) {\\n if (\\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Add ||\\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Replace\\n ) {\\n if (\\n !s.facetRegistry.areFacetFunctionSelectorsRegistered(\\n _diamondCut[i].facetAddress,\\n _diamondCut[i].functionSelectors\\n )\\n ) revert UnregisteredFacetAndSelectors();\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb42956323d199bdec243a5f9859439aae057fbfdd1d79e3a96afc857ecb3115f\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/DiamondCutFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {LibDiamond} from \\\"../../libraries/LibDiamond.sol\\\";\\nimport {LibGuardian} from \\\"../../libraries/LibGuardian.sol\\\";\\nimport {ISecurityManager} from \\\"../../infrastructure/interfaces/ISecurityManager.sol\\\";\\nimport {SignatureChecker} from \\\"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\\\";\\nimport {LibFacetStorage, DiamondCutApprovalConfig, ApprovalConfig} from \\\"../../libraries/LibFacetStorage.sol\\\";\\nimport {Modifiers} from \\\"../Modifiers.sol\\\";\\nimport {IDiamondCut} from \\\"./interfaces/IDiamondCut.sol\\\";\\n\\n/**\\n * @title DiamondCut Facet\\n * @dev Responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract DiamondCutFacet is Modifiers, IDiamondCut {\\n ISecurityManager public immutable securityManager;\\n\\n /**\\n * @notice This constructor sets the Security Manager address which is an immutable variable.\\n * Immutable variables do not impact the storage of diamond\\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\\n */\\n constructor(address _securityManager) {\\n securityManager = ISecurityManager(_securityManager);\\n }\\n\\n /**\\n * @notice Updates the flag for the interfaceId\\n * @param _interfaceId InterfaceID to update the mapping\\n * @param _flag Bool value to update the mapping of the given interface ID\\n */\\n function updateSupportsInterface(\\n bytes4 _interfaceId,\\n bool _flag\\n ) external override onlyWhenUnlocked {\\n LibDiamond.enforceIsSelf();\\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId] = _flag;\\n emit SupportsInterfaceUpdated(_interfaceId, _flag);\\n }\\n\\n /**\\n * @notice Add/replace/remove any number of functions and optionally execute\\n * a function with delegatecall when guardians don't exist\\n * @param _diamondCut Contains the facet addresses and function selectors\\n * @param _init The address of the contract or facet to execute _calldata. It's prohibited in Barz\\n */\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata\\n ) external override onlyWhenUnlocked {\\n LibDiamond.enforceIsSelf();\\n\\n _checkFacetCutValidity(_diamondCut);\\n // require approval from guardian if guardian exists\\n if (0 != LibGuardian.guardianCount())\\n revert DiamondCutFacet__InvalidRouteWithGuardian();\\n if (address(0) != _init) revert DiamondCutFacet__InvalidInitAddress();\\n\\n unchecked {\\n ++LibFacetStorage.diamondCutStorage().nonce;\\n }\\n LibDiamond.diamondCut(_diamondCut, address(0), \\\"\\\");\\n }\\n\\n /**\\n * @notice Add/replace/remove any number of functions and optionally execute\\n * a function with delegatecall when guardians exist\\n * @param _diamondCut Contains the facet addresses and function selectors\\n * @param _approvers Guardian or owner address that approves the diamond cut\\n * @param _signatures Signature of Guardians or owner that approves the diamond cut\\n */\\n function diamondCutWithGuardian(\\n FacetCut[] calldata _diamondCut,\\n address[] calldata _approvers,\\n bytes[] calldata _signatures\\n ) external override onlyWhenUnlocked {\\n if (_approvers.length != _signatures.length)\\n revert DiamondCutFacet__InvalidArrayLength();\\n _checkFacetCutValidity(_diamondCut);\\n if (0 == LibGuardian.guardianCount())\\n revert DiamondCutFacet__InvalidRouteWithGuardian();\\n\\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\\n\\n _checkApprover(_approvers);\\n _checkDuplicateOnChainApprover(cutHash, _approvers);\\n\\n bool onChainOwnerApproval = getOwnerCutApprovalWithTimeValidity(\\n cutHash\\n );\\n\\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\\n if (\\n _approvers.length +\\n getDiamondCutApprovalCountWithTimeValidity(cutHash) <\\n LibGuardian.majorityOfGuardians() + threshold\\n ) revert DiamondCutFacet__InsufficientApprovers();\\n\\n bool ownerApproved;\\n for (uint256 i; i < _approvers.length; ) {\\n if (\\n !LibGuardian.isGuardian(_approvers[i]) &&\\n _approvers[i] != address(this)\\n ) revert DiamondCutFacet__InvalidApprover();\\n if (_approvers[i] == address(this)) {\\n if (onChainOwnerApproval)\\n revert DiamondCutFacet__OwnerAlreadyApproved();\\n ownerApproved = true;\\n }\\n if (\\n !SignatureChecker.isValidSignatureNow(\\n _approvers[i],\\n cutHash,\\n _signatures[i]\\n )\\n ) revert DiamondCutFacet__InvalidApproverSignature();\\n unchecked {\\n ++i;\\n }\\n }\\n if (!ownerApproved && !onChainOwnerApproval)\\n revert DiamondCutFacet__LackOfOwnerApproval();\\n\\n unchecked {\\n ++LibFacetStorage.diamondCutStorage().nonce;\\n }\\n LibDiamond.diamondCut(_diamondCut, address(0), \\\"\\\");\\n }\\n\\n /**\\n * @notice Approves diamond cut. This can only be called directly from guardian or owner\\n * @param _diamondCut Contains the facet addresses and function selectors\\n */\\n function approveDiamondCut(\\n FacetCut[] calldata _diamondCut\\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\\n if (LibGuardian.guardianCount() == 0)\\n revert DiamondCutFacet__InvalidRouteWithoutGuardian();\\n DiamondCutApprovalConfig storage ds = LibFacetStorage\\n .diamondCutStorage()\\n .diamondCutApprovalConfigs[INNER_STRUCT];\\n _checkFacetCutValidity(_diamondCut);\\n\\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\\n uint64 approvalValidUntil = uint64(\\n block.timestamp + getApprovalValidationPeriod()\\n );\\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(\\n true,\\n approvalValidUntil\\n );\\n emit DiamondCutApproved(_diamondCut);\\n if (\\n (getDiamondCutApprovalCountWithTimeValidity(cutHash) >=\\n LibGuardian.majorityOfGuardians()) &&\\n getOwnerCutApprovalWithTimeValidity(cutHash)\\n ) {\\n unchecked {\\n ++LibFacetStorage.diamondCutStorage().nonce;\\n }\\n LibDiamond.diamondCut(_diamondCut, address(0), \\\"\\\");\\n }\\n }\\n\\n /**\\n * @notice Revokes the approval of diamond cut. This can only be called directly from guardian or owner\\n * @param _diamondCut Contains the facet addresses and function selectors\\n */\\n function revokeDiamondCutApproval(\\n FacetCut[] calldata _diamondCut\\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\\n DiamondCutApprovalConfig storage ds = LibFacetStorage\\n .diamondCutStorage()\\n .diamondCutApprovalConfigs[INNER_STRUCT];\\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\\n if (!ds.isDiamondCutApproved[cutHash][msg.sender].isApproved)\\n revert DiamondCutFacet__CannotRevokeUnapproved();\\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(false, 0);\\n emit DiamondCutApprovalRevoked(_diamondCut);\\n }\\n\\n /**\\n * @notice Gets the number of approvals of diamond cut from guardians\\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\\n */\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 _diamondCutHash\\n ) public view override returns (uint256 approvalCount) {\\n address[] memory guardians = LibGuardian.getGuardians();\\n uint256 guardiansLength = guardians.length;\\n for (uint256 i; i < guardiansLength; ) {\\n if (isCutApproved(_diamondCutHash, guardians[i])) {\\n unchecked {\\n ++approvalCount;\\n }\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n return approvalCount;\\n }\\n\\n /**\\n * @notice Returns if the owner has approved the diamond cut\\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\\n * @return isApprovedByOwner Bool value showing if the owner approved the cut\\n */\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 _diamondCutHash\\n ) public view override returns (bool isApprovedByOwner) {\\n isApprovedByOwner = isCutApproved(_diamondCutHash, address(this));\\n }\\n\\n /**\\n * @notice Returns if the given approver has approved the diamond cut\\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\\n * @param _approver Address of approver\\n * @return isApproved Bool value showing if the approver approved the cut\\n */\\n function isCutApproved(\\n bytes32 _diamondCutHash,\\n address _approver\\n ) public view override returns (bool isApproved) {\\n DiamondCutApprovalConfig storage ds = LibFacetStorage\\n .diamondCutStorage()\\n .diamondCutApprovalConfigs[INNER_STRUCT];\\n isApproved = (ds\\n .isDiamondCutApproved[_diamondCutHash][_approver].isApproved &&\\n block.timestamp <\\n ds.isDiamondCutApproved[_diamondCutHash][_approver].validUntil);\\n }\\n\\n /**\\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\\n * Approvers who approved on-chain should not be included in the off-chain approval\\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\\n * @param _approvers List of approver addresses\\n */\\n function _checkDuplicateOnChainApprover(\\n bytes32 _diamondCutHash,\\n address[] memory _approvers\\n ) public view {\\n address[] memory guardians = LibGuardian.getGuardians();\\n uint256 guardianLength = guardians.length;\\n uint256 approversLength = _approvers.length;\\n for (uint256 i; i < guardianLength; ) {\\n if (isCutApproved(_diamondCutHash, guardians[i])) {\\n for (uint256 j; j < approversLength; ) {\\n if (_approvers[j] == guardians[i])\\n revert DiamondCutFacet__DuplicateApproval();\\n unchecked {\\n ++j;\\n }\\n }\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * @notice Returns the diamond cut hash. This function ensures that this hash is safe from replay attack by including\\n * salt, address, chainId, and nonce, etc.\\n * @param _diamondCut Contains the facet addresses and function selectors\\n * @return cutHash Diamond Cut Hash\\n */\\n function getDiamondCutHash(\\n FacetCut[] calldata _diamondCut\\n ) public view override returns (bytes32 cutHash) {\\n cutHash = keccak256(\\n abi.encodePacked(\\n \\\"\\\\x19Ethereum Signed Message:\\\\n32\\\",\\n keccak256(\\n abi.encode(\\n keccak256(abi.encode(_diamondCut)),\\n address(this),\\n block.chainid,\\n LibFacetStorage.diamondCutStorage().nonce\\n )\\n )\\n )\\n );\\n }\\n\\n /**\\n * @notice Returns the approval validation Period\\n * @dev This method fetches the validation period from the security manager\\n * @return approvalValidationPeriod Approval validation period of Barz contract fetched from security manager\\n */\\n function getApprovalValidationPeriod()\\n internal\\n view\\n returns (uint256 approvalValidationPeriod)\\n {\\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\\n address(this)\\n );\\n if (approvalValidationPeriod <= 0)\\n revert DiamondCutFacet__InvalidApprovalValidationPeriod();\\n }\\n\\n /**\\n * @notice Returns the diamond cut nonce of this wallet\\n * @dev This method fetches the nonce from diamond cut storage\\n * @return cutNonce Nonce of diamond cut to protect from reply attacks\\n */\\n function getDiamondCutNonce()\\n public\\n view\\n override\\n returns (uint128 cutNonce)\\n {\\n cutNonce = LibFacetStorage.diamondCutStorage().nonce;\\n }\\n}\\n\",\"keccak256\":\"0xe91a7dd2daabf2e989c94089f4f1eb0da94276c3070559ac8988838e10dd1f5d\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/infrastructure/interfaces/IFacetRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Registry Interface\\n * @dev Interface for Facet Registry contract to keep track of facets & function selectors addable to user wallets\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IFacetRegistry {\\n struct FacetRegistryConfig {\\n bytes4[] selectors;\\n mapping(bytes4 => FacetInfo) info;\\n }\\n struct FacetInfo {\\n bool exists;\\n uint128 index;\\n }\\n\\n event FacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] facetSelectors\\n );\\n event FacetFunctionSelectorsRemoved(address facet, bytes4[] facetSelectors);\\n\\n error FacetRegistry__FacetSelectorAlreadyRegistered();\\n error FacetRegistry__UnregisteredFacetSelector();\\n\\n function registerFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function removeFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function areFacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external view returns (bool);\\n\\n function isFacetFunctionSelectorRegistered(\\n address facet,\\n bytes4 facetSelector\\n ) external view returns (bool);\\n\\n function getFacetFunctionSelectors(\\n address facet\\n ) external view returns (bytes4[] memory);\\n}\\n\",\"keccak256\":\"0x6e6dd2cab346ef7c31230740ec48d2925e4a9ab24c2f2fb268baaf408dcf02ef\",\"license\":\"Apache-2.0\"},\"contracts/infrastructure/interfaces/ISecurityManager.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Registry Interface\\n * @dev Infrastructure contract to manage security parameters of users\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\ninterface ISecurityManager {\\n error SecurityManager__OutOfBoundary();\\n error SecurityManager__CallerNotWallet();\\n error SecurityManager__AlreadyIntialized();\\n\\n function initializeAdditionSecurityPeriod(\\n uint128 defaultAdditionSecurityPeriod,\\n uint128 minAdditionSecurityPeriod,\\n uint128 maxAdditionSecurityPeriod\\n ) external;\\n\\n function initializeRemovalSecurityPeriod(\\n uint128 defaultRemovalSecurityPeriod,\\n uint128 minRemovalSecurityPeriod,\\n uint128 maxRemovalSecurityPeriod\\n ) external;\\n\\n function initializeApprovalValidationPeriod(\\n uint128 defaultApprovalValidationPeriod,\\n uint128 minApprovalValidationPeriod,\\n uint128 maxApprovalValidationPeriod\\n ) external;\\n\\n function initializeMigrationPeriod(\\n uint128 defaultMigrationPeriod,\\n uint128 minMigrationPeriod,\\n uint128 maxMigrationPeriod\\n ) external;\\n\\n function initializeLockPeriod(\\n uint128 defaultLockPeriod,\\n uint128 minLockPeriod,\\n uint128 maxLockPeriod\\n ) external;\\n\\n function initializeRecoveryPeriod(\\n uint128 defaultRecoveryPeriod,\\n uint128 minRecoveryPeriod,\\n uint128 maxRecoveryPeriod\\n ) external;\\n\\n function initializeSecurityWindow(\\n uint128 defaultSecurityWindow,\\n uint128 minSecurityWindow,\\n uint128 maxSecurityWindow\\n ) external;\\n\\n function setAdditionSecurityPeriod(\\n address wallet,\\n uint128 additionSecurityPeriod\\n ) external;\\n\\n function setRemovalSecurityPeriod(\\n address wallet,\\n uint128 removalSecurityPeriod\\n ) external;\\n\\n function setSecurityWindow(address wallet, uint128 securityWindow) external;\\n\\n function setRecoveryPeriod(address wallet, uint128 recoveryPeriod) external;\\n\\n function setLockPeriod(address wallet, uint128 lockPeriod) external;\\n\\n function setApprovalValidationPeriod(\\n address wallet,\\n uint128 approvalValidationPeriod\\n ) external;\\n\\n function setMigrationPeriod(\\n address wallet,\\n uint128 migrationPeriod\\n ) external;\\n\\n function additionSecurityPeriodOf(\\n address wallet\\n ) external view returns (uint128);\\n\\n function removalSecurityPeriodOf(\\n address wallet\\n ) external view returns (uint128);\\n\\n function securityWindowOf(address wallet) external view returns (uint128);\\n\\n function recoveryPeriodOf(address wallet) external view returns (uint128);\\n\\n function lockPeriodOf(address wallet) external view returns (uint128);\\n\\n function migrationPeriodOf(address wallet) external view returns (uint128);\\n\\n function approvalValidationPeriodOf(\\n address wallet\\n ) external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x9ac6566033ef81ba5744c8ed2b08f130b781b498ab9245bcca87567669549552\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibAppStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {SafeCast} from \\\"@openzeppelin/contracts/utils/math/SafeCast.sol\\\";\\nimport {IEntryPoint} from \\\"../aa-4337/interfaces/IEntryPoint.sol\\\";\\nimport {IFacetRegistry} from \\\"../infrastructure/interfaces/IFacetRegistry.sol\\\";\\n\\n/*\\n * @title App Storage\\n * @dev App storage for Barz contract to prevent storage collision\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Lock {\\n uint64 release;\\n bytes4 locker;\\n}\\n\\nstruct InitializersStorage {\\n // NOTE: initialized is a variable to make sure the initialization is only done once.\\n uint8 signerInitialized;\\n uint8 accountInitialized;\\n uint8 restrictionsInitialized;\\n}\\n\\nstruct AppStorage {\\n mapping(uint256 => InitializersStorage) initStorage;\\n uint8 signerMigration;\\n bytes4 validateOwnerSignatureSelector;\\n IEntryPoint entryPoint;\\n IFacetRegistry facetRegistry;\\n mapping(uint256 => Lock) locks;\\n}\\n\\nlibrary LibAppStorage {\\n error LibAppStorage__AccountAlreadyUninitialized();\\n error LibAppStorage__AccountMustBeUninitialized();\\n error LibAppStorage__SignerAlreadyUninitialized();\\n error LibAppStorage__SignerMustBeUninitialized();\\n\\n function appStorage() internal pure returns (AppStorage storage ds) {\\n assembly {\\n ds.slot := 0\\n }\\n }\\n\\n function setSignerUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerAlreadyUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 0;\\n }\\n\\n function getValidateOwnerSignatureSelector()\\n internal\\n view\\n returns (bytes4 selector)\\n {\\n selector = appStorage().validateOwnerSignatureSelector;\\n }\\n\\n function setValidateOwnerSignatureSelector(\\n bytes4 _validateOwnerSignatureSelector\\n ) internal {\\n appStorage()\\n .validateOwnerSignatureSelector = _validateOwnerSignatureSelector;\\n }\\n\\n function enforceSignerInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerMustBeUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 1;\\n }\\n\\n function enforceAccountInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].accountInitialized) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n s.initStorage[0].accountInitialized = 1;\\n }\\n\\n function initiateSignerMigration() internal {\\n appStorage().signerMigration = 1;\\n }\\n\\n function enforceSignerMigration() internal view {\\n if (1 != appStorage().signerMigration) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n }\\n\\n function finalizeSignerMigration() internal {\\n appStorage().signerMigration = 0;\\n }\\n\\n function setLock(uint256 _releaseAfter, bytes4 _locker) internal {\\n appStorage().locks[0] = Lock(SafeCast.toUint64(_releaseAfter), _locker);\\n }\\n\\n function enforceRestrictionsInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__SignerMustBeUninitialized();\\n s.initStorage[0].restrictionsInitialized = 1;\\n }\\n\\n function setRestrictionsUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__AccountAlreadyUninitialized();\\n s.initStorage[0].restrictionsInitialized = 0;\\n }\\n}\\n\\ncontract BarzStorage {\\n AppStorage internal s;\\n modifier onlyWhenUnlocked() {\\n require(\\n uint64(block.timestamp) >= s.locks[0].release,\\n \\\"Account Locked\\\"\\n );\\n _;\\n }\\n modifier onlyWhenLocked() {\\n require(\\n uint64(block.timestamp) < s.locks[0].release,\\n \\\"Account Unlocked\\\"\\n );\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x48524007862a6ce0e07f645950613ce6513ce073c37a109c75019683d42bae27\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\\n bytes4(keccak256(\\\"verifyRestrictions(address,address,uint256,bytes)\\\"));\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // Default Fallback Handler of the barz.\\n IDiamondLoupe defaultFallbackHandler;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function enforceIsSelf() internal view {\\n require(msg.sender == address(this), \\\"LibDiamond: Caller not self\\\");\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n\\n unchecked {\\n facetIndex++;\\n }\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n\\n function restrictionsFacet() internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(\\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2cabdc00de859c3a3170ce3bda5d0e5fd3933d47ce904fd1585f9818b02572f8\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibFacetStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Storage\\n * @dev Storage contract to store each facets variables with diamond storage\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Secp256k1VerificationStorage {\\n address signer;\\n}\\n\\nstruct Secp256r1VerificationStorage {\\n uint256[2] q;\\n}\\n\\nstruct GuardianStorage {\\n mapping(bytes32 => uint256) pending;\\n mapping(uint8 => StorageConfig) configs;\\n}\\n\\nstruct Info {\\n bool exists;\\n uint128 index;\\n}\\n\\nstruct StorageConfig {\\n address[] addresses;\\n mapping(address => Info) info;\\n}\\n\\nstruct RecoveryConfig {\\n bytes recoveryPublicKey;\\n uint64 executeAfter;\\n}\\n\\nstruct ApprovalConfig {\\n bool isApproved;\\n uint64 validUntil;\\n}\\n\\nstruct RecoveryApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isNewOwnerApproved;\\n}\\n\\nstruct RecoveryStorage {\\n mapping(uint8 => RecoveryConfig) recoveryConfigs;\\n mapping(uint8 => RecoveryApprovalConfig) recoveryApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct RestrictionsStorage {\\n address[] restrictions;\\n mapping(address => bool) exists;\\n}\\n\\nstruct SignatureMigrationConfig {\\n bytes migrationPublicKey;\\n address migrationVerificationFacet;\\n bytes4[] migrationSelectors;\\n uint64 migrateAfter;\\n}\\n\\nstruct SignatureMigrationApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isMigrationApproved;\\n}\\n\\nstruct SignatureMigrationStorage {\\n mapping(uint8 => SignatureMigrationConfig) migrationConfigs;\\n mapping(uint8 => SignatureMigrationApprovalConfig) migrationApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct DiamondCutApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isDiamondCutApproved;\\n}\\n\\nstruct DiamondCutStorage {\\n mapping(uint8 => DiamondCutApprovalConfig) diamondCutApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct LockStorage {\\n uint128 nonce;\\n}\\n\\nlibrary LibFacetStorage {\\n bytes32 constant K1_STORAGE_POSITION =\\n keccak256(\\n \\\"v0.trustwallet.diamond.storage.Secp256k1VerificationStorage\\\"\\n );\\n bytes32 constant R1_STORAGE_POSITION =\\n keccak256(\\n \\\"v0.trustwallet.diamond.storage.Secp256r1VerificationStorage\\\"\\n );\\n bytes32 constant GUARDIAN_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.GuardianStorage\\\");\\n bytes32 constant RECOVERY_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.RecoveryStorage\\\");\\n bytes32 constant RESTRICTION_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.RestrictionsStorage\\\");\\n bytes32 constant MIGRATION_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.SignatureMigrationStorage\\\");\\n bytes32 constant DIAMONDCUT_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.DiamondCutStorage\\\");\\n bytes32 constant LOCK_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.LockStorage\\\");\\n\\n function k1Storage()\\n internal\\n pure\\n returns (Secp256k1VerificationStorage storage ds)\\n {\\n bytes32 storagePosition = K1_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function r1Storage()\\n internal\\n pure\\n returns (Secp256r1VerificationStorage storage ds)\\n {\\n bytes32 storagePosition = R1_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function guardianStorage()\\n internal\\n pure\\n returns (GuardianStorage storage ds)\\n {\\n bytes32 storagePosition = GUARDIAN_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function recoveryStorage()\\n internal\\n pure\\n returns (RecoveryStorage storage ds)\\n {\\n bytes32 storagePosition = RECOVERY_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function restrictionsStorage()\\n internal\\n pure\\n returns (RestrictionsStorage storage ds)\\n {\\n bytes32 storagePosition = RESTRICTION_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function migrationStorage()\\n internal\\n pure\\n returns (SignatureMigrationStorage storage ds)\\n {\\n bytes32 storagePosition = MIGRATION_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function diamondCutStorage()\\n internal\\n pure\\n returns (DiamondCutStorage storage ds)\\n {\\n bytes32 storagePosition = DIAMONDCUT_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function lockStorage() internal pure returns (LockStorage storage ds) {\\n bytes32 storagePosition = LOCK_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n}\\n\",\"keccak256\":\"0x87c85decfd943deda9540733e464cb1a92eba735a301e89ce6f798016e359761\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibGuardian.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {LibFacetStorage, StorageConfig} from \\\"./LibFacetStorage.sol\\\";\\n\\n/**\\n * @title LibGuardian\\n * @dev Internal Library to provide utility feature for Guardians stored in Guardian Facet Storage\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\nlibrary LibGuardian {\\n function majorityOfGuardians()\\n internal\\n view\\n returns (uint256 guardianNumber)\\n {\\n uint256 guardianLength = guardianCount();\\n guardianNumber = (guardianLength == 0) ? 0 : guardianLength / 2 + 1;\\n }\\n\\n function isGuardian(address _guardian) internal view returns (bool) {\\n StorageConfig storage config = LibFacetStorage\\n .guardianStorage()\\n .configs[0];\\n return config.info[_guardian].exists;\\n }\\n\\n function guardianCount() internal view returns (uint256) {\\n StorageConfig storage config = LibFacetStorage\\n .guardianStorage()\\n .configs[0];\\n return config.addresses.length;\\n }\\n\\n function getGuardians() internal view returns (address[] memory) {\\n StorageConfig storage config = LibFacetStorage\\n .guardianStorage()\\n .configs[0];\\n address[] memory addresses = new address[](config.addresses.length);\\n uint256 addressesLen = config.addresses.length;\\n for (uint256 i; i < addressesLen; ) {\\n addresses[i] = config.addresses[i];\\n unchecked {\\n ++i;\\n }\\n }\\n return addresses;\\n }\\n}\\n\",\"keccak256\":\"0x6a620992d5535878fc03d1a27a6675f4c1509adfb3ddbbca1c52b546c25392dc\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x60a06040523480156200001157600080fd5b506040516200379b3803806200379b833981016040819052620000349162000046565b6001600160a01b031660805262000078565b6000602082840312156200005957600080fd5b81516001600160a01b03811681146200007157600080fd5b9392505050565b6080516137006200009b600039600081816101f10152611b2501526137006000f3fe608060405234801561001057600080fd5b50600436106100d45760003560e01c806379c0d58d11610081578063afb877bb1161005b578063afb877bb146101d9578063de675a6d146101ec578063e33ecf0a1461023857600080fd5b806379c0d58d14610192578063836d6bfb146101b35780638824a0bb146101c657600080fd5b806326fc3ef4116100b257806326fc3ef4146101145780632f4d98ea1461015c5780633c0985681461017f57600080fd5b806313c34f4b146100d95780631c776dd5146100ee5780631f931c1c14610101575b600080fd5b6100ec6100e7366004612a97565b61024b565b005b6100ec6100fc366004612ad9565b6104df565b6100ec61010f366004612b9c565b610a76565b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9bf546040516fffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b61016f61016a366004612c4a565b610c7b565b6040519015158152602001610153565b6100ec61018d366004612ca4565b610c8d565b6101a56101a0366004612c4a565b610df2565b604051908152602001610153565b61016f6101c1366004612cdb565b610e4c565b6100ec6101d4366004612dd2565b610eed565b6100ec6101e7366004612a97565b610fe1565b6102137f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610153565b6101a5610246366004612a97565b61130e565b3360009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff1615801561028a5750303314155b156102c1576040517f6238ee3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610369576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064015b60405180910390fd5b60008080527f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be6020527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d3906103be848461130e565b60008181526020848152604080832033845290915290205490915060ff16610412576040517fedc5708300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051808201825260008082526020808301828152858352868252848320338452909152908390209151825491517fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000009092169015157fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff161761010067ffffffffffffffff90921691909102179055517f3c3d8c1f0b0faff6fe0ace6b485d0595a0106dce9e303f956fd941ebdbe9a98e906104d19086908690612f54565b60405180910390a150505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610582576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b8281146105bb576040517fe854148500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6105cd6105c886886130aa565b611435565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b754600003610650576040517fa788861700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061065c878761130e565b905061069a8585808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506115b392505050565b506106d881868680806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250610eed92505050565b60006106e382610c7b565b90506000816106f35760016106f6565b60005b60ff169050806107046116d0565b61070e9190613201565b61071784610df2565b6107219088613201565b1015610759576040517f709fb08000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805b878110156109a0576107d989898381811061077a5761077a613214565b905060200201602081019061078f9190613243565b73ffffffffffffffffffffffffffffffffffffffff1660009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff1690565b1580156108225750308989838181106107f4576107f4613214565b90506020020160208101906108099190613243565b73ffffffffffffffffffffffffffffffffffffffff1614155b15610859576040517f7b2cbbb400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3089898381811061086c5761086c613214565b90506020020160208101906108819190613243565b73ffffffffffffffffffffffffffffffffffffffff16036108d95783156108d4576040517fee21708000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600191505b6109628989838181106108ee576108ee613214565b90506020020160208101906109039190613243565b8689898581811061091657610916613214565b90506020028101906109289190613265565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061174f92505050565b610998576040517fac3d341600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60010161075d565b50801580156109ad575082155b156109e4576040517f6d21730400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9bf80546fffffffffffffffffffffffffffffffff808216600101167fffffffffffffffffffffffffffffffff00000000000000000000000000000000909116179055610a6a610a538a8c6130aa565b6000604051806020016040528060008152506117ca565b50505050505050505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610b19576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b610b2161195f565b610b2e6105c885876130aa565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75415610baf576040517fa788861700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff831615610bfd576040517f871cb76100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be5b600190810180547fffffffffffffffffffffffffffffffff0000000000000000000000000000000081166fffffffffffffffffffffffffffffffff91821690930116919091179055610c74610a5385876130aa565b5050505050565b6000610c878230610e4c565b92915050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610d30576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b610d3861195f565b7fffffffff00000000000000000000000000000000000000000000000000000000821660008181527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4922602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001685151590811790915582519384529083015280517f4e6bd17989efa6d6a9607ccaac1bba27b29f99622bc830d99a3a9883b21a19c79281900390910190a15050565b600080610dfd6119ca565b805190915060005b81811015610e4457610e3085848381518110610e2357610e23613214565b6020026020010151610e4c565b15610e3c578360010193505b600101610e05565b505050919050565b60008281527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d36020818152604080842073ffffffffffffffffffffffffffffffffffffffff8616855290915282205460ff168015610ee5575060008481526020828152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152902054610100900467ffffffffffffffff1642105b949350505050565b6000610ef76119ca565b805183519192509060005b82811015610fd957610f2086858381518110610e2357610e23613214565b15610fd15760005b82811015610fcf57848281518110610f4257610f42613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16868281518110610f7257610f72613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603610fc7576040517f50f5729f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600101610f28565b505b600101610f02565b505050505050565b3360009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff161580156110205750303314155b15611057576040517f6238ee3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff9081164290911610156110fa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75460000361117d576040517f3a76e1f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080527f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be6020527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d36111d36105c883856130aa565b60006111df848461130e565b905060006111eb611af4565b6111f59042613201565b6040805180820182526001815267ffffffffffffffff838116602080840191825260008881528982528581203382529091528490209251835491517fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000009092169015157fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff16176101009190921602179055519091507f6248ff757895beed7d43d135bccf59a26b7fbdf0fe8233487c44e82c0f266ba3906112b89087908790612f54565b60405180910390a16112c86116d0565b6112d183610df2565b101580156112e357506112e382610c7b565b15610c74577f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be610c1f565b60008282604051602001611323929190612f54565b6040516020818303038152906040528051906020012030466113627f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be90565b6001015460408051602081019590955273ffffffffffffffffffffffffffffffffffffffff9093169284019290925260608301526fffffffffffffffffffffffffffffffff16608082015260a001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905280516020918201207f19457468657265756d205369676e6564204d6573736167653a0a33320000000091830191909152603c820152605c0160405160208183030381529060405280519060200120905092915050565b805160005b818110156115ae57600083828151811061145657611456613214565b602002602001015160200151600281111561147357611473612e8a565b14806114ad5750600183828151811061148e5761148e613214565b60200260200101516020015160028111156114ab576114ab612e8a565b145b156115a657600254835173ffffffffffffffffffffffffffffffffffffffff9091169063df871f72908590849081106114e8576114e8613214565b60200260200101516000015185848151811061150657611506613214565b6020026020010151604001516040518363ffffffff1660e01b815260040161152f92919061331c565b602060405180830381865afa15801561154c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611570919061334b565b6115a6576040517ff41a931c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60010161143a565b505050565b80516000908082036115f1576040517f3aee2eec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b6115ff600183613368565b8110156116c6576000611613826001613201565b90505b828110156116bd5784818151811061163057611630613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1685838151811061166057611660613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16036116b5576040517f8dd19e7d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600101611616565b506001016115f4565b5060009392505050565b600080611723600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75490565b905080156117465761173660028261337b565b611741906001613201565b611749565b60005b91505090565b600080600061175e8585611bf6565b9092509050600081600481111561177757611777612e8a565b1480156117af57508573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b806117c057506117c0868686611c3b565b9695505050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921547f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff8116908190600090600716156118395750600381901c60009081526001840160205260409020545b60005b87518110156118b6576118a983838a848151811061185c5761185c613214565b6020026020010151600001518b858151811061187a5761187a613214565b6020026020010151602001518c868151811061189857611898613214565b602002602001015160400151611d98565b909350915060010161183c565b508282146118ef576002840180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff84161790555b600782161561191157600382901c600090815260018501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb67387878760405161194493929190613424565b60405180910390a16119568686612829565b50505050505050565b3330146119c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4c69624469616d6f6e643a2043616c6c6572206e6f742073656c6600000000006044820152606401610360565b565b60008080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b780546060929067ffffffffffffffff811115611a3257611a32612d07565b604051908082528060200260200182016040528015611a5b578160200160208202803683370190505b50825490915060005b81811015611aeb57836000018181548110611a8157611a81613214565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16838281518110611abe57611abe613214565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101611a64565b50909392505050565b6040517f52430c8d0000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906352430c8d90602401602060405180830381865afa158015611b81573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ba59190613510565b6fffffffffffffffffffffffffffffffff16905060008111611bf3576040517fdac5ec8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b90565b6000808251604103611c2c5760208301516040840151606085015160001a611c2087828585612928565b94509450505050611c34565b506000905060025b9250929050565b60008060008573ffffffffffffffffffffffffffffffffffffffff16631626ba7e60e01b8686604051602401611c72929190613542565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909416939093179092529051611cfb919061355b565b600060405180830381855afa9150503d8060008114611d36576040519150601f19603f3d011682016040523d82523d6000602084013e611d3b565b606091505b5091509150818015611d4f57506020815110155b80156117c0575080517f1626ba7e0000000000000000000000000000000000000000000000000000000090611d8d9083016020908101908401613577565b149695505050505050565b600080807f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f90506000845111611e50576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610360565b6000856002811115611e6457611e64612e8a565b0361203457611e8b8660405180606001604052806024815260200161365760249139612a17565b60005b845181101561202e576000858281518110611eab57611eab613214565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c15611f7e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c72656164792065786973747300000000000000000000006064820152608401610360565b7fffffffff0000000000000000000000000000000000000000000000000000000080831660008181526020879052604090207fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608d901b168e17905560e060058e901b811692831c199c909c1690821c179a8190036120125760038c901c600090815260018601602052604081209b909b555b8b61201c81613590565b9c505060019093019250611e8e915050565b5061281d565b600185600281111561204857612048612e8a565b036123385761206f866040518060600160405280602881526020016136a360289139612a17565b60005b845181101561202e57600085828151811061208f5761208f613214565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c308103612164576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4c69624469616d6f6e644375743a2043616e2774207265706c61636520696d6d60448201527f757461626c652066756e6374696f6e00000000000000000000000000000000006064820152608401610360565b8973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361221f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e00000000000000006064820152608401610360565b73ffffffffffffffffffffffffffffffffffffffff81166122c2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e207468617420646f65736e277420657869737400000000000000006064820152608401610360565b507fffffffff0000000000000000000000000000000000000000000000000000000090911660009081526020849052604090206bffffffffffffffffffffffff919091167fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608a901b16179055600101612072565b600285600281111561234c5761234c612e8a565b036127955773ffffffffffffffffffffffffffffffffffffffff8616156123f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d7573742062652061646472657373283029000000000000000000006064820152608401610360565b600388901c6007891660005b86518110156127755760008a900361243d578261241d816135c8565b60008181526001870160205260409020549b5093506007925061244b9050565b81612447816135c8565b9250505b6000806000808a858151811061246357612463613214565b6020908102919091018101517fffffffff0000000000000000000000000000000000000000000000000000000081166000908152918a9052604090912054909150606081901c612535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608401610360565b30606082901c036125c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e0000000000000000000000000000000000006064820152608401610360565b600587901b8f901b94507fffffffff0000000000000000000000000000000000000000000000000000000080861690831614612666577fffffffff000000000000000000000000000000000000000000000000000000008516600090815260208a90526040902080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff83161790555b7fffffffff0000000000000000000000000000000000000000000000000000000091909116600090815260208990526040812055600381901c611fff16925060051b60e01690508582146126fb576000828152600188016020526040902080547fffffffff0000000000000000000000000000000000000000000000000000000080841c19909116908516831c17905561274c565b80837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c817fffffffff0000000000000000000000000000000000000000000000000000000060001b901c198e16179c505b8460000361276a57600086815260018801602052604081208190559c505b505050600101612401565b50806127828360086135fd565b61278c9190613201565b9950505061281d565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560448201527f74416374696f6e000000000000000000000000000000000000000000000000006064820152608401610360565b50959694955050505050565b73ffffffffffffffffffffffffffffffffffffffff8216612848575050565b61286a8260405180606001604052806028815260200161367b60289139612a17565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051612892919061355b565b600060405180830381855af49150503d80600081146128cd576040519150601f19603f3d011682016040523d82523d6000602084013e6128d2565b606091505b509150915081612922578051156128ec5780518082602001fd5b83836040517f192105d7000000000000000000000000000000000000000000000000000000008152600401610360929190613614565b50505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561295f5750600090506003612a0e565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156129b3573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116612a0757600060019250925050612a0e565b9150600090505b94509492505050565b813b8181612922576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103609190613643565b60008083601f840112612a6457600080fd5b50813567ffffffffffffffff811115612a7c57600080fd5b6020830191508360208260051b8501011115611c3457600080fd5b60008060208385031215612aaa57600080fd5b823567ffffffffffffffff811115612ac157600080fd5b612acd85828601612a52565b90969095509350505050565b60008060008060008060608789031215612af257600080fd5b863567ffffffffffffffff80821115612b0a57600080fd5b612b168a838b01612a52565b90985096506020890135915080821115612b2f57600080fd5b612b3b8a838b01612a52565b90965094506040890135915080821115612b5457600080fd5b50612b6189828a01612a52565b979a9699509497509295939492505050565b803573ffffffffffffffffffffffffffffffffffffffff81168114612b9757600080fd5b919050565b600080600080600060608688031215612bb457600080fd5b853567ffffffffffffffff80821115612bcc57600080fd5b612bd889838a01612a52565b9097509550859150612bec60208901612b73565b94506040880135915080821115612c0257600080fd5b818801915088601f830112612c1657600080fd5b813581811115612c2557600080fd5b896020828501011115612c3757600080fd5b9699959850939650602001949392505050565b600060208284031215612c5c57600080fd5b5035919050565b80357fffffffff0000000000000000000000000000000000000000000000000000000081168114612b9757600080fd5b8015158114612ca157600080fd5b50565b60008060408385031215612cb757600080fd5b612cc083612c63565b91506020830135612cd081612c93565b809150509250929050565b60008060408385031215612cee57600080fd5b82359150612cfe60208401612b73565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff81118282101715612d5957612d59612d07565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715612da657612da6612d07565b604052919050565b600067ffffffffffffffff821115612dc857612dc8612d07565b5060051b60200190565b60008060408385031215612de557600080fd5b8235915060208084013567ffffffffffffffff811115612e0457600080fd5b8401601f81018613612e1557600080fd5b8035612e28612e2382612dae565b612d5f565b81815260059190911b82018301908381019088831115612e4757600080fd5b928401925b82841015612e6c57612e5d84612b73565b82529284019290840190612e4c565b80955050505050509250929050565b803560038110612b9757600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60038110612ef0577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b8183526000602080850194508260005b85811015612f49577fffffffff00000000000000000000000000000000000000000000000000000000612f3683612c63565b1687529582019590820190600101612f04565b509495945050505050565b60208082528181018390526000906040808401600586811b8601830188865b8981101561309b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc089840301855281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa18c3603018112612fd457600080fd5b8b01606073ffffffffffffffffffffffffffffffffffffffff612ff683612b73565b168552613004898301612e7b565b6130108a870182612eb9565b50878201357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe183360301811261304557600080fd5b90910188810191903567ffffffffffffffff81111561306357600080fd5b80871b360383131561307457600080fd5b81898701526130868287018285612ef4565b978a0197955050509187019150600101612f73565b50909998505050505050505050565b60006130b8612e2384612dae565b83815260208082019190600586811b8601368111156130d657600080fd5b865b818110156131c557803567ffffffffffffffff808211156130f95760008081fd5b818a0191506060823603121561310f5760008081fd5b613117612d36565b61312083612b73565b815261312d878401612e7b565b87820152604080840135838111156131455760008081fd5b939093019236601f85011261315c57600092508283fd5b8335925061316c612e2384612dae565b83815292871b840188019288810190368511156131895760008081fd5b948901945b848610156131ae5761319f86612c63565b8252948901949089019061318e565b9183019190915250885250509483019483016130d8565b5092979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610c8757610c876131d2565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561325557600080fd5b61325e82612b73565b9392505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261329a57600080fd5b83018035915067ffffffffffffffff8211156132b557600080fd5b602001915036819003821315611c3457600080fd5b600081518084526020808501945080840160005b83811015612f495781517fffffffff0000000000000000000000000000000000000000000000000000000016875295820195908201906001016132de565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000610ee560408301846132ca565b60006020828403121561335d57600080fd5b815161325e81612c93565b81810381811115610c8757610c876131d2565b6000826133b1577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60005b838110156133d15781810151838201526020016133b9565b50506000910152565b600081518084526133f28160208601602086016133b6565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6000606080830181845280875180835260808601915060808160051b87010192506020808a0160005b838110156134d4577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80898703018552815173ffffffffffffffffffffffffffffffffffffffff8151168752838101516134a885890182612eb9565b506040908101519087018890526134c1878901826132ca565b965050938201939082019060010161344d565b505073ffffffffffffffffffffffffffffffffffffffff8916908701525050838103604085015261350581866133da565b979650505050505050565b60006020828403121561352257600080fd5b81516fffffffffffffffffffffffffffffffff8116811461325e57600080fd5b828152604060208201526000610ee560408301846133da565b6000825161356d8184602087016133b6565b9190910192915050565b60006020828403121561358957600080fd5b5051919050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036135c1576135c16131d2565b5060010190565b6000816135d7576135d76131d2565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b8082028115828204841417610c8757610c876131d2565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000610ee560408301846133da565b60208152600061325e60208301846133da56fe4c69624469616d6f6e644375743a2041646420666163657420686173206e6f20636f64654c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a205265706c61636520666163657420686173206e6f20636f6465a2646970667358221220c5a8c10b22f20cde3fe0431ff57305237423677a60888f5b349fc6751336ae1464736f6c63430008150033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100d45760003560e01c806379c0d58d11610081578063afb877bb1161005b578063afb877bb146101d9578063de675a6d146101ec578063e33ecf0a1461023857600080fd5b806379c0d58d14610192578063836d6bfb146101b35780638824a0bb146101c657600080fd5b806326fc3ef4116100b257806326fc3ef4146101145780632f4d98ea1461015c5780633c0985681461017f57600080fd5b806313c34f4b146100d95780631c776dd5146100ee5780631f931c1c14610101575b600080fd5b6100ec6100e7366004612a97565b61024b565b005b6100ec6100fc366004612ad9565b6104df565b6100ec61010f366004612b9c565b610a76565b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9bf546040516fffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b61016f61016a366004612c4a565b610c7b565b6040519015158152602001610153565b6100ec61018d366004612ca4565b610c8d565b6101a56101a0366004612c4a565b610df2565b604051908152602001610153565b61016f6101c1366004612cdb565b610e4c565b6100ec6101d4366004612dd2565b610eed565b6100ec6101e7366004612a97565b610fe1565b6102137f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610153565b6101a5610246366004612a97565b61130e565b3360009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff1615801561028a5750303314155b156102c1576040517f6238ee3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610369576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064015b60405180910390fd5b60008080527f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be6020527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d3906103be848461130e565b60008181526020848152604080832033845290915290205490915060ff16610412576040517fedc5708300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051808201825260008082526020808301828152858352868252848320338452909152908390209151825491517fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000009092169015157fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff161761010067ffffffffffffffff90921691909102179055517f3c3d8c1f0b0faff6fe0ace6b485d0595a0106dce9e303f956fd941ebdbe9a98e906104d19086908690612f54565b60405180910390a150505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610582576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b8281146105bb576040517fe854148500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6105cd6105c886886130aa565b611435565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b754600003610650576040517fa788861700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061065c878761130e565b905061069a8585808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506115b392505050565b506106d881868680806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250610eed92505050565b60006106e382610c7b565b90506000816106f35760016106f6565b60005b60ff169050806107046116d0565b61070e9190613201565b61071784610df2565b6107219088613201565b1015610759576040517f709fb08000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805b878110156109a0576107d989898381811061077a5761077a613214565b905060200201602081019061078f9190613243565b73ffffffffffffffffffffffffffffffffffffffff1660009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff1690565b1580156108225750308989838181106107f4576107f4613214565b90506020020160208101906108099190613243565b73ffffffffffffffffffffffffffffffffffffffff1614155b15610859576040517f7b2cbbb400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3089898381811061086c5761086c613214565b90506020020160208101906108819190613243565b73ffffffffffffffffffffffffffffffffffffffff16036108d95783156108d4576040517fee21708000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600191505b6109628989838181106108ee576108ee613214565b90506020020160208101906109039190613243565b8689898581811061091657610916613214565b90506020028101906109289190613265565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061174f92505050565b610998576040517fac3d341600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60010161075d565b50801580156109ad575082155b156109e4576040517f6d21730400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9bf80546fffffffffffffffffffffffffffffffff808216600101167fffffffffffffffffffffffffffffffff00000000000000000000000000000000909116179055610a6a610a538a8c6130aa565b6000604051806020016040528060008152506117ca565b50505050505050505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610b19576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b610b2161195f565b610b2e6105c885876130aa565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75415610baf576040517fa788861700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff831615610bfd576040517f871cb76100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be5b600190810180547fffffffffffffffffffffffffffffffff0000000000000000000000000000000081166fffffffffffffffffffffffffffffffff91821690930116919091179055610c74610a5385876130aa565b5050505050565b6000610c878230610e4c565b92915050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610d30576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b610d3861195f565b7fffffffff00000000000000000000000000000000000000000000000000000000821660008181527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4922602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001685151590811790915582519384529083015280517f4e6bd17989efa6d6a9607ccaac1bba27b29f99622bc830d99a3a9883b21a19c79281900390910190a15050565b600080610dfd6119ca565b805190915060005b81811015610e4457610e3085848381518110610e2357610e23613214565b6020026020010151610e4c565b15610e3c578360010193505b600101610e05565b505050919050565b60008281527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d36020818152604080842073ffffffffffffffffffffffffffffffffffffffff8616855290915282205460ff168015610ee5575060008481526020828152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152902054610100900467ffffffffffffffff1642105b949350505050565b6000610ef76119ca565b805183519192509060005b82811015610fd957610f2086858381518110610e2357610e23613214565b15610fd15760005b82811015610fcf57848281518110610f4257610f42613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16868281518110610f7257610f72613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603610fc7576040517f50f5729f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600101610f28565b505b600101610f02565b505050505050565b3360009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff161580156110205750303314155b15611057576040517f6238ee3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff9081164290911610156110fa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75460000361117d576040517f3a76e1f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080527f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be6020527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d36111d36105c883856130aa565b60006111df848461130e565b905060006111eb611af4565b6111f59042613201565b6040805180820182526001815267ffffffffffffffff838116602080840191825260008881528982528581203382529091528490209251835491517fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000009092169015157fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff16176101009190921602179055519091507f6248ff757895beed7d43d135bccf59a26b7fbdf0fe8233487c44e82c0f266ba3906112b89087908790612f54565b60405180910390a16112c86116d0565b6112d183610df2565b101580156112e357506112e382610c7b565b15610c74577f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be610c1f565b60008282604051602001611323929190612f54565b6040516020818303038152906040528051906020012030466113627f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be90565b6001015460408051602081019590955273ffffffffffffffffffffffffffffffffffffffff9093169284019290925260608301526fffffffffffffffffffffffffffffffff16608082015260a001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905280516020918201207f19457468657265756d205369676e6564204d6573736167653a0a33320000000091830191909152603c820152605c0160405160208183030381529060405280519060200120905092915050565b805160005b818110156115ae57600083828151811061145657611456613214565b602002602001015160200151600281111561147357611473612e8a565b14806114ad5750600183828151811061148e5761148e613214565b60200260200101516020015160028111156114ab576114ab612e8a565b145b156115a657600254835173ffffffffffffffffffffffffffffffffffffffff9091169063df871f72908590849081106114e8576114e8613214565b60200260200101516000015185848151811061150657611506613214565b6020026020010151604001516040518363ffffffff1660e01b815260040161152f92919061331c565b602060405180830381865afa15801561154c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611570919061334b565b6115a6576040517ff41a931c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60010161143a565b505050565b80516000908082036115f1576040517f3aee2eec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b6115ff600183613368565b8110156116c6576000611613826001613201565b90505b828110156116bd5784818151811061163057611630613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1685838151811061166057611660613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16036116b5576040517f8dd19e7d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600101611616565b506001016115f4565b5060009392505050565b600080611723600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75490565b905080156117465761173660028261337b565b611741906001613201565b611749565b60005b91505090565b600080600061175e8585611bf6565b9092509050600081600481111561177757611777612e8a565b1480156117af57508573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b806117c057506117c0868686611c3b565b9695505050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921547f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff8116908190600090600716156118395750600381901c60009081526001840160205260409020545b60005b87518110156118b6576118a983838a848151811061185c5761185c613214565b6020026020010151600001518b858151811061187a5761187a613214565b6020026020010151602001518c868151811061189857611898613214565b602002602001015160400151611d98565b909350915060010161183c565b508282146118ef576002840180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff84161790555b600782161561191157600382901c600090815260018501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb67387878760405161194493929190613424565b60405180910390a16119568686612829565b50505050505050565b3330146119c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4c69624469616d6f6e643a2043616c6c6572206e6f742073656c6600000000006044820152606401610360565b565b60008080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b780546060929067ffffffffffffffff811115611a3257611a32612d07565b604051908082528060200260200182016040528015611a5b578160200160208202803683370190505b50825490915060005b81811015611aeb57836000018181548110611a8157611a81613214565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16838281518110611abe57611abe613214565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101611a64565b50909392505050565b6040517f52430c8d0000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906352430c8d90602401602060405180830381865afa158015611b81573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ba59190613510565b6fffffffffffffffffffffffffffffffff16905060008111611bf3576040517fdac5ec8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b90565b6000808251604103611c2c5760208301516040840151606085015160001a611c2087828585612928565b94509450505050611c34565b506000905060025b9250929050565b60008060008573ffffffffffffffffffffffffffffffffffffffff16631626ba7e60e01b8686604051602401611c72929190613542565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909416939093179092529051611cfb919061355b565b600060405180830381855afa9150503d8060008114611d36576040519150601f19603f3d011682016040523d82523d6000602084013e611d3b565b606091505b5091509150818015611d4f57506020815110155b80156117c0575080517f1626ba7e0000000000000000000000000000000000000000000000000000000090611d8d9083016020908101908401613577565b149695505050505050565b600080807f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f90506000845111611e50576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610360565b6000856002811115611e6457611e64612e8a565b0361203457611e8b8660405180606001604052806024815260200161365760249139612a17565b60005b845181101561202e576000858281518110611eab57611eab613214565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c15611f7e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c72656164792065786973747300000000000000000000006064820152608401610360565b7fffffffff0000000000000000000000000000000000000000000000000000000080831660008181526020879052604090207fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608d901b168e17905560e060058e901b811692831c199c909c1690821c179a8190036120125760038c901c600090815260018601602052604081209b909b555b8b61201c81613590565b9c505060019093019250611e8e915050565b5061281d565b600185600281111561204857612048612e8a565b036123385761206f866040518060600160405280602881526020016136a360289139612a17565b60005b845181101561202e57600085828151811061208f5761208f613214565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c308103612164576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4c69624469616d6f6e644375743a2043616e2774207265706c61636520696d6d60448201527f757461626c652066756e6374696f6e00000000000000000000000000000000006064820152608401610360565b8973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361221f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e00000000000000006064820152608401610360565b73ffffffffffffffffffffffffffffffffffffffff81166122c2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e207468617420646f65736e277420657869737400000000000000006064820152608401610360565b507fffffffff0000000000000000000000000000000000000000000000000000000090911660009081526020849052604090206bffffffffffffffffffffffff919091167fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608a901b16179055600101612072565b600285600281111561234c5761234c612e8a565b036127955773ffffffffffffffffffffffffffffffffffffffff8616156123f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d7573742062652061646472657373283029000000000000000000006064820152608401610360565b600388901c6007891660005b86518110156127755760008a900361243d578261241d816135c8565b60008181526001870160205260409020549b5093506007925061244b9050565b81612447816135c8565b9250505b6000806000808a858151811061246357612463613214565b6020908102919091018101517fffffffff0000000000000000000000000000000000000000000000000000000081166000908152918a9052604090912054909150606081901c612535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608401610360565b30606082901c036125c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e0000000000000000000000000000000000006064820152608401610360565b600587901b8f901b94507fffffffff0000000000000000000000000000000000000000000000000000000080861690831614612666577fffffffff000000000000000000000000000000000000000000000000000000008516600090815260208a90526040902080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff83161790555b7fffffffff0000000000000000000000000000000000000000000000000000000091909116600090815260208990526040812055600381901c611fff16925060051b60e01690508582146126fb576000828152600188016020526040902080547fffffffff0000000000000000000000000000000000000000000000000000000080841c19909116908516831c17905561274c565b80837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c817fffffffff0000000000000000000000000000000000000000000000000000000060001b901c198e16179c505b8460000361276a57600086815260018801602052604081208190559c505b505050600101612401565b50806127828360086135fd565b61278c9190613201565b9950505061281d565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560448201527f74416374696f6e000000000000000000000000000000000000000000000000006064820152608401610360565b50959694955050505050565b73ffffffffffffffffffffffffffffffffffffffff8216612848575050565b61286a8260405180606001604052806028815260200161367b60289139612a17565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051612892919061355b565b600060405180830381855af49150503d80600081146128cd576040519150601f19603f3d011682016040523d82523d6000602084013e6128d2565b606091505b509150915081612922578051156128ec5780518082602001fd5b83836040517f192105d7000000000000000000000000000000000000000000000000000000008152600401610360929190613614565b50505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561295f5750600090506003612a0e565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156129b3573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116612a0757600060019250925050612a0e565b9150600090505b94509492505050565b813b8181612922576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103609190613643565b60008083601f840112612a6457600080fd5b50813567ffffffffffffffff811115612a7c57600080fd5b6020830191508360208260051b8501011115611c3457600080fd5b60008060208385031215612aaa57600080fd5b823567ffffffffffffffff811115612ac157600080fd5b612acd85828601612a52565b90969095509350505050565b60008060008060008060608789031215612af257600080fd5b863567ffffffffffffffff80821115612b0a57600080fd5b612b168a838b01612a52565b90985096506020890135915080821115612b2f57600080fd5b612b3b8a838b01612a52565b90965094506040890135915080821115612b5457600080fd5b50612b6189828a01612a52565b979a9699509497509295939492505050565b803573ffffffffffffffffffffffffffffffffffffffff81168114612b9757600080fd5b919050565b600080600080600060608688031215612bb457600080fd5b853567ffffffffffffffff80821115612bcc57600080fd5b612bd889838a01612a52565b9097509550859150612bec60208901612b73565b94506040880135915080821115612c0257600080fd5b818801915088601f830112612c1657600080fd5b813581811115612c2557600080fd5b896020828501011115612c3757600080fd5b9699959850939650602001949392505050565b600060208284031215612c5c57600080fd5b5035919050565b80357fffffffff0000000000000000000000000000000000000000000000000000000081168114612b9757600080fd5b8015158114612ca157600080fd5b50565b60008060408385031215612cb757600080fd5b612cc083612c63565b91506020830135612cd081612c93565b809150509250929050565b60008060408385031215612cee57600080fd5b82359150612cfe60208401612b73565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff81118282101715612d5957612d59612d07565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715612da657612da6612d07565b604052919050565b600067ffffffffffffffff821115612dc857612dc8612d07565b5060051b60200190565b60008060408385031215612de557600080fd5b8235915060208084013567ffffffffffffffff811115612e0457600080fd5b8401601f81018613612e1557600080fd5b8035612e28612e2382612dae565b612d5f565b81815260059190911b82018301908381019088831115612e4757600080fd5b928401925b82841015612e6c57612e5d84612b73565b82529284019290840190612e4c565b80955050505050509250929050565b803560038110612b9757600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60038110612ef0577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b8183526000602080850194508260005b85811015612f49577fffffffff00000000000000000000000000000000000000000000000000000000612f3683612c63565b1687529582019590820190600101612f04565b509495945050505050565b60208082528181018390526000906040808401600586811b8601830188865b8981101561309b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc089840301855281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa18c3603018112612fd457600080fd5b8b01606073ffffffffffffffffffffffffffffffffffffffff612ff683612b73565b168552613004898301612e7b565b6130108a870182612eb9565b50878201357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe183360301811261304557600080fd5b90910188810191903567ffffffffffffffff81111561306357600080fd5b80871b360383131561307457600080fd5b81898701526130868287018285612ef4565b978a0197955050509187019150600101612f73565b50909998505050505050505050565b60006130b8612e2384612dae565b83815260208082019190600586811b8601368111156130d657600080fd5b865b818110156131c557803567ffffffffffffffff808211156130f95760008081fd5b818a0191506060823603121561310f5760008081fd5b613117612d36565b61312083612b73565b815261312d878401612e7b565b87820152604080840135838111156131455760008081fd5b939093019236601f85011261315c57600092508283fd5b8335925061316c612e2384612dae565b83815292871b840188019288810190368511156131895760008081fd5b948901945b848610156131ae5761319f86612c63565b8252948901949089019061318e565b9183019190915250885250509483019483016130d8565b5092979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610c8757610c876131d2565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561325557600080fd5b61325e82612b73565b9392505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261329a57600080fd5b83018035915067ffffffffffffffff8211156132b557600080fd5b602001915036819003821315611c3457600080fd5b600081518084526020808501945080840160005b83811015612f495781517fffffffff0000000000000000000000000000000000000000000000000000000016875295820195908201906001016132de565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000610ee560408301846132ca565b60006020828403121561335d57600080fd5b815161325e81612c93565b81810381811115610c8757610c876131d2565b6000826133b1577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60005b838110156133d15781810151838201526020016133b9565b50506000910152565b600081518084526133f28160208601602086016133b6565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6000606080830181845280875180835260808601915060808160051b87010192506020808a0160005b838110156134d4577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80898703018552815173ffffffffffffffffffffffffffffffffffffffff8151168752838101516134a885890182612eb9565b506040908101519087018890526134c1878901826132ca565b965050938201939082019060010161344d565b505073ffffffffffffffffffffffffffffffffffffffff8916908701525050838103604085015261350581866133da565b979650505050505050565b60006020828403121561352257600080fd5b81516fffffffffffffffffffffffffffffffff8116811461325e57600080fd5b828152604060208201526000610ee560408301846133da565b6000825161356d8184602087016133b6565b9190910192915050565b60006020828403121561358957600080fd5b5051919050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036135c1576135c16131d2565b5060010190565b6000816135d7576135d76131d2565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b8082028115828204841417610c8757610c876131d2565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000610ee560408301846133da565b60208152600061325e60208301846133da56fe4c69624469616d6f6e644375743a2041646420666163657420686173206e6f20636f64654c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a205265706c61636520666163657420686173206e6f20636f6465a2646970667358221220c5a8c10b22f20cde3fe0431ff57305237423677a60888f5b349fc6751336ae1464736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "Responsible for adding/removing/replace facets in Barz", + "kind": "dev", + "methods": { + "_checkDuplicateOnChainApprover(bytes32,address[])": { + "params": { + "_approvers": "List of approver addresses", + "_diamondCutHash": "Hash of diamondCut information including the facet addresses and function selectors" + } + }, + "approveDiamondCut((address,uint8,bytes4[])[])": { + "params": { + "_diamondCut": "Contains the facet addresses and function selectors" + } + }, + "constructor": { + "params": { + "_securityManager": "Security Manager contract that holds the security related variables for all wallets" + } + }, + "diamondCut((address,uint8,bytes4[])[],address,bytes)": { + "params": { + "_diamondCut": "Contains the facet addresses and function selectors", + "_init": "The address of the contract or facet to execute _calldata. It's prohibited in Barz" + } + }, + "diamondCutWithGuardian((address,uint8,bytes4[])[],address[],bytes[])": { + "params": { + "_approvers": "Guardian or owner address that approves the diamond cut", + "_diamondCut": "Contains the facet addresses and function selectors", + "_signatures": "Signature of Guardians or owner that approves the diamond cut" + } + }, + "getDiamondCutApprovalCountWithTimeValidity(bytes32)": { + "params": { + "_diamondCutHash": "Hash of diamondCut information including the facet addresses and function selectors" + } + }, + "getDiamondCutHash((address,uint8,bytes4[])[])": { + "params": { + "_diamondCut": "Contains the facet addresses and function selectors" + }, + "returns": { + "cutHash": "Diamond Cut Hash" + } + }, + "getDiamondCutNonce()": { + "details": "This method fetches the nonce from diamond cut storage", + "returns": { + "cutNonce": "Nonce of diamond cut to protect from reply attacks" + } + }, + "getOwnerCutApprovalWithTimeValidity(bytes32)": { + "params": { + "_diamondCutHash": "Hash of diamondCut information including the facet addresses and function selectors" + }, + "returns": { + "isApprovedByOwner": "Bool value showing if the owner approved the cut" + } + }, + "isCutApproved(bytes32,address)": { + "params": { + "_approver": "Address of approver", + "_diamondCutHash": "Hash of diamondCut information including the facet addresses and function selectors" + }, + "returns": { + "isApproved": "Bool value showing if the approver approved the cut" + } + }, + "revokeDiamondCutApproval((address,uint8,bytes4[])[])": { + "params": { + "_diamondCut": "Contains the facet addresses and function selectors" + } + }, + "updateSupportsInterface(bytes4,bool)": { + "params": { + "_flag": "Bool value to update the mapping of the given interface ID", + "_interfaceId": "InterfaceID to update the mapping" + } + } + }, + "title": "DiamondCut Facet", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "_checkDuplicateOnChainApprover(bytes32,address[])": { + "notice": "Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval Approvers who approved on-chain should not be included in the off-chain approval" + }, + "approveDiamondCut((address,uint8,bytes4[])[])": { + "notice": "Approves diamond cut. This can only be called directly from guardian or owner" + }, + "constructor": { + "notice": "This constructor sets the Security Manager address which is an immutable variable. Immutable variables do not impact the storage of diamond" + }, + "diamondCut((address,uint8,bytes4[])[],address,bytes)": { + "notice": "Add/replace/remove any number of functions and optionally execute a function with delegatecall when guardians don't exist" + }, + "diamondCutWithGuardian((address,uint8,bytes4[])[],address[],bytes[])": { + "notice": "Add/replace/remove any number of functions and optionally execute a function with delegatecall when guardians exist" + }, + "getDiamondCutApprovalCountWithTimeValidity(bytes32)": { + "notice": "Gets the number of approvals of diamond cut from guardians" + }, + "getDiamondCutHash((address,uint8,bytes4[])[])": { + "notice": "Returns the diamond cut hash. This function ensures that this hash is safe from replay attack by including salt, address, chainId, and nonce, etc." + }, + "getDiamondCutNonce()": { + "notice": "Returns the diamond cut nonce of this wallet" + }, + "getOwnerCutApprovalWithTimeValidity(bytes32)": { + "notice": "Returns if the owner has approved the diamond cut" + }, + "isCutApproved(bytes32,address)": { + "notice": "Returns if the given approver has approved the diamond cut" + }, + "revokeDiamondCutApproval((address,uint8,bytes4[])[])": { + "notice": "Revokes the approval of diamond cut. This can only be called directly from guardian or owner" + }, + "updateSupportsInterface(bytes4,bool)": { + "notice": "Updates the flag for the interfaceId" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 27866, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "s", + "offset": 0, + "slot": "0", + "type": "t_struct(AppStorage)27613_storage" + } + ], + "types": { + "t_bytes4": { + "encoding": "inplace", + "label": "bytes4", + "numberOfBytes": "4" + }, + "t_contract(IEntryPoint)12286": { + "encoding": "inplace", + "label": "contract IEntryPoint", + "numberOfBytes": "20" + }, + "t_contract(IFacetRegistry)26148": { + "encoding": "inplace", + "label": "contract IFacetRegistry", + "numberOfBytes": "20" + }, + "t_mapping(t_uint256,t_struct(InitializersStorage)27592_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => struct InitializersStorage)", + "numberOfBytes": "32", + "value": "t_struct(InitializersStorage)27592_storage" + }, + "t_mapping(t_uint256,t_struct(Lock)27585_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => struct Lock)", + "numberOfBytes": "32", + "value": "t_struct(Lock)27585_storage" + }, + "t_struct(AppStorage)27613_storage": { + "encoding": "inplace", + "label": "struct AppStorage", + "members": [ + { + "astId": 27597, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "initStorage", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_uint256,t_struct(InitializersStorage)27592_storage)" + }, + { + "astId": 27599, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "signerMigration", + "offset": 0, + "slot": "1", + "type": "t_uint8" + }, + { + "astId": 27601, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "validateOwnerSignatureSelector", + "offset": 1, + "slot": "1", + "type": "t_bytes4" + }, + { + "astId": 27604, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "entryPoint", + "offset": 5, + "slot": "1", + "type": "t_contract(IEntryPoint)12286" + }, + { + "astId": 27607, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "facetRegistry", + "offset": 0, + "slot": "2", + "type": "t_contract(IFacetRegistry)26148" + }, + { + "astId": 27612, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "locks", + "offset": 0, + "slot": "3", + "type": "t_mapping(t_uint256,t_struct(Lock)27585_storage)" + } + ], + "numberOfBytes": "128" + }, + "t_struct(InitializersStorage)27592_storage": { + "encoding": "inplace", + "label": "struct InitializersStorage", + "members": [ + { + "astId": 27587, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "signerInitialized", + "offset": 0, + "slot": "0", + "type": "t_uint8" + }, + { + "astId": 27589, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "accountInitialized", + "offset": 1, + "slot": "0", + "type": "t_uint8" + }, + { + "astId": 27591, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "restrictionsInitialized", + "offset": 2, + "slot": "0", + "type": "t_uint8" + } + ], + "numberOfBytes": "32" + }, + "t_struct(Lock)27585_storage": { + "encoding": "inplace", + "label": "struct Lock", + "members": [ + { + "astId": 27582, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "release", + "offset": 0, + "slot": "0", + "type": "t_uint64" + }, + { + "astId": 27584, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "locker", + "offset": 8, + "slot": "0", + "type": "t_bytes4" + } + ], + "numberOfBytes": "32" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint64": { + "encoding": "inplace", + "label": "uint64", + "numberOfBytes": "8" + }, + "t_uint8": { + "encoding": "inplace", + "label": "uint8", + "numberOfBytes": "1" + } + } + } +} \ No newline at end of file diff --git a/deployments/mainnet/DiamondLoupeFacet.json b/deployments/mainnet/DiamondLoupeFacet.json new file mode 100644 index 0000000..1ce0a10 --- /dev/null +++ b/deployments/mainnet/DiamondLoupeFacet.json @@ -0,0 +1,306 @@ +{ + "address": "0xCe36b85d12D81cd619C745c7717f3396E184Ac7C", + "abi": [ + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_functionSelector", + "type": "bytes4" + } + ], + "name": "facetAddress", + "outputs": [ + { + "internalType": "address", + "name": "facetAddress_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_functionSelector", + "type": "bytes4" + } + ], + "name": "facetAddressFromStorage", + "outputs": [ + { + "internalType": "address", + "name": "facetAddress_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetAddresses", + "outputs": [ + { + "internalType": "address[]", + "name": "facetAddresses_", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetAddressesFromStorage", + "outputs": [ + { + "internalType": "address[]", + "name": "facetAddresses_", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_facet", + "type": "address" + } + ], + "name": "facetFunctionSelectors", + "outputs": [ + { + "internalType": "bytes4[]", + "name": "facetFunctionSelectors_", + "type": "bytes4[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_facet", + "type": "address" + } + ], + "name": "facetFunctionSelectorsFromStorage", + "outputs": [ + { + "internalType": "bytes4[]", + "name": "facetFunctionSelectors_", + "type": "bytes4[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facets", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondLoupe.Facet[]", + "name": "facets_", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetsFromStorage", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondLoupe.Facet[]", + "name": "facets_", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "isSupported", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0x9fbf6ad7f6c809bed45db0df116f0d4eafee934317d287e31ddcb25625178db7", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 77, + "gasUsed": "2036953", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x67397af89540c777bd60fdc07c23fb58f36f345427700bd02f856a2f06f42506", + "transactionHash": "0x9fbf6ad7f6c809bed45db0df116f0d4eafee934317d287e31ddcb25625178db7", + "logs": [], + "blockNumber": 19517134, + "cumulativeGasUsed": "9048432", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "ad34345aa73d96f52b3e14df983b6b29", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_functionSelector\",\"type\":\"bytes4\"}],\"name\":\"facetAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"facetAddress_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_functionSelector\",\"type\":\"bytes4\"}],\"name\":\"facetAddressFromStorage\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"facetAddress_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetAddresses\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"facetAddresses_\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetAddressesFromStorage\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"facetAddresses_\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_facet\",\"type\":\"address\"}],\"name\":\"facetFunctionSelectors\",\"outputs\":[{\"internalType\":\"bytes4[]\",\"name\":\"facetFunctionSelectors_\",\"type\":\"bytes4[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_facet\",\"type\":\"address\"}],\"name\":\"facetFunctionSelectorsFromStorage\",\"outputs\":[{\"internalType\":\"bytes4[]\",\"name\":\"facetFunctionSelectors_\",\"type\":\"bytes4[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facets\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondLoupe.Facet[]\",\"name\":\"facets_\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetsFromStorage\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondLoupe.Facet[]\",\"name\":\"facets_\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isSupported\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"DiamondLoupe contract compatible with EIP-2535\",\"kind\":\"dev\",\"methods\":{\"facetAddress(bytes4)\":{\"details\":\"If facet is not found return address(0).\",\"params\":{\"_functionSelector\":\"The function selector.\"},\"returns\":{\"facetAddress_\":\"The facet address.\"}},\"facetAddressFromStorage(bytes4)\":{\"params\":{\"_functionSelector\":\"Function selector to fetch the facet address from diamond storage\"},\"returns\":{\"facetAddress_\":\"Facet address mapped with the function selector\"}},\"facetAddresses()\":{\"returns\":{\"facetAddresses_\":\"facetAddresses_\"}},\"facetAddressesFromStorage()\":{\"returns\":{\"facetAddresses_\":\"All facet addresses attached directly to diamond storage\"}},\"facetFunctionSelectors(address)\":{\"params\":{\"_facet\":\"The facet address.\"},\"returns\":{\"facetFunctionSelectors_\":\"facetFunctionSelectors_\"}},\"facetFunctionSelectorsFromStorage(address)\":{\"params\":{\"_facet\":\"Facet address to fetch the facet function selectors from diamond storage\"},\"returns\":{\"facetFunctionSelectors_\":\"Facet function selectors of the given facet address\"}},\"facets()\":{\"details\":\"Barz uses a special architecture called default fallback handler. Default Fallback handler is used as a middleware that holds the mapping of facet function selector and facet address that Barz uses. This helps Barz to reduce significant amount of gas during the initialization process. Hence, this method aggregates both the facet information from DefaulFallbackHandler and in diamond storage and shows the data to users.\",\"returns\":{\"facets_\":\"Facet\"}},\"facetsFromStorage()\":{\"returns\":{\"facets_\":\"Facet information attached directly to diamond storage\"}},\"supportsInterface(bytes4)\":{\"params\":{\"_interfaceId\":\"Interface ID for detecting the interface\"},\"returns\":{\"isSupported\":\"Bool value showing if the standard is supported in the contract\"}}},\"title\":\"DiamondLoupe Facet\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"facetAddress(bytes4)\":{\"notice\":\"Gets the facet that supports the given selector.\"},\"facetAddressFromStorage(bytes4)\":{\"notice\":\"Returns the facet address attached to the given function selector. This excludes the facets from the default fallback handler\"},\"facetAddresses()\":{\"notice\":\"Get all the facet addresses used by Barz.\"},\"facetAddressesFromStorage()\":{\"notice\":\"Returns all facet addresses attached directly to diamond storage. This excludes the facets from the default fallback handler\"},\"facetFunctionSelectors(address)\":{\"notice\":\"Gets all the function selectors provided by a facet.\"},\"facetFunctionSelectorsFromStorage(address)\":{\"notice\":\"Returns function selectors of given facet address attached directly to diamond storage. This excludes the facets from the default fallback handler\"},\"facets()\":{\"notice\":\"Gets all facets and their selectors.\"},\"facetsFromStorage()\":{\"notice\":\"Returns the facet from the diamond storage. This excludes the facets from the default fallback handler\"},\"supportsInterface(bytes4)\":{\"notice\":\"SupportInterface to be compatible with EIP 165\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/base/DiamondLoupeFacet.sol\":\"DiamondLoupeFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/introspection/IERC165.sol\\\";\\n\\n/**\\n * @dev _Available since v3.1._\\n */\\ninterface IERC1155Receiver is IERC165 {\\n /**\\n * @dev Handles the receipt of a single ERC1155 token type. This function is\\n * called at the end of a `safeTransferFrom` after the balance has been updated.\\n *\\n * NOTE: To accept the transfer, this must return\\n * `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))`\\n * (i.e. 0xf23a6e61, or its own function selector).\\n *\\n * @param operator The address which initiated the transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param id The ID of the token being transferred\\n * @param value The amount of tokens being transferred\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155Received(\\n address operator,\\n address from,\\n uint256 id,\\n uint256 value,\\n bytes calldata data\\n ) external returns (bytes4);\\n\\n /**\\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\\n * is called at the end of a `safeBatchTransferFrom` after the balances have\\n * been updated.\\n *\\n * NOTE: To accept the transfer(s), this must return\\n * `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))`\\n * (i.e. 0xbc197c81, or its own function selector).\\n *\\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155BatchReceived(\\n address operator,\\n address from,\\n uint256[] calldata ids,\\n uint256[] calldata values,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xeb373f1fdc7b755c6a750123a9b9e3a8a02c1470042fd6505d875000a80bde0b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title ERC721 token receiver interface\\n * @dev Interface for any contract that wants to support safeTransfers\\n * from ERC721 asset contracts.\\n */\\ninterface IERC721Receiver {\\n /**\\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\\n * by `operator` from `from`, this function is called.\\n *\\n * It must return its Solidity selector to confirm the token transfer.\\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\\n *\\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\\n */\\n function onERC721Received(\\n address operator,\\n address from,\\n uint256 tokenId,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\\n *\\n * Accounts can be notified of {IERC777} tokens being sent to them by having a\\n * contract implement this interface (contract holders can be their own\\n * implementer) and registering it on the\\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\\n *\\n * See {IERC1820Registry} and {ERC1820Implementer}.\\n */\\ninterface IERC777Recipient {\\n /**\\n * @dev Called by an {IERC777} token contract whenever tokens are being\\n * moved or created into a registered account (`to`). The type of operation\\n * is conveyed by `from` being the zero address or not.\\n *\\n * This call occurs _after_ the token contract's state is updated, so\\n * {IERC777-balanceOf}, etc., can be used to query the post-operation state.\\n *\\n * This function may revert to prevent the operation from being executed.\\n */\\n function tokensReceived(\\n address operator,\\n address from,\\n address to,\\n uint256 amount,\\n bytes calldata userData,\\n bytes calldata operatorData\\n ) external;\\n}\\n\",\"keccak256\":\"0x1a5d61db2733202ba361e6d6741cd2e662380e22b80e987eacfc91973f2267dc\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"contracts/facets/base/DiamondLoupeFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IERC777Recipient} from \\\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\\\";\\nimport {IERC165} from \\\"../../interfaces/ERC/IERC165.sol\\\";\\nimport {IERC1271} from \\\"../../interfaces/ERC/IERC1271.sol\\\";\\nimport {IERC677Receiver} from \\\"../../interfaces/ERC/IERC677Receiver.sol\\\";\\nimport {IERC721Receiver} from \\\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\\\";\\nimport {IERC1155Receiver} from \\\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\\\";\\nimport {LibDiamond} from \\\"../../libraries/LibDiamond.sol\\\";\\nimport {LibLoupe} from \\\"../../libraries/LibLoupe.sol\\\";\\nimport {LibUtils} from \\\"../../libraries/LibUtils.sol\\\";\\nimport {IDiamondCut} from \\\"../../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IStorageLoupe} from \\\"./interfaces/IStorageLoupe.sol\\\";\\nimport {IDiamondLoupe} from \\\"./interfaces/IDiamondLoupe.sol\\\";\\n\\n/**\\n * @title DiamondLoupe Facet\\n * @dev DiamondLoupe contract compatible with EIP-2535\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract DiamondLoupeFacet is IDiamondLoupe, IStorageLoupe, IERC165 {\\n // Diamond Loupe Functions\\n ////////////////////////////////////////////////////////////////////\\n /// These functions are expected to be called frequently by tools off-chain.\\n\\n /**\\n * @notice Gets all facets and their selectors.\\n * @dev Barz uses a special architecture called default fallback handler. Default Fallback handler is used as a middleware\\n * that holds the mapping of facet function selector and facet address that Barz uses. This helps Barz to reduce\\n * significant amount of gas during the initialization process.\\n * Hence, this method aggregates both the facet information from DefaulFallbackHandler and in diamond storage and shows the data to users.\\n * @return facets_ Facet\\n */\\n function facets() public view override returns (Facet[] memory facets_) {\\n Facet[] memory defaultFacet = LibDiamond\\n .diamondStorage()\\n .defaultFallbackHandler\\n .facets();\\n Facet[] memory _facets = LibLoupe.facets();\\n uint256 numFacets = _facets.length;\\n bytes4[] memory keys;\\n address[] memory values;\\n for (uint256 i; i < numFacets; ) {\\n uint256 selectorsLength = _facets[i].functionSelectors.length;\\n for (uint256 j; j < selectorsLength; ) {\\n (keys, values) = LibUtils.setValue(\\n keys,\\n values,\\n _facets[i].functionSelectors[j],\\n _facets[i].facetAddress\\n );\\n unchecked {\\n ++j;\\n }\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n {\\n bool iIncrement;\\n for (uint256 i; i < defaultFacet.length; ) {\\n bool jIncrement;\\n for (\\n uint256 j;\\n j < defaultFacet[i].functionSelectors.length;\\n\\n ) {\\n if (\\n LibUtils.getValue(\\n keys,\\n values,\\n defaultFacet[i].functionSelectors[j]\\n ) != address(0)\\n ) {\\n if (defaultFacet[i].functionSelectors.length == 1) {\\n defaultFacet = LibUtils.removeFacetElement(\\n defaultFacet,\\n i\\n );\\n iIncrement = true;\\n break;\\n }\\n defaultFacet[i].functionSelectors = LibUtils\\n .removeElement(\\n defaultFacet[i].functionSelectors,\\n j\\n );\\n jIncrement = true;\\n }\\n if (!jIncrement) {\\n unchecked {\\n ++j;\\n }\\n } else {\\n jIncrement = false;\\n }\\n }\\n if (!iIncrement) {\\n unchecked {\\n ++i;\\n }\\n } else {\\n iIncrement = false;\\n }\\n }\\n }\\n {\\n uint256 facetLength = numFacets + defaultFacet.length;\\n facets_ = new Facet[](facetLength);\\n uint256 defaultFacetIndex;\\n for (uint256 i; i < facetLength; ) {\\n if (i < numFacets) {\\n facets_[i] = _facets[i];\\n bool jIncrementor;\\n for (uint256 j; j < defaultFacet.length; ) {\\n if (\\n facets_[i].facetAddress ==\\n defaultFacet[j].facetAddress\\n ) {\\n facets_[i].functionSelectors = LibUtils.mergeArrays(\\n _facets[i].functionSelectors,\\n defaultFacet[j].functionSelectors\\n );\\n defaultFacet = LibUtils.removeFacetElement(\\n defaultFacet,\\n j\\n );\\n jIncrementor = true;\\n {\\n facets_ = LibUtils.removeFacetElement(\\n facets_,\\n facets_.length - 1\\n );\\n }\\n --facetLength;\\n }\\n if (!jIncrementor) {\\n unchecked {\\n ++j;\\n }\\n } else {\\n jIncrementor = false;\\n }\\n }\\n } else {\\n facets_[i] = defaultFacet[defaultFacetIndex];\\n ++defaultFacetIndex;\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n }\\n\\n /**\\n * @notice Gets all the function selectors provided by a facet.\\n * @param _facet The facet address.\\n * @return facetFunctionSelectors_\\n */\\n function facetFunctionSelectors(\\n address _facet\\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\\n Facet[] memory facet = facets();\\n uint256 facetLength = facet.length;\\n for (uint256 i; i < facetLength; ) {\\n if (facet[i].facetAddress == _facet)\\n return facet[i].functionSelectors;\\n unchecked {\\n ++i;\\n }\\n }\\n return facetFunctionSelectors_;\\n }\\n\\n /**\\n * @notice Get all the facet addresses used by Barz.\\n * @return facetAddresses_\\n */\\n function facetAddresses()\\n external\\n view\\n override\\n returns (address[] memory facetAddresses_)\\n {\\n Facet[] memory facet = facets();\\n uint256 facetLength = facet.length;\\n facetAddresses_ = new address[](facetLength);\\n for (uint256 i; i < facetLength; ) {\\n facetAddresses_[i] = facet[i].facetAddress;\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * @notice Gets the facet that supports the given selector.\\n * @dev If facet is not found return address(0).\\n * @param _functionSelector The function selector.\\n * @return facetAddress_ The facet address.\\n */\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view override returns (address facetAddress_) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n\\n facetAddress_ = address(bytes20(ds.facets[_functionSelector]));\\n if (facetAddress_ == address(0)) {\\n facetAddress_ = IDiamondLoupe(ds.defaultFallbackHandler)\\n .facetAddress(_functionSelector);\\n }\\n }\\n\\n /**\\n * @notice SupportInterface to be compatible with EIP 165\\n * @param _interfaceId Interface ID for detecting the interface\\n * @return isSupported Bool value showing if the standard is supported in the contract\\n */\\n function supportsInterface(\\n bytes4 _interfaceId\\n ) external view override returns (bool isSupported) {\\n isSupported =\\n _interfaceId == type(IERC165).interfaceId ||\\n _interfaceId == IDiamondCut.diamondCut.selector ||\\n _interfaceId == type(IDiamondLoupe).interfaceId ||\\n _interfaceId == type(IERC1155Receiver).interfaceId ||\\n _interfaceId == type(IERC721Receiver).interfaceId ||\\n _interfaceId == type(IERC777Recipient).interfaceId ||\\n _interfaceId == IERC1271.isValidSignature.selector ||\\n _interfaceId == type(IERC677Receiver).interfaceId ||\\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId];\\n }\\n\\n /**\\n * @notice Returns the facet from the diamond storage. This excludes the facets from the default fallback handler\\n * @return facets_ Facet information attached directly to diamond storage\\n */\\n function facetsFromStorage()\\n external\\n view\\n override\\n returns (Facet[] memory facets_)\\n {\\n facets_ = LibLoupe.facets();\\n }\\n\\n /**\\n * @notice Returns the facet address attached to the given function selector. This excludes the facets from the default fallback handler\\n * @param _functionSelector Function selector to fetch the facet address from diamond storage\\n * @return facetAddress_ Facet address mapped with the function selector\\n */\\n function facetAddressFromStorage(\\n bytes4 _functionSelector\\n ) external view override returns (address facetAddress_) {\\n facetAddress_ = LibLoupe.facetAddress(_functionSelector);\\n }\\n\\n /**\\n * @notice Returns all facet addresses attached directly to diamond storage. This excludes the facets from the default fallback handler\\n * @return facetAddresses_ All facet addresses attached directly to diamond storage\\n */\\n function facetAddressesFromStorage()\\n external\\n view\\n override\\n returns (address[] memory facetAddresses_)\\n {\\n facetAddresses_ = LibLoupe.facetAddresses();\\n }\\n\\n /**\\n * @notice Returns function selectors of given facet address attached directly to diamond storage. This excludes the facets from the default fallback handler\\n * @param _facet Facet address to fetch the facet function selectors from diamond storage\\n * @return facetFunctionSelectors_ Facet function selectors of the given facet address\\n */\\n function facetFunctionSelectorsFromStorage(\\n address _facet\\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\\n facetFunctionSelectors_ = LibLoupe.facetFunctionSelectors(_facet);\\n }\\n}\\n\",\"keccak256\":\"0xf392fde159eec6483fc15fa323ecd6d764028f5b8734a66662c4116292363794\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IStorageLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"./IDiamondLoupe.sol\\\";\\n\\n/**\\n * @title LoupeFromStorage Interface\\n * @dev Interface contract to function as a loupe facet directly attached to diamond storage of Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IStorageLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facetsFromStorage()\\n external\\n view\\n returns (IDiamondLoupe.Facet[] memory);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n function facetFunctionSelectorsFromStorage(\\n address _facet\\n ) external view returns (bytes4[] memory);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n function facetAddressesFromStorage()\\n external\\n view\\n returns (address[] memory);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n function facetAddressFromStorage(\\n bytes4 _functionSelector\\n ) external view returns (address);\\n}\\n\",\"keccak256\":\"0xdf5dc9c57319e9087628c9cf9404b4f75585b76d1c2f4f59ee796c933967ea5c\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC1271 {\\n function isValidSignature(\\n bytes32 hash,\\n bytes memory signature\\n ) external view returns (bytes4);\\n}\\n\",\"keccak256\":\"0xcdddb7d5641c9d3f2432dec7fd13fddb9ae1480f25c76c21511e2fa16b8bd422\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.21;\\n\\ninterface IERC165 {\\n /// @notice Query if a contract implements an interface\\n /// @param interfaceId The interface identifier, as specified in ERC-165\\n /// @dev Interface identification is specified in ERC-165. This function\\n /// uses less than 30,000 gas.\\n /// @return `true` if the contract implements `interfaceID` and\\n /// `interfaceID` is not 0xffffffff, `false` otherwise\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xbb7f07e170898793c5535cc4b7e8944c4b990a631ac806d0b788e794abc788a3\",\"license\":\"MIT\"},\"contracts/interfaces/ERC/IERC677Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC677Receiver {\\n function onTokenTransfer(\\n address sender,\\n uint value,\\n bytes calldata data\\n ) external pure returns (bool);\\n}\\n\",\"keccak256\":\"0x4c1631cf45ea6daac0ec158c3edb9453099130b6b64f697004b83f95aa1f7350\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\\n bytes4(keccak256(\\\"verifyRestrictions(address,address,uint256,bytes)\\\"));\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // Default Fallback Handler of the barz.\\n IDiamondLoupe defaultFallbackHandler;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function enforceIsSelf() internal view {\\n require(msg.sender == address(this), \\\"LibDiamond: Caller not self\\\");\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n\\n unchecked {\\n facetIndex++;\\n }\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n\\n function restrictionsFacet() internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(\\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2cabdc00de859c3a3170ce3bda5d0e5fd3933d47ce904fd1585f9818b02572f8\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\nimport {LibDiamond} from \\\"./LibDiamond.sol\\\";\\n\\n/**\\n * @title LibLoupe\\n * @dev Internal Library to provide utility feature for reading the state of diamond facets\\n * Originally from Diamond's implementation of Mudgen(author of EIP-2535)\\n */\\nlibrary LibLoupe {\\n /// @notice Gets all facets and their selectors.\\n /// @return facets_ Facet\\n function facets()\\n internal\\n view\\n returns (IDiamondLoupe.Facet[] memory facets_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facets_ = new IDiamondLoupe.Facet[](ds.selectorCount);\\n uint16[] memory numFacetSelectors = new uint16[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facets_[facetIndex].facetAddress == facetAddress_) {\\n facets_[facetIndex].functionSelectors[\\n numFacetSelectors[facetIndex]\\n ] = selector;\\n // probably will never have more than 256 functions from one facet contract\\n require(numFacetSelectors[facetIndex] < 255);\\n numFacetSelectors[facetIndex]++;\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facets_[numFacets].facetAddress = facetAddress_;\\n facets_[numFacets].functionSelectors = new bytes4[](\\n ds.selectorCount\\n );\\n facets_[numFacets].functionSelectors[0] = selector;\\n numFacetSelectors[numFacets] = 1;\\n numFacets++;\\n }\\n }\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n uint256 numSelectors = numFacetSelectors[facetIndex];\\n bytes4[] memory selectors = facets_[facetIndex].functionSelectors;\\n // setting the number of selectors\\n assembly {\\n mstore(selectors, numSelectors)\\n }\\n }\\n // setting the number of facets\\n assembly {\\n mstore(facets_, numFacets)\\n }\\n }\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return _facetFunctionSelectors The selectors associated with a facet address.\\n function facetFunctionSelectors(\\n address _facet\\n ) internal view returns (bytes4[] memory _facetFunctionSelectors) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n uint256 numSelectors;\\n _facetFunctionSelectors = new bytes4[](ds.selectorCount);\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facet = address(bytes20(ds.facets[selector]));\\n if (_facet == facet) {\\n _facetFunctionSelectors[numSelectors] = selector;\\n numSelectors++;\\n }\\n }\\n }\\n // Set the number of selectors in the array\\n assembly {\\n mstore(_facetFunctionSelectors, numSelectors)\\n }\\n }\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n internal\\n view\\n returns (address[] memory facetAddresses_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetAddresses_ = new address[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facetAddress_ == facetAddresses_[facetIndex]) {\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facetAddresses_[numFacets] = facetAddress_;\\n numFacets++;\\n }\\n }\\n // Set the number of facet addresses in the array\\n assembly {\\n mstore(facetAddresses_, numFacets)\\n }\\n }\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(LibDiamond.diamondStorage().facets[_functionSelector])\\n );\\n }\\n}\\n\",\"keccak256\":\"0x0b11439c3cc657095e15ec2241fdcf67204b14001357b612fc5db4ff9e760a5a\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibUtils.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nlibrary LibUtils {\\n // Internal utility functions\\n function mergeArrays(\\n bytes4[] memory _array1,\\n bytes4[] memory _array2\\n ) internal pure returns (bytes4[] memory) {\\n uint256 length1 = _array1.length;\\n uint256 length2 = _array2.length;\\n bytes4[] memory mergedArray = new bytes4[](length1 + length2);\\n\\n for (uint256 i; i < length1; ) {\\n mergedArray[i] = _array1[i];\\n unchecked {\\n ++i;\\n }\\n }\\n\\n for (uint256 i; i < length2; ) {\\n mergedArray[length1 + i] = _array2[i];\\n unchecked {\\n ++i;\\n }\\n }\\n\\n return mergedArray;\\n }\\n\\n function removeFacetElement(\\n IDiamondLoupe.Facet[] memory _facets,\\n uint256 _index\\n ) internal pure returns (IDiamondLoupe.Facet[] memory) {\\n require(_index < _facets.length, \\\"Invalid index\\\");\\n require(_facets.length != 0, \\\"Invalid array\\\");\\n\\n // Create a new array with a length of `_facets.length - 1`\\n IDiamondLoupe.Facet[] memory newArray = new IDiamondLoupe.Facet[](\\n _facets.length - 1\\n );\\n uint256 newArrayLength = newArray.length;\\n // Iterate over the original array, skipping the element at the specified `index`\\n for (uint256 i; i < newArrayLength; ) {\\n if (i < _index) {\\n newArray[i] = _facets[i];\\n } else {\\n newArray[i] = _facets[i + 1];\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n\\n return newArray;\\n }\\n\\n function removeElement(\\n bytes4[] memory _array,\\n uint256 _index\\n ) internal pure returns (bytes4[] memory) {\\n require(_index < _array.length, \\\"Invalid index\\\");\\n require(_array.length != 0, \\\"Invalid array\\\");\\n\\n bytes4[] memory newArray = new bytes4[](_array.length - 1);\\n uint256 newArrayLength = newArray.length;\\n for (uint256 i; i < newArrayLength; ) {\\n if (i < _index) {\\n newArray[i] = _array[i];\\n } else {\\n newArray[i] = _array[i + 1];\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n\\n return newArray;\\n }\\n\\n function setValue(\\n bytes4[] memory _keys,\\n address[] memory _values,\\n bytes4 _key,\\n address _value\\n ) internal pure returns (bytes4[] memory, address[] memory) {\\n uint256 index = findIndex(_keys, _key);\\n uint256 keysLength = _keys.length;\\n if (index < keysLength) {\\n _values[index] = _value;\\n } else {\\n // Create new storage arrays\\n bytes4[] memory newKeys = new bytes4[](keysLength + 1);\\n address[] memory newValues = new address[](_values.length + 1);\\n\\n // Copy values to the new storage arrays\\n for (uint256 i; i < keysLength; ) {\\n newKeys[i] = _keys[i];\\n newValues[i] = _values[i];\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n // Add the new key-value pair\\n newKeys[keysLength] = _key;\\n newValues[_values.length] = _value;\\n\\n return (newKeys, newValues);\\n }\\n\\n // If the key already exists, return the original arrays\\n return (_keys, _values);\\n }\\n\\n function getValue(\\n bytes4[] memory _keys,\\n address[] memory _values,\\n bytes4 _key\\n ) internal pure returns (address) {\\n uint256 index = findIndex(_keys, _key);\\n if (index >= _keys.length) return address(0);\\n\\n return _values[index];\\n }\\n\\n function findIndex(\\n bytes4[] memory _keys,\\n bytes4 _key\\n ) internal pure returns (uint256) {\\n uint256 keysLength = _keys.length;\\n for (uint256 i; i < keysLength; ) {\\n if (_keys[i] == _key) {\\n return i;\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n return keysLength;\\n }\\n}\\n\",\"keccak256\":\"0xde8aeefe54c4be483f2b2c055aca11e2830f7094c0586a82e10ec544933b5714\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5061240b806100206000396000f3fe608060405234801561001057600080fd5b50600436106100a35760003560e01c8063adfca15e11610076578063d42139a91161005b578063d42139a914610169578063e3a2f6fe14610171578063f9796ccf1461018457600080fd5b8063adfca15e1461011e578063cdffacc61461013157600080fd5b806301a55022146100a857806301ffc9a7146100d157806352ef6b2c146100f45780637a0ed62714610109575b600080fd5b6100bb6100b6366004611e4b565b61018c565b6040516100c89190611e68565b60405180910390f35b6100e46100df366004611efc565b61019d565b60405190151581526020016100c8565b6100fc610454565b6040516100c89190611f19565b610111610518565b6040516100c89190611f67565b6100bb61012c366004611e4b565b610a63565b61014461013f366004611efc565b610b07565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100c8565b6100fc610c24565b61014461017f366004611efc565b610c33565b610111610c8c565b606061019782610c96565b92915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000148061023057507fffffffff0000000000000000000000000000000000000000000000000000000082167f1f931c1c00000000000000000000000000000000000000000000000000000000145b8061027c57507fffffffff0000000000000000000000000000000000000000000000000000000082167f48e2b09300000000000000000000000000000000000000000000000000000000145b806102c857507fffffffff0000000000000000000000000000000000000000000000000000000082167f4e2312e000000000000000000000000000000000000000000000000000000000145b8061031457507fffffffff0000000000000000000000000000000000000000000000000000000082167f150b7a0200000000000000000000000000000000000000000000000000000000145b8061035f57507fffffffff0000000000000000000000000000000000000000000000000000000082167e23de2900000000000000000000000000000000000000000000000000000000145b806103ab57507fffffffff0000000000000000000000000000000000000000000000000000000082167f1626ba7e00000000000000000000000000000000000000000000000000000000145b806103f757507fffffffff0000000000000000000000000000000000000000000000000000000082167fa4c0ed3600000000000000000000000000000000000000000000000000000000145b806101975750507fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4922602052604090205460ff1690565b60606000610460610518565b80519091508067ffffffffffffffff81111561047e5761047e61205d565b6040519080825280602002602001820160405280156104a7578160200160208202803683370190505b50925060005b81811015610512578281815181106104c7576104c761208c565b6020026020010151600001518482815181106104e5576104e561208c565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526001016104ad565b50505090565b606060007f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f600490810154604080517f7a0ed627000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff90921692637a0ed6279282820192600092908290030181865afa1580156105ac573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526105f29190810190612157565b905060006105fe610e57565b805190915060608060005b838110156106b55760008582815181106106255761062561208c565b60200260200101516020015151905060005b818110156106ab5761069e85858986815181106106565761065661208c565b60200260200101516020015184815181106106735761067361208c565b60200260200101518a878151811061068d5761068d61208c565b60200260200101516000015161134a565b9095509350600101610637565b5050600101610609565b506000805b865181101561081b576000805b8883815181106106d9576106d961208c565b602002602001015160200151518110156107ff57600073ffffffffffffffffffffffffffffffffffffffff1661074687878c878151811061071c5761071c61208c565b60200260200101516020015185815181106107395761073961208c565b60200260200101516115f1565b73ffffffffffffffffffffffffffffffffffffffff16146107e9578883815181106107735761077361208c565b6020026020010151602001515160010361079c576107918984611637565b9850600193506107ff565b6107c38984815181106107b1576107b161208c565b6020026020010151602001518261182a565b8984815181106107d5576107d561208c565b602002602001015160200181905250600191505b816107f6576001016106c7565b600091506106c7565b508261081057816001019150610815565b600092505b506106ba565b5050600085518461082c9190612304565b90508067ffffffffffffffff8111156108475761084761205d565b60405190808252806020026020018201604052801561088d57816020015b6040805180820190915260008152606060208201528152602001906001900390816108655790505b5096506000805b82811015610a585785811015610a0c578681815181106108b6576108b661208c565b60200260200101518982815181106108d0576108d061208c565b60200260200101819052506000805b8951811015610a05578981815181106108fa576108fa61208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff168b848151811061092e5761092e61208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff16036109ef5761099989848151811061096a5761096a61208c565b6020026020010151602001518b83815181106109885761098861208c565b602002602001015160200151611a3d565b8b84815181106109ab576109ab61208c565b6020026020010151602001819052506109c48a82611637565b9950600191506109e18b60018d516109dc9190612317565b611637565b9a506109ec8561232a565b94505b816109fc576001016108df565b600091506108df565b5050610a50565b878281518110610a1e57610a1e61208c565b6020026020010151898281518110610a3857610a3861208c565b602002602001018190525081610a4d9061235f565b91505b600101610894565b505050505050505090565b60606000610a6f610518565b805190915060005b81811015610aff578473ffffffffffffffffffffffffffffffffffffffff16838281518110610aa857610aa861208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1603610af757828181518110610ae157610ae161208c565b6020026020010151602001519350505050919050565b600101610a77565b505050919050565b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602081905260409091205460601c9081610c1e576004818101546040517fcdffacc60000000000000000000000000000000000000000000000000000000081527fffffffff0000000000000000000000000000000000000000000000000000000086169281019290925273ffffffffffffffffffffffffffffffffffffffff169063cdffacc690602401602060405180830381865afa158015610bf7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c1b9190612397565b91505b50919050565b6060610c2e611b8b565b905090565b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604081205460601c610197565b6060610c2e610e57565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9060009061ffff1667ffffffffffffffff811115610cfc57610cfc61205d565b604051908082528060200260200182016040528015610d25578160200160208202803683370190505b5092506000805b600284015461ffff16821015610e4d576000818152600185016020526040812054905b6008811015610e385783610d628161235f565b600288015490955061ffff1685119050610e3857600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020889052604090205460601c73ffffffffffffffffffffffffffffffffffffffff8a16819003610e235781898881518110610de457610de461208c565b7fffffffff000000000000000000000000000000000000000000000000000000009092166020928302919091019091015286610e1f8161235f565b9750505b50508080610e309061235f565b915050610d4f565b50508080610e459061235f565b915050610d2c565b5050825250919050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff1667ffffffffffffffff811115610eba57610eba61205d565b604051908082528060200260200182016040528015610f0057816020015b604080518082019091526000815260606020820152815260200190600190039081610ed85790505b50600282015490925060009061ffff1667ffffffffffffffff811115610f2857610f2861205d565b604051908082528060200260200182016040528015610f51578160200160208202803683370190505b50905060008060005b600285015461ffff168210156112d7576000818152600186016020526040812054905b60088110156112c25783610f908161235f565b600289015490955061ffff16851190506112c257600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020899052604081205460601c90805b88811015611148578273ffffffffffffffffffffffffffffffffffffffff168c82815181106110155761101561208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff160361113657838c828151811061104f5761104f61208c565b6020026020010151602001518b838151811061106d5761106d61208c565b602002602001015161ffff16815181106110895761108961208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152505060ff8a82815181106110e9576110e961208c565b602002602001015161ffff16106110ff57600080fd5b8981815181106111115761111161208c565b602002602001018051809190611126906123b4565b61ffff1690525060019150611148565b806111408161235f565b915050610fe4565b508015611157575050506112b0565b818b898151811061116a5761116a61208c565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff909116905260028a015461ffff1667ffffffffffffffff8111156111b0576111b061205d565b6040519080825280602002602001820160405280156111d9578160200160208202803683370190505b508b89815181106111ec576111ec61208c565b602002602001015160200181905250828b898151811061120e5761120e61208c565b60200260200101516020015160008151811061122c5761122c61208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681525050600189898151811061128c5761128c61208c565b61ffff90921660209283029190910190910152876112a98161235f565b9850505050505b806112ba8161235f565b915050610f7d565b505080806112cf9061235f565b915050610f5a565b5060005b8281101561133f5760008482815181106112f7576112f761208c565b602002602001015161ffff16905060008783815181106113195761131961208c565b6020026020010151602001519050818152505080806113379061235f565b9150506112db565b508185525050505090565b60608060006113598786611da0565b8751909150808210156113b857848783815181106113795761137961208c565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250506115df565b60006113c5826001612304565b67ffffffffffffffff8111156113dd576113dd61205d565b604051908082528060200260200182016040528015611406578160200160208202803683370190505b5090506000885160016114199190612304565b67ffffffffffffffff8111156114315761143161205d565b60405190808252806020026020018201604052801561145a578160200160208202803683370190505b50905060005b83811015611539578a818151811061147a5761147a61208c565b60200260200101518382815181106114945761149461208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815250508981815181106114f2576114f261208c565b602002602001015182828151811061150c5761150c61208c565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101611460565b508782848151811061154d5761154d61208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152505086818a51815181106115ad576115ad61208c565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015290945092506115e8915050565b87879350935050505b94509492505050565b6000806115fe8584611da0565b905084518110611612576000915050611630565b8381815181106116245761162461208c565b60200260200101519150505b9392505050565b6060825182106116a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420696e6465780000000000000000000000000000000000000060448201526064015b60405180910390fd5b8251600003611713576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420617272617900000000000000000000000000000000000000604482015260640161169f565b6000600184516117239190612317565b67ffffffffffffffff81111561173b5761173b61205d565b60405190808252806020026020018201604052801561178157816020015b6040805180820190915260008152606060208201528152602001906001900390816117595790505b50805190915060005b8181101561182057848110156117d6578581815181106117ac576117ac61208c565b60200260200101518382815181106117c6576117c661208c565b6020026020010181905250611818565b856117e2826001612304565b815181106117f2576117f261208c565b602002602001015183828151811061180c5761180c61208c565b60200260200101819052505b60010161178a565b5090949350505050565b606082518210611896576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420696e64657800000000000000000000000000000000000000604482015260640161169f565b8251600003611901576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420617272617900000000000000000000000000000000000000604482015260640161169f565b6000600184516119119190612317565b67ffffffffffffffff8111156119295761192961205d565b604051908082528060200260200182016040528015611952578160200160208202803683370190505b50805190915060005b8181101561182057848110156119cd5785818151811061197d5761197d61208c565b60200260200101518382815181106119975761199761208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152611a35565b856119d9826001612304565b815181106119e9576119e961208c565b6020026020010151838281518110611a0357611a0361208c565b7fffffffff00000000000000000000000000000000000000000000000000000000909216602092830291909101909101525b60010161195b565b81518151606091906000611a518284612304565b67ffffffffffffffff811115611a6957611a6961205d565b604051908082528060200260200182016040528015611a92578160200160208202803683370190505b50905060005b83811015611b0557868181518110611ab257611ab261208c565b6020026020010151828281518110611acc57611acc61208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152600101611a98565b5060005b82811015611b8157858181518110611b2357611b2361208c565b6020026020010151828286611b389190612304565b81518110611b4857611b4861208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152600101611b09565b5095945050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff1667ffffffffffffffff811115611bee57611bee61205d565b604051908082528060200260200182016040528015611c17578160200160208202803683370190505b50915060008060005b600284015461ffff16821015611d98576000818152600185016020526040812054905b6008811015611d835783611c568161235f565b600288015490955061ffff1685119050611d8357600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020889052604081205460601c90805b88811015611d19578a8181518110611cc457611cc461208c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611d075760019150611d19565b80611d118161235f565b915050611caa565b508015611d2857505050611d71565b818a8981518110611d3b57611d3b61208c565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015287611d6a8161235f565b9850505050505b80611d7b8161235f565b915050611c43565b50508080611d909061235f565b915050611c20565b505082525090565b8151600090815b81811015611e1e57837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916858281518110611de157611de161208c565b60200260200101517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603611e165791506101979050565b600101611da7565b509392505050565b73ffffffffffffffffffffffffffffffffffffffff81168114611e4857600080fd5b50565b600060208284031215611e5d57600080fd5b813561163081611e26565b6020808252825182820181905260009190848201906040850190845b81811015611ec25783517fffffffff000000000000000000000000000000000000000000000000000000001683529284019291840191600101611e84565b50909695505050505050565b7fffffffff0000000000000000000000000000000000000000000000000000000081168114611e4857600080fd5b600060208284031215611f0e57600080fd5b813561163081611ece565b6020808252825182820181905260009190848201906040850190845b81811015611ec257835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101611f35565b60006020808301818452808551808352604092508286019150828160051b8701018488016000805b8481101561204e578984037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00186528251805173ffffffffffffffffffffffffffffffffffffffff168552880151888501889052805188860181905290890190839060608701905b808310156120395783517fffffffff00000000000000000000000000000000000000000000000000000000168252928b019260019290920191908b0190611ff7565b50978a01979550505091870191600101611f8f565b50919998505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6040805190810167ffffffffffffffff811182821017156120de576120de61205d565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561212b5761212b61205d565b604052919050565b600067ffffffffffffffff82111561214d5761214d61205d565b5060051b60200190565b6000602080838503121561216a57600080fd5b825167ffffffffffffffff8082111561218257600080fd5b818501915085601f83011261219657600080fd5b81516121a96121a482612133565b6120e4565b81815260059190911b830184019084810190888311156121c857600080fd5b8585015b838110156122c8578051858111156121e45760008081fd5b86016040818c037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00181131561221a5760008081fd5b6122226120bb565b8983015161222f81611e26565b815282820151888111156122435760008081fd5b8084019350508c603f8401126122595760008081fd5b898301516122696121a482612133565b81815260059190911b84018301908b8101908f8311156122895760008081fd5b948401945b828610156122b357855194506122a385611ece565b848252948c0194908c019061228e565b838d01525050855250509186019186016121cc565b5098975050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610197576101976122d5565b81810381811115610197576101976122d5565b600081612339576123396122d5565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612390576123906122d5565b5060010190565b6000602082840312156123a957600080fd5b815161163081611e26565b600061ffff8083168181036123cb576123cb6122d5565b600101939250505056fea26469706673582212205959d8d85aad6f29d5fc37d5a52c404c25392cec49195c3b761da0e863e99b0f64736f6c63430008150033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100a35760003560e01c8063adfca15e11610076578063d42139a91161005b578063d42139a914610169578063e3a2f6fe14610171578063f9796ccf1461018457600080fd5b8063adfca15e1461011e578063cdffacc61461013157600080fd5b806301a55022146100a857806301ffc9a7146100d157806352ef6b2c146100f45780637a0ed62714610109575b600080fd5b6100bb6100b6366004611e4b565b61018c565b6040516100c89190611e68565b60405180910390f35b6100e46100df366004611efc565b61019d565b60405190151581526020016100c8565b6100fc610454565b6040516100c89190611f19565b610111610518565b6040516100c89190611f67565b6100bb61012c366004611e4b565b610a63565b61014461013f366004611efc565b610b07565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100c8565b6100fc610c24565b61014461017f366004611efc565b610c33565b610111610c8c565b606061019782610c96565b92915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000148061023057507fffffffff0000000000000000000000000000000000000000000000000000000082167f1f931c1c00000000000000000000000000000000000000000000000000000000145b8061027c57507fffffffff0000000000000000000000000000000000000000000000000000000082167f48e2b09300000000000000000000000000000000000000000000000000000000145b806102c857507fffffffff0000000000000000000000000000000000000000000000000000000082167f4e2312e000000000000000000000000000000000000000000000000000000000145b8061031457507fffffffff0000000000000000000000000000000000000000000000000000000082167f150b7a0200000000000000000000000000000000000000000000000000000000145b8061035f57507fffffffff0000000000000000000000000000000000000000000000000000000082167e23de2900000000000000000000000000000000000000000000000000000000145b806103ab57507fffffffff0000000000000000000000000000000000000000000000000000000082167f1626ba7e00000000000000000000000000000000000000000000000000000000145b806103f757507fffffffff0000000000000000000000000000000000000000000000000000000082167fa4c0ed3600000000000000000000000000000000000000000000000000000000145b806101975750507fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4922602052604090205460ff1690565b60606000610460610518565b80519091508067ffffffffffffffff81111561047e5761047e61205d565b6040519080825280602002602001820160405280156104a7578160200160208202803683370190505b50925060005b81811015610512578281815181106104c7576104c761208c565b6020026020010151600001518482815181106104e5576104e561208c565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526001016104ad565b50505090565b606060007f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f600490810154604080517f7a0ed627000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff90921692637a0ed6279282820192600092908290030181865afa1580156105ac573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526105f29190810190612157565b905060006105fe610e57565b805190915060608060005b838110156106b55760008582815181106106255761062561208c565b60200260200101516020015151905060005b818110156106ab5761069e85858986815181106106565761065661208c565b60200260200101516020015184815181106106735761067361208c565b60200260200101518a878151811061068d5761068d61208c565b60200260200101516000015161134a565b9095509350600101610637565b5050600101610609565b506000805b865181101561081b576000805b8883815181106106d9576106d961208c565b602002602001015160200151518110156107ff57600073ffffffffffffffffffffffffffffffffffffffff1661074687878c878151811061071c5761071c61208c565b60200260200101516020015185815181106107395761073961208c565b60200260200101516115f1565b73ffffffffffffffffffffffffffffffffffffffff16146107e9578883815181106107735761077361208c565b6020026020010151602001515160010361079c576107918984611637565b9850600193506107ff565b6107c38984815181106107b1576107b161208c565b6020026020010151602001518261182a565b8984815181106107d5576107d561208c565b602002602001015160200181905250600191505b816107f6576001016106c7565b600091506106c7565b508261081057816001019150610815565b600092505b506106ba565b5050600085518461082c9190612304565b90508067ffffffffffffffff8111156108475761084761205d565b60405190808252806020026020018201604052801561088d57816020015b6040805180820190915260008152606060208201528152602001906001900390816108655790505b5096506000805b82811015610a585785811015610a0c578681815181106108b6576108b661208c565b60200260200101518982815181106108d0576108d061208c565b60200260200101819052506000805b8951811015610a05578981815181106108fa576108fa61208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff168b848151811061092e5761092e61208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff16036109ef5761099989848151811061096a5761096a61208c565b6020026020010151602001518b83815181106109885761098861208c565b602002602001015160200151611a3d565b8b84815181106109ab576109ab61208c565b6020026020010151602001819052506109c48a82611637565b9950600191506109e18b60018d516109dc9190612317565b611637565b9a506109ec8561232a565b94505b816109fc576001016108df565b600091506108df565b5050610a50565b878281518110610a1e57610a1e61208c565b6020026020010151898281518110610a3857610a3861208c565b602002602001018190525081610a4d9061235f565b91505b600101610894565b505050505050505090565b60606000610a6f610518565b805190915060005b81811015610aff578473ffffffffffffffffffffffffffffffffffffffff16838281518110610aa857610aa861208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1603610af757828181518110610ae157610ae161208c565b6020026020010151602001519350505050919050565b600101610a77565b505050919050565b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602081905260409091205460601c9081610c1e576004818101546040517fcdffacc60000000000000000000000000000000000000000000000000000000081527fffffffff0000000000000000000000000000000000000000000000000000000086169281019290925273ffffffffffffffffffffffffffffffffffffffff169063cdffacc690602401602060405180830381865afa158015610bf7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c1b9190612397565b91505b50919050565b6060610c2e611b8b565b905090565b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604081205460601c610197565b6060610c2e610e57565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9060009061ffff1667ffffffffffffffff811115610cfc57610cfc61205d565b604051908082528060200260200182016040528015610d25578160200160208202803683370190505b5092506000805b600284015461ffff16821015610e4d576000818152600185016020526040812054905b6008811015610e385783610d628161235f565b600288015490955061ffff1685119050610e3857600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020889052604090205460601c73ffffffffffffffffffffffffffffffffffffffff8a16819003610e235781898881518110610de457610de461208c565b7fffffffff000000000000000000000000000000000000000000000000000000009092166020928302919091019091015286610e1f8161235f565b9750505b50508080610e309061235f565b915050610d4f565b50508080610e459061235f565b915050610d2c565b5050825250919050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff1667ffffffffffffffff811115610eba57610eba61205d565b604051908082528060200260200182016040528015610f0057816020015b604080518082019091526000815260606020820152815260200190600190039081610ed85790505b50600282015490925060009061ffff1667ffffffffffffffff811115610f2857610f2861205d565b604051908082528060200260200182016040528015610f51578160200160208202803683370190505b50905060008060005b600285015461ffff168210156112d7576000818152600186016020526040812054905b60088110156112c25783610f908161235f565b600289015490955061ffff16851190506112c257600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020899052604081205460601c90805b88811015611148578273ffffffffffffffffffffffffffffffffffffffff168c82815181106110155761101561208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff160361113657838c828151811061104f5761104f61208c565b6020026020010151602001518b838151811061106d5761106d61208c565b602002602001015161ffff16815181106110895761108961208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152505060ff8a82815181106110e9576110e961208c565b602002602001015161ffff16106110ff57600080fd5b8981815181106111115761111161208c565b602002602001018051809190611126906123b4565b61ffff1690525060019150611148565b806111408161235f565b915050610fe4565b508015611157575050506112b0565b818b898151811061116a5761116a61208c565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff909116905260028a015461ffff1667ffffffffffffffff8111156111b0576111b061205d565b6040519080825280602002602001820160405280156111d9578160200160208202803683370190505b508b89815181106111ec576111ec61208c565b602002602001015160200181905250828b898151811061120e5761120e61208c565b60200260200101516020015160008151811061122c5761122c61208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681525050600189898151811061128c5761128c61208c565b61ffff90921660209283029190910190910152876112a98161235f565b9850505050505b806112ba8161235f565b915050610f7d565b505080806112cf9061235f565b915050610f5a565b5060005b8281101561133f5760008482815181106112f7576112f761208c565b602002602001015161ffff16905060008783815181106113195761131961208c565b6020026020010151602001519050818152505080806113379061235f565b9150506112db565b508185525050505090565b60608060006113598786611da0565b8751909150808210156113b857848783815181106113795761137961208c565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250506115df565b60006113c5826001612304565b67ffffffffffffffff8111156113dd576113dd61205d565b604051908082528060200260200182016040528015611406578160200160208202803683370190505b5090506000885160016114199190612304565b67ffffffffffffffff8111156114315761143161205d565b60405190808252806020026020018201604052801561145a578160200160208202803683370190505b50905060005b83811015611539578a818151811061147a5761147a61208c565b60200260200101518382815181106114945761149461208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815250508981815181106114f2576114f261208c565b602002602001015182828151811061150c5761150c61208c565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101611460565b508782848151811061154d5761154d61208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152505086818a51815181106115ad576115ad61208c565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015290945092506115e8915050565b87879350935050505b94509492505050565b6000806115fe8584611da0565b905084518110611612576000915050611630565b8381815181106116245761162461208c565b60200260200101519150505b9392505050565b6060825182106116a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420696e6465780000000000000000000000000000000000000060448201526064015b60405180910390fd5b8251600003611713576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420617272617900000000000000000000000000000000000000604482015260640161169f565b6000600184516117239190612317565b67ffffffffffffffff81111561173b5761173b61205d565b60405190808252806020026020018201604052801561178157816020015b6040805180820190915260008152606060208201528152602001906001900390816117595790505b50805190915060005b8181101561182057848110156117d6578581815181106117ac576117ac61208c565b60200260200101518382815181106117c6576117c661208c565b6020026020010181905250611818565b856117e2826001612304565b815181106117f2576117f261208c565b602002602001015183828151811061180c5761180c61208c565b60200260200101819052505b60010161178a565b5090949350505050565b606082518210611896576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420696e64657800000000000000000000000000000000000000604482015260640161169f565b8251600003611901576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420617272617900000000000000000000000000000000000000604482015260640161169f565b6000600184516119119190612317565b67ffffffffffffffff8111156119295761192961205d565b604051908082528060200260200182016040528015611952578160200160208202803683370190505b50805190915060005b8181101561182057848110156119cd5785818151811061197d5761197d61208c565b60200260200101518382815181106119975761199761208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152611a35565b856119d9826001612304565b815181106119e9576119e961208c565b6020026020010151838281518110611a0357611a0361208c565b7fffffffff00000000000000000000000000000000000000000000000000000000909216602092830291909101909101525b60010161195b565b81518151606091906000611a518284612304565b67ffffffffffffffff811115611a6957611a6961205d565b604051908082528060200260200182016040528015611a92578160200160208202803683370190505b50905060005b83811015611b0557868181518110611ab257611ab261208c565b6020026020010151828281518110611acc57611acc61208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152600101611a98565b5060005b82811015611b8157858181518110611b2357611b2361208c565b6020026020010151828286611b389190612304565b81518110611b4857611b4861208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152600101611b09565b5095945050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff1667ffffffffffffffff811115611bee57611bee61205d565b604051908082528060200260200182016040528015611c17578160200160208202803683370190505b50915060008060005b600284015461ffff16821015611d98576000818152600185016020526040812054905b6008811015611d835783611c568161235f565b600288015490955061ffff1685119050611d8357600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020889052604081205460601c90805b88811015611d19578a8181518110611cc457611cc461208c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611d075760019150611d19565b80611d118161235f565b915050611caa565b508015611d2857505050611d71565b818a8981518110611d3b57611d3b61208c565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015287611d6a8161235f565b9850505050505b80611d7b8161235f565b915050611c43565b50508080611d909061235f565b915050611c20565b505082525090565b8151600090815b81811015611e1e57837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916858281518110611de157611de161208c565b60200260200101517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603611e165791506101979050565b600101611da7565b509392505050565b73ffffffffffffffffffffffffffffffffffffffff81168114611e4857600080fd5b50565b600060208284031215611e5d57600080fd5b813561163081611e26565b6020808252825182820181905260009190848201906040850190845b81811015611ec25783517fffffffff000000000000000000000000000000000000000000000000000000001683529284019291840191600101611e84565b50909695505050505050565b7fffffffff0000000000000000000000000000000000000000000000000000000081168114611e4857600080fd5b600060208284031215611f0e57600080fd5b813561163081611ece565b6020808252825182820181905260009190848201906040850190845b81811015611ec257835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101611f35565b60006020808301818452808551808352604092508286019150828160051b8701018488016000805b8481101561204e578984037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00186528251805173ffffffffffffffffffffffffffffffffffffffff168552880151888501889052805188860181905290890190839060608701905b808310156120395783517fffffffff00000000000000000000000000000000000000000000000000000000168252928b019260019290920191908b0190611ff7565b50978a01979550505091870191600101611f8f565b50919998505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6040805190810167ffffffffffffffff811182821017156120de576120de61205d565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561212b5761212b61205d565b604052919050565b600067ffffffffffffffff82111561214d5761214d61205d565b5060051b60200190565b6000602080838503121561216a57600080fd5b825167ffffffffffffffff8082111561218257600080fd5b818501915085601f83011261219657600080fd5b81516121a96121a482612133565b6120e4565b81815260059190911b830184019084810190888311156121c857600080fd5b8585015b838110156122c8578051858111156121e45760008081fd5b86016040818c037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00181131561221a5760008081fd5b6122226120bb565b8983015161222f81611e26565b815282820151888111156122435760008081fd5b8084019350508c603f8401126122595760008081fd5b898301516122696121a482612133565b81815260059190911b84018301908b8101908f8311156122895760008081fd5b948401945b828610156122b357855194506122a385611ece565b848252948c0194908c019061228e565b838d01525050855250509186019186016121cc565b5098975050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610197576101976122d5565b81810381811115610197576101976122d5565b600081612339576123396122d5565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612390576123906122d5565b5060010190565b6000602082840312156123a957600080fd5b815161163081611e26565b600061ffff8083168181036123cb576123cb6122d5565b600101939250505056fea26469706673582212205959d8d85aad6f29d5fc37d5a52c404c25392cec49195c3b761da0e863e99b0f64736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "DiamondLoupe contract compatible with EIP-2535", + "kind": "dev", + "methods": { + "facetAddress(bytes4)": { + "details": "If facet is not found return address(0).", + "params": { + "_functionSelector": "The function selector." + }, + "returns": { + "facetAddress_": "The facet address." + } + }, + "facetAddressFromStorage(bytes4)": { + "params": { + "_functionSelector": "Function selector to fetch the facet address from diamond storage" + }, + "returns": { + "facetAddress_": "Facet address mapped with the function selector" + } + }, + "facetAddresses()": { + "returns": { + "facetAddresses_": "facetAddresses_" + } + }, + "facetAddressesFromStorage()": { + "returns": { + "facetAddresses_": "All facet addresses attached directly to diamond storage" + } + }, + "facetFunctionSelectors(address)": { + "params": { + "_facet": "The facet address." + }, + "returns": { + "facetFunctionSelectors_": "facetFunctionSelectors_" + } + }, + "facetFunctionSelectorsFromStorage(address)": { + "params": { + "_facet": "Facet address to fetch the facet function selectors from diamond storage" + }, + "returns": { + "facetFunctionSelectors_": "Facet function selectors of the given facet address" + } + }, + "facets()": { + "details": "Barz uses a special architecture called default fallback handler. Default Fallback handler is used as a middleware that holds the mapping of facet function selector and facet address that Barz uses. This helps Barz to reduce significant amount of gas during the initialization process. Hence, this method aggregates both the facet information from DefaulFallbackHandler and in diamond storage and shows the data to users.", + "returns": { + "facets_": "Facet" + } + }, + "facetsFromStorage()": { + "returns": { + "facets_": "Facet information attached directly to diamond storage" + } + }, + "supportsInterface(bytes4)": { + "params": { + "_interfaceId": "Interface ID for detecting the interface" + }, + "returns": { + "isSupported": "Bool value showing if the standard is supported in the contract" + } + } + }, + "title": "DiamondLoupe Facet", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "facetAddress(bytes4)": { + "notice": "Gets the facet that supports the given selector." + }, + "facetAddressFromStorage(bytes4)": { + "notice": "Returns the facet address attached to the given function selector. This excludes the facets from the default fallback handler" + }, + "facetAddresses()": { + "notice": "Get all the facet addresses used by Barz." + }, + "facetAddressesFromStorage()": { + "notice": "Returns all facet addresses attached directly to diamond storage. This excludes the facets from the default fallback handler" + }, + "facetFunctionSelectors(address)": { + "notice": "Gets all the function selectors provided by a facet." + }, + "facetFunctionSelectorsFromStorage(address)": { + "notice": "Returns function selectors of given facet address attached directly to diamond storage. This excludes the facets from the default fallback handler" + }, + "facets()": { + "notice": "Gets all facets and their selectors." + }, + "facetsFromStorage()": { + "notice": "Returns the facet from the diamond storage. This excludes the facets from the default fallback handler" + }, + "supportsInterface(bytes4)": { + "notice": "SupportInterface to be compatible with EIP 165" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/mainnet/Secp256k1VerificationFacet.json b/deployments/mainnet/Secp256k1VerificationFacet.json new file mode 100644 index 0000000..0dc402c --- /dev/null +++ b/deployments/mainnet/Secp256k1VerificationFacet.json @@ -0,0 +1,483 @@ +{ + "address": "0x58Cb9Abe27fcd6f72354E98Cf5cc46BEAA2182DF", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "LibAppStorage__AccountMustBeUninitialized", + "type": "error" + }, + { + "inputs": [], + "name": "LibAppStorage__SignerAlreadyUninitialized", + "type": "error" + }, + { + "inputs": [], + "name": "LibAppStorage__SignerMustBeUninitialized", + "type": "error" + }, + { + "inputs": [], + "name": "Secp256k1VerificationFacet__InvalidSignerLength", + "type": "error" + }, + { + "inputs": [], + "name": "VerificationFacet__InitializationFailure", + "type": "error" + }, + { + "inputs": [], + "name": "VerificationFacet__InvalidFacetMapping", + "type": "error" + }, + { + "inputs": [], + "name": "VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet", + "type": "error" + }, + { + "inputs": [], + "name": "VerificationFacet__ValidateOwnerSignatureSelectorNotSet", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "SignerInitialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "SignerUninitialized", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_publicKey", + "type": "bytes" + } + ], + "name": "initializeSigner", + "outputs": [ + { + "internalType": "uint256", + "name": "initSuccess", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_publicKey", + "type": "bytes" + } + ], + "name": "isValidKeyType", + "outputs": [ + { + "internalType": "bool", + "name": "isValid", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_hash", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "_signature", + "type": "bytes" + } + ], + "name": "isValidSignature", + "outputs": [ + { + "internalType": "bytes4", + "name": "magicValue", + "type": "bytes4" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "bytes", + "name": "signer", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "self", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "uninitializeSigner", + "outputs": [ + { + "internalType": "uint256", + "name": "uninitSuccess", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "initCode", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "callGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "verificationGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "preVerificationGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxFeePerGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPriorityFeePerGas", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "paymasterAndData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "internalType": "struct UserOperation", + "name": "userOp", + "type": "tuple" + }, + { + "internalType": "bytes32", + "name": "userOpHash", + "type": "bytes32" + } + ], + "name": "validateOwnerSignature", + "outputs": [ + { + "internalType": "uint256", + "name": "validationData", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "validateOwnerSignatureSelector", + "outputs": [ + { + "internalType": "bytes4", + "name": "ownerSignatureValidatorSelector", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "initCode", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "callGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "verificationGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "preVerificationGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxFeePerGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPriorityFeePerGas", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "paymasterAndData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "internalType": "struct UserOperation", + "name": "userOp", + "type": "tuple" + }, + { + "internalType": "bytes32", + "name": "userOpHash", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "signer", + "type": "address" + } + ], + "name": "validateSignature", + "outputs": [ + { + "internalType": "uint256", + "name": "isValid", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + } + ], + "transactionHash": "0x182ae8c2035a3bdc1cf69c3a406a0816b3495651620f5c975a751f3906e6640f", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 172, + "gasUsed": "1042239", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x7d9cba98da8cdf6d4a64e1b3f40ed159de9918e33c73cec322bd7004576f5cd3", + "transactionHash": "0x182ae8c2035a3bdc1cf69c3a406a0816b3495651620f5c975a751f3906e6640f", + "logs": [], + "blockNumber": 19517151, + "cumulativeGasUsed": "10138694", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "ad34345aa73d96f52b3e14df983b6b29", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"LibAppStorage__AccountMustBeUninitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LibAppStorage__SignerAlreadyUninitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LibAppStorage__SignerMustBeUninitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Secp256k1VerificationFacet__InvalidSignerLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerificationFacet__InitializationFailure\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerificationFacet__InvalidFacetMapping\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerificationFacet__ValidateOwnerSignatureSelectorNotSet\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"SignerInitialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"SignerUninitialized\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_publicKey\",\"type\":\"bytes\"}],\"name\":\"initializeSigner\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"initSuccess\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_publicKey\",\"type\":\"bytes\"}],\"name\":\"isValidKeyType\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isValid\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_hash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"_signature\",\"type\":\"bytes\"}],\"name\":\"isValidSignature\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"magicValue\",\"type\":\"bytes4\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"signer\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"self\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"uninitializeSigner\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"uninitSuccess\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"userOp\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"}],\"name\":\"validateOwnerSignature\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"validationData\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"validateOwnerSignatureSelector\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"ownerSignatureValidatorSelector\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"userOp\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"}],\"name\":\"validateSignature\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"isValid\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)Ruslan Serebriakov (@rsrbk)\",\"details\":\"Default Ethereum's elliptic curve\",\"kind\":\"dev\",\"methods\":{\"initializeSigner(bytes)\":{\"details\":\"This method checks if the signer has already been initialized. If already initialized, it reverts. It checks if the public key is in the light format and initializes signer storage in k1 storage.\",\"params\":{\"_publicKey\":\"Bytes of owner public key\"},\"returns\":{\"initSuccess\":\"Uint value representing the success of init operation\"}},\"isValidKeyType(bytes)\":{\"details\":\"For this Secp256k1Verification Facet, the public key length should be 65 in an uncompressed public key format\",\"params\":{\"_publicKey\":\"Bytes of public key for format check\"},\"returns\":{\"isValid\":\"Boolean variable representing if the format of public key is valid\"}},\"isValidSignature(bytes32,bytes)\":{\"details\":\"This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\",\"params\":{\"_hash\":\"Hash value the owner signed\",\"_signature\":\"Signature that signed the above hash\"},\"returns\":{\"magicValue\":\"Bytes4 value representing the success/failure of validation\"}},\"owner()\":{\"returns\":{\"signer\":\"Bytes of owner address\"}},\"uninitializeSigner()\":{\"details\":\"This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\",\"returns\":{\"uninitSuccess\":\"Uint value representing the success of uninit operation\"}},\"validateOwnerSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32)\":{\"details\":\"This method validates if the user operation is signed by the owner. It internally calls validateSignature with signer public key.\",\"params\":{\"userOp\":\"UserOperation including all information for execution\",\"userOpHash\":\"Hash of UserOperation given from EntryPoint. This hash is used for signature validation\"},\"returns\":{\"validationData\":\"Uint value representing whether the validation is successful. 0 for success, 1 for failure\"}},\"validateOwnerSignatureSelector()\":{\"returns\":{\"ownerSignatureValidatorSelector\":\"Bytes4 selector of function signature to validate account owner's UserOperation signature\"}},\"validateSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,address)\":{\"details\":\"This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\",\"params\":{\"signer\":\"Address of signer who signed the contract, to be validated\",\"userOp\":\"UserOperation including all information for execution\",\"userOpHash\":\"Hash of UserOperation given from EntryPoint. This hash is used for signature validation\"},\"returns\":{\"isValid\":\"Uint value representing whether the validation is successful. 0 for success, 1 for failure\"}}},\"title\":\"Secp256k1 verification facet\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"This constructor ensures that this contract can only be used as singleton for Proxy contracts\"},\"initializeSigner(bytes)\":{\"notice\":\"Initializes the signer in K1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\"},\"isValidKeyType(bytes)\":{\"notice\":\"Validates if the format of public key is valid for this verification facet\"},\"isValidSignature(bytes32,bytes)\":{\"notice\":\"Validates if the signature is valid. Function to be compatible with EIP-1271\"},\"owner()\":{\"notice\":\"Returns the owner of the account\"},\"uninitializeSigner()\":{\"notice\":\"Uninitialize signer in K1 Facet Storage. This can only be called when the account is undergoing signature migration and has already been initialized.\"},\"validateOwnerSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32)\":{\"notice\":\"Validates if the user operation is signed by the owner.\"},\"validateOwnerSignatureSelector()\":{\"notice\":\"Returns the selector of function to validate the signature of UserOperation\"},\"validateSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,address)\":{\"notice\":\"Validates if the signature of UserOperation is signed by the given signer\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/verification/secp256k1/Secp256k1VerificationFacet.sol\":\"Secp256k1VerificationFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./math/Math.sol\\\";\\nimport \\\"./math/SignedMath.sol\\\";\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n uint256 length = Math.log10(value) + 1;\\n string memory buffer = new string(length);\\n uint256 ptr;\\n /// @solidity memory-safe-assembly\\n assembly {\\n ptr := add(buffer, add(32, length))\\n }\\n while (true) {\\n ptr--;\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\\n }\\n value /= 10;\\n if (value == 0) break;\\n }\\n return buffer;\\n }\\n }\\n\\n /**\\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\\n */\\n function toString(int256 value) internal pure returns (string memory) {\\n return string(abi.encodePacked(value < 0 ? \\\"-\\\" : \\\"\\\", toString(SignedMath.abs(value))));\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n return toHexString(value, Math.log256(value) + 1);\\n }\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n\\n /**\\n * @dev Returns true if the two strings are equal.\\n */\\n function equal(string memory a, string memory b) internal pure returns (bool) {\\n return keccak256(bytes(a)) == keccak256(bytes(b));\\n }\\n}\\n\",\"keccak256\":\"0x3088eb2868e8d13d89d16670b5f8612c4ab9ff8956272837d8e90106c59c14a0\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Strings.sol\\\";\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSA {\\n enum RecoverError {\\n NoError,\\n InvalidSignature,\\n InvalidSignatureLength,\\n InvalidSignatureS,\\n InvalidSignatureV // Deprecated in v4.8\\n }\\n\\n function _throwError(RecoverError error) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert(\\\"ECDSA: invalid signature\\\");\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert(\\\"ECDSA: invalid signature length\\\");\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert(\\\"ECDSA: invalid signature 's' value\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature` or error string. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n *\\n * Documentation for signature generation:\\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n return tryRecover(hash, v, r, s);\\n } else {\\n return (address(0), RecoverError.InvalidSignatureLength);\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature`. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, signature);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\\n uint8 v = uint8((uint256(vs) >> 255) + 27);\\n return tryRecover(hash, v, r, s);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n *\\n * _Available since v4.2._\\n */\\n function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\\n // the valid range for s in (301): 0 < s < secp256k1n \\u00f7 2 + 1, and for v in (302): v \\u2208 {27, 28}. Most\\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\\n //\\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\\n // these malleable signatures as well.\\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n return (address(0), RecoverError.InvalidSignatureS);\\n }\\n\\n // If the signature is valid (and not malleable), return the signer address\\n address signer = ecrecover(hash, v, r, s);\\n if (signer == address(0)) {\\n return (address(0), RecoverError.InvalidSignature);\\n }\\n\\n return (signer, RecoverError.NoError);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore(0x00, \\\"\\\\x19Ethereum Signed Message:\\\\n32\\\")\\n mstore(0x1c, hash)\\n message := keccak256(0x00, 0x3c)\\n }\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from `s`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n\\\", Strings.toString(s.length), s));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Typed Data, created from a\\n * `domainSeparator` and a `structHash`. This produces hash corresponding\\n * to the one signed with the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n * JSON-RPC method as part of EIP-712.\\n *\\n * See {recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n let ptr := mload(0x40)\\n mstore(ptr, \\\"\\\\x19\\\\x01\\\")\\n mstore(add(ptr, 0x02), domainSeparator)\\n mstore(add(ptr, 0x22), structHash)\\n data := keccak256(ptr, 0x42)\\n }\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Data with intended validator, created from a\\n * `validator` and `data` according to the version 0 of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x00\\\", validator, data));\\n }\\n}\\n\",\"keccak256\":\"0x809bc3edb4bcbef8263fa616c1b60ee0004b50a8a1bfa164d8f57fd31f520c58\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n enum Rounding {\\n Down, // Toward negative infinity\\n Up, // Toward infinity\\n Zero // Toward zero\\n }\\n\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow.\\n return (a & b) + (a ^ b) / 2;\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a == 0 ? 0 : (a - 1) / b + 1;\\n }\\n\\n /**\\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\\n * with further edits by Uniswap Labs also under MIT license.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\\n unchecked {\\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2^256 + prod0.\\n uint256 prod0; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division.\\n if (prod1 == 0) {\\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\\n // The surrounding unchecked block does not change this fact.\\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\\n return prod0 / denominator;\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n require(denominator > prod1, \\\"Math: mulDiv overflow\\\");\\n\\n ///////////////////////////////////////////////\\n // 512 by 256 division.\\n ///////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0].\\n uint256 remainder;\\n assembly {\\n // Compute remainder using mulmod.\\n remainder := mulmod(x, y, denominator)\\n\\n // Subtract 256 bit number from 512 bit number.\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\\n // See https://cs.stackexchange.com/q/138556/92363.\\n\\n // Does not overflow because the denominator cannot be zero at this stage in the function.\\n uint256 twos = denominator & (~denominator + 1);\\n assembly {\\n // Divide denominator by twos.\\n denominator := div(denominator, twos)\\n\\n // Divide [prod1 prod0] by twos.\\n prod0 := div(prod0, twos)\\n\\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\\n twos := add(div(sub(0, twos), twos), 1)\\n }\\n\\n // Shift in bits from prod1 into prod0.\\n prod0 |= prod1 * twos;\\n\\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\\n // four bits. That is, denominator * inv = 1 mod 2^4.\\n uint256 inverse = (3 * denominator) ^ 2;\\n\\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\\n // in modular arithmetic, doubling the correct bits in each step.\\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\\n\\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inverse;\\n return result;\\n }\\n }\\n\\n /**\\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\\n uint256 result = mulDiv(x, y, denominator);\\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\\n result += 1;\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\\n *\\n * Inspired by Henry S. Warren, Jr.'s \\\"Hacker's Delight\\\" (Chapter 11).\\n */\\n function sqrt(uint256 a) internal pure returns (uint256) {\\n if (a == 0) {\\n return 0;\\n }\\n\\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\\n //\\n // We know that the \\\"msb\\\" (most significant bit) of our target number `a` is a power of 2 such that we have\\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\\n //\\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\\n // \\u2192 `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\\n // \\u2192 `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\\n //\\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\\n uint256 result = 1 << (log2(a) >> 1);\\n\\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\\n // into the expected uint128 result.\\n unchecked {\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n return min(result, a / result);\\n }\\n }\\n\\n /**\\n * @notice Calculates sqrt(a), following the selected rounding direction.\\n */\\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = sqrt(a);\\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 2, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 128;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 64;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 32;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 16;\\n }\\n if (value >> 8 > 0) {\\n value >>= 8;\\n result += 8;\\n }\\n if (value >> 4 > 0) {\\n value >>= 4;\\n result += 4;\\n }\\n if (value >> 2 > 0) {\\n value >>= 2;\\n result += 2;\\n }\\n if (value >> 1 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log2(value);\\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 10, rounded down, of a positive value.\\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 + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 256, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n *\\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\\n */\\n function log256(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 16;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 8;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 4;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 2;\\n }\\n if (value >> 8 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log256(value);\\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe4455ac1eb7fc497bb7402579e7b4d64d928b846fce7d2b6fde06d366f21c2b3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\\n * checks.\\n *\\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\\n * easily result in undesired exploitation or bugs, since developers usually\\n * assume that overflows raise errors. `SafeCast` restores this intuition by\\n * reverting the transaction when such an operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n *\\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\\n * all math on `uint256` and `int256` and then downcasting.\\n */\\nlibrary SafeCast {\\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 * _Available since v4.7._\\n */\\n function toUint248(uint256 value) internal pure returns (uint248) {\\n require(value <= type(uint248).max, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint240(uint256 value) internal pure returns (uint240) {\\n require(value <= type(uint240).max, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint232(uint256 value) internal pure returns (uint232) {\\n require(value <= type(uint232).max, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint224(uint256 value) internal pure returns (uint224) {\\n require(value <= type(uint224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint216(uint256 value) internal pure returns (uint216) {\\n require(value <= type(uint216).max, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint208(uint256 value) internal pure returns (uint208) {\\n require(value <= type(uint208).max, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint200(uint256 value) internal pure returns (uint200) {\\n require(value <= type(uint200).max, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint192(uint256 value) internal pure returns (uint192) {\\n require(value <= type(uint192).max, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint184(uint256 value) internal pure returns (uint184) {\\n require(value <= type(uint184).max, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint176(uint256 value) internal pure returns (uint176) {\\n require(value <= type(uint176).max, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint168(uint256 value) internal pure returns (uint168) {\\n require(value <= type(uint168).max, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint160(uint256 value) internal pure returns (uint160) {\\n require(value <= type(uint160).max, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint152(uint256 value) internal pure returns (uint152) {\\n require(value <= type(uint152).max, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint144(uint256 value) internal pure returns (uint144) {\\n require(value <= type(uint144).max, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint136(uint256 value) internal pure returns (uint136) {\\n require(value <= type(uint136).max, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint128(uint256 value) internal pure returns (uint128) {\\n require(value <= type(uint128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint120(uint256 value) internal pure returns (uint120) {\\n require(value <= type(uint120).max, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint112(uint256 value) internal pure returns (uint112) {\\n require(value <= type(uint112).max, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint104(uint256 value) internal pure returns (uint104) {\\n require(value <= type(uint104).max, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint96(uint256 value) internal pure returns (uint96) {\\n require(value <= type(uint96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint88(uint256 value) internal pure returns (uint88) {\\n require(value <= type(uint88).max, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint80(uint256 value) internal pure returns (uint80) {\\n require(value <= type(uint80).max, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint72(uint256 value) internal pure returns (uint72) {\\n require(value <= type(uint72).max, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint64(uint256 value) internal pure returns (uint64) {\\n require(value <= type(uint64).max, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint56(uint256 value) internal pure returns (uint56) {\\n require(value <= type(uint56).max, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint48(uint256 value) internal pure returns (uint48) {\\n require(value <= type(uint48).max, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint40(uint256 value) internal pure returns (uint40) {\\n require(value <= type(uint40).max, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint32(uint256 value) internal pure returns (uint32) {\\n require(value <= type(uint32).max, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint24(uint256 value) internal pure returns (uint24) {\\n require(value <= type(uint24).max, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint16(uint256 value) internal pure returns (uint16) {\\n require(value <= type(uint16).max, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint8(uint256 value) internal pure returns (uint8) {\\n require(value <= type(uint8).max, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\n */\\n function toUint256(int256 value) internal pure returns (uint256) {\\n require(value >= 0, \\\"SafeCast: value must be positive\\\");\\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 * _Available since v4.7._\\n */\\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\\n downcasted = int248(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\\n downcasted = int240(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\\n downcasted = int232(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\\n downcasted = int224(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\\n downcasted = int216(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\\n downcasted = int208(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\\n downcasted = int200(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\\n downcasted = int192(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\\n downcasted = int184(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\\n downcasted = int176(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\\n downcasted = int168(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\\n downcasted = int160(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\\n downcasted = int152(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\\n downcasted = int144(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\\n downcasted = int136(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\\n downcasted = int128(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\\n downcasted = int120(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\\n downcasted = int112(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\\n downcasted = int104(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\\n downcasted = int96(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\\n downcasted = int88(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\\n downcasted = int80(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\\n downcasted = int72(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\\n downcasted = int64(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\\n downcasted = int56(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\\n downcasted = int48(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\\n downcasted = int40(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\\n downcasted = int32(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\\n downcasted = int24(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\\n downcasted = int16(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\\n downcasted = int8(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\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 require(value <= uint256(type(int256).max), \\\"SafeCast: value doesn't fit in an int256\\\");\\n return int256(value);\\n }\\n}\\n\",\"keccak256\":\"0x52a8cfb0f5239d11b457dcdd1b326992ef672714ca8da71a157255bddd13f3ad\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SignedMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard signed math utilities missing in the Solidity language.\\n */\\nlibrary SignedMath {\\n /**\\n * @dev Returns the largest of two signed numbers.\\n */\\n function max(int256 a, int256 b) internal pure returns (int256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two signed numbers.\\n */\\n function min(int256 a, int256 b) internal pure returns (int256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two signed numbers without overflow.\\n * The result is rounded towards zero.\\n */\\n function average(int256 a, int256 b) internal pure returns (int256) {\\n // Formula from the book \\\"Hacker's Delight\\\"\\n int256 x = (a & b) + ((a ^ b) >> 1);\\n return x + (int256(uint256(x) >> 255) & (a ^ b));\\n }\\n\\n /**\\n * @dev Returns the absolute unsigned value of a signed value.\\n */\\n function abs(int256 n) internal pure returns (uint256) {\\n unchecked {\\n // must be unchecked in order to support `n = type(int256).min`\\n return uint256(n >= 0 ? n : -n);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf92515413956f529d95977adc9b0567d583c6203fc31ab1c23824c35187e3ddc\",\"license\":\"MIT\"},\"contracts/aa-4337/core/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable no-inline-assembly */\\n\\n/**\\n * returned data from validateUserOp.\\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\\n * @param aggregator - address(0) - the account validated the signature by itself.\\n * address(1) - the account failed to validate the signature.\\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\\n * @param validAfter - this UserOp is valid only after this timestamp.\\n * @param validaUntil - this UserOp is valid only up to this timestamp.\\n */\\nstruct ValidationData {\\n address aggregator;\\n uint48 validAfter;\\n uint48 validUntil;\\n}\\n\\n//extract sigFailed, validAfter, validUntil.\\n// also convert zero validUntil to type(uint48).max\\nfunction _parseValidationData(\\n uint validationData\\n) pure returns (ValidationData memory data) {\\n address aggregator = address(uint160(validationData));\\n uint48 validUntil = uint48(validationData >> 160);\\n if (validUntil == 0) {\\n validUntil = type(uint48).max;\\n }\\n uint48 validAfter = uint48(validationData >> (48 + 160));\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n// intersect account and paymaster ranges.\\nfunction _intersectTimeRange(\\n uint256 validationData,\\n uint256 paymasterValidationData\\n) pure returns (ValidationData memory) {\\n ValidationData memory accountValidationData = _parseValidationData(\\n validationData\\n );\\n ValidationData memory pmValidationData = _parseValidationData(\\n paymasterValidationData\\n );\\n address aggregator = accountValidationData.aggregator;\\n if (aggregator == address(0)) {\\n aggregator = pmValidationData.aggregator;\\n }\\n uint48 validAfter = accountValidationData.validAfter;\\n uint48 validUntil = accountValidationData.validUntil;\\n uint48 pmValidAfter = pmValidationData.validAfter;\\n uint48 pmValidUntil = pmValidationData.validUntil;\\n\\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp\\n * @param data - the ValidationData to pack\\n */\\nfunction _packValidationData(\\n ValidationData memory data\\n) pure returns (uint256) {\\n return\\n uint160(data.aggregator) |\\n (uint256(data.validUntil) << 160) |\\n (uint256(data.validAfter) << (160 + 48));\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp, when not using an aggregator\\n * @param sigFailed - true for signature failure, false for success\\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\\n * @param validAfter first timestamp this UserOperation is valid\\n */\\nfunction _packValidationData(\\n bool sigFailed,\\n uint48 validUntil,\\n uint48 validAfter\\n) pure returns (uint256) {\\n return\\n (sigFailed ? 1 : 0) |\\n (uint256(validUntil) << 160) |\\n (uint256(validAfter) << (160 + 48));\\n}\\n\\n/**\\n * keccak function over calldata.\\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\\n */\\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\\n assembly {\\n let mem := mload(0x40)\\n let len := data.length\\n calldatacopy(mem, data.offset, len)\\n ret := keccak256(mem, len)\\n }\\n}\\n\",\"keccak256\":\"0xa79f06cd158ecb8c0da95493a2f348933b8627a63e228b99738bff3aa107942d\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAggregator.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\n/**\\n * Aggregated Signatures validator.\\n */\\ninterface IAggregator {\\n /**\\n * validate aggregated signature.\\n * revert if the aggregated signature does not match the given list of operations.\\n */\\n function validateSignatures(\\n UserOperation[] calldata userOps,\\n bytes calldata signature\\n ) external view;\\n\\n /**\\n * validate signature of a single userOp\\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\\n * @param userOp the userOperation received from the user.\\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\\n * (usually empty, unless account and aggregator support some kind of \\\"multisig\\\"\\n */\\n function validateUserOpSignature(\\n UserOperation calldata userOp\\n ) external view returns (bytes memory sigForUserOp);\\n\\n /**\\n * aggregate multiple signatures into a single value.\\n * This method is called off-chain to calculate the signature to pass with handleOps()\\n * bundler MAY use optimized custom code perform this aggregation\\n * @param userOps array of UserOperations to collect the signatures from.\\n * @return aggregatedSignature the aggregated signature\\n */\\n function aggregateSignatures(\\n UserOperation[] calldata userOps\\n ) external view returns (bytes memory aggregatedSignature);\\n}\\n\",\"keccak256\":\"0xdfdcd80568f037716674619b31be630fcd8316262f05a815b41d1e81782c966a\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IEntryPoint.sol\":{\"content\":\"/**\\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\\n ** Only one instance required on each chain.\\n **/\\n// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-inline-assembly */\\n/* solhint-disable reason-string */\\n\\nimport \\\"./UserOperation.sol\\\";\\nimport \\\"./IStakeManager.sol\\\";\\nimport \\\"./IAggregator.sol\\\";\\nimport \\\"./INonceManager.sol\\\";\\n\\ninterface IEntryPoint is IStakeManager, INonceManager {\\n /***\\n * An event emitted after each successful request\\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\\n * @param sender - the account that generates this request.\\n * @param paymaster - if non-null, the paymaster that pays for this request.\\n * @param nonce - the nonce value from the request.\\n * @param success - true if the sender transaction succeeded, false if reverted.\\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\\n */\\n event UserOperationEvent(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address indexed paymaster,\\n uint256 nonce,\\n bool success,\\n uint256 actualGasCost,\\n uint256 actualGasUsed\\n );\\n\\n /**\\n * account \\\"sender\\\" was deployed.\\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\\n * @param sender the account that is deployed\\n * @param factory the factory used to deploy this account (in the initCode)\\n * @param paymaster the paymaster used by this UserOp\\n */\\n event AccountDeployed(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address factory,\\n address paymaster\\n );\\n\\n /**\\n * An event emitted if the UserOperation \\\"callData\\\" reverted with non-zero length\\n * @param userOpHash the request unique identifier.\\n * @param sender the sender of this request\\n * @param nonce the nonce used in the request\\n * @param revertReason - the return bytes from the (reverted) call to \\\"callData\\\".\\n */\\n event UserOperationRevertReason(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n uint256 nonce,\\n bytes revertReason\\n );\\n\\n /**\\n * an event emitted by handleOps(), before starting the execution loop.\\n * any event emitted before this event, is part of the validation.\\n */\\n event BeforeExecution();\\n\\n /**\\n * signature aggregator used by the following UserOperationEvents within this bundle.\\n */\\n event SignatureAggregatorChanged(address indexed aggregator);\\n\\n /**\\n * a custom revert error of handleOps, to identify the offending op.\\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\\n * @param reason - revert reason\\n * The string starts with a unique code \\\"AAmn\\\", where \\\"m\\\" is \\\"1\\\" for factory, \\\"2\\\" for account and \\\"3\\\" for paymaster issues,\\n * so a failure can be attributed to the correct entity.\\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\\n */\\n error FailedOp(uint256 opIndex, string reason);\\n\\n /**\\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\\n */\\n error SignatureValidationFailed(address aggregator);\\n\\n /**\\n * Successful result from simulateValidation.\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n */\\n error ValidationResult(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo\\n );\\n\\n /**\\n * Successful result from simulateValidation, if the account returns a signature aggregator\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\\n * bundler MUST use it to verify the signature, or reject the UserOperation\\n */\\n error ValidationResultWithAggregation(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo,\\n AggregatorStakeInfo aggregatorInfo\\n );\\n\\n /**\\n * return value of getSenderAddress\\n */\\n error SenderAddressResult(address sender);\\n\\n /**\\n * return value of simulateHandleOp\\n */\\n error ExecutionResult(\\n uint256 preOpGas,\\n uint256 paid,\\n uint48 validAfter,\\n uint48 validUntil,\\n bool targetSuccess,\\n bytes targetResult\\n );\\n\\n //UserOps handled, per aggregator\\n struct UserOpsPerAggregator {\\n UserOperation[] userOps;\\n // aggregator address\\n IAggregator aggregator;\\n // aggregated signature\\n bytes signature;\\n }\\n\\n /**\\n * Execute a batch of UserOperation.\\n * no signature aggregator is used.\\n * if any account requires an aggregator (that is, it returned an aggregator when\\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\\n * @param ops the operations to execute\\n * @param beneficiary the address to receive the fees\\n */\\n function handleOps(\\n UserOperation[] calldata ops,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * Execute a batch of UserOperation with Aggregators\\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\\n * @param beneficiary the address to receive the fees\\n */\\n function handleAggregatedOps(\\n UserOpsPerAggregator[] calldata opsPerAggregator,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * generate a request Id - unique identifier for this request.\\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\\n */\\n function getUserOpHash(\\n UserOperation calldata userOp\\n ) external view returns (bytes32);\\n\\n /**\\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\\n * @param userOp the user operation to validate.\\n */\\n function simulateValidation(UserOperation calldata userOp) external;\\n\\n /**\\n * gas and return values during simulation\\n * @param preOpGas the gas used for validation (including preValidationGas)\\n * @param prefund the required prefund for this operation\\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\\n */\\n struct ReturnInfo {\\n uint256 preOpGas;\\n uint256 prefund;\\n bool sigFailed;\\n uint48 validAfter;\\n uint48 validUntil;\\n bytes paymasterContext;\\n }\\n\\n /**\\n * returned aggregated signature info.\\n * the aggregator returned by the account, and its current stake.\\n */\\n struct AggregatorStakeInfo {\\n address aggregator;\\n StakeInfo stakeInfo;\\n }\\n\\n /**\\n * Get counterfactual sender address.\\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\\n * this method always revert, and returns the address in SenderAddressResult error\\n * @param initCode the constructor code to be passed into the UserOperation.\\n */\\n function getSenderAddress(bytes memory initCode) external;\\n\\n /**\\n * simulate full execution of a UserOperation (including both validation and target execution)\\n * this method will always revert with \\\"ExecutionResult\\\".\\n * it performs full validation of the UserOperation, but ignores signature error.\\n * an optional target address is called after the userop succeeds, and its value is returned\\n * (before the entire call is reverted)\\n * Note that in order to collect the the success/failure of the target call, it must be executed\\n * with trace enabled to track the emitted events.\\n * @param op the UserOperation to simulate\\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\\n * are set to the return from that call.\\n * @param targetCallData callData to pass to target address\\n */\\n function simulateHandleOp(\\n UserOperation calldata op,\\n address target,\\n bytes calldata targetCallData\\n ) external;\\n}\\n\",\"keccak256\":\"0x9ccb1b188eda8bbf5f6c2d01bd83c3d8b2b04fcf745283051d31fe96d1d8e40f\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/INonceManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\ninterface INonceManager {\\n /**\\n * Return the next nonce for this sender.\\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\\n * But UserOp with different keys can come with arbitrary order.\\n *\\n * @param sender the account address\\n * @param key the high 192 bit of the nonce\\n * @return nonce a full nonce to pass for next UserOp with this sender.\\n */\\n function getNonce(\\n address sender,\\n uint192 key\\n ) external view returns (uint256 nonce);\\n\\n /**\\n * Manually increment the nonce of the sender.\\n * This method is exposed just for completeness..\\n * Account does NOT need to call it, neither during validation, nor elsewhere,\\n * as the EntryPoint will update the nonce regardless.\\n * Possible use-case is call it with various keys to \\\"initialize\\\" their nonces to one, so that future\\n * UserOperations will not pay extra for the first transaction with a given key.\\n */\\n function incrementNonce(uint192 key) external;\\n}\\n\",\"keccak256\":\"0xce478ad0fa0d18a3b785ac854623029e7ab463d05873dfaa365abfa1bf100912\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IStakeManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8.12;\\n\\n/**\\n * manage deposits and stakes.\\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\\n * stake is value locked for at least \\\"unstakeDelay\\\" by the staked entity.\\n */\\ninterface IStakeManager {\\n event Deposited(address indexed account, uint256 totalDeposit);\\n\\n event Withdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /// Emitted when stake or unstake delay are modified\\n event StakeLocked(\\n address indexed account,\\n uint256 totalStaked,\\n uint256 unstakeDelaySec\\n );\\n\\n /// Emitted once a stake is scheduled for withdrawal\\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\\n\\n event StakeWithdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /**\\n * @param deposit the entity's deposit\\n * @param staked true if this entity is staked.\\n * @param stake actual amount of ether staked for this entity.\\n * @param unstakeDelaySec minimum delay to withdraw the stake.\\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\\n * and the rest fit into a 2nd cell.\\n * 112 bit allows for 10^15 eth\\n * 48 bit for full timestamp\\n * 32 bit allows 150 years for unstake delay\\n */\\n struct DepositInfo {\\n uint112 deposit;\\n bool staked;\\n uint112 stake;\\n uint32 unstakeDelaySec;\\n uint48 withdrawTime;\\n }\\n\\n //API struct used by getStakeInfo and simulateValidation\\n struct StakeInfo {\\n uint256 stake;\\n uint256 unstakeDelaySec;\\n }\\n\\n /// @return info - full deposit information of given account\\n function getDepositInfo(\\n address account\\n ) external view returns (DepositInfo memory info);\\n\\n /// @return the deposit (for gas payment) of the account\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * add to the deposit of the given account\\n */\\n function depositTo(address account) external payable;\\n\\n /**\\n * add to the account's stake - amount and delay\\n * any pending unstake is first cancelled.\\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\\n */\\n function addStake(uint32 _unstakeDelaySec) external payable;\\n\\n /**\\n * attempt to unlock the stake.\\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\\n */\\n function unlockStake() external;\\n\\n /**\\n * withdraw from the (unlocked) stake.\\n * must first call unlockStake and wait for the unstakeDelay to pass\\n * @param withdrawAddress the address to send withdrawn value.\\n */\\n function withdrawStake(address payable withdrawAddress) external;\\n\\n /**\\n * withdraw from the deposit.\\n * @param withdrawAddress the address to send withdrawn value.\\n * @param withdrawAmount the amount to withdraw.\\n */\\n function withdrawTo(\\n address payable withdrawAddress,\\n uint256 withdrawAmount\\n ) external;\\n}\\n\",\"keccak256\":\"0xadcea606c9b7aafe6645441f2154a60f271330b0eee5292a632aa71c1672d546\",\"license\":\"GPL-3.0-only\"},\"contracts/aa-4337/interfaces/UserOperation.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable no-inline-assembly */\\n\\nimport {calldataKeccak} from \\\"../core/Helpers.sol\\\";\\n\\n/**\\n * User Operation struct\\n * @param sender the sender account of this request.\\n * @param nonce unique value the sender uses to verify it is not a replay.\\n * @param initCode if set, the account contract will be created by this constructor/\\n * @param callData the method call to execute on this account.\\n * @param callGasLimit the gas limit passed to the callData method call.\\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\\n * @param maxFeePerGas same as EIP-1559 gas parameter.\\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\\n */\\nstruct UserOperation {\\n address sender;\\n uint256 nonce;\\n bytes initCode;\\n bytes callData;\\n uint256 callGasLimit;\\n uint256 verificationGasLimit;\\n uint256 preVerificationGas;\\n uint256 maxFeePerGas;\\n uint256 maxPriorityFeePerGas;\\n bytes paymasterAndData;\\n bytes signature;\\n}\\n\\n/**\\n * Utility functions helpful when working with UserOperation structs.\\n */\\nlibrary UserOperationLib {\\n function getSender(\\n UserOperation calldata userOp\\n ) internal pure returns (address) {\\n address data;\\n //read sender from userOp, which is first userOp member (saves 800 gas...)\\n assembly {\\n data := calldataload(userOp)\\n }\\n return address(uint160(data));\\n }\\n\\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\\n // pay above what he signed for.\\n function gasPrice(\\n UserOperation calldata userOp\\n ) internal view returns (uint256) {\\n unchecked {\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n if (maxFeePerGas == maxPriorityFeePerGas) {\\n //legacy mode (for networks that don't support basefee opcode)\\n return maxFeePerGas;\\n }\\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\\n }\\n }\\n\\n function pack(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes memory ret) {\\n address sender = getSender(userOp);\\n uint256 nonce = userOp.nonce;\\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\\n bytes32 hashCallData = calldataKeccak(userOp.callData);\\n uint256 callGasLimit = userOp.callGasLimit;\\n uint256 verificationGasLimit = userOp.verificationGasLimit;\\n uint256 preVerificationGas = userOp.preVerificationGas;\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\\n\\n return\\n abi.encode(\\n sender,\\n nonce,\\n hashInitCode,\\n hashCallData,\\n callGasLimit,\\n verificationGasLimit,\\n preVerificationGas,\\n maxFeePerGas,\\n maxPriorityFeePerGas,\\n hashPaymasterAndData\\n );\\n }\\n\\n function hash(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes32) {\\n return keccak256(pack(userOp));\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n}\\n\",\"keccak256\":\"0x2429f5cc546bdee08c7e63858d0dda8491eaa3ab5194df884dc948c1154d2834\",\"license\":\"GPL-3.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/facets/interfaces/IVerificationFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {UserOperation} from \\\"../../aa-4337/interfaces/UserOperation.sol\\\";\\n\\n/**\\n * @title Verification Facet Interface\\n * @dev Implements logic for user ops signature verification\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\ninterface IVerificationFacet {\\n event SignerInitialized(bytes);\\n event SignerUninitialized();\\n\\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\\n error VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\\n error VerificationFacet__InitializationFailure();\\n error VerificationFacet__InvalidFacetMapping();\\n\\n function initializeSigner(bytes memory) external returns (uint256);\\n\\n function uninitializeSigner() external returns (uint256);\\n\\n function validateOwnerSignatureSelector() external view returns (bytes4);\\n\\n function owner() external view returns (bytes memory);\\n\\n function isValidKeyType(bytes calldata) external view returns (bool);\\n\\n function validateOwnerSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x72bc370a1d1b5a6d6bde67f5026733fd8f6ba434bb90e73b0bd8627fb1579928\",\"license\":\"Apache-2.0\"},\"contracts/facets/verification/secp256k1/Secp256k1VerificationFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {ECDSA} from \\\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\\\";\\nimport {UserOperation} from \\\"../../../aa-4337/interfaces/UserOperation.sol\\\";\\nimport {LibAppStorage} from \\\"../../../libraries/LibAppStorage.sol\\\";\\nimport {LibFacetStorage, Secp256k1VerificationStorage} from \\\"../../../libraries/LibFacetStorage.sol\\\";\\nimport {LibLoupe} from \\\"../../../libraries/LibLoupe.sol\\\";\\nimport {IERC1271} from \\\"../../../interfaces/ERC/IERC1271.sol\\\";\\nimport {IVerificationFacet} from \\\"../../interfaces/IVerificationFacet.sol\\\";\\n\\n/**\\n * @title Secp256k1 verification facet\\n * @dev Default Ethereum's elliptic curve\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\ncontract Secp256k1VerificationFacet is IVerificationFacet, IERC1271 {\\n using ECDSA for bytes32;\\n error Secp256k1VerificationFacet__InvalidSignerLength();\\n address public immutable self;\\n\\n /**\\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\\n */\\n constructor() {\\n LibAppStorage.enforceSignerInitialize();\\n self = address(this);\\n }\\n\\n /**\\n * @notice Initializes the signer in K1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\\n * @param _publicKey Bytes of owner public key\\n * @return initSuccess Uint value representing the success of init operation\\n */\\n function initializeSigner(\\n bytes calldata _publicKey\\n ) public override returns (uint256 initSuccess) {\\n LibAppStorage.enforceSignerInitialize();\\n if (!isValidKeyType(_publicKey))\\n revert Secp256k1VerificationFacet__InvalidSignerLength();\\n\\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\\n .k1Storage();\\n k1Storage.signer = address(uint160(uint256(keccak256(_publicKey[1:]))));\\n\\n bytes4 validateSelector = validateOwnerSignatureSelector();\\n\\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\\n if (LibLoupe.facetAddress(validateSelector) != self)\\n revert VerificationFacet__InvalidFacetMapping();\\n\\n // initialize verification function selector\\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\\n\\n initSuccess = 1;\\n\\n emit SignerInitialized(_publicKey);\\n }\\n\\n /**\\n * @notice Uninitialize signer in K1 Facet Storage. This can only be called when the account is undergoing signature migration\\n * and has already been initialized.\\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\\n * @return uninitSuccess Uint value representing the success of uninit operation\\n */\\n function uninitializeSigner()\\n external\\n override\\n returns (uint256 uninitSuccess)\\n {\\n LibAppStorage.enforceSignerMigration();\\n LibAppStorage.setSignerUninitialized();\\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\\n .k1Storage();\\n k1Storage.signer = address(0);\\n\\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\\n\\n uninitSuccess = 1;\\n\\n emit SignerUninitialized();\\n }\\n\\n /**\\n * @notice Validates if the user operation is signed by the owner.\\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\\n * signer public key.\\n * @param userOp UserOperation including all information for execution\\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\\n */\\n function validateOwnerSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) public view override returns (uint256 validationData) {\\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\\n .k1Storage();\\n validationData = validateSignature(\\n userOp,\\n userOpHash,\\n k1Storage.signer\\n );\\n }\\n\\n /**\\n * @notice Validates if the signature of UserOperation is signed by the given signer\\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\\n * @param userOp UserOperation including all information for execution\\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\\n * @param signer Address of signer who signed the contract, to be validated\\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\\n */\\n function validateSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n address signer\\n ) public pure returns (uint256 isValid) {\\n bytes32 hash = userOpHash.toEthSignedMessageHash();\\n isValid = (signer != hash.recover(userOp.signature)) ? 1 : 0;\\n }\\n\\n /**\\n * @notice Returns the selector of function to validate the signature of UserOperation\\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\\n */\\n function validateOwnerSignatureSelector()\\n public\\n pure\\n override\\n returns (bytes4 ownerSignatureValidatorSelector)\\n {\\n ownerSignatureValidatorSelector = this.validateOwnerSignature.selector;\\n // NOTE: The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\\n }\\n\\n /**\\n * @notice Returns the owner of the account\\n * @return signer Bytes of owner address\\n */\\n function owner() public view override returns (bytes memory signer) {\\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\\n .k1Storage();\\n signer = abi.encodePacked(k1Storage.signer);\\n }\\n\\n /**\\n * @notice Validates if the format of public key is valid for this verification facet\\n * @dev For this Secp256k1Verification Facet, the public key length should be 65 in an uncompressed public key format\\n * @param _publicKey Bytes of public key for format check\\n * @return isValid Boolean variable representing if the format of public key is valid\\n */\\n function isValidKeyType(\\n bytes memory _publicKey\\n ) public pure override returns (bool isValid) {\\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\\n }\\n\\n /**\\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\\n * @param _hash Hash value the owner signed\\n * @param _signature Signature that signed the above hash\\n * @return magicValue Bytes4 value representing the success/failure of validation\\n */\\n function isValidSignature(\\n bytes32 _hash,\\n bytes memory _signature\\n ) public view override returns (bytes4 magicValue) {\\n magicValue = (_hash.recover(_signature) ==\\n LibFacetStorage.k1Storage().signer)\\n ? this.isValidSignature.selector\\n : bytes4(0xffffffff);\\n }\\n}\\n\",\"keccak256\":\"0x293ca694d0bad996df8b6d83a4bfdc4e5c3b3bc2e3f19e046c280e0233dbd806\",\"license\":\"Apache-2.0\"},\"contracts/infrastructure/interfaces/IFacetRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Registry Interface\\n * @dev Interface for Facet Registry contract to keep track of facets & function selectors addable to user wallets\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IFacetRegistry {\\n struct FacetRegistryConfig {\\n bytes4[] selectors;\\n mapping(bytes4 => FacetInfo) info;\\n }\\n struct FacetInfo {\\n bool exists;\\n uint128 index;\\n }\\n\\n event FacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] facetSelectors\\n );\\n event FacetFunctionSelectorsRemoved(address facet, bytes4[] facetSelectors);\\n\\n error FacetRegistry__FacetSelectorAlreadyRegistered();\\n error FacetRegistry__UnregisteredFacetSelector();\\n\\n function registerFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function removeFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function areFacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external view returns (bool);\\n\\n function isFacetFunctionSelectorRegistered(\\n address facet,\\n bytes4 facetSelector\\n ) external view returns (bool);\\n\\n function getFacetFunctionSelectors(\\n address facet\\n ) external view returns (bytes4[] memory);\\n}\\n\",\"keccak256\":\"0x6e6dd2cab346ef7c31230740ec48d2925e4a9ab24c2f2fb268baaf408dcf02ef\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC1271 {\\n function isValidSignature(\\n bytes32 hash,\\n bytes memory signature\\n ) external view returns (bytes4);\\n}\\n\",\"keccak256\":\"0xcdddb7d5641c9d3f2432dec7fd13fddb9ae1480f25c76c21511e2fa16b8bd422\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibAppStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {SafeCast} from \\\"@openzeppelin/contracts/utils/math/SafeCast.sol\\\";\\nimport {IEntryPoint} from \\\"../aa-4337/interfaces/IEntryPoint.sol\\\";\\nimport {IFacetRegistry} from \\\"../infrastructure/interfaces/IFacetRegistry.sol\\\";\\n\\n/*\\n * @title App Storage\\n * @dev App storage for Barz contract to prevent storage collision\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Lock {\\n uint64 release;\\n bytes4 locker;\\n}\\n\\nstruct InitializersStorage {\\n // NOTE: initialized is a variable to make sure the initialization is only done once.\\n uint8 signerInitialized;\\n uint8 accountInitialized;\\n uint8 restrictionsInitialized;\\n}\\n\\nstruct AppStorage {\\n mapping(uint256 => InitializersStorage) initStorage;\\n uint8 signerMigration;\\n bytes4 validateOwnerSignatureSelector;\\n IEntryPoint entryPoint;\\n IFacetRegistry facetRegistry;\\n mapping(uint256 => Lock) locks;\\n}\\n\\nlibrary LibAppStorage {\\n error LibAppStorage__AccountAlreadyUninitialized();\\n error LibAppStorage__AccountMustBeUninitialized();\\n error LibAppStorage__SignerAlreadyUninitialized();\\n error LibAppStorage__SignerMustBeUninitialized();\\n\\n function appStorage() internal pure returns (AppStorage storage ds) {\\n assembly {\\n ds.slot := 0\\n }\\n }\\n\\n function setSignerUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerAlreadyUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 0;\\n }\\n\\n function getValidateOwnerSignatureSelector()\\n internal\\n view\\n returns (bytes4 selector)\\n {\\n selector = appStorage().validateOwnerSignatureSelector;\\n }\\n\\n function setValidateOwnerSignatureSelector(\\n bytes4 _validateOwnerSignatureSelector\\n ) internal {\\n appStorage()\\n .validateOwnerSignatureSelector = _validateOwnerSignatureSelector;\\n }\\n\\n function enforceSignerInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerMustBeUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 1;\\n }\\n\\n function enforceAccountInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].accountInitialized) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n s.initStorage[0].accountInitialized = 1;\\n }\\n\\n function initiateSignerMigration() internal {\\n appStorage().signerMigration = 1;\\n }\\n\\n function enforceSignerMigration() internal view {\\n if (1 != appStorage().signerMigration) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n }\\n\\n function finalizeSignerMigration() internal {\\n appStorage().signerMigration = 0;\\n }\\n\\n function setLock(uint256 _releaseAfter, bytes4 _locker) internal {\\n appStorage().locks[0] = Lock(SafeCast.toUint64(_releaseAfter), _locker);\\n }\\n\\n function enforceRestrictionsInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__SignerMustBeUninitialized();\\n s.initStorage[0].restrictionsInitialized = 1;\\n }\\n\\n function setRestrictionsUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__AccountAlreadyUninitialized();\\n s.initStorage[0].restrictionsInitialized = 0;\\n }\\n}\\n\\ncontract BarzStorage {\\n AppStorage internal s;\\n modifier onlyWhenUnlocked() {\\n require(\\n uint64(block.timestamp) >= s.locks[0].release,\\n \\\"Account Locked\\\"\\n );\\n _;\\n }\\n modifier onlyWhenLocked() {\\n require(\\n uint64(block.timestamp) < s.locks[0].release,\\n \\\"Account Unlocked\\\"\\n );\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x48524007862a6ce0e07f645950613ce6513ce073c37a109c75019683d42bae27\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\\n bytes4(keccak256(\\\"verifyRestrictions(address,address,uint256,bytes)\\\"));\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // Default Fallback Handler of the barz.\\n IDiamondLoupe defaultFallbackHandler;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function enforceIsSelf() internal view {\\n require(msg.sender == address(this), \\\"LibDiamond: Caller not self\\\");\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n\\n unchecked {\\n facetIndex++;\\n }\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n\\n function restrictionsFacet() internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(\\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2cabdc00de859c3a3170ce3bda5d0e5fd3933d47ce904fd1585f9818b02572f8\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibFacetStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Storage\\n * @dev Storage contract to store each facets variables with diamond storage\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Secp256k1VerificationStorage {\\n address signer;\\n}\\n\\nstruct Secp256r1VerificationStorage {\\n uint256[2] q;\\n}\\n\\nstruct GuardianStorage {\\n mapping(bytes32 => uint256) pending;\\n mapping(uint8 => StorageConfig) configs;\\n}\\n\\nstruct Info {\\n bool exists;\\n uint128 index;\\n}\\n\\nstruct StorageConfig {\\n address[] addresses;\\n mapping(address => Info) info;\\n}\\n\\nstruct RecoveryConfig {\\n bytes recoveryPublicKey;\\n uint64 executeAfter;\\n}\\n\\nstruct ApprovalConfig {\\n bool isApproved;\\n uint64 validUntil;\\n}\\n\\nstruct RecoveryApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isNewOwnerApproved;\\n}\\n\\nstruct RecoveryStorage {\\n mapping(uint8 => RecoveryConfig) recoveryConfigs;\\n mapping(uint8 => RecoveryApprovalConfig) recoveryApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct RestrictionsStorage {\\n address[] restrictions;\\n mapping(address => bool) exists;\\n}\\n\\nstruct SignatureMigrationConfig {\\n bytes migrationPublicKey;\\n address migrationVerificationFacet;\\n bytes4[] migrationSelectors;\\n uint64 migrateAfter;\\n}\\n\\nstruct SignatureMigrationApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isMigrationApproved;\\n}\\n\\nstruct SignatureMigrationStorage {\\n mapping(uint8 => SignatureMigrationConfig) migrationConfigs;\\n mapping(uint8 => SignatureMigrationApprovalConfig) migrationApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct DiamondCutApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isDiamondCutApproved;\\n}\\n\\nstruct DiamondCutStorage {\\n mapping(uint8 => DiamondCutApprovalConfig) diamondCutApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct LockStorage {\\n uint128 nonce;\\n}\\n\\nlibrary LibFacetStorage {\\n bytes32 constant K1_STORAGE_POSITION =\\n keccak256(\\n \\\"v0.trustwallet.diamond.storage.Secp256k1VerificationStorage\\\"\\n );\\n bytes32 constant R1_STORAGE_POSITION =\\n keccak256(\\n \\\"v0.trustwallet.diamond.storage.Secp256r1VerificationStorage\\\"\\n );\\n bytes32 constant GUARDIAN_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.GuardianStorage\\\");\\n bytes32 constant RECOVERY_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.RecoveryStorage\\\");\\n bytes32 constant RESTRICTION_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.RestrictionsStorage\\\");\\n bytes32 constant MIGRATION_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.SignatureMigrationStorage\\\");\\n bytes32 constant DIAMONDCUT_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.DiamondCutStorage\\\");\\n bytes32 constant LOCK_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.LockStorage\\\");\\n\\n function k1Storage()\\n internal\\n pure\\n returns (Secp256k1VerificationStorage storage ds)\\n {\\n bytes32 storagePosition = K1_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function r1Storage()\\n internal\\n pure\\n returns (Secp256r1VerificationStorage storage ds)\\n {\\n bytes32 storagePosition = R1_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function guardianStorage()\\n internal\\n pure\\n returns (GuardianStorage storage ds)\\n {\\n bytes32 storagePosition = GUARDIAN_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function recoveryStorage()\\n internal\\n pure\\n returns (RecoveryStorage storage ds)\\n {\\n bytes32 storagePosition = RECOVERY_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function restrictionsStorage()\\n internal\\n pure\\n returns (RestrictionsStorage storage ds)\\n {\\n bytes32 storagePosition = RESTRICTION_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function migrationStorage()\\n internal\\n pure\\n returns (SignatureMigrationStorage storage ds)\\n {\\n bytes32 storagePosition = MIGRATION_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function diamondCutStorage()\\n internal\\n pure\\n returns (DiamondCutStorage storage ds)\\n {\\n bytes32 storagePosition = DIAMONDCUT_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function lockStorage() internal pure returns (LockStorage storage ds) {\\n bytes32 storagePosition = LOCK_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n}\\n\",\"keccak256\":\"0x87c85decfd943deda9540733e464cb1a92eba735a301e89ce6f798016e359761\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\nimport {LibDiamond} from \\\"./LibDiamond.sol\\\";\\n\\n/**\\n * @title LibLoupe\\n * @dev Internal Library to provide utility feature for reading the state of diamond facets\\n * Originally from Diamond's implementation of Mudgen(author of EIP-2535)\\n */\\nlibrary LibLoupe {\\n /// @notice Gets all facets and their selectors.\\n /// @return facets_ Facet\\n function facets()\\n internal\\n view\\n returns (IDiamondLoupe.Facet[] memory facets_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facets_ = new IDiamondLoupe.Facet[](ds.selectorCount);\\n uint16[] memory numFacetSelectors = new uint16[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facets_[facetIndex].facetAddress == facetAddress_) {\\n facets_[facetIndex].functionSelectors[\\n numFacetSelectors[facetIndex]\\n ] = selector;\\n // probably will never have more than 256 functions from one facet contract\\n require(numFacetSelectors[facetIndex] < 255);\\n numFacetSelectors[facetIndex]++;\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facets_[numFacets].facetAddress = facetAddress_;\\n facets_[numFacets].functionSelectors = new bytes4[](\\n ds.selectorCount\\n );\\n facets_[numFacets].functionSelectors[0] = selector;\\n numFacetSelectors[numFacets] = 1;\\n numFacets++;\\n }\\n }\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n uint256 numSelectors = numFacetSelectors[facetIndex];\\n bytes4[] memory selectors = facets_[facetIndex].functionSelectors;\\n // setting the number of selectors\\n assembly {\\n mstore(selectors, numSelectors)\\n }\\n }\\n // setting the number of facets\\n assembly {\\n mstore(facets_, numFacets)\\n }\\n }\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return _facetFunctionSelectors The selectors associated with a facet address.\\n function facetFunctionSelectors(\\n address _facet\\n ) internal view returns (bytes4[] memory _facetFunctionSelectors) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n uint256 numSelectors;\\n _facetFunctionSelectors = new bytes4[](ds.selectorCount);\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facet = address(bytes20(ds.facets[selector]));\\n if (_facet == facet) {\\n _facetFunctionSelectors[numSelectors] = selector;\\n numSelectors++;\\n }\\n }\\n }\\n // Set the number of selectors in the array\\n assembly {\\n mstore(_facetFunctionSelectors, numSelectors)\\n }\\n }\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n internal\\n view\\n returns (address[] memory facetAddresses_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetAddresses_ = new address[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facetAddress_ == facetAddresses_[facetIndex]) {\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facetAddresses_[numFacets] = facetAddress_;\\n numFacets++;\\n }\\n }\\n // Set the number of facet addresses in the array\\n assembly {\\n mstore(facetAddresses_, numFacets)\\n }\\n }\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(LibDiamond.diamondStorage().facets[_functionSelector])\\n );\\n }\\n}\\n\",\"keccak256\":\"0x0b11439c3cc657095e15ec2241fdcf67204b14001357b612fc5db4ff9e760a5a\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x60a060405234801561001057600080fd5b50610019610022565b3060805261008b565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff161561006f57604051637c2cde8b60e01b815260040160405180910390fd5b600080805260209190915260409020805460ff19166001179055565b6080516111946100ad6000396000818161013f015261066401526111946000f3fe608060405234801561001057600080fd5b50600436106100a35760003560e01c80638da5cb5b11610076578063cd00e50a1161005b578063cd00e50a14610218578063cd9b47e414610220578063f45007c31461023357600080fd5b80638da5cb5b146101865780638dd50121146101f757600080fd5b80631626ba7e146100a85780633253960f146100f1578063392dd6d9146101175780637104ddb21461013a575b600080fd5b6100bb6100b6366004610de8565b610246565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020015b60405180910390f35b7f8dd50121000000000000000000000000000000000000000000000000000000006100bb565b61012a610125366004610e2f565b6102f4565b60405190151581526020016100e8565b6101617f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100e8565b7f9d0217145d12a316adea26b4f622aec07fb71e6638d613bb415476f4c179eecc546040805160609290921b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016602083015280518083036014018152603490920190526040516100e89190610e64565b61020a610205366004610ee9565b610366565b6040519081526020016100e8565b61020a6103b8565b61020a61022e366004610f2e565b6104d6565b61020a610241366004610fa0565b6107b7565b60007f9d0217145d12a316adea26b4f622aec07fb71e6638d613bb415476f4c179eecc5473ffffffffffffffffffffffffffffffffffffffff1661028a848461087c565b73ffffffffffffffffffffffffffffffffffffffff16146102cb577fffffffff000000000000000000000000000000000000000000000000000000006102ed565b7f1626ba7e000000000000000000000000000000000000000000000000000000005b9392505050565b60008151604114801561036057508160008151811061031557610315611014565b6020910101517fff00000000000000000000000000000000000000000000000000000000000000167f0400000000000000000000000000000000000000000000000000000000000000145b92915050565b7f9d0217145d12a316adea26b4f622aec07fb71e6638d613bb415476f4c179eecc8054600091906103b0908590859073ffffffffffffffffffffffffffffffffffffffff166107b7565b949350505050565b60006103c26108a0565b6103ca6108e0565b7f9d0217145d12a316adea26b4f622aec07fb71e6638d613bb415476f4c179eecc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001681556000610424600154610100900460e01b90565b7fffffffff00000000000000000000000000000000000000000000000000000000160361047d576040517f127c609a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff169055604051600192507fcccd30db6bc000b8bb8d11162228d2d69e3c361983ca3ae8c1365ce64b0fae9e90600090a15090565b60006104e061097f565b61051f83838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102f492505050565b610555576040517f22281e8500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f9d0217145d12a316adea26b4f622aec07fb71e6638d613bb415476f4c179eecc6105838360018187611043565b60405161059192919061106d565b60405190819003902081547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9091161781556001547f8dd501210000000000000000000000000000000000000000000000000000000090600090610100900460e01b7fffffffff000000000000000000000000000000000000000000000000000000001614610662576040517f5f95a63c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166106f3827fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604090205460601c90565b73ffffffffffffffffffffffffffffffffffffffff1614610740576040517fbb4752b700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff1661010060e084901c02179055600192507f6d54821a69ec281ed7ba1bf2729c700768c47df1d80fad646b0a14cc1d5c39ed85856040516107a792919061107d565b60405180910390a1505092915050565b7f19457468657265756d205369676e6564204d6573736167653a0a3332000000006000908152601c839052603c81206108346107f76101408701876110ca565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250859392505061087c9050565b73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361086d576000610870565b60015b60ff1695945050505050565b600080600061088b8585610a1f565b9150915061089881610a64565b509392505050565b6001805460ff16146108de576040517f38fc28cb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff16600114610948576040517fe00d7c7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff16156109e5576040517f7c2cde8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b6000808251604103610a555760208301516040840151606085015160001a610a4987828585610c1f565b94509450505050610a5d565b506000905060025b9250929050565b6000816004811115610a7857610a7861112f565b03610a805750565b6001816004811115610a9457610a9461112f565b03610b00576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064015b60405180910390fd5b6002816004811115610b1457610b1461112f565b03610b7b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610af7565b6003816004811115610b8f57610b8f61112f565b03610c1c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610af7565b50565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115610c565750600090506003610d05565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015610caa573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116610cfe57600060019250925050610d05565b9150600090505b94509492505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112610d4e57600080fd5b813567ffffffffffffffff80821115610d6957610d69610d0e565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715610daf57610daf610d0e565b81604052838152866020858801011115610dc857600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060408385031215610dfb57600080fd5b82359150602083013567ffffffffffffffff811115610e1957600080fd5b610e2585828601610d3d565b9150509250929050565b600060208284031215610e4157600080fd5b813567ffffffffffffffff811115610e5857600080fd5b6103b084828501610d3d565b600060208083528351808285015260005b81811015610e9157858101830151858201604001528201610e75565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b60006101608284031215610ee357600080fd5b50919050565b60008060408385031215610efc57600080fd5b823567ffffffffffffffff811115610f1357600080fd5b610f1f85828601610ed0565b95602094909401359450505050565b60008060208385031215610f4157600080fd5b823567ffffffffffffffff80821115610f5957600080fd5b818501915085601f830112610f6d57600080fd5b813581811115610f7c57600080fd5b866020828501011115610f8e57600080fd5b60209290920196919550909350505050565b600080600060608486031215610fb557600080fd5b833567ffffffffffffffff811115610fcc57600080fd5b610fd886828701610ed0565b93505060208401359150604084013573ffffffffffffffffffffffffffffffffffffffff8116811461100957600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000808585111561105357600080fd5b8386111561106057600080fd5b5050820193919092039150565b8183823760009101908152919050565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126110ff57600080fd5b83018035915067ffffffffffffffff82111561111a57600080fd5b602001915036819003821315610a5d57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea2646970667358221220de3368e3f3953432149ec8ab61e8db05409a34e6f3f223f6bc0a20072fa01cf364736f6c63430008150033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100a35760003560e01c80638da5cb5b11610076578063cd00e50a1161005b578063cd00e50a14610218578063cd9b47e414610220578063f45007c31461023357600080fd5b80638da5cb5b146101865780638dd50121146101f757600080fd5b80631626ba7e146100a85780633253960f146100f1578063392dd6d9146101175780637104ddb21461013a575b600080fd5b6100bb6100b6366004610de8565b610246565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020015b60405180910390f35b7f8dd50121000000000000000000000000000000000000000000000000000000006100bb565b61012a610125366004610e2f565b6102f4565b60405190151581526020016100e8565b6101617f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100e8565b7f9d0217145d12a316adea26b4f622aec07fb71e6638d613bb415476f4c179eecc546040805160609290921b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016602083015280518083036014018152603490920190526040516100e89190610e64565b61020a610205366004610ee9565b610366565b6040519081526020016100e8565b61020a6103b8565b61020a61022e366004610f2e565b6104d6565b61020a610241366004610fa0565b6107b7565b60007f9d0217145d12a316adea26b4f622aec07fb71e6638d613bb415476f4c179eecc5473ffffffffffffffffffffffffffffffffffffffff1661028a848461087c565b73ffffffffffffffffffffffffffffffffffffffff16146102cb577fffffffff000000000000000000000000000000000000000000000000000000006102ed565b7f1626ba7e000000000000000000000000000000000000000000000000000000005b9392505050565b60008151604114801561036057508160008151811061031557610315611014565b6020910101517fff00000000000000000000000000000000000000000000000000000000000000167f0400000000000000000000000000000000000000000000000000000000000000145b92915050565b7f9d0217145d12a316adea26b4f622aec07fb71e6638d613bb415476f4c179eecc8054600091906103b0908590859073ffffffffffffffffffffffffffffffffffffffff166107b7565b949350505050565b60006103c26108a0565b6103ca6108e0565b7f9d0217145d12a316adea26b4f622aec07fb71e6638d613bb415476f4c179eecc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001681556000610424600154610100900460e01b90565b7fffffffff00000000000000000000000000000000000000000000000000000000160361047d576040517f127c609a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff169055604051600192507fcccd30db6bc000b8bb8d11162228d2d69e3c361983ca3ae8c1365ce64b0fae9e90600090a15090565b60006104e061097f565b61051f83838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102f492505050565b610555576040517f22281e8500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f9d0217145d12a316adea26b4f622aec07fb71e6638d613bb415476f4c179eecc6105838360018187611043565b60405161059192919061106d565b60405190819003902081547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9091161781556001547f8dd501210000000000000000000000000000000000000000000000000000000090600090610100900460e01b7fffffffff000000000000000000000000000000000000000000000000000000001614610662576040517f5f95a63c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166106f3827fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604090205460601c90565b73ffffffffffffffffffffffffffffffffffffffff1614610740576040517fbb4752b700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff1661010060e084901c02179055600192507f6d54821a69ec281ed7ba1bf2729c700768c47df1d80fad646b0a14cc1d5c39ed85856040516107a792919061107d565b60405180910390a1505092915050565b7f19457468657265756d205369676e6564204d6573736167653a0a3332000000006000908152601c839052603c81206108346107f76101408701876110ca565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250859392505061087c9050565b73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361086d576000610870565b60015b60ff1695945050505050565b600080600061088b8585610a1f565b9150915061089881610a64565b509392505050565b6001805460ff16146108de576040517f38fc28cb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff16600114610948576040517fe00d7c7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff16156109e5576040517f7c2cde8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b6000808251604103610a555760208301516040840151606085015160001a610a4987828585610c1f565b94509450505050610a5d565b506000905060025b9250929050565b6000816004811115610a7857610a7861112f565b03610a805750565b6001816004811115610a9457610a9461112f565b03610b00576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064015b60405180910390fd5b6002816004811115610b1457610b1461112f565b03610b7b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610af7565b6003816004811115610b8f57610b8f61112f565b03610c1c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610af7565b50565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115610c565750600090506003610d05565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015610caa573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116610cfe57600060019250925050610d05565b9150600090505b94509492505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112610d4e57600080fd5b813567ffffffffffffffff80821115610d6957610d69610d0e565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715610daf57610daf610d0e565b81604052838152866020858801011115610dc857600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060408385031215610dfb57600080fd5b82359150602083013567ffffffffffffffff811115610e1957600080fd5b610e2585828601610d3d565b9150509250929050565b600060208284031215610e4157600080fd5b813567ffffffffffffffff811115610e5857600080fd5b6103b084828501610d3d565b600060208083528351808285015260005b81811015610e9157858101830151858201604001528201610e75565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b60006101608284031215610ee357600080fd5b50919050565b60008060408385031215610efc57600080fd5b823567ffffffffffffffff811115610f1357600080fd5b610f1f85828601610ed0565b95602094909401359450505050565b60008060208385031215610f4157600080fd5b823567ffffffffffffffff80821115610f5957600080fd5b818501915085601f830112610f6d57600080fd5b813581811115610f7c57600080fd5b866020828501011115610f8e57600080fd5b60209290920196919550909350505050565b600080600060608486031215610fb557600080fd5b833567ffffffffffffffff811115610fcc57600080fd5b610fd886828701610ed0565b93505060208401359150604084013573ffffffffffffffffffffffffffffffffffffffff8116811461100957600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000808585111561105357600080fd5b8386111561106057600080fd5b5050820193919092039150565b8183823760009101908152919050565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126110ff57600080fd5b83018035915067ffffffffffffffff82111561111a57600080fd5b602001915036819003821315610a5d57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea2646970667358221220de3368e3f3953432149ec8ab61e8db05409a34e6f3f223f6bc0a20072fa01cf364736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)Ruslan Serebriakov (@rsrbk)", + "details": "Default Ethereum's elliptic curve", + "kind": "dev", + "methods": { + "initializeSigner(bytes)": { + "details": "This method checks if the signer has already been initialized. If already initialized, it reverts. It checks if the public key is in the light format and initializes signer storage in k1 storage.", + "params": { + "_publicKey": "Bytes of owner public key" + }, + "returns": { + "initSuccess": "Uint value representing the success of init operation" + } + }, + "isValidKeyType(bytes)": { + "details": "For this Secp256k1Verification Facet, the public key length should be 65 in an uncompressed public key format", + "params": { + "_publicKey": "Bytes of public key for format check" + }, + "returns": { + "isValid": "Boolean variable representing if the format of public key is valid" + } + }, + "isValidSignature(bytes32,bytes)": { + "details": "This method verifies the signature if the owner indeed signed the hash. Returns magic value if true", + "params": { + "_hash": "Hash value the owner signed", + "_signature": "Signature that signed the above hash" + }, + "returns": { + "magicValue": "Bytes4 value representing the success/failure of validation" + } + }, + "owner()": { + "returns": { + "signer": "Bytes of owner address" + } + }, + "uninitializeSigner()": { + "details": "This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.", + "returns": { + "uninitSuccess": "Uint value representing the success of uninit operation" + } + }, + "validateOwnerSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32)": { + "details": "This method validates if the user operation is signed by the owner. It internally calls validateSignature with signer public key.", + "params": { + "userOp": "UserOperation including all information for execution", + "userOpHash": "Hash of UserOperation given from EntryPoint. This hash is used for signature validation" + }, + "returns": { + "validationData": "Uint value representing whether the validation is successful. 0 for success, 1 for failure" + } + }, + "validateOwnerSignatureSelector()": { + "returns": { + "ownerSignatureValidatorSelector": "Bytes4 selector of function signature to validate account owner's UserOperation signature" + } + }, + "validateSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,address)": { + "details": "This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address", + "params": { + "signer": "Address of signer who signed the contract, to be validated", + "userOp": "UserOperation including all information for execution", + "userOpHash": "Hash of UserOperation given from EntryPoint. This hash is used for signature validation" + }, + "returns": { + "isValid": "Uint value representing whether the validation is successful. 0 for success, 1 for failure" + } + } + }, + "title": "Secp256k1 verification facet", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "constructor": { + "notice": "This constructor ensures that this contract can only be used as singleton for Proxy contracts" + }, + "initializeSigner(bytes)": { + "notice": "Initializes the signer in K1 Facet Storage. This can only be called when the account is uninitialized or during signature migration." + }, + "isValidKeyType(bytes)": { + "notice": "Validates if the format of public key is valid for this verification facet" + }, + "isValidSignature(bytes32,bytes)": { + "notice": "Validates if the signature is valid. Function to be compatible with EIP-1271" + }, + "owner()": { + "notice": "Returns the owner of the account" + }, + "uninitializeSigner()": { + "notice": "Uninitialize signer in K1 Facet Storage. This can only be called when the account is undergoing signature migration and has already been initialized." + }, + "validateOwnerSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32)": { + "notice": "Validates if the user operation is signed by the owner." + }, + "validateOwnerSignatureSelector()": { + "notice": "Returns the selector of function to validate the signature of UserOperation" + }, + "validateSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,address)": { + "notice": "Validates if the signature of UserOperation is signed by the given signer" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/mainnet/Secp256r1VerificationFacet.json b/deployments/mainnet/Secp256r1VerificationFacet.json new file mode 100644 index 0000000..a958a7c --- /dev/null +++ b/deployments/mainnet/Secp256r1VerificationFacet.json @@ -0,0 +1,483 @@ +{ + "address": "0xeE1AF8E967eC04C84711842796A5E714D2FD33e6", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "LibAppStorage__AccountMustBeUninitialized", + "type": "error" + }, + { + "inputs": [], + "name": "LibAppStorage__SignerAlreadyUninitialized", + "type": "error" + }, + { + "inputs": [], + "name": "LibAppStorage__SignerMustBeUninitialized", + "type": "error" + }, + { + "inputs": [], + "name": "Secp256r1VerificationFacet__InvalidSignerLength", + "type": "error" + }, + { + "inputs": [], + "name": "VerificationFacet__InitializationFailure", + "type": "error" + }, + { + "inputs": [], + "name": "VerificationFacet__InvalidFacetMapping", + "type": "error" + }, + { + "inputs": [], + "name": "VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet", + "type": "error" + }, + { + "inputs": [], + "name": "VerificationFacet__ValidateOwnerSignatureSelectorNotSet", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "SignerInitialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "SignerUninitialized", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_publicKey", + "type": "bytes" + } + ], + "name": "initializeSigner", + "outputs": [ + { + "internalType": "uint256", + "name": "initSuccess", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_publicKey", + "type": "bytes" + } + ], + "name": "isValidKeyType", + "outputs": [ + { + "internalType": "bool", + "name": "isValid", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_hash", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "_signature", + "type": "bytes" + } + ], + "name": "isValidSignature", + "outputs": [ + { + "internalType": "bytes4", + "name": "magicValue", + "type": "bytes4" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "bytes", + "name": "signer", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "self", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "uninitializeSigner", + "outputs": [ + { + "internalType": "uint256", + "name": "uninitSuccess", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "initCode", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "callGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "verificationGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "preVerificationGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxFeePerGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPriorityFeePerGas", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "paymasterAndData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "internalType": "struct UserOperation", + "name": "userOp", + "type": "tuple" + }, + { + "internalType": "bytes32", + "name": "userOpHash", + "type": "bytes32" + } + ], + "name": "validateOwnerSignature", + "outputs": [ + { + "internalType": "uint256", + "name": "validationData", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "validateOwnerSignatureSelector", + "outputs": [ + { + "internalType": "bytes4", + "name": "ownerSignatureValidatorSelector", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "initCode", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "callGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "verificationGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "preVerificationGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxFeePerGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPriorityFeePerGas", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "paymasterAndData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "internalType": "struct UserOperation", + "name": "userOp", + "type": "tuple" + }, + { + "internalType": "bytes32", + "name": "userOpHash", + "type": "bytes32" + }, + { + "internalType": "uint256[2]", + "name": "q", + "type": "uint256[2]" + } + ], + "name": "validateSignature", + "outputs": [ + { + "internalType": "uint256", + "name": "isValid", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0x239bf404c8647ea84be5e09c4eb5c990f2ad514dae3073b91f11c91c5aa45768", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 96, + "gasUsed": "1809741", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0xc5f0f91b94daffcbfb0d073faf66d12f5fc67a411df01d520e5503c4f7473d2f", + "transactionHash": "0x239bf404c8647ea84be5e09c4eb5c990f2ad514dae3073b91f11c91c5aa45768", + "logs": [], + "blockNumber": 19517135, + "cumulativeGasUsed": "10984925", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "ad34345aa73d96f52b3e14df983b6b29", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"LibAppStorage__AccountMustBeUninitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LibAppStorage__SignerAlreadyUninitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LibAppStorage__SignerMustBeUninitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Secp256r1VerificationFacet__InvalidSignerLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerificationFacet__InitializationFailure\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerificationFacet__InvalidFacetMapping\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerificationFacet__ValidateOwnerSignatureSelectorNotSet\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"SignerInitialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"SignerUninitialized\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_publicKey\",\"type\":\"bytes\"}],\"name\":\"initializeSigner\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"initSuccess\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_publicKey\",\"type\":\"bytes\"}],\"name\":\"isValidKeyType\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isValid\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_hash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"_signature\",\"type\":\"bytes\"}],\"name\":\"isValidSignature\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"magicValue\",\"type\":\"bytes4\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"signer\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"self\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"uninitializeSigner\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"uninitSuccess\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"userOp\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"}],\"name\":\"validateOwnerSignature\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"validationData\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"validateOwnerSignatureSelector\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"ownerSignatureValidatorSelector\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"userOp\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256[2]\",\"name\":\"q\",\"type\":\"uint256[2]\"}],\"name\":\"validateSignature\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"isValid\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Ruslan Serebriakov (@rsrbk)David Yongjun Kim (@Powerstream3604)\",\"details\":\"Primarily used to verify user ops signed with passkeys\",\"kind\":\"dev\",\"methods\":{\"initializeSigner(bytes)\":{\"details\":\"This method checks if the signer has already been initialized. If already initialized, it reverts. It checks if the public key is in the light format and initializes signer storage in k1 storage.\",\"params\":{\"_publicKey\":\"Bytes of owner public key\"},\"returns\":{\"initSuccess\":\"Uint value representing the success of init operation\"}},\"isValidKeyType(bytes)\":{\"details\":\"For this Secp256k1Verification Facet, the public key should in an uncompressed public key format\",\"params\":{\"_publicKey\":\"Bytes of public key for format check\"},\"returns\":{\"isValid\":\"Boolean variable representing if the format of public key is valid\"}},\"isValidSignature(bytes32,bytes)\":{\"details\":\"This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\",\"params\":{\"_hash\":\"Hash value the owner signed\",\"_signature\":\"Signature that signed the above hash\"},\"returns\":{\"magicValue\":\"Bytes4 value representing the success/failure of validation\"}},\"owner()\":{\"returns\":{\"signer\":\"Bytes of owner address\"}},\"uninitializeSigner()\":{\"details\":\"This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\",\"returns\":{\"uninitSuccess\":\"Uint value representing the success of uninit operation\"}},\"validateOwnerSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32)\":{\"details\":\"This method validates if the user operation is signed by the owner. It internally calls validateSignature with signer public key.\",\"params\":{\"userOp\":\"UserOperation including all information for execution\",\"userOpHash\":\"Hash of UserOperation given from EntryPoint. This hash is used for signature validation\"},\"returns\":{\"validationData\":\"Uint value representing whether the validation is successful. 0 for success, 1 for failure\"}},\"validateOwnerSignatureSelector()\":{\"returns\":{\"ownerSignatureValidatorSelector\":\"Bytes4 selector of function signature to validate account owner's UserOperation signature\"}},\"validateSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256[2])\":{\"details\":\"This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\",\"params\":{\"q\":\"Public Key of signer who signed the contract, to be validated\",\"userOp\":\"UserOperation including all information for execution\",\"userOpHash\":\"Hash of UserOperation given from EntryPoint. This hash is used for signature validation\"},\"returns\":{\"isValid\":\"Uint value representing whether the validation is successful. 0 for success, 1 for failure\"}}},\"title\":\"Secp256r1 verification facet\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"This constructor ensures that this contract can only be used as singleton for Proxy contracts\"},\"initializeSigner(bytes)\":{\"notice\":\"Initializes the signer in R1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\"},\"isValidKeyType(bytes)\":{\"notice\":\"Validates if the format of public key is valid for this verification facet\"},\"isValidSignature(bytes32,bytes)\":{\"notice\":\"Validates if the signature is valid. Function to be compatible with EIP-1271\"},\"owner()\":{\"notice\":\"Returns the owner of the account\"},\"uninitializeSigner()\":{\"notice\":\"Uninitialize signer in R1 Facet Storage. This can only be called when the account is undergoing signature migration and has already been initialized.\"},\"validateOwnerSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32)\":{\"notice\":\"Validates if the user operation is signed by the owner.\"},\"validateOwnerSignatureSelector()\":{\"notice\":\"Returns the selector of function to validate the signature of UserOperation\"},\"validateSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256[2])\":{\"notice\":\"Validates if the signature of UserOperation is signed by the given signer\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/verification/secp256r1/Secp256r1VerificationFacet.sol\":\"Secp256r1VerificationFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/utils/math/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\\n * checks.\\n *\\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\\n * easily result in undesired exploitation or bugs, since developers usually\\n * assume that overflows raise errors. `SafeCast` restores this intuition by\\n * reverting the transaction when such an operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n *\\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\\n * all math on `uint256` and `int256` and then downcasting.\\n */\\nlibrary SafeCast {\\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 * _Available since v4.7._\\n */\\n function toUint248(uint256 value) internal pure returns (uint248) {\\n require(value <= type(uint248).max, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint240(uint256 value) internal pure returns (uint240) {\\n require(value <= type(uint240).max, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint232(uint256 value) internal pure returns (uint232) {\\n require(value <= type(uint232).max, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint224(uint256 value) internal pure returns (uint224) {\\n require(value <= type(uint224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint216(uint256 value) internal pure returns (uint216) {\\n require(value <= type(uint216).max, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint208(uint256 value) internal pure returns (uint208) {\\n require(value <= type(uint208).max, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint200(uint256 value) internal pure returns (uint200) {\\n require(value <= type(uint200).max, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint192(uint256 value) internal pure returns (uint192) {\\n require(value <= type(uint192).max, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint184(uint256 value) internal pure returns (uint184) {\\n require(value <= type(uint184).max, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint176(uint256 value) internal pure returns (uint176) {\\n require(value <= type(uint176).max, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint168(uint256 value) internal pure returns (uint168) {\\n require(value <= type(uint168).max, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint160(uint256 value) internal pure returns (uint160) {\\n require(value <= type(uint160).max, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint152(uint256 value) internal pure returns (uint152) {\\n require(value <= type(uint152).max, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint144(uint256 value) internal pure returns (uint144) {\\n require(value <= type(uint144).max, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint136(uint256 value) internal pure returns (uint136) {\\n require(value <= type(uint136).max, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint128(uint256 value) internal pure returns (uint128) {\\n require(value <= type(uint128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint120(uint256 value) internal pure returns (uint120) {\\n require(value <= type(uint120).max, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint112(uint256 value) internal pure returns (uint112) {\\n require(value <= type(uint112).max, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint104(uint256 value) internal pure returns (uint104) {\\n require(value <= type(uint104).max, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint96(uint256 value) internal pure returns (uint96) {\\n require(value <= type(uint96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint88(uint256 value) internal pure returns (uint88) {\\n require(value <= type(uint88).max, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint80(uint256 value) internal pure returns (uint80) {\\n require(value <= type(uint80).max, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint72(uint256 value) internal pure returns (uint72) {\\n require(value <= type(uint72).max, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint64(uint256 value) internal pure returns (uint64) {\\n require(value <= type(uint64).max, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint56(uint256 value) internal pure returns (uint56) {\\n require(value <= type(uint56).max, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint48(uint256 value) internal pure returns (uint48) {\\n require(value <= type(uint48).max, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint40(uint256 value) internal pure returns (uint40) {\\n require(value <= type(uint40).max, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint32(uint256 value) internal pure returns (uint32) {\\n require(value <= type(uint32).max, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint24(uint256 value) internal pure returns (uint24) {\\n require(value <= type(uint24).max, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint16(uint256 value) internal pure returns (uint16) {\\n require(value <= type(uint16).max, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint8(uint256 value) internal pure returns (uint8) {\\n require(value <= type(uint8).max, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\n */\\n function toUint256(int256 value) internal pure returns (uint256) {\\n require(value >= 0, \\\"SafeCast: value must be positive\\\");\\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 * _Available since v4.7._\\n */\\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\\n downcasted = int248(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\\n downcasted = int240(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\\n downcasted = int232(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\\n downcasted = int224(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\\n downcasted = int216(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\\n downcasted = int208(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\\n downcasted = int200(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\\n downcasted = int192(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\\n downcasted = int184(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\\n downcasted = int176(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\\n downcasted = int168(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\\n downcasted = int160(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\\n downcasted = int152(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\\n downcasted = int144(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\\n downcasted = int136(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\\n downcasted = int128(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\\n downcasted = int120(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\\n downcasted = int112(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\\n downcasted = int104(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\\n downcasted = int96(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\\n downcasted = int88(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\\n downcasted = int80(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\\n downcasted = int72(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\\n downcasted = int64(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\\n downcasted = int56(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\\n downcasted = int48(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\\n downcasted = int40(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\\n downcasted = int32(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\\n downcasted = int24(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\\n downcasted = int16(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\\n downcasted = int8(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\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 require(value <= uint256(type(int256).max), \\\"SafeCast: value doesn't fit in an int256\\\");\\n return int256(value);\\n }\\n}\\n\",\"keccak256\":\"0x52a8cfb0f5239d11b457dcdd1b326992ef672714ca8da71a157255bddd13f3ad\",\"license\":\"MIT\"},\"contracts/aa-4337/core/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable no-inline-assembly */\\n\\n/**\\n * returned data from validateUserOp.\\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\\n * @param aggregator - address(0) - the account validated the signature by itself.\\n * address(1) - the account failed to validate the signature.\\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\\n * @param validAfter - this UserOp is valid only after this timestamp.\\n * @param validaUntil - this UserOp is valid only up to this timestamp.\\n */\\nstruct ValidationData {\\n address aggregator;\\n uint48 validAfter;\\n uint48 validUntil;\\n}\\n\\n//extract sigFailed, validAfter, validUntil.\\n// also convert zero validUntil to type(uint48).max\\nfunction _parseValidationData(\\n uint validationData\\n) pure returns (ValidationData memory data) {\\n address aggregator = address(uint160(validationData));\\n uint48 validUntil = uint48(validationData >> 160);\\n if (validUntil == 0) {\\n validUntil = type(uint48).max;\\n }\\n uint48 validAfter = uint48(validationData >> (48 + 160));\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n// intersect account and paymaster ranges.\\nfunction _intersectTimeRange(\\n uint256 validationData,\\n uint256 paymasterValidationData\\n) pure returns (ValidationData memory) {\\n ValidationData memory accountValidationData = _parseValidationData(\\n validationData\\n );\\n ValidationData memory pmValidationData = _parseValidationData(\\n paymasterValidationData\\n );\\n address aggregator = accountValidationData.aggregator;\\n if (aggregator == address(0)) {\\n aggregator = pmValidationData.aggregator;\\n }\\n uint48 validAfter = accountValidationData.validAfter;\\n uint48 validUntil = accountValidationData.validUntil;\\n uint48 pmValidAfter = pmValidationData.validAfter;\\n uint48 pmValidUntil = pmValidationData.validUntil;\\n\\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp\\n * @param data - the ValidationData to pack\\n */\\nfunction _packValidationData(\\n ValidationData memory data\\n) pure returns (uint256) {\\n return\\n uint160(data.aggregator) |\\n (uint256(data.validUntil) << 160) |\\n (uint256(data.validAfter) << (160 + 48));\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp, when not using an aggregator\\n * @param sigFailed - true for signature failure, false for success\\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\\n * @param validAfter first timestamp this UserOperation is valid\\n */\\nfunction _packValidationData(\\n bool sigFailed,\\n uint48 validUntil,\\n uint48 validAfter\\n) pure returns (uint256) {\\n return\\n (sigFailed ? 1 : 0) |\\n (uint256(validUntil) << 160) |\\n (uint256(validAfter) << (160 + 48));\\n}\\n\\n/**\\n * keccak function over calldata.\\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\\n */\\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\\n assembly {\\n let mem := mload(0x40)\\n let len := data.length\\n calldatacopy(mem, data.offset, len)\\n ret := keccak256(mem, len)\\n }\\n}\\n\",\"keccak256\":\"0xa79f06cd158ecb8c0da95493a2f348933b8627a63e228b99738bff3aa107942d\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAggregator.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\n/**\\n * Aggregated Signatures validator.\\n */\\ninterface IAggregator {\\n /**\\n * validate aggregated signature.\\n * revert if the aggregated signature does not match the given list of operations.\\n */\\n function validateSignatures(\\n UserOperation[] calldata userOps,\\n bytes calldata signature\\n ) external view;\\n\\n /**\\n * validate signature of a single userOp\\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\\n * @param userOp the userOperation received from the user.\\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\\n * (usually empty, unless account and aggregator support some kind of \\\"multisig\\\"\\n */\\n function validateUserOpSignature(\\n UserOperation calldata userOp\\n ) external view returns (bytes memory sigForUserOp);\\n\\n /**\\n * aggregate multiple signatures into a single value.\\n * This method is called off-chain to calculate the signature to pass with handleOps()\\n * bundler MAY use optimized custom code perform this aggregation\\n * @param userOps array of UserOperations to collect the signatures from.\\n * @return aggregatedSignature the aggregated signature\\n */\\n function aggregateSignatures(\\n UserOperation[] calldata userOps\\n ) external view returns (bytes memory aggregatedSignature);\\n}\\n\",\"keccak256\":\"0xdfdcd80568f037716674619b31be630fcd8316262f05a815b41d1e81782c966a\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IEntryPoint.sol\":{\"content\":\"/**\\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\\n ** Only one instance required on each chain.\\n **/\\n// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-inline-assembly */\\n/* solhint-disable reason-string */\\n\\nimport \\\"./UserOperation.sol\\\";\\nimport \\\"./IStakeManager.sol\\\";\\nimport \\\"./IAggregator.sol\\\";\\nimport \\\"./INonceManager.sol\\\";\\n\\ninterface IEntryPoint is IStakeManager, INonceManager {\\n /***\\n * An event emitted after each successful request\\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\\n * @param sender - the account that generates this request.\\n * @param paymaster - if non-null, the paymaster that pays for this request.\\n * @param nonce - the nonce value from the request.\\n * @param success - true if the sender transaction succeeded, false if reverted.\\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\\n */\\n event UserOperationEvent(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address indexed paymaster,\\n uint256 nonce,\\n bool success,\\n uint256 actualGasCost,\\n uint256 actualGasUsed\\n );\\n\\n /**\\n * account \\\"sender\\\" was deployed.\\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\\n * @param sender the account that is deployed\\n * @param factory the factory used to deploy this account (in the initCode)\\n * @param paymaster the paymaster used by this UserOp\\n */\\n event AccountDeployed(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address factory,\\n address paymaster\\n );\\n\\n /**\\n * An event emitted if the UserOperation \\\"callData\\\" reverted with non-zero length\\n * @param userOpHash the request unique identifier.\\n * @param sender the sender of this request\\n * @param nonce the nonce used in the request\\n * @param revertReason - the return bytes from the (reverted) call to \\\"callData\\\".\\n */\\n event UserOperationRevertReason(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n uint256 nonce,\\n bytes revertReason\\n );\\n\\n /**\\n * an event emitted by handleOps(), before starting the execution loop.\\n * any event emitted before this event, is part of the validation.\\n */\\n event BeforeExecution();\\n\\n /**\\n * signature aggregator used by the following UserOperationEvents within this bundle.\\n */\\n event SignatureAggregatorChanged(address indexed aggregator);\\n\\n /**\\n * a custom revert error of handleOps, to identify the offending op.\\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\\n * @param reason - revert reason\\n * The string starts with a unique code \\\"AAmn\\\", where \\\"m\\\" is \\\"1\\\" for factory, \\\"2\\\" for account and \\\"3\\\" for paymaster issues,\\n * so a failure can be attributed to the correct entity.\\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\\n */\\n error FailedOp(uint256 opIndex, string reason);\\n\\n /**\\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\\n */\\n error SignatureValidationFailed(address aggregator);\\n\\n /**\\n * Successful result from simulateValidation.\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n */\\n error ValidationResult(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo\\n );\\n\\n /**\\n * Successful result from simulateValidation, if the account returns a signature aggregator\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\\n * bundler MUST use it to verify the signature, or reject the UserOperation\\n */\\n error ValidationResultWithAggregation(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo,\\n AggregatorStakeInfo aggregatorInfo\\n );\\n\\n /**\\n * return value of getSenderAddress\\n */\\n error SenderAddressResult(address sender);\\n\\n /**\\n * return value of simulateHandleOp\\n */\\n error ExecutionResult(\\n uint256 preOpGas,\\n uint256 paid,\\n uint48 validAfter,\\n uint48 validUntil,\\n bool targetSuccess,\\n bytes targetResult\\n );\\n\\n //UserOps handled, per aggregator\\n struct UserOpsPerAggregator {\\n UserOperation[] userOps;\\n // aggregator address\\n IAggregator aggregator;\\n // aggregated signature\\n bytes signature;\\n }\\n\\n /**\\n * Execute a batch of UserOperation.\\n * no signature aggregator is used.\\n * if any account requires an aggregator (that is, it returned an aggregator when\\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\\n * @param ops the operations to execute\\n * @param beneficiary the address to receive the fees\\n */\\n function handleOps(\\n UserOperation[] calldata ops,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * Execute a batch of UserOperation with Aggregators\\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\\n * @param beneficiary the address to receive the fees\\n */\\n function handleAggregatedOps(\\n UserOpsPerAggregator[] calldata opsPerAggregator,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * generate a request Id - unique identifier for this request.\\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\\n */\\n function getUserOpHash(\\n UserOperation calldata userOp\\n ) external view returns (bytes32);\\n\\n /**\\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\\n * @param userOp the user operation to validate.\\n */\\n function simulateValidation(UserOperation calldata userOp) external;\\n\\n /**\\n * gas and return values during simulation\\n * @param preOpGas the gas used for validation (including preValidationGas)\\n * @param prefund the required prefund for this operation\\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\\n */\\n struct ReturnInfo {\\n uint256 preOpGas;\\n uint256 prefund;\\n bool sigFailed;\\n uint48 validAfter;\\n uint48 validUntil;\\n bytes paymasterContext;\\n }\\n\\n /**\\n * returned aggregated signature info.\\n * the aggregator returned by the account, and its current stake.\\n */\\n struct AggregatorStakeInfo {\\n address aggregator;\\n StakeInfo stakeInfo;\\n }\\n\\n /**\\n * Get counterfactual sender address.\\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\\n * this method always revert, and returns the address in SenderAddressResult error\\n * @param initCode the constructor code to be passed into the UserOperation.\\n */\\n function getSenderAddress(bytes memory initCode) external;\\n\\n /**\\n * simulate full execution of a UserOperation (including both validation and target execution)\\n * this method will always revert with \\\"ExecutionResult\\\".\\n * it performs full validation of the UserOperation, but ignores signature error.\\n * an optional target address is called after the userop succeeds, and its value is returned\\n * (before the entire call is reverted)\\n * Note that in order to collect the the success/failure of the target call, it must be executed\\n * with trace enabled to track the emitted events.\\n * @param op the UserOperation to simulate\\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\\n * are set to the return from that call.\\n * @param targetCallData callData to pass to target address\\n */\\n function simulateHandleOp(\\n UserOperation calldata op,\\n address target,\\n bytes calldata targetCallData\\n ) external;\\n}\\n\",\"keccak256\":\"0x9ccb1b188eda8bbf5f6c2d01bd83c3d8b2b04fcf745283051d31fe96d1d8e40f\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/INonceManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\ninterface INonceManager {\\n /**\\n * Return the next nonce for this sender.\\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\\n * But UserOp with different keys can come with arbitrary order.\\n *\\n * @param sender the account address\\n * @param key the high 192 bit of the nonce\\n * @return nonce a full nonce to pass for next UserOp with this sender.\\n */\\n function getNonce(\\n address sender,\\n uint192 key\\n ) external view returns (uint256 nonce);\\n\\n /**\\n * Manually increment the nonce of the sender.\\n * This method is exposed just for completeness..\\n * Account does NOT need to call it, neither during validation, nor elsewhere,\\n * as the EntryPoint will update the nonce regardless.\\n * Possible use-case is call it with various keys to \\\"initialize\\\" their nonces to one, so that future\\n * UserOperations will not pay extra for the first transaction with a given key.\\n */\\n function incrementNonce(uint192 key) external;\\n}\\n\",\"keccak256\":\"0xce478ad0fa0d18a3b785ac854623029e7ab463d05873dfaa365abfa1bf100912\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IStakeManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8.12;\\n\\n/**\\n * manage deposits and stakes.\\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\\n * stake is value locked for at least \\\"unstakeDelay\\\" by the staked entity.\\n */\\ninterface IStakeManager {\\n event Deposited(address indexed account, uint256 totalDeposit);\\n\\n event Withdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /// Emitted when stake or unstake delay are modified\\n event StakeLocked(\\n address indexed account,\\n uint256 totalStaked,\\n uint256 unstakeDelaySec\\n );\\n\\n /// Emitted once a stake is scheduled for withdrawal\\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\\n\\n event StakeWithdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /**\\n * @param deposit the entity's deposit\\n * @param staked true if this entity is staked.\\n * @param stake actual amount of ether staked for this entity.\\n * @param unstakeDelaySec minimum delay to withdraw the stake.\\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\\n * and the rest fit into a 2nd cell.\\n * 112 bit allows for 10^15 eth\\n * 48 bit for full timestamp\\n * 32 bit allows 150 years for unstake delay\\n */\\n struct DepositInfo {\\n uint112 deposit;\\n bool staked;\\n uint112 stake;\\n uint32 unstakeDelaySec;\\n uint48 withdrawTime;\\n }\\n\\n //API struct used by getStakeInfo and simulateValidation\\n struct StakeInfo {\\n uint256 stake;\\n uint256 unstakeDelaySec;\\n }\\n\\n /// @return info - full deposit information of given account\\n function getDepositInfo(\\n address account\\n ) external view returns (DepositInfo memory info);\\n\\n /// @return the deposit (for gas payment) of the account\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * add to the deposit of the given account\\n */\\n function depositTo(address account) external payable;\\n\\n /**\\n * add to the account's stake - amount and delay\\n * any pending unstake is first cancelled.\\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\\n */\\n function addStake(uint32 _unstakeDelaySec) external payable;\\n\\n /**\\n * attempt to unlock the stake.\\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\\n */\\n function unlockStake() external;\\n\\n /**\\n * withdraw from the (unlocked) stake.\\n * must first call unlockStake and wait for the unstakeDelay to pass\\n * @param withdrawAddress the address to send withdrawn value.\\n */\\n function withdrawStake(address payable withdrawAddress) external;\\n\\n /**\\n * withdraw from the deposit.\\n * @param withdrawAddress the address to send withdrawn value.\\n * @param withdrawAmount the amount to withdraw.\\n */\\n function withdrawTo(\\n address payable withdrawAddress,\\n uint256 withdrawAmount\\n ) external;\\n}\\n\",\"keccak256\":\"0xadcea606c9b7aafe6645441f2154a60f271330b0eee5292a632aa71c1672d546\",\"license\":\"GPL-3.0-only\"},\"contracts/aa-4337/interfaces/UserOperation.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable no-inline-assembly */\\n\\nimport {calldataKeccak} from \\\"../core/Helpers.sol\\\";\\n\\n/**\\n * User Operation struct\\n * @param sender the sender account of this request.\\n * @param nonce unique value the sender uses to verify it is not a replay.\\n * @param initCode if set, the account contract will be created by this constructor/\\n * @param callData the method call to execute on this account.\\n * @param callGasLimit the gas limit passed to the callData method call.\\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\\n * @param maxFeePerGas same as EIP-1559 gas parameter.\\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\\n */\\nstruct UserOperation {\\n address sender;\\n uint256 nonce;\\n bytes initCode;\\n bytes callData;\\n uint256 callGasLimit;\\n uint256 verificationGasLimit;\\n uint256 preVerificationGas;\\n uint256 maxFeePerGas;\\n uint256 maxPriorityFeePerGas;\\n bytes paymasterAndData;\\n bytes signature;\\n}\\n\\n/**\\n * Utility functions helpful when working with UserOperation structs.\\n */\\nlibrary UserOperationLib {\\n function getSender(\\n UserOperation calldata userOp\\n ) internal pure returns (address) {\\n address data;\\n //read sender from userOp, which is first userOp member (saves 800 gas...)\\n assembly {\\n data := calldataload(userOp)\\n }\\n return address(uint160(data));\\n }\\n\\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\\n // pay above what he signed for.\\n function gasPrice(\\n UserOperation calldata userOp\\n ) internal view returns (uint256) {\\n unchecked {\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n if (maxFeePerGas == maxPriorityFeePerGas) {\\n //legacy mode (for networks that don't support basefee opcode)\\n return maxFeePerGas;\\n }\\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\\n }\\n }\\n\\n function pack(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes memory ret) {\\n address sender = getSender(userOp);\\n uint256 nonce = userOp.nonce;\\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\\n bytes32 hashCallData = calldataKeccak(userOp.callData);\\n uint256 callGasLimit = userOp.callGasLimit;\\n uint256 verificationGasLimit = userOp.verificationGasLimit;\\n uint256 preVerificationGas = userOp.preVerificationGas;\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\\n\\n return\\n abi.encode(\\n sender,\\n nonce,\\n hashInitCode,\\n hashCallData,\\n callGasLimit,\\n verificationGasLimit,\\n preVerificationGas,\\n maxFeePerGas,\\n maxPriorityFeePerGas,\\n hashPaymasterAndData\\n );\\n }\\n\\n function hash(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes32) {\\n return keccak256(pack(userOp));\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n}\\n\",\"keccak256\":\"0x2429f5cc546bdee08c7e63858d0dda8491eaa3ab5194df884dc948c1154d2834\",\"license\":\"GPL-3.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/facets/interfaces/IVerificationFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {UserOperation} from \\\"../../aa-4337/interfaces/UserOperation.sol\\\";\\n\\n/**\\n * @title Verification Facet Interface\\n * @dev Implements logic for user ops signature verification\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\ninterface IVerificationFacet {\\n event SignerInitialized(bytes);\\n event SignerUninitialized();\\n\\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\\n error VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\\n error VerificationFacet__InitializationFailure();\\n error VerificationFacet__InvalidFacetMapping();\\n\\n function initializeSigner(bytes memory) external returns (uint256);\\n\\n function uninitializeSigner() external returns (uint256);\\n\\n function validateOwnerSignatureSelector() external view returns (bytes4);\\n\\n function owner() external view returns (bytes memory);\\n\\n function isValidKeyType(bytes calldata) external view returns (bool);\\n\\n function validateOwnerSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x72bc370a1d1b5a6d6bde67f5026733fd8f6ba434bb90e73b0bd8627fb1579928\",\"license\":\"Apache-2.0\"},\"contracts/facets/verification/secp256r1/Secp256r1VerificationFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {UserOperation} from \\\"../../../aa-4337/interfaces/UserOperation.sol\\\";\\nimport {LibAppStorage} from \\\"../../../libraries/LibAppStorage.sol\\\";\\nimport {LibLoupe} from \\\"../../../libraries/LibLoupe.sol\\\";\\nimport {LibFacetStorage, Secp256r1VerificationStorage} from \\\"../../../libraries/LibFacetStorage.sol\\\";\\nimport {Base64} from \\\"./utils/Base64.sol\\\";\\nimport {LibSecp256r1} from \\\"./utils/LibSecp256r1.sol\\\";\\nimport {IERC1271} from \\\"../../../interfaces/ERC/IERC1271.sol\\\";\\nimport {IVerificationFacet} from \\\"../../interfaces/IVerificationFacet.sol\\\";\\n\\n/**\\n * @title Secp256r1 verification facet\\n * @dev Primarily used to verify user ops signed with passkeys\\n * @author Ruslan Serebriakov (@rsrbk)\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract Secp256r1VerificationFacet is IVerificationFacet, IERC1271 {\\n error Secp256r1VerificationFacet__InvalidSignerLength();\\n address public immutable self;\\n\\n /**\\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\\n */\\n constructor() {\\n LibAppStorage.enforceSignerInitialize();\\n self = address(this);\\n }\\n\\n /**\\n * @notice Initializes the signer in R1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\\n * @param _publicKey Bytes of owner public key\\n * @return initSuccess Uint value representing the success of init operation\\n */\\n function initializeSigner(\\n bytes calldata _publicKey\\n ) public override returns (uint256 initSuccess) {\\n LibAppStorage.enforceSignerInitialize();\\n\\n if (!isValidKeyType(_publicKey))\\n revert Secp256r1VerificationFacet__InvalidSignerLength();\\n\\n bytes memory publicKeyCoordinates = _publicKey[1:];\\n uint256[2] memory q;\\n assembly {\\n // Copy the bytes from the input data into the uint256 array\\n mstore(q, mload(add(publicKeyCoordinates, 32)))\\n mstore(add(q, 32), mload(add(publicKeyCoordinates, 64)))\\n }\\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\\n .r1Storage();\\n r1Storage.q = q;\\n\\n bytes4 validateSelector = validateOwnerSignatureSelector();\\n\\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\\n if (LibLoupe.facetAddress(validateSelector) != self)\\n revert VerificationFacet__InvalidFacetMapping();\\n\\n // initialize verification function selector\\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\\n\\n initSuccess = 1;\\n\\n emit SignerInitialized(_publicKey);\\n }\\n\\n /**\\n * @notice Uninitialize signer in R1 Facet Storage. This can only be called when the account is undergoing signature migration\\n * and has already been initialized.\\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\\n * @return uninitSuccess Uint value representing the success of uninit operation\\n */\\n function uninitializeSigner()\\n external\\n override\\n returns (uint256 uninitSuccess)\\n {\\n LibAppStorage.enforceSignerMigration();\\n LibAppStorage.setSignerUninitialized();\\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\\n .r1Storage();\\n r1Storage.q = [0, 0];\\n\\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\\n\\n uninitSuccess = 1;\\n\\n emit SignerUninitialized();\\n }\\n\\n /**\\n * @notice Validates if the user operation is signed by the owner.\\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\\n * signer public key.\\n * @param userOp UserOperation including all information for execution\\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\\n */\\n function validateOwnerSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) public view override returns (uint256 validationData) {\\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\\n .r1Storage();\\n validationData = validateSignature(userOp, userOpHash, r1Storage.q);\\n }\\n\\n /**\\n * @notice Validates if the signature of UserOperation is signed by the given signer\\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\\n * @param userOp UserOperation including all information for execution\\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\\n * @param q Public Key of signer who signed the contract, to be validated\\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\\n */\\n function validateSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n uint256[2] memory q\\n ) public view returns (uint256 isValid) {\\n isValid = (_validateSignature(q, userOpHash, userOp.signature)) ? 0 : 1;\\n }\\n\\n /**\\n * @notice Returns the selector of function to validate the signature of UserOperation\\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\\n */\\n function validateOwnerSignatureSelector()\\n public\\n pure\\n override\\n returns (bytes4 ownerSignatureValidatorSelector)\\n {\\n return this.validateOwnerSignature.selector; // validateOwnerSignature(UserOperation calldata userOp,bytes32 userOpHash)\\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\\n }\\n\\n /**\\n * @notice Returns the owner of the account\\n * @return signer Bytes of owner address\\n */\\n function owner() public view override returns (bytes memory signer) {\\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\\n .r1Storage();\\n signer = abi.encodePacked(r1Storage.q);\\n }\\n\\n /**\\n * @notice Validates if the format of public key is valid for this verification facet\\n * @dev For this Secp256k1Verification Facet, the public key should in an uncompressed public key format\\n * @param _publicKey Bytes of public key for format check\\n * @return isValid Boolean variable representing if the format of public key is valid\\n */\\n function isValidKeyType(\\n bytes memory _publicKey\\n ) public pure override returns (bool isValid) {\\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\\n }\\n\\n /**\\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\\n * @param _hash Hash value the owner signed\\n * @param _signature Signature that signed the above hash\\n * @return magicValue Bytes4 value representing the success/failure of validation\\n */\\n function isValidSignature(\\n bytes32 _hash,\\n bytes memory _signature\\n ) public view override returns (bytes4 magicValue) {\\n magicValue = _validateSignature(\\n LibFacetStorage.r1Storage().q,\\n _hash,\\n _signature\\n )\\n ? this.isValidSignature.selector\\n : bytes4(0xffffffff);\\n }\\n\\n function _validateSignature(\\n uint256[2] memory q,\\n bytes32 _hash,\\n bytes memory _signature\\n ) internal view returns (bool) {\\n (\\n uint256 rValue,\\n uint256 sValue,\\n bytes memory authenticatorData,\\n string memory clientDataJSONPre,\\n string memory clientDataJSONPost\\n ) = abi.decode(_signature, (uint256, uint256, bytes, string, string));\\n bytes32 clientHash;\\n {\\n string memory opHashBase64 = Base64.encode(bytes.concat(_hash));\\n string memory clientDataJSON = string.concat(\\n clientDataJSONPre,\\n opHashBase64,\\n clientDataJSONPost\\n );\\n clientHash = sha256(bytes(clientDataJSON));\\n }\\n bytes32 sigHash = sha256(bytes.concat(authenticatorData, clientHash));\\n return LibSecp256r1.Verify(q, rValue, sValue, uint256(sigHash));\\n }\\n}\\n\",\"keccak256\":\"0xdb3bae77323eef4e16ef5a5342f548527c9e82b44e8e9dab90906dc2c00082ff\",\"license\":\"Apache-2.0\"},\"contracts/facets/verification/secp256r1/utils/Base64.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @dev Provides a set of functions to operate with Base64 strings.\\n * modified for base64url https://datatracker.ietf.org/doc/html/rfc4648#section-5\\n * _Available since v4.5._\\n */\\nlibrary Base64 {\\n /**\\n * @dev Base64 Encoding/Decoding Table\\n */\\n string internal constant _TABLE =\\n \\\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_\\\";\\n\\n /**\\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\\n */\\n function encode(bytes memory data) internal pure returns (string memory) {\\n /**\\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\\n */\\n if (data.length == 0) return \\\"\\\";\\n\\n // Loads the table into memory\\n string memory table = _TABLE;\\n\\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\\n // and split into 4 numbers of 6 bits.\\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\\n // - `data.length + 2` -> Round up\\n // - `/ 3` -> Number of 3-bytes chunks\\n // - `4 *` -> 4 characters for each chunk\\n uint256 newlength = (data.length * 8) / 6;\\n if (data.length % 6 > 0) {\\n newlength++;\\n }\\n string memory result = new string(newlength);\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n // Prepare the lookup table (skip the first \\\"length\\\" byte)\\n let tablePtr := add(table, 1)\\n\\n // Prepare result pointer, jump over length\\n let resultPtr := add(result, 32)\\n\\n // Run over the input, 3 bytes at a time\\n for {\\n let dataPtr := data\\n let endPtr := add(data, mload(data))\\n } lt(dataPtr, endPtr) {\\n\\n } {\\n // Advance 3 bytes\\n dataPtr := add(dataPtr, 3)\\n let input := mload(dataPtr)\\n\\n // To write each character, shift the 3 bytes (18 bits) chunk\\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\\n // and apply logical AND with 0x3F which is the number of\\n // the previous character in the ASCII table prior to the Base64 Table\\n // The result is then added to the table to get the character to write,\\n // and finally write it in the result pointer but with a left shift\\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\\n\\n mstore8(\\n resultPtr,\\n mload(add(tablePtr, and(shr(18, input), 0x3F)))\\n )\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(\\n resultPtr,\\n mload(add(tablePtr, and(shr(12, input), 0x3F)))\\n )\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(\\n resultPtr,\\n mload(add(tablePtr, and(shr(6, input), 0x3F)))\\n )\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n }\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0xbf0afa21e5a128f260c1a8d4333dc0b0e8755a50d37dfa9b5d362d36ef9cdc14\",\"license\":\"Apache-2.0\"},\"contracts/facets/verification/secp256r1/utils/LibSecp256r1.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n// Heavily inspired from\\n// https://github.com/maxrobot/elliptic-solidity/blob/master/contracts/Secp256r1.sol\\n// https://github.com/tdrerup/elliptic-curve-solidity/blob/master/contracts/curves/EllipticCurve.sol\\n// modified to use precompile 0x05 modexp\\n// and modified jacobian double\\n// optimisations to avoid to an from from affine and jacobian coordinates\\n\\n// Additional Elliptic curve Public key / Signature validation added by\\n// David Yonjun Kim (@Powerstream3604)\\n\\nstruct JPoint {\\n uint256 x;\\n uint256 y;\\n uint256 z;\\n}\\n\\nlibrary LibSecp256r1 {\\n uint256 constant gx =\\n 0x6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296;\\n uint256 constant gy =\\n 0x4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5;\\n uint256 public constant pp =\\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF;\\n\\n uint256 public constant nn =\\n 0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551;\\n uint256 constant a =\\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC;\\n uint256 constant b =\\n 0x5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B;\\n uint256 constant MOST_SIGNIFICANT =\\n 0xc000000000000000000000000000000000000000000000000000000000000000;\\n\\n /*\\n * Verify\\n * @description - verifies that a public key has signed a given message\\n * @param Q - public key coordinates X & Y\\n * @param R - signature half R\\n * @param S - signature half S\\n * @param input - hashed message\\n */\\n function Verify(\\n uint256[2] memory q,\\n uint r,\\n uint s,\\n uint e\\n ) internal view returns (bool) {\\n if (q[0] > pp - 1 || q[1] > pp - 1) {\\n return false;\\n }\\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\\n return false;\\n }\\n if (\\n mulmod(q[1], q[1], pp) !=\\n addmod(\\n addmod(\\n mulmod(q[0], mulmod(q[0], q[0], pp), pp),\\n mulmod(a, q[0], pp),\\n pp\\n ),\\n b,\\n pp\\n )\\n ) {\\n return false;\\n }\\n\\n JPoint[16] memory points = _preComputeJacobianPoints(q);\\n return VerifyWithPrecompute(points, r, s, e);\\n }\\n\\n function VerifyWithPrecompute(\\n JPoint[16] memory points,\\n uint r,\\n uint s,\\n uint e\\n ) internal view returns (bool) {\\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\\n return false;\\n }\\n\\n uint w = _primemod(s, nn);\\n\\n uint u1 = mulmod(e, w, nn);\\n uint u2 = mulmod(r, w, nn);\\n\\n uint x;\\n uint y;\\n\\n (x, y) = ShamirMultJacobian(points, u1, u2);\\n return (x == r);\\n }\\n\\n /*\\n * Strauss Shamir trick for EC multiplication\\n * https://stackoverflow.com/questions/50993471/ec-scalar-multiplication-with-strauss-shamir-method\\n * we optimise on this a bit to do with 2 bits at a time rather than a single bit\\n * the individual points for a single pass are precomputed\\n * overall this reduces the number of additions while keeping the same number of doublings\\n */\\n function ShamirMultJacobian(\\n JPoint[16] memory points,\\n uint u1,\\n uint u2\\n ) internal view returns (uint, uint) {\\n uint x = 0;\\n uint y = 0;\\n uint z = 0;\\n uint bits = 128;\\n uint index = 0;\\n\\n while (bits > 0) {\\n if (z > 0) {\\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\\n }\\n index =\\n ((u1 & MOST_SIGNIFICANT) >> 252) |\\n ((u2 & MOST_SIGNIFICANT) >> 254);\\n if (index > 0) {\\n (x, y, z) = _jAdd(\\n x,\\n y,\\n z,\\n points[index].x,\\n points[index].y,\\n points[index].z\\n );\\n }\\n u1 <<= 2;\\n u2 <<= 2;\\n bits--;\\n }\\n (x, y) = _affineFromJacobian(x, y, z);\\n return (x, y);\\n }\\n\\n function _preComputeJacobianPoints(\\n uint256[2] memory q\\n ) internal pure returns (JPoint[16] memory points) {\\n points[0] = JPoint(0, 0, 0);\\n points[1] = JPoint(q[0], q[1], 1); // u2\\n points[2] = _jPointDouble(points[1]);\\n points[3] = _jPointAdd(points[1], points[2]);\\n\\n points[4] = JPoint(gx, gy, 1); // u1Points[1]\\n points[5] = _jPointAdd(points[4], points[1]);\\n points[6] = _jPointAdd(points[4], points[2]);\\n points[7] = _jPointAdd(points[4], points[3]);\\n\\n points[8] = _jPointDouble(points[4]); // u1Points[2]\\n points[9] = _jPointAdd(points[8], points[1]);\\n points[10] = _jPointAdd(points[8], points[2]);\\n points[11] = _jPointAdd(points[8], points[3]);\\n\\n points[12] = _jPointAdd(points[4], points[8]); // u1Points[3]\\n points[13] = _jPointAdd(points[12], points[1]);\\n points[14] = _jPointAdd(points[12], points[2]);\\n points[15] = _jPointAdd(points[12], points[3]);\\n }\\n\\n function _jPointAdd(\\n JPoint memory p1,\\n JPoint memory p2\\n ) internal pure returns (JPoint memory) {\\n uint x;\\n uint y;\\n uint z;\\n (x, y, z) = _jAdd(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z);\\n return JPoint(x, y, z);\\n }\\n\\n function _jPointDouble(\\n JPoint memory p\\n ) internal pure returns (JPoint memory) {\\n uint x;\\n uint y;\\n uint z;\\n (x, y, z) = _modifiedJacobianDouble(p.x, p.y, p.z);\\n return JPoint(x, y, z);\\n }\\n\\n /* _affineFromJacobian\\n * @desription returns affine coordinates from a jacobian input follows\\n * golang elliptic/crypto library\\n */\\n function _affineFromJacobian(\\n uint x,\\n uint y,\\n uint z\\n ) internal view returns (uint ax, uint ay) {\\n if (z == 0) {\\n return (0, 0);\\n }\\n\\n uint zinv = _primemod(z, pp);\\n uint zinvsq = mulmod(zinv, zinv, pp);\\n\\n ax = mulmod(x, zinvsq, pp);\\n ay = mulmod(y, mulmod(zinvsq, zinv, pp), pp);\\n }\\n\\n /*\\n * _jAdd\\n * @description performs Jacobian addition as defined below:\\n * http://www.hyperelliptic.org/EFD/g1p/data/shortw/jacobian/addition/add-2007-bl\\n */\\n function _jAdd(\\n uint p1,\\n uint p2,\\n uint p3,\\n uint q1,\\n uint q2,\\n uint q3\\n ) internal pure returns (uint r1, uint r2, uint r3) {\\n if (p3 == 0) {\\n r1 = q1;\\n r2 = q2;\\n r3 = q3;\\n\\n return (r1, r2, r3);\\n } else if (q3 == 0) {\\n r1 = p1;\\n r2 = p2;\\n r3 = p3;\\n\\n return (r1, r2, r3);\\n }\\n\\n assembly {\\n let\\n pd\\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\\n let z1z1 := mulmod(p3, p3, pd) // Z1Z1 = Z1^2\\n let z2z2 := mulmod(q3, q3, pd) // Z2Z2 = Z2^2\\n\\n let u1 := mulmod(p1, z2z2, pd) // U1 = X1*Z2Z2\\n let u2 := mulmod(q1, z1z1, pd) // U2 = X2*Z1Z1\\n\\n let s1 := mulmod(p2, mulmod(z2z2, q3, pd), pd) // S1 = Y1*Z2*Z2Z2\\n let s2 := mulmod(q2, mulmod(z1z1, p3, pd), pd) // S2 = Y2*Z1*Z1Z1\\n\\n let p3q3 := addmod(p3, q3, pd)\\n\\n if lt(u2, u1) {\\n u2 := add(pd, u2) // u2 = u2+pd\\n }\\n let h := sub(u2, u1) // H = U2-U1\\n\\n let i := mulmod(0x02, h, pd)\\n i := mulmod(i, i, pd) // I = (2*H)^2\\n\\n let j := mulmod(h, i, pd) // J = H*I\\n if lt(s2, s1) {\\n s2 := add(pd, s2) // u2 = u2+pd\\n }\\n let rr := mulmod(0x02, sub(s2, s1), pd) // r = 2*(S2-S1)\\n r1 := mulmod(rr, rr, pd) // X3 = R^2\\n\\n let v := mulmod(u1, i, pd) // V = U1*I\\n let j2v := addmod(j, mulmod(0x02, v, pd), pd)\\n if lt(r1, j2v) {\\n r1 := add(pd, r1) // X3 = X3+pd\\n }\\n r1 := sub(r1, j2v)\\n\\n // Y3 = r*(V-X3)-2*S1*J\\n let s12j := mulmod(mulmod(0x02, s1, pd), j, pd)\\n\\n if lt(v, r1) {\\n v := add(pd, v)\\n }\\n r2 := mulmod(rr, sub(v, r1), pd)\\n\\n if lt(r2, s12j) {\\n r2 := add(pd, r2)\\n }\\n r2 := sub(r2, s12j)\\n\\n // Z3 = ((Z1+Z2)^2-Z1Z1-Z2Z2)*H\\n z1z1 := addmod(z1z1, z2z2, pd)\\n j2v := mulmod(p3q3, p3q3, pd)\\n if lt(j2v, z1z1) {\\n j2v := add(pd, j2v)\\n }\\n r3 := mulmod(sub(j2v, z1z1), h, pd)\\n }\\n return (r1, r2, r3);\\n }\\n\\n // Point doubling on the modified jacobian coordinates\\n // http://point-at-infinity.org/ecc/Prime_Curve_Modified_Jacobian_Coordinates.html\\n function _modifiedJacobianDouble(\\n uint x,\\n uint y,\\n uint z\\n ) internal pure returns (uint x3, uint y3, uint z3) {\\n if (y == 0) return (0, 0, 0);\\n assembly {\\n let\\n pd\\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\\n let z2 := mulmod(z, z, pd)\\n let az4 := mulmod(\\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC,\\n mulmod(z2, z2, pd),\\n pd\\n )\\n let y2 := mulmod(y, y, pd)\\n let s := mulmod(0x04, mulmod(x, y2, pd), pd)\\n let u := mulmod(0x08, mulmod(y2, y2, pd), pd)\\n let m := addmod(mulmod(0x03, mulmod(x, x, pd), pd), az4, pd)\\n let twos := mulmod(0x02, s, pd)\\n let m2 := mulmod(m, m, pd)\\n if lt(m2, twos) {\\n m2 := add(pd, m2)\\n }\\n x3 := sub(m2, twos)\\n if lt(s, x3) {\\n s := add(pd, s)\\n }\\n y3 := mulmod(m, sub(s, x3), pd)\\n if lt(y3, u) {\\n y3 := add(pd, y3)\\n }\\n y3 := sub(y3, u)\\n z3 := mulmod(0x02, mulmod(y, z, pd), pd)\\n }\\n }\\n\\n // Fermats little theorem https://en.wikipedia.org/wiki/Fermat%27s_little_theorem\\n // a^(p-1) = 1 mod p\\n // a^(-1) \\u2245 a^(p-2) (mod p)\\n // we then use the precompile bigModExp to compute a^(-1)\\n function _primemod(uint value, uint p) internal view returns (uint ret) {\\n ret = modexp(value, p - 2, p);\\n return ret;\\n }\\n\\n // Wrapper for built-in BigNumber_modexp (contract 0x5) as described here. https://github.com/ethereum/EIPs/pull/198\\n function modexp(\\n uint _base,\\n uint _exp,\\n uint _mod\\n ) internal view returns (uint ret) {\\n // bigModExp(_base, _exp, _mod);\\n assembly {\\n if gt(_base, _mod) {\\n _base := mod(_base, _mod)\\n }\\n // Free memory pointer is always stored at 0x40\\n let freemem := mload(0x40)\\n\\n mstore(freemem, 0x20)\\n mstore(add(freemem, 0x20), 0x20)\\n mstore(add(freemem, 0x40), 0x20)\\n\\n mstore(add(freemem, 0x60), _base)\\n mstore(add(freemem, 0x80), _exp)\\n mstore(add(freemem, 0xa0), _mod)\\n\\n let success := staticcall(14000, 0x5, freemem, 0xc0, freemem, 0x20)\\n switch success\\n case 0 {\\n revert(0x0, 0x0)\\n }\\n default {\\n ret := mload(freemem)\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb53714ba63cddb379ba312c1e7f6a423f4d7a7e34fa1364ec8295cd57d544024\",\"license\":\"GPL-3.0\"},\"contracts/infrastructure/interfaces/IFacetRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Registry Interface\\n * @dev Interface for Facet Registry contract to keep track of facets & function selectors addable to user wallets\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IFacetRegistry {\\n struct FacetRegistryConfig {\\n bytes4[] selectors;\\n mapping(bytes4 => FacetInfo) info;\\n }\\n struct FacetInfo {\\n bool exists;\\n uint128 index;\\n }\\n\\n event FacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] facetSelectors\\n );\\n event FacetFunctionSelectorsRemoved(address facet, bytes4[] facetSelectors);\\n\\n error FacetRegistry__FacetSelectorAlreadyRegistered();\\n error FacetRegistry__UnregisteredFacetSelector();\\n\\n function registerFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function removeFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function areFacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external view returns (bool);\\n\\n function isFacetFunctionSelectorRegistered(\\n address facet,\\n bytes4 facetSelector\\n ) external view returns (bool);\\n\\n function getFacetFunctionSelectors(\\n address facet\\n ) external view returns (bytes4[] memory);\\n}\\n\",\"keccak256\":\"0x6e6dd2cab346ef7c31230740ec48d2925e4a9ab24c2f2fb268baaf408dcf02ef\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC1271 {\\n function isValidSignature(\\n bytes32 hash,\\n bytes memory signature\\n ) external view returns (bytes4);\\n}\\n\",\"keccak256\":\"0xcdddb7d5641c9d3f2432dec7fd13fddb9ae1480f25c76c21511e2fa16b8bd422\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibAppStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {SafeCast} from \\\"@openzeppelin/contracts/utils/math/SafeCast.sol\\\";\\nimport {IEntryPoint} from \\\"../aa-4337/interfaces/IEntryPoint.sol\\\";\\nimport {IFacetRegistry} from \\\"../infrastructure/interfaces/IFacetRegistry.sol\\\";\\n\\n/*\\n * @title App Storage\\n * @dev App storage for Barz contract to prevent storage collision\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Lock {\\n uint64 release;\\n bytes4 locker;\\n}\\n\\nstruct InitializersStorage {\\n // NOTE: initialized is a variable to make sure the initialization is only done once.\\n uint8 signerInitialized;\\n uint8 accountInitialized;\\n uint8 restrictionsInitialized;\\n}\\n\\nstruct AppStorage {\\n mapping(uint256 => InitializersStorage) initStorage;\\n uint8 signerMigration;\\n bytes4 validateOwnerSignatureSelector;\\n IEntryPoint entryPoint;\\n IFacetRegistry facetRegistry;\\n mapping(uint256 => Lock) locks;\\n}\\n\\nlibrary LibAppStorage {\\n error LibAppStorage__AccountAlreadyUninitialized();\\n error LibAppStorage__AccountMustBeUninitialized();\\n error LibAppStorage__SignerAlreadyUninitialized();\\n error LibAppStorage__SignerMustBeUninitialized();\\n\\n function appStorage() internal pure returns (AppStorage storage ds) {\\n assembly {\\n ds.slot := 0\\n }\\n }\\n\\n function setSignerUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerAlreadyUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 0;\\n }\\n\\n function getValidateOwnerSignatureSelector()\\n internal\\n view\\n returns (bytes4 selector)\\n {\\n selector = appStorage().validateOwnerSignatureSelector;\\n }\\n\\n function setValidateOwnerSignatureSelector(\\n bytes4 _validateOwnerSignatureSelector\\n ) internal {\\n appStorage()\\n .validateOwnerSignatureSelector = _validateOwnerSignatureSelector;\\n }\\n\\n function enforceSignerInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerMustBeUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 1;\\n }\\n\\n function enforceAccountInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].accountInitialized) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n s.initStorage[0].accountInitialized = 1;\\n }\\n\\n function initiateSignerMigration() internal {\\n appStorage().signerMigration = 1;\\n }\\n\\n function enforceSignerMigration() internal view {\\n if (1 != appStorage().signerMigration) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n }\\n\\n function finalizeSignerMigration() internal {\\n appStorage().signerMigration = 0;\\n }\\n\\n function setLock(uint256 _releaseAfter, bytes4 _locker) internal {\\n appStorage().locks[0] = Lock(SafeCast.toUint64(_releaseAfter), _locker);\\n }\\n\\n function enforceRestrictionsInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__SignerMustBeUninitialized();\\n s.initStorage[0].restrictionsInitialized = 1;\\n }\\n\\n function setRestrictionsUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__AccountAlreadyUninitialized();\\n s.initStorage[0].restrictionsInitialized = 0;\\n }\\n}\\n\\ncontract BarzStorage {\\n AppStorage internal s;\\n modifier onlyWhenUnlocked() {\\n require(\\n uint64(block.timestamp) >= s.locks[0].release,\\n \\\"Account Locked\\\"\\n );\\n _;\\n }\\n modifier onlyWhenLocked() {\\n require(\\n uint64(block.timestamp) < s.locks[0].release,\\n \\\"Account Unlocked\\\"\\n );\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x48524007862a6ce0e07f645950613ce6513ce073c37a109c75019683d42bae27\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\\n bytes4(keccak256(\\\"verifyRestrictions(address,address,uint256,bytes)\\\"));\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // Default Fallback Handler of the barz.\\n IDiamondLoupe defaultFallbackHandler;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function enforceIsSelf() internal view {\\n require(msg.sender == address(this), \\\"LibDiamond: Caller not self\\\");\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n\\n unchecked {\\n facetIndex++;\\n }\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n\\n function restrictionsFacet() internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(\\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2cabdc00de859c3a3170ce3bda5d0e5fd3933d47ce904fd1585f9818b02572f8\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibFacetStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Storage\\n * @dev Storage contract to store each facets variables with diamond storage\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Secp256k1VerificationStorage {\\n address signer;\\n}\\n\\nstruct Secp256r1VerificationStorage {\\n uint256[2] q;\\n}\\n\\nstruct GuardianStorage {\\n mapping(bytes32 => uint256) pending;\\n mapping(uint8 => StorageConfig) configs;\\n}\\n\\nstruct Info {\\n bool exists;\\n uint128 index;\\n}\\n\\nstruct StorageConfig {\\n address[] addresses;\\n mapping(address => Info) info;\\n}\\n\\nstruct RecoveryConfig {\\n bytes recoveryPublicKey;\\n uint64 executeAfter;\\n}\\n\\nstruct ApprovalConfig {\\n bool isApproved;\\n uint64 validUntil;\\n}\\n\\nstruct RecoveryApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isNewOwnerApproved;\\n}\\n\\nstruct RecoveryStorage {\\n mapping(uint8 => RecoveryConfig) recoveryConfigs;\\n mapping(uint8 => RecoveryApprovalConfig) recoveryApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct RestrictionsStorage {\\n address[] restrictions;\\n mapping(address => bool) exists;\\n}\\n\\nstruct SignatureMigrationConfig {\\n bytes migrationPublicKey;\\n address migrationVerificationFacet;\\n bytes4[] migrationSelectors;\\n uint64 migrateAfter;\\n}\\n\\nstruct SignatureMigrationApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isMigrationApproved;\\n}\\n\\nstruct SignatureMigrationStorage {\\n mapping(uint8 => SignatureMigrationConfig) migrationConfigs;\\n mapping(uint8 => SignatureMigrationApprovalConfig) migrationApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct DiamondCutApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isDiamondCutApproved;\\n}\\n\\nstruct DiamondCutStorage {\\n mapping(uint8 => DiamondCutApprovalConfig) diamondCutApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct LockStorage {\\n uint128 nonce;\\n}\\n\\nlibrary LibFacetStorage {\\n bytes32 constant K1_STORAGE_POSITION =\\n keccak256(\\n \\\"v0.trustwallet.diamond.storage.Secp256k1VerificationStorage\\\"\\n );\\n bytes32 constant R1_STORAGE_POSITION =\\n keccak256(\\n \\\"v0.trustwallet.diamond.storage.Secp256r1VerificationStorage\\\"\\n );\\n bytes32 constant GUARDIAN_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.GuardianStorage\\\");\\n bytes32 constant RECOVERY_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.RecoveryStorage\\\");\\n bytes32 constant RESTRICTION_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.RestrictionsStorage\\\");\\n bytes32 constant MIGRATION_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.SignatureMigrationStorage\\\");\\n bytes32 constant DIAMONDCUT_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.DiamondCutStorage\\\");\\n bytes32 constant LOCK_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.LockStorage\\\");\\n\\n function k1Storage()\\n internal\\n pure\\n returns (Secp256k1VerificationStorage storage ds)\\n {\\n bytes32 storagePosition = K1_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function r1Storage()\\n internal\\n pure\\n returns (Secp256r1VerificationStorage storage ds)\\n {\\n bytes32 storagePosition = R1_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function guardianStorage()\\n internal\\n pure\\n returns (GuardianStorage storage ds)\\n {\\n bytes32 storagePosition = GUARDIAN_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function recoveryStorage()\\n internal\\n pure\\n returns (RecoveryStorage storage ds)\\n {\\n bytes32 storagePosition = RECOVERY_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function restrictionsStorage()\\n internal\\n pure\\n returns (RestrictionsStorage storage ds)\\n {\\n bytes32 storagePosition = RESTRICTION_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function migrationStorage()\\n internal\\n pure\\n returns (SignatureMigrationStorage storage ds)\\n {\\n bytes32 storagePosition = MIGRATION_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function diamondCutStorage()\\n internal\\n pure\\n returns (DiamondCutStorage storage ds)\\n {\\n bytes32 storagePosition = DIAMONDCUT_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function lockStorage() internal pure returns (LockStorage storage ds) {\\n bytes32 storagePosition = LOCK_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n}\\n\",\"keccak256\":\"0x87c85decfd943deda9540733e464cb1a92eba735a301e89ce6f798016e359761\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\nimport {LibDiamond} from \\\"./LibDiamond.sol\\\";\\n\\n/**\\n * @title LibLoupe\\n * @dev Internal Library to provide utility feature for reading the state of diamond facets\\n * Originally from Diamond's implementation of Mudgen(author of EIP-2535)\\n */\\nlibrary LibLoupe {\\n /// @notice Gets all facets and their selectors.\\n /// @return facets_ Facet\\n function facets()\\n internal\\n view\\n returns (IDiamondLoupe.Facet[] memory facets_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facets_ = new IDiamondLoupe.Facet[](ds.selectorCount);\\n uint16[] memory numFacetSelectors = new uint16[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facets_[facetIndex].facetAddress == facetAddress_) {\\n facets_[facetIndex].functionSelectors[\\n numFacetSelectors[facetIndex]\\n ] = selector;\\n // probably will never have more than 256 functions from one facet contract\\n require(numFacetSelectors[facetIndex] < 255);\\n numFacetSelectors[facetIndex]++;\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facets_[numFacets].facetAddress = facetAddress_;\\n facets_[numFacets].functionSelectors = new bytes4[](\\n ds.selectorCount\\n );\\n facets_[numFacets].functionSelectors[0] = selector;\\n numFacetSelectors[numFacets] = 1;\\n numFacets++;\\n }\\n }\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n uint256 numSelectors = numFacetSelectors[facetIndex];\\n bytes4[] memory selectors = facets_[facetIndex].functionSelectors;\\n // setting the number of selectors\\n assembly {\\n mstore(selectors, numSelectors)\\n }\\n }\\n // setting the number of facets\\n assembly {\\n mstore(facets_, numFacets)\\n }\\n }\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return _facetFunctionSelectors The selectors associated with a facet address.\\n function facetFunctionSelectors(\\n address _facet\\n ) internal view returns (bytes4[] memory _facetFunctionSelectors) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n uint256 numSelectors;\\n _facetFunctionSelectors = new bytes4[](ds.selectorCount);\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facet = address(bytes20(ds.facets[selector]));\\n if (_facet == facet) {\\n _facetFunctionSelectors[numSelectors] = selector;\\n numSelectors++;\\n }\\n }\\n }\\n // Set the number of selectors in the array\\n assembly {\\n mstore(_facetFunctionSelectors, numSelectors)\\n }\\n }\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n internal\\n view\\n returns (address[] memory facetAddresses_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetAddresses_ = new address[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facetAddress_ == facetAddresses_[facetIndex]) {\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facetAddresses_[numFacets] = facetAddress_;\\n numFacets++;\\n }\\n }\\n // Set the number of facet addresses in the array\\n assembly {\\n mstore(facetAddresses_, numFacets)\\n }\\n }\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(LibDiamond.diamondStorage().facets[_functionSelector])\\n );\\n }\\n}\\n\",\"keccak256\":\"0x0b11439c3cc657095e15ec2241fdcf67204b14001357b612fc5db4ff9e760a5a\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x60a060405234801561001057600080fd5b50610019610022565b3060805261008b565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff161561006f57604051637c2cde8b60e01b815260040160405180910390fd5b600080805260209190915260409020805460ff19166001179055565b608051611f746100ad6000396000818161016001526106e10152611f746000f3fe608060405234801561001057600080fd5b50600436106100a35760003560e01c80637104ddb2116100765780638dd501211161005b5780638dd50121146101bc578063cd00e50a146101cf578063cd9b47e4146101d757600080fd5b80637104ddb21461015b5780638da5cb5b146101a757600080fd5b806311cfe388146100a85780631626ba7e146100ce5780633253960f14610112578063392dd6d914610138575b600080fd5b6100bb6100b6366004611823565b6101ea565b6040519081526020015b60405180910390f35b6100e16100dc366004611956565b610252565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020016100c5565b7f8dd50121000000000000000000000000000000000000000000000000000000006100e1565b61014b61014636600461199d565b6102fd565b60405190151581526020016100c5565b6101827f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100c5565b6101af61036f565b6040516100c591906119f6565b6100bb6101ca366004611a47565b6103ba565b6100bb61041f565b6100bb6101e5366004611a8c565b61053a565b600061023982846101ff610140880188611afe565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061083692505050565b610244576001610247565b60005b60ff16949350505050565b60006102aa7f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b1653646040805180820191829052919060029082845b81548152602001906001019080831161028b5750505050508484610836565b6102d4577fffffffff000000000000000000000000000000000000000000000000000000006102f6565b7f1626ba7e000000000000000000000000000000000000000000000000000000005b9392505050565b60008151604114801561036957508160008151811061031e5761031e611b6a565b6020910101517fff00000000000000000000000000000000000000000000000000000000000000167f0400000000000000000000000000000000000000000000000000000000000000145b92915050565b6040516060907f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364906103a5908290602001611b99565b60405160208183030381529060405291505090565b60408051808201918290526000917f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364916104179186918691859060029082845b8154815260200190600101908083116103fa5750505050506101ea565b949350505050565b60006104296109b4565b6104316109f4565b60408051808201909152600080825260208201527f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364906104749082906002611675565b506000610488600154610100900460e01b90565b7fffffffff0000000000000000000000000000000000000000000000000000000016036104e1576040517f127c609a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff169055604051600192507fcccd30db6bc000b8bb8d11162228d2d69e3c361983ca3ae8c1365ce64b0fae9e90600090a15090565b6000610544610a93565b61058383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102fd92505050565b6105b9576040517f6c334d2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006105c88360018187611bcd565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092935061060992506116b8915050565b602082015181526040820151602082015260006106437f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b16536490565b9050610651818360026116d6565b507f8dd50121000000000000000000000000000000000000000000000000000000006000610686600154610100900460e01b90565b7fffffffff0000000000000000000000000000000000000000000000000000000016146106df576040517f5f95a63c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16610770827fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604090205460601c90565b73ffffffffffffffffffffffffffffffffffffffff16146107bd576040517fbb4752b700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff1661010060e084901c02179055600194507f6d54821a69ec281ed7ba1bf2729c700768c47df1d80fad646b0a14cc1d5c39ed8787604051610824929190611bf7565b60405180910390a15050505092915050565b600080600080600080868060200190518101906108539190611c94565b9450945094509450945060008061088a8a60405160200161087691815260200190565b604051602081830303815290604052610b33565b905060008482856040516020016108a393929190611d47565b60405160208183030381529060405290506002816040516108c49190611d8a565b602060405180830381855afa1580156108e1573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906109049190611da6565b9250505060006002858360405160200161091f929190611dbf565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905261095791611d8a565b602060405180830381855afa158015610974573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906109979190611da6565b90506109a58b888884610c6f565b9b9a5050505050505050505050565b6001805460ff16146109f2576040517f38fc28cb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff16600114610a5c576040517fe00d7c7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff1615610af9576040517f7c2cde8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b60608151600003610b5257505060408051602081019091526000815290565b6000604051806060016040528060408152602001611eff6040913990506000600684516008610b819190611e10565b610b8b9190611e56565b9050600060068551610b9d9190611e6a565b1115610bb15780610bad81611e7e565b9150505b60008167ffffffffffffffff811115610bcc57610bcc61177c565b6040519080825280601f01601f191660200182016040528015610bf6576020820181803683370190505b509050600183016020820186875188015b80821015610c62576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f8116850151845350600183019250610c07565b5092979650505050505050565b6000610c9c60017fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611eb6565b85511180610cd75750610cd060017fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611eb6565b6020860151115b15610ce457506000610417565b831580610cef575082155b80610d1a57507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518410155b80610d4557507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518310155b15610d5257506000610417565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff7f5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff8088600060200201517fffffffff00000001000000000000000000000000fffffffffffffffffffffffc0988517fffffffff00000001000000000000000000000000ffffffffffffffffffffffff90819080098a5109080860208601517fffffffff00000001000000000000000000000000ffffffffffffffffffffffff90800914610e4357506000610417565b6000610e4e86610e66565b9050610e5c81868686611062565b9695505050505050565b610e6e611704565b60405180606001604052806000815260200160008152602001600081525081600060108110610e9f57610e9f611b6a565b60200201526040805160608101909152808360006020020151815260200183600160028110610ed057610ed0611b6a565b60200201518152602001600181525081600160108110610ef257610ef2611b6a565b6020020152610f088160015b602002015161116f565b6040820152610f278160015b60200201518260025b60200201516111d1565b6060828101919091526040805191820181527f6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c29682527f4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f560208301526001908201526080820152610fa18160045b6020020151826001610f1d565b60a0820152610fb1816004610f14565b60c0820152610fca8160045b6020020151826003610f1d565b60e0820152610fda816004610efe565b610100820152610feb816008610f94565b610120820152610ffc816008610f14565b61014082015261100d816008610fbd565b610160820152608081015161102490826008610f1d565b61018082015261103581600c610f94565b6101a082015261104681600c610f14565b6101c082015261105781600c610fbd565b6101e0820152919050565b600083158061106f575082155b8061109a57507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518410155b806110c557507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518310155b156110d257506000610417565b60006110fe847fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551611243565b905060007fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551828509905060007fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551838809905060008061115e8a858561125a565b509098149998505050505050505050565b61119360405180606001604052806000815260200160008152602001600081525090565b60008060006111af856000015186602001518760400151611346565b6040805160608101825293845260208401929092529082015295945050505050565b6111f560405180606001604052806000815260200160008152602001600081525090565b6000806000611220866000015187602001518860400151886000015189602001518a60400151611424565b604080516060810182529384526020840192909252908201529695505050505050565b60006102f683611254600285611eb6565b8461155c565b6000808080806080815b81156113285782156112955761127b858585611346565b9196509450925061128d858585611346565b919650945092505b50600c60fc89901c1660fe88901c17801561130b576113038585858d85601081106112c2576112c2611b6a565b6020020151518e86601081106112da576112da611b6a565b6020020151602001518f87601081106112f5576112f5611b6a565b602002015160400151611424565b919650945092505b600298891b989790971b968161132081611ec9565b925050611264565b6113338585856115b0565b909750955050505050505b935093915050565b6000806000846000036113615750600091508190508061141b565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff8085860981828283097fffffffff00000001000000000000000000000000fffffffffffffffffffffffc099050818788098283828b0960040983848384096008099150838385868d8e09600309089250838160020984848509818110156113e65785015b039650868110156113f45783015b8387820384099550508085101561140a57938201935b909303925080808688096002099150505b93509350939050565b60008060008660000361143e575084915083905082611550565b83600003611453575087915086905085611550565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff808889098186870982818d0983838b0984858a85098e0985868e87098c09868b8f08848410156114a357928701925b8484039350878460020988818209905088818609848410156114c457928901925b898585036002099350898485099c50898288099650898a8860020982089150818d10156114f0579b89019b5b818d039c5089818b87600209099450508b86101561150d57948801945b888c870384099a50838b101561152257998801995b838b039a508887890897508882830990508781101561153e5788015b88858983030999505050505050505050505b96509650969350505050565b60008184111561156c5781840693505b60405160208152602080820152602060408201528460608201528360808201528260a082015260208160c08360056136b0fa8080156100a357505051949350505050565b600080826000036115c65750600090508061133e565b60006115f2847fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611243565b905060007fffffffff00000001000000000000000000000000ffffffffffffffffffffffff82830990507fffffffff00000001000000000000000000000000ffffffffffffffffffffffff81880993507fffffffff00000001000000000000000000000000ffffffffffffffffffffffff80838309870992505050935093915050565b82600281019282156116a8579160200282015b828111156116a8578251829060ff16905591602001919060010190611688565b506116b492915061174e565b5090565b60405180604001604052806002906020820280368337509192915050565b82600281019282156116a8579160200282015b828111156116a85782518255916020019190600101906116e9565b6040518061020001604052806010905b61173860405180606001604052806000815260200160008152602001600081525090565b8152602001906001900390816117145790505090565b5b808211156116b4576000815560010161174f565b6000610160828403121561177657600080fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156117ce576117ce61177c565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561181b5761181b61177c565b604052919050565b60008060006080848603121561183857600080fd5b833567ffffffffffffffff81111561184f57600080fd5b61185b86828701611763565b935050602080850135925085605f86011261187557600080fd5b61187d6117ab565b80608087018881111561188f57600080fd5b604088015b818110156118ab5780358452928401928401611894565b50508093505050509250925092565b600067ffffffffffffffff8211156118d4576118d461177c565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261191157600080fd5b813561192461191f826118ba565b6117d4565b81815284602083860101111561193957600080fd5b816020850160208301376000918101602001919091529392505050565b6000806040838503121561196957600080fd5b82359150602083013567ffffffffffffffff81111561198757600080fd5b61199385828601611900565b9150509250929050565b6000602082840312156119af57600080fd5b813567ffffffffffffffff8111156119c657600080fd5b61041784828501611900565b60005b838110156119ed5781810151838201526020016119d5565b50506000910152565b6020815260008251806020840152611a158160408501602087016119d2565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b60008060408385031215611a5a57600080fd5b823567ffffffffffffffff811115611a7157600080fd5b611a7d85828601611763565b95602094909401359450505050565b60008060208385031215611a9f57600080fd5b823567ffffffffffffffff80821115611ab757600080fd5b818501915085601f830112611acb57600080fd5b813581811115611ada57600080fd5b866020828501011115611aec57600080fd5b60209290920196919550909350505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112611b3357600080fd5b83018035915067ffffffffffffffff821115611b4e57600080fd5b602001915036819003821315611b6357600080fd5b9250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008183825b6002811015611bbe578154835260209092019160019182019101611b9f565b50505060408201905092915050565b60008085851115611bdd57600080fd5b83861115611bea57600080fd5b5050820193919092039150565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b6000611c5261191f846118ba565b9050828152838383011115611c6657600080fd5b6102f68360208301846119d2565b600082601f830112611c8557600080fd5b6102f683835160208501611c44565b600080600080600060a08688031215611cac57600080fd5b8551945060208601519350604086015167ffffffffffffffff80821115611cd257600080fd5b818801915088601f830112611ce657600080fd5b611cf589835160208501611c44565b94506060880151915080821115611d0b57600080fd5b611d1789838a01611c74565b93506080880151915080821115611d2d57600080fd5b50611d3a88828901611c74565b9150509295509295909350565b60008451611d598184602089016119d2565b845190830190611d6d8183602089016119d2565b8451910190611d808183602088016119d2565b0195945050505050565b60008251611d9c8184602087016119d2565b9190910192915050565b600060208284031215611db857600080fd5b5051919050565b60008351611dd18184602088016119d2565b9190910191825250602001919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808202811582820484141761036957610369611de1565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082611e6557611e65611e27565b500490565b600082611e7957611e79611e27565b500690565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611eaf57611eaf611de1565b5060010190565b8181038181111561036957610369611de1565b600081611ed857611ed8611de1565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392d5fa2646970667358221220d4142da7b16effb6b95f41adeff2bc8ce0d59d3b70ca8d55e6e83224bbfbec0a64736f6c63430008150033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100a35760003560e01c80637104ddb2116100765780638dd501211161005b5780638dd50121146101bc578063cd00e50a146101cf578063cd9b47e4146101d757600080fd5b80637104ddb21461015b5780638da5cb5b146101a757600080fd5b806311cfe388146100a85780631626ba7e146100ce5780633253960f14610112578063392dd6d914610138575b600080fd5b6100bb6100b6366004611823565b6101ea565b6040519081526020015b60405180910390f35b6100e16100dc366004611956565b610252565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020016100c5565b7f8dd50121000000000000000000000000000000000000000000000000000000006100e1565b61014b61014636600461199d565b6102fd565b60405190151581526020016100c5565b6101827f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100c5565b6101af61036f565b6040516100c591906119f6565b6100bb6101ca366004611a47565b6103ba565b6100bb61041f565b6100bb6101e5366004611a8c565b61053a565b600061023982846101ff610140880188611afe565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061083692505050565b610244576001610247565b60005b60ff16949350505050565b60006102aa7f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b1653646040805180820191829052919060029082845b81548152602001906001019080831161028b5750505050508484610836565b6102d4577fffffffff000000000000000000000000000000000000000000000000000000006102f6565b7f1626ba7e000000000000000000000000000000000000000000000000000000005b9392505050565b60008151604114801561036957508160008151811061031e5761031e611b6a565b6020910101517fff00000000000000000000000000000000000000000000000000000000000000167f0400000000000000000000000000000000000000000000000000000000000000145b92915050565b6040516060907f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364906103a5908290602001611b99565b60405160208183030381529060405291505090565b60408051808201918290526000917f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364916104179186918691859060029082845b8154815260200190600101908083116103fa5750505050506101ea565b949350505050565b60006104296109b4565b6104316109f4565b60408051808201909152600080825260208201527f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364906104749082906002611675565b506000610488600154610100900460e01b90565b7fffffffff0000000000000000000000000000000000000000000000000000000016036104e1576040517f127c609a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff169055604051600192507fcccd30db6bc000b8bb8d11162228d2d69e3c361983ca3ae8c1365ce64b0fae9e90600090a15090565b6000610544610a93565b61058383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102fd92505050565b6105b9576040517f6c334d2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006105c88360018187611bcd565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092935061060992506116b8915050565b602082015181526040820151602082015260006106437f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b16536490565b9050610651818360026116d6565b507f8dd50121000000000000000000000000000000000000000000000000000000006000610686600154610100900460e01b90565b7fffffffff0000000000000000000000000000000000000000000000000000000016146106df576040517f5f95a63c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16610770827fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604090205460601c90565b73ffffffffffffffffffffffffffffffffffffffff16146107bd576040517fbb4752b700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff1661010060e084901c02179055600194507f6d54821a69ec281ed7ba1bf2729c700768c47df1d80fad646b0a14cc1d5c39ed8787604051610824929190611bf7565b60405180910390a15050505092915050565b600080600080600080868060200190518101906108539190611c94565b9450945094509450945060008061088a8a60405160200161087691815260200190565b604051602081830303815290604052610b33565b905060008482856040516020016108a393929190611d47565b60405160208183030381529060405290506002816040516108c49190611d8a565b602060405180830381855afa1580156108e1573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906109049190611da6565b9250505060006002858360405160200161091f929190611dbf565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905261095791611d8a565b602060405180830381855afa158015610974573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906109979190611da6565b90506109a58b888884610c6f565b9b9a5050505050505050505050565b6001805460ff16146109f2576040517f38fc28cb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff16600114610a5c576040517fe00d7c7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff1615610af9576040517f7c2cde8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b60608151600003610b5257505060408051602081019091526000815290565b6000604051806060016040528060408152602001611eff6040913990506000600684516008610b819190611e10565b610b8b9190611e56565b9050600060068551610b9d9190611e6a565b1115610bb15780610bad81611e7e565b9150505b60008167ffffffffffffffff811115610bcc57610bcc61177c565b6040519080825280601f01601f191660200182016040528015610bf6576020820181803683370190505b509050600183016020820186875188015b80821015610c62576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f8116850151845350600183019250610c07565b5092979650505050505050565b6000610c9c60017fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611eb6565b85511180610cd75750610cd060017fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611eb6565b6020860151115b15610ce457506000610417565b831580610cef575082155b80610d1a57507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518410155b80610d4557507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518310155b15610d5257506000610417565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff7f5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff8088600060200201517fffffffff00000001000000000000000000000000fffffffffffffffffffffffc0988517fffffffff00000001000000000000000000000000ffffffffffffffffffffffff90819080098a5109080860208601517fffffffff00000001000000000000000000000000ffffffffffffffffffffffff90800914610e4357506000610417565b6000610e4e86610e66565b9050610e5c81868686611062565b9695505050505050565b610e6e611704565b60405180606001604052806000815260200160008152602001600081525081600060108110610e9f57610e9f611b6a565b60200201526040805160608101909152808360006020020151815260200183600160028110610ed057610ed0611b6a565b60200201518152602001600181525081600160108110610ef257610ef2611b6a565b6020020152610f088160015b602002015161116f565b6040820152610f278160015b60200201518260025b60200201516111d1565b6060828101919091526040805191820181527f6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c29682527f4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f560208301526001908201526080820152610fa18160045b6020020151826001610f1d565b60a0820152610fb1816004610f14565b60c0820152610fca8160045b6020020151826003610f1d565b60e0820152610fda816004610efe565b610100820152610feb816008610f94565b610120820152610ffc816008610f14565b61014082015261100d816008610fbd565b610160820152608081015161102490826008610f1d565b61018082015261103581600c610f94565b6101a082015261104681600c610f14565b6101c082015261105781600c610fbd565b6101e0820152919050565b600083158061106f575082155b8061109a57507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518410155b806110c557507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518310155b156110d257506000610417565b60006110fe847fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551611243565b905060007fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551828509905060007fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551838809905060008061115e8a858561125a565b509098149998505050505050505050565b61119360405180606001604052806000815260200160008152602001600081525090565b60008060006111af856000015186602001518760400151611346565b6040805160608101825293845260208401929092529082015295945050505050565b6111f560405180606001604052806000815260200160008152602001600081525090565b6000806000611220866000015187602001518860400151886000015189602001518a60400151611424565b604080516060810182529384526020840192909252908201529695505050505050565b60006102f683611254600285611eb6565b8461155c565b6000808080806080815b81156113285782156112955761127b858585611346565b9196509450925061128d858585611346565b919650945092505b50600c60fc89901c1660fe88901c17801561130b576113038585858d85601081106112c2576112c2611b6a565b6020020151518e86601081106112da576112da611b6a565b6020020151602001518f87601081106112f5576112f5611b6a565b602002015160400151611424565b919650945092505b600298891b989790971b968161132081611ec9565b925050611264565b6113338585856115b0565b909750955050505050505b935093915050565b6000806000846000036113615750600091508190508061141b565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff8085860981828283097fffffffff00000001000000000000000000000000fffffffffffffffffffffffc099050818788098283828b0960040983848384096008099150838385868d8e09600309089250838160020984848509818110156113e65785015b039650868110156113f45783015b8387820384099550508085101561140a57938201935b909303925080808688096002099150505b93509350939050565b60008060008660000361143e575084915083905082611550565b83600003611453575087915086905085611550565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff808889098186870982818d0983838b0984858a85098e0985868e87098c09868b8f08848410156114a357928701925b8484039350878460020988818209905088818609848410156114c457928901925b898585036002099350898485099c50898288099650898a8860020982089150818d10156114f0579b89019b5b818d039c5089818b87600209099450508b86101561150d57948801945b888c870384099a50838b101561152257998801995b838b039a508887890897508882830990508781101561153e5788015b88858983030999505050505050505050505b96509650969350505050565b60008184111561156c5781840693505b60405160208152602080820152602060408201528460608201528360808201528260a082015260208160c08360056136b0fa8080156100a357505051949350505050565b600080826000036115c65750600090508061133e565b60006115f2847fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611243565b905060007fffffffff00000001000000000000000000000000ffffffffffffffffffffffff82830990507fffffffff00000001000000000000000000000000ffffffffffffffffffffffff81880993507fffffffff00000001000000000000000000000000ffffffffffffffffffffffff80838309870992505050935093915050565b82600281019282156116a8579160200282015b828111156116a8578251829060ff16905591602001919060010190611688565b506116b492915061174e565b5090565b60405180604001604052806002906020820280368337509192915050565b82600281019282156116a8579160200282015b828111156116a85782518255916020019190600101906116e9565b6040518061020001604052806010905b61173860405180606001604052806000815260200160008152602001600081525090565b8152602001906001900390816117145790505090565b5b808211156116b4576000815560010161174f565b6000610160828403121561177657600080fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156117ce576117ce61177c565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561181b5761181b61177c565b604052919050565b60008060006080848603121561183857600080fd5b833567ffffffffffffffff81111561184f57600080fd5b61185b86828701611763565b935050602080850135925085605f86011261187557600080fd5b61187d6117ab565b80608087018881111561188f57600080fd5b604088015b818110156118ab5780358452928401928401611894565b50508093505050509250925092565b600067ffffffffffffffff8211156118d4576118d461177c565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261191157600080fd5b813561192461191f826118ba565b6117d4565b81815284602083860101111561193957600080fd5b816020850160208301376000918101602001919091529392505050565b6000806040838503121561196957600080fd5b82359150602083013567ffffffffffffffff81111561198757600080fd5b61199385828601611900565b9150509250929050565b6000602082840312156119af57600080fd5b813567ffffffffffffffff8111156119c657600080fd5b61041784828501611900565b60005b838110156119ed5781810151838201526020016119d5565b50506000910152565b6020815260008251806020840152611a158160408501602087016119d2565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b60008060408385031215611a5a57600080fd5b823567ffffffffffffffff811115611a7157600080fd5b611a7d85828601611763565b95602094909401359450505050565b60008060208385031215611a9f57600080fd5b823567ffffffffffffffff80821115611ab757600080fd5b818501915085601f830112611acb57600080fd5b813581811115611ada57600080fd5b866020828501011115611aec57600080fd5b60209290920196919550909350505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112611b3357600080fd5b83018035915067ffffffffffffffff821115611b4e57600080fd5b602001915036819003821315611b6357600080fd5b9250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008183825b6002811015611bbe578154835260209092019160019182019101611b9f565b50505060408201905092915050565b60008085851115611bdd57600080fd5b83861115611bea57600080fd5b5050820193919092039150565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b6000611c5261191f846118ba565b9050828152838383011115611c6657600080fd5b6102f68360208301846119d2565b600082601f830112611c8557600080fd5b6102f683835160208501611c44565b600080600080600060a08688031215611cac57600080fd5b8551945060208601519350604086015167ffffffffffffffff80821115611cd257600080fd5b818801915088601f830112611ce657600080fd5b611cf589835160208501611c44565b94506060880151915080821115611d0b57600080fd5b611d1789838a01611c74565b93506080880151915080821115611d2d57600080fd5b50611d3a88828901611c74565b9150509295509295909350565b60008451611d598184602089016119d2565b845190830190611d6d8183602089016119d2565b8451910190611d808183602088016119d2565b0195945050505050565b60008251611d9c8184602087016119d2565b9190910192915050565b600060208284031215611db857600080fd5b5051919050565b60008351611dd18184602088016119d2565b9190910191825250602001919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808202811582820484141761036957610369611de1565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082611e6557611e65611e27565b500490565b600082611e7957611e79611e27565b500690565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611eaf57611eaf611de1565b5060010190565b8181038181111561036957610369611de1565b600081611ed857611ed8611de1565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392d5fa2646970667358221220d4142da7b16effb6b95f41adeff2bc8ce0d59d3b70ca8d55e6e83224bbfbec0a64736f6c63430008150033", + "devdoc": { + "author": "Ruslan Serebriakov (@rsrbk)David Yongjun Kim (@Powerstream3604)", + "details": "Primarily used to verify user ops signed with passkeys", + "kind": "dev", + "methods": { + "initializeSigner(bytes)": { + "details": "This method checks if the signer has already been initialized. If already initialized, it reverts. It checks if the public key is in the light format and initializes signer storage in k1 storage.", + "params": { + "_publicKey": "Bytes of owner public key" + }, + "returns": { + "initSuccess": "Uint value representing the success of init operation" + } + }, + "isValidKeyType(bytes)": { + "details": "For this Secp256k1Verification Facet, the public key should in an uncompressed public key format", + "params": { + "_publicKey": "Bytes of public key for format check" + }, + "returns": { + "isValid": "Boolean variable representing if the format of public key is valid" + } + }, + "isValidSignature(bytes32,bytes)": { + "details": "This method verifies the signature if the owner indeed signed the hash. Returns magic value if true", + "params": { + "_hash": "Hash value the owner signed", + "_signature": "Signature that signed the above hash" + }, + "returns": { + "magicValue": "Bytes4 value representing the success/failure of validation" + } + }, + "owner()": { + "returns": { + "signer": "Bytes of owner address" + } + }, + "uninitializeSigner()": { + "details": "This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.", + "returns": { + "uninitSuccess": "Uint value representing the success of uninit operation" + } + }, + "validateOwnerSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32)": { + "details": "This method validates if the user operation is signed by the owner. It internally calls validateSignature with signer public key.", + "params": { + "userOp": "UserOperation including all information for execution", + "userOpHash": "Hash of UserOperation given from EntryPoint. This hash is used for signature validation" + }, + "returns": { + "validationData": "Uint value representing whether the validation is successful. 0 for success, 1 for failure" + } + }, + "validateOwnerSignatureSelector()": { + "returns": { + "ownerSignatureValidatorSelector": "Bytes4 selector of function signature to validate account owner's UserOperation signature" + } + }, + "validateSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256[2])": { + "details": "This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address", + "params": { + "q": "Public Key of signer who signed the contract, to be validated", + "userOp": "UserOperation including all information for execution", + "userOpHash": "Hash of UserOperation given from EntryPoint. This hash is used for signature validation" + }, + "returns": { + "isValid": "Uint value representing whether the validation is successful. 0 for success, 1 for failure" + } + } + }, + "title": "Secp256r1 verification facet", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "constructor": { + "notice": "This constructor ensures that this contract can only be used as singleton for Proxy contracts" + }, + "initializeSigner(bytes)": { + "notice": "Initializes the signer in R1 Facet Storage. This can only be called when the account is uninitialized or during signature migration." + }, + "isValidKeyType(bytes)": { + "notice": "Validates if the format of public key is valid for this verification facet" + }, + "isValidSignature(bytes32,bytes)": { + "notice": "Validates if the signature is valid. Function to be compatible with EIP-1271" + }, + "owner()": { + "notice": "Returns the owner of the account" + }, + "uninitializeSigner()": { + "notice": "Uninitialize signer in R1 Facet Storage. This can only be called when the account is undergoing signature migration and has already been initialized." + }, + "validateOwnerSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32)": { + "notice": "Validates if the user operation is signed by the owner." + }, + "validateOwnerSignatureSelector()": { + "notice": "Returns the selector of function to validate the signature of UserOperation" + }, + "validateSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256[2])": { + "notice": "Validates if the signature of UserOperation is signed by the given signer" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/mainnet/TokenReceiverFacet.json b/deployments/mainnet/TokenReceiverFacet.json new file mode 100644 index 0000000..1df4c11 --- /dev/null +++ b/deployments/mainnet/TokenReceiverFacet.json @@ -0,0 +1,239 @@ +{ + "address": "0x3143E1C0Af0Cdc153423863923Cf4e3818e34Daa", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onERC1155BatchReceived", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onERC1155Received", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onERC721Received", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onTokenTransfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "tokensReceived", + "outputs": [], + "stateMutability": "pure", + "type": "function" + } + ], + "transactionHash": "0x43dd55268811c20250af436a9cfa6827da3213bbb3907242057745c401ef5029", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 43, + "gasUsed": "329424", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x70bfc1dfcb238cb70dcf09c10ba4f023d50fc840886014b1c558636bdc1937de", + "transactionHash": "0x43dd55268811c20250af436a9cfa6827da3213bbb3907242057745c401ef5029", + "logs": [], + "blockNumber": 19517137, + "cumulativeGasUsed": "5204253", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "ad34345aa73d96f52b3e14df983b6b29", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onERC1155BatchReceived\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onERC1155Received\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onERC721Received\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"tokensReceived\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"Contract that enables receiving ERC721/ERC1155/ERC777/ERC677 Tokens with safe transfer\",\"kind\":\"dev\",\"methods\":{},\"title\":\"TokenReceiver Facet\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\":{\"notice\":\"Handles ERC1155 Token batch callback. return Standardized onERC1155BatchReceived return value.\"},\"onERC1155Received(address,address,uint256,uint256,bytes)\":{\"notice\":\"Handles ERC1155 Token callback. return Standardized onERC1155Received return value.\"},\"onERC721Received(address,address,uint256,bytes)\":{\"notice\":\"Handles ERC721 Token callback. return Standardized onERC721Received return value.\"},\"onTokenTransfer(address,uint256,bytes)\":{\"notice\":\"Handles ERC677 Token callback. return true.\"},\"tokensReceived(address,address,address,uint256,bytes,bytes)\":{\"notice\":\"Handles ERC777 Token callback. Does not return value, empty implementation.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/TokenReceiverFacet.sol\":\"TokenReceiverFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title ERC721 token receiver interface\\n * @dev Interface for any contract that wants to support safeTransfers\\n * from ERC721 asset contracts.\\n */\\ninterface IERC721Receiver {\\n /**\\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\\n * by `operator` from `from`, this function is called.\\n *\\n * It must return its Solidity selector to confirm the token transfer.\\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\\n *\\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\\n */\\n function onERC721Received(\\n address operator,\\n address from,\\n uint256 tokenId,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\\n *\\n * Accounts can be notified of {IERC777} tokens being sent to them by having a\\n * contract implement this interface (contract holders can be their own\\n * implementer) and registering it on the\\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\\n *\\n * See {IERC1820Registry} and {ERC1820Implementer}.\\n */\\ninterface IERC777Recipient {\\n /**\\n * @dev Called by an {IERC777} token contract whenever tokens are being\\n * moved or created into a registered account (`to`). The type of operation\\n * is conveyed by `from` being the zero address or not.\\n *\\n * This call occurs _after_ the token contract's state is updated, so\\n * {IERC777-balanceOf}, etc., can be used to query the post-operation state.\\n *\\n * This function may revert to prevent the operation from being executed.\\n */\\n function tokensReceived(\\n address operator,\\n address from,\\n address to,\\n uint256 amount,\\n bytes calldata userData,\\n bytes calldata operatorData\\n ) external;\\n}\\n\",\"keccak256\":\"0x1a5d61db2733202ba361e6d6741cd2e662380e22b80e987eacfc91973f2267dc\",\"license\":\"MIT\"},\"contracts/facets/TokenReceiverFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IERC721Receiver} from \\\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\\\";\\nimport {IERC777Recipient} from \\\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\\\";\\nimport {IERC1155Receiver} from \\\"../interfaces/ERC/IERC1155Receiver.sol\\\";\\nimport {IERC677Receiver} from \\\"../interfaces/ERC/IERC677Receiver.sol\\\";\\n\\n/**\\n * @title TokenReceiver Facet\\n * @dev Contract that enables receiving ERC721/ERC1155/ERC777/ERC677 Tokens with safe transfer\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract TokenReceiverFacet is\\n IERC721Receiver,\\n IERC1155Receiver,\\n IERC777Recipient,\\n IERC677Receiver\\n{\\n /**\\n * @notice Handles ERC721 Token callback.\\n * return Standardized onERC721Received return value.\\n */\\n function onERC721Received(\\n address,\\n address,\\n uint256,\\n bytes calldata\\n ) external pure override returns (bytes4) {\\n return IERC721Receiver.onERC721Received.selector;\\n }\\n\\n /**\\n * @notice Handles ERC1155 Token callback.\\n * return Standardized onERC1155Received return value.\\n */\\n function onERC1155Received(\\n address,\\n address,\\n uint256,\\n uint256,\\n bytes calldata\\n ) external pure override returns (bytes4) {\\n return IERC1155Receiver.onERC1155Received.selector;\\n }\\n\\n /**\\n * @notice Handles ERC1155 Token batch callback.\\n * return Standardized onERC1155BatchReceived return value.\\n */\\n function onERC1155BatchReceived(\\n address,\\n address,\\n uint256[] calldata,\\n uint256[] calldata,\\n bytes calldata\\n ) external pure override returns (bytes4) {\\n return IERC1155Receiver.onERC1155BatchReceived.selector;\\n }\\n\\n /**\\n * @notice Handles ERC777 Token callback.\\n * Does not return value, empty implementation.\\n */\\n function tokensReceived(\\n address,\\n address,\\n address,\\n uint256,\\n bytes calldata,\\n bytes calldata\\n ) external pure override {}\\n\\n /**\\n * @notice Handles ERC677 Token callback.\\n * return true.\\n */\\n function onTokenTransfer(\\n address,\\n uint256,\\n bytes calldata\\n ) external pure override returns (bool) {\\n return true;\\n }\\n}\\n\",\"keccak256\":\"0xdfe483d05ef4056bb464c34ade19ab527687aff3ed0b6303b447a68b5ff7abb4\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC1155Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\n\\npragma solidity 0.8.21;\\n\\n/**\\n * @dev _Available since v3.1._\\n */\\ninterface IERC1155Receiver {\\n /**\\n * @dev Handles the receipt of a single ERC1155 token type. This function is\\n * called at the end of a `safeTransferFrom` after the balance has been updated.\\n *\\n * NOTE: To accept the transfer, this must return\\n * `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))`\\n * (i.e. 0xf23a6e61, or its own function selector).\\n *\\n * @param operator The address which initiated the transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param id The ID of the token being transferred\\n * @param value The amount of tokens being transferred\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155Received(\\n address operator,\\n address from,\\n uint256 id,\\n uint256 value,\\n bytes calldata data\\n ) external returns (bytes4);\\n\\n /**\\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\\n * is called at the end of a `safeBatchTransferFrom` after the balances have\\n * been updated.\\n *\\n * NOTE: To accept the transfer(s), this must return\\n * `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))`\\n * (i.e. 0xbc197c81, or its own function selector).\\n *\\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155BatchReceived(\\n address operator,\\n address from,\\n uint256[] calldata ids,\\n uint256[] calldata values,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0x3729c6757bae3aba03ac1c5064d67ad13b94e2a9428bf44b9be510373406da0c\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC677Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC677Receiver {\\n function onTokenTransfer(\\n address sender,\\n uint value,\\n bytes calldata data\\n ) external pure returns (bool);\\n}\\n\",\"keccak256\":\"0x4c1631cf45ea6daac0ec158c3edb9453099130b6b64f697004b83f95aa1f7350\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50610502806100206000396000f3fe608060405234801561001057600080fd5b50600436106100665760003560e01c8063a4c0ed3611610050578063a4c0ed36146100f3578063bc197c811461011b578063f23a6e611461015657600080fd5b806223de291461006b578063150b7a0214610085575b600080fd5b610083610079366004610201565b5050505050505050565b005b6100bd6100933660046102ac565b7f150b7a020000000000000000000000000000000000000000000000000000000095945050505050565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020015b60405180910390f35b61010b61010136600461031b565b6001949350505050565b60405190151581526020016100ea565b6100bd6101293660046103ba565b7fbc197c810000000000000000000000000000000000000000000000000000000098975050505050505050565b6100bd610164366004610454565b7ff23a6e61000000000000000000000000000000000000000000000000000000009695505050505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146101b357600080fd5b919050565b60008083601f8401126101ca57600080fd5b50813567ffffffffffffffff8111156101e257600080fd5b6020830191508360208285010111156101fa57600080fd5b9250929050565b60008060008060008060008060c0898b03121561021d57600080fd5b6102268961018f565b975061023460208a0161018f565b965061024260408a0161018f565b955060608901359450608089013567ffffffffffffffff8082111561026657600080fd5b6102728c838d016101b8565b909650945060a08b013591508082111561028b57600080fd5b506102988b828c016101b8565b999c989b5096995094979396929594505050565b6000806000806000608086880312156102c457600080fd5b6102cd8661018f565b94506102db6020870161018f565b935060408601359250606086013567ffffffffffffffff8111156102fe57600080fd5b61030a888289016101b8565b969995985093965092949392505050565b6000806000806060858703121561033157600080fd5b61033a8561018f565b935060208501359250604085013567ffffffffffffffff81111561035d57600080fd5b610369878288016101b8565b95989497509550505050565b60008083601f84011261038757600080fd5b50813567ffffffffffffffff81111561039f57600080fd5b6020830191508360208260051b85010111156101fa57600080fd5b60008060008060008060008060a0898b0312156103d657600080fd5b6103df8961018f565b97506103ed60208a0161018f565b9650604089013567ffffffffffffffff8082111561040a57600080fd5b6104168c838d01610375565b909850965060608b013591508082111561042f57600080fd5b61043b8c838d01610375565b909650945060808b013591508082111561028b57600080fd5b60008060008060008060a0878903121561046d57600080fd5b6104768761018f565b95506104846020880161018f565b94506040870135935060608701359250608087013567ffffffffffffffff8111156104ae57600080fd5b6104ba89828a016101b8565b979a969950949750929593949250505056fea2646970667358221220ae9a97061ae9e1485161ca9c8d3228a23e47b18755fa935f51b40e927816ca2964736f6c63430008150033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100665760003560e01c8063a4c0ed3611610050578063a4c0ed36146100f3578063bc197c811461011b578063f23a6e611461015657600080fd5b806223de291461006b578063150b7a0214610085575b600080fd5b610083610079366004610201565b5050505050505050565b005b6100bd6100933660046102ac565b7f150b7a020000000000000000000000000000000000000000000000000000000095945050505050565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020015b60405180910390f35b61010b61010136600461031b565b6001949350505050565b60405190151581526020016100ea565b6100bd6101293660046103ba565b7fbc197c810000000000000000000000000000000000000000000000000000000098975050505050505050565b6100bd610164366004610454565b7ff23a6e61000000000000000000000000000000000000000000000000000000009695505050505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146101b357600080fd5b919050565b60008083601f8401126101ca57600080fd5b50813567ffffffffffffffff8111156101e257600080fd5b6020830191508360208285010111156101fa57600080fd5b9250929050565b60008060008060008060008060c0898b03121561021d57600080fd5b6102268961018f565b975061023460208a0161018f565b965061024260408a0161018f565b955060608901359450608089013567ffffffffffffffff8082111561026657600080fd5b6102728c838d016101b8565b909650945060a08b013591508082111561028b57600080fd5b506102988b828c016101b8565b999c989b5096995094979396929594505050565b6000806000806000608086880312156102c457600080fd5b6102cd8661018f565b94506102db6020870161018f565b935060408601359250606086013567ffffffffffffffff8111156102fe57600080fd5b61030a888289016101b8565b969995985093965092949392505050565b6000806000806060858703121561033157600080fd5b61033a8561018f565b935060208501359250604085013567ffffffffffffffff81111561035d57600080fd5b610369878288016101b8565b95989497509550505050565b60008083601f84011261038757600080fd5b50813567ffffffffffffffff81111561039f57600080fd5b6020830191508360208260051b85010111156101fa57600080fd5b60008060008060008060008060a0898b0312156103d657600080fd5b6103df8961018f565b97506103ed60208a0161018f565b9650604089013567ffffffffffffffff8082111561040a57600080fd5b6104168c838d01610375565b909850965060608b013591508082111561042f57600080fd5b61043b8c838d01610375565b909650945060808b013591508082111561028b57600080fd5b60008060008060008060a0878903121561046d57600080fd5b6104768761018f565b95506104846020880161018f565b94506040870135935060608701359250608087013567ffffffffffffffff8111156104ae57600080fd5b6104ba89828a016101b8565b979a969950949750929593949250505056fea2646970667358221220ae9a97061ae9e1485161ca9c8d3228a23e47b18755fa935f51b40e927816ca2964736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "Contract that enables receiving ERC721/ERC1155/ERC777/ERC677 Tokens with safe transfer", + "kind": "dev", + "methods": {}, + "title": "TokenReceiver Facet", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)": { + "notice": "Handles ERC1155 Token batch callback. return Standardized onERC1155BatchReceived return value." + }, + "onERC1155Received(address,address,uint256,uint256,bytes)": { + "notice": "Handles ERC1155 Token callback. return Standardized onERC1155Received return value." + }, + "onERC721Received(address,address,uint256,bytes)": { + "notice": "Handles ERC721 Token callback. return Standardized onERC721Received return value." + }, + "onTokenTransfer(address,uint256,bytes)": { + "notice": "Handles ERC677 Token callback. return true." + }, + "tokensReceived(address,address,address,uint256,bytes,bytes)": { + "notice": "Handles ERC777 Token callback. Does not return value, empty implementation." + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/mainnet/solcInputs/ad34345aa73d96f52b3e14df983b6b29.json b/deployments/mainnet/solcInputs/ad34345aa73d96f52b3e14df983b6b29.json new file mode 100644 index 0000000..c2bd4dc --- /dev/null +++ b/deployments/mainnet/solcInputs/ad34345aa73d96f52b3e14df983b6b29.json @@ -0,0 +1,360 @@ +{ + "language": "Solidity", + "sources": { + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby disabling any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable2Step.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./Ownable.sol\";\n\n/**\n * @dev Contract module which provides access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership} and {acceptOwnership}.\n *\n * This module is used through inheritance. It will make available all functions\n * from parent (Ownable).\n */\nabstract contract Ownable2Step is Ownable {\n address private _pendingOwner;\n\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Returns the address of the pending owner.\n */\n function pendingOwner() public view virtual returns (address) {\n return _pendingOwner;\n }\n\n /**\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual override onlyOwner {\n _pendingOwner = newOwner;\n emit OwnershipTransferStarted(owner(), newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual override {\n delete _pendingOwner;\n super._transferOwnership(newOwner);\n }\n\n /**\n * @dev The new owner accepts the ownership transfer.\n */\n function acceptOwnership() public virtual {\n address sender = _msgSender();\n require(pendingOwner() == sender, \"Ownable2Step: caller is not the new owner\");\n _transferOwnership(sender);\n }\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC1271.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC1271 standard signature validation method for\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\n *\n * _Available since v4.1._\n */\ninterface IERC1271 {\n /**\n * @dev Should return whether the signature provided is valid for the provided data\n * @param hash Hash of the data to be signed\n * @param signature Signature byte array associated with _data\n */\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\n}\n" + }, + "@openzeppelin/contracts/security/ReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor() {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n _nonReentrantBefore();\n _;\n _nonReentrantAfter();\n }\n\n function _nonReentrantBefore() private {\n // On the first call to nonReentrant, _status will be _NOT_ENTERED\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n }\n\n function _nonReentrantAfter() private {\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Returns true if the reentrancy guard is currently set to \"entered\", which indicates there is a\n * `nonReentrant` function in the call stack.\n */\n function _reentrancyGuardEntered() internal view returns (bool) {\n return _status == _ENTERED;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/ERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/ERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC1155.sol\";\nimport \"./IERC1155Receiver.sol\";\nimport \"./extensions/IERC1155MetadataURI.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of the basic standard multi-token.\n * See https://eips.ethereum.org/EIPS/eip-1155\n * Originally based on code by Enjin: https://github.com/enjin/erc-1155\n *\n * _Available since v3.1._\n */\ncontract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {\n using Address for address;\n\n // Mapping from token ID to account balances\n mapping(uint256 => mapping(address => uint256)) private _balances;\n\n // Mapping from account to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json\n string private _uri;\n\n /**\n * @dev See {_setURI}.\n */\n constructor(string memory uri_) {\n _setURI(uri_);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return\n interfaceId == type(IERC1155).interfaceId ||\n interfaceId == type(IERC1155MetadataURI).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC1155MetadataURI-uri}.\n *\n * This implementation returns the same URI for *all* token types. It relies\n * on the token type ID substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * Clients calling this function must replace the `\\{id\\}` substring with the\n * actual token type ID.\n */\n function uri(uint256) public view virtual override returns (string memory) {\n return _uri;\n }\n\n /**\n * @dev See {IERC1155-balanceOf}.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {\n require(account != address(0), \"ERC1155: address zero is not a valid owner\");\n return _balances[id][account];\n }\n\n /**\n * @dev See {IERC1155-balanceOfBatch}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] memory accounts,\n uint256[] memory ids\n ) public view virtual override returns (uint256[] memory) {\n require(accounts.length == ids.length, \"ERC1155: accounts and ids length mismatch\");\n\n uint256[] memory batchBalances = new uint256[](accounts.length);\n\n for (uint256 i = 0; i < accounts.length; ++i) {\n batchBalances[i] = balanceOf(accounts[i], ids[i]);\n }\n\n return batchBalances;\n }\n\n /**\n * @dev See {IERC1155-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC1155-isApprovedForAll}.\n */\n function isApprovedForAll(address account, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[account][operator];\n }\n\n /**\n * @dev See {IERC1155-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n _safeTransferFrom(from, to, id, amount, data);\n }\n\n /**\n * @dev See {IERC1155-safeBatchTransferFrom}.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n _safeBatchTransferFrom(from, to, ids, amounts, data);\n }\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n\n emit TransferSingle(operator, from, to, id, amount);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n for (uint256 i = 0; i < ids.length; ++i) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n }\n\n emit TransferBatch(operator, from, to, ids, amounts);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\n\n _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);\n }\n\n /**\n * @dev Sets a new URI for all token types, by relying on the token type ID\n * substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * By this mechanism, any occurrence of the `\\{id\\}` substring in either the\n * URI or any of the amounts in the JSON file at said URI will be replaced by\n * clients with the token type ID.\n *\n * For example, the `https://token-cdn-domain/\\{id\\}.json` URI would be\n * interpreted by clients as\n * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`\n * for token type ID 0x4cce0.\n *\n * See {uri}.\n *\n * Because these URIs cannot be meaningfully represented by the {URI} event,\n * this function emits no events.\n */\n function _setURI(string memory newuri) internal virtual {\n _uri = newuri;\n }\n\n /**\n * @dev Creates `amount` tokens of token type `id`, and assigns them to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _mint(address to, uint256 id, uint256 amount, bytes memory data) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _balances[id][to] += amount;\n emit TransferSingle(operator, address(0), to, id, amount);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n for (uint256 i = 0; i < ids.length; i++) {\n _balances[ids[i]][to] += amounts[i];\n }\n\n emit TransferBatch(operator, address(0), to, ids, amounts);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);\n }\n\n /**\n * @dev Destroys `amount` tokens of token type `id` from `from`\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `from` must have at least `amount` tokens of token type `id`.\n */\n function _burn(address from, uint256 id, uint256 amount) internal virtual {\n require(from != address(0), \"ERC1155: burn from the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n\n emit TransferSingle(operator, from, address(0), id, amount);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n */\n function _burnBatch(address from, uint256[] memory ids, uint256[] memory amounts) internal virtual {\n require(from != address(0), \"ERC1155: burn from the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n\n for (uint256 i = 0; i < ids.length; i++) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n }\n\n emit TransferBatch(operator, from, address(0), ids, amounts);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {\n require(owner != operator, \"ERC1155: setting approval status for self\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning, as well as batched variants.\n *\n * The same hook is called on both single and batched variants. For single\n * transfers, the length of the `ids` and `amounts` arrays will be 1.\n *\n * Calling conditions (for each `id` and `amount` pair):\n *\n * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * of token type `id` will be transferred to `to`.\n * - When `from` is zero, `amount` tokens of token type `id` will be minted\n * for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n * will be burned.\n * - `from` and `to` are never both zero.\n * - `ids` and `amounts` have the same, non-zero length.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any token transfer. This includes minting\n * and burning, as well as batched variants.\n *\n * The same hook is called on both single and batched variants. For single\n * transfers, the length of the `id` and `amount` arrays will be 1.\n *\n * Calling conditions (for each `id` and `amount` pair):\n *\n * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * of token type `id` will be transferred to `to`.\n * - When `from` is zero, `amount` tokens of token type `id` will be minted\n * for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n * will be burned.\n * - `from` and `to` are never both zero.\n * - `ids` and `amounts` have the same, non-zero length.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {}\n\n function _doSafeTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155Receiver.onERC1155Received.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non-ERC1155Receiver implementer\");\n }\n }\n }\n\n function _doSafeBatchTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (\n bytes4 response\n ) {\n if (response != IERC1155Receiver.onERC1155BatchReceived.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non-ERC1155Receiver implementer\");\n }\n }\n }\n\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {\n uint256[] memory array = new uint256[](1);\n array[0] = element;\n\n return array;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC1155.sol\";\n\n/**\n * @dev Interface of the optional ERC1155MetadataExtension interface, as defined\n * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155MetadataURI is IERC1155 {\n /**\n * @dev Returns the URI for token type `id`.\n *\n * If the `\\{id\\}` substring is present in the URI, it must be replaced by\n * clients with the actual token type ID.\n */\n function uri(uint256 id) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155 is IERC165 {\n /**\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n */\n event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);\n\n /**\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n * transfers.\n */\n event TransferBatch(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\n\n /**\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n * `approved`.\n */\n event ApprovalForAll(address indexed account, address indexed operator, bool approved);\n\n /**\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n *\n * If an {URI} event was emitted for `id`, the standard\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n * returned by {IERC1155MetadataURI-uri}.\n */\n event URI(string value, uint256 indexed id);\n\n /**\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) external view returns (uint256);\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] calldata accounts,\n uint256[] calldata ids\n ) external view returns (uint256[] memory);\n\n /**\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n *\n * Emits an {ApprovalForAll} event.\n *\n * Requirements:\n *\n * - `operator` cannot be the caller.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n *\n * See {setApprovalForAll}.\n */\n function isApprovedForAll(address account, address operator) external view returns (bool);\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155Receiver is IERC165 {\n /**\n * @dev Handles the receipt of a single ERC1155 token type. This function is\n * called at the end of a `safeTransferFrom` after the balance has been updated.\n *\n * NOTE: To accept the transfer, this must return\n * `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n * (i.e. 0xf23a6e61, or its own function selector).\n *\n * @param operator The address which initiated the transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param id The ID of the token being transferred\n * @param value The amount of tokens being transferred\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n ) external returns (bytes4);\n\n /**\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\n * is called at the end of a `safeBatchTransferFrom` after the balances have\n * been updated.\n *\n * NOTE: To accept the transfer(s), this must return\n * `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n * (i.e. 0xbc197c81, or its own function selector).\n *\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the default value returned by this function, unless\n * it's overridden.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(address from, address to, uint256 amount) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\n // decrementing then incrementing.\n _balances[to] += amount;\n }\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n unchecked {\n // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\n _balances[account] += amount;\n }\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n // Overflow not possible: amount <= accountBalance <= totalSupply.\n _totalSupply -= amount;\n }\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\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" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` 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 amount) 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 `amount` as the allowance of `spender` over the 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 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` 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 amount) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/ERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721.sol\";\nimport \"./IERC721Receiver.sol\";\nimport \"./extensions/IERC721Metadata.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/Strings.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\n using Address for address;\n using Strings for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\n\n // Mapping from token ID to approved address\n mapping(uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return\n interfaceId == type(IERC721).interfaceId ||\n interfaceId == type(IERC721Metadata).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _ownerOf(tokenId);\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token owner or approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n _requireMinted(tokenId);\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n _safeTransfer(from, to, tokenId, data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(address from, address to, uint256 tokenId, bytes memory data) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist\n */\n function _ownerOf(uint256 tokenId) internal view virtual returns (address) {\n return _owners[tokenId];\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _ownerOf(tokenId) != address(0);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n address owner = ERC721.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(address to, uint256 tokenId, bytes memory data) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId, 1);\n\n // Check that tokenId was not minted by `_beforeTokenTransfer` hook\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n unchecked {\n // Will not overflow unless all 2**256 token ids are minted to the same owner.\n // Given that tokens are minted one by one, it is impossible in practice that\n // this ever happens. Might change if we allow batch minting.\n // The ERC fails to describe this case.\n _balances[to] += 1;\n }\n\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(address(0), to, tokenId, 1);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n * This is an internal function that does not check if the sender is authorized to operate on the token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId, 1);\n\n // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook\n owner = ERC721.ownerOf(tokenId);\n\n // Clear approvals\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // Cannot overflow, as that would require more tokens to be burned/transferred\n // out than the owner initially received through minting and transferring in.\n _balances[owner] -= 1;\n }\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(owner, address(0), tokenId, 1);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(address from, address to, uint256 tokenId) internal virtual {\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId, 1);\n\n // Check that tokenId was not transferred by `_beforeTokenTransfer` hook\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n\n // Clear approvals from the previous owner\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // `_balances[from]` cannot overflow for the same reason as described in `_burn`:\n // `from`'s balance is the number of token held, which is at least one before the current\n // transfer.\n // `_balances[to]` could overflow in the conditions described in `_mint`. That would require\n // all 2**256 token ids to be minted, which in practice is impossible.\n _balances[from] -= 1;\n _balances[to] += 1;\n }\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId, 1);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721Receiver.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`.\n * - When `from` is zero, the tokens will be minted for `to`.\n * - When `to` is zero, ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}\n\n /**\n * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`.\n * - When `from` is zero, the tokens were minted for `to`.\n * - When `to` is zero, ``from``'s tokens were burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}\n\n /**\n * @dev Unsafe write access to the balances, used by extensions that \"mint\" tokens using an {ownerOf} override.\n *\n * WARNING: Anyone calling this MUST ensure that the balances remain consistent with the ownership. The invariant\n * being that for any address `a` the value returned by `balanceOf(a)` must be equal to the number of tokens such\n * that `ownerOf(tokenId)` is `a`.\n */\n // solhint-disable-next-line func-name-mixedcase\n function __unsafe_increaseBalance(address account, uint256 amount) internal {\n _balances[account] += amount;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721Receiver {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/ERC777.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC777/ERC777.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC777.sol\";\nimport \"./IERC777Recipient.sol\";\nimport \"./IERC777Sender.sol\";\nimport \"../ERC20/IERC20.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/introspection/IERC1820Registry.sol\";\n\n/**\n * @dev Implementation of the {IERC777} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n *\n * Support for ERC20 is included in this contract, as specified by the EIP: both\n * the ERC777 and ERC20 interfaces can be safely used when interacting with it.\n * Both {IERC777-Sent} and {IERC20-Transfer} events are emitted on token\n * movements.\n *\n * Additionally, the {IERC777-granularity} value is hard-coded to `1`, meaning that there\n * are no special restrictions in the amount of tokens that created, moved, or\n * destroyed. This makes integration with ERC20 applications seamless.\n *\n * CAUTION: This file is deprecated as of v4.9 and will be removed in the next major release.\n */\ncontract ERC777 is Context, IERC777, IERC20 {\n using Address for address;\n\n IERC1820Registry internal constant _ERC1820_REGISTRY = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n mapping(address => uint256) private _balances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n bytes32 private constant _TOKENS_SENDER_INTERFACE_HASH = keccak256(\"ERC777TokensSender\");\n bytes32 private constant _TOKENS_RECIPIENT_INTERFACE_HASH = keccak256(\"ERC777TokensRecipient\");\n\n // This isn't ever read from - it's only used to respond to the defaultOperators query.\n address[] private _defaultOperatorsArray;\n\n // Immutable, but accounts may revoke them (tracked in __revokedDefaultOperators).\n mapping(address => bool) private _defaultOperators;\n\n // For each account, a mapping of its operators and revoked default operators.\n mapping(address => mapping(address => bool)) private _operators;\n mapping(address => mapping(address => bool)) private _revokedDefaultOperators;\n\n // ERC20-allowances\n mapping(address => mapping(address => uint256)) private _allowances;\n\n /**\n * @dev `defaultOperators` may be an empty array.\n */\n constructor(string memory name_, string memory symbol_, address[] memory defaultOperators_) {\n _name = name_;\n _symbol = symbol_;\n\n _defaultOperatorsArray = defaultOperators_;\n for (uint256 i = 0; i < defaultOperators_.length; i++) {\n _defaultOperators[defaultOperators_[i]] = true;\n }\n\n // register interfaces\n _ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256(\"ERC777Token\"), address(this));\n _ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256(\"ERC20Token\"), address(this));\n }\n\n /**\n * @dev See {IERC777-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC777-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {ERC20-decimals}.\n *\n * Always returns 18, as per the\n * [ERC777 EIP](https://eips.ethereum.org/EIPS/eip-777#backward-compatibility).\n */\n function decimals() public pure virtual returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC777-granularity}.\n *\n * This implementation always returns `1`.\n */\n function granularity() public view virtual override returns (uint256) {\n return 1;\n }\n\n /**\n * @dev See {IERC777-totalSupply}.\n */\n function totalSupply() public view virtual override(IERC20, IERC777) returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev Returns the amount of tokens owned by an account (`tokenHolder`).\n */\n function balanceOf(address tokenHolder) public view virtual override(IERC20, IERC777) returns (uint256) {\n return _balances[tokenHolder];\n }\n\n /**\n * @dev See {IERC777-send}.\n *\n * Also emits a {IERC20-Transfer} event for ERC20 compatibility.\n */\n function send(address recipient, uint256 amount, bytes memory data) public virtual override {\n _send(_msgSender(), recipient, amount, data, \"\", true);\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Unlike `send`, `recipient` is _not_ required to implement the {IERC777Recipient}\n * interface if it is a contract.\n *\n * Also emits a {Sent} event.\n */\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n _send(_msgSender(), recipient, amount, \"\", \"\", false);\n return true;\n }\n\n /**\n * @dev See {IERC777-burn}.\n *\n * Also emits a {IERC20-Transfer} event for ERC20 compatibility.\n */\n function burn(uint256 amount, bytes memory data) public virtual override {\n _burn(_msgSender(), amount, data, \"\");\n }\n\n /**\n * @dev See {IERC777-isOperatorFor}.\n */\n function isOperatorFor(address operator, address tokenHolder) public view virtual override returns (bool) {\n return\n operator == tokenHolder ||\n (_defaultOperators[operator] && !_revokedDefaultOperators[tokenHolder][operator]) ||\n _operators[tokenHolder][operator];\n }\n\n /**\n * @dev See {IERC777-authorizeOperator}.\n */\n function authorizeOperator(address operator) public virtual override {\n require(_msgSender() != operator, \"ERC777: authorizing self as operator\");\n\n if (_defaultOperators[operator]) {\n delete _revokedDefaultOperators[_msgSender()][operator];\n } else {\n _operators[_msgSender()][operator] = true;\n }\n\n emit AuthorizedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-revokeOperator}.\n */\n function revokeOperator(address operator) public virtual override {\n require(operator != _msgSender(), \"ERC777: revoking self as operator\");\n\n if (_defaultOperators[operator]) {\n _revokedDefaultOperators[_msgSender()][operator] = true;\n } else {\n delete _operators[_msgSender()][operator];\n }\n\n emit RevokedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-defaultOperators}.\n */\n function defaultOperators() public view virtual override returns (address[] memory) {\n return _defaultOperatorsArray;\n }\n\n /**\n * @dev See {IERC777-operatorSend}.\n *\n * Emits {Sent} and {IERC20-Transfer} events.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes memory data,\n bytes memory operatorData\n ) public virtual override {\n require(isOperatorFor(_msgSender(), sender), \"ERC777: caller is not an operator for holder\");\n _send(sender, recipient, amount, data, operatorData, true);\n }\n\n /**\n * @dev See {IERC777-operatorBurn}.\n *\n * Emits {Burned} and {IERC20-Transfer} events.\n */\n function operatorBurn(\n address account,\n uint256 amount,\n bytes memory data,\n bytes memory operatorData\n ) public virtual override {\n require(isOperatorFor(_msgSender(), account), \"ERC777: caller is not an operator for holder\");\n _burn(account, amount, data, operatorData);\n }\n\n /**\n * @dev See {IERC20-allowance}.\n *\n * Note that operator and allowance concepts are orthogonal: operators may\n * not have allowance, and accounts with allowance may not be operators\n * themselves.\n */\n function allowance(address holder, address spender) public view virtual override returns (uint256) {\n return _allowances[holder][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Note that accounts cannot have allowance issued by their operators.\n */\n function approve(address spender, uint256 value) public virtual override returns (bool) {\n address holder = _msgSender();\n _approve(holder, spender, value);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Note that operator and allowance concepts are orthogonal: operators cannot\n * call `transferFrom` (unless they have allowance), and accounts with\n * allowance cannot call `operatorSend` (unless they are operators).\n *\n * Emits {Sent}, {IERC20-Transfer} and {IERC20-Approval} events.\n */\n function transferFrom(address holder, address recipient, uint256 amount) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(holder, spender, amount);\n _send(holder, recipient, amount, \"\", \"\", false);\n return true;\n }\n\n /**\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with the caller address as the `operator` and with\n * `userData` and `operatorData`.\n *\n * See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits {Minted} and {IERC20-Transfer} events.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - if `account` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function _mint(address account, uint256 amount, bytes memory userData, bytes memory operatorData) internal virtual {\n _mint(account, amount, userData, operatorData, true);\n }\n\n /**\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * If `requireReceptionAck` is set to true, and if a send hook is\n * registered for `account`, the corresponding function will be called with\n * `operator`, `data` and `operatorData`.\n *\n * See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits {Minted} and {IERC20-Transfer} events.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - if `account` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function _mint(\n address account,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) internal virtual {\n require(account != address(0), \"ERC777: mint to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), account, amount);\n\n // Update state variables\n _totalSupply += amount;\n _balances[account] += amount;\n\n _callTokensReceived(operator, address(0), account, amount, userData, operatorData, requireReceptionAck);\n\n emit Minted(operator, account, amount, userData, operatorData);\n emit Transfer(address(0), account, amount);\n }\n\n /**\n * @dev Send tokens\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _send(\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) internal virtual {\n require(from != address(0), \"ERC777: transfer from the zero address\");\n require(to != address(0), \"ERC777: transfer to the zero address\");\n\n address operator = _msgSender();\n\n _callTokensToSend(operator, from, to, amount, userData, operatorData);\n\n _move(operator, from, to, amount, userData, operatorData);\n\n _callTokensReceived(operator, from, to, amount, userData, operatorData, requireReceptionAck);\n }\n\n /**\n * @dev Burn tokens\n * @param from address token holder address\n * @param amount uint256 amount of tokens to burn\n * @param data bytes extra information provided by the token holder\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _burn(address from, uint256 amount, bytes memory data, bytes memory operatorData) internal virtual {\n require(from != address(0), \"ERC777: burn from the zero address\");\n\n address operator = _msgSender();\n\n _callTokensToSend(operator, from, address(0), amount, data, operatorData);\n\n _beforeTokenTransfer(operator, from, address(0), amount);\n\n // Update state variables\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC777: burn amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Burned(operator, from, amount, data, operatorData);\n emit Transfer(from, address(0), amount);\n }\n\n function _move(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n ) private {\n _beforeTokenTransfer(operator, from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC777: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Sent(operator, from, to, amount, userData, operatorData);\n emit Transfer(from, to, amount);\n }\n\n /**\n * @dev See {ERC20-_approve}.\n *\n * Note that accounts cannot have allowance issued by their operators.\n */\n function _approve(address holder, address spender, uint256 value) internal virtual {\n require(holder != address(0), \"ERC777: approve from the zero address\");\n require(spender != address(0), \"ERC777: approve to the zero address\");\n\n _allowances[holder][spender] = value;\n emit Approval(holder, spender, value);\n }\n\n /**\n * @dev Call from.tokensToSend() if the interface is registered\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _callTokensToSend(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n ) private {\n address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(from, _TOKENS_SENDER_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Sender(implementer).tokensToSend(operator, from, to, amount, userData, operatorData);\n }\n }\n\n /**\n * @dev Call to.tokensReceived() if the interface is registered. Reverts if the recipient is a contract but\n * tokensReceived() was not registered for the recipient\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _callTokensReceived(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) private {\n address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(to, _TOKENS_RECIPIENT_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Recipient(implementer).tokensReceived(operator, from, to, amount, userData, operatorData);\n } else if (requireReceptionAck) {\n require(!to.isContract(), \"ERC777: token recipient contract has no implementer for ERC777TokensRecipient\");\n }\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {IERC20-Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC777: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes\n * calls to {send}, {transfer}, {operatorSend}, {transferFrom}, minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be to transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address operator, address from, address to, uint256 amount) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC777/IERC777.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777Token standard as defined in the EIP.\n *\n * This contract uses the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 registry standard] to let\n * token holders and recipients react to token movements by using setting implementers\n * for the associated interfaces in said registry. See {IERC1820Registry} and\n * {ERC1820Implementer}.\n */\ninterface IERC777 {\n /**\n * @dev Emitted when `amount` tokens are created by `operator` and assigned to `to`.\n *\n * Note that some additional user `data` and `operatorData` can be logged in the event.\n */\n event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);\n\n /**\n * @dev Emitted when `operator` destroys `amount` tokens from `account`.\n *\n * Note that some additional user `data` and `operatorData` can be logged in the event.\n */\n event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);\n\n /**\n * @dev Emitted when `operator` is made operator for `tokenHolder`.\n */\n event AuthorizedOperator(address indexed operator, address indexed tokenHolder);\n\n /**\n * @dev Emitted when `operator` is revoked its operator status for `tokenHolder`.\n */\n event RevokedOperator(address indexed operator, address indexed tokenHolder);\n\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, usually a shorter version of the\n * name.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the smallest part of the token that is not divisible. This\n * means all token operations (creation, movement and destruction) must have\n * amounts that are a multiple of this number.\n *\n * For most token contracts, this value will equal 1.\n */\n function granularity() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by an account (`owner`).\n */\n function balanceOf(address owner) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * If send or receive hooks are registered for the caller and `recipient`,\n * the corresponding functions will be called with `data` and empty\n * `operatorData`. See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits a {Sent} event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function send(address recipient, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Destroys `amount` tokens from the caller's account, reducing the\n * total supply.\n *\n * If a send hook is registered for the caller, the corresponding function\n * will be called with `data` and empty `operatorData`. See {IERC777Sender}.\n *\n * Emits a {Burned} event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n */\n function burn(uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Returns true if an account is an operator of `tokenHolder`.\n * Operators can send and burn tokens on behalf of their owners. All\n * accounts are their own operator.\n *\n * See {operatorSend} and {operatorBurn}.\n */\n function isOperatorFor(address operator, address tokenHolder) external view returns (bool);\n\n /**\n * @dev Make an account an operator of the caller.\n *\n * See {isOperatorFor}.\n *\n * Emits an {AuthorizedOperator} event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function authorizeOperator(address operator) external;\n\n /**\n * @dev Revoke an account's operator status for the caller.\n *\n * See {isOperatorFor} and {defaultOperators}.\n *\n * Emits a {RevokedOperator} event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function revokeOperator(address operator) external;\n\n /**\n * @dev Returns the list of default operators. These accounts are operators\n * for all token holders, even if {authorizeOperator} was never called on\n * them.\n *\n * This list is immutable, but individual holders may revoke these via\n * {revokeOperator}, in which case {isOperatorFor} will return false.\n */\n function defaultOperators() external view returns (address[] memory);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must\n * be an operator of `sender`.\n *\n * If send or receive hooks are registered for `sender` and `recipient`,\n * the corresponding functions will be called with `data` and\n * `operatorData`. See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits a {Sent} event.\n *\n * Requirements\n *\n * - `sender` cannot be the zero address.\n * - `sender` must have at least `amount` tokens.\n * - the caller must be an operator for `sender`.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes calldata data,\n bytes calldata operatorData\n ) external;\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the total supply.\n * The caller must be an operator of `account`.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with `data` and `operatorData`. See {IERC777Sender}.\n *\n * Emits a {Burned} event.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n * - the caller must be an operator for `account`.\n */\n function operatorBurn(address account, uint256 amount, bytes calldata data, bytes calldata operatorData) external;\n\n event Sent(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes data,\n bytes operatorData\n );\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\n *\n * Accounts can be notified of {IERC777} tokens being sent to them by having a\n * contract implement this interface (contract holders can be their own\n * implementer) and registering it on the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\n *\n * See {IERC1820Registry} and {ERC1820Implementer}.\n */\ninterface IERC777Recipient {\n /**\n * @dev Called by an {IERC777} token contract whenever tokens are being\n * moved or created into a registered account (`to`). The type of operation\n * is conveyed by `from` being the zero address or not.\n *\n * This call occurs _after_ the token contract's state is updated, so\n * {IERC777-balanceOf}, etc., can be used to query the post-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensReceived(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777Sender.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Sender.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777TokensSender standard as defined in the EIP.\n *\n * {IERC777} Token holders can be notified of operations performed on their\n * tokens by having a contract implement this interface (contract holders can be\n * their own implementer) and registering it on the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\n *\n * See {IERC1820Registry} and {ERC1820Implementer}.\n */\ninterface IERC777Sender {\n /**\n * @dev Called by an {IERC777} token contract whenever a registered holder's\n * (`from`) tokens are about to be moved or destroyed. The type of operation\n * is conveyed by `to` being the zero address or not.\n *\n * This call occurs _before_ the token contract's state is updated, so\n * {IERC777-balanceOf}, etc., can be used to query the pre-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensToSend(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n *\n * Furthermore, `isContract` will also return true if the target contract within\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n * which only has an effect at the end of a transaction.\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Counters.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary Counters {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/ECDSA.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Strings.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV // Deprecated in v4.8\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n /// @solidity memory-safe-assembly\n assembly {\n mstore(0x00, \"\\x19Ethereum Signed Message:\\n32\")\n mstore(0x1c, hash)\n message := keccak256(0x00, 0x3c)\n }\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\n /// @solidity memory-safe-assembly\n assembly {\n let ptr := mload(0x40)\n mstore(ptr, \"\\x19\\x01\")\n mstore(add(ptr, 0x02), domainSeparator)\n mstore(add(ptr, 0x22), structHash)\n data := keccak256(ptr, 0x42)\n }\n }\n\n /**\n * @dev Returns an Ethereum Signed Data with intended validator, created from a\n * `validator` and `data` according to the version 0 of EIP-191.\n *\n * See {recover}.\n */\n function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x00\", validator, data));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/SignatureChecker.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSA.sol\";\nimport \"../../interfaces/IERC1271.sol\";\n\n/**\n * @dev Signature verification helper that can be used instead of `ECDSA.recover` to seamlessly support both ECDSA\n * signatures from externally owned accounts (EOAs) as well as ERC1271 signatures from smart contract wallets like\n * Argent and Gnosis Safe.\n *\n * _Available since v4.1._\n */\nlibrary SignatureChecker {\n /**\n * @dev Checks if a signature is valid for a given signer and data hash. If the signer is a smart contract, the\n * signature is validated against that smart contract using ERC1271, otherwise it's validated using `ECDSA.recover`.\n *\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\n */\n function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature) internal view returns (bool) {\n (address recovered, ECDSA.RecoverError error) = ECDSA.tryRecover(hash, signature);\n return\n (error == ECDSA.RecoverError.NoError && recovered == signer) ||\n isValidERC1271SignatureNow(signer, hash, signature);\n }\n\n /**\n * @dev Checks if a signature is valid for a given signer and data hash. The signature is validated\n * against the signer smart contract using ERC1271.\n *\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\n */\n function isValidERC1271SignatureNow(\n address signer,\n bytes32 hash,\n bytes memory signature\n ) internal view returns (bool) {\n (bool success, bytes memory result) = signer.staticcall(\n abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, signature)\n );\n return (success &&\n result.length >= 32 &&\n abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/ERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165 is IERC165 {\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165).interfaceId;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC1820Registry.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/introspection/IERC1820Registry.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the global ERC1820 Registry, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register\n * implementers for interfaces in this registry, as well as query support.\n *\n * Implementers may be shared by multiple accounts, and can also implement more\n * than a single interface for each account. Contracts can implement interfaces\n * for themselves, but externally-owned accounts (EOA) must delegate this to a\n * contract.\n *\n * {IERC165} interfaces can also be queried via the registry.\n *\n * For an in-depth explanation and source code analysis, see the EIP text.\n */\ninterface IERC1820Registry {\n event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer);\n\n event ManagerChanged(address indexed account, address indexed newManager);\n\n /**\n * @dev Sets `newManager` as the manager for `account`. A manager of an\n * account is able to set interface implementers for it.\n *\n * By default, each account is its own manager. Passing a value of `0x0` in\n * `newManager` will reset the manager to this initial state.\n *\n * Emits a {ManagerChanged} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `account`.\n */\n function setManager(address account, address newManager) external;\n\n /**\n * @dev Returns the manager for `account`.\n *\n * See {setManager}.\n */\n function getManager(address account) external view returns (address);\n\n /**\n * @dev Sets the `implementer` contract as ``account``'s implementer for\n * `interfaceHash`.\n *\n * `account` being the zero address is an alias for the caller's address.\n * The zero address can also be used in `implementer` to remove an old one.\n *\n * See {interfaceHash} to learn how these are created.\n *\n * Emits an {InterfaceImplementerSet} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `account`.\n * - `interfaceHash` must not be an {IERC165} interface id (i.e. it must not\n * end in 28 zeroes).\n * - `implementer` must implement {IERC1820Implementer} and return true when\n * queried for support, unless `implementer` is the caller. See\n * {IERC1820Implementer-canImplementInterfaceForAddress}.\n */\n function setInterfaceImplementer(address account, bytes32 _interfaceHash, address implementer) external;\n\n /**\n * @dev Returns the implementer of `interfaceHash` for `account`. If no such\n * implementer is registered, returns the zero address.\n *\n * If `interfaceHash` is an {IERC165} interface id (i.e. it ends with 28\n * zeroes), `account` will be queried for support of it.\n *\n * `account` being the zero address is an alias for the caller's address.\n */\n function getInterfaceImplementer(address account, bytes32 _interfaceHash) external view returns (address);\n\n /**\n * @dev Returns the interface hash for an `interfaceName`, as defined in the\n * corresponding\n * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP].\n */\n function interfaceHash(string calldata interfaceName) external pure returns (bytes32);\n\n /**\n * @notice Updates the cache with whether the contract implements an ERC165 interface or not.\n * @param account Address of the contract for which to update the cache.\n * @param interfaceId ERC165 interface for which to update the cache.\n */\n function updateERC165Cache(address account, bytes4 interfaceId) external;\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not.\n * If the result is not cached a direct lookup on the contract address is performed.\n * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling\n * {updateERC165Cache} with the contract address.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool);\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not without using or updating the cache.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/math/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\n // The surrounding unchecked block does not change this fact.\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1, \"Math: mulDiv overflow\");\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n //\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n //\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n //\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1 << (log2(a) >> 1);\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = sqrt(a);\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 2, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 128;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 64;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 32;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 16;\n }\n if (value >> 8 > 0) {\n value >>= 8;\n result += 8;\n }\n if (value >> 4 > 0) {\n value >>= 4;\n result += 4;\n }\n if (value >> 2 > 0) {\n value >>= 2;\n result += 2;\n }\n if (value >> 1 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log2(value);\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 10, rounded down, of a positive value.\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 + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 256, rounded down, of a positive value.\n * Returns 0 if given 0.\n *\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n */\n function log256(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 16;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 8;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 4;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 2;\n }\n if (value >> 8 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log256(value);\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/SafeCast.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCast {\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 * _Available since v4.7._\n */\n function toUint248(uint256 value) internal pure returns (uint248) {\n require(value <= type(uint248).max, \"SafeCast: value doesn't fit in 248 bits\");\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 * _Available since v4.7._\n */\n function toUint240(uint256 value) internal pure returns (uint240) {\n require(value <= type(uint240).max, \"SafeCast: value doesn't fit in 240 bits\");\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 * _Available since v4.7._\n */\n function toUint232(uint256 value) internal pure returns (uint232) {\n require(value <= type(uint232).max, \"SafeCast: value doesn't fit in 232 bits\");\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 * _Available since v4.2._\n */\n function toUint224(uint256 value) internal pure returns (uint224) {\n require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\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 * _Available since v4.7._\n */\n function toUint216(uint256 value) internal pure returns (uint216) {\n require(value <= type(uint216).max, \"SafeCast: value doesn't fit in 216 bits\");\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 * _Available since v4.7._\n */\n function toUint208(uint256 value) internal pure returns (uint208) {\n require(value <= type(uint208).max, \"SafeCast: value doesn't fit in 208 bits\");\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 * _Available since v4.7._\n */\n function toUint200(uint256 value) internal pure returns (uint200) {\n require(value <= type(uint200).max, \"SafeCast: value doesn't fit in 200 bits\");\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 * _Available since v4.7._\n */\n function toUint192(uint256 value) internal pure returns (uint192) {\n require(value <= type(uint192).max, \"SafeCast: value doesn't fit in 192 bits\");\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 * _Available since v4.7._\n */\n function toUint184(uint256 value) internal pure returns (uint184) {\n require(value <= type(uint184).max, \"SafeCast: value doesn't fit in 184 bits\");\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 * _Available since v4.7._\n */\n function toUint176(uint256 value) internal pure returns (uint176) {\n require(value <= type(uint176).max, \"SafeCast: value doesn't fit in 176 bits\");\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 * _Available since v4.7._\n */\n function toUint168(uint256 value) internal pure returns (uint168) {\n require(value <= type(uint168).max, \"SafeCast: value doesn't fit in 168 bits\");\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 * _Available since v4.7._\n */\n function toUint160(uint256 value) internal pure returns (uint160) {\n require(value <= type(uint160).max, \"SafeCast: value doesn't fit in 160 bits\");\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 * _Available since v4.7._\n */\n function toUint152(uint256 value) internal pure returns (uint152) {\n require(value <= type(uint152).max, \"SafeCast: value doesn't fit in 152 bits\");\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 * _Available since v4.7._\n */\n function toUint144(uint256 value) internal pure returns (uint144) {\n require(value <= type(uint144).max, \"SafeCast: value doesn't fit in 144 bits\");\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 * _Available since v4.7._\n */\n function toUint136(uint256 value) internal pure returns (uint136) {\n require(value <= type(uint136).max, \"SafeCast: value doesn't fit in 136 bits\");\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 * _Available since v2.5._\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\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 * _Available since v4.7._\n */\n function toUint120(uint256 value) internal pure returns (uint120) {\n require(value <= type(uint120).max, \"SafeCast: value doesn't fit in 120 bits\");\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 * _Available since v4.7._\n */\n function toUint112(uint256 value) internal pure returns (uint112) {\n require(value <= type(uint112).max, \"SafeCast: value doesn't fit in 112 bits\");\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 * _Available since v4.7._\n */\n function toUint104(uint256 value) internal pure returns (uint104) {\n require(value <= type(uint104).max, \"SafeCast: value doesn't fit in 104 bits\");\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 * _Available since v4.2._\n */\n function toUint96(uint256 value) internal pure returns (uint96) {\n require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\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 * _Available since v4.7._\n */\n function toUint88(uint256 value) internal pure returns (uint88) {\n require(value <= type(uint88).max, \"SafeCast: value doesn't fit in 88 bits\");\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 * _Available since v4.7._\n */\n function toUint80(uint256 value) internal pure returns (uint80) {\n require(value <= type(uint80).max, \"SafeCast: value doesn't fit in 80 bits\");\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 * _Available since v4.7._\n */\n function toUint72(uint256 value) internal pure returns (uint72) {\n require(value <= type(uint72).max, \"SafeCast: value doesn't fit in 72 bits\");\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 * _Available since v2.5._\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\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 * _Available since v4.7._\n */\n function toUint56(uint256 value) internal pure returns (uint56) {\n require(value <= type(uint56).max, \"SafeCast: value doesn't fit in 56 bits\");\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 * _Available since v4.7._\n */\n function toUint48(uint256 value) internal pure returns (uint48) {\n require(value <= type(uint48).max, \"SafeCast: value doesn't fit in 48 bits\");\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 * _Available since v4.7._\n */\n function toUint40(uint256 value) internal pure returns (uint40) {\n require(value <= type(uint40).max, \"SafeCast: value doesn't fit in 40 bits\");\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 * _Available since v2.5._\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\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 * _Available since v4.7._\n */\n function toUint24(uint256 value) internal pure returns (uint24) {\n require(value <= type(uint24).max, \"SafeCast: value doesn't fit in 24 bits\");\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 * _Available since v2.5._\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\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 * _Available since v2.5._\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\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 * _Available since v3.0._\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\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 * _Available since v4.7._\n */\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\n downcasted = int248(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 248 bits\");\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 * _Available since v4.7._\n */\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\n downcasted = int240(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 240 bits\");\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 * _Available since v4.7._\n */\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\n downcasted = int232(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 232 bits\");\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 * _Available since v4.7._\n */\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\n downcasted = int224(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 224 bits\");\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 * _Available since v4.7._\n */\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\n downcasted = int216(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 216 bits\");\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 * _Available since v4.7._\n */\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\n downcasted = int208(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 208 bits\");\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 * _Available since v4.7._\n */\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\n downcasted = int200(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 200 bits\");\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 * _Available since v4.7._\n */\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\n downcasted = int192(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 192 bits\");\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 * _Available since v4.7._\n */\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\n downcasted = int184(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 184 bits\");\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 * _Available since v4.7._\n */\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\n downcasted = int176(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 176 bits\");\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 * _Available since v4.7._\n */\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\n downcasted = int168(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 168 bits\");\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 * _Available since v4.7._\n */\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\n downcasted = int160(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 160 bits\");\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 * _Available since v4.7._\n */\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\n downcasted = int152(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 152 bits\");\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 * _Available since v4.7._\n */\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\n downcasted = int144(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 144 bits\");\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 * _Available since v4.7._\n */\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\n downcasted = int136(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 136 bits\");\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 * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\n downcasted = int128(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 128 bits\");\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 * _Available since v4.7._\n */\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\n downcasted = int120(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 120 bits\");\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 * _Available since v4.7._\n */\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\n downcasted = int112(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 112 bits\");\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 * _Available since v4.7._\n */\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\n downcasted = int104(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 104 bits\");\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 * _Available since v4.7._\n */\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\n downcasted = int96(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 96 bits\");\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 * _Available since v4.7._\n */\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\n downcasted = int88(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 88 bits\");\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 * _Available since v4.7._\n */\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\n downcasted = int80(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 80 bits\");\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 * _Available since v4.7._\n */\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\n downcasted = int72(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 72 bits\");\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 * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\n downcasted = int64(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 64 bits\");\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 * _Available since v4.7._\n */\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\n downcasted = int56(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 56 bits\");\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 * _Available since v4.7._\n */\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\n downcasted = int48(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 48 bits\");\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 * _Available since v4.7._\n */\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\n downcasted = int40(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 40 bits\");\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 * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\n downcasted = int32(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 32 bits\");\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 * _Available since v4.7._\n */\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\n downcasted = int24(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 24 bits\");\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 * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\n downcasted = int16(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 16 bits\");\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 * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\n downcasted = int8(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 8 bits\");\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 * _Available since v3.0._\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 require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/SignedMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard signed math utilities missing in the Solidity language.\n */\nlibrary SignedMath {\n /**\n * @dev Returns the largest of two signed numbers.\n */\n function max(int256 a, int256 b) internal pure returns (int256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two signed numbers.\n */\n function min(int256 a, int256 b) internal pure returns (int256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two signed numbers without overflow.\n * The result is rounded towards zero.\n */\n function average(int256 a, int256 b) internal pure returns (int256) {\n // Formula from the book \"Hacker's Delight\"\n int256 x = (a & b) + ((a ^ b) >> 1);\n return x + (int256(uint256(x) >> 255) & (a ^ b));\n }\n\n /**\n * @dev Returns the absolute unsigned value of a signed value.\n */\n function abs(int256 n) internal pure returns (uint256) {\n unchecked {\n // must be unchecked in order to support `n = type(int256).min`\n return uint256(n >= 0 ? n : -n);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/Math.sol\";\nimport \"./math/SignedMath.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n unchecked {\n uint256 length = Math.log10(value) + 1;\n string memory buffer = new string(length);\n uint256 ptr;\n /// @solidity memory-safe-assembly\n assembly {\n ptr := add(buffer, add(32, length))\n }\n while (true) {\n ptr--;\n /// @solidity memory-safe-assembly\n assembly {\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n }\n value /= 10;\n if (value == 0) break;\n }\n return buffer;\n }\n }\n\n /**\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\n */\n function toString(int256 value) internal pure returns (string memory) {\n return string(abi.encodePacked(value < 0 ? \"-\" : \"\", toString(SignedMath.abs(value))));\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n unchecked {\n return toHexString(value, Math.log256(value) + 1);\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n\n /**\n * @dev Returns true if the two strings are equal.\n */\n function equal(string memory a, string memory b) internal pure returns (bool) {\n return keccak256(bytes(a)) == keccak256(bytes(b));\n }\n}\n" + }, + "contracts/aa-4337/core/BaseAccount.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-empty-blocks */\n\nimport \"../interfaces/IAccount.sol\";\nimport \"../interfaces/IEntryPoint.sol\";\nimport \"./Helpers.sol\";\n\n/**\n * Basic account implementation.\n * this contract provides the basic logic for implementing the IAccount interface - validateUserOp\n * specific account implementation should inherit it and provide the account-specific logic\n */\nabstract contract BaseAccount is IAccount {\n using UserOperationLib for UserOperation;\n\n //return value in case of signature failure, with no time-range.\n // equivalent to _packValidationData(true,0,0);\n uint256 internal constant SIG_VALIDATION_FAILED = 1;\n\n /**\n * Return the account nonce.\n * This method returns the next sequential nonce.\n * For a nonce of a specific key, use `entrypoint.getNonce(account, key)`\n */\n function getNonce() public view virtual returns (uint256) {\n return entryPoint().getNonce(address(this), 0);\n }\n\n /**\n * return the entryPoint used by this account.\n * subclass should return the current entryPoint used by this account.\n */\n function entryPoint() public view virtual returns (IEntryPoint);\n\n /**\n * Validate user's signature and nonce.\n * subclass doesn't need to override this method. Instead, it should override the specific internal validation methods.\n */\n function validateUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 missingAccountFunds\n ) external virtual override returns (uint256 validationData) {\n _requireFromEntryPoint();\n validationData = _validateSignature(userOp, userOpHash);\n _validateNonce(userOp.nonce);\n _payPrefund(missingAccountFunds);\n }\n\n /**\n * ensure the request comes from the known entrypoint.\n */\n function _requireFromEntryPoint() internal view virtual {\n require(\n msg.sender == address(entryPoint()),\n \"account: not from EntryPoint\"\n );\n }\n\n /**\n * validate the signature is valid for this message.\n * @param userOp validate the userOp.signature field\n * @param userOpHash convenient field: the hash of the request, to check the signature against\n * (also hashes the entrypoint and chain id)\n * @return validationData signature and time-range of this operation\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * If the account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function _validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) internal virtual returns (uint256 validationData);\n\n /**\n * Validate the nonce of the UserOperation.\n * This method may validate the nonce requirement of this account.\n * e.g.\n * To limit the nonce to use sequenced UserOps only (no \"out of order\" UserOps):\n * `require(nonce < type(uint64).max)`\n * For a hypothetical account that *requires* the nonce to be out-of-order:\n * `require(nonce & type(uint64).max == 0)`\n *\n * The actual nonce uniqueness is managed by the EntryPoint, and thus no other\n * action is needed by the account itself.\n *\n * @param nonce to validate\n *\n * solhint-disable-next-line no-empty-blocks\n */\n function _validateNonce(uint256 nonce) internal view virtual {}\n\n /**\n * sends to the entrypoint (msg.sender) the missing funds for this transaction.\n * subclass MAY override this method for better funds management\n * (e.g. send to the entryPoint more than the minimum required, so that in future transactions\n * it will not be required to send again)\n * @param missingAccountFunds the minimum value this method should send the entrypoint.\n * this value MAY be zero, in case there is enough deposit, or the userOp has a paymaster.\n */\n function _payPrefund(uint256 missingAccountFunds) internal virtual {\n if (missingAccountFunds != 0) {\n (bool success, ) = payable(msg.sender).call{\n value: missingAccountFunds,\n gas: type(uint256).max\n }(\"\");\n (success);\n //ignore failure (its EntryPoint's job to verify, not account.)\n }\n }\n}\n" + }, + "contracts/aa-4337/core/EntryPoint.sol": { + "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n\nimport \"../interfaces/IAccount.sol\";\nimport \"../interfaces/IPaymaster.sol\";\nimport \"../interfaces/IEntryPoint.sol\";\n\nimport \"../utils/Exec.sol\";\nimport \"./StakeManager.sol\";\nimport \"./SenderCreator.sol\";\nimport \"./Helpers.sol\";\nimport \"./NonceManager.sol\";\nimport \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\n\ncontract EntryPoint is\n IEntryPoint,\n StakeManager,\n NonceManager,\n ReentrancyGuard\n{\n using UserOperationLib for UserOperation;\n\n SenderCreator private immutable senderCreator = new SenderCreator();\n\n // internal value used during simulation: need to query aggregator.\n address private constant SIMULATE_FIND_AGGREGATOR = address(1);\n\n // marker for inner call revert on out of gas\n bytes32 private constant INNER_OUT_OF_GAS = hex\"deaddead\";\n\n uint256 private constant REVERT_REASON_MAX_LEN = 2048;\n\n /**\n * for simulation purposes, validateUserOp (and validatePaymasterUserOp) must return this value\n * in case of signature failure, instead of revert.\n */\n uint256 public constant SIG_VALIDATION_FAILED = 1;\n\n /**\n * compensate the caller's beneficiary address with the collected fees of all UserOperations.\n * @param beneficiary the address to receive the fees\n * @param amount amount to transfer.\n */\n function _compensate(address payable beneficiary, uint256 amount) internal {\n require(beneficiary != address(0), \"AA90 invalid beneficiary\");\n (bool success, ) = beneficiary.call{value: amount}(\"\");\n require(success, \"AA91 failed send to beneficiary\");\n }\n\n /**\n * execute a user op\n * @param opIndex index into the opInfo array\n * @param userOp the userOp to execute\n * @param opInfo the opInfo filled by validatePrepayment for this userOp.\n * @return collected the total amount this userOp paid.\n */\n function _executeUserOp(\n uint256 opIndex,\n UserOperation calldata userOp,\n UserOpInfo memory opInfo\n ) private returns (uint256 collected) {\n uint256 preGas = gasleft();\n bytes memory context = getMemoryBytesFromOffset(opInfo.contextOffset);\n\n try this.innerHandleOp(userOp.callData, opInfo, context) returns (\n uint256 _actualGasCost\n ) {\n collected = _actualGasCost;\n } catch {\n bytes32 innerRevertCode;\n assembly {\n returndatacopy(0, 0, 32)\n innerRevertCode := mload(0)\n }\n // handleOps was called with gas limit too low. abort entire bundle.\n if (innerRevertCode == INNER_OUT_OF_GAS) {\n //report paymaster, since if it is not deliberately caused by the bundler,\n // it must be a revert caused by paymaster.\n revert FailedOp(opIndex, \"AA95 out of gas\");\n }\n\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n collected = _handlePostOp(\n opIndex,\n IPaymaster.PostOpMode.postOpReverted,\n opInfo,\n context,\n actualGas\n );\n }\n }\n\n /**\n * Execute a batch of UserOperations.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(\n UserOperation[] calldata ops,\n address payable beneficiary\n ) public nonReentrant {\n uint256 opslen = ops.length;\n UserOpInfo[] memory opInfos = new UserOpInfo[](opslen);\n\n unchecked {\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[i];\n (\n uint256 validationData,\n uint256 pmValidationData\n ) = _validatePrepayment(i, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(\n i,\n validationData,\n pmValidationData,\n address(0)\n );\n }\n\n uint256 collected = 0;\n emit BeforeExecution();\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(i, ops[i], opInfos[i]);\n }\n\n _compensate(beneficiary, collected);\n } //unchecked\n }\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) public nonReentrant {\n uint256 opasLen = opsPerAggregator.length;\n uint256 totalOps = 0;\n for (uint256 i = 0; i < opasLen; i++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[i];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n //address(1) is special marker of \"signature error\"\n require(\n address(aggregator) != address(1),\n \"AA96 invalid aggregator\"\n );\n\n if (address(aggregator) != address(0)) {\n // solhint-disable-next-line no-empty-blocks\n try aggregator.validateSignatures(ops, opa.signature) {} catch {\n revert SignatureValidationFailed(address(aggregator));\n }\n }\n\n totalOps += ops.length;\n }\n\n UserOpInfo[] memory opInfos = new UserOpInfo[](totalOps);\n\n emit BeforeExecution();\n\n uint256 opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n uint256 opslen = ops.length;\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[opIndex];\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(opIndex, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(\n i,\n validationData,\n paymasterValidationData,\n address(aggregator)\n );\n opIndex++;\n }\n }\n\n uint256 collected = 0;\n opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n emit SignatureAggregatorChanged(address(opa.aggregator));\n UserOperation[] calldata ops = opa.userOps;\n uint256 opslen = ops.length;\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(opIndex, ops[i], opInfos[opIndex]);\n opIndex++;\n }\n }\n emit SignatureAggregatorChanged(address(0));\n\n _compensate(beneficiary, collected);\n }\n\n /// @inheritdoc IEntryPoint\n function simulateHandleOp(\n UserOperation calldata op,\n address target,\n bytes calldata targetCallData\n ) external override {\n UserOpInfo memory opInfo;\n _simulationOnlyValidations(op);\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(0, op, opInfo);\n ValidationData memory data = _intersectTimeRange(\n validationData,\n paymasterValidationData\n );\n\n numberMarker();\n uint256 paid = _executeUserOp(0, op, opInfo);\n numberMarker();\n bool targetSuccess;\n bytes memory targetResult;\n if (target != address(0)) {\n (targetSuccess, targetResult) = target.call(targetCallData);\n }\n revert ExecutionResult(\n opInfo.preOpGas,\n paid,\n data.validAfter,\n data.validUntil,\n targetSuccess,\n targetResult\n );\n }\n\n // A memory copy of UserOp static fields only.\n // Excluding: callData, initCode and signature. Replacing paymasterAndData with paymaster.\n struct MemoryUserOp {\n address sender;\n uint256 nonce;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n address paymaster;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n }\n\n struct UserOpInfo {\n MemoryUserOp mUserOp;\n bytes32 userOpHash;\n uint256 prefund;\n uint256 contextOffset;\n uint256 preOpGas;\n }\n\n /**\n * inner function to handle a UserOperation.\n * Must be declared \"external\" to open a call context, but it can only be called by handleOps.\n */\n function innerHandleOp(\n bytes memory callData,\n UserOpInfo memory opInfo,\n bytes calldata context\n ) external returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n require(msg.sender == address(this), \"AA92 internal call only\");\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n\n uint callGasLimit = mUserOp.callGasLimit;\n unchecked {\n // handleOps was called with gas limit too low. abort entire bundle.\n if (\n gasleft() < callGasLimit + mUserOp.verificationGasLimit + 5000\n ) {\n assembly {\n mstore(0, INNER_OUT_OF_GAS)\n revert(0, 32)\n }\n }\n }\n\n IPaymaster.PostOpMode mode = IPaymaster.PostOpMode.opSucceeded;\n if (callData.length > 0) {\n bool success = Exec.call(mUserOp.sender, 0, callData, callGasLimit);\n if (!success) {\n bytes memory result = Exec.getReturnData(REVERT_REASON_MAX_LEN);\n if (result.length > 0) {\n emit UserOperationRevertReason(\n opInfo.userOpHash,\n mUserOp.sender,\n mUserOp.nonce,\n result\n );\n }\n mode = IPaymaster.PostOpMode.opReverted;\n }\n }\n\n unchecked {\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n //note: opIndex is ignored (relevant only if mode==postOpReverted, which is only possible outside of innerHandleOp)\n return _handlePostOp(0, mode, opInfo, context, actualGas);\n }\n }\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(\n UserOperation calldata userOp\n ) public view returns (bytes32) {\n return\n keccak256(abi.encode(userOp.hash(), address(this), block.chainid));\n }\n\n /**\n * copy general fields from userOp into the memory opInfo structure.\n */\n function _copyUserOpToMemory(\n UserOperation calldata userOp,\n MemoryUserOp memory mUserOp\n ) internal pure {\n mUserOp.sender = userOp.sender;\n mUserOp.nonce = userOp.nonce;\n mUserOp.callGasLimit = userOp.callGasLimit;\n mUserOp.verificationGasLimit = userOp.verificationGasLimit;\n mUserOp.preVerificationGas = userOp.preVerificationGas;\n mUserOp.maxFeePerGas = userOp.maxFeePerGas;\n mUserOp.maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes calldata paymasterAndData = userOp.paymasterAndData;\n if (paymasterAndData.length > 0) {\n require(\n paymasterAndData.length >= 20,\n \"AA93 invalid paymasterAndData\"\n );\n mUserOp.paymaster = address(bytes20(paymasterAndData[:20]));\n } else {\n mUserOp.paymaster = address(0);\n }\n }\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external {\n UserOpInfo memory outOpInfo;\n\n _simulationOnlyValidations(userOp);\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(0, userOp, outOpInfo);\n StakeInfo memory paymasterInfo = _getStakeInfo(\n outOpInfo.mUserOp.paymaster\n );\n StakeInfo memory senderInfo = _getStakeInfo(outOpInfo.mUserOp.sender);\n StakeInfo memory factoryInfo;\n {\n bytes calldata initCode = userOp.initCode;\n address factory = initCode.length >= 20\n ? address(bytes20(initCode[0:20]))\n : address(0);\n factoryInfo = _getStakeInfo(factory);\n }\n\n ValidationData memory data = _intersectTimeRange(\n validationData,\n paymasterValidationData\n );\n address aggregator = data.aggregator;\n bool sigFailed = aggregator == address(1);\n ReturnInfo memory returnInfo = ReturnInfo(\n outOpInfo.preOpGas,\n outOpInfo.prefund,\n sigFailed,\n data.validAfter,\n data.validUntil,\n getMemoryBytesFromOffset(outOpInfo.contextOffset)\n );\n\n if (aggregator != address(0) && aggregator != address(1)) {\n AggregatorStakeInfo memory aggregatorInfo = AggregatorStakeInfo(\n aggregator,\n _getStakeInfo(aggregator)\n );\n revert ValidationResultWithAggregation(\n returnInfo,\n senderInfo,\n factoryInfo,\n paymasterInfo,\n aggregatorInfo\n );\n }\n revert ValidationResult(\n returnInfo,\n senderInfo,\n factoryInfo,\n paymasterInfo\n );\n }\n\n function _getRequiredPrefund(\n MemoryUserOp memory mUserOp\n ) internal pure returns (uint256 requiredPrefund) {\n unchecked {\n //when using a Paymaster, the verificationGasLimit is used also to as a limit for the postOp call.\n // our security model might call postOp eventually twice\n uint256 mul = mUserOp.paymaster != address(0) ? 3 : 1;\n uint256 requiredGas = mUserOp.callGasLimit +\n mUserOp.verificationGasLimit *\n mul +\n mUserOp.preVerificationGas;\n\n requiredPrefund = requiredGas * mUserOp.maxFeePerGas;\n }\n }\n\n // create the sender's contract if needed.\n function _createSenderIfNeeded(\n uint256 opIndex,\n UserOpInfo memory opInfo,\n bytes calldata initCode\n ) internal {\n if (initCode.length != 0) {\n address sender = opInfo.mUserOp.sender;\n if (sender.code.length != 0)\n revert FailedOp(opIndex, \"AA10 sender already constructed\");\n address sender1 = senderCreator.createSender{\n gas: opInfo.mUserOp.verificationGasLimit\n }(initCode);\n if (sender1 == address(0))\n revert FailedOp(opIndex, \"AA13 initCode failed or OOG\");\n if (sender1 != sender)\n revert FailedOp(opIndex, \"AA14 initCode must return sender\");\n if (sender1.code.length == 0)\n revert FailedOp(opIndex, \"AA15 initCode must create sender\");\n address factory = address(bytes20(initCode[0:20]));\n emit AccountDeployed(\n opInfo.userOpHash,\n sender,\n factory,\n opInfo.mUserOp.paymaster\n );\n }\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes calldata initCode) public {\n address sender = senderCreator.createSender(initCode);\n revert SenderAddressResult(sender);\n }\n\n function _simulationOnlyValidations(\n UserOperation calldata userOp\n ) internal view {\n // solhint-disable-next-line no-empty-blocks\n try\n this._validateSenderAndPaymaster(\n userOp.initCode,\n userOp.sender,\n userOp.paymasterAndData\n )\n {} catch Error(string memory revertReason) {\n if (bytes(revertReason).length != 0) {\n revert FailedOp(0, revertReason);\n }\n }\n }\n\n /**\n * Called only during simulation.\n * This function always reverts to prevent warm/cold storage differentiation in simulation vs execution.\n */\n function _validateSenderAndPaymaster(\n bytes calldata initCode,\n address sender,\n bytes calldata paymasterAndData\n ) external view {\n if (initCode.length == 0 && sender.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA20 account not deployed\");\n }\n if (paymasterAndData.length >= 20) {\n address paymaster = address(bytes20(paymasterAndData[0:20]));\n if (paymaster.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA30 paymaster not deployed\");\n }\n }\n // always revert\n revert(\"\");\n }\n\n /**\n * call account.validateUserOp.\n * revert (with FailedOp) in case validateUserOp reverts, or account didn't send required prefund.\n * decrement account's deposit if needed\n */\n function _validateAccountPrepayment(\n uint256 opIndex,\n UserOperation calldata op,\n UserOpInfo memory opInfo,\n uint256 requiredPrefund\n )\n internal\n returns (\n uint256 gasUsedByValidateAccountPrepayment,\n uint256 validationData\n )\n {\n unchecked {\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n address sender = mUserOp.sender;\n _createSenderIfNeeded(opIndex, opInfo, op.initCode);\n address paymaster = mUserOp.paymaster;\n numberMarker();\n uint256 missingAccountFunds = 0;\n if (paymaster == address(0)) {\n uint256 bal = balanceOf(sender);\n missingAccountFunds = bal > requiredPrefund\n ? 0\n : requiredPrefund - bal;\n }\n try\n IAccount(sender).validateUserOp{\n gas: mUserOp.verificationGasLimit\n }(op, opInfo.userOpHash, missingAccountFunds)\n returns (uint256 _validationData) {\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA23 reverted: \", revertReason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA23 reverted (or OOG)\");\n }\n if (paymaster == address(0)) {\n DepositInfo storage senderInfo = deposits[sender];\n uint256 deposit = senderInfo.deposit;\n if (requiredPrefund > deposit) {\n revert FailedOp(opIndex, \"AA21 didn't pay prefund\");\n }\n senderInfo.deposit = uint112(deposit - requiredPrefund);\n }\n gasUsedByValidateAccountPrepayment = preGas - gasleft();\n }\n }\n\n /**\n * In case the request has a paymaster:\n * Validate paymaster has enough deposit.\n * Call paymaster.validatePaymasterUserOp.\n * Revert with proper FailedOp in case paymaster reverts.\n * Decrement paymaster's deposit\n */\n function _validatePaymasterPrepayment(\n uint256 opIndex,\n UserOperation calldata op,\n UserOpInfo memory opInfo,\n uint256 requiredPreFund,\n uint256 gasUsedByValidateAccountPrepayment\n ) internal returns (bytes memory context, uint256 validationData) {\n unchecked {\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 verificationGasLimit = mUserOp.verificationGasLimit;\n require(\n verificationGasLimit > gasUsedByValidateAccountPrepayment,\n \"AA41 too little verificationGas\"\n );\n uint256 gas = verificationGasLimit -\n gasUsedByValidateAccountPrepayment;\n\n address paymaster = mUserOp.paymaster;\n DepositInfo storage paymasterInfo = deposits[paymaster];\n uint256 deposit = paymasterInfo.deposit;\n if (deposit < requiredPreFund) {\n revert FailedOp(opIndex, \"AA31 paymaster deposit too low\");\n }\n paymasterInfo.deposit = uint112(deposit - requiredPreFund);\n try\n IPaymaster(paymaster).validatePaymasterUserOp{gas: gas}(\n op,\n opInfo.userOpHash,\n requiredPreFund\n )\n returns (bytes memory _context, uint256 _validationData) {\n context = _context;\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA33 reverted: \", revertReason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA33 reverted (or OOG)\");\n }\n }\n }\n\n /**\n * revert if either account validationData or paymaster validationData is expired\n */\n function _validateAccountAndPaymasterValidationData(\n uint256 opIndex,\n uint256 validationData,\n uint256 paymasterValidationData,\n address expectedAggregator\n ) internal view {\n (address aggregator, bool outOfTimeRange) = _getValidationData(\n validationData\n );\n if (expectedAggregator != aggregator) {\n revert FailedOp(opIndex, \"AA24 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA22 expired or not due\");\n }\n //pmAggregator is not a real signature aggregator: we don't have logic to handle it as address.\n // non-zero address means that the paymaster fails due to some signature check (which is ok only during estimation)\n address pmAggregator;\n (pmAggregator, outOfTimeRange) = _getValidationData(\n paymasterValidationData\n );\n if (pmAggregator != address(0)) {\n revert FailedOp(opIndex, \"AA34 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA32 paymaster expired or not due\");\n }\n }\n\n function _getValidationData(\n uint256 validationData\n ) internal view returns (address aggregator, bool outOfTimeRange) {\n if (validationData == 0) {\n return (address(0), false);\n }\n ValidationData memory data = _parseValidationData(validationData);\n // solhint-disable-next-line not-rely-on-time\n outOfTimeRange =\n block.timestamp > data.validUntil ||\n block.timestamp < data.validAfter;\n aggregator = data.aggregator;\n }\n\n /**\n * validate account and paymaster (if defined).\n * also make sure total validation doesn't exceed verificationGasLimit\n * this method is called off-chain (simulateValidation()) and on-chain (from handleOps)\n * @param opIndex the index of this userOp into the \"opInfos\" array\n * @param userOp the userOp to validate\n */\n function _validatePrepayment(\n uint256 opIndex,\n UserOperation calldata userOp,\n UserOpInfo memory outOpInfo\n )\n private\n returns (uint256 validationData, uint256 paymasterValidationData)\n {\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = outOpInfo.mUserOp;\n _copyUserOpToMemory(userOp, mUserOp);\n outOpInfo.userOpHash = getUserOpHash(userOp);\n\n // validate all numeric values in userOp are well below 128 bit, so they can safely be added\n // and multiplied without causing overflow\n uint256 maxGasValues = mUserOp.preVerificationGas |\n mUserOp.verificationGasLimit |\n mUserOp.callGasLimit |\n userOp.maxFeePerGas |\n userOp.maxPriorityFeePerGas;\n require(maxGasValues <= type(uint120).max, \"AA94 gas values overflow\");\n\n uint256 gasUsedByValidateAccountPrepayment;\n uint256 requiredPreFund = _getRequiredPrefund(mUserOp);\n (\n gasUsedByValidateAccountPrepayment,\n validationData\n ) = _validateAccountPrepayment(\n opIndex,\n userOp,\n outOpInfo,\n requiredPreFund\n );\n\n if (!_validateAndUpdateNonce(mUserOp.sender, mUserOp.nonce)) {\n revert FailedOp(opIndex, \"AA25 invalid account nonce\");\n }\n\n //a \"marker\" where account opcode validation is done and paymaster opcode validation is about to start\n // (used only by off-chain simulateValidation)\n numberMarker();\n\n bytes memory context;\n if (mUserOp.paymaster != address(0)) {\n (context, paymasterValidationData) = _validatePaymasterPrepayment(\n opIndex,\n userOp,\n outOpInfo,\n requiredPreFund,\n gasUsedByValidateAccountPrepayment\n );\n }\n unchecked {\n uint256 gasUsed = preGas - gasleft();\n\n if (userOp.verificationGasLimit < gasUsed) {\n revert FailedOp(opIndex, \"AA40 over verificationGasLimit\");\n }\n outOpInfo.prefund = requiredPreFund;\n outOpInfo.contextOffset = getOffsetOfMemoryBytes(context);\n outOpInfo.preOpGas = preGas - gasleft() + userOp.preVerificationGas;\n }\n }\n\n /**\n * process post-operation.\n * called just after the callData is executed.\n * if a paymaster is defined and its validation returned a non-empty context, its postOp is called.\n * the excess amount is refunded to the account (or paymaster - if it was used in the request)\n * @param opIndex index in the batch\n * @param mode - whether is called from innerHandleOp, or outside (postOpReverted)\n * @param opInfo userOp fields and info collected during validation\n * @param context the context returned in validatePaymasterUserOp\n * @param actualGas the gas used so far by this user operation\n */\n function _handlePostOp(\n uint256 opIndex,\n IPaymaster.PostOpMode mode,\n UserOpInfo memory opInfo,\n bytes memory context,\n uint256 actualGas\n ) private returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n unchecked {\n address refundAddress;\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 gasPrice = getUserOpGasPrice(mUserOp);\n\n address paymaster = mUserOp.paymaster;\n if (paymaster == address(0)) {\n refundAddress = mUserOp.sender;\n } else {\n refundAddress = paymaster;\n if (context.length > 0) {\n actualGasCost = actualGas * gasPrice;\n if (mode != IPaymaster.PostOpMode.postOpReverted) {\n IPaymaster(paymaster).postOp{\n gas: mUserOp.verificationGasLimit\n }(mode, context, actualGasCost);\n } else {\n // solhint-disable-next-line no-empty-blocks\n try\n IPaymaster(paymaster).postOp{\n gas: mUserOp.verificationGasLimit\n }(mode, context, actualGasCost)\n {} catch Error(string memory reason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA50 postOp reverted: \", reason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA50 postOp revert\");\n }\n }\n }\n }\n actualGas += preGas - gasleft();\n actualGasCost = actualGas * gasPrice;\n if (opInfo.prefund < actualGasCost) {\n revert FailedOp(opIndex, \"AA51 prefund below actualGasCost\");\n }\n uint256 refund = opInfo.prefund - actualGasCost;\n _incrementDeposit(refundAddress, refund);\n bool success = mode == IPaymaster.PostOpMode.opSucceeded;\n emit UserOperationEvent(\n opInfo.userOpHash,\n mUserOp.sender,\n mUserOp.paymaster,\n mUserOp.nonce,\n success,\n actualGasCost,\n actualGas\n );\n } // unchecked\n }\n\n /**\n * the gas price this UserOp agrees to pay.\n * relayer/block builder might submit the TX with higher priorityFee, but the user should not\n */\n function getUserOpGasPrice(\n MemoryUserOp memory mUserOp\n ) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = mUserOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = mUserOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n function getOffsetOfMemoryBytes(\n bytes memory data\n ) internal pure returns (uint256 offset) {\n assembly {\n offset := data\n }\n }\n\n function getMemoryBytesFromOffset(\n uint256 offset\n ) internal pure returns (bytes memory data) {\n assembly {\n data := offset\n }\n }\n\n //place the NUMBER opcode in the code.\n // this is used as a marker during simulation, as this OP is completely banned from the simulated code of the\n // account and paymaster.\n function numberMarker() internal view {\n assembly {\n mstore(0, number())\n }\n }\n}\n" + }, + "contracts/aa-4337/core/Helpers.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable no-inline-assembly */\n\n/**\n * returned data from validateUserOp.\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\n * @param aggregator - address(0) - the account validated the signature by itself.\n * address(1) - the account failed to validate the signature.\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\n * @param validAfter - this UserOp is valid only after this timestamp.\n * @param validaUntil - this UserOp is valid only up to this timestamp.\n */\nstruct ValidationData {\n address aggregator;\n uint48 validAfter;\n uint48 validUntil;\n}\n\n//extract sigFailed, validAfter, validUntil.\n// also convert zero validUntil to type(uint48).max\nfunction _parseValidationData(\n uint validationData\n) pure returns (ValidationData memory data) {\n address aggregator = address(uint160(validationData));\n uint48 validUntil = uint48(validationData >> 160);\n if (validUntil == 0) {\n validUntil = type(uint48).max;\n }\n uint48 validAfter = uint48(validationData >> (48 + 160));\n return ValidationData(aggregator, validAfter, validUntil);\n}\n\n// intersect account and paymaster ranges.\nfunction _intersectTimeRange(\n uint256 validationData,\n uint256 paymasterValidationData\n) pure returns (ValidationData memory) {\n ValidationData memory accountValidationData = _parseValidationData(\n validationData\n );\n ValidationData memory pmValidationData = _parseValidationData(\n paymasterValidationData\n );\n address aggregator = accountValidationData.aggregator;\n if (aggregator == address(0)) {\n aggregator = pmValidationData.aggregator;\n }\n uint48 validAfter = accountValidationData.validAfter;\n uint48 validUntil = accountValidationData.validUntil;\n uint48 pmValidAfter = pmValidationData.validAfter;\n uint48 pmValidUntil = pmValidationData.validUntil;\n\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\n return ValidationData(aggregator, validAfter, validUntil);\n}\n\n/**\n * helper to pack the return value for validateUserOp\n * @param data - the ValidationData to pack\n */\nfunction _packValidationData(\n ValidationData memory data\n) pure returns (uint256) {\n return\n uint160(data.aggregator) |\n (uint256(data.validUntil) << 160) |\n (uint256(data.validAfter) << (160 + 48));\n}\n\n/**\n * helper to pack the return value for validateUserOp, when not using an aggregator\n * @param sigFailed - true for signature failure, false for success\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\n * @param validAfter first timestamp this UserOperation is valid\n */\nfunction _packValidationData(\n bool sigFailed,\n uint48 validUntil,\n uint48 validAfter\n) pure returns (uint256) {\n return\n (sigFailed ? 1 : 0) |\n (uint256(validUntil) << 160) |\n (uint256(validAfter) << (160 + 48));\n}\n\n/**\n * keccak function over calldata.\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\n */\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\n assembly {\n let mem := mload(0x40)\n let len := data.length\n calldatacopy(mem, data.offset, len)\n ret := keccak256(mem, len)\n }\n}\n" + }, + "contracts/aa-4337/core/NonceManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\nimport \"../interfaces/IEntryPoint.sol\";\n\n/**\n * nonce management functionality\n */\ncontract NonceManager is INonceManager {\n /**\n * The next valid sequence number for a given nonce key.\n */\n mapping(address => mapping(uint192 => uint256)) public nonceSequenceNumber;\n\n function getNonce(\n address sender,\n uint192 key\n ) public view override returns (uint256 nonce) {\n return nonceSequenceNumber[sender][key] | (uint256(key) << 64);\n }\n\n // allow an account to manually increment its own nonce.\n // (mainly so that during construction nonce can be made non-zero,\n // to \"absorb\" the gas cost of first nonce increment to 1st transaction (construction),\n // not to 2nd transaction)\n function incrementNonce(uint192 key) public override {\n nonceSequenceNumber[msg.sender][key]++;\n }\n\n /**\n * validate nonce uniqueness for this account.\n * called just after validateUserOp()\n */\n function _validateAndUpdateNonce(\n address sender,\n uint256 nonce\n ) internal returns (bool) {\n uint192 key = uint192(nonce >> 64);\n uint64 seq = uint64(nonce);\n return nonceSequenceNumber[sender][key]++ == seq;\n }\n}\n" + }, + "contracts/aa-4337/core/SenderCreator.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/**\n * helper contract for EntryPoint, to call userOp.initCode from a \"neutral\" address,\n * which is explicitly not the entryPoint itself.\n */\ncontract SenderCreator {\n /**\n * call the \"initCode\" factory to create and return the sender account address\n * @param initCode the initCode value from a UserOp. contains 20 bytes of factory address, followed by calldata\n * @return sender the returned address of the created account, or zero address on failure.\n */\n function createSender(\n bytes calldata initCode\n ) external returns (address sender) {\n address factory = address(bytes20(initCode[0:20]));\n bytes memory initCallData = initCode[20:];\n bool success;\n /* solhint-disable no-inline-assembly */\n assembly {\n success := call(\n gas(),\n factory,\n 0,\n add(initCallData, 0x20),\n mload(initCallData),\n 0,\n 32\n )\n sender := mload(0)\n }\n if (!success) {\n sender = address(0);\n }\n }\n}\n" + }, + "contracts/aa-4337/core/StakeManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity 0.8.21;\n\nimport \"../interfaces/IStakeManager.sol\";\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable not-rely-on-time */\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by a paymaster.\n */\nabstract contract StakeManager is IStakeManager {\n /// maps paymaster to their deposits and stakes\n mapping(address => DepositInfo) public deposits;\n\n /// @inheritdoc IStakeManager\n function getDepositInfo(\n address account\n ) public view returns (DepositInfo memory info) {\n return deposits[account];\n }\n\n // internal method to return just the stake info\n function _getStakeInfo(\n address addr\n ) internal view returns (StakeInfo memory info) {\n DepositInfo storage depositInfo = deposits[addr];\n info.stake = depositInfo.stake;\n info.unstakeDelaySec = depositInfo.unstakeDelaySec;\n }\n\n /// return the deposit (for gas payment) of the account\n function balanceOf(address account) public view returns (uint256) {\n return deposits[account].deposit;\n }\n\n receive() external payable {\n depositTo(msg.sender);\n }\n\n function _incrementDeposit(address account, uint256 amount) internal {\n DepositInfo storage info = deposits[account];\n uint256 newAmount = info.deposit + amount;\n require(newAmount <= type(uint112).max, \"deposit overflow\");\n info.deposit = uint112(newAmount);\n }\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) public payable {\n _incrementDeposit(account, msg.value);\n DepositInfo storage info = deposits[account];\n emit Deposited(account, info.deposit);\n }\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 unstakeDelaySec) public payable {\n DepositInfo storage info = deposits[msg.sender];\n require(unstakeDelaySec > 0, \"must specify unstake delay\");\n require(\n unstakeDelaySec >= info.unstakeDelaySec,\n \"cannot decrease unstake time\"\n );\n uint256 stake = info.stake + msg.value;\n require(stake > 0, \"no stake specified\");\n require(stake <= type(uint112).max, \"stake overflow\");\n deposits[msg.sender] = DepositInfo(\n info.deposit,\n true,\n uint112(stake),\n unstakeDelaySec,\n 0\n );\n emit StakeLocked(msg.sender, stake, unstakeDelaySec);\n }\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external {\n DepositInfo storage info = deposits[msg.sender];\n require(info.unstakeDelaySec != 0, \"not staked\");\n require(info.staked, \"already unstaking\");\n uint48 withdrawTime = uint48(block.timestamp) + info.unstakeDelaySec;\n info.withdrawTime = withdrawTime;\n info.staked = false;\n emit StakeUnlocked(msg.sender, withdrawTime);\n }\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external {\n DepositInfo storage info = deposits[msg.sender];\n uint256 stake = info.stake;\n require(stake > 0, \"No stake to withdraw\");\n require(info.withdrawTime > 0, \"must call unlockStake() first\");\n require(\n info.withdrawTime <= block.timestamp,\n \"Stake withdrawal is not due\"\n );\n info.unstakeDelaySec = 0;\n info.withdrawTime = 0;\n info.stake = 0;\n emit StakeWithdrawn(msg.sender, withdrawAddress, stake);\n (bool success, ) = withdrawAddress.call{value: stake}(\"\");\n require(success, \"failed to withdraw stake\");\n }\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(\n address payable withdrawAddress,\n uint256 withdrawAmount\n ) external {\n DepositInfo storage info = deposits[msg.sender];\n require(withdrawAmount <= info.deposit, \"Withdraw amount too large\");\n info.deposit = uint112(info.deposit - withdrawAmount);\n emit Withdrawn(msg.sender, withdrawAddress, withdrawAmount);\n (bool success, ) = withdrawAddress.call{value: withdrawAmount}(\"\");\n require(success, \"failed to withdraw\");\n }\n}\n" + }, + "contracts/aa-4337/interfaces/IAccount.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\ninterface IAccount {\n /**\n * Validate user's signature and nonce\n * the entryPoint will make the call to the recipient only if this validation call returns successfully.\n * signature failure should be reported by returning SIG_VALIDATION_FAILED (1).\n * This allows making a \"simulation call\" without a valid signature\n * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure.\n *\n * @dev Must validate caller is the entryPoint.\n * Must validate the signature and nonce\n * @param userOp the operation that is about to be executed.\n * @param userOpHash hash of the user's request data. can be used as the basis for signature.\n * @param missingAccountFunds missing funds on the account's deposit in the entrypoint.\n * This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call.\n * The excess is left as a deposit in the entrypoint, for future calls.\n * can be withdrawn anytime using \"entryPoint.withdrawTo()\"\n * In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero.\n * @return validationData packaged ValidationData structure. use `_packValidationData` and `_unpackValidationData` to encode and decode\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * If an account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validateUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 missingAccountFunds\n ) external returns (uint256 validationData);\n}\n" + }, + "contracts/aa-4337/interfaces/IAggregator.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * Aggregated Signatures validator.\n */\ninterface IAggregator {\n /**\n * validate aggregated signature.\n * revert if the aggregated signature does not match the given list of operations.\n */\n function validateSignatures(\n UserOperation[] calldata userOps,\n bytes calldata signature\n ) external view;\n\n /**\n * validate signature of a single userOp\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\n * @param userOp the userOperation received from the user.\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\n * (usually empty, unless account and aggregator support some kind of \"multisig\"\n */\n function validateUserOpSignature(\n UserOperation calldata userOp\n ) external view returns (bytes memory sigForUserOp);\n\n /**\n * aggregate multiple signatures into a single value.\n * This method is called off-chain to calculate the signature to pass with handleOps()\n * bundler MAY use optimized custom code perform this aggregation\n * @param userOps array of UserOperations to collect the signatures from.\n * @return aggregatedSignature the aggregated signature\n */\n function aggregateSignatures(\n UserOperation[] calldata userOps\n ) external view returns (bytes memory aggregatedSignature);\n}\n" + }, + "contracts/aa-4337/interfaces/IEntryPoint.sol": { + "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n/* solhint-disable reason-string */\n\nimport \"./UserOperation.sol\";\nimport \"./IStakeManager.sol\";\nimport \"./IAggregator.sol\";\nimport \"./INonceManager.sol\";\n\ninterface IEntryPoint is IStakeManager, INonceManager {\n /***\n * An event emitted after each successful request\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\n * @param sender - the account that generates this request.\n * @param paymaster - if non-null, the paymaster that pays for this request.\n * @param nonce - the nonce value from the request.\n * @param success - true if the sender transaction succeeded, false if reverted.\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\n */\n event UserOperationEvent(\n bytes32 indexed userOpHash,\n address indexed sender,\n address indexed paymaster,\n uint256 nonce,\n bool success,\n uint256 actualGasCost,\n uint256 actualGasUsed\n );\n\n /**\n * account \"sender\" was deployed.\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\n * @param sender the account that is deployed\n * @param factory the factory used to deploy this account (in the initCode)\n * @param paymaster the paymaster used by this UserOp\n */\n event AccountDeployed(\n bytes32 indexed userOpHash,\n address indexed sender,\n address factory,\n address paymaster\n );\n\n /**\n * An event emitted if the UserOperation \"callData\" reverted with non-zero length\n * @param userOpHash the request unique identifier.\n * @param sender the sender of this request\n * @param nonce the nonce used in the request\n * @param revertReason - the return bytes from the (reverted) call to \"callData\".\n */\n event UserOperationRevertReason(\n bytes32 indexed userOpHash,\n address indexed sender,\n uint256 nonce,\n bytes revertReason\n );\n\n /**\n * an event emitted by handleOps(), before starting the execution loop.\n * any event emitted before this event, is part of the validation.\n */\n event BeforeExecution();\n\n /**\n * signature aggregator used by the following UserOperationEvents within this bundle.\n */\n event SignatureAggregatorChanged(address indexed aggregator);\n\n /**\n * a custom revert error of handleOps, to identify the offending op.\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\n * @param reason - revert reason\n * The string starts with a unique code \"AAmn\", where \"m\" is \"1\" for factory, \"2\" for account and \"3\" for paymaster issues,\n * so a failure can be attributed to the correct entity.\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\n */\n error FailedOp(uint256 opIndex, string reason);\n\n /**\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\n */\n error SignatureValidationFailed(address aggregator);\n\n /**\n * Successful result from simulateValidation.\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n */\n error ValidationResult(\n ReturnInfo returnInfo,\n StakeInfo senderInfo,\n StakeInfo factoryInfo,\n StakeInfo paymasterInfo\n );\n\n /**\n * Successful result from simulateValidation, if the account returns a signature aggregator\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\n * bundler MUST use it to verify the signature, or reject the UserOperation\n */\n error ValidationResultWithAggregation(\n ReturnInfo returnInfo,\n StakeInfo senderInfo,\n StakeInfo factoryInfo,\n StakeInfo paymasterInfo,\n AggregatorStakeInfo aggregatorInfo\n );\n\n /**\n * return value of getSenderAddress\n */\n error SenderAddressResult(address sender);\n\n /**\n * return value of simulateHandleOp\n */\n error ExecutionResult(\n uint256 preOpGas,\n uint256 paid,\n uint48 validAfter,\n uint48 validUntil,\n bool targetSuccess,\n bytes targetResult\n );\n\n //UserOps handled, per aggregator\n struct UserOpsPerAggregator {\n UserOperation[] userOps;\n // aggregator address\n IAggregator aggregator;\n // aggregated signature\n bytes signature;\n }\n\n /**\n * Execute a batch of UserOperation.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(\n UserOperation[] calldata ops,\n address payable beneficiary\n ) external;\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) external;\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(\n UserOperation calldata userOp\n ) external view returns (bytes32);\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external;\n\n /**\n * gas and return values during simulation\n * @param preOpGas the gas used for validation (including preValidationGas)\n * @param prefund the required prefund for this operation\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\n */\n struct ReturnInfo {\n uint256 preOpGas;\n uint256 prefund;\n bool sigFailed;\n uint48 validAfter;\n uint48 validUntil;\n bytes paymasterContext;\n }\n\n /**\n * returned aggregated signature info.\n * the aggregator returned by the account, and its current stake.\n */\n struct AggregatorStakeInfo {\n address aggregator;\n StakeInfo stakeInfo;\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes memory initCode) external;\n\n /**\n * simulate full execution of a UserOperation (including both validation and target execution)\n * this method will always revert with \"ExecutionResult\".\n * it performs full validation of the UserOperation, but ignores signature error.\n * an optional target address is called after the userop succeeds, and its value is returned\n * (before the entire call is reverted)\n * Note that in order to collect the the success/failure of the target call, it must be executed\n * with trace enabled to track the emitted events.\n * @param op the UserOperation to simulate\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\n * are set to the return from that call.\n * @param targetCallData callData to pass to target address\n */\n function simulateHandleOp(\n UserOperation calldata op,\n address target,\n bytes calldata targetCallData\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/INonceManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\ninterface INonceManager {\n /**\n * Return the next nonce for this sender.\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\n * But UserOp with different keys can come with arbitrary order.\n *\n * @param sender the account address\n * @param key the high 192 bit of the nonce\n * @return nonce a full nonce to pass for next UserOp with this sender.\n */\n function getNonce(\n address sender,\n uint192 key\n ) external view returns (uint256 nonce);\n\n /**\n * Manually increment the nonce of the sender.\n * This method is exposed just for completeness..\n * Account does NOT need to call it, neither during validation, nor elsewhere,\n * as the EntryPoint will update the nonce regardless.\n * Possible use-case is call it with various keys to \"initialize\" their nonces to one, so that future\n * UserOperations will not pay extra for the first transaction with a given key.\n */\n function incrementNonce(uint192 key) external;\n}\n" + }, + "contracts/aa-4337/interfaces/IPaymaster.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * the interface exposed by a paymaster contract, who agrees to pay the gas for user's operations.\n * a paymaster must hold a stake to cover the required entrypoint stake and also the gas for the transaction.\n */\ninterface IPaymaster {\n enum PostOpMode {\n opSucceeded, // user op succeeded\n opReverted, // user op reverted. still has to pay for gas.\n postOpReverted //user op succeeded, but caused postOp to revert. Now it's a 2nd call, after user's op was deliberately reverted.\n }\n\n /**\n * payment validation: check if paymaster agrees to pay.\n * Must verify sender is the entryPoint.\n * Revert to reject this request.\n * Note that bundlers will reject this method if it changes the state, unless the paymaster is trusted (whitelisted)\n * The paymaster pre-pays using its deposit, and receive back a refund after the postOp method returns.\n * @param userOp the user operation\n * @param userOpHash hash of the user's request data.\n * @param maxCost the maximum cost of this transaction (based on maximum gas and gas price from userOp)\n * @return context value to send to a postOp\n * zero length to signify postOp is not required.\n * @return validationData signature and time-range of this operation, encoded the same as the return value of validateUserOperation\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validatePaymasterUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 maxCost\n ) external returns (bytes memory context, uint256 validationData);\n\n /**\n * post-operation handler.\n * Must verify sender is the entryPoint\n * @param mode enum with the following options:\n * opSucceeded - user operation succeeded.\n * opReverted - user op reverted. still has to pay for gas.\n * postOpReverted - user op succeeded, but caused postOp (in mode=opSucceeded) to revert.\n * Now this is the 2nd call, after user's op was deliberately reverted.\n * @param context - the context value returned by validatePaymasterUserOp\n * @param actualGasCost - actual gas used so far (without this postOp call).\n */\n function postOp(\n PostOpMode mode,\n bytes calldata context,\n uint256 actualGasCost\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/IStakeManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.12;\n\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by the staked entity.\n */\ninterface IStakeManager {\n event Deposited(address indexed account, uint256 totalDeposit);\n\n event Withdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /// Emitted when stake or unstake delay are modified\n event StakeLocked(\n address indexed account,\n uint256 totalStaked,\n uint256 unstakeDelaySec\n );\n\n /// Emitted once a stake is scheduled for withdrawal\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\n\n event StakeWithdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /**\n * @param deposit the entity's deposit\n * @param staked true if this entity is staked.\n * @param stake actual amount of ether staked for this entity.\n * @param unstakeDelaySec minimum delay to withdraw the stake.\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\n * and the rest fit into a 2nd cell.\n * 112 bit allows for 10^15 eth\n * 48 bit for full timestamp\n * 32 bit allows 150 years for unstake delay\n */\n struct DepositInfo {\n uint112 deposit;\n bool staked;\n uint112 stake;\n uint32 unstakeDelaySec;\n uint48 withdrawTime;\n }\n\n //API struct used by getStakeInfo and simulateValidation\n struct StakeInfo {\n uint256 stake;\n uint256 unstakeDelaySec;\n }\n\n /// @return info - full deposit information of given account\n function getDepositInfo(\n address account\n ) external view returns (DepositInfo memory info);\n\n /// @return the deposit (for gas payment) of the account\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) external payable;\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 _unstakeDelaySec) external payable;\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external;\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external;\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(\n address payable withdrawAddress,\n uint256 withdrawAmount\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/UserOperation.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable no-inline-assembly */\n\nimport {calldataKeccak} from \"../core/Helpers.sol\";\n\n/**\n * User Operation struct\n * @param sender the sender account of this request.\n * @param nonce unique value the sender uses to verify it is not a replay.\n * @param initCode if set, the account contract will be created by this constructor/\n * @param callData the method call to execute on this account.\n * @param callGasLimit the gas limit passed to the callData method call.\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\n * @param maxFeePerGas same as EIP-1559 gas parameter.\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\n */\nstruct UserOperation {\n address sender;\n uint256 nonce;\n bytes initCode;\n bytes callData;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n bytes paymasterAndData;\n bytes signature;\n}\n\n/**\n * Utility functions helpful when working with UserOperation structs.\n */\nlibrary UserOperationLib {\n function getSender(\n UserOperation calldata userOp\n ) internal pure returns (address) {\n address data;\n //read sender from userOp, which is first userOp member (saves 800 gas...)\n assembly {\n data := calldataload(userOp)\n }\n return address(uint160(data));\n }\n\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\n // pay above what he signed for.\n function gasPrice(\n UserOperation calldata userOp\n ) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function pack(\n UserOperation calldata userOp\n ) internal pure returns (bytes memory ret) {\n address sender = getSender(userOp);\n uint256 nonce = userOp.nonce;\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\n bytes32 hashCallData = calldataKeccak(userOp.callData);\n uint256 callGasLimit = userOp.callGasLimit;\n uint256 verificationGasLimit = userOp.verificationGasLimit;\n uint256 preVerificationGas = userOp.preVerificationGas;\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\n\n return\n abi.encode(\n sender,\n nonce,\n hashInitCode,\n hashCallData,\n callGasLimit,\n verificationGasLimit,\n preVerificationGas,\n maxFeePerGas,\n maxPriorityFeePerGas,\n hashPaymasterAndData\n );\n }\n\n function hash(\n UserOperation calldata userOp\n ) internal pure returns (bytes32) {\n return keccak256(pack(userOp));\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n}\n" + }, + "contracts/aa-4337/utils/Exec.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.5 <0.9.0;\n\n// solhint-disable no-inline-assembly\n\n/**\n * Utility functions helpful when making different kinds of contract calls in Solidity.\n */\nlibrary Exec {\n function call(\n address to,\n uint256 value,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := call(\n txGas,\n to,\n value,\n add(data, 0x20),\n mload(data),\n 0,\n 0\n )\n }\n }\n\n function staticcall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal view returns (bool success) {\n assembly {\n success := staticcall(txGas, to, add(data, 0x20), mload(data), 0, 0)\n }\n }\n\n function delegateCall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := delegatecall(\n txGas,\n to,\n add(data, 0x20),\n mload(data),\n 0,\n 0\n )\n }\n }\n\n // get returned data from last call or calldelegate\n function getReturnData(\n uint256 maxLen\n ) internal pure returns (bytes memory returnData) {\n assembly {\n let len := returndatasize()\n if gt(len, maxLen) {\n len := maxLen\n }\n let ptr := mload(0x40)\n mstore(0x40, add(ptr, add(len, 0x20)))\n mstore(ptr, len)\n returndatacopy(add(ptr, 0x20), 0, len)\n returnData := ptr\n }\n }\n\n // revert with explicit byte array (probably reverted info from call)\n function revertWithData(bytes memory returnData) internal pure {\n assembly {\n revert(add(returnData, 32), mload(returnData))\n }\n }\n\n function callAndRevert(\n address to,\n bytes memory data,\n uint256 maxLen\n ) internal {\n bool success = call(to, 0, data, gasleft());\n if (!success) {\n revertWithData(getReturnData(maxLen));\n }\n }\n}\n" + }, + "contracts/Barz.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"./libraries/LibDiamond.sol\";\nimport {IBarz} from \"./interfaces/IBarz.sol\";\n\n/**\n * @title Barz\n * @dev A diamond proxy wallet with a modular & upgradeable architecture\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract Barz is IBarz {\n /**\n * @notice Initializes Barz with the given parameters. Barz account is intended to be created from Barz Factory for stable deployment.\n * @dev This method makes a delegate call to account facet and account facet handles the initialization.\n * With modular architecture, Barz encompasses wide spectrum of architecture and logic.\n * The only requirement is account facet to comply with initialize() interface.\n * Barz doesn't include built-in functions and is a full proxy, for maximum extensibility and modularity.\n * @param _accountFacet Address of Account Facet in charge of the Barz initialization\n * @param _verificationFacet Address of Verification Facet for verifying the signature. Could be any signature scheme\n * @param _entryPoint Address of Entry Point contract\n * @param _facetRegistry Address of Facet Registry. Facet Registry is a registry holding trusted facets that could be added to user's wallet\n * @param _defaultFallBack Address of Default FallBack Handler. Middleware contract for more efficient deployment\n * @param _ownerPublicKey Bytes of Owner Public Key using for initialization\n */\n constructor(\n address _accountFacet,\n address _verificationFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallBack,\n bytes memory _ownerPublicKey\n ) payable {\n bytes memory initCall = abi.encodeWithSignature(\n \"initialize(address,address,address,address,bytes)\",\n _verificationFacet,\n _entryPoint,\n _facetRegistry,\n _defaultFallBack,\n _ownerPublicKey\n );\n (bool success, bytes memory result) = _accountFacet.delegatecall(\n initCall\n );\n if (!success || uint256(bytes32(result)) != 1) {\n revert Barz__InitializationFailure();\n }\n }\n\n /**\n * @notice Fallback function for Barz complying with Diamond Standard with customization of adding Default Fallback Handler\n * @dev Find facet for function that is called and execute the function if a facet is found and return any value.\n */\n fallback() external payable {\n LibDiamond.DiamondStorage storage ds;\n bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION;\n // get diamond storage\n assembly {\n ds.slot := position\n }\n // get facet from function selector\n address facet = address(bytes20(ds.facets[msg.sig]));\n if (facet == address(0))\n facet = ds.defaultFallbackHandler.facetAddress(msg.sig);\n require(facet != address(0), \"Barz: Function does not exist\");\n // Execute external function from facet using delegatecall and return any value.\n assembly {\n // copy function selector and any arguments\n calldatacopy(0, 0, calldatasize())\n // execute function call using the facet\n let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)\n // get any return value\n returndatacopy(0, 0, returndatasize())\n // return any return value or error back to the caller\n switch result\n case 0 {\n revert(0, returndatasize())\n }\n default {\n return(0, returndatasize())\n }\n }\n }\n\n /**\n * @notice Receive function to receive native token without data\n */\n receive() external payable {}\n}\n" + }, + "contracts/BarzFactory.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Barz} from \"./Barz.sol\";\nimport {IBarzFactory} from \"./interfaces/IBarzFactory.sol\";\n\n/**\n * @title Barz Factory\n * @dev Contract to easily deploy Barz to a pre-computed address with a single call\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract BarzFactory is IBarzFactory {\n address public immutable accountFacet;\n address public immutable entryPoint;\n address public immutable facetRegistry;\n address public immutable defaultFallback;\n\n /**\n * @notice Sets the initialization data for Barz contract initialization\n * @param _accountFacet Account Facet to be used to create Barz\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\n * @param _facetRegistry Facet Registry to be used to create Barz\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\n */\n constructor(\n address _accountFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallback\n ) {\n accountFacet = _accountFacet;\n entryPoint = _entryPoint;\n facetRegistry = _facetRegistry;\n defaultFallback = _defaultFallback;\n }\n\n /**\n * @notice Creates the Barz with a single call. It creates the Barz contract with the givent verification facet\n * @param _verificationFacet Address of verification facet used for creating the barz account\n * @param _owner Public Key of the owner to initialize barz account\n * @param _salt Salt used for deploying barz with create2\n * @return barz Instance of Barz contract deployed with the given parameters\n */\n function createAccount(\n address _verificationFacet,\n bytes calldata _owner,\n uint256 _salt\n ) external override returns (Barz barz) {\n address addr = getAddress(_verificationFacet, _owner, _salt);\n uint codeSize = addr.code.length;\n if (codeSize > 0) {\n return Barz(payable(addr));\n }\n barz = new Barz{salt: bytes32(_salt)}(\n accountFacet,\n _verificationFacet,\n entryPoint,\n facetRegistry,\n defaultFallback,\n _owner\n );\n emit BarzDeployed(address(barz));\n }\n\n /**\n * @notice Calculates the address of Barz with the given parameters\n * @param _verificationFacet Address of verification facet used for creating the barz account\n * @param _owner Public Key of the owner to initialize barz account\n * @param _salt Salt used for deploying barz with create2\n * @return barzAddress Precalculated Barz address\n */\n function getAddress(\n address _verificationFacet,\n bytes calldata _owner,\n uint256 _salt\n ) public view override returns (address barzAddress) {\n bytes memory bytecode = getBytecode(\n accountFacet,\n _verificationFacet,\n entryPoint,\n facetRegistry,\n defaultFallback,\n _owner\n );\n bytes32 hash = keccak256(\n abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(bytecode)\n )\n );\n barzAddress = address(uint160(uint256(hash)));\n }\n\n /**\n * @notice Returns the bytecode of Barz with the given parameter\n * @param _accountFacet Account Facet to be used to create Barz\n * @param _verificationFacet Verification Facet to be used to create Barz\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\n * @param _facetRegistry Facet Registry to be used to create Barz\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\n * @param _ownerPublicKey Public Key of owner to be used to initialize Barz ownership\n * @return barzBytecode Bytecode of Barz\n */\n function getBytecode(\n address _accountFacet,\n address _verificationFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallback,\n bytes calldata _ownerPublicKey\n ) public pure override returns (bytes memory barzBytecode) {\n bytes memory bytecode = type(Barz).creationCode;\n barzBytecode = abi.encodePacked(\n bytecode,\n abi.encode(\n _accountFacet,\n _verificationFacet,\n _entryPoint,\n _facetRegistry,\n _defaultFallback,\n _ownerPublicKey\n )\n );\n }\n\n /**\n * @notice Returns the creation code of the Barz contract\n * @return creationCode Creation code of Barz\n */\n function getCreationCode()\n public\n pure\n override\n returns (bytes memory creationCode)\n {\n creationCode = type(Barz).creationCode;\n }\n}\n" + }, + "contracts/facets/AccountFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {UserOperation} from \"../aa-4337/interfaces/UserOperation.sol\";\nimport {IEntryPoint} from \"../aa-4337/interfaces/IEntryPoint.sol\";\nimport {BaseAccount} from \"../aa-4337/core/BaseAccount.sol\";\nimport {LibAppStorage, BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {IFacetRegistry} from \"../infrastructure/interfaces/IFacetRegistry.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {IERC1271} from \"../interfaces/ERC/IERC1271.sol\";\nimport {IAccountFacet} from \"./interfaces/IAccountFacet.sol\";\n\n/**\n * @title Account Facet\n * @dev Account module contract that provides the account features and initialization of signer\n * compatible with EIP-1271 & EIP-4337\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract AccountFacet is IAccountFacet, BarzStorage, BaseAccount {\n using ECDSA for bytes32;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceAccountInitialize();\n }\n\n /**\n * @notice Returns the address of EntryPoint contract registered to Barz account\n */\n function entryPoint() public view override returns (IEntryPoint) {\n return s.entryPoint;\n }\n\n /**\n * @notice Initializes the initial storage of the Barz contract.\n * @dev This method can only be called during the initialization or signature migration.\n * If the proxy contract was created without initialization, anyone can call initialize.\n * Barz calls initialize in constructor in an atomic transaction during deployment\n * @param _verificationFacet Facet contract handling the verificationi\n * @param _anEntryPoint Entrypoint contract defined in EIP-4337 handling the flow of UserOp\n * @param _facetRegistry Registry of Facets that hold all facet information\n * @param _defaultFallBackHandler Middleware contract for default facets\n * @param _ownerPublicKey Bytes of owner public key\n */\n function initialize(\n address _verificationFacet,\n address _anEntryPoint,\n address _facetRegistry,\n address _defaultFallBackHandler,\n bytes calldata _ownerPublicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceAccountInitialize();\n s.entryPoint = IEntryPoint(_anEntryPoint);\n s.facetRegistry = IFacetRegistry(_facetRegistry);\n LibDiamond.diamondStorage().defaultFallbackHandler = IDiamondLoupe(\n _defaultFallBackHandler\n );\n\n _cutDiamondAccountFacet(_verificationFacet);\n\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n _ownerPublicKey\n );\n // Every Verification Facet should comply with initializeSigner(bytes)\n // to be compatible with the Barz contract(for initialization)\n (bool success, bytes memory result) = _verificationFacet.delegatecall(\n initCall\n );\n if (!success || uint256(bytes32(result)) != 1) {\n revert AccountFacet__InitializationFailure();\n }\n\n initSuccess = 1;\n emit AccountInitialized(s.entryPoint, _ownerPublicKey);\n }\n\n function _cutDiamondAccountFacet(address _verificationFacet) internal {\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](1);\n\n bytes4 ownerVerificationFuncSelector = IVerificationFacet(\n _verificationFacet\n ).validateOwnerSignatureSelector();\n\n bytes4[] memory verificationFunctionSelectors = new bytes4[](3);\n verificationFunctionSelectors[0] = IERC1271.isValidSignature.selector;\n verificationFunctionSelectors[1] = ownerVerificationFuncSelector;\n verificationFunctionSelectors[2] = IVerificationFacet.owner.selector;\n cut[0] = IDiamondCut.FacetCut({\n facetAddress: _verificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: verificationFunctionSelectors\n });\n\n LibDiamond.diamondCut(cut, address(0), \"\");\n }\n\n /**\n * @notice Calls the destination with inputted calldata and value from EntryPoint\n * @dev This method executes the calldata coming from the EntryPoint.\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\n * @param _dest Address of destination where the call will be forwarded to\n * @param _value Amount of native coin the owner is willing to send(e.g. ETH, BNB)\n * @param _func Bytes of calldata to execute in the destination address\n */\n function execute(\n address _dest,\n uint256 _value,\n bytes calldata _func\n ) external override onlyWhenUnlocked {\n _requireFromEntryPoint();\n address restrictionsFacet = LibDiamond.restrictionsFacet();\n if (restrictionsFacet == address(0)) _call(_dest, _value, _func);\n else _callWithRestrictions(_dest, _value, _func, restrictionsFacet);\n }\n\n /**\n * @notice Batch calls the destination with inputted calldata and value from EntryPoint\n * @dev This method batch executes the calldata coming from the EntryPoint.\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\n * @param _dest Array of addresses of destination where the call will be forwarded to\n * @param _value Array of amount of native coin the owner is willing to send(e.g. ETH, BNB)\n * @param _func Array of bytes of calldata to execute in the destination address\n */\n function executeBatch(\n address[] calldata _dest,\n uint256[] calldata _value,\n bytes[] calldata _func\n ) external override onlyWhenUnlocked {\n _requireFromEntryPoint();\n if (_dest.length != _func.length || _dest.length != _value.length)\n revert AccountFacet__InvalidArrayLength();\n address restrictionsFacet = LibDiamond.restrictionsFacet();\n if (restrictionsFacet == address(0)) {\n for (uint256 i; i < _dest.length; ) {\n _call(_dest[i], _value[i], _func[i]);\n unchecked {\n ++i;\n }\n }\n } else {\n for (uint256 i; i < _dest.length; ) {\n _callWithRestrictions(\n _dest[i],\n _value[i],\n _func[i],\n restrictionsFacet\n );\n unchecked {\n ++i;\n }\n }\n }\n }\n\n /**\n * @notice Validates the signature field of UserOperation\n * @dev This method validates if the signature of UserOp is indeed valid by delegating the call to Verification Facet\n * Barz makes a call to the pre-registered Verification Facet address in App Storage\n * @param _userOp UserOperation from owner to be validated\n * @param _userOpHash Hash of UserOperation given from the EntryPoint contract\n */\n function _validateSignature(\n UserOperation calldata _userOp,\n bytes32 _userOpHash\n ) internal override returns (uint256 validationData) {\n // Get Facet with Function Selector\n address facet = LibLoupe.facetAddress(s.validateOwnerSignatureSelector);\n if (facet == address(0))\n revert AccountFacet__NonExistentVerificationFacet();\n\n // Make function call to VerificationFacet\n bytes memory validateCall = abi.encodeWithSelector(\n s.validateOwnerSignatureSelector,\n _userOp,\n _userOpHash\n );\n (bool success, bytes memory result) = facet.delegatecall(validateCall);\n if (!success) revert AccountFacet__CallNotSuccessful();\n validationData = uint256(bytes32(result));\n if (validationData == 0) emit VerificationSuccess(_userOpHash);\n else emit VerificationFailure(_userOpHash);\n }\n\n /**\n * @notice Calls the target with the inputted value and calldata\n * @dev This method is the actual function in Barz that makes a call with an arbitrary owner-given data\n * @param _target Address of the destination contract which the call is getting forwarded to\n * @param _value Amount of Native coin the owner is wanting to make in this call\n * @param _data Calldata the owner is forwarding together in the call e.g. Swap/Token Transfer\n */\n function _call(\n address _target,\n uint256 _value,\n bytes memory _data\n ) internal {\n (bool success, bytes memory result) = _target.call{value: _value}(\n _data\n );\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n }\n\n /**\n * @notice Calls the target with the inputted value and calldata together with restrictions check\n * @dev This method is the actual function in Barz that makes a call with an arbitrary owner-given data\n * @param _target Address of the destination contract which the call is getting forwarded to\n * @param _value Amount of Native coin the owner is wanting to make in this call\n * @param _data Calldata the owner is forwarding together in the call e.g. Swap/Token Transfer\n * @param _restrictionsFacet Address of Facet to validate restrictions\n */\n function _callWithRestrictions(\n address _target,\n uint256 _value,\n bytes memory _data,\n address _restrictionsFacet\n ) internal {\n // NOTE: No restrictions facet, so restriction validation passes\n if (_checkRestrictions(_restrictionsFacet, _target, _value, _data) != 0)\n revert AccountFacet__RestrictionsFailure();\n\n (bool success, bytes memory result) = _target.call{value: _value}(\n _data\n );\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n }\n\n /**\n * @notice Checks restrictions if the restrictions facet exists\n * @dev This method checks if the restrictions facet exists and makes a verification call to an array of restrictions facet\n * @param _facet Address that holds the restrictions logic\n * @param _target Address the call is getting forwarded to\n * @param _value Amount of native coin the call is sending together with the call\n * @param _data Calldata to trigger execution in target address\n */\n function _checkRestrictions(\n address _facet,\n address _target,\n uint256 _value,\n bytes memory _data\n ) internal returns (uint256 result) {\n bytes memory call = abi.encodeWithSignature(\n \"verifyRestrictions(address,address,uint256,bytes)\",\n address(this),\n _target,\n _value,\n _data\n );\n (bool success, bytes memory response) = _facet.delegatecall(call);\n if (!success) revert AccountFacet__RestrictionsFailure();\n result = uint256(bytes32(response));\n }\n}\n" + }, + "contracts/facets/AccountRecoveryFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibFacetStorage, RecoveryStorage, RecoveryConfig, RecoveryApprovalConfig, ApprovalConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {IAccountRecoveryFacet} from \"./interfaces/IAccountRecoveryFacet.sol\";\n\n/**\n * @title Account Recovery Facet\n * @dev Contract that enables recovery of accounts when owner key is unavailable\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract AccountRecoveryFacet is IAccountRecoveryFacet, Modifiers {\n bytes constant UNINIT_CALL =\n abi.encodeWithSignature(\"uninitializeSigner()\");\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Approve recovery of account as guardian\n * @dev This method can only be called by guardian and guardian inputs the public key of the new owner\n * When the threshold(majority of guardians) passes, it automatically executes account recovery\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function approveAccountRecovery(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + _getApprovalValidationPeriod()\n );\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit RecoveryApproved(\n _recoveryPublicKey,\n msg.sender,\n approvalValidUntil\n );\n if (\n getRecoveryApprovalCountWithTimeValidity(recoveryPublicKeyHash) >=\n LibGuardian.majorityOfGuardians()\n ) _executeRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Revoke recovery of account as guardian\n * @dev This method can only be called by guardian and guardian inputs the public key of the new owner\n When the threshold(majority of guardians) passes, it automatically revokes account recovery when recovery is pending\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function revokeAccountRecoveryApproval(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n if (\n !rs\n .isNewOwnerApproved[recoveryPublicKeyHash][msg.sender].isApproved ||\n !(block.timestamp <\n rs\n .isNewOwnerApproved[recoveryPublicKeyHash][msg.sender]\n .validUntil)\n ) revert AccountRecoveryFacet__NonExistentApproval();\n\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(false, 0);\n emit RecoveryApprovalRevoked(_recoveryPublicKey, msg.sender);\n }\n\n /**\n * @notice Executes recovery with signatures or on-chain pre-approvals\n * @dev This method validates the signatures of guardians or checks the on-chain pre-approved calls to check if the threshold passes\n * When the threshold passes, account recovery is executed and revert otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _guardians Array of guardians address that are approving the recovery of Account\n * @param _signatures Array of signature bytes that signed the approval hash\n */\n function executeRecovery(\n bytes calldata _recoveryPublicKey,\n address[] calldata _guardians,\n bytes[] calldata _signatures\n ) external override {\n if (_isRecoveryPending())\n revert AccountRecoveryFacet__RecoveryAlreadyOngoing();\n if (_guardians.length != _signatures.length)\n revert AccountRecoveryFacet__InvalidArrayLength();\n validateNewOwner(_recoveryPublicKey);\n\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n\n _checkApprover(_guardians);\n _checkDuplicateOnChainApprover(recoveryPublicKeyHash, _guardians);\n\n if (\n _guardians.length +\n getRecoveryApprovalCountWithTimeValidity(\n recoveryPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians()\n ) revert AccountRecoveryFacet__InsufficientGuardians();\n for (uint256 i; i < _guardians.length; ) {\n if (!LibGuardian.isGuardian(_guardians[i]))\n revert AccountRecoveryFacet__InvalidGuardian();\n if (\n !SignatureChecker.isValidSignatureNow(\n _guardians[i],\n recoveryPublicKeyHash,\n _signatures[i]\n )\n ) revert AccountRecoveryFacet__InvalidGuardianSignature();\n unchecked {\n ++i;\n }\n }\n _executeRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Executes recovery of the account. Note that execution and finalization is a different process\n * @dev Executes the recovery and adds recovery data to recovery configuration. Locks the account\n * @param _recoveryPublicKey Public Key of the account for recovery\n */\n function _executeRecovery(bytes memory _recoveryPublicKey) internal {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n unchecked {\n ++rs.nonce;\n }\n uint64 executeAfter = uint64(block.timestamp + _getRecoveryPeriod());\n rs.recoveryConfigs[INNER_STRUCT] = RecoveryConfig(\n _recoveryPublicKey,\n executeAfter // NOTE: Remove guardian Count\n );\n LibAppStorage.setLock(\n block.timestamp + _getLockPeriod(),\n AccountRecoveryFacet.executeRecovery.selector\n );\n emit RecoveryExecuted(_recoveryPublicKey, executeAfter);\n }\n\n /**\n * @notice Finalize recovery after recovery pending period. Recovery pending period can be set by user beforehand in SecurityManager\n * @dev This method finalizes recovery and fully changes the ownership of the account to the newly inputted recovery public key\n */\n function finalizeRecovery() external override {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n if (\n uint64(block.timestamp) <=\n rs.recoveryConfigs[INNER_STRUCT].executeAfter\n ) revert AccountRecoveryFacet__RecoveryPeriodNotOver();\n bytes memory recoveryOwner = rs\n .recoveryConfigs[INNER_STRUCT]\n .recoveryPublicKey;\n\n delete rs.recoveryConfigs[INNER_STRUCT];\n\n LibAppStorage.setLock(0, bytes4(0));\n\n LibAppStorage.initiateSignerMigration();\n address verificationFacet = address(\n bytes20(\n LibDiamond.diamondStorage().facets[\n s.validateOwnerSignatureSelector\n ]\n )\n );\n (bool uninitSuccess, bytes memory uninitResult) = verificationFacet\n .delegatecall(UNINIT_CALL);\n if (!uninitSuccess) revert AccountRecoveryFacet__CallNotSuccesful();\n if (uint256(bytes32(uninitResult)) != 1)\n revert AccountRecoveryFacet__SignerUninitializationFailure();\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n recoveryOwner\n );\n (bool initSuccess, bytes memory initResult) = verificationFacet\n .delegatecall(initCall);\n if (!initSuccess) revert AccountRecoveryFacet__CallNotSuccesful();\n if (uint256(bytes32(initResult)) != 1)\n revert AccountRecoveryFacet__SignerInitializationFailure();\n LibAppStorage.finalizeSignerMigration();\n emit RecoveryFinalized(recoveryOwner);\n }\n\n /**\n * @notice Approves the cancellation of recovery\n * @dev This method approves the cancellation of recovery when recovery is still pending - waiting for finalization\n * @param _recoveryPublicKey Bytes of public key which is pending for recovery\n */\n function approveCancelRecovery(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"CancelRecovery\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + _getApprovalValidationPeriod()\n );\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit RecoveryCancellationApproved(_recoveryPublicKey, msg.sender);\n if (\n getRecoveryApprovalCountWithTimeValidity(recoveryPublicKeyHash) >=\n LibGuardian.majorityOfGuardians()\n ) {\n _cancelRecovery(_recoveryPublicKey);\n }\n }\n\n /**\n * @notice Hardstops an ongoing recovery\n * @dev This method provides a safety mechanism to protect owners of malicious guardians.\n * Owners can hardstop recovery when an malicious guardians starts the recovery process.\n * @param _signature Signature of the owner that signs the hash to hardstop recovery\n */\n function hardstopRecovery(bytes calldata _signature) external override {\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n \"0\",\n \"HardstopRecovery\"\n );\n if (\n !SignatureChecker.isValidSignatureNow(\n address(this),\n recoveryPublicKeyHash,\n _signature\n )\n ) revert AccountRecoveryFacet__InvalidOwnerSignature();\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n unchecked {\n ++rs.nonce;\n }\n delete rs.recoveryConfigs[INNER_STRUCT];\n LibAppStorage.setLock(0, bytes4(0));\n emit RecoveryHardstopped();\n }\n\n /**\n * @notice Cancels recovery with signatures or on-chain pre-approvals\n * @dev This method validates the signatures of guardians or checks the on-chain pre-approved calls to check if the threshold passes\n * When the threshold passes, account recovery is canceled and revert otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _guardians Array of guardians address that are approving the recovery of Account\n * @param _signatures Array of signature bytes that signed the cancellation approval hash\n */\n function cancelRecovery(\n bytes calldata _recoveryPublicKey,\n address[] calldata _guardians,\n bytes[] calldata _signatures\n ) external override {\n if (_guardians.length != _signatures.length)\n revert AccountRecoveryFacet__InvalidArrayLength();\n validateNewOwner(_recoveryPublicKey);\n\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"CancelRecovery\"\n );\n\n _checkApprover(_guardians);\n _checkDuplicateOnChainApprover(recoveryPublicKeyHash, _guardians);\n\n if (\n _guardians.length +\n getRecoveryApprovalCountWithTimeValidity(\n recoveryPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians()\n ) revert AccountRecoveryFacet__InsufficientGuardians();\n for (uint256 i; i < _guardians.length; ) {\n if (!LibGuardian.isGuardian(_guardians[i]))\n revert AccountRecoveryFacet__CallerNotGuardian();\n if (\n !SignatureChecker.isValidSignatureNow(\n _guardians[i],\n recoveryPublicKeyHash,\n _signatures[i]\n )\n ) revert AccountRecoveryFacet__InvalidGuardianSignature();\n unchecked {\n ++i;\n }\n }\n _cancelRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Cancel recovery when the recovery is pending. Unlock the account as well\n * @dev This method checks if the recovery is pending and reverts if not pending.\n * It increases the recovery nonce and deletes the recovery information and gets a small portion of gas in return\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function _cancelRecovery(bytes memory _recoveryPublicKey) internal {\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n LibAppStorage.setLock(0, bytes4(0));\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n unchecked {\n ++rs.nonce;\n }\n delete rs.recoveryConfigs[INNER_STRUCT];\n emit RecoveryCanceled(_recoveryPublicKey);\n }\n\n /**\n * @notice Validates the format of public key to be used for recovery\n * @dev This method checks if the public key format is correct and reverts otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function validateNewOwner(\n bytes calldata _recoveryPublicKey\n ) public view override {\n if (\n !IVerificationFacet(\n LibLoupe.facetAddress(s.validateOwnerSignatureSelector)\n ).isValidKeyType(_recoveryPublicKey)\n ) revert AccountRecoveryFacet__InvalidRecoveryPublicKey();\n }\n\n /**\n * @notice Checks if recovery is currently pending\n * @return isPending Boolean indicating if recovery is pending\n */\n function _isRecoveryPending() internal view returns (bool isPending) {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n isPending = (rs.recoveryConfigs[INNER_STRUCT].executeAfter > 0);\n }\n\n /**\n * @notice Calculate the recovery hash dependent on chain, wallet address, nonce with EIP-191 prefix for safety\n * @dev Returns the keccak256 hash of EIP-191 msg hash packed with public key, salt, nonce, wallet address, etc\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _saltString Salt string to uniquely identify each recovery hash and for security\n * @return recoveryKeyHash Bytes32 string of the recovery hash\n */\n function getApprovalRecoveryKeyHash(\n bytes memory _recoveryPublicKey,\n string memory _saltString\n ) public view override returns (bytes32 recoveryKeyHash) {\n recoveryKeyHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n _recoveryPublicKey,\n _saltString,\n address(this),\n block.chainid,\n LibFacetStorage.recoveryStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Check the onchain approval of guardians and returns the number of guardians that approved\n * @dev Loop through the guardian addresses and returns the number of guardians that approved this recovery hash\n * @param _recoveryPublicKeyHash Bytes hash of newly recovered public key and recovery value of the account\n * @return approvalCount Number of guardians that approved\n */\n function getRecoveryApprovalCountWithTimeValidity(\n bytes32 _recoveryPublicKeyHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n for (uint256 i; i < guardianLength; ) {\n if (isRecoveryApproved(_recoveryPublicKeyHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Checks if the recovery is approved by the given approver\n * @param _recoveryPublicKeyHash Hash of the public key and configuration for recovery\n * @param _approver Address of approver\n * @return isApproved Bool value if recovery hash is approved\n */\n function isRecoveryApproved(\n bytes32 _recoveryPublicKeyHash,\n address _approver\n ) public view override returns (bool isApproved) {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n if (\n rs\n .isNewOwnerApproved[_recoveryPublicKeyHash][_approver].isApproved &&\n block.timestamp <\n rs.isNewOwnerApproved[_recoveryPublicKeyHash][_approver].validUntil\n ) {\n isApproved = true;\n }\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _recoveryPublicKeyHash Hash of recovery information\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _recoveryPublicKeyHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isRecoveryApproved(_recoveryPublicKeyHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert AccountRecoveryFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the lock period of this wallet address from security manager\n * @return lockPeriod value of lock period\n */\n function _getLockPeriod() internal view returns (uint256 lockPeriod) {\n lockPeriod = securityManager.lockPeriodOf(address(this));\n if (lockPeriod == 0) revert AccountRecoveryFacet__InvalidLockPeriod();\n }\n\n /**\n * @notice Returns the lock period of this wallet address from security manager\n * @return recoveryPeriod value of recovery period\n */\n function _getRecoveryPeriod()\n internal\n view\n returns (uint256 recoveryPeriod)\n {\n recoveryPeriod = securityManager.recoveryPeriodOf(address(this));\n if (recoveryPeriod == 0)\n revert AccountRecoveryFacet__InvalidRecoveryPeriod();\n }\n\n /**\n * @notice Returns the approval validation period of this wallet address from security manager\n * @return approvalValidationPeriod value of approval validation period\n */\n function _getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod == 0)\n revert AccountRecoveryFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the recovery nonce of this wallet address from security manager\n * @return nonce value of recovery nonce\n */\n function getRecoveryNonce() public view override returns (uint128 nonce) {\n nonce = LibFacetStorage.recoveryStorage().nonce;\n }\n\n /**\n * @notice Returns the recovery information of the pending recovery\n * @return recoveryConfig value struct of pending recovery\n */\n function getPendingRecovery()\n public\n view\n override\n returns (RecoveryConfig memory recoveryConfig)\n {\n recoveryConfig = LibFacetStorage.recoveryStorage().recoveryConfigs[\n INNER_STRUCT\n ];\n }\n}\n" + }, + "contracts/facets/base/DiamondCutFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibGuardian} from \"../../libraries/LibGuardian.sol\";\nimport {ISecurityManager} from \"../../infrastructure/interfaces/ISecurityManager.sol\";\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibFacetStorage, DiamondCutApprovalConfig, ApprovalConfig} from \"../../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"../Modifiers.sol\";\nimport {IDiamondCut} from \"./interfaces/IDiamondCut.sol\";\n\n/**\n * @title DiamondCut Facet\n * @dev Responsible for adding/removing/replace facets in Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DiamondCutFacet is Modifiers, IDiamondCut {\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Updates the flag for the interfaceId\n * @param _interfaceId InterfaceID to update the mapping\n * @param _flag Bool value to update the mapping of the given interface ID\n */\n function updateSupportsInterface(\n bytes4 _interfaceId,\n bool _flag\n ) external override onlyWhenUnlocked {\n LibDiamond.enforceIsSelf();\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId] = _flag;\n emit SupportsInterfaceUpdated(_interfaceId, _flag);\n }\n\n /**\n * @notice Add/replace/remove any number of functions and optionally execute\n * a function with delegatecall when guardians don't exist\n * @param _diamondCut Contains the facet addresses and function selectors\n * @param _init The address of the contract or facet to execute _calldata. It's prohibited in Barz\n */\n function diamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata\n ) external override onlyWhenUnlocked {\n LibDiamond.enforceIsSelf();\n\n _checkFacetCutValidity(_diamondCut);\n // require approval from guardian if guardian exists\n if (0 != LibGuardian.guardianCount())\n revert DiamondCutFacet__InvalidRouteWithGuardian();\n if (address(0) != _init) revert DiamondCutFacet__InvalidInitAddress();\n\n unchecked {\n ++LibFacetStorage.diamondCutStorage().nonce;\n }\n LibDiamond.diamondCut(_diamondCut, address(0), \"\");\n }\n\n /**\n * @notice Add/replace/remove any number of functions and optionally execute\n * a function with delegatecall when guardians exist\n * @param _diamondCut Contains the facet addresses and function selectors\n * @param _approvers Guardian or owner address that approves the diamond cut\n * @param _signatures Signature of Guardians or owner that approves the diamond cut\n */\n function diamondCutWithGuardian(\n FacetCut[] calldata _diamondCut,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n ) external override onlyWhenUnlocked {\n if (_approvers.length != _signatures.length)\n revert DiamondCutFacet__InvalidArrayLength();\n _checkFacetCutValidity(_diamondCut);\n if (0 == LibGuardian.guardianCount())\n revert DiamondCutFacet__InvalidRouteWithGuardian();\n\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(cutHash, _approvers);\n\n bool onChainOwnerApproval = getOwnerCutApprovalWithTimeValidity(\n cutHash\n );\n\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n if (\n _approvers.length +\n getDiamondCutApprovalCountWithTimeValidity(cutHash) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert DiamondCutFacet__InsufficientApprovers();\n\n bool ownerApproved;\n for (uint256 i; i < _approvers.length; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n _approvers[i] != address(this)\n ) revert DiamondCutFacet__InvalidApprover();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert DiamondCutFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n cutHash,\n _signatures[i]\n )\n ) revert DiamondCutFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n if (!ownerApproved && !onChainOwnerApproval)\n revert DiamondCutFacet__LackOfOwnerApproval();\n\n unchecked {\n ++LibFacetStorage.diamondCutStorage().nonce;\n }\n LibDiamond.diamondCut(_diamondCut, address(0), \"\");\n }\n\n /**\n * @notice Approves diamond cut. This can only be called directly from guardian or owner\n * @param _diamondCut Contains the facet addresses and function selectors\n */\n function approveDiamondCut(\n FacetCut[] calldata _diamondCut\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\n if (LibGuardian.guardianCount() == 0)\n revert DiamondCutFacet__InvalidRouteWithoutGuardian();\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n _checkFacetCutValidity(_diamondCut);\n\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(\n true,\n approvalValidUntil\n );\n emit DiamondCutApproved(_diamondCut);\n if (\n (getDiamondCutApprovalCountWithTimeValidity(cutHash) >=\n LibGuardian.majorityOfGuardians()) &&\n getOwnerCutApprovalWithTimeValidity(cutHash)\n ) {\n unchecked {\n ++LibFacetStorage.diamondCutStorage().nonce;\n }\n LibDiamond.diamondCut(_diamondCut, address(0), \"\");\n }\n }\n\n /**\n * @notice Revokes the approval of diamond cut. This can only be called directly from guardian or owner\n * @param _diamondCut Contains the facet addresses and function selectors\n */\n function revokeDiamondCutApproval(\n FacetCut[] calldata _diamondCut\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\n if (!ds.isDiamondCutApproved[cutHash][msg.sender].isApproved)\n revert DiamondCutFacet__CannotRevokeUnapproved();\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(false, 0);\n emit DiamondCutApprovalRevoked(_diamondCut);\n }\n\n /**\n * @notice Gets the number of approvals of diamond cut from guardians\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n */\n function getDiamondCutApprovalCountWithTimeValidity(\n bytes32 _diamondCutHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardiansLength = guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n if (isCutApproved(_diamondCutHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n return approvalCount;\n }\n\n /**\n * @notice Returns if the owner has approved the diamond cut\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @return isApprovedByOwner Bool value showing if the owner approved the cut\n */\n function getOwnerCutApprovalWithTimeValidity(\n bytes32 _diamondCutHash\n ) public view override returns (bool isApprovedByOwner) {\n isApprovedByOwner = isCutApproved(_diamondCutHash, address(this));\n }\n\n /**\n * @notice Returns if the given approver has approved the diamond cut\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @param _approver Address of approver\n * @return isApproved Bool value showing if the approver approved the cut\n */\n function isCutApproved(\n bytes32 _diamondCutHash,\n address _approver\n ) public view override returns (bool isApproved) {\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n isApproved = (ds\n .isDiamondCutApproved[_diamondCutHash][_approver].isApproved &&\n block.timestamp <\n ds.isDiamondCutApproved[_diamondCutHash][_approver].validUntil);\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _diamondCutHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isCutApproved(_diamondCutHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert DiamondCutFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the diamond cut hash. This function ensures that this hash is safe from replay attack by including\n * salt, address, chainId, and nonce, etc.\n * @param _diamondCut Contains the facet addresses and function selectors\n * @return cutHash Diamond Cut Hash\n */\n function getDiamondCutHash(\n FacetCut[] calldata _diamondCut\n ) public view override returns (bytes32 cutHash) {\n cutHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n keccak256(abi.encode(_diamondCut)),\n address(this),\n block.chainid,\n LibFacetStorage.diamondCutStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Returns the approval validation Period\n * @dev This method fetches the validation period from the security manager\n * @return approvalValidationPeriod Approval validation period of Barz contract fetched from security manager\n */\n function getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod <= 0)\n revert DiamondCutFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the diamond cut nonce of this wallet\n * @dev This method fetches the nonce from diamond cut storage\n * @return cutNonce Nonce of diamond cut to protect from reply attacks\n */\n function getDiamondCutNonce()\n public\n view\n override\n returns (uint128 cutNonce)\n {\n cutNonce = LibFacetStorage.diamondCutStorage().nonce;\n }\n}\n" + }, + "contracts/facets/base/DiamondLoupeFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {IERC165} from \"../../interfaces/ERC/IERC165.sol\";\nimport {IERC1271} from \"../../interfaces/ERC/IERC1271.sol\";\nimport {IERC677Receiver} from \"../../interfaces/ERC/IERC677Receiver.sol\";\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC1155Receiver} from \"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\";\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../../libraries/LibLoupe.sol\";\nimport {LibUtils} from \"../../libraries/LibUtils.sol\";\nimport {IDiamondCut} from \"../../facets/base/interfaces/IDiamondCut.sol\";\nimport {IStorageLoupe} from \"./interfaces/IStorageLoupe.sol\";\nimport {IDiamondLoupe} from \"./interfaces/IDiamondLoupe.sol\";\n\n/**\n * @title DiamondLoupe Facet\n * @dev DiamondLoupe contract compatible with EIP-2535\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DiamondLoupeFacet is IDiamondLoupe, IStorageLoupe, IERC165 {\n // Diamond Loupe Functions\n ////////////////////////////////////////////////////////////////////\n /// These functions are expected to be called frequently by tools off-chain.\n\n /**\n * @notice Gets all facets and their selectors.\n * @dev Barz uses a special architecture called default fallback handler. Default Fallback handler is used as a middleware\n * that holds the mapping of facet function selector and facet address that Barz uses. This helps Barz to reduce\n * significant amount of gas during the initialization process.\n * Hence, this method aggregates both the facet information from DefaulFallbackHandler and in diamond storage and shows the data to users.\n * @return facets_ Facet\n */\n function facets() public view override returns (Facet[] memory facets_) {\n Facet[] memory defaultFacet = LibDiamond\n .diamondStorage()\n .defaultFallbackHandler\n .facets();\n Facet[] memory _facets = LibLoupe.facets();\n uint256 numFacets = _facets.length;\n bytes4[] memory keys;\n address[] memory values;\n for (uint256 i; i < numFacets; ) {\n uint256 selectorsLength = _facets[i].functionSelectors.length;\n for (uint256 j; j < selectorsLength; ) {\n (keys, values) = LibUtils.setValue(\n keys,\n values,\n _facets[i].functionSelectors[j],\n _facets[i].facetAddress\n );\n unchecked {\n ++j;\n }\n }\n unchecked {\n ++i;\n }\n }\n {\n bool iIncrement;\n for (uint256 i; i < defaultFacet.length; ) {\n bool jIncrement;\n for (\n uint256 j;\n j < defaultFacet[i].functionSelectors.length;\n\n ) {\n if (\n LibUtils.getValue(\n keys,\n values,\n defaultFacet[i].functionSelectors[j]\n ) != address(0)\n ) {\n if (defaultFacet[i].functionSelectors.length == 1) {\n defaultFacet = LibUtils.removeFacetElement(\n defaultFacet,\n i\n );\n iIncrement = true;\n break;\n }\n defaultFacet[i].functionSelectors = LibUtils\n .removeElement(\n defaultFacet[i].functionSelectors,\n j\n );\n jIncrement = true;\n }\n if (!jIncrement) {\n unchecked {\n ++j;\n }\n } else {\n jIncrement = false;\n }\n }\n if (!iIncrement) {\n unchecked {\n ++i;\n }\n } else {\n iIncrement = false;\n }\n }\n }\n {\n uint256 facetLength = numFacets + defaultFacet.length;\n facets_ = new Facet[](facetLength);\n uint256 defaultFacetIndex;\n for (uint256 i; i < facetLength; ) {\n if (i < numFacets) {\n facets_[i] = _facets[i];\n bool jIncrementor;\n for (uint256 j; j < defaultFacet.length; ) {\n if (\n facets_[i].facetAddress ==\n defaultFacet[j].facetAddress\n ) {\n facets_[i].functionSelectors = LibUtils.mergeArrays(\n _facets[i].functionSelectors,\n defaultFacet[j].functionSelectors\n );\n defaultFacet = LibUtils.removeFacetElement(\n defaultFacet,\n j\n );\n jIncrementor = true;\n {\n facets_ = LibUtils.removeFacetElement(\n facets_,\n facets_.length - 1\n );\n }\n --facetLength;\n }\n if (!jIncrementor) {\n unchecked {\n ++j;\n }\n } else {\n jIncrementor = false;\n }\n }\n } else {\n facets_[i] = defaultFacet[defaultFacetIndex];\n ++defaultFacetIndex;\n }\n unchecked {\n ++i;\n }\n }\n }\n }\n\n /**\n * @notice Gets all the function selectors provided by a facet.\n * @param _facet The facet address.\n * @return facetFunctionSelectors_\n */\n function facetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n Facet[] memory facet = facets();\n uint256 facetLength = facet.length;\n for (uint256 i; i < facetLength; ) {\n if (facet[i].facetAddress == _facet)\n return facet[i].functionSelectors;\n unchecked {\n ++i;\n }\n }\n return facetFunctionSelectors_;\n }\n\n /**\n * @notice Get all the facet addresses used by Barz.\n * @return facetAddresses_\n */\n function facetAddresses()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n Facet[] memory facet = facets();\n uint256 facetLength = facet.length;\n facetAddresses_ = new address[](facetLength);\n for (uint256 i; i < facetLength; ) {\n facetAddresses_[i] = facet[i].facetAddress;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Gets the facet that supports the given selector.\n * @dev If facet is not found return address(0).\n * @param _functionSelector The function selector.\n * @return facetAddress_ The facet address.\n */\n function facetAddress(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n\n facetAddress_ = address(bytes20(ds.facets[_functionSelector]));\n if (facetAddress_ == address(0)) {\n facetAddress_ = IDiamondLoupe(ds.defaultFallbackHandler)\n .facetAddress(_functionSelector);\n }\n }\n\n /**\n * @notice SupportInterface to be compatible with EIP 165\n * @param _interfaceId Interface ID for detecting the interface\n * @return isSupported Bool value showing if the standard is supported in the contract\n */\n function supportsInterface(\n bytes4 _interfaceId\n ) external view override returns (bool isSupported) {\n isSupported =\n _interfaceId == type(IERC165).interfaceId ||\n _interfaceId == IDiamondCut.diamondCut.selector ||\n _interfaceId == type(IDiamondLoupe).interfaceId ||\n _interfaceId == type(IERC1155Receiver).interfaceId ||\n _interfaceId == type(IERC721Receiver).interfaceId ||\n _interfaceId == type(IERC777Recipient).interfaceId ||\n _interfaceId == IERC1271.isValidSignature.selector ||\n _interfaceId == type(IERC677Receiver).interfaceId ||\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId];\n }\n\n /**\n * @notice Returns the facet from the diamond storage. This excludes the facets from the default fallback handler\n * @return facets_ Facet information attached directly to diamond storage\n */\n function facetsFromStorage()\n external\n view\n override\n returns (Facet[] memory facets_)\n {\n facets_ = LibLoupe.facets();\n }\n\n /**\n * @notice Returns the facet address attached to the given function selector. This excludes the facets from the default fallback handler\n * @param _functionSelector Function selector to fetch the facet address from diamond storage\n * @return facetAddress_ Facet address mapped with the function selector\n */\n function facetAddressFromStorage(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n facetAddress_ = LibLoupe.facetAddress(_functionSelector);\n }\n\n /**\n * @notice Returns all facet addresses attached directly to diamond storage. This excludes the facets from the default fallback handler\n * @return facetAddresses_ All facet addresses attached directly to diamond storage\n */\n function facetAddressesFromStorage()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n facetAddresses_ = LibLoupe.facetAddresses();\n }\n\n /**\n * @notice Returns function selectors of given facet address attached directly to diamond storage. This excludes the facets from the default fallback handler\n * @param _facet Facet address to fetch the facet function selectors from diamond storage\n * @return facetFunctionSelectors_ Facet function selectors of the given facet address\n */\n function facetFunctionSelectorsFromStorage(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n facetFunctionSelectors_ = LibLoupe.facetFunctionSelectors(_facet);\n }\n}\n" + }, + "contracts/facets/base/interfaces/IDiamondCut.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title DiamondCut Facet Interface\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IDiamondCut {\n error DiamondCutFacet__InvalidRouteWithGuardian();\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\n error DiamondCutFacet__InvalidArrayLength();\n error DiamondCutFacet__InsufficientApprovers();\n error DiamondCutFacet__InvalidApprover();\n error DiamondCutFacet__InvalidApproverSignature();\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\n error DiamondCutFacet__CannotRevokeUnapproved();\n error DiamondCutFacet__LackOfOwnerApproval();\n error DiamondCutFacet__OwnerAlreadyApproved();\n error DiamondCutFacet__DuplicateApproval();\n error DiamondCutFacet__InvalidInitAddress();\n\n event DiamondCutApproved(FacetCut[] diamondCut);\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\n\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\n\n enum FacetCutAction {\n Add,\n Replace,\n Remove\n }\n // Add=0, Replace=1, Remove=2\n\n struct FacetCut {\n address facetAddress;\n FacetCutAction action;\n bytes4[] functionSelectors;\n }\n\n /// @notice Add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param diamondCut Contains the facet addresses and function selectors\n /// @param init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function diamondCut(\n FacetCut[] calldata diamondCut,\n address init,\n bytes calldata _calldata\n ) external;\n\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\n\n function diamondCutWithGuardian(\n FacetCut[] calldata diamondCut,\n address[] calldata approvers,\n bytes[] calldata signatures\n ) external;\n\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\n\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\n\n function getDiamondCutApprovalCountWithTimeValidity(\n bytes32 diamondCutHash\n ) external view returns (uint256);\n\n function getOwnerCutApprovalWithTimeValidity(\n bytes32 diamondCutHash\n ) external view returns (bool);\n\n function isCutApproved(\n bytes32 diamondCutHash,\n address approver\n ) external view returns (bool);\n\n function getDiamondCutHash(\n FacetCut[] calldata diamondCut\n ) external view returns (bytes32);\n\n function getDiamondCutNonce() external view returns (uint128);\n}\n" + }, + "contracts/facets/base/interfaces/IDiamondLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n// A loupe is a small magnifying glass used to look at diamonds.\n// These functions look at diamonds\ninterface IDiamondLoupe {\n /// These functions are expected to be called frequently\n /// by tools.\n\n struct Facet {\n address facetAddress;\n bytes4[] functionSelectors;\n }\n\n /// @notice Gets all facet addresses and their four byte function selectors.\n /// @return facets_ Facet\n function facets() external view returns (Facet[] memory facets_);\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n /// @return facetFunctionSelectors_\n function facetFunctionSelectors(\n address _facet\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses()\n external\n view\n returns (address[] memory facetAddresses_);\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(\n bytes4 _functionSelector\n ) external view returns (address facetAddress_);\n}\n" + }, + "contracts/facets/base/interfaces/IStorageLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"./IDiamondLoupe.sol\";\n\n/**\n * @title LoupeFromStorage Interface\n * @dev Interface contract to function as a loupe facet directly attached to diamond storage of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IStorageLoupe {\n /// These functions are expected to be called frequently\n /// by tools.\n\n /// @notice Gets all facet addresses and their four byte function selectors.\n /// @return facets_ Facet\n function facetsFromStorage()\n external\n view\n returns (IDiamondLoupe.Facet[] memory);\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n function facetFunctionSelectorsFromStorage(\n address _facet\n ) external view returns (bytes4[] memory);\n\n /// @notice Get all the facet addresses used by a diamond.\n function facetAddressesFromStorage()\n external\n view\n returns (address[] memory);\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n function facetAddressFromStorage(\n bytes4 _functionSelector\n ) external view returns (address);\n}\n" + }, + "contracts/facets/GuardianFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibFacetStorage, GuardianStorage, StorageConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IGuardianFacet} from \"./interfaces/IGuardianFacet.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Guardian Facet\n * @dev Contract that enables addition/removal of guardians from Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract GuardianFacet is IGuardianFacet {\n ISecurityManager public immutable securityManager;\n uint8 public constant INNER_STRUCT = 0;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Add guardians to Barz.\n * @dev This method internally calls addGuardian which checks the validity of guardian address and adds\n * as guardian if valid\n * @param _guardians Array of addresses to add as guardian\n */\n function addGuardians(address[] calldata _guardians) external override {\n LibDiamond.enforceIsSelf();\n for (uint256 i; i < _guardians.length; ) {\n addGuardian(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Add a guardian to Barz.\n * @dev This method checks if the function is called by the owner and validates the address of guardian\n * When the validation passes, guardian address is added to the pending state waiting for confirmation\n * @param _guardian Address to add as guardian\n */\n function addGuardian(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (_guardian == address(this))\n revert GuardianFacet__GuardianCannotBeSelf();\n if (isGuardian(_guardian)) revert GuardianFacet__DuplicateGuardian();\n if (_guardian == address(0))\n revert GuardianFacet__ZeroAddressGuardian();\n if (\n keccak256(abi.encodePacked(_guardian)) ==\n keccak256(IVerificationFacet(address(this)).owner())\n ) revert GuardianFacet__OwnerCannotBeGuardian();\n\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n if (\n gs.pending[id] != 0 ||\n block.timestamp <= gs.pending[id] + getSecurityWindow()\n ) revert GuardianFacet__DuplicateGuardianAddition();\n\n uint256 securityPeriod = getAdditionSecurityPeriod();\n gs.pending[id] = block.timestamp + securityPeriod;\n emit GuardianAdditionRequested(\n _guardian,\n block.timestamp + securityPeriod\n );\n }\n\n /**\n * @notice Remove guardians from Barz.\n * @dev This method internally calls removeGuardian which checks the validity of guardian and removes\n * guardian when the request is valid\n * @param _guardians Array of addresses to be removed\n */\n function removeGuardians(address[] calldata _guardians) external override {\n LibDiamond.enforceIsSelf();\n for (uint256 i; i < _guardians.length; ) {\n removeGuardian(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Remove a guardian from Barz.\n * @dev This method validates if the guardian to be removed is a guardian and puts the guardian removal\n * to a pending state waiting to be confirmed.\n * @param _guardian Address of guardian to be removed\n */\n function removeGuardian(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n if (!isGuardian(_guardian)) revert GuardianFacet__NonExistentGuardian();\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n if (\n gs.pending[id] != 0 ||\n block.timestamp <= gs.pending[id] + getSecurityWindow()\n ) revert GuardianFacet__DuplicateGuardianRemoval();\n\n uint256 securityPeriod = getRemovalSecurityPeriod();\n gs.pending[id] = block.timestamp + securityPeriod;\n emit GuardianRemovalRequested(\n _guardian,\n block.timestamp + securityPeriod\n );\n }\n\n /**\n * @notice Confirm addition of guardians\n * @dev This method internally calls confirmGuardianAddition which checks the validity of pending request.\n * Guardians are fully added when they pass the validation. Anyone can call this function.\n * @param _guardians Array of guardian addresses to be added\n */\n function confirmGuardianAdditions(\n address[] calldata _guardians\n ) external override {\n for (uint256 i; i < _guardians.length; ) {\n confirmGuardianAddition(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Confirm addition of a guardian\n * @dev This method checks the validity of pending request.\n * Guardians are fully added when they pass the validation. Anyone can call this function.\n * @param _guardian Guardian address to be added\n */\n function confirmGuardianAddition(address _guardian) public override {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingAddition();\n if (gs.pending[id] >= block.timestamp)\n revert GuardianFacet__PendingAdditionNotOver();\n if (block.timestamp >= gs.pending[id] + getSecurityWindow())\n revert GuardianFacet__PendingAdditionExpired();\n\n _addGuardian(_guardian);\n\n delete gs.pending[id];\n emit GuardianAdded(_guardian);\n }\n\n /**\n * @notice Confirm removal of guardians\n * @dev This method internally calls confirmGuardianRemoval to check the validity guardian removal confirmation.\n * Guardians are fully removed when they pass the validation. Anyone can call this function.\n * @param _guardians Array of guardian addresses to be removed\n */\n function confirmGuardianRemovals(\n address[] calldata _guardians\n ) external override {\n for (uint256 i; i < _guardians.length; ) {\n confirmGuardianRemoval(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Confirm removal of a guardian\n * @dev This method checks the validity guardian removal confirmation.\n * Guardian is fully removed when they pass the validation. Anyone can call this function.\n * @param _guardian Guardian address to be removed\n */\n function confirmGuardianRemoval(address _guardian) public override {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingRemoval();\n if (gs.pending[id] >= block.timestamp)\n revert GuardianFacet__PendingRemovalNotOver();\n if (block.timestamp >= gs.pending[id] + getSecurityWindow())\n revert GuardianFacet__PendingAdditionExpired();\n\n _removeGuardian(_guardian);\n delete gs.pending[id];\n emit GuardianRemoved(_guardian);\n }\n\n /**\n * @notice Cancel pending guardian addition\n * @dev This method checks if the previous request for guardian request exists.\n * It reverts if previous request is not pending and cancels the addition otherwise.\n * @param _guardian Guardian address to be canceled from addition\n */\n function cancelGuardianAddition(address _guardian) external override {\n LibDiamond.enforceIsSelf();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingAddition();\n delete gs.pending[id];\n emit GuardianAdditionCancelled(_guardian);\n }\n\n /**\n * @notice Cancel pending guardian removal\n * @dev This method checks if the previous request for guardian request exists.\n * It reverts if previous request is not pending and cancels the removal otherwise.\n * @param _guardian Guardian address to be canceled from removal\n */\n function cancelGuardianRemoval(address _guardian) external override {\n LibDiamond.enforceIsSelf();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingRemoval();\n delete gs.pending[id];\n emit GuardianRemovalCancelled(_guardian);\n }\n\n /**\n * @notice Get the addition security period of current account from security manager\n * @dev This method returns the uint value if addition security period\n * @return additionSecurityPeriod Uint256 value of addition security period\n */\n function getAdditionSecurityPeriod()\n public\n view\n override\n returns (uint256 additionSecurityPeriod)\n {\n additionSecurityPeriod = securityManager.additionSecurityPeriodOf(\n address(this)\n );\n if (additionSecurityPeriod == 0)\n revert GuardianFacet__InvalidAdditionSecurityPeriod();\n }\n\n /**\n * @notice Get the removal security period of current account from security manager\n * @dev This method returns the uint value if removal security period\n * @return removalSecurityPeriod Uint256 value of removal security period\n */\n function getRemovalSecurityPeriod()\n public\n view\n override\n returns (uint256 removalSecurityPeriod)\n {\n removalSecurityPeriod = securityManager.removalSecurityPeriodOf(\n address(this)\n );\n if (removalSecurityPeriod == 0)\n revert GuardianFacet__InvalidRemovalSecurityPeriod();\n }\n\n /**\n * @notice Get the security window of current account from security manager\n * @dev This method returns the uint value if security window\n * @return securityWindow Uint256 value of removal security period\n */\n function getSecurityWindow()\n public\n view\n override\n returns (uint256 securityWindow)\n {\n securityWindow = securityManager.securityWindowOf(address(this));\n if (securityWindow == 0) revert GuardianFacet__InvalidSecurityWindow();\n }\n\n /**\n * @notice Checks if the addition of the given guardian address is pending\n * @dev This method returns the bool value of whether the guardian address is pending addition\n * @return isPending Bool value of representing the pending of guardian addition\n */\n function isAdditionPending(\n address _guardian\n ) public view override returns (bool isPending) {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n isPending = _isPending(id);\n }\n\n /**\n * @notice Checks if the removal of the given guardian address is pending\n * @dev This method returns the bool value of whether the guardian address is pending removal\n * @return isPending Bool value of representing the pending of guardian removal\n */\n function isRemovalPending(\n address _guardian\n ) public view override returns (bool isPending) {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n isPending = _isPending(id);\n }\n\n /**\n * @notice Checks if the given hash is pending\n * @dev This method returns the bool value whether the hash is pending\n * @return isPending Bool value of representing the pending of guardian operation\n */\n function _isPending(\n bytes32 _idHash\n ) internal view returns (bool isPending) {\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n isPending = ((gs.pending[_idHash] > 0 &&\n gs.pending[_idHash] < block.timestamp) &&\n block.timestamp < gs.pending[_idHash] + getSecurityWindow());\n }\n\n /**\n * @notice Adds guardian to storage config. This is called when guardian is fully added.\n * @dev This method add guardian address and config information to Facet Storage dedicated for guardian\n * When this function is called, guardian is fully added to this Barz Smart Account\n * @param _guardian Address of guardian to be added\n */\n function _addGuardian(address _guardian) internal {\n if (!isAdditionPending(_guardian))\n revert GuardianFacet__InvalidGuardianAddition();\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n if (config.info[_guardian].exists)\n revert GuardianFacet__AlreadyExists();\n\n config.info[_guardian].exists = true;\n config.info[_guardian].index = uint128(config.addresses.length);\n config.addresses.push(_guardian);\n }\n\n /**\n * @notice Removes guardian to storage config. This is called when guardian is fully removed.\n * @dev This method remove guardian address and config information to Facet Storage dedicated for guardian\n * When this function is called, guardian is fully removed from this Barz Smart Account\n * @param _guardian Address of guardian to be removed\n */\n function _removeGuardian(address _guardian) internal {\n if (!isRemovalPending(_guardian))\n revert GuardianFacet__InvalidGuardianRemoval();\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n if (!config.info[_guardian].exists)\n revert GuardianFacet__NonExistentGuardian();\n\n address lastAddress = config.addresses[config.addresses.length - 1];\n if (_guardian != lastAddress) {\n uint128 targetIndex = config.info[_guardian].index;\n config.addresses[targetIndex] = lastAddress;\n config.info[lastAddress].index = targetIndex;\n }\n config.addresses.pop();\n delete config.info[_guardian];\n\n emit GuardianRemoved(_guardian);\n }\n\n /**\n * @notice Reads guardian storage and fetches the addresses into an array from the storage\n * @dev This method fetches the guardian storage and returns the list of guardian addresses\n * @return guardians Array of addresses comprised of guardian\n */\n function getGuardians()\n public\n view\n override\n returns (address[] memory guardians)\n {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n uint256 guardiansLen = config.addresses.length;\n guardians = new address[](guardiansLen);\n for (uint256 i; i < guardiansLen; ) {\n guardians[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the number of majority of guardians\n * @return majorityOfGuardians_ Number of majority of guardians e.g., 2 if 3 guardians / 3 if 5 guardians\n */\n function majorityOfGuardians()\n public\n view\n override\n returns (uint256 majorityOfGuardians_)\n {\n majorityOfGuardians_ = LibGuardian.majorityOfGuardians();\n }\n\n /**\n * @notice Reads guardian storage and fetches the addresses into an array from the storage\n * @dev This method fetches the guardian storage and returns the list of guardian addresses\n * @return guardianNumber Array of guardians in the account\n */\n function guardianCount()\n public\n view\n override\n returns (uint256 guardianNumber)\n {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n guardianNumber = config.addresses.length;\n }\n\n /**\n * @notice Reads guardian storage and checks if the given address is a guardian\n * @return isGuardian_ Bool value representing if the given address is guardian\n */\n function isGuardian(\n address _guardian\n ) public view override returns (bool isGuardian_) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n isGuardian_ = config.info[_guardian].exists;\n }\n\n /**\n * @notice Checks if the guardian number is zero and returns of guardian facet is okay to be removed\n * @return isRemovable Bool value representing if guardian facet is removable\n */\n function isGuardianFacetRemovable()\n external\n view\n override\n returns (bool isRemovable)\n {\n isRemovable = (0 == guardianCount());\n }\n}\n" + }, + "contracts/facets/interfaces/IAccountFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IEntryPoint} from \"../../aa-4337/interfaces/IEntryPoint.sol\";\n\n/**\n * @title Account Facet Interface\n * @dev Interface of module contract that provides the account features and init/unitialization of signer\n * compatible with EIP-1271 & EIP-4337\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IAccountFacet {\n event AccountInitialized(\n IEntryPoint indexed entryPoint,\n bytes indexed ownerPublicKey\n );\n // NOTE: Added Below Event\n event VerificationSuccess(bytes32);\n event VerificationFailure(bytes32);\n\n error AccountFacet__InitializationFailure();\n error AccountFacet__RestrictionsFailure();\n error AccountFacet__NonExistentVerificationFacet();\n error AccountFacet__CallNotSuccessful();\n error AccountFacet__InvalidArrayLength();\n\n function initialize(\n address verificationFacet,\n address anEntryPoint,\n address facetRegistry,\n address _defaultFallBack,\n bytes calldata _ownerPublicKey\n ) external returns (uint256);\n\n function execute(address dest, uint256 value, bytes calldata func) external;\n\n function executeBatch(\n address[] calldata dest,\n uint256[] calldata value,\n bytes[] calldata func\n ) external;\n}\n" + }, + "contracts/facets/interfaces/IAccountRecoveryFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {RecoveryConfig} from \"../../libraries/LibFacetStorage.sol\";\n\n/**\n * @title Account Recovery Facet Interface\n * @dev Interface of contract that enables recovery of accounts when owner key is unavailable\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IAccountRecoveryFacet {\n event RecoveryExecuted(\n bytes indexed recoveryPublicKey,\n uint64 executeAfter\n );\n event RecoveryFinalized(bytes indexed recoveryPublicKey);\n event RecoveryCanceled(bytes indexed recoveryPublicKey);\n event RecoveryApproved(\n bytes indexed recoveryPublicKey,\n address indexed guardian,\n uint64 validUntil\n );\n event RecoveryApprovalRevoked(\n bytes indexed recoveryPublicKey,\n address indexed guardian\n );\n event RecoveryCancellationApproved(\n bytes indexed recoveryPublicKey,\n address indexed guardian\n );\n event RecoveryHardstopped();\n\n error AccountRecoveryFacet__CallerNotGuardian();\n error AccountRecoveryFacet__InvalidRecoveryPublicKey();\n error AccountRecoveryFacet__SignerInitializationFailure();\n error AccountRecoveryFacet__SignerUninitializationFailure();\n error AccountRecoveryFacet__InvalidArrayLength();\n error AccountRecoveryFacet__InsufficientGuardians();\n error AccountRecoveryFacet__RecoveryAlreadyOngoing();\n error AccountRecoveryFacet__NonexistentRecovery();\n error AccountRecoveryFacet__NonExistentApproval();\n error AccountRecoveryFacet__RecoveryPeriodNotOver();\n error AccountRecoveryFacet__InvalidLockPeriod();\n error AccountRecoveryFacet__InvalidRecoveryPeriod();\n error AccountRecoveryFacet__InvalidApprovalValidationPeriod();\n error AccountRecoveryFacet__InvalidGuardian();\n error AccountRecoveryFacet__InvalidGuardianSignature();\n error AccountRecoveryFacet__InvalidOwnerSignature();\n error AccountRecoveryFacet__CallNotSuccesful();\n error AccountRecoveryFacet__DuplicateApproval();\n\n function approveAccountRecovery(bytes calldata recoveryPublicKey) external;\n\n function revokeAccountRecoveryApproval(\n bytes calldata recoveryPublicKey\n ) external;\n\n function executeRecovery(\n bytes calldata recoveryPublicKey,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function finalizeRecovery() external;\n\n function approveCancelRecovery(bytes calldata recoveryPublicKey) external;\n\n function cancelRecovery(\n bytes calldata recoveryPublicKey,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function hardstopRecovery(bytes calldata signature) external;\n\n function validateNewOwner(bytes calldata recoveryPublicKey) external view;\n\n function getApprovalRecoveryKeyHash(\n bytes memory recoveryPublicKey,\n string memory saltString\n ) external view returns (bytes32);\n\n function getRecoveryApprovalCountWithTimeValidity(\n bytes32 recoveryPublicKeyHash\n ) external view returns (uint256);\n\n function isRecoveryApproved(\n bytes32 recoveryPublicKeyHash,\n address approver\n ) external view returns (bool);\n\n function getRecoveryNonce() external view returns (uint128);\n\n function getPendingRecovery() external view returns (RecoveryConfig memory);\n}\n" + }, + "contracts/facets/interfaces/IGuardianFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Guardian Facet Interface\n * @dev Interface of guaridna contract that enables addition/removal of guardians from Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IGuardianFacet {\n event GuardianAdditionRequested(\n address indexed guardian,\n uint256 executeAfter\n );\n event GuardianRemovalRequested(\n address indexed guardian,\n uint256 executeAfter\n );\n event GuardianAdditionCancelled(address indexed guardian);\n event GuardianRemovalCancelled(address indexed guardian);\n event GuardianAdded(address indexed guardian);\n event GuardianRemoved(address indexed guardian);\n\n error GuardianFacet__GuardianCannotBeSelf();\n error GuardianFacet__DuplicateGuardian();\n error GuardianFacet__OwnerCannotBeGuardian();\n error GuardianFacet__DuplicateGuardianAddition();\n error GuardianFacet__DuplicateGuardianRemoval();\n error GuardianFacet__UnknownPendingAddition();\n error GuardianFacet__PendingAdditionNotOver();\n error GuardianFacet__UnknownPendingRemoval();\n error GuardianFacet__PendingRemovalNotOver();\n error GuardianFacet__PendingAdditionExpired();\n error GuardianFacet__InvalidAdditionSecurityPeriod();\n error GuardianFacet__InvalidRemovalSecurityPeriod();\n error GuardianFacet__InvalidSecurityWindow();\n error GuardianFacet__NonExistentGuardian();\n error GuardianFacet__AlreadyExists();\n error GuardianFacet__InvalidGuardianAddition();\n error GuardianFacet__InvalidGuardianRemoval();\n error GuardianFacet__ZeroAddressGuardian();\n\n function addGuardian(address guardian) external;\n\n function addGuardians(address[] calldata guardians) external;\n\n function removeGuardian(address guardian) external;\n\n function removeGuardians(address[] calldata guardians) external;\n\n function confirmGuardianAddition(address guardian) external;\n\n function confirmGuardianAdditions(address[] calldata guardian) external;\n\n function confirmGuardianRemoval(address guardian) external;\n\n function confirmGuardianRemovals(address[] calldata guardian) external;\n\n function cancelGuardianAddition(address guardian) external;\n\n function cancelGuardianRemoval(address guardian) external;\n\n function isGuardian(address guardian) external view returns (bool);\n\n function isAdditionPending(address guardian) external view returns (bool);\n\n function isRemovalPending(address guardian) external view returns (bool);\n\n function isGuardianFacetRemovable() external view returns (bool);\n\n function getAdditionSecurityPeriod() external view returns (uint256);\n\n function getRemovalSecurityPeriod() external view returns (uint256);\n\n function getSecurityWindow() external view returns (uint256);\n\n function getGuardians() external view returns (address[] memory);\n\n function majorityOfGuardians() external view returns (uint256);\n\n function guardianCount() external view returns (uint256);\n}\n" + }, + "contracts/facets/interfaces/ILockFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Lock} from \"../../libraries/LibAppStorage.sol\";\n\n/**\n * @title Lock Facet Interface\n * @dev Interface of Lock contract that enables full lock/unlock of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface ILockFacet {\n event Locked(uint64 releaseAfter);\n event Unlocked();\n\n error LockFacet__InvalidRecoveryPeriod();\n error LockFacet__CannotUnlock();\n error LockFacet__InvalidSignature();\n error LockFacet__InvalidApprover();\n\n function lock() external;\n\n function unlock(address approver, bytes calldata signature) external;\n\n function getLockPeriod() external view returns (uint256);\n\n function isLocked() external view returns (bool);\n\n function getUnlockHash() external view returns (bytes32);\n\n function lockNonce() external view returns (uint128);\n\n function getPendingLock() external view returns (Lock memory);\n}\n" + }, + "contracts/facets/interfaces/IMultiSigFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Multi-sig facet Interface\n * @dev Interface of Multi-signature Facet with custom threshold.\n Wallet that adds this facet becomes a multi-sig wallet\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IMultiSigFacet {\n event ThresholdChanged(uint256 threshold);\n event OwnerAdded(address indexed newOwner);\n event OwnerRemoved(address indexed prevOwner);\n event HashApproved(bytes32 hashToApprove, address indexed owner);\n\n error MultiSigFacet__InvalidThreshold();\n error MultisigFacet__InvalidOwnerCount();\n error MultiSigFacet__InvalidRoute();\n error MultiSigFacet__InsufficientSignerLength();\n error MultiSigFacet__InvalidInitData();\n error MultiSigFacet__InvalidOwnerAddress();\n error MultiSigFacet__InvalidOwnerPair();\n error MultiSigFacet__InvalidSignatureLength();\n error MultiSigFacet__InvalidSignatureType();\n error MultiSigFacet__DuplicateOwner();\n error MultiSigFacet__OnlyOwner();\n\n function checkSignatures(\n bytes32 _dataHash,\n bytes calldata _signatures,\n uint256 _threshold\n ) external view returns (uint256);\n\n function splitSignatures(\n bytes calldata _signatures,\n uint256 _nextOffset\n )\n external\n pure\n returns (\n address owner,\n bytes memory signature,\n uint256 signatureType,\n uint256 nextOffset\n );\n\n function approveHash(bytes32 hashToApprove) external;\n\n function addOwner(address newOwner, uint256 threshold) external;\n\n function removeOwner(\n address prevOwner,\n address removedOwner,\n uint256 threshold\n ) external;\n\n function swapOwner(\n address prevOwner,\n address oldOwner,\n address newOwner\n ) external;\n\n function changeThreshold(uint256 _threshold) external;\n\n function isOwner(address owner) external view returns (bool);\n\n function getThreshold() external view returns (uint256);\n\n function getOwners() external view returns (address[] memory);\n}\n" + }, + "contracts/facets/interfaces/IRestrictionsFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Restrictions Facet Interface\n * @dev Interface of Restrictions contract that enables modular restrictions in Barz\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IRestrictionsFacet {\n event RestrictionAdded(address indexed restriction);\n event RestrictionRemoved(address indexed restriction);\n\n error RestrictionsFacet__EmptyRestrictionsList();\n error RestrictionsFacet__RestrictionNotFound();\n error RestrictionsFacet__RestrictionAlreadyExists();\n error RestrictionsFacet__ZeroAddressRestrictions();\n error RestrictionsFacet__ZeroAddressRestrictionsFacet();\n error RestrictionsFacet__RemainingRestrictionsCantBeEmpty();\n\n function initializeRestrictions(\n address[] memory _restrictions\n ) external returns (uint256);\n\n function uninitializeRestrictions() external returns (uint256);\n\n function getRestrictions() external view returns (address[] memory);\n\n function addRestriction(address restriction) external;\n\n function removeRestriction(address restriction) external;\n\n function verifyRestrictions(\n address from,\n address to,\n uint256 value,\n bytes calldata _calldata\n ) external returns (uint256);\n}\n" + }, + "contracts/facets/interfaces/ISignatureMigrationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureMigrationConfig} from \"../../libraries/LibFacetStorage.sol\";\n\n/**\n * @title Signature Migration Facet Interface\n * @dev Interface of Signature Migration contract for migrating user signature scheme to a new scheme user sets\n * Which could include\n * - ECDSA on Secp256K1 Curve\n * - ECDSA on Secp256R1 Curve\n * - BLS, Schnorr, etc\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface ISignatureMigrationFacet {\n event SignatureSchemeMigration(\n address indexed prevVerificationFacet,\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n event SignatureMigrationApproved(\n bytes newPublicKey,\n address indexed newVerificationFacet,\n bytes4[] verificationFuncSelectors,\n address indexed guardian,\n uint128 approvalValidUntil\n );\n event SignatureMigrationApprovalRevoked(\n bytes newPublicKey,\n address indexed newVerificationFacet,\n bytes4[] verificationFuncSelectors,\n address indexed guardian\n );\n event SignatureMigrationExecuted(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors,\n uint128 migrateAfter\n );\n event SignatureMigrationCanceled(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n event SignatureMigrationCancellationApproved(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n\n error SignatureMigrationFacet__SignerUninitializationFailure();\n error SignatureMigrationFacet__SignerInitializationFailure();\n error SignatureMigrationFacet__InvalidRouteWithGuardian();\n error SignatureMigrationFacet__InvalidKeyType();\n error SignatureMigrationFacet__InsufficientApprovers();\n error SignatureMigrationFacet__InvalidApproverSignature();\n error SignatureMigrationFacet__InvalidGuardian();\n error SignatureMigrationFacet__NonExistentApprover();\n error SignatureMigrationFacet__InvalidMigrationPeriod();\n error SignatureMigrationFacet__NonexistentMigration();\n error SignatureMigrationFacet__MigrationPeriodNotOver();\n error SignatureMigrationFacet__InvalidArrayLength();\n error SignatureMigrationFacet__InvalidApprovalValidationPeriod();\n error SignatureMigrationFacet__CannotRevokeUnapproved();\n error SignatureMigrationFacet__LackOfOwnerApproval();\n error SignatureMigrationFacet__OwnerAlreadyApproved();\n error SignatureMigrationFacet__NonExistentVerificationFacet();\n error SignatureMigrationFacet__DuplicateApproval();\n\n function migrateSignatureScheme(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function migrateSignatureSchemeWithGuardian(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors,\n address[] calldata approvers,\n bytes[] calldata signatures\n ) external;\n\n function approveSignatureSchemeMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function revokeSignatureMigrationApproval(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function finalizeSignatureMigration() external;\n\n function approveCancelSignatureMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function cancelSignatureMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function getApprovalMigrationKeyHash(\n bytes memory recoveryPublicKey,\n address newVerificationFacet,\n bytes4[] memory newVerificationFuncSelectors,\n string memory saltString\n ) external view returns (bytes32);\n\n function getMigrationOwnerApprovalWithTimeValidity(\n bytes32 publicKeyHash\n ) external view returns (bool);\n\n function getMigrationApprovalCountWithTimeValidity(\n bytes32 publicKeyHash\n ) external view returns (uint256);\n\n function isMigrationApproved(\n bytes32 migrationPublicKeyHash,\n address approver\n ) external view returns (bool);\n\n function getMigrationNonce() external view returns (uint128);\n\n function isMigrationPending() external view returns (bool);\n\n function getPendingMigration()\n external\n view\n returns (SignatureMigrationConfig memory);\n}\n" + }, + "contracts/facets/interfaces/IVerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {UserOperation} from \"../../aa-4337/interfaces/UserOperation.sol\";\n\n/**\n * @title Verification Facet Interface\n * @dev Implements logic for user ops signature verification\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface IVerificationFacet {\n event SignerInitialized(bytes);\n event SignerUninitialized();\n\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n error VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n error VerificationFacet__InitializationFailure();\n error VerificationFacet__InvalidFacetMapping();\n\n function initializeSigner(bytes memory) external returns (uint256);\n\n function uninitializeSigner() external returns (uint256);\n\n function validateOwnerSignatureSelector() external view returns (bytes4);\n\n function owner() external view returns (bytes memory);\n\n function isValidKeyType(bytes calldata) external view returns (bool);\n\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) external view returns (uint256);\n}\n" + }, + "contracts/facets/LockFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage, Lock} from \"../libraries/LibAppStorage.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibFacetStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {ILockFacet} from \"./interfaces/ILockFacet.sol\";\n\n/**\n * @title Lock Facet\n * @dev Contract that enables full lock/unlock of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract LockFacet is ILockFacet, Modifiers {\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Locks the account for the lock period. Lock period is defined in the security manager and it's customizable\n * This function can only be called when account is unlocked by owner or guardians\n * @dev This method checks the caller and if the account is currently locked and locks the account after fetching the\n * Lock period from the owner.\n */\n function lock() external override onlyGuardianOrOwner onlyWhenUnlocked {\n uint256 unlockTime = block.timestamp + getLockPeriod();\n unchecked {\n ++LibFacetStorage.lockStorage().nonce;\n }\n LibAppStorage.setLock(unlockTime, LockFacet.lock.selector);\n emit Locked(uint64(unlockTime));\n }\n\n /**\n * @notice Locks the account when the account is locked. This function can be called by anyone but must provide the approver address and signature.\n * The approver should be one of the guardians or owner.\n * @dev This method takes the approver address and the signature. After validating the address and the signature, it unlocks the account immediately.\n * Only one of the guardian or owner is required to lock and unlock the account.\n * @param _approver Address of approver approving the unlock of Barz account\n * @param _signature Signature of the approver that signed the msg hash for unlocking the account\n */\n function unlock(\n address _approver,\n bytes calldata _signature\n ) external override onlyWhenLocked {\n if (_approver != address(this) && !LibGuardian.isGuardian(_approver))\n revert LockFacet__InvalidApprover();\n if (\n !SignatureChecker.isValidSignatureNow(\n _approver,\n getUnlockHash(),\n _signature\n )\n ) revert LockFacet__InvalidSignature();\n _unlock();\n }\n\n /**\n * @notice Unlocks the account and increments the lock nonce\n */\n function _unlock() private {\n if (s.locks[INNER_STRUCT].locker != LockFacet.lock.selector)\n revert LockFacet__CannotUnlock();\n unchecked {\n ++LibFacetStorage.lockStorage().nonce;\n }\n LibAppStorage.setLock(0, bytes4(0));\n emit Unlocked();\n }\n\n /**\n * @notice Returns the lock period of current Barz account. Lock period information is held by Security Manager\n * @return lockPeriod Uint value of lock period in seconds\n */\n function getLockPeriod() public view override returns (uint256 lockPeriod) {\n lockPeriod = securityManager.lockPeriodOf(address(this));\n if (lockPeriod == 0) revert LockFacet__InvalidRecoveryPeriod();\n }\n\n /**\n * @notice Returns if the account is locked or not\n * @dev This method fetches the current block timestamp and compares that with release time.\n * After checking the timestamp and release time, it returns if the account is still locked or not.\n * @return isLocked_ Uint value of lock period in seconds\n */\n function isLocked() public view override returns (bool isLocked_) {\n isLocked_ = uint64(block.timestamp) < s.locks[INNER_STRUCT].release;\n }\n\n /**\n * @notice Calculates the unlock hash and returns the unlock hash safe from signature reply attack\n * @dev This method calculates the unlock hash with EIP-191 prefix, wallet address, chainID, and nonce\n * It packs the result and packs them and hashes it.\n * @return unlockHash Bytes32 unlock hash\n */\n function getUnlockHash() public view override returns (bytes32 unlockHash) {\n unlockHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n \"Unlock\",\n address(this),\n block.chainid,\n lockNonce()\n )\n )\n )\n );\n }\n\n /**\n * @notice Returns lock nonce of account. Reads nonce from lock storage within facet storage\n * @return lockNonce_ Uint128 value of lock nonce. This is incremented whenever the account is lock/unlocked\n */\n function lockNonce() public view override returns (uint128 lockNonce_) {\n lockNonce_ = LibFacetStorage.lockStorage().nonce;\n }\n\n /**\n * @notice Returns the overall information of current lock\n * @return pendingLock Struct value including all information of pending lock\n */\n function getPendingLock()\n public\n view\n override\n returns (Lock memory pendingLock)\n {\n pendingLock = s.locks[INNER_STRUCT];\n }\n}\n" + }, + "contracts/facets/Modifiers.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\n\n/**\n * @title Modifiers\n * @dev Responsible for providing modifiers/util functions to Facet contracts\n * @author David Yongjun Kim (@Powerstream3604)\n */\nabstract contract Modifiers is BarzStorage {\n uint8 constant INNER_STRUCT = 0;\n\n error CallerNotGuardian();\n error CallerNotGuardianOrOwner();\n error DuplicateApprover();\n error ZeroApproverLength();\n error UnregisteredFacetAndSelectors();\n\n /**\n * @notice Modifier to only allow guardian to make a call, reverts if any other entity is the caller\n */\n modifier onlyGuardian() {\n if (!LibGuardian.isGuardian(msg.sender)) revert CallerNotGuardian();\n _;\n }\n\n /**\n * @notice Modifier to only allow guardian or owner to make a call, reverts if any other entity is the caller\n */\n modifier onlyGuardianOrOwner() {\n if (!LibGuardian.isGuardian(msg.sender) && address(this) != msg.sender)\n revert CallerNotGuardianOrOwner();\n _;\n }\n\n /**\n * @notice Checks if the approver address is the array is unique with no duplicate\n * @dev This method loops through the array and checks if a duplicate address exists, it reverts if duplicate address exists\n * @param approvers Array of address\n */\n function _checkApprover(\n address[] memory approvers\n ) internal pure returns (bool) {\n uint256 approverLength = approvers.length;\n if (0 == approverLength) revert ZeroApproverLength();\n for (uint256 i; i < approverLength - 1; ) {\n for (uint256 j = i + 1; j < approverLength; ) {\n if (approvers[i] == approvers[j]) {\n revert DuplicateApprover(); // Found a duplicate\n }\n unchecked {\n ++j;\n }\n }\n unchecked {\n ++i;\n }\n }\n return false; // No duplicates found\n }\n\n /**\n * @notice Checks if the facet getting added or replaced is registered to facet registry\n * @dev This method loops through the cut and checks if the facet getting added/replaced is registered to facet registry\n * @param _diamondCut Array of FacetCut, data for diamondCut defined in EIP-2535\n */\n function _checkFacetCutValidity(\n IDiamondCut.FacetCut[] memory _diamondCut\n ) internal view {\n uint256 diamondCutLength = _diamondCut.length;\n for (uint256 i; i < diamondCutLength; ) {\n if (\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Add ||\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Replace\n ) {\n if (\n !s.facetRegistry.areFacetFunctionSelectorsRegistered(\n _diamondCut[i].facetAddress,\n _diamondCut[i].functionSelectors\n )\n ) revert UnregisteredFacetAndSelectors();\n }\n unchecked {\n ++i;\n }\n }\n }\n}\n" + }, + "contracts/facets/ReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibReentrancyGuardStorage, ReentrancyGuardStorage} from \"../libraries/LibReentrancyGuardStorage.sol\";\n\nabstract contract ReentrancyGuard {\n\n uint256 private constant _NOT_ENTERED = 0;\n uint256 private constant _ENTERED = 1;\n\n error ReentrancyGuard__ReentrantCall();\n\n modifier nonReentrant() {\n ReentrancyGuardStorage storage rgs = LibReentrancyGuardStorage.reentrancyguardStorage();\n\n if (rgs.status == _ENTERED) revert ReentrancyGuard__ReentrantCall();\n\n rgs.status = _ENTERED;\n\n _; // Execute function\n\n rgs.status = _NOT_ENTERED;\n }\n}\n" + }, + "contracts/facets/RestrictionsFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ReentrancyGuard} from \"./ReentrancyGuard.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, RestrictionsStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {IRestriction} from \"../restrictions/IRestriction.sol\";\nimport {IRestrictionsFacet} from \"./interfaces/IRestrictionsFacet.sol\";\n\n/**\n * @title Restrictions facet\n * @dev Responsible for storing and verifying different kinds of restrictions, for example:\n * - Whitelist / Blacklist\n * - Daily limits\n * - Trading time restrictions\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract RestrictionsFacet is IRestrictionsFacet, ReentrancyGuard {\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceRestrictionsInitialize();\n }\n\n /**\n * @notice Intialize restrictions of Barz. Restrictions facet call restriction contracts for restriction validation\n * before each call\n * @param _restrictions The initial array of restrictions.\n * @return initSuccess Int value showing if the initialization of restriction is successful\n */\n function initializeRestrictions(\n address[] calldata _restrictions\n ) public override returns (uint256 initSuccess) {\n LibDiamond.enforceIsSelf();\n LibAppStorage.enforceRestrictionsInitialize();\n\n if (_restrictions.length == 0) {\n // You can't initialize RestrictionsFacet with an empty list of restrictions\n revert RestrictionsFacet__EmptyRestrictionsList();\n }\n for (uint256 i; i < _restrictions.length; ) {\n if (_restrictions[i] == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictions();\n unchecked {\n ++i;\n }\n }\n\n LibFacetStorage.restrictionsStorage().restrictions = _restrictions;\n _updateRestrictionsMap(_restrictions, true);\n initSuccess = 1;\n }\n\n /**\n * @notice Unitialize restrictions of Barz\n * @return uninitSuccess Int value showing if the initialization of restriction is successful\n */\n function uninitializeRestrictions()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibDiamond.enforceIsSelf();\n LibAppStorage.setRestrictionsUninitialized();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n _updateRestrictionsMap(restrictionsStorage.restrictions, false);\n restrictionsStorage.restrictions = new address[](0);\n uninitSuccess = 1;\n }\n\n /**\n * @notice Returns the list of Restrictions contract address\n * @return restrictions Addresses of IRestriction which are currently active\n */\n function getRestrictions()\n public\n view\n override\n returns (address[] memory restrictions)\n {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n restrictions = restrictionsStorage.restrictions;\n }\n\n /**\n * @notice Adds restrictions to Barz with validation on the restriction contract address.\n * This method is only callable by the owner(self).\n * @param _restriction The address of the restriction to be added.\n */\n function addRestriction(address _restriction) external override {\n LibDiamond.enforceIsSelf();\n if (LibDiamond.restrictionsFacet() == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictionsFacet();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n if (_restriction == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictions();\n if (restrictionsStorage.exists[_restriction])\n revert RestrictionsFacet__RestrictionAlreadyExists();\n\n restrictionsStorage.restrictions.push(_restriction);\n restrictionsStorage.exists[_restriction] = true;\n\n emit RestrictionAdded(_restriction);\n }\n\n /**\n * @notice Remove restrictions from Barz if it existed. This method is only callable by the owner(self).\n * @param _restriction The address of the restriction to be removed.\n */\n function removeRestriction(address _restriction) external override {\n LibDiamond.enforceIsSelf();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n if (!restrictionsStorage.exists[_restriction])\n revert RestrictionsFacet__RestrictionNotFound();\n\n address[] storage restrictions = restrictionsStorage.restrictions;\n\n uint256 indexToDelete = restrictions.length;\n uint256 restrictionsLen = restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n if (restrictions[i] == _restriction) {\n indexToDelete = i;\n break;\n }\n unchecked {\n ++i;\n }\n }\n\n if (indexToDelete == 0 && restrictionsLen == 1) {\n revert RestrictionsFacet__RemainingRestrictionsCantBeEmpty();\n } else if (indexToDelete == restrictionsLen) {\n revert RestrictionsFacet__RestrictionNotFound();\n } else {\n restrictions[indexToDelete] = restrictions[restrictionsLen - 1];\n restrictions.pop();\n }\n\n restrictionsStorage.exists[_restriction] = false;\n emit RestrictionRemoved(_restriction);\n }\n\n /**\n * @notice Sets the restrictions address value mapping to true or false when adding/removing restriction contracts\n * @param _restrictions List of restriction contracts address\n * @param _newValue Bool value to flag to the list of restrictions contracts\n */\n function _updateRestrictionsMap(\n address[] memory _restrictions,\n bool _newValue\n ) internal {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n uint restrictionsLen = _restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n restrictionsStorage.exists[_restrictions[i]] = _newValue;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @dev Iterates over all restrictions and verifies each of them with the transaction parameters.\n * @param _from The address of the sender, that will be signing the transaction.\n * @param _to The receiving address.\n * @param _value Amount of ETH to transfer from sender to recipient.\n * @param _calldata Optional field to include arbitrary data.\n * @return 0 if all the checks passed, 1 otherwise.\n */\n function verifyRestrictions(\n address _from,\n address _to,\n uint256 _value,\n bytes calldata _calldata\n ) external nonReentrant returns (uint256) {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n uint restrictionsLen = restrictionsStorage.restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n IRestriction restriction = IRestriction(\n restrictionsStorage.restrictions[i]\n );\n bool checkPassed = restriction.check(_from, _to, _value, _calldata);\n if (!checkPassed) {\n return 1;\n }\n unchecked {\n ++i;\n }\n }\n\n return 0;\n }\n}\n" + }, + "contracts/facets/SignatureMigrationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, SignatureMigrationStorage, SignatureMigrationConfig, SignatureMigrationApprovalConfig, ApprovalConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IDiamondCut} from \"./base/interfaces/IDiamondCut.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {ISignatureMigrationFacet} from \"./interfaces/ISignatureMigrationFacet.sol\";\n\n/**\n * @title Signature Migration Facet\n * @dev Responsible for migrating user signature scheme to a new scheme user sets\n * Which could include\n * - ECDSA on Secp256K1 Curve\n * - ECDSA on Secp256R1 Curve\n * - BLS, Schnorr, etc\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract SignatureMigrationFacet is ISignatureMigrationFacet, Modifiers {\n bytes constant UNINIT_CALL =\n abi.encodeWithSignature(\"uninitializeSigner()\");\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This modifier verifies if the public key format matches with the new verification facet\n * @param _publicKey Bytes of public key to be validated for the new verification facet\n * @param _newVerificationFacet Address of new verification facet\n */\n modifier validateKeyType(\n bytes memory _publicKey,\n address _newVerificationFacet\n ) {\n if (\n !IVerificationFacet(_newVerificationFacet).isValidKeyType(\n _publicKey\n )\n ) revert SignatureMigrationFacet__InvalidKeyType();\n _;\n }\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n // IMPORTANT NOTE: In the client side when they call this function, the func selectors should be sorted in ascending order\n // to prevent different hash with same items in the array\n /**\n * @notice Moves the state of migration to a pending state. When pending state is over after pending period time,\n * Migration can be finalized. This function can only be called by self and when the account is unlocked.\n * @dev This method checks if the caller is self and if guardians exists. It migrates signature request to a pending state\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function migrateSignatureScheme(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n public\n override\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n // Only self contract can call this function\n LibDiamond.enforceIsSelf();\n // Should revert if guardian exist\n if (0 != LibGuardian.guardianCount())\n revert SignatureMigrationFacet__InvalidRouteWithGuardian();\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n // NOTE: Migration requires a pending period & confirmation from owner to prevent a\n // single call changing the ownership of the wallet\n /**\n * @notice Migrate signature scheme when guardians exists. Verifies the signature of guardians and moves migration to pending state.\n * Which can then be finalized when pending period is over. Owner's approval is mandatory for migration to happen\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _approvers List of approvers. This could include owner\n */\n function migrateSignatureSchemeWithGuardian(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n )\n public\n override\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n // Should revert if does not guardian exist\n if (0 == LibGuardian.guardianCount())\n revert SignatureMigrationFacet__InvalidRouteWithGuardian();\n if (_approvers.length != _signatures.length)\n revert SignatureMigrationFacet__InvalidArrayLength();\n\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(migrationPublicKeyHash, _approvers);\n\n bool onChainOwnerApproval = getMigrationOwnerApprovalWithTimeValidity(\n migrationPublicKeyHash\n );\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n\n if (\n _approvers.length +\n getMigrationApprovalCountWithTimeValidity(\n migrationPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert SignatureMigrationFacet__InsufficientApprovers();\n {\n // To prevent Stack too deep\n bool ownerApproved;\n for (uint256 i; i < _approvers.length; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n address(this) != _approvers[i]\n ) revert SignatureMigrationFacet__InvalidGuardian();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert SignatureMigrationFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n migrationPublicKeyHash,\n _signatures[i]\n )\n ) revert SignatureMigrationFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n\n if (!ownerApproved && !onChainOwnerApproval)\n revert SignatureMigrationFacet__LackOfOwnerApproval();\n }\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Internal function that moves signature mgiration to a pending state.\n * @dev This method increments migration nonce and sets the migration in the migration config. Emits events for migration execution\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _migrateSignatureScheme(\n address _newVerificationFacet,\n bytes memory _newPublicKey,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal {\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n unchecked {\n ++ms.nonce;\n }\n uint64 migrateAfter = uint64(block.timestamp + getMigrationPeriod());\n\n ms.migrationConfigs[INNER_STRUCT] = SignatureMigrationConfig(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n migrateAfter\n );\n\n emit SignatureMigrationExecuted(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors,\n migrateAfter\n );\n }\n\n /**\n * @notice Approves signature scheme migration on-chain. This can be called by owner or guardian only when the account is unlocked.\n * When the threshold of the migration approval passed and owner approval is granted, it automatically moves migration to a pending state\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function approveSignatureSchemeMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n public\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit SignatureMigrationApproved(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n msg.sender,\n approvalValidUntil\n );\n if (\n getMigrationApprovalCountWithTimeValidity(migrationPublicKeyHash) >=\n LibGuardian.majorityOfGuardians() &&\n getMigrationOwnerApprovalWithTimeValidity(migrationPublicKeyHash)\n )\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Revokes the approval of signature migration done on-chain. Emits revoke event when revoked.\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function revokeSignatureMigrationApproval(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n external\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n if (!isMigrationApproved(migrationPublicKeyHash, msg.sender))\n revert SignatureMigrationFacet__CannotRevokeUnapproved();\n\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(false, 0);\n emit SignatureMigrationApprovalRevoked(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n msg.sender\n );\n }\n\n /**\n * @notice Finalizes the pending signature scheme migration. This function can only be called by owner.\n * It removes the facets of the previous verification facet and adds the new verification facet.\n * After finalizing migration, it emits migration event which shows the change of the verification facet\n */\n function finalizeSignatureMigration() external override {\n // NOTE: Only owner can call this function\n LibDiamond.enforceIsSelf();\n\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n\n if (!isMigrationPending())\n revert SignatureMigrationFacet__NonexistentMigration();\n\n if (\n uint64(block.timestamp) <=\n ms.migrationConfigs[INNER_STRUCT].migrateAfter\n ) revert SignatureMigrationFacet__MigrationPeriodNotOver();\n address newVerificationFacet = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationVerificationFacet;\n bytes4[] memory newVerificationFuncSelectors = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationSelectors;\n bytes memory newPublicKey = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationPublicKey;\n\n address prevVerificationFacet = LibLoupe.facetAddress(\n s.validateOwnerSignatureSelector\n );\n if (prevVerificationFacet == address(0))\n revert SignatureMigrationFacet__NonExistentVerificationFacet();\n\n IDiamondCut.FacetCut[] memory UninitCut;\n IDiamondCut.FacetCut[] memory InitCut;\n {\n bytes4[] memory prevVerificationFuncSelectors = LibLoupe\n .facetFunctionSelectors(prevVerificationFacet);\n\n UninitCut = new IDiamondCut.FacetCut[](1);\n InitCut = new IDiamondCut.FacetCut[](1);\n UninitCut[0] = IDiamondCut.FacetCut({\n facetAddress: address(0),\n action: IDiamondCut.FacetCutAction.Remove,\n functionSelectors: prevVerificationFuncSelectors\n });\n InitCut[0] = IDiamondCut.FacetCut({\n facetAddress: newVerificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: newVerificationFuncSelectors\n });\n {\n IDiamondCut.FacetCut[]\n memory facetCuts = new IDiamondCut.FacetCut[](2);\n facetCuts[0] = UninitCut[0];\n facetCuts[1] = InitCut[0];\n _checkFacetCutValidity(facetCuts);\n }\n LibAppStorage.initiateSignerMigration();\n address verificationFacet = address(\n bytes20(\n LibDiamond.diamondStorage().facets[\n s.validateOwnerSignatureSelector\n ]\n )\n );\n\n (bool uninitSuccess, bytes memory uninitResult) = verificationFacet\n .delegatecall(UNINIT_CALL);\n if (!uninitSuccess || uint256(bytes32(uninitResult)) != 1)\n revert SignatureMigrationFacet__SignerUninitializationFailure();\n LibAppStorage.finalizeSignerMigration();\n\n LibDiamond.diamondCut(UninitCut, address(0), \"\");\n }\n {\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n newPublicKey\n );\n\n // Every Verification Facet should comply with initializeSigner(bytes)\n // to be compatible with the Barz contract(for initialization)\n LibDiamond.diamondCut(InitCut, address(0), \"\");\n (bool initSuccess, bytes memory initResult) = newVerificationFacet\n .delegatecall(initCall);\n if (!initSuccess || uint256(bytes32(initResult)) != 1)\n revert SignatureMigrationFacet__SignerInitializationFailure();\n\n emit SignatureSchemeMigration(\n prevVerificationFacet,\n newVerificationFacet,\n newPublicKey,\n newVerificationFuncSelectors\n );\n }\n }\n\n /**\n * @notice Approve cancellation of signature migration. If cancellation approval passes guardian threshold with owner approval\n * it automatically cancels the migration.\n * @dev This method checks if the caller is one of guardian or owner and sets true for the cancellation hash in the approval config.\n * It internally calls _cancelSignatureMigration for canceling the migration\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function approveCancelSignatureMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n external\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"CancelSignatureMigration\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit SignatureMigrationCancellationApproved(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n if (\n getMigrationApprovalCountWithTimeValidity(migrationPublicKeyHash) >=\n LibGuardian.majorityOfGuardians() &&\n getMigrationOwnerApprovalWithTimeValidity(migrationPublicKeyHash)\n )\n _cancelSignatureMigration(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Verifies the signature of guardians/owner and cancels the signature migration.\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _approvers List of approvers. This could include owner\n */\n function cancelSignatureMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n )\n external\n override\n validateKeyType(_newPublicKey, _newVerificationFacet)\n onlyWhenUnlocked\n {\n if (_approvers.length != _signatures.length)\n revert SignatureMigrationFacet__InvalidArrayLength();\n\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"CancelSignatureMigration\"\n );\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(migrationPublicKeyHash, _approvers);\n\n bool onChainOwnerApproval = getMigrationOwnerApprovalWithTimeValidity(\n migrationPublicKeyHash\n );\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n if (\n _approvers.length +\n getMigrationApprovalCountWithTimeValidity(\n migrationPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert SignatureMigrationFacet__InsufficientApprovers();\n {\n // To prevent stack too deep\n bool ownerApproved;\n for (uint256 i; i < _approvers.length; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n address(this) != _approvers[i]\n ) revert SignatureMigrationFacet__NonExistentApprover();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert SignatureMigrationFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n migrationPublicKeyHash,\n _signatures[i]\n )\n ) revert SignatureMigrationFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n if (!ownerApproved && !onChainOwnerApproval)\n revert SignatureMigrationFacet__LackOfOwnerApproval();\n }\n _cancelSignatureMigration(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Internal function that cancels signature migration.\n * @dev This method increments migration nonce and deletes the migration from the migration config. Emits events for migration cancellation\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _cancelSignatureMigration(\n address _newVerificationFacet,\n bytes memory _newPublicKey,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal {\n if (!isMigrationPending())\n revert SignatureMigrationFacet__NonexistentMigration();\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n unchecked {\n ++ms.nonce;\n }\n delete ms.migrationConfigs[INNER_STRUCT];\n emit SignatureMigrationCanceled(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Checks if the facets to be added from new verification facet is registered to facet registry\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _checkMigrationCutValidity(\n address _newVerificationFacet,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal view {\n IDiamondCut.FacetCut[] memory facetCuts = new IDiamondCut.FacetCut[](1);\n facetCuts[0] = IDiamondCut.FacetCut({\n facetAddress: _newVerificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: _newVerificationFuncSelectors\n });\n _checkFacetCutValidity(facetCuts);\n }\n\n /**\n * @notice Returns if the migration is pending of not\n * @dev This method fetches the migration storage and checks if the migrate after is above 0 value\n * @return isPending Bool value that shows if the migration is pending\n */\n function isMigrationPending()\n public\n view\n override\n returns (bool isPending)\n {\n SignatureMigrationStorage storage rs = LibFacetStorage\n .migrationStorage();\n isPending = rs.migrationConfigs[INNER_STRUCT].migrateAfter > 0;\n }\n\n /**\n * @notice Returns the migration hash. This function ensures that this hash is safe from replay attack by including\n * public key, verification facet, function selectors, salt, address, chainId, and nonce.\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _saltString Salt value for generating the migration hash\n * @return migrationKeyHash Bytes32 string of the migration key hash\n */\n function getApprovalMigrationKeyHash(\n bytes memory _newPublicKey,\n address _newVerificationFacet,\n bytes4[] memory _newVerificationFuncSelectors,\n string memory _saltString\n ) public view override returns (bytes32 migrationKeyHash) {\n migrationKeyHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n _newPublicKey,\n _newVerificationFacet,\n keccak256(abi.encode(_newVerificationFuncSelectors)),\n _saltString,\n address(this),\n block.chainid,\n LibFacetStorage.migrationStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Checks if the owner approved the hash for migration\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @return isApprovedByOwner Bool value of showing if the owner approved it or not\n */\n function getMigrationOwnerApprovalWithTimeValidity(\n bytes32 _migrationPublicKeyHash\n ) public view override returns (bool isApprovedByOwner) {\n isApprovedByOwner = isMigrationApproved(\n _migrationPublicKeyHash,\n address(this)\n );\n }\n\n /**\n * @notice Checks how many of the guardians approved the migration hash\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @return approvalCount Number of approvals\n */\n function getMigrationApprovalCountWithTimeValidity(\n bytes32 _migrationPublicKeyHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardiansLength = guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n if (isMigrationApproved(_migrationPublicKeyHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n return approvalCount;\n }\n\n /**\n * @notice Checks if the migration is approved by the given approver\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @param _approver Address of approver\n * @return isApproved Bool value if migration hash is approved\n */\n function isMigrationApproved(\n bytes32 _migrationPublicKeyHash,\n address _approver\n ) public view override returns (bool isApproved) {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n isApproved = (ms\n .isMigrationApproved[_migrationPublicKeyHash][_approver].isApproved &&\n block.timestamp <\n ms\n .isMigrationApproved[_migrationPublicKeyHash][_approver]\n .validUntil);\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _migrationPublicKeyHash Hash of migration information\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _migrationPublicKeyHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isMigrationApproved(_migrationPublicKeyHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert SignatureMigrationFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the migration period of this wallet\n * @dev This method fetches the migration period from the security manager\n * @return migrationPeriod Migration period of Barz contract fetched from security manager\n */\n function getMigrationPeriod()\n internal\n view\n returns (uint128 migrationPeriod)\n {\n migrationPeriod = securityManager.migrationPeriodOf(address(this));\n if (migrationPeriod == 0)\n revert SignatureMigrationFacet__InvalidMigrationPeriod();\n }\n\n /**\n * @notice Returns the validation period of this wallet\n * @dev This method fetches the validation period from the security manager\n * @return approvalValidationPeriod Validation period of Barz contract fetched from security manager\n */\n function getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod == 0)\n revert SignatureMigrationFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the migration nonce of this wallet\n * @dev This method fetches the nonce from migration storage\n * @return migrationNonce Nonce of migration to protect from reply attacks\n */\n function getMigrationNonce()\n public\n view\n override\n returns (uint128 migrationNonce)\n {\n migrationNonce = LibFacetStorage.migrationStorage().nonce;\n }\n\n /**\n * @notice Returns the migration configuration of this wallet\n * @dev This method fetches the migration config from the migration storage\n * @return pendingMigrationConfig Migration config currently pending for signature migration\n */\n function getPendingMigration()\n external\n view\n override\n returns (SignatureMigrationConfig memory pendingMigrationConfig)\n {\n pendingMigrationConfig = LibFacetStorage\n .migrationStorage()\n .migrationConfigs[INNER_STRUCT];\n }\n}\n" + }, + "contracts/facets/TokenReceiverFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {IERC1155Receiver} from \"../interfaces/ERC/IERC1155Receiver.sol\";\nimport {IERC677Receiver} from \"../interfaces/ERC/IERC677Receiver.sol\";\n\n/**\n * @title TokenReceiver Facet\n * @dev Contract that enables receiving ERC721/ERC1155/ERC777/ERC677 Tokens with safe transfer\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract TokenReceiverFacet is\n IERC721Receiver,\n IERC1155Receiver,\n IERC777Recipient,\n IERC677Receiver\n{\n /**\n * @notice Handles ERC721 Token callback.\n * return Standardized onERC721Received return value.\n */\n function onERC721Received(\n address,\n address,\n uint256,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC721Receiver.onERC721Received.selector;\n }\n\n /**\n * @notice Handles ERC1155 Token callback.\n * return Standardized onERC1155Received return value.\n */\n function onERC1155Received(\n address,\n address,\n uint256,\n uint256,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC1155Receiver.onERC1155Received.selector;\n }\n\n /**\n * @notice Handles ERC1155 Token batch callback.\n * return Standardized onERC1155BatchReceived return value.\n */\n function onERC1155BatchReceived(\n address,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC1155Receiver.onERC1155BatchReceived.selector;\n }\n\n /**\n * @notice Handles ERC777 Token callback.\n * Does not return value, empty implementation.\n */\n function tokensReceived(\n address,\n address,\n address,\n uint256,\n bytes calldata,\n bytes calldata\n ) external pure override {}\n\n /**\n * @notice Handles ERC677 Token callback.\n * return true.\n */\n function onTokenTransfer(\n address,\n uint256,\n bytes calldata\n ) external pure override returns (bool) {\n return true;\n }\n}\n" + }, + "contracts/facets/verification/MultiSigFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {UserOperation} from \"../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../../libraries/LibLoupe.sol\";\nimport {LibAppStorage} from \"../../libraries/LibAppStorage.sol\";\nimport {LibMultiSigStorage, MultiSigStorage} from \"../../libraries/LibMultiSigStorage.sol\";\nimport {IERC1271} from \"../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../interfaces/IVerificationFacet.sol\";\nimport {IMultiSigFacet} from \"../interfaces/IMultiSigFacet.sol\";\n\n/**\n * @title Multi-sig facet\n * @dev Multi-signature Facet with custom threshold.\n * Wallet that adds this facet becomes a multi-sig wallet.\n * Reference signature_format.md documentation for Multi-sig facet details\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract MultiSigFacet is IMultiSigFacet, IVerificationFacet, IERC1271 {\n using ECDSA for bytes32;\n\n address public immutable self;\n\n address internal constant SENTINEL_OWNERS = address(0x1);\n uint256 internal constant ADDRESS = 20;\n uint256 internal constant SIG_TYPE = 1;\n uint256 internal constant SIG_LEN = 4;\n uint256 internal constant THRESHOLD = 4;\n uint256 internal constant INVALID_SIG = 1;\n uint256 internal constant VALID_SIG = 0;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in Multisig Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the right format and initializes signer storage in k1 storage.\n * @param _owners Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _owners\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n\n if (!isValidKeyType(_owners)) revert MultiSigFacet__InvalidInitData();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n uint256 threshold = uint256(uint32(bytes4(_owners)));\n uint256 ownerCount = (_owners.length - THRESHOLD) / ADDRESS;\n\n if (threshold == 0) revert MultiSigFacet__InvalidThreshold();\n if (ownerCount == 0) revert MultisigFacet__InvalidOwnerCount();\n\n address currentOwner = SENTINEL_OWNERS;\n uint256 ptr = THRESHOLD;\n address owner_;\n for (uint256 i; i < ownerCount; ) {\n owner_ = address(bytes20(_owners[ptr:ptr + ADDRESS]));\n ptr += ADDRESS;\n if (\n owner_ == address(0) ||\n owner_ == SENTINEL_OWNERS ||\n owner_ == address(this) ||\n owner_ == currentOwner\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[owner_] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n\n ms.owners[currentOwner] = owner_;\n currentOwner = owner_;\n\n unchecked {\n ++i;\n }\n }\n ms.owners[currentOwner] = SENTINEL_OWNERS;\n ms.ownerCount = ownerCount;\n ms.threshold = threshold;\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_owners);\n }\n\n /**\n * @notice Uninitialize signer in K1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n ++ms.counter;\n address[] memory ownerlist = getOwners();\n uint256 ownerlistLength = ownerlist.length;\n for (uint256 i; i < ownerlistLength; ) {\n ms.owners[ownerlist[i]] = address(0);\n unchecked {\n ++i;\n }\n }\n ms.owners[SENTINEL_OWNERS] = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls checkSignatures with\n * user operation hash and signature together with the threshold.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n // Data 1 is invalid, Data 0 is valid\n validationData = checkSignatures(\n userOpHash,\n userOp.signature,\n LibMultiSigStorage.multisigStorage().threshold\n );\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n return this.validateOwnerSignature.selector;\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n uint totalLength = ms.ownerCount * ADDRESS;\n bytes memory result = new bytes(totalLength);\n\n // populate return array\n uint256 index;\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n while (currentOwner != SENTINEL_OWNERS) {\n assembly {\n mstore(\n add(result, add(32, mul(index, ADDRESS))),\n shl(96, currentOwner)\n )\n }\n currentOwner = ms.owners[currentOwner];\n index++;\n }\n\n return result;\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key should comply with the format in the signature_format.md doc\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n uint256 publicKeyLength = _publicKey.length;\n if (\n publicKeyLength < ADDRESS + THRESHOLD ||\n (publicKeyLength - THRESHOLD) % ADDRESS != 0\n ) return false;\n\n uint256 threshold = uint256(uint32(bytes4(_publicKey)));\n uint256 ownerCount = (publicKeyLength - THRESHOLD) / ADDRESS;\n\n isValid = !(ownerCount < threshold || threshold == 0);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes calldata _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (checkSignatures(\n _hash,\n _signature,\n LibMultiSigStorage.multisigStorage().threshold\n ) == VALID_SIG)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n\n /**\n * @notice Validates the format of the signature and verifies if the signature is signed by the expected key.\n * Reference signature_format.md doc for details about signature format and signature types\n * @param _dataHash Bytes value of data hash signed by the owners\n * @param _signatures Bytes value of signature which should comply with signature format\n * @param _threshold Uint256 value of current Multi-sig Barz's threshold\n */\n function checkSignatures(\n bytes32 _dataHash,\n bytes calldata _signatures,\n uint256 _threshold\n ) public view returns (uint256) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n address lastOwner = address(0);\n address currentOwner;\n bytes memory signature;\n uint256 signatureType;\n uint256 nextOffset;\n uint256 i;\n for (i; i < _threshold; ) {\n (\n currentOwner,\n signature,\n signatureType,\n nextOffset\n ) = splitSignatures(_signatures, nextOffset);\n if (nextOffset == 0 && i + 1 < _threshold) return INVALID_SIG;\n if (signatureType == 1) {\n // If signatureType is 1 then it is default dataHash signed.\n // This also includes the contract signature\n if (\n !SignatureChecker.isValidSignatureNow(\n currentOwner,\n _dataHash,\n signature\n )\n ) return INVALID_SIG;\n } else if (signatureType == 2) {\n // If signatureType is 2 then it is an approved hash\n if (ms.approvedHashes[ms.counter][currentOwner][_dataHash] == 0)\n return INVALID_SIG;\n } else if (signatureType == 3) {\n // If signatureType is 3 then it is a signed message hash\n // This also includes the contract signature\n bytes32 msgHash = _dataHash.toEthSignedMessageHash();\n if (\n !SignatureChecker.isValidSignatureNow(\n currentOwner,\n msgHash,\n signature\n )\n ) return INVALID_SIG;\n } else revert MultiSigFacet__InvalidRoute();\n if (\n currentOwner <= lastOwner ||\n ms.owners[currentOwner] == address(0) ||\n currentOwner == SENTINEL_OWNERS\n ) return INVALID_SIG;\n lastOwner = currentOwner;\n\n unchecked {\n ++i;\n }\n }\n return VALID_SIG;\n }\n\n /**\n * @notice Split signatures into each individual signatures. Should comply with signature format to be split\n * @param _signatures Bytes value of signature\n * @param _nextOffset Uint256 value of next offset to start splitting the signature\n */\n function splitSignatures(\n bytes calldata _signatures,\n uint256 _nextOffset\n )\n public\n pure\n returns (\n address owner_,\n bytes memory signature,\n uint256 signatureType,\n uint256 nextOffset\n )\n {\n uint256 signaturesLength = _signatures.length;\n\n if (signaturesLength <= _nextOffset + ADDRESS + SIG_LEN)\n revert MultiSigFacet__InsufficientSignerLength();\n\n owner_ = address(\n bytes20(_signatures[_nextOffset:_nextOffset + ADDRESS])\n );\n\n signatureType = uint256(\n uint8(\n bytes1(\n _signatures[_nextOffset + ADDRESS:_nextOffset +\n ADDRESS +\n SIG_TYPE]\n )\n )\n );\n\n if (signatureType > 3 || signatureType == 0)\n revert MultiSigFacet__InvalidSignatureType();\n uint256 offSet = _nextOffset + ADDRESS + SIG_TYPE;\n uint256 siglen = uint256(\n uint32(bytes4(_signatures[offSet:offSet + SIG_LEN]))\n );\n if (offSet + siglen > signaturesLength)\n revert MultiSigFacet__InvalidSignatureLength();\n\n offSet += SIG_LEN;\n if (offSet + siglen == signaturesLength) nextOffset = 0;\n else nextOffset = offSet + siglen;\n\n signature = _signatures[offSet:offSet + siglen];\n }\n\n /**\n * @notice Approves the hash of userOperation on-chain. This can only be called by owners.\n * @param _hashToApprove Bytes value of UserOperation hash to approve\n */\n function approveHash(bytes32 _hashToApprove) external {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (ms.owners[msg.sender] == address(0))\n revert MultiSigFacet__OnlyOwner();\n\n ms.approvedHashes[ms.counter][msg.sender][_hashToApprove] = 1;\n emit HashApproved(_hashToApprove, msg.sender);\n }\n\n /**\n * @notice Add owner to Barz. Update thresold if threshold is given different from current threshold\n * @dev This can only be done via a Self call.\n * @param _newOwner Address of new owner to be added\n * @param _threshold Uint256 value of threshold\n */\n function addOwner(address _newOwner, uint256 _threshold) external {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (\n _newOwner == address(0) ||\n _newOwner == SENTINEL_OWNERS ||\n _newOwner == address(this)\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_newOwner] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n\n ms.owners[_newOwner] = ms.owners[SENTINEL_OWNERS];\n ms.owners[SENTINEL_OWNERS] = _newOwner;\n ++ms.ownerCount;\n emit OwnerAdded(_newOwner);\n\n if (ms.threshold != _threshold) changeThreshold(_threshold);\n }\n\n /**\n * @notice Remove owner from Barz. Update thresold if threshold is given different from current threshold\n * @dev This can only be done via a Self call.\n * @param _prevOwner Address of owner located right behind the removed owner address in the linked list\n * @param _removedOwner Address of owner to be removed\n * @param _threshold Uint256 value of threshold\n */\n function removeOwner(\n address _prevOwner,\n address _removedOwner,\n uint256 _threshold\n ) external {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (ms.ownerCount - 1 < _threshold)\n revert MultiSigFacet__InvalidThreshold();\n if (_removedOwner == address(0) || _removedOwner == SENTINEL_OWNERS)\n revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_prevOwner] != _removedOwner)\n revert MultiSigFacet__InvalidOwnerPair();\n\n ms.owners[_prevOwner] = ms.owners[_removedOwner];\n ms.owners[_removedOwner] = address(0);\n --ms.ownerCount;\n emit OwnerRemoved(_removedOwner);\n\n if (ms.threshold != _threshold) changeThreshold(_threshold);\n }\n\n /**\n * @notice Swap owner in Barz.\n * @dev This can only be done via a Self call.\n * @param _prevOwner Address of owner located right behind the removed owner address in the linked list\n * @param _oldOwner Address of owner to be removed\n * @param _newOwner Address of owner to be added\n */\n function swapOwner(\n address _prevOwner,\n address _oldOwner,\n address _newOwner\n ) public {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (\n _newOwner == address(0) ||\n _newOwner == SENTINEL_OWNERS ||\n _newOwner == address(this)\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_newOwner] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n if (_oldOwner == address(0) || _oldOwner == SENTINEL_OWNERS)\n revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_prevOwner] != _oldOwner)\n revert MultiSigFacet__InvalidOwnerPair();\n\n ms.owners[_newOwner] = ms.owners[_oldOwner];\n ms.owners[_prevOwner] = _newOwner;\n ms.owners[_oldOwner] = address(0);\n emit OwnerRemoved(_oldOwner);\n emit OwnerAdded(_newOwner);\n }\n\n /**\n * @notice Changes the threshold of the Barz to `_threshold`.\n * @dev This can only be done via a Self call.\n * @param _threshold New threshold\n */\n function changeThreshold(uint256 _threshold) public {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (_threshold > ms.ownerCount || _threshold == 0)\n revert MultiSigFacet__InvalidThreshold();\n\n ms.threshold = _threshold;\n emit ThresholdChanged(_threshold);\n }\n\n /**\n * @notice Checks if the given address is owner\n * @param _owner Address to be checked if it's owner\n * @return isOwner_ Bool value showing if it's owner address\n */\n function isOwner(address _owner) public view returns (bool isOwner_) {\n isOwner_ = (_owner != SENTINEL_OWNERS &&\n LibMultiSigStorage.multisigStorage().owners[_owner] != address(0));\n }\n\n /**\n * @notice Returns the threshold of Barz\n * @return threshold Threshold of the Barz account\n */\n function getThreshold() public view returns (uint256 threshold) {\n threshold = LibMultiSigStorage.multisigStorage().threshold;\n }\n\n /**\n * @notice Returns the list of owner addresses\n * @return owners List of owners\n */\n function getOwners() public view returns (address[] memory owners) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n owners = new address[](ms.ownerCount);\n\n uint256 index;\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n while (currentOwner != SENTINEL_OWNERS) {\n owners[index] = currentOwner;\n currentOwner = ms.owners[currentOwner];\n index++;\n }\n }\n\n /**\n * @notice Returns the previous owner in the linked list\n * @param _owner Address of owner\n * @return prevOwner Address of previous owner\n */\n function getPrevOwner(\n address _owner\n ) public view returns (address prevOwner) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n if (currentOwner == _owner) return SENTINEL_OWNERS;\n while (currentOwner != SENTINEL_OWNERS) {\n if (ms.owners[currentOwner] == _owner) return currentOwner;\n\n currentOwner = ms.owners[currentOwner];\n }\n return address(0);\n }\n\n /**\n * @notice Returns of the owner is approved by given owner address\n * @param _owner Address of owner\n * @param _hash Hash of UserOperation\n * @return isApproved Bool value showing if the hash is approved by owner\n */\n function isApprovedHash(\n address _owner,\n bytes32 _hash\n ) public view returns (bool isApproved) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n isApproved = (ms.approvedHashes[ms.counter][_owner][_hash] == 1);\n }\n}\n" + }, + "contracts/facets/verification/secp256k1/Secp256k1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {UserOperation} from \"../../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibAppStorage} from \"../../../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, Secp256k1VerificationStorage} from \"../../../libraries/LibFacetStorage.sol\";\nimport {LibLoupe} from \"../../../libraries/LibLoupe.sol\";\nimport {IERC1271} from \"../../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../../interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Secp256k1 verification facet\n * @dev Default Ethereum's elliptic curve\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract Secp256k1VerificationFacet is IVerificationFacet, IERC1271 {\n using ECDSA for bytes32;\n error Secp256k1VerificationFacet__InvalidSignerLength();\n address public immutable self;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in K1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\n * @param _publicKey Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _publicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n if (!isValidKeyType(_publicKey))\n revert Secp256k1VerificationFacet__InvalidSignerLength();\n\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(uint160(uint256(keccak256(_publicKey[1:]))));\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_publicKey);\n }\n\n /**\n * @notice Uninitialize signer in K1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\n * signer public key.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n validationData = validateSignature(\n userOp,\n userOpHash,\n k1Storage.signer\n );\n }\n\n /**\n * @notice Validates if the signature of UserOperation is signed by the given signer\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @param signer Address of signer who signed the contract, to be validated\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n address signer\n ) public pure returns (uint256 isValid) {\n bytes32 hash = userOpHash.toEthSignedMessageHash();\n isValid = (signer != hash.recover(userOp.signature)) ? 1 : 0;\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n ownerSignatureValidatorSelector = this.validateOwnerSignature.selector;\n // NOTE: The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory signer) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n signer = abi.encodePacked(k1Storage.signer);\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key length should be 65 in an uncompressed public key format\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (_hash.recover(_signature) ==\n LibFacetStorage.k1Storage().signer)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/Secp256r1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {UserOperation} from \"../../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibAppStorage} from \"../../../libraries/LibAppStorage.sol\";\nimport {LibLoupe} from \"../../../libraries/LibLoupe.sol\";\nimport {LibFacetStorage, Secp256r1VerificationStorage} from \"../../../libraries/LibFacetStorage.sol\";\nimport {Base64} from \"./utils/Base64.sol\";\nimport {LibSecp256r1} from \"./utils/LibSecp256r1.sol\";\nimport {IERC1271} from \"../../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../../interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Secp256r1 verification facet\n * @dev Primarily used to verify user ops signed with passkeys\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract Secp256r1VerificationFacet is IVerificationFacet, IERC1271 {\n error Secp256r1VerificationFacet__InvalidSignerLength();\n address public immutable self;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in R1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\n * @param _publicKey Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _publicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n\n if (!isValidKeyType(_publicKey))\n revert Secp256r1VerificationFacet__InvalidSignerLength();\n\n bytes memory publicKeyCoordinates = _publicKey[1:];\n uint256[2] memory q;\n assembly {\n // Copy the bytes from the input data into the uint256 array\n mstore(q, mload(add(publicKeyCoordinates, 32)))\n mstore(add(q, 32), mload(add(publicKeyCoordinates, 64)))\n }\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n r1Storage.q = q;\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_publicKey);\n }\n\n /**\n * @notice Uninitialize signer in R1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n r1Storage.q = [0, 0];\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\n * signer public key.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n validationData = validateSignature(userOp, userOpHash, r1Storage.q);\n }\n\n /**\n * @notice Validates if the signature of UserOperation is signed by the given signer\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @param q Public Key of signer who signed the contract, to be validated\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256[2] memory q\n ) public view returns (uint256 isValid) {\n isValid = (_validateSignature(q, userOpHash, userOp.signature)) ? 0 : 1;\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n return this.validateOwnerSignature.selector; // validateOwnerSignature(UserOperation calldata userOp,bytes32 userOpHash)\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory signer) {\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n signer = abi.encodePacked(r1Storage.q);\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key should in an uncompressed public key format\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = _validateSignature(\n LibFacetStorage.r1Storage().q,\n _hash,\n _signature\n )\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n\n function _validateSignature(\n uint256[2] memory q,\n bytes32 _hash,\n bytes memory _signature\n ) internal view returns (bool) {\n (\n uint256 rValue,\n uint256 sValue,\n bytes memory authenticatorData,\n string memory clientDataJSONPre,\n string memory clientDataJSONPost\n ) = abi.decode(_signature, (uint256, uint256, bytes, string, string));\n bytes32 clientHash;\n {\n string memory opHashBase64 = Base64.encode(bytes.concat(_hash));\n string memory clientDataJSON = string.concat(\n clientDataJSONPre,\n opHashBase64,\n clientDataJSONPost\n );\n clientHash = sha256(bytes(clientDataJSON));\n }\n bytes32 sigHash = sha256(bytes.concat(authenticatorData, clientHash));\n return LibSecp256r1.Verify(q, rValue, sValue, uint256(sigHash));\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/utils/Base64.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @dev Provides a set of functions to operate with Base64 strings.\n * modified for base64url https://datatracker.ietf.org/doc/html/rfc4648#section-5\n * _Available since v4.5._\n */\nlibrary Base64 {\n /**\n * @dev Base64 Encoding/Decoding Table\n */\n string internal constant _TABLE =\n \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_\";\n\n /**\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\n */\n function encode(bytes memory data) internal pure returns (string memory) {\n /**\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\n */\n if (data.length == 0) return \"\";\n\n // Loads the table into memory\n string memory table = _TABLE;\n\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\n // and split into 4 numbers of 6 bits.\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\n // - `data.length + 2` -> Round up\n // - `/ 3` -> Number of 3-bytes chunks\n // - `4 *` -> 4 characters for each chunk\n uint256 newlength = (data.length * 8) / 6;\n if (data.length % 6 > 0) {\n newlength++;\n }\n string memory result = new string(newlength);\n\n /// @solidity memory-safe-assembly\n assembly {\n // Prepare the lookup table (skip the first \"length\" byte)\n let tablePtr := add(table, 1)\n\n // Prepare result pointer, jump over length\n let resultPtr := add(result, 32)\n\n // Run over the input, 3 bytes at a time\n for {\n let dataPtr := data\n let endPtr := add(data, mload(data))\n } lt(dataPtr, endPtr) {\n\n } {\n // Advance 3 bytes\n dataPtr := add(dataPtr, 3)\n let input := mload(dataPtr)\n\n // To write each character, shift the 3 bytes (18 bits) chunk\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\n // and apply logical AND with 0x3F which is the number of\n // the previous character in the ASCII table prior to the Base64 Table\n // The result is then added to the table to get the character to write,\n // and finally write it in the result pointer but with a left shift\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(18, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(12, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(6, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n }\n }\n\n return result;\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/utils/LibSecp256r1.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n// Heavily inspired from\n// https://github.com/maxrobot/elliptic-solidity/blob/master/contracts/Secp256r1.sol\n// https://github.com/tdrerup/elliptic-curve-solidity/blob/master/contracts/curves/EllipticCurve.sol\n// modified to use precompile 0x05 modexp\n// and modified jacobian double\n// optimisations to avoid to an from from affine and jacobian coordinates\n\n// Additional Elliptic curve Public key / Signature validation added by\n// David Yonjun Kim (@Powerstream3604)\n\nstruct JPoint {\n uint256 x;\n uint256 y;\n uint256 z;\n}\n\nlibrary LibSecp256r1 {\n uint256 constant gx =\n 0x6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296;\n uint256 constant gy =\n 0x4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5;\n uint256 public constant pp =\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF;\n\n uint256 public constant nn =\n 0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551;\n uint256 constant a =\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC;\n uint256 constant b =\n 0x5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B;\n uint256 constant MOST_SIGNIFICANT =\n 0xc000000000000000000000000000000000000000000000000000000000000000;\n\n /*\n * Verify\n * @description - verifies that a public key has signed a given message\n * @param Q - public key coordinates X & Y\n * @param R - signature half R\n * @param S - signature half S\n * @param input - hashed message\n */\n function Verify(\n uint256[2] memory q,\n uint r,\n uint s,\n uint e\n ) internal view returns (bool) {\n if (q[0] > pp - 1 || q[1] > pp - 1) {\n return false;\n }\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\n return false;\n }\n if (\n mulmod(q[1], q[1], pp) !=\n addmod(\n addmod(\n mulmod(q[0], mulmod(q[0], q[0], pp), pp),\n mulmod(a, q[0], pp),\n pp\n ),\n b,\n pp\n )\n ) {\n return false;\n }\n\n JPoint[16] memory points = _preComputeJacobianPoints(q);\n return VerifyWithPrecompute(points, r, s, e);\n }\n\n function VerifyWithPrecompute(\n JPoint[16] memory points,\n uint r,\n uint s,\n uint e\n ) internal view returns (bool) {\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\n return false;\n }\n\n uint w = _primemod(s, nn);\n\n uint u1 = mulmod(e, w, nn);\n uint u2 = mulmod(r, w, nn);\n\n uint x;\n uint y;\n\n (x, y) = ShamirMultJacobian(points, u1, u2);\n return (x == r);\n }\n\n /*\n * Strauss Shamir trick for EC multiplication\n * https://stackoverflow.com/questions/50993471/ec-scalar-multiplication-with-strauss-shamir-method\n * we optimise on this a bit to do with 2 bits at a time rather than a single bit\n * the individual points for a single pass are precomputed\n * overall this reduces the number of additions while keeping the same number of doublings\n */\n function ShamirMultJacobian(\n JPoint[16] memory points,\n uint u1,\n uint u2\n ) internal view returns (uint, uint) {\n uint x = 0;\n uint y = 0;\n uint z = 0;\n uint bits = 128;\n uint index = 0;\n\n while (bits > 0) {\n if (z > 0) {\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\n }\n index =\n ((u1 & MOST_SIGNIFICANT) >> 252) |\n ((u2 & MOST_SIGNIFICANT) >> 254);\n if (index > 0) {\n (x, y, z) = _jAdd(\n x,\n y,\n z,\n points[index].x,\n points[index].y,\n points[index].z\n );\n }\n u1 <<= 2;\n u2 <<= 2;\n bits--;\n }\n (x, y) = _affineFromJacobian(x, y, z);\n return (x, y);\n }\n\n function _preComputeJacobianPoints(\n uint256[2] memory q\n ) internal pure returns (JPoint[16] memory points) {\n points[0] = JPoint(0, 0, 0);\n points[1] = JPoint(q[0], q[1], 1); // u2\n points[2] = _jPointDouble(points[1]);\n points[3] = _jPointAdd(points[1], points[2]);\n\n points[4] = JPoint(gx, gy, 1); // u1Points[1]\n points[5] = _jPointAdd(points[4], points[1]);\n points[6] = _jPointAdd(points[4], points[2]);\n points[7] = _jPointAdd(points[4], points[3]);\n\n points[8] = _jPointDouble(points[4]); // u1Points[2]\n points[9] = _jPointAdd(points[8], points[1]);\n points[10] = _jPointAdd(points[8], points[2]);\n points[11] = _jPointAdd(points[8], points[3]);\n\n points[12] = _jPointAdd(points[4], points[8]); // u1Points[3]\n points[13] = _jPointAdd(points[12], points[1]);\n points[14] = _jPointAdd(points[12], points[2]);\n points[15] = _jPointAdd(points[12], points[3]);\n }\n\n function _jPointAdd(\n JPoint memory p1,\n JPoint memory p2\n ) internal pure returns (JPoint memory) {\n uint x;\n uint y;\n uint z;\n (x, y, z) = _jAdd(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z);\n return JPoint(x, y, z);\n }\n\n function _jPointDouble(\n JPoint memory p\n ) internal pure returns (JPoint memory) {\n uint x;\n uint y;\n uint z;\n (x, y, z) = _modifiedJacobianDouble(p.x, p.y, p.z);\n return JPoint(x, y, z);\n }\n\n /* _affineFromJacobian\n * @desription returns affine coordinates from a jacobian input follows\n * golang elliptic/crypto library\n */\n function _affineFromJacobian(\n uint x,\n uint y,\n uint z\n ) internal view returns (uint ax, uint ay) {\n if (z == 0) {\n return (0, 0);\n }\n\n uint zinv = _primemod(z, pp);\n uint zinvsq = mulmod(zinv, zinv, pp);\n\n ax = mulmod(x, zinvsq, pp);\n ay = mulmod(y, mulmod(zinvsq, zinv, pp), pp);\n }\n\n /*\n * _jAdd\n * @description performs Jacobian addition as defined below:\n * http://www.hyperelliptic.org/EFD/g1p/data/shortw/jacobian/addition/add-2007-bl\n */\n function _jAdd(\n uint p1,\n uint p2,\n uint p3,\n uint q1,\n uint q2,\n uint q3\n ) internal pure returns (uint r1, uint r2, uint r3) {\n if (p3 == 0) {\n r1 = q1;\n r2 = q2;\n r3 = q3;\n\n return (r1, r2, r3);\n } else if (q3 == 0) {\n r1 = p1;\n r2 = p2;\n r3 = p3;\n\n return (r1, r2, r3);\n }\n\n assembly {\n let\n pd\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\n let z1z1 := mulmod(p3, p3, pd) // Z1Z1 = Z1^2\n let z2z2 := mulmod(q3, q3, pd) // Z2Z2 = Z2^2\n\n let u1 := mulmod(p1, z2z2, pd) // U1 = X1*Z2Z2\n let u2 := mulmod(q1, z1z1, pd) // U2 = X2*Z1Z1\n\n let s1 := mulmod(p2, mulmod(z2z2, q3, pd), pd) // S1 = Y1*Z2*Z2Z2\n let s2 := mulmod(q2, mulmod(z1z1, p3, pd), pd) // S2 = Y2*Z1*Z1Z1\n\n let p3q3 := addmod(p3, q3, pd)\n\n if lt(u2, u1) {\n u2 := add(pd, u2) // u2 = u2+pd\n }\n let h := sub(u2, u1) // H = U2-U1\n\n let i := mulmod(0x02, h, pd)\n i := mulmod(i, i, pd) // I = (2*H)^2\n\n let j := mulmod(h, i, pd) // J = H*I\n if lt(s2, s1) {\n s2 := add(pd, s2) // u2 = u2+pd\n }\n let rr := mulmod(0x02, sub(s2, s1), pd) // r = 2*(S2-S1)\n r1 := mulmod(rr, rr, pd) // X3 = R^2\n\n let v := mulmod(u1, i, pd) // V = U1*I\n let j2v := addmod(j, mulmod(0x02, v, pd), pd)\n if lt(r1, j2v) {\n r1 := add(pd, r1) // X3 = X3+pd\n }\n r1 := sub(r1, j2v)\n\n // Y3 = r*(V-X3)-2*S1*J\n let s12j := mulmod(mulmod(0x02, s1, pd), j, pd)\n\n if lt(v, r1) {\n v := add(pd, v)\n }\n r2 := mulmod(rr, sub(v, r1), pd)\n\n if lt(r2, s12j) {\n r2 := add(pd, r2)\n }\n r2 := sub(r2, s12j)\n\n // Z3 = ((Z1+Z2)^2-Z1Z1-Z2Z2)*H\n z1z1 := addmod(z1z1, z2z2, pd)\n j2v := mulmod(p3q3, p3q3, pd)\n if lt(j2v, z1z1) {\n j2v := add(pd, j2v)\n }\n r3 := mulmod(sub(j2v, z1z1), h, pd)\n }\n return (r1, r2, r3);\n }\n\n // Point doubling on the modified jacobian coordinates\n // http://point-at-infinity.org/ecc/Prime_Curve_Modified_Jacobian_Coordinates.html\n function _modifiedJacobianDouble(\n uint x,\n uint y,\n uint z\n ) internal pure returns (uint x3, uint y3, uint z3) {\n if (y == 0) return (0, 0, 0);\n assembly {\n let\n pd\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\n let z2 := mulmod(z, z, pd)\n let az4 := mulmod(\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC,\n mulmod(z2, z2, pd),\n pd\n )\n let y2 := mulmod(y, y, pd)\n let s := mulmod(0x04, mulmod(x, y2, pd), pd)\n let u := mulmod(0x08, mulmod(y2, y2, pd), pd)\n let m := addmod(mulmod(0x03, mulmod(x, x, pd), pd), az4, pd)\n let twos := mulmod(0x02, s, pd)\n let m2 := mulmod(m, m, pd)\n if lt(m2, twos) {\n m2 := add(pd, m2)\n }\n x3 := sub(m2, twos)\n if lt(s, x3) {\n s := add(pd, s)\n }\n y3 := mulmod(m, sub(s, x3), pd)\n if lt(y3, u) {\n y3 := add(pd, y3)\n }\n y3 := sub(y3, u)\n z3 := mulmod(0x02, mulmod(y, z, pd), pd)\n }\n }\n\n // Fermats little theorem https://en.wikipedia.org/wiki/Fermat%27s_little_theorem\n // a^(p-1) = 1 mod p\n // a^(-1) ≅ a^(p-2) (mod p)\n // we then use the precompile bigModExp to compute a^(-1)\n function _primemod(uint value, uint p) internal view returns (uint ret) {\n ret = modexp(value, p - 2, p);\n return ret;\n }\n\n // Wrapper for built-in BigNumber_modexp (contract 0x5) as described here. https://github.com/ethereum/EIPs/pull/198\n function modexp(\n uint _base,\n uint _exp,\n uint _mod\n ) internal view returns (uint ret) {\n // bigModExp(_base, _exp, _mod);\n assembly {\n if gt(_base, _mod) {\n _base := mod(_base, _mod)\n }\n // Free memory pointer is always stored at 0x40\n let freemem := mload(0x40)\n\n mstore(freemem, 0x20)\n mstore(add(freemem, 0x20), 0x20)\n mstore(add(freemem, 0x40), 0x20)\n\n mstore(add(freemem, 0x60), _base)\n mstore(add(freemem, 0x80), _exp)\n mstore(add(freemem, 0xa0), _mod)\n\n let success := staticcall(14000, 0x5, freemem, 0xc0, freemem, 0x20)\n switch success\n case 0 {\n revert(0x0, 0x0)\n }\n default {\n ret := mload(freemem)\n }\n }\n }\n}\n" + }, + "contracts/infrastructure/DefaultFallbackHandler.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC1155Receiver} from \"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\";\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {BaseAccount} from \"../aa-4337/core/BaseAccount.sol\";\nimport {DefaultLibDiamond} from \"../libraries/DefaultLibDiamond.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IAccountFacet} from \"../facets/interfaces/IAccountFacet.sol\";\nimport {IStorageLoupe} from \"../facets/base/interfaces/IStorageLoupe.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IERC677Receiver} from \"../interfaces/ERC/IERC677Receiver.sol\";\nimport {IERC165} from \"../interfaces/ERC/IERC165.sol\";\n\n/**\n * @title DefaultFallbackHandler\n * @dev A default fallback handler for Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DefaultFallbackHandler is IDiamondLoupe {\n /**\n * @notice Sets the middleware diamond for Barz wallet as a fallback handler\n * @dev This contract is also a diamond that holds the default facets to reduce gas cost for wallet activation.\n * Within the constructor this conducts diamond cut to initially setup the diamond. This is a non-upgradeable contract\n * @param _diamondCutFacet Address if diamond cut facet\n * @param _accountFacet Address account facet\n * @param _tokenReceiverFacet Address of token receiver facet\n * @param _diamondLoupeFacet Address of diamond loupe facet\n */\n constructor(\n address _diamondCutFacet,\n address _accountFacet,\n address _tokenReceiverFacet,\n address _diamondLoupeFacet\n ) payable {\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](4);\n bytes4[] memory functionSelectors = new bytes4[](1);\n functionSelectors[0] = IDiamondCut.diamondCut.selector;\n\n bytes4[] memory accountFunctionSelectors = new bytes4[](5);\n accountFunctionSelectors[0] = IAccountFacet.execute.selector;\n accountFunctionSelectors[1] = IAccountFacet.executeBatch.selector;\n accountFunctionSelectors[2] = BaseAccount.validateUserOp.selector;\n accountFunctionSelectors[3] = BaseAccount.getNonce.selector;\n accountFunctionSelectors[4] = BaseAccount.entryPoint.selector;\n\n bytes4[] memory receiverFacetSelectors = new bytes4[](5);\n receiverFacetSelectors[0] = IERC721Receiver.onERC721Received.selector;\n receiverFacetSelectors[1] = IERC1155Receiver.onERC1155Received.selector;\n receiverFacetSelectors[2] = IERC1155Receiver\n .onERC1155BatchReceived\n .selector;\n receiverFacetSelectors[3] = IERC777Recipient.tokensReceived.selector;\n receiverFacetSelectors[4] = IERC677Receiver.onTokenTransfer.selector;\n\n bytes4[] memory loupeFacetSelectors = new bytes4[](9);\n loupeFacetSelectors[0] = IDiamondLoupe.facets.selector;\n loupeFacetSelectors[1] = IDiamondLoupe.facetFunctionSelectors.selector;\n loupeFacetSelectors[2] = IDiamondLoupe.facetAddresses.selector;\n loupeFacetSelectors[3] = IDiamondLoupe.facetAddress.selector;\n loupeFacetSelectors[4] = IERC165.supportsInterface.selector;\n loupeFacetSelectors[5] = IStorageLoupe.facetsFromStorage.selector;\n loupeFacetSelectors[6] = IStorageLoupe\n .facetFunctionSelectorsFromStorage\n .selector;\n loupeFacetSelectors[7] = IStorageLoupe\n .facetAddressesFromStorage\n .selector;\n loupeFacetSelectors[8] = IStorageLoupe.facetAddressFromStorage.selector;\n\n {\n cut[0] = IDiamondCut.FacetCut({\n facetAddress: _diamondCutFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: functionSelectors\n });\n cut[1] = IDiamondCut.FacetCut({\n facetAddress: _accountFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: accountFunctionSelectors\n });\n cut[2] = IDiamondCut.FacetCut({\n facetAddress: _tokenReceiverFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: receiverFacetSelectors\n });\n cut[3] = IDiamondCut.FacetCut({\n facetAddress: _diamondLoupeFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: loupeFacetSelectors\n });\n\n DefaultLibDiamond.diamondCut(cut, address(0), \"\");\n }\n }\n\n /**\n * @notice Returns the facet information of call facets registered to this diamond.\n * @return facets_ The facet struct array including all facet information\n */\n function facets() external view override returns (Facet[] memory facets_) {\n DefaultLibDiamond.DiamondStorage storage ds = DefaultLibDiamond\n .diamondStorage();\n uint256 numFacets = ds.facetAddresses.length;\n facets_ = new Facet[](numFacets);\n for (uint256 i; i < numFacets; ) {\n address facetAddress_ = ds.facetAddresses[i];\n facets_[i].facetAddress = facetAddress_;\n facets_[i].functionSelectors = ds\n .facetFunctionSelectors[facetAddress_]\n .functionSelectors;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Gets all the function selectors provided by a facet.\n * @param _facet The facet address.\n * @return facetFunctionSelectors_\n */\n function facetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n facetFunctionSelectors_ = DefaultLibDiamond\n .diamondStorage()\n .facetFunctionSelectors[_facet]\n .functionSelectors;\n }\n\n /**\n * @notice Get all the facet addresses used by a diamond.\n * @return facetAddresses_\n */\n function facetAddresses()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n facetAddresses_ = DefaultLibDiamond.diamondStorage().facetAddresses;\n }\n\n /** @notice Gets the facet that supports the given selector.\n * @dev If facet is not found return address(0).\n * @param _functionSelector The function selector.\n * @return facetAddress_ The facet address.\n */\n function facetAddress(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n facetAddress_ = DefaultLibDiamond\n .diamondStorage()\n .selectorToFacetAndPosition[_functionSelector]\n .facetAddress;\n }\n}\n" + }, + "contracts/infrastructure/FacetRegistry.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport {IFacetRegistry} from \"./interfaces/IFacetRegistry.sol\";\n\n/**\n * @title Facet Registry\n * @dev Contract to keep track of facets & function selectors addable to user wallets\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract FacetRegistry is IFacetRegistry, Ownable2Step {\n mapping(address => FacetRegistryConfig) private facets;\n\n /**\n * @notice Transfers the ownership of the contract to the given owner\n * @param _owner Address of owner who has access to initialize the default security variables for security manager\n */\n constructor(address _owner) {\n transferOwnership(_owner);\n _transferOwnership(_owner);\n }\n\n /**\n * @dev Registers a facet and it's function selectors to registry\n * @param _facet address of facet\n * @param _facetSelectors list of function selectors of the facet\n */\n function registerFacetFunctionSelectors(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external override onlyOwner {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n for (uint256 i; i < _facetSelectors.length; ) {\n if (facetConfig.info[_facetSelectors[i]].exists)\n revert FacetRegistry__FacetSelectorAlreadyRegistered();\n\n facetConfig.info[_facetSelectors[i]].exists = true;\n facetConfig.info[_facetSelectors[i]].index = uint128(\n facetConfig.selectors.length\n );\n facetConfig.selectors.push(_facetSelectors[i]);\n unchecked {\n ++i;\n }\n }\n emit FacetFunctionSelectorsRegistered(_facet, _facetSelectors);\n }\n\n /**\n * @dev Removes a registered facet and it's corresponding selectors from registry\n * @param _facet address of facet\n * @param _facetSelectors list of function selectors of the facet\n */\n function removeFacetFunctionSelectors(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external override onlyOwner {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n for (uint256 i; i < _facetSelectors.length; ) {\n if (!facetConfig.info[_facetSelectors[i]].exists)\n revert FacetRegistry__UnregisteredFacetSelector();\n\n bytes4 lastSelector = facetConfig.selectors[\n facetConfig.selectors.length - 1\n ];\n if (_facetSelectors[i] != lastSelector) {\n uint128 targetIndex = facetConfig\n .info[_facetSelectors[i]]\n .index;\n facetConfig.selectors[targetIndex] = lastSelector;\n facetConfig.info[lastSelector].index = targetIndex;\n }\n facetConfig.selectors.pop();\n delete facetConfig.info[_facetSelectors[i]];\n\n unchecked {\n ++i;\n }\n }\n emit FacetFunctionSelectorsRemoved(_facet, _facetSelectors);\n }\n\n /**\n * @dev Checks if a facet and it's selectors given is registered to facet registry\n * @param _facet Address of facet\n * @param _facetSelectors List of function selectors of the facet\n */\n function areFacetFunctionSelectorsRegistered(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external view override returns (bool) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n if (_facetSelectors.length == 0) return false;\n for (uint256 i; i < _facetSelectors.length; ) {\n if (!facetConfig.info[_facetSelectors[i]].exists) return false;\n unchecked {\n ++i;\n }\n }\n return true;\n }\n\n /**\n * @dev Checks if a facet and it's selector given is registered to facet registry\n * @param _facet Address of facet\n * @param _facetSelector List of function selectors of the facet\n * @return isRegistered Bool value showing if the selector is registered\n */\n function isFacetFunctionSelectorRegistered(\n address _facet,\n bytes4 _facetSelector\n ) external view override returns (bool isRegistered) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n isRegistered = facetConfig.info[_facetSelector].exists;\n }\n\n /**\n * @dev Get the registered selectors of facet from registry\n * @param _facet Address of facet\n * @return selectors Selectors registered to facet\n */\n function getFacetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory selectors) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n selectors = facetConfig.selectors;\n }\n}\n" + }, + "contracts/infrastructure/interfaces/IFacetRegistry.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Registry Interface\n * @dev Interface for Facet Registry contract to keep track of facets & function selectors addable to user wallets\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IFacetRegistry {\n struct FacetRegistryConfig {\n bytes4[] selectors;\n mapping(bytes4 => FacetInfo) info;\n }\n struct FacetInfo {\n bool exists;\n uint128 index;\n }\n\n event FacetFunctionSelectorsRegistered(\n address facet,\n bytes4[] facetSelectors\n );\n event FacetFunctionSelectorsRemoved(address facet, bytes4[] facetSelectors);\n\n error FacetRegistry__FacetSelectorAlreadyRegistered();\n error FacetRegistry__UnregisteredFacetSelector();\n\n function registerFacetFunctionSelectors(\n address facet,\n bytes4[] calldata facetSelectors\n ) external;\n\n function removeFacetFunctionSelectors(\n address facet,\n bytes4[] calldata facetSelectors\n ) external;\n\n function areFacetFunctionSelectorsRegistered(\n address facet,\n bytes4[] calldata facetSelectors\n ) external view returns (bool);\n\n function isFacetFunctionSelectorRegistered(\n address facet,\n bytes4 facetSelector\n ) external view returns (bool);\n\n function getFacetFunctionSelectors(\n address facet\n ) external view returns (bytes4[] memory);\n}\n" + }, + "contracts/infrastructure/interfaces/ISecurityManager.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Registry Interface\n * @dev Infrastructure contract to manage security parameters of users\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface ISecurityManager {\n error SecurityManager__OutOfBoundary();\n error SecurityManager__CallerNotWallet();\n error SecurityManager__AlreadyIntialized();\n\n function initializeAdditionSecurityPeriod(\n uint128 defaultAdditionSecurityPeriod,\n uint128 minAdditionSecurityPeriod,\n uint128 maxAdditionSecurityPeriod\n ) external;\n\n function initializeRemovalSecurityPeriod(\n uint128 defaultRemovalSecurityPeriod,\n uint128 minRemovalSecurityPeriod,\n uint128 maxRemovalSecurityPeriod\n ) external;\n\n function initializeApprovalValidationPeriod(\n uint128 defaultApprovalValidationPeriod,\n uint128 minApprovalValidationPeriod,\n uint128 maxApprovalValidationPeriod\n ) external;\n\n function initializeMigrationPeriod(\n uint128 defaultMigrationPeriod,\n uint128 minMigrationPeriod,\n uint128 maxMigrationPeriod\n ) external;\n\n function initializeLockPeriod(\n uint128 defaultLockPeriod,\n uint128 minLockPeriod,\n uint128 maxLockPeriod\n ) external;\n\n function initializeRecoveryPeriod(\n uint128 defaultRecoveryPeriod,\n uint128 minRecoveryPeriod,\n uint128 maxRecoveryPeriod\n ) external;\n\n function initializeSecurityWindow(\n uint128 defaultSecurityWindow,\n uint128 minSecurityWindow,\n uint128 maxSecurityWindow\n ) external;\n\n function setAdditionSecurityPeriod(\n address wallet,\n uint128 additionSecurityPeriod\n ) external;\n\n function setRemovalSecurityPeriod(\n address wallet,\n uint128 removalSecurityPeriod\n ) external;\n\n function setSecurityWindow(address wallet, uint128 securityWindow) external;\n\n function setRecoveryPeriod(address wallet, uint128 recoveryPeriod) external;\n\n function setLockPeriod(address wallet, uint128 lockPeriod) external;\n\n function setApprovalValidationPeriod(\n address wallet,\n uint128 approvalValidationPeriod\n ) external;\n\n function setMigrationPeriod(\n address wallet,\n uint128 migrationPeriod\n ) external;\n\n function additionSecurityPeriodOf(\n address wallet\n ) external view returns (uint128);\n\n function removalSecurityPeriodOf(\n address wallet\n ) external view returns (uint128);\n\n function securityWindowOf(address wallet) external view returns (uint128);\n\n function recoveryPeriodOf(address wallet) external view returns (uint128);\n\n function lockPeriodOf(address wallet) external view returns (uint128);\n\n function migrationPeriodOf(address wallet) external view returns (uint128);\n\n function approvalValidationPeriodOf(\n address wallet\n ) external view returns (uint128);\n}\n" + }, + "contracts/infrastructure/RemoteStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IGuardianFacet} from \"../facets/interfaces/IGuardianFacet.sol\";\n\n/**\n * @title Remote Storage\n * @dev Remote storage allows you to associate addresses with an array of addresses on a standalone smart contract.\n * This could be useful when you don't want to use the local diamond storage for some purpose.\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\nabstract contract RemoteStorage {\n struct StorageConfig {\n address[] addresses;\n mapping(address => Info) info;\n }\n\n struct Info {\n bool exists;\n uint128 index;\n }\n\n mapping(address => StorageConfig) internal configs;\n\n event Added(address _address);\n event Removed(address _address);\n\n error RemoteStorage__CallerNotOwner();\n error RemoteStorage__CallerNotGuardianOrOwner();\n error RemoteStorage__AlreadyExists();\n error RemoteStorage__NotFound();\n error RemoteStorage__CallerNotGuardian();\n\n bytes4 constant IS_GUARDIAN_SELECTOR =\n bytes4(keccak256(\"isGuardian(address)\"));\n bytes4 constant GUARDIAN_COUNT = bytes4(keccak256(\"guardianCount()\"));\n\n /**\n * @notice Modifier to only allow the self to call. Reverts otherwise\n */\n modifier onlyWallet(address _wallet) {\n if (msg.sender != _wallet) revert RemoteStorage__CallerNotOwner();\n _;\n }\n\n /**\n * @notice Enfore the callet to be wallet of guardian of the wallet\n * @param _wallet Address of wallet\n */\n function enforceGuardianOrWallet(address _wallet) internal view {\n if (msg.sender == _wallet) return;\n address facetAddress = IDiamondLoupe(_wallet).facetAddress(\n IS_GUARDIAN_SELECTOR\n );\n if (facetAddress != address(0))\n if (IGuardianFacet(_wallet).isGuardian(msg.sender)) return;\n revert RemoteStorage__CallerNotGuardianOrOwner();\n }\n\n /**\n * @notice Enforce the caller to be wallet IF guardians doesn't exists and only guardian when guardians exists\n * @param _wallet Target wallet address to be handled by infrastructure contracts\n */\n function enforceWalletOrGuardianIfExists(address _wallet) internal view {\n address facetAddress;\n if (msg.sender == _wallet) {\n facetAddress = IDiamondLoupe(_wallet).facetAddress(GUARDIAN_COUNT);\n if (facetAddress == address(0)) return;\n uint256 guardianCount = IGuardianFacet(_wallet).guardianCount();\n if (guardianCount != 0) revert RemoteStorage__CallerNotGuardian();\n return;\n }\n facetAddress = IDiamondLoupe(_wallet).facetAddress(\n IS_GUARDIAN_SELECTOR\n );\n if (facetAddress != address(0))\n if (IGuardianFacet(_wallet).isGuardian(msg.sender)) return;\n\n revert RemoteStorage__CallerNotGuardianOrOwner();\n }\n\n /**\n * @notice Add address to storage and reverts if the address already exists.\n * This is an internal function callable from contracts that inherit this abstract contract\n * @param _wallet Address of wallet to add the address\n * @param _address Address to be added to wallet\n */\n function addAddress(address _wallet, address _address) internal {\n StorageConfig storage config = configs[_wallet];\n if (config.info[_address].exists) revert RemoteStorage__AlreadyExists();\n\n config.info[_address].exists = true;\n config.info[_address].index = uint128(config.addresses.length);\n config.addresses.push(_address);\n\n emit Added(_address);\n }\n\n /**\n * @notice Remove address from storage and reverts if the address already exists.\n * This is an internal function callable from contracts that inherit this abstract contract\n * @param _wallet Address of wallet to remove the address\n * @param _address Address to be removed from wallet\n */\n function removeAddress(address _wallet, address _address) internal {\n StorageConfig storage config = configs[_wallet];\n if (!config.info[_address].exists) revert RemoteStorage__NotFound();\n\n address lastAddress = config.addresses[config.addresses.length - 1];\n if (_address != lastAddress) {\n uint128 targetIndex = config.info[_address].index;\n config.addresses[targetIndex] = lastAddress;\n config.info[lastAddress].index = targetIndex;\n }\n config.addresses.pop();\n delete config.info[_address];\n\n emit Removed(_address);\n }\n\n /**\n * @notice Returns the address added to the given wallet\n * @param _wallet Address of wallet to fetch the addresses added to it\n * @return addresses List of addresses added to the wallet\n */\n function getAddresses(\n address _wallet\n ) internal view returns (address[] memory addresses) {\n StorageConfig storage config = configs[_wallet];\n addresses = new address[](config.addresses.length);\n uint addressesLen = config.addresses.length;\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns bool value checking if the address exists in the given wallet address\n * @param _wallet Wallet address to check\n * @param _address Address to fetch if the address if added to given wallet\n * @return exists_ Bool value showing if the address exists in wallet\n */\n function exists(\n address _wallet,\n address _address\n ) internal view returns (bool exists_) {\n exists_ = configs[_wallet].info[_address].exists;\n }\n\n /**\n * @notice Returns the number of addresses added to the wallet\n * @param _wallet Address of wallet to check\n * @return count_ Number of addresses added to wallet\n */\n function count(address _wallet) internal view returns (uint256 count_) {\n count_ = configs[_wallet].addresses.length;\n }\n}\n" + }, + "contracts/infrastructure/SecurityManager.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport {ISecurityManager} from \"./interfaces/ISecurityManager.sol\";\n\n/**\n * @title Security Manager\n * @dev Infrastructure contract to manage security parameters of users\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract SecurityManager is ISecurityManager, Ownable2Step {\n uint128 public minAdditionSecurityPeriod;\n uint128 public maxAdditionSecurityPeriod;\n uint128 private defaultAdditionSecurityPeriod;\n\n uint128 public minRemovalSecurityPeriod;\n uint128 public maxRemovalSecurityPeriod;\n uint128 private defaultRemovalSecurityPeriod;\n\n uint128 public minSecurityWindow;\n uint128 public maxSecurityWindow;\n uint128 private defaultSecurityWindow;\n\n uint128 public minRecoveryPeriod;\n uint128 public maxRecoveryPeriod;\n uint128 private defaultRecoveryPeriod;\n\n uint128 public minLockPeriod;\n uint128 public maxLockPeriod;\n uint128 private defaultLockPeriod;\n\n uint128 public minApprovalValidationPeriod;\n uint128 public maxApprovalValidationPeriod;\n uint128 private defaultApprovalValidationPeriod;\n\n uint128 public minMigrationPeriod;\n uint128 public maxMigrationPeriod;\n uint128 private defaultMigrationPeriod;\n\n bool public _isAdditionSecurityPeriodInitialized;\n bool public _isRemovalSecurityPeriodInitialized;\n bool public _isSecurityWindowInitialized;\n bool public _isRecoveryPeriodInitialized;\n bool public _isLockPeriodInitialized;\n bool public _isApprovalValidationPeriodInitialized;\n bool public _isMigrationPeriodInitialized;\n\n mapping(address => CustomSecurityConfig) securityConfigs;\n\n struct CustomSecurityConfig {\n uint128 additionSecurityPeriod;\n uint128 removalSecurityPeriod;\n uint128 securityWindow;\n uint128 recoveryPeriod;\n uint128 lockPeriod;\n uint128 approvalValidationPeriod;\n uint128 migrationPeriod;\n }\n\n /**\n * @notice Modifier to only allow wallet itself to make a call to wallet\n */\n modifier onlyWallet(address _wallet) {\n if (msg.sender != _wallet) revert SecurityManager__CallerNotWallet();\n _;\n }\n\n /**\n * @notice Modifier to revert if the variable is already initialized\n */\n modifier initializer(bool _isInitialized) {\n if (_isInitialized) revert SecurityManager__AlreadyIntialized();\n _;\n }\n\n /**\n * @notice Transfers the ownership of the contract to the given owner\n * @param _owner Address of owner who has access to initialize the default security variables for security manager\n */\n constructor(address _owner) {\n transferOwnership(_owner);\n _transferOwnership(_owner);\n }\n\n /**\n * @notice Sets the initial default/min/max addition security period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultAdditionSecurityPeriod Default Addition Security Period for all Barz contracts\n * @param _minAdditionSecurityPeriod Minimum Addition Security Period for all Barz contracts\n * @param _maxAdditionSecurityPeriod Maximum Addition Security Period for all Barz contracts\n */\n function initializeAdditionSecurityPeriod(\n uint128 _defaultAdditionSecurityPeriod,\n uint128 _minAdditionSecurityPeriod,\n uint128 _maxAdditionSecurityPeriod\n )\n external\n override\n onlyOwner\n initializer(_isAdditionSecurityPeriodInitialized)\n {\n _isAdditionSecurityPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultAdditionSecurityPeriod,\n _minAdditionSecurityPeriod,\n _maxAdditionSecurityPeriod\n );\n defaultAdditionSecurityPeriod = _defaultAdditionSecurityPeriod;\n minAdditionSecurityPeriod = _minAdditionSecurityPeriod;\n maxAdditionSecurityPeriod = _maxAdditionSecurityPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max removal security period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultRemovalSecurityPeriod Default Removal Security Period for all Barz contracts\n * @param _minRemovalSecurityPeriod Minimum Removal Security Period for all Barz contracts\n * @param _maxRemovalSecurityPeriod Maximum Removal Security Period for all Barz contracts\n */\n function initializeRemovalSecurityPeriod(\n uint128 _defaultRemovalSecurityPeriod,\n uint128 _minRemovalSecurityPeriod,\n uint128 _maxRemovalSecurityPeriod\n )\n external\n override\n onlyOwner\n initializer(_isRemovalSecurityPeriodInitialized)\n {\n _isRemovalSecurityPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultRemovalSecurityPeriod,\n _minRemovalSecurityPeriod,\n _maxRemovalSecurityPeriod\n );\n defaultRemovalSecurityPeriod = _defaultRemovalSecurityPeriod;\n minRemovalSecurityPeriod = _minRemovalSecurityPeriod;\n maxRemovalSecurityPeriod = _maxRemovalSecurityPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/maxd security window for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultSecurityWindow Default Security Window for all Barz contracts\n * @param _minSecurityWindow Minimum Security Window for all Barz contracts\n * @param _maxSecurityWindow Maximum Security Window for all Barz contracts\n */\n function initializeSecurityWindow(\n uint128 _defaultSecurityWindow,\n uint128 _minSecurityWindow,\n uint128 _maxSecurityWindow\n ) external override onlyOwner initializer(_isSecurityWindowInitialized) {\n _isSecurityWindowInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultSecurityWindow,\n _minSecurityWindow,\n _maxSecurityWindow\n );\n defaultSecurityWindow = _defaultSecurityWindow;\n minSecurityWindow = _minSecurityWindow;\n maxSecurityWindow = _maxSecurityWindow;\n }\n\n /**\n * @notice Sets the initial default/min/max recovery period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultRecoveryPeriod Default Recovery Period for all Barz contracts\n * @param _minRecoveryPeriod Minimum Recovery Period for all Barz contracts\n * @param _maxRecoveryPeriod Maximum Recovery Period for all Barz contracts\n */\n function initializeRecoveryPeriod(\n uint128 _defaultRecoveryPeriod,\n uint128 _minRecoveryPeriod,\n uint128 _maxRecoveryPeriod\n ) external override onlyOwner initializer(_isRecoveryPeriodInitialized) {\n _isRecoveryPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultRecoveryPeriod,\n _minRecoveryPeriod,\n _maxRecoveryPeriod\n );\n defaultRecoveryPeriod = _defaultRecoveryPeriod;\n minRecoveryPeriod = _minRecoveryPeriod;\n maxRecoveryPeriod = _maxRecoveryPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max lock period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultLockPeriod Default Lock Period for all Barz contracts\n * @param _minLockPeriod Minimum Lock Period for all Barz contracts\n * @param _maxLockPeriod Maximum Lock Period for all Barz contracts\n */\n function initializeLockPeriod(\n uint128 _defaultLockPeriod,\n uint128 _minLockPeriod,\n uint128 _maxLockPeriod\n ) external override onlyOwner initializer(_isLockPeriodInitialized) {\n _isLockPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultLockPeriod,\n _minLockPeriod,\n _maxLockPeriod\n );\n defaultLockPeriod = _defaultLockPeriod;\n minLockPeriod = _minLockPeriod;\n maxLockPeriod = _maxLockPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max approval validation period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultApprovalValidationPeriod Default Approval Validation Period for all Barz contracts\n * @param _minApprovalValidationPeriod Minimum Approval Validation Period for all Barz contracts\n * @param _maxApprovalValidationPeriod Maximum Approval Validation Period for all Barz contracts\n */\n function initializeApprovalValidationPeriod(\n uint128 _defaultApprovalValidationPeriod,\n uint128 _minApprovalValidationPeriod,\n uint128 _maxApprovalValidationPeriod\n )\n external\n override\n onlyOwner\n initializer(_isApprovalValidationPeriodInitialized)\n {\n _isApprovalValidationPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultApprovalValidationPeriod,\n _minApprovalValidationPeriod,\n _maxApprovalValidationPeriod\n );\n defaultApprovalValidationPeriod = _defaultApprovalValidationPeriod;\n minApprovalValidationPeriod = _minApprovalValidationPeriod;\n maxApprovalValidationPeriod = _maxApprovalValidationPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max migration period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultMigrationPeriod Default Migration Period for all Barz contracts\n * @param _minMigrationPeriod Minimum Migration Period for all Barz contracts\n * @param _maxMigrationPeriod Maximum Migration Period for all Barz contracts\n */\n function initializeMigrationPeriod(\n uint128 _defaultMigrationPeriod,\n uint128 _minMigrationPeriod,\n uint128 _maxMigrationPeriod\n ) external override onlyOwner initializer(_isMigrationPeriodInitialized) {\n _isMigrationPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultMigrationPeriod,\n _minMigrationPeriod,\n _maxMigrationPeriod\n );\n defaultMigrationPeriod = _defaultMigrationPeriod;\n minMigrationPeriod = _minMigrationPeriod;\n maxMigrationPeriod = _maxMigrationPeriod;\n }\n\n /**\n * @notice Wallet owner sets the addition security period for the wallet. Only the owner of wallet can call this function.\n * The addition security period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _additionSecurityPeriod Custom Addition Security Period for the wallet\n */\n function setAdditionSecurityPeriod(\n address _wallet,\n uint128 _additionSecurityPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _additionSecurityPeriod,\n minAdditionSecurityPeriod,\n maxAdditionSecurityPeriod\n );\n securityConfigs[_wallet]\n .additionSecurityPeriod = _additionSecurityPeriod;\n }\n\n /**\n * @notice Wallet owner sets the removal security period for the wallet. Only the owner of wallet can call this function.\n * The removal security period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _removalSecurityPeriod Custom Removal Security Period for the wallet\n */\n function setRemovalSecurityPeriod(\n address _wallet,\n uint128 _removalSecurityPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _removalSecurityPeriod,\n minRemovalSecurityPeriod,\n maxRemovalSecurityPeriod\n );\n securityConfigs[_wallet].removalSecurityPeriod = _removalSecurityPeriod;\n }\n\n /**\n * @notice Wallet owner sets the security window for the wallet. Only the owner of wallet can call this function.\n * The security window should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _securityWindow Custom Security Window for the wallet\n */\n function setSecurityWindow(\n address _wallet,\n uint128 _securityWindow\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _securityWindow,\n minSecurityWindow,\n maxSecurityWindow\n );\n securityConfigs[_wallet].securityWindow = _securityWindow;\n }\n\n /**\n * @notice Wallet owner sets the recovery period for the wallet. Only the owner of wallet can call this function.\n * The recovery period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _recoveryPeriod Custom recovery period for the wallet\n */\n function setRecoveryPeriod(\n address _wallet,\n uint128 _recoveryPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _recoveryPeriod,\n minRecoveryPeriod,\n maxRecoveryPeriod\n );\n securityConfigs[_wallet].recoveryPeriod = _recoveryPeriod;\n }\n\n /**\n * @notice Wallet owner sets the lock period for the wallet. Only the owner of wallet can call this function.\n * The lock period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _lockPeriod Custom Lock period for the wallet\n */\n function setLockPeriod(\n address _wallet,\n uint128 _lockPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(_lockPeriod, minLockPeriod, maxLockPeriod);\n securityConfigs[_wallet].lockPeriod = _lockPeriod;\n }\n\n /**\n * @notice Wallet owner sets the approval validation period for the wallet. Only the owner of wallet can call this function.\n * The approval validation period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _approvalValidationPeriod Custom approval validation period for the wallet\n */\n function setApprovalValidationPeriod(\n address _wallet,\n uint128 _approvalValidationPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _approvalValidationPeriod,\n minApprovalValidationPeriod,\n maxApprovalValidationPeriod\n );\n securityConfigs[_wallet]\n .approvalValidationPeriod = _approvalValidationPeriod;\n }\n\n /**\n * @notice Wallet owner sets the migration period for the wallet. Only the owner of wallet can call this function.\n * The migration period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _migrationPeriod Custom migration period for the wallet\n */\n\n function setMigrationPeriod(\n address _wallet,\n uint128 _migrationPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _migrationPeriod,\n minMigrationPeriod,\n maxMigrationPeriod\n );\n securityConfigs[_wallet].migrationPeriod = _migrationPeriod;\n }\n\n /**\n * @notice Returns the addition security period. Returns default value when custom addition security period is not set\n * @param _wallet Address of wallet\n * @return additionSecurityPeriod Addition Security Period of the given Barz account or wallet\n */\n function additionSecurityPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 additionSecurityPeriod)\n {\n additionSecurityPeriod = securityConfigs[_wallet]\n .additionSecurityPeriod;\n additionSecurityPeriod = (additionSecurityPeriod == 0)\n ? defaultAdditionSecurityPeriod\n : additionSecurityPeriod;\n }\n\n /**\n * @notice Returns the removal security period. Returns default value when custom removal security period is not set\n * @param _wallet Address of wallet\n * @return removalSecurityPeriod Removal Security Period of the given Barz account or wallet\n */\n function removalSecurityPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 removalSecurityPeriod)\n {\n removalSecurityPeriod = securityConfigs[_wallet].removalSecurityPeriod;\n removalSecurityPeriod = (removalSecurityPeriod == 0)\n ? defaultRemovalSecurityPeriod\n : removalSecurityPeriod;\n }\n\n /**\n * @notice Returns the security window. Returns default value when custom security window is not set\n * @param _wallet Address of wallet\n * @return securityWindow Security window of the given Barz account or wallet\n */\n function securityWindowOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 securityWindow)\n {\n securityWindow = securityConfigs[_wallet].securityWindow;\n securityWindow = (securityWindow == 0)\n ? defaultSecurityWindow\n : securityWindow;\n }\n\n /**\n * @notice Returns the recovery period. Returns default value when custom recovery period is not set\n * @param _wallet Address of wallet\n * @return recoveryPeriod Recovery Period of the given Barz account or wallet\n */\n function recoveryPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 recoveryPeriod)\n {\n recoveryPeriod = securityConfigs[_wallet].recoveryPeriod;\n recoveryPeriod = (recoveryPeriod == 0)\n ? defaultRecoveryPeriod\n : recoveryPeriod;\n }\n\n /**\n * @notice Returns the lock period. Returns default value when custom lock period is not set\n * @param _wallet Address of wallet\n * @return lockPeriod Lock Period of the given Barz account or wallet\n */\n function lockPeriodOf(\n address _wallet\n ) public view override onlyWallet(_wallet) returns (uint128 lockPeriod) {\n lockPeriod = securityConfigs[_wallet].lockPeriod;\n lockPeriod = (lockPeriod == 0) ? defaultLockPeriod : lockPeriod;\n }\n\n /**\n * @notice Returns the approval validation period. Returns default value when custom approval validation period is not set\n * @param _wallet Address of wallet\n * @return approvalValidationPeriod Approval Validation Period of the given Barz account or wallet\n */\n function approvalValidationPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityConfigs[_wallet]\n .approvalValidationPeriod;\n approvalValidationPeriod = (approvalValidationPeriod == 0)\n ? defaultApprovalValidationPeriod\n : approvalValidationPeriod;\n }\n\n /**\n * @notice Returns the migration period. Returns default value when custom migration period is not set\n * @param _wallet Address of wallet\n * @return migrationPeriod Migration Period of the given Barz account or wallet\n */\n function migrationPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 migrationPeriod)\n {\n migrationPeriod = securityConfigs[_wallet].migrationPeriod;\n migrationPeriod = (migrationPeriod == 0)\n ? defaultMigrationPeriod\n : migrationPeriod;\n }\n\n /**\n * @notice Validates if the period is smaller than the max period or bigger than the min period\n * @param _period Period to be checked\n * @param _minPeriod Minimum period\n * @param _maxPeriod Maximum period\n */\n function _validatePeriodBoundaries(\n uint128 _period,\n uint128 _minPeriod,\n uint128 _maxPeriod\n ) internal pure {\n if (_period >= _maxPeriod || _period <= _minPeriod)\n revert SecurityManager__OutOfBoundary();\n }\n}\n" + }, + "contracts/infrastructure/WhitelistStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {RemoteStorage} from \"./RemoteStorage.sol\";\n\n/**\n * @title Whitelist storage\n * @dev Maps addresses to the corresponsing array of whitelisted addresses for each of them.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract WhitelistStorage is RemoteStorage {\n /**\n * @dev Add the address to the whitelist storage\n * @param _wallet User wallet\n * @param _address Address to be whitelisted\n */\n function whitelistAddress(address _wallet, address _address) external {\n enforceWalletOrGuardianIfExists(_wallet);\n addAddress(_wallet, _address);\n }\n\n /**\n * @dev Removes the address from the whitelist storage\n * @param _wallet User wallet\n * @param _address Address to be removed from the whitelist\n */\n function blacklistAddress(address _wallet, address _address) external {\n enforceGuardianOrWallet(_wallet);\n removeAddress(_wallet, _address);\n }\n\n /**\n * @dev Returns whether the address exists in the whitelist storage, associated with the wallet\n * @param _wallet User wallet\n * @param _address Address to be whitelisted\n */\n function isWhitelisted(\n address _wallet,\n address _address\n ) external view returns (bool) {\n return exists(_wallet, _address);\n }\n\n /**\n * @dev Returns all whitelisted addresses associated with the wallet\n * @param _wallet User wallet\n */\n function getWhitelistedAddresses(\n address _wallet\n ) external view returns (address[] memory) {\n return getAddresses(_wallet);\n }\n}\n" + }, + "contracts/interfaces/ERC/IERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\n\npragma solidity 0.8.21;\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155Receiver {\n /**\n * @dev Handles the receipt of a single ERC1155 token type. This function is\n * called at the end of a `safeTransferFrom` after the balance has been updated.\n *\n * NOTE: To accept the transfer, this must return\n * `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n * (i.e. 0xf23a6e61, or its own function selector).\n *\n * @param operator The address which initiated the transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param id The ID of the token being transferred\n * @param value The amount of tokens being transferred\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n ) external returns (bytes4);\n\n /**\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\n * is called at the end of a `safeBatchTransferFrom` after the balances have\n * been updated.\n *\n * NOTE: To accept the transfer(s), this must return\n * `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n * (i.e. 0xbc197c81, or its own function selector).\n *\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "contracts/interfaces/ERC/IERC1271.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\ninterface IERC1271 {\n function isValidSignature(\n bytes32 hash,\n bytes memory signature\n ) external view returns (bytes4);\n}\n" + }, + "contracts/interfaces/ERC/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\ninterface IERC165 {\n /// @notice Query if a contract implements an interface\n /// @param interfaceId The interface identifier, as specified in ERC-165\n /// @dev Interface identification is specified in ERC-165. This function\n /// uses less than 30,000 gas.\n /// @return `true` if the contract implements `interfaceID` and\n /// `interfaceID` is not 0xffffffff, `false` otherwise\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/IERC173.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\n/// @title ERC-173 Contract Ownership Standard\n/// Note: the ERC-165 identifier for this interface is 0x7f5828d0\n/* is ERC165 */\ninterface IERC173 {\n /// @dev This emits when ownership of a contract changes.\n event OwnershipTransferred(\n address indexed previousOwner,\n address indexed newOwner\n );\n\n /// @notice Get the address of the owner\n /// @return owner_ The address of the owner.\n function owner() external view returns (address owner_);\n\n /// @notice Set the address of the new owner of the contract\n /// @dev Set _newOwner to address(0) to renounce any ownership.\n /// @param _newOwner The address of the new owner of the contract\n function transferOwnership(address _newOwner) external;\n}\n" + }, + "contracts/interfaces/ERC/IERC677Receiver.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\ninterface IERC677Receiver {\n function onTokenTransfer(\n address sender,\n uint value,\n bytes calldata data\n ) external pure returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155 is IERC165 {\n /**\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n */\n event TransferSingle(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256 id,\n uint256 value\n );\n\n /**\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n * transfers.\n */\n event TransferBatch(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\n\n /**\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n * `approved`.\n */\n event ApprovalForAll(\n address indexed account,\n address indexed operator,\n bool approved\n );\n\n /**\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n *\n * If an {URI} event was emitted for `id`, the standard\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n * returned by {IERC1155MetadataURI-uri}.\n */\n event URI(string value, uint256 indexed id);\n\n /**\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(\n address account,\n uint256 id\n ) external view returns (uint256);\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] calldata accounts,\n uint256[] calldata ids\n ) external view returns (uint256[] memory);\n\n /**\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n *\n * Emits an {ApprovalForAll} event.\n *\n * Requirements:\n *\n * - `operator` cannot be the caller.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n *\n * See {setApprovalForAll}.\n */\n function isApprovedForAll(\n address account,\n address operator\n ) external view returns (bool);\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes calldata data\n ) external;\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(\n address indexed owner,\n address indexed spender,\n uint256 value\n );\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` 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 amount) 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(\n address owner,\n address spender\n ) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the 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 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` 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(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(\n address spender,\n uint256 addedValue\n ) external returns (bool);\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(\n address spender,\n uint256 subtractedValue\n ) external returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(\n address indexed from,\n address indexed to,\n uint256 indexed tokenId\n );\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(\n address indexed owner,\n address indexed approved,\n uint256 indexed tokenId\n );\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(\n address indexed owner,\n address indexed operator,\n bool approved\n );\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(\n uint256 tokenId\n ) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(\n address owner,\n address operator\n ) external view returns (bool);\n}\n" + }, + "contracts/interfaces/IBarz.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Barz Interface\n * @dev Interface of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IBarz {\n error Barz__InitializationFailure();\n}\n" + }, + "contracts/interfaces/IBarzFactory.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Barz} from \"../Barz.sol\";\n\n/**\n * @title Barz Factory Interface\n * @dev Interface of contract to easily deploy Barz to a pre-computed address with a single call\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IBarzFactory {\n event BarzDeployed(address);\n\n function createAccount(\n address verificationFacet,\n bytes calldata owner,\n uint256 salt\n ) external returns (Barz);\n\n function getAddress(\n address verificationFacet,\n bytes calldata owner,\n uint256 salt\n ) external view returns (address);\n\n function getBytecode(\n address accountFacet,\n address verificationFacet,\n address entryPoint,\n address facetRegistry,\n address defaultFallback,\n bytes memory ownerPublicKey\n ) external pure returns (bytes memory);\n\n function getCreationCode() external pure returns (bytes memory);\n}\n" + }, + "contracts/libraries/DefaultLibDiamond.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\n\nerror InitializationFunctionReverted(\n address _initializationContractAddress,\n bytes _calldata\n);\n\nlibrary DefaultLibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION =\n keccak256(\"trustwallet.barz.diamond.storage\");\n\n struct FacetAddressAndPosition {\n address facetAddress;\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\n }\n\n struct FacetFunctionSelectors {\n bytes4[] functionSelectors;\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\n }\n\n struct DiamondStorage {\n // maps function selector to the facet address and\n // the position of the selector in the facetFunctionSelectors.selectors array\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\n // maps facet addresses to function selectors\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\n // facet addresses\n address[] facetAddresses;\n // Used to query if a contract implements an interface.\n // Used to implement ERC-165.\n mapping(bytes4 => bool) supportedInterfaces;\n }\n\n function diamondStorage()\n internal\n pure\n returns (DiamondStorage storage ds)\n {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n event DiamondCut(\n IDiamondCut.FacetCut[] _diamondCut,\n address _init,\n bytes _calldata\n );\n\n // Internal function version of diamondCut\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n for (\n uint256 facetIndex;\n facetIndex < _diamondCut.length;\n facetIndex++\n ) {\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\n if (action == IDiamondCut.FacetCutAction.Add) {\n addFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\n replaceFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\n removeFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else {\n revert(\"LibDiamondCut: Incorrect FacetCutAction\");\n }\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Add facet can't be address(0)\"\n );\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n require(\n oldFacetAddress == address(0),\n \"LibDiamondCut: Can't add function that already exists\"\n );\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function replaceFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Replace facet can't be address(0)\"\n );\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n require(\n oldFacetAddress != _facetAddress,\n \"LibDiamondCut: Can't replace function with same facet\"\n );\n removeFunction(ds, oldFacetAddress, selector);\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function removeFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n // if function does not exist then do nothing and return\n require(\n _facetAddress == address(0),\n \"LibDiamondCut: Remove facet address must be address(0)\"\n );\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n removeFunction(ds, oldFacetAddress, selector);\n }\n }\n\n function addFacet(\n DiamondStorage storage ds,\n address _facetAddress\n ) internal {\n enforceHasContractCode(\n _facetAddress,\n \"LibDiamondCut: New facet has no code\"\n );\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds\n .facetAddresses\n .length;\n ds.facetAddresses.push(_facetAddress);\n }\n\n function addFunction(\n DiamondStorage storage ds,\n bytes4 _selector,\n uint96 _selectorPosition,\n address _facetAddress\n ) internal {\n ds\n .selectorToFacetAndPosition[_selector]\n .functionSelectorPosition = _selectorPosition;\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(\n _selector\n );\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\n }\n\n function removeFunction(\n DiamondStorage storage ds,\n address _facetAddress,\n bytes4 _selector\n ) internal {\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Can't remove function that doesn't exist\"\n );\n // an immutable function is a function defined directly in a diamond\n require(\n _facetAddress != address(this),\n \"LibDiamondCut: Can't remove immutable function\"\n );\n // replace selector with last selector, then delete last selector\n uint256 selectorPosition = ds\n .selectorToFacetAndPosition[_selector]\n .functionSelectorPosition;\n uint256 lastSelectorPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors\n .length - 1;\n // if not the same then replace _selector with lastSelector\n if (selectorPosition != lastSelectorPosition) {\n bytes4 lastSelector = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors[lastSelectorPosition];\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[\n selectorPosition\n ] = lastSelector;\n ds\n .selectorToFacetAndPosition[lastSelector]\n .functionSelectorPosition = uint96(selectorPosition);\n }\n // delete the last selector\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\n delete ds.selectorToFacetAndPosition[_selector];\n\n // if no more selectors for facet address then delete the facet address\n if (lastSelectorPosition == 0) {\n // replace facet address with last facet address and delete last facet address\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\n uint256 facetAddressPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .facetAddressPosition;\n if (facetAddressPosition != lastFacetAddressPosition) {\n address lastFacetAddress = ds.facetAddresses[\n lastFacetAddressPosition\n ];\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\n ds\n .facetFunctionSelectors[lastFacetAddress]\n .facetAddressPosition = facetAddressPosition;\n }\n ds.facetAddresses.pop();\n delete ds\n .facetFunctionSelectors[_facetAddress]\n .facetAddressPosition;\n }\n }\n\n function initializeDiamondCut(\n address _init,\n bytes memory _calldata\n ) internal {\n if (_init == address(0)) {\n return;\n }\n enforceHasContractCode(\n _init,\n \"LibDiamondCut: _init address has no code\"\n );\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length > 0) {\n // bubble up error\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(error)\n revert(add(32, error), returndata_size)\n }\n } else {\n revert InitializationFunctionReverted(_init, _calldata);\n }\n }\n }\n\n function enforceHasContractCode(\n address _contract,\n string memory _errorMessage\n ) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize > 0, _errorMessage);\n }\n}\n" + }, + "contracts/libraries/LibAppStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SafeCast} from \"@openzeppelin/contracts/utils/math/SafeCast.sol\";\nimport {IEntryPoint} from \"../aa-4337/interfaces/IEntryPoint.sol\";\nimport {IFacetRegistry} from \"../infrastructure/interfaces/IFacetRegistry.sol\";\n\n/*\n * @title App Storage\n * @dev App storage for Barz contract to prevent storage collision\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\n\nstruct Lock {\n uint64 release;\n bytes4 locker;\n}\n\nstruct InitializersStorage {\n // NOTE: initialized is a variable to make sure the initialization is only done once.\n uint8 signerInitialized;\n uint8 accountInitialized;\n uint8 restrictionsInitialized;\n}\n\nstruct AppStorage {\n mapping(uint256 => InitializersStorage) initStorage;\n uint8 signerMigration;\n bytes4 validateOwnerSignatureSelector;\n IEntryPoint entryPoint;\n IFacetRegistry facetRegistry;\n mapping(uint256 => Lock) locks;\n}\n\nlibrary LibAppStorage {\n error LibAppStorage__AccountAlreadyUninitialized();\n error LibAppStorage__AccountMustBeUninitialized();\n error LibAppStorage__SignerAlreadyUninitialized();\n error LibAppStorage__SignerMustBeUninitialized();\n\n function appStorage() internal pure returns (AppStorage storage ds) {\n assembly {\n ds.slot := 0\n }\n }\n\n function setSignerUninitialized() internal {\n AppStorage storage s = appStorage();\n if (1 != s.initStorage[0].signerInitialized) {\n revert LibAppStorage__SignerAlreadyUninitialized();\n }\n s.initStorage[0].signerInitialized = 0;\n }\n\n function getValidateOwnerSignatureSelector()\n internal\n view\n returns (bytes4 selector)\n {\n selector = appStorage().validateOwnerSignatureSelector;\n }\n\n function setValidateOwnerSignatureSelector(\n bytes4 _validateOwnerSignatureSelector\n ) internal {\n appStorage()\n .validateOwnerSignatureSelector = _validateOwnerSignatureSelector;\n }\n\n function enforceSignerInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].signerInitialized) {\n revert LibAppStorage__SignerMustBeUninitialized();\n }\n s.initStorage[0].signerInitialized = 1;\n }\n\n function enforceAccountInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].accountInitialized) {\n revert LibAppStorage__AccountMustBeUninitialized();\n }\n s.initStorage[0].accountInitialized = 1;\n }\n\n function initiateSignerMigration() internal {\n appStorage().signerMigration = 1;\n }\n\n function enforceSignerMigration() internal view {\n if (1 != appStorage().signerMigration) {\n revert LibAppStorage__AccountMustBeUninitialized();\n }\n }\n\n function finalizeSignerMigration() internal {\n appStorage().signerMigration = 0;\n }\n\n function setLock(uint256 _releaseAfter, bytes4 _locker) internal {\n appStorage().locks[0] = Lock(SafeCast.toUint64(_releaseAfter), _locker);\n }\n\n function enforceRestrictionsInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].restrictionsInitialized)\n revert LibAppStorage__SignerMustBeUninitialized();\n s.initStorage[0].restrictionsInitialized = 1;\n }\n\n function setRestrictionsUninitialized() internal {\n AppStorage storage s = appStorage();\n if (1 != s.initStorage[0].restrictionsInitialized)\n revert LibAppStorage__AccountAlreadyUninitialized();\n s.initStorage[0].restrictionsInitialized = 0;\n }\n}\n\ncontract BarzStorage {\n AppStorage internal s;\n modifier onlyWhenUnlocked() {\n require(\n uint64(block.timestamp) >= s.locks[0].release,\n \"Account Locked\"\n );\n _;\n }\n modifier onlyWhenLocked() {\n require(\n uint64(block.timestamp) < s.locks[0].release,\n \"Account Unlocked\"\n );\n _;\n }\n}\n" + }, + "contracts/libraries/LibDiamond.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\n\nerror InitializationFunctionReverted(\n address _initializationContractAddress,\n bytes _calldata\n);\n\nlibrary LibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION =\n keccak256(\"trustwallet.barz.diamond.storage\");\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\n bytes4(keccak256(\"verifyRestrictions(address,address,uint256,bytes)\"));\n struct DiamondStorage {\n // maps function selectors to the facets that execute the functions.\n // and maps the selectors to their position in the selectorSlots array.\n // func selector => address facet, selector position\n mapping(bytes4 => bytes32) facets;\n // array of slots of function selectors.\n // each slot holds 8 function selectors.\n mapping(uint256 => bytes32) selectorSlots;\n // The number of function selectors in selectorSlots\n uint16 selectorCount;\n // Used to query if a contract implements an interface.\n // Used to implement ERC-165.\n mapping(bytes4 => bool) supportedInterfaces;\n // Default Fallback Handler of the barz.\n IDiamondLoupe defaultFallbackHandler;\n }\n\n function diamondStorage()\n internal\n pure\n returns (DiamondStorage storage ds)\n {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n function enforceIsSelf() internal view {\n require(msg.sender == address(this), \"LibDiamond: Caller not self\");\n }\n\n event DiamondCut(\n IDiamondCut.FacetCut[] _diamondCut,\n address _init,\n bytes _calldata\n );\n\n bytes32 constant CLEAR_ADDRESS_MASK =\n bytes32(uint256(0xffffffffffffffffffffffff));\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\n\n // Internal function version of diamondCut\n // This code is almost the same as the external diamondCut,\n // except it is using 'Facet[] memory _diamondCut' instead of\n // 'Facet[] calldata _diamondCut'.\n // The code is duplicated to prevent copying calldata to memory which\n // causes an error for a two dimensional array.\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n DiamondStorage storage ds = diamondStorage();\n uint256 originalSelectorCount = ds.selectorCount;\n uint256 selectorCount = originalSelectorCount;\n bytes32 selectorSlot;\n // Check if last selector slot is not full\n // \"selectorCount & 7\" is a gas efficient modulo by eight \"selectorCount % 8\"\n if (selectorCount & 7 > 0) {\n // get last selectorSlot\n // \"selectorSlot >> 3\" is a gas efficient division by 8 \"selectorSlot / 8\"\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\n }\n // loop through diamond cut\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\n selectorCount,\n selectorSlot,\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].action,\n _diamondCut[facetIndex].functionSelectors\n );\n\n unchecked {\n facetIndex++;\n }\n }\n if (selectorCount != originalSelectorCount) {\n ds.selectorCount = uint16(selectorCount);\n }\n // If last selector slot is not full\n // \"selectorCount & 7\" is a gas efficient modulo by eight \"selectorCount % 8\"\n if (selectorCount & 7 > 0) {\n // \"selectorSlot >> 3\" is a gas efficient division by 8 \"selectorSlot / 8\"\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addReplaceRemoveFacetSelectors(\n uint256 _selectorCount,\n bytes32 _selectorSlot,\n address _newFacetAddress,\n IDiamondCut.FacetCutAction _action,\n bytes4[] memory _selectors\n ) internal returns (uint256, bytes32) {\n DiamondStorage storage ds = diamondStorage();\n require(\n _selectors.length > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n if (_action == IDiamondCut.FacetCutAction.Add) {\n enforceHasContractCode(\n _newFacetAddress,\n \"LibDiamondCut: Add facet has no code\"\n );\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n require(\n address(bytes20(oldFacet)) == address(0),\n \"LibDiamondCut: Can't add function that already exists\"\n );\n // add facet for selector\n ds.facets[selector] =\n bytes20(_newFacetAddress) |\n bytes32(_selectorCount);\n // \"_selectorCount & 7\" is a gas efficient modulo by eight \"_selectorCount % 8\"\n // \" << 5 is the same as multiplying by 32 ( * 32)\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\n // clear selector position in slot and add selector\n _selectorSlot =\n (_selectorSlot &\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\n (bytes32(selector) >> selectorInSlotPosition);\n // if slot is full then write it to storage\n if (selectorInSlotPosition == 224) {\n // \"_selectorSlot >> 3\" is a gas efficient division by 8 \"_selectorSlot / 8\"\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\n _selectorSlot = 0;\n }\n _selectorCount++;\n\n unchecked {\n selectorIndex++;\n }\n }\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\n enforceHasContractCode(\n _newFacetAddress,\n \"LibDiamondCut: Replace facet has no code\"\n );\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n address oldFacetAddress = address(bytes20(oldFacet));\n // only useful if immutable functions exist\n require(\n oldFacetAddress != address(this),\n \"LibDiamondCut: Can't replace immutable function\"\n );\n require(\n oldFacetAddress != _newFacetAddress,\n \"LibDiamondCut: Can't replace function with same function\"\n );\n require(\n oldFacetAddress != address(0),\n \"LibDiamondCut: Can't replace function that doesn't exist\"\n );\n // replace old facet address\n ds.facets[selector] =\n (oldFacet & CLEAR_ADDRESS_MASK) |\n bytes20(_newFacetAddress);\n\n unchecked {\n selectorIndex++;\n }\n }\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\n require(\n _newFacetAddress == address(0),\n \"LibDiamondCut: Remove facet address must be address(0)\"\n );\n // \"_selectorCount >> 3\" is a gas efficient division by 8 \"_selectorCount / 8\"\n uint256 selectorSlotCount = _selectorCount >> 3;\n // \"_selectorCount & 7\" is a gas efficient modulo by eight \"_selectorCount % 8\"\n uint256 selectorInSlotIndex = _selectorCount & 7;\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n if (_selectorSlot == 0) {\n // get last selectorSlot\n selectorSlotCount--;\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\n selectorInSlotIndex = 7;\n } else {\n selectorInSlotIndex--;\n }\n bytes4 lastSelector;\n uint256 oldSelectorsSlotCount;\n uint256 oldSelectorInSlotPosition;\n // adding a block here prevents stack too deep error\n {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n require(\n address(bytes20(oldFacet)) != address(0),\n \"LibDiamondCut: Can't remove function that doesn't exist\"\n );\n // only useful if immutable functions exist\n require(\n address(bytes20(oldFacet)) != address(this),\n \"LibDiamondCut: Can't remove immutable function\"\n );\n // replace selector with last selector in ds.facets\n // gets the last selector\n // \" << 5 is the same as multiplying by 32 ( * 32)\n lastSelector = bytes4(\n _selectorSlot << (selectorInSlotIndex << 5)\n );\n if (lastSelector != selector) {\n // update last selector slot position info\n ds.facets[lastSelector] =\n (oldFacet & CLEAR_ADDRESS_MASK) |\n bytes20(ds.facets[lastSelector]);\n }\n delete ds.facets[selector];\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\n // \"oldSelectorCount >> 3\" is a gas efficient division by 8 \"oldSelectorCount / 8\"\n oldSelectorsSlotCount = oldSelectorCount >> 3;\n // \"oldSelectorCount & 7\" is a gas efficient modulo by eight \"oldSelectorCount % 8\"\n // \" << 5 is the same as multiplying by 32 ( * 32)\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\n }\n if (oldSelectorsSlotCount != selectorSlotCount) {\n bytes32 oldSelectorSlot = ds.selectorSlots[\n oldSelectorsSlotCount\n ];\n // clears the selector we are deleting and puts the last selector in its place.\n oldSelectorSlot =\n (oldSelectorSlot &\n ~(CLEAR_SELECTOR_MASK >>\n oldSelectorInSlotPosition)) |\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\n // update storage with the modified slot\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\n } else {\n // clears the selector we are deleting and puts the last selector in its place.\n _selectorSlot =\n (_selectorSlot &\n ~(CLEAR_SELECTOR_MASK >>\n oldSelectorInSlotPosition)) |\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\n }\n if (selectorInSlotIndex == 0) {\n delete ds.selectorSlots[selectorSlotCount];\n _selectorSlot = 0;\n }\n\n unchecked {\n selectorIndex++;\n }\n }\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\n } else {\n revert(\"LibDiamondCut: Incorrect FacetCutAction\");\n }\n return (_selectorCount, _selectorSlot);\n }\n\n function initializeDiamondCut(\n address _init,\n bytes memory _calldata\n ) internal {\n if (_init == address(0)) {\n return;\n }\n enforceHasContractCode(\n _init,\n \"LibDiamondCut: _init address has no code\"\n );\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length > 0) {\n // bubble up error\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(error)\n revert(add(32, error), returndata_size)\n }\n } else {\n revert InitializationFunctionReverted(_init, _calldata);\n }\n }\n }\n\n function enforceHasContractCode(\n address _contract,\n string memory _errorMessage\n ) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize > 0, _errorMessage);\n }\n\n function restrictionsFacet() internal view returns (address facetAddress_) {\n facetAddress_ = address(\n bytes20(\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\n )\n );\n }\n}\n" + }, + "contracts/libraries/LibFacetStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Storage\n * @dev Storage contract to store each facets variables with diamond storage\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\n\nstruct Secp256k1VerificationStorage {\n address signer;\n}\n\nstruct Secp256r1VerificationStorage {\n uint256[2] q;\n}\n\nstruct GuardianStorage {\n mapping(bytes32 => uint256) pending;\n mapping(uint8 => StorageConfig) configs;\n}\n\nstruct Info {\n bool exists;\n uint128 index;\n}\n\nstruct StorageConfig {\n address[] addresses;\n mapping(address => Info) info;\n}\n\nstruct RecoveryConfig {\n bytes recoveryPublicKey;\n uint64 executeAfter;\n}\n\nstruct ApprovalConfig {\n bool isApproved;\n uint64 validUntil;\n}\n\nstruct RecoveryApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isNewOwnerApproved;\n}\n\nstruct RecoveryStorage {\n mapping(uint8 => RecoveryConfig) recoveryConfigs;\n mapping(uint8 => RecoveryApprovalConfig) recoveryApprovalConfigs;\n uint128 nonce;\n}\n\nstruct RestrictionsStorage {\n address[] restrictions;\n mapping(address => bool) exists;\n}\n\nstruct SignatureMigrationConfig {\n bytes migrationPublicKey;\n address migrationVerificationFacet;\n bytes4[] migrationSelectors;\n uint64 migrateAfter;\n}\n\nstruct SignatureMigrationApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isMigrationApproved;\n}\n\nstruct SignatureMigrationStorage {\n mapping(uint8 => SignatureMigrationConfig) migrationConfigs;\n mapping(uint8 => SignatureMigrationApprovalConfig) migrationApprovalConfigs;\n uint128 nonce;\n}\n\nstruct DiamondCutApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isDiamondCutApproved;\n}\n\nstruct DiamondCutStorage {\n mapping(uint8 => DiamondCutApprovalConfig) diamondCutApprovalConfigs;\n uint128 nonce;\n}\n\nstruct LockStorage {\n uint128 nonce;\n}\n\nlibrary LibFacetStorage {\n bytes32 constant K1_STORAGE_POSITION =\n keccak256(\n \"v0.trustwallet.diamond.storage.Secp256k1VerificationStorage\"\n );\n bytes32 constant R1_STORAGE_POSITION =\n keccak256(\n \"v0.trustwallet.diamond.storage.Secp256r1VerificationStorage\"\n );\n bytes32 constant GUARDIAN_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.GuardianStorage\");\n bytes32 constant RECOVERY_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.RecoveryStorage\");\n bytes32 constant RESTRICTION_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.RestrictionsStorage\");\n bytes32 constant MIGRATION_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.SignatureMigrationStorage\");\n bytes32 constant DIAMONDCUT_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.DiamondCutStorage\");\n bytes32 constant LOCK_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.LockStorage\");\n\n function k1Storage()\n internal\n pure\n returns (Secp256k1VerificationStorage storage ds)\n {\n bytes32 storagePosition = K1_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function r1Storage()\n internal\n pure\n returns (Secp256r1VerificationStorage storage ds)\n {\n bytes32 storagePosition = R1_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function guardianStorage()\n internal\n pure\n returns (GuardianStorage storage ds)\n {\n bytes32 storagePosition = GUARDIAN_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function recoveryStorage()\n internal\n pure\n returns (RecoveryStorage storage ds)\n {\n bytes32 storagePosition = RECOVERY_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function restrictionsStorage()\n internal\n pure\n returns (RestrictionsStorage storage ds)\n {\n bytes32 storagePosition = RESTRICTION_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function migrationStorage()\n internal\n pure\n returns (SignatureMigrationStorage storage ds)\n {\n bytes32 storagePosition = MIGRATION_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function diamondCutStorage()\n internal\n pure\n returns (DiamondCutStorage storage ds)\n {\n bytes32 storagePosition = DIAMONDCUT_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function lockStorage() internal pure returns (LockStorage storage ds) {\n bytes32 storagePosition = LOCK_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n}\n" + }, + "contracts/libraries/LibGuardian.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibFacetStorage, StorageConfig} from \"./LibFacetStorage.sol\";\n\n/**\n * @title LibGuardian\n * @dev Internal Library to provide utility feature for Guardians stored in Guardian Facet Storage\n * @author David Yongjun Kim (@Powerstream3604)\n */\nlibrary LibGuardian {\n function majorityOfGuardians()\n internal\n view\n returns (uint256 guardianNumber)\n {\n uint256 guardianLength = guardianCount();\n guardianNumber = (guardianLength == 0) ? 0 : guardianLength / 2 + 1;\n }\n\n function isGuardian(address _guardian) internal view returns (bool) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n return config.info[_guardian].exists;\n }\n\n function guardianCount() internal view returns (uint256) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n return config.addresses.length;\n }\n\n function getGuardians() internal view returns (address[] memory) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n address[] memory addresses = new address[](config.addresses.length);\n uint256 addressesLen = config.addresses.length;\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n return addresses;\n }\n}\n" + }, + "contracts/libraries/LibLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {LibDiamond} from \"./LibDiamond.sol\";\n\n/**\n * @title LibLoupe\n * @dev Internal Library to provide utility feature for reading the state of diamond facets\n * Originally from Diamond's implementation of Mudgen(author of EIP-2535)\n */\nlibrary LibLoupe {\n /// @notice Gets all facets and their selectors.\n /// @return facets_ Facet\n function facets()\n internal\n view\n returns (IDiamondLoupe.Facet[] memory facets_)\n {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facets_ = new IDiamondLoupe.Facet[](ds.selectorCount);\n uint16[] memory numFacetSelectors = new uint16[](ds.selectorCount);\n uint256 numFacets;\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facetAddress_ = address(bytes20(ds.facets[selector]));\n bool continueLoop;\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n if (facets_[facetIndex].facetAddress == facetAddress_) {\n facets_[facetIndex].functionSelectors[\n numFacetSelectors[facetIndex]\n ] = selector;\n // probably will never have more than 256 functions from one facet contract\n require(numFacetSelectors[facetIndex] < 255);\n numFacetSelectors[facetIndex]++;\n continueLoop = true;\n break;\n }\n }\n if (continueLoop) {\n continue;\n }\n facets_[numFacets].facetAddress = facetAddress_;\n facets_[numFacets].functionSelectors = new bytes4[](\n ds.selectorCount\n );\n facets_[numFacets].functionSelectors[0] = selector;\n numFacetSelectors[numFacets] = 1;\n numFacets++;\n }\n }\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n uint256 numSelectors = numFacetSelectors[facetIndex];\n bytes4[] memory selectors = facets_[facetIndex].functionSelectors;\n // setting the number of selectors\n assembly {\n mstore(selectors, numSelectors)\n }\n }\n // setting the number of facets\n assembly {\n mstore(facets_, numFacets)\n }\n }\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n /// @return _facetFunctionSelectors The selectors associated with a facet address.\n function facetFunctionSelectors(\n address _facet\n ) internal view returns (bytes4[] memory _facetFunctionSelectors) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n uint256 numSelectors;\n _facetFunctionSelectors = new bytes4[](ds.selectorCount);\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facet = address(bytes20(ds.facets[selector]));\n if (_facet == facet) {\n _facetFunctionSelectors[numSelectors] = selector;\n numSelectors++;\n }\n }\n }\n // Set the number of selectors in the array\n assembly {\n mstore(_facetFunctionSelectors, numSelectors)\n }\n }\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses()\n internal\n view\n returns (address[] memory facetAddresses_)\n {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facetAddresses_ = new address[](ds.selectorCount);\n uint256 numFacets;\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facetAddress_ = address(bytes20(ds.facets[selector]));\n bool continueLoop;\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n if (facetAddress_ == facetAddresses_[facetIndex]) {\n continueLoop = true;\n break;\n }\n }\n if (continueLoop) {\n continue;\n }\n facetAddresses_[numFacets] = facetAddress_;\n numFacets++;\n }\n }\n // Set the number of facet addresses in the array\n assembly {\n mstore(facetAddresses_, numFacets)\n }\n }\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(\n bytes4 _functionSelector\n ) internal view returns (address facetAddress_) {\n facetAddress_ = address(\n bytes20(LibDiamond.diamondStorage().facets[_functionSelector])\n );\n }\n}\n" + }, + "contracts/libraries/LibMultiSigStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Multi-sig Storage\n * @dev Storage contract for storing Multi-sig Facet variables in diamond storage pattern\n * @author David Yongjun Kim (@Powerstream3604)\n */\n\nstruct MultiSigStorage {\n mapping(address => address) owners;\n mapping(uint256 => mapping(address => mapping(bytes32 => uint256))) approvedHashes;\n uint256 ownerCount;\n uint256 threshold;\n uint256 counter;\n}\n\nlibrary LibMultiSigStorage {\n function multisigStorage()\n internal\n pure\n returns (MultiSigStorage storage ds)\n {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.MultiSigStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n}\n" + }, + "contracts/libraries/LibRecoverSpender.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title RecoverSpender\n * @dev Library to determine the action and spender of calldata\n * @author Ruslan Serebriakov (@rsrbk)\n */\nlibrary LibRecoverSpender {\n // ERC20, ERC721 & ERC1155 transfers & approvals\n bytes4 private constant ERC20_TRANSFER =\n bytes4(keccak256(\"transfer(address,uint256)\"));\n bytes4 private constant ERC20_APPROVE =\n bytes4(keccak256(\"approve(address,uint256)\"));\n bytes4 private constant ERC20_INCREASE_ALLOWANCE =\n bytes4(keccak256(\"increaseAllowance(address,uint256)\"));\n bytes4 private constant ERC20_DECREASE_ALLOWANCE =\n bytes4(keccak256(\"decreaseAllowance(address,uint256)\"));\n bytes4 private constant ERC721_SET_APPROVAL_FOR_ALL =\n bytes4(keccak256(\"setApprovalForAll(address,bool)\"));\n bytes4 private constant ERC721_TRANSFER_FROM =\n bytes4(keccak256(\"transferFrom(address,address,uint256)\"));\n bytes4 private constant ERC721_SAFE_TRANSFER_FROM =\n bytes4(keccak256(\"safeTransferFrom(address,address,uint256)\"));\n bytes4 private constant ERC721_SAFE_TRANSFER_FROM_BYTES =\n bytes4(keccak256(\"safeTransferFrom(address,address,uint256,bytes)\"));\n bytes4 private constant ERC1155_SAFE_TRANSFER_FROM =\n bytes4(\n keccak256(\"safeTransferFrom(address,address,uint256,uint256,bytes)\")\n );\n bytes4 private constant ERC1155_SAFE_BATCH_TRANSFER_FROM =\n bytes4(\n keccak256(\n \"safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)\"\n )\n );\n\n /**\n * @notice Helper method to recover the spender from a contract call.\n * The method returns the contract unless the call is to a standard method of a ERC20/ERC721/ERC1155 token\n * in which case the spender is recovered from the data.\n * @param _to The target contract.\n * @param _data The data payload.\n */\n function _recover(\n address _to,\n bytes memory _data\n ) internal pure returns (address spender) {\n if (_data.length >= 68) {\n bytes4 methodId;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n methodId := mload(add(_data, 0x20))\n }\n if (\n methodId == ERC20_TRANSFER ||\n methodId == ERC20_APPROVE ||\n methodId == ERC20_INCREASE_ALLOWANCE ||\n methodId == ERC20_DECREASE_ALLOWANCE ||\n methodId == ERC721_SET_APPROVAL_FOR_ALL\n ) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n spender := mload(add(_data, 0x24))\n }\n return spender;\n }\n if (\n methodId == ERC721_TRANSFER_FROM ||\n methodId == ERC721_SAFE_TRANSFER_FROM ||\n methodId == ERC721_SAFE_TRANSFER_FROM_BYTES ||\n methodId == ERC1155_SAFE_TRANSFER_FROM ||\n methodId == ERC1155_SAFE_BATCH_TRANSFER_FROM\n ) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n spender := mload(add(_data, 0x44))\n }\n return spender;\n }\n }\n\n spender = _to;\n }\n}\n" + }, + "contracts/libraries/LibReentrancyGuardStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nstruct ReentrancyGuardStorage {\n uint256 status;\n}\n\nlibrary LibReentrancyGuardStorage {\n bytes32 private constant REENTRANCY_GUARD_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.ReentrancyGuardStorage\");\n\n function reentrancyguardStorage()\n internal\n pure\n returns (ReentrancyGuardStorage storage ds)\n {\n bytes32 storagePosition = REENTRANCY_GUARD_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n}" + }, + "contracts/libraries/LibUtils.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\n\nlibrary LibUtils {\n // Internal utility functions\n function mergeArrays(\n bytes4[] memory _array1,\n bytes4[] memory _array2\n ) internal pure returns (bytes4[] memory) {\n uint256 length1 = _array1.length;\n uint256 length2 = _array2.length;\n bytes4[] memory mergedArray = new bytes4[](length1 + length2);\n\n for (uint256 i; i < length1; ) {\n mergedArray[i] = _array1[i];\n unchecked {\n ++i;\n }\n }\n\n for (uint256 i; i < length2; ) {\n mergedArray[length1 + i] = _array2[i];\n unchecked {\n ++i;\n }\n }\n\n return mergedArray;\n }\n\n function removeFacetElement(\n IDiamondLoupe.Facet[] memory _facets,\n uint256 _index\n ) internal pure returns (IDiamondLoupe.Facet[] memory) {\n require(_index < _facets.length, \"Invalid index\");\n require(_facets.length != 0, \"Invalid array\");\n\n // Create a new array with a length of `_facets.length - 1`\n IDiamondLoupe.Facet[] memory newArray = new IDiamondLoupe.Facet[](\n _facets.length - 1\n );\n uint256 newArrayLength = newArray.length;\n // Iterate over the original array, skipping the element at the specified `index`\n for (uint256 i; i < newArrayLength; ) {\n if (i < _index) {\n newArray[i] = _facets[i];\n } else {\n newArray[i] = _facets[i + 1];\n }\n unchecked {\n ++i;\n }\n }\n\n return newArray;\n }\n\n function removeElement(\n bytes4[] memory _array,\n uint256 _index\n ) internal pure returns (bytes4[] memory) {\n require(_index < _array.length, \"Invalid index\");\n require(_array.length != 0, \"Invalid array\");\n\n bytes4[] memory newArray = new bytes4[](_array.length - 1);\n uint256 newArrayLength = newArray.length;\n for (uint256 i; i < newArrayLength; ) {\n if (i < _index) {\n newArray[i] = _array[i];\n } else {\n newArray[i] = _array[i + 1];\n }\n unchecked {\n ++i;\n }\n }\n\n return newArray;\n }\n\n function setValue(\n bytes4[] memory _keys,\n address[] memory _values,\n bytes4 _key,\n address _value\n ) internal pure returns (bytes4[] memory, address[] memory) {\n uint256 index = findIndex(_keys, _key);\n uint256 keysLength = _keys.length;\n if (index < keysLength) {\n _values[index] = _value;\n } else {\n // Create new storage arrays\n bytes4[] memory newKeys = new bytes4[](keysLength + 1);\n address[] memory newValues = new address[](_values.length + 1);\n\n // Copy values to the new storage arrays\n for (uint256 i; i < keysLength; ) {\n newKeys[i] = _keys[i];\n newValues[i] = _values[i];\n\n unchecked {\n ++i;\n }\n }\n\n // Add the new key-value pair\n newKeys[keysLength] = _key;\n newValues[_values.length] = _value;\n\n return (newKeys, newValues);\n }\n\n // If the key already exists, return the original arrays\n return (_keys, _values);\n }\n\n function getValue(\n bytes4[] memory _keys,\n address[] memory _values,\n bytes4 _key\n ) internal pure returns (address) {\n uint256 index = findIndex(_keys, _key);\n if (index >= _keys.length) return address(0);\n\n return _values[index];\n }\n\n function findIndex(\n bytes4[] memory _keys,\n bytes4 _key\n ) internal pure returns (uint256) {\n uint256 keysLength = _keys.length;\n for (uint256 i; i < keysLength; ) {\n if (_keys[i] == _key) {\n return i;\n }\n unchecked {\n ++i;\n }\n }\n return keysLength;\n }\n}\n" + }, + "contracts/restrictions/IRestriction.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Interface for restrictions\n * @dev Restriction is a contract which decides whether to approve a certain kind of transaction, based on its internal logic.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface IRestriction {\n /**\n * @dev Based on restriction's internal logic, it should accept or reject a certain transaction.\n * @param from The address of the sender, that will be signing the transaction.\n * @param to The receiving address.\n * @param value Amount of ETH to transfer from sender to recipient.\n * @param _calldata Optional field to include arbitrary data.\n * @return bool value for whether the check is passed\n */\n function check(\n address from,\n address to,\n uint256 value,\n bytes calldata _calldata\n ) external returns (bool);\n}\n" + }, + "contracts/restrictions/WhitelistRestriction.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibRecoverSpender} from \"../libraries/LibRecoverSpender.sol\";\nimport {WhitelistStorage} from \"../infrastructure/WhitelistStorage.sol\";\nimport {IRestriction} from \"./IRestriction.sol\";\n\n/**\n * @title Whitelist Restriction\n * @dev This restriction defines a list of accepted addresses and denies any interaction with addresses outside of it.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract WhitelistRestriction is IRestriction {\n WhitelistStorage public immutable whitelistStorage;\n\n constructor(WhitelistStorage _whitelistStorage) {\n whitelistStorage = _whitelistStorage;\n }\n\n /**\n * @notice Helper method to recover the spender from a contract call.\n * The method returns the contract unless the call is to a standard method of a ERC20/ERC721/ERC1155 token\n * in which case the spender is recovered from the data.\n * @param _to The target contract.\n * @param _data The data payload.\n */\n function recoverSpender(\n address _to,\n bytes memory _data\n ) public pure returns (address spender) {\n return LibRecoverSpender._recover(_to, _data);\n }\n\n /*\n * @dev IRestriction's implementation. It will allow transaction if the sender is whitelisted, or user, or the whitelist storage.\n * @param _from The address of the sender, that will be signing the transaction.\n * @param _to The receiving address.\n * @param _calldata Optional field to include arbitrary data.\n * @return result value for whether the check is passed\n */\n function check(\n address _from,\n address _to,\n uint256 /*_value*/,\n bytes calldata _calldata\n ) external view override returns (bool result) {\n return\n whitelistStorage.isWhitelisted(\n _from,\n LibRecoverSpender._recover(_to, _calldata)\n ) ||\n _to == address(whitelistStorage) ||\n _to == msg.sender;\n }\n}\n" + }, + "contracts/test/TestCounter.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\ncontract TestCounter {\n int private count = 0;\n\n event CounterIncremented(int count);\n event CounterDecremented(int count);\n\n function incrementCounter() public {\n count += 1;\n emit CounterIncremented(count);\n }\n\n function decrementCounter() public {\n count -= 1;\n emit CounterIncremented(count);\n }\n\n function getCount() public view returns (int) {\n return count;\n }\n}\n" + }, + "contracts/test/TestERC1155.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC1155/ERC1155.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\n\ncontract TestERC1155 is ERC1155 {\n using Counters for Counters.Counter;\n\n Counters.Counter private _tokenIds;\n\n constructor() ERC1155(\"\") {}\n\n function mint(address account, uint256 amount) external {\n uint256 tokenId = _getNextTokenId();\n _mint(account, tokenId, amount, \"\");\n }\n\n function mintBatch(\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes memory data\n ) external {\n require(\n ids.length == amounts.length,\n \"TestERC1155: arrays length mismatch\"\n );\n\n _mintBatch(to, ids, amounts, data);\n }\n\n function _getNextTokenId() private returns (uint256) {\n _tokenIds.increment();\n return _tokenIds.current();\n }\n}\n" + }, + "contracts/test/TestERC777.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC777/ERC777.sol\";\n\ncontract TestERC777 is ERC777 {\n constructor(\n address[] memory _operators\n ) ERC777(\"TestERC777\", \"TERC777\", _operators) {}\n\n function mint(address account, uint256 amount) external {\n _mint(account, amount, \"\", \"\");\n }\n}\n" + }, + "contracts/test/TestInvalidSecp256k1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IVerificationFacet} from \"../facets/interfaces/IVerificationFacet.sol\";\nimport {IERC1271} from \"../interfaces/ERC/IERC1271.sol\";\nimport {AppStorage, LibAppStorage, BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {LibFacetStorage, Secp256k1VerificationStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {UserOperation} from \"../aa-4337/interfaces/UserOperation.sol\";\n\n/**\n * @title Test Secp256k1 verification facet\n * @dev Default Ethereum's elliptic curve\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract TestInvalidSecp256k1VerificationFacet is BarzStorage, IERC1271 {\n using ECDSA for bytes32;\n error Secp256k1VerificationFacet__InvalidSignerLength();\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n\n event SignerUninitialized();\n\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n }\n\n // THIS INVALID FACET DOES NOT INCLUDE initializeSigner()\n // THIS FACET IS USED TO TEST WHEN initializeSigner() DOESN'T EXIST IN FACET\n\n function uninitializeSigner() external returns (uint256 uninitSuccess) {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view returns (uint256 validationData) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n return validateSignature(userOp, userOpHash, k1Storage.signer);\n }\n\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n address signer\n ) public pure returns (uint256) {\n bytes32 hash = userOpHash.toEthSignedMessageHash();\n if (signer != hash.recover(userOp.signature)) return 1;\n return 0;\n }\n\n // This is REMOVED for testing purpose\n function validateOwnerSignatureSelector() public pure returns (bytes4) {\n // return this.validateOwnerSignature.selector;\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n function owner() public view returns (bytes memory) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n return abi.encodePacked(k1Storage.signer);\n }\n\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure returns (bool) {\n return (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (_hash.recover(_signature) ==\n LibFacetStorage.k1Storage().signer)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n}\n" + }, + "contracts/test/TestNFT.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\n\ncontract TestNFT is ERC721 {\n using Counters for Counters.Counter;\n Counters.Counter private currentTokenId;\n\n constructor() ERC721(\"TestNFT\", \"TNFT\") {}\n\n function mint(address recipient) public returns (uint256) {\n currentTokenId.increment();\n uint256 newItemId = currentTokenId.current();\n _safeMint(recipient, newItemId);\n return newItemId;\n }\n}\n" + }, + "contracts/test/TestToken.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract TestToken is ERC20 {\n constructor()\n // solhint-disable-next-line no-empty-blocks\n ERC20(\"TST\", \"TestToken\")\n {}\n\n function mint(address sender, uint256 amount) external {\n _mint(sender, amount);\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 999999 + }, + "evmVersion": "paris", + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/deployments/mantle/.chainId b/deployments/mantle/.chainId new file mode 100644 index 0000000..0b3e0a6 --- /dev/null +++ b/deployments/mantle/.chainId @@ -0,0 +1 @@ +5000 \ No newline at end of file diff --git a/deployments/mantle/.pendingTransactions b/deployments/mantle/.pendingTransactions new file mode 100644 index 0000000..00d99d8 --- /dev/null +++ b/deployments/mantle/.pendingTransactions @@ -0,0 +1,7971 @@ +{ + "0x81f60bc1bd555cae38bb4d2126a6e20ffaceac5e68d85dab7a05f386790f018f": { + "decoded": { + "from": "0xb33654322bD3803821031624f5922eb14C9b8d18", + "gasPrice": "25312500", + "maxFeePerGas": "25312500", + "maxPriorityFeePerGas": "0", + "gasLimit": "90000000000", + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "value": "0", + "nonce": 10, + "data": "0x000000000000000000000000000000000000000000000000000000000000000061010060405234801561001157600080fd5b50604051610eba380380610eba8339810160408190526100309161006e565b6001600160a01b0393841660805291831660a052821660c0521660e0526100c2565b80516001600160a01b038116811461006957600080fd5b919050565b6000806000806080858703121561008457600080fd5b61008d85610052565b935061009b60208601610052565b92506100a960408601610052565b91506100b760608601610052565b905092959194509250565b60805160a05160c05160e051610d886101326000396000818161013b015281816102b3015261048101526000818160bf01528181610292015261046001526000818161016301528181610271015261043f01526000818161018b0152818161024f015261041d0152610d886000f3fe60806040523480156200001157600080fd5b5060043610620000925760003560e01c806344409a82116200006257806344409a821462000135578063b0d691fe146200015d578063b0f5d4641462000185578063c8a7adf514620001ad57600080fd5b8062c194db14620000975780630a1acd7314620000b9578063296601cd146200010757806333bb64a7146200011e575b600080fd5b620000a1620001c4565b604051620000b091906200056c565b60405180910390f35b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001620000b0565b620000e16200011836600462000635565b6200020e565b620000a16200012f36600462000695565b6200036d565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e1620001be36600462000635565b62000414565b606060405180602001620001d89062000538565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082820381018352601f90910116604052919050565b6000806200021f8686868662000414565b905073ffffffffffffffffffffffffffffffffffffffff81163b8015620002495750905062000365565b8360001b7f0000000000000000000000000000000000000000000000000000000000000000887f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008b8b604051620002e29062000538565b620002f497969594939291906200073a565b8190604051809103906000f590508015801562000315573d6000803e3d6000fd5b5060405173ffffffffffffffffffffffffffffffffffffffff821681529093507f9e6e326008e68f57877e2bae766a5745c162e42359e34834a7f0661fa82d31b19060200160405180910390a150505b949350505050565b6060600060405180602001620003839062000538565b6020820181038252601f19601f8201166040525090508089898989898989604051602001620003b997969594939291906200073a565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052620003f79291602001620007cd565b604051602081830303815290604052915050979650505050505050565b600080620004a87f0000000000000000000000000000000000000000000000000000000000000000877f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008a8a6200036d565b8051602091820120604080517fff00000000000000000000000000000000000000000000000000000000000000818501523060601b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001660218201526035810196909652605580870192909252805180870390920182526075909501909452835193019290922095945050505050565b610552806200080183390190565b60005b838110156200056357818101518382015260200162000549565b50506000910152565b60208152600082518060208401526200058d81604085016020870162000546565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b803573ffffffffffffffffffffffffffffffffffffffff81168114620005e457600080fd5b919050565b60008083601f840112620005fc57600080fd5b50813567ffffffffffffffff8111156200061557600080fd5b6020830191508360208285010111156200062e57600080fd5b9250929050565b600080600080606085870312156200064c57600080fd5b6200065785620005bf565b9350602085013567ffffffffffffffff8111156200067457600080fd5b6200068287828801620005e9565b9598909750949560400135949350505050565b600080600080600080600060c0888a031215620006b157600080fd5b620006bc88620005bf565b9650620006cc60208901620005bf565b9550620006dc60408901620005bf565b9450620006ec60608901620005bf565b9350620006fc60808901620005bf565b925060a088013567ffffffffffffffff8111156200071957600080fd5b620007278a828b01620005e9565b989b979a50959850939692959293505050565b600073ffffffffffffffffffffffffffffffffffffffff808a16835280891660208401528088166040840152808716606084015280861660808401525060c060a08301528260c0830152828460e0840137600060e0848401015260e07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f850116830101905098975050505050505050565b60008351620007e181846020880162000546565b835190830190620007f781836020880162000546565b0194935050505056fe608060405260405161055238038061055283398101604081905261002291610163565b6000858585858560405160240161003d959493929190610264565b60408051601f198184030181529181526020820180516001600160e01b0316634a93641760e01b1790525190915060009081906001600160a01b038a16906100869085906102c3565b600060405180830381855af49150503d80600081146100c1576040519150601f19603f3d011682016040523d82523d6000602084013e6100c6565b606091505b50915091508115806100e157506100dc816102df565b600114155b156100ff57604051636ff35f8960e01b815260040160405180910390fd5b505050505050505050610306565b80516001600160a01b038116811461012457600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101561015a578181015183820152602001610142565b50506000910152565b60008060008060008060c0878903121561017c57600080fd5b6101858761010d565b95506101936020880161010d565b94506101a16040880161010d565b93506101af6060880161010d565b92506101bd6080880161010d565b60a08801519092506001600160401b03808211156101da57600080fd5b818901915089601f8301126101ee57600080fd5b81518181111561020057610200610129565b604051601f8201601f19908116603f0116810190838211818310171561022857610228610129565b816040528281528c602084870101111561024157600080fd5b61025283602083016020880161013f565b80955050505050509295509295509295565b600060018060a01b0380881683528087166020840152808616604084015280851660608401525060a0608083015282518060a08401526102ab8160c085016020870161013f565b601f01601f19169190910160c0019695505050505050565b600082516102d581846020870161013f565b9190910192915050565b80516020808301519190811015610300576000198160200360031b1b821691505b50919050565b61023d806103156000396000f3fe60806040523661000b57005b600080357fffffffff000000000000000000000000000000000000000000000000000000001681527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020819052604090912054819060601c80610125576004838101546040517fcdffacc60000000000000000000000000000000000000000000000000000000081526000357fffffffff00000000000000000000000000000000000000000000000000000000169281019290925273ffffffffffffffffffffffffffffffffffffffff169063cdffacc690602401602060405180830381865afa1580156100fe573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061012291906101ca565b90505b73ffffffffffffffffffffffffffffffffffffffff81166101a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4261727a3a2046756e6374696f6e20646f6573206e6f74206578697374000000604482015260640160405180910390fd5b3660008037600080366000845af43d6000803e8080156101c5573d6000f35b3d6000fd5b6000602082840312156101dc57600080fd5b815173ffffffffffffffffffffffffffffffffffffffff8116811461020057600080fd5b939250505056fea26469706673582212200f3fa76ace3be8675d8b4c0d6c210a922fff2c2f1444023b817d1f6c908cd56a64736f6c63430008150033a2646970667358221220329ad45a4ef4915180001cb1fc90a5f97ad94a0b280426a580cba65fce28c0f164736f6c63430008150033000000000000000000000000fde53272dcd7938d16e031a6989753c3217283320000000000000000000000005ff137d4b0fdcd49dca30c7cf57e578a026d2789000000000000000000000000afcb70e6e9514e2a15b23a01d2a9b9f7a34f2c330000000000000000000000002e7f1dae1f3799d20f5c31befdc7a620f664728d", + "r": "0x3eea54574a941481b537e6f057fd908712c19f0ebe95dcbb84ff7e33374ecca8", + "s": "0x05c5cfd35515fd77b67fe4e80e5132f2abdd26bf360c68b08012cdda40ab16c0", + "v": 0, + "chainId": 5000 + } + }, + "0x8966a9d25a93802094c376b55426fe703c503c15e8904b051e13477e8798a82c": { + "name": "Secp256k1VerificationFacet", + "deployment": { + "_format": "hh-sol-artifact-1", + "contractName": "Secp256k1VerificationFacet", + "sourceName": "contracts/facets/verification/secp256k1/Secp256k1VerificationFacet.sol", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "LibAppStorage__AccountMustBeUninitialized", + "type": "error" + }, + { + "inputs": [], + "name": "LibAppStorage__SignerAlreadyUninitialized", + "type": "error" + }, + { + "inputs": [], + "name": "LibAppStorage__SignerMustBeUninitialized", + "type": "error" + }, + { + "inputs": [], + "name": "Secp256k1VerificationFacet__InvalidSignerLength", + "type": "error" + }, + { + "inputs": [], + "name": "VerificationFacet__InitializationFailure", + "type": "error" + }, + { + "inputs": [], + "name": "VerificationFacet__InvalidFacetMapping", + "type": "error" + }, + { + "inputs": [], + "name": "VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet", + "type": "error" + }, + { + "inputs": [], + "name": "VerificationFacet__ValidateOwnerSignatureSelectorNotSet", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "SignerInitialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "SignerUninitialized", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_publicKey", + "type": "bytes" + } + ], + "name": "initializeSigner", + "outputs": [ + { + "internalType": "uint256", + "name": "initSuccess", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_publicKey", + "type": "bytes" + } + ], + "name": "isValidKeyType", + "outputs": [ + { + "internalType": "bool", + "name": "isValid", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_hash", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "_signature", + "type": "bytes" + } + ], + "name": "isValidSignature", + "outputs": [ + { + "internalType": "bytes4", + "name": "magicValue", + "type": "bytes4" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "bytes", + "name": "signer", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "self", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "uninitializeSigner", + "outputs": [ + { + "internalType": "uint256", + "name": "uninitSuccess", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "initCode", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "callGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "verificationGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "preVerificationGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxFeePerGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPriorityFeePerGas", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "paymasterAndData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "internalType": "struct UserOperation", + "name": "userOp", + "type": "tuple" + }, + { + "internalType": "bytes32", + "name": "userOpHash", + "type": "bytes32" + } + ], + "name": "validateOwnerSignature", + "outputs": [ + { + "internalType": "uint256", + "name": "validationData", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "validateOwnerSignatureSelector", + "outputs": [ + { + "internalType": "bytes4", + "name": "ownerSignatureValidatorSelector", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "initCode", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "callGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "verificationGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "preVerificationGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxFeePerGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPriorityFeePerGas", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "paymasterAndData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "internalType": "struct UserOperation", + "name": "userOp", + "type": "tuple" + }, + { + "internalType": "bytes32", + "name": "userOpHash", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "signer", + "type": "address" + } + ], + "name": "validateSignature", + "outputs": [ + { + "internalType": "uint256", + "name": "isValid", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + } + ], + "bytecode": "0x60a060405234801561001057600080fd5b50610019610022565b3060805261008b565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff161561006f57604051637c2cde8b60e01b815260040160405180910390fd5b600080805260209190915260409020805460ff19166001179055565b6080516111946100ad6000396000818161013f015261066401526111946000f3fe608060405234801561001057600080fd5b50600436106100a35760003560e01c80638da5cb5b11610076578063cd00e50a1161005b578063cd00e50a14610218578063cd9b47e414610220578063f45007c31461023357600080fd5b80638da5cb5b146101865780638dd50121146101f757600080fd5b80631626ba7e146100a85780633253960f146100f1578063392dd6d9146101175780637104ddb21461013a575b600080fd5b6100bb6100b6366004610de8565b610246565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020015b60405180910390f35b7f8dd50121000000000000000000000000000000000000000000000000000000006100bb565b61012a610125366004610e2f565b6102f4565b60405190151581526020016100e8565b6101617f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100e8565b7f9d0217145d12a316adea26b4f622aec07fb71e6638d613bb415476f4c179eecc546040805160609290921b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016602083015280518083036014018152603490920190526040516100e89190610e64565b61020a610205366004610ee9565b610366565b6040519081526020016100e8565b61020a6103b8565b61020a61022e366004610f2e565b6104d6565b61020a610241366004610fa0565b6107b7565b60007f9d0217145d12a316adea26b4f622aec07fb71e6638d613bb415476f4c179eecc5473ffffffffffffffffffffffffffffffffffffffff1661028a848461087c565b73ffffffffffffffffffffffffffffffffffffffff16146102cb577fffffffff000000000000000000000000000000000000000000000000000000006102ed565b7f1626ba7e000000000000000000000000000000000000000000000000000000005b9392505050565b60008151604114801561036057508160008151811061031557610315611014565b6020910101517fff00000000000000000000000000000000000000000000000000000000000000167f0400000000000000000000000000000000000000000000000000000000000000145b92915050565b7f9d0217145d12a316adea26b4f622aec07fb71e6638d613bb415476f4c179eecc8054600091906103b0908590859073ffffffffffffffffffffffffffffffffffffffff166107b7565b949350505050565b60006103c26108a0565b6103ca6108e0565b7f9d0217145d12a316adea26b4f622aec07fb71e6638d613bb415476f4c179eecc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001681556000610424600154610100900460e01b90565b7fffffffff00000000000000000000000000000000000000000000000000000000160361047d576040517f127c609a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff169055604051600192507fcccd30db6bc000b8bb8d11162228d2d69e3c361983ca3ae8c1365ce64b0fae9e90600090a15090565b60006104e061097f565b61051f83838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102f492505050565b610555576040517f22281e8500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f9d0217145d12a316adea26b4f622aec07fb71e6638d613bb415476f4c179eecc6105838360018187611043565b60405161059192919061106d565b60405190819003902081547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9091161781556001547f8dd501210000000000000000000000000000000000000000000000000000000090600090610100900460e01b7fffffffff000000000000000000000000000000000000000000000000000000001614610662576040517f5f95a63c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166106f3827fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604090205460601c90565b73ffffffffffffffffffffffffffffffffffffffff1614610740576040517fbb4752b700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff1661010060e084901c02179055600192507f6d54821a69ec281ed7ba1bf2729c700768c47df1d80fad646b0a14cc1d5c39ed85856040516107a792919061107d565b60405180910390a1505092915050565b7f19457468657265756d205369676e6564204d6573736167653a0a3332000000006000908152601c839052603c81206108346107f76101408701876110ca565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250859392505061087c9050565b73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361086d576000610870565b60015b60ff1695945050505050565b600080600061088b8585610a1f565b9150915061089881610a64565b509392505050565b6001805460ff16146108de576040517f38fc28cb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff16600114610948576040517fe00d7c7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff16156109e5576040517f7c2cde8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b6000808251604103610a555760208301516040840151606085015160001a610a4987828585610c1f565b94509450505050610a5d565b506000905060025b9250929050565b6000816004811115610a7857610a7861112f565b03610a805750565b6001816004811115610a9457610a9461112f565b03610b00576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064015b60405180910390fd5b6002816004811115610b1457610b1461112f565b03610b7b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610af7565b6003816004811115610b8f57610b8f61112f565b03610c1c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610af7565b50565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115610c565750600090506003610d05565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015610caa573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116610cfe57600060019250925050610d05565b9150600090505b94509492505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112610d4e57600080fd5b813567ffffffffffffffff80821115610d6957610d69610d0e565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715610daf57610daf610d0e565b81604052838152866020858801011115610dc857600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060408385031215610dfb57600080fd5b82359150602083013567ffffffffffffffff811115610e1957600080fd5b610e2585828601610d3d565b9150509250929050565b600060208284031215610e4157600080fd5b813567ffffffffffffffff811115610e5857600080fd5b6103b084828501610d3d565b600060208083528351808285015260005b81811015610e9157858101830151858201604001528201610e75565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b60006101608284031215610ee357600080fd5b50919050565b60008060408385031215610efc57600080fd5b823567ffffffffffffffff811115610f1357600080fd5b610f1f85828601610ed0565b95602094909401359450505050565b60008060208385031215610f4157600080fd5b823567ffffffffffffffff80821115610f5957600080fd5b818501915085601f830112610f6d57600080fd5b813581811115610f7c57600080fd5b866020828501011115610f8e57600080fd5b60209290920196919550909350505050565b600080600060608486031215610fb557600080fd5b833567ffffffffffffffff811115610fcc57600080fd5b610fd886828701610ed0565b93505060208401359150604084013573ffffffffffffffffffffffffffffffffffffffff8116811461100957600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000808585111561105357600080fd5b8386111561106057600080fd5b5050820193919092039150565b8183823760009101908152919050565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126110ff57600080fd5b83018035915067ffffffffffffffff82111561111a57600080fd5b602001915036819003821315610a5d57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea2646970667358221220de3368e3f3953432149ec8ab61e8db05409a34e6f3f223f6bc0a20072fa01cf364736f6c63430008150033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100a35760003560e01c80638da5cb5b11610076578063cd00e50a1161005b578063cd00e50a14610218578063cd9b47e414610220578063f45007c31461023357600080fd5b80638da5cb5b146101865780638dd50121146101f757600080fd5b80631626ba7e146100a85780633253960f146100f1578063392dd6d9146101175780637104ddb21461013a575b600080fd5b6100bb6100b6366004610de8565b610246565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020015b60405180910390f35b7f8dd50121000000000000000000000000000000000000000000000000000000006100bb565b61012a610125366004610e2f565b6102f4565b60405190151581526020016100e8565b6101617f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100e8565b7f9d0217145d12a316adea26b4f622aec07fb71e6638d613bb415476f4c179eecc546040805160609290921b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016602083015280518083036014018152603490920190526040516100e89190610e64565b61020a610205366004610ee9565b610366565b6040519081526020016100e8565b61020a6103b8565b61020a61022e366004610f2e565b6104d6565b61020a610241366004610fa0565b6107b7565b60007f9d0217145d12a316adea26b4f622aec07fb71e6638d613bb415476f4c179eecc5473ffffffffffffffffffffffffffffffffffffffff1661028a848461087c565b73ffffffffffffffffffffffffffffffffffffffff16146102cb577fffffffff000000000000000000000000000000000000000000000000000000006102ed565b7f1626ba7e000000000000000000000000000000000000000000000000000000005b9392505050565b60008151604114801561036057508160008151811061031557610315611014565b6020910101517fff00000000000000000000000000000000000000000000000000000000000000167f0400000000000000000000000000000000000000000000000000000000000000145b92915050565b7f9d0217145d12a316adea26b4f622aec07fb71e6638d613bb415476f4c179eecc8054600091906103b0908590859073ffffffffffffffffffffffffffffffffffffffff166107b7565b949350505050565b60006103c26108a0565b6103ca6108e0565b7f9d0217145d12a316adea26b4f622aec07fb71e6638d613bb415476f4c179eecc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001681556000610424600154610100900460e01b90565b7fffffffff00000000000000000000000000000000000000000000000000000000160361047d576040517f127c609a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff169055604051600192507fcccd30db6bc000b8bb8d11162228d2d69e3c361983ca3ae8c1365ce64b0fae9e90600090a15090565b60006104e061097f565b61051f83838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102f492505050565b610555576040517f22281e8500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f9d0217145d12a316adea26b4f622aec07fb71e6638d613bb415476f4c179eecc6105838360018187611043565b60405161059192919061106d565b60405190819003902081547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9091161781556001547f8dd501210000000000000000000000000000000000000000000000000000000090600090610100900460e01b7fffffffff000000000000000000000000000000000000000000000000000000001614610662576040517f5f95a63c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166106f3827fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604090205460601c90565b73ffffffffffffffffffffffffffffffffffffffff1614610740576040517fbb4752b700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff1661010060e084901c02179055600192507f6d54821a69ec281ed7ba1bf2729c700768c47df1d80fad646b0a14cc1d5c39ed85856040516107a792919061107d565b60405180910390a1505092915050565b7f19457468657265756d205369676e6564204d6573736167653a0a3332000000006000908152601c839052603c81206108346107f76101408701876110ca565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250859392505061087c9050565b73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361086d576000610870565b60015b60ff1695945050505050565b600080600061088b8585610a1f565b9150915061089881610a64565b509392505050565b6001805460ff16146108de576040517f38fc28cb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff16600114610948576040517fe00d7c7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff16156109e5576040517f7c2cde8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b6000808251604103610a555760208301516040840151606085015160001a610a4987828585610c1f565b94509450505050610a5d565b506000905060025b9250929050565b6000816004811115610a7857610a7861112f565b03610a805750565b6001816004811115610a9457610a9461112f565b03610b00576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064015b60405180910390fd5b6002816004811115610b1457610b1461112f565b03610b7b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610af7565b6003816004811115610b8f57610b8f61112f565b03610c1c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610af7565b50565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115610c565750600090506003610d05565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015610caa573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116610cfe57600060019250925050610d05565b9150600090505b94509492505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112610d4e57600080fd5b813567ffffffffffffffff80821115610d6957610d69610d0e565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715610daf57610daf610d0e565b81604052838152866020858801011115610dc857600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060408385031215610dfb57600080fd5b82359150602083013567ffffffffffffffff811115610e1957600080fd5b610e2585828601610d3d565b9150509250929050565b600060208284031215610e4157600080fd5b813567ffffffffffffffff811115610e5857600080fd5b6103b084828501610d3d565b600060208083528351808285015260005b81811015610e9157858101830151858201604001528201610e75565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b60006101608284031215610ee357600080fd5b50919050565b60008060408385031215610efc57600080fd5b823567ffffffffffffffff811115610f1357600080fd5b610f1f85828601610ed0565b95602094909401359450505050565b60008060208385031215610f4157600080fd5b823567ffffffffffffffff80821115610f5957600080fd5b818501915085601f830112610f6d57600080fd5b813581811115610f7c57600080fd5b866020828501011115610f8e57600080fd5b60209290920196919550909350505050565b600080600060608486031215610fb557600080fd5b833567ffffffffffffffff811115610fcc57600080fd5b610fd886828701610ed0565b93505060208401359150604084013573ffffffffffffffffffffffffffffffffffffffff8116811461100957600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000808585111561105357600080fd5b8386111561106057600080fd5b5050820193919092039150565b8183823760009101908152919050565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126110ff57600080fd5b83018035915067ffffffffffffffff82111561111a57600080fd5b602001915036819003821315610a5d57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea2646970667358221220de3368e3f3953432149ec8ab61e8db05409a34e6f3f223f6bc0a20072fa01cf364736f6c63430008150033", + "linkReferences": {}, + "deployedLinkReferences": {}, + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)Ruslan Serebriakov (@rsrbk)", + "details": "Default Ethereum's elliptic curve", + "kind": "dev", + "methods": { + "initializeSigner(bytes)": { + "details": "This method checks if the signer has already been initialized. If already initialized, it reverts. It checks if the public key is in the light format and initializes signer storage in k1 storage.", + "params": { + "_publicKey": "Bytes of owner public key" + }, + "returns": { + "initSuccess": "Uint value representing the success of init operation" + } + }, + "isValidKeyType(bytes)": { + "details": "For this Secp256k1Verification Facet, the public key length should be 65 in an uncompressed public key format", + "params": { + "_publicKey": "Bytes of public key for format check" + }, + "returns": { + "isValid": "Boolean variable representing if the format of public key is valid" + } + }, + "isValidSignature(bytes32,bytes)": { + "details": "This method verifies the signature if the owner indeed signed the hash. Returns magic value if true", + "params": { + "_hash": "Hash value the owner signed", + "_signature": "Signature that signed the above hash" + }, + "returns": { + "magicValue": "Bytes4 value representing the success/failure of validation" + } + }, + "owner()": { + "returns": { + "signer": "Bytes of owner address" + } + }, + "uninitializeSigner()": { + "details": "This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.", + "returns": { + "uninitSuccess": "Uint value representing the success of uninit operation" + } + }, + "validateOwnerSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32)": { + "details": "This method validates if the user operation is signed by the owner. It internally calls validateSignature with signer public key.", + "params": { + "userOp": "UserOperation including all information for execution", + "userOpHash": "Hash of UserOperation given from EntryPoint. This hash is used for signature validation" + }, + "returns": { + "validationData": "Uint value representing whether the validation is successful. 0 for success, 1 for failure" + } + }, + "validateOwnerSignatureSelector()": { + "returns": { + "ownerSignatureValidatorSelector": "Bytes4 selector of function signature to validate account owner's UserOperation signature" + } + }, + "validateSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,address)": { + "details": "This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address", + "params": { + "signer": "Address of signer who signed the contract, to be validated", + "userOp": "UserOperation including all information for execution", + "userOpHash": "Hash of UserOperation given from EntryPoint. This hash is used for signature validation" + }, + "returns": { + "isValid": "Uint value representing whether the validation is successful. 0 for success, 1 for failure" + } + } + }, + "title": "Secp256k1 verification facet", + "version": 1 + }, + "evm": { + "bytecode": { + "functionDebugData": { + "@_22303": { + "entryPoint": null, + "id": 22303, + "parameterSlots": 0, + "returnSlots": 0 + }, + "@appStorage_27629": { + "entryPoint": null, + "id": 27629, + "parameterSlots": 0, + "returnSlots": 1 + }, + "@enforceSignerInitialize_27715": { + "entryPoint": 34, + "id": 27715, + "parameterSlots": 0, + "returnSlots": 0 + } + }, + "generatedSources": [], + "linkReferences": {}, + "object": "60a060405234801561001057600080fd5b50610019610022565b3060805261008b565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff161561006f57604051637c2cde8b60e01b815260040160405180910390fd5b600080805260209190915260409020805460ff19166001179055565b6080516111946100ad6000396000818161013f015261066401526111946000f3fe608060405234801561001057600080fd5b50600436106100a35760003560e01c80638da5cb5b11610076578063cd00e50a1161005b578063cd00e50a14610218578063cd9b47e414610220578063f45007c31461023357600080fd5b80638da5cb5b146101865780638dd50121146101f757600080fd5b80631626ba7e146100a85780633253960f146100f1578063392dd6d9146101175780637104ddb21461013a575b600080fd5b6100bb6100b6366004610de8565b610246565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020015b60405180910390f35b7f8dd50121000000000000000000000000000000000000000000000000000000006100bb565b61012a610125366004610e2f565b6102f4565b60405190151581526020016100e8565b6101617f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100e8565b7f9d0217145d12a316adea26b4f622aec07fb71e6638d613bb415476f4c179eecc546040805160609290921b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016602083015280518083036014018152603490920190526040516100e89190610e64565b61020a610205366004610ee9565b610366565b6040519081526020016100e8565b61020a6103b8565b61020a61022e366004610f2e565b6104d6565b61020a610241366004610fa0565b6107b7565b60007f9d0217145d12a316adea26b4f622aec07fb71e6638d613bb415476f4c179eecc5473ffffffffffffffffffffffffffffffffffffffff1661028a848461087c565b73ffffffffffffffffffffffffffffffffffffffff16146102cb577fffffffff000000000000000000000000000000000000000000000000000000006102ed565b7f1626ba7e000000000000000000000000000000000000000000000000000000005b9392505050565b60008151604114801561036057508160008151811061031557610315611014565b6020910101517fff00000000000000000000000000000000000000000000000000000000000000167f0400000000000000000000000000000000000000000000000000000000000000145b92915050565b7f9d0217145d12a316adea26b4f622aec07fb71e6638d613bb415476f4c179eecc8054600091906103b0908590859073ffffffffffffffffffffffffffffffffffffffff166107b7565b949350505050565b60006103c26108a0565b6103ca6108e0565b7f9d0217145d12a316adea26b4f622aec07fb71e6638d613bb415476f4c179eecc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001681556000610424600154610100900460e01b90565b7fffffffff00000000000000000000000000000000000000000000000000000000160361047d576040517f127c609a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff169055604051600192507fcccd30db6bc000b8bb8d11162228d2d69e3c361983ca3ae8c1365ce64b0fae9e90600090a15090565b60006104e061097f565b61051f83838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102f492505050565b610555576040517f22281e8500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f9d0217145d12a316adea26b4f622aec07fb71e6638d613bb415476f4c179eecc6105838360018187611043565b60405161059192919061106d565b60405190819003902081547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9091161781556001547f8dd501210000000000000000000000000000000000000000000000000000000090600090610100900460e01b7fffffffff000000000000000000000000000000000000000000000000000000001614610662576040517f5f95a63c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166106f3827fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604090205460601c90565b73ffffffffffffffffffffffffffffffffffffffff1614610740576040517fbb4752b700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff1661010060e084901c02179055600192507f6d54821a69ec281ed7ba1bf2729c700768c47df1d80fad646b0a14cc1d5c39ed85856040516107a792919061107d565b60405180910390a1505092915050565b7f19457468657265756d205369676e6564204d6573736167653a0a3332000000006000908152601c839052603c81206108346107f76101408701876110ca565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250859392505061087c9050565b73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361086d576000610870565b60015b60ff1695945050505050565b600080600061088b8585610a1f565b9150915061089881610a64565b509392505050565b6001805460ff16146108de576040517f38fc28cb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff16600114610948576040517fe00d7c7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff16156109e5576040517f7c2cde8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b6000808251604103610a555760208301516040840151606085015160001a610a4987828585610c1f565b94509450505050610a5d565b506000905060025b9250929050565b6000816004811115610a7857610a7861112f565b03610a805750565b6001816004811115610a9457610a9461112f565b03610b00576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064015b60405180910390fd5b6002816004811115610b1457610b1461112f565b03610b7b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610af7565b6003816004811115610b8f57610b8f61112f565b03610c1c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610af7565b50565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115610c565750600090506003610d05565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015610caa573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116610cfe57600060019250925050610d05565b9150600090505b94509492505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112610d4e57600080fd5b813567ffffffffffffffff80821115610d6957610d69610d0e565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715610daf57610daf610d0e565b81604052838152866020858801011115610dc857600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060408385031215610dfb57600080fd5b82359150602083013567ffffffffffffffff811115610e1957600080fd5b610e2585828601610d3d565b9150509250929050565b600060208284031215610e4157600080fd5b813567ffffffffffffffff811115610e5857600080fd5b6103b084828501610d3d565b600060208083528351808285015260005b81811015610e9157858101830151858201604001528201610e75565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b60006101608284031215610ee357600080fd5b50919050565b60008060408385031215610efc57600080fd5b823567ffffffffffffffff811115610f1357600080fd5b610f1f85828601610ed0565b95602094909401359450505050565b60008060208385031215610f4157600080fd5b823567ffffffffffffffff80821115610f5957600080fd5b818501915085601f830112610f6d57600080fd5b813581811115610f7c57600080fd5b866020828501011115610f8e57600080fd5b60209290920196919550909350505050565b600080600060608486031215610fb557600080fd5b833567ffffffffffffffff811115610fcc57600080fd5b610fd886828701610ed0565b93505060208401359150604084013573ffffffffffffffffffffffffffffffffffffffff8116811461100957600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000808585111561105357600080fd5b8386111561106057600080fd5b5050820193919092039150565b8183823760009101908152919050565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126110ff57600080fd5b83018035915067ffffffffffffffff82111561111a57600080fd5b602001915036819003821315610a5d57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea2646970667358221220de3368e3f3953432149ec8ab61e8db05409a34e6f3f223f6bc0a20072fa01cf364736f6c63430008150033", + "opcodes": "PUSH1 0xA0 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0x10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x19 PUSH2 0x22 JUMP JUMPDEST ADDRESS PUSH1 0x80 MSTORE PUSH2 0x8B JUMP JUMPDEST PUSH1 0x0 DUP1 DUP1 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH32 0xAD3228B676F7D3CD4284A5443F17F1962B36E491B30A40B2405849E597BA5FB5 SLOAD PUSH1 0xFF AND ISZERO PUSH2 0x6F JUMPI PUSH1 0x40 MLOAD PUSH4 0x7C2CDE8B PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x0 DUP1 DUP1 MSTORE PUSH1 0x20 SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0x40 SWAP1 KECCAK256 DUP1 SLOAD PUSH1 0xFF NOT AND PUSH1 0x1 OR SWAP1 SSTORE JUMP JUMPDEST PUSH1 0x80 MLOAD PUSH2 0x1194 PUSH2 0xAD PUSH1 0x0 CODECOPY PUSH1 0x0 DUP2 DUP2 PUSH2 0x13F ADD MSTORE PUSH2 0x664 ADD MSTORE PUSH2 0x1194 PUSH1 0x0 RETURN INVALID PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0x10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x4 CALLDATASIZE LT PUSH2 0xA3 JUMPI PUSH1 0x0 CALLDATALOAD PUSH1 0xE0 SHR DUP1 PUSH4 0x8DA5CB5B GT PUSH2 0x76 JUMPI DUP1 PUSH4 0xCD00E50A GT PUSH2 0x5B JUMPI DUP1 PUSH4 0xCD00E50A EQ PUSH2 0x218 JUMPI DUP1 PUSH4 0xCD9B47E4 EQ PUSH2 0x220 JUMPI DUP1 PUSH4 0xF45007C3 EQ PUSH2 0x233 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 PUSH4 0x8DA5CB5B EQ PUSH2 0x186 JUMPI DUP1 PUSH4 0x8DD50121 EQ PUSH2 0x1F7 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 PUSH4 0x1626BA7E EQ PUSH2 0xA8 JUMPI DUP1 PUSH4 0x3253960F EQ PUSH2 0xF1 JUMPI DUP1 PUSH4 0x392DD6D9 EQ PUSH2 0x117 JUMPI DUP1 PUSH4 0x7104DDB2 EQ PUSH2 0x13A JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xBB PUSH2 0xB6 CALLDATASIZE PUSH1 0x4 PUSH2 0xDE8 JUMP JUMPDEST PUSH2 0x246 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 SWAP1 SWAP2 AND DUP2 MSTORE PUSH1 0x20 ADD JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH32 0x8DD5012100000000000000000000000000000000000000000000000000000000 PUSH2 0xBB JUMP JUMPDEST PUSH2 0x12A PUSH2 0x125 CALLDATASIZE PUSH1 0x4 PUSH2 0xE2F JUMP JUMPDEST PUSH2 0x2F4 JUMP JUMPDEST PUSH1 0x40 MLOAD SWAP1 ISZERO ISZERO DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0xE8 JUMP JUMPDEST PUSH2 0x161 PUSH32 0x0 DUP2 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP2 AND DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0xE8 JUMP JUMPDEST PUSH32 0x9D0217145D12A316ADEA26B4F622AEC07FB71E6638D613BB415476F4C179EECC SLOAD PUSH1 0x40 DUP1 MLOAD PUSH1 0x60 SWAP3 SWAP1 SWAP3 SHL PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000 AND PUSH1 0x20 DUP4 ADD MSTORE DUP1 MLOAD DUP1 DUP4 SUB PUSH1 0x14 ADD DUP2 MSTORE PUSH1 0x34 SWAP1 SWAP3 ADD SWAP1 MSTORE PUSH1 0x40 MLOAD PUSH2 0xE8 SWAP2 SWAP1 PUSH2 0xE64 JUMP JUMPDEST PUSH2 0x20A PUSH2 0x205 CALLDATASIZE PUSH1 0x4 PUSH2 0xEE9 JUMP JUMPDEST PUSH2 0x366 JUMP JUMPDEST PUSH1 0x40 MLOAD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0xE8 JUMP JUMPDEST PUSH2 0x20A PUSH2 0x3B8 JUMP JUMPDEST PUSH2 0x20A PUSH2 0x22E CALLDATASIZE PUSH1 0x4 PUSH2 0xF2E JUMP JUMPDEST PUSH2 0x4D6 JUMP JUMPDEST PUSH2 0x20A PUSH2 0x241 CALLDATASIZE PUSH1 0x4 PUSH2 0xFA0 JUMP JUMPDEST PUSH2 0x7B7 JUMP JUMPDEST PUSH1 0x0 PUSH32 0x9D0217145D12A316ADEA26B4F622AEC07FB71E6638D613BB415476F4C179EECC SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH2 0x28A DUP5 DUP5 PUSH2 0x87C JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND EQ PUSH2 0x2CB JUMPI PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 PUSH2 0x2ED JUMP JUMPDEST PUSH32 0x1626BA7E00000000000000000000000000000000000000000000000000000000 JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP2 MLOAD PUSH1 0x41 EQ DUP1 ISZERO PUSH2 0x360 JUMPI POP DUP2 PUSH1 0x0 DUP2 MLOAD DUP2 LT PUSH2 0x315 JUMPI PUSH2 0x315 PUSH2 0x1014 JUMP JUMPDEST PUSH1 0x20 SWAP2 ADD ADD MLOAD PUSH32 0xFF00000000000000000000000000000000000000000000000000000000000000 AND PUSH32 0x400000000000000000000000000000000000000000000000000000000000000 EQ JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH32 0x9D0217145D12A316ADEA26B4F622AEC07FB71E6638D613BB415476F4C179EECC DUP1 SLOAD PUSH1 0x0 SWAP2 SWAP1 PUSH2 0x3B0 SWAP1 DUP6 SWAP1 DUP6 SWAP1 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH2 0x7B7 JUMP JUMPDEST SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x3C2 PUSH2 0x8A0 JUMP JUMPDEST PUSH2 0x3CA PUSH2 0x8E0 JUMP JUMPDEST PUSH32 0x9D0217145D12A316ADEA26B4F622AEC07FB71E6638D613BB415476F4C179EECC DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND DUP2 SSTORE PUSH1 0x0 PUSH2 0x424 PUSH1 0x1 SLOAD PUSH2 0x100 SWAP1 DIV PUSH1 0xE0 SHL SWAP1 JUMP JUMPDEST PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 AND SUB PUSH2 0x47D JUMPI PUSH1 0x40 MLOAD PUSH32 0x127C609A00000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x1 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FF AND SWAP1 SSTORE PUSH1 0x40 MLOAD PUSH1 0x1 SWAP3 POP PUSH32 0xCCCD30DB6BC000B8BB8D11162228D2D69E3C361983CA3AE8C1365CE64B0FAE9E SWAP1 PUSH1 0x0 SWAP1 LOG1 POP SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x4E0 PUSH2 0x97F JUMP JUMPDEST PUSH2 0x51F DUP4 DUP4 DUP1 DUP1 PUSH1 0x1F ADD PUSH1 0x20 DUP1 SWAP2 DIV MUL PUSH1 0x20 ADD PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 SWAP4 SWAP3 SWAP2 SWAP1 DUP2 DUP2 MSTORE PUSH1 0x20 ADD DUP4 DUP4 DUP1 DUP3 DUP5 CALLDATACOPY PUSH1 0x0 SWAP3 ADD SWAP2 SWAP1 SWAP2 MSTORE POP PUSH2 0x2F4 SWAP3 POP POP POP JUMP JUMPDEST PUSH2 0x555 JUMPI PUSH1 0x40 MLOAD PUSH32 0x22281E8500000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH32 0x9D0217145D12A316ADEA26B4F622AEC07FB71E6638D613BB415476F4C179EECC PUSH2 0x583 DUP4 PUSH1 0x1 DUP2 DUP8 PUSH2 0x1043 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x591 SWAP3 SWAP2 SWAP1 PUSH2 0x106D JUMP JUMPDEST PUSH1 0x40 MLOAD SWAP1 DUP2 SWAP1 SUB SWAP1 KECCAK256 DUP2 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP2 AND OR DUP2 SSTORE PUSH1 0x1 SLOAD PUSH32 0x8DD5012100000000000000000000000000000000000000000000000000000000 SWAP1 PUSH1 0x0 SWAP1 PUSH2 0x100 SWAP1 DIV PUSH1 0xE0 SHL PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 AND EQ PUSH2 0x662 JUMPI PUSH1 0x40 MLOAD PUSH32 0x5F95A63C00000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH32 0x0 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH2 0x6F3 DUP3 PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH32 0x183CDE5D4F6BB7B445B8FC2F7F15D0FD1D162275ADED24183BABBFFEE7CD491F PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH1 0x60 SHR SWAP1 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND EQ PUSH2 0x740 JUMPI PUSH1 0x40 MLOAD PUSH32 0xBB4752B700000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x1 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FF AND PUSH2 0x100 PUSH1 0xE0 DUP5 SWAP1 SHR MUL OR SWAP1 SSTORE PUSH1 0x1 SWAP3 POP PUSH32 0x6D54821A69EC281ED7BA1BF2729C700768C47DF1D80FAD646B0A14CC1D5C39ED DUP6 DUP6 PUSH1 0x40 MLOAD PUSH2 0x7A7 SWAP3 SWAP2 SWAP1 PUSH2 0x107D JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG1 POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH32 0x19457468657265756D205369676E6564204D6573736167653A0A333200000000 PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1C DUP4 SWAP1 MSTORE PUSH1 0x3C DUP2 KECCAK256 PUSH2 0x834 PUSH2 0x7F7 PUSH2 0x140 DUP8 ADD DUP8 PUSH2 0x10CA JUMP JUMPDEST DUP1 DUP1 PUSH1 0x1F ADD PUSH1 0x20 DUP1 SWAP2 DIV MUL PUSH1 0x20 ADD PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 SWAP4 SWAP3 SWAP2 SWAP1 DUP2 DUP2 MSTORE PUSH1 0x20 ADD DUP4 DUP4 DUP1 DUP3 DUP5 CALLDATACOPY PUSH1 0x0 SWAP3 ADD SWAP2 SWAP1 SWAP2 MSTORE POP DUP6 SWAP4 SWAP3 POP POP PUSH2 0x87C SWAP1 POP JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SUB PUSH2 0x86D JUMPI PUSH1 0x0 PUSH2 0x870 JUMP JUMPDEST PUSH1 0x1 JUMPDEST PUSH1 0xFF AND SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH2 0x88B DUP6 DUP6 PUSH2 0xA1F JUMP JUMPDEST SWAP2 POP SWAP2 POP PUSH2 0x898 DUP2 PUSH2 0xA64 JUMP JUMPDEST POP SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x1 DUP1 SLOAD PUSH1 0xFF AND EQ PUSH2 0x8DE JUMPI PUSH1 0x40 MLOAD PUSH32 0x38FC28CB00000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST JUMP JUMPDEST PUSH1 0x0 DUP1 DUP1 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH32 0xAD3228B676F7D3CD4284A5443F17F1962B36E491B30A40B2405849E597BA5FB5 SLOAD PUSH1 0xFF AND PUSH1 0x1 EQ PUSH2 0x948 JUMPI PUSH1 0x40 MLOAD PUSH32 0xE00D7C7700000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x0 DUP1 DUP1 MSTORE PUSH1 0x20 SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0x40 SWAP1 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND SWAP1 SSTORE JUMP JUMPDEST PUSH1 0x0 DUP1 DUP1 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH32 0xAD3228B676F7D3CD4284A5443F17F1962B36E491B30A40B2405849E597BA5FB5 SLOAD PUSH1 0xFF AND ISZERO PUSH2 0x9E5 JUMPI PUSH1 0x40 MLOAD PUSH32 0x7C2CDE8B00000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x0 DUP1 DUP1 MSTORE PUSH1 0x20 SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0x40 SWAP1 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND PUSH1 0x1 OR SWAP1 SSTORE JUMP JUMPDEST PUSH1 0x0 DUP1 DUP3 MLOAD PUSH1 0x41 SUB PUSH2 0xA55 JUMPI PUSH1 0x20 DUP4 ADD MLOAD PUSH1 0x40 DUP5 ADD MLOAD PUSH1 0x60 DUP6 ADD MLOAD PUSH1 0x0 BYTE PUSH2 0xA49 DUP8 DUP3 DUP6 DUP6 PUSH2 0xC1F JUMP JUMPDEST SWAP5 POP SWAP5 POP POP POP POP PUSH2 0xA5D JUMP JUMPDEST POP PUSH1 0x0 SWAP1 POP PUSH1 0x2 JUMPDEST SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP2 PUSH1 0x4 DUP2 GT ISZERO PUSH2 0xA78 JUMPI PUSH2 0xA78 PUSH2 0x112F JUMP JUMPDEST SUB PUSH2 0xA80 JUMPI POP JUMP JUMPDEST PUSH1 0x1 DUP2 PUSH1 0x4 DUP2 GT ISZERO PUSH2 0xA94 JUMPI PUSH2 0xA94 PUSH2 0x112F JUMP JUMPDEST SUB PUSH2 0xB00 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x20 PUSH1 0x4 DUP3 ADD MSTORE PUSH1 0x18 PUSH1 0x24 DUP3 ADD MSTORE PUSH32 0x45434453413A20696E76616C6964207369676E61747572650000000000000000 PUSH1 0x44 DUP3 ADD MSTORE PUSH1 0x64 ADD JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x2 DUP2 PUSH1 0x4 DUP2 GT ISZERO PUSH2 0xB14 JUMPI PUSH2 0xB14 PUSH2 0x112F JUMP JUMPDEST SUB PUSH2 0xB7B JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x20 PUSH1 0x4 DUP3 ADD MSTORE PUSH1 0x1F PUSH1 0x24 DUP3 ADD MSTORE PUSH32 0x45434453413A20696E76616C6964207369676E6174757265206C656E67746800 PUSH1 0x44 DUP3 ADD MSTORE PUSH1 0x64 ADD PUSH2 0xAF7 JUMP JUMPDEST PUSH1 0x3 DUP2 PUSH1 0x4 DUP2 GT ISZERO PUSH2 0xB8F JUMPI PUSH2 0xB8F PUSH2 0x112F JUMP JUMPDEST SUB PUSH2 0xC1C JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x20 PUSH1 0x4 DUP3 ADD MSTORE PUSH1 0x22 PUSH1 0x24 DUP3 ADD MSTORE PUSH32 0x45434453413A20696E76616C6964207369676E6174757265202773272076616C PUSH1 0x44 DUP3 ADD MSTORE PUSH32 0x7565000000000000000000000000000000000000000000000000000000000000 PUSH1 0x64 DUP3 ADD MSTORE PUSH1 0x84 ADD PUSH2 0xAF7 JUMP JUMPDEST POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH32 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0 DUP4 GT ISZERO PUSH2 0xC56 JUMPI POP PUSH1 0x0 SWAP1 POP PUSH1 0x3 PUSH2 0xD05 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH1 0x0 DUP1 DUP3 MSTORE PUSH1 0x20 DUP3 ADD DUP1 DUP5 MSTORE DUP10 SWAP1 MSTORE PUSH1 0xFF DUP9 AND SWAP3 DUP3 ADD SWAP3 SWAP1 SWAP3 MSTORE PUSH1 0x60 DUP2 ADD DUP7 SWAP1 MSTORE PUSH1 0x80 DUP2 ADD DUP6 SWAP1 MSTORE PUSH1 0x1 SWAP1 PUSH1 0xA0 ADD PUSH1 0x20 PUSH1 0x40 MLOAD PUSH1 0x20 DUP2 SUB SWAP1 DUP1 DUP5 SUB SWAP1 DUP6 GAS STATICCALL ISZERO DUP1 ISZERO PUSH2 0xCAA JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP PUSH1 0x40 MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 ADD MLOAD SWAP2 POP POP PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND PUSH2 0xCFE JUMPI PUSH1 0x0 PUSH1 0x1 SWAP3 POP SWAP3 POP POP PUSH2 0xD05 JUMP JUMPDEST SWAP2 POP PUSH1 0x0 SWAP1 POP JUMPDEST SWAP5 POP SWAP5 SWAP3 POP POP POP JUMP JUMPDEST PUSH32 0x4E487B7100000000000000000000000000000000000000000000000000000000 PUSH1 0x0 MSTORE PUSH1 0x41 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST PUSH1 0x0 DUP3 PUSH1 0x1F DUP4 ADD SLT PUSH2 0xD4E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0xD69 JUMPI PUSH2 0xD69 PUSH2 0xD0E JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x1F DUP4 ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 DUP2 AND PUSH1 0x3F ADD AND DUP2 ADD SWAP1 DUP3 DUP3 GT DUP2 DUP4 LT OR ISZERO PUSH2 0xDAF JUMPI PUSH2 0xDAF PUSH2 0xD0E JUMP JUMPDEST DUP2 PUSH1 0x40 MSTORE DUP4 DUP2 MSTORE DUP7 PUSH1 0x20 DUP6 DUP9 ADD ADD GT ISZERO PUSH2 0xDC8 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP4 PUSH1 0x20 DUP8 ADD PUSH1 0x20 DUP4 ADD CALLDATACOPY PUSH1 0x0 PUSH1 0x20 DUP6 DUP4 ADD ADD MSTORE DUP1 SWAP5 POP POP POP POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0xDFB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP3 CALLDATALOAD SWAP2 POP PUSH1 0x20 DUP4 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xE19 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xE25 DUP6 DUP3 DUP7 ADD PUSH2 0xD3D JUMP JUMPDEST SWAP2 POP POP SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xE41 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xE58 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x3B0 DUP5 DUP3 DUP6 ADD PUSH2 0xD3D JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP1 DUP4 MSTORE DUP4 MLOAD DUP1 DUP3 DUP6 ADD MSTORE PUSH1 0x0 JUMPDEST DUP2 DUP2 LT ISZERO PUSH2 0xE91 JUMPI DUP6 DUP2 ADD DUP4 ADD MLOAD DUP6 DUP3 ADD PUSH1 0x40 ADD MSTORE DUP3 ADD PUSH2 0xE75 JUMP JUMPDEST POP PUSH1 0x0 PUSH1 0x40 DUP3 DUP7 ADD ADD MSTORE PUSH1 0x40 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 PUSH1 0x1F DUP4 ADD AND DUP6 ADD ADD SWAP3 POP POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x160 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xEE3 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0xEFC JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP3 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xF13 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xF1F DUP6 DUP3 DUP7 ADD PUSH2 0xED0 JUMP JUMPDEST SWAP6 PUSH1 0x20 SWAP5 SWAP1 SWAP5 ADD CALLDATALOAD SWAP5 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x20 DUP4 DUP6 SUB SLT ISZERO PUSH2 0xF41 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP3 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0xF59 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 DUP6 ADD SWAP2 POP DUP6 PUSH1 0x1F DUP4 ADD SLT PUSH2 0xF6D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD DUP2 DUP2 GT ISZERO PUSH2 0xF7C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP7 PUSH1 0x20 DUP3 DUP6 ADD ADD GT ISZERO PUSH2 0xF8E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x20 SWAP3 SWAP1 SWAP3 ADD SWAP7 SWAP2 SWAP6 POP SWAP1 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x60 DUP5 DUP7 SUB SLT ISZERO PUSH2 0xFB5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP4 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xFCC JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xFD8 DUP7 DUP3 DUP8 ADD PUSH2 0xED0 JUMP JUMPDEST SWAP4 POP POP PUSH1 0x20 DUP5 ADD CALLDATALOAD SWAP2 POP PUSH1 0x40 DUP5 ADD CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND DUP2 EQ PUSH2 0x1009 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 SWAP2 POP POP SWAP3 POP SWAP3 POP SWAP3 JUMP JUMPDEST PUSH32 0x4E487B7100000000000000000000000000000000000000000000000000000000 PUSH1 0x0 MSTORE PUSH1 0x32 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST PUSH1 0x0 DUP1 DUP6 DUP6 GT ISZERO PUSH2 0x1053 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP4 DUP7 GT ISZERO PUSH2 0x1060 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP POP DUP3 ADD SWAP4 SWAP2 SWAP1 SWAP3 SUB SWAP2 POP JUMP JUMPDEST DUP2 DUP4 DUP3 CALLDATACOPY PUSH1 0x0 SWAP2 ADD SWAP1 DUP2 MSTORE SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x20 DUP2 MSTORE DUP2 PUSH1 0x20 DUP3 ADD MSTORE DUP2 DUP4 PUSH1 0x40 DUP4 ADD CALLDATACOPY PUSH1 0x0 DUP2 DUP4 ADD PUSH1 0x40 SWAP1 DUP2 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0x1F SWAP1 SWAP3 ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 AND ADD ADD SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 DUP4 CALLDATALOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 DUP5 CALLDATASIZE SUB ADD DUP2 SLT PUSH2 0x10FF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP4 ADD DUP1 CALLDATALOAD SWAP2 POP PUSH8 0xFFFFFFFFFFFFFFFF DUP3 GT ISZERO PUSH2 0x111A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x20 ADD SWAP2 POP CALLDATASIZE DUP2 SWAP1 SUB DUP3 SGT ISZERO PUSH2 0xA5D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH32 0x4E487B7100000000000000000000000000000000000000000000000000000000 PUSH1 0x0 MSTORE PUSH1 0x21 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 0xDE CALLER PUSH9 0xE3F3953432149EC8AB PUSH2 0xE8DB SDIV BLOCKHASH SWAP11 CALLVALUE 0xE6 RETURN CALLCODE 0x23 0xF6 0xBC EXP KECCAK256 SMOD 0x2F LOG0 SHR RETURN PUSH5 0x736F6C6343 STOP ADDMOD ISZERO STOP CALLER ", + "sourceMap": "761:7155:70:-:0;;;1086:100;;;;;;;;;-1:-1:-1;1110:39:70;:37;:39::i;:::-;1174:4;1159:20;;761:7155;;2061:272:92;2115:20;2169:16;;;;;;;;:34;;;2164:39;2160:119;;2226:42;;-1:-1:-1;;;2226:42:92;;;;;;;;;;;2160:119;2288:13;:16;;;;;;;;;;;:38;;-1:-1:-1;;2288:38:92;2325:1;2288:38;;;2061:272::o;761:7155:70:-;;;;;;;;;;;;;;;;;;" + }, + "deployedBytecode": { + "functionDebugData": { + "@_throwError_5456": { + "entryPoint": 2660, + "id": 5456, + "parameterSlots": 1, + "returnSlots": 0 + }, + "@appStorage_27629": { + "entryPoint": null, + "id": 27629, + "parameterSlots": 0, + "returnSlots": 1 + }, + "@diamondStorage_27960": { + "entryPoint": null, + "id": 27960, + "parameterSlots": 0, + "returnSlots": 1 + }, + "@enforceSignerInitialize_27715": { + "entryPoint": 2431, + "id": 27715, + "parameterSlots": 0, + "returnSlots": 0 + }, + "@enforceSignerMigration_27770": { + "entryPoint": 2208, + "id": 27770, + "parameterSlots": 0, + "returnSlots": 0 + }, + "@facetAddress_29649": { + "entryPoint": null, + "id": 29649, + "parameterSlots": 1, + "returnSlots": 1 + }, + "@getValidateOwnerSignatureSelector_27672": { + "entryPoint": null, + "id": 27672, + "parameterSlots": 0, + "returnSlots": 1 + }, + "@initializeSigner_22393": { + "entryPoint": 1238, + "id": 22393, + "parameterSlots": 2, + "returnSlots": 1 + }, + "@isValidKeyType_22579": { + "entryPoint": 756, + "id": 22579, + "parameterSlots": 1, + "returnSlots": 1 + }, + "@isValidSignature_22612": { + "entryPoint": 582, + "id": 22612, + "parameterSlots": 2, + "returnSlots": 1 + }, + "@k1Storage_28915": { + "entryPoint": null, + "id": 28915, + "parameterSlots": 0, + "returnSlots": 1 + }, + "@owner_22555": { + "entryPoint": null, + "id": 22555, + "parameterSlots": 0, + "returnSlots": 1 + }, + "@recover_5529": { + "entryPoint": 2172, + "id": 5529, + "parameterSlots": 2, + "returnSlots": 1 + }, + "@self_22286": { + "entryPoint": null, + "id": 22286, + "parameterSlots": 0, + "returnSlots": 0 + }, + "@setSignerUninitialized_27660": { + "entryPoint": 2272, + "id": 27660, + "parameterSlots": 0, + "returnSlots": 0 + }, + "@setValidateOwnerSignatureSelector_27684": { + "entryPoint": null, + "id": 27684, + "parameterSlots": 1, + "returnSlots": 0 + }, + "@toEthSignedMessageHash_5713": { + "entryPoint": null, + "id": 5713, + "parameterSlots": 1, + "returnSlots": 1 + }, + "@tryRecover_5502": { + "entryPoint": 2591, + "id": 5502, + "parameterSlots": 2, + "returnSlots": 2 + }, + "@tryRecover_5670": { + "entryPoint": 3103, + "id": 5670, + "parameterSlots": 4, + "returnSlots": 2 + }, + "@uninitializeSigner_22455": { + "entryPoint": 952, + "id": 22455, + "parameterSlots": 0, + "returnSlots": 1 + }, + "@validateOwnerSignatureSelector_22532": { + "entryPoint": null, + "id": 22532, + "parameterSlots": 0, + "returnSlots": 1 + }, + "@validateOwnerSignature_22484": { + "entryPoint": 870, + "id": 22484, + "parameterSlots": 2, + "returnSlots": 1 + }, + "@validateSignature_22518": { + "entryPoint": 1975, + "id": 22518, + "parameterSlots": 3, + "returnSlots": 1 + }, + "abi_decode_bytes": { + "entryPoint": 3389, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "abi_decode_struct_UserOperation_calldata": { + "entryPoint": 3792, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "abi_decode_tuple_t_bytes32t_bytes_memory_ptr": { + "entryPoint": 3560, + "id": null, + "parameterSlots": 2, + "returnSlots": 2 + }, + "abi_decode_tuple_t_bytes_calldata_ptr": { + "entryPoint": 3886, + "id": null, + "parameterSlots": 2, + "returnSlots": 2 + }, + "abi_decode_tuple_t_bytes_memory_ptr": { + "entryPoint": 3631, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "abi_decode_tuple_t_struct$_UserOperation_$12474_calldata_ptrt_bytes32": { + "entryPoint": 3817, + "id": null, + "parameterSlots": 2, + "returnSlots": 2 + }, + "abi_decode_tuple_t_struct$_UserOperation_$12474_calldata_ptrt_bytes32t_address": { + "entryPoint": 4000, + "id": null, + "parameterSlots": 2, + "returnSlots": 3 + }, + "abi_encode_tuple_packed_t_address__to_t_address__nonPadded_inplace_fromStack_reversed": { + "entryPoint": null, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "abi_encode_tuple_packed_t_bytes_calldata_ptr_slice__to_t_bytes_memory_ptr__nonPadded_inplace_fromStack_reversed": { + "entryPoint": 4205, + "id": null, + "parameterSlots": 3, + "returnSlots": 1 + }, + "abi_encode_tuple_t_address__to_t_address__fromStack_reversed": { + "entryPoint": null, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "abi_encode_tuple_t_bool__to_t_bool__fromStack_reversed": { + "entryPoint": null, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "abi_encode_tuple_t_bytes32_t_uint8_t_bytes32_t_bytes32__to_t_bytes32_t_uint8_t_bytes32_t_bytes32__fromStack_reversed": { + "entryPoint": null, + "id": null, + "parameterSlots": 5, + "returnSlots": 1 + }, + "abi_encode_tuple_t_bytes4__to_t_bytes4__fromStack_reversed": { + "entryPoint": null, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "abi_encode_tuple_t_bytes_calldata_ptr__to_t_bytes_memory_ptr__fromStack_reversed": { + "entryPoint": 4221, + "id": null, + "parameterSlots": 3, + "returnSlots": 1 + }, + "abi_encode_tuple_t_bytes_memory_ptr__to_t_bytes_memory_ptr__fromStack_reversed": { + "entryPoint": 3684, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "abi_encode_tuple_t_stringliteral_00043f6bf76368aa97c21698e9b9d4779e31902453daccf3525ddfb36e53e2be__to_t_string_memory_ptr__fromStack_reversed": { + "entryPoint": null, + "id": null, + "parameterSlots": 1, + "returnSlots": 1 + }, + "abi_encode_tuple_t_stringliteral_1669ff3ba3cdf64474e1193492d05b8434e29b0b495e60095eb5f5c8ec14ce77__to_t_string_memory_ptr__fromStack_reversed": { + "entryPoint": null, + "id": null, + "parameterSlots": 1, + "returnSlots": 1 + }, + "abi_encode_tuple_t_stringliteral_520d1f787dbcafbbfc007fd2c4ecf3d2711ec587f3ee9a1215c0b646c3e530bd__to_t_string_memory_ptr__fromStack_reversed": { + "entryPoint": null, + "id": null, + "parameterSlots": 1, + "returnSlots": 1 + }, + "abi_encode_tuple_t_uint256__to_t_uint256__fromStack_reversed": { + "entryPoint": null, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "access_calldata_tail_t_bytes_calldata_ptr": { + "entryPoint": 4298, + "id": null, + "parameterSlots": 2, + "returnSlots": 2 + }, + "calldata_array_index_range_access_t_bytes_calldata_ptr": { + "entryPoint": 4163, + "id": null, + "parameterSlots": 4, + "returnSlots": 2 + }, + "panic_error_0x21": { + "entryPoint": 4399, + "id": null, + "parameterSlots": 0, + "returnSlots": 0 + }, + "panic_error_0x32": { + "entryPoint": 4116, + "id": null, + "parameterSlots": 0, + "returnSlots": 0 + }, + "panic_error_0x41": { + "entryPoint": 3342, + "id": null, + "parameterSlots": 0, + "returnSlots": 0 + } + }, + "generatedSources": [ + { + "ast": { + "nativeSrc": "0:8833:109", + "nodeType": "YulBlock", + "src": "0:8833:109", + "statements": [ + { + "nativeSrc": "6:3:109", + "nodeType": "YulBlock", + "src": "6:3:109", + "statements": [] + }, + { + "body": { + "nativeSrc": "46:152:109", + "nodeType": "YulBlock", + "src": "46:152:109", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nativeSrc": "63:1:109", + "nodeType": "YulLiteral", + "src": "63:1:109", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nativeSrc": "66:77:109", + "nodeType": "YulLiteral", + "src": "66:77:109", + "type": "", + "value": "35408467139433450592217433187231851964531694900788300625387963629091585785856" + } + ], + "functionName": { + "name": "mstore", + "nativeSrc": "56:6:109", + "nodeType": "YulIdentifier", + "src": "56:6:109" + }, + "nativeSrc": "56:88:109", + "nodeType": "YulFunctionCall", + "src": "56:88:109" + }, + "nativeSrc": "56:88:109", + "nodeType": "YulExpressionStatement", + "src": "56:88:109" + }, + { + "expression": { + "arguments": [ + { + "kind": "number", + "nativeSrc": "160:1:109", + "nodeType": "YulLiteral", + "src": "160:1:109", + "type": "", + "value": "4" + }, + { + "kind": "number", + "nativeSrc": "163:4:109", + "nodeType": "YulLiteral", + "src": "163:4:109", + "type": "", + "value": "0x41" + } + ], + "functionName": { + "name": "mstore", + "nativeSrc": "153:6:109", + "nodeType": "YulIdentifier", + "src": "153:6:109" + }, + "nativeSrc": "153:15:109", + "nodeType": "YulFunctionCall", + "src": "153:15:109" + }, + "nativeSrc": "153:15:109", + "nodeType": "YulExpressionStatement", + "src": "153:15:109" + }, + { + "expression": { + "arguments": [ + { + "kind": "number", + "nativeSrc": "184:1:109", + "nodeType": "YulLiteral", + "src": "184:1:109", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nativeSrc": "187:4:109", + "nodeType": "YulLiteral", + "src": "187:4:109", + "type": "", + "value": "0x24" + } + ], + "functionName": { + "name": "revert", + "nativeSrc": "177:6:109", + "nodeType": "YulIdentifier", + "src": "177:6:109" + }, + "nativeSrc": "177:15:109", + "nodeType": "YulFunctionCall", + "src": "177:15:109" + }, + "nativeSrc": "177:15:109", + "nodeType": "YulExpressionStatement", + "src": "177:15:109" + } + ] + }, + "name": "panic_error_0x41", + "nativeSrc": "14:184:109", + "nodeType": "YulFunctionDefinition", + "src": "14:184:109" + }, + { + "body": { + "nativeSrc": "255:725:109", + "nodeType": "YulBlock", + "src": "255:725:109", + "statements": [ + { + "body": { + "nativeSrc": "304:16:109", + "nodeType": "YulBlock", + "src": "304:16:109", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nativeSrc": "313:1:109", + "nodeType": "YulLiteral", + "src": "313:1:109", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nativeSrc": "316:1:109", + "nodeType": "YulLiteral", + "src": "316:1:109", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nativeSrc": "306:6:109", + "nodeType": "YulIdentifier", + "src": "306:6:109" + }, + "nativeSrc": "306:12:109", + "nodeType": "YulFunctionCall", + "src": "306:12:109" + }, + "nativeSrc": "306:12:109", + "nodeType": "YulExpressionStatement", + "src": "306:12:109" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "offset", + "nativeSrc": "283:6:109", + "nodeType": "YulIdentifier", + "src": "283:6:109" + }, + { + "kind": "number", + "nativeSrc": "291:4:109", + "nodeType": "YulLiteral", + "src": "291:4:109", + "type": "", + "value": "0x1f" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "279:3:109", + "nodeType": "YulIdentifier", + "src": "279:3:109" + }, + "nativeSrc": "279:17:109", + "nodeType": "YulFunctionCall", + "src": "279:17:109" + }, + { + "name": "end", + "nativeSrc": "298:3:109", + "nodeType": "YulIdentifier", + "src": "298:3:109" + } + ], + "functionName": { + "name": "slt", + "nativeSrc": "275:3:109", + "nodeType": "YulIdentifier", + "src": "275:3:109" + }, + "nativeSrc": "275:27:109", + "nodeType": "YulFunctionCall", + "src": "275:27:109" + } + ], + "functionName": { + "name": "iszero", + "nativeSrc": "268:6:109", + "nodeType": "YulIdentifier", + "src": "268:6:109" + }, + "nativeSrc": "268:35:109", + "nodeType": "YulFunctionCall", + "src": "268:35:109" + }, + "nativeSrc": "265:55:109", + "nodeType": "YulIf", + "src": "265:55:109" + }, + { + "nativeSrc": "329:30:109", + "nodeType": "YulVariableDeclaration", + "src": "329:30:109", + "value": { + "arguments": [ + { + "name": "offset", + "nativeSrc": "352:6:109", + "nodeType": "YulIdentifier", + "src": "352:6:109" + } + ], + "functionName": { + "name": "calldataload", + "nativeSrc": "339:12:109", + "nodeType": "YulIdentifier", + "src": "339:12:109" + }, + "nativeSrc": "339:20:109", + "nodeType": "YulFunctionCall", + "src": "339:20:109" + }, + "variables": [ + { + "name": "_1", + "nativeSrc": "333:2:109", + "nodeType": "YulTypedName", + "src": "333:2:109", + "type": "" + } + ] + }, + { + "nativeSrc": "368:28:109", + "nodeType": "YulVariableDeclaration", + "src": "368:28:109", + "value": { + "kind": "number", + "nativeSrc": "378:18:109", + "nodeType": "YulLiteral", + "src": "378:18:109", + "type": "", + "value": "0xffffffffffffffff" + }, + "variables": [ + { + "name": "_2", + "nativeSrc": "372:2:109", + "nodeType": "YulTypedName", + "src": "372:2:109", + "type": "" + } + ] + }, + { + "body": { + "nativeSrc": "419:22:109", + "nodeType": "YulBlock", + "src": "419:22:109", + "statements": [ + { + "expression": { + "arguments": [], + "functionName": { + "name": "panic_error_0x41", + "nativeSrc": "421:16:109", + "nodeType": "YulIdentifier", + "src": "421:16:109" + }, + "nativeSrc": "421:18:109", + "nodeType": "YulFunctionCall", + "src": "421:18:109" + }, + "nativeSrc": "421:18:109", + "nodeType": "YulExpressionStatement", + "src": "421:18:109" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "_1", + "nativeSrc": "411:2:109", + "nodeType": "YulIdentifier", + "src": "411:2:109" + }, + { + "name": "_2", + "nativeSrc": "415:2:109", + "nodeType": "YulIdentifier", + "src": "415:2:109" + } + ], + "functionName": { + "name": "gt", + "nativeSrc": "408:2:109", + "nodeType": "YulIdentifier", + "src": "408:2:109" + }, + "nativeSrc": "408:10:109", + "nodeType": "YulFunctionCall", + "src": "408:10:109" + }, + "nativeSrc": "405:36:109", + "nodeType": "YulIf", + "src": "405:36:109" + }, + { + "nativeSrc": "450:76:109", + "nodeType": "YulVariableDeclaration", + "src": "450:76:109", + "value": { + "kind": "number", + "nativeSrc": "460:66:109", + "nodeType": "YulLiteral", + "src": "460:66:109", + "type": "", + "value": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0" + }, + "variables": [ + { + "name": "_3", + "nativeSrc": "454:2:109", + "nodeType": "YulTypedName", + "src": "454:2:109", + "type": "" + } + ] + }, + { + "nativeSrc": "535:23:109", + "nodeType": "YulVariableDeclaration", + "src": "535:23:109", + "value": { + "arguments": [ + { + "kind": "number", + "nativeSrc": "555:2:109", + "nodeType": "YulLiteral", + "src": "555:2:109", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "mload", + "nativeSrc": "549:5:109", + "nodeType": "YulIdentifier", + "src": "549:5:109" + }, + "nativeSrc": "549:9:109", + "nodeType": "YulFunctionCall", + "src": "549:9:109" + }, + "variables": [ + { + "name": "memPtr", + "nativeSrc": "539:6:109", + "nodeType": "YulTypedName", + "src": "539:6:109", + "type": "" + } + ] + }, + { + "nativeSrc": "567:71:109", + "nodeType": "YulVariableDeclaration", + "src": "567:71:109", + "value": { + "arguments": [ + { + "name": "memPtr", + "nativeSrc": "589:6:109", + "nodeType": "YulIdentifier", + "src": "589:6:109" + }, + { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "_1", + "nativeSrc": "613:2:109", + "nodeType": "YulIdentifier", + "src": "613:2:109" + }, + { + "kind": "number", + "nativeSrc": "617:4:109", + "nodeType": "YulLiteral", + "src": "617:4:109", + "type": "", + "value": "0x1f" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "609:3:109", + "nodeType": "YulIdentifier", + "src": "609:3:109" + }, + "nativeSrc": "609:13:109", + "nodeType": "YulFunctionCall", + "src": "609:13:109" + }, + { + "name": "_3", + "nativeSrc": "624:2:109", + "nodeType": "YulIdentifier", + "src": "624:2:109" + } + ], + "functionName": { + "name": "and", + "nativeSrc": "605:3:109", + "nodeType": "YulIdentifier", + "src": "605:3:109" + }, + "nativeSrc": "605:22:109", + "nodeType": "YulFunctionCall", + "src": "605:22:109" + }, + { + "kind": "number", + "nativeSrc": "629:2:109", + "nodeType": "YulLiteral", + "src": "629:2:109", + "type": "", + "value": "63" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "601:3:109", + "nodeType": "YulIdentifier", + "src": "601:3:109" + }, + "nativeSrc": "601:31:109", + "nodeType": "YulFunctionCall", + "src": "601:31:109" + }, + { + "name": "_3", + "nativeSrc": "634:2:109", + "nodeType": "YulIdentifier", + "src": "634:2:109" + } + ], + "functionName": { + "name": "and", + "nativeSrc": "597:3:109", + "nodeType": "YulIdentifier", + "src": "597:3:109" + }, + "nativeSrc": "597:40:109", + "nodeType": "YulFunctionCall", + "src": "597:40:109" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "585:3:109", + "nodeType": "YulIdentifier", + "src": "585:3:109" + }, + "nativeSrc": "585:53:109", + "nodeType": "YulFunctionCall", + "src": "585:53:109" + }, + "variables": [ + { + "name": "newFreePtr", + "nativeSrc": "571:10:109", + "nodeType": "YulTypedName", + "src": "571:10:109", + "type": "" + } + ] + }, + { + "body": { + "nativeSrc": "697:22:109", + "nodeType": "YulBlock", + "src": "697:22:109", + "statements": [ + { + "expression": { + "arguments": [], + "functionName": { + "name": "panic_error_0x41", + "nativeSrc": "699:16:109", + "nodeType": "YulIdentifier", + "src": "699:16:109" + }, + "nativeSrc": "699:18:109", + "nodeType": "YulFunctionCall", + "src": "699:18:109" + }, + "nativeSrc": "699:18:109", + "nodeType": "YulExpressionStatement", + "src": "699:18:109" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "newFreePtr", + "nativeSrc": "656:10:109", + "nodeType": "YulIdentifier", + "src": "656:10:109" + }, + { + "name": "_2", + "nativeSrc": "668:2:109", + "nodeType": "YulIdentifier", + "src": "668:2:109" + } + ], + "functionName": { + "name": "gt", + "nativeSrc": "653:2:109", + "nodeType": "YulIdentifier", + "src": "653:2:109" + }, + "nativeSrc": "653:18:109", + "nodeType": "YulFunctionCall", + "src": "653:18:109" + }, + { + "arguments": [ + { + "name": "newFreePtr", + "nativeSrc": "676:10:109", + "nodeType": "YulIdentifier", + "src": "676:10:109" + }, + { + "name": "memPtr", + "nativeSrc": "688:6:109", + "nodeType": "YulIdentifier", + "src": "688:6:109" + } + ], + "functionName": { + "name": "lt", + "nativeSrc": "673:2:109", + "nodeType": "YulIdentifier", + "src": "673:2:109" + }, + "nativeSrc": "673:22:109", + "nodeType": "YulFunctionCall", + "src": "673:22:109" + } + ], + "functionName": { + "name": "or", + "nativeSrc": "650:2:109", + "nodeType": "YulIdentifier", + "src": "650:2:109" + }, + "nativeSrc": "650:46:109", + "nodeType": "YulFunctionCall", + "src": "650:46:109" + }, + "nativeSrc": "647:72:109", + "nodeType": "YulIf", + "src": "647:72:109" + }, + { + "expression": { + "arguments": [ + { + "kind": "number", + "nativeSrc": "735:2:109", + "nodeType": "YulLiteral", + "src": "735:2:109", + "type": "", + "value": "64" + }, + { + "name": "newFreePtr", + "nativeSrc": "739:10:109", + "nodeType": "YulIdentifier", + "src": "739:10:109" + } + ], + "functionName": { + "name": "mstore", + "nativeSrc": "728:6:109", + "nodeType": "YulIdentifier", + "src": "728:6:109" + }, + "nativeSrc": "728:22:109", + "nodeType": "YulFunctionCall", + "src": "728:22:109" + }, + "nativeSrc": "728:22:109", + "nodeType": "YulExpressionStatement", + "src": "728:22:109" + }, + { + "expression": { + "arguments": [ + { + "name": "memPtr", + "nativeSrc": "766:6:109", + "nodeType": "YulIdentifier", + "src": "766:6:109" + }, + { + "name": "_1", + "nativeSrc": "774:2:109", + "nodeType": "YulIdentifier", + "src": "774:2:109" + } + ], + "functionName": { + "name": "mstore", + "nativeSrc": "759:6:109", + "nodeType": "YulIdentifier", + "src": "759:6:109" + }, + "nativeSrc": "759:18:109", + "nodeType": "YulFunctionCall", + "src": "759:18:109" + }, + "nativeSrc": "759:18:109", + "nodeType": "YulExpressionStatement", + "src": "759:18:109" + }, + { + "body": { + "nativeSrc": "825:16:109", + "nodeType": "YulBlock", + "src": "825:16:109", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nativeSrc": "834:1:109", + "nodeType": "YulLiteral", + "src": "834:1:109", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nativeSrc": "837:1:109", + "nodeType": "YulLiteral", + "src": "837:1:109", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nativeSrc": "827:6:109", + "nodeType": "YulIdentifier", + "src": "827:6:109" + }, + "nativeSrc": "827:12:109", + "nodeType": "YulFunctionCall", + "src": "827:12:109" + }, + "nativeSrc": "827:12:109", + "nodeType": "YulExpressionStatement", + "src": "827:12:109" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "offset", + "nativeSrc": "800:6:109", + "nodeType": "YulIdentifier", + "src": "800:6:109" + }, + { + "name": "_1", + "nativeSrc": "808:2:109", + "nodeType": "YulIdentifier", + "src": "808:2:109" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "796:3:109", + "nodeType": "YulIdentifier", + "src": "796:3:109" + }, + "nativeSrc": "796:15:109", + "nodeType": "YulFunctionCall", + "src": "796:15:109" + }, + { + "kind": "number", + "nativeSrc": "813:4:109", + "nodeType": "YulLiteral", + "src": "813:4:109", + "type": "", + "value": "0x20" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "792:3:109", + "nodeType": "YulIdentifier", + "src": "792:3:109" + }, + "nativeSrc": "792:26:109", + "nodeType": "YulFunctionCall", + "src": "792:26:109" + }, + { + "name": "end", + "nativeSrc": "820:3:109", + "nodeType": "YulIdentifier", + "src": "820:3:109" + } + ], + "functionName": { + "name": "gt", + "nativeSrc": "789:2:109", + "nodeType": "YulIdentifier", + "src": "789:2:109" + }, + "nativeSrc": "789:35:109", + "nodeType": "YulFunctionCall", + "src": "789:35:109" + }, + "nativeSrc": "786:55:109", + "nodeType": "YulIf", + "src": "786:55:109" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "memPtr", + "nativeSrc": "867:6:109", + "nodeType": "YulIdentifier", + "src": "867:6:109" + }, + { + "kind": "number", + "nativeSrc": "875:4:109", + "nodeType": "YulLiteral", + "src": "875:4:109", + "type": "", + "value": "0x20" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "863:3:109", + "nodeType": "YulIdentifier", + "src": "863:3:109" + }, + "nativeSrc": "863:17:109", + "nodeType": "YulFunctionCall", + "src": "863:17:109" + }, + { + "arguments": [ + { + "name": "offset", + "nativeSrc": "886:6:109", + "nodeType": "YulIdentifier", + "src": "886:6:109" + }, + { + "kind": "number", + "nativeSrc": "894:4:109", + "nodeType": "YulLiteral", + "src": "894:4:109", + "type": "", + "value": "0x20" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "882:3:109", + "nodeType": "YulIdentifier", + "src": "882:3:109" + }, + "nativeSrc": "882:17:109", + "nodeType": "YulFunctionCall", + "src": "882:17:109" + }, + { + "name": "_1", + "nativeSrc": "901:2:109", + "nodeType": "YulIdentifier", + "src": "901:2:109" + } + ], + "functionName": { + "name": "calldatacopy", + "nativeSrc": "850:12:109", + "nodeType": "YulIdentifier", + "src": "850:12:109" + }, + "nativeSrc": "850:54:109", + "nodeType": "YulFunctionCall", + "src": "850:54:109" + }, + "nativeSrc": "850:54:109", + "nodeType": "YulExpressionStatement", + "src": "850:54:109" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "memPtr", + "nativeSrc": "928:6:109", + "nodeType": "YulIdentifier", + "src": "928:6:109" + }, + { + "name": "_1", + "nativeSrc": "936:2:109", + "nodeType": "YulIdentifier", + "src": "936:2:109" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "924:3:109", + "nodeType": "YulIdentifier", + "src": "924:3:109" + }, + "nativeSrc": "924:15:109", + "nodeType": "YulFunctionCall", + "src": "924:15:109" + }, + { + "kind": "number", + "nativeSrc": "941:4:109", + "nodeType": "YulLiteral", + "src": "941:4:109", + "type": "", + "value": "0x20" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "920:3:109", + "nodeType": "YulIdentifier", + "src": "920:3:109" + }, + "nativeSrc": "920:26:109", + "nodeType": "YulFunctionCall", + "src": "920:26:109" + }, + { + "kind": "number", + "nativeSrc": "948:1:109", + "nodeType": "YulLiteral", + "src": "948:1:109", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "mstore", + "nativeSrc": "913:6:109", + "nodeType": "YulIdentifier", + "src": "913:6:109" + }, + "nativeSrc": "913:37:109", + "nodeType": "YulFunctionCall", + "src": "913:37:109" + }, + "nativeSrc": "913:37:109", + "nodeType": "YulExpressionStatement", + "src": "913:37:109" + }, + { + "nativeSrc": "959:15:109", + "nodeType": "YulAssignment", + "src": "959:15:109", + "value": { + "name": "memPtr", + "nativeSrc": "968:6:109", + "nodeType": "YulIdentifier", + "src": "968:6:109" + }, + "variableNames": [ + { + "name": "array", + "nativeSrc": "959:5:109", + "nodeType": "YulIdentifier", + "src": "959:5:109" + } + ] + } + ] + }, + "name": "abi_decode_bytes", + "nativeSrc": "203:777:109", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "offset", + "nativeSrc": "229:6:109", + "nodeType": "YulTypedName", + "src": "229:6:109", + "type": "" + }, + { + "name": "end", + "nativeSrc": "237:3:109", + "nodeType": "YulTypedName", + "src": "237:3:109", + "type": "" + } + ], + "returnVariables": [ + { + "name": "array", + "nativeSrc": "245:5:109", + "nodeType": "YulTypedName", + "src": "245:5:109", + "type": "" + } + ], + "src": "203:777:109" + }, + { + "body": { + "nativeSrc": "1081:292:109", + "nodeType": "YulBlock", + "src": "1081:292:109", + "statements": [ + { + "body": { + "nativeSrc": "1127:16:109", + "nodeType": "YulBlock", + "src": "1127:16:109", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nativeSrc": "1136:1:109", + "nodeType": "YulLiteral", + "src": "1136:1:109", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nativeSrc": "1139:1:109", + "nodeType": "YulLiteral", + "src": "1139:1:109", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nativeSrc": "1129:6:109", + "nodeType": "YulIdentifier", + "src": "1129:6:109" + }, + "nativeSrc": "1129:12:109", + "nodeType": "YulFunctionCall", + "src": "1129:12:109" + }, + "nativeSrc": "1129:12:109", + "nodeType": "YulExpressionStatement", + "src": "1129:12:109" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nativeSrc": "1102:7:109", + "nodeType": "YulIdentifier", + "src": "1102:7:109" + }, + { + "name": "headStart", + "nativeSrc": "1111:9:109", + "nodeType": "YulIdentifier", + "src": "1111:9:109" + } + ], + "functionName": { + "name": "sub", + "nativeSrc": "1098:3:109", + "nodeType": "YulIdentifier", + "src": "1098:3:109" + }, + "nativeSrc": "1098:23:109", + "nodeType": "YulFunctionCall", + "src": "1098:23:109" + }, + { + "kind": "number", + "nativeSrc": "1123:2:109", + "nodeType": "YulLiteral", + "src": "1123:2:109", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "slt", + "nativeSrc": "1094:3:109", + "nodeType": "YulIdentifier", + "src": "1094:3:109" + }, + "nativeSrc": "1094:32:109", + "nodeType": "YulFunctionCall", + "src": "1094:32:109" + }, + "nativeSrc": "1091:52:109", + "nodeType": "YulIf", + "src": "1091:52:109" + }, + { + "nativeSrc": "1152:33:109", + "nodeType": "YulAssignment", + "src": "1152:33:109", + "value": { + "arguments": [ + { + "name": "headStart", + "nativeSrc": "1175:9:109", + "nodeType": "YulIdentifier", + "src": "1175:9:109" + } + ], + "functionName": { + "name": "calldataload", + "nativeSrc": "1162:12:109", + "nodeType": "YulIdentifier", + "src": "1162:12:109" + }, + "nativeSrc": "1162:23:109", + "nodeType": "YulFunctionCall", + "src": "1162:23:109" + }, + "variableNames": [ + { + "name": "value0", + "nativeSrc": "1152:6:109", + "nodeType": "YulIdentifier", + "src": "1152:6:109" + } + ] + }, + { + "nativeSrc": "1194:46:109", + "nodeType": "YulVariableDeclaration", + "src": "1194:46:109", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nativeSrc": "1225:9:109", + "nodeType": "YulIdentifier", + "src": "1225:9:109" + }, + { + "kind": "number", + "nativeSrc": "1236:2:109", + "nodeType": "YulLiteral", + "src": "1236:2:109", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "1221:3:109", + "nodeType": "YulIdentifier", + "src": "1221:3:109" + }, + "nativeSrc": "1221:18:109", + "nodeType": "YulFunctionCall", + "src": "1221:18:109" + } + ], + "functionName": { + "name": "calldataload", + "nativeSrc": "1208:12:109", + "nodeType": "YulIdentifier", + "src": "1208:12:109" + }, + "nativeSrc": "1208:32:109", + "nodeType": "YulFunctionCall", + "src": "1208:32:109" + }, + "variables": [ + { + "name": "offset", + "nativeSrc": "1198:6:109", + "nodeType": "YulTypedName", + "src": "1198:6:109", + "type": "" + } + ] + }, + { + "body": { + "nativeSrc": "1283:16:109", + "nodeType": "YulBlock", + "src": "1283:16:109", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nativeSrc": "1292:1:109", + "nodeType": "YulLiteral", + "src": "1292:1:109", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nativeSrc": "1295:1:109", + "nodeType": "YulLiteral", + "src": "1295:1:109", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nativeSrc": "1285:6:109", + "nodeType": "YulIdentifier", + "src": "1285:6:109" + }, + "nativeSrc": "1285:12:109", + "nodeType": "YulFunctionCall", + "src": "1285:12:109" + }, + "nativeSrc": "1285:12:109", + "nodeType": "YulExpressionStatement", + "src": "1285:12:109" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "offset", + "nativeSrc": "1255:6:109", + "nodeType": "YulIdentifier", + "src": "1255:6:109" + }, + { + "kind": "number", + "nativeSrc": "1263:18:109", + "nodeType": "YulLiteral", + "src": "1263:18:109", + "type": "", + "value": "0xffffffffffffffff" + } + ], + "functionName": { + "name": "gt", + "nativeSrc": "1252:2:109", + "nodeType": "YulIdentifier", + "src": "1252:2:109" + }, + "nativeSrc": "1252:30:109", + "nodeType": "YulFunctionCall", + "src": "1252:30:109" + }, + "nativeSrc": "1249:50:109", + "nodeType": "YulIf", + "src": "1249:50:109" + }, + { + "nativeSrc": "1308:59:109", + "nodeType": "YulAssignment", + "src": "1308:59:109", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nativeSrc": "1339:9:109", + "nodeType": "YulIdentifier", + "src": "1339:9:109" + }, + { + "name": "offset", + "nativeSrc": "1350:6:109", + "nodeType": "YulIdentifier", + "src": "1350:6:109" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "1335:3:109", + "nodeType": "YulIdentifier", + "src": "1335:3:109" + }, + "nativeSrc": "1335:22:109", + "nodeType": "YulFunctionCall", + "src": "1335:22:109" + }, + { + "name": "dataEnd", + "nativeSrc": "1359:7:109", + "nodeType": "YulIdentifier", + "src": "1359:7:109" + } + ], + "functionName": { + "name": "abi_decode_bytes", + "nativeSrc": "1318:16:109", + "nodeType": "YulIdentifier", + "src": "1318:16:109" + }, + "nativeSrc": "1318:49:109", + "nodeType": "YulFunctionCall", + "src": "1318:49:109" + }, + "variableNames": [ + { + "name": "value1", + "nativeSrc": "1308:6:109", + "nodeType": "YulIdentifier", + "src": "1308:6:109" + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_bytes32t_bytes_memory_ptr", + "nativeSrc": "985:388:109", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nativeSrc": "1039:9:109", + "nodeType": "YulTypedName", + "src": "1039:9:109", + "type": "" + }, + { + "name": "dataEnd", + "nativeSrc": "1050:7:109", + "nodeType": "YulTypedName", + "src": "1050:7:109", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nativeSrc": "1062:6:109", + "nodeType": "YulTypedName", + "src": "1062:6:109", + "type": "" + }, + { + "name": "value1", + "nativeSrc": "1070:6:109", + "nodeType": "YulTypedName", + "src": "1070:6:109", + "type": "" + } + ], + "src": "985:388:109" + }, + { + "body": { + "nativeSrc": "1477:149:109", + "nodeType": "YulBlock", + "src": "1477:149:109", + "statements": [ + { + "nativeSrc": "1487:26:109", + "nodeType": "YulAssignment", + "src": "1487:26:109", + "value": { + "arguments": [ + { + "name": "headStart", + "nativeSrc": "1499:9:109", + "nodeType": "YulIdentifier", + "src": "1499:9:109" + }, + { + "kind": "number", + "nativeSrc": "1510:2:109", + "nodeType": "YulLiteral", + "src": "1510:2:109", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "1495:3:109", + "nodeType": "YulIdentifier", + "src": "1495:3:109" + }, + "nativeSrc": "1495:18:109", + "nodeType": "YulFunctionCall", + "src": "1495:18:109" + }, + "variableNames": [ + { + "name": "tail", + "nativeSrc": "1487:4:109", + "nodeType": "YulIdentifier", + "src": "1487:4:109" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nativeSrc": "1529:9:109", + "nodeType": "YulIdentifier", + "src": "1529:9:109" + }, + { + "arguments": [ + { + "name": "value0", + "nativeSrc": "1544:6:109", + "nodeType": "YulIdentifier", + "src": "1544:6:109" + }, + { + "kind": "number", + "nativeSrc": "1552:66:109", + "nodeType": "YulLiteral", + "src": "1552:66:109", + "type": "", + "value": "0xffffffff00000000000000000000000000000000000000000000000000000000" + } + ], + "functionName": { + "name": "and", + "nativeSrc": "1540:3:109", + "nodeType": "YulIdentifier", + "src": "1540:3:109" + }, + "nativeSrc": "1540:79:109", + "nodeType": "YulFunctionCall", + "src": "1540:79:109" + } + ], + "functionName": { + "name": "mstore", + "nativeSrc": "1522:6:109", + "nodeType": "YulIdentifier", + "src": "1522:6:109" + }, + "nativeSrc": "1522:98:109", + "nodeType": "YulFunctionCall", + "src": "1522:98:109" + }, + "nativeSrc": "1522:98:109", + "nodeType": "YulExpressionStatement", + "src": "1522:98:109" + } + ] + }, + "name": "abi_encode_tuple_t_bytes4__to_t_bytes4__fromStack_reversed", + "nativeSrc": "1378:248:109", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nativeSrc": "1446:9:109", + "nodeType": "YulTypedName", + "src": "1446:9:109", + "type": "" + }, + { + "name": "value0", + "nativeSrc": "1457:6:109", + "nodeType": "YulTypedName", + "src": "1457:6:109", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nativeSrc": "1468:4:109", + "nodeType": "YulTypedName", + "src": "1468:4:109", + "type": "" + } + ], + "src": "1378:248:109" + }, + { + "body": { + "nativeSrc": "1710:241:109", + "nodeType": "YulBlock", + "src": "1710:241:109", + "statements": [ + { + "body": { + "nativeSrc": "1756:16:109", + "nodeType": "YulBlock", + "src": "1756:16:109", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nativeSrc": "1765:1:109", + "nodeType": "YulLiteral", + "src": "1765:1:109", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nativeSrc": "1768:1:109", + "nodeType": "YulLiteral", + "src": "1768:1:109", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nativeSrc": "1758:6:109", + "nodeType": "YulIdentifier", + "src": "1758:6:109" + }, + "nativeSrc": "1758:12:109", + "nodeType": "YulFunctionCall", + "src": "1758:12:109" + }, + "nativeSrc": "1758:12:109", + "nodeType": "YulExpressionStatement", + "src": "1758:12:109" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nativeSrc": "1731:7:109", + "nodeType": "YulIdentifier", + "src": "1731:7:109" + }, + { + "name": "headStart", + "nativeSrc": "1740:9:109", + "nodeType": "YulIdentifier", + "src": "1740:9:109" + } + ], + "functionName": { + "name": "sub", + "nativeSrc": "1727:3:109", + "nodeType": "YulIdentifier", + "src": "1727:3:109" + }, + "nativeSrc": "1727:23:109", + "nodeType": "YulFunctionCall", + "src": "1727:23:109" + }, + { + "kind": "number", + "nativeSrc": "1752:2:109", + "nodeType": "YulLiteral", + "src": "1752:2:109", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "slt", + "nativeSrc": "1723:3:109", + "nodeType": "YulIdentifier", + "src": "1723:3:109" + }, + "nativeSrc": "1723:32:109", + "nodeType": "YulFunctionCall", + "src": "1723:32:109" + }, + "nativeSrc": "1720:52:109", + "nodeType": "YulIf", + "src": "1720:52:109" + }, + { + "nativeSrc": "1781:37:109", + "nodeType": "YulVariableDeclaration", + "src": "1781:37:109", + "value": { + "arguments": [ + { + "name": "headStart", + "nativeSrc": "1808:9:109", + "nodeType": "YulIdentifier", + "src": "1808:9:109" + } + ], + "functionName": { + "name": "calldataload", + "nativeSrc": "1795:12:109", + "nodeType": "YulIdentifier", + "src": "1795:12:109" + }, + "nativeSrc": "1795:23:109", + "nodeType": "YulFunctionCall", + "src": "1795:23:109" + }, + "variables": [ + { + "name": "offset", + "nativeSrc": "1785:6:109", + "nodeType": "YulTypedName", + "src": "1785:6:109", + "type": "" + } + ] + }, + { + "body": { + "nativeSrc": "1861:16:109", + "nodeType": "YulBlock", + "src": "1861:16:109", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nativeSrc": "1870:1:109", + "nodeType": "YulLiteral", + "src": "1870:1:109", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nativeSrc": "1873:1:109", + "nodeType": "YulLiteral", + "src": "1873:1:109", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nativeSrc": "1863:6:109", + "nodeType": "YulIdentifier", + "src": "1863:6:109" + }, + "nativeSrc": "1863:12:109", + "nodeType": "YulFunctionCall", + "src": "1863:12:109" + }, + "nativeSrc": "1863:12:109", + "nodeType": "YulExpressionStatement", + "src": "1863:12:109" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "offset", + "nativeSrc": "1833:6:109", + "nodeType": "YulIdentifier", + "src": "1833:6:109" + }, + { + "kind": "number", + "nativeSrc": "1841:18:109", + "nodeType": "YulLiteral", + "src": "1841:18:109", + "type": "", + "value": "0xffffffffffffffff" + } + ], + "functionName": { + "name": "gt", + "nativeSrc": "1830:2:109", + "nodeType": "YulIdentifier", + "src": "1830:2:109" + }, + "nativeSrc": "1830:30:109", + "nodeType": "YulFunctionCall", + "src": "1830:30:109" + }, + "nativeSrc": "1827:50:109", + "nodeType": "YulIf", + "src": "1827:50:109" + }, + { + "nativeSrc": "1886:59:109", + "nodeType": "YulAssignment", + "src": "1886:59:109", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nativeSrc": "1917:9:109", + "nodeType": "YulIdentifier", + "src": "1917:9:109" + }, + { + "name": "offset", + "nativeSrc": "1928:6:109", + "nodeType": "YulIdentifier", + "src": "1928:6:109" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "1913:3:109", + "nodeType": "YulIdentifier", + "src": "1913:3:109" + }, + "nativeSrc": "1913:22:109", + "nodeType": "YulFunctionCall", + "src": "1913:22:109" + }, + { + "name": "dataEnd", + "nativeSrc": "1937:7:109", + "nodeType": "YulIdentifier", + "src": "1937:7:109" + } + ], + "functionName": { + "name": "abi_decode_bytes", + "nativeSrc": "1896:16:109", + "nodeType": "YulIdentifier", + "src": "1896:16:109" + }, + "nativeSrc": "1896:49:109", + "nodeType": "YulFunctionCall", + "src": "1896:49:109" + }, + "variableNames": [ + { + "name": "value0", + "nativeSrc": "1886:6:109", + "nodeType": "YulIdentifier", + "src": "1886:6:109" + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_bytes_memory_ptr", + "nativeSrc": "1631:320:109", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nativeSrc": "1676:9:109", + "nodeType": "YulTypedName", + "src": "1676:9:109", + "type": "" + }, + { + "name": "dataEnd", + "nativeSrc": "1687:7:109", + "nodeType": "YulTypedName", + "src": "1687:7:109", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nativeSrc": "1699:6:109", + "nodeType": "YulTypedName", + "src": "1699:6:109", + "type": "" + } + ], + "src": "1631:320:109" + }, + { + "body": { + "nativeSrc": "2051:92:109", + "nodeType": "YulBlock", + "src": "2051:92:109", + "statements": [ + { + "nativeSrc": "2061:26:109", + "nodeType": "YulAssignment", + "src": "2061:26:109", + "value": { + "arguments": [ + { + "name": "headStart", + "nativeSrc": "2073:9:109", + "nodeType": "YulIdentifier", + "src": "2073:9:109" + }, + { + "kind": "number", + "nativeSrc": "2084:2:109", + "nodeType": "YulLiteral", + "src": "2084:2:109", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "2069:3:109", + "nodeType": "YulIdentifier", + "src": "2069:3:109" + }, + "nativeSrc": "2069:18:109", + "nodeType": "YulFunctionCall", + "src": "2069:18:109" + }, + "variableNames": [ + { + "name": "tail", + "nativeSrc": "2061:4:109", + "nodeType": "YulIdentifier", + "src": "2061:4:109" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nativeSrc": "2103:9:109", + "nodeType": "YulIdentifier", + "src": "2103:9:109" + }, + { + "arguments": [ + { + "arguments": [ + { + "name": "value0", + "nativeSrc": "2128:6:109", + "nodeType": "YulIdentifier", + "src": "2128:6:109" + } + ], + "functionName": { + "name": "iszero", + "nativeSrc": "2121:6:109", + "nodeType": "YulIdentifier", + "src": "2121:6:109" + }, + "nativeSrc": "2121:14:109", + "nodeType": "YulFunctionCall", + "src": "2121:14:109" + } + ], + "functionName": { + "name": "iszero", + "nativeSrc": "2114:6:109", + "nodeType": "YulIdentifier", + "src": "2114:6:109" + }, + "nativeSrc": "2114:22:109", + "nodeType": "YulFunctionCall", + "src": "2114:22:109" + } + ], + "functionName": { + "name": "mstore", + "nativeSrc": "2096:6:109", + "nodeType": "YulIdentifier", + "src": "2096:6:109" + }, + "nativeSrc": "2096:41:109", + "nodeType": "YulFunctionCall", + "src": "2096:41:109" + }, + "nativeSrc": "2096:41:109", + "nodeType": "YulExpressionStatement", + "src": "2096:41:109" + } + ] + }, + "name": "abi_encode_tuple_t_bool__to_t_bool__fromStack_reversed", + "nativeSrc": "1956:187:109", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nativeSrc": "2020:9:109", + "nodeType": "YulTypedName", + "src": "2020:9:109", + "type": "" + }, + { + "name": "value0", + "nativeSrc": "2031:6:109", + "nodeType": "YulTypedName", + "src": "2031:6:109", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nativeSrc": "2042:4:109", + "nodeType": "YulTypedName", + "src": "2042:4:109", + "type": "" + } + ], + "src": "1956:187:109" + }, + { + "body": { + "nativeSrc": "2249:125:109", + "nodeType": "YulBlock", + "src": "2249:125:109", + "statements": [ + { + "nativeSrc": "2259:26:109", + "nodeType": "YulAssignment", + "src": "2259:26:109", + "value": { + "arguments": [ + { + "name": "headStart", + "nativeSrc": "2271:9:109", + "nodeType": "YulIdentifier", + "src": "2271:9:109" + }, + { + "kind": "number", + "nativeSrc": "2282:2:109", + "nodeType": "YulLiteral", + "src": "2282:2:109", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "2267:3:109", + "nodeType": "YulIdentifier", + "src": "2267:3:109" + }, + "nativeSrc": "2267:18:109", + "nodeType": "YulFunctionCall", + "src": "2267:18:109" + }, + "variableNames": [ + { + "name": "tail", + "nativeSrc": "2259:4:109", + "nodeType": "YulIdentifier", + "src": "2259:4:109" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nativeSrc": "2301:9:109", + "nodeType": "YulIdentifier", + "src": "2301:9:109" + }, + { + "arguments": [ + { + "name": "value0", + "nativeSrc": "2316:6:109", + "nodeType": "YulIdentifier", + "src": "2316:6:109" + }, + { + "kind": "number", + "nativeSrc": "2324:42:109", + "nodeType": "YulLiteral", + "src": "2324:42:109", + "type": "", + "value": "0xffffffffffffffffffffffffffffffffffffffff" + } + ], + "functionName": { + "name": "and", + "nativeSrc": "2312:3:109", + "nodeType": "YulIdentifier", + "src": "2312:3:109" + }, + "nativeSrc": "2312:55:109", + "nodeType": "YulFunctionCall", + "src": "2312:55:109" + } + ], + "functionName": { + "name": "mstore", + "nativeSrc": "2294:6:109", + "nodeType": "YulIdentifier", + "src": "2294:6:109" + }, + "nativeSrc": "2294:74:109", + "nodeType": "YulFunctionCall", + "src": "2294:74:109" + }, + "nativeSrc": "2294:74:109", + "nodeType": "YulExpressionStatement", + "src": "2294:74:109" + } + ] + }, + "name": "abi_encode_tuple_t_address__to_t_address__fromStack_reversed", + "nativeSrc": "2148:226:109", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nativeSrc": "2218:9:109", + "nodeType": "YulTypedName", + "src": "2218:9:109", + "type": "" + }, + { + "name": "value0", + "nativeSrc": "2229:6:109", + "nodeType": "YulTypedName", + "src": "2229:6:109", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nativeSrc": "2240:4:109", + "nodeType": "YulTypedName", + "src": "2240:4:109", + "type": "" + } + ], + "src": "2148:226:109" + }, + { + "body": { + "nativeSrc": "2498:486:109", + "nodeType": "YulBlock", + "src": "2498:486:109", + "statements": [ + { + "nativeSrc": "2508:12:109", + "nodeType": "YulVariableDeclaration", + "src": "2508:12:109", + "value": { + "kind": "number", + "nativeSrc": "2518:2:109", + "nodeType": "YulLiteral", + "src": "2518:2:109", + "type": "", + "value": "32" + }, + "variables": [ + { + "name": "_1", + "nativeSrc": "2512:2:109", + "nodeType": "YulTypedName", + "src": "2512:2:109", + "type": "" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nativeSrc": "2536:9:109", + "nodeType": "YulIdentifier", + "src": "2536:9:109" + }, + { + "name": "_1", + "nativeSrc": "2547:2:109", + "nodeType": "YulIdentifier", + "src": "2547:2:109" + } + ], + "functionName": { + "name": "mstore", + "nativeSrc": "2529:6:109", + "nodeType": "YulIdentifier", + "src": "2529:6:109" + }, + "nativeSrc": "2529:21:109", + "nodeType": "YulFunctionCall", + "src": "2529:21:109" + }, + "nativeSrc": "2529:21:109", + "nodeType": "YulExpressionStatement", + "src": "2529:21:109" + }, + { + "nativeSrc": "2559:27:109", + "nodeType": "YulVariableDeclaration", + "src": "2559:27:109", + "value": { + "arguments": [ + { + "name": "value0", + "nativeSrc": "2579:6:109", + "nodeType": "YulIdentifier", + "src": "2579:6:109" + } + ], + "functionName": { + "name": "mload", + "nativeSrc": "2573:5:109", + "nodeType": "YulIdentifier", + "src": "2573:5:109" + }, + "nativeSrc": "2573:13:109", + "nodeType": "YulFunctionCall", + "src": "2573:13:109" + }, + "variables": [ + { + "name": "length", + "nativeSrc": "2563:6:109", + "nodeType": "YulTypedName", + "src": "2563:6:109", + "type": "" + } + ] + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nativeSrc": "2606:9:109", + "nodeType": "YulIdentifier", + "src": "2606:9:109" + }, + { + "name": "_1", + "nativeSrc": "2617:2:109", + "nodeType": "YulIdentifier", + "src": "2617:2:109" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "2602:3:109", + "nodeType": "YulIdentifier", + "src": "2602:3:109" + }, + "nativeSrc": "2602:18:109", + "nodeType": "YulFunctionCall", + "src": "2602:18:109" + }, + { + "name": "length", + "nativeSrc": "2622:6:109", + "nodeType": "YulIdentifier", + "src": "2622:6:109" + } + ], + "functionName": { + "name": "mstore", + "nativeSrc": "2595:6:109", + "nodeType": "YulIdentifier", + "src": "2595:6:109" + }, + "nativeSrc": "2595:34:109", + "nodeType": "YulFunctionCall", + "src": "2595:34:109" + }, + "nativeSrc": "2595:34:109", + "nodeType": "YulExpressionStatement", + "src": "2595:34:109" + }, + { + "nativeSrc": "2638:10:109", + "nodeType": "YulVariableDeclaration", + "src": "2638:10:109", + "value": { + "kind": "number", + "nativeSrc": "2647:1:109", + "nodeType": "YulLiteral", + "src": "2647:1:109", + "type": "", + "value": "0" + }, + "variables": [ + { + "name": "i", + "nativeSrc": "2642:1:109", + "nodeType": "YulTypedName", + "src": "2642:1:109", + "type": "" + } + ] + }, + { + "body": { + "nativeSrc": "2707:90:109", + "nodeType": "YulBlock", + "src": "2707:90:109", + "statements": [ + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nativeSrc": "2736:9:109", + "nodeType": "YulIdentifier", + "src": "2736:9:109" + }, + { + "name": "i", + "nativeSrc": "2747:1:109", + "nodeType": "YulIdentifier", + "src": "2747:1:109" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "2732:3:109", + "nodeType": "YulIdentifier", + "src": "2732:3:109" + }, + "nativeSrc": "2732:17:109", + "nodeType": "YulFunctionCall", + "src": "2732:17:109" + }, + { + "kind": "number", + "nativeSrc": "2751:2:109", + "nodeType": "YulLiteral", + "src": "2751:2:109", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "2728:3:109", + "nodeType": "YulIdentifier", + "src": "2728:3:109" + }, + "nativeSrc": "2728:26:109", + "nodeType": "YulFunctionCall", + "src": "2728:26:109" + }, + { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "value0", + "nativeSrc": "2770:6:109", + "nodeType": "YulIdentifier", + "src": "2770:6:109" + }, + { + "name": "i", + "nativeSrc": "2778:1:109", + "nodeType": "YulIdentifier", + "src": "2778:1:109" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "2766:3:109", + "nodeType": "YulIdentifier", + "src": "2766:3:109" + }, + "nativeSrc": "2766:14:109", + "nodeType": "YulFunctionCall", + "src": "2766:14:109" + }, + { + "name": "_1", + "nativeSrc": "2782:2:109", + "nodeType": "YulIdentifier", + "src": "2782:2:109" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "2762:3:109", + "nodeType": "YulIdentifier", + "src": "2762:3:109" + }, + "nativeSrc": "2762:23:109", + "nodeType": "YulFunctionCall", + "src": "2762:23:109" + } + ], + "functionName": { + "name": "mload", + "nativeSrc": "2756:5:109", + "nodeType": "YulIdentifier", + "src": "2756:5:109" + }, + "nativeSrc": "2756:30:109", + "nodeType": "YulFunctionCall", + "src": "2756:30:109" + } + ], + "functionName": { + "name": "mstore", + "nativeSrc": "2721:6:109", + "nodeType": "YulIdentifier", + "src": "2721:6:109" + }, + "nativeSrc": "2721:66:109", + "nodeType": "YulFunctionCall", + "src": "2721:66:109" + }, + "nativeSrc": "2721:66:109", + "nodeType": "YulExpressionStatement", + "src": "2721:66:109" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "i", + "nativeSrc": "2668:1:109", + "nodeType": "YulIdentifier", + "src": "2668:1:109" + }, + { + "name": "length", + "nativeSrc": "2671:6:109", + "nodeType": "YulIdentifier", + "src": "2671:6:109" + } + ], + "functionName": { + "name": "lt", + "nativeSrc": "2665:2:109", + "nodeType": "YulIdentifier", + "src": "2665:2:109" + }, + "nativeSrc": "2665:13:109", + "nodeType": "YulFunctionCall", + "src": "2665:13:109" + }, + "nativeSrc": "2657:140:109", + "nodeType": "YulForLoop", + "post": { + "nativeSrc": "2679:19:109", + "nodeType": "YulBlock", + "src": "2679:19:109", + "statements": [ + { + "nativeSrc": "2681:15:109", + "nodeType": "YulAssignment", + "src": "2681:15:109", + "value": { + "arguments": [ + { + "name": "i", + "nativeSrc": "2690:1:109", + "nodeType": "YulIdentifier", + "src": "2690:1:109" + }, + { + "name": "_1", + "nativeSrc": "2693:2:109", + "nodeType": "YulIdentifier", + "src": "2693:2:109" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "2686:3:109", + "nodeType": "YulIdentifier", + "src": "2686:3:109" + }, + "nativeSrc": "2686:10:109", + "nodeType": "YulFunctionCall", + "src": "2686:10:109" + }, + "variableNames": [ + { + "name": "i", + "nativeSrc": "2681:1:109", + "nodeType": "YulIdentifier", + "src": "2681:1:109" + } + ] + } + ] + }, + "pre": { + "nativeSrc": "2661:3:109", + "nodeType": "YulBlock", + "src": "2661:3:109", + "statements": [] + }, + "src": "2657:140:109" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nativeSrc": "2821:9:109", + "nodeType": "YulIdentifier", + "src": "2821:9:109" + }, + { + "name": "length", + "nativeSrc": "2832:6:109", + "nodeType": "YulIdentifier", + "src": "2832:6:109" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "2817:3:109", + "nodeType": "YulIdentifier", + "src": "2817:3:109" + }, + "nativeSrc": "2817:22:109", + "nodeType": "YulFunctionCall", + "src": "2817:22:109" + }, + { + "kind": "number", + "nativeSrc": "2841:2:109", + "nodeType": "YulLiteral", + "src": "2841:2:109", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "2813:3:109", + "nodeType": "YulIdentifier", + "src": "2813:3:109" + }, + "nativeSrc": "2813:31:109", + "nodeType": "YulFunctionCall", + "src": "2813:31:109" + }, + { + "kind": "number", + "nativeSrc": "2846:1:109", + "nodeType": "YulLiteral", + "src": "2846:1:109", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "mstore", + "nativeSrc": "2806:6:109", + "nodeType": "YulIdentifier", + "src": "2806:6:109" + }, + "nativeSrc": "2806:42:109", + "nodeType": "YulFunctionCall", + "src": "2806:42:109" + }, + "nativeSrc": "2806:42:109", + "nodeType": "YulExpressionStatement", + "src": "2806:42:109" + }, + { + "nativeSrc": "2857:121:109", + "nodeType": "YulAssignment", + "src": "2857:121:109", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nativeSrc": "2873:9:109", + "nodeType": "YulIdentifier", + "src": "2873:9:109" + }, + { + "arguments": [ + { + "arguments": [ + { + "name": "length", + "nativeSrc": "2892:6:109", + "nodeType": "YulIdentifier", + "src": "2892:6:109" + }, + { + "kind": "number", + "nativeSrc": "2900:2:109", + "nodeType": "YulLiteral", + "src": "2900:2:109", + "type": "", + "value": "31" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "2888:3:109", + "nodeType": "YulIdentifier", + "src": "2888:3:109" + }, + "nativeSrc": "2888:15:109", + "nodeType": "YulFunctionCall", + "src": "2888:15:109" + }, + { + "kind": "number", + "nativeSrc": "2905:66:109", + "nodeType": "YulLiteral", + "src": "2905:66:109", + "type": "", + "value": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0" + } + ], + "functionName": { + "name": "and", + "nativeSrc": "2884:3:109", + "nodeType": "YulIdentifier", + "src": "2884:3:109" + }, + "nativeSrc": "2884:88:109", + "nodeType": "YulFunctionCall", + "src": "2884:88:109" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "2869:3:109", + "nodeType": "YulIdentifier", + "src": "2869:3:109" + }, + "nativeSrc": "2869:104:109", + "nodeType": "YulFunctionCall", + "src": "2869:104:109" + }, + { + "kind": "number", + "nativeSrc": "2975:2:109", + "nodeType": "YulLiteral", + "src": "2975:2:109", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "2865:3:109", + "nodeType": "YulIdentifier", + "src": "2865:3:109" + }, + "nativeSrc": "2865:113:109", + "nodeType": "YulFunctionCall", + "src": "2865:113:109" + }, + "variableNames": [ + { + "name": "tail", + "nativeSrc": "2857:4:109", + "nodeType": "YulIdentifier", + "src": "2857:4:109" + } + ] + } + ] + }, + "name": "abi_encode_tuple_t_bytes_memory_ptr__to_t_bytes_memory_ptr__fromStack_reversed", + "nativeSrc": "2379:605:109", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nativeSrc": "2467:9:109", + "nodeType": "YulTypedName", + "src": "2467:9:109", + "type": "" + }, + { + "name": "value0", + "nativeSrc": "2478:6:109", + "nodeType": "YulTypedName", + "src": "2478:6:109", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nativeSrc": "2489:4:109", + "nodeType": "YulTypedName", + "src": "2489:4:109", + "type": "" + } + ], + "src": "2379:605:109" + }, + { + "body": { + "nativeSrc": "3065:86:109", + "nodeType": "YulBlock", + "src": "3065:86:109", + "statements": [ + { + "body": { + "nativeSrc": "3105:16:109", + "nodeType": "YulBlock", + "src": "3105:16:109", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nativeSrc": "3114:1:109", + "nodeType": "YulLiteral", + "src": "3114:1:109", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nativeSrc": "3117:1:109", + "nodeType": "YulLiteral", + "src": "3117:1:109", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nativeSrc": "3107:6:109", + "nodeType": "YulIdentifier", + "src": "3107:6:109" + }, + "nativeSrc": "3107:12:109", + "nodeType": "YulFunctionCall", + "src": "3107:12:109" + }, + "nativeSrc": "3107:12:109", + "nodeType": "YulExpressionStatement", + "src": "3107:12:109" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "end", + "nativeSrc": "3086:3:109", + "nodeType": "YulIdentifier", + "src": "3086:3:109" + }, + { + "name": "offset", + "nativeSrc": "3091:6:109", + "nodeType": "YulIdentifier", + "src": "3091:6:109" + } + ], + "functionName": { + "name": "sub", + "nativeSrc": "3082:3:109", + "nodeType": "YulIdentifier", + "src": "3082:3:109" + }, + "nativeSrc": "3082:16:109", + "nodeType": "YulFunctionCall", + "src": "3082:16:109" + }, + { + "kind": "number", + "nativeSrc": "3100:3:109", + "nodeType": "YulLiteral", + "src": "3100:3:109", + "type": "", + "value": "352" + } + ], + "functionName": { + "name": "slt", + "nativeSrc": "3078:3:109", + "nodeType": "YulIdentifier", + "src": "3078:3:109" + }, + "nativeSrc": "3078:26:109", + "nodeType": "YulFunctionCall", + "src": "3078:26:109" + }, + "nativeSrc": "3075:46:109", + "nodeType": "YulIf", + "src": "3075:46:109" + }, + { + "nativeSrc": "3130:15:109", + "nodeType": "YulAssignment", + "src": "3130:15:109", + "value": { + "name": "offset", + "nativeSrc": "3139:6:109", + "nodeType": "YulIdentifier", + "src": "3139:6:109" + }, + "variableNames": [ + { + "name": "value", + "nativeSrc": "3130:5:109", + "nodeType": "YulIdentifier", + "src": "3130:5:109" + } + ] + } + ] + }, + "name": "abi_decode_struct_UserOperation_calldata", + "nativeSrc": "2989:162:109", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "offset", + "nativeSrc": "3039:6:109", + "nodeType": "YulTypedName", + "src": "3039:6:109", + "type": "" + }, + { + "name": "end", + "nativeSrc": "3047:3:109", + "nodeType": "YulTypedName", + "src": "3047:3:109", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value", + "nativeSrc": "3055:5:109", + "nodeType": "YulTypedName", + "src": "3055:5:109", + "type": "" + } + ], + "src": "2989:162:109" + }, + { + "body": { + "nativeSrc": "3277:316:109", + "nodeType": "YulBlock", + "src": "3277:316:109", + "statements": [ + { + "body": { + "nativeSrc": "3323:16:109", + "nodeType": "YulBlock", + "src": "3323:16:109", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nativeSrc": "3332:1:109", + "nodeType": "YulLiteral", + "src": "3332:1:109", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nativeSrc": "3335:1:109", + "nodeType": "YulLiteral", + "src": "3335:1:109", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nativeSrc": "3325:6:109", + "nodeType": "YulIdentifier", + "src": "3325:6:109" + }, + "nativeSrc": "3325:12:109", + "nodeType": "YulFunctionCall", + "src": "3325:12:109" + }, + "nativeSrc": "3325:12:109", + "nodeType": "YulExpressionStatement", + "src": "3325:12:109" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nativeSrc": "3298:7:109", + "nodeType": "YulIdentifier", + "src": "3298:7:109" + }, + { + "name": "headStart", + "nativeSrc": "3307:9:109", + "nodeType": "YulIdentifier", + "src": "3307:9:109" + } + ], + "functionName": { + "name": "sub", + "nativeSrc": "3294:3:109", + "nodeType": "YulIdentifier", + "src": "3294:3:109" + }, + "nativeSrc": "3294:23:109", + "nodeType": "YulFunctionCall", + "src": "3294:23:109" + }, + { + "kind": "number", + "nativeSrc": "3319:2:109", + "nodeType": "YulLiteral", + "src": "3319:2:109", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "slt", + "nativeSrc": "3290:3:109", + "nodeType": "YulIdentifier", + "src": "3290:3:109" + }, + "nativeSrc": "3290:32:109", + "nodeType": "YulFunctionCall", + "src": "3290:32:109" + }, + "nativeSrc": "3287:52:109", + "nodeType": "YulIf", + "src": "3287:52:109" + }, + { + "nativeSrc": "3348:37:109", + "nodeType": "YulVariableDeclaration", + "src": "3348:37:109", + "value": { + "arguments": [ + { + "name": "headStart", + "nativeSrc": "3375:9:109", + "nodeType": "YulIdentifier", + "src": "3375:9:109" + } + ], + "functionName": { + "name": "calldataload", + "nativeSrc": "3362:12:109", + "nodeType": "YulIdentifier", + "src": "3362:12:109" + }, + "nativeSrc": "3362:23:109", + "nodeType": "YulFunctionCall", + "src": "3362:23:109" + }, + "variables": [ + { + "name": "offset", + "nativeSrc": "3352:6:109", + "nodeType": "YulTypedName", + "src": "3352:6:109", + "type": "" + } + ] + }, + { + "body": { + "nativeSrc": "3428:16:109", + "nodeType": "YulBlock", + "src": "3428:16:109", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nativeSrc": "3437:1:109", + "nodeType": "YulLiteral", + "src": "3437:1:109", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nativeSrc": "3440:1:109", + "nodeType": "YulLiteral", + "src": "3440:1:109", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nativeSrc": "3430:6:109", + "nodeType": "YulIdentifier", + "src": "3430:6:109" + }, + "nativeSrc": "3430:12:109", + "nodeType": "YulFunctionCall", + "src": "3430:12:109" + }, + "nativeSrc": "3430:12:109", + "nodeType": "YulExpressionStatement", + "src": "3430:12:109" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "offset", + "nativeSrc": "3400:6:109", + "nodeType": "YulIdentifier", + "src": "3400:6:109" + }, + { + "kind": "number", + "nativeSrc": "3408:18:109", + "nodeType": "YulLiteral", + "src": "3408:18:109", + "type": "", + "value": "0xffffffffffffffff" + } + ], + "functionName": { + "name": "gt", + "nativeSrc": "3397:2:109", + "nodeType": "YulIdentifier", + "src": "3397:2:109" + }, + "nativeSrc": "3397:30:109", + "nodeType": "YulFunctionCall", + "src": "3397:30:109" + }, + "nativeSrc": "3394:50:109", + "nodeType": "YulIf", + "src": "3394:50:109" + }, + { + "nativeSrc": "3453:83:109", + "nodeType": "YulAssignment", + "src": "3453:83:109", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nativeSrc": "3508:9:109", + "nodeType": "YulIdentifier", + "src": "3508:9:109" + }, + { + "name": "offset", + "nativeSrc": "3519:6:109", + "nodeType": "YulIdentifier", + "src": "3519:6:109" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "3504:3:109", + "nodeType": "YulIdentifier", + "src": "3504:3:109" + }, + "nativeSrc": "3504:22:109", + "nodeType": "YulFunctionCall", + "src": "3504:22:109" + }, + { + "name": "dataEnd", + "nativeSrc": "3528:7:109", + "nodeType": "YulIdentifier", + "src": "3528:7:109" + } + ], + "functionName": { + "name": "abi_decode_struct_UserOperation_calldata", + "nativeSrc": "3463:40:109", + "nodeType": "YulIdentifier", + "src": "3463:40:109" + }, + "nativeSrc": "3463:73:109", + "nodeType": "YulFunctionCall", + "src": "3463:73:109" + }, + "variableNames": [ + { + "name": "value0", + "nativeSrc": "3453:6:109", + "nodeType": "YulIdentifier", + "src": "3453:6:109" + } + ] + }, + { + "nativeSrc": "3545:42:109", + "nodeType": "YulAssignment", + "src": "3545:42:109", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nativeSrc": "3572:9:109", + "nodeType": "YulIdentifier", + "src": "3572:9:109" + }, + { + "kind": "number", + "nativeSrc": "3583:2:109", + "nodeType": "YulLiteral", + "src": "3583:2:109", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "3568:3:109", + "nodeType": "YulIdentifier", + "src": "3568:3:109" + }, + "nativeSrc": "3568:18:109", + "nodeType": "YulFunctionCall", + "src": "3568:18:109" + } + ], + "functionName": { + "name": "calldataload", + "nativeSrc": "3555:12:109", + "nodeType": "YulIdentifier", + "src": "3555:12:109" + }, + "nativeSrc": "3555:32:109", + "nodeType": "YulFunctionCall", + "src": "3555:32:109" + }, + "variableNames": [ + { + "name": "value1", + "nativeSrc": "3545:6:109", + "nodeType": "YulIdentifier", + "src": "3545:6:109" + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_struct$_UserOperation_$12474_calldata_ptrt_bytes32", + "nativeSrc": "3156:437:109", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nativeSrc": "3235:9:109", + "nodeType": "YulTypedName", + "src": "3235:9:109", + "type": "" + }, + { + "name": "dataEnd", + "nativeSrc": "3246:7:109", + "nodeType": "YulTypedName", + "src": "3246:7:109", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nativeSrc": "3258:6:109", + "nodeType": "YulTypedName", + "src": "3258:6:109", + "type": "" + }, + { + "name": "value1", + "nativeSrc": "3266:6:109", + "nodeType": "YulTypedName", + "src": "3266:6:109", + "type": "" + } + ], + "src": "3156:437:109" + }, + { + "body": { + "nativeSrc": "3699:76:109", + "nodeType": "YulBlock", + "src": "3699:76:109", + "statements": [ + { + "nativeSrc": "3709:26:109", + "nodeType": "YulAssignment", + "src": "3709:26:109", + "value": { + "arguments": [ + { + "name": "headStart", + "nativeSrc": "3721:9:109", + "nodeType": "YulIdentifier", + "src": "3721:9:109" + }, + { + "kind": "number", + "nativeSrc": "3732:2:109", + "nodeType": "YulLiteral", + "src": "3732:2:109", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "3717:3:109", + "nodeType": "YulIdentifier", + "src": "3717:3:109" + }, + "nativeSrc": "3717:18:109", + "nodeType": "YulFunctionCall", + "src": "3717:18:109" + }, + "variableNames": [ + { + "name": "tail", + "nativeSrc": "3709:4:109", + "nodeType": "YulIdentifier", + "src": "3709:4:109" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nativeSrc": "3751:9:109", + "nodeType": "YulIdentifier", + "src": "3751:9:109" + }, + { + "name": "value0", + "nativeSrc": "3762:6:109", + "nodeType": "YulIdentifier", + "src": "3762:6:109" + } + ], + "functionName": { + "name": "mstore", + "nativeSrc": "3744:6:109", + "nodeType": "YulIdentifier", + "src": "3744:6:109" + }, + "nativeSrc": "3744:25:109", + "nodeType": "YulFunctionCall", + "src": "3744:25:109" + }, + "nativeSrc": "3744:25:109", + "nodeType": "YulExpressionStatement", + "src": "3744:25:109" + } + ] + }, + "name": "abi_encode_tuple_t_uint256__to_t_uint256__fromStack_reversed", + "nativeSrc": "3598:177:109", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nativeSrc": "3668:9:109", + "nodeType": "YulTypedName", + "src": "3668:9:109", + "type": "" + }, + { + "name": "value0", + "nativeSrc": "3679:6:109", + "nodeType": "YulTypedName", + "src": "3679:6:109", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nativeSrc": "3690:4:109", + "nodeType": "YulTypedName", + "src": "3690:4:109", + "type": "" + } + ], + "src": "3598:177:109" + }, + { + "body": { + "nativeSrc": "3869:502:109", + "nodeType": "YulBlock", + "src": "3869:502:109", + "statements": [ + { + "body": { + "nativeSrc": "3915:16:109", + "nodeType": "YulBlock", + "src": "3915:16:109", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nativeSrc": "3924:1:109", + "nodeType": "YulLiteral", + "src": "3924:1:109", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nativeSrc": "3927:1:109", + "nodeType": "YulLiteral", + "src": "3927:1:109", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nativeSrc": "3917:6:109", + "nodeType": "YulIdentifier", + "src": "3917:6:109" + }, + "nativeSrc": "3917:12:109", + "nodeType": "YulFunctionCall", + "src": "3917:12:109" + }, + "nativeSrc": "3917:12:109", + "nodeType": "YulExpressionStatement", + "src": "3917:12:109" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nativeSrc": "3890:7:109", + "nodeType": "YulIdentifier", + "src": "3890:7:109" + }, + { + "name": "headStart", + "nativeSrc": "3899:9:109", + "nodeType": "YulIdentifier", + "src": "3899:9:109" + } + ], + "functionName": { + "name": "sub", + "nativeSrc": "3886:3:109", + "nodeType": "YulIdentifier", + "src": "3886:3:109" + }, + "nativeSrc": "3886:23:109", + "nodeType": "YulFunctionCall", + "src": "3886:23:109" + }, + { + "kind": "number", + "nativeSrc": "3911:2:109", + "nodeType": "YulLiteral", + "src": "3911:2:109", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "slt", + "nativeSrc": "3882:3:109", + "nodeType": "YulIdentifier", + "src": "3882:3:109" + }, + "nativeSrc": "3882:32:109", + "nodeType": "YulFunctionCall", + "src": "3882:32:109" + }, + "nativeSrc": "3879:52:109", + "nodeType": "YulIf", + "src": "3879:52:109" + }, + { + "nativeSrc": "3940:37:109", + "nodeType": "YulVariableDeclaration", + "src": "3940:37:109", + "value": { + "arguments": [ + { + "name": "headStart", + "nativeSrc": "3967:9:109", + "nodeType": "YulIdentifier", + "src": "3967:9:109" + } + ], + "functionName": { + "name": "calldataload", + "nativeSrc": "3954:12:109", + "nodeType": "YulIdentifier", + "src": "3954:12:109" + }, + "nativeSrc": "3954:23:109", + "nodeType": "YulFunctionCall", + "src": "3954:23:109" + }, + "variables": [ + { + "name": "offset", + "nativeSrc": "3944:6:109", + "nodeType": "YulTypedName", + "src": "3944:6:109", + "type": "" + } + ] + }, + { + "nativeSrc": "3986:28:109", + "nodeType": "YulVariableDeclaration", + "src": "3986:28:109", + "value": { + "kind": "number", + "nativeSrc": "3996:18:109", + "nodeType": "YulLiteral", + "src": "3996:18:109", + "type": "", + "value": "0xffffffffffffffff" + }, + "variables": [ + { + "name": "_1", + "nativeSrc": "3990:2:109", + "nodeType": "YulTypedName", + "src": "3990:2:109", + "type": "" + } + ] + }, + { + "body": { + "nativeSrc": "4041:16:109", + "nodeType": "YulBlock", + "src": "4041:16:109", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nativeSrc": "4050:1:109", + "nodeType": "YulLiteral", + "src": "4050:1:109", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nativeSrc": "4053:1:109", + "nodeType": "YulLiteral", + "src": "4053:1:109", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nativeSrc": "4043:6:109", + "nodeType": "YulIdentifier", + "src": "4043:6:109" + }, + "nativeSrc": "4043:12:109", + "nodeType": "YulFunctionCall", + "src": "4043:12:109" + }, + "nativeSrc": "4043:12:109", + "nodeType": "YulExpressionStatement", + "src": "4043:12:109" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "offset", + "nativeSrc": "4029:6:109", + "nodeType": "YulIdentifier", + "src": "4029:6:109" + }, + { + "name": "_1", + "nativeSrc": "4037:2:109", + "nodeType": "YulIdentifier", + "src": "4037:2:109" + } + ], + "functionName": { + "name": "gt", + "nativeSrc": "4026:2:109", + "nodeType": "YulIdentifier", + "src": "4026:2:109" + }, + "nativeSrc": "4026:14:109", + "nodeType": "YulFunctionCall", + "src": "4026:14:109" + }, + "nativeSrc": "4023:34:109", + "nodeType": "YulIf", + "src": "4023:34:109" + }, + { + "nativeSrc": "4066:32:109", + "nodeType": "YulVariableDeclaration", + "src": "4066:32:109", + "value": { + "arguments": [ + { + "name": "headStart", + "nativeSrc": "4080:9:109", + "nodeType": "YulIdentifier", + "src": "4080:9:109" + }, + { + "name": "offset", + "nativeSrc": "4091:6:109", + "nodeType": "YulIdentifier", + "src": "4091:6:109" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "4076:3:109", + "nodeType": "YulIdentifier", + "src": "4076:3:109" + }, + "nativeSrc": "4076:22:109", + "nodeType": "YulFunctionCall", + "src": "4076:22:109" + }, + "variables": [ + { + "name": "_2", + "nativeSrc": "4070:2:109", + "nodeType": "YulTypedName", + "src": "4070:2:109", + "type": "" + } + ] + }, + { + "body": { + "nativeSrc": "4146:16:109", + "nodeType": "YulBlock", + "src": "4146:16:109", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nativeSrc": "4155:1:109", + "nodeType": "YulLiteral", + "src": "4155:1:109", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nativeSrc": "4158:1:109", + "nodeType": "YulLiteral", + "src": "4158:1:109", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nativeSrc": "4148:6:109", + "nodeType": "YulIdentifier", + "src": "4148:6:109" + }, + "nativeSrc": "4148:12:109", + "nodeType": "YulFunctionCall", + "src": "4148:12:109" + }, + "nativeSrc": "4148:12:109", + "nodeType": "YulExpressionStatement", + "src": "4148:12:109" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "_2", + "nativeSrc": "4125:2:109", + "nodeType": "YulIdentifier", + "src": "4125:2:109" + }, + { + "kind": "number", + "nativeSrc": "4129:4:109", + "nodeType": "YulLiteral", + "src": "4129:4:109", + "type": "", + "value": "0x1f" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "4121:3:109", + "nodeType": "YulIdentifier", + "src": "4121:3:109" + }, + "nativeSrc": "4121:13:109", + "nodeType": "YulFunctionCall", + "src": "4121:13:109" + }, + { + "name": "dataEnd", + "nativeSrc": "4136:7:109", + "nodeType": "YulIdentifier", + "src": "4136:7:109" + } + ], + "functionName": { + "name": "slt", + "nativeSrc": "4117:3:109", + "nodeType": "YulIdentifier", + "src": "4117:3:109" + }, + "nativeSrc": "4117:27:109", + "nodeType": "YulFunctionCall", + "src": "4117:27:109" + } + ], + "functionName": { + "name": "iszero", + "nativeSrc": "4110:6:109", + "nodeType": "YulIdentifier", + "src": "4110:6:109" + }, + "nativeSrc": "4110:35:109", + "nodeType": "YulFunctionCall", + "src": "4110:35:109" + }, + "nativeSrc": "4107:55:109", + "nodeType": "YulIf", + "src": "4107:55:109" + }, + { + "nativeSrc": "4171:30:109", + "nodeType": "YulVariableDeclaration", + "src": "4171:30:109", + "value": { + "arguments": [ + { + "name": "_2", + "nativeSrc": "4198:2:109", + "nodeType": "YulIdentifier", + "src": "4198:2:109" + } + ], + "functionName": { + "name": "calldataload", + "nativeSrc": "4185:12:109", + "nodeType": "YulIdentifier", + "src": "4185:12:109" + }, + "nativeSrc": "4185:16:109", + "nodeType": "YulFunctionCall", + "src": "4185:16:109" + }, + "variables": [ + { + "name": "length", + "nativeSrc": "4175:6:109", + "nodeType": "YulTypedName", + "src": "4175:6:109", + "type": "" + } + ] + }, + { + "body": { + "nativeSrc": "4228:16:109", + "nodeType": "YulBlock", + "src": "4228:16:109", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nativeSrc": "4237:1:109", + "nodeType": "YulLiteral", + "src": "4237:1:109", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nativeSrc": "4240:1:109", + "nodeType": "YulLiteral", + "src": "4240:1:109", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nativeSrc": "4230:6:109", + "nodeType": "YulIdentifier", + "src": "4230:6:109" + }, + "nativeSrc": "4230:12:109", + "nodeType": "YulFunctionCall", + "src": "4230:12:109" + }, + "nativeSrc": "4230:12:109", + "nodeType": "YulExpressionStatement", + "src": "4230:12:109" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "length", + "nativeSrc": "4216:6:109", + "nodeType": "YulIdentifier", + "src": "4216:6:109" + }, + { + "name": "_1", + "nativeSrc": "4224:2:109", + "nodeType": "YulIdentifier", + "src": "4224:2:109" + } + ], + "functionName": { + "name": "gt", + "nativeSrc": "4213:2:109", + "nodeType": "YulIdentifier", + "src": "4213:2:109" + }, + "nativeSrc": "4213:14:109", + "nodeType": "YulFunctionCall", + "src": "4213:14:109" + }, + "nativeSrc": "4210:34:109", + "nodeType": "YulIf", + "src": "4210:34:109" + }, + { + "body": { + "nativeSrc": "4294:16:109", + "nodeType": "YulBlock", + "src": "4294:16:109", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nativeSrc": "4303:1:109", + "nodeType": "YulLiteral", + "src": "4303:1:109", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nativeSrc": "4306:1:109", + "nodeType": "YulLiteral", + "src": "4306:1:109", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nativeSrc": "4296:6:109", + "nodeType": "YulIdentifier", + "src": "4296:6:109" + }, + "nativeSrc": "4296:12:109", + "nodeType": "YulFunctionCall", + "src": "4296:12:109" + }, + "nativeSrc": "4296:12:109", + "nodeType": "YulExpressionStatement", + "src": "4296:12:109" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "_2", + "nativeSrc": "4267:2:109", + "nodeType": "YulIdentifier", + "src": "4267:2:109" + }, + { + "name": "length", + "nativeSrc": "4271:6:109", + "nodeType": "YulIdentifier", + "src": "4271:6:109" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "4263:3:109", + "nodeType": "YulIdentifier", + "src": "4263:3:109" + }, + "nativeSrc": "4263:15:109", + "nodeType": "YulFunctionCall", + "src": "4263:15:109" + }, + { + "kind": "number", + "nativeSrc": "4280:2:109", + "nodeType": "YulLiteral", + "src": "4280:2:109", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "4259:3:109", + "nodeType": "YulIdentifier", + "src": "4259:3:109" + }, + "nativeSrc": "4259:24:109", + "nodeType": "YulFunctionCall", + "src": "4259:24:109" + }, + { + "name": "dataEnd", + "nativeSrc": "4285:7:109", + "nodeType": "YulIdentifier", + "src": "4285:7:109" + } + ], + "functionName": { + "name": "gt", + "nativeSrc": "4256:2:109", + "nodeType": "YulIdentifier", + "src": "4256:2:109" + }, + "nativeSrc": "4256:37:109", + "nodeType": "YulFunctionCall", + "src": "4256:37:109" + }, + "nativeSrc": "4253:57:109", + "nodeType": "YulIf", + "src": "4253:57:109" + }, + { + "nativeSrc": "4319:21:109", + "nodeType": "YulAssignment", + "src": "4319:21:109", + "value": { + "arguments": [ + { + "name": "_2", + "nativeSrc": "4333:2:109", + "nodeType": "YulIdentifier", + "src": "4333:2:109" + }, + { + "kind": "number", + "nativeSrc": "4337:2:109", + "nodeType": "YulLiteral", + "src": "4337:2:109", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "4329:3:109", + "nodeType": "YulIdentifier", + "src": "4329:3:109" + }, + "nativeSrc": "4329:11:109", + "nodeType": "YulFunctionCall", + "src": "4329:11:109" + }, + "variableNames": [ + { + "name": "value0", + "nativeSrc": "4319:6:109", + "nodeType": "YulIdentifier", + "src": "4319:6:109" + } + ] + }, + { + "nativeSrc": "4349:16:109", + "nodeType": "YulAssignment", + "src": "4349:16:109", + "value": { + "name": "length", + "nativeSrc": "4359:6:109", + "nodeType": "YulIdentifier", + "src": "4359:6:109" + }, + "variableNames": [ + { + "name": "value1", + "nativeSrc": "4349:6:109", + "nodeType": "YulIdentifier", + "src": "4349:6:109" + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_bytes_calldata_ptr", + "nativeSrc": "3780:591:109", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nativeSrc": "3827:9:109", + "nodeType": "YulTypedName", + "src": "3827:9:109", + "type": "" + }, + { + "name": "dataEnd", + "nativeSrc": "3838:7:109", + "nodeType": "YulTypedName", + "src": "3838:7:109", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nativeSrc": "3850:6:109", + "nodeType": "YulTypedName", + "src": "3850:6:109", + "type": "" + }, + { + "name": "value1", + "nativeSrc": "3858:6:109", + "nodeType": "YulTypedName", + "src": "3858:6:109", + "type": "" + } + ], + "src": "3780:591:109" + }, + { + "body": { + "nativeSrc": "4514:496:109", + "nodeType": "YulBlock", + "src": "4514:496:109", + "statements": [ + { + "body": { + "nativeSrc": "4560:16:109", + "nodeType": "YulBlock", + "src": "4560:16:109", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nativeSrc": "4569:1:109", + "nodeType": "YulLiteral", + "src": "4569:1:109", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nativeSrc": "4572:1:109", + "nodeType": "YulLiteral", + "src": "4572:1:109", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nativeSrc": "4562:6:109", + "nodeType": "YulIdentifier", + "src": "4562:6:109" + }, + "nativeSrc": "4562:12:109", + "nodeType": "YulFunctionCall", + "src": "4562:12:109" + }, + "nativeSrc": "4562:12:109", + "nodeType": "YulExpressionStatement", + "src": "4562:12:109" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nativeSrc": "4535:7:109", + "nodeType": "YulIdentifier", + "src": "4535:7:109" + }, + { + "name": "headStart", + "nativeSrc": "4544:9:109", + "nodeType": "YulIdentifier", + "src": "4544:9:109" + } + ], + "functionName": { + "name": "sub", + "nativeSrc": "4531:3:109", + "nodeType": "YulIdentifier", + "src": "4531:3:109" + }, + "nativeSrc": "4531:23:109", + "nodeType": "YulFunctionCall", + "src": "4531:23:109" + }, + { + "kind": "number", + "nativeSrc": "4556:2:109", + "nodeType": "YulLiteral", + "src": "4556:2:109", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "slt", + "nativeSrc": "4527:3:109", + "nodeType": "YulIdentifier", + "src": "4527:3:109" + }, + "nativeSrc": "4527:32:109", + "nodeType": "YulFunctionCall", + "src": "4527:32:109" + }, + "nativeSrc": "4524:52:109", + "nodeType": "YulIf", + "src": "4524:52:109" + }, + { + "nativeSrc": "4585:37:109", + "nodeType": "YulVariableDeclaration", + "src": "4585:37:109", + "value": { + "arguments": [ + { + "name": "headStart", + "nativeSrc": "4612:9:109", + "nodeType": "YulIdentifier", + "src": "4612:9:109" + } + ], + "functionName": { + "name": "calldataload", + "nativeSrc": "4599:12:109", + "nodeType": "YulIdentifier", + "src": "4599:12:109" + }, + "nativeSrc": "4599:23:109", + "nodeType": "YulFunctionCall", + "src": "4599:23:109" + }, + "variables": [ + { + "name": "offset", + "nativeSrc": "4589:6:109", + "nodeType": "YulTypedName", + "src": "4589:6:109", + "type": "" + } + ] + }, + { + "body": { + "nativeSrc": "4665:16:109", + "nodeType": "YulBlock", + "src": "4665:16:109", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nativeSrc": "4674:1:109", + "nodeType": "YulLiteral", + "src": "4674:1:109", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nativeSrc": "4677:1:109", + "nodeType": "YulLiteral", + "src": "4677:1:109", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nativeSrc": "4667:6:109", + "nodeType": "YulIdentifier", + "src": "4667:6:109" + }, + "nativeSrc": "4667:12:109", + "nodeType": "YulFunctionCall", + "src": "4667:12:109" + }, + "nativeSrc": "4667:12:109", + "nodeType": "YulExpressionStatement", + "src": "4667:12:109" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "offset", + "nativeSrc": "4637:6:109", + "nodeType": "YulIdentifier", + "src": "4637:6:109" + }, + { + "kind": "number", + "nativeSrc": "4645:18:109", + "nodeType": "YulLiteral", + "src": "4645:18:109", + "type": "", + "value": "0xffffffffffffffff" + } + ], + "functionName": { + "name": "gt", + "nativeSrc": "4634:2:109", + "nodeType": "YulIdentifier", + "src": "4634:2:109" + }, + "nativeSrc": "4634:30:109", + "nodeType": "YulFunctionCall", + "src": "4634:30:109" + }, + "nativeSrc": "4631:50:109", + "nodeType": "YulIf", + "src": "4631:50:109" + }, + { + "nativeSrc": "4690:83:109", + "nodeType": "YulAssignment", + "src": "4690:83:109", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nativeSrc": "4745:9:109", + "nodeType": "YulIdentifier", + "src": "4745:9:109" + }, + { + "name": "offset", + "nativeSrc": "4756:6:109", + "nodeType": "YulIdentifier", + "src": "4756:6:109" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "4741:3:109", + "nodeType": "YulIdentifier", + "src": "4741:3:109" + }, + "nativeSrc": "4741:22:109", + "nodeType": "YulFunctionCall", + "src": "4741:22:109" + }, + { + "name": "dataEnd", + "nativeSrc": "4765:7:109", + "nodeType": "YulIdentifier", + "src": "4765:7:109" + } + ], + "functionName": { + "name": "abi_decode_struct_UserOperation_calldata", + "nativeSrc": "4700:40:109", + "nodeType": "YulIdentifier", + "src": "4700:40:109" + }, + "nativeSrc": "4700:73:109", + "nodeType": "YulFunctionCall", + "src": "4700:73:109" + }, + "variableNames": [ + { + "name": "value0", + "nativeSrc": "4690:6:109", + "nodeType": "YulIdentifier", + "src": "4690:6:109" + } + ] + }, + { + "nativeSrc": "4782:42:109", + "nodeType": "YulAssignment", + "src": "4782:42:109", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nativeSrc": "4809:9:109", + "nodeType": "YulIdentifier", + "src": "4809:9:109" + }, + { + "kind": "number", + "nativeSrc": "4820:2:109", + "nodeType": "YulLiteral", + "src": "4820:2:109", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "4805:3:109", + "nodeType": "YulIdentifier", + "src": "4805:3:109" + }, + "nativeSrc": "4805:18:109", + "nodeType": "YulFunctionCall", + "src": "4805:18:109" + } + ], + "functionName": { + "name": "calldataload", + "nativeSrc": "4792:12:109", + "nodeType": "YulIdentifier", + "src": "4792:12:109" + }, + "nativeSrc": "4792:32:109", + "nodeType": "YulFunctionCall", + "src": "4792:32:109" + }, + "variableNames": [ + { + "name": "value1", + "nativeSrc": "4782:6:109", + "nodeType": "YulIdentifier", + "src": "4782:6:109" + } + ] + }, + { + "nativeSrc": "4833:45:109", + "nodeType": "YulVariableDeclaration", + "src": "4833:45:109", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nativeSrc": "4863:9:109", + "nodeType": "YulIdentifier", + "src": "4863:9:109" + }, + { + "kind": "number", + "nativeSrc": "4874:2:109", + "nodeType": "YulLiteral", + "src": "4874:2:109", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "4859:3:109", + "nodeType": "YulIdentifier", + "src": "4859:3:109" + }, + "nativeSrc": "4859:18:109", + "nodeType": "YulFunctionCall", + "src": "4859:18:109" + } + ], + "functionName": { + "name": "calldataload", + "nativeSrc": "4846:12:109", + "nodeType": "YulIdentifier", + "src": "4846:12:109" + }, + "nativeSrc": "4846:32:109", + "nodeType": "YulFunctionCall", + "src": "4846:32:109" + }, + "variables": [ + { + "name": "value", + "nativeSrc": "4837:5:109", + "nodeType": "YulTypedName", + "src": "4837:5:109", + "type": "" + } + ] + }, + { + "body": { + "nativeSrc": "4964:16:109", + "nodeType": "YulBlock", + "src": "4964:16:109", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nativeSrc": "4973:1:109", + "nodeType": "YulLiteral", + "src": "4973:1:109", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nativeSrc": "4976:1:109", + "nodeType": "YulLiteral", + "src": "4976:1:109", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nativeSrc": "4966:6:109", + "nodeType": "YulIdentifier", + "src": "4966:6:109" + }, + "nativeSrc": "4966:12:109", + "nodeType": "YulFunctionCall", + "src": "4966:12:109" + }, + "nativeSrc": "4966:12:109", + "nodeType": "YulExpressionStatement", + "src": "4966:12:109" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "value", + "nativeSrc": "4900:5:109", + "nodeType": "YulIdentifier", + "src": "4900:5:109" + }, + { + "arguments": [ + { + "name": "value", + "nativeSrc": "4911:5:109", + "nodeType": "YulIdentifier", + "src": "4911:5:109" + }, + { + "kind": "number", + "nativeSrc": "4918:42:109", + "nodeType": "YulLiteral", + "src": "4918:42:109", + "type": "", + "value": "0xffffffffffffffffffffffffffffffffffffffff" + } + ], + "functionName": { + "name": "and", + "nativeSrc": "4907:3:109", + "nodeType": "YulIdentifier", + "src": "4907:3:109" + }, + "nativeSrc": "4907:54:109", + "nodeType": "YulFunctionCall", + "src": "4907:54:109" + } + ], + "functionName": { + "name": "eq", + "nativeSrc": "4897:2:109", + "nodeType": "YulIdentifier", + "src": "4897:2:109" + }, + "nativeSrc": "4897:65:109", + "nodeType": "YulFunctionCall", + "src": "4897:65:109" + } + ], + "functionName": { + "name": "iszero", + "nativeSrc": "4890:6:109", + "nodeType": "YulIdentifier", + "src": "4890:6:109" + }, + "nativeSrc": "4890:73:109", + "nodeType": "YulFunctionCall", + "src": "4890:73:109" + }, + "nativeSrc": "4887:93:109", + "nodeType": "YulIf", + "src": "4887:93:109" + }, + { + "nativeSrc": "4989:15:109", + "nodeType": "YulAssignment", + "src": "4989:15:109", + "value": { + "name": "value", + "nativeSrc": "4999:5:109", + "nodeType": "YulIdentifier", + "src": "4999:5:109" + }, + "variableNames": [ + { + "name": "value2", + "nativeSrc": "4989:6:109", + "nodeType": "YulIdentifier", + "src": "4989:6:109" + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_struct$_UserOperation_$12474_calldata_ptrt_bytes32t_address", + "nativeSrc": "4376:634:109", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nativeSrc": "4464:9:109", + "nodeType": "YulTypedName", + "src": "4464:9:109", + "type": "" + }, + { + "name": "dataEnd", + "nativeSrc": "4475:7:109", + "nodeType": "YulTypedName", + "src": "4475:7:109", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nativeSrc": "4487:6:109", + "nodeType": "YulTypedName", + "src": "4487:6:109", + "type": "" + }, + { + "name": "value1", + "nativeSrc": "4495:6:109", + "nodeType": "YulTypedName", + "src": "4495:6:109", + "type": "" + }, + { + "name": "value2", + "nativeSrc": "4503:6:109", + "nodeType": "YulTypedName", + "src": "4503:6:109", + "type": "" + } + ], + "src": "4376:634:109" + }, + { + "body": { + "nativeSrc": "5047:152:109", + "nodeType": "YulBlock", + "src": "5047:152:109", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nativeSrc": "5064:1:109", + "nodeType": "YulLiteral", + "src": "5064:1:109", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nativeSrc": "5067:77:109", + "nodeType": "YulLiteral", + "src": "5067:77:109", + "type": "", + "value": "35408467139433450592217433187231851964531694900788300625387963629091585785856" + } + ], + "functionName": { + "name": "mstore", + "nativeSrc": "5057:6:109", + "nodeType": "YulIdentifier", + "src": "5057:6:109" + }, + "nativeSrc": "5057:88:109", + "nodeType": "YulFunctionCall", + "src": "5057:88:109" + }, + "nativeSrc": "5057:88:109", + "nodeType": "YulExpressionStatement", + "src": "5057:88:109" + }, + { + "expression": { + "arguments": [ + { + "kind": "number", + "nativeSrc": "5161:1:109", + "nodeType": "YulLiteral", + "src": "5161:1:109", + "type": "", + "value": "4" + }, + { + "kind": "number", + "nativeSrc": "5164:4:109", + "nodeType": "YulLiteral", + "src": "5164:4:109", + "type": "", + "value": "0x32" + } + ], + "functionName": { + "name": "mstore", + "nativeSrc": "5154:6:109", + "nodeType": "YulIdentifier", + "src": "5154:6:109" + }, + "nativeSrc": "5154:15:109", + "nodeType": "YulFunctionCall", + "src": "5154:15:109" + }, + "nativeSrc": "5154:15:109", + "nodeType": "YulExpressionStatement", + "src": "5154:15:109" + }, + { + "expression": { + "arguments": [ + { + "kind": "number", + "nativeSrc": "5185:1:109", + "nodeType": "YulLiteral", + "src": "5185:1:109", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nativeSrc": "5188:4:109", + "nodeType": "YulLiteral", + "src": "5188:4:109", + "type": "", + "value": "0x24" + } + ], + "functionName": { + "name": "revert", + "nativeSrc": "5178:6:109", + "nodeType": "YulIdentifier", + "src": "5178:6:109" + }, + "nativeSrc": "5178:15:109", + "nodeType": "YulFunctionCall", + "src": "5178:15:109" + }, + "nativeSrc": "5178:15:109", + "nodeType": "YulExpressionStatement", + "src": "5178:15:109" + } + ] + }, + "name": "panic_error_0x32", + "nativeSrc": "5015:184:109", + "nodeType": "YulFunctionDefinition", + "src": "5015:184:109" + }, + { + "body": { + "nativeSrc": "5323:145:109", + "nodeType": "YulBlock", + "src": "5323:145:109", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "pos", + "nativeSrc": "5340:3:109", + "nodeType": "YulIdentifier", + "src": "5340:3:109" + }, + { + "arguments": [ + { + "arguments": [ + { + "kind": "number", + "nativeSrc": "5353:2:109", + "nodeType": "YulLiteral", + "src": "5353:2:109", + "type": "", + "value": "96" + }, + { + "name": "value0", + "nativeSrc": "5357:6:109", + "nodeType": "YulIdentifier", + "src": "5357:6:109" + } + ], + "functionName": { + "name": "shl", + "nativeSrc": "5349:3:109", + "nodeType": "YulIdentifier", + "src": "5349:3:109" + }, + "nativeSrc": "5349:15:109", + "nodeType": "YulFunctionCall", + "src": "5349:15:109" + }, + { + "kind": "number", + "nativeSrc": "5366:66:109", + "nodeType": "YulLiteral", + "src": "5366:66:109", + "type": "", + "value": "0xffffffffffffffffffffffffffffffffffffffff000000000000000000000000" + } + ], + "functionName": { + "name": "and", + "nativeSrc": "5345:3:109", + "nodeType": "YulIdentifier", + "src": "5345:3:109" + }, + "nativeSrc": "5345:88:109", + "nodeType": "YulFunctionCall", + "src": "5345:88:109" + } + ], + "functionName": { + "name": "mstore", + "nativeSrc": "5333:6:109", + "nodeType": "YulIdentifier", + "src": "5333:6:109" + }, + "nativeSrc": "5333:101:109", + "nodeType": "YulFunctionCall", + "src": "5333:101:109" + }, + "nativeSrc": "5333:101:109", + "nodeType": "YulExpressionStatement", + "src": "5333:101:109" + }, + { + "nativeSrc": "5443:19:109", + "nodeType": "YulAssignment", + "src": "5443:19:109", + "value": { + "arguments": [ + { + "name": "pos", + "nativeSrc": "5454:3:109", + "nodeType": "YulIdentifier", + "src": "5454:3:109" + }, + { + "kind": "number", + "nativeSrc": "5459:2:109", + "nodeType": "YulLiteral", + "src": "5459:2:109", + "type": "", + "value": "20" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "5450:3:109", + "nodeType": "YulIdentifier", + "src": "5450:3:109" + }, + "nativeSrc": "5450:12:109", + "nodeType": "YulFunctionCall", + "src": "5450:12:109" + }, + "variableNames": [ + { + "name": "end", + "nativeSrc": "5443:3:109", + "nodeType": "YulIdentifier", + "src": "5443:3:109" + } + ] + } + ] + }, + "name": "abi_encode_tuple_packed_t_address__to_t_address__nonPadded_inplace_fromStack_reversed", + "nativeSrc": "5204:264:109", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "pos", + "nativeSrc": "5299:3:109", + "nodeType": "YulTypedName", + "src": "5299:3:109", + "type": "" + }, + { + "name": "value0", + "nativeSrc": "5304:6:109", + "nodeType": "YulTypedName", + "src": "5304:6:109", + "type": "" + } + ], + "returnVariables": [ + { + "name": "end", + "nativeSrc": "5315:3:109", + "nodeType": "YulTypedName", + "src": "5315:3:109", + "type": "" + } + ], + "src": "5204:264:109" + }, + { + "body": { + "nativeSrc": "5603:201:109", + "nodeType": "YulBlock", + "src": "5603:201:109", + "statements": [ + { + "body": { + "nativeSrc": "5641:16:109", + "nodeType": "YulBlock", + "src": "5641:16:109", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nativeSrc": "5650:1:109", + "nodeType": "YulLiteral", + "src": "5650:1:109", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nativeSrc": "5653:1:109", + "nodeType": "YulLiteral", + "src": "5653:1:109", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nativeSrc": "5643:6:109", + "nodeType": "YulIdentifier", + "src": "5643:6:109" + }, + "nativeSrc": "5643:12:109", + "nodeType": "YulFunctionCall", + "src": "5643:12:109" + }, + "nativeSrc": "5643:12:109", + "nodeType": "YulExpressionStatement", + "src": "5643:12:109" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "startIndex", + "nativeSrc": "5619:10:109", + "nodeType": "YulIdentifier", + "src": "5619:10:109" + }, + { + "name": "endIndex", + "nativeSrc": "5631:8:109", + "nodeType": "YulIdentifier", + "src": "5631:8:109" + } + ], + "functionName": { + "name": "gt", + "nativeSrc": "5616:2:109", + "nodeType": "YulIdentifier", + "src": "5616:2:109" + }, + "nativeSrc": "5616:24:109", + "nodeType": "YulFunctionCall", + "src": "5616:24:109" + }, + "nativeSrc": "5613:44:109", + "nodeType": "YulIf", + "src": "5613:44:109" + }, + { + "body": { + "nativeSrc": "5690:16:109", + "nodeType": "YulBlock", + "src": "5690:16:109", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nativeSrc": "5699:1:109", + "nodeType": "YulLiteral", + "src": "5699:1:109", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nativeSrc": "5702:1:109", + "nodeType": "YulLiteral", + "src": "5702:1:109", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nativeSrc": "5692:6:109", + "nodeType": "YulIdentifier", + "src": "5692:6:109" + }, + "nativeSrc": "5692:12:109", + "nodeType": "YulFunctionCall", + "src": "5692:12:109" + }, + "nativeSrc": "5692:12:109", + "nodeType": "YulExpressionStatement", + "src": "5692:12:109" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "endIndex", + "nativeSrc": "5672:8:109", + "nodeType": "YulIdentifier", + "src": "5672:8:109" + }, + { + "name": "length", + "nativeSrc": "5682:6:109", + "nodeType": "YulIdentifier", + "src": "5682:6:109" + } + ], + "functionName": { + "name": "gt", + "nativeSrc": "5669:2:109", + "nodeType": "YulIdentifier", + "src": "5669:2:109" + }, + "nativeSrc": "5669:20:109", + "nodeType": "YulFunctionCall", + "src": "5669:20:109" + }, + "nativeSrc": "5666:40:109", + "nodeType": "YulIf", + "src": "5666:40:109" + }, + { + "nativeSrc": "5715:36:109", + "nodeType": "YulAssignment", + "src": "5715:36:109", + "value": { + "arguments": [ + { + "name": "offset", + "nativeSrc": "5732:6:109", + "nodeType": "YulIdentifier", + "src": "5732:6:109" + }, + { + "name": "startIndex", + "nativeSrc": "5740:10:109", + "nodeType": "YulIdentifier", + "src": "5740:10:109" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "5728:3:109", + "nodeType": "YulIdentifier", + "src": "5728:3:109" + }, + "nativeSrc": "5728:23:109", + "nodeType": "YulFunctionCall", + "src": "5728:23:109" + }, + "variableNames": [ + { + "name": "offsetOut", + "nativeSrc": "5715:9:109", + "nodeType": "YulIdentifier", + "src": "5715:9:109" + } + ] + }, + { + "nativeSrc": "5760:38:109", + "nodeType": "YulAssignment", + "src": "5760:38:109", + "value": { + "arguments": [ + { + "name": "endIndex", + "nativeSrc": "5777:8:109", + "nodeType": "YulIdentifier", + "src": "5777:8:109" + }, + { + "name": "startIndex", + "nativeSrc": "5787:10:109", + "nodeType": "YulIdentifier", + "src": "5787:10:109" + } + ], + "functionName": { + "name": "sub", + "nativeSrc": "5773:3:109", + "nodeType": "YulIdentifier", + "src": "5773:3:109" + }, + "nativeSrc": "5773:25:109", + "nodeType": "YulFunctionCall", + "src": "5773:25:109" + }, + "variableNames": [ + { + "name": "lengthOut", + "nativeSrc": "5760:9:109", + "nodeType": "YulIdentifier", + "src": "5760:9:109" + } + ] + } + ] + }, + "name": "calldata_array_index_range_access_t_bytes_calldata_ptr", + "nativeSrc": "5473:331:109", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "offset", + "nativeSrc": "5537:6:109", + "nodeType": "YulTypedName", + "src": "5537:6:109", + "type": "" + }, + { + "name": "length", + "nativeSrc": "5545:6:109", + "nodeType": "YulTypedName", + "src": "5545:6:109", + "type": "" + }, + { + "name": "startIndex", + "nativeSrc": "5553:10:109", + "nodeType": "YulTypedName", + "src": "5553:10:109", + "type": "" + }, + { + "name": "endIndex", + "nativeSrc": "5565:8:109", + "nodeType": "YulTypedName", + "src": "5565:8:109", + "type": "" + } + ], + "returnVariables": [ + { + "name": "offsetOut", + "nativeSrc": "5578:9:109", + "nodeType": "YulTypedName", + "src": "5578:9:109", + "type": "" + }, + { + "name": "lengthOut", + "nativeSrc": "5589:9:109", + "nodeType": "YulTypedName", + "src": "5589:9:109", + "type": "" + } + ], + "src": "5473:331:109" + }, + { + "body": { + "nativeSrc": "5962:124:109", + "nodeType": "YulBlock", + "src": "5962:124:109", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "pos", + "nativeSrc": "5985:3:109", + "nodeType": "YulIdentifier", + "src": "5985:3:109" + }, + { + "name": "value0", + "nativeSrc": "5990:6:109", + "nodeType": "YulIdentifier", + "src": "5990:6:109" + }, + { + "name": "value1", + "nativeSrc": "5998:6:109", + "nodeType": "YulIdentifier", + "src": "5998:6:109" + } + ], + "functionName": { + "name": "calldatacopy", + "nativeSrc": "5972:12:109", + "nodeType": "YulIdentifier", + "src": "5972:12:109" + }, + "nativeSrc": "5972:33:109", + "nodeType": "YulFunctionCall", + "src": "5972:33:109" + }, + "nativeSrc": "5972:33:109", + "nodeType": "YulExpressionStatement", + "src": "5972:33:109" + }, + { + "nativeSrc": "6014:26:109", + "nodeType": "YulVariableDeclaration", + "src": "6014:26:109", + "value": { + "arguments": [ + { + "name": "pos", + "nativeSrc": "6028:3:109", + "nodeType": "YulIdentifier", + "src": "6028:3:109" + }, + { + "name": "value1", + "nativeSrc": "6033:6:109", + "nodeType": "YulIdentifier", + "src": "6033:6:109" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "6024:3:109", + "nodeType": "YulIdentifier", + "src": "6024:3:109" + }, + "nativeSrc": "6024:16:109", + "nodeType": "YulFunctionCall", + "src": "6024:16:109" + }, + "variables": [ + { + "name": "_1", + "nativeSrc": "6018:2:109", + "nodeType": "YulTypedName", + "src": "6018:2:109", + "type": "" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "_1", + "nativeSrc": "6056:2:109", + "nodeType": "YulIdentifier", + "src": "6056:2:109" + }, + { + "kind": "number", + "nativeSrc": "6060:1:109", + "nodeType": "YulLiteral", + "src": "6060:1:109", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "mstore", + "nativeSrc": "6049:6:109", + "nodeType": "YulIdentifier", + "src": "6049:6:109" + }, + "nativeSrc": "6049:13:109", + "nodeType": "YulFunctionCall", + "src": "6049:13:109" + }, + "nativeSrc": "6049:13:109", + "nodeType": "YulExpressionStatement", + "src": "6049:13:109" + }, + { + "nativeSrc": "6071:9:109", + "nodeType": "YulAssignment", + "src": "6071:9:109", + "value": { + "name": "_1", + "nativeSrc": "6078:2:109", + "nodeType": "YulIdentifier", + "src": "6078:2:109" + }, + "variableNames": [ + { + "name": "end", + "nativeSrc": "6071:3:109", + "nodeType": "YulIdentifier", + "src": "6071:3:109" + } + ] + } + ] + }, + "name": "abi_encode_tuple_packed_t_bytes_calldata_ptr_slice__to_t_bytes_memory_ptr__nonPadded_inplace_fromStack_reversed", + "nativeSrc": "5809:277:109", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "pos", + "nativeSrc": "5930:3:109", + "nodeType": "YulTypedName", + "src": "5930:3:109", + "type": "" + }, + { + "name": "value1", + "nativeSrc": "5935:6:109", + "nodeType": "YulTypedName", + "src": "5935:6:109", + "type": "" + }, + { + "name": "value0", + "nativeSrc": "5943:6:109", + "nodeType": "YulTypedName", + "src": "5943:6:109", + "type": "" + } + ], + "returnVariables": [ + { + "name": "end", + "nativeSrc": "5954:3:109", + "nodeType": "YulTypedName", + "src": "5954:3:109", + "type": "" + } + ], + "src": "5809:277:109" + }, + { + "body": { + "nativeSrc": "6220:318:109", + "nodeType": "YulBlock", + "src": "6220:318:109", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nativeSrc": "6237:9:109", + "nodeType": "YulIdentifier", + "src": "6237:9:109" + }, + { + "kind": "number", + "nativeSrc": "6248:2:109", + "nodeType": "YulLiteral", + "src": "6248:2:109", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "mstore", + "nativeSrc": "6230:6:109", + "nodeType": "YulIdentifier", + "src": "6230:6:109" + }, + "nativeSrc": "6230:21:109", + "nodeType": "YulFunctionCall", + "src": "6230:21:109" + }, + "nativeSrc": "6230:21:109", + "nodeType": "YulExpressionStatement", + "src": "6230:21:109" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nativeSrc": "6271:9:109", + "nodeType": "YulIdentifier", + "src": "6271:9:109" + }, + { + "kind": "number", + "nativeSrc": "6282:2:109", + "nodeType": "YulLiteral", + "src": "6282:2:109", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "6267:3:109", + "nodeType": "YulIdentifier", + "src": "6267:3:109" + }, + "nativeSrc": "6267:18:109", + "nodeType": "YulFunctionCall", + "src": "6267:18:109" + }, + { + "name": "value1", + "nativeSrc": "6287:6:109", + "nodeType": "YulIdentifier", + "src": "6287:6:109" + } + ], + "functionName": { + "name": "mstore", + "nativeSrc": "6260:6:109", + "nodeType": "YulIdentifier", + "src": "6260:6:109" + }, + "nativeSrc": "6260:34:109", + "nodeType": "YulFunctionCall", + "src": "6260:34:109" + }, + "nativeSrc": "6260:34:109", + "nodeType": "YulExpressionStatement", + "src": "6260:34:109" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nativeSrc": "6320:9:109", + "nodeType": "YulIdentifier", + "src": "6320:9:109" + }, + { + "kind": "number", + "nativeSrc": "6331:2:109", + "nodeType": "YulLiteral", + "src": "6331:2:109", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "6316:3:109", + "nodeType": "YulIdentifier", + "src": "6316:3:109" + }, + "nativeSrc": "6316:18:109", + "nodeType": "YulFunctionCall", + "src": "6316:18:109" + }, + { + "name": "value0", + "nativeSrc": "6336:6:109", + "nodeType": "YulIdentifier", + "src": "6336:6:109" + }, + { + "name": "value1", + "nativeSrc": "6344:6:109", + "nodeType": "YulIdentifier", + "src": "6344:6:109" + } + ], + "functionName": { + "name": "calldatacopy", + "nativeSrc": "6303:12:109", + "nodeType": "YulIdentifier", + "src": "6303:12:109" + }, + "nativeSrc": "6303:48:109", + "nodeType": "YulFunctionCall", + "src": "6303:48:109" + }, + "nativeSrc": "6303:48:109", + "nodeType": "YulExpressionStatement", + "src": "6303:48:109" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nativeSrc": "6375:9:109", + "nodeType": "YulIdentifier", + "src": "6375:9:109" + }, + { + "name": "value1", + "nativeSrc": "6386:6:109", + "nodeType": "YulIdentifier", + "src": "6386:6:109" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "6371:3:109", + "nodeType": "YulIdentifier", + "src": "6371:3:109" + }, + "nativeSrc": "6371:22:109", + "nodeType": "YulFunctionCall", + "src": "6371:22:109" + }, + { + "kind": "number", + "nativeSrc": "6395:2:109", + "nodeType": "YulLiteral", + "src": "6395:2:109", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "6367:3:109", + "nodeType": "YulIdentifier", + "src": "6367:3:109" + }, + "nativeSrc": "6367:31:109", + "nodeType": "YulFunctionCall", + "src": "6367:31:109" + }, + { + "kind": "number", + "nativeSrc": "6400:1:109", + "nodeType": "YulLiteral", + "src": "6400:1:109", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "mstore", + "nativeSrc": "6360:6:109", + "nodeType": "YulIdentifier", + "src": "6360:6:109" + }, + "nativeSrc": "6360:42:109", + "nodeType": "YulFunctionCall", + "src": "6360:42:109" + }, + "nativeSrc": "6360:42:109", + "nodeType": "YulExpressionStatement", + "src": "6360:42:109" + }, + { + "nativeSrc": "6411:121:109", + "nodeType": "YulAssignment", + "src": "6411:121:109", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nativeSrc": "6427:9:109", + "nodeType": "YulIdentifier", + "src": "6427:9:109" + }, + { + "arguments": [ + { + "arguments": [ + { + "name": "value1", + "nativeSrc": "6446:6:109", + "nodeType": "YulIdentifier", + "src": "6446:6:109" + }, + { + "kind": "number", + "nativeSrc": "6454:2:109", + "nodeType": "YulLiteral", + "src": "6454:2:109", + "type": "", + "value": "31" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "6442:3:109", + "nodeType": "YulIdentifier", + "src": "6442:3:109" + }, + "nativeSrc": "6442:15:109", + "nodeType": "YulFunctionCall", + "src": "6442:15:109" + }, + { + "kind": "number", + "nativeSrc": "6459:66:109", + "nodeType": "YulLiteral", + "src": "6459:66:109", + "type": "", + "value": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0" + } + ], + "functionName": { + "name": "and", + "nativeSrc": "6438:3:109", + "nodeType": "YulIdentifier", + "src": "6438:3:109" + }, + "nativeSrc": "6438:88:109", + "nodeType": "YulFunctionCall", + "src": "6438:88:109" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "6423:3:109", + "nodeType": "YulIdentifier", + "src": "6423:3:109" + }, + "nativeSrc": "6423:104:109", + "nodeType": "YulFunctionCall", + "src": "6423:104:109" + }, + { + "kind": "number", + "nativeSrc": "6529:2:109", + "nodeType": "YulLiteral", + "src": "6529:2:109", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "6419:3:109", + "nodeType": "YulIdentifier", + "src": "6419:3:109" + }, + "nativeSrc": "6419:113:109", + "nodeType": "YulFunctionCall", + "src": "6419:113:109" + }, + "variableNames": [ + { + "name": "tail", + "nativeSrc": "6411:4:109", + "nodeType": "YulIdentifier", + "src": "6411:4:109" + } + ] + } + ] + }, + "name": "abi_encode_tuple_t_bytes_calldata_ptr__to_t_bytes_memory_ptr__fromStack_reversed", + "nativeSrc": "6091:447:109", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nativeSrc": "6181:9:109", + "nodeType": "YulTypedName", + "src": "6181:9:109", + "type": "" + }, + { + "name": "value1", + "nativeSrc": "6192:6:109", + "nodeType": "YulTypedName", + "src": "6192:6:109", + "type": "" + }, + { + "name": "value0", + "nativeSrc": "6200:6:109", + "nodeType": "YulTypedName", + "src": "6200:6:109", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nativeSrc": "6211:4:109", + "nodeType": "YulTypedName", + "src": "6211:4:109", + "type": "" + } + ], + "src": "6091:447:109" + }, + { + "body": { + "nativeSrc": "6637:486:109", + "nodeType": "YulBlock", + "src": "6637:486:109", + "statements": [ + { + "nativeSrc": "6647:51:109", + "nodeType": "YulVariableDeclaration", + "src": "6647:51:109", + "value": { + "arguments": [ + { + "name": "ptr_to_tail", + "nativeSrc": "6686:11:109", + "nodeType": "YulIdentifier", + "src": "6686:11:109" + } + ], + "functionName": { + "name": "calldataload", + "nativeSrc": "6673:12:109", + "nodeType": "YulIdentifier", + "src": "6673:12:109" + }, + "nativeSrc": "6673:25:109", + "nodeType": "YulFunctionCall", + "src": "6673:25:109" + }, + "variables": [ + { + "name": "rel_offset_of_tail", + "nativeSrc": "6651:18:109", + "nodeType": "YulTypedName", + "src": "6651:18:109", + "type": "" + } + ] + }, + { + "body": { + "nativeSrc": "6846:16:109", + "nodeType": "YulBlock", + "src": "6846:16:109", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nativeSrc": "6855:1:109", + "nodeType": "YulLiteral", + "src": "6855:1:109", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nativeSrc": "6858:1:109", + "nodeType": "YulLiteral", + "src": "6858:1:109", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nativeSrc": "6848:6:109", + "nodeType": "YulIdentifier", + "src": "6848:6:109" + }, + "nativeSrc": "6848:12:109", + "nodeType": "YulFunctionCall", + "src": "6848:12:109" + }, + "nativeSrc": "6848:12:109", + "nodeType": "YulExpressionStatement", + "src": "6848:12:109" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "rel_offset_of_tail", + "nativeSrc": "6721:18:109", + "nodeType": "YulIdentifier", + "src": "6721:18:109" + }, + { + "arguments": [ + { + "arguments": [ + { + "arguments": [], + "functionName": { + "name": "calldatasize", + "nativeSrc": "6749:12:109", + "nodeType": "YulIdentifier", + "src": "6749:12:109" + }, + "nativeSrc": "6749:14:109", + "nodeType": "YulFunctionCall", + "src": "6749:14:109" + }, + { + "name": "base_ref", + "nativeSrc": "6765:8:109", + "nodeType": "YulIdentifier", + "src": "6765:8:109" + } + ], + "functionName": { + "name": "sub", + "nativeSrc": "6745:3:109", + "nodeType": "YulIdentifier", + "src": "6745:3:109" + }, + "nativeSrc": "6745:29:109", + "nodeType": "YulFunctionCall", + "src": "6745:29:109" + }, + { + "kind": "number", + "nativeSrc": "6776:66:109", + "nodeType": "YulLiteral", + "src": "6776:66:109", + "type": "", + "value": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "6741:3:109", + "nodeType": "YulIdentifier", + "src": "6741:3:109" + }, + "nativeSrc": "6741:102:109", + "nodeType": "YulFunctionCall", + "src": "6741:102:109" + } + ], + "functionName": { + "name": "slt", + "nativeSrc": "6717:3:109", + "nodeType": "YulIdentifier", + "src": "6717:3:109" + }, + "nativeSrc": "6717:127:109", + "nodeType": "YulFunctionCall", + "src": "6717:127:109" + } + ], + "functionName": { + "name": "iszero", + "nativeSrc": "6710:6:109", + "nodeType": "YulIdentifier", + "src": "6710:6:109" + }, + "nativeSrc": "6710:135:109", + "nodeType": "YulFunctionCall", + "src": "6710:135:109" + }, + "nativeSrc": "6707:155:109", + "nodeType": "YulIf", + "src": "6707:155:109" + }, + { + "nativeSrc": "6871:47:109", + "nodeType": "YulVariableDeclaration", + "src": "6871:47:109", + "value": { + "arguments": [ + { + "name": "base_ref", + "nativeSrc": "6889:8:109", + "nodeType": "YulIdentifier", + "src": "6889:8:109" + }, + { + "name": "rel_offset_of_tail", + "nativeSrc": "6899:18:109", + "nodeType": "YulIdentifier", + "src": "6899:18:109" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "6885:3:109", + "nodeType": "YulIdentifier", + "src": "6885:3:109" + }, + "nativeSrc": "6885:33:109", + "nodeType": "YulFunctionCall", + "src": "6885:33:109" + }, + "variables": [ + { + "name": "addr_1", + "nativeSrc": "6875:6:109", + "nodeType": "YulTypedName", + "src": "6875:6:109", + "type": "" + } + ] + }, + { + "nativeSrc": "6927:30:109", + "nodeType": "YulAssignment", + "src": "6927:30:109", + "value": { + "arguments": [ + { + "name": "addr_1", + "nativeSrc": "6950:6:109", + "nodeType": "YulIdentifier", + "src": "6950:6:109" + } + ], + "functionName": { + "name": "calldataload", + "nativeSrc": "6937:12:109", + "nodeType": "YulIdentifier", + "src": "6937:12:109" + }, + "nativeSrc": "6937:20:109", + "nodeType": "YulFunctionCall", + "src": "6937:20:109" + }, + "variableNames": [ + { + "name": "length", + "nativeSrc": "6927:6:109", + "nodeType": "YulIdentifier", + "src": "6927:6:109" + } + ] + }, + { + "body": { + "nativeSrc": "7000:16:109", + "nodeType": "YulBlock", + "src": "7000:16:109", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nativeSrc": "7009:1:109", + "nodeType": "YulLiteral", + "src": "7009:1:109", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nativeSrc": "7012:1:109", + "nodeType": "YulLiteral", + "src": "7012:1:109", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nativeSrc": "7002:6:109", + "nodeType": "YulIdentifier", + "src": "7002:6:109" + }, + "nativeSrc": "7002:12:109", + "nodeType": "YulFunctionCall", + "src": "7002:12:109" + }, + "nativeSrc": "7002:12:109", + "nodeType": "YulExpressionStatement", + "src": "7002:12:109" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "length", + "nativeSrc": "6972:6:109", + "nodeType": "YulIdentifier", + "src": "6972:6:109" + }, + { + "kind": "number", + "nativeSrc": "6980:18:109", + "nodeType": "YulLiteral", + "src": "6980:18:109", + "type": "", + "value": "0xffffffffffffffff" + } + ], + "functionName": { + "name": "gt", + "nativeSrc": "6969:2:109", + "nodeType": "YulIdentifier", + "src": "6969:2:109" + }, + "nativeSrc": "6969:30:109", + "nodeType": "YulFunctionCall", + "src": "6969:30:109" + }, + "nativeSrc": "6966:50:109", + "nodeType": "YulIf", + "src": "6966:50:109" + }, + { + "nativeSrc": "7025:25:109", + "nodeType": "YulAssignment", + "src": "7025:25:109", + "value": { + "arguments": [ + { + "name": "addr_1", + "nativeSrc": "7037:6:109", + "nodeType": "YulIdentifier", + "src": "7037:6:109" + }, + { + "kind": "number", + "nativeSrc": "7045:4:109", + "nodeType": "YulLiteral", + "src": "7045:4:109", + "type": "", + "value": "0x20" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "7033:3:109", + "nodeType": "YulIdentifier", + "src": "7033:3:109" + }, + "nativeSrc": "7033:17:109", + "nodeType": "YulFunctionCall", + "src": "7033:17:109" + }, + "variableNames": [ + { + "name": "addr", + "nativeSrc": "7025:4:109", + "nodeType": "YulIdentifier", + "src": "7025:4:109" + } + ] + }, + { + "body": { + "nativeSrc": "7101:16:109", + "nodeType": "YulBlock", + "src": "7101:16:109", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nativeSrc": "7110:1:109", + "nodeType": "YulLiteral", + "src": "7110:1:109", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nativeSrc": "7113:1:109", + "nodeType": "YulLiteral", + "src": "7113:1:109", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nativeSrc": "7103:6:109", + "nodeType": "YulIdentifier", + "src": "7103:6:109" + }, + "nativeSrc": "7103:12:109", + "nodeType": "YulFunctionCall", + "src": "7103:12:109" + }, + "nativeSrc": "7103:12:109", + "nodeType": "YulExpressionStatement", + "src": "7103:12:109" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "addr", + "nativeSrc": "7066:4:109", + "nodeType": "YulIdentifier", + "src": "7066:4:109" + }, + { + "arguments": [ + { + "arguments": [], + "functionName": { + "name": "calldatasize", + "nativeSrc": "7076:12:109", + "nodeType": "YulIdentifier", + "src": "7076:12:109" + }, + "nativeSrc": "7076:14:109", + "nodeType": "YulFunctionCall", + "src": "7076:14:109" + }, + { + "name": "length", + "nativeSrc": "7092:6:109", + "nodeType": "YulIdentifier", + "src": "7092:6:109" + } + ], + "functionName": { + "name": "sub", + "nativeSrc": "7072:3:109", + "nodeType": "YulIdentifier", + "src": "7072:3:109" + }, + "nativeSrc": "7072:27:109", + "nodeType": "YulFunctionCall", + "src": "7072:27:109" + } + ], + "functionName": { + "name": "sgt", + "nativeSrc": "7062:3:109", + "nodeType": "YulIdentifier", + "src": "7062:3:109" + }, + "nativeSrc": "7062:38:109", + "nodeType": "YulFunctionCall", + "src": "7062:38:109" + }, + "nativeSrc": "7059:58:109", + "nodeType": "YulIf", + "src": "7059:58:109" + } + ] + }, + "name": "access_calldata_tail_t_bytes_calldata_ptr", + "nativeSrc": "6543:580:109", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "base_ref", + "nativeSrc": "6594:8:109", + "nodeType": "YulTypedName", + "src": "6594:8:109", + "type": "" + }, + { + "name": "ptr_to_tail", + "nativeSrc": "6604:11:109", + "nodeType": "YulTypedName", + "src": "6604:11:109", + "type": "" + } + ], + "returnVariables": [ + { + "name": "addr", + "nativeSrc": "6620:4:109", + "nodeType": "YulTypedName", + "src": "6620:4:109", + "type": "" + }, + { + "name": "length", + "nativeSrc": "6626:6:109", + "nodeType": "YulTypedName", + "src": "6626:6:109", + "type": "" + } + ], + "src": "6543:580:109" + }, + { + "body": { + "nativeSrc": "7160:152:109", + "nodeType": "YulBlock", + "src": "7160:152:109", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nativeSrc": "7177:1:109", + "nodeType": "YulLiteral", + "src": "7177:1:109", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nativeSrc": "7180:77:109", + "nodeType": "YulLiteral", + "src": "7180:77:109", + "type": "", + "value": "35408467139433450592217433187231851964531694900788300625387963629091585785856" + } + ], + "functionName": { + "name": "mstore", + "nativeSrc": "7170:6:109", + "nodeType": "YulIdentifier", + "src": "7170:6:109" + }, + "nativeSrc": "7170:88:109", + "nodeType": "YulFunctionCall", + "src": "7170:88:109" + }, + "nativeSrc": "7170:88:109", + "nodeType": "YulExpressionStatement", + "src": "7170:88:109" + }, + { + "expression": { + "arguments": [ + { + "kind": "number", + "nativeSrc": "7274:1:109", + "nodeType": "YulLiteral", + "src": "7274:1:109", + "type": "", + "value": "4" + }, + { + "kind": "number", + "nativeSrc": "7277:4:109", + "nodeType": "YulLiteral", + "src": "7277:4:109", + "type": "", + "value": "0x21" + } + ], + "functionName": { + "name": "mstore", + "nativeSrc": "7267:6:109", + "nodeType": "YulIdentifier", + "src": "7267:6:109" + }, + "nativeSrc": "7267:15:109", + "nodeType": "YulFunctionCall", + "src": "7267:15:109" + }, + "nativeSrc": "7267:15:109", + "nodeType": "YulExpressionStatement", + "src": "7267:15:109" + }, + { + "expression": { + "arguments": [ + { + "kind": "number", + "nativeSrc": "7298:1:109", + "nodeType": "YulLiteral", + "src": "7298:1:109", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nativeSrc": "7301:4:109", + "nodeType": "YulLiteral", + "src": "7301:4:109", + "type": "", + "value": "0x24" + } + ], + "functionName": { + "name": "revert", + "nativeSrc": "7291:6:109", + "nodeType": "YulIdentifier", + "src": "7291:6:109" + }, + "nativeSrc": "7291:15:109", + "nodeType": "YulFunctionCall", + "src": "7291:15:109" + }, + "nativeSrc": "7291:15:109", + "nodeType": "YulExpressionStatement", + "src": "7291:15:109" + } + ] + }, + "name": "panic_error_0x21", + "nativeSrc": "7128:184:109", + "nodeType": "YulFunctionDefinition", + "src": "7128:184:109" + }, + { + "body": { + "nativeSrc": "7491:174:109", + "nodeType": "YulBlock", + "src": "7491:174:109", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nativeSrc": "7508:9:109", + "nodeType": "YulIdentifier", + "src": "7508:9:109" + }, + { + "kind": "number", + "nativeSrc": "7519:2:109", + "nodeType": "YulLiteral", + "src": "7519:2:109", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "mstore", + "nativeSrc": "7501:6:109", + "nodeType": "YulIdentifier", + "src": "7501:6:109" + }, + "nativeSrc": "7501:21:109", + "nodeType": "YulFunctionCall", + "src": "7501:21:109" + }, + "nativeSrc": "7501:21:109", + "nodeType": "YulExpressionStatement", + "src": "7501:21:109" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nativeSrc": "7542:9:109", + "nodeType": "YulIdentifier", + "src": "7542:9:109" + }, + { + "kind": "number", + "nativeSrc": "7553:2:109", + "nodeType": "YulLiteral", + "src": "7553:2:109", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "7538:3:109", + "nodeType": "YulIdentifier", + "src": "7538:3:109" + }, + "nativeSrc": "7538:18:109", + "nodeType": "YulFunctionCall", + "src": "7538:18:109" + }, + { + "kind": "number", + "nativeSrc": "7558:2:109", + "nodeType": "YulLiteral", + "src": "7558:2:109", + "type": "", + "value": "24" + } + ], + "functionName": { + "name": "mstore", + "nativeSrc": "7531:6:109", + "nodeType": "YulIdentifier", + "src": "7531:6:109" + }, + "nativeSrc": "7531:30:109", + "nodeType": "YulFunctionCall", + "src": "7531:30:109" + }, + "nativeSrc": "7531:30:109", + "nodeType": "YulExpressionStatement", + "src": "7531:30:109" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nativeSrc": "7581:9:109", + "nodeType": "YulIdentifier", + "src": "7581:9:109" + }, + { + "kind": "number", + "nativeSrc": "7592:2:109", + "nodeType": "YulLiteral", + "src": "7592:2:109", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "7577:3:109", + "nodeType": "YulIdentifier", + "src": "7577:3:109" + }, + "nativeSrc": "7577:18:109", + "nodeType": "YulFunctionCall", + "src": "7577:18:109" + }, + { + "hexValue": "45434453413a20696e76616c6964207369676e6174757265", + "kind": "string", + "nativeSrc": "7597:26:109", + "nodeType": "YulLiteral", + "src": "7597:26:109", + "type": "", + "value": "ECDSA: invalid signature" + } + ], + "functionName": { + "name": "mstore", + "nativeSrc": "7570:6:109", + "nodeType": "YulIdentifier", + "src": "7570:6:109" + }, + "nativeSrc": "7570:54:109", + "nodeType": "YulFunctionCall", + "src": "7570:54:109" + }, + "nativeSrc": "7570:54:109", + "nodeType": "YulExpressionStatement", + "src": "7570:54:109" + }, + { + "nativeSrc": "7633:26:109", + "nodeType": "YulAssignment", + "src": "7633:26:109", + "value": { + "arguments": [ + { + "name": "headStart", + "nativeSrc": "7645:9:109", + "nodeType": "YulIdentifier", + "src": "7645:9:109" + }, + { + "kind": "number", + "nativeSrc": "7656:2:109", + "nodeType": "YulLiteral", + "src": "7656:2:109", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "7641:3:109", + "nodeType": "YulIdentifier", + "src": "7641:3:109" + }, + "nativeSrc": "7641:18:109", + "nodeType": "YulFunctionCall", + "src": "7641:18:109" + }, + "variableNames": [ + { + "name": "tail", + "nativeSrc": "7633:4:109", + "nodeType": "YulIdentifier", + "src": "7633:4:109" + } + ] + } + ] + }, + "name": "abi_encode_tuple_t_stringliteral_00043f6bf76368aa97c21698e9b9d4779e31902453daccf3525ddfb36e53e2be__to_t_string_memory_ptr__fromStack_reversed", + "nativeSrc": "7317:348:109", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nativeSrc": "7468:9:109", + "nodeType": "YulTypedName", + "src": "7468:9:109", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nativeSrc": "7482:4:109", + "nodeType": "YulTypedName", + "src": "7482:4:109", + "type": "" + } + ], + "src": "7317:348:109" + }, + { + "body": { + "nativeSrc": "7844:181:109", + "nodeType": "YulBlock", + "src": "7844:181:109", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nativeSrc": "7861:9:109", + "nodeType": "YulIdentifier", + "src": "7861:9:109" + }, + { + "kind": "number", + "nativeSrc": "7872:2:109", + "nodeType": "YulLiteral", + "src": "7872:2:109", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "mstore", + "nativeSrc": "7854:6:109", + "nodeType": "YulIdentifier", + "src": "7854:6:109" + }, + "nativeSrc": "7854:21:109", + "nodeType": "YulFunctionCall", + "src": "7854:21:109" + }, + "nativeSrc": "7854:21:109", + "nodeType": "YulExpressionStatement", + "src": "7854:21:109" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nativeSrc": "7895:9:109", + "nodeType": "YulIdentifier", + "src": "7895:9:109" + }, + { + "kind": "number", + "nativeSrc": "7906:2:109", + "nodeType": "YulLiteral", + "src": "7906:2:109", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "7891:3:109", + "nodeType": "YulIdentifier", + "src": "7891:3:109" + }, + "nativeSrc": "7891:18:109", + "nodeType": "YulFunctionCall", + "src": "7891:18:109" + }, + { + "kind": "number", + "nativeSrc": "7911:2:109", + "nodeType": "YulLiteral", + "src": "7911:2:109", + "type": "", + "value": "31" + } + ], + "functionName": { + "name": "mstore", + "nativeSrc": "7884:6:109", + "nodeType": "YulIdentifier", + "src": "7884:6:109" + }, + "nativeSrc": "7884:30:109", + "nodeType": "YulFunctionCall", + "src": "7884:30:109" + }, + "nativeSrc": "7884:30:109", + "nodeType": "YulExpressionStatement", + "src": "7884:30:109" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nativeSrc": "7934:9:109", + "nodeType": "YulIdentifier", + "src": "7934:9:109" + }, + { + "kind": "number", + "nativeSrc": "7945:2:109", + "nodeType": "YulLiteral", + "src": "7945:2:109", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "7930:3:109", + "nodeType": "YulIdentifier", + "src": "7930:3:109" + }, + "nativeSrc": "7930:18:109", + "nodeType": "YulFunctionCall", + "src": "7930:18:109" + }, + { + "hexValue": "45434453413a20696e76616c6964207369676e6174757265206c656e677468", + "kind": "string", + "nativeSrc": "7950:33:109", + "nodeType": "YulLiteral", + "src": "7950:33:109", + "type": "", + "value": "ECDSA: invalid signature length" + } + ], + "functionName": { + "name": "mstore", + "nativeSrc": "7923:6:109", + "nodeType": "YulIdentifier", + "src": "7923:6:109" + }, + "nativeSrc": "7923:61:109", + "nodeType": "YulFunctionCall", + "src": "7923:61:109" + }, + "nativeSrc": "7923:61:109", + "nodeType": "YulExpressionStatement", + "src": "7923:61:109" + }, + { + "nativeSrc": "7993:26:109", + "nodeType": "YulAssignment", + "src": "7993:26:109", + "value": { + "arguments": [ + { + "name": "headStart", + "nativeSrc": "8005:9:109", + "nodeType": "YulIdentifier", + "src": "8005:9:109" + }, + { + "kind": "number", + "nativeSrc": "8016:2:109", + "nodeType": "YulLiteral", + "src": "8016:2:109", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "8001:3:109", + "nodeType": "YulIdentifier", + "src": "8001:3:109" + }, + "nativeSrc": "8001:18:109", + "nodeType": "YulFunctionCall", + "src": "8001:18:109" + }, + "variableNames": [ + { + "name": "tail", + "nativeSrc": "7993:4:109", + "nodeType": "YulIdentifier", + "src": "7993:4:109" + } + ] + } + ] + }, + "name": "abi_encode_tuple_t_stringliteral_1669ff3ba3cdf64474e1193492d05b8434e29b0b495e60095eb5f5c8ec14ce77__to_t_string_memory_ptr__fromStack_reversed", + "nativeSrc": "7670:355:109", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nativeSrc": "7821:9:109", + "nodeType": "YulTypedName", + "src": "7821:9:109", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nativeSrc": "7835:4:109", + "nodeType": "YulTypedName", + "src": "7835:4:109", + "type": "" + } + ], + "src": "7670:355:109" + }, + { + "body": { + "nativeSrc": "8204:224:109", + "nodeType": "YulBlock", + "src": "8204:224:109", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nativeSrc": "8221:9:109", + "nodeType": "YulIdentifier", + "src": "8221:9:109" + }, + { + "kind": "number", + "nativeSrc": "8232:2:109", + "nodeType": "YulLiteral", + "src": "8232:2:109", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "mstore", + "nativeSrc": "8214:6:109", + "nodeType": "YulIdentifier", + "src": "8214:6:109" + }, + "nativeSrc": "8214:21:109", + "nodeType": "YulFunctionCall", + "src": "8214:21:109" + }, + "nativeSrc": "8214:21:109", + "nodeType": "YulExpressionStatement", + "src": "8214:21:109" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nativeSrc": "8255:9:109", + "nodeType": "YulIdentifier", + "src": "8255:9:109" + }, + { + "kind": "number", + "nativeSrc": "8266:2:109", + "nodeType": "YulLiteral", + "src": "8266:2:109", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "8251:3:109", + "nodeType": "YulIdentifier", + "src": "8251:3:109" + }, + "nativeSrc": "8251:18:109", + "nodeType": "YulFunctionCall", + "src": "8251:18:109" + }, + { + "kind": "number", + "nativeSrc": "8271:2:109", + "nodeType": "YulLiteral", + "src": "8271:2:109", + "type": "", + "value": "34" + } + ], + "functionName": { + "name": "mstore", + "nativeSrc": "8244:6:109", + "nodeType": "YulIdentifier", + "src": "8244:6:109" + }, + "nativeSrc": "8244:30:109", + "nodeType": "YulFunctionCall", + "src": "8244:30:109" + }, + "nativeSrc": "8244:30:109", + "nodeType": "YulExpressionStatement", + "src": "8244:30:109" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nativeSrc": "8294:9:109", + "nodeType": "YulIdentifier", + "src": "8294:9:109" + }, + { + "kind": "number", + "nativeSrc": "8305:2:109", + "nodeType": "YulLiteral", + "src": "8305:2:109", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "8290:3:109", + "nodeType": "YulIdentifier", + "src": "8290:3:109" + }, + "nativeSrc": "8290:18:109", + "nodeType": "YulFunctionCall", + "src": "8290:18:109" + }, + { + "hexValue": "45434453413a20696e76616c6964207369676e6174757265202773272076616c", + "kind": "string", + "nativeSrc": "8310:34:109", + "nodeType": "YulLiteral", + "src": "8310:34:109", + "type": "", + "value": "ECDSA: invalid signature 's' val" + } + ], + "functionName": { + "name": "mstore", + "nativeSrc": "8283:6:109", + "nodeType": "YulIdentifier", + "src": "8283:6:109" + }, + "nativeSrc": "8283:62:109", + "nodeType": "YulFunctionCall", + "src": "8283:62:109" + }, + "nativeSrc": "8283:62:109", + "nodeType": "YulExpressionStatement", + "src": "8283:62:109" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nativeSrc": "8365:9:109", + "nodeType": "YulIdentifier", + "src": "8365:9:109" + }, + { + "kind": "number", + "nativeSrc": "8376:2:109", + "nodeType": "YulLiteral", + "src": "8376:2:109", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "8361:3:109", + "nodeType": "YulIdentifier", + "src": "8361:3:109" + }, + "nativeSrc": "8361:18:109", + "nodeType": "YulFunctionCall", + "src": "8361:18:109" + }, + { + "hexValue": "7565", + "kind": "string", + "nativeSrc": "8381:4:109", + "nodeType": "YulLiteral", + "src": "8381:4:109", + "type": "", + "value": "ue" + } + ], + "functionName": { + "name": "mstore", + "nativeSrc": "8354:6:109", + "nodeType": "YulIdentifier", + "src": "8354:6:109" + }, + "nativeSrc": "8354:32:109", + "nodeType": "YulFunctionCall", + "src": "8354:32:109" + }, + "nativeSrc": "8354:32:109", + "nodeType": "YulExpressionStatement", + "src": "8354:32:109" + }, + { + "nativeSrc": "8395:27:109", + "nodeType": "YulAssignment", + "src": "8395:27:109", + "value": { + "arguments": [ + { + "name": "headStart", + "nativeSrc": "8407:9:109", + "nodeType": "YulIdentifier", + "src": "8407:9:109" + }, + { + "kind": "number", + "nativeSrc": "8418:3:109", + "nodeType": "YulLiteral", + "src": "8418:3:109", + "type": "", + "value": "128" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "8403:3:109", + "nodeType": "YulIdentifier", + "src": "8403:3:109" + }, + "nativeSrc": "8403:19:109", + "nodeType": "YulFunctionCall", + "src": "8403:19:109" + }, + "variableNames": [ + { + "name": "tail", + "nativeSrc": "8395:4:109", + "nodeType": "YulIdentifier", + "src": "8395:4:109" + } + ] + } + ] + }, + "name": "abi_encode_tuple_t_stringliteral_520d1f787dbcafbbfc007fd2c4ecf3d2711ec587f3ee9a1215c0b646c3e530bd__to_t_string_memory_ptr__fromStack_reversed", + "nativeSrc": "8030:398:109", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nativeSrc": "8181:9:109", + "nodeType": "YulTypedName", + "src": "8181:9:109", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nativeSrc": "8195:4:109", + "nodeType": "YulTypedName", + "src": "8195:4:109", + "type": "" + } + ], + "src": "8030:398:109" + }, + { + "body": { + "nativeSrc": "8614:217:109", + "nodeType": "YulBlock", + "src": "8614:217:109", + "statements": [ + { + "nativeSrc": "8624:27:109", + "nodeType": "YulAssignment", + "src": "8624:27:109", + "value": { + "arguments": [ + { + "name": "headStart", + "nativeSrc": "8636:9:109", + "nodeType": "YulIdentifier", + "src": "8636:9:109" + }, + { + "kind": "number", + "nativeSrc": "8647:3:109", + "nodeType": "YulLiteral", + "src": "8647:3:109", + "type": "", + "value": "128" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "8632:3:109", + "nodeType": "YulIdentifier", + "src": "8632:3:109" + }, + "nativeSrc": "8632:19:109", + "nodeType": "YulFunctionCall", + "src": "8632:19:109" + }, + "variableNames": [ + { + "name": "tail", + "nativeSrc": "8624:4:109", + "nodeType": "YulIdentifier", + "src": "8624:4:109" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nativeSrc": "8667:9:109", + "nodeType": "YulIdentifier", + "src": "8667:9:109" + }, + { + "name": "value0", + "nativeSrc": "8678:6:109", + "nodeType": "YulIdentifier", + "src": "8678:6:109" + } + ], + "functionName": { + "name": "mstore", + "nativeSrc": "8660:6:109", + "nodeType": "YulIdentifier", + "src": "8660:6:109" + }, + "nativeSrc": "8660:25:109", + "nodeType": "YulFunctionCall", + "src": "8660:25:109" + }, + "nativeSrc": "8660:25:109", + "nodeType": "YulExpressionStatement", + "src": "8660:25:109" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nativeSrc": "8705:9:109", + "nodeType": "YulIdentifier", + "src": "8705:9:109" + }, + { + "kind": "number", + "nativeSrc": "8716:2:109", + "nodeType": "YulLiteral", + "src": "8716:2:109", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "8701:3:109", + "nodeType": "YulIdentifier", + "src": "8701:3:109" + }, + "nativeSrc": "8701:18:109", + "nodeType": "YulFunctionCall", + "src": "8701:18:109" + }, + { + "arguments": [ + { + "name": "value1", + "nativeSrc": "8725:6:109", + "nodeType": "YulIdentifier", + "src": "8725:6:109" + }, + { + "kind": "number", + "nativeSrc": "8733:4:109", + "nodeType": "YulLiteral", + "src": "8733:4:109", + "type": "", + "value": "0xff" + } + ], + "functionName": { + "name": "and", + "nativeSrc": "8721:3:109", + "nodeType": "YulIdentifier", + "src": "8721:3:109" + }, + "nativeSrc": "8721:17:109", + "nodeType": "YulFunctionCall", + "src": "8721:17:109" + } + ], + "functionName": { + "name": "mstore", + "nativeSrc": "8694:6:109", + "nodeType": "YulIdentifier", + "src": "8694:6:109" + }, + "nativeSrc": "8694:45:109", + "nodeType": "YulFunctionCall", + "src": "8694:45:109" + }, + "nativeSrc": "8694:45:109", + "nodeType": "YulExpressionStatement", + "src": "8694:45:109" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nativeSrc": "8759:9:109", + "nodeType": "YulIdentifier", + "src": "8759:9:109" + }, + { + "kind": "number", + "nativeSrc": "8770:2:109", + "nodeType": "YulLiteral", + "src": "8770:2:109", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "8755:3:109", + "nodeType": "YulIdentifier", + "src": "8755:3:109" + }, + "nativeSrc": "8755:18:109", + "nodeType": "YulFunctionCall", + "src": "8755:18:109" + }, + { + "name": "value2", + "nativeSrc": "8775:6:109", + "nodeType": "YulIdentifier", + "src": "8775:6:109" + } + ], + "functionName": { + "name": "mstore", + "nativeSrc": "8748:6:109", + "nodeType": "YulIdentifier", + "src": "8748:6:109" + }, + "nativeSrc": "8748:34:109", + "nodeType": "YulFunctionCall", + "src": "8748:34:109" + }, + "nativeSrc": "8748:34:109", + "nodeType": "YulExpressionStatement", + "src": "8748:34:109" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nativeSrc": "8802:9:109", + "nodeType": "YulIdentifier", + "src": "8802:9:109" + }, + { + "kind": "number", + "nativeSrc": "8813:2:109", + "nodeType": "YulLiteral", + "src": "8813:2:109", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "8798:3:109", + "nodeType": "YulIdentifier", + "src": "8798:3:109" + }, + "nativeSrc": "8798:18:109", + "nodeType": "YulFunctionCall", + "src": "8798:18:109" + }, + { + "name": "value3", + "nativeSrc": "8818:6:109", + "nodeType": "YulIdentifier", + "src": "8818:6:109" + } + ], + "functionName": { + "name": "mstore", + "nativeSrc": "8791:6:109", + "nodeType": "YulIdentifier", + "src": "8791:6:109" + }, + "nativeSrc": "8791:34:109", + "nodeType": "YulFunctionCall", + "src": "8791:34:109" + }, + "nativeSrc": "8791:34:109", + "nodeType": "YulExpressionStatement", + "src": "8791:34:109" + } + ] + }, + "name": "abi_encode_tuple_t_bytes32_t_uint8_t_bytes32_t_bytes32__to_t_bytes32_t_uint8_t_bytes32_t_bytes32__fromStack_reversed", + "nativeSrc": "8433:398:109", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nativeSrc": "8559:9:109", + "nodeType": "YulTypedName", + "src": "8559:9:109", + "type": "" + }, + { + "name": "value3", + "nativeSrc": "8570:6:109", + "nodeType": "YulTypedName", + "src": "8570:6:109", + "type": "" + }, + { + "name": "value2", + "nativeSrc": "8578:6:109", + "nodeType": "YulTypedName", + "src": "8578:6:109", + "type": "" + }, + { + "name": "value1", + "nativeSrc": "8586:6:109", + "nodeType": "YulTypedName", + "src": "8586:6:109", + "type": "" + }, + { + "name": "value0", + "nativeSrc": "8594:6:109", + "nodeType": "YulTypedName", + "src": "8594:6:109", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nativeSrc": "8605:4:109", + "nodeType": "YulTypedName", + "src": "8605:4:109", + "type": "" + } + ], + "src": "8433:398:109" + } + ] + }, + "contents": "{\n { }\n function panic_error_0x41()\n {\n mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856)\n mstore(4, 0x41)\n revert(0, 0x24)\n }\n function abi_decode_bytes(offset, end) -> array\n {\n if iszero(slt(add(offset, 0x1f), end)) { revert(0, 0) }\n let _1 := calldataload(offset)\n let _2 := 0xffffffffffffffff\n if gt(_1, _2) { panic_error_0x41() }\n let _3 := 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0\n let memPtr := mload(64)\n let newFreePtr := add(memPtr, and(add(and(add(_1, 0x1f), _3), 63), _3))\n if or(gt(newFreePtr, _2), lt(newFreePtr, memPtr)) { panic_error_0x41() }\n mstore(64, newFreePtr)\n mstore(memPtr, _1)\n if gt(add(add(offset, _1), 0x20), end) { revert(0, 0) }\n calldatacopy(add(memPtr, 0x20), add(offset, 0x20), _1)\n mstore(add(add(memPtr, _1), 0x20), 0)\n array := memPtr\n }\n function abi_decode_tuple_t_bytes32t_bytes_memory_ptr(headStart, dataEnd) -> value0, value1\n {\n if slt(sub(dataEnd, headStart), 64) { revert(0, 0) }\n value0 := calldataload(headStart)\n let offset := calldataload(add(headStart, 32))\n if gt(offset, 0xffffffffffffffff) { revert(0, 0) }\n value1 := abi_decode_bytes(add(headStart, offset), dataEnd)\n }\n function abi_encode_tuple_t_bytes4__to_t_bytes4__fromStack_reversed(headStart, value0) -> tail\n {\n tail := add(headStart, 32)\n mstore(headStart, and(value0, 0xffffffff00000000000000000000000000000000000000000000000000000000))\n }\n function abi_decode_tuple_t_bytes_memory_ptr(headStart, dataEnd) -> value0\n {\n if slt(sub(dataEnd, headStart), 32) { revert(0, 0) }\n let offset := calldataload(headStart)\n if gt(offset, 0xffffffffffffffff) { revert(0, 0) }\n value0 := abi_decode_bytes(add(headStart, offset), dataEnd)\n }\n function abi_encode_tuple_t_bool__to_t_bool__fromStack_reversed(headStart, value0) -> tail\n {\n tail := add(headStart, 32)\n mstore(headStart, iszero(iszero(value0)))\n }\n function abi_encode_tuple_t_address__to_t_address__fromStack_reversed(headStart, value0) -> tail\n {\n tail := add(headStart, 32)\n mstore(headStart, and(value0, 0xffffffffffffffffffffffffffffffffffffffff))\n }\n function abi_encode_tuple_t_bytes_memory_ptr__to_t_bytes_memory_ptr__fromStack_reversed(headStart, value0) -> tail\n {\n let _1 := 32\n mstore(headStart, _1)\n let length := mload(value0)\n mstore(add(headStart, _1), length)\n let i := 0\n for { } lt(i, length) { i := add(i, _1) }\n {\n mstore(add(add(headStart, i), 64), mload(add(add(value0, i), _1)))\n }\n mstore(add(add(headStart, length), 64), 0)\n tail := add(add(headStart, and(add(length, 31), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0)), 64)\n }\n function abi_decode_struct_UserOperation_calldata(offset, end) -> value\n {\n if slt(sub(end, offset), 352) { revert(0, 0) }\n value := offset\n }\n function abi_decode_tuple_t_struct$_UserOperation_$12474_calldata_ptrt_bytes32(headStart, dataEnd) -> value0, value1\n {\n if slt(sub(dataEnd, headStart), 64) { revert(0, 0) }\n let offset := calldataload(headStart)\n if gt(offset, 0xffffffffffffffff) { revert(0, 0) }\n value0 := abi_decode_struct_UserOperation_calldata(add(headStart, offset), dataEnd)\n value1 := calldataload(add(headStart, 32))\n }\n function abi_encode_tuple_t_uint256__to_t_uint256__fromStack_reversed(headStart, value0) -> tail\n {\n tail := add(headStart, 32)\n mstore(headStart, value0)\n }\n function abi_decode_tuple_t_bytes_calldata_ptr(headStart, dataEnd) -> value0, value1\n {\n if slt(sub(dataEnd, headStart), 32) { revert(0, 0) }\n let offset := calldataload(headStart)\n let _1 := 0xffffffffffffffff\n if gt(offset, _1) { revert(0, 0) }\n let _2 := add(headStart, offset)\n if iszero(slt(add(_2, 0x1f), dataEnd)) { revert(0, 0) }\n let length := calldataload(_2)\n if gt(length, _1) { revert(0, 0) }\n if gt(add(add(_2, length), 32), dataEnd) { revert(0, 0) }\n value0 := add(_2, 32)\n value1 := length\n }\n function abi_decode_tuple_t_struct$_UserOperation_$12474_calldata_ptrt_bytes32t_address(headStart, dataEnd) -> value0, value1, value2\n {\n if slt(sub(dataEnd, headStart), 96) { revert(0, 0) }\n let offset := calldataload(headStart)\n if gt(offset, 0xffffffffffffffff) { revert(0, 0) }\n value0 := abi_decode_struct_UserOperation_calldata(add(headStart, offset), dataEnd)\n value1 := calldataload(add(headStart, 32))\n let value := calldataload(add(headStart, 64))\n if iszero(eq(value, and(value, 0xffffffffffffffffffffffffffffffffffffffff))) { revert(0, 0) }\n value2 := value\n }\n function panic_error_0x32()\n {\n mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856)\n mstore(4, 0x32)\n revert(0, 0x24)\n }\n function abi_encode_tuple_packed_t_address__to_t_address__nonPadded_inplace_fromStack_reversed(pos, value0) -> end\n {\n mstore(pos, and(shl(96, value0), 0xffffffffffffffffffffffffffffffffffffffff000000000000000000000000))\n end := add(pos, 20)\n }\n function calldata_array_index_range_access_t_bytes_calldata_ptr(offset, length, startIndex, endIndex) -> offsetOut, lengthOut\n {\n if gt(startIndex, endIndex) { revert(0, 0) }\n if gt(endIndex, length) { revert(0, 0) }\n offsetOut := add(offset, startIndex)\n lengthOut := sub(endIndex, startIndex)\n }\n function abi_encode_tuple_packed_t_bytes_calldata_ptr_slice__to_t_bytes_memory_ptr__nonPadded_inplace_fromStack_reversed(pos, value1, value0) -> end\n {\n calldatacopy(pos, value0, value1)\n let _1 := add(pos, value1)\n mstore(_1, 0)\n end := _1\n }\n function abi_encode_tuple_t_bytes_calldata_ptr__to_t_bytes_memory_ptr__fromStack_reversed(headStart, value1, value0) -> tail\n {\n mstore(headStart, 32)\n mstore(add(headStart, 32), value1)\n calldatacopy(add(headStart, 64), value0, value1)\n mstore(add(add(headStart, value1), 64), 0)\n tail := add(add(headStart, and(add(value1, 31), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0)), 64)\n }\n function access_calldata_tail_t_bytes_calldata_ptr(base_ref, ptr_to_tail) -> addr, length\n {\n let rel_offset_of_tail := calldataload(ptr_to_tail)\n if iszero(slt(rel_offset_of_tail, add(sub(calldatasize(), base_ref), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1))) { revert(0, 0) }\n let addr_1 := add(base_ref, rel_offset_of_tail)\n length := calldataload(addr_1)\n if gt(length, 0xffffffffffffffff) { revert(0, 0) }\n addr := add(addr_1, 0x20)\n if sgt(addr, sub(calldatasize(), length)) { revert(0, 0) }\n }\n function panic_error_0x21()\n {\n mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856)\n mstore(4, 0x21)\n revert(0, 0x24)\n }\n function abi_encode_tuple_t_stringliteral_00043f6bf76368aa97c21698e9b9d4779e31902453daccf3525ddfb36e53e2be__to_t_string_memory_ptr__fromStack_reversed(headStart) -> tail\n {\n mstore(headStart, 32)\n mstore(add(headStart, 32), 24)\n mstore(add(headStart, 64), \"ECDSA: invalid signature\")\n tail := add(headStart, 96)\n }\n function abi_encode_tuple_t_stringliteral_1669ff3ba3cdf64474e1193492d05b8434e29b0b495e60095eb5f5c8ec14ce77__to_t_string_memory_ptr__fromStack_reversed(headStart) -> tail\n {\n mstore(headStart, 32)\n mstore(add(headStart, 32), 31)\n mstore(add(headStart, 64), \"ECDSA: invalid signature length\")\n tail := add(headStart, 96)\n }\n function abi_encode_tuple_t_stringliteral_520d1f787dbcafbbfc007fd2c4ecf3d2711ec587f3ee9a1215c0b646c3e530bd__to_t_string_memory_ptr__fromStack_reversed(headStart) -> tail\n {\n mstore(headStart, 32)\n mstore(add(headStart, 32), 34)\n mstore(add(headStart, 64), \"ECDSA: invalid signature 's' val\")\n mstore(add(headStart, 96), \"ue\")\n tail := add(headStart, 128)\n }\n function abi_encode_tuple_t_bytes32_t_uint8_t_bytes32_t_bytes32__to_t_bytes32_t_uint8_t_bytes32_t_bytes32__fromStack_reversed(headStart, value3, value2, value1, value0) -> tail\n {\n tail := add(headStart, 128)\n mstore(headStart, value0)\n mstore(add(headStart, 32), and(value1, 0xff))\n mstore(add(headStart, 64), value2)\n mstore(add(headStart, 96), value3)\n }\n}", + "id": 109, + "language": "Yul", + "name": "#utility.yul" + } + ], + "immutableReferences": { + "22286": [ + { + "length": 32, + "start": 319 + }, + { + "length": 32, + "start": 1636 + } + ] + }, + "linkReferences": {}, + "object": "608060405234801561001057600080fd5b50600436106100a35760003560e01c80638da5cb5b11610076578063cd00e50a1161005b578063cd00e50a14610218578063cd9b47e414610220578063f45007c31461023357600080fd5b80638da5cb5b146101865780638dd50121146101f757600080fd5b80631626ba7e146100a85780633253960f146100f1578063392dd6d9146101175780637104ddb21461013a575b600080fd5b6100bb6100b6366004610de8565b610246565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020015b60405180910390f35b7f8dd50121000000000000000000000000000000000000000000000000000000006100bb565b61012a610125366004610e2f565b6102f4565b60405190151581526020016100e8565b6101617f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100e8565b7f9d0217145d12a316adea26b4f622aec07fb71e6638d613bb415476f4c179eecc546040805160609290921b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016602083015280518083036014018152603490920190526040516100e89190610e64565b61020a610205366004610ee9565b610366565b6040519081526020016100e8565b61020a6103b8565b61020a61022e366004610f2e565b6104d6565b61020a610241366004610fa0565b6107b7565b60007f9d0217145d12a316adea26b4f622aec07fb71e6638d613bb415476f4c179eecc5473ffffffffffffffffffffffffffffffffffffffff1661028a848461087c565b73ffffffffffffffffffffffffffffffffffffffff16146102cb577fffffffff000000000000000000000000000000000000000000000000000000006102ed565b7f1626ba7e000000000000000000000000000000000000000000000000000000005b9392505050565b60008151604114801561036057508160008151811061031557610315611014565b6020910101517fff00000000000000000000000000000000000000000000000000000000000000167f0400000000000000000000000000000000000000000000000000000000000000145b92915050565b7f9d0217145d12a316adea26b4f622aec07fb71e6638d613bb415476f4c179eecc8054600091906103b0908590859073ffffffffffffffffffffffffffffffffffffffff166107b7565b949350505050565b60006103c26108a0565b6103ca6108e0565b7f9d0217145d12a316adea26b4f622aec07fb71e6638d613bb415476f4c179eecc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001681556000610424600154610100900460e01b90565b7fffffffff00000000000000000000000000000000000000000000000000000000160361047d576040517f127c609a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff169055604051600192507fcccd30db6bc000b8bb8d11162228d2d69e3c361983ca3ae8c1365ce64b0fae9e90600090a15090565b60006104e061097f565b61051f83838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102f492505050565b610555576040517f22281e8500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f9d0217145d12a316adea26b4f622aec07fb71e6638d613bb415476f4c179eecc6105838360018187611043565b60405161059192919061106d565b60405190819003902081547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9091161781556001547f8dd501210000000000000000000000000000000000000000000000000000000090600090610100900460e01b7fffffffff000000000000000000000000000000000000000000000000000000001614610662576040517f5f95a63c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166106f3827fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604090205460601c90565b73ffffffffffffffffffffffffffffffffffffffff1614610740576040517fbb4752b700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff1661010060e084901c02179055600192507f6d54821a69ec281ed7ba1bf2729c700768c47df1d80fad646b0a14cc1d5c39ed85856040516107a792919061107d565b60405180910390a1505092915050565b7f19457468657265756d205369676e6564204d6573736167653a0a3332000000006000908152601c839052603c81206108346107f76101408701876110ca565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250859392505061087c9050565b73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361086d576000610870565b60015b60ff1695945050505050565b600080600061088b8585610a1f565b9150915061089881610a64565b509392505050565b6001805460ff16146108de576040517f38fc28cb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff16600114610948576040517fe00d7c7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff16156109e5576040517f7c2cde8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b6000808251604103610a555760208301516040840151606085015160001a610a4987828585610c1f565b94509450505050610a5d565b506000905060025b9250929050565b6000816004811115610a7857610a7861112f565b03610a805750565b6001816004811115610a9457610a9461112f565b03610b00576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064015b60405180910390fd5b6002816004811115610b1457610b1461112f565b03610b7b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610af7565b6003816004811115610b8f57610b8f61112f565b03610c1c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610af7565b50565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115610c565750600090506003610d05565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015610caa573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116610cfe57600060019250925050610d05565b9150600090505b94509492505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112610d4e57600080fd5b813567ffffffffffffffff80821115610d6957610d69610d0e565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715610daf57610daf610d0e565b81604052838152866020858801011115610dc857600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060408385031215610dfb57600080fd5b82359150602083013567ffffffffffffffff811115610e1957600080fd5b610e2585828601610d3d565b9150509250929050565b600060208284031215610e4157600080fd5b813567ffffffffffffffff811115610e5857600080fd5b6103b084828501610d3d565b600060208083528351808285015260005b81811015610e9157858101830151858201604001528201610e75565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b60006101608284031215610ee357600080fd5b50919050565b60008060408385031215610efc57600080fd5b823567ffffffffffffffff811115610f1357600080fd5b610f1f85828601610ed0565b95602094909401359450505050565b60008060208385031215610f4157600080fd5b823567ffffffffffffffff80821115610f5957600080fd5b818501915085601f830112610f6d57600080fd5b813581811115610f7c57600080fd5b866020828501011115610f8e57600080fd5b60209290920196919550909350505050565b600080600060608486031215610fb557600080fd5b833567ffffffffffffffff811115610fcc57600080fd5b610fd886828701610ed0565b93505060208401359150604084013573ffffffffffffffffffffffffffffffffffffffff8116811461100957600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000808585111561105357600080fd5b8386111561106057600080fd5b5050820193919092039150565b8183823760009101908152919050565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126110ff57600080fd5b83018035915067ffffffffffffffff82111561111a57600080fd5b602001915036819003821315610a5d57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea2646970667358221220de3368e3f3953432149ec8ab61e8db05409a34e6f3f223f6bc0a20072fa01cf364736f6c63430008150033", + "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0x10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x4 CALLDATASIZE LT PUSH2 0xA3 JUMPI PUSH1 0x0 CALLDATALOAD PUSH1 0xE0 SHR DUP1 PUSH4 0x8DA5CB5B GT PUSH2 0x76 JUMPI DUP1 PUSH4 0xCD00E50A GT PUSH2 0x5B JUMPI DUP1 PUSH4 0xCD00E50A EQ PUSH2 0x218 JUMPI DUP1 PUSH4 0xCD9B47E4 EQ PUSH2 0x220 JUMPI DUP1 PUSH4 0xF45007C3 EQ PUSH2 0x233 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 PUSH4 0x8DA5CB5B EQ PUSH2 0x186 JUMPI DUP1 PUSH4 0x8DD50121 EQ PUSH2 0x1F7 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 PUSH4 0x1626BA7E EQ PUSH2 0xA8 JUMPI DUP1 PUSH4 0x3253960F EQ PUSH2 0xF1 JUMPI DUP1 PUSH4 0x392DD6D9 EQ PUSH2 0x117 JUMPI DUP1 PUSH4 0x7104DDB2 EQ PUSH2 0x13A JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xBB PUSH2 0xB6 CALLDATASIZE PUSH1 0x4 PUSH2 0xDE8 JUMP JUMPDEST PUSH2 0x246 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 SWAP1 SWAP2 AND DUP2 MSTORE PUSH1 0x20 ADD JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH32 0x8DD5012100000000000000000000000000000000000000000000000000000000 PUSH2 0xBB JUMP JUMPDEST PUSH2 0x12A PUSH2 0x125 CALLDATASIZE PUSH1 0x4 PUSH2 0xE2F JUMP JUMPDEST PUSH2 0x2F4 JUMP JUMPDEST PUSH1 0x40 MLOAD SWAP1 ISZERO ISZERO DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0xE8 JUMP JUMPDEST PUSH2 0x161 PUSH32 0x0 DUP2 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP2 AND DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0xE8 JUMP JUMPDEST PUSH32 0x9D0217145D12A316ADEA26B4F622AEC07FB71E6638D613BB415476F4C179EECC SLOAD PUSH1 0x40 DUP1 MLOAD PUSH1 0x60 SWAP3 SWAP1 SWAP3 SHL PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000 AND PUSH1 0x20 DUP4 ADD MSTORE DUP1 MLOAD DUP1 DUP4 SUB PUSH1 0x14 ADD DUP2 MSTORE PUSH1 0x34 SWAP1 SWAP3 ADD SWAP1 MSTORE PUSH1 0x40 MLOAD PUSH2 0xE8 SWAP2 SWAP1 PUSH2 0xE64 JUMP JUMPDEST PUSH2 0x20A PUSH2 0x205 CALLDATASIZE PUSH1 0x4 PUSH2 0xEE9 JUMP JUMPDEST PUSH2 0x366 JUMP JUMPDEST PUSH1 0x40 MLOAD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0xE8 JUMP JUMPDEST PUSH2 0x20A PUSH2 0x3B8 JUMP JUMPDEST PUSH2 0x20A PUSH2 0x22E CALLDATASIZE PUSH1 0x4 PUSH2 0xF2E JUMP JUMPDEST PUSH2 0x4D6 JUMP JUMPDEST PUSH2 0x20A PUSH2 0x241 CALLDATASIZE PUSH1 0x4 PUSH2 0xFA0 JUMP JUMPDEST PUSH2 0x7B7 JUMP JUMPDEST PUSH1 0x0 PUSH32 0x9D0217145D12A316ADEA26B4F622AEC07FB71E6638D613BB415476F4C179EECC SLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH2 0x28A DUP5 DUP5 PUSH2 0x87C JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND EQ PUSH2 0x2CB JUMPI PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 PUSH2 0x2ED JUMP JUMPDEST PUSH32 0x1626BA7E00000000000000000000000000000000000000000000000000000000 JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP2 MLOAD PUSH1 0x41 EQ DUP1 ISZERO PUSH2 0x360 JUMPI POP DUP2 PUSH1 0x0 DUP2 MLOAD DUP2 LT PUSH2 0x315 JUMPI PUSH2 0x315 PUSH2 0x1014 JUMP JUMPDEST PUSH1 0x20 SWAP2 ADD ADD MLOAD PUSH32 0xFF00000000000000000000000000000000000000000000000000000000000000 AND PUSH32 0x400000000000000000000000000000000000000000000000000000000000000 EQ JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH32 0x9D0217145D12A316ADEA26B4F622AEC07FB71E6638D613BB415476F4C179EECC DUP1 SLOAD PUSH1 0x0 SWAP2 SWAP1 PUSH2 0x3B0 SWAP1 DUP6 SWAP1 DUP6 SWAP1 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH2 0x7B7 JUMP JUMPDEST SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x3C2 PUSH2 0x8A0 JUMP JUMPDEST PUSH2 0x3CA PUSH2 0x8E0 JUMP JUMPDEST PUSH32 0x9D0217145D12A316ADEA26B4F622AEC07FB71E6638D613BB415476F4C179EECC DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND DUP2 SSTORE PUSH1 0x0 PUSH2 0x424 PUSH1 0x1 SLOAD PUSH2 0x100 SWAP1 DIV PUSH1 0xE0 SHL SWAP1 JUMP JUMPDEST PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 AND SUB PUSH2 0x47D JUMPI PUSH1 0x40 MLOAD PUSH32 0x127C609A00000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x1 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FF AND SWAP1 SSTORE PUSH1 0x40 MLOAD PUSH1 0x1 SWAP3 POP PUSH32 0xCCCD30DB6BC000B8BB8D11162228D2D69E3C361983CA3AE8C1365CE64B0FAE9E SWAP1 PUSH1 0x0 SWAP1 LOG1 POP SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x4E0 PUSH2 0x97F JUMP JUMPDEST PUSH2 0x51F DUP4 DUP4 DUP1 DUP1 PUSH1 0x1F ADD PUSH1 0x20 DUP1 SWAP2 DIV MUL PUSH1 0x20 ADD PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 SWAP4 SWAP3 SWAP2 SWAP1 DUP2 DUP2 MSTORE PUSH1 0x20 ADD DUP4 DUP4 DUP1 DUP3 DUP5 CALLDATACOPY PUSH1 0x0 SWAP3 ADD SWAP2 SWAP1 SWAP2 MSTORE POP PUSH2 0x2F4 SWAP3 POP POP POP JUMP JUMPDEST PUSH2 0x555 JUMPI PUSH1 0x40 MLOAD PUSH32 0x22281E8500000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH32 0x9D0217145D12A316ADEA26B4F622AEC07FB71E6638D613BB415476F4C179EECC PUSH2 0x583 DUP4 PUSH1 0x1 DUP2 DUP8 PUSH2 0x1043 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x591 SWAP3 SWAP2 SWAP1 PUSH2 0x106D JUMP JUMPDEST PUSH1 0x40 MLOAD SWAP1 DUP2 SWAP1 SUB SWAP1 KECCAK256 DUP2 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000 AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP2 AND OR DUP2 SSTORE PUSH1 0x1 SLOAD PUSH32 0x8DD5012100000000000000000000000000000000000000000000000000000000 SWAP1 PUSH1 0x0 SWAP1 PUSH2 0x100 SWAP1 DIV PUSH1 0xE0 SHL PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 AND EQ PUSH2 0x662 JUMPI PUSH1 0x40 MLOAD PUSH32 0x5F95A63C00000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH32 0x0 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH2 0x6F3 DUP3 PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH32 0x183CDE5D4F6BB7B445B8FC2F7F15D0FD1D162275ADED24183BABBFFEE7CD491F PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH1 0x60 SHR SWAP1 JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND EQ PUSH2 0x740 JUMPI PUSH1 0x40 MLOAD PUSH32 0xBB4752B700000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x1 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FF AND PUSH2 0x100 PUSH1 0xE0 DUP5 SWAP1 SHR MUL OR SWAP1 SSTORE PUSH1 0x1 SWAP3 POP PUSH32 0x6D54821A69EC281ED7BA1BF2729C700768C47DF1D80FAD646B0A14CC1D5C39ED DUP6 DUP6 PUSH1 0x40 MLOAD PUSH2 0x7A7 SWAP3 SWAP2 SWAP1 PUSH2 0x107D JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG1 POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH32 0x19457468657265756D205369676E6564204D6573736167653A0A333200000000 PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1C DUP4 SWAP1 MSTORE PUSH1 0x3C DUP2 KECCAK256 PUSH2 0x834 PUSH2 0x7F7 PUSH2 0x140 DUP8 ADD DUP8 PUSH2 0x10CA JUMP JUMPDEST DUP1 DUP1 PUSH1 0x1F ADD PUSH1 0x20 DUP1 SWAP2 DIV MUL PUSH1 0x20 ADD PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 SWAP4 SWAP3 SWAP2 SWAP1 DUP2 DUP2 MSTORE PUSH1 0x20 ADD DUP4 DUP4 DUP1 DUP3 DUP5 CALLDATACOPY PUSH1 0x0 SWAP3 ADD SWAP2 SWAP1 SWAP2 MSTORE POP DUP6 SWAP4 SWAP3 POP POP PUSH2 0x87C SWAP1 POP JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SUB PUSH2 0x86D JUMPI PUSH1 0x0 PUSH2 0x870 JUMP JUMPDEST PUSH1 0x1 JUMPDEST PUSH1 0xFF AND SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH2 0x88B DUP6 DUP6 PUSH2 0xA1F JUMP JUMPDEST SWAP2 POP SWAP2 POP PUSH2 0x898 DUP2 PUSH2 0xA64 JUMP JUMPDEST POP SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x1 DUP1 SLOAD PUSH1 0xFF AND EQ PUSH2 0x8DE JUMPI PUSH1 0x40 MLOAD PUSH32 0x38FC28CB00000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST JUMP JUMPDEST PUSH1 0x0 DUP1 DUP1 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH32 0xAD3228B676F7D3CD4284A5443F17F1962B36E491B30A40B2405849E597BA5FB5 SLOAD PUSH1 0xFF AND PUSH1 0x1 EQ PUSH2 0x948 JUMPI PUSH1 0x40 MLOAD PUSH32 0xE00D7C7700000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x0 DUP1 DUP1 MSTORE PUSH1 0x20 SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0x40 SWAP1 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND SWAP1 SSTORE JUMP JUMPDEST PUSH1 0x0 DUP1 DUP1 MSTORE PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH32 0xAD3228B676F7D3CD4284A5443F17F1962B36E491B30A40B2405849E597BA5FB5 SLOAD PUSH1 0xFF AND ISZERO PUSH2 0x9E5 JUMPI PUSH1 0x40 MLOAD PUSH32 0x7C2CDE8B00000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x0 DUP1 DUP1 MSTORE PUSH1 0x20 SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0x40 SWAP1 KECCAK256 DUP1 SLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 AND PUSH1 0x1 OR SWAP1 SSTORE JUMP JUMPDEST PUSH1 0x0 DUP1 DUP3 MLOAD PUSH1 0x41 SUB PUSH2 0xA55 JUMPI PUSH1 0x20 DUP4 ADD MLOAD PUSH1 0x40 DUP5 ADD MLOAD PUSH1 0x60 DUP6 ADD MLOAD PUSH1 0x0 BYTE PUSH2 0xA49 DUP8 DUP3 DUP6 DUP6 PUSH2 0xC1F JUMP JUMPDEST SWAP5 POP SWAP5 POP POP POP POP PUSH2 0xA5D JUMP JUMPDEST POP PUSH1 0x0 SWAP1 POP PUSH1 0x2 JUMPDEST SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP2 PUSH1 0x4 DUP2 GT ISZERO PUSH2 0xA78 JUMPI PUSH2 0xA78 PUSH2 0x112F JUMP JUMPDEST SUB PUSH2 0xA80 JUMPI POP JUMP JUMPDEST PUSH1 0x1 DUP2 PUSH1 0x4 DUP2 GT ISZERO PUSH2 0xA94 JUMPI PUSH2 0xA94 PUSH2 0x112F JUMP JUMPDEST SUB PUSH2 0xB00 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x20 PUSH1 0x4 DUP3 ADD MSTORE PUSH1 0x18 PUSH1 0x24 DUP3 ADD MSTORE PUSH32 0x45434453413A20696E76616C6964207369676E61747572650000000000000000 PUSH1 0x44 DUP3 ADD MSTORE PUSH1 0x64 ADD JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x2 DUP2 PUSH1 0x4 DUP2 GT ISZERO PUSH2 0xB14 JUMPI PUSH2 0xB14 PUSH2 0x112F JUMP JUMPDEST SUB PUSH2 0xB7B JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x20 PUSH1 0x4 DUP3 ADD MSTORE PUSH1 0x1F PUSH1 0x24 DUP3 ADD MSTORE PUSH32 0x45434453413A20696E76616C6964207369676E6174757265206C656E67746800 PUSH1 0x44 DUP3 ADD MSTORE PUSH1 0x64 ADD PUSH2 0xAF7 JUMP JUMPDEST PUSH1 0x3 DUP2 PUSH1 0x4 DUP2 GT ISZERO PUSH2 0xB8F JUMPI PUSH2 0xB8F PUSH2 0x112F JUMP JUMPDEST SUB PUSH2 0xC1C JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x20 PUSH1 0x4 DUP3 ADD MSTORE PUSH1 0x22 PUSH1 0x24 DUP3 ADD MSTORE PUSH32 0x45434453413A20696E76616C6964207369676E6174757265202773272076616C PUSH1 0x44 DUP3 ADD MSTORE PUSH32 0x7565000000000000000000000000000000000000000000000000000000000000 PUSH1 0x64 DUP3 ADD MSTORE PUSH1 0x84 ADD PUSH2 0xAF7 JUMP JUMPDEST POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH32 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0 DUP4 GT ISZERO PUSH2 0xC56 JUMPI POP PUSH1 0x0 SWAP1 POP PUSH1 0x3 PUSH2 0xD05 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH1 0x0 DUP1 DUP3 MSTORE PUSH1 0x20 DUP3 ADD DUP1 DUP5 MSTORE DUP10 SWAP1 MSTORE PUSH1 0xFF DUP9 AND SWAP3 DUP3 ADD SWAP3 SWAP1 SWAP3 MSTORE PUSH1 0x60 DUP2 ADD DUP7 SWAP1 MSTORE PUSH1 0x80 DUP2 ADD DUP6 SWAP1 MSTORE PUSH1 0x1 SWAP1 PUSH1 0xA0 ADD PUSH1 0x20 PUSH1 0x40 MLOAD PUSH1 0x20 DUP2 SUB SWAP1 DUP1 DUP5 SUB SWAP1 DUP6 GAS STATICCALL ISZERO DUP1 ISZERO PUSH2 0xCAA JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP PUSH1 0x40 MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 ADD MLOAD SWAP2 POP POP PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND PUSH2 0xCFE JUMPI PUSH1 0x0 PUSH1 0x1 SWAP3 POP SWAP3 POP POP PUSH2 0xD05 JUMP JUMPDEST SWAP2 POP PUSH1 0x0 SWAP1 POP JUMPDEST SWAP5 POP SWAP5 SWAP3 POP POP POP JUMP JUMPDEST PUSH32 0x4E487B7100000000000000000000000000000000000000000000000000000000 PUSH1 0x0 MSTORE PUSH1 0x41 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST PUSH1 0x0 DUP3 PUSH1 0x1F DUP4 ADD SLT PUSH2 0xD4E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0xD69 JUMPI PUSH2 0xD69 PUSH2 0xD0E JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x1F DUP4 ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 DUP2 AND PUSH1 0x3F ADD AND DUP2 ADD SWAP1 DUP3 DUP3 GT DUP2 DUP4 LT OR ISZERO PUSH2 0xDAF JUMPI PUSH2 0xDAF PUSH2 0xD0E JUMP JUMPDEST DUP2 PUSH1 0x40 MSTORE DUP4 DUP2 MSTORE DUP7 PUSH1 0x20 DUP6 DUP9 ADD ADD GT ISZERO PUSH2 0xDC8 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP4 PUSH1 0x20 DUP8 ADD PUSH1 0x20 DUP4 ADD CALLDATACOPY PUSH1 0x0 PUSH1 0x20 DUP6 DUP4 ADD ADD MSTORE DUP1 SWAP5 POP POP POP POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0xDFB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP3 CALLDATALOAD SWAP2 POP PUSH1 0x20 DUP4 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xE19 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xE25 DUP6 DUP3 DUP7 ADD PUSH2 0xD3D JUMP JUMPDEST SWAP2 POP POP SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xE41 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xE58 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x3B0 DUP5 DUP3 DUP6 ADD PUSH2 0xD3D JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP1 DUP4 MSTORE DUP4 MLOAD DUP1 DUP3 DUP6 ADD MSTORE PUSH1 0x0 JUMPDEST DUP2 DUP2 LT ISZERO PUSH2 0xE91 JUMPI DUP6 DUP2 ADD DUP4 ADD MLOAD DUP6 DUP3 ADD PUSH1 0x40 ADD MSTORE DUP3 ADD PUSH2 0xE75 JUMP JUMPDEST POP PUSH1 0x0 PUSH1 0x40 DUP3 DUP7 ADD ADD MSTORE PUSH1 0x40 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 PUSH1 0x1F DUP4 ADD AND DUP6 ADD ADD SWAP3 POP POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x160 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xEE3 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0xEFC JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP3 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xF13 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xF1F DUP6 DUP3 DUP7 ADD PUSH2 0xED0 JUMP JUMPDEST SWAP6 PUSH1 0x20 SWAP5 SWAP1 SWAP5 ADD CALLDATALOAD SWAP5 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x20 DUP4 DUP6 SUB SLT ISZERO PUSH2 0xF41 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP3 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0xF59 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 DUP6 ADD SWAP2 POP DUP6 PUSH1 0x1F DUP4 ADD SLT PUSH2 0xF6D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD DUP2 DUP2 GT ISZERO PUSH2 0xF7C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP7 PUSH1 0x20 DUP3 DUP6 ADD ADD GT ISZERO PUSH2 0xF8E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x20 SWAP3 SWAP1 SWAP3 ADD SWAP7 SWAP2 SWAP6 POP SWAP1 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x60 DUP5 DUP7 SUB SLT ISZERO PUSH2 0xFB5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP4 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xFCC JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xFD8 DUP7 DUP3 DUP8 ADD PUSH2 0xED0 JUMP JUMPDEST SWAP4 POP POP PUSH1 0x20 DUP5 ADD CALLDATALOAD SWAP2 POP PUSH1 0x40 DUP5 ADD CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND DUP2 EQ PUSH2 0x1009 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 SWAP2 POP POP SWAP3 POP SWAP3 POP SWAP3 JUMP JUMPDEST PUSH32 0x4E487B7100000000000000000000000000000000000000000000000000000000 PUSH1 0x0 MSTORE PUSH1 0x32 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST PUSH1 0x0 DUP1 DUP6 DUP6 GT ISZERO PUSH2 0x1053 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP4 DUP7 GT ISZERO PUSH2 0x1060 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP POP DUP3 ADD SWAP4 SWAP2 SWAP1 SWAP3 SUB SWAP2 POP JUMP JUMPDEST DUP2 DUP4 DUP3 CALLDATACOPY PUSH1 0x0 SWAP2 ADD SWAP1 DUP2 MSTORE SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x20 DUP2 MSTORE DUP2 PUSH1 0x20 DUP3 ADD MSTORE DUP2 DUP4 PUSH1 0x40 DUP4 ADD CALLDATACOPY PUSH1 0x0 DUP2 DUP4 ADD PUSH1 0x40 SWAP1 DUP2 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0x1F SWAP1 SWAP3 ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 AND ADD ADD SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 DUP4 CALLDATALOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 DUP5 CALLDATASIZE SUB ADD DUP2 SLT PUSH2 0x10FF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP4 ADD DUP1 CALLDATALOAD SWAP2 POP PUSH8 0xFFFFFFFFFFFFFFFF DUP3 GT ISZERO PUSH2 0x111A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x20 ADD SWAP2 POP CALLDATASIZE DUP2 SWAP1 SUB DUP3 SGT ISZERO PUSH2 0xA5D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH32 0x4E487B7100000000000000000000000000000000000000000000000000000000 PUSH1 0x0 MSTORE PUSH1 0x21 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 0xDE CALLER PUSH9 0xE3F3953432149EC8AB PUSH2 0xE8DB SDIV BLOCKHASH SWAP11 CALLVALUE 0xE6 RETURN CALLCODE 0x23 0xF6 0xBC EXP KECCAK256 SMOD 0x2F LOG0 SHR RETURN PUSH5 0x736F6C6343 STOP ADDMOD ISZERO STOP CALLER ", + "sourceMap": "761:7155:70:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7592:322;;;;;;:::i;:::-;;:::i;:::-;;;1552:66:109;1540:79;;;1522:98;;1510:2;1495:18;7592:322:70;;;;;;;;5892:366;6084:36;5892:366;;6986:184;;;;;;:::i;:::-;;:::i;:::-;;;2121:14:109;;2114:22;2096:41;;2084:2;2069:18;6986:184:70;1956:187:109;925:29:70;;;;;;;;2324:42:109;2312:55;;;2294:74;;2282:2;2267:18;925:29:70;2148:226:109;6373:227:70;2022:94:94;6576:16:70;6559:34;;;6420:19;5349:15:109;;;;;;6559:34:70;;;5333:101:109;6559:34:70;;;;;;;;;5450:12:109;;;;6559:34:70;;6373:227;;;;;;:::i;4329:393::-;;;;;;:::i;:::-;;:::i;:::-;;;3744:25:109;;;3732:2;3717:18;4329:393:70;3598:177:109;3136:637:70;;;:::i;1708:1011::-;;;;;;:::i;:::-;;:::i;5343:299::-;;;;;;:::i;:::-;;:::i;7592:322::-;7710:17;2022:94:94;7794:34:70;;;7753:25;:5;7767:10;7753:13;:25::i;:::-;:75;;;7752:155;;7889:18;7752:155;;;7844:30;7752:155;7739:168;7592:322;-1:-1:-1;;;7592:322:70:o;6986:184::-;7079:12;7114:10;:17;7135:2;7114:23;:48;;;;;7141:10;7152:1;7141:13;;;;;;;;:::i;:::-;;;;;;;;:21;;7114:48;7103:60;6986:184;-1:-1:-1;;6986:184:70:o;4329:393::-;2022:94:94;4689:16:70;;4464:22;;2022:94:94;4614:101:70;;4645:6;;4665:10;;4689:16;;4614:17;:101::i;:::-;4597:118;4329:393;-1:-1:-1;;;;4329:393:70:o;3136:637::-;3217:21;3254:38;:36;:38::i;:::-;3302;:36;:38::i;:::-;2022:94:94;3449:29:70;;;;;;3350:46;3493:49;1786:43:92;;;;;;;;1652:184;3493:49:70;:62;;;3489:144;;3576:57;;;;;;;;;;;;;;3489:144;1958:56:92;:90;;;;;;3745:21:70;;3728:1;;-1:-1:-1;3745:21:70;;;;;3244:529;3136:637;:::o;1708:1011::-;1800:19;1831:39;:37;:39::i;:::-;1885:26;1900:10;;1885:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1885:14:70;;-1:-1:-1;;;1885:26:70:i;:::-;1880:101;;1932:49;;;;;;;;;;;;;;1880:101;2022:94:94;2144:14:70;:10;2155:1;2144:10;;:14;:::i;:::-;2134:25;;;;;;;:::i;:::-;;;;;;;;;2091:71;;;;;;;;;;;-1:-1:-1;1786:43:92;6084:36:70;;-1:-1:-1;;1786:43:92;;;;;2246:62:70;;;2242:148;;2329:61;;;;;;;;;;;;;;2242:148;2447:4;2404:47;;:39;2426:16;6850:53:96;;6772:21;6850:53;;;394:45:93;6850:53:96;;;;;;6821:93;;;6687:234;2404:39:70;:47;;;2400:112;;2472:40;;;;;;;;;;;;;;2400:112;1958:56:92;:90;;;;;;;;;;;;;2666:1:70;2652:15;;2683:29;2701:10;;2683:29;;;;;;;:::i;:::-;;;;;;;;1821:898;;1708:1011;;;;:::o;5343:299::-;7389:34:23;5488:15:70;7376:48:23;;;7444:4;7437:18;;;7495:4;7479:21;;5596:30:70;5609:16;;;;:6;:16;:::i;:::-;5596:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;5596:4:70;;:30;-1:-1:-1;;5596:12:70;:30;-1:-1:-1;5596:30:70:i;:::-;5586:40;;:6;:40;;;5585:50;;5634:1;5585:50;;;5630:1;5585:50;5575:60;;;5343:299;-1:-1:-1;;;;;5343:299:70:o;3661:227:23:-;3739:7;3759:17;3778:18;3800:27;3811:4;3817:9;3800:10;:27::i;:::-;3758:69;;;;3837:18;3849:5;3837:11;:18::i;:::-;-1:-1:-1;3872:9:23;3661:227;-1:-1:-1;;;3661:227:23:o;2720:178:92:-;2787:28;;;;;2782:33;2778:114;;2838:43;;;;;;;;;;;;;;2778:114;2720:178::o;1374:272::-;1427:20;1481:16;;;;;;;;:34;;;;1476:39;1472:120;;1538:43;;;;;;;;;;;;;;1472:120;1638:1;1601:16;;;;;;;;;;;:38;;;;;;1374:272::o;2061:::-;2115:20;2169:16;;;;;;;;:34;;;2164:39;2160:119;;2226:42;;;;;;;;;;;;;;2160:119;2288:13;:16;;;;;;;;;;;:38;;;;2325:1;2288:38;;;2061:272::o;2145:730:23:-;2226:7;2235:12;2263:9;:16;2283:2;2263:22;2259:610;;2599:4;2584:20;;2578:27;2648:4;2633:20;;2627:27;2705:4;2690:20;;2684:27;2301:9;2676:36;2746:25;2757:4;2676:36;2578:27;2627;2746:10;:25::i;:::-;2739:32;;;;;;;;;2259:610;-1:-1:-1;2818:1:23;;-1:-1:-1;2822:35:23;2259:610;2145:730;;;;;:::o;570:511::-;647:20;638:5;:29;;;;;;;;:::i;:::-;;634:441;;570:511;:::o;634:441::-;743:29;734:5;:38;;;;;;;;:::i;:::-;;730:345;;788:34;;;;;7519:2:109;788:34:23;;;7501:21:109;7558:2;7538:18;;;7531:30;7597:26;7577:18;;;7570:54;7641:18;;788:34:23;;;;;;;;730:345;852:35;843:5;:44;;;;;;;;:::i;:::-;;839:236;;903:41;;;;;7872:2:109;903:41:23;;;7854:21:109;7911:2;7891:18;;;7884:30;7950:33;7930:18;;;7923:61;8001:18;;903:41:23;7670:355:109;839:236:23;974:30;965:5;:39;;;;;;;;:::i;:::-;;961:114;;1020:44;;;;;8232:2:109;1020:44:23;;;8214:21:109;8271:2;8251:18;;;8244:30;8310:34;8290:18;;;8283:62;8381:4;8361:18;;;8354:32;8403:19;;1020:44:23;8030:398:109;961:114:23;570:511;:::o;5009:1456::-;5097:7;;6021:66;6008:79;;6004:161;;;-1:-1:-1;6119:1:23;;-1:-1:-1;6123:30:23;6103:51;;6004:161;6276:24;;;6259:14;6276:24;;;;;;;;;8660:25:109;;;8733:4;8721:17;;8701:18;;;8694:45;;;;8755:18;;;8748:34;;;8798:18;;;8791:34;;;6276:24:23;;8632:19:109;;6276:24:23;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;6276:24:23;;;;;;-1:-1:-1;;6314:20:23;;;6310:101;;6366:1;6370:29;6350:50;;;;;;;6310:101;6429:6;-1:-1:-1;6437:20:23;;-1:-1:-1;5009:1456:23;;;;;;;;:::o;14:184:109:-;66:77;63:1;56:88;163:4;160:1;153:15;187:4;184:1;177:15;203:777;245:5;298:3;291:4;283:6;279:17;275:27;265:55;;316:1;313;306:12;265:55;352:6;339:20;378:18;415:2;411;408:10;405:36;;;421:18;;:::i;:::-;555:2;549:9;617:4;609:13;;460:66;605:22;;;629:2;601:31;597:40;585:53;;;653:18;;;673:22;;;650:46;647:72;;;699:18;;:::i;:::-;739:10;735:2;728:22;774:2;766:6;759:18;820:3;813:4;808:2;800:6;796:15;792:26;789:35;786:55;;;837:1;834;827:12;786:55;901:2;894:4;886:6;882:17;875:4;867:6;863:17;850:54;948:1;941:4;936:2;928:6;924:15;920:26;913:37;968:6;959:15;;;;;;203:777;;;;:::o;985:388::-;1062:6;1070;1123:2;1111:9;1102:7;1098:23;1094:32;1091:52;;;1139:1;1136;1129:12;1091:52;1175:9;1162:23;1152:33;;1236:2;1225:9;1221:18;1208:32;1263:18;1255:6;1252:30;1249:50;;;1295:1;1292;1285:12;1249:50;1318:49;1359:7;1350:6;1339:9;1335:22;1318:49;:::i;:::-;1308:59;;;985:388;;;;;:::o;1631:320::-;1699:6;1752:2;1740:9;1731:7;1727:23;1723:32;1720:52;;;1768:1;1765;1758:12;1720:52;1808:9;1795:23;1841:18;1833:6;1830:30;1827:50;;;1873:1;1870;1863:12;1827:50;1896:49;1937:7;1928:6;1917:9;1913:22;1896:49;:::i;2379:605::-;2489:4;2518:2;2547;2536:9;2529:21;2579:6;2573:13;2622:6;2617:2;2606:9;2602:18;2595:34;2647:1;2657:140;2671:6;2668:1;2665:13;2657:140;;;2766:14;;;2762:23;;2756:30;2732:17;;;2751:2;2728:26;2721:66;2686:10;;2657:140;;;2661:3;2846:1;2841:2;2832:6;2821:9;2817:22;2813:31;2806:42;2975:2;2905:66;2900:2;2892:6;2888:15;2884:88;2873:9;2869:104;2865:113;2857:121;;;;2379:605;;;;:::o;2989:162::-;3055:5;3100:3;3091:6;3086:3;3082:16;3078:26;3075:46;;;3117:1;3114;3107:12;3075:46;-1:-1:-1;3139:6:109;2989:162;-1:-1:-1;2989:162:109:o;3156:437::-;3258:6;3266;3319:2;3307:9;3298:7;3294:23;3290:32;3287:52;;;3335:1;3332;3325:12;3287:52;3375:9;3362:23;3408:18;3400:6;3397:30;3394:50;;;3440:1;3437;3430:12;3394:50;3463:73;3528:7;3519:6;3508:9;3504:22;3463:73;:::i;:::-;3453:83;3583:2;3568:18;;;;3555:32;;-1:-1:-1;;;;3156:437:109:o;3780:591::-;3850:6;3858;3911:2;3899:9;3890:7;3886:23;3882:32;3879:52;;;3927:1;3924;3917:12;3879:52;3967:9;3954:23;3996:18;4037:2;4029:6;4026:14;4023:34;;;4053:1;4050;4043:12;4023:34;4091:6;4080:9;4076:22;4066:32;;4136:7;4129:4;4125:2;4121:13;4117:27;4107:55;;4158:1;4155;4148:12;4107:55;4198:2;4185:16;4224:2;4216:6;4213:14;4210:34;;;4240:1;4237;4230:12;4210:34;4285:7;4280:2;4271:6;4267:2;4263:15;4259:24;4256:37;4253:57;;;4306:1;4303;4296:12;4253:57;4337:2;4329:11;;;;;4359:6;;-1:-1:-1;3780:591:109;;-1:-1:-1;;;;3780:591:109:o;4376:634::-;4487:6;4495;4503;4556:2;4544:9;4535:7;4531:23;4527:32;4524:52;;;4572:1;4569;4562:12;4524:52;4612:9;4599:23;4645:18;4637:6;4634:30;4631:50;;;4677:1;4674;4667:12;4631:50;4700:73;4765:7;4756:6;4745:9;4741:22;4700:73;:::i;:::-;4690:83;;;4820:2;4809:9;4805:18;4792:32;4782:42;;4874:2;4863:9;4859:18;4846:32;4918:42;4911:5;4907:54;4900:5;4897:65;4887:93;;4976:1;4973;4966:12;4887:93;4999:5;4989:15;;;4376:634;;;;;:::o;5015:184::-;5067:77;5064:1;5057:88;5164:4;5161:1;5154:15;5188:4;5185:1;5178:15;5473:331;5578:9;5589;5631:8;5619:10;5616:24;5613:44;;;5653:1;5650;5643:12;5613:44;5682:6;5672:8;5669:20;5666:40;;;5702:1;5699;5692:12;5666:40;-1:-1:-1;;5728:23:109;;;5773:25;;;;;-1:-1:-1;5473:331:109:o;5809:277::-;5998:6;5990;5985:3;5972:33;5954:3;6024:16;;6049:13;;;6024:16;5809:277;-1:-1:-1;5809:277:109:o;6091:447::-;6248:2;6237:9;6230:21;6287:6;6282:2;6271:9;6267:18;6260:34;6344:6;6336;6331:2;6320:9;6316:18;6303:48;6400:1;6371:22;;;6395:2;6367:31;;;6360:42;;;;6454:2;6442:15;;;6459:66;6438:88;6423:104;6419:113;;6091:447;-1:-1:-1;6091:447:109:o;6543:580::-;6620:4;6626:6;6686:11;6673:25;6776:66;6765:8;6749:14;6745:29;6741:102;6721:18;6717:127;6707:155;;6858:1;6855;6848:12;6707:155;6885:33;;6937:20;;;-1:-1:-1;6980:18:109;6969:30;;6966:50;;;7012:1;7009;7002:12;6966:50;7045:4;7033:17;;-1:-1:-1;7076:14:109;7072:27;;;7062:38;;7059:58;;;7113:1;7110;7103:12;7128:184;7180:77;7177:1;7170:88;7277:4;7274:1;7267:15;7301:4;7298:1;7291:15" + }, + "gasEstimates": { + "creation": { + "codeDepositCost": "900000", + "executionCost": "infinite", + "totalCost": "infinite" + }, + "external": { + "initializeSigner(bytes)": "infinite", + "isValidKeyType(bytes)": "infinite", + "isValidSignature(bytes32,bytes)": "infinite", + "owner()": "infinite", + "self()": "infinite", + "uninitializeSigner()": "80215", + "validateOwnerSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32)": "infinite", + "validateOwnerSignatureSelector()": "213", + "validateSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,address)": "infinite" + } + }, + "methodIdentifiers": { + "initializeSigner(bytes)": "cd9b47e4", + "isValidKeyType(bytes)": "392dd6d9", + "isValidSignature(bytes32,bytes)": "1626ba7e", + "owner()": "8da5cb5b", + "self()": "7104ddb2", + "uninitializeSigner()": "cd00e50a", + "validateOwnerSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32)": "8dd50121", + "validateOwnerSignatureSelector()": "3253960f", + "validateSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,address)": "f45007c3" + } + }, + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"LibAppStorage__AccountMustBeUninitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LibAppStorage__SignerAlreadyUninitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LibAppStorage__SignerMustBeUninitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Secp256k1VerificationFacet__InvalidSignerLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerificationFacet__InitializationFailure\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerificationFacet__InvalidFacetMapping\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerificationFacet__ValidateOwnerSignatureSelectorNotSet\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"SignerInitialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"SignerUninitialized\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_publicKey\",\"type\":\"bytes\"}],\"name\":\"initializeSigner\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"initSuccess\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_publicKey\",\"type\":\"bytes\"}],\"name\":\"isValidKeyType\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isValid\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_hash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"_signature\",\"type\":\"bytes\"}],\"name\":\"isValidSignature\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"magicValue\",\"type\":\"bytes4\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"signer\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"self\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"uninitializeSigner\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"uninitSuccess\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"userOp\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"}],\"name\":\"validateOwnerSignature\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"validationData\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"validateOwnerSignatureSelector\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"ownerSignatureValidatorSelector\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"userOp\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"}],\"name\":\"validateSignature\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"isValid\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)Ruslan Serebriakov (@rsrbk)\",\"details\":\"Default Ethereum's elliptic curve\",\"kind\":\"dev\",\"methods\":{\"initializeSigner(bytes)\":{\"details\":\"This method checks if the signer has already been initialized. If already initialized, it reverts. It checks if the public key is in the light format and initializes signer storage in k1 storage.\",\"params\":{\"_publicKey\":\"Bytes of owner public key\"},\"returns\":{\"initSuccess\":\"Uint value representing the success of init operation\"}},\"isValidKeyType(bytes)\":{\"details\":\"For this Secp256k1Verification Facet, the public key length should be 65 in an uncompressed public key format\",\"params\":{\"_publicKey\":\"Bytes of public key for format check\"},\"returns\":{\"isValid\":\"Boolean variable representing if the format of public key is valid\"}},\"isValidSignature(bytes32,bytes)\":{\"details\":\"This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\",\"params\":{\"_hash\":\"Hash value the owner signed\",\"_signature\":\"Signature that signed the above hash\"},\"returns\":{\"magicValue\":\"Bytes4 value representing the success/failure of validation\"}},\"owner()\":{\"returns\":{\"signer\":\"Bytes of owner address\"}},\"uninitializeSigner()\":{\"details\":\"This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\",\"returns\":{\"uninitSuccess\":\"Uint value representing the success of uninit operation\"}},\"validateOwnerSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32)\":{\"details\":\"This method validates if the user operation is signed by the owner. It internally calls validateSignature with signer public key.\",\"params\":{\"userOp\":\"UserOperation including all information for execution\",\"userOpHash\":\"Hash of UserOperation given from EntryPoint. This hash is used for signature validation\"},\"returns\":{\"validationData\":\"Uint value representing whether the validation is successful. 0 for success, 1 for failure\"}},\"validateOwnerSignatureSelector()\":{\"returns\":{\"ownerSignatureValidatorSelector\":\"Bytes4 selector of function signature to validate account owner's UserOperation signature\"}},\"validateSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,address)\":{\"details\":\"This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\",\"params\":{\"signer\":\"Address of signer who signed the contract, to be validated\",\"userOp\":\"UserOperation including all information for execution\",\"userOpHash\":\"Hash of UserOperation given from EntryPoint. This hash is used for signature validation\"},\"returns\":{\"isValid\":\"Uint value representing whether the validation is successful. 0 for success, 1 for failure\"}}},\"title\":\"Secp256k1 verification facet\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"This constructor ensures that this contract can only be used as singleton for Proxy contracts\"},\"initializeSigner(bytes)\":{\"notice\":\"Initializes the signer in K1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\"},\"isValidKeyType(bytes)\":{\"notice\":\"Validates if the format of public key is valid for this verification facet\"},\"isValidSignature(bytes32,bytes)\":{\"notice\":\"Validates if the signature is valid. Function to be compatible with EIP-1271\"},\"owner()\":{\"notice\":\"Returns the owner of the account\"},\"uninitializeSigner()\":{\"notice\":\"Uninitialize signer in K1 Facet Storage. This can only be called when the account is undergoing signature migration and has already been initialized.\"},\"validateOwnerSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32)\":{\"notice\":\"Validates if the user operation is signed by the owner.\"},\"validateOwnerSignatureSelector()\":{\"notice\":\"Returns the selector of function to validate the signature of UserOperation\"},\"validateSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,address)\":{\"notice\":\"Validates if the signature of UserOperation is signed by the given signer\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/verification/secp256k1/Secp256k1VerificationFacet.sol\":\"Secp256k1VerificationFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./math/Math.sol\\\";\\nimport \\\"./math/SignedMath.sol\\\";\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n uint256 length = Math.log10(value) + 1;\\n string memory buffer = new string(length);\\n uint256 ptr;\\n /// @solidity memory-safe-assembly\\n assembly {\\n ptr := add(buffer, add(32, length))\\n }\\n while (true) {\\n ptr--;\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\\n }\\n value /= 10;\\n if (value == 0) break;\\n }\\n return buffer;\\n }\\n }\\n\\n /**\\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\\n */\\n function toString(int256 value) internal pure returns (string memory) {\\n return string(abi.encodePacked(value < 0 ? \\\"-\\\" : \\\"\\\", toString(SignedMath.abs(value))));\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n return toHexString(value, Math.log256(value) + 1);\\n }\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n\\n /**\\n * @dev Returns true if the two strings are equal.\\n */\\n function equal(string memory a, string memory b) internal pure returns (bool) {\\n return keccak256(bytes(a)) == keccak256(bytes(b));\\n }\\n}\\n\",\"keccak256\":\"0x3088eb2868e8d13d89d16670b5f8612c4ab9ff8956272837d8e90106c59c14a0\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Strings.sol\\\";\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSA {\\n enum RecoverError {\\n NoError,\\n InvalidSignature,\\n InvalidSignatureLength,\\n InvalidSignatureS,\\n InvalidSignatureV // Deprecated in v4.8\\n }\\n\\n function _throwError(RecoverError error) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert(\\\"ECDSA: invalid signature\\\");\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert(\\\"ECDSA: invalid signature length\\\");\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert(\\\"ECDSA: invalid signature 's' value\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature` or error string. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n *\\n * Documentation for signature generation:\\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n return tryRecover(hash, v, r, s);\\n } else {\\n return (address(0), RecoverError.InvalidSignatureLength);\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature`. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, signature);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\\n uint8 v = uint8((uint256(vs) >> 255) + 27);\\n return tryRecover(hash, v, r, s);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n *\\n * _Available since v4.2._\\n */\\n function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\\n // the valid range for s in (301): 0 < s < secp256k1n \\u00f7 2 + 1, and for v in (302): v \\u2208 {27, 28}. Most\\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\\n //\\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\\n // these malleable signatures as well.\\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n return (address(0), RecoverError.InvalidSignatureS);\\n }\\n\\n // If the signature is valid (and not malleable), return the signer address\\n address signer = ecrecover(hash, v, r, s);\\n if (signer == address(0)) {\\n return (address(0), RecoverError.InvalidSignature);\\n }\\n\\n return (signer, RecoverError.NoError);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore(0x00, \\\"\\\\x19Ethereum Signed Message:\\\\n32\\\")\\n mstore(0x1c, hash)\\n message := keccak256(0x00, 0x3c)\\n }\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from `s`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n\\\", Strings.toString(s.length), s));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Typed Data, created from a\\n * `domainSeparator` and a `structHash`. This produces hash corresponding\\n * to the one signed with the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n * JSON-RPC method as part of EIP-712.\\n *\\n * See {recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n let ptr := mload(0x40)\\n mstore(ptr, \\\"\\\\x19\\\\x01\\\")\\n mstore(add(ptr, 0x02), domainSeparator)\\n mstore(add(ptr, 0x22), structHash)\\n data := keccak256(ptr, 0x42)\\n }\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Data with intended validator, created from a\\n * `validator` and `data` according to the version 0 of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x00\\\", validator, data));\\n }\\n}\\n\",\"keccak256\":\"0x809bc3edb4bcbef8263fa616c1b60ee0004b50a8a1bfa164d8f57fd31f520c58\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n enum Rounding {\\n Down, // Toward negative infinity\\n Up, // Toward infinity\\n Zero // Toward zero\\n }\\n\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow.\\n return (a & b) + (a ^ b) / 2;\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a == 0 ? 0 : (a - 1) / b + 1;\\n }\\n\\n /**\\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\\n * with further edits by Uniswap Labs also under MIT license.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\\n unchecked {\\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2^256 + prod0.\\n uint256 prod0; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division.\\n if (prod1 == 0) {\\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\\n // The surrounding unchecked block does not change this fact.\\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\\n return prod0 / denominator;\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n require(denominator > prod1, \\\"Math: mulDiv overflow\\\");\\n\\n ///////////////////////////////////////////////\\n // 512 by 256 division.\\n ///////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0].\\n uint256 remainder;\\n assembly {\\n // Compute remainder using mulmod.\\n remainder := mulmod(x, y, denominator)\\n\\n // Subtract 256 bit number from 512 bit number.\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\\n // See https://cs.stackexchange.com/q/138556/92363.\\n\\n // Does not overflow because the denominator cannot be zero at this stage in the function.\\n uint256 twos = denominator & (~denominator + 1);\\n assembly {\\n // Divide denominator by twos.\\n denominator := div(denominator, twos)\\n\\n // Divide [prod1 prod0] by twos.\\n prod0 := div(prod0, twos)\\n\\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\\n twos := add(div(sub(0, twos), twos), 1)\\n }\\n\\n // Shift in bits from prod1 into prod0.\\n prod0 |= prod1 * twos;\\n\\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\\n // four bits. That is, denominator * inv = 1 mod 2^4.\\n uint256 inverse = (3 * denominator) ^ 2;\\n\\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\\n // in modular arithmetic, doubling the correct bits in each step.\\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\\n\\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inverse;\\n return result;\\n }\\n }\\n\\n /**\\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\\n uint256 result = mulDiv(x, y, denominator);\\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\\n result += 1;\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\\n *\\n * Inspired by Henry S. Warren, Jr.'s \\\"Hacker's Delight\\\" (Chapter 11).\\n */\\n function sqrt(uint256 a) internal pure returns (uint256) {\\n if (a == 0) {\\n return 0;\\n }\\n\\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\\n //\\n // We know that the \\\"msb\\\" (most significant bit) of our target number `a` is a power of 2 such that we have\\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\\n //\\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\\n // \\u2192 `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\\n // \\u2192 `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\\n //\\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\\n uint256 result = 1 << (log2(a) >> 1);\\n\\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\\n // into the expected uint128 result.\\n unchecked {\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n return min(result, a / result);\\n }\\n }\\n\\n /**\\n * @notice Calculates sqrt(a), following the selected rounding direction.\\n */\\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = sqrt(a);\\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 2, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 128;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 64;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 32;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 16;\\n }\\n if (value >> 8 > 0) {\\n value >>= 8;\\n result += 8;\\n }\\n if (value >> 4 > 0) {\\n value >>= 4;\\n result += 4;\\n }\\n if (value >> 2 > 0) {\\n value >>= 2;\\n result += 2;\\n }\\n if (value >> 1 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log2(value);\\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 10, rounded down, of a positive value.\\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 + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 256, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n *\\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\\n */\\n function log256(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 16;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 8;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 4;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 2;\\n }\\n if (value >> 8 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log256(value);\\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe4455ac1eb7fc497bb7402579e7b4d64d928b846fce7d2b6fde06d366f21c2b3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\\n * checks.\\n *\\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\\n * easily result in undesired exploitation or bugs, since developers usually\\n * assume that overflows raise errors. `SafeCast` restores this intuition by\\n * reverting the transaction when such an operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n *\\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\\n * all math on `uint256` and `int256` and then downcasting.\\n */\\nlibrary SafeCast {\\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 * _Available since v4.7._\\n */\\n function toUint248(uint256 value) internal pure returns (uint248) {\\n require(value <= type(uint248).max, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint240(uint256 value) internal pure returns (uint240) {\\n require(value <= type(uint240).max, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint232(uint256 value) internal pure returns (uint232) {\\n require(value <= type(uint232).max, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint224(uint256 value) internal pure returns (uint224) {\\n require(value <= type(uint224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint216(uint256 value) internal pure returns (uint216) {\\n require(value <= type(uint216).max, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint208(uint256 value) internal pure returns (uint208) {\\n require(value <= type(uint208).max, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint200(uint256 value) internal pure returns (uint200) {\\n require(value <= type(uint200).max, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint192(uint256 value) internal pure returns (uint192) {\\n require(value <= type(uint192).max, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint184(uint256 value) internal pure returns (uint184) {\\n require(value <= type(uint184).max, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint176(uint256 value) internal pure returns (uint176) {\\n require(value <= type(uint176).max, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint168(uint256 value) internal pure returns (uint168) {\\n require(value <= type(uint168).max, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint160(uint256 value) internal pure returns (uint160) {\\n require(value <= type(uint160).max, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint152(uint256 value) internal pure returns (uint152) {\\n require(value <= type(uint152).max, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint144(uint256 value) internal pure returns (uint144) {\\n require(value <= type(uint144).max, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint136(uint256 value) internal pure returns (uint136) {\\n require(value <= type(uint136).max, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint128(uint256 value) internal pure returns (uint128) {\\n require(value <= type(uint128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint120(uint256 value) internal pure returns (uint120) {\\n require(value <= type(uint120).max, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint112(uint256 value) internal pure returns (uint112) {\\n require(value <= type(uint112).max, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint104(uint256 value) internal pure returns (uint104) {\\n require(value <= type(uint104).max, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint96(uint256 value) internal pure returns (uint96) {\\n require(value <= type(uint96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint88(uint256 value) internal pure returns (uint88) {\\n require(value <= type(uint88).max, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint80(uint256 value) internal pure returns (uint80) {\\n require(value <= type(uint80).max, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint72(uint256 value) internal pure returns (uint72) {\\n require(value <= type(uint72).max, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint64(uint256 value) internal pure returns (uint64) {\\n require(value <= type(uint64).max, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint56(uint256 value) internal pure returns (uint56) {\\n require(value <= type(uint56).max, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint48(uint256 value) internal pure returns (uint48) {\\n require(value <= type(uint48).max, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint40(uint256 value) internal pure returns (uint40) {\\n require(value <= type(uint40).max, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint32(uint256 value) internal pure returns (uint32) {\\n require(value <= type(uint32).max, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint24(uint256 value) internal pure returns (uint24) {\\n require(value <= type(uint24).max, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint16(uint256 value) internal pure returns (uint16) {\\n require(value <= type(uint16).max, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint8(uint256 value) internal pure returns (uint8) {\\n require(value <= type(uint8).max, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\n */\\n function toUint256(int256 value) internal pure returns (uint256) {\\n require(value >= 0, \\\"SafeCast: value must be positive\\\");\\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 * _Available since v4.7._\\n */\\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\\n downcasted = int248(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\\n downcasted = int240(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\\n downcasted = int232(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\\n downcasted = int224(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\\n downcasted = int216(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\\n downcasted = int208(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\\n downcasted = int200(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\\n downcasted = int192(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\\n downcasted = int184(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\\n downcasted = int176(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\\n downcasted = int168(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\\n downcasted = int160(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\\n downcasted = int152(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\\n downcasted = int144(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\\n downcasted = int136(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\\n downcasted = int128(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\\n downcasted = int120(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\\n downcasted = int112(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\\n downcasted = int104(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\\n downcasted = int96(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\\n downcasted = int88(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\\n downcasted = int80(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\\n downcasted = int72(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\\n downcasted = int64(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\\n downcasted = int56(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\\n downcasted = int48(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\\n downcasted = int40(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\\n downcasted = int32(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\\n downcasted = int24(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\\n downcasted = int16(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\\n downcasted = int8(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\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 require(value <= uint256(type(int256).max), \\\"SafeCast: value doesn't fit in an int256\\\");\\n return int256(value);\\n }\\n}\\n\",\"keccak256\":\"0x52a8cfb0f5239d11b457dcdd1b326992ef672714ca8da71a157255bddd13f3ad\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SignedMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard signed math utilities missing in the Solidity language.\\n */\\nlibrary SignedMath {\\n /**\\n * @dev Returns the largest of two signed numbers.\\n */\\n function max(int256 a, int256 b) internal pure returns (int256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two signed numbers.\\n */\\n function min(int256 a, int256 b) internal pure returns (int256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two signed numbers without overflow.\\n * The result is rounded towards zero.\\n */\\n function average(int256 a, int256 b) internal pure returns (int256) {\\n // Formula from the book \\\"Hacker's Delight\\\"\\n int256 x = (a & b) + ((a ^ b) >> 1);\\n return x + (int256(uint256(x) >> 255) & (a ^ b));\\n }\\n\\n /**\\n * @dev Returns the absolute unsigned value of a signed value.\\n */\\n function abs(int256 n) internal pure returns (uint256) {\\n unchecked {\\n // must be unchecked in order to support `n = type(int256).min`\\n return uint256(n >= 0 ? n : -n);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf92515413956f529d95977adc9b0567d583c6203fc31ab1c23824c35187e3ddc\",\"license\":\"MIT\"},\"contracts/aa-4337/core/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable no-inline-assembly */\\n\\n/**\\n * returned data from validateUserOp.\\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\\n * @param aggregator - address(0) - the account validated the signature by itself.\\n * address(1) - the account failed to validate the signature.\\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\\n * @param validAfter - this UserOp is valid only after this timestamp.\\n * @param validaUntil - this UserOp is valid only up to this timestamp.\\n */\\nstruct ValidationData {\\n address aggregator;\\n uint48 validAfter;\\n uint48 validUntil;\\n}\\n\\n//extract sigFailed, validAfter, validUntil.\\n// also convert zero validUntil to type(uint48).max\\nfunction _parseValidationData(\\n uint validationData\\n) pure returns (ValidationData memory data) {\\n address aggregator = address(uint160(validationData));\\n uint48 validUntil = uint48(validationData >> 160);\\n if (validUntil == 0) {\\n validUntil = type(uint48).max;\\n }\\n uint48 validAfter = uint48(validationData >> (48 + 160));\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n// intersect account and paymaster ranges.\\nfunction _intersectTimeRange(\\n uint256 validationData,\\n uint256 paymasterValidationData\\n) pure returns (ValidationData memory) {\\n ValidationData memory accountValidationData = _parseValidationData(\\n validationData\\n );\\n ValidationData memory pmValidationData = _parseValidationData(\\n paymasterValidationData\\n );\\n address aggregator = accountValidationData.aggregator;\\n if (aggregator == address(0)) {\\n aggregator = pmValidationData.aggregator;\\n }\\n uint48 validAfter = accountValidationData.validAfter;\\n uint48 validUntil = accountValidationData.validUntil;\\n uint48 pmValidAfter = pmValidationData.validAfter;\\n uint48 pmValidUntil = pmValidationData.validUntil;\\n\\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp\\n * @param data - the ValidationData to pack\\n */\\nfunction _packValidationData(\\n ValidationData memory data\\n) pure returns (uint256) {\\n return\\n uint160(data.aggregator) |\\n (uint256(data.validUntil) << 160) |\\n (uint256(data.validAfter) << (160 + 48));\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp, when not using an aggregator\\n * @param sigFailed - true for signature failure, false for success\\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\\n * @param validAfter first timestamp this UserOperation is valid\\n */\\nfunction _packValidationData(\\n bool sigFailed,\\n uint48 validUntil,\\n uint48 validAfter\\n) pure returns (uint256) {\\n return\\n (sigFailed ? 1 : 0) |\\n (uint256(validUntil) << 160) |\\n (uint256(validAfter) << (160 + 48));\\n}\\n\\n/**\\n * keccak function over calldata.\\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\\n */\\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\\n assembly {\\n let mem := mload(0x40)\\n let len := data.length\\n calldatacopy(mem, data.offset, len)\\n ret := keccak256(mem, len)\\n }\\n}\\n\",\"keccak256\":\"0xa79f06cd158ecb8c0da95493a2f348933b8627a63e228b99738bff3aa107942d\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAggregator.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\n/**\\n * Aggregated Signatures validator.\\n */\\ninterface IAggregator {\\n /**\\n * validate aggregated signature.\\n * revert if the aggregated signature does not match the given list of operations.\\n */\\n function validateSignatures(\\n UserOperation[] calldata userOps,\\n bytes calldata signature\\n ) external view;\\n\\n /**\\n * validate signature of a single userOp\\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\\n * @param userOp the userOperation received from the user.\\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\\n * (usually empty, unless account and aggregator support some kind of \\\"multisig\\\"\\n */\\n function validateUserOpSignature(\\n UserOperation calldata userOp\\n ) external view returns (bytes memory sigForUserOp);\\n\\n /**\\n * aggregate multiple signatures into a single value.\\n * This method is called off-chain to calculate the signature to pass with handleOps()\\n * bundler MAY use optimized custom code perform this aggregation\\n * @param userOps array of UserOperations to collect the signatures from.\\n * @return aggregatedSignature the aggregated signature\\n */\\n function aggregateSignatures(\\n UserOperation[] calldata userOps\\n ) external view returns (bytes memory aggregatedSignature);\\n}\\n\",\"keccak256\":\"0xdfdcd80568f037716674619b31be630fcd8316262f05a815b41d1e81782c966a\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IEntryPoint.sol\":{\"content\":\"/**\\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\\n ** Only one instance required on each chain.\\n **/\\n// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-inline-assembly */\\n/* solhint-disable reason-string */\\n\\nimport \\\"./UserOperation.sol\\\";\\nimport \\\"./IStakeManager.sol\\\";\\nimport \\\"./IAggregator.sol\\\";\\nimport \\\"./INonceManager.sol\\\";\\n\\ninterface IEntryPoint is IStakeManager, INonceManager {\\n /***\\n * An event emitted after each successful request\\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\\n * @param sender - the account that generates this request.\\n * @param paymaster - if non-null, the paymaster that pays for this request.\\n * @param nonce - the nonce value from the request.\\n * @param success - true if the sender transaction succeeded, false if reverted.\\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\\n */\\n event UserOperationEvent(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address indexed paymaster,\\n uint256 nonce,\\n bool success,\\n uint256 actualGasCost,\\n uint256 actualGasUsed\\n );\\n\\n /**\\n * account \\\"sender\\\" was deployed.\\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\\n * @param sender the account that is deployed\\n * @param factory the factory used to deploy this account (in the initCode)\\n * @param paymaster the paymaster used by this UserOp\\n */\\n event AccountDeployed(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address factory,\\n address paymaster\\n );\\n\\n /**\\n * An event emitted if the UserOperation \\\"callData\\\" reverted with non-zero length\\n * @param userOpHash the request unique identifier.\\n * @param sender the sender of this request\\n * @param nonce the nonce used in the request\\n * @param revertReason - the return bytes from the (reverted) call to \\\"callData\\\".\\n */\\n event UserOperationRevertReason(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n uint256 nonce,\\n bytes revertReason\\n );\\n\\n /**\\n * an event emitted by handleOps(), before starting the execution loop.\\n * any event emitted before this event, is part of the validation.\\n */\\n event BeforeExecution();\\n\\n /**\\n * signature aggregator used by the following UserOperationEvents within this bundle.\\n */\\n event SignatureAggregatorChanged(address indexed aggregator);\\n\\n /**\\n * a custom revert error of handleOps, to identify the offending op.\\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\\n * @param reason - revert reason\\n * The string starts with a unique code \\\"AAmn\\\", where \\\"m\\\" is \\\"1\\\" for factory, \\\"2\\\" for account and \\\"3\\\" for paymaster issues,\\n * so a failure can be attributed to the correct entity.\\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\\n */\\n error FailedOp(uint256 opIndex, string reason);\\n\\n /**\\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\\n */\\n error SignatureValidationFailed(address aggregator);\\n\\n /**\\n * Successful result from simulateValidation.\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n */\\n error ValidationResult(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo\\n );\\n\\n /**\\n * Successful result from simulateValidation, if the account returns a signature aggregator\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\\n * bundler MUST use it to verify the signature, or reject the UserOperation\\n */\\n error ValidationResultWithAggregation(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo,\\n AggregatorStakeInfo aggregatorInfo\\n );\\n\\n /**\\n * return value of getSenderAddress\\n */\\n error SenderAddressResult(address sender);\\n\\n /**\\n * return value of simulateHandleOp\\n */\\n error ExecutionResult(\\n uint256 preOpGas,\\n uint256 paid,\\n uint48 validAfter,\\n uint48 validUntil,\\n bool targetSuccess,\\n bytes targetResult\\n );\\n\\n //UserOps handled, per aggregator\\n struct UserOpsPerAggregator {\\n UserOperation[] userOps;\\n // aggregator address\\n IAggregator aggregator;\\n // aggregated signature\\n bytes signature;\\n }\\n\\n /**\\n * Execute a batch of UserOperation.\\n * no signature aggregator is used.\\n * if any account requires an aggregator (that is, it returned an aggregator when\\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\\n * @param ops the operations to execute\\n * @param beneficiary the address to receive the fees\\n */\\n function handleOps(\\n UserOperation[] calldata ops,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * Execute a batch of UserOperation with Aggregators\\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\\n * @param beneficiary the address to receive the fees\\n */\\n function handleAggregatedOps(\\n UserOpsPerAggregator[] calldata opsPerAggregator,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * generate a request Id - unique identifier for this request.\\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\\n */\\n function getUserOpHash(\\n UserOperation calldata userOp\\n ) external view returns (bytes32);\\n\\n /**\\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\\n * @param userOp the user operation to validate.\\n */\\n function simulateValidation(UserOperation calldata userOp) external;\\n\\n /**\\n * gas and return values during simulation\\n * @param preOpGas the gas used for validation (including preValidationGas)\\n * @param prefund the required prefund for this operation\\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\\n */\\n struct ReturnInfo {\\n uint256 preOpGas;\\n uint256 prefund;\\n bool sigFailed;\\n uint48 validAfter;\\n uint48 validUntil;\\n bytes paymasterContext;\\n }\\n\\n /**\\n * returned aggregated signature info.\\n * the aggregator returned by the account, and its current stake.\\n */\\n struct AggregatorStakeInfo {\\n address aggregator;\\n StakeInfo stakeInfo;\\n }\\n\\n /**\\n * Get counterfactual sender address.\\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\\n * this method always revert, and returns the address in SenderAddressResult error\\n * @param initCode the constructor code to be passed into the UserOperation.\\n */\\n function getSenderAddress(bytes memory initCode) external;\\n\\n /**\\n * simulate full execution of a UserOperation (including both validation and target execution)\\n * this method will always revert with \\\"ExecutionResult\\\".\\n * it performs full validation of the UserOperation, but ignores signature error.\\n * an optional target address is called after the userop succeeds, and its value is returned\\n * (before the entire call is reverted)\\n * Note that in order to collect the the success/failure of the target call, it must be executed\\n * with trace enabled to track the emitted events.\\n * @param op the UserOperation to simulate\\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\\n * are set to the return from that call.\\n * @param targetCallData callData to pass to target address\\n */\\n function simulateHandleOp(\\n UserOperation calldata op,\\n address target,\\n bytes calldata targetCallData\\n ) external;\\n}\\n\",\"keccak256\":\"0x9ccb1b188eda8bbf5f6c2d01bd83c3d8b2b04fcf745283051d31fe96d1d8e40f\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/INonceManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\ninterface INonceManager {\\n /**\\n * Return the next nonce for this sender.\\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\\n * But UserOp with different keys can come with arbitrary order.\\n *\\n * @param sender the account address\\n * @param key the high 192 bit of the nonce\\n * @return nonce a full nonce to pass for next UserOp with this sender.\\n */\\n function getNonce(\\n address sender,\\n uint192 key\\n ) external view returns (uint256 nonce);\\n\\n /**\\n * Manually increment the nonce of the sender.\\n * This method is exposed just for completeness..\\n * Account does NOT need to call it, neither during validation, nor elsewhere,\\n * as the EntryPoint will update the nonce regardless.\\n * Possible use-case is call it with various keys to \\\"initialize\\\" their nonces to one, so that future\\n * UserOperations will not pay extra for the first transaction with a given key.\\n */\\n function incrementNonce(uint192 key) external;\\n}\\n\",\"keccak256\":\"0xce478ad0fa0d18a3b785ac854623029e7ab463d05873dfaa365abfa1bf100912\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IStakeManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8.12;\\n\\n/**\\n * manage deposits and stakes.\\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\\n * stake is value locked for at least \\\"unstakeDelay\\\" by the staked entity.\\n */\\ninterface IStakeManager {\\n event Deposited(address indexed account, uint256 totalDeposit);\\n\\n event Withdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /// Emitted when stake or unstake delay are modified\\n event StakeLocked(\\n address indexed account,\\n uint256 totalStaked,\\n uint256 unstakeDelaySec\\n );\\n\\n /// Emitted once a stake is scheduled for withdrawal\\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\\n\\n event StakeWithdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /**\\n * @param deposit the entity's deposit\\n * @param staked true if this entity is staked.\\n * @param stake actual amount of ether staked for this entity.\\n * @param unstakeDelaySec minimum delay to withdraw the stake.\\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\\n * and the rest fit into a 2nd cell.\\n * 112 bit allows for 10^15 eth\\n * 48 bit for full timestamp\\n * 32 bit allows 150 years for unstake delay\\n */\\n struct DepositInfo {\\n uint112 deposit;\\n bool staked;\\n uint112 stake;\\n uint32 unstakeDelaySec;\\n uint48 withdrawTime;\\n }\\n\\n //API struct used by getStakeInfo and simulateValidation\\n struct StakeInfo {\\n uint256 stake;\\n uint256 unstakeDelaySec;\\n }\\n\\n /// @return info - full deposit information of given account\\n function getDepositInfo(\\n address account\\n ) external view returns (DepositInfo memory info);\\n\\n /// @return the deposit (for gas payment) of the account\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * add to the deposit of the given account\\n */\\n function depositTo(address account) external payable;\\n\\n /**\\n * add to the account's stake - amount and delay\\n * any pending unstake is first cancelled.\\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\\n */\\n function addStake(uint32 _unstakeDelaySec) external payable;\\n\\n /**\\n * attempt to unlock the stake.\\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\\n */\\n function unlockStake() external;\\n\\n /**\\n * withdraw from the (unlocked) stake.\\n * must first call unlockStake and wait for the unstakeDelay to pass\\n * @param withdrawAddress the address to send withdrawn value.\\n */\\n function withdrawStake(address payable withdrawAddress) external;\\n\\n /**\\n * withdraw from the deposit.\\n * @param withdrawAddress the address to send withdrawn value.\\n * @param withdrawAmount the amount to withdraw.\\n */\\n function withdrawTo(\\n address payable withdrawAddress,\\n uint256 withdrawAmount\\n ) external;\\n}\\n\",\"keccak256\":\"0xadcea606c9b7aafe6645441f2154a60f271330b0eee5292a632aa71c1672d546\",\"license\":\"GPL-3.0-only\"},\"contracts/aa-4337/interfaces/UserOperation.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable no-inline-assembly */\\n\\nimport {calldataKeccak} from \\\"../core/Helpers.sol\\\";\\n\\n/**\\n * User Operation struct\\n * @param sender the sender account of this request.\\n * @param nonce unique value the sender uses to verify it is not a replay.\\n * @param initCode if set, the account contract will be created by this constructor/\\n * @param callData the method call to execute on this account.\\n * @param callGasLimit the gas limit passed to the callData method call.\\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\\n * @param maxFeePerGas same as EIP-1559 gas parameter.\\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\\n */\\nstruct UserOperation {\\n address sender;\\n uint256 nonce;\\n bytes initCode;\\n bytes callData;\\n uint256 callGasLimit;\\n uint256 verificationGasLimit;\\n uint256 preVerificationGas;\\n uint256 maxFeePerGas;\\n uint256 maxPriorityFeePerGas;\\n bytes paymasterAndData;\\n bytes signature;\\n}\\n\\n/**\\n * Utility functions helpful when working with UserOperation structs.\\n */\\nlibrary UserOperationLib {\\n function getSender(\\n UserOperation calldata userOp\\n ) internal pure returns (address) {\\n address data;\\n //read sender from userOp, which is first userOp member (saves 800 gas...)\\n assembly {\\n data := calldataload(userOp)\\n }\\n return address(uint160(data));\\n }\\n\\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\\n // pay above what he signed for.\\n function gasPrice(\\n UserOperation calldata userOp\\n ) internal view returns (uint256) {\\n unchecked {\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n if (maxFeePerGas == maxPriorityFeePerGas) {\\n //legacy mode (for networks that don't support basefee opcode)\\n return maxFeePerGas;\\n }\\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\\n }\\n }\\n\\n function pack(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes memory ret) {\\n address sender = getSender(userOp);\\n uint256 nonce = userOp.nonce;\\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\\n bytes32 hashCallData = calldataKeccak(userOp.callData);\\n uint256 callGasLimit = userOp.callGasLimit;\\n uint256 verificationGasLimit = userOp.verificationGasLimit;\\n uint256 preVerificationGas = userOp.preVerificationGas;\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\\n\\n return\\n abi.encode(\\n sender,\\n nonce,\\n hashInitCode,\\n hashCallData,\\n callGasLimit,\\n verificationGasLimit,\\n preVerificationGas,\\n maxFeePerGas,\\n maxPriorityFeePerGas,\\n hashPaymasterAndData\\n );\\n }\\n\\n function hash(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes32) {\\n return keccak256(pack(userOp));\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n}\\n\",\"keccak256\":\"0x2429f5cc546bdee08c7e63858d0dda8491eaa3ab5194df884dc948c1154d2834\",\"license\":\"GPL-3.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/facets/interfaces/IVerificationFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {UserOperation} from \\\"../../aa-4337/interfaces/UserOperation.sol\\\";\\n\\n/**\\n * @title Verification Facet Interface\\n * @dev Implements logic for user ops signature verification\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\ninterface IVerificationFacet {\\n event SignerInitialized(bytes);\\n event SignerUninitialized();\\n\\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\\n error VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\\n error VerificationFacet__InitializationFailure();\\n error VerificationFacet__InvalidFacetMapping();\\n\\n function initializeSigner(bytes memory) external returns (uint256);\\n\\n function uninitializeSigner() external returns (uint256);\\n\\n function validateOwnerSignatureSelector() external view returns (bytes4);\\n\\n function owner() external view returns (bytes memory);\\n\\n function isValidKeyType(bytes calldata) external view returns (bool);\\n\\n function validateOwnerSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x72bc370a1d1b5a6d6bde67f5026733fd8f6ba434bb90e73b0bd8627fb1579928\",\"license\":\"Apache-2.0\"},\"contracts/facets/verification/secp256k1/Secp256k1VerificationFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {ECDSA} from \\\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\\\";\\nimport {UserOperation} from \\\"../../../aa-4337/interfaces/UserOperation.sol\\\";\\nimport {LibAppStorage} from \\\"../../../libraries/LibAppStorage.sol\\\";\\nimport {LibFacetStorage, Secp256k1VerificationStorage} from \\\"../../../libraries/LibFacetStorage.sol\\\";\\nimport {LibLoupe} from \\\"../../../libraries/LibLoupe.sol\\\";\\nimport {IERC1271} from \\\"../../../interfaces/ERC/IERC1271.sol\\\";\\nimport {IVerificationFacet} from \\\"../../interfaces/IVerificationFacet.sol\\\";\\n\\n/**\\n * @title Secp256k1 verification facet\\n * @dev Default Ethereum's elliptic curve\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\ncontract Secp256k1VerificationFacet is IVerificationFacet, IERC1271 {\\n using ECDSA for bytes32;\\n error Secp256k1VerificationFacet__InvalidSignerLength();\\n address public immutable self;\\n\\n /**\\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\\n */\\n constructor() {\\n LibAppStorage.enforceSignerInitialize();\\n self = address(this);\\n }\\n\\n /**\\n * @notice Initializes the signer in K1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\\n * @param _publicKey Bytes of owner public key\\n * @return initSuccess Uint value representing the success of init operation\\n */\\n function initializeSigner(\\n bytes calldata _publicKey\\n ) public override returns (uint256 initSuccess) {\\n LibAppStorage.enforceSignerInitialize();\\n if (!isValidKeyType(_publicKey))\\n revert Secp256k1VerificationFacet__InvalidSignerLength();\\n\\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\\n .k1Storage();\\n k1Storage.signer = address(uint160(uint256(keccak256(_publicKey[1:]))));\\n\\n bytes4 validateSelector = validateOwnerSignatureSelector();\\n\\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\\n if (LibLoupe.facetAddress(validateSelector) != self)\\n revert VerificationFacet__InvalidFacetMapping();\\n\\n // initialize verification function selector\\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\\n\\n initSuccess = 1;\\n\\n emit SignerInitialized(_publicKey);\\n }\\n\\n /**\\n * @notice Uninitialize signer in K1 Facet Storage. This can only be called when the account is undergoing signature migration\\n * and has already been initialized.\\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\\n * @return uninitSuccess Uint value representing the success of uninit operation\\n */\\n function uninitializeSigner()\\n external\\n override\\n returns (uint256 uninitSuccess)\\n {\\n LibAppStorage.enforceSignerMigration();\\n LibAppStorage.setSignerUninitialized();\\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\\n .k1Storage();\\n k1Storage.signer = address(0);\\n\\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\\n\\n uninitSuccess = 1;\\n\\n emit SignerUninitialized();\\n }\\n\\n /**\\n * @notice Validates if the user operation is signed by the owner.\\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\\n * signer public key.\\n * @param userOp UserOperation including all information for execution\\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\\n */\\n function validateOwnerSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) public view override returns (uint256 validationData) {\\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\\n .k1Storage();\\n validationData = validateSignature(\\n userOp,\\n userOpHash,\\n k1Storage.signer\\n );\\n }\\n\\n /**\\n * @notice Validates if the signature of UserOperation is signed by the given signer\\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\\n * @param userOp UserOperation including all information for execution\\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\\n * @param signer Address of signer who signed the contract, to be validated\\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\\n */\\n function validateSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n address signer\\n ) public pure returns (uint256 isValid) {\\n bytes32 hash = userOpHash.toEthSignedMessageHash();\\n isValid = (signer != hash.recover(userOp.signature)) ? 1 : 0;\\n }\\n\\n /**\\n * @notice Returns the selector of function to validate the signature of UserOperation\\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\\n */\\n function validateOwnerSignatureSelector()\\n public\\n pure\\n override\\n returns (bytes4 ownerSignatureValidatorSelector)\\n {\\n ownerSignatureValidatorSelector = this.validateOwnerSignature.selector;\\n // NOTE: The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\\n }\\n\\n /**\\n * @notice Returns the owner of the account\\n * @return signer Bytes of owner address\\n */\\n function owner() public view override returns (bytes memory signer) {\\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\\n .k1Storage();\\n signer = abi.encodePacked(k1Storage.signer);\\n }\\n\\n /**\\n * @notice Validates if the format of public key is valid for this verification facet\\n * @dev For this Secp256k1Verification Facet, the public key length should be 65 in an uncompressed public key format\\n * @param _publicKey Bytes of public key for format check\\n * @return isValid Boolean variable representing if the format of public key is valid\\n */\\n function isValidKeyType(\\n bytes memory _publicKey\\n ) public pure override returns (bool isValid) {\\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\\n }\\n\\n /**\\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\\n * @param _hash Hash value the owner signed\\n * @param _signature Signature that signed the above hash\\n * @return magicValue Bytes4 value representing the success/failure of validation\\n */\\n function isValidSignature(\\n bytes32 _hash,\\n bytes memory _signature\\n ) public view override returns (bytes4 magicValue) {\\n magicValue = (_hash.recover(_signature) ==\\n LibFacetStorage.k1Storage().signer)\\n ? this.isValidSignature.selector\\n : bytes4(0xffffffff);\\n }\\n}\\n\",\"keccak256\":\"0x293ca694d0bad996df8b6d83a4bfdc4e5c3b3bc2e3f19e046c280e0233dbd806\",\"license\":\"Apache-2.0\"},\"contracts/infrastructure/interfaces/IFacetRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Registry Interface\\n * @dev Interface for Facet Registry contract to keep track of facets & function selectors addable to user wallets\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IFacetRegistry {\\n struct FacetRegistryConfig {\\n bytes4[] selectors;\\n mapping(bytes4 => FacetInfo) info;\\n }\\n struct FacetInfo {\\n bool exists;\\n uint128 index;\\n }\\n\\n event FacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] facetSelectors\\n );\\n event FacetFunctionSelectorsRemoved(address facet, bytes4[] facetSelectors);\\n\\n error FacetRegistry__FacetSelectorAlreadyRegistered();\\n error FacetRegistry__UnregisteredFacetSelector();\\n\\n function registerFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function removeFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function areFacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external view returns (bool);\\n\\n function isFacetFunctionSelectorRegistered(\\n address facet,\\n bytes4 facetSelector\\n ) external view returns (bool);\\n\\n function getFacetFunctionSelectors(\\n address facet\\n ) external view returns (bytes4[] memory);\\n}\\n\",\"keccak256\":\"0x6e6dd2cab346ef7c31230740ec48d2925e4a9ab24c2f2fb268baaf408dcf02ef\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC1271 {\\n function isValidSignature(\\n bytes32 hash,\\n bytes memory signature\\n ) external view returns (bytes4);\\n}\\n\",\"keccak256\":\"0xcdddb7d5641c9d3f2432dec7fd13fddb9ae1480f25c76c21511e2fa16b8bd422\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibAppStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {SafeCast} from \\\"@openzeppelin/contracts/utils/math/SafeCast.sol\\\";\\nimport {IEntryPoint} from \\\"../aa-4337/interfaces/IEntryPoint.sol\\\";\\nimport {IFacetRegistry} from \\\"../infrastructure/interfaces/IFacetRegistry.sol\\\";\\n\\n/*\\n * @title App Storage\\n * @dev App storage for Barz contract to prevent storage collision\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Lock {\\n uint64 release;\\n bytes4 locker;\\n}\\n\\nstruct InitializersStorage {\\n // NOTE: initialized is a variable to make sure the initialization is only done once.\\n uint8 signerInitialized;\\n uint8 accountInitialized;\\n uint8 restrictionsInitialized;\\n}\\n\\nstruct AppStorage {\\n mapping(uint256 => InitializersStorage) initStorage;\\n uint8 signerMigration;\\n bytes4 validateOwnerSignatureSelector;\\n IEntryPoint entryPoint;\\n IFacetRegistry facetRegistry;\\n mapping(uint256 => Lock) locks;\\n}\\n\\nlibrary LibAppStorage {\\n error LibAppStorage__AccountAlreadyUninitialized();\\n error LibAppStorage__AccountMustBeUninitialized();\\n error LibAppStorage__SignerAlreadyUninitialized();\\n error LibAppStorage__SignerMustBeUninitialized();\\n\\n function appStorage() internal pure returns (AppStorage storage ds) {\\n assembly {\\n ds.slot := 0\\n }\\n }\\n\\n function setSignerUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerAlreadyUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 0;\\n }\\n\\n function getValidateOwnerSignatureSelector()\\n internal\\n view\\n returns (bytes4 selector)\\n {\\n selector = appStorage().validateOwnerSignatureSelector;\\n }\\n\\n function setValidateOwnerSignatureSelector(\\n bytes4 _validateOwnerSignatureSelector\\n ) internal {\\n appStorage()\\n .validateOwnerSignatureSelector = _validateOwnerSignatureSelector;\\n }\\n\\n function enforceSignerInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerMustBeUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 1;\\n }\\n\\n function enforceAccountInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].accountInitialized) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n s.initStorage[0].accountInitialized = 1;\\n }\\n\\n function initiateSignerMigration() internal {\\n appStorage().signerMigration = 1;\\n }\\n\\n function enforceSignerMigration() internal view {\\n if (1 != appStorage().signerMigration) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n }\\n\\n function finalizeSignerMigration() internal {\\n appStorage().signerMigration = 0;\\n }\\n\\n function setLock(uint256 _releaseAfter, bytes4 _locker) internal {\\n appStorage().locks[0] = Lock(SafeCast.toUint64(_releaseAfter), _locker);\\n }\\n\\n function enforceRestrictionsInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__SignerMustBeUninitialized();\\n s.initStorage[0].restrictionsInitialized = 1;\\n }\\n\\n function setRestrictionsUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__AccountAlreadyUninitialized();\\n s.initStorage[0].restrictionsInitialized = 0;\\n }\\n}\\n\\ncontract BarzStorage {\\n AppStorage internal s;\\n modifier onlyWhenUnlocked() {\\n require(\\n uint64(block.timestamp) >= s.locks[0].release,\\n \\\"Account Locked\\\"\\n );\\n _;\\n }\\n modifier onlyWhenLocked() {\\n require(\\n uint64(block.timestamp) < s.locks[0].release,\\n \\\"Account Unlocked\\\"\\n );\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x48524007862a6ce0e07f645950613ce6513ce073c37a109c75019683d42bae27\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\\n bytes4(keccak256(\\\"verifyRestrictions(address,address,uint256,bytes)\\\"));\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // Default Fallback Handler of the barz.\\n IDiamondLoupe defaultFallbackHandler;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function enforceIsSelf() internal view {\\n require(msg.sender == address(this), \\\"LibDiamond: Caller not self\\\");\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n\\n unchecked {\\n facetIndex++;\\n }\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n\\n function restrictionsFacet() internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(\\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2cabdc00de859c3a3170ce3bda5d0e5fd3933d47ce904fd1585f9818b02572f8\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibFacetStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Storage\\n * @dev Storage contract to store each facets variables with diamond storage\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Secp256k1VerificationStorage {\\n address signer;\\n}\\n\\nstruct Secp256r1VerificationStorage {\\n uint256[2] q;\\n}\\n\\nstruct GuardianStorage {\\n mapping(bytes32 => uint256) pending;\\n mapping(uint8 => StorageConfig) configs;\\n}\\n\\nstruct Info {\\n bool exists;\\n uint128 index;\\n}\\n\\nstruct StorageConfig {\\n address[] addresses;\\n mapping(address => Info) info;\\n}\\n\\nstruct RecoveryConfig {\\n bytes recoveryPublicKey;\\n uint64 executeAfter;\\n}\\n\\nstruct ApprovalConfig {\\n bool isApproved;\\n uint64 validUntil;\\n}\\n\\nstruct RecoveryApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isNewOwnerApproved;\\n}\\n\\nstruct RecoveryStorage {\\n mapping(uint8 => RecoveryConfig) recoveryConfigs;\\n mapping(uint8 => RecoveryApprovalConfig) recoveryApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct RestrictionsStorage {\\n address[] restrictions;\\n mapping(address => bool) exists;\\n}\\n\\nstruct SignatureMigrationConfig {\\n bytes migrationPublicKey;\\n address migrationVerificationFacet;\\n bytes4[] migrationSelectors;\\n uint64 migrateAfter;\\n}\\n\\nstruct SignatureMigrationApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isMigrationApproved;\\n}\\n\\nstruct SignatureMigrationStorage {\\n mapping(uint8 => SignatureMigrationConfig) migrationConfigs;\\n mapping(uint8 => SignatureMigrationApprovalConfig) migrationApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct DiamondCutApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isDiamondCutApproved;\\n}\\n\\nstruct DiamondCutStorage {\\n mapping(uint8 => DiamondCutApprovalConfig) diamondCutApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct LockStorage {\\n uint128 nonce;\\n}\\n\\nlibrary LibFacetStorage {\\n bytes32 constant K1_STORAGE_POSITION =\\n keccak256(\\n \\\"v0.trustwallet.diamond.storage.Secp256k1VerificationStorage\\\"\\n );\\n bytes32 constant R1_STORAGE_POSITION =\\n keccak256(\\n \\\"v0.trustwallet.diamond.storage.Secp256r1VerificationStorage\\\"\\n );\\n bytes32 constant GUARDIAN_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.GuardianStorage\\\");\\n bytes32 constant RECOVERY_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.RecoveryStorage\\\");\\n bytes32 constant RESTRICTION_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.RestrictionsStorage\\\");\\n bytes32 constant MIGRATION_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.SignatureMigrationStorage\\\");\\n bytes32 constant DIAMONDCUT_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.DiamondCutStorage\\\");\\n bytes32 constant LOCK_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.LockStorage\\\");\\n\\n function k1Storage()\\n internal\\n pure\\n returns (Secp256k1VerificationStorage storage ds)\\n {\\n bytes32 storagePosition = K1_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function r1Storage()\\n internal\\n pure\\n returns (Secp256r1VerificationStorage storage ds)\\n {\\n bytes32 storagePosition = R1_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function guardianStorage()\\n internal\\n pure\\n returns (GuardianStorage storage ds)\\n {\\n bytes32 storagePosition = GUARDIAN_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function recoveryStorage()\\n internal\\n pure\\n returns (RecoveryStorage storage ds)\\n {\\n bytes32 storagePosition = RECOVERY_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function restrictionsStorage()\\n internal\\n pure\\n returns (RestrictionsStorage storage ds)\\n {\\n bytes32 storagePosition = RESTRICTION_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function migrationStorage()\\n internal\\n pure\\n returns (SignatureMigrationStorage storage ds)\\n {\\n bytes32 storagePosition = MIGRATION_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function diamondCutStorage()\\n internal\\n pure\\n returns (DiamondCutStorage storage ds)\\n {\\n bytes32 storagePosition = DIAMONDCUT_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function lockStorage() internal pure returns (LockStorage storage ds) {\\n bytes32 storagePosition = LOCK_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n}\\n\",\"keccak256\":\"0x87c85decfd943deda9540733e464cb1a92eba735a301e89ce6f798016e359761\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\nimport {LibDiamond} from \\\"./LibDiamond.sol\\\";\\n\\n/**\\n * @title LibLoupe\\n * @dev Internal Library to provide utility feature for reading the state of diamond facets\\n * Originally from Diamond's implementation of Mudgen(author of EIP-2535)\\n */\\nlibrary LibLoupe {\\n /// @notice Gets all facets and their selectors.\\n /// @return facets_ Facet\\n function facets()\\n internal\\n view\\n returns (IDiamondLoupe.Facet[] memory facets_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facets_ = new IDiamondLoupe.Facet[](ds.selectorCount);\\n uint16[] memory numFacetSelectors = new uint16[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facets_[facetIndex].facetAddress == facetAddress_) {\\n facets_[facetIndex].functionSelectors[\\n numFacetSelectors[facetIndex]\\n ] = selector;\\n // probably will never have more than 256 functions from one facet contract\\n require(numFacetSelectors[facetIndex] < 255);\\n numFacetSelectors[facetIndex]++;\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facets_[numFacets].facetAddress = facetAddress_;\\n facets_[numFacets].functionSelectors = new bytes4[](\\n ds.selectorCount\\n );\\n facets_[numFacets].functionSelectors[0] = selector;\\n numFacetSelectors[numFacets] = 1;\\n numFacets++;\\n }\\n }\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n uint256 numSelectors = numFacetSelectors[facetIndex];\\n bytes4[] memory selectors = facets_[facetIndex].functionSelectors;\\n // setting the number of selectors\\n assembly {\\n mstore(selectors, numSelectors)\\n }\\n }\\n // setting the number of facets\\n assembly {\\n mstore(facets_, numFacets)\\n }\\n }\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return _facetFunctionSelectors The selectors associated with a facet address.\\n function facetFunctionSelectors(\\n address _facet\\n ) internal view returns (bytes4[] memory _facetFunctionSelectors) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n uint256 numSelectors;\\n _facetFunctionSelectors = new bytes4[](ds.selectorCount);\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facet = address(bytes20(ds.facets[selector]));\\n if (_facet == facet) {\\n _facetFunctionSelectors[numSelectors] = selector;\\n numSelectors++;\\n }\\n }\\n }\\n // Set the number of selectors in the array\\n assembly {\\n mstore(_facetFunctionSelectors, numSelectors)\\n }\\n }\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n internal\\n view\\n returns (address[] memory facetAddresses_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetAddresses_ = new address[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facetAddress_ == facetAddresses_[facetIndex]) {\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facetAddresses_[numFacets] = facetAddress_;\\n numFacets++;\\n }\\n }\\n // Set the number of facet addresses in the array\\n assembly {\\n mstore(facetAddresses_, numFacets)\\n }\\n }\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(LibDiamond.diamondStorage().facets[_functionSelector])\\n );\\n }\\n}\\n\",\"keccak256\":\"0x0b11439c3cc657095e15ec2241fdcf67204b14001357b612fc5db4ff9e760a5a\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "storageLayout": { + "storage": [], + "types": null + }, + "userdoc": { + "kind": "user", + "methods": { + "constructor": { + "notice": "This constructor ensures that this contract can only be used as singleton for Proxy contracts" + }, + "initializeSigner(bytes)": { + "notice": "Initializes the signer in K1 Facet Storage. This can only be called when the account is uninitialized or during signature migration." + }, + "isValidKeyType(bytes)": { + "notice": "Validates if the format of public key is valid for this verification facet" + }, + "isValidSignature(bytes32,bytes)": { + "notice": "Validates if the signature is valid. Function to be compatible with EIP-1271" + }, + "owner()": { + "notice": "Returns the owner of the account" + }, + "uninitializeSigner()": { + "notice": "Uninitialize signer in K1 Facet Storage. This can only be called when the account is undergoing signature migration and has already been initialized." + }, + "validateOwnerSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32)": { + "notice": "Validates if the user operation is signed by the owner." + }, + "validateOwnerSignatureSelector()": { + "notice": "Returns the selector of function to validate the signature of UserOperation" + }, + "validateSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,address)": { + "notice": "Validates if the signature of UserOperation is signed by the given signer" + } + }, + "version": 1 + }, + "solcInput": "{\n \"language\": \"Solidity\",\n \"sources\": {\n \"@openzeppelin/contracts/access/Ownable.sol\": {\n \"content\": \"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor() {\\n _transferOwnership(_msgSender());\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n _checkOwner();\\n _;\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if the sender is not the owner.\\n */\\n function _checkOwner() internal view virtual {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby disabling any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _transferOwnership(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n}\\n\"\n },\n \"@openzeppelin/contracts/access/Ownable2Step.sol\": {\n \"content\": \"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./Ownable.sol\\\";\\n\\n/**\\n * @dev Contract module which provides access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership} and {acceptOwnership}.\\n *\\n * This module is used through inheritance. It will make available all functions\\n * from parent (Ownable).\\n */\\nabstract contract Ownable2Step is Ownable {\\n address private _pendingOwner;\\n\\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Returns the address of the pending owner.\\n */\\n function pendingOwner() public view virtual returns (address) {\\n return _pendingOwner;\\n }\\n\\n /**\\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual override onlyOwner {\\n _pendingOwner = newOwner;\\n emit OwnershipTransferStarted(owner(), newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual override {\\n delete _pendingOwner;\\n super._transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev The new owner accepts the ownership transfer.\\n */\\n function acceptOwnership() public virtual {\\n address sender = _msgSender();\\n require(pendingOwner() == sender, \\\"Ownable2Step: caller is not the new owner\\\");\\n _transferOwnership(sender);\\n }\\n}\\n\"\n },\n \"@openzeppelin/contracts/interfaces/IERC1271.sol\": {\n \"content\": \"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC1271 standard signature validation method for\\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC1271 {\\n /**\\n * @dev Should return whether the signature provided is valid for the provided data\\n * @param hash Hash of the data to be signed\\n * @param signature Signature byte array associated with _data\\n */\\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\\n}\\n\"\n },\n \"@openzeppelin/contracts/security/ReentrancyGuard.sol\": {\n \"content\": \"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuard {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n constructor() {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and making it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n _nonReentrantBefore();\\n _;\\n _nonReentrantAfter();\\n }\\n\\n function _nonReentrantBefore() private {\\n // On the first call to nonReentrant, _status will be _NOT_ENTERED\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n }\\n\\n function _nonReentrantAfter() private {\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Returns true if the reentrancy guard is currently set to \\\"entered\\\", which indicates there is a\\n * `nonReentrant` function in the call stack.\\n */\\n function _reentrancyGuardEntered() internal view returns (bool) {\\n return _status == _ENTERED;\\n }\\n}\\n\"\n },\n \"@openzeppelin/contracts/token/ERC1155/ERC1155.sol\": {\n \"content\": \"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/ERC1155.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC1155.sol\\\";\\nimport \\\"./IERC1155Receiver.sol\\\";\\nimport \\\"./extensions/IERC1155MetadataURI.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/Context.sol\\\";\\nimport \\\"../../utils/introspection/ERC165.sol\\\";\\n\\n/**\\n * @dev Implementation of the basic standard multi-token.\\n * See https://eips.ethereum.org/EIPS/eip-1155\\n * Originally based on code by Enjin: https://github.com/enjin/erc-1155\\n *\\n * _Available since v3.1._\\n */\\ncontract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {\\n using Address for address;\\n\\n // Mapping from token ID to account balances\\n mapping(uint256 => mapping(address => uint256)) private _balances;\\n\\n // Mapping from account to operator approvals\\n mapping(address => mapping(address => bool)) private _operatorApprovals;\\n\\n // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json\\n string private _uri;\\n\\n /**\\n * @dev See {_setURI}.\\n */\\n constructor(string memory uri_) {\\n _setURI(uri_);\\n }\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\\n return\\n interfaceId == type(IERC1155).interfaceId ||\\n interfaceId == type(IERC1155MetadataURI).interfaceId ||\\n super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev See {IERC1155MetadataURI-uri}.\\n *\\n * This implementation returns the same URI for *all* token types. It relies\\n * on the token type ID substitution mechanism\\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\\n *\\n * Clients calling this function must replace the `\\\\{id\\\\}` substring with the\\n * actual token type ID.\\n */\\n function uri(uint256) public view virtual override returns (string memory) {\\n return _uri;\\n }\\n\\n /**\\n * @dev See {IERC1155-balanceOf}.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n */\\n function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {\\n require(account != address(0), \\\"ERC1155: address zero is not a valid owner\\\");\\n return _balances[id][account];\\n }\\n\\n /**\\n * @dev See {IERC1155-balanceOfBatch}.\\n *\\n * Requirements:\\n *\\n * - `accounts` and `ids` must have the same length.\\n */\\n function balanceOfBatch(\\n address[] memory accounts,\\n uint256[] memory ids\\n ) public view virtual override returns (uint256[] memory) {\\n require(accounts.length == ids.length, \\\"ERC1155: accounts and ids length mismatch\\\");\\n\\n uint256[] memory batchBalances = new uint256[](accounts.length);\\n\\n for (uint256 i = 0; i < accounts.length; ++i) {\\n batchBalances[i] = balanceOf(accounts[i], ids[i]);\\n }\\n\\n return batchBalances;\\n }\\n\\n /**\\n * @dev See {IERC1155-setApprovalForAll}.\\n */\\n function setApprovalForAll(address operator, bool approved) public virtual override {\\n _setApprovalForAll(_msgSender(), operator, approved);\\n }\\n\\n /**\\n * @dev See {IERC1155-isApprovedForAll}.\\n */\\n function isApprovedForAll(address account, address operator) public view virtual override returns (bool) {\\n return _operatorApprovals[account][operator];\\n }\\n\\n /**\\n * @dev See {IERC1155-safeTransferFrom}.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 id,\\n uint256 amount,\\n bytes memory data\\n ) public virtual override {\\n require(\\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\\n \\\"ERC1155: caller is not token owner or approved\\\"\\n );\\n _safeTransferFrom(from, to, id, amount, data);\\n }\\n\\n /**\\n * @dev See {IERC1155-safeBatchTransferFrom}.\\n */\\n function safeBatchTransferFrom(\\n address from,\\n address to,\\n uint256[] memory ids,\\n uint256[] memory amounts,\\n bytes memory data\\n ) public virtual override {\\n require(\\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\\n \\\"ERC1155: caller is not token owner or approved\\\"\\n );\\n _safeBatchTransferFrom(from, to, ids, amounts, data);\\n }\\n\\n /**\\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\\n *\\n * Emits a {TransferSingle} event.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\\n * acceptance magic value.\\n */\\n function _safeTransferFrom(\\n address from,\\n address to,\\n uint256 id,\\n uint256 amount,\\n bytes memory data\\n ) internal virtual {\\n require(to != address(0), \\\"ERC1155: transfer to the zero address\\\");\\n\\n address operator = _msgSender();\\n uint256[] memory ids = _asSingletonArray(id);\\n uint256[] memory amounts = _asSingletonArray(amount);\\n\\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\\n\\n uint256 fromBalance = _balances[id][from];\\n require(fromBalance >= amount, \\\"ERC1155: insufficient balance for transfer\\\");\\n unchecked {\\n _balances[id][from] = fromBalance - amount;\\n }\\n _balances[id][to] += amount;\\n\\n emit TransferSingle(operator, from, to, id, amount);\\n\\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\\n\\n _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);\\n }\\n\\n /**\\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_safeTransferFrom}.\\n *\\n * Emits a {TransferBatch} event.\\n *\\n * Requirements:\\n *\\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\\n * acceptance magic value.\\n */\\n function _safeBatchTransferFrom(\\n address from,\\n address to,\\n uint256[] memory ids,\\n uint256[] memory amounts,\\n bytes memory data\\n ) internal virtual {\\n require(ids.length == amounts.length, \\\"ERC1155: ids and amounts length mismatch\\\");\\n require(to != address(0), \\\"ERC1155: transfer to the zero address\\\");\\n\\n address operator = _msgSender();\\n\\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\\n\\n for (uint256 i = 0; i < ids.length; ++i) {\\n uint256 id = ids[i];\\n uint256 amount = amounts[i];\\n\\n uint256 fromBalance = _balances[id][from];\\n require(fromBalance >= amount, \\\"ERC1155: insufficient balance for transfer\\\");\\n unchecked {\\n _balances[id][from] = fromBalance - amount;\\n }\\n _balances[id][to] += amount;\\n }\\n\\n emit TransferBatch(operator, from, to, ids, amounts);\\n\\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\\n\\n _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);\\n }\\n\\n /**\\n * @dev Sets a new URI for all token types, by relying on the token type ID\\n * substitution mechanism\\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\\n *\\n * By this mechanism, any occurrence of the `\\\\{id\\\\}` substring in either the\\n * URI or any of the amounts in the JSON file at said URI will be replaced by\\n * clients with the token type ID.\\n *\\n * For example, the `https://token-cdn-domain/\\\\{id\\\\}.json` URI would be\\n * interpreted by clients as\\n * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`\\n * for token type ID 0x4cce0.\\n *\\n * See {uri}.\\n *\\n * Because these URIs cannot be meaningfully represented by the {URI} event,\\n * this function emits no events.\\n */\\n function _setURI(string memory newuri) internal virtual {\\n _uri = newuri;\\n }\\n\\n /**\\n * @dev Creates `amount` tokens of token type `id`, and assigns them to `to`.\\n *\\n * Emits a {TransferSingle} event.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\\n * acceptance magic value.\\n */\\n function _mint(address to, uint256 id, uint256 amount, bytes memory data) internal virtual {\\n require(to != address(0), \\\"ERC1155: mint to the zero address\\\");\\n\\n address operator = _msgSender();\\n uint256[] memory ids = _asSingletonArray(id);\\n uint256[] memory amounts = _asSingletonArray(amount);\\n\\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\\n\\n _balances[id][to] += amount;\\n emit TransferSingle(operator, address(0), to, id, amount);\\n\\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\\n\\n _doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data);\\n }\\n\\n /**\\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.\\n *\\n * Emits a {TransferBatch} event.\\n *\\n * Requirements:\\n *\\n * - `ids` and `amounts` must have the same length.\\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\\n * acceptance magic value.\\n */\\n function _mintBatch(\\n address to,\\n uint256[] memory ids,\\n uint256[] memory amounts,\\n bytes memory data\\n ) internal virtual {\\n require(to != address(0), \\\"ERC1155: mint to the zero address\\\");\\n require(ids.length == amounts.length, \\\"ERC1155: ids and amounts length mismatch\\\");\\n\\n address operator = _msgSender();\\n\\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\\n\\n for (uint256 i = 0; i < ids.length; i++) {\\n _balances[ids[i]][to] += amounts[i];\\n }\\n\\n emit TransferBatch(operator, address(0), to, ids, amounts);\\n\\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\\n\\n _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens of token type `id` from `from`\\n *\\n * Emits a {TransferSingle} event.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `from` must have at least `amount` tokens of token type `id`.\\n */\\n function _burn(address from, uint256 id, uint256 amount) internal virtual {\\n require(from != address(0), \\\"ERC1155: burn from the zero address\\\");\\n\\n address operator = _msgSender();\\n uint256[] memory ids = _asSingletonArray(id);\\n uint256[] memory amounts = _asSingletonArray(amount);\\n\\n _beforeTokenTransfer(operator, from, address(0), ids, amounts, \\\"\\\");\\n\\n uint256 fromBalance = _balances[id][from];\\n require(fromBalance >= amount, \\\"ERC1155: burn amount exceeds balance\\\");\\n unchecked {\\n _balances[id][from] = fromBalance - amount;\\n }\\n\\n emit TransferSingle(operator, from, address(0), id, amount);\\n\\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \\\"\\\");\\n }\\n\\n /**\\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.\\n *\\n * Emits a {TransferBatch} event.\\n *\\n * Requirements:\\n *\\n * - `ids` and `amounts` must have the same length.\\n */\\n function _burnBatch(address from, uint256[] memory ids, uint256[] memory amounts) internal virtual {\\n require(from != address(0), \\\"ERC1155: burn from the zero address\\\");\\n require(ids.length == amounts.length, \\\"ERC1155: ids and amounts length mismatch\\\");\\n\\n address operator = _msgSender();\\n\\n _beforeTokenTransfer(operator, from, address(0), ids, amounts, \\\"\\\");\\n\\n for (uint256 i = 0; i < ids.length; i++) {\\n uint256 id = ids[i];\\n uint256 amount = amounts[i];\\n\\n uint256 fromBalance = _balances[id][from];\\n require(fromBalance >= amount, \\\"ERC1155: burn amount exceeds balance\\\");\\n unchecked {\\n _balances[id][from] = fromBalance - amount;\\n }\\n }\\n\\n emit TransferBatch(operator, from, address(0), ids, amounts);\\n\\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \\\"\\\");\\n }\\n\\n /**\\n * @dev Approve `operator` to operate on all of `owner` tokens\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {\\n require(owner != operator, \\\"ERC1155: setting approval status for self\\\");\\n _operatorApprovals[owner][operator] = approved;\\n emit ApprovalForAll(owner, operator, approved);\\n }\\n\\n /**\\n * @dev Hook that is called before any token transfer. This includes minting\\n * and burning, as well as batched variants.\\n *\\n * The same hook is called on both single and batched variants. For single\\n * transfers, the length of the `ids` and `amounts` arrays will be 1.\\n *\\n * Calling conditions (for each `id` and `amount` pair):\\n *\\n * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * of token type `id` will be transferred to `to`.\\n * - When `from` is zero, `amount` tokens of token type `id` will be minted\\n * for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\\n * will be burned.\\n * - `from` and `to` are never both zero.\\n * - `ids` and `amounts` have the same, non-zero length.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address operator,\\n address from,\\n address to,\\n uint256[] memory ids,\\n uint256[] memory amounts,\\n bytes memory data\\n ) internal virtual {}\\n\\n /**\\n * @dev Hook that is called after any token transfer. This includes minting\\n * and burning, as well as batched variants.\\n *\\n * The same hook is called on both single and batched variants. For single\\n * transfers, the length of the `id` and `amount` arrays will be 1.\\n *\\n * Calling conditions (for each `id` and `amount` pair):\\n *\\n * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * of token type `id` will be transferred to `to`.\\n * - When `from` is zero, `amount` tokens of token type `id` will be minted\\n * for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\\n * will be burned.\\n * - `from` and `to` are never both zero.\\n * - `ids` and `amounts` have the same, non-zero length.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _afterTokenTransfer(\\n address operator,\\n address from,\\n address to,\\n uint256[] memory ids,\\n uint256[] memory amounts,\\n bytes memory data\\n ) internal virtual {}\\n\\n function _doSafeTransferAcceptanceCheck(\\n address operator,\\n address from,\\n address to,\\n uint256 id,\\n uint256 amount,\\n bytes memory data\\n ) private {\\n if (to.isContract()) {\\n try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\\n if (response != IERC1155Receiver.onERC1155Received.selector) {\\n revert(\\\"ERC1155: ERC1155Receiver rejected tokens\\\");\\n }\\n } catch Error(string memory reason) {\\n revert(reason);\\n } catch {\\n revert(\\\"ERC1155: transfer to non-ERC1155Receiver implementer\\\");\\n }\\n }\\n }\\n\\n function _doSafeBatchTransferAcceptanceCheck(\\n address operator,\\n address from,\\n address to,\\n uint256[] memory ids,\\n uint256[] memory amounts,\\n bytes memory data\\n ) private {\\n if (to.isContract()) {\\n try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (\\n bytes4 response\\n ) {\\n if (response != IERC1155Receiver.onERC1155BatchReceived.selector) {\\n revert(\\\"ERC1155: ERC1155Receiver rejected tokens\\\");\\n }\\n } catch Error(string memory reason) {\\n revert(reason);\\n } catch {\\n revert(\\\"ERC1155: transfer to non-ERC1155Receiver implementer\\\");\\n }\\n }\\n }\\n\\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {\\n uint256[] memory array = new uint256[](1);\\n array[0] = element;\\n\\n return array;\\n }\\n}\\n\"\n },\n \"@openzeppelin/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol\": {\n \"content\": \"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC1155.sol\\\";\\n\\n/**\\n * @dev Interface of the optional ERC1155MetadataExtension interface, as defined\\n * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].\\n *\\n * _Available since v3.1._\\n */\\ninterface IERC1155MetadataURI is IERC1155 {\\n /**\\n * @dev Returns the URI for token type `id`.\\n *\\n * If the `\\\\{id\\\\}` substring is present in the URI, it must be replaced by\\n * clients with the actual token type ID.\\n */\\n function uri(uint256 id) external view returns (string memory);\\n}\\n\"\n },\n \"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\": {\n \"content\": \"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/IERC1155.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/introspection/IERC165.sol\\\";\\n\\n/**\\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\\n *\\n * _Available since v3.1._\\n */\\ninterface IERC1155 is IERC165 {\\n /**\\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\\n */\\n event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);\\n\\n /**\\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\\n * transfers.\\n */\\n event TransferBatch(\\n address indexed operator,\\n address indexed from,\\n address indexed to,\\n uint256[] ids,\\n uint256[] values\\n );\\n\\n /**\\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\\n * `approved`.\\n */\\n event ApprovalForAll(address indexed account, address indexed operator, bool approved);\\n\\n /**\\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\\n *\\n * If an {URI} event was emitted for `id`, the standard\\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\\n * returned by {IERC1155MetadataURI-uri}.\\n */\\n event URI(string value, uint256 indexed id);\\n\\n /**\\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n */\\n function balanceOf(address account, uint256 id) external view returns (uint256);\\n\\n /**\\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\\n *\\n * Requirements:\\n *\\n * - `accounts` and `ids` must have the same length.\\n */\\n function balanceOfBatch(\\n address[] calldata accounts,\\n uint256[] calldata ids\\n ) external view returns (uint256[] memory);\\n\\n /**\\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\\n *\\n * Emits an {ApprovalForAll} event.\\n *\\n * Requirements:\\n *\\n * - `operator` cannot be the caller.\\n */\\n function setApprovalForAll(address operator, bool approved) external;\\n\\n /**\\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\\n *\\n * See {setApprovalForAll}.\\n */\\n function isApprovedForAll(address account, address operator) external view returns (bool);\\n\\n /**\\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\\n *\\n * Emits a {TransferSingle} event.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.\\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\\n * acceptance magic value.\\n */\\n function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external;\\n\\n /**\\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\\n *\\n * Emits a {TransferBatch} event.\\n *\\n * Requirements:\\n *\\n * - `ids` and `amounts` must have the same length.\\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\\n * acceptance magic value.\\n */\\n function safeBatchTransferFrom(\\n address from,\\n address to,\\n uint256[] calldata ids,\\n uint256[] calldata amounts,\\n bytes calldata data\\n ) external;\\n}\\n\"\n },\n \"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\": {\n \"content\": \"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/introspection/IERC165.sol\\\";\\n\\n/**\\n * @dev _Available since v3.1._\\n */\\ninterface IERC1155Receiver is IERC165 {\\n /**\\n * @dev Handles the receipt of a single ERC1155 token type. This function is\\n * called at the end of a `safeTransferFrom` after the balance has been updated.\\n *\\n * NOTE: To accept the transfer, this must return\\n * `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))`\\n * (i.e. 0xf23a6e61, or its own function selector).\\n *\\n * @param operator The address which initiated the transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param id The ID of the token being transferred\\n * @param value The amount of tokens being transferred\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155Received(\\n address operator,\\n address from,\\n uint256 id,\\n uint256 value,\\n bytes calldata data\\n ) external returns (bytes4);\\n\\n /**\\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\\n * is called at the end of a `safeBatchTransferFrom` after the balances have\\n * been updated.\\n *\\n * NOTE: To accept the transfer(s), this must return\\n * `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))`\\n * (i.e. 0xbc197c81, or its own function selector).\\n *\\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155BatchReceived(\\n address operator,\\n address from,\\n uint256[] calldata ids,\\n uint256[] calldata values,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\"\n },\n \"@openzeppelin/contracts/token/ERC20/ERC20.sol\": {\n \"content\": \"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"./extensions/IERC20Metadata.sol\\\";\\nimport \\\"../../utils/Context.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20PresetMinterPauser}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * The default value of {decimals} is 18. To change this, you should override\\n * this function so it returns a different value.\\n *\\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\\n * instead returning `false` on failure. This behavior is nonetheless\\n * conventional and does not conflict with the expectations of ERC20\\n * applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20 is Context, IERC20, IERC20Metadata {\\n mapping(address => uint256) private _balances;\\n\\n mapping(address => mapping(address => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}.\\n *\\n * All two of these values are immutable: they can only be set once during\\n * construction.\\n */\\n constructor(string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the default value returned by this function, unless\\n * it's overridden.\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual override returns (uint8) {\\n return 18;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n * - the caller must have a balance of at least `amount`.\\n */\\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _transfer(owner, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\\n * `transferFrom`. This is semantically equivalent to an infinite approval.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * NOTE: Does not update the allowance if the current allowance\\n * is the maximum `uint256`.\\n *\\n * Requirements:\\n *\\n * - `from` and `to` cannot be the zero address.\\n * - `from` must have a balance of at least `amount`.\\n * - the caller must have allowance for ``from``'s tokens of at least\\n * `amount`.\\n */\\n function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\\n address spender = _msgSender();\\n _spendAllowance(from, spender, amount);\\n _transfer(from, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, allowance(owner, spender) + addedValue);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n uint256 currentAllowance = allowance(owner, spender);\\n require(currentAllowance >= subtractedValue, \\\"ERC20: decreased allowance below zero\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - subtractedValue);\\n }\\n\\n return true;\\n }\\n\\n /**\\n * @dev Moves `amount` of tokens from `from` to `to`.\\n *\\n * This internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `from` must have a balance of at least `amount`.\\n */\\n function _transfer(address from, address to, uint256 amount) internal virtual {\\n require(from != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(to != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(from, to, amount);\\n\\n uint256 fromBalance = _balances[from];\\n require(fromBalance >= amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n unchecked {\\n _balances[from] = fromBalance - amount;\\n // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\\n // decrementing then incrementing.\\n _balances[to] += amount;\\n }\\n\\n emit Transfer(from, to, amount);\\n\\n _afterTokenTransfer(from, to, amount);\\n }\\n\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n */\\n function _mint(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: mint to the zero address\\\");\\n\\n _beforeTokenTransfer(address(0), account, amount);\\n\\n _totalSupply += amount;\\n unchecked {\\n // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\\n _balances[account] += amount;\\n }\\n emit Transfer(address(0), account, amount);\\n\\n _afterTokenTransfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n */\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n uint256 accountBalance = _balances[account];\\n require(accountBalance >= amount, \\\"ERC20: burn amount exceeds balance\\\");\\n unchecked {\\n _balances[account] = accountBalance - amount;\\n // Overflow not possible: amount <= accountBalance <= totalSupply.\\n _totalSupply -= amount;\\n }\\n\\n emit Transfer(account, address(0), amount);\\n\\n _afterTokenTransfer(account, address(0), amount);\\n }\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n */\\n function _approve(address owner, address spender, uint256 amount) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n /**\\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\\n *\\n * Does not update the allowance amount in case of infinite allowance.\\n * Revert if not enough allowance is available.\\n *\\n * Might emit an {Approval} event.\\n */\\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\\n uint256 currentAllowance = allowance(owner, spender);\\n if (currentAllowance != type(uint256).max) {\\n require(currentAllowance >= amount, \\\"ERC20: insufficient allowance\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - amount);\\n }\\n }\\n }\\n\\n /**\\n * @dev Hook that is called before any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * will be transferred to `to`.\\n * - when `from` is zero, `amount` tokens will be minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\\n\\n /**\\n * @dev Hook that is called after any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * has been transferred to `to`.\\n * - when `from` is zero, `amount` tokens have been minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\\n}\\n\"\n },\n \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\": {\n \"content\": \"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\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\"\n },\n \"@openzeppelin/contracts/token/ERC20/IERC20.sol\": {\n \"content\": \"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` 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 amount) 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 `amount` as the allowance of `spender` over the 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 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` 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 amount) external returns (bool);\\n}\\n\"\n },\n \"@openzeppelin/contracts/token/ERC721/ERC721.sol\": {\n \"content\": \"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/ERC721.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC721.sol\\\";\\nimport \\\"./IERC721Receiver.sol\\\";\\nimport \\\"./extensions/IERC721Metadata.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/Context.sol\\\";\\nimport \\\"../../utils/Strings.sol\\\";\\nimport \\\"../../utils/introspection/ERC165.sol\\\";\\n\\n/**\\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\\n * {ERC721Enumerable}.\\n */\\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\\n using Address for address;\\n using Strings for uint256;\\n\\n // Token name\\n string private _name;\\n\\n // Token symbol\\n string private _symbol;\\n\\n // Mapping from token ID to owner address\\n mapping(uint256 => address) private _owners;\\n\\n // Mapping owner address to token count\\n mapping(address => uint256) private _balances;\\n\\n // Mapping from token ID to approved address\\n mapping(uint256 => address) private _tokenApprovals;\\n\\n // Mapping from owner to operator approvals\\n mapping(address => mapping(address => bool)) private _operatorApprovals;\\n\\n /**\\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\\n */\\n constructor(string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\\n return\\n interfaceId == type(IERC721).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev See {IERC721-balanceOf}.\\n */\\n function balanceOf(address owner) public view virtual override returns (uint256) {\\n require(owner != address(0), \\\"ERC721: address zero is not a valid owner\\\");\\n return _balances[owner];\\n }\\n\\n /**\\n * @dev See {IERC721-ownerOf}.\\n */\\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\\n address owner = _ownerOf(tokenId);\\n require(owner != address(0), \\\"ERC721: invalid token ID\\\");\\n return owner;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-name}.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-symbol}.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-tokenURI}.\\n */\\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\\n _requireMinted(tokenId);\\n\\n string memory baseURI = _baseURI();\\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \\\"\\\";\\n }\\n\\n /**\\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\\n * by default, can be overridden in child contracts.\\n */\\n function _baseURI() internal view virtual returns (string memory) {\\n return \\\"\\\";\\n }\\n\\n /**\\n * @dev See {IERC721-approve}.\\n */\\n function approve(address to, uint256 tokenId) public virtual override {\\n address owner = ERC721.ownerOf(tokenId);\\n require(to != owner, \\\"ERC721: approval to current owner\\\");\\n\\n require(\\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\\n \\\"ERC721: approve caller is not token owner or approved for all\\\"\\n );\\n\\n _approve(to, tokenId);\\n }\\n\\n /**\\n * @dev See {IERC721-getApproved}.\\n */\\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\\n _requireMinted(tokenId);\\n\\n return _tokenApprovals[tokenId];\\n }\\n\\n /**\\n * @dev See {IERC721-setApprovalForAll}.\\n */\\n function setApprovalForAll(address operator, bool approved) public virtual override {\\n _setApprovalForAll(_msgSender(), operator, approved);\\n }\\n\\n /**\\n * @dev See {IERC721-isApprovedForAll}.\\n */\\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\\n return _operatorApprovals[owner][operator];\\n }\\n\\n /**\\n * @dev See {IERC721-transferFrom}.\\n */\\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\\n //solhint-disable-next-line max-line-length\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner or approved\\\");\\n\\n _transfer(from, to, tokenId);\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\\n safeTransferFrom(from, to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual override {\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner or approved\\\");\\n _safeTransfer(from, to, tokenId, data);\\n }\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * `data` is additional data, it has no specified format and it is sent in call to `to`.\\n *\\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\\n * implement alternative mechanisms to perform token transfer, such as signature-based.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _safeTransfer(address from, address to, uint256 tokenId, bytes memory data) internal virtual {\\n _transfer(from, to, tokenId);\\n require(_checkOnERC721Received(from, to, tokenId, data), \\\"ERC721: transfer to non ERC721Receiver implementer\\\");\\n }\\n\\n /**\\n * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist\\n */\\n function _ownerOf(uint256 tokenId) internal view virtual returns (address) {\\n return _owners[tokenId];\\n }\\n\\n /**\\n * @dev Returns whether `tokenId` exists.\\n *\\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\\n *\\n * Tokens start existing when they are minted (`_mint`),\\n * and stop existing when they are burned (`_burn`).\\n */\\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\\n return _ownerOf(tokenId) != address(0);\\n }\\n\\n /**\\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\\n address owner = ERC721.ownerOf(tokenId);\\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\\n }\\n\\n /**\\n * @dev Safely mints `tokenId` and transfers it to `to`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must not exist.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _safeMint(address to, uint256 tokenId) internal virtual {\\n _safeMint(to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\\n */\\n function _safeMint(address to, uint256 tokenId, bytes memory data) internal virtual {\\n _mint(to, tokenId);\\n require(\\n _checkOnERC721Received(address(0), to, tokenId, data),\\n \\\"ERC721: transfer to non ERC721Receiver implementer\\\"\\n );\\n }\\n\\n /**\\n * @dev Mints `tokenId` and transfers it to `to`.\\n *\\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\\n *\\n * Requirements:\\n *\\n * - `tokenId` must not exist.\\n * - `to` cannot be the zero address.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _mint(address to, uint256 tokenId) internal virtual {\\n require(to != address(0), \\\"ERC721: mint to the zero address\\\");\\n require(!_exists(tokenId), \\\"ERC721: token already minted\\\");\\n\\n _beforeTokenTransfer(address(0), to, tokenId, 1);\\n\\n // Check that tokenId was not minted by `_beforeTokenTransfer` hook\\n require(!_exists(tokenId), \\\"ERC721: token already minted\\\");\\n\\n unchecked {\\n // Will not overflow unless all 2**256 token ids are minted to the same owner.\\n // Given that tokens are minted one by one, it is impossible in practice that\\n // this ever happens. Might change if we allow batch minting.\\n // The ERC fails to describe this case.\\n _balances[to] += 1;\\n }\\n\\n _owners[tokenId] = to;\\n\\n emit Transfer(address(0), to, tokenId);\\n\\n _afterTokenTransfer(address(0), to, tokenId, 1);\\n }\\n\\n /**\\n * @dev Destroys `tokenId`.\\n * The approval is cleared when the token is burned.\\n * This is an internal function that does not check if the sender is authorized to operate on the token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _burn(uint256 tokenId) internal virtual {\\n address owner = ERC721.ownerOf(tokenId);\\n\\n _beforeTokenTransfer(owner, address(0), tokenId, 1);\\n\\n // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook\\n owner = ERC721.ownerOf(tokenId);\\n\\n // Clear approvals\\n delete _tokenApprovals[tokenId];\\n\\n unchecked {\\n // Cannot overflow, as that would require more tokens to be burned/transferred\\n // out than the owner initially received through minting and transferring in.\\n _balances[owner] -= 1;\\n }\\n delete _owners[tokenId];\\n\\n emit Transfer(owner, address(0), tokenId);\\n\\n _afterTokenTransfer(owner, address(0), tokenId, 1);\\n }\\n\\n /**\\n * @dev Transfers `tokenId` from `from` to `to`.\\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must be owned by `from`.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _transfer(address from, address to, uint256 tokenId) internal virtual {\\n require(ERC721.ownerOf(tokenId) == from, \\\"ERC721: transfer from incorrect owner\\\");\\n require(to != address(0), \\\"ERC721: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(from, to, tokenId, 1);\\n\\n // Check that tokenId was not transferred by `_beforeTokenTransfer` hook\\n require(ERC721.ownerOf(tokenId) == from, \\\"ERC721: transfer from incorrect owner\\\");\\n\\n // Clear approvals from the previous owner\\n delete _tokenApprovals[tokenId];\\n\\n unchecked {\\n // `_balances[from]` cannot overflow for the same reason as described in `_burn`:\\n // `from`'s balance is the number of token held, which is at least one before the current\\n // transfer.\\n // `_balances[to]` could overflow in the conditions described in `_mint`. That would require\\n // all 2**256 token ids to be minted, which in practice is impossible.\\n _balances[from] -= 1;\\n _balances[to] += 1;\\n }\\n _owners[tokenId] = to;\\n\\n emit Transfer(from, to, tokenId);\\n\\n _afterTokenTransfer(from, to, tokenId, 1);\\n }\\n\\n /**\\n * @dev Approve `to` to operate on `tokenId`\\n *\\n * Emits an {Approval} event.\\n */\\n function _approve(address to, uint256 tokenId) internal virtual {\\n _tokenApprovals[tokenId] = to;\\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\\n }\\n\\n /**\\n * @dev Approve `operator` to operate on all of `owner` tokens\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {\\n require(owner != operator, \\\"ERC721: approve to caller\\\");\\n _operatorApprovals[owner][operator] = approved;\\n emit ApprovalForAll(owner, operator, approved);\\n }\\n\\n /**\\n * @dev Reverts if the `tokenId` has not been minted yet.\\n */\\n function _requireMinted(uint256 tokenId) internal view virtual {\\n require(_exists(tokenId), \\\"ERC721: invalid token ID\\\");\\n }\\n\\n /**\\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\\n * The call is not executed if the target address is not a contract.\\n *\\n * @param from address representing the previous owner of the given token ID\\n * @param to target address that will receive the tokens\\n * @param tokenId uint256 ID of the token to be transferred\\n * @param data bytes optional data to send along with the call\\n * @return bool whether the call correctly returned the expected magic value\\n */\\n function _checkOnERC721Received(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) private returns (bool) {\\n if (to.isContract()) {\\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\\n return retval == IERC721Receiver.onERC721Received.selector;\\n } catch (bytes memory reason) {\\n if (reason.length == 0) {\\n revert(\\\"ERC721: transfer to non ERC721Receiver implementer\\\");\\n } else {\\n /// @solidity memory-safe-assembly\\n assembly {\\n revert(add(32, reason), mload(reason))\\n }\\n }\\n }\\n } else {\\n return true;\\n }\\n }\\n\\n /**\\n * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is\\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\\n *\\n * Calling conditions:\\n *\\n * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`.\\n * - When `from` is zero, the tokens will be minted for `to`.\\n * - When `to` is zero, ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n * - `batchSize` is non-zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}\\n\\n /**\\n * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is\\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\\n *\\n * Calling conditions:\\n *\\n * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`.\\n * - When `from` is zero, the tokens were minted for `to`.\\n * - When `to` is zero, ``from``'s tokens were burned.\\n * - `from` and `to` are never both zero.\\n * - `batchSize` is non-zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _afterTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}\\n\\n /**\\n * @dev Unsafe write access to the balances, used by extensions that \\\"mint\\\" tokens using an {ownerOf} override.\\n *\\n * WARNING: Anyone calling this MUST ensure that the balances remain consistent with the ownership. The invariant\\n * being that for any address `a` the value returned by `balanceOf(a)` must be equal to the number of tokens such\\n * that `ownerOf(tokenId)` is `a`.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function __unsafe_increaseBalance(address account, uint256 amount) internal {\\n _balances[account] += amount;\\n }\\n}\\n\"\n },\n \"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\": {\n \"content\": \"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Metadata is IERC721 {\\n /**\\n * @dev Returns the token collection name.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the token collection symbol.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\\n */\\n function tokenURI(uint256 tokenId) external view returns (string memory);\\n}\\n\"\n },\n \"@openzeppelin/contracts/token/ERC721/IERC721.sol\": {\n \"content\": \"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/IERC721.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/introspection/IERC165.sol\\\";\\n\\n/**\\n * @dev Required interface of an ERC721 compliant contract.\\n */\\ninterface IERC721 is IERC165 {\\n /**\\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\\n\\n /**\\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\\n */\\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\\n\\n /**\\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\\n */\\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\\n\\n /**\\n * @dev Returns the number of tokens in ``owner``'s account.\\n */\\n function balanceOf(address owner) external view returns (uint256 balance);\\n\\n /**\\n * @dev Returns the owner of the `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function ownerOf(uint256 tokenId) external view returns (address owner);\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Transfers `tokenId` token from `from` to `to`.\\n *\\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must be owned by `from`.\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address from, address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\\n * The approval is cleared when the token is transferred.\\n *\\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\\n *\\n * Requirements:\\n *\\n * - The caller must own the token or be an approved operator.\\n * - `tokenId` must exist.\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Approve or remove `operator` as an operator for the caller.\\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\\n *\\n * Requirements:\\n *\\n * - The `operator` cannot be the caller.\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function setApprovalForAll(address operator, bool approved) external;\\n\\n /**\\n * @dev Returns the account approved for `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function getApproved(uint256 tokenId) external view returns (address operator);\\n\\n /**\\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\\n *\\n * See {setApprovalForAll}\\n */\\n function isApprovedForAll(address owner, address operator) external view returns (bool);\\n}\\n\"\n },\n \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\": {\n \"content\": \"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title ERC721 token receiver interface\\n * @dev Interface for any contract that wants to support safeTransfers\\n * from ERC721 asset contracts.\\n */\\ninterface IERC721Receiver {\\n /**\\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\\n * by `operator` from `from`, this function is called.\\n *\\n * It must return its Solidity selector to confirm the token transfer.\\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\\n *\\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\\n */\\n function onERC721Received(\\n address operator,\\n address from,\\n uint256 tokenId,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\"\n },\n \"@openzeppelin/contracts/token/ERC777/ERC777.sol\": {\n \"content\": \"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC777/ERC777.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC777.sol\\\";\\nimport \\\"./IERC777Recipient.sol\\\";\\nimport \\\"./IERC777Sender.sol\\\";\\nimport \\\"../ERC20/IERC20.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/Context.sol\\\";\\nimport \\\"../../utils/introspection/IERC1820Registry.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC777} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n *\\n * Support for ERC20 is included in this contract, as specified by the EIP: both\\n * the ERC777 and ERC20 interfaces can be safely used when interacting with it.\\n * Both {IERC777-Sent} and {IERC20-Transfer} events are emitted on token\\n * movements.\\n *\\n * Additionally, the {IERC777-granularity} value is hard-coded to `1`, meaning that there\\n * are no special restrictions in the amount of tokens that created, moved, or\\n * destroyed. This makes integration with ERC20 applications seamless.\\n *\\n * CAUTION: This file is deprecated as of v4.9 and will be removed in the next major release.\\n */\\ncontract ERC777 is Context, IERC777, IERC20 {\\n using Address for address;\\n\\n IERC1820Registry internal constant _ERC1820_REGISTRY = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\\n\\n mapping(address => uint256) private _balances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n\\n bytes32 private constant _TOKENS_SENDER_INTERFACE_HASH = keccak256(\\\"ERC777TokensSender\\\");\\n bytes32 private constant _TOKENS_RECIPIENT_INTERFACE_HASH = keccak256(\\\"ERC777TokensRecipient\\\");\\n\\n // This isn't ever read from - it's only used to respond to the defaultOperators query.\\n address[] private _defaultOperatorsArray;\\n\\n // Immutable, but accounts may revoke them (tracked in __revokedDefaultOperators).\\n mapping(address => bool) private _defaultOperators;\\n\\n // For each account, a mapping of its operators and revoked default operators.\\n mapping(address => mapping(address => bool)) private _operators;\\n mapping(address => mapping(address => bool)) private _revokedDefaultOperators;\\n\\n // ERC20-allowances\\n mapping(address => mapping(address => uint256)) private _allowances;\\n\\n /**\\n * @dev `defaultOperators` may be an empty array.\\n */\\n constructor(string memory name_, string memory symbol_, address[] memory defaultOperators_) {\\n _name = name_;\\n _symbol = symbol_;\\n\\n _defaultOperatorsArray = defaultOperators_;\\n for (uint256 i = 0; i < defaultOperators_.length; i++) {\\n _defaultOperators[defaultOperators_[i]] = true;\\n }\\n\\n // register interfaces\\n _ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256(\\\"ERC777Token\\\"), address(this));\\n _ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256(\\\"ERC20Token\\\"), address(this));\\n }\\n\\n /**\\n * @dev See {IERC777-name}.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev See {IERC777-symbol}.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev See {ERC20-decimals}.\\n *\\n * Always returns 18, as per the\\n * [ERC777 EIP](https://eips.ethereum.org/EIPS/eip-777#backward-compatibility).\\n */\\n function decimals() public pure virtual returns (uint8) {\\n return 18;\\n }\\n\\n /**\\n * @dev See {IERC777-granularity}.\\n *\\n * This implementation always returns `1`.\\n */\\n function granularity() public view virtual override returns (uint256) {\\n return 1;\\n }\\n\\n /**\\n * @dev See {IERC777-totalSupply}.\\n */\\n function totalSupply() public view virtual override(IERC20, IERC777) returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev Returns the amount of tokens owned by an account (`tokenHolder`).\\n */\\n function balanceOf(address tokenHolder) public view virtual override(IERC20, IERC777) returns (uint256) {\\n return _balances[tokenHolder];\\n }\\n\\n /**\\n * @dev See {IERC777-send}.\\n *\\n * Also emits a {IERC20-Transfer} event for ERC20 compatibility.\\n */\\n function send(address recipient, uint256 amount, bytes memory data) public virtual override {\\n _send(_msgSender(), recipient, amount, data, \\\"\\\", true);\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Unlike `send`, `recipient` is _not_ required to implement the {IERC777Recipient}\\n * interface if it is a contract.\\n *\\n * Also emits a {Sent} event.\\n */\\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\\n _send(_msgSender(), recipient, amount, \\\"\\\", \\\"\\\", false);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC777-burn}.\\n *\\n * Also emits a {IERC20-Transfer} event for ERC20 compatibility.\\n */\\n function burn(uint256 amount, bytes memory data) public virtual override {\\n _burn(_msgSender(), amount, data, \\\"\\\");\\n }\\n\\n /**\\n * @dev See {IERC777-isOperatorFor}.\\n */\\n function isOperatorFor(address operator, address tokenHolder) public view virtual override returns (bool) {\\n return\\n operator == tokenHolder ||\\n (_defaultOperators[operator] && !_revokedDefaultOperators[tokenHolder][operator]) ||\\n _operators[tokenHolder][operator];\\n }\\n\\n /**\\n * @dev See {IERC777-authorizeOperator}.\\n */\\n function authorizeOperator(address operator) public virtual override {\\n require(_msgSender() != operator, \\\"ERC777: authorizing self as operator\\\");\\n\\n if (_defaultOperators[operator]) {\\n delete _revokedDefaultOperators[_msgSender()][operator];\\n } else {\\n _operators[_msgSender()][operator] = true;\\n }\\n\\n emit AuthorizedOperator(operator, _msgSender());\\n }\\n\\n /**\\n * @dev See {IERC777-revokeOperator}.\\n */\\n function revokeOperator(address operator) public virtual override {\\n require(operator != _msgSender(), \\\"ERC777: revoking self as operator\\\");\\n\\n if (_defaultOperators[operator]) {\\n _revokedDefaultOperators[_msgSender()][operator] = true;\\n } else {\\n delete _operators[_msgSender()][operator];\\n }\\n\\n emit RevokedOperator(operator, _msgSender());\\n }\\n\\n /**\\n * @dev See {IERC777-defaultOperators}.\\n */\\n function defaultOperators() public view virtual override returns (address[] memory) {\\n return _defaultOperatorsArray;\\n }\\n\\n /**\\n * @dev See {IERC777-operatorSend}.\\n *\\n * Emits {Sent} and {IERC20-Transfer} events.\\n */\\n function operatorSend(\\n address sender,\\n address recipient,\\n uint256 amount,\\n bytes memory data,\\n bytes memory operatorData\\n ) public virtual override {\\n require(isOperatorFor(_msgSender(), sender), \\\"ERC777: caller is not an operator for holder\\\");\\n _send(sender, recipient, amount, data, operatorData, true);\\n }\\n\\n /**\\n * @dev See {IERC777-operatorBurn}.\\n *\\n * Emits {Burned} and {IERC20-Transfer} events.\\n */\\n function operatorBurn(\\n address account,\\n uint256 amount,\\n bytes memory data,\\n bytes memory operatorData\\n ) public virtual override {\\n require(isOperatorFor(_msgSender(), account), \\\"ERC777: caller is not an operator for holder\\\");\\n _burn(account, amount, data, operatorData);\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n *\\n * Note that operator and allowance concepts are orthogonal: operators may\\n * not have allowance, and accounts with allowance may not be operators\\n * themselves.\\n */\\n function allowance(address holder, address spender) public view virtual override returns (uint256) {\\n return _allowances[holder][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on\\n * `transferFrom`. This is semantically equivalent to an infinite approval.\\n *\\n * Note that accounts cannot have allowance issued by their operators.\\n */\\n function approve(address spender, uint256 value) public virtual override returns (bool) {\\n address holder = _msgSender();\\n _approve(holder, spender, value);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * NOTE: Does not update the allowance if the current allowance\\n * is the maximum `uint256`.\\n *\\n * Note that operator and allowance concepts are orthogonal: operators cannot\\n * call `transferFrom` (unless they have allowance), and accounts with\\n * allowance cannot call `operatorSend` (unless they are operators).\\n *\\n * Emits {Sent}, {IERC20-Transfer} and {IERC20-Approval} events.\\n */\\n function transferFrom(address holder, address recipient, uint256 amount) public virtual override returns (bool) {\\n address spender = _msgSender();\\n _spendAllowance(holder, spender, amount);\\n _send(holder, recipient, amount, \\\"\\\", \\\"\\\", false);\\n return true;\\n }\\n\\n /**\\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * If a send hook is registered for `account`, the corresponding function\\n * will be called with the caller address as the `operator` and with\\n * `userData` and `operatorData`.\\n *\\n * See {IERC777Sender} and {IERC777Recipient}.\\n *\\n * Emits {Minted} and {IERC20-Transfer} events.\\n *\\n * Requirements\\n *\\n * - `account` cannot be the zero address.\\n * - if `account` is a contract, it must implement the {IERC777Recipient}\\n * interface.\\n */\\n function _mint(address account, uint256 amount, bytes memory userData, bytes memory operatorData) internal virtual {\\n _mint(account, amount, userData, operatorData, true);\\n }\\n\\n /**\\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * If `requireReceptionAck` is set to true, and if a send hook is\\n * registered for `account`, the corresponding function will be called with\\n * `operator`, `data` and `operatorData`.\\n *\\n * See {IERC777Sender} and {IERC777Recipient}.\\n *\\n * Emits {Minted} and {IERC20-Transfer} events.\\n *\\n * Requirements\\n *\\n * - `account` cannot be the zero address.\\n * - if `account` is a contract, it must implement the {IERC777Recipient}\\n * interface.\\n */\\n function _mint(\\n address account,\\n uint256 amount,\\n bytes memory userData,\\n bytes memory operatorData,\\n bool requireReceptionAck\\n ) internal virtual {\\n require(account != address(0), \\\"ERC777: mint to the zero address\\\");\\n\\n address operator = _msgSender();\\n\\n _beforeTokenTransfer(operator, address(0), account, amount);\\n\\n // Update state variables\\n _totalSupply += amount;\\n _balances[account] += amount;\\n\\n _callTokensReceived(operator, address(0), account, amount, userData, operatorData, requireReceptionAck);\\n\\n emit Minted(operator, account, amount, userData, operatorData);\\n emit Transfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Send tokens\\n * @param from address token holder address\\n * @param to address recipient address\\n * @param amount uint256 amount of tokens to transfer\\n * @param userData bytes extra information provided by the token holder (if any)\\n * @param operatorData bytes extra information provided by the operator (if any)\\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\\n */\\n function _send(\\n address from,\\n address to,\\n uint256 amount,\\n bytes memory userData,\\n bytes memory operatorData,\\n bool requireReceptionAck\\n ) internal virtual {\\n require(from != address(0), \\\"ERC777: transfer from the zero address\\\");\\n require(to != address(0), \\\"ERC777: transfer to the zero address\\\");\\n\\n address operator = _msgSender();\\n\\n _callTokensToSend(operator, from, to, amount, userData, operatorData);\\n\\n _move(operator, from, to, amount, userData, operatorData);\\n\\n _callTokensReceived(operator, from, to, amount, userData, operatorData, requireReceptionAck);\\n }\\n\\n /**\\n * @dev Burn tokens\\n * @param from address token holder address\\n * @param amount uint256 amount of tokens to burn\\n * @param data bytes extra information provided by the token holder\\n * @param operatorData bytes extra information provided by the operator (if any)\\n */\\n function _burn(address from, uint256 amount, bytes memory data, bytes memory operatorData) internal virtual {\\n require(from != address(0), \\\"ERC777: burn from the zero address\\\");\\n\\n address operator = _msgSender();\\n\\n _callTokensToSend(operator, from, address(0), amount, data, operatorData);\\n\\n _beforeTokenTransfer(operator, from, address(0), amount);\\n\\n // Update state variables\\n uint256 fromBalance = _balances[from];\\n require(fromBalance >= amount, \\\"ERC777: burn amount exceeds balance\\\");\\n unchecked {\\n _balances[from] = fromBalance - amount;\\n }\\n _totalSupply -= amount;\\n\\n emit Burned(operator, from, amount, data, operatorData);\\n emit Transfer(from, address(0), amount);\\n }\\n\\n function _move(\\n address operator,\\n address from,\\n address to,\\n uint256 amount,\\n bytes memory userData,\\n bytes memory operatorData\\n ) private {\\n _beforeTokenTransfer(operator, from, to, amount);\\n\\n uint256 fromBalance = _balances[from];\\n require(fromBalance >= amount, \\\"ERC777: transfer amount exceeds balance\\\");\\n unchecked {\\n _balances[from] = fromBalance - amount;\\n }\\n _balances[to] += amount;\\n\\n emit Sent(operator, from, to, amount, userData, operatorData);\\n emit Transfer(from, to, amount);\\n }\\n\\n /**\\n * @dev See {ERC20-_approve}.\\n *\\n * Note that accounts cannot have allowance issued by their operators.\\n */\\n function _approve(address holder, address spender, uint256 value) internal virtual {\\n require(holder != address(0), \\\"ERC777: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC777: approve to the zero address\\\");\\n\\n _allowances[holder][spender] = value;\\n emit Approval(holder, spender, value);\\n }\\n\\n /**\\n * @dev Call from.tokensToSend() if the interface is registered\\n * @param operator address operator requesting the transfer\\n * @param from address token holder address\\n * @param to address recipient address\\n * @param amount uint256 amount of tokens to transfer\\n * @param userData bytes extra information provided by the token holder (if any)\\n * @param operatorData bytes extra information provided by the operator (if any)\\n */\\n function _callTokensToSend(\\n address operator,\\n address from,\\n address to,\\n uint256 amount,\\n bytes memory userData,\\n bytes memory operatorData\\n ) private {\\n address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(from, _TOKENS_SENDER_INTERFACE_HASH);\\n if (implementer != address(0)) {\\n IERC777Sender(implementer).tokensToSend(operator, from, to, amount, userData, operatorData);\\n }\\n }\\n\\n /**\\n * @dev Call to.tokensReceived() if the interface is registered. Reverts if the recipient is a contract but\\n * tokensReceived() was not registered for the recipient\\n * @param operator address operator requesting the transfer\\n * @param from address token holder address\\n * @param to address recipient address\\n * @param amount uint256 amount of tokens to transfer\\n * @param userData bytes extra information provided by the token holder (if any)\\n * @param operatorData bytes extra information provided by the operator (if any)\\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\\n */\\n function _callTokensReceived(\\n address operator,\\n address from,\\n address to,\\n uint256 amount,\\n bytes memory userData,\\n bytes memory operatorData,\\n bool requireReceptionAck\\n ) private {\\n address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(to, _TOKENS_RECIPIENT_INTERFACE_HASH);\\n if (implementer != address(0)) {\\n IERC777Recipient(implementer).tokensReceived(operator, from, to, amount, userData, operatorData);\\n } else if (requireReceptionAck) {\\n require(!to.isContract(), \\\"ERC777: token recipient contract has no implementer for ERC777TokensRecipient\\\");\\n }\\n }\\n\\n /**\\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\\n *\\n * Does not update the allowance amount in case of infinite allowance.\\n * Revert if not enough allowance is available.\\n *\\n * Might emit an {IERC20-Approval} event.\\n */\\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\\n uint256 currentAllowance = allowance(owner, spender);\\n if (currentAllowance != type(uint256).max) {\\n require(currentAllowance >= amount, \\\"ERC777: insufficient allowance\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - amount);\\n }\\n }\\n }\\n\\n /**\\n * @dev Hook that is called before any token transfer. This includes\\n * calls to {send}, {transfer}, {operatorSend}, {transferFrom}, minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * will be to transferred to `to`.\\n * - when `from` is zero, `amount` tokens will be minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(address operator, address from, address to, uint256 amount) internal virtual {}\\n}\\n\"\n },\n \"@openzeppelin/contracts/token/ERC777/IERC777.sol\": {\n \"content\": \"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC777/IERC777.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC777Token standard as defined in the EIP.\\n *\\n * This contract uses the\\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 registry standard] to let\\n * token holders and recipients react to token movements by using setting implementers\\n * for the associated interfaces in said registry. See {IERC1820Registry} and\\n * {ERC1820Implementer}.\\n */\\ninterface IERC777 {\\n /**\\n * @dev Emitted when `amount` tokens are created by `operator` and assigned to `to`.\\n *\\n * Note that some additional user `data` and `operatorData` can be logged in the event.\\n */\\n event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);\\n\\n /**\\n * @dev Emitted when `operator` destroys `amount` tokens from `account`.\\n *\\n * Note that some additional user `data` and `operatorData` can be logged in the event.\\n */\\n event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);\\n\\n /**\\n * @dev Emitted when `operator` is made operator for `tokenHolder`.\\n */\\n event AuthorizedOperator(address indexed operator, address indexed tokenHolder);\\n\\n /**\\n * @dev Emitted when `operator` is revoked its operator status for `tokenHolder`.\\n */\\n event RevokedOperator(address indexed operator, address indexed tokenHolder);\\n\\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, usually a shorter version of the\\n * name.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the smallest part of the token that is not divisible. This\\n * means all token operations (creation, movement and destruction) must have\\n * amounts that are a multiple of this number.\\n *\\n * For most token contracts, this value will equal 1.\\n */\\n function granularity() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by an account (`owner`).\\n */\\n function balanceOf(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * If send or receive hooks are registered for the caller and `recipient`,\\n * the corresponding functions will be called with `data` and empty\\n * `operatorData`. See {IERC777Sender} and {IERC777Recipient}.\\n *\\n * Emits a {Sent} event.\\n *\\n * Requirements\\n *\\n * - the caller must have at least `amount` tokens.\\n * - `recipient` cannot be the zero address.\\n * - if `recipient` is a contract, it must implement the {IERC777Recipient}\\n * interface.\\n */\\n function send(address recipient, uint256 amount, bytes calldata data) external;\\n\\n /**\\n * @dev Destroys `amount` tokens from the caller's account, reducing the\\n * total supply.\\n *\\n * If a send hook is registered for the caller, the corresponding function\\n * will be called with `data` and empty `operatorData`. See {IERC777Sender}.\\n *\\n * Emits a {Burned} event.\\n *\\n * Requirements\\n *\\n * - the caller must have at least `amount` tokens.\\n */\\n function burn(uint256 amount, bytes calldata data) external;\\n\\n /**\\n * @dev Returns true if an account is an operator of `tokenHolder`.\\n * Operators can send and burn tokens on behalf of their owners. All\\n * accounts are their own operator.\\n *\\n * See {operatorSend} and {operatorBurn}.\\n */\\n function isOperatorFor(address operator, address tokenHolder) external view returns (bool);\\n\\n /**\\n * @dev Make an account an operator of the caller.\\n *\\n * See {isOperatorFor}.\\n *\\n * Emits an {AuthorizedOperator} event.\\n *\\n * Requirements\\n *\\n * - `operator` cannot be calling address.\\n */\\n function authorizeOperator(address operator) external;\\n\\n /**\\n * @dev Revoke an account's operator status for the caller.\\n *\\n * See {isOperatorFor} and {defaultOperators}.\\n *\\n * Emits a {RevokedOperator} event.\\n *\\n * Requirements\\n *\\n * - `operator` cannot be calling address.\\n */\\n function revokeOperator(address operator) external;\\n\\n /**\\n * @dev Returns the list of default operators. These accounts are operators\\n * for all token holders, even if {authorizeOperator} was never called on\\n * them.\\n *\\n * This list is immutable, but individual holders may revoke these via\\n * {revokeOperator}, in which case {isOperatorFor} will return false.\\n */\\n function defaultOperators() external view returns (address[] memory);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must\\n * be an operator of `sender`.\\n *\\n * If send or receive hooks are registered for `sender` and `recipient`,\\n * the corresponding functions will be called with `data` and\\n * `operatorData`. See {IERC777Sender} and {IERC777Recipient}.\\n *\\n * Emits a {Sent} event.\\n *\\n * Requirements\\n *\\n * - `sender` cannot be the zero address.\\n * - `sender` must have at least `amount` tokens.\\n * - the caller must be an operator for `sender`.\\n * - `recipient` cannot be the zero address.\\n * - if `recipient` is a contract, it must implement the {IERC777Recipient}\\n * interface.\\n */\\n function operatorSend(\\n address sender,\\n address recipient,\\n uint256 amount,\\n bytes calldata data,\\n bytes calldata operatorData\\n ) external;\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the total supply.\\n * The caller must be an operator of `account`.\\n *\\n * If a send hook is registered for `account`, the corresponding function\\n * will be called with `data` and `operatorData`. See {IERC777Sender}.\\n *\\n * Emits a {Burned} event.\\n *\\n * Requirements\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n * - the caller must be an operator for `account`.\\n */\\n function operatorBurn(address account, uint256 amount, bytes calldata data, bytes calldata operatorData) external;\\n\\n event Sent(\\n address indexed operator,\\n address indexed from,\\n address indexed to,\\n uint256 amount,\\n bytes data,\\n bytes operatorData\\n );\\n}\\n\"\n },\n \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\": {\n \"content\": \"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\\n *\\n * Accounts can be notified of {IERC777} tokens being sent to them by having a\\n * contract implement this interface (contract holders can be their own\\n * implementer) and registering it on the\\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\\n *\\n * See {IERC1820Registry} and {ERC1820Implementer}.\\n */\\ninterface IERC777Recipient {\\n /**\\n * @dev Called by an {IERC777} token contract whenever tokens are being\\n * moved or created into a registered account (`to`). The type of operation\\n * is conveyed by `from` being the zero address or not.\\n *\\n * This call occurs _after_ the token contract's state is updated, so\\n * {IERC777-balanceOf}, etc., can be used to query the post-operation state.\\n *\\n * This function may revert to prevent the operation from being executed.\\n */\\n function tokensReceived(\\n address operator,\\n address from,\\n address to,\\n uint256 amount,\\n bytes calldata userData,\\n bytes calldata operatorData\\n ) external;\\n}\\n\"\n },\n \"@openzeppelin/contracts/token/ERC777/IERC777Sender.sol\": {\n \"content\": \"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Sender.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC777TokensSender standard as defined in the EIP.\\n *\\n * {IERC777} Token holders can be notified of operations performed on their\\n * tokens by having a contract implement this interface (contract holders can be\\n * their own implementer) and registering it on the\\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\\n *\\n * See {IERC1820Registry} and {ERC1820Implementer}.\\n */\\ninterface IERC777Sender {\\n /**\\n * @dev Called by an {IERC777} token contract whenever a registered holder's\\n * (`from`) tokens are about to be moved or destroyed. The type of operation\\n * is conveyed by `to` being the zero address or not.\\n *\\n * This call occurs _before_ the token contract's state is updated, so\\n * {IERC777-balanceOf}, etc., can be used to query the pre-operation state.\\n *\\n * This function may revert to prevent the operation from being executed.\\n */\\n function tokensToSend(\\n address operator,\\n address from,\\n address to,\\n uint256 amount,\\n bytes calldata userData,\\n bytes calldata operatorData\\n ) external;\\n}\\n\"\n },\n \"@openzeppelin/contracts/utils/Address.sol\": {\n \"content\": \"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n *\\n * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\"\n },\n \"@openzeppelin/contracts/utils/Context.sol\": {\n \"content\": \"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n}\\n\"\n },\n \"@openzeppelin/contracts/utils/Counters.sol\": {\n \"content\": \"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title Counters\\n * @author Matt Condon (@shrugs)\\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\\n *\\n * Include with `using Counters for Counters.Counter;`\\n */\\nlibrary Counters {\\n struct Counter {\\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\\n // this feature: see https://github.com/ethereum/solidity/issues/4637\\n uint256 _value; // default: 0\\n }\\n\\n function current(Counter storage counter) internal view returns (uint256) {\\n return counter._value;\\n }\\n\\n function increment(Counter storage counter) internal {\\n unchecked {\\n counter._value += 1;\\n }\\n }\\n\\n function decrement(Counter storage counter) internal {\\n uint256 value = counter._value;\\n require(value > 0, \\\"Counter: decrement overflow\\\");\\n unchecked {\\n counter._value = value - 1;\\n }\\n }\\n\\n function reset(Counter storage counter) internal {\\n counter._value = 0;\\n }\\n}\\n\"\n },\n \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\": {\n \"content\": \"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Strings.sol\\\";\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSA {\\n enum RecoverError {\\n NoError,\\n InvalidSignature,\\n InvalidSignatureLength,\\n InvalidSignatureS,\\n InvalidSignatureV // Deprecated in v4.8\\n }\\n\\n function _throwError(RecoverError error) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert(\\\"ECDSA: invalid signature\\\");\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert(\\\"ECDSA: invalid signature length\\\");\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert(\\\"ECDSA: invalid signature 's' value\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature` or error string. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n *\\n * Documentation for signature generation:\\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n return tryRecover(hash, v, r, s);\\n } else {\\n return (address(0), RecoverError.InvalidSignatureLength);\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature`. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, signature);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\\n uint8 v = uint8((uint256(vs) >> 255) + 27);\\n return tryRecover(hash, v, r, s);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n *\\n * _Available since v4.2._\\n */\\n function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\\n //\\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\\n // these malleable signatures as well.\\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n return (address(0), RecoverError.InvalidSignatureS);\\n }\\n\\n // If the signature is valid (and not malleable), return the signer address\\n address signer = ecrecover(hash, v, r, s);\\n if (signer == address(0)) {\\n return (address(0), RecoverError.InvalidSignature);\\n }\\n\\n return (signer, RecoverError.NoError);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore(0x00, \\\"\\\\x19Ethereum Signed Message:\\\\n32\\\")\\n mstore(0x1c, hash)\\n message := keccak256(0x00, 0x3c)\\n }\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from `s`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n\\\", Strings.toString(s.length), s));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Typed Data, created from a\\n * `domainSeparator` and a `structHash`. This produces hash corresponding\\n * to the one signed with the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n * JSON-RPC method as part of EIP-712.\\n *\\n * See {recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n let ptr := mload(0x40)\\n mstore(ptr, \\\"\\\\x19\\\\x01\\\")\\n mstore(add(ptr, 0x02), domainSeparator)\\n mstore(add(ptr, 0x22), structHash)\\n data := keccak256(ptr, 0x42)\\n }\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Data with intended validator, created from a\\n * `validator` and `data` according to the version 0 of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x00\\\", validator, data));\\n }\\n}\\n\"\n },\n \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\": {\n \"content\": \"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/SignatureChecker.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./ECDSA.sol\\\";\\nimport \\\"../../interfaces/IERC1271.sol\\\";\\n\\n/**\\n * @dev Signature verification helper that can be used instead of `ECDSA.recover` to seamlessly support both ECDSA\\n * signatures from externally owned accounts (EOAs) as well as ERC1271 signatures from smart contract wallets like\\n * Argent and Gnosis Safe.\\n *\\n * _Available since v4.1._\\n */\\nlibrary SignatureChecker {\\n /**\\n * @dev Checks if a signature is valid for a given signer and data hash. If the signer is a smart contract, the\\n * signature is validated against that smart contract using ERC1271, otherwise it's validated using `ECDSA.recover`.\\n *\\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\\n */\\n function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature) internal view returns (bool) {\\n (address recovered, ECDSA.RecoverError error) = ECDSA.tryRecover(hash, signature);\\n return\\n (error == ECDSA.RecoverError.NoError && recovered == signer) ||\\n isValidERC1271SignatureNow(signer, hash, signature);\\n }\\n\\n /**\\n * @dev Checks if a signature is valid for a given signer and data hash. The signature is validated\\n * against the signer smart contract using ERC1271.\\n *\\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\\n */\\n function isValidERC1271SignatureNow(\\n address signer,\\n bytes32 hash,\\n bytes memory signature\\n ) internal view returns (bool) {\\n (bool success, bytes memory result) = signer.staticcall(\\n abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, signature)\\n );\\n return (success &&\\n result.length >= 32 &&\\n abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector));\\n }\\n}\\n\"\n },\n \"@openzeppelin/contracts/utils/introspection/ERC165.sol\": {\n \"content\": \"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC165.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC165} interface.\\n *\\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\\n * for the additional interface id that will be supported. For example:\\n *\\n * ```solidity\\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\\n * }\\n * ```\\n *\\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\\n */\\nabstract contract ERC165 is IERC165 {\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n return interfaceId == type(IERC165).interfaceId;\\n }\\n}\\n\"\n },\n \"@openzeppelin/contracts/utils/introspection/IERC165.sol\": {\n \"content\": \"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\"\n },\n \"@openzeppelin/contracts/utils/introspection/IERC1820Registry.sol\": {\n \"content\": \"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/introspection/IERC1820Registry.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the global ERC1820 Registry, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register\\n * implementers for interfaces in this registry, as well as query support.\\n *\\n * Implementers may be shared by multiple accounts, and can also implement more\\n * than a single interface for each account. Contracts can implement interfaces\\n * for themselves, but externally-owned accounts (EOA) must delegate this to a\\n * contract.\\n *\\n * {IERC165} interfaces can also be queried via the registry.\\n *\\n * For an in-depth explanation and source code analysis, see the EIP text.\\n */\\ninterface IERC1820Registry {\\n event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer);\\n\\n event ManagerChanged(address indexed account, address indexed newManager);\\n\\n /**\\n * @dev Sets `newManager` as the manager for `account`. A manager of an\\n * account is able to set interface implementers for it.\\n *\\n * By default, each account is its own manager. Passing a value of `0x0` in\\n * `newManager` will reset the manager to this initial state.\\n *\\n * Emits a {ManagerChanged} event.\\n *\\n * Requirements:\\n *\\n * - the caller must be the current manager for `account`.\\n */\\n function setManager(address account, address newManager) external;\\n\\n /**\\n * @dev Returns the manager for `account`.\\n *\\n * See {setManager}.\\n */\\n function getManager(address account) external view returns (address);\\n\\n /**\\n * @dev Sets the `implementer` contract as ``account``'s implementer for\\n * `interfaceHash`.\\n *\\n * `account` being the zero address is an alias for the caller's address.\\n * The zero address can also be used in `implementer` to remove an old one.\\n *\\n * See {interfaceHash} to learn how these are created.\\n *\\n * Emits an {InterfaceImplementerSet} event.\\n *\\n * Requirements:\\n *\\n * - the caller must be the current manager for `account`.\\n * - `interfaceHash` must not be an {IERC165} interface id (i.e. it must not\\n * end in 28 zeroes).\\n * - `implementer` must implement {IERC1820Implementer} and return true when\\n * queried for support, unless `implementer` is the caller. See\\n * {IERC1820Implementer-canImplementInterfaceForAddress}.\\n */\\n function setInterfaceImplementer(address account, bytes32 _interfaceHash, address implementer) external;\\n\\n /**\\n * @dev Returns the implementer of `interfaceHash` for `account`. If no such\\n * implementer is registered, returns the zero address.\\n *\\n * If `interfaceHash` is an {IERC165} interface id (i.e. it ends with 28\\n * zeroes), `account` will be queried for support of it.\\n *\\n * `account` being the zero address is an alias for the caller's address.\\n */\\n function getInterfaceImplementer(address account, bytes32 _interfaceHash) external view returns (address);\\n\\n /**\\n * @dev Returns the interface hash for an `interfaceName`, as defined in the\\n * corresponding\\n * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP].\\n */\\n function interfaceHash(string calldata interfaceName) external pure returns (bytes32);\\n\\n /**\\n * @notice Updates the cache with whether the contract implements an ERC165 interface or not.\\n * @param account Address of the contract for which to update the cache.\\n * @param interfaceId ERC165 interface for which to update the cache.\\n */\\n function updateERC165Cache(address account, bytes4 interfaceId) external;\\n\\n /**\\n * @notice Checks whether a contract implements an ERC165 interface or not.\\n * If the result is not cached a direct lookup on the contract address is performed.\\n * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling\\n * {updateERC165Cache} with the contract address.\\n * @param account Address of the contract to check.\\n * @param interfaceId ERC165 interface to check.\\n * @return True if `account` implements `interfaceId`, false otherwise.\\n */\\n function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool);\\n\\n /**\\n * @notice Checks whether a contract implements an ERC165 interface or not without using or updating the cache.\\n * @param account Address of the contract to check.\\n * @param interfaceId ERC165 interface to check.\\n * @return True if `account` implements `interfaceId`, false otherwise.\\n */\\n function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool);\\n}\\n\"\n },\n \"@openzeppelin/contracts/utils/math/Math.sol\": {\n \"content\": \"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n enum Rounding {\\n Down, // Toward negative infinity\\n Up, // Toward infinity\\n Zero // Toward zero\\n }\\n\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow.\\n return (a & b) + (a ^ b) / 2;\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a == 0 ? 0 : (a - 1) / b + 1;\\n }\\n\\n /**\\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\\n * with further edits by Uniswap Labs also under MIT license.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\\n unchecked {\\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2^256 + prod0.\\n uint256 prod0; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division.\\n if (prod1 == 0) {\\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\\n // The surrounding unchecked block does not change this fact.\\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\\n return prod0 / denominator;\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n require(denominator > prod1, \\\"Math: mulDiv overflow\\\");\\n\\n ///////////////////////////////////////////////\\n // 512 by 256 division.\\n ///////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0].\\n uint256 remainder;\\n assembly {\\n // Compute remainder using mulmod.\\n remainder := mulmod(x, y, denominator)\\n\\n // Subtract 256 bit number from 512 bit number.\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\\n // See https://cs.stackexchange.com/q/138556/92363.\\n\\n // Does not overflow because the denominator cannot be zero at this stage in the function.\\n uint256 twos = denominator & (~denominator + 1);\\n assembly {\\n // Divide denominator by twos.\\n denominator := div(denominator, twos)\\n\\n // Divide [prod1 prod0] by twos.\\n prod0 := div(prod0, twos)\\n\\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\\n twos := add(div(sub(0, twos), twos), 1)\\n }\\n\\n // Shift in bits from prod1 into prod0.\\n prod0 |= prod1 * twos;\\n\\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\\n // four bits. That is, denominator * inv = 1 mod 2^4.\\n uint256 inverse = (3 * denominator) ^ 2;\\n\\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\\n // in modular arithmetic, doubling the correct bits in each step.\\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\\n\\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inverse;\\n return result;\\n }\\n }\\n\\n /**\\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\\n uint256 result = mulDiv(x, y, denominator);\\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\\n result += 1;\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\\n *\\n * Inspired by Henry S. Warren, Jr.'s \\\"Hacker's Delight\\\" (Chapter 11).\\n */\\n function sqrt(uint256 a) internal pure returns (uint256) {\\n if (a == 0) {\\n return 0;\\n }\\n\\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\\n //\\n // We know that the \\\"msb\\\" (most significant bit) of our target number `a` is a power of 2 such that we have\\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\\n //\\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\\n // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\\n // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\\n //\\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\\n uint256 result = 1 << (log2(a) >> 1);\\n\\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\\n // into the expected uint128 result.\\n unchecked {\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n return min(result, a / result);\\n }\\n }\\n\\n /**\\n * @notice Calculates sqrt(a), following the selected rounding direction.\\n */\\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = sqrt(a);\\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 2, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 128;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 64;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 32;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 16;\\n }\\n if (value >> 8 > 0) {\\n value >>= 8;\\n result += 8;\\n }\\n if (value >> 4 > 0) {\\n value >>= 4;\\n result += 4;\\n }\\n if (value >> 2 > 0) {\\n value >>= 2;\\n result += 2;\\n }\\n if (value >> 1 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log2(value);\\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 10, rounded down, of a positive value.\\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 + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 256, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n *\\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\\n */\\n function log256(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 16;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 8;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 4;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 2;\\n }\\n if (value >> 8 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log256(value);\\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\\n }\\n }\\n}\\n\"\n },\n \"@openzeppelin/contracts/utils/math/SafeCast.sol\": {\n \"content\": \"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\\n * checks.\\n *\\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\\n * easily result in undesired exploitation or bugs, since developers usually\\n * assume that overflows raise errors. `SafeCast` restores this intuition by\\n * reverting the transaction when such an operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n *\\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\\n * all math on `uint256` and `int256` and then downcasting.\\n */\\nlibrary SafeCast {\\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 * _Available since v4.7._\\n */\\n function toUint248(uint256 value) internal pure returns (uint248) {\\n require(value <= type(uint248).max, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint240(uint256 value) internal pure returns (uint240) {\\n require(value <= type(uint240).max, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint232(uint256 value) internal pure returns (uint232) {\\n require(value <= type(uint232).max, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint224(uint256 value) internal pure returns (uint224) {\\n require(value <= type(uint224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint216(uint256 value) internal pure returns (uint216) {\\n require(value <= type(uint216).max, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint208(uint256 value) internal pure returns (uint208) {\\n require(value <= type(uint208).max, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint200(uint256 value) internal pure returns (uint200) {\\n require(value <= type(uint200).max, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint192(uint256 value) internal pure returns (uint192) {\\n require(value <= type(uint192).max, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint184(uint256 value) internal pure returns (uint184) {\\n require(value <= type(uint184).max, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint176(uint256 value) internal pure returns (uint176) {\\n require(value <= type(uint176).max, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint168(uint256 value) internal pure returns (uint168) {\\n require(value <= type(uint168).max, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint160(uint256 value) internal pure returns (uint160) {\\n require(value <= type(uint160).max, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint152(uint256 value) internal pure returns (uint152) {\\n require(value <= type(uint152).max, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint144(uint256 value) internal pure returns (uint144) {\\n require(value <= type(uint144).max, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint136(uint256 value) internal pure returns (uint136) {\\n require(value <= type(uint136).max, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint128(uint256 value) internal pure returns (uint128) {\\n require(value <= type(uint128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint120(uint256 value) internal pure returns (uint120) {\\n require(value <= type(uint120).max, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint112(uint256 value) internal pure returns (uint112) {\\n require(value <= type(uint112).max, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint104(uint256 value) internal pure returns (uint104) {\\n require(value <= type(uint104).max, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint96(uint256 value) internal pure returns (uint96) {\\n require(value <= type(uint96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint88(uint256 value) internal pure returns (uint88) {\\n require(value <= type(uint88).max, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint80(uint256 value) internal pure returns (uint80) {\\n require(value <= type(uint80).max, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint72(uint256 value) internal pure returns (uint72) {\\n require(value <= type(uint72).max, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint64(uint256 value) internal pure returns (uint64) {\\n require(value <= type(uint64).max, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint56(uint256 value) internal pure returns (uint56) {\\n require(value <= type(uint56).max, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint48(uint256 value) internal pure returns (uint48) {\\n require(value <= type(uint48).max, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint40(uint256 value) internal pure returns (uint40) {\\n require(value <= type(uint40).max, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint32(uint256 value) internal pure returns (uint32) {\\n require(value <= type(uint32).max, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint24(uint256 value) internal pure returns (uint24) {\\n require(value <= type(uint24).max, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint16(uint256 value) internal pure returns (uint16) {\\n require(value <= type(uint16).max, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint8(uint256 value) internal pure returns (uint8) {\\n require(value <= type(uint8).max, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\n */\\n function toUint256(int256 value) internal pure returns (uint256) {\\n require(value >= 0, \\\"SafeCast: value must be positive\\\");\\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 * _Available since v4.7._\\n */\\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\\n downcasted = int248(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\\n downcasted = int240(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\\n downcasted = int232(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\\n downcasted = int224(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\\n downcasted = int216(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\\n downcasted = int208(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\\n downcasted = int200(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\\n downcasted = int192(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\\n downcasted = int184(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\\n downcasted = int176(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\\n downcasted = int168(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\\n downcasted = int160(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\\n downcasted = int152(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\\n downcasted = int144(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\\n downcasted = int136(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\\n downcasted = int128(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\\n downcasted = int120(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\\n downcasted = int112(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\\n downcasted = int104(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\\n downcasted = int96(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\\n downcasted = int88(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\\n downcasted = int80(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\\n downcasted = int72(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\\n downcasted = int64(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\\n downcasted = int56(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\\n downcasted = int48(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\\n downcasted = int40(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\\n downcasted = int32(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\\n downcasted = int24(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\\n downcasted = int16(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\\n downcasted = int8(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\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 require(value <= uint256(type(int256).max), \\\"SafeCast: value doesn't fit in an int256\\\");\\n return int256(value);\\n }\\n}\\n\"\n },\n \"@openzeppelin/contracts/utils/math/SignedMath.sol\": {\n \"content\": \"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard signed math utilities missing in the Solidity language.\\n */\\nlibrary SignedMath {\\n /**\\n * @dev Returns the largest of two signed numbers.\\n */\\n function max(int256 a, int256 b) internal pure returns (int256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two signed numbers.\\n */\\n function min(int256 a, int256 b) internal pure returns (int256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two signed numbers without overflow.\\n * The result is rounded towards zero.\\n */\\n function average(int256 a, int256 b) internal pure returns (int256) {\\n // Formula from the book \\\"Hacker's Delight\\\"\\n int256 x = (a & b) + ((a ^ b) >> 1);\\n return x + (int256(uint256(x) >> 255) & (a ^ b));\\n }\\n\\n /**\\n * @dev Returns the absolute unsigned value of a signed value.\\n */\\n function abs(int256 n) internal pure returns (uint256) {\\n unchecked {\\n // must be unchecked in order to support `n = type(int256).min`\\n return uint256(n >= 0 ? n : -n);\\n }\\n }\\n}\\n\"\n },\n \"@openzeppelin/contracts/utils/Strings.sol\": {\n \"content\": \"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./math/Math.sol\\\";\\nimport \\\"./math/SignedMath.sol\\\";\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n uint256 length = Math.log10(value) + 1;\\n string memory buffer = new string(length);\\n uint256 ptr;\\n /// @solidity memory-safe-assembly\\n assembly {\\n ptr := add(buffer, add(32, length))\\n }\\n while (true) {\\n ptr--;\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\\n }\\n value /= 10;\\n if (value == 0) break;\\n }\\n return buffer;\\n }\\n }\\n\\n /**\\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\\n */\\n function toString(int256 value) internal pure returns (string memory) {\\n return string(abi.encodePacked(value < 0 ? \\\"-\\\" : \\\"\\\", toString(SignedMath.abs(value))));\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n return toHexString(value, Math.log256(value) + 1);\\n }\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n\\n /**\\n * @dev Returns true if the two strings are equal.\\n */\\n function equal(string memory a, string memory b) internal pure returns (bool) {\\n return keccak256(bytes(a)) == keccak256(bytes(b));\\n }\\n}\\n\"\n },\n \"contracts/aa-4337/core/BaseAccount.sol\": {\n \"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-empty-blocks */\\n\\nimport \\\"../interfaces/IAccount.sol\\\";\\nimport \\\"../interfaces/IEntryPoint.sol\\\";\\nimport \\\"./Helpers.sol\\\";\\n\\n/**\\n * Basic account implementation.\\n * this contract provides the basic logic for implementing the IAccount interface - validateUserOp\\n * specific account implementation should inherit it and provide the account-specific logic\\n */\\nabstract contract BaseAccount is IAccount {\\n using UserOperationLib for UserOperation;\\n\\n //return value in case of signature failure, with no time-range.\\n // equivalent to _packValidationData(true,0,0);\\n uint256 internal constant SIG_VALIDATION_FAILED = 1;\\n\\n /**\\n * Return the account nonce.\\n * This method returns the next sequential nonce.\\n * For a nonce of a specific key, use `entrypoint.getNonce(account, key)`\\n */\\n function getNonce() public view virtual returns (uint256) {\\n return entryPoint().getNonce(address(this), 0);\\n }\\n\\n /**\\n * return the entryPoint used by this account.\\n * subclass should return the current entryPoint used by this account.\\n */\\n function entryPoint() public view virtual returns (IEntryPoint);\\n\\n /**\\n * Validate user's signature and nonce.\\n * subclass doesn't need to override this method. Instead, it should override the specific internal validation methods.\\n */\\n function validateUserOp(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n uint256 missingAccountFunds\\n ) external virtual override returns (uint256 validationData) {\\n _requireFromEntryPoint();\\n validationData = _validateSignature(userOp, userOpHash);\\n _validateNonce(userOp.nonce);\\n _payPrefund(missingAccountFunds);\\n }\\n\\n /**\\n * ensure the request comes from the known entrypoint.\\n */\\n function _requireFromEntryPoint() internal view virtual {\\n require(\\n msg.sender == address(entryPoint()),\\n \\\"account: not from EntryPoint\\\"\\n );\\n }\\n\\n /**\\n * validate the signature is valid for this message.\\n * @param userOp validate the userOp.signature field\\n * @param userOpHash convenient field: the hash of the request, to check the signature against\\n * (also hashes the entrypoint and chain id)\\n * @return validationData signature and time-range of this operation\\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\\n * otherwise, an address of an \\\"authorizer\\\" contract.\\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \\\"indefinite\\\"\\n * <6-byte> validAfter - first timestamp this operation is valid\\n * If the account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\\n */\\n function _validateSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) internal virtual returns (uint256 validationData);\\n\\n /**\\n * Validate the nonce of the UserOperation.\\n * This method may validate the nonce requirement of this account.\\n * e.g.\\n * To limit the nonce to use sequenced UserOps only (no \\\"out of order\\\" UserOps):\\n * `require(nonce < type(uint64).max)`\\n * For a hypothetical account that *requires* the nonce to be out-of-order:\\n * `require(nonce & type(uint64).max == 0)`\\n *\\n * The actual nonce uniqueness is managed by the EntryPoint, and thus no other\\n * action is needed by the account itself.\\n *\\n * @param nonce to validate\\n *\\n * solhint-disable-next-line no-empty-blocks\\n */\\n function _validateNonce(uint256 nonce) internal view virtual {}\\n\\n /**\\n * sends to the entrypoint (msg.sender) the missing funds for this transaction.\\n * subclass MAY override this method for better funds management\\n * (e.g. send to the entryPoint more than the minimum required, so that in future transactions\\n * it will not be required to send again)\\n * @param missingAccountFunds the minimum value this method should send the entrypoint.\\n * this value MAY be zero, in case there is enough deposit, or the userOp has a paymaster.\\n */\\n function _payPrefund(uint256 missingAccountFunds) internal virtual {\\n if (missingAccountFunds != 0) {\\n (bool success, ) = payable(msg.sender).call{\\n value: missingAccountFunds,\\n gas: type(uint256).max\\n }(\\\"\\\");\\n (success);\\n //ignore failure (its EntryPoint's job to verify, not account.)\\n }\\n }\\n}\\n\"\n },\n \"contracts/aa-4337/core/EntryPoint.sol\": {\n \"content\": \"/**\\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\\n ** Only one instance required on each chain.\\n **/\\n// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-inline-assembly */\\n\\nimport \\\"../interfaces/IAccount.sol\\\";\\nimport \\\"../interfaces/IPaymaster.sol\\\";\\nimport \\\"../interfaces/IEntryPoint.sol\\\";\\n\\nimport \\\"../utils/Exec.sol\\\";\\nimport \\\"./StakeManager.sol\\\";\\nimport \\\"./SenderCreator.sol\\\";\\nimport \\\"./Helpers.sol\\\";\\nimport \\\"./NonceManager.sol\\\";\\nimport \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\n\\ncontract EntryPoint is\\n IEntryPoint,\\n StakeManager,\\n NonceManager,\\n ReentrancyGuard\\n{\\n using UserOperationLib for UserOperation;\\n\\n SenderCreator private immutable senderCreator = new SenderCreator();\\n\\n // internal value used during simulation: need to query aggregator.\\n address private constant SIMULATE_FIND_AGGREGATOR = address(1);\\n\\n // marker for inner call revert on out of gas\\n bytes32 private constant INNER_OUT_OF_GAS = hex\\\"deaddead\\\";\\n\\n uint256 private constant REVERT_REASON_MAX_LEN = 2048;\\n\\n /**\\n * for simulation purposes, validateUserOp (and validatePaymasterUserOp) must return this value\\n * in case of signature failure, instead of revert.\\n */\\n uint256 public constant SIG_VALIDATION_FAILED = 1;\\n\\n /**\\n * compensate the caller's beneficiary address with the collected fees of all UserOperations.\\n * @param beneficiary the address to receive the fees\\n * @param amount amount to transfer.\\n */\\n function _compensate(address payable beneficiary, uint256 amount) internal {\\n require(beneficiary != address(0), \\\"AA90 invalid beneficiary\\\");\\n (bool success, ) = beneficiary.call{value: amount}(\\\"\\\");\\n require(success, \\\"AA91 failed send to beneficiary\\\");\\n }\\n\\n /**\\n * execute a user op\\n * @param opIndex index into the opInfo array\\n * @param userOp the userOp to execute\\n * @param opInfo the opInfo filled by validatePrepayment for this userOp.\\n * @return collected the total amount this userOp paid.\\n */\\n function _executeUserOp(\\n uint256 opIndex,\\n UserOperation calldata userOp,\\n UserOpInfo memory opInfo\\n ) private returns (uint256 collected) {\\n uint256 preGas = gasleft();\\n bytes memory context = getMemoryBytesFromOffset(opInfo.contextOffset);\\n\\n try this.innerHandleOp(userOp.callData, opInfo, context) returns (\\n uint256 _actualGasCost\\n ) {\\n collected = _actualGasCost;\\n } catch {\\n bytes32 innerRevertCode;\\n assembly {\\n returndatacopy(0, 0, 32)\\n innerRevertCode := mload(0)\\n }\\n // handleOps was called with gas limit too low. abort entire bundle.\\n if (innerRevertCode == INNER_OUT_OF_GAS) {\\n //report paymaster, since if it is not deliberately caused by the bundler,\\n // it must be a revert caused by paymaster.\\n revert FailedOp(opIndex, \\\"AA95 out of gas\\\");\\n }\\n\\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\\n collected = _handlePostOp(\\n opIndex,\\n IPaymaster.PostOpMode.postOpReverted,\\n opInfo,\\n context,\\n actualGas\\n );\\n }\\n }\\n\\n /**\\n * Execute a batch of UserOperations.\\n * no signature aggregator is used.\\n * if any account requires an aggregator (that is, it returned an aggregator when\\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\\n * @param ops the operations to execute\\n * @param beneficiary the address to receive the fees\\n */\\n function handleOps(\\n UserOperation[] calldata ops,\\n address payable beneficiary\\n ) public nonReentrant {\\n uint256 opslen = ops.length;\\n UserOpInfo[] memory opInfos = new UserOpInfo[](opslen);\\n\\n unchecked {\\n for (uint256 i = 0; i < opslen; i++) {\\n UserOpInfo memory opInfo = opInfos[i];\\n (\\n uint256 validationData,\\n uint256 pmValidationData\\n ) = _validatePrepayment(i, ops[i], opInfo);\\n _validateAccountAndPaymasterValidationData(\\n i,\\n validationData,\\n pmValidationData,\\n address(0)\\n );\\n }\\n\\n uint256 collected = 0;\\n emit BeforeExecution();\\n\\n for (uint256 i = 0; i < opslen; i++) {\\n collected += _executeUserOp(i, ops[i], opInfos[i]);\\n }\\n\\n _compensate(beneficiary, collected);\\n } //unchecked\\n }\\n\\n /**\\n * Execute a batch of UserOperation with Aggregators\\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\\n * @param beneficiary the address to receive the fees\\n */\\n function handleAggregatedOps(\\n UserOpsPerAggregator[] calldata opsPerAggregator,\\n address payable beneficiary\\n ) public nonReentrant {\\n uint256 opasLen = opsPerAggregator.length;\\n uint256 totalOps = 0;\\n for (uint256 i = 0; i < opasLen; i++) {\\n UserOpsPerAggregator calldata opa = opsPerAggregator[i];\\n UserOperation[] calldata ops = opa.userOps;\\n IAggregator aggregator = opa.aggregator;\\n\\n //address(1) is special marker of \\\"signature error\\\"\\n require(\\n address(aggregator) != address(1),\\n \\\"AA96 invalid aggregator\\\"\\n );\\n\\n if (address(aggregator) != address(0)) {\\n // solhint-disable-next-line no-empty-blocks\\n try aggregator.validateSignatures(ops, opa.signature) {} catch {\\n revert SignatureValidationFailed(address(aggregator));\\n }\\n }\\n\\n totalOps += ops.length;\\n }\\n\\n UserOpInfo[] memory opInfos = new UserOpInfo[](totalOps);\\n\\n emit BeforeExecution();\\n\\n uint256 opIndex = 0;\\n for (uint256 a = 0; a < opasLen; a++) {\\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\\n UserOperation[] calldata ops = opa.userOps;\\n IAggregator aggregator = opa.aggregator;\\n\\n uint256 opslen = ops.length;\\n for (uint256 i = 0; i < opslen; i++) {\\n UserOpInfo memory opInfo = opInfos[opIndex];\\n (\\n uint256 validationData,\\n uint256 paymasterValidationData\\n ) = _validatePrepayment(opIndex, ops[i], opInfo);\\n _validateAccountAndPaymasterValidationData(\\n i,\\n validationData,\\n paymasterValidationData,\\n address(aggregator)\\n );\\n opIndex++;\\n }\\n }\\n\\n uint256 collected = 0;\\n opIndex = 0;\\n for (uint256 a = 0; a < opasLen; a++) {\\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\\n emit SignatureAggregatorChanged(address(opa.aggregator));\\n UserOperation[] calldata ops = opa.userOps;\\n uint256 opslen = ops.length;\\n\\n for (uint256 i = 0; i < opslen; i++) {\\n collected += _executeUserOp(opIndex, ops[i], opInfos[opIndex]);\\n opIndex++;\\n }\\n }\\n emit SignatureAggregatorChanged(address(0));\\n\\n _compensate(beneficiary, collected);\\n }\\n\\n /// @inheritdoc IEntryPoint\\n function simulateHandleOp(\\n UserOperation calldata op,\\n address target,\\n bytes calldata targetCallData\\n ) external override {\\n UserOpInfo memory opInfo;\\n _simulationOnlyValidations(op);\\n (\\n uint256 validationData,\\n uint256 paymasterValidationData\\n ) = _validatePrepayment(0, op, opInfo);\\n ValidationData memory data = _intersectTimeRange(\\n validationData,\\n paymasterValidationData\\n );\\n\\n numberMarker();\\n uint256 paid = _executeUserOp(0, op, opInfo);\\n numberMarker();\\n bool targetSuccess;\\n bytes memory targetResult;\\n if (target != address(0)) {\\n (targetSuccess, targetResult) = target.call(targetCallData);\\n }\\n revert ExecutionResult(\\n opInfo.preOpGas,\\n paid,\\n data.validAfter,\\n data.validUntil,\\n targetSuccess,\\n targetResult\\n );\\n }\\n\\n // A memory copy of UserOp static fields only.\\n // Excluding: callData, initCode and signature. Replacing paymasterAndData with paymaster.\\n struct MemoryUserOp {\\n address sender;\\n uint256 nonce;\\n uint256 callGasLimit;\\n uint256 verificationGasLimit;\\n uint256 preVerificationGas;\\n address paymaster;\\n uint256 maxFeePerGas;\\n uint256 maxPriorityFeePerGas;\\n }\\n\\n struct UserOpInfo {\\n MemoryUserOp mUserOp;\\n bytes32 userOpHash;\\n uint256 prefund;\\n uint256 contextOffset;\\n uint256 preOpGas;\\n }\\n\\n /**\\n * inner function to handle a UserOperation.\\n * Must be declared \\\"external\\\" to open a call context, but it can only be called by handleOps.\\n */\\n function innerHandleOp(\\n bytes memory callData,\\n UserOpInfo memory opInfo,\\n bytes calldata context\\n ) external returns (uint256 actualGasCost) {\\n uint256 preGas = gasleft();\\n require(msg.sender == address(this), \\\"AA92 internal call only\\\");\\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\\n\\n uint callGasLimit = mUserOp.callGasLimit;\\n unchecked {\\n // handleOps was called with gas limit too low. abort entire bundle.\\n if (\\n gasleft() < callGasLimit + mUserOp.verificationGasLimit + 5000\\n ) {\\n assembly {\\n mstore(0, INNER_OUT_OF_GAS)\\n revert(0, 32)\\n }\\n }\\n }\\n\\n IPaymaster.PostOpMode mode = IPaymaster.PostOpMode.opSucceeded;\\n if (callData.length > 0) {\\n bool success = Exec.call(mUserOp.sender, 0, callData, callGasLimit);\\n if (!success) {\\n bytes memory result = Exec.getReturnData(REVERT_REASON_MAX_LEN);\\n if (result.length > 0) {\\n emit UserOperationRevertReason(\\n opInfo.userOpHash,\\n mUserOp.sender,\\n mUserOp.nonce,\\n result\\n );\\n }\\n mode = IPaymaster.PostOpMode.opReverted;\\n }\\n }\\n\\n unchecked {\\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\\n //note: opIndex is ignored (relevant only if mode==postOpReverted, which is only possible outside of innerHandleOp)\\n return _handlePostOp(0, mode, opInfo, context, actualGas);\\n }\\n }\\n\\n /**\\n * generate a request Id - unique identifier for this request.\\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\\n */\\n function getUserOpHash(\\n UserOperation calldata userOp\\n ) public view returns (bytes32) {\\n return\\n keccak256(abi.encode(userOp.hash(), address(this), block.chainid));\\n }\\n\\n /**\\n * copy general fields from userOp into the memory opInfo structure.\\n */\\n function _copyUserOpToMemory(\\n UserOperation calldata userOp,\\n MemoryUserOp memory mUserOp\\n ) internal pure {\\n mUserOp.sender = userOp.sender;\\n mUserOp.nonce = userOp.nonce;\\n mUserOp.callGasLimit = userOp.callGasLimit;\\n mUserOp.verificationGasLimit = userOp.verificationGasLimit;\\n mUserOp.preVerificationGas = userOp.preVerificationGas;\\n mUserOp.maxFeePerGas = userOp.maxFeePerGas;\\n mUserOp.maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n bytes calldata paymasterAndData = userOp.paymasterAndData;\\n if (paymasterAndData.length > 0) {\\n require(\\n paymasterAndData.length >= 20,\\n \\\"AA93 invalid paymasterAndData\\\"\\n );\\n mUserOp.paymaster = address(bytes20(paymasterAndData[:20]));\\n } else {\\n mUserOp.paymaster = address(0);\\n }\\n }\\n\\n /**\\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\\n * @param userOp the user operation to validate.\\n */\\n function simulateValidation(UserOperation calldata userOp) external {\\n UserOpInfo memory outOpInfo;\\n\\n _simulationOnlyValidations(userOp);\\n (\\n uint256 validationData,\\n uint256 paymasterValidationData\\n ) = _validatePrepayment(0, userOp, outOpInfo);\\n StakeInfo memory paymasterInfo = _getStakeInfo(\\n outOpInfo.mUserOp.paymaster\\n );\\n StakeInfo memory senderInfo = _getStakeInfo(outOpInfo.mUserOp.sender);\\n StakeInfo memory factoryInfo;\\n {\\n bytes calldata initCode = userOp.initCode;\\n address factory = initCode.length >= 20\\n ? address(bytes20(initCode[0:20]))\\n : address(0);\\n factoryInfo = _getStakeInfo(factory);\\n }\\n\\n ValidationData memory data = _intersectTimeRange(\\n validationData,\\n paymasterValidationData\\n );\\n address aggregator = data.aggregator;\\n bool sigFailed = aggregator == address(1);\\n ReturnInfo memory returnInfo = ReturnInfo(\\n outOpInfo.preOpGas,\\n outOpInfo.prefund,\\n sigFailed,\\n data.validAfter,\\n data.validUntil,\\n getMemoryBytesFromOffset(outOpInfo.contextOffset)\\n );\\n\\n if (aggregator != address(0) && aggregator != address(1)) {\\n AggregatorStakeInfo memory aggregatorInfo = AggregatorStakeInfo(\\n aggregator,\\n _getStakeInfo(aggregator)\\n );\\n revert ValidationResultWithAggregation(\\n returnInfo,\\n senderInfo,\\n factoryInfo,\\n paymasterInfo,\\n aggregatorInfo\\n );\\n }\\n revert ValidationResult(\\n returnInfo,\\n senderInfo,\\n factoryInfo,\\n paymasterInfo\\n );\\n }\\n\\n function _getRequiredPrefund(\\n MemoryUserOp memory mUserOp\\n ) internal pure returns (uint256 requiredPrefund) {\\n unchecked {\\n //when using a Paymaster, the verificationGasLimit is used also to as a limit for the postOp call.\\n // our security model might call postOp eventually twice\\n uint256 mul = mUserOp.paymaster != address(0) ? 3 : 1;\\n uint256 requiredGas = mUserOp.callGasLimit +\\n mUserOp.verificationGasLimit *\\n mul +\\n mUserOp.preVerificationGas;\\n\\n requiredPrefund = requiredGas * mUserOp.maxFeePerGas;\\n }\\n }\\n\\n // create the sender's contract if needed.\\n function _createSenderIfNeeded(\\n uint256 opIndex,\\n UserOpInfo memory opInfo,\\n bytes calldata initCode\\n ) internal {\\n if (initCode.length != 0) {\\n address sender = opInfo.mUserOp.sender;\\n if (sender.code.length != 0)\\n revert FailedOp(opIndex, \\\"AA10 sender already constructed\\\");\\n address sender1 = senderCreator.createSender{\\n gas: opInfo.mUserOp.verificationGasLimit\\n }(initCode);\\n if (sender1 == address(0))\\n revert FailedOp(opIndex, \\\"AA13 initCode failed or OOG\\\");\\n if (sender1 != sender)\\n revert FailedOp(opIndex, \\\"AA14 initCode must return sender\\\");\\n if (sender1.code.length == 0)\\n revert FailedOp(opIndex, \\\"AA15 initCode must create sender\\\");\\n address factory = address(bytes20(initCode[0:20]));\\n emit AccountDeployed(\\n opInfo.userOpHash,\\n sender,\\n factory,\\n opInfo.mUserOp.paymaster\\n );\\n }\\n }\\n\\n /**\\n * Get counterfactual sender address.\\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\\n * this method always revert, and returns the address in SenderAddressResult error\\n * @param initCode the constructor code to be passed into the UserOperation.\\n */\\n function getSenderAddress(bytes calldata initCode) public {\\n address sender = senderCreator.createSender(initCode);\\n revert SenderAddressResult(sender);\\n }\\n\\n function _simulationOnlyValidations(\\n UserOperation calldata userOp\\n ) internal view {\\n // solhint-disable-next-line no-empty-blocks\\n try\\n this._validateSenderAndPaymaster(\\n userOp.initCode,\\n userOp.sender,\\n userOp.paymasterAndData\\n )\\n {} catch Error(string memory revertReason) {\\n if (bytes(revertReason).length != 0) {\\n revert FailedOp(0, revertReason);\\n }\\n }\\n }\\n\\n /**\\n * Called only during simulation.\\n * This function always reverts to prevent warm/cold storage differentiation in simulation vs execution.\\n */\\n function _validateSenderAndPaymaster(\\n bytes calldata initCode,\\n address sender,\\n bytes calldata paymasterAndData\\n ) external view {\\n if (initCode.length == 0 && sender.code.length == 0) {\\n // it would revert anyway. but give a meaningful message\\n revert(\\\"AA20 account not deployed\\\");\\n }\\n if (paymasterAndData.length >= 20) {\\n address paymaster = address(bytes20(paymasterAndData[0:20]));\\n if (paymaster.code.length == 0) {\\n // it would revert anyway. but give a meaningful message\\n revert(\\\"AA30 paymaster not deployed\\\");\\n }\\n }\\n // always revert\\n revert(\\\"\\\");\\n }\\n\\n /**\\n * call account.validateUserOp.\\n * revert (with FailedOp) in case validateUserOp reverts, or account didn't send required prefund.\\n * decrement account's deposit if needed\\n */\\n function _validateAccountPrepayment(\\n uint256 opIndex,\\n UserOperation calldata op,\\n UserOpInfo memory opInfo,\\n uint256 requiredPrefund\\n )\\n internal\\n returns (\\n uint256 gasUsedByValidateAccountPrepayment,\\n uint256 validationData\\n )\\n {\\n unchecked {\\n uint256 preGas = gasleft();\\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\\n address sender = mUserOp.sender;\\n _createSenderIfNeeded(opIndex, opInfo, op.initCode);\\n address paymaster = mUserOp.paymaster;\\n numberMarker();\\n uint256 missingAccountFunds = 0;\\n if (paymaster == address(0)) {\\n uint256 bal = balanceOf(sender);\\n missingAccountFunds = bal > requiredPrefund\\n ? 0\\n : requiredPrefund - bal;\\n }\\n try\\n IAccount(sender).validateUserOp{\\n gas: mUserOp.verificationGasLimit\\n }(op, opInfo.userOpHash, missingAccountFunds)\\n returns (uint256 _validationData) {\\n validationData = _validationData;\\n } catch Error(string memory revertReason) {\\n revert FailedOp(\\n opIndex,\\n string.concat(\\\"AA23 reverted: \\\", revertReason)\\n );\\n } catch {\\n revert FailedOp(opIndex, \\\"AA23 reverted (or OOG)\\\");\\n }\\n if (paymaster == address(0)) {\\n DepositInfo storage senderInfo = deposits[sender];\\n uint256 deposit = senderInfo.deposit;\\n if (requiredPrefund > deposit) {\\n revert FailedOp(opIndex, \\\"AA21 didn't pay prefund\\\");\\n }\\n senderInfo.deposit = uint112(deposit - requiredPrefund);\\n }\\n gasUsedByValidateAccountPrepayment = preGas - gasleft();\\n }\\n }\\n\\n /**\\n * In case the request has a paymaster:\\n * Validate paymaster has enough deposit.\\n * Call paymaster.validatePaymasterUserOp.\\n * Revert with proper FailedOp in case paymaster reverts.\\n * Decrement paymaster's deposit\\n */\\n function _validatePaymasterPrepayment(\\n uint256 opIndex,\\n UserOperation calldata op,\\n UserOpInfo memory opInfo,\\n uint256 requiredPreFund,\\n uint256 gasUsedByValidateAccountPrepayment\\n ) internal returns (bytes memory context, uint256 validationData) {\\n unchecked {\\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\\n uint256 verificationGasLimit = mUserOp.verificationGasLimit;\\n require(\\n verificationGasLimit > gasUsedByValidateAccountPrepayment,\\n \\\"AA41 too little verificationGas\\\"\\n );\\n uint256 gas = verificationGasLimit -\\n gasUsedByValidateAccountPrepayment;\\n\\n address paymaster = mUserOp.paymaster;\\n DepositInfo storage paymasterInfo = deposits[paymaster];\\n uint256 deposit = paymasterInfo.deposit;\\n if (deposit < requiredPreFund) {\\n revert FailedOp(opIndex, \\\"AA31 paymaster deposit too low\\\");\\n }\\n paymasterInfo.deposit = uint112(deposit - requiredPreFund);\\n try\\n IPaymaster(paymaster).validatePaymasterUserOp{gas: gas}(\\n op,\\n opInfo.userOpHash,\\n requiredPreFund\\n )\\n returns (bytes memory _context, uint256 _validationData) {\\n context = _context;\\n validationData = _validationData;\\n } catch Error(string memory revertReason) {\\n revert FailedOp(\\n opIndex,\\n string.concat(\\\"AA33 reverted: \\\", revertReason)\\n );\\n } catch {\\n revert FailedOp(opIndex, \\\"AA33 reverted (or OOG)\\\");\\n }\\n }\\n }\\n\\n /**\\n * revert if either account validationData or paymaster validationData is expired\\n */\\n function _validateAccountAndPaymasterValidationData(\\n uint256 opIndex,\\n uint256 validationData,\\n uint256 paymasterValidationData,\\n address expectedAggregator\\n ) internal view {\\n (address aggregator, bool outOfTimeRange) = _getValidationData(\\n validationData\\n );\\n if (expectedAggregator != aggregator) {\\n revert FailedOp(opIndex, \\\"AA24 signature error\\\");\\n }\\n if (outOfTimeRange) {\\n revert FailedOp(opIndex, \\\"AA22 expired or not due\\\");\\n }\\n //pmAggregator is not a real signature aggregator: we don't have logic to handle it as address.\\n // non-zero address means that the paymaster fails due to some signature check (which is ok only during estimation)\\n address pmAggregator;\\n (pmAggregator, outOfTimeRange) = _getValidationData(\\n paymasterValidationData\\n );\\n if (pmAggregator != address(0)) {\\n revert FailedOp(opIndex, \\\"AA34 signature error\\\");\\n }\\n if (outOfTimeRange) {\\n revert FailedOp(opIndex, \\\"AA32 paymaster expired or not due\\\");\\n }\\n }\\n\\n function _getValidationData(\\n uint256 validationData\\n ) internal view returns (address aggregator, bool outOfTimeRange) {\\n if (validationData == 0) {\\n return (address(0), false);\\n }\\n ValidationData memory data = _parseValidationData(validationData);\\n // solhint-disable-next-line not-rely-on-time\\n outOfTimeRange =\\n block.timestamp > data.validUntil ||\\n block.timestamp < data.validAfter;\\n aggregator = data.aggregator;\\n }\\n\\n /**\\n * validate account and paymaster (if defined).\\n * also make sure total validation doesn't exceed verificationGasLimit\\n * this method is called off-chain (simulateValidation()) and on-chain (from handleOps)\\n * @param opIndex the index of this userOp into the \\\"opInfos\\\" array\\n * @param userOp the userOp to validate\\n */\\n function _validatePrepayment(\\n uint256 opIndex,\\n UserOperation calldata userOp,\\n UserOpInfo memory outOpInfo\\n )\\n private\\n returns (uint256 validationData, uint256 paymasterValidationData)\\n {\\n uint256 preGas = gasleft();\\n MemoryUserOp memory mUserOp = outOpInfo.mUserOp;\\n _copyUserOpToMemory(userOp, mUserOp);\\n outOpInfo.userOpHash = getUserOpHash(userOp);\\n\\n // validate all numeric values in userOp are well below 128 bit, so they can safely be added\\n // and multiplied without causing overflow\\n uint256 maxGasValues = mUserOp.preVerificationGas |\\n mUserOp.verificationGasLimit |\\n mUserOp.callGasLimit |\\n userOp.maxFeePerGas |\\n userOp.maxPriorityFeePerGas;\\n require(maxGasValues <= type(uint120).max, \\\"AA94 gas values overflow\\\");\\n\\n uint256 gasUsedByValidateAccountPrepayment;\\n uint256 requiredPreFund = _getRequiredPrefund(mUserOp);\\n (\\n gasUsedByValidateAccountPrepayment,\\n validationData\\n ) = _validateAccountPrepayment(\\n opIndex,\\n userOp,\\n outOpInfo,\\n requiredPreFund\\n );\\n\\n if (!_validateAndUpdateNonce(mUserOp.sender, mUserOp.nonce)) {\\n revert FailedOp(opIndex, \\\"AA25 invalid account nonce\\\");\\n }\\n\\n //a \\\"marker\\\" where account opcode validation is done and paymaster opcode validation is about to start\\n // (used only by off-chain simulateValidation)\\n numberMarker();\\n\\n bytes memory context;\\n if (mUserOp.paymaster != address(0)) {\\n (context, paymasterValidationData) = _validatePaymasterPrepayment(\\n opIndex,\\n userOp,\\n outOpInfo,\\n requiredPreFund,\\n gasUsedByValidateAccountPrepayment\\n );\\n }\\n unchecked {\\n uint256 gasUsed = preGas - gasleft();\\n\\n if (userOp.verificationGasLimit < gasUsed) {\\n revert FailedOp(opIndex, \\\"AA40 over verificationGasLimit\\\");\\n }\\n outOpInfo.prefund = requiredPreFund;\\n outOpInfo.contextOffset = getOffsetOfMemoryBytes(context);\\n outOpInfo.preOpGas = preGas - gasleft() + userOp.preVerificationGas;\\n }\\n }\\n\\n /**\\n * process post-operation.\\n * called just after the callData is executed.\\n * if a paymaster is defined and its validation returned a non-empty context, its postOp is called.\\n * the excess amount is refunded to the account (or paymaster - if it was used in the request)\\n * @param opIndex index in the batch\\n * @param mode - whether is called from innerHandleOp, or outside (postOpReverted)\\n * @param opInfo userOp fields and info collected during validation\\n * @param context the context returned in validatePaymasterUserOp\\n * @param actualGas the gas used so far by this user operation\\n */\\n function _handlePostOp(\\n uint256 opIndex,\\n IPaymaster.PostOpMode mode,\\n UserOpInfo memory opInfo,\\n bytes memory context,\\n uint256 actualGas\\n ) private returns (uint256 actualGasCost) {\\n uint256 preGas = gasleft();\\n unchecked {\\n address refundAddress;\\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\\n uint256 gasPrice = getUserOpGasPrice(mUserOp);\\n\\n address paymaster = mUserOp.paymaster;\\n if (paymaster == address(0)) {\\n refundAddress = mUserOp.sender;\\n } else {\\n refundAddress = paymaster;\\n if (context.length > 0) {\\n actualGasCost = actualGas * gasPrice;\\n if (mode != IPaymaster.PostOpMode.postOpReverted) {\\n IPaymaster(paymaster).postOp{\\n gas: mUserOp.verificationGasLimit\\n }(mode, context, actualGasCost);\\n } else {\\n // solhint-disable-next-line no-empty-blocks\\n try\\n IPaymaster(paymaster).postOp{\\n gas: mUserOp.verificationGasLimit\\n }(mode, context, actualGasCost)\\n {} catch Error(string memory reason) {\\n revert FailedOp(\\n opIndex,\\n string.concat(\\\"AA50 postOp reverted: \\\", reason)\\n );\\n } catch {\\n revert FailedOp(opIndex, \\\"AA50 postOp revert\\\");\\n }\\n }\\n }\\n }\\n actualGas += preGas - gasleft();\\n actualGasCost = actualGas * gasPrice;\\n if (opInfo.prefund < actualGasCost) {\\n revert FailedOp(opIndex, \\\"AA51 prefund below actualGasCost\\\");\\n }\\n uint256 refund = opInfo.prefund - actualGasCost;\\n _incrementDeposit(refundAddress, refund);\\n bool success = mode == IPaymaster.PostOpMode.opSucceeded;\\n emit UserOperationEvent(\\n opInfo.userOpHash,\\n mUserOp.sender,\\n mUserOp.paymaster,\\n mUserOp.nonce,\\n success,\\n actualGasCost,\\n actualGas\\n );\\n } // unchecked\\n }\\n\\n /**\\n * the gas price this UserOp agrees to pay.\\n * relayer/block builder might submit the TX with higher priorityFee, but the user should not\\n */\\n function getUserOpGasPrice(\\n MemoryUserOp memory mUserOp\\n ) internal view returns (uint256) {\\n unchecked {\\n uint256 maxFeePerGas = mUserOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = mUserOp.maxPriorityFeePerGas;\\n if (maxFeePerGas == maxPriorityFeePerGas) {\\n //legacy mode (for networks that don't support basefee opcode)\\n return maxFeePerGas;\\n }\\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\\n }\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n function getOffsetOfMemoryBytes(\\n bytes memory data\\n ) internal pure returns (uint256 offset) {\\n assembly {\\n offset := data\\n }\\n }\\n\\n function getMemoryBytesFromOffset(\\n uint256 offset\\n ) internal pure returns (bytes memory data) {\\n assembly {\\n data := offset\\n }\\n }\\n\\n //place the NUMBER opcode in the code.\\n // this is used as a marker during simulation, as this OP is completely banned from the simulated code of the\\n // account and paymaster.\\n function numberMarker() internal view {\\n assembly {\\n mstore(0, number())\\n }\\n }\\n}\\n\"\n },\n \"contracts/aa-4337/core/Helpers.sol\": {\n \"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable no-inline-assembly */\\n\\n/**\\n * returned data from validateUserOp.\\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\\n * @param aggregator - address(0) - the account validated the signature by itself.\\n * address(1) - the account failed to validate the signature.\\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\\n * @param validAfter - this UserOp is valid only after this timestamp.\\n * @param validaUntil - this UserOp is valid only up to this timestamp.\\n */\\nstruct ValidationData {\\n address aggregator;\\n uint48 validAfter;\\n uint48 validUntil;\\n}\\n\\n//extract sigFailed, validAfter, validUntil.\\n// also convert zero validUntil to type(uint48).max\\nfunction _parseValidationData(\\n uint validationData\\n) pure returns (ValidationData memory data) {\\n address aggregator = address(uint160(validationData));\\n uint48 validUntil = uint48(validationData >> 160);\\n if (validUntil == 0) {\\n validUntil = type(uint48).max;\\n }\\n uint48 validAfter = uint48(validationData >> (48 + 160));\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n// intersect account and paymaster ranges.\\nfunction _intersectTimeRange(\\n uint256 validationData,\\n uint256 paymasterValidationData\\n) pure returns (ValidationData memory) {\\n ValidationData memory accountValidationData = _parseValidationData(\\n validationData\\n );\\n ValidationData memory pmValidationData = _parseValidationData(\\n paymasterValidationData\\n );\\n address aggregator = accountValidationData.aggregator;\\n if (aggregator == address(0)) {\\n aggregator = pmValidationData.aggregator;\\n }\\n uint48 validAfter = accountValidationData.validAfter;\\n uint48 validUntil = accountValidationData.validUntil;\\n uint48 pmValidAfter = pmValidationData.validAfter;\\n uint48 pmValidUntil = pmValidationData.validUntil;\\n\\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp\\n * @param data - the ValidationData to pack\\n */\\nfunction _packValidationData(\\n ValidationData memory data\\n) pure returns (uint256) {\\n return\\n uint160(data.aggregator) |\\n (uint256(data.validUntil) << 160) |\\n (uint256(data.validAfter) << (160 + 48));\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp, when not using an aggregator\\n * @param sigFailed - true for signature failure, false for success\\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\\n * @param validAfter first timestamp this UserOperation is valid\\n */\\nfunction _packValidationData(\\n bool sigFailed,\\n uint48 validUntil,\\n uint48 validAfter\\n) pure returns (uint256) {\\n return\\n (sigFailed ? 1 : 0) |\\n (uint256(validUntil) << 160) |\\n (uint256(validAfter) << (160 + 48));\\n}\\n\\n/**\\n * keccak function over calldata.\\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\\n */\\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\\n assembly {\\n let mem := mload(0x40)\\n let len := data.length\\n calldatacopy(mem, data.offset, len)\\n ret := keccak256(mem, len)\\n }\\n}\\n\"\n },\n \"contracts/aa-4337/core/NonceManager.sol\": {\n \"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\nimport \\\"../interfaces/IEntryPoint.sol\\\";\\n\\n/**\\n * nonce management functionality\\n */\\ncontract NonceManager is INonceManager {\\n /**\\n * The next valid sequence number for a given nonce key.\\n */\\n mapping(address => mapping(uint192 => uint256)) public nonceSequenceNumber;\\n\\n function getNonce(\\n address sender,\\n uint192 key\\n ) public view override returns (uint256 nonce) {\\n return nonceSequenceNumber[sender][key] | (uint256(key) << 64);\\n }\\n\\n // allow an account to manually increment its own nonce.\\n // (mainly so that during construction nonce can be made non-zero,\\n // to \\\"absorb\\\" the gas cost of first nonce increment to 1st transaction (construction),\\n // not to 2nd transaction)\\n function incrementNonce(uint192 key) public override {\\n nonceSequenceNumber[msg.sender][key]++;\\n }\\n\\n /**\\n * validate nonce uniqueness for this account.\\n * called just after validateUserOp()\\n */\\n function _validateAndUpdateNonce(\\n address sender,\\n uint256 nonce\\n ) internal returns (bool) {\\n uint192 key = uint192(nonce >> 64);\\n uint64 seq = uint64(nonce);\\n return nonceSequenceNumber[sender][key]++ == seq;\\n }\\n}\\n\"\n },\n \"contracts/aa-4337/core/SenderCreator.sol\": {\n \"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/**\\n * helper contract for EntryPoint, to call userOp.initCode from a \\\"neutral\\\" address,\\n * which is explicitly not the entryPoint itself.\\n */\\ncontract SenderCreator {\\n /**\\n * call the \\\"initCode\\\" factory to create and return the sender account address\\n * @param initCode the initCode value from a UserOp. contains 20 bytes of factory address, followed by calldata\\n * @return sender the returned address of the created account, or zero address on failure.\\n */\\n function createSender(\\n bytes calldata initCode\\n ) external returns (address sender) {\\n address factory = address(bytes20(initCode[0:20]));\\n bytes memory initCallData = initCode[20:];\\n bool success;\\n /* solhint-disable no-inline-assembly */\\n assembly {\\n success := call(\\n gas(),\\n factory,\\n 0,\\n add(initCallData, 0x20),\\n mload(initCallData),\\n 0,\\n 32\\n )\\n sender := mload(0)\\n }\\n if (!success) {\\n sender = address(0);\\n }\\n }\\n}\\n\"\n },\n \"contracts/aa-4337/core/StakeManager.sol\": {\n \"content\": \"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity 0.8.21;\\n\\nimport \\\"../interfaces/IStakeManager.sol\\\";\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable not-rely-on-time */\\n/**\\n * manage deposits and stakes.\\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\\n * stake is value locked for at least \\\"unstakeDelay\\\" by a paymaster.\\n */\\nabstract contract StakeManager is IStakeManager {\\n /// maps paymaster to their deposits and stakes\\n mapping(address => DepositInfo) public deposits;\\n\\n /// @inheritdoc IStakeManager\\n function getDepositInfo(\\n address account\\n ) public view returns (DepositInfo memory info) {\\n return deposits[account];\\n }\\n\\n // internal method to return just the stake info\\n function _getStakeInfo(\\n address addr\\n ) internal view returns (StakeInfo memory info) {\\n DepositInfo storage depositInfo = deposits[addr];\\n info.stake = depositInfo.stake;\\n info.unstakeDelaySec = depositInfo.unstakeDelaySec;\\n }\\n\\n /// return the deposit (for gas payment) of the account\\n function balanceOf(address account) public view returns (uint256) {\\n return deposits[account].deposit;\\n }\\n\\n receive() external payable {\\n depositTo(msg.sender);\\n }\\n\\n function _incrementDeposit(address account, uint256 amount) internal {\\n DepositInfo storage info = deposits[account];\\n uint256 newAmount = info.deposit + amount;\\n require(newAmount <= type(uint112).max, \\\"deposit overflow\\\");\\n info.deposit = uint112(newAmount);\\n }\\n\\n /**\\n * add to the deposit of the given account\\n */\\n function depositTo(address account) public payable {\\n _incrementDeposit(account, msg.value);\\n DepositInfo storage info = deposits[account];\\n emit Deposited(account, info.deposit);\\n }\\n\\n /**\\n * add to the account's stake - amount and delay\\n * any pending unstake is first cancelled.\\n * @param unstakeDelaySec the new lock duration before the deposit can be withdrawn.\\n */\\n function addStake(uint32 unstakeDelaySec) public payable {\\n DepositInfo storage info = deposits[msg.sender];\\n require(unstakeDelaySec > 0, \\\"must specify unstake delay\\\");\\n require(\\n unstakeDelaySec >= info.unstakeDelaySec,\\n \\\"cannot decrease unstake time\\\"\\n );\\n uint256 stake = info.stake + msg.value;\\n require(stake > 0, \\\"no stake specified\\\");\\n require(stake <= type(uint112).max, \\\"stake overflow\\\");\\n deposits[msg.sender] = DepositInfo(\\n info.deposit,\\n true,\\n uint112(stake),\\n unstakeDelaySec,\\n 0\\n );\\n emit StakeLocked(msg.sender, stake, unstakeDelaySec);\\n }\\n\\n /**\\n * attempt to unlock the stake.\\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\\n */\\n function unlockStake() external {\\n DepositInfo storage info = deposits[msg.sender];\\n require(info.unstakeDelaySec != 0, \\\"not staked\\\");\\n require(info.staked, \\\"already unstaking\\\");\\n uint48 withdrawTime = uint48(block.timestamp) + info.unstakeDelaySec;\\n info.withdrawTime = withdrawTime;\\n info.staked = false;\\n emit StakeUnlocked(msg.sender, withdrawTime);\\n }\\n\\n /**\\n * withdraw from the (unlocked) stake.\\n * must first call unlockStake and wait for the unstakeDelay to pass\\n * @param withdrawAddress the address to send withdrawn value.\\n */\\n function withdrawStake(address payable withdrawAddress) external {\\n DepositInfo storage info = deposits[msg.sender];\\n uint256 stake = info.stake;\\n require(stake > 0, \\\"No stake to withdraw\\\");\\n require(info.withdrawTime > 0, \\\"must call unlockStake() first\\\");\\n require(\\n info.withdrawTime <= block.timestamp,\\n \\\"Stake withdrawal is not due\\\"\\n );\\n info.unstakeDelaySec = 0;\\n info.withdrawTime = 0;\\n info.stake = 0;\\n emit StakeWithdrawn(msg.sender, withdrawAddress, stake);\\n (bool success, ) = withdrawAddress.call{value: stake}(\\\"\\\");\\n require(success, \\\"failed to withdraw stake\\\");\\n }\\n\\n /**\\n * withdraw from the deposit.\\n * @param withdrawAddress the address to send withdrawn value.\\n * @param withdrawAmount the amount to withdraw.\\n */\\n function withdrawTo(\\n address payable withdrawAddress,\\n uint256 withdrawAmount\\n ) external {\\n DepositInfo storage info = deposits[msg.sender];\\n require(withdrawAmount <= info.deposit, \\\"Withdraw amount too large\\\");\\n info.deposit = uint112(info.deposit - withdrawAmount);\\n emit Withdrawn(msg.sender, withdrawAddress, withdrawAmount);\\n (bool success, ) = withdrawAddress.call{value: withdrawAmount}(\\\"\\\");\\n require(success, \\\"failed to withdraw\\\");\\n }\\n}\\n\"\n },\n \"contracts/aa-4337/interfaces/IAccount.sol\": {\n \"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\ninterface IAccount {\\n /**\\n * Validate user's signature and nonce\\n * the entryPoint will make the call to the recipient only if this validation call returns successfully.\\n * signature failure should be reported by returning SIG_VALIDATION_FAILED (1).\\n * This allows making a \\\"simulation call\\\" without a valid signature\\n * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure.\\n *\\n * @dev Must validate caller is the entryPoint.\\n * Must validate the signature and nonce\\n * @param userOp the operation that is about to be executed.\\n * @param userOpHash hash of the user's request data. can be used as the basis for signature.\\n * @param missingAccountFunds missing funds on the account's deposit in the entrypoint.\\n * This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call.\\n * The excess is left as a deposit in the entrypoint, for future calls.\\n * can be withdrawn anytime using \\\"entryPoint.withdrawTo()\\\"\\n * In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero.\\n * @return validationData packaged ValidationData structure. use `_packValidationData` and `_unpackValidationData` to encode and decode\\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\\n * otherwise, an address of an \\\"authorizer\\\" contract.\\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \\\"indefinite\\\"\\n * <6-byte> validAfter - first timestamp this operation is valid\\n * If an account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\\n */\\n function validateUserOp(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n uint256 missingAccountFunds\\n ) external returns (uint256 validationData);\\n}\\n\"\n },\n \"contracts/aa-4337/interfaces/IAggregator.sol\": {\n \"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\n/**\\n * Aggregated Signatures validator.\\n */\\ninterface IAggregator {\\n /**\\n * validate aggregated signature.\\n * revert if the aggregated signature does not match the given list of operations.\\n */\\n function validateSignatures(\\n UserOperation[] calldata userOps,\\n bytes calldata signature\\n ) external view;\\n\\n /**\\n * validate signature of a single userOp\\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\\n * @param userOp the userOperation received from the user.\\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\\n * (usually empty, unless account and aggregator support some kind of \\\"multisig\\\"\\n */\\n function validateUserOpSignature(\\n UserOperation calldata userOp\\n ) external view returns (bytes memory sigForUserOp);\\n\\n /**\\n * aggregate multiple signatures into a single value.\\n * This method is called off-chain to calculate the signature to pass with handleOps()\\n * bundler MAY use optimized custom code perform this aggregation\\n * @param userOps array of UserOperations to collect the signatures from.\\n * @return aggregatedSignature the aggregated signature\\n */\\n function aggregateSignatures(\\n UserOperation[] calldata userOps\\n ) external view returns (bytes memory aggregatedSignature);\\n}\\n\"\n },\n \"contracts/aa-4337/interfaces/IEntryPoint.sol\": {\n \"content\": \"/**\\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\\n ** Only one instance required on each chain.\\n **/\\n// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-inline-assembly */\\n/* solhint-disable reason-string */\\n\\nimport \\\"./UserOperation.sol\\\";\\nimport \\\"./IStakeManager.sol\\\";\\nimport \\\"./IAggregator.sol\\\";\\nimport \\\"./INonceManager.sol\\\";\\n\\ninterface IEntryPoint is IStakeManager, INonceManager {\\n /***\\n * An event emitted after each successful request\\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\\n * @param sender - the account that generates this request.\\n * @param paymaster - if non-null, the paymaster that pays for this request.\\n * @param nonce - the nonce value from the request.\\n * @param success - true if the sender transaction succeeded, false if reverted.\\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\\n */\\n event UserOperationEvent(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address indexed paymaster,\\n uint256 nonce,\\n bool success,\\n uint256 actualGasCost,\\n uint256 actualGasUsed\\n );\\n\\n /**\\n * account \\\"sender\\\" was deployed.\\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\\n * @param sender the account that is deployed\\n * @param factory the factory used to deploy this account (in the initCode)\\n * @param paymaster the paymaster used by this UserOp\\n */\\n event AccountDeployed(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address factory,\\n address paymaster\\n );\\n\\n /**\\n * An event emitted if the UserOperation \\\"callData\\\" reverted with non-zero length\\n * @param userOpHash the request unique identifier.\\n * @param sender the sender of this request\\n * @param nonce the nonce used in the request\\n * @param revertReason - the return bytes from the (reverted) call to \\\"callData\\\".\\n */\\n event UserOperationRevertReason(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n uint256 nonce,\\n bytes revertReason\\n );\\n\\n /**\\n * an event emitted by handleOps(), before starting the execution loop.\\n * any event emitted before this event, is part of the validation.\\n */\\n event BeforeExecution();\\n\\n /**\\n * signature aggregator used by the following UserOperationEvents within this bundle.\\n */\\n event SignatureAggregatorChanged(address indexed aggregator);\\n\\n /**\\n * a custom revert error of handleOps, to identify the offending op.\\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\\n * @param reason - revert reason\\n * The string starts with a unique code \\\"AAmn\\\", where \\\"m\\\" is \\\"1\\\" for factory, \\\"2\\\" for account and \\\"3\\\" for paymaster issues,\\n * so a failure can be attributed to the correct entity.\\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\\n */\\n error FailedOp(uint256 opIndex, string reason);\\n\\n /**\\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\\n */\\n error SignatureValidationFailed(address aggregator);\\n\\n /**\\n * Successful result from simulateValidation.\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n */\\n error ValidationResult(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo\\n );\\n\\n /**\\n * Successful result from simulateValidation, if the account returns a signature aggregator\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\\n * bundler MUST use it to verify the signature, or reject the UserOperation\\n */\\n error ValidationResultWithAggregation(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo,\\n AggregatorStakeInfo aggregatorInfo\\n );\\n\\n /**\\n * return value of getSenderAddress\\n */\\n error SenderAddressResult(address sender);\\n\\n /**\\n * return value of simulateHandleOp\\n */\\n error ExecutionResult(\\n uint256 preOpGas,\\n uint256 paid,\\n uint48 validAfter,\\n uint48 validUntil,\\n bool targetSuccess,\\n bytes targetResult\\n );\\n\\n //UserOps handled, per aggregator\\n struct UserOpsPerAggregator {\\n UserOperation[] userOps;\\n // aggregator address\\n IAggregator aggregator;\\n // aggregated signature\\n bytes signature;\\n }\\n\\n /**\\n * Execute a batch of UserOperation.\\n * no signature aggregator is used.\\n * if any account requires an aggregator (that is, it returned an aggregator when\\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\\n * @param ops the operations to execute\\n * @param beneficiary the address to receive the fees\\n */\\n function handleOps(\\n UserOperation[] calldata ops,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * Execute a batch of UserOperation with Aggregators\\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\\n * @param beneficiary the address to receive the fees\\n */\\n function handleAggregatedOps(\\n UserOpsPerAggregator[] calldata opsPerAggregator,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * generate a request Id - unique identifier for this request.\\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\\n */\\n function getUserOpHash(\\n UserOperation calldata userOp\\n ) external view returns (bytes32);\\n\\n /**\\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\\n * @param userOp the user operation to validate.\\n */\\n function simulateValidation(UserOperation calldata userOp) external;\\n\\n /**\\n * gas and return values during simulation\\n * @param preOpGas the gas used for validation (including preValidationGas)\\n * @param prefund the required prefund for this operation\\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\\n */\\n struct ReturnInfo {\\n uint256 preOpGas;\\n uint256 prefund;\\n bool sigFailed;\\n uint48 validAfter;\\n uint48 validUntil;\\n bytes paymasterContext;\\n }\\n\\n /**\\n * returned aggregated signature info.\\n * the aggregator returned by the account, and its current stake.\\n */\\n struct AggregatorStakeInfo {\\n address aggregator;\\n StakeInfo stakeInfo;\\n }\\n\\n /**\\n * Get counterfactual sender address.\\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\\n * this method always revert, and returns the address in SenderAddressResult error\\n * @param initCode the constructor code to be passed into the UserOperation.\\n */\\n function getSenderAddress(bytes memory initCode) external;\\n\\n /**\\n * simulate full execution of a UserOperation (including both validation and target execution)\\n * this method will always revert with \\\"ExecutionResult\\\".\\n * it performs full validation of the UserOperation, but ignores signature error.\\n * an optional target address is called after the userop succeeds, and its value is returned\\n * (before the entire call is reverted)\\n * Note that in order to collect the the success/failure of the target call, it must be executed\\n * with trace enabled to track the emitted events.\\n * @param op the UserOperation to simulate\\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\\n * are set to the return from that call.\\n * @param targetCallData callData to pass to target address\\n */\\n function simulateHandleOp(\\n UserOperation calldata op,\\n address target,\\n bytes calldata targetCallData\\n ) external;\\n}\\n\"\n },\n \"contracts/aa-4337/interfaces/INonceManager.sol\": {\n \"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\ninterface INonceManager {\\n /**\\n * Return the next nonce for this sender.\\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\\n * But UserOp with different keys can come with arbitrary order.\\n *\\n * @param sender the account address\\n * @param key the high 192 bit of the nonce\\n * @return nonce a full nonce to pass for next UserOp with this sender.\\n */\\n function getNonce(\\n address sender,\\n uint192 key\\n ) external view returns (uint256 nonce);\\n\\n /**\\n * Manually increment the nonce of the sender.\\n * This method is exposed just for completeness..\\n * Account does NOT need to call it, neither during validation, nor elsewhere,\\n * as the EntryPoint will update the nonce regardless.\\n * Possible use-case is call it with various keys to \\\"initialize\\\" their nonces to one, so that future\\n * UserOperations will not pay extra for the first transaction with a given key.\\n */\\n function incrementNonce(uint192 key) external;\\n}\\n\"\n },\n \"contracts/aa-4337/interfaces/IPaymaster.sol\": {\n \"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\n/**\\n * the interface exposed by a paymaster contract, who agrees to pay the gas for user's operations.\\n * a paymaster must hold a stake to cover the required entrypoint stake and also the gas for the transaction.\\n */\\ninterface IPaymaster {\\n enum PostOpMode {\\n opSucceeded, // user op succeeded\\n opReverted, // user op reverted. still has to pay for gas.\\n postOpReverted //user op succeeded, but caused postOp to revert. Now it's a 2nd call, after user's op was deliberately reverted.\\n }\\n\\n /**\\n * payment validation: check if paymaster agrees to pay.\\n * Must verify sender is the entryPoint.\\n * Revert to reject this request.\\n * Note that bundlers will reject this method if it changes the state, unless the paymaster is trusted (whitelisted)\\n * The paymaster pre-pays using its deposit, and receive back a refund after the postOp method returns.\\n * @param userOp the user operation\\n * @param userOpHash hash of the user's request data.\\n * @param maxCost the maximum cost of this transaction (based on maximum gas and gas price from userOp)\\n * @return context value to send to a postOp\\n * zero length to signify postOp is not required.\\n * @return validationData signature and time-range of this operation, encoded the same as the return value of validateUserOperation\\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\\n * otherwise, an address of an \\\"authorizer\\\" contract.\\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \\\"indefinite\\\"\\n * <6-byte> validAfter - first timestamp this operation is valid\\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\\n */\\n function validatePaymasterUserOp(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n uint256 maxCost\\n ) external returns (bytes memory context, uint256 validationData);\\n\\n /**\\n * post-operation handler.\\n * Must verify sender is the entryPoint\\n * @param mode enum with the following options:\\n * opSucceeded - user operation succeeded.\\n * opReverted - user op reverted. still has to pay for gas.\\n * postOpReverted - user op succeeded, but caused postOp (in mode=opSucceeded) to revert.\\n * Now this is the 2nd call, after user's op was deliberately reverted.\\n * @param context - the context value returned by validatePaymasterUserOp\\n * @param actualGasCost - actual gas used so far (without this postOp call).\\n */\\n function postOp(\\n PostOpMode mode,\\n bytes calldata context,\\n uint256 actualGasCost\\n ) external;\\n}\\n\"\n },\n \"contracts/aa-4337/interfaces/IStakeManager.sol\": {\n \"content\": \"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8.12;\\n\\n/**\\n * manage deposits and stakes.\\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\\n * stake is value locked for at least \\\"unstakeDelay\\\" by the staked entity.\\n */\\ninterface IStakeManager {\\n event Deposited(address indexed account, uint256 totalDeposit);\\n\\n event Withdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /// Emitted when stake or unstake delay are modified\\n event StakeLocked(\\n address indexed account,\\n uint256 totalStaked,\\n uint256 unstakeDelaySec\\n );\\n\\n /// Emitted once a stake is scheduled for withdrawal\\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\\n\\n event StakeWithdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /**\\n * @param deposit the entity's deposit\\n * @param staked true if this entity is staked.\\n * @param stake actual amount of ether staked for this entity.\\n * @param unstakeDelaySec minimum delay to withdraw the stake.\\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\\n * and the rest fit into a 2nd cell.\\n * 112 bit allows for 10^15 eth\\n * 48 bit for full timestamp\\n * 32 bit allows 150 years for unstake delay\\n */\\n struct DepositInfo {\\n uint112 deposit;\\n bool staked;\\n uint112 stake;\\n uint32 unstakeDelaySec;\\n uint48 withdrawTime;\\n }\\n\\n //API struct used by getStakeInfo and simulateValidation\\n struct StakeInfo {\\n uint256 stake;\\n uint256 unstakeDelaySec;\\n }\\n\\n /// @return info - full deposit information of given account\\n function getDepositInfo(\\n address account\\n ) external view returns (DepositInfo memory info);\\n\\n /// @return the deposit (for gas payment) of the account\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * add to the deposit of the given account\\n */\\n function depositTo(address account) external payable;\\n\\n /**\\n * add to the account's stake - amount and delay\\n * any pending unstake is first cancelled.\\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\\n */\\n function addStake(uint32 _unstakeDelaySec) external payable;\\n\\n /**\\n * attempt to unlock the stake.\\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\\n */\\n function unlockStake() external;\\n\\n /**\\n * withdraw from the (unlocked) stake.\\n * must first call unlockStake and wait for the unstakeDelay to pass\\n * @param withdrawAddress the address to send withdrawn value.\\n */\\n function withdrawStake(address payable withdrawAddress) external;\\n\\n /**\\n * withdraw from the deposit.\\n * @param withdrawAddress the address to send withdrawn value.\\n * @param withdrawAmount the amount to withdraw.\\n */\\n function withdrawTo(\\n address payable withdrawAddress,\\n uint256 withdrawAmount\\n ) external;\\n}\\n\"\n },\n \"contracts/aa-4337/interfaces/UserOperation.sol\": {\n \"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable no-inline-assembly */\\n\\nimport {calldataKeccak} from \\\"../core/Helpers.sol\\\";\\n\\n/**\\n * User Operation struct\\n * @param sender the sender account of this request.\\n * @param nonce unique value the sender uses to verify it is not a replay.\\n * @param initCode if set, the account contract will be created by this constructor/\\n * @param callData the method call to execute on this account.\\n * @param callGasLimit the gas limit passed to the callData method call.\\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\\n * @param maxFeePerGas same as EIP-1559 gas parameter.\\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\\n */\\nstruct UserOperation {\\n address sender;\\n uint256 nonce;\\n bytes initCode;\\n bytes callData;\\n uint256 callGasLimit;\\n uint256 verificationGasLimit;\\n uint256 preVerificationGas;\\n uint256 maxFeePerGas;\\n uint256 maxPriorityFeePerGas;\\n bytes paymasterAndData;\\n bytes signature;\\n}\\n\\n/**\\n * Utility functions helpful when working with UserOperation structs.\\n */\\nlibrary UserOperationLib {\\n function getSender(\\n UserOperation calldata userOp\\n ) internal pure returns (address) {\\n address data;\\n //read sender from userOp, which is first userOp member (saves 800 gas...)\\n assembly {\\n data := calldataload(userOp)\\n }\\n return address(uint160(data));\\n }\\n\\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\\n // pay above what he signed for.\\n function gasPrice(\\n UserOperation calldata userOp\\n ) internal view returns (uint256) {\\n unchecked {\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n if (maxFeePerGas == maxPriorityFeePerGas) {\\n //legacy mode (for networks that don't support basefee opcode)\\n return maxFeePerGas;\\n }\\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\\n }\\n }\\n\\n function pack(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes memory ret) {\\n address sender = getSender(userOp);\\n uint256 nonce = userOp.nonce;\\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\\n bytes32 hashCallData = calldataKeccak(userOp.callData);\\n uint256 callGasLimit = userOp.callGasLimit;\\n uint256 verificationGasLimit = userOp.verificationGasLimit;\\n uint256 preVerificationGas = userOp.preVerificationGas;\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\\n\\n return\\n abi.encode(\\n sender,\\n nonce,\\n hashInitCode,\\n hashCallData,\\n callGasLimit,\\n verificationGasLimit,\\n preVerificationGas,\\n maxFeePerGas,\\n maxPriorityFeePerGas,\\n hashPaymasterAndData\\n );\\n }\\n\\n function hash(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes32) {\\n return keccak256(pack(userOp));\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n}\\n\"\n },\n \"contracts/aa-4337/utils/Exec.sol\": {\n \"content\": \"// SPDX-License-Identifier: LGPL-3.0-only\\npragma solidity >=0.7.5 <0.9.0;\\n\\n// solhint-disable no-inline-assembly\\n\\n/**\\n * Utility functions helpful when making different kinds of contract calls in Solidity.\\n */\\nlibrary Exec {\\n function call(\\n address to,\\n uint256 value,\\n bytes memory data,\\n uint256 txGas\\n ) internal returns (bool success) {\\n assembly {\\n success := call(\\n txGas,\\n to,\\n value,\\n add(data, 0x20),\\n mload(data),\\n 0,\\n 0\\n )\\n }\\n }\\n\\n function staticcall(\\n address to,\\n bytes memory data,\\n uint256 txGas\\n ) internal view returns (bool success) {\\n assembly {\\n success := staticcall(txGas, to, add(data, 0x20), mload(data), 0, 0)\\n }\\n }\\n\\n function delegateCall(\\n address to,\\n bytes memory data,\\n uint256 txGas\\n ) internal returns (bool success) {\\n assembly {\\n success := delegatecall(\\n txGas,\\n to,\\n add(data, 0x20),\\n mload(data),\\n 0,\\n 0\\n )\\n }\\n }\\n\\n // get returned data from last call or calldelegate\\n function getReturnData(\\n uint256 maxLen\\n ) internal pure returns (bytes memory returnData) {\\n assembly {\\n let len := returndatasize()\\n if gt(len, maxLen) {\\n len := maxLen\\n }\\n let ptr := mload(0x40)\\n mstore(0x40, add(ptr, add(len, 0x20)))\\n mstore(ptr, len)\\n returndatacopy(add(ptr, 0x20), 0, len)\\n returnData := ptr\\n }\\n }\\n\\n // revert with explicit byte array (probably reverted info from call)\\n function revertWithData(bytes memory returnData) internal pure {\\n assembly {\\n revert(add(returnData, 32), mload(returnData))\\n }\\n }\\n\\n function callAndRevert(\\n address to,\\n bytes memory data,\\n uint256 maxLen\\n ) internal {\\n bool success = call(to, 0, data, gasleft());\\n if (!success) {\\n revertWithData(getReturnData(maxLen));\\n }\\n }\\n}\\n\"\n },\n \"contracts/Barz.sol\": {\n \"content\": \"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {LibDiamond} from \\\"./libraries/LibDiamond.sol\\\";\\nimport {IBarz} from \\\"./interfaces/IBarz.sol\\\";\\n\\n/**\\n * @title Barz\\n * @dev A diamond proxy wallet with a modular & upgradeable architecture\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract Barz is IBarz {\\n /**\\n * @notice Initializes Barz with the given parameters. Barz account is intended to be created from Barz Factory for stable deployment.\\n * @dev This method makes a delegate call to account facet and account facet handles the initialization.\\n * With modular architecture, Barz encompasses wide spectrum of architecture and logic.\\n * The only requirement is account facet to comply with initialize() interface.\\n * Barz doesn't include built-in functions and is a full proxy, for maximum extensibility and modularity.\\n * @param _accountFacet Address of Account Facet in charge of the Barz initialization\\n * @param _verificationFacet Address of Verification Facet for verifying the signature. Could be any signature scheme\\n * @param _entryPoint Address of Entry Point contract\\n * @param _facetRegistry Address of Facet Registry. Facet Registry is a registry holding trusted facets that could be added to user's wallet\\n * @param _defaultFallBack Address of Default FallBack Handler. Middleware contract for more efficient deployment\\n * @param _ownerPublicKey Bytes of Owner Public Key using for initialization\\n */\\n constructor(\\n address _accountFacet,\\n address _verificationFacet,\\n address _entryPoint,\\n address _facetRegistry,\\n address _defaultFallBack,\\n bytes memory _ownerPublicKey\\n ) payable {\\n bytes memory initCall = abi.encodeWithSignature(\\n \\\"initialize(address,address,address,address,bytes)\\\",\\n _verificationFacet,\\n _entryPoint,\\n _facetRegistry,\\n _defaultFallBack,\\n _ownerPublicKey\\n );\\n (bool success, bytes memory result) = _accountFacet.delegatecall(\\n initCall\\n );\\n if (!success || uint256(bytes32(result)) != 1) {\\n revert Barz__InitializationFailure();\\n }\\n }\\n\\n /**\\n * @notice Fallback function for Barz complying with Diamond Standard with customization of adding Default Fallback Handler\\n * @dev Find facet for function that is called and execute the function if a facet is found and return any value.\\n */\\n fallback() external payable {\\n LibDiamond.DiamondStorage storage ds;\\n bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION;\\n // get diamond storage\\n assembly {\\n ds.slot := position\\n }\\n // get facet from function selector\\n address facet = address(bytes20(ds.facets[msg.sig]));\\n if (facet == address(0))\\n facet = ds.defaultFallbackHandler.facetAddress(msg.sig);\\n require(facet != address(0), \\\"Barz: Function does not exist\\\");\\n // Execute external function from facet using delegatecall and return any value.\\n assembly {\\n // copy function selector and any arguments\\n calldatacopy(0, 0, calldatasize())\\n // execute function call using the facet\\n let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)\\n // get any return value\\n returndatacopy(0, 0, returndatasize())\\n // return any return value or error back to the caller\\n switch result\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @notice Receive function to receive native token without data\\n */\\n receive() external payable {}\\n}\\n\"\n },\n \"contracts/BarzFactory.sol\": {\n \"content\": \"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {Barz} from \\\"./Barz.sol\\\";\\nimport {IBarzFactory} from \\\"./interfaces/IBarzFactory.sol\\\";\\n\\n/**\\n * @title Barz Factory\\n * @dev Contract to easily deploy Barz to a pre-computed address with a single call\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract BarzFactory is IBarzFactory {\\n address public immutable accountFacet;\\n address public immutable entryPoint;\\n address public immutable facetRegistry;\\n address public immutable defaultFallback;\\n\\n /**\\n * @notice Sets the initialization data for Barz contract initialization\\n * @param _accountFacet Account Facet to be used to create Barz\\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\\n * @param _facetRegistry Facet Registry to be used to create Barz\\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\\n */\\n constructor(\\n address _accountFacet,\\n address _entryPoint,\\n address _facetRegistry,\\n address _defaultFallback\\n ) {\\n accountFacet = _accountFacet;\\n entryPoint = _entryPoint;\\n facetRegistry = _facetRegistry;\\n defaultFallback = _defaultFallback;\\n }\\n\\n /**\\n * @notice Creates the Barz with a single call. It creates the Barz contract with the givent verification facet\\n * @param _verificationFacet Address of verification facet used for creating the barz account\\n * @param _owner Public Key of the owner to initialize barz account\\n * @param _salt Salt used for deploying barz with create2\\n * @return barz Instance of Barz contract deployed with the given parameters\\n */\\n function createAccount(\\n address _verificationFacet,\\n bytes calldata _owner,\\n uint256 _salt\\n ) external override returns (Barz barz) {\\n address addr = getAddress(_verificationFacet, _owner, _salt);\\n uint codeSize = addr.code.length;\\n if (codeSize > 0) {\\n return Barz(payable(addr));\\n }\\n barz = new Barz{salt: bytes32(_salt)}(\\n accountFacet,\\n _verificationFacet,\\n entryPoint,\\n facetRegistry,\\n defaultFallback,\\n _owner\\n );\\n emit BarzDeployed(address(barz));\\n }\\n\\n /**\\n * @notice Calculates the address of Barz with the given parameters\\n * @param _verificationFacet Address of verification facet used for creating the barz account\\n * @param _owner Public Key of the owner to initialize barz account\\n * @param _salt Salt used for deploying barz with create2\\n * @return barzAddress Precalculated Barz address\\n */\\n function getAddress(\\n address _verificationFacet,\\n bytes calldata _owner,\\n uint256 _salt\\n ) public view override returns (address barzAddress) {\\n bytes memory bytecode = getBytecode(\\n accountFacet,\\n _verificationFacet,\\n entryPoint,\\n facetRegistry,\\n defaultFallback,\\n _owner\\n );\\n bytes32 hash = keccak256(\\n abi.encodePacked(\\n bytes1(0xff),\\n address(this),\\n _salt,\\n keccak256(bytecode)\\n )\\n );\\n barzAddress = address(uint160(uint256(hash)));\\n }\\n\\n /**\\n * @notice Returns the bytecode of Barz with the given parameter\\n * @param _accountFacet Account Facet to be used to create Barz\\n * @param _verificationFacet Verification Facet to be used to create Barz\\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\\n * @param _facetRegistry Facet Registry to be used to create Barz\\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\\n * @param _ownerPublicKey Public Key of owner to be used to initialize Barz ownership\\n * @return barzBytecode Bytecode of Barz\\n */\\n function getBytecode(\\n address _accountFacet,\\n address _verificationFacet,\\n address _entryPoint,\\n address _facetRegistry,\\n address _defaultFallback,\\n bytes calldata _ownerPublicKey\\n ) public pure override returns (bytes memory barzBytecode) {\\n bytes memory bytecode = type(Barz).creationCode;\\n barzBytecode = abi.encodePacked(\\n bytecode,\\n abi.encode(\\n _accountFacet,\\n _verificationFacet,\\n _entryPoint,\\n _facetRegistry,\\n _defaultFallback,\\n _ownerPublicKey\\n )\\n );\\n }\\n\\n /**\\n * @notice Returns the creation code of the Barz contract\\n * @return creationCode Creation code of Barz\\n */\\n function getCreationCode()\\n public\\n pure\\n override\\n returns (bytes memory creationCode)\\n {\\n creationCode = type(Barz).creationCode;\\n }\\n}\\n\"\n },\n \"contracts/facets/AccountFacet.sol\": {\n \"content\": \"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {ECDSA} from \\\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\\\";\\nimport {UserOperation} from \\\"../aa-4337/interfaces/UserOperation.sol\\\";\\nimport {IEntryPoint} from \\\"../aa-4337/interfaces/IEntryPoint.sol\\\";\\nimport {BaseAccount} from \\\"../aa-4337/core/BaseAccount.sol\\\";\\nimport {LibAppStorage, BarzStorage} from \\\"../libraries/LibAppStorage.sol\\\";\\nimport {LibDiamond} from \\\"../libraries/LibDiamond.sol\\\";\\nimport {LibLoupe} from \\\"../libraries/LibLoupe.sol\\\";\\nimport {IFacetRegistry} from \\\"../infrastructure/interfaces/IFacetRegistry.sol\\\";\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\nimport {IVerificationFacet} from \\\"./interfaces/IVerificationFacet.sol\\\";\\nimport {IERC1271} from \\\"../interfaces/ERC/IERC1271.sol\\\";\\nimport {IAccountFacet} from \\\"./interfaces/IAccountFacet.sol\\\";\\n\\n/**\\n * @title Account Facet\\n * @dev Account module contract that provides the account features and initialization of signer\\n * compatible with EIP-1271 & EIP-4337\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract AccountFacet is IAccountFacet, BarzStorage, BaseAccount {\\n using ECDSA for bytes32;\\n\\n /**\\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\\n */\\n constructor() {\\n LibAppStorage.enforceAccountInitialize();\\n }\\n\\n /**\\n * @notice Returns the address of EntryPoint contract registered to Barz account\\n */\\n function entryPoint() public view override returns (IEntryPoint) {\\n return s.entryPoint;\\n }\\n\\n /**\\n * @notice Initializes the initial storage of the Barz contract.\\n * @dev This method can only be called during the initialization or signature migration.\\n * If the proxy contract was created without initialization, anyone can call initialize.\\n * Barz calls initialize in constructor in an atomic transaction during deployment\\n * @param _verificationFacet Facet contract handling the verificationi\\n * @param _anEntryPoint Entrypoint contract defined in EIP-4337 handling the flow of UserOp\\n * @param _facetRegistry Registry of Facets that hold all facet information\\n * @param _defaultFallBackHandler Middleware contract for default facets\\n * @param _ownerPublicKey Bytes of owner public key\\n */\\n function initialize(\\n address _verificationFacet,\\n address _anEntryPoint,\\n address _facetRegistry,\\n address _defaultFallBackHandler,\\n bytes calldata _ownerPublicKey\\n ) public override returns (uint256 initSuccess) {\\n LibAppStorage.enforceAccountInitialize();\\n s.entryPoint = IEntryPoint(_anEntryPoint);\\n s.facetRegistry = IFacetRegistry(_facetRegistry);\\n LibDiamond.diamondStorage().defaultFallbackHandler = IDiamondLoupe(\\n _defaultFallBackHandler\\n );\\n\\n _cutDiamondAccountFacet(_verificationFacet);\\n\\n bytes memory initCall = abi.encodeWithSignature(\\n \\\"initializeSigner(bytes)\\\",\\n _ownerPublicKey\\n );\\n // Every Verification Facet should comply with initializeSigner(bytes)\\n // to be compatible with the Barz contract(for initialization)\\n (bool success, bytes memory result) = _verificationFacet.delegatecall(\\n initCall\\n );\\n if (!success || uint256(bytes32(result)) != 1) {\\n revert AccountFacet__InitializationFailure();\\n }\\n\\n initSuccess = 1;\\n emit AccountInitialized(s.entryPoint, _ownerPublicKey);\\n }\\n\\n function _cutDiamondAccountFacet(address _verificationFacet) internal {\\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](1);\\n\\n bytes4 ownerVerificationFuncSelector = IVerificationFacet(\\n _verificationFacet\\n ).validateOwnerSignatureSelector();\\n\\n bytes4[] memory verificationFunctionSelectors = new bytes4[](3);\\n verificationFunctionSelectors[0] = IERC1271.isValidSignature.selector;\\n verificationFunctionSelectors[1] = ownerVerificationFuncSelector;\\n verificationFunctionSelectors[2] = IVerificationFacet.owner.selector;\\n cut[0] = IDiamondCut.FacetCut({\\n facetAddress: _verificationFacet,\\n action: IDiamondCut.FacetCutAction.Add,\\n functionSelectors: verificationFunctionSelectors\\n });\\n\\n LibDiamond.diamondCut(cut, address(0), \\\"\\\");\\n }\\n\\n /**\\n * @notice Calls the destination with inputted calldata and value from EntryPoint\\n * @dev This method executes the calldata coming from the EntryPoint.\\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\\n * @param _dest Address of destination where the call will be forwarded to\\n * @param _value Amount of native coin the owner is willing to send(e.g. ETH, BNB)\\n * @param _func Bytes of calldata to execute in the destination address\\n */\\n function execute(\\n address _dest,\\n uint256 _value,\\n bytes calldata _func\\n ) external override onlyWhenUnlocked {\\n _requireFromEntryPoint();\\n address restrictionsFacet = LibDiamond.restrictionsFacet();\\n if (restrictionsFacet == address(0)) _call(_dest, _value, _func);\\n else _callWithRestrictions(_dest, _value, _func, restrictionsFacet);\\n }\\n\\n /**\\n * @notice Batch calls the destination with inputted calldata and value from EntryPoint\\n * @dev This method batch executes the calldata coming from the EntryPoint.\\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\\n * @param _dest Array of addresses of destination where the call will be forwarded to\\n * @param _value Array of amount of native coin the owner is willing to send(e.g. ETH, BNB)\\n * @param _func Array of bytes of calldata to execute in the destination address\\n */\\n function executeBatch(\\n address[] calldata _dest,\\n uint256[] calldata _value,\\n bytes[] calldata _func\\n ) external override onlyWhenUnlocked {\\n _requireFromEntryPoint();\\n if (_dest.length != _func.length || _dest.length != _value.length)\\n revert AccountFacet__InvalidArrayLength();\\n address restrictionsFacet = LibDiamond.restrictionsFacet();\\n if (restrictionsFacet == address(0)) {\\n for (uint256 i; i < _dest.length; ) {\\n _call(_dest[i], _value[i], _func[i]);\\n unchecked {\\n ++i;\\n }\\n }\\n } else {\\n for (uint256 i; i < _dest.length; ) {\\n _callWithRestrictions(\\n _dest[i],\\n _value[i],\\n _func[i],\\n restrictionsFacet\\n );\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n }\\n\\n /**\\n * @notice Validates the signature field of UserOperation\\n * @dev This method validates if the signature of UserOp is indeed valid by delegating the call to Verification Facet\\n * Barz makes a call to the pre-registered Verification Facet address in App Storage\\n * @param _userOp UserOperation from owner to be validated\\n * @param _userOpHash Hash of UserOperation given from the EntryPoint contract\\n */\\n function _validateSignature(\\n UserOperation calldata _userOp,\\n bytes32 _userOpHash\\n ) internal override returns (uint256 validationData) {\\n // Get Facet with Function Selector\\n address facet = LibLoupe.facetAddress(s.validateOwnerSignatureSelector);\\n if (facet == address(0))\\n revert AccountFacet__NonExistentVerificationFacet();\\n\\n // Make function call to VerificationFacet\\n bytes memory validateCall = abi.encodeWithSelector(\\n s.validateOwnerSignatureSelector,\\n _userOp,\\n _userOpHash\\n );\\n (bool success, bytes memory result) = facet.delegatecall(validateCall);\\n if (!success) revert AccountFacet__CallNotSuccessful();\\n validationData = uint256(bytes32(result));\\n if (validationData == 0) emit VerificationSuccess(_userOpHash);\\n else emit VerificationFailure(_userOpHash);\\n }\\n\\n /**\\n * @notice Calls the target with the inputted value and calldata\\n * @dev This method is the actual function in Barz that makes a call with an arbitrary owner-given data\\n * @param _target Address of the destination contract which the call is getting forwarded to\\n * @param _value Amount of Native coin the owner is wanting to make in this call\\n * @param _data Calldata the owner is forwarding together in the call e.g. Swap/Token Transfer\\n */\\n function _call(\\n address _target,\\n uint256 _value,\\n bytes memory _data\\n ) internal {\\n (bool success, bytes memory result) = _target.call{value: _value}(\\n _data\\n );\\n if (!success) {\\n assembly {\\n revert(add(result, 32), mload(result))\\n }\\n }\\n }\\n\\n /**\\n * @notice Calls the target with the inputted value and calldata together with restrictions check\\n * @dev This method is the actual function in Barz that makes a call with an arbitrary owner-given data\\n * @param _target Address of the destination contract which the call is getting forwarded to\\n * @param _value Amount of Native coin the owner is wanting to make in this call\\n * @param _data Calldata the owner is forwarding together in the call e.g. Swap/Token Transfer\\n * @param _restrictionsFacet Address of Facet to validate restrictions\\n */\\n function _callWithRestrictions(\\n address _target,\\n uint256 _value,\\n bytes memory _data,\\n address _restrictionsFacet\\n ) internal {\\n // NOTE: No restrictions facet, so restriction validation passes\\n if (_checkRestrictions(_restrictionsFacet, _target, _value, _data) != 0)\\n revert AccountFacet__RestrictionsFailure();\\n\\n (bool success, bytes memory result) = _target.call{value: _value}(\\n _data\\n );\\n if (!success) {\\n assembly {\\n revert(add(result, 32), mload(result))\\n }\\n }\\n }\\n\\n /**\\n * @notice Checks restrictions if the restrictions facet exists\\n * @dev This method checks if the restrictions facet exists and makes a verification call to an array of restrictions facet\\n * @param _facet Address that holds the restrictions logic\\n * @param _target Address the call is getting forwarded to\\n * @param _value Amount of native coin the call is sending together with the call\\n * @param _data Calldata to trigger execution in target address\\n */\\n function _checkRestrictions(\\n address _facet,\\n address _target,\\n uint256 _value,\\n bytes memory _data\\n ) internal returns (uint256 result) {\\n bytes memory call = abi.encodeWithSignature(\\n \\\"verifyRestrictions(address,address,uint256,bytes)\\\",\\n address(this),\\n _target,\\n _value,\\n _data\\n );\\n (bool success, bytes memory response) = _facet.delegatecall(call);\\n if (!success) revert AccountFacet__RestrictionsFailure();\\n result = uint256(bytes32(response));\\n }\\n}\\n\"\n },\n \"contracts/facets/AccountRecoveryFacet.sol\": {\n \"content\": \"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {SignatureChecker} from \\\"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\\\";\\nimport {LibAppStorage} from \\\"../libraries/LibAppStorage.sol\\\";\\nimport {LibDiamond} from \\\"../libraries/LibDiamond.sol\\\";\\nimport {LibLoupe} from \\\"../libraries/LibLoupe.sol\\\";\\nimport {LibGuardian} from \\\"../libraries/LibGuardian.sol\\\";\\nimport {LibFacetStorage, RecoveryStorage, RecoveryConfig, RecoveryApprovalConfig, ApprovalConfig} from \\\"../libraries/LibFacetStorage.sol\\\";\\nimport {Modifiers} from \\\"./Modifiers.sol\\\";\\nimport {ISecurityManager} from \\\"../infrastructure/interfaces/ISecurityManager.sol\\\";\\nimport {IVerificationFacet} from \\\"./interfaces/IVerificationFacet.sol\\\";\\nimport {IAccountRecoveryFacet} from \\\"./interfaces/IAccountRecoveryFacet.sol\\\";\\n\\n/**\\n * @title Account Recovery Facet\\n * @dev Contract that enables recovery of accounts when owner key is unavailable\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract AccountRecoveryFacet is IAccountRecoveryFacet, Modifiers {\\n bytes constant UNINIT_CALL =\\n abi.encodeWithSignature(\\\"uninitializeSigner()\\\");\\n ISecurityManager public immutable securityManager;\\n\\n /**\\n * @notice This constructor sets the Security Manager address which is an immutable variable.\\n * Immutable variables do not impact the storage of diamond\\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\\n */\\n constructor(address _securityManager) {\\n securityManager = ISecurityManager(_securityManager);\\n }\\n\\n /**\\n * @notice Approve recovery of account as guardian\\n * @dev This method can only be called by guardian and guardian inputs the public key of the new owner\\n * When the threshold(majority of guardians) passes, it automatically executes account recovery\\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\\n */\\n function approveAccountRecovery(\\n bytes calldata _recoveryPublicKey\\n ) external override onlyGuardian {\\n RecoveryApprovalConfig storage rs = LibFacetStorage\\n .recoveryStorage()\\n .recoveryApprovalConfigs[INNER_STRUCT];\\n validateNewOwner(_recoveryPublicKey);\\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\\n _recoveryPublicKey,\\n \\\"ExecuteRecovery\\\"\\n );\\n uint64 approvalValidUntil = uint64(\\n block.timestamp + _getApprovalValidationPeriod()\\n );\\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\\n msg.sender\\n ] = ApprovalConfig(true, approvalValidUntil);\\n emit RecoveryApproved(\\n _recoveryPublicKey,\\n msg.sender,\\n approvalValidUntil\\n );\\n if (\\n getRecoveryApprovalCountWithTimeValidity(recoveryPublicKeyHash) >=\\n LibGuardian.majorityOfGuardians()\\n ) _executeRecovery(_recoveryPublicKey);\\n }\\n\\n /**\\n * @notice Revoke recovery of account as guardian\\n * @dev This method can only be called by guardian and guardian inputs the public key of the new owner\\n When the threshold(majority of guardians) passes, it automatically revokes account recovery when recovery is pending\\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\\n */\\n function revokeAccountRecoveryApproval(\\n bytes calldata _recoveryPublicKey\\n ) external override onlyGuardian {\\n RecoveryApprovalConfig storage rs = LibFacetStorage\\n .recoveryStorage()\\n .recoveryApprovalConfigs[INNER_STRUCT];\\n validateNewOwner(_recoveryPublicKey);\\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\\n _recoveryPublicKey,\\n \\\"ExecuteRecovery\\\"\\n );\\n if (\\n !rs\\n .isNewOwnerApproved[recoveryPublicKeyHash][msg.sender].isApproved ||\\n !(block.timestamp <\\n rs\\n .isNewOwnerApproved[recoveryPublicKeyHash][msg.sender]\\n .validUntil)\\n ) revert AccountRecoveryFacet__NonExistentApproval();\\n\\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\\n msg.sender\\n ] = ApprovalConfig(false, 0);\\n emit RecoveryApprovalRevoked(_recoveryPublicKey, msg.sender);\\n }\\n\\n /**\\n * @notice Executes recovery with signatures or on-chain pre-approvals\\n * @dev This method validates the signatures of guardians or checks the on-chain pre-approved calls to check if the threshold passes\\n * When the threshold passes, account recovery is executed and revert otherwise\\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\\n * @param _guardians Array of guardians address that are approving the recovery of Account\\n * @param _signatures Array of signature bytes that signed the approval hash\\n */\\n function executeRecovery(\\n bytes calldata _recoveryPublicKey,\\n address[] calldata _guardians,\\n bytes[] calldata _signatures\\n ) external override {\\n if (_isRecoveryPending())\\n revert AccountRecoveryFacet__RecoveryAlreadyOngoing();\\n if (_guardians.length != _signatures.length)\\n revert AccountRecoveryFacet__InvalidArrayLength();\\n validateNewOwner(_recoveryPublicKey);\\n\\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\\n _recoveryPublicKey,\\n \\\"ExecuteRecovery\\\"\\n );\\n\\n _checkApprover(_guardians);\\n _checkDuplicateOnChainApprover(recoveryPublicKeyHash, _guardians);\\n\\n if (\\n _guardians.length +\\n getRecoveryApprovalCountWithTimeValidity(\\n recoveryPublicKeyHash\\n ) <\\n LibGuardian.majorityOfGuardians()\\n ) revert AccountRecoveryFacet__InsufficientGuardians();\\n for (uint256 i; i < _guardians.length; ) {\\n if (!LibGuardian.isGuardian(_guardians[i]))\\n revert AccountRecoveryFacet__InvalidGuardian();\\n if (\\n !SignatureChecker.isValidSignatureNow(\\n _guardians[i],\\n recoveryPublicKeyHash,\\n _signatures[i]\\n )\\n ) revert AccountRecoveryFacet__InvalidGuardianSignature();\\n unchecked {\\n ++i;\\n }\\n }\\n _executeRecovery(_recoveryPublicKey);\\n }\\n\\n /**\\n * @notice Executes recovery of the account. Note that execution and finalization is a different process\\n * @dev Executes the recovery and adds recovery data to recovery configuration. Locks the account\\n * @param _recoveryPublicKey Public Key of the account for recovery\\n */\\n function _executeRecovery(bytes memory _recoveryPublicKey) internal {\\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\\n unchecked {\\n ++rs.nonce;\\n }\\n uint64 executeAfter = uint64(block.timestamp + _getRecoveryPeriod());\\n rs.recoveryConfigs[INNER_STRUCT] = RecoveryConfig(\\n _recoveryPublicKey,\\n executeAfter // NOTE: Remove guardian Count\\n );\\n LibAppStorage.setLock(\\n block.timestamp + _getLockPeriod(),\\n AccountRecoveryFacet.executeRecovery.selector\\n );\\n emit RecoveryExecuted(_recoveryPublicKey, executeAfter);\\n }\\n\\n /**\\n * @notice Finalize recovery after recovery pending period. Recovery pending period can be set by user beforehand in SecurityManager\\n * @dev This method finalizes recovery and fully changes the ownership of the account to the newly inputted recovery public key\\n */\\n function finalizeRecovery() external override {\\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\\n\\n if (!_isRecoveryPending())\\n revert AccountRecoveryFacet__NonexistentRecovery();\\n if (\\n uint64(block.timestamp) <=\\n rs.recoveryConfigs[INNER_STRUCT].executeAfter\\n ) revert AccountRecoveryFacet__RecoveryPeriodNotOver();\\n bytes memory recoveryOwner = rs\\n .recoveryConfigs[INNER_STRUCT]\\n .recoveryPublicKey;\\n\\n delete rs.recoveryConfigs[INNER_STRUCT];\\n\\n LibAppStorage.setLock(0, bytes4(0));\\n\\n LibAppStorage.initiateSignerMigration();\\n address verificationFacet = address(\\n bytes20(\\n LibDiamond.diamondStorage().facets[\\n s.validateOwnerSignatureSelector\\n ]\\n )\\n );\\n (bool uninitSuccess, bytes memory uninitResult) = verificationFacet\\n .delegatecall(UNINIT_CALL);\\n if (!uninitSuccess) revert AccountRecoveryFacet__CallNotSuccesful();\\n if (uint256(bytes32(uninitResult)) != 1)\\n revert AccountRecoveryFacet__SignerUninitializationFailure();\\n bytes memory initCall = abi.encodeWithSignature(\\n \\\"initializeSigner(bytes)\\\",\\n recoveryOwner\\n );\\n (bool initSuccess, bytes memory initResult) = verificationFacet\\n .delegatecall(initCall);\\n if (!initSuccess) revert AccountRecoveryFacet__CallNotSuccesful();\\n if (uint256(bytes32(initResult)) != 1)\\n revert AccountRecoveryFacet__SignerInitializationFailure();\\n LibAppStorage.finalizeSignerMigration();\\n emit RecoveryFinalized(recoveryOwner);\\n }\\n\\n /**\\n * @notice Approves the cancellation of recovery\\n * @dev This method approves the cancellation of recovery when recovery is still pending - waiting for finalization\\n * @param _recoveryPublicKey Bytes of public key which is pending for recovery\\n */\\n function approveCancelRecovery(\\n bytes calldata _recoveryPublicKey\\n ) external override onlyGuardian {\\n RecoveryApprovalConfig storage rs = LibFacetStorage\\n .recoveryStorage()\\n .recoveryApprovalConfigs[INNER_STRUCT];\\n validateNewOwner(_recoveryPublicKey);\\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\\n _recoveryPublicKey,\\n \\\"CancelRecovery\\\"\\n );\\n uint64 approvalValidUntil = uint64(\\n block.timestamp + _getApprovalValidationPeriod()\\n );\\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\\n msg.sender\\n ] = ApprovalConfig(true, approvalValidUntil);\\n emit RecoveryCancellationApproved(_recoveryPublicKey, msg.sender);\\n if (\\n getRecoveryApprovalCountWithTimeValidity(recoveryPublicKeyHash) >=\\n LibGuardian.majorityOfGuardians()\\n ) {\\n _cancelRecovery(_recoveryPublicKey);\\n }\\n }\\n\\n /**\\n * @notice Hardstops an ongoing recovery\\n * @dev This method provides a safety mechanism to protect owners of malicious guardians.\\n * Owners can hardstop recovery when an malicious guardians starts the recovery process.\\n * @param _signature Signature of the owner that signs the hash to hardstop recovery\\n */\\n function hardstopRecovery(bytes calldata _signature) external override {\\n if (!_isRecoveryPending())\\n revert AccountRecoveryFacet__NonexistentRecovery();\\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\\n \\\"0\\\",\\n \\\"HardstopRecovery\\\"\\n );\\n if (\\n !SignatureChecker.isValidSignatureNow(\\n address(this),\\n recoveryPublicKeyHash,\\n _signature\\n )\\n ) revert AccountRecoveryFacet__InvalidOwnerSignature();\\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\\n unchecked {\\n ++rs.nonce;\\n }\\n delete rs.recoveryConfigs[INNER_STRUCT];\\n LibAppStorage.setLock(0, bytes4(0));\\n emit RecoveryHardstopped();\\n }\\n\\n /**\\n * @notice Cancels recovery with signatures or on-chain pre-approvals\\n * @dev This method validates the signatures of guardians or checks the on-chain pre-approved calls to check if the threshold passes\\n * When the threshold passes, account recovery is canceled and revert otherwise\\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\\n * @param _guardians Array of guardians address that are approving the recovery of Account\\n * @param _signatures Array of signature bytes that signed the cancellation approval hash\\n */\\n function cancelRecovery(\\n bytes calldata _recoveryPublicKey,\\n address[] calldata _guardians,\\n bytes[] calldata _signatures\\n ) external override {\\n if (_guardians.length != _signatures.length)\\n revert AccountRecoveryFacet__InvalidArrayLength();\\n validateNewOwner(_recoveryPublicKey);\\n\\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\\n _recoveryPublicKey,\\n \\\"CancelRecovery\\\"\\n );\\n\\n _checkApprover(_guardians);\\n _checkDuplicateOnChainApprover(recoveryPublicKeyHash, _guardians);\\n\\n if (\\n _guardians.length +\\n getRecoveryApprovalCountWithTimeValidity(\\n recoveryPublicKeyHash\\n ) <\\n LibGuardian.majorityOfGuardians()\\n ) revert AccountRecoveryFacet__InsufficientGuardians();\\n for (uint256 i; i < _guardians.length; ) {\\n if (!LibGuardian.isGuardian(_guardians[i]))\\n revert AccountRecoveryFacet__CallerNotGuardian();\\n if (\\n !SignatureChecker.isValidSignatureNow(\\n _guardians[i],\\n recoveryPublicKeyHash,\\n _signatures[i]\\n )\\n ) revert AccountRecoveryFacet__InvalidGuardianSignature();\\n unchecked {\\n ++i;\\n }\\n }\\n _cancelRecovery(_recoveryPublicKey);\\n }\\n\\n /**\\n * @notice Cancel recovery when the recovery is pending. Unlock the account as well\\n * @dev This method checks if the recovery is pending and reverts if not pending.\\n * It increases the recovery nonce and deletes the recovery information and gets a small portion of gas in return\\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\\n */\\n function _cancelRecovery(bytes memory _recoveryPublicKey) internal {\\n if (!_isRecoveryPending())\\n revert AccountRecoveryFacet__NonexistentRecovery();\\n LibAppStorage.setLock(0, bytes4(0));\\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\\n unchecked {\\n ++rs.nonce;\\n }\\n delete rs.recoveryConfigs[INNER_STRUCT];\\n emit RecoveryCanceled(_recoveryPublicKey);\\n }\\n\\n /**\\n * @notice Validates the format of public key to be used for recovery\\n * @dev This method checks if the public key format is correct and reverts otherwise\\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\\n */\\n function validateNewOwner(\\n bytes calldata _recoveryPublicKey\\n ) public view override {\\n if (\\n !IVerificationFacet(\\n LibLoupe.facetAddress(s.validateOwnerSignatureSelector)\\n ).isValidKeyType(_recoveryPublicKey)\\n ) revert AccountRecoveryFacet__InvalidRecoveryPublicKey();\\n }\\n\\n /**\\n * @notice Checks if recovery is currently pending\\n * @return isPending Boolean indicating if recovery is pending\\n */\\n function _isRecoveryPending() internal view returns (bool isPending) {\\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\\n isPending = (rs.recoveryConfigs[INNER_STRUCT].executeAfter > 0);\\n }\\n\\n /**\\n * @notice Calculate the recovery hash dependent on chain, wallet address, nonce with EIP-191 prefix for safety\\n * @dev Returns the keccak256 hash of EIP-191 msg hash packed with public key, salt, nonce, wallet address, etc\\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\\n * @param _saltString Salt string to uniquely identify each recovery hash and for security\\n * @return recoveryKeyHash Bytes32 string of the recovery hash\\n */\\n function getApprovalRecoveryKeyHash(\\n bytes memory _recoveryPublicKey,\\n string memory _saltString\\n ) public view override returns (bytes32 recoveryKeyHash) {\\n recoveryKeyHash = keccak256(\\n abi.encodePacked(\\n \\\"\\\\x19Ethereum Signed Message:\\\\n32\\\",\\n keccak256(\\n abi.encode(\\n _recoveryPublicKey,\\n _saltString,\\n address(this),\\n block.chainid,\\n LibFacetStorage.recoveryStorage().nonce\\n )\\n )\\n )\\n );\\n }\\n\\n /**\\n * @notice Check the onchain approval of guardians and returns the number of guardians that approved\\n * @dev Loop through the guardian addresses and returns the number of guardians that approved this recovery hash\\n * @param _recoveryPublicKeyHash Bytes hash of newly recovered public key and recovery value of the account\\n * @return approvalCount Number of guardians that approved\\n */\\n function getRecoveryApprovalCountWithTimeValidity(\\n bytes32 _recoveryPublicKeyHash\\n ) public view override returns (uint256 approvalCount) {\\n address[] memory guardians = LibGuardian.getGuardians();\\n uint256 guardianLength = guardians.length;\\n for (uint256 i; i < guardianLength; ) {\\n if (isRecoveryApproved(_recoveryPublicKeyHash, guardians[i])) {\\n unchecked {\\n ++approvalCount;\\n }\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * @notice Checks if the recovery is approved by the given approver\\n * @param _recoveryPublicKeyHash Hash of the public key and configuration for recovery\\n * @param _approver Address of approver\\n * @return isApproved Bool value if recovery hash is approved\\n */\\n function isRecoveryApproved(\\n bytes32 _recoveryPublicKeyHash,\\n address _approver\\n ) public view override returns (bool isApproved) {\\n RecoveryApprovalConfig storage rs = LibFacetStorage\\n .recoveryStorage()\\n .recoveryApprovalConfigs[INNER_STRUCT];\\n if (\\n rs\\n .isNewOwnerApproved[_recoveryPublicKeyHash][_approver].isApproved &&\\n block.timestamp <\\n rs.isNewOwnerApproved[_recoveryPublicKeyHash][_approver].validUntil\\n ) {\\n isApproved = true;\\n }\\n }\\n\\n /**\\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\\n * Approvers who approved on-chain should not be included in the off-chain approval\\n * @param _recoveryPublicKeyHash Hash of recovery information\\n * @param _approvers List of approver addresses\\n */\\n function _checkDuplicateOnChainApprover(\\n bytes32 _recoveryPublicKeyHash,\\n address[] memory _approvers\\n ) public view {\\n address[] memory guardians = LibGuardian.getGuardians();\\n uint256 guardianLength = guardians.length;\\n uint256 approversLength = _approvers.length;\\n for (uint256 i; i < guardianLength; ) {\\n if (isRecoveryApproved(_recoveryPublicKeyHash, guardians[i])) {\\n for (uint256 j; j < approversLength; ) {\\n if (_approvers[j] == guardians[i])\\n revert AccountRecoveryFacet__DuplicateApproval();\\n unchecked {\\n ++j;\\n }\\n }\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * @notice Returns the lock period of this wallet address from security manager\\n * @return lockPeriod value of lock period\\n */\\n function _getLockPeriod() internal view returns (uint256 lockPeriod) {\\n lockPeriod = securityManager.lockPeriodOf(address(this));\\n if (lockPeriod == 0) revert AccountRecoveryFacet__InvalidLockPeriod();\\n }\\n\\n /**\\n * @notice Returns the lock period of this wallet address from security manager\\n * @return recoveryPeriod value of recovery period\\n */\\n function _getRecoveryPeriod()\\n internal\\n view\\n returns (uint256 recoveryPeriod)\\n {\\n recoveryPeriod = securityManager.recoveryPeriodOf(address(this));\\n if (recoveryPeriod == 0)\\n revert AccountRecoveryFacet__InvalidRecoveryPeriod();\\n }\\n\\n /**\\n * @notice Returns the approval validation period of this wallet address from security manager\\n * @return approvalValidationPeriod value of approval validation period\\n */\\n function _getApprovalValidationPeriod()\\n internal\\n view\\n returns (uint256 approvalValidationPeriod)\\n {\\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\\n address(this)\\n );\\n if (approvalValidationPeriod == 0)\\n revert AccountRecoveryFacet__InvalidApprovalValidationPeriod();\\n }\\n\\n /**\\n * @notice Returns the recovery nonce of this wallet address from security manager\\n * @return nonce value of recovery nonce\\n */\\n function getRecoveryNonce() public view override returns (uint128 nonce) {\\n nonce = LibFacetStorage.recoveryStorage().nonce;\\n }\\n\\n /**\\n * @notice Returns the recovery information of the pending recovery\\n * @return recoveryConfig value struct of pending recovery\\n */\\n function getPendingRecovery()\\n public\\n view\\n override\\n returns (RecoveryConfig memory recoveryConfig)\\n {\\n recoveryConfig = LibFacetStorage.recoveryStorage().recoveryConfigs[\\n INNER_STRUCT\\n ];\\n }\\n}\\n\"\n },\n \"contracts/facets/base/DiamondCutFacet.sol\": {\n \"content\": \"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {LibDiamond} from \\\"../../libraries/LibDiamond.sol\\\";\\nimport {LibGuardian} from \\\"../../libraries/LibGuardian.sol\\\";\\nimport {ISecurityManager} from \\\"../../infrastructure/interfaces/ISecurityManager.sol\\\";\\nimport {SignatureChecker} from \\\"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\\\";\\nimport {LibFacetStorage, DiamondCutApprovalConfig, ApprovalConfig} from \\\"../../libraries/LibFacetStorage.sol\\\";\\nimport {Modifiers} from \\\"../Modifiers.sol\\\";\\nimport {IDiamondCut} from \\\"./interfaces/IDiamondCut.sol\\\";\\n\\n/**\\n * @title DiamondCut Facet\\n * @dev Responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract DiamondCutFacet is Modifiers, IDiamondCut {\\n ISecurityManager public immutable securityManager;\\n\\n /**\\n * @notice This constructor sets the Security Manager address which is an immutable variable.\\n * Immutable variables do not impact the storage of diamond\\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\\n */\\n constructor(address _securityManager) {\\n securityManager = ISecurityManager(_securityManager);\\n }\\n\\n /**\\n * @notice Updates the flag for the interfaceId\\n * @param _interfaceId InterfaceID to update the mapping\\n * @param _flag Bool value to update the mapping of the given interface ID\\n */\\n function updateSupportsInterface(\\n bytes4 _interfaceId,\\n bool _flag\\n ) external override onlyWhenUnlocked {\\n LibDiamond.enforceIsSelf();\\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId] = _flag;\\n emit SupportsInterfaceUpdated(_interfaceId, _flag);\\n }\\n\\n /**\\n * @notice Add/replace/remove any number of functions and optionally execute\\n * a function with delegatecall when guardians don't exist\\n * @param _diamondCut Contains the facet addresses and function selectors\\n * @param _init The address of the contract or facet to execute _calldata. It's prohibited in Barz\\n */\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata\\n ) external override onlyWhenUnlocked {\\n LibDiamond.enforceIsSelf();\\n\\n _checkFacetCutValidity(_diamondCut);\\n // require approval from guardian if guardian exists\\n if (0 != LibGuardian.guardianCount())\\n revert DiamondCutFacet__InvalidRouteWithGuardian();\\n if (address(0) != _init) revert DiamondCutFacet__InvalidInitAddress();\\n\\n unchecked {\\n ++LibFacetStorage.diamondCutStorage().nonce;\\n }\\n LibDiamond.diamondCut(_diamondCut, address(0), \\\"\\\");\\n }\\n\\n /**\\n * @notice Add/replace/remove any number of functions and optionally execute\\n * a function with delegatecall when guardians exist\\n * @param _diamondCut Contains the facet addresses and function selectors\\n * @param _approvers Guardian or owner address that approves the diamond cut\\n * @param _signatures Signature of Guardians or owner that approves the diamond cut\\n */\\n function diamondCutWithGuardian(\\n FacetCut[] calldata _diamondCut,\\n address[] calldata _approvers,\\n bytes[] calldata _signatures\\n ) external override onlyWhenUnlocked {\\n if (_approvers.length != _signatures.length)\\n revert DiamondCutFacet__InvalidArrayLength();\\n _checkFacetCutValidity(_diamondCut);\\n if (0 == LibGuardian.guardianCount())\\n revert DiamondCutFacet__InvalidRouteWithGuardian();\\n\\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\\n\\n _checkApprover(_approvers);\\n _checkDuplicateOnChainApprover(cutHash, _approvers);\\n\\n bool onChainOwnerApproval = getOwnerCutApprovalWithTimeValidity(\\n cutHash\\n );\\n\\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\\n if (\\n _approvers.length +\\n getDiamondCutApprovalCountWithTimeValidity(cutHash) <\\n LibGuardian.majorityOfGuardians() + threshold\\n ) revert DiamondCutFacet__InsufficientApprovers();\\n\\n bool ownerApproved;\\n for (uint256 i; i < _approvers.length; ) {\\n if (\\n !LibGuardian.isGuardian(_approvers[i]) &&\\n _approvers[i] != address(this)\\n ) revert DiamondCutFacet__InvalidApprover();\\n if (_approvers[i] == address(this)) {\\n if (onChainOwnerApproval)\\n revert DiamondCutFacet__OwnerAlreadyApproved();\\n ownerApproved = true;\\n }\\n if (\\n !SignatureChecker.isValidSignatureNow(\\n _approvers[i],\\n cutHash,\\n _signatures[i]\\n )\\n ) revert DiamondCutFacet__InvalidApproverSignature();\\n unchecked {\\n ++i;\\n }\\n }\\n if (!ownerApproved && !onChainOwnerApproval)\\n revert DiamondCutFacet__LackOfOwnerApproval();\\n\\n unchecked {\\n ++LibFacetStorage.diamondCutStorage().nonce;\\n }\\n LibDiamond.diamondCut(_diamondCut, address(0), \\\"\\\");\\n }\\n\\n /**\\n * @notice Approves diamond cut. This can only be called directly from guardian or owner\\n * @param _diamondCut Contains the facet addresses and function selectors\\n */\\n function approveDiamondCut(\\n FacetCut[] calldata _diamondCut\\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\\n if (LibGuardian.guardianCount() == 0)\\n revert DiamondCutFacet__InvalidRouteWithoutGuardian();\\n DiamondCutApprovalConfig storage ds = LibFacetStorage\\n .diamondCutStorage()\\n .diamondCutApprovalConfigs[INNER_STRUCT];\\n _checkFacetCutValidity(_diamondCut);\\n\\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\\n uint64 approvalValidUntil = uint64(\\n block.timestamp + getApprovalValidationPeriod()\\n );\\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(\\n true,\\n approvalValidUntil\\n );\\n emit DiamondCutApproved(_diamondCut);\\n if (\\n (getDiamondCutApprovalCountWithTimeValidity(cutHash) >=\\n LibGuardian.majorityOfGuardians()) &&\\n getOwnerCutApprovalWithTimeValidity(cutHash)\\n ) {\\n unchecked {\\n ++LibFacetStorage.diamondCutStorage().nonce;\\n }\\n LibDiamond.diamondCut(_diamondCut, address(0), \\\"\\\");\\n }\\n }\\n\\n /**\\n * @notice Revokes the approval of diamond cut. This can only be called directly from guardian or owner\\n * @param _diamondCut Contains the facet addresses and function selectors\\n */\\n function revokeDiamondCutApproval(\\n FacetCut[] calldata _diamondCut\\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\\n DiamondCutApprovalConfig storage ds = LibFacetStorage\\n .diamondCutStorage()\\n .diamondCutApprovalConfigs[INNER_STRUCT];\\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\\n if (!ds.isDiamondCutApproved[cutHash][msg.sender].isApproved)\\n revert DiamondCutFacet__CannotRevokeUnapproved();\\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(false, 0);\\n emit DiamondCutApprovalRevoked(_diamondCut);\\n }\\n\\n /**\\n * @notice Gets the number of approvals of diamond cut from guardians\\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\\n */\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 _diamondCutHash\\n ) public view override returns (uint256 approvalCount) {\\n address[] memory guardians = LibGuardian.getGuardians();\\n uint256 guardiansLength = guardians.length;\\n for (uint256 i; i < guardiansLength; ) {\\n if (isCutApproved(_diamondCutHash, guardians[i])) {\\n unchecked {\\n ++approvalCount;\\n }\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n return approvalCount;\\n }\\n\\n /**\\n * @notice Returns if the owner has approved the diamond cut\\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\\n * @return isApprovedByOwner Bool value showing if the owner approved the cut\\n */\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 _diamondCutHash\\n ) public view override returns (bool isApprovedByOwner) {\\n isApprovedByOwner = isCutApproved(_diamondCutHash, address(this));\\n }\\n\\n /**\\n * @notice Returns if the given approver has approved the diamond cut\\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\\n * @param _approver Address of approver\\n * @return isApproved Bool value showing if the approver approved the cut\\n */\\n function isCutApproved(\\n bytes32 _diamondCutHash,\\n address _approver\\n ) public view override returns (bool isApproved) {\\n DiamondCutApprovalConfig storage ds = LibFacetStorage\\n .diamondCutStorage()\\n .diamondCutApprovalConfigs[INNER_STRUCT];\\n isApproved = (ds\\n .isDiamondCutApproved[_diamondCutHash][_approver].isApproved &&\\n block.timestamp <\\n ds.isDiamondCutApproved[_diamondCutHash][_approver].validUntil);\\n }\\n\\n /**\\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\\n * Approvers who approved on-chain should not be included in the off-chain approval\\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\\n * @param _approvers List of approver addresses\\n */\\n function _checkDuplicateOnChainApprover(\\n bytes32 _diamondCutHash,\\n address[] memory _approvers\\n ) public view {\\n address[] memory guardians = LibGuardian.getGuardians();\\n uint256 guardianLength = guardians.length;\\n uint256 approversLength = _approvers.length;\\n for (uint256 i; i < guardianLength; ) {\\n if (isCutApproved(_diamondCutHash, guardians[i])) {\\n for (uint256 j; j < approversLength; ) {\\n if (_approvers[j] == guardians[i])\\n revert DiamondCutFacet__DuplicateApproval();\\n unchecked {\\n ++j;\\n }\\n }\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * @notice Returns the diamond cut hash. This function ensures that this hash is safe from replay attack by including\\n * salt, address, chainId, and nonce, etc.\\n * @param _diamondCut Contains the facet addresses and function selectors\\n * @return cutHash Diamond Cut Hash\\n */\\n function getDiamondCutHash(\\n FacetCut[] calldata _diamondCut\\n ) public view override returns (bytes32 cutHash) {\\n cutHash = keccak256(\\n abi.encodePacked(\\n \\\"\\\\x19Ethereum Signed Message:\\\\n32\\\",\\n keccak256(\\n abi.encode(\\n keccak256(abi.encode(_diamondCut)),\\n address(this),\\n block.chainid,\\n LibFacetStorage.diamondCutStorage().nonce\\n )\\n )\\n )\\n );\\n }\\n\\n /**\\n * @notice Returns the approval validation Period\\n * @dev This method fetches the validation period from the security manager\\n * @return approvalValidationPeriod Approval validation period of Barz contract fetched from security manager\\n */\\n function getApprovalValidationPeriod()\\n internal\\n view\\n returns (uint256 approvalValidationPeriod)\\n {\\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\\n address(this)\\n );\\n if (approvalValidationPeriod <= 0)\\n revert DiamondCutFacet__InvalidApprovalValidationPeriod();\\n }\\n\\n /**\\n * @notice Returns the diamond cut nonce of this wallet\\n * @dev This method fetches the nonce from diamond cut storage\\n * @return cutNonce Nonce of diamond cut to protect from reply attacks\\n */\\n function getDiamondCutNonce()\\n public\\n view\\n override\\n returns (uint128 cutNonce)\\n {\\n cutNonce = LibFacetStorage.diamondCutStorage().nonce;\\n }\\n}\\n\"\n },\n \"contracts/facets/base/DiamondLoupeFacet.sol\": {\n \"content\": \"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IERC777Recipient} from \\\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\\\";\\nimport {IERC165} from \\\"../../interfaces/ERC/IERC165.sol\\\";\\nimport {IERC1271} from \\\"../../interfaces/ERC/IERC1271.sol\\\";\\nimport {IERC677Receiver} from \\\"../../interfaces/ERC/IERC677Receiver.sol\\\";\\nimport {IERC721Receiver} from \\\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\\\";\\nimport {IERC1155Receiver} from \\\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\\\";\\nimport {LibDiamond} from \\\"../../libraries/LibDiamond.sol\\\";\\nimport {LibLoupe} from \\\"../../libraries/LibLoupe.sol\\\";\\nimport {LibUtils} from \\\"../../libraries/LibUtils.sol\\\";\\nimport {IDiamondCut} from \\\"../../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IStorageLoupe} from \\\"./interfaces/IStorageLoupe.sol\\\";\\nimport {IDiamondLoupe} from \\\"./interfaces/IDiamondLoupe.sol\\\";\\n\\n/**\\n * @title DiamondLoupe Facet\\n * @dev DiamondLoupe contract compatible with EIP-2535\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract DiamondLoupeFacet is IDiamondLoupe, IStorageLoupe, IERC165 {\\n // Diamond Loupe Functions\\n ////////////////////////////////////////////////////////////////////\\n /// These functions are expected to be called frequently by tools off-chain.\\n\\n /**\\n * @notice Gets all facets and their selectors.\\n * @dev Barz uses a special architecture called default fallback handler. Default Fallback handler is used as a middleware\\n * that holds the mapping of facet function selector and facet address that Barz uses. This helps Barz to reduce\\n * significant amount of gas during the initialization process.\\n * Hence, this method aggregates both the facet information from DefaulFallbackHandler and in diamond storage and shows the data to users.\\n * @return facets_ Facet\\n */\\n function facets() public view override returns (Facet[] memory facets_) {\\n Facet[] memory defaultFacet = LibDiamond\\n .diamondStorage()\\n .defaultFallbackHandler\\n .facets();\\n Facet[] memory _facets = LibLoupe.facets();\\n uint256 numFacets = _facets.length;\\n bytes4[] memory keys;\\n address[] memory values;\\n for (uint256 i; i < numFacets; ) {\\n uint256 selectorsLength = _facets[i].functionSelectors.length;\\n for (uint256 j; j < selectorsLength; ) {\\n (keys, values) = LibUtils.setValue(\\n keys,\\n values,\\n _facets[i].functionSelectors[j],\\n _facets[i].facetAddress\\n );\\n unchecked {\\n ++j;\\n }\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n {\\n bool iIncrement;\\n for (uint256 i; i < defaultFacet.length; ) {\\n bool jIncrement;\\n for (\\n uint256 j;\\n j < defaultFacet[i].functionSelectors.length;\\n\\n ) {\\n if (\\n LibUtils.getValue(\\n keys,\\n values,\\n defaultFacet[i].functionSelectors[j]\\n ) != address(0)\\n ) {\\n if (defaultFacet[i].functionSelectors.length == 1) {\\n defaultFacet = LibUtils.removeFacetElement(\\n defaultFacet,\\n i\\n );\\n iIncrement = true;\\n break;\\n }\\n defaultFacet[i].functionSelectors = LibUtils\\n .removeElement(\\n defaultFacet[i].functionSelectors,\\n j\\n );\\n jIncrement = true;\\n }\\n if (!jIncrement) {\\n unchecked {\\n ++j;\\n }\\n } else {\\n jIncrement = false;\\n }\\n }\\n if (!iIncrement) {\\n unchecked {\\n ++i;\\n }\\n } else {\\n iIncrement = false;\\n }\\n }\\n }\\n {\\n uint256 facetLength = numFacets + defaultFacet.length;\\n facets_ = new Facet[](facetLength);\\n uint256 defaultFacetIndex;\\n for (uint256 i; i < facetLength; ) {\\n if (i < numFacets) {\\n facets_[i] = _facets[i];\\n bool jIncrementor;\\n for (uint256 j; j < defaultFacet.length; ) {\\n if (\\n facets_[i].facetAddress ==\\n defaultFacet[j].facetAddress\\n ) {\\n facets_[i].functionSelectors = LibUtils.mergeArrays(\\n _facets[i].functionSelectors,\\n defaultFacet[j].functionSelectors\\n );\\n defaultFacet = LibUtils.removeFacetElement(\\n defaultFacet,\\n j\\n );\\n jIncrementor = true;\\n {\\n facets_ = LibUtils.removeFacetElement(\\n facets_,\\n facets_.length - 1\\n );\\n }\\n --facetLength;\\n }\\n if (!jIncrementor) {\\n unchecked {\\n ++j;\\n }\\n } else {\\n jIncrementor = false;\\n }\\n }\\n } else {\\n facets_[i] = defaultFacet[defaultFacetIndex];\\n ++defaultFacetIndex;\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n }\\n\\n /**\\n * @notice Gets all the function selectors provided by a facet.\\n * @param _facet The facet address.\\n * @return facetFunctionSelectors_\\n */\\n function facetFunctionSelectors(\\n address _facet\\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\\n Facet[] memory facet = facets();\\n uint256 facetLength = facet.length;\\n for (uint256 i; i < facetLength; ) {\\n if (facet[i].facetAddress == _facet)\\n return facet[i].functionSelectors;\\n unchecked {\\n ++i;\\n }\\n }\\n return facetFunctionSelectors_;\\n }\\n\\n /**\\n * @notice Get all the facet addresses used by Barz.\\n * @return facetAddresses_\\n */\\n function facetAddresses()\\n external\\n view\\n override\\n returns (address[] memory facetAddresses_)\\n {\\n Facet[] memory facet = facets();\\n uint256 facetLength = facet.length;\\n facetAddresses_ = new address[](facetLength);\\n for (uint256 i; i < facetLength; ) {\\n facetAddresses_[i] = facet[i].facetAddress;\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * @notice Gets the facet that supports the given selector.\\n * @dev If facet is not found return address(0).\\n * @param _functionSelector The function selector.\\n * @return facetAddress_ The facet address.\\n */\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view override returns (address facetAddress_) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n\\n facetAddress_ = address(bytes20(ds.facets[_functionSelector]));\\n if (facetAddress_ == address(0)) {\\n facetAddress_ = IDiamondLoupe(ds.defaultFallbackHandler)\\n .facetAddress(_functionSelector);\\n }\\n }\\n\\n /**\\n * @notice SupportInterface to be compatible with EIP 165\\n * @param _interfaceId Interface ID for detecting the interface\\n * @return isSupported Bool value showing if the standard is supported in the contract\\n */\\n function supportsInterface(\\n bytes4 _interfaceId\\n ) external view override returns (bool isSupported) {\\n isSupported =\\n _interfaceId == type(IERC165).interfaceId ||\\n _interfaceId == IDiamondCut.diamondCut.selector ||\\n _interfaceId == type(IDiamondLoupe).interfaceId ||\\n _interfaceId == type(IERC1155Receiver).interfaceId ||\\n _interfaceId == type(IERC721Receiver).interfaceId ||\\n _interfaceId == type(IERC777Recipient).interfaceId ||\\n _interfaceId == IERC1271.isValidSignature.selector ||\\n _interfaceId == type(IERC677Receiver).interfaceId ||\\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId];\\n }\\n\\n /**\\n * @notice Returns the facet from the diamond storage. This excludes the facets from the default fallback handler\\n * @return facets_ Facet information attached directly to diamond storage\\n */\\n function facetsFromStorage()\\n external\\n view\\n override\\n returns (Facet[] memory facets_)\\n {\\n facets_ = LibLoupe.facets();\\n }\\n\\n /**\\n * @notice Returns the facet address attached to the given function selector. This excludes the facets from the default fallback handler\\n * @param _functionSelector Function selector to fetch the facet address from diamond storage\\n * @return facetAddress_ Facet address mapped with the function selector\\n */\\n function facetAddressFromStorage(\\n bytes4 _functionSelector\\n ) external view override returns (address facetAddress_) {\\n facetAddress_ = LibLoupe.facetAddress(_functionSelector);\\n }\\n\\n /**\\n * @notice Returns all facet addresses attached directly to diamond storage. This excludes the facets from the default fallback handler\\n * @return facetAddresses_ All facet addresses attached directly to diamond storage\\n */\\n function facetAddressesFromStorage()\\n external\\n view\\n override\\n returns (address[] memory facetAddresses_)\\n {\\n facetAddresses_ = LibLoupe.facetAddresses();\\n }\\n\\n /**\\n * @notice Returns function selectors of given facet address attached directly to diamond storage. This excludes the facets from the default fallback handler\\n * @param _facet Facet address to fetch the facet function selectors from diamond storage\\n * @return facetFunctionSelectors_ Facet function selectors of the given facet address\\n */\\n function facetFunctionSelectorsFromStorage(\\n address _facet\\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\\n facetFunctionSelectors_ = LibLoupe.facetFunctionSelectors(_facet);\\n }\\n}\\n\"\n },\n \"contracts/facets/base/interfaces/IDiamondCut.sol\": {\n \"content\": \"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\"\n },\n \"contracts/facets/base/interfaces/IDiamondLoupe.sol\": {\n \"content\": \"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\"\n },\n \"contracts/facets/base/interfaces/IStorageLoupe.sol\": {\n \"content\": \"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"./IDiamondLoupe.sol\\\";\\n\\n/**\\n * @title LoupeFromStorage Interface\\n * @dev Interface contract to function as a loupe facet directly attached to diamond storage of Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IStorageLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facetsFromStorage()\\n external\\n view\\n returns (IDiamondLoupe.Facet[] memory);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n function facetFunctionSelectorsFromStorage(\\n address _facet\\n ) external view returns (bytes4[] memory);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n function facetAddressesFromStorage()\\n external\\n view\\n returns (address[] memory);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n function facetAddressFromStorage(\\n bytes4 _functionSelector\\n ) external view returns (address);\\n}\\n\"\n },\n \"contracts/facets/GuardianFacet.sol\": {\n \"content\": \"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {LibDiamond} from \\\"../libraries/LibDiamond.sol\\\";\\nimport {LibFacetStorage, GuardianStorage, StorageConfig} from \\\"../libraries/LibFacetStorage.sol\\\";\\nimport {LibGuardian} from \\\"../libraries/LibGuardian.sol\\\";\\nimport {ISecurityManager} from \\\"../infrastructure/interfaces/ISecurityManager.sol\\\";\\nimport {IGuardianFacet} from \\\"./interfaces/IGuardianFacet.sol\\\";\\nimport {IVerificationFacet} from \\\"./interfaces/IVerificationFacet.sol\\\";\\n\\n/**\\n * @title Guardian Facet\\n * @dev Contract that enables addition/removal of guardians from Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract GuardianFacet is IGuardianFacet {\\n ISecurityManager public immutable securityManager;\\n uint8 public constant INNER_STRUCT = 0;\\n\\n /**\\n * @notice This constructor sets the Security Manager address which is an immutable variable.\\n * Immutable variables do not impact the storage of diamond\\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\\n */\\n constructor(address _securityManager) {\\n securityManager = ISecurityManager(_securityManager);\\n }\\n\\n /**\\n * @notice Add guardians to Barz.\\n * @dev This method internally calls addGuardian which checks the validity of guardian address and adds\\n * as guardian if valid\\n * @param _guardians Array of addresses to add as guardian\\n */\\n function addGuardians(address[] calldata _guardians) external override {\\n LibDiamond.enforceIsSelf();\\n for (uint256 i; i < _guardians.length; ) {\\n addGuardian(_guardians[i]);\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * @notice Add a guardian to Barz.\\n * @dev This method checks if the function is called by the owner and validates the address of guardian\\n * When the validation passes, guardian address is added to the pending state waiting for confirmation\\n * @param _guardian Address to add as guardian\\n */\\n function addGuardian(address _guardian) public override {\\n LibDiamond.enforceIsSelf();\\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\\n if (_guardian == address(this))\\n revert GuardianFacet__GuardianCannotBeSelf();\\n if (isGuardian(_guardian)) revert GuardianFacet__DuplicateGuardian();\\n if (_guardian == address(0))\\n revert GuardianFacet__ZeroAddressGuardian();\\n if (\\n keccak256(abi.encodePacked(_guardian)) ==\\n keccak256(IVerificationFacet(address(this)).owner())\\n ) revert GuardianFacet__OwnerCannotBeGuardian();\\n\\n bytes32 id = keccak256(abi.encodePacked(_guardian, \\\"ADD\\\"));\\n if (\\n gs.pending[id] != 0 ||\\n block.timestamp <= gs.pending[id] + getSecurityWindow()\\n ) revert GuardianFacet__DuplicateGuardianAddition();\\n\\n uint256 securityPeriod = getAdditionSecurityPeriod();\\n gs.pending[id] = block.timestamp + securityPeriod;\\n emit GuardianAdditionRequested(\\n _guardian,\\n block.timestamp + securityPeriod\\n );\\n }\\n\\n /**\\n * @notice Remove guardians from Barz.\\n * @dev This method internally calls removeGuardian which checks the validity of guardian and removes\\n * guardian when the request is valid\\n * @param _guardians Array of addresses to be removed\\n */\\n function removeGuardians(address[] calldata _guardians) external override {\\n LibDiamond.enforceIsSelf();\\n for (uint256 i; i < _guardians.length; ) {\\n removeGuardian(_guardians[i]);\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * @notice Remove a guardian from Barz.\\n * @dev This method validates if the guardian to be removed is a guardian and puts the guardian removal\\n * to a pending state waiting to be confirmed.\\n * @param _guardian Address of guardian to be removed\\n */\\n function removeGuardian(address _guardian) public override {\\n LibDiamond.enforceIsSelf();\\n if (!isGuardian(_guardian)) revert GuardianFacet__NonExistentGuardian();\\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\\n bytes32 id = keccak256(abi.encodePacked(_guardian, \\\"REMOVE\\\"));\\n if (\\n gs.pending[id] != 0 ||\\n block.timestamp <= gs.pending[id] + getSecurityWindow()\\n ) revert GuardianFacet__DuplicateGuardianRemoval();\\n\\n uint256 securityPeriod = getRemovalSecurityPeriod();\\n gs.pending[id] = block.timestamp + securityPeriod;\\n emit GuardianRemovalRequested(\\n _guardian,\\n block.timestamp + securityPeriod\\n );\\n }\\n\\n /**\\n * @notice Confirm addition of guardians\\n * @dev This method internally calls confirmGuardianAddition which checks the validity of pending request.\\n * Guardians are fully added when they pass the validation. Anyone can call this function.\\n * @param _guardians Array of guardian addresses to be added\\n */\\n function confirmGuardianAdditions(\\n address[] calldata _guardians\\n ) external override {\\n for (uint256 i; i < _guardians.length; ) {\\n confirmGuardianAddition(_guardians[i]);\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * @notice Confirm addition of a guardian\\n * @dev This method checks the validity of pending request.\\n * Guardians are fully added when they pass the validation. Anyone can call this function.\\n * @param _guardian Guardian address to be added\\n */\\n function confirmGuardianAddition(address _guardian) public override {\\n bytes32 id = keccak256(abi.encodePacked(_guardian, \\\"ADD\\\"));\\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingAddition();\\n if (gs.pending[id] >= block.timestamp)\\n revert GuardianFacet__PendingAdditionNotOver();\\n if (block.timestamp >= gs.pending[id] + getSecurityWindow())\\n revert GuardianFacet__PendingAdditionExpired();\\n\\n _addGuardian(_guardian);\\n\\n delete gs.pending[id];\\n emit GuardianAdded(_guardian);\\n }\\n\\n /**\\n * @notice Confirm removal of guardians\\n * @dev This method internally calls confirmGuardianRemoval to check the validity guardian removal confirmation.\\n * Guardians are fully removed when they pass the validation. Anyone can call this function.\\n * @param _guardians Array of guardian addresses to be removed\\n */\\n function confirmGuardianRemovals(\\n address[] calldata _guardians\\n ) external override {\\n for (uint256 i; i < _guardians.length; ) {\\n confirmGuardianRemoval(_guardians[i]);\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * @notice Confirm removal of a guardian\\n * @dev This method checks the validity guardian removal confirmation.\\n * Guardian is fully removed when they pass the validation. Anyone can call this function.\\n * @param _guardian Guardian address to be removed\\n */\\n function confirmGuardianRemoval(address _guardian) public override {\\n bytes32 id = keccak256(abi.encodePacked(_guardian, \\\"REMOVE\\\"));\\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingRemoval();\\n if (gs.pending[id] >= block.timestamp)\\n revert GuardianFacet__PendingRemovalNotOver();\\n if (block.timestamp >= gs.pending[id] + getSecurityWindow())\\n revert GuardianFacet__PendingAdditionExpired();\\n\\n _removeGuardian(_guardian);\\n delete gs.pending[id];\\n emit GuardianRemoved(_guardian);\\n }\\n\\n /**\\n * @notice Cancel pending guardian addition\\n * @dev This method checks if the previous request for guardian request exists.\\n * It reverts if previous request is not pending and cancels the addition otherwise.\\n * @param _guardian Guardian address to be canceled from addition\\n */\\n function cancelGuardianAddition(address _guardian) external override {\\n LibDiamond.enforceIsSelf();\\n bytes32 id = keccak256(abi.encodePacked(_guardian, \\\"ADD\\\"));\\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingAddition();\\n delete gs.pending[id];\\n emit GuardianAdditionCancelled(_guardian);\\n }\\n\\n /**\\n * @notice Cancel pending guardian removal\\n * @dev This method checks if the previous request for guardian request exists.\\n * It reverts if previous request is not pending and cancels the removal otherwise.\\n * @param _guardian Guardian address to be canceled from removal\\n */\\n function cancelGuardianRemoval(address _guardian) external override {\\n LibDiamond.enforceIsSelf();\\n bytes32 id = keccak256(abi.encodePacked(_guardian, \\\"REMOVE\\\"));\\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingRemoval();\\n delete gs.pending[id];\\n emit GuardianRemovalCancelled(_guardian);\\n }\\n\\n /**\\n * @notice Get the addition security period of current account from security manager\\n * @dev This method returns the uint value if addition security period\\n * @return additionSecurityPeriod Uint256 value of addition security period\\n */\\n function getAdditionSecurityPeriod()\\n public\\n view\\n override\\n returns (uint256 additionSecurityPeriod)\\n {\\n additionSecurityPeriod = securityManager.additionSecurityPeriodOf(\\n address(this)\\n );\\n if (additionSecurityPeriod == 0)\\n revert GuardianFacet__InvalidAdditionSecurityPeriod();\\n }\\n\\n /**\\n * @notice Get the removal security period of current account from security manager\\n * @dev This method returns the uint value if removal security period\\n * @return removalSecurityPeriod Uint256 value of removal security period\\n */\\n function getRemovalSecurityPeriod()\\n public\\n view\\n override\\n returns (uint256 removalSecurityPeriod)\\n {\\n removalSecurityPeriod = securityManager.removalSecurityPeriodOf(\\n address(this)\\n );\\n if (removalSecurityPeriod == 0)\\n revert GuardianFacet__InvalidRemovalSecurityPeriod();\\n }\\n\\n /**\\n * @notice Get the security window of current account from security manager\\n * @dev This method returns the uint value if security window\\n * @return securityWindow Uint256 value of removal security period\\n */\\n function getSecurityWindow()\\n public\\n view\\n override\\n returns (uint256 securityWindow)\\n {\\n securityWindow = securityManager.securityWindowOf(address(this));\\n if (securityWindow == 0) revert GuardianFacet__InvalidSecurityWindow();\\n }\\n\\n /**\\n * @notice Checks if the addition of the given guardian address is pending\\n * @dev This method returns the bool value of whether the guardian address is pending addition\\n * @return isPending Bool value of representing the pending of guardian addition\\n */\\n function isAdditionPending(\\n address _guardian\\n ) public view override returns (bool isPending) {\\n bytes32 id = keccak256(abi.encodePacked(_guardian, \\\"ADD\\\"));\\n isPending = _isPending(id);\\n }\\n\\n /**\\n * @notice Checks if the removal of the given guardian address is pending\\n * @dev This method returns the bool value of whether the guardian address is pending removal\\n * @return isPending Bool value of representing the pending of guardian removal\\n */\\n function isRemovalPending(\\n address _guardian\\n ) public view override returns (bool isPending) {\\n bytes32 id = keccak256(abi.encodePacked(_guardian, \\\"REMOVE\\\"));\\n isPending = _isPending(id);\\n }\\n\\n /**\\n * @notice Checks if the given hash is pending\\n * @dev This method returns the bool value whether the hash is pending\\n * @return isPending Bool value of representing the pending of guardian operation\\n */\\n function _isPending(\\n bytes32 _idHash\\n ) internal view returns (bool isPending) {\\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\\n isPending = ((gs.pending[_idHash] > 0 &&\\n gs.pending[_idHash] < block.timestamp) &&\\n block.timestamp < gs.pending[_idHash] + getSecurityWindow());\\n }\\n\\n /**\\n * @notice Adds guardian to storage config. This is called when guardian is fully added.\\n * @dev This method add guardian address and config information to Facet Storage dedicated for guardian\\n * When this function is called, guardian is fully added to this Barz Smart Account\\n * @param _guardian Address of guardian to be added\\n */\\n function _addGuardian(address _guardian) internal {\\n if (!isAdditionPending(_guardian))\\n revert GuardianFacet__InvalidGuardianAddition();\\n StorageConfig storage config = LibFacetStorage\\n .guardianStorage()\\n .configs[INNER_STRUCT];\\n if (config.info[_guardian].exists)\\n revert GuardianFacet__AlreadyExists();\\n\\n config.info[_guardian].exists = true;\\n config.info[_guardian].index = uint128(config.addresses.length);\\n config.addresses.push(_guardian);\\n }\\n\\n /**\\n * @notice Removes guardian to storage config. This is called when guardian is fully removed.\\n * @dev This method remove guardian address and config information to Facet Storage dedicated for guardian\\n * When this function is called, guardian is fully removed from this Barz Smart Account\\n * @param _guardian Address of guardian to be removed\\n */\\n function _removeGuardian(address _guardian) internal {\\n if (!isRemovalPending(_guardian))\\n revert GuardianFacet__InvalidGuardianRemoval();\\n StorageConfig storage config = LibFacetStorage\\n .guardianStorage()\\n .configs[INNER_STRUCT];\\n if (!config.info[_guardian].exists)\\n revert GuardianFacet__NonExistentGuardian();\\n\\n address lastAddress = config.addresses[config.addresses.length - 1];\\n if (_guardian != lastAddress) {\\n uint128 targetIndex = config.info[_guardian].index;\\n config.addresses[targetIndex] = lastAddress;\\n config.info[lastAddress].index = targetIndex;\\n }\\n config.addresses.pop();\\n delete config.info[_guardian];\\n\\n emit GuardianRemoved(_guardian);\\n }\\n\\n /**\\n * @notice Reads guardian storage and fetches the addresses into an array from the storage\\n * @dev This method fetches the guardian storage and returns the list of guardian addresses\\n * @return guardians Array of addresses comprised of guardian\\n */\\n function getGuardians()\\n public\\n view\\n override\\n returns (address[] memory guardians)\\n {\\n StorageConfig storage config = LibFacetStorage\\n .guardianStorage()\\n .configs[INNER_STRUCT];\\n uint256 guardiansLen = config.addresses.length;\\n guardians = new address[](guardiansLen);\\n for (uint256 i; i < guardiansLen; ) {\\n guardians[i] = config.addresses[i];\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * @notice Returns the number of majority of guardians\\n * @return majorityOfGuardians_ Number of majority of guardians e.g., 2 if 3 guardians / 3 if 5 guardians\\n */\\n function majorityOfGuardians()\\n public\\n view\\n override\\n returns (uint256 majorityOfGuardians_)\\n {\\n majorityOfGuardians_ = LibGuardian.majorityOfGuardians();\\n }\\n\\n /**\\n * @notice Reads guardian storage and fetches the addresses into an array from the storage\\n * @dev This method fetches the guardian storage and returns the list of guardian addresses\\n * @return guardianNumber Array of guardians in the account\\n */\\n function guardianCount()\\n public\\n view\\n override\\n returns (uint256 guardianNumber)\\n {\\n StorageConfig storage config = LibFacetStorage\\n .guardianStorage()\\n .configs[INNER_STRUCT];\\n guardianNumber = config.addresses.length;\\n }\\n\\n /**\\n * @notice Reads guardian storage and checks if the given address is a guardian\\n * @return isGuardian_ Bool value representing if the given address is guardian\\n */\\n function isGuardian(\\n address _guardian\\n ) public view override returns (bool isGuardian_) {\\n StorageConfig storage config = LibFacetStorage\\n .guardianStorage()\\n .configs[INNER_STRUCT];\\n isGuardian_ = config.info[_guardian].exists;\\n }\\n\\n /**\\n * @notice Checks if the guardian number is zero and returns of guardian facet is okay to be removed\\n * @return isRemovable Bool value representing if guardian facet is removable\\n */\\n function isGuardianFacetRemovable()\\n external\\n view\\n override\\n returns (bool isRemovable)\\n {\\n isRemovable = (0 == guardianCount());\\n }\\n}\\n\"\n },\n \"contracts/facets/interfaces/IAccountFacet.sol\": {\n \"content\": \"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IEntryPoint} from \\\"../../aa-4337/interfaces/IEntryPoint.sol\\\";\\n\\n/**\\n * @title Account Facet Interface\\n * @dev Interface of module contract that provides the account features and init/unitialization of signer\\n * compatible with EIP-1271 & EIP-4337\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IAccountFacet {\\n event AccountInitialized(\\n IEntryPoint indexed entryPoint,\\n bytes indexed ownerPublicKey\\n );\\n // NOTE: Added Below Event\\n event VerificationSuccess(bytes32);\\n event VerificationFailure(bytes32);\\n\\n error AccountFacet__InitializationFailure();\\n error AccountFacet__RestrictionsFailure();\\n error AccountFacet__NonExistentVerificationFacet();\\n error AccountFacet__CallNotSuccessful();\\n error AccountFacet__InvalidArrayLength();\\n\\n function initialize(\\n address verificationFacet,\\n address anEntryPoint,\\n address facetRegistry,\\n address _defaultFallBack,\\n bytes calldata _ownerPublicKey\\n ) external returns (uint256);\\n\\n function execute(address dest, uint256 value, bytes calldata func) external;\\n\\n function executeBatch(\\n address[] calldata dest,\\n uint256[] calldata value,\\n bytes[] calldata func\\n ) external;\\n}\\n\"\n },\n \"contracts/facets/interfaces/IAccountRecoveryFacet.sol\": {\n \"content\": \"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {RecoveryConfig} from \\\"../../libraries/LibFacetStorage.sol\\\";\\n\\n/**\\n * @title Account Recovery Facet Interface\\n * @dev Interface of contract that enables recovery of accounts when owner key is unavailable\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IAccountRecoveryFacet {\\n event RecoveryExecuted(\\n bytes indexed recoveryPublicKey,\\n uint64 executeAfter\\n );\\n event RecoveryFinalized(bytes indexed recoveryPublicKey);\\n event RecoveryCanceled(bytes indexed recoveryPublicKey);\\n event RecoveryApproved(\\n bytes indexed recoveryPublicKey,\\n address indexed guardian,\\n uint64 validUntil\\n );\\n event RecoveryApprovalRevoked(\\n bytes indexed recoveryPublicKey,\\n address indexed guardian\\n );\\n event RecoveryCancellationApproved(\\n bytes indexed recoveryPublicKey,\\n address indexed guardian\\n );\\n event RecoveryHardstopped();\\n\\n error AccountRecoveryFacet__CallerNotGuardian();\\n error AccountRecoveryFacet__InvalidRecoveryPublicKey();\\n error AccountRecoveryFacet__SignerInitializationFailure();\\n error AccountRecoveryFacet__SignerUninitializationFailure();\\n error AccountRecoveryFacet__InvalidArrayLength();\\n error AccountRecoveryFacet__InsufficientGuardians();\\n error AccountRecoveryFacet__RecoveryAlreadyOngoing();\\n error AccountRecoveryFacet__NonexistentRecovery();\\n error AccountRecoveryFacet__NonExistentApproval();\\n error AccountRecoveryFacet__RecoveryPeriodNotOver();\\n error AccountRecoveryFacet__InvalidLockPeriod();\\n error AccountRecoveryFacet__InvalidRecoveryPeriod();\\n error AccountRecoveryFacet__InvalidApprovalValidationPeriod();\\n error AccountRecoveryFacet__InvalidGuardian();\\n error AccountRecoveryFacet__InvalidGuardianSignature();\\n error AccountRecoveryFacet__InvalidOwnerSignature();\\n error AccountRecoveryFacet__CallNotSuccesful();\\n error AccountRecoveryFacet__DuplicateApproval();\\n\\n function approveAccountRecovery(bytes calldata recoveryPublicKey) external;\\n\\n function revokeAccountRecoveryApproval(\\n bytes calldata recoveryPublicKey\\n ) external;\\n\\n function executeRecovery(\\n bytes calldata recoveryPublicKey,\\n address[] calldata guardians,\\n bytes[] calldata signatures\\n ) external;\\n\\n function finalizeRecovery() external;\\n\\n function approveCancelRecovery(bytes calldata recoveryPublicKey) external;\\n\\n function cancelRecovery(\\n bytes calldata recoveryPublicKey,\\n address[] calldata guardians,\\n bytes[] calldata signatures\\n ) external;\\n\\n function hardstopRecovery(bytes calldata signature) external;\\n\\n function validateNewOwner(bytes calldata recoveryPublicKey) external view;\\n\\n function getApprovalRecoveryKeyHash(\\n bytes memory recoveryPublicKey,\\n string memory saltString\\n ) external view returns (bytes32);\\n\\n function getRecoveryApprovalCountWithTimeValidity(\\n bytes32 recoveryPublicKeyHash\\n ) external view returns (uint256);\\n\\n function isRecoveryApproved(\\n bytes32 recoveryPublicKeyHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getRecoveryNonce() external view returns (uint128);\\n\\n function getPendingRecovery() external view returns (RecoveryConfig memory);\\n}\\n\"\n },\n \"contracts/facets/interfaces/IGuardianFacet.sol\": {\n \"content\": \"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Guardian Facet Interface\\n * @dev Interface of guaridna contract that enables addition/removal of guardians from Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IGuardianFacet {\\n event GuardianAdditionRequested(\\n address indexed guardian,\\n uint256 executeAfter\\n );\\n event GuardianRemovalRequested(\\n address indexed guardian,\\n uint256 executeAfter\\n );\\n event GuardianAdditionCancelled(address indexed guardian);\\n event GuardianRemovalCancelled(address indexed guardian);\\n event GuardianAdded(address indexed guardian);\\n event GuardianRemoved(address indexed guardian);\\n\\n error GuardianFacet__GuardianCannotBeSelf();\\n error GuardianFacet__DuplicateGuardian();\\n error GuardianFacet__OwnerCannotBeGuardian();\\n error GuardianFacet__DuplicateGuardianAddition();\\n error GuardianFacet__DuplicateGuardianRemoval();\\n error GuardianFacet__UnknownPendingAddition();\\n error GuardianFacet__PendingAdditionNotOver();\\n error GuardianFacet__UnknownPendingRemoval();\\n error GuardianFacet__PendingRemovalNotOver();\\n error GuardianFacet__PendingAdditionExpired();\\n error GuardianFacet__InvalidAdditionSecurityPeriod();\\n error GuardianFacet__InvalidRemovalSecurityPeriod();\\n error GuardianFacet__InvalidSecurityWindow();\\n error GuardianFacet__NonExistentGuardian();\\n error GuardianFacet__AlreadyExists();\\n error GuardianFacet__InvalidGuardianAddition();\\n error GuardianFacet__InvalidGuardianRemoval();\\n error GuardianFacet__ZeroAddressGuardian();\\n\\n function addGuardian(address guardian) external;\\n\\n function addGuardians(address[] calldata guardians) external;\\n\\n function removeGuardian(address guardian) external;\\n\\n function removeGuardians(address[] calldata guardians) external;\\n\\n function confirmGuardianAddition(address guardian) external;\\n\\n function confirmGuardianAdditions(address[] calldata guardian) external;\\n\\n function confirmGuardianRemoval(address guardian) external;\\n\\n function confirmGuardianRemovals(address[] calldata guardian) external;\\n\\n function cancelGuardianAddition(address guardian) external;\\n\\n function cancelGuardianRemoval(address guardian) external;\\n\\n function isGuardian(address guardian) external view returns (bool);\\n\\n function isAdditionPending(address guardian) external view returns (bool);\\n\\n function isRemovalPending(address guardian) external view returns (bool);\\n\\n function isGuardianFacetRemovable() external view returns (bool);\\n\\n function getAdditionSecurityPeriod() external view returns (uint256);\\n\\n function getRemovalSecurityPeriod() external view returns (uint256);\\n\\n function getSecurityWindow() external view returns (uint256);\\n\\n function getGuardians() external view returns (address[] memory);\\n\\n function majorityOfGuardians() external view returns (uint256);\\n\\n function guardianCount() external view returns (uint256);\\n}\\n\"\n },\n \"contracts/facets/interfaces/ILockFacet.sol\": {\n \"content\": \"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {Lock} from \\\"../../libraries/LibAppStorage.sol\\\";\\n\\n/**\\n * @title Lock Facet Interface\\n * @dev Interface of Lock contract that enables full lock/unlock of Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface ILockFacet {\\n event Locked(uint64 releaseAfter);\\n event Unlocked();\\n\\n error LockFacet__InvalidRecoveryPeriod();\\n error LockFacet__CannotUnlock();\\n error LockFacet__InvalidSignature();\\n error LockFacet__InvalidApprover();\\n\\n function lock() external;\\n\\n function unlock(address approver, bytes calldata signature) external;\\n\\n function getLockPeriod() external view returns (uint256);\\n\\n function isLocked() external view returns (bool);\\n\\n function getUnlockHash() external view returns (bytes32);\\n\\n function lockNonce() external view returns (uint128);\\n\\n function getPendingLock() external view returns (Lock memory);\\n}\\n\"\n },\n \"contracts/facets/interfaces/IMultiSigFacet.sol\": {\n \"content\": \"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Multi-sig facet Interface\\n * @dev Interface of Multi-signature Facet with custom threshold.\\n Wallet that adds this facet becomes a multi-sig wallet\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IMultiSigFacet {\\n event ThresholdChanged(uint256 threshold);\\n event OwnerAdded(address indexed newOwner);\\n event OwnerRemoved(address indexed prevOwner);\\n event HashApproved(bytes32 hashToApprove, address indexed owner);\\n\\n error MultiSigFacet__InvalidThreshold();\\n error MultisigFacet__InvalidOwnerCount();\\n error MultiSigFacet__InvalidRoute();\\n error MultiSigFacet__InsufficientSignerLength();\\n error MultiSigFacet__InvalidInitData();\\n error MultiSigFacet__InvalidOwnerAddress();\\n error MultiSigFacet__InvalidOwnerPair();\\n error MultiSigFacet__InvalidSignatureLength();\\n error MultiSigFacet__InvalidSignatureType();\\n error MultiSigFacet__DuplicateOwner();\\n error MultiSigFacet__OnlyOwner();\\n\\n function checkSignatures(\\n bytes32 _dataHash,\\n bytes calldata _signatures,\\n uint256 _threshold\\n ) external view returns (uint256);\\n\\n function splitSignatures(\\n bytes calldata _signatures,\\n uint256 _nextOffset\\n )\\n external\\n pure\\n returns (\\n address owner,\\n bytes memory signature,\\n uint256 signatureType,\\n uint256 nextOffset\\n );\\n\\n function approveHash(bytes32 hashToApprove) external;\\n\\n function addOwner(address newOwner, uint256 threshold) external;\\n\\n function removeOwner(\\n address prevOwner,\\n address removedOwner,\\n uint256 threshold\\n ) external;\\n\\n function swapOwner(\\n address prevOwner,\\n address oldOwner,\\n address newOwner\\n ) external;\\n\\n function changeThreshold(uint256 _threshold) external;\\n\\n function isOwner(address owner) external view returns (bool);\\n\\n function getThreshold() external view returns (uint256);\\n\\n function getOwners() external view returns (address[] memory);\\n}\\n\"\n },\n \"contracts/facets/interfaces/IRestrictionsFacet.sol\": {\n \"content\": \"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Restrictions Facet Interface\\n * @dev Interface of Restrictions contract that enables modular restrictions in Barz\\n * @author Ruslan Serebriakov (@rsrbk)\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IRestrictionsFacet {\\n event RestrictionAdded(address indexed restriction);\\n event RestrictionRemoved(address indexed restriction);\\n\\n error RestrictionsFacet__EmptyRestrictionsList();\\n error RestrictionsFacet__RestrictionNotFound();\\n error RestrictionsFacet__RestrictionAlreadyExists();\\n error RestrictionsFacet__ZeroAddressRestrictions();\\n error RestrictionsFacet__ZeroAddressRestrictionsFacet();\\n error RestrictionsFacet__RemainingRestrictionsCantBeEmpty();\\n\\n function initializeRestrictions(\\n address[] memory _restrictions\\n ) external returns (uint256);\\n\\n function uninitializeRestrictions() external returns (uint256);\\n\\n function getRestrictions() external view returns (address[] memory);\\n\\n function addRestriction(address restriction) external;\\n\\n function removeRestriction(address restriction) external;\\n\\n function verifyRestrictions(\\n address from,\\n address to,\\n uint256 value,\\n bytes calldata _calldata\\n ) external returns (uint256);\\n}\\n\"\n },\n \"contracts/facets/interfaces/ISignatureMigrationFacet.sol\": {\n \"content\": \"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {SignatureMigrationConfig} from \\\"../../libraries/LibFacetStorage.sol\\\";\\n\\n/**\\n * @title Signature Migration Facet Interface\\n * @dev Interface of Signature Migration contract for migrating user signature scheme to a new scheme user sets\\n * Which could include\\n * - ECDSA on Secp256K1 Curve\\n * - ECDSA on Secp256R1 Curve\\n * - BLS, Schnorr, etc\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface ISignatureMigrationFacet {\\n event SignatureSchemeMigration(\\n address indexed prevVerificationFacet,\\n address indexed newVerificationFacet,\\n bytes newOwner,\\n bytes4[] verificationFuncSelectors\\n );\\n event SignatureMigrationApproved(\\n bytes newPublicKey,\\n address indexed newVerificationFacet,\\n bytes4[] verificationFuncSelectors,\\n address indexed guardian,\\n uint128 approvalValidUntil\\n );\\n event SignatureMigrationApprovalRevoked(\\n bytes newPublicKey,\\n address indexed newVerificationFacet,\\n bytes4[] verificationFuncSelectors,\\n address indexed guardian\\n );\\n event SignatureMigrationExecuted(\\n address indexed newVerificationFacet,\\n bytes newOwner,\\n bytes4[] verificationFuncSelectors,\\n uint128 migrateAfter\\n );\\n event SignatureMigrationCanceled(\\n address indexed newVerificationFacet,\\n bytes newOwner,\\n bytes4[] verificationFuncSelectors\\n );\\n event SignatureMigrationCancellationApproved(\\n address indexed newVerificationFacet,\\n bytes newOwner,\\n bytes4[] verificationFuncSelectors\\n );\\n\\n error SignatureMigrationFacet__SignerUninitializationFailure();\\n error SignatureMigrationFacet__SignerInitializationFailure();\\n error SignatureMigrationFacet__InvalidRouteWithGuardian();\\n error SignatureMigrationFacet__InvalidKeyType();\\n error SignatureMigrationFacet__InsufficientApprovers();\\n error SignatureMigrationFacet__InvalidApproverSignature();\\n error SignatureMigrationFacet__InvalidGuardian();\\n error SignatureMigrationFacet__NonExistentApprover();\\n error SignatureMigrationFacet__InvalidMigrationPeriod();\\n error SignatureMigrationFacet__NonexistentMigration();\\n error SignatureMigrationFacet__MigrationPeriodNotOver();\\n error SignatureMigrationFacet__InvalidArrayLength();\\n error SignatureMigrationFacet__InvalidApprovalValidationPeriod();\\n error SignatureMigrationFacet__CannotRevokeUnapproved();\\n error SignatureMigrationFacet__LackOfOwnerApproval();\\n error SignatureMigrationFacet__OwnerAlreadyApproved();\\n error SignatureMigrationFacet__NonExistentVerificationFacet();\\n error SignatureMigrationFacet__DuplicateApproval();\\n\\n function migrateSignatureScheme(\\n address newVerificationFacet,\\n bytes calldata newPublicKey,\\n bytes4[] calldata newVerificationFuncSelectors\\n ) external;\\n\\n function migrateSignatureSchemeWithGuardian(\\n address newVerificationFacet,\\n bytes calldata newPublicKey,\\n bytes4[] calldata newVerificationFuncSelectors,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveSignatureSchemeMigration(\\n address newVerificationFacet,\\n bytes calldata newPublicKey,\\n bytes4[] calldata newVerificationFuncSelectors\\n ) external;\\n\\n function revokeSignatureMigrationApproval(\\n address newVerificationFacet,\\n bytes calldata newPublicKey,\\n bytes4[] calldata newVerificationFuncSelectors\\n ) external;\\n\\n function finalizeSignatureMigration() external;\\n\\n function approveCancelSignatureMigration(\\n address newVerificationFacet,\\n bytes calldata newPublicKey,\\n bytes4[] calldata newVerificationFuncSelectors\\n ) external;\\n\\n function cancelSignatureMigration(\\n address newVerificationFacet,\\n bytes calldata newPublicKey,\\n bytes4[] calldata newVerificationFuncSelectors,\\n address[] calldata guardians,\\n bytes[] calldata signatures\\n ) external;\\n\\n function getApprovalMigrationKeyHash(\\n bytes memory recoveryPublicKey,\\n address newVerificationFacet,\\n bytes4[] memory newVerificationFuncSelectors,\\n string memory saltString\\n ) external view returns (bytes32);\\n\\n function getMigrationOwnerApprovalWithTimeValidity(\\n bytes32 publicKeyHash\\n ) external view returns (bool);\\n\\n function getMigrationApprovalCountWithTimeValidity(\\n bytes32 publicKeyHash\\n ) external view returns (uint256);\\n\\n function isMigrationApproved(\\n bytes32 migrationPublicKeyHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getMigrationNonce() external view returns (uint128);\\n\\n function isMigrationPending() external view returns (bool);\\n\\n function getPendingMigration()\\n external\\n view\\n returns (SignatureMigrationConfig memory);\\n}\\n\"\n },\n \"contracts/facets/interfaces/IVerificationFacet.sol\": {\n \"content\": \"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {UserOperation} from \\\"../../aa-4337/interfaces/UserOperation.sol\\\";\\n\\n/**\\n * @title Verification Facet Interface\\n * @dev Implements logic for user ops signature verification\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\ninterface IVerificationFacet {\\n event SignerInitialized(bytes);\\n event SignerUninitialized();\\n\\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\\n error VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\\n error VerificationFacet__InitializationFailure();\\n error VerificationFacet__InvalidFacetMapping();\\n\\n function initializeSigner(bytes memory) external returns (uint256);\\n\\n function uninitializeSigner() external returns (uint256);\\n\\n function validateOwnerSignatureSelector() external view returns (bytes4);\\n\\n function owner() external view returns (bytes memory);\\n\\n function isValidKeyType(bytes calldata) external view returns (bool);\\n\\n function validateOwnerSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) external view returns (uint256);\\n}\\n\"\n },\n \"contracts/facets/LockFacet.sol\": {\n \"content\": \"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {SignatureChecker} from \\\"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\\\";\\nimport {LibAppStorage, Lock} from \\\"../libraries/LibAppStorage.sol\\\";\\nimport {LibGuardian} from \\\"../libraries/LibGuardian.sol\\\";\\nimport {LibFacetStorage} from \\\"../libraries/LibFacetStorage.sol\\\";\\nimport {Modifiers} from \\\"./Modifiers.sol\\\";\\nimport {ISecurityManager} from \\\"../infrastructure/interfaces/ISecurityManager.sol\\\";\\nimport {ILockFacet} from \\\"./interfaces/ILockFacet.sol\\\";\\n\\n/**\\n * @title Lock Facet\\n * @dev Contract that enables full lock/unlock of Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract LockFacet is ILockFacet, Modifiers {\\n ISecurityManager public immutable securityManager;\\n\\n /**\\n * @notice This constructor sets the Security Manager address which is an immutable variable.\\n * Immutable variables do not impact the storage of diamond\\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\\n */\\n constructor(address _securityManager) {\\n securityManager = ISecurityManager(_securityManager);\\n }\\n\\n /**\\n * @notice Locks the account for the lock period. Lock period is defined in the security manager and it's customizable\\n * This function can only be called when account is unlocked by owner or guardians\\n * @dev This method checks the caller and if the account is currently locked and locks the account after fetching the\\n * Lock period from the owner.\\n */\\n function lock() external override onlyGuardianOrOwner onlyWhenUnlocked {\\n uint256 unlockTime = block.timestamp + getLockPeriod();\\n unchecked {\\n ++LibFacetStorage.lockStorage().nonce;\\n }\\n LibAppStorage.setLock(unlockTime, LockFacet.lock.selector);\\n emit Locked(uint64(unlockTime));\\n }\\n\\n /**\\n * @notice Locks the account when the account is locked. This function can be called by anyone but must provide the approver address and signature.\\n * The approver should be one of the guardians or owner.\\n * @dev This method takes the approver address and the signature. After validating the address and the signature, it unlocks the account immediately.\\n * Only one of the guardian or owner is required to lock and unlock the account.\\n * @param _approver Address of approver approving the unlock of Barz account\\n * @param _signature Signature of the approver that signed the msg hash for unlocking the account\\n */\\n function unlock(\\n address _approver,\\n bytes calldata _signature\\n ) external override onlyWhenLocked {\\n if (_approver != address(this) && !LibGuardian.isGuardian(_approver))\\n revert LockFacet__InvalidApprover();\\n if (\\n !SignatureChecker.isValidSignatureNow(\\n _approver,\\n getUnlockHash(),\\n _signature\\n )\\n ) revert LockFacet__InvalidSignature();\\n _unlock();\\n }\\n\\n /**\\n * @notice Unlocks the account and increments the lock nonce\\n */\\n function _unlock() private {\\n if (s.locks[INNER_STRUCT].locker != LockFacet.lock.selector)\\n revert LockFacet__CannotUnlock();\\n unchecked {\\n ++LibFacetStorage.lockStorage().nonce;\\n }\\n LibAppStorage.setLock(0, bytes4(0));\\n emit Unlocked();\\n }\\n\\n /**\\n * @notice Returns the lock period of current Barz account. Lock period information is held by Security Manager\\n * @return lockPeriod Uint value of lock period in seconds\\n */\\n function getLockPeriod() public view override returns (uint256 lockPeriod) {\\n lockPeriod = securityManager.lockPeriodOf(address(this));\\n if (lockPeriod == 0) revert LockFacet__InvalidRecoveryPeriod();\\n }\\n\\n /**\\n * @notice Returns if the account is locked or not\\n * @dev This method fetches the current block timestamp and compares that with release time.\\n * After checking the timestamp and release time, it returns if the account is still locked or not.\\n * @return isLocked_ Uint value of lock period in seconds\\n */\\n function isLocked() public view override returns (bool isLocked_) {\\n isLocked_ = uint64(block.timestamp) < s.locks[INNER_STRUCT].release;\\n }\\n\\n /**\\n * @notice Calculates the unlock hash and returns the unlock hash safe from signature reply attack\\n * @dev This method calculates the unlock hash with EIP-191 prefix, wallet address, chainID, and nonce\\n * It packs the result and packs them and hashes it.\\n * @return unlockHash Bytes32 unlock hash\\n */\\n function getUnlockHash() public view override returns (bytes32 unlockHash) {\\n unlockHash = keccak256(\\n abi.encodePacked(\\n \\\"\\\\x19Ethereum Signed Message:\\\\n32\\\",\\n keccak256(\\n abi.encode(\\n \\\"Unlock\\\",\\n address(this),\\n block.chainid,\\n lockNonce()\\n )\\n )\\n )\\n );\\n }\\n\\n /**\\n * @notice Returns lock nonce of account. Reads nonce from lock storage within facet storage\\n * @return lockNonce_ Uint128 value of lock nonce. This is incremented whenever the account is lock/unlocked\\n */\\n function lockNonce() public view override returns (uint128 lockNonce_) {\\n lockNonce_ = LibFacetStorage.lockStorage().nonce;\\n }\\n\\n /**\\n * @notice Returns the overall information of current lock\\n * @return pendingLock Struct value including all information of pending lock\\n */\\n function getPendingLock()\\n public\\n view\\n override\\n returns (Lock memory pendingLock)\\n {\\n pendingLock = s.locks[INNER_STRUCT];\\n }\\n}\\n\"\n },\n \"contracts/facets/Modifiers.sol\": {\n \"content\": \"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {LibGuardian} from \\\"../libraries/LibGuardian.sol\\\";\\nimport {BarzStorage} from \\\"../libraries/LibAppStorage.sol\\\";\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\n\\n/**\\n * @title Modifiers\\n * @dev Responsible for providing modifiers/util functions to Facet contracts\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\nabstract contract Modifiers is BarzStorage {\\n uint8 constant INNER_STRUCT = 0;\\n\\n error CallerNotGuardian();\\n error CallerNotGuardianOrOwner();\\n error DuplicateApprover();\\n error ZeroApproverLength();\\n error UnregisteredFacetAndSelectors();\\n\\n /**\\n * @notice Modifier to only allow guardian to make a call, reverts if any other entity is the caller\\n */\\n modifier onlyGuardian() {\\n if (!LibGuardian.isGuardian(msg.sender)) revert CallerNotGuardian();\\n _;\\n }\\n\\n /**\\n * @notice Modifier to only allow guardian or owner to make a call, reverts if any other entity is the caller\\n */\\n modifier onlyGuardianOrOwner() {\\n if (!LibGuardian.isGuardian(msg.sender) && address(this) != msg.sender)\\n revert CallerNotGuardianOrOwner();\\n _;\\n }\\n\\n /**\\n * @notice Checks if the approver address is the array is unique with no duplicate\\n * @dev This method loops through the array and checks if a duplicate address exists, it reverts if duplicate address exists\\n * @param approvers Array of address\\n */\\n function _checkApprover(\\n address[] memory approvers\\n ) internal pure returns (bool) {\\n uint256 approverLength = approvers.length;\\n if (0 == approverLength) revert ZeroApproverLength();\\n for (uint256 i; i < approverLength - 1; ) {\\n for (uint256 j = i + 1; j < approverLength; ) {\\n if (approvers[i] == approvers[j]) {\\n revert DuplicateApprover(); // Found a duplicate\\n }\\n unchecked {\\n ++j;\\n }\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n return false; // No duplicates found\\n }\\n\\n /**\\n * @notice Checks if the facet getting added or replaced is registered to facet registry\\n * @dev This method loops through the cut and checks if the facet getting added/replaced is registered to facet registry\\n * @param _diamondCut Array of FacetCut, data for diamondCut defined in EIP-2535\\n */\\n function _checkFacetCutValidity(\\n IDiamondCut.FacetCut[] memory _diamondCut\\n ) internal view {\\n uint256 diamondCutLength = _diamondCut.length;\\n for (uint256 i; i < diamondCutLength; ) {\\n if (\\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Add ||\\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Replace\\n ) {\\n if (\\n !s.facetRegistry.areFacetFunctionSelectorsRegistered(\\n _diamondCut[i].facetAddress,\\n _diamondCut[i].functionSelectors\\n )\\n ) revert UnregisteredFacetAndSelectors();\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n}\\n\"\n },\n \"contracts/facets/ReentrancyGuard.sol\": {\n \"content\": \"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {LibReentrancyGuardStorage, ReentrancyGuardStorage} from \\\"../libraries/LibReentrancyGuardStorage.sol\\\";\\n\\nabstract contract ReentrancyGuard {\\n\\n uint256 private constant _NOT_ENTERED = 0;\\n uint256 private constant _ENTERED = 1;\\n\\n error ReentrancyGuard__ReentrantCall();\\n\\n modifier nonReentrant() {\\n ReentrancyGuardStorage storage rgs = LibReentrancyGuardStorage.reentrancyguardStorage();\\n\\n if (rgs.status == _ENTERED) revert ReentrancyGuard__ReentrantCall();\\n\\n rgs.status = _ENTERED;\\n\\n _; // Execute function\\n\\n rgs.status = _NOT_ENTERED;\\n }\\n}\\n\"\n },\n \"contracts/facets/RestrictionsFacet.sol\": {\n \"content\": \"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {ReentrancyGuard} from \\\"./ReentrancyGuard.sol\\\";\\nimport {LibDiamond} from \\\"../libraries/LibDiamond.sol\\\";\\nimport {LibAppStorage} from \\\"../libraries/LibAppStorage.sol\\\";\\nimport {LibFacetStorage, RestrictionsStorage} from \\\"../libraries/LibFacetStorage.sol\\\";\\nimport {IRestriction} from \\\"../restrictions/IRestriction.sol\\\";\\nimport {IRestrictionsFacet} from \\\"./interfaces/IRestrictionsFacet.sol\\\";\\n\\n/**\\n * @title Restrictions facet\\n * @dev Responsible for storing and verifying different kinds of restrictions, for example:\\n * - Whitelist / Blacklist\\n * - Daily limits\\n * - Trading time restrictions\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\ncontract RestrictionsFacet is IRestrictionsFacet, ReentrancyGuard {\\n /**\\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\\n */\\n constructor() {\\n LibAppStorage.enforceRestrictionsInitialize();\\n }\\n\\n /**\\n * @notice Intialize restrictions of Barz. Restrictions facet call restriction contracts for restriction validation\\n * before each call\\n * @param _restrictions The initial array of restrictions.\\n * @return initSuccess Int value showing if the initialization of restriction is successful\\n */\\n function initializeRestrictions(\\n address[] calldata _restrictions\\n ) public override returns (uint256 initSuccess) {\\n LibDiamond.enforceIsSelf();\\n LibAppStorage.enforceRestrictionsInitialize();\\n\\n if (_restrictions.length == 0) {\\n // You can't initialize RestrictionsFacet with an empty list of restrictions\\n revert RestrictionsFacet__EmptyRestrictionsList();\\n }\\n for (uint256 i; i < _restrictions.length; ) {\\n if (_restrictions[i] == address(0))\\n revert RestrictionsFacet__ZeroAddressRestrictions();\\n unchecked {\\n ++i;\\n }\\n }\\n\\n LibFacetStorage.restrictionsStorage().restrictions = _restrictions;\\n _updateRestrictionsMap(_restrictions, true);\\n initSuccess = 1;\\n }\\n\\n /**\\n * @notice Unitialize restrictions of Barz\\n * @return uninitSuccess Int value showing if the initialization of restriction is successful\\n */\\n function uninitializeRestrictions()\\n external\\n override\\n returns (uint256 uninitSuccess)\\n {\\n LibDiamond.enforceIsSelf();\\n LibAppStorage.setRestrictionsUninitialized();\\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\\n .restrictionsStorage();\\n _updateRestrictionsMap(restrictionsStorage.restrictions, false);\\n restrictionsStorage.restrictions = new address[](0);\\n uninitSuccess = 1;\\n }\\n\\n /**\\n * @notice Returns the list of Restrictions contract address\\n * @return restrictions Addresses of IRestriction which are currently active\\n */\\n function getRestrictions()\\n public\\n view\\n override\\n returns (address[] memory restrictions)\\n {\\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\\n .restrictionsStorage();\\n restrictions = restrictionsStorage.restrictions;\\n }\\n\\n /**\\n * @notice Adds restrictions to Barz with validation on the restriction contract address.\\n * This method is only callable by the owner(self).\\n * @param _restriction The address of the restriction to be added.\\n */\\n function addRestriction(address _restriction) external override {\\n LibDiamond.enforceIsSelf();\\n if (LibDiamond.restrictionsFacet() == address(0))\\n revert RestrictionsFacet__ZeroAddressRestrictionsFacet();\\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\\n .restrictionsStorage();\\n if (_restriction == address(0))\\n revert RestrictionsFacet__ZeroAddressRestrictions();\\n if (restrictionsStorage.exists[_restriction])\\n revert RestrictionsFacet__RestrictionAlreadyExists();\\n\\n restrictionsStorage.restrictions.push(_restriction);\\n restrictionsStorage.exists[_restriction] = true;\\n\\n emit RestrictionAdded(_restriction);\\n }\\n\\n /**\\n * @notice Remove restrictions from Barz if it existed. This method is only callable by the owner(self).\\n * @param _restriction The address of the restriction to be removed.\\n */\\n function removeRestriction(address _restriction) external override {\\n LibDiamond.enforceIsSelf();\\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\\n .restrictionsStorage();\\n\\n if (!restrictionsStorage.exists[_restriction])\\n revert RestrictionsFacet__RestrictionNotFound();\\n\\n address[] storage restrictions = restrictionsStorage.restrictions;\\n\\n uint256 indexToDelete = restrictions.length;\\n uint256 restrictionsLen = restrictions.length;\\n for (uint256 i; i < restrictionsLen; ) {\\n if (restrictions[i] == _restriction) {\\n indexToDelete = i;\\n break;\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n\\n if (indexToDelete == 0 && restrictionsLen == 1) {\\n revert RestrictionsFacet__RemainingRestrictionsCantBeEmpty();\\n } else if (indexToDelete == restrictionsLen) {\\n revert RestrictionsFacet__RestrictionNotFound();\\n } else {\\n restrictions[indexToDelete] = restrictions[restrictionsLen - 1];\\n restrictions.pop();\\n }\\n\\n restrictionsStorage.exists[_restriction] = false;\\n emit RestrictionRemoved(_restriction);\\n }\\n\\n /**\\n * @notice Sets the restrictions address value mapping to true or false when adding/removing restriction contracts\\n * @param _restrictions List of restriction contracts address\\n * @param _newValue Bool value to flag to the list of restrictions contracts\\n */\\n function _updateRestrictionsMap(\\n address[] memory _restrictions,\\n bool _newValue\\n ) internal {\\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\\n .restrictionsStorage();\\n\\n uint restrictionsLen = _restrictions.length;\\n for (uint256 i; i < restrictionsLen; ) {\\n restrictionsStorage.exists[_restrictions[i]] = _newValue;\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * @dev Iterates over all restrictions and verifies each of them with the transaction parameters.\\n * @param _from The address of the sender, that will be signing the transaction.\\n * @param _to The receiving address.\\n * @param _value Amount of ETH to transfer from sender to recipient.\\n * @param _calldata Optional field to include arbitrary data.\\n * @return 0 if all the checks passed, 1 otherwise.\\n */\\n function verifyRestrictions(\\n address _from,\\n address _to,\\n uint256 _value,\\n bytes calldata _calldata\\n ) external nonReentrant returns (uint256) {\\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\\n .restrictionsStorage();\\n\\n uint restrictionsLen = restrictionsStorage.restrictions.length;\\n for (uint256 i; i < restrictionsLen; ) {\\n IRestriction restriction = IRestriction(\\n restrictionsStorage.restrictions[i]\\n );\\n bool checkPassed = restriction.check(_from, _to, _value, _calldata);\\n if (!checkPassed) {\\n return 1;\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n\\n return 0;\\n }\\n}\\n\"\n },\n \"contracts/facets/SignatureMigrationFacet.sol\": {\n \"content\": \"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {SignatureChecker} from \\\"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\\\";\\nimport {LibAppStorage} from \\\"../libraries/LibAppStorage.sol\\\";\\nimport {LibFacetStorage, SignatureMigrationStorage, SignatureMigrationConfig, SignatureMigrationApprovalConfig, ApprovalConfig} from \\\"../libraries/LibFacetStorage.sol\\\";\\nimport {LibDiamond} from \\\"../libraries/LibDiamond.sol\\\";\\nimport {LibGuardian} from \\\"../libraries/LibGuardian.sol\\\";\\nimport {LibLoupe} from \\\"../libraries/LibLoupe.sol\\\";\\nimport {Modifiers} from \\\"./Modifiers.sol\\\";\\nimport {ISecurityManager} from \\\"../infrastructure/interfaces/ISecurityManager.sol\\\";\\nimport {IDiamondCut} from \\\"./base/interfaces/IDiamondCut.sol\\\";\\nimport {IVerificationFacet} from \\\"./interfaces/IVerificationFacet.sol\\\";\\nimport {ISignatureMigrationFacet} from \\\"./interfaces/ISignatureMigrationFacet.sol\\\";\\n\\n/**\\n * @title Signature Migration Facet\\n * @dev Responsible for migrating user signature scheme to a new scheme user sets\\n * Which could include\\n * - ECDSA on Secp256K1 Curve\\n * - ECDSA on Secp256R1 Curve\\n * - BLS, Schnorr, etc\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract SignatureMigrationFacet is ISignatureMigrationFacet, Modifiers {\\n bytes constant UNINIT_CALL =\\n abi.encodeWithSignature(\\\"uninitializeSigner()\\\");\\n ISecurityManager public immutable securityManager;\\n\\n /**\\n * @notice This modifier verifies if the public key format matches with the new verification facet\\n * @param _publicKey Bytes of public key to be validated for the new verification facet\\n * @param _newVerificationFacet Address of new verification facet\\n */\\n modifier validateKeyType(\\n bytes memory _publicKey,\\n address _newVerificationFacet\\n ) {\\n if (\\n !IVerificationFacet(_newVerificationFacet).isValidKeyType(\\n _publicKey\\n )\\n ) revert SignatureMigrationFacet__InvalidKeyType();\\n _;\\n }\\n\\n /**\\n * @notice This constructor sets the Security Manager address which is an immutable variable.\\n * Immutable variables do not impact the storage of diamond\\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\\n */\\n constructor(address _securityManager) {\\n securityManager = ISecurityManager(_securityManager);\\n }\\n\\n // IMPORTANT NOTE: In the client side when they call this function, the func selectors should be sorted in ascending order\\n // to prevent different hash with same items in the array\\n /**\\n * @notice Moves the state of migration to a pending state. When pending state is over after pending period time,\\n * Migration can be finalized. This function can only be called by self and when the account is unlocked.\\n * @dev This method checks if the caller is self and if guardians exists. It migrates signature request to a pending state\\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\\n */\\n function migrateSignatureScheme(\\n address _newVerificationFacet,\\n bytes calldata _newPublicKey,\\n bytes4[] calldata _newVerificationFuncSelectors\\n )\\n public\\n override\\n onlyWhenUnlocked\\n validateKeyType(_newPublicKey, _newVerificationFacet)\\n {\\n // Only self contract can call this function\\n LibDiamond.enforceIsSelf();\\n // Should revert if guardian exist\\n if (0 != LibGuardian.guardianCount())\\n revert SignatureMigrationFacet__InvalidRouteWithGuardian();\\n {\\n _checkMigrationCutValidity(\\n _newVerificationFacet,\\n _newVerificationFuncSelectors\\n );\\n }\\n _migrateSignatureScheme(\\n _newVerificationFacet,\\n _newPublicKey,\\n _newVerificationFuncSelectors\\n );\\n }\\n\\n // NOTE: Migration requires a pending period & confirmation from owner to prevent a\\n // single call changing the ownership of the wallet\\n /**\\n * @notice Migrate signature scheme when guardians exists. Verifies the signature of guardians and moves migration to pending state.\\n * Which can then be finalized when pending period is over. Owner's approval is mandatory for migration to happen\\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\\n * @param _approvers List of approvers. This could include owner\\n */\\n function migrateSignatureSchemeWithGuardian(\\n address _newVerificationFacet,\\n bytes calldata _newPublicKey,\\n bytes4[] calldata _newVerificationFuncSelectors,\\n address[] calldata _approvers,\\n bytes[] calldata _signatures\\n )\\n public\\n override\\n onlyWhenUnlocked\\n validateKeyType(_newPublicKey, _newVerificationFacet)\\n {\\n // Should revert if does not guardian exist\\n if (0 == LibGuardian.guardianCount())\\n revert SignatureMigrationFacet__InvalidRouteWithGuardian();\\n if (_approvers.length != _signatures.length)\\n revert SignatureMigrationFacet__InvalidArrayLength();\\n\\n {\\n _checkMigrationCutValidity(\\n _newVerificationFacet,\\n _newVerificationFuncSelectors\\n );\\n }\\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\\n _newPublicKey,\\n _newVerificationFacet,\\n _newVerificationFuncSelectors,\\n \\\"MigrateSignature\\\"\\n );\\n\\n _checkApprover(_approvers);\\n _checkDuplicateOnChainApprover(migrationPublicKeyHash, _approvers);\\n\\n bool onChainOwnerApproval = getMigrationOwnerApprovalWithTimeValidity(\\n migrationPublicKeyHash\\n );\\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\\n\\n if (\\n _approvers.length +\\n getMigrationApprovalCountWithTimeValidity(\\n migrationPublicKeyHash\\n ) <\\n LibGuardian.majorityOfGuardians() + threshold\\n ) revert SignatureMigrationFacet__InsufficientApprovers();\\n {\\n // To prevent Stack too deep\\n bool ownerApproved;\\n for (uint256 i; i < _approvers.length; ) {\\n if (\\n !LibGuardian.isGuardian(_approvers[i]) &&\\n address(this) != _approvers[i]\\n ) revert SignatureMigrationFacet__InvalidGuardian();\\n if (_approvers[i] == address(this)) {\\n if (onChainOwnerApproval)\\n revert SignatureMigrationFacet__OwnerAlreadyApproved();\\n ownerApproved = true;\\n }\\n if (\\n !SignatureChecker.isValidSignatureNow(\\n _approvers[i],\\n migrationPublicKeyHash,\\n _signatures[i]\\n )\\n ) revert SignatureMigrationFacet__InvalidApproverSignature();\\n unchecked {\\n ++i;\\n }\\n }\\n\\n if (!ownerApproved && !onChainOwnerApproval)\\n revert SignatureMigrationFacet__LackOfOwnerApproval();\\n }\\n _migrateSignatureScheme(\\n _newVerificationFacet,\\n _newPublicKey,\\n _newVerificationFuncSelectors\\n );\\n }\\n\\n /**\\n * @notice Internal function that moves signature mgiration to a pending state.\\n * @dev This method increments migration nonce and sets the migration in the migration config. Emits events for migration execution\\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\\n */\\n function _migrateSignatureScheme(\\n address _newVerificationFacet,\\n bytes memory _newPublicKey,\\n bytes4[] memory _newVerificationFuncSelectors\\n ) internal {\\n SignatureMigrationStorage storage ms = LibFacetStorage\\n .migrationStorage();\\n unchecked {\\n ++ms.nonce;\\n }\\n uint64 migrateAfter = uint64(block.timestamp + getMigrationPeriod());\\n\\n ms.migrationConfigs[INNER_STRUCT] = SignatureMigrationConfig(\\n _newPublicKey,\\n _newVerificationFacet,\\n _newVerificationFuncSelectors,\\n migrateAfter\\n );\\n\\n emit SignatureMigrationExecuted(\\n _newVerificationFacet,\\n _newPublicKey,\\n _newVerificationFuncSelectors,\\n migrateAfter\\n );\\n }\\n\\n /**\\n * @notice Approves signature scheme migration on-chain. This can be called by owner or guardian only when the account is unlocked.\\n * When the threshold of the migration approval passed and owner approval is granted, it automatically moves migration to a pending state\\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\\n */\\n function approveSignatureSchemeMigration(\\n address _newVerificationFacet,\\n bytes calldata _newPublicKey,\\n bytes4[] calldata _newVerificationFuncSelectors\\n )\\n public\\n override\\n onlyGuardianOrOwner\\n onlyWhenUnlocked\\n validateKeyType(_newPublicKey, _newVerificationFacet)\\n {\\n {\\n _checkMigrationCutValidity(\\n _newVerificationFacet,\\n _newVerificationFuncSelectors\\n );\\n }\\n\\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\\n .migrationStorage()\\n .migrationApprovalConfigs[INNER_STRUCT];\\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\\n _newPublicKey,\\n _newVerificationFacet,\\n _newVerificationFuncSelectors,\\n \\\"MigrateSignature\\\"\\n );\\n uint64 approvalValidUntil = uint64(\\n block.timestamp + getApprovalValidationPeriod()\\n );\\n ms.isMigrationApproved[migrationPublicKeyHash][\\n msg.sender\\n ] = ApprovalConfig(true, approvalValidUntil);\\n emit SignatureMigrationApproved(\\n _newPublicKey,\\n _newVerificationFacet,\\n _newVerificationFuncSelectors,\\n msg.sender,\\n approvalValidUntil\\n );\\n if (\\n getMigrationApprovalCountWithTimeValidity(migrationPublicKeyHash) >=\\n LibGuardian.majorityOfGuardians() &&\\n getMigrationOwnerApprovalWithTimeValidity(migrationPublicKeyHash)\\n )\\n _migrateSignatureScheme(\\n _newVerificationFacet,\\n _newPublicKey,\\n _newVerificationFuncSelectors\\n );\\n }\\n\\n /**\\n * @notice Revokes the approval of signature migration done on-chain. Emits revoke event when revoked.\\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\\n */\\n function revokeSignatureMigrationApproval(\\n address _newVerificationFacet,\\n bytes calldata _newPublicKey,\\n bytes4[] calldata _newVerificationFuncSelectors\\n )\\n external\\n override\\n onlyGuardianOrOwner\\n onlyWhenUnlocked\\n validateKeyType(_newPublicKey, _newVerificationFacet)\\n {\\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\\n .migrationStorage()\\n .migrationApprovalConfigs[INNER_STRUCT];\\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\\n _newPublicKey,\\n _newVerificationFacet,\\n _newVerificationFuncSelectors,\\n \\\"MigrateSignature\\\"\\n );\\n if (!isMigrationApproved(migrationPublicKeyHash, msg.sender))\\n revert SignatureMigrationFacet__CannotRevokeUnapproved();\\n\\n ms.isMigrationApproved[migrationPublicKeyHash][\\n msg.sender\\n ] = ApprovalConfig(false, 0);\\n emit SignatureMigrationApprovalRevoked(\\n _newPublicKey,\\n _newVerificationFacet,\\n _newVerificationFuncSelectors,\\n msg.sender\\n );\\n }\\n\\n /**\\n * @notice Finalizes the pending signature scheme migration. This function can only be called by owner.\\n * It removes the facets of the previous verification facet and adds the new verification facet.\\n * After finalizing migration, it emits migration event which shows the change of the verification facet\\n */\\n function finalizeSignatureMigration() external override {\\n // NOTE: Only owner can call this function\\n LibDiamond.enforceIsSelf();\\n\\n SignatureMigrationStorage storage ms = LibFacetStorage\\n .migrationStorage();\\n\\n if (!isMigrationPending())\\n revert SignatureMigrationFacet__NonexistentMigration();\\n\\n if (\\n uint64(block.timestamp) <=\\n ms.migrationConfigs[INNER_STRUCT].migrateAfter\\n ) revert SignatureMigrationFacet__MigrationPeriodNotOver();\\n address newVerificationFacet = ms\\n .migrationConfigs[INNER_STRUCT]\\n .migrationVerificationFacet;\\n bytes4[] memory newVerificationFuncSelectors = ms\\n .migrationConfigs[INNER_STRUCT]\\n .migrationSelectors;\\n bytes memory newPublicKey = ms\\n .migrationConfigs[INNER_STRUCT]\\n .migrationPublicKey;\\n\\n address prevVerificationFacet = LibLoupe.facetAddress(\\n s.validateOwnerSignatureSelector\\n );\\n if (prevVerificationFacet == address(0))\\n revert SignatureMigrationFacet__NonExistentVerificationFacet();\\n\\n IDiamondCut.FacetCut[] memory UninitCut;\\n IDiamondCut.FacetCut[] memory InitCut;\\n {\\n bytes4[] memory prevVerificationFuncSelectors = LibLoupe\\n .facetFunctionSelectors(prevVerificationFacet);\\n\\n UninitCut = new IDiamondCut.FacetCut[](1);\\n InitCut = new IDiamondCut.FacetCut[](1);\\n UninitCut[0] = IDiamondCut.FacetCut({\\n facetAddress: address(0),\\n action: IDiamondCut.FacetCutAction.Remove,\\n functionSelectors: prevVerificationFuncSelectors\\n });\\n InitCut[0] = IDiamondCut.FacetCut({\\n facetAddress: newVerificationFacet,\\n action: IDiamondCut.FacetCutAction.Add,\\n functionSelectors: newVerificationFuncSelectors\\n });\\n {\\n IDiamondCut.FacetCut[]\\n memory facetCuts = new IDiamondCut.FacetCut[](2);\\n facetCuts[0] = UninitCut[0];\\n facetCuts[1] = InitCut[0];\\n _checkFacetCutValidity(facetCuts);\\n }\\n LibAppStorage.initiateSignerMigration();\\n address verificationFacet = address(\\n bytes20(\\n LibDiamond.diamondStorage().facets[\\n s.validateOwnerSignatureSelector\\n ]\\n )\\n );\\n\\n (bool uninitSuccess, bytes memory uninitResult) = verificationFacet\\n .delegatecall(UNINIT_CALL);\\n if (!uninitSuccess || uint256(bytes32(uninitResult)) != 1)\\n revert SignatureMigrationFacet__SignerUninitializationFailure();\\n LibAppStorage.finalizeSignerMigration();\\n\\n LibDiamond.diamondCut(UninitCut, address(0), \\\"\\\");\\n }\\n {\\n bytes memory initCall = abi.encodeWithSignature(\\n \\\"initializeSigner(bytes)\\\",\\n newPublicKey\\n );\\n\\n // Every Verification Facet should comply with initializeSigner(bytes)\\n // to be compatible with the Barz contract(for initialization)\\n LibDiamond.diamondCut(InitCut, address(0), \\\"\\\");\\n (bool initSuccess, bytes memory initResult) = newVerificationFacet\\n .delegatecall(initCall);\\n if (!initSuccess || uint256(bytes32(initResult)) != 1)\\n revert SignatureMigrationFacet__SignerInitializationFailure();\\n\\n emit SignatureSchemeMigration(\\n prevVerificationFacet,\\n newVerificationFacet,\\n newPublicKey,\\n newVerificationFuncSelectors\\n );\\n }\\n }\\n\\n /**\\n * @notice Approve cancellation of signature migration. If cancellation approval passes guardian threshold with owner approval\\n * it automatically cancels the migration.\\n * @dev This method checks if the caller is one of guardian or owner and sets true for the cancellation hash in the approval config.\\n * It internally calls _cancelSignatureMigration for canceling the migration\\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\\n */\\n function approveCancelSignatureMigration(\\n address _newVerificationFacet,\\n bytes calldata _newPublicKey,\\n bytes4[] calldata _newVerificationFuncSelectors\\n )\\n external\\n override\\n onlyGuardianOrOwner\\n onlyWhenUnlocked\\n validateKeyType(_newPublicKey, _newVerificationFacet)\\n {\\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\\n .migrationStorage()\\n .migrationApprovalConfigs[INNER_STRUCT];\\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\\n _newPublicKey,\\n _newVerificationFacet,\\n _newVerificationFuncSelectors,\\n \\\"CancelSignatureMigration\\\"\\n );\\n uint64 approvalValidUntil = uint64(\\n block.timestamp + getApprovalValidationPeriod()\\n );\\n ms.isMigrationApproved[migrationPublicKeyHash][\\n msg.sender\\n ] = ApprovalConfig(true, approvalValidUntil);\\n emit SignatureMigrationCancellationApproved(\\n _newVerificationFacet,\\n _newPublicKey,\\n _newVerificationFuncSelectors\\n );\\n if (\\n getMigrationApprovalCountWithTimeValidity(migrationPublicKeyHash) >=\\n LibGuardian.majorityOfGuardians() &&\\n getMigrationOwnerApprovalWithTimeValidity(migrationPublicKeyHash)\\n )\\n _cancelSignatureMigration(\\n _newVerificationFacet,\\n _newPublicKey,\\n _newVerificationFuncSelectors\\n );\\n }\\n\\n /**\\n * @notice Verifies the signature of guardians/owner and cancels the signature migration.\\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\\n * @param _approvers List of approvers. This could include owner\\n */\\n function cancelSignatureMigration(\\n address _newVerificationFacet,\\n bytes calldata _newPublicKey,\\n bytes4[] calldata _newVerificationFuncSelectors,\\n address[] calldata _approvers,\\n bytes[] calldata _signatures\\n )\\n external\\n override\\n validateKeyType(_newPublicKey, _newVerificationFacet)\\n onlyWhenUnlocked\\n {\\n if (_approvers.length != _signatures.length)\\n revert SignatureMigrationFacet__InvalidArrayLength();\\n\\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\\n _newPublicKey,\\n _newVerificationFacet,\\n _newVerificationFuncSelectors,\\n \\\"CancelSignatureMigration\\\"\\n );\\n\\n _checkApprover(_approvers);\\n _checkDuplicateOnChainApprover(migrationPublicKeyHash, _approvers);\\n\\n bool onChainOwnerApproval = getMigrationOwnerApprovalWithTimeValidity(\\n migrationPublicKeyHash\\n );\\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\\n if (\\n _approvers.length +\\n getMigrationApprovalCountWithTimeValidity(\\n migrationPublicKeyHash\\n ) <\\n LibGuardian.majorityOfGuardians() + threshold\\n ) revert SignatureMigrationFacet__InsufficientApprovers();\\n {\\n // To prevent stack too deep\\n bool ownerApproved;\\n for (uint256 i; i < _approvers.length; ) {\\n if (\\n !LibGuardian.isGuardian(_approvers[i]) &&\\n address(this) != _approvers[i]\\n ) revert SignatureMigrationFacet__NonExistentApprover();\\n if (_approvers[i] == address(this)) {\\n if (onChainOwnerApproval)\\n revert SignatureMigrationFacet__OwnerAlreadyApproved();\\n ownerApproved = true;\\n }\\n if (\\n !SignatureChecker.isValidSignatureNow(\\n _approvers[i],\\n migrationPublicKeyHash,\\n _signatures[i]\\n )\\n ) revert SignatureMigrationFacet__InvalidApproverSignature();\\n unchecked {\\n ++i;\\n }\\n }\\n if (!ownerApproved && !onChainOwnerApproval)\\n revert SignatureMigrationFacet__LackOfOwnerApproval();\\n }\\n _cancelSignatureMigration(\\n _newVerificationFacet,\\n _newPublicKey,\\n _newVerificationFuncSelectors\\n );\\n }\\n\\n /**\\n * @notice Internal function that cancels signature migration.\\n * @dev This method increments migration nonce and deletes the migration from the migration config. Emits events for migration cancellation\\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\\n */\\n function _cancelSignatureMigration(\\n address _newVerificationFacet,\\n bytes memory _newPublicKey,\\n bytes4[] memory _newVerificationFuncSelectors\\n ) internal {\\n if (!isMigrationPending())\\n revert SignatureMigrationFacet__NonexistentMigration();\\n SignatureMigrationStorage storage ms = LibFacetStorage\\n .migrationStorage();\\n unchecked {\\n ++ms.nonce;\\n }\\n delete ms.migrationConfigs[INNER_STRUCT];\\n emit SignatureMigrationCanceled(\\n _newVerificationFacet,\\n _newPublicKey,\\n _newVerificationFuncSelectors\\n );\\n }\\n\\n /**\\n * @notice Checks if the facets to be added from new verification facet is registered to facet registry\\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\\n */\\n function _checkMigrationCutValidity(\\n address _newVerificationFacet,\\n bytes4[] memory _newVerificationFuncSelectors\\n ) internal view {\\n IDiamondCut.FacetCut[] memory facetCuts = new IDiamondCut.FacetCut[](1);\\n facetCuts[0] = IDiamondCut.FacetCut({\\n facetAddress: _newVerificationFacet,\\n action: IDiamondCut.FacetCutAction.Add,\\n functionSelectors: _newVerificationFuncSelectors\\n });\\n _checkFacetCutValidity(facetCuts);\\n }\\n\\n /**\\n * @notice Returns if the migration is pending of not\\n * @dev This method fetches the migration storage and checks if the migrate after is above 0 value\\n * @return isPending Bool value that shows if the migration is pending\\n */\\n function isMigrationPending()\\n public\\n view\\n override\\n returns (bool isPending)\\n {\\n SignatureMigrationStorage storage rs = LibFacetStorage\\n .migrationStorage();\\n isPending = rs.migrationConfigs[INNER_STRUCT].migrateAfter > 0;\\n }\\n\\n /**\\n * @notice Returns the migration hash. This function ensures that this hash is safe from replay attack by including\\n * public key, verification facet, function selectors, salt, address, chainId, and nonce.\\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\\n * @param _saltString Salt value for generating the migration hash\\n * @return migrationKeyHash Bytes32 string of the migration key hash\\n */\\n function getApprovalMigrationKeyHash(\\n bytes memory _newPublicKey,\\n address _newVerificationFacet,\\n bytes4[] memory _newVerificationFuncSelectors,\\n string memory _saltString\\n ) public view override returns (bytes32 migrationKeyHash) {\\n migrationKeyHash = keccak256(\\n abi.encodePacked(\\n \\\"\\\\x19Ethereum Signed Message:\\\\n32\\\",\\n keccak256(\\n abi.encode(\\n _newPublicKey,\\n _newVerificationFacet,\\n keccak256(abi.encode(_newVerificationFuncSelectors)),\\n _saltString,\\n address(this),\\n block.chainid,\\n LibFacetStorage.migrationStorage().nonce\\n )\\n )\\n )\\n );\\n }\\n\\n /**\\n * @notice Checks if the owner approved the hash for migration\\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\\n * @return isApprovedByOwner Bool value of showing if the owner approved it or not\\n */\\n function getMigrationOwnerApprovalWithTimeValidity(\\n bytes32 _migrationPublicKeyHash\\n ) public view override returns (bool isApprovedByOwner) {\\n isApprovedByOwner = isMigrationApproved(\\n _migrationPublicKeyHash,\\n address(this)\\n );\\n }\\n\\n /**\\n * @notice Checks how many of the guardians approved the migration hash\\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\\n * @return approvalCount Number of approvals\\n */\\n function getMigrationApprovalCountWithTimeValidity(\\n bytes32 _migrationPublicKeyHash\\n ) public view override returns (uint256 approvalCount) {\\n address[] memory guardians = LibGuardian.getGuardians();\\n uint256 guardiansLength = guardians.length;\\n for (uint256 i; i < guardiansLength; ) {\\n if (isMigrationApproved(_migrationPublicKeyHash, guardians[i])) {\\n unchecked {\\n ++approvalCount;\\n }\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n return approvalCount;\\n }\\n\\n /**\\n * @notice Checks if the migration is approved by the given approver\\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\\n * @param _approver Address of approver\\n * @return isApproved Bool value if migration hash is approved\\n */\\n function isMigrationApproved(\\n bytes32 _migrationPublicKeyHash,\\n address _approver\\n ) public view override returns (bool isApproved) {\\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\\n .migrationStorage()\\n .migrationApprovalConfigs[INNER_STRUCT];\\n isApproved = (ms\\n .isMigrationApproved[_migrationPublicKeyHash][_approver].isApproved &&\\n block.timestamp <\\n ms\\n .isMigrationApproved[_migrationPublicKeyHash][_approver]\\n .validUntil);\\n }\\n\\n /**\\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\\n * Approvers who approved on-chain should not be included in the off-chain approval\\n * @param _migrationPublicKeyHash Hash of migration information\\n * @param _approvers List of approver addresses\\n */\\n function _checkDuplicateOnChainApprover(\\n bytes32 _migrationPublicKeyHash,\\n address[] memory _approvers\\n ) public view {\\n address[] memory guardians = LibGuardian.getGuardians();\\n uint256 guardianLength = guardians.length;\\n uint256 approversLength = _approvers.length;\\n for (uint256 i; i < guardianLength; ) {\\n if (isMigrationApproved(_migrationPublicKeyHash, guardians[i])) {\\n for (uint256 j; j < approversLength; ) {\\n if (_approvers[j] == guardians[i])\\n revert SignatureMigrationFacet__DuplicateApproval();\\n unchecked {\\n ++j;\\n }\\n }\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * @notice Returns the migration period of this wallet\\n * @dev This method fetches the migration period from the security manager\\n * @return migrationPeriod Migration period of Barz contract fetched from security manager\\n */\\n function getMigrationPeriod()\\n internal\\n view\\n returns (uint128 migrationPeriod)\\n {\\n migrationPeriod = securityManager.migrationPeriodOf(address(this));\\n if (migrationPeriod == 0)\\n revert SignatureMigrationFacet__InvalidMigrationPeriod();\\n }\\n\\n /**\\n * @notice Returns the validation period of this wallet\\n * @dev This method fetches the validation period from the security manager\\n * @return approvalValidationPeriod Validation period of Barz contract fetched from security manager\\n */\\n function getApprovalValidationPeriod()\\n internal\\n view\\n returns (uint256 approvalValidationPeriod)\\n {\\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\\n address(this)\\n );\\n if (approvalValidationPeriod == 0)\\n revert SignatureMigrationFacet__InvalidApprovalValidationPeriod();\\n }\\n\\n /**\\n * @notice Returns the migration nonce of this wallet\\n * @dev This method fetches the nonce from migration storage\\n * @return migrationNonce Nonce of migration to protect from reply attacks\\n */\\n function getMigrationNonce()\\n public\\n view\\n override\\n returns (uint128 migrationNonce)\\n {\\n migrationNonce = LibFacetStorage.migrationStorage().nonce;\\n }\\n\\n /**\\n * @notice Returns the migration configuration of this wallet\\n * @dev This method fetches the migration config from the migration storage\\n * @return pendingMigrationConfig Migration config currently pending for signature migration\\n */\\n function getPendingMigration()\\n external\\n view\\n override\\n returns (SignatureMigrationConfig memory pendingMigrationConfig)\\n {\\n pendingMigrationConfig = LibFacetStorage\\n .migrationStorage()\\n .migrationConfigs[INNER_STRUCT];\\n }\\n}\\n\"\n },\n \"contracts/facets/TokenReceiverFacet.sol\": {\n \"content\": \"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IERC721Receiver} from \\\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\\\";\\nimport {IERC777Recipient} from \\\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\\\";\\nimport {IERC1155Receiver} from \\\"../interfaces/ERC/IERC1155Receiver.sol\\\";\\nimport {IERC677Receiver} from \\\"../interfaces/ERC/IERC677Receiver.sol\\\";\\n\\n/**\\n * @title TokenReceiver Facet\\n * @dev Contract that enables receiving ERC721/ERC1155/ERC777/ERC677 Tokens with safe transfer\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract TokenReceiverFacet is\\n IERC721Receiver,\\n IERC1155Receiver,\\n IERC777Recipient,\\n IERC677Receiver\\n{\\n /**\\n * @notice Handles ERC721 Token callback.\\n * return Standardized onERC721Received return value.\\n */\\n function onERC721Received(\\n address,\\n address,\\n uint256,\\n bytes calldata\\n ) external pure override returns (bytes4) {\\n return IERC721Receiver.onERC721Received.selector;\\n }\\n\\n /**\\n * @notice Handles ERC1155 Token callback.\\n * return Standardized onERC1155Received return value.\\n */\\n function onERC1155Received(\\n address,\\n address,\\n uint256,\\n uint256,\\n bytes calldata\\n ) external pure override returns (bytes4) {\\n return IERC1155Receiver.onERC1155Received.selector;\\n }\\n\\n /**\\n * @notice Handles ERC1155 Token batch callback.\\n * return Standardized onERC1155BatchReceived return value.\\n */\\n function onERC1155BatchReceived(\\n address,\\n address,\\n uint256[] calldata,\\n uint256[] calldata,\\n bytes calldata\\n ) external pure override returns (bytes4) {\\n return IERC1155Receiver.onERC1155BatchReceived.selector;\\n }\\n\\n /**\\n * @notice Handles ERC777 Token callback.\\n * Does not return value, empty implementation.\\n */\\n function tokensReceived(\\n address,\\n address,\\n address,\\n uint256,\\n bytes calldata,\\n bytes calldata\\n ) external pure override {}\\n\\n /**\\n * @notice Handles ERC677 Token callback.\\n * return true.\\n */\\n function onTokenTransfer(\\n address,\\n uint256,\\n bytes calldata\\n ) external pure override returns (bool) {\\n return true;\\n }\\n}\\n\"\n },\n \"contracts/facets/verification/MultiSigFacet.sol\": {\n \"content\": \"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {ECDSA} from \\\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\\\";\\nimport {SignatureChecker} from \\\"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\\\";\\nimport {UserOperation} from \\\"../../aa-4337/interfaces/UserOperation.sol\\\";\\nimport {LibDiamond} from \\\"../../libraries/LibDiamond.sol\\\";\\nimport {LibLoupe} from \\\"../../libraries/LibLoupe.sol\\\";\\nimport {LibAppStorage} from \\\"../../libraries/LibAppStorage.sol\\\";\\nimport {LibMultiSigStorage, MultiSigStorage} from \\\"../../libraries/LibMultiSigStorage.sol\\\";\\nimport {IERC1271} from \\\"../../interfaces/ERC/IERC1271.sol\\\";\\nimport {IVerificationFacet} from \\\"../interfaces/IVerificationFacet.sol\\\";\\nimport {IMultiSigFacet} from \\\"../interfaces/IMultiSigFacet.sol\\\";\\n\\n/**\\n * @title Multi-sig facet\\n * @dev Multi-signature Facet with custom threshold.\\n * Wallet that adds this facet becomes a multi-sig wallet.\\n * Reference signature_format.md documentation for Multi-sig facet details\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract MultiSigFacet is IMultiSigFacet, IVerificationFacet, IERC1271 {\\n using ECDSA for bytes32;\\n\\n address public immutable self;\\n\\n address internal constant SENTINEL_OWNERS = address(0x1);\\n uint256 internal constant ADDRESS = 20;\\n uint256 internal constant SIG_TYPE = 1;\\n uint256 internal constant SIG_LEN = 4;\\n uint256 internal constant THRESHOLD = 4;\\n uint256 internal constant INVALID_SIG = 1;\\n uint256 internal constant VALID_SIG = 0;\\n\\n /**\\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\\n */\\n constructor() {\\n LibAppStorage.enforceSignerInitialize();\\n self = address(this);\\n }\\n\\n /**\\n * @notice Initializes the signer in Multisig Facet Storage. This can only be called when the account is uninitialized or during signature migration.\\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\\n * It checks if the public key is in the right format and initializes signer storage in k1 storage.\\n * @param _owners Bytes of owner public key\\n * @return initSuccess Uint value representing the success of init operation\\n */\\n function initializeSigner(\\n bytes calldata _owners\\n ) public override returns (uint256 initSuccess) {\\n LibAppStorage.enforceSignerInitialize();\\n\\n if (!isValidKeyType(_owners)) revert MultiSigFacet__InvalidInitData();\\n\\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\\n\\n uint256 threshold = uint256(uint32(bytes4(_owners)));\\n uint256 ownerCount = (_owners.length - THRESHOLD) / ADDRESS;\\n\\n if (threshold == 0) revert MultiSigFacet__InvalidThreshold();\\n if (ownerCount == 0) revert MultisigFacet__InvalidOwnerCount();\\n\\n address currentOwner = SENTINEL_OWNERS;\\n uint256 ptr = THRESHOLD;\\n address owner_;\\n for (uint256 i; i < ownerCount; ) {\\n owner_ = address(bytes20(_owners[ptr:ptr + ADDRESS]));\\n ptr += ADDRESS;\\n if (\\n owner_ == address(0) ||\\n owner_ == SENTINEL_OWNERS ||\\n owner_ == address(this) ||\\n owner_ == currentOwner\\n ) revert MultiSigFacet__InvalidOwnerAddress();\\n if (ms.owners[owner_] != address(0))\\n revert MultiSigFacet__DuplicateOwner();\\n\\n ms.owners[currentOwner] = owner_;\\n currentOwner = owner_;\\n\\n unchecked {\\n ++i;\\n }\\n }\\n ms.owners[currentOwner] = SENTINEL_OWNERS;\\n ms.ownerCount = ownerCount;\\n ms.threshold = threshold;\\n\\n bytes4 validateSelector = validateOwnerSignatureSelector();\\n\\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\\n if (LibLoupe.facetAddress(validateSelector) != self)\\n revert VerificationFacet__InvalidFacetMapping();\\n\\n // initialize verification function selector\\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\\n\\n initSuccess = 1;\\n\\n emit SignerInitialized(_owners);\\n }\\n\\n /**\\n * @notice Uninitialize signer in K1 Facet Storage. This can only be called when the account is undergoing signature migration\\n * and has already been initialized.\\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\\n * @return uninitSuccess Uint value representing the success of uninit operation\\n */\\n function uninitializeSigner()\\n external\\n override\\n returns (uint256 uninitSuccess)\\n {\\n LibAppStorage.enforceSignerMigration();\\n LibAppStorage.setSignerUninitialized();\\n\\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\\n ++ms.counter;\\n address[] memory ownerlist = getOwners();\\n uint256 ownerlistLength = ownerlist.length;\\n for (uint256 i; i < ownerlistLength; ) {\\n ms.owners[ownerlist[i]] = address(0);\\n unchecked {\\n ++i;\\n }\\n }\\n ms.owners[SENTINEL_OWNERS] = address(0);\\n\\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\\n\\n uninitSuccess = 1;\\n\\n emit SignerUninitialized();\\n }\\n\\n /**\\n * @notice Validates if the user operation is signed by the owner.\\n * @dev This method validates if the user operation is signed by the owner. It internally calls checkSignatures with\\n * user operation hash and signature together with the threshold.\\n * @param userOp UserOperation including all information for execution\\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\\n */\\n function validateOwnerSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) public view override returns (uint256 validationData) {\\n // Data 1 is invalid, Data 0 is valid\\n validationData = checkSignatures(\\n userOpHash,\\n userOp.signature,\\n LibMultiSigStorage.multisigStorage().threshold\\n );\\n }\\n\\n /**\\n * @notice Returns the selector of function to validate the signature of UserOperation\\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\\n */\\n function validateOwnerSignatureSelector()\\n public\\n pure\\n override\\n returns (bytes4 ownerSignatureValidatorSelector)\\n {\\n return this.validateOwnerSignature.selector;\\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\\n }\\n\\n /**\\n * @notice Returns the owner of the account\\n * @return signer Bytes of owner address\\n */\\n function owner() public view override returns (bytes memory) {\\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\\n\\n uint totalLength = ms.ownerCount * ADDRESS;\\n bytes memory result = new bytes(totalLength);\\n\\n // populate return array\\n uint256 index;\\n address currentOwner = ms.owners[SENTINEL_OWNERS];\\n while (currentOwner != SENTINEL_OWNERS) {\\n assembly {\\n mstore(\\n add(result, add(32, mul(index, ADDRESS))),\\n shl(96, currentOwner)\\n )\\n }\\n currentOwner = ms.owners[currentOwner];\\n index++;\\n }\\n\\n return result;\\n }\\n\\n /**\\n * @notice Validates if the format of public key is valid for this verification facet\\n * @dev For this Secp256k1Verification Facet, the public key should comply with the format in the signature_format.md doc\\n * @param _publicKey Bytes of public key for format check\\n * @return isValid Boolean variable representing if the format of public key is valid\\n */\\n function isValidKeyType(\\n bytes memory _publicKey\\n ) public pure override returns (bool isValid) {\\n uint256 publicKeyLength = _publicKey.length;\\n if (\\n publicKeyLength < ADDRESS + THRESHOLD ||\\n (publicKeyLength - THRESHOLD) % ADDRESS != 0\\n ) return false;\\n\\n uint256 threshold = uint256(uint32(bytes4(_publicKey)));\\n uint256 ownerCount = (publicKeyLength - THRESHOLD) / ADDRESS;\\n\\n isValid = !(ownerCount < threshold || threshold == 0);\\n }\\n\\n /**\\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\\n * @param _hash Hash value the owner signed\\n * @param _signature Signature that signed the above hash\\n * @return magicValue Bytes4 value representing the success/failure of validation\\n */\\n function isValidSignature(\\n bytes32 _hash,\\n bytes calldata _signature\\n ) public view override returns (bytes4 magicValue) {\\n magicValue = (checkSignatures(\\n _hash,\\n _signature,\\n LibMultiSigStorage.multisigStorage().threshold\\n ) == VALID_SIG)\\n ? this.isValidSignature.selector\\n : bytes4(0xffffffff);\\n }\\n\\n /**\\n * @notice Validates the format of the signature and verifies if the signature is signed by the expected key.\\n * Reference signature_format.md doc for details about signature format and signature types\\n * @param _dataHash Bytes value of data hash signed by the owners\\n * @param _signatures Bytes value of signature which should comply with signature format\\n * @param _threshold Uint256 value of current Multi-sig Barz's threshold\\n */\\n function checkSignatures(\\n bytes32 _dataHash,\\n bytes calldata _signatures,\\n uint256 _threshold\\n ) public view returns (uint256) {\\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\\n\\n address lastOwner = address(0);\\n address currentOwner;\\n bytes memory signature;\\n uint256 signatureType;\\n uint256 nextOffset;\\n uint256 i;\\n for (i; i < _threshold; ) {\\n (\\n currentOwner,\\n signature,\\n signatureType,\\n nextOffset\\n ) = splitSignatures(_signatures, nextOffset);\\n if (nextOffset == 0 && i + 1 < _threshold) return INVALID_SIG;\\n if (signatureType == 1) {\\n // If signatureType is 1 then it is default dataHash signed.\\n // This also includes the contract signature\\n if (\\n !SignatureChecker.isValidSignatureNow(\\n currentOwner,\\n _dataHash,\\n signature\\n )\\n ) return INVALID_SIG;\\n } else if (signatureType == 2) {\\n // If signatureType is 2 then it is an approved hash\\n if (ms.approvedHashes[ms.counter][currentOwner][_dataHash] == 0)\\n return INVALID_SIG;\\n } else if (signatureType == 3) {\\n // If signatureType is 3 then it is a signed message hash\\n // This also includes the contract signature\\n bytes32 msgHash = _dataHash.toEthSignedMessageHash();\\n if (\\n !SignatureChecker.isValidSignatureNow(\\n currentOwner,\\n msgHash,\\n signature\\n )\\n ) return INVALID_SIG;\\n } else revert MultiSigFacet__InvalidRoute();\\n if (\\n currentOwner <= lastOwner ||\\n ms.owners[currentOwner] == address(0) ||\\n currentOwner == SENTINEL_OWNERS\\n ) return INVALID_SIG;\\n lastOwner = currentOwner;\\n\\n unchecked {\\n ++i;\\n }\\n }\\n return VALID_SIG;\\n }\\n\\n /**\\n * @notice Split signatures into each individual signatures. Should comply with signature format to be split\\n * @param _signatures Bytes value of signature\\n * @param _nextOffset Uint256 value of next offset to start splitting the signature\\n */\\n function splitSignatures(\\n bytes calldata _signatures,\\n uint256 _nextOffset\\n )\\n public\\n pure\\n returns (\\n address owner_,\\n bytes memory signature,\\n uint256 signatureType,\\n uint256 nextOffset\\n )\\n {\\n uint256 signaturesLength = _signatures.length;\\n\\n if (signaturesLength <= _nextOffset + ADDRESS + SIG_LEN)\\n revert MultiSigFacet__InsufficientSignerLength();\\n\\n owner_ = address(\\n bytes20(_signatures[_nextOffset:_nextOffset + ADDRESS])\\n );\\n\\n signatureType = uint256(\\n uint8(\\n bytes1(\\n _signatures[_nextOffset + ADDRESS:_nextOffset +\\n ADDRESS +\\n SIG_TYPE]\\n )\\n )\\n );\\n\\n if (signatureType > 3 || signatureType == 0)\\n revert MultiSigFacet__InvalidSignatureType();\\n uint256 offSet = _nextOffset + ADDRESS + SIG_TYPE;\\n uint256 siglen = uint256(\\n uint32(bytes4(_signatures[offSet:offSet + SIG_LEN]))\\n );\\n if (offSet + siglen > signaturesLength)\\n revert MultiSigFacet__InvalidSignatureLength();\\n\\n offSet += SIG_LEN;\\n if (offSet + siglen == signaturesLength) nextOffset = 0;\\n else nextOffset = offSet + siglen;\\n\\n signature = _signatures[offSet:offSet + siglen];\\n }\\n\\n /**\\n * @notice Approves the hash of userOperation on-chain. This can only be called by owners.\\n * @param _hashToApprove Bytes value of UserOperation hash to approve\\n */\\n function approveHash(bytes32 _hashToApprove) external {\\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\\n\\n if (ms.owners[msg.sender] == address(0))\\n revert MultiSigFacet__OnlyOwner();\\n\\n ms.approvedHashes[ms.counter][msg.sender][_hashToApprove] = 1;\\n emit HashApproved(_hashToApprove, msg.sender);\\n }\\n\\n /**\\n * @notice Add owner to Barz. Update thresold if threshold is given different from current threshold\\n * @dev This can only be done via a Self call.\\n * @param _newOwner Address of new owner to be added\\n * @param _threshold Uint256 value of threshold\\n */\\n function addOwner(address _newOwner, uint256 _threshold) external {\\n LibDiamond.enforceIsSelf();\\n\\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\\n\\n if (\\n _newOwner == address(0) ||\\n _newOwner == SENTINEL_OWNERS ||\\n _newOwner == address(this)\\n ) revert MultiSigFacet__InvalidOwnerAddress();\\n if (ms.owners[_newOwner] != address(0))\\n revert MultiSigFacet__DuplicateOwner();\\n\\n ms.owners[_newOwner] = ms.owners[SENTINEL_OWNERS];\\n ms.owners[SENTINEL_OWNERS] = _newOwner;\\n ++ms.ownerCount;\\n emit OwnerAdded(_newOwner);\\n\\n if (ms.threshold != _threshold) changeThreshold(_threshold);\\n }\\n\\n /**\\n * @notice Remove owner from Barz. Update thresold if threshold is given different from current threshold\\n * @dev This can only be done via a Self call.\\n * @param _prevOwner Address of owner located right behind the removed owner address in the linked list\\n * @param _removedOwner Address of owner to be removed\\n * @param _threshold Uint256 value of threshold\\n */\\n function removeOwner(\\n address _prevOwner,\\n address _removedOwner,\\n uint256 _threshold\\n ) external {\\n LibDiamond.enforceIsSelf();\\n\\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\\n\\n if (ms.ownerCount - 1 < _threshold)\\n revert MultiSigFacet__InvalidThreshold();\\n if (_removedOwner == address(0) || _removedOwner == SENTINEL_OWNERS)\\n revert MultiSigFacet__InvalidOwnerAddress();\\n if (ms.owners[_prevOwner] != _removedOwner)\\n revert MultiSigFacet__InvalidOwnerPair();\\n\\n ms.owners[_prevOwner] = ms.owners[_removedOwner];\\n ms.owners[_removedOwner] = address(0);\\n --ms.ownerCount;\\n emit OwnerRemoved(_removedOwner);\\n\\n if (ms.threshold != _threshold) changeThreshold(_threshold);\\n }\\n\\n /**\\n * @notice Swap owner in Barz.\\n * @dev This can only be done via a Self call.\\n * @param _prevOwner Address of owner located right behind the removed owner address in the linked list\\n * @param _oldOwner Address of owner to be removed\\n * @param _newOwner Address of owner to be added\\n */\\n function swapOwner(\\n address _prevOwner,\\n address _oldOwner,\\n address _newOwner\\n ) public {\\n LibDiamond.enforceIsSelf();\\n\\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\\n\\n if (\\n _newOwner == address(0) ||\\n _newOwner == SENTINEL_OWNERS ||\\n _newOwner == address(this)\\n ) revert MultiSigFacet__InvalidOwnerAddress();\\n if (ms.owners[_newOwner] != address(0))\\n revert MultiSigFacet__DuplicateOwner();\\n if (_oldOwner == address(0) || _oldOwner == SENTINEL_OWNERS)\\n revert MultiSigFacet__InvalidOwnerAddress();\\n if (ms.owners[_prevOwner] != _oldOwner)\\n revert MultiSigFacet__InvalidOwnerPair();\\n\\n ms.owners[_newOwner] = ms.owners[_oldOwner];\\n ms.owners[_prevOwner] = _newOwner;\\n ms.owners[_oldOwner] = address(0);\\n emit OwnerRemoved(_oldOwner);\\n emit OwnerAdded(_newOwner);\\n }\\n\\n /**\\n * @notice Changes the threshold of the Barz to `_threshold`.\\n * @dev This can only be done via a Self call.\\n * @param _threshold New threshold\\n */\\n function changeThreshold(uint256 _threshold) public {\\n LibDiamond.enforceIsSelf();\\n\\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\\n\\n if (_threshold > ms.ownerCount || _threshold == 0)\\n revert MultiSigFacet__InvalidThreshold();\\n\\n ms.threshold = _threshold;\\n emit ThresholdChanged(_threshold);\\n }\\n\\n /**\\n * @notice Checks if the given address is owner\\n * @param _owner Address to be checked if it's owner\\n * @return isOwner_ Bool value showing if it's owner address\\n */\\n function isOwner(address _owner) public view returns (bool isOwner_) {\\n isOwner_ = (_owner != SENTINEL_OWNERS &&\\n LibMultiSigStorage.multisigStorage().owners[_owner] != address(0));\\n }\\n\\n /**\\n * @notice Returns the threshold of Barz\\n * @return threshold Threshold of the Barz account\\n */\\n function getThreshold() public view returns (uint256 threshold) {\\n threshold = LibMultiSigStorage.multisigStorage().threshold;\\n }\\n\\n /**\\n * @notice Returns the list of owner addresses\\n * @return owners List of owners\\n */\\n function getOwners() public view returns (address[] memory owners) {\\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\\n owners = new address[](ms.ownerCount);\\n\\n uint256 index;\\n address currentOwner = ms.owners[SENTINEL_OWNERS];\\n while (currentOwner != SENTINEL_OWNERS) {\\n owners[index] = currentOwner;\\n currentOwner = ms.owners[currentOwner];\\n index++;\\n }\\n }\\n\\n /**\\n * @notice Returns the previous owner in the linked list\\n * @param _owner Address of owner\\n * @return prevOwner Address of previous owner\\n */\\n function getPrevOwner(\\n address _owner\\n ) public view returns (address prevOwner) {\\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\\n\\n address currentOwner = ms.owners[SENTINEL_OWNERS];\\n if (currentOwner == _owner) return SENTINEL_OWNERS;\\n while (currentOwner != SENTINEL_OWNERS) {\\n if (ms.owners[currentOwner] == _owner) return currentOwner;\\n\\n currentOwner = ms.owners[currentOwner];\\n }\\n return address(0);\\n }\\n\\n /**\\n * @notice Returns of the owner is approved by given owner address\\n * @param _owner Address of owner\\n * @param _hash Hash of UserOperation\\n * @return isApproved Bool value showing if the hash is approved by owner\\n */\\n function isApprovedHash(\\n address _owner,\\n bytes32 _hash\\n ) public view returns (bool isApproved) {\\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\\n isApproved = (ms.approvedHashes[ms.counter][_owner][_hash] == 1);\\n }\\n}\\n\"\n },\n \"contracts/facets/verification/secp256k1/Secp256k1VerificationFacet.sol\": {\n \"content\": \"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {ECDSA} from \\\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\\\";\\nimport {UserOperation} from \\\"../../../aa-4337/interfaces/UserOperation.sol\\\";\\nimport {LibAppStorage} from \\\"../../../libraries/LibAppStorage.sol\\\";\\nimport {LibFacetStorage, Secp256k1VerificationStorage} from \\\"../../../libraries/LibFacetStorage.sol\\\";\\nimport {LibLoupe} from \\\"../../../libraries/LibLoupe.sol\\\";\\nimport {IERC1271} from \\\"../../../interfaces/ERC/IERC1271.sol\\\";\\nimport {IVerificationFacet} from \\\"../../interfaces/IVerificationFacet.sol\\\";\\n\\n/**\\n * @title Secp256k1 verification facet\\n * @dev Default Ethereum's elliptic curve\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\ncontract Secp256k1VerificationFacet is IVerificationFacet, IERC1271 {\\n using ECDSA for bytes32;\\n error Secp256k1VerificationFacet__InvalidSignerLength();\\n address public immutable self;\\n\\n /**\\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\\n */\\n constructor() {\\n LibAppStorage.enforceSignerInitialize();\\n self = address(this);\\n }\\n\\n /**\\n * @notice Initializes the signer in K1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\\n * @param _publicKey Bytes of owner public key\\n * @return initSuccess Uint value representing the success of init operation\\n */\\n function initializeSigner(\\n bytes calldata _publicKey\\n ) public override returns (uint256 initSuccess) {\\n LibAppStorage.enforceSignerInitialize();\\n if (!isValidKeyType(_publicKey))\\n revert Secp256k1VerificationFacet__InvalidSignerLength();\\n\\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\\n .k1Storage();\\n k1Storage.signer = address(uint160(uint256(keccak256(_publicKey[1:]))));\\n\\n bytes4 validateSelector = validateOwnerSignatureSelector();\\n\\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\\n if (LibLoupe.facetAddress(validateSelector) != self)\\n revert VerificationFacet__InvalidFacetMapping();\\n\\n // initialize verification function selector\\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\\n\\n initSuccess = 1;\\n\\n emit SignerInitialized(_publicKey);\\n }\\n\\n /**\\n * @notice Uninitialize signer in K1 Facet Storage. This can only be called when the account is undergoing signature migration\\n * and has already been initialized.\\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\\n * @return uninitSuccess Uint value representing the success of uninit operation\\n */\\n function uninitializeSigner()\\n external\\n override\\n returns (uint256 uninitSuccess)\\n {\\n LibAppStorage.enforceSignerMigration();\\n LibAppStorage.setSignerUninitialized();\\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\\n .k1Storage();\\n k1Storage.signer = address(0);\\n\\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\\n\\n uninitSuccess = 1;\\n\\n emit SignerUninitialized();\\n }\\n\\n /**\\n * @notice Validates if the user operation is signed by the owner.\\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\\n * signer public key.\\n * @param userOp UserOperation including all information for execution\\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\\n */\\n function validateOwnerSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) public view override returns (uint256 validationData) {\\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\\n .k1Storage();\\n validationData = validateSignature(\\n userOp,\\n userOpHash,\\n k1Storage.signer\\n );\\n }\\n\\n /**\\n * @notice Validates if the signature of UserOperation is signed by the given signer\\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\\n * @param userOp UserOperation including all information for execution\\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\\n * @param signer Address of signer who signed the contract, to be validated\\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\\n */\\n function validateSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n address signer\\n ) public pure returns (uint256 isValid) {\\n bytes32 hash = userOpHash.toEthSignedMessageHash();\\n isValid = (signer != hash.recover(userOp.signature)) ? 1 : 0;\\n }\\n\\n /**\\n * @notice Returns the selector of function to validate the signature of UserOperation\\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\\n */\\n function validateOwnerSignatureSelector()\\n public\\n pure\\n override\\n returns (bytes4 ownerSignatureValidatorSelector)\\n {\\n ownerSignatureValidatorSelector = this.validateOwnerSignature.selector;\\n // NOTE: The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\\n }\\n\\n /**\\n * @notice Returns the owner of the account\\n * @return signer Bytes of owner address\\n */\\n function owner() public view override returns (bytes memory signer) {\\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\\n .k1Storage();\\n signer = abi.encodePacked(k1Storage.signer);\\n }\\n\\n /**\\n * @notice Validates if the format of public key is valid for this verification facet\\n * @dev For this Secp256k1Verification Facet, the public key length should be 65 in an uncompressed public key format\\n * @param _publicKey Bytes of public key for format check\\n * @return isValid Boolean variable representing if the format of public key is valid\\n */\\n function isValidKeyType(\\n bytes memory _publicKey\\n ) public pure override returns (bool isValid) {\\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\\n }\\n\\n /**\\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\\n * @param _hash Hash value the owner signed\\n * @param _signature Signature that signed the above hash\\n * @return magicValue Bytes4 value representing the success/failure of validation\\n */\\n function isValidSignature(\\n bytes32 _hash,\\n bytes memory _signature\\n ) public view override returns (bytes4 magicValue) {\\n magicValue = (_hash.recover(_signature) ==\\n LibFacetStorage.k1Storage().signer)\\n ? this.isValidSignature.selector\\n : bytes4(0xffffffff);\\n }\\n}\\n\"\n },\n \"contracts/facets/verification/secp256r1/Secp256r1VerificationFacet.sol\": {\n \"content\": \"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {UserOperation} from \\\"../../../aa-4337/interfaces/UserOperation.sol\\\";\\nimport {LibAppStorage} from \\\"../../../libraries/LibAppStorage.sol\\\";\\nimport {LibLoupe} from \\\"../../../libraries/LibLoupe.sol\\\";\\nimport {LibFacetStorage, Secp256r1VerificationStorage} from \\\"../../../libraries/LibFacetStorage.sol\\\";\\nimport {Base64} from \\\"./utils/Base64.sol\\\";\\nimport {LibSecp256r1} from \\\"./utils/LibSecp256r1.sol\\\";\\nimport {IERC1271} from \\\"../../../interfaces/ERC/IERC1271.sol\\\";\\nimport {IVerificationFacet} from \\\"../../interfaces/IVerificationFacet.sol\\\";\\n\\n/**\\n * @title Secp256r1 verification facet\\n * @dev Primarily used to verify user ops signed with passkeys\\n * @author Ruslan Serebriakov (@rsrbk)\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract Secp256r1VerificationFacet is IVerificationFacet, IERC1271 {\\n error Secp256r1VerificationFacet__InvalidSignerLength();\\n address public immutable self;\\n\\n /**\\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\\n */\\n constructor() {\\n LibAppStorage.enforceSignerInitialize();\\n self = address(this);\\n }\\n\\n /**\\n * @notice Initializes the signer in R1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\\n * @param _publicKey Bytes of owner public key\\n * @return initSuccess Uint value representing the success of init operation\\n */\\n function initializeSigner(\\n bytes calldata _publicKey\\n ) public override returns (uint256 initSuccess) {\\n LibAppStorage.enforceSignerInitialize();\\n\\n if (!isValidKeyType(_publicKey))\\n revert Secp256r1VerificationFacet__InvalidSignerLength();\\n\\n bytes memory publicKeyCoordinates = _publicKey[1:];\\n uint256[2] memory q;\\n assembly {\\n // Copy the bytes from the input data into the uint256 array\\n mstore(q, mload(add(publicKeyCoordinates, 32)))\\n mstore(add(q, 32), mload(add(publicKeyCoordinates, 64)))\\n }\\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\\n .r1Storage();\\n r1Storage.q = q;\\n\\n bytes4 validateSelector = validateOwnerSignatureSelector();\\n\\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\\n if (LibLoupe.facetAddress(validateSelector) != self)\\n revert VerificationFacet__InvalidFacetMapping();\\n\\n // initialize verification function selector\\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\\n\\n initSuccess = 1;\\n\\n emit SignerInitialized(_publicKey);\\n }\\n\\n /**\\n * @notice Uninitialize signer in R1 Facet Storage. This can only be called when the account is undergoing signature migration\\n * and has already been initialized.\\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\\n * @return uninitSuccess Uint value representing the success of uninit operation\\n */\\n function uninitializeSigner()\\n external\\n override\\n returns (uint256 uninitSuccess)\\n {\\n LibAppStorage.enforceSignerMigration();\\n LibAppStorage.setSignerUninitialized();\\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\\n .r1Storage();\\n r1Storage.q = [0, 0];\\n\\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\\n\\n uninitSuccess = 1;\\n\\n emit SignerUninitialized();\\n }\\n\\n /**\\n * @notice Validates if the user operation is signed by the owner.\\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\\n * signer public key.\\n * @param userOp UserOperation including all information for execution\\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\\n */\\n function validateOwnerSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) public view override returns (uint256 validationData) {\\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\\n .r1Storage();\\n validationData = validateSignature(userOp, userOpHash, r1Storage.q);\\n }\\n\\n /**\\n * @notice Validates if the signature of UserOperation is signed by the given signer\\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\\n * @param userOp UserOperation including all information for execution\\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\\n * @param q Public Key of signer who signed the contract, to be validated\\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\\n */\\n function validateSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n uint256[2] memory q\\n ) public view returns (uint256 isValid) {\\n isValid = (_validateSignature(q, userOpHash, userOp.signature)) ? 0 : 1;\\n }\\n\\n /**\\n * @notice Returns the selector of function to validate the signature of UserOperation\\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\\n */\\n function validateOwnerSignatureSelector()\\n public\\n pure\\n override\\n returns (bytes4 ownerSignatureValidatorSelector)\\n {\\n return this.validateOwnerSignature.selector; // validateOwnerSignature(UserOperation calldata userOp,bytes32 userOpHash)\\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\\n }\\n\\n /**\\n * @notice Returns the owner of the account\\n * @return signer Bytes of owner address\\n */\\n function owner() public view override returns (bytes memory signer) {\\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\\n .r1Storage();\\n signer = abi.encodePacked(r1Storage.q);\\n }\\n\\n /**\\n * @notice Validates if the format of public key is valid for this verification facet\\n * @dev For this Secp256k1Verification Facet, the public key should in an uncompressed public key format\\n * @param _publicKey Bytes of public key for format check\\n * @return isValid Boolean variable representing if the format of public key is valid\\n */\\n function isValidKeyType(\\n bytes memory _publicKey\\n ) public pure override returns (bool isValid) {\\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\\n }\\n\\n /**\\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\\n * @param _hash Hash value the owner signed\\n * @param _signature Signature that signed the above hash\\n * @return magicValue Bytes4 value representing the success/failure of validation\\n */\\n function isValidSignature(\\n bytes32 _hash,\\n bytes memory _signature\\n ) public view override returns (bytes4 magicValue) {\\n magicValue = _validateSignature(\\n LibFacetStorage.r1Storage().q,\\n _hash,\\n _signature\\n )\\n ? this.isValidSignature.selector\\n : bytes4(0xffffffff);\\n }\\n\\n function _validateSignature(\\n uint256[2] memory q,\\n bytes32 _hash,\\n bytes memory _signature\\n ) internal view returns (bool) {\\n (\\n uint256 rValue,\\n uint256 sValue,\\n bytes memory authenticatorData,\\n string memory clientDataJSONPre,\\n string memory clientDataJSONPost\\n ) = abi.decode(_signature, (uint256, uint256, bytes, string, string));\\n bytes32 clientHash;\\n {\\n string memory opHashBase64 = Base64.encode(bytes.concat(_hash));\\n string memory clientDataJSON = string.concat(\\n clientDataJSONPre,\\n opHashBase64,\\n clientDataJSONPost\\n );\\n clientHash = sha256(bytes(clientDataJSON));\\n }\\n bytes32 sigHash = sha256(bytes.concat(authenticatorData, clientHash));\\n return LibSecp256r1.Verify(q, rValue, sValue, uint256(sigHash));\\n }\\n}\\n\"\n },\n \"contracts/facets/verification/secp256r1/utils/Base64.sol\": {\n \"content\": \"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @dev Provides a set of functions to operate with Base64 strings.\\n * modified for base64url https://datatracker.ietf.org/doc/html/rfc4648#section-5\\n * _Available since v4.5._\\n */\\nlibrary Base64 {\\n /**\\n * @dev Base64 Encoding/Decoding Table\\n */\\n string internal constant _TABLE =\\n \\\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_\\\";\\n\\n /**\\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\\n */\\n function encode(bytes memory data) internal pure returns (string memory) {\\n /**\\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\\n */\\n if (data.length == 0) return \\\"\\\";\\n\\n // Loads the table into memory\\n string memory table = _TABLE;\\n\\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\\n // and split into 4 numbers of 6 bits.\\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\\n // - `data.length + 2` -> Round up\\n // - `/ 3` -> Number of 3-bytes chunks\\n // - `4 *` -> 4 characters for each chunk\\n uint256 newlength = (data.length * 8) / 6;\\n if (data.length % 6 > 0) {\\n newlength++;\\n }\\n string memory result = new string(newlength);\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n // Prepare the lookup table (skip the first \\\"length\\\" byte)\\n let tablePtr := add(table, 1)\\n\\n // Prepare result pointer, jump over length\\n let resultPtr := add(result, 32)\\n\\n // Run over the input, 3 bytes at a time\\n for {\\n let dataPtr := data\\n let endPtr := add(data, mload(data))\\n } lt(dataPtr, endPtr) {\\n\\n } {\\n // Advance 3 bytes\\n dataPtr := add(dataPtr, 3)\\n let input := mload(dataPtr)\\n\\n // To write each character, shift the 3 bytes (18 bits) chunk\\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\\n // and apply logical AND with 0x3F which is the number of\\n // the previous character in the ASCII table prior to the Base64 Table\\n // The result is then added to the table to get the character to write,\\n // and finally write it in the result pointer but with a left shift\\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\\n\\n mstore8(\\n resultPtr,\\n mload(add(tablePtr, and(shr(18, input), 0x3F)))\\n )\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(\\n resultPtr,\\n mload(add(tablePtr, and(shr(12, input), 0x3F)))\\n )\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(\\n resultPtr,\\n mload(add(tablePtr, and(shr(6, input), 0x3F)))\\n )\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n }\\n }\\n\\n return result;\\n }\\n}\\n\"\n },\n \"contracts/facets/verification/secp256r1/utils/LibSecp256r1.sol\": {\n \"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n// Heavily inspired from\\n// https://github.com/maxrobot/elliptic-solidity/blob/master/contracts/Secp256r1.sol\\n// https://github.com/tdrerup/elliptic-curve-solidity/blob/master/contracts/curves/EllipticCurve.sol\\n// modified to use precompile 0x05 modexp\\n// and modified jacobian double\\n// optimisations to avoid to an from from affine and jacobian coordinates\\n\\n// Additional Elliptic curve Public key / Signature validation added by\\n// David Yonjun Kim (@Powerstream3604)\\n\\nstruct JPoint {\\n uint256 x;\\n uint256 y;\\n uint256 z;\\n}\\n\\nlibrary LibSecp256r1 {\\n uint256 constant gx =\\n 0x6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296;\\n uint256 constant gy =\\n 0x4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5;\\n uint256 public constant pp =\\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF;\\n\\n uint256 public constant nn =\\n 0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551;\\n uint256 constant a =\\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC;\\n uint256 constant b =\\n 0x5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B;\\n uint256 constant MOST_SIGNIFICANT =\\n 0xc000000000000000000000000000000000000000000000000000000000000000;\\n\\n /*\\n * Verify\\n * @description - verifies that a public key has signed a given message\\n * @param Q - public key coordinates X & Y\\n * @param R - signature half R\\n * @param S - signature half S\\n * @param input - hashed message\\n */\\n function Verify(\\n uint256[2] memory q,\\n uint r,\\n uint s,\\n uint e\\n ) internal view returns (bool) {\\n if (q[0] > pp - 1 || q[1] > pp - 1) {\\n return false;\\n }\\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\\n return false;\\n }\\n if (\\n mulmod(q[1], q[1], pp) !=\\n addmod(\\n addmod(\\n mulmod(q[0], mulmod(q[0], q[0], pp), pp),\\n mulmod(a, q[0], pp),\\n pp\\n ),\\n b,\\n pp\\n )\\n ) {\\n return false;\\n }\\n\\n JPoint[16] memory points = _preComputeJacobianPoints(q);\\n return VerifyWithPrecompute(points, r, s, e);\\n }\\n\\n function VerifyWithPrecompute(\\n JPoint[16] memory points,\\n uint r,\\n uint s,\\n uint e\\n ) internal view returns (bool) {\\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\\n return false;\\n }\\n\\n uint w = _primemod(s, nn);\\n\\n uint u1 = mulmod(e, w, nn);\\n uint u2 = mulmod(r, w, nn);\\n\\n uint x;\\n uint y;\\n\\n (x, y) = ShamirMultJacobian(points, u1, u2);\\n return (x == r);\\n }\\n\\n /*\\n * Strauss Shamir trick for EC multiplication\\n * https://stackoverflow.com/questions/50993471/ec-scalar-multiplication-with-strauss-shamir-method\\n * we optimise on this a bit to do with 2 bits at a time rather than a single bit\\n * the individual points for a single pass are precomputed\\n * overall this reduces the number of additions while keeping the same number of doublings\\n */\\n function ShamirMultJacobian(\\n JPoint[16] memory points,\\n uint u1,\\n uint u2\\n ) internal view returns (uint, uint) {\\n uint x = 0;\\n uint y = 0;\\n uint z = 0;\\n uint bits = 128;\\n uint index = 0;\\n\\n while (bits > 0) {\\n if (z > 0) {\\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\\n }\\n index =\\n ((u1 & MOST_SIGNIFICANT) >> 252) |\\n ((u2 & MOST_SIGNIFICANT) >> 254);\\n if (index > 0) {\\n (x, y, z) = _jAdd(\\n x,\\n y,\\n z,\\n points[index].x,\\n points[index].y,\\n points[index].z\\n );\\n }\\n u1 <<= 2;\\n u2 <<= 2;\\n bits--;\\n }\\n (x, y) = _affineFromJacobian(x, y, z);\\n return (x, y);\\n }\\n\\n function _preComputeJacobianPoints(\\n uint256[2] memory q\\n ) internal pure returns (JPoint[16] memory points) {\\n points[0] = JPoint(0, 0, 0);\\n points[1] = JPoint(q[0], q[1], 1); // u2\\n points[2] = _jPointDouble(points[1]);\\n points[3] = _jPointAdd(points[1], points[2]);\\n\\n points[4] = JPoint(gx, gy, 1); // u1Points[1]\\n points[5] = _jPointAdd(points[4], points[1]);\\n points[6] = _jPointAdd(points[4], points[2]);\\n points[7] = _jPointAdd(points[4], points[3]);\\n\\n points[8] = _jPointDouble(points[4]); // u1Points[2]\\n points[9] = _jPointAdd(points[8], points[1]);\\n points[10] = _jPointAdd(points[8], points[2]);\\n points[11] = _jPointAdd(points[8], points[3]);\\n\\n points[12] = _jPointAdd(points[4], points[8]); // u1Points[3]\\n points[13] = _jPointAdd(points[12], points[1]);\\n points[14] = _jPointAdd(points[12], points[2]);\\n points[15] = _jPointAdd(points[12], points[3]);\\n }\\n\\n function _jPointAdd(\\n JPoint memory p1,\\n JPoint memory p2\\n ) internal pure returns (JPoint memory) {\\n uint x;\\n uint y;\\n uint z;\\n (x, y, z) = _jAdd(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z);\\n return JPoint(x, y, z);\\n }\\n\\n function _jPointDouble(\\n JPoint memory p\\n ) internal pure returns (JPoint memory) {\\n uint x;\\n uint y;\\n uint z;\\n (x, y, z) = _modifiedJacobianDouble(p.x, p.y, p.z);\\n return JPoint(x, y, z);\\n }\\n\\n /* _affineFromJacobian\\n * @desription returns affine coordinates from a jacobian input follows\\n * golang elliptic/crypto library\\n */\\n function _affineFromJacobian(\\n uint x,\\n uint y,\\n uint z\\n ) internal view returns (uint ax, uint ay) {\\n if (z == 0) {\\n return (0, 0);\\n }\\n\\n uint zinv = _primemod(z, pp);\\n uint zinvsq = mulmod(zinv, zinv, pp);\\n\\n ax = mulmod(x, zinvsq, pp);\\n ay = mulmod(y, mulmod(zinvsq, zinv, pp), pp);\\n }\\n\\n /*\\n * _jAdd\\n * @description performs Jacobian addition as defined below:\\n * http://www.hyperelliptic.org/EFD/g1p/data/shortw/jacobian/addition/add-2007-bl\\n */\\n function _jAdd(\\n uint p1,\\n uint p2,\\n uint p3,\\n uint q1,\\n uint q2,\\n uint q3\\n ) internal pure returns (uint r1, uint r2, uint r3) {\\n if (p3 == 0) {\\n r1 = q1;\\n r2 = q2;\\n r3 = q3;\\n\\n return (r1, r2, r3);\\n } else if (q3 == 0) {\\n r1 = p1;\\n r2 = p2;\\n r3 = p3;\\n\\n return (r1, r2, r3);\\n }\\n\\n assembly {\\n let\\n pd\\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\\n let z1z1 := mulmod(p3, p3, pd) // Z1Z1 = Z1^2\\n let z2z2 := mulmod(q3, q3, pd) // Z2Z2 = Z2^2\\n\\n let u1 := mulmod(p1, z2z2, pd) // U1 = X1*Z2Z2\\n let u2 := mulmod(q1, z1z1, pd) // U2 = X2*Z1Z1\\n\\n let s1 := mulmod(p2, mulmod(z2z2, q3, pd), pd) // S1 = Y1*Z2*Z2Z2\\n let s2 := mulmod(q2, mulmod(z1z1, p3, pd), pd) // S2 = Y2*Z1*Z1Z1\\n\\n let p3q3 := addmod(p3, q3, pd)\\n\\n if lt(u2, u1) {\\n u2 := add(pd, u2) // u2 = u2+pd\\n }\\n let h := sub(u2, u1) // H = U2-U1\\n\\n let i := mulmod(0x02, h, pd)\\n i := mulmod(i, i, pd) // I = (2*H)^2\\n\\n let j := mulmod(h, i, pd) // J = H*I\\n if lt(s2, s1) {\\n s2 := add(pd, s2) // u2 = u2+pd\\n }\\n let rr := mulmod(0x02, sub(s2, s1), pd) // r = 2*(S2-S1)\\n r1 := mulmod(rr, rr, pd) // X3 = R^2\\n\\n let v := mulmod(u1, i, pd) // V = U1*I\\n let j2v := addmod(j, mulmod(0x02, v, pd), pd)\\n if lt(r1, j2v) {\\n r1 := add(pd, r1) // X3 = X3+pd\\n }\\n r1 := sub(r1, j2v)\\n\\n // Y3 = r*(V-X3)-2*S1*J\\n let s12j := mulmod(mulmod(0x02, s1, pd), j, pd)\\n\\n if lt(v, r1) {\\n v := add(pd, v)\\n }\\n r2 := mulmod(rr, sub(v, r1), pd)\\n\\n if lt(r2, s12j) {\\n r2 := add(pd, r2)\\n }\\n r2 := sub(r2, s12j)\\n\\n // Z3 = ((Z1+Z2)^2-Z1Z1-Z2Z2)*H\\n z1z1 := addmod(z1z1, z2z2, pd)\\n j2v := mulmod(p3q3, p3q3, pd)\\n if lt(j2v, z1z1) {\\n j2v := add(pd, j2v)\\n }\\n r3 := mulmod(sub(j2v, z1z1), h, pd)\\n }\\n return (r1, r2, r3);\\n }\\n\\n // Point doubling on the modified jacobian coordinates\\n // http://point-at-infinity.org/ecc/Prime_Curve_Modified_Jacobian_Coordinates.html\\n function _modifiedJacobianDouble(\\n uint x,\\n uint y,\\n uint z\\n ) internal pure returns (uint x3, uint y3, uint z3) {\\n if (y == 0) return (0, 0, 0);\\n assembly {\\n let\\n pd\\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\\n let z2 := mulmod(z, z, pd)\\n let az4 := mulmod(\\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC,\\n mulmod(z2, z2, pd),\\n pd\\n )\\n let y2 := mulmod(y, y, pd)\\n let s := mulmod(0x04, mulmod(x, y2, pd), pd)\\n let u := mulmod(0x08, mulmod(y2, y2, pd), pd)\\n let m := addmod(mulmod(0x03, mulmod(x, x, pd), pd), az4, pd)\\n let twos := mulmod(0x02, s, pd)\\n let m2 := mulmod(m, m, pd)\\n if lt(m2, twos) {\\n m2 := add(pd, m2)\\n }\\n x3 := sub(m2, twos)\\n if lt(s, x3) {\\n s := add(pd, s)\\n }\\n y3 := mulmod(m, sub(s, x3), pd)\\n if lt(y3, u) {\\n y3 := add(pd, y3)\\n }\\n y3 := sub(y3, u)\\n z3 := mulmod(0x02, mulmod(y, z, pd), pd)\\n }\\n }\\n\\n // Fermats little theorem https://en.wikipedia.org/wiki/Fermat%27s_little_theorem\\n // a^(p-1) = 1 mod p\\n // a^(-1) ≅ a^(p-2) (mod p)\\n // we then use the precompile bigModExp to compute a^(-1)\\n function _primemod(uint value, uint p) internal view returns (uint ret) {\\n ret = modexp(value, p - 2, p);\\n return ret;\\n }\\n\\n // Wrapper for built-in BigNumber_modexp (contract 0x5) as described here. https://github.com/ethereum/EIPs/pull/198\\n function modexp(\\n uint _base,\\n uint _exp,\\n uint _mod\\n ) internal view returns (uint ret) {\\n // bigModExp(_base, _exp, _mod);\\n assembly {\\n if gt(_base, _mod) {\\n _base := mod(_base, _mod)\\n }\\n // Free memory pointer is always stored at 0x40\\n let freemem := mload(0x40)\\n\\n mstore(freemem, 0x20)\\n mstore(add(freemem, 0x20), 0x20)\\n mstore(add(freemem, 0x40), 0x20)\\n\\n mstore(add(freemem, 0x60), _base)\\n mstore(add(freemem, 0x80), _exp)\\n mstore(add(freemem, 0xa0), _mod)\\n\\n let success := staticcall(14000, 0x5, freemem, 0xc0, freemem, 0x20)\\n switch success\\n case 0 {\\n revert(0x0, 0x0)\\n }\\n default {\\n ret := mload(freemem)\\n }\\n }\\n }\\n}\\n\"\n },\n \"contracts/infrastructure/DefaultFallbackHandler.sol\": {\n \"content\": \"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IERC721Receiver} from \\\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\\\";\\nimport {IERC1155Receiver} from \\\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\\\";\\nimport {IERC777Recipient} from \\\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\\\";\\nimport {BaseAccount} from \\\"../aa-4337/core/BaseAccount.sol\\\";\\nimport {DefaultLibDiamond} from \\\"../libraries/DefaultLibDiamond.sol\\\";\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IAccountFacet} from \\\"../facets/interfaces/IAccountFacet.sol\\\";\\nimport {IStorageLoupe} from \\\"../facets/base/interfaces/IStorageLoupe.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\nimport {IERC677Receiver} from \\\"../interfaces/ERC/IERC677Receiver.sol\\\";\\nimport {IERC165} from \\\"../interfaces/ERC/IERC165.sol\\\";\\n\\n/**\\n * @title DefaultFallbackHandler\\n * @dev A default fallback handler for Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract DefaultFallbackHandler is IDiamondLoupe {\\n /**\\n * @notice Sets the middleware diamond for Barz wallet as a fallback handler\\n * @dev This contract is also a diamond that holds the default facets to reduce gas cost for wallet activation.\\n * Within the constructor this conducts diamond cut to initially setup the diamond. This is a non-upgradeable contract\\n * @param _diamondCutFacet Address if diamond cut facet\\n * @param _accountFacet Address account facet\\n * @param _tokenReceiverFacet Address of token receiver facet\\n * @param _diamondLoupeFacet Address of diamond loupe facet\\n */\\n constructor(\\n address _diamondCutFacet,\\n address _accountFacet,\\n address _tokenReceiverFacet,\\n address _diamondLoupeFacet\\n ) payable {\\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](4);\\n bytes4[] memory functionSelectors = new bytes4[](1);\\n functionSelectors[0] = IDiamondCut.diamondCut.selector;\\n\\n bytes4[] memory accountFunctionSelectors = new bytes4[](5);\\n accountFunctionSelectors[0] = IAccountFacet.execute.selector;\\n accountFunctionSelectors[1] = IAccountFacet.executeBatch.selector;\\n accountFunctionSelectors[2] = BaseAccount.validateUserOp.selector;\\n accountFunctionSelectors[3] = BaseAccount.getNonce.selector;\\n accountFunctionSelectors[4] = BaseAccount.entryPoint.selector;\\n\\n bytes4[] memory receiverFacetSelectors = new bytes4[](5);\\n receiverFacetSelectors[0] = IERC721Receiver.onERC721Received.selector;\\n receiverFacetSelectors[1] = IERC1155Receiver.onERC1155Received.selector;\\n receiverFacetSelectors[2] = IERC1155Receiver\\n .onERC1155BatchReceived\\n .selector;\\n receiverFacetSelectors[3] = IERC777Recipient.tokensReceived.selector;\\n receiverFacetSelectors[4] = IERC677Receiver.onTokenTransfer.selector;\\n\\n bytes4[] memory loupeFacetSelectors = new bytes4[](9);\\n loupeFacetSelectors[0] = IDiamondLoupe.facets.selector;\\n loupeFacetSelectors[1] = IDiamondLoupe.facetFunctionSelectors.selector;\\n loupeFacetSelectors[2] = IDiamondLoupe.facetAddresses.selector;\\n loupeFacetSelectors[3] = IDiamondLoupe.facetAddress.selector;\\n loupeFacetSelectors[4] = IERC165.supportsInterface.selector;\\n loupeFacetSelectors[5] = IStorageLoupe.facetsFromStorage.selector;\\n loupeFacetSelectors[6] = IStorageLoupe\\n .facetFunctionSelectorsFromStorage\\n .selector;\\n loupeFacetSelectors[7] = IStorageLoupe\\n .facetAddressesFromStorage\\n .selector;\\n loupeFacetSelectors[8] = IStorageLoupe.facetAddressFromStorage.selector;\\n\\n {\\n cut[0] = IDiamondCut.FacetCut({\\n facetAddress: _diamondCutFacet,\\n action: IDiamondCut.FacetCutAction.Add,\\n functionSelectors: functionSelectors\\n });\\n cut[1] = IDiamondCut.FacetCut({\\n facetAddress: _accountFacet,\\n action: IDiamondCut.FacetCutAction.Add,\\n functionSelectors: accountFunctionSelectors\\n });\\n cut[2] = IDiamondCut.FacetCut({\\n facetAddress: _tokenReceiverFacet,\\n action: IDiamondCut.FacetCutAction.Add,\\n functionSelectors: receiverFacetSelectors\\n });\\n cut[3] = IDiamondCut.FacetCut({\\n facetAddress: _diamondLoupeFacet,\\n action: IDiamondCut.FacetCutAction.Add,\\n functionSelectors: loupeFacetSelectors\\n });\\n\\n DefaultLibDiamond.diamondCut(cut, address(0), \\\"\\\");\\n }\\n }\\n\\n /**\\n * @notice Returns the facet information of call facets registered to this diamond.\\n * @return facets_ The facet struct array including all facet information\\n */\\n function facets() external view override returns (Facet[] memory facets_) {\\n DefaultLibDiamond.DiamondStorage storage ds = DefaultLibDiamond\\n .diamondStorage();\\n uint256 numFacets = ds.facetAddresses.length;\\n facets_ = new Facet[](numFacets);\\n for (uint256 i; i < numFacets; ) {\\n address facetAddress_ = ds.facetAddresses[i];\\n facets_[i].facetAddress = facetAddress_;\\n facets_[i].functionSelectors = ds\\n .facetFunctionSelectors[facetAddress_]\\n .functionSelectors;\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * @notice Gets all the function selectors provided by a facet.\\n * @param _facet The facet address.\\n * @return facetFunctionSelectors_\\n */\\n function facetFunctionSelectors(\\n address _facet\\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\\n facetFunctionSelectors_ = DefaultLibDiamond\\n .diamondStorage()\\n .facetFunctionSelectors[_facet]\\n .functionSelectors;\\n }\\n\\n /**\\n * @notice Get all the facet addresses used by a diamond.\\n * @return facetAddresses_\\n */\\n function facetAddresses()\\n external\\n view\\n override\\n returns (address[] memory facetAddresses_)\\n {\\n facetAddresses_ = DefaultLibDiamond.diamondStorage().facetAddresses;\\n }\\n\\n /** @notice Gets the facet that supports the given selector.\\n * @dev If facet is not found return address(0).\\n * @param _functionSelector The function selector.\\n * @return facetAddress_ The facet address.\\n */\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view override returns (address facetAddress_) {\\n facetAddress_ = DefaultLibDiamond\\n .diamondStorage()\\n .selectorToFacetAndPosition[_functionSelector]\\n .facetAddress;\\n }\\n}\\n\"\n },\n \"contracts/infrastructure/FacetRegistry.sol\": {\n \"content\": \"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {Ownable2Step} from \\\"@openzeppelin/contracts/access/Ownable2Step.sol\\\";\\nimport {IFacetRegistry} from \\\"./interfaces/IFacetRegistry.sol\\\";\\n\\n/**\\n * @title Facet Registry\\n * @dev Contract to keep track of facets & function selectors addable to user wallets\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract FacetRegistry is IFacetRegistry, Ownable2Step {\\n mapping(address => FacetRegistryConfig) private facets;\\n\\n /**\\n * @notice Transfers the ownership of the contract to the given owner\\n * @param _owner Address of owner who has access to initialize the default security variables for security manager\\n */\\n constructor(address _owner) {\\n transferOwnership(_owner);\\n _transferOwnership(_owner);\\n }\\n\\n /**\\n * @dev Registers a facet and it's function selectors to registry\\n * @param _facet address of facet\\n * @param _facetSelectors list of function selectors of the facet\\n */\\n function registerFacetFunctionSelectors(\\n address _facet,\\n bytes4[] calldata _facetSelectors\\n ) external override onlyOwner {\\n FacetRegistryConfig storage facetConfig = facets[_facet];\\n for (uint256 i; i < _facetSelectors.length; ) {\\n if (facetConfig.info[_facetSelectors[i]].exists)\\n revert FacetRegistry__FacetSelectorAlreadyRegistered();\\n\\n facetConfig.info[_facetSelectors[i]].exists = true;\\n facetConfig.info[_facetSelectors[i]].index = uint128(\\n facetConfig.selectors.length\\n );\\n facetConfig.selectors.push(_facetSelectors[i]);\\n unchecked {\\n ++i;\\n }\\n }\\n emit FacetFunctionSelectorsRegistered(_facet, _facetSelectors);\\n }\\n\\n /**\\n * @dev Removes a registered facet and it's corresponding selectors from registry\\n * @param _facet address of facet\\n * @param _facetSelectors list of function selectors of the facet\\n */\\n function removeFacetFunctionSelectors(\\n address _facet,\\n bytes4[] calldata _facetSelectors\\n ) external override onlyOwner {\\n FacetRegistryConfig storage facetConfig = facets[_facet];\\n for (uint256 i; i < _facetSelectors.length; ) {\\n if (!facetConfig.info[_facetSelectors[i]].exists)\\n revert FacetRegistry__UnregisteredFacetSelector();\\n\\n bytes4 lastSelector = facetConfig.selectors[\\n facetConfig.selectors.length - 1\\n ];\\n if (_facetSelectors[i] != lastSelector) {\\n uint128 targetIndex = facetConfig\\n .info[_facetSelectors[i]]\\n .index;\\n facetConfig.selectors[targetIndex] = lastSelector;\\n facetConfig.info[lastSelector].index = targetIndex;\\n }\\n facetConfig.selectors.pop();\\n delete facetConfig.info[_facetSelectors[i]];\\n\\n unchecked {\\n ++i;\\n }\\n }\\n emit FacetFunctionSelectorsRemoved(_facet, _facetSelectors);\\n }\\n\\n /**\\n * @dev Checks if a facet and it's selectors given is registered to facet registry\\n * @param _facet Address of facet\\n * @param _facetSelectors List of function selectors of the facet\\n */\\n function areFacetFunctionSelectorsRegistered(\\n address _facet,\\n bytes4[] calldata _facetSelectors\\n ) external view override returns (bool) {\\n FacetRegistryConfig storage facetConfig = facets[_facet];\\n if (_facetSelectors.length == 0) return false;\\n for (uint256 i; i < _facetSelectors.length; ) {\\n if (!facetConfig.info[_facetSelectors[i]].exists) return false;\\n unchecked {\\n ++i;\\n }\\n }\\n return true;\\n }\\n\\n /**\\n * @dev Checks if a facet and it's selector given is registered to facet registry\\n * @param _facet Address of facet\\n * @param _facetSelector List of function selectors of the facet\\n * @return isRegistered Bool value showing if the selector is registered\\n */\\n function isFacetFunctionSelectorRegistered(\\n address _facet,\\n bytes4 _facetSelector\\n ) external view override returns (bool isRegistered) {\\n FacetRegistryConfig storage facetConfig = facets[_facet];\\n isRegistered = facetConfig.info[_facetSelector].exists;\\n }\\n\\n /**\\n * @dev Get the registered selectors of facet from registry\\n * @param _facet Address of facet\\n * @return selectors Selectors registered to facet\\n */\\n function getFacetFunctionSelectors(\\n address _facet\\n ) external view override returns (bytes4[] memory selectors) {\\n FacetRegistryConfig storage facetConfig = facets[_facet];\\n selectors = facetConfig.selectors;\\n }\\n}\\n\"\n },\n \"contracts/infrastructure/interfaces/IFacetRegistry.sol\": {\n \"content\": \"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Registry Interface\\n * @dev Interface for Facet Registry contract to keep track of facets & function selectors addable to user wallets\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IFacetRegistry {\\n struct FacetRegistryConfig {\\n bytes4[] selectors;\\n mapping(bytes4 => FacetInfo) info;\\n }\\n struct FacetInfo {\\n bool exists;\\n uint128 index;\\n }\\n\\n event FacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] facetSelectors\\n );\\n event FacetFunctionSelectorsRemoved(address facet, bytes4[] facetSelectors);\\n\\n error FacetRegistry__FacetSelectorAlreadyRegistered();\\n error FacetRegistry__UnregisteredFacetSelector();\\n\\n function registerFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function removeFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function areFacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external view returns (bool);\\n\\n function isFacetFunctionSelectorRegistered(\\n address facet,\\n bytes4 facetSelector\\n ) external view returns (bool);\\n\\n function getFacetFunctionSelectors(\\n address facet\\n ) external view returns (bytes4[] memory);\\n}\\n\"\n },\n \"contracts/infrastructure/interfaces/ISecurityManager.sol\": {\n \"content\": \"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Registry Interface\\n * @dev Infrastructure contract to manage security parameters of users\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\ninterface ISecurityManager {\\n error SecurityManager__OutOfBoundary();\\n error SecurityManager__CallerNotWallet();\\n error SecurityManager__AlreadyIntialized();\\n\\n function initializeAdditionSecurityPeriod(\\n uint128 defaultAdditionSecurityPeriod,\\n uint128 minAdditionSecurityPeriod,\\n uint128 maxAdditionSecurityPeriod\\n ) external;\\n\\n function initializeRemovalSecurityPeriod(\\n uint128 defaultRemovalSecurityPeriod,\\n uint128 minRemovalSecurityPeriod,\\n uint128 maxRemovalSecurityPeriod\\n ) external;\\n\\n function initializeApprovalValidationPeriod(\\n uint128 defaultApprovalValidationPeriod,\\n uint128 minApprovalValidationPeriod,\\n uint128 maxApprovalValidationPeriod\\n ) external;\\n\\n function initializeMigrationPeriod(\\n uint128 defaultMigrationPeriod,\\n uint128 minMigrationPeriod,\\n uint128 maxMigrationPeriod\\n ) external;\\n\\n function initializeLockPeriod(\\n uint128 defaultLockPeriod,\\n uint128 minLockPeriod,\\n uint128 maxLockPeriod\\n ) external;\\n\\n function initializeRecoveryPeriod(\\n uint128 defaultRecoveryPeriod,\\n uint128 minRecoveryPeriod,\\n uint128 maxRecoveryPeriod\\n ) external;\\n\\n function initializeSecurityWindow(\\n uint128 defaultSecurityWindow,\\n uint128 minSecurityWindow,\\n uint128 maxSecurityWindow\\n ) external;\\n\\n function setAdditionSecurityPeriod(\\n address wallet,\\n uint128 additionSecurityPeriod\\n ) external;\\n\\n function setRemovalSecurityPeriod(\\n address wallet,\\n uint128 removalSecurityPeriod\\n ) external;\\n\\n function setSecurityWindow(address wallet, uint128 securityWindow) external;\\n\\n function setRecoveryPeriod(address wallet, uint128 recoveryPeriod) external;\\n\\n function setLockPeriod(address wallet, uint128 lockPeriod) external;\\n\\n function setApprovalValidationPeriod(\\n address wallet,\\n uint128 approvalValidationPeriod\\n ) external;\\n\\n function setMigrationPeriod(\\n address wallet,\\n uint128 migrationPeriod\\n ) external;\\n\\n function additionSecurityPeriodOf(\\n address wallet\\n ) external view returns (uint128);\\n\\n function removalSecurityPeriodOf(\\n address wallet\\n ) external view returns (uint128);\\n\\n function securityWindowOf(address wallet) external view returns (uint128);\\n\\n function recoveryPeriodOf(address wallet) external view returns (uint128);\\n\\n function lockPeriodOf(address wallet) external view returns (uint128);\\n\\n function migrationPeriodOf(address wallet) external view returns (uint128);\\n\\n function approvalValidationPeriodOf(\\n address wallet\\n ) external view returns (uint128);\\n}\\n\"\n },\n \"contracts/infrastructure/RemoteStorage.sol\": {\n \"content\": \"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\nimport {IGuardianFacet} from \\\"../facets/interfaces/IGuardianFacet.sol\\\";\\n\\n/**\\n * @title Remote Storage\\n * @dev Remote storage allows you to associate addresses with an array of addresses on a standalone smart contract.\\n * This could be useful when you don't want to use the local diamond storage for some purpose.\\n * @author Ruslan Serebriakov (@rsrbk)\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\nabstract contract RemoteStorage {\\n struct StorageConfig {\\n address[] addresses;\\n mapping(address => Info) info;\\n }\\n\\n struct Info {\\n bool exists;\\n uint128 index;\\n }\\n\\n mapping(address => StorageConfig) internal configs;\\n\\n event Added(address _address);\\n event Removed(address _address);\\n\\n error RemoteStorage__CallerNotOwner();\\n error RemoteStorage__CallerNotGuardianOrOwner();\\n error RemoteStorage__AlreadyExists();\\n error RemoteStorage__NotFound();\\n error RemoteStorage__CallerNotGuardian();\\n\\n bytes4 constant IS_GUARDIAN_SELECTOR =\\n bytes4(keccak256(\\\"isGuardian(address)\\\"));\\n bytes4 constant GUARDIAN_COUNT = bytes4(keccak256(\\\"guardianCount()\\\"));\\n\\n /**\\n * @notice Modifier to only allow the self to call. Reverts otherwise\\n */\\n modifier onlyWallet(address _wallet) {\\n if (msg.sender != _wallet) revert RemoteStorage__CallerNotOwner();\\n _;\\n }\\n\\n /**\\n * @notice Enfore the callet to be wallet of guardian of the wallet\\n * @param _wallet Address of wallet\\n */\\n function enforceGuardianOrWallet(address _wallet) internal view {\\n if (msg.sender == _wallet) return;\\n address facetAddress = IDiamondLoupe(_wallet).facetAddress(\\n IS_GUARDIAN_SELECTOR\\n );\\n if (facetAddress != address(0))\\n if (IGuardianFacet(_wallet).isGuardian(msg.sender)) return;\\n revert RemoteStorage__CallerNotGuardianOrOwner();\\n }\\n\\n /**\\n * @notice Enforce the caller to be wallet IF guardians doesn't exists and only guardian when guardians exists\\n * @param _wallet Target wallet address to be handled by infrastructure contracts\\n */\\n function enforceWalletOrGuardianIfExists(address _wallet) internal view {\\n address facetAddress;\\n if (msg.sender == _wallet) {\\n facetAddress = IDiamondLoupe(_wallet).facetAddress(GUARDIAN_COUNT);\\n if (facetAddress == address(0)) return;\\n uint256 guardianCount = IGuardianFacet(_wallet).guardianCount();\\n if (guardianCount != 0) revert RemoteStorage__CallerNotGuardian();\\n return;\\n }\\n facetAddress = IDiamondLoupe(_wallet).facetAddress(\\n IS_GUARDIAN_SELECTOR\\n );\\n if (facetAddress != address(0))\\n if (IGuardianFacet(_wallet).isGuardian(msg.sender)) return;\\n\\n revert RemoteStorage__CallerNotGuardianOrOwner();\\n }\\n\\n /**\\n * @notice Add address to storage and reverts if the address already exists.\\n * This is an internal function callable from contracts that inherit this abstract contract\\n * @param _wallet Address of wallet to add the address\\n * @param _address Address to be added to wallet\\n */\\n function addAddress(address _wallet, address _address) internal {\\n StorageConfig storage config = configs[_wallet];\\n if (config.info[_address].exists) revert RemoteStorage__AlreadyExists();\\n\\n config.info[_address].exists = true;\\n config.info[_address].index = uint128(config.addresses.length);\\n config.addresses.push(_address);\\n\\n emit Added(_address);\\n }\\n\\n /**\\n * @notice Remove address from storage and reverts if the address already exists.\\n * This is an internal function callable from contracts that inherit this abstract contract\\n * @param _wallet Address of wallet to remove the address\\n * @param _address Address to be removed from wallet\\n */\\n function removeAddress(address _wallet, address _address) internal {\\n StorageConfig storage config = configs[_wallet];\\n if (!config.info[_address].exists) revert RemoteStorage__NotFound();\\n\\n address lastAddress = config.addresses[config.addresses.length - 1];\\n if (_address != lastAddress) {\\n uint128 targetIndex = config.info[_address].index;\\n config.addresses[targetIndex] = lastAddress;\\n config.info[lastAddress].index = targetIndex;\\n }\\n config.addresses.pop();\\n delete config.info[_address];\\n\\n emit Removed(_address);\\n }\\n\\n /**\\n * @notice Returns the address added to the given wallet\\n * @param _wallet Address of wallet to fetch the addresses added to it\\n * @return addresses List of addresses added to the wallet\\n */\\n function getAddresses(\\n address _wallet\\n ) internal view returns (address[] memory addresses) {\\n StorageConfig storage config = configs[_wallet];\\n addresses = new address[](config.addresses.length);\\n uint addressesLen = config.addresses.length;\\n for (uint256 i; i < addressesLen; ) {\\n addresses[i] = config.addresses[i];\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * @notice Returns bool value checking if the address exists in the given wallet address\\n * @param _wallet Wallet address to check\\n * @param _address Address to fetch if the address if added to given wallet\\n * @return exists_ Bool value showing if the address exists in wallet\\n */\\n function exists(\\n address _wallet,\\n address _address\\n ) internal view returns (bool exists_) {\\n exists_ = configs[_wallet].info[_address].exists;\\n }\\n\\n /**\\n * @notice Returns the number of addresses added to the wallet\\n * @param _wallet Address of wallet to check\\n * @return count_ Number of addresses added to wallet\\n */\\n function count(address _wallet) internal view returns (uint256 count_) {\\n count_ = configs[_wallet].addresses.length;\\n }\\n}\\n\"\n },\n \"contracts/infrastructure/SecurityManager.sol\": {\n \"content\": \"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {Ownable2Step} from \\\"@openzeppelin/contracts/access/Ownable2Step.sol\\\";\\nimport {ISecurityManager} from \\\"./interfaces/ISecurityManager.sol\\\";\\n\\n/**\\n * @title Security Manager\\n * @dev Infrastructure contract to manage security parameters of users\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract SecurityManager is ISecurityManager, Ownable2Step {\\n uint128 public minAdditionSecurityPeriod;\\n uint128 public maxAdditionSecurityPeriod;\\n uint128 private defaultAdditionSecurityPeriod;\\n\\n uint128 public minRemovalSecurityPeriod;\\n uint128 public maxRemovalSecurityPeriod;\\n uint128 private defaultRemovalSecurityPeriod;\\n\\n uint128 public minSecurityWindow;\\n uint128 public maxSecurityWindow;\\n uint128 private defaultSecurityWindow;\\n\\n uint128 public minRecoveryPeriod;\\n uint128 public maxRecoveryPeriod;\\n uint128 private defaultRecoveryPeriod;\\n\\n uint128 public minLockPeriod;\\n uint128 public maxLockPeriod;\\n uint128 private defaultLockPeriod;\\n\\n uint128 public minApprovalValidationPeriod;\\n uint128 public maxApprovalValidationPeriod;\\n uint128 private defaultApprovalValidationPeriod;\\n\\n uint128 public minMigrationPeriod;\\n uint128 public maxMigrationPeriod;\\n uint128 private defaultMigrationPeriod;\\n\\n bool public _isAdditionSecurityPeriodInitialized;\\n bool public _isRemovalSecurityPeriodInitialized;\\n bool public _isSecurityWindowInitialized;\\n bool public _isRecoveryPeriodInitialized;\\n bool public _isLockPeriodInitialized;\\n bool public _isApprovalValidationPeriodInitialized;\\n bool public _isMigrationPeriodInitialized;\\n\\n mapping(address => CustomSecurityConfig) securityConfigs;\\n\\n struct CustomSecurityConfig {\\n uint128 additionSecurityPeriod;\\n uint128 removalSecurityPeriod;\\n uint128 securityWindow;\\n uint128 recoveryPeriod;\\n uint128 lockPeriod;\\n uint128 approvalValidationPeriod;\\n uint128 migrationPeriod;\\n }\\n\\n /**\\n * @notice Modifier to only allow wallet itself to make a call to wallet\\n */\\n modifier onlyWallet(address _wallet) {\\n if (msg.sender != _wallet) revert SecurityManager__CallerNotWallet();\\n _;\\n }\\n\\n /**\\n * @notice Modifier to revert if the variable is already initialized\\n */\\n modifier initializer(bool _isInitialized) {\\n if (_isInitialized) revert SecurityManager__AlreadyIntialized();\\n _;\\n }\\n\\n /**\\n * @notice Transfers the ownership of the contract to the given owner\\n * @param _owner Address of owner who has access to initialize the default security variables for security manager\\n */\\n constructor(address _owner) {\\n transferOwnership(_owner);\\n _transferOwnership(_owner);\\n }\\n\\n /**\\n * @notice Sets the initial default/min/max addition security period for all Barz contracts that use this as Security Manager\\n * This function can only be called by the owner of the SecurityManager\\n * Default value should be bigger than the min and smaller than the max\\n * @param _defaultAdditionSecurityPeriod Default Addition Security Period for all Barz contracts\\n * @param _minAdditionSecurityPeriod Minimum Addition Security Period for all Barz contracts\\n * @param _maxAdditionSecurityPeriod Maximum Addition Security Period for all Barz contracts\\n */\\n function initializeAdditionSecurityPeriod(\\n uint128 _defaultAdditionSecurityPeriod,\\n uint128 _minAdditionSecurityPeriod,\\n uint128 _maxAdditionSecurityPeriod\\n )\\n external\\n override\\n onlyOwner\\n initializer(_isAdditionSecurityPeriodInitialized)\\n {\\n _isAdditionSecurityPeriodInitialized = true;\\n\\n _validatePeriodBoundaries(\\n _defaultAdditionSecurityPeriod,\\n _minAdditionSecurityPeriod,\\n _maxAdditionSecurityPeriod\\n );\\n defaultAdditionSecurityPeriod = _defaultAdditionSecurityPeriod;\\n minAdditionSecurityPeriod = _minAdditionSecurityPeriod;\\n maxAdditionSecurityPeriod = _maxAdditionSecurityPeriod;\\n }\\n\\n /**\\n * @notice Sets the initial default/min/max removal security period for all Barz contracts that use this as Security Manager\\n * This function can only be called by the owner of the SecurityManager\\n * Default value should be bigger than the min and smaller than the max\\n * @param _defaultRemovalSecurityPeriod Default Removal Security Period for all Barz contracts\\n * @param _minRemovalSecurityPeriod Minimum Removal Security Period for all Barz contracts\\n * @param _maxRemovalSecurityPeriod Maximum Removal Security Period for all Barz contracts\\n */\\n function initializeRemovalSecurityPeriod(\\n uint128 _defaultRemovalSecurityPeriod,\\n uint128 _minRemovalSecurityPeriod,\\n uint128 _maxRemovalSecurityPeriod\\n )\\n external\\n override\\n onlyOwner\\n initializer(_isRemovalSecurityPeriodInitialized)\\n {\\n _isRemovalSecurityPeriodInitialized = true;\\n\\n _validatePeriodBoundaries(\\n _defaultRemovalSecurityPeriod,\\n _minRemovalSecurityPeriod,\\n _maxRemovalSecurityPeriod\\n );\\n defaultRemovalSecurityPeriod = _defaultRemovalSecurityPeriod;\\n minRemovalSecurityPeriod = _minRemovalSecurityPeriod;\\n maxRemovalSecurityPeriod = _maxRemovalSecurityPeriod;\\n }\\n\\n /**\\n * @notice Sets the initial default/min/maxd security window for all Barz contracts that use this as Security Manager\\n * This function can only be called by the owner of the SecurityManager\\n * Default value should be bigger than the min and smaller than the max\\n * @param _defaultSecurityWindow Default Security Window for all Barz contracts\\n * @param _minSecurityWindow Minimum Security Window for all Barz contracts\\n * @param _maxSecurityWindow Maximum Security Window for all Barz contracts\\n */\\n function initializeSecurityWindow(\\n uint128 _defaultSecurityWindow,\\n uint128 _minSecurityWindow,\\n uint128 _maxSecurityWindow\\n ) external override onlyOwner initializer(_isSecurityWindowInitialized) {\\n _isSecurityWindowInitialized = true;\\n\\n _validatePeriodBoundaries(\\n _defaultSecurityWindow,\\n _minSecurityWindow,\\n _maxSecurityWindow\\n );\\n defaultSecurityWindow = _defaultSecurityWindow;\\n minSecurityWindow = _minSecurityWindow;\\n maxSecurityWindow = _maxSecurityWindow;\\n }\\n\\n /**\\n * @notice Sets the initial default/min/max recovery period for all Barz contracts that use this as Security Manager\\n * This function can only be called by the owner of the SecurityManager\\n * Default value should be bigger than the min and smaller than the max\\n * @param _defaultRecoveryPeriod Default Recovery Period for all Barz contracts\\n * @param _minRecoveryPeriod Minimum Recovery Period for all Barz contracts\\n * @param _maxRecoveryPeriod Maximum Recovery Period for all Barz contracts\\n */\\n function initializeRecoveryPeriod(\\n uint128 _defaultRecoveryPeriod,\\n uint128 _minRecoveryPeriod,\\n uint128 _maxRecoveryPeriod\\n ) external override onlyOwner initializer(_isRecoveryPeriodInitialized) {\\n _isRecoveryPeriodInitialized = true;\\n\\n _validatePeriodBoundaries(\\n _defaultRecoveryPeriod,\\n _minRecoveryPeriod,\\n _maxRecoveryPeriod\\n );\\n defaultRecoveryPeriod = _defaultRecoveryPeriod;\\n minRecoveryPeriod = _minRecoveryPeriod;\\n maxRecoveryPeriod = _maxRecoveryPeriod;\\n }\\n\\n /**\\n * @notice Sets the initial default/min/max lock period for all Barz contracts that use this as Security Manager\\n * This function can only be called by the owner of the SecurityManager\\n * Default value should be bigger than the min and smaller than the max\\n * @param _defaultLockPeriod Default Lock Period for all Barz contracts\\n * @param _minLockPeriod Minimum Lock Period for all Barz contracts\\n * @param _maxLockPeriod Maximum Lock Period for all Barz contracts\\n */\\n function initializeLockPeriod(\\n uint128 _defaultLockPeriod,\\n uint128 _minLockPeriod,\\n uint128 _maxLockPeriod\\n ) external override onlyOwner initializer(_isLockPeriodInitialized) {\\n _isLockPeriodInitialized = true;\\n\\n _validatePeriodBoundaries(\\n _defaultLockPeriod,\\n _minLockPeriod,\\n _maxLockPeriod\\n );\\n defaultLockPeriod = _defaultLockPeriod;\\n minLockPeriod = _minLockPeriod;\\n maxLockPeriod = _maxLockPeriod;\\n }\\n\\n /**\\n * @notice Sets the initial default/min/max approval validation period for all Barz contracts that use this as Security Manager\\n * This function can only be called by the owner of the SecurityManager\\n * Default value should be bigger than the min and smaller than the max\\n * @param _defaultApprovalValidationPeriod Default Approval Validation Period for all Barz contracts\\n * @param _minApprovalValidationPeriod Minimum Approval Validation Period for all Barz contracts\\n * @param _maxApprovalValidationPeriod Maximum Approval Validation Period for all Barz contracts\\n */\\n function initializeApprovalValidationPeriod(\\n uint128 _defaultApprovalValidationPeriod,\\n uint128 _minApprovalValidationPeriod,\\n uint128 _maxApprovalValidationPeriod\\n )\\n external\\n override\\n onlyOwner\\n initializer(_isApprovalValidationPeriodInitialized)\\n {\\n _isApprovalValidationPeriodInitialized = true;\\n\\n _validatePeriodBoundaries(\\n _defaultApprovalValidationPeriod,\\n _minApprovalValidationPeriod,\\n _maxApprovalValidationPeriod\\n );\\n defaultApprovalValidationPeriod = _defaultApprovalValidationPeriod;\\n minApprovalValidationPeriod = _minApprovalValidationPeriod;\\n maxApprovalValidationPeriod = _maxApprovalValidationPeriod;\\n }\\n\\n /**\\n * @notice Sets the initial default/min/max migration period for all Barz contracts that use this as Security Manager\\n * This function can only be called by the owner of the SecurityManager\\n * Default value should be bigger than the min and smaller than the max\\n * @param _defaultMigrationPeriod Default Migration Period for all Barz contracts\\n * @param _minMigrationPeriod Minimum Migration Period for all Barz contracts\\n * @param _maxMigrationPeriod Maximum Migration Period for all Barz contracts\\n */\\n function initializeMigrationPeriod(\\n uint128 _defaultMigrationPeriod,\\n uint128 _minMigrationPeriod,\\n uint128 _maxMigrationPeriod\\n ) external override onlyOwner initializer(_isMigrationPeriodInitialized) {\\n _isMigrationPeriodInitialized = true;\\n\\n _validatePeriodBoundaries(\\n _defaultMigrationPeriod,\\n _minMigrationPeriod,\\n _maxMigrationPeriod\\n );\\n defaultMigrationPeriod = _defaultMigrationPeriod;\\n minMigrationPeriod = _minMigrationPeriod;\\n maxMigrationPeriod = _maxMigrationPeriod;\\n }\\n\\n /**\\n * @notice Wallet owner sets the addition security period for the wallet. Only the owner of wallet can call this function.\\n * The addition security period should be within the boundry of min and max value set by the owner\\n * @param _wallet Address of wallet\\n * @param _additionSecurityPeriod Custom Addition Security Period for the wallet\\n */\\n function setAdditionSecurityPeriod(\\n address _wallet,\\n uint128 _additionSecurityPeriod\\n ) external override onlyWallet(_wallet) {\\n _validatePeriodBoundaries(\\n _additionSecurityPeriod,\\n minAdditionSecurityPeriod,\\n maxAdditionSecurityPeriod\\n );\\n securityConfigs[_wallet]\\n .additionSecurityPeriod = _additionSecurityPeriod;\\n }\\n\\n /**\\n * @notice Wallet owner sets the removal security period for the wallet. Only the owner of wallet can call this function.\\n * The removal security period should be within the boundry of min and max value set by the owner\\n * @param _wallet Address of wallet\\n * @param _removalSecurityPeriod Custom Removal Security Period for the wallet\\n */\\n function setRemovalSecurityPeriod(\\n address _wallet,\\n uint128 _removalSecurityPeriod\\n ) external override onlyWallet(_wallet) {\\n _validatePeriodBoundaries(\\n _removalSecurityPeriod,\\n minRemovalSecurityPeriod,\\n maxRemovalSecurityPeriod\\n );\\n securityConfigs[_wallet].removalSecurityPeriod = _removalSecurityPeriod;\\n }\\n\\n /**\\n * @notice Wallet owner sets the security window for the wallet. Only the owner of wallet can call this function.\\n * The security window should be within the boundry of min and max value set by the owner\\n * @param _wallet Address of wallet\\n * @param _securityWindow Custom Security Window for the wallet\\n */\\n function setSecurityWindow(\\n address _wallet,\\n uint128 _securityWindow\\n ) external override onlyWallet(_wallet) {\\n _validatePeriodBoundaries(\\n _securityWindow,\\n minSecurityWindow,\\n maxSecurityWindow\\n );\\n securityConfigs[_wallet].securityWindow = _securityWindow;\\n }\\n\\n /**\\n * @notice Wallet owner sets the recovery period for the wallet. Only the owner of wallet can call this function.\\n * The recovery period should be within the boundry of min and max value set by the owner\\n * @param _wallet Address of wallet\\n * @param _recoveryPeriod Custom recovery period for the wallet\\n */\\n function setRecoveryPeriod(\\n address _wallet,\\n uint128 _recoveryPeriod\\n ) external override onlyWallet(_wallet) {\\n _validatePeriodBoundaries(\\n _recoveryPeriod,\\n minRecoveryPeriod,\\n maxRecoveryPeriod\\n );\\n securityConfigs[_wallet].recoveryPeriod = _recoveryPeriod;\\n }\\n\\n /**\\n * @notice Wallet owner sets the lock period for the wallet. Only the owner of wallet can call this function.\\n * The lock period should be within the boundry of min and max value set by the owner\\n * @param _wallet Address of wallet\\n * @param _lockPeriod Custom Lock period for the wallet\\n */\\n function setLockPeriod(\\n address _wallet,\\n uint128 _lockPeriod\\n ) external override onlyWallet(_wallet) {\\n _validatePeriodBoundaries(_lockPeriod, minLockPeriod, maxLockPeriod);\\n securityConfigs[_wallet].lockPeriod = _lockPeriod;\\n }\\n\\n /**\\n * @notice Wallet owner sets the approval validation period for the wallet. Only the owner of wallet can call this function.\\n * The approval validation period should be within the boundry of min and max value set by the owner\\n * @param _wallet Address of wallet\\n * @param _approvalValidationPeriod Custom approval validation period for the wallet\\n */\\n function setApprovalValidationPeriod(\\n address _wallet,\\n uint128 _approvalValidationPeriod\\n ) external override onlyWallet(_wallet) {\\n _validatePeriodBoundaries(\\n _approvalValidationPeriod,\\n minApprovalValidationPeriod,\\n maxApprovalValidationPeriod\\n );\\n securityConfigs[_wallet]\\n .approvalValidationPeriod = _approvalValidationPeriod;\\n }\\n\\n /**\\n * @notice Wallet owner sets the migration period for the wallet. Only the owner of wallet can call this function.\\n * The migration period should be within the boundry of min and max value set by the owner\\n * @param _wallet Address of wallet\\n * @param _migrationPeriod Custom migration period for the wallet\\n */\\n\\n function setMigrationPeriod(\\n address _wallet,\\n uint128 _migrationPeriod\\n ) external override onlyWallet(_wallet) {\\n _validatePeriodBoundaries(\\n _migrationPeriod,\\n minMigrationPeriod,\\n maxMigrationPeriod\\n );\\n securityConfigs[_wallet].migrationPeriod = _migrationPeriod;\\n }\\n\\n /**\\n * @notice Returns the addition security period. Returns default value when custom addition security period is not set\\n * @param _wallet Address of wallet\\n * @return additionSecurityPeriod Addition Security Period of the given Barz account or wallet\\n */\\n function additionSecurityPeriodOf(\\n address _wallet\\n )\\n public\\n view\\n override\\n onlyWallet(_wallet)\\n returns (uint128 additionSecurityPeriod)\\n {\\n additionSecurityPeriod = securityConfigs[_wallet]\\n .additionSecurityPeriod;\\n additionSecurityPeriod = (additionSecurityPeriod == 0)\\n ? defaultAdditionSecurityPeriod\\n : additionSecurityPeriod;\\n }\\n\\n /**\\n * @notice Returns the removal security period. Returns default value when custom removal security period is not set\\n * @param _wallet Address of wallet\\n * @return removalSecurityPeriod Removal Security Period of the given Barz account or wallet\\n */\\n function removalSecurityPeriodOf(\\n address _wallet\\n )\\n public\\n view\\n override\\n onlyWallet(_wallet)\\n returns (uint128 removalSecurityPeriod)\\n {\\n removalSecurityPeriod = securityConfigs[_wallet].removalSecurityPeriod;\\n removalSecurityPeriod = (removalSecurityPeriod == 0)\\n ? defaultRemovalSecurityPeriod\\n : removalSecurityPeriod;\\n }\\n\\n /**\\n * @notice Returns the security window. Returns default value when custom security window is not set\\n * @param _wallet Address of wallet\\n * @return securityWindow Security window of the given Barz account or wallet\\n */\\n function securityWindowOf(\\n address _wallet\\n )\\n public\\n view\\n override\\n onlyWallet(_wallet)\\n returns (uint128 securityWindow)\\n {\\n securityWindow = securityConfigs[_wallet].securityWindow;\\n securityWindow = (securityWindow == 0)\\n ? defaultSecurityWindow\\n : securityWindow;\\n }\\n\\n /**\\n * @notice Returns the recovery period. Returns default value when custom recovery period is not set\\n * @param _wallet Address of wallet\\n * @return recoveryPeriod Recovery Period of the given Barz account or wallet\\n */\\n function recoveryPeriodOf(\\n address _wallet\\n )\\n public\\n view\\n override\\n onlyWallet(_wallet)\\n returns (uint128 recoveryPeriod)\\n {\\n recoveryPeriod = securityConfigs[_wallet].recoveryPeriod;\\n recoveryPeriod = (recoveryPeriod == 0)\\n ? defaultRecoveryPeriod\\n : recoveryPeriod;\\n }\\n\\n /**\\n * @notice Returns the lock period. Returns default value when custom lock period is not set\\n * @param _wallet Address of wallet\\n * @return lockPeriod Lock Period of the given Barz account or wallet\\n */\\n function lockPeriodOf(\\n address _wallet\\n ) public view override onlyWallet(_wallet) returns (uint128 lockPeriod) {\\n lockPeriod = securityConfigs[_wallet].lockPeriod;\\n lockPeriod = (lockPeriod == 0) ? defaultLockPeriod : lockPeriod;\\n }\\n\\n /**\\n * @notice Returns the approval validation period. Returns default value when custom approval validation period is not set\\n * @param _wallet Address of wallet\\n * @return approvalValidationPeriod Approval Validation Period of the given Barz account or wallet\\n */\\n function approvalValidationPeriodOf(\\n address _wallet\\n )\\n public\\n view\\n override\\n onlyWallet(_wallet)\\n returns (uint128 approvalValidationPeriod)\\n {\\n approvalValidationPeriod = securityConfigs[_wallet]\\n .approvalValidationPeriod;\\n approvalValidationPeriod = (approvalValidationPeriod == 0)\\n ? defaultApprovalValidationPeriod\\n : approvalValidationPeriod;\\n }\\n\\n /**\\n * @notice Returns the migration period. Returns default value when custom migration period is not set\\n * @param _wallet Address of wallet\\n * @return migrationPeriod Migration Period of the given Barz account or wallet\\n */\\n function migrationPeriodOf(\\n address _wallet\\n )\\n public\\n view\\n override\\n onlyWallet(_wallet)\\n returns (uint128 migrationPeriod)\\n {\\n migrationPeriod = securityConfigs[_wallet].migrationPeriod;\\n migrationPeriod = (migrationPeriod == 0)\\n ? defaultMigrationPeriod\\n : migrationPeriod;\\n }\\n\\n /**\\n * @notice Validates if the period is smaller than the max period or bigger than the min period\\n * @param _period Period to be checked\\n * @param _minPeriod Minimum period\\n * @param _maxPeriod Maximum period\\n */\\n function _validatePeriodBoundaries(\\n uint128 _period,\\n uint128 _minPeriod,\\n uint128 _maxPeriod\\n ) internal pure {\\n if (_period >= _maxPeriod || _period <= _minPeriod)\\n revert SecurityManager__OutOfBoundary();\\n }\\n}\\n\"\n },\n \"contracts/infrastructure/WhitelistStorage.sol\": {\n \"content\": \"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {RemoteStorage} from \\\"./RemoteStorage.sol\\\";\\n\\n/**\\n * @title Whitelist storage\\n * @dev Maps addresses to the corresponsing array of whitelisted addresses for each of them.\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\ncontract WhitelistStorage is RemoteStorage {\\n /**\\n * @dev Add the address to the whitelist storage\\n * @param _wallet User wallet\\n * @param _address Address to be whitelisted\\n */\\n function whitelistAddress(address _wallet, address _address) external {\\n enforceWalletOrGuardianIfExists(_wallet);\\n addAddress(_wallet, _address);\\n }\\n\\n /**\\n * @dev Removes the address from the whitelist storage\\n * @param _wallet User wallet\\n * @param _address Address to be removed from the whitelist\\n */\\n function blacklistAddress(address _wallet, address _address) external {\\n enforceGuardianOrWallet(_wallet);\\n removeAddress(_wallet, _address);\\n }\\n\\n /**\\n * @dev Returns whether the address exists in the whitelist storage, associated with the wallet\\n * @param _wallet User wallet\\n * @param _address Address to be whitelisted\\n */\\n function isWhitelisted(\\n address _wallet,\\n address _address\\n ) external view returns (bool) {\\n return exists(_wallet, _address);\\n }\\n\\n /**\\n * @dev Returns all whitelisted addresses associated with the wallet\\n * @param _wallet User wallet\\n */\\n function getWhitelistedAddresses(\\n address _wallet\\n ) external view returns (address[] memory) {\\n return getAddresses(_wallet);\\n }\\n}\\n\"\n },\n \"contracts/interfaces/ERC/IERC1155Receiver.sol\": {\n \"content\": \"// SPDX-License-Identifier: Apache-2.0\\n\\npragma solidity 0.8.21;\\n\\n/**\\n * @dev _Available since v3.1._\\n */\\ninterface IERC1155Receiver {\\n /**\\n * @dev Handles the receipt of a single ERC1155 token type. This function is\\n * called at the end of a `safeTransferFrom` after the balance has been updated.\\n *\\n * NOTE: To accept the transfer, this must return\\n * `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))`\\n * (i.e. 0xf23a6e61, or its own function selector).\\n *\\n * @param operator The address which initiated the transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param id The ID of the token being transferred\\n * @param value The amount of tokens being transferred\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155Received(\\n address operator,\\n address from,\\n uint256 id,\\n uint256 value,\\n bytes calldata data\\n ) external returns (bytes4);\\n\\n /**\\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\\n * is called at the end of a `safeBatchTransferFrom` after the balances have\\n * been updated.\\n *\\n * NOTE: To accept the transfer(s), this must return\\n * `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))`\\n * (i.e. 0xbc197c81, or its own function selector).\\n *\\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155BatchReceived(\\n address operator,\\n address from,\\n uint256[] calldata ids,\\n uint256[] calldata values,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\"\n },\n \"contracts/interfaces/ERC/IERC1271.sol\": {\n \"content\": \"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC1271 {\\n function isValidSignature(\\n bytes32 hash,\\n bytes memory signature\\n ) external view returns (bytes4);\\n}\\n\"\n },\n \"contracts/interfaces/ERC/IERC165.sol\": {\n \"content\": \"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.21;\\n\\ninterface IERC165 {\\n /// @notice Query if a contract implements an interface\\n /// @param interfaceId The interface identifier, as specified in ERC-165\\n /// @dev Interface identification is specified in ERC-165. This function\\n /// uses less than 30,000 gas.\\n /// @return `true` if the contract implements `interfaceID` and\\n /// `interfaceID` is not 0xffffffff, `false` otherwise\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\"\n },\n \"contracts/interfaces/ERC/IERC173.sol\": {\n \"content\": \"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.21;\\n\\n/// @title ERC-173 Contract Ownership Standard\\n/// Note: the ERC-165 identifier for this interface is 0x7f5828d0\\n/* is ERC165 */\\ninterface IERC173 {\\n /// @dev This emits when ownership of a contract changes.\\n event OwnershipTransferred(\\n address indexed previousOwner,\\n address indexed newOwner\\n );\\n\\n /// @notice Get the address of the owner\\n /// @return owner_ The address of the owner.\\n function owner() external view returns (address owner_);\\n\\n /// @notice Set the address of the new owner of the contract\\n /// @dev Set _newOwner to address(0) to renounce any ownership.\\n /// @param _newOwner The address of the new owner of the contract\\n function transferOwnership(address _newOwner) external;\\n}\\n\"\n },\n \"contracts/interfaces/ERC/IERC677Receiver.sol\": {\n \"content\": \"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC677Receiver {\\n function onTokenTransfer(\\n address sender,\\n uint value,\\n bytes calldata data\\n ) external pure returns (bool);\\n}\\n\"\n },\n \"contracts/interfaces/ERC/Tokens/IERC1155.sol\": {\n \"content\": \"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC165.sol\\\";\\n\\n/**\\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\\n *\\n * _Available since v3.1._\\n */\\ninterface IERC1155 is IERC165 {\\n /**\\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\\n */\\n event TransferSingle(\\n address indexed operator,\\n address indexed from,\\n address indexed to,\\n uint256 id,\\n uint256 value\\n );\\n\\n /**\\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\\n * transfers.\\n */\\n event TransferBatch(\\n address indexed operator,\\n address indexed from,\\n address indexed to,\\n uint256[] ids,\\n uint256[] values\\n );\\n\\n /**\\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\\n * `approved`.\\n */\\n event ApprovalForAll(\\n address indexed account,\\n address indexed operator,\\n bool approved\\n );\\n\\n /**\\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\\n *\\n * If an {URI} event was emitted for `id`, the standard\\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\\n * returned by {IERC1155MetadataURI-uri}.\\n */\\n event URI(string value, uint256 indexed id);\\n\\n /**\\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n */\\n function balanceOf(\\n address account,\\n uint256 id\\n ) external view returns (uint256);\\n\\n /**\\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\\n *\\n * Requirements:\\n *\\n * - `accounts` and `ids` must have the same length.\\n */\\n function balanceOfBatch(\\n address[] calldata accounts,\\n uint256[] calldata ids\\n ) external view returns (uint256[] memory);\\n\\n /**\\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\\n *\\n * Emits an {ApprovalForAll} event.\\n *\\n * Requirements:\\n *\\n * - `operator` cannot be the caller.\\n */\\n function setApprovalForAll(address operator, bool approved) external;\\n\\n /**\\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\\n *\\n * See {setApprovalForAll}.\\n */\\n function isApprovedForAll(\\n address account,\\n address operator\\n ) external view returns (bool);\\n\\n /**\\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\\n *\\n * Emits a {TransferSingle} event.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.\\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\\n * acceptance magic value.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 id,\\n uint256 amount,\\n bytes calldata data\\n ) external;\\n\\n /**\\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\\n *\\n * Emits a {TransferBatch} event.\\n *\\n * Requirements:\\n *\\n * - `ids` and `amounts` must have the same length.\\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\\n * acceptance magic value.\\n */\\n function safeBatchTransferFrom(\\n address from,\\n address to,\\n uint256[] calldata ids,\\n uint256[] calldata amounts,\\n bytes calldata data\\n ) external;\\n}\\n\"\n },\n \"contracts/interfaces/ERC/Tokens/IERC20.sol\": {\n \"content\": \"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.21;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(\\n address indexed owner,\\n address indexed spender,\\n uint256 value\\n );\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` 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 amount) 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(\\n address owner,\\n address spender\\n ) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the 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 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` 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(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(\\n address spender,\\n uint256 addedValue\\n ) external returns (bool);\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(\\n address spender,\\n uint256 subtractedValue\\n ) external returns (bool);\\n}\\n\"\n },\n \"contracts/interfaces/ERC/Tokens/IERC721.sol\": {\n \"content\": \"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC165.sol\\\";\\n\\n/**\\n * @dev Required interface of an ERC721 compliant contract.\\n */\\ninterface IERC721 is IERC165 {\\n /**\\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\\n */\\n event Transfer(\\n address indexed from,\\n address indexed to,\\n uint256 indexed tokenId\\n );\\n\\n /**\\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\\n */\\n event Approval(\\n address indexed owner,\\n address indexed approved,\\n uint256 indexed tokenId\\n );\\n\\n /**\\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\\n */\\n event ApprovalForAll(\\n address indexed owner,\\n address indexed operator,\\n bool approved\\n );\\n\\n /**\\n * @dev Returns the number of tokens in ``owner``'s account.\\n */\\n function balanceOf(address owner) external view returns (uint256 balance);\\n\\n /**\\n * @dev Returns the owner of the `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function ownerOf(uint256 tokenId) external view returns (address owner);\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes calldata data\\n ) external;\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Transfers `tokenId` token from `from` to `to`.\\n *\\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must be owned by `from`.\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address from, address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\\n * The approval is cleared when the token is transferred.\\n *\\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\\n *\\n * Requirements:\\n *\\n * - The caller must own the token or be an approved operator.\\n * - `tokenId` must exist.\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Approve or remove `operator` as an operator for the caller.\\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\\n *\\n * Requirements:\\n *\\n * - The `operator` cannot be the caller.\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function setApprovalForAll(address operator, bool approved) external;\\n\\n /**\\n * @dev Returns the account approved for `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function getApproved(\\n uint256 tokenId\\n ) external view returns (address operator);\\n\\n /**\\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\\n *\\n * See {setApprovalForAll}\\n */\\n function isApprovedForAll(\\n address owner,\\n address operator\\n ) external view returns (bool);\\n}\\n\"\n },\n \"contracts/interfaces/IBarz.sol\": {\n \"content\": \"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Barz Interface\\n * @dev Interface of Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IBarz {\\n error Barz__InitializationFailure();\\n}\\n\"\n },\n \"contracts/interfaces/IBarzFactory.sol\": {\n \"content\": \"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {Barz} from \\\"../Barz.sol\\\";\\n\\n/**\\n * @title Barz Factory Interface\\n * @dev Interface of contract to easily deploy Barz to a pre-computed address with a single call\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IBarzFactory {\\n event BarzDeployed(address);\\n\\n function createAccount(\\n address verificationFacet,\\n bytes calldata owner,\\n uint256 salt\\n ) external returns (Barz);\\n\\n function getAddress(\\n address verificationFacet,\\n bytes calldata owner,\\n uint256 salt\\n ) external view returns (address);\\n\\n function getBytecode(\\n address accountFacet,\\n address verificationFacet,\\n address entryPoint,\\n address facetRegistry,\\n address defaultFallback,\\n bytes memory ownerPublicKey\\n ) external pure returns (bytes memory);\\n\\n function getCreationCode() external pure returns (bytes memory);\\n}\\n\"\n },\n \"contracts/libraries/DefaultLibDiamond.sol\": {\n \"content\": \"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary DefaultLibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (\\n uint256 facetIndex;\\n facetIndex < _diamondCut.length;\\n facetIndex++\\n ) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(\\n address _facetAddress,\\n bytes4[] memory _functionSelectors\\n ) internal {\\n uint256 funcSelectorsLength = _functionSelectors.length;\\n require(\\n funcSelectorsLength > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _facetAddress != address(0),\\n \\\"LibDiamondCut: Add facet can't be address(0)\\\"\\n );\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (\\n uint256 selectorIndex;\\n selectorIndex < funcSelectorsLength;\\n selectorIndex++\\n ) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds\\n .selectorToFacetAndPosition[selector]\\n .facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(\\n address _facetAddress,\\n bytes4[] memory _functionSelectors\\n ) internal {\\n uint256 funcSelectorsLength = _functionSelectors.length;\\n require(\\n funcSelectorsLength > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _facetAddress != address(0),\\n \\\"LibDiamondCut: Replace facet can't be address(0)\\\"\\n );\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (\\n uint256 selectorIndex;\\n selectorIndex < funcSelectorsLength;\\n selectorIndex++\\n ) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds\\n .selectorToFacetAndPosition[selector]\\n .facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same facet\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(\\n address _facetAddress,\\n bytes4[] memory _functionSelectors\\n ) internal {\\n uint256 funcSelectorsLength = _functionSelectors.length;\\n require(\\n funcSelectorsLength > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(\\n _facetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n for (\\n uint256 selectorIndex;\\n selectorIndex < funcSelectorsLength;\\n selectorIndex++\\n ) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds\\n .selectorToFacetAndPosition[selector]\\n .facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(\\n DiamondStorage storage ds,\\n address _facetAddress\\n ) internal {\\n enforceHasContractCode(\\n _facetAddress,\\n \\\"LibDiamondCut: New facet has no code\\\"\\n );\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds\\n .facetAddresses\\n .length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds\\n .selectorToFacetAndPosition[_selector]\\n .functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(\\n _selector\\n );\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(\\n _facetAddress != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // an immutable function is a function defined directly in a diamond\\n require(\\n _facetAddress != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds\\n .selectorToFacetAndPosition[_selector]\\n .functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors[lastSelectorPosition];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n selectorPosition\\n ] = lastSelector;\\n ds\\n .selectorToFacetAndPosition[lastSelector]\\n .functionSelectorPosition = uint96(selectorPosition);\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[\\n lastFacetAddressPosition\\n ];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds\\n .facetFunctionSelectors[lastFacetAddress]\\n .facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds\\n .facetFunctionSelectors[_facetAddress]\\n .facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\"\n },\n \"contracts/libraries/LibAppStorage.sol\": {\n \"content\": \"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {SafeCast} from \\\"@openzeppelin/contracts/utils/math/SafeCast.sol\\\";\\nimport {IEntryPoint} from \\\"../aa-4337/interfaces/IEntryPoint.sol\\\";\\nimport {IFacetRegistry} from \\\"../infrastructure/interfaces/IFacetRegistry.sol\\\";\\n\\n/*\\n * @title App Storage\\n * @dev App storage for Barz contract to prevent storage collision\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Lock {\\n uint64 release;\\n bytes4 locker;\\n}\\n\\nstruct InitializersStorage {\\n // NOTE: initialized is a variable to make sure the initialization is only done once.\\n uint8 signerInitialized;\\n uint8 accountInitialized;\\n uint8 restrictionsInitialized;\\n}\\n\\nstruct AppStorage {\\n mapping(uint256 => InitializersStorage) initStorage;\\n uint8 signerMigration;\\n bytes4 validateOwnerSignatureSelector;\\n IEntryPoint entryPoint;\\n IFacetRegistry facetRegistry;\\n mapping(uint256 => Lock) locks;\\n}\\n\\nlibrary LibAppStorage {\\n error LibAppStorage__AccountAlreadyUninitialized();\\n error LibAppStorage__AccountMustBeUninitialized();\\n error LibAppStorage__SignerAlreadyUninitialized();\\n error LibAppStorage__SignerMustBeUninitialized();\\n\\n function appStorage() internal pure returns (AppStorage storage ds) {\\n assembly {\\n ds.slot := 0\\n }\\n }\\n\\n function setSignerUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerAlreadyUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 0;\\n }\\n\\n function getValidateOwnerSignatureSelector()\\n internal\\n view\\n returns (bytes4 selector)\\n {\\n selector = appStorage().validateOwnerSignatureSelector;\\n }\\n\\n function setValidateOwnerSignatureSelector(\\n bytes4 _validateOwnerSignatureSelector\\n ) internal {\\n appStorage()\\n .validateOwnerSignatureSelector = _validateOwnerSignatureSelector;\\n }\\n\\n function enforceSignerInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerMustBeUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 1;\\n }\\n\\n function enforceAccountInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].accountInitialized) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n s.initStorage[0].accountInitialized = 1;\\n }\\n\\n function initiateSignerMigration() internal {\\n appStorage().signerMigration = 1;\\n }\\n\\n function enforceSignerMigration() internal view {\\n if (1 != appStorage().signerMigration) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n }\\n\\n function finalizeSignerMigration() internal {\\n appStorage().signerMigration = 0;\\n }\\n\\n function setLock(uint256 _releaseAfter, bytes4 _locker) internal {\\n appStorage().locks[0] = Lock(SafeCast.toUint64(_releaseAfter), _locker);\\n }\\n\\n function enforceRestrictionsInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__SignerMustBeUninitialized();\\n s.initStorage[0].restrictionsInitialized = 1;\\n }\\n\\n function setRestrictionsUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__AccountAlreadyUninitialized();\\n s.initStorage[0].restrictionsInitialized = 0;\\n }\\n}\\n\\ncontract BarzStorage {\\n AppStorage internal s;\\n modifier onlyWhenUnlocked() {\\n require(\\n uint64(block.timestamp) >= s.locks[0].release,\\n \\\"Account Locked\\\"\\n );\\n _;\\n }\\n modifier onlyWhenLocked() {\\n require(\\n uint64(block.timestamp) < s.locks[0].release,\\n \\\"Account Unlocked\\\"\\n );\\n _;\\n }\\n}\\n\"\n },\n \"contracts/libraries/LibDiamond.sol\": {\n \"content\": \"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\\n bytes4(keccak256(\\\"verifyRestrictions(address,address,uint256,bytes)\\\"));\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // Default Fallback Handler of the barz.\\n IDiamondLoupe defaultFallbackHandler;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function enforceIsSelf() internal view {\\n require(msg.sender == address(this), \\\"LibDiamond: Caller not self\\\");\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n\\n unchecked {\\n facetIndex++;\\n }\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n\\n function restrictionsFacet() internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(\\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\\n )\\n );\\n }\\n}\\n\"\n },\n \"contracts/libraries/LibFacetStorage.sol\": {\n \"content\": \"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Storage\\n * @dev Storage contract to store each facets variables with diamond storage\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Secp256k1VerificationStorage {\\n address signer;\\n}\\n\\nstruct Secp256r1VerificationStorage {\\n uint256[2] q;\\n}\\n\\nstruct GuardianStorage {\\n mapping(bytes32 => uint256) pending;\\n mapping(uint8 => StorageConfig) configs;\\n}\\n\\nstruct Info {\\n bool exists;\\n uint128 index;\\n}\\n\\nstruct StorageConfig {\\n address[] addresses;\\n mapping(address => Info) info;\\n}\\n\\nstruct RecoveryConfig {\\n bytes recoveryPublicKey;\\n uint64 executeAfter;\\n}\\n\\nstruct ApprovalConfig {\\n bool isApproved;\\n uint64 validUntil;\\n}\\n\\nstruct RecoveryApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isNewOwnerApproved;\\n}\\n\\nstruct RecoveryStorage {\\n mapping(uint8 => RecoveryConfig) recoveryConfigs;\\n mapping(uint8 => RecoveryApprovalConfig) recoveryApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct RestrictionsStorage {\\n address[] restrictions;\\n mapping(address => bool) exists;\\n}\\n\\nstruct SignatureMigrationConfig {\\n bytes migrationPublicKey;\\n address migrationVerificationFacet;\\n bytes4[] migrationSelectors;\\n uint64 migrateAfter;\\n}\\n\\nstruct SignatureMigrationApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isMigrationApproved;\\n}\\n\\nstruct SignatureMigrationStorage {\\n mapping(uint8 => SignatureMigrationConfig) migrationConfigs;\\n mapping(uint8 => SignatureMigrationApprovalConfig) migrationApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct DiamondCutApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isDiamondCutApproved;\\n}\\n\\nstruct DiamondCutStorage {\\n mapping(uint8 => DiamondCutApprovalConfig) diamondCutApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct LockStorage {\\n uint128 nonce;\\n}\\n\\nlibrary LibFacetStorage {\\n bytes32 constant K1_STORAGE_POSITION =\\n keccak256(\\n \\\"v0.trustwallet.diamond.storage.Secp256k1VerificationStorage\\\"\\n );\\n bytes32 constant R1_STORAGE_POSITION =\\n keccak256(\\n \\\"v0.trustwallet.diamond.storage.Secp256r1VerificationStorage\\\"\\n );\\n bytes32 constant GUARDIAN_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.GuardianStorage\\\");\\n bytes32 constant RECOVERY_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.RecoveryStorage\\\");\\n bytes32 constant RESTRICTION_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.RestrictionsStorage\\\");\\n bytes32 constant MIGRATION_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.SignatureMigrationStorage\\\");\\n bytes32 constant DIAMONDCUT_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.DiamondCutStorage\\\");\\n bytes32 constant LOCK_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.LockStorage\\\");\\n\\n function k1Storage()\\n internal\\n pure\\n returns (Secp256k1VerificationStorage storage ds)\\n {\\n bytes32 storagePosition = K1_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function r1Storage()\\n internal\\n pure\\n returns (Secp256r1VerificationStorage storage ds)\\n {\\n bytes32 storagePosition = R1_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function guardianStorage()\\n internal\\n pure\\n returns (GuardianStorage storage ds)\\n {\\n bytes32 storagePosition = GUARDIAN_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function recoveryStorage()\\n internal\\n pure\\n returns (RecoveryStorage storage ds)\\n {\\n bytes32 storagePosition = RECOVERY_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function restrictionsStorage()\\n internal\\n pure\\n returns (RestrictionsStorage storage ds)\\n {\\n bytes32 storagePosition = RESTRICTION_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function migrationStorage()\\n internal\\n pure\\n returns (SignatureMigrationStorage storage ds)\\n {\\n bytes32 storagePosition = MIGRATION_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function diamondCutStorage()\\n internal\\n pure\\n returns (DiamondCutStorage storage ds)\\n {\\n bytes32 storagePosition = DIAMONDCUT_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function lockStorage() internal pure returns (LockStorage storage ds) {\\n bytes32 storagePosition = LOCK_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n}\\n\"\n },\n \"contracts/libraries/LibGuardian.sol\": {\n \"content\": \"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {LibFacetStorage, StorageConfig} from \\\"./LibFacetStorage.sol\\\";\\n\\n/**\\n * @title LibGuardian\\n * @dev Internal Library to provide utility feature for Guardians stored in Guardian Facet Storage\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\nlibrary LibGuardian {\\n function majorityOfGuardians()\\n internal\\n view\\n returns (uint256 guardianNumber)\\n {\\n uint256 guardianLength = guardianCount();\\n guardianNumber = (guardianLength == 0) ? 0 : guardianLength / 2 + 1;\\n }\\n\\n function isGuardian(address _guardian) internal view returns (bool) {\\n StorageConfig storage config = LibFacetStorage\\n .guardianStorage()\\n .configs[0];\\n return config.info[_guardian].exists;\\n }\\n\\n function guardianCount() internal view returns (uint256) {\\n StorageConfig storage config = LibFacetStorage\\n .guardianStorage()\\n .configs[0];\\n return config.addresses.length;\\n }\\n\\n function getGuardians() internal view returns (address[] memory) {\\n StorageConfig storage config = LibFacetStorage\\n .guardianStorage()\\n .configs[0];\\n address[] memory addresses = new address[](config.addresses.length);\\n uint256 addressesLen = config.addresses.length;\\n for (uint256 i; i < addressesLen; ) {\\n addresses[i] = config.addresses[i];\\n unchecked {\\n ++i;\\n }\\n }\\n return addresses;\\n }\\n}\\n\"\n },\n \"contracts/libraries/LibLoupe.sol\": {\n \"content\": \"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\nimport {LibDiamond} from \\\"./LibDiamond.sol\\\";\\n\\n/**\\n * @title LibLoupe\\n * @dev Internal Library to provide utility feature for reading the state of diamond facets\\n * Originally from Diamond's implementation of Mudgen(author of EIP-2535)\\n */\\nlibrary LibLoupe {\\n /// @notice Gets all facets and their selectors.\\n /// @return facets_ Facet\\n function facets()\\n internal\\n view\\n returns (IDiamondLoupe.Facet[] memory facets_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facets_ = new IDiamondLoupe.Facet[](ds.selectorCount);\\n uint16[] memory numFacetSelectors = new uint16[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facets_[facetIndex].facetAddress == facetAddress_) {\\n facets_[facetIndex].functionSelectors[\\n numFacetSelectors[facetIndex]\\n ] = selector;\\n // probably will never have more than 256 functions from one facet contract\\n require(numFacetSelectors[facetIndex] < 255);\\n numFacetSelectors[facetIndex]++;\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facets_[numFacets].facetAddress = facetAddress_;\\n facets_[numFacets].functionSelectors = new bytes4[](\\n ds.selectorCount\\n );\\n facets_[numFacets].functionSelectors[0] = selector;\\n numFacetSelectors[numFacets] = 1;\\n numFacets++;\\n }\\n }\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n uint256 numSelectors = numFacetSelectors[facetIndex];\\n bytes4[] memory selectors = facets_[facetIndex].functionSelectors;\\n // setting the number of selectors\\n assembly {\\n mstore(selectors, numSelectors)\\n }\\n }\\n // setting the number of facets\\n assembly {\\n mstore(facets_, numFacets)\\n }\\n }\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return _facetFunctionSelectors The selectors associated with a facet address.\\n function facetFunctionSelectors(\\n address _facet\\n ) internal view returns (bytes4[] memory _facetFunctionSelectors) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n uint256 numSelectors;\\n _facetFunctionSelectors = new bytes4[](ds.selectorCount);\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facet = address(bytes20(ds.facets[selector]));\\n if (_facet == facet) {\\n _facetFunctionSelectors[numSelectors] = selector;\\n numSelectors++;\\n }\\n }\\n }\\n // Set the number of selectors in the array\\n assembly {\\n mstore(_facetFunctionSelectors, numSelectors)\\n }\\n }\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n internal\\n view\\n returns (address[] memory facetAddresses_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetAddresses_ = new address[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facetAddress_ == facetAddresses_[facetIndex]) {\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facetAddresses_[numFacets] = facetAddress_;\\n numFacets++;\\n }\\n }\\n // Set the number of facet addresses in the array\\n assembly {\\n mstore(facetAddresses_, numFacets)\\n }\\n }\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(LibDiamond.diamondStorage().facets[_functionSelector])\\n );\\n }\\n}\\n\"\n },\n \"contracts/libraries/LibMultiSigStorage.sol\": {\n \"content\": \"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Multi-sig Storage\\n * @dev Storage contract for storing Multi-sig Facet variables in diamond storage pattern\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\n\\nstruct MultiSigStorage {\\n mapping(address => address) owners;\\n mapping(uint256 => mapping(address => mapping(bytes32 => uint256))) approvedHashes;\\n uint256 ownerCount;\\n uint256 threshold;\\n uint256 counter;\\n}\\n\\nlibrary LibMultiSigStorage {\\n function multisigStorage()\\n internal\\n pure\\n returns (MultiSigStorage storage ds)\\n {\\n bytes32 storagePosition = keccak256(\\n \\\"v0.trustwallet.diamond.storage.MultiSigStorage\\\"\\n );\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n}\\n\"\n },\n \"contracts/libraries/LibRecoverSpender.sol\": {\n \"content\": \"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title RecoverSpender\\n * @dev Library to determine the action and spender of calldata\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\nlibrary LibRecoverSpender {\\n // ERC20, ERC721 & ERC1155 transfers & approvals\\n bytes4 private constant ERC20_TRANSFER =\\n bytes4(keccak256(\\\"transfer(address,uint256)\\\"));\\n bytes4 private constant ERC20_APPROVE =\\n bytes4(keccak256(\\\"approve(address,uint256)\\\"));\\n bytes4 private constant ERC20_INCREASE_ALLOWANCE =\\n bytes4(keccak256(\\\"increaseAllowance(address,uint256)\\\"));\\n bytes4 private constant ERC20_DECREASE_ALLOWANCE =\\n bytes4(keccak256(\\\"decreaseAllowance(address,uint256)\\\"));\\n bytes4 private constant ERC721_SET_APPROVAL_FOR_ALL =\\n bytes4(keccak256(\\\"setApprovalForAll(address,bool)\\\"));\\n bytes4 private constant ERC721_TRANSFER_FROM =\\n bytes4(keccak256(\\\"transferFrom(address,address,uint256)\\\"));\\n bytes4 private constant ERC721_SAFE_TRANSFER_FROM =\\n bytes4(keccak256(\\\"safeTransferFrom(address,address,uint256)\\\"));\\n bytes4 private constant ERC721_SAFE_TRANSFER_FROM_BYTES =\\n bytes4(keccak256(\\\"safeTransferFrom(address,address,uint256,bytes)\\\"));\\n bytes4 private constant ERC1155_SAFE_TRANSFER_FROM =\\n bytes4(\\n keccak256(\\\"safeTransferFrom(address,address,uint256,uint256,bytes)\\\")\\n );\\n bytes4 private constant ERC1155_SAFE_BATCH_TRANSFER_FROM =\\n bytes4(\\n keccak256(\\n \\\"safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)\\\"\\n )\\n );\\n\\n /**\\n * @notice Helper method to recover the spender from a contract call.\\n * The method returns the contract unless the call is to a standard method of a ERC20/ERC721/ERC1155 token\\n * in which case the spender is recovered from the data.\\n * @param _to The target contract.\\n * @param _data The data payload.\\n */\\n function _recover(\\n address _to,\\n bytes memory _data\\n ) internal pure returns (address spender) {\\n if (_data.length >= 68) {\\n bytes4 methodId;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n methodId := mload(add(_data, 0x20))\\n }\\n if (\\n methodId == ERC20_TRANSFER ||\\n methodId == ERC20_APPROVE ||\\n methodId == ERC20_INCREASE_ALLOWANCE ||\\n methodId == ERC20_DECREASE_ALLOWANCE ||\\n methodId == ERC721_SET_APPROVAL_FOR_ALL\\n ) {\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n spender := mload(add(_data, 0x24))\\n }\\n return spender;\\n }\\n if (\\n methodId == ERC721_TRANSFER_FROM ||\\n methodId == ERC721_SAFE_TRANSFER_FROM ||\\n methodId == ERC721_SAFE_TRANSFER_FROM_BYTES ||\\n methodId == ERC1155_SAFE_TRANSFER_FROM ||\\n methodId == ERC1155_SAFE_BATCH_TRANSFER_FROM\\n ) {\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n spender := mload(add(_data, 0x44))\\n }\\n return spender;\\n }\\n }\\n\\n spender = _to;\\n }\\n}\\n\"\n },\n \"contracts/libraries/LibReentrancyGuardStorage.sol\": {\n \"content\": \"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nstruct ReentrancyGuardStorage {\\n uint256 status;\\n}\\n\\nlibrary LibReentrancyGuardStorage {\\n bytes32 private constant REENTRANCY_GUARD_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.ReentrancyGuardStorage\\\");\\n\\n function reentrancyguardStorage()\\n internal\\n pure\\n returns (ReentrancyGuardStorage storage ds)\\n {\\n bytes32 storagePosition = REENTRANCY_GUARD_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n}\"\n },\n \"contracts/libraries/LibUtils.sol\": {\n \"content\": \"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nlibrary LibUtils {\\n // Internal utility functions\\n function mergeArrays(\\n bytes4[] memory _array1,\\n bytes4[] memory _array2\\n ) internal pure returns (bytes4[] memory) {\\n uint256 length1 = _array1.length;\\n uint256 length2 = _array2.length;\\n bytes4[] memory mergedArray = new bytes4[](length1 + length2);\\n\\n for (uint256 i; i < length1; ) {\\n mergedArray[i] = _array1[i];\\n unchecked {\\n ++i;\\n }\\n }\\n\\n for (uint256 i; i < length2; ) {\\n mergedArray[length1 + i] = _array2[i];\\n unchecked {\\n ++i;\\n }\\n }\\n\\n return mergedArray;\\n }\\n\\n function removeFacetElement(\\n IDiamondLoupe.Facet[] memory _facets,\\n uint256 _index\\n ) internal pure returns (IDiamondLoupe.Facet[] memory) {\\n require(_index < _facets.length, \\\"Invalid index\\\");\\n require(_facets.length != 0, \\\"Invalid array\\\");\\n\\n // Create a new array with a length of `_facets.length - 1`\\n IDiamondLoupe.Facet[] memory newArray = new IDiamondLoupe.Facet[](\\n _facets.length - 1\\n );\\n uint256 newArrayLength = newArray.length;\\n // Iterate over the original array, skipping the element at the specified `index`\\n for (uint256 i; i < newArrayLength; ) {\\n if (i < _index) {\\n newArray[i] = _facets[i];\\n } else {\\n newArray[i] = _facets[i + 1];\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n\\n return newArray;\\n }\\n\\n function removeElement(\\n bytes4[] memory _array,\\n uint256 _index\\n ) internal pure returns (bytes4[] memory) {\\n require(_index < _array.length, \\\"Invalid index\\\");\\n require(_array.length != 0, \\\"Invalid array\\\");\\n\\n bytes4[] memory newArray = new bytes4[](_array.length - 1);\\n uint256 newArrayLength = newArray.length;\\n for (uint256 i; i < newArrayLength; ) {\\n if (i < _index) {\\n newArray[i] = _array[i];\\n } else {\\n newArray[i] = _array[i + 1];\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n\\n return newArray;\\n }\\n\\n function setValue(\\n bytes4[] memory _keys,\\n address[] memory _values,\\n bytes4 _key,\\n address _value\\n ) internal pure returns (bytes4[] memory, address[] memory) {\\n uint256 index = findIndex(_keys, _key);\\n uint256 keysLength = _keys.length;\\n if (index < keysLength) {\\n _values[index] = _value;\\n } else {\\n // Create new storage arrays\\n bytes4[] memory newKeys = new bytes4[](keysLength + 1);\\n address[] memory newValues = new address[](_values.length + 1);\\n\\n // Copy values to the new storage arrays\\n for (uint256 i; i < keysLength; ) {\\n newKeys[i] = _keys[i];\\n newValues[i] = _values[i];\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n // Add the new key-value pair\\n newKeys[keysLength] = _key;\\n newValues[_values.length] = _value;\\n\\n return (newKeys, newValues);\\n }\\n\\n // If the key already exists, return the original arrays\\n return (_keys, _values);\\n }\\n\\n function getValue(\\n bytes4[] memory _keys,\\n address[] memory _values,\\n bytes4 _key\\n ) internal pure returns (address) {\\n uint256 index = findIndex(_keys, _key);\\n if (index >= _keys.length) return address(0);\\n\\n return _values[index];\\n }\\n\\n function findIndex(\\n bytes4[] memory _keys,\\n bytes4 _key\\n ) internal pure returns (uint256) {\\n uint256 keysLength = _keys.length;\\n for (uint256 i; i < keysLength; ) {\\n if (_keys[i] == _key) {\\n return i;\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n return keysLength;\\n }\\n}\\n\"\n },\n \"contracts/restrictions/IRestriction.sol\": {\n \"content\": \"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Interface for restrictions\\n * @dev Restriction is a contract which decides whether to approve a certain kind of transaction, based on its internal logic.\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\ninterface IRestriction {\\n /**\\n * @dev Based on restriction's internal logic, it should accept or reject a certain transaction.\\n * @param from The address of the sender, that will be signing the transaction.\\n * @param to The receiving address.\\n * @param value Amount of ETH to transfer from sender to recipient.\\n * @param _calldata Optional field to include arbitrary data.\\n * @return bool value for whether the check is passed\\n */\\n function check(\\n address from,\\n address to,\\n uint256 value,\\n bytes calldata _calldata\\n ) external returns (bool);\\n}\\n\"\n },\n \"contracts/restrictions/WhitelistRestriction.sol\": {\n \"content\": \"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {LibRecoverSpender} from \\\"../libraries/LibRecoverSpender.sol\\\";\\nimport {WhitelistStorage} from \\\"../infrastructure/WhitelistStorage.sol\\\";\\nimport {IRestriction} from \\\"./IRestriction.sol\\\";\\n\\n/**\\n * @title Whitelist Restriction\\n * @dev This restriction defines a list of accepted addresses and denies any interaction with addresses outside of it.\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\ncontract WhitelistRestriction is IRestriction {\\n WhitelistStorage public immutable whitelistStorage;\\n\\n constructor(WhitelistStorage _whitelistStorage) {\\n whitelistStorage = _whitelistStorage;\\n }\\n\\n /**\\n * @notice Helper method to recover the spender from a contract call.\\n * The method returns the contract unless the call is to a standard method of a ERC20/ERC721/ERC1155 token\\n * in which case the spender is recovered from the data.\\n * @param _to The target contract.\\n * @param _data The data payload.\\n */\\n function recoverSpender(\\n address _to,\\n bytes memory _data\\n ) public pure returns (address spender) {\\n return LibRecoverSpender._recover(_to, _data);\\n }\\n\\n /*\\n * @dev IRestriction's implementation. It will allow transaction if the sender is whitelisted, or user, or the whitelist storage.\\n * @param _from The address of the sender, that will be signing the transaction.\\n * @param _to The receiving address.\\n * @param _calldata Optional field to include arbitrary data.\\n * @return result value for whether the check is passed\\n */\\n function check(\\n address _from,\\n address _to,\\n uint256 /*_value*/,\\n bytes calldata _calldata\\n ) external view override returns (bool result) {\\n return\\n whitelistStorage.isWhitelisted(\\n _from,\\n LibRecoverSpender._recover(_to, _calldata)\\n ) ||\\n _to == address(whitelistStorage) ||\\n _to == msg.sender;\\n }\\n}\\n\"\n },\n \"contracts/test/TestCounter.sol\": {\n \"content\": \"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.21;\\n\\ncontract TestCounter {\\n int private count = 0;\\n\\n event CounterIncremented(int count);\\n event CounterDecremented(int count);\\n\\n function incrementCounter() public {\\n count += 1;\\n emit CounterIncremented(count);\\n }\\n\\n function decrementCounter() public {\\n count -= 1;\\n emit CounterIncremented(count);\\n }\\n\\n function getCount() public view returns (int) {\\n return count;\\n }\\n}\\n\"\n },\n \"contracts/test/TestERC1155.sol\": {\n \"content\": \"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.0;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC1155/ERC1155.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/Counters.sol\\\";\\n\\ncontract TestERC1155 is ERC1155 {\\n using Counters for Counters.Counter;\\n\\n Counters.Counter private _tokenIds;\\n\\n constructor() ERC1155(\\\"\\\") {}\\n\\n function mint(address account, uint256 amount) external {\\n uint256 tokenId = _getNextTokenId();\\n _mint(account, tokenId, amount, \\\"\\\");\\n }\\n\\n function mintBatch(\\n address to,\\n uint256[] calldata ids,\\n uint256[] calldata amounts,\\n bytes memory data\\n ) external {\\n require(\\n ids.length == amounts.length,\\n \\\"TestERC1155: arrays length mismatch\\\"\\n );\\n\\n _mintBatch(to, ids, amounts, data);\\n }\\n\\n function _getNextTokenId() private returns (uint256) {\\n _tokenIds.increment();\\n return _tokenIds.current();\\n }\\n}\\n\"\n },\n \"contracts/test/TestERC777.sol\": {\n \"content\": \"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.0;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC777/ERC777.sol\\\";\\n\\ncontract TestERC777 is ERC777 {\\n constructor(\\n address[] memory _operators\\n ) ERC777(\\\"TestERC777\\\", \\\"TERC777\\\", _operators) {}\\n\\n function mint(address account, uint256 amount) external {\\n _mint(account, amount, \\\"\\\", \\\"\\\");\\n }\\n}\\n\"\n },\n \"contracts/test/TestInvalidSecp256k1VerificationFacet.sol\": {\n \"content\": \"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IVerificationFacet} from \\\"../facets/interfaces/IVerificationFacet.sol\\\";\\nimport {IERC1271} from \\\"../interfaces/ERC/IERC1271.sol\\\";\\nimport {AppStorage, LibAppStorage, BarzStorage} from \\\"../libraries/LibAppStorage.sol\\\";\\nimport {ECDSA} from \\\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\\\";\\nimport {LibFacetStorage, Secp256k1VerificationStorage} from \\\"../libraries/LibFacetStorage.sol\\\";\\nimport {UserOperation} from \\\"../aa-4337/interfaces/UserOperation.sol\\\";\\n\\n/**\\n * @title Test Secp256k1 verification facet\\n * @dev Default Ethereum's elliptic curve\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\ncontract TestInvalidSecp256k1VerificationFacet is BarzStorage, IERC1271 {\\n using ECDSA for bytes32;\\n error Secp256k1VerificationFacet__InvalidSignerLength();\\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\\n\\n event SignerUninitialized();\\n\\n constructor() {\\n LibAppStorage.enforceSignerInitialize();\\n }\\n\\n // THIS INVALID FACET DOES NOT INCLUDE initializeSigner()\\n // THIS FACET IS USED TO TEST WHEN initializeSigner() DOESN'T EXIST IN FACET\\n\\n function uninitializeSigner() external returns (uint256 uninitSuccess) {\\n LibAppStorage.enforceSignerMigration();\\n LibAppStorage.setSignerUninitialized();\\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\\n .k1Storage();\\n k1Storage.signer = address(0);\\n\\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\\n\\n uninitSuccess = 1;\\n\\n emit SignerUninitialized();\\n }\\n\\n function validateOwnerSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) public view returns (uint256 validationData) {\\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\\n .k1Storage();\\n return validateSignature(userOp, userOpHash, k1Storage.signer);\\n }\\n\\n function validateSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n address signer\\n ) public pure returns (uint256) {\\n bytes32 hash = userOpHash.toEthSignedMessageHash();\\n if (signer != hash.recover(userOp.signature)) return 1;\\n return 0;\\n }\\n\\n // This is REMOVED for testing purpose\\n function validateOwnerSignatureSelector() public pure returns (bytes4) {\\n // return this.validateOwnerSignature.selector;\\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\\n }\\n\\n function owner() public view returns (bytes memory) {\\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\\n .k1Storage();\\n return abi.encodePacked(k1Storage.signer);\\n }\\n\\n function isValidKeyType(\\n bytes memory _publicKey\\n ) public pure returns (bool) {\\n return (_publicKey.length == 65 && _publicKey[0] == 0x04);\\n }\\n\\n function isValidSignature(\\n bytes32 _hash,\\n bytes memory _signature\\n ) public view override returns (bytes4 magicValue) {\\n magicValue = (_hash.recover(_signature) ==\\n LibFacetStorage.k1Storage().signer)\\n ? this.isValidSignature.selector\\n : bytes4(0xffffffff);\\n }\\n}\\n\"\n },\n \"contracts/test/TestNFT.sol\": {\n \"content\": \"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.0;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC721/ERC721.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/Counters.sol\\\";\\n\\ncontract TestNFT is ERC721 {\\n using Counters for Counters.Counter;\\n Counters.Counter private currentTokenId;\\n\\n constructor() ERC721(\\\"TestNFT\\\", \\\"TNFT\\\") {}\\n\\n function mint(address recipient) public returns (uint256) {\\n currentTokenId.increment();\\n uint256 newItemId = currentTokenId.current();\\n _safeMint(recipient, newItemId);\\n return newItemId;\\n }\\n}\\n\"\n },\n \"contracts/test/TestToken.sol\": {\n \"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\n\\ncontract TestToken is ERC20 {\\n constructor()\\n // solhint-disable-next-line no-empty-blocks\\n ERC20(\\\"TST\\\", \\\"TestToken\\\")\\n {}\\n\\n function mint(address sender, uint256 amount) external {\\n _mint(sender, amount);\\n }\\n}\\n\"\n }\n },\n \"settings\": {\n \"optimizer\": {\n \"enabled\": true,\n \"runs\": 999999\n },\n \"evmVersion\": \"paris\",\n \"outputSelection\": {\n \"*\": {\n \"*\": [\n \"abi\",\n \"evm.bytecode\",\n \"evm.deployedBytecode\",\n \"evm.methodIdentifiers\",\n \"metadata\",\n \"devdoc\",\n \"userdoc\",\n \"storageLayout\",\n \"evm.gasEstimates\"\n ],\n \"\": [\n \"ast\"\n ]\n }\n },\n \"metadata\": {\n \"useLiteralContent\": true\n }\n }\n}", + "solcInputHash": "ad34345aa73d96f52b3e14df983b6b29", + "transactionHash": "0x8966a9d25a93802094c376b55426fe703c503c15e8904b051e13477e8798a82c", + "args": [] + }, + "decoded": { + "from": "0xb33654322bD3803821031624f5922eb14C9b8d18", + "gasPrice": "25312500", + "maxFeePerGas": "25312500", + "maxPriorityFeePerGas": "200000", + "gasLimit": "90000000000", + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "value": "0", + "nonce": 11, + "data": "0x000000000000000000000000000000000000000000000000000000000000000060a060405234801561001057600080fd5b50610019610022565b3060805261008b565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff161561006f57604051637c2cde8b60e01b815260040160405180910390fd5b600080805260209190915260409020805460ff19166001179055565b6080516111946100ad6000396000818161013f015261066401526111946000f3fe608060405234801561001057600080fd5b50600436106100a35760003560e01c80638da5cb5b11610076578063cd00e50a1161005b578063cd00e50a14610218578063cd9b47e414610220578063f45007c31461023357600080fd5b80638da5cb5b146101865780638dd50121146101f757600080fd5b80631626ba7e146100a85780633253960f146100f1578063392dd6d9146101175780637104ddb21461013a575b600080fd5b6100bb6100b6366004610de8565b610246565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020015b60405180910390f35b7f8dd50121000000000000000000000000000000000000000000000000000000006100bb565b61012a610125366004610e2f565b6102f4565b60405190151581526020016100e8565b6101617f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100e8565b7f9d0217145d12a316adea26b4f622aec07fb71e6638d613bb415476f4c179eecc546040805160609290921b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016602083015280518083036014018152603490920190526040516100e89190610e64565b61020a610205366004610ee9565b610366565b6040519081526020016100e8565b61020a6103b8565b61020a61022e366004610f2e565b6104d6565b61020a610241366004610fa0565b6107b7565b60007f9d0217145d12a316adea26b4f622aec07fb71e6638d613bb415476f4c179eecc5473ffffffffffffffffffffffffffffffffffffffff1661028a848461087c565b73ffffffffffffffffffffffffffffffffffffffff16146102cb577fffffffff000000000000000000000000000000000000000000000000000000006102ed565b7f1626ba7e000000000000000000000000000000000000000000000000000000005b9392505050565b60008151604114801561036057508160008151811061031557610315611014565b6020910101517fff00000000000000000000000000000000000000000000000000000000000000167f0400000000000000000000000000000000000000000000000000000000000000145b92915050565b7f9d0217145d12a316adea26b4f622aec07fb71e6638d613bb415476f4c179eecc8054600091906103b0908590859073ffffffffffffffffffffffffffffffffffffffff166107b7565b949350505050565b60006103c26108a0565b6103ca6108e0565b7f9d0217145d12a316adea26b4f622aec07fb71e6638d613bb415476f4c179eecc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001681556000610424600154610100900460e01b90565b7fffffffff00000000000000000000000000000000000000000000000000000000160361047d576040517f127c609a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff169055604051600192507fcccd30db6bc000b8bb8d11162228d2d69e3c361983ca3ae8c1365ce64b0fae9e90600090a15090565b60006104e061097f565b61051f83838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102f492505050565b610555576040517f22281e8500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f9d0217145d12a316adea26b4f622aec07fb71e6638d613bb415476f4c179eecc6105838360018187611043565b60405161059192919061106d565b60405190819003902081547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9091161781556001547f8dd501210000000000000000000000000000000000000000000000000000000090600090610100900460e01b7fffffffff000000000000000000000000000000000000000000000000000000001614610662576040517f5f95a63c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166106f3827fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604090205460601c90565b73ffffffffffffffffffffffffffffffffffffffff1614610740576040517fbb4752b700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff1661010060e084901c02179055600192507f6d54821a69ec281ed7ba1bf2729c700768c47df1d80fad646b0a14cc1d5c39ed85856040516107a792919061107d565b60405180910390a1505092915050565b7f19457468657265756d205369676e6564204d6573736167653a0a3332000000006000908152601c839052603c81206108346107f76101408701876110ca565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250859392505061087c9050565b73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361086d576000610870565b60015b60ff1695945050505050565b600080600061088b8585610a1f565b9150915061089881610a64565b509392505050565b6001805460ff16146108de576040517f38fc28cb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff16600114610948576040517fe00d7c7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff16156109e5576040517f7c2cde8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b6000808251604103610a555760208301516040840151606085015160001a610a4987828585610c1f565b94509450505050610a5d565b506000905060025b9250929050565b6000816004811115610a7857610a7861112f565b03610a805750565b6001816004811115610a9457610a9461112f565b03610b00576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064015b60405180910390fd5b6002816004811115610b1457610b1461112f565b03610b7b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610af7565b6003816004811115610b8f57610b8f61112f565b03610c1c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610af7565b50565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115610c565750600090506003610d05565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015610caa573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116610cfe57600060019250925050610d05565b9150600090505b94509492505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112610d4e57600080fd5b813567ffffffffffffffff80821115610d6957610d69610d0e565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715610daf57610daf610d0e565b81604052838152866020858801011115610dc857600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060408385031215610dfb57600080fd5b82359150602083013567ffffffffffffffff811115610e1957600080fd5b610e2585828601610d3d565b9150509250929050565b600060208284031215610e4157600080fd5b813567ffffffffffffffff811115610e5857600080fd5b6103b084828501610d3d565b600060208083528351808285015260005b81811015610e9157858101830151858201604001528201610e75565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b60006101608284031215610ee357600080fd5b50919050565b60008060408385031215610efc57600080fd5b823567ffffffffffffffff811115610f1357600080fd5b610f1f85828601610ed0565b95602094909401359450505050565b60008060208385031215610f4157600080fd5b823567ffffffffffffffff80821115610f5957600080fd5b818501915085601f830112610f6d57600080fd5b813581811115610f7c57600080fd5b866020828501011115610f8e57600080fd5b60209290920196919550909350505050565b600080600060608486031215610fb557600080fd5b833567ffffffffffffffff811115610fcc57600080fd5b610fd886828701610ed0565b93505060208401359150604084013573ffffffffffffffffffffffffffffffffffffffff8116811461100957600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000808585111561105357600080fd5b8386111561106057600080fd5b5050820193919092039150565b8183823760009101908152919050565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126110ff57600080fd5b83018035915067ffffffffffffffff82111561111a57600080fd5b602001915036819003821315610a5d57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea2646970667358221220de3368e3f3953432149ec8ab61e8db05409a34e6f3f223f6bc0a20072fa01cf364736f6c63430008150033", + "r": "0xfc36b87d20e174fa53db7f2c1745aaa3c6108b5ae4f40da4987591ed1dc331f1", + "s": "0x355b0986b6281d412721f346477a16ae7b260cde00f318fe120ad1bc385464e4", + "v": 1, + "chainId": 5000 + } + } +} \ No newline at end of file diff --git a/deployments/mantle/AccountFacet.json b/deployments/mantle/AccountFacet.json new file mode 100644 index 0000000..07c81a4 --- /dev/null +++ b/deployments/mantle/AccountFacet.json @@ -0,0 +1,591 @@ +{ + "address": "0xFde53272dcd7938d16E031A6989753c321728332", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "AccountFacet__CallNotSuccessful", + "type": "error" + }, + { + "inputs": [], + "name": "AccountFacet__InitializationFailure", + "type": "error" + }, + { + "inputs": [], + "name": "AccountFacet__InvalidArrayLength", + "type": "error" + }, + { + "inputs": [], + "name": "AccountFacet__NonExistentVerificationFacet", + "type": "error" + }, + { + "inputs": [], + "name": "AccountFacet__RestrictionsFailure", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_initializationContractAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "InitializationFunctionReverted", + "type": "error" + }, + { + "inputs": [], + "name": "LibAppStorage__AccountMustBeUninitialized", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract IEntryPoint", + "name": "entryPoint", + "type": "address" + }, + { + "indexed": true, + "internalType": "bytes", + "name": "ownerPublicKey", + "type": "bytes" + } + ], + "name": "AccountInitialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "indexed": false, + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "DiamondCut", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "VerificationFailure", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "VerificationSuccess", + "type": "event" + }, + { + "inputs": [], + "name": "entryPoint", + "outputs": [ + { + "internalType": "contract IEntryPoint", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_dest", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_func", + "type": "bytes" + } + ], + "name": "execute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_dest", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "_value", + "type": "uint256[]" + }, + { + "internalType": "bytes[]", + "name": "_func", + "type": "bytes[]" + } + ], + "name": "executeBatch", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getNonce", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_verificationFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_anEntryPoint", + "type": "address" + }, + { + "internalType": "address", + "name": "_facetRegistry", + "type": "address" + }, + { + "internalType": "address", + "name": "_defaultFallBackHandler", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_ownerPublicKey", + "type": "bytes" + } + ], + "name": "initialize", + "outputs": [ + { + "internalType": "uint256", + "name": "initSuccess", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "initCode", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "callGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "verificationGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "preVerificationGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxFeePerGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPriorityFeePerGas", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "paymasterAndData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "internalType": "struct UserOperation", + "name": "userOp", + "type": "tuple" + }, + { + "internalType": "bytes32", + "name": "userOpHash", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "missingAccountFunds", + "type": "uint256" + } + ], + "name": "validateUserOp", + "outputs": [ + { + "internalType": "uint256", + "name": "validationData", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0x93d39dc08c72b9ff35d8504a0f53cccb88750f1bf318c4de661ee422fea55400", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xb33654322bD3803821031624f5922eb14C9b8d18", + "contractAddress": null, + "transactionIndex": 8, + "gasUsed": "15626179072", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0xd8bf2c344ba168044feaefa3b007e21dcf36752f1d7444f524484363a6079463", + "transactionHash": "0x93d39dc08c72b9ff35d8504a0f53cccb88750f1bf318c4de661ee422fea55400", + "logs": [], + "blockNumber": 61655386, + "cumulativeGasUsed": "24913927487", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "ad34345aa73d96f52b3e14df983b6b29", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AccountFacet__CallNotSuccessful\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AccountFacet__InitializationFailure\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AccountFacet__InvalidArrayLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AccountFacet__NonExistentVerificationFacet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AccountFacet__RestrictionsFailure\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_initializationContractAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"InitializationFunctionReverted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LibAppStorage__AccountMustBeUninitialized\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract IEntryPoint\",\"name\":\"entryPoint\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes\",\"name\":\"ownerPublicKey\",\"type\":\"bytes\"}],\"name\":\"AccountInitialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"DiamondCut\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"VerificationFailure\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"VerificationSuccess\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"entryPoint\",\"outputs\":[{\"internalType\":\"contract IEntryPoint\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_dest\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_func\",\"type\":\"bytes\"}],\"name\":\"execute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_dest\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"_value\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes[]\",\"name\":\"_func\",\"type\":\"bytes[]\"}],\"name\":\"executeBatch\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_verificationFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_anEntryPoint\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_facetRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_defaultFallBackHandler\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_ownerPublicKey\",\"type\":\"bytes\"}],\"name\":\"initialize\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"initSuccess\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"userOp\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"missingAccountFunds\",\"type\":\"uint256\"}],\"name\":\"validateUserOp\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"validationData\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"Account module contract that provides the account features and initialization of signer compatible with EIP-1271 & EIP-4337\",\"kind\":\"dev\",\"methods\":{\"execute(address,uint256,bytes)\":{\"details\":\"This method executes the calldata coming from the EntryPoint. Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\",\"params\":{\"_dest\":\"Address of destination where the call will be forwarded to\",\"_func\":\"Bytes of calldata to execute in the destination address\",\"_value\":\"Amount of native coin the owner is willing to send(e.g. ETH, BNB)\"}},\"executeBatch(address[],uint256[],bytes[])\":{\"details\":\"This method batch executes the calldata coming from the EntryPoint. Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\",\"params\":{\"_dest\":\"Array of addresses of destination where the call will be forwarded to\",\"_func\":\"Array of bytes of calldata to execute in the destination address\",\"_value\":\"Array of amount of native coin the owner is willing to send(e.g. ETH, BNB)\"}},\"initialize(address,address,address,address,bytes)\":{\"details\":\"This method can only be called during the initialization or signature migration. If the proxy contract was created without initialization, anyone can call initialize. Barz calls initialize in constructor in an atomic transaction during deployment\",\"params\":{\"_anEntryPoint\":\"Entrypoint contract defined in EIP-4337 handling the flow of UserOp\",\"_defaultFallBackHandler\":\"Middleware contract for default facets\",\"_facetRegistry\":\"Registry of Facets that hold all facet information\",\"_ownerPublicKey\":\"Bytes of owner public key\",\"_verificationFacet\":\"Facet contract handling the verificationi\"}}},\"title\":\"Account Facet\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"This constructor ensures that this contract can only be used as singleton for Proxy contracts\"},\"entryPoint()\":{\"notice\":\"Returns the address of EntryPoint contract registered to Barz account\"},\"execute(address,uint256,bytes)\":{\"notice\":\"Calls the destination with inputted calldata and value from EntryPoint\"},\"executeBatch(address[],uint256[],bytes[])\":{\"notice\":\"Batch calls the destination with inputted calldata and value from EntryPoint\"},\"getNonce()\":{\"notice\":\"Return the account nonce. This method returns the next sequential nonce. For a nonce of a specific key, use `entrypoint.getNonce(account, key)`\"},\"initialize(address,address,address,address,bytes)\":{\"notice\":\"Initializes the initial storage of the Barz contract.\"},\"validateUserOp((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256)\":{\"notice\":\"Validate user's signature and nonce. subclass doesn't need to override this method. Instead, it should override the specific internal validation methods.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/AccountFacet.sol\":\"AccountFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./math/Math.sol\\\";\\nimport \\\"./math/SignedMath.sol\\\";\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n uint256 length = Math.log10(value) + 1;\\n string memory buffer = new string(length);\\n uint256 ptr;\\n /// @solidity memory-safe-assembly\\n assembly {\\n ptr := add(buffer, add(32, length))\\n }\\n while (true) {\\n ptr--;\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\\n }\\n value /= 10;\\n if (value == 0) break;\\n }\\n return buffer;\\n }\\n }\\n\\n /**\\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\\n */\\n function toString(int256 value) internal pure returns (string memory) {\\n return string(abi.encodePacked(value < 0 ? \\\"-\\\" : \\\"\\\", toString(SignedMath.abs(value))));\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n return toHexString(value, Math.log256(value) + 1);\\n }\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n\\n /**\\n * @dev Returns true if the two strings are equal.\\n */\\n function equal(string memory a, string memory b) internal pure returns (bool) {\\n return keccak256(bytes(a)) == keccak256(bytes(b));\\n }\\n}\\n\",\"keccak256\":\"0x3088eb2868e8d13d89d16670b5f8612c4ab9ff8956272837d8e90106c59c14a0\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Strings.sol\\\";\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSA {\\n enum RecoverError {\\n NoError,\\n InvalidSignature,\\n InvalidSignatureLength,\\n InvalidSignatureS,\\n InvalidSignatureV // Deprecated in v4.8\\n }\\n\\n function _throwError(RecoverError error) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert(\\\"ECDSA: invalid signature\\\");\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert(\\\"ECDSA: invalid signature length\\\");\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert(\\\"ECDSA: invalid signature 's' value\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature` or error string. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n *\\n * Documentation for signature generation:\\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n return tryRecover(hash, v, r, s);\\n } else {\\n return (address(0), RecoverError.InvalidSignatureLength);\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature`. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, signature);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\\n uint8 v = uint8((uint256(vs) >> 255) + 27);\\n return tryRecover(hash, v, r, s);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n *\\n * _Available since v4.2._\\n */\\n function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\\n // the valid range for s in (301): 0 < s < secp256k1n \\u00f7 2 + 1, and for v in (302): v \\u2208 {27, 28}. Most\\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\\n //\\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\\n // these malleable signatures as well.\\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n return (address(0), RecoverError.InvalidSignatureS);\\n }\\n\\n // If the signature is valid (and not malleable), return the signer address\\n address signer = ecrecover(hash, v, r, s);\\n if (signer == address(0)) {\\n return (address(0), RecoverError.InvalidSignature);\\n }\\n\\n return (signer, RecoverError.NoError);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore(0x00, \\\"\\\\x19Ethereum Signed Message:\\\\n32\\\")\\n mstore(0x1c, hash)\\n message := keccak256(0x00, 0x3c)\\n }\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from `s`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n\\\", Strings.toString(s.length), s));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Typed Data, created from a\\n * `domainSeparator` and a `structHash`. This produces hash corresponding\\n * to the one signed with the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n * JSON-RPC method as part of EIP-712.\\n *\\n * See {recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n let ptr := mload(0x40)\\n mstore(ptr, \\\"\\\\x19\\\\x01\\\")\\n mstore(add(ptr, 0x02), domainSeparator)\\n mstore(add(ptr, 0x22), structHash)\\n data := keccak256(ptr, 0x42)\\n }\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Data with intended validator, created from a\\n * `validator` and `data` according to the version 0 of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x00\\\", validator, data));\\n }\\n}\\n\",\"keccak256\":\"0x809bc3edb4bcbef8263fa616c1b60ee0004b50a8a1bfa164d8f57fd31f520c58\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n enum Rounding {\\n Down, // Toward negative infinity\\n Up, // Toward infinity\\n Zero // Toward zero\\n }\\n\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow.\\n return (a & b) + (a ^ b) / 2;\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a == 0 ? 0 : (a - 1) / b + 1;\\n }\\n\\n /**\\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\\n * with further edits by Uniswap Labs also under MIT license.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\\n unchecked {\\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2^256 + prod0.\\n uint256 prod0; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division.\\n if (prod1 == 0) {\\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\\n // The surrounding unchecked block does not change this fact.\\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\\n return prod0 / denominator;\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n require(denominator > prod1, \\\"Math: mulDiv overflow\\\");\\n\\n ///////////////////////////////////////////////\\n // 512 by 256 division.\\n ///////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0].\\n uint256 remainder;\\n assembly {\\n // Compute remainder using mulmod.\\n remainder := mulmod(x, y, denominator)\\n\\n // Subtract 256 bit number from 512 bit number.\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\\n // See https://cs.stackexchange.com/q/138556/92363.\\n\\n // Does not overflow because the denominator cannot be zero at this stage in the function.\\n uint256 twos = denominator & (~denominator + 1);\\n assembly {\\n // Divide denominator by twos.\\n denominator := div(denominator, twos)\\n\\n // Divide [prod1 prod0] by twos.\\n prod0 := div(prod0, twos)\\n\\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\\n twos := add(div(sub(0, twos), twos), 1)\\n }\\n\\n // Shift in bits from prod1 into prod0.\\n prod0 |= prod1 * twos;\\n\\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\\n // four bits. That is, denominator * inv = 1 mod 2^4.\\n uint256 inverse = (3 * denominator) ^ 2;\\n\\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\\n // in modular arithmetic, doubling the correct bits in each step.\\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\\n\\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inverse;\\n return result;\\n }\\n }\\n\\n /**\\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\\n uint256 result = mulDiv(x, y, denominator);\\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\\n result += 1;\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\\n *\\n * Inspired by Henry S. Warren, Jr.'s \\\"Hacker's Delight\\\" (Chapter 11).\\n */\\n function sqrt(uint256 a) internal pure returns (uint256) {\\n if (a == 0) {\\n return 0;\\n }\\n\\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\\n //\\n // We know that the \\\"msb\\\" (most significant bit) of our target number `a` is a power of 2 such that we have\\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\\n //\\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\\n // \\u2192 `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\\n // \\u2192 `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\\n //\\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\\n uint256 result = 1 << (log2(a) >> 1);\\n\\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\\n // into the expected uint128 result.\\n unchecked {\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n return min(result, a / result);\\n }\\n }\\n\\n /**\\n * @notice Calculates sqrt(a), following the selected rounding direction.\\n */\\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = sqrt(a);\\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 2, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 128;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 64;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 32;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 16;\\n }\\n if (value >> 8 > 0) {\\n value >>= 8;\\n result += 8;\\n }\\n if (value >> 4 > 0) {\\n value >>= 4;\\n result += 4;\\n }\\n if (value >> 2 > 0) {\\n value >>= 2;\\n result += 2;\\n }\\n if (value >> 1 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log2(value);\\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 10, rounded down, of a positive value.\\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 + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 256, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n *\\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\\n */\\n function log256(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 16;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 8;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 4;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 2;\\n }\\n if (value >> 8 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log256(value);\\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe4455ac1eb7fc497bb7402579e7b4d64d928b846fce7d2b6fde06d366f21c2b3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\\n * checks.\\n *\\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\\n * easily result in undesired exploitation or bugs, since developers usually\\n * assume that overflows raise errors. `SafeCast` restores this intuition by\\n * reverting the transaction when such an operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n *\\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\\n * all math on `uint256` and `int256` and then downcasting.\\n */\\nlibrary SafeCast {\\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 * _Available since v4.7._\\n */\\n function toUint248(uint256 value) internal pure returns (uint248) {\\n require(value <= type(uint248).max, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint240(uint256 value) internal pure returns (uint240) {\\n require(value <= type(uint240).max, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint232(uint256 value) internal pure returns (uint232) {\\n require(value <= type(uint232).max, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint224(uint256 value) internal pure returns (uint224) {\\n require(value <= type(uint224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint216(uint256 value) internal pure returns (uint216) {\\n require(value <= type(uint216).max, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint208(uint256 value) internal pure returns (uint208) {\\n require(value <= type(uint208).max, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint200(uint256 value) internal pure returns (uint200) {\\n require(value <= type(uint200).max, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint192(uint256 value) internal pure returns (uint192) {\\n require(value <= type(uint192).max, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint184(uint256 value) internal pure returns (uint184) {\\n require(value <= type(uint184).max, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint176(uint256 value) internal pure returns (uint176) {\\n require(value <= type(uint176).max, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint168(uint256 value) internal pure returns (uint168) {\\n require(value <= type(uint168).max, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint160(uint256 value) internal pure returns (uint160) {\\n require(value <= type(uint160).max, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint152(uint256 value) internal pure returns (uint152) {\\n require(value <= type(uint152).max, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint144(uint256 value) internal pure returns (uint144) {\\n require(value <= type(uint144).max, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint136(uint256 value) internal pure returns (uint136) {\\n require(value <= type(uint136).max, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint128(uint256 value) internal pure returns (uint128) {\\n require(value <= type(uint128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint120(uint256 value) internal pure returns (uint120) {\\n require(value <= type(uint120).max, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint112(uint256 value) internal pure returns (uint112) {\\n require(value <= type(uint112).max, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint104(uint256 value) internal pure returns (uint104) {\\n require(value <= type(uint104).max, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint96(uint256 value) internal pure returns (uint96) {\\n require(value <= type(uint96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint88(uint256 value) internal pure returns (uint88) {\\n require(value <= type(uint88).max, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint80(uint256 value) internal pure returns (uint80) {\\n require(value <= type(uint80).max, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint72(uint256 value) internal pure returns (uint72) {\\n require(value <= type(uint72).max, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint64(uint256 value) internal pure returns (uint64) {\\n require(value <= type(uint64).max, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint56(uint256 value) internal pure returns (uint56) {\\n require(value <= type(uint56).max, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint48(uint256 value) internal pure returns (uint48) {\\n require(value <= type(uint48).max, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint40(uint256 value) internal pure returns (uint40) {\\n require(value <= type(uint40).max, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint32(uint256 value) internal pure returns (uint32) {\\n require(value <= type(uint32).max, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint24(uint256 value) internal pure returns (uint24) {\\n require(value <= type(uint24).max, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint16(uint256 value) internal pure returns (uint16) {\\n require(value <= type(uint16).max, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint8(uint256 value) internal pure returns (uint8) {\\n require(value <= type(uint8).max, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\n */\\n function toUint256(int256 value) internal pure returns (uint256) {\\n require(value >= 0, \\\"SafeCast: value must be positive\\\");\\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 * _Available since v4.7._\\n */\\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\\n downcasted = int248(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\\n downcasted = int240(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\\n downcasted = int232(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\\n downcasted = int224(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\\n downcasted = int216(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\\n downcasted = int208(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\\n downcasted = int200(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\\n downcasted = int192(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\\n downcasted = int184(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\\n downcasted = int176(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\\n downcasted = int168(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\\n downcasted = int160(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\\n downcasted = int152(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\\n downcasted = int144(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\\n downcasted = int136(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\\n downcasted = int128(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\\n downcasted = int120(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\\n downcasted = int112(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\\n downcasted = int104(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\\n downcasted = int96(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\\n downcasted = int88(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\\n downcasted = int80(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\\n downcasted = int72(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\\n downcasted = int64(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\\n downcasted = int56(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\\n downcasted = int48(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\\n downcasted = int40(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\\n downcasted = int32(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\\n downcasted = int24(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\\n downcasted = int16(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\\n downcasted = int8(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\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 require(value <= uint256(type(int256).max), \\\"SafeCast: value doesn't fit in an int256\\\");\\n return int256(value);\\n }\\n}\\n\",\"keccak256\":\"0x52a8cfb0f5239d11b457dcdd1b326992ef672714ca8da71a157255bddd13f3ad\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SignedMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard signed math utilities missing in the Solidity language.\\n */\\nlibrary SignedMath {\\n /**\\n * @dev Returns the largest of two signed numbers.\\n */\\n function max(int256 a, int256 b) internal pure returns (int256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two signed numbers.\\n */\\n function min(int256 a, int256 b) internal pure returns (int256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two signed numbers without overflow.\\n * The result is rounded towards zero.\\n */\\n function average(int256 a, int256 b) internal pure returns (int256) {\\n // Formula from the book \\\"Hacker's Delight\\\"\\n int256 x = (a & b) + ((a ^ b) >> 1);\\n return x + (int256(uint256(x) >> 255) & (a ^ b));\\n }\\n\\n /**\\n * @dev Returns the absolute unsigned value of a signed value.\\n */\\n function abs(int256 n) internal pure returns (uint256) {\\n unchecked {\\n // must be unchecked in order to support `n = type(int256).min`\\n return uint256(n >= 0 ? n : -n);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf92515413956f529d95977adc9b0567d583c6203fc31ab1c23824c35187e3ddc\",\"license\":\"MIT\"},\"contracts/aa-4337/core/BaseAccount.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-empty-blocks */\\n\\nimport \\\"../interfaces/IAccount.sol\\\";\\nimport \\\"../interfaces/IEntryPoint.sol\\\";\\nimport \\\"./Helpers.sol\\\";\\n\\n/**\\n * Basic account implementation.\\n * this contract provides the basic logic for implementing the IAccount interface - validateUserOp\\n * specific account implementation should inherit it and provide the account-specific logic\\n */\\nabstract contract BaseAccount is IAccount {\\n using UserOperationLib for UserOperation;\\n\\n //return value in case of signature failure, with no time-range.\\n // equivalent to _packValidationData(true,0,0);\\n uint256 internal constant SIG_VALIDATION_FAILED = 1;\\n\\n /**\\n * Return the account nonce.\\n * This method returns the next sequential nonce.\\n * For a nonce of a specific key, use `entrypoint.getNonce(account, key)`\\n */\\n function getNonce() public view virtual returns (uint256) {\\n return entryPoint().getNonce(address(this), 0);\\n }\\n\\n /**\\n * return the entryPoint used by this account.\\n * subclass should return the current entryPoint used by this account.\\n */\\n function entryPoint() public view virtual returns (IEntryPoint);\\n\\n /**\\n * Validate user's signature and nonce.\\n * subclass doesn't need to override this method. Instead, it should override the specific internal validation methods.\\n */\\n function validateUserOp(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n uint256 missingAccountFunds\\n ) external virtual override returns (uint256 validationData) {\\n _requireFromEntryPoint();\\n validationData = _validateSignature(userOp, userOpHash);\\n _validateNonce(userOp.nonce);\\n _payPrefund(missingAccountFunds);\\n }\\n\\n /**\\n * ensure the request comes from the known entrypoint.\\n */\\n function _requireFromEntryPoint() internal view virtual {\\n require(\\n msg.sender == address(entryPoint()),\\n \\\"account: not from EntryPoint\\\"\\n );\\n }\\n\\n /**\\n * validate the signature is valid for this message.\\n * @param userOp validate the userOp.signature field\\n * @param userOpHash convenient field: the hash of the request, to check the signature against\\n * (also hashes the entrypoint and chain id)\\n * @return validationData signature and time-range of this operation\\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\\n * otherwise, an address of an \\\"authorizer\\\" contract.\\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \\\"indefinite\\\"\\n * <6-byte> validAfter - first timestamp this operation is valid\\n * If the account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\\n */\\n function _validateSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) internal virtual returns (uint256 validationData);\\n\\n /**\\n * Validate the nonce of the UserOperation.\\n * This method may validate the nonce requirement of this account.\\n * e.g.\\n * To limit the nonce to use sequenced UserOps only (no \\\"out of order\\\" UserOps):\\n * `require(nonce < type(uint64).max)`\\n * For a hypothetical account that *requires* the nonce to be out-of-order:\\n * `require(nonce & type(uint64).max == 0)`\\n *\\n * The actual nonce uniqueness is managed by the EntryPoint, and thus no other\\n * action is needed by the account itself.\\n *\\n * @param nonce to validate\\n *\\n * solhint-disable-next-line no-empty-blocks\\n */\\n function _validateNonce(uint256 nonce) internal view virtual {}\\n\\n /**\\n * sends to the entrypoint (msg.sender) the missing funds for this transaction.\\n * subclass MAY override this method for better funds management\\n * (e.g. send to the entryPoint more than the minimum required, so that in future transactions\\n * it will not be required to send again)\\n * @param missingAccountFunds the minimum value this method should send the entrypoint.\\n * this value MAY be zero, in case there is enough deposit, or the userOp has a paymaster.\\n */\\n function _payPrefund(uint256 missingAccountFunds) internal virtual {\\n if (missingAccountFunds != 0) {\\n (bool success, ) = payable(msg.sender).call{\\n value: missingAccountFunds,\\n gas: type(uint256).max\\n }(\\\"\\\");\\n (success);\\n //ignore failure (its EntryPoint's job to verify, not account.)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa0dcc386b0f04711db3e394fb50e55a3b3b1a4d19fac1f10895844e1aa4e3d5c\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/core/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable no-inline-assembly */\\n\\n/**\\n * returned data from validateUserOp.\\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\\n * @param aggregator - address(0) - the account validated the signature by itself.\\n * address(1) - the account failed to validate the signature.\\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\\n * @param validAfter - this UserOp is valid only after this timestamp.\\n * @param validaUntil - this UserOp is valid only up to this timestamp.\\n */\\nstruct ValidationData {\\n address aggregator;\\n uint48 validAfter;\\n uint48 validUntil;\\n}\\n\\n//extract sigFailed, validAfter, validUntil.\\n// also convert zero validUntil to type(uint48).max\\nfunction _parseValidationData(\\n uint validationData\\n) pure returns (ValidationData memory data) {\\n address aggregator = address(uint160(validationData));\\n uint48 validUntil = uint48(validationData >> 160);\\n if (validUntil == 0) {\\n validUntil = type(uint48).max;\\n }\\n uint48 validAfter = uint48(validationData >> (48 + 160));\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n// intersect account and paymaster ranges.\\nfunction _intersectTimeRange(\\n uint256 validationData,\\n uint256 paymasterValidationData\\n) pure returns (ValidationData memory) {\\n ValidationData memory accountValidationData = _parseValidationData(\\n validationData\\n );\\n ValidationData memory pmValidationData = _parseValidationData(\\n paymasterValidationData\\n );\\n address aggregator = accountValidationData.aggregator;\\n if (aggregator == address(0)) {\\n aggregator = pmValidationData.aggregator;\\n }\\n uint48 validAfter = accountValidationData.validAfter;\\n uint48 validUntil = accountValidationData.validUntil;\\n uint48 pmValidAfter = pmValidationData.validAfter;\\n uint48 pmValidUntil = pmValidationData.validUntil;\\n\\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp\\n * @param data - the ValidationData to pack\\n */\\nfunction _packValidationData(\\n ValidationData memory data\\n) pure returns (uint256) {\\n return\\n uint160(data.aggregator) |\\n (uint256(data.validUntil) << 160) |\\n (uint256(data.validAfter) << (160 + 48));\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp, when not using an aggregator\\n * @param sigFailed - true for signature failure, false for success\\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\\n * @param validAfter first timestamp this UserOperation is valid\\n */\\nfunction _packValidationData(\\n bool sigFailed,\\n uint48 validUntil,\\n uint48 validAfter\\n) pure returns (uint256) {\\n return\\n (sigFailed ? 1 : 0) |\\n (uint256(validUntil) << 160) |\\n (uint256(validAfter) << (160 + 48));\\n}\\n\\n/**\\n * keccak function over calldata.\\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\\n */\\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\\n assembly {\\n let mem := mload(0x40)\\n let len := data.length\\n calldatacopy(mem, data.offset, len)\\n ret := keccak256(mem, len)\\n }\\n}\\n\",\"keccak256\":\"0xa79f06cd158ecb8c0da95493a2f348933b8627a63e228b99738bff3aa107942d\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAccount.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\ninterface IAccount {\\n /**\\n * Validate user's signature and nonce\\n * the entryPoint will make the call to the recipient only if this validation call returns successfully.\\n * signature failure should be reported by returning SIG_VALIDATION_FAILED (1).\\n * This allows making a \\\"simulation call\\\" without a valid signature\\n * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure.\\n *\\n * @dev Must validate caller is the entryPoint.\\n * Must validate the signature and nonce\\n * @param userOp the operation that is about to be executed.\\n * @param userOpHash hash of the user's request data. can be used as the basis for signature.\\n * @param missingAccountFunds missing funds on the account's deposit in the entrypoint.\\n * This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call.\\n * The excess is left as a deposit in the entrypoint, for future calls.\\n * can be withdrawn anytime using \\\"entryPoint.withdrawTo()\\\"\\n * In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero.\\n * @return validationData packaged ValidationData structure. use `_packValidationData` and `_unpackValidationData` to encode and decode\\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\\n * otherwise, an address of an \\\"authorizer\\\" contract.\\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \\\"indefinite\\\"\\n * <6-byte> validAfter - first timestamp this operation is valid\\n * If an account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\\n */\\n function validateUserOp(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n uint256 missingAccountFunds\\n ) external returns (uint256 validationData);\\n}\\n\",\"keccak256\":\"0xcbc4b0973cf954c5895b7796335f651fbfcfb55f67dfa789a3d354f8e23c4f2b\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAggregator.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\n/**\\n * Aggregated Signatures validator.\\n */\\ninterface IAggregator {\\n /**\\n * validate aggregated signature.\\n * revert if the aggregated signature does not match the given list of operations.\\n */\\n function validateSignatures(\\n UserOperation[] calldata userOps,\\n bytes calldata signature\\n ) external view;\\n\\n /**\\n * validate signature of a single userOp\\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\\n * @param userOp the userOperation received from the user.\\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\\n * (usually empty, unless account and aggregator support some kind of \\\"multisig\\\"\\n */\\n function validateUserOpSignature(\\n UserOperation calldata userOp\\n ) external view returns (bytes memory sigForUserOp);\\n\\n /**\\n * aggregate multiple signatures into a single value.\\n * This method is called off-chain to calculate the signature to pass with handleOps()\\n * bundler MAY use optimized custom code perform this aggregation\\n * @param userOps array of UserOperations to collect the signatures from.\\n * @return aggregatedSignature the aggregated signature\\n */\\n function aggregateSignatures(\\n UserOperation[] calldata userOps\\n ) external view returns (bytes memory aggregatedSignature);\\n}\\n\",\"keccak256\":\"0xdfdcd80568f037716674619b31be630fcd8316262f05a815b41d1e81782c966a\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IEntryPoint.sol\":{\"content\":\"/**\\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\\n ** Only one instance required on each chain.\\n **/\\n// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-inline-assembly */\\n/* solhint-disable reason-string */\\n\\nimport \\\"./UserOperation.sol\\\";\\nimport \\\"./IStakeManager.sol\\\";\\nimport \\\"./IAggregator.sol\\\";\\nimport \\\"./INonceManager.sol\\\";\\n\\ninterface IEntryPoint is IStakeManager, INonceManager {\\n /***\\n * An event emitted after each successful request\\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\\n * @param sender - the account that generates this request.\\n * @param paymaster - if non-null, the paymaster that pays for this request.\\n * @param nonce - the nonce value from the request.\\n * @param success - true if the sender transaction succeeded, false if reverted.\\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\\n */\\n event UserOperationEvent(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address indexed paymaster,\\n uint256 nonce,\\n bool success,\\n uint256 actualGasCost,\\n uint256 actualGasUsed\\n );\\n\\n /**\\n * account \\\"sender\\\" was deployed.\\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\\n * @param sender the account that is deployed\\n * @param factory the factory used to deploy this account (in the initCode)\\n * @param paymaster the paymaster used by this UserOp\\n */\\n event AccountDeployed(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address factory,\\n address paymaster\\n );\\n\\n /**\\n * An event emitted if the UserOperation \\\"callData\\\" reverted with non-zero length\\n * @param userOpHash the request unique identifier.\\n * @param sender the sender of this request\\n * @param nonce the nonce used in the request\\n * @param revertReason - the return bytes from the (reverted) call to \\\"callData\\\".\\n */\\n event UserOperationRevertReason(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n uint256 nonce,\\n bytes revertReason\\n );\\n\\n /**\\n * an event emitted by handleOps(), before starting the execution loop.\\n * any event emitted before this event, is part of the validation.\\n */\\n event BeforeExecution();\\n\\n /**\\n * signature aggregator used by the following UserOperationEvents within this bundle.\\n */\\n event SignatureAggregatorChanged(address indexed aggregator);\\n\\n /**\\n * a custom revert error of handleOps, to identify the offending op.\\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\\n * @param reason - revert reason\\n * The string starts with a unique code \\\"AAmn\\\", where \\\"m\\\" is \\\"1\\\" for factory, \\\"2\\\" for account and \\\"3\\\" for paymaster issues,\\n * so a failure can be attributed to the correct entity.\\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\\n */\\n error FailedOp(uint256 opIndex, string reason);\\n\\n /**\\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\\n */\\n error SignatureValidationFailed(address aggregator);\\n\\n /**\\n * Successful result from simulateValidation.\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n */\\n error ValidationResult(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo\\n );\\n\\n /**\\n * Successful result from simulateValidation, if the account returns a signature aggregator\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\\n * bundler MUST use it to verify the signature, or reject the UserOperation\\n */\\n error ValidationResultWithAggregation(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo,\\n AggregatorStakeInfo aggregatorInfo\\n );\\n\\n /**\\n * return value of getSenderAddress\\n */\\n error SenderAddressResult(address sender);\\n\\n /**\\n * return value of simulateHandleOp\\n */\\n error ExecutionResult(\\n uint256 preOpGas,\\n uint256 paid,\\n uint48 validAfter,\\n uint48 validUntil,\\n bool targetSuccess,\\n bytes targetResult\\n );\\n\\n //UserOps handled, per aggregator\\n struct UserOpsPerAggregator {\\n UserOperation[] userOps;\\n // aggregator address\\n IAggregator aggregator;\\n // aggregated signature\\n bytes signature;\\n }\\n\\n /**\\n * Execute a batch of UserOperation.\\n * no signature aggregator is used.\\n * if any account requires an aggregator (that is, it returned an aggregator when\\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\\n * @param ops the operations to execute\\n * @param beneficiary the address to receive the fees\\n */\\n function handleOps(\\n UserOperation[] calldata ops,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * Execute a batch of UserOperation with Aggregators\\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\\n * @param beneficiary the address to receive the fees\\n */\\n function handleAggregatedOps(\\n UserOpsPerAggregator[] calldata opsPerAggregator,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * generate a request Id - unique identifier for this request.\\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\\n */\\n function getUserOpHash(\\n UserOperation calldata userOp\\n ) external view returns (bytes32);\\n\\n /**\\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\\n * @param userOp the user operation to validate.\\n */\\n function simulateValidation(UserOperation calldata userOp) external;\\n\\n /**\\n * gas and return values during simulation\\n * @param preOpGas the gas used for validation (including preValidationGas)\\n * @param prefund the required prefund for this operation\\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\\n */\\n struct ReturnInfo {\\n uint256 preOpGas;\\n uint256 prefund;\\n bool sigFailed;\\n uint48 validAfter;\\n uint48 validUntil;\\n bytes paymasterContext;\\n }\\n\\n /**\\n * returned aggregated signature info.\\n * the aggregator returned by the account, and its current stake.\\n */\\n struct AggregatorStakeInfo {\\n address aggregator;\\n StakeInfo stakeInfo;\\n }\\n\\n /**\\n * Get counterfactual sender address.\\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\\n * this method always revert, and returns the address in SenderAddressResult error\\n * @param initCode the constructor code to be passed into the UserOperation.\\n */\\n function getSenderAddress(bytes memory initCode) external;\\n\\n /**\\n * simulate full execution of a UserOperation (including both validation and target execution)\\n * this method will always revert with \\\"ExecutionResult\\\".\\n * it performs full validation of the UserOperation, but ignores signature error.\\n * an optional target address is called after the userop succeeds, and its value is returned\\n * (before the entire call is reverted)\\n * Note that in order to collect the the success/failure of the target call, it must be executed\\n * with trace enabled to track the emitted events.\\n * @param op the UserOperation to simulate\\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\\n * are set to the return from that call.\\n * @param targetCallData callData to pass to target address\\n */\\n function simulateHandleOp(\\n UserOperation calldata op,\\n address target,\\n bytes calldata targetCallData\\n ) external;\\n}\\n\",\"keccak256\":\"0x9ccb1b188eda8bbf5f6c2d01bd83c3d8b2b04fcf745283051d31fe96d1d8e40f\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/INonceManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\ninterface INonceManager {\\n /**\\n * Return the next nonce for this sender.\\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\\n * But UserOp with different keys can come with arbitrary order.\\n *\\n * @param sender the account address\\n * @param key the high 192 bit of the nonce\\n * @return nonce a full nonce to pass for next UserOp with this sender.\\n */\\n function getNonce(\\n address sender,\\n uint192 key\\n ) external view returns (uint256 nonce);\\n\\n /**\\n * Manually increment the nonce of the sender.\\n * This method is exposed just for completeness..\\n * Account does NOT need to call it, neither during validation, nor elsewhere,\\n * as the EntryPoint will update the nonce regardless.\\n * Possible use-case is call it with various keys to \\\"initialize\\\" their nonces to one, so that future\\n * UserOperations will not pay extra for the first transaction with a given key.\\n */\\n function incrementNonce(uint192 key) external;\\n}\\n\",\"keccak256\":\"0xce478ad0fa0d18a3b785ac854623029e7ab463d05873dfaa365abfa1bf100912\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IStakeManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8.12;\\n\\n/**\\n * manage deposits and stakes.\\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\\n * stake is value locked for at least \\\"unstakeDelay\\\" by the staked entity.\\n */\\ninterface IStakeManager {\\n event Deposited(address indexed account, uint256 totalDeposit);\\n\\n event Withdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /// Emitted when stake or unstake delay are modified\\n event StakeLocked(\\n address indexed account,\\n uint256 totalStaked,\\n uint256 unstakeDelaySec\\n );\\n\\n /// Emitted once a stake is scheduled for withdrawal\\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\\n\\n event StakeWithdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /**\\n * @param deposit the entity's deposit\\n * @param staked true if this entity is staked.\\n * @param stake actual amount of ether staked for this entity.\\n * @param unstakeDelaySec minimum delay to withdraw the stake.\\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\\n * and the rest fit into a 2nd cell.\\n * 112 bit allows for 10^15 eth\\n * 48 bit for full timestamp\\n * 32 bit allows 150 years for unstake delay\\n */\\n struct DepositInfo {\\n uint112 deposit;\\n bool staked;\\n uint112 stake;\\n uint32 unstakeDelaySec;\\n uint48 withdrawTime;\\n }\\n\\n //API struct used by getStakeInfo and simulateValidation\\n struct StakeInfo {\\n uint256 stake;\\n uint256 unstakeDelaySec;\\n }\\n\\n /// @return info - full deposit information of given account\\n function getDepositInfo(\\n address account\\n ) external view returns (DepositInfo memory info);\\n\\n /// @return the deposit (for gas payment) of the account\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * add to the deposit of the given account\\n */\\n function depositTo(address account) external payable;\\n\\n /**\\n * add to the account's stake - amount and delay\\n * any pending unstake is first cancelled.\\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\\n */\\n function addStake(uint32 _unstakeDelaySec) external payable;\\n\\n /**\\n * attempt to unlock the stake.\\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\\n */\\n function unlockStake() external;\\n\\n /**\\n * withdraw from the (unlocked) stake.\\n * must first call unlockStake and wait for the unstakeDelay to pass\\n * @param withdrawAddress the address to send withdrawn value.\\n */\\n function withdrawStake(address payable withdrawAddress) external;\\n\\n /**\\n * withdraw from the deposit.\\n * @param withdrawAddress the address to send withdrawn value.\\n * @param withdrawAmount the amount to withdraw.\\n */\\n function withdrawTo(\\n address payable withdrawAddress,\\n uint256 withdrawAmount\\n ) external;\\n}\\n\",\"keccak256\":\"0xadcea606c9b7aafe6645441f2154a60f271330b0eee5292a632aa71c1672d546\",\"license\":\"GPL-3.0-only\"},\"contracts/aa-4337/interfaces/UserOperation.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable no-inline-assembly */\\n\\nimport {calldataKeccak} from \\\"../core/Helpers.sol\\\";\\n\\n/**\\n * User Operation struct\\n * @param sender the sender account of this request.\\n * @param nonce unique value the sender uses to verify it is not a replay.\\n * @param initCode if set, the account contract will be created by this constructor/\\n * @param callData the method call to execute on this account.\\n * @param callGasLimit the gas limit passed to the callData method call.\\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\\n * @param maxFeePerGas same as EIP-1559 gas parameter.\\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\\n */\\nstruct UserOperation {\\n address sender;\\n uint256 nonce;\\n bytes initCode;\\n bytes callData;\\n uint256 callGasLimit;\\n uint256 verificationGasLimit;\\n uint256 preVerificationGas;\\n uint256 maxFeePerGas;\\n uint256 maxPriorityFeePerGas;\\n bytes paymasterAndData;\\n bytes signature;\\n}\\n\\n/**\\n * Utility functions helpful when working with UserOperation structs.\\n */\\nlibrary UserOperationLib {\\n function getSender(\\n UserOperation calldata userOp\\n ) internal pure returns (address) {\\n address data;\\n //read sender from userOp, which is first userOp member (saves 800 gas...)\\n assembly {\\n data := calldataload(userOp)\\n }\\n return address(uint160(data));\\n }\\n\\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\\n // pay above what he signed for.\\n function gasPrice(\\n UserOperation calldata userOp\\n ) internal view returns (uint256) {\\n unchecked {\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n if (maxFeePerGas == maxPriorityFeePerGas) {\\n //legacy mode (for networks that don't support basefee opcode)\\n return maxFeePerGas;\\n }\\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\\n }\\n }\\n\\n function pack(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes memory ret) {\\n address sender = getSender(userOp);\\n uint256 nonce = userOp.nonce;\\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\\n bytes32 hashCallData = calldataKeccak(userOp.callData);\\n uint256 callGasLimit = userOp.callGasLimit;\\n uint256 verificationGasLimit = userOp.verificationGasLimit;\\n uint256 preVerificationGas = userOp.preVerificationGas;\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\\n\\n return\\n abi.encode(\\n sender,\\n nonce,\\n hashInitCode,\\n hashCallData,\\n callGasLimit,\\n verificationGasLimit,\\n preVerificationGas,\\n maxFeePerGas,\\n maxPriorityFeePerGas,\\n hashPaymasterAndData\\n );\\n }\\n\\n function hash(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes32) {\\n return keccak256(pack(userOp));\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n}\\n\",\"keccak256\":\"0x2429f5cc546bdee08c7e63858d0dda8491eaa3ab5194df884dc948c1154d2834\",\"license\":\"GPL-3.0\"},\"contracts/facets/AccountFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {ECDSA} from \\\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\\\";\\nimport {UserOperation} from \\\"../aa-4337/interfaces/UserOperation.sol\\\";\\nimport {IEntryPoint} from \\\"../aa-4337/interfaces/IEntryPoint.sol\\\";\\nimport {BaseAccount} from \\\"../aa-4337/core/BaseAccount.sol\\\";\\nimport {LibAppStorage, BarzStorage} from \\\"../libraries/LibAppStorage.sol\\\";\\nimport {LibDiamond} from \\\"../libraries/LibDiamond.sol\\\";\\nimport {LibLoupe} from \\\"../libraries/LibLoupe.sol\\\";\\nimport {IFacetRegistry} from \\\"../infrastructure/interfaces/IFacetRegistry.sol\\\";\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\nimport {IVerificationFacet} from \\\"./interfaces/IVerificationFacet.sol\\\";\\nimport {IERC1271} from \\\"../interfaces/ERC/IERC1271.sol\\\";\\nimport {IAccountFacet} from \\\"./interfaces/IAccountFacet.sol\\\";\\n\\n/**\\n * @title Account Facet\\n * @dev Account module contract that provides the account features and initialization of signer\\n * compatible with EIP-1271 & EIP-4337\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract AccountFacet is IAccountFacet, BarzStorage, BaseAccount {\\n using ECDSA for bytes32;\\n\\n /**\\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\\n */\\n constructor() {\\n LibAppStorage.enforceAccountInitialize();\\n }\\n\\n /**\\n * @notice Returns the address of EntryPoint contract registered to Barz account\\n */\\n function entryPoint() public view override returns (IEntryPoint) {\\n return s.entryPoint;\\n }\\n\\n /**\\n * @notice Initializes the initial storage of the Barz contract.\\n * @dev This method can only be called during the initialization or signature migration.\\n * If the proxy contract was created without initialization, anyone can call initialize.\\n * Barz calls initialize in constructor in an atomic transaction during deployment\\n * @param _verificationFacet Facet contract handling the verificationi\\n * @param _anEntryPoint Entrypoint contract defined in EIP-4337 handling the flow of UserOp\\n * @param _facetRegistry Registry of Facets that hold all facet information\\n * @param _defaultFallBackHandler Middleware contract for default facets\\n * @param _ownerPublicKey Bytes of owner public key\\n */\\n function initialize(\\n address _verificationFacet,\\n address _anEntryPoint,\\n address _facetRegistry,\\n address _defaultFallBackHandler,\\n bytes calldata _ownerPublicKey\\n ) public override returns (uint256 initSuccess) {\\n LibAppStorage.enforceAccountInitialize();\\n s.entryPoint = IEntryPoint(_anEntryPoint);\\n s.facetRegistry = IFacetRegistry(_facetRegistry);\\n LibDiamond.diamondStorage().defaultFallbackHandler = IDiamondLoupe(\\n _defaultFallBackHandler\\n );\\n\\n _cutDiamondAccountFacet(_verificationFacet);\\n\\n bytes memory initCall = abi.encodeWithSignature(\\n \\\"initializeSigner(bytes)\\\",\\n _ownerPublicKey\\n );\\n // Every Verification Facet should comply with initializeSigner(bytes)\\n // to be compatible with the Barz contract(for initialization)\\n (bool success, bytes memory result) = _verificationFacet.delegatecall(\\n initCall\\n );\\n if (!success || uint256(bytes32(result)) != 1) {\\n revert AccountFacet__InitializationFailure();\\n }\\n\\n initSuccess = 1;\\n emit AccountInitialized(s.entryPoint, _ownerPublicKey);\\n }\\n\\n function _cutDiamondAccountFacet(address _verificationFacet) internal {\\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](1);\\n\\n bytes4 ownerVerificationFuncSelector = IVerificationFacet(\\n _verificationFacet\\n ).validateOwnerSignatureSelector();\\n\\n bytes4[] memory verificationFunctionSelectors = new bytes4[](3);\\n verificationFunctionSelectors[0] = IERC1271.isValidSignature.selector;\\n verificationFunctionSelectors[1] = ownerVerificationFuncSelector;\\n verificationFunctionSelectors[2] = IVerificationFacet.owner.selector;\\n cut[0] = IDiamondCut.FacetCut({\\n facetAddress: _verificationFacet,\\n action: IDiamondCut.FacetCutAction.Add,\\n functionSelectors: verificationFunctionSelectors\\n });\\n\\n LibDiamond.diamondCut(cut, address(0), \\\"\\\");\\n }\\n\\n /**\\n * @notice Calls the destination with inputted calldata and value from EntryPoint\\n * @dev This method executes the calldata coming from the EntryPoint.\\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\\n * @param _dest Address of destination where the call will be forwarded to\\n * @param _value Amount of native coin the owner is willing to send(e.g. ETH, BNB)\\n * @param _func Bytes of calldata to execute in the destination address\\n */\\n function execute(\\n address _dest,\\n uint256 _value,\\n bytes calldata _func\\n ) external override onlyWhenUnlocked {\\n _requireFromEntryPoint();\\n address restrictionsFacet = LibDiamond.restrictionsFacet();\\n if (restrictionsFacet == address(0)) _call(_dest, _value, _func);\\n else _callWithRestrictions(_dest, _value, _func, restrictionsFacet);\\n }\\n\\n /**\\n * @notice Batch calls the destination with inputted calldata and value from EntryPoint\\n * @dev This method batch executes the calldata coming from the EntryPoint.\\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\\n * @param _dest Array of addresses of destination where the call will be forwarded to\\n * @param _value Array of amount of native coin the owner is willing to send(e.g. ETH, BNB)\\n * @param _func Array of bytes of calldata to execute in the destination address\\n */\\n function executeBatch(\\n address[] calldata _dest,\\n uint256[] calldata _value,\\n bytes[] calldata _func\\n ) external override onlyWhenUnlocked {\\n _requireFromEntryPoint();\\n if (_dest.length != _func.length || _dest.length != _value.length)\\n revert AccountFacet__InvalidArrayLength();\\n address restrictionsFacet = LibDiamond.restrictionsFacet();\\n if (restrictionsFacet == address(0)) {\\n for (uint256 i; i < _dest.length; ) {\\n _call(_dest[i], _value[i], _func[i]);\\n unchecked {\\n ++i;\\n }\\n }\\n } else {\\n for (uint256 i; i < _dest.length; ) {\\n _callWithRestrictions(\\n _dest[i],\\n _value[i],\\n _func[i],\\n restrictionsFacet\\n );\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n }\\n\\n /**\\n * @notice Validates the signature field of UserOperation\\n * @dev This method validates if the signature of UserOp is indeed valid by delegating the call to Verification Facet\\n * Barz makes a call to the pre-registered Verification Facet address in App Storage\\n * @param _userOp UserOperation from owner to be validated\\n * @param _userOpHash Hash of UserOperation given from the EntryPoint contract\\n */\\n function _validateSignature(\\n UserOperation calldata _userOp,\\n bytes32 _userOpHash\\n ) internal override returns (uint256 validationData) {\\n // Get Facet with Function Selector\\n address facet = LibLoupe.facetAddress(s.validateOwnerSignatureSelector);\\n if (facet == address(0))\\n revert AccountFacet__NonExistentVerificationFacet();\\n\\n // Make function call to VerificationFacet\\n bytes memory validateCall = abi.encodeWithSelector(\\n s.validateOwnerSignatureSelector,\\n _userOp,\\n _userOpHash\\n );\\n (bool success, bytes memory result) = facet.delegatecall(validateCall);\\n if (!success) revert AccountFacet__CallNotSuccessful();\\n validationData = uint256(bytes32(result));\\n if (validationData == 0) emit VerificationSuccess(_userOpHash);\\n else emit VerificationFailure(_userOpHash);\\n }\\n\\n /**\\n * @notice Calls the target with the inputted value and calldata\\n * @dev This method is the actual function in Barz that makes a call with an arbitrary owner-given data\\n * @param _target Address of the destination contract which the call is getting forwarded to\\n * @param _value Amount of Native coin the owner is wanting to make in this call\\n * @param _data Calldata the owner is forwarding together in the call e.g. Swap/Token Transfer\\n */\\n function _call(\\n address _target,\\n uint256 _value,\\n bytes memory _data\\n ) internal {\\n (bool success, bytes memory result) = _target.call{value: _value}(\\n _data\\n );\\n if (!success) {\\n assembly {\\n revert(add(result, 32), mload(result))\\n }\\n }\\n }\\n\\n /**\\n * @notice Calls the target with the inputted value and calldata together with restrictions check\\n * @dev This method is the actual function in Barz that makes a call with an arbitrary owner-given data\\n * @param _target Address of the destination contract which the call is getting forwarded to\\n * @param _value Amount of Native coin the owner is wanting to make in this call\\n * @param _data Calldata the owner is forwarding together in the call e.g. Swap/Token Transfer\\n * @param _restrictionsFacet Address of Facet to validate restrictions\\n */\\n function _callWithRestrictions(\\n address _target,\\n uint256 _value,\\n bytes memory _data,\\n address _restrictionsFacet\\n ) internal {\\n // NOTE: No restrictions facet, so restriction validation passes\\n if (_checkRestrictions(_restrictionsFacet, _target, _value, _data) != 0)\\n revert AccountFacet__RestrictionsFailure();\\n\\n (bool success, bytes memory result) = _target.call{value: _value}(\\n _data\\n );\\n if (!success) {\\n assembly {\\n revert(add(result, 32), mload(result))\\n }\\n }\\n }\\n\\n /**\\n * @notice Checks restrictions if the restrictions facet exists\\n * @dev This method checks if the restrictions facet exists and makes a verification call to an array of restrictions facet\\n * @param _facet Address that holds the restrictions logic\\n * @param _target Address the call is getting forwarded to\\n * @param _value Amount of native coin the call is sending together with the call\\n * @param _data Calldata to trigger execution in target address\\n */\\n function _checkRestrictions(\\n address _facet,\\n address _target,\\n uint256 _value,\\n bytes memory _data\\n ) internal returns (uint256 result) {\\n bytes memory call = abi.encodeWithSignature(\\n \\\"verifyRestrictions(address,address,uint256,bytes)\\\",\\n address(this),\\n _target,\\n _value,\\n _data\\n );\\n (bool success, bytes memory response) = _facet.delegatecall(call);\\n if (!success) revert AccountFacet__RestrictionsFailure();\\n result = uint256(bytes32(response));\\n }\\n}\\n\",\"keccak256\":\"0xcd92bcdd447010880f78e57e213123269c9e023adfc0a540608daa127d8649ca\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/facets/interfaces/IAccountFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IEntryPoint} from \\\"../../aa-4337/interfaces/IEntryPoint.sol\\\";\\n\\n/**\\n * @title Account Facet Interface\\n * @dev Interface of module contract that provides the account features and init/unitialization of signer\\n * compatible with EIP-1271 & EIP-4337\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IAccountFacet {\\n event AccountInitialized(\\n IEntryPoint indexed entryPoint,\\n bytes indexed ownerPublicKey\\n );\\n // NOTE: Added Below Event\\n event VerificationSuccess(bytes32);\\n event VerificationFailure(bytes32);\\n\\n error AccountFacet__InitializationFailure();\\n error AccountFacet__RestrictionsFailure();\\n error AccountFacet__NonExistentVerificationFacet();\\n error AccountFacet__CallNotSuccessful();\\n error AccountFacet__InvalidArrayLength();\\n\\n function initialize(\\n address verificationFacet,\\n address anEntryPoint,\\n address facetRegistry,\\n address _defaultFallBack,\\n bytes calldata _ownerPublicKey\\n ) external returns (uint256);\\n\\n function execute(address dest, uint256 value, bytes calldata func) external;\\n\\n function executeBatch(\\n address[] calldata dest,\\n uint256[] calldata value,\\n bytes[] calldata func\\n ) external;\\n}\\n\",\"keccak256\":\"0x74a9cb0b8f2f4a5148e366a401a0354426c536c012c025025d07cc25a4cd5382\",\"license\":\"Apache-2.0\"},\"contracts/facets/interfaces/IVerificationFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {UserOperation} from \\\"../../aa-4337/interfaces/UserOperation.sol\\\";\\n\\n/**\\n * @title Verification Facet Interface\\n * @dev Implements logic for user ops signature verification\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\ninterface IVerificationFacet {\\n event SignerInitialized(bytes);\\n event SignerUninitialized();\\n\\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\\n error VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\\n error VerificationFacet__InitializationFailure();\\n error VerificationFacet__InvalidFacetMapping();\\n\\n function initializeSigner(bytes memory) external returns (uint256);\\n\\n function uninitializeSigner() external returns (uint256);\\n\\n function validateOwnerSignatureSelector() external view returns (bytes4);\\n\\n function owner() external view returns (bytes memory);\\n\\n function isValidKeyType(bytes calldata) external view returns (bool);\\n\\n function validateOwnerSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x72bc370a1d1b5a6d6bde67f5026733fd8f6ba434bb90e73b0bd8627fb1579928\",\"license\":\"Apache-2.0\"},\"contracts/infrastructure/interfaces/IFacetRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Registry Interface\\n * @dev Interface for Facet Registry contract to keep track of facets & function selectors addable to user wallets\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IFacetRegistry {\\n struct FacetRegistryConfig {\\n bytes4[] selectors;\\n mapping(bytes4 => FacetInfo) info;\\n }\\n struct FacetInfo {\\n bool exists;\\n uint128 index;\\n }\\n\\n event FacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] facetSelectors\\n );\\n event FacetFunctionSelectorsRemoved(address facet, bytes4[] facetSelectors);\\n\\n error FacetRegistry__FacetSelectorAlreadyRegistered();\\n error FacetRegistry__UnregisteredFacetSelector();\\n\\n function registerFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function removeFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function areFacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external view returns (bool);\\n\\n function isFacetFunctionSelectorRegistered(\\n address facet,\\n bytes4 facetSelector\\n ) external view returns (bool);\\n\\n function getFacetFunctionSelectors(\\n address facet\\n ) external view returns (bytes4[] memory);\\n}\\n\",\"keccak256\":\"0x6e6dd2cab346ef7c31230740ec48d2925e4a9ab24c2f2fb268baaf408dcf02ef\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC1271 {\\n function isValidSignature(\\n bytes32 hash,\\n bytes memory signature\\n ) external view returns (bytes4);\\n}\\n\",\"keccak256\":\"0xcdddb7d5641c9d3f2432dec7fd13fddb9ae1480f25c76c21511e2fa16b8bd422\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibAppStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {SafeCast} from \\\"@openzeppelin/contracts/utils/math/SafeCast.sol\\\";\\nimport {IEntryPoint} from \\\"../aa-4337/interfaces/IEntryPoint.sol\\\";\\nimport {IFacetRegistry} from \\\"../infrastructure/interfaces/IFacetRegistry.sol\\\";\\n\\n/*\\n * @title App Storage\\n * @dev App storage for Barz contract to prevent storage collision\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Lock {\\n uint64 release;\\n bytes4 locker;\\n}\\n\\nstruct InitializersStorage {\\n // NOTE: initialized is a variable to make sure the initialization is only done once.\\n uint8 signerInitialized;\\n uint8 accountInitialized;\\n uint8 restrictionsInitialized;\\n}\\n\\nstruct AppStorage {\\n mapping(uint256 => InitializersStorage) initStorage;\\n uint8 signerMigration;\\n bytes4 validateOwnerSignatureSelector;\\n IEntryPoint entryPoint;\\n IFacetRegistry facetRegistry;\\n mapping(uint256 => Lock) locks;\\n}\\n\\nlibrary LibAppStorage {\\n error LibAppStorage__AccountAlreadyUninitialized();\\n error LibAppStorage__AccountMustBeUninitialized();\\n error LibAppStorage__SignerAlreadyUninitialized();\\n error LibAppStorage__SignerMustBeUninitialized();\\n\\n function appStorage() internal pure returns (AppStorage storage ds) {\\n assembly {\\n ds.slot := 0\\n }\\n }\\n\\n function setSignerUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerAlreadyUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 0;\\n }\\n\\n function getValidateOwnerSignatureSelector()\\n internal\\n view\\n returns (bytes4 selector)\\n {\\n selector = appStorage().validateOwnerSignatureSelector;\\n }\\n\\n function setValidateOwnerSignatureSelector(\\n bytes4 _validateOwnerSignatureSelector\\n ) internal {\\n appStorage()\\n .validateOwnerSignatureSelector = _validateOwnerSignatureSelector;\\n }\\n\\n function enforceSignerInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerMustBeUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 1;\\n }\\n\\n function enforceAccountInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].accountInitialized) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n s.initStorage[0].accountInitialized = 1;\\n }\\n\\n function initiateSignerMigration() internal {\\n appStorage().signerMigration = 1;\\n }\\n\\n function enforceSignerMigration() internal view {\\n if (1 != appStorage().signerMigration) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n }\\n\\n function finalizeSignerMigration() internal {\\n appStorage().signerMigration = 0;\\n }\\n\\n function setLock(uint256 _releaseAfter, bytes4 _locker) internal {\\n appStorage().locks[0] = Lock(SafeCast.toUint64(_releaseAfter), _locker);\\n }\\n\\n function enforceRestrictionsInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__SignerMustBeUninitialized();\\n s.initStorage[0].restrictionsInitialized = 1;\\n }\\n\\n function setRestrictionsUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__AccountAlreadyUninitialized();\\n s.initStorage[0].restrictionsInitialized = 0;\\n }\\n}\\n\\ncontract BarzStorage {\\n AppStorage internal s;\\n modifier onlyWhenUnlocked() {\\n require(\\n uint64(block.timestamp) >= s.locks[0].release,\\n \\\"Account Locked\\\"\\n );\\n _;\\n }\\n modifier onlyWhenLocked() {\\n require(\\n uint64(block.timestamp) < s.locks[0].release,\\n \\\"Account Unlocked\\\"\\n );\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x48524007862a6ce0e07f645950613ce6513ce073c37a109c75019683d42bae27\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\\n bytes4(keccak256(\\\"verifyRestrictions(address,address,uint256,bytes)\\\"));\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // Default Fallback Handler of the barz.\\n IDiamondLoupe defaultFallbackHandler;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function enforceIsSelf() internal view {\\n require(msg.sender == address(this), \\\"LibDiamond: Caller not self\\\");\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n\\n unchecked {\\n facetIndex++;\\n }\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n\\n function restrictionsFacet() internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(\\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2cabdc00de859c3a3170ce3bda5d0e5fd3933d47ce904fd1585f9818b02572f8\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\nimport {LibDiamond} from \\\"./LibDiamond.sol\\\";\\n\\n/**\\n * @title LibLoupe\\n * @dev Internal Library to provide utility feature for reading the state of diamond facets\\n * Originally from Diamond's implementation of Mudgen(author of EIP-2535)\\n */\\nlibrary LibLoupe {\\n /// @notice Gets all facets and their selectors.\\n /// @return facets_ Facet\\n function facets()\\n internal\\n view\\n returns (IDiamondLoupe.Facet[] memory facets_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facets_ = new IDiamondLoupe.Facet[](ds.selectorCount);\\n uint16[] memory numFacetSelectors = new uint16[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facets_[facetIndex].facetAddress == facetAddress_) {\\n facets_[facetIndex].functionSelectors[\\n numFacetSelectors[facetIndex]\\n ] = selector;\\n // probably will never have more than 256 functions from one facet contract\\n require(numFacetSelectors[facetIndex] < 255);\\n numFacetSelectors[facetIndex]++;\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facets_[numFacets].facetAddress = facetAddress_;\\n facets_[numFacets].functionSelectors = new bytes4[](\\n ds.selectorCount\\n );\\n facets_[numFacets].functionSelectors[0] = selector;\\n numFacetSelectors[numFacets] = 1;\\n numFacets++;\\n }\\n }\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n uint256 numSelectors = numFacetSelectors[facetIndex];\\n bytes4[] memory selectors = facets_[facetIndex].functionSelectors;\\n // setting the number of selectors\\n assembly {\\n mstore(selectors, numSelectors)\\n }\\n }\\n // setting the number of facets\\n assembly {\\n mstore(facets_, numFacets)\\n }\\n }\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return _facetFunctionSelectors The selectors associated with a facet address.\\n function facetFunctionSelectors(\\n address _facet\\n ) internal view returns (bytes4[] memory _facetFunctionSelectors) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n uint256 numSelectors;\\n _facetFunctionSelectors = new bytes4[](ds.selectorCount);\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facet = address(bytes20(ds.facets[selector]));\\n if (_facet == facet) {\\n _facetFunctionSelectors[numSelectors] = selector;\\n numSelectors++;\\n }\\n }\\n }\\n // Set the number of selectors in the array\\n assembly {\\n mstore(_facetFunctionSelectors, numSelectors)\\n }\\n }\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n internal\\n view\\n returns (address[] memory facetAddresses_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetAddresses_ = new address[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facetAddress_ == facetAddresses_[facetIndex]) {\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facetAddresses_[numFacets] = facetAddress_;\\n numFacets++;\\n }\\n }\\n // Set the number of facet addresses in the array\\n assembly {\\n mstore(facetAddresses_, numFacets)\\n }\\n }\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(LibDiamond.diamondStorage().facets[_functionSelector])\\n );\\n }\\n}\\n\",\"keccak256\":\"0x0b11439c3cc657095e15ec2241fdcf67204b14001357b612fc5db4ff9e760a5a\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5061001961001e565b61008e565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb554610100900460ff1615610070576040516338fc28cb60e01b815260040160405180910390fd5b600080805260209190915260409020805461ff001916610100179055565b6129b6806200009e6000396000f3fe608060405234801561001057600080fd5b50600436106100725760003560e01c8063b0d691fe11610050578063b0d691fe146100c5578063b61d27f61461010c578063d087d2881461011f57600080fd5b80633a871cdd1461007757806347e1da2a1461009d5780634a936417146100b2575b600080fd5b61008a610085366004611fb5565b610127565b6040519081526020015b60405180910390f35b6100b06100ab366004612055565b61014d565b005b61008a6100c036600461215a565b610450565b60015465010000000000900473ffffffffffffffffffffffffffffffffffffffff1660405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610094565b6100b061011a3660046121ce565b6106d0565b61008a61089d565b600061013161095e565b61013b8484610a16565b905061014682610c5d565b9392505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff9081164290911610156101f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064015b60405180910390fd5b6101fd61095e565b848114158061020c5750848314155b15610243576040517fdde5716100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006102b87fac87185d000000000000000000000000000000000000000000000000000000006000527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020527f6d9f2463c8c0d8cb8be556a773ab21d4321328909a1725f2ef7cae0c320e95da5460601c90565b905073ffffffffffffffffffffffffffffffffffffffff811661038f5760005b86811015610389576103818888838181106102f5576102f5612228565b905060200201602081019061030a9190612257565b87878481811061031c5761031c612228565b9050602002013586868581811061033557610335612228565b90506020028101906103479190612272565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610cc892505050565b6001016102d8565b50610447565b60005b868110156104455761043d8888838181106103af576103af612228565b90506020020160208101906103c49190612257565b8787848181106103d6576103d6612228565b905060200201358686858181106103ef576103ef612228565b90506020028101906104019190612272565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250889250610d45915050565b600101610392565b505b50505050505050565b600061045a610e0d565b6001805473ffffffffffffffffffffffffffffffffffffffff88811665010000000000027fffffffffffffff0000000000000000000000000000000000000000ffffffffff90921691909117909155600280548783167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216179091557f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd492380549287169290911691909117905561051187610eb3565b60008383604051602401610526929190612320565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fcd9b47e40000000000000000000000000000000000000000000000000000000017905251909150600090819073ffffffffffffffffffffffffffffffffffffffff8b16906105c8908590612360565b600060405180830381855af49150503d8060008114610603576040519150601f19603f3d011682016040523d82523d6000602084013e610608565b606091505b5091509150811580610623575061061e8161237c565b600114155b1561065a576040517f1602372100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60019350858560405161066e9291906123c1565b60405190819003812060015490916501000000000090910473ffffffffffffffffffffffffffffffffffffffff16907fd429ff0b972be4ae725700a373d05007287994e4c86cb83315b43ffa85b595fd90600090a35050509695505050505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610773576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064016101ec565b61077b61095e565b60006107f07fac87185d000000000000000000000000000000000000000000000000000000006000527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020527f6d9f2463c8c0d8cb8be556a773ab21d4321328909a1725f2ef7cae0c320e95da5460601c90565b905073ffffffffffffffffffffffffffffffffffffffff81166108535761084e858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610cc892505050565b610896565b610896858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250879250610d45915050565b5050505050565b60015460009065010000000000900473ffffffffffffffffffffffffffffffffffffffff166040517f35567e1a0000000000000000000000000000000000000000000000000000000081523060048201526000602482015273ffffffffffffffffffffffffffffffffffffffff91909116906335567e1a90604401602060405180830381865afa158015610935573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061095991906123d1565b905090565b60015465010000000000900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a14576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f6163636f756e743a206e6f742066726f6d20456e747279506f696e740000000060448201526064016101ec565b565b600154610100900460e01b7fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604081205460601c80610aab576040517f6eb2360200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600154604051600091610100900460e01b90610acd908790879060240161244e565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090506000808373ffffffffffffffffffffffffffffffffffffffff1683604051610b549190612360565b600060405180830381855af49150503d8060008114610b8f576040519150601f19603f3d011682016040523d82523d6000602084013e610b94565b606091505b509150915081610bd0576040517f3cbbb65000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610bd98161237c565b94506000859003610c1c576040518681527f19e781916118c373dadcb7776fae0a2dbb6bbdeedae143ce68031e22801ef8659060200160405180910390a1610c50565b6040518681527fbbfee2df7f28b899771f1015dc85d7840ff9f6162f23f6aa99686e8fbd2ce1319060200160405180910390a15b5050505092915050565b50565b8015610c5a5760405160009033907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90849084818181858888f193505050503d8060008114610896576040519150601f19603f3d011682016040523d82523d6000602084013e610896565b6000808473ffffffffffffffffffffffffffffffffffffffff168484604051610cf19190612360565b60006040518083038185875af1925050503d8060008114610d2e576040519150601f19603f3d011682016040523d82523d6000602084013e610d33565b606091505b50915091508161089657805160208201fd5b610d5181858585611117565b15610d88576040517f01f595e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000808573ffffffffffffffffffffffffffffffffffffffff168585604051610db19190612360565b60006040518083038185875af1925050503d8060008114610dee576040519150601f19603f3d011682016040523d82523d6000602084013e610df3565b606091505b509150915081610e0557805160208201fd5b505050505050565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb554610100900460ff1615610e78576040517f38fc28cb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100179055565b604080516001808252818301909252600091816020015b60408051606080820183526000808352602083015291810191909152815260200190600190039081610eca57905050905060008273ffffffffffffffffffffffffffffffffffffffff16633253960f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f6c9190612592565b604080516003808252608082019092529192506000919060208201606080368337019050509050631626ba7e60e01b81600081518110610fae57610fae612228565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681525050818160018151811061100e5761100e612228565b7fffffffff000000000000000000000000000000000000000000000000000000009092166020928302919091019091015280517f8da5cb5b00000000000000000000000000000000000000000000000000000000908290600290811061107657611076612228565b7fffffffff00000000000000000000000000000000000000000000000000000000909216602092830291909101820152604080516060810190915273ffffffffffffffffffffffffffffffffffffffff861681529081016000815260200182815250836000815181106110eb576110eb612228565b602002602001018190525061111183600060405180602001604052806000815250611264565b50505050565b60008030858585604051602401611131949392919061264d565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fac87185d0000000000000000000000000000000000000000000000000000000017905251909150600090819073ffffffffffffffffffffffffffffffffffffffff8916906111d3908590612360565b600060405180830381855af49150503d806000811461120e576040519150601f19603f3d011682016040523d82523d6000602084013e611213565b606091505b50915091508161124f576040517f01f595e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6112588161237c565b98975050505050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921547f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff8116908190600090600716156112d35750600381901c60009081526001840160205260409020545b60005b87518110156113505761134383838a84815181106112f6576112f6612228565b6020026020010151600001518b858151811061131457611314612228565b6020026020010151602001518c868151811061133257611332612228565b6020026020010151604001516113f0565b90935091506001016112d6565b50828214611389576002840180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff84161790555b60078216156113ab57600382901c600090815260018501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb6738787876040516113de93929190612696565b60405180910390a16104478686611e81565b600080807f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f905060008451116114a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f2063757400000000000000000000000000000000000000000060648201526084016101ec565b60008560028111156114bc576114bc6125d4565b0361168c576114e38660405180606001604052806024815260200161290d60249139611f7a565b60005b845181101561168657600085828151811061150357611503612228565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c156115d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c726561647920657869737473000000000000000000000060648201526084016101ec565b7fffffffff0000000000000000000000000000000000000000000000000000000080831660008181526020879052604090207fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608d901b168e17905560e060058e901b811692831c199c909c1690821c179a81900361166a5760038c901c600090815260018601602052604081209b909b555b8b6116748161282d565b9c5050600190930192506114e6915050565b50611e75565b60018560028111156116a0576116a06125d4565b03611990576116c78660405180606001604052806028815260200161295960289139611f7a565b60005b84518110156116865760008582815181106116e7576116e7612228565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c3081036117bc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4c69624469616d6f6e644375743a2043616e2774207265706c61636520696d6d60448201527f757461626c652066756e6374696f6e000000000000000000000000000000000060648201526084016101ec565b8973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611877576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e000000000000000060648201526084016101ec565b73ffffffffffffffffffffffffffffffffffffffff811661191a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e207468617420646f65736e2774206578697374000000000000000060648201526084016101ec565b507fffffffff0000000000000000000000000000000000000000000000000000000090911660009081526020849052604090206bffffffffffffffffffffffff919091167fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608a901b161790556001016116ca565b60028560028111156119a4576119a46125d4565b03611ded5773ffffffffffffffffffffffffffffffffffffffff861615611a4d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d75737420626520616464726573732830290000000000000000000060648201526084016101ec565b600388901c6007891660005b8651811015611dcd5760008a9003611a955782611a7581612865565b60008181526001870160205260409020549b50935060079250611aa39050565b81611a9f81612865565b9250505b6000806000808a8581518110611abb57611abb612228565b6020908102919091018101517fffffffff0000000000000000000000000000000000000000000000000000000081166000908152918a9052604090912054909150606081901c611b8d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e277420657869737400000000000000000060648201526084016101ec565b30606082901c03611c20576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e00000000000000000000000000000000000060648201526084016101ec565b600587901b8f901b94507fffffffff0000000000000000000000000000000000000000000000000000000080861690831614611cbe577fffffffff000000000000000000000000000000000000000000000000000000008516600090815260208a90526040902080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff83161790555b7fffffffff0000000000000000000000000000000000000000000000000000000091909116600090815260208990526040812055600381901c611fff16925060051b60e0169050858214611d53576000828152600188016020526040902080547fffffffff0000000000000000000000000000000000000000000000000000000080841c19909116908516831c179055611da4565b80837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c817fffffffff0000000000000000000000000000000000000000000000000000000060001b901c198e16179c505b84600003611dc257600086815260018801602052604081208190559c505b505050600101611a59565b5080611dda83600861289a565b611de491906128b7565b99505050611e75565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560448201527f74416374696f6e0000000000000000000000000000000000000000000000000060648201526084016101ec565b50959694955050505050565b73ffffffffffffffffffffffffffffffffffffffff8216611ea0575050565b611ec28260405180606001604052806028815260200161293160289139611f7a565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051611eea9190612360565b600060405180830381855af49150503d8060008114611f25576040519150601f19603f3d011682016040523d82523d6000602084013e611f2a565b606091505b50915091508161111157805115611f445780518082602001fd5b83836040517f192105d70000000000000000000000000000000000000000000000000000000081526004016101ec9291906128ca565b813b8181611111576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101ec91906128f9565b600080600060608486031215611fca57600080fd5b833567ffffffffffffffff811115611fe157600080fd5b84016101608187031215611ff457600080fd5b95602085013595506040909401359392505050565b60008083601f84011261201b57600080fd5b50813567ffffffffffffffff81111561203357600080fd5b6020830191508360208260051b850101111561204e57600080fd5b9250929050565b6000806000806000806060878903121561206e57600080fd5b863567ffffffffffffffff8082111561208657600080fd5b6120928a838b01612009565b909850965060208901359150808211156120ab57600080fd5b6120b78a838b01612009565b909650945060408901359150808211156120d057600080fd5b506120dd89828a01612009565b979a9699509497509295939492505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461211357600080fd5b919050565b60008083601f84011261212a57600080fd5b50813567ffffffffffffffff81111561214257600080fd5b60208301915083602082850101111561204e57600080fd5b60008060008060008060a0878903121561217357600080fd5b61217c876120ef565b955061218a602088016120ef565b9450612198604088016120ef565b93506121a6606088016120ef565b9250608087013567ffffffffffffffff8111156121c257600080fd5b6120dd89828a01612118565b600080600080606085870312156121e457600080fd5b6121ed856120ef565b935060208501359250604085013567ffffffffffffffff81111561221057600080fd5b61221c87828801612118565b95989497509550505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561226957600080fd5b610146826120ef565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126122a757600080fd5b83018035915067ffffffffffffffff8211156122c257600080fd5b60200191503681900382131561204e57600080fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b6020815260006123346020830184866122d7565b949350505050565b60005b8381101561235757818101518382015260200161233f565b50506000910152565b6000825161237281846020870161233c565b9190910192915050565b805160208083015191908110156123bb577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8160200360031b1b821691505b50919050565b8183823760009101908152919050565b6000602082840312156123e357600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261241f57600080fd5b830160208101925035905067ffffffffffffffff81111561243f57600080fd5b80360382131561204e57600080fd5b6040815261247c60408201612462856120ef565b73ffffffffffffffffffffffffffffffffffffffff169052565b60208301356060820152600061249560408501856123ea565b6101608060808601526124ad6101a0860183856122d7565b92506124bc60608801886123ea565b92507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0808786030160a08801526124f48585846122d7565b9450608089013560c088015260a089013560e0880152610100935060c089013584880152610120915060e089013582880152610140848a01358189015261253d838b018b6123ea565b955092508188870301848901526125558686856122d7565b9550612563818b018b6123ea565b9550935050808786030161018088015250506125808383836122d7565b93505050508260208301529392505050565b6000602082840312156125a457600080fd5b81517fffffffff000000000000000000000000000000000000000000000000000000008116811461014657600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6000815180845261261b81602086016020860161233c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600073ffffffffffffffffffffffffffffffffffffffff80871683528086166020840152508360408301526080606083015261268c6080830184612603565b9695505050505050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b848110156127c1577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808a8503018652815188850173ffffffffffffffffffffffffffffffffffffffff82511686528482015160038110612748577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b808310156127ac5783517fffffffff0000000000000000000000000000000000000000000000000000000016825292860192600192909201919086019061276a565b509785019795505050908201906001016126bf565b505073ffffffffffffffffffffffffffffffffffffffff8a169088015286810360408801526127f08189612603565b9a9950505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361285e5761285e6127fe565b5060010190565b600081612874576128746127fe565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b80820281158282048414176128b1576128b16127fe565b92915050565b808201808211156128b1576128b16127fe565b73ffffffffffffffffffffffffffffffffffffffff831681526040602082015260006123346040830184612603565b602081526000610146602083018461260356fe4c69624469616d6f6e644375743a2041646420666163657420686173206e6f20636f64654c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a205265706c61636520666163657420686173206e6f20636f6465a2646970667358221220a952f19990a20474450919a2df9ddff4430a71350892e0954f2bb073575ad64864736f6c63430008150033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100725760003560e01c8063b0d691fe11610050578063b0d691fe146100c5578063b61d27f61461010c578063d087d2881461011f57600080fd5b80633a871cdd1461007757806347e1da2a1461009d5780634a936417146100b2575b600080fd5b61008a610085366004611fb5565b610127565b6040519081526020015b60405180910390f35b6100b06100ab366004612055565b61014d565b005b61008a6100c036600461215a565b610450565b60015465010000000000900473ffffffffffffffffffffffffffffffffffffffff1660405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610094565b6100b061011a3660046121ce565b6106d0565b61008a61089d565b600061013161095e565b61013b8484610a16565b905061014682610c5d565b9392505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff9081164290911610156101f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064015b60405180910390fd5b6101fd61095e565b848114158061020c5750848314155b15610243576040517fdde5716100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006102b87fac87185d000000000000000000000000000000000000000000000000000000006000527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020527f6d9f2463c8c0d8cb8be556a773ab21d4321328909a1725f2ef7cae0c320e95da5460601c90565b905073ffffffffffffffffffffffffffffffffffffffff811661038f5760005b86811015610389576103818888838181106102f5576102f5612228565b905060200201602081019061030a9190612257565b87878481811061031c5761031c612228565b9050602002013586868581811061033557610335612228565b90506020028101906103479190612272565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610cc892505050565b6001016102d8565b50610447565b60005b868110156104455761043d8888838181106103af576103af612228565b90506020020160208101906103c49190612257565b8787848181106103d6576103d6612228565b905060200201358686858181106103ef576103ef612228565b90506020028101906104019190612272565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250889250610d45915050565b600101610392565b505b50505050505050565b600061045a610e0d565b6001805473ffffffffffffffffffffffffffffffffffffffff88811665010000000000027fffffffffffffff0000000000000000000000000000000000000000ffffffffff90921691909117909155600280548783167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216179091557f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd492380549287169290911691909117905561051187610eb3565b60008383604051602401610526929190612320565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fcd9b47e40000000000000000000000000000000000000000000000000000000017905251909150600090819073ffffffffffffffffffffffffffffffffffffffff8b16906105c8908590612360565b600060405180830381855af49150503d8060008114610603576040519150601f19603f3d011682016040523d82523d6000602084013e610608565b606091505b5091509150811580610623575061061e8161237c565b600114155b1561065a576040517f1602372100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60019350858560405161066e9291906123c1565b60405190819003812060015490916501000000000090910473ffffffffffffffffffffffffffffffffffffffff16907fd429ff0b972be4ae725700a373d05007287994e4c86cb83315b43ffa85b595fd90600090a35050509695505050505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610773576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064016101ec565b61077b61095e565b60006107f07fac87185d000000000000000000000000000000000000000000000000000000006000527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020527f6d9f2463c8c0d8cb8be556a773ab21d4321328909a1725f2ef7cae0c320e95da5460601c90565b905073ffffffffffffffffffffffffffffffffffffffff81166108535761084e858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610cc892505050565b610896565b610896858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250879250610d45915050565b5050505050565b60015460009065010000000000900473ffffffffffffffffffffffffffffffffffffffff166040517f35567e1a0000000000000000000000000000000000000000000000000000000081523060048201526000602482015273ffffffffffffffffffffffffffffffffffffffff91909116906335567e1a90604401602060405180830381865afa158015610935573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061095991906123d1565b905090565b60015465010000000000900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a14576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f6163636f756e743a206e6f742066726f6d20456e747279506f696e740000000060448201526064016101ec565b565b600154610100900460e01b7fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604081205460601c80610aab576040517f6eb2360200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600154604051600091610100900460e01b90610acd908790879060240161244e565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090506000808373ffffffffffffffffffffffffffffffffffffffff1683604051610b549190612360565b600060405180830381855af49150503d8060008114610b8f576040519150601f19603f3d011682016040523d82523d6000602084013e610b94565b606091505b509150915081610bd0576040517f3cbbb65000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610bd98161237c565b94506000859003610c1c576040518681527f19e781916118c373dadcb7776fae0a2dbb6bbdeedae143ce68031e22801ef8659060200160405180910390a1610c50565b6040518681527fbbfee2df7f28b899771f1015dc85d7840ff9f6162f23f6aa99686e8fbd2ce1319060200160405180910390a15b5050505092915050565b50565b8015610c5a5760405160009033907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90849084818181858888f193505050503d8060008114610896576040519150601f19603f3d011682016040523d82523d6000602084013e610896565b6000808473ffffffffffffffffffffffffffffffffffffffff168484604051610cf19190612360565b60006040518083038185875af1925050503d8060008114610d2e576040519150601f19603f3d011682016040523d82523d6000602084013e610d33565b606091505b50915091508161089657805160208201fd5b610d5181858585611117565b15610d88576040517f01f595e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000808573ffffffffffffffffffffffffffffffffffffffff168585604051610db19190612360565b60006040518083038185875af1925050503d8060008114610dee576040519150601f19603f3d011682016040523d82523d6000602084013e610df3565b606091505b509150915081610e0557805160208201fd5b505050505050565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb554610100900460ff1615610e78576040517f38fc28cb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100179055565b604080516001808252818301909252600091816020015b60408051606080820183526000808352602083015291810191909152815260200190600190039081610eca57905050905060008273ffffffffffffffffffffffffffffffffffffffff16633253960f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f6c9190612592565b604080516003808252608082019092529192506000919060208201606080368337019050509050631626ba7e60e01b81600081518110610fae57610fae612228565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681525050818160018151811061100e5761100e612228565b7fffffffff000000000000000000000000000000000000000000000000000000009092166020928302919091019091015280517f8da5cb5b00000000000000000000000000000000000000000000000000000000908290600290811061107657611076612228565b7fffffffff00000000000000000000000000000000000000000000000000000000909216602092830291909101820152604080516060810190915273ffffffffffffffffffffffffffffffffffffffff861681529081016000815260200182815250836000815181106110eb576110eb612228565b602002602001018190525061111183600060405180602001604052806000815250611264565b50505050565b60008030858585604051602401611131949392919061264d565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fac87185d0000000000000000000000000000000000000000000000000000000017905251909150600090819073ffffffffffffffffffffffffffffffffffffffff8916906111d3908590612360565b600060405180830381855af49150503d806000811461120e576040519150601f19603f3d011682016040523d82523d6000602084013e611213565b606091505b50915091508161124f576040517f01f595e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6112588161237c565b98975050505050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921547f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff8116908190600090600716156112d35750600381901c60009081526001840160205260409020545b60005b87518110156113505761134383838a84815181106112f6576112f6612228565b6020026020010151600001518b858151811061131457611314612228565b6020026020010151602001518c868151811061133257611332612228565b6020026020010151604001516113f0565b90935091506001016112d6565b50828214611389576002840180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff84161790555b60078216156113ab57600382901c600090815260018501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb6738787876040516113de93929190612696565b60405180910390a16104478686611e81565b600080807f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f905060008451116114a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f2063757400000000000000000000000000000000000000000060648201526084016101ec565b60008560028111156114bc576114bc6125d4565b0361168c576114e38660405180606001604052806024815260200161290d60249139611f7a565b60005b845181101561168657600085828151811061150357611503612228565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c156115d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c726561647920657869737473000000000000000000000060648201526084016101ec565b7fffffffff0000000000000000000000000000000000000000000000000000000080831660008181526020879052604090207fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608d901b168e17905560e060058e901b811692831c199c909c1690821c179a81900361166a5760038c901c600090815260018601602052604081209b909b555b8b6116748161282d565b9c5050600190930192506114e6915050565b50611e75565b60018560028111156116a0576116a06125d4565b03611990576116c78660405180606001604052806028815260200161295960289139611f7a565b60005b84518110156116865760008582815181106116e7576116e7612228565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c3081036117bc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4c69624469616d6f6e644375743a2043616e2774207265706c61636520696d6d60448201527f757461626c652066756e6374696f6e000000000000000000000000000000000060648201526084016101ec565b8973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611877576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e000000000000000060648201526084016101ec565b73ffffffffffffffffffffffffffffffffffffffff811661191a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e207468617420646f65736e2774206578697374000000000000000060648201526084016101ec565b507fffffffff0000000000000000000000000000000000000000000000000000000090911660009081526020849052604090206bffffffffffffffffffffffff919091167fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608a901b161790556001016116ca565b60028560028111156119a4576119a46125d4565b03611ded5773ffffffffffffffffffffffffffffffffffffffff861615611a4d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d75737420626520616464726573732830290000000000000000000060648201526084016101ec565b600388901c6007891660005b8651811015611dcd5760008a9003611a955782611a7581612865565b60008181526001870160205260409020549b50935060079250611aa39050565b81611a9f81612865565b9250505b6000806000808a8581518110611abb57611abb612228565b6020908102919091018101517fffffffff0000000000000000000000000000000000000000000000000000000081166000908152918a9052604090912054909150606081901c611b8d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e277420657869737400000000000000000060648201526084016101ec565b30606082901c03611c20576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e00000000000000000000000000000000000060648201526084016101ec565b600587901b8f901b94507fffffffff0000000000000000000000000000000000000000000000000000000080861690831614611cbe577fffffffff000000000000000000000000000000000000000000000000000000008516600090815260208a90526040902080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff83161790555b7fffffffff0000000000000000000000000000000000000000000000000000000091909116600090815260208990526040812055600381901c611fff16925060051b60e0169050858214611d53576000828152600188016020526040902080547fffffffff0000000000000000000000000000000000000000000000000000000080841c19909116908516831c179055611da4565b80837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c817fffffffff0000000000000000000000000000000000000000000000000000000060001b901c198e16179c505b84600003611dc257600086815260018801602052604081208190559c505b505050600101611a59565b5080611dda83600861289a565b611de491906128b7565b99505050611e75565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560448201527f74416374696f6e0000000000000000000000000000000000000000000000000060648201526084016101ec565b50959694955050505050565b73ffffffffffffffffffffffffffffffffffffffff8216611ea0575050565b611ec28260405180606001604052806028815260200161293160289139611f7a565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051611eea9190612360565b600060405180830381855af49150503d8060008114611f25576040519150601f19603f3d011682016040523d82523d6000602084013e611f2a565b606091505b50915091508161111157805115611f445780518082602001fd5b83836040517f192105d70000000000000000000000000000000000000000000000000000000081526004016101ec9291906128ca565b813b8181611111576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101ec91906128f9565b600080600060608486031215611fca57600080fd5b833567ffffffffffffffff811115611fe157600080fd5b84016101608187031215611ff457600080fd5b95602085013595506040909401359392505050565b60008083601f84011261201b57600080fd5b50813567ffffffffffffffff81111561203357600080fd5b6020830191508360208260051b850101111561204e57600080fd5b9250929050565b6000806000806000806060878903121561206e57600080fd5b863567ffffffffffffffff8082111561208657600080fd5b6120928a838b01612009565b909850965060208901359150808211156120ab57600080fd5b6120b78a838b01612009565b909650945060408901359150808211156120d057600080fd5b506120dd89828a01612009565b979a9699509497509295939492505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461211357600080fd5b919050565b60008083601f84011261212a57600080fd5b50813567ffffffffffffffff81111561214257600080fd5b60208301915083602082850101111561204e57600080fd5b60008060008060008060a0878903121561217357600080fd5b61217c876120ef565b955061218a602088016120ef565b9450612198604088016120ef565b93506121a6606088016120ef565b9250608087013567ffffffffffffffff8111156121c257600080fd5b6120dd89828a01612118565b600080600080606085870312156121e457600080fd5b6121ed856120ef565b935060208501359250604085013567ffffffffffffffff81111561221057600080fd5b61221c87828801612118565b95989497509550505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561226957600080fd5b610146826120ef565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126122a757600080fd5b83018035915067ffffffffffffffff8211156122c257600080fd5b60200191503681900382131561204e57600080fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b6020815260006123346020830184866122d7565b949350505050565b60005b8381101561235757818101518382015260200161233f565b50506000910152565b6000825161237281846020870161233c565b9190910192915050565b805160208083015191908110156123bb577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8160200360031b1b821691505b50919050565b8183823760009101908152919050565b6000602082840312156123e357600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261241f57600080fd5b830160208101925035905067ffffffffffffffff81111561243f57600080fd5b80360382131561204e57600080fd5b6040815261247c60408201612462856120ef565b73ffffffffffffffffffffffffffffffffffffffff169052565b60208301356060820152600061249560408501856123ea565b6101608060808601526124ad6101a0860183856122d7565b92506124bc60608801886123ea565b92507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0808786030160a08801526124f48585846122d7565b9450608089013560c088015260a089013560e0880152610100935060c089013584880152610120915060e089013582880152610140848a01358189015261253d838b018b6123ea565b955092508188870301848901526125558686856122d7565b9550612563818b018b6123ea565b9550935050808786030161018088015250506125808383836122d7565b93505050508260208301529392505050565b6000602082840312156125a457600080fd5b81517fffffffff000000000000000000000000000000000000000000000000000000008116811461014657600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6000815180845261261b81602086016020860161233c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600073ffffffffffffffffffffffffffffffffffffffff80871683528086166020840152508360408301526080606083015261268c6080830184612603565b9695505050505050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b848110156127c1577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808a8503018652815188850173ffffffffffffffffffffffffffffffffffffffff82511686528482015160038110612748577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b808310156127ac5783517fffffffff0000000000000000000000000000000000000000000000000000000016825292860192600192909201919086019061276a565b509785019795505050908201906001016126bf565b505073ffffffffffffffffffffffffffffffffffffffff8a169088015286810360408801526127f08189612603565b9a9950505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361285e5761285e6127fe565b5060010190565b600081612874576128746127fe565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b80820281158282048414176128b1576128b16127fe565b92915050565b808201808211156128b1576128b16127fe565b73ffffffffffffffffffffffffffffffffffffffff831681526040602082015260006123346040830184612603565b602081526000610146602083018461260356fe4c69624469616d6f6e644375743a2041646420666163657420686173206e6f20636f64654c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a205265706c61636520666163657420686173206e6f20636f6465a2646970667358221220a952f19990a20474450919a2df9ddff4430a71350892e0954f2bb073575ad64864736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "Account module contract that provides the account features and initialization of signer compatible with EIP-1271 & EIP-4337", + "kind": "dev", + "methods": { + "execute(address,uint256,bytes)": { + "details": "This method executes the calldata coming from the EntryPoint. Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)", + "params": { + "_dest": "Address of destination where the call will be forwarded to", + "_func": "Bytes of calldata to execute in the destination address", + "_value": "Amount of native coin the owner is willing to send(e.g. ETH, BNB)" + } + }, + "executeBatch(address[],uint256[],bytes[])": { + "details": "This method batch executes the calldata coming from the EntryPoint. Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)", + "params": { + "_dest": "Array of addresses of destination where the call will be forwarded to", + "_func": "Array of bytes of calldata to execute in the destination address", + "_value": "Array of amount of native coin the owner is willing to send(e.g. ETH, BNB)" + } + }, + "initialize(address,address,address,address,bytes)": { + "details": "This method can only be called during the initialization or signature migration. If the proxy contract was created without initialization, anyone can call initialize. Barz calls initialize in constructor in an atomic transaction during deployment", + "params": { + "_anEntryPoint": "Entrypoint contract defined in EIP-4337 handling the flow of UserOp", + "_defaultFallBackHandler": "Middleware contract for default facets", + "_facetRegistry": "Registry of Facets that hold all facet information", + "_ownerPublicKey": "Bytes of owner public key", + "_verificationFacet": "Facet contract handling the verificationi" + } + } + }, + "title": "Account Facet", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "constructor": { + "notice": "This constructor ensures that this contract can only be used as singleton for Proxy contracts" + }, + "entryPoint()": { + "notice": "Returns the address of EntryPoint contract registered to Barz account" + }, + "execute(address,uint256,bytes)": { + "notice": "Calls the destination with inputted calldata and value from EntryPoint" + }, + "executeBatch(address[],uint256[],bytes[])": { + "notice": "Batch calls the destination with inputted calldata and value from EntryPoint" + }, + "getNonce()": { + "notice": "Return the account nonce. This method returns the next sequential nonce. For a nonce of a specific key, use `entrypoint.getNonce(account, key)`" + }, + "initialize(address,address,address,address,bytes)": { + "notice": "Initializes the initial storage of the Barz contract." + }, + "validateUserOp((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256)": { + "notice": "Validate user's signature and nonce. subclass doesn't need to override this method. Instead, it should override the specific internal validation methods." + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 27866, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "s", + "offset": 0, + "slot": "0", + "type": "t_struct(AppStorage)27613_storage" + } + ], + "types": { + "t_bytes4": { + "encoding": "inplace", + "label": "bytes4", + "numberOfBytes": "4" + }, + "t_contract(IEntryPoint)12286": { + "encoding": "inplace", + "label": "contract IEntryPoint", + "numberOfBytes": "20" + }, + "t_contract(IFacetRegistry)26148": { + "encoding": "inplace", + "label": "contract IFacetRegistry", + "numberOfBytes": "20" + }, + "t_mapping(t_uint256,t_struct(InitializersStorage)27592_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => struct InitializersStorage)", + "numberOfBytes": "32", + "value": "t_struct(InitializersStorage)27592_storage" + }, + "t_mapping(t_uint256,t_struct(Lock)27585_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => struct Lock)", + "numberOfBytes": "32", + "value": "t_struct(Lock)27585_storage" + }, + "t_struct(AppStorage)27613_storage": { + "encoding": "inplace", + "label": "struct AppStorage", + "members": [ + { + "astId": 27597, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "initStorage", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_uint256,t_struct(InitializersStorage)27592_storage)" + }, + { + "astId": 27599, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "signerMigration", + "offset": 0, + "slot": "1", + "type": "t_uint8" + }, + { + "astId": 27601, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "validateOwnerSignatureSelector", + "offset": 1, + "slot": "1", + "type": "t_bytes4" + }, + { + "astId": 27604, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "entryPoint", + "offset": 5, + "slot": "1", + "type": "t_contract(IEntryPoint)12286" + }, + { + "astId": 27607, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "facetRegistry", + "offset": 0, + "slot": "2", + "type": "t_contract(IFacetRegistry)26148" + }, + { + "astId": 27612, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "locks", + "offset": 0, + "slot": "3", + "type": "t_mapping(t_uint256,t_struct(Lock)27585_storage)" + } + ], + "numberOfBytes": "128" + }, + "t_struct(InitializersStorage)27592_storage": { + "encoding": "inplace", + "label": "struct InitializersStorage", + "members": [ + { + "astId": 27587, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "signerInitialized", + "offset": 0, + "slot": "0", + "type": "t_uint8" + }, + { + "astId": 27589, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "accountInitialized", + "offset": 1, + "slot": "0", + "type": "t_uint8" + }, + { + "astId": 27591, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "restrictionsInitialized", + "offset": 2, + "slot": "0", + "type": "t_uint8" + } + ], + "numberOfBytes": "32" + }, + "t_struct(Lock)27585_storage": { + "encoding": "inplace", + "label": "struct Lock", + "members": [ + { + "astId": 27582, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "release", + "offset": 0, + "slot": "0", + "type": "t_uint64" + }, + { + "astId": 27584, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "locker", + "offset": 8, + "slot": "0", + "type": "t_bytes4" + } + ], + "numberOfBytes": "32" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint64": { + "encoding": "inplace", + "label": "uint64", + "numberOfBytes": "8" + }, + "t_uint8": { + "encoding": "inplace", + "label": "uint8", + "numberOfBytes": "1" + } + } + } +} \ No newline at end of file diff --git a/deployments/mantle/BarzFactory.json b/deployments/mantle/BarzFactory.json new file mode 100644 index 0000000..889ede4 --- /dev/null +++ b/deployments/mantle/BarzFactory.json @@ -0,0 +1,302 @@ +{ + "address": "0x729c310186a57833f622630a16d13f710b83272a", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_accountFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_entryPoint", + "type": "address" + }, + { + "internalType": "address", + "name": "_facetRegistry", + "type": "address" + }, + { + "internalType": "address", + "name": "_defaultFallback", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "BarzDeployed", + "type": "event" + }, + { + "inputs": [], + "name": "accountFacet", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_verificationFacet", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_owner", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "_salt", + "type": "uint256" + } + ], + "name": "createAccount", + "outputs": [ + { + "internalType": "contract Barz", + "name": "barz", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "defaultFallback", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "entryPoint", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetRegistry", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_verificationFacet", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_owner", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "_salt", + "type": "uint256" + } + ], + "name": "getAddress", + "outputs": [ + { + "internalType": "address", + "name": "barzAddress", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_accountFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_verificationFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_entryPoint", + "type": "address" + }, + { + "internalType": "address", + "name": "_facetRegistry", + "type": "address" + }, + { + "internalType": "address", + "name": "_defaultFallback", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_ownerPublicKey", + "type": "bytes" + } + ], + "name": "getBytecode", + "outputs": [ + { + "internalType": "bytes", + "name": "barzBytecode", + "type": "bytes" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "getCreationCode", + "outputs": [ + { + "internalType": "bytes", + "name": "creationCode", + "type": "bytes" + } + ], + "stateMutability": "pure", + "type": "function" + } + ], + "args": [ + "0xFde53272dcd7938d16E031A6989753c321728332", + "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789", + "0xAfCb70e6e9514E2A15B23A01d2a9b9f7A34f2c33", + "0x2e7f1dAe1F3799d20f5c31bEFdc7A620f664728D" + ], + "numDeployments": 1, + "solcInputHash": "ad34345aa73d96f52b3e14df983b6b29", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_accountFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_entryPoint\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_facetRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_defaultFallback\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"BarzDeployed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"accountFacet\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_verificationFacet\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_owner\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_salt\",\"type\":\"uint256\"}],\"name\":\"createAccount\",\"outputs\":[{\"internalType\":\"contract Barz\",\"name\":\"barz\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"defaultFallback\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"entryPoint\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetRegistry\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_verificationFacet\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_owner\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_salt\",\"type\":\"uint256\"}],\"name\":\"getAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"barzAddress\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_accountFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_verificationFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_entryPoint\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_facetRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_defaultFallback\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_ownerPublicKey\",\"type\":\"bytes\"}],\"name\":\"getBytecode\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"barzBytecode\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCreationCode\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"creationCode\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"Contract to easily deploy Barz to a pre-computed address with a single call\",\"kind\":\"dev\",\"methods\":{\"constructor\":{\"params\":{\"_accountFacet\":\"Account Facet to be used to create Barz\",\"_defaultFallback\":\"Default Fallback Handler to be used to create Barz\",\"_entryPoint\":\"Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\",\"_facetRegistry\":\"Facet Registry to be used to create Barz\"}},\"createAccount(address,bytes,uint256)\":{\"params\":{\"_owner\":\"Public Key of the owner to initialize barz account\",\"_salt\":\"Salt used for deploying barz with create2\",\"_verificationFacet\":\"Address of verification facet used for creating the barz account\"},\"returns\":{\"barz\":\"Instance of Barz contract deployed with the given parameters\"}},\"getAddress(address,bytes,uint256)\":{\"params\":{\"_owner\":\"Public Key of the owner to initialize barz account\",\"_salt\":\"Salt used for deploying barz with create2\",\"_verificationFacet\":\"Address of verification facet used for creating the barz account\"},\"returns\":{\"barzAddress\":\"Precalculated Barz address\"}},\"getBytecode(address,address,address,address,address,bytes)\":{\"params\":{\"_accountFacet\":\"Account Facet to be used to create Barz\",\"_defaultFallback\":\"Default Fallback Handler to be used to create Barz\",\"_entryPoint\":\"Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\",\"_facetRegistry\":\"Facet Registry to be used to create Barz\",\"_ownerPublicKey\":\"Public Key of owner to be used to initialize Barz ownership\",\"_verificationFacet\":\"Verification Facet to be used to create Barz\"},\"returns\":{\"barzBytecode\":\"Bytecode of Barz\"}},\"getCreationCode()\":{\"returns\":{\"creationCode\":\"Creation code of Barz\"}}},\"title\":\"Barz Factory\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"Sets the initialization data for Barz contract initialization\"},\"createAccount(address,bytes,uint256)\":{\"notice\":\"Creates the Barz with a single call. It creates the Barz contract with the givent verification facet\"},\"getAddress(address,bytes,uint256)\":{\"notice\":\"Calculates the address of Barz with the given parameters\"},\"getBytecode(address,address,address,address,address,bytes)\":{\"notice\":\"Returns the bytecode of Barz with the given parameter\"},\"getCreationCode()\":{\"notice\":\"Returns the creation code of the Barz contract\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/BarzFactory.sol\":\"BarzFactory\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"contracts/Barz.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {LibDiamond} from \\\"./libraries/LibDiamond.sol\\\";\\nimport {IBarz} from \\\"./interfaces/IBarz.sol\\\";\\n\\n/**\\n * @title Barz\\n * @dev A diamond proxy wallet with a modular & upgradeable architecture\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract Barz is IBarz {\\n /**\\n * @notice Initializes Barz with the given parameters. Barz account is intended to be created from Barz Factory for stable deployment.\\n * @dev This method makes a delegate call to account facet and account facet handles the initialization.\\n * With modular architecture, Barz encompasses wide spectrum of architecture and logic.\\n * The only requirement is account facet to comply with initialize() interface.\\n * Barz doesn't include built-in functions and is a full proxy, for maximum extensibility and modularity.\\n * @param _accountFacet Address of Account Facet in charge of the Barz initialization\\n * @param _verificationFacet Address of Verification Facet for verifying the signature. Could be any signature scheme\\n * @param _entryPoint Address of Entry Point contract\\n * @param _facetRegistry Address of Facet Registry. Facet Registry is a registry holding trusted facets that could be added to user's wallet\\n * @param _defaultFallBack Address of Default FallBack Handler. Middleware contract for more efficient deployment\\n * @param _ownerPublicKey Bytes of Owner Public Key using for initialization\\n */\\n constructor(\\n address _accountFacet,\\n address _verificationFacet,\\n address _entryPoint,\\n address _facetRegistry,\\n address _defaultFallBack,\\n bytes memory _ownerPublicKey\\n ) payable {\\n bytes memory initCall = abi.encodeWithSignature(\\n \\\"initialize(address,address,address,address,bytes)\\\",\\n _verificationFacet,\\n _entryPoint,\\n _facetRegistry,\\n _defaultFallBack,\\n _ownerPublicKey\\n );\\n (bool success, bytes memory result) = _accountFacet.delegatecall(\\n initCall\\n );\\n if (!success || uint256(bytes32(result)) != 1) {\\n revert Barz__InitializationFailure();\\n }\\n }\\n\\n /**\\n * @notice Fallback function for Barz complying with Diamond Standard with customization of adding Default Fallback Handler\\n * @dev Find facet for function that is called and execute the function if a facet is found and return any value.\\n */\\n fallback() external payable {\\n LibDiamond.DiamondStorage storage ds;\\n bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION;\\n // get diamond storage\\n assembly {\\n ds.slot := position\\n }\\n // get facet from function selector\\n address facet = address(bytes20(ds.facets[msg.sig]));\\n if (facet == address(0))\\n facet = ds.defaultFallbackHandler.facetAddress(msg.sig);\\n require(facet != address(0), \\\"Barz: Function does not exist\\\");\\n // Execute external function from facet using delegatecall and return any value.\\n assembly {\\n // copy function selector and any arguments\\n calldatacopy(0, 0, calldatasize())\\n // execute function call using the facet\\n let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)\\n // get any return value\\n returndatacopy(0, 0, returndatasize())\\n // return any return value or error back to the caller\\n switch result\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @notice Receive function to receive native token without data\\n */\\n receive() external payable {}\\n}\\n\",\"keccak256\":\"0xd1c773409a4b3d1ca0316445d9ea1d686bab9cd5f6731fbdb0766a93edfd7bdb\",\"license\":\"Apache-2.0\"},\"contracts/BarzFactory.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {Barz} from \\\"./Barz.sol\\\";\\nimport {IBarzFactory} from \\\"./interfaces/IBarzFactory.sol\\\";\\n\\n/**\\n * @title Barz Factory\\n * @dev Contract to easily deploy Barz to a pre-computed address with a single call\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract BarzFactory is IBarzFactory {\\n address public immutable accountFacet;\\n address public immutable entryPoint;\\n address public immutable facetRegistry;\\n address public immutable defaultFallback;\\n\\n /**\\n * @notice Sets the initialization data for Barz contract initialization\\n * @param _accountFacet Account Facet to be used to create Barz\\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\\n * @param _facetRegistry Facet Registry to be used to create Barz\\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\\n */\\n constructor(\\n address _accountFacet,\\n address _entryPoint,\\n address _facetRegistry,\\n address _defaultFallback\\n ) {\\n accountFacet = _accountFacet;\\n entryPoint = _entryPoint;\\n facetRegistry = _facetRegistry;\\n defaultFallback = _defaultFallback;\\n }\\n\\n /**\\n * @notice Creates the Barz with a single call. It creates the Barz contract with the givent verification facet\\n * @param _verificationFacet Address of verification facet used for creating the barz account\\n * @param _owner Public Key of the owner to initialize barz account\\n * @param _salt Salt used for deploying barz with create2\\n * @return barz Instance of Barz contract deployed with the given parameters\\n */\\n function createAccount(\\n address _verificationFacet,\\n bytes calldata _owner,\\n uint256 _salt\\n ) external override returns (Barz barz) {\\n address addr = getAddress(_verificationFacet, _owner, _salt);\\n uint codeSize = addr.code.length;\\n if (codeSize > 0) {\\n return Barz(payable(addr));\\n }\\n barz = new Barz{salt: bytes32(_salt)}(\\n accountFacet,\\n _verificationFacet,\\n entryPoint,\\n facetRegistry,\\n defaultFallback,\\n _owner\\n );\\n emit BarzDeployed(address(barz));\\n }\\n\\n /**\\n * @notice Calculates the address of Barz with the given parameters\\n * @param _verificationFacet Address of verification facet used for creating the barz account\\n * @param _owner Public Key of the owner to initialize barz account\\n * @param _salt Salt used for deploying barz with create2\\n * @return barzAddress Precalculated Barz address\\n */\\n function getAddress(\\n address _verificationFacet,\\n bytes calldata _owner,\\n uint256 _salt\\n ) public view override returns (address barzAddress) {\\n bytes memory bytecode = getBytecode(\\n accountFacet,\\n _verificationFacet,\\n entryPoint,\\n facetRegistry,\\n defaultFallback,\\n _owner\\n );\\n bytes32 hash = keccak256(\\n abi.encodePacked(\\n bytes1(0xff),\\n address(this),\\n _salt,\\n keccak256(bytecode)\\n )\\n );\\n barzAddress = address(uint160(uint256(hash)));\\n }\\n\\n /**\\n * @notice Returns the bytecode of Barz with the given parameter\\n * @param _accountFacet Account Facet to be used to create Barz\\n * @param _verificationFacet Verification Facet to be used to create Barz\\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\\n * @param _facetRegistry Facet Registry to be used to create Barz\\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\\n * @param _ownerPublicKey Public Key of owner to be used to initialize Barz ownership\\n * @return barzBytecode Bytecode of Barz\\n */\\n function getBytecode(\\n address _accountFacet,\\n address _verificationFacet,\\n address _entryPoint,\\n address _facetRegistry,\\n address _defaultFallback,\\n bytes calldata _ownerPublicKey\\n ) public pure override returns (bytes memory barzBytecode) {\\n bytes memory bytecode = type(Barz).creationCode;\\n barzBytecode = abi.encodePacked(\\n bytecode,\\n abi.encode(\\n _accountFacet,\\n _verificationFacet,\\n _entryPoint,\\n _facetRegistry,\\n _defaultFallback,\\n _ownerPublicKey\\n )\\n );\\n }\\n\\n /**\\n * @notice Returns the creation code of the Barz contract\\n * @return creationCode Creation code of Barz\\n */\\n function getCreationCode()\\n public\\n pure\\n override\\n returns (bytes memory creationCode)\\n {\\n creationCode = type(Barz).creationCode;\\n }\\n}\\n\",\"keccak256\":\"0x76d6058fa4714f5ef87b876e49ce7e21f581164901eea906ec743e82362b1df6\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IBarz.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Barz Interface\\n * @dev Interface of Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IBarz {\\n error Barz__InitializationFailure();\\n}\\n\",\"keccak256\":\"0xca9f0c2c1ad7d06088fa16ae92d587416f2d10d8f999d7afe8ca5c4d73410aba\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IBarzFactory.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {Barz} from \\\"../Barz.sol\\\";\\n\\n/**\\n * @title Barz Factory Interface\\n * @dev Interface of contract to easily deploy Barz to a pre-computed address with a single call\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IBarzFactory {\\n event BarzDeployed(address);\\n\\n function createAccount(\\n address verificationFacet,\\n bytes calldata owner,\\n uint256 salt\\n ) external returns (Barz);\\n\\n function getAddress(\\n address verificationFacet,\\n bytes calldata owner,\\n uint256 salt\\n ) external view returns (address);\\n\\n function getBytecode(\\n address accountFacet,\\n address verificationFacet,\\n address entryPoint,\\n address facetRegistry,\\n address defaultFallback,\\n bytes memory ownerPublicKey\\n ) external pure returns (bytes memory);\\n\\n function getCreationCode() external pure returns (bytes memory);\\n}\\n\",\"keccak256\":\"0xadb48a6f3025f6395e26ffd5f9319da73ad2383906c8223e8455f41f420fba26\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\\n bytes4(keccak256(\\\"verifyRestrictions(address,address,uint256,bytes)\\\"));\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // Default Fallback Handler of the barz.\\n IDiamondLoupe defaultFallbackHandler;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function enforceIsSelf() internal view {\\n require(msg.sender == address(this), \\\"LibDiamond: Caller not self\\\");\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n\\n unchecked {\\n facetIndex++;\\n }\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n\\n function restrictionsFacet() internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(\\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2cabdc00de859c3a3170ce3bda5d0e5fd3933d47ce904fd1585f9818b02572f8\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x61010060405234801561001157600080fd5b50604051610eba380380610eba8339810160408190526100309161006e565b6001600160a01b0393841660805291831660a052821660c0521660e0526100c2565b80516001600160a01b038116811461006957600080fd5b919050565b6000806000806080858703121561008457600080fd5b61008d85610052565b935061009b60208601610052565b92506100a960408601610052565b91506100b760608601610052565b905092959194509250565b60805160a05160c05160e051610d886101326000396000818161013b015281816102b3015261048101526000818160bf01528181610292015261046001526000818161016301528181610271015261043f01526000818161018b0152818161024f015261041d0152610d886000f3fe60806040523480156200001157600080fd5b5060043610620000925760003560e01c806344409a82116200006257806344409a821462000135578063b0d691fe146200015d578063b0f5d4641462000185578063c8a7adf514620001ad57600080fd5b8062c194db14620000975780630a1acd7314620000b9578063296601cd146200010757806333bb64a7146200011e575b600080fd5b620000a1620001c4565b604051620000b091906200056c565b60405180910390f35b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001620000b0565b620000e16200011836600462000635565b6200020e565b620000a16200012f36600462000695565b6200036d565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e1620001be36600462000635565b62000414565b606060405180602001620001d89062000538565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082820381018352601f90910116604052919050565b6000806200021f8686868662000414565b905073ffffffffffffffffffffffffffffffffffffffff81163b8015620002495750905062000365565b8360001b7f0000000000000000000000000000000000000000000000000000000000000000887f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008b8b604051620002e29062000538565b620002f497969594939291906200073a565b8190604051809103906000f590508015801562000315573d6000803e3d6000fd5b5060405173ffffffffffffffffffffffffffffffffffffffff821681529093507f9e6e326008e68f57877e2bae766a5745c162e42359e34834a7f0661fa82d31b19060200160405180910390a150505b949350505050565b6060600060405180602001620003839062000538565b6020820181038252601f19601f8201166040525090508089898989898989604051602001620003b997969594939291906200073a565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052620003f79291602001620007cd565b604051602081830303815290604052915050979650505050505050565b600080620004a87f0000000000000000000000000000000000000000000000000000000000000000877f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008a8a6200036d565b8051602091820120604080517fff00000000000000000000000000000000000000000000000000000000000000818501523060601b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001660218201526035810196909652605580870192909252805180870390920182526075909501909452835193019290922095945050505050565b610552806200080183390190565b60005b838110156200056357818101518382015260200162000549565b50506000910152565b60208152600082518060208401526200058d81604085016020870162000546565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b803573ffffffffffffffffffffffffffffffffffffffff81168114620005e457600080fd5b919050565b60008083601f840112620005fc57600080fd5b50813567ffffffffffffffff8111156200061557600080fd5b6020830191508360208285010111156200062e57600080fd5b9250929050565b600080600080606085870312156200064c57600080fd5b6200065785620005bf565b9350602085013567ffffffffffffffff8111156200067457600080fd5b6200068287828801620005e9565b9598909750949560400135949350505050565b600080600080600080600060c0888a031215620006b157600080fd5b620006bc88620005bf565b9650620006cc60208901620005bf565b9550620006dc60408901620005bf565b9450620006ec60608901620005bf565b9350620006fc60808901620005bf565b925060a088013567ffffffffffffffff8111156200071957600080fd5b620007278a828b01620005e9565b989b979a50959850939692959293505050565b600073ffffffffffffffffffffffffffffffffffffffff808a16835280891660208401528088166040840152808716606084015280861660808401525060c060a08301528260c0830152828460e0840137600060e0848401015260e07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f850116830101905098975050505050505050565b60008351620007e181846020880162000546565b835190830190620007f781836020880162000546565b0194935050505056fe608060405260405161055238038061055283398101604081905261002291610163565b6000858585858560405160240161003d959493929190610264565b60408051601f198184030181529181526020820180516001600160e01b0316634a93641760e01b1790525190915060009081906001600160a01b038a16906100869085906102c3565b600060405180830381855af49150503d80600081146100c1576040519150601f19603f3d011682016040523d82523d6000602084013e6100c6565b606091505b50915091508115806100e157506100dc816102df565b600114155b156100ff57604051636ff35f8960e01b815260040160405180910390fd5b505050505050505050610306565b80516001600160a01b038116811461012457600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101561015a578181015183820152602001610142565b50506000910152565b60008060008060008060c0878903121561017c57600080fd5b6101858761010d565b95506101936020880161010d565b94506101a16040880161010d565b93506101af6060880161010d565b92506101bd6080880161010d565b60a08801519092506001600160401b03808211156101da57600080fd5b818901915089601f8301126101ee57600080fd5b81518181111561020057610200610129565b604051601f8201601f19908116603f0116810190838211818310171561022857610228610129565b816040528281528c602084870101111561024157600080fd5b61025283602083016020880161013f565b80955050505050509295509295509295565b600060018060a01b0380881683528087166020840152808616604084015280851660608401525060a0608083015282518060a08401526102ab8160c085016020870161013f565b601f01601f19169190910160c0019695505050505050565b600082516102d581846020870161013f565b9190910192915050565b80516020808301519190811015610300576000198160200360031b1b821691505b50919050565b61023d806103156000396000f3fe60806040523661000b57005b600080357fffffffff000000000000000000000000000000000000000000000000000000001681527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020819052604090912054819060601c80610125576004838101546040517fcdffacc60000000000000000000000000000000000000000000000000000000081526000357fffffffff00000000000000000000000000000000000000000000000000000000169281019290925273ffffffffffffffffffffffffffffffffffffffff169063cdffacc690602401602060405180830381865afa1580156100fe573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061012291906101ca565b90505b73ffffffffffffffffffffffffffffffffffffffff81166101a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4261727a3a2046756e6374696f6e20646f6573206e6f74206578697374000000604482015260640160405180910390fd5b3660008037600080366000845af43d6000803e8080156101c5573d6000f35b3d6000fd5b6000602082840312156101dc57600080fd5b815173ffffffffffffffffffffffffffffffffffffffff8116811461020057600080fd5b939250505056fea26469706673582212200f3fa76ace3be8675d8b4c0d6c210a922fff2c2f1444023b817d1f6c908cd56a64736f6c63430008150033a2646970667358221220329ad45a4ef4915180001cb1fc90a5f97ad94a0b280426a580cba65fce28c0f164736f6c63430008150033", + "deployedBytecode": "0x60806040523480156200001157600080fd5b5060043610620000925760003560e01c806344409a82116200006257806344409a821462000135578063b0d691fe146200015d578063b0f5d4641462000185578063c8a7adf514620001ad57600080fd5b8062c194db14620000975780630a1acd7314620000b9578063296601cd146200010757806333bb64a7146200011e575b600080fd5b620000a1620001c4565b604051620000b091906200056c565b60405180910390f35b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001620000b0565b620000e16200011836600462000635565b6200020e565b620000a16200012f36600462000695565b6200036d565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e1620001be36600462000635565b62000414565b606060405180602001620001d89062000538565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082820381018352601f90910116604052919050565b6000806200021f8686868662000414565b905073ffffffffffffffffffffffffffffffffffffffff81163b8015620002495750905062000365565b8360001b7f0000000000000000000000000000000000000000000000000000000000000000887f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008b8b604051620002e29062000538565b620002f497969594939291906200073a565b8190604051809103906000f590508015801562000315573d6000803e3d6000fd5b5060405173ffffffffffffffffffffffffffffffffffffffff821681529093507f9e6e326008e68f57877e2bae766a5745c162e42359e34834a7f0661fa82d31b19060200160405180910390a150505b949350505050565b6060600060405180602001620003839062000538565b6020820181038252601f19601f8201166040525090508089898989898989604051602001620003b997969594939291906200073a565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052620003f79291602001620007cd565b604051602081830303815290604052915050979650505050505050565b600080620004a87f0000000000000000000000000000000000000000000000000000000000000000877f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008a8a6200036d565b8051602091820120604080517fff00000000000000000000000000000000000000000000000000000000000000818501523060601b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001660218201526035810196909652605580870192909252805180870390920182526075909501909452835193019290922095945050505050565b610552806200080183390190565b60005b838110156200056357818101518382015260200162000549565b50506000910152565b60208152600082518060208401526200058d81604085016020870162000546565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b803573ffffffffffffffffffffffffffffffffffffffff81168114620005e457600080fd5b919050565b60008083601f840112620005fc57600080fd5b50813567ffffffffffffffff8111156200061557600080fd5b6020830191508360208285010111156200062e57600080fd5b9250929050565b600080600080606085870312156200064c57600080fd5b6200065785620005bf565b9350602085013567ffffffffffffffff8111156200067457600080fd5b6200068287828801620005e9565b9598909750949560400135949350505050565b600080600080600080600060c0888a031215620006b157600080fd5b620006bc88620005bf565b9650620006cc60208901620005bf565b9550620006dc60408901620005bf565b9450620006ec60608901620005bf565b9350620006fc60808901620005bf565b925060a088013567ffffffffffffffff8111156200071957600080fd5b620007278a828b01620005e9565b989b979a50959850939692959293505050565b600073ffffffffffffffffffffffffffffffffffffffff808a16835280891660208401528088166040840152808716606084015280861660808401525060c060a08301528260c0830152828460e0840137600060e0848401015260e07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f850116830101905098975050505050505050565b60008351620007e181846020880162000546565b835190830190620007f781836020880162000546565b0194935050505056fe608060405260405161055238038061055283398101604081905261002291610163565b6000858585858560405160240161003d959493929190610264565b60408051601f198184030181529181526020820180516001600160e01b0316634a93641760e01b1790525190915060009081906001600160a01b038a16906100869085906102c3565b600060405180830381855af49150503d80600081146100c1576040519150601f19603f3d011682016040523d82523d6000602084013e6100c6565b606091505b50915091508115806100e157506100dc816102df565b600114155b156100ff57604051636ff35f8960e01b815260040160405180910390fd5b505050505050505050610306565b80516001600160a01b038116811461012457600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101561015a578181015183820152602001610142565b50506000910152565b60008060008060008060c0878903121561017c57600080fd5b6101858761010d565b95506101936020880161010d565b94506101a16040880161010d565b93506101af6060880161010d565b92506101bd6080880161010d565b60a08801519092506001600160401b03808211156101da57600080fd5b818901915089601f8301126101ee57600080fd5b81518181111561020057610200610129565b604051601f8201601f19908116603f0116810190838211818310171561022857610228610129565b816040528281528c602084870101111561024157600080fd5b61025283602083016020880161013f565b80955050505050509295509295509295565b600060018060a01b0380881683528087166020840152808616604084015280851660608401525060a0608083015282518060a08401526102ab8160c085016020870161013f565b601f01601f19169190910160c0019695505050505050565b600082516102d581846020870161013f565b9190910192915050565b80516020808301519190811015610300576000198160200360031b1b821691505b50919050565b61023d806103156000396000f3fe60806040523661000b57005b600080357fffffffff000000000000000000000000000000000000000000000000000000001681527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020819052604090912054819060601c80610125576004838101546040517fcdffacc60000000000000000000000000000000000000000000000000000000081526000357fffffffff00000000000000000000000000000000000000000000000000000000169281019290925273ffffffffffffffffffffffffffffffffffffffff169063cdffacc690602401602060405180830381865afa1580156100fe573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061012291906101ca565b90505b73ffffffffffffffffffffffffffffffffffffffff81166101a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4261727a3a2046756e6374696f6e20646f6573206e6f74206578697374000000604482015260640160405180910390fd5b3660008037600080366000845af43d6000803e8080156101c5573d6000f35b3d6000fd5b6000602082840312156101dc57600080fd5b815173ffffffffffffffffffffffffffffffffffffffff8116811461020057600080fd5b939250505056fea26469706673582212200f3fa76ace3be8675d8b4c0d6c210a922fff2c2f1444023b817d1f6c908cd56a64736f6c63430008150033a2646970667358221220329ad45a4ef4915180001cb1fc90a5f97ad94a0b280426a580cba65fce28c0f164736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "Contract to easily deploy Barz to a pre-computed address with a single call", + "kind": "dev", + "methods": { + "constructor": { + "params": { + "_accountFacet": "Account Facet to be used to create Barz", + "_defaultFallback": "Default Fallback Handler to be used to create Barz", + "_entryPoint": "Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF", + "_facetRegistry": "Facet Registry to be used to create Barz" + } + }, + "createAccount(address,bytes,uint256)": { + "params": { + "_owner": "Public Key of the owner to initialize barz account", + "_salt": "Salt used for deploying barz with create2", + "_verificationFacet": "Address of verification facet used for creating the barz account" + }, + "returns": { + "barz": "Instance of Barz contract deployed with the given parameters" + } + }, + "getAddress(address,bytes,uint256)": { + "params": { + "_owner": "Public Key of the owner to initialize barz account", + "_salt": "Salt used for deploying barz with create2", + "_verificationFacet": "Address of verification facet used for creating the barz account" + }, + "returns": { + "barzAddress": "Precalculated Barz address" + } + }, + "getBytecode(address,address,address,address,address,bytes)": { + "params": { + "_accountFacet": "Account Facet to be used to create Barz", + "_defaultFallback": "Default Fallback Handler to be used to create Barz", + "_entryPoint": "Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF", + "_facetRegistry": "Facet Registry to be used to create Barz", + "_ownerPublicKey": "Public Key of owner to be used to initialize Barz ownership", + "_verificationFacet": "Verification Facet to be used to create Barz" + }, + "returns": { + "barzBytecode": "Bytecode of Barz" + } + }, + "getCreationCode()": { + "returns": { + "creationCode": "Creation code of Barz" + } + } + }, + "title": "Barz Factory", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "constructor": { + "notice": "Sets the initialization data for Barz contract initialization" + }, + "createAccount(address,bytes,uint256)": { + "notice": "Creates the Barz with a single call. It creates the Barz contract with the givent verification facet" + }, + "getAddress(address,bytes,uint256)": { + "notice": "Calculates the address of Barz with the given parameters" + }, + "getBytecode(address,address,address,address,address,bytes)": { + "notice": "Returns the bytecode of Barz with the given parameter" + }, + "getCreationCode()": { + "notice": "Returns the creation code of the Barz contract" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/mantle/DefaultFallbackHandler.json b/deployments/mantle/DefaultFallbackHandler.json new file mode 100644 index 0000000..146516a --- /dev/null +++ b/deployments/mantle/DefaultFallbackHandler.json @@ -0,0 +1,275 @@ +{ + "address": "0x2e7f1dAe1F3799d20f5c31bEFdc7A620f664728D", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_diamondCutFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_accountFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_tokenReceiverFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_diamondLoupeFacet", + "type": "address" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_initializationContractAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "InitializationFunctionReverted", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "indexed": false, + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "DiamondCut", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_functionSelector", + "type": "bytes4" + } + ], + "name": "facetAddress", + "outputs": [ + { + "internalType": "address", + "name": "facetAddress_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetAddresses", + "outputs": [ + { + "internalType": "address[]", + "name": "facetAddresses_", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_facet", + "type": "address" + } + ], + "name": "facetFunctionSelectors", + "outputs": [ + { + "internalType": "bytes4[]", + "name": "facetFunctionSelectors_", + "type": "bytes4[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facets", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondLoupe.Facet[]", + "name": "facets_", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0xf797265f54f937782b3c4b657fc2ce186f1b6701c6ac893a0be464fc7f9b843c", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xb33654322bD3803821031624f5922eb14C9b8d18", + "contractAddress": null, + "transactionIndex": 5, + "gasUsed": "11131237742", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000001000000000800002000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000", + "blockHash": "0x2e96bb4a1f2cd5d81199117635f15a3007e4c48b66ccd472c3347454742a94e1", + "transactionHash": "0xf797265f54f937782b3c4b657fc2ce186f1b6701c6ac893a0be464fc7f9b843c", + "logs": [ + { + "transactionIndex": 5, + "blockNumber": 61655430, + "transactionHash": "0xf797265f54f937782b3c4b657fc2ce186f1b6701c6ac893a0be464fc7f9b843c", + "address": "0x2e7f1dAe1F3799d20f5c31bEFdc7A620f664728D", + "topics": [ + "0x8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb673" + ], + "data": "0x000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000580000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000000000000000000000000000000000003600000000000000000000000000b9504140771c3688ff041917192277d2f52e1e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000011f931c1c00000000000000000000000000000000000000000000000000000000000000000000000000000000fde53272dcd7938d16e031a6989753c321728332000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000005b61d27f60000000000000000000000000000000000000000000000000000000047e1da2a000000000000000000000000000000000000000000000000000000003a871cdd00000000000000000000000000000000000000000000000000000000d087d28800000000000000000000000000000000000000000000000000000000b0d691fe000000000000000000000000000000000000000000000000000000000000000000000000000000003143e1c0af0cdc153423863923cf4e3818e34daa000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000005150b7a0200000000000000000000000000000000000000000000000000000000f23a6e6100000000000000000000000000000000000000000000000000000000bc197c81000000000000000000000000000000000000000000000000000000000023de2900000000000000000000000000000000000000000000000000000000a4c0ed3600000000000000000000000000000000000000000000000000000000000000000000000000000000ce36b85d12d81cd619c745c7717f3396e184ac7c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000097a0ed62700000000000000000000000000000000000000000000000000000000adfca15e0000000000000000000000000000000000000000000000000000000052ef6b2c00000000000000000000000000000000000000000000000000000000cdffacc60000000000000000000000000000000000000000000000000000000001ffc9a700000000000000000000000000000000000000000000000000000000f9796ccf0000000000000000000000000000000000000000000000000000000001a5502200000000000000000000000000000000000000000000000000000000d42139a900000000000000000000000000000000000000000000000000000000e3a2f6fe000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "logIndex": 18, + "blockHash": "0x2e96bb4a1f2cd5d81199117635f15a3007e4c48b66ccd472c3347454742a94e1" + } + ], + "blockNumber": 61655430, + "cumulativeGasUsed": "14703409460", + "status": 1, + "byzantium": true + }, + "args": [ + "0x0B9504140771C3688Ff041917192277D2f52E1e0", + "0xFde53272dcd7938d16E031A6989753c321728332", + "0x3143E1C0Af0Cdc153423863923Cf4e3818e34Daa", + "0xCe36b85d12D81cd619C745c7717f3396E184Ac7C" + ], + "numDeployments": 1, + "solcInputHash": "ad34345aa73d96f52b3e14df983b6b29", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_diamondCutFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_accountFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_tokenReceiverFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_diamondLoupeFacet\",\"type\":\"address\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_initializationContractAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"InitializationFunctionReverted\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"DiamondCut\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_functionSelector\",\"type\":\"bytes4\"}],\"name\":\"facetAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"facetAddress_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetAddresses\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"facetAddresses_\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_facet\",\"type\":\"address\"}],\"name\":\"facetFunctionSelectors\",\"outputs\":[{\"internalType\":\"bytes4[]\",\"name\":\"facetFunctionSelectors_\",\"type\":\"bytes4[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facets\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondLoupe.Facet[]\",\"name\":\"facets_\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"A default fallback handler for Barz\",\"kind\":\"dev\",\"methods\":{\"constructor\":{\"details\":\"This contract is also a diamond that holds the default facets to reduce gas cost for wallet activation. Within the constructor this conducts diamond cut to initially setup the diamond. This is a non-upgradeable contract\",\"params\":{\"_accountFacet\":\"Address account facet\",\"_diamondCutFacet\":\"Address if diamond cut facet\",\"_diamondLoupeFacet\":\"Address of diamond loupe facet\",\"_tokenReceiverFacet\":\"Address of token receiver facet\"}},\"facetAddress(bytes4)\":{\"details\":\"If facet is not found return address(0).\",\"params\":{\"_functionSelector\":\"The function selector.\"},\"returns\":{\"facetAddress_\":\"The facet address.\"}},\"facetAddresses()\":{\"returns\":{\"facetAddresses_\":\"facetAddresses_\"}},\"facetFunctionSelectors(address)\":{\"params\":{\"_facet\":\"The facet address.\"},\"returns\":{\"facetFunctionSelectors_\":\"facetFunctionSelectors_\"}},\"facets()\":{\"returns\":{\"facets_\":\"The facet struct array including all facet information\"}}},\"title\":\"DefaultFallbackHandler\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"Sets the middleware diamond for Barz wallet as a fallback handler\"},\"facetAddress(bytes4)\":{\"notice\":\"Gets the facet that supports the given selector.\"},\"facetAddresses()\":{\"notice\":\"Get all the facet addresses used by a diamond.\"},\"facetFunctionSelectors(address)\":{\"notice\":\"Gets all the function selectors provided by a facet.\"},\"facets()\":{\"notice\":\"Returns the facet information of call facets registered to this diamond.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/infrastructure/DefaultFallbackHandler.sol\":\"DefaultFallbackHandler\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/introspection/IERC165.sol\\\";\\n\\n/**\\n * @dev _Available since v3.1._\\n */\\ninterface IERC1155Receiver is IERC165 {\\n /**\\n * @dev Handles the receipt of a single ERC1155 token type. This function is\\n * called at the end of a `safeTransferFrom` after the balance has been updated.\\n *\\n * NOTE: To accept the transfer, this must return\\n * `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))`\\n * (i.e. 0xf23a6e61, or its own function selector).\\n *\\n * @param operator The address which initiated the transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param id The ID of the token being transferred\\n * @param value The amount of tokens being transferred\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155Received(\\n address operator,\\n address from,\\n uint256 id,\\n uint256 value,\\n bytes calldata data\\n ) external returns (bytes4);\\n\\n /**\\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\\n * is called at the end of a `safeBatchTransferFrom` after the balances have\\n * been updated.\\n *\\n * NOTE: To accept the transfer(s), this must return\\n * `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))`\\n * (i.e. 0xbc197c81, or its own function selector).\\n *\\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155BatchReceived(\\n address operator,\\n address from,\\n uint256[] calldata ids,\\n uint256[] calldata values,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xeb373f1fdc7b755c6a750123a9b9e3a8a02c1470042fd6505d875000a80bde0b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title ERC721 token receiver interface\\n * @dev Interface for any contract that wants to support safeTransfers\\n * from ERC721 asset contracts.\\n */\\ninterface IERC721Receiver {\\n /**\\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\\n * by `operator` from `from`, this function is called.\\n *\\n * It must return its Solidity selector to confirm the token transfer.\\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\\n *\\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\\n */\\n function onERC721Received(\\n address operator,\\n address from,\\n uint256 tokenId,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\\n *\\n * Accounts can be notified of {IERC777} tokens being sent to them by having a\\n * contract implement this interface (contract holders can be their own\\n * implementer) and registering it on the\\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\\n *\\n * See {IERC1820Registry} and {ERC1820Implementer}.\\n */\\ninterface IERC777Recipient {\\n /**\\n * @dev Called by an {IERC777} token contract whenever tokens are being\\n * moved or created into a registered account (`to`). The type of operation\\n * is conveyed by `from` being the zero address or not.\\n *\\n * This call occurs _after_ the token contract's state is updated, so\\n * {IERC777-balanceOf}, etc., can be used to query the post-operation state.\\n *\\n * This function may revert to prevent the operation from being executed.\\n */\\n function tokensReceived(\\n address operator,\\n address from,\\n address to,\\n uint256 amount,\\n bytes calldata userData,\\n bytes calldata operatorData\\n ) external;\\n}\\n\",\"keccak256\":\"0x1a5d61db2733202ba361e6d6741cd2e662380e22b80e987eacfc91973f2267dc\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"contracts/aa-4337/core/BaseAccount.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-empty-blocks */\\n\\nimport \\\"../interfaces/IAccount.sol\\\";\\nimport \\\"../interfaces/IEntryPoint.sol\\\";\\nimport \\\"./Helpers.sol\\\";\\n\\n/**\\n * Basic account implementation.\\n * this contract provides the basic logic for implementing the IAccount interface - validateUserOp\\n * specific account implementation should inherit it and provide the account-specific logic\\n */\\nabstract contract BaseAccount is IAccount {\\n using UserOperationLib for UserOperation;\\n\\n //return value in case of signature failure, with no time-range.\\n // equivalent to _packValidationData(true,0,0);\\n uint256 internal constant SIG_VALIDATION_FAILED = 1;\\n\\n /**\\n * Return the account nonce.\\n * This method returns the next sequential nonce.\\n * For a nonce of a specific key, use `entrypoint.getNonce(account, key)`\\n */\\n function getNonce() public view virtual returns (uint256) {\\n return entryPoint().getNonce(address(this), 0);\\n }\\n\\n /**\\n * return the entryPoint used by this account.\\n * subclass should return the current entryPoint used by this account.\\n */\\n function entryPoint() public view virtual returns (IEntryPoint);\\n\\n /**\\n * Validate user's signature and nonce.\\n * subclass doesn't need to override this method. Instead, it should override the specific internal validation methods.\\n */\\n function validateUserOp(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n uint256 missingAccountFunds\\n ) external virtual override returns (uint256 validationData) {\\n _requireFromEntryPoint();\\n validationData = _validateSignature(userOp, userOpHash);\\n _validateNonce(userOp.nonce);\\n _payPrefund(missingAccountFunds);\\n }\\n\\n /**\\n * ensure the request comes from the known entrypoint.\\n */\\n function _requireFromEntryPoint() internal view virtual {\\n require(\\n msg.sender == address(entryPoint()),\\n \\\"account: not from EntryPoint\\\"\\n );\\n }\\n\\n /**\\n * validate the signature is valid for this message.\\n * @param userOp validate the userOp.signature field\\n * @param userOpHash convenient field: the hash of the request, to check the signature against\\n * (also hashes the entrypoint and chain id)\\n * @return validationData signature and time-range of this operation\\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\\n * otherwise, an address of an \\\"authorizer\\\" contract.\\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \\\"indefinite\\\"\\n * <6-byte> validAfter - first timestamp this operation is valid\\n * If the account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\\n */\\n function _validateSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) internal virtual returns (uint256 validationData);\\n\\n /**\\n * Validate the nonce of the UserOperation.\\n * This method may validate the nonce requirement of this account.\\n * e.g.\\n * To limit the nonce to use sequenced UserOps only (no \\\"out of order\\\" UserOps):\\n * `require(nonce < type(uint64).max)`\\n * For a hypothetical account that *requires* the nonce to be out-of-order:\\n * `require(nonce & type(uint64).max == 0)`\\n *\\n * The actual nonce uniqueness is managed by the EntryPoint, and thus no other\\n * action is needed by the account itself.\\n *\\n * @param nonce to validate\\n *\\n * solhint-disable-next-line no-empty-blocks\\n */\\n function _validateNonce(uint256 nonce) internal view virtual {}\\n\\n /**\\n * sends to the entrypoint (msg.sender) the missing funds for this transaction.\\n * subclass MAY override this method for better funds management\\n * (e.g. send to the entryPoint more than the minimum required, so that in future transactions\\n * it will not be required to send again)\\n * @param missingAccountFunds the minimum value this method should send the entrypoint.\\n * this value MAY be zero, in case there is enough deposit, or the userOp has a paymaster.\\n */\\n function _payPrefund(uint256 missingAccountFunds) internal virtual {\\n if (missingAccountFunds != 0) {\\n (bool success, ) = payable(msg.sender).call{\\n value: missingAccountFunds,\\n gas: type(uint256).max\\n }(\\\"\\\");\\n (success);\\n //ignore failure (its EntryPoint's job to verify, not account.)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa0dcc386b0f04711db3e394fb50e55a3b3b1a4d19fac1f10895844e1aa4e3d5c\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/core/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable no-inline-assembly */\\n\\n/**\\n * returned data from validateUserOp.\\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\\n * @param aggregator - address(0) - the account validated the signature by itself.\\n * address(1) - the account failed to validate the signature.\\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\\n * @param validAfter - this UserOp is valid only after this timestamp.\\n * @param validaUntil - this UserOp is valid only up to this timestamp.\\n */\\nstruct ValidationData {\\n address aggregator;\\n uint48 validAfter;\\n uint48 validUntil;\\n}\\n\\n//extract sigFailed, validAfter, validUntil.\\n// also convert zero validUntil to type(uint48).max\\nfunction _parseValidationData(\\n uint validationData\\n) pure returns (ValidationData memory data) {\\n address aggregator = address(uint160(validationData));\\n uint48 validUntil = uint48(validationData >> 160);\\n if (validUntil == 0) {\\n validUntil = type(uint48).max;\\n }\\n uint48 validAfter = uint48(validationData >> (48 + 160));\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n// intersect account and paymaster ranges.\\nfunction _intersectTimeRange(\\n uint256 validationData,\\n uint256 paymasterValidationData\\n) pure returns (ValidationData memory) {\\n ValidationData memory accountValidationData = _parseValidationData(\\n validationData\\n );\\n ValidationData memory pmValidationData = _parseValidationData(\\n paymasterValidationData\\n );\\n address aggregator = accountValidationData.aggregator;\\n if (aggregator == address(0)) {\\n aggregator = pmValidationData.aggregator;\\n }\\n uint48 validAfter = accountValidationData.validAfter;\\n uint48 validUntil = accountValidationData.validUntil;\\n uint48 pmValidAfter = pmValidationData.validAfter;\\n uint48 pmValidUntil = pmValidationData.validUntil;\\n\\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp\\n * @param data - the ValidationData to pack\\n */\\nfunction _packValidationData(\\n ValidationData memory data\\n) pure returns (uint256) {\\n return\\n uint160(data.aggregator) |\\n (uint256(data.validUntil) << 160) |\\n (uint256(data.validAfter) << (160 + 48));\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp, when not using an aggregator\\n * @param sigFailed - true for signature failure, false for success\\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\\n * @param validAfter first timestamp this UserOperation is valid\\n */\\nfunction _packValidationData(\\n bool sigFailed,\\n uint48 validUntil,\\n uint48 validAfter\\n) pure returns (uint256) {\\n return\\n (sigFailed ? 1 : 0) |\\n (uint256(validUntil) << 160) |\\n (uint256(validAfter) << (160 + 48));\\n}\\n\\n/**\\n * keccak function over calldata.\\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\\n */\\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\\n assembly {\\n let mem := mload(0x40)\\n let len := data.length\\n calldatacopy(mem, data.offset, len)\\n ret := keccak256(mem, len)\\n }\\n}\\n\",\"keccak256\":\"0xa79f06cd158ecb8c0da95493a2f348933b8627a63e228b99738bff3aa107942d\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAccount.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\ninterface IAccount {\\n /**\\n * Validate user's signature and nonce\\n * the entryPoint will make the call to the recipient only if this validation call returns successfully.\\n * signature failure should be reported by returning SIG_VALIDATION_FAILED (1).\\n * This allows making a \\\"simulation call\\\" without a valid signature\\n * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure.\\n *\\n * @dev Must validate caller is the entryPoint.\\n * Must validate the signature and nonce\\n * @param userOp the operation that is about to be executed.\\n * @param userOpHash hash of the user's request data. can be used as the basis for signature.\\n * @param missingAccountFunds missing funds on the account's deposit in the entrypoint.\\n * This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call.\\n * The excess is left as a deposit in the entrypoint, for future calls.\\n * can be withdrawn anytime using \\\"entryPoint.withdrawTo()\\\"\\n * In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero.\\n * @return validationData packaged ValidationData structure. use `_packValidationData` and `_unpackValidationData` to encode and decode\\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\\n * otherwise, an address of an \\\"authorizer\\\" contract.\\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \\\"indefinite\\\"\\n * <6-byte> validAfter - first timestamp this operation is valid\\n * If an account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\\n */\\n function validateUserOp(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n uint256 missingAccountFunds\\n ) external returns (uint256 validationData);\\n}\\n\",\"keccak256\":\"0xcbc4b0973cf954c5895b7796335f651fbfcfb55f67dfa789a3d354f8e23c4f2b\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAggregator.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\n/**\\n * Aggregated Signatures validator.\\n */\\ninterface IAggregator {\\n /**\\n * validate aggregated signature.\\n * revert if the aggregated signature does not match the given list of operations.\\n */\\n function validateSignatures(\\n UserOperation[] calldata userOps,\\n bytes calldata signature\\n ) external view;\\n\\n /**\\n * validate signature of a single userOp\\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\\n * @param userOp the userOperation received from the user.\\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\\n * (usually empty, unless account and aggregator support some kind of \\\"multisig\\\"\\n */\\n function validateUserOpSignature(\\n UserOperation calldata userOp\\n ) external view returns (bytes memory sigForUserOp);\\n\\n /**\\n * aggregate multiple signatures into a single value.\\n * This method is called off-chain to calculate the signature to pass with handleOps()\\n * bundler MAY use optimized custom code perform this aggregation\\n * @param userOps array of UserOperations to collect the signatures from.\\n * @return aggregatedSignature the aggregated signature\\n */\\n function aggregateSignatures(\\n UserOperation[] calldata userOps\\n ) external view returns (bytes memory aggregatedSignature);\\n}\\n\",\"keccak256\":\"0xdfdcd80568f037716674619b31be630fcd8316262f05a815b41d1e81782c966a\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IEntryPoint.sol\":{\"content\":\"/**\\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\\n ** Only one instance required on each chain.\\n **/\\n// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-inline-assembly */\\n/* solhint-disable reason-string */\\n\\nimport \\\"./UserOperation.sol\\\";\\nimport \\\"./IStakeManager.sol\\\";\\nimport \\\"./IAggregator.sol\\\";\\nimport \\\"./INonceManager.sol\\\";\\n\\ninterface IEntryPoint is IStakeManager, INonceManager {\\n /***\\n * An event emitted after each successful request\\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\\n * @param sender - the account that generates this request.\\n * @param paymaster - if non-null, the paymaster that pays for this request.\\n * @param nonce - the nonce value from the request.\\n * @param success - true if the sender transaction succeeded, false if reverted.\\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\\n */\\n event UserOperationEvent(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address indexed paymaster,\\n uint256 nonce,\\n bool success,\\n uint256 actualGasCost,\\n uint256 actualGasUsed\\n );\\n\\n /**\\n * account \\\"sender\\\" was deployed.\\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\\n * @param sender the account that is deployed\\n * @param factory the factory used to deploy this account (in the initCode)\\n * @param paymaster the paymaster used by this UserOp\\n */\\n event AccountDeployed(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address factory,\\n address paymaster\\n );\\n\\n /**\\n * An event emitted if the UserOperation \\\"callData\\\" reverted with non-zero length\\n * @param userOpHash the request unique identifier.\\n * @param sender the sender of this request\\n * @param nonce the nonce used in the request\\n * @param revertReason - the return bytes from the (reverted) call to \\\"callData\\\".\\n */\\n event UserOperationRevertReason(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n uint256 nonce,\\n bytes revertReason\\n );\\n\\n /**\\n * an event emitted by handleOps(), before starting the execution loop.\\n * any event emitted before this event, is part of the validation.\\n */\\n event BeforeExecution();\\n\\n /**\\n * signature aggregator used by the following UserOperationEvents within this bundle.\\n */\\n event SignatureAggregatorChanged(address indexed aggregator);\\n\\n /**\\n * a custom revert error of handleOps, to identify the offending op.\\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\\n * @param reason - revert reason\\n * The string starts with a unique code \\\"AAmn\\\", where \\\"m\\\" is \\\"1\\\" for factory, \\\"2\\\" for account and \\\"3\\\" for paymaster issues,\\n * so a failure can be attributed to the correct entity.\\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\\n */\\n error FailedOp(uint256 opIndex, string reason);\\n\\n /**\\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\\n */\\n error SignatureValidationFailed(address aggregator);\\n\\n /**\\n * Successful result from simulateValidation.\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n */\\n error ValidationResult(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo\\n );\\n\\n /**\\n * Successful result from simulateValidation, if the account returns a signature aggregator\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\\n * bundler MUST use it to verify the signature, or reject the UserOperation\\n */\\n error ValidationResultWithAggregation(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo,\\n AggregatorStakeInfo aggregatorInfo\\n );\\n\\n /**\\n * return value of getSenderAddress\\n */\\n error SenderAddressResult(address sender);\\n\\n /**\\n * return value of simulateHandleOp\\n */\\n error ExecutionResult(\\n uint256 preOpGas,\\n uint256 paid,\\n uint48 validAfter,\\n uint48 validUntil,\\n bool targetSuccess,\\n bytes targetResult\\n );\\n\\n //UserOps handled, per aggregator\\n struct UserOpsPerAggregator {\\n UserOperation[] userOps;\\n // aggregator address\\n IAggregator aggregator;\\n // aggregated signature\\n bytes signature;\\n }\\n\\n /**\\n * Execute a batch of UserOperation.\\n * no signature aggregator is used.\\n * if any account requires an aggregator (that is, it returned an aggregator when\\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\\n * @param ops the operations to execute\\n * @param beneficiary the address to receive the fees\\n */\\n function handleOps(\\n UserOperation[] calldata ops,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * Execute a batch of UserOperation with Aggregators\\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\\n * @param beneficiary the address to receive the fees\\n */\\n function handleAggregatedOps(\\n UserOpsPerAggregator[] calldata opsPerAggregator,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * generate a request Id - unique identifier for this request.\\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\\n */\\n function getUserOpHash(\\n UserOperation calldata userOp\\n ) external view returns (bytes32);\\n\\n /**\\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\\n * @param userOp the user operation to validate.\\n */\\n function simulateValidation(UserOperation calldata userOp) external;\\n\\n /**\\n * gas and return values during simulation\\n * @param preOpGas the gas used for validation (including preValidationGas)\\n * @param prefund the required prefund for this operation\\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\\n */\\n struct ReturnInfo {\\n uint256 preOpGas;\\n uint256 prefund;\\n bool sigFailed;\\n uint48 validAfter;\\n uint48 validUntil;\\n bytes paymasterContext;\\n }\\n\\n /**\\n * returned aggregated signature info.\\n * the aggregator returned by the account, and its current stake.\\n */\\n struct AggregatorStakeInfo {\\n address aggregator;\\n StakeInfo stakeInfo;\\n }\\n\\n /**\\n * Get counterfactual sender address.\\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\\n * this method always revert, and returns the address in SenderAddressResult error\\n * @param initCode the constructor code to be passed into the UserOperation.\\n */\\n function getSenderAddress(bytes memory initCode) external;\\n\\n /**\\n * simulate full execution of a UserOperation (including both validation and target execution)\\n * this method will always revert with \\\"ExecutionResult\\\".\\n * it performs full validation of the UserOperation, but ignores signature error.\\n * an optional target address is called after the userop succeeds, and its value is returned\\n * (before the entire call is reverted)\\n * Note that in order to collect the the success/failure of the target call, it must be executed\\n * with trace enabled to track the emitted events.\\n * @param op the UserOperation to simulate\\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\\n * are set to the return from that call.\\n * @param targetCallData callData to pass to target address\\n */\\n function simulateHandleOp(\\n UserOperation calldata op,\\n address target,\\n bytes calldata targetCallData\\n ) external;\\n}\\n\",\"keccak256\":\"0x9ccb1b188eda8bbf5f6c2d01bd83c3d8b2b04fcf745283051d31fe96d1d8e40f\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/INonceManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\ninterface INonceManager {\\n /**\\n * Return the next nonce for this sender.\\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\\n * But UserOp with different keys can come with arbitrary order.\\n *\\n * @param sender the account address\\n * @param key the high 192 bit of the nonce\\n * @return nonce a full nonce to pass for next UserOp with this sender.\\n */\\n function getNonce(\\n address sender,\\n uint192 key\\n ) external view returns (uint256 nonce);\\n\\n /**\\n * Manually increment the nonce of the sender.\\n * This method is exposed just for completeness..\\n * Account does NOT need to call it, neither during validation, nor elsewhere,\\n * as the EntryPoint will update the nonce regardless.\\n * Possible use-case is call it with various keys to \\\"initialize\\\" their nonces to one, so that future\\n * UserOperations will not pay extra for the first transaction with a given key.\\n */\\n function incrementNonce(uint192 key) external;\\n}\\n\",\"keccak256\":\"0xce478ad0fa0d18a3b785ac854623029e7ab463d05873dfaa365abfa1bf100912\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IStakeManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8.12;\\n\\n/**\\n * manage deposits and stakes.\\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\\n * stake is value locked for at least \\\"unstakeDelay\\\" by the staked entity.\\n */\\ninterface IStakeManager {\\n event Deposited(address indexed account, uint256 totalDeposit);\\n\\n event Withdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /// Emitted when stake or unstake delay are modified\\n event StakeLocked(\\n address indexed account,\\n uint256 totalStaked,\\n uint256 unstakeDelaySec\\n );\\n\\n /// Emitted once a stake is scheduled for withdrawal\\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\\n\\n event StakeWithdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /**\\n * @param deposit the entity's deposit\\n * @param staked true if this entity is staked.\\n * @param stake actual amount of ether staked for this entity.\\n * @param unstakeDelaySec minimum delay to withdraw the stake.\\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\\n * and the rest fit into a 2nd cell.\\n * 112 bit allows for 10^15 eth\\n * 48 bit for full timestamp\\n * 32 bit allows 150 years for unstake delay\\n */\\n struct DepositInfo {\\n uint112 deposit;\\n bool staked;\\n uint112 stake;\\n uint32 unstakeDelaySec;\\n uint48 withdrawTime;\\n }\\n\\n //API struct used by getStakeInfo and simulateValidation\\n struct StakeInfo {\\n uint256 stake;\\n uint256 unstakeDelaySec;\\n }\\n\\n /// @return info - full deposit information of given account\\n function getDepositInfo(\\n address account\\n ) external view returns (DepositInfo memory info);\\n\\n /// @return the deposit (for gas payment) of the account\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * add to the deposit of the given account\\n */\\n function depositTo(address account) external payable;\\n\\n /**\\n * add to the account's stake - amount and delay\\n * any pending unstake is first cancelled.\\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\\n */\\n function addStake(uint32 _unstakeDelaySec) external payable;\\n\\n /**\\n * attempt to unlock the stake.\\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\\n */\\n function unlockStake() external;\\n\\n /**\\n * withdraw from the (unlocked) stake.\\n * must first call unlockStake and wait for the unstakeDelay to pass\\n * @param withdrawAddress the address to send withdrawn value.\\n */\\n function withdrawStake(address payable withdrawAddress) external;\\n\\n /**\\n * withdraw from the deposit.\\n * @param withdrawAddress the address to send withdrawn value.\\n * @param withdrawAmount the amount to withdraw.\\n */\\n function withdrawTo(\\n address payable withdrawAddress,\\n uint256 withdrawAmount\\n ) external;\\n}\\n\",\"keccak256\":\"0xadcea606c9b7aafe6645441f2154a60f271330b0eee5292a632aa71c1672d546\",\"license\":\"GPL-3.0-only\"},\"contracts/aa-4337/interfaces/UserOperation.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable no-inline-assembly */\\n\\nimport {calldataKeccak} from \\\"../core/Helpers.sol\\\";\\n\\n/**\\n * User Operation struct\\n * @param sender the sender account of this request.\\n * @param nonce unique value the sender uses to verify it is not a replay.\\n * @param initCode if set, the account contract will be created by this constructor/\\n * @param callData the method call to execute on this account.\\n * @param callGasLimit the gas limit passed to the callData method call.\\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\\n * @param maxFeePerGas same as EIP-1559 gas parameter.\\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\\n */\\nstruct UserOperation {\\n address sender;\\n uint256 nonce;\\n bytes initCode;\\n bytes callData;\\n uint256 callGasLimit;\\n uint256 verificationGasLimit;\\n uint256 preVerificationGas;\\n uint256 maxFeePerGas;\\n uint256 maxPriorityFeePerGas;\\n bytes paymasterAndData;\\n bytes signature;\\n}\\n\\n/**\\n * Utility functions helpful when working with UserOperation structs.\\n */\\nlibrary UserOperationLib {\\n function getSender(\\n UserOperation calldata userOp\\n ) internal pure returns (address) {\\n address data;\\n //read sender from userOp, which is first userOp member (saves 800 gas...)\\n assembly {\\n data := calldataload(userOp)\\n }\\n return address(uint160(data));\\n }\\n\\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\\n // pay above what he signed for.\\n function gasPrice(\\n UserOperation calldata userOp\\n ) internal view returns (uint256) {\\n unchecked {\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n if (maxFeePerGas == maxPriorityFeePerGas) {\\n //legacy mode (for networks that don't support basefee opcode)\\n return maxFeePerGas;\\n }\\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\\n }\\n }\\n\\n function pack(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes memory ret) {\\n address sender = getSender(userOp);\\n uint256 nonce = userOp.nonce;\\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\\n bytes32 hashCallData = calldataKeccak(userOp.callData);\\n uint256 callGasLimit = userOp.callGasLimit;\\n uint256 verificationGasLimit = userOp.verificationGasLimit;\\n uint256 preVerificationGas = userOp.preVerificationGas;\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\\n\\n return\\n abi.encode(\\n sender,\\n nonce,\\n hashInitCode,\\n hashCallData,\\n callGasLimit,\\n verificationGasLimit,\\n preVerificationGas,\\n maxFeePerGas,\\n maxPriorityFeePerGas,\\n hashPaymasterAndData\\n );\\n }\\n\\n function hash(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes32) {\\n return keccak256(pack(userOp));\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n}\\n\",\"keccak256\":\"0x2429f5cc546bdee08c7e63858d0dda8491eaa3ab5194df884dc948c1154d2834\",\"license\":\"GPL-3.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IStorageLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"./IDiamondLoupe.sol\\\";\\n\\n/**\\n * @title LoupeFromStorage Interface\\n * @dev Interface contract to function as a loupe facet directly attached to diamond storage of Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IStorageLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facetsFromStorage()\\n external\\n view\\n returns (IDiamondLoupe.Facet[] memory);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n function facetFunctionSelectorsFromStorage(\\n address _facet\\n ) external view returns (bytes4[] memory);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n function facetAddressesFromStorage()\\n external\\n view\\n returns (address[] memory);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n function facetAddressFromStorage(\\n bytes4 _functionSelector\\n ) external view returns (address);\\n}\\n\",\"keccak256\":\"0xdf5dc9c57319e9087628c9cf9404b4f75585b76d1c2f4f59ee796c933967ea5c\",\"license\":\"Apache-2.0\"},\"contracts/facets/interfaces/IAccountFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IEntryPoint} from \\\"../../aa-4337/interfaces/IEntryPoint.sol\\\";\\n\\n/**\\n * @title Account Facet Interface\\n * @dev Interface of module contract that provides the account features and init/unitialization of signer\\n * compatible with EIP-1271 & EIP-4337\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IAccountFacet {\\n event AccountInitialized(\\n IEntryPoint indexed entryPoint,\\n bytes indexed ownerPublicKey\\n );\\n // NOTE: Added Below Event\\n event VerificationSuccess(bytes32);\\n event VerificationFailure(bytes32);\\n\\n error AccountFacet__InitializationFailure();\\n error AccountFacet__RestrictionsFailure();\\n error AccountFacet__NonExistentVerificationFacet();\\n error AccountFacet__CallNotSuccessful();\\n error AccountFacet__InvalidArrayLength();\\n\\n function initialize(\\n address verificationFacet,\\n address anEntryPoint,\\n address facetRegistry,\\n address _defaultFallBack,\\n bytes calldata _ownerPublicKey\\n ) external returns (uint256);\\n\\n function execute(address dest, uint256 value, bytes calldata func) external;\\n\\n function executeBatch(\\n address[] calldata dest,\\n uint256[] calldata value,\\n bytes[] calldata func\\n ) external;\\n}\\n\",\"keccak256\":\"0x74a9cb0b8f2f4a5148e366a401a0354426c536c012c025025d07cc25a4cd5382\",\"license\":\"Apache-2.0\"},\"contracts/infrastructure/DefaultFallbackHandler.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IERC721Receiver} from \\\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\\\";\\nimport {IERC1155Receiver} from \\\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\\\";\\nimport {IERC777Recipient} from \\\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\\\";\\nimport {BaseAccount} from \\\"../aa-4337/core/BaseAccount.sol\\\";\\nimport {DefaultLibDiamond} from \\\"../libraries/DefaultLibDiamond.sol\\\";\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IAccountFacet} from \\\"../facets/interfaces/IAccountFacet.sol\\\";\\nimport {IStorageLoupe} from \\\"../facets/base/interfaces/IStorageLoupe.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\nimport {IERC677Receiver} from \\\"../interfaces/ERC/IERC677Receiver.sol\\\";\\nimport {IERC165} from \\\"../interfaces/ERC/IERC165.sol\\\";\\n\\n/**\\n * @title DefaultFallbackHandler\\n * @dev A default fallback handler for Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract DefaultFallbackHandler is IDiamondLoupe {\\n /**\\n * @notice Sets the middleware diamond for Barz wallet as a fallback handler\\n * @dev This contract is also a diamond that holds the default facets to reduce gas cost for wallet activation.\\n * Within the constructor this conducts diamond cut to initially setup the diamond. This is a non-upgradeable contract\\n * @param _diamondCutFacet Address if diamond cut facet\\n * @param _accountFacet Address account facet\\n * @param _tokenReceiverFacet Address of token receiver facet\\n * @param _diamondLoupeFacet Address of diamond loupe facet\\n */\\n constructor(\\n address _diamondCutFacet,\\n address _accountFacet,\\n address _tokenReceiverFacet,\\n address _diamondLoupeFacet\\n ) payable {\\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](4);\\n bytes4[] memory functionSelectors = new bytes4[](1);\\n functionSelectors[0] = IDiamondCut.diamondCut.selector;\\n\\n bytes4[] memory accountFunctionSelectors = new bytes4[](5);\\n accountFunctionSelectors[0] = IAccountFacet.execute.selector;\\n accountFunctionSelectors[1] = IAccountFacet.executeBatch.selector;\\n accountFunctionSelectors[2] = BaseAccount.validateUserOp.selector;\\n accountFunctionSelectors[3] = BaseAccount.getNonce.selector;\\n accountFunctionSelectors[4] = BaseAccount.entryPoint.selector;\\n\\n bytes4[] memory receiverFacetSelectors = new bytes4[](5);\\n receiverFacetSelectors[0] = IERC721Receiver.onERC721Received.selector;\\n receiverFacetSelectors[1] = IERC1155Receiver.onERC1155Received.selector;\\n receiverFacetSelectors[2] = IERC1155Receiver\\n .onERC1155BatchReceived\\n .selector;\\n receiverFacetSelectors[3] = IERC777Recipient.tokensReceived.selector;\\n receiverFacetSelectors[4] = IERC677Receiver.onTokenTransfer.selector;\\n\\n bytes4[] memory loupeFacetSelectors = new bytes4[](9);\\n loupeFacetSelectors[0] = IDiamondLoupe.facets.selector;\\n loupeFacetSelectors[1] = IDiamondLoupe.facetFunctionSelectors.selector;\\n loupeFacetSelectors[2] = IDiamondLoupe.facetAddresses.selector;\\n loupeFacetSelectors[3] = IDiamondLoupe.facetAddress.selector;\\n loupeFacetSelectors[4] = IERC165.supportsInterface.selector;\\n loupeFacetSelectors[5] = IStorageLoupe.facetsFromStorage.selector;\\n loupeFacetSelectors[6] = IStorageLoupe\\n .facetFunctionSelectorsFromStorage\\n .selector;\\n loupeFacetSelectors[7] = IStorageLoupe\\n .facetAddressesFromStorage\\n .selector;\\n loupeFacetSelectors[8] = IStorageLoupe.facetAddressFromStorage.selector;\\n\\n {\\n cut[0] = IDiamondCut.FacetCut({\\n facetAddress: _diamondCutFacet,\\n action: IDiamondCut.FacetCutAction.Add,\\n functionSelectors: functionSelectors\\n });\\n cut[1] = IDiamondCut.FacetCut({\\n facetAddress: _accountFacet,\\n action: IDiamondCut.FacetCutAction.Add,\\n functionSelectors: accountFunctionSelectors\\n });\\n cut[2] = IDiamondCut.FacetCut({\\n facetAddress: _tokenReceiverFacet,\\n action: IDiamondCut.FacetCutAction.Add,\\n functionSelectors: receiverFacetSelectors\\n });\\n cut[3] = IDiamondCut.FacetCut({\\n facetAddress: _diamondLoupeFacet,\\n action: IDiamondCut.FacetCutAction.Add,\\n functionSelectors: loupeFacetSelectors\\n });\\n\\n DefaultLibDiamond.diamondCut(cut, address(0), \\\"\\\");\\n }\\n }\\n\\n /**\\n * @notice Returns the facet information of call facets registered to this diamond.\\n * @return facets_ The facet struct array including all facet information\\n */\\n function facets() external view override returns (Facet[] memory facets_) {\\n DefaultLibDiamond.DiamondStorage storage ds = DefaultLibDiamond\\n .diamondStorage();\\n uint256 numFacets = ds.facetAddresses.length;\\n facets_ = new Facet[](numFacets);\\n for (uint256 i; i < numFacets; ) {\\n address facetAddress_ = ds.facetAddresses[i];\\n facets_[i].facetAddress = facetAddress_;\\n facets_[i].functionSelectors = ds\\n .facetFunctionSelectors[facetAddress_]\\n .functionSelectors;\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * @notice Gets all the function selectors provided by a facet.\\n * @param _facet The facet address.\\n * @return facetFunctionSelectors_\\n */\\n function facetFunctionSelectors(\\n address _facet\\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\\n facetFunctionSelectors_ = DefaultLibDiamond\\n .diamondStorage()\\n .facetFunctionSelectors[_facet]\\n .functionSelectors;\\n }\\n\\n /**\\n * @notice Get all the facet addresses used by a diamond.\\n * @return facetAddresses_\\n */\\n function facetAddresses()\\n external\\n view\\n override\\n returns (address[] memory facetAddresses_)\\n {\\n facetAddresses_ = DefaultLibDiamond.diamondStorage().facetAddresses;\\n }\\n\\n /** @notice Gets the facet that supports the given selector.\\n * @dev If facet is not found return address(0).\\n * @param _functionSelector The function selector.\\n * @return facetAddress_ The facet address.\\n */\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view override returns (address facetAddress_) {\\n facetAddress_ = DefaultLibDiamond\\n .diamondStorage()\\n .selectorToFacetAndPosition[_functionSelector]\\n .facetAddress;\\n }\\n}\\n\",\"keccak256\":\"0xa482fe778481e34e9fb3c4074231f8048437e934c0ca9a0c78e8e61d3a24470a\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.21;\\n\\ninterface IERC165 {\\n /// @notice Query if a contract implements an interface\\n /// @param interfaceId The interface identifier, as specified in ERC-165\\n /// @dev Interface identification is specified in ERC-165. This function\\n /// uses less than 30,000 gas.\\n /// @return `true` if the contract implements `interfaceID` and\\n /// `interfaceID` is not 0xffffffff, `false` otherwise\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xbb7f07e170898793c5535cc4b7e8944c4b990a631ac806d0b788e794abc788a3\",\"license\":\"MIT\"},\"contracts/interfaces/ERC/IERC677Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC677Receiver {\\n function onTokenTransfer(\\n address sender,\\n uint value,\\n bytes calldata data\\n ) external pure returns (bool);\\n}\\n\",\"keccak256\":\"0x4c1631cf45ea6daac0ec158c3edb9453099130b6b64f697004b83f95aa1f7350\",\"license\":\"Apache-2.0\"},\"contracts/libraries/DefaultLibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary DefaultLibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (\\n uint256 facetIndex;\\n facetIndex < _diamondCut.length;\\n facetIndex++\\n ) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(\\n address _facetAddress,\\n bytes4[] memory _functionSelectors\\n ) internal {\\n uint256 funcSelectorsLength = _functionSelectors.length;\\n require(\\n funcSelectorsLength > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _facetAddress != address(0),\\n \\\"LibDiamondCut: Add facet can't be address(0)\\\"\\n );\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (\\n uint256 selectorIndex;\\n selectorIndex < funcSelectorsLength;\\n selectorIndex++\\n ) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds\\n .selectorToFacetAndPosition[selector]\\n .facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(\\n address _facetAddress,\\n bytes4[] memory _functionSelectors\\n ) internal {\\n uint256 funcSelectorsLength = _functionSelectors.length;\\n require(\\n funcSelectorsLength > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _facetAddress != address(0),\\n \\\"LibDiamondCut: Replace facet can't be address(0)\\\"\\n );\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (\\n uint256 selectorIndex;\\n selectorIndex < funcSelectorsLength;\\n selectorIndex++\\n ) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds\\n .selectorToFacetAndPosition[selector]\\n .facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same facet\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(\\n address _facetAddress,\\n bytes4[] memory _functionSelectors\\n ) internal {\\n uint256 funcSelectorsLength = _functionSelectors.length;\\n require(\\n funcSelectorsLength > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(\\n _facetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n for (\\n uint256 selectorIndex;\\n selectorIndex < funcSelectorsLength;\\n selectorIndex++\\n ) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds\\n .selectorToFacetAndPosition[selector]\\n .facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(\\n DiamondStorage storage ds,\\n address _facetAddress\\n ) internal {\\n enforceHasContractCode(\\n _facetAddress,\\n \\\"LibDiamondCut: New facet has no code\\\"\\n );\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds\\n .facetAddresses\\n .length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds\\n .selectorToFacetAndPosition[_selector]\\n .functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(\\n _selector\\n );\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(\\n _facetAddress != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // an immutable function is a function defined directly in a diamond\\n require(\\n _facetAddress != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds\\n .selectorToFacetAndPosition[_selector]\\n .functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors[lastSelectorPosition];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n selectorPosition\\n ] = lastSelector;\\n ds\\n .selectorToFacetAndPosition[lastSelector]\\n .functionSelectorPosition = uint96(selectorPosition);\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[\\n lastFacetAddressPosition\\n ];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds\\n .facetFunctionSelectors[lastFacetAddress]\\n .facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds\\n .facetFunctionSelectors[_facetAddress]\\n .facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x1b08f332d62919288bb1f0d154ca4b85f4e167d2a06e680f8ec93dba65be3be1\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x6080604052604051620020183803806200201883398101604081905262000026916200156b565b60408051600480825260a08201909252600091816020015b604080516060808201835260008083526020830152918101919091528152602001906001900390816200003e5750506040805160018082528183019092529192506000919060208083019080368337019050509050631f931c1c60e01b81600081518110620000b157620000b1620015c8565b6001600160e01b03199290921660209283029190910182015260408051600580825260c08201909252600092909190820160a08036833701905050905063b61d27f660e01b816000815181106200010c576200010c620015c8565b6001600160e01b03199092166020928302919091019091015280516323f0ed1560e11b9082906001908110620001465762000146620015c8565b6001600160e01b0319909216602092830291909101909101528051633a871cdd60e01b9082906002908110620001805762000180620015c8565b6001600160e01b0319909216602092830291909101909101528051631a10fa5160e31b9082906003908110620001ba57620001ba620015c8565b6001600160e01b031990921660209283029190910190910152805163586b48ff60e11b9082906004908110620001f457620001f4620015c8565b6001600160e01b03199290921660209283029190910182015260408051600580825260c08201909252600092909190820160a08036833701905050905063150b7a0260e01b816000815181106200024f576200024f620015c8565b6001600160e01b031990921660209283029190910190910152805163f23a6e6160e01b9082906001908110620002895762000289620015c8565b6001600160e01b031990921660209283029190910190910152805163bc197c8160e01b9082906002908110620002c357620002c3620015c8565b6001600160e01b03199092166020928302919091019091015280516223de2960e01b9082906003908110620002fc57620002fc620015c8565b6001600160e01b0319909216602092830291909101909101528051635260769b60e11b9082906004908110620003365762000336620015c8565b6001600160e01b0319929092166020928302919091018201526040805160098082526101408201909252600092909190820161012080368337019050509050637a0ed62760e01b81600081518110620003935762000393620015c8565b6001600160e01b03199092166020928302919091019091015280516356fe50af60e11b9082906001908110620003cd57620003cd620015c8565b6001600160e01b03199092166020928302919091019091015280516314bbdacb60e21b9082906002908110620004075762000407620015c8565b6001600160e01b03199092166020928302919091019091015280516366ffd66360e11b9082906003908110620004415762000441620015c8565b6001600160e01b03199092166020928302919091019091015280516301ffc9a760e01b90829060049081106200047b576200047b620015c8565b6001600160e01b031990921660209283029190910190910152805163f9796ccf60e01b9082906005908110620004b557620004b5620015c8565b6001600160e01b031990921660209283029190910190910152805162d2a81160e11b9082906006908110620004ee57620004ee620015c8565b6001600160e01b031990921660209283029190910190910152805163d42139a960e01b9082906007908110620005285762000528620015c8565b6001600160e01b03199092166020928302919091019091015280516371d17b7f60e11b9082906008908110620005625762000562620015c8565b6001600160e01b031990921660209283029190910182015260408051606081019091526001600160a01b038b168152908101600081526020018581525085600081518110620005b557620005b5620015c8565b60200260200101819052506040518060600160405280896001600160a01b0316815260200160006002811115620005f057620005f0620015de565b815260200184815250856001815181106200060f576200060f620015c8565b60200260200101819052506040518060600160405280886001600160a01b03168152602001600060028111156200064a576200064a620015de565b81526020018381525085600281518110620006695762000669620015c8565b60200260200101819052506040518060600160405280876001600160a01b0316815260200160006002811115620006a457620006a4620015de565b81526020018281525085600381518110620006c357620006c3620015c8565b6020026020010181905250620006f1856000604051806020016040528060008152506200070060201b60201c565b5050505050505050506200184c565b60005b83518110156200090c576000848281518110620007245762000724620015c8565b602002602001015160200151905060006002811115620007485762000748620015de565b8160028111156200075d576200075d620015de565b03620007bb57620007b58583815181106200077c576200077c620015c8565b6020026020010151600001518684815181106200079d576200079d620015c8565b6020026020010151604001516200095b60201b60201c565b620008f6565b6001816002811115620007d257620007d2620015de565b036200082a57620007b5858381518110620007f157620007f1620015c8565b602002602001015160000151868481518110620008125762000812620015c8565b60200260200101516040015162000bf760201b60201c565b6002816002811115620008415762000841620015de565b036200089957620007b5858381518110620008605762000860620015c8565b602002602001015160000151868481518110620008815762000881620015c8565b60200260200101516040015162000ea160201b60201c565b60405162461bcd60e51b815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f727265637420466163657443756044820152663a20b1ba34b7b760c91b60648201526084015b60405180910390fd5b508062000903816200160a565b91505062000703565b507f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb67383838360405162000942939291906200167a565b60405180910390a162000956828262001005565b505050565b805180620009af5760405162461bcd60e51b815260206004820152602b602482015260008051602062001ff883398151915260448201526a1858d95d081d1bc818dd5d60aa1b6064820152608401620008ed565b60008051602062001f8c8339815191526001600160a01b03841662000a2c5760405162461bcd60e51b815260206004820152602c60248201527f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260448201526b65206164647265737328302960a01b6064820152608401620008ed565b6001600160a01b0384166000908152600182016020526040812054906001600160601b038216900362000a655762000a658286620010dd565b60005b8381101562000bef57600085828151811062000a885762000a88620015c8565b6020908102919091018101516001600160e01b031981166000908152918690526040909120549091506001600160a01b0316801562000b305760405162461bcd60e51b815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c72656164792065786973747300000000000000000000006064820152608401620008ed565b6001600160e01b0319821660008181526020878152604080832080546001600160a01b03908116600160a01b6001600160601b038c16021782558d168085526001808c0185529285208054938401815585528385206008840401805463ffffffff60079095166004026101000a948502191660e08a901c94909402939093179092559390925287905281546001600160a01b0319161790558362000bd48162001781565b9450505050808062000be6906200160a565b91505062000a68565b505050505050565b80518062000c4b5760405162461bcd60e51b815260206004820152602b602482015260008051602062001ff883398151915260448201526a1858d95d081d1bc818dd5d60aa1b6064820152608401620008ed565b60008051602062001f8c8339815191526001600160a01b03841662000ccc5760405162461bcd60e51b815260206004820152603060248201527f4c69624469616d6f6e644375743a205265706c6163652066616365742063616e60448201526f2774206265206164647265737328302960801b6064820152608401620008ed565b6001600160a01b0384166000908152600182016020526040812054906001600160601b038216900362000d055762000d058286620010dd565b60005b8381101562000bef57600085828151811062000d285762000d28620015c8565b6020908102919091018101516001600160e01b031981166000908152918690526040909120549091506001600160a01b03908116908816810362000dd55760405162461bcd60e51b815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d6520666163657400000000000000000000006064820152608401620008ed565b62000de28582846200114a565b6001600160e01b0319821660008181526020878152604080832080546001600160a01b03908116600160a01b6001600160601b038c16021782558d168085526001808c0185529285208054938401815585528385206008840401805463ffffffff60079095166004026101000a948502191660e08a901c94909402939093179092559390925287905281546001600160a01b0319161790558362000e868162001781565b9450505050808062000e98906200160a565b91505062000d08565b80518062000ef55760405162461bcd60e51b815260206004820152602b602482015260008051602062001ff883398151915260448201526a1858d95d081d1bc818dd5d60aa1b6064820152608401620008ed565b60008051602062001f8c8339815191526001600160a01b0384161562000f845760405162461bcd60e51b815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d7573742062652061646472657373283029000000000000000000006064820152608401620008ed565b60005b8281101562000ffe57600084828151811062000fa75762000fa7620015c8565b6020908102919091018101516001600160e01b031981166000908152918590526040909120549091506001600160a01b031662000fe68482846200114a565b5050808062000ff5906200160a565b91505062000f87565b5050505050565b6001600160a01b03821662001018575050565b6200103d8260405180606001604052806028815260200162001fac602891396200152a565b600080836001600160a01b0316836040516200105a9190620017b2565b600060405180830381855af49150503d806000811462001097576040519150601f19603f3d011682016040523d82523d6000602084013e6200109c565b606091505b509150915081620010d757805115620010b85780518082602001fd5b838360405163192105d760e01b8152600401620008ed929190620017d0565b50505050565b620011028160405180606001604052806024815260200162001fd4602491396200152a565b6002820180546001600160a01b0390921660008181526001948501602090815260408220860185905594840183559182529290200180546001600160a01b0319169091179055565b6001600160a01b038216620011c85760405162461bcd60e51b815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608401620008ed565b306001600160a01b03831603620012395760405162461bcd60e51b815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201526d3a30b1363290333ab731ba34b7b760911b6064820152608401620008ed565b6001600160e01b03198116600090815260208481526040808320546001600160a01b0386168452600180880190935290832054600160a01b9091046001600160601b031692916200128a91620017fe565b905080821462001383576001600160a01b03841660009081526001860160205260408120805483908110620012c357620012c3620015c8565b600091825260208083206008830401546001600160a01b038916845260018a019091526040909220805460079092166004026101000a90920460e01b925082919085908110620013175762001317620015c8565b600091825260208083206008830401805463ffffffff60079094166004026101000a938402191660e09590951c929092029390931790556001600160e01b03199290921682528690526040902080546001600160a01b0316600160a01b6001600160601b038516021790555b6001600160a01b03841660009081526001860160205260409020805480620013af57620013af6200181a565b60008281526020808220600860001990940193840401805463ffffffff600460078716026101000a0219169055919092556001600160e01b0319851682528690526040812081905581900362000ffe5760028501546000906200141590600190620017fe565b6001600160a01b0386166000908152600180890160205260409091200154909150808214620014cb576000876002018381548110620014585762001458620015c8565b6000918252602090912001546002890180546001600160a01b0390921692508291849081106200148c576200148c620015c8565b600091825260208083209190910180546001600160a01b0319166001600160a01b03948516179055929091168152600189810190925260409020018190555b86600201805480620014e157620014e16200181a565b60008281526020808220830160001990810180546001600160a01b03191690559092019092556001600160a01b0388168252600189810190915260408220015550505050505050565b813b8181620010d75760405162461bcd60e51b8152600401620008ed919062001830565b80516001600160a01b03811681146200156657600080fd5b919050565b600080600080608085870312156200158257600080fd5b6200158d856200154e565b93506200159d602086016200154e565b9250620015ad604086016200154e565b9150620015bd606086016200154e565b905092959194509250565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016200161f576200161f620015f4565b5060010190565b60005b838110156200164357818101518382015260200162001629565b50506000910152565b600081518084526200166681602086016020860162001626565b601f01601f19169290920160200192915050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b848110156200174f57898403607f19018652815180516001600160a01b03168552838101518986019060038110620016eb57634e487b7160e01b600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b80831015620017395783516001600160e01b03191682529286019260019290920191908601906200170d565b50978501979550505090820190600101620016a3565b50506001600160a01b038a169088015286810360408801526200177381896200164c565b9a9950505050505050505050565b60006001600160601b038281166002600160601b03198101620017a857620017a8620015f4565b6001019392505050565b60008251620017c681846020870162001626565b9190910192915050565b6001600160a01b0383168152604060208201819052600090620017f6908301846200164c565b949350505050565b81810381811115620018145762001814620015f4565b92915050565b634e487b7160e01b600052603160045260246000fd5b6020815260006200184560208301846200164c565b9392505050565b610730806200185c6000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806352ef6b2c146100515780637a0ed6271461006f578063adfca15e14610084578063cdffacc6146100a4575b600080fd5b610059610140565b60405161006691906104ab565b60405180910390f35b6100776101d1565b6040516100669190610562565b61009761009236600461060a565b6103d1565b6040516100669190610647565b61011b6100b236600461065a565b7fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610066565b60607f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6002018054806020026020016040519081016040528092919081815260200182805480156101c757602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161019c575b5050505050905090565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f908067ffffffffffffffff8111156102315761023161069c565b60405190808252806020026020018201604052801561027757816020015b60408051808201909152600081526060602082015281526020019060019003908161024f5790505b50925060005b818110156103cb57600083600201828154811061029c5761029c6106cb565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050808583815181106102dc576102dc6106cb565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff928316905290821660009081526001860182526040908190208054825181850281018501909352808352919290919083018282801561039d57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161034a5790505b50505050508583815181106103b4576103b46106cb565b60209081029190910181015101525060010161027d565b50505090565b73ffffffffffffffffffffffffffffffffffffffff811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4920602090815260409182902080548351818402810184019094528084526060939283018282801561049f57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161044c5790505b50505050509050919050565b6020808252825182820181905260009190848201906040850190845b818110156104f957835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016104c7565b50909695505050505050565b600081518084526020808501945080840160005b838110156105575781517fffffffff000000000000000000000000000000000000000000000000000000001687529582019590820190600101610519565b509495945050505050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b838110156105fc578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00185528151805173ffffffffffffffffffffffffffffffffffffffff1684528701518784018790526105e987850182610505565b9588019593505090860190600101610589565b509098975050505050505050565b60006020828403121561061c57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461064057600080fd5b9392505050565b6020815260006106406020830184610505565b60006020828403121561066c57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461064057600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea264697066735822122024a872696a5ad50024326567061c50adea63ff0d49edf0ac60339459d33d571664736f6c63430008150033183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f4c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a204e657720666163657420686173206e6f20636f64654c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e2066", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806352ef6b2c146100515780637a0ed6271461006f578063adfca15e14610084578063cdffacc6146100a4575b600080fd5b610059610140565b60405161006691906104ab565b60405180910390f35b6100776101d1565b6040516100669190610562565b61009761009236600461060a565b6103d1565b6040516100669190610647565b61011b6100b236600461065a565b7fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610066565b60607f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6002018054806020026020016040519081016040528092919081815260200182805480156101c757602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161019c575b5050505050905090565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f908067ffffffffffffffff8111156102315761023161069c565b60405190808252806020026020018201604052801561027757816020015b60408051808201909152600081526060602082015281526020019060019003908161024f5790505b50925060005b818110156103cb57600083600201828154811061029c5761029c6106cb565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050808583815181106102dc576102dc6106cb565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff928316905290821660009081526001860182526040908190208054825181850281018501909352808352919290919083018282801561039d57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161034a5790505b50505050508583815181106103b4576103b46106cb565b60209081029190910181015101525060010161027d565b50505090565b73ffffffffffffffffffffffffffffffffffffffff811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4920602090815260409182902080548351818402810184019094528084526060939283018282801561049f57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161044c5790505b50505050509050919050565b6020808252825182820181905260009190848201906040850190845b818110156104f957835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016104c7565b50909695505050505050565b600081518084526020808501945080840160005b838110156105575781517fffffffff000000000000000000000000000000000000000000000000000000001687529582019590820190600101610519565b509495945050505050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b838110156105fc578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00185528151805173ffffffffffffffffffffffffffffffffffffffff1684528701518784018790526105e987850182610505565b9588019593505090860190600101610589565b509098975050505050505050565b60006020828403121561061c57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461064057600080fd5b9392505050565b6020815260006106406020830184610505565b60006020828403121561066c57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461064057600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea264697066735822122024a872696a5ad50024326567061c50adea63ff0d49edf0ac60339459d33d571664736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "A default fallback handler for Barz", + "kind": "dev", + "methods": { + "constructor": { + "details": "This contract is also a diamond that holds the default facets to reduce gas cost for wallet activation. Within the constructor this conducts diamond cut to initially setup the diamond. This is a non-upgradeable contract", + "params": { + "_accountFacet": "Address account facet", + "_diamondCutFacet": "Address if diamond cut facet", + "_diamondLoupeFacet": "Address of diamond loupe facet", + "_tokenReceiverFacet": "Address of token receiver facet" + } + }, + "facetAddress(bytes4)": { + "details": "If facet is not found return address(0).", + "params": { + "_functionSelector": "The function selector." + }, + "returns": { + "facetAddress_": "The facet address." + } + }, + "facetAddresses()": { + "returns": { + "facetAddresses_": "facetAddresses_" + } + }, + "facetFunctionSelectors(address)": { + "params": { + "_facet": "The facet address." + }, + "returns": { + "facetFunctionSelectors_": "facetFunctionSelectors_" + } + }, + "facets()": { + "returns": { + "facets_": "The facet struct array including all facet information" + } + } + }, + "title": "DefaultFallbackHandler", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "constructor": { + "notice": "Sets the middleware diamond for Barz wallet as a fallback handler" + }, + "facetAddress(bytes4)": { + "notice": "Gets the facet that supports the given selector." + }, + "facetAddresses()": { + "notice": "Get all the facet addresses used by a diamond." + }, + "facetFunctionSelectors(address)": { + "notice": "Gets all the function selectors provided by a facet." + }, + "facets()": { + "notice": "Returns the facet information of call facets registered to this diamond." + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/mantle/DiamondCutFacet.json b/deployments/mantle/DiamondCutFacet.json new file mode 100644 index 0000000..3663073 --- /dev/null +++ b/deployments/mantle/DiamondCutFacet.json @@ -0,0 +1,856 @@ +{ + "address": "0x0B9504140771C3688Ff041917192277D2f52E1e0", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_securityManager", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "CallerNotGuardian", + "type": "error" + }, + { + "inputs": [], + "name": "CallerNotGuardianOrOwner", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__CannotRevokeUnapproved", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__DuplicateApproval", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InsufficientApprovers", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidApprovalValidationPeriod", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidApprover", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidApproverSignature", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidArrayLength", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidInitAddress", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidRouteWithGuardian", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidRouteWithoutGuardian", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__LackOfOwnerApproval", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__OwnerAlreadyApproved", + "type": "error" + }, + { + "inputs": [], + "name": "DuplicateApprover", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_initializationContractAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "InitializationFunctionReverted", + "type": "error" + }, + { + "inputs": [], + "name": "UnregisteredFacetAndSelectors", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroApproverLength", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "indexed": false, + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "DiamondCut", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "diamondCut", + "type": "tuple[]" + } + ], + "name": "DiamondCutApprovalRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "diamondCut", + "type": "tuple[]" + } + ], + "name": "DiamondCutApproved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + }, + { + "indexed": false, + "internalType": "bool", + "name": "_lag", + "type": "bool" + } + ], + "name": "SupportsInterfaceUpdated", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_diamondCutHash", + "type": "bytes32" + }, + { + "internalType": "address[]", + "name": "_approvers", + "type": "address[]" + } + ], + "name": "_checkDuplicateOnChainApprover", + "outputs": [], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + } + ], + "name": "approveDiamondCut", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "diamondCut", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "internalType": "address[]", + "name": "_approvers", + "type": "address[]" + }, + { + "internalType": "bytes[]", + "name": "_signatures", + "type": "bytes[]" + } + ], + "name": "diamondCutWithGuardian", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_diamondCutHash", + "type": "bytes32" + } + ], + "name": "getDiamondCutApprovalCountWithTimeValidity", + "outputs": [ + { + "internalType": "uint256", + "name": "approvalCount", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + } + ], + "name": "getDiamondCutHash", + "outputs": [ + { + "internalType": "bytes32", + "name": "cutHash", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getDiamondCutNonce", + "outputs": [ + { + "internalType": "uint128", + "name": "cutNonce", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_diamondCutHash", + "type": "bytes32" + } + ], + "name": "getOwnerCutApprovalWithTimeValidity", + "outputs": [ + { + "internalType": "bool", + "name": "isApprovedByOwner", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_diamondCutHash", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "_approver", + "type": "address" + } + ], + "name": "isCutApproved", + "outputs": [ + { + "internalType": "bool", + "name": "isApproved", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + } + ], + "name": "revokeDiamondCutApproval", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "securityManager", + "outputs": [ + { + "internalType": "contract ISecurityManager", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_interfaceId", + "type": "bytes4" + }, + { + "internalType": "bool", + "name": "_flag", + "type": "bool" + } + ], + "name": "updateSupportsInterface", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0xcdd66ad9d2781b812b8fdee06c52cbc152e6c2492cd50330dba085da4db8bfec", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xb33654322bD3803821031624f5922eb14C9b8d18", + "contractAddress": null, + "transactionIndex": 2, + "gasUsed": "20515932406", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x999d4f4118b7b4e0f602af7ebe27b3fe7b598058bba7d760ed8168ab4aca2c0c", + "transactionHash": "0xcdd66ad9d2781b812b8fdee06c52cbc152e6c2492cd50330dba085da4db8bfec", + "logs": [], + "blockNumber": 61655181, + "cumulativeGasUsed": "21450080539", + "status": 1, + "byzantium": true + }, + "args": [ + "0xcBe266adbfd7CB32988128e7f37b7c8b3C5521A8" + ], + "numDeployments": 1, + "solcInputHash": "ad34345aa73d96f52b3e14df983b6b29", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_securityManager\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"CallerNotGuardian\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallerNotGuardianOrOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__CannotRevokeUnapproved\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__DuplicateApproval\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InsufficientApprovers\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidApprovalValidationPeriod\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidApprover\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidApproverSignature\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidArrayLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidInitAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidRouteWithGuardian\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidRouteWithoutGuardian\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__LackOfOwnerApproval\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__OwnerAlreadyApproved\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateApprover\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_initializationContractAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"InitializationFunctionReverted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnregisteredFacetAndSelectors\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroApproverLength\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"DiamondCut\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"diamondCut\",\"type\":\"tuple[]\"}],\"name\":\"DiamondCutApprovalRevoked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"diamondCut\",\"type\":\"tuple[]\"}],\"name\":\"DiamondCutApproved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"_lag\",\"type\":\"bool\"}],\"name\":\"SupportsInterfaceUpdated\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_diamondCutHash\",\"type\":\"bytes32\"},{\"internalType\":\"address[]\",\"name\":\"_approvers\",\"type\":\"address[]\"}],\"name\":\"_checkDuplicateOnChainApprover\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"}],\"name\":\"approveDiamondCut\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"diamondCut\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"internalType\":\"address[]\",\"name\":\"_approvers\",\"type\":\"address[]\"},{\"internalType\":\"bytes[]\",\"name\":\"_signatures\",\"type\":\"bytes[]\"}],\"name\":\"diamondCutWithGuardian\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_diamondCutHash\",\"type\":\"bytes32\"}],\"name\":\"getDiamondCutApprovalCountWithTimeValidity\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"approvalCount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"}],\"name\":\"getDiamondCutHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"cutHash\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDiamondCutNonce\",\"outputs\":[{\"internalType\":\"uint128\",\"name\":\"cutNonce\",\"type\":\"uint128\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_diamondCutHash\",\"type\":\"bytes32\"}],\"name\":\"getOwnerCutApprovalWithTimeValidity\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isApprovedByOwner\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_diamondCutHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"_approver\",\"type\":\"address\"}],\"name\":\"isCutApproved\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isApproved\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"}],\"name\":\"revokeDiamondCutApproval\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"securityManager\",\"outputs\":[{\"internalType\":\"contract ISecurityManager\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_interfaceId\",\"type\":\"bytes4\"},{\"internalType\":\"bool\",\"name\":\"_flag\",\"type\":\"bool\"}],\"name\":\"updateSupportsInterface\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"Responsible for adding/removing/replace facets in Barz\",\"kind\":\"dev\",\"methods\":{\"_checkDuplicateOnChainApprover(bytes32,address[])\":{\"params\":{\"_approvers\":\"List of approver addresses\",\"_diamondCutHash\":\"Hash of diamondCut information including the facet addresses and function selectors\"}},\"approveDiamondCut((address,uint8,bytes4[])[])\":{\"params\":{\"_diamondCut\":\"Contains the facet addresses and function selectors\"}},\"constructor\":{\"params\":{\"_securityManager\":\"Security Manager contract that holds the security related variables for all wallets\"}},\"diamondCut((address,uint8,bytes4[])[],address,bytes)\":{\"params\":{\"_diamondCut\":\"Contains the facet addresses and function selectors\",\"_init\":\"The address of the contract or facet to execute _calldata. It's prohibited in Barz\"}},\"diamondCutWithGuardian((address,uint8,bytes4[])[],address[],bytes[])\":{\"params\":{\"_approvers\":\"Guardian or owner address that approves the diamond cut\",\"_diamondCut\":\"Contains the facet addresses and function selectors\",\"_signatures\":\"Signature of Guardians or owner that approves the diamond cut\"}},\"getDiamondCutApprovalCountWithTimeValidity(bytes32)\":{\"params\":{\"_diamondCutHash\":\"Hash of diamondCut information including the facet addresses and function selectors\"}},\"getDiamondCutHash((address,uint8,bytes4[])[])\":{\"params\":{\"_diamondCut\":\"Contains the facet addresses and function selectors\"},\"returns\":{\"cutHash\":\"Diamond Cut Hash\"}},\"getDiamondCutNonce()\":{\"details\":\"This method fetches the nonce from diamond cut storage\",\"returns\":{\"cutNonce\":\"Nonce of diamond cut to protect from reply attacks\"}},\"getOwnerCutApprovalWithTimeValidity(bytes32)\":{\"params\":{\"_diamondCutHash\":\"Hash of diamondCut information including the facet addresses and function selectors\"},\"returns\":{\"isApprovedByOwner\":\"Bool value showing if the owner approved the cut\"}},\"isCutApproved(bytes32,address)\":{\"params\":{\"_approver\":\"Address of approver\",\"_diamondCutHash\":\"Hash of diamondCut information including the facet addresses and function selectors\"},\"returns\":{\"isApproved\":\"Bool value showing if the approver approved the cut\"}},\"revokeDiamondCutApproval((address,uint8,bytes4[])[])\":{\"params\":{\"_diamondCut\":\"Contains the facet addresses and function selectors\"}},\"updateSupportsInterface(bytes4,bool)\":{\"params\":{\"_flag\":\"Bool value to update the mapping of the given interface ID\",\"_interfaceId\":\"InterfaceID to update the mapping\"}}},\"title\":\"DiamondCut Facet\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"_checkDuplicateOnChainApprover(bytes32,address[])\":{\"notice\":\"Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval Approvers who approved on-chain should not be included in the off-chain approval\"},\"approveDiamondCut((address,uint8,bytes4[])[])\":{\"notice\":\"Approves diamond cut. This can only be called directly from guardian or owner\"},\"constructor\":{\"notice\":\"This constructor sets the Security Manager address which is an immutable variable. Immutable variables do not impact the storage of diamond\"},\"diamondCut((address,uint8,bytes4[])[],address,bytes)\":{\"notice\":\"Add/replace/remove any number of functions and optionally execute a function with delegatecall when guardians don't exist\"},\"diamondCutWithGuardian((address,uint8,bytes4[])[],address[],bytes[])\":{\"notice\":\"Add/replace/remove any number of functions and optionally execute a function with delegatecall when guardians exist\"},\"getDiamondCutApprovalCountWithTimeValidity(bytes32)\":{\"notice\":\"Gets the number of approvals of diamond cut from guardians\"},\"getDiamondCutHash((address,uint8,bytes4[])[])\":{\"notice\":\"Returns the diamond cut hash. This function ensures that this hash is safe from replay attack by including salt, address, chainId, and nonce, etc.\"},\"getDiamondCutNonce()\":{\"notice\":\"Returns the diamond cut nonce of this wallet\"},\"getOwnerCutApprovalWithTimeValidity(bytes32)\":{\"notice\":\"Returns if the owner has approved the diamond cut\"},\"isCutApproved(bytes32,address)\":{\"notice\":\"Returns if the given approver has approved the diamond cut\"},\"revokeDiamondCutApproval((address,uint8,bytes4[])[])\":{\"notice\":\"Revokes the approval of diamond cut. This can only be called directly from guardian or owner\"},\"updateSupportsInterface(bytes4,bool)\":{\"notice\":\"Updates the flag for the interfaceId\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/base/DiamondCutFacet.sol\":\"DiamondCutFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/interfaces/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC1271 standard signature validation method for\\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC1271 {\\n /**\\n * @dev Should return whether the signature provided is valid for the provided data\\n * @param hash Hash of the data to be signed\\n * @param signature Signature byte array associated with _data\\n */\\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\\n}\\n\",\"keccak256\":\"0x0705a4b1b86d7b0bd8432118f226ba139c44b9dcaba0a6eafba2dd7d0639c544\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./math/Math.sol\\\";\\nimport \\\"./math/SignedMath.sol\\\";\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n uint256 length = Math.log10(value) + 1;\\n string memory buffer = new string(length);\\n uint256 ptr;\\n /// @solidity memory-safe-assembly\\n assembly {\\n ptr := add(buffer, add(32, length))\\n }\\n while (true) {\\n ptr--;\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\\n }\\n value /= 10;\\n if (value == 0) break;\\n }\\n return buffer;\\n }\\n }\\n\\n /**\\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\\n */\\n function toString(int256 value) internal pure returns (string memory) {\\n return string(abi.encodePacked(value < 0 ? \\\"-\\\" : \\\"\\\", toString(SignedMath.abs(value))));\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n return toHexString(value, Math.log256(value) + 1);\\n }\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n\\n /**\\n * @dev Returns true if the two strings are equal.\\n */\\n function equal(string memory a, string memory b) internal pure returns (bool) {\\n return keccak256(bytes(a)) == keccak256(bytes(b));\\n }\\n}\\n\",\"keccak256\":\"0x3088eb2868e8d13d89d16670b5f8612c4ab9ff8956272837d8e90106c59c14a0\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Strings.sol\\\";\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSA {\\n enum RecoverError {\\n NoError,\\n InvalidSignature,\\n InvalidSignatureLength,\\n InvalidSignatureS,\\n InvalidSignatureV // Deprecated in v4.8\\n }\\n\\n function _throwError(RecoverError error) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert(\\\"ECDSA: invalid signature\\\");\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert(\\\"ECDSA: invalid signature length\\\");\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert(\\\"ECDSA: invalid signature 's' value\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature` or error string. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n *\\n * Documentation for signature generation:\\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n return tryRecover(hash, v, r, s);\\n } else {\\n return (address(0), RecoverError.InvalidSignatureLength);\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature`. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, signature);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\\n uint8 v = uint8((uint256(vs) >> 255) + 27);\\n return tryRecover(hash, v, r, s);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n *\\n * _Available since v4.2._\\n */\\n function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\\n // the valid range for s in (301): 0 < s < secp256k1n \\u00f7 2 + 1, and for v in (302): v \\u2208 {27, 28}. Most\\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\\n //\\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\\n // these malleable signatures as well.\\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n return (address(0), RecoverError.InvalidSignatureS);\\n }\\n\\n // If the signature is valid (and not malleable), return the signer address\\n address signer = ecrecover(hash, v, r, s);\\n if (signer == address(0)) {\\n return (address(0), RecoverError.InvalidSignature);\\n }\\n\\n return (signer, RecoverError.NoError);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore(0x00, \\\"\\\\x19Ethereum Signed Message:\\\\n32\\\")\\n mstore(0x1c, hash)\\n message := keccak256(0x00, 0x3c)\\n }\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from `s`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n\\\", Strings.toString(s.length), s));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Typed Data, created from a\\n * `domainSeparator` and a `structHash`. This produces hash corresponding\\n * to the one signed with the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n * JSON-RPC method as part of EIP-712.\\n *\\n * See {recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n let ptr := mload(0x40)\\n mstore(ptr, \\\"\\\\x19\\\\x01\\\")\\n mstore(add(ptr, 0x02), domainSeparator)\\n mstore(add(ptr, 0x22), structHash)\\n data := keccak256(ptr, 0x42)\\n }\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Data with intended validator, created from a\\n * `validator` and `data` according to the version 0 of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x00\\\", validator, data));\\n }\\n}\\n\",\"keccak256\":\"0x809bc3edb4bcbef8263fa616c1b60ee0004b50a8a1bfa164d8f57fd31f520c58\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/SignatureChecker.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./ECDSA.sol\\\";\\nimport \\\"../../interfaces/IERC1271.sol\\\";\\n\\n/**\\n * @dev Signature verification helper that can be used instead of `ECDSA.recover` to seamlessly support both ECDSA\\n * signatures from externally owned accounts (EOAs) as well as ERC1271 signatures from smart contract wallets like\\n * Argent and Gnosis Safe.\\n *\\n * _Available since v4.1._\\n */\\nlibrary SignatureChecker {\\n /**\\n * @dev Checks if a signature is valid for a given signer and data hash. If the signer is a smart contract, the\\n * signature is validated against that smart contract using ERC1271, otherwise it's validated using `ECDSA.recover`.\\n *\\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\\n */\\n function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature) internal view returns (bool) {\\n (address recovered, ECDSA.RecoverError error) = ECDSA.tryRecover(hash, signature);\\n return\\n (error == ECDSA.RecoverError.NoError && recovered == signer) ||\\n isValidERC1271SignatureNow(signer, hash, signature);\\n }\\n\\n /**\\n * @dev Checks if a signature is valid for a given signer and data hash. The signature is validated\\n * against the signer smart contract using ERC1271.\\n *\\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\\n */\\n function isValidERC1271SignatureNow(\\n address signer,\\n bytes32 hash,\\n bytes memory signature\\n ) internal view returns (bool) {\\n (bool success, bytes memory result) = signer.staticcall(\\n abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, signature)\\n );\\n return (success &&\\n result.length >= 32 &&\\n abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector));\\n }\\n}\\n\",\"keccak256\":\"0x3af3ca86df39aac39a0514c84459d691434a108d2151c8ce9d69f32e315cab80\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n enum Rounding {\\n Down, // Toward negative infinity\\n Up, // Toward infinity\\n Zero // Toward zero\\n }\\n\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow.\\n return (a & b) + (a ^ b) / 2;\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a == 0 ? 0 : (a - 1) / b + 1;\\n }\\n\\n /**\\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\\n * with further edits by Uniswap Labs also under MIT license.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\\n unchecked {\\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2^256 + prod0.\\n uint256 prod0; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division.\\n if (prod1 == 0) {\\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\\n // The surrounding unchecked block does not change this fact.\\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\\n return prod0 / denominator;\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n require(denominator > prod1, \\\"Math: mulDiv overflow\\\");\\n\\n ///////////////////////////////////////////////\\n // 512 by 256 division.\\n ///////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0].\\n uint256 remainder;\\n assembly {\\n // Compute remainder using mulmod.\\n remainder := mulmod(x, y, denominator)\\n\\n // Subtract 256 bit number from 512 bit number.\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\\n // See https://cs.stackexchange.com/q/138556/92363.\\n\\n // Does not overflow because the denominator cannot be zero at this stage in the function.\\n uint256 twos = denominator & (~denominator + 1);\\n assembly {\\n // Divide denominator by twos.\\n denominator := div(denominator, twos)\\n\\n // Divide [prod1 prod0] by twos.\\n prod0 := div(prod0, twos)\\n\\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\\n twos := add(div(sub(0, twos), twos), 1)\\n }\\n\\n // Shift in bits from prod1 into prod0.\\n prod0 |= prod1 * twos;\\n\\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\\n // four bits. That is, denominator * inv = 1 mod 2^4.\\n uint256 inverse = (3 * denominator) ^ 2;\\n\\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\\n // in modular arithmetic, doubling the correct bits in each step.\\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\\n\\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inverse;\\n return result;\\n }\\n }\\n\\n /**\\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\\n uint256 result = mulDiv(x, y, denominator);\\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\\n result += 1;\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\\n *\\n * Inspired by Henry S. Warren, Jr.'s \\\"Hacker's Delight\\\" (Chapter 11).\\n */\\n function sqrt(uint256 a) internal pure returns (uint256) {\\n if (a == 0) {\\n return 0;\\n }\\n\\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\\n //\\n // We know that the \\\"msb\\\" (most significant bit) of our target number `a` is a power of 2 such that we have\\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\\n //\\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\\n // \\u2192 `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\\n // \\u2192 `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\\n //\\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\\n uint256 result = 1 << (log2(a) >> 1);\\n\\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\\n // into the expected uint128 result.\\n unchecked {\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n return min(result, a / result);\\n }\\n }\\n\\n /**\\n * @notice Calculates sqrt(a), following the selected rounding direction.\\n */\\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = sqrt(a);\\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 2, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 128;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 64;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 32;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 16;\\n }\\n if (value >> 8 > 0) {\\n value >>= 8;\\n result += 8;\\n }\\n if (value >> 4 > 0) {\\n value >>= 4;\\n result += 4;\\n }\\n if (value >> 2 > 0) {\\n value >>= 2;\\n result += 2;\\n }\\n if (value >> 1 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log2(value);\\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 10, rounded down, of a positive value.\\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 + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 256, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n *\\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\\n */\\n function log256(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 16;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 8;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 4;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 2;\\n }\\n if (value >> 8 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log256(value);\\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe4455ac1eb7fc497bb7402579e7b4d64d928b846fce7d2b6fde06d366f21c2b3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\\n * checks.\\n *\\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\\n * easily result in undesired exploitation or bugs, since developers usually\\n * assume that overflows raise errors. `SafeCast` restores this intuition by\\n * reverting the transaction when such an operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n *\\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\\n * all math on `uint256` and `int256` and then downcasting.\\n */\\nlibrary SafeCast {\\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 * _Available since v4.7._\\n */\\n function toUint248(uint256 value) internal pure returns (uint248) {\\n require(value <= type(uint248).max, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint240(uint256 value) internal pure returns (uint240) {\\n require(value <= type(uint240).max, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint232(uint256 value) internal pure returns (uint232) {\\n require(value <= type(uint232).max, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint224(uint256 value) internal pure returns (uint224) {\\n require(value <= type(uint224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint216(uint256 value) internal pure returns (uint216) {\\n require(value <= type(uint216).max, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint208(uint256 value) internal pure returns (uint208) {\\n require(value <= type(uint208).max, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint200(uint256 value) internal pure returns (uint200) {\\n require(value <= type(uint200).max, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint192(uint256 value) internal pure returns (uint192) {\\n require(value <= type(uint192).max, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint184(uint256 value) internal pure returns (uint184) {\\n require(value <= type(uint184).max, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint176(uint256 value) internal pure returns (uint176) {\\n require(value <= type(uint176).max, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint168(uint256 value) internal pure returns (uint168) {\\n require(value <= type(uint168).max, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint160(uint256 value) internal pure returns (uint160) {\\n require(value <= type(uint160).max, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint152(uint256 value) internal pure returns (uint152) {\\n require(value <= type(uint152).max, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint144(uint256 value) internal pure returns (uint144) {\\n require(value <= type(uint144).max, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint136(uint256 value) internal pure returns (uint136) {\\n require(value <= type(uint136).max, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint128(uint256 value) internal pure returns (uint128) {\\n require(value <= type(uint128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint120(uint256 value) internal pure returns (uint120) {\\n require(value <= type(uint120).max, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint112(uint256 value) internal pure returns (uint112) {\\n require(value <= type(uint112).max, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint104(uint256 value) internal pure returns (uint104) {\\n require(value <= type(uint104).max, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint96(uint256 value) internal pure returns (uint96) {\\n require(value <= type(uint96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint88(uint256 value) internal pure returns (uint88) {\\n require(value <= type(uint88).max, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint80(uint256 value) internal pure returns (uint80) {\\n require(value <= type(uint80).max, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint72(uint256 value) internal pure returns (uint72) {\\n require(value <= type(uint72).max, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint64(uint256 value) internal pure returns (uint64) {\\n require(value <= type(uint64).max, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint56(uint256 value) internal pure returns (uint56) {\\n require(value <= type(uint56).max, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint48(uint256 value) internal pure returns (uint48) {\\n require(value <= type(uint48).max, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint40(uint256 value) internal pure returns (uint40) {\\n require(value <= type(uint40).max, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint32(uint256 value) internal pure returns (uint32) {\\n require(value <= type(uint32).max, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint24(uint256 value) internal pure returns (uint24) {\\n require(value <= type(uint24).max, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint16(uint256 value) internal pure returns (uint16) {\\n require(value <= type(uint16).max, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint8(uint256 value) internal pure returns (uint8) {\\n require(value <= type(uint8).max, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\n */\\n function toUint256(int256 value) internal pure returns (uint256) {\\n require(value >= 0, \\\"SafeCast: value must be positive\\\");\\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 * _Available since v4.7._\\n */\\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\\n downcasted = int248(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\\n downcasted = int240(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\\n downcasted = int232(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\\n downcasted = int224(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\\n downcasted = int216(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\\n downcasted = int208(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\\n downcasted = int200(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\\n downcasted = int192(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\\n downcasted = int184(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\\n downcasted = int176(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\\n downcasted = int168(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\\n downcasted = int160(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\\n downcasted = int152(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\\n downcasted = int144(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\\n downcasted = int136(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\\n downcasted = int128(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\\n downcasted = int120(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\\n downcasted = int112(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\\n downcasted = int104(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\\n downcasted = int96(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\\n downcasted = int88(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\\n downcasted = int80(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\\n downcasted = int72(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\\n downcasted = int64(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\\n downcasted = int56(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\\n downcasted = int48(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\\n downcasted = int40(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\\n downcasted = int32(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\\n downcasted = int24(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\\n downcasted = int16(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\\n downcasted = int8(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\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 require(value <= uint256(type(int256).max), \\\"SafeCast: value doesn't fit in an int256\\\");\\n return int256(value);\\n }\\n}\\n\",\"keccak256\":\"0x52a8cfb0f5239d11b457dcdd1b326992ef672714ca8da71a157255bddd13f3ad\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SignedMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard signed math utilities missing in the Solidity language.\\n */\\nlibrary SignedMath {\\n /**\\n * @dev Returns the largest of two signed numbers.\\n */\\n function max(int256 a, int256 b) internal pure returns (int256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two signed numbers.\\n */\\n function min(int256 a, int256 b) internal pure returns (int256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two signed numbers without overflow.\\n * The result is rounded towards zero.\\n */\\n function average(int256 a, int256 b) internal pure returns (int256) {\\n // Formula from the book \\\"Hacker's Delight\\\"\\n int256 x = (a & b) + ((a ^ b) >> 1);\\n return x + (int256(uint256(x) >> 255) & (a ^ b));\\n }\\n\\n /**\\n * @dev Returns the absolute unsigned value of a signed value.\\n */\\n function abs(int256 n) internal pure returns (uint256) {\\n unchecked {\\n // must be unchecked in order to support `n = type(int256).min`\\n return uint256(n >= 0 ? n : -n);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf92515413956f529d95977adc9b0567d583c6203fc31ab1c23824c35187e3ddc\",\"license\":\"MIT\"},\"contracts/aa-4337/core/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable no-inline-assembly */\\n\\n/**\\n * returned data from validateUserOp.\\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\\n * @param aggregator - address(0) - the account validated the signature by itself.\\n * address(1) - the account failed to validate the signature.\\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\\n * @param validAfter - this UserOp is valid only after this timestamp.\\n * @param validaUntil - this UserOp is valid only up to this timestamp.\\n */\\nstruct ValidationData {\\n address aggregator;\\n uint48 validAfter;\\n uint48 validUntil;\\n}\\n\\n//extract sigFailed, validAfter, validUntil.\\n// also convert zero validUntil to type(uint48).max\\nfunction _parseValidationData(\\n uint validationData\\n) pure returns (ValidationData memory data) {\\n address aggregator = address(uint160(validationData));\\n uint48 validUntil = uint48(validationData >> 160);\\n if (validUntil == 0) {\\n validUntil = type(uint48).max;\\n }\\n uint48 validAfter = uint48(validationData >> (48 + 160));\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n// intersect account and paymaster ranges.\\nfunction _intersectTimeRange(\\n uint256 validationData,\\n uint256 paymasterValidationData\\n) pure returns (ValidationData memory) {\\n ValidationData memory accountValidationData = _parseValidationData(\\n validationData\\n );\\n ValidationData memory pmValidationData = _parseValidationData(\\n paymasterValidationData\\n );\\n address aggregator = accountValidationData.aggregator;\\n if (aggregator == address(0)) {\\n aggregator = pmValidationData.aggregator;\\n }\\n uint48 validAfter = accountValidationData.validAfter;\\n uint48 validUntil = accountValidationData.validUntil;\\n uint48 pmValidAfter = pmValidationData.validAfter;\\n uint48 pmValidUntil = pmValidationData.validUntil;\\n\\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp\\n * @param data - the ValidationData to pack\\n */\\nfunction _packValidationData(\\n ValidationData memory data\\n) pure returns (uint256) {\\n return\\n uint160(data.aggregator) |\\n (uint256(data.validUntil) << 160) |\\n (uint256(data.validAfter) << (160 + 48));\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp, when not using an aggregator\\n * @param sigFailed - true for signature failure, false for success\\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\\n * @param validAfter first timestamp this UserOperation is valid\\n */\\nfunction _packValidationData(\\n bool sigFailed,\\n uint48 validUntil,\\n uint48 validAfter\\n) pure returns (uint256) {\\n return\\n (sigFailed ? 1 : 0) |\\n (uint256(validUntil) << 160) |\\n (uint256(validAfter) << (160 + 48));\\n}\\n\\n/**\\n * keccak function over calldata.\\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\\n */\\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\\n assembly {\\n let mem := mload(0x40)\\n let len := data.length\\n calldatacopy(mem, data.offset, len)\\n ret := keccak256(mem, len)\\n }\\n}\\n\",\"keccak256\":\"0xa79f06cd158ecb8c0da95493a2f348933b8627a63e228b99738bff3aa107942d\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAggregator.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\n/**\\n * Aggregated Signatures validator.\\n */\\ninterface IAggregator {\\n /**\\n * validate aggregated signature.\\n * revert if the aggregated signature does not match the given list of operations.\\n */\\n function validateSignatures(\\n UserOperation[] calldata userOps,\\n bytes calldata signature\\n ) external view;\\n\\n /**\\n * validate signature of a single userOp\\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\\n * @param userOp the userOperation received from the user.\\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\\n * (usually empty, unless account and aggregator support some kind of \\\"multisig\\\"\\n */\\n function validateUserOpSignature(\\n UserOperation calldata userOp\\n ) external view returns (bytes memory sigForUserOp);\\n\\n /**\\n * aggregate multiple signatures into a single value.\\n * This method is called off-chain to calculate the signature to pass with handleOps()\\n * bundler MAY use optimized custom code perform this aggregation\\n * @param userOps array of UserOperations to collect the signatures from.\\n * @return aggregatedSignature the aggregated signature\\n */\\n function aggregateSignatures(\\n UserOperation[] calldata userOps\\n ) external view returns (bytes memory aggregatedSignature);\\n}\\n\",\"keccak256\":\"0xdfdcd80568f037716674619b31be630fcd8316262f05a815b41d1e81782c966a\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IEntryPoint.sol\":{\"content\":\"/**\\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\\n ** Only one instance required on each chain.\\n **/\\n// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-inline-assembly */\\n/* solhint-disable reason-string */\\n\\nimport \\\"./UserOperation.sol\\\";\\nimport \\\"./IStakeManager.sol\\\";\\nimport \\\"./IAggregator.sol\\\";\\nimport \\\"./INonceManager.sol\\\";\\n\\ninterface IEntryPoint is IStakeManager, INonceManager {\\n /***\\n * An event emitted after each successful request\\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\\n * @param sender - the account that generates this request.\\n * @param paymaster - if non-null, the paymaster that pays for this request.\\n * @param nonce - the nonce value from the request.\\n * @param success - true if the sender transaction succeeded, false if reverted.\\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\\n */\\n event UserOperationEvent(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address indexed paymaster,\\n uint256 nonce,\\n bool success,\\n uint256 actualGasCost,\\n uint256 actualGasUsed\\n );\\n\\n /**\\n * account \\\"sender\\\" was deployed.\\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\\n * @param sender the account that is deployed\\n * @param factory the factory used to deploy this account (in the initCode)\\n * @param paymaster the paymaster used by this UserOp\\n */\\n event AccountDeployed(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address factory,\\n address paymaster\\n );\\n\\n /**\\n * An event emitted if the UserOperation \\\"callData\\\" reverted with non-zero length\\n * @param userOpHash the request unique identifier.\\n * @param sender the sender of this request\\n * @param nonce the nonce used in the request\\n * @param revertReason - the return bytes from the (reverted) call to \\\"callData\\\".\\n */\\n event UserOperationRevertReason(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n uint256 nonce,\\n bytes revertReason\\n );\\n\\n /**\\n * an event emitted by handleOps(), before starting the execution loop.\\n * any event emitted before this event, is part of the validation.\\n */\\n event BeforeExecution();\\n\\n /**\\n * signature aggregator used by the following UserOperationEvents within this bundle.\\n */\\n event SignatureAggregatorChanged(address indexed aggregator);\\n\\n /**\\n * a custom revert error of handleOps, to identify the offending op.\\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\\n * @param reason - revert reason\\n * The string starts with a unique code \\\"AAmn\\\", where \\\"m\\\" is \\\"1\\\" for factory, \\\"2\\\" for account and \\\"3\\\" for paymaster issues,\\n * so a failure can be attributed to the correct entity.\\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\\n */\\n error FailedOp(uint256 opIndex, string reason);\\n\\n /**\\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\\n */\\n error SignatureValidationFailed(address aggregator);\\n\\n /**\\n * Successful result from simulateValidation.\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n */\\n error ValidationResult(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo\\n );\\n\\n /**\\n * Successful result from simulateValidation, if the account returns a signature aggregator\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\\n * bundler MUST use it to verify the signature, or reject the UserOperation\\n */\\n error ValidationResultWithAggregation(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo,\\n AggregatorStakeInfo aggregatorInfo\\n );\\n\\n /**\\n * return value of getSenderAddress\\n */\\n error SenderAddressResult(address sender);\\n\\n /**\\n * return value of simulateHandleOp\\n */\\n error ExecutionResult(\\n uint256 preOpGas,\\n uint256 paid,\\n uint48 validAfter,\\n uint48 validUntil,\\n bool targetSuccess,\\n bytes targetResult\\n );\\n\\n //UserOps handled, per aggregator\\n struct UserOpsPerAggregator {\\n UserOperation[] userOps;\\n // aggregator address\\n IAggregator aggregator;\\n // aggregated signature\\n bytes signature;\\n }\\n\\n /**\\n * Execute a batch of UserOperation.\\n * no signature aggregator is used.\\n * if any account requires an aggregator (that is, it returned an aggregator when\\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\\n * @param ops the operations to execute\\n * @param beneficiary the address to receive the fees\\n */\\n function handleOps(\\n UserOperation[] calldata ops,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * Execute a batch of UserOperation with Aggregators\\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\\n * @param beneficiary the address to receive the fees\\n */\\n function handleAggregatedOps(\\n UserOpsPerAggregator[] calldata opsPerAggregator,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * generate a request Id - unique identifier for this request.\\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\\n */\\n function getUserOpHash(\\n UserOperation calldata userOp\\n ) external view returns (bytes32);\\n\\n /**\\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\\n * @param userOp the user operation to validate.\\n */\\n function simulateValidation(UserOperation calldata userOp) external;\\n\\n /**\\n * gas and return values during simulation\\n * @param preOpGas the gas used for validation (including preValidationGas)\\n * @param prefund the required prefund for this operation\\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\\n */\\n struct ReturnInfo {\\n uint256 preOpGas;\\n uint256 prefund;\\n bool sigFailed;\\n uint48 validAfter;\\n uint48 validUntil;\\n bytes paymasterContext;\\n }\\n\\n /**\\n * returned aggregated signature info.\\n * the aggregator returned by the account, and its current stake.\\n */\\n struct AggregatorStakeInfo {\\n address aggregator;\\n StakeInfo stakeInfo;\\n }\\n\\n /**\\n * Get counterfactual sender address.\\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\\n * this method always revert, and returns the address in SenderAddressResult error\\n * @param initCode the constructor code to be passed into the UserOperation.\\n */\\n function getSenderAddress(bytes memory initCode) external;\\n\\n /**\\n * simulate full execution of a UserOperation (including both validation and target execution)\\n * this method will always revert with \\\"ExecutionResult\\\".\\n * it performs full validation of the UserOperation, but ignores signature error.\\n * an optional target address is called after the userop succeeds, and its value is returned\\n * (before the entire call is reverted)\\n * Note that in order to collect the the success/failure of the target call, it must be executed\\n * with trace enabled to track the emitted events.\\n * @param op the UserOperation to simulate\\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\\n * are set to the return from that call.\\n * @param targetCallData callData to pass to target address\\n */\\n function simulateHandleOp(\\n UserOperation calldata op,\\n address target,\\n bytes calldata targetCallData\\n ) external;\\n}\\n\",\"keccak256\":\"0x9ccb1b188eda8bbf5f6c2d01bd83c3d8b2b04fcf745283051d31fe96d1d8e40f\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/INonceManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\ninterface INonceManager {\\n /**\\n * Return the next nonce for this sender.\\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\\n * But UserOp with different keys can come with arbitrary order.\\n *\\n * @param sender the account address\\n * @param key the high 192 bit of the nonce\\n * @return nonce a full nonce to pass for next UserOp with this sender.\\n */\\n function getNonce(\\n address sender,\\n uint192 key\\n ) external view returns (uint256 nonce);\\n\\n /**\\n * Manually increment the nonce of the sender.\\n * This method is exposed just for completeness..\\n * Account does NOT need to call it, neither during validation, nor elsewhere,\\n * as the EntryPoint will update the nonce regardless.\\n * Possible use-case is call it with various keys to \\\"initialize\\\" their nonces to one, so that future\\n * UserOperations will not pay extra for the first transaction with a given key.\\n */\\n function incrementNonce(uint192 key) external;\\n}\\n\",\"keccak256\":\"0xce478ad0fa0d18a3b785ac854623029e7ab463d05873dfaa365abfa1bf100912\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IStakeManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8.12;\\n\\n/**\\n * manage deposits and stakes.\\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\\n * stake is value locked for at least \\\"unstakeDelay\\\" by the staked entity.\\n */\\ninterface IStakeManager {\\n event Deposited(address indexed account, uint256 totalDeposit);\\n\\n event Withdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /// Emitted when stake or unstake delay are modified\\n event StakeLocked(\\n address indexed account,\\n uint256 totalStaked,\\n uint256 unstakeDelaySec\\n );\\n\\n /// Emitted once a stake is scheduled for withdrawal\\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\\n\\n event StakeWithdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /**\\n * @param deposit the entity's deposit\\n * @param staked true if this entity is staked.\\n * @param stake actual amount of ether staked for this entity.\\n * @param unstakeDelaySec minimum delay to withdraw the stake.\\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\\n * and the rest fit into a 2nd cell.\\n * 112 bit allows for 10^15 eth\\n * 48 bit for full timestamp\\n * 32 bit allows 150 years for unstake delay\\n */\\n struct DepositInfo {\\n uint112 deposit;\\n bool staked;\\n uint112 stake;\\n uint32 unstakeDelaySec;\\n uint48 withdrawTime;\\n }\\n\\n //API struct used by getStakeInfo and simulateValidation\\n struct StakeInfo {\\n uint256 stake;\\n uint256 unstakeDelaySec;\\n }\\n\\n /// @return info - full deposit information of given account\\n function getDepositInfo(\\n address account\\n ) external view returns (DepositInfo memory info);\\n\\n /// @return the deposit (for gas payment) of the account\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * add to the deposit of the given account\\n */\\n function depositTo(address account) external payable;\\n\\n /**\\n * add to the account's stake - amount and delay\\n * any pending unstake is first cancelled.\\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\\n */\\n function addStake(uint32 _unstakeDelaySec) external payable;\\n\\n /**\\n * attempt to unlock the stake.\\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\\n */\\n function unlockStake() external;\\n\\n /**\\n * withdraw from the (unlocked) stake.\\n * must first call unlockStake and wait for the unstakeDelay to pass\\n * @param withdrawAddress the address to send withdrawn value.\\n */\\n function withdrawStake(address payable withdrawAddress) external;\\n\\n /**\\n * withdraw from the deposit.\\n * @param withdrawAddress the address to send withdrawn value.\\n * @param withdrawAmount the amount to withdraw.\\n */\\n function withdrawTo(\\n address payable withdrawAddress,\\n uint256 withdrawAmount\\n ) external;\\n}\\n\",\"keccak256\":\"0xadcea606c9b7aafe6645441f2154a60f271330b0eee5292a632aa71c1672d546\",\"license\":\"GPL-3.0-only\"},\"contracts/aa-4337/interfaces/UserOperation.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable no-inline-assembly */\\n\\nimport {calldataKeccak} from \\\"../core/Helpers.sol\\\";\\n\\n/**\\n * User Operation struct\\n * @param sender the sender account of this request.\\n * @param nonce unique value the sender uses to verify it is not a replay.\\n * @param initCode if set, the account contract will be created by this constructor/\\n * @param callData the method call to execute on this account.\\n * @param callGasLimit the gas limit passed to the callData method call.\\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\\n * @param maxFeePerGas same as EIP-1559 gas parameter.\\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\\n */\\nstruct UserOperation {\\n address sender;\\n uint256 nonce;\\n bytes initCode;\\n bytes callData;\\n uint256 callGasLimit;\\n uint256 verificationGasLimit;\\n uint256 preVerificationGas;\\n uint256 maxFeePerGas;\\n uint256 maxPriorityFeePerGas;\\n bytes paymasterAndData;\\n bytes signature;\\n}\\n\\n/**\\n * Utility functions helpful when working with UserOperation structs.\\n */\\nlibrary UserOperationLib {\\n function getSender(\\n UserOperation calldata userOp\\n ) internal pure returns (address) {\\n address data;\\n //read sender from userOp, which is first userOp member (saves 800 gas...)\\n assembly {\\n data := calldataload(userOp)\\n }\\n return address(uint160(data));\\n }\\n\\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\\n // pay above what he signed for.\\n function gasPrice(\\n UserOperation calldata userOp\\n ) internal view returns (uint256) {\\n unchecked {\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n if (maxFeePerGas == maxPriorityFeePerGas) {\\n //legacy mode (for networks that don't support basefee opcode)\\n return maxFeePerGas;\\n }\\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\\n }\\n }\\n\\n function pack(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes memory ret) {\\n address sender = getSender(userOp);\\n uint256 nonce = userOp.nonce;\\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\\n bytes32 hashCallData = calldataKeccak(userOp.callData);\\n uint256 callGasLimit = userOp.callGasLimit;\\n uint256 verificationGasLimit = userOp.verificationGasLimit;\\n uint256 preVerificationGas = userOp.preVerificationGas;\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\\n\\n return\\n abi.encode(\\n sender,\\n nonce,\\n hashInitCode,\\n hashCallData,\\n callGasLimit,\\n verificationGasLimit,\\n preVerificationGas,\\n maxFeePerGas,\\n maxPriorityFeePerGas,\\n hashPaymasterAndData\\n );\\n }\\n\\n function hash(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes32) {\\n return keccak256(pack(userOp));\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n}\\n\",\"keccak256\":\"0x2429f5cc546bdee08c7e63858d0dda8491eaa3ab5194df884dc948c1154d2834\",\"license\":\"GPL-3.0\"},\"contracts/facets/Modifiers.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {LibGuardian} from \\\"../libraries/LibGuardian.sol\\\";\\nimport {BarzStorage} from \\\"../libraries/LibAppStorage.sol\\\";\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\n\\n/**\\n * @title Modifiers\\n * @dev Responsible for providing modifiers/util functions to Facet contracts\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\nabstract contract Modifiers is BarzStorage {\\n uint8 constant INNER_STRUCT = 0;\\n\\n error CallerNotGuardian();\\n error CallerNotGuardianOrOwner();\\n error DuplicateApprover();\\n error ZeroApproverLength();\\n error UnregisteredFacetAndSelectors();\\n\\n /**\\n * @notice Modifier to only allow guardian to make a call, reverts if any other entity is the caller\\n */\\n modifier onlyGuardian() {\\n if (!LibGuardian.isGuardian(msg.sender)) revert CallerNotGuardian();\\n _;\\n }\\n\\n /**\\n * @notice Modifier to only allow guardian or owner to make a call, reverts if any other entity is the caller\\n */\\n modifier onlyGuardianOrOwner() {\\n if (!LibGuardian.isGuardian(msg.sender) && address(this) != msg.sender)\\n revert CallerNotGuardianOrOwner();\\n _;\\n }\\n\\n /**\\n * @notice Checks if the approver address is the array is unique with no duplicate\\n * @dev This method loops through the array and checks if a duplicate address exists, it reverts if duplicate address exists\\n * @param approvers Array of address\\n */\\n function _checkApprover(\\n address[] memory approvers\\n ) internal pure returns (bool) {\\n uint256 approverLength = approvers.length;\\n if (0 == approverLength) revert ZeroApproverLength();\\n for (uint256 i; i < approverLength - 1; ) {\\n for (uint256 j = i + 1; j < approverLength; ) {\\n if (approvers[i] == approvers[j]) {\\n revert DuplicateApprover(); // Found a duplicate\\n }\\n unchecked {\\n ++j;\\n }\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n return false; // No duplicates found\\n }\\n\\n /**\\n * @notice Checks if the facet getting added or replaced is registered to facet registry\\n * @dev This method loops through the cut and checks if the facet getting added/replaced is registered to facet registry\\n * @param _diamondCut Array of FacetCut, data for diamondCut defined in EIP-2535\\n */\\n function _checkFacetCutValidity(\\n IDiamondCut.FacetCut[] memory _diamondCut\\n ) internal view {\\n uint256 diamondCutLength = _diamondCut.length;\\n for (uint256 i; i < diamondCutLength; ) {\\n if (\\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Add ||\\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Replace\\n ) {\\n if (\\n !s.facetRegistry.areFacetFunctionSelectorsRegistered(\\n _diamondCut[i].facetAddress,\\n _diamondCut[i].functionSelectors\\n )\\n ) revert UnregisteredFacetAndSelectors();\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb42956323d199bdec243a5f9859439aae057fbfdd1d79e3a96afc857ecb3115f\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/DiamondCutFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {LibDiamond} from \\\"../../libraries/LibDiamond.sol\\\";\\nimport {LibGuardian} from \\\"../../libraries/LibGuardian.sol\\\";\\nimport {ISecurityManager} from \\\"../../infrastructure/interfaces/ISecurityManager.sol\\\";\\nimport {SignatureChecker} from \\\"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\\\";\\nimport {LibFacetStorage, DiamondCutApprovalConfig, ApprovalConfig} from \\\"../../libraries/LibFacetStorage.sol\\\";\\nimport {Modifiers} from \\\"../Modifiers.sol\\\";\\nimport {IDiamondCut} from \\\"./interfaces/IDiamondCut.sol\\\";\\n\\n/**\\n * @title DiamondCut Facet\\n * @dev Responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract DiamondCutFacet is Modifiers, IDiamondCut {\\n ISecurityManager public immutable securityManager;\\n\\n /**\\n * @notice This constructor sets the Security Manager address which is an immutable variable.\\n * Immutable variables do not impact the storage of diamond\\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\\n */\\n constructor(address _securityManager) {\\n securityManager = ISecurityManager(_securityManager);\\n }\\n\\n /**\\n * @notice Updates the flag for the interfaceId\\n * @param _interfaceId InterfaceID to update the mapping\\n * @param _flag Bool value to update the mapping of the given interface ID\\n */\\n function updateSupportsInterface(\\n bytes4 _interfaceId,\\n bool _flag\\n ) external override onlyWhenUnlocked {\\n LibDiamond.enforceIsSelf();\\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId] = _flag;\\n emit SupportsInterfaceUpdated(_interfaceId, _flag);\\n }\\n\\n /**\\n * @notice Add/replace/remove any number of functions and optionally execute\\n * a function with delegatecall when guardians don't exist\\n * @param _diamondCut Contains the facet addresses and function selectors\\n * @param _init The address of the contract or facet to execute _calldata. It's prohibited in Barz\\n */\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata\\n ) external override onlyWhenUnlocked {\\n LibDiamond.enforceIsSelf();\\n\\n _checkFacetCutValidity(_diamondCut);\\n // require approval from guardian if guardian exists\\n if (0 != LibGuardian.guardianCount())\\n revert DiamondCutFacet__InvalidRouteWithGuardian();\\n if (address(0) != _init) revert DiamondCutFacet__InvalidInitAddress();\\n\\n unchecked {\\n ++LibFacetStorage.diamondCutStorage().nonce;\\n }\\n LibDiamond.diamondCut(_diamondCut, address(0), \\\"\\\");\\n }\\n\\n /**\\n * @notice Add/replace/remove any number of functions and optionally execute\\n * a function with delegatecall when guardians exist\\n * @param _diamondCut Contains the facet addresses and function selectors\\n * @param _approvers Guardian or owner address that approves the diamond cut\\n * @param _signatures Signature of Guardians or owner that approves the diamond cut\\n */\\n function diamondCutWithGuardian(\\n FacetCut[] calldata _diamondCut,\\n address[] calldata _approvers,\\n bytes[] calldata _signatures\\n ) external override onlyWhenUnlocked {\\n if (_approvers.length != _signatures.length)\\n revert DiamondCutFacet__InvalidArrayLength();\\n _checkFacetCutValidity(_diamondCut);\\n if (0 == LibGuardian.guardianCount())\\n revert DiamondCutFacet__InvalidRouteWithGuardian();\\n\\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\\n\\n _checkApprover(_approvers);\\n _checkDuplicateOnChainApprover(cutHash, _approvers);\\n\\n bool onChainOwnerApproval = getOwnerCutApprovalWithTimeValidity(\\n cutHash\\n );\\n\\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\\n if (\\n _approvers.length +\\n getDiamondCutApprovalCountWithTimeValidity(cutHash) <\\n LibGuardian.majorityOfGuardians() + threshold\\n ) revert DiamondCutFacet__InsufficientApprovers();\\n\\n bool ownerApproved;\\n for (uint256 i; i < _approvers.length; ) {\\n if (\\n !LibGuardian.isGuardian(_approvers[i]) &&\\n _approvers[i] != address(this)\\n ) revert DiamondCutFacet__InvalidApprover();\\n if (_approvers[i] == address(this)) {\\n if (onChainOwnerApproval)\\n revert DiamondCutFacet__OwnerAlreadyApproved();\\n ownerApproved = true;\\n }\\n if (\\n !SignatureChecker.isValidSignatureNow(\\n _approvers[i],\\n cutHash,\\n _signatures[i]\\n )\\n ) revert DiamondCutFacet__InvalidApproverSignature();\\n unchecked {\\n ++i;\\n }\\n }\\n if (!ownerApproved && !onChainOwnerApproval)\\n revert DiamondCutFacet__LackOfOwnerApproval();\\n\\n unchecked {\\n ++LibFacetStorage.diamondCutStorage().nonce;\\n }\\n LibDiamond.diamondCut(_diamondCut, address(0), \\\"\\\");\\n }\\n\\n /**\\n * @notice Approves diamond cut. This can only be called directly from guardian or owner\\n * @param _diamondCut Contains the facet addresses and function selectors\\n */\\n function approveDiamondCut(\\n FacetCut[] calldata _diamondCut\\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\\n if (LibGuardian.guardianCount() == 0)\\n revert DiamondCutFacet__InvalidRouteWithoutGuardian();\\n DiamondCutApprovalConfig storage ds = LibFacetStorage\\n .diamondCutStorage()\\n .diamondCutApprovalConfigs[INNER_STRUCT];\\n _checkFacetCutValidity(_diamondCut);\\n\\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\\n uint64 approvalValidUntil = uint64(\\n block.timestamp + getApprovalValidationPeriod()\\n );\\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(\\n true,\\n approvalValidUntil\\n );\\n emit DiamondCutApproved(_diamondCut);\\n if (\\n (getDiamondCutApprovalCountWithTimeValidity(cutHash) >=\\n LibGuardian.majorityOfGuardians()) &&\\n getOwnerCutApprovalWithTimeValidity(cutHash)\\n ) {\\n unchecked {\\n ++LibFacetStorage.diamondCutStorage().nonce;\\n }\\n LibDiamond.diamondCut(_diamondCut, address(0), \\\"\\\");\\n }\\n }\\n\\n /**\\n * @notice Revokes the approval of diamond cut. This can only be called directly from guardian or owner\\n * @param _diamondCut Contains the facet addresses and function selectors\\n */\\n function revokeDiamondCutApproval(\\n FacetCut[] calldata _diamondCut\\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\\n DiamondCutApprovalConfig storage ds = LibFacetStorage\\n .diamondCutStorage()\\n .diamondCutApprovalConfigs[INNER_STRUCT];\\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\\n if (!ds.isDiamondCutApproved[cutHash][msg.sender].isApproved)\\n revert DiamondCutFacet__CannotRevokeUnapproved();\\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(false, 0);\\n emit DiamondCutApprovalRevoked(_diamondCut);\\n }\\n\\n /**\\n * @notice Gets the number of approvals of diamond cut from guardians\\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\\n */\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 _diamondCutHash\\n ) public view override returns (uint256 approvalCount) {\\n address[] memory guardians = LibGuardian.getGuardians();\\n uint256 guardiansLength = guardians.length;\\n for (uint256 i; i < guardiansLength; ) {\\n if (isCutApproved(_diamondCutHash, guardians[i])) {\\n unchecked {\\n ++approvalCount;\\n }\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n return approvalCount;\\n }\\n\\n /**\\n * @notice Returns if the owner has approved the diamond cut\\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\\n * @return isApprovedByOwner Bool value showing if the owner approved the cut\\n */\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 _diamondCutHash\\n ) public view override returns (bool isApprovedByOwner) {\\n isApprovedByOwner = isCutApproved(_diamondCutHash, address(this));\\n }\\n\\n /**\\n * @notice Returns if the given approver has approved the diamond cut\\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\\n * @param _approver Address of approver\\n * @return isApproved Bool value showing if the approver approved the cut\\n */\\n function isCutApproved(\\n bytes32 _diamondCutHash,\\n address _approver\\n ) public view override returns (bool isApproved) {\\n DiamondCutApprovalConfig storage ds = LibFacetStorage\\n .diamondCutStorage()\\n .diamondCutApprovalConfigs[INNER_STRUCT];\\n isApproved = (ds\\n .isDiamondCutApproved[_diamondCutHash][_approver].isApproved &&\\n block.timestamp <\\n ds.isDiamondCutApproved[_diamondCutHash][_approver].validUntil);\\n }\\n\\n /**\\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\\n * Approvers who approved on-chain should not be included in the off-chain approval\\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\\n * @param _approvers List of approver addresses\\n */\\n function _checkDuplicateOnChainApprover(\\n bytes32 _diamondCutHash,\\n address[] memory _approvers\\n ) public view {\\n address[] memory guardians = LibGuardian.getGuardians();\\n uint256 guardianLength = guardians.length;\\n uint256 approversLength = _approvers.length;\\n for (uint256 i; i < guardianLength; ) {\\n if (isCutApproved(_diamondCutHash, guardians[i])) {\\n for (uint256 j; j < approversLength; ) {\\n if (_approvers[j] == guardians[i])\\n revert DiamondCutFacet__DuplicateApproval();\\n unchecked {\\n ++j;\\n }\\n }\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * @notice Returns the diamond cut hash. This function ensures that this hash is safe from replay attack by including\\n * salt, address, chainId, and nonce, etc.\\n * @param _diamondCut Contains the facet addresses and function selectors\\n * @return cutHash Diamond Cut Hash\\n */\\n function getDiamondCutHash(\\n FacetCut[] calldata _diamondCut\\n ) public view override returns (bytes32 cutHash) {\\n cutHash = keccak256(\\n abi.encodePacked(\\n \\\"\\\\x19Ethereum Signed Message:\\\\n32\\\",\\n keccak256(\\n abi.encode(\\n keccak256(abi.encode(_diamondCut)),\\n address(this),\\n block.chainid,\\n LibFacetStorage.diamondCutStorage().nonce\\n )\\n )\\n )\\n );\\n }\\n\\n /**\\n * @notice Returns the approval validation Period\\n * @dev This method fetches the validation period from the security manager\\n * @return approvalValidationPeriod Approval validation period of Barz contract fetched from security manager\\n */\\n function getApprovalValidationPeriod()\\n internal\\n view\\n returns (uint256 approvalValidationPeriod)\\n {\\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\\n address(this)\\n );\\n if (approvalValidationPeriod <= 0)\\n revert DiamondCutFacet__InvalidApprovalValidationPeriod();\\n }\\n\\n /**\\n * @notice Returns the diamond cut nonce of this wallet\\n * @dev This method fetches the nonce from diamond cut storage\\n * @return cutNonce Nonce of diamond cut to protect from reply attacks\\n */\\n function getDiamondCutNonce()\\n public\\n view\\n override\\n returns (uint128 cutNonce)\\n {\\n cutNonce = LibFacetStorage.diamondCutStorage().nonce;\\n }\\n}\\n\",\"keccak256\":\"0xe91a7dd2daabf2e989c94089f4f1eb0da94276c3070559ac8988838e10dd1f5d\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/infrastructure/interfaces/IFacetRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Registry Interface\\n * @dev Interface for Facet Registry contract to keep track of facets & function selectors addable to user wallets\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IFacetRegistry {\\n struct FacetRegistryConfig {\\n bytes4[] selectors;\\n mapping(bytes4 => FacetInfo) info;\\n }\\n struct FacetInfo {\\n bool exists;\\n uint128 index;\\n }\\n\\n event FacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] facetSelectors\\n );\\n event FacetFunctionSelectorsRemoved(address facet, bytes4[] facetSelectors);\\n\\n error FacetRegistry__FacetSelectorAlreadyRegistered();\\n error FacetRegistry__UnregisteredFacetSelector();\\n\\n function registerFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function removeFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function areFacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external view returns (bool);\\n\\n function isFacetFunctionSelectorRegistered(\\n address facet,\\n bytes4 facetSelector\\n ) external view returns (bool);\\n\\n function getFacetFunctionSelectors(\\n address facet\\n ) external view returns (bytes4[] memory);\\n}\\n\",\"keccak256\":\"0x6e6dd2cab346ef7c31230740ec48d2925e4a9ab24c2f2fb268baaf408dcf02ef\",\"license\":\"Apache-2.0\"},\"contracts/infrastructure/interfaces/ISecurityManager.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Registry Interface\\n * @dev Infrastructure contract to manage security parameters of users\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\ninterface ISecurityManager {\\n error SecurityManager__OutOfBoundary();\\n error SecurityManager__CallerNotWallet();\\n error SecurityManager__AlreadyIntialized();\\n\\n function initializeAdditionSecurityPeriod(\\n uint128 defaultAdditionSecurityPeriod,\\n uint128 minAdditionSecurityPeriod,\\n uint128 maxAdditionSecurityPeriod\\n ) external;\\n\\n function initializeRemovalSecurityPeriod(\\n uint128 defaultRemovalSecurityPeriod,\\n uint128 minRemovalSecurityPeriod,\\n uint128 maxRemovalSecurityPeriod\\n ) external;\\n\\n function initializeApprovalValidationPeriod(\\n uint128 defaultApprovalValidationPeriod,\\n uint128 minApprovalValidationPeriod,\\n uint128 maxApprovalValidationPeriod\\n ) external;\\n\\n function initializeMigrationPeriod(\\n uint128 defaultMigrationPeriod,\\n uint128 minMigrationPeriod,\\n uint128 maxMigrationPeriod\\n ) external;\\n\\n function initializeLockPeriod(\\n uint128 defaultLockPeriod,\\n uint128 minLockPeriod,\\n uint128 maxLockPeriod\\n ) external;\\n\\n function initializeRecoveryPeriod(\\n uint128 defaultRecoveryPeriod,\\n uint128 minRecoveryPeriod,\\n uint128 maxRecoveryPeriod\\n ) external;\\n\\n function initializeSecurityWindow(\\n uint128 defaultSecurityWindow,\\n uint128 minSecurityWindow,\\n uint128 maxSecurityWindow\\n ) external;\\n\\n function setAdditionSecurityPeriod(\\n address wallet,\\n uint128 additionSecurityPeriod\\n ) external;\\n\\n function setRemovalSecurityPeriod(\\n address wallet,\\n uint128 removalSecurityPeriod\\n ) external;\\n\\n function setSecurityWindow(address wallet, uint128 securityWindow) external;\\n\\n function setRecoveryPeriod(address wallet, uint128 recoveryPeriod) external;\\n\\n function setLockPeriod(address wallet, uint128 lockPeriod) external;\\n\\n function setApprovalValidationPeriod(\\n address wallet,\\n uint128 approvalValidationPeriod\\n ) external;\\n\\n function setMigrationPeriod(\\n address wallet,\\n uint128 migrationPeriod\\n ) external;\\n\\n function additionSecurityPeriodOf(\\n address wallet\\n ) external view returns (uint128);\\n\\n function removalSecurityPeriodOf(\\n address wallet\\n ) external view returns (uint128);\\n\\n function securityWindowOf(address wallet) external view returns (uint128);\\n\\n function recoveryPeriodOf(address wallet) external view returns (uint128);\\n\\n function lockPeriodOf(address wallet) external view returns (uint128);\\n\\n function migrationPeriodOf(address wallet) external view returns (uint128);\\n\\n function approvalValidationPeriodOf(\\n address wallet\\n ) external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x9ac6566033ef81ba5744c8ed2b08f130b781b498ab9245bcca87567669549552\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibAppStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {SafeCast} from \\\"@openzeppelin/contracts/utils/math/SafeCast.sol\\\";\\nimport {IEntryPoint} from \\\"../aa-4337/interfaces/IEntryPoint.sol\\\";\\nimport {IFacetRegistry} from \\\"../infrastructure/interfaces/IFacetRegistry.sol\\\";\\n\\n/*\\n * @title App Storage\\n * @dev App storage for Barz contract to prevent storage collision\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Lock {\\n uint64 release;\\n bytes4 locker;\\n}\\n\\nstruct InitializersStorage {\\n // NOTE: initialized is a variable to make sure the initialization is only done once.\\n uint8 signerInitialized;\\n uint8 accountInitialized;\\n uint8 restrictionsInitialized;\\n}\\n\\nstruct AppStorage {\\n mapping(uint256 => InitializersStorage) initStorage;\\n uint8 signerMigration;\\n bytes4 validateOwnerSignatureSelector;\\n IEntryPoint entryPoint;\\n IFacetRegistry facetRegistry;\\n mapping(uint256 => Lock) locks;\\n}\\n\\nlibrary LibAppStorage {\\n error LibAppStorage__AccountAlreadyUninitialized();\\n error LibAppStorage__AccountMustBeUninitialized();\\n error LibAppStorage__SignerAlreadyUninitialized();\\n error LibAppStorage__SignerMustBeUninitialized();\\n\\n function appStorage() internal pure returns (AppStorage storage ds) {\\n assembly {\\n ds.slot := 0\\n }\\n }\\n\\n function setSignerUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerAlreadyUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 0;\\n }\\n\\n function getValidateOwnerSignatureSelector()\\n internal\\n view\\n returns (bytes4 selector)\\n {\\n selector = appStorage().validateOwnerSignatureSelector;\\n }\\n\\n function setValidateOwnerSignatureSelector(\\n bytes4 _validateOwnerSignatureSelector\\n ) internal {\\n appStorage()\\n .validateOwnerSignatureSelector = _validateOwnerSignatureSelector;\\n }\\n\\n function enforceSignerInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerMustBeUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 1;\\n }\\n\\n function enforceAccountInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].accountInitialized) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n s.initStorage[0].accountInitialized = 1;\\n }\\n\\n function initiateSignerMigration() internal {\\n appStorage().signerMigration = 1;\\n }\\n\\n function enforceSignerMigration() internal view {\\n if (1 != appStorage().signerMigration) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n }\\n\\n function finalizeSignerMigration() internal {\\n appStorage().signerMigration = 0;\\n }\\n\\n function setLock(uint256 _releaseAfter, bytes4 _locker) internal {\\n appStorage().locks[0] = Lock(SafeCast.toUint64(_releaseAfter), _locker);\\n }\\n\\n function enforceRestrictionsInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__SignerMustBeUninitialized();\\n s.initStorage[0].restrictionsInitialized = 1;\\n }\\n\\n function setRestrictionsUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__AccountAlreadyUninitialized();\\n s.initStorage[0].restrictionsInitialized = 0;\\n }\\n}\\n\\ncontract BarzStorage {\\n AppStorage internal s;\\n modifier onlyWhenUnlocked() {\\n require(\\n uint64(block.timestamp) >= s.locks[0].release,\\n \\\"Account Locked\\\"\\n );\\n _;\\n }\\n modifier onlyWhenLocked() {\\n require(\\n uint64(block.timestamp) < s.locks[0].release,\\n \\\"Account Unlocked\\\"\\n );\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x48524007862a6ce0e07f645950613ce6513ce073c37a109c75019683d42bae27\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\\n bytes4(keccak256(\\\"verifyRestrictions(address,address,uint256,bytes)\\\"));\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // Default Fallback Handler of the barz.\\n IDiamondLoupe defaultFallbackHandler;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function enforceIsSelf() internal view {\\n require(msg.sender == address(this), \\\"LibDiamond: Caller not self\\\");\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n\\n unchecked {\\n facetIndex++;\\n }\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n\\n function restrictionsFacet() internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(\\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2cabdc00de859c3a3170ce3bda5d0e5fd3933d47ce904fd1585f9818b02572f8\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibFacetStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Storage\\n * @dev Storage contract to store each facets variables with diamond storage\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Secp256k1VerificationStorage {\\n address signer;\\n}\\n\\nstruct Secp256r1VerificationStorage {\\n uint256[2] q;\\n}\\n\\nstruct GuardianStorage {\\n mapping(bytes32 => uint256) pending;\\n mapping(uint8 => StorageConfig) configs;\\n}\\n\\nstruct Info {\\n bool exists;\\n uint128 index;\\n}\\n\\nstruct StorageConfig {\\n address[] addresses;\\n mapping(address => Info) info;\\n}\\n\\nstruct RecoveryConfig {\\n bytes recoveryPublicKey;\\n uint64 executeAfter;\\n}\\n\\nstruct ApprovalConfig {\\n bool isApproved;\\n uint64 validUntil;\\n}\\n\\nstruct RecoveryApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isNewOwnerApproved;\\n}\\n\\nstruct RecoveryStorage {\\n mapping(uint8 => RecoveryConfig) recoveryConfigs;\\n mapping(uint8 => RecoveryApprovalConfig) recoveryApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct RestrictionsStorage {\\n address[] restrictions;\\n mapping(address => bool) exists;\\n}\\n\\nstruct SignatureMigrationConfig {\\n bytes migrationPublicKey;\\n address migrationVerificationFacet;\\n bytes4[] migrationSelectors;\\n uint64 migrateAfter;\\n}\\n\\nstruct SignatureMigrationApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isMigrationApproved;\\n}\\n\\nstruct SignatureMigrationStorage {\\n mapping(uint8 => SignatureMigrationConfig) migrationConfigs;\\n mapping(uint8 => SignatureMigrationApprovalConfig) migrationApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct DiamondCutApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isDiamondCutApproved;\\n}\\n\\nstruct DiamondCutStorage {\\n mapping(uint8 => DiamondCutApprovalConfig) diamondCutApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct LockStorage {\\n uint128 nonce;\\n}\\n\\nlibrary LibFacetStorage {\\n bytes32 constant K1_STORAGE_POSITION =\\n keccak256(\\n \\\"v0.trustwallet.diamond.storage.Secp256k1VerificationStorage\\\"\\n );\\n bytes32 constant R1_STORAGE_POSITION =\\n keccak256(\\n \\\"v0.trustwallet.diamond.storage.Secp256r1VerificationStorage\\\"\\n );\\n bytes32 constant GUARDIAN_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.GuardianStorage\\\");\\n bytes32 constant RECOVERY_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.RecoveryStorage\\\");\\n bytes32 constant RESTRICTION_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.RestrictionsStorage\\\");\\n bytes32 constant MIGRATION_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.SignatureMigrationStorage\\\");\\n bytes32 constant DIAMONDCUT_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.DiamondCutStorage\\\");\\n bytes32 constant LOCK_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.LockStorage\\\");\\n\\n function k1Storage()\\n internal\\n pure\\n returns (Secp256k1VerificationStorage storage ds)\\n {\\n bytes32 storagePosition = K1_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function r1Storage()\\n internal\\n pure\\n returns (Secp256r1VerificationStorage storage ds)\\n {\\n bytes32 storagePosition = R1_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function guardianStorage()\\n internal\\n pure\\n returns (GuardianStorage storage ds)\\n {\\n bytes32 storagePosition = GUARDIAN_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function recoveryStorage()\\n internal\\n pure\\n returns (RecoveryStorage storage ds)\\n {\\n bytes32 storagePosition = RECOVERY_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function restrictionsStorage()\\n internal\\n pure\\n returns (RestrictionsStorage storage ds)\\n {\\n bytes32 storagePosition = RESTRICTION_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function migrationStorage()\\n internal\\n pure\\n returns (SignatureMigrationStorage storage ds)\\n {\\n bytes32 storagePosition = MIGRATION_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function diamondCutStorage()\\n internal\\n pure\\n returns (DiamondCutStorage storage ds)\\n {\\n bytes32 storagePosition = DIAMONDCUT_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function lockStorage() internal pure returns (LockStorage storage ds) {\\n bytes32 storagePosition = LOCK_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n}\\n\",\"keccak256\":\"0x87c85decfd943deda9540733e464cb1a92eba735a301e89ce6f798016e359761\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibGuardian.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {LibFacetStorage, StorageConfig} from \\\"./LibFacetStorage.sol\\\";\\n\\n/**\\n * @title LibGuardian\\n * @dev Internal Library to provide utility feature for Guardians stored in Guardian Facet Storage\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\nlibrary LibGuardian {\\n function majorityOfGuardians()\\n internal\\n view\\n returns (uint256 guardianNumber)\\n {\\n uint256 guardianLength = guardianCount();\\n guardianNumber = (guardianLength == 0) ? 0 : guardianLength / 2 + 1;\\n }\\n\\n function isGuardian(address _guardian) internal view returns (bool) {\\n StorageConfig storage config = LibFacetStorage\\n .guardianStorage()\\n .configs[0];\\n return config.info[_guardian].exists;\\n }\\n\\n function guardianCount() internal view returns (uint256) {\\n StorageConfig storage config = LibFacetStorage\\n .guardianStorage()\\n .configs[0];\\n return config.addresses.length;\\n }\\n\\n function getGuardians() internal view returns (address[] memory) {\\n StorageConfig storage config = LibFacetStorage\\n .guardianStorage()\\n .configs[0];\\n address[] memory addresses = new address[](config.addresses.length);\\n uint256 addressesLen = config.addresses.length;\\n for (uint256 i; i < addressesLen; ) {\\n addresses[i] = config.addresses[i];\\n unchecked {\\n ++i;\\n }\\n }\\n return addresses;\\n }\\n}\\n\",\"keccak256\":\"0x6a620992d5535878fc03d1a27a6675f4c1509adfb3ddbbca1c52b546c25392dc\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x60a06040523480156200001157600080fd5b506040516200379b3803806200379b833981016040819052620000349162000046565b6001600160a01b031660805262000078565b6000602082840312156200005957600080fd5b81516001600160a01b03811681146200007157600080fd5b9392505050565b6080516137006200009b600039600081816101f10152611b2501526137006000f3fe608060405234801561001057600080fd5b50600436106100d45760003560e01c806379c0d58d11610081578063afb877bb1161005b578063afb877bb146101d9578063de675a6d146101ec578063e33ecf0a1461023857600080fd5b806379c0d58d14610192578063836d6bfb146101b35780638824a0bb146101c657600080fd5b806326fc3ef4116100b257806326fc3ef4146101145780632f4d98ea1461015c5780633c0985681461017f57600080fd5b806313c34f4b146100d95780631c776dd5146100ee5780631f931c1c14610101575b600080fd5b6100ec6100e7366004612a97565b61024b565b005b6100ec6100fc366004612ad9565b6104df565b6100ec61010f366004612b9c565b610a76565b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9bf546040516fffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b61016f61016a366004612c4a565b610c7b565b6040519015158152602001610153565b6100ec61018d366004612ca4565b610c8d565b6101a56101a0366004612c4a565b610df2565b604051908152602001610153565b61016f6101c1366004612cdb565b610e4c565b6100ec6101d4366004612dd2565b610eed565b6100ec6101e7366004612a97565b610fe1565b6102137f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610153565b6101a5610246366004612a97565b61130e565b3360009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff1615801561028a5750303314155b156102c1576040517f6238ee3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610369576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064015b60405180910390fd5b60008080527f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be6020527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d3906103be848461130e565b60008181526020848152604080832033845290915290205490915060ff16610412576040517fedc5708300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051808201825260008082526020808301828152858352868252848320338452909152908390209151825491517fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000009092169015157fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff161761010067ffffffffffffffff90921691909102179055517f3c3d8c1f0b0faff6fe0ace6b485d0595a0106dce9e303f956fd941ebdbe9a98e906104d19086908690612f54565b60405180910390a150505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610582576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b8281146105bb576040517fe854148500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6105cd6105c886886130aa565b611435565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b754600003610650576040517fa788861700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061065c878761130e565b905061069a8585808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506115b392505050565b506106d881868680806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250610eed92505050565b60006106e382610c7b565b90506000816106f35760016106f6565b60005b60ff169050806107046116d0565b61070e9190613201565b61071784610df2565b6107219088613201565b1015610759576040517f709fb08000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805b878110156109a0576107d989898381811061077a5761077a613214565b905060200201602081019061078f9190613243565b73ffffffffffffffffffffffffffffffffffffffff1660009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff1690565b1580156108225750308989838181106107f4576107f4613214565b90506020020160208101906108099190613243565b73ffffffffffffffffffffffffffffffffffffffff1614155b15610859576040517f7b2cbbb400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3089898381811061086c5761086c613214565b90506020020160208101906108819190613243565b73ffffffffffffffffffffffffffffffffffffffff16036108d95783156108d4576040517fee21708000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600191505b6109628989838181106108ee576108ee613214565b90506020020160208101906109039190613243565b8689898581811061091657610916613214565b90506020028101906109289190613265565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061174f92505050565b610998576040517fac3d341600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60010161075d565b50801580156109ad575082155b156109e4576040517f6d21730400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9bf80546fffffffffffffffffffffffffffffffff808216600101167fffffffffffffffffffffffffffffffff00000000000000000000000000000000909116179055610a6a610a538a8c6130aa565b6000604051806020016040528060008152506117ca565b50505050505050505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610b19576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b610b2161195f565b610b2e6105c885876130aa565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75415610baf576040517fa788861700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff831615610bfd576040517f871cb76100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be5b600190810180547fffffffffffffffffffffffffffffffff0000000000000000000000000000000081166fffffffffffffffffffffffffffffffff91821690930116919091179055610c74610a5385876130aa565b5050505050565b6000610c878230610e4c565b92915050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610d30576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b610d3861195f565b7fffffffff00000000000000000000000000000000000000000000000000000000821660008181527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4922602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001685151590811790915582519384529083015280517f4e6bd17989efa6d6a9607ccaac1bba27b29f99622bc830d99a3a9883b21a19c79281900390910190a15050565b600080610dfd6119ca565b805190915060005b81811015610e4457610e3085848381518110610e2357610e23613214565b6020026020010151610e4c565b15610e3c578360010193505b600101610e05565b505050919050565b60008281527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d36020818152604080842073ffffffffffffffffffffffffffffffffffffffff8616855290915282205460ff168015610ee5575060008481526020828152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152902054610100900467ffffffffffffffff1642105b949350505050565b6000610ef76119ca565b805183519192509060005b82811015610fd957610f2086858381518110610e2357610e23613214565b15610fd15760005b82811015610fcf57848281518110610f4257610f42613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16868281518110610f7257610f72613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603610fc7576040517f50f5729f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600101610f28565b505b600101610f02565b505050505050565b3360009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff161580156110205750303314155b15611057576040517f6238ee3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff9081164290911610156110fa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75460000361117d576040517f3a76e1f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080527f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be6020527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d36111d36105c883856130aa565b60006111df848461130e565b905060006111eb611af4565b6111f59042613201565b6040805180820182526001815267ffffffffffffffff838116602080840191825260008881528982528581203382529091528490209251835491517fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000009092169015157fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff16176101009190921602179055519091507f6248ff757895beed7d43d135bccf59a26b7fbdf0fe8233487c44e82c0f266ba3906112b89087908790612f54565b60405180910390a16112c86116d0565b6112d183610df2565b101580156112e357506112e382610c7b565b15610c74577f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be610c1f565b60008282604051602001611323929190612f54565b6040516020818303038152906040528051906020012030466113627f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be90565b6001015460408051602081019590955273ffffffffffffffffffffffffffffffffffffffff9093169284019290925260608301526fffffffffffffffffffffffffffffffff16608082015260a001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905280516020918201207f19457468657265756d205369676e6564204d6573736167653a0a33320000000091830191909152603c820152605c0160405160208183030381529060405280519060200120905092915050565b805160005b818110156115ae57600083828151811061145657611456613214565b602002602001015160200151600281111561147357611473612e8a565b14806114ad5750600183828151811061148e5761148e613214565b60200260200101516020015160028111156114ab576114ab612e8a565b145b156115a657600254835173ffffffffffffffffffffffffffffffffffffffff9091169063df871f72908590849081106114e8576114e8613214565b60200260200101516000015185848151811061150657611506613214565b6020026020010151604001516040518363ffffffff1660e01b815260040161152f92919061331c565b602060405180830381865afa15801561154c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611570919061334b565b6115a6576040517ff41a931c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60010161143a565b505050565b80516000908082036115f1576040517f3aee2eec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b6115ff600183613368565b8110156116c6576000611613826001613201565b90505b828110156116bd5784818151811061163057611630613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1685838151811061166057611660613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16036116b5576040517f8dd19e7d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600101611616565b506001016115f4565b5060009392505050565b600080611723600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75490565b905080156117465761173660028261337b565b611741906001613201565b611749565b60005b91505090565b600080600061175e8585611bf6565b9092509050600081600481111561177757611777612e8a565b1480156117af57508573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b806117c057506117c0868686611c3b565b9695505050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921547f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff8116908190600090600716156118395750600381901c60009081526001840160205260409020545b60005b87518110156118b6576118a983838a848151811061185c5761185c613214565b6020026020010151600001518b858151811061187a5761187a613214565b6020026020010151602001518c868151811061189857611898613214565b602002602001015160400151611d98565b909350915060010161183c565b508282146118ef576002840180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff84161790555b600782161561191157600382901c600090815260018501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb67387878760405161194493929190613424565b60405180910390a16119568686612829565b50505050505050565b3330146119c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4c69624469616d6f6e643a2043616c6c6572206e6f742073656c6600000000006044820152606401610360565b565b60008080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b780546060929067ffffffffffffffff811115611a3257611a32612d07565b604051908082528060200260200182016040528015611a5b578160200160208202803683370190505b50825490915060005b81811015611aeb57836000018181548110611a8157611a81613214565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16838281518110611abe57611abe613214565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101611a64565b50909392505050565b6040517f52430c8d0000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906352430c8d90602401602060405180830381865afa158015611b81573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ba59190613510565b6fffffffffffffffffffffffffffffffff16905060008111611bf3576040517fdac5ec8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b90565b6000808251604103611c2c5760208301516040840151606085015160001a611c2087828585612928565b94509450505050611c34565b506000905060025b9250929050565b60008060008573ffffffffffffffffffffffffffffffffffffffff16631626ba7e60e01b8686604051602401611c72929190613542565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909416939093179092529051611cfb919061355b565b600060405180830381855afa9150503d8060008114611d36576040519150601f19603f3d011682016040523d82523d6000602084013e611d3b565b606091505b5091509150818015611d4f57506020815110155b80156117c0575080517f1626ba7e0000000000000000000000000000000000000000000000000000000090611d8d9083016020908101908401613577565b149695505050505050565b600080807f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f90506000845111611e50576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610360565b6000856002811115611e6457611e64612e8a565b0361203457611e8b8660405180606001604052806024815260200161365760249139612a17565b60005b845181101561202e576000858281518110611eab57611eab613214565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c15611f7e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c72656164792065786973747300000000000000000000006064820152608401610360565b7fffffffff0000000000000000000000000000000000000000000000000000000080831660008181526020879052604090207fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608d901b168e17905560e060058e901b811692831c199c909c1690821c179a8190036120125760038c901c600090815260018601602052604081209b909b555b8b61201c81613590565b9c505060019093019250611e8e915050565b5061281d565b600185600281111561204857612048612e8a565b036123385761206f866040518060600160405280602881526020016136a360289139612a17565b60005b845181101561202e57600085828151811061208f5761208f613214565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c308103612164576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4c69624469616d6f6e644375743a2043616e2774207265706c61636520696d6d60448201527f757461626c652066756e6374696f6e00000000000000000000000000000000006064820152608401610360565b8973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361221f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e00000000000000006064820152608401610360565b73ffffffffffffffffffffffffffffffffffffffff81166122c2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e207468617420646f65736e277420657869737400000000000000006064820152608401610360565b507fffffffff0000000000000000000000000000000000000000000000000000000090911660009081526020849052604090206bffffffffffffffffffffffff919091167fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608a901b16179055600101612072565b600285600281111561234c5761234c612e8a565b036127955773ffffffffffffffffffffffffffffffffffffffff8616156123f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d7573742062652061646472657373283029000000000000000000006064820152608401610360565b600388901c6007891660005b86518110156127755760008a900361243d578261241d816135c8565b60008181526001870160205260409020549b5093506007925061244b9050565b81612447816135c8565b9250505b6000806000808a858151811061246357612463613214565b6020908102919091018101517fffffffff0000000000000000000000000000000000000000000000000000000081166000908152918a9052604090912054909150606081901c612535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608401610360565b30606082901c036125c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e0000000000000000000000000000000000006064820152608401610360565b600587901b8f901b94507fffffffff0000000000000000000000000000000000000000000000000000000080861690831614612666577fffffffff000000000000000000000000000000000000000000000000000000008516600090815260208a90526040902080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff83161790555b7fffffffff0000000000000000000000000000000000000000000000000000000091909116600090815260208990526040812055600381901c611fff16925060051b60e01690508582146126fb576000828152600188016020526040902080547fffffffff0000000000000000000000000000000000000000000000000000000080841c19909116908516831c17905561274c565b80837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c817fffffffff0000000000000000000000000000000000000000000000000000000060001b901c198e16179c505b8460000361276a57600086815260018801602052604081208190559c505b505050600101612401565b50806127828360086135fd565b61278c9190613201565b9950505061281d565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560448201527f74416374696f6e000000000000000000000000000000000000000000000000006064820152608401610360565b50959694955050505050565b73ffffffffffffffffffffffffffffffffffffffff8216612848575050565b61286a8260405180606001604052806028815260200161367b60289139612a17565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051612892919061355b565b600060405180830381855af49150503d80600081146128cd576040519150601f19603f3d011682016040523d82523d6000602084013e6128d2565b606091505b509150915081612922578051156128ec5780518082602001fd5b83836040517f192105d7000000000000000000000000000000000000000000000000000000008152600401610360929190613614565b50505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561295f5750600090506003612a0e565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156129b3573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116612a0757600060019250925050612a0e565b9150600090505b94509492505050565b813b8181612922576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103609190613643565b60008083601f840112612a6457600080fd5b50813567ffffffffffffffff811115612a7c57600080fd5b6020830191508360208260051b8501011115611c3457600080fd5b60008060208385031215612aaa57600080fd5b823567ffffffffffffffff811115612ac157600080fd5b612acd85828601612a52565b90969095509350505050565b60008060008060008060608789031215612af257600080fd5b863567ffffffffffffffff80821115612b0a57600080fd5b612b168a838b01612a52565b90985096506020890135915080821115612b2f57600080fd5b612b3b8a838b01612a52565b90965094506040890135915080821115612b5457600080fd5b50612b6189828a01612a52565b979a9699509497509295939492505050565b803573ffffffffffffffffffffffffffffffffffffffff81168114612b9757600080fd5b919050565b600080600080600060608688031215612bb457600080fd5b853567ffffffffffffffff80821115612bcc57600080fd5b612bd889838a01612a52565b9097509550859150612bec60208901612b73565b94506040880135915080821115612c0257600080fd5b818801915088601f830112612c1657600080fd5b813581811115612c2557600080fd5b896020828501011115612c3757600080fd5b9699959850939650602001949392505050565b600060208284031215612c5c57600080fd5b5035919050565b80357fffffffff0000000000000000000000000000000000000000000000000000000081168114612b9757600080fd5b8015158114612ca157600080fd5b50565b60008060408385031215612cb757600080fd5b612cc083612c63565b91506020830135612cd081612c93565b809150509250929050565b60008060408385031215612cee57600080fd5b82359150612cfe60208401612b73565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff81118282101715612d5957612d59612d07565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715612da657612da6612d07565b604052919050565b600067ffffffffffffffff821115612dc857612dc8612d07565b5060051b60200190565b60008060408385031215612de557600080fd5b8235915060208084013567ffffffffffffffff811115612e0457600080fd5b8401601f81018613612e1557600080fd5b8035612e28612e2382612dae565b612d5f565b81815260059190911b82018301908381019088831115612e4757600080fd5b928401925b82841015612e6c57612e5d84612b73565b82529284019290840190612e4c565b80955050505050509250929050565b803560038110612b9757600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60038110612ef0577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b8183526000602080850194508260005b85811015612f49577fffffffff00000000000000000000000000000000000000000000000000000000612f3683612c63565b1687529582019590820190600101612f04565b509495945050505050565b60208082528181018390526000906040808401600586811b8601830188865b8981101561309b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc089840301855281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa18c3603018112612fd457600080fd5b8b01606073ffffffffffffffffffffffffffffffffffffffff612ff683612b73565b168552613004898301612e7b565b6130108a870182612eb9565b50878201357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe183360301811261304557600080fd5b90910188810191903567ffffffffffffffff81111561306357600080fd5b80871b360383131561307457600080fd5b81898701526130868287018285612ef4565b978a0197955050509187019150600101612f73565b50909998505050505050505050565b60006130b8612e2384612dae565b83815260208082019190600586811b8601368111156130d657600080fd5b865b818110156131c557803567ffffffffffffffff808211156130f95760008081fd5b818a0191506060823603121561310f5760008081fd5b613117612d36565b61312083612b73565b815261312d878401612e7b565b87820152604080840135838111156131455760008081fd5b939093019236601f85011261315c57600092508283fd5b8335925061316c612e2384612dae565b83815292871b840188019288810190368511156131895760008081fd5b948901945b848610156131ae5761319f86612c63565b8252948901949089019061318e565b9183019190915250885250509483019483016130d8565b5092979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610c8757610c876131d2565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561325557600080fd5b61325e82612b73565b9392505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261329a57600080fd5b83018035915067ffffffffffffffff8211156132b557600080fd5b602001915036819003821315611c3457600080fd5b600081518084526020808501945080840160005b83811015612f495781517fffffffff0000000000000000000000000000000000000000000000000000000016875295820195908201906001016132de565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000610ee560408301846132ca565b60006020828403121561335d57600080fd5b815161325e81612c93565b81810381811115610c8757610c876131d2565b6000826133b1577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60005b838110156133d15781810151838201526020016133b9565b50506000910152565b600081518084526133f28160208601602086016133b6565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6000606080830181845280875180835260808601915060808160051b87010192506020808a0160005b838110156134d4577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80898703018552815173ffffffffffffffffffffffffffffffffffffffff8151168752838101516134a885890182612eb9565b506040908101519087018890526134c1878901826132ca565b965050938201939082019060010161344d565b505073ffffffffffffffffffffffffffffffffffffffff8916908701525050838103604085015261350581866133da565b979650505050505050565b60006020828403121561352257600080fd5b81516fffffffffffffffffffffffffffffffff8116811461325e57600080fd5b828152604060208201526000610ee560408301846133da565b6000825161356d8184602087016133b6565b9190910192915050565b60006020828403121561358957600080fd5b5051919050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036135c1576135c16131d2565b5060010190565b6000816135d7576135d76131d2565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b8082028115828204841417610c8757610c876131d2565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000610ee560408301846133da565b60208152600061325e60208301846133da56fe4c69624469616d6f6e644375743a2041646420666163657420686173206e6f20636f64654c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a205265706c61636520666163657420686173206e6f20636f6465a2646970667358221220c5a8c10b22f20cde3fe0431ff57305237423677a60888f5b349fc6751336ae1464736f6c63430008150033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100d45760003560e01c806379c0d58d11610081578063afb877bb1161005b578063afb877bb146101d9578063de675a6d146101ec578063e33ecf0a1461023857600080fd5b806379c0d58d14610192578063836d6bfb146101b35780638824a0bb146101c657600080fd5b806326fc3ef4116100b257806326fc3ef4146101145780632f4d98ea1461015c5780633c0985681461017f57600080fd5b806313c34f4b146100d95780631c776dd5146100ee5780631f931c1c14610101575b600080fd5b6100ec6100e7366004612a97565b61024b565b005b6100ec6100fc366004612ad9565b6104df565b6100ec61010f366004612b9c565b610a76565b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9bf546040516fffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b61016f61016a366004612c4a565b610c7b565b6040519015158152602001610153565b6100ec61018d366004612ca4565b610c8d565b6101a56101a0366004612c4a565b610df2565b604051908152602001610153565b61016f6101c1366004612cdb565b610e4c565b6100ec6101d4366004612dd2565b610eed565b6100ec6101e7366004612a97565b610fe1565b6102137f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610153565b6101a5610246366004612a97565b61130e565b3360009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff1615801561028a5750303314155b156102c1576040517f6238ee3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610369576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064015b60405180910390fd5b60008080527f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be6020527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d3906103be848461130e565b60008181526020848152604080832033845290915290205490915060ff16610412576040517fedc5708300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051808201825260008082526020808301828152858352868252848320338452909152908390209151825491517fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000009092169015157fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff161761010067ffffffffffffffff90921691909102179055517f3c3d8c1f0b0faff6fe0ace6b485d0595a0106dce9e303f956fd941ebdbe9a98e906104d19086908690612f54565b60405180910390a150505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610582576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b8281146105bb576040517fe854148500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6105cd6105c886886130aa565b611435565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b754600003610650576040517fa788861700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061065c878761130e565b905061069a8585808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506115b392505050565b506106d881868680806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250610eed92505050565b60006106e382610c7b565b90506000816106f35760016106f6565b60005b60ff169050806107046116d0565b61070e9190613201565b61071784610df2565b6107219088613201565b1015610759576040517f709fb08000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805b878110156109a0576107d989898381811061077a5761077a613214565b905060200201602081019061078f9190613243565b73ffffffffffffffffffffffffffffffffffffffff1660009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff1690565b1580156108225750308989838181106107f4576107f4613214565b90506020020160208101906108099190613243565b73ffffffffffffffffffffffffffffffffffffffff1614155b15610859576040517f7b2cbbb400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3089898381811061086c5761086c613214565b90506020020160208101906108819190613243565b73ffffffffffffffffffffffffffffffffffffffff16036108d95783156108d4576040517fee21708000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600191505b6109628989838181106108ee576108ee613214565b90506020020160208101906109039190613243565b8689898581811061091657610916613214565b90506020028101906109289190613265565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061174f92505050565b610998576040517fac3d341600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60010161075d565b50801580156109ad575082155b156109e4576040517f6d21730400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9bf80546fffffffffffffffffffffffffffffffff808216600101167fffffffffffffffffffffffffffffffff00000000000000000000000000000000909116179055610a6a610a538a8c6130aa565b6000604051806020016040528060008152506117ca565b50505050505050505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610b19576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b610b2161195f565b610b2e6105c885876130aa565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75415610baf576040517fa788861700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff831615610bfd576040517f871cb76100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be5b600190810180547fffffffffffffffffffffffffffffffff0000000000000000000000000000000081166fffffffffffffffffffffffffffffffff91821690930116919091179055610c74610a5385876130aa565b5050505050565b6000610c878230610e4c565b92915050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610d30576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b610d3861195f565b7fffffffff00000000000000000000000000000000000000000000000000000000821660008181527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4922602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001685151590811790915582519384529083015280517f4e6bd17989efa6d6a9607ccaac1bba27b29f99622bc830d99a3a9883b21a19c79281900390910190a15050565b600080610dfd6119ca565b805190915060005b81811015610e4457610e3085848381518110610e2357610e23613214565b6020026020010151610e4c565b15610e3c578360010193505b600101610e05565b505050919050565b60008281527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d36020818152604080842073ffffffffffffffffffffffffffffffffffffffff8616855290915282205460ff168015610ee5575060008481526020828152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152902054610100900467ffffffffffffffff1642105b949350505050565b6000610ef76119ca565b805183519192509060005b82811015610fd957610f2086858381518110610e2357610e23613214565b15610fd15760005b82811015610fcf57848281518110610f4257610f42613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16868281518110610f7257610f72613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603610fc7576040517f50f5729f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600101610f28565b505b600101610f02565b505050505050565b3360009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff161580156110205750303314155b15611057576040517f6238ee3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff9081164290911610156110fa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75460000361117d576040517f3a76e1f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080527f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be6020527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d36111d36105c883856130aa565b60006111df848461130e565b905060006111eb611af4565b6111f59042613201565b6040805180820182526001815267ffffffffffffffff838116602080840191825260008881528982528581203382529091528490209251835491517fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000009092169015157fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff16176101009190921602179055519091507f6248ff757895beed7d43d135bccf59a26b7fbdf0fe8233487c44e82c0f266ba3906112b89087908790612f54565b60405180910390a16112c86116d0565b6112d183610df2565b101580156112e357506112e382610c7b565b15610c74577f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be610c1f565b60008282604051602001611323929190612f54565b6040516020818303038152906040528051906020012030466113627f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be90565b6001015460408051602081019590955273ffffffffffffffffffffffffffffffffffffffff9093169284019290925260608301526fffffffffffffffffffffffffffffffff16608082015260a001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905280516020918201207f19457468657265756d205369676e6564204d6573736167653a0a33320000000091830191909152603c820152605c0160405160208183030381529060405280519060200120905092915050565b805160005b818110156115ae57600083828151811061145657611456613214565b602002602001015160200151600281111561147357611473612e8a565b14806114ad5750600183828151811061148e5761148e613214565b60200260200101516020015160028111156114ab576114ab612e8a565b145b156115a657600254835173ffffffffffffffffffffffffffffffffffffffff9091169063df871f72908590849081106114e8576114e8613214565b60200260200101516000015185848151811061150657611506613214565b6020026020010151604001516040518363ffffffff1660e01b815260040161152f92919061331c565b602060405180830381865afa15801561154c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611570919061334b565b6115a6576040517ff41a931c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60010161143a565b505050565b80516000908082036115f1576040517f3aee2eec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b6115ff600183613368565b8110156116c6576000611613826001613201565b90505b828110156116bd5784818151811061163057611630613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1685838151811061166057611660613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16036116b5576040517f8dd19e7d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600101611616565b506001016115f4565b5060009392505050565b600080611723600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75490565b905080156117465761173660028261337b565b611741906001613201565b611749565b60005b91505090565b600080600061175e8585611bf6565b9092509050600081600481111561177757611777612e8a565b1480156117af57508573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b806117c057506117c0868686611c3b565b9695505050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921547f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff8116908190600090600716156118395750600381901c60009081526001840160205260409020545b60005b87518110156118b6576118a983838a848151811061185c5761185c613214565b6020026020010151600001518b858151811061187a5761187a613214565b6020026020010151602001518c868151811061189857611898613214565b602002602001015160400151611d98565b909350915060010161183c565b508282146118ef576002840180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff84161790555b600782161561191157600382901c600090815260018501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb67387878760405161194493929190613424565b60405180910390a16119568686612829565b50505050505050565b3330146119c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4c69624469616d6f6e643a2043616c6c6572206e6f742073656c6600000000006044820152606401610360565b565b60008080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b780546060929067ffffffffffffffff811115611a3257611a32612d07565b604051908082528060200260200182016040528015611a5b578160200160208202803683370190505b50825490915060005b81811015611aeb57836000018181548110611a8157611a81613214565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16838281518110611abe57611abe613214565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101611a64565b50909392505050565b6040517f52430c8d0000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906352430c8d90602401602060405180830381865afa158015611b81573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ba59190613510565b6fffffffffffffffffffffffffffffffff16905060008111611bf3576040517fdac5ec8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b90565b6000808251604103611c2c5760208301516040840151606085015160001a611c2087828585612928565b94509450505050611c34565b506000905060025b9250929050565b60008060008573ffffffffffffffffffffffffffffffffffffffff16631626ba7e60e01b8686604051602401611c72929190613542565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909416939093179092529051611cfb919061355b565b600060405180830381855afa9150503d8060008114611d36576040519150601f19603f3d011682016040523d82523d6000602084013e611d3b565b606091505b5091509150818015611d4f57506020815110155b80156117c0575080517f1626ba7e0000000000000000000000000000000000000000000000000000000090611d8d9083016020908101908401613577565b149695505050505050565b600080807f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f90506000845111611e50576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610360565b6000856002811115611e6457611e64612e8a565b0361203457611e8b8660405180606001604052806024815260200161365760249139612a17565b60005b845181101561202e576000858281518110611eab57611eab613214565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c15611f7e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c72656164792065786973747300000000000000000000006064820152608401610360565b7fffffffff0000000000000000000000000000000000000000000000000000000080831660008181526020879052604090207fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608d901b168e17905560e060058e901b811692831c199c909c1690821c179a8190036120125760038c901c600090815260018601602052604081209b909b555b8b61201c81613590565b9c505060019093019250611e8e915050565b5061281d565b600185600281111561204857612048612e8a565b036123385761206f866040518060600160405280602881526020016136a360289139612a17565b60005b845181101561202e57600085828151811061208f5761208f613214565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c308103612164576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4c69624469616d6f6e644375743a2043616e2774207265706c61636520696d6d60448201527f757461626c652066756e6374696f6e00000000000000000000000000000000006064820152608401610360565b8973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361221f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e00000000000000006064820152608401610360565b73ffffffffffffffffffffffffffffffffffffffff81166122c2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e207468617420646f65736e277420657869737400000000000000006064820152608401610360565b507fffffffff0000000000000000000000000000000000000000000000000000000090911660009081526020849052604090206bffffffffffffffffffffffff919091167fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608a901b16179055600101612072565b600285600281111561234c5761234c612e8a565b036127955773ffffffffffffffffffffffffffffffffffffffff8616156123f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d7573742062652061646472657373283029000000000000000000006064820152608401610360565b600388901c6007891660005b86518110156127755760008a900361243d578261241d816135c8565b60008181526001870160205260409020549b5093506007925061244b9050565b81612447816135c8565b9250505b6000806000808a858151811061246357612463613214565b6020908102919091018101517fffffffff0000000000000000000000000000000000000000000000000000000081166000908152918a9052604090912054909150606081901c612535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608401610360565b30606082901c036125c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e0000000000000000000000000000000000006064820152608401610360565b600587901b8f901b94507fffffffff0000000000000000000000000000000000000000000000000000000080861690831614612666577fffffffff000000000000000000000000000000000000000000000000000000008516600090815260208a90526040902080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff83161790555b7fffffffff0000000000000000000000000000000000000000000000000000000091909116600090815260208990526040812055600381901c611fff16925060051b60e01690508582146126fb576000828152600188016020526040902080547fffffffff0000000000000000000000000000000000000000000000000000000080841c19909116908516831c17905561274c565b80837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c817fffffffff0000000000000000000000000000000000000000000000000000000060001b901c198e16179c505b8460000361276a57600086815260018801602052604081208190559c505b505050600101612401565b50806127828360086135fd565b61278c9190613201565b9950505061281d565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560448201527f74416374696f6e000000000000000000000000000000000000000000000000006064820152608401610360565b50959694955050505050565b73ffffffffffffffffffffffffffffffffffffffff8216612848575050565b61286a8260405180606001604052806028815260200161367b60289139612a17565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051612892919061355b565b600060405180830381855af49150503d80600081146128cd576040519150601f19603f3d011682016040523d82523d6000602084013e6128d2565b606091505b509150915081612922578051156128ec5780518082602001fd5b83836040517f192105d7000000000000000000000000000000000000000000000000000000008152600401610360929190613614565b50505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561295f5750600090506003612a0e565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156129b3573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116612a0757600060019250925050612a0e565b9150600090505b94509492505050565b813b8181612922576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103609190613643565b60008083601f840112612a6457600080fd5b50813567ffffffffffffffff811115612a7c57600080fd5b6020830191508360208260051b8501011115611c3457600080fd5b60008060208385031215612aaa57600080fd5b823567ffffffffffffffff811115612ac157600080fd5b612acd85828601612a52565b90969095509350505050565b60008060008060008060608789031215612af257600080fd5b863567ffffffffffffffff80821115612b0a57600080fd5b612b168a838b01612a52565b90985096506020890135915080821115612b2f57600080fd5b612b3b8a838b01612a52565b90965094506040890135915080821115612b5457600080fd5b50612b6189828a01612a52565b979a9699509497509295939492505050565b803573ffffffffffffffffffffffffffffffffffffffff81168114612b9757600080fd5b919050565b600080600080600060608688031215612bb457600080fd5b853567ffffffffffffffff80821115612bcc57600080fd5b612bd889838a01612a52565b9097509550859150612bec60208901612b73565b94506040880135915080821115612c0257600080fd5b818801915088601f830112612c1657600080fd5b813581811115612c2557600080fd5b896020828501011115612c3757600080fd5b9699959850939650602001949392505050565b600060208284031215612c5c57600080fd5b5035919050565b80357fffffffff0000000000000000000000000000000000000000000000000000000081168114612b9757600080fd5b8015158114612ca157600080fd5b50565b60008060408385031215612cb757600080fd5b612cc083612c63565b91506020830135612cd081612c93565b809150509250929050565b60008060408385031215612cee57600080fd5b82359150612cfe60208401612b73565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff81118282101715612d5957612d59612d07565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715612da657612da6612d07565b604052919050565b600067ffffffffffffffff821115612dc857612dc8612d07565b5060051b60200190565b60008060408385031215612de557600080fd5b8235915060208084013567ffffffffffffffff811115612e0457600080fd5b8401601f81018613612e1557600080fd5b8035612e28612e2382612dae565b612d5f565b81815260059190911b82018301908381019088831115612e4757600080fd5b928401925b82841015612e6c57612e5d84612b73565b82529284019290840190612e4c565b80955050505050509250929050565b803560038110612b9757600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60038110612ef0577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b8183526000602080850194508260005b85811015612f49577fffffffff00000000000000000000000000000000000000000000000000000000612f3683612c63565b1687529582019590820190600101612f04565b509495945050505050565b60208082528181018390526000906040808401600586811b8601830188865b8981101561309b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc089840301855281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa18c3603018112612fd457600080fd5b8b01606073ffffffffffffffffffffffffffffffffffffffff612ff683612b73565b168552613004898301612e7b565b6130108a870182612eb9565b50878201357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe183360301811261304557600080fd5b90910188810191903567ffffffffffffffff81111561306357600080fd5b80871b360383131561307457600080fd5b81898701526130868287018285612ef4565b978a0197955050509187019150600101612f73565b50909998505050505050505050565b60006130b8612e2384612dae565b83815260208082019190600586811b8601368111156130d657600080fd5b865b818110156131c557803567ffffffffffffffff808211156130f95760008081fd5b818a0191506060823603121561310f5760008081fd5b613117612d36565b61312083612b73565b815261312d878401612e7b565b87820152604080840135838111156131455760008081fd5b939093019236601f85011261315c57600092508283fd5b8335925061316c612e2384612dae565b83815292871b840188019288810190368511156131895760008081fd5b948901945b848610156131ae5761319f86612c63565b8252948901949089019061318e565b9183019190915250885250509483019483016130d8565b5092979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610c8757610c876131d2565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561325557600080fd5b61325e82612b73565b9392505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261329a57600080fd5b83018035915067ffffffffffffffff8211156132b557600080fd5b602001915036819003821315611c3457600080fd5b600081518084526020808501945080840160005b83811015612f495781517fffffffff0000000000000000000000000000000000000000000000000000000016875295820195908201906001016132de565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000610ee560408301846132ca565b60006020828403121561335d57600080fd5b815161325e81612c93565b81810381811115610c8757610c876131d2565b6000826133b1577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60005b838110156133d15781810151838201526020016133b9565b50506000910152565b600081518084526133f28160208601602086016133b6565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6000606080830181845280875180835260808601915060808160051b87010192506020808a0160005b838110156134d4577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80898703018552815173ffffffffffffffffffffffffffffffffffffffff8151168752838101516134a885890182612eb9565b506040908101519087018890526134c1878901826132ca565b965050938201939082019060010161344d565b505073ffffffffffffffffffffffffffffffffffffffff8916908701525050838103604085015261350581866133da565b979650505050505050565b60006020828403121561352257600080fd5b81516fffffffffffffffffffffffffffffffff8116811461325e57600080fd5b828152604060208201526000610ee560408301846133da565b6000825161356d8184602087016133b6565b9190910192915050565b60006020828403121561358957600080fd5b5051919050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036135c1576135c16131d2565b5060010190565b6000816135d7576135d76131d2565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b8082028115828204841417610c8757610c876131d2565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000610ee560408301846133da565b60208152600061325e60208301846133da56fe4c69624469616d6f6e644375743a2041646420666163657420686173206e6f20636f64654c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a205265706c61636520666163657420686173206e6f20636f6465a2646970667358221220c5a8c10b22f20cde3fe0431ff57305237423677a60888f5b349fc6751336ae1464736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "Responsible for adding/removing/replace facets in Barz", + "kind": "dev", + "methods": { + "_checkDuplicateOnChainApprover(bytes32,address[])": { + "params": { + "_approvers": "List of approver addresses", + "_diamondCutHash": "Hash of diamondCut information including the facet addresses and function selectors" + } + }, + "approveDiamondCut((address,uint8,bytes4[])[])": { + "params": { + "_diamondCut": "Contains the facet addresses and function selectors" + } + }, + "constructor": { + "params": { + "_securityManager": "Security Manager contract that holds the security related variables for all wallets" + } + }, + "diamondCut((address,uint8,bytes4[])[],address,bytes)": { + "params": { + "_diamondCut": "Contains the facet addresses and function selectors", + "_init": "The address of the contract or facet to execute _calldata. It's prohibited in Barz" + } + }, + "diamondCutWithGuardian((address,uint8,bytes4[])[],address[],bytes[])": { + "params": { + "_approvers": "Guardian or owner address that approves the diamond cut", + "_diamondCut": "Contains the facet addresses and function selectors", + "_signatures": "Signature of Guardians or owner that approves the diamond cut" + } + }, + "getDiamondCutApprovalCountWithTimeValidity(bytes32)": { + "params": { + "_diamondCutHash": "Hash of diamondCut information including the facet addresses and function selectors" + } + }, + "getDiamondCutHash((address,uint8,bytes4[])[])": { + "params": { + "_diamondCut": "Contains the facet addresses and function selectors" + }, + "returns": { + "cutHash": "Diamond Cut Hash" + } + }, + "getDiamondCutNonce()": { + "details": "This method fetches the nonce from diamond cut storage", + "returns": { + "cutNonce": "Nonce of diamond cut to protect from reply attacks" + } + }, + "getOwnerCutApprovalWithTimeValidity(bytes32)": { + "params": { + "_diamondCutHash": "Hash of diamondCut information including the facet addresses and function selectors" + }, + "returns": { + "isApprovedByOwner": "Bool value showing if the owner approved the cut" + } + }, + "isCutApproved(bytes32,address)": { + "params": { + "_approver": "Address of approver", + "_diamondCutHash": "Hash of diamondCut information including the facet addresses and function selectors" + }, + "returns": { + "isApproved": "Bool value showing if the approver approved the cut" + } + }, + "revokeDiamondCutApproval((address,uint8,bytes4[])[])": { + "params": { + "_diamondCut": "Contains the facet addresses and function selectors" + } + }, + "updateSupportsInterface(bytes4,bool)": { + "params": { + "_flag": "Bool value to update the mapping of the given interface ID", + "_interfaceId": "InterfaceID to update the mapping" + } + } + }, + "title": "DiamondCut Facet", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "_checkDuplicateOnChainApprover(bytes32,address[])": { + "notice": "Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval Approvers who approved on-chain should not be included in the off-chain approval" + }, + "approveDiamondCut((address,uint8,bytes4[])[])": { + "notice": "Approves diamond cut. This can only be called directly from guardian or owner" + }, + "constructor": { + "notice": "This constructor sets the Security Manager address which is an immutable variable. Immutable variables do not impact the storage of diamond" + }, + "diamondCut((address,uint8,bytes4[])[],address,bytes)": { + "notice": "Add/replace/remove any number of functions and optionally execute a function with delegatecall when guardians don't exist" + }, + "diamondCutWithGuardian((address,uint8,bytes4[])[],address[],bytes[])": { + "notice": "Add/replace/remove any number of functions and optionally execute a function with delegatecall when guardians exist" + }, + "getDiamondCutApprovalCountWithTimeValidity(bytes32)": { + "notice": "Gets the number of approvals of diamond cut from guardians" + }, + "getDiamondCutHash((address,uint8,bytes4[])[])": { + "notice": "Returns the diamond cut hash. This function ensures that this hash is safe from replay attack by including salt, address, chainId, and nonce, etc." + }, + "getDiamondCutNonce()": { + "notice": "Returns the diamond cut nonce of this wallet" + }, + "getOwnerCutApprovalWithTimeValidity(bytes32)": { + "notice": "Returns if the owner has approved the diamond cut" + }, + "isCutApproved(bytes32,address)": { + "notice": "Returns if the given approver has approved the diamond cut" + }, + "revokeDiamondCutApproval((address,uint8,bytes4[])[])": { + "notice": "Revokes the approval of diamond cut. This can only be called directly from guardian or owner" + }, + "updateSupportsInterface(bytes4,bool)": { + "notice": "Updates the flag for the interfaceId" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 27866, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "s", + "offset": 0, + "slot": "0", + "type": "t_struct(AppStorage)27613_storage" + } + ], + "types": { + "t_bytes4": { + "encoding": "inplace", + "label": "bytes4", + "numberOfBytes": "4" + }, + "t_contract(IEntryPoint)12286": { + "encoding": "inplace", + "label": "contract IEntryPoint", + "numberOfBytes": "20" + }, + "t_contract(IFacetRegistry)26148": { + "encoding": "inplace", + "label": "contract IFacetRegistry", + "numberOfBytes": "20" + }, + "t_mapping(t_uint256,t_struct(InitializersStorage)27592_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => struct InitializersStorage)", + "numberOfBytes": "32", + "value": "t_struct(InitializersStorage)27592_storage" + }, + "t_mapping(t_uint256,t_struct(Lock)27585_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => struct Lock)", + "numberOfBytes": "32", + "value": "t_struct(Lock)27585_storage" + }, + "t_struct(AppStorage)27613_storage": { + "encoding": "inplace", + "label": "struct AppStorage", + "members": [ + { + "astId": 27597, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "initStorage", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_uint256,t_struct(InitializersStorage)27592_storage)" + }, + { + "astId": 27599, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "signerMigration", + "offset": 0, + "slot": "1", + "type": "t_uint8" + }, + { + "astId": 27601, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "validateOwnerSignatureSelector", + "offset": 1, + "slot": "1", + "type": "t_bytes4" + }, + { + "astId": 27604, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "entryPoint", + "offset": 5, + "slot": "1", + "type": "t_contract(IEntryPoint)12286" + }, + { + "astId": 27607, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "facetRegistry", + "offset": 0, + "slot": "2", + "type": "t_contract(IFacetRegistry)26148" + }, + { + "astId": 27612, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "locks", + "offset": 0, + "slot": "3", + "type": "t_mapping(t_uint256,t_struct(Lock)27585_storage)" + } + ], + "numberOfBytes": "128" + }, + "t_struct(InitializersStorage)27592_storage": { + "encoding": "inplace", + "label": "struct InitializersStorage", + "members": [ + { + "astId": 27587, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "signerInitialized", + "offset": 0, + "slot": "0", + "type": "t_uint8" + }, + { + "astId": 27589, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "accountInitialized", + "offset": 1, + "slot": "0", + "type": "t_uint8" + }, + { + "astId": 27591, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "restrictionsInitialized", + "offset": 2, + "slot": "0", + "type": "t_uint8" + } + ], + "numberOfBytes": "32" + }, + "t_struct(Lock)27585_storage": { + "encoding": "inplace", + "label": "struct Lock", + "members": [ + { + "astId": 27582, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "release", + "offset": 0, + "slot": "0", + "type": "t_uint64" + }, + { + "astId": 27584, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "locker", + "offset": 8, + "slot": "0", + "type": "t_bytes4" + } + ], + "numberOfBytes": "32" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint64": { + "encoding": "inplace", + "label": "uint64", + "numberOfBytes": "8" + }, + "t_uint8": { + "encoding": "inplace", + "label": "uint8", + "numberOfBytes": "1" + } + } + } +} \ No newline at end of file diff --git a/deployments/mantle/DiamondLoupeFacet.json b/deployments/mantle/DiamondLoupeFacet.json new file mode 100644 index 0000000..7b0ed80 --- /dev/null +++ b/deployments/mantle/DiamondLoupeFacet.json @@ -0,0 +1,290 @@ +{ + "address": "0xCe36b85d12D81cd619C745c7717f3396E184Ac7C", + "abi": [ + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_functionSelector", + "type": "bytes4" + } + ], + "name": "facetAddress", + "outputs": [ + { + "internalType": "address", + "name": "facetAddress_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_functionSelector", + "type": "bytes4" + } + ], + "name": "facetAddressFromStorage", + "outputs": [ + { + "internalType": "address", + "name": "facetAddress_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetAddresses", + "outputs": [ + { + "internalType": "address[]", + "name": "facetAddresses_", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetAddressesFromStorage", + "outputs": [ + { + "internalType": "address[]", + "name": "facetAddresses_", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_facet", + "type": "address" + } + ], + "name": "facetFunctionSelectors", + "outputs": [ + { + "internalType": "bytes4[]", + "name": "facetFunctionSelectors_", + "type": "bytes4[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_facet", + "type": "address" + } + ], + "name": "facetFunctionSelectorsFromStorage", + "outputs": [ + { + "internalType": "bytes4[]", + "name": "facetFunctionSelectors_", + "type": "bytes4[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facets", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondLoupe.Facet[]", + "name": "facets_", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetsFromStorage", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondLoupe.Facet[]", + "name": "facets_", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "isSupported", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "args": [], + "numDeployments": 1, + "solcInputHash": "ad34345aa73d96f52b3e14df983b6b29", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_functionSelector\",\"type\":\"bytes4\"}],\"name\":\"facetAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"facetAddress_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_functionSelector\",\"type\":\"bytes4\"}],\"name\":\"facetAddressFromStorage\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"facetAddress_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetAddresses\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"facetAddresses_\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetAddressesFromStorage\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"facetAddresses_\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_facet\",\"type\":\"address\"}],\"name\":\"facetFunctionSelectors\",\"outputs\":[{\"internalType\":\"bytes4[]\",\"name\":\"facetFunctionSelectors_\",\"type\":\"bytes4[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_facet\",\"type\":\"address\"}],\"name\":\"facetFunctionSelectorsFromStorage\",\"outputs\":[{\"internalType\":\"bytes4[]\",\"name\":\"facetFunctionSelectors_\",\"type\":\"bytes4[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facets\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondLoupe.Facet[]\",\"name\":\"facets_\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetsFromStorage\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondLoupe.Facet[]\",\"name\":\"facets_\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isSupported\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"DiamondLoupe contract compatible with EIP-2535\",\"kind\":\"dev\",\"methods\":{\"facetAddress(bytes4)\":{\"details\":\"If facet is not found return address(0).\",\"params\":{\"_functionSelector\":\"The function selector.\"},\"returns\":{\"facetAddress_\":\"The facet address.\"}},\"facetAddressFromStorage(bytes4)\":{\"params\":{\"_functionSelector\":\"Function selector to fetch the facet address from diamond storage\"},\"returns\":{\"facetAddress_\":\"Facet address mapped with the function selector\"}},\"facetAddresses()\":{\"returns\":{\"facetAddresses_\":\"facetAddresses_\"}},\"facetAddressesFromStorage()\":{\"returns\":{\"facetAddresses_\":\"All facet addresses attached directly to diamond storage\"}},\"facetFunctionSelectors(address)\":{\"params\":{\"_facet\":\"The facet address.\"},\"returns\":{\"facetFunctionSelectors_\":\"facetFunctionSelectors_\"}},\"facetFunctionSelectorsFromStorage(address)\":{\"params\":{\"_facet\":\"Facet address to fetch the facet function selectors from diamond storage\"},\"returns\":{\"facetFunctionSelectors_\":\"Facet function selectors of the given facet address\"}},\"facets()\":{\"details\":\"Barz uses a special architecture called default fallback handler. Default Fallback handler is used as a middleware that holds the mapping of facet function selector and facet address that Barz uses. This helps Barz to reduce significant amount of gas during the initialization process. Hence, this method aggregates both the facet information from DefaulFallbackHandler and in diamond storage and shows the data to users.\",\"returns\":{\"facets_\":\"Facet\"}},\"facetsFromStorage()\":{\"returns\":{\"facets_\":\"Facet information attached directly to diamond storage\"}},\"supportsInterface(bytes4)\":{\"params\":{\"_interfaceId\":\"Interface ID for detecting the interface\"},\"returns\":{\"isSupported\":\"Bool value showing if the standard is supported in the contract\"}}},\"title\":\"DiamondLoupe Facet\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"facetAddress(bytes4)\":{\"notice\":\"Gets the facet that supports the given selector.\"},\"facetAddressFromStorage(bytes4)\":{\"notice\":\"Returns the facet address attached to the given function selector. This excludes the facets from the default fallback handler\"},\"facetAddresses()\":{\"notice\":\"Get all the facet addresses used by Barz.\"},\"facetAddressesFromStorage()\":{\"notice\":\"Returns all facet addresses attached directly to diamond storage. This excludes the facets from the default fallback handler\"},\"facetFunctionSelectors(address)\":{\"notice\":\"Gets all the function selectors provided by a facet.\"},\"facetFunctionSelectorsFromStorage(address)\":{\"notice\":\"Returns function selectors of given facet address attached directly to diamond storage. This excludes the facets from the default fallback handler\"},\"facets()\":{\"notice\":\"Gets all facets and their selectors.\"},\"facetsFromStorage()\":{\"notice\":\"Returns the facet from the diamond storage. This excludes the facets from the default fallback handler\"},\"supportsInterface(bytes4)\":{\"notice\":\"SupportInterface to be compatible with EIP 165\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/base/DiamondLoupeFacet.sol\":\"DiamondLoupeFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/introspection/IERC165.sol\\\";\\n\\n/**\\n * @dev _Available since v3.1._\\n */\\ninterface IERC1155Receiver is IERC165 {\\n /**\\n * @dev Handles the receipt of a single ERC1155 token type. This function is\\n * called at the end of a `safeTransferFrom` after the balance has been updated.\\n *\\n * NOTE: To accept the transfer, this must return\\n * `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))`\\n * (i.e. 0xf23a6e61, or its own function selector).\\n *\\n * @param operator The address which initiated the transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param id The ID of the token being transferred\\n * @param value The amount of tokens being transferred\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155Received(\\n address operator,\\n address from,\\n uint256 id,\\n uint256 value,\\n bytes calldata data\\n ) external returns (bytes4);\\n\\n /**\\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\\n * is called at the end of a `safeBatchTransferFrom` after the balances have\\n * been updated.\\n *\\n * NOTE: To accept the transfer(s), this must return\\n * `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))`\\n * (i.e. 0xbc197c81, or its own function selector).\\n *\\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155BatchReceived(\\n address operator,\\n address from,\\n uint256[] calldata ids,\\n uint256[] calldata values,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xeb373f1fdc7b755c6a750123a9b9e3a8a02c1470042fd6505d875000a80bde0b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title ERC721 token receiver interface\\n * @dev Interface for any contract that wants to support safeTransfers\\n * from ERC721 asset contracts.\\n */\\ninterface IERC721Receiver {\\n /**\\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\\n * by `operator` from `from`, this function is called.\\n *\\n * It must return its Solidity selector to confirm the token transfer.\\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\\n *\\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\\n */\\n function onERC721Received(\\n address operator,\\n address from,\\n uint256 tokenId,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\\n *\\n * Accounts can be notified of {IERC777} tokens being sent to them by having a\\n * contract implement this interface (contract holders can be their own\\n * implementer) and registering it on the\\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\\n *\\n * See {IERC1820Registry} and {ERC1820Implementer}.\\n */\\ninterface IERC777Recipient {\\n /**\\n * @dev Called by an {IERC777} token contract whenever tokens are being\\n * moved or created into a registered account (`to`). The type of operation\\n * is conveyed by `from` being the zero address or not.\\n *\\n * This call occurs _after_ the token contract's state is updated, so\\n * {IERC777-balanceOf}, etc., can be used to query the post-operation state.\\n *\\n * This function may revert to prevent the operation from being executed.\\n */\\n function tokensReceived(\\n address operator,\\n address from,\\n address to,\\n uint256 amount,\\n bytes calldata userData,\\n bytes calldata operatorData\\n ) external;\\n}\\n\",\"keccak256\":\"0x1a5d61db2733202ba361e6d6741cd2e662380e22b80e987eacfc91973f2267dc\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"contracts/facets/base/DiamondLoupeFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IERC777Recipient} from \\\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\\\";\\nimport {IERC165} from \\\"../../interfaces/ERC/IERC165.sol\\\";\\nimport {IERC1271} from \\\"../../interfaces/ERC/IERC1271.sol\\\";\\nimport {IERC677Receiver} from \\\"../../interfaces/ERC/IERC677Receiver.sol\\\";\\nimport {IERC721Receiver} from \\\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\\\";\\nimport {IERC1155Receiver} from \\\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\\\";\\nimport {LibDiamond} from \\\"../../libraries/LibDiamond.sol\\\";\\nimport {LibLoupe} from \\\"../../libraries/LibLoupe.sol\\\";\\nimport {LibUtils} from \\\"../../libraries/LibUtils.sol\\\";\\nimport {IDiamondCut} from \\\"../../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IStorageLoupe} from \\\"./interfaces/IStorageLoupe.sol\\\";\\nimport {IDiamondLoupe} from \\\"./interfaces/IDiamondLoupe.sol\\\";\\n\\n/**\\n * @title DiamondLoupe Facet\\n * @dev DiamondLoupe contract compatible with EIP-2535\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract DiamondLoupeFacet is IDiamondLoupe, IStorageLoupe, IERC165 {\\n // Diamond Loupe Functions\\n ////////////////////////////////////////////////////////////////////\\n /// These functions are expected to be called frequently by tools off-chain.\\n\\n /**\\n * @notice Gets all facets and their selectors.\\n * @dev Barz uses a special architecture called default fallback handler. Default Fallback handler is used as a middleware\\n * that holds the mapping of facet function selector and facet address that Barz uses. This helps Barz to reduce\\n * significant amount of gas during the initialization process.\\n * Hence, this method aggregates both the facet information from DefaulFallbackHandler and in diamond storage and shows the data to users.\\n * @return facets_ Facet\\n */\\n function facets() public view override returns (Facet[] memory facets_) {\\n Facet[] memory defaultFacet = LibDiamond\\n .diamondStorage()\\n .defaultFallbackHandler\\n .facets();\\n Facet[] memory _facets = LibLoupe.facets();\\n uint256 numFacets = _facets.length;\\n bytes4[] memory keys;\\n address[] memory values;\\n for (uint256 i; i < numFacets; ) {\\n uint256 selectorsLength = _facets[i].functionSelectors.length;\\n for (uint256 j; j < selectorsLength; ) {\\n (keys, values) = LibUtils.setValue(\\n keys,\\n values,\\n _facets[i].functionSelectors[j],\\n _facets[i].facetAddress\\n );\\n unchecked {\\n ++j;\\n }\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n {\\n bool iIncrement;\\n for (uint256 i; i < defaultFacet.length; ) {\\n bool jIncrement;\\n for (\\n uint256 j;\\n j < defaultFacet[i].functionSelectors.length;\\n\\n ) {\\n if (\\n LibUtils.getValue(\\n keys,\\n values,\\n defaultFacet[i].functionSelectors[j]\\n ) != address(0)\\n ) {\\n if (defaultFacet[i].functionSelectors.length == 1) {\\n defaultFacet = LibUtils.removeFacetElement(\\n defaultFacet,\\n i\\n );\\n iIncrement = true;\\n break;\\n }\\n defaultFacet[i].functionSelectors = LibUtils\\n .removeElement(\\n defaultFacet[i].functionSelectors,\\n j\\n );\\n jIncrement = true;\\n }\\n if (!jIncrement) {\\n unchecked {\\n ++j;\\n }\\n } else {\\n jIncrement = false;\\n }\\n }\\n if (!iIncrement) {\\n unchecked {\\n ++i;\\n }\\n } else {\\n iIncrement = false;\\n }\\n }\\n }\\n {\\n uint256 facetLength = numFacets + defaultFacet.length;\\n facets_ = new Facet[](facetLength);\\n uint256 defaultFacetIndex;\\n for (uint256 i; i < facetLength; ) {\\n if (i < numFacets) {\\n facets_[i] = _facets[i];\\n bool jIncrementor;\\n for (uint256 j; j < defaultFacet.length; ) {\\n if (\\n facets_[i].facetAddress ==\\n defaultFacet[j].facetAddress\\n ) {\\n facets_[i].functionSelectors = LibUtils.mergeArrays(\\n _facets[i].functionSelectors,\\n defaultFacet[j].functionSelectors\\n );\\n defaultFacet = LibUtils.removeFacetElement(\\n defaultFacet,\\n j\\n );\\n jIncrementor = true;\\n {\\n facets_ = LibUtils.removeFacetElement(\\n facets_,\\n facets_.length - 1\\n );\\n }\\n --facetLength;\\n }\\n if (!jIncrementor) {\\n unchecked {\\n ++j;\\n }\\n } else {\\n jIncrementor = false;\\n }\\n }\\n } else {\\n facets_[i] = defaultFacet[defaultFacetIndex];\\n ++defaultFacetIndex;\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n }\\n\\n /**\\n * @notice Gets all the function selectors provided by a facet.\\n * @param _facet The facet address.\\n * @return facetFunctionSelectors_\\n */\\n function facetFunctionSelectors(\\n address _facet\\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\\n Facet[] memory facet = facets();\\n uint256 facetLength = facet.length;\\n for (uint256 i; i < facetLength; ) {\\n if (facet[i].facetAddress == _facet)\\n return facet[i].functionSelectors;\\n unchecked {\\n ++i;\\n }\\n }\\n return facetFunctionSelectors_;\\n }\\n\\n /**\\n * @notice Get all the facet addresses used by Barz.\\n * @return facetAddresses_\\n */\\n function facetAddresses()\\n external\\n view\\n override\\n returns (address[] memory facetAddresses_)\\n {\\n Facet[] memory facet = facets();\\n uint256 facetLength = facet.length;\\n facetAddresses_ = new address[](facetLength);\\n for (uint256 i; i < facetLength; ) {\\n facetAddresses_[i] = facet[i].facetAddress;\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * @notice Gets the facet that supports the given selector.\\n * @dev If facet is not found return address(0).\\n * @param _functionSelector The function selector.\\n * @return facetAddress_ The facet address.\\n */\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view override returns (address facetAddress_) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n\\n facetAddress_ = address(bytes20(ds.facets[_functionSelector]));\\n if (facetAddress_ == address(0)) {\\n facetAddress_ = IDiamondLoupe(ds.defaultFallbackHandler)\\n .facetAddress(_functionSelector);\\n }\\n }\\n\\n /**\\n * @notice SupportInterface to be compatible with EIP 165\\n * @param _interfaceId Interface ID for detecting the interface\\n * @return isSupported Bool value showing if the standard is supported in the contract\\n */\\n function supportsInterface(\\n bytes4 _interfaceId\\n ) external view override returns (bool isSupported) {\\n isSupported =\\n _interfaceId == type(IERC165).interfaceId ||\\n _interfaceId == IDiamondCut.diamondCut.selector ||\\n _interfaceId == type(IDiamondLoupe).interfaceId ||\\n _interfaceId == type(IERC1155Receiver).interfaceId ||\\n _interfaceId == type(IERC721Receiver).interfaceId ||\\n _interfaceId == type(IERC777Recipient).interfaceId ||\\n _interfaceId == IERC1271.isValidSignature.selector ||\\n _interfaceId == type(IERC677Receiver).interfaceId ||\\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId];\\n }\\n\\n /**\\n * @notice Returns the facet from the diamond storage. This excludes the facets from the default fallback handler\\n * @return facets_ Facet information attached directly to diamond storage\\n */\\n function facetsFromStorage()\\n external\\n view\\n override\\n returns (Facet[] memory facets_)\\n {\\n facets_ = LibLoupe.facets();\\n }\\n\\n /**\\n * @notice Returns the facet address attached to the given function selector. This excludes the facets from the default fallback handler\\n * @param _functionSelector Function selector to fetch the facet address from diamond storage\\n * @return facetAddress_ Facet address mapped with the function selector\\n */\\n function facetAddressFromStorage(\\n bytes4 _functionSelector\\n ) external view override returns (address facetAddress_) {\\n facetAddress_ = LibLoupe.facetAddress(_functionSelector);\\n }\\n\\n /**\\n * @notice Returns all facet addresses attached directly to diamond storage. This excludes the facets from the default fallback handler\\n * @return facetAddresses_ All facet addresses attached directly to diamond storage\\n */\\n function facetAddressesFromStorage()\\n external\\n view\\n override\\n returns (address[] memory facetAddresses_)\\n {\\n facetAddresses_ = LibLoupe.facetAddresses();\\n }\\n\\n /**\\n * @notice Returns function selectors of given facet address attached directly to diamond storage. This excludes the facets from the default fallback handler\\n * @param _facet Facet address to fetch the facet function selectors from diamond storage\\n * @return facetFunctionSelectors_ Facet function selectors of the given facet address\\n */\\n function facetFunctionSelectorsFromStorage(\\n address _facet\\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\\n facetFunctionSelectors_ = LibLoupe.facetFunctionSelectors(_facet);\\n }\\n}\\n\",\"keccak256\":\"0xf392fde159eec6483fc15fa323ecd6d764028f5b8734a66662c4116292363794\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IStorageLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"./IDiamondLoupe.sol\\\";\\n\\n/**\\n * @title LoupeFromStorage Interface\\n * @dev Interface contract to function as a loupe facet directly attached to diamond storage of Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IStorageLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facetsFromStorage()\\n external\\n view\\n returns (IDiamondLoupe.Facet[] memory);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n function facetFunctionSelectorsFromStorage(\\n address _facet\\n ) external view returns (bytes4[] memory);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n function facetAddressesFromStorage()\\n external\\n view\\n returns (address[] memory);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n function facetAddressFromStorage(\\n bytes4 _functionSelector\\n ) external view returns (address);\\n}\\n\",\"keccak256\":\"0xdf5dc9c57319e9087628c9cf9404b4f75585b76d1c2f4f59ee796c933967ea5c\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC1271 {\\n function isValidSignature(\\n bytes32 hash,\\n bytes memory signature\\n ) external view returns (bytes4);\\n}\\n\",\"keccak256\":\"0xcdddb7d5641c9d3f2432dec7fd13fddb9ae1480f25c76c21511e2fa16b8bd422\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.21;\\n\\ninterface IERC165 {\\n /// @notice Query if a contract implements an interface\\n /// @param interfaceId The interface identifier, as specified in ERC-165\\n /// @dev Interface identification is specified in ERC-165. This function\\n /// uses less than 30,000 gas.\\n /// @return `true` if the contract implements `interfaceID` and\\n /// `interfaceID` is not 0xffffffff, `false` otherwise\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xbb7f07e170898793c5535cc4b7e8944c4b990a631ac806d0b788e794abc788a3\",\"license\":\"MIT\"},\"contracts/interfaces/ERC/IERC677Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC677Receiver {\\n function onTokenTransfer(\\n address sender,\\n uint value,\\n bytes calldata data\\n ) external pure returns (bool);\\n}\\n\",\"keccak256\":\"0x4c1631cf45ea6daac0ec158c3edb9453099130b6b64f697004b83f95aa1f7350\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\\n bytes4(keccak256(\\\"verifyRestrictions(address,address,uint256,bytes)\\\"));\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // Default Fallback Handler of the barz.\\n IDiamondLoupe defaultFallbackHandler;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function enforceIsSelf() internal view {\\n require(msg.sender == address(this), \\\"LibDiamond: Caller not self\\\");\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n\\n unchecked {\\n facetIndex++;\\n }\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n\\n function restrictionsFacet() internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(\\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2cabdc00de859c3a3170ce3bda5d0e5fd3933d47ce904fd1585f9818b02572f8\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\nimport {LibDiamond} from \\\"./LibDiamond.sol\\\";\\n\\n/**\\n * @title LibLoupe\\n * @dev Internal Library to provide utility feature for reading the state of diamond facets\\n * Originally from Diamond's implementation of Mudgen(author of EIP-2535)\\n */\\nlibrary LibLoupe {\\n /// @notice Gets all facets and their selectors.\\n /// @return facets_ Facet\\n function facets()\\n internal\\n view\\n returns (IDiamondLoupe.Facet[] memory facets_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facets_ = new IDiamondLoupe.Facet[](ds.selectorCount);\\n uint16[] memory numFacetSelectors = new uint16[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facets_[facetIndex].facetAddress == facetAddress_) {\\n facets_[facetIndex].functionSelectors[\\n numFacetSelectors[facetIndex]\\n ] = selector;\\n // probably will never have more than 256 functions from one facet contract\\n require(numFacetSelectors[facetIndex] < 255);\\n numFacetSelectors[facetIndex]++;\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facets_[numFacets].facetAddress = facetAddress_;\\n facets_[numFacets].functionSelectors = new bytes4[](\\n ds.selectorCount\\n );\\n facets_[numFacets].functionSelectors[0] = selector;\\n numFacetSelectors[numFacets] = 1;\\n numFacets++;\\n }\\n }\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n uint256 numSelectors = numFacetSelectors[facetIndex];\\n bytes4[] memory selectors = facets_[facetIndex].functionSelectors;\\n // setting the number of selectors\\n assembly {\\n mstore(selectors, numSelectors)\\n }\\n }\\n // setting the number of facets\\n assembly {\\n mstore(facets_, numFacets)\\n }\\n }\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return _facetFunctionSelectors The selectors associated with a facet address.\\n function facetFunctionSelectors(\\n address _facet\\n ) internal view returns (bytes4[] memory _facetFunctionSelectors) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n uint256 numSelectors;\\n _facetFunctionSelectors = new bytes4[](ds.selectorCount);\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facet = address(bytes20(ds.facets[selector]));\\n if (_facet == facet) {\\n _facetFunctionSelectors[numSelectors] = selector;\\n numSelectors++;\\n }\\n }\\n }\\n // Set the number of selectors in the array\\n assembly {\\n mstore(_facetFunctionSelectors, numSelectors)\\n }\\n }\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n internal\\n view\\n returns (address[] memory facetAddresses_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetAddresses_ = new address[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facetAddress_ == facetAddresses_[facetIndex]) {\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facetAddresses_[numFacets] = facetAddress_;\\n numFacets++;\\n }\\n }\\n // Set the number of facet addresses in the array\\n assembly {\\n mstore(facetAddresses_, numFacets)\\n }\\n }\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(LibDiamond.diamondStorage().facets[_functionSelector])\\n );\\n }\\n}\\n\",\"keccak256\":\"0x0b11439c3cc657095e15ec2241fdcf67204b14001357b612fc5db4ff9e760a5a\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibUtils.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nlibrary LibUtils {\\n // Internal utility functions\\n function mergeArrays(\\n bytes4[] memory _array1,\\n bytes4[] memory _array2\\n ) internal pure returns (bytes4[] memory) {\\n uint256 length1 = _array1.length;\\n uint256 length2 = _array2.length;\\n bytes4[] memory mergedArray = new bytes4[](length1 + length2);\\n\\n for (uint256 i; i < length1; ) {\\n mergedArray[i] = _array1[i];\\n unchecked {\\n ++i;\\n }\\n }\\n\\n for (uint256 i; i < length2; ) {\\n mergedArray[length1 + i] = _array2[i];\\n unchecked {\\n ++i;\\n }\\n }\\n\\n return mergedArray;\\n }\\n\\n function removeFacetElement(\\n IDiamondLoupe.Facet[] memory _facets,\\n uint256 _index\\n ) internal pure returns (IDiamondLoupe.Facet[] memory) {\\n require(_index < _facets.length, \\\"Invalid index\\\");\\n require(_facets.length != 0, \\\"Invalid array\\\");\\n\\n // Create a new array with a length of `_facets.length - 1`\\n IDiamondLoupe.Facet[] memory newArray = new IDiamondLoupe.Facet[](\\n _facets.length - 1\\n );\\n uint256 newArrayLength = newArray.length;\\n // Iterate over the original array, skipping the element at the specified `index`\\n for (uint256 i; i < newArrayLength; ) {\\n if (i < _index) {\\n newArray[i] = _facets[i];\\n } else {\\n newArray[i] = _facets[i + 1];\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n\\n return newArray;\\n }\\n\\n function removeElement(\\n bytes4[] memory _array,\\n uint256 _index\\n ) internal pure returns (bytes4[] memory) {\\n require(_index < _array.length, \\\"Invalid index\\\");\\n require(_array.length != 0, \\\"Invalid array\\\");\\n\\n bytes4[] memory newArray = new bytes4[](_array.length - 1);\\n uint256 newArrayLength = newArray.length;\\n for (uint256 i; i < newArrayLength; ) {\\n if (i < _index) {\\n newArray[i] = _array[i];\\n } else {\\n newArray[i] = _array[i + 1];\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n\\n return newArray;\\n }\\n\\n function setValue(\\n bytes4[] memory _keys,\\n address[] memory _values,\\n bytes4 _key,\\n address _value\\n ) internal pure returns (bytes4[] memory, address[] memory) {\\n uint256 index = findIndex(_keys, _key);\\n uint256 keysLength = _keys.length;\\n if (index < keysLength) {\\n _values[index] = _value;\\n } else {\\n // Create new storage arrays\\n bytes4[] memory newKeys = new bytes4[](keysLength + 1);\\n address[] memory newValues = new address[](_values.length + 1);\\n\\n // Copy values to the new storage arrays\\n for (uint256 i; i < keysLength; ) {\\n newKeys[i] = _keys[i];\\n newValues[i] = _values[i];\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n // Add the new key-value pair\\n newKeys[keysLength] = _key;\\n newValues[_values.length] = _value;\\n\\n return (newKeys, newValues);\\n }\\n\\n // If the key already exists, return the original arrays\\n return (_keys, _values);\\n }\\n\\n function getValue(\\n bytes4[] memory _keys,\\n address[] memory _values,\\n bytes4 _key\\n ) internal pure returns (address) {\\n uint256 index = findIndex(_keys, _key);\\n if (index >= _keys.length) return address(0);\\n\\n return _values[index];\\n }\\n\\n function findIndex(\\n bytes4[] memory _keys,\\n bytes4 _key\\n ) internal pure returns (uint256) {\\n uint256 keysLength = _keys.length;\\n for (uint256 i; i < keysLength; ) {\\n if (_keys[i] == _key) {\\n return i;\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n return keysLength;\\n }\\n}\\n\",\"keccak256\":\"0xde8aeefe54c4be483f2b2c055aca11e2830f7094c0586a82e10ec544933b5714\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5061240b806100206000396000f3fe608060405234801561001057600080fd5b50600436106100a35760003560e01c8063adfca15e11610076578063d42139a91161005b578063d42139a914610169578063e3a2f6fe14610171578063f9796ccf1461018457600080fd5b8063adfca15e1461011e578063cdffacc61461013157600080fd5b806301a55022146100a857806301ffc9a7146100d157806352ef6b2c146100f45780637a0ed62714610109575b600080fd5b6100bb6100b6366004611e4b565b61018c565b6040516100c89190611e68565b60405180910390f35b6100e46100df366004611efc565b61019d565b60405190151581526020016100c8565b6100fc610454565b6040516100c89190611f19565b610111610518565b6040516100c89190611f67565b6100bb61012c366004611e4b565b610a63565b61014461013f366004611efc565b610b07565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100c8565b6100fc610c24565b61014461017f366004611efc565b610c33565b610111610c8c565b606061019782610c96565b92915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000148061023057507fffffffff0000000000000000000000000000000000000000000000000000000082167f1f931c1c00000000000000000000000000000000000000000000000000000000145b8061027c57507fffffffff0000000000000000000000000000000000000000000000000000000082167f48e2b09300000000000000000000000000000000000000000000000000000000145b806102c857507fffffffff0000000000000000000000000000000000000000000000000000000082167f4e2312e000000000000000000000000000000000000000000000000000000000145b8061031457507fffffffff0000000000000000000000000000000000000000000000000000000082167f150b7a0200000000000000000000000000000000000000000000000000000000145b8061035f57507fffffffff0000000000000000000000000000000000000000000000000000000082167e23de2900000000000000000000000000000000000000000000000000000000145b806103ab57507fffffffff0000000000000000000000000000000000000000000000000000000082167f1626ba7e00000000000000000000000000000000000000000000000000000000145b806103f757507fffffffff0000000000000000000000000000000000000000000000000000000082167fa4c0ed3600000000000000000000000000000000000000000000000000000000145b806101975750507fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4922602052604090205460ff1690565b60606000610460610518565b80519091508067ffffffffffffffff81111561047e5761047e61205d565b6040519080825280602002602001820160405280156104a7578160200160208202803683370190505b50925060005b81811015610512578281815181106104c7576104c761208c565b6020026020010151600001518482815181106104e5576104e561208c565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526001016104ad565b50505090565b606060007f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f600490810154604080517f7a0ed627000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff90921692637a0ed6279282820192600092908290030181865afa1580156105ac573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526105f29190810190612157565b905060006105fe610e57565b805190915060608060005b838110156106b55760008582815181106106255761062561208c565b60200260200101516020015151905060005b818110156106ab5761069e85858986815181106106565761065661208c565b60200260200101516020015184815181106106735761067361208c565b60200260200101518a878151811061068d5761068d61208c565b60200260200101516000015161134a565b9095509350600101610637565b5050600101610609565b506000805b865181101561081b576000805b8883815181106106d9576106d961208c565b602002602001015160200151518110156107ff57600073ffffffffffffffffffffffffffffffffffffffff1661074687878c878151811061071c5761071c61208c565b60200260200101516020015185815181106107395761073961208c565b60200260200101516115f1565b73ffffffffffffffffffffffffffffffffffffffff16146107e9578883815181106107735761077361208c565b6020026020010151602001515160010361079c576107918984611637565b9850600193506107ff565b6107c38984815181106107b1576107b161208c565b6020026020010151602001518261182a565b8984815181106107d5576107d561208c565b602002602001015160200181905250600191505b816107f6576001016106c7565b600091506106c7565b508261081057816001019150610815565b600092505b506106ba565b5050600085518461082c9190612304565b90508067ffffffffffffffff8111156108475761084761205d565b60405190808252806020026020018201604052801561088d57816020015b6040805180820190915260008152606060208201528152602001906001900390816108655790505b5096506000805b82811015610a585785811015610a0c578681815181106108b6576108b661208c565b60200260200101518982815181106108d0576108d061208c565b60200260200101819052506000805b8951811015610a05578981815181106108fa576108fa61208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff168b848151811061092e5761092e61208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff16036109ef5761099989848151811061096a5761096a61208c565b6020026020010151602001518b83815181106109885761098861208c565b602002602001015160200151611a3d565b8b84815181106109ab576109ab61208c565b6020026020010151602001819052506109c48a82611637565b9950600191506109e18b60018d516109dc9190612317565b611637565b9a506109ec8561232a565b94505b816109fc576001016108df565b600091506108df565b5050610a50565b878281518110610a1e57610a1e61208c565b6020026020010151898281518110610a3857610a3861208c565b602002602001018190525081610a4d9061235f565b91505b600101610894565b505050505050505090565b60606000610a6f610518565b805190915060005b81811015610aff578473ffffffffffffffffffffffffffffffffffffffff16838281518110610aa857610aa861208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1603610af757828181518110610ae157610ae161208c565b6020026020010151602001519350505050919050565b600101610a77565b505050919050565b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602081905260409091205460601c9081610c1e576004818101546040517fcdffacc60000000000000000000000000000000000000000000000000000000081527fffffffff0000000000000000000000000000000000000000000000000000000086169281019290925273ffffffffffffffffffffffffffffffffffffffff169063cdffacc690602401602060405180830381865afa158015610bf7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c1b9190612397565b91505b50919050565b6060610c2e611b8b565b905090565b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604081205460601c610197565b6060610c2e610e57565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9060009061ffff1667ffffffffffffffff811115610cfc57610cfc61205d565b604051908082528060200260200182016040528015610d25578160200160208202803683370190505b5092506000805b600284015461ffff16821015610e4d576000818152600185016020526040812054905b6008811015610e385783610d628161235f565b600288015490955061ffff1685119050610e3857600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020889052604090205460601c73ffffffffffffffffffffffffffffffffffffffff8a16819003610e235781898881518110610de457610de461208c565b7fffffffff000000000000000000000000000000000000000000000000000000009092166020928302919091019091015286610e1f8161235f565b9750505b50508080610e309061235f565b915050610d4f565b50508080610e459061235f565b915050610d2c565b5050825250919050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff1667ffffffffffffffff811115610eba57610eba61205d565b604051908082528060200260200182016040528015610f0057816020015b604080518082019091526000815260606020820152815260200190600190039081610ed85790505b50600282015490925060009061ffff1667ffffffffffffffff811115610f2857610f2861205d565b604051908082528060200260200182016040528015610f51578160200160208202803683370190505b50905060008060005b600285015461ffff168210156112d7576000818152600186016020526040812054905b60088110156112c25783610f908161235f565b600289015490955061ffff16851190506112c257600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020899052604081205460601c90805b88811015611148578273ffffffffffffffffffffffffffffffffffffffff168c82815181106110155761101561208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff160361113657838c828151811061104f5761104f61208c565b6020026020010151602001518b838151811061106d5761106d61208c565b602002602001015161ffff16815181106110895761108961208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152505060ff8a82815181106110e9576110e961208c565b602002602001015161ffff16106110ff57600080fd5b8981815181106111115761111161208c565b602002602001018051809190611126906123b4565b61ffff1690525060019150611148565b806111408161235f565b915050610fe4565b508015611157575050506112b0565b818b898151811061116a5761116a61208c565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff909116905260028a015461ffff1667ffffffffffffffff8111156111b0576111b061205d565b6040519080825280602002602001820160405280156111d9578160200160208202803683370190505b508b89815181106111ec576111ec61208c565b602002602001015160200181905250828b898151811061120e5761120e61208c565b60200260200101516020015160008151811061122c5761122c61208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681525050600189898151811061128c5761128c61208c565b61ffff90921660209283029190910190910152876112a98161235f565b9850505050505b806112ba8161235f565b915050610f7d565b505080806112cf9061235f565b915050610f5a565b5060005b8281101561133f5760008482815181106112f7576112f761208c565b602002602001015161ffff16905060008783815181106113195761131961208c565b6020026020010151602001519050818152505080806113379061235f565b9150506112db565b508185525050505090565b60608060006113598786611da0565b8751909150808210156113b857848783815181106113795761137961208c565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250506115df565b60006113c5826001612304565b67ffffffffffffffff8111156113dd576113dd61205d565b604051908082528060200260200182016040528015611406578160200160208202803683370190505b5090506000885160016114199190612304565b67ffffffffffffffff8111156114315761143161205d565b60405190808252806020026020018201604052801561145a578160200160208202803683370190505b50905060005b83811015611539578a818151811061147a5761147a61208c565b60200260200101518382815181106114945761149461208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815250508981815181106114f2576114f261208c565b602002602001015182828151811061150c5761150c61208c565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101611460565b508782848151811061154d5761154d61208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152505086818a51815181106115ad576115ad61208c565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015290945092506115e8915050565b87879350935050505b94509492505050565b6000806115fe8584611da0565b905084518110611612576000915050611630565b8381815181106116245761162461208c565b60200260200101519150505b9392505050565b6060825182106116a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420696e6465780000000000000000000000000000000000000060448201526064015b60405180910390fd5b8251600003611713576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420617272617900000000000000000000000000000000000000604482015260640161169f565b6000600184516117239190612317565b67ffffffffffffffff81111561173b5761173b61205d565b60405190808252806020026020018201604052801561178157816020015b6040805180820190915260008152606060208201528152602001906001900390816117595790505b50805190915060005b8181101561182057848110156117d6578581815181106117ac576117ac61208c565b60200260200101518382815181106117c6576117c661208c565b6020026020010181905250611818565b856117e2826001612304565b815181106117f2576117f261208c565b602002602001015183828151811061180c5761180c61208c565b60200260200101819052505b60010161178a565b5090949350505050565b606082518210611896576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420696e64657800000000000000000000000000000000000000604482015260640161169f565b8251600003611901576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420617272617900000000000000000000000000000000000000604482015260640161169f565b6000600184516119119190612317565b67ffffffffffffffff8111156119295761192961205d565b604051908082528060200260200182016040528015611952578160200160208202803683370190505b50805190915060005b8181101561182057848110156119cd5785818151811061197d5761197d61208c565b60200260200101518382815181106119975761199761208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152611a35565b856119d9826001612304565b815181106119e9576119e961208c565b6020026020010151838281518110611a0357611a0361208c565b7fffffffff00000000000000000000000000000000000000000000000000000000909216602092830291909101909101525b60010161195b565b81518151606091906000611a518284612304565b67ffffffffffffffff811115611a6957611a6961205d565b604051908082528060200260200182016040528015611a92578160200160208202803683370190505b50905060005b83811015611b0557868181518110611ab257611ab261208c565b6020026020010151828281518110611acc57611acc61208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152600101611a98565b5060005b82811015611b8157858181518110611b2357611b2361208c565b6020026020010151828286611b389190612304565b81518110611b4857611b4861208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152600101611b09565b5095945050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff1667ffffffffffffffff811115611bee57611bee61205d565b604051908082528060200260200182016040528015611c17578160200160208202803683370190505b50915060008060005b600284015461ffff16821015611d98576000818152600185016020526040812054905b6008811015611d835783611c568161235f565b600288015490955061ffff1685119050611d8357600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020889052604081205460601c90805b88811015611d19578a8181518110611cc457611cc461208c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611d075760019150611d19565b80611d118161235f565b915050611caa565b508015611d2857505050611d71565b818a8981518110611d3b57611d3b61208c565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015287611d6a8161235f565b9850505050505b80611d7b8161235f565b915050611c43565b50508080611d909061235f565b915050611c20565b505082525090565b8151600090815b81811015611e1e57837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916858281518110611de157611de161208c565b60200260200101517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603611e165791506101979050565b600101611da7565b509392505050565b73ffffffffffffffffffffffffffffffffffffffff81168114611e4857600080fd5b50565b600060208284031215611e5d57600080fd5b813561163081611e26565b6020808252825182820181905260009190848201906040850190845b81811015611ec25783517fffffffff000000000000000000000000000000000000000000000000000000001683529284019291840191600101611e84565b50909695505050505050565b7fffffffff0000000000000000000000000000000000000000000000000000000081168114611e4857600080fd5b600060208284031215611f0e57600080fd5b813561163081611ece565b6020808252825182820181905260009190848201906040850190845b81811015611ec257835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101611f35565b60006020808301818452808551808352604092508286019150828160051b8701018488016000805b8481101561204e578984037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00186528251805173ffffffffffffffffffffffffffffffffffffffff168552880151888501889052805188860181905290890190839060608701905b808310156120395783517fffffffff00000000000000000000000000000000000000000000000000000000168252928b019260019290920191908b0190611ff7565b50978a01979550505091870191600101611f8f565b50919998505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6040805190810167ffffffffffffffff811182821017156120de576120de61205d565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561212b5761212b61205d565b604052919050565b600067ffffffffffffffff82111561214d5761214d61205d565b5060051b60200190565b6000602080838503121561216a57600080fd5b825167ffffffffffffffff8082111561218257600080fd5b818501915085601f83011261219657600080fd5b81516121a96121a482612133565b6120e4565b81815260059190911b830184019084810190888311156121c857600080fd5b8585015b838110156122c8578051858111156121e45760008081fd5b86016040818c037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00181131561221a5760008081fd5b6122226120bb565b8983015161222f81611e26565b815282820151888111156122435760008081fd5b8084019350508c603f8401126122595760008081fd5b898301516122696121a482612133565b81815260059190911b84018301908b8101908f8311156122895760008081fd5b948401945b828610156122b357855194506122a385611ece565b848252948c0194908c019061228e565b838d01525050855250509186019186016121cc565b5098975050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610197576101976122d5565b81810381811115610197576101976122d5565b600081612339576123396122d5565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612390576123906122d5565b5060010190565b6000602082840312156123a957600080fd5b815161163081611e26565b600061ffff8083168181036123cb576123cb6122d5565b600101939250505056fea26469706673582212205959d8d85aad6f29d5fc37d5a52c404c25392cec49195c3b761da0e863e99b0f64736f6c63430008150033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100a35760003560e01c8063adfca15e11610076578063d42139a91161005b578063d42139a914610169578063e3a2f6fe14610171578063f9796ccf1461018457600080fd5b8063adfca15e1461011e578063cdffacc61461013157600080fd5b806301a55022146100a857806301ffc9a7146100d157806352ef6b2c146100f45780637a0ed62714610109575b600080fd5b6100bb6100b6366004611e4b565b61018c565b6040516100c89190611e68565b60405180910390f35b6100e46100df366004611efc565b61019d565b60405190151581526020016100c8565b6100fc610454565b6040516100c89190611f19565b610111610518565b6040516100c89190611f67565b6100bb61012c366004611e4b565b610a63565b61014461013f366004611efc565b610b07565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100c8565b6100fc610c24565b61014461017f366004611efc565b610c33565b610111610c8c565b606061019782610c96565b92915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000148061023057507fffffffff0000000000000000000000000000000000000000000000000000000082167f1f931c1c00000000000000000000000000000000000000000000000000000000145b8061027c57507fffffffff0000000000000000000000000000000000000000000000000000000082167f48e2b09300000000000000000000000000000000000000000000000000000000145b806102c857507fffffffff0000000000000000000000000000000000000000000000000000000082167f4e2312e000000000000000000000000000000000000000000000000000000000145b8061031457507fffffffff0000000000000000000000000000000000000000000000000000000082167f150b7a0200000000000000000000000000000000000000000000000000000000145b8061035f57507fffffffff0000000000000000000000000000000000000000000000000000000082167e23de2900000000000000000000000000000000000000000000000000000000145b806103ab57507fffffffff0000000000000000000000000000000000000000000000000000000082167f1626ba7e00000000000000000000000000000000000000000000000000000000145b806103f757507fffffffff0000000000000000000000000000000000000000000000000000000082167fa4c0ed3600000000000000000000000000000000000000000000000000000000145b806101975750507fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4922602052604090205460ff1690565b60606000610460610518565b80519091508067ffffffffffffffff81111561047e5761047e61205d565b6040519080825280602002602001820160405280156104a7578160200160208202803683370190505b50925060005b81811015610512578281815181106104c7576104c761208c565b6020026020010151600001518482815181106104e5576104e561208c565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526001016104ad565b50505090565b606060007f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f600490810154604080517f7a0ed627000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff90921692637a0ed6279282820192600092908290030181865afa1580156105ac573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526105f29190810190612157565b905060006105fe610e57565b805190915060608060005b838110156106b55760008582815181106106255761062561208c565b60200260200101516020015151905060005b818110156106ab5761069e85858986815181106106565761065661208c565b60200260200101516020015184815181106106735761067361208c565b60200260200101518a878151811061068d5761068d61208c565b60200260200101516000015161134a565b9095509350600101610637565b5050600101610609565b506000805b865181101561081b576000805b8883815181106106d9576106d961208c565b602002602001015160200151518110156107ff57600073ffffffffffffffffffffffffffffffffffffffff1661074687878c878151811061071c5761071c61208c565b60200260200101516020015185815181106107395761073961208c565b60200260200101516115f1565b73ffffffffffffffffffffffffffffffffffffffff16146107e9578883815181106107735761077361208c565b6020026020010151602001515160010361079c576107918984611637565b9850600193506107ff565b6107c38984815181106107b1576107b161208c565b6020026020010151602001518261182a565b8984815181106107d5576107d561208c565b602002602001015160200181905250600191505b816107f6576001016106c7565b600091506106c7565b508261081057816001019150610815565b600092505b506106ba565b5050600085518461082c9190612304565b90508067ffffffffffffffff8111156108475761084761205d565b60405190808252806020026020018201604052801561088d57816020015b6040805180820190915260008152606060208201528152602001906001900390816108655790505b5096506000805b82811015610a585785811015610a0c578681815181106108b6576108b661208c565b60200260200101518982815181106108d0576108d061208c565b60200260200101819052506000805b8951811015610a05578981815181106108fa576108fa61208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff168b848151811061092e5761092e61208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff16036109ef5761099989848151811061096a5761096a61208c565b6020026020010151602001518b83815181106109885761098861208c565b602002602001015160200151611a3d565b8b84815181106109ab576109ab61208c565b6020026020010151602001819052506109c48a82611637565b9950600191506109e18b60018d516109dc9190612317565b611637565b9a506109ec8561232a565b94505b816109fc576001016108df565b600091506108df565b5050610a50565b878281518110610a1e57610a1e61208c565b6020026020010151898281518110610a3857610a3861208c565b602002602001018190525081610a4d9061235f565b91505b600101610894565b505050505050505090565b60606000610a6f610518565b805190915060005b81811015610aff578473ffffffffffffffffffffffffffffffffffffffff16838281518110610aa857610aa861208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1603610af757828181518110610ae157610ae161208c565b6020026020010151602001519350505050919050565b600101610a77565b505050919050565b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602081905260409091205460601c9081610c1e576004818101546040517fcdffacc60000000000000000000000000000000000000000000000000000000081527fffffffff0000000000000000000000000000000000000000000000000000000086169281019290925273ffffffffffffffffffffffffffffffffffffffff169063cdffacc690602401602060405180830381865afa158015610bf7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c1b9190612397565b91505b50919050565b6060610c2e611b8b565b905090565b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604081205460601c610197565b6060610c2e610e57565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9060009061ffff1667ffffffffffffffff811115610cfc57610cfc61205d565b604051908082528060200260200182016040528015610d25578160200160208202803683370190505b5092506000805b600284015461ffff16821015610e4d576000818152600185016020526040812054905b6008811015610e385783610d628161235f565b600288015490955061ffff1685119050610e3857600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020889052604090205460601c73ffffffffffffffffffffffffffffffffffffffff8a16819003610e235781898881518110610de457610de461208c565b7fffffffff000000000000000000000000000000000000000000000000000000009092166020928302919091019091015286610e1f8161235f565b9750505b50508080610e309061235f565b915050610d4f565b50508080610e459061235f565b915050610d2c565b5050825250919050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff1667ffffffffffffffff811115610eba57610eba61205d565b604051908082528060200260200182016040528015610f0057816020015b604080518082019091526000815260606020820152815260200190600190039081610ed85790505b50600282015490925060009061ffff1667ffffffffffffffff811115610f2857610f2861205d565b604051908082528060200260200182016040528015610f51578160200160208202803683370190505b50905060008060005b600285015461ffff168210156112d7576000818152600186016020526040812054905b60088110156112c25783610f908161235f565b600289015490955061ffff16851190506112c257600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020899052604081205460601c90805b88811015611148578273ffffffffffffffffffffffffffffffffffffffff168c82815181106110155761101561208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff160361113657838c828151811061104f5761104f61208c565b6020026020010151602001518b838151811061106d5761106d61208c565b602002602001015161ffff16815181106110895761108961208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152505060ff8a82815181106110e9576110e961208c565b602002602001015161ffff16106110ff57600080fd5b8981815181106111115761111161208c565b602002602001018051809190611126906123b4565b61ffff1690525060019150611148565b806111408161235f565b915050610fe4565b508015611157575050506112b0565b818b898151811061116a5761116a61208c565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff909116905260028a015461ffff1667ffffffffffffffff8111156111b0576111b061205d565b6040519080825280602002602001820160405280156111d9578160200160208202803683370190505b508b89815181106111ec576111ec61208c565b602002602001015160200181905250828b898151811061120e5761120e61208c565b60200260200101516020015160008151811061122c5761122c61208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681525050600189898151811061128c5761128c61208c565b61ffff90921660209283029190910190910152876112a98161235f565b9850505050505b806112ba8161235f565b915050610f7d565b505080806112cf9061235f565b915050610f5a565b5060005b8281101561133f5760008482815181106112f7576112f761208c565b602002602001015161ffff16905060008783815181106113195761131961208c565b6020026020010151602001519050818152505080806113379061235f565b9150506112db565b508185525050505090565b60608060006113598786611da0565b8751909150808210156113b857848783815181106113795761137961208c565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250506115df565b60006113c5826001612304565b67ffffffffffffffff8111156113dd576113dd61205d565b604051908082528060200260200182016040528015611406578160200160208202803683370190505b5090506000885160016114199190612304565b67ffffffffffffffff8111156114315761143161205d565b60405190808252806020026020018201604052801561145a578160200160208202803683370190505b50905060005b83811015611539578a818151811061147a5761147a61208c565b60200260200101518382815181106114945761149461208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815250508981815181106114f2576114f261208c565b602002602001015182828151811061150c5761150c61208c565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101611460565b508782848151811061154d5761154d61208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152505086818a51815181106115ad576115ad61208c565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015290945092506115e8915050565b87879350935050505b94509492505050565b6000806115fe8584611da0565b905084518110611612576000915050611630565b8381815181106116245761162461208c565b60200260200101519150505b9392505050565b6060825182106116a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420696e6465780000000000000000000000000000000000000060448201526064015b60405180910390fd5b8251600003611713576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420617272617900000000000000000000000000000000000000604482015260640161169f565b6000600184516117239190612317565b67ffffffffffffffff81111561173b5761173b61205d565b60405190808252806020026020018201604052801561178157816020015b6040805180820190915260008152606060208201528152602001906001900390816117595790505b50805190915060005b8181101561182057848110156117d6578581815181106117ac576117ac61208c565b60200260200101518382815181106117c6576117c661208c565b6020026020010181905250611818565b856117e2826001612304565b815181106117f2576117f261208c565b602002602001015183828151811061180c5761180c61208c565b60200260200101819052505b60010161178a565b5090949350505050565b606082518210611896576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420696e64657800000000000000000000000000000000000000604482015260640161169f565b8251600003611901576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420617272617900000000000000000000000000000000000000604482015260640161169f565b6000600184516119119190612317565b67ffffffffffffffff8111156119295761192961205d565b604051908082528060200260200182016040528015611952578160200160208202803683370190505b50805190915060005b8181101561182057848110156119cd5785818151811061197d5761197d61208c565b60200260200101518382815181106119975761199761208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152611a35565b856119d9826001612304565b815181106119e9576119e961208c565b6020026020010151838281518110611a0357611a0361208c565b7fffffffff00000000000000000000000000000000000000000000000000000000909216602092830291909101909101525b60010161195b565b81518151606091906000611a518284612304565b67ffffffffffffffff811115611a6957611a6961205d565b604051908082528060200260200182016040528015611a92578160200160208202803683370190505b50905060005b83811015611b0557868181518110611ab257611ab261208c565b6020026020010151828281518110611acc57611acc61208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152600101611a98565b5060005b82811015611b8157858181518110611b2357611b2361208c565b6020026020010151828286611b389190612304565b81518110611b4857611b4861208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152600101611b09565b5095945050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff1667ffffffffffffffff811115611bee57611bee61205d565b604051908082528060200260200182016040528015611c17578160200160208202803683370190505b50915060008060005b600284015461ffff16821015611d98576000818152600185016020526040812054905b6008811015611d835783611c568161235f565b600288015490955061ffff1685119050611d8357600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020889052604081205460601c90805b88811015611d19578a8181518110611cc457611cc461208c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611d075760019150611d19565b80611d118161235f565b915050611caa565b508015611d2857505050611d71565b818a8981518110611d3b57611d3b61208c565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015287611d6a8161235f565b9850505050505b80611d7b8161235f565b915050611c43565b50508080611d909061235f565b915050611c20565b505082525090565b8151600090815b81811015611e1e57837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916858281518110611de157611de161208c565b60200260200101517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603611e165791506101979050565b600101611da7565b509392505050565b73ffffffffffffffffffffffffffffffffffffffff81168114611e4857600080fd5b50565b600060208284031215611e5d57600080fd5b813561163081611e26565b6020808252825182820181905260009190848201906040850190845b81811015611ec25783517fffffffff000000000000000000000000000000000000000000000000000000001683529284019291840191600101611e84565b50909695505050505050565b7fffffffff0000000000000000000000000000000000000000000000000000000081168114611e4857600080fd5b600060208284031215611f0e57600080fd5b813561163081611ece565b6020808252825182820181905260009190848201906040850190845b81811015611ec257835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101611f35565b60006020808301818452808551808352604092508286019150828160051b8701018488016000805b8481101561204e578984037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00186528251805173ffffffffffffffffffffffffffffffffffffffff168552880151888501889052805188860181905290890190839060608701905b808310156120395783517fffffffff00000000000000000000000000000000000000000000000000000000168252928b019260019290920191908b0190611ff7565b50978a01979550505091870191600101611f8f565b50919998505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6040805190810167ffffffffffffffff811182821017156120de576120de61205d565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561212b5761212b61205d565b604052919050565b600067ffffffffffffffff82111561214d5761214d61205d565b5060051b60200190565b6000602080838503121561216a57600080fd5b825167ffffffffffffffff8082111561218257600080fd5b818501915085601f83011261219657600080fd5b81516121a96121a482612133565b6120e4565b81815260059190911b830184019084810190888311156121c857600080fd5b8585015b838110156122c8578051858111156121e45760008081fd5b86016040818c037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00181131561221a5760008081fd5b6122226120bb565b8983015161222f81611e26565b815282820151888111156122435760008081fd5b8084019350508c603f8401126122595760008081fd5b898301516122696121a482612133565b81815260059190911b84018301908b8101908f8311156122895760008081fd5b948401945b828610156122b357855194506122a385611ece565b848252948c0194908c019061228e565b838d01525050855250509186019186016121cc565b5098975050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610197576101976122d5565b81810381811115610197576101976122d5565b600081612339576123396122d5565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612390576123906122d5565b5060010190565b6000602082840312156123a957600080fd5b815161163081611e26565b600061ffff8083168181036123cb576123cb6122d5565b600101939250505056fea26469706673582212205959d8d85aad6f29d5fc37d5a52c404c25392cec49195c3b761da0e863e99b0f64736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "DiamondLoupe contract compatible with EIP-2535", + "kind": "dev", + "methods": { + "facetAddress(bytes4)": { + "details": "If facet is not found return address(0).", + "params": { + "_functionSelector": "The function selector." + }, + "returns": { + "facetAddress_": "The facet address." + } + }, + "facetAddressFromStorage(bytes4)": { + "params": { + "_functionSelector": "Function selector to fetch the facet address from diamond storage" + }, + "returns": { + "facetAddress_": "Facet address mapped with the function selector" + } + }, + "facetAddresses()": { + "returns": { + "facetAddresses_": "facetAddresses_" + } + }, + "facetAddressesFromStorage()": { + "returns": { + "facetAddresses_": "All facet addresses attached directly to diamond storage" + } + }, + "facetFunctionSelectors(address)": { + "params": { + "_facet": "The facet address." + }, + "returns": { + "facetFunctionSelectors_": "facetFunctionSelectors_" + } + }, + "facetFunctionSelectorsFromStorage(address)": { + "params": { + "_facet": "Facet address to fetch the facet function selectors from diamond storage" + }, + "returns": { + "facetFunctionSelectors_": "Facet function selectors of the given facet address" + } + }, + "facets()": { + "details": "Barz uses a special architecture called default fallback handler. Default Fallback handler is used as a middleware that holds the mapping of facet function selector and facet address that Barz uses. This helps Barz to reduce significant amount of gas during the initialization process. Hence, this method aggregates both the facet information from DefaulFallbackHandler and in diamond storage and shows the data to users.", + "returns": { + "facets_": "Facet" + } + }, + "facetsFromStorage()": { + "returns": { + "facets_": "Facet information attached directly to diamond storage" + } + }, + "supportsInterface(bytes4)": { + "params": { + "_interfaceId": "Interface ID for detecting the interface" + }, + "returns": { + "isSupported": "Bool value showing if the standard is supported in the contract" + } + } + }, + "title": "DiamondLoupe Facet", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "facetAddress(bytes4)": { + "notice": "Gets the facet that supports the given selector." + }, + "facetAddressFromStorage(bytes4)": { + "notice": "Returns the facet address attached to the given function selector. This excludes the facets from the default fallback handler" + }, + "facetAddresses()": { + "notice": "Get all the facet addresses used by Barz." + }, + "facetAddressesFromStorage()": { + "notice": "Returns all facet addresses attached directly to diamond storage. This excludes the facets from the default fallback handler" + }, + "facetFunctionSelectors(address)": { + "notice": "Gets all the function selectors provided by a facet." + }, + "facetFunctionSelectorsFromStorage(address)": { + "notice": "Returns function selectors of given facet address attached directly to diamond storage. This excludes the facets from the default fallback handler" + }, + "facets()": { + "notice": "Gets all facets and their selectors." + }, + "facetsFromStorage()": { + "notice": "Returns the facet from the diamond storage. This excludes the facets from the default fallback handler" + }, + "supportsInterface(bytes4)": { + "notice": "SupportInterface to be compatible with EIP 165" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/mantle/Secp256r1VerificationFacet.json b/deployments/mantle/Secp256r1VerificationFacet.json new file mode 100644 index 0000000..e8cac82 --- /dev/null +++ b/deployments/mantle/Secp256r1VerificationFacet.json @@ -0,0 +1,483 @@ +{ + "address": "0xeE1AF8E967eC04C84711842796A5E714D2FD33e6", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "LibAppStorage__AccountMustBeUninitialized", + "type": "error" + }, + { + "inputs": [], + "name": "LibAppStorage__SignerAlreadyUninitialized", + "type": "error" + }, + { + "inputs": [], + "name": "LibAppStorage__SignerMustBeUninitialized", + "type": "error" + }, + { + "inputs": [], + "name": "Secp256r1VerificationFacet__InvalidSignerLength", + "type": "error" + }, + { + "inputs": [], + "name": "VerificationFacet__InitializationFailure", + "type": "error" + }, + { + "inputs": [], + "name": "VerificationFacet__InvalidFacetMapping", + "type": "error" + }, + { + "inputs": [], + "name": "VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet", + "type": "error" + }, + { + "inputs": [], + "name": "VerificationFacet__ValidateOwnerSignatureSelectorNotSet", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "SignerInitialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "SignerUninitialized", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_publicKey", + "type": "bytes" + } + ], + "name": "initializeSigner", + "outputs": [ + { + "internalType": "uint256", + "name": "initSuccess", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_publicKey", + "type": "bytes" + } + ], + "name": "isValidKeyType", + "outputs": [ + { + "internalType": "bool", + "name": "isValid", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_hash", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "_signature", + "type": "bytes" + } + ], + "name": "isValidSignature", + "outputs": [ + { + "internalType": "bytes4", + "name": "magicValue", + "type": "bytes4" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "bytes", + "name": "signer", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "self", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "uninitializeSigner", + "outputs": [ + { + "internalType": "uint256", + "name": "uninitSuccess", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "initCode", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "callGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "verificationGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "preVerificationGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxFeePerGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPriorityFeePerGas", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "paymasterAndData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "internalType": "struct UserOperation", + "name": "userOp", + "type": "tuple" + }, + { + "internalType": "bytes32", + "name": "userOpHash", + "type": "bytes32" + } + ], + "name": "validateOwnerSignature", + "outputs": [ + { + "internalType": "uint256", + "name": "validationData", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "validateOwnerSignatureSelector", + "outputs": [ + { + "internalType": "bytes4", + "name": "ownerSignatureValidatorSelector", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "initCode", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "callGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "verificationGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "preVerificationGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxFeePerGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPriorityFeePerGas", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "paymasterAndData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "internalType": "struct UserOperation", + "name": "userOp", + "type": "tuple" + }, + { + "internalType": "bytes32", + "name": "userOpHash", + "type": "bytes32" + }, + { + "internalType": "uint256[2]", + "name": "q", + "type": "uint256[2]" + } + ], + "name": "validateSignature", + "outputs": [ + { + "internalType": "uint256", + "name": "isValid", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0x5273fae52198724ef66078739e957e37c5db6a4613e1ffcb6d6cfe86596197d5", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xb33654322bD3803821031624f5922eb14C9b8d18", + "contractAddress": null, + "transactionIndex": 1, + "gasUsed": "11497956050", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x2c51e6decf70458c7854e938a62c1753295b8456b4b95114055c38952ac7fa6c", + "transactionHash": "0x5273fae52198724ef66078739e957e37c5db6a4613e1ffcb6d6cfe86596197d5", + "logs": [], + "blockNumber": 61655377, + "cumulativeGasUsed": "11498020051", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "ad34345aa73d96f52b3e14df983b6b29", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"LibAppStorage__AccountMustBeUninitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LibAppStorage__SignerAlreadyUninitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LibAppStorage__SignerMustBeUninitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Secp256r1VerificationFacet__InvalidSignerLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerificationFacet__InitializationFailure\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerificationFacet__InvalidFacetMapping\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerificationFacet__ValidateOwnerSignatureSelectorNotSet\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"SignerInitialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"SignerUninitialized\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_publicKey\",\"type\":\"bytes\"}],\"name\":\"initializeSigner\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"initSuccess\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_publicKey\",\"type\":\"bytes\"}],\"name\":\"isValidKeyType\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isValid\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_hash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"_signature\",\"type\":\"bytes\"}],\"name\":\"isValidSignature\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"magicValue\",\"type\":\"bytes4\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"signer\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"self\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"uninitializeSigner\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"uninitSuccess\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"userOp\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"}],\"name\":\"validateOwnerSignature\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"validationData\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"validateOwnerSignatureSelector\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"ownerSignatureValidatorSelector\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"userOp\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256[2]\",\"name\":\"q\",\"type\":\"uint256[2]\"}],\"name\":\"validateSignature\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"isValid\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Ruslan Serebriakov (@rsrbk)David Yongjun Kim (@Powerstream3604)\",\"details\":\"Primarily used to verify user ops signed with passkeys\",\"kind\":\"dev\",\"methods\":{\"initializeSigner(bytes)\":{\"details\":\"This method checks if the signer has already been initialized. If already initialized, it reverts. It checks if the public key is in the light format and initializes signer storage in k1 storage.\",\"params\":{\"_publicKey\":\"Bytes of owner public key\"},\"returns\":{\"initSuccess\":\"Uint value representing the success of init operation\"}},\"isValidKeyType(bytes)\":{\"details\":\"For this Secp256k1Verification Facet, the public key should in an uncompressed public key format\",\"params\":{\"_publicKey\":\"Bytes of public key for format check\"},\"returns\":{\"isValid\":\"Boolean variable representing if the format of public key is valid\"}},\"isValidSignature(bytes32,bytes)\":{\"details\":\"This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\",\"params\":{\"_hash\":\"Hash value the owner signed\",\"_signature\":\"Signature that signed the above hash\"},\"returns\":{\"magicValue\":\"Bytes4 value representing the success/failure of validation\"}},\"owner()\":{\"returns\":{\"signer\":\"Bytes of owner address\"}},\"uninitializeSigner()\":{\"details\":\"This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\",\"returns\":{\"uninitSuccess\":\"Uint value representing the success of uninit operation\"}},\"validateOwnerSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32)\":{\"details\":\"This method validates if the user operation is signed by the owner. It internally calls validateSignature with signer public key.\",\"params\":{\"userOp\":\"UserOperation including all information for execution\",\"userOpHash\":\"Hash of UserOperation given from EntryPoint. This hash is used for signature validation\"},\"returns\":{\"validationData\":\"Uint value representing whether the validation is successful. 0 for success, 1 for failure\"}},\"validateOwnerSignatureSelector()\":{\"returns\":{\"ownerSignatureValidatorSelector\":\"Bytes4 selector of function signature to validate account owner's UserOperation signature\"}},\"validateSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256[2])\":{\"details\":\"This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\",\"params\":{\"q\":\"Public Key of signer who signed the contract, to be validated\",\"userOp\":\"UserOperation including all information for execution\",\"userOpHash\":\"Hash of UserOperation given from EntryPoint. This hash is used for signature validation\"},\"returns\":{\"isValid\":\"Uint value representing whether the validation is successful. 0 for success, 1 for failure\"}}},\"title\":\"Secp256r1 verification facet\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"This constructor ensures that this contract can only be used as singleton for Proxy contracts\"},\"initializeSigner(bytes)\":{\"notice\":\"Initializes the signer in R1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\"},\"isValidKeyType(bytes)\":{\"notice\":\"Validates if the format of public key is valid for this verification facet\"},\"isValidSignature(bytes32,bytes)\":{\"notice\":\"Validates if the signature is valid. Function to be compatible with EIP-1271\"},\"owner()\":{\"notice\":\"Returns the owner of the account\"},\"uninitializeSigner()\":{\"notice\":\"Uninitialize signer in R1 Facet Storage. This can only be called when the account is undergoing signature migration and has already been initialized.\"},\"validateOwnerSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32)\":{\"notice\":\"Validates if the user operation is signed by the owner.\"},\"validateOwnerSignatureSelector()\":{\"notice\":\"Returns the selector of function to validate the signature of UserOperation\"},\"validateSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256[2])\":{\"notice\":\"Validates if the signature of UserOperation is signed by the given signer\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/verification/secp256r1/Secp256r1VerificationFacet.sol\":\"Secp256r1VerificationFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/utils/math/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\\n * checks.\\n *\\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\\n * easily result in undesired exploitation or bugs, since developers usually\\n * assume that overflows raise errors. `SafeCast` restores this intuition by\\n * reverting the transaction when such an operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n *\\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\\n * all math on `uint256` and `int256` and then downcasting.\\n */\\nlibrary SafeCast {\\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 * _Available since v4.7._\\n */\\n function toUint248(uint256 value) internal pure returns (uint248) {\\n require(value <= type(uint248).max, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint240(uint256 value) internal pure returns (uint240) {\\n require(value <= type(uint240).max, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint232(uint256 value) internal pure returns (uint232) {\\n require(value <= type(uint232).max, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint224(uint256 value) internal pure returns (uint224) {\\n require(value <= type(uint224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint216(uint256 value) internal pure returns (uint216) {\\n require(value <= type(uint216).max, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint208(uint256 value) internal pure returns (uint208) {\\n require(value <= type(uint208).max, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint200(uint256 value) internal pure returns (uint200) {\\n require(value <= type(uint200).max, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint192(uint256 value) internal pure returns (uint192) {\\n require(value <= type(uint192).max, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint184(uint256 value) internal pure returns (uint184) {\\n require(value <= type(uint184).max, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint176(uint256 value) internal pure returns (uint176) {\\n require(value <= type(uint176).max, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint168(uint256 value) internal pure returns (uint168) {\\n require(value <= type(uint168).max, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint160(uint256 value) internal pure returns (uint160) {\\n require(value <= type(uint160).max, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint152(uint256 value) internal pure returns (uint152) {\\n require(value <= type(uint152).max, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint144(uint256 value) internal pure returns (uint144) {\\n require(value <= type(uint144).max, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint136(uint256 value) internal pure returns (uint136) {\\n require(value <= type(uint136).max, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint128(uint256 value) internal pure returns (uint128) {\\n require(value <= type(uint128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint120(uint256 value) internal pure returns (uint120) {\\n require(value <= type(uint120).max, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint112(uint256 value) internal pure returns (uint112) {\\n require(value <= type(uint112).max, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint104(uint256 value) internal pure returns (uint104) {\\n require(value <= type(uint104).max, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint96(uint256 value) internal pure returns (uint96) {\\n require(value <= type(uint96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint88(uint256 value) internal pure returns (uint88) {\\n require(value <= type(uint88).max, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint80(uint256 value) internal pure returns (uint80) {\\n require(value <= type(uint80).max, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint72(uint256 value) internal pure returns (uint72) {\\n require(value <= type(uint72).max, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint64(uint256 value) internal pure returns (uint64) {\\n require(value <= type(uint64).max, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint56(uint256 value) internal pure returns (uint56) {\\n require(value <= type(uint56).max, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint48(uint256 value) internal pure returns (uint48) {\\n require(value <= type(uint48).max, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint40(uint256 value) internal pure returns (uint40) {\\n require(value <= type(uint40).max, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint32(uint256 value) internal pure returns (uint32) {\\n require(value <= type(uint32).max, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint24(uint256 value) internal pure returns (uint24) {\\n require(value <= type(uint24).max, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint16(uint256 value) internal pure returns (uint16) {\\n require(value <= type(uint16).max, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint8(uint256 value) internal pure returns (uint8) {\\n require(value <= type(uint8).max, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\n */\\n function toUint256(int256 value) internal pure returns (uint256) {\\n require(value >= 0, \\\"SafeCast: value must be positive\\\");\\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 * _Available since v4.7._\\n */\\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\\n downcasted = int248(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\\n downcasted = int240(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\\n downcasted = int232(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\\n downcasted = int224(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\\n downcasted = int216(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\\n downcasted = int208(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\\n downcasted = int200(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\\n downcasted = int192(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\\n downcasted = int184(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\\n downcasted = int176(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\\n downcasted = int168(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\\n downcasted = int160(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\\n downcasted = int152(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\\n downcasted = int144(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\\n downcasted = int136(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\\n downcasted = int128(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\\n downcasted = int120(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\\n downcasted = int112(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\\n downcasted = int104(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\\n downcasted = int96(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\\n downcasted = int88(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\\n downcasted = int80(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\\n downcasted = int72(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\\n downcasted = int64(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\\n downcasted = int56(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\\n downcasted = int48(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\\n downcasted = int40(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\\n downcasted = int32(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\\n downcasted = int24(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\\n downcasted = int16(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\\n downcasted = int8(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\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 require(value <= uint256(type(int256).max), \\\"SafeCast: value doesn't fit in an int256\\\");\\n return int256(value);\\n }\\n}\\n\",\"keccak256\":\"0x52a8cfb0f5239d11b457dcdd1b326992ef672714ca8da71a157255bddd13f3ad\",\"license\":\"MIT\"},\"contracts/aa-4337/core/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable no-inline-assembly */\\n\\n/**\\n * returned data from validateUserOp.\\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\\n * @param aggregator - address(0) - the account validated the signature by itself.\\n * address(1) - the account failed to validate the signature.\\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\\n * @param validAfter - this UserOp is valid only after this timestamp.\\n * @param validaUntil - this UserOp is valid only up to this timestamp.\\n */\\nstruct ValidationData {\\n address aggregator;\\n uint48 validAfter;\\n uint48 validUntil;\\n}\\n\\n//extract sigFailed, validAfter, validUntil.\\n// also convert zero validUntil to type(uint48).max\\nfunction _parseValidationData(\\n uint validationData\\n) pure returns (ValidationData memory data) {\\n address aggregator = address(uint160(validationData));\\n uint48 validUntil = uint48(validationData >> 160);\\n if (validUntil == 0) {\\n validUntil = type(uint48).max;\\n }\\n uint48 validAfter = uint48(validationData >> (48 + 160));\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n// intersect account and paymaster ranges.\\nfunction _intersectTimeRange(\\n uint256 validationData,\\n uint256 paymasterValidationData\\n) pure returns (ValidationData memory) {\\n ValidationData memory accountValidationData = _parseValidationData(\\n validationData\\n );\\n ValidationData memory pmValidationData = _parseValidationData(\\n paymasterValidationData\\n );\\n address aggregator = accountValidationData.aggregator;\\n if (aggregator == address(0)) {\\n aggregator = pmValidationData.aggregator;\\n }\\n uint48 validAfter = accountValidationData.validAfter;\\n uint48 validUntil = accountValidationData.validUntil;\\n uint48 pmValidAfter = pmValidationData.validAfter;\\n uint48 pmValidUntil = pmValidationData.validUntil;\\n\\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp\\n * @param data - the ValidationData to pack\\n */\\nfunction _packValidationData(\\n ValidationData memory data\\n) pure returns (uint256) {\\n return\\n uint160(data.aggregator) |\\n (uint256(data.validUntil) << 160) |\\n (uint256(data.validAfter) << (160 + 48));\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp, when not using an aggregator\\n * @param sigFailed - true for signature failure, false for success\\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\\n * @param validAfter first timestamp this UserOperation is valid\\n */\\nfunction _packValidationData(\\n bool sigFailed,\\n uint48 validUntil,\\n uint48 validAfter\\n) pure returns (uint256) {\\n return\\n (sigFailed ? 1 : 0) |\\n (uint256(validUntil) << 160) |\\n (uint256(validAfter) << (160 + 48));\\n}\\n\\n/**\\n * keccak function over calldata.\\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\\n */\\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\\n assembly {\\n let mem := mload(0x40)\\n let len := data.length\\n calldatacopy(mem, data.offset, len)\\n ret := keccak256(mem, len)\\n }\\n}\\n\",\"keccak256\":\"0xa79f06cd158ecb8c0da95493a2f348933b8627a63e228b99738bff3aa107942d\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAggregator.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\n/**\\n * Aggregated Signatures validator.\\n */\\ninterface IAggregator {\\n /**\\n * validate aggregated signature.\\n * revert if the aggregated signature does not match the given list of operations.\\n */\\n function validateSignatures(\\n UserOperation[] calldata userOps,\\n bytes calldata signature\\n ) external view;\\n\\n /**\\n * validate signature of a single userOp\\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\\n * @param userOp the userOperation received from the user.\\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\\n * (usually empty, unless account and aggregator support some kind of \\\"multisig\\\"\\n */\\n function validateUserOpSignature(\\n UserOperation calldata userOp\\n ) external view returns (bytes memory sigForUserOp);\\n\\n /**\\n * aggregate multiple signatures into a single value.\\n * This method is called off-chain to calculate the signature to pass with handleOps()\\n * bundler MAY use optimized custom code perform this aggregation\\n * @param userOps array of UserOperations to collect the signatures from.\\n * @return aggregatedSignature the aggregated signature\\n */\\n function aggregateSignatures(\\n UserOperation[] calldata userOps\\n ) external view returns (bytes memory aggregatedSignature);\\n}\\n\",\"keccak256\":\"0xdfdcd80568f037716674619b31be630fcd8316262f05a815b41d1e81782c966a\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IEntryPoint.sol\":{\"content\":\"/**\\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\\n ** Only one instance required on each chain.\\n **/\\n// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-inline-assembly */\\n/* solhint-disable reason-string */\\n\\nimport \\\"./UserOperation.sol\\\";\\nimport \\\"./IStakeManager.sol\\\";\\nimport \\\"./IAggregator.sol\\\";\\nimport \\\"./INonceManager.sol\\\";\\n\\ninterface IEntryPoint is IStakeManager, INonceManager {\\n /***\\n * An event emitted after each successful request\\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\\n * @param sender - the account that generates this request.\\n * @param paymaster - if non-null, the paymaster that pays for this request.\\n * @param nonce - the nonce value from the request.\\n * @param success - true if the sender transaction succeeded, false if reverted.\\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\\n */\\n event UserOperationEvent(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address indexed paymaster,\\n uint256 nonce,\\n bool success,\\n uint256 actualGasCost,\\n uint256 actualGasUsed\\n );\\n\\n /**\\n * account \\\"sender\\\" was deployed.\\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\\n * @param sender the account that is deployed\\n * @param factory the factory used to deploy this account (in the initCode)\\n * @param paymaster the paymaster used by this UserOp\\n */\\n event AccountDeployed(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address factory,\\n address paymaster\\n );\\n\\n /**\\n * An event emitted if the UserOperation \\\"callData\\\" reverted with non-zero length\\n * @param userOpHash the request unique identifier.\\n * @param sender the sender of this request\\n * @param nonce the nonce used in the request\\n * @param revertReason - the return bytes from the (reverted) call to \\\"callData\\\".\\n */\\n event UserOperationRevertReason(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n uint256 nonce,\\n bytes revertReason\\n );\\n\\n /**\\n * an event emitted by handleOps(), before starting the execution loop.\\n * any event emitted before this event, is part of the validation.\\n */\\n event BeforeExecution();\\n\\n /**\\n * signature aggregator used by the following UserOperationEvents within this bundle.\\n */\\n event SignatureAggregatorChanged(address indexed aggregator);\\n\\n /**\\n * a custom revert error of handleOps, to identify the offending op.\\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\\n * @param reason - revert reason\\n * The string starts with a unique code \\\"AAmn\\\", where \\\"m\\\" is \\\"1\\\" for factory, \\\"2\\\" for account and \\\"3\\\" for paymaster issues,\\n * so a failure can be attributed to the correct entity.\\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\\n */\\n error FailedOp(uint256 opIndex, string reason);\\n\\n /**\\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\\n */\\n error SignatureValidationFailed(address aggregator);\\n\\n /**\\n * Successful result from simulateValidation.\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n */\\n error ValidationResult(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo\\n );\\n\\n /**\\n * Successful result from simulateValidation, if the account returns a signature aggregator\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\\n * bundler MUST use it to verify the signature, or reject the UserOperation\\n */\\n error ValidationResultWithAggregation(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo,\\n AggregatorStakeInfo aggregatorInfo\\n );\\n\\n /**\\n * return value of getSenderAddress\\n */\\n error SenderAddressResult(address sender);\\n\\n /**\\n * return value of simulateHandleOp\\n */\\n error ExecutionResult(\\n uint256 preOpGas,\\n uint256 paid,\\n uint48 validAfter,\\n uint48 validUntil,\\n bool targetSuccess,\\n bytes targetResult\\n );\\n\\n //UserOps handled, per aggregator\\n struct UserOpsPerAggregator {\\n UserOperation[] userOps;\\n // aggregator address\\n IAggregator aggregator;\\n // aggregated signature\\n bytes signature;\\n }\\n\\n /**\\n * Execute a batch of UserOperation.\\n * no signature aggregator is used.\\n * if any account requires an aggregator (that is, it returned an aggregator when\\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\\n * @param ops the operations to execute\\n * @param beneficiary the address to receive the fees\\n */\\n function handleOps(\\n UserOperation[] calldata ops,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * Execute a batch of UserOperation with Aggregators\\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\\n * @param beneficiary the address to receive the fees\\n */\\n function handleAggregatedOps(\\n UserOpsPerAggregator[] calldata opsPerAggregator,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * generate a request Id - unique identifier for this request.\\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\\n */\\n function getUserOpHash(\\n UserOperation calldata userOp\\n ) external view returns (bytes32);\\n\\n /**\\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\\n * @param userOp the user operation to validate.\\n */\\n function simulateValidation(UserOperation calldata userOp) external;\\n\\n /**\\n * gas and return values during simulation\\n * @param preOpGas the gas used for validation (including preValidationGas)\\n * @param prefund the required prefund for this operation\\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\\n */\\n struct ReturnInfo {\\n uint256 preOpGas;\\n uint256 prefund;\\n bool sigFailed;\\n uint48 validAfter;\\n uint48 validUntil;\\n bytes paymasterContext;\\n }\\n\\n /**\\n * returned aggregated signature info.\\n * the aggregator returned by the account, and its current stake.\\n */\\n struct AggregatorStakeInfo {\\n address aggregator;\\n StakeInfo stakeInfo;\\n }\\n\\n /**\\n * Get counterfactual sender address.\\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\\n * this method always revert, and returns the address in SenderAddressResult error\\n * @param initCode the constructor code to be passed into the UserOperation.\\n */\\n function getSenderAddress(bytes memory initCode) external;\\n\\n /**\\n * simulate full execution of a UserOperation (including both validation and target execution)\\n * this method will always revert with \\\"ExecutionResult\\\".\\n * it performs full validation of the UserOperation, but ignores signature error.\\n * an optional target address is called after the userop succeeds, and its value is returned\\n * (before the entire call is reverted)\\n * Note that in order to collect the the success/failure of the target call, it must be executed\\n * with trace enabled to track the emitted events.\\n * @param op the UserOperation to simulate\\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\\n * are set to the return from that call.\\n * @param targetCallData callData to pass to target address\\n */\\n function simulateHandleOp(\\n UserOperation calldata op,\\n address target,\\n bytes calldata targetCallData\\n ) external;\\n}\\n\",\"keccak256\":\"0x9ccb1b188eda8bbf5f6c2d01bd83c3d8b2b04fcf745283051d31fe96d1d8e40f\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/INonceManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\ninterface INonceManager {\\n /**\\n * Return the next nonce for this sender.\\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\\n * But UserOp with different keys can come with arbitrary order.\\n *\\n * @param sender the account address\\n * @param key the high 192 bit of the nonce\\n * @return nonce a full nonce to pass for next UserOp with this sender.\\n */\\n function getNonce(\\n address sender,\\n uint192 key\\n ) external view returns (uint256 nonce);\\n\\n /**\\n * Manually increment the nonce of the sender.\\n * This method is exposed just for completeness..\\n * Account does NOT need to call it, neither during validation, nor elsewhere,\\n * as the EntryPoint will update the nonce regardless.\\n * Possible use-case is call it with various keys to \\\"initialize\\\" their nonces to one, so that future\\n * UserOperations will not pay extra for the first transaction with a given key.\\n */\\n function incrementNonce(uint192 key) external;\\n}\\n\",\"keccak256\":\"0xce478ad0fa0d18a3b785ac854623029e7ab463d05873dfaa365abfa1bf100912\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IStakeManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8.12;\\n\\n/**\\n * manage deposits and stakes.\\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\\n * stake is value locked for at least \\\"unstakeDelay\\\" by the staked entity.\\n */\\ninterface IStakeManager {\\n event Deposited(address indexed account, uint256 totalDeposit);\\n\\n event Withdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /// Emitted when stake or unstake delay are modified\\n event StakeLocked(\\n address indexed account,\\n uint256 totalStaked,\\n uint256 unstakeDelaySec\\n );\\n\\n /// Emitted once a stake is scheduled for withdrawal\\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\\n\\n event StakeWithdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /**\\n * @param deposit the entity's deposit\\n * @param staked true if this entity is staked.\\n * @param stake actual amount of ether staked for this entity.\\n * @param unstakeDelaySec minimum delay to withdraw the stake.\\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\\n * and the rest fit into a 2nd cell.\\n * 112 bit allows for 10^15 eth\\n * 48 bit for full timestamp\\n * 32 bit allows 150 years for unstake delay\\n */\\n struct DepositInfo {\\n uint112 deposit;\\n bool staked;\\n uint112 stake;\\n uint32 unstakeDelaySec;\\n uint48 withdrawTime;\\n }\\n\\n //API struct used by getStakeInfo and simulateValidation\\n struct StakeInfo {\\n uint256 stake;\\n uint256 unstakeDelaySec;\\n }\\n\\n /// @return info - full deposit information of given account\\n function getDepositInfo(\\n address account\\n ) external view returns (DepositInfo memory info);\\n\\n /// @return the deposit (for gas payment) of the account\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * add to the deposit of the given account\\n */\\n function depositTo(address account) external payable;\\n\\n /**\\n * add to the account's stake - amount and delay\\n * any pending unstake is first cancelled.\\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\\n */\\n function addStake(uint32 _unstakeDelaySec) external payable;\\n\\n /**\\n * attempt to unlock the stake.\\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\\n */\\n function unlockStake() external;\\n\\n /**\\n * withdraw from the (unlocked) stake.\\n * must first call unlockStake and wait for the unstakeDelay to pass\\n * @param withdrawAddress the address to send withdrawn value.\\n */\\n function withdrawStake(address payable withdrawAddress) external;\\n\\n /**\\n * withdraw from the deposit.\\n * @param withdrawAddress the address to send withdrawn value.\\n * @param withdrawAmount the amount to withdraw.\\n */\\n function withdrawTo(\\n address payable withdrawAddress,\\n uint256 withdrawAmount\\n ) external;\\n}\\n\",\"keccak256\":\"0xadcea606c9b7aafe6645441f2154a60f271330b0eee5292a632aa71c1672d546\",\"license\":\"GPL-3.0-only\"},\"contracts/aa-4337/interfaces/UserOperation.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable no-inline-assembly */\\n\\nimport {calldataKeccak} from \\\"../core/Helpers.sol\\\";\\n\\n/**\\n * User Operation struct\\n * @param sender the sender account of this request.\\n * @param nonce unique value the sender uses to verify it is not a replay.\\n * @param initCode if set, the account contract will be created by this constructor/\\n * @param callData the method call to execute on this account.\\n * @param callGasLimit the gas limit passed to the callData method call.\\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\\n * @param maxFeePerGas same as EIP-1559 gas parameter.\\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\\n */\\nstruct UserOperation {\\n address sender;\\n uint256 nonce;\\n bytes initCode;\\n bytes callData;\\n uint256 callGasLimit;\\n uint256 verificationGasLimit;\\n uint256 preVerificationGas;\\n uint256 maxFeePerGas;\\n uint256 maxPriorityFeePerGas;\\n bytes paymasterAndData;\\n bytes signature;\\n}\\n\\n/**\\n * Utility functions helpful when working with UserOperation structs.\\n */\\nlibrary UserOperationLib {\\n function getSender(\\n UserOperation calldata userOp\\n ) internal pure returns (address) {\\n address data;\\n //read sender from userOp, which is first userOp member (saves 800 gas...)\\n assembly {\\n data := calldataload(userOp)\\n }\\n return address(uint160(data));\\n }\\n\\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\\n // pay above what he signed for.\\n function gasPrice(\\n UserOperation calldata userOp\\n ) internal view returns (uint256) {\\n unchecked {\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n if (maxFeePerGas == maxPriorityFeePerGas) {\\n //legacy mode (for networks that don't support basefee opcode)\\n return maxFeePerGas;\\n }\\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\\n }\\n }\\n\\n function pack(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes memory ret) {\\n address sender = getSender(userOp);\\n uint256 nonce = userOp.nonce;\\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\\n bytes32 hashCallData = calldataKeccak(userOp.callData);\\n uint256 callGasLimit = userOp.callGasLimit;\\n uint256 verificationGasLimit = userOp.verificationGasLimit;\\n uint256 preVerificationGas = userOp.preVerificationGas;\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\\n\\n return\\n abi.encode(\\n sender,\\n nonce,\\n hashInitCode,\\n hashCallData,\\n callGasLimit,\\n verificationGasLimit,\\n preVerificationGas,\\n maxFeePerGas,\\n maxPriorityFeePerGas,\\n hashPaymasterAndData\\n );\\n }\\n\\n function hash(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes32) {\\n return keccak256(pack(userOp));\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n}\\n\",\"keccak256\":\"0x2429f5cc546bdee08c7e63858d0dda8491eaa3ab5194df884dc948c1154d2834\",\"license\":\"GPL-3.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/facets/interfaces/IVerificationFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {UserOperation} from \\\"../../aa-4337/interfaces/UserOperation.sol\\\";\\n\\n/**\\n * @title Verification Facet Interface\\n * @dev Implements logic for user ops signature verification\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\ninterface IVerificationFacet {\\n event SignerInitialized(bytes);\\n event SignerUninitialized();\\n\\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\\n error VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\\n error VerificationFacet__InitializationFailure();\\n error VerificationFacet__InvalidFacetMapping();\\n\\n function initializeSigner(bytes memory) external returns (uint256);\\n\\n function uninitializeSigner() external returns (uint256);\\n\\n function validateOwnerSignatureSelector() external view returns (bytes4);\\n\\n function owner() external view returns (bytes memory);\\n\\n function isValidKeyType(bytes calldata) external view returns (bool);\\n\\n function validateOwnerSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x72bc370a1d1b5a6d6bde67f5026733fd8f6ba434bb90e73b0bd8627fb1579928\",\"license\":\"Apache-2.0\"},\"contracts/facets/verification/secp256r1/Secp256r1VerificationFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {UserOperation} from \\\"../../../aa-4337/interfaces/UserOperation.sol\\\";\\nimport {LibAppStorage} from \\\"../../../libraries/LibAppStorage.sol\\\";\\nimport {LibLoupe} from \\\"../../../libraries/LibLoupe.sol\\\";\\nimport {LibFacetStorage, Secp256r1VerificationStorage} from \\\"../../../libraries/LibFacetStorage.sol\\\";\\nimport {Base64} from \\\"./utils/Base64.sol\\\";\\nimport {LibSecp256r1} from \\\"./utils/LibSecp256r1.sol\\\";\\nimport {IERC1271} from \\\"../../../interfaces/ERC/IERC1271.sol\\\";\\nimport {IVerificationFacet} from \\\"../../interfaces/IVerificationFacet.sol\\\";\\n\\n/**\\n * @title Secp256r1 verification facet\\n * @dev Primarily used to verify user ops signed with passkeys\\n * @author Ruslan Serebriakov (@rsrbk)\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract Secp256r1VerificationFacet is IVerificationFacet, IERC1271 {\\n error Secp256r1VerificationFacet__InvalidSignerLength();\\n address public immutable self;\\n\\n /**\\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\\n */\\n constructor() {\\n LibAppStorage.enforceSignerInitialize();\\n self = address(this);\\n }\\n\\n /**\\n * @notice Initializes the signer in R1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\\n * @param _publicKey Bytes of owner public key\\n * @return initSuccess Uint value representing the success of init operation\\n */\\n function initializeSigner(\\n bytes calldata _publicKey\\n ) public override returns (uint256 initSuccess) {\\n LibAppStorage.enforceSignerInitialize();\\n\\n if (!isValidKeyType(_publicKey))\\n revert Secp256r1VerificationFacet__InvalidSignerLength();\\n\\n bytes memory publicKeyCoordinates = _publicKey[1:];\\n uint256[2] memory q;\\n assembly {\\n // Copy the bytes from the input data into the uint256 array\\n mstore(q, mload(add(publicKeyCoordinates, 32)))\\n mstore(add(q, 32), mload(add(publicKeyCoordinates, 64)))\\n }\\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\\n .r1Storage();\\n r1Storage.q = q;\\n\\n bytes4 validateSelector = validateOwnerSignatureSelector();\\n\\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\\n if (LibLoupe.facetAddress(validateSelector) != self)\\n revert VerificationFacet__InvalidFacetMapping();\\n\\n // initialize verification function selector\\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\\n\\n initSuccess = 1;\\n\\n emit SignerInitialized(_publicKey);\\n }\\n\\n /**\\n * @notice Uninitialize signer in R1 Facet Storage. This can only be called when the account is undergoing signature migration\\n * and has already been initialized.\\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\\n * @return uninitSuccess Uint value representing the success of uninit operation\\n */\\n function uninitializeSigner()\\n external\\n override\\n returns (uint256 uninitSuccess)\\n {\\n LibAppStorage.enforceSignerMigration();\\n LibAppStorage.setSignerUninitialized();\\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\\n .r1Storage();\\n r1Storage.q = [0, 0];\\n\\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\\n\\n uninitSuccess = 1;\\n\\n emit SignerUninitialized();\\n }\\n\\n /**\\n * @notice Validates if the user operation is signed by the owner.\\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\\n * signer public key.\\n * @param userOp UserOperation including all information for execution\\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\\n */\\n function validateOwnerSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) public view override returns (uint256 validationData) {\\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\\n .r1Storage();\\n validationData = validateSignature(userOp, userOpHash, r1Storage.q);\\n }\\n\\n /**\\n * @notice Validates if the signature of UserOperation is signed by the given signer\\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\\n * @param userOp UserOperation including all information for execution\\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\\n * @param q Public Key of signer who signed the contract, to be validated\\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\\n */\\n function validateSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n uint256[2] memory q\\n ) public view returns (uint256 isValid) {\\n isValid = (_validateSignature(q, userOpHash, userOp.signature)) ? 0 : 1;\\n }\\n\\n /**\\n * @notice Returns the selector of function to validate the signature of UserOperation\\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\\n */\\n function validateOwnerSignatureSelector()\\n public\\n pure\\n override\\n returns (bytes4 ownerSignatureValidatorSelector)\\n {\\n return this.validateOwnerSignature.selector; // validateOwnerSignature(UserOperation calldata userOp,bytes32 userOpHash)\\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\\n }\\n\\n /**\\n * @notice Returns the owner of the account\\n * @return signer Bytes of owner address\\n */\\n function owner() public view override returns (bytes memory signer) {\\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\\n .r1Storage();\\n signer = abi.encodePacked(r1Storage.q);\\n }\\n\\n /**\\n * @notice Validates if the format of public key is valid for this verification facet\\n * @dev For this Secp256k1Verification Facet, the public key should in an uncompressed public key format\\n * @param _publicKey Bytes of public key for format check\\n * @return isValid Boolean variable representing if the format of public key is valid\\n */\\n function isValidKeyType(\\n bytes memory _publicKey\\n ) public pure override returns (bool isValid) {\\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\\n }\\n\\n /**\\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\\n * @param _hash Hash value the owner signed\\n * @param _signature Signature that signed the above hash\\n * @return magicValue Bytes4 value representing the success/failure of validation\\n */\\n function isValidSignature(\\n bytes32 _hash,\\n bytes memory _signature\\n ) public view override returns (bytes4 magicValue) {\\n magicValue = _validateSignature(\\n LibFacetStorage.r1Storage().q,\\n _hash,\\n _signature\\n )\\n ? this.isValidSignature.selector\\n : bytes4(0xffffffff);\\n }\\n\\n function _validateSignature(\\n uint256[2] memory q,\\n bytes32 _hash,\\n bytes memory _signature\\n ) internal view returns (bool) {\\n (\\n uint256 rValue,\\n uint256 sValue,\\n bytes memory authenticatorData,\\n string memory clientDataJSONPre,\\n string memory clientDataJSONPost\\n ) = abi.decode(_signature, (uint256, uint256, bytes, string, string));\\n bytes32 clientHash;\\n {\\n string memory opHashBase64 = Base64.encode(bytes.concat(_hash));\\n string memory clientDataJSON = string.concat(\\n clientDataJSONPre,\\n opHashBase64,\\n clientDataJSONPost\\n );\\n clientHash = sha256(bytes(clientDataJSON));\\n }\\n bytes32 sigHash = sha256(bytes.concat(authenticatorData, clientHash));\\n return LibSecp256r1.Verify(q, rValue, sValue, uint256(sigHash));\\n }\\n}\\n\",\"keccak256\":\"0xdb3bae77323eef4e16ef5a5342f548527c9e82b44e8e9dab90906dc2c00082ff\",\"license\":\"Apache-2.0\"},\"contracts/facets/verification/secp256r1/utils/Base64.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @dev Provides a set of functions to operate with Base64 strings.\\n * modified for base64url https://datatracker.ietf.org/doc/html/rfc4648#section-5\\n * _Available since v4.5._\\n */\\nlibrary Base64 {\\n /**\\n * @dev Base64 Encoding/Decoding Table\\n */\\n string internal constant _TABLE =\\n \\\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_\\\";\\n\\n /**\\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\\n */\\n function encode(bytes memory data) internal pure returns (string memory) {\\n /**\\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\\n */\\n if (data.length == 0) return \\\"\\\";\\n\\n // Loads the table into memory\\n string memory table = _TABLE;\\n\\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\\n // and split into 4 numbers of 6 bits.\\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\\n // - `data.length + 2` -> Round up\\n // - `/ 3` -> Number of 3-bytes chunks\\n // - `4 *` -> 4 characters for each chunk\\n uint256 newlength = (data.length * 8) / 6;\\n if (data.length % 6 > 0) {\\n newlength++;\\n }\\n string memory result = new string(newlength);\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n // Prepare the lookup table (skip the first \\\"length\\\" byte)\\n let tablePtr := add(table, 1)\\n\\n // Prepare result pointer, jump over length\\n let resultPtr := add(result, 32)\\n\\n // Run over the input, 3 bytes at a time\\n for {\\n let dataPtr := data\\n let endPtr := add(data, mload(data))\\n } lt(dataPtr, endPtr) {\\n\\n } {\\n // Advance 3 bytes\\n dataPtr := add(dataPtr, 3)\\n let input := mload(dataPtr)\\n\\n // To write each character, shift the 3 bytes (18 bits) chunk\\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\\n // and apply logical AND with 0x3F which is the number of\\n // the previous character in the ASCII table prior to the Base64 Table\\n // The result is then added to the table to get the character to write,\\n // and finally write it in the result pointer but with a left shift\\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\\n\\n mstore8(\\n resultPtr,\\n mload(add(tablePtr, and(shr(18, input), 0x3F)))\\n )\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(\\n resultPtr,\\n mload(add(tablePtr, and(shr(12, input), 0x3F)))\\n )\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(\\n resultPtr,\\n mload(add(tablePtr, and(shr(6, input), 0x3F)))\\n )\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n }\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0xbf0afa21e5a128f260c1a8d4333dc0b0e8755a50d37dfa9b5d362d36ef9cdc14\",\"license\":\"Apache-2.0\"},\"contracts/facets/verification/secp256r1/utils/LibSecp256r1.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n// Heavily inspired from\\n// https://github.com/maxrobot/elliptic-solidity/blob/master/contracts/Secp256r1.sol\\n// https://github.com/tdrerup/elliptic-curve-solidity/blob/master/contracts/curves/EllipticCurve.sol\\n// modified to use precompile 0x05 modexp\\n// and modified jacobian double\\n// optimisations to avoid to an from from affine and jacobian coordinates\\n\\n// Additional Elliptic curve Public key / Signature validation added by\\n// David Yonjun Kim (@Powerstream3604)\\n\\nstruct JPoint {\\n uint256 x;\\n uint256 y;\\n uint256 z;\\n}\\n\\nlibrary LibSecp256r1 {\\n uint256 constant gx =\\n 0x6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296;\\n uint256 constant gy =\\n 0x4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5;\\n uint256 public constant pp =\\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF;\\n\\n uint256 public constant nn =\\n 0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551;\\n uint256 constant a =\\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC;\\n uint256 constant b =\\n 0x5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B;\\n uint256 constant MOST_SIGNIFICANT =\\n 0xc000000000000000000000000000000000000000000000000000000000000000;\\n\\n /*\\n * Verify\\n * @description - verifies that a public key has signed a given message\\n * @param Q - public key coordinates X & Y\\n * @param R - signature half R\\n * @param S - signature half S\\n * @param input - hashed message\\n */\\n function Verify(\\n uint256[2] memory q,\\n uint r,\\n uint s,\\n uint e\\n ) internal view returns (bool) {\\n if (q[0] > pp - 1 || q[1] > pp - 1) {\\n return false;\\n }\\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\\n return false;\\n }\\n if (\\n mulmod(q[1], q[1], pp) !=\\n addmod(\\n addmod(\\n mulmod(q[0], mulmod(q[0], q[0], pp), pp),\\n mulmod(a, q[0], pp),\\n pp\\n ),\\n b,\\n pp\\n )\\n ) {\\n return false;\\n }\\n\\n JPoint[16] memory points = _preComputeJacobianPoints(q);\\n return VerifyWithPrecompute(points, r, s, e);\\n }\\n\\n function VerifyWithPrecompute(\\n JPoint[16] memory points,\\n uint r,\\n uint s,\\n uint e\\n ) internal view returns (bool) {\\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\\n return false;\\n }\\n\\n uint w = _primemod(s, nn);\\n\\n uint u1 = mulmod(e, w, nn);\\n uint u2 = mulmod(r, w, nn);\\n\\n uint x;\\n uint y;\\n\\n (x, y) = ShamirMultJacobian(points, u1, u2);\\n return (x == r);\\n }\\n\\n /*\\n * Strauss Shamir trick for EC multiplication\\n * https://stackoverflow.com/questions/50993471/ec-scalar-multiplication-with-strauss-shamir-method\\n * we optimise on this a bit to do with 2 bits at a time rather than a single bit\\n * the individual points for a single pass are precomputed\\n * overall this reduces the number of additions while keeping the same number of doublings\\n */\\n function ShamirMultJacobian(\\n JPoint[16] memory points,\\n uint u1,\\n uint u2\\n ) internal view returns (uint, uint) {\\n uint x = 0;\\n uint y = 0;\\n uint z = 0;\\n uint bits = 128;\\n uint index = 0;\\n\\n while (bits > 0) {\\n if (z > 0) {\\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\\n }\\n index =\\n ((u1 & MOST_SIGNIFICANT) >> 252) |\\n ((u2 & MOST_SIGNIFICANT) >> 254);\\n if (index > 0) {\\n (x, y, z) = _jAdd(\\n x,\\n y,\\n z,\\n points[index].x,\\n points[index].y,\\n points[index].z\\n );\\n }\\n u1 <<= 2;\\n u2 <<= 2;\\n bits--;\\n }\\n (x, y) = _affineFromJacobian(x, y, z);\\n return (x, y);\\n }\\n\\n function _preComputeJacobianPoints(\\n uint256[2] memory q\\n ) internal pure returns (JPoint[16] memory points) {\\n points[0] = JPoint(0, 0, 0);\\n points[1] = JPoint(q[0], q[1], 1); // u2\\n points[2] = _jPointDouble(points[1]);\\n points[3] = _jPointAdd(points[1], points[2]);\\n\\n points[4] = JPoint(gx, gy, 1); // u1Points[1]\\n points[5] = _jPointAdd(points[4], points[1]);\\n points[6] = _jPointAdd(points[4], points[2]);\\n points[7] = _jPointAdd(points[4], points[3]);\\n\\n points[8] = _jPointDouble(points[4]); // u1Points[2]\\n points[9] = _jPointAdd(points[8], points[1]);\\n points[10] = _jPointAdd(points[8], points[2]);\\n points[11] = _jPointAdd(points[8], points[3]);\\n\\n points[12] = _jPointAdd(points[4], points[8]); // u1Points[3]\\n points[13] = _jPointAdd(points[12], points[1]);\\n points[14] = _jPointAdd(points[12], points[2]);\\n points[15] = _jPointAdd(points[12], points[3]);\\n }\\n\\n function _jPointAdd(\\n JPoint memory p1,\\n JPoint memory p2\\n ) internal pure returns (JPoint memory) {\\n uint x;\\n uint y;\\n uint z;\\n (x, y, z) = _jAdd(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z);\\n return JPoint(x, y, z);\\n }\\n\\n function _jPointDouble(\\n JPoint memory p\\n ) internal pure returns (JPoint memory) {\\n uint x;\\n uint y;\\n uint z;\\n (x, y, z) = _modifiedJacobianDouble(p.x, p.y, p.z);\\n return JPoint(x, y, z);\\n }\\n\\n /* _affineFromJacobian\\n * @desription returns affine coordinates from a jacobian input follows\\n * golang elliptic/crypto library\\n */\\n function _affineFromJacobian(\\n uint x,\\n uint y,\\n uint z\\n ) internal view returns (uint ax, uint ay) {\\n if (z == 0) {\\n return (0, 0);\\n }\\n\\n uint zinv = _primemod(z, pp);\\n uint zinvsq = mulmod(zinv, zinv, pp);\\n\\n ax = mulmod(x, zinvsq, pp);\\n ay = mulmod(y, mulmod(zinvsq, zinv, pp), pp);\\n }\\n\\n /*\\n * _jAdd\\n * @description performs Jacobian addition as defined below:\\n * http://www.hyperelliptic.org/EFD/g1p/data/shortw/jacobian/addition/add-2007-bl\\n */\\n function _jAdd(\\n uint p1,\\n uint p2,\\n uint p3,\\n uint q1,\\n uint q2,\\n uint q3\\n ) internal pure returns (uint r1, uint r2, uint r3) {\\n if (p3 == 0) {\\n r1 = q1;\\n r2 = q2;\\n r3 = q3;\\n\\n return (r1, r2, r3);\\n } else if (q3 == 0) {\\n r1 = p1;\\n r2 = p2;\\n r3 = p3;\\n\\n return (r1, r2, r3);\\n }\\n\\n assembly {\\n let\\n pd\\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\\n let z1z1 := mulmod(p3, p3, pd) // Z1Z1 = Z1^2\\n let z2z2 := mulmod(q3, q3, pd) // Z2Z2 = Z2^2\\n\\n let u1 := mulmod(p1, z2z2, pd) // U1 = X1*Z2Z2\\n let u2 := mulmod(q1, z1z1, pd) // U2 = X2*Z1Z1\\n\\n let s1 := mulmod(p2, mulmod(z2z2, q3, pd), pd) // S1 = Y1*Z2*Z2Z2\\n let s2 := mulmod(q2, mulmod(z1z1, p3, pd), pd) // S2 = Y2*Z1*Z1Z1\\n\\n let p3q3 := addmod(p3, q3, pd)\\n\\n if lt(u2, u1) {\\n u2 := add(pd, u2) // u2 = u2+pd\\n }\\n let h := sub(u2, u1) // H = U2-U1\\n\\n let i := mulmod(0x02, h, pd)\\n i := mulmod(i, i, pd) // I = (2*H)^2\\n\\n let j := mulmod(h, i, pd) // J = H*I\\n if lt(s2, s1) {\\n s2 := add(pd, s2) // u2 = u2+pd\\n }\\n let rr := mulmod(0x02, sub(s2, s1), pd) // r = 2*(S2-S1)\\n r1 := mulmod(rr, rr, pd) // X3 = R^2\\n\\n let v := mulmod(u1, i, pd) // V = U1*I\\n let j2v := addmod(j, mulmod(0x02, v, pd), pd)\\n if lt(r1, j2v) {\\n r1 := add(pd, r1) // X3 = X3+pd\\n }\\n r1 := sub(r1, j2v)\\n\\n // Y3 = r*(V-X3)-2*S1*J\\n let s12j := mulmod(mulmod(0x02, s1, pd), j, pd)\\n\\n if lt(v, r1) {\\n v := add(pd, v)\\n }\\n r2 := mulmod(rr, sub(v, r1), pd)\\n\\n if lt(r2, s12j) {\\n r2 := add(pd, r2)\\n }\\n r2 := sub(r2, s12j)\\n\\n // Z3 = ((Z1+Z2)^2-Z1Z1-Z2Z2)*H\\n z1z1 := addmod(z1z1, z2z2, pd)\\n j2v := mulmod(p3q3, p3q3, pd)\\n if lt(j2v, z1z1) {\\n j2v := add(pd, j2v)\\n }\\n r3 := mulmod(sub(j2v, z1z1), h, pd)\\n }\\n return (r1, r2, r3);\\n }\\n\\n // Point doubling on the modified jacobian coordinates\\n // http://point-at-infinity.org/ecc/Prime_Curve_Modified_Jacobian_Coordinates.html\\n function _modifiedJacobianDouble(\\n uint x,\\n uint y,\\n uint z\\n ) internal pure returns (uint x3, uint y3, uint z3) {\\n if (y == 0) return (0, 0, 0);\\n assembly {\\n let\\n pd\\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\\n let z2 := mulmod(z, z, pd)\\n let az4 := mulmod(\\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC,\\n mulmod(z2, z2, pd),\\n pd\\n )\\n let y2 := mulmod(y, y, pd)\\n let s := mulmod(0x04, mulmod(x, y2, pd), pd)\\n let u := mulmod(0x08, mulmod(y2, y2, pd), pd)\\n let m := addmod(mulmod(0x03, mulmod(x, x, pd), pd), az4, pd)\\n let twos := mulmod(0x02, s, pd)\\n let m2 := mulmod(m, m, pd)\\n if lt(m2, twos) {\\n m2 := add(pd, m2)\\n }\\n x3 := sub(m2, twos)\\n if lt(s, x3) {\\n s := add(pd, s)\\n }\\n y3 := mulmod(m, sub(s, x3), pd)\\n if lt(y3, u) {\\n y3 := add(pd, y3)\\n }\\n y3 := sub(y3, u)\\n z3 := mulmod(0x02, mulmod(y, z, pd), pd)\\n }\\n }\\n\\n // Fermats little theorem https://en.wikipedia.org/wiki/Fermat%27s_little_theorem\\n // a^(p-1) = 1 mod p\\n // a^(-1) \\u2245 a^(p-2) (mod p)\\n // we then use the precompile bigModExp to compute a^(-1)\\n function _primemod(uint value, uint p) internal view returns (uint ret) {\\n ret = modexp(value, p - 2, p);\\n return ret;\\n }\\n\\n // Wrapper for built-in BigNumber_modexp (contract 0x5) as described here. https://github.com/ethereum/EIPs/pull/198\\n function modexp(\\n uint _base,\\n uint _exp,\\n uint _mod\\n ) internal view returns (uint ret) {\\n // bigModExp(_base, _exp, _mod);\\n assembly {\\n if gt(_base, _mod) {\\n _base := mod(_base, _mod)\\n }\\n // Free memory pointer is always stored at 0x40\\n let freemem := mload(0x40)\\n\\n mstore(freemem, 0x20)\\n mstore(add(freemem, 0x20), 0x20)\\n mstore(add(freemem, 0x40), 0x20)\\n\\n mstore(add(freemem, 0x60), _base)\\n mstore(add(freemem, 0x80), _exp)\\n mstore(add(freemem, 0xa0), _mod)\\n\\n let success := staticcall(14000, 0x5, freemem, 0xc0, freemem, 0x20)\\n switch success\\n case 0 {\\n revert(0x0, 0x0)\\n }\\n default {\\n ret := mload(freemem)\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb53714ba63cddb379ba312c1e7f6a423f4d7a7e34fa1364ec8295cd57d544024\",\"license\":\"GPL-3.0\"},\"contracts/infrastructure/interfaces/IFacetRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Registry Interface\\n * @dev Interface for Facet Registry contract to keep track of facets & function selectors addable to user wallets\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IFacetRegistry {\\n struct FacetRegistryConfig {\\n bytes4[] selectors;\\n mapping(bytes4 => FacetInfo) info;\\n }\\n struct FacetInfo {\\n bool exists;\\n uint128 index;\\n }\\n\\n event FacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] facetSelectors\\n );\\n event FacetFunctionSelectorsRemoved(address facet, bytes4[] facetSelectors);\\n\\n error FacetRegistry__FacetSelectorAlreadyRegistered();\\n error FacetRegistry__UnregisteredFacetSelector();\\n\\n function registerFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function removeFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function areFacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external view returns (bool);\\n\\n function isFacetFunctionSelectorRegistered(\\n address facet,\\n bytes4 facetSelector\\n ) external view returns (bool);\\n\\n function getFacetFunctionSelectors(\\n address facet\\n ) external view returns (bytes4[] memory);\\n}\\n\",\"keccak256\":\"0x6e6dd2cab346ef7c31230740ec48d2925e4a9ab24c2f2fb268baaf408dcf02ef\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC1271 {\\n function isValidSignature(\\n bytes32 hash,\\n bytes memory signature\\n ) external view returns (bytes4);\\n}\\n\",\"keccak256\":\"0xcdddb7d5641c9d3f2432dec7fd13fddb9ae1480f25c76c21511e2fa16b8bd422\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibAppStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {SafeCast} from \\\"@openzeppelin/contracts/utils/math/SafeCast.sol\\\";\\nimport {IEntryPoint} from \\\"../aa-4337/interfaces/IEntryPoint.sol\\\";\\nimport {IFacetRegistry} from \\\"../infrastructure/interfaces/IFacetRegistry.sol\\\";\\n\\n/*\\n * @title App Storage\\n * @dev App storage for Barz contract to prevent storage collision\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Lock {\\n uint64 release;\\n bytes4 locker;\\n}\\n\\nstruct InitializersStorage {\\n // NOTE: initialized is a variable to make sure the initialization is only done once.\\n uint8 signerInitialized;\\n uint8 accountInitialized;\\n uint8 restrictionsInitialized;\\n}\\n\\nstruct AppStorage {\\n mapping(uint256 => InitializersStorage) initStorage;\\n uint8 signerMigration;\\n bytes4 validateOwnerSignatureSelector;\\n IEntryPoint entryPoint;\\n IFacetRegistry facetRegistry;\\n mapping(uint256 => Lock) locks;\\n}\\n\\nlibrary LibAppStorage {\\n error LibAppStorage__AccountAlreadyUninitialized();\\n error LibAppStorage__AccountMustBeUninitialized();\\n error LibAppStorage__SignerAlreadyUninitialized();\\n error LibAppStorage__SignerMustBeUninitialized();\\n\\n function appStorage() internal pure returns (AppStorage storage ds) {\\n assembly {\\n ds.slot := 0\\n }\\n }\\n\\n function setSignerUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerAlreadyUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 0;\\n }\\n\\n function getValidateOwnerSignatureSelector()\\n internal\\n view\\n returns (bytes4 selector)\\n {\\n selector = appStorage().validateOwnerSignatureSelector;\\n }\\n\\n function setValidateOwnerSignatureSelector(\\n bytes4 _validateOwnerSignatureSelector\\n ) internal {\\n appStorage()\\n .validateOwnerSignatureSelector = _validateOwnerSignatureSelector;\\n }\\n\\n function enforceSignerInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerMustBeUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 1;\\n }\\n\\n function enforceAccountInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].accountInitialized) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n s.initStorage[0].accountInitialized = 1;\\n }\\n\\n function initiateSignerMigration() internal {\\n appStorage().signerMigration = 1;\\n }\\n\\n function enforceSignerMigration() internal view {\\n if (1 != appStorage().signerMigration) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n }\\n\\n function finalizeSignerMigration() internal {\\n appStorage().signerMigration = 0;\\n }\\n\\n function setLock(uint256 _releaseAfter, bytes4 _locker) internal {\\n appStorage().locks[0] = Lock(SafeCast.toUint64(_releaseAfter), _locker);\\n }\\n\\n function enforceRestrictionsInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__SignerMustBeUninitialized();\\n s.initStorage[0].restrictionsInitialized = 1;\\n }\\n\\n function setRestrictionsUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__AccountAlreadyUninitialized();\\n s.initStorage[0].restrictionsInitialized = 0;\\n }\\n}\\n\\ncontract BarzStorage {\\n AppStorage internal s;\\n modifier onlyWhenUnlocked() {\\n require(\\n uint64(block.timestamp) >= s.locks[0].release,\\n \\\"Account Locked\\\"\\n );\\n _;\\n }\\n modifier onlyWhenLocked() {\\n require(\\n uint64(block.timestamp) < s.locks[0].release,\\n \\\"Account Unlocked\\\"\\n );\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x48524007862a6ce0e07f645950613ce6513ce073c37a109c75019683d42bae27\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\\n bytes4(keccak256(\\\"verifyRestrictions(address,address,uint256,bytes)\\\"));\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // Default Fallback Handler of the barz.\\n IDiamondLoupe defaultFallbackHandler;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function enforceIsSelf() internal view {\\n require(msg.sender == address(this), \\\"LibDiamond: Caller not self\\\");\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n\\n unchecked {\\n facetIndex++;\\n }\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n\\n function restrictionsFacet() internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(\\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2cabdc00de859c3a3170ce3bda5d0e5fd3933d47ce904fd1585f9818b02572f8\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibFacetStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Storage\\n * @dev Storage contract to store each facets variables with diamond storage\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Secp256k1VerificationStorage {\\n address signer;\\n}\\n\\nstruct Secp256r1VerificationStorage {\\n uint256[2] q;\\n}\\n\\nstruct GuardianStorage {\\n mapping(bytes32 => uint256) pending;\\n mapping(uint8 => StorageConfig) configs;\\n}\\n\\nstruct Info {\\n bool exists;\\n uint128 index;\\n}\\n\\nstruct StorageConfig {\\n address[] addresses;\\n mapping(address => Info) info;\\n}\\n\\nstruct RecoveryConfig {\\n bytes recoveryPublicKey;\\n uint64 executeAfter;\\n}\\n\\nstruct ApprovalConfig {\\n bool isApproved;\\n uint64 validUntil;\\n}\\n\\nstruct RecoveryApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isNewOwnerApproved;\\n}\\n\\nstruct RecoveryStorage {\\n mapping(uint8 => RecoveryConfig) recoveryConfigs;\\n mapping(uint8 => RecoveryApprovalConfig) recoveryApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct RestrictionsStorage {\\n address[] restrictions;\\n mapping(address => bool) exists;\\n}\\n\\nstruct SignatureMigrationConfig {\\n bytes migrationPublicKey;\\n address migrationVerificationFacet;\\n bytes4[] migrationSelectors;\\n uint64 migrateAfter;\\n}\\n\\nstruct SignatureMigrationApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isMigrationApproved;\\n}\\n\\nstruct SignatureMigrationStorage {\\n mapping(uint8 => SignatureMigrationConfig) migrationConfigs;\\n mapping(uint8 => SignatureMigrationApprovalConfig) migrationApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct DiamondCutApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isDiamondCutApproved;\\n}\\n\\nstruct DiamondCutStorage {\\n mapping(uint8 => DiamondCutApprovalConfig) diamondCutApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct LockStorage {\\n uint128 nonce;\\n}\\n\\nlibrary LibFacetStorage {\\n bytes32 constant K1_STORAGE_POSITION =\\n keccak256(\\n \\\"v0.trustwallet.diamond.storage.Secp256k1VerificationStorage\\\"\\n );\\n bytes32 constant R1_STORAGE_POSITION =\\n keccak256(\\n \\\"v0.trustwallet.diamond.storage.Secp256r1VerificationStorage\\\"\\n );\\n bytes32 constant GUARDIAN_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.GuardianStorage\\\");\\n bytes32 constant RECOVERY_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.RecoveryStorage\\\");\\n bytes32 constant RESTRICTION_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.RestrictionsStorage\\\");\\n bytes32 constant MIGRATION_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.SignatureMigrationStorage\\\");\\n bytes32 constant DIAMONDCUT_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.DiamondCutStorage\\\");\\n bytes32 constant LOCK_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.LockStorage\\\");\\n\\n function k1Storage()\\n internal\\n pure\\n returns (Secp256k1VerificationStorage storage ds)\\n {\\n bytes32 storagePosition = K1_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function r1Storage()\\n internal\\n pure\\n returns (Secp256r1VerificationStorage storage ds)\\n {\\n bytes32 storagePosition = R1_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function guardianStorage()\\n internal\\n pure\\n returns (GuardianStorage storage ds)\\n {\\n bytes32 storagePosition = GUARDIAN_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function recoveryStorage()\\n internal\\n pure\\n returns (RecoveryStorage storage ds)\\n {\\n bytes32 storagePosition = RECOVERY_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function restrictionsStorage()\\n internal\\n pure\\n returns (RestrictionsStorage storage ds)\\n {\\n bytes32 storagePosition = RESTRICTION_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function migrationStorage()\\n internal\\n pure\\n returns (SignatureMigrationStorage storage ds)\\n {\\n bytes32 storagePosition = MIGRATION_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function diamondCutStorage()\\n internal\\n pure\\n returns (DiamondCutStorage storage ds)\\n {\\n bytes32 storagePosition = DIAMONDCUT_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function lockStorage() internal pure returns (LockStorage storage ds) {\\n bytes32 storagePosition = LOCK_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n}\\n\",\"keccak256\":\"0x87c85decfd943deda9540733e464cb1a92eba735a301e89ce6f798016e359761\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\nimport {LibDiamond} from \\\"./LibDiamond.sol\\\";\\n\\n/**\\n * @title LibLoupe\\n * @dev Internal Library to provide utility feature for reading the state of diamond facets\\n * Originally from Diamond's implementation of Mudgen(author of EIP-2535)\\n */\\nlibrary LibLoupe {\\n /// @notice Gets all facets and their selectors.\\n /// @return facets_ Facet\\n function facets()\\n internal\\n view\\n returns (IDiamondLoupe.Facet[] memory facets_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facets_ = new IDiamondLoupe.Facet[](ds.selectorCount);\\n uint16[] memory numFacetSelectors = new uint16[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facets_[facetIndex].facetAddress == facetAddress_) {\\n facets_[facetIndex].functionSelectors[\\n numFacetSelectors[facetIndex]\\n ] = selector;\\n // probably will never have more than 256 functions from one facet contract\\n require(numFacetSelectors[facetIndex] < 255);\\n numFacetSelectors[facetIndex]++;\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facets_[numFacets].facetAddress = facetAddress_;\\n facets_[numFacets].functionSelectors = new bytes4[](\\n ds.selectorCount\\n );\\n facets_[numFacets].functionSelectors[0] = selector;\\n numFacetSelectors[numFacets] = 1;\\n numFacets++;\\n }\\n }\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n uint256 numSelectors = numFacetSelectors[facetIndex];\\n bytes4[] memory selectors = facets_[facetIndex].functionSelectors;\\n // setting the number of selectors\\n assembly {\\n mstore(selectors, numSelectors)\\n }\\n }\\n // setting the number of facets\\n assembly {\\n mstore(facets_, numFacets)\\n }\\n }\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return _facetFunctionSelectors The selectors associated with a facet address.\\n function facetFunctionSelectors(\\n address _facet\\n ) internal view returns (bytes4[] memory _facetFunctionSelectors) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n uint256 numSelectors;\\n _facetFunctionSelectors = new bytes4[](ds.selectorCount);\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facet = address(bytes20(ds.facets[selector]));\\n if (_facet == facet) {\\n _facetFunctionSelectors[numSelectors] = selector;\\n numSelectors++;\\n }\\n }\\n }\\n // Set the number of selectors in the array\\n assembly {\\n mstore(_facetFunctionSelectors, numSelectors)\\n }\\n }\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n internal\\n view\\n returns (address[] memory facetAddresses_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetAddresses_ = new address[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facetAddress_ == facetAddresses_[facetIndex]) {\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facetAddresses_[numFacets] = facetAddress_;\\n numFacets++;\\n }\\n }\\n // Set the number of facet addresses in the array\\n assembly {\\n mstore(facetAddresses_, numFacets)\\n }\\n }\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(LibDiamond.diamondStorage().facets[_functionSelector])\\n );\\n }\\n}\\n\",\"keccak256\":\"0x0b11439c3cc657095e15ec2241fdcf67204b14001357b612fc5db4ff9e760a5a\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x60a060405234801561001057600080fd5b50610019610022565b3060805261008b565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff161561006f57604051637c2cde8b60e01b815260040160405180910390fd5b600080805260209190915260409020805460ff19166001179055565b608051611f746100ad6000396000818161016001526106e10152611f746000f3fe608060405234801561001057600080fd5b50600436106100a35760003560e01c80637104ddb2116100765780638dd501211161005b5780638dd50121146101bc578063cd00e50a146101cf578063cd9b47e4146101d757600080fd5b80637104ddb21461015b5780638da5cb5b146101a757600080fd5b806311cfe388146100a85780631626ba7e146100ce5780633253960f14610112578063392dd6d914610138575b600080fd5b6100bb6100b6366004611823565b6101ea565b6040519081526020015b60405180910390f35b6100e16100dc366004611956565b610252565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020016100c5565b7f8dd50121000000000000000000000000000000000000000000000000000000006100e1565b61014b61014636600461199d565b6102fd565b60405190151581526020016100c5565b6101827f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100c5565b6101af61036f565b6040516100c591906119f6565b6100bb6101ca366004611a47565b6103ba565b6100bb61041f565b6100bb6101e5366004611a8c565b61053a565b600061023982846101ff610140880188611afe565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061083692505050565b610244576001610247565b60005b60ff16949350505050565b60006102aa7f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b1653646040805180820191829052919060029082845b81548152602001906001019080831161028b5750505050508484610836565b6102d4577fffffffff000000000000000000000000000000000000000000000000000000006102f6565b7f1626ba7e000000000000000000000000000000000000000000000000000000005b9392505050565b60008151604114801561036957508160008151811061031e5761031e611b6a565b6020910101517fff00000000000000000000000000000000000000000000000000000000000000167f0400000000000000000000000000000000000000000000000000000000000000145b92915050565b6040516060907f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364906103a5908290602001611b99565b60405160208183030381529060405291505090565b60408051808201918290526000917f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364916104179186918691859060029082845b8154815260200190600101908083116103fa5750505050506101ea565b949350505050565b60006104296109b4565b6104316109f4565b60408051808201909152600080825260208201527f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364906104749082906002611675565b506000610488600154610100900460e01b90565b7fffffffff0000000000000000000000000000000000000000000000000000000016036104e1576040517f127c609a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff169055604051600192507fcccd30db6bc000b8bb8d11162228d2d69e3c361983ca3ae8c1365ce64b0fae9e90600090a15090565b6000610544610a93565b61058383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102fd92505050565b6105b9576040517f6c334d2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006105c88360018187611bcd565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092935061060992506116b8915050565b602082015181526040820151602082015260006106437f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b16536490565b9050610651818360026116d6565b507f8dd50121000000000000000000000000000000000000000000000000000000006000610686600154610100900460e01b90565b7fffffffff0000000000000000000000000000000000000000000000000000000016146106df576040517f5f95a63c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16610770827fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604090205460601c90565b73ffffffffffffffffffffffffffffffffffffffff16146107bd576040517fbb4752b700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff1661010060e084901c02179055600194507f6d54821a69ec281ed7ba1bf2729c700768c47df1d80fad646b0a14cc1d5c39ed8787604051610824929190611bf7565b60405180910390a15050505092915050565b600080600080600080868060200190518101906108539190611c94565b9450945094509450945060008061088a8a60405160200161087691815260200190565b604051602081830303815290604052610b33565b905060008482856040516020016108a393929190611d47565b60405160208183030381529060405290506002816040516108c49190611d8a565b602060405180830381855afa1580156108e1573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906109049190611da6565b9250505060006002858360405160200161091f929190611dbf565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905261095791611d8a565b602060405180830381855afa158015610974573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906109979190611da6565b90506109a58b888884610c6f565b9b9a5050505050505050505050565b6001805460ff16146109f2576040517f38fc28cb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff16600114610a5c576040517fe00d7c7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff1615610af9576040517f7c2cde8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b60608151600003610b5257505060408051602081019091526000815290565b6000604051806060016040528060408152602001611eff6040913990506000600684516008610b819190611e10565b610b8b9190611e56565b9050600060068551610b9d9190611e6a565b1115610bb15780610bad81611e7e565b9150505b60008167ffffffffffffffff811115610bcc57610bcc61177c565b6040519080825280601f01601f191660200182016040528015610bf6576020820181803683370190505b509050600183016020820186875188015b80821015610c62576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f8116850151845350600183019250610c07565b5092979650505050505050565b6000610c9c60017fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611eb6565b85511180610cd75750610cd060017fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611eb6565b6020860151115b15610ce457506000610417565b831580610cef575082155b80610d1a57507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518410155b80610d4557507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518310155b15610d5257506000610417565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff7f5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff8088600060200201517fffffffff00000001000000000000000000000000fffffffffffffffffffffffc0988517fffffffff00000001000000000000000000000000ffffffffffffffffffffffff90819080098a5109080860208601517fffffffff00000001000000000000000000000000ffffffffffffffffffffffff90800914610e4357506000610417565b6000610e4e86610e66565b9050610e5c81868686611062565b9695505050505050565b610e6e611704565b60405180606001604052806000815260200160008152602001600081525081600060108110610e9f57610e9f611b6a565b60200201526040805160608101909152808360006020020151815260200183600160028110610ed057610ed0611b6a565b60200201518152602001600181525081600160108110610ef257610ef2611b6a565b6020020152610f088160015b602002015161116f565b6040820152610f278160015b60200201518260025b60200201516111d1565b6060828101919091526040805191820181527f6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c29682527f4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f560208301526001908201526080820152610fa18160045b6020020151826001610f1d565b60a0820152610fb1816004610f14565b60c0820152610fca8160045b6020020151826003610f1d565b60e0820152610fda816004610efe565b610100820152610feb816008610f94565b610120820152610ffc816008610f14565b61014082015261100d816008610fbd565b610160820152608081015161102490826008610f1d565b61018082015261103581600c610f94565b6101a082015261104681600c610f14565b6101c082015261105781600c610fbd565b6101e0820152919050565b600083158061106f575082155b8061109a57507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518410155b806110c557507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518310155b156110d257506000610417565b60006110fe847fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551611243565b905060007fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551828509905060007fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551838809905060008061115e8a858561125a565b509098149998505050505050505050565b61119360405180606001604052806000815260200160008152602001600081525090565b60008060006111af856000015186602001518760400151611346565b6040805160608101825293845260208401929092529082015295945050505050565b6111f560405180606001604052806000815260200160008152602001600081525090565b6000806000611220866000015187602001518860400151886000015189602001518a60400151611424565b604080516060810182529384526020840192909252908201529695505050505050565b60006102f683611254600285611eb6565b8461155c565b6000808080806080815b81156113285782156112955761127b858585611346565b9196509450925061128d858585611346565b919650945092505b50600c60fc89901c1660fe88901c17801561130b576113038585858d85601081106112c2576112c2611b6a565b6020020151518e86601081106112da576112da611b6a565b6020020151602001518f87601081106112f5576112f5611b6a565b602002015160400151611424565b919650945092505b600298891b989790971b968161132081611ec9565b925050611264565b6113338585856115b0565b909750955050505050505b935093915050565b6000806000846000036113615750600091508190508061141b565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff8085860981828283097fffffffff00000001000000000000000000000000fffffffffffffffffffffffc099050818788098283828b0960040983848384096008099150838385868d8e09600309089250838160020984848509818110156113e65785015b039650868110156113f45783015b8387820384099550508085101561140a57938201935b909303925080808688096002099150505b93509350939050565b60008060008660000361143e575084915083905082611550565b83600003611453575087915086905085611550565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff808889098186870982818d0983838b0984858a85098e0985868e87098c09868b8f08848410156114a357928701925b8484039350878460020988818209905088818609848410156114c457928901925b898585036002099350898485099c50898288099650898a8860020982089150818d10156114f0579b89019b5b818d039c5089818b87600209099450508b86101561150d57948801945b888c870384099a50838b101561152257998801995b838b039a508887890897508882830990508781101561153e5788015b88858983030999505050505050505050505b96509650969350505050565b60008184111561156c5781840693505b60405160208152602080820152602060408201528460608201528360808201528260a082015260208160c08360056136b0fa8080156100a357505051949350505050565b600080826000036115c65750600090508061133e565b60006115f2847fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611243565b905060007fffffffff00000001000000000000000000000000ffffffffffffffffffffffff82830990507fffffffff00000001000000000000000000000000ffffffffffffffffffffffff81880993507fffffffff00000001000000000000000000000000ffffffffffffffffffffffff80838309870992505050935093915050565b82600281019282156116a8579160200282015b828111156116a8578251829060ff16905591602001919060010190611688565b506116b492915061174e565b5090565b60405180604001604052806002906020820280368337509192915050565b82600281019282156116a8579160200282015b828111156116a85782518255916020019190600101906116e9565b6040518061020001604052806010905b61173860405180606001604052806000815260200160008152602001600081525090565b8152602001906001900390816117145790505090565b5b808211156116b4576000815560010161174f565b6000610160828403121561177657600080fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156117ce576117ce61177c565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561181b5761181b61177c565b604052919050565b60008060006080848603121561183857600080fd5b833567ffffffffffffffff81111561184f57600080fd5b61185b86828701611763565b935050602080850135925085605f86011261187557600080fd5b61187d6117ab565b80608087018881111561188f57600080fd5b604088015b818110156118ab5780358452928401928401611894565b50508093505050509250925092565b600067ffffffffffffffff8211156118d4576118d461177c565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261191157600080fd5b813561192461191f826118ba565b6117d4565b81815284602083860101111561193957600080fd5b816020850160208301376000918101602001919091529392505050565b6000806040838503121561196957600080fd5b82359150602083013567ffffffffffffffff81111561198757600080fd5b61199385828601611900565b9150509250929050565b6000602082840312156119af57600080fd5b813567ffffffffffffffff8111156119c657600080fd5b61041784828501611900565b60005b838110156119ed5781810151838201526020016119d5565b50506000910152565b6020815260008251806020840152611a158160408501602087016119d2565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b60008060408385031215611a5a57600080fd5b823567ffffffffffffffff811115611a7157600080fd5b611a7d85828601611763565b95602094909401359450505050565b60008060208385031215611a9f57600080fd5b823567ffffffffffffffff80821115611ab757600080fd5b818501915085601f830112611acb57600080fd5b813581811115611ada57600080fd5b866020828501011115611aec57600080fd5b60209290920196919550909350505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112611b3357600080fd5b83018035915067ffffffffffffffff821115611b4e57600080fd5b602001915036819003821315611b6357600080fd5b9250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008183825b6002811015611bbe578154835260209092019160019182019101611b9f565b50505060408201905092915050565b60008085851115611bdd57600080fd5b83861115611bea57600080fd5b5050820193919092039150565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b6000611c5261191f846118ba565b9050828152838383011115611c6657600080fd5b6102f68360208301846119d2565b600082601f830112611c8557600080fd5b6102f683835160208501611c44565b600080600080600060a08688031215611cac57600080fd5b8551945060208601519350604086015167ffffffffffffffff80821115611cd257600080fd5b818801915088601f830112611ce657600080fd5b611cf589835160208501611c44565b94506060880151915080821115611d0b57600080fd5b611d1789838a01611c74565b93506080880151915080821115611d2d57600080fd5b50611d3a88828901611c74565b9150509295509295909350565b60008451611d598184602089016119d2565b845190830190611d6d8183602089016119d2565b8451910190611d808183602088016119d2565b0195945050505050565b60008251611d9c8184602087016119d2565b9190910192915050565b600060208284031215611db857600080fd5b5051919050565b60008351611dd18184602088016119d2565b9190910191825250602001919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808202811582820484141761036957610369611de1565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082611e6557611e65611e27565b500490565b600082611e7957611e79611e27565b500690565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611eaf57611eaf611de1565b5060010190565b8181038181111561036957610369611de1565b600081611ed857611ed8611de1565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392d5fa2646970667358221220d4142da7b16effb6b95f41adeff2bc8ce0d59d3b70ca8d55e6e83224bbfbec0a64736f6c63430008150033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100a35760003560e01c80637104ddb2116100765780638dd501211161005b5780638dd50121146101bc578063cd00e50a146101cf578063cd9b47e4146101d757600080fd5b80637104ddb21461015b5780638da5cb5b146101a757600080fd5b806311cfe388146100a85780631626ba7e146100ce5780633253960f14610112578063392dd6d914610138575b600080fd5b6100bb6100b6366004611823565b6101ea565b6040519081526020015b60405180910390f35b6100e16100dc366004611956565b610252565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020016100c5565b7f8dd50121000000000000000000000000000000000000000000000000000000006100e1565b61014b61014636600461199d565b6102fd565b60405190151581526020016100c5565b6101827f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100c5565b6101af61036f565b6040516100c591906119f6565b6100bb6101ca366004611a47565b6103ba565b6100bb61041f565b6100bb6101e5366004611a8c565b61053a565b600061023982846101ff610140880188611afe565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061083692505050565b610244576001610247565b60005b60ff16949350505050565b60006102aa7f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b1653646040805180820191829052919060029082845b81548152602001906001019080831161028b5750505050508484610836565b6102d4577fffffffff000000000000000000000000000000000000000000000000000000006102f6565b7f1626ba7e000000000000000000000000000000000000000000000000000000005b9392505050565b60008151604114801561036957508160008151811061031e5761031e611b6a565b6020910101517fff00000000000000000000000000000000000000000000000000000000000000167f0400000000000000000000000000000000000000000000000000000000000000145b92915050565b6040516060907f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364906103a5908290602001611b99565b60405160208183030381529060405291505090565b60408051808201918290526000917f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364916104179186918691859060029082845b8154815260200190600101908083116103fa5750505050506101ea565b949350505050565b60006104296109b4565b6104316109f4565b60408051808201909152600080825260208201527f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364906104749082906002611675565b506000610488600154610100900460e01b90565b7fffffffff0000000000000000000000000000000000000000000000000000000016036104e1576040517f127c609a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff169055604051600192507fcccd30db6bc000b8bb8d11162228d2d69e3c361983ca3ae8c1365ce64b0fae9e90600090a15090565b6000610544610a93565b61058383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102fd92505050565b6105b9576040517f6c334d2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006105c88360018187611bcd565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092935061060992506116b8915050565b602082015181526040820151602082015260006106437f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b16536490565b9050610651818360026116d6565b507f8dd50121000000000000000000000000000000000000000000000000000000006000610686600154610100900460e01b90565b7fffffffff0000000000000000000000000000000000000000000000000000000016146106df576040517f5f95a63c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16610770827fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604090205460601c90565b73ffffffffffffffffffffffffffffffffffffffff16146107bd576040517fbb4752b700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff1661010060e084901c02179055600194507f6d54821a69ec281ed7ba1bf2729c700768c47df1d80fad646b0a14cc1d5c39ed8787604051610824929190611bf7565b60405180910390a15050505092915050565b600080600080600080868060200190518101906108539190611c94565b9450945094509450945060008061088a8a60405160200161087691815260200190565b604051602081830303815290604052610b33565b905060008482856040516020016108a393929190611d47565b60405160208183030381529060405290506002816040516108c49190611d8a565b602060405180830381855afa1580156108e1573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906109049190611da6565b9250505060006002858360405160200161091f929190611dbf565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905261095791611d8a565b602060405180830381855afa158015610974573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906109979190611da6565b90506109a58b888884610c6f565b9b9a5050505050505050505050565b6001805460ff16146109f2576040517f38fc28cb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff16600114610a5c576040517fe00d7c7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff1615610af9576040517f7c2cde8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b60608151600003610b5257505060408051602081019091526000815290565b6000604051806060016040528060408152602001611eff6040913990506000600684516008610b819190611e10565b610b8b9190611e56565b9050600060068551610b9d9190611e6a565b1115610bb15780610bad81611e7e565b9150505b60008167ffffffffffffffff811115610bcc57610bcc61177c565b6040519080825280601f01601f191660200182016040528015610bf6576020820181803683370190505b509050600183016020820186875188015b80821015610c62576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f8116850151845350600183019250610c07565b5092979650505050505050565b6000610c9c60017fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611eb6565b85511180610cd75750610cd060017fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611eb6565b6020860151115b15610ce457506000610417565b831580610cef575082155b80610d1a57507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518410155b80610d4557507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518310155b15610d5257506000610417565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff7f5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff8088600060200201517fffffffff00000001000000000000000000000000fffffffffffffffffffffffc0988517fffffffff00000001000000000000000000000000ffffffffffffffffffffffff90819080098a5109080860208601517fffffffff00000001000000000000000000000000ffffffffffffffffffffffff90800914610e4357506000610417565b6000610e4e86610e66565b9050610e5c81868686611062565b9695505050505050565b610e6e611704565b60405180606001604052806000815260200160008152602001600081525081600060108110610e9f57610e9f611b6a565b60200201526040805160608101909152808360006020020151815260200183600160028110610ed057610ed0611b6a565b60200201518152602001600181525081600160108110610ef257610ef2611b6a565b6020020152610f088160015b602002015161116f565b6040820152610f278160015b60200201518260025b60200201516111d1565b6060828101919091526040805191820181527f6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c29682527f4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f560208301526001908201526080820152610fa18160045b6020020151826001610f1d565b60a0820152610fb1816004610f14565b60c0820152610fca8160045b6020020151826003610f1d565b60e0820152610fda816004610efe565b610100820152610feb816008610f94565b610120820152610ffc816008610f14565b61014082015261100d816008610fbd565b610160820152608081015161102490826008610f1d565b61018082015261103581600c610f94565b6101a082015261104681600c610f14565b6101c082015261105781600c610fbd565b6101e0820152919050565b600083158061106f575082155b8061109a57507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518410155b806110c557507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518310155b156110d257506000610417565b60006110fe847fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551611243565b905060007fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551828509905060007fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551838809905060008061115e8a858561125a565b509098149998505050505050505050565b61119360405180606001604052806000815260200160008152602001600081525090565b60008060006111af856000015186602001518760400151611346565b6040805160608101825293845260208401929092529082015295945050505050565b6111f560405180606001604052806000815260200160008152602001600081525090565b6000806000611220866000015187602001518860400151886000015189602001518a60400151611424565b604080516060810182529384526020840192909252908201529695505050505050565b60006102f683611254600285611eb6565b8461155c565b6000808080806080815b81156113285782156112955761127b858585611346565b9196509450925061128d858585611346565b919650945092505b50600c60fc89901c1660fe88901c17801561130b576113038585858d85601081106112c2576112c2611b6a565b6020020151518e86601081106112da576112da611b6a565b6020020151602001518f87601081106112f5576112f5611b6a565b602002015160400151611424565b919650945092505b600298891b989790971b968161132081611ec9565b925050611264565b6113338585856115b0565b909750955050505050505b935093915050565b6000806000846000036113615750600091508190508061141b565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff8085860981828283097fffffffff00000001000000000000000000000000fffffffffffffffffffffffc099050818788098283828b0960040983848384096008099150838385868d8e09600309089250838160020984848509818110156113e65785015b039650868110156113f45783015b8387820384099550508085101561140a57938201935b909303925080808688096002099150505b93509350939050565b60008060008660000361143e575084915083905082611550565b83600003611453575087915086905085611550565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff808889098186870982818d0983838b0984858a85098e0985868e87098c09868b8f08848410156114a357928701925b8484039350878460020988818209905088818609848410156114c457928901925b898585036002099350898485099c50898288099650898a8860020982089150818d10156114f0579b89019b5b818d039c5089818b87600209099450508b86101561150d57948801945b888c870384099a50838b101561152257998801995b838b039a508887890897508882830990508781101561153e5788015b88858983030999505050505050505050505b96509650969350505050565b60008184111561156c5781840693505b60405160208152602080820152602060408201528460608201528360808201528260a082015260208160c08360056136b0fa8080156100a357505051949350505050565b600080826000036115c65750600090508061133e565b60006115f2847fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611243565b905060007fffffffff00000001000000000000000000000000ffffffffffffffffffffffff82830990507fffffffff00000001000000000000000000000000ffffffffffffffffffffffff81880993507fffffffff00000001000000000000000000000000ffffffffffffffffffffffff80838309870992505050935093915050565b82600281019282156116a8579160200282015b828111156116a8578251829060ff16905591602001919060010190611688565b506116b492915061174e565b5090565b60405180604001604052806002906020820280368337509192915050565b82600281019282156116a8579160200282015b828111156116a85782518255916020019190600101906116e9565b6040518061020001604052806010905b61173860405180606001604052806000815260200160008152602001600081525090565b8152602001906001900390816117145790505090565b5b808211156116b4576000815560010161174f565b6000610160828403121561177657600080fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156117ce576117ce61177c565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561181b5761181b61177c565b604052919050565b60008060006080848603121561183857600080fd5b833567ffffffffffffffff81111561184f57600080fd5b61185b86828701611763565b935050602080850135925085605f86011261187557600080fd5b61187d6117ab565b80608087018881111561188f57600080fd5b604088015b818110156118ab5780358452928401928401611894565b50508093505050509250925092565b600067ffffffffffffffff8211156118d4576118d461177c565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261191157600080fd5b813561192461191f826118ba565b6117d4565b81815284602083860101111561193957600080fd5b816020850160208301376000918101602001919091529392505050565b6000806040838503121561196957600080fd5b82359150602083013567ffffffffffffffff81111561198757600080fd5b61199385828601611900565b9150509250929050565b6000602082840312156119af57600080fd5b813567ffffffffffffffff8111156119c657600080fd5b61041784828501611900565b60005b838110156119ed5781810151838201526020016119d5565b50506000910152565b6020815260008251806020840152611a158160408501602087016119d2565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b60008060408385031215611a5a57600080fd5b823567ffffffffffffffff811115611a7157600080fd5b611a7d85828601611763565b95602094909401359450505050565b60008060208385031215611a9f57600080fd5b823567ffffffffffffffff80821115611ab757600080fd5b818501915085601f830112611acb57600080fd5b813581811115611ada57600080fd5b866020828501011115611aec57600080fd5b60209290920196919550909350505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112611b3357600080fd5b83018035915067ffffffffffffffff821115611b4e57600080fd5b602001915036819003821315611b6357600080fd5b9250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008183825b6002811015611bbe578154835260209092019160019182019101611b9f565b50505060408201905092915050565b60008085851115611bdd57600080fd5b83861115611bea57600080fd5b5050820193919092039150565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b6000611c5261191f846118ba565b9050828152838383011115611c6657600080fd5b6102f68360208301846119d2565b600082601f830112611c8557600080fd5b6102f683835160208501611c44565b600080600080600060a08688031215611cac57600080fd5b8551945060208601519350604086015167ffffffffffffffff80821115611cd257600080fd5b818801915088601f830112611ce657600080fd5b611cf589835160208501611c44565b94506060880151915080821115611d0b57600080fd5b611d1789838a01611c74565b93506080880151915080821115611d2d57600080fd5b50611d3a88828901611c74565b9150509295509295909350565b60008451611d598184602089016119d2565b845190830190611d6d8183602089016119d2565b8451910190611d808183602088016119d2565b0195945050505050565b60008251611d9c8184602087016119d2565b9190910192915050565b600060208284031215611db857600080fd5b5051919050565b60008351611dd18184602088016119d2565b9190910191825250602001919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808202811582820484141761036957610369611de1565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082611e6557611e65611e27565b500490565b600082611e7957611e79611e27565b500690565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611eaf57611eaf611de1565b5060010190565b8181038181111561036957610369611de1565b600081611ed857611ed8611de1565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392d5fa2646970667358221220d4142da7b16effb6b95f41adeff2bc8ce0d59d3b70ca8d55e6e83224bbfbec0a64736f6c63430008150033", + "devdoc": { + "author": "Ruslan Serebriakov (@rsrbk)David Yongjun Kim (@Powerstream3604)", + "details": "Primarily used to verify user ops signed with passkeys", + "kind": "dev", + "methods": { + "initializeSigner(bytes)": { + "details": "This method checks if the signer has already been initialized. If already initialized, it reverts. It checks if the public key is in the light format and initializes signer storage in k1 storage.", + "params": { + "_publicKey": "Bytes of owner public key" + }, + "returns": { + "initSuccess": "Uint value representing the success of init operation" + } + }, + "isValidKeyType(bytes)": { + "details": "For this Secp256k1Verification Facet, the public key should in an uncompressed public key format", + "params": { + "_publicKey": "Bytes of public key for format check" + }, + "returns": { + "isValid": "Boolean variable representing if the format of public key is valid" + } + }, + "isValidSignature(bytes32,bytes)": { + "details": "This method verifies the signature if the owner indeed signed the hash. Returns magic value if true", + "params": { + "_hash": "Hash value the owner signed", + "_signature": "Signature that signed the above hash" + }, + "returns": { + "magicValue": "Bytes4 value representing the success/failure of validation" + } + }, + "owner()": { + "returns": { + "signer": "Bytes of owner address" + } + }, + "uninitializeSigner()": { + "details": "This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.", + "returns": { + "uninitSuccess": "Uint value representing the success of uninit operation" + } + }, + "validateOwnerSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32)": { + "details": "This method validates if the user operation is signed by the owner. It internally calls validateSignature with signer public key.", + "params": { + "userOp": "UserOperation including all information for execution", + "userOpHash": "Hash of UserOperation given from EntryPoint. This hash is used for signature validation" + }, + "returns": { + "validationData": "Uint value representing whether the validation is successful. 0 for success, 1 for failure" + } + }, + "validateOwnerSignatureSelector()": { + "returns": { + "ownerSignatureValidatorSelector": "Bytes4 selector of function signature to validate account owner's UserOperation signature" + } + }, + "validateSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256[2])": { + "details": "This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address", + "params": { + "q": "Public Key of signer who signed the contract, to be validated", + "userOp": "UserOperation including all information for execution", + "userOpHash": "Hash of UserOperation given from EntryPoint. This hash is used for signature validation" + }, + "returns": { + "isValid": "Uint value representing whether the validation is successful. 0 for success, 1 for failure" + } + } + }, + "title": "Secp256r1 verification facet", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "constructor": { + "notice": "This constructor ensures that this contract can only be used as singleton for Proxy contracts" + }, + "initializeSigner(bytes)": { + "notice": "Initializes the signer in R1 Facet Storage. This can only be called when the account is uninitialized or during signature migration." + }, + "isValidKeyType(bytes)": { + "notice": "Validates if the format of public key is valid for this verification facet" + }, + "isValidSignature(bytes32,bytes)": { + "notice": "Validates if the signature is valid. Function to be compatible with EIP-1271" + }, + "owner()": { + "notice": "Returns the owner of the account" + }, + "uninitializeSigner()": { + "notice": "Uninitialize signer in R1 Facet Storage. This can only be called when the account is undergoing signature migration and has already been initialized." + }, + "validateOwnerSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32)": { + "notice": "Validates if the user operation is signed by the owner." + }, + "validateOwnerSignatureSelector()": { + "notice": "Returns the selector of function to validate the signature of UserOperation" + }, + "validateSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256[2])": { + "notice": "Validates if the signature of UserOperation is signed by the given signer" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/mantle/TokenReceiverFacet.json b/deployments/mantle/TokenReceiverFacet.json new file mode 100644 index 0000000..db0fc58 --- /dev/null +++ b/deployments/mantle/TokenReceiverFacet.json @@ -0,0 +1,239 @@ +{ + "address": "0x3143E1C0Af0Cdc153423863923Cf4e3818e34Daa", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onERC1155BatchReceived", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onERC1155Received", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onERC721Received", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onTokenTransfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "tokensReceived", + "outputs": [], + "stateMutability": "pure", + "type": "function" + } + ], + "transactionHash": "0xb5332e3e9fc69597bfeac091f3e37eab684a41958031266e6fdf6e119d965252", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xb33654322bD3803821031624f5922eb14C9b8d18", + "contractAddress": null, + "transactionIndex": 1, + "gasUsed": "2208173042", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x511965e9e1bf243601dc33fde191ee7fad03f15a7fd442a600528770aafeec11", + "transactionHash": "0xb5332e3e9fc69597bfeac091f3e37eab684a41958031266e6fdf6e119d965252", + "logs": [], + "blockNumber": 61655419, + "cumulativeGasUsed": "2208237043", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "ad34345aa73d96f52b3e14df983b6b29", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onERC1155BatchReceived\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onERC1155Received\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onERC721Received\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"tokensReceived\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"Contract that enables receiving ERC721/ERC1155/ERC777/ERC677 Tokens with safe transfer\",\"kind\":\"dev\",\"methods\":{},\"title\":\"TokenReceiver Facet\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\":{\"notice\":\"Handles ERC1155 Token batch callback. return Standardized onERC1155BatchReceived return value.\"},\"onERC1155Received(address,address,uint256,uint256,bytes)\":{\"notice\":\"Handles ERC1155 Token callback. return Standardized onERC1155Received return value.\"},\"onERC721Received(address,address,uint256,bytes)\":{\"notice\":\"Handles ERC721 Token callback. return Standardized onERC721Received return value.\"},\"onTokenTransfer(address,uint256,bytes)\":{\"notice\":\"Handles ERC677 Token callback. return true.\"},\"tokensReceived(address,address,address,uint256,bytes,bytes)\":{\"notice\":\"Handles ERC777 Token callback. Does not return value, empty implementation.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/TokenReceiverFacet.sol\":\"TokenReceiverFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title ERC721 token receiver interface\\n * @dev Interface for any contract that wants to support safeTransfers\\n * from ERC721 asset contracts.\\n */\\ninterface IERC721Receiver {\\n /**\\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\\n * by `operator` from `from`, this function is called.\\n *\\n * It must return its Solidity selector to confirm the token transfer.\\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\\n *\\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\\n */\\n function onERC721Received(\\n address operator,\\n address from,\\n uint256 tokenId,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\\n *\\n * Accounts can be notified of {IERC777} tokens being sent to them by having a\\n * contract implement this interface (contract holders can be their own\\n * implementer) and registering it on the\\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\\n *\\n * See {IERC1820Registry} and {ERC1820Implementer}.\\n */\\ninterface IERC777Recipient {\\n /**\\n * @dev Called by an {IERC777} token contract whenever tokens are being\\n * moved or created into a registered account (`to`). The type of operation\\n * is conveyed by `from` being the zero address or not.\\n *\\n * This call occurs _after_ the token contract's state is updated, so\\n * {IERC777-balanceOf}, etc., can be used to query the post-operation state.\\n *\\n * This function may revert to prevent the operation from being executed.\\n */\\n function tokensReceived(\\n address operator,\\n address from,\\n address to,\\n uint256 amount,\\n bytes calldata userData,\\n bytes calldata operatorData\\n ) external;\\n}\\n\",\"keccak256\":\"0x1a5d61db2733202ba361e6d6741cd2e662380e22b80e987eacfc91973f2267dc\",\"license\":\"MIT\"},\"contracts/facets/TokenReceiverFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IERC721Receiver} from \\\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\\\";\\nimport {IERC777Recipient} from \\\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\\\";\\nimport {IERC1155Receiver} from \\\"../interfaces/ERC/IERC1155Receiver.sol\\\";\\nimport {IERC677Receiver} from \\\"../interfaces/ERC/IERC677Receiver.sol\\\";\\n\\n/**\\n * @title TokenReceiver Facet\\n * @dev Contract that enables receiving ERC721/ERC1155/ERC777/ERC677 Tokens with safe transfer\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract TokenReceiverFacet is\\n IERC721Receiver,\\n IERC1155Receiver,\\n IERC777Recipient,\\n IERC677Receiver\\n{\\n /**\\n * @notice Handles ERC721 Token callback.\\n * return Standardized onERC721Received return value.\\n */\\n function onERC721Received(\\n address,\\n address,\\n uint256,\\n bytes calldata\\n ) external pure override returns (bytes4) {\\n return IERC721Receiver.onERC721Received.selector;\\n }\\n\\n /**\\n * @notice Handles ERC1155 Token callback.\\n * return Standardized onERC1155Received return value.\\n */\\n function onERC1155Received(\\n address,\\n address,\\n uint256,\\n uint256,\\n bytes calldata\\n ) external pure override returns (bytes4) {\\n return IERC1155Receiver.onERC1155Received.selector;\\n }\\n\\n /**\\n * @notice Handles ERC1155 Token batch callback.\\n * return Standardized onERC1155BatchReceived return value.\\n */\\n function onERC1155BatchReceived(\\n address,\\n address,\\n uint256[] calldata,\\n uint256[] calldata,\\n bytes calldata\\n ) external pure override returns (bytes4) {\\n return IERC1155Receiver.onERC1155BatchReceived.selector;\\n }\\n\\n /**\\n * @notice Handles ERC777 Token callback.\\n * Does not return value, empty implementation.\\n */\\n function tokensReceived(\\n address,\\n address,\\n address,\\n uint256,\\n bytes calldata,\\n bytes calldata\\n ) external pure override {}\\n\\n /**\\n * @notice Handles ERC677 Token callback.\\n * return true.\\n */\\n function onTokenTransfer(\\n address,\\n uint256,\\n bytes calldata\\n ) external pure override returns (bool) {\\n return true;\\n }\\n}\\n\",\"keccak256\":\"0xdfe483d05ef4056bb464c34ade19ab527687aff3ed0b6303b447a68b5ff7abb4\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC1155Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\n\\npragma solidity 0.8.21;\\n\\n/**\\n * @dev _Available since v3.1._\\n */\\ninterface IERC1155Receiver {\\n /**\\n * @dev Handles the receipt of a single ERC1155 token type. This function is\\n * called at the end of a `safeTransferFrom` after the balance has been updated.\\n *\\n * NOTE: To accept the transfer, this must return\\n * `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))`\\n * (i.e. 0xf23a6e61, or its own function selector).\\n *\\n * @param operator The address which initiated the transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param id The ID of the token being transferred\\n * @param value The amount of tokens being transferred\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155Received(\\n address operator,\\n address from,\\n uint256 id,\\n uint256 value,\\n bytes calldata data\\n ) external returns (bytes4);\\n\\n /**\\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\\n * is called at the end of a `safeBatchTransferFrom` after the balances have\\n * been updated.\\n *\\n * NOTE: To accept the transfer(s), this must return\\n * `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))`\\n * (i.e. 0xbc197c81, or its own function selector).\\n *\\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155BatchReceived(\\n address operator,\\n address from,\\n uint256[] calldata ids,\\n uint256[] calldata values,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0x3729c6757bae3aba03ac1c5064d67ad13b94e2a9428bf44b9be510373406da0c\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC677Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC677Receiver {\\n function onTokenTransfer(\\n address sender,\\n uint value,\\n bytes calldata data\\n ) external pure returns (bool);\\n}\\n\",\"keccak256\":\"0x4c1631cf45ea6daac0ec158c3edb9453099130b6b64f697004b83f95aa1f7350\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50610502806100206000396000f3fe608060405234801561001057600080fd5b50600436106100665760003560e01c8063a4c0ed3611610050578063a4c0ed36146100f3578063bc197c811461011b578063f23a6e611461015657600080fd5b806223de291461006b578063150b7a0214610085575b600080fd5b610083610079366004610201565b5050505050505050565b005b6100bd6100933660046102ac565b7f150b7a020000000000000000000000000000000000000000000000000000000095945050505050565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020015b60405180910390f35b61010b61010136600461031b565b6001949350505050565b60405190151581526020016100ea565b6100bd6101293660046103ba565b7fbc197c810000000000000000000000000000000000000000000000000000000098975050505050505050565b6100bd610164366004610454565b7ff23a6e61000000000000000000000000000000000000000000000000000000009695505050505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146101b357600080fd5b919050565b60008083601f8401126101ca57600080fd5b50813567ffffffffffffffff8111156101e257600080fd5b6020830191508360208285010111156101fa57600080fd5b9250929050565b60008060008060008060008060c0898b03121561021d57600080fd5b6102268961018f565b975061023460208a0161018f565b965061024260408a0161018f565b955060608901359450608089013567ffffffffffffffff8082111561026657600080fd5b6102728c838d016101b8565b909650945060a08b013591508082111561028b57600080fd5b506102988b828c016101b8565b999c989b5096995094979396929594505050565b6000806000806000608086880312156102c457600080fd5b6102cd8661018f565b94506102db6020870161018f565b935060408601359250606086013567ffffffffffffffff8111156102fe57600080fd5b61030a888289016101b8565b969995985093965092949392505050565b6000806000806060858703121561033157600080fd5b61033a8561018f565b935060208501359250604085013567ffffffffffffffff81111561035d57600080fd5b610369878288016101b8565b95989497509550505050565b60008083601f84011261038757600080fd5b50813567ffffffffffffffff81111561039f57600080fd5b6020830191508360208260051b85010111156101fa57600080fd5b60008060008060008060008060a0898b0312156103d657600080fd5b6103df8961018f565b97506103ed60208a0161018f565b9650604089013567ffffffffffffffff8082111561040a57600080fd5b6104168c838d01610375565b909850965060608b013591508082111561042f57600080fd5b61043b8c838d01610375565b909650945060808b013591508082111561028b57600080fd5b60008060008060008060a0878903121561046d57600080fd5b6104768761018f565b95506104846020880161018f565b94506040870135935060608701359250608087013567ffffffffffffffff8111156104ae57600080fd5b6104ba89828a016101b8565b979a969950949750929593949250505056fea2646970667358221220ae9a97061ae9e1485161ca9c8d3228a23e47b18755fa935f51b40e927816ca2964736f6c63430008150033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100665760003560e01c8063a4c0ed3611610050578063a4c0ed36146100f3578063bc197c811461011b578063f23a6e611461015657600080fd5b806223de291461006b578063150b7a0214610085575b600080fd5b610083610079366004610201565b5050505050505050565b005b6100bd6100933660046102ac565b7f150b7a020000000000000000000000000000000000000000000000000000000095945050505050565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020015b60405180910390f35b61010b61010136600461031b565b6001949350505050565b60405190151581526020016100ea565b6100bd6101293660046103ba565b7fbc197c810000000000000000000000000000000000000000000000000000000098975050505050505050565b6100bd610164366004610454565b7ff23a6e61000000000000000000000000000000000000000000000000000000009695505050505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146101b357600080fd5b919050565b60008083601f8401126101ca57600080fd5b50813567ffffffffffffffff8111156101e257600080fd5b6020830191508360208285010111156101fa57600080fd5b9250929050565b60008060008060008060008060c0898b03121561021d57600080fd5b6102268961018f565b975061023460208a0161018f565b965061024260408a0161018f565b955060608901359450608089013567ffffffffffffffff8082111561026657600080fd5b6102728c838d016101b8565b909650945060a08b013591508082111561028b57600080fd5b506102988b828c016101b8565b999c989b5096995094979396929594505050565b6000806000806000608086880312156102c457600080fd5b6102cd8661018f565b94506102db6020870161018f565b935060408601359250606086013567ffffffffffffffff8111156102fe57600080fd5b61030a888289016101b8565b969995985093965092949392505050565b6000806000806060858703121561033157600080fd5b61033a8561018f565b935060208501359250604085013567ffffffffffffffff81111561035d57600080fd5b610369878288016101b8565b95989497509550505050565b60008083601f84011261038757600080fd5b50813567ffffffffffffffff81111561039f57600080fd5b6020830191508360208260051b85010111156101fa57600080fd5b60008060008060008060008060a0898b0312156103d657600080fd5b6103df8961018f565b97506103ed60208a0161018f565b9650604089013567ffffffffffffffff8082111561040a57600080fd5b6104168c838d01610375565b909850965060608b013591508082111561042f57600080fd5b61043b8c838d01610375565b909650945060808b013591508082111561028b57600080fd5b60008060008060008060a0878903121561046d57600080fd5b6104768761018f565b95506104846020880161018f565b94506040870135935060608701359250608087013567ffffffffffffffff8111156104ae57600080fd5b6104ba89828a016101b8565b979a969950949750929593949250505056fea2646970667358221220ae9a97061ae9e1485161ca9c8d3228a23e47b18755fa935f51b40e927816ca2964736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "Contract that enables receiving ERC721/ERC1155/ERC777/ERC677 Tokens with safe transfer", + "kind": "dev", + "methods": {}, + "title": "TokenReceiver Facet", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)": { + "notice": "Handles ERC1155 Token batch callback. return Standardized onERC1155BatchReceived return value." + }, + "onERC1155Received(address,address,uint256,uint256,bytes)": { + "notice": "Handles ERC1155 Token callback. return Standardized onERC1155Received return value." + }, + "onERC721Received(address,address,uint256,bytes)": { + "notice": "Handles ERC721 Token callback. return Standardized onERC721Received return value." + }, + "onTokenTransfer(address,uint256,bytes)": { + "notice": "Handles ERC677 Token callback. return true." + }, + "tokensReceived(address,address,address,uint256,bytes,bytes)": { + "notice": "Handles ERC777 Token callback. Does not return value, empty implementation." + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/mantle/solcInputs/ad34345aa73d96f52b3e14df983b6b29.json b/deployments/mantle/solcInputs/ad34345aa73d96f52b3e14df983b6b29.json new file mode 100644 index 0000000..c2bd4dc --- /dev/null +++ b/deployments/mantle/solcInputs/ad34345aa73d96f52b3e14df983b6b29.json @@ -0,0 +1,360 @@ +{ + "language": "Solidity", + "sources": { + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby disabling any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable2Step.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./Ownable.sol\";\n\n/**\n * @dev Contract module which provides access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership} and {acceptOwnership}.\n *\n * This module is used through inheritance. It will make available all functions\n * from parent (Ownable).\n */\nabstract contract Ownable2Step is Ownable {\n address private _pendingOwner;\n\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Returns the address of the pending owner.\n */\n function pendingOwner() public view virtual returns (address) {\n return _pendingOwner;\n }\n\n /**\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual override onlyOwner {\n _pendingOwner = newOwner;\n emit OwnershipTransferStarted(owner(), newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual override {\n delete _pendingOwner;\n super._transferOwnership(newOwner);\n }\n\n /**\n * @dev The new owner accepts the ownership transfer.\n */\n function acceptOwnership() public virtual {\n address sender = _msgSender();\n require(pendingOwner() == sender, \"Ownable2Step: caller is not the new owner\");\n _transferOwnership(sender);\n }\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC1271.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC1271 standard signature validation method for\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\n *\n * _Available since v4.1._\n */\ninterface IERC1271 {\n /**\n * @dev Should return whether the signature provided is valid for the provided data\n * @param hash Hash of the data to be signed\n * @param signature Signature byte array associated with _data\n */\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\n}\n" + }, + "@openzeppelin/contracts/security/ReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor() {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n _nonReentrantBefore();\n _;\n _nonReentrantAfter();\n }\n\n function _nonReentrantBefore() private {\n // On the first call to nonReentrant, _status will be _NOT_ENTERED\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n }\n\n function _nonReentrantAfter() private {\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Returns true if the reentrancy guard is currently set to \"entered\", which indicates there is a\n * `nonReentrant` function in the call stack.\n */\n function _reentrancyGuardEntered() internal view returns (bool) {\n return _status == _ENTERED;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/ERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/ERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC1155.sol\";\nimport \"./IERC1155Receiver.sol\";\nimport \"./extensions/IERC1155MetadataURI.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of the basic standard multi-token.\n * See https://eips.ethereum.org/EIPS/eip-1155\n * Originally based on code by Enjin: https://github.com/enjin/erc-1155\n *\n * _Available since v3.1._\n */\ncontract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {\n using Address for address;\n\n // Mapping from token ID to account balances\n mapping(uint256 => mapping(address => uint256)) private _balances;\n\n // Mapping from account to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json\n string private _uri;\n\n /**\n * @dev See {_setURI}.\n */\n constructor(string memory uri_) {\n _setURI(uri_);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return\n interfaceId == type(IERC1155).interfaceId ||\n interfaceId == type(IERC1155MetadataURI).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC1155MetadataURI-uri}.\n *\n * This implementation returns the same URI for *all* token types. It relies\n * on the token type ID substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * Clients calling this function must replace the `\\{id\\}` substring with the\n * actual token type ID.\n */\n function uri(uint256) public view virtual override returns (string memory) {\n return _uri;\n }\n\n /**\n * @dev See {IERC1155-balanceOf}.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {\n require(account != address(0), \"ERC1155: address zero is not a valid owner\");\n return _balances[id][account];\n }\n\n /**\n * @dev See {IERC1155-balanceOfBatch}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] memory accounts,\n uint256[] memory ids\n ) public view virtual override returns (uint256[] memory) {\n require(accounts.length == ids.length, \"ERC1155: accounts and ids length mismatch\");\n\n uint256[] memory batchBalances = new uint256[](accounts.length);\n\n for (uint256 i = 0; i < accounts.length; ++i) {\n batchBalances[i] = balanceOf(accounts[i], ids[i]);\n }\n\n return batchBalances;\n }\n\n /**\n * @dev See {IERC1155-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC1155-isApprovedForAll}.\n */\n function isApprovedForAll(address account, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[account][operator];\n }\n\n /**\n * @dev See {IERC1155-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n _safeTransferFrom(from, to, id, amount, data);\n }\n\n /**\n * @dev See {IERC1155-safeBatchTransferFrom}.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n _safeBatchTransferFrom(from, to, ids, amounts, data);\n }\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n\n emit TransferSingle(operator, from, to, id, amount);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n for (uint256 i = 0; i < ids.length; ++i) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n }\n\n emit TransferBatch(operator, from, to, ids, amounts);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\n\n _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);\n }\n\n /**\n * @dev Sets a new URI for all token types, by relying on the token type ID\n * substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * By this mechanism, any occurrence of the `\\{id\\}` substring in either the\n * URI or any of the amounts in the JSON file at said URI will be replaced by\n * clients with the token type ID.\n *\n * For example, the `https://token-cdn-domain/\\{id\\}.json` URI would be\n * interpreted by clients as\n * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`\n * for token type ID 0x4cce0.\n *\n * See {uri}.\n *\n * Because these URIs cannot be meaningfully represented by the {URI} event,\n * this function emits no events.\n */\n function _setURI(string memory newuri) internal virtual {\n _uri = newuri;\n }\n\n /**\n * @dev Creates `amount` tokens of token type `id`, and assigns them to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _mint(address to, uint256 id, uint256 amount, bytes memory data) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _balances[id][to] += amount;\n emit TransferSingle(operator, address(0), to, id, amount);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n for (uint256 i = 0; i < ids.length; i++) {\n _balances[ids[i]][to] += amounts[i];\n }\n\n emit TransferBatch(operator, address(0), to, ids, amounts);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);\n }\n\n /**\n * @dev Destroys `amount` tokens of token type `id` from `from`\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `from` must have at least `amount` tokens of token type `id`.\n */\n function _burn(address from, uint256 id, uint256 amount) internal virtual {\n require(from != address(0), \"ERC1155: burn from the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n\n emit TransferSingle(operator, from, address(0), id, amount);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n */\n function _burnBatch(address from, uint256[] memory ids, uint256[] memory amounts) internal virtual {\n require(from != address(0), \"ERC1155: burn from the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n\n for (uint256 i = 0; i < ids.length; i++) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n }\n\n emit TransferBatch(operator, from, address(0), ids, amounts);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {\n require(owner != operator, \"ERC1155: setting approval status for self\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning, as well as batched variants.\n *\n * The same hook is called on both single and batched variants. For single\n * transfers, the length of the `ids` and `amounts` arrays will be 1.\n *\n * Calling conditions (for each `id` and `amount` pair):\n *\n * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * of token type `id` will be transferred to `to`.\n * - When `from` is zero, `amount` tokens of token type `id` will be minted\n * for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n * will be burned.\n * - `from` and `to` are never both zero.\n * - `ids` and `amounts` have the same, non-zero length.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any token transfer. This includes minting\n * and burning, as well as batched variants.\n *\n * The same hook is called on both single and batched variants. For single\n * transfers, the length of the `id` and `amount` arrays will be 1.\n *\n * Calling conditions (for each `id` and `amount` pair):\n *\n * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * of token type `id` will be transferred to `to`.\n * - When `from` is zero, `amount` tokens of token type `id` will be minted\n * for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n * will be burned.\n * - `from` and `to` are never both zero.\n * - `ids` and `amounts` have the same, non-zero length.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {}\n\n function _doSafeTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155Receiver.onERC1155Received.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non-ERC1155Receiver implementer\");\n }\n }\n }\n\n function _doSafeBatchTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (\n bytes4 response\n ) {\n if (response != IERC1155Receiver.onERC1155BatchReceived.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non-ERC1155Receiver implementer\");\n }\n }\n }\n\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {\n uint256[] memory array = new uint256[](1);\n array[0] = element;\n\n return array;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC1155.sol\";\n\n/**\n * @dev Interface of the optional ERC1155MetadataExtension interface, as defined\n * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155MetadataURI is IERC1155 {\n /**\n * @dev Returns the URI for token type `id`.\n *\n * If the `\\{id\\}` substring is present in the URI, it must be replaced by\n * clients with the actual token type ID.\n */\n function uri(uint256 id) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155 is IERC165 {\n /**\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n */\n event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);\n\n /**\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n * transfers.\n */\n event TransferBatch(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\n\n /**\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n * `approved`.\n */\n event ApprovalForAll(address indexed account, address indexed operator, bool approved);\n\n /**\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n *\n * If an {URI} event was emitted for `id`, the standard\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n * returned by {IERC1155MetadataURI-uri}.\n */\n event URI(string value, uint256 indexed id);\n\n /**\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) external view returns (uint256);\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] calldata accounts,\n uint256[] calldata ids\n ) external view returns (uint256[] memory);\n\n /**\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n *\n * Emits an {ApprovalForAll} event.\n *\n * Requirements:\n *\n * - `operator` cannot be the caller.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n *\n * See {setApprovalForAll}.\n */\n function isApprovedForAll(address account, address operator) external view returns (bool);\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155Receiver is IERC165 {\n /**\n * @dev Handles the receipt of a single ERC1155 token type. This function is\n * called at the end of a `safeTransferFrom` after the balance has been updated.\n *\n * NOTE: To accept the transfer, this must return\n * `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n * (i.e. 0xf23a6e61, or its own function selector).\n *\n * @param operator The address which initiated the transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param id The ID of the token being transferred\n * @param value The amount of tokens being transferred\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n ) external returns (bytes4);\n\n /**\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\n * is called at the end of a `safeBatchTransferFrom` after the balances have\n * been updated.\n *\n * NOTE: To accept the transfer(s), this must return\n * `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n * (i.e. 0xbc197c81, or its own function selector).\n *\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the default value returned by this function, unless\n * it's overridden.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(address from, address to, uint256 amount) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\n // decrementing then incrementing.\n _balances[to] += amount;\n }\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n unchecked {\n // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\n _balances[account] += amount;\n }\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n // Overflow not possible: amount <= accountBalance <= totalSupply.\n _totalSupply -= amount;\n }\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\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" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` 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 amount) 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 `amount` as the allowance of `spender` over the 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 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` 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 amount) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/ERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721.sol\";\nimport \"./IERC721Receiver.sol\";\nimport \"./extensions/IERC721Metadata.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/Strings.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\n using Address for address;\n using Strings for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\n\n // Mapping from token ID to approved address\n mapping(uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return\n interfaceId == type(IERC721).interfaceId ||\n interfaceId == type(IERC721Metadata).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _ownerOf(tokenId);\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token owner or approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n _requireMinted(tokenId);\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n _safeTransfer(from, to, tokenId, data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(address from, address to, uint256 tokenId, bytes memory data) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist\n */\n function _ownerOf(uint256 tokenId) internal view virtual returns (address) {\n return _owners[tokenId];\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _ownerOf(tokenId) != address(0);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n address owner = ERC721.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(address to, uint256 tokenId, bytes memory data) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId, 1);\n\n // Check that tokenId was not minted by `_beforeTokenTransfer` hook\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n unchecked {\n // Will not overflow unless all 2**256 token ids are minted to the same owner.\n // Given that tokens are minted one by one, it is impossible in practice that\n // this ever happens. Might change if we allow batch minting.\n // The ERC fails to describe this case.\n _balances[to] += 1;\n }\n\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(address(0), to, tokenId, 1);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n * This is an internal function that does not check if the sender is authorized to operate on the token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId, 1);\n\n // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook\n owner = ERC721.ownerOf(tokenId);\n\n // Clear approvals\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // Cannot overflow, as that would require more tokens to be burned/transferred\n // out than the owner initially received through minting and transferring in.\n _balances[owner] -= 1;\n }\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(owner, address(0), tokenId, 1);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(address from, address to, uint256 tokenId) internal virtual {\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId, 1);\n\n // Check that tokenId was not transferred by `_beforeTokenTransfer` hook\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n\n // Clear approvals from the previous owner\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // `_balances[from]` cannot overflow for the same reason as described in `_burn`:\n // `from`'s balance is the number of token held, which is at least one before the current\n // transfer.\n // `_balances[to]` could overflow in the conditions described in `_mint`. That would require\n // all 2**256 token ids to be minted, which in practice is impossible.\n _balances[from] -= 1;\n _balances[to] += 1;\n }\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId, 1);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721Receiver.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`.\n * - When `from` is zero, the tokens will be minted for `to`.\n * - When `to` is zero, ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}\n\n /**\n * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`.\n * - When `from` is zero, the tokens were minted for `to`.\n * - When `to` is zero, ``from``'s tokens were burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}\n\n /**\n * @dev Unsafe write access to the balances, used by extensions that \"mint\" tokens using an {ownerOf} override.\n *\n * WARNING: Anyone calling this MUST ensure that the balances remain consistent with the ownership. The invariant\n * being that for any address `a` the value returned by `balanceOf(a)` must be equal to the number of tokens such\n * that `ownerOf(tokenId)` is `a`.\n */\n // solhint-disable-next-line func-name-mixedcase\n function __unsafe_increaseBalance(address account, uint256 amount) internal {\n _balances[account] += amount;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721Receiver {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/ERC777.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC777/ERC777.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC777.sol\";\nimport \"./IERC777Recipient.sol\";\nimport \"./IERC777Sender.sol\";\nimport \"../ERC20/IERC20.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/introspection/IERC1820Registry.sol\";\n\n/**\n * @dev Implementation of the {IERC777} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n *\n * Support for ERC20 is included in this contract, as specified by the EIP: both\n * the ERC777 and ERC20 interfaces can be safely used when interacting with it.\n * Both {IERC777-Sent} and {IERC20-Transfer} events are emitted on token\n * movements.\n *\n * Additionally, the {IERC777-granularity} value is hard-coded to `1`, meaning that there\n * are no special restrictions in the amount of tokens that created, moved, or\n * destroyed. This makes integration with ERC20 applications seamless.\n *\n * CAUTION: This file is deprecated as of v4.9 and will be removed in the next major release.\n */\ncontract ERC777 is Context, IERC777, IERC20 {\n using Address for address;\n\n IERC1820Registry internal constant _ERC1820_REGISTRY = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n mapping(address => uint256) private _balances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n bytes32 private constant _TOKENS_SENDER_INTERFACE_HASH = keccak256(\"ERC777TokensSender\");\n bytes32 private constant _TOKENS_RECIPIENT_INTERFACE_HASH = keccak256(\"ERC777TokensRecipient\");\n\n // This isn't ever read from - it's only used to respond to the defaultOperators query.\n address[] private _defaultOperatorsArray;\n\n // Immutable, but accounts may revoke them (tracked in __revokedDefaultOperators).\n mapping(address => bool) private _defaultOperators;\n\n // For each account, a mapping of its operators and revoked default operators.\n mapping(address => mapping(address => bool)) private _operators;\n mapping(address => mapping(address => bool)) private _revokedDefaultOperators;\n\n // ERC20-allowances\n mapping(address => mapping(address => uint256)) private _allowances;\n\n /**\n * @dev `defaultOperators` may be an empty array.\n */\n constructor(string memory name_, string memory symbol_, address[] memory defaultOperators_) {\n _name = name_;\n _symbol = symbol_;\n\n _defaultOperatorsArray = defaultOperators_;\n for (uint256 i = 0; i < defaultOperators_.length; i++) {\n _defaultOperators[defaultOperators_[i]] = true;\n }\n\n // register interfaces\n _ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256(\"ERC777Token\"), address(this));\n _ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256(\"ERC20Token\"), address(this));\n }\n\n /**\n * @dev See {IERC777-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC777-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {ERC20-decimals}.\n *\n * Always returns 18, as per the\n * [ERC777 EIP](https://eips.ethereum.org/EIPS/eip-777#backward-compatibility).\n */\n function decimals() public pure virtual returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC777-granularity}.\n *\n * This implementation always returns `1`.\n */\n function granularity() public view virtual override returns (uint256) {\n return 1;\n }\n\n /**\n * @dev See {IERC777-totalSupply}.\n */\n function totalSupply() public view virtual override(IERC20, IERC777) returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev Returns the amount of tokens owned by an account (`tokenHolder`).\n */\n function balanceOf(address tokenHolder) public view virtual override(IERC20, IERC777) returns (uint256) {\n return _balances[tokenHolder];\n }\n\n /**\n * @dev See {IERC777-send}.\n *\n * Also emits a {IERC20-Transfer} event for ERC20 compatibility.\n */\n function send(address recipient, uint256 amount, bytes memory data) public virtual override {\n _send(_msgSender(), recipient, amount, data, \"\", true);\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Unlike `send`, `recipient` is _not_ required to implement the {IERC777Recipient}\n * interface if it is a contract.\n *\n * Also emits a {Sent} event.\n */\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n _send(_msgSender(), recipient, amount, \"\", \"\", false);\n return true;\n }\n\n /**\n * @dev See {IERC777-burn}.\n *\n * Also emits a {IERC20-Transfer} event for ERC20 compatibility.\n */\n function burn(uint256 amount, bytes memory data) public virtual override {\n _burn(_msgSender(), amount, data, \"\");\n }\n\n /**\n * @dev See {IERC777-isOperatorFor}.\n */\n function isOperatorFor(address operator, address tokenHolder) public view virtual override returns (bool) {\n return\n operator == tokenHolder ||\n (_defaultOperators[operator] && !_revokedDefaultOperators[tokenHolder][operator]) ||\n _operators[tokenHolder][operator];\n }\n\n /**\n * @dev See {IERC777-authorizeOperator}.\n */\n function authorizeOperator(address operator) public virtual override {\n require(_msgSender() != operator, \"ERC777: authorizing self as operator\");\n\n if (_defaultOperators[operator]) {\n delete _revokedDefaultOperators[_msgSender()][operator];\n } else {\n _operators[_msgSender()][operator] = true;\n }\n\n emit AuthorizedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-revokeOperator}.\n */\n function revokeOperator(address operator) public virtual override {\n require(operator != _msgSender(), \"ERC777: revoking self as operator\");\n\n if (_defaultOperators[operator]) {\n _revokedDefaultOperators[_msgSender()][operator] = true;\n } else {\n delete _operators[_msgSender()][operator];\n }\n\n emit RevokedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-defaultOperators}.\n */\n function defaultOperators() public view virtual override returns (address[] memory) {\n return _defaultOperatorsArray;\n }\n\n /**\n * @dev See {IERC777-operatorSend}.\n *\n * Emits {Sent} and {IERC20-Transfer} events.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes memory data,\n bytes memory operatorData\n ) public virtual override {\n require(isOperatorFor(_msgSender(), sender), \"ERC777: caller is not an operator for holder\");\n _send(sender, recipient, amount, data, operatorData, true);\n }\n\n /**\n * @dev See {IERC777-operatorBurn}.\n *\n * Emits {Burned} and {IERC20-Transfer} events.\n */\n function operatorBurn(\n address account,\n uint256 amount,\n bytes memory data,\n bytes memory operatorData\n ) public virtual override {\n require(isOperatorFor(_msgSender(), account), \"ERC777: caller is not an operator for holder\");\n _burn(account, amount, data, operatorData);\n }\n\n /**\n * @dev See {IERC20-allowance}.\n *\n * Note that operator and allowance concepts are orthogonal: operators may\n * not have allowance, and accounts with allowance may not be operators\n * themselves.\n */\n function allowance(address holder, address spender) public view virtual override returns (uint256) {\n return _allowances[holder][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Note that accounts cannot have allowance issued by their operators.\n */\n function approve(address spender, uint256 value) public virtual override returns (bool) {\n address holder = _msgSender();\n _approve(holder, spender, value);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Note that operator and allowance concepts are orthogonal: operators cannot\n * call `transferFrom` (unless they have allowance), and accounts with\n * allowance cannot call `operatorSend` (unless they are operators).\n *\n * Emits {Sent}, {IERC20-Transfer} and {IERC20-Approval} events.\n */\n function transferFrom(address holder, address recipient, uint256 amount) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(holder, spender, amount);\n _send(holder, recipient, amount, \"\", \"\", false);\n return true;\n }\n\n /**\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with the caller address as the `operator` and with\n * `userData` and `operatorData`.\n *\n * See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits {Minted} and {IERC20-Transfer} events.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - if `account` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function _mint(address account, uint256 amount, bytes memory userData, bytes memory operatorData) internal virtual {\n _mint(account, amount, userData, operatorData, true);\n }\n\n /**\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * If `requireReceptionAck` is set to true, and if a send hook is\n * registered for `account`, the corresponding function will be called with\n * `operator`, `data` and `operatorData`.\n *\n * See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits {Minted} and {IERC20-Transfer} events.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - if `account` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function _mint(\n address account,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) internal virtual {\n require(account != address(0), \"ERC777: mint to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), account, amount);\n\n // Update state variables\n _totalSupply += amount;\n _balances[account] += amount;\n\n _callTokensReceived(operator, address(0), account, amount, userData, operatorData, requireReceptionAck);\n\n emit Minted(operator, account, amount, userData, operatorData);\n emit Transfer(address(0), account, amount);\n }\n\n /**\n * @dev Send tokens\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _send(\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) internal virtual {\n require(from != address(0), \"ERC777: transfer from the zero address\");\n require(to != address(0), \"ERC777: transfer to the zero address\");\n\n address operator = _msgSender();\n\n _callTokensToSend(operator, from, to, amount, userData, operatorData);\n\n _move(operator, from, to, amount, userData, operatorData);\n\n _callTokensReceived(operator, from, to, amount, userData, operatorData, requireReceptionAck);\n }\n\n /**\n * @dev Burn tokens\n * @param from address token holder address\n * @param amount uint256 amount of tokens to burn\n * @param data bytes extra information provided by the token holder\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _burn(address from, uint256 amount, bytes memory data, bytes memory operatorData) internal virtual {\n require(from != address(0), \"ERC777: burn from the zero address\");\n\n address operator = _msgSender();\n\n _callTokensToSend(operator, from, address(0), amount, data, operatorData);\n\n _beforeTokenTransfer(operator, from, address(0), amount);\n\n // Update state variables\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC777: burn amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Burned(operator, from, amount, data, operatorData);\n emit Transfer(from, address(0), amount);\n }\n\n function _move(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n ) private {\n _beforeTokenTransfer(operator, from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC777: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Sent(operator, from, to, amount, userData, operatorData);\n emit Transfer(from, to, amount);\n }\n\n /**\n * @dev See {ERC20-_approve}.\n *\n * Note that accounts cannot have allowance issued by their operators.\n */\n function _approve(address holder, address spender, uint256 value) internal virtual {\n require(holder != address(0), \"ERC777: approve from the zero address\");\n require(spender != address(0), \"ERC777: approve to the zero address\");\n\n _allowances[holder][spender] = value;\n emit Approval(holder, spender, value);\n }\n\n /**\n * @dev Call from.tokensToSend() if the interface is registered\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _callTokensToSend(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n ) private {\n address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(from, _TOKENS_SENDER_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Sender(implementer).tokensToSend(operator, from, to, amount, userData, operatorData);\n }\n }\n\n /**\n * @dev Call to.tokensReceived() if the interface is registered. Reverts if the recipient is a contract but\n * tokensReceived() was not registered for the recipient\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _callTokensReceived(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) private {\n address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(to, _TOKENS_RECIPIENT_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Recipient(implementer).tokensReceived(operator, from, to, amount, userData, operatorData);\n } else if (requireReceptionAck) {\n require(!to.isContract(), \"ERC777: token recipient contract has no implementer for ERC777TokensRecipient\");\n }\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {IERC20-Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC777: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes\n * calls to {send}, {transfer}, {operatorSend}, {transferFrom}, minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be to transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address operator, address from, address to, uint256 amount) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC777/IERC777.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777Token standard as defined in the EIP.\n *\n * This contract uses the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 registry standard] to let\n * token holders and recipients react to token movements by using setting implementers\n * for the associated interfaces in said registry. See {IERC1820Registry} and\n * {ERC1820Implementer}.\n */\ninterface IERC777 {\n /**\n * @dev Emitted when `amount` tokens are created by `operator` and assigned to `to`.\n *\n * Note that some additional user `data` and `operatorData` can be logged in the event.\n */\n event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);\n\n /**\n * @dev Emitted when `operator` destroys `amount` tokens from `account`.\n *\n * Note that some additional user `data` and `operatorData` can be logged in the event.\n */\n event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);\n\n /**\n * @dev Emitted when `operator` is made operator for `tokenHolder`.\n */\n event AuthorizedOperator(address indexed operator, address indexed tokenHolder);\n\n /**\n * @dev Emitted when `operator` is revoked its operator status for `tokenHolder`.\n */\n event RevokedOperator(address indexed operator, address indexed tokenHolder);\n\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, usually a shorter version of the\n * name.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the smallest part of the token that is not divisible. This\n * means all token operations (creation, movement and destruction) must have\n * amounts that are a multiple of this number.\n *\n * For most token contracts, this value will equal 1.\n */\n function granularity() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by an account (`owner`).\n */\n function balanceOf(address owner) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * If send or receive hooks are registered for the caller and `recipient`,\n * the corresponding functions will be called with `data` and empty\n * `operatorData`. See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits a {Sent} event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function send(address recipient, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Destroys `amount` tokens from the caller's account, reducing the\n * total supply.\n *\n * If a send hook is registered for the caller, the corresponding function\n * will be called with `data` and empty `operatorData`. See {IERC777Sender}.\n *\n * Emits a {Burned} event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n */\n function burn(uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Returns true if an account is an operator of `tokenHolder`.\n * Operators can send and burn tokens on behalf of their owners. All\n * accounts are their own operator.\n *\n * See {operatorSend} and {operatorBurn}.\n */\n function isOperatorFor(address operator, address tokenHolder) external view returns (bool);\n\n /**\n * @dev Make an account an operator of the caller.\n *\n * See {isOperatorFor}.\n *\n * Emits an {AuthorizedOperator} event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function authorizeOperator(address operator) external;\n\n /**\n * @dev Revoke an account's operator status for the caller.\n *\n * See {isOperatorFor} and {defaultOperators}.\n *\n * Emits a {RevokedOperator} event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function revokeOperator(address operator) external;\n\n /**\n * @dev Returns the list of default operators. These accounts are operators\n * for all token holders, even if {authorizeOperator} was never called on\n * them.\n *\n * This list is immutable, but individual holders may revoke these via\n * {revokeOperator}, in which case {isOperatorFor} will return false.\n */\n function defaultOperators() external view returns (address[] memory);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must\n * be an operator of `sender`.\n *\n * If send or receive hooks are registered for `sender` and `recipient`,\n * the corresponding functions will be called with `data` and\n * `operatorData`. See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits a {Sent} event.\n *\n * Requirements\n *\n * - `sender` cannot be the zero address.\n * - `sender` must have at least `amount` tokens.\n * - the caller must be an operator for `sender`.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes calldata data,\n bytes calldata operatorData\n ) external;\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the total supply.\n * The caller must be an operator of `account`.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with `data` and `operatorData`. See {IERC777Sender}.\n *\n * Emits a {Burned} event.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n * - the caller must be an operator for `account`.\n */\n function operatorBurn(address account, uint256 amount, bytes calldata data, bytes calldata operatorData) external;\n\n event Sent(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes data,\n bytes operatorData\n );\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\n *\n * Accounts can be notified of {IERC777} tokens being sent to them by having a\n * contract implement this interface (contract holders can be their own\n * implementer) and registering it on the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\n *\n * See {IERC1820Registry} and {ERC1820Implementer}.\n */\ninterface IERC777Recipient {\n /**\n * @dev Called by an {IERC777} token contract whenever tokens are being\n * moved or created into a registered account (`to`). The type of operation\n * is conveyed by `from` being the zero address or not.\n *\n * This call occurs _after_ the token contract's state is updated, so\n * {IERC777-balanceOf}, etc., can be used to query the post-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensReceived(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777Sender.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Sender.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777TokensSender standard as defined in the EIP.\n *\n * {IERC777} Token holders can be notified of operations performed on their\n * tokens by having a contract implement this interface (contract holders can be\n * their own implementer) and registering it on the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\n *\n * See {IERC1820Registry} and {ERC1820Implementer}.\n */\ninterface IERC777Sender {\n /**\n * @dev Called by an {IERC777} token contract whenever a registered holder's\n * (`from`) tokens are about to be moved or destroyed. The type of operation\n * is conveyed by `to` being the zero address or not.\n *\n * This call occurs _before_ the token contract's state is updated, so\n * {IERC777-balanceOf}, etc., can be used to query the pre-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensToSend(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n *\n * Furthermore, `isContract` will also return true if the target contract within\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n * which only has an effect at the end of a transaction.\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Counters.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary Counters {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/ECDSA.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Strings.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV // Deprecated in v4.8\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n /// @solidity memory-safe-assembly\n assembly {\n mstore(0x00, \"\\x19Ethereum Signed Message:\\n32\")\n mstore(0x1c, hash)\n message := keccak256(0x00, 0x3c)\n }\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\n /// @solidity memory-safe-assembly\n assembly {\n let ptr := mload(0x40)\n mstore(ptr, \"\\x19\\x01\")\n mstore(add(ptr, 0x02), domainSeparator)\n mstore(add(ptr, 0x22), structHash)\n data := keccak256(ptr, 0x42)\n }\n }\n\n /**\n * @dev Returns an Ethereum Signed Data with intended validator, created from a\n * `validator` and `data` according to the version 0 of EIP-191.\n *\n * See {recover}.\n */\n function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x00\", validator, data));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/SignatureChecker.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSA.sol\";\nimport \"../../interfaces/IERC1271.sol\";\n\n/**\n * @dev Signature verification helper that can be used instead of `ECDSA.recover` to seamlessly support both ECDSA\n * signatures from externally owned accounts (EOAs) as well as ERC1271 signatures from smart contract wallets like\n * Argent and Gnosis Safe.\n *\n * _Available since v4.1._\n */\nlibrary SignatureChecker {\n /**\n * @dev Checks if a signature is valid for a given signer and data hash. If the signer is a smart contract, the\n * signature is validated against that smart contract using ERC1271, otherwise it's validated using `ECDSA.recover`.\n *\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\n */\n function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature) internal view returns (bool) {\n (address recovered, ECDSA.RecoverError error) = ECDSA.tryRecover(hash, signature);\n return\n (error == ECDSA.RecoverError.NoError && recovered == signer) ||\n isValidERC1271SignatureNow(signer, hash, signature);\n }\n\n /**\n * @dev Checks if a signature is valid for a given signer and data hash. The signature is validated\n * against the signer smart contract using ERC1271.\n *\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\n */\n function isValidERC1271SignatureNow(\n address signer,\n bytes32 hash,\n bytes memory signature\n ) internal view returns (bool) {\n (bool success, bytes memory result) = signer.staticcall(\n abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, signature)\n );\n return (success &&\n result.length >= 32 &&\n abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/ERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165 is IERC165 {\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165).interfaceId;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC1820Registry.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/introspection/IERC1820Registry.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the global ERC1820 Registry, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register\n * implementers for interfaces in this registry, as well as query support.\n *\n * Implementers may be shared by multiple accounts, and can also implement more\n * than a single interface for each account. Contracts can implement interfaces\n * for themselves, but externally-owned accounts (EOA) must delegate this to a\n * contract.\n *\n * {IERC165} interfaces can also be queried via the registry.\n *\n * For an in-depth explanation and source code analysis, see the EIP text.\n */\ninterface IERC1820Registry {\n event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer);\n\n event ManagerChanged(address indexed account, address indexed newManager);\n\n /**\n * @dev Sets `newManager` as the manager for `account`. A manager of an\n * account is able to set interface implementers for it.\n *\n * By default, each account is its own manager. Passing a value of `0x0` in\n * `newManager` will reset the manager to this initial state.\n *\n * Emits a {ManagerChanged} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `account`.\n */\n function setManager(address account, address newManager) external;\n\n /**\n * @dev Returns the manager for `account`.\n *\n * See {setManager}.\n */\n function getManager(address account) external view returns (address);\n\n /**\n * @dev Sets the `implementer` contract as ``account``'s implementer for\n * `interfaceHash`.\n *\n * `account` being the zero address is an alias for the caller's address.\n * The zero address can also be used in `implementer` to remove an old one.\n *\n * See {interfaceHash} to learn how these are created.\n *\n * Emits an {InterfaceImplementerSet} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `account`.\n * - `interfaceHash` must not be an {IERC165} interface id (i.e. it must not\n * end in 28 zeroes).\n * - `implementer` must implement {IERC1820Implementer} and return true when\n * queried for support, unless `implementer` is the caller. See\n * {IERC1820Implementer-canImplementInterfaceForAddress}.\n */\n function setInterfaceImplementer(address account, bytes32 _interfaceHash, address implementer) external;\n\n /**\n * @dev Returns the implementer of `interfaceHash` for `account`. If no such\n * implementer is registered, returns the zero address.\n *\n * If `interfaceHash` is an {IERC165} interface id (i.e. it ends with 28\n * zeroes), `account` will be queried for support of it.\n *\n * `account` being the zero address is an alias for the caller's address.\n */\n function getInterfaceImplementer(address account, bytes32 _interfaceHash) external view returns (address);\n\n /**\n * @dev Returns the interface hash for an `interfaceName`, as defined in the\n * corresponding\n * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP].\n */\n function interfaceHash(string calldata interfaceName) external pure returns (bytes32);\n\n /**\n * @notice Updates the cache with whether the contract implements an ERC165 interface or not.\n * @param account Address of the contract for which to update the cache.\n * @param interfaceId ERC165 interface for which to update the cache.\n */\n function updateERC165Cache(address account, bytes4 interfaceId) external;\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not.\n * If the result is not cached a direct lookup on the contract address is performed.\n * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling\n * {updateERC165Cache} with the contract address.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool);\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not without using or updating the cache.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/math/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\n // The surrounding unchecked block does not change this fact.\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1, \"Math: mulDiv overflow\");\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n //\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n //\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n //\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1 << (log2(a) >> 1);\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = sqrt(a);\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 2, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 128;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 64;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 32;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 16;\n }\n if (value >> 8 > 0) {\n value >>= 8;\n result += 8;\n }\n if (value >> 4 > 0) {\n value >>= 4;\n result += 4;\n }\n if (value >> 2 > 0) {\n value >>= 2;\n result += 2;\n }\n if (value >> 1 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log2(value);\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 10, rounded down, of a positive value.\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 + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 256, rounded down, of a positive value.\n * Returns 0 if given 0.\n *\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n */\n function log256(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 16;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 8;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 4;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 2;\n }\n if (value >> 8 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log256(value);\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/SafeCast.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCast {\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 * _Available since v4.7._\n */\n function toUint248(uint256 value) internal pure returns (uint248) {\n require(value <= type(uint248).max, \"SafeCast: value doesn't fit in 248 bits\");\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 * _Available since v4.7._\n */\n function toUint240(uint256 value) internal pure returns (uint240) {\n require(value <= type(uint240).max, \"SafeCast: value doesn't fit in 240 bits\");\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 * _Available since v4.7._\n */\n function toUint232(uint256 value) internal pure returns (uint232) {\n require(value <= type(uint232).max, \"SafeCast: value doesn't fit in 232 bits\");\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 * _Available since v4.2._\n */\n function toUint224(uint256 value) internal pure returns (uint224) {\n require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\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 * _Available since v4.7._\n */\n function toUint216(uint256 value) internal pure returns (uint216) {\n require(value <= type(uint216).max, \"SafeCast: value doesn't fit in 216 bits\");\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 * _Available since v4.7._\n */\n function toUint208(uint256 value) internal pure returns (uint208) {\n require(value <= type(uint208).max, \"SafeCast: value doesn't fit in 208 bits\");\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 * _Available since v4.7._\n */\n function toUint200(uint256 value) internal pure returns (uint200) {\n require(value <= type(uint200).max, \"SafeCast: value doesn't fit in 200 bits\");\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 * _Available since v4.7._\n */\n function toUint192(uint256 value) internal pure returns (uint192) {\n require(value <= type(uint192).max, \"SafeCast: value doesn't fit in 192 bits\");\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 * _Available since v4.7._\n */\n function toUint184(uint256 value) internal pure returns (uint184) {\n require(value <= type(uint184).max, \"SafeCast: value doesn't fit in 184 bits\");\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 * _Available since v4.7._\n */\n function toUint176(uint256 value) internal pure returns (uint176) {\n require(value <= type(uint176).max, \"SafeCast: value doesn't fit in 176 bits\");\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 * _Available since v4.7._\n */\n function toUint168(uint256 value) internal pure returns (uint168) {\n require(value <= type(uint168).max, \"SafeCast: value doesn't fit in 168 bits\");\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 * _Available since v4.7._\n */\n function toUint160(uint256 value) internal pure returns (uint160) {\n require(value <= type(uint160).max, \"SafeCast: value doesn't fit in 160 bits\");\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 * _Available since v4.7._\n */\n function toUint152(uint256 value) internal pure returns (uint152) {\n require(value <= type(uint152).max, \"SafeCast: value doesn't fit in 152 bits\");\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 * _Available since v4.7._\n */\n function toUint144(uint256 value) internal pure returns (uint144) {\n require(value <= type(uint144).max, \"SafeCast: value doesn't fit in 144 bits\");\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 * _Available since v4.7._\n */\n function toUint136(uint256 value) internal pure returns (uint136) {\n require(value <= type(uint136).max, \"SafeCast: value doesn't fit in 136 bits\");\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 * _Available since v2.5._\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\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 * _Available since v4.7._\n */\n function toUint120(uint256 value) internal pure returns (uint120) {\n require(value <= type(uint120).max, \"SafeCast: value doesn't fit in 120 bits\");\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 * _Available since v4.7._\n */\n function toUint112(uint256 value) internal pure returns (uint112) {\n require(value <= type(uint112).max, \"SafeCast: value doesn't fit in 112 bits\");\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 * _Available since v4.7._\n */\n function toUint104(uint256 value) internal pure returns (uint104) {\n require(value <= type(uint104).max, \"SafeCast: value doesn't fit in 104 bits\");\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 * _Available since v4.2._\n */\n function toUint96(uint256 value) internal pure returns (uint96) {\n require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\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 * _Available since v4.7._\n */\n function toUint88(uint256 value) internal pure returns (uint88) {\n require(value <= type(uint88).max, \"SafeCast: value doesn't fit in 88 bits\");\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 * _Available since v4.7._\n */\n function toUint80(uint256 value) internal pure returns (uint80) {\n require(value <= type(uint80).max, \"SafeCast: value doesn't fit in 80 bits\");\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 * _Available since v4.7._\n */\n function toUint72(uint256 value) internal pure returns (uint72) {\n require(value <= type(uint72).max, \"SafeCast: value doesn't fit in 72 bits\");\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 * _Available since v2.5._\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\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 * _Available since v4.7._\n */\n function toUint56(uint256 value) internal pure returns (uint56) {\n require(value <= type(uint56).max, \"SafeCast: value doesn't fit in 56 bits\");\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 * _Available since v4.7._\n */\n function toUint48(uint256 value) internal pure returns (uint48) {\n require(value <= type(uint48).max, \"SafeCast: value doesn't fit in 48 bits\");\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 * _Available since v4.7._\n */\n function toUint40(uint256 value) internal pure returns (uint40) {\n require(value <= type(uint40).max, \"SafeCast: value doesn't fit in 40 bits\");\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 * _Available since v2.5._\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\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 * _Available since v4.7._\n */\n function toUint24(uint256 value) internal pure returns (uint24) {\n require(value <= type(uint24).max, \"SafeCast: value doesn't fit in 24 bits\");\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 * _Available since v2.5._\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\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 * _Available since v2.5._\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\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 * _Available since v3.0._\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\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 * _Available since v4.7._\n */\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\n downcasted = int248(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 248 bits\");\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 * _Available since v4.7._\n */\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\n downcasted = int240(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 240 bits\");\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 * _Available since v4.7._\n */\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\n downcasted = int232(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 232 bits\");\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 * _Available since v4.7._\n */\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\n downcasted = int224(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 224 bits\");\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 * _Available since v4.7._\n */\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\n downcasted = int216(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 216 bits\");\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 * _Available since v4.7._\n */\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\n downcasted = int208(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 208 bits\");\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 * _Available since v4.7._\n */\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\n downcasted = int200(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 200 bits\");\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 * _Available since v4.7._\n */\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\n downcasted = int192(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 192 bits\");\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 * _Available since v4.7._\n */\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\n downcasted = int184(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 184 bits\");\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 * _Available since v4.7._\n */\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\n downcasted = int176(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 176 bits\");\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 * _Available since v4.7._\n */\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\n downcasted = int168(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 168 bits\");\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 * _Available since v4.7._\n */\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\n downcasted = int160(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 160 bits\");\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 * _Available since v4.7._\n */\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\n downcasted = int152(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 152 bits\");\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 * _Available since v4.7._\n */\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\n downcasted = int144(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 144 bits\");\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 * _Available since v4.7._\n */\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\n downcasted = int136(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 136 bits\");\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 * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\n downcasted = int128(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 128 bits\");\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 * _Available since v4.7._\n */\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\n downcasted = int120(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 120 bits\");\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 * _Available since v4.7._\n */\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\n downcasted = int112(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 112 bits\");\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 * _Available since v4.7._\n */\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\n downcasted = int104(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 104 bits\");\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 * _Available since v4.7._\n */\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\n downcasted = int96(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 96 bits\");\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 * _Available since v4.7._\n */\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\n downcasted = int88(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 88 bits\");\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 * _Available since v4.7._\n */\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\n downcasted = int80(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 80 bits\");\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 * _Available since v4.7._\n */\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\n downcasted = int72(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 72 bits\");\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 * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\n downcasted = int64(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 64 bits\");\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 * _Available since v4.7._\n */\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\n downcasted = int56(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 56 bits\");\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 * _Available since v4.7._\n */\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\n downcasted = int48(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 48 bits\");\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 * _Available since v4.7._\n */\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\n downcasted = int40(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 40 bits\");\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 * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\n downcasted = int32(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 32 bits\");\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 * _Available since v4.7._\n */\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\n downcasted = int24(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 24 bits\");\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 * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\n downcasted = int16(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 16 bits\");\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 * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\n downcasted = int8(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 8 bits\");\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 * _Available since v3.0._\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 require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/SignedMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard signed math utilities missing in the Solidity language.\n */\nlibrary SignedMath {\n /**\n * @dev Returns the largest of two signed numbers.\n */\n function max(int256 a, int256 b) internal pure returns (int256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two signed numbers.\n */\n function min(int256 a, int256 b) internal pure returns (int256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two signed numbers without overflow.\n * The result is rounded towards zero.\n */\n function average(int256 a, int256 b) internal pure returns (int256) {\n // Formula from the book \"Hacker's Delight\"\n int256 x = (a & b) + ((a ^ b) >> 1);\n return x + (int256(uint256(x) >> 255) & (a ^ b));\n }\n\n /**\n * @dev Returns the absolute unsigned value of a signed value.\n */\n function abs(int256 n) internal pure returns (uint256) {\n unchecked {\n // must be unchecked in order to support `n = type(int256).min`\n return uint256(n >= 0 ? n : -n);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/Math.sol\";\nimport \"./math/SignedMath.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n unchecked {\n uint256 length = Math.log10(value) + 1;\n string memory buffer = new string(length);\n uint256 ptr;\n /// @solidity memory-safe-assembly\n assembly {\n ptr := add(buffer, add(32, length))\n }\n while (true) {\n ptr--;\n /// @solidity memory-safe-assembly\n assembly {\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n }\n value /= 10;\n if (value == 0) break;\n }\n return buffer;\n }\n }\n\n /**\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\n */\n function toString(int256 value) internal pure returns (string memory) {\n return string(abi.encodePacked(value < 0 ? \"-\" : \"\", toString(SignedMath.abs(value))));\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n unchecked {\n return toHexString(value, Math.log256(value) + 1);\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n\n /**\n * @dev Returns true if the two strings are equal.\n */\n function equal(string memory a, string memory b) internal pure returns (bool) {\n return keccak256(bytes(a)) == keccak256(bytes(b));\n }\n}\n" + }, + "contracts/aa-4337/core/BaseAccount.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-empty-blocks */\n\nimport \"../interfaces/IAccount.sol\";\nimport \"../interfaces/IEntryPoint.sol\";\nimport \"./Helpers.sol\";\n\n/**\n * Basic account implementation.\n * this contract provides the basic logic for implementing the IAccount interface - validateUserOp\n * specific account implementation should inherit it and provide the account-specific logic\n */\nabstract contract BaseAccount is IAccount {\n using UserOperationLib for UserOperation;\n\n //return value in case of signature failure, with no time-range.\n // equivalent to _packValidationData(true,0,0);\n uint256 internal constant SIG_VALIDATION_FAILED = 1;\n\n /**\n * Return the account nonce.\n * This method returns the next sequential nonce.\n * For a nonce of a specific key, use `entrypoint.getNonce(account, key)`\n */\n function getNonce() public view virtual returns (uint256) {\n return entryPoint().getNonce(address(this), 0);\n }\n\n /**\n * return the entryPoint used by this account.\n * subclass should return the current entryPoint used by this account.\n */\n function entryPoint() public view virtual returns (IEntryPoint);\n\n /**\n * Validate user's signature and nonce.\n * subclass doesn't need to override this method. Instead, it should override the specific internal validation methods.\n */\n function validateUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 missingAccountFunds\n ) external virtual override returns (uint256 validationData) {\n _requireFromEntryPoint();\n validationData = _validateSignature(userOp, userOpHash);\n _validateNonce(userOp.nonce);\n _payPrefund(missingAccountFunds);\n }\n\n /**\n * ensure the request comes from the known entrypoint.\n */\n function _requireFromEntryPoint() internal view virtual {\n require(\n msg.sender == address(entryPoint()),\n \"account: not from EntryPoint\"\n );\n }\n\n /**\n * validate the signature is valid for this message.\n * @param userOp validate the userOp.signature field\n * @param userOpHash convenient field: the hash of the request, to check the signature against\n * (also hashes the entrypoint and chain id)\n * @return validationData signature and time-range of this operation\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * If the account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function _validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) internal virtual returns (uint256 validationData);\n\n /**\n * Validate the nonce of the UserOperation.\n * This method may validate the nonce requirement of this account.\n * e.g.\n * To limit the nonce to use sequenced UserOps only (no \"out of order\" UserOps):\n * `require(nonce < type(uint64).max)`\n * For a hypothetical account that *requires* the nonce to be out-of-order:\n * `require(nonce & type(uint64).max == 0)`\n *\n * The actual nonce uniqueness is managed by the EntryPoint, and thus no other\n * action is needed by the account itself.\n *\n * @param nonce to validate\n *\n * solhint-disable-next-line no-empty-blocks\n */\n function _validateNonce(uint256 nonce) internal view virtual {}\n\n /**\n * sends to the entrypoint (msg.sender) the missing funds for this transaction.\n * subclass MAY override this method for better funds management\n * (e.g. send to the entryPoint more than the minimum required, so that in future transactions\n * it will not be required to send again)\n * @param missingAccountFunds the minimum value this method should send the entrypoint.\n * this value MAY be zero, in case there is enough deposit, or the userOp has a paymaster.\n */\n function _payPrefund(uint256 missingAccountFunds) internal virtual {\n if (missingAccountFunds != 0) {\n (bool success, ) = payable(msg.sender).call{\n value: missingAccountFunds,\n gas: type(uint256).max\n }(\"\");\n (success);\n //ignore failure (its EntryPoint's job to verify, not account.)\n }\n }\n}\n" + }, + "contracts/aa-4337/core/EntryPoint.sol": { + "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n\nimport \"../interfaces/IAccount.sol\";\nimport \"../interfaces/IPaymaster.sol\";\nimport \"../interfaces/IEntryPoint.sol\";\n\nimport \"../utils/Exec.sol\";\nimport \"./StakeManager.sol\";\nimport \"./SenderCreator.sol\";\nimport \"./Helpers.sol\";\nimport \"./NonceManager.sol\";\nimport \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\n\ncontract EntryPoint is\n IEntryPoint,\n StakeManager,\n NonceManager,\n ReentrancyGuard\n{\n using UserOperationLib for UserOperation;\n\n SenderCreator private immutable senderCreator = new SenderCreator();\n\n // internal value used during simulation: need to query aggregator.\n address private constant SIMULATE_FIND_AGGREGATOR = address(1);\n\n // marker for inner call revert on out of gas\n bytes32 private constant INNER_OUT_OF_GAS = hex\"deaddead\";\n\n uint256 private constant REVERT_REASON_MAX_LEN = 2048;\n\n /**\n * for simulation purposes, validateUserOp (and validatePaymasterUserOp) must return this value\n * in case of signature failure, instead of revert.\n */\n uint256 public constant SIG_VALIDATION_FAILED = 1;\n\n /**\n * compensate the caller's beneficiary address with the collected fees of all UserOperations.\n * @param beneficiary the address to receive the fees\n * @param amount amount to transfer.\n */\n function _compensate(address payable beneficiary, uint256 amount) internal {\n require(beneficiary != address(0), \"AA90 invalid beneficiary\");\n (bool success, ) = beneficiary.call{value: amount}(\"\");\n require(success, \"AA91 failed send to beneficiary\");\n }\n\n /**\n * execute a user op\n * @param opIndex index into the opInfo array\n * @param userOp the userOp to execute\n * @param opInfo the opInfo filled by validatePrepayment for this userOp.\n * @return collected the total amount this userOp paid.\n */\n function _executeUserOp(\n uint256 opIndex,\n UserOperation calldata userOp,\n UserOpInfo memory opInfo\n ) private returns (uint256 collected) {\n uint256 preGas = gasleft();\n bytes memory context = getMemoryBytesFromOffset(opInfo.contextOffset);\n\n try this.innerHandleOp(userOp.callData, opInfo, context) returns (\n uint256 _actualGasCost\n ) {\n collected = _actualGasCost;\n } catch {\n bytes32 innerRevertCode;\n assembly {\n returndatacopy(0, 0, 32)\n innerRevertCode := mload(0)\n }\n // handleOps was called with gas limit too low. abort entire bundle.\n if (innerRevertCode == INNER_OUT_OF_GAS) {\n //report paymaster, since if it is not deliberately caused by the bundler,\n // it must be a revert caused by paymaster.\n revert FailedOp(opIndex, \"AA95 out of gas\");\n }\n\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n collected = _handlePostOp(\n opIndex,\n IPaymaster.PostOpMode.postOpReverted,\n opInfo,\n context,\n actualGas\n );\n }\n }\n\n /**\n * Execute a batch of UserOperations.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(\n UserOperation[] calldata ops,\n address payable beneficiary\n ) public nonReentrant {\n uint256 opslen = ops.length;\n UserOpInfo[] memory opInfos = new UserOpInfo[](opslen);\n\n unchecked {\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[i];\n (\n uint256 validationData,\n uint256 pmValidationData\n ) = _validatePrepayment(i, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(\n i,\n validationData,\n pmValidationData,\n address(0)\n );\n }\n\n uint256 collected = 0;\n emit BeforeExecution();\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(i, ops[i], opInfos[i]);\n }\n\n _compensate(beneficiary, collected);\n } //unchecked\n }\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) public nonReentrant {\n uint256 opasLen = opsPerAggregator.length;\n uint256 totalOps = 0;\n for (uint256 i = 0; i < opasLen; i++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[i];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n //address(1) is special marker of \"signature error\"\n require(\n address(aggregator) != address(1),\n \"AA96 invalid aggregator\"\n );\n\n if (address(aggregator) != address(0)) {\n // solhint-disable-next-line no-empty-blocks\n try aggregator.validateSignatures(ops, opa.signature) {} catch {\n revert SignatureValidationFailed(address(aggregator));\n }\n }\n\n totalOps += ops.length;\n }\n\n UserOpInfo[] memory opInfos = new UserOpInfo[](totalOps);\n\n emit BeforeExecution();\n\n uint256 opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n uint256 opslen = ops.length;\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[opIndex];\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(opIndex, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(\n i,\n validationData,\n paymasterValidationData,\n address(aggregator)\n );\n opIndex++;\n }\n }\n\n uint256 collected = 0;\n opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n emit SignatureAggregatorChanged(address(opa.aggregator));\n UserOperation[] calldata ops = opa.userOps;\n uint256 opslen = ops.length;\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(opIndex, ops[i], opInfos[opIndex]);\n opIndex++;\n }\n }\n emit SignatureAggregatorChanged(address(0));\n\n _compensate(beneficiary, collected);\n }\n\n /// @inheritdoc IEntryPoint\n function simulateHandleOp(\n UserOperation calldata op,\n address target,\n bytes calldata targetCallData\n ) external override {\n UserOpInfo memory opInfo;\n _simulationOnlyValidations(op);\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(0, op, opInfo);\n ValidationData memory data = _intersectTimeRange(\n validationData,\n paymasterValidationData\n );\n\n numberMarker();\n uint256 paid = _executeUserOp(0, op, opInfo);\n numberMarker();\n bool targetSuccess;\n bytes memory targetResult;\n if (target != address(0)) {\n (targetSuccess, targetResult) = target.call(targetCallData);\n }\n revert ExecutionResult(\n opInfo.preOpGas,\n paid,\n data.validAfter,\n data.validUntil,\n targetSuccess,\n targetResult\n );\n }\n\n // A memory copy of UserOp static fields only.\n // Excluding: callData, initCode and signature. Replacing paymasterAndData with paymaster.\n struct MemoryUserOp {\n address sender;\n uint256 nonce;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n address paymaster;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n }\n\n struct UserOpInfo {\n MemoryUserOp mUserOp;\n bytes32 userOpHash;\n uint256 prefund;\n uint256 contextOffset;\n uint256 preOpGas;\n }\n\n /**\n * inner function to handle a UserOperation.\n * Must be declared \"external\" to open a call context, but it can only be called by handleOps.\n */\n function innerHandleOp(\n bytes memory callData,\n UserOpInfo memory opInfo,\n bytes calldata context\n ) external returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n require(msg.sender == address(this), \"AA92 internal call only\");\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n\n uint callGasLimit = mUserOp.callGasLimit;\n unchecked {\n // handleOps was called with gas limit too low. abort entire bundle.\n if (\n gasleft() < callGasLimit + mUserOp.verificationGasLimit + 5000\n ) {\n assembly {\n mstore(0, INNER_OUT_OF_GAS)\n revert(0, 32)\n }\n }\n }\n\n IPaymaster.PostOpMode mode = IPaymaster.PostOpMode.opSucceeded;\n if (callData.length > 0) {\n bool success = Exec.call(mUserOp.sender, 0, callData, callGasLimit);\n if (!success) {\n bytes memory result = Exec.getReturnData(REVERT_REASON_MAX_LEN);\n if (result.length > 0) {\n emit UserOperationRevertReason(\n opInfo.userOpHash,\n mUserOp.sender,\n mUserOp.nonce,\n result\n );\n }\n mode = IPaymaster.PostOpMode.opReverted;\n }\n }\n\n unchecked {\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n //note: opIndex is ignored (relevant only if mode==postOpReverted, which is only possible outside of innerHandleOp)\n return _handlePostOp(0, mode, opInfo, context, actualGas);\n }\n }\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(\n UserOperation calldata userOp\n ) public view returns (bytes32) {\n return\n keccak256(abi.encode(userOp.hash(), address(this), block.chainid));\n }\n\n /**\n * copy general fields from userOp into the memory opInfo structure.\n */\n function _copyUserOpToMemory(\n UserOperation calldata userOp,\n MemoryUserOp memory mUserOp\n ) internal pure {\n mUserOp.sender = userOp.sender;\n mUserOp.nonce = userOp.nonce;\n mUserOp.callGasLimit = userOp.callGasLimit;\n mUserOp.verificationGasLimit = userOp.verificationGasLimit;\n mUserOp.preVerificationGas = userOp.preVerificationGas;\n mUserOp.maxFeePerGas = userOp.maxFeePerGas;\n mUserOp.maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes calldata paymasterAndData = userOp.paymasterAndData;\n if (paymasterAndData.length > 0) {\n require(\n paymasterAndData.length >= 20,\n \"AA93 invalid paymasterAndData\"\n );\n mUserOp.paymaster = address(bytes20(paymasterAndData[:20]));\n } else {\n mUserOp.paymaster = address(0);\n }\n }\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external {\n UserOpInfo memory outOpInfo;\n\n _simulationOnlyValidations(userOp);\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(0, userOp, outOpInfo);\n StakeInfo memory paymasterInfo = _getStakeInfo(\n outOpInfo.mUserOp.paymaster\n );\n StakeInfo memory senderInfo = _getStakeInfo(outOpInfo.mUserOp.sender);\n StakeInfo memory factoryInfo;\n {\n bytes calldata initCode = userOp.initCode;\n address factory = initCode.length >= 20\n ? address(bytes20(initCode[0:20]))\n : address(0);\n factoryInfo = _getStakeInfo(factory);\n }\n\n ValidationData memory data = _intersectTimeRange(\n validationData,\n paymasterValidationData\n );\n address aggregator = data.aggregator;\n bool sigFailed = aggregator == address(1);\n ReturnInfo memory returnInfo = ReturnInfo(\n outOpInfo.preOpGas,\n outOpInfo.prefund,\n sigFailed,\n data.validAfter,\n data.validUntil,\n getMemoryBytesFromOffset(outOpInfo.contextOffset)\n );\n\n if (aggregator != address(0) && aggregator != address(1)) {\n AggregatorStakeInfo memory aggregatorInfo = AggregatorStakeInfo(\n aggregator,\n _getStakeInfo(aggregator)\n );\n revert ValidationResultWithAggregation(\n returnInfo,\n senderInfo,\n factoryInfo,\n paymasterInfo,\n aggregatorInfo\n );\n }\n revert ValidationResult(\n returnInfo,\n senderInfo,\n factoryInfo,\n paymasterInfo\n );\n }\n\n function _getRequiredPrefund(\n MemoryUserOp memory mUserOp\n ) internal pure returns (uint256 requiredPrefund) {\n unchecked {\n //when using a Paymaster, the verificationGasLimit is used also to as a limit for the postOp call.\n // our security model might call postOp eventually twice\n uint256 mul = mUserOp.paymaster != address(0) ? 3 : 1;\n uint256 requiredGas = mUserOp.callGasLimit +\n mUserOp.verificationGasLimit *\n mul +\n mUserOp.preVerificationGas;\n\n requiredPrefund = requiredGas * mUserOp.maxFeePerGas;\n }\n }\n\n // create the sender's contract if needed.\n function _createSenderIfNeeded(\n uint256 opIndex,\n UserOpInfo memory opInfo,\n bytes calldata initCode\n ) internal {\n if (initCode.length != 0) {\n address sender = opInfo.mUserOp.sender;\n if (sender.code.length != 0)\n revert FailedOp(opIndex, \"AA10 sender already constructed\");\n address sender1 = senderCreator.createSender{\n gas: opInfo.mUserOp.verificationGasLimit\n }(initCode);\n if (sender1 == address(0))\n revert FailedOp(opIndex, \"AA13 initCode failed or OOG\");\n if (sender1 != sender)\n revert FailedOp(opIndex, \"AA14 initCode must return sender\");\n if (sender1.code.length == 0)\n revert FailedOp(opIndex, \"AA15 initCode must create sender\");\n address factory = address(bytes20(initCode[0:20]));\n emit AccountDeployed(\n opInfo.userOpHash,\n sender,\n factory,\n opInfo.mUserOp.paymaster\n );\n }\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes calldata initCode) public {\n address sender = senderCreator.createSender(initCode);\n revert SenderAddressResult(sender);\n }\n\n function _simulationOnlyValidations(\n UserOperation calldata userOp\n ) internal view {\n // solhint-disable-next-line no-empty-blocks\n try\n this._validateSenderAndPaymaster(\n userOp.initCode,\n userOp.sender,\n userOp.paymasterAndData\n )\n {} catch Error(string memory revertReason) {\n if (bytes(revertReason).length != 0) {\n revert FailedOp(0, revertReason);\n }\n }\n }\n\n /**\n * Called only during simulation.\n * This function always reverts to prevent warm/cold storage differentiation in simulation vs execution.\n */\n function _validateSenderAndPaymaster(\n bytes calldata initCode,\n address sender,\n bytes calldata paymasterAndData\n ) external view {\n if (initCode.length == 0 && sender.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA20 account not deployed\");\n }\n if (paymasterAndData.length >= 20) {\n address paymaster = address(bytes20(paymasterAndData[0:20]));\n if (paymaster.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA30 paymaster not deployed\");\n }\n }\n // always revert\n revert(\"\");\n }\n\n /**\n * call account.validateUserOp.\n * revert (with FailedOp) in case validateUserOp reverts, or account didn't send required prefund.\n * decrement account's deposit if needed\n */\n function _validateAccountPrepayment(\n uint256 opIndex,\n UserOperation calldata op,\n UserOpInfo memory opInfo,\n uint256 requiredPrefund\n )\n internal\n returns (\n uint256 gasUsedByValidateAccountPrepayment,\n uint256 validationData\n )\n {\n unchecked {\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n address sender = mUserOp.sender;\n _createSenderIfNeeded(opIndex, opInfo, op.initCode);\n address paymaster = mUserOp.paymaster;\n numberMarker();\n uint256 missingAccountFunds = 0;\n if (paymaster == address(0)) {\n uint256 bal = balanceOf(sender);\n missingAccountFunds = bal > requiredPrefund\n ? 0\n : requiredPrefund - bal;\n }\n try\n IAccount(sender).validateUserOp{\n gas: mUserOp.verificationGasLimit\n }(op, opInfo.userOpHash, missingAccountFunds)\n returns (uint256 _validationData) {\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA23 reverted: \", revertReason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA23 reverted (or OOG)\");\n }\n if (paymaster == address(0)) {\n DepositInfo storage senderInfo = deposits[sender];\n uint256 deposit = senderInfo.deposit;\n if (requiredPrefund > deposit) {\n revert FailedOp(opIndex, \"AA21 didn't pay prefund\");\n }\n senderInfo.deposit = uint112(deposit - requiredPrefund);\n }\n gasUsedByValidateAccountPrepayment = preGas - gasleft();\n }\n }\n\n /**\n * In case the request has a paymaster:\n * Validate paymaster has enough deposit.\n * Call paymaster.validatePaymasterUserOp.\n * Revert with proper FailedOp in case paymaster reverts.\n * Decrement paymaster's deposit\n */\n function _validatePaymasterPrepayment(\n uint256 opIndex,\n UserOperation calldata op,\n UserOpInfo memory opInfo,\n uint256 requiredPreFund,\n uint256 gasUsedByValidateAccountPrepayment\n ) internal returns (bytes memory context, uint256 validationData) {\n unchecked {\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 verificationGasLimit = mUserOp.verificationGasLimit;\n require(\n verificationGasLimit > gasUsedByValidateAccountPrepayment,\n \"AA41 too little verificationGas\"\n );\n uint256 gas = verificationGasLimit -\n gasUsedByValidateAccountPrepayment;\n\n address paymaster = mUserOp.paymaster;\n DepositInfo storage paymasterInfo = deposits[paymaster];\n uint256 deposit = paymasterInfo.deposit;\n if (deposit < requiredPreFund) {\n revert FailedOp(opIndex, \"AA31 paymaster deposit too low\");\n }\n paymasterInfo.deposit = uint112(deposit - requiredPreFund);\n try\n IPaymaster(paymaster).validatePaymasterUserOp{gas: gas}(\n op,\n opInfo.userOpHash,\n requiredPreFund\n )\n returns (bytes memory _context, uint256 _validationData) {\n context = _context;\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA33 reverted: \", revertReason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA33 reverted (or OOG)\");\n }\n }\n }\n\n /**\n * revert if either account validationData or paymaster validationData is expired\n */\n function _validateAccountAndPaymasterValidationData(\n uint256 opIndex,\n uint256 validationData,\n uint256 paymasterValidationData,\n address expectedAggregator\n ) internal view {\n (address aggregator, bool outOfTimeRange) = _getValidationData(\n validationData\n );\n if (expectedAggregator != aggregator) {\n revert FailedOp(opIndex, \"AA24 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA22 expired or not due\");\n }\n //pmAggregator is not a real signature aggregator: we don't have logic to handle it as address.\n // non-zero address means that the paymaster fails due to some signature check (which is ok only during estimation)\n address pmAggregator;\n (pmAggregator, outOfTimeRange) = _getValidationData(\n paymasterValidationData\n );\n if (pmAggregator != address(0)) {\n revert FailedOp(opIndex, \"AA34 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA32 paymaster expired or not due\");\n }\n }\n\n function _getValidationData(\n uint256 validationData\n ) internal view returns (address aggregator, bool outOfTimeRange) {\n if (validationData == 0) {\n return (address(0), false);\n }\n ValidationData memory data = _parseValidationData(validationData);\n // solhint-disable-next-line not-rely-on-time\n outOfTimeRange =\n block.timestamp > data.validUntil ||\n block.timestamp < data.validAfter;\n aggregator = data.aggregator;\n }\n\n /**\n * validate account and paymaster (if defined).\n * also make sure total validation doesn't exceed verificationGasLimit\n * this method is called off-chain (simulateValidation()) and on-chain (from handleOps)\n * @param opIndex the index of this userOp into the \"opInfos\" array\n * @param userOp the userOp to validate\n */\n function _validatePrepayment(\n uint256 opIndex,\n UserOperation calldata userOp,\n UserOpInfo memory outOpInfo\n )\n private\n returns (uint256 validationData, uint256 paymasterValidationData)\n {\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = outOpInfo.mUserOp;\n _copyUserOpToMemory(userOp, mUserOp);\n outOpInfo.userOpHash = getUserOpHash(userOp);\n\n // validate all numeric values in userOp are well below 128 bit, so they can safely be added\n // and multiplied without causing overflow\n uint256 maxGasValues = mUserOp.preVerificationGas |\n mUserOp.verificationGasLimit |\n mUserOp.callGasLimit |\n userOp.maxFeePerGas |\n userOp.maxPriorityFeePerGas;\n require(maxGasValues <= type(uint120).max, \"AA94 gas values overflow\");\n\n uint256 gasUsedByValidateAccountPrepayment;\n uint256 requiredPreFund = _getRequiredPrefund(mUserOp);\n (\n gasUsedByValidateAccountPrepayment,\n validationData\n ) = _validateAccountPrepayment(\n opIndex,\n userOp,\n outOpInfo,\n requiredPreFund\n );\n\n if (!_validateAndUpdateNonce(mUserOp.sender, mUserOp.nonce)) {\n revert FailedOp(opIndex, \"AA25 invalid account nonce\");\n }\n\n //a \"marker\" where account opcode validation is done and paymaster opcode validation is about to start\n // (used only by off-chain simulateValidation)\n numberMarker();\n\n bytes memory context;\n if (mUserOp.paymaster != address(0)) {\n (context, paymasterValidationData) = _validatePaymasterPrepayment(\n opIndex,\n userOp,\n outOpInfo,\n requiredPreFund,\n gasUsedByValidateAccountPrepayment\n );\n }\n unchecked {\n uint256 gasUsed = preGas - gasleft();\n\n if (userOp.verificationGasLimit < gasUsed) {\n revert FailedOp(opIndex, \"AA40 over verificationGasLimit\");\n }\n outOpInfo.prefund = requiredPreFund;\n outOpInfo.contextOffset = getOffsetOfMemoryBytes(context);\n outOpInfo.preOpGas = preGas - gasleft() + userOp.preVerificationGas;\n }\n }\n\n /**\n * process post-operation.\n * called just after the callData is executed.\n * if a paymaster is defined and its validation returned a non-empty context, its postOp is called.\n * the excess amount is refunded to the account (or paymaster - if it was used in the request)\n * @param opIndex index in the batch\n * @param mode - whether is called from innerHandleOp, or outside (postOpReverted)\n * @param opInfo userOp fields and info collected during validation\n * @param context the context returned in validatePaymasterUserOp\n * @param actualGas the gas used so far by this user operation\n */\n function _handlePostOp(\n uint256 opIndex,\n IPaymaster.PostOpMode mode,\n UserOpInfo memory opInfo,\n bytes memory context,\n uint256 actualGas\n ) private returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n unchecked {\n address refundAddress;\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 gasPrice = getUserOpGasPrice(mUserOp);\n\n address paymaster = mUserOp.paymaster;\n if (paymaster == address(0)) {\n refundAddress = mUserOp.sender;\n } else {\n refundAddress = paymaster;\n if (context.length > 0) {\n actualGasCost = actualGas * gasPrice;\n if (mode != IPaymaster.PostOpMode.postOpReverted) {\n IPaymaster(paymaster).postOp{\n gas: mUserOp.verificationGasLimit\n }(mode, context, actualGasCost);\n } else {\n // solhint-disable-next-line no-empty-blocks\n try\n IPaymaster(paymaster).postOp{\n gas: mUserOp.verificationGasLimit\n }(mode, context, actualGasCost)\n {} catch Error(string memory reason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA50 postOp reverted: \", reason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA50 postOp revert\");\n }\n }\n }\n }\n actualGas += preGas - gasleft();\n actualGasCost = actualGas * gasPrice;\n if (opInfo.prefund < actualGasCost) {\n revert FailedOp(opIndex, \"AA51 prefund below actualGasCost\");\n }\n uint256 refund = opInfo.prefund - actualGasCost;\n _incrementDeposit(refundAddress, refund);\n bool success = mode == IPaymaster.PostOpMode.opSucceeded;\n emit UserOperationEvent(\n opInfo.userOpHash,\n mUserOp.sender,\n mUserOp.paymaster,\n mUserOp.nonce,\n success,\n actualGasCost,\n actualGas\n );\n } // unchecked\n }\n\n /**\n * the gas price this UserOp agrees to pay.\n * relayer/block builder might submit the TX with higher priorityFee, but the user should not\n */\n function getUserOpGasPrice(\n MemoryUserOp memory mUserOp\n ) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = mUserOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = mUserOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n function getOffsetOfMemoryBytes(\n bytes memory data\n ) internal pure returns (uint256 offset) {\n assembly {\n offset := data\n }\n }\n\n function getMemoryBytesFromOffset(\n uint256 offset\n ) internal pure returns (bytes memory data) {\n assembly {\n data := offset\n }\n }\n\n //place the NUMBER opcode in the code.\n // this is used as a marker during simulation, as this OP is completely banned from the simulated code of the\n // account and paymaster.\n function numberMarker() internal view {\n assembly {\n mstore(0, number())\n }\n }\n}\n" + }, + "contracts/aa-4337/core/Helpers.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable no-inline-assembly */\n\n/**\n * returned data from validateUserOp.\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\n * @param aggregator - address(0) - the account validated the signature by itself.\n * address(1) - the account failed to validate the signature.\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\n * @param validAfter - this UserOp is valid only after this timestamp.\n * @param validaUntil - this UserOp is valid only up to this timestamp.\n */\nstruct ValidationData {\n address aggregator;\n uint48 validAfter;\n uint48 validUntil;\n}\n\n//extract sigFailed, validAfter, validUntil.\n// also convert zero validUntil to type(uint48).max\nfunction _parseValidationData(\n uint validationData\n) pure returns (ValidationData memory data) {\n address aggregator = address(uint160(validationData));\n uint48 validUntil = uint48(validationData >> 160);\n if (validUntil == 0) {\n validUntil = type(uint48).max;\n }\n uint48 validAfter = uint48(validationData >> (48 + 160));\n return ValidationData(aggregator, validAfter, validUntil);\n}\n\n// intersect account and paymaster ranges.\nfunction _intersectTimeRange(\n uint256 validationData,\n uint256 paymasterValidationData\n) pure returns (ValidationData memory) {\n ValidationData memory accountValidationData = _parseValidationData(\n validationData\n );\n ValidationData memory pmValidationData = _parseValidationData(\n paymasterValidationData\n );\n address aggregator = accountValidationData.aggregator;\n if (aggregator == address(0)) {\n aggregator = pmValidationData.aggregator;\n }\n uint48 validAfter = accountValidationData.validAfter;\n uint48 validUntil = accountValidationData.validUntil;\n uint48 pmValidAfter = pmValidationData.validAfter;\n uint48 pmValidUntil = pmValidationData.validUntil;\n\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\n return ValidationData(aggregator, validAfter, validUntil);\n}\n\n/**\n * helper to pack the return value for validateUserOp\n * @param data - the ValidationData to pack\n */\nfunction _packValidationData(\n ValidationData memory data\n) pure returns (uint256) {\n return\n uint160(data.aggregator) |\n (uint256(data.validUntil) << 160) |\n (uint256(data.validAfter) << (160 + 48));\n}\n\n/**\n * helper to pack the return value for validateUserOp, when not using an aggregator\n * @param sigFailed - true for signature failure, false for success\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\n * @param validAfter first timestamp this UserOperation is valid\n */\nfunction _packValidationData(\n bool sigFailed,\n uint48 validUntil,\n uint48 validAfter\n) pure returns (uint256) {\n return\n (sigFailed ? 1 : 0) |\n (uint256(validUntil) << 160) |\n (uint256(validAfter) << (160 + 48));\n}\n\n/**\n * keccak function over calldata.\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\n */\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\n assembly {\n let mem := mload(0x40)\n let len := data.length\n calldatacopy(mem, data.offset, len)\n ret := keccak256(mem, len)\n }\n}\n" + }, + "contracts/aa-4337/core/NonceManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\nimport \"../interfaces/IEntryPoint.sol\";\n\n/**\n * nonce management functionality\n */\ncontract NonceManager is INonceManager {\n /**\n * The next valid sequence number for a given nonce key.\n */\n mapping(address => mapping(uint192 => uint256)) public nonceSequenceNumber;\n\n function getNonce(\n address sender,\n uint192 key\n ) public view override returns (uint256 nonce) {\n return nonceSequenceNumber[sender][key] | (uint256(key) << 64);\n }\n\n // allow an account to manually increment its own nonce.\n // (mainly so that during construction nonce can be made non-zero,\n // to \"absorb\" the gas cost of first nonce increment to 1st transaction (construction),\n // not to 2nd transaction)\n function incrementNonce(uint192 key) public override {\n nonceSequenceNumber[msg.sender][key]++;\n }\n\n /**\n * validate nonce uniqueness for this account.\n * called just after validateUserOp()\n */\n function _validateAndUpdateNonce(\n address sender,\n uint256 nonce\n ) internal returns (bool) {\n uint192 key = uint192(nonce >> 64);\n uint64 seq = uint64(nonce);\n return nonceSequenceNumber[sender][key]++ == seq;\n }\n}\n" + }, + "contracts/aa-4337/core/SenderCreator.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/**\n * helper contract for EntryPoint, to call userOp.initCode from a \"neutral\" address,\n * which is explicitly not the entryPoint itself.\n */\ncontract SenderCreator {\n /**\n * call the \"initCode\" factory to create and return the sender account address\n * @param initCode the initCode value from a UserOp. contains 20 bytes of factory address, followed by calldata\n * @return sender the returned address of the created account, or zero address on failure.\n */\n function createSender(\n bytes calldata initCode\n ) external returns (address sender) {\n address factory = address(bytes20(initCode[0:20]));\n bytes memory initCallData = initCode[20:];\n bool success;\n /* solhint-disable no-inline-assembly */\n assembly {\n success := call(\n gas(),\n factory,\n 0,\n add(initCallData, 0x20),\n mload(initCallData),\n 0,\n 32\n )\n sender := mload(0)\n }\n if (!success) {\n sender = address(0);\n }\n }\n}\n" + }, + "contracts/aa-4337/core/StakeManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity 0.8.21;\n\nimport \"../interfaces/IStakeManager.sol\";\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable not-rely-on-time */\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by a paymaster.\n */\nabstract contract StakeManager is IStakeManager {\n /// maps paymaster to their deposits and stakes\n mapping(address => DepositInfo) public deposits;\n\n /// @inheritdoc IStakeManager\n function getDepositInfo(\n address account\n ) public view returns (DepositInfo memory info) {\n return deposits[account];\n }\n\n // internal method to return just the stake info\n function _getStakeInfo(\n address addr\n ) internal view returns (StakeInfo memory info) {\n DepositInfo storage depositInfo = deposits[addr];\n info.stake = depositInfo.stake;\n info.unstakeDelaySec = depositInfo.unstakeDelaySec;\n }\n\n /// return the deposit (for gas payment) of the account\n function balanceOf(address account) public view returns (uint256) {\n return deposits[account].deposit;\n }\n\n receive() external payable {\n depositTo(msg.sender);\n }\n\n function _incrementDeposit(address account, uint256 amount) internal {\n DepositInfo storage info = deposits[account];\n uint256 newAmount = info.deposit + amount;\n require(newAmount <= type(uint112).max, \"deposit overflow\");\n info.deposit = uint112(newAmount);\n }\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) public payable {\n _incrementDeposit(account, msg.value);\n DepositInfo storage info = deposits[account];\n emit Deposited(account, info.deposit);\n }\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 unstakeDelaySec) public payable {\n DepositInfo storage info = deposits[msg.sender];\n require(unstakeDelaySec > 0, \"must specify unstake delay\");\n require(\n unstakeDelaySec >= info.unstakeDelaySec,\n \"cannot decrease unstake time\"\n );\n uint256 stake = info.stake + msg.value;\n require(stake > 0, \"no stake specified\");\n require(stake <= type(uint112).max, \"stake overflow\");\n deposits[msg.sender] = DepositInfo(\n info.deposit,\n true,\n uint112(stake),\n unstakeDelaySec,\n 0\n );\n emit StakeLocked(msg.sender, stake, unstakeDelaySec);\n }\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external {\n DepositInfo storage info = deposits[msg.sender];\n require(info.unstakeDelaySec != 0, \"not staked\");\n require(info.staked, \"already unstaking\");\n uint48 withdrawTime = uint48(block.timestamp) + info.unstakeDelaySec;\n info.withdrawTime = withdrawTime;\n info.staked = false;\n emit StakeUnlocked(msg.sender, withdrawTime);\n }\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external {\n DepositInfo storage info = deposits[msg.sender];\n uint256 stake = info.stake;\n require(stake > 0, \"No stake to withdraw\");\n require(info.withdrawTime > 0, \"must call unlockStake() first\");\n require(\n info.withdrawTime <= block.timestamp,\n \"Stake withdrawal is not due\"\n );\n info.unstakeDelaySec = 0;\n info.withdrawTime = 0;\n info.stake = 0;\n emit StakeWithdrawn(msg.sender, withdrawAddress, stake);\n (bool success, ) = withdrawAddress.call{value: stake}(\"\");\n require(success, \"failed to withdraw stake\");\n }\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(\n address payable withdrawAddress,\n uint256 withdrawAmount\n ) external {\n DepositInfo storage info = deposits[msg.sender];\n require(withdrawAmount <= info.deposit, \"Withdraw amount too large\");\n info.deposit = uint112(info.deposit - withdrawAmount);\n emit Withdrawn(msg.sender, withdrawAddress, withdrawAmount);\n (bool success, ) = withdrawAddress.call{value: withdrawAmount}(\"\");\n require(success, \"failed to withdraw\");\n }\n}\n" + }, + "contracts/aa-4337/interfaces/IAccount.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\ninterface IAccount {\n /**\n * Validate user's signature and nonce\n * the entryPoint will make the call to the recipient only if this validation call returns successfully.\n * signature failure should be reported by returning SIG_VALIDATION_FAILED (1).\n * This allows making a \"simulation call\" without a valid signature\n * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure.\n *\n * @dev Must validate caller is the entryPoint.\n * Must validate the signature and nonce\n * @param userOp the operation that is about to be executed.\n * @param userOpHash hash of the user's request data. can be used as the basis for signature.\n * @param missingAccountFunds missing funds on the account's deposit in the entrypoint.\n * This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call.\n * The excess is left as a deposit in the entrypoint, for future calls.\n * can be withdrawn anytime using \"entryPoint.withdrawTo()\"\n * In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero.\n * @return validationData packaged ValidationData structure. use `_packValidationData` and `_unpackValidationData` to encode and decode\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * If an account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validateUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 missingAccountFunds\n ) external returns (uint256 validationData);\n}\n" + }, + "contracts/aa-4337/interfaces/IAggregator.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * Aggregated Signatures validator.\n */\ninterface IAggregator {\n /**\n * validate aggregated signature.\n * revert if the aggregated signature does not match the given list of operations.\n */\n function validateSignatures(\n UserOperation[] calldata userOps,\n bytes calldata signature\n ) external view;\n\n /**\n * validate signature of a single userOp\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\n * @param userOp the userOperation received from the user.\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\n * (usually empty, unless account and aggregator support some kind of \"multisig\"\n */\n function validateUserOpSignature(\n UserOperation calldata userOp\n ) external view returns (bytes memory sigForUserOp);\n\n /**\n * aggregate multiple signatures into a single value.\n * This method is called off-chain to calculate the signature to pass with handleOps()\n * bundler MAY use optimized custom code perform this aggregation\n * @param userOps array of UserOperations to collect the signatures from.\n * @return aggregatedSignature the aggregated signature\n */\n function aggregateSignatures(\n UserOperation[] calldata userOps\n ) external view returns (bytes memory aggregatedSignature);\n}\n" + }, + "contracts/aa-4337/interfaces/IEntryPoint.sol": { + "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n/* solhint-disable reason-string */\n\nimport \"./UserOperation.sol\";\nimport \"./IStakeManager.sol\";\nimport \"./IAggregator.sol\";\nimport \"./INonceManager.sol\";\n\ninterface IEntryPoint is IStakeManager, INonceManager {\n /***\n * An event emitted after each successful request\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\n * @param sender - the account that generates this request.\n * @param paymaster - if non-null, the paymaster that pays for this request.\n * @param nonce - the nonce value from the request.\n * @param success - true if the sender transaction succeeded, false if reverted.\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\n */\n event UserOperationEvent(\n bytes32 indexed userOpHash,\n address indexed sender,\n address indexed paymaster,\n uint256 nonce,\n bool success,\n uint256 actualGasCost,\n uint256 actualGasUsed\n );\n\n /**\n * account \"sender\" was deployed.\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\n * @param sender the account that is deployed\n * @param factory the factory used to deploy this account (in the initCode)\n * @param paymaster the paymaster used by this UserOp\n */\n event AccountDeployed(\n bytes32 indexed userOpHash,\n address indexed sender,\n address factory,\n address paymaster\n );\n\n /**\n * An event emitted if the UserOperation \"callData\" reverted with non-zero length\n * @param userOpHash the request unique identifier.\n * @param sender the sender of this request\n * @param nonce the nonce used in the request\n * @param revertReason - the return bytes from the (reverted) call to \"callData\".\n */\n event UserOperationRevertReason(\n bytes32 indexed userOpHash,\n address indexed sender,\n uint256 nonce,\n bytes revertReason\n );\n\n /**\n * an event emitted by handleOps(), before starting the execution loop.\n * any event emitted before this event, is part of the validation.\n */\n event BeforeExecution();\n\n /**\n * signature aggregator used by the following UserOperationEvents within this bundle.\n */\n event SignatureAggregatorChanged(address indexed aggregator);\n\n /**\n * a custom revert error of handleOps, to identify the offending op.\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\n * @param reason - revert reason\n * The string starts with a unique code \"AAmn\", where \"m\" is \"1\" for factory, \"2\" for account and \"3\" for paymaster issues,\n * so a failure can be attributed to the correct entity.\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\n */\n error FailedOp(uint256 opIndex, string reason);\n\n /**\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\n */\n error SignatureValidationFailed(address aggregator);\n\n /**\n * Successful result from simulateValidation.\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n */\n error ValidationResult(\n ReturnInfo returnInfo,\n StakeInfo senderInfo,\n StakeInfo factoryInfo,\n StakeInfo paymasterInfo\n );\n\n /**\n * Successful result from simulateValidation, if the account returns a signature aggregator\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\n * bundler MUST use it to verify the signature, or reject the UserOperation\n */\n error ValidationResultWithAggregation(\n ReturnInfo returnInfo,\n StakeInfo senderInfo,\n StakeInfo factoryInfo,\n StakeInfo paymasterInfo,\n AggregatorStakeInfo aggregatorInfo\n );\n\n /**\n * return value of getSenderAddress\n */\n error SenderAddressResult(address sender);\n\n /**\n * return value of simulateHandleOp\n */\n error ExecutionResult(\n uint256 preOpGas,\n uint256 paid,\n uint48 validAfter,\n uint48 validUntil,\n bool targetSuccess,\n bytes targetResult\n );\n\n //UserOps handled, per aggregator\n struct UserOpsPerAggregator {\n UserOperation[] userOps;\n // aggregator address\n IAggregator aggregator;\n // aggregated signature\n bytes signature;\n }\n\n /**\n * Execute a batch of UserOperation.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(\n UserOperation[] calldata ops,\n address payable beneficiary\n ) external;\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) external;\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(\n UserOperation calldata userOp\n ) external view returns (bytes32);\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external;\n\n /**\n * gas and return values during simulation\n * @param preOpGas the gas used for validation (including preValidationGas)\n * @param prefund the required prefund for this operation\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\n */\n struct ReturnInfo {\n uint256 preOpGas;\n uint256 prefund;\n bool sigFailed;\n uint48 validAfter;\n uint48 validUntil;\n bytes paymasterContext;\n }\n\n /**\n * returned aggregated signature info.\n * the aggregator returned by the account, and its current stake.\n */\n struct AggregatorStakeInfo {\n address aggregator;\n StakeInfo stakeInfo;\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes memory initCode) external;\n\n /**\n * simulate full execution of a UserOperation (including both validation and target execution)\n * this method will always revert with \"ExecutionResult\".\n * it performs full validation of the UserOperation, but ignores signature error.\n * an optional target address is called after the userop succeeds, and its value is returned\n * (before the entire call is reverted)\n * Note that in order to collect the the success/failure of the target call, it must be executed\n * with trace enabled to track the emitted events.\n * @param op the UserOperation to simulate\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\n * are set to the return from that call.\n * @param targetCallData callData to pass to target address\n */\n function simulateHandleOp(\n UserOperation calldata op,\n address target,\n bytes calldata targetCallData\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/INonceManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\ninterface INonceManager {\n /**\n * Return the next nonce for this sender.\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\n * But UserOp with different keys can come with arbitrary order.\n *\n * @param sender the account address\n * @param key the high 192 bit of the nonce\n * @return nonce a full nonce to pass for next UserOp with this sender.\n */\n function getNonce(\n address sender,\n uint192 key\n ) external view returns (uint256 nonce);\n\n /**\n * Manually increment the nonce of the sender.\n * This method is exposed just for completeness..\n * Account does NOT need to call it, neither during validation, nor elsewhere,\n * as the EntryPoint will update the nonce regardless.\n * Possible use-case is call it with various keys to \"initialize\" their nonces to one, so that future\n * UserOperations will not pay extra for the first transaction with a given key.\n */\n function incrementNonce(uint192 key) external;\n}\n" + }, + "contracts/aa-4337/interfaces/IPaymaster.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * the interface exposed by a paymaster contract, who agrees to pay the gas for user's operations.\n * a paymaster must hold a stake to cover the required entrypoint stake and also the gas for the transaction.\n */\ninterface IPaymaster {\n enum PostOpMode {\n opSucceeded, // user op succeeded\n opReverted, // user op reverted. still has to pay for gas.\n postOpReverted //user op succeeded, but caused postOp to revert. Now it's a 2nd call, after user's op was deliberately reverted.\n }\n\n /**\n * payment validation: check if paymaster agrees to pay.\n * Must verify sender is the entryPoint.\n * Revert to reject this request.\n * Note that bundlers will reject this method if it changes the state, unless the paymaster is trusted (whitelisted)\n * The paymaster pre-pays using its deposit, and receive back a refund after the postOp method returns.\n * @param userOp the user operation\n * @param userOpHash hash of the user's request data.\n * @param maxCost the maximum cost of this transaction (based on maximum gas and gas price from userOp)\n * @return context value to send to a postOp\n * zero length to signify postOp is not required.\n * @return validationData signature and time-range of this operation, encoded the same as the return value of validateUserOperation\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validatePaymasterUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 maxCost\n ) external returns (bytes memory context, uint256 validationData);\n\n /**\n * post-operation handler.\n * Must verify sender is the entryPoint\n * @param mode enum with the following options:\n * opSucceeded - user operation succeeded.\n * opReverted - user op reverted. still has to pay for gas.\n * postOpReverted - user op succeeded, but caused postOp (in mode=opSucceeded) to revert.\n * Now this is the 2nd call, after user's op was deliberately reverted.\n * @param context - the context value returned by validatePaymasterUserOp\n * @param actualGasCost - actual gas used so far (without this postOp call).\n */\n function postOp(\n PostOpMode mode,\n bytes calldata context,\n uint256 actualGasCost\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/IStakeManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.12;\n\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by the staked entity.\n */\ninterface IStakeManager {\n event Deposited(address indexed account, uint256 totalDeposit);\n\n event Withdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /// Emitted when stake or unstake delay are modified\n event StakeLocked(\n address indexed account,\n uint256 totalStaked,\n uint256 unstakeDelaySec\n );\n\n /// Emitted once a stake is scheduled for withdrawal\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\n\n event StakeWithdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /**\n * @param deposit the entity's deposit\n * @param staked true if this entity is staked.\n * @param stake actual amount of ether staked for this entity.\n * @param unstakeDelaySec minimum delay to withdraw the stake.\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\n * and the rest fit into a 2nd cell.\n * 112 bit allows for 10^15 eth\n * 48 bit for full timestamp\n * 32 bit allows 150 years for unstake delay\n */\n struct DepositInfo {\n uint112 deposit;\n bool staked;\n uint112 stake;\n uint32 unstakeDelaySec;\n uint48 withdrawTime;\n }\n\n //API struct used by getStakeInfo and simulateValidation\n struct StakeInfo {\n uint256 stake;\n uint256 unstakeDelaySec;\n }\n\n /// @return info - full deposit information of given account\n function getDepositInfo(\n address account\n ) external view returns (DepositInfo memory info);\n\n /// @return the deposit (for gas payment) of the account\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) external payable;\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 _unstakeDelaySec) external payable;\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external;\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external;\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(\n address payable withdrawAddress,\n uint256 withdrawAmount\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/UserOperation.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable no-inline-assembly */\n\nimport {calldataKeccak} from \"../core/Helpers.sol\";\n\n/**\n * User Operation struct\n * @param sender the sender account of this request.\n * @param nonce unique value the sender uses to verify it is not a replay.\n * @param initCode if set, the account contract will be created by this constructor/\n * @param callData the method call to execute on this account.\n * @param callGasLimit the gas limit passed to the callData method call.\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\n * @param maxFeePerGas same as EIP-1559 gas parameter.\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\n */\nstruct UserOperation {\n address sender;\n uint256 nonce;\n bytes initCode;\n bytes callData;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n bytes paymasterAndData;\n bytes signature;\n}\n\n/**\n * Utility functions helpful when working with UserOperation structs.\n */\nlibrary UserOperationLib {\n function getSender(\n UserOperation calldata userOp\n ) internal pure returns (address) {\n address data;\n //read sender from userOp, which is first userOp member (saves 800 gas...)\n assembly {\n data := calldataload(userOp)\n }\n return address(uint160(data));\n }\n\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\n // pay above what he signed for.\n function gasPrice(\n UserOperation calldata userOp\n ) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function pack(\n UserOperation calldata userOp\n ) internal pure returns (bytes memory ret) {\n address sender = getSender(userOp);\n uint256 nonce = userOp.nonce;\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\n bytes32 hashCallData = calldataKeccak(userOp.callData);\n uint256 callGasLimit = userOp.callGasLimit;\n uint256 verificationGasLimit = userOp.verificationGasLimit;\n uint256 preVerificationGas = userOp.preVerificationGas;\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\n\n return\n abi.encode(\n sender,\n nonce,\n hashInitCode,\n hashCallData,\n callGasLimit,\n verificationGasLimit,\n preVerificationGas,\n maxFeePerGas,\n maxPriorityFeePerGas,\n hashPaymasterAndData\n );\n }\n\n function hash(\n UserOperation calldata userOp\n ) internal pure returns (bytes32) {\n return keccak256(pack(userOp));\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n}\n" + }, + "contracts/aa-4337/utils/Exec.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.5 <0.9.0;\n\n// solhint-disable no-inline-assembly\n\n/**\n * Utility functions helpful when making different kinds of contract calls in Solidity.\n */\nlibrary Exec {\n function call(\n address to,\n uint256 value,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := call(\n txGas,\n to,\n value,\n add(data, 0x20),\n mload(data),\n 0,\n 0\n )\n }\n }\n\n function staticcall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal view returns (bool success) {\n assembly {\n success := staticcall(txGas, to, add(data, 0x20), mload(data), 0, 0)\n }\n }\n\n function delegateCall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := delegatecall(\n txGas,\n to,\n add(data, 0x20),\n mload(data),\n 0,\n 0\n )\n }\n }\n\n // get returned data from last call or calldelegate\n function getReturnData(\n uint256 maxLen\n ) internal pure returns (bytes memory returnData) {\n assembly {\n let len := returndatasize()\n if gt(len, maxLen) {\n len := maxLen\n }\n let ptr := mload(0x40)\n mstore(0x40, add(ptr, add(len, 0x20)))\n mstore(ptr, len)\n returndatacopy(add(ptr, 0x20), 0, len)\n returnData := ptr\n }\n }\n\n // revert with explicit byte array (probably reverted info from call)\n function revertWithData(bytes memory returnData) internal pure {\n assembly {\n revert(add(returnData, 32), mload(returnData))\n }\n }\n\n function callAndRevert(\n address to,\n bytes memory data,\n uint256 maxLen\n ) internal {\n bool success = call(to, 0, data, gasleft());\n if (!success) {\n revertWithData(getReturnData(maxLen));\n }\n }\n}\n" + }, + "contracts/Barz.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"./libraries/LibDiamond.sol\";\nimport {IBarz} from \"./interfaces/IBarz.sol\";\n\n/**\n * @title Barz\n * @dev A diamond proxy wallet with a modular & upgradeable architecture\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract Barz is IBarz {\n /**\n * @notice Initializes Barz with the given parameters. Barz account is intended to be created from Barz Factory for stable deployment.\n * @dev This method makes a delegate call to account facet and account facet handles the initialization.\n * With modular architecture, Barz encompasses wide spectrum of architecture and logic.\n * The only requirement is account facet to comply with initialize() interface.\n * Barz doesn't include built-in functions and is a full proxy, for maximum extensibility and modularity.\n * @param _accountFacet Address of Account Facet in charge of the Barz initialization\n * @param _verificationFacet Address of Verification Facet for verifying the signature. Could be any signature scheme\n * @param _entryPoint Address of Entry Point contract\n * @param _facetRegistry Address of Facet Registry. Facet Registry is a registry holding trusted facets that could be added to user's wallet\n * @param _defaultFallBack Address of Default FallBack Handler. Middleware contract for more efficient deployment\n * @param _ownerPublicKey Bytes of Owner Public Key using for initialization\n */\n constructor(\n address _accountFacet,\n address _verificationFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallBack,\n bytes memory _ownerPublicKey\n ) payable {\n bytes memory initCall = abi.encodeWithSignature(\n \"initialize(address,address,address,address,bytes)\",\n _verificationFacet,\n _entryPoint,\n _facetRegistry,\n _defaultFallBack,\n _ownerPublicKey\n );\n (bool success, bytes memory result) = _accountFacet.delegatecall(\n initCall\n );\n if (!success || uint256(bytes32(result)) != 1) {\n revert Barz__InitializationFailure();\n }\n }\n\n /**\n * @notice Fallback function for Barz complying with Diamond Standard with customization of adding Default Fallback Handler\n * @dev Find facet for function that is called and execute the function if a facet is found and return any value.\n */\n fallback() external payable {\n LibDiamond.DiamondStorage storage ds;\n bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION;\n // get diamond storage\n assembly {\n ds.slot := position\n }\n // get facet from function selector\n address facet = address(bytes20(ds.facets[msg.sig]));\n if (facet == address(0))\n facet = ds.defaultFallbackHandler.facetAddress(msg.sig);\n require(facet != address(0), \"Barz: Function does not exist\");\n // Execute external function from facet using delegatecall and return any value.\n assembly {\n // copy function selector and any arguments\n calldatacopy(0, 0, calldatasize())\n // execute function call using the facet\n let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)\n // get any return value\n returndatacopy(0, 0, returndatasize())\n // return any return value or error back to the caller\n switch result\n case 0 {\n revert(0, returndatasize())\n }\n default {\n return(0, returndatasize())\n }\n }\n }\n\n /**\n * @notice Receive function to receive native token without data\n */\n receive() external payable {}\n}\n" + }, + "contracts/BarzFactory.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Barz} from \"./Barz.sol\";\nimport {IBarzFactory} from \"./interfaces/IBarzFactory.sol\";\n\n/**\n * @title Barz Factory\n * @dev Contract to easily deploy Barz to a pre-computed address with a single call\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract BarzFactory is IBarzFactory {\n address public immutable accountFacet;\n address public immutable entryPoint;\n address public immutable facetRegistry;\n address public immutable defaultFallback;\n\n /**\n * @notice Sets the initialization data for Barz contract initialization\n * @param _accountFacet Account Facet to be used to create Barz\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\n * @param _facetRegistry Facet Registry to be used to create Barz\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\n */\n constructor(\n address _accountFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallback\n ) {\n accountFacet = _accountFacet;\n entryPoint = _entryPoint;\n facetRegistry = _facetRegistry;\n defaultFallback = _defaultFallback;\n }\n\n /**\n * @notice Creates the Barz with a single call. It creates the Barz contract with the givent verification facet\n * @param _verificationFacet Address of verification facet used for creating the barz account\n * @param _owner Public Key of the owner to initialize barz account\n * @param _salt Salt used for deploying barz with create2\n * @return barz Instance of Barz contract deployed with the given parameters\n */\n function createAccount(\n address _verificationFacet,\n bytes calldata _owner,\n uint256 _salt\n ) external override returns (Barz barz) {\n address addr = getAddress(_verificationFacet, _owner, _salt);\n uint codeSize = addr.code.length;\n if (codeSize > 0) {\n return Barz(payable(addr));\n }\n barz = new Barz{salt: bytes32(_salt)}(\n accountFacet,\n _verificationFacet,\n entryPoint,\n facetRegistry,\n defaultFallback,\n _owner\n );\n emit BarzDeployed(address(barz));\n }\n\n /**\n * @notice Calculates the address of Barz with the given parameters\n * @param _verificationFacet Address of verification facet used for creating the barz account\n * @param _owner Public Key of the owner to initialize barz account\n * @param _salt Salt used for deploying barz with create2\n * @return barzAddress Precalculated Barz address\n */\n function getAddress(\n address _verificationFacet,\n bytes calldata _owner,\n uint256 _salt\n ) public view override returns (address barzAddress) {\n bytes memory bytecode = getBytecode(\n accountFacet,\n _verificationFacet,\n entryPoint,\n facetRegistry,\n defaultFallback,\n _owner\n );\n bytes32 hash = keccak256(\n abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(bytecode)\n )\n );\n barzAddress = address(uint160(uint256(hash)));\n }\n\n /**\n * @notice Returns the bytecode of Barz with the given parameter\n * @param _accountFacet Account Facet to be used to create Barz\n * @param _verificationFacet Verification Facet to be used to create Barz\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\n * @param _facetRegistry Facet Registry to be used to create Barz\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\n * @param _ownerPublicKey Public Key of owner to be used to initialize Barz ownership\n * @return barzBytecode Bytecode of Barz\n */\n function getBytecode(\n address _accountFacet,\n address _verificationFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallback,\n bytes calldata _ownerPublicKey\n ) public pure override returns (bytes memory barzBytecode) {\n bytes memory bytecode = type(Barz).creationCode;\n barzBytecode = abi.encodePacked(\n bytecode,\n abi.encode(\n _accountFacet,\n _verificationFacet,\n _entryPoint,\n _facetRegistry,\n _defaultFallback,\n _ownerPublicKey\n )\n );\n }\n\n /**\n * @notice Returns the creation code of the Barz contract\n * @return creationCode Creation code of Barz\n */\n function getCreationCode()\n public\n pure\n override\n returns (bytes memory creationCode)\n {\n creationCode = type(Barz).creationCode;\n }\n}\n" + }, + "contracts/facets/AccountFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {UserOperation} from \"../aa-4337/interfaces/UserOperation.sol\";\nimport {IEntryPoint} from \"../aa-4337/interfaces/IEntryPoint.sol\";\nimport {BaseAccount} from \"../aa-4337/core/BaseAccount.sol\";\nimport {LibAppStorage, BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {IFacetRegistry} from \"../infrastructure/interfaces/IFacetRegistry.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {IERC1271} from \"../interfaces/ERC/IERC1271.sol\";\nimport {IAccountFacet} from \"./interfaces/IAccountFacet.sol\";\n\n/**\n * @title Account Facet\n * @dev Account module contract that provides the account features and initialization of signer\n * compatible with EIP-1271 & EIP-4337\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract AccountFacet is IAccountFacet, BarzStorage, BaseAccount {\n using ECDSA for bytes32;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceAccountInitialize();\n }\n\n /**\n * @notice Returns the address of EntryPoint contract registered to Barz account\n */\n function entryPoint() public view override returns (IEntryPoint) {\n return s.entryPoint;\n }\n\n /**\n * @notice Initializes the initial storage of the Barz contract.\n * @dev This method can only be called during the initialization or signature migration.\n * If the proxy contract was created without initialization, anyone can call initialize.\n * Barz calls initialize in constructor in an atomic transaction during deployment\n * @param _verificationFacet Facet contract handling the verificationi\n * @param _anEntryPoint Entrypoint contract defined in EIP-4337 handling the flow of UserOp\n * @param _facetRegistry Registry of Facets that hold all facet information\n * @param _defaultFallBackHandler Middleware contract for default facets\n * @param _ownerPublicKey Bytes of owner public key\n */\n function initialize(\n address _verificationFacet,\n address _anEntryPoint,\n address _facetRegistry,\n address _defaultFallBackHandler,\n bytes calldata _ownerPublicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceAccountInitialize();\n s.entryPoint = IEntryPoint(_anEntryPoint);\n s.facetRegistry = IFacetRegistry(_facetRegistry);\n LibDiamond.diamondStorage().defaultFallbackHandler = IDiamondLoupe(\n _defaultFallBackHandler\n );\n\n _cutDiamondAccountFacet(_verificationFacet);\n\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n _ownerPublicKey\n );\n // Every Verification Facet should comply with initializeSigner(bytes)\n // to be compatible with the Barz contract(for initialization)\n (bool success, bytes memory result) = _verificationFacet.delegatecall(\n initCall\n );\n if (!success || uint256(bytes32(result)) != 1) {\n revert AccountFacet__InitializationFailure();\n }\n\n initSuccess = 1;\n emit AccountInitialized(s.entryPoint, _ownerPublicKey);\n }\n\n function _cutDiamondAccountFacet(address _verificationFacet) internal {\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](1);\n\n bytes4 ownerVerificationFuncSelector = IVerificationFacet(\n _verificationFacet\n ).validateOwnerSignatureSelector();\n\n bytes4[] memory verificationFunctionSelectors = new bytes4[](3);\n verificationFunctionSelectors[0] = IERC1271.isValidSignature.selector;\n verificationFunctionSelectors[1] = ownerVerificationFuncSelector;\n verificationFunctionSelectors[2] = IVerificationFacet.owner.selector;\n cut[0] = IDiamondCut.FacetCut({\n facetAddress: _verificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: verificationFunctionSelectors\n });\n\n LibDiamond.diamondCut(cut, address(0), \"\");\n }\n\n /**\n * @notice Calls the destination with inputted calldata and value from EntryPoint\n * @dev This method executes the calldata coming from the EntryPoint.\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\n * @param _dest Address of destination where the call will be forwarded to\n * @param _value Amount of native coin the owner is willing to send(e.g. ETH, BNB)\n * @param _func Bytes of calldata to execute in the destination address\n */\n function execute(\n address _dest,\n uint256 _value,\n bytes calldata _func\n ) external override onlyWhenUnlocked {\n _requireFromEntryPoint();\n address restrictionsFacet = LibDiamond.restrictionsFacet();\n if (restrictionsFacet == address(0)) _call(_dest, _value, _func);\n else _callWithRestrictions(_dest, _value, _func, restrictionsFacet);\n }\n\n /**\n * @notice Batch calls the destination with inputted calldata and value from EntryPoint\n * @dev This method batch executes the calldata coming from the EntryPoint.\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\n * @param _dest Array of addresses of destination where the call will be forwarded to\n * @param _value Array of amount of native coin the owner is willing to send(e.g. ETH, BNB)\n * @param _func Array of bytes of calldata to execute in the destination address\n */\n function executeBatch(\n address[] calldata _dest,\n uint256[] calldata _value,\n bytes[] calldata _func\n ) external override onlyWhenUnlocked {\n _requireFromEntryPoint();\n if (_dest.length != _func.length || _dest.length != _value.length)\n revert AccountFacet__InvalidArrayLength();\n address restrictionsFacet = LibDiamond.restrictionsFacet();\n if (restrictionsFacet == address(0)) {\n for (uint256 i; i < _dest.length; ) {\n _call(_dest[i], _value[i], _func[i]);\n unchecked {\n ++i;\n }\n }\n } else {\n for (uint256 i; i < _dest.length; ) {\n _callWithRestrictions(\n _dest[i],\n _value[i],\n _func[i],\n restrictionsFacet\n );\n unchecked {\n ++i;\n }\n }\n }\n }\n\n /**\n * @notice Validates the signature field of UserOperation\n * @dev This method validates if the signature of UserOp is indeed valid by delegating the call to Verification Facet\n * Barz makes a call to the pre-registered Verification Facet address in App Storage\n * @param _userOp UserOperation from owner to be validated\n * @param _userOpHash Hash of UserOperation given from the EntryPoint contract\n */\n function _validateSignature(\n UserOperation calldata _userOp,\n bytes32 _userOpHash\n ) internal override returns (uint256 validationData) {\n // Get Facet with Function Selector\n address facet = LibLoupe.facetAddress(s.validateOwnerSignatureSelector);\n if (facet == address(0))\n revert AccountFacet__NonExistentVerificationFacet();\n\n // Make function call to VerificationFacet\n bytes memory validateCall = abi.encodeWithSelector(\n s.validateOwnerSignatureSelector,\n _userOp,\n _userOpHash\n );\n (bool success, bytes memory result) = facet.delegatecall(validateCall);\n if (!success) revert AccountFacet__CallNotSuccessful();\n validationData = uint256(bytes32(result));\n if (validationData == 0) emit VerificationSuccess(_userOpHash);\n else emit VerificationFailure(_userOpHash);\n }\n\n /**\n * @notice Calls the target with the inputted value and calldata\n * @dev This method is the actual function in Barz that makes a call with an arbitrary owner-given data\n * @param _target Address of the destination contract which the call is getting forwarded to\n * @param _value Amount of Native coin the owner is wanting to make in this call\n * @param _data Calldata the owner is forwarding together in the call e.g. Swap/Token Transfer\n */\n function _call(\n address _target,\n uint256 _value,\n bytes memory _data\n ) internal {\n (bool success, bytes memory result) = _target.call{value: _value}(\n _data\n );\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n }\n\n /**\n * @notice Calls the target with the inputted value and calldata together with restrictions check\n * @dev This method is the actual function in Barz that makes a call with an arbitrary owner-given data\n * @param _target Address of the destination contract which the call is getting forwarded to\n * @param _value Amount of Native coin the owner is wanting to make in this call\n * @param _data Calldata the owner is forwarding together in the call e.g. Swap/Token Transfer\n * @param _restrictionsFacet Address of Facet to validate restrictions\n */\n function _callWithRestrictions(\n address _target,\n uint256 _value,\n bytes memory _data,\n address _restrictionsFacet\n ) internal {\n // NOTE: No restrictions facet, so restriction validation passes\n if (_checkRestrictions(_restrictionsFacet, _target, _value, _data) != 0)\n revert AccountFacet__RestrictionsFailure();\n\n (bool success, bytes memory result) = _target.call{value: _value}(\n _data\n );\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n }\n\n /**\n * @notice Checks restrictions if the restrictions facet exists\n * @dev This method checks if the restrictions facet exists and makes a verification call to an array of restrictions facet\n * @param _facet Address that holds the restrictions logic\n * @param _target Address the call is getting forwarded to\n * @param _value Amount of native coin the call is sending together with the call\n * @param _data Calldata to trigger execution in target address\n */\n function _checkRestrictions(\n address _facet,\n address _target,\n uint256 _value,\n bytes memory _data\n ) internal returns (uint256 result) {\n bytes memory call = abi.encodeWithSignature(\n \"verifyRestrictions(address,address,uint256,bytes)\",\n address(this),\n _target,\n _value,\n _data\n );\n (bool success, bytes memory response) = _facet.delegatecall(call);\n if (!success) revert AccountFacet__RestrictionsFailure();\n result = uint256(bytes32(response));\n }\n}\n" + }, + "contracts/facets/AccountRecoveryFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibFacetStorage, RecoveryStorage, RecoveryConfig, RecoveryApprovalConfig, ApprovalConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {IAccountRecoveryFacet} from \"./interfaces/IAccountRecoveryFacet.sol\";\n\n/**\n * @title Account Recovery Facet\n * @dev Contract that enables recovery of accounts when owner key is unavailable\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract AccountRecoveryFacet is IAccountRecoveryFacet, Modifiers {\n bytes constant UNINIT_CALL =\n abi.encodeWithSignature(\"uninitializeSigner()\");\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Approve recovery of account as guardian\n * @dev This method can only be called by guardian and guardian inputs the public key of the new owner\n * When the threshold(majority of guardians) passes, it automatically executes account recovery\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function approveAccountRecovery(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + _getApprovalValidationPeriod()\n );\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit RecoveryApproved(\n _recoveryPublicKey,\n msg.sender,\n approvalValidUntil\n );\n if (\n getRecoveryApprovalCountWithTimeValidity(recoveryPublicKeyHash) >=\n LibGuardian.majorityOfGuardians()\n ) _executeRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Revoke recovery of account as guardian\n * @dev This method can only be called by guardian and guardian inputs the public key of the new owner\n When the threshold(majority of guardians) passes, it automatically revokes account recovery when recovery is pending\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function revokeAccountRecoveryApproval(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n if (\n !rs\n .isNewOwnerApproved[recoveryPublicKeyHash][msg.sender].isApproved ||\n !(block.timestamp <\n rs\n .isNewOwnerApproved[recoveryPublicKeyHash][msg.sender]\n .validUntil)\n ) revert AccountRecoveryFacet__NonExistentApproval();\n\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(false, 0);\n emit RecoveryApprovalRevoked(_recoveryPublicKey, msg.sender);\n }\n\n /**\n * @notice Executes recovery with signatures or on-chain pre-approvals\n * @dev This method validates the signatures of guardians or checks the on-chain pre-approved calls to check if the threshold passes\n * When the threshold passes, account recovery is executed and revert otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _guardians Array of guardians address that are approving the recovery of Account\n * @param _signatures Array of signature bytes that signed the approval hash\n */\n function executeRecovery(\n bytes calldata _recoveryPublicKey,\n address[] calldata _guardians,\n bytes[] calldata _signatures\n ) external override {\n if (_isRecoveryPending())\n revert AccountRecoveryFacet__RecoveryAlreadyOngoing();\n if (_guardians.length != _signatures.length)\n revert AccountRecoveryFacet__InvalidArrayLength();\n validateNewOwner(_recoveryPublicKey);\n\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n\n _checkApprover(_guardians);\n _checkDuplicateOnChainApprover(recoveryPublicKeyHash, _guardians);\n\n if (\n _guardians.length +\n getRecoveryApprovalCountWithTimeValidity(\n recoveryPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians()\n ) revert AccountRecoveryFacet__InsufficientGuardians();\n for (uint256 i; i < _guardians.length; ) {\n if (!LibGuardian.isGuardian(_guardians[i]))\n revert AccountRecoveryFacet__InvalidGuardian();\n if (\n !SignatureChecker.isValidSignatureNow(\n _guardians[i],\n recoveryPublicKeyHash,\n _signatures[i]\n )\n ) revert AccountRecoveryFacet__InvalidGuardianSignature();\n unchecked {\n ++i;\n }\n }\n _executeRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Executes recovery of the account. Note that execution and finalization is a different process\n * @dev Executes the recovery and adds recovery data to recovery configuration. Locks the account\n * @param _recoveryPublicKey Public Key of the account for recovery\n */\n function _executeRecovery(bytes memory _recoveryPublicKey) internal {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n unchecked {\n ++rs.nonce;\n }\n uint64 executeAfter = uint64(block.timestamp + _getRecoveryPeriod());\n rs.recoveryConfigs[INNER_STRUCT] = RecoveryConfig(\n _recoveryPublicKey,\n executeAfter // NOTE: Remove guardian Count\n );\n LibAppStorage.setLock(\n block.timestamp + _getLockPeriod(),\n AccountRecoveryFacet.executeRecovery.selector\n );\n emit RecoveryExecuted(_recoveryPublicKey, executeAfter);\n }\n\n /**\n * @notice Finalize recovery after recovery pending period. Recovery pending period can be set by user beforehand in SecurityManager\n * @dev This method finalizes recovery and fully changes the ownership of the account to the newly inputted recovery public key\n */\n function finalizeRecovery() external override {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n if (\n uint64(block.timestamp) <=\n rs.recoveryConfigs[INNER_STRUCT].executeAfter\n ) revert AccountRecoveryFacet__RecoveryPeriodNotOver();\n bytes memory recoveryOwner = rs\n .recoveryConfigs[INNER_STRUCT]\n .recoveryPublicKey;\n\n delete rs.recoveryConfigs[INNER_STRUCT];\n\n LibAppStorage.setLock(0, bytes4(0));\n\n LibAppStorage.initiateSignerMigration();\n address verificationFacet = address(\n bytes20(\n LibDiamond.diamondStorage().facets[\n s.validateOwnerSignatureSelector\n ]\n )\n );\n (bool uninitSuccess, bytes memory uninitResult) = verificationFacet\n .delegatecall(UNINIT_CALL);\n if (!uninitSuccess) revert AccountRecoveryFacet__CallNotSuccesful();\n if (uint256(bytes32(uninitResult)) != 1)\n revert AccountRecoveryFacet__SignerUninitializationFailure();\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n recoveryOwner\n );\n (bool initSuccess, bytes memory initResult) = verificationFacet\n .delegatecall(initCall);\n if (!initSuccess) revert AccountRecoveryFacet__CallNotSuccesful();\n if (uint256(bytes32(initResult)) != 1)\n revert AccountRecoveryFacet__SignerInitializationFailure();\n LibAppStorage.finalizeSignerMigration();\n emit RecoveryFinalized(recoveryOwner);\n }\n\n /**\n * @notice Approves the cancellation of recovery\n * @dev This method approves the cancellation of recovery when recovery is still pending - waiting for finalization\n * @param _recoveryPublicKey Bytes of public key which is pending for recovery\n */\n function approveCancelRecovery(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"CancelRecovery\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + _getApprovalValidationPeriod()\n );\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit RecoveryCancellationApproved(_recoveryPublicKey, msg.sender);\n if (\n getRecoveryApprovalCountWithTimeValidity(recoveryPublicKeyHash) >=\n LibGuardian.majorityOfGuardians()\n ) {\n _cancelRecovery(_recoveryPublicKey);\n }\n }\n\n /**\n * @notice Hardstops an ongoing recovery\n * @dev This method provides a safety mechanism to protect owners of malicious guardians.\n * Owners can hardstop recovery when an malicious guardians starts the recovery process.\n * @param _signature Signature of the owner that signs the hash to hardstop recovery\n */\n function hardstopRecovery(bytes calldata _signature) external override {\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n \"0\",\n \"HardstopRecovery\"\n );\n if (\n !SignatureChecker.isValidSignatureNow(\n address(this),\n recoveryPublicKeyHash,\n _signature\n )\n ) revert AccountRecoveryFacet__InvalidOwnerSignature();\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n unchecked {\n ++rs.nonce;\n }\n delete rs.recoveryConfigs[INNER_STRUCT];\n LibAppStorage.setLock(0, bytes4(0));\n emit RecoveryHardstopped();\n }\n\n /**\n * @notice Cancels recovery with signatures or on-chain pre-approvals\n * @dev This method validates the signatures of guardians or checks the on-chain pre-approved calls to check if the threshold passes\n * When the threshold passes, account recovery is canceled and revert otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _guardians Array of guardians address that are approving the recovery of Account\n * @param _signatures Array of signature bytes that signed the cancellation approval hash\n */\n function cancelRecovery(\n bytes calldata _recoveryPublicKey,\n address[] calldata _guardians,\n bytes[] calldata _signatures\n ) external override {\n if (_guardians.length != _signatures.length)\n revert AccountRecoveryFacet__InvalidArrayLength();\n validateNewOwner(_recoveryPublicKey);\n\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"CancelRecovery\"\n );\n\n _checkApprover(_guardians);\n _checkDuplicateOnChainApprover(recoveryPublicKeyHash, _guardians);\n\n if (\n _guardians.length +\n getRecoveryApprovalCountWithTimeValidity(\n recoveryPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians()\n ) revert AccountRecoveryFacet__InsufficientGuardians();\n for (uint256 i; i < _guardians.length; ) {\n if (!LibGuardian.isGuardian(_guardians[i]))\n revert AccountRecoveryFacet__CallerNotGuardian();\n if (\n !SignatureChecker.isValidSignatureNow(\n _guardians[i],\n recoveryPublicKeyHash,\n _signatures[i]\n )\n ) revert AccountRecoveryFacet__InvalidGuardianSignature();\n unchecked {\n ++i;\n }\n }\n _cancelRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Cancel recovery when the recovery is pending. Unlock the account as well\n * @dev This method checks if the recovery is pending and reverts if not pending.\n * It increases the recovery nonce and deletes the recovery information and gets a small portion of gas in return\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function _cancelRecovery(bytes memory _recoveryPublicKey) internal {\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n LibAppStorage.setLock(0, bytes4(0));\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n unchecked {\n ++rs.nonce;\n }\n delete rs.recoveryConfigs[INNER_STRUCT];\n emit RecoveryCanceled(_recoveryPublicKey);\n }\n\n /**\n * @notice Validates the format of public key to be used for recovery\n * @dev This method checks if the public key format is correct and reverts otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function validateNewOwner(\n bytes calldata _recoveryPublicKey\n ) public view override {\n if (\n !IVerificationFacet(\n LibLoupe.facetAddress(s.validateOwnerSignatureSelector)\n ).isValidKeyType(_recoveryPublicKey)\n ) revert AccountRecoveryFacet__InvalidRecoveryPublicKey();\n }\n\n /**\n * @notice Checks if recovery is currently pending\n * @return isPending Boolean indicating if recovery is pending\n */\n function _isRecoveryPending() internal view returns (bool isPending) {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n isPending = (rs.recoveryConfigs[INNER_STRUCT].executeAfter > 0);\n }\n\n /**\n * @notice Calculate the recovery hash dependent on chain, wallet address, nonce with EIP-191 prefix for safety\n * @dev Returns the keccak256 hash of EIP-191 msg hash packed with public key, salt, nonce, wallet address, etc\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _saltString Salt string to uniquely identify each recovery hash and for security\n * @return recoveryKeyHash Bytes32 string of the recovery hash\n */\n function getApprovalRecoveryKeyHash(\n bytes memory _recoveryPublicKey,\n string memory _saltString\n ) public view override returns (bytes32 recoveryKeyHash) {\n recoveryKeyHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n _recoveryPublicKey,\n _saltString,\n address(this),\n block.chainid,\n LibFacetStorage.recoveryStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Check the onchain approval of guardians and returns the number of guardians that approved\n * @dev Loop through the guardian addresses and returns the number of guardians that approved this recovery hash\n * @param _recoveryPublicKeyHash Bytes hash of newly recovered public key and recovery value of the account\n * @return approvalCount Number of guardians that approved\n */\n function getRecoveryApprovalCountWithTimeValidity(\n bytes32 _recoveryPublicKeyHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n for (uint256 i; i < guardianLength; ) {\n if (isRecoveryApproved(_recoveryPublicKeyHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Checks if the recovery is approved by the given approver\n * @param _recoveryPublicKeyHash Hash of the public key and configuration for recovery\n * @param _approver Address of approver\n * @return isApproved Bool value if recovery hash is approved\n */\n function isRecoveryApproved(\n bytes32 _recoveryPublicKeyHash,\n address _approver\n ) public view override returns (bool isApproved) {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n if (\n rs\n .isNewOwnerApproved[_recoveryPublicKeyHash][_approver].isApproved &&\n block.timestamp <\n rs.isNewOwnerApproved[_recoveryPublicKeyHash][_approver].validUntil\n ) {\n isApproved = true;\n }\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _recoveryPublicKeyHash Hash of recovery information\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _recoveryPublicKeyHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isRecoveryApproved(_recoveryPublicKeyHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert AccountRecoveryFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the lock period of this wallet address from security manager\n * @return lockPeriod value of lock period\n */\n function _getLockPeriod() internal view returns (uint256 lockPeriod) {\n lockPeriod = securityManager.lockPeriodOf(address(this));\n if (lockPeriod == 0) revert AccountRecoveryFacet__InvalidLockPeriod();\n }\n\n /**\n * @notice Returns the lock period of this wallet address from security manager\n * @return recoveryPeriod value of recovery period\n */\n function _getRecoveryPeriod()\n internal\n view\n returns (uint256 recoveryPeriod)\n {\n recoveryPeriod = securityManager.recoveryPeriodOf(address(this));\n if (recoveryPeriod == 0)\n revert AccountRecoveryFacet__InvalidRecoveryPeriod();\n }\n\n /**\n * @notice Returns the approval validation period of this wallet address from security manager\n * @return approvalValidationPeriod value of approval validation period\n */\n function _getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod == 0)\n revert AccountRecoveryFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the recovery nonce of this wallet address from security manager\n * @return nonce value of recovery nonce\n */\n function getRecoveryNonce() public view override returns (uint128 nonce) {\n nonce = LibFacetStorage.recoveryStorage().nonce;\n }\n\n /**\n * @notice Returns the recovery information of the pending recovery\n * @return recoveryConfig value struct of pending recovery\n */\n function getPendingRecovery()\n public\n view\n override\n returns (RecoveryConfig memory recoveryConfig)\n {\n recoveryConfig = LibFacetStorage.recoveryStorage().recoveryConfigs[\n INNER_STRUCT\n ];\n }\n}\n" + }, + "contracts/facets/base/DiamondCutFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibGuardian} from \"../../libraries/LibGuardian.sol\";\nimport {ISecurityManager} from \"../../infrastructure/interfaces/ISecurityManager.sol\";\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibFacetStorage, DiamondCutApprovalConfig, ApprovalConfig} from \"../../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"../Modifiers.sol\";\nimport {IDiamondCut} from \"./interfaces/IDiamondCut.sol\";\n\n/**\n * @title DiamondCut Facet\n * @dev Responsible for adding/removing/replace facets in Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DiamondCutFacet is Modifiers, IDiamondCut {\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Updates the flag for the interfaceId\n * @param _interfaceId InterfaceID to update the mapping\n * @param _flag Bool value to update the mapping of the given interface ID\n */\n function updateSupportsInterface(\n bytes4 _interfaceId,\n bool _flag\n ) external override onlyWhenUnlocked {\n LibDiamond.enforceIsSelf();\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId] = _flag;\n emit SupportsInterfaceUpdated(_interfaceId, _flag);\n }\n\n /**\n * @notice Add/replace/remove any number of functions and optionally execute\n * a function with delegatecall when guardians don't exist\n * @param _diamondCut Contains the facet addresses and function selectors\n * @param _init The address of the contract or facet to execute _calldata. It's prohibited in Barz\n */\n function diamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata\n ) external override onlyWhenUnlocked {\n LibDiamond.enforceIsSelf();\n\n _checkFacetCutValidity(_diamondCut);\n // require approval from guardian if guardian exists\n if (0 != LibGuardian.guardianCount())\n revert DiamondCutFacet__InvalidRouteWithGuardian();\n if (address(0) != _init) revert DiamondCutFacet__InvalidInitAddress();\n\n unchecked {\n ++LibFacetStorage.diamondCutStorage().nonce;\n }\n LibDiamond.diamondCut(_diamondCut, address(0), \"\");\n }\n\n /**\n * @notice Add/replace/remove any number of functions and optionally execute\n * a function with delegatecall when guardians exist\n * @param _diamondCut Contains the facet addresses and function selectors\n * @param _approvers Guardian or owner address that approves the diamond cut\n * @param _signatures Signature of Guardians or owner that approves the diamond cut\n */\n function diamondCutWithGuardian(\n FacetCut[] calldata _diamondCut,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n ) external override onlyWhenUnlocked {\n if (_approvers.length != _signatures.length)\n revert DiamondCutFacet__InvalidArrayLength();\n _checkFacetCutValidity(_diamondCut);\n if (0 == LibGuardian.guardianCount())\n revert DiamondCutFacet__InvalidRouteWithGuardian();\n\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(cutHash, _approvers);\n\n bool onChainOwnerApproval = getOwnerCutApprovalWithTimeValidity(\n cutHash\n );\n\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n if (\n _approvers.length +\n getDiamondCutApprovalCountWithTimeValidity(cutHash) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert DiamondCutFacet__InsufficientApprovers();\n\n bool ownerApproved;\n for (uint256 i; i < _approvers.length; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n _approvers[i] != address(this)\n ) revert DiamondCutFacet__InvalidApprover();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert DiamondCutFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n cutHash,\n _signatures[i]\n )\n ) revert DiamondCutFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n if (!ownerApproved && !onChainOwnerApproval)\n revert DiamondCutFacet__LackOfOwnerApproval();\n\n unchecked {\n ++LibFacetStorage.diamondCutStorage().nonce;\n }\n LibDiamond.diamondCut(_diamondCut, address(0), \"\");\n }\n\n /**\n * @notice Approves diamond cut. This can only be called directly from guardian or owner\n * @param _diamondCut Contains the facet addresses and function selectors\n */\n function approveDiamondCut(\n FacetCut[] calldata _diamondCut\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\n if (LibGuardian.guardianCount() == 0)\n revert DiamondCutFacet__InvalidRouteWithoutGuardian();\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n _checkFacetCutValidity(_diamondCut);\n\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(\n true,\n approvalValidUntil\n );\n emit DiamondCutApproved(_diamondCut);\n if (\n (getDiamondCutApprovalCountWithTimeValidity(cutHash) >=\n LibGuardian.majorityOfGuardians()) &&\n getOwnerCutApprovalWithTimeValidity(cutHash)\n ) {\n unchecked {\n ++LibFacetStorage.diamondCutStorage().nonce;\n }\n LibDiamond.diamondCut(_diamondCut, address(0), \"\");\n }\n }\n\n /**\n * @notice Revokes the approval of diamond cut. This can only be called directly from guardian or owner\n * @param _diamondCut Contains the facet addresses and function selectors\n */\n function revokeDiamondCutApproval(\n FacetCut[] calldata _diamondCut\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\n if (!ds.isDiamondCutApproved[cutHash][msg.sender].isApproved)\n revert DiamondCutFacet__CannotRevokeUnapproved();\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(false, 0);\n emit DiamondCutApprovalRevoked(_diamondCut);\n }\n\n /**\n * @notice Gets the number of approvals of diamond cut from guardians\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n */\n function getDiamondCutApprovalCountWithTimeValidity(\n bytes32 _diamondCutHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardiansLength = guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n if (isCutApproved(_diamondCutHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n return approvalCount;\n }\n\n /**\n * @notice Returns if the owner has approved the diamond cut\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @return isApprovedByOwner Bool value showing if the owner approved the cut\n */\n function getOwnerCutApprovalWithTimeValidity(\n bytes32 _diamondCutHash\n ) public view override returns (bool isApprovedByOwner) {\n isApprovedByOwner = isCutApproved(_diamondCutHash, address(this));\n }\n\n /**\n * @notice Returns if the given approver has approved the diamond cut\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @param _approver Address of approver\n * @return isApproved Bool value showing if the approver approved the cut\n */\n function isCutApproved(\n bytes32 _diamondCutHash,\n address _approver\n ) public view override returns (bool isApproved) {\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n isApproved = (ds\n .isDiamondCutApproved[_diamondCutHash][_approver].isApproved &&\n block.timestamp <\n ds.isDiamondCutApproved[_diamondCutHash][_approver].validUntil);\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _diamondCutHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isCutApproved(_diamondCutHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert DiamondCutFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the diamond cut hash. This function ensures that this hash is safe from replay attack by including\n * salt, address, chainId, and nonce, etc.\n * @param _diamondCut Contains the facet addresses and function selectors\n * @return cutHash Diamond Cut Hash\n */\n function getDiamondCutHash(\n FacetCut[] calldata _diamondCut\n ) public view override returns (bytes32 cutHash) {\n cutHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n keccak256(abi.encode(_diamondCut)),\n address(this),\n block.chainid,\n LibFacetStorage.diamondCutStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Returns the approval validation Period\n * @dev This method fetches the validation period from the security manager\n * @return approvalValidationPeriod Approval validation period of Barz contract fetched from security manager\n */\n function getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod <= 0)\n revert DiamondCutFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the diamond cut nonce of this wallet\n * @dev This method fetches the nonce from diamond cut storage\n * @return cutNonce Nonce of diamond cut to protect from reply attacks\n */\n function getDiamondCutNonce()\n public\n view\n override\n returns (uint128 cutNonce)\n {\n cutNonce = LibFacetStorage.diamondCutStorage().nonce;\n }\n}\n" + }, + "contracts/facets/base/DiamondLoupeFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {IERC165} from \"../../interfaces/ERC/IERC165.sol\";\nimport {IERC1271} from \"../../interfaces/ERC/IERC1271.sol\";\nimport {IERC677Receiver} from \"../../interfaces/ERC/IERC677Receiver.sol\";\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC1155Receiver} from \"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\";\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../../libraries/LibLoupe.sol\";\nimport {LibUtils} from \"../../libraries/LibUtils.sol\";\nimport {IDiamondCut} from \"../../facets/base/interfaces/IDiamondCut.sol\";\nimport {IStorageLoupe} from \"./interfaces/IStorageLoupe.sol\";\nimport {IDiamondLoupe} from \"./interfaces/IDiamondLoupe.sol\";\n\n/**\n * @title DiamondLoupe Facet\n * @dev DiamondLoupe contract compatible with EIP-2535\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DiamondLoupeFacet is IDiamondLoupe, IStorageLoupe, IERC165 {\n // Diamond Loupe Functions\n ////////////////////////////////////////////////////////////////////\n /// These functions are expected to be called frequently by tools off-chain.\n\n /**\n * @notice Gets all facets and their selectors.\n * @dev Barz uses a special architecture called default fallback handler. Default Fallback handler is used as a middleware\n * that holds the mapping of facet function selector and facet address that Barz uses. This helps Barz to reduce\n * significant amount of gas during the initialization process.\n * Hence, this method aggregates both the facet information from DefaulFallbackHandler and in diamond storage and shows the data to users.\n * @return facets_ Facet\n */\n function facets() public view override returns (Facet[] memory facets_) {\n Facet[] memory defaultFacet = LibDiamond\n .diamondStorage()\n .defaultFallbackHandler\n .facets();\n Facet[] memory _facets = LibLoupe.facets();\n uint256 numFacets = _facets.length;\n bytes4[] memory keys;\n address[] memory values;\n for (uint256 i; i < numFacets; ) {\n uint256 selectorsLength = _facets[i].functionSelectors.length;\n for (uint256 j; j < selectorsLength; ) {\n (keys, values) = LibUtils.setValue(\n keys,\n values,\n _facets[i].functionSelectors[j],\n _facets[i].facetAddress\n );\n unchecked {\n ++j;\n }\n }\n unchecked {\n ++i;\n }\n }\n {\n bool iIncrement;\n for (uint256 i; i < defaultFacet.length; ) {\n bool jIncrement;\n for (\n uint256 j;\n j < defaultFacet[i].functionSelectors.length;\n\n ) {\n if (\n LibUtils.getValue(\n keys,\n values,\n defaultFacet[i].functionSelectors[j]\n ) != address(0)\n ) {\n if (defaultFacet[i].functionSelectors.length == 1) {\n defaultFacet = LibUtils.removeFacetElement(\n defaultFacet,\n i\n );\n iIncrement = true;\n break;\n }\n defaultFacet[i].functionSelectors = LibUtils\n .removeElement(\n defaultFacet[i].functionSelectors,\n j\n );\n jIncrement = true;\n }\n if (!jIncrement) {\n unchecked {\n ++j;\n }\n } else {\n jIncrement = false;\n }\n }\n if (!iIncrement) {\n unchecked {\n ++i;\n }\n } else {\n iIncrement = false;\n }\n }\n }\n {\n uint256 facetLength = numFacets + defaultFacet.length;\n facets_ = new Facet[](facetLength);\n uint256 defaultFacetIndex;\n for (uint256 i; i < facetLength; ) {\n if (i < numFacets) {\n facets_[i] = _facets[i];\n bool jIncrementor;\n for (uint256 j; j < defaultFacet.length; ) {\n if (\n facets_[i].facetAddress ==\n defaultFacet[j].facetAddress\n ) {\n facets_[i].functionSelectors = LibUtils.mergeArrays(\n _facets[i].functionSelectors,\n defaultFacet[j].functionSelectors\n );\n defaultFacet = LibUtils.removeFacetElement(\n defaultFacet,\n j\n );\n jIncrementor = true;\n {\n facets_ = LibUtils.removeFacetElement(\n facets_,\n facets_.length - 1\n );\n }\n --facetLength;\n }\n if (!jIncrementor) {\n unchecked {\n ++j;\n }\n } else {\n jIncrementor = false;\n }\n }\n } else {\n facets_[i] = defaultFacet[defaultFacetIndex];\n ++defaultFacetIndex;\n }\n unchecked {\n ++i;\n }\n }\n }\n }\n\n /**\n * @notice Gets all the function selectors provided by a facet.\n * @param _facet The facet address.\n * @return facetFunctionSelectors_\n */\n function facetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n Facet[] memory facet = facets();\n uint256 facetLength = facet.length;\n for (uint256 i; i < facetLength; ) {\n if (facet[i].facetAddress == _facet)\n return facet[i].functionSelectors;\n unchecked {\n ++i;\n }\n }\n return facetFunctionSelectors_;\n }\n\n /**\n * @notice Get all the facet addresses used by Barz.\n * @return facetAddresses_\n */\n function facetAddresses()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n Facet[] memory facet = facets();\n uint256 facetLength = facet.length;\n facetAddresses_ = new address[](facetLength);\n for (uint256 i; i < facetLength; ) {\n facetAddresses_[i] = facet[i].facetAddress;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Gets the facet that supports the given selector.\n * @dev If facet is not found return address(0).\n * @param _functionSelector The function selector.\n * @return facetAddress_ The facet address.\n */\n function facetAddress(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n\n facetAddress_ = address(bytes20(ds.facets[_functionSelector]));\n if (facetAddress_ == address(0)) {\n facetAddress_ = IDiamondLoupe(ds.defaultFallbackHandler)\n .facetAddress(_functionSelector);\n }\n }\n\n /**\n * @notice SupportInterface to be compatible with EIP 165\n * @param _interfaceId Interface ID for detecting the interface\n * @return isSupported Bool value showing if the standard is supported in the contract\n */\n function supportsInterface(\n bytes4 _interfaceId\n ) external view override returns (bool isSupported) {\n isSupported =\n _interfaceId == type(IERC165).interfaceId ||\n _interfaceId == IDiamondCut.diamondCut.selector ||\n _interfaceId == type(IDiamondLoupe).interfaceId ||\n _interfaceId == type(IERC1155Receiver).interfaceId ||\n _interfaceId == type(IERC721Receiver).interfaceId ||\n _interfaceId == type(IERC777Recipient).interfaceId ||\n _interfaceId == IERC1271.isValidSignature.selector ||\n _interfaceId == type(IERC677Receiver).interfaceId ||\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId];\n }\n\n /**\n * @notice Returns the facet from the diamond storage. This excludes the facets from the default fallback handler\n * @return facets_ Facet information attached directly to diamond storage\n */\n function facetsFromStorage()\n external\n view\n override\n returns (Facet[] memory facets_)\n {\n facets_ = LibLoupe.facets();\n }\n\n /**\n * @notice Returns the facet address attached to the given function selector. This excludes the facets from the default fallback handler\n * @param _functionSelector Function selector to fetch the facet address from diamond storage\n * @return facetAddress_ Facet address mapped with the function selector\n */\n function facetAddressFromStorage(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n facetAddress_ = LibLoupe.facetAddress(_functionSelector);\n }\n\n /**\n * @notice Returns all facet addresses attached directly to diamond storage. This excludes the facets from the default fallback handler\n * @return facetAddresses_ All facet addresses attached directly to diamond storage\n */\n function facetAddressesFromStorage()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n facetAddresses_ = LibLoupe.facetAddresses();\n }\n\n /**\n * @notice Returns function selectors of given facet address attached directly to diamond storage. This excludes the facets from the default fallback handler\n * @param _facet Facet address to fetch the facet function selectors from diamond storage\n * @return facetFunctionSelectors_ Facet function selectors of the given facet address\n */\n function facetFunctionSelectorsFromStorage(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n facetFunctionSelectors_ = LibLoupe.facetFunctionSelectors(_facet);\n }\n}\n" + }, + "contracts/facets/base/interfaces/IDiamondCut.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title DiamondCut Facet Interface\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IDiamondCut {\n error DiamondCutFacet__InvalidRouteWithGuardian();\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\n error DiamondCutFacet__InvalidArrayLength();\n error DiamondCutFacet__InsufficientApprovers();\n error DiamondCutFacet__InvalidApprover();\n error DiamondCutFacet__InvalidApproverSignature();\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\n error DiamondCutFacet__CannotRevokeUnapproved();\n error DiamondCutFacet__LackOfOwnerApproval();\n error DiamondCutFacet__OwnerAlreadyApproved();\n error DiamondCutFacet__DuplicateApproval();\n error DiamondCutFacet__InvalidInitAddress();\n\n event DiamondCutApproved(FacetCut[] diamondCut);\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\n\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\n\n enum FacetCutAction {\n Add,\n Replace,\n Remove\n }\n // Add=0, Replace=1, Remove=2\n\n struct FacetCut {\n address facetAddress;\n FacetCutAction action;\n bytes4[] functionSelectors;\n }\n\n /// @notice Add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param diamondCut Contains the facet addresses and function selectors\n /// @param init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function diamondCut(\n FacetCut[] calldata diamondCut,\n address init,\n bytes calldata _calldata\n ) external;\n\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\n\n function diamondCutWithGuardian(\n FacetCut[] calldata diamondCut,\n address[] calldata approvers,\n bytes[] calldata signatures\n ) external;\n\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\n\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\n\n function getDiamondCutApprovalCountWithTimeValidity(\n bytes32 diamondCutHash\n ) external view returns (uint256);\n\n function getOwnerCutApprovalWithTimeValidity(\n bytes32 diamondCutHash\n ) external view returns (bool);\n\n function isCutApproved(\n bytes32 diamondCutHash,\n address approver\n ) external view returns (bool);\n\n function getDiamondCutHash(\n FacetCut[] calldata diamondCut\n ) external view returns (bytes32);\n\n function getDiamondCutNonce() external view returns (uint128);\n}\n" + }, + "contracts/facets/base/interfaces/IDiamondLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n// A loupe is a small magnifying glass used to look at diamonds.\n// These functions look at diamonds\ninterface IDiamondLoupe {\n /// These functions are expected to be called frequently\n /// by tools.\n\n struct Facet {\n address facetAddress;\n bytes4[] functionSelectors;\n }\n\n /// @notice Gets all facet addresses and their four byte function selectors.\n /// @return facets_ Facet\n function facets() external view returns (Facet[] memory facets_);\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n /// @return facetFunctionSelectors_\n function facetFunctionSelectors(\n address _facet\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses()\n external\n view\n returns (address[] memory facetAddresses_);\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(\n bytes4 _functionSelector\n ) external view returns (address facetAddress_);\n}\n" + }, + "contracts/facets/base/interfaces/IStorageLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"./IDiamondLoupe.sol\";\n\n/**\n * @title LoupeFromStorage Interface\n * @dev Interface contract to function as a loupe facet directly attached to diamond storage of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IStorageLoupe {\n /// These functions are expected to be called frequently\n /// by tools.\n\n /// @notice Gets all facet addresses and their four byte function selectors.\n /// @return facets_ Facet\n function facetsFromStorage()\n external\n view\n returns (IDiamondLoupe.Facet[] memory);\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n function facetFunctionSelectorsFromStorage(\n address _facet\n ) external view returns (bytes4[] memory);\n\n /// @notice Get all the facet addresses used by a diamond.\n function facetAddressesFromStorage()\n external\n view\n returns (address[] memory);\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n function facetAddressFromStorage(\n bytes4 _functionSelector\n ) external view returns (address);\n}\n" + }, + "contracts/facets/GuardianFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibFacetStorage, GuardianStorage, StorageConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IGuardianFacet} from \"./interfaces/IGuardianFacet.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Guardian Facet\n * @dev Contract that enables addition/removal of guardians from Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract GuardianFacet is IGuardianFacet {\n ISecurityManager public immutable securityManager;\n uint8 public constant INNER_STRUCT = 0;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Add guardians to Barz.\n * @dev This method internally calls addGuardian which checks the validity of guardian address and adds\n * as guardian if valid\n * @param _guardians Array of addresses to add as guardian\n */\n function addGuardians(address[] calldata _guardians) external override {\n LibDiamond.enforceIsSelf();\n for (uint256 i; i < _guardians.length; ) {\n addGuardian(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Add a guardian to Barz.\n * @dev This method checks if the function is called by the owner and validates the address of guardian\n * When the validation passes, guardian address is added to the pending state waiting for confirmation\n * @param _guardian Address to add as guardian\n */\n function addGuardian(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (_guardian == address(this))\n revert GuardianFacet__GuardianCannotBeSelf();\n if (isGuardian(_guardian)) revert GuardianFacet__DuplicateGuardian();\n if (_guardian == address(0))\n revert GuardianFacet__ZeroAddressGuardian();\n if (\n keccak256(abi.encodePacked(_guardian)) ==\n keccak256(IVerificationFacet(address(this)).owner())\n ) revert GuardianFacet__OwnerCannotBeGuardian();\n\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n if (\n gs.pending[id] != 0 ||\n block.timestamp <= gs.pending[id] + getSecurityWindow()\n ) revert GuardianFacet__DuplicateGuardianAddition();\n\n uint256 securityPeriod = getAdditionSecurityPeriod();\n gs.pending[id] = block.timestamp + securityPeriod;\n emit GuardianAdditionRequested(\n _guardian,\n block.timestamp + securityPeriod\n );\n }\n\n /**\n * @notice Remove guardians from Barz.\n * @dev This method internally calls removeGuardian which checks the validity of guardian and removes\n * guardian when the request is valid\n * @param _guardians Array of addresses to be removed\n */\n function removeGuardians(address[] calldata _guardians) external override {\n LibDiamond.enforceIsSelf();\n for (uint256 i; i < _guardians.length; ) {\n removeGuardian(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Remove a guardian from Barz.\n * @dev This method validates if the guardian to be removed is a guardian and puts the guardian removal\n * to a pending state waiting to be confirmed.\n * @param _guardian Address of guardian to be removed\n */\n function removeGuardian(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n if (!isGuardian(_guardian)) revert GuardianFacet__NonExistentGuardian();\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n if (\n gs.pending[id] != 0 ||\n block.timestamp <= gs.pending[id] + getSecurityWindow()\n ) revert GuardianFacet__DuplicateGuardianRemoval();\n\n uint256 securityPeriod = getRemovalSecurityPeriod();\n gs.pending[id] = block.timestamp + securityPeriod;\n emit GuardianRemovalRequested(\n _guardian,\n block.timestamp + securityPeriod\n );\n }\n\n /**\n * @notice Confirm addition of guardians\n * @dev This method internally calls confirmGuardianAddition which checks the validity of pending request.\n * Guardians are fully added when they pass the validation. Anyone can call this function.\n * @param _guardians Array of guardian addresses to be added\n */\n function confirmGuardianAdditions(\n address[] calldata _guardians\n ) external override {\n for (uint256 i; i < _guardians.length; ) {\n confirmGuardianAddition(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Confirm addition of a guardian\n * @dev This method checks the validity of pending request.\n * Guardians are fully added when they pass the validation. Anyone can call this function.\n * @param _guardian Guardian address to be added\n */\n function confirmGuardianAddition(address _guardian) public override {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingAddition();\n if (gs.pending[id] >= block.timestamp)\n revert GuardianFacet__PendingAdditionNotOver();\n if (block.timestamp >= gs.pending[id] + getSecurityWindow())\n revert GuardianFacet__PendingAdditionExpired();\n\n _addGuardian(_guardian);\n\n delete gs.pending[id];\n emit GuardianAdded(_guardian);\n }\n\n /**\n * @notice Confirm removal of guardians\n * @dev This method internally calls confirmGuardianRemoval to check the validity guardian removal confirmation.\n * Guardians are fully removed when they pass the validation. Anyone can call this function.\n * @param _guardians Array of guardian addresses to be removed\n */\n function confirmGuardianRemovals(\n address[] calldata _guardians\n ) external override {\n for (uint256 i; i < _guardians.length; ) {\n confirmGuardianRemoval(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Confirm removal of a guardian\n * @dev This method checks the validity guardian removal confirmation.\n * Guardian is fully removed when they pass the validation. Anyone can call this function.\n * @param _guardian Guardian address to be removed\n */\n function confirmGuardianRemoval(address _guardian) public override {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingRemoval();\n if (gs.pending[id] >= block.timestamp)\n revert GuardianFacet__PendingRemovalNotOver();\n if (block.timestamp >= gs.pending[id] + getSecurityWindow())\n revert GuardianFacet__PendingAdditionExpired();\n\n _removeGuardian(_guardian);\n delete gs.pending[id];\n emit GuardianRemoved(_guardian);\n }\n\n /**\n * @notice Cancel pending guardian addition\n * @dev This method checks if the previous request for guardian request exists.\n * It reverts if previous request is not pending and cancels the addition otherwise.\n * @param _guardian Guardian address to be canceled from addition\n */\n function cancelGuardianAddition(address _guardian) external override {\n LibDiamond.enforceIsSelf();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingAddition();\n delete gs.pending[id];\n emit GuardianAdditionCancelled(_guardian);\n }\n\n /**\n * @notice Cancel pending guardian removal\n * @dev This method checks if the previous request for guardian request exists.\n * It reverts if previous request is not pending and cancels the removal otherwise.\n * @param _guardian Guardian address to be canceled from removal\n */\n function cancelGuardianRemoval(address _guardian) external override {\n LibDiamond.enforceIsSelf();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingRemoval();\n delete gs.pending[id];\n emit GuardianRemovalCancelled(_guardian);\n }\n\n /**\n * @notice Get the addition security period of current account from security manager\n * @dev This method returns the uint value if addition security period\n * @return additionSecurityPeriod Uint256 value of addition security period\n */\n function getAdditionSecurityPeriod()\n public\n view\n override\n returns (uint256 additionSecurityPeriod)\n {\n additionSecurityPeriod = securityManager.additionSecurityPeriodOf(\n address(this)\n );\n if (additionSecurityPeriod == 0)\n revert GuardianFacet__InvalidAdditionSecurityPeriod();\n }\n\n /**\n * @notice Get the removal security period of current account from security manager\n * @dev This method returns the uint value if removal security period\n * @return removalSecurityPeriod Uint256 value of removal security period\n */\n function getRemovalSecurityPeriod()\n public\n view\n override\n returns (uint256 removalSecurityPeriod)\n {\n removalSecurityPeriod = securityManager.removalSecurityPeriodOf(\n address(this)\n );\n if (removalSecurityPeriod == 0)\n revert GuardianFacet__InvalidRemovalSecurityPeriod();\n }\n\n /**\n * @notice Get the security window of current account from security manager\n * @dev This method returns the uint value if security window\n * @return securityWindow Uint256 value of removal security period\n */\n function getSecurityWindow()\n public\n view\n override\n returns (uint256 securityWindow)\n {\n securityWindow = securityManager.securityWindowOf(address(this));\n if (securityWindow == 0) revert GuardianFacet__InvalidSecurityWindow();\n }\n\n /**\n * @notice Checks if the addition of the given guardian address is pending\n * @dev This method returns the bool value of whether the guardian address is pending addition\n * @return isPending Bool value of representing the pending of guardian addition\n */\n function isAdditionPending(\n address _guardian\n ) public view override returns (bool isPending) {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n isPending = _isPending(id);\n }\n\n /**\n * @notice Checks if the removal of the given guardian address is pending\n * @dev This method returns the bool value of whether the guardian address is pending removal\n * @return isPending Bool value of representing the pending of guardian removal\n */\n function isRemovalPending(\n address _guardian\n ) public view override returns (bool isPending) {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n isPending = _isPending(id);\n }\n\n /**\n * @notice Checks if the given hash is pending\n * @dev This method returns the bool value whether the hash is pending\n * @return isPending Bool value of representing the pending of guardian operation\n */\n function _isPending(\n bytes32 _idHash\n ) internal view returns (bool isPending) {\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n isPending = ((gs.pending[_idHash] > 0 &&\n gs.pending[_idHash] < block.timestamp) &&\n block.timestamp < gs.pending[_idHash] + getSecurityWindow());\n }\n\n /**\n * @notice Adds guardian to storage config. This is called when guardian is fully added.\n * @dev This method add guardian address and config information to Facet Storage dedicated for guardian\n * When this function is called, guardian is fully added to this Barz Smart Account\n * @param _guardian Address of guardian to be added\n */\n function _addGuardian(address _guardian) internal {\n if (!isAdditionPending(_guardian))\n revert GuardianFacet__InvalidGuardianAddition();\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n if (config.info[_guardian].exists)\n revert GuardianFacet__AlreadyExists();\n\n config.info[_guardian].exists = true;\n config.info[_guardian].index = uint128(config.addresses.length);\n config.addresses.push(_guardian);\n }\n\n /**\n * @notice Removes guardian to storage config. This is called when guardian is fully removed.\n * @dev This method remove guardian address and config information to Facet Storage dedicated for guardian\n * When this function is called, guardian is fully removed from this Barz Smart Account\n * @param _guardian Address of guardian to be removed\n */\n function _removeGuardian(address _guardian) internal {\n if (!isRemovalPending(_guardian))\n revert GuardianFacet__InvalidGuardianRemoval();\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n if (!config.info[_guardian].exists)\n revert GuardianFacet__NonExistentGuardian();\n\n address lastAddress = config.addresses[config.addresses.length - 1];\n if (_guardian != lastAddress) {\n uint128 targetIndex = config.info[_guardian].index;\n config.addresses[targetIndex] = lastAddress;\n config.info[lastAddress].index = targetIndex;\n }\n config.addresses.pop();\n delete config.info[_guardian];\n\n emit GuardianRemoved(_guardian);\n }\n\n /**\n * @notice Reads guardian storage and fetches the addresses into an array from the storage\n * @dev This method fetches the guardian storage and returns the list of guardian addresses\n * @return guardians Array of addresses comprised of guardian\n */\n function getGuardians()\n public\n view\n override\n returns (address[] memory guardians)\n {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n uint256 guardiansLen = config.addresses.length;\n guardians = new address[](guardiansLen);\n for (uint256 i; i < guardiansLen; ) {\n guardians[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the number of majority of guardians\n * @return majorityOfGuardians_ Number of majority of guardians e.g., 2 if 3 guardians / 3 if 5 guardians\n */\n function majorityOfGuardians()\n public\n view\n override\n returns (uint256 majorityOfGuardians_)\n {\n majorityOfGuardians_ = LibGuardian.majorityOfGuardians();\n }\n\n /**\n * @notice Reads guardian storage and fetches the addresses into an array from the storage\n * @dev This method fetches the guardian storage and returns the list of guardian addresses\n * @return guardianNumber Array of guardians in the account\n */\n function guardianCount()\n public\n view\n override\n returns (uint256 guardianNumber)\n {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n guardianNumber = config.addresses.length;\n }\n\n /**\n * @notice Reads guardian storage and checks if the given address is a guardian\n * @return isGuardian_ Bool value representing if the given address is guardian\n */\n function isGuardian(\n address _guardian\n ) public view override returns (bool isGuardian_) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n isGuardian_ = config.info[_guardian].exists;\n }\n\n /**\n * @notice Checks if the guardian number is zero and returns of guardian facet is okay to be removed\n * @return isRemovable Bool value representing if guardian facet is removable\n */\n function isGuardianFacetRemovable()\n external\n view\n override\n returns (bool isRemovable)\n {\n isRemovable = (0 == guardianCount());\n }\n}\n" + }, + "contracts/facets/interfaces/IAccountFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IEntryPoint} from \"../../aa-4337/interfaces/IEntryPoint.sol\";\n\n/**\n * @title Account Facet Interface\n * @dev Interface of module contract that provides the account features and init/unitialization of signer\n * compatible with EIP-1271 & EIP-4337\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IAccountFacet {\n event AccountInitialized(\n IEntryPoint indexed entryPoint,\n bytes indexed ownerPublicKey\n );\n // NOTE: Added Below Event\n event VerificationSuccess(bytes32);\n event VerificationFailure(bytes32);\n\n error AccountFacet__InitializationFailure();\n error AccountFacet__RestrictionsFailure();\n error AccountFacet__NonExistentVerificationFacet();\n error AccountFacet__CallNotSuccessful();\n error AccountFacet__InvalidArrayLength();\n\n function initialize(\n address verificationFacet,\n address anEntryPoint,\n address facetRegistry,\n address _defaultFallBack,\n bytes calldata _ownerPublicKey\n ) external returns (uint256);\n\n function execute(address dest, uint256 value, bytes calldata func) external;\n\n function executeBatch(\n address[] calldata dest,\n uint256[] calldata value,\n bytes[] calldata func\n ) external;\n}\n" + }, + "contracts/facets/interfaces/IAccountRecoveryFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {RecoveryConfig} from \"../../libraries/LibFacetStorage.sol\";\n\n/**\n * @title Account Recovery Facet Interface\n * @dev Interface of contract that enables recovery of accounts when owner key is unavailable\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IAccountRecoveryFacet {\n event RecoveryExecuted(\n bytes indexed recoveryPublicKey,\n uint64 executeAfter\n );\n event RecoveryFinalized(bytes indexed recoveryPublicKey);\n event RecoveryCanceled(bytes indexed recoveryPublicKey);\n event RecoveryApproved(\n bytes indexed recoveryPublicKey,\n address indexed guardian,\n uint64 validUntil\n );\n event RecoveryApprovalRevoked(\n bytes indexed recoveryPublicKey,\n address indexed guardian\n );\n event RecoveryCancellationApproved(\n bytes indexed recoveryPublicKey,\n address indexed guardian\n );\n event RecoveryHardstopped();\n\n error AccountRecoveryFacet__CallerNotGuardian();\n error AccountRecoveryFacet__InvalidRecoveryPublicKey();\n error AccountRecoveryFacet__SignerInitializationFailure();\n error AccountRecoveryFacet__SignerUninitializationFailure();\n error AccountRecoveryFacet__InvalidArrayLength();\n error AccountRecoveryFacet__InsufficientGuardians();\n error AccountRecoveryFacet__RecoveryAlreadyOngoing();\n error AccountRecoveryFacet__NonexistentRecovery();\n error AccountRecoveryFacet__NonExistentApproval();\n error AccountRecoveryFacet__RecoveryPeriodNotOver();\n error AccountRecoveryFacet__InvalidLockPeriod();\n error AccountRecoveryFacet__InvalidRecoveryPeriod();\n error AccountRecoveryFacet__InvalidApprovalValidationPeriod();\n error AccountRecoveryFacet__InvalidGuardian();\n error AccountRecoveryFacet__InvalidGuardianSignature();\n error AccountRecoveryFacet__InvalidOwnerSignature();\n error AccountRecoveryFacet__CallNotSuccesful();\n error AccountRecoveryFacet__DuplicateApproval();\n\n function approveAccountRecovery(bytes calldata recoveryPublicKey) external;\n\n function revokeAccountRecoveryApproval(\n bytes calldata recoveryPublicKey\n ) external;\n\n function executeRecovery(\n bytes calldata recoveryPublicKey,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function finalizeRecovery() external;\n\n function approveCancelRecovery(bytes calldata recoveryPublicKey) external;\n\n function cancelRecovery(\n bytes calldata recoveryPublicKey,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function hardstopRecovery(bytes calldata signature) external;\n\n function validateNewOwner(bytes calldata recoveryPublicKey) external view;\n\n function getApprovalRecoveryKeyHash(\n bytes memory recoveryPublicKey,\n string memory saltString\n ) external view returns (bytes32);\n\n function getRecoveryApprovalCountWithTimeValidity(\n bytes32 recoveryPublicKeyHash\n ) external view returns (uint256);\n\n function isRecoveryApproved(\n bytes32 recoveryPublicKeyHash,\n address approver\n ) external view returns (bool);\n\n function getRecoveryNonce() external view returns (uint128);\n\n function getPendingRecovery() external view returns (RecoveryConfig memory);\n}\n" + }, + "contracts/facets/interfaces/IGuardianFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Guardian Facet Interface\n * @dev Interface of guaridna contract that enables addition/removal of guardians from Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IGuardianFacet {\n event GuardianAdditionRequested(\n address indexed guardian,\n uint256 executeAfter\n );\n event GuardianRemovalRequested(\n address indexed guardian,\n uint256 executeAfter\n );\n event GuardianAdditionCancelled(address indexed guardian);\n event GuardianRemovalCancelled(address indexed guardian);\n event GuardianAdded(address indexed guardian);\n event GuardianRemoved(address indexed guardian);\n\n error GuardianFacet__GuardianCannotBeSelf();\n error GuardianFacet__DuplicateGuardian();\n error GuardianFacet__OwnerCannotBeGuardian();\n error GuardianFacet__DuplicateGuardianAddition();\n error GuardianFacet__DuplicateGuardianRemoval();\n error GuardianFacet__UnknownPendingAddition();\n error GuardianFacet__PendingAdditionNotOver();\n error GuardianFacet__UnknownPendingRemoval();\n error GuardianFacet__PendingRemovalNotOver();\n error GuardianFacet__PendingAdditionExpired();\n error GuardianFacet__InvalidAdditionSecurityPeriod();\n error GuardianFacet__InvalidRemovalSecurityPeriod();\n error GuardianFacet__InvalidSecurityWindow();\n error GuardianFacet__NonExistentGuardian();\n error GuardianFacet__AlreadyExists();\n error GuardianFacet__InvalidGuardianAddition();\n error GuardianFacet__InvalidGuardianRemoval();\n error GuardianFacet__ZeroAddressGuardian();\n\n function addGuardian(address guardian) external;\n\n function addGuardians(address[] calldata guardians) external;\n\n function removeGuardian(address guardian) external;\n\n function removeGuardians(address[] calldata guardians) external;\n\n function confirmGuardianAddition(address guardian) external;\n\n function confirmGuardianAdditions(address[] calldata guardian) external;\n\n function confirmGuardianRemoval(address guardian) external;\n\n function confirmGuardianRemovals(address[] calldata guardian) external;\n\n function cancelGuardianAddition(address guardian) external;\n\n function cancelGuardianRemoval(address guardian) external;\n\n function isGuardian(address guardian) external view returns (bool);\n\n function isAdditionPending(address guardian) external view returns (bool);\n\n function isRemovalPending(address guardian) external view returns (bool);\n\n function isGuardianFacetRemovable() external view returns (bool);\n\n function getAdditionSecurityPeriod() external view returns (uint256);\n\n function getRemovalSecurityPeriod() external view returns (uint256);\n\n function getSecurityWindow() external view returns (uint256);\n\n function getGuardians() external view returns (address[] memory);\n\n function majorityOfGuardians() external view returns (uint256);\n\n function guardianCount() external view returns (uint256);\n}\n" + }, + "contracts/facets/interfaces/ILockFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Lock} from \"../../libraries/LibAppStorage.sol\";\n\n/**\n * @title Lock Facet Interface\n * @dev Interface of Lock contract that enables full lock/unlock of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface ILockFacet {\n event Locked(uint64 releaseAfter);\n event Unlocked();\n\n error LockFacet__InvalidRecoveryPeriod();\n error LockFacet__CannotUnlock();\n error LockFacet__InvalidSignature();\n error LockFacet__InvalidApprover();\n\n function lock() external;\n\n function unlock(address approver, bytes calldata signature) external;\n\n function getLockPeriod() external view returns (uint256);\n\n function isLocked() external view returns (bool);\n\n function getUnlockHash() external view returns (bytes32);\n\n function lockNonce() external view returns (uint128);\n\n function getPendingLock() external view returns (Lock memory);\n}\n" + }, + "contracts/facets/interfaces/IMultiSigFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Multi-sig facet Interface\n * @dev Interface of Multi-signature Facet with custom threshold.\n Wallet that adds this facet becomes a multi-sig wallet\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IMultiSigFacet {\n event ThresholdChanged(uint256 threshold);\n event OwnerAdded(address indexed newOwner);\n event OwnerRemoved(address indexed prevOwner);\n event HashApproved(bytes32 hashToApprove, address indexed owner);\n\n error MultiSigFacet__InvalidThreshold();\n error MultisigFacet__InvalidOwnerCount();\n error MultiSigFacet__InvalidRoute();\n error MultiSigFacet__InsufficientSignerLength();\n error MultiSigFacet__InvalidInitData();\n error MultiSigFacet__InvalidOwnerAddress();\n error MultiSigFacet__InvalidOwnerPair();\n error MultiSigFacet__InvalidSignatureLength();\n error MultiSigFacet__InvalidSignatureType();\n error MultiSigFacet__DuplicateOwner();\n error MultiSigFacet__OnlyOwner();\n\n function checkSignatures(\n bytes32 _dataHash,\n bytes calldata _signatures,\n uint256 _threshold\n ) external view returns (uint256);\n\n function splitSignatures(\n bytes calldata _signatures,\n uint256 _nextOffset\n )\n external\n pure\n returns (\n address owner,\n bytes memory signature,\n uint256 signatureType,\n uint256 nextOffset\n );\n\n function approveHash(bytes32 hashToApprove) external;\n\n function addOwner(address newOwner, uint256 threshold) external;\n\n function removeOwner(\n address prevOwner,\n address removedOwner,\n uint256 threshold\n ) external;\n\n function swapOwner(\n address prevOwner,\n address oldOwner,\n address newOwner\n ) external;\n\n function changeThreshold(uint256 _threshold) external;\n\n function isOwner(address owner) external view returns (bool);\n\n function getThreshold() external view returns (uint256);\n\n function getOwners() external view returns (address[] memory);\n}\n" + }, + "contracts/facets/interfaces/IRestrictionsFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Restrictions Facet Interface\n * @dev Interface of Restrictions contract that enables modular restrictions in Barz\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IRestrictionsFacet {\n event RestrictionAdded(address indexed restriction);\n event RestrictionRemoved(address indexed restriction);\n\n error RestrictionsFacet__EmptyRestrictionsList();\n error RestrictionsFacet__RestrictionNotFound();\n error RestrictionsFacet__RestrictionAlreadyExists();\n error RestrictionsFacet__ZeroAddressRestrictions();\n error RestrictionsFacet__ZeroAddressRestrictionsFacet();\n error RestrictionsFacet__RemainingRestrictionsCantBeEmpty();\n\n function initializeRestrictions(\n address[] memory _restrictions\n ) external returns (uint256);\n\n function uninitializeRestrictions() external returns (uint256);\n\n function getRestrictions() external view returns (address[] memory);\n\n function addRestriction(address restriction) external;\n\n function removeRestriction(address restriction) external;\n\n function verifyRestrictions(\n address from,\n address to,\n uint256 value,\n bytes calldata _calldata\n ) external returns (uint256);\n}\n" + }, + "contracts/facets/interfaces/ISignatureMigrationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureMigrationConfig} from \"../../libraries/LibFacetStorage.sol\";\n\n/**\n * @title Signature Migration Facet Interface\n * @dev Interface of Signature Migration contract for migrating user signature scheme to a new scheme user sets\n * Which could include\n * - ECDSA on Secp256K1 Curve\n * - ECDSA on Secp256R1 Curve\n * - BLS, Schnorr, etc\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface ISignatureMigrationFacet {\n event SignatureSchemeMigration(\n address indexed prevVerificationFacet,\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n event SignatureMigrationApproved(\n bytes newPublicKey,\n address indexed newVerificationFacet,\n bytes4[] verificationFuncSelectors,\n address indexed guardian,\n uint128 approvalValidUntil\n );\n event SignatureMigrationApprovalRevoked(\n bytes newPublicKey,\n address indexed newVerificationFacet,\n bytes4[] verificationFuncSelectors,\n address indexed guardian\n );\n event SignatureMigrationExecuted(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors,\n uint128 migrateAfter\n );\n event SignatureMigrationCanceled(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n event SignatureMigrationCancellationApproved(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n\n error SignatureMigrationFacet__SignerUninitializationFailure();\n error SignatureMigrationFacet__SignerInitializationFailure();\n error SignatureMigrationFacet__InvalidRouteWithGuardian();\n error SignatureMigrationFacet__InvalidKeyType();\n error SignatureMigrationFacet__InsufficientApprovers();\n error SignatureMigrationFacet__InvalidApproverSignature();\n error SignatureMigrationFacet__InvalidGuardian();\n error SignatureMigrationFacet__NonExistentApprover();\n error SignatureMigrationFacet__InvalidMigrationPeriod();\n error SignatureMigrationFacet__NonexistentMigration();\n error SignatureMigrationFacet__MigrationPeriodNotOver();\n error SignatureMigrationFacet__InvalidArrayLength();\n error SignatureMigrationFacet__InvalidApprovalValidationPeriod();\n error SignatureMigrationFacet__CannotRevokeUnapproved();\n error SignatureMigrationFacet__LackOfOwnerApproval();\n error SignatureMigrationFacet__OwnerAlreadyApproved();\n error SignatureMigrationFacet__NonExistentVerificationFacet();\n error SignatureMigrationFacet__DuplicateApproval();\n\n function migrateSignatureScheme(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function migrateSignatureSchemeWithGuardian(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors,\n address[] calldata approvers,\n bytes[] calldata signatures\n ) external;\n\n function approveSignatureSchemeMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function revokeSignatureMigrationApproval(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function finalizeSignatureMigration() external;\n\n function approveCancelSignatureMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function cancelSignatureMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function getApprovalMigrationKeyHash(\n bytes memory recoveryPublicKey,\n address newVerificationFacet,\n bytes4[] memory newVerificationFuncSelectors,\n string memory saltString\n ) external view returns (bytes32);\n\n function getMigrationOwnerApprovalWithTimeValidity(\n bytes32 publicKeyHash\n ) external view returns (bool);\n\n function getMigrationApprovalCountWithTimeValidity(\n bytes32 publicKeyHash\n ) external view returns (uint256);\n\n function isMigrationApproved(\n bytes32 migrationPublicKeyHash,\n address approver\n ) external view returns (bool);\n\n function getMigrationNonce() external view returns (uint128);\n\n function isMigrationPending() external view returns (bool);\n\n function getPendingMigration()\n external\n view\n returns (SignatureMigrationConfig memory);\n}\n" + }, + "contracts/facets/interfaces/IVerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {UserOperation} from \"../../aa-4337/interfaces/UserOperation.sol\";\n\n/**\n * @title Verification Facet Interface\n * @dev Implements logic for user ops signature verification\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface IVerificationFacet {\n event SignerInitialized(bytes);\n event SignerUninitialized();\n\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n error VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n error VerificationFacet__InitializationFailure();\n error VerificationFacet__InvalidFacetMapping();\n\n function initializeSigner(bytes memory) external returns (uint256);\n\n function uninitializeSigner() external returns (uint256);\n\n function validateOwnerSignatureSelector() external view returns (bytes4);\n\n function owner() external view returns (bytes memory);\n\n function isValidKeyType(bytes calldata) external view returns (bool);\n\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) external view returns (uint256);\n}\n" + }, + "contracts/facets/LockFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage, Lock} from \"../libraries/LibAppStorage.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibFacetStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {ILockFacet} from \"./interfaces/ILockFacet.sol\";\n\n/**\n * @title Lock Facet\n * @dev Contract that enables full lock/unlock of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract LockFacet is ILockFacet, Modifiers {\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Locks the account for the lock period. Lock period is defined in the security manager and it's customizable\n * This function can only be called when account is unlocked by owner or guardians\n * @dev This method checks the caller and if the account is currently locked and locks the account after fetching the\n * Lock period from the owner.\n */\n function lock() external override onlyGuardianOrOwner onlyWhenUnlocked {\n uint256 unlockTime = block.timestamp + getLockPeriod();\n unchecked {\n ++LibFacetStorage.lockStorage().nonce;\n }\n LibAppStorage.setLock(unlockTime, LockFacet.lock.selector);\n emit Locked(uint64(unlockTime));\n }\n\n /**\n * @notice Locks the account when the account is locked. This function can be called by anyone but must provide the approver address and signature.\n * The approver should be one of the guardians or owner.\n * @dev This method takes the approver address and the signature. After validating the address and the signature, it unlocks the account immediately.\n * Only one of the guardian or owner is required to lock and unlock the account.\n * @param _approver Address of approver approving the unlock of Barz account\n * @param _signature Signature of the approver that signed the msg hash for unlocking the account\n */\n function unlock(\n address _approver,\n bytes calldata _signature\n ) external override onlyWhenLocked {\n if (_approver != address(this) && !LibGuardian.isGuardian(_approver))\n revert LockFacet__InvalidApprover();\n if (\n !SignatureChecker.isValidSignatureNow(\n _approver,\n getUnlockHash(),\n _signature\n )\n ) revert LockFacet__InvalidSignature();\n _unlock();\n }\n\n /**\n * @notice Unlocks the account and increments the lock nonce\n */\n function _unlock() private {\n if (s.locks[INNER_STRUCT].locker != LockFacet.lock.selector)\n revert LockFacet__CannotUnlock();\n unchecked {\n ++LibFacetStorage.lockStorage().nonce;\n }\n LibAppStorage.setLock(0, bytes4(0));\n emit Unlocked();\n }\n\n /**\n * @notice Returns the lock period of current Barz account. Lock period information is held by Security Manager\n * @return lockPeriod Uint value of lock period in seconds\n */\n function getLockPeriod() public view override returns (uint256 lockPeriod) {\n lockPeriod = securityManager.lockPeriodOf(address(this));\n if (lockPeriod == 0) revert LockFacet__InvalidRecoveryPeriod();\n }\n\n /**\n * @notice Returns if the account is locked or not\n * @dev This method fetches the current block timestamp and compares that with release time.\n * After checking the timestamp and release time, it returns if the account is still locked or not.\n * @return isLocked_ Uint value of lock period in seconds\n */\n function isLocked() public view override returns (bool isLocked_) {\n isLocked_ = uint64(block.timestamp) < s.locks[INNER_STRUCT].release;\n }\n\n /**\n * @notice Calculates the unlock hash and returns the unlock hash safe from signature reply attack\n * @dev This method calculates the unlock hash with EIP-191 prefix, wallet address, chainID, and nonce\n * It packs the result and packs them and hashes it.\n * @return unlockHash Bytes32 unlock hash\n */\n function getUnlockHash() public view override returns (bytes32 unlockHash) {\n unlockHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n \"Unlock\",\n address(this),\n block.chainid,\n lockNonce()\n )\n )\n )\n );\n }\n\n /**\n * @notice Returns lock nonce of account. Reads nonce from lock storage within facet storage\n * @return lockNonce_ Uint128 value of lock nonce. This is incremented whenever the account is lock/unlocked\n */\n function lockNonce() public view override returns (uint128 lockNonce_) {\n lockNonce_ = LibFacetStorage.lockStorage().nonce;\n }\n\n /**\n * @notice Returns the overall information of current lock\n * @return pendingLock Struct value including all information of pending lock\n */\n function getPendingLock()\n public\n view\n override\n returns (Lock memory pendingLock)\n {\n pendingLock = s.locks[INNER_STRUCT];\n }\n}\n" + }, + "contracts/facets/Modifiers.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\n\n/**\n * @title Modifiers\n * @dev Responsible for providing modifiers/util functions to Facet contracts\n * @author David Yongjun Kim (@Powerstream3604)\n */\nabstract contract Modifiers is BarzStorage {\n uint8 constant INNER_STRUCT = 0;\n\n error CallerNotGuardian();\n error CallerNotGuardianOrOwner();\n error DuplicateApprover();\n error ZeroApproverLength();\n error UnregisteredFacetAndSelectors();\n\n /**\n * @notice Modifier to only allow guardian to make a call, reverts if any other entity is the caller\n */\n modifier onlyGuardian() {\n if (!LibGuardian.isGuardian(msg.sender)) revert CallerNotGuardian();\n _;\n }\n\n /**\n * @notice Modifier to only allow guardian or owner to make a call, reverts if any other entity is the caller\n */\n modifier onlyGuardianOrOwner() {\n if (!LibGuardian.isGuardian(msg.sender) && address(this) != msg.sender)\n revert CallerNotGuardianOrOwner();\n _;\n }\n\n /**\n * @notice Checks if the approver address is the array is unique with no duplicate\n * @dev This method loops through the array and checks if a duplicate address exists, it reverts if duplicate address exists\n * @param approvers Array of address\n */\n function _checkApprover(\n address[] memory approvers\n ) internal pure returns (bool) {\n uint256 approverLength = approvers.length;\n if (0 == approverLength) revert ZeroApproverLength();\n for (uint256 i; i < approverLength - 1; ) {\n for (uint256 j = i + 1; j < approverLength; ) {\n if (approvers[i] == approvers[j]) {\n revert DuplicateApprover(); // Found a duplicate\n }\n unchecked {\n ++j;\n }\n }\n unchecked {\n ++i;\n }\n }\n return false; // No duplicates found\n }\n\n /**\n * @notice Checks if the facet getting added or replaced is registered to facet registry\n * @dev This method loops through the cut and checks if the facet getting added/replaced is registered to facet registry\n * @param _diamondCut Array of FacetCut, data for diamondCut defined in EIP-2535\n */\n function _checkFacetCutValidity(\n IDiamondCut.FacetCut[] memory _diamondCut\n ) internal view {\n uint256 diamondCutLength = _diamondCut.length;\n for (uint256 i; i < diamondCutLength; ) {\n if (\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Add ||\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Replace\n ) {\n if (\n !s.facetRegistry.areFacetFunctionSelectorsRegistered(\n _diamondCut[i].facetAddress,\n _diamondCut[i].functionSelectors\n )\n ) revert UnregisteredFacetAndSelectors();\n }\n unchecked {\n ++i;\n }\n }\n }\n}\n" + }, + "contracts/facets/ReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibReentrancyGuardStorage, ReentrancyGuardStorage} from \"../libraries/LibReentrancyGuardStorage.sol\";\n\nabstract contract ReentrancyGuard {\n\n uint256 private constant _NOT_ENTERED = 0;\n uint256 private constant _ENTERED = 1;\n\n error ReentrancyGuard__ReentrantCall();\n\n modifier nonReentrant() {\n ReentrancyGuardStorage storage rgs = LibReentrancyGuardStorage.reentrancyguardStorage();\n\n if (rgs.status == _ENTERED) revert ReentrancyGuard__ReentrantCall();\n\n rgs.status = _ENTERED;\n\n _; // Execute function\n\n rgs.status = _NOT_ENTERED;\n }\n}\n" + }, + "contracts/facets/RestrictionsFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ReentrancyGuard} from \"./ReentrancyGuard.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, RestrictionsStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {IRestriction} from \"../restrictions/IRestriction.sol\";\nimport {IRestrictionsFacet} from \"./interfaces/IRestrictionsFacet.sol\";\n\n/**\n * @title Restrictions facet\n * @dev Responsible for storing and verifying different kinds of restrictions, for example:\n * - Whitelist / Blacklist\n * - Daily limits\n * - Trading time restrictions\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract RestrictionsFacet is IRestrictionsFacet, ReentrancyGuard {\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceRestrictionsInitialize();\n }\n\n /**\n * @notice Intialize restrictions of Barz. Restrictions facet call restriction contracts for restriction validation\n * before each call\n * @param _restrictions The initial array of restrictions.\n * @return initSuccess Int value showing if the initialization of restriction is successful\n */\n function initializeRestrictions(\n address[] calldata _restrictions\n ) public override returns (uint256 initSuccess) {\n LibDiamond.enforceIsSelf();\n LibAppStorage.enforceRestrictionsInitialize();\n\n if (_restrictions.length == 0) {\n // You can't initialize RestrictionsFacet with an empty list of restrictions\n revert RestrictionsFacet__EmptyRestrictionsList();\n }\n for (uint256 i; i < _restrictions.length; ) {\n if (_restrictions[i] == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictions();\n unchecked {\n ++i;\n }\n }\n\n LibFacetStorage.restrictionsStorage().restrictions = _restrictions;\n _updateRestrictionsMap(_restrictions, true);\n initSuccess = 1;\n }\n\n /**\n * @notice Unitialize restrictions of Barz\n * @return uninitSuccess Int value showing if the initialization of restriction is successful\n */\n function uninitializeRestrictions()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibDiamond.enforceIsSelf();\n LibAppStorage.setRestrictionsUninitialized();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n _updateRestrictionsMap(restrictionsStorage.restrictions, false);\n restrictionsStorage.restrictions = new address[](0);\n uninitSuccess = 1;\n }\n\n /**\n * @notice Returns the list of Restrictions contract address\n * @return restrictions Addresses of IRestriction which are currently active\n */\n function getRestrictions()\n public\n view\n override\n returns (address[] memory restrictions)\n {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n restrictions = restrictionsStorage.restrictions;\n }\n\n /**\n * @notice Adds restrictions to Barz with validation on the restriction contract address.\n * This method is only callable by the owner(self).\n * @param _restriction The address of the restriction to be added.\n */\n function addRestriction(address _restriction) external override {\n LibDiamond.enforceIsSelf();\n if (LibDiamond.restrictionsFacet() == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictionsFacet();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n if (_restriction == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictions();\n if (restrictionsStorage.exists[_restriction])\n revert RestrictionsFacet__RestrictionAlreadyExists();\n\n restrictionsStorage.restrictions.push(_restriction);\n restrictionsStorage.exists[_restriction] = true;\n\n emit RestrictionAdded(_restriction);\n }\n\n /**\n * @notice Remove restrictions from Barz if it existed. This method is only callable by the owner(self).\n * @param _restriction The address of the restriction to be removed.\n */\n function removeRestriction(address _restriction) external override {\n LibDiamond.enforceIsSelf();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n if (!restrictionsStorage.exists[_restriction])\n revert RestrictionsFacet__RestrictionNotFound();\n\n address[] storage restrictions = restrictionsStorage.restrictions;\n\n uint256 indexToDelete = restrictions.length;\n uint256 restrictionsLen = restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n if (restrictions[i] == _restriction) {\n indexToDelete = i;\n break;\n }\n unchecked {\n ++i;\n }\n }\n\n if (indexToDelete == 0 && restrictionsLen == 1) {\n revert RestrictionsFacet__RemainingRestrictionsCantBeEmpty();\n } else if (indexToDelete == restrictionsLen) {\n revert RestrictionsFacet__RestrictionNotFound();\n } else {\n restrictions[indexToDelete] = restrictions[restrictionsLen - 1];\n restrictions.pop();\n }\n\n restrictionsStorage.exists[_restriction] = false;\n emit RestrictionRemoved(_restriction);\n }\n\n /**\n * @notice Sets the restrictions address value mapping to true or false when adding/removing restriction contracts\n * @param _restrictions List of restriction contracts address\n * @param _newValue Bool value to flag to the list of restrictions contracts\n */\n function _updateRestrictionsMap(\n address[] memory _restrictions,\n bool _newValue\n ) internal {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n uint restrictionsLen = _restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n restrictionsStorage.exists[_restrictions[i]] = _newValue;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @dev Iterates over all restrictions and verifies each of them with the transaction parameters.\n * @param _from The address of the sender, that will be signing the transaction.\n * @param _to The receiving address.\n * @param _value Amount of ETH to transfer from sender to recipient.\n * @param _calldata Optional field to include arbitrary data.\n * @return 0 if all the checks passed, 1 otherwise.\n */\n function verifyRestrictions(\n address _from,\n address _to,\n uint256 _value,\n bytes calldata _calldata\n ) external nonReentrant returns (uint256) {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n uint restrictionsLen = restrictionsStorage.restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n IRestriction restriction = IRestriction(\n restrictionsStorage.restrictions[i]\n );\n bool checkPassed = restriction.check(_from, _to, _value, _calldata);\n if (!checkPassed) {\n return 1;\n }\n unchecked {\n ++i;\n }\n }\n\n return 0;\n }\n}\n" + }, + "contracts/facets/SignatureMigrationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, SignatureMigrationStorage, SignatureMigrationConfig, SignatureMigrationApprovalConfig, ApprovalConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IDiamondCut} from \"./base/interfaces/IDiamondCut.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {ISignatureMigrationFacet} from \"./interfaces/ISignatureMigrationFacet.sol\";\n\n/**\n * @title Signature Migration Facet\n * @dev Responsible for migrating user signature scheme to a new scheme user sets\n * Which could include\n * - ECDSA on Secp256K1 Curve\n * - ECDSA on Secp256R1 Curve\n * - BLS, Schnorr, etc\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract SignatureMigrationFacet is ISignatureMigrationFacet, Modifiers {\n bytes constant UNINIT_CALL =\n abi.encodeWithSignature(\"uninitializeSigner()\");\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This modifier verifies if the public key format matches with the new verification facet\n * @param _publicKey Bytes of public key to be validated for the new verification facet\n * @param _newVerificationFacet Address of new verification facet\n */\n modifier validateKeyType(\n bytes memory _publicKey,\n address _newVerificationFacet\n ) {\n if (\n !IVerificationFacet(_newVerificationFacet).isValidKeyType(\n _publicKey\n )\n ) revert SignatureMigrationFacet__InvalidKeyType();\n _;\n }\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n // IMPORTANT NOTE: In the client side when they call this function, the func selectors should be sorted in ascending order\n // to prevent different hash with same items in the array\n /**\n * @notice Moves the state of migration to a pending state. When pending state is over after pending period time,\n * Migration can be finalized. This function can only be called by self and when the account is unlocked.\n * @dev This method checks if the caller is self and if guardians exists. It migrates signature request to a pending state\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function migrateSignatureScheme(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n public\n override\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n // Only self contract can call this function\n LibDiamond.enforceIsSelf();\n // Should revert if guardian exist\n if (0 != LibGuardian.guardianCount())\n revert SignatureMigrationFacet__InvalidRouteWithGuardian();\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n // NOTE: Migration requires a pending period & confirmation from owner to prevent a\n // single call changing the ownership of the wallet\n /**\n * @notice Migrate signature scheme when guardians exists. Verifies the signature of guardians and moves migration to pending state.\n * Which can then be finalized when pending period is over. Owner's approval is mandatory for migration to happen\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _approvers List of approvers. This could include owner\n */\n function migrateSignatureSchemeWithGuardian(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n )\n public\n override\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n // Should revert if does not guardian exist\n if (0 == LibGuardian.guardianCount())\n revert SignatureMigrationFacet__InvalidRouteWithGuardian();\n if (_approvers.length != _signatures.length)\n revert SignatureMigrationFacet__InvalidArrayLength();\n\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(migrationPublicKeyHash, _approvers);\n\n bool onChainOwnerApproval = getMigrationOwnerApprovalWithTimeValidity(\n migrationPublicKeyHash\n );\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n\n if (\n _approvers.length +\n getMigrationApprovalCountWithTimeValidity(\n migrationPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert SignatureMigrationFacet__InsufficientApprovers();\n {\n // To prevent Stack too deep\n bool ownerApproved;\n for (uint256 i; i < _approvers.length; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n address(this) != _approvers[i]\n ) revert SignatureMigrationFacet__InvalidGuardian();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert SignatureMigrationFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n migrationPublicKeyHash,\n _signatures[i]\n )\n ) revert SignatureMigrationFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n\n if (!ownerApproved && !onChainOwnerApproval)\n revert SignatureMigrationFacet__LackOfOwnerApproval();\n }\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Internal function that moves signature mgiration to a pending state.\n * @dev This method increments migration nonce and sets the migration in the migration config. Emits events for migration execution\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _migrateSignatureScheme(\n address _newVerificationFacet,\n bytes memory _newPublicKey,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal {\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n unchecked {\n ++ms.nonce;\n }\n uint64 migrateAfter = uint64(block.timestamp + getMigrationPeriod());\n\n ms.migrationConfigs[INNER_STRUCT] = SignatureMigrationConfig(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n migrateAfter\n );\n\n emit SignatureMigrationExecuted(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors,\n migrateAfter\n );\n }\n\n /**\n * @notice Approves signature scheme migration on-chain. This can be called by owner or guardian only when the account is unlocked.\n * When the threshold of the migration approval passed and owner approval is granted, it automatically moves migration to a pending state\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function approveSignatureSchemeMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n public\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit SignatureMigrationApproved(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n msg.sender,\n approvalValidUntil\n );\n if (\n getMigrationApprovalCountWithTimeValidity(migrationPublicKeyHash) >=\n LibGuardian.majorityOfGuardians() &&\n getMigrationOwnerApprovalWithTimeValidity(migrationPublicKeyHash)\n )\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Revokes the approval of signature migration done on-chain. Emits revoke event when revoked.\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function revokeSignatureMigrationApproval(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n external\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n if (!isMigrationApproved(migrationPublicKeyHash, msg.sender))\n revert SignatureMigrationFacet__CannotRevokeUnapproved();\n\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(false, 0);\n emit SignatureMigrationApprovalRevoked(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n msg.sender\n );\n }\n\n /**\n * @notice Finalizes the pending signature scheme migration. This function can only be called by owner.\n * It removes the facets of the previous verification facet and adds the new verification facet.\n * After finalizing migration, it emits migration event which shows the change of the verification facet\n */\n function finalizeSignatureMigration() external override {\n // NOTE: Only owner can call this function\n LibDiamond.enforceIsSelf();\n\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n\n if (!isMigrationPending())\n revert SignatureMigrationFacet__NonexistentMigration();\n\n if (\n uint64(block.timestamp) <=\n ms.migrationConfigs[INNER_STRUCT].migrateAfter\n ) revert SignatureMigrationFacet__MigrationPeriodNotOver();\n address newVerificationFacet = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationVerificationFacet;\n bytes4[] memory newVerificationFuncSelectors = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationSelectors;\n bytes memory newPublicKey = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationPublicKey;\n\n address prevVerificationFacet = LibLoupe.facetAddress(\n s.validateOwnerSignatureSelector\n );\n if (prevVerificationFacet == address(0))\n revert SignatureMigrationFacet__NonExistentVerificationFacet();\n\n IDiamondCut.FacetCut[] memory UninitCut;\n IDiamondCut.FacetCut[] memory InitCut;\n {\n bytes4[] memory prevVerificationFuncSelectors = LibLoupe\n .facetFunctionSelectors(prevVerificationFacet);\n\n UninitCut = new IDiamondCut.FacetCut[](1);\n InitCut = new IDiamondCut.FacetCut[](1);\n UninitCut[0] = IDiamondCut.FacetCut({\n facetAddress: address(0),\n action: IDiamondCut.FacetCutAction.Remove,\n functionSelectors: prevVerificationFuncSelectors\n });\n InitCut[0] = IDiamondCut.FacetCut({\n facetAddress: newVerificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: newVerificationFuncSelectors\n });\n {\n IDiamondCut.FacetCut[]\n memory facetCuts = new IDiamondCut.FacetCut[](2);\n facetCuts[0] = UninitCut[0];\n facetCuts[1] = InitCut[0];\n _checkFacetCutValidity(facetCuts);\n }\n LibAppStorage.initiateSignerMigration();\n address verificationFacet = address(\n bytes20(\n LibDiamond.diamondStorage().facets[\n s.validateOwnerSignatureSelector\n ]\n )\n );\n\n (bool uninitSuccess, bytes memory uninitResult) = verificationFacet\n .delegatecall(UNINIT_CALL);\n if (!uninitSuccess || uint256(bytes32(uninitResult)) != 1)\n revert SignatureMigrationFacet__SignerUninitializationFailure();\n LibAppStorage.finalizeSignerMigration();\n\n LibDiamond.diamondCut(UninitCut, address(0), \"\");\n }\n {\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n newPublicKey\n );\n\n // Every Verification Facet should comply with initializeSigner(bytes)\n // to be compatible with the Barz contract(for initialization)\n LibDiamond.diamondCut(InitCut, address(0), \"\");\n (bool initSuccess, bytes memory initResult) = newVerificationFacet\n .delegatecall(initCall);\n if (!initSuccess || uint256(bytes32(initResult)) != 1)\n revert SignatureMigrationFacet__SignerInitializationFailure();\n\n emit SignatureSchemeMigration(\n prevVerificationFacet,\n newVerificationFacet,\n newPublicKey,\n newVerificationFuncSelectors\n );\n }\n }\n\n /**\n * @notice Approve cancellation of signature migration. If cancellation approval passes guardian threshold with owner approval\n * it automatically cancels the migration.\n * @dev This method checks if the caller is one of guardian or owner and sets true for the cancellation hash in the approval config.\n * It internally calls _cancelSignatureMigration for canceling the migration\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function approveCancelSignatureMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n external\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"CancelSignatureMigration\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit SignatureMigrationCancellationApproved(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n if (\n getMigrationApprovalCountWithTimeValidity(migrationPublicKeyHash) >=\n LibGuardian.majorityOfGuardians() &&\n getMigrationOwnerApprovalWithTimeValidity(migrationPublicKeyHash)\n )\n _cancelSignatureMigration(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Verifies the signature of guardians/owner and cancels the signature migration.\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _approvers List of approvers. This could include owner\n */\n function cancelSignatureMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n )\n external\n override\n validateKeyType(_newPublicKey, _newVerificationFacet)\n onlyWhenUnlocked\n {\n if (_approvers.length != _signatures.length)\n revert SignatureMigrationFacet__InvalidArrayLength();\n\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"CancelSignatureMigration\"\n );\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(migrationPublicKeyHash, _approvers);\n\n bool onChainOwnerApproval = getMigrationOwnerApprovalWithTimeValidity(\n migrationPublicKeyHash\n );\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n if (\n _approvers.length +\n getMigrationApprovalCountWithTimeValidity(\n migrationPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert SignatureMigrationFacet__InsufficientApprovers();\n {\n // To prevent stack too deep\n bool ownerApproved;\n for (uint256 i; i < _approvers.length; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n address(this) != _approvers[i]\n ) revert SignatureMigrationFacet__NonExistentApprover();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert SignatureMigrationFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n migrationPublicKeyHash,\n _signatures[i]\n )\n ) revert SignatureMigrationFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n if (!ownerApproved && !onChainOwnerApproval)\n revert SignatureMigrationFacet__LackOfOwnerApproval();\n }\n _cancelSignatureMigration(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Internal function that cancels signature migration.\n * @dev This method increments migration nonce and deletes the migration from the migration config. Emits events for migration cancellation\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _cancelSignatureMigration(\n address _newVerificationFacet,\n bytes memory _newPublicKey,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal {\n if (!isMigrationPending())\n revert SignatureMigrationFacet__NonexistentMigration();\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n unchecked {\n ++ms.nonce;\n }\n delete ms.migrationConfigs[INNER_STRUCT];\n emit SignatureMigrationCanceled(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Checks if the facets to be added from new verification facet is registered to facet registry\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _checkMigrationCutValidity(\n address _newVerificationFacet,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal view {\n IDiamondCut.FacetCut[] memory facetCuts = new IDiamondCut.FacetCut[](1);\n facetCuts[0] = IDiamondCut.FacetCut({\n facetAddress: _newVerificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: _newVerificationFuncSelectors\n });\n _checkFacetCutValidity(facetCuts);\n }\n\n /**\n * @notice Returns if the migration is pending of not\n * @dev This method fetches the migration storage and checks if the migrate after is above 0 value\n * @return isPending Bool value that shows if the migration is pending\n */\n function isMigrationPending()\n public\n view\n override\n returns (bool isPending)\n {\n SignatureMigrationStorage storage rs = LibFacetStorage\n .migrationStorage();\n isPending = rs.migrationConfigs[INNER_STRUCT].migrateAfter > 0;\n }\n\n /**\n * @notice Returns the migration hash. This function ensures that this hash is safe from replay attack by including\n * public key, verification facet, function selectors, salt, address, chainId, and nonce.\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _saltString Salt value for generating the migration hash\n * @return migrationKeyHash Bytes32 string of the migration key hash\n */\n function getApprovalMigrationKeyHash(\n bytes memory _newPublicKey,\n address _newVerificationFacet,\n bytes4[] memory _newVerificationFuncSelectors,\n string memory _saltString\n ) public view override returns (bytes32 migrationKeyHash) {\n migrationKeyHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n _newPublicKey,\n _newVerificationFacet,\n keccak256(abi.encode(_newVerificationFuncSelectors)),\n _saltString,\n address(this),\n block.chainid,\n LibFacetStorage.migrationStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Checks if the owner approved the hash for migration\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @return isApprovedByOwner Bool value of showing if the owner approved it or not\n */\n function getMigrationOwnerApprovalWithTimeValidity(\n bytes32 _migrationPublicKeyHash\n ) public view override returns (bool isApprovedByOwner) {\n isApprovedByOwner = isMigrationApproved(\n _migrationPublicKeyHash,\n address(this)\n );\n }\n\n /**\n * @notice Checks how many of the guardians approved the migration hash\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @return approvalCount Number of approvals\n */\n function getMigrationApprovalCountWithTimeValidity(\n bytes32 _migrationPublicKeyHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardiansLength = guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n if (isMigrationApproved(_migrationPublicKeyHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n return approvalCount;\n }\n\n /**\n * @notice Checks if the migration is approved by the given approver\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @param _approver Address of approver\n * @return isApproved Bool value if migration hash is approved\n */\n function isMigrationApproved(\n bytes32 _migrationPublicKeyHash,\n address _approver\n ) public view override returns (bool isApproved) {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n isApproved = (ms\n .isMigrationApproved[_migrationPublicKeyHash][_approver].isApproved &&\n block.timestamp <\n ms\n .isMigrationApproved[_migrationPublicKeyHash][_approver]\n .validUntil);\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _migrationPublicKeyHash Hash of migration information\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _migrationPublicKeyHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isMigrationApproved(_migrationPublicKeyHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert SignatureMigrationFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the migration period of this wallet\n * @dev This method fetches the migration period from the security manager\n * @return migrationPeriod Migration period of Barz contract fetched from security manager\n */\n function getMigrationPeriod()\n internal\n view\n returns (uint128 migrationPeriod)\n {\n migrationPeriod = securityManager.migrationPeriodOf(address(this));\n if (migrationPeriod == 0)\n revert SignatureMigrationFacet__InvalidMigrationPeriod();\n }\n\n /**\n * @notice Returns the validation period of this wallet\n * @dev This method fetches the validation period from the security manager\n * @return approvalValidationPeriod Validation period of Barz contract fetched from security manager\n */\n function getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod == 0)\n revert SignatureMigrationFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the migration nonce of this wallet\n * @dev This method fetches the nonce from migration storage\n * @return migrationNonce Nonce of migration to protect from reply attacks\n */\n function getMigrationNonce()\n public\n view\n override\n returns (uint128 migrationNonce)\n {\n migrationNonce = LibFacetStorage.migrationStorage().nonce;\n }\n\n /**\n * @notice Returns the migration configuration of this wallet\n * @dev This method fetches the migration config from the migration storage\n * @return pendingMigrationConfig Migration config currently pending for signature migration\n */\n function getPendingMigration()\n external\n view\n override\n returns (SignatureMigrationConfig memory pendingMigrationConfig)\n {\n pendingMigrationConfig = LibFacetStorage\n .migrationStorage()\n .migrationConfigs[INNER_STRUCT];\n }\n}\n" + }, + "contracts/facets/TokenReceiverFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {IERC1155Receiver} from \"../interfaces/ERC/IERC1155Receiver.sol\";\nimport {IERC677Receiver} from \"../interfaces/ERC/IERC677Receiver.sol\";\n\n/**\n * @title TokenReceiver Facet\n * @dev Contract that enables receiving ERC721/ERC1155/ERC777/ERC677 Tokens with safe transfer\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract TokenReceiverFacet is\n IERC721Receiver,\n IERC1155Receiver,\n IERC777Recipient,\n IERC677Receiver\n{\n /**\n * @notice Handles ERC721 Token callback.\n * return Standardized onERC721Received return value.\n */\n function onERC721Received(\n address,\n address,\n uint256,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC721Receiver.onERC721Received.selector;\n }\n\n /**\n * @notice Handles ERC1155 Token callback.\n * return Standardized onERC1155Received return value.\n */\n function onERC1155Received(\n address,\n address,\n uint256,\n uint256,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC1155Receiver.onERC1155Received.selector;\n }\n\n /**\n * @notice Handles ERC1155 Token batch callback.\n * return Standardized onERC1155BatchReceived return value.\n */\n function onERC1155BatchReceived(\n address,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC1155Receiver.onERC1155BatchReceived.selector;\n }\n\n /**\n * @notice Handles ERC777 Token callback.\n * Does not return value, empty implementation.\n */\n function tokensReceived(\n address,\n address,\n address,\n uint256,\n bytes calldata,\n bytes calldata\n ) external pure override {}\n\n /**\n * @notice Handles ERC677 Token callback.\n * return true.\n */\n function onTokenTransfer(\n address,\n uint256,\n bytes calldata\n ) external pure override returns (bool) {\n return true;\n }\n}\n" + }, + "contracts/facets/verification/MultiSigFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {UserOperation} from \"../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../../libraries/LibLoupe.sol\";\nimport {LibAppStorage} from \"../../libraries/LibAppStorage.sol\";\nimport {LibMultiSigStorage, MultiSigStorage} from \"../../libraries/LibMultiSigStorage.sol\";\nimport {IERC1271} from \"../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../interfaces/IVerificationFacet.sol\";\nimport {IMultiSigFacet} from \"../interfaces/IMultiSigFacet.sol\";\n\n/**\n * @title Multi-sig facet\n * @dev Multi-signature Facet with custom threshold.\n * Wallet that adds this facet becomes a multi-sig wallet.\n * Reference signature_format.md documentation for Multi-sig facet details\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract MultiSigFacet is IMultiSigFacet, IVerificationFacet, IERC1271 {\n using ECDSA for bytes32;\n\n address public immutable self;\n\n address internal constant SENTINEL_OWNERS = address(0x1);\n uint256 internal constant ADDRESS = 20;\n uint256 internal constant SIG_TYPE = 1;\n uint256 internal constant SIG_LEN = 4;\n uint256 internal constant THRESHOLD = 4;\n uint256 internal constant INVALID_SIG = 1;\n uint256 internal constant VALID_SIG = 0;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in Multisig Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the right format and initializes signer storage in k1 storage.\n * @param _owners Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _owners\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n\n if (!isValidKeyType(_owners)) revert MultiSigFacet__InvalidInitData();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n uint256 threshold = uint256(uint32(bytes4(_owners)));\n uint256 ownerCount = (_owners.length - THRESHOLD) / ADDRESS;\n\n if (threshold == 0) revert MultiSigFacet__InvalidThreshold();\n if (ownerCount == 0) revert MultisigFacet__InvalidOwnerCount();\n\n address currentOwner = SENTINEL_OWNERS;\n uint256 ptr = THRESHOLD;\n address owner_;\n for (uint256 i; i < ownerCount; ) {\n owner_ = address(bytes20(_owners[ptr:ptr + ADDRESS]));\n ptr += ADDRESS;\n if (\n owner_ == address(0) ||\n owner_ == SENTINEL_OWNERS ||\n owner_ == address(this) ||\n owner_ == currentOwner\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[owner_] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n\n ms.owners[currentOwner] = owner_;\n currentOwner = owner_;\n\n unchecked {\n ++i;\n }\n }\n ms.owners[currentOwner] = SENTINEL_OWNERS;\n ms.ownerCount = ownerCount;\n ms.threshold = threshold;\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_owners);\n }\n\n /**\n * @notice Uninitialize signer in K1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n ++ms.counter;\n address[] memory ownerlist = getOwners();\n uint256 ownerlistLength = ownerlist.length;\n for (uint256 i; i < ownerlistLength; ) {\n ms.owners[ownerlist[i]] = address(0);\n unchecked {\n ++i;\n }\n }\n ms.owners[SENTINEL_OWNERS] = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls checkSignatures with\n * user operation hash and signature together with the threshold.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n // Data 1 is invalid, Data 0 is valid\n validationData = checkSignatures(\n userOpHash,\n userOp.signature,\n LibMultiSigStorage.multisigStorage().threshold\n );\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n return this.validateOwnerSignature.selector;\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n uint totalLength = ms.ownerCount * ADDRESS;\n bytes memory result = new bytes(totalLength);\n\n // populate return array\n uint256 index;\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n while (currentOwner != SENTINEL_OWNERS) {\n assembly {\n mstore(\n add(result, add(32, mul(index, ADDRESS))),\n shl(96, currentOwner)\n )\n }\n currentOwner = ms.owners[currentOwner];\n index++;\n }\n\n return result;\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key should comply with the format in the signature_format.md doc\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n uint256 publicKeyLength = _publicKey.length;\n if (\n publicKeyLength < ADDRESS + THRESHOLD ||\n (publicKeyLength - THRESHOLD) % ADDRESS != 0\n ) return false;\n\n uint256 threshold = uint256(uint32(bytes4(_publicKey)));\n uint256 ownerCount = (publicKeyLength - THRESHOLD) / ADDRESS;\n\n isValid = !(ownerCount < threshold || threshold == 0);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes calldata _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (checkSignatures(\n _hash,\n _signature,\n LibMultiSigStorage.multisigStorage().threshold\n ) == VALID_SIG)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n\n /**\n * @notice Validates the format of the signature and verifies if the signature is signed by the expected key.\n * Reference signature_format.md doc for details about signature format and signature types\n * @param _dataHash Bytes value of data hash signed by the owners\n * @param _signatures Bytes value of signature which should comply with signature format\n * @param _threshold Uint256 value of current Multi-sig Barz's threshold\n */\n function checkSignatures(\n bytes32 _dataHash,\n bytes calldata _signatures,\n uint256 _threshold\n ) public view returns (uint256) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n address lastOwner = address(0);\n address currentOwner;\n bytes memory signature;\n uint256 signatureType;\n uint256 nextOffset;\n uint256 i;\n for (i; i < _threshold; ) {\n (\n currentOwner,\n signature,\n signatureType,\n nextOffset\n ) = splitSignatures(_signatures, nextOffset);\n if (nextOffset == 0 && i + 1 < _threshold) return INVALID_SIG;\n if (signatureType == 1) {\n // If signatureType is 1 then it is default dataHash signed.\n // This also includes the contract signature\n if (\n !SignatureChecker.isValidSignatureNow(\n currentOwner,\n _dataHash,\n signature\n )\n ) return INVALID_SIG;\n } else if (signatureType == 2) {\n // If signatureType is 2 then it is an approved hash\n if (ms.approvedHashes[ms.counter][currentOwner][_dataHash] == 0)\n return INVALID_SIG;\n } else if (signatureType == 3) {\n // If signatureType is 3 then it is a signed message hash\n // This also includes the contract signature\n bytes32 msgHash = _dataHash.toEthSignedMessageHash();\n if (\n !SignatureChecker.isValidSignatureNow(\n currentOwner,\n msgHash,\n signature\n )\n ) return INVALID_SIG;\n } else revert MultiSigFacet__InvalidRoute();\n if (\n currentOwner <= lastOwner ||\n ms.owners[currentOwner] == address(0) ||\n currentOwner == SENTINEL_OWNERS\n ) return INVALID_SIG;\n lastOwner = currentOwner;\n\n unchecked {\n ++i;\n }\n }\n return VALID_SIG;\n }\n\n /**\n * @notice Split signatures into each individual signatures. Should comply with signature format to be split\n * @param _signatures Bytes value of signature\n * @param _nextOffset Uint256 value of next offset to start splitting the signature\n */\n function splitSignatures(\n bytes calldata _signatures,\n uint256 _nextOffset\n )\n public\n pure\n returns (\n address owner_,\n bytes memory signature,\n uint256 signatureType,\n uint256 nextOffset\n )\n {\n uint256 signaturesLength = _signatures.length;\n\n if (signaturesLength <= _nextOffset + ADDRESS + SIG_LEN)\n revert MultiSigFacet__InsufficientSignerLength();\n\n owner_ = address(\n bytes20(_signatures[_nextOffset:_nextOffset + ADDRESS])\n );\n\n signatureType = uint256(\n uint8(\n bytes1(\n _signatures[_nextOffset + ADDRESS:_nextOffset +\n ADDRESS +\n SIG_TYPE]\n )\n )\n );\n\n if (signatureType > 3 || signatureType == 0)\n revert MultiSigFacet__InvalidSignatureType();\n uint256 offSet = _nextOffset + ADDRESS + SIG_TYPE;\n uint256 siglen = uint256(\n uint32(bytes4(_signatures[offSet:offSet + SIG_LEN]))\n );\n if (offSet + siglen > signaturesLength)\n revert MultiSigFacet__InvalidSignatureLength();\n\n offSet += SIG_LEN;\n if (offSet + siglen == signaturesLength) nextOffset = 0;\n else nextOffset = offSet + siglen;\n\n signature = _signatures[offSet:offSet + siglen];\n }\n\n /**\n * @notice Approves the hash of userOperation on-chain. This can only be called by owners.\n * @param _hashToApprove Bytes value of UserOperation hash to approve\n */\n function approveHash(bytes32 _hashToApprove) external {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (ms.owners[msg.sender] == address(0))\n revert MultiSigFacet__OnlyOwner();\n\n ms.approvedHashes[ms.counter][msg.sender][_hashToApprove] = 1;\n emit HashApproved(_hashToApprove, msg.sender);\n }\n\n /**\n * @notice Add owner to Barz. Update thresold if threshold is given different from current threshold\n * @dev This can only be done via a Self call.\n * @param _newOwner Address of new owner to be added\n * @param _threshold Uint256 value of threshold\n */\n function addOwner(address _newOwner, uint256 _threshold) external {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (\n _newOwner == address(0) ||\n _newOwner == SENTINEL_OWNERS ||\n _newOwner == address(this)\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_newOwner] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n\n ms.owners[_newOwner] = ms.owners[SENTINEL_OWNERS];\n ms.owners[SENTINEL_OWNERS] = _newOwner;\n ++ms.ownerCount;\n emit OwnerAdded(_newOwner);\n\n if (ms.threshold != _threshold) changeThreshold(_threshold);\n }\n\n /**\n * @notice Remove owner from Barz. Update thresold if threshold is given different from current threshold\n * @dev This can only be done via a Self call.\n * @param _prevOwner Address of owner located right behind the removed owner address in the linked list\n * @param _removedOwner Address of owner to be removed\n * @param _threshold Uint256 value of threshold\n */\n function removeOwner(\n address _prevOwner,\n address _removedOwner,\n uint256 _threshold\n ) external {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (ms.ownerCount - 1 < _threshold)\n revert MultiSigFacet__InvalidThreshold();\n if (_removedOwner == address(0) || _removedOwner == SENTINEL_OWNERS)\n revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_prevOwner] != _removedOwner)\n revert MultiSigFacet__InvalidOwnerPair();\n\n ms.owners[_prevOwner] = ms.owners[_removedOwner];\n ms.owners[_removedOwner] = address(0);\n --ms.ownerCount;\n emit OwnerRemoved(_removedOwner);\n\n if (ms.threshold != _threshold) changeThreshold(_threshold);\n }\n\n /**\n * @notice Swap owner in Barz.\n * @dev This can only be done via a Self call.\n * @param _prevOwner Address of owner located right behind the removed owner address in the linked list\n * @param _oldOwner Address of owner to be removed\n * @param _newOwner Address of owner to be added\n */\n function swapOwner(\n address _prevOwner,\n address _oldOwner,\n address _newOwner\n ) public {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (\n _newOwner == address(0) ||\n _newOwner == SENTINEL_OWNERS ||\n _newOwner == address(this)\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_newOwner] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n if (_oldOwner == address(0) || _oldOwner == SENTINEL_OWNERS)\n revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_prevOwner] != _oldOwner)\n revert MultiSigFacet__InvalidOwnerPair();\n\n ms.owners[_newOwner] = ms.owners[_oldOwner];\n ms.owners[_prevOwner] = _newOwner;\n ms.owners[_oldOwner] = address(0);\n emit OwnerRemoved(_oldOwner);\n emit OwnerAdded(_newOwner);\n }\n\n /**\n * @notice Changes the threshold of the Barz to `_threshold`.\n * @dev This can only be done via a Self call.\n * @param _threshold New threshold\n */\n function changeThreshold(uint256 _threshold) public {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (_threshold > ms.ownerCount || _threshold == 0)\n revert MultiSigFacet__InvalidThreshold();\n\n ms.threshold = _threshold;\n emit ThresholdChanged(_threshold);\n }\n\n /**\n * @notice Checks if the given address is owner\n * @param _owner Address to be checked if it's owner\n * @return isOwner_ Bool value showing if it's owner address\n */\n function isOwner(address _owner) public view returns (bool isOwner_) {\n isOwner_ = (_owner != SENTINEL_OWNERS &&\n LibMultiSigStorage.multisigStorage().owners[_owner] != address(0));\n }\n\n /**\n * @notice Returns the threshold of Barz\n * @return threshold Threshold of the Barz account\n */\n function getThreshold() public view returns (uint256 threshold) {\n threshold = LibMultiSigStorage.multisigStorage().threshold;\n }\n\n /**\n * @notice Returns the list of owner addresses\n * @return owners List of owners\n */\n function getOwners() public view returns (address[] memory owners) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n owners = new address[](ms.ownerCount);\n\n uint256 index;\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n while (currentOwner != SENTINEL_OWNERS) {\n owners[index] = currentOwner;\n currentOwner = ms.owners[currentOwner];\n index++;\n }\n }\n\n /**\n * @notice Returns the previous owner in the linked list\n * @param _owner Address of owner\n * @return prevOwner Address of previous owner\n */\n function getPrevOwner(\n address _owner\n ) public view returns (address prevOwner) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n if (currentOwner == _owner) return SENTINEL_OWNERS;\n while (currentOwner != SENTINEL_OWNERS) {\n if (ms.owners[currentOwner] == _owner) return currentOwner;\n\n currentOwner = ms.owners[currentOwner];\n }\n return address(0);\n }\n\n /**\n * @notice Returns of the owner is approved by given owner address\n * @param _owner Address of owner\n * @param _hash Hash of UserOperation\n * @return isApproved Bool value showing if the hash is approved by owner\n */\n function isApprovedHash(\n address _owner,\n bytes32 _hash\n ) public view returns (bool isApproved) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n isApproved = (ms.approvedHashes[ms.counter][_owner][_hash] == 1);\n }\n}\n" + }, + "contracts/facets/verification/secp256k1/Secp256k1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {UserOperation} from \"../../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibAppStorage} from \"../../../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, Secp256k1VerificationStorage} from \"../../../libraries/LibFacetStorage.sol\";\nimport {LibLoupe} from \"../../../libraries/LibLoupe.sol\";\nimport {IERC1271} from \"../../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../../interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Secp256k1 verification facet\n * @dev Default Ethereum's elliptic curve\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract Secp256k1VerificationFacet is IVerificationFacet, IERC1271 {\n using ECDSA for bytes32;\n error Secp256k1VerificationFacet__InvalidSignerLength();\n address public immutable self;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in K1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\n * @param _publicKey Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _publicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n if (!isValidKeyType(_publicKey))\n revert Secp256k1VerificationFacet__InvalidSignerLength();\n\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(uint160(uint256(keccak256(_publicKey[1:]))));\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_publicKey);\n }\n\n /**\n * @notice Uninitialize signer in K1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\n * signer public key.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n validationData = validateSignature(\n userOp,\n userOpHash,\n k1Storage.signer\n );\n }\n\n /**\n * @notice Validates if the signature of UserOperation is signed by the given signer\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @param signer Address of signer who signed the contract, to be validated\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n address signer\n ) public pure returns (uint256 isValid) {\n bytes32 hash = userOpHash.toEthSignedMessageHash();\n isValid = (signer != hash.recover(userOp.signature)) ? 1 : 0;\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n ownerSignatureValidatorSelector = this.validateOwnerSignature.selector;\n // NOTE: The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory signer) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n signer = abi.encodePacked(k1Storage.signer);\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key length should be 65 in an uncompressed public key format\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (_hash.recover(_signature) ==\n LibFacetStorage.k1Storage().signer)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/Secp256r1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {UserOperation} from \"../../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibAppStorage} from \"../../../libraries/LibAppStorage.sol\";\nimport {LibLoupe} from \"../../../libraries/LibLoupe.sol\";\nimport {LibFacetStorage, Secp256r1VerificationStorage} from \"../../../libraries/LibFacetStorage.sol\";\nimport {Base64} from \"./utils/Base64.sol\";\nimport {LibSecp256r1} from \"./utils/LibSecp256r1.sol\";\nimport {IERC1271} from \"../../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../../interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Secp256r1 verification facet\n * @dev Primarily used to verify user ops signed with passkeys\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract Secp256r1VerificationFacet is IVerificationFacet, IERC1271 {\n error Secp256r1VerificationFacet__InvalidSignerLength();\n address public immutable self;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in R1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\n * @param _publicKey Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _publicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n\n if (!isValidKeyType(_publicKey))\n revert Secp256r1VerificationFacet__InvalidSignerLength();\n\n bytes memory publicKeyCoordinates = _publicKey[1:];\n uint256[2] memory q;\n assembly {\n // Copy the bytes from the input data into the uint256 array\n mstore(q, mload(add(publicKeyCoordinates, 32)))\n mstore(add(q, 32), mload(add(publicKeyCoordinates, 64)))\n }\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n r1Storage.q = q;\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_publicKey);\n }\n\n /**\n * @notice Uninitialize signer in R1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n r1Storage.q = [0, 0];\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\n * signer public key.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n validationData = validateSignature(userOp, userOpHash, r1Storage.q);\n }\n\n /**\n * @notice Validates if the signature of UserOperation is signed by the given signer\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @param q Public Key of signer who signed the contract, to be validated\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256[2] memory q\n ) public view returns (uint256 isValid) {\n isValid = (_validateSignature(q, userOpHash, userOp.signature)) ? 0 : 1;\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n return this.validateOwnerSignature.selector; // validateOwnerSignature(UserOperation calldata userOp,bytes32 userOpHash)\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory signer) {\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n signer = abi.encodePacked(r1Storage.q);\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key should in an uncompressed public key format\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = _validateSignature(\n LibFacetStorage.r1Storage().q,\n _hash,\n _signature\n )\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n\n function _validateSignature(\n uint256[2] memory q,\n bytes32 _hash,\n bytes memory _signature\n ) internal view returns (bool) {\n (\n uint256 rValue,\n uint256 sValue,\n bytes memory authenticatorData,\n string memory clientDataJSONPre,\n string memory clientDataJSONPost\n ) = abi.decode(_signature, (uint256, uint256, bytes, string, string));\n bytes32 clientHash;\n {\n string memory opHashBase64 = Base64.encode(bytes.concat(_hash));\n string memory clientDataJSON = string.concat(\n clientDataJSONPre,\n opHashBase64,\n clientDataJSONPost\n );\n clientHash = sha256(bytes(clientDataJSON));\n }\n bytes32 sigHash = sha256(bytes.concat(authenticatorData, clientHash));\n return LibSecp256r1.Verify(q, rValue, sValue, uint256(sigHash));\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/utils/Base64.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @dev Provides a set of functions to operate with Base64 strings.\n * modified for base64url https://datatracker.ietf.org/doc/html/rfc4648#section-5\n * _Available since v4.5._\n */\nlibrary Base64 {\n /**\n * @dev Base64 Encoding/Decoding Table\n */\n string internal constant _TABLE =\n \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_\";\n\n /**\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\n */\n function encode(bytes memory data) internal pure returns (string memory) {\n /**\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\n */\n if (data.length == 0) return \"\";\n\n // Loads the table into memory\n string memory table = _TABLE;\n\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\n // and split into 4 numbers of 6 bits.\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\n // - `data.length + 2` -> Round up\n // - `/ 3` -> Number of 3-bytes chunks\n // - `4 *` -> 4 characters for each chunk\n uint256 newlength = (data.length * 8) / 6;\n if (data.length % 6 > 0) {\n newlength++;\n }\n string memory result = new string(newlength);\n\n /// @solidity memory-safe-assembly\n assembly {\n // Prepare the lookup table (skip the first \"length\" byte)\n let tablePtr := add(table, 1)\n\n // Prepare result pointer, jump over length\n let resultPtr := add(result, 32)\n\n // Run over the input, 3 bytes at a time\n for {\n let dataPtr := data\n let endPtr := add(data, mload(data))\n } lt(dataPtr, endPtr) {\n\n } {\n // Advance 3 bytes\n dataPtr := add(dataPtr, 3)\n let input := mload(dataPtr)\n\n // To write each character, shift the 3 bytes (18 bits) chunk\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\n // and apply logical AND with 0x3F which is the number of\n // the previous character in the ASCII table prior to the Base64 Table\n // The result is then added to the table to get the character to write,\n // and finally write it in the result pointer but with a left shift\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(18, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(12, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(6, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n }\n }\n\n return result;\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/utils/LibSecp256r1.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n// Heavily inspired from\n// https://github.com/maxrobot/elliptic-solidity/blob/master/contracts/Secp256r1.sol\n// https://github.com/tdrerup/elliptic-curve-solidity/blob/master/contracts/curves/EllipticCurve.sol\n// modified to use precompile 0x05 modexp\n// and modified jacobian double\n// optimisations to avoid to an from from affine and jacobian coordinates\n\n// Additional Elliptic curve Public key / Signature validation added by\n// David Yonjun Kim (@Powerstream3604)\n\nstruct JPoint {\n uint256 x;\n uint256 y;\n uint256 z;\n}\n\nlibrary LibSecp256r1 {\n uint256 constant gx =\n 0x6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296;\n uint256 constant gy =\n 0x4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5;\n uint256 public constant pp =\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF;\n\n uint256 public constant nn =\n 0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551;\n uint256 constant a =\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC;\n uint256 constant b =\n 0x5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B;\n uint256 constant MOST_SIGNIFICANT =\n 0xc000000000000000000000000000000000000000000000000000000000000000;\n\n /*\n * Verify\n * @description - verifies that a public key has signed a given message\n * @param Q - public key coordinates X & Y\n * @param R - signature half R\n * @param S - signature half S\n * @param input - hashed message\n */\n function Verify(\n uint256[2] memory q,\n uint r,\n uint s,\n uint e\n ) internal view returns (bool) {\n if (q[0] > pp - 1 || q[1] > pp - 1) {\n return false;\n }\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\n return false;\n }\n if (\n mulmod(q[1], q[1], pp) !=\n addmod(\n addmod(\n mulmod(q[0], mulmod(q[0], q[0], pp), pp),\n mulmod(a, q[0], pp),\n pp\n ),\n b,\n pp\n )\n ) {\n return false;\n }\n\n JPoint[16] memory points = _preComputeJacobianPoints(q);\n return VerifyWithPrecompute(points, r, s, e);\n }\n\n function VerifyWithPrecompute(\n JPoint[16] memory points,\n uint r,\n uint s,\n uint e\n ) internal view returns (bool) {\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\n return false;\n }\n\n uint w = _primemod(s, nn);\n\n uint u1 = mulmod(e, w, nn);\n uint u2 = mulmod(r, w, nn);\n\n uint x;\n uint y;\n\n (x, y) = ShamirMultJacobian(points, u1, u2);\n return (x == r);\n }\n\n /*\n * Strauss Shamir trick for EC multiplication\n * https://stackoverflow.com/questions/50993471/ec-scalar-multiplication-with-strauss-shamir-method\n * we optimise on this a bit to do with 2 bits at a time rather than a single bit\n * the individual points for a single pass are precomputed\n * overall this reduces the number of additions while keeping the same number of doublings\n */\n function ShamirMultJacobian(\n JPoint[16] memory points,\n uint u1,\n uint u2\n ) internal view returns (uint, uint) {\n uint x = 0;\n uint y = 0;\n uint z = 0;\n uint bits = 128;\n uint index = 0;\n\n while (bits > 0) {\n if (z > 0) {\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\n }\n index =\n ((u1 & MOST_SIGNIFICANT) >> 252) |\n ((u2 & MOST_SIGNIFICANT) >> 254);\n if (index > 0) {\n (x, y, z) = _jAdd(\n x,\n y,\n z,\n points[index].x,\n points[index].y,\n points[index].z\n );\n }\n u1 <<= 2;\n u2 <<= 2;\n bits--;\n }\n (x, y) = _affineFromJacobian(x, y, z);\n return (x, y);\n }\n\n function _preComputeJacobianPoints(\n uint256[2] memory q\n ) internal pure returns (JPoint[16] memory points) {\n points[0] = JPoint(0, 0, 0);\n points[1] = JPoint(q[0], q[1], 1); // u2\n points[2] = _jPointDouble(points[1]);\n points[3] = _jPointAdd(points[1], points[2]);\n\n points[4] = JPoint(gx, gy, 1); // u1Points[1]\n points[5] = _jPointAdd(points[4], points[1]);\n points[6] = _jPointAdd(points[4], points[2]);\n points[7] = _jPointAdd(points[4], points[3]);\n\n points[8] = _jPointDouble(points[4]); // u1Points[2]\n points[9] = _jPointAdd(points[8], points[1]);\n points[10] = _jPointAdd(points[8], points[2]);\n points[11] = _jPointAdd(points[8], points[3]);\n\n points[12] = _jPointAdd(points[4], points[8]); // u1Points[3]\n points[13] = _jPointAdd(points[12], points[1]);\n points[14] = _jPointAdd(points[12], points[2]);\n points[15] = _jPointAdd(points[12], points[3]);\n }\n\n function _jPointAdd(\n JPoint memory p1,\n JPoint memory p2\n ) internal pure returns (JPoint memory) {\n uint x;\n uint y;\n uint z;\n (x, y, z) = _jAdd(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z);\n return JPoint(x, y, z);\n }\n\n function _jPointDouble(\n JPoint memory p\n ) internal pure returns (JPoint memory) {\n uint x;\n uint y;\n uint z;\n (x, y, z) = _modifiedJacobianDouble(p.x, p.y, p.z);\n return JPoint(x, y, z);\n }\n\n /* _affineFromJacobian\n * @desription returns affine coordinates from a jacobian input follows\n * golang elliptic/crypto library\n */\n function _affineFromJacobian(\n uint x,\n uint y,\n uint z\n ) internal view returns (uint ax, uint ay) {\n if (z == 0) {\n return (0, 0);\n }\n\n uint zinv = _primemod(z, pp);\n uint zinvsq = mulmod(zinv, zinv, pp);\n\n ax = mulmod(x, zinvsq, pp);\n ay = mulmod(y, mulmod(zinvsq, zinv, pp), pp);\n }\n\n /*\n * _jAdd\n * @description performs Jacobian addition as defined below:\n * http://www.hyperelliptic.org/EFD/g1p/data/shortw/jacobian/addition/add-2007-bl\n */\n function _jAdd(\n uint p1,\n uint p2,\n uint p3,\n uint q1,\n uint q2,\n uint q3\n ) internal pure returns (uint r1, uint r2, uint r3) {\n if (p3 == 0) {\n r1 = q1;\n r2 = q2;\n r3 = q3;\n\n return (r1, r2, r3);\n } else if (q3 == 0) {\n r1 = p1;\n r2 = p2;\n r3 = p3;\n\n return (r1, r2, r3);\n }\n\n assembly {\n let\n pd\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\n let z1z1 := mulmod(p3, p3, pd) // Z1Z1 = Z1^2\n let z2z2 := mulmod(q3, q3, pd) // Z2Z2 = Z2^2\n\n let u1 := mulmod(p1, z2z2, pd) // U1 = X1*Z2Z2\n let u2 := mulmod(q1, z1z1, pd) // U2 = X2*Z1Z1\n\n let s1 := mulmod(p2, mulmod(z2z2, q3, pd), pd) // S1 = Y1*Z2*Z2Z2\n let s2 := mulmod(q2, mulmod(z1z1, p3, pd), pd) // S2 = Y2*Z1*Z1Z1\n\n let p3q3 := addmod(p3, q3, pd)\n\n if lt(u2, u1) {\n u2 := add(pd, u2) // u2 = u2+pd\n }\n let h := sub(u2, u1) // H = U2-U1\n\n let i := mulmod(0x02, h, pd)\n i := mulmod(i, i, pd) // I = (2*H)^2\n\n let j := mulmod(h, i, pd) // J = H*I\n if lt(s2, s1) {\n s2 := add(pd, s2) // u2 = u2+pd\n }\n let rr := mulmod(0x02, sub(s2, s1), pd) // r = 2*(S2-S1)\n r1 := mulmod(rr, rr, pd) // X3 = R^2\n\n let v := mulmod(u1, i, pd) // V = U1*I\n let j2v := addmod(j, mulmod(0x02, v, pd), pd)\n if lt(r1, j2v) {\n r1 := add(pd, r1) // X3 = X3+pd\n }\n r1 := sub(r1, j2v)\n\n // Y3 = r*(V-X3)-2*S1*J\n let s12j := mulmod(mulmod(0x02, s1, pd), j, pd)\n\n if lt(v, r1) {\n v := add(pd, v)\n }\n r2 := mulmod(rr, sub(v, r1), pd)\n\n if lt(r2, s12j) {\n r2 := add(pd, r2)\n }\n r2 := sub(r2, s12j)\n\n // Z3 = ((Z1+Z2)^2-Z1Z1-Z2Z2)*H\n z1z1 := addmod(z1z1, z2z2, pd)\n j2v := mulmod(p3q3, p3q3, pd)\n if lt(j2v, z1z1) {\n j2v := add(pd, j2v)\n }\n r3 := mulmod(sub(j2v, z1z1), h, pd)\n }\n return (r1, r2, r3);\n }\n\n // Point doubling on the modified jacobian coordinates\n // http://point-at-infinity.org/ecc/Prime_Curve_Modified_Jacobian_Coordinates.html\n function _modifiedJacobianDouble(\n uint x,\n uint y,\n uint z\n ) internal pure returns (uint x3, uint y3, uint z3) {\n if (y == 0) return (0, 0, 0);\n assembly {\n let\n pd\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\n let z2 := mulmod(z, z, pd)\n let az4 := mulmod(\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC,\n mulmod(z2, z2, pd),\n pd\n )\n let y2 := mulmod(y, y, pd)\n let s := mulmod(0x04, mulmod(x, y2, pd), pd)\n let u := mulmod(0x08, mulmod(y2, y2, pd), pd)\n let m := addmod(mulmod(0x03, mulmod(x, x, pd), pd), az4, pd)\n let twos := mulmod(0x02, s, pd)\n let m2 := mulmod(m, m, pd)\n if lt(m2, twos) {\n m2 := add(pd, m2)\n }\n x3 := sub(m2, twos)\n if lt(s, x3) {\n s := add(pd, s)\n }\n y3 := mulmod(m, sub(s, x3), pd)\n if lt(y3, u) {\n y3 := add(pd, y3)\n }\n y3 := sub(y3, u)\n z3 := mulmod(0x02, mulmod(y, z, pd), pd)\n }\n }\n\n // Fermats little theorem https://en.wikipedia.org/wiki/Fermat%27s_little_theorem\n // a^(p-1) = 1 mod p\n // a^(-1) ≅ a^(p-2) (mod p)\n // we then use the precompile bigModExp to compute a^(-1)\n function _primemod(uint value, uint p) internal view returns (uint ret) {\n ret = modexp(value, p - 2, p);\n return ret;\n }\n\n // Wrapper for built-in BigNumber_modexp (contract 0x5) as described here. https://github.com/ethereum/EIPs/pull/198\n function modexp(\n uint _base,\n uint _exp,\n uint _mod\n ) internal view returns (uint ret) {\n // bigModExp(_base, _exp, _mod);\n assembly {\n if gt(_base, _mod) {\n _base := mod(_base, _mod)\n }\n // Free memory pointer is always stored at 0x40\n let freemem := mload(0x40)\n\n mstore(freemem, 0x20)\n mstore(add(freemem, 0x20), 0x20)\n mstore(add(freemem, 0x40), 0x20)\n\n mstore(add(freemem, 0x60), _base)\n mstore(add(freemem, 0x80), _exp)\n mstore(add(freemem, 0xa0), _mod)\n\n let success := staticcall(14000, 0x5, freemem, 0xc0, freemem, 0x20)\n switch success\n case 0 {\n revert(0x0, 0x0)\n }\n default {\n ret := mload(freemem)\n }\n }\n }\n}\n" + }, + "contracts/infrastructure/DefaultFallbackHandler.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC1155Receiver} from \"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\";\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {BaseAccount} from \"../aa-4337/core/BaseAccount.sol\";\nimport {DefaultLibDiamond} from \"../libraries/DefaultLibDiamond.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IAccountFacet} from \"../facets/interfaces/IAccountFacet.sol\";\nimport {IStorageLoupe} from \"../facets/base/interfaces/IStorageLoupe.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IERC677Receiver} from \"../interfaces/ERC/IERC677Receiver.sol\";\nimport {IERC165} from \"../interfaces/ERC/IERC165.sol\";\n\n/**\n * @title DefaultFallbackHandler\n * @dev A default fallback handler for Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DefaultFallbackHandler is IDiamondLoupe {\n /**\n * @notice Sets the middleware diamond for Barz wallet as a fallback handler\n * @dev This contract is also a diamond that holds the default facets to reduce gas cost for wallet activation.\n * Within the constructor this conducts diamond cut to initially setup the diamond. This is a non-upgradeable contract\n * @param _diamondCutFacet Address if diamond cut facet\n * @param _accountFacet Address account facet\n * @param _tokenReceiverFacet Address of token receiver facet\n * @param _diamondLoupeFacet Address of diamond loupe facet\n */\n constructor(\n address _diamondCutFacet,\n address _accountFacet,\n address _tokenReceiverFacet,\n address _diamondLoupeFacet\n ) payable {\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](4);\n bytes4[] memory functionSelectors = new bytes4[](1);\n functionSelectors[0] = IDiamondCut.diamondCut.selector;\n\n bytes4[] memory accountFunctionSelectors = new bytes4[](5);\n accountFunctionSelectors[0] = IAccountFacet.execute.selector;\n accountFunctionSelectors[1] = IAccountFacet.executeBatch.selector;\n accountFunctionSelectors[2] = BaseAccount.validateUserOp.selector;\n accountFunctionSelectors[3] = BaseAccount.getNonce.selector;\n accountFunctionSelectors[4] = BaseAccount.entryPoint.selector;\n\n bytes4[] memory receiverFacetSelectors = new bytes4[](5);\n receiverFacetSelectors[0] = IERC721Receiver.onERC721Received.selector;\n receiverFacetSelectors[1] = IERC1155Receiver.onERC1155Received.selector;\n receiverFacetSelectors[2] = IERC1155Receiver\n .onERC1155BatchReceived\n .selector;\n receiverFacetSelectors[3] = IERC777Recipient.tokensReceived.selector;\n receiverFacetSelectors[4] = IERC677Receiver.onTokenTransfer.selector;\n\n bytes4[] memory loupeFacetSelectors = new bytes4[](9);\n loupeFacetSelectors[0] = IDiamondLoupe.facets.selector;\n loupeFacetSelectors[1] = IDiamondLoupe.facetFunctionSelectors.selector;\n loupeFacetSelectors[2] = IDiamondLoupe.facetAddresses.selector;\n loupeFacetSelectors[3] = IDiamondLoupe.facetAddress.selector;\n loupeFacetSelectors[4] = IERC165.supportsInterface.selector;\n loupeFacetSelectors[5] = IStorageLoupe.facetsFromStorage.selector;\n loupeFacetSelectors[6] = IStorageLoupe\n .facetFunctionSelectorsFromStorage\n .selector;\n loupeFacetSelectors[7] = IStorageLoupe\n .facetAddressesFromStorage\n .selector;\n loupeFacetSelectors[8] = IStorageLoupe.facetAddressFromStorage.selector;\n\n {\n cut[0] = IDiamondCut.FacetCut({\n facetAddress: _diamondCutFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: functionSelectors\n });\n cut[1] = IDiamondCut.FacetCut({\n facetAddress: _accountFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: accountFunctionSelectors\n });\n cut[2] = IDiamondCut.FacetCut({\n facetAddress: _tokenReceiverFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: receiverFacetSelectors\n });\n cut[3] = IDiamondCut.FacetCut({\n facetAddress: _diamondLoupeFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: loupeFacetSelectors\n });\n\n DefaultLibDiamond.diamondCut(cut, address(0), \"\");\n }\n }\n\n /**\n * @notice Returns the facet information of call facets registered to this diamond.\n * @return facets_ The facet struct array including all facet information\n */\n function facets() external view override returns (Facet[] memory facets_) {\n DefaultLibDiamond.DiamondStorage storage ds = DefaultLibDiamond\n .diamondStorage();\n uint256 numFacets = ds.facetAddresses.length;\n facets_ = new Facet[](numFacets);\n for (uint256 i; i < numFacets; ) {\n address facetAddress_ = ds.facetAddresses[i];\n facets_[i].facetAddress = facetAddress_;\n facets_[i].functionSelectors = ds\n .facetFunctionSelectors[facetAddress_]\n .functionSelectors;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Gets all the function selectors provided by a facet.\n * @param _facet The facet address.\n * @return facetFunctionSelectors_\n */\n function facetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n facetFunctionSelectors_ = DefaultLibDiamond\n .diamondStorage()\n .facetFunctionSelectors[_facet]\n .functionSelectors;\n }\n\n /**\n * @notice Get all the facet addresses used by a diamond.\n * @return facetAddresses_\n */\n function facetAddresses()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n facetAddresses_ = DefaultLibDiamond.diamondStorage().facetAddresses;\n }\n\n /** @notice Gets the facet that supports the given selector.\n * @dev If facet is not found return address(0).\n * @param _functionSelector The function selector.\n * @return facetAddress_ The facet address.\n */\n function facetAddress(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n facetAddress_ = DefaultLibDiamond\n .diamondStorage()\n .selectorToFacetAndPosition[_functionSelector]\n .facetAddress;\n }\n}\n" + }, + "contracts/infrastructure/FacetRegistry.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport {IFacetRegistry} from \"./interfaces/IFacetRegistry.sol\";\n\n/**\n * @title Facet Registry\n * @dev Contract to keep track of facets & function selectors addable to user wallets\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract FacetRegistry is IFacetRegistry, Ownable2Step {\n mapping(address => FacetRegistryConfig) private facets;\n\n /**\n * @notice Transfers the ownership of the contract to the given owner\n * @param _owner Address of owner who has access to initialize the default security variables for security manager\n */\n constructor(address _owner) {\n transferOwnership(_owner);\n _transferOwnership(_owner);\n }\n\n /**\n * @dev Registers a facet and it's function selectors to registry\n * @param _facet address of facet\n * @param _facetSelectors list of function selectors of the facet\n */\n function registerFacetFunctionSelectors(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external override onlyOwner {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n for (uint256 i; i < _facetSelectors.length; ) {\n if (facetConfig.info[_facetSelectors[i]].exists)\n revert FacetRegistry__FacetSelectorAlreadyRegistered();\n\n facetConfig.info[_facetSelectors[i]].exists = true;\n facetConfig.info[_facetSelectors[i]].index = uint128(\n facetConfig.selectors.length\n );\n facetConfig.selectors.push(_facetSelectors[i]);\n unchecked {\n ++i;\n }\n }\n emit FacetFunctionSelectorsRegistered(_facet, _facetSelectors);\n }\n\n /**\n * @dev Removes a registered facet and it's corresponding selectors from registry\n * @param _facet address of facet\n * @param _facetSelectors list of function selectors of the facet\n */\n function removeFacetFunctionSelectors(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external override onlyOwner {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n for (uint256 i; i < _facetSelectors.length; ) {\n if (!facetConfig.info[_facetSelectors[i]].exists)\n revert FacetRegistry__UnregisteredFacetSelector();\n\n bytes4 lastSelector = facetConfig.selectors[\n facetConfig.selectors.length - 1\n ];\n if (_facetSelectors[i] != lastSelector) {\n uint128 targetIndex = facetConfig\n .info[_facetSelectors[i]]\n .index;\n facetConfig.selectors[targetIndex] = lastSelector;\n facetConfig.info[lastSelector].index = targetIndex;\n }\n facetConfig.selectors.pop();\n delete facetConfig.info[_facetSelectors[i]];\n\n unchecked {\n ++i;\n }\n }\n emit FacetFunctionSelectorsRemoved(_facet, _facetSelectors);\n }\n\n /**\n * @dev Checks if a facet and it's selectors given is registered to facet registry\n * @param _facet Address of facet\n * @param _facetSelectors List of function selectors of the facet\n */\n function areFacetFunctionSelectorsRegistered(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external view override returns (bool) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n if (_facetSelectors.length == 0) return false;\n for (uint256 i; i < _facetSelectors.length; ) {\n if (!facetConfig.info[_facetSelectors[i]].exists) return false;\n unchecked {\n ++i;\n }\n }\n return true;\n }\n\n /**\n * @dev Checks if a facet and it's selector given is registered to facet registry\n * @param _facet Address of facet\n * @param _facetSelector List of function selectors of the facet\n * @return isRegistered Bool value showing if the selector is registered\n */\n function isFacetFunctionSelectorRegistered(\n address _facet,\n bytes4 _facetSelector\n ) external view override returns (bool isRegistered) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n isRegistered = facetConfig.info[_facetSelector].exists;\n }\n\n /**\n * @dev Get the registered selectors of facet from registry\n * @param _facet Address of facet\n * @return selectors Selectors registered to facet\n */\n function getFacetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory selectors) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n selectors = facetConfig.selectors;\n }\n}\n" + }, + "contracts/infrastructure/interfaces/IFacetRegistry.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Registry Interface\n * @dev Interface for Facet Registry contract to keep track of facets & function selectors addable to user wallets\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IFacetRegistry {\n struct FacetRegistryConfig {\n bytes4[] selectors;\n mapping(bytes4 => FacetInfo) info;\n }\n struct FacetInfo {\n bool exists;\n uint128 index;\n }\n\n event FacetFunctionSelectorsRegistered(\n address facet,\n bytes4[] facetSelectors\n );\n event FacetFunctionSelectorsRemoved(address facet, bytes4[] facetSelectors);\n\n error FacetRegistry__FacetSelectorAlreadyRegistered();\n error FacetRegistry__UnregisteredFacetSelector();\n\n function registerFacetFunctionSelectors(\n address facet,\n bytes4[] calldata facetSelectors\n ) external;\n\n function removeFacetFunctionSelectors(\n address facet,\n bytes4[] calldata facetSelectors\n ) external;\n\n function areFacetFunctionSelectorsRegistered(\n address facet,\n bytes4[] calldata facetSelectors\n ) external view returns (bool);\n\n function isFacetFunctionSelectorRegistered(\n address facet,\n bytes4 facetSelector\n ) external view returns (bool);\n\n function getFacetFunctionSelectors(\n address facet\n ) external view returns (bytes4[] memory);\n}\n" + }, + "contracts/infrastructure/interfaces/ISecurityManager.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Registry Interface\n * @dev Infrastructure contract to manage security parameters of users\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface ISecurityManager {\n error SecurityManager__OutOfBoundary();\n error SecurityManager__CallerNotWallet();\n error SecurityManager__AlreadyIntialized();\n\n function initializeAdditionSecurityPeriod(\n uint128 defaultAdditionSecurityPeriod,\n uint128 minAdditionSecurityPeriod,\n uint128 maxAdditionSecurityPeriod\n ) external;\n\n function initializeRemovalSecurityPeriod(\n uint128 defaultRemovalSecurityPeriod,\n uint128 minRemovalSecurityPeriod,\n uint128 maxRemovalSecurityPeriod\n ) external;\n\n function initializeApprovalValidationPeriod(\n uint128 defaultApprovalValidationPeriod,\n uint128 minApprovalValidationPeriod,\n uint128 maxApprovalValidationPeriod\n ) external;\n\n function initializeMigrationPeriod(\n uint128 defaultMigrationPeriod,\n uint128 minMigrationPeriod,\n uint128 maxMigrationPeriod\n ) external;\n\n function initializeLockPeriod(\n uint128 defaultLockPeriod,\n uint128 minLockPeriod,\n uint128 maxLockPeriod\n ) external;\n\n function initializeRecoveryPeriod(\n uint128 defaultRecoveryPeriod,\n uint128 minRecoveryPeriod,\n uint128 maxRecoveryPeriod\n ) external;\n\n function initializeSecurityWindow(\n uint128 defaultSecurityWindow,\n uint128 minSecurityWindow,\n uint128 maxSecurityWindow\n ) external;\n\n function setAdditionSecurityPeriod(\n address wallet,\n uint128 additionSecurityPeriod\n ) external;\n\n function setRemovalSecurityPeriod(\n address wallet,\n uint128 removalSecurityPeriod\n ) external;\n\n function setSecurityWindow(address wallet, uint128 securityWindow) external;\n\n function setRecoveryPeriod(address wallet, uint128 recoveryPeriod) external;\n\n function setLockPeriod(address wallet, uint128 lockPeriod) external;\n\n function setApprovalValidationPeriod(\n address wallet,\n uint128 approvalValidationPeriod\n ) external;\n\n function setMigrationPeriod(\n address wallet,\n uint128 migrationPeriod\n ) external;\n\n function additionSecurityPeriodOf(\n address wallet\n ) external view returns (uint128);\n\n function removalSecurityPeriodOf(\n address wallet\n ) external view returns (uint128);\n\n function securityWindowOf(address wallet) external view returns (uint128);\n\n function recoveryPeriodOf(address wallet) external view returns (uint128);\n\n function lockPeriodOf(address wallet) external view returns (uint128);\n\n function migrationPeriodOf(address wallet) external view returns (uint128);\n\n function approvalValidationPeriodOf(\n address wallet\n ) external view returns (uint128);\n}\n" + }, + "contracts/infrastructure/RemoteStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IGuardianFacet} from \"../facets/interfaces/IGuardianFacet.sol\";\n\n/**\n * @title Remote Storage\n * @dev Remote storage allows you to associate addresses with an array of addresses on a standalone smart contract.\n * This could be useful when you don't want to use the local diamond storage for some purpose.\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\nabstract contract RemoteStorage {\n struct StorageConfig {\n address[] addresses;\n mapping(address => Info) info;\n }\n\n struct Info {\n bool exists;\n uint128 index;\n }\n\n mapping(address => StorageConfig) internal configs;\n\n event Added(address _address);\n event Removed(address _address);\n\n error RemoteStorage__CallerNotOwner();\n error RemoteStorage__CallerNotGuardianOrOwner();\n error RemoteStorage__AlreadyExists();\n error RemoteStorage__NotFound();\n error RemoteStorage__CallerNotGuardian();\n\n bytes4 constant IS_GUARDIAN_SELECTOR =\n bytes4(keccak256(\"isGuardian(address)\"));\n bytes4 constant GUARDIAN_COUNT = bytes4(keccak256(\"guardianCount()\"));\n\n /**\n * @notice Modifier to only allow the self to call. Reverts otherwise\n */\n modifier onlyWallet(address _wallet) {\n if (msg.sender != _wallet) revert RemoteStorage__CallerNotOwner();\n _;\n }\n\n /**\n * @notice Enfore the callet to be wallet of guardian of the wallet\n * @param _wallet Address of wallet\n */\n function enforceGuardianOrWallet(address _wallet) internal view {\n if (msg.sender == _wallet) return;\n address facetAddress = IDiamondLoupe(_wallet).facetAddress(\n IS_GUARDIAN_SELECTOR\n );\n if (facetAddress != address(0))\n if (IGuardianFacet(_wallet).isGuardian(msg.sender)) return;\n revert RemoteStorage__CallerNotGuardianOrOwner();\n }\n\n /**\n * @notice Enforce the caller to be wallet IF guardians doesn't exists and only guardian when guardians exists\n * @param _wallet Target wallet address to be handled by infrastructure contracts\n */\n function enforceWalletOrGuardianIfExists(address _wallet) internal view {\n address facetAddress;\n if (msg.sender == _wallet) {\n facetAddress = IDiamondLoupe(_wallet).facetAddress(GUARDIAN_COUNT);\n if (facetAddress == address(0)) return;\n uint256 guardianCount = IGuardianFacet(_wallet).guardianCount();\n if (guardianCount != 0) revert RemoteStorage__CallerNotGuardian();\n return;\n }\n facetAddress = IDiamondLoupe(_wallet).facetAddress(\n IS_GUARDIAN_SELECTOR\n );\n if (facetAddress != address(0))\n if (IGuardianFacet(_wallet).isGuardian(msg.sender)) return;\n\n revert RemoteStorage__CallerNotGuardianOrOwner();\n }\n\n /**\n * @notice Add address to storage and reverts if the address already exists.\n * This is an internal function callable from contracts that inherit this abstract contract\n * @param _wallet Address of wallet to add the address\n * @param _address Address to be added to wallet\n */\n function addAddress(address _wallet, address _address) internal {\n StorageConfig storage config = configs[_wallet];\n if (config.info[_address].exists) revert RemoteStorage__AlreadyExists();\n\n config.info[_address].exists = true;\n config.info[_address].index = uint128(config.addresses.length);\n config.addresses.push(_address);\n\n emit Added(_address);\n }\n\n /**\n * @notice Remove address from storage and reverts if the address already exists.\n * This is an internal function callable from contracts that inherit this abstract contract\n * @param _wallet Address of wallet to remove the address\n * @param _address Address to be removed from wallet\n */\n function removeAddress(address _wallet, address _address) internal {\n StorageConfig storage config = configs[_wallet];\n if (!config.info[_address].exists) revert RemoteStorage__NotFound();\n\n address lastAddress = config.addresses[config.addresses.length - 1];\n if (_address != lastAddress) {\n uint128 targetIndex = config.info[_address].index;\n config.addresses[targetIndex] = lastAddress;\n config.info[lastAddress].index = targetIndex;\n }\n config.addresses.pop();\n delete config.info[_address];\n\n emit Removed(_address);\n }\n\n /**\n * @notice Returns the address added to the given wallet\n * @param _wallet Address of wallet to fetch the addresses added to it\n * @return addresses List of addresses added to the wallet\n */\n function getAddresses(\n address _wallet\n ) internal view returns (address[] memory addresses) {\n StorageConfig storage config = configs[_wallet];\n addresses = new address[](config.addresses.length);\n uint addressesLen = config.addresses.length;\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns bool value checking if the address exists in the given wallet address\n * @param _wallet Wallet address to check\n * @param _address Address to fetch if the address if added to given wallet\n * @return exists_ Bool value showing if the address exists in wallet\n */\n function exists(\n address _wallet,\n address _address\n ) internal view returns (bool exists_) {\n exists_ = configs[_wallet].info[_address].exists;\n }\n\n /**\n * @notice Returns the number of addresses added to the wallet\n * @param _wallet Address of wallet to check\n * @return count_ Number of addresses added to wallet\n */\n function count(address _wallet) internal view returns (uint256 count_) {\n count_ = configs[_wallet].addresses.length;\n }\n}\n" + }, + "contracts/infrastructure/SecurityManager.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport {ISecurityManager} from \"./interfaces/ISecurityManager.sol\";\n\n/**\n * @title Security Manager\n * @dev Infrastructure contract to manage security parameters of users\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract SecurityManager is ISecurityManager, Ownable2Step {\n uint128 public minAdditionSecurityPeriod;\n uint128 public maxAdditionSecurityPeriod;\n uint128 private defaultAdditionSecurityPeriod;\n\n uint128 public minRemovalSecurityPeriod;\n uint128 public maxRemovalSecurityPeriod;\n uint128 private defaultRemovalSecurityPeriod;\n\n uint128 public minSecurityWindow;\n uint128 public maxSecurityWindow;\n uint128 private defaultSecurityWindow;\n\n uint128 public minRecoveryPeriod;\n uint128 public maxRecoveryPeriod;\n uint128 private defaultRecoveryPeriod;\n\n uint128 public minLockPeriod;\n uint128 public maxLockPeriod;\n uint128 private defaultLockPeriod;\n\n uint128 public minApprovalValidationPeriod;\n uint128 public maxApprovalValidationPeriod;\n uint128 private defaultApprovalValidationPeriod;\n\n uint128 public minMigrationPeriod;\n uint128 public maxMigrationPeriod;\n uint128 private defaultMigrationPeriod;\n\n bool public _isAdditionSecurityPeriodInitialized;\n bool public _isRemovalSecurityPeriodInitialized;\n bool public _isSecurityWindowInitialized;\n bool public _isRecoveryPeriodInitialized;\n bool public _isLockPeriodInitialized;\n bool public _isApprovalValidationPeriodInitialized;\n bool public _isMigrationPeriodInitialized;\n\n mapping(address => CustomSecurityConfig) securityConfigs;\n\n struct CustomSecurityConfig {\n uint128 additionSecurityPeriod;\n uint128 removalSecurityPeriod;\n uint128 securityWindow;\n uint128 recoveryPeriod;\n uint128 lockPeriod;\n uint128 approvalValidationPeriod;\n uint128 migrationPeriod;\n }\n\n /**\n * @notice Modifier to only allow wallet itself to make a call to wallet\n */\n modifier onlyWallet(address _wallet) {\n if (msg.sender != _wallet) revert SecurityManager__CallerNotWallet();\n _;\n }\n\n /**\n * @notice Modifier to revert if the variable is already initialized\n */\n modifier initializer(bool _isInitialized) {\n if (_isInitialized) revert SecurityManager__AlreadyIntialized();\n _;\n }\n\n /**\n * @notice Transfers the ownership of the contract to the given owner\n * @param _owner Address of owner who has access to initialize the default security variables for security manager\n */\n constructor(address _owner) {\n transferOwnership(_owner);\n _transferOwnership(_owner);\n }\n\n /**\n * @notice Sets the initial default/min/max addition security period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultAdditionSecurityPeriod Default Addition Security Period for all Barz contracts\n * @param _minAdditionSecurityPeriod Minimum Addition Security Period for all Barz contracts\n * @param _maxAdditionSecurityPeriod Maximum Addition Security Period for all Barz contracts\n */\n function initializeAdditionSecurityPeriod(\n uint128 _defaultAdditionSecurityPeriod,\n uint128 _minAdditionSecurityPeriod,\n uint128 _maxAdditionSecurityPeriod\n )\n external\n override\n onlyOwner\n initializer(_isAdditionSecurityPeriodInitialized)\n {\n _isAdditionSecurityPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultAdditionSecurityPeriod,\n _minAdditionSecurityPeriod,\n _maxAdditionSecurityPeriod\n );\n defaultAdditionSecurityPeriod = _defaultAdditionSecurityPeriod;\n minAdditionSecurityPeriod = _minAdditionSecurityPeriod;\n maxAdditionSecurityPeriod = _maxAdditionSecurityPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max removal security period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultRemovalSecurityPeriod Default Removal Security Period for all Barz contracts\n * @param _minRemovalSecurityPeriod Minimum Removal Security Period for all Barz contracts\n * @param _maxRemovalSecurityPeriod Maximum Removal Security Period for all Barz contracts\n */\n function initializeRemovalSecurityPeriod(\n uint128 _defaultRemovalSecurityPeriod,\n uint128 _minRemovalSecurityPeriod,\n uint128 _maxRemovalSecurityPeriod\n )\n external\n override\n onlyOwner\n initializer(_isRemovalSecurityPeriodInitialized)\n {\n _isRemovalSecurityPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultRemovalSecurityPeriod,\n _minRemovalSecurityPeriod,\n _maxRemovalSecurityPeriod\n );\n defaultRemovalSecurityPeriod = _defaultRemovalSecurityPeriod;\n minRemovalSecurityPeriod = _minRemovalSecurityPeriod;\n maxRemovalSecurityPeriod = _maxRemovalSecurityPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/maxd security window for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultSecurityWindow Default Security Window for all Barz contracts\n * @param _minSecurityWindow Minimum Security Window for all Barz contracts\n * @param _maxSecurityWindow Maximum Security Window for all Barz contracts\n */\n function initializeSecurityWindow(\n uint128 _defaultSecurityWindow,\n uint128 _minSecurityWindow,\n uint128 _maxSecurityWindow\n ) external override onlyOwner initializer(_isSecurityWindowInitialized) {\n _isSecurityWindowInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultSecurityWindow,\n _minSecurityWindow,\n _maxSecurityWindow\n );\n defaultSecurityWindow = _defaultSecurityWindow;\n minSecurityWindow = _minSecurityWindow;\n maxSecurityWindow = _maxSecurityWindow;\n }\n\n /**\n * @notice Sets the initial default/min/max recovery period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultRecoveryPeriod Default Recovery Period for all Barz contracts\n * @param _minRecoveryPeriod Minimum Recovery Period for all Barz contracts\n * @param _maxRecoveryPeriod Maximum Recovery Period for all Barz contracts\n */\n function initializeRecoveryPeriod(\n uint128 _defaultRecoveryPeriod,\n uint128 _minRecoveryPeriod,\n uint128 _maxRecoveryPeriod\n ) external override onlyOwner initializer(_isRecoveryPeriodInitialized) {\n _isRecoveryPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultRecoveryPeriod,\n _minRecoveryPeriod,\n _maxRecoveryPeriod\n );\n defaultRecoveryPeriod = _defaultRecoveryPeriod;\n minRecoveryPeriod = _minRecoveryPeriod;\n maxRecoveryPeriod = _maxRecoveryPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max lock period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultLockPeriod Default Lock Period for all Barz contracts\n * @param _minLockPeriod Minimum Lock Period for all Barz contracts\n * @param _maxLockPeriod Maximum Lock Period for all Barz contracts\n */\n function initializeLockPeriod(\n uint128 _defaultLockPeriod,\n uint128 _minLockPeriod,\n uint128 _maxLockPeriod\n ) external override onlyOwner initializer(_isLockPeriodInitialized) {\n _isLockPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultLockPeriod,\n _minLockPeriod,\n _maxLockPeriod\n );\n defaultLockPeriod = _defaultLockPeriod;\n minLockPeriod = _minLockPeriod;\n maxLockPeriod = _maxLockPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max approval validation period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultApprovalValidationPeriod Default Approval Validation Period for all Barz contracts\n * @param _minApprovalValidationPeriod Minimum Approval Validation Period for all Barz contracts\n * @param _maxApprovalValidationPeriod Maximum Approval Validation Period for all Barz contracts\n */\n function initializeApprovalValidationPeriod(\n uint128 _defaultApprovalValidationPeriod,\n uint128 _minApprovalValidationPeriod,\n uint128 _maxApprovalValidationPeriod\n )\n external\n override\n onlyOwner\n initializer(_isApprovalValidationPeriodInitialized)\n {\n _isApprovalValidationPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultApprovalValidationPeriod,\n _minApprovalValidationPeriod,\n _maxApprovalValidationPeriod\n );\n defaultApprovalValidationPeriod = _defaultApprovalValidationPeriod;\n minApprovalValidationPeriod = _minApprovalValidationPeriod;\n maxApprovalValidationPeriod = _maxApprovalValidationPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max migration period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultMigrationPeriod Default Migration Period for all Barz contracts\n * @param _minMigrationPeriod Minimum Migration Period for all Barz contracts\n * @param _maxMigrationPeriod Maximum Migration Period for all Barz contracts\n */\n function initializeMigrationPeriod(\n uint128 _defaultMigrationPeriod,\n uint128 _minMigrationPeriod,\n uint128 _maxMigrationPeriod\n ) external override onlyOwner initializer(_isMigrationPeriodInitialized) {\n _isMigrationPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultMigrationPeriod,\n _minMigrationPeriod,\n _maxMigrationPeriod\n );\n defaultMigrationPeriod = _defaultMigrationPeriod;\n minMigrationPeriod = _minMigrationPeriod;\n maxMigrationPeriod = _maxMigrationPeriod;\n }\n\n /**\n * @notice Wallet owner sets the addition security period for the wallet. Only the owner of wallet can call this function.\n * The addition security period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _additionSecurityPeriod Custom Addition Security Period for the wallet\n */\n function setAdditionSecurityPeriod(\n address _wallet,\n uint128 _additionSecurityPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _additionSecurityPeriod,\n minAdditionSecurityPeriod,\n maxAdditionSecurityPeriod\n );\n securityConfigs[_wallet]\n .additionSecurityPeriod = _additionSecurityPeriod;\n }\n\n /**\n * @notice Wallet owner sets the removal security period for the wallet. Only the owner of wallet can call this function.\n * The removal security period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _removalSecurityPeriod Custom Removal Security Period for the wallet\n */\n function setRemovalSecurityPeriod(\n address _wallet,\n uint128 _removalSecurityPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _removalSecurityPeriod,\n minRemovalSecurityPeriod,\n maxRemovalSecurityPeriod\n );\n securityConfigs[_wallet].removalSecurityPeriod = _removalSecurityPeriod;\n }\n\n /**\n * @notice Wallet owner sets the security window for the wallet. Only the owner of wallet can call this function.\n * The security window should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _securityWindow Custom Security Window for the wallet\n */\n function setSecurityWindow(\n address _wallet,\n uint128 _securityWindow\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _securityWindow,\n minSecurityWindow,\n maxSecurityWindow\n );\n securityConfigs[_wallet].securityWindow = _securityWindow;\n }\n\n /**\n * @notice Wallet owner sets the recovery period for the wallet. Only the owner of wallet can call this function.\n * The recovery period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _recoveryPeriod Custom recovery period for the wallet\n */\n function setRecoveryPeriod(\n address _wallet,\n uint128 _recoveryPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _recoveryPeriod,\n minRecoveryPeriod,\n maxRecoveryPeriod\n );\n securityConfigs[_wallet].recoveryPeriod = _recoveryPeriod;\n }\n\n /**\n * @notice Wallet owner sets the lock period for the wallet. Only the owner of wallet can call this function.\n * The lock period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _lockPeriod Custom Lock period for the wallet\n */\n function setLockPeriod(\n address _wallet,\n uint128 _lockPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(_lockPeriod, minLockPeriod, maxLockPeriod);\n securityConfigs[_wallet].lockPeriod = _lockPeriod;\n }\n\n /**\n * @notice Wallet owner sets the approval validation period for the wallet. Only the owner of wallet can call this function.\n * The approval validation period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _approvalValidationPeriod Custom approval validation period for the wallet\n */\n function setApprovalValidationPeriod(\n address _wallet,\n uint128 _approvalValidationPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _approvalValidationPeriod,\n minApprovalValidationPeriod,\n maxApprovalValidationPeriod\n );\n securityConfigs[_wallet]\n .approvalValidationPeriod = _approvalValidationPeriod;\n }\n\n /**\n * @notice Wallet owner sets the migration period for the wallet. Only the owner of wallet can call this function.\n * The migration period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _migrationPeriod Custom migration period for the wallet\n */\n\n function setMigrationPeriod(\n address _wallet,\n uint128 _migrationPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _migrationPeriod,\n minMigrationPeriod,\n maxMigrationPeriod\n );\n securityConfigs[_wallet].migrationPeriod = _migrationPeriod;\n }\n\n /**\n * @notice Returns the addition security period. Returns default value when custom addition security period is not set\n * @param _wallet Address of wallet\n * @return additionSecurityPeriod Addition Security Period of the given Barz account or wallet\n */\n function additionSecurityPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 additionSecurityPeriod)\n {\n additionSecurityPeriod = securityConfigs[_wallet]\n .additionSecurityPeriod;\n additionSecurityPeriod = (additionSecurityPeriod == 0)\n ? defaultAdditionSecurityPeriod\n : additionSecurityPeriod;\n }\n\n /**\n * @notice Returns the removal security period. Returns default value when custom removal security period is not set\n * @param _wallet Address of wallet\n * @return removalSecurityPeriod Removal Security Period of the given Barz account or wallet\n */\n function removalSecurityPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 removalSecurityPeriod)\n {\n removalSecurityPeriod = securityConfigs[_wallet].removalSecurityPeriod;\n removalSecurityPeriod = (removalSecurityPeriod == 0)\n ? defaultRemovalSecurityPeriod\n : removalSecurityPeriod;\n }\n\n /**\n * @notice Returns the security window. Returns default value when custom security window is not set\n * @param _wallet Address of wallet\n * @return securityWindow Security window of the given Barz account or wallet\n */\n function securityWindowOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 securityWindow)\n {\n securityWindow = securityConfigs[_wallet].securityWindow;\n securityWindow = (securityWindow == 0)\n ? defaultSecurityWindow\n : securityWindow;\n }\n\n /**\n * @notice Returns the recovery period. Returns default value when custom recovery period is not set\n * @param _wallet Address of wallet\n * @return recoveryPeriod Recovery Period of the given Barz account or wallet\n */\n function recoveryPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 recoveryPeriod)\n {\n recoveryPeriod = securityConfigs[_wallet].recoveryPeriod;\n recoveryPeriod = (recoveryPeriod == 0)\n ? defaultRecoveryPeriod\n : recoveryPeriod;\n }\n\n /**\n * @notice Returns the lock period. Returns default value when custom lock period is not set\n * @param _wallet Address of wallet\n * @return lockPeriod Lock Period of the given Barz account or wallet\n */\n function lockPeriodOf(\n address _wallet\n ) public view override onlyWallet(_wallet) returns (uint128 lockPeriod) {\n lockPeriod = securityConfigs[_wallet].lockPeriod;\n lockPeriod = (lockPeriod == 0) ? defaultLockPeriod : lockPeriod;\n }\n\n /**\n * @notice Returns the approval validation period. Returns default value when custom approval validation period is not set\n * @param _wallet Address of wallet\n * @return approvalValidationPeriod Approval Validation Period of the given Barz account or wallet\n */\n function approvalValidationPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityConfigs[_wallet]\n .approvalValidationPeriod;\n approvalValidationPeriod = (approvalValidationPeriod == 0)\n ? defaultApprovalValidationPeriod\n : approvalValidationPeriod;\n }\n\n /**\n * @notice Returns the migration period. Returns default value when custom migration period is not set\n * @param _wallet Address of wallet\n * @return migrationPeriod Migration Period of the given Barz account or wallet\n */\n function migrationPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 migrationPeriod)\n {\n migrationPeriod = securityConfigs[_wallet].migrationPeriod;\n migrationPeriod = (migrationPeriod == 0)\n ? defaultMigrationPeriod\n : migrationPeriod;\n }\n\n /**\n * @notice Validates if the period is smaller than the max period or bigger than the min period\n * @param _period Period to be checked\n * @param _minPeriod Minimum period\n * @param _maxPeriod Maximum period\n */\n function _validatePeriodBoundaries(\n uint128 _period,\n uint128 _minPeriod,\n uint128 _maxPeriod\n ) internal pure {\n if (_period >= _maxPeriod || _period <= _minPeriod)\n revert SecurityManager__OutOfBoundary();\n }\n}\n" + }, + "contracts/infrastructure/WhitelistStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {RemoteStorage} from \"./RemoteStorage.sol\";\n\n/**\n * @title Whitelist storage\n * @dev Maps addresses to the corresponsing array of whitelisted addresses for each of them.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract WhitelistStorage is RemoteStorage {\n /**\n * @dev Add the address to the whitelist storage\n * @param _wallet User wallet\n * @param _address Address to be whitelisted\n */\n function whitelistAddress(address _wallet, address _address) external {\n enforceWalletOrGuardianIfExists(_wallet);\n addAddress(_wallet, _address);\n }\n\n /**\n * @dev Removes the address from the whitelist storage\n * @param _wallet User wallet\n * @param _address Address to be removed from the whitelist\n */\n function blacklistAddress(address _wallet, address _address) external {\n enforceGuardianOrWallet(_wallet);\n removeAddress(_wallet, _address);\n }\n\n /**\n * @dev Returns whether the address exists in the whitelist storage, associated with the wallet\n * @param _wallet User wallet\n * @param _address Address to be whitelisted\n */\n function isWhitelisted(\n address _wallet,\n address _address\n ) external view returns (bool) {\n return exists(_wallet, _address);\n }\n\n /**\n * @dev Returns all whitelisted addresses associated with the wallet\n * @param _wallet User wallet\n */\n function getWhitelistedAddresses(\n address _wallet\n ) external view returns (address[] memory) {\n return getAddresses(_wallet);\n }\n}\n" + }, + "contracts/interfaces/ERC/IERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\n\npragma solidity 0.8.21;\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155Receiver {\n /**\n * @dev Handles the receipt of a single ERC1155 token type. This function is\n * called at the end of a `safeTransferFrom` after the balance has been updated.\n *\n * NOTE: To accept the transfer, this must return\n * `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n * (i.e. 0xf23a6e61, or its own function selector).\n *\n * @param operator The address which initiated the transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param id The ID of the token being transferred\n * @param value The amount of tokens being transferred\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n ) external returns (bytes4);\n\n /**\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\n * is called at the end of a `safeBatchTransferFrom` after the balances have\n * been updated.\n *\n * NOTE: To accept the transfer(s), this must return\n * `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n * (i.e. 0xbc197c81, or its own function selector).\n *\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "contracts/interfaces/ERC/IERC1271.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\ninterface IERC1271 {\n function isValidSignature(\n bytes32 hash,\n bytes memory signature\n ) external view returns (bytes4);\n}\n" + }, + "contracts/interfaces/ERC/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\ninterface IERC165 {\n /// @notice Query if a contract implements an interface\n /// @param interfaceId The interface identifier, as specified in ERC-165\n /// @dev Interface identification is specified in ERC-165. This function\n /// uses less than 30,000 gas.\n /// @return `true` if the contract implements `interfaceID` and\n /// `interfaceID` is not 0xffffffff, `false` otherwise\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/IERC173.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\n/// @title ERC-173 Contract Ownership Standard\n/// Note: the ERC-165 identifier for this interface is 0x7f5828d0\n/* is ERC165 */\ninterface IERC173 {\n /// @dev This emits when ownership of a contract changes.\n event OwnershipTransferred(\n address indexed previousOwner,\n address indexed newOwner\n );\n\n /// @notice Get the address of the owner\n /// @return owner_ The address of the owner.\n function owner() external view returns (address owner_);\n\n /// @notice Set the address of the new owner of the contract\n /// @dev Set _newOwner to address(0) to renounce any ownership.\n /// @param _newOwner The address of the new owner of the contract\n function transferOwnership(address _newOwner) external;\n}\n" + }, + "contracts/interfaces/ERC/IERC677Receiver.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\ninterface IERC677Receiver {\n function onTokenTransfer(\n address sender,\n uint value,\n bytes calldata data\n ) external pure returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155 is IERC165 {\n /**\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n */\n event TransferSingle(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256 id,\n uint256 value\n );\n\n /**\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n * transfers.\n */\n event TransferBatch(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\n\n /**\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n * `approved`.\n */\n event ApprovalForAll(\n address indexed account,\n address indexed operator,\n bool approved\n );\n\n /**\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n *\n * If an {URI} event was emitted for `id`, the standard\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n * returned by {IERC1155MetadataURI-uri}.\n */\n event URI(string value, uint256 indexed id);\n\n /**\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(\n address account,\n uint256 id\n ) external view returns (uint256);\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] calldata accounts,\n uint256[] calldata ids\n ) external view returns (uint256[] memory);\n\n /**\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n *\n * Emits an {ApprovalForAll} event.\n *\n * Requirements:\n *\n * - `operator` cannot be the caller.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n *\n * See {setApprovalForAll}.\n */\n function isApprovedForAll(\n address account,\n address operator\n ) external view returns (bool);\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes calldata data\n ) external;\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(\n address indexed owner,\n address indexed spender,\n uint256 value\n );\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` 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 amount) 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(\n address owner,\n address spender\n ) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the 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 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` 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(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(\n address spender,\n uint256 addedValue\n ) external returns (bool);\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(\n address spender,\n uint256 subtractedValue\n ) external returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(\n address indexed from,\n address indexed to,\n uint256 indexed tokenId\n );\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(\n address indexed owner,\n address indexed approved,\n uint256 indexed tokenId\n );\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(\n address indexed owner,\n address indexed operator,\n bool approved\n );\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(\n uint256 tokenId\n ) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(\n address owner,\n address operator\n ) external view returns (bool);\n}\n" + }, + "contracts/interfaces/IBarz.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Barz Interface\n * @dev Interface of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IBarz {\n error Barz__InitializationFailure();\n}\n" + }, + "contracts/interfaces/IBarzFactory.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Barz} from \"../Barz.sol\";\n\n/**\n * @title Barz Factory Interface\n * @dev Interface of contract to easily deploy Barz to a pre-computed address with a single call\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IBarzFactory {\n event BarzDeployed(address);\n\n function createAccount(\n address verificationFacet,\n bytes calldata owner,\n uint256 salt\n ) external returns (Barz);\n\n function getAddress(\n address verificationFacet,\n bytes calldata owner,\n uint256 salt\n ) external view returns (address);\n\n function getBytecode(\n address accountFacet,\n address verificationFacet,\n address entryPoint,\n address facetRegistry,\n address defaultFallback,\n bytes memory ownerPublicKey\n ) external pure returns (bytes memory);\n\n function getCreationCode() external pure returns (bytes memory);\n}\n" + }, + "contracts/libraries/DefaultLibDiamond.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\n\nerror InitializationFunctionReverted(\n address _initializationContractAddress,\n bytes _calldata\n);\n\nlibrary DefaultLibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION =\n keccak256(\"trustwallet.barz.diamond.storage\");\n\n struct FacetAddressAndPosition {\n address facetAddress;\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\n }\n\n struct FacetFunctionSelectors {\n bytes4[] functionSelectors;\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\n }\n\n struct DiamondStorage {\n // maps function selector to the facet address and\n // the position of the selector in the facetFunctionSelectors.selectors array\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\n // maps facet addresses to function selectors\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\n // facet addresses\n address[] facetAddresses;\n // Used to query if a contract implements an interface.\n // Used to implement ERC-165.\n mapping(bytes4 => bool) supportedInterfaces;\n }\n\n function diamondStorage()\n internal\n pure\n returns (DiamondStorage storage ds)\n {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n event DiamondCut(\n IDiamondCut.FacetCut[] _diamondCut,\n address _init,\n bytes _calldata\n );\n\n // Internal function version of diamondCut\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n for (\n uint256 facetIndex;\n facetIndex < _diamondCut.length;\n facetIndex++\n ) {\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\n if (action == IDiamondCut.FacetCutAction.Add) {\n addFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\n replaceFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\n removeFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else {\n revert(\"LibDiamondCut: Incorrect FacetCutAction\");\n }\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Add facet can't be address(0)\"\n );\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n require(\n oldFacetAddress == address(0),\n \"LibDiamondCut: Can't add function that already exists\"\n );\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function replaceFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Replace facet can't be address(0)\"\n );\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n require(\n oldFacetAddress != _facetAddress,\n \"LibDiamondCut: Can't replace function with same facet\"\n );\n removeFunction(ds, oldFacetAddress, selector);\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function removeFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n // if function does not exist then do nothing and return\n require(\n _facetAddress == address(0),\n \"LibDiamondCut: Remove facet address must be address(0)\"\n );\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n removeFunction(ds, oldFacetAddress, selector);\n }\n }\n\n function addFacet(\n DiamondStorage storage ds,\n address _facetAddress\n ) internal {\n enforceHasContractCode(\n _facetAddress,\n \"LibDiamondCut: New facet has no code\"\n );\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds\n .facetAddresses\n .length;\n ds.facetAddresses.push(_facetAddress);\n }\n\n function addFunction(\n DiamondStorage storage ds,\n bytes4 _selector,\n uint96 _selectorPosition,\n address _facetAddress\n ) internal {\n ds\n .selectorToFacetAndPosition[_selector]\n .functionSelectorPosition = _selectorPosition;\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(\n _selector\n );\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\n }\n\n function removeFunction(\n DiamondStorage storage ds,\n address _facetAddress,\n bytes4 _selector\n ) internal {\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Can't remove function that doesn't exist\"\n );\n // an immutable function is a function defined directly in a diamond\n require(\n _facetAddress != address(this),\n \"LibDiamondCut: Can't remove immutable function\"\n );\n // replace selector with last selector, then delete last selector\n uint256 selectorPosition = ds\n .selectorToFacetAndPosition[_selector]\n .functionSelectorPosition;\n uint256 lastSelectorPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors\n .length - 1;\n // if not the same then replace _selector with lastSelector\n if (selectorPosition != lastSelectorPosition) {\n bytes4 lastSelector = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors[lastSelectorPosition];\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[\n selectorPosition\n ] = lastSelector;\n ds\n .selectorToFacetAndPosition[lastSelector]\n .functionSelectorPosition = uint96(selectorPosition);\n }\n // delete the last selector\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\n delete ds.selectorToFacetAndPosition[_selector];\n\n // if no more selectors for facet address then delete the facet address\n if (lastSelectorPosition == 0) {\n // replace facet address with last facet address and delete last facet address\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\n uint256 facetAddressPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .facetAddressPosition;\n if (facetAddressPosition != lastFacetAddressPosition) {\n address lastFacetAddress = ds.facetAddresses[\n lastFacetAddressPosition\n ];\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\n ds\n .facetFunctionSelectors[lastFacetAddress]\n .facetAddressPosition = facetAddressPosition;\n }\n ds.facetAddresses.pop();\n delete ds\n .facetFunctionSelectors[_facetAddress]\n .facetAddressPosition;\n }\n }\n\n function initializeDiamondCut(\n address _init,\n bytes memory _calldata\n ) internal {\n if (_init == address(0)) {\n return;\n }\n enforceHasContractCode(\n _init,\n \"LibDiamondCut: _init address has no code\"\n );\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length > 0) {\n // bubble up error\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(error)\n revert(add(32, error), returndata_size)\n }\n } else {\n revert InitializationFunctionReverted(_init, _calldata);\n }\n }\n }\n\n function enforceHasContractCode(\n address _contract,\n string memory _errorMessage\n ) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize > 0, _errorMessage);\n }\n}\n" + }, + "contracts/libraries/LibAppStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SafeCast} from \"@openzeppelin/contracts/utils/math/SafeCast.sol\";\nimport {IEntryPoint} from \"../aa-4337/interfaces/IEntryPoint.sol\";\nimport {IFacetRegistry} from \"../infrastructure/interfaces/IFacetRegistry.sol\";\n\n/*\n * @title App Storage\n * @dev App storage for Barz contract to prevent storage collision\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\n\nstruct Lock {\n uint64 release;\n bytes4 locker;\n}\n\nstruct InitializersStorage {\n // NOTE: initialized is a variable to make sure the initialization is only done once.\n uint8 signerInitialized;\n uint8 accountInitialized;\n uint8 restrictionsInitialized;\n}\n\nstruct AppStorage {\n mapping(uint256 => InitializersStorage) initStorage;\n uint8 signerMigration;\n bytes4 validateOwnerSignatureSelector;\n IEntryPoint entryPoint;\n IFacetRegistry facetRegistry;\n mapping(uint256 => Lock) locks;\n}\n\nlibrary LibAppStorage {\n error LibAppStorage__AccountAlreadyUninitialized();\n error LibAppStorage__AccountMustBeUninitialized();\n error LibAppStorage__SignerAlreadyUninitialized();\n error LibAppStorage__SignerMustBeUninitialized();\n\n function appStorage() internal pure returns (AppStorage storage ds) {\n assembly {\n ds.slot := 0\n }\n }\n\n function setSignerUninitialized() internal {\n AppStorage storage s = appStorage();\n if (1 != s.initStorage[0].signerInitialized) {\n revert LibAppStorage__SignerAlreadyUninitialized();\n }\n s.initStorage[0].signerInitialized = 0;\n }\n\n function getValidateOwnerSignatureSelector()\n internal\n view\n returns (bytes4 selector)\n {\n selector = appStorage().validateOwnerSignatureSelector;\n }\n\n function setValidateOwnerSignatureSelector(\n bytes4 _validateOwnerSignatureSelector\n ) internal {\n appStorage()\n .validateOwnerSignatureSelector = _validateOwnerSignatureSelector;\n }\n\n function enforceSignerInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].signerInitialized) {\n revert LibAppStorage__SignerMustBeUninitialized();\n }\n s.initStorage[0].signerInitialized = 1;\n }\n\n function enforceAccountInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].accountInitialized) {\n revert LibAppStorage__AccountMustBeUninitialized();\n }\n s.initStorage[0].accountInitialized = 1;\n }\n\n function initiateSignerMigration() internal {\n appStorage().signerMigration = 1;\n }\n\n function enforceSignerMigration() internal view {\n if (1 != appStorage().signerMigration) {\n revert LibAppStorage__AccountMustBeUninitialized();\n }\n }\n\n function finalizeSignerMigration() internal {\n appStorage().signerMigration = 0;\n }\n\n function setLock(uint256 _releaseAfter, bytes4 _locker) internal {\n appStorage().locks[0] = Lock(SafeCast.toUint64(_releaseAfter), _locker);\n }\n\n function enforceRestrictionsInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].restrictionsInitialized)\n revert LibAppStorage__SignerMustBeUninitialized();\n s.initStorage[0].restrictionsInitialized = 1;\n }\n\n function setRestrictionsUninitialized() internal {\n AppStorage storage s = appStorage();\n if (1 != s.initStorage[0].restrictionsInitialized)\n revert LibAppStorage__AccountAlreadyUninitialized();\n s.initStorage[0].restrictionsInitialized = 0;\n }\n}\n\ncontract BarzStorage {\n AppStorage internal s;\n modifier onlyWhenUnlocked() {\n require(\n uint64(block.timestamp) >= s.locks[0].release,\n \"Account Locked\"\n );\n _;\n }\n modifier onlyWhenLocked() {\n require(\n uint64(block.timestamp) < s.locks[0].release,\n \"Account Unlocked\"\n );\n _;\n }\n}\n" + }, + "contracts/libraries/LibDiamond.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\n\nerror InitializationFunctionReverted(\n address _initializationContractAddress,\n bytes _calldata\n);\n\nlibrary LibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION =\n keccak256(\"trustwallet.barz.diamond.storage\");\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\n bytes4(keccak256(\"verifyRestrictions(address,address,uint256,bytes)\"));\n struct DiamondStorage {\n // maps function selectors to the facets that execute the functions.\n // and maps the selectors to their position in the selectorSlots array.\n // func selector => address facet, selector position\n mapping(bytes4 => bytes32) facets;\n // array of slots of function selectors.\n // each slot holds 8 function selectors.\n mapping(uint256 => bytes32) selectorSlots;\n // The number of function selectors in selectorSlots\n uint16 selectorCount;\n // Used to query if a contract implements an interface.\n // Used to implement ERC-165.\n mapping(bytes4 => bool) supportedInterfaces;\n // Default Fallback Handler of the barz.\n IDiamondLoupe defaultFallbackHandler;\n }\n\n function diamondStorage()\n internal\n pure\n returns (DiamondStorage storage ds)\n {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n function enforceIsSelf() internal view {\n require(msg.sender == address(this), \"LibDiamond: Caller not self\");\n }\n\n event DiamondCut(\n IDiamondCut.FacetCut[] _diamondCut,\n address _init,\n bytes _calldata\n );\n\n bytes32 constant CLEAR_ADDRESS_MASK =\n bytes32(uint256(0xffffffffffffffffffffffff));\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\n\n // Internal function version of diamondCut\n // This code is almost the same as the external diamondCut,\n // except it is using 'Facet[] memory _diamondCut' instead of\n // 'Facet[] calldata _diamondCut'.\n // The code is duplicated to prevent copying calldata to memory which\n // causes an error for a two dimensional array.\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n DiamondStorage storage ds = diamondStorage();\n uint256 originalSelectorCount = ds.selectorCount;\n uint256 selectorCount = originalSelectorCount;\n bytes32 selectorSlot;\n // Check if last selector slot is not full\n // \"selectorCount & 7\" is a gas efficient modulo by eight \"selectorCount % 8\"\n if (selectorCount & 7 > 0) {\n // get last selectorSlot\n // \"selectorSlot >> 3\" is a gas efficient division by 8 \"selectorSlot / 8\"\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\n }\n // loop through diamond cut\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\n selectorCount,\n selectorSlot,\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].action,\n _diamondCut[facetIndex].functionSelectors\n );\n\n unchecked {\n facetIndex++;\n }\n }\n if (selectorCount != originalSelectorCount) {\n ds.selectorCount = uint16(selectorCount);\n }\n // If last selector slot is not full\n // \"selectorCount & 7\" is a gas efficient modulo by eight \"selectorCount % 8\"\n if (selectorCount & 7 > 0) {\n // \"selectorSlot >> 3\" is a gas efficient division by 8 \"selectorSlot / 8\"\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addReplaceRemoveFacetSelectors(\n uint256 _selectorCount,\n bytes32 _selectorSlot,\n address _newFacetAddress,\n IDiamondCut.FacetCutAction _action,\n bytes4[] memory _selectors\n ) internal returns (uint256, bytes32) {\n DiamondStorage storage ds = diamondStorage();\n require(\n _selectors.length > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n if (_action == IDiamondCut.FacetCutAction.Add) {\n enforceHasContractCode(\n _newFacetAddress,\n \"LibDiamondCut: Add facet has no code\"\n );\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n require(\n address(bytes20(oldFacet)) == address(0),\n \"LibDiamondCut: Can't add function that already exists\"\n );\n // add facet for selector\n ds.facets[selector] =\n bytes20(_newFacetAddress) |\n bytes32(_selectorCount);\n // \"_selectorCount & 7\" is a gas efficient modulo by eight \"_selectorCount % 8\"\n // \" << 5 is the same as multiplying by 32 ( * 32)\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\n // clear selector position in slot and add selector\n _selectorSlot =\n (_selectorSlot &\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\n (bytes32(selector) >> selectorInSlotPosition);\n // if slot is full then write it to storage\n if (selectorInSlotPosition == 224) {\n // \"_selectorSlot >> 3\" is a gas efficient division by 8 \"_selectorSlot / 8\"\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\n _selectorSlot = 0;\n }\n _selectorCount++;\n\n unchecked {\n selectorIndex++;\n }\n }\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\n enforceHasContractCode(\n _newFacetAddress,\n \"LibDiamondCut: Replace facet has no code\"\n );\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n address oldFacetAddress = address(bytes20(oldFacet));\n // only useful if immutable functions exist\n require(\n oldFacetAddress != address(this),\n \"LibDiamondCut: Can't replace immutable function\"\n );\n require(\n oldFacetAddress != _newFacetAddress,\n \"LibDiamondCut: Can't replace function with same function\"\n );\n require(\n oldFacetAddress != address(0),\n \"LibDiamondCut: Can't replace function that doesn't exist\"\n );\n // replace old facet address\n ds.facets[selector] =\n (oldFacet & CLEAR_ADDRESS_MASK) |\n bytes20(_newFacetAddress);\n\n unchecked {\n selectorIndex++;\n }\n }\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\n require(\n _newFacetAddress == address(0),\n \"LibDiamondCut: Remove facet address must be address(0)\"\n );\n // \"_selectorCount >> 3\" is a gas efficient division by 8 \"_selectorCount / 8\"\n uint256 selectorSlotCount = _selectorCount >> 3;\n // \"_selectorCount & 7\" is a gas efficient modulo by eight \"_selectorCount % 8\"\n uint256 selectorInSlotIndex = _selectorCount & 7;\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n if (_selectorSlot == 0) {\n // get last selectorSlot\n selectorSlotCount--;\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\n selectorInSlotIndex = 7;\n } else {\n selectorInSlotIndex--;\n }\n bytes4 lastSelector;\n uint256 oldSelectorsSlotCount;\n uint256 oldSelectorInSlotPosition;\n // adding a block here prevents stack too deep error\n {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n require(\n address(bytes20(oldFacet)) != address(0),\n \"LibDiamondCut: Can't remove function that doesn't exist\"\n );\n // only useful if immutable functions exist\n require(\n address(bytes20(oldFacet)) != address(this),\n \"LibDiamondCut: Can't remove immutable function\"\n );\n // replace selector with last selector in ds.facets\n // gets the last selector\n // \" << 5 is the same as multiplying by 32 ( * 32)\n lastSelector = bytes4(\n _selectorSlot << (selectorInSlotIndex << 5)\n );\n if (lastSelector != selector) {\n // update last selector slot position info\n ds.facets[lastSelector] =\n (oldFacet & CLEAR_ADDRESS_MASK) |\n bytes20(ds.facets[lastSelector]);\n }\n delete ds.facets[selector];\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\n // \"oldSelectorCount >> 3\" is a gas efficient division by 8 \"oldSelectorCount / 8\"\n oldSelectorsSlotCount = oldSelectorCount >> 3;\n // \"oldSelectorCount & 7\" is a gas efficient modulo by eight \"oldSelectorCount % 8\"\n // \" << 5 is the same as multiplying by 32 ( * 32)\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\n }\n if (oldSelectorsSlotCount != selectorSlotCount) {\n bytes32 oldSelectorSlot = ds.selectorSlots[\n oldSelectorsSlotCount\n ];\n // clears the selector we are deleting and puts the last selector in its place.\n oldSelectorSlot =\n (oldSelectorSlot &\n ~(CLEAR_SELECTOR_MASK >>\n oldSelectorInSlotPosition)) |\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\n // update storage with the modified slot\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\n } else {\n // clears the selector we are deleting and puts the last selector in its place.\n _selectorSlot =\n (_selectorSlot &\n ~(CLEAR_SELECTOR_MASK >>\n oldSelectorInSlotPosition)) |\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\n }\n if (selectorInSlotIndex == 0) {\n delete ds.selectorSlots[selectorSlotCount];\n _selectorSlot = 0;\n }\n\n unchecked {\n selectorIndex++;\n }\n }\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\n } else {\n revert(\"LibDiamondCut: Incorrect FacetCutAction\");\n }\n return (_selectorCount, _selectorSlot);\n }\n\n function initializeDiamondCut(\n address _init,\n bytes memory _calldata\n ) internal {\n if (_init == address(0)) {\n return;\n }\n enforceHasContractCode(\n _init,\n \"LibDiamondCut: _init address has no code\"\n );\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length > 0) {\n // bubble up error\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(error)\n revert(add(32, error), returndata_size)\n }\n } else {\n revert InitializationFunctionReverted(_init, _calldata);\n }\n }\n }\n\n function enforceHasContractCode(\n address _contract,\n string memory _errorMessage\n ) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize > 0, _errorMessage);\n }\n\n function restrictionsFacet() internal view returns (address facetAddress_) {\n facetAddress_ = address(\n bytes20(\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\n )\n );\n }\n}\n" + }, + "contracts/libraries/LibFacetStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Storage\n * @dev Storage contract to store each facets variables with diamond storage\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\n\nstruct Secp256k1VerificationStorage {\n address signer;\n}\n\nstruct Secp256r1VerificationStorage {\n uint256[2] q;\n}\n\nstruct GuardianStorage {\n mapping(bytes32 => uint256) pending;\n mapping(uint8 => StorageConfig) configs;\n}\n\nstruct Info {\n bool exists;\n uint128 index;\n}\n\nstruct StorageConfig {\n address[] addresses;\n mapping(address => Info) info;\n}\n\nstruct RecoveryConfig {\n bytes recoveryPublicKey;\n uint64 executeAfter;\n}\n\nstruct ApprovalConfig {\n bool isApproved;\n uint64 validUntil;\n}\n\nstruct RecoveryApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isNewOwnerApproved;\n}\n\nstruct RecoveryStorage {\n mapping(uint8 => RecoveryConfig) recoveryConfigs;\n mapping(uint8 => RecoveryApprovalConfig) recoveryApprovalConfigs;\n uint128 nonce;\n}\n\nstruct RestrictionsStorage {\n address[] restrictions;\n mapping(address => bool) exists;\n}\n\nstruct SignatureMigrationConfig {\n bytes migrationPublicKey;\n address migrationVerificationFacet;\n bytes4[] migrationSelectors;\n uint64 migrateAfter;\n}\n\nstruct SignatureMigrationApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isMigrationApproved;\n}\n\nstruct SignatureMigrationStorage {\n mapping(uint8 => SignatureMigrationConfig) migrationConfigs;\n mapping(uint8 => SignatureMigrationApprovalConfig) migrationApprovalConfigs;\n uint128 nonce;\n}\n\nstruct DiamondCutApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isDiamondCutApproved;\n}\n\nstruct DiamondCutStorage {\n mapping(uint8 => DiamondCutApprovalConfig) diamondCutApprovalConfigs;\n uint128 nonce;\n}\n\nstruct LockStorage {\n uint128 nonce;\n}\n\nlibrary LibFacetStorage {\n bytes32 constant K1_STORAGE_POSITION =\n keccak256(\n \"v0.trustwallet.diamond.storage.Secp256k1VerificationStorage\"\n );\n bytes32 constant R1_STORAGE_POSITION =\n keccak256(\n \"v0.trustwallet.diamond.storage.Secp256r1VerificationStorage\"\n );\n bytes32 constant GUARDIAN_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.GuardianStorage\");\n bytes32 constant RECOVERY_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.RecoveryStorage\");\n bytes32 constant RESTRICTION_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.RestrictionsStorage\");\n bytes32 constant MIGRATION_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.SignatureMigrationStorage\");\n bytes32 constant DIAMONDCUT_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.DiamondCutStorage\");\n bytes32 constant LOCK_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.LockStorage\");\n\n function k1Storage()\n internal\n pure\n returns (Secp256k1VerificationStorage storage ds)\n {\n bytes32 storagePosition = K1_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function r1Storage()\n internal\n pure\n returns (Secp256r1VerificationStorage storage ds)\n {\n bytes32 storagePosition = R1_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function guardianStorage()\n internal\n pure\n returns (GuardianStorage storage ds)\n {\n bytes32 storagePosition = GUARDIAN_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function recoveryStorage()\n internal\n pure\n returns (RecoveryStorage storage ds)\n {\n bytes32 storagePosition = RECOVERY_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function restrictionsStorage()\n internal\n pure\n returns (RestrictionsStorage storage ds)\n {\n bytes32 storagePosition = RESTRICTION_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function migrationStorage()\n internal\n pure\n returns (SignatureMigrationStorage storage ds)\n {\n bytes32 storagePosition = MIGRATION_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function diamondCutStorage()\n internal\n pure\n returns (DiamondCutStorage storage ds)\n {\n bytes32 storagePosition = DIAMONDCUT_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function lockStorage() internal pure returns (LockStorage storage ds) {\n bytes32 storagePosition = LOCK_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n}\n" + }, + "contracts/libraries/LibGuardian.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibFacetStorage, StorageConfig} from \"./LibFacetStorage.sol\";\n\n/**\n * @title LibGuardian\n * @dev Internal Library to provide utility feature for Guardians stored in Guardian Facet Storage\n * @author David Yongjun Kim (@Powerstream3604)\n */\nlibrary LibGuardian {\n function majorityOfGuardians()\n internal\n view\n returns (uint256 guardianNumber)\n {\n uint256 guardianLength = guardianCount();\n guardianNumber = (guardianLength == 0) ? 0 : guardianLength / 2 + 1;\n }\n\n function isGuardian(address _guardian) internal view returns (bool) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n return config.info[_guardian].exists;\n }\n\n function guardianCount() internal view returns (uint256) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n return config.addresses.length;\n }\n\n function getGuardians() internal view returns (address[] memory) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n address[] memory addresses = new address[](config.addresses.length);\n uint256 addressesLen = config.addresses.length;\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n return addresses;\n }\n}\n" + }, + "contracts/libraries/LibLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {LibDiamond} from \"./LibDiamond.sol\";\n\n/**\n * @title LibLoupe\n * @dev Internal Library to provide utility feature for reading the state of diamond facets\n * Originally from Diamond's implementation of Mudgen(author of EIP-2535)\n */\nlibrary LibLoupe {\n /// @notice Gets all facets and their selectors.\n /// @return facets_ Facet\n function facets()\n internal\n view\n returns (IDiamondLoupe.Facet[] memory facets_)\n {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facets_ = new IDiamondLoupe.Facet[](ds.selectorCount);\n uint16[] memory numFacetSelectors = new uint16[](ds.selectorCount);\n uint256 numFacets;\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facetAddress_ = address(bytes20(ds.facets[selector]));\n bool continueLoop;\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n if (facets_[facetIndex].facetAddress == facetAddress_) {\n facets_[facetIndex].functionSelectors[\n numFacetSelectors[facetIndex]\n ] = selector;\n // probably will never have more than 256 functions from one facet contract\n require(numFacetSelectors[facetIndex] < 255);\n numFacetSelectors[facetIndex]++;\n continueLoop = true;\n break;\n }\n }\n if (continueLoop) {\n continue;\n }\n facets_[numFacets].facetAddress = facetAddress_;\n facets_[numFacets].functionSelectors = new bytes4[](\n ds.selectorCount\n );\n facets_[numFacets].functionSelectors[0] = selector;\n numFacetSelectors[numFacets] = 1;\n numFacets++;\n }\n }\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n uint256 numSelectors = numFacetSelectors[facetIndex];\n bytes4[] memory selectors = facets_[facetIndex].functionSelectors;\n // setting the number of selectors\n assembly {\n mstore(selectors, numSelectors)\n }\n }\n // setting the number of facets\n assembly {\n mstore(facets_, numFacets)\n }\n }\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n /// @return _facetFunctionSelectors The selectors associated with a facet address.\n function facetFunctionSelectors(\n address _facet\n ) internal view returns (bytes4[] memory _facetFunctionSelectors) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n uint256 numSelectors;\n _facetFunctionSelectors = new bytes4[](ds.selectorCount);\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facet = address(bytes20(ds.facets[selector]));\n if (_facet == facet) {\n _facetFunctionSelectors[numSelectors] = selector;\n numSelectors++;\n }\n }\n }\n // Set the number of selectors in the array\n assembly {\n mstore(_facetFunctionSelectors, numSelectors)\n }\n }\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses()\n internal\n view\n returns (address[] memory facetAddresses_)\n {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facetAddresses_ = new address[](ds.selectorCount);\n uint256 numFacets;\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facetAddress_ = address(bytes20(ds.facets[selector]));\n bool continueLoop;\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n if (facetAddress_ == facetAddresses_[facetIndex]) {\n continueLoop = true;\n break;\n }\n }\n if (continueLoop) {\n continue;\n }\n facetAddresses_[numFacets] = facetAddress_;\n numFacets++;\n }\n }\n // Set the number of facet addresses in the array\n assembly {\n mstore(facetAddresses_, numFacets)\n }\n }\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(\n bytes4 _functionSelector\n ) internal view returns (address facetAddress_) {\n facetAddress_ = address(\n bytes20(LibDiamond.diamondStorage().facets[_functionSelector])\n );\n }\n}\n" + }, + "contracts/libraries/LibMultiSigStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Multi-sig Storage\n * @dev Storage contract for storing Multi-sig Facet variables in diamond storage pattern\n * @author David Yongjun Kim (@Powerstream3604)\n */\n\nstruct MultiSigStorage {\n mapping(address => address) owners;\n mapping(uint256 => mapping(address => mapping(bytes32 => uint256))) approvedHashes;\n uint256 ownerCount;\n uint256 threshold;\n uint256 counter;\n}\n\nlibrary LibMultiSigStorage {\n function multisigStorage()\n internal\n pure\n returns (MultiSigStorage storage ds)\n {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.MultiSigStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n}\n" + }, + "contracts/libraries/LibRecoverSpender.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title RecoverSpender\n * @dev Library to determine the action and spender of calldata\n * @author Ruslan Serebriakov (@rsrbk)\n */\nlibrary LibRecoverSpender {\n // ERC20, ERC721 & ERC1155 transfers & approvals\n bytes4 private constant ERC20_TRANSFER =\n bytes4(keccak256(\"transfer(address,uint256)\"));\n bytes4 private constant ERC20_APPROVE =\n bytes4(keccak256(\"approve(address,uint256)\"));\n bytes4 private constant ERC20_INCREASE_ALLOWANCE =\n bytes4(keccak256(\"increaseAllowance(address,uint256)\"));\n bytes4 private constant ERC20_DECREASE_ALLOWANCE =\n bytes4(keccak256(\"decreaseAllowance(address,uint256)\"));\n bytes4 private constant ERC721_SET_APPROVAL_FOR_ALL =\n bytes4(keccak256(\"setApprovalForAll(address,bool)\"));\n bytes4 private constant ERC721_TRANSFER_FROM =\n bytes4(keccak256(\"transferFrom(address,address,uint256)\"));\n bytes4 private constant ERC721_SAFE_TRANSFER_FROM =\n bytes4(keccak256(\"safeTransferFrom(address,address,uint256)\"));\n bytes4 private constant ERC721_SAFE_TRANSFER_FROM_BYTES =\n bytes4(keccak256(\"safeTransferFrom(address,address,uint256,bytes)\"));\n bytes4 private constant ERC1155_SAFE_TRANSFER_FROM =\n bytes4(\n keccak256(\"safeTransferFrom(address,address,uint256,uint256,bytes)\")\n );\n bytes4 private constant ERC1155_SAFE_BATCH_TRANSFER_FROM =\n bytes4(\n keccak256(\n \"safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)\"\n )\n );\n\n /**\n * @notice Helper method to recover the spender from a contract call.\n * The method returns the contract unless the call is to a standard method of a ERC20/ERC721/ERC1155 token\n * in which case the spender is recovered from the data.\n * @param _to The target contract.\n * @param _data The data payload.\n */\n function _recover(\n address _to,\n bytes memory _data\n ) internal pure returns (address spender) {\n if (_data.length >= 68) {\n bytes4 methodId;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n methodId := mload(add(_data, 0x20))\n }\n if (\n methodId == ERC20_TRANSFER ||\n methodId == ERC20_APPROVE ||\n methodId == ERC20_INCREASE_ALLOWANCE ||\n methodId == ERC20_DECREASE_ALLOWANCE ||\n methodId == ERC721_SET_APPROVAL_FOR_ALL\n ) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n spender := mload(add(_data, 0x24))\n }\n return spender;\n }\n if (\n methodId == ERC721_TRANSFER_FROM ||\n methodId == ERC721_SAFE_TRANSFER_FROM ||\n methodId == ERC721_SAFE_TRANSFER_FROM_BYTES ||\n methodId == ERC1155_SAFE_TRANSFER_FROM ||\n methodId == ERC1155_SAFE_BATCH_TRANSFER_FROM\n ) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n spender := mload(add(_data, 0x44))\n }\n return spender;\n }\n }\n\n spender = _to;\n }\n}\n" + }, + "contracts/libraries/LibReentrancyGuardStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nstruct ReentrancyGuardStorage {\n uint256 status;\n}\n\nlibrary LibReentrancyGuardStorage {\n bytes32 private constant REENTRANCY_GUARD_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.ReentrancyGuardStorage\");\n\n function reentrancyguardStorage()\n internal\n pure\n returns (ReentrancyGuardStorage storage ds)\n {\n bytes32 storagePosition = REENTRANCY_GUARD_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n}" + }, + "contracts/libraries/LibUtils.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\n\nlibrary LibUtils {\n // Internal utility functions\n function mergeArrays(\n bytes4[] memory _array1,\n bytes4[] memory _array2\n ) internal pure returns (bytes4[] memory) {\n uint256 length1 = _array1.length;\n uint256 length2 = _array2.length;\n bytes4[] memory mergedArray = new bytes4[](length1 + length2);\n\n for (uint256 i; i < length1; ) {\n mergedArray[i] = _array1[i];\n unchecked {\n ++i;\n }\n }\n\n for (uint256 i; i < length2; ) {\n mergedArray[length1 + i] = _array2[i];\n unchecked {\n ++i;\n }\n }\n\n return mergedArray;\n }\n\n function removeFacetElement(\n IDiamondLoupe.Facet[] memory _facets,\n uint256 _index\n ) internal pure returns (IDiamondLoupe.Facet[] memory) {\n require(_index < _facets.length, \"Invalid index\");\n require(_facets.length != 0, \"Invalid array\");\n\n // Create a new array with a length of `_facets.length - 1`\n IDiamondLoupe.Facet[] memory newArray = new IDiamondLoupe.Facet[](\n _facets.length - 1\n );\n uint256 newArrayLength = newArray.length;\n // Iterate over the original array, skipping the element at the specified `index`\n for (uint256 i; i < newArrayLength; ) {\n if (i < _index) {\n newArray[i] = _facets[i];\n } else {\n newArray[i] = _facets[i + 1];\n }\n unchecked {\n ++i;\n }\n }\n\n return newArray;\n }\n\n function removeElement(\n bytes4[] memory _array,\n uint256 _index\n ) internal pure returns (bytes4[] memory) {\n require(_index < _array.length, \"Invalid index\");\n require(_array.length != 0, \"Invalid array\");\n\n bytes4[] memory newArray = new bytes4[](_array.length - 1);\n uint256 newArrayLength = newArray.length;\n for (uint256 i; i < newArrayLength; ) {\n if (i < _index) {\n newArray[i] = _array[i];\n } else {\n newArray[i] = _array[i + 1];\n }\n unchecked {\n ++i;\n }\n }\n\n return newArray;\n }\n\n function setValue(\n bytes4[] memory _keys,\n address[] memory _values,\n bytes4 _key,\n address _value\n ) internal pure returns (bytes4[] memory, address[] memory) {\n uint256 index = findIndex(_keys, _key);\n uint256 keysLength = _keys.length;\n if (index < keysLength) {\n _values[index] = _value;\n } else {\n // Create new storage arrays\n bytes4[] memory newKeys = new bytes4[](keysLength + 1);\n address[] memory newValues = new address[](_values.length + 1);\n\n // Copy values to the new storage arrays\n for (uint256 i; i < keysLength; ) {\n newKeys[i] = _keys[i];\n newValues[i] = _values[i];\n\n unchecked {\n ++i;\n }\n }\n\n // Add the new key-value pair\n newKeys[keysLength] = _key;\n newValues[_values.length] = _value;\n\n return (newKeys, newValues);\n }\n\n // If the key already exists, return the original arrays\n return (_keys, _values);\n }\n\n function getValue(\n bytes4[] memory _keys,\n address[] memory _values,\n bytes4 _key\n ) internal pure returns (address) {\n uint256 index = findIndex(_keys, _key);\n if (index >= _keys.length) return address(0);\n\n return _values[index];\n }\n\n function findIndex(\n bytes4[] memory _keys,\n bytes4 _key\n ) internal pure returns (uint256) {\n uint256 keysLength = _keys.length;\n for (uint256 i; i < keysLength; ) {\n if (_keys[i] == _key) {\n return i;\n }\n unchecked {\n ++i;\n }\n }\n return keysLength;\n }\n}\n" + }, + "contracts/restrictions/IRestriction.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Interface for restrictions\n * @dev Restriction is a contract which decides whether to approve a certain kind of transaction, based on its internal logic.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface IRestriction {\n /**\n * @dev Based on restriction's internal logic, it should accept or reject a certain transaction.\n * @param from The address of the sender, that will be signing the transaction.\n * @param to The receiving address.\n * @param value Amount of ETH to transfer from sender to recipient.\n * @param _calldata Optional field to include arbitrary data.\n * @return bool value for whether the check is passed\n */\n function check(\n address from,\n address to,\n uint256 value,\n bytes calldata _calldata\n ) external returns (bool);\n}\n" + }, + "contracts/restrictions/WhitelistRestriction.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibRecoverSpender} from \"../libraries/LibRecoverSpender.sol\";\nimport {WhitelistStorage} from \"../infrastructure/WhitelistStorage.sol\";\nimport {IRestriction} from \"./IRestriction.sol\";\n\n/**\n * @title Whitelist Restriction\n * @dev This restriction defines a list of accepted addresses and denies any interaction with addresses outside of it.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract WhitelistRestriction is IRestriction {\n WhitelistStorage public immutable whitelistStorage;\n\n constructor(WhitelistStorage _whitelistStorage) {\n whitelistStorage = _whitelistStorage;\n }\n\n /**\n * @notice Helper method to recover the spender from a contract call.\n * The method returns the contract unless the call is to a standard method of a ERC20/ERC721/ERC1155 token\n * in which case the spender is recovered from the data.\n * @param _to The target contract.\n * @param _data The data payload.\n */\n function recoverSpender(\n address _to,\n bytes memory _data\n ) public pure returns (address spender) {\n return LibRecoverSpender._recover(_to, _data);\n }\n\n /*\n * @dev IRestriction's implementation. It will allow transaction if the sender is whitelisted, or user, or the whitelist storage.\n * @param _from The address of the sender, that will be signing the transaction.\n * @param _to The receiving address.\n * @param _calldata Optional field to include arbitrary data.\n * @return result value for whether the check is passed\n */\n function check(\n address _from,\n address _to,\n uint256 /*_value*/,\n bytes calldata _calldata\n ) external view override returns (bool result) {\n return\n whitelistStorage.isWhitelisted(\n _from,\n LibRecoverSpender._recover(_to, _calldata)\n ) ||\n _to == address(whitelistStorage) ||\n _to == msg.sender;\n }\n}\n" + }, + "contracts/test/TestCounter.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\ncontract TestCounter {\n int private count = 0;\n\n event CounterIncremented(int count);\n event CounterDecremented(int count);\n\n function incrementCounter() public {\n count += 1;\n emit CounterIncremented(count);\n }\n\n function decrementCounter() public {\n count -= 1;\n emit CounterIncremented(count);\n }\n\n function getCount() public view returns (int) {\n return count;\n }\n}\n" + }, + "contracts/test/TestERC1155.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC1155/ERC1155.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\n\ncontract TestERC1155 is ERC1155 {\n using Counters for Counters.Counter;\n\n Counters.Counter private _tokenIds;\n\n constructor() ERC1155(\"\") {}\n\n function mint(address account, uint256 amount) external {\n uint256 tokenId = _getNextTokenId();\n _mint(account, tokenId, amount, \"\");\n }\n\n function mintBatch(\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes memory data\n ) external {\n require(\n ids.length == amounts.length,\n \"TestERC1155: arrays length mismatch\"\n );\n\n _mintBatch(to, ids, amounts, data);\n }\n\n function _getNextTokenId() private returns (uint256) {\n _tokenIds.increment();\n return _tokenIds.current();\n }\n}\n" + }, + "contracts/test/TestERC777.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC777/ERC777.sol\";\n\ncontract TestERC777 is ERC777 {\n constructor(\n address[] memory _operators\n ) ERC777(\"TestERC777\", \"TERC777\", _operators) {}\n\n function mint(address account, uint256 amount) external {\n _mint(account, amount, \"\", \"\");\n }\n}\n" + }, + "contracts/test/TestInvalidSecp256k1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IVerificationFacet} from \"../facets/interfaces/IVerificationFacet.sol\";\nimport {IERC1271} from \"../interfaces/ERC/IERC1271.sol\";\nimport {AppStorage, LibAppStorage, BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {LibFacetStorage, Secp256k1VerificationStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {UserOperation} from \"../aa-4337/interfaces/UserOperation.sol\";\n\n/**\n * @title Test Secp256k1 verification facet\n * @dev Default Ethereum's elliptic curve\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract TestInvalidSecp256k1VerificationFacet is BarzStorage, IERC1271 {\n using ECDSA for bytes32;\n error Secp256k1VerificationFacet__InvalidSignerLength();\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n\n event SignerUninitialized();\n\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n }\n\n // THIS INVALID FACET DOES NOT INCLUDE initializeSigner()\n // THIS FACET IS USED TO TEST WHEN initializeSigner() DOESN'T EXIST IN FACET\n\n function uninitializeSigner() external returns (uint256 uninitSuccess) {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view returns (uint256 validationData) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n return validateSignature(userOp, userOpHash, k1Storage.signer);\n }\n\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n address signer\n ) public pure returns (uint256) {\n bytes32 hash = userOpHash.toEthSignedMessageHash();\n if (signer != hash.recover(userOp.signature)) return 1;\n return 0;\n }\n\n // This is REMOVED for testing purpose\n function validateOwnerSignatureSelector() public pure returns (bytes4) {\n // return this.validateOwnerSignature.selector;\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n function owner() public view returns (bytes memory) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n return abi.encodePacked(k1Storage.signer);\n }\n\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure returns (bool) {\n return (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (_hash.recover(_signature) ==\n LibFacetStorage.k1Storage().signer)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n}\n" + }, + "contracts/test/TestNFT.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\n\ncontract TestNFT is ERC721 {\n using Counters for Counters.Counter;\n Counters.Counter private currentTokenId;\n\n constructor() ERC721(\"TestNFT\", \"TNFT\") {}\n\n function mint(address recipient) public returns (uint256) {\n currentTokenId.increment();\n uint256 newItemId = currentTokenId.current();\n _safeMint(recipient, newItemId);\n return newItemId;\n }\n}\n" + }, + "contracts/test/TestToken.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract TestToken is ERC20 {\n constructor()\n // solhint-disable-next-line no-empty-blocks\n ERC20(\"TST\", \"TestToken\")\n {}\n\n function mint(address sender, uint256 amount) external {\n _mint(sender, amount);\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 999999 + }, + "evmVersion": "paris", + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/deployments/opBNB/.chainId b/deployments/opBNB/.chainId new file mode 100644 index 0000000..cbd6012 --- /dev/null +++ b/deployments/opBNB/.chainId @@ -0,0 +1 @@ +204 \ No newline at end of file diff --git a/deployments/opBNB/AccountFacet.json b/deployments/opBNB/AccountFacet.json new file mode 100644 index 0000000..8f9eee9 --- /dev/null +++ b/deployments/opBNB/AccountFacet.json @@ -0,0 +1,591 @@ +{ + "address": "0xFde53272dcd7938d16E031A6989753c321728332", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "AccountFacet__CallNotSuccessful", + "type": "error" + }, + { + "inputs": [], + "name": "AccountFacet__InitializationFailure", + "type": "error" + }, + { + "inputs": [], + "name": "AccountFacet__InvalidArrayLength", + "type": "error" + }, + { + "inputs": [], + "name": "AccountFacet__NonExistentVerificationFacet", + "type": "error" + }, + { + "inputs": [], + "name": "AccountFacet__RestrictionsFailure", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_initializationContractAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "InitializationFunctionReverted", + "type": "error" + }, + { + "inputs": [], + "name": "LibAppStorage__AccountMustBeUninitialized", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract IEntryPoint", + "name": "entryPoint", + "type": "address" + }, + { + "indexed": true, + "internalType": "bytes", + "name": "ownerPublicKey", + "type": "bytes" + } + ], + "name": "AccountInitialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "indexed": false, + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "DiamondCut", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "VerificationFailure", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "VerificationSuccess", + "type": "event" + }, + { + "inputs": [], + "name": "entryPoint", + "outputs": [ + { + "internalType": "contract IEntryPoint", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_dest", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_func", + "type": "bytes" + } + ], + "name": "execute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_dest", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "_value", + "type": "uint256[]" + }, + { + "internalType": "bytes[]", + "name": "_func", + "type": "bytes[]" + } + ], + "name": "executeBatch", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getNonce", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_verificationFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_anEntryPoint", + "type": "address" + }, + { + "internalType": "address", + "name": "_facetRegistry", + "type": "address" + }, + { + "internalType": "address", + "name": "_defaultFallBackHandler", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_ownerPublicKey", + "type": "bytes" + } + ], + "name": "initialize", + "outputs": [ + { + "internalType": "uint256", + "name": "initSuccess", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "initCode", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "callGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "verificationGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "preVerificationGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxFeePerGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPriorityFeePerGas", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "paymasterAndData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "internalType": "struct UserOperation", + "name": "userOp", + "type": "tuple" + }, + { + "internalType": "bytes32", + "name": "userOpHash", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "missingAccountFunds", + "type": "uint256" + } + ], + "name": "validateUserOp", + "outputs": [ + { + "internalType": "uint256", + "name": "validationData", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0xd1da2d242d5dcf60e4e169d530fa277062d704266a45d8723b028fdce8adcde3", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 3, + "gasUsed": "2369950", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x625a37b71d3b1c95f2930d56ec8b65250c28e493854a92d703fcbc684fa83058", + "transactionHash": "0xd1da2d242d5dcf60e4e169d530fa277062d704266a45d8723b028fdce8adcde3", + "logs": [], + "blockNumber": 8731259, + "cumulativeGasUsed": "2492079", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 2, + "solcInputHash": "4356503edd8ae34e73cb6dd1c8e2fc8a", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AccountFacet__CallNotSuccessful\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AccountFacet__InitializationFailure\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AccountFacet__InvalidArrayLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AccountFacet__NonExistentVerificationFacet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AccountFacet__RestrictionsFailure\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_initializationContractAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"InitializationFunctionReverted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LibAppStorage__AccountMustBeUninitialized\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract IEntryPoint\",\"name\":\"entryPoint\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes\",\"name\":\"ownerPublicKey\",\"type\":\"bytes\"}],\"name\":\"AccountInitialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"DiamondCut\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"VerificationFailure\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"VerificationSuccess\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"entryPoint\",\"outputs\":[{\"internalType\":\"contract IEntryPoint\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_dest\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_func\",\"type\":\"bytes\"}],\"name\":\"execute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_dest\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"_value\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes[]\",\"name\":\"_func\",\"type\":\"bytes[]\"}],\"name\":\"executeBatch\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_verificationFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_anEntryPoint\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_facetRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_defaultFallBackHandler\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_ownerPublicKey\",\"type\":\"bytes\"}],\"name\":\"initialize\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"initSuccess\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"userOp\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"missingAccountFunds\",\"type\":\"uint256\"}],\"name\":\"validateUserOp\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"validationData\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"Account module contract that provides the account features and initialization of signer compatible with EIP-1271 & EIP-4337\",\"kind\":\"dev\",\"methods\":{\"execute(address,uint256,bytes)\":{\"details\":\"This method executes the calldata coming from the EntryPoint. Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\",\"params\":{\"_dest\":\"Address of destination where the call will be forwarded to\",\"_func\":\"Bytes of calldata to execute in the destination address\",\"_value\":\"Amount of native coin the owner is willing to send(e.g. ETH, BNB)\"}},\"executeBatch(address[],uint256[],bytes[])\":{\"details\":\"This method batch executes the calldata coming from the EntryPoint. Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\",\"params\":{\"_dest\":\"Array of addresses of destination where the call will be forwarded to\",\"_func\":\"Array of bytes of calldata to execute in the destination address\",\"_value\":\"Array of amount of native coin the owner is willing to send(e.g. ETH, BNB)\"}},\"initialize(address,address,address,address,bytes)\":{\"details\":\"This method can only be called during the initialization or signature migration. If the proxy contract was created without initialization, anyone can call initialize. Barz calls initialize in constructor in an atomic transaction during deployment\",\"params\":{\"_anEntryPoint\":\"Entrypoint contract defined in EIP-4337 handling the flow of UserOp\",\"_defaultFallBackHandler\":\"Middleware contract for default facets\",\"_facetRegistry\":\"Registry of Facets that hold all facet information\",\"_ownerPublicKey\":\"Bytes of owner public key\",\"_verificationFacet\":\"Facet contract handling the verificationi\"}}},\"title\":\"Account Facet\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"This constructor ensures that this contract can only be used as singleton for Proxy contracts\"},\"entryPoint()\":{\"notice\":\"Returns the address of EntryPoint contract registered to Barz account\"},\"execute(address,uint256,bytes)\":{\"notice\":\"Calls the destination with inputted calldata and value from EntryPoint\"},\"executeBatch(address[],uint256[],bytes[])\":{\"notice\":\"Batch calls the destination with inputted calldata and value from EntryPoint\"},\"getNonce()\":{\"notice\":\"Return the account nonce. This method returns the next sequential nonce. For a nonce of a specific key, use `entrypoint.getNonce(account, key)`\"},\"initialize(address,address,address,address,bytes)\":{\"notice\":\"Initializes the initial storage of the Barz contract.\"},\"validateUserOp((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256)\":{\"notice\":\"Validate user's signature and nonce. subclass doesn't need to override this method. Instead, it should override the specific internal validation methods.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/AccountFacet.sol\":\"AccountFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./math/Math.sol\\\";\\nimport \\\"./math/SignedMath.sol\\\";\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n uint256 length = Math.log10(value) + 1;\\n string memory buffer = new string(length);\\n uint256 ptr;\\n /// @solidity memory-safe-assembly\\n assembly {\\n ptr := add(buffer, add(32, length))\\n }\\n while (true) {\\n ptr--;\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\\n }\\n value /= 10;\\n if (value == 0) break;\\n }\\n return buffer;\\n }\\n }\\n\\n /**\\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\\n */\\n function toString(int256 value) internal pure returns (string memory) {\\n return string(abi.encodePacked(value < 0 ? \\\"-\\\" : \\\"\\\", toString(SignedMath.abs(value))));\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n return toHexString(value, Math.log256(value) + 1);\\n }\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n\\n /**\\n * @dev Returns true if the two strings are equal.\\n */\\n function equal(string memory a, string memory b) internal pure returns (bool) {\\n return keccak256(bytes(a)) == keccak256(bytes(b));\\n }\\n}\\n\",\"keccak256\":\"0x3088eb2868e8d13d89d16670b5f8612c4ab9ff8956272837d8e90106c59c14a0\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Strings.sol\\\";\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSA {\\n enum RecoverError {\\n NoError,\\n InvalidSignature,\\n InvalidSignatureLength,\\n InvalidSignatureS,\\n InvalidSignatureV // Deprecated in v4.8\\n }\\n\\n function _throwError(RecoverError error) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert(\\\"ECDSA: invalid signature\\\");\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert(\\\"ECDSA: invalid signature length\\\");\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert(\\\"ECDSA: invalid signature 's' value\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature` or error string. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n *\\n * Documentation for signature generation:\\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n return tryRecover(hash, v, r, s);\\n } else {\\n return (address(0), RecoverError.InvalidSignatureLength);\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature`. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, signature);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\\n uint8 v = uint8((uint256(vs) >> 255) + 27);\\n return tryRecover(hash, v, r, s);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n *\\n * _Available since v4.2._\\n */\\n function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\\n // the valid range for s in (301): 0 < s < secp256k1n \\u00f7 2 + 1, and for v in (302): v \\u2208 {27, 28}. Most\\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\\n //\\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\\n // these malleable signatures as well.\\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n return (address(0), RecoverError.InvalidSignatureS);\\n }\\n\\n // If the signature is valid (and not malleable), return the signer address\\n address signer = ecrecover(hash, v, r, s);\\n if (signer == address(0)) {\\n return (address(0), RecoverError.InvalidSignature);\\n }\\n\\n return (signer, RecoverError.NoError);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore(0x00, \\\"\\\\x19Ethereum Signed Message:\\\\n32\\\")\\n mstore(0x1c, hash)\\n message := keccak256(0x00, 0x3c)\\n }\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from `s`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n\\\", Strings.toString(s.length), s));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Typed Data, created from a\\n * `domainSeparator` and a `structHash`. This produces hash corresponding\\n * to the one signed with the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n * JSON-RPC method as part of EIP-712.\\n *\\n * See {recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n let ptr := mload(0x40)\\n mstore(ptr, \\\"\\\\x19\\\\x01\\\")\\n mstore(add(ptr, 0x02), domainSeparator)\\n mstore(add(ptr, 0x22), structHash)\\n data := keccak256(ptr, 0x42)\\n }\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Data with intended validator, created from a\\n * `validator` and `data` according to the version 0 of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x00\\\", validator, data));\\n }\\n}\\n\",\"keccak256\":\"0x809bc3edb4bcbef8263fa616c1b60ee0004b50a8a1bfa164d8f57fd31f520c58\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n enum Rounding {\\n Down, // Toward negative infinity\\n Up, // Toward infinity\\n Zero // Toward zero\\n }\\n\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow.\\n return (a & b) + (a ^ b) / 2;\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a == 0 ? 0 : (a - 1) / b + 1;\\n }\\n\\n /**\\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\\n * with further edits by Uniswap Labs also under MIT license.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\\n unchecked {\\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2^256 + prod0.\\n uint256 prod0; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division.\\n if (prod1 == 0) {\\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\\n // The surrounding unchecked block does not change this fact.\\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\\n return prod0 / denominator;\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n require(denominator > prod1, \\\"Math: mulDiv overflow\\\");\\n\\n ///////////////////////////////////////////////\\n // 512 by 256 division.\\n ///////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0].\\n uint256 remainder;\\n assembly {\\n // Compute remainder using mulmod.\\n remainder := mulmod(x, y, denominator)\\n\\n // Subtract 256 bit number from 512 bit number.\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\\n // See https://cs.stackexchange.com/q/138556/92363.\\n\\n // Does not overflow because the denominator cannot be zero at this stage in the function.\\n uint256 twos = denominator & (~denominator + 1);\\n assembly {\\n // Divide denominator by twos.\\n denominator := div(denominator, twos)\\n\\n // Divide [prod1 prod0] by twos.\\n prod0 := div(prod0, twos)\\n\\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\\n twos := add(div(sub(0, twos), twos), 1)\\n }\\n\\n // Shift in bits from prod1 into prod0.\\n prod0 |= prod1 * twos;\\n\\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\\n // four bits. That is, denominator * inv = 1 mod 2^4.\\n uint256 inverse = (3 * denominator) ^ 2;\\n\\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\\n // in modular arithmetic, doubling the correct bits in each step.\\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\\n\\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inverse;\\n return result;\\n }\\n }\\n\\n /**\\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\\n uint256 result = mulDiv(x, y, denominator);\\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\\n result += 1;\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\\n *\\n * Inspired by Henry S. Warren, Jr.'s \\\"Hacker's Delight\\\" (Chapter 11).\\n */\\n function sqrt(uint256 a) internal pure returns (uint256) {\\n if (a == 0) {\\n return 0;\\n }\\n\\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\\n //\\n // We know that the \\\"msb\\\" (most significant bit) of our target number `a` is a power of 2 such that we have\\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\\n //\\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\\n // \\u2192 `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\\n // \\u2192 `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\\n //\\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\\n uint256 result = 1 << (log2(a) >> 1);\\n\\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\\n // into the expected uint128 result.\\n unchecked {\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n return min(result, a / result);\\n }\\n }\\n\\n /**\\n * @notice Calculates sqrt(a), following the selected rounding direction.\\n */\\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = sqrt(a);\\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 2, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 128;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 64;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 32;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 16;\\n }\\n if (value >> 8 > 0) {\\n value >>= 8;\\n result += 8;\\n }\\n if (value >> 4 > 0) {\\n value >>= 4;\\n result += 4;\\n }\\n if (value >> 2 > 0) {\\n value >>= 2;\\n result += 2;\\n }\\n if (value >> 1 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log2(value);\\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 10, rounded down, of a positive value.\\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 + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 256, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n *\\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\\n */\\n function log256(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 16;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 8;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 4;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 2;\\n }\\n if (value >> 8 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log256(value);\\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe4455ac1eb7fc497bb7402579e7b4d64d928b846fce7d2b6fde06d366f21c2b3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\\n * checks.\\n *\\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\\n * easily result in undesired exploitation or bugs, since developers usually\\n * assume that overflows raise errors. `SafeCast` restores this intuition by\\n * reverting the transaction when such an operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n *\\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\\n * all math on `uint256` and `int256` and then downcasting.\\n */\\nlibrary SafeCast {\\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 * _Available since v4.7._\\n */\\n function toUint248(uint256 value) internal pure returns (uint248) {\\n require(value <= type(uint248).max, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint240(uint256 value) internal pure returns (uint240) {\\n require(value <= type(uint240).max, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint232(uint256 value) internal pure returns (uint232) {\\n require(value <= type(uint232).max, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint224(uint256 value) internal pure returns (uint224) {\\n require(value <= type(uint224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint216(uint256 value) internal pure returns (uint216) {\\n require(value <= type(uint216).max, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint208(uint256 value) internal pure returns (uint208) {\\n require(value <= type(uint208).max, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint200(uint256 value) internal pure returns (uint200) {\\n require(value <= type(uint200).max, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint192(uint256 value) internal pure returns (uint192) {\\n require(value <= type(uint192).max, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint184(uint256 value) internal pure returns (uint184) {\\n require(value <= type(uint184).max, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint176(uint256 value) internal pure returns (uint176) {\\n require(value <= type(uint176).max, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint168(uint256 value) internal pure returns (uint168) {\\n require(value <= type(uint168).max, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint160(uint256 value) internal pure returns (uint160) {\\n require(value <= type(uint160).max, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint152(uint256 value) internal pure returns (uint152) {\\n require(value <= type(uint152).max, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint144(uint256 value) internal pure returns (uint144) {\\n require(value <= type(uint144).max, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint136(uint256 value) internal pure returns (uint136) {\\n require(value <= type(uint136).max, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint128(uint256 value) internal pure returns (uint128) {\\n require(value <= type(uint128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint120(uint256 value) internal pure returns (uint120) {\\n require(value <= type(uint120).max, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint112(uint256 value) internal pure returns (uint112) {\\n require(value <= type(uint112).max, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint104(uint256 value) internal pure returns (uint104) {\\n require(value <= type(uint104).max, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint96(uint256 value) internal pure returns (uint96) {\\n require(value <= type(uint96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint88(uint256 value) internal pure returns (uint88) {\\n require(value <= type(uint88).max, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint80(uint256 value) internal pure returns (uint80) {\\n require(value <= type(uint80).max, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint72(uint256 value) internal pure returns (uint72) {\\n require(value <= type(uint72).max, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint64(uint256 value) internal pure returns (uint64) {\\n require(value <= type(uint64).max, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint56(uint256 value) internal pure returns (uint56) {\\n require(value <= type(uint56).max, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint48(uint256 value) internal pure returns (uint48) {\\n require(value <= type(uint48).max, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint40(uint256 value) internal pure returns (uint40) {\\n require(value <= type(uint40).max, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint32(uint256 value) internal pure returns (uint32) {\\n require(value <= type(uint32).max, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint24(uint256 value) internal pure returns (uint24) {\\n require(value <= type(uint24).max, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint16(uint256 value) internal pure returns (uint16) {\\n require(value <= type(uint16).max, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint8(uint256 value) internal pure returns (uint8) {\\n require(value <= type(uint8).max, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\n */\\n function toUint256(int256 value) internal pure returns (uint256) {\\n require(value >= 0, \\\"SafeCast: value must be positive\\\");\\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 * _Available since v4.7._\\n */\\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\\n downcasted = int248(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\\n downcasted = int240(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\\n downcasted = int232(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\\n downcasted = int224(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\\n downcasted = int216(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\\n downcasted = int208(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\\n downcasted = int200(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\\n downcasted = int192(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\\n downcasted = int184(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\\n downcasted = int176(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\\n downcasted = int168(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\\n downcasted = int160(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\\n downcasted = int152(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\\n downcasted = int144(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\\n downcasted = int136(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\\n downcasted = int128(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\\n downcasted = int120(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\\n downcasted = int112(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\\n downcasted = int104(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\\n downcasted = int96(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\\n downcasted = int88(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\\n downcasted = int80(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\\n downcasted = int72(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\\n downcasted = int64(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\\n downcasted = int56(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\\n downcasted = int48(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\\n downcasted = int40(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\\n downcasted = int32(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\\n downcasted = int24(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\\n downcasted = int16(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\\n downcasted = int8(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\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 require(value <= uint256(type(int256).max), \\\"SafeCast: value doesn't fit in an int256\\\");\\n return int256(value);\\n }\\n}\\n\",\"keccak256\":\"0x52a8cfb0f5239d11b457dcdd1b326992ef672714ca8da71a157255bddd13f3ad\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SignedMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard signed math utilities missing in the Solidity language.\\n */\\nlibrary SignedMath {\\n /**\\n * @dev Returns the largest of two signed numbers.\\n */\\n function max(int256 a, int256 b) internal pure returns (int256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two signed numbers.\\n */\\n function min(int256 a, int256 b) internal pure returns (int256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two signed numbers without overflow.\\n * The result is rounded towards zero.\\n */\\n function average(int256 a, int256 b) internal pure returns (int256) {\\n // Formula from the book \\\"Hacker's Delight\\\"\\n int256 x = (a & b) + ((a ^ b) >> 1);\\n return x + (int256(uint256(x) >> 255) & (a ^ b));\\n }\\n\\n /**\\n * @dev Returns the absolute unsigned value of a signed value.\\n */\\n function abs(int256 n) internal pure returns (uint256) {\\n unchecked {\\n // must be unchecked in order to support `n = type(int256).min`\\n return uint256(n >= 0 ? n : -n);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf92515413956f529d95977adc9b0567d583c6203fc31ab1c23824c35187e3ddc\",\"license\":\"MIT\"},\"contracts/aa-4337/core/BaseAccount.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-empty-blocks */\\n\\nimport \\\"../interfaces/IAccount.sol\\\";\\nimport \\\"../interfaces/IEntryPoint.sol\\\";\\nimport \\\"./Helpers.sol\\\";\\n\\n/**\\n * Basic account implementation.\\n * this contract provides the basic logic for implementing the IAccount interface - validateUserOp\\n * specific account implementation should inherit it and provide the account-specific logic\\n */\\nabstract contract BaseAccount is IAccount {\\n using UserOperationLib for UserOperation;\\n\\n //return value in case of signature failure, with no time-range.\\n // equivalent to _packValidationData(true,0,0);\\n uint256 internal constant SIG_VALIDATION_FAILED = 1;\\n\\n /**\\n * Return the account nonce.\\n * This method returns the next sequential nonce.\\n * For a nonce of a specific key, use `entrypoint.getNonce(account, key)`\\n */\\n function getNonce() public view virtual returns (uint256) {\\n return entryPoint().getNonce(address(this), 0);\\n }\\n\\n /**\\n * return the entryPoint used by this account.\\n * subclass should return the current entryPoint used by this account.\\n */\\n function entryPoint() public view virtual returns (IEntryPoint);\\n\\n /**\\n * Validate user's signature and nonce.\\n * subclass doesn't need to override this method. Instead, it should override the specific internal validation methods.\\n */\\n function validateUserOp(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n uint256 missingAccountFunds\\n ) external virtual override returns (uint256 validationData) {\\n _requireFromEntryPoint();\\n validationData = _validateSignature(userOp, userOpHash);\\n _validateNonce(userOp.nonce);\\n _payPrefund(missingAccountFunds);\\n }\\n\\n /**\\n * ensure the request comes from the known entrypoint.\\n */\\n function _requireFromEntryPoint() internal view virtual {\\n require(\\n msg.sender == address(entryPoint()),\\n \\\"account: not from EntryPoint\\\"\\n );\\n }\\n\\n /**\\n * validate the signature is valid for this message.\\n * @param userOp validate the userOp.signature field\\n * @param userOpHash convenient field: the hash of the request, to check the signature against\\n * (also hashes the entrypoint and chain id)\\n * @return validationData signature and time-range of this operation\\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\\n * otherwise, an address of an \\\"authorizer\\\" contract.\\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \\\"indefinite\\\"\\n * <6-byte> validAfter - first timestamp this operation is valid\\n * If the account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\\n */\\n function _validateSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) internal virtual returns (uint256 validationData);\\n\\n /**\\n * Validate the nonce of the UserOperation.\\n * This method may validate the nonce requirement of this account.\\n * e.g.\\n * To limit the nonce to use sequenced UserOps only (no \\\"out of order\\\" UserOps):\\n * `require(nonce < type(uint64).max)`\\n * For a hypothetical account that *requires* the nonce to be out-of-order:\\n * `require(nonce & type(uint64).max == 0)`\\n *\\n * The actual nonce uniqueness is managed by the EntryPoint, and thus no other\\n * action is needed by the account itself.\\n *\\n * @param nonce to validate\\n *\\n * solhint-disable-next-line no-empty-blocks\\n */\\n function _validateNonce(uint256 nonce) internal view virtual {}\\n\\n /**\\n * sends to the entrypoint (msg.sender) the missing funds for this transaction.\\n * subclass MAY override this method for better funds management\\n * (e.g. send to the entryPoint more than the minimum required, so that in future transactions\\n * it will not be required to send again)\\n * @param missingAccountFunds the minimum value this method should send the entrypoint.\\n * this value MAY be zero, in case there is enough deposit, or the userOp has a paymaster.\\n */\\n function _payPrefund(uint256 missingAccountFunds) internal virtual {\\n if (missingAccountFunds != 0) {\\n (bool success, ) = payable(msg.sender).call{\\n value: missingAccountFunds,\\n gas: type(uint256).max\\n }(\\\"\\\");\\n (success);\\n //ignore failure (its EntryPoint's job to verify, not account.)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa0dcc386b0f04711db3e394fb50e55a3b3b1a4d19fac1f10895844e1aa4e3d5c\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/core/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable no-inline-assembly */\\n\\n/**\\n * returned data from validateUserOp.\\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\\n * @param aggregator - address(0) - the account validated the signature by itself.\\n * address(1) - the account failed to validate the signature.\\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\\n * @param validAfter - this UserOp is valid only after this timestamp.\\n * @param validaUntil - this UserOp is valid only up to this timestamp.\\n */\\nstruct ValidationData {\\n address aggregator;\\n uint48 validAfter;\\n uint48 validUntil;\\n}\\n\\n//extract sigFailed, validAfter, validUntil.\\n// also convert zero validUntil to type(uint48).max\\nfunction _parseValidationData(\\n uint validationData\\n) pure returns (ValidationData memory data) {\\n address aggregator = address(uint160(validationData));\\n uint48 validUntil = uint48(validationData >> 160);\\n if (validUntil == 0) {\\n validUntil = type(uint48).max;\\n }\\n uint48 validAfter = uint48(validationData >> (48 + 160));\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n// intersect account and paymaster ranges.\\nfunction _intersectTimeRange(\\n uint256 validationData,\\n uint256 paymasterValidationData\\n) pure returns (ValidationData memory) {\\n ValidationData memory accountValidationData = _parseValidationData(\\n validationData\\n );\\n ValidationData memory pmValidationData = _parseValidationData(\\n paymasterValidationData\\n );\\n address aggregator = accountValidationData.aggregator;\\n if (aggregator == address(0)) {\\n aggregator = pmValidationData.aggregator;\\n }\\n uint48 validAfter = accountValidationData.validAfter;\\n uint48 validUntil = accountValidationData.validUntil;\\n uint48 pmValidAfter = pmValidationData.validAfter;\\n uint48 pmValidUntil = pmValidationData.validUntil;\\n\\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp\\n * @param data - the ValidationData to pack\\n */\\nfunction _packValidationData(\\n ValidationData memory data\\n) pure returns (uint256) {\\n return\\n uint160(data.aggregator) |\\n (uint256(data.validUntil) << 160) |\\n (uint256(data.validAfter) << (160 + 48));\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp, when not using an aggregator\\n * @param sigFailed - true for signature failure, false for success\\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\\n * @param validAfter first timestamp this UserOperation is valid\\n */\\nfunction _packValidationData(\\n bool sigFailed,\\n uint48 validUntil,\\n uint48 validAfter\\n) pure returns (uint256) {\\n return\\n (sigFailed ? 1 : 0) |\\n (uint256(validUntil) << 160) |\\n (uint256(validAfter) << (160 + 48));\\n}\\n\\n/**\\n * keccak function over calldata.\\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\\n */\\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\\n assembly {\\n let mem := mload(0x40)\\n let len := data.length\\n calldatacopy(mem, data.offset, len)\\n ret := keccak256(mem, len)\\n }\\n}\\n\",\"keccak256\":\"0xa79f06cd158ecb8c0da95493a2f348933b8627a63e228b99738bff3aa107942d\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAccount.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\ninterface IAccount {\\n /**\\n * Validate user's signature and nonce\\n * the entryPoint will make the call to the recipient only if this validation call returns successfully.\\n * signature failure should be reported by returning SIG_VALIDATION_FAILED (1).\\n * This allows making a \\\"simulation call\\\" without a valid signature\\n * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure.\\n *\\n * @dev Must validate caller is the entryPoint.\\n * Must validate the signature and nonce\\n * @param userOp the operation that is about to be executed.\\n * @param userOpHash hash of the user's request data. can be used as the basis for signature.\\n * @param missingAccountFunds missing funds on the account's deposit in the entrypoint.\\n * This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call.\\n * The excess is left as a deposit in the entrypoint, for future calls.\\n * can be withdrawn anytime using \\\"entryPoint.withdrawTo()\\\"\\n * In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero.\\n * @return validationData packaged ValidationData structure. use `_packValidationData` and `_unpackValidationData` to encode and decode\\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\\n * otherwise, an address of an \\\"authorizer\\\" contract.\\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \\\"indefinite\\\"\\n * <6-byte> validAfter - first timestamp this operation is valid\\n * If an account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\\n */\\n function validateUserOp(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n uint256 missingAccountFunds\\n ) external returns (uint256 validationData);\\n}\\n\",\"keccak256\":\"0xcbc4b0973cf954c5895b7796335f651fbfcfb55f67dfa789a3d354f8e23c4f2b\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAggregator.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\n/**\\n * Aggregated Signatures validator.\\n */\\ninterface IAggregator {\\n /**\\n * validate aggregated signature.\\n * revert if the aggregated signature does not match the given list of operations.\\n */\\n function validateSignatures(\\n UserOperation[] calldata userOps,\\n bytes calldata signature\\n ) external view;\\n\\n /**\\n * validate signature of a single userOp\\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\\n * @param userOp the userOperation received from the user.\\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\\n * (usually empty, unless account and aggregator support some kind of \\\"multisig\\\"\\n */\\n function validateUserOpSignature(\\n UserOperation calldata userOp\\n ) external view returns (bytes memory sigForUserOp);\\n\\n /**\\n * aggregate multiple signatures into a single value.\\n * This method is called off-chain to calculate the signature to pass with handleOps()\\n * bundler MAY use optimized custom code perform this aggregation\\n * @param userOps array of UserOperations to collect the signatures from.\\n * @return aggregatedSignature the aggregated signature\\n */\\n function aggregateSignatures(\\n UserOperation[] calldata userOps\\n ) external view returns (bytes memory aggregatedSignature);\\n}\\n\",\"keccak256\":\"0xdfdcd80568f037716674619b31be630fcd8316262f05a815b41d1e81782c966a\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IEntryPoint.sol\":{\"content\":\"/**\\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\\n ** Only one instance required on each chain.\\n **/\\n// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-inline-assembly */\\n/* solhint-disable reason-string */\\n\\nimport \\\"./UserOperation.sol\\\";\\nimport \\\"./IStakeManager.sol\\\";\\nimport \\\"./IAggregator.sol\\\";\\nimport \\\"./INonceManager.sol\\\";\\n\\ninterface IEntryPoint is IStakeManager, INonceManager {\\n /***\\n * An event emitted after each successful request\\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\\n * @param sender - the account that generates this request.\\n * @param paymaster - if non-null, the paymaster that pays for this request.\\n * @param nonce - the nonce value from the request.\\n * @param success - true if the sender transaction succeeded, false if reverted.\\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\\n */\\n event UserOperationEvent(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address indexed paymaster,\\n uint256 nonce,\\n bool success,\\n uint256 actualGasCost,\\n uint256 actualGasUsed\\n );\\n\\n /**\\n * account \\\"sender\\\" was deployed.\\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\\n * @param sender the account that is deployed\\n * @param factory the factory used to deploy this account (in the initCode)\\n * @param paymaster the paymaster used by this UserOp\\n */\\n event AccountDeployed(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address factory,\\n address paymaster\\n );\\n\\n /**\\n * An event emitted if the UserOperation \\\"callData\\\" reverted with non-zero length\\n * @param userOpHash the request unique identifier.\\n * @param sender the sender of this request\\n * @param nonce the nonce used in the request\\n * @param revertReason - the return bytes from the (reverted) call to \\\"callData\\\".\\n */\\n event UserOperationRevertReason(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n uint256 nonce,\\n bytes revertReason\\n );\\n\\n /**\\n * an event emitted by handleOps(), before starting the execution loop.\\n * any event emitted before this event, is part of the validation.\\n */\\n event BeforeExecution();\\n\\n /**\\n * signature aggregator used by the following UserOperationEvents within this bundle.\\n */\\n event SignatureAggregatorChanged(address indexed aggregator);\\n\\n /**\\n * a custom revert error of handleOps, to identify the offending op.\\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\\n * @param reason - revert reason\\n * The string starts with a unique code \\\"AAmn\\\", where \\\"m\\\" is \\\"1\\\" for factory, \\\"2\\\" for account and \\\"3\\\" for paymaster issues,\\n * so a failure can be attributed to the correct entity.\\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\\n */\\n error FailedOp(uint256 opIndex, string reason);\\n\\n /**\\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\\n */\\n error SignatureValidationFailed(address aggregator);\\n\\n /**\\n * Successful result from simulateValidation.\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n */\\n error ValidationResult(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo\\n );\\n\\n /**\\n * Successful result from simulateValidation, if the account returns a signature aggregator\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\\n * bundler MUST use it to verify the signature, or reject the UserOperation\\n */\\n error ValidationResultWithAggregation(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo,\\n AggregatorStakeInfo aggregatorInfo\\n );\\n\\n /**\\n * return value of getSenderAddress\\n */\\n error SenderAddressResult(address sender);\\n\\n /**\\n * return value of simulateHandleOp\\n */\\n error ExecutionResult(\\n uint256 preOpGas,\\n uint256 paid,\\n uint48 validAfter,\\n uint48 validUntil,\\n bool targetSuccess,\\n bytes targetResult\\n );\\n\\n //UserOps handled, per aggregator\\n struct UserOpsPerAggregator {\\n UserOperation[] userOps;\\n // aggregator address\\n IAggregator aggregator;\\n // aggregated signature\\n bytes signature;\\n }\\n\\n /**\\n * Execute a batch of UserOperation.\\n * no signature aggregator is used.\\n * if any account requires an aggregator (that is, it returned an aggregator when\\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\\n * @param ops the operations to execute\\n * @param beneficiary the address to receive the fees\\n */\\n function handleOps(\\n UserOperation[] calldata ops,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * Execute a batch of UserOperation with Aggregators\\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\\n * @param beneficiary the address to receive the fees\\n */\\n function handleAggregatedOps(\\n UserOpsPerAggregator[] calldata opsPerAggregator,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * generate a request Id - unique identifier for this request.\\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\\n */\\n function getUserOpHash(\\n UserOperation calldata userOp\\n ) external view returns (bytes32);\\n\\n /**\\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\\n * @param userOp the user operation to validate.\\n */\\n function simulateValidation(UserOperation calldata userOp) external;\\n\\n /**\\n * gas and return values during simulation\\n * @param preOpGas the gas used for validation (including preValidationGas)\\n * @param prefund the required prefund for this operation\\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\\n */\\n struct ReturnInfo {\\n uint256 preOpGas;\\n uint256 prefund;\\n bool sigFailed;\\n uint48 validAfter;\\n uint48 validUntil;\\n bytes paymasterContext;\\n }\\n\\n /**\\n * returned aggregated signature info.\\n * the aggregator returned by the account, and its current stake.\\n */\\n struct AggregatorStakeInfo {\\n address aggregator;\\n StakeInfo stakeInfo;\\n }\\n\\n /**\\n * Get counterfactual sender address.\\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\\n * this method always revert, and returns the address in SenderAddressResult error\\n * @param initCode the constructor code to be passed into the UserOperation.\\n */\\n function getSenderAddress(bytes memory initCode) external;\\n\\n /**\\n * simulate full execution of a UserOperation (including both validation and target execution)\\n * this method will always revert with \\\"ExecutionResult\\\".\\n * it performs full validation of the UserOperation, but ignores signature error.\\n * an optional target address is called after the userop succeeds, and its value is returned\\n * (before the entire call is reverted)\\n * Note that in order to collect the the success/failure of the target call, it must be executed\\n * with trace enabled to track the emitted events.\\n * @param op the UserOperation to simulate\\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\\n * are set to the return from that call.\\n * @param targetCallData callData to pass to target address\\n */\\n function simulateHandleOp(\\n UserOperation calldata op,\\n address target,\\n bytes calldata targetCallData\\n ) external;\\n}\\n\",\"keccak256\":\"0x9ccb1b188eda8bbf5f6c2d01bd83c3d8b2b04fcf745283051d31fe96d1d8e40f\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/INonceManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\ninterface INonceManager {\\n /**\\n * Return the next nonce for this sender.\\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\\n * But UserOp with different keys can come with arbitrary order.\\n *\\n * @param sender the account address\\n * @param key the high 192 bit of the nonce\\n * @return nonce a full nonce to pass for next UserOp with this sender.\\n */\\n function getNonce(\\n address sender,\\n uint192 key\\n ) external view returns (uint256 nonce);\\n\\n /**\\n * Manually increment the nonce of the sender.\\n * This method is exposed just for completeness..\\n * Account does NOT need to call it, neither during validation, nor elsewhere,\\n * as the EntryPoint will update the nonce regardless.\\n * Possible use-case is call it with various keys to \\\"initialize\\\" their nonces to one, so that future\\n * UserOperations will not pay extra for the first transaction with a given key.\\n */\\n function incrementNonce(uint192 key) external;\\n}\\n\",\"keccak256\":\"0xce478ad0fa0d18a3b785ac854623029e7ab463d05873dfaa365abfa1bf100912\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IStakeManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8.12;\\n\\n/**\\n * manage deposits and stakes.\\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\\n * stake is value locked for at least \\\"unstakeDelay\\\" by the staked entity.\\n */\\ninterface IStakeManager {\\n event Deposited(address indexed account, uint256 totalDeposit);\\n\\n event Withdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /// Emitted when stake or unstake delay are modified\\n event StakeLocked(\\n address indexed account,\\n uint256 totalStaked,\\n uint256 unstakeDelaySec\\n );\\n\\n /// Emitted once a stake is scheduled for withdrawal\\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\\n\\n event StakeWithdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /**\\n * @param deposit the entity's deposit\\n * @param staked true if this entity is staked.\\n * @param stake actual amount of ether staked for this entity.\\n * @param unstakeDelaySec minimum delay to withdraw the stake.\\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\\n * and the rest fit into a 2nd cell.\\n * 112 bit allows for 10^15 eth\\n * 48 bit for full timestamp\\n * 32 bit allows 150 years for unstake delay\\n */\\n struct DepositInfo {\\n uint112 deposit;\\n bool staked;\\n uint112 stake;\\n uint32 unstakeDelaySec;\\n uint48 withdrawTime;\\n }\\n\\n //API struct used by getStakeInfo and simulateValidation\\n struct StakeInfo {\\n uint256 stake;\\n uint256 unstakeDelaySec;\\n }\\n\\n /// @return info - full deposit information of given account\\n function getDepositInfo(\\n address account\\n ) external view returns (DepositInfo memory info);\\n\\n /// @return the deposit (for gas payment) of the account\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * add to the deposit of the given account\\n */\\n function depositTo(address account) external payable;\\n\\n /**\\n * add to the account's stake - amount and delay\\n * any pending unstake is first cancelled.\\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\\n */\\n function addStake(uint32 _unstakeDelaySec) external payable;\\n\\n /**\\n * attempt to unlock the stake.\\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\\n */\\n function unlockStake() external;\\n\\n /**\\n * withdraw from the (unlocked) stake.\\n * must first call unlockStake and wait for the unstakeDelay to pass\\n * @param withdrawAddress the address to send withdrawn value.\\n */\\n function withdrawStake(address payable withdrawAddress) external;\\n\\n /**\\n * withdraw from the deposit.\\n * @param withdrawAddress the address to send withdrawn value.\\n * @param withdrawAmount the amount to withdraw.\\n */\\n function withdrawTo(\\n address payable withdrawAddress,\\n uint256 withdrawAmount\\n ) external;\\n}\\n\",\"keccak256\":\"0xadcea606c9b7aafe6645441f2154a60f271330b0eee5292a632aa71c1672d546\",\"license\":\"GPL-3.0-only\"},\"contracts/aa-4337/interfaces/UserOperation.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable no-inline-assembly */\\n\\nimport {calldataKeccak} from \\\"../core/Helpers.sol\\\";\\n\\n/**\\n * User Operation struct\\n * @param sender the sender account of this request.\\n * @param nonce unique value the sender uses to verify it is not a replay.\\n * @param initCode if set, the account contract will be created by this constructor/\\n * @param callData the method call to execute on this account.\\n * @param callGasLimit the gas limit passed to the callData method call.\\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\\n * @param maxFeePerGas same as EIP-1559 gas parameter.\\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\\n */\\nstruct UserOperation {\\n address sender;\\n uint256 nonce;\\n bytes initCode;\\n bytes callData;\\n uint256 callGasLimit;\\n uint256 verificationGasLimit;\\n uint256 preVerificationGas;\\n uint256 maxFeePerGas;\\n uint256 maxPriorityFeePerGas;\\n bytes paymasterAndData;\\n bytes signature;\\n}\\n\\n/**\\n * Utility functions helpful when working with UserOperation structs.\\n */\\nlibrary UserOperationLib {\\n function getSender(\\n UserOperation calldata userOp\\n ) internal pure returns (address) {\\n address data;\\n //read sender from userOp, which is first userOp member (saves 800 gas...)\\n assembly {\\n data := calldataload(userOp)\\n }\\n return address(uint160(data));\\n }\\n\\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\\n // pay above what he signed for.\\n function gasPrice(\\n UserOperation calldata userOp\\n ) internal view returns (uint256) {\\n unchecked {\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n if (maxFeePerGas == maxPriorityFeePerGas) {\\n //legacy mode (for networks that don't support basefee opcode)\\n return maxFeePerGas;\\n }\\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\\n }\\n }\\n\\n function pack(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes memory ret) {\\n address sender = getSender(userOp);\\n uint256 nonce = userOp.nonce;\\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\\n bytes32 hashCallData = calldataKeccak(userOp.callData);\\n uint256 callGasLimit = userOp.callGasLimit;\\n uint256 verificationGasLimit = userOp.verificationGasLimit;\\n uint256 preVerificationGas = userOp.preVerificationGas;\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\\n\\n return\\n abi.encode(\\n sender,\\n nonce,\\n hashInitCode,\\n hashCallData,\\n callGasLimit,\\n verificationGasLimit,\\n preVerificationGas,\\n maxFeePerGas,\\n maxPriorityFeePerGas,\\n hashPaymasterAndData\\n );\\n }\\n\\n function hash(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes32) {\\n return keccak256(pack(userOp));\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n}\\n\",\"keccak256\":\"0x2429f5cc546bdee08c7e63858d0dda8491eaa3ab5194df884dc948c1154d2834\",\"license\":\"GPL-3.0\"},\"contracts/facets/AccountFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {ECDSA} from \\\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\\\";\\nimport {UserOperation} from \\\"../aa-4337/interfaces/UserOperation.sol\\\";\\nimport {IEntryPoint} from \\\"../aa-4337/interfaces/IEntryPoint.sol\\\";\\nimport {BaseAccount} from \\\"../aa-4337/core/BaseAccount.sol\\\";\\nimport {LibAppStorage, BarzStorage} from \\\"../libraries/LibAppStorage.sol\\\";\\nimport {LibDiamond} from \\\"../libraries/LibDiamond.sol\\\";\\nimport {LibLoupe} from \\\"../libraries/LibLoupe.sol\\\";\\nimport {IFacetRegistry} from \\\"../infrastructure/interfaces/IFacetRegistry.sol\\\";\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\nimport {IVerificationFacet} from \\\"./interfaces/IVerificationFacet.sol\\\";\\nimport {IERC1271} from \\\"../interfaces/ERC/IERC1271.sol\\\";\\nimport {IAccountFacet} from \\\"./interfaces/IAccountFacet.sol\\\";\\n\\n/**\\n * @title Account Facet\\n * @dev Account module contract that provides the account features and initialization of signer\\n * compatible with EIP-1271 & EIP-4337\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract AccountFacet is IAccountFacet, BarzStorage, BaseAccount {\\n using ECDSA for bytes32;\\n\\n /**\\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\\n */\\n constructor() {\\n LibAppStorage.enforceAccountInitialize();\\n }\\n\\n /**\\n * @notice Returns the address of EntryPoint contract registered to Barz account\\n */\\n function entryPoint() public view override returns (IEntryPoint) {\\n return s.entryPoint;\\n }\\n\\n /**\\n * @notice Initializes the initial storage of the Barz contract.\\n * @dev This method can only be called during the initialization or signature migration.\\n * If the proxy contract was created without initialization, anyone can call initialize.\\n * Barz calls initialize in constructor in an atomic transaction during deployment\\n * @param _verificationFacet Facet contract handling the verificationi\\n * @param _anEntryPoint Entrypoint contract defined in EIP-4337 handling the flow of UserOp\\n * @param _facetRegistry Registry of Facets that hold all facet information\\n * @param _defaultFallBackHandler Middleware contract for default facets\\n * @param _ownerPublicKey Bytes of owner public key\\n */\\n function initialize(\\n address _verificationFacet,\\n address _anEntryPoint,\\n address _facetRegistry,\\n address _defaultFallBackHandler,\\n bytes calldata _ownerPublicKey\\n ) public override returns (uint256 initSuccess) {\\n LibAppStorage.enforceAccountInitialize();\\n s.entryPoint = IEntryPoint(_anEntryPoint);\\n s.facetRegistry = IFacetRegistry(_facetRegistry);\\n LibDiamond.diamondStorage().defaultFallbackHandler = IDiamondLoupe(\\n _defaultFallBackHandler\\n );\\n\\n _cutDiamondAccountFacet(_verificationFacet);\\n\\n bytes memory initCall = abi.encodeWithSignature(\\n \\\"initializeSigner(bytes)\\\",\\n _ownerPublicKey\\n );\\n // Every Verification Facet should comply with initializeSigner(bytes)\\n // to be compatible with the Barz contract(for initialization)\\n (bool success, bytes memory result) = _verificationFacet.delegatecall(\\n initCall\\n );\\n if (!success || uint256(bytes32(result)) != 1) {\\n revert AccountFacet__InitializationFailure();\\n }\\n\\n initSuccess = 1;\\n emit AccountInitialized(s.entryPoint, _ownerPublicKey);\\n }\\n\\n function _cutDiamondAccountFacet(address _verificationFacet) internal {\\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](1);\\n\\n bytes4 ownerVerificationFuncSelector = IVerificationFacet(\\n _verificationFacet\\n ).validateOwnerSignatureSelector();\\n\\n bytes4[] memory verificationFunctionSelectors = new bytes4[](3);\\n verificationFunctionSelectors[0] = IERC1271.isValidSignature.selector;\\n verificationFunctionSelectors[1] = ownerVerificationFuncSelector;\\n verificationFunctionSelectors[2] = IVerificationFacet.owner.selector;\\n cut[0] = IDiamondCut.FacetCut({\\n facetAddress: _verificationFacet,\\n action: IDiamondCut.FacetCutAction.Add,\\n functionSelectors: verificationFunctionSelectors\\n });\\n\\n LibDiamond.diamondCut(cut, address(0), \\\"\\\");\\n }\\n\\n /**\\n * @notice Calls the destination with inputted calldata and value from EntryPoint\\n * @dev This method executes the calldata coming from the EntryPoint.\\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\\n * @param _dest Address of destination where the call will be forwarded to\\n * @param _value Amount of native coin the owner is willing to send(e.g. ETH, BNB)\\n * @param _func Bytes of calldata to execute in the destination address\\n */\\n function execute(\\n address _dest,\\n uint256 _value,\\n bytes calldata _func\\n ) external override onlyWhenUnlocked {\\n _requireFromEntryPoint();\\n address restrictionsFacet = LibDiamond.restrictionsFacet();\\n if (restrictionsFacet == address(0)) _call(_dest, _value, _func);\\n else _callWithRestrictions(_dest, _value, _func, restrictionsFacet);\\n }\\n\\n /**\\n * @notice Batch calls the destination with inputted calldata and value from EntryPoint\\n * @dev This method batch executes the calldata coming from the EntryPoint.\\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\\n * @param _dest Array of addresses of destination where the call will be forwarded to\\n * @param _value Array of amount of native coin the owner is willing to send(e.g. ETH, BNB)\\n * @param _func Array of bytes of calldata to execute in the destination address\\n */\\n function executeBatch(\\n address[] calldata _dest,\\n uint256[] calldata _value,\\n bytes[] calldata _func\\n ) external override onlyWhenUnlocked {\\n _requireFromEntryPoint();\\n if (_dest.length != _func.length || _dest.length != _value.length)\\n revert AccountFacet__InvalidArrayLength();\\n address restrictionsFacet = LibDiamond.restrictionsFacet();\\n if (restrictionsFacet == address(0)) {\\n for (uint256 i; i < _dest.length; ) {\\n _call(_dest[i], _value[i], _func[i]);\\n unchecked {\\n ++i;\\n }\\n }\\n } else {\\n for (uint256 i; i < _dest.length; ) {\\n _callWithRestrictions(\\n _dest[i],\\n _value[i],\\n _func[i],\\n restrictionsFacet\\n );\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n }\\n\\n /**\\n * @notice Validates the signature field of UserOperation\\n * @dev This method validates if the signature of UserOp is indeed valid by delegating the call to Verification Facet\\n * Barz makes a call to the pre-registered Verification Facet address in App Storage\\n * @param _userOp UserOperation from owner to be validated\\n * @param _userOpHash Hash of UserOperation given from the EntryPoint contract\\n */\\n function _validateSignature(\\n UserOperation calldata _userOp,\\n bytes32 _userOpHash\\n ) internal override returns (uint256 validationData) {\\n // Get Facet with Function Selector\\n address facet = LibLoupe.facetAddress(s.validateOwnerSignatureSelector);\\n if (facet == address(0))\\n revert AccountFacet__NonExistentVerificationFacet();\\n\\n // Make function call to VerificationFacet\\n bytes memory validateCall = abi.encodeWithSelector(\\n s.validateOwnerSignatureSelector,\\n _userOp,\\n _userOpHash\\n );\\n (bool success, bytes memory result) = facet.delegatecall(validateCall);\\n if (!success) revert AccountFacet__CallNotSuccessful();\\n validationData = uint256(bytes32(result));\\n if (validationData == 0) emit VerificationSuccess(_userOpHash);\\n else emit VerificationFailure(_userOpHash);\\n }\\n\\n /**\\n * @notice Calls the target with the inputted value and calldata\\n * @dev This method is the actual function in Barz that makes a call with an arbitrary owner-given data\\n * @param _target Address of the destination contract which the call is getting forwarded to\\n * @param _value Amount of Native coin the owner is wanting to make in this call\\n * @param _data Calldata the owner is forwarding together in the call e.g. Swap/Token Transfer\\n */\\n function _call(\\n address _target,\\n uint256 _value,\\n bytes memory _data\\n ) internal {\\n (bool success, bytes memory result) = _target.call{value: _value}(\\n _data\\n );\\n if (!success) {\\n assembly {\\n revert(add(result, 32), mload(result))\\n }\\n }\\n }\\n\\n /**\\n * @notice Calls the target with the inputted value and calldata together with restrictions check\\n * @dev This method is the actual function in Barz that makes a call with an arbitrary owner-given data\\n * @param _target Address of the destination contract which the call is getting forwarded to\\n * @param _value Amount of Native coin the owner is wanting to make in this call\\n * @param _data Calldata the owner is forwarding together in the call e.g. Swap/Token Transfer\\n * @param _restrictionsFacet Address of Facet to validate restrictions\\n */\\n function _callWithRestrictions(\\n address _target,\\n uint256 _value,\\n bytes memory _data,\\n address _restrictionsFacet\\n ) internal {\\n // NOTE: No restrictions facet, so restriction validation passes\\n if (_checkRestrictions(_restrictionsFacet, _target, _value, _data) != 0)\\n revert AccountFacet__RestrictionsFailure();\\n\\n (bool success, bytes memory result) = _target.call{value: _value}(\\n _data\\n );\\n if (!success) {\\n assembly {\\n revert(add(result, 32), mload(result))\\n }\\n }\\n }\\n\\n /**\\n * @notice Checks restrictions if the restrictions facet exists\\n * @dev This method checks if the restrictions facet exists and makes a verification call to an array of restrictions facet\\n * @param _facet Address that holds the restrictions logic\\n * @param _target Address the call is getting forwarded to\\n * @param _value Amount of native coin the call is sending together with the call\\n * @param _data Calldata to trigger execution in target address\\n */\\n function _checkRestrictions(\\n address _facet,\\n address _target,\\n uint256 _value,\\n bytes memory _data\\n ) internal returns (uint256 result) {\\n bytes memory call = abi.encodeWithSignature(\\n \\\"verifyRestrictions(address,address,uint256,bytes)\\\",\\n address(this),\\n _target,\\n _value,\\n _data\\n );\\n (bool success, bytes memory response) = _facet.delegatecall(call);\\n if (!success) revert AccountFacet__RestrictionsFailure();\\n result = uint256(bytes32(response));\\n }\\n}\\n\",\"keccak256\":\"0xcd92bcdd447010880f78e57e213123269c9e023adfc0a540608daa127d8649ca\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/facets/interfaces/IAccountFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IEntryPoint} from \\\"../../aa-4337/interfaces/IEntryPoint.sol\\\";\\n\\n/**\\n * @title Account Facet Interface\\n * @dev Interface of module contract that provides the account features and init/unitialization of signer\\n * compatible with EIP-1271 & EIP-4337\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IAccountFacet {\\n event AccountInitialized(\\n IEntryPoint indexed entryPoint,\\n bytes indexed ownerPublicKey\\n );\\n // NOTE: Added Below Event\\n event VerificationSuccess(bytes32);\\n event VerificationFailure(bytes32);\\n\\n error AccountFacet__InitializationFailure();\\n error AccountFacet__RestrictionsFailure();\\n error AccountFacet__NonExistentVerificationFacet();\\n error AccountFacet__CallNotSuccessful();\\n error AccountFacet__InvalidArrayLength();\\n\\n function initialize(\\n address verificationFacet,\\n address anEntryPoint,\\n address facetRegistry,\\n address _defaultFallBack,\\n bytes calldata _ownerPublicKey\\n ) external returns (uint256);\\n\\n function execute(address dest, uint256 value, bytes calldata func) external;\\n\\n function executeBatch(\\n address[] calldata dest,\\n uint256[] calldata value,\\n bytes[] calldata func\\n ) external;\\n}\\n\",\"keccak256\":\"0x74a9cb0b8f2f4a5148e366a401a0354426c536c012c025025d07cc25a4cd5382\",\"license\":\"Apache-2.0\"},\"contracts/facets/interfaces/IVerificationFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {UserOperation} from \\\"../../aa-4337/interfaces/UserOperation.sol\\\";\\n\\n/**\\n * @title Verification Facet Interface\\n * @dev Implements logic for user ops signature verification\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\ninterface IVerificationFacet {\\n event SignerInitialized(bytes);\\n event SignerUninitialized();\\n\\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\\n error VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\\n error VerificationFacet__InitializationFailure();\\n error VerificationFacet__InvalidFacetMapping();\\n\\n function initializeSigner(bytes memory) external returns (uint256);\\n\\n function uninitializeSigner() external returns (uint256);\\n\\n function validateOwnerSignatureSelector() external view returns (bytes4);\\n\\n function owner() external view returns (bytes memory);\\n\\n function isValidKeyType(bytes calldata) external view returns (bool);\\n\\n function validateOwnerSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x72bc370a1d1b5a6d6bde67f5026733fd8f6ba434bb90e73b0bd8627fb1579928\",\"license\":\"Apache-2.0\"},\"contracts/infrastructure/interfaces/IFacetRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Registry Interface\\n * @dev Interface for Facet Registry contract to keep track of facets & function selectors addable to user wallets\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IFacetRegistry {\\n struct FacetRegistryConfig {\\n bytes4[] selectors;\\n mapping(bytes4 => FacetInfo) info;\\n }\\n struct FacetInfo {\\n bool exists;\\n uint128 index;\\n }\\n\\n event FacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] facetSelectors\\n );\\n event FacetFunctionSelectorsRemoved(address facet, bytes4[] facetSelectors);\\n\\n error FacetRegistry__FacetSelectorAlreadyRegistered();\\n error FacetRegistry__UnregisteredFacetSelector();\\n\\n function registerFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function removeFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function areFacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external view returns (bool);\\n\\n function isFacetFunctionSelectorRegistered(\\n address facet,\\n bytes4 facetSelector\\n ) external view returns (bool);\\n\\n function getFacetFunctionSelectors(\\n address facet\\n ) external view returns (bytes4[] memory);\\n}\\n\",\"keccak256\":\"0x6e6dd2cab346ef7c31230740ec48d2925e4a9ab24c2f2fb268baaf408dcf02ef\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC1271 {\\n function isValidSignature(\\n bytes32 hash,\\n bytes memory signature\\n ) external view returns (bytes4);\\n}\\n\",\"keccak256\":\"0xcdddb7d5641c9d3f2432dec7fd13fddb9ae1480f25c76c21511e2fa16b8bd422\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibAppStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {SafeCast} from \\\"@openzeppelin/contracts/utils/math/SafeCast.sol\\\";\\nimport {IEntryPoint} from \\\"../aa-4337/interfaces/IEntryPoint.sol\\\";\\nimport {IFacetRegistry} from \\\"../infrastructure/interfaces/IFacetRegistry.sol\\\";\\n\\n/*\\n * @title App Storage\\n * @dev App storage for Barz contract to prevent storage collision\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Lock {\\n uint64 release;\\n bytes4 locker;\\n}\\n\\nstruct InitializersStorage {\\n // NOTE: initialized is a variable to make sure the initialization is only done once.\\n uint8 signerInitialized;\\n uint8 accountInitialized;\\n uint8 restrictionsInitialized;\\n}\\n\\nstruct AppStorage {\\n mapping(uint256 => InitializersStorage) initStorage;\\n uint8 signerMigration;\\n bytes4 validateOwnerSignatureSelector;\\n IEntryPoint entryPoint;\\n IFacetRegistry facetRegistry;\\n mapping(uint256 => Lock) locks;\\n}\\n\\nlibrary LibAppStorage {\\n error LibAppStorage__AccountAlreadyUninitialized();\\n error LibAppStorage__AccountMustBeUninitialized();\\n error LibAppStorage__SignerAlreadyUninitialized();\\n error LibAppStorage__SignerMustBeUninitialized();\\n\\n function appStorage() internal pure returns (AppStorage storage ds) {\\n assembly {\\n ds.slot := 0\\n }\\n }\\n\\n function setSignerUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerAlreadyUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 0;\\n }\\n\\n function getValidateOwnerSignatureSelector()\\n internal\\n view\\n returns (bytes4 selector)\\n {\\n selector = appStorage().validateOwnerSignatureSelector;\\n }\\n\\n function setValidateOwnerSignatureSelector(\\n bytes4 _validateOwnerSignatureSelector\\n ) internal {\\n appStorage()\\n .validateOwnerSignatureSelector = _validateOwnerSignatureSelector;\\n }\\n\\n function enforceSignerInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerMustBeUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 1;\\n }\\n\\n function enforceAccountInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].accountInitialized) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n s.initStorage[0].accountInitialized = 1;\\n }\\n\\n function initiateSignerMigration() internal {\\n appStorage().signerMigration = 1;\\n }\\n\\n function enforceSignerMigration() internal view {\\n if (1 != appStorage().signerMigration) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n }\\n\\n function finalizeSignerMigration() internal {\\n appStorage().signerMigration = 0;\\n }\\n\\n function setLock(uint256 _releaseAfter, bytes4 _locker) internal {\\n appStorage().locks[0] = Lock(SafeCast.toUint64(_releaseAfter), _locker);\\n }\\n\\n function enforceRestrictionsInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__SignerMustBeUninitialized();\\n s.initStorage[0].restrictionsInitialized = 1;\\n }\\n\\n function setRestrictionsUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__AccountAlreadyUninitialized();\\n s.initStorage[0].restrictionsInitialized = 0;\\n }\\n}\\n\\ncontract BarzStorage {\\n AppStorage internal s;\\n modifier onlyWhenUnlocked() {\\n require(\\n uint64(block.timestamp) >= s.locks[0].release,\\n \\\"Account Locked\\\"\\n );\\n _;\\n }\\n modifier onlyWhenLocked() {\\n require(\\n uint64(block.timestamp) < s.locks[0].release,\\n \\\"Account Unlocked\\\"\\n );\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x48524007862a6ce0e07f645950613ce6513ce073c37a109c75019683d42bae27\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\\n bytes4(keccak256(\\\"verifyRestrictions(address,address,uint256,bytes)\\\"));\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // Default Fallback Handler of the barz.\\n IDiamondLoupe defaultFallbackHandler;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function enforceIsSelf() internal view {\\n require(msg.sender == address(this), \\\"LibDiamond: Caller not self\\\");\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n\\n unchecked {\\n facetIndex++;\\n }\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n\\n function restrictionsFacet() internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(\\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2cabdc00de859c3a3170ce3bda5d0e5fd3933d47ce904fd1585f9818b02572f8\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\nimport {LibDiamond} from \\\"./LibDiamond.sol\\\";\\n\\n/**\\n * @title LibLoupe\\n * @dev Internal Library to provide utility feature for reading the state of diamond facets\\n * Originally from Diamond's implementation of Mudgen(author of EIP-2535)\\n */\\nlibrary LibLoupe {\\n /// @notice Gets all facets and their selectors.\\n /// @return facets_ Facet\\n function facets()\\n internal\\n view\\n returns (IDiamondLoupe.Facet[] memory facets_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facets_ = new IDiamondLoupe.Facet[](ds.selectorCount);\\n uint16[] memory numFacetSelectors = new uint16[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facets_[facetIndex].facetAddress == facetAddress_) {\\n facets_[facetIndex].functionSelectors[\\n numFacetSelectors[facetIndex]\\n ] = selector;\\n // probably will never have more than 256 functions from one facet contract\\n require(numFacetSelectors[facetIndex] < 255);\\n numFacetSelectors[facetIndex]++;\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facets_[numFacets].facetAddress = facetAddress_;\\n facets_[numFacets].functionSelectors = new bytes4[](\\n ds.selectorCount\\n );\\n facets_[numFacets].functionSelectors[0] = selector;\\n numFacetSelectors[numFacets] = 1;\\n numFacets++;\\n }\\n }\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n uint256 numSelectors = numFacetSelectors[facetIndex];\\n bytes4[] memory selectors = facets_[facetIndex].functionSelectors;\\n // setting the number of selectors\\n assembly {\\n mstore(selectors, numSelectors)\\n }\\n }\\n // setting the number of facets\\n assembly {\\n mstore(facets_, numFacets)\\n }\\n }\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return _facetFunctionSelectors The selectors associated with a facet address.\\n function facetFunctionSelectors(\\n address _facet\\n ) internal view returns (bytes4[] memory _facetFunctionSelectors) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n uint256 numSelectors;\\n _facetFunctionSelectors = new bytes4[](ds.selectorCount);\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facet = address(bytes20(ds.facets[selector]));\\n if (_facet == facet) {\\n _facetFunctionSelectors[numSelectors] = selector;\\n numSelectors++;\\n }\\n }\\n }\\n // Set the number of selectors in the array\\n assembly {\\n mstore(_facetFunctionSelectors, numSelectors)\\n }\\n }\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n internal\\n view\\n returns (address[] memory facetAddresses_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetAddresses_ = new address[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facetAddress_ == facetAddresses_[facetIndex]) {\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facetAddresses_[numFacets] = facetAddress_;\\n numFacets++;\\n }\\n }\\n // Set the number of facet addresses in the array\\n assembly {\\n mstore(facetAddresses_, numFacets)\\n }\\n }\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(LibDiamond.diamondStorage().facets[_functionSelector])\\n );\\n }\\n}\\n\",\"keccak256\":\"0x0b11439c3cc657095e15ec2241fdcf67204b14001357b612fc5db4ff9e760a5a\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5061001961001e565b61008e565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb554610100900460ff1615610070576040516338fc28cb60e01b815260040160405180910390fd5b600080805260209190915260409020805461ff001916610100179055565b6129b6806200009e6000396000f3fe608060405234801561001057600080fd5b50600436106100725760003560e01c8063b0d691fe11610050578063b0d691fe146100c5578063b61d27f61461010c578063d087d2881461011f57600080fd5b80633a871cdd1461007757806347e1da2a1461009d5780634a936417146100b2575b600080fd5b61008a610085366004611fb5565b610127565b6040519081526020015b60405180910390f35b6100b06100ab366004612055565b61014d565b005b61008a6100c036600461215a565b610450565b60015465010000000000900473ffffffffffffffffffffffffffffffffffffffff1660405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610094565b6100b061011a3660046121ce565b6106d0565b61008a61089d565b600061013161095e565b61013b8484610a16565b905061014682610c5d565b9392505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff9081164290911610156101f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064015b60405180910390fd5b6101fd61095e565b848114158061020c5750848314155b15610243576040517fdde5716100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006102b87fac87185d000000000000000000000000000000000000000000000000000000006000527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020527f6d9f2463c8c0d8cb8be556a773ab21d4321328909a1725f2ef7cae0c320e95da5460601c90565b905073ffffffffffffffffffffffffffffffffffffffff811661038f5760005b86811015610389576103818888838181106102f5576102f5612228565b905060200201602081019061030a9190612257565b87878481811061031c5761031c612228565b9050602002013586868581811061033557610335612228565b90506020028101906103479190612272565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610cc892505050565b6001016102d8565b50610447565b60005b868110156104455761043d8888838181106103af576103af612228565b90506020020160208101906103c49190612257565b8787848181106103d6576103d6612228565b905060200201358686858181106103ef576103ef612228565b90506020028101906104019190612272565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250889250610d45915050565b600101610392565b505b50505050505050565b600061045a610e0d565b6001805473ffffffffffffffffffffffffffffffffffffffff88811665010000000000027fffffffffffffff0000000000000000000000000000000000000000ffffffffff90921691909117909155600280548783167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216179091557f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd492380549287169290911691909117905561051187610eb3565b60008383604051602401610526929190612320565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fcd9b47e40000000000000000000000000000000000000000000000000000000017905251909150600090819073ffffffffffffffffffffffffffffffffffffffff8b16906105c8908590612360565b600060405180830381855af49150503d8060008114610603576040519150601f19603f3d011682016040523d82523d6000602084013e610608565b606091505b5091509150811580610623575061061e8161237c565b600114155b1561065a576040517f1602372100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60019350858560405161066e9291906123c1565b60405190819003812060015490916501000000000090910473ffffffffffffffffffffffffffffffffffffffff16907fd429ff0b972be4ae725700a373d05007287994e4c86cb83315b43ffa85b595fd90600090a35050509695505050505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610773576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064016101ec565b61077b61095e565b60006107f07fac87185d000000000000000000000000000000000000000000000000000000006000527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020527f6d9f2463c8c0d8cb8be556a773ab21d4321328909a1725f2ef7cae0c320e95da5460601c90565b905073ffffffffffffffffffffffffffffffffffffffff81166108535761084e858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610cc892505050565b610896565b610896858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250879250610d45915050565b5050505050565b60015460009065010000000000900473ffffffffffffffffffffffffffffffffffffffff166040517f35567e1a0000000000000000000000000000000000000000000000000000000081523060048201526000602482015273ffffffffffffffffffffffffffffffffffffffff91909116906335567e1a90604401602060405180830381865afa158015610935573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061095991906123d1565b905090565b60015465010000000000900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a14576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f6163636f756e743a206e6f742066726f6d20456e747279506f696e740000000060448201526064016101ec565b565b600154610100900460e01b7fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604081205460601c80610aab576040517f6eb2360200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600154604051600091610100900460e01b90610acd908790879060240161244e565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090506000808373ffffffffffffffffffffffffffffffffffffffff1683604051610b549190612360565b600060405180830381855af49150503d8060008114610b8f576040519150601f19603f3d011682016040523d82523d6000602084013e610b94565b606091505b509150915081610bd0576040517f3cbbb65000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610bd98161237c565b94506000859003610c1c576040518681527f19e781916118c373dadcb7776fae0a2dbb6bbdeedae143ce68031e22801ef8659060200160405180910390a1610c50565b6040518681527fbbfee2df7f28b899771f1015dc85d7840ff9f6162f23f6aa99686e8fbd2ce1319060200160405180910390a15b5050505092915050565b50565b8015610c5a5760405160009033907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90849084818181858888f193505050503d8060008114610896576040519150601f19603f3d011682016040523d82523d6000602084013e610896565b6000808473ffffffffffffffffffffffffffffffffffffffff168484604051610cf19190612360565b60006040518083038185875af1925050503d8060008114610d2e576040519150601f19603f3d011682016040523d82523d6000602084013e610d33565b606091505b50915091508161089657805160208201fd5b610d5181858585611117565b15610d88576040517f01f595e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000808573ffffffffffffffffffffffffffffffffffffffff168585604051610db19190612360565b60006040518083038185875af1925050503d8060008114610dee576040519150601f19603f3d011682016040523d82523d6000602084013e610df3565b606091505b509150915081610e0557805160208201fd5b505050505050565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb554610100900460ff1615610e78576040517f38fc28cb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100179055565b604080516001808252818301909252600091816020015b60408051606080820183526000808352602083015291810191909152815260200190600190039081610eca57905050905060008273ffffffffffffffffffffffffffffffffffffffff16633253960f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f6c9190612592565b604080516003808252608082019092529192506000919060208201606080368337019050509050631626ba7e60e01b81600081518110610fae57610fae612228565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681525050818160018151811061100e5761100e612228565b7fffffffff000000000000000000000000000000000000000000000000000000009092166020928302919091019091015280517f8da5cb5b00000000000000000000000000000000000000000000000000000000908290600290811061107657611076612228565b7fffffffff00000000000000000000000000000000000000000000000000000000909216602092830291909101820152604080516060810190915273ffffffffffffffffffffffffffffffffffffffff861681529081016000815260200182815250836000815181106110eb576110eb612228565b602002602001018190525061111183600060405180602001604052806000815250611264565b50505050565b60008030858585604051602401611131949392919061264d565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fac87185d0000000000000000000000000000000000000000000000000000000017905251909150600090819073ffffffffffffffffffffffffffffffffffffffff8916906111d3908590612360565b600060405180830381855af49150503d806000811461120e576040519150601f19603f3d011682016040523d82523d6000602084013e611213565b606091505b50915091508161124f576040517f01f595e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6112588161237c565b98975050505050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921547f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff8116908190600090600716156112d35750600381901c60009081526001840160205260409020545b60005b87518110156113505761134383838a84815181106112f6576112f6612228565b6020026020010151600001518b858151811061131457611314612228565b6020026020010151602001518c868151811061133257611332612228565b6020026020010151604001516113f0565b90935091506001016112d6565b50828214611389576002840180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff84161790555b60078216156113ab57600382901c600090815260018501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb6738787876040516113de93929190612696565b60405180910390a16104478686611e81565b600080807f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f905060008451116114a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f2063757400000000000000000000000000000000000000000060648201526084016101ec565b60008560028111156114bc576114bc6125d4565b0361168c576114e38660405180606001604052806024815260200161290d60249139611f7a565b60005b845181101561168657600085828151811061150357611503612228565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c156115d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c726561647920657869737473000000000000000000000060648201526084016101ec565b7fffffffff0000000000000000000000000000000000000000000000000000000080831660008181526020879052604090207fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608d901b168e17905560e060058e901b811692831c199c909c1690821c179a81900361166a5760038c901c600090815260018601602052604081209b909b555b8b6116748161282d565b9c5050600190930192506114e6915050565b50611e75565b60018560028111156116a0576116a06125d4565b03611990576116c78660405180606001604052806028815260200161295960289139611f7a565b60005b84518110156116865760008582815181106116e7576116e7612228565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c3081036117bc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4c69624469616d6f6e644375743a2043616e2774207265706c61636520696d6d60448201527f757461626c652066756e6374696f6e000000000000000000000000000000000060648201526084016101ec565b8973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611877576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e000000000000000060648201526084016101ec565b73ffffffffffffffffffffffffffffffffffffffff811661191a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e207468617420646f65736e2774206578697374000000000000000060648201526084016101ec565b507fffffffff0000000000000000000000000000000000000000000000000000000090911660009081526020849052604090206bffffffffffffffffffffffff919091167fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608a901b161790556001016116ca565b60028560028111156119a4576119a46125d4565b03611ded5773ffffffffffffffffffffffffffffffffffffffff861615611a4d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d75737420626520616464726573732830290000000000000000000060648201526084016101ec565b600388901c6007891660005b8651811015611dcd5760008a9003611a955782611a7581612865565b60008181526001870160205260409020549b50935060079250611aa39050565b81611a9f81612865565b9250505b6000806000808a8581518110611abb57611abb612228565b6020908102919091018101517fffffffff0000000000000000000000000000000000000000000000000000000081166000908152918a9052604090912054909150606081901c611b8d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e277420657869737400000000000000000060648201526084016101ec565b30606082901c03611c20576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e00000000000000000000000000000000000060648201526084016101ec565b600587901b8f901b94507fffffffff0000000000000000000000000000000000000000000000000000000080861690831614611cbe577fffffffff000000000000000000000000000000000000000000000000000000008516600090815260208a90526040902080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff83161790555b7fffffffff0000000000000000000000000000000000000000000000000000000091909116600090815260208990526040812055600381901c611fff16925060051b60e0169050858214611d53576000828152600188016020526040902080547fffffffff0000000000000000000000000000000000000000000000000000000080841c19909116908516831c179055611da4565b80837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c817fffffffff0000000000000000000000000000000000000000000000000000000060001b901c198e16179c505b84600003611dc257600086815260018801602052604081208190559c505b505050600101611a59565b5080611dda83600861289a565b611de491906128b7565b99505050611e75565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560448201527f74416374696f6e0000000000000000000000000000000000000000000000000060648201526084016101ec565b50959694955050505050565b73ffffffffffffffffffffffffffffffffffffffff8216611ea0575050565b611ec28260405180606001604052806028815260200161293160289139611f7a565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051611eea9190612360565b600060405180830381855af49150503d8060008114611f25576040519150601f19603f3d011682016040523d82523d6000602084013e611f2a565b606091505b50915091508161111157805115611f445780518082602001fd5b83836040517f192105d70000000000000000000000000000000000000000000000000000000081526004016101ec9291906128ca565b813b8181611111576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101ec91906128f9565b600080600060608486031215611fca57600080fd5b833567ffffffffffffffff811115611fe157600080fd5b84016101608187031215611ff457600080fd5b95602085013595506040909401359392505050565b60008083601f84011261201b57600080fd5b50813567ffffffffffffffff81111561203357600080fd5b6020830191508360208260051b850101111561204e57600080fd5b9250929050565b6000806000806000806060878903121561206e57600080fd5b863567ffffffffffffffff8082111561208657600080fd5b6120928a838b01612009565b909850965060208901359150808211156120ab57600080fd5b6120b78a838b01612009565b909650945060408901359150808211156120d057600080fd5b506120dd89828a01612009565b979a9699509497509295939492505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461211357600080fd5b919050565b60008083601f84011261212a57600080fd5b50813567ffffffffffffffff81111561214257600080fd5b60208301915083602082850101111561204e57600080fd5b60008060008060008060a0878903121561217357600080fd5b61217c876120ef565b955061218a602088016120ef565b9450612198604088016120ef565b93506121a6606088016120ef565b9250608087013567ffffffffffffffff8111156121c257600080fd5b6120dd89828a01612118565b600080600080606085870312156121e457600080fd5b6121ed856120ef565b935060208501359250604085013567ffffffffffffffff81111561221057600080fd5b61221c87828801612118565b95989497509550505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561226957600080fd5b610146826120ef565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126122a757600080fd5b83018035915067ffffffffffffffff8211156122c257600080fd5b60200191503681900382131561204e57600080fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b6020815260006123346020830184866122d7565b949350505050565b60005b8381101561235757818101518382015260200161233f565b50506000910152565b6000825161237281846020870161233c565b9190910192915050565b805160208083015191908110156123bb577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8160200360031b1b821691505b50919050565b8183823760009101908152919050565b6000602082840312156123e357600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261241f57600080fd5b830160208101925035905067ffffffffffffffff81111561243f57600080fd5b80360382131561204e57600080fd5b6040815261247c60408201612462856120ef565b73ffffffffffffffffffffffffffffffffffffffff169052565b60208301356060820152600061249560408501856123ea565b6101608060808601526124ad6101a0860183856122d7565b92506124bc60608801886123ea565b92507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0808786030160a08801526124f48585846122d7565b9450608089013560c088015260a089013560e0880152610100935060c089013584880152610120915060e089013582880152610140848a01358189015261253d838b018b6123ea565b955092508188870301848901526125558686856122d7565b9550612563818b018b6123ea565b9550935050808786030161018088015250506125808383836122d7565b93505050508260208301529392505050565b6000602082840312156125a457600080fd5b81517fffffffff000000000000000000000000000000000000000000000000000000008116811461014657600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6000815180845261261b81602086016020860161233c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600073ffffffffffffffffffffffffffffffffffffffff80871683528086166020840152508360408301526080606083015261268c6080830184612603565b9695505050505050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b848110156127c1577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808a8503018652815188850173ffffffffffffffffffffffffffffffffffffffff82511686528482015160038110612748577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b808310156127ac5783517fffffffff0000000000000000000000000000000000000000000000000000000016825292860192600192909201919086019061276a565b509785019795505050908201906001016126bf565b505073ffffffffffffffffffffffffffffffffffffffff8a169088015286810360408801526127f08189612603565b9a9950505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361285e5761285e6127fe565b5060010190565b600081612874576128746127fe565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b80820281158282048414176128b1576128b16127fe565b92915050565b808201808211156128b1576128b16127fe565b73ffffffffffffffffffffffffffffffffffffffff831681526040602082015260006123346040830184612603565b602081526000610146602083018461260356fe4c69624469616d6f6e644375743a2041646420666163657420686173206e6f20636f64654c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a205265706c61636520666163657420686173206e6f20636f6465a2646970667358221220a952f19990a20474450919a2df9ddff4430a71350892e0954f2bb073575ad64864736f6c63430008150033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100725760003560e01c8063b0d691fe11610050578063b0d691fe146100c5578063b61d27f61461010c578063d087d2881461011f57600080fd5b80633a871cdd1461007757806347e1da2a1461009d5780634a936417146100b2575b600080fd5b61008a610085366004611fb5565b610127565b6040519081526020015b60405180910390f35b6100b06100ab366004612055565b61014d565b005b61008a6100c036600461215a565b610450565b60015465010000000000900473ffffffffffffffffffffffffffffffffffffffff1660405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610094565b6100b061011a3660046121ce565b6106d0565b61008a61089d565b600061013161095e565b61013b8484610a16565b905061014682610c5d565b9392505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff9081164290911610156101f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064015b60405180910390fd5b6101fd61095e565b848114158061020c5750848314155b15610243576040517fdde5716100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006102b87fac87185d000000000000000000000000000000000000000000000000000000006000527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020527f6d9f2463c8c0d8cb8be556a773ab21d4321328909a1725f2ef7cae0c320e95da5460601c90565b905073ffffffffffffffffffffffffffffffffffffffff811661038f5760005b86811015610389576103818888838181106102f5576102f5612228565b905060200201602081019061030a9190612257565b87878481811061031c5761031c612228565b9050602002013586868581811061033557610335612228565b90506020028101906103479190612272565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610cc892505050565b6001016102d8565b50610447565b60005b868110156104455761043d8888838181106103af576103af612228565b90506020020160208101906103c49190612257565b8787848181106103d6576103d6612228565b905060200201358686858181106103ef576103ef612228565b90506020028101906104019190612272565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250889250610d45915050565b600101610392565b505b50505050505050565b600061045a610e0d565b6001805473ffffffffffffffffffffffffffffffffffffffff88811665010000000000027fffffffffffffff0000000000000000000000000000000000000000ffffffffff90921691909117909155600280548783167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216179091557f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd492380549287169290911691909117905561051187610eb3565b60008383604051602401610526929190612320565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fcd9b47e40000000000000000000000000000000000000000000000000000000017905251909150600090819073ffffffffffffffffffffffffffffffffffffffff8b16906105c8908590612360565b600060405180830381855af49150503d8060008114610603576040519150601f19603f3d011682016040523d82523d6000602084013e610608565b606091505b5091509150811580610623575061061e8161237c565b600114155b1561065a576040517f1602372100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60019350858560405161066e9291906123c1565b60405190819003812060015490916501000000000090910473ffffffffffffffffffffffffffffffffffffffff16907fd429ff0b972be4ae725700a373d05007287994e4c86cb83315b43ffa85b595fd90600090a35050509695505050505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610773576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064016101ec565b61077b61095e565b60006107f07fac87185d000000000000000000000000000000000000000000000000000000006000527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020527f6d9f2463c8c0d8cb8be556a773ab21d4321328909a1725f2ef7cae0c320e95da5460601c90565b905073ffffffffffffffffffffffffffffffffffffffff81166108535761084e858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610cc892505050565b610896565b610896858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250879250610d45915050565b5050505050565b60015460009065010000000000900473ffffffffffffffffffffffffffffffffffffffff166040517f35567e1a0000000000000000000000000000000000000000000000000000000081523060048201526000602482015273ffffffffffffffffffffffffffffffffffffffff91909116906335567e1a90604401602060405180830381865afa158015610935573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061095991906123d1565b905090565b60015465010000000000900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a14576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f6163636f756e743a206e6f742066726f6d20456e747279506f696e740000000060448201526064016101ec565b565b600154610100900460e01b7fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604081205460601c80610aab576040517f6eb2360200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600154604051600091610100900460e01b90610acd908790879060240161244e565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090506000808373ffffffffffffffffffffffffffffffffffffffff1683604051610b549190612360565b600060405180830381855af49150503d8060008114610b8f576040519150601f19603f3d011682016040523d82523d6000602084013e610b94565b606091505b509150915081610bd0576040517f3cbbb65000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610bd98161237c565b94506000859003610c1c576040518681527f19e781916118c373dadcb7776fae0a2dbb6bbdeedae143ce68031e22801ef8659060200160405180910390a1610c50565b6040518681527fbbfee2df7f28b899771f1015dc85d7840ff9f6162f23f6aa99686e8fbd2ce1319060200160405180910390a15b5050505092915050565b50565b8015610c5a5760405160009033907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90849084818181858888f193505050503d8060008114610896576040519150601f19603f3d011682016040523d82523d6000602084013e610896565b6000808473ffffffffffffffffffffffffffffffffffffffff168484604051610cf19190612360565b60006040518083038185875af1925050503d8060008114610d2e576040519150601f19603f3d011682016040523d82523d6000602084013e610d33565b606091505b50915091508161089657805160208201fd5b610d5181858585611117565b15610d88576040517f01f595e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000808573ffffffffffffffffffffffffffffffffffffffff168585604051610db19190612360565b60006040518083038185875af1925050503d8060008114610dee576040519150601f19603f3d011682016040523d82523d6000602084013e610df3565b606091505b509150915081610e0557805160208201fd5b505050505050565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb554610100900460ff1615610e78576040517f38fc28cb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100179055565b604080516001808252818301909252600091816020015b60408051606080820183526000808352602083015291810191909152815260200190600190039081610eca57905050905060008273ffffffffffffffffffffffffffffffffffffffff16633253960f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f6c9190612592565b604080516003808252608082019092529192506000919060208201606080368337019050509050631626ba7e60e01b81600081518110610fae57610fae612228565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681525050818160018151811061100e5761100e612228565b7fffffffff000000000000000000000000000000000000000000000000000000009092166020928302919091019091015280517f8da5cb5b00000000000000000000000000000000000000000000000000000000908290600290811061107657611076612228565b7fffffffff00000000000000000000000000000000000000000000000000000000909216602092830291909101820152604080516060810190915273ffffffffffffffffffffffffffffffffffffffff861681529081016000815260200182815250836000815181106110eb576110eb612228565b602002602001018190525061111183600060405180602001604052806000815250611264565b50505050565b60008030858585604051602401611131949392919061264d565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fac87185d0000000000000000000000000000000000000000000000000000000017905251909150600090819073ffffffffffffffffffffffffffffffffffffffff8916906111d3908590612360565b600060405180830381855af49150503d806000811461120e576040519150601f19603f3d011682016040523d82523d6000602084013e611213565b606091505b50915091508161124f576040517f01f595e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6112588161237c565b98975050505050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921547f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff8116908190600090600716156112d35750600381901c60009081526001840160205260409020545b60005b87518110156113505761134383838a84815181106112f6576112f6612228565b6020026020010151600001518b858151811061131457611314612228565b6020026020010151602001518c868151811061133257611332612228565b6020026020010151604001516113f0565b90935091506001016112d6565b50828214611389576002840180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff84161790555b60078216156113ab57600382901c600090815260018501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb6738787876040516113de93929190612696565b60405180910390a16104478686611e81565b600080807f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f905060008451116114a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f2063757400000000000000000000000000000000000000000060648201526084016101ec565b60008560028111156114bc576114bc6125d4565b0361168c576114e38660405180606001604052806024815260200161290d60249139611f7a565b60005b845181101561168657600085828151811061150357611503612228565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c156115d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c726561647920657869737473000000000000000000000060648201526084016101ec565b7fffffffff0000000000000000000000000000000000000000000000000000000080831660008181526020879052604090207fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608d901b168e17905560e060058e901b811692831c199c909c1690821c179a81900361166a5760038c901c600090815260018601602052604081209b909b555b8b6116748161282d565b9c5050600190930192506114e6915050565b50611e75565b60018560028111156116a0576116a06125d4565b03611990576116c78660405180606001604052806028815260200161295960289139611f7a565b60005b84518110156116865760008582815181106116e7576116e7612228565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c3081036117bc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4c69624469616d6f6e644375743a2043616e2774207265706c61636520696d6d60448201527f757461626c652066756e6374696f6e000000000000000000000000000000000060648201526084016101ec565b8973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611877576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e000000000000000060648201526084016101ec565b73ffffffffffffffffffffffffffffffffffffffff811661191a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e207468617420646f65736e2774206578697374000000000000000060648201526084016101ec565b507fffffffff0000000000000000000000000000000000000000000000000000000090911660009081526020849052604090206bffffffffffffffffffffffff919091167fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608a901b161790556001016116ca565b60028560028111156119a4576119a46125d4565b03611ded5773ffffffffffffffffffffffffffffffffffffffff861615611a4d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d75737420626520616464726573732830290000000000000000000060648201526084016101ec565b600388901c6007891660005b8651811015611dcd5760008a9003611a955782611a7581612865565b60008181526001870160205260409020549b50935060079250611aa39050565b81611a9f81612865565b9250505b6000806000808a8581518110611abb57611abb612228565b6020908102919091018101517fffffffff0000000000000000000000000000000000000000000000000000000081166000908152918a9052604090912054909150606081901c611b8d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e277420657869737400000000000000000060648201526084016101ec565b30606082901c03611c20576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e00000000000000000000000000000000000060648201526084016101ec565b600587901b8f901b94507fffffffff0000000000000000000000000000000000000000000000000000000080861690831614611cbe577fffffffff000000000000000000000000000000000000000000000000000000008516600090815260208a90526040902080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff83161790555b7fffffffff0000000000000000000000000000000000000000000000000000000091909116600090815260208990526040812055600381901c611fff16925060051b60e0169050858214611d53576000828152600188016020526040902080547fffffffff0000000000000000000000000000000000000000000000000000000080841c19909116908516831c179055611da4565b80837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c817fffffffff0000000000000000000000000000000000000000000000000000000060001b901c198e16179c505b84600003611dc257600086815260018801602052604081208190559c505b505050600101611a59565b5080611dda83600861289a565b611de491906128b7565b99505050611e75565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560448201527f74416374696f6e0000000000000000000000000000000000000000000000000060648201526084016101ec565b50959694955050505050565b73ffffffffffffffffffffffffffffffffffffffff8216611ea0575050565b611ec28260405180606001604052806028815260200161293160289139611f7a565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051611eea9190612360565b600060405180830381855af49150503d8060008114611f25576040519150601f19603f3d011682016040523d82523d6000602084013e611f2a565b606091505b50915091508161111157805115611f445780518082602001fd5b83836040517f192105d70000000000000000000000000000000000000000000000000000000081526004016101ec9291906128ca565b813b8181611111576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101ec91906128f9565b600080600060608486031215611fca57600080fd5b833567ffffffffffffffff811115611fe157600080fd5b84016101608187031215611ff457600080fd5b95602085013595506040909401359392505050565b60008083601f84011261201b57600080fd5b50813567ffffffffffffffff81111561203357600080fd5b6020830191508360208260051b850101111561204e57600080fd5b9250929050565b6000806000806000806060878903121561206e57600080fd5b863567ffffffffffffffff8082111561208657600080fd5b6120928a838b01612009565b909850965060208901359150808211156120ab57600080fd5b6120b78a838b01612009565b909650945060408901359150808211156120d057600080fd5b506120dd89828a01612009565b979a9699509497509295939492505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461211357600080fd5b919050565b60008083601f84011261212a57600080fd5b50813567ffffffffffffffff81111561214257600080fd5b60208301915083602082850101111561204e57600080fd5b60008060008060008060a0878903121561217357600080fd5b61217c876120ef565b955061218a602088016120ef565b9450612198604088016120ef565b93506121a6606088016120ef565b9250608087013567ffffffffffffffff8111156121c257600080fd5b6120dd89828a01612118565b600080600080606085870312156121e457600080fd5b6121ed856120ef565b935060208501359250604085013567ffffffffffffffff81111561221057600080fd5b61221c87828801612118565b95989497509550505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561226957600080fd5b610146826120ef565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126122a757600080fd5b83018035915067ffffffffffffffff8211156122c257600080fd5b60200191503681900382131561204e57600080fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b6020815260006123346020830184866122d7565b949350505050565b60005b8381101561235757818101518382015260200161233f565b50506000910152565b6000825161237281846020870161233c565b9190910192915050565b805160208083015191908110156123bb577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8160200360031b1b821691505b50919050565b8183823760009101908152919050565b6000602082840312156123e357600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261241f57600080fd5b830160208101925035905067ffffffffffffffff81111561243f57600080fd5b80360382131561204e57600080fd5b6040815261247c60408201612462856120ef565b73ffffffffffffffffffffffffffffffffffffffff169052565b60208301356060820152600061249560408501856123ea565b6101608060808601526124ad6101a0860183856122d7565b92506124bc60608801886123ea565b92507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0808786030160a08801526124f48585846122d7565b9450608089013560c088015260a089013560e0880152610100935060c089013584880152610120915060e089013582880152610140848a01358189015261253d838b018b6123ea565b955092508188870301848901526125558686856122d7565b9550612563818b018b6123ea565b9550935050808786030161018088015250506125808383836122d7565b93505050508260208301529392505050565b6000602082840312156125a457600080fd5b81517fffffffff000000000000000000000000000000000000000000000000000000008116811461014657600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6000815180845261261b81602086016020860161233c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600073ffffffffffffffffffffffffffffffffffffffff80871683528086166020840152508360408301526080606083015261268c6080830184612603565b9695505050505050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b848110156127c1577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808a8503018652815188850173ffffffffffffffffffffffffffffffffffffffff82511686528482015160038110612748577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b808310156127ac5783517fffffffff0000000000000000000000000000000000000000000000000000000016825292860192600192909201919086019061276a565b509785019795505050908201906001016126bf565b505073ffffffffffffffffffffffffffffffffffffffff8a169088015286810360408801526127f08189612603565b9a9950505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361285e5761285e6127fe565b5060010190565b600081612874576128746127fe565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b80820281158282048414176128b1576128b16127fe565b92915050565b808201808211156128b1576128b16127fe565b73ffffffffffffffffffffffffffffffffffffffff831681526040602082015260006123346040830184612603565b602081526000610146602083018461260356fe4c69624469616d6f6e644375743a2041646420666163657420686173206e6f20636f64654c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a205265706c61636520666163657420686173206e6f20636f6465a2646970667358221220a952f19990a20474450919a2df9ddff4430a71350892e0954f2bb073575ad64864736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "Account module contract that provides the account features and initialization of signer compatible with EIP-1271 & EIP-4337", + "kind": "dev", + "methods": { + "execute(address,uint256,bytes)": { + "details": "This method executes the calldata coming from the EntryPoint. Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)", + "params": { + "_dest": "Address of destination where the call will be forwarded to", + "_func": "Bytes of calldata to execute in the destination address", + "_value": "Amount of native coin the owner is willing to send(e.g. ETH, BNB)" + } + }, + "executeBatch(address[],uint256[],bytes[])": { + "details": "This method batch executes the calldata coming from the EntryPoint. Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)", + "params": { + "_dest": "Array of addresses of destination where the call will be forwarded to", + "_func": "Array of bytes of calldata to execute in the destination address", + "_value": "Array of amount of native coin the owner is willing to send(e.g. ETH, BNB)" + } + }, + "initialize(address,address,address,address,bytes)": { + "details": "This method can only be called during the initialization or signature migration. If the proxy contract was created without initialization, anyone can call initialize. Barz calls initialize in constructor in an atomic transaction during deployment", + "params": { + "_anEntryPoint": "Entrypoint contract defined in EIP-4337 handling the flow of UserOp", + "_defaultFallBackHandler": "Middleware contract for default facets", + "_facetRegistry": "Registry of Facets that hold all facet information", + "_ownerPublicKey": "Bytes of owner public key", + "_verificationFacet": "Facet contract handling the verificationi" + } + } + }, + "title": "Account Facet", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "constructor": { + "notice": "This constructor ensures that this contract can only be used as singleton for Proxy contracts" + }, + "entryPoint()": { + "notice": "Returns the address of EntryPoint contract registered to Barz account" + }, + "execute(address,uint256,bytes)": { + "notice": "Calls the destination with inputted calldata and value from EntryPoint" + }, + "executeBatch(address[],uint256[],bytes[])": { + "notice": "Batch calls the destination with inputted calldata and value from EntryPoint" + }, + "getNonce()": { + "notice": "Return the account nonce. This method returns the next sequential nonce. For a nonce of a specific key, use `entrypoint.getNonce(account, key)`" + }, + "initialize(address,address,address,address,bytes)": { + "notice": "Initializes the initial storage of the Barz contract." + }, + "validateUserOp((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256)": { + "notice": "Validate user's signature and nonce. subclass doesn't need to override this method. Instead, it should override the specific internal validation methods." + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 27823, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "s", + "offset": 0, + "slot": "0", + "type": "t_struct(AppStorage)27570_storage" + } + ], + "types": { + "t_bytes4": { + "encoding": "inplace", + "label": "bytes4", + "numberOfBytes": "4" + }, + "t_contract(IEntryPoint)12286": { + "encoding": "inplace", + "label": "contract IEntryPoint", + "numberOfBytes": "20" + }, + "t_contract(IFacetRegistry)26105": { + "encoding": "inplace", + "label": "contract IFacetRegistry", + "numberOfBytes": "20" + }, + "t_mapping(t_uint256,t_struct(InitializersStorage)27549_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => struct InitializersStorage)", + "numberOfBytes": "32", + "value": "t_struct(InitializersStorage)27549_storage" + }, + "t_mapping(t_uint256,t_struct(Lock)27542_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => struct Lock)", + "numberOfBytes": "32", + "value": "t_struct(Lock)27542_storage" + }, + "t_struct(AppStorage)27570_storage": { + "encoding": "inplace", + "label": "struct AppStorage", + "members": [ + { + "astId": 27554, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "initStorage", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_uint256,t_struct(InitializersStorage)27549_storage)" + }, + { + "astId": 27556, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "signerMigration", + "offset": 0, + "slot": "1", + "type": "t_uint8" + }, + { + "astId": 27558, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "validateOwnerSignatureSelector", + "offset": 1, + "slot": "1", + "type": "t_bytes4" + }, + { + "astId": 27561, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "entryPoint", + "offset": 5, + "slot": "1", + "type": "t_contract(IEntryPoint)12286" + }, + { + "astId": 27564, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "facetRegistry", + "offset": 0, + "slot": "2", + "type": "t_contract(IFacetRegistry)26105" + }, + { + "astId": 27569, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "locks", + "offset": 0, + "slot": "3", + "type": "t_mapping(t_uint256,t_struct(Lock)27542_storage)" + } + ], + "numberOfBytes": "128" + }, + "t_struct(InitializersStorage)27549_storage": { + "encoding": "inplace", + "label": "struct InitializersStorage", + "members": [ + { + "astId": 27544, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "signerInitialized", + "offset": 0, + "slot": "0", + "type": "t_uint8" + }, + { + "astId": 27546, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "accountInitialized", + "offset": 1, + "slot": "0", + "type": "t_uint8" + }, + { + "astId": 27548, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "restrictionsInitialized", + "offset": 2, + "slot": "0", + "type": "t_uint8" + } + ], + "numberOfBytes": "32" + }, + "t_struct(Lock)27542_storage": { + "encoding": "inplace", + "label": "struct Lock", + "members": [ + { + "astId": 27539, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "release", + "offset": 0, + "slot": "0", + "type": "t_uint64" + }, + { + "astId": 27541, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "locker", + "offset": 8, + "slot": "0", + "type": "t_bytes4" + } + ], + "numberOfBytes": "32" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint64": { + "encoding": "inplace", + "label": "uint64", + "numberOfBytes": "8" + }, + "t_uint8": { + "encoding": "inplace", + "label": "uint8", + "numberOfBytes": "1" + } + } + } +} \ No newline at end of file diff --git a/deployments/opBNB/BarzFactory.json b/deployments/opBNB/BarzFactory.json new file mode 100644 index 0000000..bf6d395 --- /dev/null +++ b/deployments/opBNB/BarzFactory.json @@ -0,0 +1,318 @@ +{ + "address": "0x729c310186a57833f622630a16d13f710b83272a", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_accountFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_entryPoint", + "type": "address" + }, + { + "internalType": "address", + "name": "_facetRegistry", + "type": "address" + }, + { + "internalType": "address", + "name": "_defaultFallback", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "BarzDeployed", + "type": "event" + }, + { + "inputs": [], + "name": "accountFacet", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_verificationFacet", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_owner", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "_salt", + "type": "uint256" + } + ], + "name": "createAccount", + "outputs": [ + { + "internalType": "contract Barz", + "name": "barz", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "defaultFallback", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "entryPoint", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetRegistry", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_verificationFacet", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_owner", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "_salt", + "type": "uint256" + } + ], + "name": "getAddress", + "outputs": [ + { + "internalType": "address", + "name": "barzAddress", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_accountFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_verificationFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_entryPoint", + "type": "address" + }, + { + "internalType": "address", + "name": "_facetRegistry", + "type": "address" + }, + { + "internalType": "address", + "name": "_defaultFallback", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_ownerPublicKey", + "type": "bytes" + } + ], + "name": "getBytecode", + "outputs": [ + { + "internalType": "bytes", + "name": "barzBytecode", + "type": "bytes" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "getCreationCode", + "outputs": [ + { + "internalType": "bytes", + "name": "creationCode", + "type": "bytes" + } + ], + "stateMutability": "pure", + "type": "function" + } + ], + "transactionHash": "0x44c66c9db4929170821f7b1e785f307313b6e8ff0454259764a40d2a4c4590b1", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 2, + "gasUsed": "801756", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x8d6d0c7b04abe8a434884b1ce6a9700a137f59d111e253855cea7cead56a1925", + "transactionHash": "0x44c66c9db4929170821f7b1e785f307313b6e8ff0454259764a40d2a4c4590b1", + "logs": [], + "blockNumber": 8731279, + "cumulativeGasUsed": "884483", + "status": 1, + "byzantium": true + }, + "args": [ + "0xFde53272dcd7938d16E031A6989753c321728332", + "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789", + "0xAfCb70e6e9514E2A15B23A01d2a9b9f7A34f2c33", + "0x2e7f1dAe1F3799d20f5c31bEFdc7A620f664728D" + ], + "numDeployments": 2, + "solcInputHash": "4356503edd8ae34e73cb6dd1c8e2fc8a", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_accountFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_entryPoint\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_facetRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_defaultFallback\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"BarzDeployed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"accountFacet\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_verificationFacet\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_owner\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_salt\",\"type\":\"uint256\"}],\"name\":\"createAccount\",\"outputs\":[{\"internalType\":\"contract Barz\",\"name\":\"barz\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"defaultFallback\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"entryPoint\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetRegistry\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_verificationFacet\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_owner\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_salt\",\"type\":\"uint256\"}],\"name\":\"getAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"barzAddress\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_accountFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_verificationFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_entryPoint\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_facetRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_defaultFallback\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_ownerPublicKey\",\"type\":\"bytes\"}],\"name\":\"getBytecode\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"barzBytecode\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCreationCode\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"creationCode\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"Contract to easily deploy Barz to a pre-computed address with a single call\",\"kind\":\"dev\",\"methods\":{\"constructor\":{\"params\":{\"_accountFacet\":\"Account Facet to be used to create Barz\",\"_defaultFallback\":\"Default Fallback Handler to be used to create Barz\",\"_entryPoint\":\"Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\",\"_facetRegistry\":\"Facet Registry to be used to create Barz\"}},\"createAccount(address,bytes,uint256)\":{\"params\":{\"_owner\":\"Public Key of the owner to initialize barz account\",\"_salt\":\"Salt used for deploying barz with create2\",\"_verificationFacet\":\"Address of verification facet used for creating the barz account\"},\"returns\":{\"barz\":\"Instance of Barz contract deployed with the given parameters\"}},\"getAddress(address,bytes,uint256)\":{\"params\":{\"_owner\":\"Public Key of the owner to initialize barz account\",\"_salt\":\"Salt used for deploying barz with create2\",\"_verificationFacet\":\"Address of verification facet used for creating the barz account\"},\"returns\":{\"barzAddress\":\"Precalculated Barz address\"}},\"getBytecode(address,address,address,address,address,bytes)\":{\"params\":{\"_accountFacet\":\"Account Facet to be used to create Barz\",\"_defaultFallback\":\"Default Fallback Handler to be used to create Barz\",\"_entryPoint\":\"Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\",\"_facetRegistry\":\"Facet Registry to be used to create Barz\",\"_ownerPublicKey\":\"Public Key of owner to be used to initialize Barz ownership\",\"_verificationFacet\":\"Verification Facet to be used to create Barz\"},\"returns\":{\"barzBytecode\":\"Bytecode of Barz\"}},\"getCreationCode()\":{\"returns\":{\"creationCode\":\"Creation code of Barz\"}}},\"title\":\"Barz Factory\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"Sets the initialization data for Barz contract initialization\"},\"createAccount(address,bytes,uint256)\":{\"notice\":\"Creates the Barz with a single call. It creates the Barz contract with the givent verification facet\"},\"getAddress(address,bytes,uint256)\":{\"notice\":\"Calculates the address of Barz with the given parameters\"},\"getBytecode(address,address,address,address,address,bytes)\":{\"notice\":\"Returns the bytecode of Barz with the given parameter\"},\"getCreationCode()\":{\"notice\":\"Returns the creation code of the Barz contract\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/BarzFactory.sol\":\"BarzFactory\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"contracts/Barz.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {LibDiamond} from \\\"./libraries/LibDiamond.sol\\\";\\nimport {IBarz} from \\\"./interfaces/IBarz.sol\\\";\\n\\n/**\\n * @title Barz\\n * @dev A diamond proxy wallet with a modular & upgradeable architecture\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract Barz is IBarz {\\n /**\\n * @notice Initializes Barz with the given parameters. Barz account is intended to be created from Barz Factory for stable deployment.\\n * @dev This method makes a delegate call to account facet and account facet handles the initialization.\\n * With modular architecture, Barz encompasses wide spectrum of architecture and logic.\\n * The only requirement is account facet to comply with initialize() interface.\\n * Barz doesn't include built-in functions and is a full proxy, for maximum extensibility and modularity.\\n * @param _accountFacet Address of Account Facet in charge of the Barz initialization\\n * @param _verificationFacet Address of Verification Facet for verifying the signature. Could be any signature scheme\\n * @param _entryPoint Address of Entry Point contract\\n * @param _facetRegistry Address of Facet Registry. Facet Registry is a registry holding trusted facets that could be added to user's wallet\\n * @param _defaultFallBack Address of Default FallBack Handler. Middleware contract for more efficient deployment\\n * @param _ownerPublicKey Bytes of Owner Public Key using for initialization\\n */\\n constructor(\\n address _accountFacet,\\n address _verificationFacet,\\n address _entryPoint,\\n address _facetRegistry,\\n address _defaultFallBack,\\n bytes memory _ownerPublicKey\\n ) payable {\\n bytes memory initCall = abi.encodeWithSignature(\\n \\\"initialize(address,address,address,address,bytes)\\\",\\n _verificationFacet,\\n _entryPoint,\\n _facetRegistry,\\n _defaultFallBack,\\n _ownerPublicKey\\n );\\n (bool success, bytes memory result) = _accountFacet.delegatecall(\\n initCall\\n );\\n if (!success || uint256(bytes32(result)) != 1) {\\n revert Barz__InitializationFailure();\\n }\\n }\\n\\n /**\\n * @notice Fallback function for Barz complying with Diamond Standard with customization of adding Default Fallback Handler\\n * @dev Find facet for function that is called and execute the function if a facet is found and return any value.\\n */\\n fallback() external payable {\\n LibDiamond.DiamondStorage storage ds;\\n bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION;\\n // get diamond storage\\n assembly {\\n ds.slot := position\\n }\\n // get facet from function selector\\n address facet = address(bytes20(ds.facets[msg.sig]));\\n if (facet == address(0))\\n facet = ds.defaultFallbackHandler.facetAddress(msg.sig);\\n require(facet != address(0), \\\"Barz: Function does not exist\\\");\\n // Execute external function from facet using delegatecall and return any value.\\n assembly {\\n // copy function selector and any arguments\\n calldatacopy(0, 0, calldatasize())\\n // execute function call using the facet\\n let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)\\n // get any return value\\n returndatacopy(0, 0, returndatasize())\\n // return any return value or error back to the caller\\n switch result\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @notice Receive function to receive native token without data\\n */\\n receive() external payable {}\\n}\\n\",\"keccak256\":\"0xd1c773409a4b3d1ca0316445d9ea1d686bab9cd5f6731fbdb0766a93edfd7bdb\",\"license\":\"Apache-2.0\"},\"contracts/BarzFactory.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {Barz} from \\\"./Barz.sol\\\";\\nimport {IBarzFactory} from \\\"./interfaces/IBarzFactory.sol\\\";\\n\\n/**\\n * @title Barz Factory\\n * @dev Contract to easily deploy Barz to a pre-computed address with a single call\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract BarzFactory is IBarzFactory {\\n address public immutable accountFacet;\\n address public immutable entryPoint;\\n address public immutable facetRegistry;\\n address public immutable defaultFallback;\\n\\n /**\\n * @notice Sets the initialization data for Barz contract initialization\\n * @param _accountFacet Account Facet to be used to create Barz\\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\\n * @param _facetRegistry Facet Registry to be used to create Barz\\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\\n */\\n constructor(\\n address _accountFacet,\\n address _entryPoint,\\n address _facetRegistry,\\n address _defaultFallback\\n ) {\\n accountFacet = _accountFacet;\\n entryPoint = _entryPoint;\\n facetRegistry = _facetRegistry;\\n defaultFallback = _defaultFallback;\\n }\\n\\n /**\\n * @notice Creates the Barz with a single call. It creates the Barz contract with the givent verification facet\\n * @param _verificationFacet Address of verification facet used for creating the barz account\\n * @param _owner Public Key of the owner to initialize barz account\\n * @param _salt Salt used for deploying barz with create2\\n * @return barz Instance of Barz contract deployed with the given parameters\\n */\\n function createAccount(\\n address _verificationFacet,\\n bytes calldata _owner,\\n uint256 _salt\\n ) external override returns (Barz barz) {\\n address addr = getAddress(_verificationFacet, _owner, _salt);\\n uint codeSize = addr.code.length;\\n if (codeSize > 0) {\\n return Barz(payable(addr));\\n }\\n barz = new Barz{salt: bytes32(_salt)}(\\n accountFacet,\\n _verificationFacet,\\n entryPoint,\\n facetRegistry,\\n defaultFallback,\\n _owner\\n );\\n emit BarzDeployed(address(barz));\\n }\\n\\n /**\\n * @notice Calculates the address of Barz with the given parameters\\n * @param _verificationFacet Address of verification facet used for creating the barz account\\n * @param _owner Public Key of the owner to initialize barz account\\n * @param _salt Salt used for deploying barz with create2\\n * @return barzAddress Precalculated Barz address\\n */\\n function getAddress(\\n address _verificationFacet,\\n bytes calldata _owner,\\n uint256 _salt\\n ) public view override returns (address barzAddress) {\\n bytes memory bytecode = getBytecode(\\n accountFacet,\\n _verificationFacet,\\n entryPoint,\\n facetRegistry,\\n defaultFallback,\\n _owner\\n );\\n bytes32 hash = keccak256(\\n abi.encodePacked(\\n bytes1(0xff),\\n address(this),\\n _salt,\\n keccak256(bytecode)\\n )\\n );\\n barzAddress = address(uint160(uint256(hash)));\\n }\\n\\n /**\\n * @notice Returns the bytecode of Barz with the given parameter\\n * @param _accountFacet Account Facet to be used to create Barz\\n * @param _verificationFacet Verification Facet to be used to create Barz\\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\\n * @param _facetRegistry Facet Registry to be used to create Barz\\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\\n * @param _ownerPublicKey Public Key of owner to be used to initialize Barz ownership\\n * @return barzBytecode Bytecode of Barz\\n */\\n function getBytecode(\\n address _accountFacet,\\n address _verificationFacet,\\n address _entryPoint,\\n address _facetRegistry,\\n address _defaultFallback,\\n bytes calldata _ownerPublicKey\\n ) public pure override returns (bytes memory barzBytecode) {\\n bytes memory bytecode = type(Barz).creationCode;\\n barzBytecode = abi.encodePacked(\\n bytecode,\\n abi.encode(\\n _accountFacet,\\n _verificationFacet,\\n _entryPoint,\\n _facetRegistry,\\n _defaultFallback,\\n _ownerPublicKey\\n )\\n );\\n }\\n\\n /**\\n * @notice Returns the creation code of the Barz contract\\n * @return creationCode Creation code of Barz\\n */\\n function getCreationCode()\\n public\\n pure\\n override\\n returns (bytes memory creationCode)\\n {\\n creationCode = type(Barz).creationCode;\\n }\\n}\\n\",\"keccak256\":\"0x76d6058fa4714f5ef87b876e49ce7e21f581164901eea906ec743e82362b1df6\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IBarz.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Barz Interface\\n * @dev Interface of Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IBarz {\\n error Barz__InitializationFailure();\\n}\\n\",\"keccak256\":\"0xca9f0c2c1ad7d06088fa16ae92d587416f2d10d8f999d7afe8ca5c4d73410aba\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IBarzFactory.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {Barz} from \\\"../Barz.sol\\\";\\n\\n/**\\n * @title Barz Factory Interface\\n * @dev Interface of contract to easily deploy Barz to a pre-computed address with a single call\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IBarzFactory {\\n event BarzDeployed(address);\\n\\n function createAccount(\\n address verificationFacet,\\n bytes calldata owner,\\n uint256 salt\\n ) external returns (Barz);\\n\\n function getAddress(\\n address verificationFacet,\\n bytes calldata owner,\\n uint256 salt\\n ) external view returns (address);\\n\\n function getBytecode(\\n address accountFacet,\\n address verificationFacet,\\n address entryPoint,\\n address facetRegistry,\\n address defaultFallback,\\n bytes memory ownerPublicKey\\n ) external pure returns (bytes memory);\\n\\n function getCreationCode() external pure returns (bytes memory);\\n}\\n\",\"keccak256\":\"0xadb48a6f3025f6395e26ffd5f9319da73ad2383906c8223e8455f41f420fba26\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\\n bytes4(keccak256(\\\"verifyRestrictions(address,address,uint256,bytes)\\\"));\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // Default Fallback Handler of the barz.\\n IDiamondLoupe defaultFallbackHandler;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function enforceIsSelf() internal view {\\n require(msg.sender == address(this), \\\"LibDiamond: Caller not self\\\");\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n\\n unchecked {\\n facetIndex++;\\n }\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n\\n function restrictionsFacet() internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(\\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2cabdc00de859c3a3170ce3bda5d0e5fd3933d47ce904fd1585f9818b02572f8\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x61010060405234801561001157600080fd5b50604051610eba380380610eba8339810160408190526100309161006e565b6001600160a01b0393841660805291831660a052821660c0521660e0526100c2565b80516001600160a01b038116811461006957600080fd5b919050565b6000806000806080858703121561008457600080fd5b61008d85610052565b935061009b60208601610052565b92506100a960408601610052565b91506100b760608601610052565b905092959194509250565b60805160a05160c05160e051610d886101326000396000818161013b015281816102b3015261048101526000818160bf01528181610292015261046001526000818161016301528181610271015261043f01526000818161018b0152818161024f015261041d0152610d886000f3fe60806040523480156200001157600080fd5b5060043610620000925760003560e01c806344409a82116200006257806344409a821462000135578063b0d691fe146200015d578063b0f5d4641462000185578063c8a7adf514620001ad57600080fd5b8062c194db14620000975780630a1acd7314620000b9578063296601cd146200010757806333bb64a7146200011e575b600080fd5b620000a1620001c4565b604051620000b091906200056c565b60405180910390f35b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001620000b0565b620000e16200011836600462000635565b6200020e565b620000a16200012f36600462000695565b6200036d565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e1620001be36600462000635565b62000414565b606060405180602001620001d89062000538565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082820381018352601f90910116604052919050565b6000806200021f8686868662000414565b905073ffffffffffffffffffffffffffffffffffffffff81163b8015620002495750905062000365565b8360001b7f0000000000000000000000000000000000000000000000000000000000000000887f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008b8b604051620002e29062000538565b620002f497969594939291906200073a565b8190604051809103906000f590508015801562000315573d6000803e3d6000fd5b5060405173ffffffffffffffffffffffffffffffffffffffff821681529093507f9e6e326008e68f57877e2bae766a5745c162e42359e34834a7f0661fa82d31b19060200160405180910390a150505b949350505050565b6060600060405180602001620003839062000538565b6020820181038252601f19601f8201166040525090508089898989898989604051602001620003b997969594939291906200073a565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052620003f79291602001620007cd565b604051602081830303815290604052915050979650505050505050565b600080620004a87f0000000000000000000000000000000000000000000000000000000000000000877f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008a8a6200036d565b8051602091820120604080517fff00000000000000000000000000000000000000000000000000000000000000818501523060601b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001660218201526035810196909652605580870192909252805180870390920182526075909501909452835193019290922095945050505050565b610552806200080183390190565b60005b838110156200056357818101518382015260200162000549565b50506000910152565b60208152600082518060208401526200058d81604085016020870162000546565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b803573ffffffffffffffffffffffffffffffffffffffff81168114620005e457600080fd5b919050565b60008083601f840112620005fc57600080fd5b50813567ffffffffffffffff8111156200061557600080fd5b6020830191508360208285010111156200062e57600080fd5b9250929050565b600080600080606085870312156200064c57600080fd5b6200065785620005bf565b9350602085013567ffffffffffffffff8111156200067457600080fd5b6200068287828801620005e9565b9598909750949560400135949350505050565b600080600080600080600060c0888a031215620006b157600080fd5b620006bc88620005bf565b9650620006cc60208901620005bf565b9550620006dc60408901620005bf565b9450620006ec60608901620005bf565b9350620006fc60808901620005bf565b925060a088013567ffffffffffffffff8111156200071957600080fd5b620007278a828b01620005e9565b989b979a50959850939692959293505050565b600073ffffffffffffffffffffffffffffffffffffffff808a16835280891660208401528088166040840152808716606084015280861660808401525060c060a08301528260c0830152828460e0840137600060e0848401015260e07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f850116830101905098975050505050505050565b60008351620007e181846020880162000546565b835190830190620007f781836020880162000546565b0194935050505056fe608060405260405161055238038061055283398101604081905261002291610163565b6000858585858560405160240161003d959493929190610264565b60408051601f198184030181529181526020820180516001600160e01b0316634a93641760e01b1790525190915060009081906001600160a01b038a16906100869085906102c3565b600060405180830381855af49150503d80600081146100c1576040519150601f19603f3d011682016040523d82523d6000602084013e6100c6565b606091505b50915091508115806100e157506100dc816102df565b600114155b156100ff57604051636ff35f8960e01b815260040160405180910390fd5b505050505050505050610306565b80516001600160a01b038116811461012457600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101561015a578181015183820152602001610142565b50506000910152565b60008060008060008060c0878903121561017c57600080fd5b6101858761010d565b95506101936020880161010d565b94506101a16040880161010d565b93506101af6060880161010d565b92506101bd6080880161010d565b60a08801519092506001600160401b03808211156101da57600080fd5b818901915089601f8301126101ee57600080fd5b81518181111561020057610200610129565b604051601f8201601f19908116603f0116810190838211818310171561022857610228610129565b816040528281528c602084870101111561024157600080fd5b61025283602083016020880161013f565b80955050505050509295509295509295565b600060018060a01b0380881683528087166020840152808616604084015280851660608401525060a0608083015282518060a08401526102ab8160c085016020870161013f565b601f01601f19169190910160c0019695505050505050565b600082516102d581846020870161013f565b9190910192915050565b80516020808301519190811015610300576000198160200360031b1b821691505b50919050565b61023d806103156000396000f3fe60806040523661000b57005b600080357fffffffff000000000000000000000000000000000000000000000000000000001681527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020819052604090912054819060601c80610125576004838101546040517fcdffacc60000000000000000000000000000000000000000000000000000000081526000357fffffffff00000000000000000000000000000000000000000000000000000000169281019290925273ffffffffffffffffffffffffffffffffffffffff169063cdffacc690602401602060405180830381865afa1580156100fe573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061012291906101ca565b90505b73ffffffffffffffffffffffffffffffffffffffff81166101a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4261727a3a2046756e6374696f6e20646f6573206e6f74206578697374000000604482015260640160405180910390fd5b3660008037600080366000845af43d6000803e8080156101c5573d6000f35b3d6000fd5b6000602082840312156101dc57600080fd5b815173ffffffffffffffffffffffffffffffffffffffff8116811461020057600080fd5b939250505056fea26469706673582212200f3fa76ace3be8675d8b4c0d6c210a922fff2c2f1444023b817d1f6c908cd56a64736f6c63430008150033a2646970667358221220329ad45a4ef4915180001cb1fc90a5f97ad94a0b280426a580cba65fce28c0f164736f6c63430008150033", + "deployedBytecode": "0x60806040523480156200001157600080fd5b5060043610620000925760003560e01c806344409a82116200006257806344409a821462000135578063b0d691fe146200015d578063b0f5d4641462000185578063c8a7adf514620001ad57600080fd5b8062c194db14620000975780630a1acd7314620000b9578063296601cd146200010757806333bb64a7146200011e575b600080fd5b620000a1620001c4565b604051620000b091906200056c565b60405180910390f35b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001620000b0565b620000e16200011836600462000635565b6200020e565b620000a16200012f36600462000695565b6200036d565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e1620001be36600462000635565b62000414565b606060405180602001620001d89062000538565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082820381018352601f90910116604052919050565b6000806200021f8686868662000414565b905073ffffffffffffffffffffffffffffffffffffffff81163b8015620002495750905062000365565b8360001b7f0000000000000000000000000000000000000000000000000000000000000000887f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008b8b604051620002e29062000538565b620002f497969594939291906200073a565b8190604051809103906000f590508015801562000315573d6000803e3d6000fd5b5060405173ffffffffffffffffffffffffffffffffffffffff821681529093507f9e6e326008e68f57877e2bae766a5745c162e42359e34834a7f0661fa82d31b19060200160405180910390a150505b949350505050565b6060600060405180602001620003839062000538565b6020820181038252601f19601f8201166040525090508089898989898989604051602001620003b997969594939291906200073a565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052620003f79291602001620007cd565b604051602081830303815290604052915050979650505050505050565b600080620004a87f0000000000000000000000000000000000000000000000000000000000000000877f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008a8a6200036d565b8051602091820120604080517fff00000000000000000000000000000000000000000000000000000000000000818501523060601b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001660218201526035810196909652605580870192909252805180870390920182526075909501909452835193019290922095945050505050565b610552806200080183390190565b60005b838110156200056357818101518382015260200162000549565b50506000910152565b60208152600082518060208401526200058d81604085016020870162000546565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b803573ffffffffffffffffffffffffffffffffffffffff81168114620005e457600080fd5b919050565b60008083601f840112620005fc57600080fd5b50813567ffffffffffffffff8111156200061557600080fd5b6020830191508360208285010111156200062e57600080fd5b9250929050565b600080600080606085870312156200064c57600080fd5b6200065785620005bf565b9350602085013567ffffffffffffffff8111156200067457600080fd5b6200068287828801620005e9565b9598909750949560400135949350505050565b600080600080600080600060c0888a031215620006b157600080fd5b620006bc88620005bf565b9650620006cc60208901620005bf565b9550620006dc60408901620005bf565b9450620006ec60608901620005bf565b9350620006fc60808901620005bf565b925060a088013567ffffffffffffffff8111156200071957600080fd5b620007278a828b01620005e9565b989b979a50959850939692959293505050565b600073ffffffffffffffffffffffffffffffffffffffff808a16835280891660208401528088166040840152808716606084015280861660808401525060c060a08301528260c0830152828460e0840137600060e0848401015260e07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f850116830101905098975050505050505050565b60008351620007e181846020880162000546565b835190830190620007f781836020880162000546565b0194935050505056fe608060405260405161055238038061055283398101604081905261002291610163565b6000858585858560405160240161003d959493929190610264565b60408051601f198184030181529181526020820180516001600160e01b0316634a93641760e01b1790525190915060009081906001600160a01b038a16906100869085906102c3565b600060405180830381855af49150503d80600081146100c1576040519150601f19603f3d011682016040523d82523d6000602084013e6100c6565b606091505b50915091508115806100e157506100dc816102df565b600114155b156100ff57604051636ff35f8960e01b815260040160405180910390fd5b505050505050505050610306565b80516001600160a01b038116811461012457600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101561015a578181015183820152602001610142565b50506000910152565b60008060008060008060c0878903121561017c57600080fd5b6101858761010d565b95506101936020880161010d565b94506101a16040880161010d565b93506101af6060880161010d565b92506101bd6080880161010d565b60a08801519092506001600160401b03808211156101da57600080fd5b818901915089601f8301126101ee57600080fd5b81518181111561020057610200610129565b604051601f8201601f19908116603f0116810190838211818310171561022857610228610129565b816040528281528c602084870101111561024157600080fd5b61025283602083016020880161013f565b80955050505050509295509295509295565b600060018060a01b0380881683528087166020840152808616604084015280851660608401525060a0608083015282518060a08401526102ab8160c085016020870161013f565b601f01601f19169190910160c0019695505050505050565b600082516102d581846020870161013f565b9190910192915050565b80516020808301519190811015610300576000198160200360031b1b821691505b50919050565b61023d806103156000396000f3fe60806040523661000b57005b600080357fffffffff000000000000000000000000000000000000000000000000000000001681527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020819052604090912054819060601c80610125576004838101546040517fcdffacc60000000000000000000000000000000000000000000000000000000081526000357fffffffff00000000000000000000000000000000000000000000000000000000169281019290925273ffffffffffffffffffffffffffffffffffffffff169063cdffacc690602401602060405180830381865afa1580156100fe573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061012291906101ca565b90505b73ffffffffffffffffffffffffffffffffffffffff81166101a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4261727a3a2046756e6374696f6e20646f6573206e6f74206578697374000000604482015260640160405180910390fd5b3660008037600080366000845af43d6000803e8080156101c5573d6000f35b3d6000fd5b6000602082840312156101dc57600080fd5b815173ffffffffffffffffffffffffffffffffffffffff8116811461020057600080fd5b939250505056fea26469706673582212200f3fa76ace3be8675d8b4c0d6c210a922fff2c2f1444023b817d1f6c908cd56a64736f6c63430008150033a2646970667358221220329ad45a4ef4915180001cb1fc90a5f97ad94a0b280426a580cba65fce28c0f164736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "Contract to easily deploy Barz to a pre-computed address with a single call", + "kind": "dev", + "methods": { + "constructor": { + "params": { + "_accountFacet": "Account Facet to be used to create Barz", + "_defaultFallback": "Default Fallback Handler to be used to create Barz", + "_entryPoint": "Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF", + "_facetRegistry": "Facet Registry to be used to create Barz" + } + }, + "createAccount(address,bytes,uint256)": { + "params": { + "_owner": "Public Key of the owner to initialize barz account", + "_salt": "Salt used for deploying barz with create2", + "_verificationFacet": "Address of verification facet used for creating the barz account" + }, + "returns": { + "barz": "Instance of Barz contract deployed with the given parameters" + } + }, + "getAddress(address,bytes,uint256)": { + "params": { + "_owner": "Public Key of the owner to initialize barz account", + "_salt": "Salt used for deploying barz with create2", + "_verificationFacet": "Address of verification facet used for creating the barz account" + }, + "returns": { + "barzAddress": "Precalculated Barz address" + } + }, + "getBytecode(address,address,address,address,address,bytes)": { + "params": { + "_accountFacet": "Account Facet to be used to create Barz", + "_defaultFallback": "Default Fallback Handler to be used to create Barz", + "_entryPoint": "Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF", + "_facetRegistry": "Facet Registry to be used to create Barz", + "_ownerPublicKey": "Public Key of owner to be used to initialize Barz ownership", + "_verificationFacet": "Verification Facet to be used to create Barz" + }, + "returns": { + "barzBytecode": "Bytecode of Barz" + } + }, + "getCreationCode()": { + "returns": { + "creationCode": "Creation code of Barz" + } + } + }, + "title": "Barz Factory", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "constructor": { + "notice": "Sets the initialization data for Barz contract initialization" + }, + "createAccount(address,bytes,uint256)": { + "notice": "Creates the Barz with a single call. It creates the Barz contract with the givent verification facet" + }, + "getAddress(address,bytes,uint256)": { + "notice": "Calculates the address of Barz with the given parameters" + }, + "getBytecode(address,address,address,address,address,bytes)": { + "notice": "Returns the bytecode of Barz with the given parameter" + }, + "getCreationCode()": { + "notice": "Returns the creation code of the Barz contract" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/opBNB/DefaultFallbackHandler.json b/deployments/opBNB/DefaultFallbackHandler.json new file mode 100644 index 0000000..2ecbee0 --- /dev/null +++ b/deployments/opBNB/DefaultFallbackHandler.json @@ -0,0 +1,275 @@ +{ + "address": "0x2e7f1dAe1F3799d20f5c31bEFdc7A620f664728D", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_diamondCutFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_accountFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_tokenReceiverFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_diamondLoupeFacet", + "type": "address" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_initializationContractAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "InitializationFunctionReverted", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "indexed": false, + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "DiamondCut", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_functionSelector", + "type": "bytes4" + } + ], + "name": "facetAddress", + "outputs": [ + { + "internalType": "address", + "name": "facetAddress_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetAddresses", + "outputs": [ + { + "internalType": "address[]", + "name": "facetAddresses_", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_facet", + "type": "address" + } + ], + "name": "facetFunctionSelectors", + "outputs": [ + { + "internalType": "bytes4[]", + "name": "facetFunctionSelectors_", + "type": "bytes4[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facets", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondLoupe.Facet[]", + "name": "facets_", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0x21aebfcddd0db8866fcea9d32c94f9ce8fa87308c72b71424bdf4017c38d97d7", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 2, + "gasUsed": "1438535", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000001000000000800002000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000", + "blockHash": "0xa301f105de4f83ef7df4fed99dfc8b4c7bc9d1038dddc8d8c4e8c02dd87ca0fe", + "transactionHash": "0x21aebfcddd0db8866fcea9d32c94f9ce8fa87308c72b71424bdf4017c38d97d7", + "logs": [ + { + "transactionIndex": 2, + "blockNumber": 8731274, + "transactionHash": "0x21aebfcddd0db8866fcea9d32c94f9ce8fa87308c72b71424bdf4017c38d97d7", + "address": "0x2e7f1dAe1F3799d20f5c31bEFdc7A620f664728D", + "topics": [ + "0x8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb673" + ], + "data": "0x000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000580000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000000000000000000000000000000000003600000000000000000000000000b9504140771c3688ff041917192277d2f52e1e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000011f931c1c00000000000000000000000000000000000000000000000000000000000000000000000000000000fde53272dcd7938d16e031a6989753c321728332000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000005b61d27f60000000000000000000000000000000000000000000000000000000047e1da2a000000000000000000000000000000000000000000000000000000003a871cdd00000000000000000000000000000000000000000000000000000000d087d28800000000000000000000000000000000000000000000000000000000b0d691fe000000000000000000000000000000000000000000000000000000000000000000000000000000003143e1c0af0cdc153423863923cf4e3818e34daa000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000005150b7a0200000000000000000000000000000000000000000000000000000000f23a6e6100000000000000000000000000000000000000000000000000000000bc197c81000000000000000000000000000000000000000000000000000000000023de2900000000000000000000000000000000000000000000000000000000a4c0ed3600000000000000000000000000000000000000000000000000000000000000000000000000000000ce36b85d12d81cd619c745c7717f3396e184ac7c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000097a0ed62700000000000000000000000000000000000000000000000000000000adfca15e0000000000000000000000000000000000000000000000000000000052ef6b2c00000000000000000000000000000000000000000000000000000000cdffacc60000000000000000000000000000000000000000000000000000000001ffc9a700000000000000000000000000000000000000000000000000000000f9796ccf0000000000000000000000000000000000000000000000000000000001a5502200000000000000000000000000000000000000000000000000000000d42139a900000000000000000000000000000000000000000000000000000000e3a2f6fe000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "logIndex": 8, + "blockHash": "0xa301f105de4f83ef7df4fed99dfc8b4c7bc9d1038dddc8d8c4e8c02dd87ca0fe" + } + ], + "blockNumber": 8731274, + "cumulativeGasUsed": "1671198", + "status": 1, + "byzantium": true + }, + "args": [ + "0x0B9504140771C3688Ff041917192277D2f52E1e0", + "0xFde53272dcd7938d16E031A6989753c321728332", + "0x3143E1C0Af0Cdc153423863923Cf4e3818e34Daa", + "0xCe36b85d12D81cd619C745c7717f3396E184Ac7C" + ], + "numDeployments": 2, + "solcInputHash": "4356503edd8ae34e73cb6dd1c8e2fc8a", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_diamondCutFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_accountFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_tokenReceiverFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_diamondLoupeFacet\",\"type\":\"address\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_initializationContractAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"InitializationFunctionReverted\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"DiamondCut\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_functionSelector\",\"type\":\"bytes4\"}],\"name\":\"facetAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"facetAddress_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetAddresses\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"facetAddresses_\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_facet\",\"type\":\"address\"}],\"name\":\"facetFunctionSelectors\",\"outputs\":[{\"internalType\":\"bytes4[]\",\"name\":\"facetFunctionSelectors_\",\"type\":\"bytes4[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facets\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondLoupe.Facet[]\",\"name\":\"facets_\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"A default fallback handler for Barz\",\"kind\":\"dev\",\"methods\":{\"constructor\":{\"details\":\"This contract is also a diamond that holds the default facets to reduce gas cost for wallet activation. Within the constructor this conducts diamond cut to initially setup the diamond. This is a non-upgradeable contract\",\"params\":{\"_accountFacet\":\"Address account facet\",\"_diamondCutFacet\":\"Address if diamond cut facet\",\"_diamondLoupeFacet\":\"Address of diamond loupe facet\",\"_tokenReceiverFacet\":\"Address of token receiver facet\"}},\"facetAddress(bytes4)\":{\"details\":\"If facet is not found return address(0).\",\"params\":{\"_functionSelector\":\"The function selector.\"},\"returns\":{\"facetAddress_\":\"The facet address.\"}},\"facetAddresses()\":{\"returns\":{\"facetAddresses_\":\"facetAddresses_\"}},\"facetFunctionSelectors(address)\":{\"params\":{\"_facet\":\"The facet address.\"},\"returns\":{\"facetFunctionSelectors_\":\"facetFunctionSelectors_\"}},\"facets()\":{\"returns\":{\"facets_\":\"The facet struct array including all facet information\"}}},\"title\":\"DefaultFallbackHandler\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"Sets the middleware diamond for Barz wallet as a fallback handler\"},\"facetAddress(bytes4)\":{\"notice\":\"Gets the facet that supports the given selector.\"},\"facetAddresses()\":{\"notice\":\"Get all the facet addresses used by a diamond.\"},\"facetFunctionSelectors(address)\":{\"notice\":\"Gets all the function selectors provided by a facet.\"},\"facets()\":{\"notice\":\"Returns the facet information of call facets registered to this diamond.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/infrastructure/DefaultFallbackHandler.sol\":\"DefaultFallbackHandler\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/introspection/IERC165.sol\\\";\\n\\n/**\\n * @dev _Available since v3.1._\\n */\\ninterface IERC1155Receiver is IERC165 {\\n /**\\n * @dev Handles the receipt of a single ERC1155 token type. This function is\\n * called at the end of a `safeTransferFrom` after the balance has been updated.\\n *\\n * NOTE: To accept the transfer, this must return\\n * `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))`\\n * (i.e. 0xf23a6e61, or its own function selector).\\n *\\n * @param operator The address which initiated the transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param id The ID of the token being transferred\\n * @param value The amount of tokens being transferred\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155Received(\\n address operator,\\n address from,\\n uint256 id,\\n uint256 value,\\n bytes calldata data\\n ) external returns (bytes4);\\n\\n /**\\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\\n * is called at the end of a `safeBatchTransferFrom` after the balances have\\n * been updated.\\n *\\n * NOTE: To accept the transfer(s), this must return\\n * `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))`\\n * (i.e. 0xbc197c81, or its own function selector).\\n *\\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155BatchReceived(\\n address operator,\\n address from,\\n uint256[] calldata ids,\\n uint256[] calldata values,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xeb373f1fdc7b755c6a750123a9b9e3a8a02c1470042fd6505d875000a80bde0b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title ERC721 token receiver interface\\n * @dev Interface for any contract that wants to support safeTransfers\\n * from ERC721 asset contracts.\\n */\\ninterface IERC721Receiver {\\n /**\\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\\n * by `operator` from `from`, this function is called.\\n *\\n * It must return its Solidity selector to confirm the token transfer.\\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\\n *\\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\\n */\\n function onERC721Received(\\n address operator,\\n address from,\\n uint256 tokenId,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\\n *\\n * Accounts can be notified of {IERC777} tokens being sent to them by having a\\n * contract implement this interface (contract holders can be their own\\n * implementer) and registering it on the\\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\\n *\\n * See {IERC1820Registry} and {ERC1820Implementer}.\\n */\\ninterface IERC777Recipient {\\n /**\\n * @dev Called by an {IERC777} token contract whenever tokens are being\\n * moved or created into a registered account (`to`). The type of operation\\n * is conveyed by `from` being the zero address or not.\\n *\\n * This call occurs _after_ the token contract's state is updated, so\\n * {IERC777-balanceOf}, etc., can be used to query the post-operation state.\\n *\\n * This function may revert to prevent the operation from being executed.\\n */\\n function tokensReceived(\\n address operator,\\n address from,\\n address to,\\n uint256 amount,\\n bytes calldata userData,\\n bytes calldata operatorData\\n ) external;\\n}\\n\",\"keccak256\":\"0x1a5d61db2733202ba361e6d6741cd2e662380e22b80e987eacfc91973f2267dc\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"contracts/aa-4337/core/BaseAccount.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-empty-blocks */\\n\\nimport \\\"../interfaces/IAccount.sol\\\";\\nimport \\\"../interfaces/IEntryPoint.sol\\\";\\nimport \\\"./Helpers.sol\\\";\\n\\n/**\\n * Basic account implementation.\\n * this contract provides the basic logic for implementing the IAccount interface - validateUserOp\\n * specific account implementation should inherit it and provide the account-specific logic\\n */\\nabstract contract BaseAccount is IAccount {\\n using UserOperationLib for UserOperation;\\n\\n //return value in case of signature failure, with no time-range.\\n // equivalent to _packValidationData(true,0,0);\\n uint256 internal constant SIG_VALIDATION_FAILED = 1;\\n\\n /**\\n * Return the account nonce.\\n * This method returns the next sequential nonce.\\n * For a nonce of a specific key, use `entrypoint.getNonce(account, key)`\\n */\\n function getNonce() public view virtual returns (uint256) {\\n return entryPoint().getNonce(address(this), 0);\\n }\\n\\n /**\\n * return the entryPoint used by this account.\\n * subclass should return the current entryPoint used by this account.\\n */\\n function entryPoint() public view virtual returns (IEntryPoint);\\n\\n /**\\n * Validate user's signature and nonce.\\n * subclass doesn't need to override this method. Instead, it should override the specific internal validation methods.\\n */\\n function validateUserOp(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n uint256 missingAccountFunds\\n ) external virtual override returns (uint256 validationData) {\\n _requireFromEntryPoint();\\n validationData = _validateSignature(userOp, userOpHash);\\n _validateNonce(userOp.nonce);\\n _payPrefund(missingAccountFunds);\\n }\\n\\n /**\\n * ensure the request comes from the known entrypoint.\\n */\\n function _requireFromEntryPoint() internal view virtual {\\n require(\\n msg.sender == address(entryPoint()),\\n \\\"account: not from EntryPoint\\\"\\n );\\n }\\n\\n /**\\n * validate the signature is valid for this message.\\n * @param userOp validate the userOp.signature field\\n * @param userOpHash convenient field: the hash of the request, to check the signature against\\n * (also hashes the entrypoint and chain id)\\n * @return validationData signature and time-range of this operation\\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\\n * otherwise, an address of an \\\"authorizer\\\" contract.\\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \\\"indefinite\\\"\\n * <6-byte> validAfter - first timestamp this operation is valid\\n * If the account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\\n */\\n function _validateSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) internal virtual returns (uint256 validationData);\\n\\n /**\\n * Validate the nonce of the UserOperation.\\n * This method may validate the nonce requirement of this account.\\n * e.g.\\n * To limit the nonce to use sequenced UserOps only (no \\\"out of order\\\" UserOps):\\n * `require(nonce < type(uint64).max)`\\n * For a hypothetical account that *requires* the nonce to be out-of-order:\\n * `require(nonce & type(uint64).max == 0)`\\n *\\n * The actual nonce uniqueness is managed by the EntryPoint, and thus no other\\n * action is needed by the account itself.\\n *\\n * @param nonce to validate\\n *\\n * solhint-disable-next-line no-empty-blocks\\n */\\n function _validateNonce(uint256 nonce) internal view virtual {}\\n\\n /**\\n * sends to the entrypoint (msg.sender) the missing funds for this transaction.\\n * subclass MAY override this method for better funds management\\n * (e.g. send to the entryPoint more than the minimum required, so that in future transactions\\n * it will not be required to send again)\\n * @param missingAccountFunds the minimum value this method should send the entrypoint.\\n * this value MAY be zero, in case there is enough deposit, or the userOp has a paymaster.\\n */\\n function _payPrefund(uint256 missingAccountFunds) internal virtual {\\n if (missingAccountFunds != 0) {\\n (bool success, ) = payable(msg.sender).call{\\n value: missingAccountFunds,\\n gas: type(uint256).max\\n }(\\\"\\\");\\n (success);\\n //ignore failure (its EntryPoint's job to verify, not account.)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa0dcc386b0f04711db3e394fb50e55a3b3b1a4d19fac1f10895844e1aa4e3d5c\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/core/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable no-inline-assembly */\\n\\n/**\\n * returned data from validateUserOp.\\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\\n * @param aggregator - address(0) - the account validated the signature by itself.\\n * address(1) - the account failed to validate the signature.\\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\\n * @param validAfter - this UserOp is valid only after this timestamp.\\n * @param validaUntil - this UserOp is valid only up to this timestamp.\\n */\\nstruct ValidationData {\\n address aggregator;\\n uint48 validAfter;\\n uint48 validUntil;\\n}\\n\\n//extract sigFailed, validAfter, validUntil.\\n// also convert zero validUntil to type(uint48).max\\nfunction _parseValidationData(\\n uint validationData\\n) pure returns (ValidationData memory data) {\\n address aggregator = address(uint160(validationData));\\n uint48 validUntil = uint48(validationData >> 160);\\n if (validUntil == 0) {\\n validUntil = type(uint48).max;\\n }\\n uint48 validAfter = uint48(validationData >> (48 + 160));\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n// intersect account and paymaster ranges.\\nfunction _intersectTimeRange(\\n uint256 validationData,\\n uint256 paymasterValidationData\\n) pure returns (ValidationData memory) {\\n ValidationData memory accountValidationData = _parseValidationData(\\n validationData\\n );\\n ValidationData memory pmValidationData = _parseValidationData(\\n paymasterValidationData\\n );\\n address aggregator = accountValidationData.aggregator;\\n if (aggregator == address(0)) {\\n aggregator = pmValidationData.aggregator;\\n }\\n uint48 validAfter = accountValidationData.validAfter;\\n uint48 validUntil = accountValidationData.validUntil;\\n uint48 pmValidAfter = pmValidationData.validAfter;\\n uint48 pmValidUntil = pmValidationData.validUntil;\\n\\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp\\n * @param data - the ValidationData to pack\\n */\\nfunction _packValidationData(\\n ValidationData memory data\\n) pure returns (uint256) {\\n return\\n uint160(data.aggregator) |\\n (uint256(data.validUntil) << 160) |\\n (uint256(data.validAfter) << (160 + 48));\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp, when not using an aggregator\\n * @param sigFailed - true for signature failure, false for success\\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\\n * @param validAfter first timestamp this UserOperation is valid\\n */\\nfunction _packValidationData(\\n bool sigFailed,\\n uint48 validUntil,\\n uint48 validAfter\\n) pure returns (uint256) {\\n return\\n (sigFailed ? 1 : 0) |\\n (uint256(validUntil) << 160) |\\n (uint256(validAfter) << (160 + 48));\\n}\\n\\n/**\\n * keccak function over calldata.\\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\\n */\\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\\n assembly {\\n let mem := mload(0x40)\\n let len := data.length\\n calldatacopy(mem, data.offset, len)\\n ret := keccak256(mem, len)\\n }\\n}\\n\",\"keccak256\":\"0xa79f06cd158ecb8c0da95493a2f348933b8627a63e228b99738bff3aa107942d\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAccount.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\ninterface IAccount {\\n /**\\n * Validate user's signature and nonce\\n * the entryPoint will make the call to the recipient only if this validation call returns successfully.\\n * signature failure should be reported by returning SIG_VALIDATION_FAILED (1).\\n * This allows making a \\\"simulation call\\\" without a valid signature\\n * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure.\\n *\\n * @dev Must validate caller is the entryPoint.\\n * Must validate the signature and nonce\\n * @param userOp the operation that is about to be executed.\\n * @param userOpHash hash of the user's request data. can be used as the basis for signature.\\n * @param missingAccountFunds missing funds on the account's deposit in the entrypoint.\\n * This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call.\\n * The excess is left as a deposit in the entrypoint, for future calls.\\n * can be withdrawn anytime using \\\"entryPoint.withdrawTo()\\\"\\n * In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero.\\n * @return validationData packaged ValidationData structure. use `_packValidationData` and `_unpackValidationData` to encode and decode\\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\\n * otherwise, an address of an \\\"authorizer\\\" contract.\\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \\\"indefinite\\\"\\n * <6-byte> validAfter - first timestamp this operation is valid\\n * If an account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\\n */\\n function validateUserOp(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n uint256 missingAccountFunds\\n ) external returns (uint256 validationData);\\n}\\n\",\"keccak256\":\"0xcbc4b0973cf954c5895b7796335f651fbfcfb55f67dfa789a3d354f8e23c4f2b\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAggregator.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\n/**\\n * Aggregated Signatures validator.\\n */\\ninterface IAggregator {\\n /**\\n * validate aggregated signature.\\n * revert if the aggregated signature does not match the given list of operations.\\n */\\n function validateSignatures(\\n UserOperation[] calldata userOps,\\n bytes calldata signature\\n ) external view;\\n\\n /**\\n * validate signature of a single userOp\\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\\n * @param userOp the userOperation received from the user.\\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\\n * (usually empty, unless account and aggregator support some kind of \\\"multisig\\\"\\n */\\n function validateUserOpSignature(\\n UserOperation calldata userOp\\n ) external view returns (bytes memory sigForUserOp);\\n\\n /**\\n * aggregate multiple signatures into a single value.\\n * This method is called off-chain to calculate the signature to pass with handleOps()\\n * bundler MAY use optimized custom code perform this aggregation\\n * @param userOps array of UserOperations to collect the signatures from.\\n * @return aggregatedSignature the aggregated signature\\n */\\n function aggregateSignatures(\\n UserOperation[] calldata userOps\\n ) external view returns (bytes memory aggregatedSignature);\\n}\\n\",\"keccak256\":\"0xdfdcd80568f037716674619b31be630fcd8316262f05a815b41d1e81782c966a\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IEntryPoint.sol\":{\"content\":\"/**\\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\\n ** Only one instance required on each chain.\\n **/\\n// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-inline-assembly */\\n/* solhint-disable reason-string */\\n\\nimport \\\"./UserOperation.sol\\\";\\nimport \\\"./IStakeManager.sol\\\";\\nimport \\\"./IAggregator.sol\\\";\\nimport \\\"./INonceManager.sol\\\";\\n\\ninterface IEntryPoint is IStakeManager, INonceManager {\\n /***\\n * An event emitted after each successful request\\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\\n * @param sender - the account that generates this request.\\n * @param paymaster - if non-null, the paymaster that pays for this request.\\n * @param nonce - the nonce value from the request.\\n * @param success - true if the sender transaction succeeded, false if reverted.\\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\\n */\\n event UserOperationEvent(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address indexed paymaster,\\n uint256 nonce,\\n bool success,\\n uint256 actualGasCost,\\n uint256 actualGasUsed\\n );\\n\\n /**\\n * account \\\"sender\\\" was deployed.\\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\\n * @param sender the account that is deployed\\n * @param factory the factory used to deploy this account (in the initCode)\\n * @param paymaster the paymaster used by this UserOp\\n */\\n event AccountDeployed(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address factory,\\n address paymaster\\n );\\n\\n /**\\n * An event emitted if the UserOperation \\\"callData\\\" reverted with non-zero length\\n * @param userOpHash the request unique identifier.\\n * @param sender the sender of this request\\n * @param nonce the nonce used in the request\\n * @param revertReason - the return bytes from the (reverted) call to \\\"callData\\\".\\n */\\n event UserOperationRevertReason(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n uint256 nonce,\\n bytes revertReason\\n );\\n\\n /**\\n * an event emitted by handleOps(), before starting the execution loop.\\n * any event emitted before this event, is part of the validation.\\n */\\n event BeforeExecution();\\n\\n /**\\n * signature aggregator used by the following UserOperationEvents within this bundle.\\n */\\n event SignatureAggregatorChanged(address indexed aggregator);\\n\\n /**\\n * a custom revert error of handleOps, to identify the offending op.\\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\\n * @param reason - revert reason\\n * The string starts with a unique code \\\"AAmn\\\", where \\\"m\\\" is \\\"1\\\" for factory, \\\"2\\\" for account and \\\"3\\\" for paymaster issues,\\n * so a failure can be attributed to the correct entity.\\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\\n */\\n error FailedOp(uint256 opIndex, string reason);\\n\\n /**\\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\\n */\\n error SignatureValidationFailed(address aggregator);\\n\\n /**\\n * Successful result from simulateValidation.\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n */\\n error ValidationResult(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo\\n );\\n\\n /**\\n * Successful result from simulateValidation, if the account returns a signature aggregator\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\\n * bundler MUST use it to verify the signature, or reject the UserOperation\\n */\\n error ValidationResultWithAggregation(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo,\\n AggregatorStakeInfo aggregatorInfo\\n );\\n\\n /**\\n * return value of getSenderAddress\\n */\\n error SenderAddressResult(address sender);\\n\\n /**\\n * return value of simulateHandleOp\\n */\\n error ExecutionResult(\\n uint256 preOpGas,\\n uint256 paid,\\n uint48 validAfter,\\n uint48 validUntil,\\n bool targetSuccess,\\n bytes targetResult\\n );\\n\\n //UserOps handled, per aggregator\\n struct UserOpsPerAggregator {\\n UserOperation[] userOps;\\n // aggregator address\\n IAggregator aggregator;\\n // aggregated signature\\n bytes signature;\\n }\\n\\n /**\\n * Execute a batch of UserOperation.\\n * no signature aggregator is used.\\n * if any account requires an aggregator (that is, it returned an aggregator when\\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\\n * @param ops the operations to execute\\n * @param beneficiary the address to receive the fees\\n */\\n function handleOps(\\n UserOperation[] calldata ops,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * Execute a batch of UserOperation with Aggregators\\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\\n * @param beneficiary the address to receive the fees\\n */\\n function handleAggregatedOps(\\n UserOpsPerAggregator[] calldata opsPerAggregator,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * generate a request Id - unique identifier for this request.\\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\\n */\\n function getUserOpHash(\\n UserOperation calldata userOp\\n ) external view returns (bytes32);\\n\\n /**\\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\\n * @param userOp the user operation to validate.\\n */\\n function simulateValidation(UserOperation calldata userOp) external;\\n\\n /**\\n * gas and return values during simulation\\n * @param preOpGas the gas used for validation (including preValidationGas)\\n * @param prefund the required prefund for this operation\\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\\n */\\n struct ReturnInfo {\\n uint256 preOpGas;\\n uint256 prefund;\\n bool sigFailed;\\n uint48 validAfter;\\n uint48 validUntil;\\n bytes paymasterContext;\\n }\\n\\n /**\\n * returned aggregated signature info.\\n * the aggregator returned by the account, and its current stake.\\n */\\n struct AggregatorStakeInfo {\\n address aggregator;\\n StakeInfo stakeInfo;\\n }\\n\\n /**\\n * Get counterfactual sender address.\\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\\n * this method always revert, and returns the address in SenderAddressResult error\\n * @param initCode the constructor code to be passed into the UserOperation.\\n */\\n function getSenderAddress(bytes memory initCode) external;\\n\\n /**\\n * simulate full execution of a UserOperation (including both validation and target execution)\\n * this method will always revert with \\\"ExecutionResult\\\".\\n * it performs full validation of the UserOperation, but ignores signature error.\\n * an optional target address is called after the userop succeeds, and its value is returned\\n * (before the entire call is reverted)\\n * Note that in order to collect the the success/failure of the target call, it must be executed\\n * with trace enabled to track the emitted events.\\n * @param op the UserOperation to simulate\\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\\n * are set to the return from that call.\\n * @param targetCallData callData to pass to target address\\n */\\n function simulateHandleOp(\\n UserOperation calldata op,\\n address target,\\n bytes calldata targetCallData\\n ) external;\\n}\\n\",\"keccak256\":\"0x9ccb1b188eda8bbf5f6c2d01bd83c3d8b2b04fcf745283051d31fe96d1d8e40f\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/INonceManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\ninterface INonceManager {\\n /**\\n * Return the next nonce for this sender.\\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\\n * But UserOp with different keys can come with arbitrary order.\\n *\\n * @param sender the account address\\n * @param key the high 192 bit of the nonce\\n * @return nonce a full nonce to pass for next UserOp with this sender.\\n */\\n function getNonce(\\n address sender,\\n uint192 key\\n ) external view returns (uint256 nonce);\\n\\n /**\\n * Manually increment the nonce of the sender.\\n * This method is exposed just for completeness..\\n * Account does NOT need to call it, neither during validation, nor elsewhere,\\n * as the EntryPoint will update the nonce regardless.\\n * Possible use-case is call it with various keys to \\\"initialize\\\" their nonces to one, so that future\\n * UserOperations will not pay extra for the first transaction with a given key.\\n */\\n function incrementNonce(uint192 key) external;\\n}\\n\",\"keccak256\":\"0xce478ad0fa0d18a3b785ac854623029e7ab463d05873dfaa365abfa1bf100912\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IStakeManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8.12;\\n\\n/**\\n * manage deposits and stakes.\\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\\n * stake is value locked for at least \\\"unstakeDelay\\\" by the staked entity.\\n */\\ninterface IStakeManager {\\n event Deposited(address indexed account, uint256 totalDeposit);\\n\\n event Withdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /// Emitted when stake or unstake delay are modified\\n event StakeLocked(\\n address indexed account,\\n uint256 totalStaked,\\n uint256 unstakeDelaySec\\n );\\n\\n /// Emitted once a stake is scheduled for withdrawal\\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\\n\\n event StakeWithdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /**\\n * @param deposit the entity's deposit\\n * @param staked true if this entity is staked.\\n * @param stake actual amount of ether staked for this entity.\\n * @param unstakeDelaySec minimum delay to withdraw the stake.\\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\\n * and the rest fit into a 2nd cell.\\n * 112 bit allows for 10^15 eth\\n * 48 bit for full timestamp\\n * 32 bit allows 150 years for unstake delay\\n */\\n struct DepositInfo {\\n uint112 deposit;\\n bool staked;\\n uint112 stake;\\n uint32 unstakeDelaySec;\\n uint48 withdrawTime;\\n }\\n\\n //API struct used by getStakeInfo and simulateValidation\\n struct StakeInfo {\\n uint256 stake;\\n uint256 unstakeDelaySec;\\n }\\n\\n /// @return info - full deposit information of given account\\n function getDepositInfo(\\n address account\\n ) external view returns (DepositInfo memory info);\\n\\n /// @return the deposit (for gas payment) of the account\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * add to the deposit of the given account\\n */\\n function depositTo(address account) external payable;\\n\\n /**\\n * add to the account's stake - amount and delay\\n * any pending unstake is first cancelled.\\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\\n */\\n function addStake(uint32 _unstakeDelaySec) external payable;\\n\\n /**\\n * attempt to unlock the stake.\\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\\n */\\n function unlockStake() external;\\n\\n /**\\n * withdraw from the (unlocked) stake.\\n * must first call unlockStake and wait for the unstakeDelay to pass\\n * @param withdrawAddress the address to send withdrawn value.\\n */\\n function withdrawStake(address payable withdrawAddress) external;\\n\\n /**\\n * withdraw from the deposit.\\n * @param withdrawAddress the address to send withdrawn value.\\n * @param withdrawAmount the amount to withdraw.\\n */\\n function withdrawTo(\\n address payable withdrawAddress,\\n uint256 withdrawAmount\\n ) external;\\n}\\n\",\"keccak256\":\"0xadcea606c9b7aafe6645441f2154a60f271330b0eee5292a632aa71c1672d546\",\"license\":\"GPL-3.0-only\"},\"contracts/aa-4337/interfaces/UserOperation.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable no-inline-assembly */\\n\\nimport {calldataKeccak} from \\\"../core/Helpers.sol\\\";\\n\\n/**\\n * User Operation struct\\n * @param sender the sender account of this request.\\n * @param nonce unique value the sender uses to verify it is not a replay.\\n * @param initCode if set, the account contract will be created by this constructor/\\n * @param callData the method call to execute on this account.\\n * @param callGasLimit the gas limit passed to the callData method call.\\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\\n * @param maxFeePerGas same as EIP-1559 gas parameter.\\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\\n */\\nstruct UserOperation {\\n address sender;\\n uint256 nonce;\\n bytes initCode;\\n bytes callData;\\n uint256 callGasLimit;\\n uint256 verificationGasLimit;\\n uint256 preVerificationGas;\\n uint256 maxFeePerGas;\\n uint256 maxPriorityFeePerGas;\\n bytes paymasterAndData;\\n bytes signature;\\n}\\n\\n/**\\n * Utility functions helpful when working with UserOperation structs.\\n */\\nlibrary UserOperationLib {\\n function getSender(\\n UserOperation calldata userOp\\n ) internal pure returns (address) {\\n address data;\\n //read sender from userOp, which is first userOp member (saves 800 gas...)\\n assembly {\\n data := calldataload(userOp)\\n }\\n return address(uint160(data));\\n }\\n\\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\\n // pay above what he signed for.\\n function gasPrice(\\n UserOperation calldata userOp\\n ) internal view returns (uint256) {\\n unchecked {\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n if (maxFeePerGas == maxPriorityFeePerGas) {\\n //legacy mode (for networks that don't support basefee opcode)\\n return maxFeePerGas;\\n }\\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\\n }\\n }\\n\\n function pack(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes memory ret) {\\n address sender = getSender(userOp);\\n uint256 nonce = userOp.nonce;\\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\\n bytes32 hashCallData = calldataKeccak(userOp.callData);\\n uint256 callGasLimit = userOp.callGasLimit;\\n uint256 verificationGasLimit = userOp.verificationGasLimit;\\n uint256 preVerificationGas = userOp.preVerificationGas;\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\\n\\n return\\n abi.encode(\\n sender,\\n nonce,\\n hashInitCode,\\n hashCallData,\\n callGasLimit,\\n verificationGasLimit,\\n preVerificationGas,\\n maxFeePerGas,\\n maxPriorityFeePerGas,\\n hashPaymasterAndData\\n );\\n }\\n\\n function hash(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes32) {\\n return keccak256(pack(userOp));\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n}\\n\",\"keccak256\":\"0x2429f5cc546bdee08c7e63858d0dda8491eaa3ab5194df884dc948c1154d2834\",\"license\":\"GPL-3.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IStorageLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"./IDiamondLoupe.sol\\\";\\n\\n/**\\n * @title LoupeFromStorage Interface\\n * @dev Interface contract to function as a loupe facet directly attached to diamond storage of Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IStorageLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facetsFromStorage()\\n external\\n view\\n returns (IDiamondLoupe.Facet[] memory);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n function facetFunctionSelectorsFromStorage(\\n address _facet\\n ) external view returns (bytes4[] memory);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n function facetAddressesFromStorage()\\n external\\n view\\n returns (address[] memory);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n function facetAddressFromStorage(\\n bytes4 _functionSelector\\n ) external view returns (address);\\n}\\n\",\"keccak256\":\"0xdf5dc9c57319e9087628c9cf9404b4f75585b76d1c2f4f59ee796c933967ea5c\",\"license\":\"Apache-2.0\"},\"contracts/facets/interfaces/IAccountFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IEntryPoint} from \\\"../../aa-4337/interfaces/IEntryPoint.sol\\\";\\n\\n/**\\n * @title Account Facet Interface\\n * @dev Interface of module contract that provides the account features and init/unitialization of signer\\n * compatible with EIP-1271 & EIP-4337\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IAccountFacet {\\n event AccountInitialized(\\n IEntryPoint indexed entryPoint,\\n bytes indexed ownerPublicKey\\n );\\n // NOTE: Added Below Event\\n event VerificationSuccess(bytes32);\\n event VerificationFailure(bytes32);\\n\\n error AccountFacet__InitializationFailure();\\n error AccountFacet__RestrictionsFailure();\\n error AccountFacet__NonExistentVerificationFacet();\\n error AccountFacet__CallNotSuccessful();\\n error AccountFacet__InvalidArrayLength();\\n\\n function initialize(\\n address verificationFacet,\\n address anEntryPoint,\\n address facetRegistry,\\n address _defaultFallBack,\\n bytes calldata _ownerPublicKey\\n ) external returns (uint256);\\n\\n function execute(address dest, uint256 value, bytes calldata func) external;\\n\\n function executeBatch(\\n address[] calldata dest,\\n uint256[] calldata value,\\n bytes[] calldata func\\n ) external;\\n}\\n\",\"keccak256\":\"0x74a9cb0b8f2f4a5148e366a401a0354426c536c012c025025d07cc25a4cd5382\",\"license\":\"Apache-2.0\"},\"contracts/infrastructure/DefaultFallbackHandler.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IERC721Receiver} from \\\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\\\";\\nimport {IERC1155Receiver} from \\\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\\\";\\nimport {IERC777Recipient} from \\\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\\\";\\nimport {BaseAccount} from \\\"../aa-4337/core/BaseAccount.sol\\\";\\nimport {DefaultLibDiamond} from \\\"../libraries/DefaultLibDiamond.sol\\\";\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IAccountFacet} from \\\"../facets/interfaces/IAccountFacet.sol\\\";\\nimport {IStorageLoupe} from \\\"../facets/base/interfaces/IStorageLoupe.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\nimport {IERC677Receiver} from \\\"../interfaces/ERC/IERC677Receiver.sol\\\";\\nimport {IERC165} from \\\"../interfaces/ERC/IERC165.sol\\\";\\n\\n/**\\n * @title DefaultFallbackHandler\\n * @dev A default fallback handler for Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract DefaultFallbackHandler is IDiamondLoupe {\\n /**\\n * @notice Sets the middleware diamond for Barz wallet as a fallback handler\\n * @dev This contract is also a diamond that holds the default facets to reduce gas cost for wallet activation.\\n * Within the constructor this conducts diamond cut to initially setup the diamond. This is a non-upgradeable contract\\n * @param _diamondCutFacet Address if diamond cut facet\\n * @param _accountFacet Address account facet\\n * @param _tokenReceiverFacet Address of token receiver facet\\n * @param _diamondLoupeFacet Address of diamond loupe facet\\n */\\n constructor(\\n address _diamondCutFacet,\\n address _accountFacet,\\n address _tokenReceiverFacet,\\n address _diamondLoupeFacet\\n ) payable {\\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](4);\\n bytes4[] memory functionSelectors = new bytes4[](1);\\n functionSelectors[0] = IDiamondCut.diamondCut.selector;\\n\\n bytes4[] memory accountFunctionSelectors = new bytes4[](5);\\n accountFunctionSelectors[0] = IAccountFacet.execute.selector;\\n accountFunctionSelectors[1] = IAccountFacet.executeBatch.selector;\\n accountFunctionSelectors[2] = BaseAccount.validateUserOp.selector;\\n accountFunctionSelectors[3] = BaseAccount.getNonce.selector;\\n accountFunctionSelectors[4] = BaseAccount.entryPoint.selector;\\n\\n bytes4[] memory receiverFacetSelectors = new bytes4[](5);\\n receiverFacetSelectors[0] = IERC721Receiver.onERC721Received.selector;\\n receiverFacetSelectors[1] = IERC1155Receiver.onERC1155Received.selector;\\n receiverFacetSelectors[2] = IERC1155Receiver\\n .onERC1155BatchReceived\\n .selector;\\n receiverFacetSelectors[3] = IERC777Recipient.tokensReceived.selector;\\n receiverFacetSelectors[4] = IERC677Receiver.onTokenTransfer.selector;\\n\\n bytes4[] memory loupeFacetSelectors = new bytes4[](9);\\n loupeFacetSelectors[0] = IDiamondLoupe.facets.selector;\\n loupeFacetSelectors[1] = IDiamondLoupe.facetFunctionSelectors.selector;\\n loupeFacetSelectors[2] = IDiamondLoupe.facetAddresses.selector;\\n loupeFacetSelectors[3] = IDiamondLoupe.facetAddress.selector;\\n loupeFacetSelectors[4] = IERC165.supportsInterface.selector;\\n loupeFacetSelectors[5] = IStorageLoupe.facetsFromStorage.selector;\\n loupeFacetSelectors[6] = IStorageLoupe\\n .facetFunctionSelectorsFromStorage\\n .selector;\\n loupeFacetSelectors[7] = IStorageLoupe\\n .facetAddressesFromStorage\\n .selector;\\n loupeFacetSelectors[8] = IStorageLoupe.facetAddressFromStorage.selector;\\n\\n {\\n cut[0] = IDiamondCut.FacetCut({\\n facetAddress: _diamondCutFacet,\\n action: IDiamondCut.FacetCutAction.Add,\\n functionSelectors: functionSelectors\\n });\\n cut[1] = IDiamondCut.FacetCut({\\n facetAddress: _accountFacet,\\n action: IDiamondCut.FacetCutAction.Add,\\n functionSelectors: accountFunctionSelectors\\n });\\n cut[2] = IDiamondCut.FacetCut({\\n facetAddress: _tokenReceiverFacet,\\n action: IDiamondCut.FacetCutAction.Add,\\n functionSelectors: receiverFacetSelectors\\n });\\n cut[3] = IDiamondCut.FacetCut({\\n facetAddress: _diamondLoupeFacet,\\n action: IDiamondCut.FacetCutAction.Add,\\n functionSelectors: loupeFacetSelectors\\n });\\n\\n DefaultLibDiamond.diamondCut(cut, address(0), \\\"\\\");\\n }\\n }\\n\\n /**\\n * @notice Returns the facet information of call facets registered to this diamond.\\n * @return facets_ The facet struct array including all facet information\\n */\\n function facets() external view override returns (Facet[] memory facets_) {\\n DefaultLibDiamond.DiamondStorage storage ds = DefaultLibDiamond\\n .diamondStorage();\\n uint256 numFacets = ds.facetAddresses.length;\\n facets_ = new Facet[](numFacets);\\n for (uint256 i; i < numFacets; ) {\\n address facetAddress_ = ds.facetAddresses[i];\\n facets_[i].facetAddress = facetAddress_;\\n facets_[i].functionSelectors = ds\\n .facetFunctionSelectors[facetAddress_]\\n .functionSelectors;\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * @notice Gets all the function selectors provided by a facet.\\n * @param _facet The facet address.\\n * @return facetFunctionSelectors_\\n */\\n function facetFunctionSelectors(\\n address _facet\\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\\n facetFunctionSelectors_ = DefaultLibDiamond\\n .diamondStorage()\\n .facetFunctionSelectors[_facet]\\n .functionSelectors;\\n }\\n\\n /**\\n * @notice Get all the facet addresses used by a diamond.\\n * @return facetAddresses_\\n */\\n function facetAddresses()\\n external\\n view\\n override\\n returns (address[] memory facetAddresses_)\\n {\\n facetAddresses_ = DefaultLibDiamond.diamondStorage().facetAddresses;\\n }\\n\\n /** @notice Gets the facet that supports the given selector.\\n * @dev If facet is not found return address(0).\\n * @param _functionSelector The function selector.\\n * @return facetAddress_ The facet address.\\n */\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view override returns (address facetAddress_) {\\n facetAddress_ = DefaultLibDiamond\\n .diamondStorage()\\n .selectorToFacetAndPosition[_functionSelector]\\n .facetAddress;\\n }\\n}\\n\",\"keccak256\":\"0xa482fe778481e34e9fb3c4074231f8048437e934c0ca9a0c78e8e61d3a24470a\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.21;\\n\\ninterface IERC165 {\\n /// @notice Query if a contract implements an interface\\n /// @param interfaceId The interface identifier, as specified in ERC-165\\n /// @dev Interface identification is specified in ERC-165. This function\\n /// uses less than 30,000 gas.\\n /// @return `true` if the contract implements `interfaceID` and\\n /// `interfaceID` is not 0xffffffff, `false` otherwise\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xbb7f07e170898793c5535cc4b7e8944c4b990a631ac806d0b788e794abc788a3\",\"license\":\"MIT\"},\"contracts/interfaces/ERC/IERC677Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC677Receiver {\\n function onTokenTransfer(\\n address sender,\\n uint value,\\n bytes calldata data\\n ) external pure returns (bool);\\n}\\n\",\"keccak256\":\"0x4c1631cf45ea6daac0ec158c3edb9453099130b6b64f697004b83f95aa1f7350\",\"license\":\"Apache-2.0\"},\"contracts/libraries/DefaultLibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary DefaultLibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (\\n uint256 facetIndex;\\n facetIndex < _diamondCut.length;\\n facetIndex++\\n ) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(\\n address _facetAddress,\\n bytes4[] memory _functionSelectors\\n ) internal {\\n uint256 funcSelectorsLength = _functionSelectors.length;\\n require(\\n funcSelectorsLength > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _facetAddress != address(0),\\n \\\"LibDiamondCut: Add facet can't be address(0)\\\"\\n );\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (\\n uint256 selectorIndex;\\n selectorIndex < funcSelectorsLength;\\n selectorIndex++\\n ) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds\\n .selectorToFacetAndPosition[selector]\\n .facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(\\n address _facetAddress,\\n bytes4[] memory _functionSelectors\\n ) internal {\\n uint256 funcSelectorsLength = _functionSelectors.length;\\n require(\\n funcSelectorsLength > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _facetAddress != address(0),\\n \\\"LibDiamondCut: Replace facet can't be address(0)\\\"\\n );\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (\\n uint256 selectorIndex;\\n selectorIndex < funcSelectorsLength;\\n selectorIndex++\\n ) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds\\n .selectorToFacetAndPosition[selector]\\n .facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same facet\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(\\n address _facetAddress,\\n bytes4[] memory _functionSelectors\\n ) internal {\\n uint256 funcSelectorsLength = _functionSelectors.length;\\n require(\\n funcSelectorsLength > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(\\n _facetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n for (\\n uint256 selectorIndex;\\n selectorIndex < funcSelectorsLength;\\n selectorIndex++\\n ) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds\\n .selectorToFacetAndPosition[selector]\\n .facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(\\n DiamondStorage storage ds,\\n address _facetAddress\\n ) internal {\\n enforceHasContractCode(\\n _facetAddress,\\n \\\"LibDiamondCut: New facet has no code\\\"\\n );\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds\\n .facetAddresses\\n .length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds\\n .selectorToFacetAndPosition[_selector]\\n .functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(\\n _selector\\n );\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(\\n _facetAddress != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // an immutable function is a function defined directly in a diamond\\n require(\\n _facetAddress != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds\\n .selectorToFacetAndPosition[_selector]\\n .functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors[lastSelectorPosition];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n selectorPosition\\n ] = lastSelector;\\n ds\\n .selectorToFacetAndPosition[lastSelector]\\n .functionSelectorPosition = uint96(selectorPosition);\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[\\n lastFacetAddressPosition\\n ];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds\\n .facetFunctionSelectors[lastFacetAddress]\\n .facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds\\n .facetFunctionSelectors[_facetAddress]\\n .facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x1b08f332d62919288bb1f0d154ca4b85f4e167d2a06e680f8ec93dba65be3be1\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x6080604052604051620020183803806200201883398101604081905262000026916200156b565b60408051600480825260a08201909252600091816020015b604080516060808201835260008083526020830152918101919091528152602001906001900390816200003e5750506040805160018082528183019092529192506000919060208083019080368337019050509050631f931c1c60e01b81600081518110620000b157620000b1620015c8565b6001600160e01b03199290921660209283029190910182015260408051600580825260c08201909252600092909190820160a08036833701905050905063b61d27f660e01b816000815181106200010c576200010c620015c8565b6001600160e01b03199092166020928302919091019091015280516323f0ed1560e11b9082906001908110620001465762000146620015c8565b6001600160e01b0319909216602092830291909101909101528051633a871cdd60e01b9082906002908110620001805762000180620015c8565b6001600160e01b0319909216602092830291909101909101528051631a10fa5160e31b9082906003908110620001ba57620001ba620015c8565b6001600160e01b031990921660209283029190910190910152805163586b48ff60e11b9082906004908110620001f457620001f4620015c8565b6001600160e01b03199290921660209283029190910182015260408051600580825260c08201909252600092909190820160a08036833701905050905063150b7a0260e01b816000815181106200024f576200024f620015c8565b6001600160e01b031990921660209283029190910190910152805163f23a6e6160e01b9082906001908110620002895762000289620015c8565b6001600160e01b031990921660209283029190910190910152805163bc197c8160e01b9082906002908110620002c357620002c3620015c8565b6001600160e01b03199092166020928302919091019091015280516223de2960e01b9082906003908110620002fc57620002fc620015c8565b6001600160e01b0319909216602092830291909101909101528051635260769b60e11b9082906004908110620003365762000336620015c8565b6001600160e01b0319929092166020928302919091018201526040805160098082526101408201909252600092909190820161012080368337019050509050637a0ed62760e01b81600081518110620003935762000393620015c8565b6001600160e01b03199092166020928302919091019091015280516356fe50af60e11b9082906001908110620003cd57620003cd620015c8565b6001600160e01b03199092166020928302919091019091015280516314bbdacb60e21b9082906002908110620004075762000407620015c8565b6001600160e01b03199092166020928302919091019091015280516366ffd66360e11b9082906003908110620004415762000441620015c8565b6001600160e01b03199092166020928302919091019091015280516301ffc9a760e01b90829060049081106200047b576200047b620015c8565b6001600160e01b031990921660209283029190910190910152805163f9796ccf60e01b9082906005908110620004b557620004b5620015c8565b6001600160e01b031990921660209283029190910190910152805162d2a81160e11b9082906006908110620004ee57620004ee620015c8565b6001600160e01b031990921660209283029190910190910152805163d42139a960e01b9082906007908110620005285762000528620015c8565b6001600160e01b03199092166020928302919091019091015280516371d17b7f60e11b9082906008908110620005625762000562620015c8565b6001600160e01b031990921660209283029190910182015260408051606081019091526001600160a01b038b168152908101600081526020018581525085600081518110620005b557620005b5620015c8565b60200260200101819052506040518060600160405280896001600160a01b0316815260200160006002811115620005f057620005f0620015de565b815260200184815250856001815181106200060f576200060f620015c8565b60200260200101819052506040518060600160405280886001600160a01b03168152602001600060028111156200064a576200064a620015de565b81526020018381525085600281518110620006695762000669620015c8565b60200260200101819052506040518060600160405280876001600160a01b0316815260200160006002811115620006a457620006a4620015de565b81526020018281525085600381518110620006c357620006c3620015c8565b6020026020010181905250620006f1856000604051806020016040528060008152506200070060201b60201c565b5050505050505050506200184c565b60005b83518110156200090c576000848281518110620007245762000724620015c8565b602002602001015160200151905060006002811115620007485762000748620015de565b8160028111156200075d576200075d620015de565b03620007bb57620007b58583815181106200077c576200077c620015c8565b6020026020010151600001518684815181106200079d576200079d620015c8565b6020026020010151604001516200095b60201b60201c565b620008f6565b6001816002811115620007d257620007d2620015de565b036200082a57620007b5858381518110620007f157620007f1620015c8565b602002602001015160000151868481518110620008125762000812620015c8565b60200260200101516040015162000bf760201b60201c565b6002816002811115620008415762000841620015de565b036200089957620007b5858381518110620008605762000860620015c8565b602002602001015160000151868481518110620008815762000881620015c8565b60200260200101516040015162000ea160201b60201c565b60405162461bcd60e51b815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f727265637420466163657443756044820152663a20b1ba34b7b760c91b60648201526084015b60405180910390fd5b508062000903816200160a565b91505062000703565b507f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb67383838360405162000942939291906200167a565b60405180910390a162000956828262001005565b505050565b805180620009af5760405162461bcd60e51b815260206004820152602b602482015260008051602062001ff883398151915260448201526a1858d95d081d1bc818dd5d60aa1b6064820152608401620008ed565b60008051602062001f8c8339815191526001600160a01b03841662000a2c5760405162461bcd60e51b815260206004820152602c60248201527f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260448201526b65206164647265737328302960a01b6064820152608401620008ed565b6001600160a01b0384166000908152600182016020526040812054906001600160601b038216900362000a655762000a658286620010dd565b60005b8381101562000bef57600085828151811062000a885762000a88620015c8565b6020908102919091018101516001600160e01b031981166000908152918690526040909120549091506001600160a01b0316801562000b305760405162461bcd60e51b815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c72656164792065786973747300000000000000000000006064820152608401620008ed565b6001600160e01b0319821660008181526020878152604080832080546001600160a01b03908116600160a01b6001600160601b038c16021782558d168085526001808c0185529285208054938401815585528385206008840401805463ffffffff60079095166004026101000a948502191660e08a901c94909402939093179092559390925287905281546001600160a01b0319161790558362000bd48162001781565b9450505050808062000be6906200160a565b91505062000a68565b505050505050565b80518062000c4b5760405162461bcd60e51b815260206004820152602b602482015260008051602062001ff883398151915260448201526a1858d95d081d1bc818dd5d60aa1b6064820152608401620008ed565b60008051602062001f8c8339815191526001600160a01b03841662000ccc5760405162461bcd60e51b815260206004820152603060248201527f4c69624469616d6f6e644375743a205265706c6163652066616365742063616e60448201526f2774206265206164647265737328302960801b6064820152608401620008ed565b6001600160a01b0384166000908152600182016020526040812054906001600160601b038216900362000d055762000d058286620010dd565b60005b8381101562000bef57600085828151811062000d285762000d28620015c8565b6020908102919091018101516001600160e01b031981166000908152918690526040909120549091506001600160a01b03908116908816810362000dd55760405162461bcd60e51b815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d6520666163657400000000000000000000006064820152608401620008ed565b62000de28582846200114a565b6001600160e01b0319821660008181526020878152604080832080546001600160a01b03908116600160a01b6001600160601b038c16021782558d168085526001808c0185529285208054938401815585528385206008840401805463ffffffff60079095166004026101000a948502191660e08a901c94909402939093179092559390925287905281546001600160a01b0319161790558362000e868162001781565b9450505050808062000e98906200160a565b91505062000d08565b80518062000ef55760405162461bcd60e51b815260206004820152602b602482015260008051602062001ff883398151915260448201526a1858d95d081d1bc818dd5d60aa1b6064820152608401620008ed565b60008051602062001f8c8339815191526001600160a01b0384161562000f845760405162461bcd60e51b815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d7573742062652061646472657373283029000000000000000000006064820152608401620008ed565b60005b8281101562000ffe57600084828151811062000fa75762000fa7620015c8565b6020908102919091018101516001600160e01b031981166000908152918590526040909120549091506001600160a01b031662000fe68482846200114a565b5050808062000ff5906200160a565b91505062000f87565b5050505050565b6001600160a01b03821662001018575050565b6200103d8260405180606001604052806028815260200162001fac602891396200152a565b600080836001600160a01b0316836040516200105a9190620017b2565b600060405180830381855af49150503d806000811462001097576040519150601f19603f3d011682016040523d82523d6000602084013e6200109c565b606091505b509150915081620010d757805115620010b85780518082602001fd5b838360405163192105d760e01b8152600401620008ed929190620017d0565b50505050565b620011028160405180606001604052806024815260200162001fd4602491396200152a565b6002820180546001600160a01b0390921660008181526001948501602090815260408220860185905594840183559182529290200180546001600160a01b0319169091179055565b6001600160a01b038216620011c85760405162461bcd60e51b815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608401620008ed565b306001600160a01b03831603620012395760405162461bcd60e51b815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201526d3a30b1363290333ab731ba34b7b760911b6064820152608401620008ed565b6001600160e01b03198116600090815260208481526040808320546001600160a01b0386168452600180880190935290832054600160a01b9091046001600160601b031692916200128a91620017fe565b905080821462001383576001600160a01b03841660009081526001860160205260408120805483908110620012c357620012c3620015c8565b600091825260208083206008830401546001600160a01b038916845260018a019091526040909220805460079092166004026101000a90920460e01b925082919085908110620013175762001317620015c8565b600091825260208083206008830401805463ffffffff60079094166004026101000a938402191660e09590951c929092029390931790556001600160e01b03199290921682528690526040902080546001600160a01b0316600160a01b6001600160601b038516021790555b6001600160a01b03841660009081526001860160205260409020805480620013af57620013af6200181a565b60008281526020808220600860001990940193840401805463ffffffff600460078716026101000a0219169055919092556001600160e01b0319851682528690526040812081905581900362000ffe5760028501546000906200141590600190620017fe565b6001600160a01b0386166000908152600180890160205260409091200154909150808214620014cb576000876002018381548110620014585762001458620015c8565b6000918252602090912001546002890180546001600160a01b0390921692508291849081106200148c576200148c620015c8565b600091825260208083209190910180546001600160a01b0319166001600160a01b03948516179055929091168152600189810190925260409020018190555b86600201805480620014e157620014e16200181a565b60008281526020808220830160001990810180546001600160a01b03191690559092019092556001600160a01b0388168252600189810190915260408220015550505050505050565b813b8181620010d75760405162461bcd60e51b8152600401620008ed919062001830565b80516001600160a01b03811681146200156657600080fd5b919050565b600080600080608085870312156200158257600080fd5b6200158d856200154e565b93506200159d602086016200154e565b9250620015ad604086016200154e565b9150620015bd606086016200154e565b905092959194509250565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016200161f576200161f620015f4565b5060010190565b60005b838110156200164357818101518382015260200162001629565b50506000910152565b600081518084526200166681602086016020860162001626565b601f01601f19169290920160200192915050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b848110156200174f57898403607f19018652815180516001600160a01b03168552838101518986019060038110620016eb57634e487b7160e01b600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b80831015620017395783516001600160e01b03191682529286019260019290920191908601906200170d565b50978501979550505090820190600101620016a3565b50506001600160a01b038a169088015286810360408801526200177381896200164c565b9a9950505050505050505050565b60006001600160601b038281166002600160601b03198101620017a857620017a8620015f4565b6001019392505050565b60008251620017c681846020870162001626565b9190910192915050565b6001600160a01b0383168152604060208201819052600090620017f6908301846200164c565b949350505050565b81810381811115620018145762001814620015f4565b92915050565b634e487b7160e01b600052603160045260246000fd5b6020815260006200184560208301846200164c565b9392505050565b610730806200185c6000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806352ef6b2c146100515780637a0ed6271461006f578063adfca15e14610084578063cdffacc6146100a4575b600080fd5b610059610140565b60405161006691906104ab565b60405180910390f35b6100776101d1565b6040516100669190610562565b61009761009236600461060a565b6103d1565b6040516100669190610647565b61011b6100b236600461065a565b7fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610066565b60607f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6002018054806020026020016040519081016040528092919081815260200182805480156101c757602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161019c575b5050505050905090565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f908067ffffffffffffffff8111156102315761023161069c565b60405190808252806020026020018201604052801561027757816020015b60408051808201909152600081526060602082015281526020019060019003908161024f5790505b50925060005b818110156103cb57600083600201828154811061029c5761029c6106cb565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050808583815181106102dc576102dc6106cb565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff928316905290821660009081526001860182526040908190208054825181850281018501909352808352919290919083018282801561039d57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161034a5790505b50505050508583815181106103b4576103b46106cb565b60209081029190910181015101525060010161027d565b50505090565b73ffffffffffffffffffffffffffffffffffffffff811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4920602090815260409182902080548351818402810184019094528084526060939283018282801561049f57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161044c5790505b50505050509050919050565b6020808252825182820181905260009190848201906040850190845b818110156104f957835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016104c7565b50909695505050505050565b600081518084526020808501945080840160005b838110156105575781517fffffffff000000000000000000000000000000000000000000000000000000001687529582019590820190600101610519565b509495945050505050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b838110156105fc578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00185528151805173ffffffffffffffffffffffffffffffffffffffff1684528701518784018790526105e987850182610505565b9588019593505090860190600101610589565b509098975050505050505050565b60006020828403121561061c57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461064057600080fd5b9392505050565b6020815260006106406020830184610505565b60006020828403121561066c57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461064057600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea264697066735822122024a872696a5ad50024326567061c50adea63ff0d49edf0ac60339459d33d571664736f6c63430008150033183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f4c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a204e657720666163657420686173206e6f20636f64654c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e2066", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806352ef6b2c146100515780637a0ed6271461006f578063adfca15e14610084578063cdffacc6146100a4575b600080fd5b610059610140565b60405161006691906104ab565b60405180910390f35b6100776101d1565b6040516100669190610562565b61009761009236600461060a565b6103d1565b6040516100669190610647565b61011b6100b236600461065a565b7fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610066565b60607f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6002018054806020026020016040519081016040528092919081815260200182805480156101c757602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161019c575b5050505050905090565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f908067ffffffffffffffff8111156102315761023161069c565b60405190808252806020026020018201604052801561027757816020015b60408051808201909152600081526060602082015281526020019060019003908161024f5790505b50925060005b818110156103cb57600083600201828154811061029c5761029c6106cb565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050808583815181106102dc576102dc6106cb565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff928316905290821660009081526001860182526040908190208054825181850281018501909352808352919290919083018282801561039d57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161034a5790505b50505050508583815181106103b4576103b46106cb565b60209081029190910181015101525060010161027d565b50505090565b73ffffffffffffffffffffffffffffffffffffffff811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4920602090815260409182902080548351818402810184019094528084526060939283018282801561049f57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161044c5790505b50505050509050919050565b6020808252825182820181905260009190848201906040850190845b818110156104f957835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016104c7565b50909695505050505050565b600081518084526020808501945080840160005b838110156105575781517fffffffff000000000000000000000000000000000000000000000000000000001687529582019590820190600101610519565b509495945050505050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b838110156105fc578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00185528151805173ffffffffffffffffffffffffffffffffffffffff1684528701518784018790526105e987850182610505565b9588019593505090860190600101610589565b509098975050505050505050565b60006020828403121561061c57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461064057600080fd5b9392505050565b6020815260006106406020830184610505565b60006020828403121561066c57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461064057600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea264697066735822122024a872696a5ad50024326567061c50adea63ff0d49edf0ac60339459d33d571664736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "A default fallback handler for Barz", + "kind": "dev", + "methods": { + "constructor": { + "details": "This contract is also a diamond that holds the default facets to reduce gas cost for wallet activation. Within the constructor this conducts diamond cut to initially setup the diamond. This is a non-upgradeable contract", + "params": { + "_accountFacet": "Address account facet", + "_diamondCutFacet": "Address if diamond cut facet", + "_diamondLoupeFacet": "Address of diamond loupe facet", + "_tokenReceiverFacet": "Address of token receiver facet" + } + }, + "facetAddress(bytes4)": { + "details": "If facet is not found return address(0).", + "params": { + "_functionSelector": "The function selector." + }, + "returns": { + "facetAddress_": "The facet address." + } + }, + "facetAddresses()": { + "returns": { + "facetAddresses_": "facetAddresses_" + } + }, + "facetFunctionSelectors(address)": { + "params": { + "_facet": "The facet address." + }, + "returns": { + "facetFunctionSelectors_": "facetFunctionSelectors_" + } + }, + "facets()": { + "returns": { + "facets_": "The facet struct array including all facet information" + } + } + }, + "title": "DefaultFallbackHandler", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "constructor": { + "notice": "Sets the middleware diamond for Barz wallet as a fallback handler" + }, + "facetAddress(bytes4)": { + "notice": "Gets the facet that supports the given selector." + }, + "facetAddresses()": { + "notice": "Get all the facet addresses used by a diamond." + }, + "facetFunctionSelectors(address)": { + "notice": "Gets all the function selectors provided by a facet." + }, + "facets()": { + "notice": "Returns the facet information of call facets registered to this diamond." + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/opBNB/DiamondCutFacet.json b/deployments/opBNB/DiamondCutFacet.json new file mode 100644 index 0000000..d992bb1 --- /dev/null +++ b/deployments/opBNB/DiamondCutFacet.json @@ -0,0 +1,856 @@ +{ + "address": "0x0B9504140771C3688Ff041917192277D2f52E1e0", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_securityManager", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "CallerNotGuardian", + "type": "error" + }, + { + "inputs": [], + "name": "CallerNotGuardianOrOwner", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__CannotRevokeUnapproved", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__DuplicateApproval", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InsufficientApprovers", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidApprovalValidationPeriod", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidApprover", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidApproverSignature", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidArrayLength", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidInitAddress", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidRouteWithGuardian", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidRouteWithoutGuardian", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__LackOfOwnerApproval", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__OwnerAlreadyApproved", + "type": "error" + }, + { + "inputs": [], + "name": "DuplicateApprover", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_initializationContractAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "InitializationFunctionReverted", + "type": "error" + }, + { + "inputs": [], + "name": "UnregisteredFacetAndSelectors", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroApproverLength", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "indexed": false, + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "DiamondCut", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "diamondCut", + "type": "tuple[]" + } + ], + "name": "DiamondCutApprovalRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "diamondCut", + "type": "tuple[]" + } + ], + "name": "DiamondCutApproved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + }, + { + "indexed": false, + "internalType": "bool", + "name": "_lag", + "type": "bool" + } + ], + "name": "SupportsInterfaceUpdated", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_diamondCutHash", + "type": "bytes32" + }, + { + "internalType": "address[]", + "name": "_approvers", + "type": "address[]" + } + ], + "name": "_checkDuplicateOnChainApprover", + "outputs": [], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + } + ], + "name": "approveDiamondCut", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "diamondCut", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "internalType": "address[]", + "name": "_approvers", + "type": "address[]" + }, + { + "internalType": "bytes[]", + "name": "_signatures", + "type": "bytes[]" + } + ], + "name": "diamondCutWithGuardian", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_diamondCutHash", + "type": "bytes32" + } + ], + "name": "getDiamondCutApprovalCountWithTimeValidity", + "outputs": [ + { + "internalType": "uint256", + "name": "approvalCount", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + } + ], + "name": "getDiamondCutHash", + "outputs": [ + { + "internalType": "bytes32", + "name": "cutHash", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getDiamondCutNonce", + "outputs": [ + { + "internalType": "uint128", + "name": "cutNonce", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_diamondCutHash", + "type": "bytes32" + } + ], + "name": "getOwnerCutApprovalWithTimeValidity", + "outputs": [ + { + "internalType": "bool", + "name": "isApprovedByOwner", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_diamondCutHash", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "_approver", + "type": "address" + } + ], + "name": "isCutApproved", + "outputs": [ + { + "internalType": "bool", + "name": "isApproved", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + } + ], + "name": "revokeDiamondCutApproval", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "securityManager", + "outputs": [ + { + "internalType": "contract ISecurityManager", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_interfaceId", + "type": "bytes4" + }, + { + "internalType": "bool", + "name": "_flag", + "type": "bool" + } + ], + "name": "updateSupportsInterface", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0x3bce0eaa0b53d9dba855fb5a0abb594987bccd697edced57ec5ef99ad0b0560a", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 5, + "gasUsed": "3078987", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x71b2923439d637c92d2cf0f1b07a69c63b136f814468d9942eefa1b22c14663f", + "transactionHash": "0x3bce0eaa0b53d9dba855fb5a0abb594987bccd697edced57ec5ef99ad0b0560a", + "logs": [], + "blockNumber": 8731243, + "cumulativeGasUsed": "3254354", + "status": 1, + "byzantium": true + }, + "args": [ + "0xcBe266adbfd7CB32988128e7f37b7c8b3C5521A8" + ], + "numDeployments": 2, + "solcInputHash": "4356503edd8ae34e73cb6dd1c8e2fc8a", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_securityManager\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"CallerNotGuardian\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallerNotGuardianOrOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__CannotRevokeUnapproved\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__DuplicateApproval\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InsufficientApprovers\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidApprovalValidationPeriod\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidApprover\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidApproverSignature\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidArrayLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidInitAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidRouteWithGuardian\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidRouteWithoutGuardian\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__LackOfOwnerApproval\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__OwnerAlreadyApproved\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateApprover\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_initializationContractAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"InitializationFunctionReverted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnregisteredFacetAndSelectors\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroApproverLength\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"DiamondCut\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"diamondCut\",\"type\":\"tuple[]\"}],\"name\":\"DiamondCutApprovalRevoked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"diamondCut\",\"type\":\"tuple[]\"}],\"name\":\"DiamondCutApproved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"_lag\",\"type\":\"bool\"}],\"name\":\"SupportsInterfaceUpdated\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_diamondCutHash\",\"type\":\"bytes32\"},{\"internalType\":\"address[]\",\"name\":\"_approvers\",\"type\":\"address[]\"}],\"name\":\"_checkDuplicateOnChainApprover\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"}],\"name\":\"approveDiamondCut\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"diamondCut\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"internalType\":\"address[]\",\"name\":\"_approvers\",\"type\":\"address[]\"},{\"internalType\":\"bytes[]\",\"name\":\"_signatures\",\"type\":\"bytes[]\"}],\"name\":\"diamondCutWithGuardian\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_diamondCutHash\",\"type\":\"bytes32\"}],\"name\":\"getDiamondCutApprovalCountWithTimeValidity\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"approvalCount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"}],\"name\":\"getDiamondCutHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"cutHash\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDiamondCutNonce\",\"outputs\":[{\"internalType\":\"uint128\",\"name\":\"cutNonce\",\"type\":\"uint128\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_diamondCutHash\",\"type\":\"bytes32\"}],\"name\":\"getOwnerCutApprovalWithTimeValidity\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isApprovedByOwner\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_diamondCutHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"_approver\",\"type\":\"address\"}],\"name\":\"isCutApproved\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isApproved\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"}],\"name\":\"revokeDiamondCutApproval\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"securityManager\",\"outputs\":[{\"internalType\":\"contract ISecurityManager\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_interfaceId\",\"type\":\"bytes4\"},{\"internalType\":\"bool\",\"name\":\"_flag\",\"type\":\"bool\"}],\"name\":\"updateSupportsInterface\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"Responsible for adding/removing/replace facets in Barz\",\"kind\":\"dev\",\"methods\":{\"_checkDuplicateOnChainApprover(bytes32,address[])\":{\"params\":{\"_approvers\":\"List of approver addresses\",\"_diamondCutHash\":\"Hash of diamondCut information including the facet addresses and function selectors\"}},\"approveDiamondCut((address,uint8,bytes4[])[])\":{\"params\":{\"_diamondCut\":\"Contains the facet addresses and function selectors\"}},\"constructor\":{\"params\":{\"_securityManager\":\"Security Manager contract that holds the security related variables for all wallets\"}},\"diamondCut((address,uint8,bytes4[])[],address,bytes)\":{\"params\":{\"_diamondCut\":\"Contains the facet addresses and function selectors\",\"_init\":\"The address of the contract or facet to execute _calldata. It's prohibited in Barz\"}},\"diamondCutWithGuardian((address,uint8,bytes4[])[],address[],bytes[])\":{\"params\":{\"_approvers\":\"Guardian or owner address that approves the diamond cut\",\"_diamondCut\":\"Contains the facet addresses and function selectors\",\"_signatures\":\"Signature of Guardians or owner that approves the diamond cut\"}},\"getDiamondCutApprovalCountWithTimeValidity(bytes32)\":{\"params\":{\"_diamondCutHash\":\"Hash of diamondCut information including the facet addresses and function selectors\"}},\"getDiamondCutHash((address,uint8,bytes4[])[])\":{\"params\":{\"_diamondCut\":\"Contains the facet addresses and function selectors\"},\"returns\":{\"cutHash\":\"Diamond Cut Hash\"}},\"getDiamondCutNonce()\":{\"details\":\"This method fetches the nonce from diamond cut storage\",\"returns\":{\"cutNonce\":\"Nonce of diamond cut to protect from reply attacks\"}},\"getOwnerCutApprovalWithTimeValidity(bytes32)\":{\"params\":{\"_diamondCutHash\":\"Hash of diamondCut information including the facet addresses and function selectors\"},\"returns\":{\"isApprovedByOwner\":\"Bool value showing if the owner approved the cut\"}},\"isCutApproved(bytes32,address)\":{\"params\":{\"_approver\":\"Address of approver\",\"_diamondCutHash\":\"Hash of diamondCut information including the facet addresses and function selectors\"},\"returns\":{\"isApproved\":\"Bool value showing if the approver approved the cut\"}},\"revokeDiamondCutApproval((address,uint8,bytes4[])[])\":{\"params\":{\"_diamondCut\":\"Contains the facet addresses and function selectors\"}},\"updateSupportsInterface(bytes4,bool)\":{\"params\":{\"_flag\":\"Bool value to update the mapping of the given interface ID\",\"_interfaceId\":\"InterfaceID to update the mapping\"}}},\"title\":\"DiamondCut Facet\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"_checkDuplicateOnChainApprover(bytes32,address[])\":{\"notice\":\"Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval Approvers who approved on-chain should not be included in the off-chain approval\"},\"approveDiamondCut((address,uint8,bytes4[])[])\":{\"notice\":\"Approves diamond cut. This can only be called directly from guardian or owner\"},\"constructor\":{\"notice\":\"This constructor sets the Security Manager address which is an immutable variable. Immutable variables do not impact the storage of diamond\"},\"diamondCut((address,uint8,bytes4[])[],address,bytes)\":{\"notice\":\"Add/replace/remove any number of functions and optionally execute a function with delegatecall when guardians don't exist\"},\"diamondCutWithGuardian((address,uint8,bytes4[])[],address[],bytes[])\":{\"notice\":\"Add/replace/remove any number of functions and optionally execute a function with delegatecall when guardians exist\"},\"getDiamondCutApprovalCountWithTimeValidity(bytes32)\":{\"notice\":\"Gets the number of approvals of diamond cut from guardians\"},\"getDiamondCutHash((address,uint8,bytes4[])[])\":{\"notice\":\"Returns the diamond cut hash. This function ensures that this hash is safe from replay attack by including salt, address, chainId, and nonce, etc.\"},\"getDiamondCutNonce()\":{\"notice\":\"Returns the diamond cut nonce of this wallet\"},\"getOwnerCutApprovalWithTimeValidity(bytes32)\":{\"notice\":\"Returns if the owner has approved the diamond cut\"},\"isCutApproved(bytes32,address)\":{\"notice\":\"Returns if the given approver has approved the diamond cut\"},\"revokeDiamondCutApproval((address,uint8,bytes4[])[])\":{\"notice\":\"Revokes the approval of diamond cut. This can only be called directly from guardian or owner\"},\"updateSupportsInterface(bytes4,bool)\":{\"notice\":\"Updates the flag for the interfaceId\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/base/DiamondCutFacet.sol\":\"DiamondCutFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/interfaces/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC1271 standard signature validation method for\\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC1271 {\\n /**\\n * @dev Should return whether the signature provided is valid for the provided data\\n * @param hash Hash of the data to be signed\\n * @param signature Signature byte array associated with _data\\n */\\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\\n}\\n\",\"keccak256\":\"0x0705a4b1b86d7b0bd8432118f226ba139c44b9dcaba0a6eafba2dd7d0639c544\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./math/Math.sol\\\";\\nimport \\\"./math/SignedMath.sol\\\";\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n uint256 length = Math.log10(value) + 1;\\n string memory buffer = new string(length);\\n uint256 ptr;\\n /// @solidity memory-safe-assembly\\n assembly {\\n ptr := add(buffer, add(32, length))\\n }\\n while (true) {\\n ptr--;\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\\n }\\n value /= 10;\\n if (value == 0) break;\\n }\\n return buffer;\\n }\\n }\\n\\n /**\\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\\n */\\n function toString(int256 value) internal pure returns (string memory) {\\n return string(abi.encodePacked(value < 0 ? \\\"-\\\" : \\\"\\\", toString(SignedMath.abs(value))));\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n return toHexString(value, Math.log256(value) + 1);\\n }\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n\\n /**\\n * @dev Returns true if the two strings are equal.\\n */\\n function equal(string memory a, string memory b) internal pure returns (bool) {\\n return keccak256(bytes(a)) == keccak256(bytes(b));\\n }\\n}\\n\",\"keccak256\":\"0x3088eb2868e8d13d89d16670b5f8612c4ab9ff8956272837d8e90106c59c14a0\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Strings.sol\\\";\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSA {\\n enum RecoverError {\\n NoError,\\n InvalidSignature,\\n InvalidSignatureLength,\\n InvalidSignatureS,\\n InvalidSignatureV // Deprecated in v4.8\\n }\\n\\n function _throwError(RecoverError error) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert(\\\"ECDSA: invalid signature\\\");\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert(\\\"ECDSA: invalid signature length\\\");\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert(\\\"ECDSA: invalid signature 's' value\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature` or error string. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n *\\n * Documentation for signature generation:\\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n return tryRecover(hash, v, r, s);\\n } else {\\n return (address(0), RecoverError.InvalidSignatureLength);\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature`. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, signature);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\\n uint8 v = uint8((uint256(vs) >> 255) + 27);\\n return tryRecover(hash, v, r, s);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n *\\n * _Available since v4.2._\\n */\\n function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\\n // the valid range for s in (301): 0 < s < secp256k1n \\u00f7 2 + 1, and for v in (302): v \\u2208 {27, 28}. Most\\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\\n //\\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\\n // these malleable signatures as well.\\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n return (address(0), RecoverError.InvalidSignatureS);\\n }\\n\\n // If the signature is valid (and not malleable), return the signer address\\n address signer = ecrecover(hash, v, r, s);\\n if (signer == address(0)) {\\n return (address(0), RecoverError.InvalidSignature);\\n }\\n\\n return (signer, RecoverError.NoError);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore(0x00, \\\"\\\\x19Ethereum Signed Message:\\\\n32\\\")\\n mstore(0x1c, hash)\\n message := keccak256(0x00, 0x3c)\\n }\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from `s`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n\\\", Strings.toString(s.length), s));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Typed Data, created from a\\n * `domainSeparator` and a `structHash`. This produces hash corresponding\\n * to the one signed with the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n * JSON-RPC method as part of EIP-712.\\n *\\n * See {recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n let ptr := mload(0x40)\\n mstore(ptr, \\\"\\\\x19\\\\x01\\\")\\n mstore(add(ptr, 0x02), domainSeparator)\\n mstore(add(ptr, 0x22), structHash)\\n data := keccak256(ptr, 0x42)\\n }\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Data with intended validator, created from a\\n * `validator` and `data` according to the version 0 of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x00\\\", validator, data));\\n }\\n}\\n\",\"keccak256\":\"0x809bc3edb4bcbef8263fa616c1b60ee0004b50a8a1bfa164d8f57fd31f520c58\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/SignatureChecker.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./ECDSA.sol\\\";\\nimport \\\"../../interfaces/IERC1271.sol\\\";\\n\\n/**\\n * @dev Signature verification helper that can be used instead of `ECDSA.recover` to seamlessly support both ECDSA\\n * signatures from externally owned accounts (EOAs) as well as ERC1271 signatures from smart contract wallets like\\n * Argent and Gnosis Safe.\\n *\\n * _Available since v4.1._\\n */\\nlibrary SignatureChecker {\\n /**\\n * @dev Checks if a signature is valid for a given signer and data hash. If the signer is a smart contract, the\\n * signature is validated against that smart contract using ERC1271, otherwise it's validated using `ECDSA.recover`.\\n *\\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\\n */\\n function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature) internal view returns (bool) {\\n (address recovered, ECDSA.RecoverError error) = ECDSA.tryRecover(hash, signature);\\n return\\n (error == ECDSA.RecoverError.NoError && recovered == signer) ||\\n isValidERC1271SignatureNow(signer, hash, signature);\\n }\\n\\n /**\\n * @dev Checks if a signature is valid for a given signer and data hash. The signature is validated\\n * against the signer smart contract using ERC1271.\\n *\\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\\n */\\n function isValidERC1271SignatureNow(\\n address signer,\\n bytes32 hash,\\n bytes memory signature\\n ) internal view returns (bool) {\\n (bool success, bytes memory result) = signer.staticcall(\\n abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, signature)\\n );\\n return (success &&\\n result.length >= 32 &&\\n abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector));\\n }\\n}\\n\",\"keccak256\":\"0x3af3ca86df39aac39a0514c84459d691434a108d2151c8ce9d69f32e315cab80\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n enum Rounding {\\n Down, // Toward negative infinity\\n Up, // Toward infinity\\n Zero // Toward zero\\n }\\n\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow.\\n return (a & b) + (a ^ b) / 2;\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a == 0 ? 0 : (a - 1) / b + 1;\\n }\\n\\n /**\\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\\n * with further edits by Uniswap Labs also under MIT license.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\\n unchecked {\\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2^256 + prod0.\\n uint256 prod0; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division.\\n if (prod1 == 0) {\\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\\n // The surrounding unchecked block does not change this fact.\\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\\n return prod0 / denominator;\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n require(denominator > prod1, \\\"Math: mulDiv overflow\\\");\\n\\n ///////////////////////////////////////////////\\n // 512 by 256 division.\\n ///////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0].\\n uint256 remainder;\\n assembly {\\n // Compute remainder using mulmod.\\n remainder := mulmod(x, y, denominator)\\n\\n // Subtract 256 bit number from 512 bit number.\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\\n // See https://cs.stackexchange.com/q/138556/92363.\\n\\n // Does not overflow because the denominator cannot be zero at this stage in the function.\\n uint256 twos = denominator & (~denominator + 1);\\n assembly {\\n // Divide denominator by twos.\\n denominator := div(denominator, twos)\\n\\n // Divide [prod1 prod0] by twos.\\n prod0 := div(prod0, twos)\\n\\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\\n twos := add(div(sub(0, twos), twos), 1)\\n }\\n\\n // Shift in bits from prod1 into prod0.\\n prod0 |= prod1 * twos;\\n\\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\\n // four bits. That is, denominator * inv = 1 mod 2^4.\\n uint256 inverse = (3 * denominator) ^ 2;\\n\\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\\n // in modular arithmetic, doubling the correct bits in each step.\\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\\n\\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inverse;\\n return result;\\n }\\n }\\n\\n /**\\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\\n uint256 result = mulDiv(x, y, denominator);\\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\\n result += 1;\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\\n *\\n * Inspired by Henry S. Warren, Jr.'s \\\"Hacker's Delight\\\" (Chapter 11).\\n */\\n function sqrt(uint256 a) internal pure returns (uint256) {\\n if (a == 0) {\\n return 0;\\n }\\n\\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\\n //\\n // We know that the \\\"msb\\\" (most significant bit) of our target number `a` is a power of 2 such that we have\\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\\n //\\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\\n // \\u2192 `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\\n // \\u2192 `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\\n //\\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\\n uint256 result = 1 << (log2(a) >> 1);\\n\\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\\n // into the expected uint128 result.\\n unchecked {\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n return min(result, a / result);\\n }\\n }\\n\\n /**\\n * @notice Calculates sqrt(a), following the selected rounding direction.\\n */\\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = sqrt(a);\\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 2, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 128;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 64;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 32;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 16;\\n }\\n if (value >> 8 > 0) {\\n value >>= 8;\\n result += 8;\\n }\\n if (value >> 4 > 0) {\\n value >>= 4;\\n result += 4;\\n }\\n if (value >> 2 > 0) {\\n value >>= 2;\\n result += 2;\\n }\\n if (value >> 1 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log2(value);\\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 10, rounded down, of a positive value.\\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 + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 256, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n *\\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\\n */\\n function log256(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 16;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 8;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 4;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 2;\\n }\\n if (value >> 8 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log256(value);\\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe4455ac1eb7fc497bb7402579e7b4d64d928b846fce7d2b6fde06d366f21c2b3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\\n * checks.\\n *\\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\\n * easily result in undesired exploitation or bugs, since developers usually\\n * assume that overflows raise errors. `SafeCast` restores this intuition by\\n * reverting the transaction when such an operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n *\\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\\n * all math on `uint256` and `int256` and then downcasting.\\n */\\nlibrary SafeCast {\\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 * _Available since v4.7._\\n */\\n function toUint248(uint256 value) internal pure returns (uint248) {\\n require(value <= type(uint248).max, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint240(uint256 value) internal pure returns (uint240) {\\n require(value <= type(uint240).max, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint232(uint256 value) internal pure returns (uint232) {\\n require(value <= type(uint232).max, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint224(uint256 value) internal pure returns (uint224) {\\n require(value <= type(uint224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint216(uint256 value) internal pure returns (uint216) {\\n require(value <= type(uint216).max, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint208(uint256 value) internal pure returns (uint208) {\\n require(value <= type(uint208).max, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint200(uint256 value) internal pure returns (uint200) {\\n require(value <= type(uint200).max, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint192(uint256 value) internal pure returns (uint192) {\\n require(value <= type(uint192).max, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint184(uint256 value) internal pure returns (uint184) {\\n require(value <= type(uint184).max, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint176(uint256 value) internal pure returns (uint176) {\\n require(value <= type(uint176).max, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint168(uint256 value) internal pure returns (uint168) {\\n require(value <= type(uint168).max, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint160(uint256 value) internal pure returns (uint160) {\\n require(value <= type(uint160).max, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint152(uint256 value) internal pure returns (uint152) {\\n require(value <= type(uint152).max, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint144(uint256 value) internal pure returns (uint144) {\\n require(value <= type(uint144).max, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint136(uint256 value) internal pure returns (uint136) {\\n require(value <= type(uint136).max, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint128(uint256 value) internal pure returns (uint128) {\\n require(value <= type(uint128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint120(uint256 value) internal pure returns (uint120) {\\n require(value <= type(uint120).max, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint112(uint256 value) internal pure returns (uint112) {\\n require(value <= type(uint112).max, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint104(uint256 value) internal pure returns (uint104) {\\n require(value <= type(uint104).max, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint96(uint256 value) internal pure returns (uint96) {\\n require(value <= type(uint96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint88(uint256 value) internal pure returns (uint88) {\\n require(value <= type(uint88).max, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint80(uint256 value) internal pure returns (uint80) {\\n require(value <= type(uint80).max, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint72(uint256 value) internal pure returns (uint72) {\\n require(value <= type(uint72).max, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint64(uint256 value) internal pure returns (uint64) {\\n require(value <= type(uint64).max, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint56(uint256 value) internal pure returns (uint56) {\\n require(value <= type(uint56).max, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint48(uint256 value) internal pure returns (uint48) {\\n require(value <= type(uint48).max, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint40(uint256 value) internal pure returns (uint40) {\\n require(value <= type(uint40).max, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint32(uint256 value) internal pure returns (uint32) {\\n require(value <= type(uint32).max, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint24(uint256 value) internal pure returns (uint24) {\\n require(value <= type(uint24).max, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint16(uint256 value) internal pure returns (uint16) {\\n require(value <= type(uint16).max, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint8(uint256 value) internal pure returns (uint8) {\\n require(value <= type(uint8).max, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\n */\\n function toUint256(int256 value) internal pure returns (uint256) {\\n require(value >= 0, \\\"SafeCast: value must be positive\\\");\\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 * _Available since v4.7._\\n */\\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\\n downcasted = int248(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\\n downcasted = int240(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\\n downcasted = int232(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\\n downcasted = int224(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\\n downcasted = int216(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\\n downcasted = int208(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\\n downcasted = int200(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\\n downcasted = int192(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\\n downcasted = int184(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\\n downcasted = int176(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\\n downcasted = int168(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\\n downcasted = int160(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\\n downcasted = int152(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\\n downcasted = int144(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\\n downcasted = int136(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\\n downcasted = int128(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\\n downcasted = int120(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\\n downcasted = int112(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\\n downcasted = int104(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\\n downcasted = int96(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\\n downcasted = int88(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\\n downcasted = int80(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\\n downcasted = int72(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\\n downcasted = int64(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\\n downcasted = int56(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\\n downcasted = int48(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\\n downcasted = int40(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\\n downcasted = int32(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\\n downcasted = int24(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\\n downcasted = int16(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\\n downcasted = int8(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\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 require(value <= uint256(type(int256).max), \\\"SafeCast: value doesn't fit in an int256\\\");\\n return int256(value);\\n }\\n}\\n\",\"keccak256\":\"0x52a8cfb0f5239d11b457dcdd1b326992ef672714ca8da71a157255bddd13f3ad\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SignedMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard signed math utilities missing in the Solidity language.\\n */\\nlibrary SignedMath {\\n /**\\n * @dev Returns the largest of two signed numbers.\\n */\\n function max(int256 a, int256 b) internal pure returns (int256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two signed numbers.\\n */\\n function min(int256 a, int256 b) internal pure returns (int256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two signed numbers without overflow.\\n * The result is rounded towards zero.\\n */\\n function average(int256 a, int256 b) internal pure returns (int256) {\\n // Formula from the book \\\"Hacker's Delight\\\"\\n int256 x = (a & b) + ((a ^ b) >> 1);\\n return x + (int256(uint256(x) >> 255) & (a ^ b));\\n }\\n\\n /**\\n * @dev Returns the absolute unsigned value of a signed value.\\n */\\n function abs(int256 n) internal pure returns (uint256) {\\n unchecked {\\n // must be unchecked in order to support `n = type(int256).min`\\n return uint256(n >= 0 ? n : -n);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf92515413956f529d95977adc9b0567d583c6203fc31ab1c23824c35187e3ddc\",\"license\":\"MIT\"},\"contracts/aa-4337/core/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable no-inline-assembly */\\n\\n/**\\n * returned data from validateUserOp.\\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\\n * @param aggregator - address(0) - the account validated the signature by itself.\\n * address(1) - the account failed to validate the signature.\\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\\n * @param validAfter - this UserOp is valid only after this timestamp.\\n * @param validaUntil - this UserOp is valid only up to this timestamp.\\n */\\nstruct ValidationData {\\n address aggregator;\\n uint48 validAfter;\\n uint48 validUntil;\\n}\\n\\n//extract sigFailed, validAfter, validUntil.\\n// also convert zero validUntil to type(uint48).max\\nfunction _parseValidationData(\\n uint validationData\\n) pure returns (ValidationData memory data) {\\n address aggregator = address(uint160(validationData));\\n uint48 validUntil = uint48(validationData >> 160);\\n if (validUntil == 0) {\\n validUntil = type(uint48).max;\\n }\\n uint48 validAfter = uint48(validationData >> (48 + 160));\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n// intersect account and paymaster ranges.\\nfunction _intersectTimeRange(\\n uint256 validationData,\\n uint256 paymasterValidationData\\n) pure returns (ValidationData memory) {\\n ValidationData memory accountValidationData = _parseValidationData(\\n validationData\\n );\\n ValidationData memory pmValidationData = _parseValidationData(\\n paymasterValidationData\\n );\\n address aggregator = accountValidationData.aggregator;\\n if (aggregator == address(0)) {\\n aggregator = pmValidationData.aggregator;\\n }\\n uint48 validAfter = accountValidationData.validAfter;\\n uint48 validUntil = accountValidationData.validUntil;\\n uint48 pmValidAfter = pmValidationData.validAfter;\\n uint48 pmValidUntil = pmValidationData.validUntil;\\n\\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp\\n * @param data - the ValidationData to pack\\n */\\nfunction _packValidationData(\\n ValidationData memory data\\n) pure returns (uint256) {\\n return\\n uint160(data.aggregator) |\\n (uint256(data.validUntil) << 160) |\\n (uint256(data.validAfter) << (160 + 48));\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp, when not using an aggregator\\n * @param sigFailed - true for signature failure, false for success\\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\\n * @param validAfter first timestamp this UserOperation is valid\\n */\\nfunction _packValidationData(\\n bool sigFailed,\\n uint48 validUntil,\\n uint48 validAfter\\n) pure returns (uint256) {\\n return\\n (sigFailed ? 1 : 0) |\\n (uint256(validUntil) << 160) |\\n (uint256(validAfter) << (160 + 48));\\n}\\n\\n/**\\n * keccak function over calldata.\\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\\n */\\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\\n assembly {\\n let mem := mload(0x40)\\n let len := data.length\\n calldatacopy(mem, data.offset, len)\\n ret := keccak256(mem, len)\\n }\\n}\\n\",\"keccak256\":\"0xa79f06cd158ecb8c0da95493a2f348933b8627a63e228b99738bff3aa107942d\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAggregator.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\n/**\\n * Aggregated Signatures validator.\\n */\\ninterface IAggregator {\\n /**\\n * validate aggregated signature.\\n * revert if the aggregated signature does not match the given list of operations.\\n */\\n function validateSignatures(\\n UserOperation[] calldata userOps,\\n bytes calldata signature\\n ) external view;\\n\\n /**\\n * validate signature of a single userOp\\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\\n * @param userOp the userOperation received from the user.\\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\\n * (usually empty, unless account and aggregator support some kind of \\\"multisig\\\"\\n */\\n function validateUserOpSignature(\\n UserOperation calldata userOp\\n ) external view returns (bytes memory sigForUserOp);\\n\\n /**\\n * aggregate multiple signatures into a single value.\\n * This method is called off-chain to calculate the signature to pass with handleOps()\\n * bundler MAY use optimized custom code perform this aggregation\\n * @param userOps array of UserOperations to collect the signatures from.\\n * @return aggregatedSignature the aggregated signature\\n */\\n function aggregateSignatures(\\n UserOperation[] calldata userOps\\n ) external view returns (bytes memory aggregatedSignature);\\n}\\n\",\"keccak256\":\"0xdfdcd80568f037716674619b31be630fcd8316262f05a815b41d1e81782c966a\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IEntryPoint.sol\":{\"content\":\"/**\\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\\n ** Only one instance required on each chain.\\n **/\\n// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-inline-assembly */\\n/* solhint-disable reason-string */\\n\\nimport \\\"./UserOperation.sol\\\";\\nimport \\\"./IStakeManager.sol\\\";\\nimport \\\"./IAggregator.sol\\\";\\nimport \\\"./INonceManager.sol\\\";\\n\\ninterface IEntryPoint is IStakeManager, INonceManager {\\n /***\\n * An event emitted after each successful request\\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\\n * @param sender - the account that generates this request.\\n * @param paymaster - if non-null, the paymaster that pays for this request.\\n * @param nonce - the nonce value from the request.\\n * @param success - true if the sender transaction succeeded, false if reverted.\\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\\n */\\n event UserOperationEvent(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address indexed paymaster,\\n uint256 nonce,\\n bool success,\\n uint256 actualGasCost,\\n uint256 actualGasUsed\\n );\\n\\n /**\\n * account \\\"sender\\\" was deployed.\\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\\n * @param sender the account that is deployed\\n * @param factory the factory used to deploy this account (in the initCode)\\n * @param paymaster the paymaster used by this UserOp\\n */\\n event AccountDeployed(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address factory,\\n address paymaster\\n );\\n\\n /**\\n * An event emitted if the UserOperation \\\"callData\\\" reverted with non-zero length\\n * @param userOpHash the request unique identifier.\\n * @param sender the sender of this request\\n * @param nonce the nonce used in the request\\n * @param revertReason - the return bytes from the (reverted) call to \\\"callData\\\".\\n */\\n event UserOperationRevertReason(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n uint256 nonce,\\n bytes revertReason\\n );\\n\\n /**\\n * an event emitted by handleOps(), before starting the execution loop.\\n * any event emitted before this event, is part of the validation.\\n */\\n event BeforeExecution();\\n\\n /**\\n * signature aggregator used by the following UserOperationEvents within this bundle.\\n */\\n event SignatureAggregatorChanged(address indexed aggregator);\\n\\n /**\\n * a custom revert error of handleOps, to identify the offending op.\\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\\n * @param reason - revert reason\\n * The string starts with a unique code \\\"AAmn\\\", where \\\"m\\\" is \\\"1\\\" for factory, \\\"2\\\" for account and \\\"3\\\" for paymaster issues,\\n * so a failure can be attributed to the correct entity.\\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\\n */\\n error FailedOp(uint256 opIndex, string reason);\\n\\n /**\\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\\n */\\n error SignatureValidationFailed(address aggregator);\\n\\n /**\\n * Successful result from simulateValidation.\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n */\\n error ValidationResult(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo\\n );\\n\\n /**\\n * Successful result from simulateValidation, if the account returns a signature aggregator\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\\n * bundler MUST use it to verify the signature, or reject the UserOperation\\n */\\n error ValidationResultWithAggregation(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo,\\n AggregatorStakeInfo aggregatorInfo\\n );\\n\\n /**\\n * return value of getSenderAddress\\n */\\n error SenderAddressResult(address sender);\\n\\n /**\\n * return value of simulateHandleOp\\n */\\n error ExecutionResult(\\n uint256 preOpGas,\\n uint256 paid,\\n uint48 validAfter,\\n uint48 validUntil,\\n bool targetSuccess,\\n bytes targetResult\\n );\\n\\n //UserOps handled, per aggregator\\n struct UserOpsPerAggregator {\\n UserOperation[] userOps;\\n // aggregator address\\n IAggregator aggregator;\\n // aggregated signature\\n bytes signature;\\n }\\n\\n /**\\n * Execute a batch of UserOperation.\\n * no signature aggregator is used.\\n * if any account requires an aggregator (that is, it returned an aggregator when\\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\\n * @param ops the operations to execute\\n * @param beneficiary the address to receive the fees\\n */\\n function handleOps(\\n UserOperation[] calldata ops,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * Execute a batch of UserOperation with Aggregators\\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\\n * @param beneficiary the address to receive the fees\\n */\\n function handleAggregatedOps(\\n UserOpsPerAggregator[] calldata opsPerAggregator,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * generate a request Id - unique identifier for this request.\\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\\n */\\n function getUserOpHash(\\n UserOperation calldata userOp\\n ) external view returns (bytes32);\\n\\n /**\\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\\n * @param userOp the user operation to validate.\\n */\\n function simulateValidation(UserOperation calldata userOp) external;\\n\\n /**\\n * gas and return values during simulation\\n * @param preOpGas the gas used for validation (including preValidationGas)\\n * @param prefund the required prefund for this operation\\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\\n */\\n struct ReturnInfo {\\n uint256 preOpGas;\\n uint256 prefund;\\n bool sigFailed;\\n uint48 validAfter;\\n uint48 validUntil;\\n bytes paymasterContext;\\n }\\n\\n /**\\n * returned aggregated signature info.\\n * the aggregator returned by the account, and its current stake.\\n */\\n struct AggregatorStakeInfo {\\n address aggregator;\\n StakeInfo stakeInfo;\\n }\\n\\n /**\\n * Get counterfactual sender address.\\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\\n * this method always revert, and returns the address in SenderAddressResult error\\n * @param initCode the constructor code to be passed into the UserOperation.\\n */\\n function getSenderAddress(bytes memory initCode) external;\\n\\n /**\\n * simulate full execution of a UserOperation (including both validation and target execution)\\n * this method will always revert with \\\"ExecutionResult\\\".\\n * it performs full validation of the UserOperation, but ignores signature error.\\n * an optional target address is called after the userop succeeds, and its value is returned\\n * (before the entire call is reverted)\\n * Note that in order to collect the the success/failure of the target call, it must be executed\\n * with trace enabled to track the emitted events.\\n * @param op the UserOperation to simulate\\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\\n * are set to the return from that call.\\n * @param targetCallData callData to pass to target address\\n */\\n function simulateHandleOp(\\n UserOperation calldata op,\\n address target,\\n bytes calldata targetCallData\\n ) external;\\n}\\n\",\"keccak256\":\"0x9ccb1b188eda8bbf5f6c2d01bd83c3d8b2b04fcf745283051d31fe96d1d8e40f\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/INonceManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\ninterface INonceManager {\\n /**\\n * Return the next nonce for this sender.\\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\\n * But UserOp with different keys can come with arbitrary order.\\n *\\n * @param sender the account address\\n * @param key the high 192 bit of the nonce\\n * @return nonce a full nonce to pass for next UserOp with this sender.\\n */\\n function getNonce(\\n address sender,\\n uint192 key\\n ) external view returns (uint256 nonce);\\n\\n /**\\n * Manually increment the nonce of the sender.\\n * This method is exposed just for completeness..\\n * Account does NOT need to call it, neither during validation, nor elsewhere,\\n * as the EntryPoint will update the nonce regardless.\\n * Possible use-case is call it with various keys to \\\"initialize\\\" their nonces to one, so that future\\n * UserOperations will not pay extra for the first transaction with a given key.\\n */\\n function incrementNonce(uint192 key) external;\\n}\\n\",\"keccak256\":\"0xce478ad0fa0d18a3b785ac854623029e7ab463d05873dfaa365abfa1bf100912\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IStakeManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8.12;\\n\\n/**\\n * manage deposits and stakes.\\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\\n * stake is value locked for at least \\\"unstakeDelay\\\" by the staked entity.\\n */\\ninterface IStakeManager {\\n event Deposited(address indexed account, uint256 totalDeposit);\\n\\n event Withdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /// Emitted when stake or unstake delay are modified\\n event StakeLocked(\\n address indexed account,\\n uint256 totalStaked,\\n uint256 unstakeDelaySec\\n );\\n\\n /// Emitted once a stake is scheduled for withdrawal\\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\\n\\n event StakeWithdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /**\\n * @param deposit the entity's deposit\\n * @param staked true if this entity is staked.\\n * @param stake actual amount of ether staked for this entity.\\n * @param unstakeDelaySec minimum delay to withdraw the stake.\\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\\n * and the rest fit into a 2nd cell.\\n * 112 bit allows for 10^15 eth\\n * 48 bit for full timestamp\\n * 32 bit allows 150 years for unstake delay\\n */\\n struct DepositInfo {\\n uint112 deposit;\\n bool staked;\\n uint112 stake;\\n uint32 unstakeDelaySec;\\n uint48 withdrawTime;\\n }\\n\\n //API struct used by getStakeInfo and simulateValidation\\n struct StakeInfo {\\n uint256 stake;\\n uint256 unstakeDelaySec;\\n }\\n\\n /// @return info - full deposit information of given account\\n function getDepositInfo(\\n address account\\n ) external view returns (DepositInfo memory info);\\n\\n /// @return the deposit (for gas payment) of the account\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * add to the deposit of the given account\\n */\\n function depositTo(address account) external payable;\\n\\n /**\\n * add to the account's stake - amount and delay\\n * any pending unstake is first cancelled.\\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\\n */\\n function addStake(uint32 _unstakeDelaySec) external payable;\\n\\n /**\\n * attempt to unlock the stake.\\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\\n */\\n function unlockStake() external;\\n\\n /**\\n * withdraw from the (unlocked) stake.\\n * must first call unlockStake and wait for the unstakeDelay to pass\\n * @param withdrawAddress the address to send withdrawn value.\\n */\\n function withdrawStake(address payable withdrawAddress) external;\\n\\n /**\\n * withdraw from the deposit.\\n * @param withdrawAddress the address to send withdrawn value.\\n * @param withdrawAmount the amount to withdraw.\\n */\\n function withdrawTo(\\n address payable withdrawAddress,\\n uint256 withdrawAmount\\n ) external;\\n}\\n\",\"keccak256\":\"0xadcea606c9b7aafe6645441f2154a60f271330b0eee5292a632aa71c1672d546\",\"license\":\"GPL-3.0-only\"},\"contracts/aa-4337/interfaces/UserOperation.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable no-inline-assembly */\\n\\nimport {calldataKeccak} from \\\"../core/Helpers.sol\\\";\\n\\n/**\\n * User Operation struct\\n * @param sender the sender account of this request.\\n * @param nonce unique value the sender uses to verify it is not a replay.\\n * @param initCode if set, the account contract will be created by this constructor/\\n * @param callData the method call to execute on this account.\\n * @param callGasLimit the gas limit passed to the callData method call.\\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\\n * @param maxFeePerGas same as EIP-1559 gas parameter.\\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\\n */\\nstruct UserOperation {\\n address sender;\\n uint256 nonce;\\n bytes initCode;\\n bytes callData;\\n uint256 callGasLimit;\\n uint256 verificationGasLimit;\\n uint256 preVerificationGas;\\n uint256 maxFeePerGas;\\n uint256 maxPriorityFeePerGas;\\n bytes paymasterAndData;\\n bytes signature;\\n}\\n\\n/**\\n * Utility functions helpful when working with UserOperation structs.\\n */\\nlibrary UserOperationLib {\\n function getSender(\\n UserOperation calldata userOp\\n ) internal pure returns (address) {\\n address data;\\n //read sender from userOp, which is first userOp member (saves 800 gas...)\\n assembly {\\n data := calldataload(userOp)\\n }\\n return address(uint160(data));\\n }\\n\\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\\n // pay above what he signed for.\\n function gasPrice(\\n UserOperation calldata userOp\\n ) internal view returns (uint256) {\\n unchecked {\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n if (maxFeePerGas == maxPriorityFeePerGas) {\\n //legacy mode (for networks that don't support basefee opcode)\\n return maxFeePerGas;\\n }\\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\\n }\\n }\\n\\n function pack(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes memory ret) {\\n address sender = getSender(userOp);\\n uint256 nonce = userOp.nonce;\\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\\n bytes32 hashCallData = calldataKeccak(userOp.callData);\\n uint256 callGasLimit = userOp.callGasLimit;\\n uint256 verificationGasLimit = userOp.verificationGasLimit;\\n uint256 preVerificationGas = userOp.preVerificationGas;\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\\n\\n return\\n abi.encode(\\n sender,\\n nonce,\\n hashInitCode,\\n hashCallData,\\n callGasLimit,\\n verificationGasLimit,\\n preVerificationGas,\\n maxFeePerGas,\\n maxPriorityFeePerGas,\\n hashPaymasterAndData\\n );\\n }\\n\\n function hash(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes32) {\\n return keccak256(pack(userOp));\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n}\\n\",\"keccak256\":\"0x2429f5cc546bdee08c7e63858d0dda8491eaa3ab5194df884dc948c1154d2834\",\"license\":\"GPL-3.0\"},\"contracts/facets/Modifiers.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {LibGuardian} from \\\"../libraries/LibGuardian.sol\\\";\\nimport {BarzStorage} from \\\"../libraries/LibAppStorage.sol\\\";\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\n\\n/**\\n * @title Modifiers\\n * @dev Responsible for providing modifiers/util functions to Facet contracts\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\nabstract contract Modifiers is BarzStorage {\\n uint8 constant INNER_STRUCT = 0;\\n\\n error CallerNotGuardian();\\n error CallerNotGuardianOrOwner();\\n error DuplicateApprover();\\n error ZeroApproverLength();\\n error UnregisteredFacetAndSelectors();\\n\\n /**\\n * @notice Modifier to only allow guardian to make a call, reverts if any other entity is the caller\\n */\\n modifier onlyGuardian() {\\n if (!LibGuardian.isGuardian(msg.sender)) revert CallerNotGuardian();\\n _;\\n }\\n\\n /**\\n * @notice Modifier to only allow guardian or owner to make a call, reverts if any other entity is the caller\\n */\\n modifier onlyGuardianOrOwner() {\\n if (!LibGuardian.isGuardian(msg.sender) && address(this) != msg.sender)\\n revert CallerNotGuardianOrOwner();\\n _;\\n }\\n\\n /**\\n * @notice Checks if the approver address is the array is unique with no duplicate\\n * @dev This method loops through the array and checks if a duplicate address exists, it reverts if duplicate address exists\\n * @param approvers Array of address\\n */\\n function _checkApprover(\\n address[] memory approvers\\n ) internal pure returns (bool) {\\n uint256 approverLength = approvers.length;\\n if (0 == approverLength) revert ZeroApproverLength();\\n for (uint256 i; i < approverLength - 1; ) {\\n for (uint256 j = i + 1; j < approverLength; ) {\\n if (approvers[i] == approvers[j]) {\\n revert DuplicateApprover(); // Found a duplicate\\n }\\n unchecked {\\n ++j;\\n }\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n return false; // No duplicates found\\n }\\n\\n /**\\n * @notice Checks if the facet getting added or replaced is registered to facet registry\\n * @dev This method loops through the cut and checks if the facet getting added/replaced is registered to facet registry\\n * @param _diamondCut Array of FacetCut, data for diamondCut defined in EIP-2535\\n */\\n function _checkFacetCutValidity(\\n IDiamondCut.FacetCut[] memory _diamondCut\\n ) internal view {\\n uint256 diamondCutLength = _diamondCut.length;\\n for (uint256 i; i < diamondCutLength; ) {\\n if (\\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Add ||\\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Replace\\n ) {\\n if (\\n !s.facetRegistry.areFacetFunctionSelectorsRegistered(\\n _diamondCut[i].facetAddress,\\n _diamondCut[i].functionSelectors\\n )\\n ) revert UnregisteredFacetAndSelectors();\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb42956323d199bdec243a5f9859439aae057fbfdd1d79e3a96afc857ecb3115f\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/DiamondCutFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {LibDiamond} from \\\"../../libraries/LibDiamond.sol\\\";\\nimport {LibGuardian} from \\\"../../libraries/LibGuardian.sol\\\";\\nimport {ISecurityManager} from \\\"../../infrastructure/interfaces/ISecurityManager.sol\\\";\\nimport {SignatureChecker} from \\\"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\\\";\\nimport {LibFacetStorage, DiamondCutApprovalConfig, ApprovalConfig} from \\\"../../libraries/LibFacetStorage.sol\\\";\\nimport {Modifiers} from \\\"../Modifiers.sol\\\";\\nimport {IDiamondCut} from \\\"./interfaces/IDiamondCut.sol\\\";\\n\\n/**\\n * @title DiamondCut Facet\\n * @dev Responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract DiamondCutFacet is Modifiers, IDiamondCut {\\n ISecurityManager public immutable securityManager;\\n\\n /**\\n * @notice This constructor sets the Security Manager address which is an immutable variable.\\n * Immutable variables do not impact the storage of diamond\\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\\n */\\n constructor(address _securityManager) {\\n securityManager = ISecurityManager(_securityManager);\\n }\\n\\n /**\\n * @notice Updates the flag for the interfaceId\\n * @param _interfaceId InterfaceID to update the mapping\\n * @param _flag Bool value to update the mapping of the given interface ID\\n */\\n function updateSupportsInterface(\\n bytes4 _interfaceId,\\n bool _flag\\n ) external override onlyWhenUnlocked {\\n LibDiamond.enforceIsSelf();\\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId] = _flag;\\n emit SupportsInterfaceUpdated(_interfaceId, _flag);\\n }\\n\\n /**\\n * @notice Add/replace/remove any number of functions and optionally execute\\n * a function with delegatecall when guardians don't exist\\n * @param _diamondCut Contains the facet addresses and function selectors\\n * @param _init The address of the contract or facet to execute _calldata. It's prohibited in Barz\\n */\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata\\n ) external override onlyWhenUnlocked {\\n LibDiamond.enforceIsSelf();\\n\\n _checkFacetCutValidity(_diamondCut);\\n // require approval from guardian if guardian exists\\n if (0 != LibGuardian.guardianCount())\\n revert DiamondCutFacet__InvalidRouteWithGuardian();\\n if (address(0) != _init) revert DiamondCutFacet__InvalidInitAddress();\\n\\n unchecked {\\n ++LibFacetStorage.diamondCutStorage().nonce;\\n }\\n LibDiamond.diamondCut(_diamondCut, address(0), \\\"\\\");\\n }\\n\\n /**\\n * @notice Add/replace/remove any number of functions and optionally execute\\n * a function with delegatecall when guardians exist\\n * @param _diamondCut Contains the facet addresses and function selectors\\n * @param _approvers Guardian or owner address that approves the diamond cut\\n * @param _signatures Signature of Guardians or owner that approves the diamond cut\\n */\\n function diamondCutWithGuardian(\\n FacetCut[] calldata _diamondCut,\\n address[] calldata _approvers,\\n bytes[] calldata _signatures\\n ) external override onlyWhenUnlocked {\\n if (_approvers.length != _signatures.length)\\n revert DiamondCutFacet__InvalidArrayLength();\\n _checkFacetCutValidity(_diamondCut);\\n if (0 == LibGuardian.guardianCount())\\n revert DiamondCutFacet__InvalidRouteWithGuardian();\\n\\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\\n\\n _checkApprover(_approvers);\\n _checkDuplicateOnChainApprover(cutHash, _approvers);\\n\\n bool onChainOwnerApproval = getOwnerCutApprovalWithTimeValidity(\\n cutHash\\n );\\n\\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\\n if (\\n _approvers.length +\\n getDiamondCutApprovalCountWithTimeValidity(cutHash) <\\n LibGuardian.majorityOfGuardians() + threshold\\n ) revert DiamondCutFacet__InsufficientApprovers();\\n\\n bool ownerApproved;\\n for (uint256 i; i < _approvers.length; ) {\\n if (\\n !LibGuardian.isGuardian(_approvers[i]) &&\\n _approvers[i] != address(this)\\n ) revert DiamondCutFacet__InvalidApprover();\\n if (_approvers[i] == address(this)) {\\n if (onChainOwnerApproval)\\n revert DiamondCutFacet__OwnerAlreadyApproved();\\n ownerApproved = true;\\n }\\n if (\\n !SignatureChecker.isValidSignatureNow(\\n _approvers[i],\\n cutHash,\\n _signatures[i]\\n )\\n ) revert DiamondCutFacet__InvalidApproverSignature();\\n unchecked {\\n ++i;\\n }\\n }\\n if (!ownerApproved && !onChainOwnerApproval)\\n revert DiamondCutFacet__LackOfOwnerApproval();\\n\\n unchecked {\\n ++LibFacetStorage.diamondCutStorage().nonce;\\n }\\n LibDiamond.diamondCut(_diamondCut, address(0), \\\"\\\");\\n }\\n\\n /**\\n * @notice Approves diamond cut. This can only be called directly from guardian or owner\\n * @param _diamondCut Contains the facet addresses and function selectors\\n */\\n function approveDiamondCut(\\n FacetCut[] calldata _diamondCut\\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\\n if (LibGuardian.guardianCount() == 0)\\n revert DiamondCutFacet__InvalidRouteWithoutGuardian();\\n DiamondCutApprovalConfig storage ds = LibFacetStorage\\n .diamondCutStorage()\\n .diamondCutApprovalConfigs[INNER_STRUCT];\\n _checkFacetCutValidity(_diamondCut);\\n\\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\\n uint64 approvalValidUntil = uint64(\\n block.timestamp + getApprovalValidationPeriod()\\n );\\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(\\n true,\\n approvalValidUntil\\n );\\n emit DiamondCutApproved(_diamondCut);\\n if (\\n (getDiamondCutApprovalCountWithTimeValidity(cutHash) >=\\n LibGuardian.majorityOfGuardians()) &&\\n getOwnerCutApprovalWithTimeValidity(cutHash)\\n ) {\\n unchecked {\\n ++LibFacetStorage.diamondCutStorage().nonce;\\n }\\n LibDiamond.diamondCut(_diamondCut, address(0), \\\"\\\");\\n }\\n }\\n\\n /**\\n * @notice Revokes the approval of diamond cut. This can only be called directly from guardian or owner\\n * @param _diamondCut Contains the facet addresses and function selectors\\n */\\n function revokeDiamondCutApproval(\\n FacetCut[] calldata _diamondCut\\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\\n DiamondCutApprovalConfig storage ds = LibFacetStorage\\n .diamondCutStorage()\\n .diamondCutApprovalConfigs[INNER_STRUCT];\\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\\n if (!ds.isDiamondCutApproved[cutHash][msg.sender].isApproved)\\n revert DiamondCutFacet__CannotRevokeUnapproved();\\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(false, 0);\\n emit DiamondCutApprovalRevoked(_diamondCut);\\n }\\n\\n /**\\n * @notice Gets the number of approvals of diamond cut from guardians\\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\\n */\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 _diamondCutHash\\n ) public view override returns (uint256 approvalCount) {\\n address[] memory guardians = LibGuardian.getGuardians();\\n uint256 guardiansLength = guardians.length;\\n for (uint256 i; i < guardiansLength; ) {\\n if (isCutApproved(_diamondCutHash, guardians[i])) {\\n unchecked {\\n ++approvalCount;\\n }\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n return approvalCount;\\n }\\n\\n /**\\n * @notice Returns if the owner has approved the diamond cut\\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\\n * @return isApprovedByOwner Bool value showing if the owner approved the cut\\n */\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 _diamondCutHash\\n ) public view override returns (bool isApprovedByOwner) {\\n isApprovedByOwner = isCutApproved(_diamondCutHash, address(this));\\n }\\n\\n /**\\n * @notice Returns if the given approver has approved the diamond cut\\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\\n * @param _approver Address of approver\\n * @return isApproved Bool value showing if the approver approved the cut\\n */\\n function isCutApproved(\\n bytes32 _diamondCutHash,\\n address _approver\\n ) public view override returns (bool isApproved) {\\n DiamondCutApprovalConfig storage ds = LibFacetStorage\\n .diamondCutStorage()\\n .diamondCutApprovalConfigs[INNER_STRUCT];\\n isApproved = (ds\\n .isDiamondCutApproved[_diamondCutHash][_approver].isApproved &&\\n block.timestamp <\\n ds.isDiamondCutApproved[_diamondCutHash][_approver].validUntil);\\n }\\n\\n /**\\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\\n * Approvers who approved on-chain should not be included in the off-chain approval\\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\\n * @param _approvers List of approver addresses\\n */\\n function _checkDuplicateOnChainApprover(\\n bytes32 _diamondCutHash,\\n address[] memory _approvers\\n ) public view {\\n address[] memory guardians = LibGuardian.getGuardians();\\n uint256 guardianLength = guardians.length;\\n uint256 approversLength = _approvers.length;\\n for (uint256 i; i < guardianLength; ) {\\n if (isCutApproved(_diamondCutHash, guardians[i])) {\\n for (uint256 j; j < approversLength; ) {\\n if (_approvers[j] == guardians[i])\\n revert DiamondCutFacet__DuplicateApproval();\\n unchecked {\\n ++j;\\n }\\n }\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * @notice Returns the diamond cut hash. This function ensures that this hash is safe from replay attack by including\\n * salt, address, chainId, and nonce, etc.\\n * @param _diamondCut Contains the facet addresses and function selectors\\n * @return cutHash Diamond Cut Hash\\n */\\n function getDiamondCutHash(\\n FacetCut[] calldata _diamondCut\\n ) public view override returns (bytes32 cutHash) {\\n cutHash = keccak256(\\n abi.encodePacked(\\n \\\"\\\\x19Ethereum Signed Message:\\\\n32\\\",\\n keccak256(\\n abi.encode(\\n keccak256(abi.encode(_diamondCut)),\\n address(this),\\n block.chainid,\\n LibFacetStorage.diamondCutStorage().nonce\\n )\\n )\\n )\\n );\\n }\\n\\n /**\\n * @notice Returns the approval validation Period\\n * @dev This method fetches the validation period from the security manager\\n * @return approvalValidationPeriod Approval validation period of Barz contract fetched from security manager\\n */\\n function getApprovalValidationPeriod()\\n internal\\n view\\n returns (uint256 approvalValidationPeriod)\\n {\\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\\n address(this)\\n );\\n if (approvalValidationPeriod <= 0)\\n revert DiamondCutFacet__InvalidApprovalValidationPeriod();\\n }\\n\\n /**\\n * @notice Returns the diamond cut nonce of this wallet\\n * @dev This method fetches the nonce from diamond cut storage\\n * @return cutNonce Nonce of diamond cut to protect from reply attacks\\n */\\n function getDiamondCutNonce()\\n public\\n view\\n override\\n returns (uint128 cutNonce)\\n {\\n cutNonce = LibFacetStorage.diamondCutStorage().nonce;\\n }\\n}\\n\",\"keccak256\":\"0xe91a7dd2daabf2e989c94089f4f1eb0da94276c3070559ac8988838e10dd1f5d\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/infrastructure/interfaces/IFacetRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Registry Interface\\n * @dev Interface for Facet Registry contract to keep track of facets & function selectors addable to user wallets\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IFacetRegistry {\\n struct FacetRegistryConfig {\\n bytes4[] selectors;\\n mapping(bytes4 => FacetInfo) info;\\n }\\n struct FacetInfo {\\n bool exists;\\n uint128 index;\\n }\\n\\n event FacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] facetSelectors\\n );\\n event FacetFunctionSelectorsRemoved(address facet, bytes4[] facetSelectors);\\n\\n error FacetRegistry__FacetSelectorAlreadyRegistered();\\n error FacetRegistry__UnregisteredFacetSelector();\\n\\n function registerFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function removeFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function areFacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external view returns (bool);\\n\\n function isFacetFunctionSelectorRegistered(\\n address facet,\\n bytes4 facetSelector\\n ) external view returns (bool);\\n\\n function getFacetFunctionSelectors(\\n address facet\\n ) external view returns (bytes4[] memory);\\n}\\n\",\"keccak256\":\"0x6e6dd2cab346ef7c31230740ec48d2925e4a9ab24c2f2fb268baaf408dcf02ef\",\"license\":\"Apache-2.0\"},\"contracts/infrastructure/interfaces/ISecurityManager.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Registry Interface\\n * @dev Infrastructure contract to manage security parameters of users\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\ninterface ISecurityManager {\\n error SecurityManager__OutOfBoundary();\\n error SecurityManager__CallerNotWallet();\\n error SecurityManager__AlreadyIntialized();\\n\\n function initializeAdditionSecurityPeriod(\\n uint128 defaultAdditionSecurityPeriod,\\n uint128 minAdditionSecurityPeriod,\\n uint128 maxAdditionSecurityPeriod\\n ) external;\\n\\n function initializeRemovalSecurityPeriod(\\n uint128 defaultRemovalSecurityPeriod,\\n uint128 minRemovalSecurityPeriod,\\n uint128 maxRemovalSecurityPeriod\\n ) external;\\n\\n function initializeApprovalValidationPeriod(\\n uint128 defaultApprovalValidationPeriod,\\n uint128 minApprovalValidationPeriod,\\n uint128 maxApprovalValidationPeriod\\n ) external;\\n\\n function initializeMigrationPeriod(\\n uint128 defaultMigrationPeriod,\\n uint128 minMigrationPeriod,\\n uint128 maxMigrationPeriod\\n ) external;\\n\\n function initializeLockPeriod(\\n uint128 defaultLockPeriod,\\n uint128 minLockPeriod,\\n uint128 maxLockPeriod\\n ) external;\\n\\n function initializeRecoveryPeriod(\\n uint128 defaultRecoveryPeriod,\\n uint128 minRecoveryPeriod,\\n uint128 maxRecoveryPeriod\\n ) external;\\n\\n function initializeSecurityWindow(\\n uint128 defaultSecurityWindow,\\n uint128 minSecurityWindow,\\n uint128 maxSecurityWindow\\n ) external;\\n\\n function setAdditionSecurityPeriod(\\n address wallet,\\n uint128 additionSecurityPeriod\\n ) external;\\n\\n function setRemovalSecurityPeriod(\\n address wallet,\\n uint128 removalSecurityPeriod\\n ) external;\\n\\n function setSecurityWindow(address wallet, uint128 securityWindow) external;\\n\\n function setRecoveryPeriod(address wallet, uint128 recoveryPeriod) external;\\n\\n function setLockPeriod(address wallet, uint128 lockPeriod) external;\\n\\n function setApprovalValidationPeriod(\\n address wallet,\\n uint128 approvalValidationPeriod\\n ) external;\\n\\n function setMigrationPeriod(\\n address wallet,\\n uint128 migrationPeriod\\n ) external;\\n\\n function additionSecurityPeriodOf(\\n address wallet\\n ) external view returns (uint128);\\n\\n function removalSecurityPeriodOf(\\n address wallet\\n ) external view returns (uint128);\\n\\n function securityWindowOf(address wallet) external view returns (uint128);\\n\\n function recoveryPeriodOf(address wallet) external view returns (uint128);\\n\\n function lockPeriodOf(address wallet) external view returns (uint128);\\n\\n function migrationPeriodOf(address wallet) external view returns (uint128);\\n\\n function approvalValidationPeriodOf(\\n address wallet\\n ) external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x9ac6566033ef81ba5744c8ed2b08f130b781b498ab9245bcca87567669549552\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibAppStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {SafeCast} from \\\"@openzeppelin/contracts/utils/math/SafeCast.sol\\\";\\nimport {IEntryPoint} from \\\"../aa-4337/interfaces/IEntryPoint.sol\\\";\\nimport {IFacetRegistry} from \\\"../infrastructure/interfaces/IFacetRegistry.sol\\\";\\n\\n/*\\n * @title App Storage\\n * @dev App storage for Barz contract to prevent storage collision\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Lock {\\n uint64 release;\\n bytes4 locker;\\n}\\n\\nstruct InitializersStorage {\\n // NOTE: initialized is a variable to make sure the initialization is only done once.\\n uint8 signerInitialized;\\n uint8 accountInitialized;\\n uint8 restrictionsInitialized;\\n}\\n\\nstruct AppStorage {\\n mapping(uint256 => InitializersStorage) initStorage;\\n uint8 signerMigration;\\n bytes4 validateOwnerSignatureSelector;\\n IEntryPoint entryPoint;\\n IFacetRegistry facetRegistry;\\n mapping(uint256 => Lock) locks;\\n}\\n\\nlibrary LibAppStorage {\\n error LibAppStorage__AccountAlreadyUninitialized();\\n error LibAppStorage__AccountMustBeUninitialized();\\n error LibAppStorage__SignerAlreadyUninitialized();\\n error LibAppStorage__SignerMustBeUninitialized();\\n\\n function appStorage() internal pure returns (AppStorage storage ds) {\\n assembly {\\n ds.slot := 0\\n }\\n }\\n\\n function setSignerUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerAlreadyUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 0;\\n }\\n\\n function getValidateOwnerSignatureSelector()\\n internal\\n view\\n returns (bytes4 selector)\\n {\\n selector = appStorage().validateOwnerSignatureSelector;\\n }\\n\\n function setValidateOwnerSignatureSelector(\\n bytes4 _validateOwnerSignatureSelector\\n ) internal {\\n appStorage()\\n .validateOwnerSignatureSelector = _validateOwnerSignatureSelector;\\n }\\n\\n function enforceSignerInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerMustBeUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 1;\\n }\\n\\n function enforceAccountInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].accountInitialized) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n s.initStorage[0].accountInitialized = 1;\\n }\\n\\n function initiateSignerMigration() internal {\\n appStorage().signerMigration = 1;\\n }\\n\\n function enforceSignerMigration() internal view {\\n if (1 != appStorage().signerMigration) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n }\\n\\n function finalizeSignerMigration() internal {\\n appStorage().signerMigration = 0;\\n }\\n\\n function setLock(uint256 _releaseAfter, bytes4 _locker) internal {\\n appStorage().locks[0] = Lock(SafeCast.toUint64(_releaseAfter), _locker);\\n }\\n\\n function enforceRestrictionsInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__SignerMustBeUninitialized();\\n s.initStorage[0].restrictionsInitialized = 1;\\n }\\n\\n function setRestrictionsUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__AccountAlreadyUninitialized();\\n s.initStorage[0].restrictionsInitialized = 0;\\n }\\n}\\n\\ncontract BarzStorage {\\n AppStorage internal s;\\n modifier onlyWhenUnlocked() {\\n require(\\n uint64(block.timestamp) >= s.locks[0].release,\\n \\\"Account Locked\\\"\\n );\\n _;\\n }\\n modifier onlyWhenLocked() {\\n require(\\n uint64(block.timestamp) < s.locks[0].release,\\n \\\"Account Unlocked\\\"\\n );\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x48524007862a6ce0e07f645950613ce6513ce073c37a109c75019683d42bae27\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\\n bytes4(keccak256(\\\"verifyRestrictions(address,address,uint256,bytes)\\\"));\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // Default Fallback Handler of the barz.\\n IDiamondLoupe defaultFallbackHandler;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function enforceIsSelf() internal view {\\n require(msg.sender == address(this), \\\"LibDiamond: Caller not self\\\");\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n\\n unchecked {\\n facetIndex++;\\n }\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n\\n function restrictionsFacet() internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(\\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2cabdc00de859c3a3170ce3bda5d0e5fd3933d47ce904fd1585f9818b02572f8\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibFacetStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Storage\\n * @dev Storage contract to store each facets variables with diamond storage\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Secp256k1VerificationStorage {\\n address signer;\\n}\\n\\nstruct Secp256r1VerificationStorage {\\n uint256[2] q;\\n}\\n\\nstruct GuardianStorage {\\n mapping(bytes32 => uint256) pending;\\n mapping(uint8 => StorageConfig) configs;\\n}\\n\\nstruct Info {\\n bool exists;\\n uint128 index;\\n}\\n\\nstruct StorageConfig {\\n address[] addresses;\\n mapping(address => Info) info;\\n}\\n\\nstruct RecoveryConfig {\\n bytes recoveryPublicKey;\\n uint64 executeAfter;\\n}\\n\\nstruct ApprovalConfig {\\n bool isApproved;\\n uint64 validUntil;\\n}\\n\\nstruct RecoveryApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isNewOwnerApproved;\\n}\\n\\nstruct RecoveryStorage {\\n mapping(uint8 => RecoveryConfig) recoveryConfigs;\\n mapping(uint8 => RecoveryApprovalConfig) recoveryApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct RestrictionsStorage {\\n address[] restrictions;\\n mapping(address => bool) exists;\\n}\\n\\nstruct SignatureMigrationConfig {\\n bytes migrationPublicKey;\\n address migrationVerificationFacet;\\n bytes4[] migrationSelectors;\\n uint64 migrateAfter;\\n}\\n\\nstruct SignatureMigrationApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isMigrationApproved;\\n}\\n\\nstruct SignatureMigrationStorage {\\n mapping(uint8 => SignatureMigrationConfig) migrationConfigs;\\n mapping(uint8 => SignatureMigrationApprovalConfig) migrationApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct DiamondCutApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isDiamondCutApproved;\\n}\\n\\nstruct DiamondCutStorage {\\n mapping(uint8 => DiamondCutApprovalConfig) diamondCutApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct LockStorage {\\n uint128 nonce;\\n}\\n\\nlibrary LibFacetStorage {\\n bytes32 constant K1_STORAGE_POSITION =\\n keccak256(\\n \\\"v0.trustwallet.diamond.storage.Secp256k1VerificationStorage\\\"\\n );\\n bytes32 constant R1_STORAGE_POSITION =\\n keccak256(\\n \\\"v0.trustwallet.diamond.storage.Secp256r1VerificationStorage\\\"\\n );\\n bytes32 constant GUARDIAN_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.GuardianStorage\\\");\\n bytes32 constant RECOVERY_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.RecoveryStorage\\\");\\n bytes32 constant RESTRICTION_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.RestrictionsStorage\\\");\\n bytes32 constant MIGRATION_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.SignatureMigrationStorage\\\");\\n bytes32 constant DIAMONDCUT_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.DiamondCutStorage\\\");\\n bytes32 constant LOCK_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.LockStorage\\\");\\n\\n function k1Storage()\\n internal\\n pure\\n returns (Secp256k1VerificationStorage storage ds)\\n {\\n bytes32 storagePosition = K1_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function r1Storage()\\n internal\\n pure\\n returns (Secp256r1VerificationStorage storage ds)\\n {\\n bytes32 storagePosition = R1_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function guardianStorage()\\n internal\\n pure\\n returns (GuardianStorage storage ds)\\n {\\n bytes32 storagePosition = GUARDIAN_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function recoveryStorage()\\n internal\\n pure\\n returns (RecoveryStorage storage ds)\\n {\\n bytes32 storagePosition = RECOVERY_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function restrictionsStorage()\\n internal\\n pure\\n returns (RestrictionsStorage storage ds)\\n {\\n bytes32 storagePosition = RESTRICTION_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function migrationStorage()\\n internal\\n pure\\n returns (SignatureMigrationStorage storage ds)\\n {\\n bytes32 storagePosition = MIGRATION_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function diamondCutStorage()\\n internal\\n pure\\n returns (DiamondCutStorage storage ds)\\n {\\n bytes32 storagePosition = DIAMONDCUT_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function lockStorage() internal pure returns (LockStorage storage ds) {\\n bytes32 storagePosition = LOCK_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n}\\n\",\"keccak256\":\"0x87c85decfd943deda9540733e464cb1a92eba735a301e89ce6f798016e359761\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibGuardian.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {LibFacetStorage, StorageConfig} from \\\"./LibFacetStorage.sol\\\";\\n\\n/**\\n * @title LibGuardian\\n * @dev Internal Library to provide utility feature for Guardians stored in Guardian Facet Storage\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\nlibrary LibGuardian {\\n function majorityOfGuardians()\\n internal\\n view\\n returns (uint256 guardianNumber)\\n {\\n uint256 guardianLength = guardianCount();\\n guardianNumber = (guardianLength == 0) ? 0 : guardianLength / 2 + 1;\\n }\\n\\n function isGuardian(address _guardian) internal view returns (bool) {\\n StorageConfig storage config = LibFacetStorage\\n .guardianStorage()\\n .configs[0];\\n return config.info[_guardian].exists;\\n }\\n\\n function guardianCount() internal view returns (uint256) {\\n StorageConfig storage config = LibFacetStorage\\n .guardianStorage()\\n .configs[0];\\n return config.addresses.length;\\n }\\n\\n function getGuardians() internal view returns (address[] memory) {\\n StorageConfig storage config = LibFacetStorage\\n .guardianStorage()\\n .configs[0];\\n address[] memory addresses = new address[](config.addresses.length);\\n uint256 addressesLen = config.addresses.length;\\n for (uint256 i; i < addressesLen; ) {\\n addresses[i] = config.addresses[i];\\n unchecked {\\n ++i;\\n }\\n }\\n return addresses;\\n }\\n}\\n\",\"keccak256\":\"0x6a620992d5535878fc03d1a27a6675f4c1509adfb3ddbbca1c52b546c25392dc\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x60a06040523480156200001157600080fd5b506040516200379b3803806200379b833981016040819052620000349162000046565b6001600160a01b031660805262000078565b6000602082840312156200005957600080fd5b81516001600160a01b03811681146200007157600080fd5b9392505050565b6080516137006200009b600039600081816101f10152611b2501526137006000f3fe608060405234801561001057600080fd5b50600436106100d45760003560e01c806379c0d58d11610081578063afb877bb1161005b578063afb877bb146101d9578063de675a6d146101ec578063e33ecf0a1461023857600080fd5b806379c0d58d14610192578063836d6bfb146101b35780638824a0bb146101c657600080fd5b806326fc3ef4116100b257806326fc3ef4146101145780632f4d98ea1461015c5780633c0985681461017f57600080fd5b806313c34f4b146100d95780631c776dd5146100ee5780631f931c1c14610101575b600080fd5b6100ec6100e7366004612a97565b61024b565b005b6100ec6100fc366004612ad9565b6104df565b6100ec61010f366004612b9c565b610a76565b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9bf546040516fffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b61016f61016a366004612c4a565b610c7b565b6040519015158152602001610153565b6100ec61018d366004612ca4565b610c8d565b6101a56101a0366004612c4a565b610df2565b604051908152602001610153565b61016f6101c1366004612cdb565b610e4c565b6100ec6101d4366004612dd2565b610eed565b6100ec6101e7366004612a97565b610fe1565b6102137f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610153565b6101a5610246366004612a97565b61130e565b3360009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff1615801561028a5750303314155b156102c1576040517f6238ee3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610369576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064015b60405180910390fd5b60008080527f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be6020527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d3906103be848461130e565b60008181526020848152604080832033845290915290205490915060ff16610412576040517fedc5708300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051808201825260008082526020808301828152858352868252848320338452909152908390209151825491517fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000009092169015157fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff161761010067ffffffffffffffff90921691909102179055517f3c3d8c1f0b0faff6fe0ace6b485d0595a0106dce9e303f956fd941ebdbe9a98e906104d19086908690612f54565b60405180910390a150505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610582576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b8281146105bb576040517fe854148500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6105cd6105c886886130aa565b611435565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b754600003610650576040517fa788861700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061065c878761130e565b905061069a8585808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506115b392505050565b506106d881868680806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250610eed92505050565b60006106e382610c7b565b90506000816106f35760016106f6565b60005b60ff169050806107046116d0565b61070e9190613201565b61071784610df2565b6107219088613201565b1015610759576040517f709fb08000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805b878110156109a0576107d989898381811061077a5761077a613214565b905060200201602081019061078f9190613243565b73ffffffffffffffffffffffffffffffffffffffff1660009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff1690565b1580156108225750308989838181106107f4576107f4613214565b90506020020160208101906108099190613243565b73ffffffffffffffffffffffffffffffffffffffff1614155b15610859576040517f7b2cbbb400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3089898381811061086c5761086c613214565b90506020020160208101906108819190613243565b73ffffffffffffffffffffffffffffffffffffffff16036108d95783156108d4576040517fee21708000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600191505b6109628989838181106108ee576108ee613214565b90506020020160208101906109039190613243565b8689898581811061091657610916613214565b90506020028101906109289190613265565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061174f92505050565b610998576040517fac3d341600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60010161075d565b50801580156109ad575082155b156109e4576040517f6d21730400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9bf80546fffffffffffffffffffffffffffffffff808216600101167fffffffffffffffffffffffffffffffff00000000000000000000000000000000909116179055610a6a610a538a8c6130aa565b6000604051806020016040528060008152506117ca565b50505050505050505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610b19576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b610b2161195f565b610b2e6105c885876130aa565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75415610baf576040517fa788861700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff831615610bfd576040517f871cb76100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be5b600190810180547fffffffffffffffffffffffffffffffff0000000000000000000000000000000081166fffffffffffffffffffffffffffffffff91821690930116919091179055610c74610a5385876130aa565b5050505050565b6000610c878230610e4c565b92915050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610d30576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b610d3861195f565b7fffffffff00000000000000000000000000000000000000000000000000000000821660008181527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4922602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001685151590811790915582519384529083015280517f4e6bd17989efa6d6a9607ccaac1bba27b29f99622bc830d99a3a9883b21a19c79281900390910190a15050565b600080610dfd6119ca565b805190915060005b81811015610e4457610e3085848381518110610e2357610e23613214565b6020026020010151610e4c565b15610e3c578360010193505b600101610e05565b505050919050565b60008281527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d36020818152604080842073ffffffffffffffffffffffffffffffffffffffff8616855290915282205460ff168015610ee5575060008481526020828152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152902054610100900467ffffffffffffffff1642105b949350505050565b6000610ef76119ca565b805183519192509060005b82811015610fd957610f2086858381518110610e2357610e23613214565b15610fd15760005b82811015610fcf57848281518110610f4257610f42613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16868281518110610f7257610f72613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603610fc7576040517f50f5729f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600101610f28565b505b600101610f02565b505050505050565b3360009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff161580156110205750303314155b15611057576040517f6238ee3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff9081164290911610156110fa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75460000361117d576040517f3a76e1f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080527f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be6020527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d36111d36105c883856130aa565b60006111df848461130e565b905060006111eb611af4565b6111f59042613201565b6040805180820182526001815267ffffffffffffffff838116602080840191825260008881528982528581203382529091528490209251835491517fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000009092169015157fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff16176101009190921602179055519091507f6248ff757895beed7d43d135bccf59a26b7fbdf0fe8233487c44e82c0f266ba3906112b89087908790612f54565b60405180910390a16112c86116d0565b6112d183610df2565b101580156112e357506112e382610c7b565b15610c74577f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be610c1f565b60008282604051602001611323929190612f54565b6040516020818303038152906040528051906020012030466113627f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be90565b6001015460408051602081019590955273ffffffffffffffffffffffffffffffffffffffff9093169284019290925260608301526fffffffffffffffffffffffffffffffff16608082015260a001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905280516020918201207f19457468657265756d205369676e6564204d6573736167653a0a33320000000091830191909152603c820152605c0160405160208183030381529060405280519060200120905092915050565b805160005b818110156115ae57600083828151811061145657611456613214565b602002602001015160200151600281111561147357611473612e8a565b14806114ad5750600183828151811061148e5761148e613214565b60200260200101516020015160028111156114ab576114ab612e8a565b145b156115a657600254835173ffffffffffffffffffffffffffffffffffffffff9091169063df871f72908590849081106114e8576114e8613214565b60200260200101516000015185848151811061150657611506613214565b6020026020010151604001516040518363ffffffff1660e01b815260040161152f92919061331c565b602060405180830381865afa15801561154c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611570919061334b565b6115a6576040517ff41a931c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60010161143a565b505050565b80516000908082036115f1576040517f3aee2eec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b6115ff600183613368565b8110156116c6576000611613826001613201565b90505b828110156116bd5784818151811061163057611630613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1685838151811061166057611660613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16036116b5576040517f8dd19e7d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600101611616565b506001016115f4565b5060009392505050565b600080611723600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75490565b905080156117465761173660028261337b565b611741906001613201565b611749565b60005b91505090565b600080600061175e8585611bf6565b9092509050600081600481111561177757611777612e8a565b1480156117af57508573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b806117c057506117c0868686611c3b565b9695505050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921547f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff8116908190600090600716156118395750600381901c60009081526001840160205260409020545b60005b87518110156118b6576118a983838a848151811061185c5761185c613214565b6020026020010151600001518b858151811061187a5761187a613214565b6020026020010151602001518c868151811061189857611898613214565b602002602001015160400151611d98565b909350915060010161183c565b508282146118ef576002840180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff84161790555b600782161561191157600382901c600090815260018501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb67387878760405161194493929190613424565b60405180910390a16119568686612829565b50505050505050565b3330146119c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4c69624469616d6f6e643a2043616c6c6572206e6f742073656c6600000000006044820152606401610360565b565b60008080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b780546060929067ffffffffffffffff811115611a3257611a32612d07565b604051908082528060200260200182016040528015611a5b578160200160208202803683370190505b50825490915060005b81811015611aeb57836000018181548110611a8157611a81613214565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16838281518110611abe57611abe613214565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101611a64565b50909392505050565b6040517f52430c8d0000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906352430c8d90602401602060405180830381865afa158015611b81573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ba59190613510565b6fffffffffffffffffffffffffffffffff16905060008111611bf3576040517fdac5ec8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b90565b6000808251604103611c2c5760208301516040840151606085015160001a611c2087828585612928565b94509450505050611c34565b506000905060025b9250929050565b60008060008573ffffffffffffffffffffffffffffffffffffffff16631626ba7e60e01b8686604051602401611c72929190613542565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909416939093179092529051611cfb919061355b565b600060405180830381855afa9150503d8060008114611d36576040519150601f19603f3d011682016040523d82523d6000602084013e611d3b565b606091505b5091509150818015611d4f57506020815110155b80156117c0575080517f1626ba7e0000000000000000000000000000000000000000000000000000000090611d8d9083016020908101908401613577565b149695505050505050565b600080807f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f90506000845111611e50576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610360565b6000856002811115611e6457611e64612e8a565b0361203457611e8b8660405180606001604052806024815260200161365760249139612a17565b60005b845181101561202e576000858281518110611eab57611eab613214565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c15611f7e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c72656164792065786973747300000000000000000000006064820152608401610360565b7fffffffff0000000000000000000000000000000000000000000000000000000080831660008181526020879052604090207fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608d901b168e17905560e060058e901b811692831c199c909c1690821c179a8190036120125760038c901c600090815260018601602052604081209b909b555b8b61201c81613590565b9c505060019093019250611e8e915050565b5061281d565b600185600281111561204857612048612e8a565b036123385761206f866040518060600160405280602881526020016136a360289139612a17565b60005b845181101561202e57600085828151811061208f5761208f613214565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c308103612164576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4c69624469616d6f6e644375743a2043616e2774207265706c61636520696d6d60448201527f757461626c652066756e6374696f6e00000000000000000000000000000000006064820152608401610360565b8973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361221f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e00000000000000006064820152608401610360565b73ffffffffffffffffffffffffffffffffffffffff81166122c2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e207468617420646f65736e277420657869737400000000000000006064820152608401610360565b507fffffffff0000000000000000000000000000000000000000000000000000000090911660009081526020849052604090206bffffffffffffffffffffffff919091167fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608a901b16179055600101612072565b600285600281111561234c5761234c612e8a565b036127955773ffffffffffffffffffffffffffffffffffffffff8616156123f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d7573742062652061646472657373283029000000000000000000006064820152608401610360565b600388901c6007891660005b86518110156127755760008a900361243d578261241d816135c8565b60008181526001870160205260409020549b5093506007925061244b9050565b81612447816135c8565b9250505b6000806000808a858151811061246357612463613214565b6020908102919091018101517fffffffff0000000000000000000000000000000000000000000000000000000081166000908152918a9052604090912054909150606081901c612535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608401610360565b30606082901c036125c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e0000000000000000000000000000000000006064820152608401610360565b600587901b8f901b94507fffffffff0000000000000000000000000000000000000000000000000000000080861690831614612666577fffffffff000000000000000000000000000000000000000000000000000000008516600090815260208a90526040902080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff83161790555b7fffffffff0000000000000000000000000000000000000000000000000000000091909116600090815260208990526040812055600381901c611fff16925060051b60e01690508582146126fb576000828152600188016020526040902080547fffffffff0000000000000000000000000000000000000000000000000000000080841c19909116908516831c17905561274c565b80837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c817fffffffff0000000000000000000000000000000000000000000000000000000060001b901c198e16179c505b8460000361276a57600086815260018801602052604081208190559c505b505050600101612401565b50806127828360086135fd565b61278c9190613201565b9950505061281d565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560448201527f74416374696f6e000000000000000000000000000000000000000000000000006064820152608401610360565b50959694955050505050565b73ffffffffffffffffffffffffffffffffffffffff8216612848575050565b61286a8260405180606001604052806028815260200161367b60289139612a17565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051612892919061355b565b600060405180830381855af49150503d80600081146128cd576040519150601f19603f3d011682016040523d82523d6000602084013e6128d2565b606091505b509150915081612922578051156128ec5780518082602001fd5b83836040517f192105d7000000000000000000000000000000000000000000000000000000008152600401610360929190613614565b50505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561295f5750600090506003612a0e565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156129b3573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116612a0757600060019250925050612a0e565b9150600090505b94509492505050565b813b8181612922576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103609190613643565b60008083601f840112612a6457600080fd5b50813567ffffffffffffffff811115612a7c57600080fd5b6020830191508360208260051b8501011115611c3457600080fd5b60008060208385031215612aaa57600080fd5b823567ffffffffffffffff811115612ac157600080fd5b612acd85828601612a52565b90969095509350505050565b60008060008060008060608789031215612af257600080fd5b863567ffffffffffffffff80821115612b0a57600080fd5b612b168a838b01612a52565b90985096506020890135915080821115612b2f57600080fd5b612b3b8a838b01612a52565b90965094506040890135915080821115612b5457600080fd5b50612b6189828a01612a52565b979a9699509497509295939492505050565b803573ffffffffffffffffffffffffffffffffffffffff81168114612b9757600080fd5b919050565b600080600080600060608688031215612bb457600080fd5b853567ffffffffffffffff80821115612bcc57600080fd5b612bd889838a01612a52565b9097509550859150612bec60208901612b73565b94506040880135915080821115612c0257600080fd5b818801915088601f830112612c1657600080fd5b813581811115612c2557600080fd5b896020828501011115612c3757600080fd5b9699959850939650602001949392505050565b600060208284031215612c5c57600080fd5b5035919050565b80357fffffffff0000000000000000000000000000000000000000000000000000000081168114612b9757600080fd5b8015158114612ca157600080fd5b50565b60008060408385031215612cb757600080fd5b612cc083612c63565b91506020830135612cd081612c93565b809150509250929050565b60008060408385031215612cee57600080fd5b82359150612cfe60208401612b73565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff81118282101715612d5957612d59612d07565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715612da657612da6612d07565b604052919050565b600067ffffffffffffffff821115612dc857612dc8612d07565b5060051b60200190565b60008060408385031215612de557600080fd5b8235915060208084013567ffffffffffffffff811115612e0457600080fd5b8401601f81018613612e1557600080fd5b8035612e28612e2382612dae565b612d5f565b81815260059190911b82018301908381019088831115612e4757600080fd5b928401925b82841015612e6c57612e5d84612b73565b82529284019290840190612e4c565b80955050505050509250929050565b803560038110612b9757600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60038110612ef0577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b8183526000602080850194508260005b85811015612f49577fffffffff00000000000000000000000000000000000000000000000000000000612f3683612c63565b1687529582019590820190600101612f04565b509495945050505050565b60208082528181018390526000906040808401600586811b8601830188865b8981101561309b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc089840301855281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa18c3603018112612fd457600080fd5b8b01606073ffffffffffffffffffffffffffffffffffffffff612ff683612b73565b168552613004898301612e7b565b6130108a870182612eb9565b50878201357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe183360301811261304557600080fd5b90910188810191903567ffffffffffffffff81111561306357600080fd5b80871b360383131561307457600080fd5b81898701526130868287018285612ef4565b978a0197955050509187019150600101612f73565b50909998505050505050505050565b60006130b8612e2384612dae565b83815260208082019190600586811b8601368111156130d657600080fd5b865b818110156131c557803567ffffffffffffffff808211156130f95760008081fd5b818a0191506060823603121561310f5760008081fd5b613117612d36565b61312083612b73565b815261312d878401612e7b565b87820152604080840135838111156131455760008081fd5b939093019236601f85011261315c57600092508283fd5b8335925061316c612e2384612dae565b83815292871b840188019288810190368511156131895760008081fd5b948901945b848610156131ae5761319f86612c63565b8252948901949089019061318e565b9183019190915250885250509483019483016130d8565b5092979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610c8757610c876131d2565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561325557600080fd5b61325e82612b73565b9392505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261329a57600080fd5b83018035915067ffffffffffffffff8211156132b557600080fd5b602001915036819003821315611c3457600080fd5b600081518084526020808501945080840160005b83811015612f495781517fffffffff0000000000000000000000000000000000000000000000000000000016875295820195908201906001016132de565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000610ee560408301846132ca565b60006020828403121561335d57600080fd5b815161325e81612c93565b81810381811115610c8757610c876131d2565b6000826133b1577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60005b838110156133d15781810151838201526020016133b9565b50506000910152565b600081518084526133f28160208601602086016133b6565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6000606080830181845280875180835260808601915060808160051b87010192506020808a0160005b838110156134d4577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80898703018552815173ffffffffffffffffffffffffffffffffffffffff8151168752838101516134a885890182612eb9565b506040908101519087018890526134c1878901826132ca565b965050938201939082019060010161344d565b505073ffffffffffffffffffffffffffffffffffffffff8916908701525050838103604085015261350581866133da565b979650505050505050565b60006020828403121561352257600080fd5b81516fffffffffffffffffffffffffffffffff8116811461325e57600080fd5b828152604060208201526000610ee560408301846133da565b6000825161356d8184602087016133b6565b9190910192915050565b60006020828403121561358957600080fd5b5051919050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036135c1576135c16131d2565b5060010190565b6000816135d7576135d76131d2565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b8082028115828204841417610c8757610c876131d2565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000610ee560408301846133da565b60208152600061325e60208301846133da56fe4c69624469616d6f6e644375743a2041646420666163657420686173206e6f20636f64654c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a205265706c61636520666163657420686173206e6f20636f6465a2646970667358221220c5a8c10b22f20cde3fe0431ff57305237423677a60888f5b349fc6751336ae1464736f6c63430008150033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100d45760003560e01c806379c0d58d11610081578063afb877bb1161005b578063afb877bb146101d9578063de675a6d146101ec578063e33ecf0a1461023857600080fd5b806379c0d58d14610192578063836d6bfb146101b35780638824a0bb146101c657600080fd5b806326fc3ef4116100b257806326fc3ef4146101145780632f4d98ea1461015c5780633c0985681461017f57600080fd5b806313c34f4b146100d95780631c776dd5146100ee5780631f931c1c14610101575b600080fd5b6100ec6100e7366004612a97565b61024b565b005b6100ec6100fc366004612ad9565b6104df565b6100ec61010f366004612b9c565b610a76565b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9bf546040516fffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b61016f61016a366004612c4a565b610c7b565b6040519015158152602001610153565b6100ec61018d366004612ca4565b610c8d565b6101a56101a0366004612c4a565b610df2565b604051908152602001610153565b61016f6101c1366004612cdb565b610e4c565b6100ec6101d4366004612dd2565b610eed565b6100ec6101e7366004612a97565b610fe1565b6102137f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610153565b6101a5610246366004612a97565b61130e565b3360009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff1615801561028a5750303314155b156102c1576040517f6238ee3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610369576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064015b60405180910390fd5b60008080527f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be6020527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d3906103be848461130e565b60008181526020848152604080832033845290915290205490915060ff16610412576040517fedc5708300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051808201825260008082526020808301828152858352868252848320338452909152908390209151825491517fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000009092169015157fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff161761010067ffffffffffffffff90921691909102179055517f3c3d8c1f0b0faff6fe0ace6b485d0595a0106dce9e303f956fd941ebdbe9a98e906104d19086908690612f54565b60405180910390a150505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610582576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b8281146105bb576040517fe854148500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6105cd6105c886886130aa565b611435565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b754600003610650576040517fa788861700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061065c878761130e565b905061069a8585808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506115b392505050565b506106d881868680806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250610eed92505050565b60006106e382610c7b565b90506000816106f35760016106f6565b60005b60ff169050806107046116d0565b61070e9190613201565b61071784610df2565b6107219088613201565b1015610759576040517f709fb08000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805b878110156109a0576107d989898381811061077a5761077a613214565b905060200201602081019061078f9190613243565b73ffffffffffffffffffffffffffffffffffffffff1660009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff1690565b1580156108225750308989838181106107f4576107f4613214565b90506020020160208101906108099190613243565b73ffffffffffffffffffffffffffffffffffffffff1614155b15610859576040517f7b2cbbb400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3089898381811061086c5761086c613214565b90506020020160208101906108819190613243565b73ffffffffffffffffffffffffffffffffffffffff16036108d95783156108d4576040517fee21708000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600191505b6109628989838181106108ee576108ee613214565b90506020020160208101906109039190613243565b8689898581811061091657610916613214565b90506020028101906109289190613265565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061174f92505050565b610998576040517fac3d341600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60010161075d565b50801580156109ad575082155b156109e4576040517f6d21730400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9bf80546fffffffffffffffffffffffffffffffff808216600101167fffffffffffffffffffffffffffffffff00000000000000000000000000000000909116179055610a6a610a538a8c6130aa565b6000604051806020016040528060008152506117ca565b50505050505050505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610b19576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b610b2161195f565b610b2e6105c885876130aa565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75415610baf576040517fa788861700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff831615610bfd576040517f871cb76100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be5b600190810180547fffffffffffffffffffffffffffffffff0000000000000000000000000000000081166fffffffffffffffffffffffffffffffff91821690930116919091179055610c74610a5385876130aa565b5050505050565b6000610c878230610e4c565b92915050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610d30576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b610d3861195f565b7fffffffff00000000000000000000000000000000000000000000000000000000821660008181527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4922602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001685151590811790915582519384529083015280517f4e6bd17989efa6d6a9607ccaac1bba27b29f99622bc830d99a3a9883b21a19c79281900390910190a15050565b600080610dfd6119ca565b805190915060005b81811015610e4457610e3085848381518110610e2357610e23613214565b6020026020010151610e4c565b15610e3c578360010193505b600101610e05565b505050919050565b60008281527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d36020818152604080842073ffffffffffffffffffffffffffffffffffffffff8616855290915282205460ff168015610ee5575060008481526020828152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152902054610100900467ffffffffffffffff1642105b949350505050565b6000610ef76119ca565b805183519192509060005b82811015610fd957610f2086858381518110610e2357610e23613214565b15610fd15760005b82811015610fcf57848281518110610f4257610f42613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16868281518110610f7257610f72613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603610fc7576040517f50f5729f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600101610f28565b505b600101610f02565b505050505050565b3360009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff161580156110205750303314155b15611057576040517f6238ee3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff9081164290911610156110fa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75460000361117d576040517f3a76e1f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080527f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be6020527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d36111d36105c883856130aa565b60006111df848461130e565b905060006111eb611af4565b6111f59042613201565b6040805180820182526001815267ffffffffffffffff838116602080840191825260008881528982528581203382529091528490209251835491517fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000009092169015157fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff16176101009190921602179055519091507f6248ff757895beed7d43d135bccf59a26b7fbdf0fe8233487c44e82c0f266ba3906112b89087908790612f54565b60405180910390a16112c86116d0565b6112d183610df2565b101580156112e357506112e382610c7b565b15610c74577f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be610c1f565b60008282604051602001611323929190612f54565b6040516020818303038152906040528051906020012030466113627f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be90565b6001015460408051602081019590955273ffffffffffffffffffffffffffffffffffffffff9093169284019290925260608301526fffffffffffffffffffffffffffffffff16608082015260a001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905280516020918201207f19457468657265756d205369676e6564204d6573736167653a0a33320000000091830191909152603c820152605c0160405160208183030381529060405280519060200120905092915050565b805160005b818110156115ae57600083828151811061145657611456613214565b602002602001015160200151600281111561147357611473612e8a565b14806114ad5750600183828151811061148e5761148e613214565b60200260200101516020015160028111156114ab576114ab612e8a565b145b156115a657600254835173ffffffffffffffffffffffffffffffffffffffff9091169063df871f72908590849081106114e8576114e8613214565b60200260200101516000015185848151811061150657611506613214565b6020026020010151604001516040518363ffffffff1660e01b815260040161152f92919061331c565b602060405180830381865afa15801561154c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611570919061334b565b6115a6576040517ff41a931c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60010161143a565b505050565b80516000908082036115f1576040517f3aee2eec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b6115ff600183613368565b8110156116c6576000611613826001613201565b90505b828110156116bd5784818151811061163057611630613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1685838151811061166057611660613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16036116b5576040517f8dd19e7d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600101611616565b506001016115f4565b5060009392505050565b600080611723600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75490565b905080156117465761173660028261337b565b611741906001613201565b611749565b60005b91505090565b600080600061175e8585611bf6565b9092509050600081600481111561177757611777612e8a565b1480156117af57508573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b806117c057506117c0868686611c3b565b9695505050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921547f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff8116908190600090600716156118395750600381901c60009081526001840160205260409020545b60005b87518110156118b6576118a983838a848151811061185c5761185c613214565b6020026020010151600001518b858151811061187a5761187a613214565b6020026020010151602001518c868151811061189857611898613214565b602002602001015160400151611d98565b909350915060010161183c565b508282146118ef576002840180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff84161790555b600782161561191157600382901c600090815260018501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb67387878760405161194493929190613424565b60405180910390a16119568686612829565b50505050505050565b3330146119c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4c69624469616d6f6e643a2043616c6c6572206e6f742073656c6600000000006044820152606401610360565b565b60008080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b780546060929067ffffffffffffffff811115611a3257611a32612d07565b604051908082528060200260200182016040528015611a5b578160200160208202803683370190505b50825490915060005b81811015611aeb57836000018181548110611a8157611a81613214565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16838281518110611abe57611abe613214565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101611a64565b50909392505050565b6040517f52430c8d0000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906352430c8d90602401602060405180830381865afa158015611b81573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ba59190613510565b6fffffffffffffffffffffffffffffffff16905060008111611bf3576040517fdac5ec8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b90565b6000808251604103611c2c5760208301516040840151606085015160001a611c2087828585612928565b94509450505050611c34565b506000905060025b9250929050565b60008060008573ffffffffffffffffffffffffffffffffffffffff16631626ba7e60e01b8686604051602401611c72929190613542565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909416939093179092529051611cfb919061355b565b600060405180830381855afa9150503d8060008114611d36576040519150601f19603f3d011682016040523d82523d6000602084013e611d3b565b606091505b5091509150818015611d4f57506020815110155b80156117c0575080517f1626ba7e0000000000000000000000000000000000000000000000000000000090611d8d9083016020908101908401613577565b149695505050505050565b600080807f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f90506000845111611e50576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610360565b6000856002811115611e6457611e64612e8a565b0361203457611e8b8660405180606001604052806024815260200161365760249139612a17565b60005b845181101561202e576000858281518110611eab57611eab613214565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c15611f7e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c72656164792065786973747300000000000000000000006064820152608401610360565b7fffffffff0000000000000000000000000000000000000000000000000000000080831660008181526020879052604090207fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608d901b168e17905560e060058e901b811692831c199c909c1690821c179a8190036120125760038c901c600090815260018601602052604081209b909b555b8b61201c81613590565b9c505060019093019250611e8e915050565b5061281d565b600185600281111561204857612048612e8a565b036123385761206f866040518060600160405280602881526020016136a360289139612a17565b60005b845181101561202e57600085828151811061208f5761208f613214565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c308103612164576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4c69624469616d6f6e644375743a2043616e2774207265706c61636520696d6d60448201527f757461626c652066756e6374696f6e00000000000000000000000000000000006064820152608401610360565b8973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361221f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e00000000000000006064820152608401610360565b73ffffffffffffffffffffffffffffffffffffffff81166122c2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e207468617420646f65736e277420657869737400000000000000006064820152608401610360565b507fffffffff0000000000000000000000000000000000000000000000000000000090911660009081526020849052604090206bffffffffffffffffffffffff919091167fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608a901b16179055600101612072565b600285600281111561234c5761234c612e8a565b036127955773ffffffffffffffffffffffffffffffffffffffff8616156123f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d7573742062652061646472657373283029000000000000000000006064820152608401610360565b600388901c6007891660005b86518110156127755760008a900361243d578261241d816135c8565b60008181526001870160205260409020549b5093506007925061244b9050565b81612447816135c8565b9250505b6000806000808a858151811061246357612463613214565b6020908102919091018101517fffffffff0000000000000000000000000000000000000000000000000000000081166000908152918a9052604090912054909150606081901c612535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608401610360565b30606082901c036125c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e0000000000000000000000000000000000006064820152608401610360565b600587901b8f901b94507fffffffff0000000000000000000000000000000000000000000000000000000080861690831614612666577fffffffff000000000000000000000000000000000000000000000000000000008516600090815260208a90526040902080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff83161790555b7fffffffff0000000000000000000000000000000000000000000000000000000091909116600090815260208990526040812055600381901c611fff16925060051b60e01690508582146126fb576000828152600188016020526040902080547fffffffff0000000000000000000000000000000000000000000000000000000080841c19909116908516831c17905561274c565b80837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c817fffffffff0000000000000000000000000000000000000000000000000000000060001b901c198e16179c505b8460000361276a57600086815260018801602052604081208190559c505b505050600101612401565b50806127828360086135fd565b61278c9190613201565b9950505061281d565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560448201527f74416374696f6e000000000000000000000000000000000000000000000000006064820152608401610360565b50959694955050505050565b73ffffffffffffffffffffffffffffffffffffffff8216612848575050565b61286a8260405180606001604052806028815260200161367b60289139612a17565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051612892919061355b565b600060405180830381855af49150503d80600081146128cd576040519150601f19603f3d011682016040523d82523d6000602084013e6128d2565b606091505b509150915081612922578051156128ec5780518082602001fd5b83836040517f192105d7000000000000000000000000000000000000000000000000000000008152600401610360929190613614565b50505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561295f5750600090506003612a0e565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156129b3573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116612a0757600060019250925050612a0e565b9150600090505b94509492505050565b813b8181612922576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103609190613643565b60008083601f840112612a6457600080fd5b50813567ffffffffffffffff811115612a7c57600080fd5b6020830191508360208260051b8501011115611c3457600080fd5b60008060208385031215612aaa57600080fd5b823567ffffffffffffffff811115612ac157600080fd5b612acd85828601612a52565b90969095509350505050565b60008060008060008060608789031215612af257600080fd5b863567ffffffffffffffff80821115612b0a57600080fd5b612b168a838b01612a52565b90985096506020890135915080821115612b2f57600080fd5b612b3b8a838b01612a52565b90965094506040890135915080821115612b5457600080fd5b50612b6189828a01612a52565b979a9699509497509295939492505050565b803573ffffffffffffffffffffffffffffffffffffffff81168114612b9757600080fd5b919050565b600080600080600060608688031215612bb457600080fd5b853567ffffffffffffffff80821115612bcc57600080fd5b612bd889838a01612a52565b9097509550859150612bec60208901612b73565b94506040880135915080821115612c0257600080fd5b818801915088601f830112612c1657600080fd5b813581811115612c2557600080fd5b896020828501011115612c3757600080fd5b9699959850939650602001949392505050565b600060208284031215612c5c57600080fd5b5035919050565b80357fffffffff0000000000000000000000000000000000000000000000000000000081168114612b9757600080fd5b8015158114612ca157600080fd5b50565b60008060408385031215612cb757600080fd5b612cc083612c63565b91506020830135612cd081612c93565b809150509250929050565b60008060408385031215612cee57600080fd5b82359150612cfe60208401612b73565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff81118282101715612d5957612d59612d07565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715612da657612da6612d07565b604052919050565b600067ffffffffffffffff821115612dc857612dc8612d07565b5060051b60200190565b60008060408385031215612de557600080fd5b8235915060208084013567ffffffffffffffff811115612e0457600080fd5b8401601f81018613612e1557600080fd5b8035612e28612e2382612dae565b612d5f565b81815260059190911b82018301908381019088831115612e4757600080fd5b928401925b82841015612e6c57612e5d84612b73565b82529284019290840190612e4c565b80955050505050509250929050565b803560038110612b9757600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60038110612ef0577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b8183526000602080850194508260005b85811015612f49577fffffffff00000000000000000000000000000000000000000000000000000000612f3683612c63565b1687529582019590820190600101612f04565b509495945050505050565b60208082528181018390526000906040808401600586811b8601830188865b8981101561309b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc089840301855281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa18c3603018112612fd457600080fd5b8b01606073ffffffffffffffffffffffffffffffffffffffff612ff683612b73565b168552613004898301612e7b565b6130108a870182612eb9565b50878201357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe183360301811261304557600080fd5b90910188810191903567ffffffffffffffff81111561306357600080fd5b80871b360383131561307457600080fd5b81898701526130868287018285612ef4565b978a0197955050509187019150600101612f73565b50909998505050505050505050565b60006130b8612e2384612dae565b83815260208082019190600586811b8601368111156130d657600080fd5b865b818110156131c557803567ffffffffffffffff808211156130f95760008081fd5b818a0191506060823603121561310f5760008081fd5b613117612d36565b61312083612b73565b815261312d878401612e7b565b87820152604080840135838111156131455760008081fd5b939093019236601f85011261315c57600092508283fd5b8335925061316c612e2384612dae565b83815292871b840188019288810190368511156131895760008081fd5b948901945b848610156131ae5761319f86612c63565b8252948901949089019061318e565b9183019190915250885250509483019483016130d8565b5092979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610c8757610c876131d2565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561325557600080fd5b61325e82612b73565b9392505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261329a57600080fd5b83018035915067ffffffffffffffff8211156132b557600080fd5b602001915036819003821315611c3457600080fd5b600081518084526020808501945080840160005b83811015612f495781517fffffffff0000000000000000000000000000000000000000000000000000000016875295820195908201906001016132de565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000610ee560408301846132ca565b60006020828403121561335d57600080fd5b815161325e81612c93565b81810381811115610c8757610c876131d2565b6000826133b1577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60005b838110156133d15781810151838201526020016133b9565b50506000910152565b600081518084526133f28160208601602086016133b6565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6000606080830181845280875180835260808601915060808160051b87010192506020808a0160005b838110156134d4577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80898703018552815173ffffffffffffffffffffffffffffffffffffffff8151168752838101516134a885890182612eb9565b506040908101519087018890526134c1878901826132ca565b965050938201939082019060010161344d565b505073ffffffffffffffffffffffffffffffffffffffff8916908701525050838103604085015261350581866133da565b979650505050505050565b60006020828403121561352257600080fd5b81516fffffffffffffffffffffffffffffffff8116811461325e57600080fd5b828152604060208201526000610ee560408301846133da565b6000825161356d8184602087016133b6565b9190910192915050565b60006020828403121561358957600080fd5b5051919050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036135c1576135c16131d2565b5060010190565b6000816135d7576135d76131d2565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b8082028115828204841417610c8757610c876131d2565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000610ee560408301846133da565b60208152600061325e60208301846133da56fe4c69624469616d6f6e644375743a2041646420666163657420686173206e6f20636f64654c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a205265706c61636520666163657420686173206e6f20636f6465a2646970667358221220c5a8c10b22f20cde3fe0431ff57305237423677a60888f5b349fc6751336ae1464736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "Responsible for adding/removing/replace facets in Barz", + "kind": "dev", + "methods": { + "_checkDuplicateOnChainApprover(bytes32,address[])": { + "params": { + "_approvers": "List of approver addresses", + "_diamondCutHash": "Hash of diamondCut information including the facet addresses and function selectors" + } + }, + "approveDiamondCut((address,uint8,bytes4[])[])": { + "params": { + "_diamondCut": "Contains the facet addresses and function selectors" + } + }, + "constructor": { + "params": { + "_securityManager": "Security Manager contract that holds the security related variables for all wallets" + } + }, + "diamondCut((address,uint8,bytes4[])[],address,bytes)": { + "params": { + "_diamondCut": "Contains the facet addresses and function selectors", + "_init": "The address of the contract or facet to execute _calldata. It's prohibited in Barz" + } + }, + "diamondCutWithGuardian((address,uint8,bytes4[])[],address[],bytes[])": { + "params": { + "_approvers": "Guardian or owner address that approves the diamond cut", + "_diamondCut": "Contains the facet addresses and function selectors", + "_signatures": "Signature of Guardians or owner that approves the diamond cut" + } + }, + "getDiamondCutApprovalCountWithTimeValidity(bytes32)": { + "params": { + "_diamondCutHash": "Hash of diamondCut information including the facet addresses and function selectors" + } + }, + "getDiamondCutHash((address,uint8,bytes4[])[])": { + "params": { + "_diamondCut": "Contains the facet addresses and function selectors" + }, + "returns": { + "cutHash": "Diamond Cut Hash" + } + }, + "getDiamondCutNonce()": { + "details": "This method fetches the nonce from diamond cut storage", + "returns": { + "cutNonce": "Nonce of diamond cut to protect from reply attacks" + } + }, + "getOwnerCutApprovalWithTimeValidity(bytes32)": { + "params": { + "_diamondCutHash": "Hash of diamondCut information including the facet addresses and function selectors" + }, + "returns": { + "isApprovedByOwner": "Bool value showing if the owner approved the cut" + } + }, + "isCutApproved(bytes32,address)": { + "params": { + "_approver": "Address of approver", + "_diamondCutHash": "Hash of diamondCut information including the facet addresses and function selectors" + }, + "returns": { + "isApproved": "Bool value showing if the approver approved the cut" + } + }, + "revokeDiamondCutApproval((address,uint8,bytes4[])[])": { + "params": { + "_diamondCut": "Contains the facet addresses and function selectors" + } + }, + "updateSupportsInterface(bytes4,bool)": { + "params": { + "_flag": "Bool value to update the mapping of the given interface ID", + "_interfaceId": "InterfaceID to update the mapping" + } + } + }, + "title": "DiamondCut Facet", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "_checkDuplicateOnChainApprover(bytes32,address[])": { + "notice": "Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval Approvers who approved on-chain should not be included in the off-chain approval" + }, + "approveDiamondCut((address,uint8,bytes4[])[])": { + "notice": "Approves diamond cut. This can only be called directly from guardian or owner" + }, + "constructor": { + "notice": "This constructor sets the Security Manager address which is an immutable variable. Immutable variables do not impact the storage of diamond" + }, + "diamondCut((address,uint8,bytes4[])[],address,bytes)": { + "notice": "Add/replace/remove any number of functions and optionally execute a function with delegatecall when guardians don't exist" + }, + "diamondCutWithGuardian((address,uint8,bytes4[])[],address[],bytes[])": { + "notice": "Add/replace/remove any number of functions and optionally execute a function with delegatecall when guardians exist" + }, + "getDiamondCutApprovalCountWithTimeValidity(bytes32)": { + "notice": "Gets the number of approvals of diamond cut from guardians" + }, + "getDiamondCutHash((address,uint8,bytes4[])[])": { + "notice": "Returns the diamond cut hash. This function ensures that this hash is safe from replay attack by including salt, address, chainId, and nonce, etc." + }, + "getDiamondCutNonce()": { + "notice": "Returns the diamond cut nonce of this wallet" + }, + "getOwnerCutApprovalWithTimeValidity(bytes32)": { + "notice": "Returns if the owner has approved the diamond cut" + }, + "isCutApproved(bytes32,address)": { + "notice": "Returns if the given approver has approved the diamond cut" + }, + "revokeDiamondCutApproval((address,uint8,bytes4[])[])": { + "notice": "Revokes the approval of diamond cut. This can only be called directly from guardian or owner" + }, + "updateSupportsInterface(bytes4,bool)": { + "notice": "Updates the flag for the interfaceId" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 27823, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "s", + "offset": 0, + "slot": "0", + "type": "t_struct(AppStorage)27570_storage" + } + ], + "types": { + "t_bytes4": { + "encoding": "inplace", + "label": "bytes4", + "numberOfBytes": "4" + }, + "t_contract(IEntryPoint)12286": { + "encoding": "inplace", + "label": "contract IEntryPoint", + "numberOfBytes": "20" + }, + "t_contract(IFacetRegistry)26105": { + "encoding": "inplace", + "label": "contract IFacetRegistry", + "numberOfBytes": "20" + }, + "t_mapping(t_uint256,t_struct(InitializersStorage)27549_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => struct InitializersStorage)", + "numberOfBytes": "32", + "value": "t_struct(InitializersStorage)27549_storage" + }, + "t_mapping(t_uint256,t_struct(Lock)27542_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => struct Lock)", + "numberOfBytes": "32", + "value": "t_struct(Lock)27542_storage" + }, + "t_struct(AppStorage)27570_storage": { + "encoding": "inplace", + "label": "struct AppStorage", + "members": [ + { + "astId": 27554, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "initStorage", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_uint256,t_struct(InitializersStorage)27549_storage)" + }, + { + "astId": 27556, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "signerMigration", + "offset": 0, + "slot": "1", + "type": "t_uint8" + }, + { + "astId": 27558, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "validateOwnerSignatureSelector", + "offset": 1, + "slot": "1", + "type": "t_bytes4" + }, + { + "astId": 27561, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "entryPoint", + "offset": 5, + "slot": "1", + "type": "t_contract(IEntryPoint)12286" + }, + { + "astId": 27564, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "facetRegistry", + "offset": 0, + "slot": "2", + "type": "t_contract(IFacetRegistry)26105" + }, + { + "astId": 27569, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "locks", + "offset": 0, + "slot": "3", + "type": "t_mapping(t_uint256,t_struct(Lock)27542_storage)" + } + ], + "numberOfBytes": "128" + }, + "t_struct(InitializersStorage)27549_storage": { + "encoding": "inplace", + "label": "struct InitializersStorage", + "members": [ + { + "astId": 27544, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "signerInitialized", + "offset": 0, + "slot": "0", + "type": "t_uint8" + }, + { + "astId": 27546, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "accountInitialized", + "offset": 1, + "slot": "0", + "type": "t_uint8" + }, + { + "astId": 27548, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "restrictionsInitialized", + "offset": 2, + "slot": "0", + "type": "t_uint8" + } + ], + "numberOfBytes": "32" + }, + "t_struct(Lock)27542_storage": { + "encoding": "inplace", + "label": "struct Lock", + "members": [ + { + "astId": 27539, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "release", + "offset": 0, + "slot": "0", + "type": "t_uint64" + }, + { + "astId": 27541, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "locker", + "offset": 8, + "slot": "0", + "type": "t_bytes4" + } + ], + "numberOfBytes": "32" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint64": { + "encoding": "inplace", + "label": "uint64", + "numberOfBytes": "8" + }, + "t_uint8": { + "encoding": "inplace", + "label": "uint8", + "numberOfBytes": "1" + } + } + } +} \ No newline at end of file diff --git a/deployments/opBNB/DiamondLoupeFacet.json b/deployments/opBNB/DiamondLoupeFacet.json new file mode 100644 index 0000000..e974666 --- /dev/null +++ b/deployments/opBNB/DiamondLoupeFacet.json @@ -0,0 +1,306 @@ +{ + "address": "0xCe36b85d12D81cd619C745c7717f3396E184Ac7C", + "abi": [ + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_functionSelector", + "type": "bytes4" + } + ], + "name": "facetAddress", + "outputs": [ + { + "internalType": "address", + "name": "facetAddress_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_functionSelector", + "type": "bytes4" + } + ], + "name": "facetAddressFromStorage", + "outputs": [ + { + "internalType": "address", + "name": "facetAddress_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetAddresses", + "outputs": [ + { + "internalType": "address[]", + "name": "facetAddresses_", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetAddressesFromStorage", + "outputs": [ + { + "internalType": "address[]", + "name": "facetAddresses_", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_facet", + "type": "address" + } + ], + "name": "facetFunctionSelectors", + "outputs": [ + { + "internalType": "bytes4[]", + "name": "facetFunctionSelectors_", + "type": "bytes4[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_facet", + "type": "address" + } + ], + "name": "facetFunctionSelectorsFromStorage", + "outputs": [ + { + "internalType": "bytes4[]", + "name": "facetFunctionSelectors_", + "type": "bytes4[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facets", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondLoupe.Facet[]", + "name": "facets_", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetsFromStorage", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondLoupe.Facet[]", + "name": "facets_", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "isSupported", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0xefc3200054cf6d0f04f18857dd019effbfc3896d053caf0596f71cca8035c5ff", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 7, + "gasUsed": "2036373", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x2a427255c3939c7506231a69216bd1074a2ca4a382daa86e1e2ee3169bb88f2b", + "transactionHash": "0xefc3200054cf6d0f04f18857dd019effbfc3896d053caf0596f71cca8035c5ff", + "logs": [], + "blockNumber": 8731248, + "cumulativeGasUsed": "2701671", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 2, + "solcInputHash": "4356503edd8ae34e73cb6dd1c8e2fc8a", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_functionSelector\",\"type\":\"bytes4\"}],\"name\":\"facetAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"facetAddress_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_functionSelector\",\"type\":\"bytes4\"}],\"name\":\"facetAddressFromStorage\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"facetAddress_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetAddresses\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"facetAddresses_\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetAddressesFromStorage\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"facetAddresses_\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_facet\",\"type\":\"address\"}],\"name\":\"facetFunctionSelectors\",\"outputs\":[{\"internalType\":\"bytes4[]\",\"name\":\"facetFunctionSelectors_\",\"type\":\"bytes4[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_facet\",\"type\":\"address\"}],\"name\":\"facetFunctionSelectorsFromStorage\",\"outputs\":[{\"internalType\":\"bytes4[]\",\"name\":\"facetFunctionSelectors_\",\"type\":\"bytes4[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facets\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondLoupe.Facet[]\",\"name\":\"facets_\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetsFromStorage\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondLoupe.Facet[]\",\"name\":\"facets_\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isSupported\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"DiamondLoupe contract compatible with EIP-2535\",\"kind\":\"dev\",\"methods\":{\"facetAddress(bytes4)\":{\"details\":\"If facet is not found return address(0).\",\"params\":{\"_functionSelector\":\"The function selector.\"},\"returns\":{\"facetAddress_\":\"The facet address.\"}},\"facetAddressFromStorage(bytes4)\":{\"params\":{\"_functionSelector\":\"Function selector to fetch the facet address from diamond storage\"},\"returns\":{\"facetAddress_\":\"Facet address mapped with the function selector\"}},\"facetAddresses()\":{\"returns\":{\"facetAddresses_\":\"facetAddresses_\"}},\"facetAddressesFromStorage()\":{\"returns\":{\"facetAddresses_\":\"All facet addresses attached directly to diamond storage\"}},\"facetFunctionSelectors(address)\":{\"params\":{\"_facet\":\"The facet address.\"},\"returns\":{\"facetFunctionSelectors_\":\"facetFunctionSelectors_\"}},\"facetFunctionSelectorsFromStorage(address)\":{\"params\":{\"_facet\":\"Facet address to fetch the facet function selectors from diamond storage\"},\"returns\":{\"facetFunctionSelectors_\":\"Facet function selectors of the given facet address\"}},\"facets()\":{\"details\":\"Barz uses a special architecture called default fallback handler. Default Fallback handler is used as a middleware that holds the mapping of facet function selector and facet address that Barz uses. This helps Barz to reduce significant amount of gas during the initialization process. Hence, this method aggregates both the facet information from DefaulFallbackHandler and in diamond storage and shows the data to users.\",\"returns\":{\"facets_\":\"Facet\"}},\"facetsFromStorage()\":{\"returns\":{\"facets_\":\"Facet information attached directly to diamond storage\"}},\"supportsInterface(bytes4)\":{\"params\":{\"_interfaceId\":\"Interface ID for detecting the interface\"},\"returns\":{\"isSupported\":\"Bool value showing if the standard is supported in the contract\"}}},\"title\":\"DiamondLoupe Facet\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"facetAddress(bytes4)\":{\"notice\":\"Gets the facet that supports the given selector.\"},\"facetAddressFromStorage(bytes4)\":{\"notice\":\"Returns the facet address attached to the given function selector. This excludes the facets from the default fallback handler\"},\"facetAddresses()\":{\"notice\":\"Get all the facet addresses used by Barz.\"},\"facetAddressesFromStorage()\":{\"notice\":\"Returns all facet addresses attached directly to diamond storage. This excludes the facets from the default fallback handler\"},\"facetFunctionSelectors(address)\":{\"notice\":\"Gets all the function selectors provided by a facet.\"},\"facetFunctionSelectorsFromStorage(address)\":{\"notice\":\"Returns function selectors of given facet address attached directly to diamond storage. This excludes the facets from the default fallback handler\"},\"facets()\":{\"notice\":\"Gets all facets and their selectors.\"},\"facetsFromStorage()\":{\"notice\":\"Returns the facet from the diamond storage. This excludes the facets from the default fallback handler\"},\"supportsInterface(bytes4)\":{\"notice\":\"SupportInterface to be compatible with EIP 165\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/base/DiamondLoupeFacet.sol\":\"DiamondLoupeFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/introspection/IERC165.sol\\\";\\n\\n/**\\n * @dev _Available since v3.1._\\n */\\ninterface IERC1155Receiver is IERC165 {\\n /**\\n * @dev Handles the receipt of a single ERC1155 token type. This function is\\n * called at the end of a `safeTransferFrom` after the balance has been updated.\\n *\\n * NOTE: To accept the transfer, this must return\\n * `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))`\\n * (i.e. 0xf23a6e61, or its own function selector).\\n *\\n * @param operator The address which initiated the transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param id The ID of the token being transferred\\n * @param value The amount of tokens being transferred\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155Received(\\n address operator,\\n address from,\\n uint256 id,\\n uint256 value,\\n bytes calldata data\\n ) external returns (bytes4);\\n\\n /**\\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\\n * is called at the end of a `safeBatchTransferFrom` after the balances have\\n * been updated.\\n *\\n * NOTE: To accept the transfer(s), this must return\\n * `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))`\\n * (i.e. 0xbc197c81, or its own function selector).\\n *\\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155BatchReceived(\\n address operator,\\n address from,\\n uint256[] calldata ids,\\n uint256[] calldata values,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xeb373f1fdc7b755c6a750123a9b9e3a8a02c1470042fd6505d875000a80bde0b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title ERC721 token receiver interface\\n * @dev Interface for any contract that wants to support safeTransfers\\n * from ERC721 asset contracts.\\n */\\ninterface IERC721Receiver {\\n /**\\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\\n * by `operator` from `from`, this function is called.\\n *\\n * It must return its Solidity selector to confirm the token transfer.\\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\\n *\\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\\n */\\n function onERC721Received(\\n address operator,\\n address from,\\n uint256 tokenId,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\\n *\\n * Accounts can be notified of {IERC777} tokens being sent to them by having a\\n * contract implement this interface (contract holders can be their own\\n * implementer) and registering it on the\\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\\n *\\n * See {IERC1820Registry} and {ERC1820Implementer}.\\n */\\ninterface IERC777Recipient {\\n /**\\n * @dev Called by an {IERC777} token contract whenever tokens are being\\n * moved or created into a registered account (`to`). The type of operation\\n * is conveyed by `from` being the zero address or not.\\n *\\n * This call occurs _after_ the token contract's state is updated, so\\n * {IERC777-balanceOf}, etc., can be used to query the post-operation state.\\n *\\n * This function may revert to prevent the operation from being executed.\\n */\\n function tokensReceived(\\n address operator,\\n address from,\\n address to,\\n uint256 amount,\\n bytes calldata userData,\\n bytes calldata operatorData\\n ) external;\\n}\\n\",\"keccak256\":\"0x1a5d61db2733202ba361e6d6741cd2e662380e22b80e987eacfc91973f2267dc\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"contracts/facets/base/DiamondLoupeFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IERC777Recipient} from \\\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\\\";\\nimport {IERC165} from \\\"../../interfaces/ERC/IERC165.sol\\\";\\nimport {IERC1271} from \\\"../../interfaces/ERC/IERC1271.sol\\\";\\nimport {IERC677Receiver} from \\\"../../interfaces/ERC/IERC677Receiver.sol\\\";\\nimport {IERC721Receiver} from \\\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\\\";\\nimport {IERC1155Receiver} from \\\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\\\";\\nimport {LibDiamond} from \\\"../../libraries/LibDiamond.sol\\\";\\nimport {LibLoupe} from \\\"../../libraries/LibLoupe.sol\\\";\\nimport {LibUtils} from \\\"../../libraries/LibUtils.sol\\\";\\nimport {IDiamondCut} from \\\"../../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IStorageLoupe} from \\\"./interfaces/IStorageLoupe.sol\\\";\\nimport {IDiamondLoupe} from \\\"./interfaces/IDiamondLoupe.sol\\\";\\n\\n/**\\n * @title DiamondLoupe Facet\\n * @dev DiamondLoupe contract compatible with EIP-2535\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract DiamondLoupeFacet is IDiamondLoupe, IStorageLoupe, IERC165 {\\n // Diamond Loupe Functions\\n ////////////////////////////////////////////////////////////////////\\n /// These functions are expected to be called frequently by tools off-chain.\\n\\n /**\\n * @notice Gets all facets and their selectors.\\n * @dev Barz uses a special architecture called default fallback handler. Default Fallback handler is used as a middleware\\n * that holds the mapping of facet function selector and facet address that Barz uses. This helps Barz to reduce\\n * significant amount of gas during the initialization process.\\n * Hence, this method aggregates both the facet information from DefaulFallbackHandler and in diamond storage and shows the data to users.\\n * @return facets_ Facet\\n */\\n function facets() public view override returns (Facet[] memory facets_) {\\n Facet[] memory defaultFacet = LibDiamond\\n .diamondStorage()\\n .defaultFallbackHandler\\n .facets();\\n Facet[] memory _facets = LibLoupe.facets();\\n uint256 numFacets = _facets.length;\\n bytes4[] memory keys;\\n address[] memory values;\\n for (uint256 i; i < numFacets; ) {\\n uint256 selectorsLength = _facets[i].functionSelectors.length;\\n for (uint256 j; j < selectorsLength; ) {\\n (keys, values) = LibUtils.setValue(\\n keys,\\n values,\\n _facets[i].functionSelectors[j],\\n _facets[i].facetAddress\\n );\\n unchecked {\\n ++j;\\n }\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n {\\n bool iIncrement;\\n for (uint256 i; i < defaultFacet.length; ) {\\n bool jIncrement;\\n for (\\n uint256 j;\\n j < defaultFacet[i].functionSelectors.length;\\n\\n ) {\\n if (\\n LibUtils.getValue(\\n keys,\\n values,\\n defaultFacet[i].functionSelectors[j]\\n ) != address(0)\\n ) {\\n if (defaultFacet[i].functionSelectors.length == 1) {\\n defaultFacet = LibUtils.removeFacetElement(\\n defaultFacet,\\n i\\n );\\n iIncrement = true;\\n break;\\n }\\n defaultFacet[i].functionSelectors = LibUtils\\n .removeElement(\\n defaultFacet[i].functionSelectors,\\n j\\n );\\n jIncrement = true;\\n }\\n if (!jIncrement) {\\n unchecked {\\n ++j;\\n }\\n } else {\\n jIncrement = false;\\n }\\n }\\n if (!iIncrement) {\\n unchecked {\\n ++i;\\n }\\n } else {\\n iIncrement = false;\\n }\\n }\\n }\\n {\\n uint256 facetLength = numFacets + defaultFacet.length;\\n facets_ = new Facet[](facetLength);\\n uint256 defaultFacetIndex;\\n for (uint256 i; i < facetLength; ) {\\n if (i < numFacets) {\\n facets_[i] = _facets[i];\\n bool jIncrementor;\\n for (uint256 j; j < defaultFacet.length; ) {\\n if (\\n facets_[i].facetAddress ==\\n defaultFacet[j].facetAddress\\n ) {\\n facets_[i].functionSelectors = LibUtils.mergeArrays(\\n _facets[i].functionSelectors,\\n defaultFacet[j].functionSelectors\\n );\\n defaultFacet = LibUtils.removeFacetElement(\\n defaultFacet,\\n j\\n );\\n jIncrementor = true;\\n {\\n facets_ = LibUtils.removeFacetElement(\\n facets_,\\n facets_.length - 1\\n );\\n }\\n --facetLength;\\n }\\n if (!jIncrementor) {\\n unchecked {\\n ++j;\\n }\\n } else {\\n jIncrementor = false;\\n }\\n }\\n } else {\\n facets_[i] = defaultFacet[defaultFacetIndex];\\n ++defaultFacetIndex;\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n }\\n\\n /**\\n * @notice Gets all the function selectors provided by a facet.\\n * @param _facet The facet address.\\n * @return facetFunctionSelectors_\\n */\\n function facetFunctionSelectors(\\n address _facet\\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\\n Facet[] memory facet = facets();\\n uint256 facetLength = facet.length;\\n for (uint256 i; i < facetLength; ) {\\n if (facet[i].facetAddress == _facet)\\n return facet[i].functionSelectors;\\n unchecked {\\n ++i;\\n }\\n }\\n return facetFunctionSelectors_;\\n }\\n\\n /**\\n * @notice Get all the facet addresses used by Barz.\\n * @return facetAddresses_\\n */\\n function facetAddresses()\\n external\\n view\\n override\\n returns (address[] memory facetAddresses_)\\n {\\n Facet[] memory facet = facets();\\n uint256 facetLength = facet.length;\\n facetAddresses_ = new address[](facetLength);\\n for (uint256 i; i < facetLength; ) {\\n facetAddresses_[i] = facet[i].facetAddress;\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * @notice Gets the facet that supports the given selector.\\n * @dev If facet is not found return address(0).\\n * @param _functionSelector The function selector.\\n * @return facetAddress_ The facet address.\\n */\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view override returns (address facetAddress_) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n\\n facetAddress_ = address(bytes20(ds.facets[_functionSelector]));\\n if (facetAddress_ == address(0)) {\\n facetAddress_ = IDiamondLoupe(ds.defaultFallbackHandler)\\n .facetAddress(_functionSelector);\\n }\\n }\\n\\n /**\\n * @notice SupportInterface to be compatible with EIP 165\\n * @param _interfaceId Interface ID for detecting the interface\\n * @return isSupported Bool value showing if the standard is supported in the contract\\n */\\n function supportsInterface(\\n bytes4 _interfaceId\\n ) external view override returns (bool isSupported) {\\n isSupported =\\n _interfaceId == type(IERC165).interfaceId ||\\n _interfaceId == IDiamondCut.diamondCut.selector ||\\n _interfaceId == type(IDiamondLoupe).interfaceId ||\\n _interfaceId == type(IERC1155Receiver).interfaceId ||\\n _interfaceId == type(IERC721Receiver).interfaceId ||\\n _interfaceId == type(IERC777Recipient).interfaceId ||\\n _interfaceId == IERC1271.isValidSignature.selector ||\\n _interfaceId == type(IERC677Receiver).interfaceId ||\\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId];\\n }\\n\\n /**\\n * @notice Returns the facet from the diamond storage. This excludes the facets from the default fallback handler\\n * @return facets_ Facet information attached directly to diamond storage\\n */\\n function facetsFromStorage()\\n external\\n view\\n override\\n returns (Facet[] memory facets_)\\n {\\n facets_ = LibLoupe.facets();\\n }\\n\\n /**\\n * @notice Returns the facet address attached to the given function selector. This excludes the facets from the default fallback handler\\n * @param _functionSelector Function selector to fetch the facet address from diamond storage\\n * @return facetAddress_ Facet address mapped with the function selector\\n */\\n function facetAddressFromStorage(\\n bytes4 _functionSelector\\n ) external view override returns (address facetAddress_) {\\n facetAddress_ = LibLoupe.facetAddress(_functionSelector);\\n }\\n\\n /**\\n * @notice Returns all facet addresses attached directly to diamond storage. This excludes the facets from the default fallback handler\\n * @return facetAddresses_ All facet addresses attached directly to diamond storage\\n */\\n function facetAddressesFromStorage()\\n external\\n view\\n override\\n returns (address[] memory facetAddresses_)\\n {\\n facetAddresses_ = LibLoupe.facetAddresses();\\n }\\n\\n /**\\n * @notice Returns function selectors of given facet address attached directly to diamond storage. This excludes the facets from the default fallback handler\\n * @param _facet Facet address to fetch the facet function selectors from diamond storage\\n * @return facetFunctionSelectors_ Facet function selectors of the given facet address\\n */\\n function facetFunctionSelectorsFromStorage(\\n address _facet\\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\\n facetFunctionSelectors_ = LibLoupe.facetFunctionSelectors(_facet);\\n }\\n}\\n\",\"keccak256\":\"0xf392fde159eec6483fc15fa323ecd6d764028f5b8734a66662c4116292363794\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IStorageLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"./IDiamondLoupe.sol\\\";\\n\\n/**\\n * @title LoupeFromStorage Interface\\n * @dev Interface contract to function as a loupe facet directly attached to diamond storage of Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IStorageLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facetsFromStorage()\\n external\\n view\\n returns (IDiamondLoupe.Facet[] memory);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n function facetFunctionSelectorsFromStorage(\\n address _facet\\n ) external view returns (bytes4[] memory);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n function facetAddressesFromStorage()\\n external\\n view\\n returns (address[] memory);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n function facetAddressFromStorage(\\n bytes4 _functionSelector\\n ) external view returns (address);\\n}\\n\",\"keccak256\":\"0xdf5dc9c57319e9087628c9cf9404b4f75585b76d1c2f4f59ee796c933967ea5c\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC1271 {\\n function isValidSignature(\\n bytes32 hash,\\n bytes memory signature\\n ) external view returns (bytes4);\\n}\\n\",\"keccak256\":\"0xcdddb7d5641c9d3f2432dec7fd13fddb9ae1480f25c76c21511e2fa16b8bd422\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.21;\\n\\ninterface IERC165 {\\n /// @notice Query if a contract implements an interface\\n /// @param interfaceId The interface identifier, as specified in ERC-165\\n /// @dev Interface identification is specified in ERC-165. This function\\n /// uses less than 30,000 gas.\\n /// @return `true` if the contract implements `interfaceID` and\\n /// `interfaceID` is not 0xffffffff, `false` otherwise\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xbb7f07e170898793c5535cc4b7e8944c4b990a631ac806d0b788e794abc788a3\",\"license\":\"MIT\"},\"contracts/interfaces/ERC/IERC677Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC677Receiver {\\n function onTokenTransfer(\\n address sender,\\n uint value,\\n bytes calldata data\\n ) external pure returns (bool);\\n}\\n\",\"keccak256\":\"0x4c1631cf45ea6daac0ec158c3edb9453099130b6b64f697004b83f95aa1f7350\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\\n bytes4(keccak256(\\\"verifyRestrictions(address,address,uint256,bytes)\\\"));\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // Default Fallback Handler of the barz.\\n IDiamondLoupe defaultFallbackHandler;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function enforceIsSelf() internal view {\\n require(msg.sender == address(this), \\\"LibDiamond: Caller not self\\\");\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n\\n unchecked {\\n facetIndex++;\\n }\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n\\n function restrictionsFacet() internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(\\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2cabdc00de859c3a3170ce3bda5d0e5fd3933d47ce904fd1585f9818b02572f8\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\nimport {LibDiamond} from \\\"./LibDiamond.sol\\\";\\n\\n/**\\n * @title LibLoupe\\n * @dev Internal Library to provide utility feature for reading the state of diamond facets\\n * Originally from Diamond's implementation of Mudgen(author of EIP-2535)\\n */\\nlibrary LibLoupe {\\n /// @notice Gets all facets and their selectors.\\n /// @return facets_ Facet\\n function facets()\\n internal\\n view\\n returns (IDiamondLoupe.Facet[] memory facets_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facets_ = new IDiamondLoupe.Facet[](ds.selectorCount);\\n uint16[] memory numFacetSelectors = new uint16[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facets_[facetIndex].facetAddress == facetAddress_) {\\n facets_[facetIndex].functionSelectors[\\n numFacetSelectors[facetIndex]\\n ] = selector;\\n // probably will never have more than 256 functions from one facet contract\\n require(numFacetSelectors[facetIndex] < 255);\\n numFacetSelectors[facetIndex]++;\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facets_[numFacets].facetAddress = facetAddress_;\\n facets_[numFacets].functionSelectors = new bytes4[](\\n ds.selectorCount\\n );\\n facets_[numFacets].functionSelectors[0] = selector;\\n numFacetSelectors[numFacets] = 1;\\n numFacets++;\\n }\\n }\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n uint256 numSelectors = numFacetSelectors[facetIndex];\\n bytes4[] memory selectors = facets_[facetIndex].functionSelectors;\\n // setting the number of selectors\\n assembly {\\n mstore(selectors, numSelectors)\\n }\\n }\\n // setting the number of facets\\n assembly {\\n mstore(facets_, numFacets)\\n }\\n }\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return _facetFunctionSelectors The selectors associated with a facet address.\\n function facetFunctionSelectors(\\n address _facet\\n ) internal view returns (bytes4[] memory _facetFunctionSelectors) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n uint256 numSelectors;\\n _facetFunctionSelectors = new bytes4[](ds.selectorCount);\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facet = address(bytes20(ds.facets[selector]));\\n if (_facet == facet) {\\n _facetFunctionSelectors[numSelectors] = selector;\\n numSelectors++;\\n }\\n }\\n }\\n // Set the number of selectors in the array\\n assembly {\\n mstore(_facetFunctionSelectors, numSelectors)\\n }\\n }\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n internal\\n view\\n returns (address[] memory facetAddresses_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetAddresses_ = new address[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facetAddress_ == facetAddresses_[facetIndex]) {\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facetAddresses_[numFacets] = facetAddress_;\\n numFacets++;\\n }\\n }\\n // Set the number of facet addresses in the array\\n assembly {\\n mstore(facetAddresses_, numFacets)\\n }\\n }\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(LibDiamond.diamondStorage().facets[_functionSelector])\\n );\\n }\\n}\\n\",\"keccak256\":\"0x0b11439c3cc657095e15ec2241fdcf67204b14001357b612fc5db4ff9e760a5a\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibUtils.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nlibrary LibUtils {\\n // Internal utility functions\\n function mergeArrays(\\n bytes4[] memory _array1,\\n bytes4[] memory _array2\\n ) internal pure returns (bytes4[] memory) {\\n uint256 length1 = _array1.length;\\n uint256 length2 = _array2.length;\\n bytes4[] memory mergedArray = new bytes4[](length1 + length2);\\n\\n for (uint256 i; i < length1; ) {\\n mergedArray[i] = _array1[i];\\n unchecked {\\n ++i;\\n }\\n }\\n\\n for (uint256 i; i < length2; ) {\\n mergedArray[length1 + i] = _array2[i];\\n unchecked {\\n ++i;\\n }\\n }\\n\\n return mergedArray;\\n }\\n\\n function removeFacetElement(\\n IDiamondLoupe.Facet[] memory _facets,\\n uint256 _index\\n ) internal pure returns (IDiamondLoupe.Facet[] memory) {\\n require(_index < _facets.length, \\\"Invalid index\\\");\\n require(_facets.length != 0, \\\"Invalid array\\\");\\n\\n // Create a new array with a length of `_facets.length - 1`\\n IDiamondLoupe.Facet[] memory newArray = new IDiamondLoupe.Facet[](\\n _facets.length - 1\\n );\\n uint256 newArrayLength = newArray.length;\\n // Iterate over the original array, skipping the element at the specified `index`\\n for (uint256 i; i < newArrayLength; ) {\\n if (i < _index) {\\n newArray[i] = _facets[i];\\n } else {\\n newArray[i] = _facets[i + 1];\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n\\n return newArray;\\n }\\n\\n function removeElement(\\n bytes4[] memory _array,\\n uint256 _index\\n ) internal pure returns (bytes4[] memory) {\\n require(_index < _array.length, \\\"Invalid index\\\");\\n require(_array.length != 0, \\\"Invalid array\\\");\\n\\n bytes4[] memory newArray = new bytes4[](_array.length - 1);\\n uint256 newArrayLength = newArray.length;\\n for (uint256 i; i < newArrayLength; ) {\\n if (i < _index) {\\n newArray[i] = _array[i];\\n } else {\\n newArray[i] = _array[i + 1];\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n\\n return newArray;\\n }\\n\\n function setValue(\\n bytes4[] memory _keys,\\n address[] memory _values,\\n bytes4 _key,\\n address _value\\n ) internal pure returns (bytes4[] memory, address[] memory) {\\n uint256 index = findIndex(_keys, _key);\\n uint256 keysLength = _keys.length;\\n if (index < keysLength) {\\n _values[index] = _value;\\n } else {\\n // Create new storage arrays\\n bytes4[] memory newKeys = new bytes4[](keysLength + 1);\\n address[] memory newValues = new address[](_values.length + 1);\\n\\n // Copy values to the new storage arrays\\n for (uint256 i; i < keysLength; ) {\\n newKeys[i] = _keys[i];\\n newValues[i] = _values[i];\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n // Add the new key-value pair\\n newKeys[keysLength] = _key;\\n newValues[_values.length] = _value;\\n\\n return (newKeys, newValues);\\n }\\n\\n // If the key already exists, return the original arrays\\n return (_keys, _values);\\n }\\n\\n function getValue(\\n bytes4[] memory _keys,\\n address[] memory _values,\\n bytes4 _key\\n ) internal pure returns (address) {\\n uint256 index = findIndex(_keys, _key);\\n if (index >= _keys.length) return address(0);\\n\\n return _values[index];\\n }\\n\\n function findIndex(\\n bytes4[] memory _keys,\\n bytes4 _key\\n ) internal pure returns (uint256) {\\n uint256 keysLength = _keys.length;\\n for (uint256 i; i < keysLength; ) {\\n if (_keys[i] == _key) {\\n return i;\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n return keysLength;\\n }\\n}\\n\",\"keccak256\":\"0xde8aeefe54c4be483f2b2c055aca11e2830f7094c0586a82e10ec544933b5714\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5061240b806100206000396000f3fe608060405234801561001057600080fd5b50600436106100a35760003560e01c8063adfca15e11610076578063d42139a91161005b578063d42139a914610169578063e3a2f6fe14610171578063f9796ccf1461018457600080fd5b8063adfca15e1461011e578063cdffacc61461013157600080fd5b806301a55022146100a857806301ffc9a7146100d157806352ef6b2c146100f45780637a0ed62714610109575b600080fd5b6100bb6100b6366004611e4b565b61018c565b6040516100c89190611e68565b60405180910390f35b6100e46100df366004611efc565b61019d565b60405190151581526020016100c8565b6100fc610454565b6040516100c89190611f19565b610111610518565b6040516100c89190611f67565b6100bb61012c366004611e4b565b610a63565b61014461013f366004611efc565b610b07565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100c8565b6100fc610c24565b61014461017f366004611efc565b610c33565b610111610c8c565b606061019782610c96565b92915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000148061023057507fffffffff0000000000000000000000000000000000000000000000000000000082167f1f931c1c00000000000000000000000000000000000000000000000000000000145b8061027c57507fffffffff0000000000000000000000000000000000000000000000000000000082167f48e2b09300000000000000000000000000000000000000000000000000000000145b806102c857507fffffffff0000000000000000000000000000000000000000000000000000000082167f4e2312e000000000000000000000000000000000000000000000000000000000145b8061031457507fffffffff0000000000000000000000000000000000000000000000000000000082167f150b7a0200000000000000000000000000000000000000000000000000000000145b8061035f57507fffffffff0000000000000000000000000000000000000000000000000000000082167e23de2900000000000000000000000000000000000000000000000000000000145b806103ab57507fffffffff0000000000000000000000000000000000000000000000000000000082167f1626ba7e00000000000000000000000000000000000000000000000000000000145b806103f757507fffffffff0000000000000000000000000000000000000000000000000000000082167fa4c0ed3600000000000000000000000000000000000000000000000000000000145b806101975750507fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4922602052604090205460ff1690565b60606000610460610518565b80519091508067ffffffffffffffff81111561047e5761047e61205d565b6040519080825280602002602001820160405280156104a7578160200160208202803683370190505b50925060005b81811015610512578281815181106104c7576104c761208c565b6020026020010151600001518482815181106104e5576104e561208c565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526001016104ad565b50505090565b606060007f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f600490810154604080517f7a0ed627000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff90921692637a0ed6279282820192600092908290030181865afa1580156105ac573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526105f29190810190612157565b905060006105fe610e57565b805190915060608060005b838110156106b55760008582815181106106255761062561208c565b60200260200101516020015151905060005b818110156106ab5761069e85858986815181106106565761065661208c565b60200260200101516020015184815181106106735761067361208c565b60200260200101518a878151811061068d5761068d61208c565b60200260200101516000015161134a565b9095509350600101610637565b5050600101610609565b506000805b865181101561081b576000805b8883815181106106d9576106d961208c565b602002602001015160200151518110156107ff57600073ffffffffffffffffffffffffffffffffffffffff1661074687878c878151811061071c5761071c61208c565b60200260200101516020015185815181106107395761073961208c565b60200260200101516115f1565b73ffffffffffffffffffffffffffffffffffffffff16146107e9578883815181106107735761077361208c565b6020026020010151602001515160010361079c576107918984611637565b9850600193506107ff565b6107c38984815181106107b1576107b161208c565b6020026020010151602001518261182a565b8984815181106107d5576107d561208c565b602002602001015160200181905250600191505b816107f6576001016106c7565b600091506106c7565b508261081057816001019150610815565b600092505b506106ba565b5050600085518461082c9190612304565b90508067ffffffffffffffff8111156108475761084761205d565b60405190808252806020026020018201604052801561088d57816020015b6040805180820190915260008152606060208201528152602001906001900390816108655790505b5096506000805b82811015610a585785811015610a0c578681815181106108b6576108b661208c565b60200260200101518982815181106108d0576108d061208c565b60200260200101819052506000805b8951811015610a05578981815181106108fa576108fa61208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff168b848151811061092e5761092e61208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff16036109ef5761099989848151811061096a5761096a61208c565b6020026020010151602001518b83815181106109885761098861208c565b602002602001015160200151611a3d565b8b84815181106109ab576109ab61208c565b6020026020010151602001819052506109c48a82611637565b9950600191506109e18b60018d516109dc9190612317565b611637565b9a506109ec8561232a565b94505b816109fc576001016108df565b600091506108df565b5050610a50565b878281518110610a1e57610a1e61208c565b6020026020010151898281518110610a3857610a3861208c565b602002602001018190525081610a4d9061235f565b91505b600101610894565b505050505050505090565b60606000610a6f610518565b805190915060005b81811015610aff578473ffffffffffffffffffffffffffffffffffffffff16838281518110610aa857610aa861208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1603610af757828181518110610ae157610ae161208c565b6020026020010151602001519350505050919050565b600101610a77565b505050919050565b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602081905260409091205460601c9081610c1e576004818101546040517fcdffacc60000000000000000000000000000000000000000000000000000000081527fffffffff0000000000000000000000000000000000000000000000000000000086169281019290925273ffffffffffffffffffffffffffffffffffffffff169063cdffacc690602401602060405180830381865afa158015610bf7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c1b9190612397565b91505b50919050565b6060610c2e611b8b565b905090565b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604081205460601c610197565b6060610c2e610e57565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9060009061ffff1667ffffffffffffffff811115610cfc57610cfc61205d565b604051908082528060200260200182016040528015610d25578160200160208202803683370190505b5092506000805b600284015461ffff16821015610e4d576000818152600185016020526040812054905b6008811015610e385783610d628161235f565b600288015490955061ffff1685119050610e3857600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020889052604090205460601c73ffffffffffffffffffffffffffffffffffffffff8a16819003610e235781898881518110610de457610de461208c565b7fffffffff000000000000000000000000000000000000000000000000000000009092166020928302919091019091015286610e1f8161235f565b9750505b50508080610e309061235f565b915050610d4f565b50508080610e459061235f565b915050610d2c565b5050825250919050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff1667ffffffffffffffff811115610eba57610eba61205d565b604051908082528060200260200182016040528015610f0057816020015b604080518082019091526000815260606020820152815260200190600190039081610ed85790505b50600282015490925060009061ffff1667ffffffffffffffff811115610f2857610f2861205d565b604051908082528060200260200182016040528015610f51578160200160208202803683370190505b50905060008060005b600285015461ffff168210156112d7576000818152600186016020526040812054905b60088110156112c25783610f908161235f565b600289015490955061ffff16851190506112c257600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020899052604081205460601c90805b88811015611148578273ffffffffffffffffffffffffffffffffffffffff168c82815181106110155761101561208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff160361113657838c828151811061104f5761104f61208c565b6020026020010151602001518b838151811061106d5761106d61208c565b602002602001015161ffff16815181106110895761108961208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152505060ff8a82815181106110e9576110e961208c565b602002602001015161ffff16106110ff57600080fd5b8981815181106111115761111161208c565b602002602001018051809190611126906123b4565b61ffff1690525060019150611148565b806111408161235f565b915050610fe4565b508015611157575050506112b0565b818b898151811061116a5761116a61208c565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff909116905260028a015461ffff1667ffffffffffffffff8111156111b0576111b061205d565b6040519080825280602002602001820160405280156111d9578160200160208202803683370190505b508b89815181106111ec576111ec61208c565b602002602001015160200181905250828b898151811061120e5761120e61208c565b60200260200101516020015160008151811061122c5761122c61208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681525050600189898151811061128c5761128c61208c565b61ffff90921660209283029190910190910152876112a98161235f565b9850505050505b806112ba8161235f565b915050610f7d565b505080806112cf9061235f565b915050610f5a565b5060005b8281101561133f5760008482815181106112f7576112f761208c565b602002602001015161ffff16905060008783815181106113195761131961208c565b6020026020010151602001519050818152505080806113379061235f565b9150506112db565b508185525050505090565b60608060006113598786611da0565b8751909150808210156113b857848783815181106113795761137961208c565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250506115df565b60006113c5826001612304565b67ffffffffffffffff8111156113dd576113dd61205d565b604051908082528060200260200182016040528015611406578160200160208202803683370190505b5090506000885160016114199190612304565b67ffffffffffffffff8111156114315761143161205d565b60405190808252806020026020018201604052801561145a578160200160208202803683370190505b50905060005b83811015611539578a818151811061147a5761147a61208c565b60200260200101518382815181106114945761149461208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815250508981815181106114f2576114f261208c565b602002602001015182828151811061150c5761150c61208c565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101611460565b508782848151811061154d5761154d61208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152505086818a51815181106115ad576115ad61208c565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015290945092506115e8915050565b87879350935050505b94509492505050565b6000806115fe8584611da0565b905084518110611612576000915050611630565b8381815181106116245761162461208c565b60200260200101519150505b9392505050565b6060825182106116a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420696e6465780000000000000000000000000000000000000060448201526064015b60405180910390fd5b8251600003611713576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420617272617900000000000000000000000000000000000000604482015260640161169f565b6000600184516117239190612317565b67ffffffffffffffff81111561173b5761173b61205d565b60405190808252806020026020018201604052801561178157816020015b6040805180820190915260008152606060208201528152602001906001900390816117595790505b50805190915060005b8181101561182057848110156117d6578581815181106117ac576117ac61208c565b60200260200101518382815181106117c6576117c661208c565b6020026020010181905250611818565b856117e2826001612304565b815181106117f2576117f261208c565b602002602001015183828151811061180c5761180c61208c565b60200260200101819052505b60010161178a565b5090949350505050565b606082518210611896576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420696e64657800000000000000000000000000000000000000604482015260640161169f565b8251600003611901576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420617272617900000000000000000000000000000000000000604482015260640161169f565b6000600184516119119190612317565b67ffffffffffffffff8111156119295761192961205d565b604051908082528060200260200182016040528015611952578160200160208202803683370190505b50805190915060005b8181101561182057848110156119cd5785818151811061197d5761197d61208c565b60200260200101518382815181106119975761199761208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152611a35565b856119d9826001612304565b815181106119e9576119e961208c565b6020026020010151838281518110611a0357611a0361208c565b7fffffffff00000000000000000000000000000000000000000000000000000000909216602092830291909101909101525b60010161195b565b81518151606091906000611a518284612304565b67ffffffffffffffff811115611a6957611a6961205d565b604051908082528060200260200182016040528015611a92578160200160208202803683370190505b50905060005b83811015611b0557868181518110611ab257611ab261208c565b6020026020010151828281518110611acc57611acc61208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152600101611a98565b5060005b82811015611b8157858181518110611b2357611b2361208c565b6020026020010151828286611b389190612304565b81518110611b4857611b4861208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152600101611b09565b5095945050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff1667ffffffffffffffff811115611bee57611bee61205d565b604051908082528060200260200182016040528015611c17578160200160208202803683370190505b50915060008060005b600284015461ffff16821015611d98576000818152600185016020526040812054905b6008811015611d835783611c568161235f565b600288015490955061ffff1685119050611d8357600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020889052604081205460601c90805b88811015611d19578a8181518110611cc457611cc461208c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611d075760019150611d19565b80611d118161235f565b915050611caa565b508015611d2857505050611d71565b818a8981518110611d3b57611d3b61208c565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015287611d6a8161235f565b9850505050505b80611d7b8161235f565b915050611c43565b50508080611d909061235f565b915050611c20565b505082525090565b8151600090815b81811015611e1e57837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916858281518110611de157611de161208c565b60200260200101517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603611e165791506101979050565b600101611da7565b509392505050565b73ffffffffffffffffffffffffffffffffffffffff81168114611e4857600080fd5b50565b600060208284031215611e5d57600080fd5b813561163081611e26565b6020808252825182820181905260009190848201906040850190845b81811015611ec25783517fffffffff000000000000000000000000000000000000000000000000000000001683529284019291840191600101611e84565b50909695505050505050565b7fffffffff0000000000000000000000000000000000000000000000000000000081168114611e4857600080fd5b600060208284031215611f0e57600080fd5b813561163081611ece565b6020808252825182820181905260009190848201906040850190845b81811015611ec257835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101611f35565b60006020808301818452808551808352604092508286019150828160051b8701018488016000805b8481101561204e578984037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00186528251805173ffffffffffffffffffffffffffffffffffffffff168552880151888501889052805188860181905290890190839060608701905b808310156120395783517fffffffff00000000000000000000000000000000000000000000000000000000168252928b019260019290920191908b0190611ff7565b50978a01979550505091870191600101611f8f565b50919998505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6040805190810167ffffffffffffffff811182821017156120de576120de61205d565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561212b5761212b61205d565b604052919050565b600067ffffffffffffffff82111561214d5761214d61205d565b5060051b60200190565b6000602080838503121561216a57600080fd5b825167ffffffffffffffff8082111561218257600080fd5b818501915085601f83011261219657600080fd5b81516121a96121a482612133565b6120e4565b81815260059190911b830184019084810190888311156121c857600080fd5b8585015b838110156122c8578051858111156121e45760008081fd5b86016040818c037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00181131561221a5760008081fd5b6122226120bb565b8983015161222f81611e26565b815282820151888111156122435760008081fd5b8084019350508c603f8401126122595760008081fd5b898301516122696121a482612133565b81815260059190911b84018301908b8101908f8311156122895760008081fd5b948401945b828610156122b357855194506122a385611ece565b848252948c0194908c019061228e565b838d01525050855250509186019186016121cc565b5098975050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610197576101976122d5565b81810381811115610197576101976122d5565b600081612339576123396122d5565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612390576123906122d5565b5060010190565b6000602082840312156123a957600080fd5b815161163081611e26565b600061ffff8083168181036123cb576123cb6122d5565b600101939250505056fea26469706673582212205959d8d85aad6f29d5fc37d5a52c404c25392cec49195c3b761da0e863e99b0f64736f6c63430008150033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100a35760003560e01c8063adfca15e11610076578063d42139a91161005b578063d42139a914610169578063e3a2f6fe14610171578063f9796ccf1461018457600080fd5b8063adfca15e1461011e578063cdffacc61461013157600080fd5b806301a55022146100a857806301ffc9a7146100d157806352ef6b2c146100f45780637a0ed62714610109575b600080fd5b6100bb6100b6366004611e4b565b61018c565b6040516100c89190611e68565b60405180910390f35b6100e46100df366004611efc565b61019d565b60405190151581526020016100c8565b6100fc610454565b6040516100c89190611f19565b610111610518565b6040516100c89190611f67565b6100bb61012c366004611e4b565b610a63565b61014461013f366004611efc565b610b07565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100c8565b6100fc610c24565b61014461017f366004611efc565b610c33565b610111610c8c565b606061019782610c96565b92915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000148061023057507fffffffff0000000000000000000000000000000000000000000000000000000082167f1f931c1c00000000000000000000000000000000000000000000000000000000145b8061027c57507fffffffff0000000000000000000000000000000000000000000000000000000082167f48e2b09300000000000000000000000000000000000000000000000000000000145b806102c857507fffffffff0000000000000000000000000000000000000000000000000000000082167f4e2312e000000000000000000000000000000000000000000000000000000000145b8061031457507fffffffff0000000000000000000000000000000000000000000000000000000082167f150b7a0200000000000000000000000000000000000000000000000000000000145b8061035f57507fffffffff0000000000000000000000000000000000000000000000000000000082167e23de2900000000000000000000000000000000000000000000000000000000145b806103ab57507fffffffff0000000000000000000000000000000000000000000000000000000082167f1626ba7e00000000000000000000000000000000000000000000000000000000145b806103f757507fffffffff0000000000000000000000000000000000000000000000000000000082167fa4c0ed3600000000000000000000000000000000000000000000000000000000145b806101975750507fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4922602052604090205460ff1690565b60606000610460610518565b80519091508067ffffffffffffffff81111561047e5761047e61205d565b6040519080825280602002602001820160405280156104a7578160200160208202803683370190505b50925060005b81811015610512578281815181106104c7576104c761208c565b6020026020010151600001518482815181106104e5576104e561208c565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526001016104ad565b50505090565b606060007f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f600490810154604080517f7a0ed627000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff90921692637a0ed6279282820192600092908290030181865afa1580156105ac573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526105f29190810190612157565b905060006105fe610e57565b805190915060608060005b838110156106b55760008582815181106106255761062561208c565b60200260200101516020015151905060005b818110156106ab5761069e85858986815181106106565761065661208c565b60200260200101516020015184815181106106735761067361208c565b60200260200101518a878151811061068d5761068d61208c565b60200260200101516000015161134a565b9095509350600101610637565b5050600101610609565b506000805b865181101561081b576000805b8883815181106106d9576106d961208c565b602002602001015160200151518110156107ff57600073ffffffffffffffffffffffffffffffffffffffff1661074687878c878151811061071c5761071c61208c565b60200260200101516020015185815181106107395761073961208c565b60200260200101516115f1565b73ffffffffffffffffffffffffffffffffffffffff16146107e9578883815181106107735761077361208c565b6020026020010151602001515160010361079c576107918984611637565b9850600193506107ff565b6107c38984815181106107b1576107b161208c565b6020026020010151602001518261182a565b8984815181106107d5576107d561208c565b602002602001015160200181905250600191505b816107f6576001016106c7565b600091506106c7565b508261081057816001019150610815565b600092505b506106ba565b5050600085518461082c9190612304565b90508067ffffffffffffffff8111156108475761084761205d565b60405190808252806020026020018201604052801561088d57816020015b6040805180820190915260008152606060208201528152602001906001900390816108655790505b5096506000805b82811015610a585785811015610a0c578681815181106108b6576108b661208c565b60200260200101518982815181106108d0576108d061208c565b60200260200101819052506000805b8951811015610a05578981815181106108fa576108fa61208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff168b848151811061092e5761092e61208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff16036109ef5761099989848151811061096a5761096a61208c565b6020026020010151602001518b83815181106109885761098861208c565b602002602001015160200151611a3d565b8b84815181106109ab576109ab61208c565b6020026020010151602001819052506109c48a82611637565b9950600191506109e18b60018d516109dc9190612317565b611637565b9a506109ec8561232a565b94505b816109fc576001016108df565b600091506108df565b5050610a50565b878281518110610a1e57610a1e61208c565b6020026020010151898281518110610a3857610a3861208c565b602002602001018190525081610a4d9061235f565b91505b600101610894565b505050505050505090565b60606000610a6f610518565b805190915060005b81811015610aff578473ffffffffffffffffffffffffffffffffffffffff16838281518110610aa857610aa861208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1603610af757828181518110610ae157610ae161208c565b6020026020010151602001519350505050919050565b600101610a77565b505050919050565b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602081905260409091205460601c9081610c1e576004818101546040517fcdffacc60000000000000000000000000000000000000000000000000000000081527fffffffff0000000000000000000000000000000000000000000000000000000086169281019290925273ffffffffffffffffffffffffffffffffffffffff169063cdffacc690602401602060405180830381865afa158015610bf7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c1b9190612397565b91505b50919050565b6060610c2e611b8b565b905090565b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604081205460601c610197565b6060610c2e610e57565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9060009061ffff1667ffffffffffffffff811115610cfc57610cfc61205d565b604051908082528060200260200182016040528015610d25578160200160208202803683370190505b5092506000805b600284015461ffff16821015610e4d576000818152600185016020526040812054905b6008811015610e385783610d628161235f565b600288015490955061ffff1685119050610e3857600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020889052604090205460601c73ffffffffffffffffffffffffffffffffffffffff8a16819003610e235781898881518110610de457610de461208c565b7fffffffff000000000000000000000000000000000000000000000000000000009092166020928302919091019091015286610e1f8161235f565b9750505b50508080610e309061235f565b915050610d4f565b50508080610e459061235f565b915050610d2c565b5050825250919050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff1667ffffffffffffffff811115610eba57610eba61205d565b604051908082528060200260200182016040528015610f0057816020015b604080518082019091526000815260606020820152815260200190600190039081610ed85790505b50600282015490925060009061ffff1667ffffffffffffffff811115610f2857610f2861205d565b604051908082528060200260200182016040528015610f51578160200160208202803683370190505b50905060008060005b600285015461ffff168210156112d7576000818152600186016020526040812054905b60088110156112c25783610f908161235f565b600289015490955061ffff16851190506112c257600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020899052604081205460601c90805b88811015611148578273ffffffffffffffffffffffffffffffffffffffff168c82815181106110155761101561208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff160361113657838c828151811061104f5761104f61208c565b6020026020010151602001518b838151811061106d5761106d61208c565b602002602001015161ffff16815181106110895761108961208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152505060ff8a82815181106110e9576110e961208c565b602002602001015161ffff16106110ff57600080fd5b8981815181106111115761111161208c565b602002602001018051809190611126906123b4565b61ffff1690525060019150611148565b806111408161235f565b915050610fe4565b508015611157575050506112b0565b818b898151811061116a5761116a61208c565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff909116905260028a015461ffff1667ffffffffffffffff8111156111b0576111b061205d565b6040519080825280602002602001820160405280156111d9578160200160208202803683370190505b508b89815181106111ec576111ec61208c565b602002602001015160200181905250828b898151811061120e5761120e61208c565b60200260200101516020015160008151811061122c5761122c61208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681525050600189898151811061128c5761128c61208c565b61ffff90921660209283029190910190910152876112a98161235f565b9850505050505b806112ba8161235f565b915050610f7d565b505080806112cf9061235f565b915050610f5a565b5060005b8281101561133f5760008482815181106112f7576112f761208c565b602002602001015161ffff16905060008783815181106113195761131961208c565b6020026020010151602001519050818152505080806113379061235f565b9150506112db565b508185525050505090565b60608060006113598786611da0565b8751909150808210156113b857848783815181106113795761137961208c565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250506115df565b60006113c5826001612304565b67ffffffffffffffff8111156113dd576113dd61205d565b604051908082528060200260200182016040528015611406578160200160208202803683370190505b5090506000885160016114199190612304565b67ffffffffffffffff8111156114315761143161205d565b60405190808252806020026020018201604052801561145a578160200160208202803683370190505b50905060005b83811015611539578a818151811061147a5761147a61208c565b60200260200101518382815181106114945761149461208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815250508981815181106114f2576114f261208c565b602002602001015182828151811061150c5761150c61208c565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101611460565b508782848151811061154d5761154d61208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152505086818a51815181106115ad576115ad61208c565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015290945092506115e8915050565b87879350935050505b94509492505050565b6000806115fe8584611da0565b905084518110611612576000915050611630565b8381815181106116245761162461208c565b60200260200101519150505b9392505050565b6060825182106116a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420696e6465780000000000000000000000000000000000000060448201526064015b60405180910390fd5b8251600003611713576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420617272617900000000000000000000000000000000000000604482015260640161169f565b6000600184516117239190612317565b67ffffffffffffffff81111561173b5761173b61205d565b60405190808252806020026020018201604052801561178157816020015b6040805180820190915260008152606060208201528152602001906001900390816117595790505b50805190915060005b8181101561182057848110156117d6578581815181106117ac576117ac61208c565b60200260200101518382815181106117c6576117c661208c565b6020026020010181905250611818565b856117e2826001612304565b815181106117f2576117f261208c565b602002602001015183828151811061180c5761180c61208c565b60200260200101819052505b60010161178a565b5090949350505050565b606082518210611896576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420696e64657800000000000000000000000000000000000000604482015260640161169f565b8251600003611901576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420617272617900000000000000000000000000000000000000604482015260640161169f565b6000600184516119119190612317565b67ffffffffffffffff8111156119295761192961205d565b604051908082528060200260200182016040528015611952578160200160208202803683370190505b50805190915060005b8181101561182057848110156119cd5785818151811061197d5761197d61208c565b60200260200101518382815181106119975761199761208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152611a35565b856119d9826001612304565b815181106119e9576119e961208c565b6020026020010151838281518110611a0357611a0361208c565b7fffffffff00000000000000000000000000000000000000000000000000000000909216602092830291909101909101525b60010161195b565b81518151606091906000611a518284612304565b67ffffffffffffffff811115611a6957611a6961205d565b604051908082528060200260200182016040528015611a92578160200160208202803683370190505b50905060005b83811015611b0557868181518110611ab257611ab261208c565b6020026020010151828281518110611acc57611acc61208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152600101611a98565b5060005b82811015611b8157858181518110611b2357611b2361208c565b6020026020010151828286611b389190612304565b81518110611b4857611b4861208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152600101611b09565b5095945050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff1667ffffffffffffffff811115611bee57611bee61205d565b604051908082528060200260200182016040528015611c17578160200160208202803683370190505b50915060008060005b600284015461ffff16821015611d98576000818152600185016020526040812054905b6008811015611d835783611c568161235f565b600288015490955061ffff1685119050611d8357600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020889052604081205460601c90805b88811015611d19578a8181518110611cc457611cc461208c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611d075760019150611d19565b80611d118161235f565b915050611caa565b508015611d2857505050611d71565b818a8981518110611d3b57611d3b61208c565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015287611d6a8161235f565b9850505050505b80611d7b8161235f565b915050611c43565b50508080611d909061235f565b915050611c20565b505082525090565b8151600090815b81811015611e1e57837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916858281518110611de157611de161208c565b60200260200101517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603611e165791506101979050565b600101611da7565b509392505050565b73ffffffffffffffffffffffffffffffffffffffff81168114611e4857600080fd5b50565b600060208284031215611e5d57600080fd5b813561163081611e26565b6020808252825182820181905260009190848201906040850190845b81811015611ec25783517fffffffff000000000000000000000000000000000000000000000000000000001683529284019291840191600101611e84565b50909695505050505050565b7fffffffff0000000000000000000000000000000000000000000000000000000081168114611e4857600080fd5b600060208284031215611f0e57600080fd5b813561163081611ece565b6020808252825182820181905260009190848201906040850190845b81811015611ec257835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101611f35565b60006020808301818452808551808352604092508286019150828160051b8701018488016000805b8481101561204e578984037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00186528251805173ffffffffffffffffffffffffffffffffffffffff168552880151888501889052805188860181905290890190839060608701905b808310156120395783517fffffffff00000000000000000000000000000000000000000000000000000000168252928b019260019290920191908b0190611ff7565b50978a01979550505091870191600101611f8f565b50919998505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6040805190810167ffffffffffffffff811182821017156120de576120de61205d565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561212b5761212b61205d565b604052919050565b600067ffffffffffffffff82111561214d5761214d61205d565b5060051b60200190565b6000602080838503121561216a57600080fd5b825167ffffffffffffffff8082111561218257600080fd5b818501915085601f83011261219657600080fd5b81516121a96121a482612133565b6120e4565b81815260059190911b830184019084810190888311156121c857600080fd5b8585015b838110156122c8578051858111156121e45760008081fd5b86016040818c037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00181131561221a5760008081fd5b6122226120bb565b8983015161222f81611e26565b815282820151888111156122435760008081fd5b8084019350508c603f8401126122595760008081fd5b898301516122696121a482612133565b81815260059190911b84018301908b8101908f8311156122895760008081fd5b948401945b828610156122b357855194506122a385611ece565b848252948c0194908c019061228e565b838d01525050855250509186019186016121cc565b5098975050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610197576101976122d5565b81810381811115610197576101976122d5565b600081612339576123396122d5565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612390576123906122d5565b5060010190565b6000602082840312156123a957600080fd5b815161163081611e26565b600061ffff8083168181036123cb576123cb6122d5565b600101939250505056fea26469706673582212205959d8d85aad6f29d5fc37d5a52c404c25392cec49195c3b761da0e863e99b0f64736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "DiamondLoupe contract compatible with EIP-2535", + "kind": "dev", + "methods": { + "facetAddress(bytes4)": { + "details": "If facet is not found return address(0).", + "params": { + "_functionSelector": "The function selector." + }, + "returns": { + "facetAddress_": "The facet address." + } + }, + "facetAddressFromStorage(bytes4)": { + "params": { + "_functionSelector": "Function selector to fetch the facet address from diamond storage" + }, + "returns": { + "facetAddress_": "Facet address mapped with the function selector" + } + }, + "facetAddresses()": { + "returns": { + "facetAddresses_": "facetAddresses_" + } + }, + "facetAddressesFromStorage()": { + "returns": { + "facetAddresses_": "All facet addresses attached directly to diamond storage" + } + }, + "facetFunctionSelectors(address)": { + "params": { + "_facet": "The facet address." + }, + "returns": { + "facetFunctionSelectors_": "facetFunctionSelectors_" + } + }, + "facetFunctionSelectorsFromStorage(address)": { + "params": { + "_facet": "Facet address to fetch the facet function selectors from diamond storage" + }, + "returns": { + "facetFunctionSelectors_": "Facet function selectors of the given facet address" + } + }, + "facets()": { + "details": "Barz uses a special architecture called default fallback handler. Default Fallback handler is used as a middleware that holds the mapping of facet function selector and facet address that Barz uses. This helps Barz to reduce significant amount of gas during the initialization process. Hence, this method aggregates both the facet information from DefaulFallbackHandler and in diamond storage and shows the data to users.", + "returns": { + "facets_": "Facet" + } + }, + "facetsFromStorage()": { + "returns": { + "facets_": "Facet information attached directly to diamond storage" + } + }, + "supportsInterface(bytes4)": { + "params": { + "_interfaceId": "Interface ID for detecting the interface" + }, + "returns": { + "isSupported": "Bool value showing if the standard is supported in the contract" + } + } + }, + "title": "DiamondLoupe Facet", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "facetAddress(bytes4)": { + "notice": "Gets the facet that supports the given selector." + }, + "facetAddressFromStorage(bytes4)": { + "notice": "Returns the facet address attached to the given function selector. This excludes the facets from the default fallback handler" + }, + "facetAddresses()": { + "notice": "Get all the facet addresses used by Barz." + }, + "facetAddressesFromStorage()": { + "notice": "Returns all facet addresses attached directly to diamond storage. This excludes the facets from the default fallback handler" + }, + "facetFunctionSelectors(address)": { + "notice": "Gets all the function selectors provided by a facet." + }, + "facetFunctionSelectorsFromStorage(address)": { + "notice": "Returns function selectors of given facet address attached directly to diamond storage. This excludes the facets from the default fallback handler" + }, + "facets()": { + "notice": "Gets all facets and their selectors." + }, + "facetsFromStorage()": { + "notice": "Returns the facet from the diamond storage. This excludes the facets from the default fallback handler" + }, + "supportsInterface(bytes4)": { + "notice": "SupportInterface to be compatible with EIP 165" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/opBNB/Secp256r1VerificationFacet.json b/deployments/opBNB/Secp256r1VerificationFacet.json new file mode 100644 index 0000000..7baa2ab --- /dev/null +++ b/deployments/opBNB/Secp256r1VerificationFacet.json @@ -0,0 +1,483 @@ +{ + "address": "0xeE1AF8E967eC04C84711842796A5E714D2FD33e6", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "LibAppStorage__AccountMustBeUninitialized", + "type": "error" + }, + { + "inputs": [], + "name": "LibAppStorage__SignerAlreadyUninitialized", + "type": "error" + }, + { + "inputs": [], + "name": "LibAppStorage__SignerMustBeUninitialized", + "type": "error" + }, + { + "inputs": [], + "name": "Secp256r1VerificationFacet__InvalidSignerLength", + "type": "error" + }, + { + "inputs": [], + "name": "VerificationFacet__InitializationFailure", + "type": "error" + }, + { + "inputs": [], + "name": "VerificationFacet__InvalidFacetMapping", + "type": "error" + }, + { + "inputs": [], + "name": "VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet", + "type": "error" + }, + { + "inputs": [], + "name": "VerificationFacet__ValidateOwnerSignatureSelectorNotSet", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "SignerInitialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "SignerUninitialized", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_publicKey", + "type": "bytes" + } + ], + "name": "initializeSigner", + "outputs": [ + { + "internalType": "uint256", + "name": "initSuccess", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_publicKey", + "type": "bytes" + } + ], + "name": "isValidKeyType", + "outputs": [ + { + "internalType": "bool", + "name": "isValid", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_hash", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "_signature", + "type": "bytes" + } + ], + "name": "isValidSignature", + "outputs": [ + { + "internalType": "bytes4", + "name": "magicValue", + "type": "bytes4" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "bytes", + "name": "signer", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "self", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "uninitializeSigner", + "outputs": [ + { + "internalType": "uint256", + "name": "uninitSuccess", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "initCode", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "callGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "verificationGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "preVerificationGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxFeePerGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPriorityFeePerGas", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "paymasterAndData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "internalType": "struct UserOperation", + "name": "userOp", + "type": "tuple" + }, + { + "internalType": "bytes32", + "name": "userOpHash", + "type": "bytes32" + } + ], + "name": "validateOwnerSignature", + "outputs": [ + { + "internalType": "uint256", + "name": "validationData", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "validateOwnerSignatureSelector", + "outputs": [ + { + "internalType": "bytes4", + "name": "ownerSignatureValidatorSelector", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "initCode", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "callGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "verificationGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "preVerificationGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxFeePerGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPriorityFeePerGas", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "paymasterAndData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "internalType": "struct UserOperation", + "name": "userOp", + "type": "tuple" + }, + { + "internalType": "bytes32", + "name": "userOpHash", + "type": "bytes32" + }, + { + "internalType": "uint256[2]", + "name": "q", + "type": "uint256[2]" + } + ], + "name": "validateSignature", + "outputs": [ + { + "internalType": "uint256", + "name": "isValid", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0x70688fb8576003d6e48957d04ea3662df7c5f23ec918751858aad25d59b33da7", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 3, + "gasUsed": "1809225", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x48dcf21413e532eedd3fe63d320ab6fd892f6e9ef9029c2ab6acd0b0dcd1a69e", + "transactionHash": "0x70688fb8576003d6e48957d04ea3662df7c5f23ec918751858aad25d59b33da7", + "logs": [], + "blockNumber": 8731253, + "cumulativeGasUsed": "2045311", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 2, + "solcInputHash": "4356503edd8ae34e73cb6dd1c8e2fc8a", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"LibAppStorage__AccountMustBeUninitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LibAppStorage__SignerAlreadyUninitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LibAppStorage__SignerMustBeUninitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Secp256r1VerificationFacet__InvalidSignerLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerificationFacet__InitializationFailure\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerificationFacet__InvalidFacetMapping\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerificationFacet__ValidateOwnerSignatureSelectorNotSet\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"SignerInitialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"SignerUninitialized\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_publicKey\",\"type\":\"bytes\"}],\"name\":\"initializeSigner\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"initSuccess\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_publicKey\",\"type\":\"bytes\"}],\"name\":\"isValidKeyType\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isValid\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_hash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"_signature\",\"type\":\"bytes\"}],\"name\":\"isValidSignature\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"magicValue\",\"type\":\"bytes4\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"signer\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"self\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"uninitializeSigner\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"uninitSuccess\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"userOp\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"}],\"name\":\"validateOwnerSignature\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"validationData\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"validateOwnerSignatureSelector\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"ownerSignatureValidatorSelector\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"userOp\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256[2]\",\"name\":\"q\",\"type\":\"uint256[2]\"}],\"name\":\"validateSignature\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"isValid\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Ruslan Serebriakov (@rsrbk)David Yongjun Kim (@Powerstream3604)\",\"details\":\"Primarily used to verify user ops signed with passkeys\",\"kind\":\"dev\",\"methods\":{\"initializeSigner(bytes)\":{\"details\":\"This method checks if the signer has already been initialized. If already initialized, it reverts. It checks if the public key is in the light format and initializes signer storage in k1 storage.\",\"params\":{\"_publicKey\":\"Bytes of owner public key\"},\"returns\":{\"initSuccess\":\"Uint value representing the success of init operation\"}},\"isValidKeyType(bytes)\":{\"details\":\"For this Secp256k1Verification Facet, the public key should in an uncompressed public key format\",\"params\":{\"_publicKey\":\"Bytes of public key for format check\"},\"returns\":{\"isValid\":\"Boolean variable representing if the format of public key is valid\"}},\"isValidSignature(bytes32,bytes)\":{\"details\":\"This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\",\"params\":{\"_hash\":\"Hash value the owner signed\",\"_signature\":\"Signature that signed the above hash\"},\"returns\":{\"magicValue\":\"Bytes4 value representing the success/failure of validation\"}},\"owner()\":{\"returns\":{\"signer\":\"Bytes of owner address\"}},\"uninitializeSigner()\":{\"details\":\"This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\",\"returns\":{\"uninitSuccess\":\"Uint value representing the success of uninit operation\"}},\"validateOwnerSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32)\":{\"details\":\"This method validates if the user operation is signed by the owner. It internally calls validateSignature with signer public key.\",\"params\":{\"userOp\":\"UserOperation including all information for execution\",\"userOpHash\":\"Hash of UserOperation given from EntryPoint. This hash is used for signature validation\"},\"returns\":{\"validationData\":\"Uint value representing whether the validation is successful. 0 for success, 1 for failure\"}},\"validateOwnerSignatureSelector()\":{\"returns\":{\"ownerSignatureValidatorSelector\":\"Bytes4 selector of function signature to validate account owner's UserOperation signature\"}},\"validateSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256[2])\":{\"details\":\"This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\",\"params\":{\"q\":\"Public Key of signer who signed the contract, to be validated\",\"userOp\":\"UserOperation including all information for execution\",\"userOpHash\":\"Hash of UserOperation given from EntryPoint. This hash is used for signature validation\"},\"returns\":{\"isValid\":\"Uint value representing whether the validation is successful. 0 for success, 1 for failure\"}}},\"title\":\"Secp256r1 verification facet\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"This constructor ensures that this contract can only be used as singleton for Proxy contracts\"},\"initializeSigner(bytes)\":{\"notice\":\"Initializes the signer in R1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\"},\"isValidKeyType(bytes)\":{\"notice\":\"Validates if the format of public key is valid for this verification facet\"},\"isValidSignature(bytes32,bytes)\":{\"notice\":\"Validates if the signature is valid. Function to be compatible with EIP-1271\"},\"owner()\":{\"notice\":\"Returns the owner of the account\"},\"uninitializeSigner()\":{\"notice\":\"Uninitialize signer in R1 Facet Storage. This can only be called when the account is undergoing signature migration and has already been initialized.\"},\"validateOwnerSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32)\":{\"notice\":\"Validates if the user operation is signed by the owner.\"},\"validateOwnerSignatureSelector()\":{\"notice\":\"Returns the selector of function to validate the signature of UserOperation\"},\"validateSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256[2])\":{\"notice\":\"Validates if the signature of UserOperation is signed by the given signer\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/verification/secp256r1/Secp256r1VerificationFacet.sol\":\"Secp256r1VerificationFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/utils/math/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\\n * checks.\\n *\\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\\n * easily result in undesired exploitation or bugs, since developers usually\\n * assume that overflows raise errors. `SafeCast` restores this intuition by\\n * reverting the transaction when such an operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n *\\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\\n * all math on `uint256` and `int256` and then downcasting.\\n */\\nlibrary SafeCast {\\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 * _Available since v4.7._\\n */\\n function toUint248(uint256 value) internal pure returns (uint248) {\\n require(value <= type(uint248).max, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint240(uint256 value) internal pure returns (uint240) {\\n require(value <= type(uint240).max, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint232(uint256 value) internal pure returns (uint232) {\\n require(value <= type(uint232).max, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint224(uint256 value) internal pure returns (uint224) {\\n require(value <= type(uint224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint216(uint256 value) internal pure returns (uint216) {\\n require(value <= type(uint216).max, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint208(uint256 value) internal pure returns (uint208) {\\n require(value <= type(uint208).max, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint200(uint256 value) internal pure returns (uint200) {\\n require(value <= type(uint200).max, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint192(uint256 value) internal pure returns (uint192) {\\n require(value <= type(uint192).max, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint184(uint256 value) internal pure returns (uint184) {\\n require(value <= type(uint184).max, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint176(uint256 value) internal pure returns (uint176) {\\n require(value <= type(uint176).max, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint168(uint256 value) internal pure returns (uint168) {\\n require(value <= type(uint168).max, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint160(uint256 value) internal pure returns (uint160) {\\n require(value <= type(uint160).max, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint152(uint256 value) internal pure returns (uint152) {\\n require(value <= type(uint152).max, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint144(uint256 value) internal pure returns (uint144) {\\n require(value <= type(uint144).max, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint136(uint256 value) internal pure returns (uint136) {\\n require(value <= type(uint136).max, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint128(uint256 value) internal pure returns (uint128) {\\n require(value <= type(uint128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint120(uint256 value) internal pure returns (uint120) {\\n require(value <= type(uint120).max, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint112(uint256 value) internal pure returns (uint112) {\\n require(value <= type(uint112).max, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint104(uint256 value) internal pure returns (uint104) {\\n require(value <= type(uint104).max, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint96(uint256 value) internal pure returns (uint96) {\\n require(value <= type(uint96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint88(uint256 value) internal pure returns (uint88) {\\n require(value <= type(uint88).max, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint80(uint256 value) internal pure returns (uint80) {\\n require(value <= type(uint80).max, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint72(uint256 value) internal pure returns (uint72) {\\n require(value <= type(uint72).max, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint64(uint256 value) internal pure returns (uint64) {\\n require(value <= type(uint64).max, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint56(uint256 value) internal pure returns (uint56) {\\n require(value <= type(uint56).max, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint48(uint256 value) internal pure returns (uint48) {\\n require(value <= type(uint48).max, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint40(uint256 value) internal pure returns (uint40) {\\n require(value <= type(uint40).max, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint32(uint256 value) internal pure returns (uint32) {\\n require(value <= type(uint32).max, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint24(uint256 value) internal pure returns (uint24) {\\n require(value <= type(uint24).max, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint16(uint256 value) internal pure returns (uint16) {\\n require(value <= type(uint16).max, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint8(uint256 value) internal pure returns (uint8) {\\n require(value <= type(uint8).max, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\n */\\n function toUint256(int256 value) internal pure returns (uint256) {\\n require(value >= 0, \\\"SafeCast: value must be positive\\\");\\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 * _Available since v4.7._\\n */\\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\\n downcasted = int248(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\\n downcasted = int240(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\\n downcasted = int232(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\\n downcasted = int224(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\\n downcasted = int216(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\\n downcasted = int208(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\\n downcasted = int200(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\\n downcasted = int192(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\\n downcasted = int184(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\\n downcasted = int176(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\\n downcasted = int168(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\\n downcasted = int160(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\\n downcasted = int152(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\\n downcasted = int144(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\\n downcasted = int136(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\\n downcasted = int128(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\\n downcasted = int120(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\\n downcasted = int112(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\\n downcasted = int104(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\\n downcasted = int96(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\\n downcasted = int88(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\\n downcasted = int80(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\\n downcasted = int72(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\\n downcasted = int64(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\\n downcasted = int56(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\\n downcasted = int48(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\\n downcasted = int40(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\\n downcasted = int32(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\\n downcasted = int24(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\\n downcasted = int16(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\\n downcasted = int8(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\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 require(value <= uint256(type(int256).max), \\\"SafeCast: value doesn't fit in an int256\\\");\\n return int256(value);\\n }\\n}\\n\",\"keccak256\":\"0x52a8cfb0f5239d11b457dcdd1b326992ef672714ca8da71a157255bddd13f3ad\",\"license\":\"MIT\"},\"contracts/aa-4337/core/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable no-inline-assembly */\\n\\n/**\\n * returned data from validateUserOp.\\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\\n * @param aggregator - address(0) - the account validated the signature by itself.\\n * address(1) - the account failed to validate the signature.\\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\\n * @param validAfter - this UserOp is valid only after this timestamp.\\n * @param validaUntil - this UserOp is valid only up to this timestamp.\\n */\\nstruct ValidationData {\\n address aggregator;\\n uint48 validAfter;\\n uint48 validUntil;\\n}\\n\\n//extract sigFailed, validAfter, validUntil.\\n// also convert zero validUntil to type(uint48).max\\nfunction _parseValidationData(\\n uint validationData\\n) pure returns (ValidationData memory data) {\\n address aggregator = address(uint160(validationData));\\n uint48 validUntil = uint48(validationData >> 160);\\n if (validUntil == 0) {\\n validUntil = type(uint48).max;\\n }\\n uint48 validAfter = uint48(validationData >> (48 + 160));\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n// intersect account and paymaster ranges.\\nfunction _intersectTimeRange(\\n uint256 validationData,\\n uint256 paymasterValidationData\\n) pure returns (ValidationData memory) {\\n ValidationData memory accountValidationData = _parseValidationData(\\n validationData\\n );\\n ValidationData memory pmValidationData = _parseValidationData(\\n paymasterValidationData\\n );\\n address aggregator = accountValidationData.aggregator;\\n if (aggregator == address(0)) {\\n aggregator = pmValidationData.aggregator;\\n }\\n uint48 validAfter = accountValidationData.validAfter;\\n uint48 validUntil = accountValidationData.validUntil;\\n uint48 pmValidAfter = pmValidationData.validAfter;\\n uint48 pmValidUntil = pmValidationData.validUntil;\\n\\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp\\n * @param data - the ValidationData to pack\\n */\\nfunction _packValidationData(\\n ValidationData memory data\\n) pure returns (uint256) {\\n return\\n uint160(data.aggregator) |\\n (uint256(data.validUntil) << 160) |\\n (uint256(data.validAfter) << (160 + 48));\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp, when not using an aggregator\\n * @param sigFailed - true for signature failure, false for success\\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\\n * @param validAfter first timestamp this UserOperation is valid\\n */\\nfunction _packValidationData(\\n bool sigFailed,\\n uint48 validUntil,\\n uint48 validAfter\\n) pure returns (uint256) {\\n return\\n (sigFailed ? 1 : 0) |\\n (uint256(validUntil) << 160) |\\n (uint256(validAfter) << (160 + 48));\\n}\\n\\n/**\\n * keccak function over calldata.\\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\\n */\\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\\n assembly {\\n let mem := mload(0x40)\\n let len := data.length\\n calldatacopy(mem, data.offset, len)\\n ret := keccak256(mem, len)\\n }\\n}\\n\",\"keccak256\":\"0xa79f06cd158ecb8c0da95493a2f348933b8627a63e228b99738bff3aa107942d\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAggregator.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\n/**\\n * Aggregated Signatures validator.\\n */\\ninterface IAggregator {\\n /**\\n * validate aggregated signature.\\n * revert if the aggregated signature does not match the given list of operations.\\n */\\n function validateSignatures(\\n UserOperation[] calldata userOps,\\n bytes calldata signature\\n ) external view;\\n\\n /**\\n * validate signature of a single userOp\\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\\n * @param userOp the userOperation received from the user.\\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\\n * (usually empty, unless account and aggregator support some kind of \\\"multisig\\\"\\n */\\n function validateUserOpSignature(\\n UserOperation calldata userOp\\n ) external view returns (bytes memory sigForUserOp);\\n\\n /**\\n * aggregate multiple signatures into a single value.\\n * This method is called off-chain to calculate the signature to pass with handleOps()\\n * bundler MAY use optimized custom code perform this aggregation\\n * @param userOps array of UserOperations to collect the signatures from.\\n * @return aggregatedSignature the aggregated signature\\n */\\n function aggregateSignatures(\\n UserOperation[] calldata userOps\\n ) external view returns (bytes memory aggregatedSignature);\\n}\\n\",\"keccak256\":\"0xdfdcd80568f037716674619b31be630fcd8316262f05a815b41d1e81782c966a\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IEntryPoint.sol\":{\"content\":\"/**\\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\\n ** Only one instance required on each chain.\\n **/\\n// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-inline-assembly */\\n/* solhint-disable reason-string */\\n\\nimport \\\"./UserOperation.sol\\\";\\nimport \\\"./IStakeManager.sol\\\";\\nimport \\\"./IAggregator.sol\\\";\\nimport \\\"./INonceManager.sol\\\";\\n\\ninterface IEntryPoint is IStakeManager, INonceManager {\\n /***\\n * An event emitted after each successful request\\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\\n * @param sender - the account that generates this request.\\n * @param paymaster - if non-null, the paymaster that pays for this request.\\n * @param nonce - the nonce value from the request.\\n * @param success - true if the sender transaction succeeded, false if reverted.\\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\\n */\\n event UserOperationEvent(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address indexed paymaster,\\n uint256 nonce,\\n bool success,\\n uint256 actualGasCost,\\n uint256 actualGasUsed\\n );\\n\\n /**\\n * account \\\"sender\\\" was deployed.\\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\\n * @param sender the account that is deployed\\n * @param factory the factory used to deploy this account (in the initCode)\\n * @param paymaster the paymaster used by this UserOp\\n */\\n event AccountDeployed(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address factory,\\n address paymaster\\n );\\n\\n /**\\n * An event emitted if the UserOperation \\\"callData\\\" reverted with non-zero length\\n * @param userOpHash the request unique identifier.\\n * @param sender the sender of this request\\n * @param nonce the nonce used in the request\\n * @param revertReason - the return bytes from the (reverted) call to \\\"callData\\\".\\n */\\n event UserOperationRevertReason(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n uint256 nonce,\\n bytes revertReason\\n );\\n\\n /**\\n * an event emitted by handleOps(), before starting the execution loop.\\n * any event emitted before this event, is part of the validation.\\n */\\n event BeforeExecution();\\n\\n /**\\n * signature aggregator used by the following UserOperationEvents within this bundle.\\n */\\n event SignatureAggregatorChanged(address indexed aggregator);\\n\\n /**\\n * a custom revert error of handleOps, to identify the offending op.\\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\\n * @param reason - revert reason\\n * The string starts with a unique code \\\"AAmn\\\", where \\\"m\\\" is \\\"1\\\" for factory, \\\"2\\\" for account and \\\"3\\\" for paymaster issues,\\n * so a failure can be attributed to the correct entity.\\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\\n */\\n error FailedOp(uint256 opIndex, string reason);\\n\\n /**\\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\\n */\\n error SignatureValidationFailed(address aggregator);\\n\\n /**\\n * Successful result from simulateValidation.\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n */\\n error ValidationResult(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo\\n );\\n\\n /**\\n * Successful result from simulateValidation, if the account returns a signature aggregator\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\\n * bundler MUST use it to verify the signature, or reject the UserOperation\\n */\\n error ValidationResultWithAggregation(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo,\\n AggregatorStakeInfo aggregatorInfo\\n );\\n\\n /**\\n * return value of getSenderAddress\\n */\\n error SenderAddressResult(address sender);\\n\\n /**\\n * return value of simulateHandleOp\\n */\\n error ExecutionResult(\\n uint256 preOpGas,\\n uint256 paid,\\n uint48 validAfter,\\n uint48 validUntil,\\n bool targetSuccess,\\n bytes targetResult\\n );\\n\\n //UserOps handled, per aggregator\\n struct UserOpsPerAggregator {\\n UserOperation[] userOps;\\n // aggregator address\\n IAggregator aggregator;\\n // aggregated signature\\n bytes signature;\\n }\\n\\n /**\\n * Execute a batch of UserOperation.\\n * no signature aggregator is used.\\n * if any account requires an aggregator (that is, it returned an aggregator when\\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\\n * @param ops the operations to execute\\n * @param beneficiary the address to receive the fees\\n */\\n function handleOps(\\n UserOperation[] calldata ops,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * Execute a batch of UserOperation with Aggregators\\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\\n * @param beneficiary the address to receive the fees\\n */\\n function handleAggregatedOps(\\n UserOpsPerAggregator[] calldata opsPerAggregator,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * generate a request Id - unique identifier for this request.\\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\\n */\\n function getUserOpHash(\\n UserOperation calldata userOp\\n ) external view returns (bytes32);\\n\\n /**\\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\\n * @param userOp the user operation to validate.\\n */\\n function simulateValidation(UserOperation calldata userOp) external;\\n\\n /**\\n * gas and return values during simulation\\n * @param preOpGas the gas used for validation (including preValidationGas)\\n * @param prefund the required prefund for this operation\\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\\n */\\n struct ReturnInfo {\\n uint256 preOpGas;\\n uint256 prefund;\\n bool sigFailed;\\n uint48 validAfter;\\n uint48 validUntil;\\n bytes paymasterContext;\\n }\\n\\n /**\\n * returned aggregated signature info.\\n * the aggregator returned by the account, and its current stake.\\n */\\n struct AggregatorStakeInfo {\\n address aggregator;\\n StakeInfo stakeInfo;\\n }\\n\\n /**\\n * Get counterfactual sender address.\\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\\n * this method always revert, and returns the address in SenderAddressResult error\\n * @param initCode the constructor code to be passed into the UserOperation.\\n */\\n function getSenderAddress(bytes memory initCode) external;\\n\\n /**\\n * simulate full execution of a UserOperation (including both validation and target execution)\\n * this method will always revert with \\\"ExecutionResult\\\".\\n * it performs full validation of the UserOperation, but ignores signature error.\\n * an optional target address is called after the userop succeeds, and its value is returned\\n * (before the entire call is reverted)\\n * Note that in order to collect the the success/failure of the target call, it must be executed\\n * with trace enabled to track the emitted events.\\n * @param op the UserOperation to simulate\\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\\n * are set to the return from that call.\\n * @param targetCallData callData to pass to target address\\n */\\n function simulateHandleOp(\\n UserOperation calldata op,\\n address target,\\n bytes calldata targetCallData\\n ) external;\\n}\\n\",\"keccak256\":\"0x9ccb1b188eda8bbf5f6c2d01bd83c3d8b2b04fcf745283051d31fe96d1d8e40f\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/INonceManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\ninterface INonceManager {\\n /**\\n * Return the next nonce for this sender.\\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\\n * But UserOp with different keys can come with arbitrary order.\\n *\\n * @param sender the account address\\n * @param key the high 192 bit of the nonce\\n * @return nonce a full nonce to pass for next UserOp with this sender.\\n */\\n function getNonce(\\n address sender,\\n uint192 key\\n ) external view returns (uint256 nonce);\\n\\n /**\\n * Manually increment the nonce of the sender.\\n * This method is exposed just for completeness..\\n * Account does NOT need to call it, neither during validation, nor elsewhere,\\n * as the EntryPoint will update the nonce regardless.\\n * Possible use-case is call it with various keys to \\\"initialize\\\" their nonces to one, so that future\\n * UserOperations will not pay extra for the first transaction with a given key.\\n */\\n function incrementNonce(uint192 key) external;\\n}\\n\",\"keccak256\":\"0xce478ad0fa0d18a3b785ac854623029e7ab463d05873dfaa365abfa1bf100912\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IStakeManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8.12;\\n\\n/**\\n * manage deposits and stakes.\\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\\n * stake is value locked for at least \\\"unstakeDelay\\\" by the staked entity.\\n */\\ninterface IStakeManager {\\n event Deposited(address indexed account, uint256 totalDeposit);\\n\\n event Withdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /// Emitted when stake or unstake delay are modified\\n event StakeLocked(\\n address indexed account,\\n uint256 totalStaked,\\n uint256 unstakeDelaySec\\n );\\n\\n /// Emitted once a stake is scheduled for withdrawal\\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\\n\\n event StakeWithdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /**\\n * @param deposit the entity's deposit\\n * @param staked true if this entity is staked.\\n * @param stake actual amount of ether staked for this entity.\\n * @param unstakeDelaySec minimum delay to withdraw the stake.\\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\\n * and the rest fit into a 2nd cell.\\n * 112 bit allows for 10^15 eth\\n * 48 bit for full timestamp\\n * 32 bit allows 150 years for unstake delay\\n */\\n struct DepositInfo {\\n uint112 deposit;\\n bool staked;\\n uint112 stake;\\n uint32 unstakeDelaySec;\\n uint48 withdrawTime;\\n }\\n\\n //API struct used by getStakeInfo and simulateValidation\\n struct StakeInfo {\\n uint256 stake;\\n uint256 unstakeDelaySec;\\n }\\n\\n /// @return info - full deposit information of given account\\n function getDepositInfo(\\n address account\\n ) external view returns (DepositInfo memory info);\\n\\n /// @return the deposit (for gas payment) of the account\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * add to the deposit of the given account\\n */\\n function depositTo(address account) external payable;\\n\\n /**\\n * add to the account's stake - amount and delay\\n * any pending unstake is first cancelled.\\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\\n */\\n function addStake(uint32 _unstakeDelaySec) external payable;\\n\\n /**\\n * attempt to unlock the stake.\\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\\n */\\n function unlockStake() external;\\n\\n /**\\n * withdraw from the (unlocked) stake.\\n * must first call unlockStake and wait for the unstakeDelay to pass\\n * @param withdrawAddress the address to send withdrawn value.\\n */\\n function withdrawStake(address payable withdrawAddress) external;\\n\\n /**\\n * withdraw from the deposit.\\n * @param withdrawAddress the address to send withdrawn value.\\n * @param withdrawAmount the amount to withdraw.\\n */\\n function withdrawTo(\\n address payable withdrawAddress,\\n uint256 withdrawAmount\\n ) external;\\n}\\n\",\"keccak256\":\"0xadcea606c9b7aafe6645441f2154a60f271330b0eee5292a632aa71c1672d546\",\"license\":\"GPL-3.0-only\"},\"contracts/aa-4337/interfaces/UserOperation.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable no-inline-assembly */\\n\\nimport {calldataKeccak} from \\\"../core/Helpers.sol\\\";\\n\\n/**\\n * User Operation struct\\n * @param sender the sender account of this request.\\n * @param nonce unique value the sender uses to verify it is not a replay.\\n * @param initCode if set, the account contract will be created by this constructor/\\n * @param callData the method call to execute on this account.\\n * @param callGasLimit the gas limit passed to the callData method call.\\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\\n * @param maxFeePerGas same as EIP-1559 gas parameter.\\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\\n */\\nstruct UserOperation {\\n address sender;\\n uint256 nonce;\\n bytes initCode;\\n bytes callData;\\n uint256 callGasLimit;\\n uint256 verificationGasLimit;\\n uint256 preVerificationGas;\\n uint256 maxFeePerGas;\\n uint256 maxPriorityFeePerGas;\\n bytes paymasterAndData;\\n bytes signature;\\n}\\n\\n/**\\n * Utility functions helpful when working with UserOperation structs.\\n */\\nlibrary UserOperationLib {\\n function getSender(\\n UserOperation calldata userOp\\n ) internal pure returns (address) {\\n address data;\\n //read sender from userOp, which is first userOp member (saves 800 gas...)\\n assembly {\\n data := calldataload(userOp)\\n }\\n return address(uint160(data));\\n }\\n\\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\\n // pay above what he signed for.\\n function gasPrice(\\n UserOperation calldata userOp\\n ) internal view returns (uint256) {\\n unchecked {\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n if (maxFeePerGas == maxPriorityFeePerGas) {\\n //legacy mode (for networks that don't support basefee opcode)\\n return maxFeePerGas;\\n }\\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\\n }\\n }\\n\\n function pack(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes memory ret) {\\n address sender = getSender(userOp);\\n uint256 nonce = userOp.nonce;\\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\\n bytes32 hashCallData = calldataKeccak(userOp.callData);\\n uint256 callGasLimit = userOp.callGasLimit;\\n uint256 verificationGasLimit = userOp.verificationGasLimit;\\n uint256 preVerificationGas = userOp.preVerificationGas;\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\\n\\n return\\n abi.encode(\\n sender,\\n nonce,\\n hashInitCode,\\n hashCallData,\\n callGasLimit,\\n verificationGasLimit,\\n preVerificationGas,\\n maxFeePerGas,\\n maxPriorityFeePerGas,\\n hashPaymasterAndData\\n );\\n }\\n\\n function hash(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes32) {\\n return keccak256(pack(userOp));\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n}\\n\",\"keccak256\":\"0x2429f5cc546bdee08c7e63858d0dda8491eaa3ab5194df884dc948c1154d2834\",\"license\":\"GPL-3.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/facets/interfaces/IVerificationFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {UserOperation} from \\\"../../aa-4337/interfaces/UserOperation.sol\\\";\\n\\n/**\\n * @title Verification Facet Interface\\n * @dev Implements logic for user ops signature verification\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\ninterface IVerificationFacet {\\n event SignerInitialized(bytes);\\n event SignerUninitialized();\\n\\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\\n error VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\\n error VerificationFacet__InitializationFailure();\\n error VerificationFacet__InvalidFacetMapping();\\n\\n function initializeSigner(bytes memory) external returns (uint256);\\n\\n function uninitializeSigner() external returns (uint256);\\n\\n function validateOwnerSignatureSelector() external view returns (bytes4);\\n\\n function owner() external view returns (bytes memory);\\n\\n function isValidKeyType(bytes calldata) external view returns (bool);\\n\\n function validateOwnerSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x72bc370a1d1b5a6d6bde67f5026733fd8f6ba434bb90e73b0bd8627fb1579928\",\"license\":\"Apache-2.0\"},\"contracts/facets/verification/secp256r1/Secp256r1VerificationFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {UserOperation} from \\\"../../../aa-4337/interfaces/UserOperation.sol\\\";\\nimport {LibAppStorage} from \\\"../../../libraries/LibAppStorage.sol\\\";\\nimport {LibLoupe} from \\\"../../../libraries/LibLoupe.sol\\\";\\nimport {LibFacetStorage, Secp256r1VerificationStorage} from \\\"../../../libraries/LibFacetStorage.sol\\\";\\nimport {Base64} from \\\"./utils/Base64.sol\\\";\\nimport {LibSecp256r1} from \\\"./utils/LibSecp256r1.sol\\\";\\nimport {IERC1271} from \\\"../../../interfaces/ERC/IERC1271.sol\\\";\\nimport {IVerificationFacet} from \\\"../../interfaces/IVerificationFacet.sol\\\";\\n\\n/**\\n * @title Secp256r1 verification facet\\n * @dev Primarily used to verify user ops signed with passkeys\\n * @author Ruslan Serebriakov (@rsrbk)\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract Secp256r1VerificationFacet is IVerificationFacet, IERC1271 {\\n error Secp256r1VerificationFacet__InvalidSignerLength();\\n address public immutable self;\\n\\n /**\\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\\n */\\n constructor() {\\n LibAppStorage.enforceSignerInitialize();\\n self = address(this);\\n }\\n\\n /**\\n * @notice Initializes the signer in R1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\\n * @param _publicKey Bytes of owner public key\\n * @return initSuccess Uint value representing the success of init operation\\n */\\n function initializeSigner(\\n bytes calldata _publicKey\\n ) public override returns (uint256 initSuccess) {\\n LibAppStorage.enforceSignerInitialize();\\n\\n if (!isValidKeyType(_publicKey))\\n revert Secp256r1VerificationFacet__InvalidSignerLength();\\n\\n bytes memory publicKeyCoordinates = _publicKey[1:];\\n uint256[2] memory q;\\n assembly {\\n // Copy the bytes from the input data into the uint256 array\\n mstore(q, mload(add(publicKeyCoordinates, 32)))\\n mstore(add(q, 32), mload(add(publicKeyCoordinates, 64)))\\n }\\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\\n .r1Storage();\\n r1Storage.q = q;\\n\\n bytes4 validateSelector = validateOwnerSignatureSelector();\\n\\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\\n if (LibLoupe.facetAddress(validateSelector) != self)\\n revert VerificationFacet__InvalidFacetMapping();\\n\\n // initialize verification function selector\\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\\n\\n initSuccess = 1;\\n\\n emit SignerInitialized(_publicKey);\\n }\\n\\n /**\\n * @notice Uninitialize signer in R1 Facet Storage. This can only be called when the account is undergoing signature migration\\n * and has already been initialized.\\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\\n * @return uninitSuccess Uint value representing the success of uninit operation\\n */\\n function uninitializeSigner()\\n external\\n override\\n returns (uint256 uninitSuccess)\\n {\\n LibAppStorage.enforceSignerMigration();\\n LibAppStorage.setSignerUninitialized();\\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\\n .r1Storage();\\n r1Storage.q = [0, 0];\\n\\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\\n\\n uninitSuccess = 1;\\n\\n emit SignerUninitialized();\\n }\\n\\n /**\\n * @notice Validates if the user operation is signed by the owner.\\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\\n * signer public key.\\n * @param userOp UserOperation including all information for execution\\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\\n */\\n function validateOwnerSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) public view override returns (uint256 validationData) {\\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\\n .r1Storage();\\n validationData = validateSignature(userOp, userOpHash, r1Storage.q);\\n }\\n\\n /**\\n * @notice Validates if the signature of UserOperation is signed by the given signer\\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\\n * @param userOp UserOperation including all information for execution\\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\\n * @param q Public Key of signer who signed the contract, to be validated\\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\\n */\\n function validateSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n uint256[2] memory q\\n ) public view returns (uint256 isValid) {\\n isValid = (_validateSignature(q, userOpHash, userOp.signature)) ? 0 : 1;\\n }\\n\\n /**\\n * @notice Returns the selector of function to validate the signature of UserOperation\\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\\n */\\n function validateOwnerSignatureSelector()\\n public\\n pure\\n override\\n returns (bytes4 ownerSignatureValidatorSelector)\\n {\\n return this.validateOwnerSignature.selector; // validateOwnerSignature(UserOperation calldata userOp,bytes32 userOpHash)\\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\\n }\\n\\n /**\\n * @notice Returns the owner of the account\\n * @return signer Bytes of owner address\\n */\\n function owner() public view override returns (bytes memory signer) {\\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\\n .r1Storage();\\n signer = abi.encodePacked(r1Storage.q);\\n }\\n\\n /**\\n * @notice Validates if the format of public key is valid for this verification facet\\n * @dev For this Secp256k1Verification Facet, the public key should in an uncompressed public key format\\n * @param _publicKey Bytes of public key for format check\\n * @return isValid Boolean variable representing if the format of public key is valid\\n */\\n function isValidKeyType(\\n bytes memory _publicKey\\n ) public pure override returns (bool isValid) {\\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\\n }\\n\\n /**\\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\\n * @param _hash Hash value the owner signed\\n * @param _signature Signature that signed the above hash\\n * @return magicValue Bytes4 value representing the success/failure of validation\\n */\\n function isValidSignature(\\n bytes32 _hash,\\n bytes memory _signature\\n ) public view override returns (bytes4 magicValue) {\\n magicValue = _validateSignature(\\n LibFacetStorage.r1Storage().q,\\n _hash,\\n _signature\\n )\\n ? this.isValidSignature.selector\\n : bytes4(0xffffffff);\\n }\\n\\n function _validateSignature(\\n uint256[2] memory q,\\n bytes32 _hash,\\n bytes memory _signature\\n ) internal view returns (bool) {\\n (\\n uint256 rValue,\\n uint256 sValue,\\n bytes memory authenticatorData,\\n string memory clientDataJSONPre,\\n string memory clientDataJSONPost\\n ) = abi.decode(_signature, (uint256, uint256, bytes, string, string));\\n bytes32 clientHash;\\n {\\n string memory opHashBase64 = Base64.encode(bytes.concat(_hash));\\n string memory clientDataJSON = string.concat(\\n clientDataJSONPre,\\n opHashBase64,\\n clientDataJSONPost\\n );\\n clientHash = sha256(bytes(clientDataJSON));\\n }\\n bytes32 sigHash = sha256(bytes.concat(authenticatorData, clientHash));\\n return LibSecp256r1.Verify(q, rValue, sValue, uint256(sigHash));\\n }\\n}\\n\",\"keccak256\":\"0xdb3bae77323eef4e16ef5a5342f548527c9e82b44e8e9dab90906dc2c00082ff\",\"license\":\"Apache-2.0\"},\"contracts/facets/verification/secp256r1/utils/Base64.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @dev Provides a set of functions to operate with Base64 strings.\\n * modified for base64url https://datatracker.ietf.org/doc/html/rfc4648#section-5\\n * _Available since v4.5._\\n */\\nlibrary Base64 {\\n /**\\n * @dev Base64 Encoding/Decoding Table\\n */\\n string internal constant _TABLE =\\n \\\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_\\\";\\n\\n /**\\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\\n */\\n function encode(bytes memory data) internal pure returns (string memory) {\\n /**\\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\\n */\\n if (data.length == 0) return \\\"\\\";\\n\\n // Loads the table into memory\\n string memory table = _TABLE;\\n\\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\\n // and split into 4 numbers of 6 bits.\\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\\n // - `data.length + 2` -> Round up\\n // - `/ 3` -> Number of 3-bytes chunks\\n // - `4 *` -> 4 characters for each chunk\\n uint256 newlength = (data.length * 8) / 6;\\n if (data.length % 6 > 0) {\\n newlength++;\\n }\\n string memory result = new string(newlength);\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n // Prepare the lookup table (skip the first \\\"length\\\" byte)\\n let tablePtr := add(table, 1)\\n\\n // Prepare result pointer, jump over length\\n let resultPtr := add(result, 32)\\n\\n // Run over the input, 3 bytes at a time\\n for {\\n let dataPtr := data\\n let endPtr := add(data, mload(data))\\n } lt(dataPtr, endPtr) {\\n\\n } {\\n // Advance 3 bytes\\n dataPtr := add(dataPtr, 3)\\n let input := mload(dataPtr)\\n\\n // To write each character, shift the 3 bytes (18 bits) chunk\\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\\n // and apply logical AND with 0x3F which is the number of\\n // the previous character in the ASCII table prior to the Base64 Table\\n // The result is then added to the table to get the character to write,\\n // and finally write it in the result pointer but with a left shift\\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\\n\\n mstore8(\\n resultPtr,\\n mload(add(tablePtr, and(shr(18, input), 0x3F)))\\n )\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(\\n resultPtr,\\n mload(add(tablePtr, and(shr(12, input), 0x3F)))\\n )\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(\\n resultPtr,\\n mload(add(tablePtr, and(shr(6, input), 0x3F)))\\n )\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n }\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0xbf0afa21e5a128f260c1a8d4333dc0b0e8755a50d37dfa9b5d362d36ef9cdc14\",\"license\":\"Apache-2.0\"},\"contracts/facets/verification/secp256r1/utils/LibSecp256r1.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n// Heavily inspired from\\n// https://github.com/maxrobot/elliptic-solidity/blob/master/contracts/Secp256r1.sol\\n// https://github.com/tdrerup/elliptic-curve-solidity/blob/master/contracts/curves/EllipticCurve.sol\\n// modified to use precompile 0x05 modexp\\n// and modified jacobian double\\n// optimisations to avoid to an from from affine and jacobian coordinates\\n\\n// Additional Elliptic curve Public key / Signature validation added by\\n// David Yonjun Kim (@Powerstream3604)\\n\\nstruct JPoint {\\n uint256 x;\\n uint256 y;\\n uint256 z;\\n}\\n\\nlibrary LibSecp256r1 {\\n uint256 constant gx =\\n 0x6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296;\\n uint256 constant gy =\\n 0x4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5;\\n uint256 public constant pp =\\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF;\\n\\n uint256 public constant nn =\\n 0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551;\\n uint256 constant a =\\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC;\\n uint256 constant b =\\n 0x5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B;\\n uint256 constant MOST_SIGNIFICANT =\\n 0xc000000000000000000000000000000000000000000000000000000000000000;\\n\\n /*\\n * Verify\\n * @description - verifies that a public key has signed a given message\\n * @param Q - public key coordinates X & Y\\n * @param R - signature half R\\n * @param S - signature half S\\n * @param input - hashed message\\n */\\n function Verify(\\n uint256[2] memory q,\\n uint r,\\n uint s,\\n uint e\\n ) internal view returns (bool) {\\n if (q[0] > pp - 1 || q[1] > pp - 1) {\\n return false;\\n }\\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\\n return false;\\n }\\n if (\\n mulmod(q[1], q[1], pp) !=\\n addmod(\\n addmod(\\n mulmod(q[0], mulmod(q[0], q[0], pp), pp),\\n mulmod(a, q[0], pp),\\n pp\\n ),\\n b,\\n pp\\n )\\n ) {\\n return false;\\n }\\n\\n JPoint[16] memory points = _preComputeJacobianPoints(q);\\n return VerifyWithPrecompute(points, r, s, e);\\n }\\n\\n function VerifyWithPrecompute(\\n JPoint[16] memory points,\\n uint r,\\n uint s,\\n uint e\\n ) internal view returns (bool) {\\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\\n return false;\\n }\\n\\n uint w = _primemod(s, nn);\\n\\n uint u1 = mulmod(e, w, nn);\\n uint u2 = mulmod(r, w, nn);\\n\\n uint x;\\n uint y;\\n\\n (x, y) = ShamirMultJacobian(points, u1, u2);\\n return (x == r);\\n }\\n\\n /*\\n * Strauss Shamir trick for EC multiplication\\n * https://stackoverflow.com/questions/50993471/ec-scalar-multiplication-with-strauss-shamir-method\\n * we optimise on this a bit to do with 2 bits at a time rather than a single bit\\n * the individual points for a single pass are precomputed\\n * overall this reduces the number of additions while keeping the same number of doublings\\n */\\n function ShamirMultJacobian(\\n JPoint[16] memory points,\\n uint u1,\\n uint u2\\n ) internal view returns (uint, uint) {\\n uint x = 0;\\n uint y = 0;\\n uint z = 0;\\n uint bits = 128;\\n uint index = 0;\\n\\n while (bits > 0) {\\n if (z > 0) {\\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\\n }\\n index =\\n ((u1 & MOST_SIGNIFICANT) >> 252) |\\n ((u2 & MOST_SIGNIFICANT) >> 254);\\n if (index > 0) {\\n (x, y, z) = _jAdd(\\n x,\\n y,\\n z,\\n points[index].x,\\n points[index].y,\\n points[index].z\\n );\\n }\\n u1 <<= 2;\\n u2 <<= 2;\\n bits--;\\n }\\n (x, y) = _affineFromJacobian(x, y, z);\\n return (x, y);\\n }\\n\\n function _preComputeJacobianPoints(\\n uint256[2] memory q\\n ) internal pure returns (JPoint[16] memory points) {\\n points[0] = JPoint(0, 0, 0);\\n points[1] = JPoint(q[0], q[1], 1); // u2\\n points[2] = _jPointDouble(points[1]);\\n points[3] = _jPointAdd(points[1], points[2]);\\n\\n points[4] = JPoint(gx, gy, 1); // u1Points[1]\\n points[5] = _jPointAdd(points[4], points[1]);\\n points[6] = _jPointAdd(points[4], points[2]);\\n points[7] = _jPointAdd(points[4], points[3]);\\n\\n points[8] = _jPointDouble(points[4]); // u1Points[2]\\n points[9] = _jPointAdd(points[8], points[1]);\\n points[10] = _jPointAdd(points[8], points[2]);\\n points[11] = _jPointAdd(points[8], points[3]);\\n\\n points[12] = _jPointAdd(points[4], points[8]); // u1Points[3]\\n points[13] = _jPointAdd(points[12], points[1]);\\n points[14] = _jPointAdd(points[12], points[2]);\\n points[15] = _jPointAdd(points[12], points[3]);\\n }\\n\\n function _jPointAdd(\\n JPoint memory p1,\\n JPoint memory p2\\n ) internal pure returns (JPoint memory) {\\n uint x;\\n uint y;\\n uint z;\\n (x, y, z) = _jAdd(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z);\\n return JPoint(x, y, z);\\n }\\n\\n function _jPointDouble(\\n JPoint memory p\\n ) internal pure returns (JPoint memory) {\\n uint x;\\n uint y;\\n uint z;\\n (x, y, z) = _modifiedJacobianDouble(p.x, p.y, p.z);\\n return JPoint(x, y, z);\\n }\\n\\n /* _affineFromJacobian\\n * @desription returns affine coordinates from a jacobian input follows\\n * golang elliptic/crypto library\\n */\\n function _affineFromJacobian(\\n uint x,\\n uint y,\\n uint z\\n ) internal view returns (uint ax, uint ay) {\\n if (z == 0) {\\n return (0, 0);\\n }\\n\\n uint zinv = _primemod(z, pp);\\n uint zinvsq = mulmod(zinv, zinv, pp);\\n\\n ax = mulmod(x, zinvsq, pp);\\n ay = mulmod(y, mulmod(zinvsq, zinv, pp), pp);\\n }\\n\\n /*\\n * _jAdd\\n * @description performs Jacobian addition as defined below:\\n * http://www.hyperelliptic.org/EFD/g1p/data/shortw/jacobian/addition/add-2007-bl\\n */\\n function _jAdd(\\n uint p1,\\n uint p2,\\n uint p3,\\n uint q1,\\n uint q2,\\n uint q3\\n ) internal pure returns (uint r1, uint r2, uint r3) {\\n if (p3 == 0) {\\n r1 = q1;\\n r2 = q2;\\n r3 = q3;\\n\\n return (r1, r2, r3);\\n } else if (q3 == 0) {\\n r1 = p1;\\n r2 = p2;\\n r3 = p3;\\n\\n return (r1, r2, r3);\\n }\\n\\n assembly {\\n let\\n pd\\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\\n let z1z1 := mulmod(p3, p3, pd) // Z1Z1 = Z1^2\\n let z2z2 := mulmod(q3, q3, pd) // Z2Z2 = Z2^2\\n\\n let u1 := mulmod(p1, z2z2, pd) // U1 = X1*Z2Z2\\n let u2 := mulmod(q1, z1z1, pd) // U2 = X2*Z1Z1\\n\\n let s1 := mulmod(p2, mulmod(z2z2, q3, pd), pd) // S1 = Y1*Z2*Z2Z2\\n let s2 := mulmod(q2, mulmod(z1z1, p3, pd), pd) // S2 = Y2*Z1*Z1Z1\\n\\n let p3q3 := addmod(p3, q3, pd)\\n\\n if lt(u2, u1) {\\n u2 := add(pd, u2) // u2 = u2+pd\\n }\\n let h := sub(u2, u1) // H = U2-U1\\n\\n let i := mulmod(0x02, h, pd)\\n i := mulmod(i, i, pd) // I = (2*H)^2\\n\\n let j := mulmod(h, i, pd) // J = H*I\\n if lt(s2, s1) {\\n s2 := add(pd, s2) // u2 = u2+pd\\n }\\n let rr := mulmod(0x02, sub(s2, s1), pd) // r = 2*(S2-S1)\\n r1 := mulmod(rr, rr, pd) // X3 = R^2\\n\\n let v := mulmod(u1, i, pd) // V = U1*I\\n let j2v := addmod(j, mulmod(0x02, v, pd), pd)\\n if lt(r1, j2v) {\\n r1 := add(pd, r1) // X3 = X3+pd\\n }\\n r1 := sub(r1, j2v)\\n\\n // Y3 = r*(V-X3)-2*S1*J\\n let s12j := mulmod(mulmod(0x02, s1, pd), j, pd)\\n\\n if lt(v, r1) {\\n v := add(pd, v)\\n }\\n r2 := mulmod(rr, sub(v, r1), pd)\\n\\n if lt(r2, s12j) {\\n r2 := add(pd, r2)\\n }\\n r2 := sub(r2, s12j)\\n\\n // Z3 = ((Z1+Z2)^2-Z1Z1-Z2Z2)*H\\n z1z1 := addmod(z1z1, z2z2, pd)\\n j2v := mulmod(p3q3, p3q3, pd)\\n if lt(j2v, z1z1) {\\n j2v := add(pd, j2v)\\n }\\n r3 := mulmod(sub(j2v, z1z1), h, pd)\\n }\\n return (r1, r2, r3);\\n }\\n\\n // Point doubling on the modified jacobian coordinates\\n // http://point-at-infinity.org/ecc/Prime_Curve_Modified_Jacobian_Coordinates.html\\n function _modifiedJacobianDouble(\\n uint x,\\n uint y,\\n uint z\\n ) internal pure returns (uint x3, uint y3, uint z3) {\\n if (y == 0) return (0, 0, 0);\\n assembly {\\n let\\n pd\\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\\n let z2 := mulmod(z, z, pd)\\n let az4 := mulmod(\\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC,\\n mulmod(z2, z2, pd),\\n pd\\n )\\n let y2 := mulmod(y, y, pd)\\n let s := mulmod(0x04, mulmod(x, y2, pd), pd)\\n let u := mulmod(0x08, mulmod(y2, y2, pd), pd)\\n let m := addmod(mulmod(0x03, mulmod(x, x, pd), pd), az4, pd)\\n let twos := mulmod(0x02, s, pd)\\n let m2 := mulmod(m, m, pd)\\n if lt(m2, twos) {\\n m2 := add(pd, m2)\\n }\\n x3 := sub(m2, twos)\\n if lt(s, x3) {\\n s := add(pd, s)\\n }\\n y3 := mulmod(m, sub(s, x3), pd)\\n if lt(y3, u) {\\n y3 := add(pd, y3)\\n }\\n y3 := sub(y3, u)\\n z3 := mulmod(0x02, mulmod(y, z, pd), pd)\\n }\\n }\\n\\n // Fermats little theorem https://en.wikipedia.org/wiki/Fermat%27s_little_theorem\\n // a^(p-1) = 1 mod p\\n // a^(-1) \\u2245 a^(p-2) (mod p)\\n // we then use the precompile bigModExp to compute a^(-1)\\n function _primemod(uint value, uint p) internal view returns (uint ret) {\\n ret = modexp(value, p - 2, p);\\n return ret;\\n }\\n\\n // Wrapper for built-in BigNumber_modexp (contract 0x5) as described here. https://github.com/ethereum/EIPs/pull/198\\n function modexp(\\n uint _base,\\n uint _exp,\\n uint _mod\\n ) internal view returns (uint ret) {\\n // bigModExp(_base, _exp, _mod);\\n assembly {\\n if gt(_base, _mod) {\\n _base := mod(_base, _mod)\\n }\\n // Free memory pointer is always stored at 0x40\\n let freemem := mload(0x40)\\n\\n mstore(freemem, 0x20)\\n mstore(add(freemem, 0x20), 0x20)\\n mstore(add(freemem, 0x40), 0x20)\\n\\n mstore(add(freemem, 0x60), _base)\\n mstore(add(freemem, 0x80), _exp)\\n mstore(add(freemem, 0xa0), _mod)\\n\\n let success := staticcall(14000, 0x5, freemem, 0xc0, freemem, 0x20)\\n switch success\\n case 0 {\\n revert(0x0, 0x0)\\n }\\n default {\\n ret := mload(freemem)\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb53714ba63cddb379ba312c1e7f6a423f4d7a7e34fa1364ec8295cd57d544024\",\"license\":\"GPL-3.0\"},\"contracts/infrastructure/interfaces/IFacetRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Registry Interface\\n * @dev Interface for Facet Registry contract to keep track of facets & function selectors addable to user wallets\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IFacetRegistry {\\n struct FacetRegistryConfig {\\n bytes4[] selectors;\\n mapping(bytes4 => FacetInfo) info;\\n }\\n struct FacetInfo {\\n bool exists;\\n uint128 index;\\n }\\n\\n event FacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] facetSelectors\\n );\\n event FacetFunctionSelectorsRemoved(address facet, bytes4[] facetSelectors);\\n\\n error FacetRegistry__FacetSelectorAlreadyRegistered();\\n error FacetRegistry__UnregisteredFacetSelector();\\n\\n function registerFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function removeFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function areFacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external view returns (bool);\\n\\n function isFacetFunctionSelectorRegistered(\\n address facet,\\n bytes4 facetSelector\\n ) external view returns (bool);\\n\\n function getFacetFunctionSelectors(\\n address facet\\n ) external view returns (bytes4[] memory);\\n}\\n\",\"keccak256\":\"0x6e6dd2cab346ef7c31230740ec48d2925e4a9ab24c2f2fb268baaf408dcf02ef\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC1271 {\\n function isValidSignature(\\n bytes32 hash,\\n bytes memory signature\\n ) external view returns (bytes4);\\n}\\n\",\"keccak256\":\"0xcdddb7d5641c9d3f2432dec7fd13fddb9ae1480f25c76c21511e2fa16b8bd422\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibAppStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {SafeCast} from \\\"@openzeppelin/contracts/utils/math/SafeCast.sol\\\";\\nimport {IEntryPoint} from \\\"../aa-4337/interfaces/IEntryPoint.sol\\\";\\nimport {IFacetRegistry} from \\\"../infrastructure/interfaces/IFacetRegistry.sol\\\";\\n\\n/*\\n * @title App Storage\\n * @dev App storage for Barz contract to prevent storage collision\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Lock {\\n uint64 release;\\n bytes4 locker;\\n}\\n\\nstruct InitializersStorage {\\n // NOTE: initialized is a variable to make sure the initialization is only done once.\\n uint8 signerInitialized;\\n uint8 accountInitialized;\\n uint8 restrictionsInitialized;\\n}\\n\\nstruct AppStorage {\\n mapping(uint256 => InitializersStorage) initStorage;\\n uint8 signerMigration;\\n bytes4 validateOwnerSignatureSelector;\\n IEntryPoint entryPoint;\\n IFacetRegistry facetRegistry;\\n mapping(uint256 => Lock) locks;\\n}\\n\\nlibrary LibAppStorage {\\n error LibAppStorage__AccountAlreadyUninitialized();\\n error LibAppStorage__AccountMustBeUninitialized();\\n error LibAppStorage__SignerAlreadyUninitialized();\\n error LibAppStorage__SignerMustBeUninitialized();\\n\\n function appStorage() internal pure returns (AppStorage storage ds) {\\n assembly {\\n ds.slot := 0\\n }\\n }\\n\\n function setSignerUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerAlreadyUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 0;\\n }\\n\\n function getValidateOwnerSignatureSelector()\\n internal\\n view\\n returns (bytes4 selector)\\n {\\n selector = appStorage().validateOwnerSignatureSelector;\\n }\\n\\n function setValidateOwnerSignatureSelector(\\n bytes4 _validateOwnerSignatureSelector\\n ) internal {\\n appStorage()\\n .validateOwnerSignatureSelector = _validateOwnerSignatureSelector;\\n }\\n\\n function enforceSignerInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerMustBeUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 1;\\n }\\n\\n function enforceAccountInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].accountInitialized) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n s.initStorage[0].accountInitialized = 1;\\n }\\n\\n function initiateSignerMigration() internal {\\n appStorage().signerMigration = 1;\\n }\\n\\n function enforceSignerMigration() internal view {\\n if (1 != appStorage().signerMigration) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n }\\n\\n function finalizeSignerMigration() internal {\\n appStorage().signerMigration = 0;\\n }\\n\\n function setLock(uint256 _releaseAfter, bytes4 _locker) internal {\\n appStorage().locks[0] = Lock(SafeCast.toUint64(_releaseAfter), _locker);\\n }\\n\\n function enforceRestrictionsInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__SignerMustBeUninitialized();\\n s.initStorage[0].restrictionsInitialized = 1;\\n }\\n\\n function setRestrictionsUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__AccountAlreadyUninitialized();\\n s.initStorage[0].restrictionsInitialized = 0;\\n }\\n}\\n\\ncontract BarzStorage {\\n AppStorage internal s;\\n modifier onlyWhenUnlocked() {\\n require(\\n uint64(block.timestamp) >= s.locks[0].release,\\n \\\"Account Locked\\\"\\n );\\n _;\\n }\\n modifier onlyWhenLocked() {\\n require(\\n uint64(block.timestamp) < s.locks[0].release,\\n \\\"Account Unlocked\\\"\\n );\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x48524007862a6ce0e07f645950613ce6513ce073c37a109c75019683d42bae27\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\\n bytes4(keccak256(\\\"verifyRestrictions(address,address,uint256,bytes)\\\"));\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // Default Fallback Handler of the barz.\\n IDiamondLoupe defaultFallbackHandler;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function enforceIsSelf() internal view {\\n require(msg.sender == address(this), \\\"LibDiamond: Caller not self\\\");\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n\\n unchecked {\\n facetIndex++;\\n }\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n\\n function restrictionsFacet() internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(\\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2cabdc00de859c3a3170ce3bda5d0e5fd3933d47ce904fd1585f9818b02572f8\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibFacetStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Storage\\n * @dev Storage contract to store each facets variables with diamond storage\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Secp256k1VerificationStorage {\\n address signer;\\n}\\n\\nstruct Secp256r1VerificationStorage {\\n uint256[2] q;\\n}\\n\\nstruct GuardianStorage {\\n mapping(bytes32 => uint256) pending;\\n mapping(uint8 => StorageConfig) configs;\\n}\\n\\nstruct Info {\\n bool exists;\\n uint128 index;\\n}\\n\\nstruct StorageConfig {\\n address[] addresses;\\n mapping(address => Info) info;\\n}\\n\\nstruct RecoveryConfig {\\n bytes recoveryPublicKey;\\n uint64 executeAfter;\\n}\\n\\nstruct ApprovalConfig {\\n bool isApproved;\\n uint64 validUntil;\\n}\\n\\nstruct RecoveryApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isNewOwnerApproved;\\n}\\n\\nstruct RecoveryStorage {\\n mapping(uint8 => RecoveryConfig) recoveryConfigs;\\n mapping(uint8 => RecoveryApprovalConfig) recoveryApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct RestrictionsStorage {\\n address[] restrictions;\\n mapping(address => bool) exists;\\n}\\n\\nstruct SignatureMigrationConfig {\\n bytes migrationPublicKey;\\n address migrationVerificationFacet;\\n bytes4[] migrationSelectors;\\n uint64 migrateAfter;\\n}\\n\\nstruct SignatureMigrationApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isMigrationApproved;\\n}\\n\\nstruct SignatureMigrationStorage {\\n mapping(uint8 => SignatureMigrationConfig) migrationConfigs;\\n mapping(uint8 => SignatureMigrationApprovalConfig) migrationApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct DiamondCutApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isDiamondCutApproved;\\n}\\n\\nstruct DiamondCutStorage {\\n mapping(uint8 => DiamondCutApprovalConfig) diamondCutApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct LockStorage {\\n uint128 nonce;\\n}\\n\\nlibrary LibFacetStorage {\\n bytes32 constant K1_STORAGE_POSITION =\\n keccak256(\\n \\\"v0.trustwallet.diamond.storage.Secp256k1VerificationStorage\\\"\\n );\\n bytes32 constant R1_STORAGE_POSITION =\\n keccak256(\\n \\\"v0.trustwallet.diamond.storage.Secp256r1VerificationStorage\\\"\\n );\\n bytes32 constant GUARDIAN_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.GuardianStorage\\\");\\n bytes32 constant RECOVERY_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.RecoveryStorage\\\");\\n bytes32 constant RESTRICTION_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.RestrictionsStorage\\\");\\n bytes32 constant MIGRATION_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.SignatureMigrationStorage\\\");\\n bytes32 constant DIAMONDCUT_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.DiamondCutStorage\\\");\\n bytes32 constant LOCK_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.LockStorage\\\");\\n\\n function k1Storage()\\n internal\\n pure\\n returns (Secp256k1VerificationStorage storage ds)\\n {\\n bytes32 storagePosition = K1_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function r1Storage()\\n internal\\n pure\\n returns (Secp256r1VerificationStorage storage ds)\\n {\\n bytes32 storagePosition = R1_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function guardianStorage()\\n internal\\n pure\\n returns (GuardianStorage storage ds)\\n {\\n bytes32 storagePosition = GUARDIAN_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function recoveryStorage()\\n internal\\n pure\\n returns (RecoveryStorage storage ds)\\n {\\n bytes32 storagePosition = RECOVERY_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function restrictionsStorage()\\n internal\\n pure\\n returns (RestrictionsStorage storage ds)\\n {\\n bytes32 storagePosition = RESTRICTION_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function migrationStorage()\\n internal\\n pure\\n returns (SignatureMigrationStorage storage ds)\\n {\\n bytes32 storagePosition = MIGRATION_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function diamondCutStorage()\\n internal\\n pure\\n returns (DiamondCutStorage storage ds)\\n {\\n bytes32 storagePosition = DIAMONDCUT_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function lockStorage() internal pure returns (LockStorage storage ds) {\\n bytes32 storagePosition = LOCK_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n}\\n\",\"keccak256\":\"0x87c85decfd943deda9540733e464cb1a92eba735a301e89ce6f798016e359761\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\nimport {LibDiamond} from \\\"./LibDiamond.sol\\\";\\n\\n/**\\n * @title LibLoupe\\n * @dev Internal Library to provide utility feature for reading the state of diamond facets\\n * Originally from Diamond's implementation of Mudgen(author of EIP-2535)\\n */\\nlibrary LibLoupe {\\n /// @notice Gets all facets and their selectors.\\n /// @return facets_ Facet\\n function facets()\\n internal\\n view\\n returns (IDiamondLoupe.Facet[] memory facets_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facets_ = new IDiamondLoupe.Facet[](ds.selectorCount);\\n uint16[] memory numFacetSelectors = new uint16[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facets_[facetIndex].facetAddress == facetAddress_) {\\n facets_[facetIndex].functionSelectors[\\n numFacetSelectors[facetIndex]\\n ] = selector;\\n // probably will never have more than 256 functions from one facet contract\\n require(numFacetSelectors[facetIndex] < 255);\\n numFacetSelectors[facetIndex]++;\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facets_[numFacets].facetAddress = facetAddress_;\\n facets_[numFacets].functionSelectors = new bytes4[](\\n ds.selectorCount\\n );\\n facets_[numFacets].functionSelectors[0] = selector;\\n numFacetSelectors[numFacets] = 1;\\n numFacets++;\\n }\\n }\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n uint256 numSelectors = numFacetSelectors[facetIndex];\\n bytes4[] memory selectors = facets_[facetIndex].functionSelectors;\\n // setting the number of selectors\\n assembly {\\n mstore(selectors, numSelectors)\\n }\\n }\\n // setting the number of facets\\n assembly {\\n mstore(facets_, numFacets)\\n }\\n }\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return _facetFunctionSelectors The selectors associated with a facet address.\\n function facetFunctionSelectors(\\n address _facet\\n ) internal view returns (bytes4[] memory _facetFunctionSelectors) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n uint256 numSelectors;\\n _facetFunctionSelectors = new bytes4[](ds.selectorCount);\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facet = address(bytes20(ds.facets[selector]));\\n if (_facet == facet) {\\n _facetFunctionSelectors[numSelectors] = selector;\\n numSelectors++;\\n }\\n }\\n }\\n // Set the number of selectors in the array\\n assembly {\\n mstore(_facetFunctionSelectors, numSelectors)\\n }\\n }\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n internal\\n view\\n returns (address[] memory facetAddresses_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetAddresses_ = new address[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facetAddress_ == facetAddresses_[facetIndex]) {\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facetAddresses_[numFacets] = facetAddress_;\\n numFacets++;\\n }\\n }\\n // Set the number of facet addresses in the array\\n assembly {\\n mstore(facetAddresses_, numFacets)\\n }\\n }\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(LibDiamond.diamondStorage().facets[_functionSelector])\\n );\\n }\\n}\\n\",\"keccak256\":\"0x0b11439c3cc657095e15ec2241fdcf67204b14001357b612fc5db4ff9e760a5a\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x60a060405234801561001057600080fd5b50610019610022565b3060805261008b565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff161561006f57604051637c2cde8b60e01b815260040160405180910390fd5b600080805260209190915260409020805460ff19166001179055565b608051611f746100ad6000396000818161016001526106e10152611f746000f3fe608060405234801561001057600080fd5b50600436106100a35760003560e01c80637104ddb2116100765780638dd501211161005b5780638dd50121146101bc578063cd00e50a146101cf578063cd9b47e4146101d757600080fd5b80637104ddb21461015b5780638da5cb5b146101a757600080fd5b806311cfe388146100a85780631626ba7e146100ce5780633253960f14610112578063392dd6d914610138575b600080fd5b6100bb6100b6366004611823565b6101ea565b6040519081526020015b60405180910390f35b6100e16100dc366004611956565b610252565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020016100c5565b7f8dd50121000000000000000000000000000000000000000000000000000000006100e1565b61014b61014636600461199d565b6102fd565b60405190151581526020016100c5565b6101827f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100c5565b6101af61036f565b6040516100c591906119f6565b6100bb6101ca366004611a47565b6103ba565b6100bb61041f565b6100bb6101e5366004611a8c565b61053a565b600061023982846101ff610140880188611afe565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061083692505050565b610244576001610247565b60005b60ff16949350505050565b60006102aa7f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b1653646040805180820191829052919060029082845b81548152602001906001019080831161028b5750505050508484610836565b6102d4577fffffffff000000000000000000000000000000000000000000000000000000006102f6565b7f1626ba7e000000000000000000000000000000000000000000000000000000005b9392505050565b60008151604114801561036957508160008151811061031e5761031e611b6a565b6020910101517fff00000000000000000000000000000000000000000000000000000000000000167f0400000000000000000000000000000000000000000000000000000000000000145b92915050565b6040516060907f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364906103a5908290602001611b99565b60405160208183030381529060405291505090565b60408051808201918290526000917f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364916104179186918691859060029082845b8154815260200190600101908083116103fa5750505050506101ea565b949350505050565b60006104296109b4565b6104316109f4565b60408051808201909152600080825260208201527f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364906104749082906002611675565b506000610488600154610100900460e01b90565b7fffffffff0000000000000000000000000000000000000000000000000000000016036104e1576040517f127c609a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff169055604051600192507fcccd30db6bc000b8bb8d11162228d2d69e3c361983ca3ae8c1365ce64b0fae9e90600090a15090565b6000610544610a93565b61058383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102fd92505050565b6105b9576040517f6c334d2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006105c88360018187611bcd565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092935061060992506116b8915050565b602082015181526040820151602082015260006106437f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b16536490565b9050610651818360026116d6565b507f8dd50121000000000000000000000000000000000000000000000000000000006000610686600154610100900460e01b90565b7fffffffff0000000000000000000000000000000000000000000000000000000016146106df576040517f5f95a63c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16610770827fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604090205460601c90565b73ffffffffffffffffffffffffffffffffffffffff16146107bd576040517fbb4752b700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff1661010060e084901c02179055600194507f6d54821a69ec281ed7ba1bf2729c700768c47df1d80fad646b0a14cc1d5c39ed8787604051610824929190611bf7565b60405180910390a15050505092915050565b600080600080600080868060200190518101906108539190611c94565b9450945094509450945060008061088a8a60405160200161087691815260200190565b604051602081830303815290604052610b33565b905060008482856040516020016108a393929190611d47565b60405160208183030381529060405290506002816040516108c49190611d8a565b602060405180830381855afa1580156108e1573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906109049190611da6565b9250505060006002858360405160200161091f929190611dbf565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905261095791611d8a565b602060405180830381855afa158015610974573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906109979190611da6565b90506109a58b888884610c6f565b9b9a5050505050505050505050565b6001805460ff16146109f2576040517f38fc28cb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff16600114610a5c576040517fe00d7c7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff1615610af9576040517f7c2cde8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b60608151600003610b5257505060408051602081019091526000815290565b6000604051806060016040528060408152602001611eff6040913990506000600684516008610b819190611e10565b610b8b9190611e56565b9050600060068551610b9d9190611e6a565b1115610bb15780610bad81611e7e565b9150505b60008167ffffffffffffffff811115610bcc57610bcc61177c565b6040519080825280601f01601f191660200182016040528015610bf6576020820181803683370190505b509050600183016020820186875188015b80821015610c62576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f8116850151845350600183019250610c07565b5092979650505050505050565b6000610c9c60017fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611eb6565b85511180610cd75750610cd060017fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611eb6565b6020860151115b15610ce457506000610417565b831580610cef575082155b80610d1a57507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518410155b80610d4557507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518310155b15610d5257506000610417565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff7f5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff8088600060200201517fffffffff00000001000000000000000000000000fffffffffffffffffffffffc0988517fffffffff00000001000000000000000000000000ffffffffffffffffffffffff90819080098a5109080860208601517fffffffff00000001000000000000000000000000ffffffffffffffffffffffff90800914610e4357506000610417565b6000610e4e86610e66565b9050610e5c81868686611062565b9695505050505050565b610e6e611704565b60405180606001604052806000815260200160008152602001600081525081600060108110610e9f57610e9f611b6a565b60200201526040805160608101909152808360006020020151815260200183600160028110610ed057610ed0611b6a565b60200201518152602001600181525081600160108110610ef257610ef2611b6a565b6020020152610f088160015b602002015161116f565b6040820152610f278160015b60200201518260025b60200201516111d1565b6060828101919091526040805191820181527f6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c29682527f4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f560208301526001908201526080820152610fa18160045b6020020151826001610f1d565b60a0820152610fb1816004610f14565b60c0820152610fca8160045b6020020151826003610f1d565b60e0820152610fda816004610efe565b610100820152610feb816008610f94565b610120820152610ffc816008610f14565b61014082015261100d816008610fbd565b610160820152608081015161102490826008610f1d565b61018082015261103581600c610f94565b6101a082015261104681600c610f14565b6101c082015261105781600c610fbd565b6101e0820152919050565b600083158061106f575082155b8061109a57507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518410155b806110c557507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518310155b156110d257506000610417565b60006110fe847fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551611243565b905060007fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551828509905060007fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551838809905060008061115e8a858561125a565b509098149998505050505050505050565b61119360405180606001604052806000815260200160008152602001600081525090565b60008060006111af856000015186602001518760400151611346565b6040805160608101825293845260208401929092529082015295945050505050565b6111f560405180606001604052806000815260200160008152602001600081525090565b6000806000611220866000015187602001518860400151886000015189602001518a60400151611424565b604080516060810182529384526020840192909252908201529695505050505050565b60006102f683611254600285611eb6565b8461155c565b6000808080806080815b81156113285782156112955761127b858585611346565b9196509450925061128d858585611346565b919650945092505b50600c60fc89901c1660fe88901c17801561130b576113038585858d85601081106112c2576112c2611b6a565b6020020151518e86601081106112da576112da611b6a565b6020020151602001518f87601081106112f5576112f5611b6a565b602002015160400151611424565b919650945092505b600298891b989790971b968161132081611ec9565b925050611264565b6113338585856115b0565b909750955050505050505b935093915050565b6000806000846000036113615750600091508190508061141b565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff8085860981828283097fffffffff00000001000000000000000000000000fffffffffffffffffffffffc099050818788098283828b0960040983848384096008099150838385868d8e09600309089250838160020984848509818110156113e65785015b039650868110156113f45783015b8387820384099550508085101561140a57938201935b909303925080808688096002099150505b93509350939050565b60008060008660000361143e575084915083905082611550565b83600003611453575087915086905085611550565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff808889098186870982818d0983838b0984858a85098e0985868e87098c09868b8f08848410156114a357928701925b8484039350878460020988818209905088818609848410156114c457928901925b898585036002099350898485099c50898288099650898a8860020982089150818d10156114f0579b89019b5b818d039c5089818b87600209099450508b86101561150d57948801945b888c870384099a50838b101561152257998801995b838b039a508887890897508882830990508781101561153e5788015b88858983030999505050505050505050505b96509650969350505050565b60008184111561156c5781840693505b60405160208152602080820152602060408201528460608201528360808201528260a082015260208160c08360056136b0fa8080156100a357505051949350505050565b600080826000036115c65750600090508061133e565b60006115f2847fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611243565b905060007fffffffff00000001000000000000000000000000ffffffffffffffffffffffff82830990507fffffffff00000001000000000000000000000000ffffffffffffffffffffffff81880993507fffffffff00000001000000000000000000000000ffffffffffffffffffffffff80838309870992505050935093915050565b82600281019282156116a8579160200282015b828111156116a8578251829060ff16905591602001919060010190611688565b506116b492915061174e565b5090565b60405180604001604052806002906020820280368337509192915050565b82600281019282156116a8579160200282015b828111156116a85782518255916020019190600101906116e9565b6040518061020001604052806010905b61173860405180606001604052806000815260200160008152602001600081525090565b8152602001906001900390816117145790505090565b5b808211156116b4576000815560010161174f565b6000610160828403121561177657600080fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156117ce576117ce61177c565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561181b5761181b61177c565b604052919050565b60008060006080848603121561183857600080fd5b833567ffffffffffffffff81111561184f57600080fd5b61185b86828701611763565b935050602080850135925085605f86011261187557600080fd5b61187d6117ab565b80608087018881111561188f57600080fd5b604088015b818110156118ab5780358452928401928401611894565b50508093505050509250925092565b600067ffffffffffffffff8211156118d4576118d461177c565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261191157600080fd5b813561192461191f826118ba565b6117d4565b81815284602083860101111561193957600080fd5b816020850160208301376000918101602001919091529392505050565b6000806040838503121561196957600080fd5b82359150602083013567ffffffffffffffff81111561198757600080fd5b61199385828601611900565b9150509250929050565b6000602082840312156119af57600080fd5b813567ffffffffffffffff8111156119c657600080fd5b61041784828501611900565b60005b838110156119ed5781810151838201526020016119d5565b50506000910152565b6020815260008251806020840152611a158160408501602087016119d2565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b60008060408385031215611a5a57600080fd5b823567ffffffffffffffff811115611a7157600080fd5b611a7d85828601611763565b95602094909401359450505050565b60008060208385031215611a9f57600080fd5b823567ffffffffffffffff80821115611ab757600080fd5b818501915085601f830112611acb57600080fd5b813581811115611ada57600080fd5b866020828501011115611aec57600080fd5b60209290920196919550909350505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112611b3357600080fd5b83018035915067ffffffffffffffff821115611b4e57600080fd5b602001915036819003821315611b6357600080fd5b9250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008183825b6002811015611bbe578154835260209092019160019182019101611b9f565b50505060408201905092915050565b60008085851115611bdd57600080fd5b83861115611bea57600080fd5b5050820193919092039150565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b6000611c5261191f846118ba565b9050828152838383011115611c6657600080fd5b6102f68360208301846119d2565b600082601f830112611c8557600080fd5b6102f683835160208501611c44565b600080600080600060a08688031215611cac57600080fd5b8551945060208601519350604086015167ffffffffffffffff80821115611cd257600080fd5b818801915088601f830112611ce657600080fd5b611cf589835160208501611c44565b94506060880151915080821115611d0b57600080fd5b611d1789838a01611c74565b93506080880151915080821115611d2d57600080fd5b50611d3a88828901611c74565b9150509295509295909350565b60008451611d598184602089016119d2565b845190830190611d6d8183602089016119d2565b8451910190611d808183602088016119d2565b0195945050505050565b60008251611d9c8184602087016119d2565b9190910192915050565b600060208284031215611db857600080fd5b5051919050565b60008351611dd18184602088016119d2565b9190910191825250602001919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808202811582820484141761036957610369611de1565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082611e6557611e65611e27565b500490565b600082611e7957611e79611e27565b500690565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611eaf57611eaf611de1565b5060010190565b8181038181111561036957610369611de1565b600081611ed857611ed8611de1565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392d5fa2646970667358221220d4142da7b16effb6b95f41adeff2bc8ce0d59d3b70ca8d55e6e83224bbfbec0a64736f6c63430008150033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100a35760003560e01c80637104ddb2116100765780638dd501211161005b5780638dd50121146101bc578063cd00e50a146101cf578063cd9b47e4146101d757600080fd5b80637104ddb21461015b5780638da5cb5b146101a757600080fd5b806311cfe388146100a85780631626ba7e146100ce5780633253960f14610112578063392dd6d914610138575b600080fd5b6100bb6100b6366004611823565b6101ea565b6040519081526020015b60405180910390f35b6100e16100dc366004611956565b610252565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020016100c5565b7f8dd50121000000000000000000000000000000000000000000000000000000006100e1565b61014b61014636600461199d565b6102fd565b60405190151581526020016100c5565b6101827f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100c5565b6101af61036f565b6040516100c591906119f6565b6100bb6101ca366004611a47565b6103ba565b6100bb61041f565b6100bb6101e5366004611a8c565b61053a565b600061023982846101ff610140880188611afe565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061083692505050565b610244576001610247565b60005b60ff16949350505050565b60006102aa7f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b1653646040805180820191829052919060029082845b81548152602001906001019080831161028b5750505050508484610836565b6102d4577fffffffff000000000000000000000000000000000000000000000000000000006102f6565b7f1626ba7e000000000000000000000000000000000000000000000000000000005b9392505050565b60008151604114801561036957508160008151811061031e5761031e611b6a565b6020910101517fff00000000000000000000000000000000000000000000000000000000000000167f0400000000000000000000000000000000000000000000000000000000000000145b92915050565b6040516060907f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364906103a5908290602001611b99565b60405160208183030381529060405291505090565b60408051808201918290526000917f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364916104179186918691859060029082845b8154815260200190600101908083116103fa5750505050506101ea565b949350505050565b60006104296109b4565b6104316109f4565b60408051808201909152600080825260208201527f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364906104749082906002611675565b506000610488600154610100900460e01b90565b7fffffffff0000000000000000000000000000000000000000000000000000000016036104e1576040517f127c609a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff169055604051600192507fcccd30db6bc000b8bb8d11162228d2d69e3c361983ca3ae8c1365ce64b0fae9e90600090a15090565b6000610544610a93565b61058383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102fd92505050565b6105b9576040517f6c334d2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006105c88360018187611bcd565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092935061060992506116b8915050565b602082015181526040820151602082015260006106437f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b16536490565b9050610651818360026116d6565b507f8dd50121000000000000000000000000000000000000000000000000000000006000610686600154610100900460e01b90565b7fffffffff0000000000000000000000000000000000000000000000000000000016146106df576040517f5f95a63c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16610770827fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604090205460601c90565b73ffffffffffffffffffffffffffffffffffffffff16146107bd576040517fbb4752b700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff1661010060e084901c02179055600194507f6d54821a69ec281ed7ba1bf2729c700768c47df1d80fad646b0a14cc1d5c39ed8787604051610824929190611bf7565b60405180910390a15050505092915050565b600080600080600080868060200190518101906108539190611c94565b9450945094509450945060008061088a8a60405160200161087691815260200190565b604051602081830303815290604052610b33565b905060008482856040516020016108a393929190611d47565b60405160208183030381529060405290506002816040516108c49190611d8a565b602060405180830381855afa1580156108e1573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906109049190611da6565b9250505060006002858360405160200161091f929190611dbf565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905261095791611d8a565b602060405180830381855afa158015610974573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906109979190611da6565b90506109a58b888884610c6f565b9b9a5050505050505050505050565b6001805460ff16146109f2576040517f38fc28cb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff16600114610a5c576040517fe00d7c7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff1615610af9576040517f7c2cde8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b60608151600003610b5257505060408051602081019091526000815290565b6000604051806060016040528060408152602001611eff6040913990506000600684516008610b819190611e10565b610b8b9190611e56565b9050600060068551610b9d9190611e6a565b1115610bb15780610bad81611e7e565b9150505b60008167ffffffffffffffff811115610bcc57610bcc61177c565b6040519080825280601f01601f191660200182016040528015610bf6576020820181803683370190505b509050600183016020820186875188015b80821015610c62576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f8116850151845350600183019250610c07565b5092979650505050505050565b6000610c9c60017fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611eb6565b85511180610cd75750610cd060017fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611eb6565b6020860151115b15610ce457506000610417565b831580610cef575082155b80610d1a57507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518410155b80610d4557507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518310155b15610d5257506000610417565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff7f5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff8088600060200201517fffffffff00000001000000000000000000000000fffffffffffffffffffffffc0988517fffffffff00000001000000000000000000000000ffffffffffffffffffffffff90819080098a5109080860208601517fffffffff00000001000000000000000000000000ffffffffffffffffffffffff90800914610e4357506000610417565b6000610e4e86610e66565b9050610e5c81868686611062565b9695505050505050565b610e6e611704565b60405180606001604052806000815260200160008152602001600081525081600060108110610e9f57610e9f611b6a565b60200201526040805160608101909152808360006020020151815260200183600160028110610ed057610ed0611b6a565b60200201518152602001600181525081600160108110610ef257610ef2611b6a565b6020020152610f088160015b602002015161116f565b6040820152610f278160015b60200201518260025b60200201516111d1565b6060828101919091526040805191820181527f6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c29682527f4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f560208301526001908201526080820152610fa18160045b6020020151826001610f1d565b60a0820152610fb1816004610f14565b60c0820152610fca8160045b6020020151826003610f1d565b60e0820152610fda816004610efe565b610100820152610feb816008610f94565b610120820152610ffc816008610f14565b61014082015261100d816008610fbd565b610160820152608081015161102490826008610f1d565b61018082015261103581600c610f94565b6101a082015261104681600c610f14565b6101c082015261105781600c610fbd565b6101e0820152919050565b600083158061106f575082155b8061109a57507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518410155b806110c557507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518310155b156110d257506000610417565b60006110fe847fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551611243565b905060007fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551828509905060007fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551838809905060008061115e8a858561125a565b509098149998505050505050505050565b61119360405180606001604052806000815260200160008152602001600081525090565b60008060006111af856000015186602001518760400151611346565b6040805160608101825293845260208401929092529082015295945050505050565b6111f560405180606001604052806000815260200160008152602001600081525090565b6000806000611220866000015187602001518860400151886000015189602001518a60400151611424565b604080516060810182529384526020840192909252908201529695505050505050565b60006102f683611254600285611eb6565b8461155c565b6000808080806080815b81156113285782156112955761127b858585611346565b9196509450925061128d858585611346565b919650945092505b50600c60fc89901c1660fe88901c17801561130b576113038585858d85601081106112c2576112c2611b6a565b6020020151518e86601081106112da576112da611b6a565b6020020151602001518f87601081106112f5576112f5611b6a565b602002015160400151611424565b919650945092505b600298891b989790971b968161132081611ec9565b925050611264565b6113338585856115b0565b909750955050505050505b935093915050565b6000806000846000036113615750600091508190508061141b565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff8085860981828283097fffffffff00000001000000000000000000000000fffffffffffffffffffffffc099050818788098283828b0960040983848384096008099150838385868d8e09600309089250838160020984848509818110156113e65785015b039650868110156113f45783015b8387820384099550508085101561140a57938201935b909303925080808688096002099150505b93509350939050565b60008060008660000361143e575084915083905082611550565b83600003611453575087915086905085611550565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff808889098186870982818d0983838b0984858a85098e0985868e87098c09868b8f08848410156114a357928701925b8484039350878460020988818209905088818609848410156114c457928901925b898585036002099350898485099c50898288099650898a8860020982089150818d10156114f0579b89019b5b818d039c5089818b87600209099450508b86101561150d57948801945b888c870384099a50838b101561152257998801995b838b039a508887890897508882830990508781101561153e5788015b88858983030999505050505050505050505b96509650969350505050565b60008184111561156c5781840693505b60405160208152602080820152602060408201528460608201528360808201528260a082015260208160c08360056136b0fa8080156100a357505051949350505050565b600080826000036115c65750600090508061133e565b60006115f2847fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611243565b905060007fffffffff00000001000000000000000000000000ffffffffffffffffffffffff82830990507fffffffff00000001000000000000000000000000ffffffffffffffffffffffff81880993507fffffffff00000001000000000000000000000000ffffffffffffffffffffffff80838309870992505050935093915050565b82600281019282156116a8579160200282015b828111156116a8578251829060ff16905591602001919060010190611688565b506116b492915061174e565b5090565b60405180604001604052806002906020820280368337509192915050565b82600281019282156116a8579160200282015b828111156116a85782518255916020019190600101906116e9565b6040518061020001604052806010905b61173860405180606001604052806000815260200160008152602001600081525090565b8152602001906001900390816117145790505090565b5b808211156116b4576000815560010161174f565b6000610160828403121561177657600080fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156117ce576117ce61177c565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561181b5761181b61177c565b604052919050565b60008060006080848603121561183857600080fd5b833567ffffffffffffffff81111561184f57600080fd5b61185b86828701611763565b935050602080850135925085605f86011261187557600080fd5b61187d6117ab565b80608087018881111561188f57600080fd5b604088015b818110156118ab5780358452928401928401611894565b50508093505050509250925092565b600067ffffffffffffffff8211156118d4576118d461177c565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261191157600080fd5b813561192461191f826118ba565b6117d4565b81815284602083860101111561193957600080fd5b816020850160208301376000918101602001919091529392505050565b6000806040838503121561196957600080fd5b82359150602083013567ffffffffffffffff81111561198757600080fd5b61199385828601611900565b9150509250929050565b6000602082840312156119af57600080fd5b813567ffffffffffffffff8111156119c657600080fd5b61041784828501611900565b60005b838110156119ed5781810151838201526020016119d5565b50506000910152565b6020815260008251806020840152611a158160408501602087016119d2565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b60008060408385031215611a5a57600080fd5b823567ffffffffffffffff811115611a7157600080fd5b611a7d85828601611763565b95602094909401359450505050565b60008060208385031215611a9f57600080fd5b823567ffffffffffffffff80821115611ab757600080fd5b818501915085601f830112611acb57600080fd5b813581811115611ada57600080fd5b866020828501011115611aec57600080fd5b60209290920196919550909350505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112611b3357600080fd5b83018035915067ffffffffffffffff821115611b4e57600080fd5b602001915036819003821315611b6357600080fd5b9250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008183825b6002811015611bbe578154835260209092019160019182019101611b9f565b50505060408201905092915050565b60008085851115611bdd57600080fd5b83861115611bea57600080fd5b5050820193919092039150565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b6000611c5261191f846118ba565b9050828152838383011115611c6657600080fd5b6102f68360208301846119d2565b600082601f830112611c8557600080fd5b6102f683835160208501611c44565b600080600080600060a08688031215611cac57600080fd5b8551945060208601519350604086015167ffffffffffffffff80821115611cd257600080fd5b818801915088601f830112611ce657600080fd5b611cf589835160208501611c44565b94506060880151915080821115611d0b57600080fd5b611d1789838a01611c74565b93506080880151915080821115611d2d57600080fd5b50611d3a88828901611c74565b9150509295509295909350565b60008451611d598184602089016119d2565b845190830190611d6d8183602089016119d2565b8451910190611d808183602088016119d2565b0195945050505050565b60008251611d9c8184602087016119d2565b9190910192915050565b600060208284031215611db857600080fd5b5051919050565b60008351611dd18184602088016119d2565b9190910191825250602001919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808202811582820484141761036957610369611de1565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082611e6557611e65611e27565b500490565b600082611e7957611e79611e27565b500690565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611eaf57611eaf611de1565b5060010190565b8181038181111561036957610369611de1565b600081611ed857611ed8611de1565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392d5fa2646970667358221220d4142da7b16effb6b95f41adeff2bc8ce0d59d3b70ca8d55e6e83224bbfbec0a64736f6c63430008150033", + "devdoc": { + "author": "Ruslan Serebriakov (@rsrbk)David Yongjun Kim (@Powerstream3604)", + "details": "Primarily used to verify user ops signed with passkeys", + "kind": "dev", + "methods": { + "initializeSigner(bytes)": { + "details": "This method checks if the signer has already been initialized. If already initialized, it reverts. It checks if the public key is in the light format and initializes signer storage in k1 storage.", + "params": { + "_publicKey": "Bytes of owner public key" + }, + "returns": { + "initSuccess": "Uint value representing the success of init operation" + } + }, + "isValidKeyType(bytes)": { + "details": "For this Secp256k1Verification Facet, the public key should in an uncompressed public key format", + "params": { + "_publicKey": "Bytes of public key for format check" + }, + "returns": { + "isValid": "Boolean variable representing if the format of public key is valid" + } + }, + "isValidSignature(bytes32,bytes)": { + "details": "This method verifies the signature if the owner indeed signed the hash. Returns magic value if true", + "params": { + "_hash": "Hash value the owner signed", + "_signature": "Signature that signed the above hash" + }, + "returns": { + "magicValue": "Bytes4 value representing the success/failure of validation" + } + }, + "owner()": { + "returns": { + "signer": "Bytes of owner address" + } + }, + "uninitializeSigner()": { + "details": "This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.", + "returns": { + "uninitSuccess": "Uint value representing the success of uninit operation" + } + }, + "validateOwnerSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32)": { + "details": "This method validates if the user operation is signed by the owner. It internally calls validateSignature with signer public key.", + "params": { + "userOp": "UserOperation including all information for execution", + "userOpHash": "Hash of UserOperation given from EntryPoint. This hash is used for signature validation" + }, + "returns": { + "validationData": "Uint value representing whether the validation is successful. 0 for success, 1 for failure" + } + }, + "validateOwnerSignatureSelector()": { + "returns": { + "ownerSignatureValidatorSelector": "Bytes4 selector of function signature to validate account owner's UserOperation signature" + } + }, + "validateSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256[2])": { + "details": "This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address", + "params": { + "q": "Public Key of signer who signed the contract, to be validated", + "userOp": "UserOperation including all information for execution", + "userOpHash": "Hash of UserOperation given from EntryPoint. This hash is used for signature validation" + }, + "returns": { + "isValid": "Uint value representing whether the validation is successful. 0 for success, 1 for failure" + } + } + }, + "title": "Secp256r1 verification facet", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "constructor": { + "notice": "This constructor ensures that this contract can only be used as singleton for Proxy contracts" + }, + "initializeSigner(bytes)": { + "notice": "Initializes the signer in R1 Facet Storage. This can only be called when the account is uninitialized or during signature migration." + }, + "isValidKeyType(bytes)": { + "notice": "Validates if the format of public key is valid for this verification facet" + }, + "isValidSignature(bytes32,bytes)": { + "notice": "Validates if the signature is valid. Function to be compatible with EIP-1271" + }, + "owner()": { + "notice": "Returns the owner of the account" + }, + "uninitializeSigner()": { + "notice": "Uninitialize signer in R1 Facet Storage. This can only be called when the account is undergoing signature migration and has already been initialized." + }, + "validateOwnerSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32)": { + "notice": "Validates if the user operation is signed by the owner." + }, + "validateOwnerSignatureSelector()": { + "notice": "Returns the selector of function to validate the signature of UserOperation" + }, + "validateSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256[2])": { + "notice": "Validates if the signature of UserOperation is signed by the given signer" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/opBNB/TokenReceiverFacet.json b/deployments/opBNB/TokenReceiverFacet.json new file mode 100644 index 0000000..1b107e4 --- /dev/null +++ b/deployments/opBNB/TokenReceiverFacet.json @@ -0,0 +1,239 @@ +{ + "address": "0x3143E1C0Af0Cdc153423863923Cf4e3818e34Daa", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onERC1155BatchReceived", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onERC1155Received", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onERC721Received", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onTokenTransfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "tokensReceived", + "outputs": [], + "stateMutability": "pure", + "type": "function" + } + ], + "transactionHash": "0x12e60dcc8d7b8449f0f7183a0b74c3f92cfef5071b2791d8e9471eeb92a64235", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 2, + "gasUsed": "329340", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x6aaefc312173f3ae996dcd9542d0deddcb50c74412f6dab825c565e02482e305", + "transactionHash": "0x12e60dcc8d7b8449f0f7183a0b74c3f92cfef5071b2791d8e9471eeb92a64235", + "logs": [], + "blockNumber": 8469789, + "cumulativeGasUsed": "424633", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "167a830377988095f5f829bf03425fb0", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onERC1155BatchReceived\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onERC1155Received\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onERC721Received\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"tokensReceived\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"Contract that enables receiving ERC721/ERC1155/ERC777/ERC677 Tokens with safe transfer\",\"kind\":\"dev\",\"methods\":{},\"title\":\"TokenReceiver Facet\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\":{\"notice\":\"Handles ERC1155 Token batch callback. return Standardized onERC1155BatchReceived return value.\"},\"onERC1155Received(address,address,uint256,uint256,bytes)\":{\"notice\":\"Handles ERC1155 Token callback. return Standardized onERC1155Received return value.\"},\"onERC721Received(address,address,uint256,bytes)\":{\"notice\":\"Handles ERC721 Token callback. return Standardized onERC721Received return value.\"},\"onTokenTransfer(address,uint256,bytes)\":{\"notice\":\"Handles ERC677 Token callback. return true.\"},\"tokensReceived(address,address,address,uint256,bytes,bytes)\":{\"notice\":\"Handles ERC777 Token callback. Does not return value, empty implementation.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/TokenReceiverFacet.sol\":\"TokenReceiverFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title ERC721 token receiver interface\\n * @dev Interface for any contract that wants to support safeTransfers\\n * from ERC721 asset contracts.\\n */\\ninterface IERC721Receiver {\\n /**\\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\\n * by `operator` from `from`, this function is called.\\n *\\n * It must return its Solidity selector to confirm the token transfer.\\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\\n *\\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\\n */\\n function onERC721Received(\\n address operator,\\n address from,\\n uint256 tokenId,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\\n *\\n * Accounts can be notified of {IERC777} tokens being sent to them by having a\\n * contract implement this interface (contract holders can be their own\\n * implementer) and registering it on the\\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\\n *\\n * See {IERC1820Registry} and {ERC1820Implementer}.\\n */\\ninterface IERC777Recipient {\\n /**\\n * @dev Called by an {IERC777} token contract whenever tokens are being\\n * moved or created into a registered account (`to`). The type of operation\\n * is conveyed by `from` being the zero address or not.\\n *\\n * This call occurs _after_ the token contract's state is updated, so\\n * {IERC777-balanceOf}, etc., can be used to query the post-operation state.\\n *\\n * This function may revert to prevent the operation from being executed.\\n */\\n function tokensReceived(\\n address operator,\\n address from,\\n address to,\\n uint256 amount,\\n bytes calldata userData,\\n bytes calldata operatorData\\n ) external;\\n}\\n\",\"keccak256\":\"0x1a5d61db2733202ba361e6d6741cd2e662380e22b80e987eacfc91973f2267dc\",\"license\":\"MIT\"},\"contracts/facets/TokenReceiverFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IERC721Receiver} from \\\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\\\";\\nimport {IERC777Recipient} from \\\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\\\";\\nimport {IERC1155Receiver} from \\\"../interfaces/ERC/IERC1155Receiver.sol\\\";\\nimport {IERC677Receiver} from \\\"../interfaces/ERC/IERC677Receiver.sol\\\";\\n\\n/**\\n * @title TokenReceiver Facet\\n * @dev Contract that enables receiving ERC721/ERC1155/ERC777/ERC677 Tokens with safe transfer\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract TokenReceiverFacet is\\n IERC721Receiver,\\n IERC1155Receiver,\\n IERC777Recipient,\\n IERC677Receiver\\n{\\n /**\\n * @notice Handles ERC721 Token callback.\\n * return Standardized onERC721Received return value.\\n */\\n function onERC721Received(\\n address,\\n address,\\n uint256,\\n bytes calldata\\n ) external pure override returns (bytes4) {\\n return IERC721Receiver.onERC721Received.selector;\\n }\\n\\n /**\\n * @notice Handles ERC1155 Token callback.\\n * return Standardized onERC1155Received return value.\\n */\\n function onERC1155Received(\\n address,\\n address,\\n uint256,\\n uint256,\\n bytes calldata\\n ) external pure override returns (bytes4) {\\n return IERC1155Receiver.onERC1155Received.selector;\\n }\\n\\n /**\\n * @notice Handles ERC1155 Token batch callback.\\n * return Standardized onERC1155BatchReceived return value.\\n */\\n function onERC1155BatchReceived(\\n address,\\n address,\\n uint256[] calldata,\\n uint256[] calldata,\\n bytes calldata\\n ) external pure override returns (bytes4) {\\n return IERC1155Receiver.onERC1155BatchReceived.selector;\\n }\\n\\n /**\\n * @notice Handles ERC777 Token callback.\\n * Does not return value, empty implementation.\\n */\\n function tokensReceived(\\n address,\\n address,\\n address,\\n uint256,\\n bytes calldata,\\n bytes calldata\\n ) external pure override {}\\n\\n /**\\n * @notice Handles ERC677 Token callback.\\n * return true.\\n */\\n function onTokenTransfer(\\n address,\\n uint256,\\n bytes calldata\\n ) external pure override returns (bool) {\\n return true;\\n }\\n}\\n\",\"keccak256\":\"0xdfe483d05ef4056bb464c34ade19ab527687aff3ed0b6303b447a68b5ff7abb4\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC1155Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\n\\npragma solidity 0.8.21;\\n\\n/**\\n * @dev _Available since v3.1._\\n */\\ninterface IERC1155Receiver {\\n /**\\n * @dev Handles the receipt of a single ERC1155 token type. This function is\\n * called at the end of a `safeTransferFrom` after the balance has been updated.\\n *\\n * NOTE: To accept the transfer, this must return\\n * `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))`\\n * (i.e. 0xf23a6e61, or its own function selector).\\n *\\n * @param operator The address which initiated the transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param id The ID of the token being transferred\\n * @param value The amount of tokens being transferred\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155Received(\\n address operator,\\n address from,\\n uint256 id,\\n uint256 value,\\n bytes calldata data\\n ) external returns (bytes4);\\n\\n /**\\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\\n * is called at the end of a `safeBatchTransferFrom` after the balances have\\n * been updated.\\n *\\n * NOTE: To accept the transfer(s), this must return\\n * `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))`\\n * (i.e. 0xbc197c81, or its own function selector).\\n *\\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155BatchReceived(\\n address operator,\\n address from,\\n uint256[] calldata ids,\\n uint256[] calldata values,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0x3729c6757bae3aba03ac1c5064d67ad13b94e2a9428bf44b9be510373406da0c\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC677Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC677Receiver {\\n function onTokenTransfer(\\n address sender,\\n uint value,\\n bytes calldata data\\n ) external pure returns (bool);\\n}\\n\",\"keccak256\":\"0x4c1631cf45ea6daac0ec158c3edb9453099130b6b64f697004b83f95aa1f7350\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50610502806100206000396000f3fe608060405234801561001057600080fd5b50600436106100665760003560e01c8063a4c0ed3611610050578063a4c0ed36146100f3578063bc197c811461011b578063f23a6e611461015657600080fd5b806223de291461006b578063150b7a0214610085575b600080fd5b610083610079366004610201565b5050505050505050565b005b6100bd6100933660046102ac565b7f150b7a020000000000000000000000000000000000000000000000000000000095945050505050565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020015b60405180910390f35b61010b61010136600461031b565b6001949350505050565b60405190151581526020016100ea565b6100bd6101293660046103ba565b7fbc197c810000000000000000000000000000000000000000000000000000000098975050505050505050565b6100bd610164366004610454565b7ff23a6e61000000000000000000000000000000000000000000000000000000009695505050505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146101b357600080fd5b919050565b60008083601f8401126101ca57600080fd5b50813567ffffffffffffffff8111156101e257600080fd5b6020830191508360208285010111156101fa57600080fd5b9250929050565b60008060008060008060008060c0898b03121561021d57600080fd5b6102268961018f565b975061023460208a0161018f565b965061024260408a0161018f565b955060608901359450608089013567ffffffffffffffff8082111561026657600080fd5b6102728c838d016101b8565b909650945060a08b013591508082111561028b57600080fd5b506102988b828c016101b8565b999c989b5096995094979396929594505050565b6000806000806000608086880312156102c457600080fd5b6102cd8661018f565b94506102db6020870161018f565b935060408601359250606086013567ffffffffffffffff8111156102fe57600080fd5b61030a888289016101b8565b969995985093965092949392505050565b6000806000806060858703121561033157600080fd5b61033a8561018f565b935060208501359250604085013567ffffffffffffffff81111561035d57600080fd5b610369878288016101b8565b95989497509550505050565b60008083601f84011261038757600080fd5b50813567ffffffffffffffff81111561039f57600080fd5b6020830191508360208260051b85010111156101fa57600080fd5b60008060008060008060008060a0898b0312156103d657600080fd5b6103df8961018f565b97506103ed60208a0161018f565b9650604089013567ffffffffffffffff8082111561040a57600080fd5b6104168c838d01610375565b909850965060608b013591508082111561042f57600080fd5b61043b8c838d01610375565b909650945060808b013591508082111561028b57600080fd5b60008060008060008060a0878903121561046d57600080fd5b6104768761018f565b95506104846020880161018f565b94506040870135935060608701359250608087013567ffffffffffffffff8111156104ae57600080fd5b6104ba89828a016101b8565b979a969950949750929593949250505056fea2646970667358221220ae9a97061ae9e1485161ca9c8d3228a23e47b18755fa935f51b40e927816ca2964736f6c63430008150033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100665760003560e01c8063a4c0ed3611610050578063a4c0ed36146100f3578063bc197c811461011b578063f23a6e611461015657600080fd5b806223de291461006b578063150b7a0214610085575b600080fd5b610083610079366004610201565b5050505050505050565b005b6100bd6100933660046102ac565b7f150b7a020000000000000000000000000000000000000000000000000000000095945050505050565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020015b60405180910390f35b61010b61010136600461031b565b6001949350505050565b60405190151581526020016100ea565b6100bd6101293660046103ba565b7fbc197c810000000000000000000000000000000000000000000000000000000098975050505050505050565b6100bd610164366004610454565b7ff23a6e61000000000000000000000000000000000000000000000000000000009695505050505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146101b357600080fd5b919050565b60008083601f8401126101ca57600080fd5b50813567ffffffffffffffff8111156101e257600080fd5b6020830191508360208285010111156101fa57600080fd5b9250929050565b60008060008060008060008060c0898b03121561021d57600080fd5b6102268961018f565b975061023460208a0161018f565b965061024260408a0161018f565b955060608901359450608089013567ffffffffffffffff8082111561026657600080fd5b6102728c838d016101b8565b909650945060a08b013591508082111561028b57600080fd5b506102988b828c016101b8565b999c989b5096995094979396929594505050565b6000806000806000608086880312156102c457600080fd5b6102cd8661018f565b94506102db6020870161018f565b935060408601359250606086013567ffffffffffffffff8111156102fe57600080fd5b61030a888289016101b8565b969995985093965092949392505050565b6000806000806060858703121561033157600080fd5b61033a8561018f565b935060208501359250604085013567ffffffffffffffff81111561035d57600080fd5b610369878288016101b8565b95989497509550505050565b60008083601f84011261038757600080fd5b50813567ffffffffffffffff81111561039f57600080fd5b6020830191508360208260051b85010111156101fa57600080fd5b60008060008060008060008060a0898b0312156103d657600080fd5b6103df8961018f565b97506103ed60208a0161018f565b9650604089013567ffffffffffffffff8082111561040a57600080fd5b6104168c838d01610375565b909850965060608b013591508082111561042f57600080fd5b61043b8c838d01610375565b909650945060808b013591508082111561028b57600080fd5b60008060008060008060a0878903121561046d57600080fd5b6104768761018f565b95506104846020880161018f565b94506040870135935060608701359250608087013567ffffffffffffffff8111156104ae57600080fd5b6104ba89828a016101b8565b979a969950949750929593949250505056fea2646970667358221220ae9a97061ae9e1485161ca9c8d3228a23e47b18755fa935f51b40e927816ca2964736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "Contract that enables receiving ERC721/ERC1155/ERC777/ERC677 Tokens with safe transfer", + "kind": "dev", + "methods": {}, + "title": "TokenReceiver Facet", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)": { + "notice": "Handles ERC1155 Token batch callback. return Standardized onERC1155BatchReceived return value." + }, + "onERC1155Received(address,address,uint256,uint256,bytes)": { + "notice": "Handles ERC1155 Token callback. return Standardized onERC1155Received return value." + }, + "onERC721Received(address,address,uint256,bytes)": { + "notice": "Handles ERC721 Token callback. return Standardized onERC721Received return value." + }, + "onTokenTransfer(address,uint256,bytes)": { + "notice": "Handles ERC677 Token callback. return true." + }, + "tokensReceived(address,address,address,uint256,bytes,bytes)": { + "notice": "Handles ERC777 Token callback. Does not return value, empty implementation." + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/opBNB/solcInputs/167a830377988095f5f829bf03425fb0.json b/deployments/opBNB/solcInputs/167a830377988095f5f829bf03425fb0.json new file mode 100644 index 0000000..2833a16 --- /dev/null +++ b/deployments/opBNB/solcInputs/167a830377988095f5f829bf03425fb0.json @@ -0,0 +1,354 @@ +{ + "language": "Solidity", + "sources": { + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby disabling any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable2Step.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./Ownable.sol\";\n\n/**\n * @dev Contract module which provides access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership} and {acceptOwnership}.\n *\n * This module is used through inheritance. It will make available all functions\n * from parent (Ownable).\n */\nabstract contract Ownable2Step is Ownable {\n address private _pendingOwner;\n\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Returns the address of the pending owner.\n */\n function pendingOwner() public view virtual returns (address) {\n return _pendingOwner;\n }\n\n /**\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual override onlyOwner {\n _pendingOwner = newOwner;\n emit OwnershipTransferStarted(owner(), newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual override {\n delete _pendingOwner;\n super._transferOwnership(newOwner);\n }\n\n /**\n * @dev The new owner accepts the ownership transfer.\n */\n function acceptOwnership() public virtual {\n address sender = _msgSender();\n require(pendingOwner() == sender, \"Ownable2Step: caller is not the new owner\");\n _transferOwnership(sender);\n }\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC1271.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC1271 standard signature validation method for\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\n *\n * _Available since v4.1._\n */\ninterface IERC1271 {\n /**\n * @dev Should return whether the signature provided is valid for the provided data\n * @param hash Hash of the data to be signed\n * @param signature Signature byte array associated with _data\n */\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\n}\n" + }, + "@openzeppelin/contracts/security/ReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor() {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n _nonReentrantBefore();\n _;\n _nonReentrantAfter();\n }\n\n function _nonReentrantBefore() private {\n // On the first call to nonReentrant, _status will be _NOT_ENTERED\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n }\n\n function _nonReentrantAfter() private {\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Returns true if the reentrancy guard is currently set to \"entered\", which indicates there is a\n * `nonReentrant` function in the call stack.\n */\n function _reentrancyGuardEntered() internal view returns (bool) {\n return _status == _ENTERED;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/ERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/ERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC1155.sol\";\nimport \"./IERC1155Receiver.sol\";\nimport \"./extensions/IERC1155MetadataURI.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of the basic standard multi-token.\n * See https://eips.ethereum.org/EIPS/eip-1155\n * Originally based on code by Enjin: https://github.com/enjin/erc-1155\n *\n * _Available since v3.1._\n */\ncontract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {\n using Address for address;\n\n // Mapping from token ID to account balances\n mapping(uint256 => mapping(address => uint256)) private _balances;\n\n // Mapping from account to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json\n string private _uri;\n\n /**\n * @dev See {_setURI}.\n */\n constructor(string memory uri_) {\n _setURI(uri_);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return\n interfaceId == type(IERC1155).interfaceId ||\n interfaceId == type(IERC1155MetadataURI).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC1155MetadataURI-uri}.\n *\n * This implementation returns the same URI for *all* token types. It relies\n * on the token type ID substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * Clients calling this function must replace the `\\{id\\}` substring with the\n * actual token type ID.\n */\n function uri(uint256) public view virtual override returns (string memory) {\n return _uri;\n }\n\n /**\n * @dev See {IERC1155-balanceOf}.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {\n require(account != address(0), \"ERC1155: address zero is not a valid owner\");\n return _balances[id][account];\n }\n\n /**\n * @dev See {IERC1155-balanceOfBatch}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] memory accounts,\n uint256[] memory ids\n ) public view virtual override returns (uint256[] memory) {\n require(accounts.length == ids.length, \"ERC1155: accounts and ids length mismatch\");\n\n uint256[] memory batchBalances = new uint256[](accounts.length);\n\n for (uint256 i = 0; i < accounts.length; ++i) {\n batchBalances[i] = balanceOf(accounts[i], ids[i]);\n }\n\n return batchBalances;\n }\n\n /**\n * @dev See {IERC1155-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC1155-isApprovedForAll}.\n */\n function isApprovedForAll(address account, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[account][operator];\n }\n\n /**\n * @dev See {IERC1155-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n _safeTransferFrom(from, to, id, amount, data);\n }\n\n /**\n * @dev See {IERC1155-safeBatchTransferFrom}.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n _safeBatchTransferFrom(from, to, ids, amounts, data);\n }\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n\n emit TransferSingle(operator, from, to, id, amount);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n for (uint256 i = 0; i < ids.length; ++i) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n }\n\n emit TransferBatch(operator, from, to, ids, amounts);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\n\n _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);\n }\n\n /**\n * @dev Sets a new URI for all token types, by relying on the token type ID\n * substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * By this mechanism, any occurrence of the `\\{id\\}` substring in either the\n * URI or any of the amounts in the JSON file at said URI will be replaced by\n * clients with the token type ID.\n *\n * For example, the `https://token-cdn-domain/\\{id\\}.json` URI would be\n * interpreted by clients as\n * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`\n * for token type ID 0x4cce0.\n *\n * See {uri}.\n *\n * Because these URIs cannot be meaningfully represented by the {URI} event,\n * this function emits no events.\n */\n function _setURI(string memory newuri) internal virtual {\n _uri = newuri;\n }\n\n /**\n * @dev Creates `amount` tokens of token type `id`, and assigns them to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _mint(address to, uint256 id, uint256 amount, bytes memory data) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _balances[id][to] += amount;\n emit TransferSingle(operator, address(0), to, id, amount);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n for (uint256 i = 0; i < ids.length; i++) {\n _balances[ids[i]][to] += amounts[i];\n }\n\n emit TransferBatch(operator, address(0), to, ids, amounts);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);\n }\n\n /**\n * @dev Destroys `amount` tokens of token type `id` from `from`\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `from` must have at least `amount` tokens of token type `id`.\n */\n function _burn(address from, uint256 id, uint256 amount) internal virtual {\n require(from != address(0), \"ERC1155: burn from the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n\n emit TransferSingle(operator, from, address(0), id, amount);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n */\n function _burnBatch(address from, uint256[] memory ids, uint256[] memory amounts) internal virtual {\n require(from != address(0), \"ERC1155: burn from the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n\n for (uint256 i = 0; i < ids.length; i++) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n }\n\n emit TransferBatch(operator, from, address(0), ids, amounts);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {\n require(owner != operator, \"ERC1155: setting approval status for self\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning, as well as batched variants.\n *\n * The same hook is called on both single and batched variants. For single\n * transfers, the length of the `ids` and `amounts` arrays will be 1.\n *\n * Calling conditions (for each `id` and `amount` pair):\n *\n * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * of token type `id` will be transferred to `to`.\n * - When `from` is zero, `amount` tokens of token type `id` will be minted\n * for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n * will be burned.\n * - `from` and `to` are never both zero.\n * - `ids` and `amounts` have the same, non-zero length.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any token transfer. This includes minting\n * and burning, as well as batched variants.\n *\n * The same hook is called on both single and batched variants. For single\n * transfers, the length of the `id` and `amount` arrays will be 1.\n *\n * Calling conditions (for each `id` and `amount` pair):\n *\n * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * of token type `id` will be transferred to `to`.\n * - When `from` is zero, `amount` tokens of token type `id` will be minted\n * for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n * will be burned.\n * - `from` and `to` are never both zero.\n * - `ids` and `amounts` have the same, non-zero length.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {}\n\n function _doSafeTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155Receiver.onERC1155Received.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non-ERC1155Receiver implementer\");\n }\n }\n }\n\n function _doSafeBatchTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (\n bytes4 response\n ) {\n if (response != IERC1155Receiver.onERC1155BatchReceived.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non-ERC1155Receiver implementer\");\n }\n }\n }\n\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {\n uint256[] memory array = new uint256[](1);\n array[0] = element;\n\n return array;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC1155.sol\";\n\n/**\n * @dev Interface of the optional ERC1155MetadataExtension interface, as defined\n * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155MetadataURI is IERC1155 {\n /**\n * @dev Returns the URI for token type `id`.\n *\n * If the `\\{id\\}` substring is present in the URI, it must be replaced by\n * clients with the actual token type ID.\n */\n function uri(uint256 id) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155 is IERC165 {\n /**\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n */\n event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);\n\n /**\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n * transfers.\n */\n event TransferBatch(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\n\n /**\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n * `approved`.\n */\n event ApprovalForAll(address indexed account, address indexed operator, bool approved);\n\n /**\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n *\n * If an {URI} event was emitted for `id`, the standard\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n * returned by {IERC1155MetadataURI-uri}.\n */\n event URI(string value, uint256 indexed id);\n\n /**\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) external view returns (uint256);\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] calldata accounts,\n uint256[] calldata ids\n ) external view returns (uint256[] memory);\n\n /**\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n *\n * Emits an {ApprovalForAll} event.\n *\n * Requirements:\n *\n * - `operator` cannot be the caller.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n *\n * See {setApprovalForAll}.\n */\n function isApprovedForAll(address account, address operator) external view returns (bool);\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155Receiver is IERC165 {\n /**\n * @dev Handles the receipt of a single ERC1155 token type. This function is\n * called at the end of a `safeTransferFrom` after the balance has been updated.\n *\n * NOTE: To accept the transfer, this must return\n * `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n * (i.e. 0xf23a6e61, or its own function selector).\n *\n * @param operator The address which initiated the transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param id The ID of the token being transferred\n * @param value The amount of tokens being transferred\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n ) external returns (bytes4);\n\n /**\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\n * is called at the end of a `safeBatchTransferFrom` after the balances have\n * been updated.\n *\n * NOTE: To accept the transfer(s), this must return\n * `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n * (i.e. 0xbc197c81, or its own function selector).\n *\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the default value returned by this function, unless\n * it's overridden.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(address from, address to, uint256 amount) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\n // decrementing then incrementing.\n _balances[to] += amount;\n }\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n unchecked {\n // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\n _balances[account] += amount;\n }\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n // Overflow not possible: amount <= accountBalance <= totalSupply.\n _totalSupply -= amount;\n }\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\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" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` 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 amount) 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 `amount` as the allowance of `spender` over the 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 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` 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 amount) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/ERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721.sol\";\nimport \"./IERC721Receiver.sol\";\nimport \"./extensions/IERC721Metadata.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/Strings.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\n using Address for address;\n using Strings for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\n\n // Mapping from token ID to approved address\n mapping(uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return\n interfaceId == type(IERC721).interfaceId ||\n interfaceId == type(IERC721Metadata).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _ownerOf(tokenId);\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token owner or approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n _requireMinted(tokenId);\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n _safeTransfer(from, to, tokenId, data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(address from, address to, uint256 tokenId, bytes memory data) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist\n */\n function _ownerOf(uint256 tokenId) internal view virtual returns (address) {\n return _owners[tokenId];\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _ownerOf(tokenId) != address(0);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n address owner = ERC721.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(address to, uint256 tokenId, bytes memory data) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId, 1);\n\n // Check that tokenId was not minted by `_beforeTokenTransfer` hook\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n unchecked {\n // Will not overflow unless all 2**256 token ids are minted to the same owner.\n // Given that tokens are minted one by one, it is impossible in practice that\n // this ever happens. Might change if we allow batch minting.\n // The ERC fails to describe this case.\n _balances[to] += 1;\n }\n\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(address(0), to, tokenId, 1);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n * This is an internal function that does not check if the sender is authorized to operate on the token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId, 1);\n\n // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook\n owner = ERC721.ownerOf(tokenId);\n\n // Clear approvals\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // Cannot overflow, as that would require more tokens to be burned/transferred\n // out than the owner initially received through minting and transferring in.\n _balances[owner] -= 1;\n }\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(owner, address(0), tokenId, 1);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(address from, address to, uint256 tokenId) internal virtual {\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId, 1);\n\n // Check that tokenId was not transferred by `_beforeTokenTransfer` hook\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n\n // Clear approvals from the previous owner\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // `_balances[from]` cannot overflow for the same reason as described in `_burn`:\n // `from`'s balance is the number of token held, which is at least one before the current\n // transfer.\n // `_balances[to]` could overflow in the conditions described in `_mint`. That would require\n // all 2**256 token ids to be minted, which in practice is impossible.\n _balances[from] -= 1;\n _balances[to] += 1;\n }\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId, 1);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721Receiver.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`.\n * - When `from` is zero, the tokens will be minted for `to`.\n * - When `to` is zero, ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}\n\n /**\n * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`.\n * - When `from` is zero, the tokens were minted for `to`.\n * - When `to` is zero, ``from``'s tokens were burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}\n\n /**\n * @dev Unsafe write access to the balances, used by extensions that \"mint\" tokens using an {ownerOf} override.\n *\n * WARNING: Anyone calling this MUST ensure that the balances remain consistent with the ownership. The invariant\n * being that for any address `a` the value returned by `balanceOf(a)` must be equal to the number of tokens such\n * that `ownerOf(tokenId)` is `a`.\n */\n // solhint-disable-next-line func-name-mixedcase\n function __unsafe_increaseBalance(address account, uint256 amount) internal {\n _balances[account] += amount;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721Receiver {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/ERC777.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC777/ERC777.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC777.sol\";\nimport \"./IERC777Recipient.sol\";\nimport \"./IERC777Sender.sol\";\nimport \"../ERC20/IERC20.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/introspection/IERC1820Registry.sol\";\n\n/**\n * @dev Implementation of the {IERC777} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n *\n * Support for ERC20 is included in this contract, as specified by the EIP: both\n * the ERC777 and ERC20 interfaces can be safely used when interacting with it.\n * Both {IERC777-Sent} and {IERC20-Transfer} events are emitted on token\n * movements.\n *\n * Additionally, the {IERC777-granularity} value is hard-coded to `1`, meaning that there\n * are no special restrictions in the amount of tokens that created, moved, or\n * destroyed. This makes integration with ERC20 applications seamless.\n *\n * CAUTION: This file is deprecated as of v4.9 and will be removed in the next major release.\n */\ncontract ERC777 is Context, IERC777, IERC20 {\n using Address for address;\n\n IERC1820Registry internal constant _ERC1820_REGISTRY = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n mapping(address => uint256) private _balances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n bytes32 private constant _TOKENS_SENDER_INTERFACE_HASH = keccak256(\"ERC777TokensSender\");\n bytes32 private constant _TOKENS_RECIPIENT_INTERFACE_HASH = keccak256(\"ERC777TokensRecipient\");\n\n // This isn't ever read from - it's only used to respond to the defaultOperators query.\n address[] private _defaultOperatorsArray;\n\n // Immutable, but accounts may revoke them (tracked in __revokedDefaultOperators).\n mapping(address => bool) private _defaultOperators;\n\n // For each account, a mapping of its operators and revoked default operators.\n mapping(address => mapping(address => bool)) private _operators;\n mapping(address => mapping(address => bool)) private _revokedDefaultOperators;\n\n // ERC20-allowances\n mapping(address => mapping(address => uint256)) private _allowances;\n\n /**\n * @dev `defaultOperators` may be an empty array.\n */\n constructor(string memory name_, string memory symbol_, address[] memory defaultOperators_) {\n _name = name_;\n _symbol = symbol_;\n\n _defaultOperatorsArray = defaultOperators_;\n for (uint256 i = 0; i < defaultOperators_.length; i++) {\n _defaultOperators[defaultOperators_[i]] = true;\n }\n\n // register interfaces\n _ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256(\"ERC777Token\"), address(this));\n _ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256(\"ERC20Token\"), address(this));\n }\n\n /**\n * @dev See {IERC777-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC777-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {ERC20-decimals}.\n *\n * Always returns 18, as per the\n * [ERC777 EIP](https://eips.ethereum.org/EIPS/eip-777#backward-compatibility).\n */\n function decimals() public pure virtual returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC777-granularity}.\n *\n * This implementation always returns `1`.\n */\n function granularity() public view virtual override returns (uint256) {\n return 1;\n }\n\n /**\n * @dev See {IERC777-totalSupply}.\n */\n function totalSupply() public view virtual override(IERC20, IERC777) returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev Returns the amount of tokens owned by an account (`tokenHolder`).\n */\n function balanceOf(address tokenHolder) public view virtual override(IERC20, IERC777) returns (uint256) {\n return _balances[tokenHolder];\n }\n\n /**\n * @dev See {IERC777-send}.\n *\n * Also emits a {IERC20-Transfer} event for ERC20 compatibility.\n */\n function send(address recipient, uint256 amount, bytes memory data) public virtual override {\n _send(_msgSender(), recipient, amount, data, \"\", true);\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Unlike `send`, `recipient` is _not_ required to implement the {IERC777Recipient}\n * interface if it is a contract.\n *\n * Also emits a {Sent} event.\n */\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n _send(_msgSender(), recipient, amount, \"\", \"\", false);\n return true;\n }\n\n /**\n * @dev See {IERC777-burn}.\n *\n * Also emits a {IERC20-Transfer} event for ERC20 compatibility.\n */\n function burn(uint256 amount, bytes memory data) public virtual override {\n _burn(_msgSender(), amount, data, \"\");\n }\n\n /**\n * @dev See {IERC777-isOperatorFor}.\n */\n function isOperatorFor(address operator, address tokenHolder) public view virtual override returns (bool) {\n return\n operator == tokenHolder ||\n (_defaultOperators[operator] && !_revokedDefaultOperators[tokenHolder][operator]) ||\n _operators[tokenHolder][operator];\n }\n\n /**\n * @dev See {IERC777-authorizeOperator}.\n */\n function authorizeOperator(address operator) public virtual override {\n require(_msgSender() != operator, \"ERC777: authorizing self as operator\");\n\n if (_defaultOperators[operator]) {\n delete _revokedDefaultOperators[_msgSender()][operator];\n } else {\n _operators[_msgSender()][operator] = true;\n }\n\n emit AuthorizedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-revokeOperator}.\n */\n function revokeOperator(address operator) public virtual override {\n require(operator != _msgSender(), \"ERC777: revoking self as operator\");\n\n if (_defaultOperators[operator]) {\n _revokedDefaultOperators[_msgSender()][operator] = true;\n } else {\n delete _operators[_msgSender()][operator];\n }\n\n emit RevokedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-defaultOperators}.\n */\n function defaultOperators() public view virtual override returns (address[] memory) {\n return _defaultOperatorsArray;\n }\n\n /**\n * @dev See {IERC777-operatorSend}.\n *\n * Emits {Sent} and {IERC20-Transfer} events.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes memory data,\n bytes memory operatorData\n ) public virtual override {\n require(isOperatorFor(_msgSender(), sender), \"ERC777: caller is not an operator for holder\");\n _send(sender, recipient, amount, data, operatorData, true);\n }\n\n /**\n * @dev See {IERC777-operatorBurn}.\n *\n * Emits {Burned} and {IERC20-Transfer} events.\n */\n function operatorBurn(\n address account,\n uint256 amount,\n bytes memory data,\n bytes memory operatorData\n ) public virtual override {\n require(isOperatorFor(_msgSender(), account), \"ERC777: caller is not an operator for holder\");\n _burn(account, amount, data, operatorData);\n }\n\n /**\n * @dev See {IERC20-allowance}.\n *\n * Note that operator and allowance concepts are orthogonal: operators may\n * not have allowance, and accounts with allowance may not be operators\n * themselves.\n */\n function allowance(address holder, address spender) public view virtual override returns (uint256) {\n return _allowances[holder][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Note that accounts cannot have allowance issued by their operators.\n */\n function approve(address spender, uint256 value) public virtual override returns (bool) {\n address holder = _msgSender();\n _approve(holder, spender, value);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Note that operator and allowance concepts are orthogonal: operators cannot\n * call `transferFrom` (unless they have allowance), and accounts with\n * allowance cannot call `operatorSend` (unless they are operators).\n *\n * Emits {Sent}, {IERC20-Transfer} and {IERC20-Approval} events.\n */\n function transferFrom(address holder, address recipient, uint256 amount) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(holder, spender, amount);\n _send(holder, recipient, amount, \"\", \"\", false);\n return true;\n }\n\n /**\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with the caller address as the `operator` and with\n * `userData` and `operatorData`.\n *\n * See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits {Minted} and {IERC20-Transfer} events.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - if `account` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function _mint(address account, uint256 amount, bytes memory userData, bytes memory operatorData) internal virtual {\n _mint(account, amount, userData, operatorData, true);\n }\n\n /**\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * If `requireReceptionAck` is set to true, and if a send hook is\n * registered for `account`, the corresponding function will be called with\n * `operator`, `data` and `operatorData`.\n *\n * See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits {Minted} and {IERC20-Transfer} events.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - if `account` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function _mint(\n address account,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) internal virtual {\n require(account != address(0), \"ERC777: mint to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), account, amount);\n\n // Update state variables\n _totalSupply += amount;\n _balances[account] += amount;\n\n _callTokensReceived(operator, address(0), account, amount, userData, operatorData, requireReceptionAck);\n\n emit Minted(operator, account, amount, userData, operatorData);\n emit Transfer(address(0), account, amount);\n }\n\n /**\n * @dev Send tokens\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _send(\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) internal virtual {\n require(from != address(0), \"ERC777: transfer from the zero address\");\n require(to != address(0), \"ERC777: transfer to the zero address\");\n\n address operator = _msgSender();\n\n _callTokensToSend(operator, from, to, amount, userData, operatorData);\n\n _move(operator, from, to, amount, userData, operatorData);\n\n _callTokensReceived(operator, from, to, amount, userData, operatorData, requireReceptionAck);\n }\n\n /**\n * @dev Burn tokens\n * @param from address token holder address\n * @param amount uint256 amount of tokens to burn\n * @param data bytes extra information provided by the token holder\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _burn(address from, uint256 amount, bytes memory data, bytes memory operatorData) internal virtual {\n require(from != address(0), \"ERC777: burn from the zero address\");\n\n address operator = _msgSender();\n\n _callTokensToSend(operator, from, address(0), amount, data, operatorData);\n\n _beforeTokenTransfer(operator, from, address(0), amount);\n\n // Update state variables\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC777: burn amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Burned(operator, from, amount, data, operatorData);\n emit Transfer(from, address(0), amount);\n }\n\n function _move(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n ) private {\n _beforeTokenTransfer(operator, from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC777: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Sent(operator, from, to, amount, userData, operatorData);\n emit Transfer(from, to, amount);\n }\n\n /**\n * @dev See {ERC20-_approve}.\n *\n * Note that accounts cannot have allowance issued by their operators.\n */\n function _approve(address holder, address spender, uint256 value) internal virtual {\n require(holder != address(0), \"ERC777: approve from the zero address\");\n require(spender != address(0), \"ERC777: approve to the zero address\");\n\n _allowances[holder][spender] = value;\n emit Approval(holder, spender, value);\n }\n\n /**\n * @dev Call from.tokensToSend() if the interface is registered\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _callTokensToSend(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n ) private {\n address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(from, _TOKENS_SENDER_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Sender(implementer).tokensToSend(operator, from, to, amount, userData, operatorData);\n }\n }\n\n /**\n * @dev Call to.tokensReceived() if the interface is registered. Reverts if the recipient is a contract but\n * tokensReceived() was not registered for the recipient\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _callTokensReceived(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) private {\n address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(to, _TOKENS_RECIPIENT_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Recipient(implementer).tokensReceived(operator, from, to, amount, userData, operatorData);\n } else if (requireReceptionAck) {\n require(!to.isContract(), \"ERC777: token recipient contract has no implementer for ERC777TokensRecipient\");\n }\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {IERC20-Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC777: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes\n * calls to {send}, {transfer}, {operatorSend}, {transferFrom}, minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be to transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address operator, address from, address to, uint256 amount) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC777/IERC777.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777Token standard as defined in the EIP.\n *\n * This contract uses the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 registry standard] to let\n * token holders and recipients react to token movements by using setting implementers\n * for the associated interfaces in said registry. See {IERC1820Registry} and\n * {ERC1820Implementer}.\n */\ninterface IERC777 {\n /**\n * @dev Emitted when `amount` tokens are created by `operator` and assigned to `to`.\n *\n * Note that some additional user `data` and `operatorData` can be logged in the event.\n */\n event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);\n\n /**\n * @dev Emitted when `operator` destroys `amount` tokens from `account`.\n *\n * Note that some additional user `data` and `operatorData` can be logged in the event.\n */\n event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);\n\n /**\n * @dev Emitted when `operator` is made operator for `tokenHolder`.\n */\n event AuthorizedOperator(address indexed operator, address indexed tokenHolder);\n\n /**\n * @dev Emitted when `operator` is revoked its operator status for `tokenHolder`.\n */\n event RevokedOperator(address indexed operator, address indexed tokenHolder);\n\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, usually a shorter version of the\n * name.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the smallest part of the token that is not divisible. This\n * means all token operations (creation, movement and destruction) must have\n * amounts that are a multiple of this number.\n *\n * For most token contracts, this value will equal 1.\n */\n function granularity() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by an account (`owner`).\n */\n function balanceOf(address owner) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * If send or receive hooks are registered for the caller and `recipient`,\n * the corresponding functions will be called with `data` and empty\n * `operatorData`. See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits a {Sent} event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function send(address recipient, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Destroys `amount` tokens from the caller's account, reducing the\n * total supply.\n *\n * If a send hook is registered for the caller, the corresponding function\n * will be called with `data` and empty `operatorData`. See {IERC777Sender}.\n *\n * Emits a {Burned} event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n */\n function burn(uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Returns true if an account is an operator of `tokenHolder`.\n * Operators can send and burn tokens on behalf of their owners. All\n * accounts are their own operator.\n *\n * See {operatorSend} and {operatorBurn}.\n */\n function isOperatorFor(address operator, address tokenHolder) external view returns (bool);\n\n /**\n * @dev Make an account an operator of the caller.\n *\n * See {isOperatorFor}.\n *\n * Emits an {AuthorizedOperator} event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function authorizeOperator(address operator) external;\n\n /**\n * @dev Revoke an account's operator status for the caller.\n *\n * See {isOperatorFor} and {defaultOperators}.\n *\n * Emits a {RevokedOperator} event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function revokeOperator(address operator) external;\n\n /**\n * @dev Returns the list of default operators. These accounts are operators\n * for all token holders, even if {authorizeOperator} was never called on\n * them.\n *\n * This list is immutable, but individual holders may revoke these via\n * {revokeOperator}, in which case {isOperatorFor} will return false.\n */\n function defaultOperators() external view returns (address[] memory);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must\n * be an operator of `sender`.\n *\n * If send or receive hooks are registered for `sender` and `recipient`,\n * the corresponding functions will be called with `data` and\n * `operatorData`. See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits a {Sent} event.\n *\n * Requirements\n *\n * - `sender` cannot be the zero address.\n * - `sender` must have at least `amount` tokens.\n * - the caller must be an operator for `sender`.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes calldata data,\n bytes calldata operatorData\n ) external;\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the total supply.\n * The caller must be an operator of `account`.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with `data` and `operatorData`. See {IERC777Sender}.\n *\n * Emits a {Burned} event.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n * - the caller must be an operator for `account`.\n */\n function operatorBurn(address account, uint256 amount, bytes calldata data, bytes calldata operatorData) external;\n\n event Sent(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes data,\n bytes operatorData\n );\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\n *\n * Accounts can be notified of {IERC777} tokens being sent to them by having a\n * contract implement this interface (contract holders can be their own\n * implementer) and registering it on the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\n *\n * See {IERC1820Registry} and {ERC1820Implementer}.\n */\ninterface IERC777Recipient {\n /**\n * @dev Called by an {IERC777} token contract whenever tokens are being\n * moved or created into a registered account (`to`). The type of operation\n * is conveyed by `from` being the zero address or not.\n *\n * This call occurs _after_ the token contract's state is updated, so\n * {IERC777-balanceOf}, etc., can be used to query the post-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensReceived(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777Sender.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Sender.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777TokensSender standard as defined in the EIP.\n *\n * {IERC777} Token holders can be notified of operations performed on their\n * tokens by having a contract implement this interface (contract holders can be\n * their own implementer) and registering it on the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\n *\n * See {IERC1820Registry} and {ERC1820Implementer}.\n */\ninterface IERC777Sender {\n /**\n * @dev Called by an {IERC777} token contract whenever a registered holder's\n * (`from`) tokens are about to be moved or destroyed. The type of operation\n * is conveyed by `to` being the zero address or not.\n *\n * This call occurs _before_ the token contract's state is updated, so\n * {IERC777-balanceOf}, etc., can be used to query the pre-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensToSend(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n *\n * Furthermore, `isContract` will also return true if the target contract within\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n * which only has an effect at the end of a transaction.\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Counters.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary Counters {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/ECDSA.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Strings.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV // Deprecated in v4.8\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n /// @solidity memory-safe-assembly\n assembly {\n mstore(0x00, \"\\x19Ethereum Signed Message:\\n32\")\n mstore(0x1c, hash)\n message := keccak256(0x00, 0x3c)\n }\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\n /// @solidity memory-safe-assembly\n assembly {\n let ptr := mload(0x40)\n mstore(ptr, \"\\x19\\x01\")\n mstore(add(ptr, 0x02), domainSeparator)\n mstore(add(ptr, 0x22), structHash)\n data := keccak256(ptr, 0x42)\n }\n }\n\n /**\n * @dev Returns an Ethereum Signed Data with intended validator, created from a\n * `validator` and `data` according to the version 0 of EIP-191.\n *\n * See {recover}.\n */\n function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x00\", validator, data));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/SignatureChecker.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSA.sol\";\nimport \"../../interfaces/IERC1271.sol\";\n\n/**\n * @dev Signature verification helper that can be used instead of `ECDSA.recover` to seamlessly support both ECDSA\n * signatures from externally owned accounts (EOAs) as well as ERC1271 signatures from smart contract wallets like\n * Argent and Gnosis Safe.\n *\n * _Available since v4.1._\n */\nlibrary SignatureChecker {\n /**\n * @dev Checks if a signature is valid for a given signer and data hash. If the signer is a smart contract, the\n * signature is validated against that smart contract using ERC1271, otherwise it's validated using `ECDSA.recover`.\n *\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\n */\n function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature) internal view returns (bool) {\n (address recovered, ECDSA.RecoverError error) = ECDSA.tryRecover(hash, signature);\n return\n (error == ECDSA.RecoverError.NoError && recovered == signer) ||\n isValidERC1271SignatureNow(signer, hash, signature);\n }\n\n /**\n * @dev Checks if a signature is valid for a given signer and data hash. The signature is validated\n * against the signer smart contract using ERC1271.\n *\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\n */\n function isValidERC1271SignatureNow(\n address signer,\n bytes32 hash,\n bytes memory signature\n ) internal view returns (bool) {\n (bool success, bytes memory result) = signer.staticcall(\n abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, signature)\n );\n return (success &&\n result.length >= 32 &&\n abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/ERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165 is IERC165 {\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165).interfaceId;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC1820Registry.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/introspection/IERC1820Registry.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the global ERC1820 Registry, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register\n * implementers for interfaces in this registry, as well as query support.\n *\n * Implementers may be shared by multiple accounts, and can also implement more\n * than a single interface for each account. Contracts can implement interfaces\n * for themselves, but externally-owned accounts (EOA) must delegate this to a\n * contract.\n *\n * {IERC165} interfaces can also be queried via the registry.\n *\n * For an in-depth explanation and source code analysis, see the EIP text.\n */\ninterface IERC1820Registry {\n event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer);\n\n event ManagerChanged(address indexed account, address indexed newManager);\n\n /**\n * @dev Sets `newManager` as the manager for `account`. A manager of an\n * account is able to set interface implementers for it.\n *\n * By default, each account is its own manager. Passing a value of `0x0` in\n * `newManager` will reset the manager to this initial state.\n *\n * Emits a {ManagerChanged} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `account`.\n */\n function setManager(address account, address newManager) external;\n\n /**\n * @dev Returns the manager for `account`.\n *\n * See {setManager}.\n */\n function getManager(address account) external view returns (address);\n\n /**\n * @dev Sets the `implementer` contract as ``account``'s implementer for\n * `interfaceHash`.\n *\n * `account` being the zero address is an alias for the caller's address.\n * The zero address can also be used in `implementer` to remove an old one.\n *\n * See {interfaceHash} to learn how these are created.\n *\n * Emits an {InterfaceImplementerSet} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `account`.\n * - `interfaceHash` must not be an {IERC165} interface id (i.e. it must not\n * end in 28 zeroes).\n * - `implementer` must implement {IERC1820Implementer} and return true when\n * queried for support, unless `implementer` is the caller. See\n * {IERC1820Implementer-canImplementInterfaceForAddress}.\n */\n function setInterfaceImplementer(address account, bytes32 _interfaceHash, address implementer) external;\n\n /**\n * @dev Returns the implementer of `interfaceHash` for `account`. If no such\n * implementer is registered, returns the zero address.\n *\n * If `interfaceHash` is an {IERC165} interface id (i.e. it ends with 28\n * zeroes), `account` will be queried for support of it.\n *\n * `account` being the zero address is an alias for the caller's address.\n */\n function getInterfaceImplementer(address account, bytes32 _interfaceHash) external view returns (address);\n\n /**\n * @dev Returns the interface hash for an `interfaceName`, as defined in the\n * corresponding\n * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP].\n */\n function interfaceHash(string calldata interfaceName) external pure returns (bytes32);\n\n /**\n * @notice Updates the cache with whether the contract implements an ERC165 interface or not.\n * @param account Address of the contract for which to update the cache.\n * @param interfaceId ERC165 interface for which to update the cache.\n */\n function updateERC165Cache(address account, bytes4 interfaceId) external;\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not.\n * If the result is not cached a direct lookup on the contract address is performed.\n * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling\n * {updateERC165Cache} with the contract address.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool);\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not without using or updating the cache.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/math/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\n // The surrounding unchecked block does not change this fact.\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1, \"Math: mulDiv overflow\");\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n //\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n //\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n //\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1 << (log2(a) >> 1);\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = sqrt(a);\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 2, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 128;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 64;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 32;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 16;\n }\n if (value >> 8 > 0) {\n value >>= 8;\n result += 8;\n }\n if (value >> 4 > 0) {\n value >>= 4;\n result += 4;\n }\n if (value >> 2 > 0) {\n value >>= 2;\n result += 2;\n }\n if (value >> 1 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log2(value);\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 10, rounded down, of a positive value.\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 + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 256, rounded down, of a positive value.\n * Returns 0 if given 0.\n *\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n */\n function log256(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 16;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 8;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 4;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 2;\n }\n if (value >> 8 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log256(value);\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/SafeCast.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCast {\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 * _Available since v4.7._\n */\n function toUint248(uint256 value) internal pure returns (uint248) {\n require(value <= type(uint248).max, \"SafeCast: value doesn't fit in 248 bits\");\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 * _Available since v4.7._\n */\n function toUint240(uint256 value) internal pure returns (uint240) {\n require(value <= type(uint240).max, \"SafeCast: value doesn't fit in 240 bits\");\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 * _Available since v4.7._\n */\n function toUint232(uint256 value) internal pure returns (uint232) {\n require(value <= type(uint232).max, \"SafeCast: value doesn't fit in 232 bits\");\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 * _Available since v4.2._\n */\n function toUint224(uint256 value) internal pure returns (uint224) {\n require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\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 * _Available since v4.7._\n */\n function toUint216(uint256 value) internal pure returns (uint216) {\n require(value <= type(uint216).max, \"SafeCast: value doesn't fit in 216 bits\");\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 * _Available since v4.7._\n */\n function toUint208(uint256 value) internal pure returns (uint208) {\n require(value <= type(uint208).max, \"SafeCast: value doesn't fit in 208 bits\");\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 * _Available since v4.7._\n */\n function toUint200(uint256 value) internal pure returns (uint200) {\n require(value <= type(uint200).max, \"SafeCast: value doesn't fit in 200 bits\");\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 * _Available since v4.7._\n */\n function toUint192(uint256 value) internal pure returns (uint192) {\n require(value <= type(uint192).max, \"SafeCast: value doesn't fit in 192 bits\");\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 * _Available since v4.7._\n */\n function toUint184(uint256 value) internal pure returns (uint184) {\n require(value <= type(uint184).max, \"SafeCast: value doesn't fit in 184 bits\");\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 * _Available since v4.7._\n */\n function toUint176(uint256 value) internal pure returns (uint176) {\n require(value <= type(uint176).max, \"SafeCast: value doesn't fit in 176 bits\");\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 * _Available since v4.7._\n */\n function toUint168(uint256 value) internal pure returns (uint168) {\n require(value <= type(uint168).max, \"SafeCast: value doesn't fit in 168 bits\");\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 * _Available since v4.7._\n */\n function toUint160(uint256 value) internal pure returns (uint160) {\n require(value <= type(uint160).max, \"SafeCast: value doesn't fit in 160 bits\");\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 * _Available since v4.7._\n */\n function toUint152(uint256 value) internal pure returns (uint152) {\n require(value <= type(uint152).max, \"SafeCast: value doesn't fit in 152 bits\");\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 * _Available since v4.7._\n */\n function toUint144(uint256 value) internal pure returns (uint144) {\n require(value <= type(uint144).max, \"SafeCast: value doesn't fit in 144 bits\");\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 * _Available since v4.7._\n */\n function toUint136(uint256 value) internal pure returns (uint136) {\n require(value <= type(uint136).max, \"SafeCast: value doesn't fit in 136 bits\");\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 * _Available since v2.5._\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\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 * _Available since v4.7._\n */\n function toUint120(uint256 value) internal pure returns (uint120) {\n require(value <= type(uint120).max, \"SafeCast: value doesn't fit in 120 bits\");\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 * _Available since v4.7._\n */\n function toUint112(uint256 value) internal pure returns (uint112) {\n require(value <= type(uint112).max, \"SafeCast: value doesn't fit in 112 bits\");\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 * _Available since v4.7._\n */\n function toUint104(uint256 value) internal pure returns (uint104) {\n require(value <= type(uint104).max, \"SafeCast: value doesn't fit in 104 bits\");\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 * _Available since v4.2._\n */\n function toUint96(uint256 value) internal pure returns (uint96) {\n require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\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 * _Available since v4.7._\n */\n function toUint88(uint256 value) internal pure returns (uint88) {\n require(value <= type(uint88).max, \"SafeCast: value doesn't fit in 88 bits\");\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 * _Available since v4.7._\n */\n function toUint80(uint256 value) internal pure returns (uint80) {\n require(value <= type(uint80).max, \"SafeCast: value doesn't fit in 80 bits\");\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 * _Available since v4.7._\n */\n function toUint72(uint256 value) internal pure returns (uint72) {\n require(value <= type(uint72).max, \"SafeCast: value doesn't fit in 72 bits\");\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 * _Available since v2.5._\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\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 * _Available since v4.7._\n */\n function toUint56(uint256 value) internal pure returns (uint56) {\n require(value <= type(uint56).max, \"SafeCast: value doesn't fit in 56 bits\");\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 * _Available since v4.7._\n */\n function toUint48(uint256 value) internal pure returns (uint48) {\n require(value <= type(uint48).max, \"SafeCast: value doesn't fit in 48 bits\");\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 * _Available since v4.7._\n */\n function toUint40(uint256 value) internal pure returns (uint40) {\n require(value <= type(uint40).max, \"SafeCast: value doesn't fit in 40 bits\");\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 * _Available since v2.5._\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\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 * _Available since v4.7._\n */\n function toUint24(uint256 value) internal pure returns (uint24) {\n require(value <= type(uint24).max, \"SafeCast: value doesn't fit in 24 bits\");\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 * _Available since v2.5._\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\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 * _Available since v2.5._\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\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 * _Available since v3.0._\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\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 * _Available since v4.7._\n */\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\n downcasted = int248(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 248 bits\");\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 * _Available since v4.7._\n */\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\n downcasted = int240(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 240 bits\");\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 * _Available since v4.7._\n */\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\n downcasted = int232(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 232 bits\");\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 * _Available since v4.7._\n */\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\n downcasted = int224(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 224 bits\");\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 * _Available since v4.7._\n */\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\n downcasted = int216(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 216 bits\");\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 * _Available since v4.7._\n */\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\n downcasted = int208(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 208 bits\");\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 * _Available since v4.7._\n */\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\n downcasted = int200(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 200 bits\");\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 * _Available since v4.7._\n */\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\n downcasted = int192(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 192 bits\");\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 * _Available since v4.7._\n */\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\n downcasted = int184(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 184 bits\");\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 * _Available since v4.7._\n */\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\n downcasted = int176(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 176 bits\");\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 * _Available since v4.7._\n */\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\n downcasted = int168(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 168 bits\");\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 * _Available since v4.7._\n */\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\n downcasted = int160(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 160 bits\");\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 * _Available since v4.7._\n */\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\n downcasted = int152(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 152 bits\");\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 * _Available since v4.7._\n */\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\n downcasted = int144(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 144 bits\");\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 * _Available since v4.7._\n */\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\n downcasted = int136(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 136 bits\");\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 * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\n downcasted = int128(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 128 bits\");\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 * _Available since v4.7._\n */\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\n downcasted = int120(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 120 bits\");\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 * _Available since v4.7._\n */\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\n downcasted = int112(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 112 bits\");\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 * _Available since v4.7._\n */\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\n downcasted = int104(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 104 bits\");\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 * _Available since v4.7._\n */\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\n downcasted = int96(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 96 bits\");\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 * _Available since v4.7._\n */\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\n downcasted = int88(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 88 bits\");\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 * _Available since v4.7._\n */\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\n downcasted = int80(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 80 bits\");\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 * _Available since v4.7._\n */\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\n downcasted = int72(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 72 bits\");\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 * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\n downcasted = int64(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 64 bits\");\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 * _Available since v4.7._\n */\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\n downcasted = int56(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 56 bits\");\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 * _Available since v4.7._\n */\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\n downcasted = int48(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 48 bits\");\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 * _Available since v4.7._\n */\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\n downcasted = int40(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 40 bits\");\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 * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\n downcasted = int32(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 32 bits\");\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 * _Available since v4.7._\n */\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\n downcasted = int24(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 24 bits\");\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 * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\n downcasted = int16(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 16 bits\");\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 * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\n downcasted = int8(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 8 bits\");\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 * _Available since v3.0._\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 require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/SignedMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard signed math utilities missing in the Solidity language.\n */\nlibrary SignedMath {\n /**\n * @dev Returns the largest of two signed numbers.\n */\n function max(int256 a, int256 b) internal pure returns (int256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two signed numbers.\n */\n function min(int256 a, int256 b) internal pure returns (int256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two signed numbers without overflow.\n * The result is rounded towards zero.\n */\n function average(int256 a, int256 b) internal pure returns (int256) {\n // Formula from the book \"Hacker's Delight\"\n int256 x = (a & b) + ((a ^ b) >> 1);\n return x + (int256(uint256(x) >> 255) & (a ^ b));\n }\n\n /**\n * @dev Returns the absolute unsigned value of a signed value.\n */\n function abs(int256 n) internal pure returns (uint256) {\n unchecked {\n // must be unchecked in order to support `n = type(int256).min`\n return uint256(n >= 0 ? n : -n);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/Math.sol\";\nimport \"./math/SignedMath.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n unchecked {\n uint256 length = Math.log10(value) + 1;\n string memory buffer = new string(length);\n uint256 ptr;\n /// @solidity memory-safe-assembly\n assembly {\n ptr := add(buffer, add(32, length))\n }\n while (true) {\n ptr--;\n /// @solidity memory-safe-assembly\n assembly {\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n }\n value /= 10;\n if (value == 0) break;\n }\n return buffer;\n }\n }\n\n /**\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\n */\n function toString(int256 value) internal pure returns (string memory) {\n return string(abi.encodePacked(value < 0 ? \"-\" : \"\", toString(SignedMath.abs(value))));\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n unchecked {\n return toHexString(value, Math.log256(value) + 1);\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n\n /**\n * @dev Returns true if the two strings are equal.\n */\n function equal(string memory a, string memory b) internal pure returns (bool) {\n return keccak256(bytes(a)) == keccak256(bytes(b));\n }\n}\n" + }, + "contracts/aa-4337/core/BaseAccount.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-empty-blocks */\n\nimport \"../interfaces/IAccount.sol\";\nimport \"../interfaces/IEntryPoint.sol\";\nimport \"./Helpers.sol\";\n\n/**\n * Basic account implementation.\n * this contract provides the basic logic for implementing the IAccount interface - validateUserOp\n * specific account implementation should inherit it and provide the account-specific logic\n */\nabstract contract BaseAccount is IAccount {\n using UserOperationLib for UserOperation;\n\n //return value in case of signature failure, with no time-range.\n // equivalent to _packValidationData(true,0,0);\n uint256 internal constant SIG_VALIDATION_FAILED = 1;\n\n /**\n * Return the account nonce.\n * This method returns the next sequential nonce.\n * For a nonce of a specific key, use `entrypoint.getNonce(account, key)`\n */\n function getNonce() public view virtual returns (uint256) {\n return entryPoint().getNonce(address(this), 0);\n }\n\n /**\n * return the entryPoint used by this account.\n * subclass should return the current entryPoint used by this account.\n */\n function entryPoint() public view virtual returns (IEntryPoint);\n\n /**\n * Validate user's signature and nonce.\n * subclass doesn't need to override this method. Instead, it should override the specific internal validation methods.\n */\n function validateUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 missingAccountFunds\n ) external virtual override returns (uint256 validationData) {\n _requireFromEntryPoint();\n validationData = _validateSignature(userOp, userOpHash);\n _validateNonce(userOp.nonce);\n _payPrefund(missingAccountFunds);\n }\n\n /**\n * ensure the request comes from the known entrypoint.\n */\n function _requireFromEntryPoint() internal view virtual {\n require(\n msg.sender == address(entryPoint()),\n \"account: not from EntryPoint\"\n );\n }\n\n /**\n * validate the signature is valid for this message.\n * @param userOp validate the userOp.signature field\n * @param userOpHash convenient field: the hash of the request, to check the signature against\n * (also hashes the entrypoint and chain id)\n * @return validationData signature and time-range of this operation\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * If the account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function _validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) internal virtual returns (uint256 validationData);\n\n /**\n * Validate the nonce of the UserOperation.\n * This method may validate the nonce requirement of this account.\n * e.g.\n * To limit the nonce to use sequenced UserOps only (no \"out of order\" UserOps):\n * `require(nonce < type(uint64).max)`\n * For a hypothetical account that *requires* the nonce to be out-of-order:\n * `require(nonce & type(uint64).max == 0)`\n *\n * The actual nonce uniqueness is managed by the EntryPoint, and thus no other\n * action is needed by the account itself.\n *\n * @param nonce to validate\n *\n * solhint-disable-next-line no-empty-blocks\n */\n function _validateNonce(uint256 nonce) internal view virtual {}\n\n /**\n * sends to the entrypoint (msg.sender) the missing funds for this transaction.\n * subclass MAY override this method for better funds management\n * (e.g. send to the entryPoint more than the minimum required, so that in future transactions\n * it will not be required to send again)\n * @param missingAccountFunds the minimum value this method should send the entrypoint.\n * this value MAY be zero, in case there is enough deposit, or the userOp has a paymaster.\n */\n function _payPrefund(uint256 missingAccountFunds) internal virtual {\n if (missingAccountFunds != 0) {\n (bool success, ) = payable(msg.sender).call{\n value: missingAccountFunds,\n gas: type(uint256).max\n }(\"\");\n (success);\n //ignore failure (its EntryPoint's job to verify, not account.)\n }\n }\n}\n" + }, + "contracts/aa-4337/core/EntryPoint.sol": { + "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n\nimport \"../interfaces/IAccount.sol\";\nimport \"../interfaces/IPaymaster.sol\";\nimport \"../interfaces/IEntryPoint.sol\";\n\nimport \"../utils/Exec.sol\";\nimport \"./StakeManager.sol\";\nimport \"./SenderCreator.sol\";\nimport \"./Helpers.sol\";\nimport \"./NonceManager.sol\";\nimport \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\n\ncontract EntryPoint is\n IEntryPoint,\n StakeManager,\n NonceManager,\n ReentrancyGuard\n{\n using UserOperationLib for UserOperation;\n\n SenderCreator private immutable senderCreator = new SenderCreator();\n\n // internal value used during simulation: need to query aggregator.\n address private constant SIMULATE_FIND_AGGREGATOR = address(1);\n\n // marker for inner call revert on out of gas\n bytes32 private constant INNER_OUT_OF_GAS = hex\"deaddead\";\n\n uint256 private constant REVERT_REASON_MAX_LEN = 2048;\n\n /**\n * for simulation purposes, validateUserOp (and validatePaymasterUserOp) must return this value\n * in case of signature failure, instead of revert.\n */\n uint256 public constant SIG_VALIDATION_FAILED = 1;\n\n /**\n * compensate the caller's beneficiary address with the collected fees of all UserOperations.\n * @param beneficiary the address to receive the fees\n * @param amount amount to transfer.\n */\n function _compensate(address payable beneficiary, uint256 amount) internal {\n require(beneficiary != address(0), \"AA90 invalid beneficiary\");\n (bool success, ) = beneficiary.call{value: amount}(\"\");\n require(success, \"AA91 failed send to beneficiary\");\n }\n\n /**\n * execute a user op\n * @param opIndex index into the opInfo array\n * @param userOp the userOp to execute\n * @param opInfo the opInfo filled by validatePrepayment for this userOp.\n * @return collected the total amount this userOp paid.\n */\n function _executeUserOp(\n uint256 opIndex,\n UserOperation calldata userOp,\n UserOpInfo memory opInfo\n ) private returns (uint256 collected) {\n uint256 preGas = gasleft();\n bytes memory context = getMemoryBytesFromOffset(opInfo.contextOffset);\n\n try this.innerHandleOp(userOp.callData, opInfo, context) returns (\n uint256 _actualGasCost\n ) {\n collected = _actualGasCost;\n } catch {\n bytes32 innerRevertCode;\n assembly {\n returndatacopy(0, 0, 32)\n innerRevertCode := mload(0)\n }\n // handleOps was called with gas limit too low. abort entire bundle.\n if (innerRevertCode == INNER_OUT_OF_GAS) {\n //report paymaster, since if it is not deliberately caused by the bundler,\n // it must be a revert caused by paymaster.\n revert FailedOp(opIndex, \"AA95 out of gas\");\n }\n\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n collected = _handlePostOp(\n opIndex,\n IPaymaster.PostOpMode.postOpReverted,\n opInfo,\n context,\n actualGas\n );\n }\n }\n\n /**\n * Execute a batch of UserOperations.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(\n UserOperation[] calldata ops,\n address payable beneficiary\n ) public nonReentrant {\n uint256 opslen = ops.length;\n UserOpInfo[] memory opInfos = new UserOpInfo[](opslen);\n\n unchecked {\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[i];\n (\n uint256 validationData,\n uint256 pmValidationData\n ) = _validatePrepayment(i, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(\n i,\n validationData,\n pmValidationData,\n address(0)\n );\n }\n\n uint256 collected = 0;\n emit BeforeExecution();\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(i, ops[i], opInfos[i]);\n }\n\n _compensate(beneficiary, collected);\n } //unchecked\n }\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) public nonReentrant {\n uint256 opasLen = opsPerAggregator.length;\n uint256 totalOps = 0;\n for (uint256 i = 0; i < opasLen; i++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[i];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n //address(1) is special marker of \"signature error\"\n require(\n address(aggregator) != address(1),\n \"AA96 invalid aggregator\"\n );\n\n if (address(aggregator) != address(0)) {\n // solhint-disable-next-line no-empty-blocks\n try aggregator.validateSignatures(ops, opa.signature) {} catch {\n revert SignatureValidationFailed(address(aggregator));\n }\n }\n\n totalOps += ops.length;\n }\n\n UserOpInfo[] memory opInfos = new UserOpInfo[](totalOps);\n\n emit BeforeExecution();\n\n uint256 opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n uint256 opslen = ops.length;\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[opIndex];\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(opIndex, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(\n i,\n validationData,\n paymasterValidationData,\n address(aggregator)\n );\n opIndex++;\n }\n }\n\n uint256 collected = 0;\n opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n emit SignatureAggregatorChanged(address(opa.aggregator));\n UserOperation[] calldata ops = opa.userOps;\n uint256 opslen = ops.length;\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(opIndex, ops[i], opInfos[opIndex]);\n opIndex++;\n }\n }\n emit SignatureAggregatorChanged(address(0));\n\n _compensate(beneficiary, collected);\n }\n\n /// @inheritdoc IEntryPoint\n function simulateHandleOp(\n UserOperation calldata op,\n address target,\n bytes calldata targetCallData\n ) external override {\n UserOpInfo memory opInfo;\n _simulationOnlyValidations(op);\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(0, op, opInfo);\n ValidationData memory data = _intersectTimeRange(\n validationData,\n paymasterValidationData\n );\n\n numberMarker();\n uint256 paid = _executeUserOp(0, op, opInfo);\n numberMarker();\n bool targetSuccess;\n bytes memory targetResult;\n if (target != address(0)) {\n (targetSuccess, targetResult) = target.call(targetCallData);\n }\n revert ExecutionResult(\n opInfo.preOpGas,\n paid,\n data.validAfter,\n data.validUntil,\n targetSuccess,\n targetResult\n );\n }\n\n // A memory copy of UserOp static fields only.\n // Excluding: callData, initCode and signature. Replacing paymasterAndData with paymaster.\n struct MemoryUserOp {\n address sender;\n uint256 nonce;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n address paymaster;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n }\n\n struct UserOpInfo {\n MemoryUserOp mUserOp;\n bytes32 userOpHash;\n uint256 prefund;\n uint256 contextOffset;\n uint256 preOpGas;\n }\n\n /**\n * inner function to handle a UserOperation.\n * Must be declared \"external\" to open a call context, but it can only be called by handleOps.\n */\n function innerHandleOp(\n bytes memory callData,\n UserOpInfo memory opInfo,\n bytes calldata context\n ) external returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n require(msg.sender == address(this), \"AA92 internal call only\");\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n\n uint callGasLimit = mUserOp.callGasLimit;\n unchecked {\n // handleOps was called with gas limit too low. abort entire bundle.\n if (\n gasleft() < callGasLimit + mUserOp.verificationGasLimit + 5000\n ) {\n assembly {\n mstore(0, INNER_OUT_OF_GAS)\n revert(0, 32)\n }\n }\n }\n\n IPaymaster.PostOpMode mode = IPaymaster.PostOpMode.opSucceeded;\n if (callData.length > 0) {\n bool success = Exec.call(mUserOp.sender, 0, callData, callGasLimit);\n if (!success) {\n bytes memory result = Exec.getReturnData(REVERT_REASON_MAX_LEN);\n if (result.length > 0) {\n emit UserOperationRevertReason(\n opInfo.userOpHash,\n mUserOp.sender,\n mUserOp.nonce,\n result\n );\n }\n mode = IPaymaster.PostOpMode.opReverted;\n }\n }\n\n unchecked {\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n //note: opIndex is ignored (relevant only if mode==postOpReverted, which is only possible outside of innerHandleOp)\n return _handlePostOp(0, mode, opInfo, context, actualGas);\n }\n }\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(\n UserOperation calldata userOp\n ) public view returns (bytes32) {\n return\n keccak256(abi.encode(userOp.hash(), address(this), block.chainid));\n }\n\n /**\n * copy general fields from userOp into the memory opInfo structure.\n */\n function _copyUserOpToMemory(\n UserOperation calldata userOp,\n MemoryUserOp memory mUserOp\n ) internal pure {\n mUserOp.sender = userOp.sender;\n mUserOp.nonce = userOp.nonce;\n mUserOp.callGasLimit = userOp.callGasLimit;\n mUserOp.verificationGasLimit = userOp.verificationGasLimit;\n mUserOp.preVerificationGas = userOp.preVerificationGas;\n mUserOp.maxFeePerGas = userOp.maxFeePerGas;\n mUserOp.maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes calldata paymasterAndData = userOp.paymasterAndData;\n if (paymasterAndData.length > 0) {\n require(\n paymasterAndData.length >= 20,\n \"AA93 invalid paymasterAndData\"\n );\n mUserOp.paymaster = address(bytes20(paymasterAndData[:20]));\n } else {\n mUserOp.paymaster = address(0);\n }\n }\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external {\n UserOpInfo memory outOpInfo;\n\n _simulationOnlyValidations(userOp);\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(0, userOp, outOpInfo);\n StakeInfo memory paymasterInfo = _getStakeInfo(\n outOpInfo.mUserOp.paymaster\n );\n StakeInfo memory senderInfo = _getStakeInfo(outOpInfo.mUserOp.sender);\n StakeInfo memory factoryInfo;\n {\n bytes calldata initCode = userOp.initCode;\n address factory = initCode.length >= 20\n ? address(bytes20(initCode[0:20]))\n : address(0);\n factoryInfo = _getStakeInfo(factory);\n }\n\n ValidationData memory data = _intersectTimeRange(\n validationData,\n paymasterValidationData\n );\n address aggregator = data.aggregator;\n bool sigFailed = aggregator == address(1);\n ReturnInfo memory returnInfo = ReturnInfo(\n outOpInfo.preOpGas,\n outOpInfo.prefund,\n sigFailed,\n data.validAfter,\n data.validUntil,\n getMemoryBytesFromOffset(outOpInfo.contextOffset)\n );\n\n if (aggregator != address(0) && aggregator != address(1)) {\n AggregatorStakeInfo memory aggregatorInfo = AggregatorStakeInfo(\n aggregator,\n _getStakeInfo(aggregator)\n );\n revert ValidationResultWithAggregation(\n returnInfo,\n senderInfo,\n factoryInfo,\n paymasterInfo,\n aggregatorInfo\n );\n }\n revert ValidationResult(\n returnInfo,\n senderInfo,\n factoryInfo,\n paymasterInfo\n );\n }\n\n function _getRequiredPrefund(\n MemoryUserOp memory mUserOp\n ) internal pure returns (uint256 requiredPrefund) {\n unchecked {\n //when using a Paymaster, the verificationGasLimit is used also to as a limit for the postOp call.\n // our security model might call postOp eventually twice\n uint256 mul = mUserOp.paymaster != address(0) ? 3 : 1;\n uint256 requiredGas = mUserOp.callGasLimit +\n mUserOp.verificationGasLimit *\n mul +\n mUserOp.preVerificationGas;\n\n requiredPrefund = requiredGas * mUserOp.maxFeePerGas;\n }\n }\n\n // create the sender's contract if needed.\n function _createSenderIfNeeded(\n uint256 opIndex,\n UserOpInfo memory opInfo,\n bytes calldata initCode\n ) internal {\n if (initCode.length != 0) {\n address sender = opInfo.mUserOp.sender;\n if (sender.code.length != 0)\n revert FailedOp(opIndex, \"AA10 sender already constructed\");\n address sender1 = senderCreator.createSender{\n gas: opInfo.mUserOp.verificationGasLimit\n }(initCode);\n if (sender1 == address(0))\n revert FailedOp(opIndex, \"AA13 initCode failed or OOG\");\n if (sender1 != sender)\n revert FailedOp(opIndex, \"AA14 initCode must return sender\");\n if (sender1.code.length == 0)\n revert FailedOp(opIndex, \"AA15 initCode must create sender\");\n address factory = address(bytes20(initCode[0:20]));\n emit AccountDeployed(\n opInfo.userOpHash,\n sender,\n factory,\n opInfo.mUserOp.paymaster\n );\n }\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes calldata initCode) public {\n address sender = senderCreator.createSender(initCode);\n revert SenderAddressResult(sender);\n }\n\n function _simulationOnlyValidations(\n UserOperation calldata userOp\n ) internal view {\n // solhint-disable-next-line no-empty-blocks\n try\n this._validateSenderAndPaymaster(\n userOp.initCode,\n userOp.sender,\n userOp.paymasterAndData\n )\n {} catch Error(string memory revertReason) {\n if (bytes(revertReason).length != 0) {\n revert FailedOp(0, revertReason);\n }\n }\n }\n\n /**\n * Called only during simulation.\n * This function always reverts to prevent warm/cold storage differentiation in simulation vs execution.\n */\n function _validateSenderAndPaymaster(\n bytes calldata initCode,\n address sender,\n bytes calldata paymasterAndData\n ) external view {\n if (initCode.length == 0 && sender.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA20 account not deployed\");\n }\n if (paymasterAndData.length >= 20) {\n address paymaster = address(bytes20(paymasterAndData[0:20]));\n if (paymaster.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA30 paymaster not deployed\");\n }\n }\n // always revert\n revert(\"\");\n }\n\n /**\n * call account.validateUserOp.\n * revert (with FailedOp) in case validateUserOp reverts, or account didn't send required prefund.\n * decrement account's deposit if needed\n */\n function _validateAccountPrepayment(\n uint256 opIndex,\n UserOperation calldata op,\n UserOpInfo memory opInfo,\n uint256 requiredPrefund\n )\n internal\n returns (\n uint256 gasUsedByValidateAccountPrepayment,\n uint256 validationData\n )\n {\n unchecked {\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n address sender = mUserOp.sender;\n _createSenderIfNeeded(opIndex, opInfo, op.initCode);\n address paymaster = mUserOp.paymaster;\n numberMarker();\n uint256 missingAccountFunds = 0;\n if (paymaster == address(0)) {\n uint256 bal = balanceOf(sender);\n missingAccountFunds = bal > requiredPrefund\n ? 0\n : requiredPrefund - bal;\n }\n try\n IAccount(sender).validateUserOp{\n gas: mUserOp.verificationGasLimit\n }(op, opInfo.userOpHash, missingAccountFunds)\n returns (uint256 _validationData) {\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA23 reverted: \", revertReason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA23 reverted (or OOG)\");\n }\n if (paymaster == address(0)) {\n DepositInfo storage senderInfo = deposits[sender];\n uint256 deposit = senderInfo.deposit;\n if (requiredPrefund > deposit) {\n revert FailedOp(opIndex, \"AA21 didn't pay prefund\");\n }\n senderInfo.deposit = uint112(deposit - requiredPrefund);\n }\n gasUsedByValidateAccountPrepayment = preGas - gasleft();\n }\n }\n\n /**\n * In case the request has a paymaster:\n * Validate paymaster has enough deposit.\n * Call paymaster.validatePaymasterUserOp.\n * Revert with proper FailedOp in case paymaster reverts.\n * Decrement paymaster's deposit\n */\n function _validatePaymasterPrepayment(\n uint256 opIndex,\n UserOperation calldata op,\n UserOpInfo memory opInfo,\n uint256 requiredPreFund,\n uint256 gasUsedByValidateAccountPrepayment\n ) internal returns (bytes memory context, uint256 validationData) {\n unchecked {\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 verificationGasLimit = mUserOp.verificationGasLimit;\n require(\n verificationGasLimit > gasUsedByValidateAccountPrepayment,\n \"AA41 too little verificationGas\"\n );\n uint256 gas = verificationGasLimit -\n gasUsedByValidateAccountPrepayment;\n\n address paymaster = mUserOp.paymaster;\n DepositInfo storage paymasterInfo = deposits[paymaster];\n uint256 deposit = paymasterInfo.deposit;\n if (deposit < requiredPreFund) {\n revert FailedOp(opIndex, \"AA31 paymaster deposit too low\");\n }\n paymasterInfo.deposit = uint112(deposit - requiredPreFund);\n try\n IPaymaster(paymaster).validatePaymasterUserOp{gas: gas}(\n op,\n opInfo.userOpHash,\n requiredPreFund\n )\n returns (bytes memory _context, uint256 _validationData) {\n context = _context;\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA33 reverted: \", revertReason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA33 reverted (or OOG)\");\n }\n }\n }\n\n /**\n * revert if either account validationData or paymaster validationData is expired\n */\n function _validateAccountAndPaymasterValidationData(\n uint256 opIndex,\n uint256 validationData,\n uint256 paymasterValidationData,\n address expectedAggregator\n ) internal view {\n (address aggregator, bool outOfTimeRange) = _getValidationData(\n validationData\n );\n if (expectedAggregator != aggregator) {\n revert FailedOp(opIndex, \"AA24 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA22 expired or not due\");\n }\n //pmAggregator is not a real signature aggregator: we don't have logic to handle it as address.\n // non-zero address means that the paymaster fails due to some signature check (which is ok only during estimation)\n address pmAggregator;\n (pmAggregator, outOfTimeRange) = _getValidationData(\n paymasterValidationData\n );\n if (pmAggregator != address(0)) {\n revert FailedOp(opIndex, \"AA34 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA32 paymaster expired or not due\");\n }\n }\n\n function _getValidationData(\n uint256 validationData\n ) internal view returns (address aggregator, bool outOfTimeRange) {\n if (validationData == 0) {\n return (address(0), false);\n }\n ValidationData memory data = _parseValidationData(validationData);\n // solhint-disable-next-line not-rely-on-time\n outOfTimeRange =\n block.timestamp > data.validUntil ||\n block.timestamp < data.validAfter;\n aggregator = data.aggregator;\n }\n\n /**\n * validate account and paymaster (if defined).\n * also make sure total validation doesn't exceed verificationGasLimit\n * this method is called off-chain (simulateValidation()) and on-chain (from handleOps)\n * @param opIndex the index of this userOp into the \"opInfos\" array\n * @param userOp the userOp to validate\n */\n function _validatePrepayment(\n uint256 opIndex,\n UserOperation calldata userOp,\n UserOpInfo memory outOpInfo\n )\n private\n returns (uint256 validationData, uint256 paymasterValidationData)\n {\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = outOpInfo.mUserOp;\n _copyUserOpToMemory(userOp, mUserOp);\n outOpInfo.userOpHash = getUserOpHash(userOp);\n\n // validate all numeric values in userOp are well below 128 bit, so they can safely be added\n // and multiplied without causing overflow\n uint256 maxGasValues = mUserOp.preVerificationGas |\n mUserOp.verificationGasLimit |\n mUserOp.callGasLimit |\n userOp.maxFeePerGas |\n userOp.maxPriorityFeePerGas;\n require(maxGasValues <= type(uint120).max, \"AA94 gas values overflow\");\n\n uint256 gasUsedByValidateAccountPrepayment;\n uint256 requiredPreFund = _getRequiredPrefund(mUserOp);\n (\n gasUsedByValidateAccountPrepayment,\n validationData\n ) = _validateAccountPrepayment(\n opIndex,\n userOp,\n outOpInfo,\n requiredPreFund\n );\n\n if (!_validateAndUpdateNonce(mUserOp.sender, mUserOp.nonce)) {\n revert FailedOp(opIndex, \"AA25 invalid account nonce\");\n }\n\n //a \"marker\" where account opcode validation is done and paymaster opcode validation is about to start\n // (used only by off-chain simulateValidation)\n numberMarker();\n\n bytes memory context;\n if (mUserOp.paymaster != address(0)) {\n (context, paymasterValidationData) = _validatePaymasterPrepayment(\n opIndex,\n userOp,\n outOpInfo,\n requiredPreFund,\n gasUsedByValidateAccountPrepayment\n );\n }\n unchecked {\n uint256 gasUsed = preGas - gasleft();\n\n if (userOp.verificationGasLimit < gasUsed) {\n revert FailedOp(opIndex, \"AA40 over verificationGasLimit\");\n }\n outOpInfo.prefund = requiredPreFund;\n outOpInfo.contextOffset = getOffsetOfMemoryBytes(context);\n outOpInfo.preOpGas = preGas - gasleft() + userOp.preVerificationGas;\n }\n }\n\n /**\n * process post-operation.\n * called just after the callData is executed.\n * if a paymaster is defined and its validation returned a non-empty context, its postOp is called.\n * the excess amount is refunded to the account (or paymaster - if it was used in the request)\n * @param opIndex index in the batch\n * @param mode - whether is called from innerHandleOp, or outside (postOpReverted)\n * @param opInfo userOp fields and info collected during validation\n * @param context the context returned in validatePaymasterUserOp\n * @param actualGas the gas used so far by this user operation\n */\n function _handlePostOp(\n uint256 opIndex,\n IPaymaster.PostOpMode mode,\n UserOpInfo memory opInfo,\n bytes memory context,\n uint256 actualGas\n ) private returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n unchecked {\n address refundAddress;\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 gasPrice = getUserOpGasPrice(mUserOp);\n\n address paymaster = mUserOp.paymaster;\n if (paymaster == address(0)) {\n refundAddress = mUserOp.sender;\n } else {\n refundAddress = paymaster;\n if (context.length > 0) {\n actualGasCost = actualGas * gasPrice;\n if (mode != IPaymaster.PostOpMode.postOpReverted) {\n IPaymaster(paymaster).postOp{\n gas: mUserOp.verificationGasLimit\n }(mode, context, actualGasCost);\n } else {\n // solhint-disable-next-line no-empty-blocks\n try\n IPaymaster(paymaster).postOp{\n gas: mUserOp.verificationGasLimit\n }(mode, context, actualGasCost)\n {} catch Error(string memory reason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA50 postOp reverted: \", reason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA50 postOp revert\");\n }\n }\n }\n }\n actualGas += preGas - gasleft();\n actualGasCost = actualGas * gasPrice;\n if (opInfo.prefund < actualGasCost) {\n revert FailedOp(opIndex, \"AA51 prefund below actualGasCost\");\n }\n uint256 refund = opInfo.prefund - actualGasCost;\n _incrementDeposit(refundAddress, refund);\n bool success = mode == IPaymaster.PostOpMode.opSucceeded;\n emit UserOperationEvent(\n opInfo.userOpHash,\n mUserOp.sender,\n mUserOp.paymaster,\n mUserOp.nonce,\n success,\n actualGasCost,\n actualGas\n );\n } // unchecked\n }\n\n /**\n * the gas price this UserOp agrees to pay.\n * relayer/block builder might submit the TX with higher priorityFee, but the user should not\n */\n function getUserOpGasPrice(\n MemoryUserOp memory mUserOp\n ) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = mUserOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = mUserOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n function getOffsetOfMemoryBytes(\n bytes memory data\n ) internal pure returns (uint256 offset) {\n assembly {\n offset := data\n }\n }\n\n function getMemoryBytesFromOffset(\n uint256 offset\n ) internal pure returns (bytes memory data) {\n assembly {\n data := offset\n }\n }\n\n //place the NUMBER opcode in the code.\n // this is used as a marker during simulation, as this OP is completely banned from the simulated code of the\n // account and paymaster.\n function numberMarker() internal view {\n assembly {\n mstore(0, number())\n }\n }\n}\n" + }, + "contracts/aa-4337/core/Helpers.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable no-inline-assembly */\n\n/**\n * returned data from validateUserOp.\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\n * @param aggregator - address(0) - the account validated the signature by itself.\n * address(1) - the account failed to validate the signature.\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\n * @param validAfter - this UserOp is valid only after this timestamp.\n * @param validaUntil - this UserOp is valid only up to this timestamp.\n */\nstruct ValidationData {\n address aggregator;\n uint48 validAfter;\n uint48 validUntil;\n}\n\n//extract sigFailed, validAfter, validUntil.\n// also convert zero validUntil to type(uint48).max\nfunction _parseValidationData(\n uint validationData\n) pure returns (ValidationData memory data) {\n address aggregator = address(uint160(validationData));\n uint48 validUntil = uint48(validationData >> 160);\n if (validUntil == 0) {\n validUntil = type(uint48).max;\n }\n uint48 validAfter = uint48(validationData >> (48 + 160));\n return ValidationData(aggregator, validAfter, validUntil);\n}\n\n// intersect account and paymaster ranges.\nfunction _intersectTimeRange(\n uint256 validationData,\n uint256 paymasterValidationData\n) pure returns (ValidationData memory) {\n ValidationData memory accountValidationData = _parseValidationData(\n validationData\n );\n ValidationData memory pmValidationData = _parseValidationData(\n paymasterValidationData\n );\n address aggregator = accountValidationData.aggregator;\n if (aggregator == address(0)) {\n aggregator = pmValidationData.aggregator;\n }\n uint48 validAfter = accountValidationData.validAfter;\n uint48 validUntil = accountValidationData.validUntil;\n uint48 pmValidAfter = pmValidationData.validAfter;\n uint48 pmValidUntil = pmValidationData.validUntil;\n\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\n return ValidationData(aggregator, validAfter, validUntil);\n}\n\n/**\n * helper to pack the return value for validateUserOp\n * @param data - the ValidationData to pack\n */\nfunction _packValidationData(\n ValidationData memory data\n) pure returns (uint256) {\n return\n uint160(data.aggregator) |\n (uint256(data.validUntil) << 160) |\n (uint256(data.validAfter) << (160 + 48));\n}\n\n/**\n * helper to pack the return value for validateUserOp, when not using an aggregator\n * @param sigFailed - true for signature failure, false for success\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\n * @param validAfter first timestamp this UserOperation is valid\n */\nfunction _packValidationData(\n bool sigFailed,\n uint48 validUntil,\n uint48 validAfter\n) pure returns (uint256) {\n return\n (sigFailed ? 1 : 0) |\n (uint256(validUntil) << 160) |\n (uint256(validAfter) << (160 + 48));\n}\n\n/**\n * keccak function over calldata.\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\n */\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\n assembly {\n let mem := mload(0x40)\n let len := data.length\n calldatacopy(mem, data.offset, len)\n ret := keccak256(mem, len)\n }\n}\n" + }, + "contracts/aa-4337/core/NonceManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\nimport \"../interfaces/IEntryPoint.sol\";\n\n/**\n * nonce management functionality\n */\ncontract NonceManager is INonceManager {\n /**\n * The next valid sequence number for a given nonce key.\n */\n mapping(address => mapping(uint192 => uint256)) public nonceSequenceNumber;\n\n function getNonce(\n address sender,\n uint192 key\n ) public view override returns (uint256 nonce) {\n return nonceSequenceNumber[sender][key] | (uint256(key) << 64);\n }\n\n // allow an account to manually increment its own nonce.\n // (mainly so that during construction nonce can be made non-zero,\n // to \"absorb\" the gas cost of first nonce increment to 1st transaction (construction),\n // not to 2nd transaction)\n function incrementNonce(uint192 key) public override {\n nonceSequenceNumber[msg.sender][key]++;\n }\n\n /**\n * validate nonce uniqueness for this account.\n * called just after validateUserOp()\n */\n function _validateAndUpdateNonce(\n address sender,\n uint256 nonce\n ) internal returns (bool) {\n uint192 key = uint192(nonce >> 64);\n uint64 seq = uint64(nonce);\n return nonceSequenceNumber[sender][key]++ == seq;\n }\n}\n" + }, + "contracts/aa-4337/core/SenderCreator.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/**\n * helper contract for EntryPoint, to call userOp.initCode from a \"neutral\" address,\n * which is explicitly not the entryPoint itself.\n */\ncontract SenderCreator {\n /**\n * call the \"initCode\" factory to create and return the sender account address\n * @param initCode the initCode value from a UserOp. contains 20 bytes of factory address, followed by calldata\n * @return sender the returned address of the created account, or zero address on failure.\n */\n function createSender(\n bytes calldata initCode\n ) external returns (address sender) {\n address factory = address(bytes20(initCode[0:20]));\n bytes memory initCallData = initCode[20:];\n bool success;\n /* solhint-disable no-inline-assembly */\n assembly {\n success := call(\n gas(),\n factory,\n 0,\n add(initCallData, 0x20),\n mload(initCallData),\n 0,\n 32\n )\n sender := mload(0)\n }\n if (!success) {\n sender = address(0);\n }\n }\n}\n" + }, + "contracts/aa-4337/core/StakeManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity 0.8.21;\n\nimport \"../interfaces/IStakeManager.sol\";\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable not-rely-on-time */\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by a paymaster.\n */\nabstract contract StakeManager is IStakeManager {\n /// maps paymaster to their deposits and stakes\n mapping(address => DepositInfo) public deposits;\n\n /// @inheritdoc IStakeManager\n function getDepositInfo(\n address account\n ) public view returns (DepositInfo memory info) {\n return deposits[account];\n }\n\n // internal method to return just the stake info\n function _getStakeInfo(\n address addr\n ) internal view returns (StakeInfo memory info) {\n DepositInfo storage depositInfo = deposits[addr];\n info.stake = depositInfo.stake;\n info.unstakeDelaySec = depositInfo.unstakeDelaySec;\n }\n\n /// return the deposit (for gas payment) of the account\n function balanceOf(address account) public view returns (uint256) {\n return deposits[account].deposit;\n }\n\n receive() external payable {\n depositTo(msg.sender);\n }\n\n function _incrementDeposit(address account, uint256 amount) internal {\n DepositInfo storage info = deposits[account];\n uint256 newAmount = info.deposit + amount;\n require(newAmount <= type(uint112).max, \"deposit overflow\");\n info.deposit = uint112(newAmount);\n }\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) public payable {\n _incrementDeposit(account, msg.value);\n DepositInfo storage info = deposits[account];\n emit Deposited(account, info.deposit);\n }\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 unstakeDelaySec) public payable {\n DepositInfo storage info = deposits[msg.sender];\n require(unstakeDelaySec > 0, \"must specify unstake delay\");\n require(\n unstakeDelaySec >= info.unstakeDelaySec,\n \"cannot decrease unstake time\"\n );\n uint256 stake = info.stake + msg.value;\n require(stake > 0, \"no stake specified\");\n require(stake <= type(uint112).max, \"stake overflow\");\n deposits[msg.sender] = DepositInfo(\n info.deposit,\n true,\n uint112(stake),\n unstakeDelaySec,\n 0\n );\n emit StakeLocked(msg.sender, stake, unstakeDelaySec);\n }\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external {\n DepositInfo storage info = deposits[msg.sender];\n require(info.unstakeDelaySec != 0, \"not staked\");\n require(info.staked, \"already unstaking\");\n uint48 withdrawTime = uint48(block.timestamp) + info.unstakeDelaySec;\n info.withdrawTime = withdrawTime;\n info.staked = false;\n emit StakeUnlocked(msg.sender, withdrawTime);\n }\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external {\n DepositInfo storage info = deposits[msg.sender];\n uint256 stake = info.stake;\n require(stake > 0, \"No stake to withdraw\");\n require(info.withdrawTime > 0, \"must call unlockStake() first\");\n require(\n info.withdrawTime <= block.timestamp,\n \"Stake withdrawal is not due\"\n );\n info.unstakeDelaySec = 0;\n info.withdrawTime = 0;\n info.stake = 0;\n emit StakeWithdrawn(msg.sender, withdrawAddress, stake);\n (bool success, ) = withdrawAddress.call{value: stake}(\"\");\n require(success, \"failed to withdraw stake\");\n }\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(\n address payable withdrawAddress,\n uint256 withdrawAmount\n ) external {\n DepositInfo storage info = deposits[msg.sender];\n require(withdrawAmount <= info.deposit, \"Withdraw amount too large\");\n info.deposit = uint112(info.deposit - withdrawAmount);\n emit Withdrawn(msg.sender, withdrawAddress, withdrawAmount);\n (bool success, ) = withdrawAddress.call{value: withdrawAmount}(\"\");\n require(success, \"failed to withdraw\");\n }\n}\n" + }, + "contracts/aa-4337/interfaces/IAccount.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\ninterface IAccount {\n /**\n * Validate user's signature and nonce\n * the entryPoint will make the call to the recipient only if this validation call returns successfully.\n * signature failure should be reported by returning SIG_VALIDATION_FAILED (1).\n * This allows making a \"simulation call\" without a valid signature\n * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure.\n *\n * @dev Must validate caller is the entryPoint.\n * Must validate the signature and nonce\n * @param userOp the operation that is about to be executed.\n * @param userOpHash hash of the user's request data. can be used as the basis for signature.\n * @param missingAccountFunds missing funds on the account's deposit in the entrypoint.\n * This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call.\n * The excess is left as a deposit in the entrypoint, for future calls.\n * can be withdrawn anytime using \"entryPoint.withdrawTo()\"\n * In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero.\n * @return validationData packaged ValidationData structure. use `_packValidationData` and `_unpackValidationData` to encode and decode\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * If an account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validateUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 missingAccountFunds\n ) external returns (uint256 validationData);\n}\n" + }, + "contracts/aa-4337/interfaces/IAggregator.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * Aggregated Signatures validator.\n */\ninterface IAggregator {\n /**\n * validate aggregated signature.\n * revert if the aggregated signature does not match the given list of operations.\n */\n function validateSignatures(\n UserOperation[] calldata userOps,\n bytes calldata signature\n ) external view;\n\n /**\n * validate signature of a single userOp\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\n * @param userOp the userOperation received from the user.\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\n * (usually empty, unless account and aggregator support some kind of \"multisig\"\n */\n function validateUserOpSignature(\n UserOperation calldata userOp\n ) external view returns (bytes memory sigForUserOp);\n\n /**\n * aggregate multiple signatures into a single value.\n * This method is called off-chain to calculate the signature to pass with handleOps()\n * bundler MAY use optimized custom code perform this aggregation\n * @param userOps array of UserOperations to collect the signatures from.\n * @return aggregatedSignature the aggregated signature\n */\n function aggregateSignatures(\n UserOperation[] calldata userOps\n ) external view returns (bytes memory aggregatedSignature);\n}\n" + }, + "contracts/aa-4337/interfaces/IEntryPoint.sol": { + "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n/* solhint-disable reason-string */\n\nimport \"./UserOperation.sol\";\nimport \"./IStakeManager.sol\";\nimport \"./IAggregator.sol\";\nimport \"./INonceManager.sol\";\n\ninterface IEntryPoint is IStakeManager, INonceManager {\n /***\n * An event emitted after each successful request\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\n * @param sender - the account that generates this request.\n * @param paymaster - if non-null, the paymaster that pays for this request.\n * @param nonce - the nonce value from the request.\n * @param success - true if the sender transaction succeeded, false if reverted.\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\n */\n event UserOperationEvent(\n bytes32 indexed userOpHash,\n address indexed sender,\n address indexed paymaster,\n uint256 nonce,\n bool success,\n uint256 actualGasCost,\n uint256 actualGasUsed\n );\n\n /**\n * account \"sender\" was deployed.\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\n * @param sender the account that is deployed\n * @param factory the factory used to deploy this account (in the initCode)\n * @param paymaster the paymaster used by this UserOp\n */\n event AccountDeployed(\n bytes32 indexed userOpHash,\n address indexed sender,\n address factory,\n address paymaster\n );\n\n /**\n * An event emitted if the UserOperation \"callData\" reverted with non-zero length\n * @param userOpHash the request unique identifier.\n * @param sender the sender of this request\n * @param nonce the nonce used in the request\n * @param revertReason - the return bytes from the (reverted) call to \"callData\".\n */\n event UserOperationRevertReason(\n bytes32 indexed userOpHash,\n address indexed sender,\n uint256 nonce,\n bytes revertReason\n );\n\n /**\n * an event emitted by handleOps(), before starting the execution loop.\n * any event emitted before this event, is part of the validation.\n */\n event BeforeExecution();\n\n /**\n * signature aggregator used by the following UserOperationEvents within this bundle.\n */\n event SignatureAggregatorChanged(address indexed aggregator);\n\n /**\n * a custom revert error of handleOps, to identify the offending op.\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\n * @param reason - revert reason\n * The string starts with a unique code \"AAmn\", where \"m\" is \"1\" for factory, \"2\" for account and \"3\" for paymaster issues,\n * so a failure can be attributed to the correct entity.\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\n */\n error FailedOp(uint256 opIndex, string reason);\n\n /**\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\n */\n error SignatureValidationFailed(address aggregator);\n\n /**\n * Successful result from simulateValidation.\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n */\n error ValidationResult(\n ReturnInfo returnInfo,\n StakeInfo senderInfo,\n StakeInfo factoryInfo,\n StakeInfo paymasterInfo\n );\n\n /**\n * Successful result from simulateValidation, if the account returns a signature aggregator\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\n * bundler MUST use it to verify the signature, or reject the UserOperation\n */\n error ValidationResultWithAggregation(\n ReturnInfo returnInfo,\n StakeInfo senderInfo,\n StakeInfo factoryInfo,\n StakeInfo paymasterInfo,\n AggregatorStakeInfo aggregatorInfo\n );\n\n /**\n * return value of getSenderAddress\n */\n error SenderAddressResult(address sender);\n\n /**\n * return value of simulateHandleOp\n */\n error ExecutionResult(\n uint256 preOpGas,\n uint256 paid,\n uint48 validAfter,\n uint48 validUntil,\n bool targetSuccess,\n bytes targetResult\n );\n\n //UserOps handled, per aggregator\n struct UserOpsPerAggregator {\n UserOperation[] userOps;\n // aggregator address\n IAggregator aggregator;\n // aggregated signature\n bytes signature;\n }\n\n /**\n * Execute a batch of UserOperation.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(\n UserOperation[] calldata ops,\n address payable beneficiary\n ) external;\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) external;\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(\n UserOperation calldata userOp\n ) external view returns (bytes32);\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external;\n\n /**\n * gas and return values during simulation\n * @param preOpGas the gas used for validation (including preValidationGas)\n * @param prefund the required prefund for this operation\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\n */\n struct ReturnInfo {\n uint256 preOpGas;\n uint256 prefund;\n bool sigFailed;\n uint48 validAfter;\n uint48 validUntil;\n bytes paymasterContext;\n }\n\n /**\n * returned aggregated signature info.\n * the aggregator returned by the account, and its current stake.\n */\n struct AggregatorStakeInfo {\n address aggregator;\n StakeInfo stakeInfo;\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes memory initCode) external;\n\n /**\n * simulate full execution of a UserOperation (including both validation and target execution)\n * this method will always revert with \"ExecutionResult\".\n * it performs full validation of the UserOperation, but ignores signature error.\n * an optional target address is called after the userop succeeds, and its value is returned\n * (before the entire call is reverted)\n * Note that in order to collect the the success/failure of the target call, it must be executed\n * with trace enabled to track the emitted events.\n * @param op the UserOperation to simulate\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\n * are set to the return from that call.\n * @param targetCallData callData to pass to target address\n */\n function simulateHandleOp(\n UserOperation calldata op,\n address target,\n bytes calldata targetCallData\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/INonceManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\ninterface INonceManager {\n /**\n * Return the next nonce for this sender.\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\n * But UserOp with different keys can come with arbitrary order.\n *\n * @param sender the account address\n * @param key the high 192 bit of the nonce\n * @return nonce a full nonce to pass for next UserOp with this sender.\n */\n function getNonce(\n address sender,\n uint192 key\n ) external view returns (uint256 nonce);\n\n /**\n * Manually increment the nonce of the sender.\n * This method is exposed just for completeness..\n * Account does NOT need to call it, neither during validation, nor elsewhere,\n * as the EntryPoint will update the nonce regardless.\n * Possible use-case is call it with various keys to \"initialize\" their nonces to one, so that future\n * UserOperations will not pay extra for the first transaction with a given key.\n */\n function incrementNonce(uint192 key) external;\n}\n" + }, + "contracts/aa-4337/interfaces/IPaymaster.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * the interface exposed by a paymaster contract, who agrees to pay the gas for user's operations.\n * a paymaster must hold a stake to cover the required entrypoint stake and also the gas for the transaction.\n */\ninterface IPaymaster {\n enum PostOpMode {\n opSucceeded, // user op succeeded\n opReverted, // user op reverted. still has to pay for gas.\n postOpReverted //user op succeeded, but caused postOp to revert. Now it's a 2nd call, after user's op was deliberately reverted.\n }\n\n /**\n * payment validation: check if paymaster agrees to pay.\n * Must verify sender is the entryPoint.\n * Revert to reject this request.\n * Note that bundlers will reject this method if it changes the state, unless the paymaster is trusted (whitelisted)\n * The paymaster pre-pays using its deposit, and receive back a refund after the postOp method returns.\n * @param userOp the user operation\n * @param userOpHash hash of the user's request data.\n * @param maxCost the maximum cost of this transaction (based on maximum gas and gas price from userOp)\n * @return context value to send to a postOp\n * zero length to signify postOp is not required.\n * @return validationData signature and time-range of this operation, encoded the same as the return value of validateUserOperation\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validatePaymasterUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 maxCost\n ) external returns (bytes memory context, uint256 validationData);\n\n /**\n * post-operation handler.\n * Must verify sender is the entryPoint\n * @param mode enum with the following options:\n * opSucceeded - user operation succeeded.\n * opReverted - user op reverted. still has to pay for gas.\n * postOpReverted - user op succeeded, but caused postOp (in mode=opSucceeded) to revert.\n * Now this is the 2nd call, after user's op was deliberately reverted.\n * @param context - the context value returned by validatePaymasterUserOp\n * @param actualGasCost - actual gas used so far (without this postOp call).\n */\n function postOp(\n PostOpMode mode,\n bytes calldata context,\n uint256 actualGasCost\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/IStakeManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.12;\n\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by the staked entity.\n */\ninterface IStakeManager {\n event Deposited(address indexed account, uint256 totalDeposit);\n\n event Withdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /// Emitted when stake or unstake delay are modified\n event StakeLocked(\n address indexed account,\n uint256 totalStaked,\n uint256 unstakeDelaySec\n );\n\n /// Emitted once a stake is scheduled for withdrawal\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\n\n event StakeWithdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /**\n * @param deposit the entity's deposit\n * @param staked true if this entity is staked.\n * @param stake actual amount of ether staked for this entity.\n * @param unstakeDelaySec minimum delay to withdraw the stake.\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\n * and the rest fit into a 2nd cell.\n * 112 bit allows for 10^15 eth\n * 48 bit for full timestamp\n * 32 bit allows 150 years for unstake delay\n */\n struct DepositInfo {\n uint112 deposit;\n bool staked;\n uint112 stake;\n uint32 unstakeDelaySec;\n uint48 withdrawTime;\n }\n\n //API struct used by getStakeInfo and simulateValidation\n struct StakeInfo {\n uint256 stake;\n uint256 unstakeDelaySec;\n }\n\n /// @return info - full deposit information of given account\n function getDepositInfo(\n address account\n ) external view returns (DepositInfo memory info);\n\n /// @return the deposit (for gas payment) of the account\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) external payable;\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 _unstakeDelaySec) external payable;\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external;\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external;\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(\n address payable withdrawAddress,\n uint256 withdrawAmount\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/UserOperation.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable no-inline-assembly */\n\nimport {calldataKeccak} from \"../core/Helpers.sol\";\n\n/**\n * User Operation struct\n * @param sender the sender account of this request.\n * @param nonce unique value the sender uses to verify it is not a replay.\n * @param initCode if set, the account contract will be created by this constructor/\n * @param callData the method call to execute on this account.\n * @param callGasLimit the gas limit passed to the callData method call.\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\n * @param maxFeePerGas same as EIP-1559 gas parameter.\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\n */\nstruct UserOperation {\n address sender;\n uint256 nonce;\n bytes initCode;\n bytes callData;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n bytes paymasterAndData;\n bytes signature;\n}\n\n/**\n * Utility functions helpful when working with UserOperation structs.\n */\nlibrary UserOperationLib {\n function getSender(\n UserOperation calldata userOp\n ) internal pure returns (address) {\n address data;\n //read sender from userOp, which is first userOp member (saves 800 gas...)\n assembly {\n data := calldataload(userOp)\n }\n return address(uint160(data));\n }\n\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\n // pay above what he signed for.\n function gasPrice(\n UserOperation calldata userOp\n ) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function pack(\n UserOperation calldata userOp\n ) internal pure returns (bytes memory ret) {\n address sender = getSender(userOp);\n uint256 nonce = userOp.nonce;\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\n bytes32 hashCallData = calldataKeccak(userOp.callData);\n uint256 callGasLimit = userOp.callGasLimit;\n uint256 verificationGasLimit = userOp.verificationGasLimit;\n uint256 preVerificationGas = userOp.preVerificationGas;\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\n\n return\n abi.encode(\n sender,\n nonce,\n hashInitCode,\n hashCallData,\n callGasLimit,\n verificationGasLimit,\n preVerificationGas,\n maxFeePerGas,\n maxPriorityFeePerGas,\n hashPaymasterAndData\n );\n }\n\n function hash(\n UserOperation calldata userOp\n ) internal pure returns (bytes32) {\n return keccak256(pack(userOp));\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n}\n" + }, + "contracts/aa-4337/utils/Exec.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.5 <0.9.0;\n\n// solhint-disable no-inline-assembly\n\n/**\n * Utility functions helpful when making different kinds of contract calls in Solidity.\n */\nlibrary Exec {\n function call(\n address to,\n uint256 value,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := call(\n txGas,\n to,\n value,\n add(data, 0x20),\n mload(data),\n 0,\n 0\n )\n }\n }\n\n function staticcall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal view returns (bool success) {\n assembly {\n success := staticcall(txGas, to, add(data, 0x20), mload(data), 0, 0)\n }\n }\n\n function delegateCall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := delegatecall(\n txGas,\n to,\n add(data, 0x20),\n mload(data),\n 0,\n 0\n )\n }\n }\n\n // get returned data from last call or calldelegate\n function getReturnData(\n uint256 maxLen\n ) internal pure returns (bytes memory returnData) {\n assembly {\n let len := returndatasize()\n if gt(len, maxLen) {\n len := maxLen\n }\n let ptr := mload(0x40)\n mstore(0x40, add(ptr, add(len, 0x20)))\n mstore(ptr, len)\n returndatacopy(add(ptr, 0x20), 0, len)\n returnData := ptr\n }\n }\n\n // revert with explicit byte array (probably reverted info from call)\n function revertWithData(bytes memory returnData) internal pure {\n assembly {\n revert(add(returnData, 32), mload(returnData))\n }\n }\n\n function callAndRevert(\n address to,\n bytes memory data,\n uint256 maxLen\n ) internal {\n bool success = call(to, 0, data, gasleft());\n if (!success) {\n revertWithData(getReturnData(maxLen));\n }\n }\n}\n" + }, + "contracts/Barz.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"./libraries/LibDiamond.sol\";\nimport {IBarz} from \"./interfaces/IBarz.sol\";\n\n/**\n * @title Barz\n * @dev A diamond proxy wallet with a modular & upgradeable architecture\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract Barz is IBarz {\n /**\n * @notice Initializes Barz with the given parameters. Barz account is intended to be created from Barz Factory for stable deployment.\n * @dev This method makes a delegate call to account facet and account facet handles the initialization.\n * With modular architecture, Barz encompasses wide spectrum of architecture and logic.\n * The only requirement is account facet to comply with initialize() interface.\n * Barz doesn't include built-in functions and is a full proxy, for maximum extensibility and modularity.\n * @param _accountFacet Address of Account Facet in charge of the Barz initialization\n * @param _verificationFacet Address of Verification Facet for verifying the signature. Could be any signature scheme\n * @param _entryPoint Address of Entry Point contract\n * @param _facetRegistry Address of Facet Registry. Facet Registry is a registry holding trusted facets that could be added to user's wallet\n * @param _defaultFallBack Address of Default FallBack Handler. Middleware contract for more efficient deployment\n * @param _ownerPublicKey Bytes of Owner Public Key using for initialization\n */\n constructor(\n address _accountFacet,\n address _verificationFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallBack,\n bytes memory _ownerPublicKey\n ) payable {\n bytes memory initCall = abi.encodeWithSignature(\n \"initialize(address,address,address,address,bytes)\",\n _verificationFacet,\n _entryPoint,\n _facetRegistry,\n _defaultFallBack,\n _ownerPublicKey\n );\n (bool success, bytes memory result) = _accountFacet.delegatecall(\n initCall\n );\n if (!success || uint256(bytes32(result)) != 1) {\n revert Barz__InitializationFailure();\n }\n }\n\n /**\n * @notice Fallback function for Barz complying with Diamond Standard with customization of adding Default Fallback Handler\n * @dev Find facet for function that is called and execute the function if a facet is found and return any value.\n */\n fallback() external payable {\n LibDiamond.DiamondStorage storage ds;\n bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION;\n // get diamond storage\n assembly {\n ds.slot := position\n }\n // get facet from function selector\n address facet = address(bytes20(ds.facets[msg.sig]));\n if (facet == address(0))\n facet = ds.defaultFallbackHandler.facetAddress(msg.sig);\n require(facet != address(0), \"Barz: Function does not exist\");\n // Execute external function from facet using delegatecall and return any value.\n assembly {\n // copy function selector and any arguments\n calldatacopy(0, 0, calldatasize())\n // execute function call using the facet\n let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)\n // get any return value\n returndatacopy(0, 0, returndatasize())\n // return any return value or error back to the caller\n switch result\n case 0 {\n revert(0, returndatasize())\n }\n default {\n return(0, returndatasize())\n }\n }\n }\n\n /**\n * @notice Receive function to receive native token without data\n */\n receive() external payable {}\n}\n" + }, + "contracts/BarzFactory.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Barz} from \"./Barz.sol\";\nimport {IBarzFactory} from \"./interfaces/IBarzFactory.sol\";\n\n/**\n * @title Barz Factory\n * @dev Contract to easily deploy Barz to a pre-computed address with a single call\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract BarzFactory is IBarzFactory {\n event BarzDeployed(address);\n\n address public immutable accountFacet;\n address public immutable entryPoint;\n address public immutable facetRegistry;\n address public immutable defaultFallback;\n\n /**\n * @notice Sets the initialization data for Barz contract initialization\n * @param _accountFacet Account Facet to be used to create Barz\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\n * @param _facetRegistry Facet Registry to be used to create Barz\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\n */\n constructor(\n address _accountFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallback\n ) {\n accountFacet = _accountFacet;\n entryPoint = _entryPoint;\n facetRegistry = _facetRegistry;\n defaultFallback = _defaultFallback;\n }\n\n /**\n * @notice Creates the Barz with a single call. It creates the Barz contract with the givent verification facet\n * @param _verificationFacet Address of verification facet used for creating the barz account\n * @param _owner Public Key of the owner to initialize barz account\n * @param _salt Salt used for deploying barz with create2\n * @return barz Instance of Barz contract deployed with the given parameters\n */\n function createAccount(\n address _verificationFacet,\n bytes calldata _owner,\n uint256 _salt\n ) external override returns (Barz barz) {\n address addr = getAddress(_verificationFacet, _owner, _salt);\n uint codeSize = addr.code.length;\n if (codeSize > 0) {\n return Barz(payable(addr));\n }\n barz = new Barz{salt: bytes32(_salt)}(\n accountFacet,\n _verificationFacet,\n entryPoint,\n facetRegistry,\n defaultFallback,\n _owner\n );\n emit BarzDeployed(address(barz));\n }\n\n /**\n * @notice Calculates the address of Barz with the given parameters\n * @param _verificationFacet Address of verification facet used for creating the barz account\n * @param _owner Public Key of the owner to initialize barz account\n * @param _salt Salt used for deploying barz with create2\n * @return barzAddress Precalculated Barz address\n */\n function getAddress(\n address _verificationFacet,\n bytes calldata _owner,\n uint256 _salt\n ) public view override returns (address barzAddress) {\n bytes memory bytecode = getBytecode(\n accountFacet,\n _verificationFacet,\n entryPoint,\n facetRegistry,\n defaultFallback,\n _owner\n );\n bytes32 hash = keccak256(\n abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(bytecode)\n )\n );\n barzAddress = address(uint160(uint256(hash)));\n }\n\n /**\n * @notice Returns the bytecode of Barz with the given parameter\n * @param _accountFacet Account Facet to be used to create Barz\n * @param _verificationFacet Verification Facet to be used to create Barz\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\n * @param _facetRegistry Facet Registry to be used to create Barz\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\n * @param _ownerPublicKey Public Key of owner to be used to initialize Barz ownership\n * @return barzBytecode Bytecode of Barz\n */\n function getBytecode(\n address _accountFacet,\n address _verificationFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallback,\n bytes calldata _ownerPublicKey\n ) public pure override returns (bytes memory barzBytecode) {\n bytes memory bytecode = type(Barz).creationCode;\n barzBytecode = abi.encodePacked(\n bytecode,\n abi.encode(\n _accountFacet,\n _verificationFacet,\n _entryPoint,\n _facetRegistry,\n _defaultFallback,\n _ownerPublicKey\n )\n );\n }\n\n /**\n * @notice Returns the creation code of the Barz contract\n * @return creationCode Creation code of Barz\n */\n function getCreationCode()\n public\n pure\n override\n returns (bytes memory creationCode)\n {\n creationCode = type(Barz).creationCode;\n }\n}\n" + }, + "contracts/facets/AccountFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {UserOperation} from \"../aa-4337/interfaces/UserOperation.sol\";\nimport {IEntryPoint} from \"../aa-4337/interfaces/IEntryPoint.sol\";\nimport {BaseAccount} from \"../aa-4337/core/BaseAccount.sol\";\nimport {LibAppStorage, BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {IFacetRegistry} from \"../infrastructure/interfaces/IFacetRegistry.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {IERC1271} from \"../interfaces/ERC/IERC1271.sol\";\nimport {IAccountFacet} from \"./interfaces/IAccountFacet.sol\";\n\n/**\n * @title Account Facet\n * @dev Account module contract that provides the account features and initialization of signer\n * compatible with EIP-1271 & EIP-4337\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract AccountFacet is BarzStorage, BaseAccount, IAccountFacet {\n using ECDSA for bytes32;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceAccountInitialize();\n }\n\n /**\n * @notice Returns the address of EntryPoint contract registered to Barz account\n */\n function entryPoint() public view override returns (IEntryPoint) {\n return s.entryPoint;\n }\n\n /**\n * @notice Initializes the initial storage of the Barz contract.\n * @dev This method can only be called during the initialization or signature migration.\n * If the proxy contract was created without initialization, anyone can call initialize.\n * Barz calls initialize in constructor in an atomic transaction during deployment\n * @param _verificationFacet Facet contract handling the verificationi\n * @param _anEntryPoint Entrypoint contract defined in EIP-4337 handling the flow of UserOp\n * @param _facetRegistry Registry of Facets that hold all facet information\n * @param _defaultFallBackHandler Middleware contract for default facets\n * @param _ownerPublicKey Bytes of owner public key\n */\n function initialize(\n address _verificationFacet,\n address _anEntryPoint,\n address _facetRegistry,\n address _defaultFallBackHandler,\n bytes calldata _ownerPublicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceAccountInitialize();\n s.entryPoint = IEntryPoint(_anEntryPoint);\n s.facetRegistry = IFacetRegistry(_facetRegistry);\n LibDiamond.diamondStorage().defaultFallbackHandler = IDiamondLoupe(\n _defaultFallBackHandler\n );\n\n _cutDiamondAccountFacet(_verificationFacet);\n\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n _ownerPublicKey\n );\n // Every Verification Facet should comply with initializeSigner(bytes)\n // to be compatible with the Barz contract(for initialization)\n (bool success, bytes memory result) = _verificationFacet.delegatecall(\n initCall\n );\n if (!success || uint256(bytes32(result)) != 1) {\n revert AccountFacet__InitializationFailure();\n }\n\n initSuccess = 1;\n emit AccountInitialized(s.entryPoint, _ownerPublicKey);\n }\n\n function _cutDiamondAccountFacet(address _verificationFacet) internal {\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](1);\n\n bytes4 ownerVerificationFuncSelector = IVerificationFacet(\n _verificationFacet\n ).validateOwnerSignatureSelector();\n\n bytes4[] memory verificationFunctionSelectors = new bytes4[](3);\n verificationFunctionSelectors[0] = IERC1271.isValidSignature.selector;\n verificationFunctionSelectors[1] = ownerVerificationFuncSelector;\n verificationFunctionSelectors[2] = IVerificationFacet.owner.selector;\n cut[0] = IDiamondCut.FacetCut({\n facetAddress: _verificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: verificationFunctionSelectors\n });\n\n LibDiamond.diamondCut(cut, address(0), \"\");\n }\n\n /**\n * @notice Calls the destination with inputted calldata and value from EntryPoint\n * @dev This method executes the calldata coming from the EntryPoint.\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\n * @param _dest Address of destination where the call will be forwarded to\n * @param _value Amount of native coin the owner is willing to send(e.g. ETH, BNB)\n * @param _func Bytes of calldata to execute in the destination address\n */\n function execute(\n address _dest,\n uint256 _value,\n bytes calldata _func\n ) external override onlyWhenUnlocked {\n _requireFromEntryPoint();\n _call(_dest, _value, _func);\n }\n\n /**\n * @notice Batch calls the destination with inputted calldata and value from EntryPoint\n * @dev This method batch executes the calldata coming from the EntryPoint.\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\n * @param _dest Array of addresses of destination where the call will be forwarded to\n * @param _value Array of amount of native coin the owner is willing to send(e.g. ETH, BNB)\n * @param _func Array of bytes of calldata to execute in the destination address\n */\n function executeBatch(\n address[] calldata _dest,\n uint256[] calldata _value,\n bytes[] calldata _func\n ) external override onlyWhenUnlocked {\n _requireFromEntryPoint();\n require(\n _dest.length == _func.length && _dest.length == _value.length,\n \"wrong array lengths\"\n );\n for (uint256 i; i < _dest.length; ) {\n _call(_dest[i], _value[i], _func[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Validates the signature field of UserOperation\n * @dev This method validates if the signature of UserOp is indeed valid by delegating the call to Verification Facet\n * Barz makes a call to the pre-registered Verification Facet address in App Storage\n * @param _userOp UserOperation from owner to be validated\n * @param _userOpHash Hash of UserOperation given from the EntryPoint contract\n */\n function _validateSignature(\n UserOperation calldata _userOp,\n bytes32 _userOpHash\n ) internal override returns (uint256 validationData) {\n // Get Facet with Function Selector\n address facet = LibLoupe.facetAddress(s.validateOwnerSignatureSelector);\n if (facet == address(0))\n revert AccountFacet__NonExistentVerificationFacet();\n\n // Make function call to VerificationFacet\n bytes memory validateCall = abi.encodeWithSelector(\n s.validateOwnerSignatureSelector,\n _userOp,\n _userOpHash\n );\n (bool success, bytes memory result) = facet.delegatecall(validateCall);\n if (!success) revert AccountFacet__CallNotSuccessful();\n validationData = uint256(bytes32(result));\n if (validationData == 0) emit VerificationSuccess(_userOpHash);\n else emit VerificationFailure(_userOpHash);\n }\n\n /**\n * @notice Calls the target with the inputted value and calldata\n * @dev This method is the actual function in Barz that makes a call with an arbitrary owner-given data\n * @param _target Address of the destination contract which the call is getting forwarded to\n * @param _value Amount of Native coin the owner is wanting to make in this call\n * @param _data Calldata the owner is forwarding together in the call e.g. Swap/Token Transfer\n */\n function _call(\n address _target,\n uint256 _value,\n bytes memory _data\n ) internal {\n address facet = LibDiamond.restrictionsFacet();\n // NOTE: No restrictions facet, so restriction validation passes\n if (facet != address(0)) {\n if (_checkRestrictions(facet, _target, _value, _data) == 1)\n revert AccountFacet__RestrictionsFailure();\n }\n\n (bool success, bytes memory result) = _target.call{value: _value}(\n _data\n );\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n }\n\n /**\n * @notice Checks restrictions if the restrictions facet exists\n * @dev This method checks if the restrictions facet exists and makes a verification call to an array of restrictions facet\n * @param _facet Address that holds the restrictions logic\n * @param _target Address the call is getting forwarded to\n * @param _value Amount of native coin the call is sending together with the call\n * @param _data Calldata to trigger execution in target address\n */\n function _checkRestrictions(\n address _facet,\n address _target,\n uint256 _value,\n bytes memory _data\n ) internal returns (uint256 result) {\n bytes memory call = abi.encodeWithSignature(\n \"verifyRestrictions(address,address,uint256,bytes)\",\n address(this),\n _target,\n _value,\n _data\n );\n (bool success, bytes memory response) = _facet.delegatecall(call);\n if (!success) revert AccountFacet__RestrictionsFailure();\n result = uint256(bytes32(response));\n }\n}\n" + }, + "contracts/facets/AccountRecoveryFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibFacetStorage, RecoveryStorage, RecoveryConfig, RecoveryApprovalConfig, ApprovalConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {IAccountRecoveryFacet} from \"./interfaces/IAccountRecoveryFacet.sol\";\n\n/**\n * @title Account Recovery Facet\n * @dev Contract that enables recovery of accounts when owner key is unavailable\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract AccountRecoveryFacet is IAccountRecoveryFacet, Modifiers {\n bytes constant UNINIT_CALL =\n abi.encodeWithSignature(\"uninitializeSigner()\");\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Approve recovery of account as guardian\n * @dev This method can only be called by guardian and guardian inputs the public key of the new owner\n * When the threshold(majority of guardians) passes, it automatically executes account recovery\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function approveAccountRecovery(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + _getApprovalValidationPeriod()\n );\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit RecoveryApproved(\n _recoveryPublicKey,\n msg.sender,\n approvalValidUntil\n );\n if (\n getRecoveryApprovalCountWithTimeValidity(recoveryPublicKeyHash) >=\n LibGuardian.majorityOfGuardians()\n ) _executeRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Revoke recovery of account as guardian\n * @dev This method can only be called by guardian and guardian inputs the public key of the new owner\n When the threshold(majority of guardians) passes, it automatically revokes account recovery when recovery is pending\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function revokeAccountRecoveryApproval(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n if (\n !rs\n .isNewOwnerApproved[recoveryPublicKeyHash][msg.sender].isApproved ||\n !(block.timestamp <\n rs\n .isNewOwnerApproved[recoveryPublicKeyHash][msg.sender]\n .validUntil)\n ) revert AccountRecoveryFacet__NonExistentApproval();\n\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(false, 0);\n emit RecoveryApprovalRevoked(_recoveryPublicKey, msg.sender);\n }\n\n /**\n * @notice Executes recovery with signatures or on-chain pre-approvals\n * @dev This method validates the signatures of guardians or checks the on-chain pre-approved calls to check if the threshold passes\n * When the threshold passes, account recovery is executed and revert otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _guardians Array of guardians address that are approving the recovery of Account\n * @param _signatures Array of signature bytes that signed the approval hash\n */\n function executeRecovery(\n bytes calldata _recoveryPublicKey,\n address[] calldata _guardians,\n bytes[] calldata _signatures\n ) external override {\n if (_isRecoveryPending())\n revert AccountRecoveryFacet__RecoveryAlreadyOngoing();\n if (_guardians.length != _signatures.length)\n revert AccountRecoveryFacet__InvalidArrayLength();\n validateNewOwner(_recoveryPublicKey);\n\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n\n _checkApprover(_guardians);\n _checkDuplicateOnChainApprover(recoveryPublicKeyHash, _guardians);\n\n if (\n _guardians.length +\n getRecoveryApprovalCountWithTimeValidity(\n recoveryPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians()\n ) revert AccountRecoveryFacet__InsufficientGuardians();\n for (uint256 i; i < _guardians.length; ) {\n if (!LibGuardian.isGuardian(_guardians[i]))\n revert AccountRecoveryFacet__InvalidGuardian();\n if (\n !SignatureChecker.isValidSignatureNow(\n _guardians[i],\n recoveryPublicKeyHash,\n _signatures[i]\n )\n ) revert AccountRecoveryFacet__InvalidGuardianSignature();\n unchecked {\n ++i;\n }\n }\n _executeRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Executes recovery of the account. Note that execution and finalization is a different process\n * @dev Executes the recovery and adds recovery data to recovery configuration. Locks the account\n * @param _recoveryPublicKey Public Key of the account for recovery\n */\n function _executeRecovery(bytes memory _recoveryPublicKey) internal {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n ++rs.nonce;\n uint64 executeAfter = uint64(block.timestamp + _getRecoveryPeriod());\n rs.recoveryConfigs[INNER_STRUCT] = RecoveryConfig(\n _recoveryPublicKey,\n executeAfter // NOTE: Remove guardian Count\n );\n LibAppStorage.setLock(\n block.timestamp + _getLockPeriod(),\n AccountRecoveryFacet.executeRecovery.selector\n );\n emit RecoveryExecuted(_recoveryPublicKey, executeAfter);\n }\n\n /**\n * @notice Finalize recovery after recovery pending period. Recovery pending period can be set by user beforehand in SecurityManager\n * @dev This method finalizes recovery and fully changes the ownership of the account to the newly inputted recovery public key\n */\n function finalizeRecovery() external override {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n if (\n uint64(block.timestamp) <=\n rs.recoveryConfigs[INNER_STRUCT].executeAfter\n ) revert AccountRecoveryFacet__RecoveryPeriodNotOver();\n bytes memory recoveryOwner = rs\n .recoveryConfigs[INNER_STRUCT]\n .recoveryPublicKey;\n\n delete rs.recoveryConfigs[INNER_STRUCT];\n\n LibAppStorage.setLock(0, bytes4(0));\n\n LibAppStorage.initiateSignerMigration();\n address verificationFacet = address(\n bytes20(\n LibDiamond.diamondStorage().facets[\n s.validateOwnerSignatureSelector\n ]\n )\n );\n (bool success, bytes memory result) = verificationFacet.delegatecall(\n UNINIT_CALL\n );\n if (!success) revert AccountRecoveryFacet__CallNotSuccesful();\n uint256 validationData = uint256(bytes32(result));\n if (validationData != 1)\n revert AccountRecoveryFacet__SignerUninitializationFailure();\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n recoveryOwner\n );\n (success, result) = verificationFacet.delegatecall(initCall);\n if (!success) revert AccountRecoveryFacet__CallNotSuccesful();\n validationData = uint256(bytes32(result));\n if (validationData != 1)\n revert AccountRecoveryFacet__SignerInitializationFailure();\n LibAppStorage.finalizeSignerMigration();\n emit RecoveryFinalized(recoveryOwner);\n }\n\n /**\n * @notice Approves the cancellation of recovery\n * @dev This method approves the cancellation of recovery when recovery is still pending - waiting for finalization\n * @param _recoveryPublicKey Bytes of public key which is pending for recovery\n */\n function approveCancelRecovery(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"CancelRecovery\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + _getApprovalValidationPeriod()\n );\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit RecoveryCancellationApproved(_recoveryPublicKey, msg.sender);\n if (\n getRecoveryApprovalCountWithTimeValidity(recoveryPublicKeyHash) >=\n LibGuardian.majorityOfGuardians()\n ) {\n _cancelRecovery(_recoveryPublicKey);\n }\n }\n\n /**\n * @notice Hardstops an ongoing recovery\n * @dev This method provides a safety mechanism to protect owners of malicious guardians.\n * Owners can hardstop recovery when an malicious guardians starts the recovery process.\n * @param _signature Signature of the owner that signs the hash to hardstop recovery\n */\n function hardstopRecovery(bytes calldata _signature) external override {\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n \"0\",\n \"HardstopRecovery\"\n );\n if (\n !SignatureChecker.isValidSignatureNow(\n address(this),\n recoveryPublicKeyHash,\n _signature\n )\n ) revert AccountRecoveryFacet__InvalidOwnerSignature();\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n ++rs.nonce;\n delete rs.recoveryConfigs[INNER_STRUCT];\n LibAppStorage.setLock(0, bytes4(0));\n emit RecoveryHardstopped();\n }\n\n /**\n * @notice Cancels recovery with signatures or on-chain pre-approvals\n * @dev This method validates the signatures of guardians or checks the on-chain pre-approved calls to check if the threshold passes\n * When the threshold passes, account recovery is canceled and revert otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _guardians Array of guardians address that are approving the recovery of Account\n * @param _signatures Array of signature bytes that signed the cancellation approval hash\n */\n function cancelRecovery(\n bytes calldata _recoveryPublicKey,\n address[] calldata _guardians,\n bytes[] calldata _signatures\n ) external override {\n if (_guardians.length != _signatures.length)\n revert AccountRecoveryFacet__InvalidArrayLength();\n validateNewOwner(_recoveryPublicKey);\n\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"CancelRecovery\"\n );\n\n _checkApprover(_guardians);\n _checkDuplicateOnChainApprover(recoveryPublicKeyHash, _guardians);\n\n if (\n _guardians.length +\n getRecoveryApprovalCountWithTimeValidity(\n recoveryPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians()\n ) revert AccountRecoveryFacet__InsufficientGuardians();\n for (uint256 i; i < _guardians.length; ) {\n if (!LibGuardian.isGuardian(_guardians[i]))\n revert AccountRecoveryFacet__CallerNotGuardian();\n if (\n !SignatureChecker.isValidSignatureNow(\n _guardians[i],\n recoveryPublicKeyHash,\n _signatures[i]\n )\n ) revert AccountRecoveryFacet__InvalidGuardianSignature();\n unchecked {\n ++i;\n }\n }\n _cancelRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Cancel recovery when the recovery is pending. Unlock the account as well\n * @dev This method checks if the recovery is pending and reverts if not pending.\n * It increases the recovery nonce and deletes the recovery information and gets a small portion of gas in return\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function _cancelRecovery(bytes memory _recoveryPublicKey) internal {\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n LibAppStorage.setLock(0, bytes4(0));\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n ++rs.nonce;\n delete rs.recoveryConfigs[INNER_STRUCT];\n emit RecoveryCanceled(_recoveryPublicKey);\n }\n\n /**\n * @notice Validates the format of public key to be used for recovery\n * @dev This method checks if the public key format is correct and reverts otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function validateNewOwner(bytes memory _recoveryPublicKey) public view {\n if (\n !IVerificationFacet(\n LibLoupe.facetAddress(s.validateOwnerSignatureSelector)\n ).isValidKeyType(_recoveryPublicKey)\n ) revert AccountRecoveryFacet__InvalidRecoveryPublicKey();\n }\n\n /**\n * @notice Checks if recovery is currently pending\n * @return isPending Boolean indicating if recovery is pending\n */\n function _isRecoveryPending() internal view returns (bool isPending) {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n isPending = (rs.recoveryConfigs[INNER_STRUCT].executeAfter > 0);\n }\n\n /**\n * @notice Calculate the recovery hash dependent on chain, wallet address, nonce with EIP-191 prefix for safety\n * @dev Returns the keccak256 hash of EIP-191 msg hash packed with public key, salt, nonce, wallet address, etc\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _saltString Salt string to uniquely identify each recovery hash and for security\n * @return recoveryKeyHash Bytes32 string of the recovery hash\n */\n function getApprovalRecoveryKeyHash(\n bytes memory _recoveryPublicKey,\n string memory _saltString\n ) public view override returns (bytes32 recoveryKeyHash) {\n recoveryKeyHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n _recoveryPublicKey,\n _saltString,\n address(this),\n block.chainid,\n LibFacetStorage.recoveryStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Check the onchain approval of guardians and returns the number of guardians that approved\n * @dev Loop through the guardian addresses and returns the number of guardians that approved this recovery hash\n * @param _recoveryPublicKeyHash Bytes hash of newly recovered public key and recovery value of the account\n * @return approvalCount Number of guardians that approved\n */\n function getRecoveryApprovalCountWithTimeValidity(\n bytes32 _recoveryPublicKeyHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n for (uint256 i; i < guardianLength; ) {\n if (isRecoveryApproved(_recoveryPublicKeyHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Checks if the recovery is approved by the given approver\n * @param _recoveryPublicKeyHash Hash of the public key and configuration for recovery\n * @param _approver Address of approver\n * @return isApproved Bool value if recovery hash is approved\n */\n function isRecoveryApproved(\n bytes32 _recoveryPublicKeyHash,\n address _approver\n ) public view override returns (bool isApproved) {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n if (\n rs\n .isNewOwnerApproved[_recoveryPublicKeyHash][_approver].isApproved &&\n block.timestamp <\n rs.isNewOwnerApproved[_recoveryPublicKeyHash][_approver].validUntil\n ) {\n isApproved = true;\n }\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _recoveryPublicKeyHash Hash of recovery information\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _recoveryPublicKeyHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isRecoveryApproved(_recoveryPublicKeyHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert AccountRecoveryFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the lock period of this wallet address from security manager\n * @return lockPeriod value of lock period\n */\n function _getLockPeriod() internal view returns (uint256 lockPeriod) {\n lockPeriod = securityManager.lockPeriodOf(address(this));\n if (lockPeriod == 0) revert AccountRecoveryFacet__InvalidLockPeriod();\n }\n\n /**\n * @notice Returns the lock period of this wallet address from security manager\n * @return recoveryPeriod value of recovery period\n */\n function _getRecoveryPeriod()\n internal\n view\n returns (uint256 recoveryPeriod)\n {\n recoveryPeriod = securityManager.recoveryPeriodOf(address(this));\n if (recoveryPeriod == 0)\n revert AccountRecoveryFacet__InvalidRecoveryPeriod();\n }\n\n /**\n * @notice Returns the approval validation period of this wallet address from security manager\n * @return approvalValidationPeriod value of approval validation period\n */\n function _getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod == 0)\n revert AccountRecoveryFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the recovery nonce of this wallet address from security manager\n * @return nonce value of recovery nonce\n */\n function getRecoveryNonce() public view override returns (uint128 nonce) {\n nonce = LibFacetStorage.recoveryStorage().nonce;\n }\n\n /**\n * @notice Returns the recovery information of the pending recovery\n * @return recoveryConfig value struct of pending recovery\n */\n function getPendingRecovery()\n public\n view\n override\n returns (RecoveryConfig memory recoveryConfig)\n {\n recoveryConfig = LibFacetStorage.recoveryStorage().recoveryConfigs[\n INNER_STRUCT\n ];\n }\n}\n" + }, + "contracts/facets/base/DiamondCutFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibGuardian} from \"../../libraries/LibGuardian.sol\";\nimport {ISecurityManager} from \"../../infrastructure/interfaces/ISecurityManager.sol\";\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibFacetStorage, DiamondCutApprovalConfig, ApprovalConfig} from \"../../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"../Modifiers.sol\";\nimport {IDiamondCut} from \"./interfaces/IDiamondCut.sol\";\n\n/**\n * @title DiamondCut Facet\n * @dev Responsible for adding/removing/replace facets in Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DiamondCutFacet is Modifiers, IDiamondCut {\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Updates the flag for the interfaceId\n * @param _interfaceId InterfaceID to update the mapping\n * @param _flag Bool value to update the mapping of the given interface ID\n */\n function updateSupportsInterface(\n bytes4 _interfaceId,\n bool _flag\n ) external override onlyWhenUnlocked {\n LibDiamond.enforceIsSelf();\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId] = _flag;\n emit SupportsInterfaceUpdated(_interfaceId, _flag);\n }\n\n /**\n * @notice Add/replace/remove any number of functions and optionally execute\n * a function with delegatecall when guardians don't exist\n * @param _diamondCut Contains the facet addresses and function selectors\n * @param _init The address of the contract or facet to execute _calldata. It's prohibited in Barz\n */\n function diamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata\n ) external override onlyWhenUnlocked {\n LibDiamond.enforceIsSelf();\n\n _checkFacetCutValidity(_diamondCut);\n // require approval from guardian if guardian exists\n if (0 != LibGuardian.guardianCount())\n revert DiamondCutFacet__InvalidRouteWithGuardian();\n if (address(0) != _init) revert DiamondCutFacet__InvalidInitAddress();\n\n ++LibFacetStorage.diamondCutStorage().nonce;\n LibDiamond.diamondCut(_diamondCut, address(0), \"\");\n }\n\n /**\n * @notice Add/replace/remove any number of functions and optionally execute\n * a function with delegatecall when guardians exist\n * @param _diamondCut Contains the facet addresses and function selectors\n * @param _approvers Guardian or owner address that approves the diamond cut\n * @param _signatures Signature of Guardians or owner that approves the diamond cut\n */\n function diamondCutWithGuardian(\n FacetCut[] calldata _diamondCut,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n ) external override onlyWhenUnlocked {\n if (_approvers.length != _signatures.length)\n revert DiamondCutFacet__InvalidArrayLength();\n _checkFacetCutValidity(_diamondCut);\n if (0 == LibGuardian.guardianCount())\n revert DiamondCutFacet__InvalidRouteWithGuardian();\n\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(cutHash, _approvers);\n\n bool onChainOwnerApproval = getOwnerCutApprovalWithTimeValidity(\n cutHash\n );\n\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n if (\n _approvers.length +\n getDiamondCutApprovalCountWithTimeValidity(cutHash) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert DiamondCutFacet__InsufficientApprovers();\n\n bool ownerApproved;\n for (uint256 i; i < _approvers.length; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n _approvers[i] != address(this)\n ) revert DiamondCutFacet__InvalidApprover();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert DiamondCutFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n cutHash,\n _signatures[i]\n )\n ) revert DiamondCutFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n if (!ownerApproved && !onChainOwnerApproval)\n revert DiamondCutFacet__LackOfOwnerApproval();\n\n ++LibFacetStorage.diamondCutStorage().nonce;\n LibDiamond.diamondCut(_diamondCut, address(0), \"\");\n }\n\n /**\n * @notice Approves diamond cut. This can only be called directly from guardian or owner\n * @param _diamondCut Contains the facet addresses and function selectors\n */\n function approveDiamondCut(\n FacetCut[] calldata _diamondCut\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\n if (LibGuardian.guardianCount() == 0)\n revert DiamondCutFacet__InvalidRouteWithoutGuardian();\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n _checkFacetCutValidity(_diamondCut);\n\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(\n true,\n approvalValidUntil\n );\n emit DiamondCutApproved(_diamondCut);\n if (\n (getDiamondCutApprovalCountWithTimeValidity(cutHash) >=\n LibGuardian.majorityOfGuardians()) &&\n getOwnerCutApprovalWithTimeValidity(cutHash)\n ) {\n ++LibFacetStorage.diamondCutStorage().nonce;\n LibDiamond.diamondCut(_diamondCut, address(0), \"\");\n }\n }\n\n /**\n * @notice Revokes the approval of diamond cut. This can only be called directly from guardian or owner\n * @param _diamondCut Contains the facet addresses and function selectors\n */\n function revokeDiamondCutApproval(\n FacetCut[] calldata _diamondCut\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\n if (!ds.isDiamondCutApproved[cutHash][msg.sender].isApproved)\n revert DiamondCutFacet__CannotRevokeUnapproved();\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(false, 0);\n emit DiamondCutApprovalRevoked(_diamondCut);\n }\n\n /**\n * @notice Gets the number of approvals of diamond cut from guardians\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n */\n function getDiamondCutApprovalCountWithTimeValidity(\n bytes32 _diamondCutHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardiansLength = guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n if (isCutApproved(_diamondCutHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n return approvalCount;\n }\n\n /**\n * @notice Returns if the owner has approved the diamond cut\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @return isApprovedByOwner Bool value showing if the owner approved the cut\n */\n function getOwnerCutApprovalWithTimeValidity(\n bytes32 _diamondCutHash\n ) public view override returns (bool isApprovedByOwner) {\n isApprovedByOwner = isCutApproved(_diamondCutHash, address(this));\n }\n\n /**\n * @notice Returns if the given approver has approved the diamond cut\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @param _approver Address of approver\n * @return isApproved Bool value showing if the approver approved the cut\n */\n function isCutApproved(\n bytes32 _diamondCutHash,\n address _approver\n ) public view override returns (bool isApproved) {\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n isApproved = (ds\n .isDiamondCutApproved[_diamondCutHash][_approver].isApproved &&\n block.timestamp <\n ds.isDiamondCutApproved[_diamondCutHash][_approver].validUntil);\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _diamondCutHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isCutApproved(_diamondCutHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert DiamondCutFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the diamond cut hash. This function ensures that this hash is safe from replay attack by including\n * salt, address, chainId, and nonce, etc.\n * @param _diamondCut Contains the facet addresses and function selectors\n * @return cutHash Diamond Cut Hash\n */\n function getDiamondCutHash(\n FacetCut[] calldata _diamondCut\n ) public view override returns (bytes32 cutHash) {\n cutHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n keccak256(abi.encode(_diamondCut)),\n address(this),\n block.chainid,\n LibFacetStorage.diamondCutStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Returns the approval validation Period\n * @dev This method fetches the validation period from the security manager\n * @return approvalValidationPeriod Approval validation period of Barz contract fetched from security manager\n */\n function getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod <= 0)\n revert DiamondCutFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the diamond cut nonce of this wallet\n * @dev This method fetches the nonce from diamond cut storage\n * @return cutNonce Nonce of diamond cut to protect from reply attacks\n */\n function getDiamondCutNonce()\n public\n view\n override\n returns (uint128 cutNonce)\n {\n cutNonce = LibFacetStorage.diamondCutStorage().nonce;\n }\n}\n" + }, + "contracts/facets/base/DiamondLoupeFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {IERC165} from \"../../interfaces/ERC/IERC165.sol\";\nimport {IERC1271} from \"../../interfaces/ERC/IERC1271.sol\";\nimport {IERC677Receiver} from \"../../interfaces/ERC/IERC677Receiver.sol\";\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC1155Receiver} from \"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\";\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../../libraries/LibLoupe.sol\";\nimport {LibUtils} from \"../../libraries/LibUtils.sol\";\nimport {IDiamondCut} from \"../../facets/base/interfaces/IDiamondCut.sol\";\nimport {IStorageLoupe} from \"./interfaces/IStorageLoupe.sol\";\nimport {IDiamondLoupe} from \"./interfaces/IDiamondLoupe.sol\";\n\n/**\n * @title DiamondLoupe Facet\n * @dev DiamondLoupe contract compatible with EIP-2535\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DiamondLoupeFacet is IDiamondLoupe, IStorageLoupe, IERC165 {\n // Diamond Loupe Functions\n ////////////////////////////////////////////////////////////////////\n /// These functions are expected to be called frequently by tools off-chain.\n\n /**\n * @notice Gets all facets and their selectors.\n * @dev Barz uses a special architecture called default fallback handler. Default Fallback handler is used as a middleware\n * that holds the mapping of facet function selector and facet address that Barz uses. This helps Barz to reduce\n * significant amount of gas during the initialization process.\n * Hence, this method aggregates both the facet information from DefaulFallbackHandler and in diamond storage and shows the data to users.\n * @return facets_ Facet\n */\n function facets() public view override returns (Facet[] memory facets_) {\n Facet[] memory defaultFacet = LibDiamond\n .diamondStorage()\n .defaultFallbackHandler\n .facets();\n Facet[] memory _facets = LibLoupe.facets();\n uint256 numFacets = _facets.length;\n bytes4[] memory keys;\n address[] memory values;\n for (uint256 i; i < numFacets; ) {\n uint256 selectorsLength = _facets[i].functionSelectors.length;\n for (uint256 j; j < selectorsLength; ) {\n (keys, values) = LibUtils.setValue(\n keys,\n values,\n _facets[i].functionSelectors[j],\n _facets[i].facetAddress\n );\n unchecked {\n ++j;\n }\n }\n unchecked {\n ++i;\n }\n }\n {\n bool iIncrement;\n for (uint256 i; i < defaultFacet.length; ) {\n bool jIncrement;\n for (\n uint256 j;\n j < defaultFacet[i].functionSelectors.length;\n\n ) {\n if (\n LibUtils.getValue(\n keys,\n values,\n defaultFacet[i].functionSelectors[j]\n ) != address(0)\n ) {\n if (defaultFacet[i].functionSelectors.length == 1) {\n defaultFacet = LibUtils.removeFacetElement(\n defaultFacet,\n i\n );\n iIncrement = true;\n break;\n }\n defaultFacet[i].functionSelectors = LibUtils\n .removeElement(\n defaultFacet[i].functionSelectors,\n j\n );\n jIncrement = true;\n }\n if (!jIncrement) {\n unchecked {\n ++j;\n }\n } else {\n jIncrement = false;\n }\n }\n if (!iIncrement) {\n unchecked {\n ++i;\n }\n } else {\n iIncrement = false;\n }\n }\n }\n {\n uint256 facetLength = numFacets + defaultFacet.length;\n facets_ = new Facet[](facetLength);\n uint256 defaultFacetIndex;\n for (uint256 i; i < facetLength; ) {\n if (i < numFacets) {\n facets_[i] = _facets[i];\n bool jIncrementor;\n for (uint256 j; j < defaultFacet.length; ) {\n if (\n facets_[i].facetAddress ==\n defaultFacet[j].facetAddress\n ) {\n facets_[i].functionSelectors = LibUtils.mergeArrays(\n _facets[i].functionSelectors,\n defaultFacet[j].functionSelectors\n );\n defaultFacet = LibUtils.removeFacetElement(\n defaultFacet,\n j\n );\n jIncrementor = true;\n {\n facets_ = LibUtils.removeFacetElement(\n facets_,\n facets_.length - 1\n );\n }\n --facetLength;\n }\n if (!jIncrementor) {\n unchecked {\n ++j;\n }\n } else {\n jIncrementor = false;\n }\n }\n } else {\n facets_[i] = defaultFacet[defaultFacetIndex];\n ++defaultFacetIndex;\n }\n unchecked {\n ++i;\n }\n }\n }\n }\n\n /**\n * @notice Gets all the function selectors provided by a facet.\n * @param _facet The facet address.\n * @return facetFunctionSelectors_\n */\n function facetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n Facet[] memory facet = facets();\n uint256 facetLength = facet.length;\n for (uint256 i; i < facetLength; ) {\n if (facet[i].facetAddress == _facet)\n return facet[i].functionSelectors;\n unchecked {\n ++i;\n }\n }\n return facetFunctionSelectors_;\n }\n\n /**\n * @notice Get all the facet addresses used by Barz.\n * @return facetAddresses_\n */\n function facetAddresses()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n Facet[] memory facet = facets();\n uint256 facetLength = facet.length;\n facetAddresses_ = new address[](facetLength);\n for (uint256 i; i < facetLength; ) {\n facetAddresses_[i] = facet[i].facetAddress;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Gets the facet that supports the given selector.\n * @dev If facet is not found return address(0).\n * @param _functionSelector The function selector.\n * @return facetAddress_ The facet address.\n */\n function facetAddress(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n\n facetAddress_ = address(bytes20(ds.facets[_functionSelector]));\n if (facetAddress_ == address(0)) {\n facetAddress_ = IDiamondLoupe(ds.defaultFallbackHandler)\n .facetAddress(_functionSelector);\n }\n }\n\n /**\n * @notice SupportInterface to be compatible with EIP 165\n * @param _interfaceId Interface ID for detecting the interface\n * @return isSupported Bool value showing if the standard is supported in the contract\n */\n function supportsInterface(\n bytes4 _interfaceId\n ) external view override returns (bool isSupported) {\n isSupported =\n _interfaceId == type(IERC165).interfaceId ||\n _interfaceId == IDiamondCut.diamondCut.selector ||\n _interfaceId == type(IDiamondLoupe).interfaceId ||\n _interfaceId == type(IERC1155Receiver).interfaceId ||\n _interfaceId == type(IERC721Receiver).interfaceId ||\n _interfaceId == type(IERC777Recipient).interfaceId ||\n _interfaceId == IERC1271.isValidSignature.selector ||\n _interfaceId == type(IERC677Receiver).interfaceId ||\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId];\n }\n\n /**\n * @notice Returns the facet from the diamond storage. This excludes the facets from the default fallback handler\n * @return facets_ Facet information attached directly to diamond storage\n */\n function facetsFromStorage()\n external\n view\n override\n returns (Facet[] memory facets_)\n {\n facets_ = LibLoupe.facets();\n }\n\n /**\n * @notice Returns the facet address attached to the given function selector. This excludes the facets from the default fallback handler\n * @param _functionSelector Function selector to fetch the facet address from diamond storage\n * @return facetAddress_ Facet address mapped with the function selector\n */\n function facetAddressFromStorage(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n facetAddress_ = LibLoupe.facetAddress(_functionSelector);\n }\n\n /**\n * @notice Returns all facet addresses attached directly to diamond storage. This excludes the facets from the default fallback handler\n * @return facetAddresses_ All facet addresses attached directly to diamond storage\n */\n function facetAddressesFromStorage()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n facetAddresses_ = LibLoupe.facetAddresses();\n }\n\n /**\n * @notice Returns function selectors of given facet address attached directly to diamond storage. This excludes the facets from the default fallback handler\n * @param _facet Facet address to fetch the facet function selectors from diamond storage\n * @return facetFunctionSelectors_ Facet function selectors of the given facet address\n */\n function facetFunctionSelectorsFromStorage(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n facetFunctionSelectors_ = LibLoupe.facetFunctionSelectors(_facet);\n }\n}\n" + }, + "contracts/facets/base/interfaces/IDiamondCut.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title DiamondCut Facet Interface\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IDiamondCut {\n error DiamondCutFacet__InvalidRouteWithGuardian();\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\n error DiamondCutFacet__InvalidArrayLength();\n error DiamondCutFacet__InsufficientApprovers();\n error DiamondCutFacet__InvalidApprover();\n error DiamondCutFacet__InvalidApproverSignature();\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\n error DiamondCutFacet__CannotRevokeUnapproved();\n error DiamondCutFacet__LackOfOwnerApproval();\n error DiamondCutFacet__OwnerAlreadyApproved();\n error DiamondCutFacet__DuplicateApproval();\n error DiamondCutFacet__InvalidInitAddress();\n\n event DiamondCutApproved(FacetCut[] diamondCut);\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\n\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\n\n enum FacetCutAction {\n Add,\n Replace,\n Remove\n }\n // Add=0, Replace=1, Remove=2\n\n struct FacetCut {\n address facetAddress;\n FacetCutAction action;\n bytes4[] functionSelectors;\n }\n\n /// @notice Add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param diamondCut Contains the facet addresses and function selectors\n /// @param init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function diamondCut(\n FacetCut[] calldata diamondCut,\n address init,\n bytes calldata _calldata\n ) external;\n\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\n\n function diamondCutWithGuardian(\n FacetCut[] calldata diamondCut,\n address[] calldata approvers,\n bytes[] calldata signatures\n ) external;\n\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\n\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\n\n function getDiamondCutApprovalCountWithTimeValidity(\n bytes32 diamondCutHash\n ) external view returns (uint256);\n\n function getOwnerCutApprovalWithTimeValidity(\n bytes32 diamondCutHash\n ) external view returns (bool);\n\n function isCutApproved(\n bytes32 diamondCutHash,\n address approver\n ) external view returns (bool);\n\n function getDiamondCutHash(\n FacetCut[] calldata diamondCut\n ) external view returns (bytes32);\n\n function getDiamondCutNonce() external view returns (uint128);\n}\n" + }, + "contracts/facets/base/interfaces/IDiamondLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n// A loupe is a small magnifying glass used to look at diamonds.\n// These functions look at diamonds\ninterface IDiamondLoupe {\n /// These functions are expected to be called frequently\n /// by tools.\n\n struct Facet {\n address facetAddress;\n bytes4[] functionSelectors;\n }\n\n /// @notice Gets all facet addresses and their four byte function selectors.\n /// @return facets_ Facet\n function facets() external view returns (Facet[] memory facets_);\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n /// @return facetFunctionSelectors_\n function facetFunctionSelectors(\n address _facet\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses()\n external\n view\n returns (address[] memory facetAddresses_);\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(\n bytes4 _functionSelector\n ) external view returns (address facetAddress_);\n}\n" + }, + "contracts/facets/base/interfaces/IStorageLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"./IDiamondLoupe.sol\";\n\n/**\n * @title LoupeFromStorage Interface\n * @dev Interface contract to function as a loupe facet directly attached to diamond storage of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IStorageLoupe {\n /// These functions are expected to be called frequently\n /// by tools.\n\n /// @notice Gets all facet addresses and their four byte function selectors.\n /// @return facets_ Facet\n function facetsFromStorage()\n external\n view\n returns (IDiamondLoupe.Facet[] memory);\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n function facetFunctionSelectorsFromStorage(\n address _facet\n ) external view returns (bytes4[] memory);\n\n /// @notice Get all the facet addresses used by a diamond.\n function facetAddressesFromStorage()\n external\n view\n returns (address[] memory);\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n function facetAddressFromStorage(\n bytes4 _functionSelector\n ) external view returns (address);\n}\n" + }, + "contracts/facets/GuardianFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibFacetStorage, GuardianStorage, StorageConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IGuardianFacet} from \"./interfaces/IGuardianFacet.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Guardian Facet\n * @dev Contract that enables addition/removal of guardians from Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract GuardianFacet is IGuardianFacet {\n ISecurityManager public immutable securityManager;\n uint8 public constant INNER_STRUCT = 0;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Add guardians to Barz.\n * @dev This method internally calls addGuardian which checks the validity of guardian address and adds\n * as guardian if valid\n * @param _guardians Array of addresses to add as guardian\n */\n function addGuardians(address[] calldata _guardians) external override {\n LibDiamond.enforceIsSelf();\n for (uint256 i; i < _guardians.length; ) {\n addGuardian(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Add a guardian to Barz.\n * @dev This method checks if the function is called by the owner and validates the address of guardian\n * When the validation passes, guardian address is added to the pending state waiting for confirmation\n * @param _guardian Address to add as guardian\n */\n function addGuardian(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (_guardian == address(this))\n revert GuardianFacet__GuardianCannotBeSelf();\n if (isGuardian(_guardian)) revert GuardianFacet__DuplicateGuardian();\n if (_guardian == address(0))\n revert GuardianFacet__ZeroAddressGuardian();\n if (\n keccak256(abi.encodePacked(_guardian)) ==\n keccak256(IVerificationFacet(address(this)).owner())\n ) revert GuardianFacet__OwnerCannotBeGuardian();\n\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n if (\n gs.pending[id] != 0 ||\n block.timestamp <= gs.pending[id] + getSecurityWindow()\n ) revert GuardianFacet__DuplicateGuardianAddition();\n\n uint256 securityPeriod = getAdditionSecurityPeriod();\n gs.pending[id] = block.timestamp + securityPeriod;\n emit GuardianAdditionRequested(\n _guardian,\n block.timestamp + securityPeriod\n );\n }\n\n /**\n * @notice Remove guardians from Barz.\n * @dev This method internally calls removeGuardian which checks the validity of guardian and removes\n * guardian when the request is valid\n * @param _guardians Array of addresses to be removed\n */\n function removeGuardians(address[] calldata _guardians) external override {\n LibDiamond.enforceIsSelf();\n for (uint256 i; i < _guardians.length; ) {\n removeGuardian(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Remove a guardian from Barz.\n * @dev This method validates if the guardian to be removed is a guardian and puts the guardian removal\n * to a pending state waiting to be confirmed.\n * @param _guardian Address of guardian to be removed\n */\n function removeGuardian(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n if (!isGuardian(_guardian)) revert GuardianFacet__NonExistentGuardian();\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n if (\n gs.pending[id] != 0 ||\n block.timestamp <= gs.pending[id] + getSecurityWindow()\n ) revert GuardianFacet__DuplicateGuardianRemoval();\n\n uint256 securityPeriod = getRemovalSecurityPeriod();\n gs.pending[id] = block.timestamp + securityPeriod;\n emit GuardianRemovalRequested(\n _guardian,\n block.timestamp + securityPeriod\n );\n }\n\n /**\n * @notice Confirm addition of guardians\n * @dev This method internally calls confirmGuardianAddition which checks the validity of pending request.\n * Guardians are fully added when they pass the validation. Anyone can call this function.\n * @param _guardians Array of guardian addresses to be added\n */\n function confirmGuardianAdditions(\n address[] calldata _guardians\n ) external override {\n for (uint256 i; i < _guardians.length; ) {\n confirmGuardianAddition(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Confirm addition of a guardian\n * @dev This method checks the validity of pending request.\n * Guardians are fully added when they pass the validation. Anyone can call this function.\n * @param _guardian Guardian address to be added\n */\n function confirmGuardianAddition(address _guardian) public override {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingAddition();\n if (gs.pending[id] >= block.timestamp)\n revert GuardianFacet__PendingAdditionNotOver();\n if (block.timestamp >= gs.pending[id] + getSecurityWindow())\n revert GuardianFacet__PendingAdditionExpired();\n\n _addGuardian(_guardian);\n\n delete gs.pending[id];\n emit GuardianAdded(_guardian);\n }\n\n /**\n * @notice Confirm removal of guardians\n * @dev This method internally calls confirmGuardianRemoval to check the validity guardian removal confirmation.\n * Guardians are fully removed when they pass the validation. Anyone can call this function.\n * @param _guardians Array of guardian addresses to be removed\n */\n function confirmGuardianRemovals(\n address[] calldata _guardians\n ) external override {\n for (uint256 i; i < _guardians.length; ) {\n confirmGuardianRemoval(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Confirm removal of a guardian\n * @dev This method checks the validity guardian removal confirmation.\n * Guardian is fully removed when they pass the validation. Anyone can call this function.\n * @param _guardian Guardian address to be removed\n */\n function confirmGuardianRemoval(address _guardian) public override {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingRemoval();\n if (gs.pending[id] >= block.timestamp)\n revert GuardianFacet__PendingRemovalNotOver();\n if (block.timestamp >= gs.pending[id] + getSecurityWindow())\n revert GuardianFacet__PendingAdditionExpired();\n\n _removeGuardian(_guardian);\n delete gs.pending[id];\n emit GuardianRemoved(_guardian);\n }\n\n /**\n * @notice Cancel pending guardian addition\n * @dev This method checks if the previous request for guardian request exists.\n * It reverts if previous request is not pending and cancels the addition otherwise.\n * @param _guardian Guardian address to be canceled from addition\n */\n function cancelGuardianAddition(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingAddition();\n delete gs.pending[id];\n emit GuardianAdditionCancelled(_guardian);\n }\n\n /**\n * @notice Cancel pending guardian removal\n * @dev This method checks if the previous request for guardian request exists.\n * It reverts if previous request is not pending and cancels the removal otherwise.\n * @param _guardian Guardian address to be canceled from removal\n */\n function cancelGuardianRemoval(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingRemoval();\n delete gs.pending[id];\n emit GuardianRemovalCancelled(_guardian);\n }\n\n /**\n * @notice Get the addition security period of current account from security manager\n * @dev This method returns the uint value if addition security period\n * @return additionSecurityPeriod Uint256 value of addition security period\n */\n function getAdditionSecurityPeriod()\n public\n view\n override\n returns (uint256 additionSecurityPeriod)\n {\n additionSecurityPeriod = securityManager.additionSecurityPeriodOf(\n address(this)\n );\n if (additionSecurityPeriod == 0)\n revert GuardianFacet__InvalidAdditionSecurityPeriod();\n }\n\n /**\n * @notice Get the removal security period of current account from security manager\n * @dev This method returns the uint value if removal security period\n * @return removalSecurityPeriod Uint256 value of removal security period\n */\n function getRemovalSecurityPeriod()\n public\n view\n override\n returns (uint256 removalSecurityPeriod)\n {\n removalSecurityPeriod = securityManager.removalSecurityPeriodOf(\n address(this)\n );\n if (removalSecurityPeriod == 0)\n revert GuardianFacet__InvalidRemovalSecurityPeriod();\n }\n\n /**\n * @notice Get the security window of current account from security manager\n * @dev This method returns the uint value if security window\n * @return securityWindow Uint256 value of removal security period\n */\n function getSecurityWindow()\n public\n view\n override\n returns (uint256 securityWindow)\n {\n securityWindow = securityManager.securityWindowOf(address(this));\n if (securityWindow == 0) revert GuardianFacet__InvalidSecurityWindow();\n }\n\n /**\n * @notice Checks if the addition of the given guardian address is pending\n * @dev This method returns the bool value of whether the guardian address is pending addition\n * @return isPending Bool value of representing the pending of guardian addition\n */\n function isAdditionPending(\n address _guardian\n ) public view override returns (bool isPending) {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n isPending = _isPending(id);\n }\n\n /**\n * @notice Checks if the removal of the given guardian address is pending\n * @dev This method returns the bool value of whether the guardian address is pending removal\n * @return isPending Bool value of representing the pending of guardian removal\n */\n function isRemovalPending(\n address _guardian\n ) public view override returns (bool isPending) {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n isPending = _isPending(id);\n }\n\n /**\n * @notice Checks if the given hash is pending\n * @dev This method returns the bool value whether the hash is pending\n * @return isPending Bool value of representing the pending of guardian operation\n */\n function _isPending(\n bytes32 _idHash\n ) internal view returns (bool isPending) {\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n isPending = ((gs.pending[_idHash] > 0 &&\n gs.pending[_idHash] < block.timestamp) &&\n block.timestamp < gs.pending[_idHash] + getSecurityWindow());\n }\n\n /**\n * @notice Adds guardian to storage config. This is called when guardian is fully added.\n * @dev This method add guardian address and config information to Facet Storage dedicated for guardian\n * When this function is called, guardian is fully added to this Barz Smart Account\n * @param _guardian Address of guardian to be added\n */\n function _addGuardian(address _guardian) internal {\n if (!isAdditionPending(_guardian))\n revert GuardianFacet__InvalidGuardianAddition();\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n if (config.info[_guardian].exists)\n revert GuardianFacet__AlreadyExists();\n\n config.info[_guardian].exists = true;\n config.info[_guardian].index = uint128(config.addresses.length);\n config.addresses.push(_guardian);\n }\n\n /**\n * @notice Removes guardian to storage config. This is called when guardian is fully removed.\n * @dev This method remove guardian address and config information to Facet Storage dedicated for guardian\n * When this function is called, guardian is fully removed from this Barz Smart Account\n * @param _guardian Address of guardian to be removed\n */\n function _removeGuardian(address _guardian) internal {\n if (!isRemovalPending(_guardian))\n revert GuardianFacet__InvalidGuardianRemoval();\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n if (!config.info[_guardian].exists)\n revert GuardianFacet__NonExistentGuardian();\n\n address lastAddress = config.addresses[config.addresses.length - 1];\n if (_guardian != lastAddress) {\n uint128 targetIndex = config.info[_guardian].index;\n config.addresses[targetIndex] = lastAddress;\n config.info[lastAddress].index = targetIndex;\n }\n config.addresses.pop();\n delete config.info[_guardian];\n\n emit GuardianRemoved(_guardian);\n }\n\n /**\n * @notice Reads guardian storage and fetches the addresses into an array from the storage\n * @dev This method fetches the guardian storage and returns the list of guardian addresses\n * @return addresses Array of addresses comprised of guardian\n */\n function getGuardians()\n public\n view\n override\n returns (address[] memory addresses)\n {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n addresses = new address[](config.addresses.length);\n uint256 addressesLen = config.addresses.length;\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the number of majority of guardians\n * @return majorityOfGuardians_ Number of majority of guardians e.g., 2 if 3 guardians / 3 if 5 guardians\n */\n function majorityOfGuardians()\n public\n view\n override\n returns (uint256 majorityOfGuardians_)\n {\n majorityOfGuardians_ = LibGuardian.majorityOfGuardians();\n }\n\n /**\n * @notice Reads guardian storage and fetches the addresses into an array from the storage\n * @dev This method fetches the guardian storage and returns the list of guardian addresses\n * @return guardianNumber Array of guardians in the account\n */\n function guardianCount()\n public\n view\n override\n returns (uint256 guardianNumber)\n {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n guardianNumber = config.addresses.length;\n }\n\n /**\n * @notice Reads guardian storage and checks if the given address is a guardian\n * @return isGuardian_ Bool value representing if the given address is guardian\n */\n function isGuardian(\n address _guardian\n ) public view override returns (bool isGuardian_) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n isGuardian_ = config.info[_guardian].exists;\n }\n\n /**\n * @notice Checks if the guardian number is zero and returns of guardian facet is okay to be removed\n * @return isRemovable Bool value representing if guardian facet is removable\n */\n function isGuardianFacetRemovable()\n external\n view\n override\n returns (bool isRemovable)\n {\n isRemovable = (0 == guardianCount());\n }\n}\n" + }, + "contracts/facets/interfaces/IAccountFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IEntryPoint} from \"../../aa-4337/interfaces/IEntryPoint.sol\";\n\n/**\n * @title Account Facet Interface\n * @dev Interface of module contract that provides the account features and init/unitialization of signer\n * compatible with EIP-1271 & EIP-4337\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IAccountFacet {\n event AccountInitialized(\n IEntryPoint indexed entryPoint,\n bytes indexed ownerPublicKey\n );\n // NOTE: Added Below Event\n event VerificationSuccess(bytes32);\n event VerificationFailure(bytes32);\n\n error AccountFacet__InitializationFailure();\n error AccountFacet__RestrictionsFailure();\n error AccountFacet__NonExistentVerificationFacet();\n error AccountFacet__CallNotSuccessful();\n\n function initialize(\n address verificationFacet,\n address anEntryPoint,\n address facetRegistry,\n address _defaultFallBack,\n bytes calldata _ownerPublicKey\n ) external returns (uint256);\n\n function execute(address dest, uint256 value, bytes calldata func) external;\n\n function executeBatch(\n address[] calldata dest,\n uint256[] calldata value,\n bytes[] calldata func\n ) external;\n}\n" + }, + "contracts/facets/interfaces/IAccountRecoveryFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {RecoveryConfig} from \"../../libraries/LibFacetStorage.sol\";\n\n/**\n * @title Account Recovery Facet Interface\n * @dev Interface of contract that enables recovery of accounts when owner key is unavailable\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IAccountRecoveryFacet {\n event RecoveryExecuted(\n bytes indexed recoveryPublicKey,\n uint64 executeAfter\n );\n event RecoveryFinalized(bytes indexed recoveryPublicKey);\n event RecoveryCanceled(bytes indexed recoveryPublicKey);\n event RecoveryApproved(\n bytes indexed recoveryPublicKey,\n address indexed guardian,\n uint64 validUntil\n );\n event RecoveryApprovalRevoked(\n bytes indexed recoveryPublicKey,\n address indexed guardian\n );\n event RecoveryCancellationApproved(\n bytes indexed recoveryPublicKey,\n address indexed guardian\n );\n event RecoveryHardstopped();\n\n error AccountRecoveryFacet__CallerNotGuardian();\n error AccountRecoveryFacet__InvalidRecoveryPublicKey();\n error AccountRecoveryFacet__SignerInitializationFailure();\n error AccountRecoveryFacet__SignerUninitializationFailure();\n error AccountRecoveryFacet__InvalidArrayLength();\n error AccountRecoveryFacet__InsufficientGuardians();\n error AccountRecoveryFacet__RecoveryAlreadyOngoing();\n error AccountRecoveryFacet__NonexistentRecovery();\n error AccountRecoveryFacet__NonExistentApproval();\n error AccountRecoveryFacet__RecoveryPeriodNotOver();\n error AccountRecoveryFacet__InvalidLockPeriod();\n error AccountRecoveryFacet__InvalidRecoveryPeriod();\n error AccountRecoveryFacet__InvalidApprovalValidationPeriod();\n error AccountRecoveryFacet__InvalidGuardian();\n error AccountRecoveryFacet__InvalidGuardianSignature();\n error AccountRecoveryFacet__InvalidOwnerSignature();\n error AccountRecoveryFacet__CallNotSuccesful();\n error AccountRecoveryFacet__DuplicateApproval();\n\n function approveAccountRecovery(bytes calldata recoveryPublicKey) external;\n\n function revokeAccountRecoveryApproval(\n bytes calldata recoveryPublicKey\n ) external;\n\n function executeRecovery(\n bytes calldata recoveryPublicKey,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function finalizeRecovery() external;\n\n function approveCancelRecovery(bytes calldata recoveryPublicKey) external;\n\n function cancelRecovery(\n bytes calldata recoveryPublicKey,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function hardstopRecovery(bytes calldata signature) external;\n\n function getApprovalRecoveryKeyHash(\n bytes memory recoveryPublicKey,\n string memory saltString\n ) external view returns (bytes32);\n\n function getRecoveryApprovalCountWithTimeValidity(\n bytes32 recoveryPublicKeyHash\n ) external view returns (uint256);\n\n function isRecoveryApproved(\n bytes32 recoveryPublicKeyHash,\n address approver\n ) external view returns (bool);\n\n function getRecoveryNonce() external view returns (uint128);\n\n function getPendingRecovery() external view returns (RecoveryConfig memory);\n}\n" + }, + "contracts/facets/interfaces/IGuardianFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Guardian Facet Interface\n * @dev Interface of guaridna contract that enables addition/removal of guardians from Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IGuardianFacet {\n event GuardianAdditionRequested(\n address indexed guardian,\n uint256 executeAfter\n );\n event GuardianRemovalRequested(\n address indexed guardian,\n uint256 executeAfter\n );\n event GuardianAdditionCancelled(address indexed guardian);\n event GuardianRemovalCancelled(address indexed guardian);\n event GuardianAdded(address indexed guardian);\n event GuardianRemoved(address indexed guardian);\n\n error GuardianFacet__GuardianCannotBeSelf();\n error GuardianFacet__DuplicateGuardian();\n error GuardianFacet__OwnerCannotBeGuardian();\n error GuardianFacet__DuplicateGuardianAddition();\n error GuardianFacet__DuplicateGuardianRemoval();\n error GuardianFacet__UnknownPendingAddition();\n error GuardianFacet__PendingAdditionNotOver();\n error GuardianFacet__UnknownPendingRemoval();\n error GuardianFacet__PendingRemovalNotOver();\n error GuardianFacet__PendingAdditionExpired();\n error GuardianFacet__InvalidAdditionSecurityPeriod();\n error GuardianFacet__InvalidRemovalSecurityPeriod();\n error GuardianFacet__InvalidSecurityWindow();\n error GuardianFacet__NonExistentGuardian();\n error GuardianFacet__AlreadyExists();\n error GuardianFacet__InvalidGuardianAddition();\n error GuardianFacet__InvalidGuardianRemoval();\n error GuardianFacet__ZeroAddressGuardian();\n\n function addGuardian(address guardian) external;\n\n function addGuardians(address[] calldata guardians) external;\n\n function removeGuardian(address guardian) external;\n\n function removeGuardians(address[] calldata guardians) external;\n\n function confirmGuardianAddition(address guardian) external;\n\n function confirmGuardianAdditions(address[] calldata guardian) external;\n\n function confirmGuardianRemoval(address guardian) external;\n\n function confirmGuardianRemovals(address[] calldata guardian) external;\n\n function cancelGuardianAddition(address guardian) external;\n\n function cancelGuardianRemoval(address guardian) external;\n\n function isGuardian(address guardian) external view returns (bool);\n\n function isAdditionPending(address guardian) external view returns (bool);\n\n function isRemovalPending(address guardian) external view returns (bool);\n\n function isGuardianFacetRemovable() external view returns (bool);\n\n function getAdditionSecurityPeriod() external view returns (uint256);\n\n function getRemovalSecurityPeriod() external view returns (uint256);\n\n function getSecurityWindow() external view returns (uint256);\n\n function getGuardians() external view returns (address[] memory);\n\n function majorityOfGuardians() external view returns (uint256);\n\n function guardianCount() external view returns (uint256);\n}\n" + }, + "contracts/facets/interfaces/ILockFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Lock} from \"../../libraries/LibAppStorage.sol\";\n\n/**\n * @title Lock Facet Interface\n * @dev Interface of Lock contract that enables full lock/unlock of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface ILockFacet {\n event Locked(uint64 releaseAfter);\n event Unlocked();\n\n error LockFacet__InvalidRecoveryPeriod();\n error LockFacet__CannotUnlock();\n error LockFacet__InvalidSignature();\n error LockFacet__InvalidApprover();\n\n function lock() external;\n\n function unlock(address approver, bytes calldata signature) external;\n\n function getLockPeriod() external view returns (uint256);\n\n function isLocked() external view returns (bool);\n\n function getUnlockHash() external view returns (bytes32);\n\n function lockNonce() external view returns (uint128);\n\n function getPendingLock() external view returns (Lock memory);\n}\n" + }, + "contracts/facets/interfaces/IMultiSigFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Multi-sig facet Interface\n * @dev Interface of Multi-signature Facet with custom threshold.\n Wallet that adds this facet becomes a multi-sig wallet\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IMultiSigFacet {\n event ThresholdChanged(uint256 threshold);\n event OwnerAdded(address indexed newOwner);\n event OwnerRemoved(address indexed prevOwner);\n event HashApproved(bytes32 hashToApprove, address indexed owner);\n\n error MultiSigFacet__InvalidThreshold();\n error MultisigFacet__InvalidOwnerCount();\n error MultiSigFacet__InvalidRoute();\n error MultiSigFacet__InsufficientSignerLength();\n error MultiSigFacet__InvalidInitData();\n error MultiSigFacet__InvalidOwnerAddress();\n error MultiSigFacet__InvalidOwnerPair();\n error MultiSigFacet__InvalidSignatureLength();\n error MultiSigFacet__InvalidSignatureType();\n error MultiSigFacet__DuplicateOwner();\n error MultiSigFacet__OnlyOwner();\n\n function checkSignatures(\n bytes32 _dataHash,\n bytes calldata _signatures,\n uint256 _threshold\n ) external view returns (uint256);\n\n function splitSignatures(\n bytes calldata _signatures,\n uint256 _nextOffset\n )\n external\n pure\n returns (\n address owner,\n bytes memory signature,\n uint256 signatureType,\n uint256 nextOffset\n );\n\n function approveHash(bytes32 hashToApprove) external;\n\n function addOwner(address newOwner, uint256 threshold) external;\n\n function removeOwner(\n address prevOwner,\n address removedOwner,\n uint256 threshold\n ) external;\n\n function swapOwner(\n address prevOwner,\n address oldOwner,\n address newOwner\n ) external;\n\n function changeThreshold(uint256 _threshold) external;\n\n function isOwner(address owner) external view returns (bool);\n\n function getThreshold() external view returns (uint256);\n\n function getOwners() external view returns (address[] memory);\n}\n" + }, + "contracts/facets/interfaces/IRestrictionsFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Restrictions Facet Interface\n * @dev Interface of Restrictions contract that enables modular restrictions in Barz\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IRestrictionsFacet {\n event RestrictionAdded(address indexed restriction);\n event RestrictionRemoved(address indexed restriction);\n\n error RestrictionsFacet__EmptyRestrictionsList();\n error RestrictionsFacet__RestrictionNotFound();\n error RestrictionsFacet__RestrictionAlreadyExists();\n error RestrictionsFacet__ZeroAddressRestrictions();\n error RestrictionsFacet__ZeroAddressRestrictionsFacet();\n error RestrictionsFacet__RemainingRestrictionsCantBeEmpty();\n\n function initializeRestrictions(\n address[] memory _restrictions\n ) external returns (uint256);\n\n function uninitializeRestrictions() external returns (uint256);\n\n function getRestrictions() external view returns (address[] memory);\n\n function addRestriction(address restriction) external;\n\n function removeRestriction(address restriction) external;\n\n function verifyRestrictions(\n address from,\n address to,\n uint256 value,\n bytes calldata _calldata\n ) external returns (uint256);\n}\n" + }, + "contracts/facets/interfaces/ISignatureMigrationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureMigrationConfig} from \"../../libraries/LibFacetStorage.sol\";\n\n/**\n * @title Signature Migration Facet Interface\n * @dev Interface of Signature Migration contract for migrating user signature scheme to a new scheme user sets\n * Which could include\n * - ECDSA on Secp256K1 Curve\n * - ECDSA on Secp256R1 Curve\n * - BLS, Schnorr, etc\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface ISignatureMigrationFacet {\n event SignatureSchemeMigration(\n address indexed prevVerificationFacet,\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n event SignatureMigrationApproved(\n bytes newPublicKey,\n address indexed newVerificationFacet,\n bytes4[] verificationFuncSelectors,\n address indexed guardian,\n uint128 approvalValidUntil\n );\n event SignatureMigrationApprovalRevoked(\n bytes newPublicKey,\n address indexed newVerificationFacet,\n bytes4[] verificationFuncSelectors,\n address indexed guardian\n );\n event SignatureMigrationExecuted(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors,\n uint128 migrateAfter\n );\n event SignatureMigrationCanceled(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n event SignatureMigrationCancellationApproved(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n\n error SignatureMigrationFacet__SignerUninitializationFailure();\n error SignatureMigrationFacet__InvalidRouteWithGuardian();\n error SignatureMigrationFacet__InvalidKeyType();\n error SignatureMigrationFacet__InsufficientApprovers();\n error SignatureMigrationFacet__InvalidApproverSignature();\n error SignatureMigrationFacet__InvalidGuardian();\n error SignatureMigrationFacet__NonExistentApprover();\n error SignatureMigrationFacet__InvalidMigrationPeriod();\n error SignatureMigrationFacet__NonexistentMigration();\n error SignatureMigrationFacet__MigrationPeriodNotOver();\n error SignatureMigrationFacet__InvalidArrayLength();\n error SignatureMigrationFacet__InvalidApprovalValidationPeriod();\n error SignatureMigrationFacet__CannotRevokeUnapproved();\n error SignatureMigrationFacet__LackOfOwnerApproval();\n error SignatureMigrationFacet__OwnerAlreadyApproved();\n error SignatureMigrationFacet__NonExistentVerificationFacet();\n error SignatureMigrationFacet__DuplicateApproval();\n\n function migrateSignatureScheme(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function migrateSignatureSchemeWithGuardian(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors,\n address[] calldata approvers,\n bytes[] calldata signatures\n ) external;\n\n function approveSignatureSchemeMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function revokeSignatureMigrationApproval(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function finalizeSignatureMigration() external;\n\n function approveCancelSignatureMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function cancelSignatureMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function getApprovalMigrationKeyHash(\n bytes memory recoveryPublicKey,\n address newVerificationFacet,\n bytes4[] memory newVerificationFuncSelectors,\n string memory saltString\n ) external view returns (bytes32);\n\n function getMigrationOwnerApprovalWithTimeValidity(\n bytes32 publicKeyHash\n ) external view returns (bool);\n\n function getMigrationApprovalCountWithTimeValidity(\n bytes32 publicKeyHash\n ) external view returns (uint256);\n\n function isMigrationApproved(\n bytes32 migrationPublicKeyHash,\n address approver\n ) external view returns (bool);\n\n function getMigrationNonce() external view returns (uint128);\n\n function isMigrationPending() external view returns (bool);\n\n function getPendingMigration()\n external\n view\n returns (SignatureMigrationConfig memory);\n}\n" + }, + "contracts/facets/interfaces/IVerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {UserOperation} from \"../../aa-4337/interfaces/UserOperation.sol\";\n\n/**\n * @title Verification Facet Interface\n * @dev Implements logic for user ops signature verification\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface IVerificationFacet {\n event SignerInitialized(bytes);\n event SignerUninitialized();\n\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n error VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n error VerificationFacet__InitializationFailure();\n error VerificationFacet__InvalidFacetMapping();\n\n function initializeSigner(bytes memory) external returns (uint256);\n\n function uninitializeSigner() external returns (uint256);\n\n function validateOwnerSignatureSelector() external view returns (bytes4);\n\n function owner() external view returns (bytes memory);\n\n function isValidKeyType(bytes calldata) external view returns (bool);\n\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) external view returns (uint256);\n}\n" + }, + "contracts/facets/LockFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage, Lock} from \"../libraries/LibAppStorage.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibFacetStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {ILockFacet} from \"./interfaces/ILockFacet.sol\";\n\n/**\n * @title Lock Facet\n * @dev Contract that enables full lock/unlock of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract LockFacet is ILockFacet, Modifiers {\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Locks the account for the lock period. Lock period is defined in the security manager and it's customizable\n * This function can only be called when account is unlocked by owner or guardians\n * @dev This method checks the caller and if the account is currently locked and locks the account after fetching the\n * Lock period from the owner.\n */\n function lock() external override onlyGuardianOrOwner onlyWhenUnlocked {\n uint256 unlockTime = block.timestamp + getLockPeriod();\n ++LibFacetStorage.lockStorage().nonce;\n LibAppStorage.setLock(unlockTime, LockFacet.lock.selector);\n emit Locked(uint64(unlockTime));\n }\n\n /**\n * @notice Locks the account when the account is locked. This function can be called by anyone but must provide the approver address and signature.\n * The approver should be one of the guardians or owner.\n * @dev This method takes the approver address and the signature. After validating the address and the signature, it unlocks the account immediately.\n * Only one of the guardian or owner is required to lock and unlock the account.\n * @param _approver Address of approver approving the unlock of Barz account\n * @param _signature Signature of the approver that signed the msg hash for unlocking the account\n */\n function unlock(\n address _approver,\n bytes calldata _signature\n ) external override onlyWhenLocked {\n if (_approver != address(this) && !LibGuardian.isGuardian(_approver))\n revert LockFacet__InvalidApprover();\n if (\n !SignatureChecker.isValidSignatureNow(\n _approver,\n getUnlockHash(),\n _signature\n )\n ) revert LockFacet__InvalidSignature();\n _unlock();\n }\n\n /**\n * @notice Unlocks the account and increments the lock nonce\n */\n function _unlock() private {\n if (s.locks[INNER_STRUCT].locker != LockFacet.lock.selector)\n revert LockFacet__CannotUnlock();\n ++LibFacetStorage.lockStorage().nonce;\n LibAppStorage.setLock(0, bytes4(0));\n emit Unlocked();\n }\n\n /**\n * @notice Returns the lock period of current Barz account. Lock period information is held by Security Manager\n * @return lockPeriod Uint value of lock period in seconds\n */\n function getLockPeriod() public view override returns (uint256 lockPeriod) {\n lockPeriod = securityManager.lockPeriodOf(address(this));\n if (lockPeriod == 0) revert LockFacet__InvalidRecoveryPeriod();\n }\n\n /**\n * @notice Returns if the account is locked or not\n * @dev This method fetches the current block timestamp and compares that with release time.\n * After checking the timestamp and release time, it returns if the account is still locked or not.\n * @return isLocked_ Uint value of lock period in seconds\n */\n function isLocked() public view override returns (bool isLocked_) {\n isLocked_ = uint64(block.timestamp) < s.locks[INNER_STRUCT].release;\n }\n\n /**\n * @notice Calculates the unlock hash and returns the unlock hash safe from signature reply attack\n * @dev This method calculates the unlock hash with EIP-191 prefix, wallet address, chainID, and nonce\n * It packs the result and packs them and hashes it.\n * @return unlockHash Bytes32 unlock hash\n */\n function getUnlockHash() public view override returns (bytes32 unlockHash) {\n unlockHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n \"Unlock\",\n address(this),\n block.chainid,\n lockNonce()\n )\n )\n )\n );\n }\n\n /**\n * @notice Returns lock nonce of account. Reads nonce from lock storage within facet storage\n * @return lockNonce_ Uint128 value of lock nonce. This is incremented whenever the account is lock/unlocked\n */\n function lockNonce() public view override returns (uint128 lockNonce_) {\n lockNonce_ = LibFacetStorage.lockStorage().nonce;\n }\n\n /**\n * @notice Returns the overall information of current lock\n * @return pendingLock Struct value including all information of pending lock\n */\n function getPendingLock()\n public\n view\n override\n returns (Lock memory pendingLock)\n {\n pendingLock = s.locks[INNER_STRUCT];\n }\n}\n" + }, + "contracts/facets/Modifiers.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {IFacetRegistry} from \"../infrastructure/interfaces/IFacetRegistry.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\n\n/**\n * @title Modifiers\n * @dev Responsible for providing modifiers/util functions to Facet contracts\n * @author David Yongjun Kim (@Powerstream3604)\n */\nabstract contract Modifiers is BarzStorage {\n uint8 constant INNER_STRUCT = 0;\n\n error CallerNotGuardian();\n error CallerNotGuardianOrOwner();\n error DuplicateApprover();\n error ZeroApproverLength();\n error UnregisteredFacetAndSelectors();\n\n /**\n * @notice Modifier to only allow guardian to make a call, reverts if any other entity is the caller\n */\n modifier onlyGuardian() {\n if (!LibGuardian.isGuardian(msg.sender)) revert CallerNotGuardian();\n _;\n }\n\n /**\n * @notice Modifier to only allow guardian or owner to make a call, reverts if any other entity is the caller\n */\n modifier onlyGuardianOrOwner() {\n if (!LibGuardian.isGuardian(msg.sender) && address(this) != msg.sender)\n revert CallerNotGuardianOrOwner();\n _;\n }\n\n /**\n * @notice Checks if the approver address is the array is unique with no duplicate\n * @dev This method loops through the array and checks if a duplicate address exists, it reverts if duplicate address exists\n * @param approvers Array of address\n */\n function _checkApprover(\n address[] memory approvers\n ) internal pure returns (bool) {\n uint256 approverLength = approvers.length;\n if (0 == approverLength) revert ZeroApproverLength();\n for (uint256 i; i < approverLength - 1; ) {\n for (uint256 j = i + 1; j < approverLength; ) {\n if (approvers[i] == approvers[j]) {\n revert DuplicateApprover(); // Found a duplicate\n }\n unchecked {\n ++j;\n }\n }\n unchecked {\n ++i;\n }\n }\n return false; // No duplicates found\n }\n\n /**\n * @notice Checks if the facet getting added or replaced is registered to facet registry\n * @dev This method loops through the cut and checks if the facet getting added/replaced is registered to facet registry\n * @param _diamondCut Array of FacetCut, data for diamondCut defined in EIP-2535\n */\n function _checkFacetCutValidity(\n IDiamondCut.FacetCut[] memory _diamondCut\n ) internal view {\n uint256 diamondCutLength = _diamondCut.length;\n for (uint256 i; i < diamondCutLength; ) {\n if (\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Add ||\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Replace\n ) {\n if (\n !s.facetRegistry.areFacetFunctionSelectorsRegistered(\n _diamondCut[i].facetAddress,\n _diamondCut[i].functionSelectors\n )\n ) revert UnregisteredFacetAndSelectors();\n }\n unchecked {\n ++i;\n }\n }\n }\n}\n" + }, + "contracts/facets/RestrictionsFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, RestrictionsStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {IRestriction} from \"../restrictions/IRestriction.sol\";\nimport {IRestrictionsFacet} from \"./interfaces/IRestrictionsFacet.sol\";\n\n/**\n * @title Restrictions facet\n * @dev Responsible for storing and verifying different kinds of restrictions, for example:\n * - Whitelist / Blacklist\n * - Daily limits\n * - Trading time restrictions\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract RestrictionsFacet is IRestrictionsFacet {\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceRestrictionsInitialize();\n }\n\n /**\n * @notice Intialize restrictions of Barz. Restrictions facet call restriction contracts for restriction validation\n * before each call\n * @param _restrictions The initial array of restrictions.\n * @return initSuccess Int value showing if the initialization of restriction is successful\n */\n function initializeRestrictions(\n address[] calldata _restrictions\n ) public override returns (uint256 initSuccess) {\n LibDiamond.enforceIsSelf();\n LibAppStorage.enforceRestrictionsInitialize();\n\n if (_restrictions.length == 0) {\n // You can't initialize RestrictionsFacet with an empty list of restrictions\n revert RestrictionsFacet__EmptyRestrictionsList();\n }\n for (uint256 i; i < _restrictions.length; ) {\n if (_restrictions[i] == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictions();\n unchecked {\n ++i;\n }\n }\n\n LibFacetStorage.restrictionsStorage().restrictions = _restrictions;\n _updateRestrictionsMap(_restrictions, true);\n initSuccess = 1;\n }\n\n /**\n * @notice Unitialize restrictions of Barz\n * @return uninitSuccess Int value showing if the initialization of restriction is successful\n */\n function uninitializeRestrictions()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibDiamond.enforceIsSelf();\n LibAppStorage.setRestrictionsUninitialized();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n _updateRestrictionsMap(restrictionsStorage.restrictions, false);\n restrictionsStorage.restrictions = new address[](0);\n uninitSuccess = 1;\n }\n\n /**\n * @notice Returns the list of Restrictions contract address\n * @return restrictions Addresses of IRestriction which are currently active\n */\n function getRestrictions()\n public\n view\n override\n returns (address[] memory restrictions)\n {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n restrictions = restrictionsStorage.restrictions;\n }\n\n /**\n * @notice Adds restrictions to Barz with validation on the restriction contract address.\n * This method is only callable by the owner(self).\n * @param _restriction The address of the restriction to be added.\n */\n function addRestriction(address _restriction) external override {\n LibDiamond.enforceIsSelf();\n if (LibDiamond.restrictionsFacet() == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictionsFacet();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n if (_restriction == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictions();\n if (restrictionsStorage.exists[_restriction])\n revert RestrictionsFacet__RestrictionAlreadyExists();\n\n restrictionsStorage.restrictions.push(_restriction);\n restrictionsStorage.exists[_restriction] = true;\n\n emit RestrictionAdded(_restriction);\n }\n\n /**\n * @notice Remove restrictions from Barz if it existed. This method is only callable by the owner(self).\n * @param _restriction The address of the restriction to be removed.\n */\n function removeRestriction(address _restriction) external override {\n LibDiamond.enforceIsSelf();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n if (!restrictionsStorage.exists[_restriction])\n revert RestrictionsFacet__RestrictionNotFound();\n\n address[] storage restrictions = restrictionsStorage.restrictions;\n\n uint256 indexToDelete = restrictions.length;\n uint256 restrictionsLen = restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n if (restrictions[i] == _restriction) {\n indexToDelete = i;\n break;\n }\n unchecked {\n ++i;\n }\n }\n\n if (indexToDelete == 0 && restrictionsLen == 1) {\n revert RestrictionsFacet__RemainingRestrictionsCantBeEmpty();\n } else if (indexToDelete == restrictionsLen) {\n revert RestrictionsFacet__RestrictionNotFound();\n } else {\n restrictions[indexToDelete] = restrictions[restrictionsLen - 1];\n restrictions.pop();\n }\n\n restrictionsStorage.exists[_restriction] = false;\n emit RestrictionRemoved(_restriction);\n }\n\n /**\n * @notice Sets the restrictions address value mapping to true or false when adding/removing restriction contracts\n * @param _restrictions List of restriction contracts address\n * @param _newValue Bool value to flag to the list of restrictions contracts\n */\n function _updateRestrictionsMap(\n address[] memory _restrictions,\n bool _newValue\n ) internal {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n uint restrictionsLen = _restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n restrictionsStorage.exists[_restrictions[i]] = _newValue;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @dev Iterates over all restrictions and verifies each of them with the transaction parameters.\n * @param _from The address of the sender, that will be signing the transaction.\n * @param _to The receiving address.\n * @param _value Amount of ETH to transfer from sender to recipient.\n * @param _calldata Optional field to include arbitrary data.\n * @return 0 if all the checks passed, 1 otherwise.\n */\n function verifyRestrictions(\n address _from,\n address _to,\n uint256 _value,\n bytes calldata _calldata\n ) external returns (uint256) {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n uint restrictionsLen = restrictionsStorage.restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n IRestriction restriction = IRestriction(\n restrictionsStorage.restrictions[i]\n );\n bool checkPassed = restriction.check(_from, _to, _value, _calldata);\n if (!checkPassed) {\n return 1;\n }\n unchecked {\n ++i;\n }\n }\n\n return 0;\n }\n}\n" + }, + "contracts/facets/SignatureMigrationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, SignatureMigrationStorage, SignatureMigrationConfig, SignatureMigrationApprovalConfig, ApprovalConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IDiamondCut} from \"./base/interfaces/IDiamondCut.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {ISignatureMigrationFacet} from \"./interfaces/ISignatureMigrationFacet.sol\";\n\n/**\n * @title Signature Migration Facet\n * @dev Responsible for migrating user signature scheme to a new scheme user sets\n * Which could include\n * - ECDSA on Secp256K1 Curve\n * - ECDSA on Secp256R1 Curve\n * - BLS, Schnorr, etc\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract SignatureMigrationFacet is ISignatureMigrationFacet, Modifiers {\n bytes constant UNINIT_CALL =\n abi.encodeWithSignature(\"uninitializeSigner()\");\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This modifier verifies if the public key format matches with the new verification facet\n * @param _publicKey Bytes of public key to be validated for the new verification facet\n * @param _newVerificationFacet Address of new verification facet\n */\n modifier validateKeyType(\n bytes memory _publicKey,\n address _newVerificationFacet\n ) {\n if (\n !IVerificationFacet(_newVerificationFacet).isValidKeyType(\n _publicKey\n )\n ) revert SignatureMigrationFacet__InvalidKeyType();\n _;\n }\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n // IMPORTANT NOTE: In the client side when they call this function, the func selectors should be sorted in ascending order\n // to prevent different hash with same items in the array\n /**\n * @notice Moves the state of migration to a pending state. When pending state is over after pending period time,\n * Migration can be finalized. This function can only be called by self and when the account is unlocked.\n * @dev This method checks if the caller is self and if guardians exists. It migrates signature request to a pending state\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function migrateSignatureScheme(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n public\n override\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n // Only self contract can call this function\n LibDiamond.enforceIsSelf();\n // Should revert if guardian exist\n if (0 != LibGuardian.guardianCount())\n revert SignatureMigrationFacet__InvalidRouteWithGuardian();\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n // NOTE: Migration requires a pending period & confirmation from owner to prevent a\n // single call changing the ownership of the wallet\n /**\n * @notice Migrate signature scheme when guardians exists. Verifies the signature of guardians and moves migration to pending state.\n * Which can then be finalized when pending period is over. Owner's approval is mandatory for migration to happen\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _approvers List of approvers. This could include owner\n */\n function migrateSignatureSchemeWithGuardian(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n )\n public\n override\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n // Should revert if does not guardian exist\n if (0 == LibGuardian.guardianCount())\n revert SignatureMigrationFacet__InvalidRouteWithGuardian();\n if (_approvers.length != _signatures.length)\n revert SignatureMigrationFacet__InvalidArrayLength();\n\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(migrationPublicKeyHash, _approvers);\n\n bool onChainOwnerApproval = getMigrationOwnerApprovalWithTimeValidity(\n migrationPublicKeyHash\n );\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n\n if (\n _approvers.length +\n getMigrationApprovalCountWithTimeValidity(\n migrationPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert SignatureMigrationFacet__InsufficientApprovers();\n {\n // To prevent Stack too deep\n bool ownerApproved;\n for (uint256 i; i < _approvers.length; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n address(this) != _approvers[i]\n ) revert SignatureMigrationFacet__InvalidGuardian();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert SignatureMigrationFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n migrationPublicKeyHash,\n _signatures[i]\n )\n ) revert SignatureMigrationFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n\n if (!ownerApproved && !onChainOwnerApproval)\n revert SignatureMigrationFacet__LackOfOwnerApproval();\n }\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Internal function that moves signature mgiration to a pending state.\n * @dev This method increments migration nonce and sets the migration in the migration config. Emits events for migration execution\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _migrateSignatureScheme(\n address _newVerificationFacet,\n bytes memory _newPublicKey,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal {\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n\n ++ms.nonce;\n uint64 migrateAfter = uint64(block.timestamp + getMigrationPeriod());\n\n ms.migrationConfigs[INNER_STRUCT] = SignatureMigrationConfig(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n migrateAfter\n );\n\n emit SignatureMigrationExecuted(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors,\n migrateAfter\n );\n }\n\n /**\n * @notice Approves signature scheme migration on-chain. This can be called by owner or guardian only when the account is unlocked.\n * When the threshold of the migration approval passed and owner approval is granted, it automatically moves migration to a pending state\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function approveSignatureSchemeMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n public\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit SignatureMigrationApproved(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n msg.sender,\n approvalValidUntil\n );\n if (\n getMigrationApprovalCountWithTimeValidity(migrationPublicKeyHash) >=\n LibGuardian.majorityOfGuardians() &&\n getMigrationOwnerApprovalWithTimeValidity(migrationPublicKeyHash)\n )\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Revokes the approval of signature migration done on-chain. Emits revoke event when revoked.\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function revokeSignatureMigrationApproval(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n external\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n if (!isMigrationApproved(migrationPublicKeyHash, msg.sender))\n revert SignatureMigrationFacet__CannotRevokeUnapproved();\n\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(false, 0);\n emit SignatureMigrationApprovalRevoked(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n msg.sender\n );\n }\n\n /**\n * @notice Finalizes the pending signature scheme migration. This function can only be called by owner.\n * It removes the facets of the previous verification facet and adds the new verification facet.\n * After finalizing migration, it emits migration event which shows the change of the verification facet\n */\n function finalizeSignatureMigration() external override {\n // NOTE: Only owner can call this function\n LibDiamond.enforceIsSelf();\n\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n\n if (!isMigrationPending())\n revert SignatureMigrationFacet__NonexistentMigration();\n\n if (\n uint64(block.timestamp) <=\n ms.migrationConfigs[INNER_STRUCT].migrateAfter\n ) revert SignatureMigrationFacet__MigrationPeriodNotOver();\n address newVerificationFacet = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationVerificationFacet;\n bytes4[] memory newVerificationFuncSelectors = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationSelectors;\n bytes memory newPublicKey = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationPublicKey;\n\n address prevVerificationFacet = LibLoupe.facetAddress(\n s.validateOwnerSignatureSelector\n );\n if (prevVerificationFacet == address(0))\n revert SignatureMigrationFacet__NonExistentVerificationFacet();\n\n IDiamondCut.FacetCut[] memory UninitCut;\n IDiamondCut.FacetCut[] memory InitCut;\n {\n bytes4[] memory prevVerificationFuncSelectors = LibLoupe\n .facetFunctionSelectors(prevVerificationFacet);\n\n UninitCut = new IDiamondCut.FacetCut[](1);\n InitCut = new IDiamondCut.FacetCut[](1);\n UninitCut[0] = IDiamondCut.FacetCut({\n facetAddress: address(0),\n action: IDiamondCut.FacetCutAction.Remove,\n functionSelectors: prevVerificationFuncSelectors\n });\n InitCut[0] = IDiamondCut.FacetCut({\n facetAddress: newVerificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: newVerificationFuncSelectors\n });\n {\n IDiamondCut.FacetCut[]\n memory facetCuts = new IDiamondCut.FacetCut[](2);\n facetCuts[0] = UninitCut[0];\n facetCuts[1] = InitCut[0];\n _checkFacetCutValidity(facetCuts);\n }\n LibAppStorage.initiateSignerMigration();\n address verificationFacet = address(\n bytes20(\n LibDiamond.diamondStorage().facets[\n s.validateOwnerSignatureSelector\n ]\n )\n );\n\n (bool success, bytes memory result) = verificationFacet\n .delegatecall(UNINIT_CALL);\n require(success, \"MigrationFacet: uninitialize not successful\");\n uint256 validationData = uint256(bytes32(result));\n if (validationData == 0)\n revert SignatureMigrationFacet__SignerUninitializationFailure();\n\n LibDiamond.diamondCut(UninitCut, address(0), \"\");\n }\n {\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n newPublicKey\n );\n\n // Every Verification Facet should comply with initializeSigner(bytes)\n // to be compatible with the Barz contract(for initialization)\n LibDiamond.diamondCut(InitCut, newVerificationFacet, initCall);\n LibAppStorage.finalizeSignerMigration();\n emit SignatureSchemeMigration(\n prevVerificationFacet,\n newVerificationFacet,\n newPublicKey,\n newVerificationFuncSelectors\n );\n }\n }\n\n /**\n * @notice Approve cancellation of signature migration. If cancellation approval passes guardian threshold with owner approval\n * it automatically cancels the migration.\n * @dev This method checks if the caller is one of guardian or owner and sets true for the cancellation hash in the approval config.\n * It internally calls _cancelSignatureMigration for canceling the migration\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function approveCancelSignatureMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n external\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"CancelSignatureMigration\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit SignatureMigrationCancellationApproved(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n if (\n getMigrationApprovalCountWithTimeValidity(migrationPublicKeyHash) >=\n LibGuardian.majorityOfGuardians() &&\n getMigrationOwnerApprovalWithTimeValidity(migrationPublicKeyHash)\n )\n _cancelSignatureMigration(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Verifies the signature of guardians/owner and cancels the signature migration.\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _approvers List of approvers. This could include owner\n */\n function cancelSignatureMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n )\n external\n override\n validateKeyType(_newPublicKey, _newVerificationFacet)\n onlyWhenUnlocked\n {\n if (_approvers.length != _signatures.length)\n revert SignatureMigrationFacet__InvalidArrayLength();\n\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"CancelSignatureMigration\"\n );\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(migrationPublicKeyHash, _approvers);\n\n bool onChainOwnerApproval = getMigrationOwnerApprovalWithTimeValidity(\n migrationPublicKeyHash\n );\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n if (\n _approvers.length +\n getMigrationApprovalCountWithTimeValidity(\n migrationPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert SignatureMigrationFacet__InsufficientApprovers();\n {\n // To prevent stack too deep\n bool ownerApproved;\n for (uint256 i; i < _approvers.length; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n address(this) != _approvers[i]\n ) revert SignatureMigrationFacet__NonExistentApprover();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert SignatureMigrationFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n migrationPublicKeyHash,\n _signatures[i]\n )\n ) revert SignatureMigrationFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n if (!ownerApproved && !onChainOwnerApproval)\n revert SignatureMigrationFacet__LackOfOwnerApproval();\n }\n _cancelSignatureMigration(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Internal function that cancels signature migration.\n * @dev This method increments migration nonce and deletes the migration from the migration config. Emits events for migration cancellation\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _cancelSignatureMigration(\n address _newVerificationFacet,\n bytes memory _newPublicKey,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal {\n if (!isMigrationPending())\n revert SignatureMigrationFacet__NonexistentMigration();\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n ++ms.nonce;\n delete ms.migrationConfigs[INNER_STRUCT];\n emit SignatureMigrationCanceled(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Checks if the facets to be added from new verification facet is registered to facet registry\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _checkMigrationCutValidity(\n address _newVerificationFacet,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal view {\n IDiamondCut.FacetCut[] memory facetCuts = new IDiamondCut.FacetCut[](1);\n facetCuts[0] = IDiamondCut.FacetCut({\n facetAddress: _newVerificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: _newVerificationFuncSelectors\n });\n _checkFacetCutValidity(facetCuts);\n }\n\n /**\n * @notice Returns if the migration is pending of not\n * @dev This method fetches the migration storage and checks if the migrate after is above 0 value\n * @return isPending Bool value that shows if the migration is pending\n */\n function isMigrationPending()\n public\n view\n override\n returns (bool isPending)\n {\n SignatureMigrationStorage storage rs = LibFacetStorage\n .migrationStorage();\n isPending = rs.migrationConfigs[INNER_STRUCT].migrateAfter > 0;\n }\n\n /**\n * @notice Returns the migration hash. This function ensures that this hash is safe from replay attack by including\n * public key, verification facet, function selectors, salt, address, chainId, and nonce.\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _saltString Salt value for generating the migration hash\n * @return migrationKeyHash Bytes32 string of the migration key hash\n */\n function getApprovalMigrationKeyHash(\n bytes memory _newPublicKey,\n address _newVerificationFacet,\n bytes4[] memory _newVerificationFuncSelectors,\n string memory _saltString\n ) public view override returns (bytes32 migrationKeyHash) {\n migrationKeyHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n _newPublicKey,\n _newVerificationFacet,\n keccak256(abi.encode(_newVerificationFuncSelectors)),\n _saltString,\n address(this),\n block.chainid,\n LibFacetStorage.migrationStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Checks if the owner approved the hash for migration\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @return isApprovedByOwner Bool value of showing if the owner approved it or not\n */\n function getMigrationOwnerApprovalWithTimeValidity(\n bytes32 _migrationPublicKeyHash\n ) public view override returns (bool isApprovedByOwner) {\n isApprovedByOwner = isMigrationApproved(\n _migrationPublicKeyHash,\n address(this)\n );\n }\n\n /**\n * @notice Checks how many of the guardians approved the migration hash\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @return approvalCount Number of approvals\n */\n function getMigrationApprovalCountWithTimeValidity(\n bytes32 _migrationPublicKeyHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardiansLength = guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n if (isMigrationApproved(_migrationPublicKeyHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n return approvalCount;\n }\n\n /**\n * @notice Checks if the migration is approved by the given approver\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @param _approver Address of approver\n * @return isApproved Bool value if migration hash is approved\n */\n function isMigrationApproved(\n bytes32 _migrationPublicKeyHash,\n address _approver\n ) public view override returns (bool isApproved) {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n isApproved = (ms\n .isMigrationApproved[_migrationPublicKeyHash][_approver].isApproved &&\n block.timestamp <\n ms\n .isMigrationApproved[_migrationPublicKeyHash][_approver]\n .validUntil);\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _migrationPublicKeyHash Hash of migration information\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _migrationPublicKeyHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isMigrationApproved(_migrationPublicKeyHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert SignatureMigrationFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the migration period of this wallet\n * @dev This method fetches the migration period from the security manager\n * @return migrationPeriod Migration period of Barz contract fetched from security manager\n */\n function getMigrationPeriod()\n internal\n view\n returns (uint128 migrationPeriod)\n {\n migrationPeriod = securityManager.migrationPeriodOf(address(this));\n if (migrationPeriod == 0)\n revert SignatureMigrationFacet__InvalidMigrationPeriod();\n }\n\n /**\n * @notice Returns the validation period of this wallet\n * @dev This method fetches the validation period from the security manager\n * @return approvalValidationPeriod Validation period of Barz contract fetched from security manager\n */\n function getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod == 0)\n revert SignatureMigrationFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the migration nonce of this wallet\n * @dev This method fetches the nonce from migration storage\n * @return migrationNonce Nonce of migration to protect from reply attacks\n */\n function getMigrationNonce()\n public\n view\n override\n returns (uint128 migrationNonce)\n {\n migrationNonce = LibFacetStorage.migrationStorage().nonce;\n }\n\n /**\n * @notice Returns the migration configuration of this wallet\n * @dev This method fetches the migration config from the migration storage\n * @return pendingMigrationConfig Migration config currently pending for signature migration\n */\n function getPendingMigration()\n external\n view\n override\n returns (SignatureMigrationConfig memory pendingMigrationConfig)\n {\n pendingMigrationConfig = LibFacetStorage\n .migrationStorage()\n .migrationConfigs[INNER_STRUCT];\n }\n}\n" + }, + "contracts/facets/TokenReceiverFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {IERC1155Receiver} from \"../interfaces/ERC/IERC1155Receiver.sol\";\nimport {IERC677Receiver} from \"../interfaces/ERC/IERC677Receiver.sol\";\n\n/**\n * @title TokenReceiver Facet\n * @dev Contract that enables receiving ERC721/ERC1155/ERC777/ERC677 Tokens with safe transfer\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract TokenReceiverFacet is\n IERC721Receiver,\n IERC1155Receiver,\n IERC777Recipient,\n IERC677Receiver\n{\n /**\n * @notice Handles ERC721 Token callback.\n * return Standardized onERC721Received return value.\n */\n function onERC721Received(\n address,\n address,\n uint256,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC721Receiver.onERC721Received.selector;\n }\n\n /**\n * @notice Handles ERC1155 Token callback.\n * return Standardized onERC1155Received return value.\n */\n function onERC1155Received(\n address,\n address,\n uint256,\n uint256,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC1155Receiver.onERC1155Received.selector;\n }\n\n /**\n * @notice Handles ERC1155 Token batch callback.\n * return Standardized onERC1155BatchReceived return value.\n */\n function onERC1155BatchReceived(\n address,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC1155Receiver.onERC1155BatchReceived.selector;\n }\n\n /**\n * @notice Handles ERC777 Token callback.\n * Does not return value, empty implementation.\n */\n function tokensReceived(\n address,\n address,\n address,\n uint256,\n bytes calldata,\n bytes calldata\n ) external pure override {}\n\n /**\n * @notice Handles ERC677 Token callback.\n * return true.\n */\n function onTokenTransfer(\n address,\n uint256,\n bytes calldata\n ) external pure override returns (bool) {\n return true;\n }\n}\n" + }, + "contracts/facets/verification/MultiSigFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {UserOperation} from \"../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../../libraries/LibLoupe.sol\";\nimport {LibAppStorage} from \"../../libraries/LibAppStorage.sol\";\nimport {LibMultiSigStorage, MultiSigStorage} from \"../../libraries/LibMultiSigStorage.sol\";\nimport {IERC1271} from \"../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../interfaces/IVerificationFacet.sol\";\nimport {IMultiSigFacet} from \"../interfaces/IMultiSigFacet.sol\";\n\n/**\n * @title Multi-sig facet\n * @dev Multi-signature Facet with custom threshold.\n * Wallet that adds this facet becomes a multi-sig wallet.\n * Reference signature_format.md documentation for Multi-sig facet details\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract MultiSigFacet is IMultiSigFacet, IVerificationFacet, IERC1271 {\n using ECDSA for bytes32;\n\n address public immutable self;\n\n address internal constant SENTINEL_OWNERS = address(0x1);\n uint256 internal constant ADDRESS = 20;\n uint256 internal constant SIG_TYPE = 1;\n uint256 internal constant SIG_LEN = 4;\n uint256 internal constant THRESHOLD = 4;\n uint256 internal constant INVALID_SIG = 1;\n uint256 internal constant VALID_SIG = 0;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in Multisig Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the right format and initializes signer storage in k1 storage.\n * @param _owners Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _owners\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n\n if (!isValidKeyType(_owners)) revert MultiSigFacet__InvalidInitData();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n uint256 threshold = uint256(uint32(bytes4(_owners)));\n uint256 ownerCount = (_owners.length - THRESHOLD) / ADDRESS;\n\n if (threshold == 0) revert MultiSigFacet__InvalidThreshold();\n if (ownerCount == 0) revert MultisigFacet__InvalidOwnerCount();\n\n address currentOwner = SENTINEL_OWNERS;\n uint256 ptr = THRESHOLD;\n address owner_;\n for (uint256 i; i < ownerCount; ) {\n owner_ = address(bytes20(_owners[ptr:ptr + ADDRESS]));\n ptr += ADDRESS;\n if (\n owner_ == address(0) ||\n owner_ == SENTINEL_OWNERS ||\n owner_ == address(this) ||\n owner_ == currentOwner\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[owner_] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n\n ms.owners[currentOwner] = owner_;\n currentOwner = owner_;\n\n unchecked {\n ++i;\n }\n }\n ms.owners[currentOwner] = SENTINEL_OWNERS;\n ms.ownerCount = ownerCount;\n ms.threshold = threshold;\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_owners);\n }\n\n /**\n * @notice Uninitialize signer in K1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n ++ms.counter;\n address[] memory ownerlist = getOwners();\n uint256 ownerlistLength = ownerlist.length;\n for (uint256 i; i < ownerlistLength; ) {\n ms.owners[ownerlist[i]] = address(0);\n unchecked {\n ++i;\n }\n }\n ms.owners[SENTINEL_OWNERS] = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls checkSignatures with\n * user operation hash and signature together with the threshold.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n // Data 1 is invalid, Data 0 is valid\n validationData = checkSignatures(\n userOpHash,\n userOp.signature,\n LibMultiSigStorage.multisigStorage().threshold\n );\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n return this.validateOwnerSignature.selector;\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n uint totalLength = ms.ownerCount * ADDRESS;\n bytes memory result = new bytes(totalLength);\n\n // populate return array\n uint256 index;\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n while (currentOwner != SENTINEL_OWNERS) {\n assembly {\n mstore(\n add(result, add(32, mul(index, ADDRESS))),\n shl(96, currentOwner)\n )\n }\n currentOwner = ms.owners[currentOwner];\n index++;\n }\n\n return result;\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key should comply with the format in the signature_format.md doc\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n uint256 publicKeyLength = _publicKey.length;\n if (\n publicKeyLength < ADDRESS + THRESHOLD ||\n (publicKeyLength - THRESHOLD) % ADDRESS != 0\n ) return false;\n\n uint256 threshold = uint256(uint32(bytes4(_publicKey)));\n uint256 ownerCount = (publicKeyLength - THRESHOLD) / ADDRESS;\n\n isValid = !(ownerCount < threshold || threshold == 0);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes calldata _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (checkSignatures(\n _hash,\n _signature,\n LibMultiSigStorage.multisigStorage().threshold\n ) == VALID_SIG)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n\n /**\n * @notice Validates the format of the signature and verifies if the signature is signed by the expected key.\n * Reference signature_format.md doc for details about signature format and signature types\n * @param _dataHash Bytes value of data hash signed by the owners\n * @param _signatures Bytes value of signature which should comply with signature format\n * @param _threshold Uint256 value of current Multi-sig Barz's threshold\n */\n function checkSignatures(\n bytes32 _dataHash,\n bytes calldata _signatures,\n uint256 _threshold\n ) public view returns (uint256) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n address lastOwner = address(0);\n address currentOwner;\n bytes memory signature;\n uint256 signatureType;\n uint256 nextOffset;\n uint256 i;\n for (i; i < _threshold; ) {\n (\n currentOwner,\n signature,\n signatureType,\n nextOffset\n ) = splitSignatures(_signatures, nextOffset);\n if (nextOffset == 0 && i + 1 < _threshold) return INVALID_SIG;\n if (signatureType == 1) {\n // If signatureType is 1 then it is default dataHash signed.\n // This also includes the contract signature\n if (\n !SignatureChecker.isValidSignatureNow(\n currentOwner,\n _dataHash,\n signature\n )\n ) return INVALID_SIG;\n } else if (signatureType == 2) {\n // If signatureType is 2 then it is an approved hash\n if (ms.approvedHashes[ms.counter][currentOwner][_dataHash] == 0)\n return INVALID_SIG;\n } else if (signatureType == 3) {\n // If signatureType is 3 then it is a signed message hash\n // This also includes the contract signature\n bytes32 msgHash = _dataHash.toEthSignedMessageHash();\n if (\n !SignatureChecker.isValidSignatureNow(\n currentOwner,\n msgHash,\n signature\n )\n ) return INVALID_SIG;\n } else revert MultiSigFacet__InvalidRoute();\n if (\n currentOwner <= lastOwner ||\n ms.owners[currentOwner] == address(0) ||\n currentOwner == SENTINEL_OWNERS\n ) return INVALID_SIG;\n lastOwner = currentOwner;\n\n unchecked {\n ++i;\n }\n }\n return VALID_SIG;\n }\n\n /**\n * @notice Split signatures into each individual signatures. Should comply with signature format to be split\n * @param _signatures Bytes value of signature\n * @param _nextOffset Uint256 value of next offset to start splitting the signature\n */\n function splitSignatures(\n bytes calldata _signatures,\n uint256 _nextOffset\n )\n public\n pure\n returns (\n address owner_,\n bytes memory signature,\n uint256 signatureType,\n uint256 nextOffset\n )\n {\n uint256 signaturesLength = _signatures.length;\n\n if (signaturesLength <= _nextOffset + ADDRESS + SIG_LEN)\n revert MultiSigFacet__InsufficientSignerLength();\n\n owner_ = address(\n bytes20(_signatures[_nextOffset:_nextOffset + ADDRESS])\n );\n\n signatureType = uint256(\n uint8(\n bytes1(\n _signatures[_nextOffset + ADDRESS:_nextOffset +\n ADDRESS +\n SIG_TYPE]\n )\n )\n );\n\n if (signatureType > 3 || signatureType == 0)\n revert MultiSigFacet__InvalidSignatureType();\n uint256 offSet = _nextOffset + ADDRESS + SIG_TYPE;\n uint256 siglen = uint256(\n uint32(bytes4(_signatures[offSet:offSet + SIG_LEN]))\n );\n if (offSet + siglen > signaturesLength)\n revert MultiSigFacet__InvalidSignatureLength();\n\n offSet += SIG_LEN;\n if (offSet + siglen == signaturesLength) nextOffset = 0;\n else nextOffset = offSet + siglen;\n\n signature = _signatures[offSet:offSet + siglen];\n }\n\n /**\n * @notice Approves the hash of userOperation on-chain. This can only be called by owners.\n * @param _hashToApprove Bytes value of UserOperation hash to approve\n */\n function approveHash(bytes32 _hashToApprove) external {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (ms.owners[msg.sender] == address(0))\n revert MultiSigFacet__OnlyOwner();\n\n ms.approvedHashes[ms.counter][msg.sender][_hashToApprove] = 1;\n emit HashApproved(_hashToApprove, msg.sender);\n }\n\n /**\n * @notice Add owner to Barz. Update thresold if threshold is given different from current threshold\n * @dev This can only be done via a Self call.\n * @param _newOwner Address of new owner to be added\n * @param _threshold Uint256 value of threshold\n */\n function addOwner(address _newOwner, uint256 _threshold) external {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (\n _newOwner == address(0) ||\n _newOwner == SENTINEL_OWNERS ||\n _newOwner == address(this)\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_newOwner] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n\n ms.owners[_newOwner] = ms.owners[SENTINEL_OWNERS];\n ms.owners[SENTINEL_OWNERS] = _newOwner;\n ++ms.ownerCount;\n emit OwnerAdded(_newOwner);\n\n if (ms.threshold != _threshold) changeThreshold(_threshold);\n }\n\n /**\n * @notice Remove owner from Barz. Update thresold if threshold is given different from current threshold\n * @dev This can only be done via a Self call.\n * @param _prevOwner Address of owner located right behind the removed owner address in the linked list\n * @param _removedOwner Address of owner to be removed\n * @param _threshold Uint256 value of threshold\n */\n function removeOwner(\n address _prevOwner,\n address _removedOwner,\n uint256 _threshold\n ) external {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (ms.ownerCount - 1 < _threshold)\n revert MultiSigFacet__InvalidThreshold();\n if (_removedOwner == address(0) || _removedOwner == SENTINEL_OWNERS)\n revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_prevOwner] != _removedOwner)\n revert MultiSigFacet__InvalidOwnerPair();\n\n ms.owners[_prevOwner] = ms.owners[_removedOwner];\n ms.owners[_removedOwner] = address(0);\n --ms.ownerCount;\n emit OwnerRemoved(_removedOwner);\n\n if (ms.threshold != _threshold) changeThreshold(_threshold);\n }\n\n /**\n * @notice Swap owner in Barz.\n * @dev This can only be done via a Self call.\n * @param _prevOwner Address of owner located right behind the removed owner address in the linked list\n * @param _oldOwner Address of owner to be removed\n * @param _newOwner Address of owner to be added\n */\n function swapOwner(\n address _prevOwner,\n address _oldOwner,\n address _newOwner\n ) public {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (\n _newOwner == address(0) ||\n _newOwner == SENTINEL_OWNERS ||\n _newOwner == address(this)\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_newOwner] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n if (_oldOwner == address(0) || _oldOwner == SENTINEL_OWNERS)\n revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_prevOwner] != _oldOwner)\n revert MultiSigFacet__InvalidOwnerPair();\n\n ms.owners[_newOwner] = ms.owners[_oldOwner];\n ms.owners[_prevOwner] = _newOwner;\n ms.owners[_oldOwner] = address(0);\n emit OwnerRemoved(_oldOwner);\n emit OwnerAdded(_newOwner);\n }\n\n /**\n * @notice Changes the threshold of the Barz to `_threshold`.\n * @dev This can only be done via a Self call.\n * @param _threshold New threshold\n */\n function changeThreshold(uint256 _threshold) public {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (_threshold > ms.ownerCount || _threshold == 0)\n revert MultiSigFacet__InvalidThreshold();\n\n ms.threshold = _threshold;\n emit ThresholdChanged(_threshold);\n }\n\n /**\n * @notice Checks if the given address is owner\n * @param _owner Address to be checked if it's owner\n * @return isOwner_ Bool value showing if it's owner address\n */\n function isOwner(address _owner) public view returns (bool isOwner_) {\n isOwner_ = (_owner != SENTINEL_OWNERS &&\n LibMultiSigStorage.multisigStorage().owners[_owner] != address(0));\n }\n\n /**\n * @notice Returns the threshold of Barz\n * @return threshold Threshold of the Barz account\n */\n function getThreshold() public view returns (uint256 threshold) {\n threshold = LibMultiSigStorage.multisigStorage().threshold;\n }\n\n /**\n * @notice Returns the list of owner addresses\n * @return owners List of owners\n */\n function getOwners() public view returns (address[] memory owners) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n owners = new address[](ms.ownerCount);\n\n uint256 index;\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n while (currentOwner != SENTINEL_OWNERS) {\n owners[index] = currentOwner;\n currentOwner = ms.owners[currentOwner];\n index++;\n }\n }\n\n /**\n * @notice Returns the previous owner in the linked list\n * @param _owner Address of owner\n * @return prevOwner Address of previous owner\n */\n function getPrevOwner(\n address _owner\n ) public view returns (address prevOwner) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n if (currentOwner == _owner) return SENTINEL_OWNERS;\n while (currentOwner != SENTINEL_OWNERS) {\n if (ms.owners[currentOwner] == _owner) return currentOwner;\n\n currentOwner = ms.owners[currentOwner];\n }\n return address(0);\n }\n\n /**\n * @notice Returns of the owner is approved by given owner address\n * @param _owner Address of owner\n * @param _hash Hash of UserOperation\n * @return isApproved Bool value showing if the hash is approved by owner\n */\n function isApprovedHash(\n address _owner,\n bytes32 _hash\n ) public view returns (bool isApproved) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n isApproved = (ms.approvedHashes[ms.counter][_owner][_hash] == 1);\n }\n}\n" + }, + "contracts/facets/verification/secp256k1/Secp256k1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {UserOperation} from \"../../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibAppStorage} from \"../../../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, Secp256k1VerificationStorage} from \"../../../libraries/LibFacetStorage.sol\";\nimport {LibLoupe} from \"../../../libraries/LibLoupe.sol\";\nimport {IERC1271} from \"../../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../../interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Secp256k1 verification facet\n * @dev Default Ethereum's elliptic curve\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract Secp256k1VerificationFacet is IVerificationFacet, IERC1271 {\n using ECDSA for bytes32;\n error Secp256k1VerificationFacet__InvalidSignerLength();\n address public immutable self;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in K1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\n * @param _publicKey Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _publicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n if (!isValidKeyType(_publicKey))\n revert Secp256k1VerificationFacet__InvalidSignerLength();\n\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(uint160(uint256(keccak256(_publicKey[1:]))));\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_publicKey);\n }\n\n /**\n * @notice Uninitialize signer in K1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\n * signer public key.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n validationData = validateSignature(\n userOp,\n userOpHash,\n k1Storage.signer\n );\n }\n\n /**\n * @notice Validates if the signature of UserOperation is signed by the given signer\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @param signer Address of signer who signed the contract, to be validated\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n address signer\n ) public pure returns (uint256 isValid) {\n bytes32 hash = userOpHash.toEthSignedMessageHash();\n isValid = (signer != hash.recover(userOp.signature)) ? 1 : 0;\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n ownerSignatureValidatorSelector = this.validateOwnerSignature.selector;\n // NOTE: The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory signer) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n signer = abi.encodePacked(k1Storage.signer);\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key length should be 65 in an uncompressed public key format\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (_hash.recover(_signature) ==\n LibFacetStorage.k1Storage().signer)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/Secp256r1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {UserOperation} from \"../../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibAppStorage} from \"../../../libraries/LibAppStorage.sol\";\nimport {LibLoupe} from \"../../../libraries/LibLoupe.sol\";\nimport {LibFacetStorage, Secp256r1VerificationStorage} from \"../../../libraries/LibFacetStorage.sol\";\nimport {Base64} from \"./utils/Base64.sol\";\nimport {LibSecp256r1} from \"./utils/LibSecp256r1.sol\";\nimport {IERC1271} from \"../../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../../interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Secp256r1 verification facet\n * @dev Primarily used to verify user ops signed with passkeys\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract Secp256r1VerificationFacet is IVerificationFacet, IERC1271 {\n error Secp256r1VerificationFacet__InvalidSignerLength();\n address public immutable self;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in R1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\n * @param _publicKey Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _publicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n\n if (!isValidKeyType(_publicKey))\n revert Secp256r1VerificationFacet__InvalidSignerLength();\n\n bytes memory publicKeyCoordinates = _publicKey[1:];\n uint256[2] memory q;\n assembly {\n // Copy the bytes from the input data into the uint256 array\n mstore(q, mload(add(publicKeyCoordinates, 32)))\n mstore(add(q, 32), mload(add(publicKeyCoordinates, 64)))\n }\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n r1Storage.q = q;\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_publicKey);\n }\n\n /**\n * @notice Uninitialize signer in R1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n r1Storage.q = [0, 0];\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\n * signer public key.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n validationData = validateSignature(userOp, userOpHash, r1Storage.q);\n }\n\n /**\n * @notice Validates if the signature of UserOperation is signed by the given signer\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @param q Public Key of signer who signed the contract, to be validated\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256[2] memory q\n ) public view returns (uint256 isValid) {\n isValid = (_validateSignature(q, userOpHash, userOp.signature)) ? 0 : 1;\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n return this.validateOwnerSignature.selector; // validateOwnerSignature(UserOperation calldata userOp,bytes32 userOpHash)\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory signer) {\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n signer = abi.encodePacked(r1Storage.q);\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key should in an uncompressed public key format\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = _validateSignature(\n LibFacetStorage.r1Storage().q,\n _hash,\n _signature\n )\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n\n function _validateSignature(\n uint256[2] memory q,\n bytes32 _hash,\n bytes memory _signature\n ) internal view returns (bool) {\n (\n uint256 rValue,\n uint256 sValue,\n bytes memory authenticatorData,\n string memory clientDataJSONPre,\n string memory clientDataJSONPost\n ) = abi.decode(_signature, (uint256, uint256, bytes, string, string));\n bytes32 clientHash;\n {\n string memory opHashBase64 = Base64.encode(bytes.concat(_hash));\n string memory clientDataJSON = string.concat(\n clientDataJSONPre,\n opHashBase64,\n clientDataJSONPost\n );\n clientHash = sha256(bytes(clientDataJSON));\n }\n bytes32 sigHash = sha256(bytes.concat(authenticatorData, clientHash));\n return LibSecp256r1.Verify(q, rValue, sValue, uint256(sigHash));\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/utils/Base64.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @dev Provides a set of functions to operate with Base64 strings.\n * modified for base64url https://datatracker.ietf.org/doc/html/rfc4648#section-5\n * _Available since v4.5._\n */\nlibrary Base64 {\n /**\n * @dev Base64 Encoding/Decoding Table\n */\n string internal constant _TABLE =\n \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_\";\n\n /**\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\n */\n function encode(bytes memory data) internal pure returns (string memory) {\n /**\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\n */\n if (data.length == 0) return \"\";\n\n // Loads the table into memory\n string memory table = _TABLE;\n\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\n // and split into 4 numbers of 6 bits.\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\n // - `data.length + 2` -> Round up\n // - `/ 3` -> Number of 3-bytes chunks\n // - `4 *` -> 4 characters for each chunk\n uint256 newlength = (data.length * 8) / 6;\n if (data.length % 6 > 0) {\n newlength++;\n }\n string memory result = new string(newlength);\n\n /// @solidity memory-safe-assembly\n assembly {\n // Prepare the lookup table (skip the first \"length\" byte)\n let tablePtr := add(table, 1)\n\n // Prepare result pointer, jump over length\n let resultPtr := add(result, 32)\n\n // Run over the input, 3 bytes at a time\n for {\n let dataPtr := data\n let endPtr := add(data, mload(data))\n } lt(dataPtr, endPtr) {\n\n } {\n // Advance 3 bytes\n dataPtr := add(dataPtr, 3)\n let input := mload(dataPtr)\n\n // To write each character, shift the 3 bytes (18 bits) chunk\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\n // and apply logical AND with 0x3F which is the number of\n // the previous character in the ASCII table prior to the Base64 Table\n // The result is then added to the table to get the character to write,\n // and finally write it in the result pointer but with a left shift\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(18, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(12, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(6, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n }\n }\n\n return result;\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/utils/LibSecp256r1.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n// Heavily inspired from\n// https://github.com/maxrobot/elliptic-solidity/blob/master/contracts/Secp256r1.sol\n// https://github.com/tdrerup/elliptic-curve-solidity/blob/master/contracts/curves/EllipticCurve.sol\n// modified to use precompile 0x05 modexp\n// and modified jacobian double\n// optimisations to avoid to an from from affine and jacobian coordinates\n\n// Additional Elliptic curve Public key / Signature validation added by\n// David Yonjun Kim (@Powerstream3604)\n\nstruct JPoint {\n uint256 x;\n uint256 y;\n uint256 z;\n}\n\nlibrary LibSecp256r1 {\n uint256 constant gx =\n 0x6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296;\n uint256 constant gy =\n 0x4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5;\n uint256 public constant pp =\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF;\n\n uint256 public constant nn =\n 0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551;\n uint256 constant a =\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC;\n uint256 constant b =\n 0x5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B;\n uint256 constant MOST_SIGNIFICANT =\n 0xc000000000000000000000000000000000000000000000000000000000000000;\n\n /*\n * Verify\n * @description - verifies that a public key has signed a given message\n * @param Q - public key coordinates X & Y\n * @param R - signature half R\n * @param S - signature half S\n * @param input - hashed message\n */\n function Verify(\n uint256[2] memory q,\n uint r,\n uint s,\n uint e\n ) internal view returns (bool) {\n if (q[0] > pp - 1 || q[1] > pp - 1) {\n return false;\n }\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\n return false;\n }\n if (\n mulmod(q[1], q[1], pp) !=\n addmod(\n addmod(\n mulmod(q[0], mulmod(q[0], q[0], pp), pp),\n mulmod(a, q[0], pp),\n pp\n ),\n b,\n pp\n )\n ) {\n return false;\n }\n\n JPoint[16] memory points = _preComputeJacobianPoints(q);\n return VerifyWithPrecompute(points, r, s, e);\n }\n\n function VerifyWithPrecompute(\n JPoint[16] memory points,\n uint r,\n uint s,\n uint e\n ) internal view returns (bool) {\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\n return false;\n }\n\n uint w = _primemod(s, nn);\n\n uint u1 = mulmod(e, w, nn);\n uint u2 = mulmod(r, w, nn);\n\n uint x;\n uint y;\n\n (x, y) = ShamirMultJacobian(points, u1, u2);\n return (x == r);\n }\n\n /*\n * Strauss Shamir trick for EC multiplication\n * https://stackoverflow.com/questions/50993471/ec-scalar-multiplication-with-strauss-shamir-method\n * we optimise on this a bit to do with 2 bits at a time rather than a single bit\n * the individual points for a single pass are precomputed\n * overall this reduces the number of additions while keeping the same number of doublings\n */\n function ShamirMultJacobian(\n JPoint[16] memory points,\n uint u1,\n uint u2\n ) internal view returns (uint, uint) {\n uint x = 0;\n uint y = 0;\n uint z = 0;\n uint bits = 128;\n uint index = 0;\n\n while (bits > 0) {\n if (z > 0) {\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\n }\n index =\n ((u1 & MOST_SIGNIFICANT) >> 252) |\n ((u2 & MOST_SIGNIFICANT) >> 254);\n if (index > 0) {\n (x, y, z) = _jAdd(\n x,\n y,\n z,\n points[index].x,\n points[index].y,\n points[index].z\n );\n }\n u1 <<= 2;\n u2 <<= 2;\n bits--;\n }\n (x, y) = _affineFromJacobian(x, y, z);\n return (x, y);\n }\n\n function _preComputeJacobianPoints(\n uint256[2] memory q\n ) internal pure returns (JPoint[16] memory points) {\n points[0] = JPoint(0, 0, 0);\n points[1] = JPoint(q[0], q[1], 1); // u2\n points[2] = _jPointDouble(points[1]);\n points[3] = _jPointAdd(points[1], points[2]);\n\n points[4] = JPoint(gx, gy, 1); // u1Points[1]\n points[5] = _jPointAdd(points[4], points[1]);\n points[6] = _jPointAdd(points[4], points[2]);\n points[7] = _jPointAdd(points[4], points[3]);\n\n points[8] = _jPointDouble(points[4]); // u1Points[2]\n points[9] = _jPointAdd(points[8], points[1]);\n points[10] = _jPointAdd(points[8], points[2]);\n points[11] = _jPointAdd(points[8], points[3]);\n\n points[12] = _jPointAdd(points[4], points[8]); // u1Points[3]\n points[13] = _jPointAdd(points[12], points[1]);\n points[14] = _jPointAdd(points[12], points[2]);\n points[15] = _jPointAdd(points[12], points[3]);\n }\n\n function _jPointAdd(\n JPoint memory p1,\n JPoint memory p2\n ) internal pure returns (JPoint memory) {\n uint x;\n uint y;\n uint z;\n (x, y, z) = _jAdd(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z);\n return JPoint(x, y, z);\n }\n\n function _jPointDouble(\n JPoint memory p\n ) internal pure returns (JPoint memory) {\n uint x;\n uint y;\n uint z;\n (x, y, z) = _modifiedJacobianDouble(p.x, p.y, p.z);\n return JPoint(x, y, z);\n }\n\n /* _affineFromJacobian\n * @desription returns affine coordinates from a jacobian input follows\n * golang elliptic/crypto library\n */\n function _affineFromJacobian(\n uint x,\n uint y,\n uint z\n ) internal view returns (uint ax, uint ay) {\n if (z == 0) {\n return (0, 0);\n }\n\n uint zinv = _primemod(z, pp);\n uint zinvsq = mulmod(zinv, zinv, pp);\n\n ax = mulmod(x, zinvsq, pp);\n ay = mulmod(y, mulmod(zinvsq, zinv, pp), pp);\n }\n\n /*\n * _jAdd\n * @description performs Jacobian addition as defined below:\n * http://www.hyperelliptic.org/EFD/g1p/data/shortw/jacobian/addition/add-2007-bl\n */\n function _jAdd(\n uint p1,\n uint p2,\n uint p3,\n uint q1,\n uint q2,\n uint q3\n ) internal pure returns (uint r1, uint r2, uint r3) {\n if (p3 == 0) {\n r1 = q1;\n r2 = q2;\n r3 = q3;\n\n return (r1, r2, r3);\n } else if (q3 == 0) {\n r1 = p1;\n r2 = p2;\n r3 = p3;\n\n return (r1, r2, r3);\n }\n\n assembly {\n let\n pd\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\n let z1z1 := mulmod(p3, p3, pd) // Z1Z1 = Z1^2\n let z2z2 := mulmod(q3, q3, pd) // Z2Z2 = Z2^2\n\n let u1 := mulmod(p1, z2z2, pd) // U1 = X1*Z2Z2\n let u2 := mulmod(q1, z1z1, pd) // U2 = X2*Z1Z1\n\n let s1 := mulmod(p2, mulmod(z2z2, q3, pd), pd) // S1 = Y1*Z2*Z2Z2\n let s2 := mulmod(q2, mulmod(z1z1, p3, pd), pd) // S2 = Y2*Z1*Z1Z1\n\n let p3q3 := addmod(p3, q3, pd)\n\n if lt(u2, u1) {\n u2 := add(pd, u2) // u2 = u2+pd\n }\n let h := sub(u2, u1) // H = U2-U1\n\n let i := mulmod(0x02, h, pd)\n i := mulmod(i, i, pd) // I = (2*H)^2\n\n let j := mulmod(h, i, pd) // J = H*I\n if lt(s2, s1) {\n s2 := add(pd, s2) // u2 = u2+pd\n }\n let rr := mulmod(0x02, sub(s2, s1), pd) // r = 2*(S2-S1)\n r1 := mulmod(rr, rr, pd) // X3 = R^2\n\n let v := mulmod(u1, i, pd) // V = U1*I\n let j2v := addmod(j, mulmod(0x02, v, pd), pd)\n if lt(r1, j2v) {\n r1 := add(pd, r1) // X3 = X3+pd\n }\n r1 := sub(r1, j2v)\n\n // Y3 = r*(V-X3)-2*S1*J\n let s12j := mulmod(mulmod(0x02, s1, pd), j, pd)\n\n if lt(v, r1) {\n v := add(pd, v)\n }\n r2 := mulmod(rr, sub(v, r1), pd)\n\n if lt(r2, s12j) {\n r2 := add(pd, r2)\n }\n r2 := sub(r2, s12j)\n\n // Z3 = ((Z1+Z2)^2-Z1Z1-Z2Z2)*H\n z1z1 := addmod(z1z1, z2z2, pd)\n j2v := mulmod(p3q3, p3q3, pd)\n if lt(j2v, z1z1) {\n j2v := add(pd, j2v)\n }\n r3 := mulmod(sub(j2v, z1z1), h, pd)\n }\n return (r1, r2, r3);\n }\n\n // Point doubling on the modified jacobian coordinates\n // http://point-at-infinity.org/ecc/Prime_Curve_Modified_Jacobian_Coordinates.html\n function _modifiedJacobianDouble(\n uint x,\n uint y,\n uint z\n ) internal pure returns (uint x3, uint y3, uint z3) {\n if (y == 0) return (0, 0, 0);\n assembly {\n let\n pd\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\n let z2 := mulmod(z, z, pd)\n let az4 := mulmod(\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC,\n mulmod(z2, z2, pd),\n pd\n )\n let y2 := mulmod(y, y, pd)\n let s := mulmod(0x04, mulmod(x, y2, pd), pd)\n let u := mulmod(0x08, mulmod(y2, y2, pd), pd)\n let m := addmod(mulmod(0x03, mulmod(x, x, pd), pd), az4, pd)\n let twos := mulmod(0x02, s, pd)\n let m2 := mulmod(m, m, pd)\n if lt(m2, twos) {\n m2 := add(pd, m2)\n }\n x3 := sub(m2, twos)\n if lt(s, x3) {\n s := add(pd, s)\n }\n y3 := mulmod(m, sub(s, x3), pd)\n if lt(y3, u) {\n y3 := add(pd, y3)\n }\n y3 := sub(y3, u)\n z3 := mulmod(0x02, mulmod(y, z, pd), pd)\n }\n }\n\n // Fermats little theorem https://en.wikipedia.org/wiki/Fermat%27s_little_theorem\n // a^(p-1) = 1 mod p\n // a^(-1) ≅ a^(p-2) (mod p)\n // we then use the precompile bigModExp to compute a^(-1)\n function _primemod(uint value, uint p) internal view returns (uint ret) {\n ret = modexp(value, p - 2, p);\n return ret;\n }\n\n // Wrapper for built-in BigNumber_modexp (contract 0x5) as described here. https://github.com/ethereum/EIPs/pull/198\n function modexp(\n uint _base,\n uint _exp,\n uint _mod\n ) internal view returns (uint ret) {\n // bigModExp(_base, _exp, _mod);\n assembly {\n if gt(_base, _mod) {\n _base := mod(_base, _mod)\n }\n // Free memory pointer is always stored at 0x40\n let freemem := mload(0x40)\n\n mstore(freemem, 0x20)\n mstore(add(freemem, 0x20), 0x20)\n mstore(add(freemem, 0x40), 0x20)\n\n mstore(add(freemem, 0x60), _base)\n mstore(add(freemem, 0x80), _exp)\n mstore(add(freemem, 0xa0), _mod)\n\n let success := staticcall(14000, 0x5, freemem, 0xc0, freemem, 0x20)\n switch success\n case 0 {\n revert(0x0, 0x0)\n }\n default {\n ret := mload(freemem)\n }\n }\n }\n}\n" + }, + "contracts/infrastructure/DefaultFallbackHandler.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC1155Receiver} from \"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\";\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {BaseAccount} from \"../aa-4337/core/BaseAccount.sol\";\nimport {DefaultLibDiamond} from \"../libraries/DefaultLibDiamond.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IAccountFacet} from \"../facets/interfaces/IAccountFacet.sol\";\nimport {IStorageLoupe} from \"../facets/base/interfaces/IStorageLoupe.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IERC677Receiver} from \"../interfaces/ERC/IERC677Receiver.sol\";\nimport {IERC165} from \"../interfaces/ERC/IERC165.sol\";\n\n/**\n * @title DefaultFallbackHandler\n * @dev A default fallback handler for Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DefaultFallbackHandler is IDiamondLoupe {\n /**\n * @notice Sets the middleware diamond for Barz wallet as a fallback handler\n * @dev This contract is also a diamond that holds the default facets to reduce gas cost for wallet activation.\n * Within the constructor this conducts diamond cut to initially setup the diamond. This is a non-upgradeable contract\n * @param _diamondCutFacet Address if diamond cut facet\n * @param _accountFacet Address account facet\n * @param _tokenReceiverFacet Address of token receiver facet\n * @param _diamondLoupeFacet Address of diamond loupe facet\n */\n constructor(\n address _diamondCutFacet,\n address _accountFacet,\n address _tokenReceiverFacet,\n address _diamondLoupeFacet\n ) payable {\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](4);\n bytes4[] memory functionSelectors = new bytes4[](1);\n functionSelectors[0] = IDiamondCut.diamondCut.selector;\n\n bytes4[] memory accountFunctionSelectors = new bytes4[](5);\n accountFunctionSelectors[0] = IAccountFacet.execute.selector;\n accountFunctionSelectors[1] = IAccountFacet.executeBatch.selector;\n accountFunctionSelectors[2] = BaseAccount.validateUserOp.selector;\n accountFunctionSelectors[3] = BaseAccount.getNonce.selector;\n accountFunctionSelectors[4] = BaseAccount.entryPoint.selector;\n\n bytes4[] memory receiverFacetSelectors = new bytes4[](5);\n receiverFacetSelectors[0] = IERC721Receiver.onERC721Received.selector;\n receiverFacetSelectors[1] = IERC1155Receiver.onERC1155Received.selector;\n receiverFacetSelectors[2] = IERC1155Receiver\n .onERC1155BatchReceived\n .selector;\n receiverFacetSelectors[3] = IERC777Recipient.tokensReceived.selector;\n receiverFacetSelectors[4] = IERC677Receiver.onTokenTransfer.selector;\n\n bytes4[] memory loupeFacetSelectors = new bytes4[](9);\n loupeFacetSelectors[0] = IDiamondLoupe.facets.selector;\n loupeFacetSelectors[1] = IDiamondLoupe.facetFunctionSelectors.selector;\n loupeFacetSelectors[2] = IDiamondLoupe.facetAddresses.selector;\n loupeFacetSelectors[3] = IDiamondLoupe.facetAddress.selector;\n loupeFacetSelectors[4] = IERC165.supportsInterface.selector;\n loupeFacetSelectors[5] = IStorageLoupe.facetsFromStorage.selector;\n loupeFacetSelectors[6] = IStorageLoupe\n .facetFunctionSelectorsFromStorage\n .selector;\n loupeFacetSelectors[7] = IStorageLoupe\n .facetAddressesFromStorage\n .selector;\n loupeFacetSelectors[8] = IStorageLoupe.facetAddressFromStorage.selector;\n\n {\n cut[0] = IDiamondCut.FacetCut({\n facetAddress: _diamondCutFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: functionSelectors\n });\n cut[1] = IDiamondCut.FacetCut({\n facetAddress: _accountFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: accountFunctionSelectors\n });\n cut[2] = IDiamondCut.FacetCut({\n facetAddress: _tokenReceiverFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: receiverFacetSelectors\n });\n cut[3] = IDiamondCut.FacetCut({\n facetAddress: _diamondLoupeFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: loupeFacetSelectors\n });\n\n DefaultLibDiamond.diamondCut(cut, address(0), \"\");\n }\n }\n\n /**\n * @notice Returns the facet information of call facets registered to this diamond.\n * @return facets_ The facet struct array including all facet information\n */\n function facets() external view override returns (Facet[] memory facets_) {\n DefaultLibDiamond.DiamondStorage storage ds = DefaultLibDiamond\n .diamondStorage();\n uint256 numFacets = ds.facetAddresses.length;\n facets_ = new Facet[](numFacets);\n for (uint256 i; i < numFacets; ) {\n address facetAddress_ = ds.facetAddresses[i];\n facets_[i].facetAddress = facetAddress_;\n facets_[i].functionSelectors = ds\n .facetFunctionSelectors[facetAddress_]\n .functionSelectors;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Gets all the function selectors provided by a facet.\n * @param _facet The facet address.\n * @return facetFunctionSelectors_\n */\n function facetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n facetFunctionSelectors_ = DefaultLibDiamond\n .diamondStorage()\n .facetFunctionSelectors[_facet]\n .functionSelectors;\n }\n\n /**\n * @notice Get all the facet addresses used by a diamond.\n * @return facetAddresses_\n */\n function facetAddresses()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n facetAddresses_ = DefaultLibDiamond.diamondStorage().facetAddresses;\n }\n\n /** @notice Gets the facet that supports the given selector.\n * @dev If facet is not found return address(0).\n * @param _functionSelector The function selector.\n * @return facetAddress_ The facet address.\n */\n function facetAddress(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n facetAddress_ = DefaultLibDiamond\n .diamondStorage()\n .selectorToFacetAndPosition[_functionSelector]\n .facetAddress;\n }\n}\n" + }, + "contracts/infrastructure/FacetRegistry.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport {IFacetRegistry} from \"./interfaces/IFacetRegistry.sol\";\n\n/**\n * @title Facet Registry\n * @dev Contract to keep track of facets & function selectors addable to user wallets\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract FacetRegistry is IFacetRegistry, Ownable2Step {\n mapping(address => FacetRegistryConfig) private facets;\n\n /**\n * @notice Transfers the ownership of the contract to the given owner\n * @param _owner Address of owner who has access to initialize the default security variables for security manager\n */\n constructor(address _owner) {\n transferOwnership(_owner);\n _transferOwnership(_owner);\n }\n\n /**\n * @dev Registers a facet and it's function selectors to registry\n * @param _facet address of facet\n * @param _facetSelectors list of function selectors of the facet\n */\n function registerFacetFunctionSelectors(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external override onlyOwner {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n for (uint256 i; i < _facetSelectors.length; ) {\n if (facetConfig.info[_facetSelectors[i]].exists)\n revert FacetRegistry__FacetSelectorAlreadyRegistered();\n\n facetConfig.info[_facetSelectors[i]].exists = true;\n facetConfig.info[_facetSelectors[i]].index = uint128(\n facetConfig.selectors.length\n );\n facetConfig.selectors.push(_facetSelectors[i]);\n unchecked {\n ++i;\n }\n }\n emit FacetFunctionSelectorsRegistered(_facet, _facetSelectors);\n }\n\n /**\n * @dev Removes a registered facet and it's corresponding selectors from registry\n * @param _facet address of facet\n * @param _facetSelectors list of function selectors of the facet\n */\n function removeFacetFunctionSelectors(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external override onlyOwner {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n for (uint256 i; i < _facetSelectors.length; ) {\n if (!facetConfig.info[_facetSelectors[i]].exists)\n revert FacetRegistry__UnregisteredFacetSelector();\n\n bytes4 lastSelector = facetConfig.selectors[\n facetConfig.selectors.length - 1\n ];\n if (_facetSelectors[i] != lastSelector) {\n uint128 targetIndex = facetConfig\n .info[_facetSelectors[i]]\n .index;\n facetConfig.selectors[targetIndex] = lastSelector;\n facetConfig.info[lastSelector].index = targetIndex;\n }\n facetConfig.selectors.pop();\n delete facetConfig.info[_facetSelectors[i]];\n\n unchecked {\n ++i;\n }\n }\n emit FacetFunctionSelectorsRemoved(_facet, _facetSelectors);\n }\n\n /**\n * @dev Checks if a facet and it's selectors given is registered to facet registry\n * @param _facet Address of facet\n * @param _facetSelectors List of function selectors of the facet\n */\n function areFacetFunctionSelectorsRegistered(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external view override returns (bool) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n if (_facetSelectors.length == 0) return false;\n for (uint256 i; i < _facetSelectors.length; ) {\n if (!facetConfig.info[_facetSelectors[i]].exists) return false;\n unchecked {\n ++i;\n }\n }\n return true;\n }\n\n /**\n * @dev Checks if a facet and it's selector given is registered to facet registry\n * @param _facet Address of facet\n * @param _facetSelector List of function selectors of the facet\n * @return isRegistered Bool value showing if the selector is registered\n */\n function isFacetFunctionSelectorRegistered(\n address _facet,\n bytes4 _facetSelector\n ) external view override returns (bool isRegistered) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n isRegistered = facetConfig.info[_facetSelector].exists;\n }\n\n /**\n * @dev Get the registered selectors of facet from registry\n * @param _facet Address of facet\n * @return selectors Selectors registered to facet\n */\n function getFacetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory selectors) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n selectors = facetConfig.selectors;\n }\n}\n" + }, + "contracts/infrastructure/interfaces/IFacetRegistry.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Registry Interface\n * @dev Interface for Facet Registry contract to keep track of facets & function selectors addable to user wallets\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IFacetRegistry {\n struct FacetRegistryConfig {\n bytes4[] selectors;\n mapping(bytes4 => FacetInfo) info;\n }\n struct FacetInfo {\n bool exists;\n uint128 index;\n }\n\n event FacetFunctionSelectorsRegistered(\n address facet,\n bytes4[] facetSelectors\n );\n event FacetFunctionSelectorsRemoved(address facet, bytes4[] facetSelectors);\n\n error FacetRegistry__FacetSelectorAlreadyRegistered();\n error FacetRegistry__UnregisteredFacetSelector();\n\n function registerFacetFunctionSelectors(\n address facet,\n bytes4[] calldata facetSelectors\n ) external;\n\n function removeFacetFunctionSelectors(\n address facet,\n bytes4[] calldata facetSelectors\n ) external;\n\n function areFacetFunctionSelectorsRegistered(\n address facet,\n bytes4[] calldata facetSelectors\n ) external view returns (bool);\n\n function isFacetFunctionSelectorRegistered(\n address facet,\n bytes4 facetSelector\n ) external view returns (bool);\n\n function getFacetFunctionSelectors(\n address facet\n ) external view returns (bytes4[] memory);\n}\n" + }, + "contracts/infrastructure/interfaces/ISecurityManager.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Registry Interface\n * @dev Infrastructure contract to manage security parameters of users\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface ISecurityManager {\n error SecurityManager__OutOfBoundary();\n error SecurityManager__CallerNotWallet();\n error SecurityManager__AlreadyIntialized();\n\n function initializeAdditionSecurityPeriod(\n uint128 defaultAdditionSecurityPeriod,\n uint128 minAdditionSecurityPeriod,\n uint128 maxAdditionSecurityPeriod\n ) external;\n\n function initializeRemovalSecurityPeriod(\n uint128 defaultRemovalSecurityPeriod,\n uint128 minRemovalSecurityPeriod,\n uint128 maxRemovalSecurityPeriod\n ) external;\n\n function initializeApprovalValidationPeriod(\n uint128 defaultApprovalValidationPeriod,\n uint128 minApprovalValidationPeriod,\n uint128 maxApprovalValidationPeriod\n ) external;\n\n function initializeMigrationPeriod(\n uint128 defaultMigrationPeriod,\n uint128 minMigrationPeriod,\n uint128 maxMigrationPeriod\n ) external;\n\n function initializeLockPeriod(\n uint128 defaultLockPeriod,\n uint128 minLockPeriod,\n uint128 maxLockPeriod\n ) external;\n\n function initializeRecoveryPeriod(\n uint128 defaultRecoveryPeriod,\n uint128 minRecoveryPeriod,\n uint128 maxRecoveryPeriod\n ) external;\n\n function initializeSecurityWindow(\n uint128 defaultSecurityWindow,\n uint128 minSecurityWindow,\n uint128 maxSecurityWindow\n ) external;\n\n function setAdditionSecurityPeriod(\n address wallet,\n uint128 additionSecurityPeriod\n ) external;\n\n function setRemovalSecurityPeriod(\n address wallet,\n uint128 removalSecurityPeriod\n ) external;\n\n function setSecurityWindow(address wallet, uint128 securityWindow) external;\n\n function setRecoveryPeriod(address wallet, uint128 recoveryPeriod) external;\n\n function setLockPeriod(address wallet, uint128 lockPeriod) external;\n\n function setApprovalValidationPeriod(\n address wallet,\n uint128 approvalValidationPeriod\n ) external;\n\n function setMigrationPeriod(\n address wallet,\n uint128 migrationPeriod\n ) external;\n\n function additionSecurityPeriodOf(\n address wallet\n ) external view returns (uint128);\n\n function removalSecurityPeriodOf(\n address wallet\n ) external view returns (uint128);\n\n function securityWindowOf(address wallet) external view returns (uint128);\n\n function recoveryPeriodOf(address wallet) external view returns (uint128);\n\n function lockPeriodOf(address wallet) external view returns (uint128);\n\n function migrationPeriodOf(address wallet) external view returns (uint128);\n\n function approvalValidationPeriodOf(\n address wallet\n ) external view returns (uint128);\n}\n" + }, + "contracts/infrastructure/RemoteStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IGuardianFacet} from \"../facets/interfaces/IGuardianFacet.sol\";\n\n/**\n * @title Remote Storage\n * @dev Remote storage allows you to associate addresses with an array of addresses on a standalone smart contract.\n * This could be useful when you don't want to use the local diamond storage for some purpose.\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\nabstract contract RemoteStorage {\n struct StorageConfig {\n address[] addresses;\n mapping(address => Info) info;\n }\n\n struct Info {\n bool exists;\n uint128 index;\n }\n\n mapping(address => StorageConfig) internal configs;\n\n event Added(address _address);\n event Removed(address _address);\n\n error RemoteStorage__CallerNotOwner();\n error RemoteStorage__CallerNotGuardianOrOwner();\n error RemoteStorage__AlreadyExists();\n error RemoteStorage__NotFound();\n error RemoteStorage__CallerNotGuardian();\n\n bytes4 constant IS_GUARDIAN_SELECTOR =\n bytes4(keccak256(\"isGuardian(address)\"));\n bytes4 constant GUARDIAN_COUNT = bytes4(keccak256(\"guardianCount()\"));\n\n /**\n * @notice Modifier to only allow the self to call. Reverts otherwise\n */\n modifier onlyWallet(address _wallet) {\n if (msg.sender != _wallet) revert RemoteStorage__CallerNotOwner();\n _;\n }\n\n /**\n * @notice Enfore the callet to be wallet of guardian of the wallet\n * @param _wallet Address of wallet\n */\n function enforceGuardianOrWallet(address _wallet) internal view {\n if (msg.sender == _wallet) return;\n address facetAddress = IDiamondLoupe(_wallet).facetAddress(\n IS_GUARDIAN_SELECTOR\n );\n if (facetAddress != address(0))\n if (IGuardianFacet(_wallet).isGuardian(msg.sender)) return;\n revert RemoteStorage__CallerNotGuardianOrOwner();\n }\n\n /**\n * @notice Enforce the caller to be wallet IF guardians doesn't exists and only guardian when guardians exists\n * @param _wallet Target wallet address to be handled by infrastructure contracts\n */\n function enforceWalletOrGuardianIfExists(address _wallet) internal view {\n address facetAddress;\n if (msg.sender == _wallet) {\n facetAddress = IDiamondLoupe(_wallet).facetAddress(GUARDIAN_COUNT);\n if (facetAddress == address(0)) return;\n uint256 guardianCount = IGuardianFacet(_wallet).guardianCount();\n if (guardianCount != 0) revert RemoteStorage__CallerNotGuardian();\n return;\n }\n facetAddress = IDiamondLoupe(_wallet).facetAddress(\n IS_GUARDIAN_SELECTOR\n );\n if (facetAddress != address(0))\n if (IGuardianFacet(_wallet).isGuardian(msg.sender)) return;\n\n revert RemoteStorage__CallerNotGuardianOrOwner();\n }\n\n /**\n * @notice Add address to storage and reverts if the address already exists.\n * This is an internal function callable from contracts that inherit this abstract contract\n * @param _wallet Address of wallet to add the address\n * @param _address Address to be added to wallet\n */\n function addAddress(address _wallet, address _address) internal {\n StorageConfig storage config = configs[_wallet];\n if (config.info[_address].exists) revert RemoteStorage__AlreadyExists();\n\n config.info[_address].exists = true;\n config.info[_address].index = uint128(config.addresses.length);\n config.addresses.push(_address);\n\n emit Added(_address);\n }\n\n /**\n * @notice Remove address from storage and reverts if the address already exists.\n * This is an internal function callable from contracts that inherit this abstract contract\n * @param _wallet Address of wallet to remove the address\n * @param _address Address to be removed from wallet\n */\n function removeAddress(address _wallet, address _address) internal {\n StorageConfig storage config = configs[_wallet];\n if (!config.info[_address].exists) revert RemoteStorage__NotFound();\n\n address lastAddress = config.addresses[config.addresses.length - 1];\n if (_address != lastAddress) {\n uint128 targetIndex = config.info[_address].index;\n config.addresses[targetIndex] = lastAddress;\n config.info[lastAddress].index = targetIndex;\n }\n config.addresses.pop();\n delete config.info[_address];\n\n emit Removed(_address);\n }\n\n /**\n * @notice Returns the address added to the given wallet\n * @param _wallet Address of wallet to fetch the addresses added to it\n * @return addresses List of addresses added to the wallet\n */\n function getAddresses(\n address _wallet\n ) internal view returns (address[] memory addresses) {\n StorageConfig storage config = configs[_wallet];\n addresses = new address[](config.addresses.length);\n uint addressesLen = config.addresses.length;\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns bool value checking if the address exists in the given wallet address\n * @param _wallet Wallet address to check\n * @param _address Address to fetch if the address if added to given wallet\n * @return exists_ Bool value showing if the address exists in wallet\n */\n function exists(\n address _wallet,\n address _address\n ) internal view returns (bool exists_) {\n exists_ = configs[_wallet].info[_address].exists;\n }\n\n /**\n * @notice Returns the number of addresses added to the wallet\n * @param _wallet Address of wallet to check\n * @return count_ Number of addresses added to wallet\n */\n function count(address _wallet) internal view returns (uint256 count_) {\n count_ = configs[_wallet].addresses.length;\n }\n}\n" + }, + "contracts/infrastructure/SecurityManager.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport {ISecurityManager} from \"./interfaces/ISecurityManager.sol\";\n\n/**\n * @title Security Manager\n * @dev Infrastructure contract to manage security parameters of users\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract SecurityManager is ISecurityManager, Ownable2Step {\n uint128 public minAdditionSecurityPeriod;\n uint128 public maxAdditionSecurityPeriod;\n uint128 private defaultAdditionSecurityPeriod;\n\n uint128 public minRemovalSecurityPeriod;\n uint128 public maxRemovalSecurityPeriod;\n uint128 private defaultRemovalSecurityPeriod;\n\n uint128 public minSecurityWindow;\n uint128 public maxSecurityWindow;\n uint128 private defaultSecurityWindow;\n\n uint128 public minRecoveryPeriod;\n uint128 public maxRecoveryPeriod;\n uint128 private defaultRecoveryPeriod;\n\n uint128 public minLockPeriod;\n uint128 public maxLockPeriod;\n uint128 private defaultLockPeriod;\n\n uint128 public minApprovalValidationPeriod;\n uint128 public maxApprovalValidationPeriod;\n uint128 private defaultApprovalValidationPeriod;\n\n uint128 public minMigrationPeriod;\n uint128 public maxMigrationPeriod;\n uint128 private defaultMigrationPeriod;\n\n bool public _isAdditionSecurityPeriodInitialized;\n bool public _isRemovalSecurityPeriodInitialized;\n bool public _isSecurityWindowInitialized;\n bool public _isRecoveryPeriodInitialized;\n bool public _isLockPeriodInitialized;\n bool public _isApprovalValidationPeriodInitialized;\n bool public _isMigrationPeriodInitialized;\n\n mapping(address => CustomSecurityConfig) securityConfigs;\n\n struct CustomSecurityConfig {\n uint128 additionSecurityPeriod;\n uint128 removalSecurityPeriod;\n uint128 securityWindow;\n uint128 recoveryPeriod;\n uint128 lockPeriod;\n uint128 approvalValidationPeriod;\n uint128 migrationPeriod;\n }\n\n /**\n * @notice Modifier to only allow wallet itself to make a call to wallet\n */\n modifier onlyWallet(address _wallet) {\n if (msg.sender != _wallet) revert SecurityManager__CallerNotWallet();\n _;\n }\n\n /**\n * @notice Modifier to revert if the variable is already initialized\n */\n modifier initializer(bool _isInitialized) {\n if (_isInitialized) revert SecurityManager__AlreadyIntialized();\n _;\n }\n\n /**\n * @notice Transfers the ownership of the contract to the given owner\n * @param _owner Address of owner who has access to initialize the default security variables for security manager\n */\n constructor(address _owner) {\n transferOwnership(_owner);\n _transferOwnership(_owner);\n }\n\n /**\n * @notice Sets the initial default/min/max addition security period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultAdditionSecurityPeriod Default Addition Security Period for all Barz contracts\n * @param _minAdditionSecurityPeriod Minimum Addition Security Period for all Barz contracts\n * @param _maxAdditionSecurityPeriod Maximum Addition Security Period for all Barz contracts\n */\n function initializeAdditionSecurityPeriod(\n uint128 _defaultAdditionSecurityPeriod,\n uint128 _minAdditionSecurityPeriod,\n uint128 _maxAdditionSecurityPeriod\n )\n external\n override\n onlyOwner\n initializer(_isAdditionSecurityPeriodInitialized)\n {\n _isAdditionSecurityPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultAdditionSecurityPeriod,\n _minAdditionSecurityPeriod,\n _maxAdditionSecurityPeriod\n );\n defaultAdditionSecurityPeriod = _defaultAdditionSecurityPeriod;\n minAdditionSecurityPeriod = _minAdditionSecurityPeriod;\n maxAdditionSecurityPeriod = _maxAdditionSecurityPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max removal security period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultRemovalSecurityPeriod Default Removal Security Period for all Barz contracts\n * @param _minRemovalSecurityPeriod Minimum Removal Security Period for all Barz contracts\n * @param _maxRemovalSecurityPeriod Maximum Removal Security Period for all Barz contracts\n */\n function initializeRemovalSecurityPeriod(\n uint128 _defaultRemovalSecurityPeriod,\n uint128 _minRemovalSecurityPeriod,\n uint128 _maxRemovalSecurityPeriod\n )\n external\n override\n onlyOwner\n initializer(_isRemovalSecurityPeriodInitialized)\n {\n _isRemovalSecurityPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultRemovalSecurityPeriod,\n _minRemovalSecurityPeriod,\n _maxRemovalSecurityPeriod\n );\n defaultRemovalSecurityPeriod = _defaultRemovalSecurityPeriod;\n minRemovalSecurityPeriod = _minRemovalSecurityPeriod;\n maxRemovalSecurityPeriod = _maxRemovalSecurityPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/maxd security window for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultSecurityWindow Default Security Window for all Barz contracts\n * @param _minSecurityWindow Minimum Security Window for all Barz contracts\n * @param _maxSecurityWindow Maximum Security Window for all Barz contracts\n */\n function initializeSecurityWindow(\n uint128 _defaultSecurityWindow,\n uint128 _minSecurityWindow,\n uint128 _maxSecurityWindow\n ) external override onlyOwner initializer(_isSecurityWindowInitialized) {\n _isSecurityWindowInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultSecurityWindow,\n _minSecurityWindow,\n _maxSecurityWindow\n );\n defaultSecurityWindow = _defaultSecurityWindow;\n minSecurityWindow = _minSecurityWindow;\n maxSecurityWindow = _maxSecurityWindow;\n }\n\n /**\n * @notice Sets the initial default/min/max recovery period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultRecoveryPeriod Default Recovery Period for all Barz contracts\n * @param _minRecoveryPeriod Minimum Recovery Period for all Barz contracts\n * @param _maxRecoveryPeriod Maximum Recovery Period for all Barz contracts\n */\n function initializeRecoveryPeriod(\n uint128 _defaultRecoveryPeriod,\n uint128 _minRecoveryPeriod,\n uint128 _maxRecoveryPeriod\n ) external override onlyOwner initializer(_isRecoveryPeriodInitialized) {\n _isRecoveryPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultRecoveryPeriod,\n _minRecoveryPeriod,\n _maxRecoveryPeriod\n );\n defaultRecoveryPeriod = _defaultRecoveryPeriod;\n minRecoveryPeriod = _minRecoveryPeriod;\n maxRecoveryPeriod = _maxRecoveryPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max lock period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultLockPeriod Default Lock Period for all Barz contracts\n * @param _minLockPeriod Minimum Lock Period for all Barz contracts\n * @param _maxLockPeriod Maximum Lock Period for all Barz contracts\n */\n function initializeLockPeriod(\n uint128 _defaultLockPeriod,\n uint128 _minLockPeriod,\n uint128 _maxLockPeriod\n ) external override onlyOwner initializer(_isLockPeriodInitialized) {\n _isLockPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultLockPeriod,\n _minLockPeriod,\n _maxLockPeriod\n );\n defaultLockPeriod = _defaultLockPeriod;\n minLockPeriod = _minLockPeriod;\n maxLockPeriod = _maxLockPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max approval validation period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultApprovalValidationPeriod Default Approval Validation Period for all Barz contracts\n * @param _minApprovalValidationPeriod Minimum Approval Validation Period for all Barz contracts\n * @param _maxApprovalValidationPeriod Maximum Approval Validation Period for all Barz contracts\n */\n function initializeApprovalValidationPeriod(\n uint128 _defaultApprovalValidationPeriod,\n uint128 _minApprovalValidationPeriod,\n uint128 _maxApprovalValidationPeriod\n )\n external\n override\n onlyOwner\n initializer(_isApprovalValidationPeriodInitialized)\n {\n _isApprovalValidationPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultApprovalValidationPeriod,\n _minApprovalValidationPeriod,\n _maxApprovalValidationPeriod\n );\n defaultApprovalValidationPeriod = _defaultApprovalValidationPeriod;\n minApprovalValidationPeriod = _minApprovalValidationPeriod;\n maxApprovalValidationPeriod = _maxApprovalValidationPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max migration period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultMigrationPeriod Default Migration Period for all Barz contracts\n * @param _minMigrationPeriod Minimum Migration Period for all Barz contracts\n * @param _maxMigrationPeriod Maximum Migration Period for all Barz contracts\n */\n function initializeMigrationPeriod(\n uint128 _defaultMigrationPeriod,\n uint128 _minMigrationPeriod,\n uint128 _maxMigrationPeriod\n ) external override onlyOwner initializer(_isMigrationPeriodInitialized) {\n _isMigrationPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultMigrationPeriod,\n _minMigrationPeriod,\n _maxMigrationPeriod\n );\n defaultMigrationPeriod = _defaultMigrationPeriod;\n minMigrationPeriod = _minMigrationPeriod;\n maxMigrationPeriod = _maxMigrationPeriod;\n }\n\n /**\n * @notice Wallet owner sets the addition security period for the wallet. Only the owner of wallet can call this function.\n * The addition security period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _additionSecurityPeriod Custom Addition Security Period for the wallet\n */\n function setAdditionSecurityPeriod(\n address _wallet,\n uint128 _additionSecurityPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _additionSecurityPeriod,\n minAdditionSecurityPeriod,\n maxAdditionSecurityPeriod\n );\n securityConfigs[_wallet]\n .additionSecurityPeriod = _additionSecurityPeriod;\n }\n\n /**\n * @notice Wallet owner sets the removal security period for the wallet. Only the owner of wallet can call this function.\n * The removal security period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _removalSecurityPeriod Custom Removal Security Period for the wallet\n */\n function setRemovalSecurityPeriod(\n address _wallet,\n uint128 _removalSecurityPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _removalSecurityPeriod,\n minRemovalSecurityPeriod,\n maxRemovalSecurityPeriod\n );\n securityConfigs[_wallet].removalSecurityPeriod = _removalSecurityPeriod;\n }\n\n /**\n * @notice Wallet owner sets the security window for the wallet. Only the owner of wallet can call this function.\n * The security window should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _securityWindow Custom Security Window for the wallet\n */\n function setSecurityWindow(\n address _wallet,\n uint128 _securityWindow\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _securityWindow,\n minSecurityWindow,\n maxSecurityWindow\n );\n securityConfigs[_wallet].securityWindow = _securityWindow;\n }\n\n /**\n * @notice Wallet owner sets the recovery period for the wallet. Only the owner of wallet can call this function.\n * The recovery period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _recoveryPeriod Custom recovery period for the wallet\n */\n function setRecoveryPeriod(\n address _wallet,\n uint128 _recoveryPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _recoveryPeriod,\n minRecoveryPeriod,\n maxRecoveryPeriod\n );\n securityConfigs[_wallet].recoveryPeriod = _recoveryPeriod;\n }\n\n /**\n * @notice Wallet owner sets the lock period for the wallet. Only the owner of wallet can call this function.\n * The lock period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _lockPeriod Custom Lock period for the wallet\n */\n function setLockPeriod(\n address _wallet,\n uint128 _lockPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(_lockPeriod, minLockPeriod, maxLockPeriod);\n securityConfigs[_wallet].lockPeriod = _lockPeriod;\n }\n\n /**\n * @notice Wallet owner sets the approval validation period for the wallet. Only the owner of wallet can call this function.\n * The approval validation period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _approvalValidationPeriod Custom approval validation period for the wallet\n */\n function setApprovalValidationPeriod(\n address _wallet,\n uint128 _approvalValidationPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _approvalValidationPeriod,\n minApprovalValidationPeriod,\n maxApprovalValidationPeriod\n );\n securityConfigs[_wallet]\n .approvalValidationPeriod = _approvalValidationPeriod;\n }\n\n /**\n * @notice Wallet owner sets the migration period for the wallet. Only the owner of wallet can call this function.\n * The migration period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _migrationPeriod Custom migration period for the wallet\n */\n\n function setMigrationPeriod(\n address _wallet,\n uint128 _migrationPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _migrationPeriod,\n minMigrationPeriod,\n maxMigrationPeriod\n );\n securityConfigs[_wallet].migrationPeriod = _migrationPeriod;\n }\n\n /**\n * @notice Returns the addition security period. Returns default value when custom addition security period is not set\n * @param _wallet Address of wallet\n * @return additionSecurityPeriod Addition Security Period of the given Barz account or wallet\n */\n function additionSecurityPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 additionSecurityPeriod)\n {\n additionSecurityPeriod = securityConfigs[_wallet]\n .additionSecurityPeriod;\n additionSecurityPeriod = (additionSecurityPeriod == 0)\n ? defaultAdditionSecurityPeriod\n : additionSecurityPeriod;\n }\n\n /**\n * @notice Returns the removal security period. Returns default value when custom removal security period is not set\n * @param _wallet Address of wallet\n * @return removalSecurityPeriod Removal Security Period of the given Barz account or wallet\n */\n function removalSecurityPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 removalSecurityPeriod)\n {\n removalSecurityPeriod = securityConfigs[_wallet].removalSecurityPeriod;\n removalSecurityPeriod = (removalSecurityPeriod == 0)\n ? defaultRemovalSecurityPeriod\n : removalSecurityPeriod;\n }\n\n /**\n * @notice Returns the security window. Returns default value when custom security window is not set\n * @param _wallet Address of wallet\n * @return securityWindow Security window of the given Barz account or wallet\n */\n function securityWindowOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 securityWindow)\n {\n securityWindow = securityConfigs[_wallet].securityWindow;\n securityWindow = (securityWindow == 0)\n ? defaultSecurityWindow\n : securityWindow;\n }\n\n /**\n * @notice Returns the recovery period. Returns default value when custom recovery period is not set\n * @param _wallet Address of wallet\n * @return recoveryPeriod Recovery Period of the given Barz account or wallet\n */\n function recoveryPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 recoveryPeriod)\n {\n recoveryPeriod = securityConfigs[_wallet].recoveryPeriod;\n recoveryPeriod = (recoveryPeriod == 0)\n ? defaultRecoveryPeriod\n : recoveryPeriod;\n }\n\n /**\n * @notice Returns the lock period. Returns default value when custom lock period is not set\n * @param _wallet Address of wallet\n * @return lockPeriod Lock Period of the given Barz account or wallet\n */\n function lockPeriodOf(\n address _wallet\n ) public view override onlyWallet(_wallet) returns (uint128 lockPeriod) {\n lockPeriod = securityConfigs[_wallet].lockPeriod;\n lockPeriod = (lockPeriod == 0) ? defaultLockPeriod : lockPeriod;\n }\n\n /**\n * @notice Returns the approval validation period. Returns default value when custom approval validation period is not set\n * @param _wallet Address of wallet\n * @return approvalValidationPeriod Approval Validation Period of the given Barz account or wallet\n */\n function approvalValidationPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityConfigs[_wallet]\n .approvalValidationPeriod;\n approvalValidationPeriod = (approvalValidationPeriod == 0)\n ? defaultApprovalValidationPeriod\n : approvalValidationPeriod;\n }\n\n /**\n * @notice Returns the migration period. Returns default value when custom migration period is not set\n * @param _wallet Address of wallet\n * @return migrationPeriod Migration Period of the given Barz account or wallet\n */\n function migrationPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 migrationPeriod)\n {\n migrationPeriod = securityConfigs[_wallet].migrationPeriod;\n migrationPeriod = (migrationPeriod == 0)\n ? defaultMigrationPeriod\n : migrationPeriod;\n }\n\n /**\n * @notice Validates if the period is smaller than the max period or bigger than the min period\n * @param _period Period to be checked\n * @param _minPeriod Minimum period\n * @param _maxPeriod Maximum period\n */\n function _validatePeriodBoundaries(\n uint128 _period,\n uint128 _minPeriod,\n uint128 _maxPeriod\n ) internal pure {\n if (_period >= _maxPeriod || _period <= _minPeriod)\n revert SecurityManager__OutOfBoundary();\n }\n}\n" + }, + "contracts/infrastructure/WhitelistStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {RemoteStorage} from \"./RemoteStorage.sol\";\n\n/**\n * @title Whitelist storage\n * @dev Maps addresses to the corresponsing array of whitelisted addresses for each of them.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract WhitelistStorage is RemoteStorage {\n /**\n * @dev Add the address to the whitelist storage\n * @param _wallet User wallet\n * @param _address Address to be whitelisted\n */\n function whitelistAddress(address _wallet, address _address) external {\n enforceWalletOrGuardianIfExists(_wallet);\n addAddress(_wallet, _address);\n }\n\n /**\n * @dev Removes the address from the whitelist storage\n * @param _wallet User wallet\n * @param _address Address to be removed from the whitelist\n */\n function blacklistAddress(address _wallet, address _address) external {\n enforceGuardianOrWallet(_wallet);\n removeAddress(_wallet, _address);\n }\n\n /**\n * @dev Returns whether the address exists in the whitelist storage, associated with the wallet\n * @param _wallet User wallet\n * @param _address Address to be whitelisted\n */\n function isWhitelisted(\n address _wallet,\n address _address\n ) external view returns (bool) {\n return exists(_wallet, _address);\n }\n\n /**\n * @dev Returns all whitelisted addresses associated with the wallet\n * @param _wallet User wallet\n */\n function getWhitelistedAddresses(\n address _wallet\n ) external view returns (address[] memory) {\n return getAddresses(_wallet);\n }\n}\n" + }, + "contracts/interfaces/ERC/IERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\n\npragma solidity 0.8.21;\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155Receiver {\n /**\n * @dev Handles the receipt of a single ERC1155 token type. This function is\n * called at the end of a `safeTransferFrom` after the balance has been updated.\n *\n * NOTE: To accept the transfer, this must return\n * `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n * (i.e. 0xf23a6e61, or its own function selector).\n *\n * @param operator The address which initiated the transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param id The ID of the token being transferred\n * @param value The amount of tokens being transferred\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n ) external returns (bytes4);\n\n /**\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\n * is called at the end of a `safeBatchTransferFrom` after the balances have\n * been updated.\n *\n * NOTE: To accept the transfer(s), this must return\n * `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n * (i.e. 0xbc197c81, or its own function selector).\n *\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "contracts/interfaces/ERC/IERC1271.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\ninterface IERC1271 {\n function isValidSignature(\n bytes32 hash,\n bytes memory signature\n ) external view returns (bytes4);\n}\n" + }, + "contracts/interfaces/ERC/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\ninterface IERC165 {\n /// @notice Query if a contract implements an interface\n /// @param interfaceId The interface identifier, as specified in ERC-165\n /// @dev Interface identification is specified in ERC-165. This function\n /// uses less than 30,000 gas.\n /// @return `true` if the contract implements `interfaceID` and\n /// `interfaceID` is not 0xffffffff, `false` otherwise\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/IERC173.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\n/// @title ERC-173 Contract Ownership Standard\n/// Note: the ERC-165 identifier for this interface is 0x7f5828d0\n/* is ERC165 */\ninterface IERC173 {\n /// @dev This emits when ownership of a contract changes.\n event OwnershipTransferred(\n address indexed previousOwner,\n address indexed newOwner\n );\n\n /// @notice Get the address of the owner\n /// @return owner_ The address of the owner.\n function owner() external view returns (address owner_);\n\n /// @notice Set the address of the new owner of the contract\n /// @dev Set _newOwner to address(0) to renounce any ownership.\n /// @param _newOwner The address of the new owner of the contract\n function transferOwnership(address _newOwner) external;\n}\n" + }, + "contracts/interfaces/ERC/IERC677Receiver.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\ninterface IERC677Receiver {\n function onTokenTransfer(\n address sender,\n uint value,\n bytes calldata data\n ) external pure returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155 is IERC165 {\n /**\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n */\n event TransferSingle(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256 id,\n uint256 value\n );\n\n /**\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n * transfers.\n */\n event TransferBatch(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\n\n /**\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n * `approved`.\n */\n event ApprovalForAll(\n address indexed account,\n address indexed operator,\n bool approved\n );\n\n /**\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n *\n * If an {URI} event was emitted for `id`, the standard\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n * returned by {IERC1155MetadataURI-uri}.\n */\n event URI(string value, uint256 indexed id);\n\n /**\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(\n address account,\n uint256 id\n ) external view returns (uint256);\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] calldata accounts,\n uint256[] calldata ids\n ) external view returns (uint256[] memory);\n\n /**\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n *\n * Emits an {ApprovalForAll} event.\n *\n * Requirements:\n *\n * - `operator` cannot be the caller.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n *\n * See {setApprovalForAll}.\n */\n function isApprovedForAll(\n address account,\n address operator\n ) external view returns (bool);\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes calldata data\n ) external;\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(\n address indexed owner,\n address indexed spender,\n uint256 value\n );\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` 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 amount) 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(\n address owner,\n address spender\n ) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the 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 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` 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(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(\n address spender,\n uint256 addedValue\n ) external returns (bool);\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(\n address spender,\n uint256 subtractedValue\n ) external returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(\n address indexed from,\n address indexed to,\n uint256 indexed tokenId\n );\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(\n address indexed owner,\n address indexed approved,\n uint256 indexed tokenId\n );\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(\n address indexed owner,\n address indexed operator,\n bool approved\n );\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(\n uint256 tokenId\n ) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(\n address owner,\n address operator\n ) external view returns (bool);\n}\n" + }, + "contracts/interfaces/IBarz.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Barz Interface\n * @dev Interface of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IBarz {\n error Barz__InitializationFailure();\n}\n" + }, + "contracts/interfaces/IBarzFactory.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Barz} from \"../Barz.sol\";\n\n/**\n * @title Barz Factory Interface\n * @dev Interface of contract to easily deploy Barz to a pre-computed address with a single call\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IBarzFactory {\n function createAccount(\n address verificationFacet,\n bytes calldata owner,\n uint256 salt\n ) external returns (Barz);\n\n function getAddress(\n address verificationFacet,\n bytes calldata owner,\n uint256 salt\n ) external view returns (address);\n\n function getBytecode(\n address accountFacet,\n address verificationFacet,\n address entryPoint,\n address facetRegistry,\n address defaultFallback,\n bytes memory ownerPublicKey\n ) external pure returns (bytes memory);\n\n function getCreationCode() external pure returns (bytes memory);\n}\n" + }, + "contracts/libraries/DefaultLibDiamond.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\n\nerror InitializationFunctionReverted(\n address _initializationContractAddress,\n bytes _calldata\n);\n\nlibrary DefaultLibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION =\n keccak256(\"trustwallet.barz.diamond.storage\");\n\n struct FacetAddressAndPosition {\n address facetAddress;\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\n }\n\n struct FacetFunctionSelectors {\n bytes4[] functionSelectors;\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\n }\n\n struct DiamondStorage {\n // maps function selector to the facet address and\n // the position of the selector in the facetFunctionSelectors.selectors array\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\n // maps facet addresses to function selectors\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\n // facet addresses\n address[] facetAddresses;\n // Used to query if a contract implements an interface.\n // Used to implement ERC-165.\n mapping(bytes4 => bool) supportedInterfaces;\n }\n\n function diamondStorage()\n internal\n pure\n returns (DiamondStorage storage ds)\n {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n event DiamondCut(\n IDiamondCut.FacetCut[] _diamondCut,\n address _init,\n bytes _calldata\n );\n\n // Internal function version of diamondCut\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n for (\n uint256 facetIndex;\n facetIndex < _diamondCut.length;\n facetIndex++\n ) {\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\n if (action == IDiamondCut.FacetCutAction.Add) {\n addFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\n replaceFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\n removeFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else {\n revert(\"LibDiamondCut: Incorrect FacetCutAction\");\n }\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Add facet can't be address(0)\"\n );\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n require(\n oldFacetAddress == address(0),\n \"LibDiamondCut: Can't add function that already exists\"\n );\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function replaceFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Replace facet can't be address(0)\"\n );\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n require(\n oldFacetAddress != _facetAddress,\n \"LibDiamondCut: Can't replace function with same facet\"\n );\n removeFunction(ds, oldFacetAddress, selector);\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function removeFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n // if function does not exist then do nothing and return\n require(\n _facetAddress == address(0),\n \"LibDiamondCut: Remove facet address must be address(0)\"\n );\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n removeFunction(ds, oldFacetAddress, selector);\n }\n }\n\n function addFacet(\n DiamondStorage storage ds,\n address _facetAddress\n ) internal {\n enforceHasContractCode(\n _facetAddress,\n \"LibDiamondCut: New facet has no code\"\n );\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds\n .facetAddresses\n .length;\n ds.facetAddresses.push(_facetAddress);\n }\n\n function addFunction(\n DiamondStorage storage ds,\n bytes4 _selector,\n uint96 _selectorPosition,\n address _facetAddress\n ) internal {\n ds\n .selectorToFacetAndPosition[_selector]\n .functionSelectorPosition = _selectorPosition;\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(\n _selector\n );\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\n }\n\n function removeFunction(\n DiamondStorage storage ds,\n address _facetAddress,\n bytes4 _selector\n ) internal {\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Can't remove function that doesn't exist\"\n );\n // an immutable function is a function defined directly in a diamond\n require(\n _facetAddress != address(this),\n \"LibDiamondCut: Can't remove immutable function\"\n );\n // replace selector with last selector, then delete last selector\n uint256 selectorPosition = ds\n .selectorToFacetAndPosition[_selector]\n .functionSelectorPosition;\n uint256 lastSelectorPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors\n .length - 1;\n // if not the same then replace _selector with lastSelector\n if (selectorPosition != lastSelectorPosition) {\n bytes4 lastSelector = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors[lastSelectorPosition];\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[\n selectorPosition\n ] = lastSelector;\n ds\n .selectorToFacetAndPosition[lastSelector]\n .functionSelectorPosition = uint96(selectorPosition);\n }\n // delete the last selector\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\n delete ds.selectorToFacetAndPosition[_selector];\n\n // if no more selectors for facet address then delete the facet address\n if (lastSelectorPosition == 0) {\n // replace facet address with last facet address and delete last facet address\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\n uint256 facetAddressPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .facetAddressPosition;\n if (facetAddressPosition != lastFacetAddressPosition) {\n address lastFacetAddress = ds.facetAddresses[\n lastFacetAddressPosition\n ];\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\n ds\n .facetFunctionSelectors[lastFacetAddress]\n .facetAddressPosition = facetAddressPosition;\n }\n ds.facetAddresses.pop();\n delete ds\n .facetFunctionSelectors[_facetAddress]\n .facetAddressPosition;\n }\n }\n\n function initializeDiamondCut(\n address _init,\n bytes memory _calldata\n ) internal {\n if (_init == address(0)) {\n return;\n }\n enforceHasContractCode(\n _init,\n \"LibDiamondCut: _init address has no code\"\n );\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length > 0) {\n // bubble up error\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(error)\n revert(add(32, error), returndata_size)\n }\n } else {\n revert InitializationFunctionReverted(_init, _calldata);\n }\n }\n }\n\n function enforceHasContractCode(\n address _contract,\n string memory _errorMessage\n ) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize > 0, _errorMessage);\n }\n}\n" + }, + "contracts/libraries/LibAppStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SafeCast} from \"@openzeppelin/contracts/utils/math/SafeCast.sol\";\nimport {IEntryPoint} from \"../aa-4337/interfaces/IEntryPoint.sol\";\nimport {IFacetRegistry} from \"../infrastructure/interfaces/IFacetRegistry.sol\";\n\n/*\n * @title App Storage\n * @dev App storage for Barz contract to prevent storage collision\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\n\nstruct Lock {\n uint64 release;\n bytes4 locker;\n}\n\nstruct InitializersStorage {\n // NOTE: initialized is a variable to make sure the initialization is only done once.\n uint8 signerInitialized;\n uint8 accountInitialized;\n uint8 restrictionsInitialized;\n}\n\nstruct AppStorage {\n mapping(uint256 => InitializersStorage) initStorage;\n uint8 signerMigration;\n bytes4 validateOwnerSignatureSelector;\n IEntryPoint entryPoint;\n IFacetRegistry facetRegistry;\n mapping(uint256 => Lock) locks;\n}\n\nlibrary LibAppStorage {\n error LibAppStorage__AccountAlreadyUninitialized();\n error LibAppStorage__AccountMustBeUninitialized();\n error LibAppStorage__SignerAlreadyUninitialized();\n error LibAppStorage__SignerMustBeUninitialized();\n\n function appStorage() internal pure returns (AppStorage storage ds) {\n assembly {\n ds.slot := 0\n }\n }\n\n function setSignerUninitialized() internal {\n AppStorage storage s = appStorage();\n if (1 != s.initStorage[0].signerInitialized) {\n revert LibAppStorage__SignerAlreadyUninitialized();\n }\n s.initStorage[0].signerInitialized = 0;\n }\n\n function getValidateOwnerSignatureSelector()\n internal\n view\n returns (bytes4 selector)\n {\n selector = appStorage().validateOwnerSignatureSelector;\n }\n\n function setValidateOwnerSignatureSelector(\n bytes4 _validateOwnerSignatureSelector\n ) internal {\n appStorage()\n .validateOwnerSignatureSelector = _validateOwnerSignatureSelector;\n }\n\n function enforceSignerInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].signerInitialized) {\n revert LibAppStorage__SignerMustBeUninitialized();\n }\n s.initStorage[0].signerInitialized = 1;\n }\n\n function enforceAccountInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].accountInitialized) {\n revert LibAppStorage__AccountMustBeUninitialized();\n }\n s.initStorage[0].accountInitialized = 1;\n }\n\n function initiateSignerMigration() internal {\n appStorage().signerMigration = 1;\n }\n\n function enforceSignerMigration() internal view {\n if (1 != appStorage().signerMigration) {\n revert LibAppStorage__AccountMustBeUninitialized();\n }\n }\n\n function finalizeSignerMigration() internal {\n appStorage().signerMigration = 0;\n }\n\n function setLock(uint256 _releaseAfter, bytes4 _locker) internal {\n appStorage().locks[0] = Lock(SafeCast.toUint64(_releaseAfter), _locker);\n }\n\n function enforceRestrictionsInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].restrictionsInitialized)\n revert LibAppStorage__SignerMustBeUninitialized();\n s.initStorage[0].restrictionsInitialized = 1;\n }\n\n function setRestrictionsUninitialized() internal {\n AppStorage storage s = appStorage();\n if (1 != s.initStorage[0].restrictionsInitialized)\n revert LibAppStorage__AccountAlreadyUninitialized();\n s.initStorage[0].restrictionsInitialized = 0;\n }\n}\n\ncontract BarzStorage {\n AppStorage internal s;\n modifier onlyWhenUnlocked() {\n require(\n uint64(block.timestamp) >= s.locks[0].release,\n \"Account Locked\"\n );\n _;\n }\n modifier onlyWhenLocked() {\n require(\n uint64(block.timestamp) < s.locks[0].release,\n \"Account Unlocked\"\n );\n _;\n }\n}\n" + }, + "contracts/libraries/LibDiamond.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\n\nerror InitializationFunctionReverted(\n address _initializationContractAddress,\n bytes _calldata\n);\n\nlibrary LibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION =\n keccak256(\"trustwallet.barz.diamond.storage\");\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\n bytes4(keccak256(\"verifyRestrictions(address,address,uint256,bytes)\"));\n struct DiamondStorage {\n // maps function selectors to the facets that execute the functions.\n // and maps the selectors to their position in the selectorSlots array.\n // func selector => address facet, selector position\n mapping(bytes4 => bytes32) facets;\n // array of slots of function selectors.\n // each slot holds 8 function selectors.\n mapping(uint256 => bytes32) selectorSlots;\n // The number of function selectors in selectorSlots\n uint16 selectorCount;\n // Used to query if a contract implements an interface.\n // Used to implement ERC-165.\n mapping(bytes4 => bool) supportedInterfaces;\n // Default Fallback Handler of the barz.\n IDiamondLoupe defaultFallbackHandler;\n }\n\n function diamondStorage()\n internal\n pure\n returns (DiamondStorage storage ds)\n {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n function enforceIsSelf() internal view {\n require(msg.sender == address(this), \"LibDiamond: Caller not self\");\n }\n\n event DiamondCut(\n IDiamondCut.FacetCut[] _diamondCut,\n address _init,\n bytes _calldata\n );\n\n bytes32 constant CLEAR_ADDRESS_MASK =\n bytes32(uint256(0xffffffffffffffffffffffff));\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\n\n // Internal function version of diamondCut\n // This code is almost the same as the external diamondCut,\n // except it is using 'Facet[] memory _diamondCut' instead of\n // 'Facet[] calldata _diamondCut'.\n // The code is duplicated to prevent copying calldata to memory which\n // causes an error for a two dimensional array.\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n DiamondStorage storage ds = diamondStorage();\n uint256 originalSelectorCount = ds.selectorCount;\n uint256 selectorCount = originalSelectorCount;\n bytes32 selectorSlot;\n // Check if last selector slot is not full\n // \"selectorCount & 7\" is a gas efficient modulo by eight \"selectorCount % 8\"\n if (selectorCount & 7 > 0) {\n // get last selectorSlot\n // \"selectorSlot >> 3\" is a gas efficient division by 8 \"selectorSlot / 8\"\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\n }\n // loop through diamond cut\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\n selectorCount,\n selectorSlot,\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].action,\n _diamondCut[facetIndex].functionSelectors\n );\n\n unchecked {\n facetIndex++;\n }\n }\n if (selectorCount != originalSelectorCount) {\n ds.selectorCount = uint16(selectorCount);\n }\n // If last selector slot is not full\n // \"selectorCount & 7\" is a gas efficient modulo by eight \"selectorCount % 8\"\n if (selectorCount & 7 > 0) {\n // \"selectorSlot >> 3\" is a gas efficient division by 8 \"selectorSlot / 8\"\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addReplaceRemoveFacetSelectors(\n uint256 _selectorCount,\n bytes32 _selectorSlot,\n address _newFacetAddress,\n IDiamondCut.FacetCutAction _action,\n bytes4[] memory _selectors\n ) internal returns (uint256, bytes32) {\n DiamondStorage storage ds = diamondStorage();\n require(\n _selectors.length > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n if (_action == IDiamondCut.FacetCutAction.Add) {\n enforceHasContractCode(\n _newFacetAddress,\n \"LibDiamondCut: Add facet has no code\"\n );\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n require(\n address(bytes20(oldFacet)) == address(0),\n \"LibDiamondCut: Can't add function that already exists\"\n );\n // add facet for selector\n ds.facets[selector] =\n bytes20(_newFacetAddress) |\n bytes32(_selectorCount);\n // \"_selectorCount & 7\" is a gas efficient modulo by eight \"_selectorCount % 8\"\n // \" << 5 is the same as multiplying by 32 ( * 32)\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\n // clear selector position in slot and add selector\n _selectorSlot =\n (_selectorSlot &\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\n (bytes32(selector) >> selectorInSlotPosition);\n // if slot is full then write it to storage\n if (selectorInSlotPosition == 224) {\n // \"_selectorSlot >> 3\" is a gas efficient division by 8 \"_selectorSlot / 8\"\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\n _selectorSlot = 0;\n }\n _selectorCount++;\n\n unchecked {\n selectorIndex++;\n }\n }\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\n enforceHasContractCode(\n _newFacetAddress,\n \"LibDiamondCut: Replace facet has no code\"\n );\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n address oldFacetAddress = address(bytes20(oldFacet));\n // only useful if immutable functions exist\n require(\n oldFacetAddress != address(this),\n \"LibDiamondCut: Can't replace immutable function\"\n );\n require(\n oldFacetAddress != _newFacetAddress,\n \"LibDiamondCut: Can't replace function with same function\"\n );\n require(\n oldFacetAddress != address(0),\n \"LibDiamondCut: Can't replace function that doesn't exist\"\n );\n // replace old facet address\n ds.facets[selector] =\n (oldFacet & CLEAR_ADDRESS_MASK) |\n bytes20(_newFacetAddress);\n\n unchecked {\n selectorIndex++;\n }\n }\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\n require(\n _newFacetAddress == address(0),\n \"LibDiamondCut: Remove facet address must be address(0)\"\n );\n // \"_selectorCount >> 3\" is a gas efficient division by 8 \"_selectorCount / 8\"\n uint256 selectorSlotCount = _selectorCount >> 3;\n // \"_selectorCount & 7\" is a gas efficient modulo by eight \"_selectorCount % 8\"\n uint256 selectorInSlotIndex = _selectorCount & 7;\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n if (_selectorSlot == 0) {\n // get last selectorSlot\n selectorSlotCount--;\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\n selectorInSlotIndex = 7;\n } else {\n selectorInSlotIndex--;\n }\n bytes4 lastSelector;\n uint256 oldSelectorsSlotCount;\n uint256 oldSelectorInSlotPosition;\n // adding a block here prevents stack too deep error\n {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n require(\n address(bytes20(oldFacet)) != address(0),\n \"LibDiamondCut: Can't remove function that doesn't exist\"\n );\n // only useful if immutable functions exist\n require(\n address(bytes20(oldFacet)) != address(this),\n \"LibDiamondCut: Can't remove immutable function\"\n );\n // replace selector with last selector in ds.facets\n // gets the last selector\n // \" << 5 is the same as multiplying by 32 ( * 32)\n lastSelector = bytes4(\n _selectorSlot << (selectorInSlotIndex << 5)\n );\n if (lastSelector != selector) {\n // update last selector slot position info\n ds.facets[lastSelector] =\n (oldFacet & CLEAR_ADDRESS_MASK) |\n bytes20(ds.facets[lastSelector]);\n }\n delete ds.facets[selector];\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\n // \"oldSelectorCount >> 3\" is a gas efficient division by 8 \"oldSelectorCount / 8\"\n oldSelectorsSlotCount = oldSelectorCount >> 3;\n // \"oldSelectorCount & 7\" is a gas efficient modulo by eight \"oldSelectorCount % 8\"\n // \" << 5 is the same as multiplying by 32 ( * 32)\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\n }\n if (oldSelectorsSlotCount != selectorSlotCount) {\n bytes32 oldSelectorSlot = ds.selectorSlots[\n oldSelectorsSlotCount\n ];\n // clears the selector we are deleting and puts the last selector in its place.\n oldSelectorSlot =\n (oldSelectorSlot &\n ~(CLEAR_SELECTOR_MASK >>\n oldSelectorInSlotPosition)) |\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\n // update storage with the modified slot\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\n } else {\n // clears the selector we are deleting and puts the last selector in its place.\n _selectorSlot =\n (_selectorSlot &\n ~(CLEAR_SELECTOR_MASK >>\n oldSelectorInSlotPosition)) |\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\n }\n if (selectorInSlotIndex == 0) {\n delete ds.selectorSlots[selectorSlotCount];\n _selectorSlot = 0;\n }\n\n unchecked {\n selectorIndex++;\n }\n }\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\n } else {\n revert(\"LibDiamondCut: Incorrect FacetCutAction\");\n }\n return (_selectorCount, _selectorSlot);\n }\n\n function initializeDiamondCut(\n address _init,\n bytes memory _calldata\n ) internal {\n if (_init == address(0)) {\n return;\n }\n enforceHasContractCode(\n _init,\n \"LibDiamondCut: _init address has no code\"\n );\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length > 0) {\n // bubble up error\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(error)\n revert(add(32, error), returndata_size)\n }\n } else {\n revert InitializationFunctionReverted(_init, _calldata);\n }\n }\n }\n\n function enforceHasContractCode(\n address _contract,\n string memory _errorMessage\n ) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize > 0, _errorMessage);\n }\n\n function restrictionsFacet() internal view returns (address facetAddress_) {\n facetAddress_ = address(\n bytes20(\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\n )\n );\n }\n}\n" + }, + "contracts/libraries/LibFacetStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Storage\n * @dev Storage contract to store each facets variables with diamond storage\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\n\nstruct Secp256k1VerificationStorage {\n address signer;\n}\n\nstruct Secp256r1VerificationStorage {\n uint256[2] q;\n}\n\nstruct GuardianStorage {\n mapping(bytes32 => uint256) pending;\n mapping(uint8 => StorageConfig) configs;\n}\n\nstruct Info {\n bool exists;\n uint128 index;\n}\n\nstruct StorageConfig {\n address[] addresses;\n mapping(address => Info) info;\n}\n\nstruct RecoveryConfig {\n bytes recoveryPublicKey;\n uint64 executeAfter;\n}\n\nstruct ApprovalConfig {\n bool isApproved;\n uint64 validUntil;\n}\n\nstruct RecoveryApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isNewOwnerApproved;\n}\n\nstruct RecoveryStorage {\n mapping(uint8 => RecoveryConfig) recoveryConfigs;\n mapping(uint8 => RecoveryApprovalConfig) recoveryApprovalConfigs;\n uint128 nonce;\n}\n\nstruct RestrictionsStorage {\n address[] restrictions;\n mapping(address => bool) exists;\n}\n\nstruct SignatureMigrationConfig {\n bytes migrationPublicKey;\n address migrationVerificationFacet;\n bytes4[] migrationSelectors;\n uint64 migrateAfter;\n}\n\nstruct SignatureMigrationApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isMigrationApproved;\n}\n\nstruct SignatureMigrationStorage {\n mapping(uint8 => SignatureMigrationConfig) migrationConfigs;\n mapping(uint8 => SignatureMigrationApprovalConfig) migrationApprovalConfigs;\n uint128 nonce;\n}\n\nstruct DiamondCutApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isDiamondCutApproved;\n}\n\nstruct DiamondCutStorage {\n mapping(uint8 => DiamondCutApprovalConfig) diamondCutApprovalConfigs;\n uint128 nonce;\n}\n\nstruct LockStorage {\n uint128 nonce;\n}\n\nlibrary LibFacetStorage {\n bytes32 constant K1_STORAGE_POSITION =\n keccak256(\n \"v0.trustwallet.diamond.storage.Secp256k1VerificationStorage\"\n );\n bytes32 constant R1_STORAGE_POSITION =\n keccak256(\n \"v0.trustwallet.diamond.storage.Secp256r1VerificationStorage\"\n );\n bytes32 constant GUARDIAN_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.GuardianStorage\");\n bytes32 constant RECOVERY_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.RecoveryStorage\");\n bytes32 constant RESTRICTION_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.RestrictionsStorage\");\n bytes32 constant MIGRATION_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.SignatureMigrationStorage\");\n bytes32 constant DIAMONDCUT_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.DiamondCutStorage\");\n bytes32 constant LOCK_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.LockStorage\");\n\n function k1Storage()\n internal\n pure\n returns (Secp256k1VerificationStorage storage ds)\n {\n bytes32 storagePosition = K1_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function r1Storage()\n internal\n pure\n returns (Secp256r1VerificationStorage storage ds)\n {\n bytes32 storagePosition = R1_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function guardianStorage()\n internal\n pure\n returns (GuardianStorage storage ds)\n {\n bytes32 storagePosition = GUARDIAN_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function recoveryStorage()\n internal\n pure\n returns (RecoveryStorage storage ds)\n {\n bytes32 storagePosition = RECOVERY_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function restrictionsStorage()\n internal\n pure\n returns (RestrictionsStorage storage ds)\n {\n bytes32 storagePosition = RESTRICTION_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function migrationStorage()\n internal\n pure\n returns (SignatureMigrationStorage storage ds)\n {\n bytes32 storagePosition = MIGRATION_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function diamondCutStorage()\n internal\n pure\n returns (DiamondCutStorage storage ds)\n {\n bytes32 storagePosition = DIAMONDCUT_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function lockStorage() internal pure returns (LockStorage storage ds) {\n bytes32 storagePosition = LOCK_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n}\n" + }, + "contracts/libraries/LibGuardian.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibFacetStorage, StorageConfig} from \"./LibFacetStorage.sol\";\n\n/**\n * @title LibGuardian\n * @dev Internal Library to provide utility feature for Guardians stored in Guardian Facet Storage\n * @author David Yongjun Kim (@Powerstream3604)\n */\nlibrary LibGuardian {\n function majorityOfGuardians()\n internal\n view\n returns (uint256 guardianNumber)\n {\n uint256 guardianLength = guardianCount();\n guardianNumber = (guardianLength == 0) ? 0 : guardianLength / 2 + 1;\n }\n\n function isGuardian(address _guardian) internal view returns (bool) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n return config.info[_guardian].exists;\n }\n\n function guardianCount() internal view returns (uint256) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n return config.addresses.length;\n }\n\n function getGuardians() internal view returns (address[] memory) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n address[] memory addresses = new address[](config.addresses.length);\n uint256 addressesLen = config.addresses.length;\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n return addresses;\n }\n}\n" + }, + "contracts/libraries/LibLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {LibDiamond} from \"./LibDiamond.sol\";\n\n/**\n * @title LibLoupe\n * @dev Internal Library to provide utility feature for reading the state of diamond facets\n * @author David Yongjun Kim (@Powerstream3604)\n */\nlibrary LibLoupe {\n /// @notice Gets all facets and their selectors.\n /// @return facets_ Facet\n function facets()\n internal\n view\n returns (IDiamondLoupe.Facet[] memory facets_)\n {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facets_ = new IDiamondLoupe.Facet[](ds.selectorCount);\n uint16[] memory numFacetSelectors = new uint16[](ds.selectorCount);\n uint256 numFacets;\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facetAddress_ = address(bytes20(ds.facets[selector]));\n bool continueLoop;\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n if (facets_[facetIndex].facetAddress == facetAddress_) {\n facets_[facetIndex].functionSelectors[\n numFacetSelectors[facetIndex]\n ] = selector;\n // probably will never have more than 256 functions from one facet contract\n require(numFacetSelectors[facetIndex] < 255);\n numFacetSelectors[facetIndex]++;\n continueLoop = true;\n break;\n }\n }\n if (continueLoop) {\n continue;\n }\n facets_[numFacets].facetAddress = facetAddress_;\n facets_[numFacets].functionSelectors = new bytes4[](\n ds.selectorCount\n );\n facets_[numFacets].functionSelectors[0] = selector;\n numFacetSelectors[numFacets] = 1;\n numFacets++;\n }\n }\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n uint256 numSelectors = numFacetSelectors[facetIndex];\n bytes4[] memory selectors = facets_[facetIndex].functionSelectors;\n // setting the number of selectors\n assembly {\n mstore(selectors, numSelectors)\n }\n }\n // setting the number of facets\n assembly {\n mstore(facets_, numFacets)\n }\n }\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n /// @return _facetFunctionSelectors The selectors associated with a facet address.\n function facetFunctionSelectors(\n address _facet\n ) internal view returns (bytes4[] memory _facetFunctionSelectors) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n uint256 numSelectors;\n _facetFunctionSelectors = new bytes4[](ds.selectorCount);\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facet = address(bytes20(ds.facets[selector]));\n if (_facet == facet) {\n _facetFunctionSelectors[numSelectors] = selector;\n numSelectors++;\n }\n }\n }\n // Set the number of selectors in the array\n assembly {\n mstore(_facetFunctionSelectors, numSelectors)\n }\n }\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses()\n internal\n view\n returns (address[] memory facetAddresses_)\n {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facetAddresses_ = new address[](ds.selectorCount);\n uint256 numFacets;\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facetAddress_ = address(bytes20(ds.facets[selector]));\n bool continueLoop;\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n if (facetAddress_ == facetAddresses_[facetIndex]) {\n continueLoop = true;\n break;\n }\n }\n if (continueLoop) {\n continue;\n }\n facetAddresses_[numFacets] = facetAddress_;\n numFacets++;\n }\n }\n // Set the number of facet addresses in the array\n assembly {\n mstore(facetAddresses_, numFacets)\n }\n }\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(\n bytes4 _functionSelector\n ) internal view returns (address facetAddress_) {\n facetAddress_ = address(\n bytes20(LibDiamond.diamondStorage().facets[_functionSelector])\n );\n }\n}\n" + }, + "contracts/libraries/LibMultiSigStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Multi-sig Storage\n * @dev Storage contract for storing Multi-sig Facet variables in diamond storage pattern\n * @author David Yongjun Kim (@Powerstream3604)\n */\n\nstruct MultiSigStorage {\n mapping(address => address) owners;\n mapping(uint256 => mapping(address => mapping(bytes32 => uint256))) approvedHashes;\n uint256 ownerCount;\n uint256 threshold;\n uint256 counter;\n}\n\nlibrary LibMultiSigStorage {\n function multisigStorage()\n internal\n pure\n returns (MultiSigStorage storage ds)\n {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.MultiSigStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n}\n" + }, + "contracts/libraries/LibRecoverSpender.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title RecoverSpender\n * @dev Library to determine the action and spender of calldata\n * @author Ruslan Serebriakov (@rsrbk)\n */\nlibrary LibRecoverSpender {\n // ERC20, ERC721 & ERC1155 transfers & approvals\n bytes4 private constant ERC20_TRANSFER =\n bytes4(keccak256(\"transfer(address,uint256)\"));\n bytes4 private constant ERC20_APPROVE =\n bytes4(keccak256(\"approve(address,uint256)\"));\n bytes4 private constant ERC20_INCREASE_ALLOWANCE =\n bytes4(keccak256(\"increaseAllowance(address,uint256)\"));\n bytes4 private constant ERC20_DECREASE_ALLOWANCE =\n bytes4(keccak256(\"decreaseAllowance(address,uint256)\"));\n bytes4 private constant ERC721_SET_APPROVAL_FOR_ALL =\n bytes4(keccak256(\"setApprovalForAll(address,bool)\"));\n bytes4 private constant ERC721_TRANSFER_FROM =\n bytes4(keccak256(\"transferFrom(address,address,uint256)\"));\n bytes4 private constant ERC721_SAFE_TRANSFER_FROM =\n bytes4(keccak256(\"safeTransferFrom(address,address,uint256)\"));\n bytes4 private constant ERC721_SAFE_TRANSFER_FROM_BYTES =\n bytes4(keccak256(\"safeTransferFrom(address,address,uint256,bytes)\"));\n bytes4 private constant ERC1155_SAFE_TRANSFER_FROM =\n bytes4(\n keccak256(\"safeTransferFrom(address,address,uint256,uint256,bytes)\")\n );\n bytes4 private constant ERC1155_SAFE_BATCH_TRANSFER_FROM =\n bytes4(\n keccak256(\n \"safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)\"\n )\n );\n\n /**\n * @notice Helper method to recover the spender from a contract call.\n * The method returns the contract unless the call is to a standard method of a ERC20/ERC721/ERC1155 token\n * in which case the spender is recovered from the data.\n * @param _to The target contract.\n * @param _data The data payload.\n */\n function _recover(\n address _to,\n bytes memory _data\n ) internal pure returns (address spender) {\n if (_data.length >= 68) {\n bytes4 methodId;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n methodId := mload(add(_data, 0x20))\n }\n if (\n methodId == ERC20_TRANSFER ||\n methodId == ERC20_APPROVE ||\n methodId == ERC20_INCREASE_ALLOWANCE ||\n methodId == ERC20_DECREASE_ALLOWANCE ||\n methodId == ERC721_SET_APPROVAL_FOR_ALL\n ) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n spender := mload(add(_data, 0x24))\n }\n return spender;\n }\n if (\n methodId == ERC721_TRANSFER_FROM ||\n methodId == ERC721_SAFE_TRANSFER_FROM ||\n methodId == ERC721_SAFE_TRANSFER_FROM_BYTES ||\n methodId == ERC1155_SAFE_TRANSFER_FROM ||\n methodId == ERC1155_SAFE_BATCH_TRANSFER_FROM\n ) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n spender := mload(add(_data, 0x44))\n }\n return spender;\n }\n }\n\n spender = _to;\n }\n}\n" + }, + "contracts/libraries/LibUtils.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\n\nlibrary LibUtils {\n // Internal utility functions\n function mergeArrays(\n bytes4[] memory _array1,\n bytes4[] memory _array2\n ) internal pure returns (bytes4[] memory) {\n uint256 length1 = _array1.length;\n uint256 length2 = _array2.length;\n bytes4[] memory mergedArray = new bytes4[](length1 + length2);\n\n for (uint256 i; i < length1; ) {\n mergedArray[i] = _array1[i];\n unchecked {\n ++i;\n }\n }\n\n for (uint256 i; i < length2; ) {\n mergedArray[length1 + i] = _array2[i];\n unchecked {\n ++i;\n }\n }\n\n return mergedArray;\n }\n\n function removeFacetElement(\n IDiamondLoupe.Facet[] memory _facets,\n uint256 _index\n ) internal pure returns (IDiamondLoupe.Facet[] memory) {\n require(_index < _facets.length, \"Invalid index\");\n require(_facets.length != 0, \"Invalid array\");\n\n // Create a new array with a length of `_facets.length - 1`\n IDiamondLoupe.Facet[] memory newArray = new IDiamondLoupe.Facet[](\n _facets.length - 1\n );\n uint256 newArrayLength = newArray.length;\n // Iterate over the original array, skipping the element at the specified `index`\n for (uint256 i; i < newArrayLength; ) {\n if (i < _index) {\n newArray[i] = _facets[i];\n } else {\n newArray[i] = _facets[i + 1];\n }\n unchecked {\n ++i;\n }\n }\n\n return newArray;\n }\n\n function removeElement(\n bytes4[] memory _array,\n uint256 _index\n ) internal pure returns (bytes4[] memory) {\n require(_index < _array.length, \"Invalid index\");\n require(_array.length != 0, \"Invalid array\");\n\n bytes4[] memory newArray = new bytes4[](_array.length - 1);\n uint256 newArrayLength = newArray.length;\n for (uint256 i; i < newArrayLength; ) {\n if (i < _index) {\n newArray[i] = _array[i];\n } else {\n newArray[i] = _array[i + 1];\n }\n unchecked {\n ++i;\n }\n }\n\n return newArray;\n }\n\n function setValue(\n bytes4[] memory _keys,\n address[] memory _values,\n bytes4 _key,\n address _value\n ) internal pure returns (bytes4[] memory, address[] memory) {\n uint256 index = findIndex(_keys, _key);\n uint256 keysLength = _keys.length;\n if (index < keysLength) {\n _values[index] = _value;\n } else {\n // Create new storage arrays\n bytes4[] memory newKeys = new bytes4[](keysLength + 1);\n address[] memory newValues = new address[](_values.length + 1);\n\n // Copy values to the new storage arrays\n for (uint256 i; i < keysLength; ) {\n newKeys[i] = _keys[i];\n newValues[i] = _values[i];\n\n unchecked {\n ++i;\n }\n }\n\n // Add the new key-value pair\n newKeys[keysLength] = _key;\n newValues[_values.length] = _value;\n\n return (newKeys, newValues);\n }\n\n // If the key already exists, return the original arrays\n return (_keys, _values);\n }\n\n function getValue(\n bytes4[] memory _keys,\n address[] memory _values,\n bytes4 _key\n ) internal pure returns (address) {\n uint256 index = findIndex(_keys, _key);\n if (index >= _keys.length) return address(0);\n\n return _values[index];\n }\n\n function findIndex(\n bytes4[] memory _keys,\n bytes4 _key\n ) internal pure returns (uint256) {\n uint256 keysLength = _keys.length;\n for (uint256 i; i < keysLength; ) {\n if (_keys[i] == _key) {\n return i;\n }\n unchecked {\n ++i;\n }\n }\n return keysLength;\n }\n}\n" + }, + "contracts/restrictions/IRestriction.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Interface for restrictions\n * @dev Restriction is a contract which decides whether to approve a certain kind of transaction, based on its internal logic.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface IRestriction {\n /**\n * @dev Based on restriction's internal logic, it should accept or reject a certain transaction.\n * @param from The address of the sender, that will be signing the transaction.\n * @param to The receiving address.\n * @param value Amount of ETH to transfer from sender to recipient.\n * @param _calldata Optional field to include arbitrary data.\n * @return bool value for whether the check is passed\n */\n function check(\n address from,\n address to,\n uint256 value,\n bytes calldata _calldata\n ) external returns (bool);\n}\n" + }, + "contracts/restrictions/WhitelistRestriction.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibRecoverSpender} from \"../libraries/LibRecoverSpender.sol\";\nimport {WhitelistStorage} from \"../infrastructure/WhitelistStorage.sol\";\nimport {IRestriction} from \"./IRestriction.sol\";\n\n/**\n * @title Whitelist Restriction\n * @dev This restriction defines a list of accepted addresses and denies any interaction with addresses outside of it.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract WhitelistRestriction is IRestriction {\n WhitelistStorage public immutable whitelistStorage;\n\n constructor(WhitelistStorage _whitelistStorage) {\n whitelistStorage = _whitelistStorage;\n }\n\n /**\n * @notice Helper method to recover the spender from a contract call.\n * The method returns the contract unless the call is to a standard method of a ERC20/ERC721/ERC1155 token\n * in which case the spender is recovered from the data.\n * @param _to The target contract.\n * @param _data The data payload.\n */\n function recoverSpender(\n address _to,\n bytes memory _data\n ) public pure returns (address spender) {\n return LibRecoverSpender._recover(_to, _data);\n }\n\n /*\n * @dev IRestriction's implementation. It will allow transaction if the sender is whitelisted, or user, or the whitelist storage.\n * @param _from The address of the sender, that will be signing the transaction.\n * @param _to The receiving address.\n * @param _calldata Optional field to include arbitrary data.\n * @return result value for whether the check is passed\n */\n function check(\n address _from,\n address _to,\n uint256 /*_value*/,\n bytes calldata _calldata\n ) external view override returns (bool result) {\n return\n whitelistStorage.isWhitelisted(\n _from,\n LibRecoverSpender._recover(_to, _calldata)\n ) ||\n _to == address(whitelistStorage) ||\n _to == msg.sender;\n }\n}\n" + }, + "contracts/test/Counter.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\ncontract TestCounter {\n int private count = 0;\n\n function incrementCounter() public {\n count += 1;\n }\n\n function decrementCounter() public {\n count -= 1;\n }\n\n function getCount() public view returns (int) {\n return count;\n }\n}\n" + }, + "contracts/test/TestERC1155.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC1155/ERC1155.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\n\ncontract TestERC1155 is ERC1155 {\n using Counters for Counters.Counter;\n\n Counters.Counter private _tokenIds;\n\n constructor() ERC1155(\"\") {}\n\n function mint(address account, uint256 amount) external {\n uint256 tokenId = _getNextTokenId();\n _mint(account, tokenId, amount, \"\");\n }\n\n function mintBatch(\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes memory data\n ) external {\n require(\n ids.length == amounts.length,\n \"TestERC1155: arrays length mismatch\"\n );\n\n _mintBatch(to, ids, amounts, data);\n }\n\n function _getNextTokenId() private returns (uint256) {\n _tokenIds.increment();\n return _tokenIds.current();\n }\n}\n" + }, + "contracts/test/TestERC777.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC777/ERC777.sol\";\n\ncontract TestERC777 is ERC777 {\n constructor(\n address[] memory _operators\n ) ERC777(\"TestERC777\", \"TERC777\", _operators) {}\n\n function mint(address account, uint256 amount) external {\n _mint(account, amount, \"\", \"\");\n }\n}\n" + }, + "contracts/test/TestInvalidSecp256k1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IVerificationFacet} from \"../facets/interfaces/IVerificationFacet.sol\";\nimport {IERC1271} from \"../interfaces/ERC/IERC1271.sol\";\nimport {AppStorage, LibAppStorage, BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {LibFacetStorage, Secp256k1VerificationStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {UserOperation} from \"../aa-4337/interfaces/UserOperation.sol\";\n\n/**\n * @title Test Secp256k1 verification facet\n * @dev Default Ethereum's elliptic curve\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract TestInvalidSecp256k1VerificationFacet is BarzStorage, IERC1271 {\n using ECDSA for bytes32;\n error Secp256k1VerificationFacet__InvalidSignerLength();\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n\n event SignerUninitialized();\n\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n }\n\n // THIS INVALID FACET DOES NOT INCLUDE initializeSigner()\n // THIS FACET IS USED TO TEST WHEN initializeSigner() DOESN'T EXIST IN FACET\n\n function uninitializeSigner() external returns (uint256 uninitSuccess) {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view returns (uint256 validationData) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n return validateSignature(userOp, userOpHash, k1Storage.signer);\n }\n\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n address signer\n ) public pure returns (uint256) {\n bytes32 hash = userOpHash.toEthSignedMessageHash();\n if (signer != hash.recover(userOp.signature)) return 1;\n return 0;\n }\n\n // This is REMOVED for testing purpose\n function validateOwnerSignatureSelector() public pure returns (bytes4) {\n // return this.validateOwnerSignature.selector;\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n function owner() public view returns (bytes memory) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n return abi.encodePacked(k1Storage.signer);\n }\n\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure returns (bool) {\n return (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (_hash.recover(_signature) ==\n LibFacetStorage.k1Storage().signer)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n}\n" + }, + "contracts/test/TestNFT.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\n\ncontract TestNFT is ERC721 {\n using Counters for Counters.Counter;\n Counters.Counter private currentTokenId;\n\n constructor() ERC721(\"TestNFT\", \"TNFT\") {}\n\n function mint(address recipient) public returns (uint256) {\n currentTokenId.increment();\n uint256 newItemId = currentTokenId.current();\n _safeMint(recipient, newItemId);\n return newItemId;\n }\n}\n" + }, + "contracts/test/TestToken.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract TestToken is ERC20 {\n constructor()\n // solhint-disable-next-line no-empty-blocks\n ERC20(\"TST\", \"TestToken\")\n {}\n\n function mint(address sender, uint256 amount) external {\n _mint(sender, amount);\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 999999 + }, + "evmVersion": "paris", + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/deployments/opBNB/solcInputs/4356503edd8ae34e73cb6dd1c8e2fc8a.json b/deployments/opBNB/solcInputs/4356503edd8ae34e73cb6dd1c8e2fc8a.json new file mode 100644 index 0000000..db88715 --- /dev/null +++ b/deployments/opBNB/solcInputs/4356503edd8ae34e73cb6dd1c8e2fc8a.json @@ -0,0 +1,354 @@ +{ + "language": "Solidity", + "sources": { + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby disabling any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable2Step.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./Ownable.sol\";\n\n/**\n * @dev Contract module which provides access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership} and {acceptOwnership}.\n *\n * This module is used through inheritance. It will make available all functions\n * from parent (Ownable).\n */\nabstract contract Ownable2Step is Ownable {\n address private _pendingOwner;\n\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Returns the address of the pending owner.\n */\n function pendingOwner() public view virtual returns (address) {\n return _pendingOwner;\n }\n\n /**\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual override onlyOwner {\n _pendingOwner = newOwner;\n emit OwnershipTransferStarted(owner(), newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual override {\n delete _pendingOwner;\n super._transferOwnership(newOwner);\n }\n\n /**\n * @dev The new owner accepts the ownership transfer.\n */\n function acceptOwnership() public virtual {\n address sender = _msgSender();\n require(pendingOwner() == sender, \"Ownable2Step: caller is not the new owner\");\n _transferOwnership(sender);\n }\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC1271.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC1271 standard signature validation method for\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\n *\n * _Available since v4.1._\n */\ninterface IERC1271 {\n /**\n * @dev Should return whether the signature provided is valid for the provided data\n * @param hash Hash of the data to be signed\n * @param signature Signature byte array associated with _data\n */\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\n}\n" + }, + "@openzeppelin/contracts/security/ReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor() {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n _nonReentrantBefore();\n _;\n _nonReentrantAfter();\n }\n\n function _nonReentrantBefore() private {\n // On the first call to nonReentrant, _status will be _NOT_ENTERED\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n }\n\n function _nonReentrantAfter() private {\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Returns true if the reentrancy guard is currently set to \"entered\", which indicates there is a\n * `nonReentrant` function in the call stack.\n */\n function _reentrancyGuardEntered() internal view returns (bool) {\n return _status == _ENTERED;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/ERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/ERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC1155.sol\";\nimport \"./IERC1155Receiver.sol\";\nimport \"./extensions/IERC1155MetadataURI.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of the basic standard multi-token.\n * See https://eips.ethereum.org/EIPS/eip-1155\n * Originally based on code by Enjin: https://github.com/enjin/erc-1155\n *\n * _Available since v3.1._\n */\ncontract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {\n using Address for address;\n\n // Mapping from token ID to account balances\n mapping(uint256 => mapping(address => uint256)) private _balances;\n\n // Mapping from account to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json\n string private _uri;\n\n /**\n * @dev See {_setURI}.\n */\n constructor(string memory uri_) {\n _setURI(uri_);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return\n interfaceId == type(IERC1155).interfaceId ||\n interfaceId == type(IERC1155MetadataURI).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC1155MetadataURI-uri}.\n *\n * This implementation returns the same URI for *all* token types. It relies\n * on the token type ID substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * Clients calling this function must replace the `\\{id\\}` substring with the\n * actual token type ID.\n */\n function uri(uint256) public view virtual override returns (string memory) {\n return _uri;\n }\n\n /**\n * @dev See {IERC1155-balanceOf}.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {\n require(account != address(0), \"ERC1155: address zero is not a valid owner\");\n return _balances[id][account];\n }\n\n /**\n * @dev See {IERC1155-balanceOfBatch}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] memory accounts,\n uint256[] memory ids\n ) public view virtual override returns (uint256[] memory) {\n require(accounts.length == ids.length, \"ERC1155: accounts and ids length mismatch\");\n\n uint256[] memory batchBalances = new uint256[](accounts.length);\n\n for (uint256 i = 0; i < accounts.length; ++i) {\n batchBalances[i] = balanceOf(accounts[i], ids[i]);\n }\n\n return batchBalances;\n }\n\n /**\n * @dev See {IERC1155-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC1155-isApprovedForAll}.\n */\n function isApprovedForAll(address account, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[account][operator];\n }\n\n /**\n * @dev See {IERC1155-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n _safeTransferFrom(from, to, id, amount, data);\n }\n\n /**\n * @dev See {IERC1155-safeBatchTransferFrom}.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n _safeBatchTransferFrom(from, to, ids, amounts, data);\n }\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n\n emit TransferSingle(operator, from, to, id, amount);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n for (uint256 i = 0; i < ids.length; ++i) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n }\n\n emit TransferBatch(operator, from, to, ids, amounts);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\n\n _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);\n }\n\n /**\n * @dev Sets a new URI for all token types, by relying on the token type ID\n * substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * By this mechanism, any occurrence of the `\\{id\\}` substring in either the\n * URI or any of the amounts in the JSON file at said URI will be replaced by\n * clients with the token type ID.\n *\n * For example, the `https://token-cdn-domain/\\{id\\}.json` URI would be\n * interpreted by clients as\n * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`\n * for token type ID 0x4cce0.\n *\n * See {uri}.\n *\n * Because these URIs cannot be meaningfully represented by the {URI} event,\n * this function emits no events.\n */\n function _setURI(string memory newuri) internal virtual {\n _uri = newuri;\n }\n\n /**\n * @dev Creates `amount` tokens of token type `id`, and assigns them to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _mint(address to, uint256 id, uint256 amount, bytes memory data) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _balances[id][to] += amount;\n emit TransferSingle(operator, address(0), to, id, amount);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n for (uint256 i = 0; i < ids.length; i++) {\n _balances[ids[i]][to] += amounts[i];\n }\n\n emit TransferBatch(operator, address(0), to, ids, amounts);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);\n }\n\n /**\n * @dev Destroys `amount` tokens of token type `id` from `from`\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `from` must have at least `amount` tokens of token type `id`.\n */\n function _burn(address from, uint256 id, uint256 amount) internal virtual {\n require(from != address(0), \"ERC1155: burn from the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n\n emit TransferSingle(operator, from, address(0), id, amount);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n */\n function _burnBatch(address from, uint256[] memory ids, uint256[] memory amounts) internal virtual {\n require(from != address(0), \"ERC1155: burn from the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n\n for (uint256 i = 0; i < ids.length; i++) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n }\n\n emit TransferBatch(operator, from, address(0), ids, amounts);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {\n require(owner != operator, \"ERC1155: setting approval status for self\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning, as well as batched variants.\n *\n * The same hook is called on both single and batched variants. For single\n * transfers, the length of the `ids` and `amounts` arrays will be 1.\n *\n * Calling conditions (for each `id` and `amount` pair):\n *\n * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * of token type `id` will be transferred to `to`.\n * - When `from` is zero, `amount` tokens of token type `id` will be minted\n * for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n * will be burned.\n * - `from` and `to` are never both zero.\n * - `ids` and `amounts` have the same, non-zero length.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any token transfer. This includes minting\n * and burning, as well as batched variants.\n *\n * The same hook is called on both single and batched variants. For single\n * transfers, the length of the `id` and `amount` arrays will be 1.\n *\n * Calling conditions (for each `id` and `amount` pair):\n *\n * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * of token type `id` will be transferred to `to`.\n * - When `from` is zero, `amount` tokens of token type `id` will be minted\n * for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n * will be burned.\n * - `from` and `to` are never both zero.\n * - `ids` and `amounts` have the same, non-zero length.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {}\n\n function _doSafeTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155Receiver.onERC1155Received.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non-ERC1155Receiver implementer\");\n }\n }\n }\n\n function _doSafeBatchTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (\n bytes4 response\n ) {\n if (response != IERC1155Receiver.onERC1155BatchReceived.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non-ERC1155Receiver implementer\");\n }\n }\n }\n\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {\n uint256[] memory array = new uint256[](1);\n array[0] = element;\n\n return array;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC1155.sol\";\n\n/**\n * @dev Interface of the optional ERC1155MetadataExtension interface, as defined\n * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155MetadataURI is IERC1155 {\n /**\n * @dev Returns the URI for token type `id`.\n *\n * If the `\\{id\\}` substring is present in the URI, it must be replaced by\n * clients with the actual token type ID.\n */\n function uri(uint256 id) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155 is IERC165 {\n /**\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n */\n event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);\n\n /**\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n * transfers.\n */\n event TransferBatch(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\n\n /**\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n * `approved`.\n */\n event ApprovalForAll(address indexed account, address indexed operator, bool approved);\n\n /**\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n *\n * If an {URI} event was emitted for `id`, the standard\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n * returned by {IERC1155MetadataURI-uri}.\n */\n event URI(string value, uint256 indexed id);\n\n /**\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) external view returns (uint256);\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] calldata accounts,\n uint256[] calldata ids\n ) external view returns (uint256[] memory);\n\n /**\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n *\n * Emits an {ApprovalForAll} event.\n *\n * Requirements:\n *\n * - `operator` cannot be the caller.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n *\n * See {setApprovalForAll}.\n */\n function isApprovedForAll(address account, address operator) external view returns (bool);\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155Receiver is IERC165 {\n /**\n * @dev Handles the receipt of a single ERC1155 token type. This function is\n * called at the end of a `safeTransferFrom` after the balance has been updated.\n *\n * NOTE: To accept the transfer, this must return\n * `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n * (i.e. 0xf23a6e61, or its own function selector).\n *\n * @param operator The address which initiated the transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param id The ID of the token being transferred\n * @param value The amount of tokens being transferred\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n ) external returns (bytes4);\n\n /**\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\n * is called at the end of a `safeBatchTransferFrom` after the balances have\n * been updated.\n *\n * NOTE: To accept the transfer(s), this must return\n * `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n * (i.e. 0xbc197c81, or its own function selector).\n *\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the default value returned by this function, unless\n * it's overridden.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(address from, address to, uint256 amount) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\n // decrementing then incrementing.\n _balances[to] += amount;\n }\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n unchecked {\n // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\n _balances[account] += amount;\n }\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n // Overflow not possible: amount <= accountBalance <= totalSupply.\n _totalSupply -= amount;\n }\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\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" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` 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 amount) 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 `amount` as the allowance of `spender` over the 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 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` 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 amount) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/ERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721.sol\";\nimport \"./IERC721Receiver.sol\";\nimport \"./extensions/IERC721Metadata.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/Strings.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\n using Address for address;\n using Strings for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\n\n // Mapping from token ID to approved address\n mapping(uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return\n interfaceId == type(IERC721).interfaceId ||\n interfaceId == type(IERC721Metadata).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _ownerOf(tokenId);\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token owner or approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n _requireMinted(tokenId);\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n _safeTransfer(from, to, tokenId, data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(address from, address to, uint256 tokenId, bytes memory data) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist\n */\n function _ownerOf(uint256 tokenId) internal view virtual returns (address) {\n return _owners[tokenId];\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _ownerOf(tokenId) != address(0);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n address owner = ERC721.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(address to, uint256 tokenId, bytes memory data) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId, 1);\n\n // Check that tokenId was not minted by `_beforeTokenTransfer` hook\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n unchecked {\n // Will not overflow unless all 2**256 token ids are minted to the same owner.\n // Given that tokens are minted one by one, it is impossible in practice that\n // this ever happens. Might change if we allow batch minting.\n // The ERC fails to describe this case.\n _balances[to] += 1;\n }\n\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(address(0), to, tokenId, 1);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n * This is an internal function that does not check if the sender is authorized to operate on the token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId, 1);\n\n // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook\n owner = ERC721.ownerOf(tokenId);\n\n // Clear approvals\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // Cannot overflow, as that would require more tokens to be burned/transferred\n // out than the owner initially received through minting and transferring in.\n _balances[owner] -= 1;\n }\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(owner, address(0), tokenId, 1);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(address from, address to, uint256 tokenId) internal virtual {\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId, 1);\n\n // Check that tokenId was not transferred by `_beforeTokenTransfer` hook\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n\n // Clear approvals from the previous owner\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // `_balances[from]` cannot overflow for the same reason as described in `_burn`:\n // `from`'s balance is the number of token held, which is at least one before the current\n // transfer.\n // `_balances[to]` could overflow in the conditions described in `_mint`. That would require\n // all 2**256 token ids to be minted, which in practice is impossible.\n _balances[from] -= 1;\n _balances[to] += 1;\n }\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId, 1);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721Receiver.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`.\n * - When `from` is zero, the tokens will be minted for `to`.\n * - When `to` is zero, ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}\n\n /**\n * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`.\n * - When `from` is zero, the tokens were minted for `to`.\n * - When `to` is zero, ``from``'s tokens were burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}\n\n /**\n * @dev Unsafe write access to the balances, used by extensions that \"mint\" tokens using an {ownerOf} override.\n *\n * WARNING: Anyone calling this MUST ensure that the balances remain consistent with the ownership. The invariant\n * being that for any address `a` the value returned by `balanceOf(a)` must be equal to the number of tokens such\n * that `ownerOf(tokenId)` is `a`.\n */\n // solhint-disable-next-line func-name-mixedcase\n function __unsafe_increaseBalance(address account, uint256 amount) internal {\n _balances[account] += amount;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721Receiver {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/ERC777.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC777/ERC777.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC777.sol\";\nimport \"./IERC777Recipient.sol\";\nimport \"./IERC777Sender.sol\";\nimport \"../ERC20/IERC20.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/introspection/IERC1820Registry.sol\";\n\n/**\n * @dev Implementation of the {IERC777} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n *\n * Support for ERC20 is included in this contract, as specified by the EIP: both\n * the ERC777 and ERC20 interfaces can be safely used when interacting with it.\n * Both {IERC777-Sent} and {IERC20-Transfer} events are emitted on token\n * movements.\n *\n * Additionally, the {IERC777-granularity} value is hard-coded to `1`, meaning that there\n * are no special restrictions in the amount of tokens that created, moved, or\n * destroyed. This makes integration with ERC20 applications seamless.\n *\n * CAUTION: This file is deprecated as of v4.9 and will be removed in the next major release.\n */\ncontract ERC777 is Context, IERC777, IERC20 {\n using Address for address;\n\n IERC1820Registry internal constant _ERC1820_REGISTRY = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n mapping(address => uint256) private _balances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n bytes32 private constant _TOKENS_SENDER_INTERFACE_HASH = keccak256(\"ERC777TokensSender\");\n bytes32 private constant _TOKENS_RECIPIENT_INTERFACE_HASH = keccak256(\"ERC777TokensRecipient\");\n\n // This isn't ever read from - it's only used to respond to the defaultOperators query.\n address[] private _defaultOperatorsArray;\n\n // Immutable, but accounts may revoke them (tracked in __revokedDefaultOperators).\n mapping(address => bool) private _defaultOperators;\n\n // For each account, a mapping of its operators and revoked default operators.\n mapping(address => mapping(address => bool)) private _operators;\n mapping(address => mapping(address => bool)) private _revokedDefaultOperators;\n\n // ERC20-allowances\n mapping(address => mapping(address => uint256)) private _allowances;\n\n /**\n * @dev `defaultOperators` may be an empty array.\n */\n constructor(string memory name_, string memory symbol_, address[] memory defaultOperators_) {\n _name = name_;\n _symbol = symbol_;\n\n _defaultOperatorsArray = defaultOperators_;\n for (uint256 i = 0; i < defaultOperators_.length; i++) {\n _defaultOperators[defaultOperators_[i]] = true;\n }\n\n // register interfaces\n _ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256(\"ERC777Token\"), address(this));\n _ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256(\"ERC20Token\"), address(this));\n }\n\n /**\n * @dev See {IERC777-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC777-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {ERC20-decimals}.\n *\n * Always returns 18, as per the\n * [ERC777 EIP](https://eips.ethereum.org/EIPS/eip-777#backward-compatibility).\n */\n function decimals() public pure virtual returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC777-granularity}.\n *\n * This implementation always returns `1`.\n */\n function granularity() public view virtual override returns (uint256) {\n return 1;\n }\n\n /**\n * @dev See {IERC777-totalSupply}.\n */\n function totalSupply() public view virtual override(IERC20, IERC777) returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev Returns the amount of tokens owned by an account (`tokenHolder`).\n */\n function balanceOf(address tokenHolder) public view virtual override(IERC20, IERC777) returns (uint256) {\n return _balances[tokenHolder];\n }\n\n /**\n * @dev See {IERC777-send}.\n *\n * Also emits a {IERC20-Transfer} event for ERC20 compatibility.\n */\n function send(address recipient, uint256 amount, bytes memory data) public virtual override {\n _send(_msgSender(), recipient, amount, data, \"\", true);\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Unlike `send`, `recipient` is _not_ required to implement the {IERC777Recipient}\n * interface if it is a contract.\n *\n * Also emits a {Sent} event.\n */\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n _send(_msgSender(), recipient, amount, \"\", \"\", false);\n return true;\n }\n\n /**\n * @dev See {IERC777-burn}.\n *\n * Also emits a {IERC20-Transfer} event for ERC20 compatibility.\n */\n function burn(uint256 amount, bytes memory data) public virtual override {\n _burn(_msgSender(), amount, data, \"\");\n }\n\n /**\n * @dev See {IERC777-isOperatorFor}.\n */\n function isOperatorFor(address operator, address tokenHolder) public view virtual override returns (bool) {\n return\n operator == tokenHolder ||\n (_defaultOperators[operator] && !_revokedDefaultOperators[tokenHolder][operator]) ||\n _operators[tokenHolder][operator];\n }\n\n /**\n * @dev See {IERC777-authorizeOperator}.\n */\n function authorizeOperator(address operator) public virtual override {\n require(_msgSender() != operator, \"ERC777: authorizing self as operator\");\n\n if (_defaultOperators[operator]) {\n delete _revokedDefaultOperators[_msgSender()][operator];\n } else {\n _operators[_msgSender()][operator] = true;\n }\n\n emit AuthorizedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-revokeOperator}.\n */\n function revokeOperator(address operator) public virtual override {\n require(operator != _msgSender(), \"ERC777: revoking self as operator\");\n\n if (_defaultOperators[operator]) {\n _revokedDefaultOperators[_msgSender()][operator] = true;\n } else {\n delete _operators[_msgSender()][operator];\n }\n\n emit RevokedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-defaultOperators}.\n */\n function defaultOperators() public view virtual override returns (address[] memory) {\n return _defaultOperatorsArray;\n }\n\n /**\n * @dev See {IERC777-operatorSend}.\n *\n * Emits {Sent} and {IERC20-Transfer} events.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes memory data,\n bytes memory operatorData\n ) public virtual override {\n require(isOperatorFor(_msgSender(), sender), \"ERC777: caller is not an operator for holder\");\n _send(sender, recipient, amount, data, operatorData, true);\n }\n\n /**\n * @dev See {IERC777-operatorBurn}.\n *\n * Emits {Burned} and {IERC20-Transfer} events.\n */\n function operatorBurn(\n address account,\n uint256 amount,\n bytes memory data,\n bytes memory operatorData\n ) public virtual override {\n require(isOperatorFor(_msgSender(), account), \"ERC777: caller is not an operator for holder\");\n _burn(account, amount, data, operatorData);\n }\n\n /**\n * @dev See {IERC20-allowance}.\n *\n * Note that operator and allowance concepts are orthogonal: operators may\n * not have allowance, and accounts with allowance may not be operators\n * themselves.\n */\n function allowance(address holder, address spender) public view virtual override returns (uint256) {\n return _allowances[holder][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Note that accounts cannot have allowance issued by their operators.\n */\n function approve(address spender, uint256 value) public virtual override returns (bool) {\n address holder = _msgSender();\n _approve(holder, spender, value);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Note that operator and allowance concepts are orthogonal: operators cannot\n * call `transferFrom` (unless they have allowance), and accounts with\n * allowance cannot call `operatorSend` (unless they are operators).\n *\n * Emits {Sent}, {IERC20-Transfer} and {IERC20-Approval} events.\n */\n function transferFrom(address holder, address recipient, uint256 amount) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(holder, spender, amount);\n _send(holder, recipient, amount, \"\", \"\", false);\n return true;\n }\n\n /**\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with the caller address as the `operator` and with\n * `userData` and `operatorData`.\n *\n * See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits {Minted} and {IERC20-Transfer} events.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - if `account` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function _mint(address account, uint256 amount, bytes memory userData, bytes memory operatorData) internal virtual {\n _mint(account, amount, userData, operatorData, true);\n }\n\n /**\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * If `requireReceptionAck` is set to true, and if a send hook is\n * registered for `account`, the corresponding function will be called with\n * `operator`, `data` and `operatorData`.\n *\n * See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits {Minted} and {IERC20-Transfer} events.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - if `account` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function _mint(\n address account,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) internal virtual {\n require(account != address(0), \"ERC777: mint to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), account, amount);\n\n // Update state variables\n _totalSupply += amount;\n _balances[account] += amount;\n\n _callTokensReceived(operator, address(0), account, amount, userData, operatorData, requireReceptionAck);\n\n emit Minted(operator, account, amount, userData, operatorData);\n emit Transfer(address(0), account, amount);\n }\n\n /**\n * @dev Send tokens\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _send(\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) internal virtual {\n require(from != address(0), \"ERC777: transfer from the zero address\");\n require(to != address(0), \"ERC777: transfer to the zero address\");\n\n address operator = _msgSender();\n\n _callTokensToSend(operator, from, to, amount, userData, operatorData);\n\n _move(operator, from, to, amount, userData, operatorData);\n\n _callTokensReceived(operator, from, to, amount, userData, operatorData, requireReceptionAck);\n }\n\n /**\n * @dev Burn tokens\n * @param from address token holder address\n * @param amount uint256 amount of tokens to burn\n * @param data bytes extra information provided by the token holder\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _burn(address from, uint256 amount, bytes memory data, bytes memory operatorData) internal virtual {\n require(from != address(0), \"ERC777: burn from the zero address\");\n\n address operator = _msgSender();\n\n _callTokensToSend(operator, from, address(0), amount, data, operatorData);\n\n _beforeTokenTransfer(operator, from, address(0), amount);\n\n // Update state variables\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC777: burn amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Burned(operator, from, amount, data, operatorData);\n emit Transfer(from, address(0), amount);\n }\n\n function _move(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n ) private {\n _beforeTokenTransfer(operator, from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC777: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Sent(operator, from, to, amount, userData, operatorData);\n emit Transfer(from, to, amount);\n }\n\n /**\n * @dev See {ERC20-_approve}.\n *\n * Note that accounts cannot have allowance issued by their operators.\n */\n function _approve(address holder, address spender, uint256 value) internal virtual {\n require(holder != address(0), \"ERC777: approve from the zero address\");\n require(spender != address(0), \"ERC777: approve to the zero address\");\n\n _allowances[holder][spender] = value;\n emit Approval(holder, spender, value);\n }\n\n /**\n * @dev Call from.tokensToSend() if the interface is registered\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _callTokensToSend(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n ) private {\n address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(from, _TOKENS_SENDER_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Sender(implementer).tokensToSend(operator, from, to, amount, userData, operatorData);\n }\n }\n\n /**\n * @dev Call to.tokensReceived() if the interface is registered. Reverts if the recipient is a contract but\n * tokensReceived() was not registered for the recipient\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _callTokensReceived(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) private {\n address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(to, _TOKENS_RECIPIENT_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Recipient(implementer).tokensReceived(operator, from, to, amount, userData, operatorData);\n } else if (requireReceptionAck) {\n require(!to.isContract(), \"ERC777: token recipient contract has no implementer for ERC777TokensRecipient\");\n }\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {IERC20-Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC777: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes\n * calls to {send}, {transfer}, {operatorSend}, {transferFrom}, minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be to transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address operator, address from, address to, uint256 amount) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC777/IERC777.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777Token standard as defined in the EIP.\n *\n * This contract uses the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 registry standard] to let\n * token holders and recipients react to token movements by using setting implementers\n * for the associated interfaces in said registry. See {IERC1820Registry} and\n * {ERC1820Implementer}.\n */\ninterface IERC777 {\n /**\n * @dev Emitted when `amount` tokens are created by `operator` and assigned to `to`.\n *\n * Note that some additional user `data` and `operatorData` can be logged in the event.\n */\n event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);\n\n /**\n * @dev Emitted when `operator` destroys `amount` tokens from `account`.\n *\n * Note that some additional user `data` and `operatorData` can be logged in the event.\n */\n event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);\n\n /**\n * @dev Emitted when `operator` is made operator for `tokenHolder`.\n */\n event AuthorizedOperator(address indexed operator, address indexed tokenHolder);\n\n /**\n * @dev Emitted when `operator` is revoked its operator status for `tokenHolder`.\n */\n event RevokedOperator(address indexed operator, address indexed tokenHolder);\n\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, usually a shorter version of the\n * name.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the smallest part of the token that is not divisible. This\n * means all token operations (creation, movement and destruction) must have\n * amounts that are a multiple of this number.\n *\n * For most token contracts, this value will equal 1.\n */\n function granularity() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by an account (`owner`).\n */\n function balanceOf(address owner) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * If send or receive hooks are registered for the caller and `recipient`,\n * the corresponding functions will be called with `data` and empty\n * `operatorData`. See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits a {Sent} event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function send(address recipient, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Destroys `amount` tokens from the caller's account, reducing the\n * total supply.\n *\n * If a send hook is registered for the caller, the corresponding function\n * will be called with `data` and empty `operatorData`. See {IERC777Sender}.\n *\n * Emits a {Burned} event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n */\n function burn(uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Returns true if an account is an operator of `tokenHolder`.\n * Operators can send and burn tokens on behalf of their owners. All\n * accounts are their own operator.\n *\n * See {operatorSend} and {operatorBurn}.\n */\n function isOperatorFor(address operator, address tokenHolder) external view returns (bool);\n\n /**\n * @dev Make an account an operator of the caller.\n *\n * See {isOperatorFor}.\n *\n * Emits an {AuthorizedOperator} event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function authorizeOperator(address operator) external;\n\n /**\n * @dev Revoke an account's operator status for the caller.\n *\n * See {isOperatorFor} and {defaultOperators}.\n *\n * Emits a {RevokedOperator} event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function revokeOperator(address operator) external;\n\n /**\n * @dev Returns the list of default operators. These accounts are operators\n * for all token holders, even if {authorizeOperator} was never called on\n * them.\n *\n * This list is immutable, but individual holders may revoke these via\n * {revokeOperator}, in which case {isOperatorFor} will return false.\n */\n function defaultOperators() external view returns (address[] memory);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must\n * be an operator of `sender`.\n *\n * If send or receive hooks are registered for `sender` and `recipient`,\n * the corresponding functions will be called with `data` and\n * `operatorData`. See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits a {Sent} event.\n *\n * Requirements\n *\n * - `sender` cannot be the zero address.\n * - `sender` must have at least `amount` tokens.\n * - the caller must be an operator for `sender`.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes calldata data,\n bytes calldata operatorData\n ) external;\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the total supply.\n * The caller must be an operator of `account`.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with `data` and `operatorData`. See {IERC777Sender}.\n *\n * Emits a {Burned} event.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n * - the caller must be an operator for `account`.\n */\n function operatorBurn(address account, uint256 amount, bytes calldata data, bytes calldata operatorData) external;\n\n event Sent(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes data,\n bytes operatorData\n );\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\n *\n * Accounts can be notified of {IERC777} tokens being sent to them by having a\n * contract implement this interface (contract holders can be their own\n * implementer) and registering it on the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\n *\n * See {IERC1820Registry} and {ERC1820Implementer}.\n */\ninterface IERC777Recipient {\n /**\n * @dev Called by an {IERC777} token contract whenever tokens are being\n * moved or created into a registered account (`to`). The type of operation\n * is conveyed by `from` being the zero address or not.\n *\n * This call occurs _after_ the token contract's state is updated, so\n * {IERC777-balanceOf}, etc., can be used to query the post-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensReceived(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777Sender.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Sender.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777TokensSender standard as defined in the EIP.\n *\n * {IERC777} Token holders can be notified of operations performed on their\n * tokens by having a contract implement this interface (contract holders can be\n * their own implementer) and registering it on the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\n *\n * See {IERC1820Registry} and {ERC1820Implementer}.\n */\ninterface IERC777Sender {\n /**\n * @dev Called by an {IERC777} token contract whenever a registered holder's\n * (`from`) tokens are about to be moved or destroyed. The type of operation\n * is conveyed by `to` being the zero address or not.\n *\n * This call occurs _before_ the token contract's state is updated, so\n * {IERC777-balanceOf}, etc., can be used to query the pre-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensToSend(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n *\n * Furthermore, `isContract` will also return true if the target contract within\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n * which only has an effect at the end of a transaction.\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Counters.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary Counters {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/ECDSA.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Strings.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV // Deprecated in v4.8\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n /// @solidity memory-safe-assembly\n assembly {\n mstore(0x00, \"\\x19Ethereum Signed Message:\\n32\")\n mstore(0x1c, hash)\n message := keccak256(0x00, 0x3c)\n }\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\n /// @solidity memory-safe-assembly\n assembly {\n let ptr := mload(0x40)\n mstore(ptr, \"\\x19\\x01\")\n mstore(add(ptr, 0x02), domainSeparator)\n mstore(add(ptr, 0x22), structHash)\n data := keccak256(ptr, 0x42)\n }\n }\n\n /**\n * @dev Returns an Ethereum Signed Data with intended validator, created from a\n * `validator` and `data` according to the version 0 of EIP-191.\n *\n * See {recover}.\n */\n function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x00\", validator, data));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/SignatureChecker.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSA.sol\";\nimport \"../../interfaces/IERC1271.sol\";\n\n/**\n * @dev Signature verification helper that can be used instead of `ECDSA.recover` to seamlessly support both ECDSA\n * signatures from externally owned accounts (EOAs) as well as ERC1271 signatures from smart contract wallets like\n * Argent and Gnosis Safe.\n *\n * _Available since v4.1._\n */\nlibrary SignatureChecker {\n /**\n * @dev Checks if a signature is valid for a given signer and data hash. If the signer is a smart contract, the\n * signature is validated against that smart contract using ERC1271, otherwise it's validated using `ECDSA.recover`.\n *\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\n */\n function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature) internal view returns (bool) {\n (address recovered, ECDSA.RecoverError error) = ECDSA.tryRecover(hash, signature);\n return\n (error == ECDSA.RecoverError.NoError && recovered == signer) ||\n isValidERC1271SignatureNow(signer, hash, signature);\n }\n\n /**\n * @dev Checks if a signature is valid for a given signer and data hash. The signature is validated\n * against the signer smart contract using ERC1271.\n *\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\n */\n function isValidERC1271SignatureNow(\n address signer,\n bytes32 hash,\n bytes memory signature\n ) internal view returns (bool) {\n (bool success, bytes memory result) = signer.staticcall(\n abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, signature)\n );\n return (success &&\n result.length >= 32 &&\n abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/ERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165 is IERC165 {\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165).interfaceId;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC1820Registry.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/introspection/IERC1820Registry.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the global ERC1820 Registry, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register\n * implementers for interfaces in this registry, as well as query support.\n *\n * Implementers may be shared by multiple accounts, and can also implement more\n * than a single interface for each account. Contracts can implement interfaces\n * for themselves, but externally-owned accounts (EOA) must delegate this to a\n * contract.\n *\n * {IERC165} interfaces can also be queried via the registry.\n *\n * For an in-depth explanation and source code analysis, see the EIP text.\n */\ninterface IERC1820Registry {\n event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer);\n\n event ManagerChanged(address indexed account, address indexed newManager);\n\n /**\n * @dev Sets `newManager` as the manager for `account`. A manager of an\n * account is able to set interface implementers for it.\n *\n * By default, each account is its own manager. Passing a value of `0x0` in\n * `newManager` will reset the manager to this initial state.\n *\n * Emits a {ManagerChanged} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `account`.\n */\n function setManager(address account, address newManager) external;\n\n /**\n * @dev Returns the manager for `account`.\n *\n * See {setManager}.\n */\n function getManager(address account) external view returns (address);\n\n /**\n * @dev Sets the `implementer` contract as ``account``'s implementer for\n * `interfaceHash`.\n *\n * `account` being the zero address is an alias for the caller's address.\n * The zero address can also be used in `implementer` to remove an old one.\n *\n * See {interfaceHash} to learn how these are created.\n *\n * Emits an {InterfaceImplementerSet} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `account`.\n * - `interfaceHash` must not be an {IERC165} interface id (i.e. it must not\n * end in 28 zeroes).\n * - `implementer` must implement {IERC1820Implementer} and return true when\n * queried for support, unless `implementer` is the caller. See\n * {IERC1820Implementer-canImplementInterfaceForAddress}.\n */\n function setInterfaceImplementer(address account, bytes32 _interfaceHash, address implementer) external;\n\n /**\n * @dev Returns the implementer of `interfaceHash` for `account`. If no such\n * implementer is registered, returns the zero address.\n *\n * If `interfaceHash` is an {IERC165} interface id (i.e. it ends with 28\n * zeroes), `account` will be queried for support of it.\n *\n * `account` being the zero address is an alias for the caller's address.\n */\n function getInterfaceImplementer(address account, bytes32 _interfaceHash) external view returns (address);\n\n /**\n * @dev Returns the interface hash for an `interfaceName`, as defined in the\n * corresponding\n * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP].\n */\n function interfaceHash(string calldata interfaceName) external pure returns (bytes32);\n\n /**\n * @notice Updates the cache with whether the contract implements an ERC165 interface or not.\n * @param account Address of the contract for which to update the cache.\n * @param interfaceId ERC165 interface for which to update the cache.\n */\n function updateERC165Cache(address account, bytes4 interfaceId) external;\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not.\n * If the result is not cached a direct lookup on the contract address is performed.\n * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling\n * {updateERC165Cache} with the contract address.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool);\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not without using or updating the cache.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/math/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\n // The surrounding unchecked block does not change this fact.\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1, \"Math: mulDiv overflow\");\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n //\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n //\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n //\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1 << (log2(a) >> 1);\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = sqrt(a);\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 2, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 128;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 64;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 32;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 16;\n }\n if (value >> 8 > 0) {\n value >>= 8;\n result += 8;\n }\n if (value >> 4 > 0) {\n value >>= 4;\n result += 4;\n }\n if (value >> 2 > 0) {\n value >>= 2;\n result += 2;\n }\n if (value >> 1 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log2(value);\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 10, rounded down, of a positive value.\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 + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 256, rounded down, of a positive value.\n * Returns 0 if given 0.\n *\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n */\n function log256(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 16;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 8;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 4;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 2;\n }\n if (value >> 8 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log256(value);\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/SafeCast.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCast {\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 * _Available since v4.7._\n */\n function toUint248(uint256 value) internal pure returns (uint248) {\n require(value <= type(uint248).max, \"SafeCast: value doesn't fit in 248 bits\");\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 * _Available since v4.7._\n */\n function toUint240(uint256 value) internal pure returns (uint240) {\n require(value <= type(uint240).max, \"SafeCast: value doesn't fit in 240 bits\");\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 * _Available since v4.7._\n */\n function toUint232(uint256 value) internal pure returns (uint232) {\n require(value <= type(uint232).max, \"SafeCast: value doesn't fit in 232 bits\");\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 * _Available since v4.2._\n */\n function toUint224(uint256 value) internal pure returns (uint224) {\n require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\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 * _Available since v4.7._\n */\n function toUint216(uint256 value) internal pure returns (uint216) {\n require(value <= type(uint216).max, \"SafeCast: value doesn't fit in 216 bits\");\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 * _Available since v4.7._\n */\n function toUint208(uint256 value) internal pure returns (uint208) {\n require(value <= type(uint208).max, \"SafeCast: value doesn't fit in 208 bits\");\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 * _Available since v4.7._\n */\n function toUint200(uint256 value) internal pure returns (uint200) {\n require(value <= type(uint200).max, \"SafeCast: value doesn't fit in 200 bits\");\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 * _Available since v4.7._\n */\n function toUint192(uint256 value) internal pure returns (uint192) {\n require(value <= type(uint192).max, \"SafeCast: value doesn't fit in 192 bits\");\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 * _Available since v4.7._\n */\n function toUint184(uint256 value) internal pure returns (uint184) {\n require(value <= type(uint184).max, \"SafeCast: value doesn't fit in 184 bits\");\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 * _Available since v4.7._\n */\n function toUint176(uint256 value) internal pure returns (uint176) {\n require(value <= type(uint176).max, \"SafeCast: value doesn't fit in 176 bits\");\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 * _Available since v4.7._\n */\n function toUint168(uint256 value) internal pure returns (uint168) {\n require(value <= type(uint168).max, \"SafeCast: value doesn't fit in 168 bits\");\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 * _Available since v4.7._\n */\n function toUint160(uint256 value) internal pure returns (uint160) {\n require(value <= type(uint160).max, \"SafeCast: value doesn't fit in 160 bits\");\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 * _Available since v4.7._\n */\n function toUint152(uint256 value) internal pure returns (uint152) {\n require(value <= type(uint152).max, \"SafeCast: value doesn't fit in 152 bits\");\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 * _Available since v4.7._\n */\n function toUint144(uint256 value) internal pure returns (uint144) {\n require(value <= type(uint144).max, \"SafeCast: value doesn't fit in 144 bits\");\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 * _Available since v4.7._\n */\n function toUint136(uint256 value) internal pure returns (uint136) {\n require(value <= type(uint136).max, \"SafeCast: value doesn't fit in 136 bits\");\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 * _Available since v2.5._\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\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 * _Available since v4.7._\n */\n function toUint120(uint256 value) internal pure returns (uint120) {\n require(value <= type(uint120).max, \"SafeCast: value doesn't fit in 120 bits\");\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 * _Available since v4.7._\n */\n function toUint112(uint256 value) internal pure returns (uint112) {\n require(value <= type(uint112).max, \"SafeCast: value doesn't fit in 112 bits\");\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 * _Available since v4.7._\n */\n function toUint104(uint256 value) internal pure returns (uint104) {\n require(value <= type(uint104).max, \"SafeCast: value doesn't fit in 104 bits\");\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 * _Available since v4.2._\n */\n function toUint96(uint256 value) internal pure returns (uint96) {\n require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\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 * _Available since v4.7._\n */\n function toUint88(uint256 value) internal pure returns (uint88) {\n require(value <= type(uint88).max, \"SafeCast: value doesn't fit in 88 bits\");\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 * _Available since v4.7._\n */\n function toUint80(uint256 value) internal pure returns (uint80) {\n require(value <= type(uint80).max, \"SafeCast: value doesn't fit in 80 bits\");\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 * _Available since v4.7._\n */\n function toUint72(uint256 value) internal pure returns (uint72) {\n require(value <= type(uint72).max, \"SafeCast: value doesn't fit in 72 bits\");\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 * _Available since v2.5._\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\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 * _Available since v4.7._\n */\n function toUint56(uint256 value) internal pure returns (uint56) {\n require(value <= type(uint56).max, \"SafeCast: value doesn't fit in 56 bits\");\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 * _Available since v4.7._\n */\n function toUint48(uint256 value) internal pure returns (uint48) {\n require(value <= type(uint48).max, \"SafeCast: value doesn't fit in 48 bits\");\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 * _Available since v4.7._\n */\n function toUint40(uint256 value) internal pure returns (uint40) {\n require(value <= type(uint40).max, \"SafeCast: value doesn't fit in 40 bits\");\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 * _Available since v2.5._\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\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 * _Available since v4.7._\n */\n function toUint24(uint256 value) internal pure returns (uint24) {\n require(value <= type(uint24).max, \"SafeCast: value doesn't fit in 24 bits\");\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 * _Available since v2.5._\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\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 * _Available since v2.5._\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\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 * _Available since v3.0._\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\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 * _Available since v4.7._\n */\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\n downcasted = int248(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 248 bits\");\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 * _Available since v4.7._\n */\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\n downcasted = int240(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 240 bits\");\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 * _Available since v4.7._\n */\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\n downcasted = int232(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 232 bits\");\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 * _Available since v4.7._\n */\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\n downcasted = int224(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 224 bits\");\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 * _Available since v4.7._\n */\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\n downcasted = int216(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 216 bits\");\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 * _Available since v4.7._\n */\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\n downcasted = int208(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 208 bits\");\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 * _Available since v4.7._\n */\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\n downcasted = int200(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 200 bits\");\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 * _Available since v4.7._\n */\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\n downcasted = int192(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 192 bits\");\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 * _Available since v4.7._\n */\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\n downcasted = int184(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 184 bits\");\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 * _Available since v4.7._\n */\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\n downcasted = int176(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 176 bits\");\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 * _Available since v4.7._\n */\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\n downcasted = int168(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 168 bits\");\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 * _Available since v4.7._\n */\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\n downcasted = int160(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 160 bits\");\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 * _Available since v4.7._\n */\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\n downcasted = int152(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 152 bits\");\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 * _Available since v4.7._\n */\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\n downcasted = int144(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 144 bits\");\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 * _Available since v4.7._\n */\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\n downcasted = int136(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 136 bits\");\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 * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\n downcasted = int128(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 128 bits\");\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 * _Available since v4.7._\n */\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\n downcasted = int120(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 120 bits\");\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 * _Available since v4.7._\n */\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\n downcasted = int112(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 112 bits\");\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 * _Available since v4.7._\n */\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\n downcasted = int104(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 104 bits\");\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 * _Available since v4.7._\n */\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\n downcasted = int96(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 96 bits\");\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 * _Available since v4.7._\n */\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\n downcasted = int88(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 88 bits\");\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 * _Available since v4.7._\n */\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\n downcasted = int80(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 80 bits\");\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 * _Available since v4.7._\n */\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\n downcasted = int72(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 72 bits\");\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 * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\n downcasted = int64(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 64 bits\");\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 * _Available since v4.7._\n */\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\n downcasted = int56(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 56 bits\");\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 * _Available since v4.7._\n */\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\n downcasted = int48(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 48 bits\");\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 * _Available since v4.7._\n */\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\n downcasted = int40(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 40 bits\");\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 * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\n downcasted = int32(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 32 bits\");\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 * _Available since v4.7._\n */\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\n downcasted = int24(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 24 bits\");\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 * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\n downcasted = int16(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 16 bits\");\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 * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\n downcasted = int8(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 8 bits\");\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 * _Available since v3.0._\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 require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/SignedMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard signed math utilities missing in the Solidity language.\n */\nlibrary SignedMath {\n /**\n * @dev Returns the largest of two signed numbers.\n */\n function max(int256 a, int256 b) internal pure returns (int256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two signed numbers.\n */\n function min(int256 a, int256 b) internal pure returns (int256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two signed numbers without overflow.\n * The result is rounded towards zero.\n */\n function average(int256 a, int256 b) internal pure returns (int256) {\n // Formula from the book \"Hacker's Delight\"\n int256 x = (a & b) + ((a ^ b) >> 1);\n return x + (int256(uint256(x) >> 255) & (a ^ b));\n }\n\n /**\n * @dev Returns the absolute unsigned value of a signed value.\n */\n function abs(int256 n) internal pure returns (uint256) {\n unchecked {\n // must be unchecked in order to support `n = type(int256).min`\n return uint256(n >= 0 ? n : -n);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/Math.sol\";\nimport \"./math/SignedMath.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n unchecked {\n uint256 length = Math.log10(value) + 1;\n string memory buffer = new string(length);\n uint256 ptr;\n /// @solidity memory-safe-assembly\n assembly {\n ptr := add(buffer, add(32, length))\n }\n while (true) {\n ptr--;\n /// @solidity memory-safe-assembly\n assembly {\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n }\n value /= 10;\n if (value == 0) break;\n }\n return buffer;\n }\n }\n\n /**\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\n */\n function toString(int256 value) internal pure returns (string memory) {\n return string(abi.encodePacked(value < 0 ? \"-\" : \"\", toString(SignedMath.abs(value))));\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n unchecked {\n return toHexString(value, Math.log256(value) + 1);\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n\n /**\n * @dev Returns true if the two strings are equal.\n */\n function equal(string memory a, string memory b) internal pure returns (bool) {\n return keccak256(bytes(a)) == keccak256(bytes(b));\n }\n}\n" + }, + "contracts/aa-4337/core/BaseAccount.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-empty-blocks */\n\nimport \"../interfaces/IAccount.sol\";\nimport \"../interfaces/IEntryPoint.sol\";\nimport \"./Helpers.sol\";\n\n/**\n * Basic account implementation.\n * this contract provides the basic logic for implementing the IAccount interface - validateUserOp\n * specific account implementation should inherit it and provide the account-specific logic\n */\nabstract contract BaseAccount is IAccount {\n using UserOperationLib for UserOperation;\n\n //return value in case of signature failure, with no time-range.\n // equivalent to _packValidationData(true,0,0);\n uint256 internal constant SIG_VALIDATION_FAILED = 1;\n\n /**\n * Return the account nonce.\n * This method returns the next sequential nonce.\n * For a nonce of a specific key, use `entrypoint.getNonce(account, key)`\n */\n function getNonce() public view virtual returns (uint256) {\n return entryPoint().getNonce(address(this), 0);\n }\n\n /**\n * return the entryPoint used by this account.\n * subclass should return the current entryPoint used by this account.\n */\n function entryPoint() public view virtual returns (IEntryPoint);\n\n /**\n * Validate user's signature and nonce.\n * subclass doesn't need to override this method. Instead, it should override the specific internal validation methods.\n */\n function validateUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 missingAccountFunds\n ) external virtual override returns (uint256 validationData) {\n _requireFromEntryPoint();\n validationData = _validateSignature(userOp, userOpHash);\n _validateNonce(userOp.nonce);\n _payPrefund(missingAccountFunds);\n }\n\n /**\n * ensure the request comes from the known entrypoint.\n */\n function _requireFromEntryPoint() internal view virtual {\n require(\n msg.sender == address(entryPoint()),\n \"account: not from EntryPoint\"\n );\n }\n\n /**\n * validate the signature is valid for this message.\n * @param userOp validate the userOp.signature field\n * @param userOpHash convenient field: the hash of the request, to check the signature against\n * (also hashes the entrypoint and chain id)\n * @return validationData signature and time-range of this operation\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * If the account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function _validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) internal virtual returns (uint256 validationData);\n\n /**\n * Validate the nonce of the UserOperation.\n * This method may validate the nonce requirement of this account.\n * e.g.\n * To limit the nonce to use sequenced UserOps only (no \"out of order\" UserOps):\n * `require(nonce < type(uint64).max)`\n * For a hypothetical account that *requires* the nonce to be out-of-order:\n * `require(nonce & type(uint64).max == 0)`\n *\n * The actual nonce uniqueness is managed by the EntryPoint, and thus no other\n * action is needed by the account itself.\n *\n * @param nonce to validate\n *\n * solhint-disable-next-line no-empty-blocks\n */\n function _validateNonce(uint256 nonce) internal view virtual {}\n\n /**\n * sends to the entrypoint (msg.sender) the missing funds for this transaction.\n * subclass MAY override this method for better funds management\n * (e.g. send to the entryPoint more than the minimum required, so that in future transactions\n * it will not be required to send again)\n * @param missingAccountFunds the minimum value this method should send the entrypoint.\n * this value MAY be zero, in case there is enough deposit, or the userOp has a paymaster.\n */\n function _payPrefund(uint256 missingAccountFunds) internal virtual {\n if (missingAccountFunds != 0) {\n (bool success, ) = payable(msg.sender).call{\n value: missingAccountFunds,\n gas: type(uint256).max\n }(\"\");\n (success);\n //ignore failure (its EntryPoint's job to verify, not account.)\n }\n }\n}\n" + }, + "contracts/aa-4337/core/EntryPoint.sol": { + "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n\nimport \"../interfaces/IAccount.sol\";\nimport \"../interfaces/IPaymaster.sol\";\nimport \"../interfaces/IEntryPoint.sol\";\n\nimport \"../utils/Exec.sol\";\nimport \"./StakeManager.sol\";\nimport \"./SenderCreator.sol\";\nimport \"./Helpers.sol\";\nimport \"./NonceManager.sol\";\nimport \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\n\ncontract EntryPoint is\n IEntryPoint,\n StakeManager,\n NonceManager,\n ReentrancyGuard\n{\n using UserOperationLib for UserOperation;\n\n SenderCreator private immutable senderCreator = new SenderCreator();\n\n // internal value used during simulation: need to query aggregator.\n address private constant SIMULATE_FIND_AGGREGATOR = address(1);\n\n // marker for inner call revert on out of gas\n bytes32 private constant INNER_OUT_OF_GAS = hex\"deaddead\";\n\n uint256 private constant REVERT_REASON_MAX_LEN = 2048;\n\n /**\n * for simulation purposes, validateUserOp (and validatePaymasterUserOp) must return this value\n * in case of signature failure, instead of revert.\n */\n uint256 public constant SIG_VALIDATION_FAILED = 1;\n\n /**\n * compensate the caller's beneficiary address with the collected fees of all UserOperations.\n * @param beneficiary the address to receive the fees\n * @param amount amount to transfer.\n */\n function _compensate(address payable beneficiary, uint256 amount) internal {\n require(beneficiary != address(0), \"AA90 invalid beneficiary\");\n (bool success, ) = beneficiary.call{value: amount}(\"\");\n require(success, \"AA91 failed send to beneficiary\");\n }\n\n /**\n * execute a user op\n * @param opIndex index into the opInfo array\n * @param userOp the userOp to execute\n * @param opInfo the opInfo filled by validatePrepayment for this userOp.\n * @return collected the total amount this userOp paid.\n */\n function _executeUserOp(\n uint256 opIndex,\n UserOperation calldata userOp,\n UserOpInfo memory opInfo\n ) private returns (uint256 collected) {\n uint256 preGas = gasleft();\n bytes memory context = getMemoryBytesFromOffset(opInfo.contextOffset);\n\n try this.innerHandleOp(userOp.callData, opInfo, context) returns (\n uint256 _actualGasCost\n ) {\n collected = _actualGasCost;\n } catch {\n bytes32 innerRevertCode;\n assembly {\n returndatacopy(0, 0, 32)\n innerRevertCode := mload(0)\n }\n // handleOps was called with gas limit too low. abort entire bundle.\n if (innerRevertCode == INNER_OUT_OF_GAS) {\n //report paymaster, since if it is not deliberately caused by the bundler,\n // it must be a revert caused by paymaster.\n revert FailedOp(opIndex, \"AA95 out of gas\");\n }\n\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n collected = _handlePostOp(\n opIndex,\n IPaymaster.PostOpMode.postOpReverted,\n opInfo,\n context,\n actualGas\n );\n }\n }\n\n /**\n * Execute a batch of UserOperations.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(\n UserOperation[] calldata ops,\n address payable beneficiary\n ) public nonReentrant {\n uint256 opslen = ops.length;\n UserOpInfo[] memory opInfos = new UserOpInfo[](opslen);\n\n unchecked {\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[i];\n (\n uint256 validationData,\n uint256 pmValidationData\n ) = _validatePrepayment(i, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(\n i,\n validationData,\n pmValidationData,\n address(0)\n );\n }\n\n uint256 collected = 0;\n emit BeforeExecution();\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(i, ops[i], opInfos[i]);\n }\n\n _compensate(beneficiary, collected);\n } //unchecked\n }\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) public nonReentrant {\n uint256 opasLen = opsPerAggregator.length;\n uint256 totalOps = 0;\n for (uint256 i = 0; i < opasLen; i++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[i];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n //address(1) is special marker of \"signature error\"\n require(\n address(aggregator) != address(1),\n \"AA96 invalid aggregator\"\n );\n\n if (address(aggregator) != address(0)) {\n // solhint-disable-next-line no-empty-blocks\n try aggregator.validateSignatures(ops, opa.signature) {} catch {\n revert SignatureValidationFailed(address(aggregator));\n }\n }\n\n totalOps += ops.length;\n }\n\n UserOpInfo[] memory opInfos = new UserOpInfo[](totalOps);\n\n emit BeforeExecution();\n\n uint256 opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n uint256 opslen = ops.length;\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[opIndex];\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(opIndex, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(\n i,\n validationData,\n paymasterValidationData,\n address(aggregator)\n );\n opIndex++;\n }\n }\n\n uint256 collected = 0;\n opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n emit SignatureAggregatorChanged(address(opa.aggregator));\n UserOperation[] calldata ops = opa.userOps;\n uint256 opslen = ops.length;\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(opIndex, ops[i], opInfos[opIndex]);\n opIndex++;\n }\n }\n emit SignatureAggregatorChanged(address(0));\n\n _compensate(beneficiary, collected);\n }\n\n /// @inheritdoc IEntryPoint\n function simulateHandleOp(\n UserOperation calldata op,\n address target,\n bytes calldata targetCallData\n ) external override {\n UserOpInfo memory opInfo;\n _simulationOnlyValidations(op);\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(0, op, opInfo);\n ValidationData memory data = _intersectTimeRange(\n validationData,\n paymasterValidationData\n );\n\n numberMarker();\n uint256 paid = _executeUserOp(0, op, opInfo);\n numberMarker();\n bool targetSuccess;\n bytes memory targetResult;\n if (target != address(0)) {\n (targetSuccess, targetResult) = target.call(targetCallData);\n }\n revert ExecutionResult(\n opInfo.preOpGas,\n paid,\n data.validAfter,\n data.validUntil,\n targetSuccess,\n targetResult\n );\n }\n\n // A memory copy of UserOp static fields only.\n // Excluding: callData, initCode and signature. Replacing paymasterAndData with paymaster.\n struct MemoryUserOp {\n address sender;\n uint256 nonce;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n address paymaster;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n }\n\n struct UserOpInfo {\n MemoryUserOp mUserOp;\n bytes32 userOpHash;\n uint256 prefund;\n uint256 contextOffset;\n uint256 preOpGas;\n }\n\n /**\n * inner function to handle a UserOperation.\n * Must be declared \"external\" to open a call context, but it can only be called by handleOps.\n */\n function innerHandleOp(\n bytes memory callData,\n UserOpInfo memory opInfo,\n bytes calldata context\n ) external returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n require(msg.sender == address(this), \"AA92 internal call only\");\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n\n uint callGasLimit = mUserOp.callGasLimit;\n unchecked {\n // handleOps was called with gas limit too low. abort entire bundle.\n if (\n gasleft() < callGasLimit + mUserOp.verificationGasLimit + 5000\n ) {\n assembly {\n mstore(0, INNER_OUT_OF_GAS)\n revert(0, 32)\n }\n }\n }\n\n IPaymaster.PostOpMode mode = IPaymaster.PostOpMode.opSucceeded;\n if (callData.length > 0) {\n bool success = Exec.call(mUserOp.sender, 0, callData, callGasLimit);\n if (!success) {\n bytes memory result = Exec.getReturnData(REVERT_REASON_MAX_LEN);\n if (result.length > 0) {\n emit UserOperationRevertReason(\n opInfo.userOpHash,\n mUserOp.sender,\n mUserOp.nonce,\n result\n );\n }\n mode = IPaymaster.PostOpMode.opReverted;\n }\n }\n\n unchecked {\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n //note: opIndex is ignored (relevant only if mode==postOpReverted, which is only possible outside of innerHandleOp)\n return _handlePostOp(0, mode, opInfo, context, actualGas);\n }\n }\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(\n UserOperation calldata userOp\n ) public view returns (bytes32) {\n return\n keccak256(abi.encode(userOp.hash(), address(this), block.chainid));\n }\n\n /**\n * copy general fields from userOp into the memory opInfo structure.\n */\n function _copyUserOpToMemory(\n UserOperation calldata userOp,\n MemoryUserOp memory mUserOp\n ) internal pure {\n mUserOp.sender = userOp.sender;\n mUserOp.nonce = userOp.nonce;\n mUserOp.callGasLimit = userOp.callGasLimit;\n mUserOp.verificationGasLimit = userOp.verificationGasLimit;\n mUserOp.preVerificationGas = userOp.preVerificationGas;\n mUserOp.maxFeePerGas = userOp.maxFeePerGas;\n mUserOp.maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes calldata paymasterAndData = userOp.paymasterAndData;\n if (paymasterAndData.length > 0) {\n require(\n paymasterAndData.length >= 20,\n \"AA93 invalid paymasterAndData\"\n );\n mUserOp.paymaster = address(bytes20(paymasterAndData[:20]));\n } else {\n mUserOp.paymaster = address(0);\n }\n }\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external {\n UserOpInfo memory outOpInfo;\n\n _simulationOnlyValidations(userOp);\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(0, userOp, outOpInfo);\n StakeInfo memory paymasterInfo = _getStakeInfo(\n outOpInfo.mUserOp.paymaster\n );\n StakeInfo memory senderInfo = _getStakeInfo(outOpInfo.mUserOp.sender);\n StakeInfo memory factoryInfo;\n {\n bytes calldata initCode = userOp.initCode;\n address factory = initCode.length >= 20\n ? address(bytes20(initCode[0:20]))\n : address(0);\n factoryInfo = _getStakeInfo(factory);\n }\n\n ValidationData memory data = _intersectTimeRange(\n validationData,\n paymasterValidationData\n );\n address aggregator = data.aggregator;\n bool sigFailed = aggregator == address(1);\n ReturnInfo memory returnInfo = ReturnInfo(\n outOpInfo.preOpGas,\n outOpInfo.prefund,\n sigFailed,\n data.validAfter,\n data.validUntil,\n getMemoryBytesFromOffset(outOpInfo.contextOffset)\n );\n\n if (aggregator != address(0) && aggregator != address(1)) {\n AggregatorStakeInfo memory aggregatorInfo = AggregatorStakeInfo(\n aggregator,\n _getStakeInfo(aggregator)\n );\n revert ValidationResultWithAggregation(\n returnInfo,\n senderInfo,\n factoryInfo,\n paymasterInfo,\n aggregatorInfo\n );\n }\n revert ValidationResult(\n returnInfo,\n senderInfo,\n factoryInfo,\n paymasterInfo\n );\n }\n\n function _getRequiredPrefund(\n MemoryUserOp memory mUserOp\n ) internal pure returns (uint256 requiredPrefund) {\n unchecked {\n //when using a Paymaster, the verificationGasLimit is used also to as a limit for the postOp call.\n // our security model might call postOp eventually twice\n uint256 mul = mUserOp.paymaster != address(0) ? 3 : 1;\n uint256 requiredGas = mUserOp.callGasLimit +\n mUserOp.verificationGasLimit *\n mul +\n mUserOp.preVerificationGas;\n\n requiredPrefund = requiredGas * mUserOp.maxFeePerGas;\n }\n }\n\n // create the sender's contract if needed.\n function _createSenderIfNeeded(\n uint256 opIndex,\n UserOpInfo memory opInfo,\n bytes calldata initCode\n ) internal {\n if (initCode.length != 0) {\n address sender = opInfo.mUserOp.sender;\n if (sender.code.length != 0)\n revert FailedOp(opIndex, \"AA10 sender already constructed\");\n address sender1 = senderCreator.createSender{\n gas: opInfo.mUserOp.verificationGasLimit\n }(initCode);\n if (sender1 == address(0))\n revert FailedOp(opIndex, \"AA13 initCode failed or OOG\");\n if (sender1 != sender)\n revert FailedOp(opIndex, \"AA14 initCode must return sender\");\n if (sender1.code.length == 0)\n revert FailedOp(opIndex, \"AA15 initCode must create sender\");\n address factory = address(bytes20(initCode[0:20]));\n emit AccountDeployed(\n opInfo.userOpHash,\n sender,\n factory,\n opInfo.mUserOp.paymaster\n );\n }\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes calldata initCode) public {\n address sender = senderCreator.createSender(initCode);\n revert SenderAddressResult(sender);\n }\n\n function _simulationOnlyValidations(\n UserOperation calldata userOp\n ) internal view {\n // solhint-disable-next-line no-empty-blocks\n try\n this._validateSenderAndPaymaster(\n userOp.initCode,\n userOp.sender,\n userOp.paymasterAndData\n )\n {} catch Error(string memory revertReason) {\n if (bytes(revertReason).length != 0) {\n revert FailedOp(0, revertReason);\n }\n }\n }\n\n /**\n * Called only during simulation.\n * This function always reverts to prevent warm/cold storage differentiation in simulation vs execution.\n */\n function _validateSenderAndPaymaster(\n bytes calldata initCode,\n address sender,\n bytes calldata paymasterAndData\n ) external view {\n if (initCode.length == 0 && sender.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA20 account not deployed\");\n }\n if (paymasterAndData.length >= 20) {\n address paymaster = address(bytes20(paymasterAndData[0:20]));\n if (paymaster.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA30 paymaster not deployed\");\n }\n }\n // always revert\n revert(\"\");\n }\n\n /**\n * call account.validateUserOp.\n * revert (with FailedOp) in case validateUserOp reverts, or account didn't send required prefund.\n * decrement account's deposit if needed\n */\n function _validateAccountPrepayment(\n uint256 opIndex,\n UserOperation calldata op,\n UserOpInfo memory opInfo,\n uint256 requiredPrefund\n )\n internal\n returns (\n uint256 gasUsedByValidateAccountPrepayment,\n uint256 validationData\n )\n {\n unchecked {\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n address sender = mUserOp.sender;\n _createSenderIfNeeded(opIndex, opInfo, op.initCode);\n address paymaster = mUserOp.paymaster;\n numberMarker();\n uint256 missingAccountFunds = 0;\n if (paymaster == address(0)) {\n uint256 bal = balanceOf(sender);\n missingAccountFunds = bal > requiredPrefund\n ? 0\n : requiredPrefund - bal;\n }\n try\n IAccount(sender).validateUserOp{\n gas: mUserOp.verificationGasLimit\n }(op, opInfo.userOpHash, missingAccountFunds)\n returns (uint256 _validationData) {\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA23 reverted: \", revertReason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA23 reverted (or OOG)\");\n }\n if (paymaster == address(0)) {\n DepositInfo storage senderInfo = deposits[sender];\n uint256 deposit = senderInfo.deposit;\n if (requiredPrefund > deposit) {\n revert FailedOp(opIndex, \"AA21 didn't pay prefund\");\n }\n senderInfo.deposit = uint112(deposit - requiredPrefund);\n }\n gasUsedByValidateAccountPrepayment = preGas - gasleft();\n }\n }\n\n /**\n * In case the request has a paymaster:\n * Validate paymaster has enough deposit.\n * Call paymaster.validatePaymasterUserOp.\n * Revert with proper FailedOp in case paymaster reverts.\n * Decrement paymaster's deposit\n */\n function _validatePaymasterPrepayment(\n uint256 opIndex,\n UserOperation calldata op,\n UserOpInfo memory opInfo,\n uint256 requiredPreFund,\n uint256 gasUsedByValidateAccountPrepayment\n ) internal returns (bytes memory context, uint256 validationData) {\n unchecked {\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 verificationGasLimit = mUserOp.verificationGasLimit;\n require(\n verificationGasLimit > gasUsedByValidateAccountPrepayment,\n \"AA41 too little verificationGas\"\n );\n uint256 gas = verificationGasLimit -\n gasUsedByValidateAccountPrepayment;\n\n address paymaster = mUserOp.paymaster;\n DepositInfo storage paymasterInfo = deposits[paymaster];\n uint256 deposit = paymasterInfo.deposit;\n if (deposit < requiredPreFund) {\n revert FailedOp(opIndex, \"AA31 paymaster deposit too low\");\n }\n paymasterInfo.deposit = uint112(deposit - requiredPreFund);\n try\n IPaymaster(paymaster).validatePaymasterUserOp{gas: gas}(\n op,\n opInfo.userOpHash,\n requiredPreFund\n )\n returns (bytes memory _context, uint256 _validationData) {\n context = _context;\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA33 reverted: \", revertReason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA33 reverted (or OOG)\");\n }\n }\n }\n\n /**\n * revert if either account validationData or paymaster validationData is expired\n */\n function _validateAccountAndPaymasterValidationData(\n uint256 opIndex,\n uint256 validationData,\n uint256 paymasterValidationData,\n address expectedAggregator\n ) internal view {\n (address aggregator, bool outOfTimeRange) = _getValidationData(\n validationData\n );\n if (expectedAggregator != aggregator) {\n revert FailedOp(opIndex, \"AA24 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA22 expired or not due\");\n }\n //pmAggregator is not a real signature aggregator: we don't have logic to handle it as address.\n // non-zero address means that the paymaster fails due to some signature check (which is ok only during estimation)\n address pmAggregator;\n (pmAggregator, outOfTimeRange) = _getValidationData(\n paymasterValidationData\n );\n if (pmAggregator != address(0)) {\n revert FailedOp(opIndex, \"AA34 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA32 paymaster expired or not due\");\n }\n }\n\n function _getValidationData(\n uint256 validationData\n ) internal view returns (address aggregator, bool outOfTimeRange) {\n if (validationData == 0) {\n return (address(0), false);\n }\n ValidationData memory data = _parseValidationData(validationData);\n // solhint-disable-next-line not-rely-on-time\n outOfTimeRange =\n block.timestamp > data.validUntil ||\n block.timestamp < data.validAfter;\n aggregator = data.aggregator;\n }\n\n /**\n * validate account and paymaster (if defined).\n * also make sure total validation doesn't exceed verificationGasLimit\n * this method is called off-chain (simulateValidation()) and on-chain (from handleOps)\n * @param opIndex the index of this userOp into the \"opInfos\" array\n * @param userOp the userOp to validate\n */\n function _validatePrepayment(\n uint256 opIndex,\n UserOperation calldata userOp,\n UserOpInfo memory outOpInfo\n )\n private\n returns (uint256 validationData, uint256 paymasterValidationData)\n {\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = outOpInfo.mUserOp;\n _copyUserOpToMemory(userOp, mUserOp);\n outOpInfo.userOpHash = getUserOpHash(userOp);\n\n // validate all numeric values in userOp are well below 128 bit, so they can safely be added\n // and multiplied without causing overflow\n uint256 maxGasValues = mUserOp.preVerificationGas |\n mUserOp.verificationGasLimit |\n mUserOp.callGasLimit |\n userOp.maxFeePerGas |\n userOp.maxPriorityFeePerGas;\n require(maxGasValues <= type(uint120).max, \"AA94 gas values overflow\");\n\n uint256 gasUsedByValidateAccountPrepayment;\n uint256 requiredPreFund = _getRequiredPrefund(mUserOp);\n (\n gasUsedByValidateAccountPrepayment,\n validationData\n ) = _validateAccountPrepayment(\n opIndex,\n userOp,\n outOpInfo,\n requiredPreFund\n );\n\n if (!_validateAndUpdateNonce(mUserOp.sender, mUserOp.nonce)) {\n revert FailedOp(opIndex, \"AA25 invalid account nonce\");\n }\n\n //a \"marker\" where account opcode validation is done and paymaster opcode validation is about to start\n // (used only by off-chain simulateValidation)\n numberMarker();\n\n bytes memory context;\n if (mUserOp.paymaster != address(0)) {\n (context, paymasterValidationData) = _validatePaymasterPrepayment(\n opIndex,\n userOp,\n outOpInfo,\n requiredPreFund,\n gasUsedByValidateAccountPrepayment\n );\n }\n unchecked {\n uint256 gasUsed = preGas - gasleft();\n\n if (userOp.verificationGasLimit < gasUsed) {\n revert FailedOp(opIndex, \"AA40 over verificationGasLimit\");\n }\n outOpInfo.prefund = requiredPreFund;\n outOpInfo.contextOffset = getOffsetOfMemoryBytes(context);\n outOpInfo.preOpGas = preGas - gasleft() + userOp.preVerificationGas;\n }\n }\n\n /**\n * process post-operation.\n * called just after the callData is executed.\n * if a paymaster is defined and its validation returned a non-empty context, its postOp is called.\n * the excess amount is refunded to the account (or paymaster - if it was used in the request)\n * @param opIndex index in the batch\n * @param mode - whether is called from innerHandleOp, or outside (postOpReverted)\n * @param opInfo userOp fields and info collected during validation\n * @param context the context returned in validatePaymasterUserOp\n * @param actualGas the gas used so far by this user operation\n */\n function _handlePostOp(\n uint256 opIndex,\n IPaymaster.PostOpMode mode,\n UserOpInfo memory opInfo,\n bytes memory context,\n uint256 actualGas\n ) private returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n unchecked {\n address refundAddress;\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 gasPrice = getUserOpGasPrice(mUserOp);\n\n address paymaster = mUserOp.paymaster;\n if (paymaster == address(0)) {\n refundAddress = mUserOp.sender;\n } else {\n refundAddress = paymaster;\n if (context.length > 0) {\n actualGasCost = actualGas * gasPrice;\n if (mode != IPaymaster.PostOpMode.postOpReverted) {\n IPaymaster(paymaster).postOp{\n gas: mUserOp.verificationGasLimit\n }(mode, context, actualGasCost);\n } else {\n // solhint-disable-next-line no-empty-blocks\n try\n IPaymaster(paymaster).postOp{\n gas: mUserOp.verificationGasLimit\n }(mode, context, actualGasCost)\n {} catch Error(string memory reason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA50 postOp reverted: \", reason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA50 postOp revert\");\n }\n }\n }\n }\n actualGas += preGas - gasleft();\n actualGasCost = actualGas * gasPrice;\n if (opInfo.prefund < actualGasCost) {\n revert FailedOp(opIndex, \"AA51 prefund below actualGasCost\");\n }\n uint256 refund = opInfo.prefund - actualGasCost;\n _incrementDeposit(refundAddress, refund);\n bool success = mode == IPaymaster.PostOpMode.opSucceeded;\n emit UserOperationEvent(\n opInfo.userOpHash,\n mUserOp.sender,\n mUserOp.paymaster,\n mUserOp.nonce,\n success,\n actualGasCost,\n actualGas\n );\n } // unchecked\n }\n\n /**\n * the gas price this UserOp agrees to pay.\n * relayer/block builder might submit the TX with higher priorityFee, but the user should not\n */\n function getUserOpGasPrice(\n MemoryUserOp memory mUserOp\n ) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = mUserOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = mUserOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n function getOffsetOfMemoryBytes(\n bytes memory data\n ) internal pure returns (uint256 offset) {\n assembly {\n offset := data\n }\n }\n\n function getMemoryBytesFromOffset(\n uint256 offset\n ) internal pure returns (bytes memory data) {\n assembly {\n data := offset\n }\n }\n\n //place the NUMBER opcode in the code.\n // this is used as a marker during simulation, as this OP is completely banned from the simulated code of the\n // account and paymaster.\n function numberMarker() internal view {\n assembly {\n mstore(0, number())\n }\n }\n}\n" + }, + "contracts/aa-4337/core/Helpers.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable no-inline-assembly */\n\n/**\n * returned data from validateUserOp.\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\n * @param aggregator - address(0) - the account validated the signature by itself.\n * address(1) - the account failed to validate the signature.\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\n * @param validAfter - this UserOp is valid only after this timestamp.\n * @param validaUntil - this UserOp is valid only up to this timestamp.\n */\nstruct ValidationData {\n address aggregator;\n uint48 validAfter;\n uint48 validUntil;\n}\n\n//extract sigFailed, validAfter, validUntil.\n// also convert zero validUntil to type(uint48).max\nfunction _parseValidationData(\n uint validationData\n) pure returns (ValidationData memory data) {\n address aggregator = address(uint160(validationData));\n uint48 validUntil = uint48(validationData >> 160);\n if (validUntil == 0) {\n validUntil = type(uint48).max;\n }\n uint48 validAfter = uint48(validationData >> (48 + 160));\n return ValidationData(aggregator, validAfter, validUntil);\n}\n\n// intersect account and paymaster ranges.\nfunction _intersectTimeRange(\n uint256 validationData,\n uint256 paymasterValidationData\n) pure returns (ValidationData memory) {\n ValidationData memory accountValidationData = _parseValidationData(\n validationData\n );\n ValidationData memory pmValidationData = _parseValidationData(\n paymasterValidationData\n );\n address aggregator = accountValidationData.aggregator;\n if (aggregator == address(0)) {\n aggregator = pmValidationData.aggregator;\n }\n uint48 validAfter = accountValidationData.validAfter;\n uint48 validUntil = accountValidationData.validUntil;\n uint48 pmValidAfter = pmValidationData.validAfter;\n uint48 pmValidUntil = pmValidationData.validUntil;\n\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\n return ValidationData(aggregator, validAfter, validUntil);\n}\n\n/**\n * helper to pack the return value for validateUserOp\n * @param data - the ValidationData to pack\n */\nfunction _packValidationData(\n ValidationData memory data\n) pure returns (uint256) {\n return\n uint160(data.aggregator) |\n (uint256(data.validUntil) << 160) |\n (uint256(data.validAfter) << (160 + 48));\n}\n\n/**\n * helper to pack the return value for validateUserOp, when not using an aggregator\n * @param sigFailed - true for signature failure, false for success\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\n * @param validAfter first timestamp this UserOperation is valid\n */\nfunction _packValidationData(\n bool sigFailed,\n uint48 validUntil,\n uint48 validAfter\n) pure returns (uint256) {\n return\n (sigFailed ? 1 : 0) |\n (uint256(validUntil) << 160) |\n (uint256(validAfter) << (160 + 48));\n}\n\n/**\n * keccak function over calldata.\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\n */\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\n assembly {\n let mem := mload(0x40)\n let len := data.length\n calldatacopy(mem, data.offset, len)\n ret := keccak256(mem, len)\n }\n}\n" + }, + "contracts/aa-4337/core/NonceManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\nimport \"../interfaces/IEntryPoint.sol\";\n\n/**\n * nonce management functionality\n */\ncontract NonceManager is INonceManager {\n /**\n * The next valid sequence number for a given nonce key.\n */\n mapping(address => mapping(uint192 => uint256)) public nonceSequenceNumber;\n\n function getNonce(\n address sender,\n uint192 key\n ) public view override returns (uint256 nonce) {\n return nonceSequenceNumber[sender][key] | (uint256(key) << 64);\n }\n\n // allow an account to manually increment its own nonce.\n // (mainly so that during construction nonce can be made non-zero,\n // to \"absorb\" the gas cost of first nonce increment to 1st transaction (construction),\n // not to 2nd transaction)\n function incrementNonce(uint192 key) public override {\n nonceSequenceNumber[msg.sender][key]++;\n }\n\n /**\n * validate nonce uniqueness for this account.\n * called just after validateUserOp()\n */\n function _validateAndUpdateNonce(\n address sender,\n uint256 nonce\n ) internal returns (bool) {\n uint192 key = uint192(nonce >> 64);\n uint64 seq = uint64(nonce);\n return nonceSequenceNumber[sender][key]++ == seq;\n }\n}\n" + }, + "contracts/aa-4337/core/SenderCreator.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/**\n * helper contract for EntryPoint, to call userOp.initCode from a \"neutral\" address,\n * which is explicitly not the entryPoint itself.\n */\ncontract SenderCreator {\n /**\n * call the \"initCode\" factory to create and return the sender account address\n * @param initCode the initCode value from a UserOp. contains 20 bytes of factory address, followed by calldata\n * @return sender the returned address of the created account, or zero address on failure.\n */\n function createSender(\n bytes calldata initCode\n ) external returns (address sender) {\n address factory = address(bytes20(initCode[0:20]));\n bytes memory initCallData = initCode[20:];\n bool success;\n /* solhint-disable no-inline-assembly */\n assembly {\n success := call(\n gas(),\n factory,\n 0,\n add(initCallData, 0x20),\n mload(initCallData),\n 0,\n 32\n )\n sender := mload(0)\n }\n if (!success) {\n sender = address(0);\n }\n }\n}\n" + }, + "contracts/aa-4337/core/StakeManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity 0.8.21;\n\nimport \"../interfaces/IStakeManager.sol\";\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable not-rely-on-time */\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by a paymaster.\n */\nabstract contract StakeManager is IStakeManager {\n /// maps paymaster to their deposits and stakes\n mapping(address => DepositInfo) public deposits;\n\n /// @inheritdoc IStakeManager\n function getDepositInfo(\n address account\n ) public view returns (DepositInfo memory info) {\n return deposits[account];\n }\n\n // internal method to return just the stake info\n function _getStakeInfo(\n address addr\n ) internal view returns (StakeInfo memory info) {\n DepositInfo storage depositInfo = deposits[addr];\n info.stake = depositInfo.stake;\n info.unstakeDelaySec = depositInfo.unstakeDelaySec;\n }\n\n /// return the deposit (for gas payment) of the account\n function balanceOf(address account) public view returns (uint256) {\n return deposits[account].deposit;\n }\n\n receive() external payable {\n depositTo(msg.sender);\n }\n\n function _incrementDeposit(address account, uint256 amount) internal {\n DepositInfo storage info = deposits[account];\n uint256 newAmount = info.deposit + amount;\n require(newAmount <= type(uint112).max, \"deposit overflow\");\n info.deposit = uint112(newAmount);\n }\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) public payable {\n _incrementDeposit(account, msg.value);\n DepositInfo storage info = deposits[account];\n emit Deposited(account, info.deposit);\n }\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 unstakeDelaySec) public payable {\n DepositInfo storage info = deposits[msg.sender];\n require(unstakeDelaySec > 0, \"must specify unstake delay\");\n require(\n unstakeDelaySec >= info.unstakeDelaySec,\n \"cannot decrease unstake time\"\n );\n uint256 stake = info.stake + msg.value;\n require(stake > 0, \"no stake specified\");\n require(stake <= type(uint112).max, \"stake overflow\");\n deposits[msg.sender] = DepositInfo(\n info.deposit,\n true,\n uint112(stake),\n unstakeDelaySec,\n 0\n );\n emit StakeLocked(msg.sender, stake, unstakeDelaySec);\n }\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external {\n DepositInfo storage info = deposits[msg.sender];\n require(info.unstakeDelaySec != 0, \"not staked\");\n require(info.staked, \"already unstaking\");\n uint48 withdrawTime = uint48(block.timestamp) + info.unstakeDelaySec;\n info.withdrawTime = withdrawTime;\n info.staked = false;\n emit StakeUnlocked(msg.sender, withdrawTime);\n }\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external {\n DepositInfo storage info = deposits[msg.sender];\n uint256 stake = info.stake;\n require(stake > 0, \"No stake to withdraw\");\n require(info.withdrawTime > 0, \"must call unlockStake() first\");\n require(\n info.withdrawTime <= block.timestamp,\n \"Stake withdrawal is not due\"\n );\n info.unstakeDelaySec = 0;\n info.withdrawTime = 0;\n info.stake = 0;\n emit StakeWithdrawn(msg.sender, withdrawAddress, stake);\n (bool success, ) = withdrawAddress.call{value: stake}(\"\");\n require(success, \"failed to withdraw stake\");\n }\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(\n address payable withdrawAddress,\n uint256 withdrawAmount\n ) external {\n DepositInfo storage info = deposits[msg.sender];\n require(withdrawAmount <= info.deposit, \"Withdraw amount too large\");\n info.deposit = uint112(info.deposit - withdrawAmount);\n emit Withdrawn(msg.sender, withdrawAddress, withdrawAmount);\n (bool success, ) = withdrawAddress.call{value: withdrawAmount}(\"\");\n require(success, \"failed to withdraw\");\n }\n}\n" + }, + "contracts/aa-4337/interfaces/IAccount.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\ninterface IAccount {\n /**\n * Validate user's signature and nonce\n * the entryPoint will make the call to the recipient only if this validation call returns successfully.\n * signature failure should be reported by returning SIG_VALIDATION_FAILED (1).\n * This allows making a \"simulation call\" without a valid signature\n * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure.\n *\n * @dev Must validate caller is the entryPoint.\n * Must validate the signature and nonce\n * @param userOp the operation that is about to be executed.\n * @param userOpHash hash of the user's request data. can be used as the basis for signature.\n * @param missingAccountFunds missing funds on the account's deposit in the entrypoint.\n * This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call.\n * The excess is left as a deposit in the entrypoint, for future calls.\n * can be withdrawn anytime using \"entryPoint.withdrawTo()\"\n * In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero.\n * @return validationData packaged ValidationData structure. use `_packValidationData` and `_unpackValidationData` to encode and decode\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * If an account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validateUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 missingAccountFunds\n ) external returns (uint256 validationData);\n}\n" + }, + "contracts/aa-4337/interfaces/IAggregator.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * Aggregated Signatures validator.\n */\ninterface IAggregator {\n /**\n * validate aggregated signature.\n * revert if the aggregated signature does not match the given list of operations.\n */\n function validateSignatures(\n UserOperation[] calldata userOps,\n bytes calldata signature\n ) external view;\n\n /**\n * validate signature of a single userOp\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\n * @param userOp the userOperation received from the user.\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\n * (usually empty, unless account and aggregator support some kind of \"multisig\"\n */\n function validateUserOpSignature(\n UserOperation calldata userOp\n ) external view returns (bytes memory sigForUserOp);\n\n /**\n * aggregate multiple signatures into a single value.\n * This method is called off-chain to calculate the signature to pass with handleOps()\n * bundler MAY use optimized custom code perform this aggregation\n * @param userOps array of UserOperations to collect the signatures from.\n * @return aggregatedSignature the aggregated signature\n */\n function aggregateSignatures(\n UserOperation[] calldata userOps\n ) external view returns (bytes memory aggregatedSignature);\n}\n" + }, + "contracts/aa-4337/interfaces/IEntryPoint.sol": { + "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n/* solhint-disable reason-string */\n\nimport \"./UserOperation.sol\";\nimport \"./IStakeManager.sol\";\nimport \"./IAggregator.sol\";\nimport \"./INonceManager.sol\";\n\ninterface IEntryPoint is IStakeManager, INonceManager {\n /***\n * An event emitted after each successful request\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\n * @param sender - the account that generates this request.\n * @param paymaster - if non-null, the paymaster that pays for this request.\n * @param nonce - the nonce value from the request.\n * @param success - true if the sender transaction succeeded, false if reverted.\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\n */\n event UserOperationEvent(\n bytes32 indexed userOpHash,\n address indexed sender,\n address indexed paymaster,\n uint256 nonce,\n bool success,\n uint256 actualGasCost,\n uint256 actualGasUsed\n );\n\n /**\n * account \"sender\" was deployed.\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\n * @param sender the account that is deployed\n * @param factory the factory used to deploy this account (in the initCode)\n * @param paymaster the paymaster used by this UserOp\n */\n event AccountDeployed(\n bytes32 indexed userOpHash,\n address indexed sender,\n address factory,\n address paymaster\n );\n\n /**\n * An event emitted if the UserOperation \"callData\" reverted with non-zero length\n * @param userOpHash the request unique identifier.\n * @param sender the sender of this request\n * @param nonce the nonce used in the request\n * @param revertReason - the return bytes from the (reverted) call to \"callData\".\n */\n event UserOperationRevertReason(\n bytes32 indexed userOpHash,\n address indexed sender,\n uint256 nonce,\n bytes revertReason\n );\n\n /**\n * an event emitted by handleOps(), before starting the execution loop.\n * any event emitted before this event, is part of the validation.\n */\n event BeforeExecution();\n\n /**\n * signature aggregator used by the following UserOperationEvents within this bundle.\n */\n event SignatureAggregatorChanged(address indexed aggregator);\n\n /**\n * a custom revert error of handleOps, to identify the offending op.\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\n * @param reason - revert reason\n * The string starts with a unique code \"AAmn\", where \"m\" is \"1\" for factory, \"2\" for account and \"3\" for paymaster issues,\n * so a failure can be attributed to the correct entity.\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\n */\n error FailedOp(uint256 opIndex, string reason);\n\n /**\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\n */\n error SignatureValidationFailed(address aggregator);\n\n /**\n * Successful result from simulateValidation.\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n */\n error ValidationResult(\n ReturnInfo returnInfo,\n StakeInfo senderInfo,\n StakeInfo factoryInfo,\n StakeInfo paymasterInfo\n );\n\n /**\n * Successful result from simulateValidation, if the account returns a signature aggregator\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\n * bundler MUST use it to verify the signature, or reject the UserOperation\n */\n error ValidationResultWithAggregation(\n ReturnInfo returnInfo,\n StakeInfo senderInfo,\n StakeInfo factoryInfo,\n StakeInfo paymasterInfo,\n AggregatorStakeInfo aggregatorInfo\n );\n\n /**\n * return value of getSenderAddress\n */\n error SenderAddressResult(address sender);\n\n /**\n * return value of simulateHandleOp\n */\n error ExecutionResult(\n uint256 preOpGas,\n uint256 paid,\n uint48 validAfter,\n uint48 validUntil,\n bool targetSuccess,\n bytes targetResult\n );\n\n //UserOps handled, per aggregator\n struct UserOpsPerAggregator {\n UserOperation[] userOps;\n // aggregator address\n IAggregator aggregator;\n // aggregated signature\n bytes signature;\n }\n\n /**\n * Execute a batch of UserOperation.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(\n UserOperation[] calldata ops,\n address payable beneficiary\n ) external;\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) external;\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(\n UserOperation calldata userOp\n ) external view returns (bytes32);\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external;\n\n /**\n * gas and return values during simulation\n * @param preOpGas the gas used for validation (including preValidationGas)\n * @param prefund the required prefund for this operation\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\n */\n struct ReturnInfo {\n uint256 preOpGas;\n uint256 prefund;\n bool sigFailed;\n uint48 validAfter;\n uint48 validUntil;\n bytes paymasterContext;\n }\n\n /**\n * returned aggregated signature info.\n * the aggregator returned by the account, and its current stake.\n */\n struct AggregatorStakeInfo {\n address aggregator;\n StakeInfo stakeInfo;\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes memory initCode) external;\n\n /**\n * simulate full execution of a UserOperation (including both validation and target execution)\n * this method will always revert with \"ExecutionResult\".\n * it performs full validation of the UserOperation, but ignores signature error.\n * an optional target address is called after the userop succeeds, and its value is returned\n * (before the entire call is reverted)\n * Note that in order to collect the the success/failure of the target call, it must be executed\n * with trace enabled to track the emitted events.\n * @param op the UserOperation to simulate\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\n * are set to the return from that call.\n * @param targetCallData callData to pass to target address\n */\n function simulateHandleOp(\n UserOperation calldata op,\n address target,\n bytes calldata targetCallData\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/INonceManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\ninterface INonceManager {\n /**\n * Return the next nonce for this sender.\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\n * But UserOp with different keys can come with arbitrary order.\n *\n * @param sender the account address\n * @param key the high 192 bit of the nonce\n * @return nonce a full nonce to pass for next UserOp with this sender.\n */\n function getNonce(\n address sender,\n uint192 key\n ) external view returns (uint256 nonce);\n\n /**\n * Manually increment the nonce of the sender.\n * This method is exposed just for completeness..\n * Account does NOT need to call it, neither during validation, nor elsewhere,\n * as the EntryPoint will update the nonce regardless.\n * Possible use-case is call it with various keys to \"initialize\" their nonces to one, so that future\n * UserOperations will not pay extra for the first transaction with a given key.\n */\n function incrementNonce(uint192 key) external;\n}\n" + }, + "contracts/aa-4337/interfaces/IPaymaster.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * the interface exposed by a paymaster contract, who agrees to pay the gas for user's operations.\n * a paymaster must hold a stake to cover the required entrypoint stake and also the gas for the transaction.\n */\ninterface IPaymaster {\n enum PostOpMode {\n opSucceeded, // user op succeeded\n opReverted, // user op reverted. still has to pay for gas.\n postOpReverted //user op succeeded, but caused postOp to revert. Now it's a 2nd call, after user's op was deliberately reverted.\n }\n\n /**\n * payment validation: check if paymaster agrees to pay.\n * Must verify sender is the entryPoint.\n * Revert to reject this request.\n * Note that bundlers will reject this method if it changes the state, unless the paymaster is trusted (whitelisted)\n * The paymaster pre-pays using its deposit, and receive back a refund after the postOp method returns.\n * @param userOp the user operation\n * @param userOpHash hash of the user's request data.\n * @param maxCost the maximum cost of this transaction (based on maximum gas and gas price from userOp)\n * @return context value to send to a postOp\n * zero length to signify postOp is not required.\n * @return validationData signature and time-range of this operation, encoded the same as the return value of validateUserOperation\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validatePaymasterUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 maxCost\n ) external returns (bytes memory context, uint256 validationData);\n\n /**\n * post-operation handler.\n * Must verify sender is the entryPoint\n * @param mode enum with the following options:\n * opSucceeded - user operation succeeded.\n * opReverted - user op reverted. still has to pay for gas.\n * postOpReverted - user op succeeded, but caused postOp (in mode=opSucceeded) to revert.\n * Now this is the 2nd call, after user's op was deliberately reverted.\n * @param context - the context value returned by validatePaymasterUserOp\n * @param actualGasCost - actual gas used so far (without this postOp call).\n */\n function postOp(\n PostOpMode mode,\n bytes calldata context,\n uint256 actualGasCost\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/IStakeManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.12;\n\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by the staked entity.\n */\ninterface IStakeManager {\n event Deposited(address indexed account, uint256 totalDeposit);\n\n event Withdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /// Emitted when stake or unstake delay are modified\n event StakeLocked(\n address indexed account,\n uint256 totalStaked,\n uint256 unstakeDelaySec\n );\n\n /// Emitted once a stake is scheduled for withdrawal\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\n\n event StakeWithdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /**\n * @param deposit the entity's deposit\n * @param staked true if this entity is staked.\n * @param stake actual amount of ether staked for this entity.\n * @param unstakeDelaySec minimum delay to withdraw the stake.\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\n * and the rest fit into a 2nd cell.\n * 112 bit allows for 10^15 eth\n * 48 bit for full timestamp\n * 32 bit allows 150 years for unstake delay\n */\n struct DepositInfo {\n uint112 deposit;\n bool staked;\n uint112 stake;\n uint32 unstakeDelaySec;\n uint48 withdrawTime;\n }\n\n //API struct used by getStakeInfo and simulateValidation\n struct StakeInfo {\n uint256 stake;\n uint256 unstakeDelaySec;\n }\n\n /// @return info - full deposit information of given account\n function getDepositInfo(\n address account\n ) external view returns (DepositInfo memory info);\n\n /// @return the deposit (for gas payment) of the account\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) external payable;\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 _unstakeDelaySec) external payable;\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external;\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external;\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(\n address payable withdrawAddress,\n uint256 withdrawAmount\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/UserOperation.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable no-inline-assembly */\n\nimport {calldataKeccak} from \"../core/Helpers.sol\";\n\n/**\n * User Operation struct\n * @param sender the sender account of this request.\n * @param nonce unique value the sender uses to verify it is not a replay.\n * @param initCode if set, the account contract will be created by this constructor/\n * @param callData the method call to execute on this account.\n * @param callGasLimit the gas limit passed to the callData method call.\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\n * @param maxFeePerGas same as EIP-1559 gas parameter.\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\n */\nstruct UserOperation {\n address sender;\n uint256 nonce;\n bytes initCode;\n bytes callData;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n bytes paymasterAndData;\n bytes signature;\n}\n\n/**\n * Utility functions helpful when working with UserOperation structs.\n */\nlibrary UserOperationLib {\n function getSender(\n UserOperation calldata userOp\n ) internal pure returns (address) {\n address data;\n //read sender from userOp, which is first userOp member (saves 800 gas...)\n assembly {\n data := calldataload(userOp)\n }\n return address(uint160(data));\n }\n\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\n // pay above what he signed for.\n function gasPrice(\n UserOperation calldata userOp\n ) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function pack(\n UserOperation calldata userOp\n ) internal pure returns (bytes memory ret) {\n address sender = getSender(userOp);\n uint256 nonce = userOp.nonce;\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\n bytes32 hashCallData = calldataKeccak(userOp.callData);\n uint256 callGasLimit = userOp.callGasLimit;\n uint256 verificationGasLimit = userOp.verificationGasLimit;\n uint256 preVerificationGas = userOp.preVerificationGas;\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\n\n return\n abi.encode(\n sender,\n nonce,\n hashInitCode,\n hashCallData,\n callGasLimit,\n verificationGasLimit,\n preVerificationGas,\n maxFeePerGas,\n maxPriorityFeePerGas,\n hashPaymasterAndData\n );\n }\n\n function hash(\n UserOperation calldata userOp\n ) internal pure returns (bytes32) {\n return keccak256(pack(userOp));\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n}\n" + }, + "contracts/aa-4337/utils/Exec.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.5 <0.9.0;\n\n// solhint-disable no-inline-assembly\n\n/**\n * Utility functions helpful when making different kinds of contract calls in Solidity.\n */\nlibrary Exec {\n function call(\n address to,\n uint256 value,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := call(\n txGas,\n to,\n value,\n add(data, 0x20),\n mload(data),\n 0,\n 0\n )\n }\n }\n\n function staticcall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal view returns (bool success) {\n assembly {\n success := staticcall(txGas, to, add(data, 0x20), mload(data), 0, 0)\n }\n }\n\n function delegateCall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := delegatecall(\n txGas,\n to,\n add(data, 0x20),\n mload(data),\n 0,\n 0\n )\n }\n }\n\n // get returned data from last call or calldelegate\n function getReturnData(\n uint256 maxLen\n ) internal pure returns (bytes memory returnData) {\n assembly {\n let len := returndatasize()\n if gt(len, maxLen) {\n len := maxLen\n }\n let ptr := mload(0x40)\n mstore(0x40, add(ptr, add(len, 0x20)))\n mstore(ptr, len)\n returndatacopy(add(ptr, 0x20), 0, len)\n returnData := ptr\n }\n }\n\n // revert with explicit byte array (probably reverted info from call)\n function revertWithData(bytes memory returnData) internal pure {\n assembly {\n revert(add(returnData, 32), mload(returnData))\n }\n }\n\n function callAndRevert(\n address to,\n bytes memory data,\n uint256 maxLen\n ) internal {\n bool success = call(to, 0, data, gasleft());\n if (!success) {\n revertWithData(getReturnData(maxLen));\n }\n }\n}\n" + }, + "contracts/Barz.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"./libraries/LibDiamond.sol\";\nimport {IBarz} from \"./interfaces/IBarz.sol\";\n\n/**\n * @title Barz\n * @dev A diamond proxy wallet with a modular & upgradeable architecture\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract Barz is IBarz {\n /**\n * @notice Initializes Barz with the given parameters. Barz account is intended to be created from Barz Factory for stable deployment.\n * @dev This method makes a delegate call to account facet and account facet handles the initialization.\n * With modular architecture, Barz encompasses wide spectrum of architecture and logic.\n * The only requirement is account facet to comply with initialize() interface.\n * Barz doesn't include built-in functions and is a full proxy, for maximum extensibility and modularity.\n * @param _accountFacet Address of Account Facet in charge of the Barz initialization\n * @param _verificationFacet Address of Verification Facet for verifying the signature. Could be any signature scheme\n * @param _entryPoint Address of Entry Point contract\n * @param _facetRegistry Address of Facet Registry. Facet Registry is a registry holding trusted facets that could be added to user's wallet\n * @param _defaultFallBack Address of Default FallBack Handler. Middleware contract for more efficient deployment\n * @param _ownerPublicKey Bytes of Owner Public Key using for initialization\n */\n constructor(\n address _accountFacet,\n address _verificationFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallBack,\n bytes memory _ownerPublicKey\n ) payable {\n bytes memory initCall = abi.encodeWithSignature(\n \"initialize(address,address,address,address,bytes)\",\n _verificationFacet,\n _entryPoint,\n _facetRegistry,\n _defaultFallBack,\n _ownerPublicKey\n );\n (bool success, bytes memory result) = _accountFacet.delegatecall(\n initCall\n );\n if (!success || uint256(bytes32(result)) != 1) {\n revert Barz__InitializationFailure();\n }\n }\n\n /**\n * @notice Fallback function for Barz complying with Diamond Standard with customization of adding Default Fallback Handler\n * @dev Find facet for function that is called and execute the function if a facet is found and return any value.\n */\n fallback() external payable {\n LibDiamond.DiamondStorage storage ds;\n bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION;\n // get diamond storage\n assembly {\n ds.slot := position\n }\n // get facet from function selector\n address facet = address(bytes20(ds.facets[msg.sig]));\n if (facet == address(0))\n facet = ds.defaultFallbackHandler.facetAddress(msg.sig);\n require(facet != address(0), \"Barz: Function does not exist\");\n // Execute external function from facet using delegatecall and return any value.\n assembly {\n // copy function selector and any arguments\n calldatacopy(0, 0, calldatasize())\n // execute function call using the facet\n let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)\n // get any return value\n returndatacopy(0, 0, returndatasize())\n // return any return value or error back to the caller\n switch result\n case 0 {\n revert(0, returndatasize())\n }\n default {\n return(0, returndatasize())\n }\n }\n }\n\n /**\n * @notice Receive function to receive native token without data\n */\n receive() external payable {}\n}\n" + }, + "contracts/BarzFactory.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Barz} from \"./Barz.sol\";\nimport {IBarzFactory} from \"./interfaces/IBarzFactory.sol\";\n\n/**\n * @title Barz Factory\n * @dev Contract to easily deploy Barz to a pre-computed address with a single call\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract BarzFactory is IBarzFactory {\n address public immutable accountFacet;\n address public immutable entryPoint;\n address public immutable facetRegistry;\n address public immutable defaultFallback;\n\n /**\n * @notice Sets the initialization data for Barz contract initialization\n * @param _accountFacet Account Facet to be used to create Barz\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\n * @param _facetRegistry Facet Registry to be used to create Barz\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\n */\n constructor(\n address _accountFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallback\n ) {\n accountFacet = _accountFacet;\n entryPoint = _entryPoint;\n facetRegistry = _facetRegistry;\n defaultFallback = _defaultFallback;\n }\n\n /**\n * @notice Creates the Barz with a single call. It creates the Barz contract with the givent verification facet\n * @param _verificationFacet Address of verification facet used for creating the barz account\n * @param _owner Public Key of the owner to initialize barz account\n * @param _salt Salt used for deploying barz with create2\n * @return barz Instance of Barz contract deployed with the given parameters\n */\n function createAccount(\n address _verificationFacet,\n bytes calldata _owner,\n uint256 _salt\n ) external override returns (Barz barz) {\n address addr = getAddress(_verificationFacet, _owner, _salt);\n uint codeSize = addr.code.length;\n if (codeSize > 0) {\n return Barz(payable(addr));\n }\n barz = new Barz{salt: bytes32(_salt)}(\n accountFacet,\n _verificationFacet,\n entryPoint,\n facetRegistry,\n defaultFallback,\n _owner\n );\n emit BarzDeployed(address(barz));\n }\n\n /**\n * @notice Calculates the address of Barz with the given parameters\n * @param _verificationFacet Address of verification facet used for creating the barz account\n * @param _owner Public Key of the owner to initialize barz account\n * @param _salt Salt used for deploying barz with create2\n * @return barzAddress Precalculated Barz address\n */\n function getAddress(\n address _verificationFacet,\n bytes calldata _owner,\n uint256 _salt\n ) public view override returns (address barzAddress) {\n bytes memory bytecode = getBytecode(\n accountFacet,\n _verificationFacet,\n entryPoint,\n facetRegistry,\n defaultFallback,\n _owner\n );\n bytes32 hash = keccak256(\n abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(bytecode)\n )\n );\n barzAddress = address(uint160(uint256(hash)));\n }\n\n /**\n * @notice Returns the bytecode of Barz with the given parameter\n * @param _accountFacet Account Facet to be used to create Barz\n * @param _verificationFacet Verification Facet to be used to create Barz\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\n * @param _facetRegistry Facet Registry to be used to create Barz\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\n * @param _ownerPublicKey Public Key of owner to be used to initialize Barz ownership\n * @return barzBytecode Bytecode of Barz\n */\n function getBytecode(\n address _accountFacet,\n address _verificationFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallback,\n bytes calldata _ownerPublicKey\n ) public pure override returns (bytes memory barzBytecode) {\n bytes memory bytecode = type(Barz).creationCode;\n barzBytecode = abi.encodePacked(\n bytecode,\n abi.encode(\n _accountFacet,\n _verificationFacet,\n _entryPoint,\n _facetRegistry,\n _defaultFallback,\n _ownerPublicKey\n )\n );\n }\n\n /**\n * @notice Returns the creation code of the Barz contract\n * @return creationCode Creation code of Barz\n */\n function getCreationCode()\n public\n pure\n override\n returns (bytes memory creationCode)\n {\n creationCode = type(Barz).creationCode;\n }\n}\n" + }, + "contracts/facets/AccountFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {UserOperation} from \"../aa-4337/interfaces/UserOperation.sol\";\nimport {IEntryPoint} from \"../aa-4337/interfaces/IEntryPoint.sol\";\nimport {BaseAccount} from \"../aa-4337/core/BaseAccount.sol\";\nimport {LibAppStorage, BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {IFacetRegistry} from \"../infrastructure/interfaces/IFacetRegistry.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {IERC1271} from \"../interfaces/ERC/IERC1271.sol\";\nimport {IAccountFacet} from \"./interfaces/IAccountFacet.sol\";\n\n/**\n * @title Account Facet\n * @dev Account module contract that provides the account features and initialization of signer\n * compatible with EIP-1271 & EIP-4337\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract AccountFacet is IAccountFacet, BarzStorage, BaseAccount {\n using ECDSA for bytes32;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceAccountInitialize();\n }\n\n /**\n * @notice Returns the address of EntryPoint contract registered to Barz account\n */\n function entryPoint() public view override returns (IEntryPoint) {\n return s.entryPoint;\n }\n\n /**\n * @notice Initializes the initial storage of the Barz contract.\n * @dev This method can only be called during the initialization or signature migration.\n * If the proxy contract was created without initialization, anyone can call initialize.\n * Barz calls initialize in constructor in an atomic transaction during deployment\n * @param _verificationFacet Facet contract handling the verificationi\n * @param _anEntryPoint Entrypoint contract defined in EIP-4337 handling the flow of UserOp\n * @param _facetRegistry Registry of Facets that hold all facet information\n * @param _defaultFallBackHandler Middleware contract for default facets\n * @param _ownerPublicKey Bytes of owner public key\n */\n function initialize(\n address _verificationFacet,\n address _anEntryPoint,\n address _facetRegistry,\n address _defaultFallBackHandler,\n bytes calldata _ownerPublicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceAccountInitialize();\n s.entryPoint = IEntryPoint(_anEntryPoint);\n s.facetRegistry = IFacetRegistry(_facetRegistry);\n LibDiamond.diamondStorage().defaultFallbackHandler = IDiamondLoupe(\n _defaultFallBackHandler\n );\n\n _cutDiamondAccountFacet(_verificationFacet);\n\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n _ownerPublicKey\n );\n // Every Verification Facet should comply with initializeSigner(bytes)\n // to be compatible with the Barz contract(for initialization)\n (bool success, bytes memory result) = _verificationFacet.delegatecall(\n initCall\n );\n if (!success || uint256(bytes32(result)) != 1) {\n revert AccountFacet__InitializationFailure();\n }\n\n initSuccess = 1;\n emit AccountInitialized(s.entryPoint, _ownerPublicKey);\n }\n\n function _cutDiamondAccountFacet(address _verificationFacet) internal {\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](1);\n\n bytes4 ownerVerificationFuncSelector = IVerificationFacet(\n _verificationFacet\n ).validateOwnerSignatureSelector();\n\n bytes4[] memory verificationFunctionSelectors = new bytes4[](3);\n verificationFunctionSelectors[0] = IERC1271.isValidSignature.selector;\n verificationFunctionSelectors[1] = ownerVerificationFuncSelector;\n verificationFunctionSelectors[2] = IVerificationFacet.owner.selector;\n cut[0] = IDiamondCut.FacetCut({\n facetAddress: _verificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: verificationFunctionSelectors\n });\n\n LibDiamond.diamondCut(cut, address(0), \"\");\n }\n\n /**\n * @notice Calls the destination with inputted calldata and value from EntryPoint\n * @dev This method executes the calldata coming from the EntryPoint.\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\n * @param _dest Address of destination where the call will be forwarded to\n * @param _value Amount of native coin the owner is willing to send(e.g. ETH, BNB)\n * @param _func Bytes of calldata to execute in the destination address\n */\n function execute(\n address _dest,\n uint256 _value,\n bytes calldata _func\n ) external override onlyWhenUnlocked {\n _requireFromEntryPoint();\n address restrictionsFacet = LibDiamond.restrictionsFacet();\n if (restrictionsFacet == address(0)) _call(_dest, _value, _func);\n else _callWithRestrictions(_dest, _value, _func, restrictionsFacet);\n }\n\n /**\n * @notice Batch calls the destination with inputted calldata and value from EntryPoint\n * @dev This method batch executes the calldata coming from the EntryPoint.\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\n * @param _dest Array of addresses of destination where the call will be forwarded to\n * @param _value Array of amount of native coin the owner is willing to send(e.g. ETH, BNB)\n * @param _func Array of bytes of calldata to execute in the destination address\n */\n function executeBatch(\n address[] calldata _dest,\n uint256[] calldata _value,\n bytes[] calldata _func\n ) external override onlyWhenUnlocked {\n _requireFromEntryPoint();\n if (_dest.length != _func.length || _dest.length != _value.length)\n revert AccountFacet__InvalidArrayLength();\n address restrictionsFacet = LibDiamond.restrictionsFacet();\n if (restrictionsFacet == address(0)) {\n for (uint256 i; i < _dest.length; ) {\n _call(_dest[i], _value[i], _func[i]);\n unchecked {\n ++i;\n }\n }\n } else {\n for (uint256 i; i < _dest.length; ) {\n _callWithRestrictions(\n _dest[i],\n _value[i],\n _func[i],\n restrictionsFacet\n );\n unchecked {\n ++i;\n }\n }\n }\n }\n\n /**\n * @notice Validates the signature field of UserOperation\n * @dev This method validates if the signature of UserOp is indeed valid by delegating the call to Verification Facet\n * Barz makes a call to the pre-registered Verification Facet address in App Storage\n * @param _userOp UserOperation from owner to be validated\n * @param _userOpHash Hash of UserOperation given from the EntryPoint contract\n */\n function _validateSignature(\n UserOperation calldata _userOp,\n bytes32 _userOpHash\n ) internal override returns (uint256 validationData) {\n // Get Facet with Function Selector\n address facet = LibLoupe.facetAddress(s.validateOwnerSignatureSelector);\n if (facet == address(0))\n revert AccountFacet__NonExistentVerificationFacet();\n\n // Make function call to VerificationFacet\n bytes memory validateCall = abi.encodeWithSelector(\n s.validateOwnerSignatureSelector,\n _userOp,\n _userOpHash\n );\n (bool success, bytes memory result) = facet.delegatecall(validateCall);\n if (!success) revert AccountFacet__CallNotSuccessful();\n validationData = uint256(bytes32(result));\n if (validationData == 0) emit VerificationSuccess(_userOpHash);\n else emit VerificationFailure(_userOpHash);\n }\n\n /**\n * @notice Calls the target with the inputted value and calldata\n * @dev This method is the actual function in Barz that makes a call with an arbitrary owner-given data\n * @param _target Address of the destination contract which the call is getting forwarded to\n * @param _value Amount of Native coin the owner is wanting to make in this call\n * @param _data Calldata the owner is forwarding together in the call e.g. Swap/Token Transfer\n */\n function _call(\n address _target,\n uint256 _value,\n bytes memory _data\n ) internal {\n (bool success, bytes memory result) = _target.call{value: _value}(\n _data\n );\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n }\n\n /**\n * @notice Calls the target with the inputted value and calldata together with restrictions check\n * @dev This method is the actual function in Barz that makes a call with an arbitrary owner-given data\n * @param _target Address of the destination contract which the call is getting forwarded to\n * @param _value Amount of Native coin the owner is wanting to make in this call\n * @param _data Calldata the owner is forwarding together in the call e.g. Swap/Token Transfer\n * @param _restrictionsFacet Address of Facet to validate restrictions\n */\n function _callWithRestrictions(\n address _target,\n uint256 _value,\n bytes memory _data,\n address _restrictionsFacet\n ) internal {\n // NOTE: No restrictions facet, so restriction validation passes\n if (_checkRestrictions(_restrictionsFacet, _target, _value, _data) != 0)\n revert AccountFacet__RestrictionsFailure();\n\n (bool success, bytes memory result) = _target.call{value: _value}(\n _data\n );\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n }\n\n /**\n * @notice Checks restrictions if the restrictions facet exists\n * @dev This method checks if the restrictions facet exists and makes a verification call to an array of restrictions facet\n * @param _facet Address that holds the restrictions logic\n * @param _target Address the call is getting forwarded to\n * @param _value Amount of native coin the call is sending together with the call\n * @param _data Calldata to trigger execution in target address\n */\n function _checkRestrictions(\n address _facet,\n address _target,\n uint256 _value,\n bytes memory _data\n ) internal returns (uint256 result) {\n bytes memory call = abi.encodeWithSignature(\n \"verifyRestrictions(address,address,uint256,bytes)\",\n address(this),\n _target,\n _value,\n _data\n );\n (bool success, bytes memory response) = _facet.delegatecall(call);\n if (!success) revert AccountFacet__RestrictionsFailure();\n result = uint256(bytes32(response));\n }\n}\n" + }, + "contracts/facets/AccountRecoveryFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibFacetStorage, RecoveryStorage, RecoveryConfig, RecoveryApprovalConfig, ApprovalConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {IAccountRecoveryFacet} from \"./interfaces/IAccountRecoveryFacet.sol\";\n\n/**\n * @title Account Recovery Facet\n * @dev Contract that enables recovery of accounts when owner key is unavailable\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract AccountRecoveryFacet is IAccountRecoveryFacet, Modifiers {\n bytes constant UNINIT_CALL =\n abi.encodeWithSignature(\"uninitializeSigner()\");\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Approve recovery of account as guardian\n * @dev This method can only be called by guardian and guardian inputs the public key of the new owner\n * When the threshold(majority of guardians) passes, it automatically executes account recovery\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function approveAccountRecovery(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + _getApprovalValidationPeriod()\n );\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit RecoveryApproved(\n _recoveryPublicKey,\n msg.sender,\n approvalValidUntil\n );\n if (\n getRecoveryApprovalCountWithTimeValidity(recoveryPublicKeyHash) >=\n LibGuardian.majorityOfGuardians()\n ) _executeRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Revoke recovery of account as guardian\n * @dev This method can only be called by guardian and guardian inputs the public key of the new owner\n When the threshold(majority of guardians) passes, it automatically revokes account recovery when recovery is pending\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function revokeAccountRecoveryApproval(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n if (\n !rs\n .isNewOwnerApproved[recoveryPublicKeyHash][msg.sender].isApproved ||\n !(block.timestamp <\n rs\n .isNewOwnerApproved[recoveryPublicKeyHash][msg.sender]\n .validUntil)\n ) revert AccountRecoveryFacet__NonExistentApproval();\n\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(false, 0);\n emit RecoveryApprovalRevoked(_recoveryPublicKey, msg.sender);\n }\n\n /**\n * @notice Executes recovery with signatures or on-chain pre-approvals\n * @dev This method validates the signatures of guardians or checks the on-chain pre-approved calls to check if the threshold passes\n * When the threshold passes, account recovery is executed and revert otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _guardians Array of guardians address that are approving the recovery of Account\n * @param _signatures Array of signature bytes that signed the approval hash\n */\n function executeRecovery(\n bytes calldata _recoveryPublicKey,\n address[] calldata _guardians,\n bytes[] calldata _signatures\n ) external override {\n if (_isRecoveryPending())\n revert AccountRecoveryFacet__RecoveryAlreadyOngoing();\n if (_guardians.length != _signatures.length)\n revert AccountRecoveryFacet__InvalidArrayLength();\n validateNewOwner(_recoveryPublicKey);\n\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n\n _checkApprover(_guardians);\n _checkDuplicateOnChainApprover(recoveryPublicKeyHash, _guardians);\n\n if (\n _guardians.length +\n getRecoveryApprovalCountWithTimeValidity(\n recoveryPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians()\n ) revert AccountRecoveryFacet__InsufficientGuardians();\n for (uint256 i; i < _guardians.length; ) {\n if (!LibGuardian.isGuardian(_guardians[i]))\n revert AccountRecoveryFacet__InvalidGuardian();\n if (\n !SignatureChecker.isValidSignatureNow(\n _guardians[i],\n recoveryPublicKeyHash,\n _signatures[i]\n )\n ) revert AccountRecoveryFacet__InvalidGuardianSignature();\n unchecked {\n ++i;\n }\n }\n _executeRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Executes recovery of the account. Note that execution and finalization is a different process\n * @dev Executes the recovery and adds recovery data to recovery configuration. Locks the account\n * @param _recoveryPublicKey Public Key of the account for recovery\n */\n function _executeRecovery(bytes memory _recoveryPublicKey) internal {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n unchecked {\n ++rs.nonce;\n }\n uint64 executeAfter = uint64(block.timestamp + _getRecoveryPeriod());\n rs.recoveryConfigs[INNER_STRUCT] = RecoveryConfig(\n _recoveryPublicKey,\n executeAfter // NOTE: Remove guardian Count\n );\n LibAppStorage.setLock(\n block.timestamp + _getLockPeriod(),\n AccountRecoveryFacet.executeRecovery.selector\n );\n emit RecoveryExecuted(_recoveryPublicKey, executeAfter);\n }\n\n /**\n * @notice Finalize recovery after recovery pending period. Recovery pending period can be set by user beforehand in SecurityManager\n * @dev This method finalizes recovery and fully changes the ownership of the account to the newly inputted recovery public key\n */\n function finalizeRecovery() external override {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n if (\n uint64(block.timestamp) <=\n rs.recoveryConfigs[INNER_STRUCT].executeAfter\n ) revert AccountRecoveryFacet__RecoveryPeriodNotOver();\n bytes memory recoveryOwner = rs\n .recoveryConfigs[INNER_STRUCT]\n .recoveryPublicKey;\n\n delete rs.recoveryConfigs[INNER_STRUCT];\n\n LibAppStorage.setLock(0, bytes4(0));\n\n LibAppStorage.initiateSignerMigration();\n address verificationFacet = address(\n bytes20(\n LibDiamond.diamondStorage().facets[\n s.validateOwnerSignatureSelector\n ]\n )\n );\n (bool success, bytes memory result) = verificationFacet.delegatecall(\n UNINIT_CALL\n );\n if (!success) revert AccountRecoveryFacet__CallNotSuccesful();\n uint256 validationData = uint256(bytes32(result));\n if (validationData != 1)\n revert AccountRecoveryFacet__SignerUninitializationFailure();\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n recoveryOwner\n );\n (success, result) = verificationFacet.delegatecall(initCall);\n if (!success) revert AccountRecoveryFacet__CallNotSuccesful();\n validationData = uint256(bytes32(result));\n if (validationData != 1)\n revert AccountRecoveryFacet__SignerInitializationFailure();\n LibAppStorage.finalizeSignerMigration();\n emit RecoveryFinalized(recoveryOwner);\n }\n\n /**\n * @notice Approves the cancellation of recovery\n * @dev This method approves the cancellation of recovery when recovery is still pending - waiting for finalization\n * @param _recoveryPublicKey Bytes of public key which is pending for recovery\n */\n function approveCancelRecovery(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"CancelRecovery\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + _getApprovalValidationPeriod()\n );\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit RecoveryCancellationApproved(_recoveryPublicKey, msg.sender);\n if (\n getRecoveryApprovalCountWithTimeValidity(recoveryPublicKeyHash) >=\n LibGuardian.majorityOfGuardians()\n ) {\n _cancelRecovery(_recoveryPublicKey);\n }\n }\n\n /**\n * @notice Hardstops an ongoing recovery\n * @dev This method provides a safety mechanism to protect owners of malicious guardians.\n * Owners can hardstop recovery when an malicious guardians starts the recovery process.\n * @param _signature Signature of the owner that signs the hash to hardstop recovery\n */\n function hardstopRecovery(bytes calldata _signature) external override {\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n \"0\",\n \"HardstopRecovery\"\n );\n if (\n !SignatureChecker.isValidSignatureNow(\n address(this),\n recoveryPublicKeyHash,\n _signature\n )\n ) revert AccountRecoveryFacet__InvalidOwnerSignature();\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n unchecked {\n ++rs.nonce;\n }\n delete rs.recoveryConfigs[INNER_STRUCT];\n LibAppStorage.setLock(0, bytes4(0));\n emit RecoveryHardstopped();\n }\n\n /**\n * @notice Cancels recovery with signatures or on-chain pre-approvals\n * @dev This method validates the signatures of guardians or checks the on-chain pre-approved calls to check if the threshold passes\n * When the threshold passes, account recovery is canceled and revert otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _guardians Array of guardians address that are approving the recovery of Account\n * @param _signatures Array of signature bytes that signed the cancellation approval hash\n */\n function cancelRecovery(\n bytes calldata _recoveryPublicKey,\n address[] calldata _guardians,\n bytes[] calldata _signatures\n ) external override {\n if (_guardians.length != _signatures.length)\n revert AccountRecoveryFacet__InvalidArrayLength();\n validateNewOwner(_recoveryPublicKey);\n\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"CancelRecovery\"\n );\n\n _checkApprover(_guardians);\n _checkDuplicateOnChainApprover(recoveryPublicKeyHash, _guardians);\n\n if (\n _guardians.length +\n getRecoveryApprovalCountWithTimeValidity(\n recoveryPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians()\n ) revert AccountRecoveryFacet__InsufficientGuardians();\n for (uint256 i; i < _guardians.length; ) {\n if (!LibGuardian.isGuardian(_guardians[i]))\n revert AccountRecoveryFacet__CallerNotGuardian();\n if (\n !SignatureChecker.isValidSignatureNow(\n _guardians[i],\n recoveryPublicKeyHash,\n _signatures[i]\n )\n ) revert AccountRecoveryFacet__InvalidGuardianSignature();\n unchecked {\n ++i;\n }\n }\n _cancelRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Cancel recovery when the recovery is pending. Unlock the account as well\n * @dev This method checks if the recovery is pending and reverts if not pending.\n * It increases the recovery nonce and deletes the recovery information and gets a small portion of gas in return\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function _cancelRecovery(bytes memory _recoveryPublicKey) internal {\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n LibAppStorage.setLock(0, bytes4(0));\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n unchecked {\n ++rs.nonce;\n }\n delete rs.recoveryConfigs[INNER_STRUCT];\n emit RecoveryCanceled(_recoveryPublicKey);\n }\n\n /**\n * @notice Validates the format of public key to be used for recovery\n * @dev This method checks if the public key format is correct and reverts otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function validateNewOwner(bytes memory _recoveryPublicKey) public view {\n if (\n !IVerificationFacet(\n LibLoupe.facetAddress(s.validateOwnerSignatureSelector)\n ).isValidKeyType(_recoveryPublicKey)\n ) revert AccountRecoveryFacet__InvalidRecoveryPublicKey();\n }\n\n /**\n * @notice Checks if recovery is currently pending\n * @return isPending Boolean indicating if recovery is pending\n */\n function _isRecoveryPending() internal view returns (bool isPending) {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n isPending = (rs.recoveryConfigs[INNER_STRUCT].executeAfter > 0);\n }\n\n /**\n * @notice Calculate the recovery hash dependent on chain, wallet address, nonce with EIP-191 prefix for safety\n * @dev Returns the keccak256 hash of EIP-191 msg hash packed with public key, salt, nonce, wallet address, etc\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _saltString Salt string to uniquely identify each recovery hash and for security\n * @return recoveryKeyHash Bytes32 string of the recovery hash\n */\n function getApprovalRecoveryKeyHash(\n bytes memory _recoveryPublicKey,\n string memory _saltString\n ) public view override returns (bytes32 recoveryKeyHash) {\n recoveryKeyHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n _recoveryPublicKey,\n _saltString,\n address(this),\n block.chainid,\n LibFacetStorage.recoveryStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Check the onchain approval of guardians and returns the number of guardians that approved\n * @dev Loop through the guardian addresses and returns the number of guardians that approved this recovery hash\n * @param _recoveryPublicKeyHash Bytes hash of newly recovered public key and recovery value of the account\n * @return approvalCount Number of guardians that approved\n */\n function getRecoveryApprovalCountWithTimeValidity(\n bytes32 _recoveryPublicKeyHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n for (uint256 i; i < guardianLength; ) {\n if (isRecoveryApproved(_recoveryPublicKeyHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Checks if the recovery is approved by the given approver\n * @param _recoveryPublicKeyHash Hash of the public key and configuration for recovery\n * @param _approver Address of approver\n * @return isApproved Bool value if recovery hash is approved\n */\n function isRecoveryApproved(\n bytes32 _recoveryPublicKeyHash,\n address _approver\n ) public view override returns (bool isApproved) {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n if (\n rs\n .isNewOwnerApproved[_recoveryPublicKeyHash][_approver].isApproved &&\n block.timestamp <\n rs.isNewOwnerApproved[_recoveryPublicKeyHash][_approver].validUntil\n ) {\n isApproved = true;\n }\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _recoveryPublicKeyHash Hash of recovery information\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _recoveryPublicKeyHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isRecoveryApproved(_recoveryPublicKeyHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert AccountRecoveryFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the lock period of this wallet address from security manager\n * @return lockPeriod value of lock period\n */\n function _getLockPeriod() internal view returns (uint256 lockPeriod) {\n lockPeriod = securityManager.lockPeriodOf(address(this));\n if (lockPeriod == 0) revert AccountRecoveryFacet__InvalidLockPeriod();\n }\n\n /**\n * @notice Returns the lock period of this wallet address from security manager\n * @return recoveryPeriod value of recovery period\n */\n function _getRecoveryPeriod()\n internal\n view\n returns (uint256 recoveryPeriod)\n {\n recoveryPeriod = securityManager.recoveryPeriodOf(address(this));\n if (recoveryPeriod == 0)\n revert AccountRecoveryFacet__InvalidRecoveryPeriod();\n }\n\n /**\n * @notice Returns the approval validation period of this wallet address from security manager\n * @return approvalValidationPeriod value of approval validation period\n */\n function _getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod == 0)\n revert AccountRecoveryFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the recovery nonce of this wallet address from security manager\n * @return nonce value of recovery nonce\n */\n function getRecoveryNonce() public view override returns (uint128 nonce) {\n nonce = LibFacetStorage.recoveryStorage().nonce;\n }\n\n /**\n * @notice Returns the recovery information of the pending recovery\n * @return recoveryConfig value struct of pending recovery\n */\n function getPendingRecovery()\n public\n view\n override\n returns (RecoveryConfig memory recoveryConfig)\n {\n recoveryConfig = LibFacetStorage.recoveryStorage().recoveryConfigs[\n INNER_STRUCT\n ];\n }\n}\n" + }, + "contracts/facets/base/DiamondCutFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibGuardian} from \"../../libraries/LibGuardian.sol\";\nimport {ISecurityManager} from \"../../infrastructure/interfaces/ISecurityManager.sol\";\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibFacetStorage, DiamondCutApprovalConfig, ApprovalConfig} from \"../../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"../Modifiers.sol\";\nimport {IDiamondCut} from \"./interfaces/IDiamondCut.sol\";\n\n/**\n * @title DiamondCut Facet\n * @dev Responsible for adding/removing/replace facets in Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DiamondCutFacet is Modifiers, IDiamondCut {\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Updates the flag for the interfaceId\n * @param _interfaceId InterfaceID to update the mapping\n * @param _flag Bool value to update the mapping of the given interface ID\n */\n function updateSupportsInterface(\n bytes4 _interfaceId,\n bool _flag\n ) external override onlyWhenUnlocked {\n LibDiamond.enforceIsSelf();\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId] = _flag;\n emit SupportsInterfaceUpdated(_interfaceId, _flag);\n }\n\n /**\n * @notice Add/replace/remove any number of functions and optionally execute\n * a function with delegatecall when guardians don't exist\n * @param _diamondCut Contains the facet addresses and function selectors\n * @param _init The address of the contract or facet to execute _calldata. It's prohibited in Barz\n */\n function diamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata\n ) external override onlyWhenUnlocked {\n LibDiamond.enforceIsSelf();\n\n _checkFacetCutValidity(_diamondCut);\n // require approval from guardian if guardian exists\n if (0 != LibGuardian.guardianCount())\n revert DiamondCutFacet__InvalidRouteWithGuardian();\n if (address(0) != _init) revert DiamondCutFacet__InvalidInitAddress();\n\n unchecked {\n ++LibFacetStorage.diamondCutStorage().nonce;\n }\n LibDiamond.diamondCut(_diamondCut, address(0), \"\");\n }\n\n /**\n * @notice Add/replace/remove any number of functions and optionally execute\n * a function with delegatecall when guardians exist\n * @param _diamondCut Contains the facet addresses and function selectors\n * @param _approvers Guardian or owner address that approves the diamond cut\n * @param _signatures Signature of Guardians or owner that approves the diamond cut\n */\n function diamondCutWithGuardian(\n FacetCut[] calldata _diamondCut,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n ) external override onlyWhenUnlocked {\n if (_approvers.length != _signatures.length)\n revert DiamondCutFacet__InvalidArrayLength();\n _checkFacetCutValidity(_diamondCut);\n if (0 == LibGuardian.guardianCount())\n revert DiamondCutFacet__InvalidRouteWithGuardian();\n\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(cutHash, _approvers);\n\n bool onChainOwnerApproval = getOwnerCutApprovalWithTimeValidity(\n cutHash\n );\n\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n if (\n _approvers.length +\n getDiamondCutApprovalCountWithTimeValidity(cutHash) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert DiamondCutFacet__InsufficientApprovers();\n\n bool ownerApproved;\n for (uint256 i; i < _approvers.length; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n _approvers[i] != address(this)\n ) revert DiamondCutFacet__InvalidApprover();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert DiamondCutFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n cutHash,\n _signatures[i]\n )\n ) revert DiamondCutFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n if (!ownerApproved && !onChainOwnerApproval)\n revert DiamondCutFacet__LackOfOwnerApproval();\n\n unchecked {\n ++LibFacetStorage.diamondCutStorage().nonce;\n }\n LibDiamond.diamondCut(_diamondCut, address(0), \"\");\n }\n\n /**\n * @notice Approves diamond cut. This can only be called directly from guardian or owner\n * @param _diamondCut Contains the facet addresses and function selectors\n */\n function approveDiamondCut(\n FacetCut[] calldata _diamondCut\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\n if (LibGuardian.guardianCount() == 0)\n revert DiamondCutFacet__InvalidRouteWithoutGuardian();\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n _checkFacetCutValidity(_diamondCut);\n\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(\n true,\n approvalValidUntil\n );\n emit DiamondCutApproved(_diamondCut);\n if (\n (getDiamondCutApprovalCountWithTimeValidity(cutHash) >=\n LibGuardian.majorityOfGuardians()) &&\n getOwnerCutApprovalWithTimeValidity(cutHash)\n ) {\n unchecked {\n ++LibFacetStorage.diamondCutStorage().nonce;\n }\n LibDiamond.diamondCut(_diamondCut, address(0), \"\");\n }\n }\n\n /**\n * @notice Revokes the approval of diamond cut. This can only be called directly from guardian or owner\n * @param _diamondCut Contains the facet addresses and function selectors\n */\n function revokeDiamondCutApproval(\n FacetCut[] calldata _diamondCut\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\n if (!ds.isDiamondCutApproved[cutHash][msg.sender].isApproved)\n revert DiamondCutFacet__CannotRevokeUnapproved();\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(false, 0);\n emit DiamondCutApprovalRevoked(_diamondCut);\n }\n\n /**\n * @notice Gets the number of approvals of diamond cut from guardians\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n */\n function getDiamondCutApprovalCountWithTimeValidity(\n bytes32 _diamondCutHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardiansLength = guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n if (isCutApproved(_diamondCutHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n return approvalCount;\n }\n\n /**\n * @notice Returns if the owner has approved the diamond cut\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @return isApprovedByOwner Bool value showing if the owner approved the cut\n */\n function getOwnerCutApprovalWithTimeValidity(\n bytes32 _diamondCutHash\n ) public view override returns (bool isApprovedByOwner) {\n isApprovedByOwner = isCutApproved(_diamondCutHash, address(this));\n }\n\n /**\n * @notice Returns if the given approver has approved the diamond cut\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @param _approver Address of approver\n * @return isApproved Bool value showing if the approver approved the cut\n */\n function isCutApproved(\n bytes32 _diamondCutHash,\n address _approver\n ) public view override returns (bool isApproved) {\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n isApproved = (ds\n .isDiamondCutApproved[_diamondCutHash][_approver].isApproved &&\n block.timestamp <\n ds.isDiamondCutApproved[_diamondCutHash][_approver].validUntil);\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _diamondCutHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isCutApproved(_diamondCutHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert DiamondCutFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the diamond cut hash. This function ensures that this hash is safe from replay attack by including\n * salt, address, chainId, and nonce, etc.\n * @param _diamondCut Contains the facet addresses and function selectors\n * @return cutHash Diamond Cut Hash\n */\n function getDiamondCutHash(\n FacetCut[] calldata _diamondCut\n ) public view override returns (bytes32 cutHash) {\n cutHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n keccak256(abi.encode(_diamondCut)),\n address(this),\n block.chainid,\n LibFacetStorage.diamondCutStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Returns the approval validation Period\n * @dev This method fetches the validation period from the security manager\n * @return approvalValidationPeriod Approval validation period of Barz contract fetched from security manager\n */\n function getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod <= 0)\n revert DiamondCutFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the diamond cut nonce of this wallet\n * @dev This method fetches the nonce from diamond cut storage\n * @return cutNonce Nonce of diamond cut to protect from reply attacks\n */\n function getDiamondCutNonce()\n public\n view\n override\n returns (uint128 cutNonce)\n {\n cutNonce = LibFacetStorage.diamondCutStorage().nonce;\n }\n}\n" + }, + "contracts/facets/base/DiamondLoupeFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {IERC165} from \"../../interfaces/ERC/IERC165.sol\";\nimport {IERC1271} from \"../../interfaces/ERC/IERC1271.sol\";\nimport {IERC677Receiver} from \"../../interfaces/ERC/IERC677Receiver.sol\";\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC1155Receiver} from \"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\";\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../../libraries/LibLoupe.sol\";\nimport {LibUtils} from \"../../libraries/LibUtils.sol\";\nimport {IDiamondCut} from \"../../facets/base/interfaces/IDiamondCut.sol\";\nimport {IStorageLoupe} from \"./interfaces/IStorageLoupe.sol\";\nimport {IDiamondLoupe} from \"./interfaces/IDiamondLoupe.sol\";\n\n/**\n * @title DiamondLoupe Facet\n * @dev DiamondLoupe contract compatible with EIP-2535\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DiamondLoupeFacet is IDiamondLoupe, IStorageLoupe, IERC165 {\n // Diamond Loupe Functions\n ////////////////////////////////////////////////////////////////////\n /// These functions are expected to be called frequently by tools off-chain.\n\n /**\n * @notice Gets all facets and their selectors.\n * @dev Barz uses a special architecture called default fallback handler. Default Fallback handler is used as a middleware\n * that holds the mapping of facet function selector and facet address that Barz uses. This helps Barz to reduce\n * significant amount of gas during the initialization process.\n * Hence, this method aggregates both the facet information from DefaulFallbackHandler and in diamond storage and shows the data to users.\n * @return facets_ Facet\n */\n function facets() public view override returns (Facet[] memory facets_) {\n Facet[] memory defaultFacet = LibDiamond\n .diamondStorage()\n .defaultFallbackHandler\n .facets();\n Facet[] memory _facets = LibLoupe.facets();\n uint256 numFacets = _facets.length;\n bytes4[] memory keys;\n address[] memory values;\n for (uint256 i; i < numFacets; ) {\n uint256 selectorsLength = _facets[i].functionSelectors.length;\n for (uint256 j; j < selectorsLength; ) {\n (keys, values) = LibUtils.setValue(\n keys,\n values,\n _facets[i].functionSelectors[j],\n _facets[i].facetAddress\n );\n unchecked {\n ++j;\n }\n }\n unchecked {\n ++i;\n }\n }\n {\n bool iIncrement;\n for (uint256 i; i < defaultFacet.length; ) {\n bool jIncrement;\n for (\n uint256 j;\n j < defaultFacet[i].functionSelectors.length;\n\n ) {\n if (\n LibUtils.getValue(\n keys,\n values,\n defaultFacet[i].functionSelectors[j]\n ) != address(0)\n ) {\n if (defaultFacet[i].functionSelectors.length == 1) {\n defaultFacet = LibUtils.removeFacetElement(\n defaultFacet,\n i\n );\n iIncrement = true;\n break;\n }\n defaultFacet[i].functionSelectors = LibUtils\n .removeElement(\n defaultFacet[i].functionSelectors,\n j\n );\n jIncrement = true;\n }\n if (!jIncrement) {\n unchecked {\n ++j;\n }\n } else {\n jIncrement = false;\n }\n }\n if (!iIncrement) {\n unchecked {\n ++i;\n }\n } else {\n iIncrement = false;\n }\n }\n }\n {\n uint256 facetLength = numFacets + defaultFacet.length;\n facets_ = new Facet[](facetLength);\n uint256 defaultFacetIndex;\n for (uint256 i; i < facetLength; ) {\n if (i < numFacets) {\n facets_[i] = _facets[i];\n bool jIncrementor;\n for (uint256 j; j < defaultFacet.length; ) {\n if (\n facets_[i].facetAddress ==\n defaultFacet[j].facetAddress\n ) {\n facets_[i].functionSelectors = LibUtils.mergeArrays(\n _facets[i].functionSelectors,\n defaultFacet[j].functionSelectors\n );\n defaultFacet = LibUtils.removeFacetElement(\n defaultFacet,\n j\n );\n jIncrementor = true;\n {\n facets_ = LibUtils.removeFacetElement(\n facets_,\n facets_.length - 1\n );\n }\n --facetLength;\n }\n if (!jIncrementor) {\n unchecked {\n ++j;\n }\n } else {\n jIncrementor = false;\n }\n }\n } else {\n facets_[i] = defaultFacet[defaultFacetIndex];\n ++defaultFacetIndex;\n }\n unchecked {\n ++i;\n }\n }\n }\n }\n\n /**\n * @notice Gets all the function selectors provided by a facet.\n * @param _facet The facet address.\n * @return facetFunctionSelectors_\n */\n function facetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n Facet[] memory facet = facets();\n uint256 facetLength = facet.length;\n for (uint256 i; i < facetLength; ) {\n if (facet[i].facetAddress == _facet)\n return facet[i].functionSelectors;\n unchecked {\n ++i;\n }\n }\n return facetFunctionSelectors_;\n }\n\n /**\n * @notice Get all the facet addresses used by Barz.\n * @return facetAddresses_\n */\n function facetAddresses()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n Facet[] memory facet = facets();\n uint256 facetLength = facet.length;\n facetAddresses_ = new address[](facetLength);\n for (uint256 i; i < facetLength; ) {\n facetAddresses_[i] = facet[i].facetAddress;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Gets the facet that supports the given selector.\n * @dev If facet is not found return address(0).\n * @param _functionSelector The function selector.\n * @return facetAddress_ The facet address.\n */\n function facetAddress(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n\n facetAddress_ = address(bytes20(ds.facets[_functionSelector]));\n if (facetAddress_ == address(0)) {\n facetAddress_ = IDiamondLoupe(ds.defaultFallbackHandler)\n .facetAddress(_functionSelector);\n }\n }\n\n /**\n * @notice SupportInterface to be compatible with EIP 165\n * @param _interfaceId Interface ID for detecting the interface\n * @return isSupported Bool value showing if the standard is supported in the contract\n */\n function supportsInterface(\n bytes4 _interfaceId\n ) external view override returns (bool isSupported) {\n isSupported =\n _interfaceId == type(IERC165).interfaceId ||\n _interfaceId == IDiamondCut.diamondCut.selector ||\n _interfaceId == type(IDiamondLoupe).interfaceId ||\n _interfaceId == type(IERC1155Receiver).interfaceId ||\n _interfaceId == type(IERC721Receiver).interfaceId ||\n _interfaceId == type(IERC777Recipient).interfaceId ||\n _interfaceId == IERC1271.isValidSignature.selector ||\n _interfaceId == type(IERC677Receiver).interfaceId ||\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId];\n }\n\n /**\n * @notice Returns the facet from the diamond storage. This excludes the facets from the default fallback handler\n * @return facets_ Facet information attached directly to diamond storage\n */\n function facetsFromStorage()\n external\n view\n override\n returns (Facet[] memory facets_)\n {\n facets_ = LibLoupe.facets();\n }\n\n /**\n * @notice Returns the facet address attached to the given function selector. This excludes the facets from the default fallback handler\n * @param _functionSelector Function selector to fetch the facet address from diamond storage\n * @return facetAddress_ Facet address mapped with the function selector\n */\n function facetAddressFromStorage(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n facetAddress_ = LibLoupe.facetAddress(_functionSelector);\n }\n\n /**\n * @notice Returns all facet addresses attached directly to diamond storage. This excludes the facets from the default fallback handler\n * @return facetAddresses_ All facet addresses attached directly to diamond storage\n */\n function facetAddressesFromStorage()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n facetAddresses_ = LibLoupe.facetAddresses();\n }\n\n /**\n * @notice Returns function selectors of given facet address attached directly to diamond storage. This excludes the facets from the default fallback handler\n * @param _facet Facet address to fetch the facet function selectors from diamond storage\n * @return facetFunctionSelectors_ Facet function selectors of the given facet address\n */\n function facetFunctionSelectorsFromStorage(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n facetFunctionSelectors_ = LibLoupe.facetFunctionSelectors(_facet);\n }\n}\n" + }, + "contracts/facets/base/interfaces/IDiamondCut.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title DiamondCut Facet Interface\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IDiamondCut {\n error DiamondCutFacet__InvalidRouteWithGuardian();\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\n error DiamondCutFacet__InvalidArrayLength();\n error DiamondCutFacet__InsufficientApprovers();\n error DiamondCutFacet__InvalidApprover();\n error DiamondCutFacet__InvalidApproverSignature();\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\n error DiamondCutFacet__CannotRevokeUnapproved();\n error DiamondCutFacet__LackOfOwnerApproval();\n error DiamondCutFacet__OwnerAlreadyApproved();\n error DiamondCutFacet__DuplicateApproval();\n error DiamondCutFacet__InvalidInitAddress();\n\n event DiamondCutApproved(FacetCut[] diamondCut);\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\n\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\n\n enum FacetCutAction {\n Add,\n Replace,\n Remove\n }\n // Add=0, Replace=1, Remove=2\n\n struct FacetCut {\n address facetAddress;\n FacetCutAction action;\n bytes4[] functionSelectors;\n }\n\n /// @notice Add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param diamondCut Contains the facet addresses and function selectors\n /// @param init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function diamondCut(\n FacetCut[] calldata diamondCut,\n address init,\n bytes calldata _calldata\n ) external;\n\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\n\n function diamondCutWithGuardian(\n FacetCut[] calldata diamondCut,\n address[] calldata approvers,\n bytes[] calldata signatures\n ) external;\n\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\n\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\n\n function getDiamondCutApprovalCountWithTimeValidity(\n bytes32 diamondCutHash\n ) external view returns (uint256);\n\n function getOwnerCutApprovalWithTimeValidity(\n bytes32 diamondCutHash\n ) external view returns (bool);\n\n function isCutApproved(\n bytes32 diamondCutHash,\n address approver\n ) external view returns (bool);\n\n function getDiamondCutHash(\n FacetCut[] calldata diamondCut\n ) external view returns (bytes32);\n\n function getDiamondCutNonce() external view returns (uint128);\n}\n" + }, + "contracts/facets/base/interfaces/IDiamondLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n// A loupe is a small magnifying glass used to look at diamonds.\n// These functions look at diamonds\ninterface IDiamondLoupe {\n /// These functions are expected to be called frequently\n /// by tools.\n\n struct Facet {\n address facetAddress;\n bytes4[] functionSelectors;\n }\n\n /// @notice Gets all facet addresses and their four byte function selectors.\n /// @return facets_ Facet\n function facets() external view returns (Facet[] memory facets_);\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n /// @return facetFunctionSelectors_\n function facetFunctionSelectors(\n address _facet\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses()\n external\n view\n returns (address[] memory facetAddresses_);\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(\n bytes4 _functionSelector\n ) external view returns (address facetAddress_);\n}\n" + }, + "contracts/facets/base/interfaces/IStorageLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"./IDiamondLoupe.sol\";\n\n/**\n * @title LoupeFromStorage Interface\n * @dev Interface contract to function as a loupe facet directly attached to diamond storage of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IStorageLoupe {\n /// These functions are expected to be called frequently\n /// by tools.\n\n /// @notice Gets all facet addresses and their four byte function selectors.\n /// @return facets_ Facet\n function facetsFromStorage()\n external\n view\n returns (IDiamondLoupe.Facet[] memory);\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n function facetFunctionSelectorsFromStorage(\n address _facet\n ) external view returns (bytes4[] memory);\n\n /// @notice Get all the facet addresses used by a diamond.\n function facetAddressesFromStorage()\n external\n view\n returns (address[] memory);\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n function facetAddressFromStorage(\n bytes4 _functionSelector\n ) external view returns (address);\n}\n" + }, + "contracts/facets/GuardianFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibFacetStorage, GuardianStorage, StorageConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IGuardianFacet} from \"./interfaces/IGuardianFacet.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Guardian Facet\n * @dev Contract that enables addition/removal of guardians from Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract GuardianFacet is IGuardianFacet {\n ISecurityManager public immutable securityManager;\n uint8 public constant INNER_STRUCT = 0;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Add guardians to Barz.\n * @dev This method internally calls addGuardian which checks the validity of guardian address and adds\n * as guardian if valid\n * @param _guardians Array of addresses to add as guardian\n */\n function addGuardians(address[] calldata _guardians) external override {\n LibDiamond.enforceIsSelf();\n for (uint256 i; i < _guardians.length; ) {\n addGuardian(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Add a guardian to Barz.\n * @dev This method checks if the function is called by the owner and validates the address of guardian\n * When the validation passes, guardian address is added to the pending state waiting for confirmation\n * @param _guardian Address to add as guardian\n */\n function addGuardian(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (_guardian == address(this))\n revert GuardianFacet__GuardianCannotBeSelf();\n if (isGuardian(_guardian)) revert GuardianFacet__DuplicateGuardian();\n if (_guardian == address(0))\n revert GuardianFacet__ZeroAddressGuardian();\n if (\n keccak256(abi.encodePacked(_guardian)) ==\n keccak256(IVerificationFacet(address(this)).owner())\n ) revert GuardianFacet__OwnerCannotBeGuardian();\n\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n if (\n gs.pending[id] != 0 ||\n block.timestamp <= gs.pending[id] + getSecurityWindow()\n ) revert GuardianFacet__DuplicateGuardianAddition();\n\n uint256 securityPeriod = getAdditionSecurityPeriod();\n gs.pending[id] = block.timestamp + securityPeriod;\n emit GuardianAdditionRequested(\n _guardian,\n block.timestamp + securityPeriod\n );\n }\n\n /**\n * @notice Remove guardians from Barz.\n * @dev This method internally calls removeGuardian which checks the validity of guardian and removes\n * guardian when the request is valid\n * @param _guardians Array of addresses to be removed\n */\n function removeGuardians(address[] calldata _guardians) external override {\n LibDiamond.enforceIsSelf();\n for (uint256 i; i < _guardians.length; ) {\n removeGuardian(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Remove a guardian from Barz.\n * @dev This method validates if the guardian to be removed is a guardian and puts the guardian removal\n * to a pending state waiting to be confirmed.\n * @param _guardian Address of guardian to be removed\n */\n function removeGuardian(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n if (!isGuardian(_guardian)) revert GuardianFacet__NonExistentGuardian();\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n if (\n gs.pending[id] != 0 ||\n block.timestamp <= gs.pending[id] + getSecurityWindow()\n ) revert GuardianFacet__DuplicateGuardianRemoval();\n\n uint256 securityPeriod = getRemovalSecurityPeriod();\n gs.pending[id] = block.timestamp + securityPeriod;\n emit GuardianRemovalRequested(\n _guardian,\n block.timestamp + securityPeriod\n );\n }\n\n /**\n * @notice Confirm addition of guardians\n * @dev This method internally calls confirmGuardianAddition which checks the validity of pending request.\n * Guardians are fully added when they pass the validation. Anyone can call this function.\n * @param _guardians Array of guardian addresses to be added\n */\n function confirmGuardianAdditions(\n address[] calldata _guardians\n ) external override {\n for (uint256 i; i < _guardians.length; ) {\n confirmGuardianAddition(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Confirm addition of a guardian\n * @dev This method checks the validity of pending request.\n * Guardians are fully added when they pass the validation. Anyone can call this function.\n * @param _guardian Guardian address to be added\n */\n function confirmGuardianAddition(address _guardian) public override {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingAddition();\n if (gs.pending[id] >= block.timestamp)\n revert GuardianFacet__PendingAdditionNotOver();\n if (block.timestamp >= gs.pending[id] + getSecurityWindow())\n revert GuardianFacet__PendingAdditionExpired();\n\n _addGuardian(_guardian);\n\n delete gs.pending[id];\n emit GuardianAdded(_guardian);\n }\n\n /**\n * @notice Confirm removal of guardians\n * @dev This method internally calls confirmGuardianRemoval to check the validity guardian removal confirmation.\n * Guardians are fully removed when they pass the validation. Anyone can call this function.\n * @param _guardians Array of guardian addresses to be removed\n */\n function confirmGuardianRemovals(\n address[] calldata _guardians\n ) external override {\n for (uint256 i; i < _guardians.length; ) {\n confirmGuardianRemoval(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Confirm removal of a guardian\n * @dev This method checks the validity guardian removal confirmation.\n * Guardian is fully removed when they pass the validation. Anyone can call this function.\n * @param _guardian Guardian address to be removed\n */\n function confirmGuardianRemoval(address _guardian) public override {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingRemoval();\n if (gs.pending[id] >= block.timestamp)\n revert GuardianFacet__PendingRemovalNotOver();\n if (block.timestamp >= gs.pending[id] + getSecurityWindow())\n revert GuardianFacet__PendingAdditionExpired();\n\n _removeGuardian(_guardian);\n delete gs.pending[id];\n emit GuardianRemoved(_guardian);\n }\n\n /**\n * @notice Cancel pending guardian addition\n * @dev This method checks if the previous request for guardian request exists.\n * It reverts if previous request is not pending and cancels the addition otherwise.\n * @param _guardian Guardian address to be canceled from addition\n */\n function cancelGuardianAddition(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingAddition();\n delete gs.pending[id];\n emit GuardianAdditionCancelled(_guardian);\n }\n\n /**\n * @notice Cancel pending guardian removal\n * @dev This method checks if the previous request for guardian request exists.\n * It reverts if previous request is not pending and cancels the removal otherwise.\n * @param _guardian Guardian address to be canceled from removal\n */\n function cancelGuardianRemoval(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingRemoval();\n delete gs.pending[id];\n emit GuardianRemovalCancelled(_guardian);\n }\n\n /**\n * @notice Get the addition security period of current account from security manager\n * @dev This method returns the uint value if addition security period\n * @return additionSecurityPeriod Uint256 value of addition security period\n */\n function getAdditionSecurityPeriod()\n public\n view\n override\n returns (uint256 additionSecurityPeriod)\n {\n additionSecurityPeriod = securityManager.additionSecurityPeriodOf(\n address(this)\n );\n if (additionSecurityPeriod == 0)\n revert GuardianFacet__InvalidAdditionSecurityPeriod();\n }\n\n /**\n * @notice Get the removal security period of current account from security manager\n * @dev This method returns the uint value if removal security period\n * @return removalSecurityPeriod Uint256 value of removal security period\n */\n function getRemovalSecurityPeriod()\n public\n view\n override\n returns (uint256 removalSecurityPeriod)\n {\n removalSecurityPeriod = securityManager.removalSecurityPeriodOf(\n address(this)\n );\n if (removalSecurityPeriod == 0)\n revert GuardianFacet__InvalidRemovalSecurityPeriod();\n }\n\n /**\n * @notice Get the security window of current account from security manager\n * @dev This method returns the uint value if security window\n * @return securityWindow Uint256 value of removal security period\n */\n function getSecurityWindow()\n public\n view\n override\n returns (uint256 securityWindow)\n {\n securityWindow = securityManager.securityWindowOf(address(this));\n if (securityWindow == 0) revert GuardianFacet__InvalidSecurityWindow();\n }\n\n /**\n * @notice Checks if the addition of the given guardian address is pending\n * @dev This method returns the bool value of whether the guardian address is pending addition\n * @return isPending Bool value of representing the pending of guardian addition\n */\n function isAdditionPending(\n address _guardian\n ) public view override returns (bool isPending) {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n isPending = _isPending(id);\n }\n\n /**\n * @notice Checks if the removal of the given guardian address is pending\n * @dev This method returns the bool value of whether the guardian address is pending removal\n * @return isPending Bool value of representing the pending of guardian removal\n */\n function isRemovalPending(\n address _guardian\n ) public view override returns (bool isPending) {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n isPending = _isPending(id);\n }\n\n /**\n * @notice Checks if the given hash is pending\n * @dev This method returns the bool value whether the hash is pending\n * @return isPending Bool value of representing the pending of guardian operation\n */\n function _isPending(\n bytes32 _idHash\n ) internal view returns (bool isPending) {\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n isPending = ((gs.pending[_idHash] > 0 &&\n gs.pending[_idHash] < block.timestamp) &&\n block.timestamp < gs.pending[_idHash] + getSecurityWindow());\n }\n\n /**\n * @notice Adds guardian to storage config. This is called when guardian is fully added.\n * @dev This method add guardian address and config information to Facet Storage dedicated for guardian\n * When this function is called, guardian is fully added to this Barz Smart Account\n * @param _guardian Address of guardian to be added\n */\n function _addGuardian(address _guardian) internal {\n if (!isAdditionPending(_guardian))\n revert GuardianFacet__InvalidGuardianAddition();\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n if (config.info[_guardian].exists)\n revert GuardianFacet__AlreadyExists();\n\n config.info[_guardian].exists = true;\n config.info[_guardian].index = uint128(config.addresses.length);\n config.addresses.push(_guardian);\n }\n\n /**\n * @notice Removes guardian to storage config. This is called when guardian is fully removed.\n * @dev This method remove guardian address and config information to Facet Storage dedicated for guardian\n * When this function is called, guardian is fully removed from this Barz Smart Account\n * @param _guardian Address of guardian to be removed\n */\n function _removeGuardian(address _guardian) internal {\n if (!isRemovalPending(_guardian))\n revert GuardianFacet__InvalidGuardianRemoval();\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n if (!config.info[_guardian].exists)\n revert GuardianFacet__NonExistentGuardian();\n\n address lastAddress = config.addresses[config.addresses.length - 1];\n if (_guardian != lastAddress) {\n uint128 targetIndex = config.info[_guardian].index;\n config.addresses[targetIndex] = lastAddress;\n config.info[lastAddress].index = targetIndex;\n }\n config.addresses.pop();\n delete config.info[_guardian];\n\n emit GuardianRemoved(_guardian);\n }\n\n /**\n * @notice Reads guardian storage and fetches the addresses into an array from the storage\n * @dev This method fetches the guardian storage and returns the list of guardian addresses\n * @return addresses Array of addresses comprised of guardian\n */\n function getGuardians()\n public\n view\n override\n returns (address[] memory addresses)\n {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n uint256 addressesLen = config.addresses.length;\n addresses = new address[](addressesLen);\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the number of majority of guardians\n * @return majorityOfGuardians_ Number of majority of guardians e.g., 2 if 3 guardians / 3 if 5 guardians\n */\n function majorityOfGuardians()\n public\n view\n override\n returns (uint256 majorityOfGuardians_)\n {\n majorityOfGuardians_ = LibGuardian.majorityOfGuardians();\n }\n\n /**\n * @notice Reads guardian storage and fetches the addresses into an array from the storage\n * @dev This method fetches the guardian storage and returns the list of guardian addresses\n * @return guardianNumber Array of guardians in the account\n */\n function guardianCount()\n public\n view\n override\n returns (uint256 guardianNumber)\n {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n guardianNumber = config.addresses.length;\n }\n\n /**\n * @notice Reads guardian storage and checks if the given address is a guardian\n * @return isGuardian_ Bool value representing if the given address is guardian\n */\n function isGuardian(\n address _guardian\n ) public view override returns (bool isGuardian_) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n isGuardian_ = config.info[_guardian].exists;\n }\n\n /**\n * @notice Checks if the guardian number is zero and returns of guardian facet is okay to be removed\n * @return isRemovable Bool value representing if guardian facet is removable\n */\n function isGuardianFacetRemovable()\n external\n view\n override\n returns (bool isRemovable)\n {\n isRemovable = (0 == guardianCount());\n }\n}\n" + }, + "contracts/facets/interfaces/IAccountFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IEntryPoint} from \"../../aa-4337/interfaces/IEntryPoint.sol\";\n\n/**\n * @title Account Facet Interface\n * @dev Interface of module contract that provides the account features and init/unitialization of signer\n * compatible with EIP-1271 & EIP-4337\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IAccountFacet {\n event AccountInitialized(\n IEntryPoint indexed entryPoint,\n bytes indexed ownerPublicKey\n );\n // NOTE: Added Below Event\n event VerificationSuccess(bytes32);\n event VerificationFailure(bytes32);\n\n error AccountFacet__InitializationFailure();\n error AccountFacet__RestrictionsFailure();\n error AccountFacet__NonExistentVerificationFacet();\n error AccountFacet__CallNotSuccessful();\n error AccountFacet__InvalidArrayLength();\n\n function initialize(\n address verificationFacet,\n address anEntryPoint,\n address facetRegistry,\n address _defaultFallBack,\n bytes calldata _ownerPublicKey\n ) external returns (uint256);\n\n function execute(address dest, uint256 value, bytes calldata func) external;\n\n function executeBatch(\n address[] calldata dest,\n uint256[] calldata value,\n bytes[] calldata func\n ) external;\n}\n" + }, + "contracts/facets/interfaces/IAccountRecoveryFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {RecoveryConfig} from \"../../libraries/LibFacetStorage.sol\";\n\n/**\n * @title Account Recovery Facet Interface\n * @dev Interface of contract that enables recovery of accounts when owner key is unavailable\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IAccountRecoveryFacet {\n event RecoveryExecuted(\n bytes indexed recoveryPublicKey,\n uint64 executeAfter\n );\n event RecoveryFinalized(bytes indexed recoveryPublicKey);\n event RecoveryCanceled(bytes indexed recoveryPublicKey);\n event RecoveryApproved(\n bytes indexed recoveryPublicKey,\n address indexed guardian,\n uint64 validUntil\n );\n event RecoveryApprovalRevoked(\n bytes indexed recoveryPublicKey,\n address indexed guardian\n );\n event RecoveryCancellationApproved(\n bytes indexed recoveryPublicKey,\n address indexed guardian\n );\n event RecoveryHardstopped();\n\n error AccountRecoveryFacet__CallerNotGuardian();\n error AccountRecoveryFacet__InvalidRecoveryPublicKey();\n error AccountRecoveryFacet__SignerInitializationFailure();\n error AccountRecoveryFacet__SignerUninitializationFailure();\n error AccountRecoveryFacet__InvalidArrayLength();\n error AccountRecoveryFacet__InsufficientGuardians();\n error AccountRecoveryFacet__RecoveryAlreadyOngoing();\n error AccountRecoveryFacet__NonexistentRecovery();\n error AccountRecoveryFacet__NonExistentApproval();\n error AccountRecoveryFacet__RecoveryPeriodNotOver();\n error AccountRecoveryFacet__InvalidLockPeriod();\n error AccountRecoveryFacet__InvalidRecoveryPeriod();\n error AccountRecoveryFacet__InvalidApprovalValidationPeriod();\n error AccountRecoveryFacet__InvalidGuardian();\n error AccountRecoveryFacet__InvalidGuardianSignature();\n error AccountRecoveryFacet__InvalidOwnerSignature();\n error AccountRecoveryFacet__CallNotSuccesful();\n error AccountRecoveryFacet__DuplicateApproval();\n\n function approveAccountRecovery(bytes calldata recoveryPublicKey) external;\n\n function revokeAccountRecoveryApproval(\n bytes calldata recoveryPublicKey\n ) external;\n\n function executeRecovery(\n bytes calldata recoveryPublicKey,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function finalizeRecovery() external;\n\n function approveCancelRecovery(bytes calldata recoveryPublicKey) external;\n\n function cancelRecovery(\n bytes calldata recoveryPublicKey,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function hardstopRecovery(bytes calldata signature) external;\n\n function getApprovalRecoveryKeyHash(\n bytes memory recoveryPublicKey,\n string memory saltString\n ) external view returns (bytes32);\n\n function getRecoveryApprovalCountWithTimeValidity(\n bytes32 recoveryPublicKeyHash\n ) external view returns (uint256);\n\n function isRecoveryApproved(\n bytes32 recoveryPublicKeyHash,\n address approver\n ) external view returns (bool);\n\n function getRecoveryNonce() external view returns (uint128);\n\n function getPendingRecovery() external view returns (RecoveryConfig memory);\n}\n" + }, + "contracts/facets/interfaces/IGuardianFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Guardian Facet Interface\n * @dev Interface of guaridna contract that enables addition/removal of guardians from Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IGuardianFacet {\n event GuardianAdditionRequested(\n address indexed guardian,\n uint256 executeAfter\n );\n event GuardianRemovalRequested(\n address indexed guardian,\n uint256 executeAfter\n );\n event GuardianAdditionCancelled(address indexed guardian);\n event GuardianRemovalCancelled(address indexed guardian);\n event GuardianAdded(address indexed guardian);\n event GuardianRemoved(address indexed guardian);\n\n error GuardianFacet__GuardianCannotBeSelf();\n error GuardianFacet__DuplicateGuardian();\n error GuardianFacet__OwnerCannotBeGuardian();\n error GuardianFacet__DuplicateGuardianAddition();\n error GuardianFacet__DuplicateGuardianRemoval();\n error GuardianFacet__UnknownPendingAddition();\n error GuardianFacet__PendingAdditionNotOver();\n error GuardianFacet__UnknownPendingRemoval();\n error GuardianFacet__PendingRemovalNotOver();\n error GuardianFacet__PendingAdditionExpired();\n error GuardianFacet__InvalidAdditionSecurityPeriod();\n error GuardianFacet__InvalidRemovalSecurityPeriod();\n error GuardianFacet__InvalidSecurityWindow();\n error GuardianFacet__NonExistentGuardian();\n error GuardianFacet__AlreadyExists();\n error GuardianFacet__InvalidGuardianAddition();\n error GuardianFacet__InvalidGuardianRemoval();\n error GuardianFacet__ZeroAddressGuardian();\n\n function addGuardian(address guardian) external;\n\n function addGuardians(address[] calldata guardians) external;\n\n function removeGuardian(address guardian) external;\n\n function removeGuardians(address[] calldata guardians) external;\n\n function confirmGuardianAddition(address guardian) external;\n\n function confirmGuardianAdditions(address[] calldata guardian) external;\n\n function confirmGuardianRemoval(address guardian) external;\n\n function confirmGuardianRemovals(address[] calldata guardian) external;\n\n function cancelGuardianAddition(address guardian) external;\n\n function cancelGuardianRemoval(address guardian) external;\n\n function isGuardian(address guardian) external view returns (bool);\n\n function isAdditionPending(address guardian) external view returns (bool);\n\n function isRemovalPending(address guardian) external view returns (bool);\n\n function isGuardianFacetRemovable() external view returns (bool);\n\n function getAdditionSecurityPeriod() external view returns (uint256);\n\n function getRemovalSecurityPeriod() external view returns (uint256);\n\n function getSecurityWindow() external view returns (uint256);\n\n function getGuardians() external view returns (address[] memory);\n\n function majorityOfGuardians() external view returns (uint256);\n\n function guardianCount() external view returns (uint256);\n}\n" + }, + "contracts/facets/interfaces/ILockFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Lock} from \"../../libraries/LibAppStorage.sol\";\n\n/**\n * @title Lock Facet Interface\n * @dev Interface of Lock contract that enables full lock/unlock of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface ILockFacet {\n event Locked(uint64 releaseAfter);\n event Unlocked();\n\n error LockFacet__InvalidRecoveryPeriod();\n error LockFacet__CannotUnlock();\n error LockFacet__InvalidSignature();\n error LockFacet__InvalidApprover();\n\n function lock() external;\n\n function unlock(address approver, bytes calldata signature) external;\n\n function getLockPeriod() external view returns (uint256);\n\n function isLocked() external view returns (bool);\n\n function getUnlockHash() external view returns (bytes32);\n\n function lockNonce() external view returns (uint128);\n\n function getPendingLock() external view returns (Lock memory);\n}\n" + }, + "contracts/facets/interfaces/IMultiSigFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Multi-sig facet Interface\n * @dev Interface of Multi-signature Facet with custom threshold.\n Wallet that adds this facet becomes a multi-sig wallet\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IMultiSigFacet {\n event ThresholdChanged(uint256 threshold);\n event OwnerAdded(address indexed newOwner);\n event OwnerRemoved(address indexed prevOwner);\n event HashApproved(bytes32 hashToApprove, address indexed owner);\n\n error MultiSigFacet__InvalidThreshold();\n error MultisigFacet__InvalidOwnerCount();\n error MultiSigFacet__InvalidRoute();\n error MultiSigFacet__InsufficientSignerLength();\n error MultiSigFacet__InvalidInitData();\n error MultiSigFacet__InvalidOwnerAddress();\n error MultiSigFacet__InvalidOwnerPair();\n error MultiSigFacet__InvalidSignatureLength();\n error MultiSigFacet__InvalidSignatureType();\n error MultiSigFacet__DuplicateOwner();\n error MultiSigFacet__OnlyOwner();\n\n function checkSignatures(\n bytes32 _dataHash,\n bytes calldata _signatures,\n uint256 _threshold\n ) external view returns (uint256);\n\n function splitSignatures(\n bytes calldata _signatures,\n uint256 _nextOffset\n )\n external\n pure\n returns (\n address owner,\n bytes memory signature,\n uint256 signatureType,\n uint256 nextOffset\n );\n\n function approveHash(bytes32 hashToApprove) external;\n\n function addOwner(address newOwner, uint256 threshold) external;\n\n function removeOwner(\n address prevOwner,\n address removedOwner,\n uint256 threshold\n ) external;\n\n function swapOwner(\n address prevOwner,\n address oldOwner,\n address newOwner\n ) external;\n\n function changeThreshold(uint256 _threshold) external;\n\n function isOwner(address owner) external view returns (bool);\n\n function getThreshold() external view returns (uint256);\n\n function getOwners() external view returns (address[] memory);\n}\n" + }, + "contracts/facets/interfaces/IRestrictionsFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Restrictions Facet Interface\n * @dev Interface of Restrictions contract that enables modular restrictions in Barz\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IRestrictionsFacet {\n event RestrictionAdded(address indexed restriction);\n event RestrictionRemoved(address indexed restriction);\n\n error RestrictionsFacet__EmptyRestrictionsList();\n error RestrictionsFacet__RestrictionNotFound();\n error RestrictionsFacet__RestrictionAlreadyExists();\n error RestrictionsFacet__ZeroAddressRestrictions();\n error RestrictionsFacet__ZeroAddressRestrictionsFacet();\n error RestrictionsFacet__RemainingRestrictionsCantBeEmpty();\n\n function initializeRestrictions(\n address[] memory _restrictions\n ) external returns (uint256);\n\n function uninitializeRestrictions() external returns (uint256);\n\n function getRestrictions() external view returns (address[] memory);\n\n function addRestriction(address restriction) external;\n\n function removeRestriction(address restriction) external;\n\n function verifyRestrictions(\n address from,\n address to,\n uint256 value,\n bytes calldata _calldata\n ) external returns (uint256);\n}\n" + }, + "contracts/facets/interfaces/ISignatureMigrationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureMigrationConfig} from \"../../libraries/LibFacetStorage.sol\";\n\n/**\n * @title Signature Migration Facet Interface\n * @dev Interface of Signature Migration contract for migrating user signature scheme to a new scheme user sets\n * Which could include\n * - ECDSA on Secp256K1 Curve\n * - ECDSA on Secp256R1 Curve\n * - BLS, Schnorr, etc\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface ISignatureMigrationFacet {\n event SignatureSchemeMigration(\n address indexed prevVerificationFacet,\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n event SignatureMigrationApproved(\n bytes newPublicKey,\n address indexed newVerificationFacet,\n bytes4[] verificationFuncSelectors,\n address indexed guardian,\n uint128 approvalValidUntil\n );\n event SignatureMigrationApprovalRevoked(\n bytes newPublicKey,\n address indexed newVerificationFacet,\n bytes4[] verificationFuncSelectors,\n address indexed guardian\n );\n event SignatureMigrationExecuted(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors,\n uint128 migrateAfter\n );\n event SignatureMigrationCanceled(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n event SignatureMigrationCancellationApproved(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n\n error SignatureMigrationFacet__SignerUninitializationFailure();\n error SignatureMigrationFacet__SignerInitializationFailure();\n error SignatureMigrationFacet__InvalidRouteWithGuardian();\n error SignatureMigrationFacet__InvalidKeyType();\n error SignatureMigrationFacet__InsufficientApprovers();\n error SignatureMigrationFacet__InvalidApproverSignature();\n error SignatureMigrationFacet__InvalidGuardian();\n error SignatureMigrationFacet__NonExistentApprover();\n error SignatureMigrationFacet__InvalidMigrationPeriod();\n error SignatureMigrationFacet__NonexistentMigration();\n error SignatureMigrationFacet__MigrationPeriodNotOver();\n error SignatureMigrationFacet__InvalidArrayLength();\n error SignatureMigrationFacet__InvalidApprovalValidationPeriod();\n error SignatureMigrationFacet__CannotRevokeUnapproved();\n error SignatureMigrationFacet__LackOfOwnerApproval();\n error SignatureMigrationFacet__OwnerAlreadyApproved();\n error SignatureMigrationFacet__NonExistentVerificationFacet();\n error SignatureMigrationFacet__DuplicateApproval();\n\n function migrateSignatureScheme(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function migrateSignatureSchemeWithGuardian(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors,\n address[] calldata approvers,\n bytes[] calldata signatures\n ) external;\n\n function approveSignatureSchemeMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function revokeSignatureMigrationApproval(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function finalizeSignatureMigration() external;\n\n function approveCancelSignatureMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function cancelSignatureMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function getApprovalMigrationKeyHash(\n bytes memory recoveryPublicKey,\n address newVerificationFacet,\n bytes4[] memory newVerificationFuncSelectors,\n string memory saltString\n ) external view returns (bytes32);\n\n function getMigrationOwnerApprovalWithTimeValidity(\n bytes32 publicKeyHash\n ) external view returns (bool);\n\n function getMigrationApprovalCountWithTimeValidity(\n bytes32 publicKeyHash\n ) external view returns (uint256);\n\n function isMigrationApproved(\n bytes32 migrationPublicKeyHash,\n address approver\n ) external view returns (bool);\n\n function getMigrationNonce() external view returns (uint128);\n\n function isMigrationPending() external view returns (bool);\n\n function getPendingMigration()\n external\n view\n returns (SignatureMigrationConfig memory);\n}\n" + }, + "contracts/facets/interfaces/IVerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {UserOperation} from \"../../aa-4337/interfaces/UserOperation.sol\";\n\n/**\n * @title Verification Facet Interface\n * @dev Implements logic for user ops signature verification\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface IVerificationFacet {\n event SignerInitialized(bytes);\n event SignerUninitialized();\n\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n error VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n error VerificationFacet__InitializationFailure();\n error VerificationFacet__InvalidFacetMapping();\n\n function initializeSigner(bytes memory) external returns (uint256);\n\n function uninitializeSigner() external returns (uint256);\n\n function validateOwnerSignatureSelector() external view returns (bytes4);\n\n function owner() external view returns (bytes memory);\n\n function isValidKeyType(bytes calldata) external view returns (bool);\n\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) external view returns (uint256);\n}\n" + }, + "contracts/facets/LockFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage, Lock} from \"../libraries/LibAppStorage.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibFacetStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {ILockFacet} from \"./interfaces/ILockFacet.sol\";\n\n/**\n * @title Lock Facet\n * @dev Contract that enables full lock/unlock of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract LockFacet is ILockFacet, Modifiers {\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Locks the account for the lock period. Lock period is defined in the security manager and it's customizable\n * This function can only be called when account is unlocked by owner or guardians\n * @dev This method checks the caller and if the account is currently locked and locks the account after fetching the\n * Lock period from the owner.\n */\n function lock() external override onlyGuardianOrOwner onlyWhenUnlocked {\n uint256 unlockTime = block.timestamp + getLockPeriod();\n unchecked {\n ++LibFacetStorage.lockStorage().nonce;\n }\n LibAppStorage.setLock(unlockTime, LockFacet.lock.selector);\n emit Locked(uint64(unlockTime));\n }\n\n /**\n * @notice Locks the account when the account is locked. This function can be called by anyone but must provide the approver address and signature.\n * The approver should be one of the guardians or owner.\n * @dev This method takes the approver address and the signature. After validating the address and the signature, it unlocks the account immediately.\n * Only one of the guardian or owner is required to lock and unlock the account.\n * @param _approver Address of approver approving the unlock of Barz account\n * @param _signature Signature of the approver that signed the msg hash for unlocking the account\n */\n function unlock(\n address _approver,\n bytes calldata _signature\n ) external override onlyWhenLocked {\n if (_approver != address(this) && !LibGuardian.isGuardian(_approver))\n revert LockFacet__InvalidApprover();\n if (\n !SignatureChecker.isValidSignatureNow(\n _approver,\n getUnlockHash(),\n _signature\n )\n ) revert LockFacet__InvalidSignature();\n _unlock();\n }\n\n /**\n * @notice Unlocks the account and increments the lock nonce\n */\n function _unlock() private {\n if (s.locks[INNER_STRUCT].locker != LockFacet.lock.selector)\n revert LockFacet__CannotUnlock();\n unchecked {\n ++LibFacetStorage.lockStorage().nonce;\n }\n LibAppStorage.setLock(0, bytes4(0));\n emit Unlocked();\n }\n\n /**\n * @notice Returns the lock period of current Barz account. Lock period information is held by Security Manager\n * @return lockPeriod Uint value of lock period in seconds\n */\n function getLockPeriod() public view override returns (uint256 lockPeriod) {\n lockPeriod = securityManager.lockPeriodOf(address(this));\n if (lockPeriod == 0) revert LockFacet__InvalidRecoveryPeriod();\n }\n\n /**\n * @notice Returns if the account is locked or not\n * @dev This method fetches the current block timestamp and compares that with release time.\n * After checking the timestamp and release time, it returns if the account is still locked or not.\n * @return isLocked_ Uint value of lock period in seconds\n */\n function isLocked() public view override returns (bool isLocked_) {\n isLocked_ = uint64(block.timestamp) < s.locks[INNER_STRUCT].release;\n }\n\n /**\n * @notice Calculates the unlock hash and returns the unlock hash safe from signature reply attack\n * @dev This method calculates the unlock hash with EIP-191 prefix, wallet address, chainID, and nonce\n * It packs the result and packs them and hashes it.\n * @return unlockHash Bytes32 unlock hash\n */\n function getUnlockHash() public view override returns (bytes32 unlockHash) {\n unlockHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n \"Unlock\",\n address(this),\n block.chainid,\n lockNonce()\n )\n )\n )\n );\n }\n\n /**\n * @notice Returns lock nonce of account. Reads nonce from lock storage within facet storage\n * @return lockNonce_ Uint128 value of lock nonce. This is incremented whenever the account is lock/unlocked\n */\n function lockNonce() public view override returns (uint128 lockNonce_) {\n lockNonce_ = LibFacetStorage.lockStorage().nonce;\n }\n\n /**\n * @notice Returns the overall information of current lock\n * @return pendingLock Struct value including all information of pending lock\n */\n function getPendingLock()\n public\n view\n override\n returns (Lock memory pendingLock)\n {\n pendingLock = s.locks[INNER_STRUCT];\n }\n}\n" + }, + "contracts/facets/Modifiers.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\n\n/**\n * @title Modifiers\n * @dev Responsible for providing modifiers/util functions to Facet contracts\n * @author David Yongjun Kim (@Powerstream3604)\n */\nabstract contract Modifiers is BarzStorage {\n uint8 constant INNER_STRUCT = 0;\n\n error CallerNotGuardian();\n error CallerNotGuardianOrOwner();\n error DuplicateApprover();\n error ZeroApproverLength();\n error UnregisteredFacetAndSelectors();\n\n /**\n * @notice Modifier to only allow guardian to make a call, reverts if any other entity is the caller\n */\n modifier onlyGuardian() {\n if (!LibGuardian.isGuardian(msg.sender)) revert CallerNotGuardian();\n _;\n }\n\n /**\n * @notice Modifier to only allow guardian or owner to make a call, reverts if any other entity is the caller\n */\n modifier onlyGuardianOrOwner() {\n if (!LibGuardian.isGuardian(msg.sender) && address(this) != msg.sender)\n revert CallerNotGuardianOrOwner();\n _;\n }\n\n /**\n * @notice Checks if the approver address is the array is unique with no duplicate\n * @dev This method loops through the array and checks if a duplicate address exists, it reverts if duplicate address exists\n * @param approvers Array of address\n */\n function _checkApprover(\n address[] memory approvers\n ) internal pure returns (bool) {\n uint256 approverLength = approvers.length;\n if (0 == approverLength) revert ZeroApproverLength();\n for (uint256 i; i < approverLength - 1; ) {\n for (uint256 j = i + 1; j < approverLength; ) {\n if (approvers[i] == approvers[j]) {\n revert DuplicateApprover(); // Found a duplicate\n }\n unchecked {\n ++j;\n }\n }\n unchecked {\n ++i;\n }\n }\n return false; // No duplicates found\n }\n\n /**\n * @notice Checks if the facet getting added or replaced is registered to facet registry\n * @dev This method loops through the cut and checks if the facet getting added/replaced is registered to facet registry\n * @param _diamondCut Array of FacetCut, data for diamondCut defined in EIP-2535\n */\n function _checkFacetCutValidity(\n IDiamondCut.FacetCut[] memory _diamondCut\n ) internal view {\n uint256 diamondCutLength = _diamondCut.length;\n for (uint256 i; i < diamondCutLength; ) {\n if (\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Add ||\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Replace\n ) {\n if (\n !s.facetRegistry.areFacetFunctionSelectorsRegistered(\n _diamondCut[i].facetAddress,\n _diamondCut[i].functionSelectors\n )\n ) revert UnregisteredFacetAndSelectors();\n }\n unchecked {\n ++i;\n }\n }\n }\n}\n" + }, + "contracts/facets/RestrictionsFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ReentrancyGuard} from \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, RestrictionsStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {IRestriction} from \"../restrictions/IRestriction.sol\";\nimport {IRestrictionsFacet} from \"./interfaces/IRestrictionsFacet.sol\";\n\n/**\n * @title Restrictions facet\n * @dev Responsible for storing and verifying different kinds of restrictions, for example:\n * - Whitelist / Blacklist\n * - Daily limits\n * - Trading time restrictions\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract RestrictionsFacet is IRestrictionsFacet, ReentrancyGuard {\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceRestrictionsInitialize();\n }\n\n /**\n * @notice Intialize restrictions of Barz. Restrictions facet call restriction contracts for restriction validation\n * before each call\n * @param _restrictions The initial array of restrictions.\n * @return initSuccess Int value showing if the initialization of restriction is successful\n */\n function initializeRestrictions(\n address[] calldata _restrictions\n ) public override returns (uint256 initSuccess) {\n LibDiamond.enforceIsSelf();\n LibAppStorage.enforceRestrictionsInitialize();\n\n if (_restrictions.length == 0) {\n // You can't initialize RestrictionsFacet with an empty list of restrictions\n revert RestrictionsFacet__EmptyRestrictionsList();\n }\n for (uint256 i; i < _restrictions.length; ) {\n if (_restrictions[i] == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictions();\n unchecked {\n ++i;\n }\n }\n\n LibFacetStorage.restrictionsStorage().restrictions = _restrictions;\n _updateRestrictionsMap(_restrictions, true);\n initSuccess = 1;\n }\n\n /**\n * @notice Unitialize restrictions of Barz\n * @return uninitSuccess Int value showing if the initialization of restriction is successful\n */\n function uninitializeRestrictions()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibDiamond.enforceIsSelf();\n LibAppStorage.setRestrictionsUninitialized();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n _updateRestrictionsMap(restrictionsStorage.restrictions, false);\n restrictionsStorage.restrictions = new address[](0);\n uninitSuccess = 1;\n }\n\n /**\n * @notice Returns the list of Restrictions contract address\n * @return restrictions Addresses of IRestriction which are currently active\n */\n function getRestrictions()\n public\n view\n override\n returns (address[] memory restrictions)\n {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n restrictions = restrictionsStorage.restrictions;\n }\n\n /**\n * @notice Adds restrictions to Barz with validation on the restriction contract address.\n * This method is only callable by the owner(self).\n * @param _restriction The address of the restriction to be added.\n */\n function addRestriction(address _restriction) external override {\n LibDiamond.enforceIsSelf();\n if (LibDiamond.restrictionsFacet() == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictionsFacet();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n if (_restriction == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictions();\n if (restrictionsStorage.exists[_restriction])\n revert RestrictionsFacet__RestrictionAlreadyExists();\n\n restrictionsStorage.restrictions.push(_restriction);\n restrictionsStorage.exists[_restriction] = true;\n\n emit RestrictionAdded(_restriction);\n }\n\n /**\n * @notice Remove restrictions from Barz if it existed. This method is only callable by the owner(self).\n * @param _restriction The address of the restriction to be removed.\n */\n function removeRestriction(address _restriction) external override {\n LibDiamond.enforceIsSelf();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n if (!restrictionsStorage.exists[_restriction])\n revert RestrictionsFacet__RestrictionNotFound();\n\n address[] storage restrictions = restrictionsStorage.restrictions;\n\n uint256 indexToDelete = restrictions.length;\n uint256 restrictionsLen = restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n if (restrictions[i] == _restriction) {\n indexToDelete = i;\n break;\n }\n unchecked {\n ++i;\n }\n }\n\n if (indexToDelete == 0 && restrictionsLen == 1) {\n revert RestrictionsFacet__RemainingRestrictionsCantBeEmpty();\n } else if (indexToDelete == restrictionsLen) {\n revert RestrictionsFacet__RestrictionNotFound();\n } else {\n restrictions[indexToDelete] = restrictions[restrictionsLen - 1];\n restrictions.pop();\n }\n\n restrictionsStorage.exists[_restriction] = false;\n emit RestrictionRemoved(_restriction);\n }\n\n /**\n * @notice Sets the restrictions address value mapping to true or false when adding/removing restriction contracts\n * @param _restrictions List of restriction contracts address\n * @param _newValue Bool value to flag to the list of restrictions contracts\n */\n function _updateRestrictionsMap(\n address[] memory _restrictions,\n bool _newValue\n ) internal {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n uint restrictionsLen = _restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n restrictionsStorage.exists[_restrictions[i]] = _newValue;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @dev Iterates over all restrictions and verifies each of them with the transaction parameters.\n * @param _from The address of the sender, that will be signing the transaction.\n * @param _to The receiving address.\n * @param _value Amount of ETH to transfer from sender to recipient.\n * @param _calldata Optional field to include arbitrary data.\n * @return 0 if all the checks passed, 1 otherwise.\n */\n function verifyRestrictions(\n address _from,\n address _to,\n uint256 _value,\n bytes calldata _calldata\n ) external nonReentrant returns (uint256) {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n uint restrictionsLen = restrictionsStorage.restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n IRestriction restriction = IRestriction(\n restrictionsStorage.restrictions[i]\n );\n bool checkPassed = restriction.check(_from, _to, _value, _calldata);\n if (!checkPassed) {\n return 1;\n }\n unchecked {\n ++i;\n }\n }\n\n return 0;\n }\n}\n" + }, + "contracts/facets/SignatureMigrationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, SignatureMigrationStorage, SignatureMigrationConfig, SignatureMigrationApprovalConfig, ApprovalConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IDiamondCut} from \"./base/interfaces/IDiamondCut.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {ISignatureMigrationFacet} from \"./interfaces/ISignatureMigrationFacet.sol\";\n\n/**\n * @title Signature Migration Facet\n * @dev Responsible for migrating user signature scheme to a new scheme user sets\n * Which could include\n * - ECDSA on Secp256K1 Curve\n * - ECDSA on Secp256R1 Curve\n * - BLS, Schnorr, etc\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract SignatureMigrationFacet is ISignatureMigrationFacet, Modifiers {\n bytes constant UNINIT_CALL =\n abi.encodeWithSignature(\"uninitializeSigner()\");\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This modifier verifies if the public key format matches with the new verification facet\n * @param _publicKey Bytes of public key to be validated for the new verification facet\n * @param _newVerificationFacet Address of new verification facet\n */\n modifier validateKeyType(\n bytes memory _publicKey,\n address _newVerificationFacet\n ) {\n if (\n !IVerificationFacet(_newVerificationFacet).isValidKeyType(\n _publicKey\n )\n ) revert SignatureMigrationFacet__InvalidKeyType();\n _;\n }\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n // IMPORTANT NOTE: In the client side when they call this function, the func selectors should be sorted in ascending order\n // to prevent different hash with same items in the array\n /**\n * @notice Moves the state of migration to a pending state. When pending state is over after pending period time,\n * Migration can be finalized. This function can only be called by self and when the account is unlocked.\n * @dev This method checks if the caller is self and if guardians exists. It migrates signature request to a pending state\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function migrateSignatureScheme(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n public\n override\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n // Only self contract can call this function\n LibDiamond.enforceIsSelf();\n // Should revert if guardian exist\n if (0 != LibGuardian.guardianCount())\n revert SignatureMigrationFacet__InvalidRouteWithGuardian();\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n // NOTE: Migration requires a pending period & confirmation from owner to prevent a\n // single call changing the ownership of the wallet\n /**\n * @notice Migrate signature scheme when guardians exists. Verifies the signature of guardians and moves migration to pending state.\n * Which can then be finalized when pending period is over. Owner's approval is mandatory for migration to happen\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _approvers List of approvers. This could include owner\n */\n function migrateSignatureSchemeWithGuardian(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n )\n public\n override\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n // Should revert if does not guardian exist\n if (0 == LibGuardian.guardianCount())\n revert SignatureMigrationFacet__InvalidRouteWithGuardian();\n if (_approvers.length != _signatures.length)\n revert SignatureMigrationFacet__InvalidArrayLength();\n\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(migrationPublicKeyHash, _approvers);\n\n bool onChainOwnerApproval = getMigrationOwnerApprovalWithTimeValidity(\n migrationPublicKeyHash\n );\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n\n if (\n _approvers.length +\n getMigrationApprovalCountWithTimeValidity(\n migrationPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert SignatureMigrationFacet__InsufficientApprovers();\n {\n // To prevent Stack too deep\n bool ownerApproved;\n for (uint256 i; i < _approvers.length; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n address(this) != _approvers[i]\n ) revert SignatureMigrationFacet__InvalidGuardian();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert SignatureMigrationFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n migrationPublicKeyHash,\n _signatures[i]\n )\n ) revert SignatureMigrationFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n\n if (!ownerApproved && !onChainOwnerApproval)\n revert SignatureMigrationFacet__LackOfOwnerApproval();\n }\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Internal function that moves signature mgiration to a pending state.\n * @dev This method increments migration nonce and sets the migration in the migration config. Emits events for migration execution\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _migrateSignatureScheme(\n address _newVerificationFacet,\n bytes memory _newPublicKey,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal {\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n unchecked {\n ++ms.nonce;\n }\n uint64 migrateAfter = uint64(block.timestamp + getMigrationPeriod());\n\n ms.migrationConfigs[INNER_STRUCT] = SignatureMigrationConfig(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n migrateAfter\n );\n\n emit SignatureMigrationExecuted(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors,\n migrateAfter\n );\n }\n\n /**\n * @notice Approves signature scheme migration on-chain. This can be called by owner or guardian only when the account is unlocked.\n * When the threshold of the migration approval passed and owner approval is granted, it automatically moves migration to a pending state\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function approveSignatureSchemeMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n public\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit SignatureMigrationApproved(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n msg.sender,\n approvalValidUntil\n );\n if (\n getMigrationApprovalCountWithTimeValidity(migrationPublicKeyHash) >=\n LibGuardian.majorityOfGuardians() &&\n getMigrationOwnerApprovalWithTimeValidity(migrationPublicKeyHash)\n )\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Revokes the approval of signature migration done on-chain. Emits revoke event when revoked.\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function revokeSignatureMigrationApproval(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n external\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n if (!isMigrationApproved(migrationPublicKeyHash, msg.sender))\n revert SignatureMigrationFacet__CannotRevokeUnapproved();\n\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(false, 0);\n emit SignatureMigrationApprovalRevoked(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n msg.sender\n );\n }\n\n /**\n * @notice Finalizes the pending signature scheme migration. This function can only be called by owner.\n * It removes the facets of the previous verification facet and adds the new verification facet.\n * After finalizing migration, it emits migration event which shows the change of the verification facet\n */\n function finalizeSignatureMigration() external override {\n // NOTE: Only owner can call this function\n LibDiamond.enforceIsSelf();\n\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n\n if (!isMigrationPending())\n revert SignatureMigrationFacet__NonexistentMigration();\n\n if (\n uint64(block.timestamp) <=\n ms.migrationConfigs[INNER_STRUCT].migrateAfter\n ) revert SignatureMigrationFacet__MigrationPeriodNotOver();\n address newVerificationFacet = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationVerificationFacet;\n bytes4[] memory newVerificationFuncSelectors = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationSelectors;\n bytes memory newPublicKey = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationPublicKey;\n\n address prevVerificationFacet = LibLoupe.facetAddress(\n s.validateOwnerSignatureSelector\n );\n if (prevVerificationFacet == address(0))\n revert SignatureMigrationFacet__NonExistentVerificationFacet();\n\n IDiamondCut.FacetCut[] memory UninitCut;\n IDiamondCut.FacetCut[] memory InitCut;\n {\n bytes4[] memory prevVerificationFuncSelectors = LibLoupe\n .facetFunctionSelectors(prevVerificationFacet);\n\n UninitCut = new IDiamondCut.FacetCut[](1);\n InitCut = new IDiamondCut.FacetCut[](1);\n UninitCut[0] = IDiamondCut.FacetCut({\n facetAddress: address(0),\n action: IDiamondCut.FacetCutAction.Remove,\n functionSelectors: prevVerificationFuncSelectors\n });\n InitCut[0] = IDiamondCut.FacetCut({\n facetAddress: newVerificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: newVerificationFuncSelectors\n });\n {\n IDiamondCut.FacetCut[]\n memory facetCuts = new IDiamondCut.FacetCut[](2);\n facetCuts[0] = UninitCut[0];\n facetCuts[1] = InitCut[0];\n _checkFacetCutValidity(facetCuts);\n }\n LibAppStorage.initiateSignerMigration();\n address verificationFacet = address(\n bytes20(\n LibDiamond.diamondStorage().facets[\n s.validateOwnerSignatureSelector\n ]\n )\n );\n\n (bool uninitSuccess, bytes memory uninitResult) = verificationFacet\n .delegatecall(UNINIT_CALL);\n if (!uninitSuccess || uint256(bytes32(uninitResult)) != 1)\n revert SignatureMigrationFacet__SignerUninitializationFailure();\n LibAppStorage.finalizeSignerMigration();\n\n LibDiamond.diamondCut(UninitCut, address(0), \"\");\n }\n {\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n newPublicKey\n );\n\n // Every Verification Facet should comply with initializeSigner(bytes)\n // to be compatible with the Barz contract(for initialization)\n LibDiamond.diamondCut(InitCut, address(0), \"\");\n (bool initSuccess, bytes memory initResult) = newVerificationFacet\n .delegatecall(initCall);\n if (!initSuccess || uint256(bytes32(initResult)) != 1)\n revert SignatureMigrationFacet__SignerInitializationFailure();\n\n emit SignatureSchemeMigration(\n prevVerificationFacet,\n newVerificationFacet,\n newPublicKey,\n newVerificationFuncSelectors\n );\n }\n }\n\n /**\n * @notice Approve cancellation of signature migration. If cancellation approval passes guardian threshold with owner approval\n * it automatically cancels the migration.\n * @dev This method checks if the caller is one of guardian or owner and sets true for the cancellation hash in the approval config.\n * It internally calls _cancelSignatureMigration for canceling the migration\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function approveCancelSignatureMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n external\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"CancelSignatureMigration\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit SignatureMigrationCancellationApproved(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n if (\n getMigrationApprovalCountWithTimeValidity(migrationPublicKeyHash) >=\n LibGuardian.majorityOfGuardians() &&\n getMigrationOwnerApprovalWithTimeValidity(migrationPublicKeyHash)\n )\n _cancelSignatureMigration(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Verifies the signature of guardians/owner and cancels the signature migration.\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _approvers List of approvers. This could include owner\n */\n function cancelSignatureMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n )\n external\n override\n validateKeyType(_newPublicKey, _newVerificationFacet)\n onlyWhenUnlocked\n {\n if (_approvers.length != _signatures.length)\n revert SignatureMigrationFacet__InvalidArrayLength();\n\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"CancelSignatureMigration\"\n );\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(migrationPublicKeyHash, _approvers);\n\n bool onChainOwnerApproval = getMigrationOwnerApprovalWithTimeValidity(\n migrationPublicKeyHash\n );\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n if (\n _approvers.length +\n getMigrationApprovalCountWithTimeValidity(\n migrationPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert SignatureMigrationFacet__InsufficientApprovers();\n {\n // To prevent stack too deep\n bool ownerApproved;\n for (uint256 i; i < _approvers.length; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n address(this) != _approvers[i]\n ) revert SignatureMigrationFacet__NonExistentApprover();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert SignatureMigrationFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n migrationPublicKeyHash,\n _signatures[i]\n )\n ) revert SignatureMigrationFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n if (!ownerApproved && !onChainOwnerApproval)\n revert SignatureMigrationFacet__LackOfOwnerApproval();\n }\n _cancelSignatureMigration(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Internal function that cancels signature migration.\n * @dev This method increments migration nonce and deletes the migration from the migration config. Emits events for migration cancellation\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _cancelSignatureMigration(\n address _newVerificationFacet,\n bytes memory _newPublicKey,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal {\n if (!isMigrationPending())\n revert SignatureMigrationFacet__NonexistentMigration();\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n unchecked {\n ++ms.nonce;\n }\n delete ms.migrationConfigs[INNER_STRUCT];\n emit SignatureMigrationCanceled(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Checks if the facets to be added from new verification facet is registered to facet registry\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _checkMigrationCutValidity(\n address _newVerificationFacet,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal view {\n IDiamondCut.FacetCut[] memory facetCuts = new IDiamondCut.FacetCut[](1);\n facetCuts[0] = IDiamondCut.FacetCut({\n facetAddress: _newVerificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: _newVerificationFuncSelectors\n });\n _checkFacetCutValidity(facetCuts);\n }\n\n /**\n * @notice Returns if the migration is pending of not\n * @dev This method fetches the migration storage and checks if the migrate after is above 0 value\n * @return isPending Bool value that shows if the migration is pending\n */\n function isMigrationPending()\n public\n view\n override\n returns (bool isPending)\n {\n SignatureMigrationStorage storage rs = LibFacetStorage\n .migrationStorage();\n isPending = rs.migrationConfigs[INNER_STRUCT].migrateAfter > 0;\n }\n\n /**\n * @notice Returns the migration hash. This function ensures that this hash is safe from replay attack by including\n * public key, verification facet, function selectors, salt, address, chainId, and nonce.\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _saltString Salt value for generating the migration hash\n * @return migrationKeyHash Bytes32 string of the migration key hash\n */\n function getApprovalMigrationKeyHash(\n bytes memory _newPublicKey,\n address _newVerificationFacet,\n bytes4[] memory _newVerificationFuncSelectors,\n string memory _saltString\n ) public view override returns (bytes32 migrationKeyHash) {\n migrationKeyHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n _newPublicKey,\n _newVerificationFacet,\n keccak256(abi.encode(_newVerificationFuncSelectors)),\n _saltString,\n address(this),\n block.chainid,\n LibFacetStorage.migrationStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Checks if the owner approved the hash for migration\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @return isApprovedByOwner Bool value of showing if the owner approved it or not\n */\n function getMigrationOwnerApprovalWithTimeValidity(\n bytes32 _migrationPublicKeyHash\n ) public view override returns (bool isApprovedByOwner) {\n isApprovedByOwner = isMigrationApproved(\n _migrationPublicKeyHash,\n address(this)\n );\n }\n\n /**\n * @notice Checks how many of the guardians approved the migration hash\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @return approvalCount Number of approvals\n */\n function getMigrationApprovalCountWithTimeValidity(\n bytes32 _migrationPublicKeyHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardiansLength = guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n if (isMigrationApproved(_migrationPublicKeyHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n return approvalCount;\n }\n\n /**\n * @notice Checks if the migration is approved by the given approver\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @param _approver Address of approver\n * @return isApproved Bool value if migration hash is approved\n */\n function isMigrationApproved(\n bytes32 _migrationPublicKeyHash,\n address _approver\n ) public view override returns (bool isApproved) {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n isApproved = (ms\n .isMigrationApproved[_migrationPublicKeyHash][_approver].isApproved &&\n block.timestamp <\n ms\n .isMigrationApproved[_migrationPublicKeyHash][_approver]\n .validUntil);\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _migrationPublicKeyHash Hash of migration information\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _migrationPublicKeyHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isMigrationApproved(_migrationPublicKeyHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert SignatureMigrationFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the migration period of this wallet\n * @dev This method fetches the migration period from the security manager\n * @return migrationPeriod Migration period of Barz contract fetched from security manager\n */\n function getMigrationPeriod()\n internal\n view\n returns (uint128 migrationPeriod)\n {\n migrationPeriod = securityManager.migrationPeriodOf(address(this));\n if (migrationPeriod == 0)\n revert SignatureMigrationFacet__InvalidMigrationPeriod();\n }\n\n /**\n * @notice Returns the validation period of this wallet\n * @dev This method fetches the validation period from the security manager\n * @return approvalValidationPeriod Validation period of Barz contract fetched from security manager\n */\n function getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod == 0)\n revert SignatureMigrationFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the migration nonce of this wallet\n * @dev This method fetches the nonce from migration storage\n * @return migrationNonce Nonce of migration to protect from reply attacks\n */\n function getMigrationNonce()\n public\n view\n override\n returns (uint128 migrationNonce)\n {\n migrationNonce = LibFacetStorage.migrationStorage().nonce;\n }\n\n /**\n * @notice Returns the migration configuration of this wallet\n * @dev This method fetches the migration config from the migration storage\n * @return pendingMigrationConfig Migration config currently pending for signature migration\n */\n function getPendingMigration()\n external\n view\n override\n returns (SignatureMigrationConfig memory pendingMigrationConfig)\n {\n pendingMigrationConfig = LibFacetStorage\n .migrationStorage()\n .migrationConfigs[INNER_STRUCT];\n }\n}\n" + }, + "contracts/facets/TokenReceiverFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {IERC1155Receiver} from \"../interfaces/ERC/IERC1155Receiver.sol\";\nimport {IERC677Receiver} from \"../interfaces/ERC/IERC677Receiver.sol\";\n\n/**\n * @title TokenReceiver Facet\n * @dev Contract that enables receiving ERC721/ERC1155/ERC777/ERC677 Tokens with safe transfer\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract TokenReceiverFacet is\n IERC721Receiver,\n IERC1155Receiver,\n IERC777Recipient,\n IERC677Receiver\n{\n /**\n * @notice Handles ERC721 Token callback.\n * return Standardized onERC721Received return value.\n */\n function onERC721Received(\n address,\n address,\n uint256,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC721Receiver.onERC721Received.selector;\n }\n\n /**\n * @notice Handles ERC1155 Token callback.\n * return Standardized onERC1155Received return value.\n */\n function onERC1155Received(\n address,\n address,\n uint256,\n uint256,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC1155Receiver.onERC1155Received.selector;\n }\n\n /**\n * @notice Handles ERC1155 Token batch callback.\n * return Standardized onERC1155BatchReceived return value.\n */\n function onERC1155BatchReceived(\n address,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC1155Receiver.onERC1155BatchReceived.selector;\n }\n\n /**\n * @notice Handles ERC777 Token callback.\n * Does not return value, empty implementation.\n */\n function tokensReceived(\n address,\n address,\n address,\n uint256,\n bytes calldata,\n bytes calldata\n ) external pure override {}\n\n /**\n * @notice Handles ERC677 Token callback.\n * return true.\n */\n function onTokenTransfer(\n address,\n uint256,\n bytes calldata\n ) external pure override returns (bool) {\n return true;\n }\n}\n" + }, + "contracts/facets/verification/MultiSigFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {UserOperation} from \"../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../../libraries/LibLoupe.sol\";\nimport {LibAppStorage} from \"../../libraries/LibAppStorage.sol\";\nimport {LibMultiSigStorage, MultiSigStorage} from \"../../libraries/LibMultiSigStorage.sol\";\nimport {IERC1271} from \"../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../interfaces/IVerificationFacet.sol\";\nimport {IMultiSigFacet} from \"../interfaces/IMultiSigFacet.sol\";\n\n/**\n * @title Multi-sig facet\n * @dev Multi-signature Facet with custom threshold.\n * Wallet that adds this facet becomes a multi-sig wallet.\n * Reference signature_format.md documentation for Multi-sig facet details\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract MultiSigFacet is IMultiSigFacet, IVerificationFacet, IERC1271 {\n using ECDSA for bytes32;\n\n address public immutable self;\n\n address internal constant SENTINEL_OWNERS = address(0x1);\n uint256 internal constant ADDRESS = 20;\n uint256 internal constant SIG_TYPE = 1;\n uint256 internal constant SIG_LEN = 4;\n uint256 internal constant THRESHOLD = 4;\n uint256 internal constant INVALID_SIG = 1;\n uint256 internal constant VALID_SIG = 0;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in Multisig Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the right format and initializes signer storage in k1 storage.\n * @param _owners Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _owners\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n\n if (!isValidKeyType(_owners)) revert MultiSigFacet__InvalidInitData();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n uint256 threshold = uint256(uint32(bytes4(_owners)));\n uint256 ownerCount = (_owners.length - THRESHOLD) / ADDRESS;\n\n if (threshold == 0) revert MultiSigFacet__InvalidThreshold();\n if (ownerCount == 0) revert MultisigFacet__InvalidOwnerCount();\n\n address currentOwner = SENTINEL_OWNERS;\n uint256 ptr = THRESHOLD;\n address owner_;\n for (uint256 i; i < ownerCount; ) {\n owner_ = address(bytes20(_owners[ptr:ptr + ADDRESS]));\n ptr += ADDRESS;\n if (\n owner_ == address(0) ||\n owner_ == SENTINEL_OWNERS ||\n owner_ == address(this) ||\n owner_ == currentOwner\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[owner_] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n\n ms.owners[currentOwner] = owner_;\n currentOwner = owner_;\n\n unchecked {\n ++i;\n }\n }\n ms.owners[currentOwner] = SENTINEL_OWNERS;\n ms.ownerCount = ownerCount;\n ms.threshold = threshold;\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_owners);\n }\n\n /**\n * @notice Uninitialize signer in K1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n ++ms.counter;\n address[] memory ownerlist = getOwners();\n uint256 ownerlistLength = ownerlist.length;\n for (uint256 i; i < ownerlistLength; ) {\n ms.owners[ownerlist[i]] = address(0);\n unchecked {\n ++i;\n }\n }\n ms.owners[SENTINEL_OWNERS] = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls checkSignatures with\n * user operation hash and signature together with the threshold.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n // Data 1 is invalid, Data 0 is valid\n validationData = checkSignatures(\n userOpHash,\n userOp.signature,\n LibMultiSigStorage.multisigStorage().threshold\n );\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n return this.validateOwnerSignature.selector;\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n uint totalLength = ms.ownerCount * ADDRESS;\n bytes memory result = new bytes(totalLength);\n\n // populate return array\n uint256 index;\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n while (currentOwner != SENTINEL_OWNERS) {\n assembly {\n mstore(\n add(result, add(32, mul(index, ADDRESS))),\n shl(96, currentOwner)\n )\n }\n currentOwner = ms.owners[currentOwner];\n index++;\n }\n\n return result;\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key should comply with the format in the signature_format.md doc\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n uint256 publicKeyLength = _publicKey.length;\n if (\n publicKeyLength < ADDRESS + THRESHOLD ||\n (publicKeyLength - THRESHOLD) % ADDRESS != 0\n ) return false;\n\n uint256 threshold = uint256(uint32(bytes4(_publicKey)));\n uint256 ownerCount = (publicKeyLength - THRESHOLD) / ADDRESS;\n\n isValid = !(ownerCount < threshold || threshold == 0);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes calldata _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (checkSignatures(\n _hash,\n _signature,\n LibMultiSigStorage.multisigStorage().threshold\n ) == VALID_SIG)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n\n /**\n * @notice Validates the format of the signature and verifies if the signature is signed by the expected key.\n * Reference signature_format.md doc for details about signature format and signature types\n * @param _dataHash Bytes value of data hash signed by the owners\n * @param _signatures Bytes value of signature which should comply with signature format\n * @param _threshold Uint256 value of current Multi-sig Barz's threshold\n */\n function checkSignatures(\n bytes32 _dataHash,\n bytes calldata _signatures,\n uint256 _threshold\n ) public view returns (uint256) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n address lastOwner = address(0);\n address currentOwner;\n bytes memory signature;\n uint256 signatureType;\n uint256 nextOffset;\n uint256 i;\n for (i; i < _threshold; ) {\n (\n currentOwner,\n signature,\n signatureType,\n nextOffset\n ) = splitSignatures(_signatures, nextOffset);\n if (nextOffset == 0 && i + 1 < _threshold) return INVALID_SIG;\n if (signatureType == 1) {\n // If signatureType is 1 then it is default dataHash signed.\n // This also includes the contract signature\n if (\n !SignatureChecker.isValidSignatureNow(\n currentOwner,\n _dataHash,\n signature\n )\n ) return INVALID_SIG;\n } else if (signatureType == 2) {\n // If signatureType is 2 then it is an approved hash\n if (ms.approvedHashes[ms.counter][currentOwner][_dataHash] == 0)\n return INVALID_SIG;\n } else if (signatureType == 3) {\n // If signatureType is 3 then it is a signed message hash\n // This also includes the contract signature\n bytes32 msgHash = _dataHash.toEthSignedMessageHash();\n if (\n !SignatureChecker.isValidSignatureNow(\n currentOwner,\n msgHash,\n signature\n )\n ) return INVALID_SIG;\n } else revert MultiSigFacet__InvalidRoute();\n if (\n currentOwner <= lastOwner ||\n ms.owners[currentOwner] == address(0) ||\n currentOwner == SENTINEL_OWNERS\n ) return INVALID_SIG;\n lastOwner = currentOwner;\n\n unchecked {\n ++i;\n }\n }\n return VALID_SIG;\n }\n\n /**\n * @notice Split signatures into each individual signatures. Should comply with signature format to be split\n * @param _signatures Bytes value of signature\n * @param _nextOffset Uint256 value of next offset to start splitting the signature\n */\n function splitSignatures(\n bytes calldata _signatures,\n uint256 _nextOffset\n )\n public\n pure\n returns (\n address owner_,\n bytes memory signature,\n uint256 signatureType,\n uint256 nextOffset\n )\n {\n uint256 signaturesLength = _signatures.length;\n\n if (signaturesLength <= _nextOffset + ADDRESS + SIG_LEN)\n revert MultiSigFacet__InsufficientSignerLength();\n\n owner_ = address(\n bytes20(_signatures[_nextOffset:_nextOffset + ADDRESS])\n );\n\n signatureType = uint256(\n uint8(\n bytes1(\n _signatures[_nextOffset + ADDRESS:_nextOffset +\n ADDRESS +\n SIG_TYPE]\n )\n )\n );\n\n if (signatureType > 3 || signatureType == 0)\n revert MultiSigFacet__InvalidSignatureType();\n uint256 offSet = _nextOffset + ADDRESS + SIG_TYPE;\n uint256 siglen = uint256(\n uint32(bytes4(_signatures[offSet:offSet + SIG_LEN]))\n );\n if (offSet + siglen > signaturesLength)\n revert MultiSigFacet__InvalidSignatureLength();\n\n offSet += SIG_LEN;\n if (offSet + siglen == signaturesLength) nextOffset = 0;\n else nextOffset = offSet + siglen;\n\n signature = _signatures[offSet:offSet + siglen];\n }\n\n /**\n * @notice Approves the hash of userOperation on-chain. This can only be called by owners.\n * @param _hashToApprove Bytes value of UserOperation hash to approve\n */\n function approveHash(bytes32 _hashToApprove) external {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (ms.owners[msg.sender] == address(0))\n revert MultiSigFacet__OnlyOwner();\n\n ms.approvedHashes[ms.counter][msg.sender][_hashToApprove] = 1;\n emit HashApproved(_hashToApprove, msg.sender);\n }\n\n /**\n * @notice Add owner to Barz. Update thresold if threshold is given different from current threshold\n * @dev This can only be done via a Self call.\n * @param _newOwner Address of new owner to be added\n * @param _threshold Uint256 value of threshold\n */\n function addOwner(address _newOwner, uint256 _threshold) external {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (\n _newOwner == address(0) ||\n _newOwner == SENTINEL_OWNERS ||\n _newOwner == address(this)\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_newOwner] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n\n ms.owners[_newOwner] = ms.owners[SENTINEL_OWNERS];\n ms.owners[SENTINEL_OWNERS] = _newOwner;\n ++ms.ownerCount;\n emit OwnerAdded(_newOwner);\n\n if (ms.threshold != _threshold) changeThreshold(_threshold);\n }\n\n /**\n * @notice Remove owner from Barz. Update thresold if threshold is given different from current threshold\n * @dev This can only be done via a Self call.\n * @param _prevOwner Address of owner located right behind the removed owner address in the linked list\n * @param _removedOwner Address of owner to be removed\n * @param _threshold Uint256 value of threshold\n */\n function removeOwner(\n address _prevOwner,\n address _removedOwner,\n uint256 _threshold\n ) external {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (ms.ownerCount - 1 < _threshold)\n revert MultiSigFacet__InvalidThreshold();\n if (_removedOwner == address(0) || _removedOwner == SENTINEL_OWNERS)\n revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_prevOwner] != _removedOwner)\n revert MultiSigFacet__InvalidOwnerPair();\n\n ms.owners[_prevOwner] = ms.owners[_removedOwner];\n ms.owners[_removedOwner] = address(0);\n --ms.ownerCount;\n emit OwnerRemoved(_removedOwner);\n\n if (ms.threshold != _threshold) changeThreshold(_threshold);\n }\n\n /**\n * @notice Swap owner in Barz.\n * @dev This can only be done via a Self call.\n * @param _prevOwner Address of owner located right behind the removed owner address in the linked list\n * @param _oldOwner Address of owner to be removed\n * @param _newOwner Address of owner to be added\n */\n function swapOwner(\n address _prevOwner,\n address _oldOwner,\n address _newOwner\n ) public {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (\n _newOwner == address(0) ||\n _newOwner == SENTINEL_OWNERS ||\n _newOwner == address(this)\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_newOwner] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n if (_oldOwner == address(0) || _oldOwner == SENTINEL_OWNERS)\n revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_prevOwner] != _oldOwner)\n revert MultiSigFacet__InvalidOwnerPair();\n\n ms.owners[_newOwner] = ms.owners[_oldOwner];\n ms.owners[_prevOwner] = _newOwner;\n ms.owners[_oldOwner] = address(0);\n emit OwnerRemoved(_oldOwner);\n emit OwnerAdded(_newOwner);\n }\n\n /**\n * @notice Changes the threshold of the Barz to `_threshold`.\n * @dev This can only be done via a Self call.\n * @param _threshold New threshold\n */\n function changeThreshold(uint256 _threshold) public {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (_threshold > ms.ownerCount || _threshold == 0)\n revert MultiSigFacet__InvalidThreshold();\n\n ms.threshold = _threshold;\n emit ThresholdChanged(_threshold);\n }\n\n /**\n * @notice Checks if the given address is owner\n * @param _owner Address to be checked if it's owner\n * @return isOwner_ Bool value showing if it's owner address\n */\n function isOwner(address _owner) public view returns (bool isOwner_) {\n isOwner_ = (_owner != SENTINEL_OWNERS &&\n LibMultiSigStorage.multisigStorage().owners[_owner] != address(0));\n }\n\n /**\n * @notice Returns the threshold of Barz\n * @return threshold Threshold of the Barz account\n */\n function getThreshold() public view returns (uint256 threshold) {\n threshold = LibMultiSigStorage.multisigStorage().threshold;\n }\n\n /**\n * @notice Returns the list of owner addresses\n * @return owners List of owners\n */\n function getOwners() public view returns (address[] memory owners) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n owners = new address[](ms.ownerCount);\n\n uint256 index;\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n while (currentOwner != SENTINEL_OWNERS) {\n owners[index] = currentOwner;\n currentOwner = ms.owners[currentOwner];\n index++;\n }\n }\n\n /**\n * @notice Returns the previous owner in the linked list\n * @param _owner Address of owner\n * @return prevOwner Address of previous owner\n */\n function getPrevOwner(\n address _owner\n ) public view returns (address prevOwner) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n if (currentOwner == _owner) return SENTINEL_OWNERS;\n while (currentOwner != SENTINEL_OWNERS) {\n if (ms.owners[currentOwner] == _owner) return currentOwner;\n\n currentOwner = ms.owners[currentOwner];\n }\n return address(0);\n }\n\n /**\n * @notice Returns of the owner is approved by given owner address\n * @param _owner Address of owner\n * @param _hash Hash of UserOperation\n * @return isApproved Bool value showing if the hash is approved by owner\n */\n function isApprovedHash(\n address _owner,\n bytes32 _hash\n ) public view returns (bool isApproved) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n isApproved = (ms.approvedHashes[ms.counter][_owner][_hash] == 1);\n }\n}\n" + }, + "contracts/facets/verification/secp256k1/Secp256k1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {UserOperation} from \"../../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibAppStorage} from \"../../../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, Secp256k1VerificationStorage} from \"../../../libraries/LibFacetStorage.sol\";\nimport {LibLoupe} from \"../../../libraries/LibLoupe.sol\";\nimport {IERC1271} from \"../../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../../interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Secp256k1 verification facet\n * @dev Default Ethereum's elliptic curve\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract Secp256k1VerificationFacet is IVerificationFacet, IERC1271 {\n using ECDSA for bytes32;\n error Secp256k1VerificationFacet__InvalidSignerLength();\n address public immutable self;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in K1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\n * @param _publicKey Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _publicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n if (!isValidKeyType(_publicKey))\n revert Secp256k1VerificationFacet__InvalidSignerLength();\n\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(uint160(uint256(keccak256(_publicKey[1:]))));\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_publicKey);\n }\n\n /**\n * @notice Uninitialize signer in K1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\n * signer public key.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n validationData = validateSignature(\n userOp,\n userOpHash,\n k1Storage.signer\n );\n }\n\n /**\n * @notice Validates if the signature of UserOperation is signed by the given signer\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @param signer Address of signer who signed the contract, to be validated\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n address signer\n ) public pure returns (uint256 isValid) {\n bytes32 hash = userOpHash.toEthSignedMessageHash();\n isValid = (signer != hash.recover(userOp.signature)) ? 1 : 0;\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n ownerSignatureValidatorSelector = this.validateOwnerSignature.selector;\n // NOTE: The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory signer) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n signer = abi.encodePacked(k1Storage.signer);\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key length should be 65 in an uncompressed public key format\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (_hash.recover(_signature) ==\n LibFacetStorage.k1Storage().signer)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/Secp256r1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {UserOperation} from \"../../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibAppStorage} from \"../../../libraries/LibAppStorage.sol\";\nimport {LibLoupe} from \"../../../libraries/LibLoupe.sol\";\nimport {LibFacetStorage, Secp256r1VerificationStorage} from \"../../../libraries/LibFacetStorage.sol\";\nimport {Base64} from \"./utils/Base64.sol\";\nimport {LibSecp256r1} from \"./utils/LibSecp256r1.sol\";\nimport {IERC1271} from \"../../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../../interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Secp256r1 verification facet\n * @dev Primarily used to verify user ops signed with passkeys\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract Secp256r1VerificationFacet is IVerificationFacet, IERC1271 {\n error Secp256r1VerificationFacet__InvalidSignerLength();\n address public immutable self;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in R1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\n * @param _publicKey Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _publicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n\n if (!isValidKeyType(_publicKey))\n revert Secp256r1VerificationFacet__InvalidSignerLength();\n\n bytes memory publicKeyCoordinates = _publicKey[1:];\n uint256[2] memory q;\n assembly {\n // Copy the bytes from the input data into the uint256 array\n mstore(q, mload(add(publicKeyCoordinates, 32)))\n mstore(add(q, 32), mload(add(publicKeyCoordinates, 64)))\n }\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n r1Storage.q = q;\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_publicKey);\n }\n\n /**\n * @notice Uninitialize signer in R1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n r1Storage.q = [0, 0];\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\n * signer public key.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n validationData = validateSignature(userOp, userOpHash, r1Storage.q);\n }\n\n /**\n * @notice Validates if the signature of UserOperation is signed by the given signer\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @param q Public Key of signer who signed the contract, to be validated\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256[2] memory q\n ) public view returns (uint256 isValid) {\n isValid = (_validateSignature(q, userOpHash, userOp.signature)) ? 0 : 1;\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n return this.validateOwnerSignature.selector; // validateOwnerSignature(UserOperation calldata userOp,bytes32 userOpHash)\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory signer) {\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n signer = abi.encodePacked(r1Storage.q);\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key should in an uncompressed public key format\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = _validateSignature(\n LibFacetStorage.r1Storage().q,\n _hash,\n _signature\n )\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n\n function _validateSignature(\n uint256[2] memory q,\n bytes32 _hash,\n bytes memory _signature\n ) internal view returns (bool) {\n (\n uint256 rValue,\n uint256 sValue,\n bytes memory authenticatorData,\n string memory clientDataJSONPre,\n string memory clientDataJSONPost\n ) = abi.decode(_signature, (uint256, uint256, bytes, string, string));\n bytes32 clientHash;\n {\n string memory opHashBase64 = Base64.encode(bytes.concat(_hash));\n string memory clientDataJSON = string.concat(\n clientDataJSONPre,\n opHashBase64,\n clientDataJSONPost\n );\n clientHash = sha256(bytes(clientDataJSON));\n }\n bytes32 sigHash = sha256(bytes.concat(authenticatorData, clientHash));\n return LibSecp256r1.Verify(q, rValue, sValue, uint256(sigHash));\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/utils/Base64.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @dev Provides a set of functions to operate with Base64 strings.\n * modified for base64url https://datatracker.ietf.org/doc/html/rfc4648#section-5\n * _Available since v4.5._\n */\nlibrary Base64 {\n /**\n * @dev Base64 Encoding/Decoding Table\n */\n string internal constant _TABLE =\n \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_\";\n\n /**\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\n */\n function encode(bytes memory data) internal pure returns (string memory) {\n /**\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\n */\n if (data.length == 0) return \"\";\n\n // Loads the table into memory\n string memory table = _TABLE;\n\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\n // and split into 4 numbers of 6 bits.\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\n // - `data.length + 2` -> Round up\n // - `/ 3` -> Number of 3-bytes chunks\n // - `4 *` -> 4 characters for each chunk\n uint256 newlength = (data.length * 8) / 6;\n if (data.length % 6 > 0) {\n newlength++;\n }\n string memory result = new string(newlength);\n\n /// @solidity memory-safe-assembly\n assembly {\n // Prepare the lookup table (skip the first \"length\" byte)\n let tablePtr := add(table, 1)\n\n // Prepare result pointer, jump over length\n let resultPtr := add(result, 32)\n\n // Run over the input, 3 bytes at a time\n for {\n let dataPtr := data\n let endPtr := add(data, mload(data))\n } lt(dataPtr, endPtr) {\n\n } {\n // Advance 3 bytes\n dataPtr := add(dataPtr, 3)\n let input := mload(dataPtr)\n\n // To write each character, shift the 3 bytes (18 bits) chunk\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\n // and apply logical AND with 0x3F which is the number of\n // the previous character in the ASCII table prior to the Base64 Table\n // The result is then added to the table to get the character to write,\n // and finally write it in the result pointer but with a left shift\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(18, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(12, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(6, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n }\n }\n\n return result;\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/utils/LibSecp256r1.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n// Heavily inspired from\n// https://github.com/maxrobot/elliptic-solidity/blob/master/contracts/Secp256r1.sol\n// https://github.com/tdrerup/elliptic-curve-solidity/blob/master/contracts/curves/EllipticCurve.sol\n// modified to use precompile 0x05 modexp\n// and modified jacobian double\n// optimisations to avoid to an from from affine and jacobian coordinates\n\n// Additional Elliptic curve Public key / Signature validation added by\n// David Yonjun Kim (@Powerstream3604)\n\nstruct JPoint {\n uint256 x;\n uint256 y;\n uint256 z;\n}\n\nlibrary LibSecp256r1 {\n uint256 constant gx =\n 0x6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296;\n uint256 constant gy =\n 0x4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5;\n uint256 public constant pp =\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF;\n\n uint256 public constant nn =\n 0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551;\n uint256 constant a =\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC;\n uint256 constant b =\n 0x5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B;\n uint256 constant MOST_SIGNIFICANT =\n 0xc000000000000000000000000000000000000000000000000000000000000000;\n\n /*\n * Verify\n * @description - verifies that a public key has signed a given message\n * @param Q - public key coordinates X & Y\n * @param R - signature half R\n * @param S - signature half S\n * @param input - hashed message\n */\n function Verify(\n uint256[2] memory q,\n uint r,\n uint s,\n uint e\n ) internal view returns (bool) {\n if (q[0] > pp - 1 || q[1] > pp - 1) {\n return false;\n }\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\n return false;\n }\n if (\n mulmod(q[1], q[1], pp) !=\n addmod(\n addmod(\n mulmod(q[0], mulmod(q[0], q[0], pp), pp),\n mulmod(a, q[0], pp),\n pp\n ),\n b,\n pp\n )\n ) {\n return false;\n }\n\n JPoint[16] memory points = _preComputeJacobianPoints(q);\n return VerifyWithPrecompute(points, r, s, e);\n }\n\n function VerifyWithPrecompute(\n JPoint[16] memory points,\n uint r,\n uint s,\n uint e\n ) internal view returns (bool) {\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\n return false;\n }\n\n uint w = _primemod(s, nn);\n\n uint u1 = mulmod(e, w, nn);\n uint u2 = mulmod(r, w, nn);\n\n uint x;\n uint y;\n\n (x, y) = ShamirMultJacobian(points, u1, u2);\n return (x == r);\n }\n\n /*\n * Strauss Shamir trick for EC multiplication\n * https://stackoverflow.com/questions/50993471/ec-scalar-multiplication-with-strauss-shamir-method\n * we optimise on this a bit to do with 2 bits at a time rather than a single bit\n * the individual points for a single pass are precomputed\n * overall this reduces the number of additions while keeping the same number of doublings\n */\n function ShamirMultJacobian(\n JPoint[16] memory points,\n uint u1,\n uint u2\n ) internal view returns (uint, uint) {\n uint x = 0;\n uint y = 0;\n uint z = 0;\n uint bits = 128;\n uint index = 0;\n\n while (bits > 0) {\n if (z > 0) {\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\n }\n index =\n ((u1 & MOST_SIGNIFICANT) >> 252) |\n ((u2 & MOST_SIGNIFICANT) >> 254);\n if (index > 0) {\n (x, y, z) = _jAdd(\n x,\n y,\n z,\n points[index].x,\n points[index].y,\n points[index].z\n );\n }\n u1 <<= 2;\n u2 <<= 2;\n bits--;\n }\n (x, y) = _affineFromJacobian(x, y, z);\n return (x, y);\n }\n\n function _preComputeJacobianPoints(\n uint256[2] memory q\n ) internal pure returns (JPoint[16] memory points) {\n points[0] = JPoint(0, 0, 0);\n points[1] = JPoint(q[0], q[1], 1); // u2\n points[2] = _jPointDouble(points[1]);\n points[3] = _jPointAdd(points[1], points[2]);\n\n points[4] = JPoint(gx, gy, 1); // u1Points[1]\n points[5] = _jPointAdd(points[4], points[1]);\n points[6] = _jPointAdd(points[4], points[2]);\n points[7] = _jPointAdd(points[4], points[3]);\n\n points[8] = _jPointDouble(points[4]); // u1Points[2]\n points[9] = _jPointAdd(points[8], points[1]);\n points[10] = _jPointAdd(points[8], points[2]);\n points[11] = _jPointAdd(points[8], points[3]);\n\n points[12] = _jPointAdd(points[4], points[8]); // u1Points[3]\n points[13] = _jPointAdd(points[12], points[1]);\n points[14] = _jPointAdd(points[12], points[2]);\n points[15] = _jPointAdd(points[12], points[3]);\n }\n\n function _jPointAdd(\n JPoint memory p1,\n JPoint memory p2\n ) internal pure returns (JPoint memory) {\n uint x;\n uint y;\n uint z;\n (x, y, z) = _jAdd(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z);\n return JPoint(x, y, z);\n }\n\n function _jPointDouble(\n JPoint memory p\n ) internal pure returns (JPoint memory) {\n uint x;\n uint y;\n uint z;\n (x, y, z) = _modifiedJacobianDouble(p.x, p.y, p.z);\n return JPoint(x, y, z);\n }\n\n /* _affineFromJacobian\n * @desription returns affine coordinates from a jacobian input follows\n * golang elliptic/crypto library\n */\n function _affineFromJacobian(\n uint x,\n uint y,\n uint z\n ) internal view returns (uint ax, uint ay) {\n if (z == 0) {\n return (0, 0);\n }\n\n uint zinv = _primemod(z, pp);\n uint zinvsq = mulmod(zinv, zinv, pp);\n\n ax = mulmod(x, zinvsq, pp);\n ay = mulmod(y, mulmod(zinvsq, zinv, pp), pp);\n }\n\n /*\n * _jAdd\n * @description performs Jacobian addition as defined below:\n * http://www.hyperelliptic.org/EFD/g1p/data/shortw/jacobian/addition/add-2007-bl\n */\n function _jAdd(\n uint p1,\n uint p2,\n uint p3,\n uint q1,\n uint q2,\n uint q3\n ) internal pure returns (uint r1, uint r2, uint r3) {\n if (p3 == 0) {\n r1 = q1;\n r2 = q2;\n r3 = q3;\n\n return (r1, r2, r3);\n } else if (q3 == 0) {\n r1 = p1;\n r2 = p2;\n r3 = p3;\n\n return (r1, r2, r3);\n }\n\n assembly {\n let\n pd\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\n let z1z1 := mulmod(p3, p3, pd) // Z1Z1 = Z1^2\n let z2z2 := mulmod(q3, q3, pd) // Z2Z2 = Z2^2\n\n let u1 := mulmod(p1, z2z2, pd) // U1 = X1*Z2Z2\n let u2 := mulmod(q1, z1z1, pd) // U2 = X2*Z1Z1\n\n let s1 := mulmod(p2, mulmod(z2z2, q3, pd), pd) // S1 = Y1*Z2*Z2Z2\n let s2 := mulmod(q2, mulmod(z1z1, p3, pd), pd) // S2 = Y2*Z1*Z1Z1\n\n let p3q3 := addmod(p3, q3, pd)\n\n if lt(u2, u1) {\n u2 := add(pd, u2) // u2 = u2+pd\n }\n let h := sub(u2, u1) // H = U2-U1\n\n let i := mulmod(0x02, h, pd)\n i := mulmod(i, i, pd) // I = (2*H)^2\n\n let j := mulmod(h, i, pd) // J = H*I\n if lt(s2, s1) {\n s2 := add(pd, s2) // u2 = u2+pd\n }\n let rr := mulmod(0x02, sub(s2, s1), pd) // r = 2*(S2-S1)\n r1 := mulmod(rr, rr, pd) // X3 = R^2\n\n let v := mulmod(u1, i, pd) // V = U1*I\n let j2v := addmod(j, mulmod(0x02, v, pd), pd)\n if lt(r1, j2v) {\n r1 := add(pd, r1) // X3 = X3+pd\n }\n r1 := sub(r1, j2v)\n\n // Y3 = r*(V-X3)-2*S1*J\n let s12j := mulmod(mulmod(0x02, s1, pd), j, pd)\n\n if lt(v, r1) {\n v := add(pd, v)\n }\n r2 := mulmod(rr, sub(v, r1), pd)\n\n if lt(r2, s12j) {\n r2 := add(pd, r2)\n }\n r2 := sub(r2, s12j)\n\n // Z3 = ((Z1+Z2)^2-Z1Z1-Z2Z2)*H\n z1z1 := addmod(z1z1, z2z2, pd)\n j2v := mulmod(p3q3, p3q3, pd)\n if lt(j2v, z1z1) {\n j2v := add(pd, j2v)\n }\n r3 := mulmod(sub(j2v, z1z1), h, pd)\n }\n return (r1, r2, r3);\n }\n\n // Point doubling on the modified jacobian coordinates\n // http://point-at-infinity.org/ecc/Prime_Curve_Modified_Jacobian_Coordinates.html\n function _modifiedJacobianDouble(\n uint x,\n uint y,\n uint z\n ) internal pure returns (uint x3, uint y3, uint z3) {\n if (y == 0) return (0, 0, 0);\n assembly {\n let\n pd\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\n let z2 := mulmod(z, z, pd)\n let az4 := mulmod(\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC,\n mulmod(z2, z2, pd),\n pd\n )\n let y2 := mulmod(y, y, pd)\n let s := mulmod(0x04, mulmod(x, y2, pd), pd)\n let u := mulmod(0x08, mulmod(y2, y2, pd), pd)\n let m := addmod(mulmod(0x03, mulmod(x, x, pd), pd), az4, pd)\n let twos := mulmod(0x02, s, pd)\n let m2 := mulmod(m, m, pd)\n if lt(m2, twos) {\n m2 := add(pd, m2)\n }\n x3 := sub(m2, twos)\n if lt(s, x3) {\n s := add(pd, s)\n }\n y3 := mulmod(m, sub(s, x3), pd)\n if lt(y3, u) {\n y3 := add(pd, y3)\n }\n y3 := sub(y3, u)\n z3 := mulmod(0x02, mulmod(y, z, pd), pd)\n }\n }\n\n // Fermats little theorem https://en.wikipedia.org/wiki/Fermat%27s_little_theorem\n // a^(p-1) = 1 mod p\n // a^(-1) ≅ a^(p-2) (mod p)\n // we then use the precompile bigModExp to compute a^(-1)\n function _primemod(uint value, uint p) internal view returns (uint ret) {\n ret = modexp(value, p - 2, p);\n return ret;\n }\n\n // Wrapper for built-in BigNumber_modexp (contract 0x5) as described here. https://github.com/ethereum/EIPs/pull/198\n function modexp(\n uint _base,\n uint _exp,\n uint _mod\n ) internal view returns (uint ret) {\n // bigModExp(_base, _exp, _mod);\n assembly {\n if gt(_base, _mod) {\n _base := mod(_base, _mod)\n }\n // Free memory pointer is always stored at 0x40\n let freemem := mload(0x40)\n\n mstore(freemem, 0x20)\n mstore(add(freemem, 0x20), 0x20)\n mstore(add(freemem, 0x40), 0x20)\n\n mstore(add(freemem, 0x60), _base)\n mstore(add(freemem, 0x80), _exp)\n mstore(add(freemem, 0xa0), _mod)\n\n let success := staticcall(14000, 0x5, freemem, 0xc0, freemem, 0x20)\n switch success\n case 0 {\n revert(0x0, 0x0)\n }\n default {\n ret := mload(freemem)\n }\n }\n }\n}\n" + }, + "contracts/infrastructure/DefaultFallbackHandler.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC1155Receiver} from \"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\";\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {BaseAccount} from \"../aa-4337/core/BaseAccount.sol\";\nimport {DefaultLibDiamond} from \"../libraries/DefaultLibDiamond.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IAccountFacet} from \"../facets/interfaces/IAccountFacet.sol\";\nimport {IStorageLoupe} from \"../facets/base/interfaces/IStorageLoupe.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IERC677Receiver} from \"../interfaces/ERC/IERC677Receiver.sol\";\nimport {IERC165} from \"../interfaces/ERC/IERC165.sol\";\n\n/**\n * @title DefaultFallbackHandler\n * @dev A default fallback handler for Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DefaultFallbackHandler is IDiamondLoupe {\n /**\n * @notice Sets the middleware diamond for Barz wallet as a fallback handler\n * @dev This contract is also a diamond that holds the default facets to reduce gas cost for wallet activation.\n * Within the constructor this conducts diamond cut to initially setup the diamond. This is a non-upgradeable contract\n * @param _diamondCutFacet Address if diamond cut facet\n * @param _accountFacet Address account facet\n * @param _tokenReceiverFacet Address of token receiver facet\n * @param _diamondLoupeFacet Address of diamond loupe facet\n */\n constructor(\n address _diamondCutFacet,\n address _accountFacet,\n address _tokenReceiverFacet,\n address _diamondLoupeFacet\n ) payable {\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](4);\n bytes4[] memory functionSelectors = new bytes4[](1);\n functionSelectors[0] = IDiamondCut.diamondCut.selector;\n\n bytes4[] memory accountFunctionSelectors = new bytes4[](5);\n accountFunctionSelectors[0] = IAccountFacet.execute.selector;\n accountFunctionSelectors[1] = IAccountFacet.executeBatch.selector;\n accountFunctionSelectors[2] = BaseAccount.validateUserOp.selector;\n accountFunctionSelectors[3] = BaseAccount.getNonce.selector;\n accountFunctionSelectors[4] = BaseAccount.entryPoint.selector;\n\n bytes4[] memory receiverFacetSelectors = new bytes4[](5);\n receiverFacetSelectors[0] = IERC721Receiver.onERC721Received.selector;\n receiverFacetSelectors[1] = IERC1155Receiver.onERC1155Received.selector;\n receiverFacetSelectors[2] = IERC1155Receiver\n .onERC1155BatchReceived\n .selector;\n receiverFacetSelectors[3] = IERC777Recipient.tokensReceived.selector;\n receiverFacetSelectors[4] = IERC677Receiver.onTokenTransfer.selector;\n\n bytes4[] memory loupeFacetSelectors = new bytes4[](9);\n loupeFacetSelectors[0] = IDiamondLoupe.facets.selector;\n loupeFacetSelectors[1] = IDiamondLoupe.facetFunctionSelectors.selector;\n loupeFacetSelectors[2] = IDiamondLoupe.facetAddresses.selector;\n loupeFacetSelectors[3] = IDiamondLoupe.facetAddress.selector;\n loupeFacetSelectors[4] = IERC165.supportsInterface.selector;\n loupeFacetSelectors[5] = IStorageLoupe.facetsFromStorage.selector;\n loupeFacetSelectors[6] = IStorageLoupe\n .facetFunctionSelectorsFromStorage\n .selector;\n loupeFacetSelectors[7] = IStorageLoupe\n .facetAddressesFromStorage\n .selector;\n loupeFacetSelectors[8] = IStorageLoupe.facetAddressFromStorage.selector;\n\n {\n cut[0] = IDiamondCut.FacetCut({\n facetAddress: _diamondCutFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: functionSelectors\n });\n cut[1] = IDiamondCut.FacetCut({\n facetAddress: _accountFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: accountFunctionSelectors\n });\n cut[2] = IDiamondCut.FacetCut({\n facetAddress: _tokenReceiverFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: receiverFacetSelectors\n });\n cut[3] = IDiamondCut.FacetCut({\n facetAddress: _diamondLoupeFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: loupeFacetSelectors\n });\n\n DefaultLibDiamond.diamondCut(cut, address(0), \"\");\n }\n }\n\n /**\n * @notice Returns the facet information of call facets registered to this diamond.\n * @return facets_ The facet struct array including all facet information\n */\n function facets() external view override returns (Facet[] memory facets_) {\n DefaultLibDiamond.DiamondStorage storage ds = DefaultLibDiamond\n .diamondStorage();\n uint256 numFacets = ds.facetAddresses.length;\n facets_ = new Facet[](numFacets);\n for (uint256 i; i < numFacets; ) {\n address facetAddress_ = ds.facetAddresses[i];\n facets_[i].facetAddress = facetAddress_;\n facets_[i].functionSelectors = ds\n .facetFunctionSelectors[facetAddress_]\n .functionSelectors;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Gets all the function selectors provided by a facet.\n * @param _facet The facet address.\n * @return facetFunctionSelectors_\n */\n function facetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n facetFunctionSelectors_ = DefaultLibDiamond\n .diamondStorage()\n .facetFunctionSelectors[_facet]\n .functionSelectors;\n }\n\n /**\n * @notice Get all the facet addresses used by a diamond.\n * @return facetAddresses_\n */\n function facetAddresses()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n facetAddresses_ = DefaultLibDiamond.diamondStorage().facetAddresses;\n }\n\n /** @notice Gets the facet that supports the given selector.\n * @dev If facet is not found return address(0).\n * @param _functionSelector The function selector.\n * @return facetAddress_ The facet address.\n */\n function facetAddress(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n facetAddress_ = DefaultLibDiamond\n .diamondStorage()\n .selectorToFacetAndPosition[_functionSelector]\n .facetAddress;\n }\n}\n" + }, + "contracts/infrastructure/FacetRegistry.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport {IFacetRegistry} from \"./interfaces/IFacetRegistry.sol\";\n\n/**\n * @title Facet Registry\n * @dev Contract to keep track of facets & function selectors addable to user wallets\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract FacetRegistry is IFacetRegistry, Ownable2Step {\n mapping(address => FacetRegistryConfig) private facets;\n\n /**\n * @notice Transfers the ownership of the contract to the given owner\n * @param _owner Address of owner who has access to initialize the default security variables for security manager\n */\n constructor(address _owner) {\n transferOwnership(_owner);\n _transferOwnership(_owner);\n }\n\n /**\n * @dev Registers a facet and it's function selectors to registry\n * @param _facet address of facet\n * @param _facetSelectors list of function selectors of the facet\n */\n function registerFacetFunctionSelectors(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external override onlyOwner {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n for (uint256 i; i < _facetSelectors.length; ) {\n if (facetConfig.info[_facetSelectors[i]].exists)\n revert FacetRegistry__FacetSelectorAlreadyRegistered();\n\n facetConfig.info[_facetSelectors[i]].exists = true;\n facetConfig.info[_facetSelectors[i]].index = uint128(\n facetConfig.selectors.length\n );\n facetConfig.selectors.push(_facetSelectors[i]);\n unchecked {\n ++i;\n }\n }\n emit FacetFunctionSelectorsRegistered(_facet, _facetSelectors);\n }\n\n /**\n * @dev Removes a registered facet and it's corresponding selectors from registry\n * @param _facet address of facet\n * @param _facetSelectors list of function selectors of the facet\n */\n function removeFacetFunctionSelectors(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external override onlyOwner {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n for (uint256 i; i < _facetSelectors.length; ) {\n if (!facetConfig.info[_facetSelectors[i]].exists)\n revert FacetRegistry__UnregisteredFacetSelector();\n\n bytes4 lastSelector = facetConfig.selectors[\n facetConfig.selectors.length - 1\n ];\n if (_facetSelectors[i] != lastSelector) {\n uint128 targetIndex = facetConfig\n .info[_facetSelectors[i]]\n .index;\n facetConfig.selectors[targetIndex] = lastSelector;\n facetConfig.info[lastSelector].index = targetIndex;\n }\n facetConfig.selectors.pop();\n delete facetConfig.info[_facetSelectors[i]];\n\n unchecked {\n ++i;\n }\n }\n emit FacetFunctionSelectorsRemoved(_facet, _facetSelectors);\n }\n\n /**\n * @dev Checks if a facet and it's selectors given is registered to facet registry\n * @param _facet Address of facet\n * @param _facetSelectors List of function selectors of the facet\n */\n function areFacetFunctionSelectorsRegistered(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external view override returns (bool) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n if (_facetSelectors.length == 0) return false;\n for (uint256 i; i < _facetSelectors.length; ) {\n if (!facetConfig.info[_facetSelectors[i]].exists) return false;\n unchecked {\n ++i;\n }\n }\n return true;\n }\n\n /**\n * @dev Checks if a facet and it's selector given is registered to facet registry\n * @param _facet Address of facet\n * @param _facetSelector List of function selectors of the facet\n * @return isRegistered Bool value showing if the selector is registered\n */\n function isFacetFunctionSelectorRegistered(\n address _facet,\n bytes4 _facetSelector\n ) external view override returns (bool isRegistered) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n isRegistered = facetConfig.info[_facetSelector].exists;\n }\n\n /**\n * @dev Get the registered selectors of facet from registry\n * @param _facet Address of facet\n * @return selectors Selectors registered to facet\n */\n function getFacetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory selectors) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n selectors = facetConfig.selectors;\n }\n}\n" + }, + "contracts/infrastructure/interfaces/IFacetRegistry.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Registry Interface\n * @dev Interface for Facet Registry contract to keep track of facets & function selectors addable to user wallets\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IFacetRegistry {\n struct FacetRegistryConfig {\n bytes4[] selectors;\n mapping(bytes4 => FacetInfo) info;\n }\n struct FacetInfo {\n bool exists;\n uint128 index;\n }\n\n event FacetFunctionSelectorsRegistered(\n address facet,\n bytes4[] facetSelectors\n );\n event FacetFunctionSelectorsRemoved(address facet, bytes4[] facetSelectors);\n\n error FacetRegistry__FacetSelectorAlreadyRegistered();\n error FacetRegistry__UnregisteredFacetSelector();\n\n function registerFacetFunctionSelectors(\n address facet,\n bytes4[] calldata facetSelectors\n ) external;\n\n function removeFacetFunctionSelectors(\n address facet,\n bytes4[] calldata facetSelectors\n ) external;\n\n function areFacetFunctionSelectorsRegistered(\n address facet,\n bytes4[] calldata facetSelectors\n ) external view returns (bool);\n\n function isFacetFunctionSelectorRegistered(\n address facet,\n bytes4 facetSelector\n ) external view returns (bool);\n\n function getFacetFunctionSelectors(\n address facet\n ) external view returns (bytes4[] memory);\n}\n" + }, + "contracts/infrastructure/interfaces/ISecurityManager.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Registry Interface\n * @dev Infrastructure contract to manage security parameters of users\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface ISecurityManager {\n error SecurityManager__OutOfBoundary();\n error SecurityManager__CallerNotWallet();\n error SecurityManager__AlreadyIntialized();\n\n function initializeAdditionSecurityPeriod(\n uint128 defaultAdditionSecurityPeriod,\n uint128 minAdditionSecurityPeriod,\n uint128 maxAdditionSecurityPeriod\n ) external;\n\n function initializeRemovalSecurityPeriod(\n uint128 defaultRemovalSecurityPeriod,\n uint128 minRemovalSecurityPeriod,\n uint128 maxRemovalSecurityPeriod\n ) external;\n\n function initializeApprovalValidationPeriod(\n uint128 defaultApprovalValidationPeriod,\n uint128 minApprovalValidationPeriod,\n uint128 maxApprovalValidationPeriod\n ) external;\n\n function initializeMigrationPeriod(\n uint128 defaultMigrationPeriod,\n uint128 minMigrationPeriod,\n uint128 maxMigrationPeriod\n ) external;\n\n function initializeLockPeriod(\n uint128 defaultLockPeriod,\n uint128 minLockPeriod,\n uint128 maxLockPeriod\n ) external;\n\n function initializeRecoveryPeriod(\n uint128 defaultRecoveryPeriod,\n uint128 minRecoveryPeriod,\n uint128 maxRecoveryPeriod\n ) external;\n\n function initializeSecurityWindow(\n uint128 defaultSecurityWindow,\n uint128 minSecurityWindow,\n uint128 maxSecurityWindow\n ) external;\n\n function setAdditionSecurityPeriod(\n address wallet,\n uint128 additionSecurityPeriod\n ) external;\n\n function setRemovalSecurityPeriod(\n address wallet,\n uint128 removalSecurityPeriod\n ) external;\n\n function setSecurityWindow(address wallet, uint128 securityWindow) external;\n\n function setRecoveryPeriod(address wallet, uint128 recoveryPeriod) external;\n\n function setLockPeriod(address wallet, uint128 lockPeriod) external;\n\n function setApprovalValidationPeriod(\n address wallet,\n uint128 approvalValidationPeriod\n ) external;\n\n function setMigrationPeriod(\n address wallet,\n uint128 migrationPeriod\n ) external;\n\n function additionSecurityPeriodOf(\n address wallet\n ) external view returns (uint128);\n\n function removalSecurityPeriodOf(\n address wallet\n ) external view returns (uint128);\n\n function securityWindowOf(address wallet) external view returns (uint128);\n\n function recoveryPeriodOf(address wallet) external view returns (uint128);\n\n function lockPeriodOf(address wallet) external view returns (uint128);\n\n function migrationPeriodOf(address wallet) external view returns (uint128);\n\n function approvalValidationPeriodOf(\n address wallet\n ) external view returns (uint128);\n}\n" + }, + "contracts/infrastructure/RemoteStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IGuardianFacet} from \"../facets/interfaces/IGuardianFacet.sol\";\n\n/**\n * @title Remote Storage\n * @dev Remote storage allows you to associate addresses with an array of addresses on a standalone smart contract.\n * This could be useful when you don't want to use the local diamond storage for some purpose.\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\nabstract contract RemoteStorage {\n struct StorageConfig {\n address[] addresses;\n mapping(address => Info) info;\n }\n\n struct Info {\n bool exists;\n uint128 index;\n }\n\n mapping(address => StorageConfig) internal configs;\n\n event Added(address _address);\n event Removed(address _address);\n\n error RemoteStorage__CallerNotOwner();\n error RemoteStorage__CallerNotGuardianOrOwner();\n error RemoteStorage__AlreadyExists();\n error RemoteStorage__NotFound();\n error RemoteStorage__CallerNotGuardian();\n\n bytes4 constant IS_GUARDIAN_SELECTOR =\n bytes4(keccak256(\"isGuardian(address)\"));\n bytes4 constant GUARDIAN_COUNT = bytes4(keccak256(\"guardianCount()\"));\n\n /**\n * @notice Modifier to only allow the self to call. Reverts otherwise\n */\n modifier onlyWallet(address _wallet) {\n if (msg.sender != _wallet) revert RemoteStorage__CallerNotOwner();\n _;\n }\n\n /**\n * @notice Enfore the callet to be wallet of guardian of the wallet\n * @param _wallet Address of wallet\n */\n function enforceGuardianOrWallet(address _wallet) internal view {\n if (msg.sender == _wallet) return;\n address facetAddress = IDiamondLoupe(_wallet).facetAddress(\n IS_GUARDIAN_SELECTOR\n );\n if (facetAddress != address(0))\n if (IGuardianFacet(_wallet).isGuardian(msg.sender)) return;\n revert RemoteStorage__CallerNotGuardianOrOwner();\n }\n\n /**\n * @notice Enforce the caller to be wallet IF guardians doesn't exists and only guardian when guardians exists\n * @param _wallet Target wallet address to be handled by infrastructure contracts\n */\n function enforceWalletOrGuardianIfExists(address _wallet) internal view {\n address facetAddress;\n if (msg.sender == _wallet) {\n facetAddress = IDiamondLoupe(_wallet).facetAddress(GUARDIAN_COUNT);\n if (facetAddress == address(0)) return;\n uint256 guardianCount = IGuardianFacet(_wallet).guardianCount();\n if (guardianCount != 0) revert RemoteStorage__CallerNotGuardian();\n return;\n }\n facetAddress = IDiamondLoupe(_wallet).facetAddress(\n IS_GUARDIAN_SELECTOR\n );\n if (facetAddress != address(0))\n if (IGuardianFacet(_wallet).isGuardian(msg.sender)) return;\n\n revert RemoteStorage__CallerNotGuardianOrOwner();\n }\n\n /**\n * @notice Add address to storage and reverts if the address already exists.\n * This is an internal function callable from contracts that inherit this abstract contract\n * @param _wallet Address of wallet to add the address\n * @param _address Address to be added to wallet\n */\n function addAddress(address _wallet, address _address) internal {\n StorageConfig storage config = configs[_wallet];\n if (config.info[_address].exists) revert RemoteStorage__AlreadyExists();\n\n config.info[_address].exists = true;\n config.info[_address].index = uint128(config.addresses.length);\n config.addresses.push(_address);\n\n emit Added(_address);\n }\n\n /**\n * @notice Remove address from storage and reverts if the address already exists.\n * This is an internal function callable from contracts that inherit this abstract contract\n * @param _wallet Address of wallet to remove the address\n * @param _address Address to be removed from wallet\n */\n function removeAddress(address _wallet, address _address) internal {\n StorageConfig storage config = configs[_wallet];\n if (!config.info[_address].exists) revert RemoteStorage__NotFound();\n\n address lastAddress = config.addresses[config.addresses.length - 1];\n if (_address != lastAddress) {\n uint128 targetIndex = config.info[_address].index;\n config.addresses[targetIndex] = lastAddress;\n config.info[lastAddress].index = targetIndex;\n }\n config.addresses.pop();\n delete config.info[_address];\n\n emit Removed(_address);\n }\n\n /**\n * @notice Returns the address added to the given wallet\n * @param _wallet Address of wallet to fetch the addresses added to it\n * @return addresses List of addresses added to the wallet\n */\n function getAddresses(\n address _wallet\n ) internal view returns (address[] memory addresses) {\n StorageConfig storage config = configs[_wallet];\n addresses = new address[](config.addresses.length);\n uint addressesLen = config.addresses.length;\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns bool value checking if the address exists in the given wallet address\n * @param _wallet Wallet address to check\n * @param _address Address to fetch if the address if added to given wallet\n * @return exists_ Bool value showing if the address exists in wallet\n */\n function exists(\n address _wallet,\n address _address\n ) internal view returns (bool exists_) {\n exists_ = configs[_wallet].info[_address].exists;\n }\n\n /**\n * @notice Returns the number of addresses added to the wallet\n * @param _wallet Address of wallet to check\n * @return count_ Number of addresses added to wallet\n */\n function count(address _wallet) internal view returns (uint256 count_) {\n count_ = configs[_wallet].addresses.length;\n }\n}\n" + }, + "contracts/infrastructure/SecurityManager.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport {ISecurityManager} from \"./interfaces/ISecurityManager.sol\";\n\n/**\n * @title Security Manager\n * @dev Infrastructure contract to manage security parameters of users\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract SecurityManager is ISecurityManager, Ownable2Step {\n uint128 public minAdditionSecurityPeriod;\n uint128 public maxAdditionSecurityPeriod;\n uint128 private defaultAdditionSecurityPeriod;\n\n uint128 public minRemovalSecurityPeriod;\n uint128 public maxRemovalSecurityPeriod;\n uint128 private defaultRemovalSecurityPeriod;\n\n uint128 public minSecurityWindow;\n uint128 public maxSecurityWindow;\n uint128 private defaultSecurityWindow;\n\n uint128 public minRecoveryPeriod;\n uint128 public maxRecoveryPeriod;\n uint128 private defaultRecoveryPeriod;\n\n uint128 public minLockPeriod;\n uint128 public maxLockPeriod;\n uint128 private defaultLockPeriod;\n\n uint128 public minApprovalValidationPeriod;\n uint128 public maxApprovalValidationPeriod;\n uint128 private defaultApprovalValidationPeriod;\n\n uint128 public minMigrationPeriod;\n uint128 public maxMigrationPeriod;\n uint128 private defaultMigrationPeriod;\n\n bool public _isAdditionSecurityPeriodInitialized;\n bool public _isRemovalSecurityPeriodInitialized;\n bool public _isSecurityWindowInitialized;\n bool public _isRecoveryPeriodInitialized;\n bool public _isLockPeriodInitialized;\n bool public _isApprovalValidationPeriodInitialized;\n bool public _isMigrationPeriodInitialized;\n\n mapping(address => CustomSecurityConfig) securityConfigs;\n\n struct CustomSecurityConfig {\n uint128 additionSecurityPeriod;\n uint128 removalSecurityPeriod;\n uint128 securityWindow;\n uint128 recoveryPeriod;\n uint128 lockPeriod;\n uint128 approvalValidationPeriod;\n uint128 migrationPeriod;\n }\n\n /**\n * @notice Modifier to only allow wallet itself to make a call to wallet\n */\n modifier onlyWallet(address _wallet) {\n if (msg.sender != _wallet) revert SecurityManager__CallerNotWallet();\n _;\n }\n\n /**\n * @notice Modifier to revert if the variable is already initialized\n */\n modifier initializer(bool _isInitialized) {\n if (_isInitialized) revert SecurityManager__AlreadyIntialized();\n _;\n }\n\n /**\n * @notice Transfers the ownership of the contract to the given owner\n * @param _owner Address of owner who has access to initialize the default security variables for security manager\n */\n constructor(address _owner) {\n transferOwnership(_owner);\n _transferOwnership(_owner);\n }\n\n /**\n * @notice Sets the initial default/min/max addition security period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultAdditionSecurityPeriod Default Addition Security Period for all Barz contracts\n * @param _minAdditionSecurityPeriod Minimum Addition Security Period for all Barz contracts\n * @param _maxAdditionSecurityPeriod Maximum Addition Security Period for all Barz contracts\n */\n function initializeAdditionSecurityPeriod(\n uint128 _defaultAdditionSecurityPeriod,\n uint128 _minAdditionSecurityPeriod,\n uint128 _maxAdditionSecurityPeriod\n )\n external\n override\n onlyOwner\n initializer(_isAdditionSecurityPeriodInitialized)\n {\n _isAdditionSecurityPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultAdditionSecurityPeriod,\n _minAdditionSecurityPeriod,\n _maxAdditionSecurityPeriod\n );\n defaultAdditionSecurityPeriod = _defaultAdditionSecurityPeriod;\n minAdditionSecurityPeriod = _minAdditionSecurityPeriod;\n maxAdditionSecurityPeriod = _maxAdditionSecurityPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max removal security period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultRemovalSecurityPeriod Default Removal Security Period for all Barz contracts\n * @param _minRemovalSecurityPeriod Minimum Removal Security Period for all Barz contracts\n * @param _maxRemovalSecurityPeriod Maximum Removal Security Period for all Barz contracts\n */\n function initializeRemovalSecurityPeriod(\n uint128 _defaultRemovalSecurityPeriod,\n uint128 _minRemovalSecurityPeriod,\n uint128 _maxRemovalSecurityPeriod\n )\n external\n override\n onlyOwner\n initializer(_isRemovalSecurityPeriodInitialized)\n {\n _isRemovalSecurityPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultRemovalSecurityPeriod,\n _minRemovalSecurityPeriod,\n _maxRemovalSecurityPeriod\n );\n defaultRemovalSecurityPeriod = _defaultRemovalSecurityPeriod;\n minRemovalSecurityPeriod = _minRemovalSecurityPeriod;\n maxRemovalSecurityPeriod = _maxRemovalSecurityPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/maxd security window for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultSecurityWindow Default Security Window for all Barz contracts\n * @param _minSecurityWindow Minimum Security Window for all Barz contracts\n * @param _maxSecurityWindow Maximum Security Window for all Barz contracts\n */\n function initializeSecurityWindow(\n uint128 _defaultSecurityWindow,\n uint128 _minSecurityWindow,\n uint128 _maxSecurityWindow\n ) external override onlyOwner initializer(_isSecurityWindowInitialized) {\n _isSecurityWindowInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultSecurityWindow,\n _minSecurityWindow,\n _maxSecurityWindow\n );\n defaultSecurityWindow = _defaultSecurityWindow;\n minSecurityWindow = _minSecurityWindow;\n maxSecurityWindow = _maxSecurityWindow;\n }\n\n /**\n * @notice Sets the initial default/min/max recovery period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultRecoveryPeriod Default Recovery Period for all Barz contracts\n * @param _minRecoveryPeriod Minimum Recovery Period for all Barz contracts\n * @param _maxRecoveryPeriod Maximum Recovery Period for all Barz contracts\n */\n function initializeRecoveryPeriod(\n uint128 _defaultRecoveryPeriod,\n uint128 _minRecoveryPeriod,\n uint128 _maxRecoveryPeriod\n ) external override onlyOwner initializer(_isRecoveryPeriodInitialized) {\n _isRecoveryPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultRecoveryPeriod,\n _minRecoveryPeriod,\n _maxRecoveryPeriod\n );\n defaultRecoveryPeriod = _defaultRecoveryPeriod;\n minRecoveryPeriod = _minRecoveryPeriod;\n maxRecoveryPeriod = _maxRecoveryPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max lock period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultLockPeriod Default Lock Period for all Barz contracts\n * @param _minLockPeriod Minimum Lock Period for all Barz contracts\n * @param _maxLockPeriod Maximum Lock Period for all Barz contracts\n */\n function initializeLockPeriod(\n uint128 _defaultLockPeriod,\n uint128 _minLockPeriod,\n uint128 _maxLockPeriod\n ) external override onlyOwner initializer(_isLockPeriodInitialized) {\n _isLockPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultLockPeriod,\n _minLockPeriod,\n _maxLockPeriod\n );\n defaultLockPeriod = _defaultLockPeriod;\n minLockPeriod = _minLockPeriod;\n maxLockPeriod = _maxLockPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max approval validation period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultApprovalValidationPeriod Default Approval Validation Period for all Barz contracts\n * @param _minApprovalValidationPeriod Minimum Approval Validation Period for all Barz contracts\n * @param _maxApprovalValidationPeriod Maximum Approval Validation Period for all Barz contracts\n */\n function initializeApprovalValidationPeriod(\n uint128 _defaultApprovalValidationPeriod,\n uint128 _minApprovalValidationPeriod,\n uint128 _maxApprovalValidationPeriod\n )\n external\n override\n onlyOwner\n initializer(_isApprovalValidationPeriodInitialized)\n {\n _isApprovalValidationPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultApprovalValidationPeriod,\n _minApprovalValidationPeriod,\n _maxApprovalValidationPeriod\n );\n defaultApprovalValidationPeriod = _defaultApprovalValidationPeriod;\n minApprovalValidationPeriod = _minApprovalValidationPeriod;\n maxApprovalValidationPeriod = _maxApprovalValidationPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max migration period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultMigrationPeriod Default Migration Period for all Barz contracts\n * @param _minMigrationPeriod Minimum Migration Period for all Barz contracts\n * @param _maxMigrationPeriod Maximum Migration Period for all Barz contracts\n */\n function initializeMigrationPeriod(\n uint128 _defaultMigrationPeriod,\n uint128 _minMigrationPeriod,\n uint128 _maxMigrationPeriod\n ) external override onlyOwner initializer(_isMigrationPeriodInitialized) {\n _isMigrationPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultMigrationPeriod,\n _minMigrationPeriod,\n _maxMigrationPeriod\n );\n defaultMigrationPeriod = _defaultMigrationPeriod;\n minMigrationPeriod = _minMigrationPeriod;\n maxMigrationPeriod = _maxMigrationPeriod;\n }\n\n /**\n * @notice Wallet owner sets the addition security period for the wallet. Only the owner of wallet can call this function.\n * The addition security period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _additionSecurityPeriod Custom Addition Security Period for the wallet\n */\n function setAdditionSecurityPeriod(\n address _wallet,\n uint128 _additionSecurityPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _additionSecurityPeriod,\n minAdditionSecurityPeriod,\n maxAdditionSecurityPeriod\n );\n securityConfigs[_wallet]\n .additionSecurityPeriod = _additionSecurityPeriod;\n }\n\n /**\n * @notice Wallet owner sets the removal security period for the wallet. Only the owner of wallet can call this function.\n * The removal security period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _removalSecurityPeriod Custom Removal Security Period for the wallet\n */\n function setRemovalSecurityPeriod(\n address _wallet,\n uint128 _removalSecurityPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _removalSecurityPeriod,\n minRemovalSecurityPeriod,\n maxRemovalSecurityPeriod\n );\n securityConfigs[_wallet].removalSecurityPeriod = _removalSecurityPeriod;\n }\n\n /**\n * @notice Wallet owner sets the security window for the wallet. Only the owner of wallet can call this function.\n * The security window should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _securityWindow Custom Security Window for the wallet\n */\n function setSecurityWindow(\n address _wallet,\n uint128 _securityWindow\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _securityWindow,\n minSecurityWindow,\n maxSecurityWindow\n );\n securityConfigs[_wallet].securityWindow = _securityWindow;\n }\n\n /**\n * @notice Wallet owner sets the recovery period for the wallet. Only the owner of wallet can call this function.\n * The recovery period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _recoveryPeriod Custom recovery period for the wallet\n */\n function setRecoveryPeriod(\n address _wallet,\n uint128 _recoveryPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _recoveryPeriod,\n minRecoveryPeriod,\n maxRecoveryPeriod\n );\n securityConfigs[_wallet].recoveryPeriod = _recoveryPeriod;\n }\n\n /**\n * @notice Wallet owner sets the lock period for the wallet. Only the owner of wallet can call this function.\n * The lock period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _lockPeriod Custom Lock period for the wallet\n */\n function setLockPeriod(\n address _wallet,\n uint128 _lockPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(_lockPeriod, minLockPeriod, maxLockPeriod);\n securityConfigs[_wallet].lockPeriod = _lockPeriod;\n }\n\n /**\n * @notice Wallet owner sets the approval validation period for the wallet. Only the owner of wallet can call this function.\n * The approval validation period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _approvalValidationPeriod Custom approval validation period for the wallet\n */\n function setApprovalValidationPeriod(\n address _wallet,\n uint128 _approvalValidationPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _approvalValidationPeriod,\n minApprovalValidationPeriod,\n maxApprovalValidationPeriod\n );\n securityConfigs[_wallet]\n .approvalValidationPeriod = _approvalValidationPeriod;\n }\n\n /**\n * @notice Wallet owner sets the migration period for the wallet. Only the owner of wallet can call this function.\n * The migration period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _migrationPeriod Custom migration period for the wallet\n */\n\n function setMigrationPeriod(\n address _wallet,\n uint128 _migrationPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _migrationPeriod,\n minMigrationPeriod,\n maxMigrationPeriod\n );\n securityConfigs[_wallet].migrationPeriod = _migrationPeriod;\n }\n\n /**\n * @notice Returns the addition security period. Returns default value when custom addition security period is not set\n * @param _wallet Address of wallet\n * @return additionSecurityPeriod Addition Security Period of the given Barz account or wallet\n */\n function additionSecurityPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 additionSecurityPeriod)\n {\n additionSecurityPeriod = securityConfigs[_wallet]\n .additionSecurityPeriod;\n additionSecurityPeriod = (additionSecurityPeriod == 0)\n ? defaultAdditionSecurityPeriod\n : additionSecurityPeriod;\n }\n\n /**\n * @notice Returns the removal security period. Returns default value when custom removal security period is not set\n * @param _wallet Address of wallet\n * @return removalSecurityPeriod Removal Security Period of the given Barz account or wallet\n */\n function removalSecurityPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 removalSecurityPeriod)\n {\n removalSecurityPeriod = securityConfigs[_wallet].removalSecurityPeriod;\n removalSecurityPeriod = (removalSecurityPeriod == 0)\n ? defaultRemovalSecurityPeriod\n : removalSecurityPeriod;\n }\n\n /**\n * @notice Returns the security window. Returns default value when custom security window is not set\n * @param _wallet Address of wallet\n * @return securityWindow Security window of the given Barz account or wallet\n */\n function securityWindowOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 securityWindow)\n {\n securityWindow = securityConfigs[_wallet].securityWindow;\n securityWindow = (securityWindow == 0)\n ? defaultSecurityWindow\n : securityWindow;\n }\n\n /**\n * @notice Returns the recovery period. Returns default value when custom recovery period is not set\n * @param _wallet Address of wallet\n * @return recoveryPeriod Recovery Period of the given Barz account or wallet\n */\n function recoveryPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 recoveryPeriod)\n {\n recoveryPeriod = securityConfigs[_wallet].recoveryPeriod;\n recoveryPeriod = (recoveryPeriod == 0)\n ? defaultRecoveryPeriod\n : recoveryPeriod;\n }\n\n /**\n * @notice Returns the lock period. Returns default value when custom lock period is not set\n * @param _wallet Address of wallet\n * @return lockPeriod Lock Period of the given Barz account or wallet\n */\n function lockPeriodOf(\n address _wallet\n ) public view override onlyWallet(_wallet) returns (uint128 lockPeriod) {\n lockPeriod = securityConfigs[_wallet].lockPeriod;\n lockPeriod = (lockPeriod == 0) ? defaultLockPeriod : lockPeriod;\n }\n\n /**\n * @notice Returns the approval validation period. Returns default value when custom approval validation period is not set\n * @param _wallet Address of wallet\n * @return approvalValidationPeriod Approval Validation Period of the given Barz account or wallet\n */\n function approvalValidationPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityConfigs[_wallet]\n .approvalValidationPeriod;\n approvalValidationPeriod = (approvalValidationPeriod == 0)\n ? defaultApprovalValidationPeriod\n : approvalValidationPeriod;\n }\n\n /**\n * @notice Returns the migration period. Returns default value when custom migration period is not set\n * @param _wallet Address of wallet\n * @return migrationPeriod Migration Period of the given Barz account or wallet\n */\n function migrationPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 migrationPeriod)\n {\n migrationPeriod = securityConfigs[_wallet].migrationPeriod;\n migrationPeriod = (migrationPeriod == 0)\n ? defaultMigrationPeriod\n : migrationPeriod;\n }\n\n /**\n * @notice Validates if the period is smaller than the max period or bigger than the min period\n * @param _period Period to be checked\n * @param _minPeriod Minimum period\n * @param _maxPeriod Maximum period\n */\n function _validatePeriodBoundaries(\n uint128 _period,\n uint128 _minPeriod,\n uint128 _maxPeriod\n ) internal pure {\n if (_period >= _maxPeriod || _period <= _minPeriod)\n revert SecurityManager__OutOfBoundary();\n }\n}\n" + }, + "contracts/infrastructure/WhitelistStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {RemoteStorage} from \"./RemoteStorage.sol\";\n\n/**\n * @title Whitelist storage\n * @dev Maps addresses to the corresponsing array of whitelisted addresses for each of them.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract WhitelistStorage is RemoteStorage {\n /**\n * @dev Add the address to the whitelist storage\n * @param _wallet User wallet\n * @param _address Address to be whitelisted\n */\n function whitelistAddress(address _wallet, address _address) external {\n enforceWalletOrGuardianIfExists(_wallet);\n addAddress(_wallet, _address);\n }\n\n /**\n * @dev Removes the address from the whitelist storage\n * @param _wallet User wallet\n * @param _address Address to be removed from the whitelist\n */\n function blacklistAddress(address _wallet, address _address) external {\n enforceGuardianOrWallet(_wallet);\n removeAddress(_wallet, _address);\n }\n\n /**\n * @dev Returns whether the address exists in the whitelist storage, associated with the wallet\n * @param _wallet User wallet\n * @param _address Address to be whitelisted\n */\n function isWhitelisted(\n address _wallet,\n address _address\n ) external view returns (bool) {\n return exists(_wallet, _address);\n }\n\n /**\n * @dev Returns all whitelisted addresses associated with the wallet\n * @param _wallet User wallet\n */\n function getWhitelistedAddresses(\n address _wallet\n ) external view returns (address[] memory) {\n return getAddresses(_wallet);\n }\n}\n" + }, + "contracts/interfaces/ERC/IERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\n\npragma solidity 0.8.21;\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155Receiver {\n /**\n * @dev Handles the receipt of a single ERC1155 token type. This function is\n * called at the end of a `safeTransferFrom` after the balance has been updated.\n *\n * NOTE: To accept the transfer, this must return\n * `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n * (i.e. 0xf23a6e61, or its own function selector).\n *\n * @param operator The address which initiated the transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param id The ID of the token being transferred\n * @param value The amount of tokens being transferred\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n ) external returns (bytes4);\n\n /**\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\n * is called at the end of a `safeBatchTransferFrom` after the balances have\n * been updated.\n *\n * NOTE: To accept the transfer(s), this must return\n * `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n * (i.e. 0xbc197c81, or its own function selector).\n *\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "contracts/interfaces/ERC/IERC1271.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\ninterface IERC1271 {\n function isValidSignature(\n bytes32 hash,\n bytes memory signature\n ) external view returns (bytes4);\n}\n" + }, + "contracts/interfaces/ERC/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\ninterface IERC165 {\n /// @notice Query if a contract implements an interface\n /// @param interfaceId The interface identifier, as specified in ERC-165\n /// @dev Interface identification is specified in ERC-165. This function\n /// uses less than 30,000 gas.\n /// @return `true` if the contract implements `interfaceID` and\n /// `interfaceID` is not 0xffffffff, `false` otherwise\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/IERC173.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\n/// @title ERC-173 Contract Ownership Standard\n/// Note: the ERC-165 identifier for this interface is 0x7f5828d0\n/* is ERC165 */\ninterface IERC173 {\n /// @dev This emits when ownership of a contract changes.\n event OwnershipTransferred(\n address indexed previousOwner,\n address indexed newOwner\n );\n\n /// @notice Get the address of the owner\n /// @return owner_ The address of the owner.\n function owner() external view returns (address owner_);\n\n /// @notice Set the address of the new owner of the contract\n /// @dev Set _newOwner to address(0) to renounce any ownership.\n /// @param _newOwner The address of the new owner of the contract\n function transferOwnership(address _newOwner) external;\n}\n" + }, + "contracts/interfaces/ERC/IERC677Receiver.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\ninterface IERC677Receiver {\n function onTokenTransfer(\n address sender,\n uint value,\n bytes calldata data\n ) external pure returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155 is IERC165 {\n /**\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n */\n event TransferSingle(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256 id,\n uint256 value\n );\n\n /**\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n * transfers.\n */\n event TransferBatch(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\n\n /**\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n * `approved`.\n */\n event ApprovalForAll(\n address indexed account,\n address indexed operator,\n bool approved\n );\n\n /**\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n *\n * If an {URI} event was emitted for `id`, the standard\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n * returned by {IERC1155MetadataURI-uri}.\n */\n event URI(string value, uint256 indexed id);\n\n /**\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(\n address account,\n uint256 id\n ) external view returns (uint256);\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] calldata accounts,\n uint256[] calldata ids\n ) external view returns (uint256[] memory);\n\n /**\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n *\n * Emits an {ApprovalForAll} event.\n *\n * Requirements:\n *\n * - `operator` cannot be the caller.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n *\n * See {setApprovalForAll}.\n */\n function isApprovedForAll(\n address account,\n address operator\n ) external view returns (bool);\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes calldata data\n ) external;\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(\n address indexed owner,\n address indexed spender,\n uint256 value\n );\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` 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 amount) 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(\n address owner,\n address spender\n ) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the 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 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` 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(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(\n address spender,\n uint256 addedValue\n ) external returns (bool);\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(\n address spender,\n uint256 subtractedValue\n ) external returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(\n address indexed from,\n address indexed to,\n uint256 indexed tokenId\n );\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(\n address indexed owner,\n address indexed approved,\n uint256 indexed tokenId\n );\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(\n address indexed owner,\n address indexed operator,\n bool approved\n );\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(\n uint256 tokenId\n ) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(\n address owner,\n address operator\n ) external view returns (bool);\n}\n" + }, + "contracts/interfaces/IBarz.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Barz Interface\n * @dev Interface of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IBarz {\n error Barz__InitializationFailure();\n}\n" + }, + "contracts/interfaces/IBarzFactory.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Barz} from \"../Barz.sol\";\n\n/**\n * @title Barz Factory Interface\n * @dev Interface of contract to easily deploy Barz to a pre-computed address with a single call\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IBarzFactory {\n event BarzDeployed(address);\n\n function createAccount(\n address verificationFacet,\n bytes calldata owner,\n uint256 salt\n ) external returns (Barz);\n\n function getAddress(\n address verificationFacet,\n bytes calldata owner,\n uint256 salt\n ) external view returns (address);\n\n function getBytecode(\n address accountFacet,\n address verificationFacet,\n address entryPoint,\n address facetRegistry,\n address defaultFallback,\n bytes memory ownerPublicKey\n ) external pure returns (bytes memory);\n\n function getCreationCode() external pure returns (bytes memory);\n}\n" + }, + "contracts/libraries/DefaultLibDiamond.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\n\nerror InitializationFunctionReverted(\n address _initializationContractAddress,\n bytes _calldata\n);\n\nlibrary DefaultLibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION =\n keccak256(\"trustwallet.barz.diamond.storage\");\n\n struct FacetAddressAndPosition {\n address facetAddress;\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\n }\n\n struct FacetFunctionSelectors {\n bytes4[] functionSelectors;\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\n }\n\n struct DiamondStorage {\n // maps function selector to the facet address and\n // the position of the selector in the facetFunctionSelectors.selectors array\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\n // maps facet addresses to function selectors\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\n // facet addresses\n address[] facetAddresses;\n // Used to query if a contract implements an interface.\n // Used to implement ERC-165.\n mapping(bytes4 => bool) supportedInterfaces;\n }\n\n function diamondStorage()\n internal\n pure\n returns (DiamondStorage storage ds)\n {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n event DiamondCut(\n IDiamondCut.FacetCut[] _diamondCut,\n address _init,\n bytes _calldata\n );\n\n // Internal function version of diamondCut\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n for (\n uint256 facetIndex;\n facetIndex < _diamondCut.length;\n facetIndex++\n ) {\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\n if (action == IDiamondCut.FacetCutAction.Add) {\n addFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\n replaceFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\n removeFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else {\n revert(\"LibDiamondCut: Incorrect FacetCutAction\");\n }\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Add facet can't be address(0)\"\n );\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n require(\n oldFacetAddress == address(0),\n \"LibDiamondCut: Can't add function that already exists\"\n );\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function replaceFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Replace facet can't be address(0)\"\n );\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n require(\n oldFacetAddress != _facetAddress,\n \"LibDiamondCut: Can't replace function with same facet\"\n );\n removeFunction(ds, oldFacetAddress, selector);\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function removeFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n // if function does not exist then do nothing and return\n require(\n _facetAddress == address(0),\n \"LibDiamondCut: Remove facet address must be address(0)\"\n );\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n removeFunction(ds, oldFacetAddress, selector);\n }\n }\n\n function addFacet(\n DiamondStorage storage ds,\n address _facetAddress\n ) internal {\n enforceHasContractCode(\n _facetAddress,\n \"LibDiamondCut: New facet has no code\"\n );\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds\n .facetAddresses\n .length;\n ds.facetAddresses.push(_facetAddress);\n }\n\n function addFunction(\n DiamondStorage storage ds,\n bytes4 _selector,\n uint96 _selectorPosition,\n address _facetAddress\n ) internal {\n ds\n .selectorToFacetAndPosition[_selector]\n .functionSelectorPosition = _selectorPosition;\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(\n _selector\n );\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\n }\n\n function removeFunction(\n DiamondStorage storage ds,\n address _facetAddress,\n bytes4 _selector\n ) internal {\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Can't remove function that doesn't exist\"\n );\n // an immutable function is a function defined directly in a diamond\n require(\n _facetAddress != address(this),\n \"LibDiamondCut: Can't remove immutable function\"\n );\n // replace selector with last selector, then delete last selector\n uint256 selectorPosition = ds\n .selectorToFacetAndPosition[_selector]\n .functionSelectorPosition;\n uint256 lastSelectorPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors\n .length - 1;\n // if not the same then replace _selector with lastSelector\n if (selectorPosition != lastSelectorPosition) {\n bytes4 lastSelector = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors[lastSelectorPosition];\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[\n selectorPosition\n ] = lastSelector;\n ds\n .selectorToFacetAndPosition[lastSelector]\n .functionSelectorPosition = uint96(selectorPosition);\n }\n // delete the last selector\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\n delete ds.selectorToFacetAndPosition[_selector];\n\n // if no more selectors for facet address then delete the facet address\n if (lastSelectorPosition == 0) {\n // replace facet address with last facet address and delete last facet address\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\n uint256 facetAddressPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .facetAddressPosition;\n if (facetAddressPosition != lastFacetAddressPosition) {\n address lastFacetAddress = ds.facetAddresses[\n lastFacetAddressPosition\n ];\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\n ds\n .facetFunctionSelectors[lastFacetAddress]\n .facetAddressPosition = facetAddressPosition;\n }\n ds.facetAddresses.pop();\n delete ds\n .facetFunctionSelectors[_facetAddress]\n .facetAddressPosition;\n }\n }\n\n function initializeDiamondCut(\n address _init,\n bytes memory _calldata\n ) internal {\n if (_init == address(0)) {\n return;\n }\n enforceHasContractCode(\n _init,\n \"LibDiamondCut: _init address has no code\"\n );\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length > 0) {\n // bubble up error\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(error)\n revert(add(32, error), returndata_size)\n }\n } else {\n revert InitializationFunctionReverted(_init, _calldata);\n }\n }\n }\n\n function enforceHasContractCode(\n address _contract,\n string memory _errorMessage\n ) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize > 0, _errorMessage);\n }\n}\n" + }, + "contracts/libraries/LibAppStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SafeCast} from \"@openzeppelin/contracts/utils/math/SafeCast.sol\";\nimport {IEntryPoint} from \"../aa-4337/interfaces/IEntryPoint.sol\";\nimport {IFacetRegistry} from \"../infrastructure/interfaces/IFacetRegistry.sol\";\n\n/*\n * @title App Storage\n * @dev App storage for Barz contract to prevent storage collision\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\n\nstruct Lock {\n uint64 release;\n bytes4 locker;\n}\n\nstruct InitializersStorage {\n // NOTE: initialized is a variable to make sure the initialization is only done once.\n uint8 signerInitialized;\n uint8 accountInitialized;\n uint8 restrictionsInitialized;\n}\n\nstruct AppStorage {\n mapping(uint256 => InitializersStorage) initStorage;\n uint8 signerMigration;\n bytes4 validateOwnerSignatureSelector;\n IEntryPoint entryPoint;\n IFacetRegistry facetRegistry;\n mapping(uint256 => Lock) locks;\n}\n\nlibrary LibAppStorage {\n error LibAppStorage__AccountAlreadyUninitialized();\n error LibAppStorage__AccountMustBeUninitialized();\n error LibAppStorage__SignerAlreadyUninitialized();\n error LibAppStorage__SignerMustBeUninitialized();\n\n function appStorage() internal pure returns (AppStorage storage ds) {\n assembly {\n ds.slot := 0\n }\n }\n\n function setSignerUninitialized() internal {\n AppStorage storage s = appStorage();\n if (1 != s.initStorage[0].signerInitialized) {\n revert LibAppStorage__SignerAlreadyUninitialized();\n }\n s.initStorage[0].signerInitialized = 0;\n }\n\n function getValidateOwnerSignatureSelector()\n internal\n view\n returns (bytes4 selector)\n {\n selector = appStorage().validateOwnerSignatureSelector;\n }\n\n function setValidateOwnerSignatureSelector(\n bytes4 _validateOwnerSignatureSelector\n ) internal {\n appStorage()\n .validateOwnerSignatureSelector = _validateOwnerSignatureSelector;\n }\n\n function enforceSignerInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].signerInitialized) {\n revert LibAppStorage__SignerMustBeUninitialized();\n }\n s.initStorage[0].signerInitialized = 1;\n }\n\n function enforceAccountInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].accountInitialized) {\n revert LibAppStorage__AccountMustBeUninitialized();\n }\n s.initStorage[0].accountInitialized = 1;\n }\n\n function initiateSignerMigration() internal {\n appStorage().signerMigration = 1;\n }\n\n function enforceSignerMigration() internal view {\n if (1 != appStorage().signerMigration) {\n revert LibAppStorage__AccountMustBeUninitialized();\n }\n }\n\n function finalizeSignerMigration() internal {\n appStorage().signerMigration = 0;\n }\n\n function setLock(uint256 _releaseAfter, bytes4 _locker) internal {\n appStorage().locks[0] = Lock(SafeCast.toUint64(_releaseAfter), _locker);\n }\n\n function enforceRestrictionsInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].restrictionsInitialized)\n revert LibAppStorage__SignerMustBeUninitialized();\n s.initStorage[0].restrictionsInitialized = 1;\n }\n\n function setRestrictionsUninitialized() internal {\n AppStorage storage s = appStorage();\n if (1 != s.initStorage[0].restrictionsInitialized)\n revert LibAppStorage__AccountAlreadyUninitialized();\n s.initStorage[0].restrictionsInitialized = 0;\n }\n}\n\ncontract BarzStorage {\n AppStorage internal s;\n modifier onlyWhenUnlocked() {\n require(\n uint64(block.timestamp) >= s.locks[0].release,\n \"Account Locked\"\n );\n _;\n }\n modifier onlyWhenLocked() {\n require(\n uint64(block.timestamp) < s.locks[0].release,\n \"Account Unlocked\"\n );\n _;\n }\n}\n" + }, + "contracts/libraries/LibDiamond.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\n\nerror InitializationFunctionReverted(\n address _initializationContractAddress,\n bytes _calldata\n);\n\nlibrary LibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION =\n keccak256(\"trustwallet.barz.diamond.storage\");\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\n bytes4(keccak256(\"verifyRestrictions(address,address,uint256,bytes)\"));\n struct DiamondStorage {\n // maps function selectors to the facets that execute the functions.\n // and maps the selectors to their position in the selectorSlots array.\n // func selector => address facet, selector position\n mapping(bytes4 => bytes32) facets;\n // array of slots of function selectors.\n // each slot holds 8 function selectors.\n mapping(uint256 => bytes32) selectorSlots;\n // The number of function selectors in selectorSlots\n uint16 selectorCount;\n // Used to query if a contract implements an interface.\n // Used to implement ERC-165.\n mapping(bytes4 => bool) supportedInterfaces;\n // Default Fallback Handler of the barz.\n IDiamondLoupe defaultFallbackHandler;\n }\n\n function diamondStorage()\n internal\n pure\n returns (DiamondStorage storage ds)\n {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n function enforceIsSelf() internal view {\n require(msg.sender == address(this), \"LibDiamond: Caller not self\");\n }\n\n event DiamondCut(\n IDiamondCut.FacetCut[] _diamondCut,\n address _init,\n bytes _calldata\n );\n\n bytes32 constant CLEAR_ADDRESS_MASK =\n bytes32(uint256(0xffffffffffffffffffffffff));\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\n\n // Internal function version of diamondCut\n // This code is almost the same as the external diamondCut,\n // except it is using 'Facet[] memory _diamondCut' instead of\n // 'Facet[] calldata _diamondCut'.\n // The code is duplicated to prevent copying calldata to memory which\n // causes an error for a two dimensional array.\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n DiamondStorage storage ds = diamondStorage();\n uint256 originalSelectorCount = ds.selectorCount;\n uint256 selectorCount = originalSelectorCount;\n bytes32 selectorSlot;\n // Check if last selector slot is not full\n // \"selectorCount & 7\" is a gas efficient modulo by eight \"selectorCount % 8\"\n if (selectorCount & 7 > 0) {\n // get last selectorSlot\n // \"selectorSlot >> 3\" is a gas efficient division by 8 \"selectorSlot / 8\"\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\n }\n // loop through diamond cut\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\n selectorCount,\n selectorSlot,\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].action,\n _diamondCut[facetIndex].functionSelectors\n );\n\n unchecked {\n facetIndex++;\n }\n }\n if (selectorCount != originalSelectorCount) {\n ds.selectorCount = uint16(selectorCount);\n }\n // If last selector slot is not full\n // \"selectorCount & 7\" is a gas efficient modulo by eight \"selectorCount % 8\"\n if (selectorCount & 7 > 0) {\n // \"selectorSlot >> 3\" is a gas efficient division by 8 \"selectorSlot / 8\"\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addReplaceRemoveFacetSelectors(\n uint256 _selectorCount,\n bytes32 _selectorSlot,\n address _newFacetAddress,\n IDiamondCut.FacetCutAction _action,\n bytes4[] memory _selectors\n ) internal returns (uint256, bytes32) {\n DiamondStorage storage ds = diamondStorage();\n require(\n _selectors.length > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n if (_action == IDiamondCut.FacetCutAction.Add) {\n enforceHasContractCode(\n _newFacetAddress,\n \"LibDiamondCut: Add facet has no code\"\n );\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n require(\n address(bytes20(oldFacet)) == address(0),\n \"LibDiamondCut: Can't add function that already exists\"\n );\n // add facet for selector\n ds.facets[selector] =\n bytes20(_newFacetAddress) |\n bytes32(_selectorCount);\n // \"_selectorCount & 7\" is a gas efficient modulo by eight \"_selectorCount % 8\"\n // \" << 5 is the same as multiplying by 32 ( * 32)\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\n // clear selector position in slot and add selector\n _selectorSlot =\n (_selectorSlot &\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\n (bytes32(selector) >> selectorInSlotPosition);\n // if slot is full then write it to storage\n if (selectorInSlotPosition == 224) {\n // \"_selectorSlot >> 3\" is a gas efficient division by 8 \"_selectorSlot / 8\"\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\n _selectorSlot = 0;\n }\n _selectorCount++;\n\n unchecked {\n selectorIndex++;\n }\n }\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\n enforceHasContractCode(\n _newFacetAddress,\n \"LibDiamondCut: Replace facet has no code\"\n );\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n address oldFacetAddress = address(bytes20(oldFacet));\n // only useful if immutable functions exist\n require(\n oldFacetAddress != address(this),\n \"LibDiamondCut: Can't replace immutable function\"\n );\n require(\n oldFacetAddress != _newFacetAddress,\n \"LibDiamondCut: Can't replace function with same function\"\n );\n require(\n oldFacetAddress != address(0),\n \"LibDiamondCut: Can't replace function that doesn't exist\"\n );\n // replace old facet address\n ds.facets[selector] =\n (oldFacet & CLEAR_ADDRESS_MASK) |\n bytes20(_newFacetAddress);\n\n unchecked {\n selectorIndex++;\n }\n }\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\n require(\n _newFacetAddress == address(0),\n \"LibDiamondCut: Remove facet address must be address(0)\"\n );\n // \"_selectorCount >> 3\" is a gas efficient division by 8 \"_selectorCount / 8\"\n uint256 selectorSlotCount = _selectorCount >> 3;\n // \"_selectorCount & 7\" is a gas efficient modulo by eight \"_selectorCount % 8\"\n uint256 selectorInSlotIndex = _selectorCount & 7;\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n if (_selectorSlot == 0) {\n // get last selectorSlot\n selectorSlotCount--;\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\n selectorInSlotIndex = 7;\n } else {\n selectorInSlotIndex--;\n }\n bytes4 lastSelector;\n uint256 oldSelectorsSlotCount;\n uint256 oldSelectorInSlotPosition;\n // adding a block here prevents stack too deep error\n {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n require(\n address(bytes20(oldFacet)) != address(0),\n \"LibDiamondCut: Can't remove function that doesn't exist\"\n );\n // only useful if immutable functions exist\n require(\n address(bytes20(oldFacet)) != address(this),\n \"LibDiamondCut: Can't remove immutable function\"\n );\n // replace selector with last selector in ds.facets\n // gets the last selector\n // \" << 5 is the same as multiplying by 32 ( * 32)\n lastSelector = bytes4(\n _selectorSlot << (selectorInSlotIndex << 5)\n );\n if (lastSelector != selector) {\n // update last selector slot position info\n ds.facets[lastSelector] =\n (oldFacet & CLEAR_ADDRESS_MASK) |\n bytes20(ds.facets[lastSelector]);\n }\n delete ds.facets[selector];\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\n // \"oldSelectorCount >> 3\" is a gas efficient division by 8 \"oldSelectorCount / 8\"\n oldSelectorsSlotCount = oldSelectorCount >> 3;\n // \"oldSelectorCount & 7\" is a gas efficient modulo by eight \"oldSelectorCount % 8\"\n // \" << 5 is the same as multiplying by 32 ( * 32)\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\n }\n if (oldSelectorsSlotCount != selectorSlotCount) {\n bytes32 oldSelectorSlot = ds.selectorSlots[\n oldSelectorsSlotCount\n ];\n // clears the selector we are deleting and puts the last selector in its place.\n oldSelectorSlot =\n (oldSelectorSlot &\n ~(CLEAR_SELECTOR_MASK >>\n oldSelectorInSlotPosition)) |\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\n // update storage with the modified slot\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\n } else {\n // clears the selector we are deleting and puts the last selector in its place.\n _selectorSlot =\n (_selectorSlot &\n ~(CLEAR_SELECTOR_MASK >>\n oldSelectorInSlotPosition)) |\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\n }\n if (selectorInSlotIndex == 0) {\n delete ds.selectorSlots[selectorSlotCount];\n _selectorSlot = 0;\n }\n\n unchecked {\n selectorIndex++;\n }\n }\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\n } else {\n revert(\"LibDiamondCut: Incorrect FacetCutAction\");\n }\n return (_selectorCount, _selectorSlot);\n }\n\n function initializeDiamondCut(\n address _init,\n bytes memory _calldata\n ) internal {\n if (_init == address(0)) {\n return;\n }\n enforceHasContractCode(\n _init,\n \"LibDiamondCut: _init address has no code\"\n );\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length > 0) {\n // bubble up error\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(error)\n revert(add(32, error), returndata_size)\n }\n } else {\n revert InitializationFunctionReverted(_init, _calldata);\n }\n }\n }\n\n function enforceHasContractCode(\n address _contract,\n string memory _errorMessage\n ) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize > 0, _errorMessage);\n }\n\n function restrictionsFacet() internal view returns (address facetAddress_) {\n facetAddress_ = address(\n bytes20(\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\n )\n );\n }\n}\n" + }, + "contracts/libraries/LibFacetStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Storage\n * @dev Storage contract to store each facets variables with diamond storage\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\n\nstruct Secp256k1VerificationStorage {\n address signer;\n}\n\nstruct Secp256r1VerificationStorage {\n uint256[2] q;\n}\n\nstruct GuardianStorage {\n mapping(bytes32 => uint256) pending;\n mapping(uint8 => StorageConfig) configs;\n}\n\nstruct Info {\n bool exists;\n uint128 index;\n}\n\nstruct StorageConfig {\n address[] addresses;\n mapping(address => Info) info;\n}\n\nstruct RecoveryConfig {\n bytes recoveryPublicKey;\n uint64 executeAfter;\n}\n\nstruct ApprovalConfig {\n bool isApproved;\n uint64 validUntil;\n}\n\nstruct RecoveryApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isNewOwnerApproved;\n}\n\nstruct RecoveryStorage {\n mapping(uint8 => RecoveryConfig) recoveryConfigs;\n mapping(uint8 => RecoveryApprovalConfig) recoveryApprovalConfigs;\n uint128 nonce;\n}\n\nstruct RestrictionsStorage {\n address[] restrictions;\n mapping(address => bool) exists;\n}\n\nstruct SignatureMigrationConfig {\n bytes migrationPublicKey;\n address migrationVerificationFacet;\n bytes4[] migrationSelectors;\n uint64 migrateAfter;\n}\n\nstruct SignatureMigrationApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isMigrationApproved;\n}\n\nstruct SignatureMigrationStorage {\n mapping(uint8 => SignatureMigrationConfig) migrationConfigs;\n mapping(uint8 => SignatureMigrationApprovalConfig) migrationApprovalConfigs;\n uint128 nonce;\n}\n\nstruct DiamondCutApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isDiamondCutApproved;\n}\n\nstruct DiamondCutStorage {\n mapping(uint8 => DiamondCutApprovalConfig) diamondCutApprovalConfigs;\n uint128 nonce;\n}\n\nstruct LockStorage {\n uint128 nonce;\n}\n\nlibrary LibFacetStorage {\n bytes32 constant K1_STORAGE_POSITION =\n keccak256(\n \"v0.trustwallet.diamond.storage.Secp256k1VerificationStorage\"\n );\n bytes32 constant R1_STORAGE_POSITION =\n keccak256(\n \"v0.trustwallet.diamond.storage.Secp256r1VerificationStorage\"\n );\n bytes32 constant GUARDIAN_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.GuardianStorage\");\n bytes32 constant RECOVERY_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.RecoveryStorage\");\n bytes32 constant RESTRICTION_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.RestrictionsStorage\");\n bytes32 constant MIGRATION_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.SignatureMigrationStorage\");\n bytes32 constant DIAMONDCUT_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.DiamondCutStorage\");\n bytes32 constant LOCK_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.LockStorage\");\n\n function k1Storage()\n internal\n pure\n returns (Secp256k1VerificationStorage storage ds)\n {\n bytes32 storagePosition = K1_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function r1Storage()\n internal\n pure\n returns (Secp256r1VerificationStorage storage ds)\n {\n bytes32 storagePosition = R1_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function guardianStorage()\n internal\n pure\n returns (GuardianStorage storage ds)\n {\n bytes32 storagePosition = GUARDIAN_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function recoveryStorage()\n internal\n pure\n returns (RecoveryStorage storage ds)\n {\n bytes32 storagePosition = RECOVERY_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function restrictionsStorage()\n internal\n pure\n returns (RestrictionsStorage storage ds)\n {\n bytes32 storagePosition = RESTRICTION_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function migrationStorage()\n internal\n pure\n returns (SignatureMigrationStorage storage ds)\n {\n bytes32 storagePosition = MIGRATION_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function diamondCutStorage()\n internal\n pure\n returns (DiamondCutStorage storage ds)\n {\n bytes32 storagePosition = DIAMONDCUT_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function lockStorage() internal pure returns (LockStorage storage ds) {\n bytes32 storagePosition = LOCK_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n}\n" + }, + "contracts/libraries/LibGuardian.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibFacetStorage, StorageConfig} from \"./LibFacetStorage.sol\";\n\n/**\n * @title LibGuardian\n * @dev Internal Library to provide utility feature for Guardians stored in Guardian Facet Storage\n * @author David Yongjun Kim (@Powerstream3604)\n */\nlibrary LibGuardian {\n function majorityOfGuardians()\n internal\n view\n returns (uint256 guardianNumber)\n {\n uint256 guardianLength = guardianCount();\n guardianNumber = (guardianLength == 0) ? 0 : guardianLength / 2 + 1;\n }\n\n function isGuardian(address _guardian) internal view returns (bool) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n return config.info[_guardian].exists;\n }\n\n function guardianCount() internal view returns (uint256) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n return config.addresses.length;\n }\n\n function getGuardians() internal view returns (address[] memory) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n address[] memory addresses = new address[](config.addresses.length);\n uint256 addressesLen = config.addresses.length;\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n return addresses;\n }\n}\n" + }, + "contracts/libraries/LibLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {LibDiamond} from \"./LibDiamond.sol\";\n\n/**\n * @title LibLoupe\n * @dev Internal Library to provide utility feature for reading the state of diamond facets\n * Originally from Diamond's implementation of Mudgen(author of EIP-2535)\n */\nlibrary LibLoupe {\n /// @notice Gets all facets and their selectors.\n /// @return facets_ Facet\n function facets()\n internal\n view\n returns (IDiamondLoupe.Facet[] memory facets_)\n {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facets_ = new IDiamondLoupe.Facet[](ds.selectorCount);\n uint16[] memory numFacetSelectors = new uint16[](ds.selectorCount);\n uint256 numFacets;\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facetAddress_ = address(bytes20(ds.facets[selector]));\n bool continueLoop;\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n if (facets_[facetIndex].facetAddress == facetAddress_) {\n facets_[facetIndex].functionSelectors[\n numFacetSelectors[facetIndex]\n ] = selector;\n // probably will never have more than 256 functions from one facet contract\n require(numFacetSelectors[facetIndex] < 255);\n numFacetSelectors[facetIndex]++;\n continueLoop = true;\n break;\n }\n }\n if (continueLoop) {\n continue;\n }\n facets_[numFacets].facetAddress = facetAddress_;\n facets_[numFacets].functionSelectors = new bytes4[](\n ds.selectorCount\n );\n facets_[numFacets].functionSelectors[0] = selector;\n numFacetSelectors[numFacets] = 1;\n numFacets++;\n }\n }\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n uint256 numSelectors = numFacetSelectors[facetIndex];\n bytes4[] memory selectors = facets_[facetIndex].functionSelectors;\n // setting the number of selectors\n assembly {\n mstore(selectors, numSelectors)\n }\n }\n // setting the number of facets\n assembly {\n mstore(facets_, numFacets)\n }\n }\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n /// @return _facetFunctionSelectors The selectors associated with a facet address.\n function facetFunctionSelectors(\n address _facet\n ) internal view returns (bytes4[] memory _facetFunctionSelectors) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n uint256 numSelectors;\n _facetFunctionSelectors = new bytes4[](ds.selectorCount);\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facet = address(bytes20(ds.facets[selector]));\n if (_facet == facet) {\n _facetFunctionSelectors[numSelectors] = selector;\n numSelectors++;\n }\n }\n }\n // Set the number of selectors in the array\n assembly {\n mstore(_facetFunctionSelectors, numSelectors)\n }\n }\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses()\n internal\n view\n returns (address[] memory facetAddresses_)\n {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facetAddresses_ = new address[](ds.selectorCount);\n uint256 numFacets;\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facetAddress_ = address(bytes20(ds.facets[selector]));\n bool continueLoop;\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n if (facetAddress_ == facetAddresses_[facetIndex]) {\n continueLoop = true;\n break;\n }\n }\n if (continueLoop) {\n continue;\n }\n facetAddresses_[numFacets] = facetAddress_;\n numFacets++;\n }\n }\n // Set the number of facet addresses in the array\n assembly {\n mstore(facetAddresses_, numFacets)\n }\n }\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(\n bytes4 _functionSelector\n ) internal view returns (address facetAddress_) {\n facetAddress_ = address(\n bytes20(LibDiamond.diamondStorage().facets[_functionSelector])\n );\n }\n}\n" + }, + "contracts/libraries/LibMultiSigStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Multi-sig Storage\n * @dev Storage contract for storing Multi-sig Facet variables in diamond storage pattern\n * @author David Yongjun Kim (@Powerstream3604)\n */\n\nstruct MultiSigStorage {\n mapping(address => address) owners;\n mapping(uint256 => mapping(address => mapping(bytes32 => uint256))) approvedHashes;\n uint256 ownerCount;\n uint256 threshold;\n uint256 counter;\n}\n\nlibrary LibMultiSigStorage {\n function multisigStorage()\n internal\n pure\n returns (MultiSigStorage storage ds)\n {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.MultiSigStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n}\n" + }, + "contracts/libraries/LibRecoverSpender.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title RecoverSpender\n * @dev Library to determine the action and spender of calldata\n * @author Ruslan Serebriakov (@rsrbk)\n */\nlibrary LibRecoverSpender {\n // ERC20, ERC721 & ERC1155 transfers & approvals\n bytes4 private constant ERC20_TRANSFER =\n bytes4(keccak256(\"transfer(address,uint256)\"));\n bytes4 private constant ERC20_APPROVE =\n bytes4(keccak256(\"approve(address,uint256)\"));\n bytes4 private constant ERC20_INCREASE_ALLOWANCE =\n bytes4(keccak256(\"increaseAllowance(address,uint256)\"));\n bytes4 private constant ERC20_DECREASE_ALLOWANCE =\n bytes4(keccak256(\"decreaseAllowance(address,uint256)\"));\n bytes4 private constant ERC721_SET_APPROVAL_FOR_ALL =\n bytes4(keccak256(\"setApprovalForAll(address,bool)\"));\n bytes4 private constant ERC721_TRANSFER_FROM =\n bytes4(keccak256(\"transferFrom(address,address,uint256)\"));\n bytes4 private constant ERC721_SAFE_TRANSFER_FROM =\n bytes4(keccak256(\"safeTransferFrom(address,address,uint256)\"));\n bytes4 private constant ERC721_SAFE_TRANSFER_FROM_BYTES =\n bytes4(keccak256(\"safeTransferFrom(address,address,uint256,bytes)\"));\n bytes4 private constant ERC1155_SAFE_TRANSFER_FROM =\n bytes4(\n keccak256(\"safeTransferFrom(address,address,uint256,uint256,bytes)\")\n );\n bytes4 private constant ERC1155_SAFE_BATCH_TRANSFER_FROM =\n bytes4(\n keccak256(\n \"safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)\"\n )\n );\n\n /**\n * @notice Helper method to recover the spender from a contract call.\n * The method returns the contract unless the call is to a standard method of a ERC20/ERC721/ERC1155 token\n * in which case the spender is recovered from the data.\n * @param _to The target contract.\n * @param _data The data payload.\n */\n function _recover(\n address _to,\n bytes memory _data\n ) internal pure returns (address spender) {\n if (_data.length >= 68) {\n bytes4 methodId;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n methodId := mload(add(_data, 0x20))\n }\n if (\n methodId == ERC20_TRANSFER ||\n methodId == ERC20_APPROVE ||\n methodId == ERC20_INCREASE_ALLOWANCE ||\n methodId == ERC20_DECREASE_ALLOWANCE ||\n methodId == ERC721_SET_APPROVAL_FOR_ALL\n ) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n spender := mload(add(_data, 0x24))\n }\n return spender;\n }\n if (\n methodId == ERC721_TRANSFER_FROM ||\n methodId == ERC721_SAFE_TRANSFER_FROM ||\n methodId == ERC721_SAFE_TRANSFER_FROM_BYTES ||\n methodId == ERC1155_SAFE_TRANSFER_FROM ||\n methodId == ERC1155_SAFE_BATCH_TRANSFER_FROM\n ) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n spender := mload(add(_data, 0x44))\n }\n return spender;\n }\n }\n\n spender = _to;\n }\n}\n" + }, + "contracts/libraries/LibUtils.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\n\nlibrary LibUtils {\n // Internal utility functions\n function mergeArrays(\n bytes4[] memory _array1,\n bytes4[] memory _array2\n ) internal pure returns (bytes4[] memory) {\n uint256 length1 = _array1.length;\n uint256 length2 = _array2.length;\n bytes4[] memory mergedArray = new bytes4[](length1 + length2);\n\n for (uint256 i; i < length1; ) {\n mergedArray[i] = _array1[i];\n unchecked {\n ++i;\n }\n }\n\n for (uint256 i; i < length2; ) {\n mergedArray[length1 + i] = _array2[i];\n unchecked {\n ++i;\n }\n }\n\n return mergedArray;\n }\n\n function removeFacetElement(\n IDiamondLoupe.Facet[] memory _facets,\n uint256 _index\n ) internal pure returns (IDiamondLoupe.Facet[] memory) {\n require(_index < _facets.length, \"Invalid index\");\n require(_facets.length != 0, \"Invalid array\");\n\n // Create a new array with a length of `_facets.length - 1`\n IDiamondLoupe.Facet[] memory newArray = new IDiamondLoupe.Facet[](\n _facets.length - 1\n );\n uint256 newArrayLength = newArray.length;\n // Iterate over the original array, skipping the element at the specified `index`\n for (uint256 i; i < newArrayLength; ) {\n if (i < _index) {\n newArray[i] = _facets[i];\n } else {\n newArray[i] = _facets[i + 1];\n }\n unchecked {\n ++i;\n }\n }\n\n return newArray;\n }\n\n function removeElement(\n bytes4[] memory _array,\n uint256 _index\n ) internal pure returns (bytes4[] memory) {\n require(_index < _array.length, \"Invalid index\");\n require(_array.length != 0, \"Invalid array\");\n\n bytes4[] memory newArray = new bytes4[](_array.length - 1);\n uint256 newArrayLength = newArray.length;\n for (uint256 i; i < newArrayLength; ) {\n if (i < _index) {\n newArray[i] = _array[i];\n } else {\n newArray[i] = _array[i + 1];\n }\n unchecked {\n ++i;\n }\n }\n\n return newArray;\n }\n\n function setValue(\n bytes4[] memory _keys,\n address[] memory _values,\n bytes4 _key,\n address _value\n ) internal pure returns (bytes4[] memory, address[] memory) {\n uint256 index = findIndex(_keys, _key);\n uint256 keysLength = _keys.length;\n if (index < keysLength) {\n _values[index] = _value;\n } else {\n // Create new storage arrays\n bytes4[] memory newKeys = new bytes4[](keysLength + 1);\n address[] memory newValues = new address[](_values.length + 1);\n\n // Copy values to the new storage arrays\n for (uint256 i; i < keysLength; ) {\n newKeys[i] = _keys[i];\n newValues[i] = _values[i];\n\n unchecked {\n ++i;\n }\n }\n\n // Add the new key-value pair\n newKeys[keysLength] = _key;\n newValues[_values.length] = _value;\n\n return (newKeys, newValues);\n }\n\n // If the key already exists, return the original arrays\n return (_keys, _values);\n }\n\n function getValue(\n bytes4[] memory _keys,\n address[] memory _values,\n bytes4 _key\n ) internal pure returns (address) {\n uint256 index = findIndex(_keys, _key);\n if (index >= _keys.length) return address(0);\n\n return _values[index];\n }\n\n function findIndex(\n bytes4[] memory _keys,\n bytes4 _key\n ) internal pure returns (uint256) {\n uint256 keysLength = _keys.length;\n for (uint256 i; i < keysLength; ) {\n if (_keys[i] == _key) {\n return i;\n }\n unchecked {\n ++i;\n }\n }\n return keysLength;\n }\n}\n" + }, + "contracts/restrictions/IRestriction.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Interface for restrictions\n * @dev Restriction is a contract which decides whether to approve a certain kind of transaction, based on its internal logic.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface IRestriction {\n /**\n * @dev Based on restriction's internal logic, it should accept or reject a certain transaction.\n * @param from The address of the sender, that will be signing the transaction.\n * @param to The receiving address.\n * @param value Amount of ETH to transfer from sender to recipient.\n * @param _calldata Optional field to include arbitrary data.\n * @return bool value for whether the check is passed\n */\n function check(\n address from,\n address to,\n uint256 value,\n bytes calldata _calldata\n ) external returns (bool);\n}\n" + }, + "contracts/restrictions/WhitelistRestriction.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibRecoverSpender} from \"../libraries/LibRecoverSpender.sol\";\nimport {WhitelistStorage} from \"../infrastructure/WhitelistStorage.sol\";\nimport {IRestriction} from \"./IRestriction.sol\";\n\n/**\n * @title Whitelist Restriction\n * @dev This restriction defines a list of accepted addresses and denies any interaction with addresses outside of it.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract WhitelistRestriction is IRestriction {\n WhitelistStorage public immutable whitelistStorage;\n\n constructor(WhitelistStorage _whitelistStorage) {\n whitelistStorage = _whitelistStorage;\n }\n\n /**\n * @notice Helper method to recover the spender from a contract call.\n * The method returns the contract unless the call is to a standard method of a ERC20/ERC721/ERC1155 token\n * in which case the spender is recovered from the data.\n * @param _to The target contract.\n * @param _data The data payload.\n */\n function recoverSpender(\n address _to,\n bytes memory _data\n ) public pure returns (address spender) {\n return LibRecoverSpender._recover(_to, _data);\n }\n\n /*\n * @dev IRestriction's implementation. It will allow transaction if the sender is whitelisted, or user, or the whitelist storage.\n * @param _from The address of the sender, that will be signing the transaction.\n * @param _to The receiving address.\n * @param _calldata Optional field to include arbitrary data.\n * @return result value for whether the check is passed\n */\n function check(\n address _from,\n address _to,\n uint256 /*_value*/,\n bytes calldata _calldata\n ) external view override returns (bool result) {\n return\n whitelistStorage.isWhitelisted(\n _from,\n LibRecoverSpender._recover(_to, _calldata)\n ) ||\n _to == address(whitelistStorage) ||\n _to == msg.sender;\n }\n}\n" + }, + "contracts/test/Counter.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\ncontract TestCounter {\n int private count = 0;\n\n function incrementCounter() public {\n count += 1;\n }\n\n function decrementCounter() public {\n count -= 1;\n }\n\n function getCount() public view returns (int) {\n return count;\n }\n}\n" + }, + "contracts/test/TestERC1155.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC1155/ERC1155.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\n\ncontract TestERC1155 is ERC1155 {\n using Counters for Counters.Counter;\n\n Counters.Counter private _tokenIds;\n\n constructor() ERC1155(\"\") {}\n\n function mint(address account, uint256 amount) external {\n uint256 tokenId = _getNextTokenId();\n _mint(account, tokenId, amount, \"\");\n }\n\n function mintBatch(\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes memory data\n ) external {\n require(\n ids.length == amounts.length,\n \"TestERC1155: arrays length mismatch\"\n );\n\n _mintBatch(to, ids, amounts, data);\n }\n\n function _getNextTokenId() private returns (uint256) {\n _tokenIds.increment();\n return _tokenIds.current();\n }\n}\n" + }, + "contracts/test/TestERC777.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC777/ERC777.sol\";\n\ncontract TestERC777 is ERC777 {\n constructor(\n address[] memory _operators\n ) ERC777(\"TestERC777\", \"TERC777\", _operators) {}\n\n function mint(address account, uint256 amount) external {\n _mint(account, amount, \"\", \"\");\n }\n}\n" + }, + "contracts/test/TestInvalidSecp256k1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IVerificationFacet} from \"../facets/interfaces/IVerificationFacet.sol\";\nimport {IERC1271} from \"../interfaces/ERC/IERC1271.sol\";\nimport {AppStorage, LibAppStorage, BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {LibFacetStorage, Secp256k1VerificationStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {UserOperation} from \"../aa-4337/interfaces/UserOperation.sol\";\n\n/**\n * @title Test Secp256k1 verification facet\n * @dev Default Ethereum's elliptic curve\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract TestInvalidSecp256k1VerificationFacet is BarzStorage, IERC1271 {\n using ECDSA for bytes32;\n error Secp256k1VerificationFacet__InvalidSignerLength();\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n\n event SignerUninitialized();\n\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n }\n\n // THIS INVALID FACET DOES NOT INCLUDE initializeSigner()\n // THIS FACET IS USED TO TEST WHEN initializeSigner() DOESN'T EXIST IN FACET\n\n function uninitializeSigner() external returns (uint256 uninitSuccess) {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view returns (uint256 validationData) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n return validateSignature(userOp, userOpHash, k1Storage.signer);\n }\n\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n address signer\n ) public pure returns (uint256) {\n bytes32 hash = userOpHash.toEthSignedMessageHash();\n if (signer != hash.recover(userOp.signature)) return 1;\n return 0;\n }\n\n // This is REMOVED for testing purpose\n function validateOwnerSignatureSelector() public pure returns (bytes4) {\n // return this.validateOwnerSignature.selector;\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n function owner() public view returns (bytes memory) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n return abi.encodePacked(k1Storage.signer);\n }\n\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure returns (bool) {\n return (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (_hash.recover(_signature) ==\n LibFacetStorage.k1Storage().signer)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n}\n" + }, + "contracts/test/TestNFT.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\n\ncontract TestNFT is ERC721 {\n using Counters for Counters.Counter;\n Counters.Counter private currentTokenId;\n\n constructor() ERC721(\"TestNFT\", \"TNFT\") {}\n\n function mint(address recipient) public returns (uint256) {\n currentTokenId.increment();\n uint256 newItemId = currentTokenId.current();\n _safeMint(recipient, newItemId);\n return newItemId;\n }\n}\n" + }, + "contracts/test/TestToken.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract TestToken is ERC20 {\n constructor()\n // solhint-disable-next-line no-empty-blocks\n ERC20(\"TST\", \"TestToken\")\n {}\n\n function mint(address sender, uint256 amount) external {\n _mint(sender, amount);\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 999999 + }, + "evmVersion": "paris", + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/deployments/optimism/.chainId b/deployments/optimism/.chainId new file mode 100644 index 0000000..9a03714 --- /dev/null +++ b/deployments/optimism/.chainId @@ -0,0 +1 @@ +10 \ No newline at end of file diff --git a/deployments/optimism/AccountFacet.json b/deployments/optimism/AccountFacet.json new file mode 100644 index 0000000..5b08f5f --- /dev/null +++ b/deployments/optimism/AccountFacet.json @@ -0,0 +1,591 @@ +{ + "address": "0xFde53272dcd7938d16E031A6989753c321728332", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "AccountFacet__CallNotSuccessful", + "type": "error" + }, + { + "inputs": [], + "name": "AccountFacet__InitializationFailure", + "type": "error" + }, + { + "inputs": [], + "name": "AccountFacet__InvalidArrayLength", + "type": "error" + }, + { + "inputs": [], + "name": "AccountFacet__NonExistentVerificationFacet", + "type": "error" + }, + { + "inputs": [], + "name": "AccountFacet__RestrictionsFailure", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_initializationContractAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "InitializationFunctionReverted", + "type": "error" + }, + { + "inputs": [], + "name": "LibAppStorage__AccountMustBeUninitialized", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract IEntryPoint", + "name": "entryPoint", + "type": "address" + }, + { + "indexed": true, + "internalType": "bytes", + "name": "ownerPublicKey", + "type": "bytes" + } + ], + "name": "AccountInitialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "indexed": false, + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "DiamondCut", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "VerificationFailure", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "VerificationSuccess", + "type": "event" + }, + { + "inputs": [], + "name": "entryPoint", + "outputs": [ + { + "internalType": "contract IEntryPoint", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_dest", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_func", + "type": "bytes" + } + ], + "name": "execute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_dest", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "_value", + "type": "uint256[]" + }, + { + "internalType": "bytes[]", + "name": "_func", + "type": "bytes[]" + } + ], + "name": "executeBatch", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getNonce", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_verificationFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_anEntryPoint", + "type": "address" + }, + { + "internalType": "address", + "name": "_facetRegistry", + "type": "address" + }, + { + "internalType": "address", + "name": "_defaultFallBackHandler", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_ownerPublicKey", + "type": "bytes" + } + ], + "name": "initialize", + "outputs": [ + { + "internalType": "uint256", + "name": "initSuccess", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "initCode", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "callGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "verificationGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "preVerificationGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxFeePerGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPriorityFeePerGas", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "paymasterAndData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "internalType": "struct UserOperation", + "name": "userOp", + "type": "tuple" + }, + { + "internalType": "bytes32", + "name": "userOpHash", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "missingAccountFunds", + "type": "uint256" + } + ], + "name": "validateUserOp", + "outputs": [ + { + "internalType": "uint256", + "name": "validationData", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0x9b63bdee143ad1d3c49af7486ec8b5bd6b90aee37f630eca1f21f6512324556f", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 4, + "gasUsed": "2369950", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x963788d005ec82b7127a3630a34100910c2429b99dfc9baf6512bfebc8dc0e83", + "transactionHash": "0x9b63bdee143ad1d3c49af7486ec8b5bd6b90aee37f630eca1f21f6512324556f", + "logs": [], + "blockNumber": 112443697, + "cumulativeGasUsed": "2514289", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 3, + "solcInputHash": "4356503edd8ae34e73cb6dd1c8e2fc8a", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AccountFacet__CallNotSuccessful\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AccountFacet__InitializationFailure\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AccountFacet__InvalidArrayLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AccountFacet__NonExistentVerificationFacet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AccountFacet__RestrictionsFailure\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_initializationContractAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"InitializationFunctionReverted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LibAppStorage__AccountMustBeUninitialized\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract IEntryPoint\",\"name\":\"entryPoint\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes\",\"name\":\"ownerPublicKey\",\"type\":\"bytes\"}],\"name\":\"AccountInitialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"DiamondCut\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"VerificationFailure\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"VerificationSuccess\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"entryPoint\",\"outputs\":[{\"internalType\":\"contract IEntryPoint\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_dest\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_func\",\"type\":\"bytes\"}],\"name\":\"execute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_dest\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"_value\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes[]\",\"name\":\"_func\",\"type\":\"bytes[]\"}],\"name\":\"executeBatch\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_verificationFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_anEntryPoint\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_facetRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_defaultFallBackHandler\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_ownerPublicKey\",\"type\":\"bytes\"}],\"name\":\"initialize\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"initSuccess\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"userOp\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"missingAccountFunds\",\"type\":\"uint256\"}],\"name\":\"validateUserOp\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"validationData\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"Account module contract that provides the account features and initialization of signer compatible with EIP-1271 & EIP-4337\",\"kind\":\"dev\",\"methods\":{\"execute(address,uint256,bytes)\":{\"details\":\"This method executes the calldata coming from the EntryPoint. Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\",\"params\":{\"_dest\":\"Address of destination where the call will be forwarded to\",\"_func\":\"Bytes of calldata to execute in the destination address\",\"_value\":\"Amount of native coin the owner is willing to send(e.g. ETH, BNB)\"}},\"executeBatch(address[],uint256[],bytes[])\":{\"details\":\"This method batch executes the calldata coming from the EntryPoint. Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\",\"params\":{\"_dest\":\"Array of addresses of destination where the call will be forwarded to\",\"_func\":\"Array of bytes of calldata to execute in the destination address\",\"_value\":\"Array of amount of native coin the owner is willing to send(e.g. ETH, BNB)\"}},\"initialize(address,address,address,address,bytes)\":{\"details\":\"This method can only be called during the initialization or signature migration. If the proxy contract was created without initialization, anyone can call initialize. Barz calls initialize in constructor in an atomic transaction during deployment\",\"params\":{\"_anEntryPoint\":\"Entrypoint contract defined in EIP-4337 handling the flow of UserOp\",\"_defaultFallBackHandler\":\"Middleware contract for default facets\",\"_facetRegistry\":\"Registry of Facets that hold all facet information\",\"_ownerPublicKey\":\"Bytes of owner public key\",\"_verificationFacet\":\"Facet contract handling the verificationi\"}}},\"title\":\"Account Facet\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"This constructor ensures that this contract can only be used as singleton for Proxy contracts\"},\"entryPoint()\":{\"notice\":\"Returns the address of EntryPoint contract registered to Barz account\"},\"execute(address,uint256,bytes)\":{\"notice\":\"Calls the destination with inputted calldata and value from EntryPoint\"},\"executeBatch(address[],uint256[],bytes[])\":{\"notice\":\"Batch calls the destination with inputted calldata and value from EntryPoint\"},\"getNonce()\":{\"notice\":\"Return the account nonce. This method returns the next sequential nonce. For a nonce of a specific key, use `entrypoint.getNonce(account, key)`\"},\"initialize(address,address,address,address,bytes)\":{\"notice\":\"Initializes the initial storage of the Barz contract.\"},\"validateUserOp((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256)\":{\"notice\":\"Validate user's signature and nonce. subclass doesn't need to override this method. Instead, it should override the specific internal validation methods.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/AccountFacet.sol\":\"AccountFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./math/Math.sol\\\";\\nimport \\\"./math/SignedMath.sol\\\";\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n uint256 length = Math.log10(value) + 1;\\n string memory buffer = new string(length);\\n uint256 ptr;\\n /// @solidity memory-safe-assembly\\n assembly {\\n ptr := add(buffer, add(32, length))\\n }\\n while (true) {\\n ptr--;\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\\n }\\n value /= 10;\\n if (value == 0) break;\\n }\\n return buffer;\\n }\\n }\\n\\n /**\\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\\n */\\n function toString(int256 value) internal pure returns (string memory) {\\n return string(abi.encodePacked(value < 0 ? \\\"-\\\" : \\\"\\\", toString(SignedMath.abs(value))));\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n return toHexString(value, Math.log256(value) + 1);\\n }\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n\\n /**\\n * @dev Returns true if the two strings are equal.\\n */\\n function equal(string memory a, string memory b) internal pure returns (bool) {\\n return keccak256(bytes(a)) == keccak256(bytes(b));\\n }\\n}\\n\",\"keccak256\":\"0x3088eb2868e8d13d89d16670b5f8612c4ab9ff8956272837d8e90106c59c14a0\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Strings.sol\\\";\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSA {\\n enum RecoverError {\\n NoError,\\n InvalidSignature,\\n InvalidSignatureLength,\\n InvalidSignatureS,\\n InvalidSignatureV // Deprecated in v4.8\\n }\\n\\n function _throwError(RecoverError error) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert(\\\"ECDSA: invalid signature\\\");\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert(\\\"ECDSA: invalid signature length\\\");\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert(\\\"ECDSA: invalid signature 's' value\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature` or error string. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n *\\n * Documentation for signature generation:\\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n return tryRecover(hash, v, r, s);\\n } else {\\n return (address(0), RecoverError.InvalidSignatureLength);\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature`. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, signature);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\\n uint8 v = uint8((uint256(vs) >> 255) + 27);\\n return tryRecover(hash, v, r, s);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n *\\n * _Available since v4.2._\\n */\\n function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\\n // the valid range for s in (301): 0 < s < secp256k1n \\u00f7 2 + 1, and for v in (302): v \\u2208 {27, 28}. Most\\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\\n //\\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\\n // these malleable signatures as well.\\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n return (address(0), RecoverError.InvalidSignatureS);\\n }\\n\\n // If the signature is valid (and not malleable), return the signer address\\n address signer = ecrecover(hash, v, r, s);\\n if (signer == address(0)) {\\n return (address(0), RecoverError.InvalidSignature);\\n }\\n\\n return (signer, RecoverError.NoError);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore(0x00, \\\"\\\\x19Ethereum Signed Message:\\\\n32\\\")\\n mstore(0x1c, hash)\\n message := keccak256(0x00, 0x3c)\\n }\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from `s`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n\\\", Strings.toString(s.length), s));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Typed Data, created from a\\n * `domainSeparator` and a `structHash`. This produces hash corresponding\\n * to the one signed with the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n * JSON-RPC method as part of EIP-712.\\n *\\n * See {recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n let ptr := mload(0x40)\\n mstore(ptr, \\\"\\\\x19\\\\x01\\\")\\n mstore(add(ptr, 0x02), domainSeparator)\\n mstore(add(ptr, 0x22), structHash)\\n data := keccak256(ptr, 0x42)\\n }\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Data with intended validator, created from a\\n * `validator` and `data` according to the version 0 of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x00\\\", validator, data));\\n }\\n}\\n\",\"keccak256\":\"0x809bc3edb4bcbef8263fa616c1b60ee0004b50a8a1bfa164d8f57fd31f520c58\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n enum Rounding {\\n Down, // Toward negative infinity\\n Up, // Toward infinity\\n Zero // Toward zero\\n }\\n\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow.\\n return (a & b) + (a ^ b) / 2;\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a == 0 ? 0 : (a - 1) / b + 1;\\n }\\n\\n /**\\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\\n * with further edits by Uniswap Labs also under MIT license.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\\n unchecked {\\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2^256 + prod0.\\n uint256 prod0; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division.\\n if (prod1 == 0) {\\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\\n // The surrounding unchecked block does not change this fact.\\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\\n return prod0 / denominator;\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n require(denominator > prod1, \\\"Math: mulDiv overflow\\\");\\n\\n ///////////////////////////////////////////////\\n // 512 by 256 division.\\n ///////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0].\\n uint256 remainder;\\n assembly {\\n // Compute remainder using mulmod.\\n remainder := mulmod(x, y, denominator)\\n\\n // Subtract 256 bit number from 512 bit number.\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\\n // See https://cs.stackexchange.com/q/138556/92363.\\n\\n // Does not overflow because the denominator cannot be zero at this stage in the function.\\n uint256 twos = denominator & (~denominator + 1);\\n assembly {\\n // Divide denominator by twos.\\n denominator := div(denominator, twos)\\n\\n // Divide [prod1 prod0] by twos.\\n prod0 := div(prod0, twos)\\n\\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\\n twos := add(div(sub(0, twos), twos), 1)\\n }\\n\\n // Shift in bits from prod1 into prod0.\\n prod0 |= prod1 * twos;\\n\\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\\n // four bits. That is, denominator * inv = 1 mod 2^4.\\n uint256 inverse = (3 * denominator) ^ 2;\\n\\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\\n // in modular arithmetic, doubling the correct bits in each step.\\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\\n\\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inverse;\\n return result;\\n }\\n }\\n\\n /**\\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\\n uint256 result = mulDiv(x, y, denominator);\\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\\n result += 1;\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\\n *\\n * Inspired by Henry S. Warren, Jr.'s \\\"Hacker's Delight\\\" (Chapter 11).\\n */\\n function sqrt(uint256 a) internal pure returns (uint256) {\\n if (a == 0) {\\n return 0;\\n }\\n\\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\\n //\\n // We know that the \\\"msb\\\" (most significant bit) of our target number `a` is a power of 2 such that we have\\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\\n //\\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\\n // \\u2192 `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\\n // \\u2192 `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\\n //\\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\\n uint256 result = 1 << (log2(a) >> 1);\\n\\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\\n // into the expected uint128 result.\\n unchecked {\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n return min(result, a / result);\\n }\\n }\\n\\n /**\\n * @notice Calculates sqrt(a), following the selected rounding direction.\\n */\\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = sqrt(a);\\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 2, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 128;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 64;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 32;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 16;\\n }\\n if (value >> 8 > 0) {\\n value >>= 8;\\n result += 8;\\n }\\n if (value >> 4 > 0) {\\n value >>= 4;\\n result += 4;\\n }\\n if (value >> 2 > 0) {\\n value >>= 2;\\n result += 2;\\n }\\n if (value >> 1 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log2(value);\\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 10, rounded down, of a positive value.\\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 + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 256, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n *\\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\\n */\\n function log256(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 16;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 8;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 4;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 2;\\n }\\n if (value >> 8 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log256(value);\\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe4455ac1eb7fc497bb7402579e7b4d64d928b846fce7d2b6fde06d366f21c2b3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\\n * checks.\\n *\\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\\n * easily result in undesired exploitation or bugs, since developers usually\\n * assume that overflows raise errors. `SafeCast` restores this intuition by\\n * reverting the transaction when such an operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n *\\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\\n * all math on `uint256` and `int256` and then downcasting.\\n */\\nlibrary SafeCast {\\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 * _Available since v4.7._\\n */\\n function toUint248(uint256 value) internal pure returns (uint248) {\\n require(value <= type(uint248).max, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint240(uint256 value) internal pure returns (uint240) {\\n require(value <= type(uint240).max, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint232(uint256 value) internal pure returns (uint232) {\\n require(value <= type(uint232).max, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint224(uint256 value) internal pure returns (uint224) {\\n require(value <= type(uint224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint216(uint256 value) internal pure returns (uint216) {\\n require(value <= type(uint216).max, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint208(uint256 value) internal pure returns (uint208) {\\n require(value <= type(uint208).max, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint200(uint256 value) internal pure returns (uint200) {\\n require(value <= type(uint200).max, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint192(uint256 value) internal pure returns (uint192) {\\n require(value <= type(uint192).max, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint184(uint256 value) internal pure returns (uint184) {\\n require(value <= type(uint184).max, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint176(uint256 value) internal pure returns (uint176) {\\n require(value <= type(uint176).max, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint168(uint256 value) internal pure returns (uint168) {\\n require(value <= type(uint168).max, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint160(uint256 value) internal pure returns (uint160) {\\n require(value <= type(uint160).max, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint152(uint256 value) internal pure returns (uint152) {\\n require(value <= type(uint152).max, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint144(uint256 value) internal pure returns (uint144) {\\n require(value <= type(uint144).max, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint136(uint256 value) internal pure returns (uint136) {\\n require(value <= type(uint136).max, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint128(uint256 value) internal pure returns (uint128) {\\n require(value <= type(uint128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint120(uint256 value) internal pure returns (uint120) {\\n require(value <= type(uint120).max, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint112(uint256 value) internal pure returns (uint112) {\\n require(value <= type(uint112).max, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint104(uint256 value) internal pure returns (uint104) {\\n require(value <= type(uint104).max, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint96(uint256 value) internal pure returns (uint96) {\\n require(value <= type(uint96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint88(uint256 value) internal pure returns (uint88) {\\n require(value <= type(uint88).max, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint80(uint256 value) internal pure returns (uint80) {\\n require(value <= type(uint80).max, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint72(uint256 value) internal pure returns (uint72) {\\n require(value <= type(uint72).max, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint64(uint256 value) internal pure returns (uint64) {\\n require(value <= type(uint64).max, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint56(uint256 value) internal pure returns (uint56) {\\n require(value <= type(uint56).max, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint48(uint256 value) internal pure returns (uint48) {\\n require(value <= type(uint48).max, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint40(uint256 value) internal pure returns (uint40) {\\n require(value <= type(uint40).max, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint32(uint256 value) internal pure returns (uint32) {\\n require(value <= type(uint32).max, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint24(uint256 value) internal pure returns (uint24) {\\n require(value <= type(uint24).max, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint16(uint256 value) internal pure returns (uint16) {\\n require(value <= type(uint16).max, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint8(uint256 value) internal pure returns (uint8) {\\n require(value <= type(uint8).max, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\n */\\n function toUint256(int256 value) internal pure returns (uint256) {\\n require(value >= 0, \\\"SafeCast: value must be positive\\\");\\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 * _Available since v4.7._\\n */\\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\\n downcasted = int248(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\\n downcasted = int240(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\\n downcasted = int232(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\\n downcasted = int224(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\\n downcasted = int216(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\\n downcasted = int208(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\\n downcasted = int200(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\\n downcasted = int192(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\\n downcasted = int184(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\\n downcasted = int176(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\\n downcasted = int168(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\\n downcasted = int160(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\\n downcasted = int152(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\\n downcasted = int144(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\\n downcasted = int136(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\\n downcasted = int128(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\\n downcasted = int120(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\\n downcasted = int112(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\\n downcasted = int104(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\\n downcasted = int96(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\\n downcasted = int88(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\\n downcasted = int80(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\\n downcasted = int72(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\\n downcasted = int64(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\\n downcasted = int56(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\\n downcasted = int48(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\\n downcasted = int40(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\\n downcasted = int32(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\\n downcasted = int24(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\\n downcasted = int16(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\\n downcasted = int8(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\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 require(value <= uint256(type(int256).max), \\\"SafeCast: value doesn't fit in an int256\\\");\\n return int256(value);\\n }\\n}\\n\",\"keccak256\":\"0x52a8cfb0f5239d11b457dcdd1b326992ef672714ca8da71a157255bddd13f3ad\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SignedMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard signed math utilities missing in the Solidity language.\\n */\\nlibrary SignedMath {\\n /**\\n * @dev Returns the largest of two signed numbers.\\n */\\n function max(int256 a, int256 b) internal pure returns (int256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two signed numbers.\\n */\\n function min(int256 a, int256 b) internal pure returns (int256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two signed numbers without overflow.\\n * The result is rounded towards zero.\\n */\\n function average(int256 a, int256 b) internal pure returns (int256) {\\n // Formula from the book \\\"Hacker's Delight\\\"\\n int256 x = (a & b) + ((a ^ b) >> 1);\\n return x + (int256(uint256(x) >> 255) & (a ^ b));\\n }\\n\\n /**\\n * @dev Returns the absolute unsigned value of a signed value.\\n */\\n function abs(int256 n) internal pure returns (uint256) {\\n unchecked {\\n // must be unchecked in order to support `n = type(int256).min`\\n return uint256(n >= 0 ? n : -n);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf92515413956f529d95977adc9b0567d583c6203fc31ab1c23824c35187e3ddc\",\"license\":\"MIT\"},\"contracts/aa-4337/core/BaseAccount.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-empty-blocks */\\n\\nimport \\\"../interfaces/IAccount.sol\\\";\\nimport \\\"../interfaces/IEntryPoint.sol\\\";\\nimport \\\"./Helpers.sol\\\";\\n\\n/**\\n * Basic account implementation.\\n * this contract provides the basic logic for implementing the IAccount interface - validateUserOp\\n * specific account implementation should inherit it and provide the account-specific logic\\n */\\nabstract contract BaseAccount is IAccount {\\n using UserOperationLib for UserOperation;\\n\\n //return value in case of signature failure, with no time-range.\\n // equivalent to _packValidationData(true,0,0);\\n uint256 internal constant SIG_VALIDATION_FAILED = 1;\\n\\n /**\\n * Return the account nonce.\\n * This method returns the next sequential nonce.\\n * For a nonce of a specific key, use `entrypoint.getNonce(account, key)`\\n */\\n function getNonce() public view virtual returns (uint256) {\\n return entryPoint().getNonce(address(this), 0);\\n }\\n\\n /**\\n * return the entryPoint used by this account.\\n * subclass should return the current entryPoint used by this account.\\n */\\n function entryPoint() public view virtual returns (IEntryPoint);\\n\\n /**\\n * Validate user's signature and nonce.\\n * subclass doesn't need to override this method. Instead, it should override the specific internal validation methods.\\n */\\n function validateUserOp(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n uint256 missingAccountFunds\\n ) external virtual override returns (uint256 validationData) {\\n _requireFromEntryPoint();\\n validationData = _validateSignature(userOp, userOpHash);\\n _validateNonce(userOp.nonce);\\n _payPrefund(missingAccountFunds);\\n }\\n\\n /**\\n * ensure the request comes from the known entrypoint.\\n */\\n function _requireFromEntryPoint() internal view virtual {\\n require(\\n msg.sender == address(entryPoint()),\\n \\\"account: not from EntryPoint\\\"\\n );\\n }\\n\\n /**\\n * validate the signature is valid for this message.\\n * @param userOp validate the userOp.signature field\\n * @param userOpHash convenient field: the hash of the request, to check the signature against\\n * (also hashes the entrypoint and chain id)\\n * @return validationData signature and time-range of this operation\\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\\n * otherwise, an address of an \\\"authorizer\\\" contract.\\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \\\"indefinite\\\"\\n * <6-byte> validAfter - first timestamp this operation is valid\\n * If the account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\\n */\\n function _validateSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) internal virtual returns (uint256 validationData);\\n\\n /**\\n * Validate the nonce of the UserOperation.\\n * This method may validate the nonce requirement of this account.\\n * e.g.\\n * To limit the nonce to use sequenced UserOps only (no \\\"out of order\\\" UserOps):\\n * `require(nonce < type(uint64).max)`\\n * For a hypothetical account that *requires* the nonce to be out-of-order:\\n * `require(nonce & type(uint64).max == 0)`\\n *\\n * The actual nonce uniqueness is managed by the EntryPoint, and thus no other\\n * action is needed by the account itself.\\n *\\n * @param nonce to validate\\n *\\n * solhint-disable-next-line no-empty-blocks\\n */\\n function _validateNonce(uint256 nonce) internal view virtual {}\\n\\n /**\\n * sends to the entrypoint (msg.sender) the missing funds for this transaction.\\n * subclass MAY override this method for better funds management\\n * (e.g. send to the entryPoint more than the minimum required, so that in future transactions\\n * it will not be required to send again)\\n * @param missingAccountFunds the minimum value this method should send the entrypoint.\\n * this value MAY be zero, in case there is enough deposit, or the userOp has a paymaster.\\n */\\n function _payPrefund(uint256 missingAccountFunds) internal virtual {\\n if (missingAccountFunds != 0) {\\n (bool success, ) = payable(msg.sender).call{\\n value: missingAccountFunds,\\n gas: type(uint256).max\\n }(\\\"\\\");\\n (success);\\n //ignore failure (its EntryPoint's job to verify, not account.)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa0dcc386b0f04711db3e394fb50e55a3b3b1a4d19fac1f10895844e1aa4e3d5c\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/core/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable no-inline-assembly */\\n\\n/**\\n * returned data from validateUserOp.\\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\\n * @param aggregator - address(0) - the account validated the signature by itself.\\n * address(1) - the account failed to validate the signature.\\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\\n * @param validAfter - this UserOp is valid only after this timestamp.\\n * @param validaUntil - this UserOp is valid only up to this timestamp.\\n */\\nstruct ValidationData {\\n address aggregator;\\n uint48 validAfter;\\n uint48 validUntil;\\n}\\n\\n//extract sigFailed, validAfter, validUntil.\\n// also convert zero validUntil to type(uint48).max\\nfunction _parseValidationData(\\n uint validationData\\n) pure returns (ValidationData memory data) {\\n address aggregator = address(uint160(validationData));\\n uint48 validUntil = uint48(validationData >> 160);\\n if (validUntil == 0) {\\n validUntil = type(uint48).max;\\n }\\n uint48 validAfter = uint48(validationData >> (48 + 160));\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n// intersect account and paymaster ranges.\\nfunction _intersectTimeRange(\\n uint256 validationData,\\n uint256 paymasterValidationData\\n) pure returns (ValidationData memory) {\\n ValidationData memory accountValidationData = _parseValidationData(\\n validationData\\n );\\n ValidationData memory pmValidationData = _parseValidationData(\\n paymasterValidationData\\n );\\n address aggregator = accountValidationData.aggregator;\\n if (aggregator == address(0)) {\\n aggregator = pmValidationData.aggregator;\\n }\\n uint48 validAfter = accountValidationData.validAfter;\\n uint48 validUntil = accountValidationData.validUntil;\\n uint48 pmValidAfter = pmValidationData.validAfter;\\n uint48 pmValidUntil = pmValidationData.validUntil;\\n\\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp\\n * @param data - the ValidationData to pack\\n */\\nfunction _packValidationData(\\n ValidationData memory data\\n) pure returns (uint256) {\\n return\\n uint160(data.aggregator) |\\n (uint256(data.validUntil) << 160) |\\n (uint256(data.validAfter) << (160 + 48));\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp, when not using an aggregator\\n * @param sigFailed - true for signature failure, false for success\\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\\n * @param validAfter first timestamp this UserOperation is valid\\n */\\nfunction _packValidationData(\\n bool sigFailed,\\n uint48 validUntil,\\n uint48 validAfter\\n) pure returns (uint256) {\\n return\\n (sigFailed ? 1 : 0) |\\n (uint256(validUntil) << 160) |\\n (uint256(validAfter) << (160 + 48));\\n}\\n\\n/**\\n * keccak function over calldata.\\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\\n */\\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\\n assembly {\\n let mem := mload(0x40)\\n let len := data.length\\n calldatacopy(mem, data.offset, len)\\n ret := keccak256(mem, len)\\n }\\n}\\n\",\"keccak256\":\"0xa79f06cd158ecb8c0da95493a2f348933b8627a63e228b99738bff3aa107942d\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAccount.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\ninterface IAccount {\\n /**\\n * Validate user's signature and nonce\\n * the entryPoint will make the call to the recipient only if this validation call returns successfully.\\n * signature failure should be reported by returning SIG_VALIDATION_FAILED (1).\\n * This allows making a \\\"simulation call\\\" without a valid signature\\n * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure.\\n *\\n * @dev Must validate caller is the entryPoint.\\n * Must validate the signature and nonce\\n * @param userOp the operation that is about to be executed.\\n * @param userOpHash hash of the user's request data. can be used as the basis for signature.\\n * @param missingAccountFunds missing funds on the account's deposit in the entrypoint.\\n * This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call.\\n * The excess is left as a deposit in the entrypoint, for future calls.\\n * can be withdrawn anytime using \\\"entryPoint.withdrawTo()\\\"\\n * In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero.\\n * @return validationData packaged ValidationData structure. use `_packValidationData` and `_unpackValidationData` to encode and decode\\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\\n * otherwise, an address of an \\\"authorizer\\\" contract.\\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \\\"indefinite\\\"\\n * <6-byte> validAfter - first timestamp this operation is valid\\n * If an account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\\n */\\n function validateUserOp(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n uint256 missingAccountFunds\\n ) external returns (uint256 validationData);\\n}\\n\",\"keccak256\":\"0xcbc4b0973cf954c5895b7796335f651fbfcfb55f67dfa789a3d354f8e23c4f2b\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAggregator.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\n/**\\n * Aggregated Signatures validator.\\n */\\ninterface IAggregator {\\n /**\\n * validate aggregated signature.\\n * revert if the aggregated signature does not match the given list of operations.\\n */\\n function validateSignatures(\\n UserOperation[] calldata userOps,\\n bytes calldata signature\\n ) external view;\\n\\n /**\\n * validate signature of a single userOp\\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\\n * @param userOp the userOperation received from the user.\\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\\n * (usually empty, unless account and aggregator support some kind of \\\"multisig\\\"\\n */\\n function validateUserOpSignature(\\n UserOperation calldata userOp\\n ) external view returns (bytes memory sigForUserOp);\\n\\n /**\\n * aggregate multiple signatures into a single value.\\n * This method is called off-chain to calculate the signature to pass with handleOps()\\n * bundler MAY use optimized custom code perform this aggregation\\n * @param userOps array of UserOperations to collect the signatures from.\\n * @return aggregatedSignature the aggregated signature\\n */\\n function aggregateSignatures(\\n UserOperation[] calldata userOps\\n ) external view returns (bytes memory aggregatedSignature);\\n}\\n\",\"keccak256\":\"0xdfdcd80568f037716674619b31be630fcd8316262f05a815b41d1e81782c966a\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IEntryPoint.sol\":{\"content\":\"/**\\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\\n ** Only one instance required on each chain.\\n **/\\n// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-inline-assembly */\\n/* solhint-disable reason-string */\\n\\nimport \\\"./UserOperation.sol\\\";\\nimport \\\"./IStakeManager.sol\\\";\\nimport \\\"./IAggregator.sol\\\";\\nimport \\\"./INonceManager.sol\\\";\\n\\ninterface IEntryPoint is IStakeManager, INonceManager {\\n /***\\n * An event emitted after each successful request\\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\\n * @param sender - the account that generates this request.\\n * @param paymaster - if non-null, the paymaster that pays for this request.\\n * @param nonce - the nonce value from the request.\\n * @param success - true if the sender transaction succeeded, false if reverted.\\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\\n */\\n event UserOperationEvent(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address indexed paymaster,\\n uint256 nonce,\\n bool success,\\n uint256 actualGasCost,\\n uint256 actualGasUsed\\n );\\n\\n /**\\n * account \\\"sender\\\" was deployed.\\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\\n * @param sender the account that is deployed\\n * @param factory the factory used to deploy this account (in the initCode)\\n * @param paymaster the paymaster used by this UserOp\\n */\\n event AccountDeployed(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address factory,\\n address paymaster\\n );\\n\\n /**\\n * An event emitted if the UserOperation \\\"callData\\\" reverted with non-zero length\\n * @param userOpHash the request unique identifier.\\n * @param sender the sender of this request\\n * @param nonce the nonce used in the request\\n * @param revertReason - the return bytes from the (reverted) call to \\\"callData\\\".\\n */\\n event UserOperationRevertReason(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n uint256 nonce,\\n bytes revertReason\\n );\\n\\n /**\\n * an event emitted by handleOps(), before starting the execution loop.\\n * any event emitted before this event, is part of the validation.\\n */\\n event BeforeExecution();\\n\\n /**\\n * signature aggregator used by the following UserOperationEvents within this bundle.\\n */\\n event SignatureAggregatorChanged(address indexed aggregator);\\n\\n /**\\n * a custom revert error of handleOps, to identify the offending op.\\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\\n * @param reason - revert reason\\n * The string starts with a unique code \\\"AAmn\\\", where \\\"m\\\" is \\\"1\\\" for factory, \\\"2\\\" for account and \\\"3\\\" for paymaster issues,\\n * so a failure can be attributed to the correct entity.\\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\\n */\\n error FailedOp(uint256 opIndex, string reason);\\n\\n /**\\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\\n */\\n error SignatureValidationFailed(address aggregator);\\n\\n /**\\n * Successful result from simulateValidation.\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n */\\n error ValidationResult(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo\\n );\\n\\n /**\\n * Successful result from simulateValidation, if the account returns a signature aggregator\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\\n * bundler MUST use it to verify the signature, or reject the UserOperation\\n */\\n error ValidationResultWithAggregation(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo,\\n AggregatorStakeInfo aggregatorInfo\\n );\\n\\n /**\\n * return value of getSenderAddress\\n */\\n error SenderAddressResult(address sender);\\n\\n /**\\n * return value of simulateHandleOp\\n */\\n error ExecutionResult(\\n uint256 preOpGas,\\n uint256 paid,\\n uint48 validAfter,\\n uint48 validUntil,\\n bool targetSuccess,\\n bytes targetResult\\n );\\n\\n //UserOps handled, per aggregator\\n struct UserOpsPerAggregator {\\n UserOperation[] userOps;\\n // aggregator address\\n IAggregator aggregator;\\n // aggregated signature\\n bytes signature;\\n }\\n\\n /**\\n * Execute a batch of UserOperation.\\n * no signature aggregator is used.\\n * if any account requires an aggregator (that is, it returned an aggregator when\\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\\n * @param ops the operations to execute\\n * @param beneficiary the address to receive the fees\\n */\\n function handleOps(\\n UserOperation[] calldata ops,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * Execute a batch of UserOperation with Aggregators\\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\\n * @param beneficiary the address to receive the fees\\n */\\n function handleAggregatedOps(\\n UserOpsPerAggregator[] calldata opsPerAggregator,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * generate a request Id - unique identifier for this request.\\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\\n */\\n function getUserOpHash(\\n UserOperation calldata userOp\\n ) external view returns (bytes32);\\n\\n /**\\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\\n * @param userOp the user operation to validate.\\n */\\n function simulateValidation(UserOperation calldata userOp) external;\\n\\n /**\\n * gas and return values during simulation\\n * @param preOpGas the gas used for validation (including preValidationGas)\\n * @param prefund the required prefund for this operation\\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\\n */\\n struct ReturnInfo {\\n uint256 preOpGas;\\n uint256 prefund;\\n bool sigFailed;\\n uint48 validAfter;\\n uint48 validUntil;\\n bytes paymasterContext;\\n }\\n\\n /**\\n * returned aggregated signature info.\\n * the aggregator returned by the account, and its current stake.\\n */\\n struct AggregatorStakeInfo {\\n address aggregator;\\n StakeInfo stakeInfo;\\n }\\n\\n /**\\n * Get counterfactual sender address.\\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\\n * this method always revert, and returns the address in SenderAddressResult error\\n * @param initCode the constructor code to be passed into the UserOperation.\\n */\\n function getSenderAddress(bytes memory initCode) external;\\n\\n /**\\n * simulate full execution of a UserOperation (including both validation and target execution)\\n * this method will always revert with \\\"ExecutionResult\\\".\\n * it performs full validation of the UserOperation, but ignores signature error.\\n * an optional target address is called after the userop succeeds, and its value is returned\\n * (before the entire call is reverted)\\n * Note that in order to collect the the success/failure of the target call, it must be executed\\n * with trace enabled to track the emitted events.\\n * @param op the UserOperation to simulate\\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\\n * are set to the return from that call.\\n * @param targetCallData callData to pass to target address\\n */\\n function simulateHandleOp(\\n UserOperation calldata op,\\n address target,\\n bytes calldata targetCallData\\n ) external;\\n}\\n\",\"keccak256\":\"0x9ccb1b188eda8bbf5f6c2d01bd83c3d8b2b04fcf745283051d31fe96d1d8e40f\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/INonceManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\ninterface INonceManager {\\n /**\\n * Return the next nonce for this sender.\\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\\n * But UserOp with different keys can come with arbitrary order.\\n *\\n * @param sender the account address\\n * @param key the high 192 bit of the nonce\\n * @return nonce a full nonce to pass for next UserOp with this sender.\\n */\\n function getNonce(\\n address sender,\\n uint192 key\\n ) external view returns (uint256 nonce);\\n\\n /**\\n * Manually increment the nonce of the sender.\\n * This method is exposed just for completeness..\\n * Account does NOT need to call it, neither during validation, nor elsewhere,\\n * as the EntryPoint will update the nonce regardless.\\n * Possible use-case is call it with various keys to \\\"initialize\\\" their nonces to one, so that future\\n * UserOperations will not pay extra for the first transaction with a given key.\\n */\\n function incrementNonce(uint192 key) external;\\n}\\n\",\"keccak256\":\"0xce478ad0fa0d18a3b785ac854623029e7ab463d05873dfaa365abfa1bf100912\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IStakeManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8.12;\\n\\n/**\\n * manage deposits and stakes.\\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\\n * stake is value locked for at least \\\"unstakeDelay\\\" by the staked entity.\\n */\\ninterface IStakeManager {\\n event Deposited(address indexed account, uint256 totalDeposit);\\n\\n event Withdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /// Emitted when stake or unstake delay are modified\\n event StakeLocked(\\n address indexed account,\\n uint256 totalStaked,\\n uint256 unstakeDelaySec\\n );\\n\\n /// Emitted once a stake is scheduled for withdrawal\\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\\n\\n event StakeWithdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /**\\n * @param deposit the entity's deposit\\n * @param staked true if this entity is staked.\\n * @param stake actual amount of ether staked for this entity.\\n * @param unstakeDelaySec minimum delay to withdraw the stake.\\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\\n * and the rest fit into a 2nd cell.\\n * 112 bit allows for 10^15 eth\\n * 48 bit for full timestamp\\n * 32 bit allows 150 years for unstake delay\\n */\\n struct DepositInfo {\\n uint112 deposit;\\n bool staked;\\n uint112 stake;\\n uint32 unstakeDelaySec;\\n uint48 withdrawTime;\\n }\\n\\n //API struct used by getStakeInfo and simulateValidation\\n struct StakeInfo {\\n uint256 stake;\\n uint256 unstakeDelaySec;\\n }\\n\\n /// @return info - full deposit information of given account\\n function getDepositInfo(\\n address account\\n ) external view returns (DepositInfo memory info);\\n\\n /// @return the deposit (for gas payment) of the account\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * add to the deposit of the given account\\n */\\n function depositTo(address account) external payable;\\n\\n /**\\n * add to the account's stake - amount and delay\\n * any pending unstake is first cancelled.\\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\\n */\\n function addStake(uint32 _unstakeDelaySec) external payable;\\n\\n /**\\n * attempt to unlock the stake.\\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\\n */\\n function unlockStake() external;\\n\\n /**\\n * withdraw from the (unlocked) stake.\\n * must first call unlockStake and wait for the unstakeDelay to pass\\n * @param withdrawAddress the address to send withdrawn value.\\n */\\n function withdrawStake(address payable withdrawAddress) external;\\n\\n /**\\n * withdraw from the deposit.\\n * @param withdrawAddress the address to send withdrawn value.\\n * @param withdrawAmount the amount to withdraw.\\n */\\n function withdrawTo(\\n address payable withdrawAddress,\\n uint256 withdrawAmount\\n ) external;\\n}\\n\",\"keccak256\":\"0xadcea606c9b7aafe6645441f2154a60f271330b0eee5292a632aa71c1672d546\",\"license\":\"GPL-3.0-only\"},\"contracts/aa-4337/interfaces/UserOperation.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable no-inline-assembly */\\n\\nimport {calldataKeccak} from \\\"../core/Helpers.sol\\\";\\n\\n/**\\n * User Operation struct\\n * @param sender the sender account of this request.\\n * @param nonce unique value the sender uses to verify it is not a replay.\\n * @param initCode if set, the account contract will be created by this constructor/\\n * @param callData the method call to execute on this account.\\n * @param callGasLimit the gas limit passed to the callData method call.\\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\\n * @param maxFeePerGas same as EIP-1559 gas parameter.\\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\\n */\\nstruct UserOperation {\\n address sender;\\n uint256 nonce;\\n bytes initCode;\\n bytes callData;\\n uint256 callGasLimit;\\n uint256 verificationGasLimit;\\n uint256 preVerificationGas;\\n uint256 maxFeePerGas;\\n uint256 maxPriorityFeePerGas;\\n bytes paymasterAndData;\\n bytes signature;\\n}\\n\\n/**\\n * Utility functions helpful when working with UserOperation structs.\\n */\\nlibrary UserOperationLib {\\n function getSender(\\n UserOperation calldata userOp\\n ) internal pure returns (address) {\\n address data;\\n //read sender from userOp, which is first userOp member (saves 800 gas...)\\n assembly {\\n data := calldataload(userOp)\\n }\\n return address(uint160(data));\\n }\\n\\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\\n // pay above what he signed for.\\n function gasPrice(\\n UserOperation calldata userOp\\n ) internal view returns (uint256) {\\n unchecked {\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n if (maxFeePerGas == maxPriorityFeePerGas) {\\n //legacy mode (for networks that don't support basefee opcode)\\n return maxFeePerGas;\\n }\\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\\n }\\n }\\n\\n function pack(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes memory ret) {\\n address sender = getSender(userOp);\\n uint256 nonce = userOp.nonce;\\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\\n bytes32 hashCallData = calldataKeccak(userOp.callData);\\n uint256 callGasLimit = userOp.callGasLimit;\\n uint256 verificationGasLimit = userOp.verificationGasLimit;\\n uint256 preVerificationGas = userOp.preVerificationGas;\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\\n\\n return\\n abi.encode(\\n sender,\\n nonce,\\n hashInitCode,\\n hashCallData,\\n callGasLimit,\\n verificationGasLimit,\\n preVerificationGas,\\n maxFeePerGas,\\n maxPriorityFeePerGas,\\n hashPaymasterAndData\\n );\\n }\\n\\n function hash(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes32) {\\n return keccak256(pack(userOp));\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n}\\n\",\"keccak256\":\"0x2429f5cc546bdee08c7e63858d0dda8491eaa3ab5194df884dc948c1154d2834\",\"license\":\"GPL-3.0\"},\"contracts/facets/AccountFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {ECDSA} from \\\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\\\";\\nimport {UserOperation} from \\\"../aa-4337/interfaces/UserOperation.sol\\\";\\nimport {IEntryPoint} from \\\"../aa-4337/interfaces/IEntryPoint.sol\\\";\\nimport {BaseAccount} from \\\"../aa-4337/core/BaseAccount.sol\\\";\\nimport {LibAppStorage, BarzStorage} from \\\"../libraries/LibAppStorage.sol\\\";\\nimport {LibDiamond} from \\\"../libraries/LibDiamond.sol\\\";\\nimport {LibLoupe} from \\\"../libraries/LibLoupe.sol\\\";\\nimport {IFacetRegistry} from \\\"../infrastructure/interfaces/IFacetRegistry.sol\\\";\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\nimport {IVerificationFacet} from \\\"./interfaces/IVerificationFacet.sol\\\";\\nimport {IERC1271} from \\\"../interfaces/ERC/IERC1271.sol\\\";\\nimport {IAccountFacet} from \\\"./interfaces/IAccountFacet.sol\\\";\\n\\n/**\\n * @title Account Facet\\n * @dev Account module contract that provides the account features and initialization of signer\\n * compatible with EIP-1271 & EIP-4337\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract AccountFacet is IAccountFacet, BarzStorage, BaseAccount {\\n using ECDSA for bytes32;\\n\\n /**\\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\\n */\\n constructor() {\\n LibAppStorage.enforceAccountInitialize();\\n }\\n\\n /**\\n * @notice Returns the address of EntryPoint contract registered to Barz account\\n */\\n function entryPoint() public view override returns (IEntryPoint) {\\n return s.entryPoint;\\n }\\n\\n /**\\n * @notice Initializes the initial storage of the Barz contract.\\n * @dev This method can only be called during the initialization or signature migration.\\n * If the proxy contract was created without initialization, anyone can call initialize.\\n * Barz calls initialize in constructor in an atomic transaction during deployment\\n * @param _verificationFacet Facet contract handling the verificationi\\n * @param _anEntryPoint Entrypoint contract defined in EIP-4337 handling the flow of UserOp\\n * @param _facetRegistry Registry of Facets that hold all facet information\\n * @param _defaultFallBackHandler Middleware contract for default facets\\n * @param _ownerPublicKey Bytes of owner public key\\n */\\n function initialize(\\n address _verificationFacet,\\n address _anEntryPoint,\\n address _facetRegistry,\\n address _defaultFallBackHandler,\\n bytes calldata _ownerPublicKey\\n ) public override returns (uint256 initSuccess) {\\n LibAppStorage.enforceAccountInitialize();\\n s.entryPoint = IEntryPoint(_anEntryPoint);\\n s.facetRegistry = IFacetRegistry(_facetRegistry);\\n LibDiamond.diamondStorage().defaultFallbackHandler = IDiamondLoupe(\\n _defaultFallBackHandler\\n );\\n\\n _cutDiamondAccountFacet(_verificationFacet);\\n\\n bytes memory initCall = abi.encodeWithSignature(\\n \\\"initializeSigner(bytes)\\\",\\n _ownerPublicKey\\n );\\n // Every Verification Facet should comply with initializeSigner(bytes)\\n // to be compatible with the Barz contract(for initialization)\\n (bool success, bytes memory result) = _verificationFacet.delegatecall(\\n initCall\\n );\\n if (!success || uint256(bytes32(result)) != 1) {\\n revert AccountFacet__InitializationFailure();\\n }\\n\\n initSuccess = 1;\\n emit AccountInitialized(s.entryPoint, _ownerPublicKey);\\n }\\n\\n function _cutDiamondAccountFacet(address _verificationFacet) internal {\\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](1);\\n\\n bytes4 ownerVerificationFuncSelector = IVerificationFacet(\\n _verificationFacet\\n ).validateOwnerSignatureSelector();\\n\\n bytes4[] memory verificationFunctionSelectors = new bytes4[](3);\\n verificationFunctionSelectors[0] = IERC1271.isValidSignature.selector;\\n verificationFunctionSelectors[1] = ownerVerificationFuncSelector;\\n verificationFunctionSelectors[2] = IVerificationFacet.owner.selector;\\n cut[0] = IDiamondCut.FacetCut({\\n facetAddress: _verificationFacet,\\n action: IDiamondCut.FacetCutAction.Add,\\n functionSelectors: verificationFunctionSelectors\\n });\\n\\n LibDiamond.diamondCut(cut, address(0), \\\"\\\");\\n }\\n\\n /**\\n * @notice Calls the destination with inputted calldata and value from EntryPoint\\n * @dev This method executes the calldata coming from the EntryPoint.\\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\\n * @param _dest Address of destination where the call will be forwarded to\\n * @param _value Amount of native coin the owner is willing to send(e.g. ETH, BNB)\\n * @param _func Bytes of calldata to execute in the destination address\\n */\\n function execute(\\n address _dest,\\n uint256 _value,\\n bytes calldata _func\\n ) external override onlyWhenUnlocked {\\n _requireFromEntryPoint();\\n address restrictionsFacet = LibDiamond.restrictionsFacet();\\n if (restrictionsFacet == address(0)) _call(_dest, _value, _func);\\n else _callWithRestrictions(_dest, _value, _func, restrictionsFacet);\\n }\\n\\n /**\\n * @notice Batch calls the destination with inputted calldata and value from EntryPoint\\n * @dev This method batch executes the calldata coming from the EntryPoint.\\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\\n * @param _dest Array of addresses of destination where the call will be forwarded to\\n * @param _value Array of amount of native coin the owner is willing to send(e.g. ETH, BNB)\\n * @param _func Array of bytes of calldata to execute in the destination address\\n */\\n function executeBatch(\\n address[] calldata _dest,\\n uint256[] calldata _value,\\n bytes[] calldata _func\\n ) external override onlyWhenUnlocked {\\n _requireFromEntryPoint();\\n if (_dest.length != _func.length || _dest.length != _value.length)\\n revert AccountFacet__InvalidArrayLength();\\n address restrictionsFacet = LibDiamond.restrictionsFacet();\\n if (restrictionsFacet == address(0)) {\\n for (uint256 i; i < _dest.length; ) {\\n _call(_dest[i], _value[i], _func[i]);\\n unchecked {\\n ++i;\\n }\\n }\\n } else {\\n for (uint256 i; i < _dest.length; ) {\\n _callWithRestrictions(\\n _dest[i],\\n _value[i],\\n _func[i],\\n restrictionsFacet\\n );\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n }\\n\\n /**\\n * @notice Validates the signature field of UserOperation\\n * @dev This method validates if the signature of UserOp is indeed valid by delegating the call to Verification Facet\\n * Barz makes a call to the pre-registered Verification Facet address in App Storage\\n * @param _userOp UserOperation from owner to be validated\\n * @param _userOpHash Hash of UserOperation given from the EntryPoint contract\\n */\\n function _validateSignature(\\n UserOperation calldata _userOp,\\n bytes32 _userOpHash\\n ) internal override returns (uint256 validationData) {\\n // Get Facet with Function Selector\\n address facet = LibLoupe.facetAddress(s.validateOwnerSignatureSelector);\\n if (facet == address(0))\\n revert AccountFacet__NonExistentVerificationFacet();\\n\\n // Make function call to VerificationFacet\\n bytes memory validateCall = abi.encodeWithSelector(\\n s.validateOwnerSignatureSelector,\\n _userOp,\\n _userOpHash\\n );\\n (bool success, bytes memory result) = facet.delegatecall(validateCall);\\n if (!success) revert AccountFacet__CallNotSuccessful();\\n validationData = uint256(bytes32(result));\\n if (validationData == 0) emit VerificationSuccess(_userOpHash);\\n else emit VerificationFailure(_userOpHash);\\n }\\n\\n /**\\n * @notice Calls the target with the inputted value and calldata\\n * @dev This method is the actual function in Barz that makes a call with an arbitrary owner-given data\\n * @param _target Address of the destination contract which the call is getting forwarded to\\n * @param _value Amount of Native coin the owner is wanting to make in this call\\n * @param _data Calldata the owner is forwarding together in the call e.g. Swap/Token Transfer\\n */\\n function _call(\\n address _target,\\n uint256 _value,\\n bytes memory _data\\n ) internal {\\n (bool success, bytes memory result) = _target.call{value: _value}(\\n _data\\n );\\n if (!success) {\\n assembly {\\n revert(add(result, 32), mload(result))\\n }\\n }\\n }\\n\\n /**\\n * @notice Calls the target with the inputted value and calldata together with restrictions check\\n * @dev This method is the actual function in Barz that makes a call with an arbitrary owner-given data\\n * @param _target Address of the destination contract which the call is getting forwarded to\\n * @param _value Amount of Native coin the owner is wanting to make in this call\\n * @param _data Calldata the owner is forwarding together in the call e.g. Swap/Token Transfer\\n * @param _restrictionsFacet Address of Facet to validate restrictions\\n */\\n function _callWithRestrictions(\\n address _target,\\n uint256 _value,\\n bytes memory _data,\\n address _restrictionsFacet\\n ) internal {\\n // NOTE: No restrictions facet, so restriction validation passes\\n if (_checkRestrictions(_restrictionsFacet, _target, _value, _data) != 0)\\n revert AccountFacet__RestrictionsFailure();\\n\\n (bool success, bytes memory result) = _target.call{value: _value}(\\n _data\\n );\\n if (!success) {\\n assembly {\\n revert(add(result, 32), mload(result))\\n }\\n }\\n }\\n\\n /**\\n * @notice Checks restrictions if the restrictions facet exists\\n * @dev This method checks if the restrictions facet exists and makes a verification call to an array of restrictions facet\\n * @param _facet Address that holds the restrictions logic\\n * @param _target Address the call is getting forwarded to\\n * @param _value Amount of native coin the call is sending together with the call\\n * @param _data Calldata to trigger execution in target address\\n */\\n function _checkRestrictions(\\n address _facet,\\n address _target,\\n uint256 _value,\\n bytes memory _data\\n ) internal returns (uint256 result) {\\n bytes memory call = abi.encodeWithSignature(\\n \\\"verifyRestrictions(address,address,uint256,bytes)\\\",\\n address(this),\\n _target,\\n _value,\\n _data\\n );\\n (bool success, bytes memory response) = _facet.delegatecall(call);\\n if (!success) revert AccountFacet__RestrictionsFailure();\\n result = uint256(bytes32(response));\\n }\\n}\\n\",\"keccak256\":\"0xcd92bcdd447010880f78e57e213123269c9e023adfc0a540608daa127d8649ca\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/facets/interfaces/IAccountFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IEntryPoint} from \\\"../../aa-4337/interfaces/IEntryPoint.sol\\\";\\n\\n/**\\n * @title Account Facet Interface\\n * @dev Interface of module contract that provides the account features and init/unitialization of signer\\n * compatible with EIP-1271 & EIP-4337\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IAccountFacet {\\n event AccountInitialized(\\n IEntryPoint indexed entryPoint,\\n bytes indexed ownerPublicKey\\n );\\n // NOTE: Added Below Event\\n event VerificationSuccess(bytes32);\\n event VerificationFailure(bytes32);\\n\\n error AccountFacet__InitializationFailure();\\n error AccountFacet__RestrictionsFailure();\\n error AccountFacet__NonExistentVerificationFacet();\\n error AccountFacet__CallNotSuccessful();\\n error AccountFacet__InvalidArrayLength();\\n\\n function initialize(\\n address verificationFacet,\\n address anEntryPoint,\\n address facetRegistry,\\n address _defaultFallBack,\\n bytes calldata _ownerPublicKey\\n ) external returns (uint256);\\n\\n function execute(address dest, uint256 value, bytes calldata func) external;\\n\\n function executeBatch(\\n address[] calldata dest,\\n uint256[] calldata value,\\n bytes[] calldata func\\n ) external;\\n}\\n\",\"keccak256\":\"0x74a9cb0b8f2f4a5148e366a401a0354426c536c012c025025d07cc25a4cd5382\",\"license\":\"Apache-2.0\"},\"contracts/facets/interfaces/IVerificationFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {UserOperation} from \\\"../../aa-4337/interfaces/UserOperation.sol\\\";\\n\\n/**\\n * @title Verification Facet Interface\\n * @dev Implements logic for user ops signature verification\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\ninterface IVerificationFacet {\\n event SignerInitialized(bytes);\\n event SignerUninitialized();\\n\\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\\n error VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\\n error VerificationFacet__InitializationFailure();\\n error VerificationFacet__InvalidFacetMapping();\\n\\n function initializeSigner(bytes memory) external returns (uint256);\\n\\n function uninitializeSigner() external returns (uint256);\\n\\n function validateOwnerSignatureSelector() external view returns (bytes4);\\n\\n function owner() external view returns (bytes memory);\\n\\n function isValidKeyType(bytes calldata) external view returns (bool);\\n\\n function validateOwnerSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x72bc370a1d1b5a6d6bde67f5026733fd8f6ba434bb90e73b0bd8627fb1579928\",\"license\":\"Apache-2.0\"},\"contracts/infrastructure/interfaces/IFacetRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Registry Interface\\n * @dev Interface for Facet Registry contract to keep track of facets & function selectors addable to user wallets\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IFacetRegistry {\\n struct FacetRegistryConfig {\\n bytes4[] selectors;\\n mapping(bytes4 => FacetInfo) info;\\n }\\n struct FacetInfo {\\n bool exists;\\n uint128 index;\\n }\\n\\n event FacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] facetSelectors\\n );\\n event FacetFunctionSelectorsRemoved(address facet, bytes4[] facetSelectors);\\n\\n error FacetRegistry__FacetSelectorAlreadyRegistered();\\n error FacetRegistry__UnregisteredFacetSelector();\\n\\n function registerFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function removeFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function areFacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external view returns (bool);\\n\\n function isFacetFunctionSelectorRegistered(\\n address facet,\\n bytes4 facetSelector\\n ) external view returns (bool);\\n\\n function getFacetFunctionSelectors(\\n address facet\\n ) external view returns (bytes4[] memory);\\n}\\n\",\"keccak256\":\"0x6e6dd2cab346ef7c31230740ec48d2925e4a9ab24c2f2fb268baaf408dcf02ef\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC1271 {\\n function isValidSignature(\\n bytes32 hash,\\n bytes memory signature\\n ) external view returns (bytes4);\\n}\\n\",\"keccak256\":\"0xcdddb7d5641c9d3f2432dec7fd13fddb9ae1480f25c76c21511e2fa16b8bd422\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibAppStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {SafeCast} from \\\"@openzeppelin/contracts/utils/math/SafeCast.sol\\\";\\nimport {IEntryPoint} from \\\"../aa-4337/interfaces/IEntryPoint.sol\\\";\\nimport {IFacetRegistry} from \\\"../infrastructure/interfaces/IFacetRegistry.sol\\\";\\n\\n/*\\n * @title App Storage\\n * @dev App storage for Barz contract to prevent storage collision\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Lock {\\n uint64 release;\\n bytes4 locker;\\n}\\n\\nstruct InitializersStorage {\\n // NOTE: initialized is a variable to make sure the initialization is only done once.\\n uint8 signerInitialized;\\n uint8 accountInitialized;\\n uint8 restrictionsInitialized;\\n}\\n\\nstruct AppStorage {\\n mapping(uint256 => InitializersStorage) initStorage;\\n uint8 signerMigration;\\n bytes4 validateOwnerSignatureSelector;\\n IEntryPoint entryPoint;\\n IFacetRegistry facetRegistry;\\n mapping(uint256 => Lock) locks;\\n}\\n\\nlibrary LibAppStorage {\\n error LibAppStorage__AccountAlreadyUninitialized();\\n error LibAppStorage__AccountMustBeUninitialized();\\n error LibAppStorage__SignerAlreadyUninitialized();\\n error LibAppStorage__SignerMustBeUninitialized();\\n\\n function appStorage() internal pure returns (AppStorage storage ds) {\\n assembly {\\n ds.slot := 0\\n }\\n }\\n\\n function setSignerUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerAlreadyUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 0;\\n }\\n\\n function getValidateOwnerSignatureSelector()\\n internal\\n view\\n returns (bytes4 selector)\\n {\\n selector = appStorage().validateOwnerSignatureSelector;\\n }\\n\\n function setValidateOwnerSignatureSelector(\\n bytes4 _validateOwnerSignatureSelector\\n ) internal {\\n appStorage()\\n .validateOwnerSignatureSelector = _validateOwnerSignatureSelector;\\n }\\n\\n function enforceSignerInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerMustBeUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 1;\\n }\\n\\n function enforceAccountInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].accountInitialized) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n s.initStorage[0].accountInitialized = 1;\\n }\\n\\n function initiateSignerMigration() internal {\\n appStorage().signerMigration = 1;\\n }\\n\\n function enforceSignerMigration() internal view {\\n if (1 != appStorage().signerMigration) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n }\\n\\n function finalizeSignerMigration() internal {\\n appStorage().signerMigration = 0;\\n }\\n\\n function setLock(uint256 _releaseAfter, bytes4 _locker) internal {\\n appStorage().locks[0] = Lock(SafeCast.toUint64(_releaseAfter), _locker);\\n }\\n\\n function enforceRestrictionsInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__SignerMustBeUninitialized();\\n s.initStorage[0].restrictionsInitialized = 1;\\n }\\n\\n function setRestrictionsUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__AccountAlreadyUninitialized();\\n s.initStorage[0].restrictionsInitialized = 0;\\n }\\n}\\n\\ncontract BarzStorage {\\n AppStorage internal s;\\n modifier onlyWhenUnlocked() {\\n require(\\n uint64(block.timestamp) >= s.locks[0].release,\\n \\\"Account Locked\\\"\\n );\\n _;\\n }\\n modifier onlyWhenLocked() {\\n require(\\n uint64(block.timestamp) < s.locks[0].release,\\n \\\"Account Unlocked\\\"\\n );\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x48524007862a6ce0e07f645950613ce6513ce073c37a109c75019683d42bae27\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\\n bytes4(keccak256(\\\"verifyRestrictions(address,address,uint256,bytes)\\\"));\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // Default Fallback Handler of the barz.\\n IDiamondLoupe defaultFallbackHandler;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function enforceIsSelf() internal view {\\n require(msg.sender == address(this), \\\"LibDiamond: Caller not self\\\");\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n\\n unchecked {\\n facetIndex++;\\n }\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n\\n function restrictionsFacet() internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(\\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2cabdc00de859c3a3170ce3bda5d0e5fd3933d47ce904fd1585f9818b02572f8\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\nimport {LibDiamond} from \\\"./LibDiamond.sol\\\";\\n\\n/**\\n * @title LibLoupe\\n * @dev Internal Library to provide utility feature for reading the state of diamond facets\\n * Originally from Diamond's implementation of Mudgen(author of EIP-2535)\\n */\\nlibrary LibLoupe {\\n /// @notice Gets all facets and their selectors.\\n /// @return facets_ Facet\\n function facets()\\n internal\\n view\\n returns (IDiamondLoupe.Facet[] memory facets_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facets_ = new IDiamondLoupe.Facet[](ds.selectorCount);\\n uint16[] memory numFacetSelectors = new uint16[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facets_[facetIndex].facetAddress == facetAddress_) {\\n facets_[facetIndex].functionSelectors[\\n numFacetSelectors[facetIndex]\\n ] = selector;\\n // probably will never have more than 256 functions from one facet contract\\n require(numFacetSelectors[facetIndex] < 255);\\n numFacetSelectors[facetIndex]++;\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facets_[numFacets].facetAddress = facetAddress_;\\n facets_[numFacets].functionSelectors = new bytes4[](\\n ds.selectorCount\\n );\\n facets_[numFacets].functionSelectors[0] = selector;\\n numFacetSelectors[numFacets] = 1;\\n numFacets++;\\n }\\n }\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n uint256 numSelectors = numFacetSelectors[facetIndex];\\n bytes4[] memory selectors = facets_[facetIndex].functionSelectors;\\n // setting the number of selectors\\n assembly {\\n mstore(selectors, numSelectors)\\n }\\n }\\n // setting the number of facets\\n assembly {\\n mstore(facets_, numFacets)\\n }\\n }\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return _facetFunctionSelectors The selectors associated with a facet address.\\n function facetFunctionSelectors(\\n address _facet\\n ) internal view returns (bytes4[] memory _facetFunctionSelectors) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n uint256 numSelectors;\\n _facetFunctionSelectors = new bytes4[](ds.selectorCount);\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facet = address(bytes20(ds.facets[selector]));\\n if (_facet == facet) {\\n _facetFunctionSelectors[numSelectors] = selector;\\n numSelectors++;\\n }\\n }\\n }\\n // Set the number of selectors in the array\\n assembly {\\n mstore(_facetFunctionSelectors, numSelectors)\\n }\\n }\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n internal\\n view\\n returns (address[] memory facetAddresses_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetAddresses_ = new address[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facetAddress_ == facetAddresses_[facetIndex]) {\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facetAddresses_[numFacets] = facetAddress_;\\n numFacets++;\\n }\\n }\\n // Set the number of facet addresses in the array\\n assembly {\\n mstore(facetAddresses_, numFacets)\\n }\\n }\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(LibDiamond.diamondStorage().facets[_functionSelector])\\n );\\n }\\n}\\n\",\"keccak256\":\"0x0b11439c3cc657095e15ec2241fdcf67204b14001357b612fc5db4ff9e760a5a\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5061001961001e565b61008e565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb554610100900460ff1615610070576040516338fc28cb60e01b815260040160405180910390fd5b600080805260209190915260409020805461ff001916610100179055565b6129b6806200009e6000396000f3fe608060405234801561001057600080fd5b50600436106100725760003560e01c8063b0d691fe11610050578063b0d691fe146100c5578063b61d27f61461010c578063d087d2881461011f57600080fd5b80633a871cdd1461007757806347e1da2a1461009d5780634a936417146100b2575b600080fd5b61008a610085366004611fb5565b610127565b6040519081526020015b60405180910390f35b6100b06100ab366004612055565b61014d565b005b61008a6100c036600461215a565b610450565b60015465010000000000900473ffffffffffffffffffffffffffffffffffffffff1660405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610094565b6100b061011a3660046121ce565b6106d0565b61008a61089d565b600061013161095e565b61013b8484610a16565b905061014682610c5d565b9392505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff9081164290911610156101f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064015b60405180910390fd5b6101fd61095e565b848114158061020c5750848314155b15610243576040517fdde5716100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006102b87fac87185d000000000000000000000000000000000000000000000000000000006000527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020527f6d9f2463c8c0d8cb8be556a773ab21d4321328909a1725f2ef7cae0c320e95da5460601c90565b905073ffffffffffffffffffffffffffffffffffffffff811661038f5760005b86811015610389576103818888838181106102f5576102f5612228565b905060200201602081019061030a9190612257565b87878481811061031c5761031c612228565b9050602002013586868581811061033557610335612228565b90506020028101906103479190612272565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610cc892505050565b6001016102d8565b50610447565b60005b868110156104455761043d8888838181106103af576103af612228565b90506020020160208101906103c49190612257565b8787848181106103d6576103d6612228565b905060200201358686858181106103ef576103ef612228565b90506020028101906104019190612272565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250889250610d45915050565b600101610392565b505b50505050505050565b600061045a610e0d565b6001805473ffffffffffffffffffffffffffffffffffffffff88811665010000000000027fffffffffffffff0000000000000000000000000000000000000000ffffffffff90921691909117909155600280548783167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216179091557f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd492380549287169290911691909117905561051187610eb3565b60008383604051602401610526929190612320565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fcd9b47e40000000000000000000000000000000000000000000000000000000017905251909150600090819073ffffffffffffffffffffffffffffffffffffffff8b16906105c8908590612360565b600060405180830381855af49150503d8060008114610603576040519150601f19603f3d011682016040523d82523d6000602084013e610608565b606091505b5091509150811580610623575061061e8161237c565b600114155b1561065a576040517f1602372100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60019350858560405161066e9291906123c1565b60405190819003812060015490916501000000000090910473ffffffffffffffffffffffffffffffffffffffff16907fd429ff0b972be4ae725700a373d05007287994e4c86cb83315b43ffa85b595fd90600090a35050509695505050505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610773576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064016101ec565b61077b61095e565b60006107f07fac87185d000000000000000000000000000000000000000000000000000000006000527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020527f6d9f2463c8c0d8cb8be556a773ab21d4321328909a1725f2ef7cae0c320e95da5460601c90565b905073ffffffffffffffffffffffffffffffffffffffff81166108535761084e858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610cc892505050565b610896565b610896858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250879250610d45915050565b5050505050565b60015460009065010000000000900473ffffffffffffffffffffffffffffffffffffffff166040517f35567e1a0000000000000000000000000000000000000000000000000000000081523060048201526000602482015273ffffffffffffffffffffffffffffffffffffffff91909116906335567e1a90604401602060405180830381865afa158015610935573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061095991906123d1565b905090565b60015465010000000000900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a14576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f6163636f756e743a206e6f742066726f6d20456e747279506f696e740000000060448201526064016101ec565b565b600154610100900460e01b7fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604081205460601c80610aab576040517f6eb2360200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600154604051600091610100900460e01b90610acd908790879060240161244e565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090506000808373ffffffffffffffffffffffffffffffffffffffff1683604051610b549190612360565b600060405180830381855af49150503d8060008114610b8f576040519150601f19603f3d011682016040523d82523d6000602084013e610b94565b606091505b509150915081610bd0576040517f3cbbb65000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610bd98161237c565b94506000859003610c1c576040518681527f19e781916118c373dadcb7776fae0a2dbb6bbdeedae143ce68031e22801ef8659060200160405180910390a1610c50565b6040518681527fbbfee2df7f28b899771f1015dc85d7840ff9f6162f23f6aa99686e8fbd2ce1319060200160405180910390a15b5050505092915050565b50565b8015610c5a5760405160009033907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90849084818181858888f193505050503d8060008114610896576040519150601f19603f3d011682016040523d82523d6000602084013e610896565b6000808473ffffffffffffffffffffffffffffffffffffffff168484604051610cf19190612360565b60006040518083038185875af1925050503d8060008114610d2e576040519150601f19603f3d011682016040523d82523d6000602084013e610d33565b606091505b50915091508161089657805160208201fd5b610d5181858585611117565b15610d88576040517f01f595e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000808573ffffffffffffffffffffffffffffffffffffffff168585604051610db19190612360565b60006040518083038185875af1925050503d8060008114610dee576040519150601f19603f3d011682016040523d82523d6000602084013e610df3565b606091505b509150915081610e0557805160208201fd5b505050505050565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb554610100900460ff1615610e78576040517f38fc28cb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100179055565b604080516001808252818301909252600091816020015b60408051606080820183526000808352602083015291810191909152815260200190600190039081610eca57905050905060008273ffffffffffffffffffffffffffffffffffffffff16633253960f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f6c9190612592565b604080516003808252608082019092529192506000919060208201606080368337019050509050631626ba7e60e01b81600081518110610fae57610fae612228565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681525050818160018151811061100e5761100e612228565b7fffffffff000000000000000000000000000000000000000000000000000000009092166020928302919091019091015280517f8da5cb5b00000000000000000000000000000000000000000000000000000000908290600290811061107657611076612228565b7fffffffff00000000000000000000000000000000000000000000000000000000909216602092830291909101820152604080516060810190915273ffffffffffffffffffffffffffffffffffffffff861681529081016000815260200182815250836000815181106110eb576110eb612228565b602002602001018190525061111183600060405180602001604052806000815250611264565b50505050565b60008030858585604051602401611131949392919061264d565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fac87185d0000000000000000000000000000000000000000000000000000000017905251909150600090819073ffffffffffffffffffffffffffffffffffffffff8916906111d3908590612360565b600060405180830381855af49150503d806000811461120e576040519150601f19603f3d011682016040523d82523d6000602084013e611213565b606091505b50915091508161124f576040517f01f595e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6112588161237c565b98975050505050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921547f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff8116908190600090600716156112d35750600381901c60009081526001840160205260409020545b60005b87518110156113505761134383838a84815181106112f6576112f6612228565b6020026020010151600001518b858151811061131457611314612228565b6020026020010151602001518c868151811061133257611332612228565b6020026020010151604001516113f0565b90935091506001016112d6565b50828214611389576002840180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff84161790555b60078216156113ab57600382901c600090815260018501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb6738787876040516113de93929190612696565b60405180910390a16104478686611e81565b600080807f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f905060008451116114a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f2063757400000000000000000000000000000000000000000060648201526084016101ec565b60008560028111156114bc576114bc6125d4565b0361168c576114e38660405180606001604052806024815260200161290d60249139611f7a565b60005b845181101561168657600085828151811061150357611503612228565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c156115d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c726561647920657869737473000000000000000000000060648201526084016101ec565b7fffffffff0000000000000000000000000000000000000000000000000000000080831660008181526020879052604090207fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608d901b168e17905560e060058e901b811692831c199c909c1690821c179a81900361166a5760038c901c600090815260018601602052604081209b909b555b8b6116748161282d565b9c5050600190930192506114e6915050565b50611e75565b60018560028111156116a0576116a06125d4565b03611990576116c78660405180606001604052806028815260200161295960289139611f7a565b60005b84518110156116865760008582815181106116e7576116e7612228565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c3081036117bc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4c69624469616d6f6e644375743a2043616e2774207265706c61636520696d6d60448201527f757461626c652066756e6374696f6e000000000000000000000000000000000060648201526084016101ec565b8973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611877576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e000000000000000060648201526084016101ec565b73ffffffffffffffffffffffffffffffffffffffff811661191a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e207468617420646f65736e2774206578697374000000000000000060648201526084016101ec565b507fffffffff0000000000000000000000000000000000000000000000000000000090911660009081526020849052604090206bffffffffffffffffffffffff919091167fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608a901b161790556001016116ca565b60028560028111156119a4576119a46125d4565b03611ded5773ffffffffffffffffffffffffffffffffffffffff861615611a4d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d75737420626520616464726573732830290000000000000000000060648201526084016101ec565b600388901c6007891660005b8651811015611dcd5760008a9003611a955782611a7581612865565b60008181526001870160205260409020549b50935060079250611aa39050565b81611a9f81612865565b9250505b6000806000808a8581518110611abb57611abb612228565b6020908102919091018101517fffffffff0000000000000000000000000000000000000000000000000000000081166000908152918a9052604090912054909150606081901c611b8d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e277420657869737400000000000000000060648201526084016101ec565b30606082901c03611c20576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e00000000000000000000000000000000000060648201526084016101ec565b600587901b8f901b94507fffffffff0000000000000000000000000000000000000000000000000000000080861690831614611cbe577fffffffff000000000000000000000000000000000000000000000000000000008516600090815260208a90526040902080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff83161790555b7fffffffff0000000000000000000000000000000000000000000000000000000091909116600090815260208990526040812055600381901c611fff16925060051b60e0169050858214611d53576000828152600188016020526040902080547fffffffff0000000000000000000000000000000000000000000000000000000080841c19909116908516831c179055611da4565b80837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c817fffffffff0000000000000000000000000000000000000000000000000000000060001b901c198e16179c505b84600003611dc257600086815260018801602052604081208190559c505b505050600101611a59565b5080611dda83600861289a565b611de491906128b7565b99505050611e75565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560448201527f74416374696f6e0000000000000000000000000000000000000000000000000060648201526084016101ec565b50959694955050505050565b73ffffffffffffffffffffffffffffffffffffffff8216611ea0575050565b611ec28260405180606001604052806028815260200161293160289139611f7a565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051611eea9190612360565b600060405180830381855af49150503d8060008114611f25576040519150601f19603f3d011682016040523d82523d6000602084013e611f2a565b606091505b50915091508161111157805115611f445780518082602001fd5b83836040517f192105d70000000000000000000000000000000000000000000000000000000081526004016101ec9291906128ca565b813b8181611111576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101ec91906128f9565b600080600060608486031215611fca57600080fd5b833567ffffffffffffffff811115611fe157600080fd5b84016101608187031215611ff457600080fd5b95602085013595506040909401359392505050565b60008083601f84011261201b57600080fd5b50813567ffffffffffffffff81111561203357600080fd5b6020830191508360208260051b850101111561204e57600080fd5b9250929050565b6000806000806000806060878903121561206e57600080fd5b863567ffffffffffffffff8082111561208657600080fd5b6120928a838b01612009565b909850965060208901359150808211156120ab57600080fd5b6120b78a838b01612009565b909650945060408901359150808211156120d057600080fd5b506120dd89828a01612009565b979a9699509497509295939492505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461211357600080fd5b919050565b60008083601f84011261212a57600080fd5b50813567ffffffffffffffff81111561214257600080fd5b60208301915083602082850101111561204e57600080fd5b60008060008060008060a0878903121561217357600080fd5b61217c876120ef565b955061218a602088016120ef565b9450612198604088016120ef565b93506121a6606088016120ef565b9250608087013567ffffffffffffffff8111156121c257600080fd5b6120dd89828a01612118565b600080600080606085870312156121e457600080fd5b6121ed856120ef565b935060208501359250604085013567ffffffffffffffff81111561221057600080fd5b61221c87828801612118565b95989497509550505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561226957600080fd5b610146826120ef565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126122a757600080fd5b83018035915067ffffffffffffffff8211156122c257600080fd5b60200191503681900382131561204e57600080fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b6020815260006123346020830184866122d7565b949350505050565b60005b8381101561235757818101518382015260200161233f565b50506000910152565b6000825161237281846020870161233c565b9190910192915050565b805160208083015191908110156123bb577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8160200360031b1b821691505b50919050565b8183823760009101908152919050565b6000602082840312156123e357600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261241f57600080fd5b830160208101925035905067ffffffffffffffff81111561243f57600080fd5b80360382131561204e57600080fd5b6040815261247c60408201612462856120ef565b73ffffffffffffffffffffffffffffffffffffffff169052565b60208301356060820152600061249560408501856123ea565b6101608060808601526124ad6101a0860183856122d7565b92506124bc60608801886123ea565b92507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0808786030160a08801526124f48585846122d7565b9450608089013560c088015260a089013560e0880152610100935060c089013584880152610120915060e089013582880152610140848a01358189015261253d838b018b6123ea565b955092508188870301848901526125558686856122d7565b9550612563818b018b6123ea565b9550935050808786030161018088015250506125808383836122d7565b93505050508260208301529392505050565b6000602082840312156125a457600080fd5b81517fffffffff000000000000000000000000000000000000000000000000000000008116811461014657600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6000815180845261261b81602086016020860161233c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600073ffffffffffffffffffffffffffffffffffffffff80871683528086166020840152508360408301526080606083015261268c6080830184612603565b9695505050505050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b848110156127c1577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808a8503018652815188850173ffffffffffffffffffffffffffffffffffffffff82511686528482015160038110612748577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b808310156127ac5783517fffffffff0000000000000000000000000000000000000000000000000000000016825292860192600192909201919086019061276a565b509785019795505050908201906001016126bf565b505073ffffffffffffffffffffffffffffffffffffffff8a169088015286810360408801526127f08189612603565b9a9950505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361285e5761285e6127fe565b5060010190565b600081612874576128746127fe565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b80820281158282048414176128b1576128b16127fe565b92915050565b808201808211156128b1576128b16127fe565b73ffffffffffffffffffffffffffffffffffffffff831681526040602082015260006123346040830184612603565b602081526000610146602083018461260356fe4c69624469616d6f6e644375743a2041646420666163657420686173206e6f20636f64654c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a205265706c61636520666163657420686173206e6f20636f6465a2646970667358221220a952f19990a20474450919a2df9ddff4430a71350892e0954f2bb073575ad64864736f6c63430008150033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100725760003560e01c8063b0d691fe11610050578063b0d691fe146100c5578063b61d27f61461010c578063d087d2881461011f57600080fd5b80633a871cdd1461007757806347e1da2a1461009d5780634a936417146100b2575b600080fd5b61008a610085366004611fb5565b610127565b6040519081526020015b60405180910390f35b6100b06100ab366004612055565b61014d565b005b61008a6100c036600461215a565b610450565b60015465010000000000900473ffffffffffffffffffffffffffffffffffffffff1660405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610094565b6100b061011a3660046121ce565b6106d0565b61008a61089d565b600061013161095e565b61013b8484610a16565b905061014682610c5d565b9392505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff9081164290911610156101f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064015b60405180910390fd5b6101fd61095e565b848114158061020c5750848314155b15610243576040517fdde5716100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006102b87fac87185d000000000000000000000000000000000000000000000000000000006000527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020527f6d9f2463c8c0d8cb8be556a773ab21d4321328909a1725f2ef7cae0c320e95da5460601c90565b905073ffffffffffffffffffffffffffffffffffffffff811661038f5760005b86811015610389576103818888838181106102f5576102f5612228565b905060200201602081019061030a9190612257565b87878481811061031c5761031c612228565b9050602002013586868581811061033557610335612228565b90506020028101906103479190612272565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610cc892505050565b6001016102d8565b50610447565b60005b868110156104455761043d8888838181106103af576103af612228565b90506020020160208101906103c49190612257565b8787848181106103d6576103d6612228565b905060200201358686858181106103ef576103ef612228565b90506020028101906104019190612272565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250889250610d45915050565b600101610392565b505b50505050505050565b600061045a610e0d565b6001805473ffffffffffffffffffffffffffffffffffffffff88811665010000000000027fffffffffffffff0000000000000000000000000000000000000000ffffffffff90921691909117909155600280548783167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216179091557f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd492380549287169290911691909117905561051187610eb3565b60008383604051602401610526929190612320565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fcd9b47e40000000000000000000000000000000000000000000000000000000017905251909150600090819073ffffffffffffffffffffffffffffffffffffffff8b16906105c8908590612360565b600060405180830381855af49150503d8060008114610603576040519150601f19603f3d011682016040523d82523d6000602084013e610608565b606091505b5091509150811580610623575061061e8161237c565b600114155b1561065a576040517f1602372100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60019350858560405161066e9291906123c1565b60405190819003812060015490916501000000000090910473ffffffffffffffffffffffffffffffffffffffff16907fd429ff0b972be4ae725700a373d05007287994e4c86cb83315b43ffa85b595fd90600090a35050509695505050505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610773576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064016101ec565b61077b61095e565b60006107f07fac87185d000000000000000000000000000000000000000000000000000000006000527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020527f6d9f2463c8c0d8cb8be556a773ab21d4321328909a1725f2ef7cae0c320e95da5460601c90565b905073ffffffffffffffffffffffffffffffffffffffff81166108535761084e858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610cc892505050565b610896565b610896858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250879250610d45915050565b5050505050565b60015460009065010000000000900473ffffffffffffffffffffffffffffffffffffffff166040517f35567e1a0000000000000000000000000000000000000000000000000000000081523060048201526000602482015273ffffffffffffffffffffffffffffffffffffffff91909116906335567e1a90604401602060405180830381865afa158015610935573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061095991906123d1565b905090565b60015465010000000000900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a14576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f6163636f756e743a206e6f742066726f6d20456e747279506f696e740000000060448201526064016101ec565b565b600154610100900460e01b7fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604081205460601c80610aab576040517f6eb2360200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600154604051600091610100900460e01b90610acd908790879060240161244e565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090506000808373ffffffffffffffffffffffffffffffffffffffff1683604051610b549190612360565b600060405180830381855af49150503d8060008114610b8f576040519150601f19603f3d011682016040523d82523d6000602084013e610b94565b606091505b509150915081610bd0576040517f3cbbb65000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610bd98161237c565b94506000859003610c1c576040518681527f19e781916118c373dadcb7776fae0a2dbb6bbdeedae143ce68031e22801ef8659060200160405180910390a1610c50565b6040518681527fbbfee2df7f28b899771f1015dc85d7840ff9f6162f23f6aa99686e8fbd2ce1319060200160405180910390a15b5050505092915050565b50565b8015610c5a5760405160009033907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90849084818181858888f193505050503d8060008114610896576040519150601f19603f3d011682016040523d82523d6000602084013e610896565b6000808473ffffffffffffffffffffffffffffffffffffffff168484604051610cf19190612360565b60006040518083038185875af1925050503d8060008114610d2e576040519150601f19603f3d011682016040523d82523d6000602084013e610d33565b606091505b50915091508161089657805160208201fd5b610d5181858585611117565b15610d88576040517f01f595e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000808573ffffffffffffffffffffffffffffffffffffffff168585604051610db19190612360565b60006040518083038185875af1925050503d8060008114610dee576040519150601f19603f3d011682016040523d82523d6000602084013e610df3565b606091505b509150915081610e0557805160208201fd5b505050505050565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb554610100900460ff1615610e78576040517f38fc28cb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100179055565b604080516001808252818301909252600091816020015b60408051606080820183526000808352602083015291810191909152815260200190600190039081610eca57905050905060008273ffffffffffffffffffffffffffffffffffffffff16633253960f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f6c9190612592565b604080516003808252608082019092529192506000919060208201606080368337019050509050631626ba7e60e01b81600081518110610fae57610fae612228565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681525050818160018151811061100e5761100e612228565b7fffffffff000000000000000000000000000000000000000000000000000000009092166020928302919091019091015280517f8da5cb5b00000000000000000000000000000000000000000000000000000000908290600290811061107657611076612228565b7fffffffff00000000000000000000000000000000000000000000000000000000909216602092830291909101820152604080516060810190915273ffffffffffffffffffffffffffffffffffffffff861681529081016000815260200182815250836000815181106110eb576110eb612228565b602002602001018190525061111183600060405180602001604052806000815250611264565b50505050565b60008030858585604051602401611131949392919061264d565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fac87185d0000000000000000000000000000000000000000000000000000000017905251909150600090819073ffffffffffffffffffffffffffffffffffffffff8916906111d3908590612360565b600060405180830381855af49150503d806000811461120e576040519150601f19603f3d011682016040523d82523d6000602084013e611213565b606091505b50915091508161124f576040517f01f595e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6112588161237c565b98975050505050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921547f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff8116908190600090600716156112d35750600381901c60009081526001840160205260409020545b60005b87518110156113505761134383838a84815181106112f6576112f6612228565b6020026020010151600001518b858151811061131457611314612228565b6020026020010151602001518c868151811061133257611332612228565b6020026020010151604001516113f0565b90935091506001016112d6565b50828214611389576002840180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff84161790555b60078216156113ab57600382901c600090815260018501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb6738787876040516113de93929190612696565b60405180910390a16104478686611e81565b600080807f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f905060008451116114a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f2063757400000000000000000000000000000000000000000060648201526084016101ec565b60008560028111156114bc576114bc6125d4565b0361168c576114e38660405180606001604052806024815260200161290d60249139611f7a565b60005b845181101561168657600085828151811061150357611503612228565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c156115d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c726561647920657869737473000000000000000000000060648201526084016101ec565b7fffffffff0000000000000000000000000000000000000000000000000000000080831660008181526020879052604090207fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608d901b168e17905560e060058e901b811692831c199c909c1690821c179a81900361166a5760038c901c600090815260018601602052604081209b909b555b8b6116748161282d565b9c5050600190930192506114e6915050565b50611e75565b60018560028111156116a0576116a06125d4565b03611990576116c78660405180606001604052806028815260200161295960289139611f7a565b60005b84518110156116865760008582815181106116e7576116e7612228565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c3081036117bc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4c69624469616d6f6e644375743a2043616e2774207265706c61636520696d6d60448201527f757461626c652066756e6374696f6e000000000000000000000000000000000060648201526084016101ec565b8973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611877576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e000000000000000060648201526084016101ec565b73ffffffffffffffffffffffffffffffffffffffff811661191a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e207468617420646f65736e2774206578697374000000000000000060648201526084016101ec565b507fffffffff0000000000000000000000000000000000000000000000000000000090911660009081526020849052604090206bffffffffffffffffffffffff919091167fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608a901b161790556001016116ca565b60028560028111156119a4576119a46125d4565b03611ded5773ffffffffffffffffffffffffffffffffffffffff861615611a4d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d75737420626520616464726573732830290000000000000000000060648201526084016101ec565b600388901c6007891660005b8651811015611dcd5760008a9003611a955782611a7581612865565b60008181526001870160205260409020549b50935060079250611aa39050565b81611a9f81612865565b9250505b6000806000808a8581518110611abb57611abb612228565b6020908102919091018101517fffffffff0000000000000000000000000000000000000000000000000000000081166000908152918a9052604090912054909150606081901c611b8d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e277420657869737400000000000000000060648201526084016101ec565b30606082901c03611c20576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e00000000000000000000000000000000000060648201526084016101ec565b600587901b8f901b94507fffffffff0000000000000000000000000000000000000000000000000000000080861690831614611cbe577fffffffff000000000000000000000000000000000000000000000000000000008516600090815260208a90526040902080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff83161790555b7fffffffff0000000000000000000000000000000000000000000000000000000091909116600090815260208990526040812055600381901c611fff16925060051b60e0169050858214611d53576000828152600188016020526040902080547fffffffff0000000000000000000000000000000000000000000000000000000080841c19909116908516831c179055611da4565b80837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c817fffffffff0000000000000000000000000000000000000000000000000000000060001b901c198e16179c505b84600003611dc257600086815260018801602052604081208190559c505b505050600101611a59565b5080611dda83600861289a565b611de491906128b7565b99505050611e75565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560448201527f74416374696f6e0000000000000000000000000000000000000000000000000060648201526084016101ec565b50959694955050505050565b73ffffffffffffffffffffffffffffffffffffffff8216611ea0575050565b611ec28260405180606001604052806028815260200161293160289139611f7a565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051611eea9190612360565b600060405180830381855af49150503d8060008114611f25576040519150601f19603f3d011682016040523d82523d6000602084013e611f2a565b606091505b50915091508161111157805115611f445780518082602001fd5b83836040517f192105d70000000000000000000000000000000000000000000000000000000081526004016101ec9291906128ca565b813b8181611111576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101ec91906128f9565b600080600060608486031215611fca57600080fd5b833567ffffffffffffffff811115611fe157600080fd5b84016101608187031215611ff457600080fd5b95602085013595506040909401359392505050565b60008083601f84011261201b57600080fd5b50813567ffffffffffffffff81111561203357600080fd5b6020830191508360208260051b850101111561204e57600080fd5b9250929050565b6000806000806000806060878903121561206e57600080fd5b863567ffffffffffffffff8082111561208657600080fd5b6120928a838b01612009565b909850965060208901359150808211156120ab57600080fd5b6120b78a838b01612009565b909650945060408901359150808211156120d057600080fd5b506120dd89828a01612009565b979a9699509497509295939492505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461211357600080fd5b919050565b60008083601f84011261212a57600080fd5b50813567ffffffffffffffff81111561214257600080fd5b60208301915083602082850101111561204e57600080fd5b60008060008060008060a0878903121561217357600080fd5b61217c876120ef565b955061218a602088016120ef565b9450612198604088016120ef565b93506121a6606088016120ef565b9250608087013567ffffffffffffffff8111156121c257600080fd5b6120dd89828a01612118565b600080600080606085870312156121e457600080fd5b6121ed856120ef565b935060208501359250604085013567ffffffffffffffff81111561221057600080fd5b61221c87828801612118565b95989497509550505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561226957600080fd5b610146826120ef565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126122a757600080fd5b83018035915067ffffffffffffffff8211156122c257600080fd5b60200191503681900382131561204e57600080fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b6020815260006123346020830184866122d7565b949350505050565b60005b8381101561235757818101518382015260200161233f565b50506000910152565b6000825161237281846020870161233c565b9190910192915050565b805160208083015191908110156123bb577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8160200360031b1b821691505b50919050565b8183823760009101908152919050565b6000602082840312156123e357600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261241f57600080fd5b830160208101925035905067ffffffffffffffff81111561243f57600080fd5b80360382131561204e57600080fd5b6040815261247c60408201612462856120ef565b73ffffffffffffffffffffffffffffffffffffffff169052565b60208301356060820152600061249560408501856123ea565b6101608060808601526124ad6101a0860183856122d7565b92506124bc60608801886123ea565b92507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0808786030160a08801526124f48585846122d7565b9450608089013560c088015260a089013560e0880152610100935060c089013584880152610120915060e089013582880152610140848a01358189015261253d838b018b6123ea565b955092508188870301848901526125558686856122d7565b9550612563818b018b6123ea565b9550935050808786030161018088015250506125808383836122d7565b93505050508260208301529392505050565b6000602082840312156125a457600080fd5b81517fffffffff000000000000000000000000000000000000000000000000000000008116811461014657600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6000815180845261261b81602086016020860161233c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600073ffffffffffffffffffffffffffffffffffffffff80871683528086166020840152508360408301526080606083015261268c6080830184612603565b9695505050505050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b848110156127c1577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808a8503018652815188850173ffffffffffffffffffffffffffffffffffffffff82511686528482015160038110612748577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b808310156127ac5783517fffffffff0000000000000000000000000000000000000000000000000000000016825292860192600192909201919086019061276a565b509785019795505050908201906001016126bf565b505073ffffffffffffffffffffffffffffffffffffffff8a169088015286810360408801526127f08189612603565b9a9950505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361285e5761285e6127fe565b5060010190565b600081612874576128746127fe565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b80820281158282048414176128b1576128b16127fe565b92915050565b808201808211156128b1576128b16127fe565b73ffffffffffffffffffffffffffffffffffffffff831681526040602082015260006123346040830184612603565b602081526000610146602083018461260356fe4c69624469616d6f6e644375743a2041646420666163657420686173206e6f20636f64654c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a205265706c61636520666163657420686173206e6f20636f6465a2646970667358221220a952f19990a20474450919a2df9ddff4430a71350892e0954f2bb073575ad64864736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "Account module contract that provides the account features and initialization of signer compatible with EIP-1271 & EIP-4337", + "kind": "dev", + "methods": { + "execute(address,uint256,bytes)": { + "details": "This method executes the calldata coming from the EntryPoint. Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)", + "params": { + "_dest": "Address of destination where the call will be forwarded to", + "_func": "Bytes of calldata to execute in the destination address", + "_value": "Amount of native coin the owner is willing to send(e.g. ETH, BNB)" + } + }, + "executeBatch(address[],uint256[],bytes[])": { + "details": "This method batch executes the calldata coming from the EntryPoint. Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)", + "params": { + "_dest": "Array of addresses of destination where the call will be forwarded to", + "_func": "Array of bytes of calldata to execute in the destination address", + "_value": "Array of amount of native coin the owner is willing to send(e.g. ETH, BNB)" + } + }, + "initialize(address,address,address,address,bytes)": { + "details": "This method can only be called during the initialization or signature migration. If the proxy contract was created without initialization, anyone can call initialize. Barz calls initialize in constructor in an atomic transaction during deployment", + "params": { + "_anEntryPoint": "Entrypoint contract defined in EIP-4337 handling the flow of UserOp", + "_defaultFallBackHandler": "Middleware contract for default facets", + "_facetRegistry": "Registry of Facets that hold all facet information", + "_ownerPublicKey": "Bytes of owner public key", + "_verificationFacet": "Facet contract handling the verificationi" + } + } + }, + "title": "Account Facet", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "constructor": { + "notice": "This constructor ensures that this contract can only be used as singleton for Proxy contracts" + }, + "entryPoint()": { + "notice": "Returns the address of EntryPoint contract registered to Barz account" + }, + "execute(address,uint256,bytes)": { + "notice": "Calls the destination with inputted calldata and value from EntryPoint" + }, + "executeBatch(address[],uint256[],bytes[])": { + "notice": "Batch calls the destination with inputted calldata and value from EntryPoint" + }, + "getNonce()": { + "notice": "Return the account nonce. This method returns the next sequential nonce. For a nonce of a specific key, use `entrypoint.getNonce(account, key)`" + }, + "initialize(address,address,address,address,bytes)": { + "notice": "Initializes the initial storage of the Barz contract." + }, + "validateUserOp((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256)": { + "notice": "Validate user's signature and nonce. subclass doesn't need to override this method. Instead, it should override the specific internal validation methods." + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 27823, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "s", + "offset": 0, + "slot": "0", + "type": "t_struct(AppStorage)27570_storage" + } + ], + "types": { + "t_bytes4": { + "encoding": "inplace", + "label": "bytes4", + "numberOfBytes": "4" + }, + "t_contract(IEntryPoint)12286": { + "encoding": "inplace", + "label": "contract IEntryPoint", + "numberOfBytes": "20" + }, + "t_contract(IFacetRegistry)26105": { + "encoding": "inplace", + "label": "contract IFacetRegistry", + "numberOfBytes": "20" + }, + "t_mapping(t_uint256,t_struct(InitializersStorage)27549_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => struct InitializersStorage)", + "numberOfBytes": "32", + "value": "t_struct(InitializersStorage)27549_storage" + }, + "t_mapping(t_uint256,t_struct(Lock)27542_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => struct Lock)", + "numberOfBytes": "32", + "value": "t_struct(Lock)27542_storage" + }, + "t_struct(AppStorage)27570_storage": { + "encoding": "inplace", + "label": "struct AppStorage", + "members": [ + { + "astId": 27554, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "initStorage", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_uint256,t_struct(InitializersStorage)27549_storage)" + }, + { + "astId": 27556, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "signerMigration", + "offset": 0, + "slot": "1", + "type": "t_uint8" + }, + { + "astId": 27558, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "validateOwnerSignatureSelector", + "offset": 1, + "slot": "1", + "type": "t_bytes4" + }, + { + "astId": 27561, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "entryPoint", + "offset": 5, + "slot": "1", + "type": "t_contract(IEntryPoint)12286" + }, + { + "astId": 27564, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "facetRegistry", + "offset": 0, + "slot": "2", + "type": "t_contract(IFacetRegistry)26105" + }, + { + "astId": 27569, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "locks", + "offset": 0, + "slot": "3", + "type": "t_mapping(t_uint256,t_struct(Lock)27542_storage)" + } + ], + "numberOfBytes": "128" + }, + "t_struct(InitializersStorage)27549_storage": { + "encoding": "inplace", + "label": "struct InitializersStorage", + "members": [ + { + "astId": 27544, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "signerInitialized", + "offset": 0, + "slot": "0", + "type": "t_uint8" + }, + { + "astId": 27546, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "accountInitialized", + "offset": 1, + "slot": "0", + "type": "t_uint8" + }, + { + "astId": 27548, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "restrictionsInitialized", + "offset": 2, + "slot": "0", + "type": "t_uint8" + } + ], + "numberOfBytes": "32" + }, + "t_struct(Lock)27542_storage": { + "encoding": "inplace", + "label": "struct Lock", + "members": [ + { + "astId": 27539, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "release", + "offset": 0, + "slot": "0", + "type": "t_uint64" + }, + { + "astId": 27541, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "locker", + "offset": 8, + "slot": "0", + "type": "t_bytes4" + } + ], + "numberOfBytes": "32" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint64": { + "encoding": "inplace", + "label": "uint64", + "numberOfBytes": "8" + }, + "t_uint8": { + "encoding": "inplace", + "label": "uint8", + "numberOfBytes": "1" + } + } + } +} \ No newline at end of file diff --git a/deployments/optimism/BarzFactory.json b/deployments/optimism/BarzFactory.json new file mode 100644 index 0000000..f04e0e3 --- /dev/null +++ b/deployments/optimism/BarzFactory.json @@ -0,0 +1,318 @@ +{ + "address": "0x729c310186a57833f622630a16d13f710b83272a", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_accountFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_entryPoint", + "type": "address" + }, + { + "internalType": "address", + "name": "_facetRegistry", + "type": "address" + }, + { + "internalType": "address", + "name": "_defaultFallback", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "BarzDeployed", + "type": "event" + }, + { + "inputs": [], + "name": "accountFacet", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_verificationFacet", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_owner", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "_salt", + "type": "uint256" + } + ], + "name": "createAccount", + "outputs": [ + { + "internalType": "contract Barz", + "name": "barz", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "defaultFallback", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "entryPoint", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetRegistry", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_verificationFacet", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_owner", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "_salt", + "type": "uint256" + } + ], + "name": "getAddress", + "outputs": [ + { + "internalType": "address", + "name": "barzAddress", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_accountFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_verificationFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_entryPoint", + "type": "address" + }, + { + "internalType": "address", + "name": "_facetRegistry", + "type": "address" + }, + { + "internalType": "address", + "name": "_defaultFallback", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_ownerPublicKey", + "type": "bytes" + } + ], + "name": "getBytecode", + "outputs": [ + { + "internalType": "bytes", + "name": "barzBytecode", + "type": "bytes" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "getCreationCode", + "outputs": [ + { + "internalType": "bytes", + "name": "creationCode", + "type": "bytes" + } + ], + "stateMutability": "pure", + "type": "function" + } + ], + "transactionHash": "0x8a81f58cff406074afe20667110927c04deff3d3fef89d06df46d278da757fd4", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 6, + "gasUsed": "801756", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x41edba6c0ce2a067fc16410155a3cb3037ec75f9b1d7ed5fd7cb11d332226b29", + "transactionHash": "0x8a81f58cff406074afe20667110927c04deff3d3fef89d06df46d278da757fd4", + "logs": [], + "blockNumber": 112443702, + "cumulativeGasUsed": "3519798", + "status": 1, + "byzantium": true + }, + "args": [ + "0xFde53272dcd7938d16E031A6989753c321728332", + "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789", + "0xAfCb70e6e9514E2A15B23A01d2a9b9f7A34f2c33", + "0x2e7f1dAe1F3799d20f5c31bEFdc7A620f664728D" + ], + "numDeployments": 3, + "solcInputHash": "4356503edd8ae34e73cb6dd1c8e2fc8a", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_accountFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_entryPoint\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_facetRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_defaultFallback\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"BarzDeployed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"accountFacet\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_verificationFacet\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_owner\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_salt\",\"type\":\"uint256\"}],\"name\":\"createAccount\",\"outputs\":[{\"internalType\":\"contract Barz\",\"name\":\"barz\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"defaultFallback\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"entryPoint\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetRegistry\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_verificationFacet\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_owner\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_salt\",\"type\":\"uint256\"}],\"name\":\"getAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"barzAddress\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_accountFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_verificationFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_entryPoint\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_facetRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_defaultFallback\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_ownerPublicKey\",\"type\":\"bytes\"}],\"name\":\"getBytecode\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"barzBytecode\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCreationCode\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"creationCode\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"Contract to easily deploy Barz to a pre-computed address with a single call\",\"kind\":\"dev\",\"methods\":{\"constructor\":{\"params\":{\"_accountFacet\":\"Account Facet to be used to create Barz\",\"_defaultFallback\":\"Default Fallback Handler to be used to create Barz\",\"_entryPoint\":\"Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\",\"_facetRegistry\":\"Facet Registry to be used to create Barz\"}},\"createAccount(address,bytes,uint256)\":{\"params\":{\"_owner\":\"Public Key of the owner to initialize barz account\",\"_salt\":\"Salt used for deploying barz with create2\",\"_verificationFacet\":\"Address of verification facet used for creating the barz account\"},\"returns\":{\"barz\":\"Instance of Barz contract deployed with the given parameters\"}},\"getAddress(address,bytes,uint256)\":{\"params\":{\"_owner\":\"Public Key of the owner to initialize barz account\",\"_salt\":\"Salt used for deploying barz with create2\",\"_verificationFacet\":\"Address of verification facet used for creating the barz account\"},\"returns\":{\"barzAddress\":\"Precalculated Barz address\"}},\"getBytecode(address,address,address,address,address,bytes)\":{\"params\":{\"_accountFacet\":\"Account Facet to be used to create Barz\",\"_defaultFallback\":\"Default Fallback Handler to be used to create Barz\",\"_entryPoint\":\"Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\",\"_facetRegistry\":\"Facet Registry to be used to create Barz\",\"_ownerPublicKey\":\"Public Key of owner to be used to initialize Barz ownership\",\"_verificationFacet\":\"Verification Facet to be used to create Barz\"},\"returns\":{\"barzBytecode\":\"Bytecode of Barz\"}},\"getCreationCode()\":{\"returns\":{\"creationCode\":\"Creation code of Barz\"}}},\"title\":\"Barz Factory\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"Sets the initialization data for Barz contract initialization\"},\"createAccount(address,bytes,uint256)\":{\"notice\":\"Creates the Barz with a single call. It creates the Barz contract with the givent verification facet\"},\"getAddress(address,bytes,uint256)\":{\"notice\":\"Calculates the address of Barz with the given parameters\"},\"getBytecode(address,address,address,address,address,bytes)\":{\"notice\":\"Returns the bytecode of Barz with the given parameter\"},\"getCreationCode()\":{\"notice\":\"Returns the creation code of the Barz contract\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/BarzFactory.sol\":\"BarzFactory\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"contracts/Barz.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {LibDiamond} from \\\"./libraries/LibDiamond.sol\\\";\\nimport {IBarz} from \\\"./interfaces/IBarz.sol\\\";\\n\\n/**\\n * @title Barz\\n * @dev A diamond proxy wallet with a modular & upgradeable architecture\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract Barz is IBarz {\\n /**\\n * @notice Initializes Barz with the given parameters. Barz account is intended to be created from Barz Factory for stable deployment.\\n * @dev This method makes a delegate call to account facet and account facet handles the initialization.\\n * With modular architecture, Barz encompasses wide spectrum of architecture and logic.\\n * The only requirement is account facet to comply with initialize() interface.\\n * Barz doesn't include built-in functions and is a full proxy, for maximum extensibility and modularity.\\n * @param _accountFacet Address of Account Facet in charge of the Barz initialization\\n * @param _verificationFacet Address of Verification Facet for verifying the signature. Could be any signature scheme\\n * @param _entryPoint Address of Entry Point contract\\n * @param _facetRegistry Address of Facet Registry. Facet Registry is a registry holding trusted facets that could be added to user's wallet\\n * @param _defaultFallBack Address of Default FallBack Handler. Middleware contract for more efficient deployment\\n * @param _ownerPublicKey Bytes of Owner Public Key using for initialization\\n */\\n constructor(\\n address _accountFacet,\\n address _verificationFacet,\\n address _entryPoint,\\n address _facetRegistry,\\n address _defaultFallBack,\\n bytes memory _ownerPublicKey\\n ) payable {\\n bytes memory initCall = abi.encodeWithSignature(\\n \\\"initialize(address,address,address,address,bytes)\\\",\\n _verificationFacet,\\n _entryPoint,\\n _facetRegistry,\\n _defaultFallBack,\\n _ownerPublicKey\\n );\\n (bool success, bytes memory result) = _accountFacet.delegatecall(\\n initCall\\n );\\n if (!success || uint256(bytes32(result)) != 1) {\\n revert Barz__InitializationFailure();\\n }\\n }\\n\\n /**\\n * @notice Fallback function for Barz complying with Diamond Standard with customization of adding Default Fallback Handler\\n * @dev Find facet for function that is called and execute the function if a facet is found and return any value.\\n */\\n fallback() external payable {\\n LibDiamond.DiamondStorage storage ds;\\n bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION;\\n // get diamond storage\\n assembly {\\n ds.slot := position\\n }\\n // get facet from function selector\\n address facet = address(bytes20(ds.facets[msg.sig]));\\n if (facet == address(0))\\n facet = ds.defaultFallbackHandler.facetAddress(msg.sig);\\n require(facet != address(0), \\\"Barz: Function does not exist\\\");\\n // Execute external function from facet using delegatecall and return any value.\\n assembly {\\n // copy function selector and any arguments\\n calldatacopy(0, 0, calldatasize())\\n // execute function call using the facet\\n let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)\\n // get any return value\\n returndatacopy(0, 0, returndatasize())\\n // return any return value or error back to the caller\\n switch result\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @notice Receive function to receive native token without data\\n */\\n receive() external payable {}\\n}\\n\",\"keccak256\":\"0xd1c773409a4b3d1ca0316445d9ea1d686bab9cd5f6731fbdb0766a93edfd7bdb\",\"license\":\"Apache-2.0\"},\"contracts/BarzFactory.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {Barz} from \\\"./Barz.sol\\\";\\nimport {IBarzFactory} from \\\"./interfaces/IBarzFactory.sol\\\";\\n\\n/**\\n * @title Barz Factory\\n * @dev Contract to easily deploy Barz to a pre-computed address with a single call\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract BarzFactory is IBarzFactory {\\n address public immutable accountFacet;\\n address public immutable entryPoint;\\n address public immutable facetRegistry;\\n address public immutable defaultFallback;\\n\\n /**\\n * @notice Sets the initialization data for Barz contract initialization\\n * @param _accountFacet Account Facet to be used to create Barz\\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\\n * @param _facetRegistry Facet Registry to be used to create Barz\\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\\n */\\n constructor(\\n address _accountFacet,\\n address _entryPoint,\\n address _facetRegistry,\\n address _defaultFallback\\n ) {\\n accountFacet = _accountFacet;\\n entryPoint = _entryPoint;\\n facetRegistry = _facetRegistry;\\n defaultFallback = _defaultFallback;\\n }\\n\\n /**\\n * @notice Creates the Barz with a single call. It creates the Barz contract with the givent verification facet\\n * @param _verificationFacet Address of verification facet used for creating the barz account\\n * @param _owner Public Key of the owner to initialize barz account\\n * @param _salt Salt used for deploying barz with create2\\n * @return barz Instance of Barz contract deployed with the given parameters\\n */\\n function createAccount(\\n address _verificationFacet,\\n bytes calldata _owner,\\n uint256 _salt\\n ) external override returns (Barz barz) {\\n address addr = getAddress(_verificationFacet, _owner, _salt);\\n uint codeSize = addr.code.length;\\n if (codeSize > 0) {\\n return Barz(payable(addr));\\n }\\n barz = new Barz{salt: bytes32(_salt)}(\\n accountFacet,\\n _verificationFacet,\\n entryPoint,\\n facetRegistry,\\n defaultFallback,\\n _owner\\n );\\n emit BarzDeployed(address(barz));\\n }\\n\\n /**\\n * @notice Calculates the address of Barz with the given parameters\\n * @param _verificationFacet Address of verification facet used for creating the barz account\\n * @param _owner Public Key of the owner to initialize barz account\\n * @param _salt Salt used for deploying barz with create2\\n * @return barzAddress Precalculated Barz address\\n */\\n function getAddress(\\n address _verificationFacet,\\n bytes calldata _owner,\\n uint256 _salt\\n ) public view override returns (address barzAddress) {\\n bytes memory bytecode = getBytecode(\\n accountFacet,\\n _verificationFacet,\\n entryPoint,\\n facetRegistry,\\n defaultFallback,\\n _owner\\n );\\n bytes32 hash = keccak256(\\n abi.encodePacked(\\n bytes1(0xff),\\n address(this),\\n _salt,\\n keccak256(bytecode)\\n )\\n );\\n barzAddress = address(uint160(uint256(hash)));\\n }\\n\\n /**\\n * @notice Returns the bytecode of Barz with the given parameter\\n * @param _accountFacet Account Facet to be used to create Barz\\n * @param _verificationFacet Verification Facet to be used to create Barz\\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\\n * @param _facetRegistry Facet Registry to be used to create Barz\\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\\n * @param _ownerPublicKey Public Key of owner to be used to initialize Barz ownership\\n * @return barzBytecode Bytecode of Barz\\n */\\n function getBytecode(\\n address _accountFacet,\\n address _verificationFacet,\\n address _entryPoint,\\n address _facetRegistry,\\n address _defaultFallback,\\n bytes calldata _ownerPublicKey\\n ) public pure override returns (bytes memory barzBytecode) {\\n bytes memory bytecode = type(Barz).creationCode;\\n barzBytecode = abi.encodePacked(\\n bytecode,\\n abi.encode(\\n _accountFacet,\\n _verificationFacet,\\n _entryPoint,\\n _facetRegistry,\\n _defaultFallback,\\n _ownerPublicKey\\n )\\n );\\n }\\n\\n /**\\n * @notice Returns the creation code of the Barz contract\\n * @return creationCode Creation code of Barz\\n */\\n function getCreationCode()\\n public\\n pure\\n override\\n returns (bytes memory creationCode)\\n {\\n creationCode = type(Barz).creationCode;\\n }\\n}\\n\",\"keccak256\":\"0x76d6058fa4714f5ef87b876e49ce7e21f581164901eea906ec743e82362b1df6\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IBarz.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Barz Interface\\n * @dev Interface of Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IBarz {\\n error Barz__InitializationFailure();\\n}\\n\",\"keccak256\":\"0xca9f0c2c1ad7d06088fa16ae92d587416f2d10d8f999d7afe8ca5c4d73410aba\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IBarzFactory.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {Barz} from \\\"../Barz.sol\\\";\\n\\n/**\\n * @title Barz Factory Interface\\n * @dev Interface of contract to easily deploy Barz to a pre-computed address with a single call\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IBarzFactory {\\n event BarzDeployed(address);\\n\\n function createAccount(\\n address verificationFacet,\\n bytes calldata owner,\\n uint256 salt\\n ) external returns (Barz);\\n\\n function getAddress(\\n address verificationFacet,\\n bytes calldata owner,\\n uint256 salt\\n ) external view returns (address);\\n\\n function getBytecode(\\n address accountFacet,\\n address verificationFacet,\\n address entryPoint,\\n address facetRegistry,\\n address defaultFallback,\\n bytes memory ownerPublicKey\\n ) external pure returns (bytes memory);\\n\\n function getCreationCode() external pure returns (bytes memory);\\n}\\n\",\"keccak256\":\"0xadb48a6f3025f6395e26ffd5f9319da73ad2383906c8223e8455f41f420fba26\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\\n bytes4(keccak256(\\\"verifyRestrictions(address,address,uint256,bytes)\\\"));\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // Default Fallback Handler of the barz.\\n IDiamondLoupe defaultFallbackHandler;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function enforceIsSelf() internal view {\\n require(msg.sender == address(this), \\\"LibDiamond: Caller not self\\\");\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n\\n unchecked {\\n facetIndex++;\\n }\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n\\n function restrictionsFacet() internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(\\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2cabdc00de859c3a3170ce3bda5d0e5fd3933d47ce904fd1585f9818b02572f8\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x61010060405234801561001157600080fd5b50604051610eba380380610eba8339810160408190526100309161006e565b6001600160a01b0393841660805291831660a052821660c0521660e0526100c2565b80516001600160a01b038116811461006957600080fd5b919050565b6000806000806080858703121561008457600080fd5b61008d85610052565b935061009b60208601610052565b92506100a960408601610052565b91506100b760608601610052565b905092959194509250565b60805160a05160c05160e051610d886101326000396000818161013b015281816102b3015261048101526000818160bf01528181610292015261046001526000818161016301528181610271015261043f01526000818161018b0152818161024f015261041d0152610d886000f3fe60806040523480156200001157600080fd5b5060043610620000925760003560e01c806344409a82116200006257806344409a821462000135578063b0d691fe146200015d578063b0f5d4641462000185578063c8a7adf514620001ad57600080fd5b8062c194db14620000975780630a1acd7314620000b9578063296601cd146200010757806333bb64a7146200011e575b600080fd5b620000a1620001c4565b604051620000b091906200056c565b60405180910390f35b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001620000b0565b620000e16200011836600462000635565b6200020e565b620000a16200012f36600462000695565b6200036d565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e1620001be36600462000635565b62000414565b606060405180602001620001d89062000538565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082820381018352601f90910116604052919050565b6000806200021f8686868662000414565b905073ffffffffffffffffffffffffffffffffffffffff81163b8015620002495750905062000365565b8360001b7f0000000000000000000000000000000000000000000000000000000000000000887f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008b8b604051620002e29062000538565b620002f497969594939291906200073a565b8190604051809103906000f590508015801562000315573d6000803e3d6000fd5b5060405173ffffffffffffffffffffffffffffffffffffffff821681529093507f9e6e326008e68f57877e2bae766a5745c162e42359e34834a7f0661fa82d31b19060200160405180910390a150505b949350505050565b6060600060405180602001620003839062000538565b6020820181038252601f19601f8201166040525090508089898989898989604051602001620003b997969594939291906200073a565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052620003f79291602001620007cd565b604051602081830303815290604052915050979650505050505050565b600080620004a87f0000000000000000000000000000000000000000000000000000000000000000877f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008a8a6200036d565b8051602091820120604080517fff00000000000000000000000000000000000000000000000000000000000000818501523060601b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001660218201526035810196909652605580870192909252805180870390920182526075909501909452835193019290922095945050505050565b610552806200080183390190565b60005b838110156200056357818101518382015260200162000549565b50506000910152565b60208152600082518060208401526200058d81604085016020870162000546565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b803573ffffffffffffffffffffffffffffffffffffffff81168114620005e457600080fd5b919050565b60008083601f840112620005fc57600080fd5b50813567ffffffffffffffff8111156200061557600080fd5b6020830191508360208285010111156200062e57600080fd5b9250929050565b600080600080606085870312156200064c57600080fd5b6200065785620005bf565b9350602085013567ffffffffffffffff8111156200067457600080fd5b6200068287828801620005e9565b9598909750949560400135949350505050565b600080600080600080600060c0888a031215620006b157600080fd5b620006bc88620005bf565b9650620006cc60208901620005bf565b9550620006dc60408901620005bf565b9450620006ec60608901620005bf565b9350620006fc60808901620005bf565b925060a088013567ffffffffffffffff8111156200071957600080fd5b620007278a828b01620005e9565b989b979a50959850939692959293505050565b600073ffffffffffffffffffffffffffffffffffffffff808a16835280891660208401528088166040840152808716606084015280861660808401525060c060a08301528260c0830152828460e0840137600060e0848401015260e07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f850116830101905098975050505050505050565b60008351620007e181846020880162000546565b835190830190620007f781836020880162000546565b0194935050505056fe608060405260405161055238038061055283398101604081905261002291610163565b6000858585858560405160240161003d959493929190610264565b60408051601f198184030181529181526020820180516001600160e01b0316634a93641760e01b1790525190915060009081906001600160a01b038a16906100869085906102c3565b600060405180830381855af49150503d80600081146100c1576040519150601f19603f3d011682016040523d82523d6000602084013e6100c6565b606091505b50915091508115806100e157506100dc816102df565b600114155b156100ff57604051636ff35f8960e01b815260040160405180910390fd5b505050505050505050610306565b80516001600160a01b038116811461012457600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101561015a578181015183820152602001610142565b50506000910152565b60008060008060008060c0878903121561017c57600080fd5b6101858761010d565b95506101936020880161010d565b94506101a16040880161010d565b93506101af6060880161010d565b92506101bd6080880161010d565b60a08801519092506001600160401b03808211156101da57600080fd5b818901915089601f8301126101ee57600080fd5b81518181111561020057610200610129565b604051601f8201601f19908116603f0116810190838211818310171561022857610228610129565b816040528281528c602084870101111561024157600080fd5b61025283602083016020880161013f565b80955050505050509295509295509295565b600060018060a01b0380881683528087166020840152808616604084015280851660608401525060a0608083015282518060a08401526102ab8160c085016020870161013f565b601f01601f19169190910160c0019695505050505050565b600082516102d581846020870161013f565b9190910192915050565b80516020808301519190811015610300576000198160200360031b1b821691505b50919050565b61023d806103156000396000f3fe60806040523661000b57005b600080357fffffffff000000000000000000000000000000000000000000000000000000001681527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020819052604090912054819060601c80610125576004838101546040517fcdffacc60000000000000000000000000000000000000000000000000000000081526000357fffffffff00000000000000000000000000000000000000000000000000000000169281019290925273ffffffffffffffffffffffffffffffffffffffff169063cdffacc690602401602060405180830381865afa1580156100fe573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061012291906101ca565b90505b73ffffffffffffffffffffffffffffffffffffffff81166101a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4261727a3a2046756e6374696f6e20646f6573206e6f74206578697374000000604482015260640160405180910390fd5b3660008037600080366000845af43d6000803e8080156101c5573d6000f35b3d6000fd5b6000602082840312156101dc57600080fd5b815173ffffffffffffffffffffffffffffffffffffffff8116811461020057600080fd5b939250505056fea26469706673582212200f3fa76ace3be8675d8b4c0d6c210a922fff2c2f1444023b817d1f6c908cd56a64736f6c63430008150033a2646970667358221220329ad45a4ef4915180001cb1fc90a5f97ad94a0b280426a580cba65fce28c0f164736f6c63430008150033", + "deployedBytecode": "0x60806040523480156200001157600080fd5b5060043610620000925760003560e01c806344409a82116200006257806344409a821462000135578063b0d691fe146200015d578063b0f5d4641462000185578063c8a7adf514620001ad57600080fd5b8062c194db14620000975780630a1acd7314620000b9578063296601cd146200010757806333bb64a7146200011e575b600080fd5b620000a1620001c4565b604051620000b091906200056c565b60405180910390f35b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001620000b0565b620000e16200011836600462000635565b6200020e565b620000a16200012f36600462000695565b6200036d565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e1620001be36600462000635565b62000414565b606060405180602001620001d89062000538565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082820381018352601f90910116604052919050565b6000806200021f8686868662000414565b905073ffffffffffffffffffffffffffffffffffffffff81163b8015620002495750905062000365565b8360001b7f0000000000000000000000000000000000000000000000000000000000000000887f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008b8b604051620002e29062000538565b620002f497969594939291906200073a565b8190604051809103906000f590508015801562000315573d6000803e3d6000fd5b5060405173ffffffffffffffffffffffffffffffffffffffff821681529093507f9e6e326008e68f57877e2bae766a5745c162e42359e34834a7f0661fa82d31b19060200160405180910390a150505b949350505050565b6060600060405180602001620003839062000538565b6020820181038252601f19601f8201166040525090508089898989898989604051602001620003b997969594939291906200073a565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052620003f79291602001620007cd565b604051602081830303815290604052915050979650505050505050565b600080620004a87f0000000000000000000000000000000000000000000000000000000000000000877f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008a8a6200036d565b8051602091820120604080517fff00000000000000000000000000000000000000000000000000000000000000818501523060601b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001660218201526035810196909652605580870192909252805180870390920182526075909501909452835193019290922095945050505050565b610552806200080183390190565b60005b838110156200056357818101518382015260200162000549565b50506000910152565b60208152600082518060208401526200058d81604085016020870162000546565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b803573ffffffffffffffffffffffffffffffffffffffff81168114620005e457600080fd5b919050565b60008083601f840112620005fc57600080fd5b50813567ffffffffffffffff8111156200061557600080fd5b6020830191508360208285010111156200062e57600080fd5b9250929050565b600080600080606085870312156200064c57600080fd5b6200065785620005bf565b9350602085013567ffffffffffffffff8111156200067457600080fd5b6200068287828801620005e9565b9598909750949560400135949350505050565b600080600080600080600060c0888a031215620006b157600080fd5b620006bc88620005bf565b9650620006cc60208901620005bf565b9550620006dc60408901620005bf565b9450620006ec60608901620005bf565b9350620006fc60808901620005bf565b925060a088013567ffffffffffffffff8111156200071957600080fd5b620007278a828b01620005e9565b989b979a50959850939692959293505050565b600073ffffffffffffffffffffffffffffffffffffffff808a16835280891660208401528088166040840152808716606084015280861660808401525060c060a08301528260c0830152828460e0840137600060e0848401015260e07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f850116830101905098975050505050505050565b60008351620007e181846020880162000546565b835190830190620007f781836020880162000546565b0194935050505056fe608060405260405161055238038061055283398101604081905261002291610163565b6000858585858560405160240161003d959493929190610264565b60408051601f198184030181529181526020820180516001600160e01b0316634a93641760e01b1790525190915060009081906001600160a01b038a16906100869085906102c3565b600060405180830381855af49150503d80600081146100c1576040519150601f19603f3d011682016040523d82523d6000602084013e6100c6565b606091505b50915091508115806100e157506100dc816102df565b600114155b156100ff57604051636ff35f8960e01b815260040160405180910390fd5b505050505050505050610306565b80516001600160a01b038116811461012457600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101561015a578181015183820152602001610142565b50506000910152565b60008060008060008060c0878903121561017c57600080fd5b6101858761010d565b95506101936020880161010d565b94506101a16040880161010d565b93506101af6060880161010d565b92506101bd6080880161010d565b60a08801519092506001600160401b03808211156101da57600080fd5b818901915089601f8301126101ee57600080fd5b81518181111561020057610200610129565b604051601f8201601f19908116603f0116810190838211818310171561022857610228610129565b816040528281528c602084870101111561024157600080fd5b61025283602083016020880161013f565b80955050505050509295509295509295565b600060018060a01b0380881683528087166020840152808616604084015280851660608401525060a0608083015282518060a08401526102ab8160c085016020870161013f565b601f01601f19169190910160c0019695505050505050565b600082516102d581846020870161013f565b9190910192915050565b80516020808301519190811015610300576000198160200360031b1b821691505b50919050565b61023d806103156000396000f3fe60806040523661000b57005b600080357fffffffff000000000000000000000000000000000000000000000000000000001681527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020819052604090912054819060601c80610125576004838101546040517fcdffacc60000000000000000000000000000000000000000000000000000000081526000357fffffffff00000000000000000000000000000000000000000000000000000000169281019290925273ffffffffffffffffffffffffffffffffffffffff169063cdffacc690602401602060405180830381865afa1580156100fe573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061012291906101ca565b90505b73ffffffffffffffffffffffffffffffffffffffff81166101a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4261727a3a2046756e6374696f6e20646f6573206e6f74206578697374000000604482015260640160405180910390fd5b3660008037600080366000845af43d6000803e8080156101c5573d6000f35b3d6000fd5b6000602082840312156101dc57600080fd5b815173ffffffffffffffffffffffffffffffffffffffff8116811461020057600080fd5b939250505056fea26469706673582212200f3fa76ace3be8675d8b4c0d6c210a922fff2c2f1444023b817d1f6c908cd56a64736f6c63430008150033a2646970667358221220329ad45a4ef4915180001cb1fc90a5f97ad94a0b280426a580cba65fce28c0f164736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "Contract to easily deploy Barz to a pre-computed address with a single call", + "kind": "dev", + "methods": { + "constructor": { + "params": { + "_accountFacet": "Account Facet to be used to create Barz", + "_defaultFallback": "Default Fallback Handler to be used to create Barz", + "_entryPoint": "Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF", + "_facetRegistry": "Facet Registry to be used to create Barz" + } + }, + "createAccount(address,bytes,uint256)": { + "params": { + "_owner": "Public Key of the owner to initialize barz account", + "_salt": "Salt used for deploying barz with create2", + "_verificationFacet": "Address of verification facet used for creating the barz account" + }, + "returns": { + "barz": "Instance of Barz contract deployed with the given parameters" + } + }, + "getAddress(address,bytes,uint256)": { + "params": { + "_owner": "Public Key of the owner to initialize barz account", + "_salt": "Salt used for deploying barz with create2", + "_verificationFacet": "Address of verification facet used for creating the barz account" + }, + "returns": { + "barzAddress": "Precalculated Barz address" + } + }, + "getBytecode(address,address,address,address,address,bytes)": { + "params": { + "_accountFacet": "Account Facet to be used to create Barz", + "_defaultFallback": "Default Fallback Handler to be used to create Barz", + "_entryPoint": "Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF", + "_facetRegistry": "Facet Registry to be used to create Barz", + "_ownerPublicKey": "Public Key of owner to be used to initialize Barz ownership", + "_verificationFacet": "Verification Facet to be used to create Barz" + }, + "returns": { + "barzBytecode": "Bytecode of Barz" + } + }, + "getCreationCode()": { + "returns": { + "creationCode": "Creation code of Barz" + } + } + }, + "title": "Barz Factory", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "constructor": { + "notice": "Sets the initialization data for Barz contract initialization" + }, + "createAccount(address,bytes,uint256)": { + "notice": "Creates the Barz with a single call. It creates the Barz contract with the givent verification facet" + }, + "getAddress(address,bytes,uint256)": { + "notice": "Calculates the address of Barz with the given parameters" + }, + "getBytecode(address,address,address,address,address,bytes)": { + "notice": "Returns the bytecode of Barz with the given parameter" + }, + "getCreationCode()": { + "notice": "Returns the creation code of the Barz contract" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/optimism/DefaultFallbackHandler.json b/deployments/optimism/DefaultFallbackHandler.json new file mode 100644 index 0000000..afe21c1 --- /dev/null +++ b/deployments/optimism/DefaultFallbackHandler.json @@ -0,0 +1,275 @@ +{ + "address": "0x2e7f1dAe1F3799d20f5c31bEFdc7A620f664728D", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_diamondCutFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_accountFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_tokenReceiverFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_diamondLoupeFacet", + "type": "address" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_initializationContractAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "InitializationFunctionReverted", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "indexed": false, + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "DiamondCut", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_functionSelector", + "type": "bytes4" + } + ], + "name": "facetAddress", + "outputs": [ + { + "internalType": "address", + "name": "facetAddress_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetAddresses", + "outputs": [ + { + "internalType": "address[]", + "name": "facetAddresses_", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_facet", + "type": "address" + } + ], + "name": "facetFunctionSelectors", + "outputs": [ + { + "internalType": "bytes4[]", + "name": "facetFunctionSelectors_", + "type": "bytes4[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facets", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondLoupe.Facet[]", + "name": "facets_", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0x4131a09fd002cf66cd59551bfae00b81f132cb6d855bd8ae333dbdf176468690", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 5, + "gasUsed": "1438535", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000001000000000800002000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000", + "blockHash": "0xc8e017444441ac850bffa516784f8519aa2300a7bd6dd6bd02ec3fcc2ba15c7b", + "transactionHash": "0x4131a09fd002cf66cd59551bfae00b81f132cb6d855bd8ae333dbdf176468690", + "logs": [ + { + "transactionIndex": 5, + "blockNumber": 112443700, + "transactionHash": "0x4131a09fd002cf66cd59551bfae00b81f132cb6d855bd8ae333dbdf176468690", + "address": "0x2e7f1dAe1F3799d20f5c31bEFdc7A620f664728D", + "topics": [ + "0x8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb673" + ], + "data": "0x000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000580000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000000000000000000000000000000000003600000000000000000000000000b9504140771c3688ff041917192277d2f52e1e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000011f931c1c00000000000000000000000000000000000000000000000000000000000000000000000000000000fde53272dcd7938d16e031a6989753c321728332000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000005b61d27f60000000000000000000000000000000000000000000000000000000047e1da2a000000000000000000000000000000000000000000000000000000003a871cdd00000000000000000000000000000000000000000000000000000000d087d28800000000000000000000000000000000000000000000000000000000b0d691fe000000000000000000000000000000000000000000000000000000000000000000000000000000003143e1c0af0cdc153423863923cf4e3818e34daa000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000005150b7a0200000000000000000000000000000000000000000000000000000000f23a6e6100000000000000000000000000000000000000000000000000000000bc197c81000000000000000000000000000000000000000000000000000000000023de2900000000000000000000000000000000000000000000000000000000a4c0ed3600000000000000000000000000000000000000000000000000000000000000000000000000000000ce36b85d12d81cd619c745c7717f3396e184ac7c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000097a0ed62700000000000000000000000000000000000000000000000000000000adfca15e0000000000000000000000000000000000000000000000000000000052ef6b2c00000000000000000000000000000000000000000000000000000000cdffacc60000000000000000000000000000000000000000000000000000000001ffc9a700000000000000000000000000000000000000000000000000000000f9796ccf0000000000000000000000000000000000000000000000000000000001a5502200000000000000000000000000000000000000000000000000000000d42139a900000000000000000000000000000000000000000000000000000000e3a2f6fe000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "logIndex": 4, + "blockHash": "0xc8e017444441ac850bffa516784f8519aa2300a7bd6dd6bd02ec3fcc2ba15c7b" + } + ], + "blockNumber": 112443700, + "cumulativeGasUsed": "1868728", + "status": 1, + "byzantium": true + }, + "args": [ + "0x0B9504140771C3688Ff041917192277D2f52E1e0", + "0xFde53272dcd7938d16E031A6989753c321728332", + "0x3143E1C0Af0Cdc153423863923Cf4e3818e34Daa", + "0xCe36b85d12D81cd619C745c7717f3396E184Ac7C" + ], + "numDeployments": 3, + "solcInputHash": "4356503edd8ae34e73cb6dd1c8e2fc8a", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_diamondCutFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_accountFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_tokenReceiverFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_diamondLoupeFacet\",\"type\":\"address\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_initializationContractAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"InitializationFunctionReverted\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"DiamondCut\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_functionSelector\",\"type\":\"bytes4\"}],\"name\":\"facetAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"facetAddress_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetAddresses\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"facetAddresses_\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_facet\",\"type\":\"address\"}],\"name\":\"facetFunctionSelectors\",\"outputs\":[{\"internalType\":\"bytes4[]\",\"name\":\"facetFunctionSelectors_\",\"type\":\"bytes4[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facets\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondLoupe.Facet[]\",\"name\":\"facets_\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"A default fallback handler for Barz\",\"kind\":\"dev\",\"methods\":{\"constructor\":{\"details\":\"This contract is also a diamond that holds the default facets to reduce gas cost for wallet activation. Within the constructor this conducts diamond cut to initially setup the diamond. This is a non-upgradeable contract\",\"params\":{\"_accountFacet\":\"Address account facet\",\"_diamondCutFacet\":\"Address if diamond cut facet\",\"_diamondLoupeFacet\":\"Address of diamond loupe facet\",\"_tokenReceiverFacet\":\"Address of token receiver facet\"}},\"facetAddress(bytes4)\":{\"details\":\"If facet is not found return address(0).\",\"params\":{\"_functionSelector\":\"The function selector.\"},\"returns\":{\"facetAddress_\":\"The facet address.\"}},\"facetAddresses()\":{\"returns\":{\"facetAddresses_\":\"facetAddresses_\"}},\"facetFunctionSelectors(address)\":{\"params\":{\"_facet\":\"The facet address.\"},\"returns\":{\"facetFunctionSelectors_\":\"facetFunctionSelectors_\"}},\"facets()\":{\"returns\":{\"facets_\":\"The facet struct array including all facet information\"}}},\"title\":\"DefaultFallbackHandler\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"Sets the middleware diamond for Barz wallet as a fallback handler\"},\"facetAddress(bytes4)\":{\"notice\":\"Gets the facet that supports the given selector.\"},\"facetAddresses()\":{\"notice\":\"Get all the facet addresses used by a diamond.\"},\"facetFunctionSelectors(address)\":{\"notice\":\"Gets all the function selectors provided by a facet.\"},\"facets()\":{\"notice\":\"Returns the facet information of call facets registered to this diamond.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/infrastructure/DefaultFallbackHandler.sol\":\"DefaultFallbackHandler\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/introspection/IERC165.sol\\\";\\n\\n/**\\n * @dev _Available since v3.1._\\n */\\ninterface IERC1155Receiver is IERC165 {\\n /**\\n * @dev Handles the receipt of a single ERC1155 token type. This function is\\n * called at the end of a `safeTransferFrom` after the balance has been updated.\\n *\\n * NOTE: To accept the transfer, this must return\\n * `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))`\\n * (i.e. 0xf23a6e61, or its own function selector).\\n *\\n * @param operator The address which initiated the transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param id The ID of the token being transferred\\n * @param value The amount of tokens being transferred\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155Received(\\n address operator,\\n address from,\\n uint256 id,\\n uint256 value,\\n bytes calldata data\\n ) external returns (bytes4);\\n\\n /**\\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\\n * is called at the end of a `safeBatchTransferFrom` after the balances have\\n * been updated.\\n *\\n * NOTE: To accept the transfer(s), this must return\\n * `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))`\\n * (i.e. 0xbc197c81, or its own function selector).\\n *\\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155BatchReceived(\\n address operator,\\n address from,\\n uint256[] calldata ids,\\n uint256[] calldata values,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xeb373f1fdc7b755c6a750123a9b9e3a8a02c1470042fd6505d875000a80bde0b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title ERC721 token receiver interface\\n * @dev Interface for any contract that wants to support safeTransfers\\n * from ERC721 asset contracts.\\n */\\ninterface IERC721Receiver {\\n /**\\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\\n * by `operator` from `from`, this function is called.\\n *\\n * It must return its Solidity selector to confirm the token transfer.\\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\\n *\\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\\n */\\n function onERC721Received(\\n address operator,\\n address from,\\n uint256 tokenId,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\\n *\\n * Accounts can be notified of {IERC777} tokens being sent to them by having a\\n * contract implement this interface (contract holders can be their own\\n * implementer) and registering it on the\\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\\n *\\n * See {IERC1820Registry} and {ERC1820Implementer}.\\n */\\ninterface IERC777Recipient {\\n /**\\n * @dev Called by an {IERC777} token contract whenever tokens are being\\n * moved or created into a registered account (`to`). The type of operation\\n * is conveyed by `from` being the zero address or not.\\n *\\n * This call occurs _after_ the token contract's state is updated, so\\n * {IERC777-balanceOf}, etc., can be used to query the post-operation state.\\n *\\n * This function may revert to prevent the operation from being executed.\\n */\\n function tokensReceived(\\n address operator,\\n address from,\\n address to,\\n uint256 amount,\\n bytes calldata userData,\\n bytes calldata operatorData\\n ) external;\\n}\\n\",\"keccak256\":\"0x1a5d61db2733202ba361e6d6741cd2e662380e22b80e987eacfc91973f2267dc\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"contracts/aa-4337/core/BaseAccount.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-empty-blocks */\\n\\nimport \\\"../interfaces/IAccount.sol\\\";\\nimport \\\"../interfaces/IEntryPoint.sol\\\";\\nimport \\\"./Helpers.sol\\\";\\n\\n/**\\n * Basic account implementation.\\n * this contract provides the basic logic for implementing the IAccount interface - validateUserOp\\n * specific account implementation should inherit it and provide the account-specific logic\\n */\\nabstract contract BaseAccount is IAccount {\\n using UserOperationLib for UserOperation;\\n\\n //return value in case of signature failure, with no time-range.\\n // equivalent to _packValidationData(true,0,0);\\n uint256 internal constant SIG_VALIDATION_FAILED = 1;\\n\\n /**\\n * Return the account nonce.\\n * This method returns the next sequential nonce.\\n * For a nonce of a specific key, use `entrypoint.getNonce(account, key)`\\n */\\n function getNonce() public view virtual returns (uint256) {\\n return entryPoint().getNonce(address(this), 0);\\n }\\n\\n /**\\n * return the entryPoint used by this account.\\n * subclass should return the current entryPoint used by this account.\\n */\\n function entryPoint() public view virtual returns (IEntryPoint);\\n\\n /**\\n * Validate user's signature and nonce.\\n * subclass doesn't need to override this method. Instead, it should override the specific internal validation methods.\\n */\\n function validateUserOp(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n uint256 missingAccountFunds\\n ) external virtual override returns (uint256 validationData) {\\n _requireFromEntryPoint();\\n validationData = _validateSignature(userOp, userOpHash);\\n _validateNonce(userOp.nonce);\\n _payPrefund(missingAccountFunds);\\n }\\n\\n /**\\n * ensure the request comes from the known entrypoint.\\n */\\n function _requireFromEntryPoint() internal view virtual {\\n require(\\n msg.sender == address(entryPoint()),\\n \\\"account: not from EntryPoint\\\"\\n );\\n }\\n\\n /**\\n * validate the signature is valid for this message.\\n * @param userOp validate the userOp.signature field\\n * @param userOpHash convenient field: the hash of the request, to check the signature against\\n * (also hashes the entrypoint and chain id)\\n * @return validationData signature and time-range of this operation\\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\\n * otherwise, an address of an \\\"authorizer\\\" contract.\\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \\\"indefinite\\\"\\n * <6-byte> validAfter - first timestamp this operation is valid\\n * If the account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\\n */\\n function _validateSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) internal virtual returns (uint256 validationData);\\n\\n /**\\n * Validate the nonce of the UserOperation.\\n * This method may validate the nonce requirement of this account.\\n * e.g.\\n * To limit the nonce to use sequenced UserOps only (no \\\"out of order\\\" UserOps):\\n * `require(nonce < type(uint64).max)`\\n * For a hypothetical account that *requires* the nonce to be out-of-order:\\n * `require(nonce & type(uint64).max == 0)`\\n *\\n * The actual nonce uniqueness is managed by the EntryPoint, and thus no other\\n * action is needed by the account itself.\\n *\\n * @param nonce to validate\\n *\\n * solhint-disable-next-line no-empty-blocks\\n */\\n function _validateNonce(uint256 nonce) internal view virtual {}\\n\\n /**\\n * sends to the entrypoint (msg.sender) the missing funds for this transaction.\\n * subclass MAY override this method for better funds management\\n * (e.g. send to the entryPoint more than the minimum required, so that in future transactions\\n * it will not be required to send again)\\n * @param missingAccountFunds the minimum value this method should send the entrypoint.\\n * this value MAY be zero, in case there is enough deposit, or the userOp has a paymaster.\\n */\\n function _payPrefund(uint256 missingAccountFunds) internal virtual {\\n if (missingAccountFunds != 0) {\\n (bool success, ) = payable(msg.sender).call{\\n value: missingAccountFunds,\\n gas: type(uint256).max\\n }(\\\"\\\");\\n (success);\\n //ignore failure (its EntryPoint's job to verify, not account.)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa0dcc386b0f04711db3e394fb50e55a3b3b1a4d19fac1f10895844e1aa4e3d5c\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/core/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable no-inline-assembly */\\n\\n/**\\n * returned data from validateUserOp.\\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\\n * @param aggregator - address(0) - the account validated the signature by itself.\\n * address(1) - the account failed to validate the signature.\\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\\n * @param validAfter - this UserOp is valid only after this timestamp.\\n * @param validaUntil - this UserOp is valid only up to this timestamp.\\n */\\nstruct ValidationData {\\n address aggregator;\\n uint48 validAfter;\\n uint48 validUntil;\\n}\\n\\n//extract sigFailed, validAfter, validUntil.\\n// also convert zero validUntil to type(uint48).max\\nfunction _parseValidationData(\\n uint validationData\\n) pure returns (ValidationData memory data) {\\n address aggregator = address(uint160(validationData));\\n uint48 validUntil = uint48(validationData >> 160);\\n if (validUntil == 0) {\\n validUntil = type(uint48).max;\\n }\\n uint48 validAfter = uint48(validationData >> (48 + 160));\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n// intersect account and paymaster ranges.\\nfunction _intersectTimeRange(\\n uint256 validationData,\\n uint256 paymasterValidationData\\n) pure returns (ValidationData memory) {\\n ValidationData memory accountValidationData = _parseValidationData(\\n validationData\\n );\\n ValidationData memory pmValidationData = _parseValidationData(\\n paymasterValidationData\\n );\\n address aggregator = accountValidationData.aggregator;\\n if (aggregator == address(0)) {\\n aggregator = pmValidationData.aggregator;\\n }\\n uint48 validAfter = accountValidationData.validAfter;\\n uint48 validUntil = accountValidationData.validUntil;\\n uint48 pmValidAfter = pmValidationData.validAfter;\\n uint48 pmValidUntil = pmValidationData.validUntil;\\n\\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp\\n * @param data - the ValidationData to pack\\n */\\nfunction _packValidationData(\\n ValidationData memory data\\n) pure returns (uint256) {\\n return\\n uint160(data.aggregator) |\\n (uint256(data.validUntil) << 160) |\\n (uint256(data.validAfter) << (160 + 48));\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp, when not using an aggregator\\n * @param sigFailed - true for signature failure, false for success\\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\\n * @param validAfter first timestamp this UserOperation is valid\\n */\\nfunction _packValidationData(\\n bool sigFailed,\\n uint48 validUntil,\\n uint48 validAfter\\n) pure returns (uint256) {\\n return\\n (sigFailed ? 1 : 0) |\\n (uint256(validUntil) << 160) |\\n (uint256(validAfter) << (160 + 48));\\n}\\n\\n/**\\n * keccak function over calldata.\\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\\n */\\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\\n assembly {\\n let mem := mload(0x40)\\n let len := data.length\\n calldatacopy(mem, data.offset, len)\\n ret := keccak256(mem, len)\\n }\\n}\\n\",\"keccak256\":\"0xa79f06cd158ecb8c0da95493a2f348933b8627a63e228b99738bff3aa107942d\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAccount.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\ninterface IAccount {\\n /**\\n * Validate user's signature and nonce\\n * the entryPoint will make the call to the recipient only if this validation call returns successfully.\\n * signature failure should be reported by returning SIG_VALIDATION_FAILED (1).\\n * This allows making a \\\"simulation call\\\" without a valid signature\\n * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure.\\n *\\n * @dev Must validate caller is the entryPoint.\\n * Must validate the signature and nonce\\n * @param userOp the operation that is about to be executed.\\n * @param userOpHash hash of the user's request data. can be used as the basis for signature.\\n * @param missingAccountFunds missing funds on the account's deposit in the entrypoint.\\n * This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call.\\n * The excess is left as a deposit in the entrypoint, for future calls.\\n * can be withdrawn anytime using \\\"entryPoint.withdrawTo()\\\"\\n * In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero.\\n * @return validationData packaged ValidationData structure. use `_packValidationData` and `_unpackValidationData` to encode and decode\\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\\n * otherwise, an address of an \\\"authorizer\\\" contract.\\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \\\"indefinite\\\"\\n * <6-byte> validAfter - first timestamp this operation is valid\\n * If an account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\\n */\\n function validateUserOp(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n uint256 missingAccountFunds\\n ) external returns (uint256 validationData);\\n}\\n\",\"keccak256\":\"0xcbc4b0973cf954c5895b7796335f651fbfcfb55f67dfa789a3d354f8e23c4f2b\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAggregator.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\n/**\\n * Aggregated Signatures validator.\\n */\\ninterface IAggregator {\\n /**\\n * validate aggregated signature.\\n * revert if the aggregated signature does not match the given list of operations.\\n */\\n function validateSignatures(\\n UserOperation[] calldata userOps,\\n bytes calldata signature\\n ) external view;\\n\\n /**\\n * validate signature of a single userOp\\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\\n * @param userOp the userOperation received from the user.\\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\\n * (usually empty, unless account and aggregator support some kind of \\\"multisig\\\"\\n */\\n function validateUserOpSignature(\\n UserOperation calldata userOp\\n ) external view returns (bytes memory sigForUserOp);\\n\\n /**\\n * aggregate multiple signatures into a single value.\\n * This method is called off-chain to calculate the signature to pass with handleOps()\\n * bundler MAY use optimized custom code perform this aggregation\\n * @param userOps array of UserOperations to collect the signatures from.\\n * @return aggregatedSignature the aggregated signature\\n */\\n function aggregateSignatures(\\n UserOperation[] calldata userOps\\n ) external view returns (bytes memory aggregatedSignature);\\n}\\n\",\"keccak256\":\"0xdfdcd80568f037716674619b31be630fcd8316262f05a815b41d1e81782c966a\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IEntryPoint.sol\":{\"content\":\"/**\\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\\n ** Only one instance required on each chain.\\n **/\\n// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-inline-assembly */\\n/* solhint-disable reason-string */\\n\\nimport \\\"./UserOperation.sol\\\";\\nimport \\\"./IStakeManager.sol\\\";\\nimport \\\"./IAggregator.sol\\\";\\nimport \\\"./INonceManager.sol\\\";\\n\\ninterface IEntryPoint is IStakeManager, INonceManager {\\n /***\\n * An event emitted after each successful request\\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\\n * @param sender - the account that generates this request.\\n * @param paymaster - if non-null, the paymaster that pays for this request.\\n * @param nonce - the nonce value from the request.\\n * @param success - true if the sender transaction succeeded, false if reverted.\\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\\n */\\n event UserOperationEvent(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address indexed paymaster,\\n uint256 nonce,\\n bool success,\\n uint256 actualGasCost,\\n uint256 actualGasUsed\\n );\\n\\n /**\\n * account \\\"sender\\\" was deployed.\\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\\n * @param sender the account that is deployed\\n * @param factory the factory used to deploy this account (in the initCode)\\n * @param paymaster the paymaster used by this UserOp\\n */\\n event AccountDeployed(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address factory,\\n address paymaster\\n );\\n\\n /**\\n * An event emitted if the UserOperation \\\"callData\\\" reverted with non-zero length\\n * @param userOpHash the request unique identifier.\\n * @param sender the sender of this request\\n * @param nonce the nonce used in the request\\n * @param revertReason - the return bytes from the (reverted) call to \\\"callData\\\".\\n */\\n event UserOperationRevertReason(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n uint256 nonce,\\n bytes revertReason\\n );\\n\\n /**\\n * an event emitted by handleOps(), before starting the execution loop.\\n * any event emitted before this event, is part of the validation.\\n */\\n event BeforeExecution();\\n\\n /**\\n * signature aggregator used by the following UserOperationEvents within this bundle.\\n */\\n event SignatureAggregatorChanged(address indexed aggregator);\\n\\n /**\\n * a custom revert error of handleOps, to identify the offending op.\\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\\n * @param reason - revert reason\\n * The string starts with a unique code \\\"AAmn\\\", where \\\"m\\\" is \\\"1\\\" for factory, \\\"2\\\" for account and \\\"3\\\" for paymaster issues,\\n * so a failure can be attributed to the correct entity.\\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\\n */\\n error FailedOp(uint256 opIndex, string reason);\\n\\n /**\\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\\n */\\n error SignatureValidationFailed(address aggregator);\\n\\n /**\\n * Successful result from simulateValidation.\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n */\\n error ValidationResult(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo\\n );\\n\\n /**\\n * Successful result from simulateValidation, if the account returns a signature aggregator\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\\n * bundler MUST use it to verify the signature, or reject the UserOperation\\n */\\n error ValidationResultWithAggregation(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo,\\n AggregatorStakeInfo aggregatorInfo\\n );\\n\\n /**\\n * return value of getSenderAddress\\n */\\n error SenderAddressResult(address sender);\\n\\n /**\\n * return value of simulateHandleOp\\n */\\n error ExecutionResult(\\n uint256 preOpGas,\\n uint256 paid,\\n uint48 validAfter,\\n uint48 validUntil,\\n bool targetSuccess,\\n bytes targetResult\\n );\\n\\n //UserOps handled, per aggregator\\n struct UserOpsPerAggregator {\\n UserOperation[] userOps;\\n // aggregator address\\n IAggregator aggregator;\\n // aggregated signature\\n bytes signature;\\n }\\n\\n /**\\n * Execute a batch of UserOperation.\\n * no signature aggregator is used.\\n * if any account requires an aggregator (that is, it returned an aggregator when\\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\\n * @param ops the operations to execute\\n * @param beneficiary the address to receive the fees\\n */\\n function handleOps(\\n UserOperation[] calldata ops,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * Execute a batch of UserOperation with Aggregators\\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\\n * @param beneficiary the address to receive the fees\\n */\\n function handleAggregatedOps(\\n UserOpsPerAggregator[] calldata opsPerAggregator,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * generate a request Id - unique identifier for this request.\\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\\n */\\n function getUserOpHash(\\n UserOperation calldata userOp\\n ) external view returns (bytes32);\\n\\n /**\\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\\n * @param userOp the user operation to validate.\\n */\\n function simulateValidation(UserOperation calldata userOp) external;\\n\\n /**\\n * gas and return values during simulation\\n * @param preOpGas the gas used for validation (including preValidationGas)\\n * @param prefund the required prefund for this operation\\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\\n */\\n struct ReturnInfo {\\n uint256 preOpGas;\\n uint256 prefund;\\n bool sigFailed;\\n uint48 validAfter;\\n uint48 validUntil;\\n bytes paymasterContext;\\n }\\n\\n /**\\n * returned aggregated signature info.\\n * the aggregator returned by the account, and its current stake.\\n */\\n struct AggregatorStakeInfo {\\n address aggregator;\\n StakeInfo stakeInfo;\\n }\\n\\n /**\\n * Get counterfactual sender address.\\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\\n * this method always revert, and returns the address in SenderAddressResult error\\n * @param initCode the constructor code to be passed into the UserOperation.\\n */\\n function getSenderAddress(bytes memory initCode) external;\\n\\n /**\\n * simulate full execution of a UserOperation (including both validation and target execution)\\n * this method will always revert with \\\"ExecutionResult\\\".\\n * it performs full validation of the UserOperation, but ignores signature error.\\n * an optional target address is called after the userop succeeds, and its value is returned\\n * (before the entire call is reverted)\\n * Note that in order to collect the the success/failure of the target call, it must be executed\\n * with trace enabled to track the emitted events.\\n * @param op the UserOperation to simulate\\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\\n * are set to the return from that call.\\n * @param targetCallData callData to pass to target address\\n */\\n function simulateHandleOp(\\n UserOperation calldata op,\\n address target,\\n bytes calldata targetCallData\\n ) external;\\n}\\n\",\"keccak256\":\"0x9ccb1b188eda8bbf5f6c2d01bd83c3d8b2b04fcf745283051d31fe96d1d8e40f\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/INonceManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\ninterface INonceManager {\\n /**\\n * Return the next nonce for this sender.\\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\\n * But UserOp with different keys can come with arbitrary order.\\n *\\n * @param sender the account address\\n * @param key the high 192 bit of the nonce\\n * @return nonce a full nonce to pass for next UserOp with this sender.\\n */\\n function getNonce(\\n address sender,\\n uint192 key\\n ) external view returns (uint256 nonce);\\n\\n /**\\n * Manually increment the nonce of the sender.\\n * This method is exposed just for completeness..\\n * Account does NOT need to call it, neither during validation, nor elsewhere,\\n * as the EntryPoint will update the nonce regardless.\\n * Possible use-case is call it with various keys to \\\"initialize\\\" their nonces to one, so that future\\n * UserOperations will not pay extra for the first transaction with a given key.\\n */\\n function incrementNonce(uint192 key) external;\\n}\\n\",\"keccak256\":\"0xce478ad0fa0d18a3b785ac854623029e7ab463d05873dfaa365abfa1bf100912\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IStakeManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8.12;\\n\\n/**\\n * manage deposits and stakes.\\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\\n * stake is value locked for at least \\\"unstakeDelay\\\" by the staked entity.\\n */\\ninterface IStakeManager {\\n event Deposited(address indexed account, uint256 totalDeposit);\\n\\n event Withdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /// Emitted when stake or unstake delay are modified\\n event StakeLocked(\\n address indexed account,\\n uint256 totalStaked,\\n uint256 unstakeDelaySec\\n );\\n\\n /// Emitted once a stake is scheduled for withdrawal\\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\\n\\n event StakeWithdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /**\\n * @param deposit the entity's deposit\\n * @param staked true if this entity is staked.\\n * @param stake actual amount of ether staked for this entity.\\n * @param unstakeDelaySec minimum delay to withdraw the stake.\\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\\n * and the rest fit into a 2nd cell.\\n * 112 bit allows for 10^15 eth\\n * 48 bit for full timestamp\\n * 32 bit allows 150 years for unstake delay\\n */\\n struct DepositInfo {\\n uint112 deposit;\\n bool staked;\\n uint112 stake;\\n uint32 unstakeDelaySec;\\n uint48 withdrawTime;\\n }\\n\\n //API struct used by getStakeInfo and simulateValidation\\n struct StakeInfo {\\n uint256 stake;\\n uint256 unstakeDelaySec;\\n }\\n\\n /// @return info - full deposit information of given account\\n function getDepositInfo(\\n address account\\n ) external view returns (DepositInfo memory info);\\n\\n /// @return the deposit (for gas payment) of the account\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * add to the deposit of the given account\\n */\\n function depositTo(address account) external payable;\\n\\n /**\\n * add to the account's stake - amount and delay\\n * any pending unstake is first cancelled.\\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\\n */\\n function addStake(uint32 _unstakeDelaySec) external payable;\\n\\n /**\\n * attempt to unlock the stake.\\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\\n */\\n function unlockStake() external;\\n\\n /**\\n * withdraw from the (unlocked) stake.\\n * must first call unlockStake and wait for the unstakeDelay to pass\\n * @param withdrawAddress the address to send withdrawn value.\\n */\\n function withdrawStake(address payable withdrawAddress) external;\\n\\n /**\\n * withdraw from the deposit.\\n * @param withdrawAddress the address to send withdrawn value.\\n * @param withdrawAmount the amount to withdraw.\\n */\\n function withdrawTo(\\n address payable withdrawAddress,\\n uint256 withdrawAmount\\n ) external;\\n}\\n\",\"keccak256\":\"0xadcea606c9b7aafe6645441f2154a60f271330b0eee5292a632aa71c1672d546\",\"license\":\"GPL-3.0-only\"},\"contracts/aa-4337/interfaces/UserOperation.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable no-inline-assembly */\\n\\nimport {calldataKeccak} from \\\"../core/Helpers.sol\\\";\\n\\n/**\\n * User Operation struct\\n * @param sender the sender account of this request.\\n * @param nonce unique value the sender uses to verify it is not a replay.\\n * @param initCode if set, the account contract will be created by this constructor/\\n * @param callData the method call to execute on this account.\\n * @param callGasLimit the gas limit passed to the callData method call.\\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\\n * @param maxFeePerGas same as EIP-1559 gas parameter.\\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\\n */\\nstruct UserOperation {\\n address sender;\\n uint256 nonce;\\n bytes initCode;\\n bytes callData;\\n uint256 callGasLimit;\\n uint256 verificationGasLimit;\\n uint256 preVerificationGas;\\n uint256 maxFeePerGas;\\n uint256 maxPriorityFeePerGas;\\n bytes paymasterAndData;\\n bytes signature;\\n}\\n\\n/**\\n * Utility functions helpful when working with UserOperation structs.\\n */\\nlibrary UserOperationLib {\\n function getSender(\\n UserOperation calldata userOp\\n ) internal pure returns (address) {\\n address data;\\n //read sender from userOp, which is first userOp member (saves 800 gas...)\\n assembly {\\n data := calldataload(userOp)\\n }\\n return address(uint160(data));\\n }\\n\\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\\n // pay above what he signed for.\\n function gasPrice(\\n UserOperation calldata userOp\\n ) internal view returns (uint256) {\\n unchecked {\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n if (maxFeePerGas == maxPriorityFeePerGas) {\\n //legacy mode (for networks that don't support basefee opcode)\\n return maxFeePerGas;\\n }\\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\\n }\\n }\\n\\n function pack(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes memory ret) {\\n address sender = getSender(userOp);\\n uint256 nonce = userOp.nonce;\\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\\n bytes32 hashCallData = calldataKeccak(userOp.callData);\\n uint256 callGasLimit = userOp.callGasLimit;\\n uint256 verificationGasLimit = userOp.verificationGasLimit;\\n uint256 preVerificationGas = userOp.preVerificationGas;\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\\n\\n return\\n abi.encode(\\n sender,\\n nonce,\\n hashInitCode,\\n hashCallData,\\n callGasLimit,\\n verificationGasLimit,\\n preVerificationGas,\\n maxFeePerGas,\\n maxPriorityFeePerGas,\\n hashPaymasterAndData\\n );\\n }\\n\\n function hash(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes32) {\\n return keccak256(pack(userOp));\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n}\\n\",\"keccak256\":\"0x2429f5cc546bdee08c7e63858d0dda8491eaa3ab5194df884dc948c1154d2834\",\"license\":\"GPL-3.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IStorageLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"./IDiamondLoupe.sol\\\";\\n\\n/**\\n * @title LoupeFromStorage Interface\\n * @dev Interface contract to function as a loupe facet directly attached to diamond storage of Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IStorageLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facetsFromStorage()\\n external\\n view\\n returns (IDiamondLoupe.Facet[] memory);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n function facetFunctionSelectorsFromStorage(\\n address _facet\\n ) external view returns (bytes4[] memory);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n function facetAddressesFromStorage()\\n external\\n view\\n returns (address[] memory);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n function facetAddressFromStorage(\\n bytes4 _functionSelector\\n ) external view returns (address);\\n}\\n\",\"keccak256\":\"0xdf5dc9c57319e9087628c9cf9404b4f75585b76d1c2f4f59ee796c933967ea5c\",\"license\":\"Apache-2.0\"},\"contracts/facets/interfaces/IAccountFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IEntryPoint} from \\\"../../aa-4337/interfaces/IEntryPoint.sol\\\";\\n\\n/**\\n * @title Account Facet Interface\\n * @dev Interface of module contract that provides the account features and init/unitialization of signer\\n * compatible with EIP-1271 & EIP-4337\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IAccountFacet {\\n event AccountInitialized(\\n IEntryPoint indexed entryPoint,\\n bytes indexed ownerPublicKey\\n );\\n // NOTE: Added Below Event\\n event VerificationSuccess(bytes32);\\n event VerificationFailure(bytes32);\\n\\n error AccountFacet__InitializationFailure();\\n error AccountFacet__RestrictionsFailure();\\n error AccountFacet__NonExistentVerificationFacet();\\n error AccountFacet__CallNotSuccessful();\\n error AccountFacet__InvalidArrayLength();\\n\\n function initialize(\\n address verificationFacet,\\n address anEntryPoint,\\n address facetRegistry,\\n address _defaultFallBack,\\n bytes calldata _ownerPublicKey\\n ) external returns (uint256);\\n\\n function execute(address dest, uint256 value, bytes calldata func) external;\\n\\n function executeBatch(\\n address[] calldata dest,\\n uint256[] calldata value,\\n bytes[] calldata func\\n ) external;\\n}\\n\",\"keccak256\":\"0x74a9cb0b8f2f4a5148e366a401a0354426c536c012c025025d07cc25a4cd5382\",\"license\":\"Apache-2.0\"},\"contracts/infrastructure/DefaultFallbackHandler.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IERC721Receiver} from \\\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\\\";\\nimport {IERC1155Receiver} from \\\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\\\";\\nimport {IERC777Recipient} from \\\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\\\";\\nimport {BaseAccount} from \\\"../aa-4337/core/BaseAccount.sol\\\";\\nimport {DefaultLibDiamond} from \\\"../libraries/DefaultLibDiamond.sol\\\";\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IAccountFacet} from \\\"../facets/interfaces/IAccountFacet.sol\\\";\\nimport {IStorageLoupe} from \\\"../facets/base/interfaces/IStorageLoupe.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\nimport {IERC677Receiver} from \\\"../interfaces/ERC/IERC677Receiver.sol\\\";\\nimport {IERC165} from \\\"../interfaces/ERC/IERC165.sol\\\";\\n\\n/**\\n * @title DefaultFallbackHandler\\n * @dev A default fallback handler for Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract DefaultFallbackHandler is IDiamondLoupe {\\n /**\\n * @notice Sets the middleware diamond for Barz wallet as a fallback handler\\n * @dev This contract is also a diamond that holds the default facets to reduce gas cost for wallet activation.\\n * Within the constructor this conducts diamond cut to initially setup the diamond. This is a non-upgradeable contract\\n * @param _diamondCutFacet Address if diamond cut facet\\n * @param _accountFacet Address account facet\\n * @param _tokenReceiverFacet Address of token receiver facet\\n * @param _diamondLoupeFacet Address of diamond loupe facet\\n */\\n constructor(\\n address _diamondCutFacet,\\n address _accountFacet,\\n address _tokenReceiverFacet,\\n address _diamondLoupeFacet\\n ) payable {\\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](4);\\n bytes4[] memory functionSelectors = new bytes4[](1);\\n functionSelectors[0] = IDiamondCut.diamondCut.selector;\\n\\n bytes4[] memory accountFunctionSelectors = new bytes4[](5);\\n accountFunctionSelectors[0] = IAccountFacet.execute.selector;\\n accountFunctionSelectors[1] = IAccountFacet.executeBatch.selector;\\n accountFunctionSelectors[2] = BaseAccount.validateUserOp.selector;\\n accountFunctionSelectors[3] = BaseAccount.getNonce.selector;\\n accountFunctionSelectors[4] = BaseAccount.entryPoint.selector;\\n\\n bytes4[] memory receiverFacetSelectors = new bytes4[](5);\\n receiverFacetSelectors[0] = IERC721Receiver.onERC721Received.selector;\\n receiverFacetSelectors[1] = IERC1155Receiver.onERC1155Received.selector;\\n receiverFacetSelectors[2] = IERC1155Receiver\\n .onERC1155BatchReceived\\n .selector;\\n receiverFacetSelectors[3] = IERC777Recipient.tokensReceived.selector;\\n receiverFacetSelectors[4] = IERC677Receiver.onTokenTransfer.selector;\\n\\n bytes4[] memory loupeFacetSelectors = new bytes4[](9);\\n loupeFacetSelectors[0] = IDiamondLoupe.facets.selector;\\n loupeFacetSelectors[1] = IDiamondLoupe.facetFunctionSelectors.selector;\\n loupeFacetSelectors[2] = IDiamondLoupe.facetAddresses.selector;\\n loupeFacetSelectors[3] = IDiamondLoupe.facetAddress.selector;\\n loupeFacetSelectors[4] = IERC165.supportsInterface.selector;\\n loupeFacetSelectors[5] = IStorageLoupe.facetsFromStorage.selector;\\n loupeFacetSelectors[6] = IStorageLoupe\\n .facetFunctionSelectorsFromStorage\\n .selector;\\n loupeFacetSelectors[7] = IStorageLoupe\\n .facetAddressesFromStorage\\n .selector;\\n loupeFacetSelectors[8] = IStorageLoupe.facetAddressFromStorage.selector;\\n\\n {\\n cut[0] = IDiamondCut.FacetCut({\\n facetAddress: _diamondCutFacet,\\n action: IDiamondCut.FacetCutAction.Add,\\n functionSelectors: functionSelectors\\n });\\n cut[1] = IDiamondCut.FacetCut({\\n facetAddress: _accountFacet,\\n action: IDiamondCut.FacetCutAction.Add,\\n functionSelectors: accountFunctionSelectors\\n });\\n cut[2] = IDiamondCut.FacetCut({\\n facetAddress: _tokenReceiverFacet,\\n action: IDiamondCut.FacetCutAction.Add,\\n functionSelectors: receiverFacetSelectors\\n });\\n cut[3] = IDiamondCut.FacetCut({\\n facetAddress: _diamondLoupeFacet,\\n action: IDiamondCut.FacetCutAction.Add,\\n functionSelectors: loupeFacetSelectors\\n });\\n\\n DefaultLibDiamond.diamondCut(cut, address(0), \\\"\\\");\\n }\\n }\\n\\n /**\\n * @notice Returns the facet information of call facets registered to this diamond.\\n * @return facets_ The facet struct array including all facet information\\n */\\n function facets() external view override returns (Facet[] memory facets_) {\\n DefaultLibDiamond.DiamondStorage storage ds = DefaultLibDiamond\\n .diamondStorage();\\n uint256 numFacets = ds.facetAddresses.length;\\n facets_ = new Facet[](numFacets);\\n for (uint256 i; i < numFacets; ) {\\n address facetAddress_ = ds.facetAddresses[i];\\n facets_[i].facetAddress = facetAddress_;\\n facets_[i].functionSelectors = ds\\n .facetFunctionSelectors[facetAddress_]\\n .functionSelectors;\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * @notice Gets all the function selectors provided by a facet.\\n * @param _facet The facet address.\\n * @return facetFunctionSelectors_\\n */\\n function facetFunctionSelectors(\\n address _facet\\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\\n facetFunctionSelectors_ = DefaultLibDiamond\\n .diamondStorage()\\n .facetFunctionSelectors[_facet]\\n .functionSelectors;\\n }\\n\\n /**\\n * @notice Get all the facet addresses used by a diamond.\\n * @return facetAddresses_\\n */\\n function facetAddresses()\\n external\\n view\\n override\\n returns (address[] memory facetAddresses_)\\n {\\n facetAddresses_ = DefaultLibDiamond.diamondStorage().facetAddresses;\\n }\\n\\n /** @notice Gets the facet that supports the given selector.\\n * @dev If facet is not found return address(0).\\n * @param _functionSelector The function selector.\\n * @return facetAddress_ The facet address.\\n */\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view override returns (address facetAddress_) {\\n facetAddress_ = DefaultLibDiamond\\n .diamondStorage()\\n .selectorToFacetAndPosition[_functionSelector]\\n .facetAddress;\\n }\\n}\\n\",\"keccak256\":\"0xa482fe778481e34e9fb3c4074231f8048437e934c0ca9a0c78e8e61d3a24470a\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.21;\\n\\ninterface IERC165 {\\n /// @notice Query if a contract implements an interface\\n /// @param interfaceId The interface identifier, as specified in ERC-165\\n /// @dev Interface identification is specified in ERC-165. This function\\n /// uses less than 30,000 gas.\\n /// @return `true` if the contract implements `interfaceID` and\\n /// `interfaceID` is not 0xffffffff, `false` otherwise\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xbb7f07e170898793c5535cc4b7e8944c4b990a631ac806d0b788e794abc788a3\",\"license\":\"MIT\"},\"contracts/interfaces/ERC/IERC677Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC677Receiver {\\n function onTokenTransfer(\\n address sender,\\n uint value,\\n bytes calldata data\\n ) external pure returns (bool);\\n}\\n\",\"keccak256\":\"0x4c1631cf45ea6daac0ec158c3edb9453099130b6b64f697004b83f95aa1f7350\",\"license\":\"Apache-2.0\"},\"contracts/libraries/DefaultLibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary DefaultLibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (\\n uint256 facetIndex;\\n facetIndex < _diamondCut.length;\\n facetIndex++\\n ) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(\\n address _facetAddress,\\n bytes4[] memory _functionSelectors\\n ) internal {\\n uint256 funcSelectorsLength = _functionSelectors.length;\\n require(\\n funcSelectorsLength > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _facetAddress != address(0),\\n \\\"LibDiamondCut: Add facet can't be address(0)\\\"\\n );\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (\\n uint256 selectorIndex;\\n selectorIndex < funcSelectorsLength;\\n selectorIndex++\\n ) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds\\n .selectorToFacetAndPosition[selector]\\n .facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(\\n address _facetAddress,\\n bytes4[] memory _functionSelectors\\n ) internal {\\n uint256 funcSelectorsLength = _functionSelectors.length;\\n require(\\n funcSelectorsLength > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _facetAddress != address(0),\\n \\\"LibDiamondCut: Replace facet can't be address(0)\\\"\\n );\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (\\n uint256 selectorIndex;\\n selectorIndex < funcSelectorsLength;\\n selectorIndex++\\n ) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds\\n .selectorToFacetAndPosition[selector]\\n .facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same facet\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(\\n address _facetAddress,\\n bytes4[] memory _functionSelectors\\n ) internal {\\n uint256 funcSelectorsLength = _functionSelectors.length;\\n require(\\n funcSelectorsLength > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(\\n _facetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n for (\\n uint256 selectorIndex;\\n selectorIndex < funcSelectorsLength;\\n selectorIndex++\\n ) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds\\n .selectorToFacetAndPosition[selector]\\n .facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(\\n DiamondStorage storage ds,\\n address _facetAddress\\n ) internal {\\n enforceHasContractCode(\\n _facetAddress,\\n \\\"LibDiamondCut: New facet has no code\\\"\\n );\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds\\n .facetAddresses\\n .length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds\\n .selectorToFacetAndPosition[_selector]\\n .functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(\\n _selector\\n );\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(\\n _facetAddress != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // an immutable function is a function defined directly in a diamond\\n require(\\n _facetAddress != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds\\n .selectorToFacetAndPosition[_selector]\\n .functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors[lastSelectorPosition];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n selectorPosition\\n ] = lastSelector;\\n ds\\n .selectorToFacetAndPosition[lastSelector]\\n .functionSelectorPosition = uint96(selectorPosition);\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[\\n lastFacetAddressPosition\\n ];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds\\n .facetFunctionSelectors[lastFacetAddress]\\n .facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds\\n .facetFunctionSelectors[_facetAddress]\\n .facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x1b08f332d62919288bb1f0d154ca4b85f4e167d2a06e680f8ec93dba65be3be1\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x6080604052604051620020183803806200201883398101604081905262000026916200156b565b60408051600480825260a08201909252600091816020015b604080516060808201835260008083526020830152918101919091528152602001906001900390816200003e5750506040805160018082528183019092529192506000919060208083019080368337019050509050631f931c1c60e01b81600081518110620000b157620000b1620015c8565b6001600160e01b03199290921660209283029190910182015260408051600580825260c08201909252600092909190820160a08036833701905050905063b61d27f660e01b816000815181106200010c576200010c620015c8565b6001600160e01b03199092166020928302919091019091015280516323f0ed1560e11b9082906001908110620001465762000146620015c8565b6001600160e01b0319909216602092830291909101909101528051633a871cdd60e01b9082906002908110620001805762000180620015c8565b6001600160e01b0319909216602092830291909101909101528051631a10fa5160e31b9082906003908110620001ba57620001ba620015c8565b6001600160e01b031990921660209283029190910190910152805163586b48ff60e11b9082906004908110620001f457620001f4620015c8565b6001600160e01b03199290921660209283029190910182015260408051600580825260c08201909252600092909190820160a08036833701905050905063150b7a0260e01b816000815181106200024f576200024f620015c8565b6001600160e01b031990921660209283029190910190910152805163f23a6e6160e01b9082906001908110620002895762000289620015c8565b6001600160e01b031990921660209283029190910190910152805163bc197c8160e01b9082906002908110620002c357620002c3620015c8565b6001600160e01b03199092166020928302919091019091015280516223de2960e01b9082906003908110620002fc57620002fc620015c8565b6001600160e01b0319909216602092830291909101909101528051635260769b60e11b9082906004908110620003365762000336620015c8565b6001600160e01b0319929092166020928302919091018201526040805160098082526101408201909252600092909190820161012080368337019050509050637a0ed62760e01b81600081518110620003935762000393620015c8565b6001600160e01b03199092166020928302919091019091015280516356fe50af60e11b9082906001908110620003cd57620003cd620015c8565b6001600160e01b03199092166020928302919091019091015280516314bbdacb60e21b9082906002908110620004075762000407620015c8565b6001600160e01b03199092166020928302919091019091015280516366ffd66360e11b9082906003908110620004415762000441620015c8565b6001600160e01b03199092166020928302919091019091015280516301ffc9a760e01b90829060049081106200047b576200047b620015c8565b6001600160e01b031990921660209283029190910190910152805163f9796ccf60e01b9082906005908110620004b557620004b5620015c8565b6001600160e01b031990921660209283029190910190910152805162d2a81160e11b9082906006908110620004ee57620004ee620015c8565b6001600160e01b031990921660209283029190910190910152805163d42139a960e01b9082906007908110620005285762000528620015c8565b6001600160e01b03199092166020928302919091019091015280516371d17b7f60e11b9082906008908110620005625762000562620015c8565b6001600160e01b031990921660209283029190910182015260408051606081019091526001600160a01b038b168152908101600081526020018581525085600081518110620005b557620005b5620015c8565b60200260200101819052506040518060600160405280896001600160a01b0316815260200160006002811115620005f057620005f0620015de565b815260200184815250856001815181106200060f576200060f620015c8565b60200260200101819052506040518060600160405280886001600160a01b03168152602001600060028111156200064a576200064a620015de565b81526020018381525085600281518110620006695762000669620015c8565b60200260200101819052506040518060600160405280876001600160a01b0316815260200160006002811115620006a457620006a4620015de565b81526020018281525085600381518110620006c357620006c3620015c8565b6020026020010181905250620006f1856000604051806020016040528060008152506200070060201b60201c565b5050505050505050506200184c565b60005b83518110156200090c576000848281518110620007245762000724620015c8565b602002602001015160200151905060006002811115620007485762000748620015de565b8160028111156200075d576200075d620015de565b03620007bb57620007b58583815181106200077c576200077c620015c8565b6020026020010151600001518684815181106200079d576200079d620015c8565b6020026020010151604001516200095b60201b60201c565b620008f6565b6001816002811115620007d257620007d2620015de565b036200082a57620007b5858381518110620007f157620007f1620015c8565b602002602001015160000151868481518110620008125762000812620015c8565b60200260200101516040015162000bf760201b60201c565b6002816002811115620008415762000841620015de565b036200089957620007b5858381518110620008605762000860620015c8565b602002602001015160000151868481518110620008815762000881620015c8565b60200260200101516040015162000ea160201b60201c565b60405162461bcd60e51b815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f727265637420466163657443756044820152663a20b1ba34b7b760c91b60648201526084015b60405180910390fd5b508062000903816200160a565b91505062000703565b507f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb67383838360405162000942939291906200167a565b60405180910390a162000956828262001005565b505050565b805180620009af5760405162461bcd60e51b815260206004820152602b602482015260008051602062001ff883398151915260448201526a1858d95d081d1bc818dd5d60aa1b6064820152608401620008ed565b60008051602062001f8c8339815191526001600160a01b03841662000a2c5760405162461bcd60e51b815260206004820152602c60248201527f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260448201526b65206164647265737328302960a01b6064820152608401620008ed565b6001600160a01b0384166000908152600182016020526040812054906001600160601b038216900362000a655762000a658286620010dd565b60005b8381101562000bef57600085828151811062000a885762000a88620015c8565b6020908102919091018101516001600160e01b031981166000908152918690526040909120549091506001600160a01b0316801562000b305760405162461bcd60e51b815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c72656164792065786973747300000000000000000000006064820152608401620008ed565b6001600160e01b0319821660008181526020878152604080832080546001600160a01b03908116600160a01b6001600160601b038c16021782558d168085526001808c0185529285208054938401815585528385206008840401805463ffffffff60079095166004026101000a948502191660e08a901c94909402939093179092559390925287905281546001600160a01b0319161790558362000bd48162001781565b9450505050808062000be6906200160a565b91505062000a68565b505050505050565b80518062000c4b5760405162461bcd60e51b815260206004820152602b602482015260008051602062001ff883398151915260448201526a1858d95d081d1bc818dd5d60aa1b6064820152608401620008ed565b60008051602062001f8c8339815191526001600160a01b03841662000ccc5760405162461bcd60e51b815260206004820152603060248201527f4c69624469616d6f6e644375743a205265706c6163652066616365742063616e60448201526f2774206265206164647265737328302960801b6064820152608401620008ed565b6001600160a01b0384166000908152600182016020526040812054906001600160601b038216900362000d055762000d058286620010dd565b60005b8381101562000bef57600085828151811062000d285762000d28620015c8565b6020908102919091018101516001600160e01b031981166000908152918690526040909120549091506001600160a01b03908116908816810362000dd55760405162461bcd60e51b815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d6520666163657400000000000000000000006064820152608401620008ed565b62000de28582846200114a565b6001600160e01b0319821660008181526020878152604080832080546001600160a01b03908116600160a01b6001600160601b038c16021782558d168085526001808c0185529285208054938401815585528385206008840401805463ffffffff60079095166004026101000a948502191660e08a901c94909402939093179092559390925287905281546001600160a01b0319161790558362000e868162001781565b9450505050808062000e98906200160a565b91505062000d08565b80518062000ef55760405162461bcd60e51b815260206004820152602b602482015260008051602062001ff883398151915260448201526a1858d95d081d1bc818dd5d60aa1b6064820152608401620008ed565b60008051602062001f8c8339815191526001600160a01b0384161562000f845760405162461bcd60e51b815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d7573742062652061646472657373283029000000000000000000006064820152608401620008ed565b60005b8281101562000ffe57600084828151811062000fa75762000fa7620015c8565b6020908102919091018101516001600160e01b031981166000908152918590526040909120549091506001600160a01b031662000fe68482846200114a565b5050808062000ff5906200160a565b91505062000f87565b5050505050565b6001600160a01b03821662001018575050565b6200103d8260405180606001604052806028815260200162001fac602891396200152a565b600080836001600160a01b0316836040516200105a9190620017b2565b600060405180830381855af49150503d806000811462001097576040519150601f19603f3d011682016040523d82523d6000602084013e6200109c565b606091505b509150915081620010d757805115620010b85780518082602001fd5b838360405163192105d760e01b8152600401620008ed929190620017d0565b50505050565b620011028160405180606001604052806024815260200162001fd4602491396200152a565b6002820180546001600160a01b0390921660008181526001948501602090815260408220860185905594840183559182529290200180546001600160a01b0319169091179055565b6001600160a01b038216620011c85760405162461bcd60e51b815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608401620008ed565b306001600160a01b03831603620012395760405162461bcd60e51b815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201526d3a30b1363290333ab731ba34b7b760911b6064820152608401620008ed565b6001600160e01b03198116600090815260208481526040808320546001600160a01b0386168452600180880190935290832054600160a01b9091046001600160601b031692916200128a91620017fe565b905080821462001383576001600160a01b03841660009081526001860160205260408120805483908110620012c357620012c3620015c8565b600091825260208083206008830401546001600160a01b038916845260018a019091526040909220805460079092166004026101000a90920460e01b925082919085908110620013175762001317620015c8565b600091825260208083206008830401805463ffffffff60079094166004026101000a938402191660e09590951c929092029390931790556001600160e01b03199290921682528690526040902080546001600160a01b0316600160a01b6001600160601b038516021790555b6001600160a01b03841660009081526001860160205260409020805480620013af57620013af6200181a565b60008281526020808220600860001990940193840401805463ffffffff600460078716026101000a0219169055919092556001600160e01b0319851682528690526040812081905581900362000ffe5760028501546000906200141590600190620017fe565b6001600160a01b0386166000908152600180890160205260409091200154909150808214620014cb576000876002018381548110620014585762001458620015c8565b6000918252602090912001546002890180546001600160a01b0390921692508291849081106200148c576200148c620015c8565b600091825260208083209190910180546001600160a01b0319166001600160a01b03948516179055929091168152600189810190925260409020018190555b86600201805480620014e157620014e16200181a565b60008281526020808220830160001990810180546001600160a01b03191690559092019092556001600160a01b0388168252600189810190915260408220015550505050505050565b813b8181620010d75760405162461bcd60e51b8152600401620008ed919062001830565b80516001600160a01b03811681146200156657600080fd5b919050565b600080600080608085870312156200158257600080fd5b6200158d856200154e565b93506200159d602086016200154e565b9250620015ad604086016200154e565b9150620015bd606086016200154e565b905092959194509250565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016200161f576200161f620015f4565b5060010190565b60005b838110156200164357818101518382015260200162001629565b50506000910152565b600081518084526200166681602086016020860162001626565b601f01601f19169290920160200192915050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b848110156200174f57898403607f19018652815180516001600160a01b03168552838101518986019060038110620016eb57634e487b7160e01b600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b80831015620017395783516001600160e01b03191682529286019260019290920191908601906200170d565b50978501979550505090820190600101620016a3565b50506001600160a01b038a169088015286810360408801526200177381896200164c565b9a9950505050505050505050565b60006001600160601b038281166002600160601b03198101620017a857620017a8620015f4565b6001019392505050565b60008251620017c681846020870162001626565b9190910192915050565b6001600160a01b0383168152604060208201819052600090620017f6908301846200164c565b949350505050565b81810381811115620018145762001814620015f4565b92915050565b634e487b7160e01b600052603160045260246000fd5b6020815260006200184560208301846200164c565b9392505050565b610730806200185c6000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806352ef6b2c146100515780637a0ed6271461006f578063adfca15e14610084578063cdffacc6146100a4575b600080fd5b610059610140565b60405161006691906104ab565b60405180910390f35b6100776101d1565b6040516100669190610562565b61009761009236600461060a565b6103d1565b6040516100669190610647565b61011b6100b236600461065a565b7fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610066565b60607f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6002018054806020026020016040519081016040528092919081815260200182805480156101c757602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161019c575b5050505050905090565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f908067ffffffffffffffff8111156102315761023161069c565b60405190808252806020026020018201604052801561027757816020015b60408051808201909152600081526060602082015281526020019060019003908161024f5790505b50925060005b818110156103cb57600083600201828154811061029c5761029c6106cb565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050808583815181106102dc576102dc6106cb565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff928316905290821660009081526001860182526040908190208054825181850281018501909352808352919290919083018282801561039d57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161034a5790505b50505050508583815181106103b4576103b46106cb565b60209081029190910181015101525060010161027d565b50505090565b73ffffffffffffffffffffffffffffffffffffffff811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4920602090815260409182902080548351818402810184019094528084526060939283018282801561049f57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161044c5790505b50505050509050919050565b6020808252825182820181905260009190848201906040850190845b818110156104f957835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016104c7565b50909695505050505050565b600081518084526020808501945080840160005b838110156105575781517fffffffff000000000000000000000000000000000000000000000000000000001687529582019590820190600101610519565b509495945050505050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b838110156105fc578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00185528151805173ffffffffffffffffffffffffffffffffffffffff1684528701518784018790526105e987850182610505565b9588019593505090860190600101610589565b509098975050505050505050565b60006020828403121561061c57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461064057600080fd5b9392505050565b6020815260006106406020830184610505565b60006020828403121561066c57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461064057600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea264697066735822122024a872696a5ad50024326567061c50adea63ff0d49edf0ac60339459d33d571664736f6c63430008150033183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f4c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a204e657720666163657420686173206e6f20636f64654c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e2066", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806352ef6b2c146100515780637a0ed6271461006f578063adfca15e14610084578063cdffacc6146100a4575b600080fd5b610059610140565b60405161006691906104ab565b60405180910390f35b6100776101d1565b6040516100669190610562565b61009761009236600461060a565b6103d1565b6040516100669190610647565b61011b6100b236600461065a565b7fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610066565b60607f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6002018054806020026020016040519081016040528092919081815260200182805480156101c757602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161019c575b5050505050905090565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f908067ffffffffffffffff8111156102315761023161069c565b60405190808252806020026020018201604052801561027757816020015b60408051808201909152600081526060602082015281526020019060019003908161024f5790505b50925060005b818110156103cb57600083600201828154811061029c5761029c6106cb565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050808583815181106102dc576102dc6106cb565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff928316905290821660009081526001860182526040908190208054825181850281018501909352808352919290919083018282801561039d57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161034a5790505b50505050508583815181106103b4576103b46106cb565b60209081029190910181015101525060010161027d565b50505090565b73ffffffffffffffffffffffffffffffffffffffff811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4920602090815260409182902080548351818402810184019094528084526060939283018282801561049f57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161044c5790505b50505050509050919050565b6020808252825182820181905260009190848201906040850190845b818110156104f957835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016104c7565b50909695505050505050565b600081518084526020808501945080840160005b838110156105575781517fffffffff000000000000000000000000000000000000000000000000000000001687529582019590820190600101610519565b509495945050505050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b838110156105fc578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00185528151805173ffffffffffffffffffffffffffffffffffffffff1684528701518784018790526105e987850182610505565b9588019593505090860190600101610589565b509098975050505050505050565b60006020828403121561061c57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461064057600080fd5b9392505050565b6020815260006106406020830184610505565b60006020828403121561066c57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461064057600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea264697066735822122024a872696a5ad50024326567061c50adea63ff0d49edf0ac60339459d33d571664736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "A default fallback handler for Barz", + "kind": "dev", + "methods": { + "constructor": { + "details": "This contract is also a diamond that holds the default facets to reduce gas cost for wallet activation. Within the constructor this conducts diamond cut to initially setup the diamond. This is a non-upgradeable contract", + "params": { + "_accountFacet": "Address account facet", + "_diamondCutFacet": "Address if diamond cut facet", + "_diamondLoupeFacet": "Address of diamond loupe facet", + "_tokenReceiverFacet": "Address of token receiver facet" + } + }, + "facetAddress(bytes4)": { + "details": "If facet is not found return address(0).", + "params": { + "_functionSelector": "The function selector." + }, + "returns": { + "facetAddress_": "The facet address." + } + }, + "facetAddresses()": { + "returns": { + "facetAddresses_": "facetAddresses_" + } + }, + "facetFunctionSelectors(address)": { + "params": { + "_facet": "The facet address." + }, + "returns": { + "facetFunctionSelectors_": "facetFunctionSelectors_" + } + }, + "facets()": { + "returns": { + "facets_": "The facet struct array including all facet information" + } + } + }, + "title": "DefaultFallbackHandler", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "constructor": { + "notice": "Sets the middleware diamond for Barz wallet as a fallback handler" + }, + "facetAddress(bytes4)": { + "notice": "Gets the facet that supports the given selector." + }, + "facetAddresses()": { + "notice": "Get all the facet addresses used by a diamond." + }, + "facetFunctionSelectors(address)": { + "notice": "Gets all the function selectors provided by a facet." + }, + "facets()": { + "notice": "Returns the facet information of call facets registered to this diamond." + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/optimism/DiamondCutFacet.json b/deployments/optimism/DiamondCutFacet.json new file mode 100644 index 0000000..155ee78 --- /dev/null +++ b/deployments/optimism/DiamondCutFacet.json @@ -0,0 +1,856 @@ +{ + "address": "0x0B9504140771C3688Ff041917192277D2f52E1e0", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_securityManager", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "CallerNotGuardian", + "type": "error" + }, + { + "inputs": [], + "name": "CallerNotGuardianOrOwner", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__CannotRevokeUnapproved", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__DuplicateApproval", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InsufficientApprovers", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidApprovalValidationPeriod", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidApprover", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidApproverSignature", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidArrayLength", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidInitAddress", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidRouteWithGuardian", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidRouteWithoutGuardian", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__LackOfOwnerApproval", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__OwnerAlreadyApproved", + "type": "error" + }, + { + "inputs": [], + "name": "DuplicateApprover", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_initializationContractAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "InitializationFunctionReverted", + "type": "error" + }, + { + "inputs": [], + "name": "UnregisteredFacetAndSelectors", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroApproverLength", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "indexed": false, + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "DiamondCut", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "diamondCut", + "type": "tuple[]" + } + ], + "name": "DiamondCutApprovalRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "diamondCut", + "type": "tuple[]" + } + ], + "name": "DiamondCutApproved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + }, + { + "indexed": false, + "internalType": "bool", + "name": "_lag", + "type": "bool" + } + ], + "name": "SupportsInterfaceUpdated", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_diamondCutHash", + "type": "bytes32" + }, + { + "internalType": "address[]", + "name": "_approvers", + "type": "address[]" + } + ], + "name": "_checkDuplicateOnChainApprover", + "outputs": [], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + } + ], + "name": "approveDiamondCut", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "diamondCut", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "internalType": "address[]", + "name": "_approvers", + "type": "address[]" + }, + { + "internalType": "bytes[]", + "name": "_signatures", + "type": "bytes[]" + } + ], + "name": "diamondCutWithGuardian", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_diamondCutHash", + "type": "bytes32" + } + ], + "name": "getDiamondCutApprovalCountWithTimeValidity", + "outputs": [ + { + "internalType": "uint256", + "name": "approvalCount", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + } + ], + "name": "getDiamondCutHash", + "outputs": [ + { + "internalType": "bytes32", + "name": "cutHash", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getDiamondCutNonce", + "outputs": [ + { + "internalType": "uint128", + "name": "cutNonce", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_diamondCutHash", + "type": "bytes32" + } + ], + "name": "getOwnerCutApprovalWithTimeValidity", + "outputs": [ + { + "internalType": "bool", + "name": "isApprovedByOwner", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_diamondCutHash", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "_approver", + "type": "address" + } + ], + "name": "isCutApproved", + "outputs": [ + { + "internalType": "bool", + "name": "isApproved", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + } + ], + "name": "revokeDiamondCutApproval", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "securityManager", + "outputs": [ + { + "internalType": "contract ISecurityManager", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_interfaceId", + "type": "bytes4" + }, + { + "internalType": "bool", + "name": "_flag", + "type": "bool" + } + ], + "name": "updateSupportsInterface", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0xbfc7df5fbb9cbabdacd4794e7b4fafd6577a7179e6270a5acc7d523dc3da4aaf", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 6, + "gasUsed": "3078987", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x68da9552123c740a1280cdfa0e62adaa6b87fb4bfaadd64027803af1fd97d2c1", + "transactionHash": "0xbfc7df5fbb9cbabdacd4794e7b4fafd6577a7179e6270a5acc7d523dc3da4aaf", + "logs": [], + "blockNumber": 112443270, + "cumulativeGasUsed": "11171058", + "status": 1, + "byzantium": true + }, + "args": [ + "0xcBe266adbfd7CB32988128e7f37b7c8b3C5521A8" + ], + "numDeployments": 3, + "solcInputHash": "4356503edd8ae34e73cb6dd1c8e2fc8a", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_securityManager\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"CallerNotGuardian\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallerNotGuardianOrOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__CannotRevokeUnapproved\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__DuplicateApproval\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InsufficientApprovers\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidApprovalValidationPeriod\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidApprover\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidApproverSignature\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidArrayLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidInitAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidRouteWithGuardian\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidRouteWithoutGuardian\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__LackOfOwnerApproval\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__OwnerAlreadyApproved\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateApprover\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_initializationContractAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"InitializationFunctionReverted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnregisteredFacetAndSelectors\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroApproverLength\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"DiamondCut\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"diamondCut\",\"type\":\"tuple[]\"}],\"name\":\"DiamondCutApprovalRevoked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"diamondCut\",\"type\":\"tuple[]\"}],\"name\":\"DiamondCutApproved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"_lag\",\"type\":\"bool\"}],\"name\":\"SupportsInterfaceUpdated\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_diamondCutHash\",\"type\":\"bytes32\"},{\"internalType\":\"address[]\",\"name\":\"_approvers\",\"type\":\"address[]\"}],\"name\":\"_checkDuplicateOnChainApprover\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"}],\"name\":\"approveDiamondCut\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"diamondCut\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"internalType\":\"address[]\",\"name\":\"_approvers\",\"type\":\"address[]\"},{\"internalType\":\"bytes[]\",\"name\":\"_signatures\",\"type\":\"bytes[]\"}],\"name\":\"diamondCutWithGuardian\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_diamondCutHash\",\"type\":\"bytes32\"}],\"name\":\"getDiamondCutApprovalCountWithTimeValidity\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"approvalCount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"}],\"name\":\"getDiamondCutHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"cutHash\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDiamondCutNonce\",\"outputs\":[{\"internalType\":\"uint128\",\"name\":\"cutNonce\",\"type\":\"uint128\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_diamondCutHash\",\"type\":\"bytes32\"}],\"name\":\"getOwnerCutApprovalWithTimeValidity\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isApprovedByOwner\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_diamondCutHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"_approver\",\"type\":\"address\"}],\"name\":\"isCutApproved\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isApproved\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"}],\"name\":\"revokeDiamondCutApproval\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"securityManager\",\"outputs\":[{\"internalType\":\"contract ISecurityManager\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_interfaceId\",\"type\":\"bytes4\"},{\"internalType\":\"bool\",\"name\":\"_flag\",\"type\":\"bool\"}],\"name\":\"updateSupportsInterface\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"Responsible for adding/removing/replace facets in Barz\",\"kind\":\"dev\",\"methods\":{\"_checkDuplicateOnChainApprover(bytes32,address[])\":{\"params\":{\"_approvers\":\"List of approver addresses\",\"_diamondCutHash\":\"Hash of diamondCut information including the facet addresses and function selectors\"}},\"approveDiamondCut((address,uint8,bytes4[])[])\":{\"params\":{\"_diamondCut\":\"Contains the facet addresses and function selectors\"}},\"constructor\":{\"params\":{\"_securityManager\":\"Security Manager contract that holds the security related variables for all wallets\"}},\"diamondCut((address,uint8,bytes4[])[],address,bytes)\":{\"params\":{\"_diamondCut\":\"Contains the facet addresses and function selectors\",\"_init\":\"The address of the contract or facet to execute _calldata. It's prohibited in Barz\"}},\"diamondCutWithGuardian((address,uint8,bytes4[])[],address[],bytes[])\":{\"params\":{\"_approvers\":\"Guardian or owner address that approves the diamond cut\",\"_diamondCut\":\"Contains the facet addresses and function selectors\",\"_signatures\":\"Signature of Guardians or owner that approves the diamond cut\"}},\"getDiamondCutApprovalCountWithTimeValidity(bytes32)\":{\"params\":{\"_diamondCutHash\":\"Hash of diamondCut information including the facet addresses and function selectors\"}},\"getDiamondCutHash((address,uint8,bytes4[])[])\":{\"params\":{\"_diamondCut\":\"Contains the facet addresses and function selectors\"},\"returns\":{\"cutHash\":\"Diamond Cut Hash\"}},\"getDiamondCutNonce()\":{\"details\":\"This method fetches the nonce from diamond cut storage\",\"returns\":{\"cutNonce\":\"Nonce of diamond cut to protect from reply attacks\"}},\"getOwnerCutApprovalWithTimeValidity(bytes32)\":{\"params\":{\"_diamondCutHash\":\"Hash of diamondCut information including the facet addresses and function selectors\"},\"returns\":{\"isApprovedByOwner\":\"Bool value showing if the owner approved the cut\"}},\"isCutApproved(bytes32,address)\":{\"params\":{\"_approver\":\"Address of approver\",\"_diamondCutHash\":\"Hash of diamondCut information including the facet addresses and function selectors\"},\"returns\":{\"isApproved\":\"Bool value showing if the approver approved the cut\"}},\"revokeDiamondCutApproval((address,uint8,bytes4[])[])\":{\"params\":{\"_diamondCut\":\"Contains the facet addresses and function selectors\"}},\"updateSupportsInterface(bytes4,bool)\":{\"params\":{\"_flag\":\"Bool value to update the mapping of the given interface ID\",\"_interfaceId\":\"InterfaceID to update the mapping\"}}},\"title\":\"DiamondCut Facet\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"_checkDuplicateOnChainApprover(bytes32,address[])\":{\"notice\":\"Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval Approvers who approved on-chain should not be included in the off-chain approval\"},\"approveDiamondCut((address,uint8,bytes4[])[])\":{\"notice\":\"Approves diamond cut. This can only be called directly from guardian or owner\"},\"constructor\":{\"notice\":\"This constructor sets the Security Manager address which is an immutable variable. Immutable variables do not impact the storage of diamond\"},\"diamondCut((address,uint8,bytes4[])[],address,bytes)\":{\"notice\":\"Add/replace/remove any number of functions and optionally execute a function with delegatecall when guardians don't exist\"},\"diamondCutWithGuardian((address,uint8,bytes4[])[],address[],bytes[])\":{\"notice\":\"Add/replace/remove any number of functions and optionally execute a function with delegatecall when guardians exist\"},\"getDiamondCutApprovalCountWithTimeValidity(bytes32)\":{\"notice\":\"Gets the number of approvals of diamond cut from guardians\"},\"getDiamondCutHash((address,uint8,bytes4[])[])\":{\"notice\":\"Returns the diamond cut hash. This function ensures that this hash is safe from replay attack by including salt, address, chainId, and nonce, etc.\"},\"getDiamondCutNonce()\":{\"notice\":\"Returns the diamond cut nonce of this wallet\"},\"getOwnerCutApprovalWithTimeValidity(bytes32)\":{\"notice\":\"Returns if the owner has approved the diamond cut\"},\"isCutApproved(bytes32,address)\":{\"notice\":\"Returns if the given approver has approved the diamond cut\"},\"revokeDiamondCutApproval((address,uint8,bytes4[])[])\":{\"notice\":\"Revokes the approval of diamond cut. This can only be called directly from guardian or owner\"},\"updateSupportsInterface(bytes4,bool)\":{\"notice\":\"Updates the flag for the interfaceId\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/base/DiamondCutFacet.sol\":\"DiamondCutFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/interfaces/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC1271 standard signature validation method for\\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC1271 {\\n /**\\n * @dev Should return whether the signature provided is valid for the provided data\\n * @param hash Hash of the data to be signed\\n * @param signature Signature byte array associated with _data\\n */\\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\\n}\\n\",\"keccak256\":\"0x0705a4b1b86d7b0bd8432118f226ba139c44b9dcaba0a6eafba2dd7d0639c544\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./math/Math.sol\\\";\\nimport \\\"./math/SignedMath.sol\\\";\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n uint256 length = Math.log10(value) + 1;\\n string memory buffer = new string(length);\\n uint256 ptr;\\n /// @solidity memory-safe-assembly\\n assembly {\\n ptr := add(buffer, add(32, length))\\n }\\n while (true) {\\n ptr--;\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\\n }\\n value /= 10;\\n if (value == 0) break;\\n }\\n return buffer;\\n }\\n }\\n\\n /**\\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\\n */\\n function toString(int256 value) internal pure returns (string memory) {\\n return string(abi.encodePacked(value < 0 ? \\\"-\\\" : \\\"\\\", toString(SignedMath.abs(value))));\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n return toHexString(value, Math.log256(value) + 1);\\n }\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n\\n /**\\n * @dev Returns true if the two strings are equal.\\n */\\n function equal(string memory a, string memory b) internal pure returns (bool) {\\n return keccak256(bytes(a)) == keccak256(bytes(b));\\n }\\n}\\n\",\"keccak256\":\"0x3088eb2868e8d13d89d16670b5f8612c4ab9ff8956272837d8e90106c59c14a0\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Strings.sol\\\";\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSA {\\n enum RecoverError {\\n NoError,\\n InvalidSignature,\\n InvalidSignatureLength,\\n InvalidSignatureS,\\n InvalidSignatureV // Deprecated in v4.8\\n }\\n\\n function _throwError(RecoverError error) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert(\\\"ECDSA: invalid signature\\\");\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert(\\\"ECDSA: invalid signature length\\\");\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert(\\\"ECDSA: invalid signature 's' value\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature` or error string. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n *\\n * Documentation for signature generation:\\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n return tryRecover(hash, v, r, s);\\n } else {\\n return (address(0), RecoverError.InvalidSignatureLength);\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature`. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, signature);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\\n uint8 v = uint8((uint256(vs) >> 255) + 27);\\n return tryRecover(hash, v, r, s);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n *\\n * _Available since v4.2._\\n */\\n function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\\n // the valid range for s in (301): 0 < s < secp256k1n \\u00f7 2 + 1, and for v in (302): v \\u2208 {27, 28}. Most\\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\\n //\\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\\n // these malleable signatures as well.\\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n return (address(0), RecoverError.InvalidSignatureS);\\n }\\n\\n // If the signature is valid (and not malleable), return the signer address\\n address signer = ecrecover(hash, v, r, s);\\n if (signer == address(0)) {\\n return (address(0), RecoverError.InvalidSignature);\\n }\\n\\n return (signer, RecoverError.NoError);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore(0x00, \\\"\\\\x19Ethereum Signed Message:\\\\n32\\\")\\n mstore(0x1c, hash)\\n message := keccak256(0x00, 0x3c)\\n }\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from `s`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n\\\", Strings.toString(s.length), s));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Typed Data, created from a\\n * `domainSeparator` and a `structHash`. This produces hash corresponding\\n * to the one signed with the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n * JSON-RPC method as part of EIP-712.\\n *\\n * See {recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n let ptr := mload(0x40)\\n mstore(ptr, \\\"\\\\x19\\\\x01\\\")\\n mstore(add(ptr, 0x02), domainSeparator)\\n mstore(add(ptr, 0x22), structHash)\\n data := keccak256(ptr, 0x42)\\n }\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Data with intended validator, created from a\\n * `validator` and `data` according to the version 0 of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x00\\\", validator, data));\\n }\\n}\\n\",\"keccak256\":\"0x809bc3edb4bcbef8263fa616c1b60ee0004b50a8a1bfa164d8f57fd31f520c58\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/SignatureChecker.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./ECDSA.sol\\\";\\nimport \\\"../../interfaces/IERC1271.sol\\\";\\n\\n/**\\n * @dev Signature verification helper that can be used instead of `ECDSA.recover` to seamlessly support both ECDSA\\n * signatures from externally owned accounts (EOAs) as well as ERC1271 signatures from smart contract wallets like\\n * Argent and Gnosis Safe.\\n *\\n * _Available since v4.1._\\n */\\nlibrary SignatureChecker {\\n /**\\n * @dev Checks if a signature is valid for a given signer and data hash. If the signer is a smart contract, the\\n * signature is validated against that smart contract using ERC1271, otherwise it's validated using `ECDSA.recover`.\\n *\\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\\n */\\n function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature) internal view returns (bool) {\\n (address recovered, ECDSA.RecoverError error) = ECDSA.tryRecover(hash, signature);\\n return\\n (error == ECDSA.RecoverError.NoError && recovered == signer) ||\\n isValidERC1271SignatureNow(signer, hash, signature);\\n }\\n\\n /**\\n * @dev Checks if a signature is valid for a given signer and data hash. The signature is validated\\n * against the signer smart contract using ERC1271.\\n *\\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\\n */\\n function isValidERC1271SignatureNow(\\n address signer,\\n bytes32 hash,\\n bytes memory signature\\n ) internal view returns (bool) {\\n (bool success, bytes memory result) = signer.staticcall(\\n abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, signature)\\n );\\n return (success &&\\n result.length >= 32 &&\\n abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector));\\n }\\n}\\n\",\"keccak256\":\"0x3af3ca86df39aac39a0514c84459d691434a108d2151c8ce9d69f32e315cab80\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n enum Rounding {\\n Down, // Toward negative infinity\\n Up, // Toward infinity\\n Zero // Toward zero\\n }\\n\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow.\\n return (a & b) + (a ^ b) / 2;\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a == 0 ? 0 : (a - 1) / b + 1;\\n }\\n\\n /**\\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\\n * with further edits by Uniswap Labs also under MIT license.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\\n unchecked {\\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2^256 + prod0.\\n uint256 prod0; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division.\\n if (prod1 == 0) {\\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\\n // The surrounding unchecked block does not change this fact.\\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\\n return prod0 / denominator;\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n require(denominator > prod1, \\\"Math: mulDiv overflow\\\");\\n\\n ///////////////////////////////////////////////\\n // 512 by 256 division.\\n ///////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0].\\n uint256 remainder;\\n assembly {\\n // Compute remainder using mulmod.\\n remainder := mulmod(x, y, denominator)\\n\\n // Subtract 256 bit number from 512 bit number.\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\\n // See https://cs.stackexchange.com/q/138556/92363.\\n\\n // Does not overflow because the denominator cannot be zero at this stage in the function.\\n uint256 twos = denominator & (~denominator + 1);\\n assembly {\\n // Divide denominator by twos.\\n denominator := div(denominator, twos)\\n\\n // Divide [prod1 prod0] by twos.\\n prod0 := div(prod0, twos)\\n\\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\\n twos := add(div(sub(0, twos), twos), 1)\\n }\\n\\n // Shift in bits from prod1 into prod0.\\n prod0 |= prod1 * twos;\\n\\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\\n // four bits. That is, denominator * inv = 1 mod 2^4.\\n uint256 inverse = (3 * denominator) ^ 2;\\n\\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\\n // in modular arithmetic, doubling the correct bits in each step.\\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\\n\\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inverse;\\n return result;\\n }\\n }\\n\\n /**\\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\\n uint256 result = mulDiv(x, y, denominator);\\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\\n result += 1;\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\\n *\\n * Inspired by Henry S. Warren, Jr.'s \\\"Hacker's Delight\\\" (Chapter 11).\\n */\\n function sqrt(uint256 a) internal pure returns (uint256) {\\n if (a == 0) {\\n return 0;\\n }\\n\\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\\n //\\n // We know that the \\\"msb\\\" (most significant bit) of our target number `a` is a power of 2 such that we have\\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\\n //\\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\\n // \\u2192 `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\\n // \\u2192 `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\\n //\\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\\n uint256 result = 1 << (log2(a) >> 1);\\n\\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\\n // into the expected uint128 result.\\n unchecked {\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n return min(result, a / result);\\n }\\n }\\n\\n /**\\n * @notice Calculates sqrt(a), following the selected rounding direction.\\n */\\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = sqrt(a);\\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 2, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 128;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 64;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 32;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 16;\\n }\\n if (value >> 8 > 0) {\\n value >>= 8;\\n result += 8;\\n }\\n if (value >> 4 > 0) {\\n value >>= 4;\\n result += 4;\\n }\\n if (value >> 2 > 0) {\\n value >>= 2;\\n result += 2;\\n }\\n if (value >> 1 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log2(value);\\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 10, rounded down, of a positive value.\\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 + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 256, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n *\\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\\n */\\n function log256(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 16;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 8;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 4;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 2;\\n }\\n if (value >> 8 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log256(value);\\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe4455ac1eb7fc497bb7402579e7b4d64d928b846fce7d2b6fde06d366f21c2b3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\\n * checks.\\n *\\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\\n * easily result in undesired exploitation or bugs, since developers usually\\n * assume that overflows raise errors. `SafeCast` restores this intuition by\\n * reverting the transaction when such an operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n *\\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\\n * all math on `uint256` and `int256` and then downcasting.\\n */\\nlibrary SafeCast {\\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 * _Available since v4.7._\\n */\\n function toUint248(uint256 value) internal pure returns (uint248) {\\n require(value <= type(uint248).max, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint240(uint256 value) internal pure returns (uint240) {\\n require(value <= type(uint240).max, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint232(uint256 value) internal pure returns (uint232) {\\n require(value <= type(uint232).max, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint224(uint256 value) internal pure returns (uint224) {\\n require(value <= type(uint224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint216(uint256 value) internal pure returns (uint216) {\\n require(value <= type(uint216).max, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint208(uint256 value) internal pure returns (uint208) {\\n require(value <= type(uint208).max, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint200(uint256 value) internal pure returns (uint200) {\\n require(value <= type(uint200).max, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint192(uint256 value) internal pure returns (uint192) {\\n require(value <= type(uint192).max, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint184(uint256 value) internal pure returns (uint184) {\\n require(value <= type(uint184).max, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint176(uint256 value) internal pure returns (uint176) {\\n require(value <= type(uint176).max, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint168(uint256 value) internal pure returns (uint168) {\\n require(value <= type(uint168).max, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint160(uint256 value) internal pure returns (uint160) {\\n require(value <= type(uint160).max, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint152(uint256 value) internal pure returns (uint152) {\\n require(value <= type(uint152).max, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint144(uint256 value) internal pure returns (uint144) {\\n require(value <= type(uint144).max, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint136(uint256 value) internal pure returns (uint136) {\\n require(value <= type(uint136).max, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint128(uint256 value) internal pure returns (uint128) {\\n require(value <= type(uint128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint120(uint256 value) internal pure returns (uint120) {\\n require(value <= type(uint120).max, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint112(uint256 value) internal pure returns (uint112) {\\n require(value <= type(uint112).max, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint104(uint256 value) internal pure returns (uint104) {\\n require(value <= type(uint104).max, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint96(uint256 value) internal pure returns (uint96) {\\n require(value <= type(uint96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint88(uint256 value) internal pure returns (uint88) {\\n require(value <= type(uint88).max, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint80(uint256 value) internal pure returns (uint80) {\\n require(value <= type(uint80).max, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint72(uint256 value) internal pure returns (uint72) {\\n require(value <= type(uint72).max, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint64(uint256 value) internal pure returns (uint64) {\\n require(value <= type(uint64).max, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint56(uint256 value) internal pure returns (uint56) {\\n require(value <= type(uint56).max, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint48(uint256 value) internal pure returns (uint48) {\\n require(value <= type(uint48).max, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint40(uint256 value) internal pure returns (uint40) {\\n require(value <= type(uint40).max, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint32(uint256 value) internal pure returns (uint32) {\\n require(value <= type(uint32).max, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint24(uint256 value) internal pure returns (uint24) {\\n require(value <= type(uint24).max, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint16(uint256 value) internal pure returns (uint16) {\\n require(value <= type(uint16).max, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint8(uint256 value) internal pure returns (uint8) {\\n require(value <= type(uint8).max, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\n */\\n function toUint256(int256 value) internal pure returns (uint256) {\\n require(value >= 0, \\\"SafeCast: value must be positive\\\");\\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 * _Available since v4.7._\\n */\\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\\n downcasted = int248(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\\n downcasted = int240(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\\n downcasted = int232(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\\n downcasted = int224(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\\n downcasted = int216(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\\n downcasted = int208(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\\n downcasted = int200(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\\n downcasted = int192(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\\n downcasted = int184(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\\n downcasted = int176(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\\n downcasted = int168(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\\n downcasted = int160(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\\n downcasted = int152(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\\n downcasted = int144(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\\n downcasted = int136(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\\n downcasted = int128(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\\n downcasted = int120(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\\n downcasted = int112(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\\n downcasted = int104(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\\n downcasted = int96(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\\n downcasted = int88(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\\n downcasted = int80(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\\n downcasted = int72(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\\n downcasted = int64(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\\n downcasted = int56(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\\n downcasted = int48(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\\n downcasted = int40(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\\n downcasted = int32(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\\n downcasted = int24(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\\n downcasted = int16(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\\n downcasted = int8(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\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 require(value <= uint256(type(int256).max), \\\"SafeCast: value doesn't fit in an int256\\\");\\n return int256(value);\\n }\\n}\\n\",\"keccak256\":\"0x52a8cfb0f5239d11b457dcdd1b326992ef672714ca8da71a157255bddd13f3ad\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SignedMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard signed math utilities missing in the Solidity language.\\n */\\nlibrary SignedMath {\\n /**\\n * @dev Returns the largest of two signed numbers.\\n */\\n function max(int256 a, int256 b) internal pure returns (int256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two signed numbers.\\n */\\n function min(int256 a, int256 b) internal pure returns (int256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two signed numbers without overflow.\\n * The result is rounded towards zero.\\n */\\n function average(int256 a, int256 b) internal pure returns (int256) {\\n // Formula from the book \\\"Hacker's Delight\\\"\\n int256 x = (a & b) + ((a ^ b) >> 1);\\n return x + (int256(uint256(x) >> 255) & (a ^ b));\\n }\\n\\n /**\\n * @dev Returns the absolute unsigned value of a signed value.\\n */\\n function abs(int256 n) internal pure returns (uint256) {\\n unchecked {\\n // must be unchecked in order to support `n = type(int256).min`\\n return uint256(n >= 0 ? n : -n);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf92515413956f529d95977adc9b0567d583c6203fc31ab1c23824c35187e3ddc\",\"license\":\"MIT\"},\"contracts/aa-4337/core/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable no-inline-assembly */\\n\\n/**\\n * returned data from validateUserOp.\\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\\n * @param aggregator - address(0) - the account validated the signature by itself.\\n * address(1) - the account failed to validate the signature.\\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\\n * @param validAfter - this UserOp is valid only after this timestamp.\\n * @param validaUntil - this UserOp is valid only up to this timestamp.\\n */\\nstruct ValidationData {\\n address aggregator;\\n uint48 validAfter;\\n uint48 validUntil;\\n}\\n\\n//extract sigFailed, validAfter, validUntil.\\n// also convert zero validUntil to type(uint48).max\\nfunction _parseValidationData(\\n uint validationData\\n) pure returns (ValidationData memory data) {\\n address aggregator = address(uint160(validationData));\\n uint48 validUntil = uint48(validationData >> 160);\\n if (validUntil == 0) {\\n validUntil = type(uint48).max;\\n }\\n uint48 validAfter = uint48(validationData >> (48 + 160));\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n// intersect account and paymaster ranges.\\nfunction _intersectTimeRange(\\n uint256 validationData,\\n uint256 paymasterValidationData\\n) pure returns (ValidationData memory) {\\n ValidationData memory accountValidationData = _parseValidationData(\\n validationData\\n );\\n ValidationData memory pmValidationData = _parseValidationData(\\n paymasterValidationData\\n );\\n address aggregator = accountValidationData.aggregator;\\n if (aggregator == address(0)) {\\n aggregator = pmValidationData.aggregator;\\n }\\n uint48 validAfter = accountValidationData.validAfter;\\n uint48 validUntil = accountValidationData.validUntil;\\n uint48 pmValidAfter = pmValidationData.validAfter;\\n uint48 pmValidUntil = pmValidationData.validUntil;\\n\\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp\\n * @param data - the ValidationData to pack\\n */\\nfunction _packValidationData(\\n ValidationData memory data\\n) pure returns (uint256) {\\n return\\n uint160(data.aggregator) |\\n (uint256(data.validUntil) << 160) |\\n (uint256(data.validAfter) << (160 + 48));\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp, when not using an aggregator\\n * @param sigFailed - true for signature failure, false for success\\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\\n * @param validAfter first timestamp this UserOperation is valid\\n */\\nfunction _packValidationData(\\n bool sigFailed,\\n uint48 validUntil,\\n uint48 validAfter\\n) pure returns (uint256) {\\n return\\n (sigFailed ? 1 : 0) |\\n (uint256(validUntil) << 160) |\\n (uint256(validAfter) << (160 + 48));\\n}\\n\\n/**\\n * keccak function over calldata.\\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\\n */\\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\\n assembly {\\n let mem := mload(0x40)\\n let len := data.length\\n calldatacopy(mem, data.offset, len)\\n ret := keccak256(mem, len)\\n }\\n}\\n\",\"keccak256\":\"0xa79f06cd158ecb8c0da95493a2f348933b8627a63e228b99738bff3aa107942d\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAggregator.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\n/**\\n * Aggregated Signatures validator.\\n */\\ninterface IAggregator {\\n /**\\n * validate aggregated signature.\\n * revert if the aggregated signature does not match the given list of operations.\\n */\\n function validateSignatures(\\n UserOperation[] calldata userOps,\\n bytes calldata signature\\n ) external view;\\n\\n /**\\n * validate signature of a single userOp\\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\\n * @param userOp the userOperation received from the user.\\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\\n * (usually empty, unless account and aggregator support some kind of \\\"multisig\\\"\\n */\\n function validateUserOpSignature(\\n UserOperation calldata userOp\\n ) external view returns (bytes memory sigForUserOp);\\n\\n /**\\n * aggregate multiple signatures into a single value.\\n * This method is called off-chain to calculate the signature to pass with handleOps()\\n * bundler MAY use optimized custom code perform this aggregation\\n * @param userOps array of UserOperations to collect the signatures from.\\n * @return aggregatedSignature the aggregated signature\\n */\\n function aggregateSignatures(\\n UserOperation[] calldata userOps\\n ) external view returns (bytes memory aggregatedSignature);\\n}\\n\",\"keccak256\":\"0xdfdcd80568f037716674619b31be630fcd8316262f05a815b41d1e81782c966a\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IEntryPoint.sol\":{\"content\":\"/**\\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\\n ** Only one instance required on each chain.\\n **/\\n// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-inline-assembly */\\n/* solhint-disable reason-string */\\n\\nimport \\\"./UserOperation.sol\\\";\\nimport \\\"./IStakeManager.sol\\\";\\nimport \\\"./IAggregator.sol\\\";\\nimport \\\"./INonceManager.sol\\\";\\n\\ninterface IEntryPoint is IStakeManager, INonceManager {\\n /***\\n * An event emitted after each successful request\\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\\n * @param sender - the account that generates this request.\\n * @param paymaster - if non-null, the paymaster that pays for this request.\\n * @param nonce - the nonce value from the request.\\n * @param success - true if the sender transaction succeeded, false if reverted.\\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\\n */\\n event UserOperationEvent(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address indexed paymaster,\\n uint256 nonce,\\n bool success,\\n uint256 actualGasCost,\\n uint256 actualGasUsed\\n );\\n\\n /**\\n * account \\\"sender\\\" was deployed.\\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\\n * @param sender the account that is deployed\\n * @param factory the factory used to deploy this account (in the initCode)\\n * @param paymaster the paymaster used by this UserOp\\n */\\n event AccountDeployed(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address factory,\\n address paymaster\\n );\\n\\n /**\\n * An event emitted if the UserOperation \\\"callData\\\" reverted with non-zero length\\n * @param userOpHash the request unique identifier.\\n * @param sender the sender of this request\\n * @param nonce the nonce used in the request\\n * @param revertReason - the return bytes from the (reverted) call to \\\"callData\\\".\\n */\\n event UserOperationRevertReason(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n uint256 nonce,\\n bytes revertReason\\n );\\n\\n /**\\n * an event emitted by handleOps(), before starting the execution loop.\\n * any event emitted before this event, is part of the validation.\\n */\\n event BeforeExecution();\\n\\n /**\\n * signature aggregator used by the following UserOperationEvents within this bundle.\\n */\\n event SignatureAggregatorChanged(address indexed aggregator);\\n\\n /**\\n * a custom revert error of handleOps, to identify the offending op.\\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\\n * @param reason - revert reason\\n * The string starts with a unique code \\\"AAmn\\\", where \\\"m\\\" is \\\"1\\\" for factory, \\\"2\\\" for account and \\\"3\\\" for paymaster issues,\\n * so a failure can be attributed to the correct entity.\\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\\n */\\n error FailedOp(uint256 opIndex, string reason);\\n\\n /**\\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\\n */\\n error SignatureValidationFailed(address aggregator);\\n\\n /**\\n * Successful result from simulateValidation.\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n */\\n error ValidationResult(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo\\n );\\n\\n /**\\n * Successful result from simulateValidation, if the account returns a signature aggregator\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\\n * bundler MUST use it to verify the signature, or reject the UserOperation\\n */\\n error ValidationResultWithAggregation(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo,\\n AggregatorStakeInfo aggregatorInfo\\n );\\n\\n /**\\n * return value of getSenderAddress\\n */\\n error SenderAddressResult(address sender);\\n\\n /**\\n * return value of simulateHandleOp\\n */\\n error ExecutionResult(\\n uint256 preOpGas,\\n uint256 paid,\\n uint48 validAfter,\\n uint48 validUntil,\\n bool targetSuccess,\\n bytes targetResult\\n );\\n\\n //UserOps handled, per aggregator\\n struct UserOpsPerAggregator {\\n UserOperation[] userOps;\\n // aggregator address\\n IAggregator aggregator;\\n // aggregated signature\\n bytes signature;\\n }\\n\\n /**\\n * Execute a batch of UserOperation.\\n * no signature aggregator is used.\\n * if any account requires an aggregator (that is, it returned an aggregator when\\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\\n * @param ops the operations to execute\\n * @param beneficiary the address to receive the fees\\n */\\n function handleOps(\\n UserOperation[] calldata ops,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * Execute a batch of UserOperation with Aggregators\\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\\n * @param beneficiary the address to receive the fees\\n */\\n function handleAggregatedOps(\\n UserOpsPerAggregator[] calldata opsPerAggregator,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * generate a request Id - unique identifier for this request.\\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\\n */\\n function getUserOpHash(\\n UserOperation calldata userOp\\n ) external view returns (bytes32);\\n\\n /**\\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\\n * @param userOp the user operation to validate.\\n */\\n function simulateValidation(UserOperation calldata userOp) external;\\n\\n /**\\n * gas and return values during simulation\\n * @param preOpGas the gas used for validation (including preValidationGas)\\n * @param prefund the required prefund for this operation\\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\\n */\\n struct ReturnInfo {\\n uint256 preOpGas;\\n uint256 prefund;\\n bool sigFailed;\\n uint48 validAfter;\\n uint48 validUntil;\\n bytes paymasterContext;\\n }\\n\\n /**\\n * returned aggregated signature info.\\n * the aggregator returned by the account, and its current stake.\\n */\\n struct AggregatorStakeInfo {\\n address aggregator;\\n StakeInfo stakeInfo;\\n }\\n\\n /**\\n * Get counterfactual sender address.\\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\\n * this method always revert, and returns the address in SenderAddressResult error\\n * @param initCode the constructor code to be passed into the UserOperation.\\n */\\n function getSenderAddress(bytes memory initCode) external;\\n\\n /**\\n * simulate full execution of a UserOperation (including both validation and target execution)\\n * this method will always revert with \\\"ExecutionResult\\\".\\n * it performs full validation of the UserOperation, but ignores signature error.\\n * an optional target address is called after the userop succeeds, and its value is returned\\n * (before the entire call is reverted)\\n * Note that in order to collect the the success/failure of the target call, it must be executed\\n * with trace enabled to track the emitted events.\\n * @param op the UserOperation to simulate\\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\\n * are set to the return from that call.\\n * @param targetCallData callData to pass to target address\\n */\\n function simulateHandleOp(\\n UserOperation calldata op,\\n address target,\\n bytes calldata targetCallData\\n ) external;\\n}\\n\",\"keccak256\":\"0x9ccb1b188eda8bbf5f6c2d01bd83c3d8b2b04fcf745283051d31fe96d1d8e40f\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/INonceManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\ninterface INonceManager {\\n /**\\n * Return the next nonce for this sender.\\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\\n * But UserOp with different keys can come with arbitrary order.\\n *\\n * @param sender the account address\\n * @param key the high 192 bit of the nonce\\n * @return nonce a full nonce to pass for next UserOp with this sender.\\n */\\n function getNonce(\\n address sender,\\n uint192 key\\n ) external view returns (uint256 nonce);\\n\\n /**\\n * Manually increment the nonce of the sender.\\n * This method is exposed just for completeness..\\n * Account does NOT need to call it, neither during validation, nor elsewhere,\\n * as the EntryPoint will update the nonce regardless.\\n * Possible use-case is call it with various keys to \\\"initialize\\\" their nonces to one, so that future\\n * UserOperations will not pay extra for the first transaction with a given key.\\n */\\n function incrementNonce(uint192 key) external;\\n}\\n\",\"keccak256\":\"0xce478ad0fa0d18a3b785ac854623029e7ab463d05873dfaa365abfa1bf100912\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IStakeManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8.12;\\n\\n/**\\n * manage deposits and stakes.\\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\\n * stake is value locked for at least \\\"unstakeDelay\\\" by the staked entity.\\n */\\ninterface IStakeManager {\\n event Deposited(address indexed account, uint256 totalDeposit);\\n\\n event Withdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /// Emitted when stake or unstake delay are modified\\n event StakeLocked(\\n address indexed account,\\n uint256 totalStaked,\\n uint256 unstakeDelaySec\\n );\\n\\n /// Emitted once a stake is scheduled for withdrawal\\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\\n\\n event StakeWithdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /**\\n * @param deposit the entity's deposit\\n * @param staked true if this entity is staked.\\n * @param stake actual amount of ether staked for this entity.\\n * @param unstakeDelaySec minimum delay to withdraw the stake.\\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\\n * and the rest fit into a 2nd cell.\\n * 112 bit allows for 10^15 eth\\n * 48 bit for full timestamp\\n * 32 bit allows 150 years for unstake delay\\n */\\n struct DepositInfo {\\n uint112 deposit;\\n bool staked;\\n uint112 stake;\\n uint32 unstakeDelaySec;\\n uint48 withdrawTime;\\n }\\n\\n //API struct used by getStakeInfo and simulateValidation\\n struct StakeInfo {\\n uint256 stake;\\n uint256 unstakeDelaySec;\\n }\\n\\n /// @return info - full deposit information of given account\\n function getDepositInfo(\\n address account\\n ) external view returns (DepositInfo memory info);\\n\\n /// @return the deposit (for gas payment) of the account\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * add to the deposit of the given account\\n */\\n function depositTo(address account) external payable;\\n\\n /**\\n * add to the account's stake - amount and delay\\n * any pending unstake is first cancelled.\\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\\n */\\n function addStake(uint32 _unstakeDelaySec) external payable;\\n\\n /**\\n * attempt to unlock the stake.\\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\\n */\\n function unlockStake() external;\\n\\n /**\\n * withdraw from the (unlocked) stake.\\n * must first call unlockStake and wait for the unstakeDelay to pass\\n * @param withdrawAddress the address to send withdrawn value.\\n */\\n function withdrawStake(address payable withdrawAddress) external;\\n\\n /**\\n * withdraw from the deposit.\\n * @param withdrawAddress the address to send withdrawn value.\\n * @param withdrawAmount the amount to withdraw.\\n */\\n function withdrawTo(\\n address payable withdrawAddress,\\n uint256 withdrawAmount\\n ) external;\\n}\\n\",\"keccak256\":\"0xadcea606c9b7aafe6645441f2154a60f271330b0eee5292a632aa71c1672d546\",\"license\":\"GPL-3.0-only\"},\"contracts/aa-4337/interfaces/UserOperation.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable no-inline-assembly */\\n\\nimport {calldataKeccak} from \\\"../core/Helpers.sol\\\";\\n\\n/**\\n * User Operation struct\\n * @param sender the sender account of this request.\\n * @param nonce unique value the sender uses to verify it is not a replay.\\n * @param initCode if set, the account contract will be created by this constructor/\\n * @param callData the method call to execute on this account.\\n * @param callGasLimit the gas limit passed to the callData method call.\\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\\n * @param maxFeePerGas same as EIP-1559 gas parameter.\\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\\n */\\nstruct UserOperation {\\n address sender;\\n uint256 nonce;\\n bytes initCode;\\n bytes callData;\\n uint256 callGasLimit;\\n uint256 verificationGasLimit;\\n uint256 preVerificationGas;\\n uint256 maxFeePerGas;\\n uint256 maxPriorityFeePerGas;\\n bytes paymasterAndData;\\n bytes signature;\\n}\\n\\n/**\\n * Utility functions helpful when working with UserOperation structs.\\n */\\nlibrary UserOperationLib {\\n function getSender(\\n UserOperation calldata userOp\\n ) internal pure returns (address) {\\n address data;\\n //read sender from userOp, which is first userOp member (saves 800 gas...)\\n assembly {\\n data := calldataload(userOp)\\n }\\n return address(uint160(data));\\n }\\n\\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\\n // pay above what he signed for.\\n function gasPrice(\\n UserOperation calldata userOp\\n ) internal view returns (uint256) {\\n unchecked {\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n if (maxFeePerGas == maxPriorityFeePerGas) {\\n //legacy mode (for networks that don't support basefee opcode)\\n return maxFeePerGas;\\n }\\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\\n }\\n }\\n\\n function pack(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes memory ret) {\\n address sender = getSender(userOp);\\n uint256 nonce = userOp.nonce;\\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\\n bytes32 hashCallData = calldataKeccak(userOp.callData);\\n uint256 callGasLimit = userOp.callGasLimit;\\n uint256 verificationGasLimit = userOp.verificationGasLimit;\\n uint256 preVerificationGas = userOp.preVerificationGas;\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\\n\\n return\\n abi.encode(\\n sender,\\n nonce,\\n hashInitCode,\\n hashCallData,\\n callGasLimit,\\n verificationGasLimit,\\n preVerificationGas,\\n maxFeePerGas,\\n maxPriorityFeePerGas,\\n hashPaymasterAndData\\n );\\n }\\n\\n function hash(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes32) {\\n return keccak256(pack(userOp));\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n}\\n\",\"keccak256\":\"0x2429f5cc546bdee08c7e63858d0dda8491eaa3ab5194df884dc948c1154d2834\",\"license\":\"GPL-3.0\"},\"contracts/facets/Modifiers.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {LibGuardian} from \\\"../libraries/LibGuardian.sol\\\";\\nimport {BarzStorage} from \\\"../libraries/LibAppStorage.sol\\\";\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\n\\n/**\\n * @title Modifiers\\n * @dev Responsible for providing modifiers/util functions to Facet contracts\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\nabstract contract Modifiers is BarzStorage {\\n uint8 constant INNER_STRUCT = 0;\\n\\n error CallerNotGuardian();\\n error CallerNotGuardianOrOwner();\\n error DuplicateApprover();\\n error ZeroApproverLength();\\n error UnregisteredFacetAndSelectors();\\n\\n /**\\n * @notice Modifier to only allow guardian to make a call, reverts if any other entity is the caller\\n */\\n modifier onlyGuardian() {\\n if (!LibGuardian.isGuardian(msg.sender)) revert CallerNotGuardian();\\n _;\\n }\\n\\n /**\\n * @notice Modifier to only allow guardian or owner to make a call, reverts if any other entity is the caller\\n */\\n modifier onlyGuardianOrOwner() {\\n if (!LibGuardian.isGuardian(msg.sender) && address(this) != msg.sender)\\n revert CallerNotGuardianOrOwner();\\n _;\\n }\\n\\n /**\\n * @notice Checks if the approver address is the array is unique with no duplicate\\n * @dev This method loops through the array and checks if a duplicate address exists, it reverts if duplicate address exists\\n * @param approvers Array of address\\n */\\n function _checkApprover(\\n address[] memory approvers\\n ) internal pure returns (bool) {\\n uint256 approverLength = approvers.length;\\n if (0 == approverLength) revert ZeroApproverLength();\\n for (uint256 i; i < approverLength - 1; ) {\\n for (uint256 j = i + 1; j < approverLength; ) {\\n if (approvers[i] == approvers[j]) {\\n revert DuplicateApprover(); // Found a duplicate\\n }\\n unchecked {\\n ++j;\\n }\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n return false; // No duplicates found\\n }\\n\\n /**\\n * @notice Checks if the facet getting added or replaced is registered to facet registry\\n * @dev This method loops through the cut and checks if the facet getting added/replaced is registered to facet registry\\n * @param _diamondCut Array of FacetCut, data for diamondCut defined in EIP-2535\\n */\\n function _checkFacetCutValidity(\\n IDiamondCut.FacetCut[] memory _diamondCut\\n ) internal view {\\n uint256 diamondCutLength = _diamondCut.length;\\n for (uint256 i; i < diamondCutLength; ) {\\n if (\\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Add ||\\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Replace\\n ) {\\n if (\\n !s.facetRegistry.areFacetFunctionSelectorsRegistered(\\n _diamondCut[i].facetAddress,\\n _diamondCut[i].functionSelectors\\n )\\n ) revert UnregisteredFacetAndSelectors();\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb42956323d199bdec243a5f9859439aae057fbfdd1d79e3a96afc857ecb3115f\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/DiamondCutFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {LibDiamond} from \\\"../../libraries/LibDiamond.sol\\\";\\nimport {LibGuardian} from \\\"../../libraries/LibGuardian.sol\\\";\\nimport {ISecurityManager} from \\\"../../infrastructure/interfaces/ISecurityManager.sol\\\";\\nimport {SignatureChecker} from \\\"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\\\";\\nimport {LibFacetStorage, DiamondCutApprovalConfig, ApprovalConfig} from \\\"../../libraries/LibFacetStorage.sol\\\";\\nimport {Modifiers} from \\\"../Modifiers.sol\\\";\\nimport {IDiamondCut} from \\\"./interfaces/IDiamondCut.sol\\\";\\n\\n/**\\n * @title DiamondCut Facet\\n * @dev Responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract DiamondCutFacet is Modifiers, IDiamondCut {\\n ISecurityManager public immutable securityManager;\\n\\n /**\\n * @notice This constructor sets the Security Manager address which is an immutable variable.\\n * Immutable variables do not impact the storage of diamond\\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\\n */\\n constructor(address _securityManager) {\\n securityManager = ISecurityManager(_securityManager);\\n }\\n\\n /**\\n * @notice Updates the flag for the interfaceId\\n * @param _interfaceId InterfaceID to update the mapping\\n * @param _flag Bool value to update the mapping of the given interface ID\\n */\\n function updateSupportsInterface(\\n bytes4 _interfaceId,\\n bool _flag\\n ) external override onlyWhenUnlocked {\\n LibDiamond.enforceIsSelf();\\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId] = _flag;\\n emit SupportsInterfaceUpdated(_interfaceId, _flag);\\n }\\n\\n /**\\n * @notice Add/replace/remove any number of functions and optionally execute\\n * a function with delegatecall when guardians don't exist\\n * @param _diamondCut Contains the facet addresses and function selectors\\n * @param _init The address of the contract or facet to execute _calldata. It's prohibited in Barz\\n */\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata\\n ) external override onlyWhenUnlocked {\\n LibDiamond.enforceIsSelf();\\n\\n _checkFacetCutValidity(_diamondCut);\\n // require approval from guardian if guardian exists\\n if (0 != LibGuardian.guardianCount())\\n revert DiamondCutFacet__InvalidRouteWithGuardian();\\n if (address(0) != _init) revert DiamondCutFacet__InvalidInitAddress();\\n\\n unchecked {\\n ++LibFacetStorage.diamondCutStorage().nonce;\\n }\\n LibDiamond.diamondCut(_diamondCut, address(0), \\\"\\\");\\n }\\n\\n /**\\n * @notice Add/replace/remove any number of functions and optionally execute\\n * a function with delegatecall when guardians exist\\n * @param _diamondCut Contains the facet addresses and function selectors\\n * @param _approvers Guardian or owner address that approves the diamond cut\\n * @param _signatures Signature of Guardians or owner that approves the diamond cut\\n */\\n function diamondCutWithGuardian(\\n FacetCut[] calldata _diamondCut,\\n address[] calldata _approvers,\\n bytes[] calldata _signatures\\n ) external override onlyWhenUnlocked {\\n if (_approvers.length != _signatures.length)\\n revert DiamondCutFacet__InvalidArrayLength();\\n _checkFacetCutValidity(_diamondCut);\\n if (0 == LibGuardian.guardianCount())\\n revert DiamondCutFacet__InvalidRouteWithGuardian();\\n\\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\\n\\n _checkApprover(_approvers);\\n _checkDuplicateOnChainApprover(cutHash, _approvers);\\n\\n bool onChainOwnerApproval = getOwnerCutApprovalWithTimeValidity(\\n cutHash\\n );\\n\\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\\n if (\\n _approvers.length +\\n getDiamondCutApprovalCountWithTimeValidity(cutHash) <\\n LibGuardian.majorityOfGuardians() + threshold\\n ) revert DiamondCutFacet__InsufficientApprovers();\\n\\n bool ownerApproved;\\n for (uint256 i; i < _approvers.length; ) {\\n if (\\n !LibGuardian.isGuardian(_approvers[i]) &&\\n _approvers[i] != address(this)\\n ) revert DiamondCutFacet__InvalidApprover();\\n if (_approvers[i] == address(this)) {\\n if (onChainOwnerApproval)\\n revert DiamondCutFacet__OwnerAlreadyApproved();\\n ownerApproved = true;\\n }\\n if (\\n !SignatureChecker.isValidSignatureNow(\\n _approvers[i],\\n cutHash,\\n _signatures[i]\\n )\\n ) revert DiamondCutFacet__InvalidApproverSignature();\\n unchecked {\\n ++i;\\n }\\n }\\n if (!ownerApproved && !onChainOwnerApproval)\\n revert DiamondCutFacet__LackOfOwnerApproval();\\n\\n unchecked {\\n ++LibFacetStorage.diamondCutStorage().nonce;\\n }\\n LibDiamond.diamondCut(_diamondCut, address(0), \\\"\\\");\\n }\\n\\n /**\\n * @notice Approves diamond cut. This can only be called directly from guardian or owner\\n * @param _diamondCut Contains the facet addresses and function selectors\\n */\\n function approveDiamondCut(\\n FacetCut[] calldata _diamondCut\\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\\n if (LibGuardian.guardianCount() == 0)\\n revert DiamondCutFacet__InvalidRouteWithoutGuardian();\\n DiamondCutApprovalConfig storage ds = LibFacetStorage\\n .diamondCutStorage()\\n .diamondCutApprovalConfigs[INNER_STRUCT];\\n _checkFacetCutValidity(_diamondCut);\\n\\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\\n uint64 approvalValidUntil = uint64(\\n block.timestamp + getApprovalValidationPeriod()\\n );\\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(\\n true,\\n approvalValidUntil\\n );\\n emit DiamondCutApproved(_diamondCut);\\n if (\\n (getDiamondCutApprovalCountWithTimeValidity(cutHash) >=\\n LibGuardian.majorityOfGuardians()) &&\\n getOwnerCutApprovalWithTimeValidity(cutHash)\\n ) {\\n unchecked {\\n ++LibFacetStorage.diamondCutStorage().nonce;\\n }\\n LibDiamond.diamondCut(_diamondCut, address(0), \\\"\\\");\\n }\\n }\\n\\n /**\\n * @notice Revokes the approval of diamond cut. This can only be called directly from guardian or owner\\n * @param _diamondCut Contains the facet addresses and function selectors\\n */\\n function revokeDiamondCutApproval(\\n FacetCut[] calldata _diamondCut\\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\\n DiamondCutApprovalConfig storage ds = LibFacetStorage\\n .diamondCutStorage()\\n .diamondCutApprovalConfigs[INNER_STRUCT];\\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\\n if (!ds.isDiamondCutApproved[cutHash][msg.sender].isApproved)\\n revert DiamondCutFacet__CannotRevokeUnapproved();\\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(false, 0);\\n emit DiamondCutApprovalRevoked(_diamondCut);\\n }\\n\\n /**\\n * @notice Gets the number of approvals of diamond cut from guardians\\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\\n */\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 _diamondCutHash\\n ) public view override returns (uint256 approvalCount) {\\n address[] memory guardians = LibGuardian.getGuardians();\\n uint256 guardiansLength = guardians.length;\\n for (uint256 i; i < guardiansLength; ) {\\n if (isCutApproved(_diamondCutHash, guardians[i])) {\\n unchecked {\\n ++approvalCount;\\n }\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n return approvalCount;\\n }\\n\\n /**\\n * @notice Returns if the owner has approved the diamond cut\\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\\n * @return isApprovedByOwner Bool value showing if the owner approved the cut\\n */\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 _diamondCutHash\\n ) public view override returns (bool isApprovedByOwner) {\\n isApprovedByOwner = isCutApproved(_diamondCutHash, address(this));\\n }\\n\\n /**\\n * @notice Returns if the given approver has approved the diamond cut\\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\\n * @param _approver Address of approver\\n * @return isApproved Bool value showing if the approver approved the cut\\n */\\n function isCutApproved(\\n bytes32 _diamondCutHash,\\n address _approver\\n ) public view override returns (bool isApproved) {\\n DiamondCutApprovalConfig storage ds = LibFacetStorage\\n .diamondCutStorage()\\n .diamondCutApprovalConfigs[INNER_STRUCT];\\n isApproved = (ds\\n .isDiamondCutApproved[_diamondCutHash][_approver].isApproved &&\\n block.timestamp <\\n ds.isDiamondCutApproved[_diamondCutHash][_approver].validUntil);\\n }\\n\\n /**\\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\\n * Approvers who approved on-chain should not be included in the off-chain approval\\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\\n * @param _approvers List of approver addresses\\n */\\n function _checkDuplicateOnChainApprover(\\n bytes32 _diamondCutHash,\\n address[] memory _approvers\\n ) public view {\\n address[] memory guardians = LibGuardian.getGuardians();\\n uint256 guardianLength = guardians.length;\\n uint256 approversLength = _approvers.length;\\n for (uint256 i; i < guardianLength; ) {\\n if (isCutApproved(_diamondCutHash, guardians[i])) {\\n for (uint256 j; j < approversLength; ) {\\n if (_approvers[j] == guardians[i])\\n revert DiamondCutFacet__DuplicateApproval();\\n unchecked {\\n ++j;\\n }\\n }\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * @notice Returns the diamond cut hash. This function ensures that this hash is safe from replay attack by including\\n * salt, address, chainId, and nonce, etc.\\n * @param _diamondCut Contains the facet addresses and function selectors\\n * @return cutHash Diamond Cut Hash\\n */\\n function getDiamondCutHash(\\n FacetCut[] calldata _diamondCut\\n ) public view override returns (bytes32 cutHash) {\\n cutHash = keccak256(\\n abi.encodePacked(\\n \\\"\\\\x19Ethereum Signed Message:\\\\n32\\\",\\n keccak256(\\n abi.encode(\\n keccak256(abi.encode(_diamondCut)),\\n address(this),\\n block.chainid,\\n LibFacetStorage.diamondCutStorage().nonce\\n )\\n )\\n )\\n );\\n }\\n\\n /**\\n * @notice Returns the approval validation Period\\n * @dev This method fetches the validation period from the security manager\\n * @return approvalValidationPeriod Approval validation period of Barz contract fetched from security manager\\n */\\n function getApprovalValidationPeriod()\\n internal\\n view\\n returns (uint256 approvalValidationPeriod)\\n {\\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\\n address(this)\\n );\\n if (approvalValidationPeriod <= 0)\\n revert DiamondCutFacet__InvalidApprovalValidationPeriod();\\n }\\n\\n /**\\n * @notice Returns the diamond cut nonce of this wallet\\n * @dev This method fetches the nonce from diamond cut storage\\n * @return cutNonce Nonce of diamond cut to protect from reply attacks\\n */\\n function getDiamondCutNonce()\\n public\\n view\\n override\\n returns (uint128 cutNonce)\\n {\\n cutNonce = LibFacetStorage.diamondCutStorage().nonce;\\n }\\n}\\n\",\"keccak256\":\"0xe91a7dd2daabf2e989c94089f4f1eb0da94276c3070559ac8988838e10dd1f5d\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/infrastructure/interfaces/IFacetRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Registry Interface\\n * @dev Interface for Facet Registry contract to keep track of facets & function selectors addable to user wallets\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IFacetRegistry {\\n struct FacetRegistryConfig {\\n bytes4[] selectors;\\n mapping(bytes4 => FacetInfo) info;\\n }\\n struct FacetInfo {\\n bool exists;\\n uint128 index;\\n }\\n\\n event FacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] facetSelectors\\n );\\n event FacetFunctionSelectorsRemoved(address facet, bytes4[] facetSelectors);\\n\\n error FacetRegistry__FacetSelectorAlreadyRegistered();\\n error FacetRegistry__UnregisteredFacetSelector();\\n\\n function registerFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function removeFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function areFacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external view returns (bool);\\n\\n function isFacetFunctionSelectorRegistered(\\n address facet,\\n bytes4 facetSelector\\n ) external view returns (bool);\\n\\n function getFacetFunctionSelectors(\\n address facet\\n ) external view returns (bytes4[] memory);\\n}\\n\",\"keccak256\":\"0x6e6dd2cab346ef7c31230740ec48d2925e4a9ab24c2f2fb268baaf408dcf02ef\",\"license\":\"Apache-2.0\"},\"contracts/infrastructure/interfaces/ISecurityManager.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Registry Interface\\n * @dev Infrastructure contract to manage security parameters of users\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\ninterface ISecurityManager {\\n error SecurityManager__OutOfBoundary();\\n error SecurityManager__CallerNotWallet();\\n error SecurityManager__AlreadyIntialized();\\n\\n function initializeAdditionSecurityPeriod(\\n uint128 defaultAdditionSecurityPeriod,\\n uint128 minAdditionSecurityPeriod,\\n uint128 maxAdditionSecurityPeriod\\n ) external;\\n\\n function initializeRemovalSecurityPeriod(\\n uint128 defaultRemovalSecurityPeriod,\\n uint128 minRemovalSecurityPeriod,\\n uint128 maxRemovalSecurityPeriod\\n ) external;\\n\\n function initializeApprovalValidationPeriod(\\n uint128 defaultApprovalValidationPeriod,\\n uint128 minApprovalValidationPeriod,\\n uint128 maxApprovalValidationPeriod\\n ) external;\\n\\n function initializeMigrationPeriod(\\n uint128 defaultMigrationPeriod,\\n uint128 minMigrationPeriod,\\n uint128 maxMigrationPeriod\\n ) external;\\n\\n function initializeLockPeriod(\\n uint128 defaultLockPeriod,\\n uint128 minLockPeriod,\\n uint128 maxLockPeriod\\n ) external;\\n\\n function initializeRecoveryPeriod(\\n uint128 defaultRecoveryPeriod,\\n uint128 minRecoveryPeriod,\\n uint128 maxRecoveryPeriod\\n ) external;\\n\\n function initializeSecurityWindow(\\n uint128 defaultSecurityWindow,\\n uint128 minSecurityWindow,\\n uint128 maxSecurityWindow\\n ) external;\\n\\n function setAdditionSecurityPeriod(\\n address wallet,\\n uint128 additionSecurityPeriod\\n ) external;\\n\\n function setRemovalSecurityPeriod(\\n address wallet,\\n uint128 removalSecurityPeriod\\n ) external;\\n\\n function setSecurityWindow(address wallet, uint128 securityWindow) external;\\n\\n function setRecoveryPeriod(address wallet, uint128 recoveryPeriod) external;\\n\\n function setLockPeriod(address wallet, uint128 lockPeriod) external;\\n\\n function setApprovalValidationPeriod(\\n address wallet,\\n uint128 approvalValidationPeriod\\n ) external;\\n\\n function setMigrationPeriod(\\n address wallet,\\n uint128 migrationPeriod\\n ) external;\\n\\n function additionSecurityPeriodOf(\\n address wallet\\n ) external view returns (uint128);\\n\\n function removalSecurityPeriodOf(\\n address wallet\\n ) external view returns (uint128);\\n\\n function securityWindowOf(address wallet) external view returns (uint128);\\n\\n function recoveryPeriodOf(address wallet) external view returns (uint128);\\n\\n function lockPeriodOf(address wallet) external view returns (uint128);\\n\\n function migrationPeriodOf(address wallet) external view returns (uint128);\\n\\n function approvalValidationPeriodOf(\\n address wallet\\n ) external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x9ac6566033ef81ba5744c8ed2b08f130b781b498ab9245bcca87567669549552\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibAppStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {SafeCast} from \\\"@openzeppelin/contracts/utils/math/SafeCast.sol\\\";\\nimport {IEntryPoint} from \\\"../aa-4337/interfaces/IEntryPoint.sol\\\";\\nimport {IFacetRegistry} from \\\"../infrastructure/interfaces/IFacetRegistry.sol\\\";\\n\\n/*\\n * @title App Storage\\n * @dev App storage for Barz contract to prevent storage collision\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Lock {\\n uint64 release;\\n bytes4 locker;\\n}\\n\\nstruct InitializersStorage {\\n // NOTE: initialized is a variable to make sure the initialization is only done once.\\n uint8 signerInitialized;\\n uint8 accountInitialized;\\n uint8 restrictionsInitialized;\\n}\\n\\nstruct AppStorage {\\n mapping(uint256 => InitializersStorage) initStorage;\\n uint8 signerMigration;\\n bytes4 validateOwnerSignatureSelector;\\n IEntryPoint entryPoint;\\n IFacetRegistry facetRegistry;\\n mapping(uint256 => Lock) locks;\\n}\\n\\nlibrary LibAppStorage {\\n error LibAppStorage__AccountAlreadyUninitialized();\\n error LibAppStorage__AccountMustBeUninitialized();\\n error LibAppStorage__SignerAlreadyUninitialized();\\n error LibAppStorage__SignerMustBeUninitialized();\\n\\n function appStorage() internal pure returns (AppStorage storage ds) {\\n assembly {\\n ds.slot := 0\\n }\\n }\\n\\n function setSignerUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerAlreadyUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 0;\\n }\\n\\n function getValidateOwnerSignatureSelector()\\n internal\\n view\\n returns (bytes4 selector)\\n {\\n selector = appStorage().validateOwnerSignatureSelector;\\n }\\n\\n function setValidateOwnerSignatureSelector(\\n bytes4 _validateOwnerSignatureSelector\\n ) internal {\\n appStorage()\\n .validateOwnerSignatureSelector = _validateOwnerSignatureSelector;\\n }\\n\\n function enforceSignerInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerMustBeUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 1;\\n }\\n\\n function enforceAccountInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].accountInitialized) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n s.initStorage[0].accountInitialized = 1;\\n }\\n\\n function initiateSignerMigration() internal {\\n appStorage().signerMigration = 1;\\n }\\n\\n function enforceSignerMigration() internal view {\\n if (1 != appStorage().signerMigration) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n }\\n\\n function finalizeSignerMigration() internal {\\n appStorage().signerMigration = 0;\\n }\\n\\n function setLock(uint256 _releaseAfter, bytes4 _locker) internal {\\n appStorage().locks[0] = Lock(SafeCast.toUint64(_releaseAfter), _locker);\\n }\\n\\n function enforceRestrictionsInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__SignerMustBeUninitialized();\\n s.initStorage[0].restrictionsInitialized = 1;\\n }\\n\\n function setRestrictionsUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__AccountAlreadyUninitialized();\\n s.initStorage[0].restrictionsInitialized = 0;\\n }\\n}\\n\\ncontract BarzStorage {\\n AppStorage internal s;\\n modifier onlyWhenUnlocked() {\\n require(\\n uint64(block.timestamp) >= s.locks[0].release,\\n \\\"Account Locked\\\"\\n );\\n _;\\n }\\n modifier onlyWhenLocked() {\\n require(\\n uint64(block.timestamp) < s.locks[0].release,\\n \\\"Account Unlocked\\\"\\n );\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x48524007862a6ce0e07f645950613ce6513ce073c37a109c75019683d42bae27\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\\n bytes4(keccak256(\\\"verifyRestrictions(address,address,uint256,bytes)\\\"));\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // Default Fallback Handler of the barz.\\n IDiamondLoupe defaultFallbackHandler;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function enforceIsSelf() internal view {\\n require(msg.sender == address(this), \\\"LibDiamond: Caller not self\\\");\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n\\n unchecked {\\n facetIndex++;\\n }\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n\\n function restrictionsFacet() internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(\\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2cabdc00de859c3a3170ce3bda5d0e5fd3933d47ce904fd1585f9818b02572f8\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibFacetStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Storage\\n * @dev Storage contract to store each facets variables with diamond storage\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Secp256k1VerificationStorage {\\n address signer;\\n}\\n\\nstruct Secp256r1VerificationStorage {\\n uint256[2] q;\\n}\\n\\nstruct GuardianStorage {\\n mapping(bytes32 => uint256) pending;\\n mapping(uint8 => StorageConfig) configs;\\n}\\n\\nstruct Info {\\n bool exists;\\n uint128 index;\\n}\\n\\nstruct StorageConfig {\\n address[] addresses;\\n mapping(address => Info) info;\\n}\\n\\nstruct RecoveryConfig {\\n bytes recoveryPublicKey;\\n uint64 executeAfter;\\n}\\n\\nstruct ApprovalConfig {\\n bool isApproved;\\n uint64 validUntil;\\n}\\n\\nstruct RecoveryApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isNewOwnerApproved;\\n}\\n\\nstruct RecoveryStorage {\\n mapping(uint8 => RecoveryConfig) recoveryConfigs;\\n mapping(uint8 => RecoveryApprovalConfig) recoveryApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct RestrictionsStorage {\\n address[] restrictions;\\n mapping(address => bool) exists;\\n}\\n\\nstruct SignatureMigrationConfig {\\n bytes migrationPublicKey;\\n address migrationVerificationFacet;\\n bytes4[] migrationSelectors;\\n uint64 migrateAfter;\\n}\\n\\nstruct SignatureMigrationApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isMigrationApproved;\\n}\\n\\nstruct SignatureMigrationStorage {\\n mapping(uint8 => SignatureMigrationConfig) migrationConfigs;\\n mapping(uint8 => SignatureMigrationApprovalConfig) migrationApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct DiamondCutApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isDiamondCutApproved;\\n}\\n\\nstruct DiamondCutStorage {\\n mapping(uint8 => DiamondCutApprovalConfig) diamondCutApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct LockStorage {\\n uint128 nonce;\\n}\\n\\nlibrary LibFacetStorage {\\n bytes32 constant K1_STORAGE_POSITION =\\n keccak256(\\n \\\"v0.trustwallet.diamond.storage.Secp256k1VerificationStorage\\\"\\n );\\n bytes32 constant R1_STORAGE_POSITION =\\n keccak256(\\n \\\"v0.trustwallet.diamond.storage.Secp256r1VerificationStorage\\\"\\n );\\n bytes32 constant GUARDIAN_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.GuardianStorage\\\");\\n bytes32 constant RECOVERY_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.RecoveryStorage\\\");\\n bytes32 constant RESTRICTION_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.RestrictionsStorage\\\");\\n bytes32 constant MIGRATION_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.SignatureMigrationStorage\\\");\\n bytes32 constant DIAMONDCUT_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.DiamondCutStorage\\\");\\n bytes32 constant LOCK_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.LockStorage\\\");\\n\\n function k1Storage()\\n internal\\n pure\\n returns (Secp256k1VerificationStorage storage ds)\\n {\\n bytes32 storagePosition = K1_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function r1Storage()\\n internal\\n pure\\n returns (Secp256r1VerificationStorage storage ds)\\n {\\n bytes32 storagePosition = R1_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function guardianStorage()\\n internal\\n pure\\n returns (GuardianStorage storage ds)\\n {\\n bytes32 storagePosition = GUARDIAN_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function recoveryStorage()\\n internal\\n pure\\n returns (RecoveryStorage storage ds)\\n {\\n bytes32 storagePosition = RECOVERY_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function restrictionsStorage()\\n internal\\n pure\\n returns (RestrictionsStorage storage ds)\\n {\\n bytes32 storagePosition = RESTRICTION_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function migrationStorage()\\n internal\\n pure\\n returns (SignatureMigrationStorage storage ds)\\n {\\n bytes32 storagePosition = MIGRATION_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function diamondCutStorage()\\n internal\\n pure\\n returns (DiamondCutStorage storage ds)\\n {\\n bytes32 storagePosition = DIAMONDCUT_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function lockStorage() internal pure returns (LockStorage storage ds) {\\n bytes32 storagePosition = LOCK_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n}\\n\",\"keccak256\":\"0x87c85decfd943deda9540733e464cb1a92eba735a301e89ce6f798016e359761\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibGuardian.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {LibFacetStorage, StorageConfig} from \\\"./LibFacetStorage.sol\\\";\\n\\n/**\\n * @title LibGuardian\\n * @dev Internal Library to provide utility feature for Guardians stored in Guardian Facet Storage\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\nlibrary LibGuardian {\\n function majorityOfGuardians()\\n internal\\n view\\n returns (uint256 guardianNumber)\\n {\\n uint256 guardianLength = guardianCount();\\n guardianNumber = (guardianLength == 0) ? 0 : guardianLength / 2 + 1;\\n }\\n\\n function isGuardian(address _guardian) internal view returns (bool) {\\n StorageConfig storage config = LibFacetStorage\\n .guardianStorage()\\n .configs[0];\\n return config.info[_guardian].exists;\\n }\\n\\n function guardianCount() internal view returns (uint256) {\\n StorageConfig storage config = LibFacetStorage\\n .guardianStorage()\\n .configs[0];\\n return config.addresses.length;\\n }\\n\\n function getGuardians() internal view returns (address[] memory) {\\n StorageConfig storage config = LibFacetStorage\\n .guardianStorage()\\n .configs[0];\\n address[] memory addresses = new address[](config.addresses.length);\\n uint256 addressesLen = config.addresses.length;\\n for (uint256 i; i < addressesLen; ) {\\n addresses[i] = config.addresses[i];\\n unchecked {\\n ++i;\\n }\\n }\\n return addresses;\\n }\\n}\\n\",\"keccak256\":\"0x6a620992d5535878fc03d1a27a6675f4c1509adfb3ddbbca1c52b546c25392dc\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x60a06040523480156200001157600080fd5b506040516200379b3803806200379b833981016040819052620000349162000046565b6001600160a01b031660805262000078565b6000602082840312156200005957600080fd5b81516001600160a01b03811681146200007157600080fd5b9392505050565b6080516137006200009b600039600081816101f10152611b2501526137006000f3fe608060405234801561001057600080fd5b50600436106100d45760003560e01c806379c0d58d11610081578063afb877bb1161005b578063afb877bb146101d9578063de675a6d146101ec578063e33ecf0a1461023857600080fd5b806379c0d58d14610192578063836d6bfb146101b35780638824a0bb146101c657600080fd5b806326fc3ef4116100b257806326fc3ef4146101145780632f4d98ea1461015c5780633c0985681461017f57600080fd5b806313c34f4b146100d95780631c776dd5146100ee5780631f931c1c14610101575b600080fd5b6100ec6100e7366004612a97565b61024b565b005b6100ec6100fc366004612ad9565b6104df565b6100ec61010f366004612b9c565b610a76565b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9bf546040516fffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b61016f61016a366004612c4a565b610c7b565b6040519015158152602001610153565b6100ec61018d366004612ca4565b610c8d565b6101a56101a0366004612c4a565b610df2565b604051908152602001610153565b61016f6101c1366004612cdb565b610e4c565b6100ec6101d4366004612dd2565b610eed565b6100ec6101e7366004612a97565b610fe1565b6102137f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610153565b6101a5610246366004612a97565b61130e565b3360009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff1615801561028a5750303314155b156102c1576040517f6238ee3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610369576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064015b60405180910390fd5b60008080527f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be6020527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d3906103be848461130e565b60008181526020848152604080832033845290915290205490915060ff16610412576040517fedc5708300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051808201825260008082526020808301828152858352868252848320338452909152908390209151825491517fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000009092169015157fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff161761010067ffffffffffffffff90921691909102179055517f3c3d8c1f0b0faff6fe0ace6b485d0595a0106dce9e303f956fd941ebdbe9a98e906104d19086908690612f54565b60405180910390a150505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610582576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b8281146105bb576040517fe854148500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6105cd6105c886886130aa565b611435565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b754600003610650576040517fa788861700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061065c878761130e565b905061069a8585808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506115b392505050565b506106d881868680806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250610eed92505050565b60006106e382610c7b565b90506000816106f35760016106f6565b60005b60ff169050806107046116d0565b61070e9190613201565b61071784610df2565b6107219088613201565b1015610759576040517f709fb08000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805b878110156109a0576107d989898381811061077a5761077a613214565b905060200201602081019061078f9190613243565b73ffffffffffffffffffffffffffffffffffffffff1660009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff1690565b1580156108225750308989838181106107f4576107f4613214565b90506020020160208101906108099190613243565b73ffffffffffffffffffffffffffffffffffffffff1614155b15610859576040517f7b2cbbb400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3089898381811061086c5761086c613214565b90506020020160208101906108819190613243565b73ffffffffffffffffffffffffffffffffffffffff16036108d95783156108d4576040517fee21708000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600191505b6109628989838181106108ee576108ee613214565b90506020020160208101906109039190613243565b8689898581811061091657610916613214565b90506020028101906109289190613265565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061174f92505050565b610998576040517fac3d341600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60010161075d565b50801580156109ad575082155b156109e4576040517f6d21730400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9bf80546fffffffffffffffffffffffffffffffff808216600101167fffffffffffffffffffffffffffffffff00000000000000000000000000000000909116179055610a6a610a538a8c6130aa565b6000604051806020016040528060008152506117ca565b50505050505050505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610b19576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b610b2161195f565b610b2e6105c885876130aa565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75415610baf576040517fa788861700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff831615610bfd576040517f871cb76100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be5b600190810180547fffffffffffffffffffffffffffffffff0000000000000000000000000000000081166fffffffffffffffffffffffffffffffff91821690930116919091179055610c74610a5385876130aa565b5050505050565b6000610c878230610e4c565b92915050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610d30576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b610d3861195f565b7fffffffff00000000000000000000000000000000000000000000000000000000821660008181527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4922602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001685151590811790915582519384529083015280517f4e6bd17989efa6d6a9607ccaac1bba27b29f99622bc830d99a3a9883b21a19c79281900390910190a15050565b600080610dfd6119ca565b805190915060005b81811015610e4457610e3085848381518110610e2357610e23613214565b6020026020010151610e4c565b15610e3c578360010193505b600101610e05565b505050919050565b60008281527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d36020818152604080842073ffffffffffffffffffffffffffffffffffffffff8616855290915282205460ff168015610ee5575060008481526020828152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152902054610100900467ffffffffffffffff1642105b949350505050565b6000610ef76119ca565b805183519192509060005b82811015610fd957610f2086858381518110610e2357610e23613214565b15610fd15760005b82811015610fcf57848281518110610f4257610f42613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16868281518110610f7257610f72613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603610fc7576040517f50f5729f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600101610f28565b505b600101610f02565b505050505050565b3360009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff161580156110205750303314155b15611057576040517f6238ee3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff9081164290911610156110fa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75460000361117d576040517f3a76e1f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080527f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be6020527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d36111d36105c883856130aa565b60006111df848461130e565b905060006111eb611af4565b6111f59042613201565b6040805180820182526001815267ffffffffffffffff838116602080840191825260008881528982528581203382529091528490209251835491517fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000009092169015157fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff16176101009190921602179055519091507f6248ff757895beed7d43d135bccf59a26b7fbdf0fe8233487c44e82c0f266ba3906112b89087908790612f54565b60405180910390a16112c86116d0565b6112d183610df2565b101580156112e357506112e382610c7b565b15610c74577f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be610c1f565b60008282604051602001611323929190612f54565b6040516020818303038152906040528051906020012030466113627f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be90565b6001015460408051602081019590955273ffffffffffffffffffffffffffffffffffffffff9093169284019290925260608301526fffffffffffffffffffffffffffffffff16608082015260a001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905280516020918201207f19457468657265756d205369676e6564204d6573736167653a0a33320000000091830191909152603c820152605c0160405160208183030381529060405280519060200120905092915050565b805160005b818110156115ae57600083828151811061145657611456613214565b602002602001015160200151600281111561147357611473612e8a565b14806114ad5750600183828151811061148e5761148e613214565b60200260200101516020015160028111156114ab576114ab612e8a565b145b156115a657600254835173ffffffffffffffffffffffffffffffffffffffff9091169063df871f72908590849081106114e8576114e8613214565b60200260200101516000015185848151811061150657611506613214565b6020026020010151604001516040518363ffffffff1660e01b815260040161152f92919061331c565b602060405180830381865afa15801561154c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611570919061334b565b6115a6576040517ff41a931c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60010161143a565b505050565b80516000908082036115f1576040517f3aee2eec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b6115ff600183613368565b8110156116c6576000611613826001613201565b90505b828110156116bd5784818151811061163057611630613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1685838151811061166057611660613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16036116b5576040517f8dd19e7d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600101611616565b506001016115f4565b5060009392505050565b600080611723600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75490565b905080156117465761173660028261337b565b611741906001613201565b611749565b60005b91505090565b600080600061175e8585611bf6565b9092509050600081600481111561177757611777612e8a565b1480156117af57508573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b806117c057506117c0868686611c3b565b9695505050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921547f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff8116908190600090600716156118395750600381901c60009081526001840160205260409020545b60005b87518110156118b6576118a983838a848151811061185c5761185c613214565b6020026020010151600001518b858151811061187a5761187a613214565b6020026020010151602001518c868151811061189857611898613214565b602002602001015160400151611d98565b909350915060010161183c565b508282146118ef576002840180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff84161790555b600782161561191157600382901c600090815260018501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb67387878760405161194493929190613424565b60405180910390a16119568686612829565b50505050505050565b3330146119c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4c69624469616d6f6e643a2043616c6c6572206e6f742073656c6600000000006044820152606401610360565b565b60008080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b780546060929067ffffffffffffffff811115611a3257611a32612d07565b604051908082528060200260200182016040528015611a5b578160200160208202803683370190505b50825490915060005b81811015611aeb57836000018181548110611a8157611a81613214565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16838281518110611abe57611abe613214565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101611a64565b50909392505050565b6040517f52430c8d0000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906352430c8d90602401602060405180830381865afa158015611b81573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ba59190613510565b6fffffffffffffffffffffffffffffffff16905060008111611bf3576040517fdac5ec8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b90565b6000808251604103611c2c5760208301516040840151606085015160001a611c2087828585612928565b94509450505050611c34565b506000905060025b9250929050565b60008060008573ffffffffffffffffffffffffffffffffffffffff16631626ba7e60e01b8686604051602401611c72929190613542565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909416939093179092529051611cfb919061355b565b600060405180830381855afa9150503d8060008114611d36576040519150601f19603f3d011682016040523d82523d6000602084013e611d3b565b606091505b5091509150818015611d4f57506020815110155b80156117c0575080517f1626ba7e0000000000000000000000000000000000000000000000000000000090611d8d9083016020908101908401613577565b149695505050505050565b600080807f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f90506000845111611e50576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610360565b6000856002811115611e6457611e64612e8a565b0361203457611e8b8660405180606001604052806024815260200161365760249139612a17565b60005b845181101561202e576000858281518110611eab57611eab613214565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c15611f7e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c72656164792065786973747300000000000000000000006064820152608401610360565b7fffffffff0000000000000000000000000000000000000000000000000000000080831660008181526020879052604090207fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608d901b168e17905560e060058e901b811692831c199c909c1690821c179a8190036120125760038c901c600090815260018601602052604081209b909b555b8b61201c81613590565b9c505060019093019250611e8e915050565b5061281d565b600185600281111561204857612048612e8a565b036123385761206f866040518060600160405280602881526020016136a360289139612a17565b60005b845181101561202e57600085828151811061208f5761208f613214565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c308103612164576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4c69624469616d6f6e644375743a2043616e2774207265706c61636520696d6d60448201527f757461626c652066756e6374696f6e00000000000000000000000000000000006064820152608401610360565b8973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361221f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e00000000000000006064820152608401610360565b73ffffffffffffffffffffffffffffffffffffffff81166122c2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e207468617420646f65736e277420657869737400000000000000006064820152608401610360565b507fffffffff0000000000000000000000000000000000000000000000000000000090911660009081526020849052604090206bffffffffffffffffffffffff919091167fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608a901b16179055600101612072565b600285600281111561234c5761234c612e8a565b036127955773ffffffffffffffffffffffffffffffffffffffff8616156123f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d7573742062652061646472657373283029000000000000000000006064820152608401610360565b600388901c6007891660005b86518110156127755760008a900361243d578261241d816135c8565b60008181526001870160205260409020549b5093506007925061244b9050565b81612447816135c8565b9250505b6000806000808a858151811061246357612463613214565b6020908102919091018101517fffffffff0000000000000000000000000000000000000000000000000000000081166000908152918a9052604090912054909150606081901c612535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608401610360565b30606082901c036125c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e0000000000000000000000000000000000006064820152608401610360565b600587901b8f901b94507fffffffff0000000000000000000000000000000000000000000000000000000080861690831614612666577fffffffff000000000000000000000000000000000000000000000000000000008516600090815260208a90526040902080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff83161790555b7fffffffff0000000000000000000000000000000000000000000000000000000091909116600090815260208990526040812055600381901c611fff16925060051b60e01690508582146126fb576000828152600188016020526040902080547fffffffff0000000000000000000000000000000000000000000000000000000080841c19909116908516831c17905561274c565b80837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c817fffffffff0000000000000000000000000000000000000000000000000000000060001b901c198e16179c505b8460000361276a57600086815260018801602052604081208190559c505b505050600101612401565b50806127828360086135fd565b61278c9190613201565b9950505061281d565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560448201527f74416374696f6e000000000000000000000000000000000000000000000000006064820152608401610360565b50959694955050505050565b73ffffffffffffffffffffffffffffffffffffffff8216612848575050565b61286a8260405180606001604052806028815260200161367b60289139612a17565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051612892919061355b565b600060405180830381855af49150503d80600081146128cd576040519150601f19603f3d011682016040523d82523d6000602084013e6128d2565b606091505b509150915081612922578051156128ec5780518082602001fd5b83836040517f192105d7000000000000000000000000000000000000000000000000000000008152600401610360929190613614565b50505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561295f5750600090506003612a0e565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156129b3573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116612a0757600060019250925050612a0e565b9150600090505b94509492505050565b813b8181612922576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103609190613643565b60008083601f840112612a6457600080fd5b50813567ffffffffffffffff811115612a7c57600080fd5b6020830191508360208260051b8501011115611c3457600080fd5b60008060208385031215612aaa57600080fd5b823567ffffffffffffffff811115612ac157600080fd5b612acd85828601612a52565b90969095509350505050565b60008060008060008060608789031215612af257600080fd5b863567ffffffffffffffff80821115612b0a57600080fd5b612b168a838b01612a52565b90985096506020890135915080821115612b2f57600080fd5b612b3b8a838b01612a52565b90965094506040890135915080821115612b5457600080fd5b50612b6189828a01612a52565b979a9699509497509295939492505050565b803573ffffffffffffffffffffffffffffffffffffffff81168114612b9757600080fd5b919050565b600080600080600060608688031215612bb457600080fd5b853567ffffffffffffffff80821115612bcc57600080fd5b612bd889838a01612a52565b9097509550859150612bec60208901612b73565b94506040880135915080821115612c0257600080fd5b818801915088601f830112612c1657600080fd5b813581811115612c2557600080fd5b896020828501011115612c3757600080fd5b9699959850939650602001949392505050565b600060208284031215612c5c57600080fd5b5035919050565b80357fffffffff0000000000000000000000000000000000000000000000000000000081168114612b9757600080fd5b8015158114612ca157600080fd5b50565b60008060408385031215612cb757600080fd5b612cc083612c63565b91506020830135612cd081612c93565b809150509250929050565b60008060408385031215612cee57600080fd5b82359150612cfe60208401612b73565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff81118282101715612d5957612d59612d07565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715612da657612da6612d07565b604052919050565b600067ffffffffffffffff821115612dc857612dc8612d07565b5060051b60200190565b60008060408385031215612de557600080fd5b8235915060208084013567ffffffffffffffff811115612e0457600080fd5b8401601f81018613612e1557600080fd5b8035612e28612e2382612dae565b612d5f565b81815260059190911b82018301908381019088831115612e4757600080fd5b928401925b82841015612e6c57612e5d84612b73565b82529284019290840190612e4c565b80955050505050509250929050565b803560038110612b9757600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60038110612ef0577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b8183526000602080850194508260005b85811015612f49577fffffffff00000000000000000000000000000000000000000000000000000000612f3683612c63565b1687529582019590820190600101612f04565b509495945050505050565b60208082528181018390526000906040808401600586811b8601830188865b8981101561309b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc089840301855281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa18c3603018112612fd457600080fd5b8b01606073ffffffffffffffffffffffffffffffffffffffff612ff683612b73565b168552613004898301612e7b565b6130108a870182612eb9565b50878201357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe183360301811261304557600080fd5b90910188810191903567ffffffffffffffff81111561306357600080fd5b80871b360383131561307457600080fd5b81898701526130868287018285612ef4565b978a0197955050509187019150600101612f73565b50909998505050505050505050565b60006130b8612e2384612dae565b83815260208082019190600586811b8601368111156130d657600080fd5b865b818110156131c557803567ffffffffffffffff808211156130f95760008081fd5b818a0191506060823603121561310f5760008081fd5b613117612d36565b61312083612b73565b815261312d878401612e7b565b87820152604080840135838111156131455760008081fd5b939093019236601f85011261315c57600092508283fd5b8335925061316c612e2384612dae565b83815292871b840188019288810190368511156131895760008081fd5b948901945b848610156131ae5761319f86612c63565b8252948901949089019061318e565b9183019190915250885250509483019483016130d8565b5092979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610c8757610c876131d2565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561325557600080fd5b61325e82612b73565b9392505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261329a57600080fd5b83018035915067ffffffffffffffff8211156132b557600080fd5b602001915036819003821315611c3457600080fd5b600081518084526020808501945080840160005b83811015612f495781517fffffffff0000000000000000000000000000000000000000000000000000000016875295820195908201906001016132de565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000610ee560408301846132ca565b60006020828403121561335d57600080fd5b815161325e81612c93565b81810381811115610c8757610c876131d2565b6000826133b1577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60005b838110156133d15781810151838201526020016133b9565b50506000910152565b600081518084526133f28160208601602086016133b6565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6000606080830181845280875180835260808601915060808160051b87010192506020808a0160005b838110156134d4577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80898703018552815173ffffffffffffffffffffffffffffffffffffffff8151168752838101516134a885890182612eb9565b506040908101519087018890526134c1878901826132ca565b965050938201939082019060010161344d565b505073ffffffffffffffffffffffffffffffffffffffff8916908701525050838103604085015261350581866133da565b979650505050505050565b60006020828403121561352257600080fd5b81516fffffffffffffffffffffffffffffffff8116811461325e57600080fd5b828152604060208201526000610ee560408301846133da565b6000825161356d8184602087016133b6565b9190910192915050565b60006020828403121561358957600080fd5b5051919050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036135c1576135c16131d2565b5060010190565b6000816135d7576135d76131d2565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b8082028115828204841417610c8757610c876131d2565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000610ee560408301846133da565b60208152600061325e60208301846133da56fe4c69624469616d6f6e644375743a2041646420666163657420686173206e6f20636f64654c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a205265706c61636520666163657420686173206e6f20636f6465a2646970667358221220c5a8c10b22f20cde3fe0431ff57305237423677a60888f5b349fc6751336ae1464736f6c63430008150033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100d45760003560e01c806379c0d58d11610081578063afb877bb1161005b578063afb877bb146101d9578063de675a6d146101ec578063e33ecf0a1461023857600080fd5b806379c0d58d14610192578063836d6bfb146101b35780638824a0bb146101c657600080fd5b806326fc3ef4116100b257806326fc3ef4146101145780632f4d98ea1461015c5780633c0985681461017f57600080fd5b806313c34f4b146100d95780631c776dd5146100ee5780631f931c1c14610101575b600080fd5b6100ec6100e7366004612a97565b61024b565b005b6100ec6100fc366004612ad9565b6104df565b6100ec61010f366004612b9c565b610a76565b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9bf546040516fffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b61016f61016a366004612c4a565b610c7b565b6040519015158152602001610153565b6100ec61018d366004612ca4565b610c8d565b6101a56101a0366004612c4a565b610df2565b604051908152602001610153565b61016f6101c1366004612cdb565b610e4c565b6100ec6101d4366004612dd2565b610eed565b6100ec6101e7366004612a97565b610fe1565b6102137f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610153565b6101a5610246366004612a97565b61130e565b3360009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff1615801561028a5750303314155b156102c1576040517f6238ee3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610369576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064015b60405180910390fd5b60008080527f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be6020527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d3906103be848461130e565b60008181526020848152604080832033845290915290205490915060ff16610412576040517fedc5708300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051808201825260008082526020808301828152858352868252848320338452909152908390209151825491517fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000009092169015157fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff161761010067ffffffffffffffff90921691909102179055517f3c3d8c1f0b0faff6fe0ace6b485d0595a0106dce9e303f956fd941ebdbe9a98e906104d19086908690612f54565b60405180910390a150505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610582576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b8281146105bb576040517fe854148500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6105cd6105c886886130aa565b611435565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b754600003610650576040517fa788861700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061065c878761130e565b905061069a8585808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506115b392505050565b506106d881868680806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250610eed92505050565b60006106e382610c7b565b90506000816106f35760016106f6565b60005b60ff169050806107046116d0565b61070e9190613201565b61071784610df2565b6107219088613201565b1015610759576040517f709fb08000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805b878110156109a0576107d989898381811061077a5761077a613214565b905060200201602081019061078f9190613243565b73ffffffffffffffffffffffffffffffffffffffff1660009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff1690565b1580156108225750308989838181106107f4576107f4613214565b90506020020160208101906108099190613243565b73ffffffffffffffffffffffffffffffffffffffff1614155b15610859576040517f7b2cbbb400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3089898381811061086c5761086c613214565b90506020020160208101906108819190613243565b73ffffffffffffffffffffffffffffffffffffffff16036108d95783156108d4576040517fee21708000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600191505b6109628989838181106108ee576108ee613214565b90506020020160208101906109039190613243565b8689898581811061091657610916613214565b90506020028101906109289190613265565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061174f92505050565b610998576040517fac3d341600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60010161075d565b50801580156109ad575082155b156109e4576040517f6d21730400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9bf80546fffffffffffffffffffffffffffffffff808216600101167fffffffffffffffffffffffffffffffff00000000000000000000000000000000909116179055610a6a610a538a8c6130aa565b6000604051806020016040528060008152506117ca565b50505050505050505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610b19576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b610b2161195f565b610b2e6105c885876130aa565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75415610baf576040517fa788861700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff831615610bfd576040517f871cb76100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be5b600190810180547fffffffffffffffffffffffffffffffff0000000000000000000000000000000081166fffffffffffffffffffffffffffffffff91821690930116919091179055610c74610a5385876130aa565b5050505050565b6000610c878230610e4c565b92915050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610d30576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b610d3861195f565b7fffffffff00000000000000000000000000000000000000000000000000000000821660008181527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4922602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001685151590811790915582519384529083015280517f4e6bd17989efa6d6a9607ccaac1bba27b29f99622bc830d99a3a9883b21a19c79281900390910190a15050565b600080610dfd6119ca565b805190915060005b81811015610e4457610e3085848381518110610e2357610e23613214565b6020026020010151610e4c565b15610e3c578360010193505b600101610e05565b505050919050565b60008281527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d36020818152604080842073ffffffffffffffffffffffffffffffffffffffff8616855290915282205460ff168015610ee5575060008481526020828152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152902054610100900467ffffffffffffffff1642105b949350505050565b6000610ef76119ca565b805183519192509060005b82811015610fd957610f2086858381518110610e2357610e23613214565b15610fd15760005b82811015610fcf57848281518110610f4257610f42613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16868281518110610f7257610f72613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603610fc7576040517f50f5729f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600101610f28565b505b600101610f02565b505050505050565b3360009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff161580156110205750303314155b15611057576040517f6238ee3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff9081164290911610156110fa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75460000361117d576040517f3a76e1f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080527f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be6020527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d36111d36105c883856130aa565b60006111df848461130e565b905060006111eb611af4565b6111f59042613201565b6040805180820182526001815267ffffffffffffffff838116602080840191825260008881528982528581203382529091528490209251835491517fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000009092169015157fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff16176101009190921602179055519091507f6248ff757895beed7d43d135bccf59a26b7fbdf0fe8233487c44e82c0f266ba3906112b89087908790612f54565b60405180910390a16112c86116d0565b6112d183610df2565b101580156112e357506112e382610c7b565b15610c74577f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be610c1f565b60008282604051602001611323929190612f54565b6040516020818303038152906040528051906020012030466113627f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be90565b6001015460408051602081019590955273ffffffffffffffffffffffffffffffffffffffff9093169284019290925260608301526fffffffffffffffffffffffffffffffff16608082015260a001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905280516020918201207f19457468657265756d205369676e6564204d6573736167653a0a33320000000091830191909152603c820152605c0160405160208183030381529060405280519060200120905092915050565b805160005b818110156115ae57600083828151811061145657611456613214565b602002602001015160200151600281111561147357611473612e8a565b14806114ad5750600183828151811061148e5761148e613214565b60200260200101516020015160028111156114ab576114ab612e8a565b145b156115a657600254835173ffffffffffffffffffffffffffffffffffffffff9091169063df871f72908590849081106114e8576114e8613214565b60200260200101516000015185848151811061150657611506613214565b6020026020010151604001516040518363ffffffff1660e01b815260040161152f92919061331c565b602060405180830381865afa15801561154c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611570919061334b565b6115a6576040517ff41a931c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60010161143a565b505050565b80516000908082036115f1576040517f3aee2eec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b6115ff600183613368565b8110156116c6576000611613826001613201565b90505b828110156116bd5784818151811061163057611630613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1685838151811061166057611660613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16036116b5576040517f8dd19e7d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600101611616565b506001016115f4565b5060009392505050565b600080611723600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75490565b905080156117465761173660028261337b565b611741906001613201565b611749565b60005b91505090565b600080600061175e8585611bf6565b9092509050600081600481111561177757611777612e8a565b1480156117af57508573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b806117c057506117c0868686611c3b565b9695505050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921547f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff8116908190600090600716156118395750600381901c60009081526001840160205260409020545b60005b87518110156118b6576118a983838a848151811061185c5761185c613214565b6020026020010151600001518b858151811061187a5761187a613214565b6020026020010151602001518c868151811061189857611898613214565b602002602001015160400151611d98565b909350915060010161183c565b508282146118ef576002840180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff84161790555b600782161561191157600382901c600090815260018501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb67387878760405161194493929190613424565b60405180910390a16119568686612829565b50505050505050565b3330146119c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4c69624469616d6f6e643a2043616c6c6572206e6f742073656c6600000000006044820152606401610360565b565b60008080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b780546060929067ffffffffffffffff811115611a3257611a32612d07565b604051908082528060200260200182016040528015611a5b578160200160208202803683370190505b50825490915060005b81811015611aeb57836000018181548110611a8157611a81613214565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16838281518110611abe57611abe613214565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101611a64565b50909392505050565b6040517f52430c8d0000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906352430c8d90602401602060405180830381865afa158015611b81573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ba59190613510565b6fffffffffffffffffffffffffffffffff16905060008111611bf3576040517fdac5ec8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b90565b6000808251604103611c2c5760208301516040840151606085015160001a611c2087828585612928565b94509450505050611c34565b506000905060025b9250929050565b60008060008573ffffffffffffffffffffffffffffffffffffffff16631626ba7e60e01b8686604051602401611c72929190613542565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909416939093179092529051611cfb919061355b565b600060405180830381855afa9150503d8060008114611d36576040519150601f19603f3d011682016040523d82523d6000602084013e611d3b565b606091505b5091509150818015611d4f57506020815110155b80156117c0575080517f1626ba7e0000000000000000000000000000000000000000000000000000000090611d8d9083016020908101908401613577565b149695505050505050565b600080807f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f90506000845111611e50576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610360565b6000856002811115611e6457611e64612e8a565b0361203457611e8b8660405180606001604052806024815260200161365760249139612a17565b60005b845181101561202e576000858281518110611eab57611eab613214565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c15611f7e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c72656164792065786973747300000000000000000000006064820152608401610360565b7fffffffff0000000000000000000000000000000000000000000000000000000080831660008181526020879052604090207fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608d901b168e17905560e060058e901b811692831c199c909c1690821c179a8190036120125760038c901c600090815260018601602052604081209b909b555b8b61201c81613590565b9c505060019093019250611e8e915050565b5061281d565b600185600281111561204857612048612e8a565b036123385761206f866040518060600160405280602881526020016136a360289139612a17565b60005b845181101561202e57600085828151811061208f5761208f613214565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c308103612164576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4c69624469616d6f6e644375743a2043616e2774207265706c61636520696d6d60448201527f757461626c652066756e6374696f6e00000000000000000000000000000000006064820152608401610360565b8973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361221f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e00000000000000006064820152608401610360565b73ffffffffffffffffffffffffffffffffffffffff81166122c2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e207468617420646f65736e277420657869737400000000000000006064820152608401610360565b507fffffffff0000000000000000000000000000000000000000000000000000000090911660009081526020849052604090206bffffffffffffffffffffffff919091167fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608a901b16179055600101612072565b600285600281111561234c5761234c612e8a565b036127955773ffffffffffffffffffffffffffffffffffffffff8616156123f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d7573742062652061646472657373283029000000000000000000006064820152608401610360565b600388901c6007891660005b86518110156127755760008a900361243d578261241d816135c8565b60008181526001870160205260409020549b5093506007925061244b9050565b81612447816135c8565b9250505b6000806000808a858151811061246357612463613214565b6020908102919091018101517fffffffff0000000000000000000000000000000000000000000000000000000081166000908152918a9052604090912054909150606081901c612535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608401610360565b30606082901c036125c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e0000000000000000000000000000000000006064820152608401610360565b600587901b8f901b94507fffffffff0000000000000000000000000000000000000000000000000000000080861690831614612666577fffffffff000000000000000000000000000000000000000000000000000000008516600090815260208a90526040902080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff83161790555b7fffffffff0000000000000000000000000000000000000000000000000000000091909116600090815260208990526040812055600381901c611fff16925060051b60e01690508582146126fb576000828152600188016020526040902080547fffffffff0000000000000000000000000000000000000000000000000000000080841c19909116908516831c17905561274c565b80837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c817fffffffff0000000000000000000000000000000000000000000000000000000060001b901c198e16179c505b8460000361276a57600086815260018801602052604081208190559c505b505050600101612401565b50806127828360086135fd565b61278c9190613201565b9950505061281d565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560448201527f74416374696f6e000000000000000000000000000000000000000000000000006064820152608401610360565b50959694955050505050565b73ffffffffffffffffffffffffffffffffffffffff8216612848575050565b61286a8260405180606001604052806028815260200161367b60289139612a17565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051612892919061355b565b600060405180830381855af49150503d80600081146128cd576040519150601f19603f3d011682016040523d82523d6000602084013e6128d2565b606091505b509150915081612922578051156128ec5780518082602001fd5b83836040517f192105d7000000000000000000000000000000000000000000000000000000008152600401610360929190613614565b50505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561295f5750600090506003612a0e565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156129b3573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116612a0757600060019250925050612a0e565b9150600090505b94509492505050565b813b8181612922576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103609190613643565b60008083601f840112612a6457600080fd5b50813567ffffffffffffffff811115612a7c57600080fd5b6020830191508360208260051b8501011115611c3457600080fd5b60008060208385031215612aaa57600080fd5b823567ffffffffffffffff811115612ac157600080fd5b612acd85828601612a52565b90969095509350505050565b60008060008060008060608789031215612af257600080fd5b863567ffffffffffffffff80821115612b0a57600080fd5b612b168a838b01612a52565b90985096506020890135915080821115612b2f57600080fd5b612b3b8a838b01612a52565b90965094506040890135915080821115612b5457600080fd5b50612b6189828a01612a52565b979a9699509497509295939492505050565b803573ffffffffffffffffffffffffffffffffffffffff81168114612b9757600080fd5b919050565b600080600080600060608688031215612bb457600080fd5b853567ffffffffffffffff80821115612bcc57600080fd5b612bd889838a01612a52565b9097509550859150612bec60208901612b73565b94506040880135915080821115612c0257600080fd5b818801915088601f830112612c1657600080fd5b813581811115612c2557600080fd5b896020828501011115612c3757600080fd5b9699959850939650602001949392505050565b600060208284031215612c5c57600080fd5b5035919050565b80357fffffffff0000000000000000000000000000000000000000000000000000000081168114612b9757600080fd5b8015158114612ca157600080fd5b50565b60008060408385031215612cb757600080fd5b612cc083612c63565b91506020830135612cd081612c93565b809150509250929050565b60008060408385031215612cee57600080fd5b82359150612cfe60208401612b73565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff81118282101715612d5957612d59612d07565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715612da657612da6612d07565b604052919050565b600067ffffffffffffffff821115612dc857612dc8612d07565b5060051b60200190565b60008060408385031215612de557600080fd5b8235915060208084013567ffffffffffffffff811115612e0457600080fd5b8401601f81018613612e1557600080fd5b8035612e28612e2382612dae565b612d5f565b81815260059190911b82018301908381019088831115612e4757600080fd5b928401925b82841015612e6c57612e5d84612b73565b82529284019290840190612e4c565b80955050505050509250929050565b803560038110612b9757600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60038110612ef0577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b8183526000602080850194508260005b85811015612f49577fffffffff00000000000000000000000000000000000000000000000000000000612f3683612c63565b1687529582019590820190600101612f04565b509495945050505050565b60208082528181018390526000906040808401600586811b8601830188865b8981101561309b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc089840301855281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa18c3603018112612fd457600080fd5b8b01606073ffffffffffffffffffffffffffffffffffffffff612ff683612b73565b168552613004898301612e7b565b6130108a870182612eb9565b50878201357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe183360301811261304557600080fd5b90910188810191903567ffffffffffffffff81111561306357600080fd5b80871b360383131561307457600080fd5b81898701526130868287018285612ef4565b978a0197955050509187019150600101612f73565b50909998505050505050505050565b60006130b8612e2384612dae565b83815260208082019190600586811b8601368111156130d657600080fd5b865b818110156131c557803567ffffffffffffffff808211156130f95760008081fd5b818a0191506060823603121561310f5760008081fd5b613117612d36565b61312083612b73565b815261312d878401612e7b565b87820152604080840135838111156131455760008081fd5b939093019236601f85011261315c57600092508283fd5b8335925061316c612e2384612dae565b83815292871b840188019288810190368511156131895760008081fd5b948901945b848610156131ae5761319f86612c63565b8252948901949089019061318e565b9183019190915250885250509483019483016130d8565b5092979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610c8757610c876131d2565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561325557600080fd5b61325e82612b73565b9392505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261329a57600080fd5b83018035915067ffffffffffffffff8211156132b557600080fd5b602001915036819003821315611c3457600080fd5b600081518084526020808501945080840160005b83811015612f495781517fffffffff0000000000000000000000000000000000000000000000000000000016875295820195908201906001016132de565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000610ee560408301846132ca565b60006020828403121561335d57600080fd5b815161325e81612c93565b81810381811115610c8757610c876131d2565b6000826133b1577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60005b838110156133d15781810151838201526020016133b9565b50506000910152565b600081518084526133f28160208601602086016133b6565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6000606080830181845280875180835260808601915060808160051b87010192506020808a0160005b838110156134d4577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80898703018552815173ffffffffffffffffffffffffffffffffffffffff8151168752838101516134a885890182612eb9565b506040908101519087018890526134c1878901826132ca565b965050938201939082019060010161344d565b505073ffffffffffffffffffffffffffffffffffffffff8916908701525050838103604085015261350581866133da565b979650505050505050565b60006020828403121561352257600080fd5b81516fffffffffffffffffffffffffffffffff8116811461325e57600080fd5b828152604060208201526000610ee560408301846133da565b6000825161356d8184602087016133b6565b9190910192915050565b60006020828403121561358957600080fd5b5051919050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036135c1576135c16131d2565b5060010190565b6000816135d7576135d76131d2565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b8082028115828204841417610c8757610c876131d2565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000610ee560408301846133da565b60208152600061325e60208301846133da56fe4c69624469616d6f6e644375743a2041646420666163657420686173206e6f20636f64654c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a205265706c61636520666163657420686173206e6f20636f6465a2646970667358221220c5a8c10b22f20cde3fe0431ff57305237423677a60888f5b349fc6751336ae1464736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "Responsible for adding/removing/replace facets in Barz", + "kind": "dev", + "methods": { + "_checkDuplicateOnChainApprover(bytes32,address[])": { + "params": { + "_approvers": "List of approver addresses", + "_diamondCutHash": "Hash of diamondCut information including the facet addresses and function selectors" + } + }, + "approveDiamondCut((address,uint8,bytes4[])[])": { + "params": { + "_diamondCut": "Contains the facet addresses and function selectors" + } + }, + "constructor": { + "params": { + "_securityManager": "Security Manager contract that holds the security related variables for all wallets" + } + }, + "diamondCut((address,uint8,bytes4[])[],address,bytes)": { + "params": { + "_diamondCut": "Contains the facet addresses and function selectors", + "_init": "The address of the contract or facet to execute _calldata. It's prohibited in Barz" + } + }, + "diamondCutWithGuardian((address,uint8,bytes4[])[],address[],bytes[])": { + "params": { + "_approvers": "Guardian or owner address that approves the diamond cut", + "_diamondCut": "Contains the facet addresses and function selectors", + "_signatures": "Signature of Guardians or owner that approves the diamond cut" + } + }, + "getDiamondCutApprovalCountWithTimeValidity(bytes32)": { + "params": { + "_diamondCutHash": "Hash of diamondCut information including the facet addresses and function selectors" + } + }, + "getDiamondCutHash((address,uint8,bytes4[])[])": { + "params": { + "_diamondCut": "Contains the facet addresses and function selectors" + }, + "returns": { + "cutHash": "Diamond Cut Hash" + } + }, + "getDiamondCutNonce()": { + "details": "This method fetches the nonce from diamond cut storage", + "returns": { + "cutNonce": "Nonce of diamond cut to protect from reply attacks" + } + }, + "getOwnerCutApprovalWithTimeValidity(bytes32)": { + "params": { + "_diamondCutHash": "Hash of diamondCut information including the facet addresses and function selectors" + }, + "returns": { + "isApprovedByOwner": "Bool value showing if the owner approved the cut" + } + }, + "isCutApproved(bytes32,address)": { + "params": { + "_approver": "Address of approver", + "_diamondCutHash": "Hash of diamondCut information including the facet addresses and function selectors" + }, + "returns": { + "isApproved": "Bool value showing if the approver approved the cut" + } + }, + "revokeDiamondCutApproval((address,uint8,bytes4[])[])": { + "params": { + "_diamondCut": "Contains the facet addresses and function selectors" + } + }, + "updateSupportsInterface(bytes4,bool)": { + "params": { + "_flag": "Bool value to update the mapping of the given interface ID", + "_interfaceId": "InterfaceID to update the mapping" + } + } + }, + "title": "DiamondCut Facet", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "_checkDuplicateOnChainApprover(bytes32,address[])": { + "notice": "Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval Approvers who approved on-chain should not be included in the off-chain approval" + }, + "approveDiamondCut((address,uint8,bytes4[])[])": { + "notice": "Approves diamond cut. This can only be called directly from guardian or owner" + }, + "constructor": { + "notice": "This constructor sets the Security Manager address which is an immutable variable. Immutable variables do not impact the storage of diamond" + }, + "diamondCut((address,uint8,bytes4[])[],address,bytes)": { + "notice": "Add/replace/remove any number of functions and optionally execute a function with delegatecall when guardians don't exist" + }, + "diamondCutWithGuardian((address,uint8,bytes4[])[],address[],bytes[])": { + "notice": "Add/replace/remove any number of functions and optionally execute a function with delegatecall when guardians exist" + }, + "getDiamondCutApprovalCountWithTimeValidity(bytes32)": { + "notice": "Gets the number of approvals of diamond cut from guardians" + }, + "getDiamondCutHash((address,uint8,bytes4[])[])": { + "notice": "Returns the diamond cut hash. This function ensures that this hash is safe from replay attack by including salt, address, chainId, and nonce, etc." + }, + "getDiamondCutNonce()": { + "notice": "Returns the diamond cut nonce of this wallet" + }, + "getOwnerCutApprovalWithTimeValidity(bytes32)": { + "notice": "Returns if the owner has approved the diamond cut" + }, + "isCutApproved(bytes32,address)": { + "notice": "Returns if the given approver has approved the diamond cut" + }, + "revokeDiamondCutApproval((address,uint8,bytes4[])[])": { + "notice": "Revokes the approval of diamond cut. This can only be called directly from guardian or owner" + }, + "updateSupportsInterface(bytes4,bool)": { + "notice": "Updates the flag for the interfaceId" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 27823, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "s", + "offset": 0, + "slot": "0", + "type": "t_struct(AppStorage)27570_storage" + } + ], + "types": { + "t_bytes4": { + "encoding": "inplace", + "label": "bytes4", + "numberOfBytes": "4" + }, + "t_contract(IEntryPoint)12286": { + "encoding": "inplace", + "label": "contract IEntryPoint", + "numberOfBytes": "20" + }, + "t_contract(IFacetRegistry)26105": { + "encoding": "inplace", + "label": "contract IFacetRegistry", + "numberOfBytes": "20" + }, + "t_mapping(t_uint256,t_struct(InitializersStorage)27549_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => struct InitializersStorage)", + "numberOfBytes": "32", + "value": "t_struct(InitializersStorage)27549_storage" + }, + "t_mapping(t_uint256,t_struct(Lock)27542_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => struct Lock)", + "numberOfBytes": "32", + "value": "t_struct(Lock)27542_storage" + }, + "t_struct(AppStorage)27570_storage": { + "encoding": "inplace", + "label": "struct AppStorage", + "members": [ + { + "astId": 27554, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "initStorage", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_uint256,t_struct(InitializersStorage)27549_storage)" + }, + { + "astId": 27556, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "signerMigration", + "offset": 0, + "slot": "1", + "type": "t_uint8" + }, + { + "astId": 27558, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "validateOwnerSignatureSelector", + "offset": 1, + "slot": "1", + "type": "t_bytes4" + }, + { + "astId": 27561, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "entryPoint", + "offset": 5, + "slot": "1", + "type": "t_contract(IEntryPoint)12286" + }, + { + "astId": 27564, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "facetRegistry", + "offset": 0, + "slot": "2", + "type": "t_contract(IFacetRegistry)26105" + }, + { + "astId": 27569, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "locks", + "offset": 0, + "slot": "3", + "type": "t_mapping(t_uint256,t_struct(Lock)27542_storage)" + } + ], + "numberOfBytes": "128" + }, + "t_struct(InitializersStorage)27549_storage": { + "encoding": "inplace", + "label": "struct InitializersStorage", + "members": [ + { + "astId": 27544, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "signerInitialized", + "offset": 0, + "slot": "0", + "type": "t_uint8" + }, + { + "astId": 27546, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "accountInitialized", + "offset": 1, + "slot": "0", + "type": "t_uint8" + }, + { + "astId": 27548, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "restrictionsInitialized", + "offset": 2, + "slot": "0", + "type": "t_uint8" + } + ], + "numberOfBytes": "32" + }, + "t_struct(Lock)27542_storage": { + "encoding": "inplace", + "label": "struct Lock", + "members": [ + { + "astId": 27539, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "release", + "offset": 0, + "slot": "0", + "type": "t_uint64" + }, + { + "astId": 27541, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "locker", + "offset": 8, + "slot": "0", + "type": "t_bytes4" + } + ], + "numberOfBytes": "32" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint64": { + "encoding": "inplace", + "label": "uint64", + "numberOfBytes": "8" + }, + "t_uint8": { + "encoding": "inplace", + "label": "uint8", + "numberOfBytes": "1" + } + } + } +} \ No newline at end of file diff --git a/deployments/optimism/DiamondLoupeFacet.json b/deployments/optimism/DiamondLoupeFacet.json new file mode 100644 index 0000000..b85322b --- /dev/null +++ b/deployments/optimism/DiamondLoupeFacet.json @@ -0,0 +1,306 @@ +{ + "address": "0xCe36b85d12D81cd619C745c7717f3396E184Ac7C", + "abi": [ + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_functionSelector", + "type": "bytes4" + } + ], + "name": "facetAddress", + "outputs": [ + { + "internalType": "address", + "name": "facetAddress_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_functionSelector", + "type": "bytes4" + } + ], + "name": "facetAddressFromStorage", + "outputs": [ + { + "internalType": "address", + "name": "facetAddress_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetAddresses", + "outputs": [ + { + "internalType": "address[]", + "name": "facetAddresses_", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetAddressesFromStorage", + "outputs": [ + { + "internalType": "address[]", + "name": "facetAddresses_", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_facet", + "type": "address" + } + ], + "name": "facetFunctionSelectors", + "outputs": [ + { + "internalType": "bytes4[]", + "name": "facetFunctionSelectors_", + "type": "bytes4[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_facet", + "type": "address" + } + ], + "name": "facetFunctionSelectorsFromStorage", + "outputs": [ + { + "internalType": "bytes4[]", + "name": "facetFunctionSelectors_", + "type": "bytes4[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facets", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondLoupe.Facet[]", + "name": "facets_", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetsFromStorage", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondLoupe.Facet[]", + "name": "facets_", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "isSupported", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0xd00ac0a35301c23ceafa964119b37e36ac5c6f404a4c45b6524dc50ead1d30a1", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 9, + "gasUsed": "2036373", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x7c5478b4870780388358e4236b1e567b5c466226db6ebba9bd0153d501b462b0", + "transactionHash": "0xd00ac0a35301c23ceafa964119b37e36ac5c6f404a4c45b6524dc50ead1d30a1", + "logs": [], + "blockNumber": 112443274, + "cumulativeGasUsed": "2893728", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 3, + "solcInputHash": "4356503edd8ae34e73cb6dd1c8e2fc8a", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_functionSelector\",\"type\":\"bytes4\"}],\"name\":\"facetAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"facetAddress_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_functionSelector\",\"type\":\"bytes4\"}],\"name\":\"facetAddressFromStorage\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"facetAddress_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetAddresses\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"facetAddresses_\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetAddressesFromStorage\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"facetAddresses_\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_facet\",\"type\":\"address\"}],\"name\":\"facetFunctionSelectors\",\"outputs\":[{\"internalType\":\"bytes4[]\",\"name\":\"facetFunctionSelectors_\",\"type\":\"bytes4[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_facet\",\"type\":\"address\"}],\"name\":\"facetFunctionSelectorsFromStorage\",\"outputs\":[{\"internalType\":\"bytes4[]\",\"name\":\"facetFunctionSelectors_\",\"type\":\"bytes4[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facets\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondLoupe.Facet[]\",\"name\":\"facets_\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetsFromStorage\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondLoupe.Facet[]\",\"name\":\"facets_\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isSupported\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"DiamondLoupe contract compatible with EIP-2535\",\"kind\":\"dev\",\"methods\":{\"facetAddress(bytes4)\":{\"details\":\"If facet is not found return address(0).\",\"params\":{\"_functionSelector\":\"The function selector.\"},\"returns\":{\"facetAddress_\":\"The facet address.\"}},\"facetAddressFromStorage(bytes4)\":{\"params\":{\"_functionSelector\":\"Function selector to fetch the facet address from diamond storage\"},\"returns\":{\"facetAddress_\":\"Facet address mapped with the function selector\"}},\"facetAddresses()\":{\"returns\":{\"facetAddresses_\":\"facetAddresses_\"}},\"facetAddressesFromStorage()\":{\"returns\":{\"facetAddresses_\":\"All facet addresses attached directly to diamond storage\"}},\"facetFunctionSelectors(address)\":{\"params\":{\"_facet\":\"The facet address.\"},\"returns\":{\"facetFunctionSelectors_\":\"facetFunctionSelectors_\"}},\"facetFunctionSelectorsFromStorage(address)\":{\"params\":{\"_facet\":\"Facet address to fetch the facet function selectors from diamond storage\"},\"returns\":{\"facetFunctionSelectors_\":\"Facet function selectors of the given facet address\"}},\"facets()\":{\"details\":\"Barz uses a special architecture called default fallback handler. Default Fallback handler is used as a middleware that holds the mapping of facet function selector and facet address that Barz uses. This helps Barz to reduce significant amount of gas during the initialization process. Hence, this method aggregates both the facet information from DefaulFallbackHandler and in diamond storage and shows the data to users.\",\"returns\":{\"facets_\":\"Facet\"}},\"facetsFromStorage()\":{\"returns\":{\"facets_\":\"Facet information attached directly to diamond storage\"}},\"supportsInterface(bytes4)\":{\"params\":{\"_interfaceId\":\"Interface ID for detecting the interface\"},\"returns\":{\"isSupported\":\"Bool value showing if the standard is supported in the contract\"}}},\"title\":\"DiamondLoupe Facet\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"facetAddress(bytes4)\":{\"notice\":\"Gets the facet that supports the given selector.\"},\"facetAddressFromStorage(bytes4)\":{\"notice\":\"Returns the facet address attached to the given function selector. This excludes the facets from the default fallback handler\"},\"facetAddresses()\":{\"notice\":\"Get all the facet addresses used by Barz.\"},\"facetAddressesFromStorage()\":{\"notice\":\"Returns all facet addresses attached directly to diamond storage. This excludes the facets from the default fallback handler\"},\"facetFunctionSelectors(address)\":{\"notice\":\"Gets all the function selectors provided by a facet.\"},\"facetFunctionSelectorsFromStorage(address)\":{\"notice\":\"Returns function selectors of given facet address attached directly to diamond storage. This excludes the facets from the default fallback handler\"},\"facets()\":{\"notice\":\"Gets all facets and their selectors.\"},\"facetsFromStorage()\":{\"notice\":\"Returns the facet from the diamond storage. This excludes the facets from the default fallback handler\"},\"supportsInterface(bytes4)\":{\"notice\":\"SupportInterface to be compatible with EIP 165\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/base/DiamondLoupeFacet.sol\":\"DiamondLoupeFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/introspection/IERC165.sol\\\";\\n\\n/**\\n * @dev _Available since v3.1._\\n */\\ninterface IERC1155Receiver is IERC165 {\\n /**\\n * @dev Handles the receipt of a single ERC1155 token type. This function is\\n * called at the end of a `safeTransferFrom` after the balance has been updated.\\n *\\n * NOTE: To accept the transfer, this must return\\n * `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))`\\n * (i.e. 0xf23a6e61, or its own function selector).\\n *\\n * @param operator The address which initiated the transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param id The ID of the token being transferred\\n * @param value The amount of tokens being transferred\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155Received(\\n address operator,\\n address from,\\n uint256 id,\\n uint256 value,\\n bytes calldata data\\n ) external returns (bytes4);\\n\\n /**\\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\\n * is called at the end of a `safeBatchTransferFrom` after the balances have\\n * been updated.\\n *\\n * NOTE: To accept the transfer(s), this must return\\n * `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))`\\n * (i.e. 0xbc197c81, or its own function selector).\\n *\\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155BatchReceived(\\n address operator,\\n address from,\\n uint256[] calldata ids,\\n uint256[] calldata values,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xeb373f1fdc7b755c6a750123a9b9e3a8a02c1470042fd6505d875000a80bde0b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title ERC721 token receiver interface\\n * @dev Interface for any contract that wants to support safeTransfers\\n * from ERC721 asset contracts.\\n */\\ninterface IERC721Receiver {\\n /**\\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\\n * by `operator` from `from`, this function is called.\\n *\\n * It must return its Solidity selector to confirm the token transfer.\\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\\n *\\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\\n */\\n function onERC721Received(\\n address operator,\\n address from,\\n uint256 tokenId,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\\n *\\n * Accounts can be notified of {IERC777} tokens being sent to them by having a\\n * contract implement this interface (contract holders can be their own\\n * implementer) and registering it on the\\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\\n *\\n * See {IERC1820Registry} and {ERC1820Implementer}.\\n */\\ninterface IERC777Recipient {\\n /**\\n * @dev Called by an {IERC777} token contract whenever tokens are being\\n * moved or created into a registered account (`to`). The type of operation\\n * is conveyed by `from` being the zero address or not.\\n *\\n * This call occurs _after_ the token contract's state is updated, so\\n * {IERC777-balanceOf}, etc., can be used to query the post-operation state.\\n *\\n * This function may revert to prevent the operation from being executed.\\n */\\n function tokensReceived(\\n address operator,\\n address from,\\n address to,\\n uint256 amount,\\n bytes calldata userData,\\n bytes calldata operatorData\\n ) external;\\n}\\n\",\"keccak256\":\"0x1a5d61db2733202ba361e6d6741cd2e662380e22b80e987eacfc91973f2267dc\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"contracts/facets/base/DiamondLoupeFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IERC777Recipient} from \\\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\\\";\\nimport {IERC165} from \\\"../../interfaces/ERC/IERC165.sol\\\";\\nimport {IERC1271} from \\\"../../interfaces/ERC/IERC1271.sol\\\";\\nimport {IERC677Receiver} from \\\"../../interfaces/ERC/IERC677Receiver.sol\\\";\\nimport {IERC721Receiver} from \\\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\\\";\\nimport {IERC1155Receiver} from \\\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\\\";\\nimport {LibDiamond} from \\\"../../libraries/LibDiamond.sol\\\";\\nimport {LibLoupe} from \\\"../../libraries/LibLoupe.sol\\\";\\nimport {LibUtils} from \\\"../../libraries/LibUtils.sol\\\";\\nimport {IDiamondCut} from \\\"../../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IStorageLoupe} from \\\"./interfaces/IStorageLoupe.sol\\\";\\nimport {IDiamondLoupe} from \\\"./interfaces/IDiamondLoupe.sol\\\";\\n\\n/**\\n * @title DiamondLoupe Facet\\n * @dev DiamondLoupe contract compatible with EIP-2535\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract DiamondLoupeFacet is IDiamondLoupe, IStorageLoupe, IERC165 {\\n // Diamond Loupe Functions\\n ////////////////////////////////////////////////////////////////////\\n /// These functions are expected to be called frequently by tools off-chain.\\n\\n /**\\n * @notice Gets all facets and their selectors.\\n * @dev Barz uses a special architecture called default fallback handler. Default Fallback handler is used as a middleware\\n * that holds the mapping of facet function selector and facet address that Barz uses. This helps Barz to reduce\\n * significant amount of gas during the initialization process.\\n * Hence, this method aggregates both the facet information from DefaulFallbackHandler and in diamond storage and shows the data to users.\\n * @return facets_ Facet\\n */\\n function facets() public view override returns (Facet[] memory facets_) {\\n Facet[] memory defaultFacet = LibDiamond\\n .diamondStorage()\\n .defaultFallbackHandler\\n .facets();\\n Facet[] memory _facets = LibLoupe.facets();\\n uint256 numFacets = _facets.length;\\n bytes4[] memory keys;\\n address[] memory values;\\n for (uint256 i; i < numFacets; ) {\\n uint256 selectorsLength = _facets[i].functionSelectors.length;\\n for (uint256 j; j < selectorsLength; ) {\\n (keys, values) = LibUtils.setValue(\\n keys,\\n values,\\n _facets[i].functionSelectors[j],\\n _facets[i].facetAddress\\n );\\n unchecked {\\n ++j;\\n }\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n {\\n bool iIncrement;\\n for (uint256 i; i < defaultFacet.length; ) {\\n bool jIncrement;\\n for (\\n uint256 j;\\n j < defaultFacet[i].functionSelectors.length;\\n\\n ) {\\n if (\\n LibUtils.getValue(\\n keys,\\n values,\\n defaultFacet[i].functionSelectors[j]\\n ) != address(0)\\n ) {\\n if (defaultFacet[i].functionSelectors.length == 1) {\\n defaultFacet = LibUtils.removeFacetElement(\\n defaultFacet,\\n i\\n );\\n iIncrement = true;\\n break;\\n }\\n defaultFacet[i].functionSelectors = LibUtils\\n .removeElement(\\n defaultFacet[i].functionSelectors,\\n j\\n );\\n jIncrement = true;\\n }\\n if (!jIncrement) {\\n unchecked {\\n ++j;\\n }\\n } else {\\n jIncrement = false;\\n }\\n }\\n if (!iIncrement) {\\n unchecked {\\n ++i;\\n }\\n } else {\\n iIncrement = false;\\n }\\n }\\n }\\n {\\n uint256 facetLength = numFacets + defaultFacet.length;\\n facets_ = new Facet[](facetLength);\\n uint256 defaultFacetIndex;\\n for (uint256 i; i < facetLength; ) {\\n if (i < numFacets) {\\n facets_[i] = _facets[i];\\n bool jIncrementor;\\n for (uint256 j; j < defaultFacet.length; ) {\\n if (\\n facets_[i].facetAddress ==\\n defaultFacet[j].facetAddress\\n ) {\\n facets_[i].functionSelectors = LibUtils.mergeArrays(\\n _facets[i].functionSelectors,\\n defaultFacet[j].functionSelectors\\n );\\n defaultFacet = LibUtils.removeFacetElement(\\n defaultFacet,\\n j\\n );\\n jIncrementor = true;\\n {\\n facets_ = LibUtils.removeFacetElement(\\n facets_,\\n facets_.length - 1\\n );\\n }\\n --facetLength;\\n }\\n if (!jIncrementor) {\\n unchecked {\\n ++j;\\n }\\n } else {\\n jIncrementor = false;\\n }\\n }\\n } else {\\n facets_[i] = defaultFacet[defaultFacetIndex];\\n ++defaultFacetIndex;\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n }\\n\\n /**\\n * @notice Gets all the function selectors provided by a facet.\\n * @param _facet The facet address.\\n * @return facetFunctionSelectors_\\n */\\n function facetFunctionSelectors(\\n address _facet\\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\\n Facet[] memory facet = facets();\\n uint256 facetLength = facet.length;\\n for (uint256 i; i < facetLength; ) {\\n if (facet[i].facetAddress == _facet)\\n return facet[i].functionSelectors;\\n unchecked {\\n ++i;\\n }\\n }\\n return facetFunctionSelectors_;\\n }\\n\\n /**\\n * @notice Get all the facet addresses used by Barz.\\n * @return facetAddresses_\\n */\\n function facetAddresses()\\n external\\n view\\n override\\n returns (address[] memory facetAddresses_)\\n {\\n Facet[] memory facet = facets();\\n uint256 facetLength = facet.length;\\n facetAddresses_ = new address[](facetLength);\\n for (uint256 i; i < facetLength; ) {\\n facetAddresses_[i] = facet[i].facetAddress;\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * @notice Gets the facet that supports the given selector.\\n * @dev If facet is not found return address(0).\\n * @param _functionSelector The function selector.\\n * @return facetAddress_ The facet address.\\n */\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view override returns (address facetAddress_) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n\\n facetAddress_ = address(bytes20(ds.facets[_functionSelector]));\\n if (facetAddress_ == address(0)) {\\n facetAddress_ = IDiamondLoupe(ds.defaultFallbackHandler)\\n .facetAddress(_functionSelector);\\n }\\n }\\n\\n /**\\n * @notice SupportInterface to be compatible with EIP 165\\n * @param _interfaceId Interface ID for detecting the interface\\n * @return isSupported Bool value showing if the standard is supported in the contract\\n */\\n function supportsInterface(\\n bytes4 _interfaceId\\n ) external view override returns (bool isSupported) {\\n isSupported =\\n _interfaceId == type(IERC165).interfaceId ||\\n _interfaceId == IDiamondCut.diamondCut.selector ||\\n _interfaceId == type(IDiamondLoupe).interfaceId ||\\n _interfaceId == type(IERC1155Receiver).interfaceId ||\\n _interfaceId == type(IERC721Receiver).interfaceId ||\\n _interfaceId == type(IERC777Recipient).interfaceId ||\\n _interfaceId == IERC1271.isValidSignature.selector ||\\n _interfaceId == type(IERC677Receiver).interfaceId ||\\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId];\\n }\\n\\n /**\\n * @notice Returns the facet from the diamond storage. This excludes the facets from the default fallback handler\\n * @return facets_ Facet information attached directly to diamond storage\\n */\\n function facetsFromStorage()\\n external\\n view\\n override\\n returns (Facet[] memory facets_)\\n {\\n facets_ = LibLoupe.facets();\\n }\\n\\n /**\\n * @notice Returns the facet address attached to the given function selector. This excludes the facets from the default fallback handler\\n * @param _functionSelector Function selector to fetch the facet address from diamond storage\\n * @return facetAddress_ Facet address mapped with the function selector\\n */\\n function facetAddressFromStorage(\\n bytes4 _functionSelector\\n ) external view override returns (address facetAddress_) {\\n facetAddress_ = LibLoupe.facetAddress(_functionSelector);\\n }\\n\\n /**\\n * @notice Returns all facet addresses attached directly to diamond storage. This excludes the facets from the default fallback handler\\n * @return facetAddresses_ All facet addresses attached directly to diamond storage\\n */\\n function facetAddressesFromStorage()\\n external\\n view\\n override\\n returns (address[] memory facetAddresses_)\\n {\\n facetAddresses_ = LibLoupe.facetAddresses();\\n }\\n\\n /**\\n * @notice Returns function selectors of given facet address attached directly to diamond storage. This excludes the facets from the default fallback handler\\n * @param _facet Facet address to fetch the facet function selectors from diamond storage\\n * @return facetFunctionSelectors_ Facet function selectors of the given facet address\\n */\\n function facetFunctionSelectorsFromStorage(\\n address _facet\\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\\n facetFunctionSelectors_ = LibLoupe.facetFunctionSelectors(_facet);\\n }\\n}\\n\",\"keccak256\":\"0xf392fde159eec6483fc15fa323ecd6d764028f5b8734a66662c4116292363794\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IStorageLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"./IDiamondLoupe.sol\\\";\\n\\n/**\\n * @title LoupeFromStorage Interface\\n * @dev Interface contract to function as a loupe facet directly attached to diamond storage of Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IStorageLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facetsFromStorage()\\n external\\n view\\n returns (IDiamondLoupe.Facet[] memory);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n function facetFunctionSelectorsFromStorage(\\n address _facet\\n ) external view returns (bytes4[] memory);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n function facetAddressesFromStorage()\\n external\\n view\\n returns (address[] memory);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n function facetAddressFromStorage(\\n bytes4 _functionSelector\\n ) external view returns (address);\\n}\\n\",\"keccak256\":\"0xdf5dc9c57319e9087628c9cf9404b4f75585b76d1c2f4f59ee796c933967ea5c\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC1271 {\\n function isValidSignature(\\n bytes32 hash,\\n bytes memory signature\\n ) external view returns (bytes4);\\n}\\n\",\"keccak256\":\"0xcdddb7d5641c9d3f2432dec7fd13fddb9ae1480f25c76c21511e2fa16b8bd422\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.21;\\n\\ninterface IERC165 {\\n /// @notice Query if a contract implements an interface\\n /// @param interfaceId The interface identifier, as specified in ERC-165\\n /// @dev Interface identification is specified in ERC-165. This function\\n /// uses less than 30,000 gas.\\n /// @return `true` if the contract implements `interfaceID` and\\n /// `interfaceID` is not 0xffffffff, `false` otherwise\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xbb7f07e170898793c5535cc4b7e8944c4b990a631ac806d0b788e794abc788a3\",\"license\":\"MIT\"},\"contracts/interfaces/ERC/IERC677Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC677Receiver {\\n function onTokenTransfer(\\n address sender,\\n uint value,\\n bytes calldata data\\n ) external pure returns (bool);\\n}\\n\",\"keccak256\":\"0x4c1631cf45ea6daac0ec158c3edb9453099130b6b64f697004b83f95aa1f7350\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\\n bytes4(keccak256(\\\"verifyRestrictions(address,address,uint256,bytes)\\\"));\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // Default Fallback Handler of the barz.\\n IDiamondLoupe defaultFallbackHandler;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function enforceIsSelf() internal view {\\n require(msg.sender == address(this), \\\"LibDiamond: Caller not self\\\");\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n\\n unchecked {\\n facetIndex++;\\n }\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n\\n function restrictionsFacet() internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(\\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2cabdc00de859c3a3170ce3bda5d0e5fd3933d47ce904fd1585f9818b02572f8\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\nimport {LibDiamond} from \\\"./LibDiamond.sol\\\";\\n\\n/**\\n * @title LibLoupe\\n * @dev Internal Library to provide utility feature for reading the state of diamond facets\\n * Originally from Diamond's implementation of Mudgen(author of EIP-2535)\\n */\\nlibrary LibLoupe {\\n /// @notice Gets all facets and their selectors.\\n /// @return facets_ Facet\\n function facets()\\n internal\\n view\\n returns (IDiamondLoupe.Facet[] memory facets_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facets_ = new IDiamondLoupe.Facet[](ds.selectorCount);\\n uint16[] memory numFacetSelectors = new uint16[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facets_[facetIndex].facetAddress == facetAddress_) {\\n facets_[facetIndex].functionSelectors[\\n numFacetSelectors[facetIndex]\\n ] = selector;\\n // probably will never have more than 256 functions from one facet contract\\n require(numFacetSelectors[facetIndex] < 255);\\n numFacetSelectors[facetIndex]++;\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facets_[numFacets].facetAddress = facetAddress_;\\n facets_[numFacets].functionSelectors = new bytes4[](\\n ds.selectorCount\\n );\\n facets_[numFacets].functionSelectors[0] = selector;\\n numFacetSelectors[numFacets] = 1;\\n numFacets++;\\n }\\n }\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n uint256 numSelectors = numFacetSelectors[facetIndex];\\n bytes4[] memory selectors = facets_[facetIndex].functionSelectors;\\n // setting the number of selectors\\n assembly {\\n mstore(selectors, numSelectors)\\n }\\n }\\n // setting the number of facets\\n assembly {\\n mstore(facets_, numFacets)\\n }\\n }\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return _facetFunctionSelectors The selectors associated with a facet address.\\n function facetFunctionSelectors(\\n address _facet\\n ) internal view returns (bytes4[] memory _facetFunctionSelectors) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n uint256 numSelectors;\\n _facetFunctionSelectors = new bytes4[](ds.selectorCount);\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facet = address(bytes20(ds.facets[selector]));\\n if (_facet == facet) {\\n _facetFunctionSelectors[numSelectors] = selector;\\n numSelectors++;\\n }\\n }\\n }\\n // Set the number of selectors in the array\\n assembly {\\n mstore(_facetFunctionSelectors, numSelectors)\\n }\\n }\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n internal\\n view\\n returns (address[] memory facetAddresses_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetAddresses_ = new address[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facetAddress_ == facetAddresses_[facetIndex]) {\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facetAddresses_[numFacets] = facetAddress_;\\n numFacets++;\\n }\\n }\\n // Set the number of facet addresses in the array\\n assembly {\\n mstore(facetAddresses_, numFacets)\\n }\\n }\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(LibDiamond.diamondStorage().facets[_functionSelector])\\n );\\n }\\n}\\n\",\"keccak256\":\"0x0b11439c3cc657095e15ec2241fdcf67204b14001357b612fc5db4ff9e760a5a\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibUtils.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nlibrary LibUtils {\\n // Internal utility functions\\n function mergeArrays(\\n bytes4[] memory _array1,\\n bytes4[] memory _array2\\n ) internal pure returns (bytes4[] memory) {\\n uint256 length1 = _array1.length;\\n uint256 length2 = _array2.length;\\n bytes4[] memory mergedArray = new bytes4[](length1 + length2);\\n\\n for (uint256 i; i < length1; ) {\\n mergedArray[i] = _array1[i];\\n unchecked {\\n ++i;\\n }\\n }\\n\\n for (uint256 i; i < length2; ) {\\n mergedArray[length1 + i] = _array2[i];\\n unchecked {\\n ++i;\\n }\\n }\\n\\n return mergedArray;\\n }\\n\\n function removeFacetElement(\\n IDiamondLoupe.Facet[] memory _facets,\\n uint256 _index\\n ) internal pure returns (IDiamondLoupe.Facet[] memory) {\\n require(_index < _facets.length, \\\"Invalid index\\\");\\n require(_facets.length != 0, \\\"Invalid array\\\");\\n\\n // Create a new array with a length of `_facets.length - 1`\\n IDiamondLoupe.Facet[] memory newArray = new IDiamondLoupe.Facet[](\\n _facets.length - 1\\n );\\n uint256 newArrayLength = newArray.length;\\n // Iterate over the original array, skipping the element at the specified `index`\\n for (uint256 i; i < newArrayLength; ) {\\n if (i < _index) {\\n newArray[i] = _facets[i];\\n } else {\\n newArray[i] = _facets[i + 1];\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n\\n return newArray;\\n }\\n\\n function removeElement(\\n bytes4[] memory _array,\\n uint256 _index\\n ) internal pure returns (bytes4[] memory) {\\n require(_index < _array.length, \\\"Invalid index\\\");\\n require(_array.length != 0, \\\"Invalid array\\\");\\n\\n bytes4[] memory newArray = new bytes4[](_array.length - 1);\\n uint256 newArrayLength = newArray.length;\\n for (uint256 i; i < newArrayLength; ) {\\n if (i < _index) {\\n newArray[i] = _array[i];\\n } else {\\n newArray[i] = _array[i + 1];\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n\\n return newArray;\\n }\\n\\n function setValue(\\n bytes4[] memory _keys,\\n address[] memory _values,\\n bytes4 _key,\\n address _value\\n ) internal pure returns (bytes4[] memory, address[] memory) {\\n uint256 index = findIndex(_keys, _key);\\n uint256 keysLength = _keys.length;\\n if (index < keysLength) {\\n _values[index] = _value;\\n } else {\\n // Create new storage arrays\\n bytes4[] memory newKeys = new bytes4[](keysLength + 1);\\n address[] memory newValues = new address[](_values.length + 1);\\n\\n // Copy values to the new storage arrays\\n for (uint256 i; i < keysLength; ) {\\n newKeys[i] = _keys[i];\\n newValues[i] = _values[i];\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n // Add the new key-value pair\\n newKeys[keysLength] = _key;\\n newValues[_values.length] = _value;\\n\\n return (newKeys, newValues);\\n }\\n\\n // If the key already exists, return the original arrays\\n return (_keys, _values);\\n }\\n\\n function getValue(\\n bytes4[] memory _keys,\\n address[] memory _values,\\n bytes4 _key\\n ) internal pure returns (address) {\\n uint256 index = findIndex(_keys, _key);\\n if (index >= _keys.length) return address(0);\\n\\n return _values[index];\\n }\\n\\n function findIndex(\\n bytes4[] memory _keys,\\n bytes4 _key\\n ) internal pure returns (uint256) {\\n uint256 keysLength = _keys.length;\\n for (uint256 i; i < keysLength; ) {\\n if (_keys[i] == _key) {\\n return i;\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n return keysLength;\\n }\\n}\\n\",\"keccak256\":\"0xde8aeefe54c4be483f2b2c055aca11e2830f7094c0586a82e10ec544933b5714\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5061240b806100206000396000f3fe608060405234801561001057600080fd5b50600436106100a35760003560e01c8063adfca15e11610076578063d42139a91161005b578063d42139a914610169578063e3a2f6fe14610171578063f9796ccf1461018457600080fd5b8063adfca15e1461011e578063cdffacc61461013157600080fd5b806301a55022146100a857806301ffc9a7146100d157806352ef6b2c146100f45780637a0ed62714610109575b600080fd5b6100bb6100b6366004611e4b565b61018c565b6040516100c89190611e68565b60405180910390f35b6100e46100df366004611efc565b61019d565b60405190151581526020016100c8565b6100fc610454565b6040516100c89190611f19565b610111610518565b6040516100c89190611f67565b6100bb61012c366004611e4b565b610a63565b61014461013f366004611efc565b610b07565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100c8565b6100fc610c24565b61014461017f366004611efc565b610c33565b610111610c8c565b606061019782610c96565b92915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000148061023057507fffffffff0000000000000000000000000000000000000000000000000000000082167f1f931c1c00000000000000000000000000000000000000000000000000000000145b8061027c57507fffffffff0000000000000000000000000000000000000000000000000000000082167f48e2b09300000000000000000000000000000000000000000000000000000000145b806102c857507fffffffff0000000000000000000000000000000000000000000000000000000082167f4e2312e000000000000000000000000000000000000000000000000000000000145b8061031457507fffffffff0000000000000000000000000000000000000000000000000000000082167f150b7a0200000000000000000000000000000000000000000000000000000000145b8061035f57507fffffffff0000000000000000000000000000000000000000000000000000000082167e23de2900000000000000000000000000000000000000000000000000000000145b806103ab57507fffffffff0000000000000000000000000000000000000000000000000000000082167f1626ba7e00000000000000000000000000000000000000000000000000000000145b806103f757507fffffffff0000000000000000000000000000000000000000000000000000000082167fa4c0ed3600000000000000000000000000000000000000000000000000000000145b806101975750507fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4922602052604090205460ff1690565b60606000610460610518565b80519091508067ffffffffffffffff81111561047e5761047e61205d565b6040519080825280602002602001820160405280156104a7578160200160208202803683370190505b50925060005b81811015610512578281815181106104c7576104c761208c565b6020026020010151600001518482815181106104e5576104e561208c565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526001016104ad565b50505090565b606060007f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f600490810154604080517f7a0ed627000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff90921692637a0ed6279282820192600092908290030181865afa1580156105ac573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526105f29190810190612157565b905060006105fe610e57565b805190915060608060005b838110156106b55760008582815181106106255761062561208c565b60200260200101516020015151905060005b818110156106ab5761069e85858986815181106106565761065661208c565b60200260200101516020015184815181106106735761067361208c565b60200260200101518a878151811061068d5761068d61208c565b60200260200101516000015161134a565b9095509350600101610637565b5050600101610609565b506000805b865181101561081b576000805b8883815181106106d9576106d961208c565b602002602001015160200151518110156107ff57600073ffffffffffffffffffffffffffffffffffffffff1661074687878c878151811061071c5761071c61208c565b60200260200101516020015185815181106107395761073961208c565b60200260200101516115f1565b73ffffffffffffffffffffffffffffffffffffffff16146107e9578883815181106107735761077361208c565b6020026020010151602001515160010361079c576107918984611637565b9850600193506107ff565b6107c38984815181106107b1576107b161208c565b6020026020010151602001518261182a565b8984815181106107d5576107d561208c565b602002602001015160200181905250600191505b816107f6576001016106c7565b600091506106c7565b508261081057816001019150610815565b600092505b506106ba565b5050600085518461082c9190612304565b90508067ffffffffffffffff8111156108475761084761205d565b60405190808252806020026020018201604052801561088d57816020015b6040805180820190915260008152606060208201528152602001906001900390816108655790505b5096506000805b82811015610a585785811015610a0c578681815181106108b6576108b661208c565b60200260200101518982815181106108d0576108d061208c565b60200260200101819052506000805b8951811015610a05578981815181106108fa576108fa61208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff168b848151811061092e5761092e61208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff16036109ef5761099989848151811061096a5761096a61208c565b6020026020010151602001518b83815181106109885761098861208c565b602002602001015160200151611a3d565b8b84815181106109ab576109ab61208c565b6020026020010151602001819052506109c48a82611637565b9950600191506109e18b60018d516109dc9190612317565b611637565b9a506109ec8561232a565b94505b816109fc576001016108df565b600091506108df565b5050610a50565b878281518110610a1e57610a1e61208c565b6020026020010151898281518110610a3857610a3861208c565b602002602001018190525081610a4d9061235f565b91505b600101610894565b505050505050505090565b60606000610a6f610518565b805190915060005b81811015610aff578473ffffffffffffffffffffffffffffffffffffffff16838281518110610aa857610aa861208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1603610af757828181518110610ae157610ae161208c565b6020026020010151602001519350505050919050565b600101610a77565b505050919050565b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602081905260409091205460601c9081610c1e576004818101546040517fcdffacc60000000000000000000000000000000000000000000000000000000081527fffffffff0000000000000000000000000000000000000000000000000000000086169281019290925273ffffffffffffffffffffffffffffffffffffffff169063cdffacc690602401602060405180830381865afa158015610bf7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c1b9190612397565b91505b50919050565b6060610c2e611b8b565b905090565b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604081205460601c610197565b6060610c2e610e57565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9060009061ffff1667ffffffffffffffff811115610cfc57610cfc61205d565b604051908082528060200260200182016040528015610d25578160200160208202803683370190505b5092506000805b600284015461ffff16821015610e4d576000818152600185016020526040812054905b6008811015610e385783610d628161235f565b600288015490955061ffff1685119050610e3857600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020889052604090205460601c73ffffffffffffffffffffffffffffffffffffffff8a16819003610e235781898881518110610de457610de461208c565b7fffffffff000000000000000000000000000000000000000000000000000000009092166020928302919091019091015286610e1f8161235f565b9750505b50508080610e309061235f565b915050610d4f565b50508080610e459061235f565b915050610d2c565b5050825250919050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff1667ffffffffffffffff811115610eba57610eba61205d565b604051908082528060200260200182016040528015610f0057816020015b604080518082019091526000815260606020820152815260200190600190039081610ed85790505b50600282015490925060009061ffff1667ffffffffffffffff811115610f2857610f2861205d565b604051908082528060200260200182016040528015610f51578160200160208202803683370190505b50905060008060005b600285015461ffff168210156112d7576000818152600186016020526040812054905b60088110156112c25783610f908161235f565b600289015490955061ffff16851190506112c257600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020899052604081205460601c90805b88811015611148578273ffffffffffffffffffffffffffffffffffffffff168c82815181106110155761101561208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff160361113657838c828151811061104f5761104f61208c565b6020026020010151602001518b838151811061106d5761106d61208c565b602002602001015161ffff16815181106110895761108961208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152505060ff8a82815181106110e9576110e961208c565b602002602001015161ffff16106110ff57600080fd5b8981815181106111115761111161208c565b602002602001018051809190611126906123b4565b61ffff1690525060019150611148565b806111408161235f565b915050610fe4565b508015611157575050506112b0565b818b898151811061116a5761116a61208c565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff909116905260028a015461ffff1667ffffffffffffffff8111156111b0576111b061205d565b6040519080825280602002602001820160405280156111d9578160200160208202803683370190505b508b89815181106111ec576111ec61208c565b602002602001015160200181905250828b898151811061120e5761120e61208c565b60200260200101516020015160008151811061122c5761122c61208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681525050600189898151811061128c5761128c61208c565b61ffff90921660209283029190910190910152876112a98161235f565b9850505050505b806112ba8161235f565b915050610f7d565b505080806112cf9061235f565b915050610f5a565b5060005b8281101561133f5760008482815181106112f7576112f761208c565b602002602001015161ffff16905060008783815181106113195761131961208c565b6020026020010151602001519050818152505080806113379061235f565b9150506112db565b508185525050505090565b60608060006113598786611da0565b8751909150808210156113b857848783815181106113795761137961208c565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250506115df565b60006113c5826001612304565b67ffffffffffffffff8111156113dd576113dd61205d565b604051908082528060200260200182016040528015611406578160200160208202803683370190505b5090506000885160016114199190612304565b67ffffffffffffffff8111156114315761143161205d565b60405190808252806020026020018201604052801561145a578160200160208202803683370190505b50905060005b83811015611539578a818151811061147a5761147a61208c565b60200260200101518382815181106114945761149461208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815250508981815181106114f2576114f261208c565b602002602001015182828151811061150c5761150c61208c565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101611460565b508782848151811061154d5761154d61208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152505086818a51815181106115ad576115ad61208c565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015290945092506115e8915050565b87879350935050505b94509492505050565b6000806115fe8584611da0565b905084518110611612576000915050611630565b8381815181106116245761162461208c565b60200260200101519150505b9392505050565b6060825182106116a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420696e6465780000000000000000000000000000000000000060448201526064015b60405180910390fd5b8251600003611713576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420617272617900000000000000000000000000000000000000604482015260640161169f565b6000600184516117239190612317565b67ffffffffffffffff81111561173b5761173b61205d565b60405190808252806020026020018201604052801561178157816020015b6040805180820190915260008152606060208201528152602001906001900390816117595790505b50805190915060005b8181101561182057848110156117d6578581815181106117ac576117ac61208c565b60200260200101518382815181106117c6576117c661208c565b6020026020010181905250611818565b856117e2826001612304565b815181106117f2576117f261208c565b602002602001015183828151811061180c5761180c61208c565b60200260200101819052505b60010161178a565b5090949350505050565b606082518210611896576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420696e64657800000000000000000000000000000000000000604482015260640161169f565b8251600003611901576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420617272617900000000000000000000000000000000000000604482015260640161169f565b6000600184516119119190612317565b67ffffffffffffffff8111156119295761192961205d565b604051908082528060200260200182016040528015611952578160200160208202803683370190505b50805190915060005b8181101561182057848110156119cd5785818151811061197d5761197d61208c565b60200260200101518382815181106119975761199761208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152611a35565b856119d9826001612304565b815181106119e9576119e961208c565b6020026020010151838281518110611a0357611a0361208c565b7fffffffff00000000000000000000000000000000000000000000000000000000909216602092830291909101909101525b60010161195b565b81518151606091906000611a518284612304565b67ffffffffffffffff811115611a6957611a6961205d565b604051908082528060200260200182016040528015611a92578160200160208202803683370190505b50905060005b83811015611b0557868181518110611ab257611ab261208c565b6020026020010151828281518110611acc57611acc61208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152600101611a98565b5060005b82811015611b8157858181518110611b2357611b2361208c565b6020026020010151828286611b389190612304565b81518110611b4857611b4861208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152600101611b09565b5095945050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff1667ffffffffffffffff811115611bee57611bee61205d565b604051908082528060200260200182016040528015611c17578160200160208202803683370190505b50915060008060005b600284015461ffff16821015611d98576000818152600185016020526040812054905b6008811015611d835783611c568161235f565b600288015490955061ffff1685119050611d8357600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020889052604081205460601c90805b88811015611d19578a8181518110611cc457611cc461208c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611d075760019150611d19565b80611d118161235f565b915050611caa565b508015611d2857505050611d71565b818a8981518110611d3b57611d3b61208c565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015287611d6a8161235f565b9850505050505b80611d7b8161235f565b915050611c43565b50508080611d909061235f565b915050611c20565b505082525090565b8151600090815b81811015611e1e57837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916858281518110611de157611de161208c565b60200260200101517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603611e165791506101979050565b600101611da7565b509392505050565b73ffffffffffffffffffffffffffffffffffffffff81168114611e4857600080fd5b50565b600060208284031215611e5d57600080fd5b813561163081611e26565b6020808252825182820181905260009190848201906040850190845b81811015611ec25783517fffffffff000000000000000000000000000000000000000000000000000000001683529284019291840191600101611e84565b50909695505050505050565b7fffffffff0000000000000000000000000000000000000000000000000000000081168114611e4857600080fd5b600060208284031215611f0e57600080fd5b813561163081611ece565b6020808252825182820181905260009190848201906040850190845b81811015611ec257835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101611f35565b60006020808301818452808551808352604092508286019150828160051b8701018488016000805b8481101561204e578984037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00186528251805173ffffffffffffffffffffffffffffffffffffffff168552880151888501889052805188860181905290890190839060608701905b808310156120395783517fffffffff00000000000000000000000000000000000000000000000000000000168252928b019260019290920191908b0190611ff7565b50978a01979550505091870191600101611f8f565b50919998505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6040805190810167ffffffffffffffff811182821017156120de576120de61205d565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561212b5761212b61205d565b604052919050565b600067ffffffffffffffff82111561214d5761214d61205d565b5060051b60200190565b6000602080838503121561216a57600080fd5b825167ffffffffffffffff8082111561218257600080fd5b818501915085601f83011261219657600080fd5b81516121a96121a482612133565b6120e4565b81815260059190911b830184019084810190888311156121c857600080fd5b8585015b838110156122c8578051858111156121e45760008081fd5b86016040818c037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00181131561221a5760008081fd5b6122226120bb565b8983015161222f81611e26565b815282820151888111156122435760008081fd5b8084019350508c603f8401126122595760008081fd5b898301516122696121a482612133565b81815260059190911b84018301908b8101908f8311156122895760008081fd5b948401945b828610156122b357855194506122a385611ece565b848252948c0194908c019061228e565b838d01525050855250509186019186016121cc565b5098975050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610197576101976122d5565b81810381811115610197576101976122d5565b600081612339576123396122d5565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612390576123906122d5565b5060010190565b6000602082840312156123a957600080fd5b815161163081611e26565b600061ffff8083168181036123cb576123cb6122d5565b600101939250505056fea26469706673582212205959d8d85aad6f29d5fc37d5a52c404c25392cec49195c3b761da0e863e99b0f64736f6c63430008150033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100a35760003560e01c8063adfca15e11610076578063d42139a91161005b578063d42139a914610169578063e3a2f6fe14610171578063f9796ccf1461018457600080fd5b8063adfca15e1461011e578063cdffacc61461013157600080fd5b806301a55022146100a857806301ffc9a7146100d157806352ef6b2c146100f45780637a0ed62714610109575b600080fd5b6100bb6100b6366004611e4b565b61018c565b6040516100c89190611e68565b60405180910390f35b6100e46100df366004611efc565b61019d565b60405190151581526020016100c8565b6100fc610454565b6040516100c89190611f19565b610111610518565b6040516100c89190611f67565b6100bb61012c366004611e4b565b610a63565b61014461013f366004611efc565b610b07565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100c8565b6100fc610c24565b61014461017f366004611efc565b610c33565b610111610c8c565b606061019782610c96565b92915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000148061023057507fffffffff0000000000000000000000000000000000000000000000000000000082167f1f931c1c00000000000000000000000000000000000000000000000000000000145b8061027c57507fffffffff0000000000000000000000000000000000000000000000000000000082167f48e2b09300000000000000000000000000000000000000000000000000000000145b806102c857507fffffffff0000000000000000000000000000000000000000000000000000000082167f4e2312e000000000000000000000000000000000000000000000000000000000145b8061031457507fffffffff0000000000000000000000000000000000000000000000000000000082167f150b7a0200000000000000000000000000000000000000000000000000000000145b8061035f57507fffffffff0000000000000000000000000000000000000000000000000000000082167e23de2900000000000000000000000000000000000000000000000000000000145b806103ab57507fffffffff0000000000000000000000000000000000000000000000000000000082167f1626ba7e00000000000000000000000000000000000000000000000000000000145b806103f757507fffffffff0000000000000000000000000000000000000000000000000000000082167fa4c0ed3600000000000000000000000000000000000000000000000000000000145b806101975750507fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4922602052604090205460ff1690565b60606000610460610518565b80519091508067ffffffffffffffff81111561047e5761047e61205d565b6040519080825280602002602001820160405280156104a7578160200160208202803683370190505b50925060005b81811015610512578281815181106104c7576104c761208c565b6020026020010151600001518482815181106104e5576104e561208c565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526001016104ad565b50505090565b606060007f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f600490810154604080517f7a0ed627000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff90921692637a0ed6279282820192600092908290030181865afa1580156105ac573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526105f29190810190612157565b905060006105fe610e57565b805190915060608060005b838110156106b55760008582815181106106255761062561208c565b60200260200101516020015151905060005b818110156106ab5761069e85858986815181106106565761065661208c565b60200260200101516020015184815181106106735761067361208c565b60200260200101518a878151811061068d5761068d61208c565b60200260200101516000015161134a565b9095509350600101610637565b5050600101610609565b506000805b865181101561081b576000805b8883815181106106d9576106d961208c565b602002602001015160200151518110156107ff57600073ffffffffffffffffffffffffffffffffffffffff1661074687878c878151811061071c5761071c61208c565b60200260200101516020015185815181106107395761073961208c565b60200260200101516115f1565b73ffffffffffffffffffffffffffffffffffffffff16146107e9578883815181106107735761077361208c565b6020026020010151602001515160010361079c576107918984611637565b9850600193506107ff565b6107c38984815181106107b1576107b161208c565b6020026020010151602001518261182a565b8984815181106107d5576107d561208c565b602002602001015160200181905250600191505b816107f6576001016106c7565b600091506106c7565b508261081057816001019150610815565b600092505b506106ba565b5050600085518461082c9190612304565b90508067ffffffffffffffff8111156108475761084761205d565b60405190808252806020026020018201604052801561088d57816020015b6040805180820190915260008152606060208201528152602001906001900390816108655790505b5096506000805b82811015610a585785811015610a0c578681815181106108b6576108b661208c565b60200260200101518982815181106108d0576108d061208c565b60200260200101819052506000805b8951811015610a05578981815181106108fa576108fa61208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff168b848151811061092e5761092e61208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff16036109ef5761099989848151811061096a5761096a61208c565b6020026020010151602001518b83815181106109885761098861208c565b602002602001015160200151611a3d565b8b84815181106109ab576109ab61208c565b6020026020010151602001819052506109c48a82611637565b9950600191506109e18b60018d516109dc9190612317565b611637565b9a506109ec8561232a565b94505b816109fc576001016108df565b600091506108df565b5050610a50565b878281518110610a1e57610a1e61208c565b6020026020010151898281518110610a3857610a3861208c565b602002602001018190525081610a4d9061235f565b91505b600101610894565b505050505050505090565b60606000610a6f610518565b805190915060005b81811015610aff578473ffffffffffffffffffffffffffffffffffffffff16838281518110610aa857610aa861208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1603610af757828181518110610ae157610ae161208c565b6020026020010151602001519350505050919050565b600101610a77565b505050919050565b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602081905260409091205460601c9081610c1e576004818101546040517fcdffacc60000000000000000000000000000000000000000000000000000000081527fffffffff0000000000000000000000000000000000000000000000000000000086169281019290925273ffffffffffffffffffffffffffffffffffffffff169063cdffacc690602401602060405180830381865afa158015610bf7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c1b9190612397565b91505b50919050565b6060610c2e611b8b565b905090565b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604081205460601c610197565b6060610c2e610e57565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9060009061ffff1667ffffffffffffffff811115610cfc57610cfc61205d565b604051908082528060200260200182016040528015610d25578160200160208202803683370190505b5092506000805b600284015461ffff16821015610e4d576000818152600185016020526040812054905b6008811015610e385783610d628161235f565b600288015490955061ffff1685119050610e3857600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020889052604090205460601c73ffffffffffffffffffffffffffffffffffffffff8a16819003610e235781898881518110610de457610de461208c565b7fffffffff000000000000000000000000000000000000000000000000000000009092166020928302919091019091015286610e1f8161235f565b9750505b50508080610e309061235f565b915050610d4f565b50508080610e459061235f565b915050610d2c565b5050825250919050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff1667ffffffffffffffff811115610eba57610eba61205d565b604051908082528060200260200182016040528015610f0057816020015b604080518082019091526000815260606020820152815260200190600190039081610ed85790505b50600282015490925060009061ffff1667ffffffffffffffff811115610f2857610f2861205d565b604051908082528060200260200182016040528015610f51578160200160208202803683370190505b50905060008060005b600285015461ffff168210156112d7576000818152600186016020526040812054905b60088110156112c25783610f908161235f565b600289015490955061ffff16851190506112c257600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020899052604081205460601c90805b88811015611148578273ffffffffffffffffffffffffffffffffffffffff168c82815181106110155761101561208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff160361113657838c828151811061104f5761104f61208c565b6020026020010151602001518b838151811061106d5761106d61208c565b602002602001015161ffff16815181106110895761108961208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152505060ff8a82815181106110e9576110e961208c565b602002602001015161ffff16106110ff57600080fd5b8981815181106111115761111161208c565b602002602001018051809190611126906123b4565b61ffff1690525060019150611148565b806111408161235f565b915050610fe4565b508015611157575050506112b0565b818b898151811061116a5761116a61208c565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff909116905260028a015461ffff1667ffffffffffffffff8111156111b0576111b061205d565b6040519080825280602002602001820160405280156111d9578160200160208202803683370190505b508b89815181106111ec576111ec61208c565b602002602001015160200181905250828b898151811061120e5761120e61208c565b60200260200101516020015160008151811061122c5761122c61208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681525050600189898151811061128c5761128c61208c565b61ffff90921660209283029190910190910152876112a98161235f565b9850505050505b806112ba8161235f565b915050610f7d565b505080806112cf9061235f565b915050610f5a565b5060005b8281101561133f5760008482815181106112f7576112f761208c565b602002602001015161ffff16905060008783815181106113195761131961208c565b6020026020010151602001519050818152505080806113379061235f565b9150506112db565b508185525050505090565b60608060006113598786611da0565b8751909150808210156113b857848783815181106113795761137961208c565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250506115df565b60006113c5826001612304565b67ffffffffffffffff8111156113dd576113dd61205d565b604051908082528060200260200182016040528015611406578160200160208202803683370190505b5090506000885160016114199190612304565b67ffffffffffffffff8111156114315761143161205d565b60405190808252806020026020018201604052801561145a578160200160208202803683370190505b50905060005b83811015611539578a818151811061147a5761147a61208c565b60200260200101518382815181106114945761149461208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815250508981815181106114f2576114f261208c565b602002602001015182828151811061150c5761150c61208c565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101611460565b508782848151811061154d5761154d61208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152505086818a51815181106115ad576115ad61208c565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015290945092506115e8915050565b87879350935050505b94509492505050565b6000806115fe8584611da0565b905084518110611612576000915050611630565b8381815181106116245761162461208c565b60200260200101519150505b9392505050565b6060825182106116a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420696e6465780000000000000000000000000000000000000060448201526064015b60405180910390fd5b8251600003611713576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420617272617900000000000000000000000000000000000000604482015260640161169f565b6000600184516117239190612317565b67ffffffffffffffff81111561173b5761173b61205d565b60405190808252806020026020018201604052801561178157816020015b6040805180820190915260008152606060208201528152602001906001900390816117595790505b50805190915060005b8181101561182057848110156117d6578581815181106117ac576117ac61208c565b60200260200101518382815181106117c6576117c661208c565b6020026020010181905250611818565b856117e2826001612304565b815181106117f2576117f261208c565b602002602001015183828151811061180c5761180c61208c565b60200260200101819052505b60010161178a565b5090949350505050565b606082518210611896576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420696e64657800000000000000000000000000000000000000604482015260640161169f565b8251600003611901576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420617272617900000000000000000000000000000000000000604482015260640161169f565b6000600184516119119190612317565b67ffffffffffffffff8111156119295761192961205d565b604051908082528060200260200182016040528015611952578160200160208202803683370190505b50805190915060005b8181101561182057848110156119cd5785818151811061197d5761197d61208c565b60200260200101518382815181106119975761199761208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152611a35565b856119d9826001612304565b815181106119e9576119e961208c565b6020026020010151838281518110611a0357611a0361208c565b7fffffffff00000000000000000000000000000000000000000000000000000000909216602092830291909101909101525b60010161195b565b81518151606091906000611a518284612304565b67ffffffffffffffff811115611a6957611a6961205d565b604051908082528060200260200182016040528015611a92578160200160208202803683370190505b50905060005b83811015611b0557868181518110611ab257611ab261208c565b6020026020010151828281518110611acc57611acc61208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152600101611a98565b5060005b82811015611b8157858181518110611b2357611b2361208c565b6020026020010151828286611b389190612304565b81518110611b4857611b4861208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152600101611b09565b5095945050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff1667ffffffffffffffff811115611bee57611bee61205d565b604051908082528060200260200182016040528015611c17578160200160208202803683370190505b50915060008060005b600284015461ffff16821015611d98576000818152600185016020526040812054905b6008811015611d835783611c568161235f565b600288015490955061ffff1685119050611d8357600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020889052604081205460601c90805b88811015611d19578a8181518110611cc457611cc461208c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611d075760019150611d19565b80611d118161235f565b915050611caa565b508015611d2857505050611d71565b818a8981518110611d3b57611d3b61208c565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015287611d6a8161235f565b9850505050505b80611d7b8161235f565b915050611c43565b50508080611d909061235f565b915050611c20565b505082525090565b8151600090815b81811015611e1e57837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916858281518110611de157611de161208c565b60200260200101517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603611e165791506101979050565b600101611da7565b509392505050565b73ffffffffffffffffffffffffffffffffffffffff81168114611e4857600080fd5b50565b600060208284031215611e5d57600080fd5b813561163081611e26565b6020808252825182820181905260009190848201906040850190845b81811015611ec25783517fffffffff000000000000000000000000000000000000000000000000000000001683529284019291840191600101611e84565b50909695505050505050565b7fffffffff0000000000000000000000000000000000000000000000000000000081168114611e4857600080fd5b600060208284031215611f0e57600080fd5b813561163081611ece565b6020808252825182820181905260009190848201906040850190845b81811015611ec257835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101611f35565b60006020808301818452808551808352604092508286019150828160051b8701018488016000805b8481101561204e578984037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00186528251805173ffffffffffffffffffffffffffffffffffffffff168552880151888501889052805188860181905290890190839060608701905b808310156120395783517fffffffff00000000000000000000000000000000000000000000000000000000168252928b019260019290920191908b0190611ff7565b50978a01979550505091870191600101611f8f565b50919998505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6040805190810167ffffffffffffffff811182821017156120de576120de61205d565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561212b5761212b61205d565b604052919050565b600067ffffffffffffffff82111561214d5761214d61205d565b5060051b60200190565b6000602080838503121561216a57600080fd5b825167ffffffffffffffff8082111561218257600080fd5b818501915085601f83011261219657600080fd5b81516121a96121a482612133565b6120e4565b81815260059190911b830184019084810190888311156121c857600080fd5b8585015b838110156122c8578051858111156121e45760008081fd5b86016040818c037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00181131561221a5760008081fd5b6122226120bb565b8983015161222f81611e26565b815282820151888111156122435760008081fd5b8084019350508c603f8401126122595760008081fd5b898301516122696121a482612133565b81815260059190911b84018301908b8101908f8311156122895760008081fd5b948401945b828610156122b357855194506122a385611ece565b848252948c0194908c019061228e565b838d01525050855250509186019186016121cc565b5098975050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610197576101976122d5565b81810381811115610197576101976122d5565b600081612339576123396122d5565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612390576123906122d5565b5060010190565b6000602082840312156123a957600080fd5b815161163081611e26565b600061ffff8083168181036123cb576123cb6122d5565b600101939250505056fea26469706673582212205959d8d85aad6f29d5fc37d5a52c404c25392cec49195c3b761da0e863e99b0f64736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "DiamondLoupe contract compatible with EIP-2535", + "kind": "dev", + "methods": { + "facetAddress(bytes4)": { + "details": "If facet is not found return address(0).", + "params": { + "_functionSelector": "The function selector." + }, + "returns": { + "facetAddress_": "The facet address." + } + }, + "facetAddressFromStorage(bytes4)": { + "params": { + "_functionSelector": "Function selector to fetch the facet address from diamond storage" + }, + "returns": { + "facetAddress_": "Facet address mapped with the function selector" + } + }, + "facetAddresses()": { + "returns": { + "facetAddresses_": "facetAddresses_" + } + }, + "facetAddressesFromStorage()": { + "returns": { + "facetAddresses_": "All facet addresses attached directly to diamond storage" + } + }, + "facetFunctionSelectors(address)": { + "params": { + "_facet": "The facet address." + }, + "returns": { + "facetFunctionSelectors_": "facetFunctionSelectors_" + } + }, + "facetFunctionSelectorsFromStorage(address)": { + "params": { + "_facet": "Facet address to fetch the facet function selectors from diamond storage" + }, + "returns": { + "facetFunctionSelectors_": "Facet function selectors of the given facet address" + } + }, + "facets()": { + "details": "Barz uses a special architecture called default fallback handler. Default Fallback handler is used as a middleware that holds the mapping of facet function selector and facet address that Barz uses. This helps Barz to reduce significant amount of gas during the initialization process. Hence, this method aggregates both the facet information from DefaulFallbackHandler and in diamond storage and shows the data to users.", + "returns": { + "facets_": "Facet" + } + }, + "facetsFromStorage()": { + "returns": { + "facets_": "Facet information attached directly to diamond storage" + } + }, + "supportsInterface(bytes4)": { + "params": { + "_interfaceId": "Interface ID for detecting the interface" + }, + "returns": { + "isSupported": "Bool value showing if the standard is supported in the contract" + } + } + }, + "title": "DiamondLoupe Facet", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "facetAddress(bytes4)": { + "notice": "Gets the facet that supports the given selector." + }, + "facetAddressFromStorage(bytes4)": { + "notice": "Returns the facet address attached to the given function selector. This excludes the facets from the default fallback handler" + }, + "facetAddresses()": { + "notice": "Get all the facet addresses used by Barz." + }, + "facetAddressesFromStorage()": { + "notice": "Returns all facet addresses attached directly to diamond storage. This excludes the facets from the default fallback handler" + }, + "facetFunctionSelectors(address)": { + "notice": "Gets all the function selectors provided by a facet." + }, + "facetFunctionSelectorsFromStorage(address)": { + "notice": "Returns function selectors of given facet address attached directly to diamond storage. This excludes the facets from the default fallback handler" + }, + "facets()": { + "notice": "Gets all facets and their selectors." + }, + "facetsFromStorage()": { + "notice": "Returns the facet from the diamond storage. This excludes the facets from the default fallback handler" + }, + "supportsInterface(bytes4)": { + "notice": "SupportInterface to be compatible with EIP 165" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/optimism/Secp256r1VerificationFacet.json b/deployments/optimism/Secp256r1VerificationFacet.json new file mode 100644 index 0000000..d74f765 --- /dev/null +++ b/deployments/optimism/Secp256r1VerificationFacet.json @@ -0,0 +1,483 @@ +{ + "address": "0xeE1AF8E967eC04C84711842796A5E714D2FD33e6", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "LibAppStorage__AccountMustBeUninitialized", + "type": "error" + }, + { + "inputs": [], + "name": "LibAppStorage__SignerAlreadyUninitialized", + "type": "error" + }, + { + "inputs": [], + "name": "LibAppStorage__SignerMustBeUninitialized", + "type": "error" + }, + { + "inputs": [], + "name": "Secp256r1VerificationFacet__InvalidSignerLength", + "type": "error" + }, + { + "inputs": [], + "name": "VerificationFacet__InitializationFailure", + "type": "error" + }, + { + "inputs": [], + "name": "VerificationFacet__InvalidFacetMapping", + "type": "error" + }, + { + "inputs": [], + "name": "VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet", + "type": "error" + }, + { + "inputs": [], + "name": "VerificationFacet__ValidateOwnerSignatureSelectorNotSet", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "SignerInitialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "SignerUninitialized", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_publicKey", + "type": "bytes" + } + ], + "name": "initializeSigner", + "outputs": [ + { + "internalType": "uint256", + "name": "initSuccess", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_publicKey", + "type": "bytes" + } + ], + "name": "isValidKeyType", + "outputs": [ + { + "internalType": "bool", + "name": "isValid", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_hash", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "_signature", + "type": "bytes" + } + ], + "name": "isValidSignature", + "outputs": [ + { + "internalType": "bytes4", + "name": "magicValue", + "type": "bytes4" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "bytes", + "name": "signer", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "self", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "uninitializeSigner", + "outputs": [ + { + "internalType": "uint256", + "name": "uninitSuccess", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "initCode", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "callGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "verificationGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "preVerificationGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxFeePerGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPriorityFeePerGas", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "paymasterAndData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "internalType": "struct UserOperation", + "name": "userOp", + "type": "tuple" + }, + { + "internalType": "bytes32", + "name": "userOpHash", + "type": "bytes32" + } + ], + "name": "validateOwnerSignature", + "outputs": [ + { + "internalType": "uint256", + "name": "validationData", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "validateOwnerSignatureSelector", + "outputs": [ + { + "internalType": "bytes4", + "name": "ownerSignatureValidatorSelector", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "initCode", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "callGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "verificationGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "preVerificationGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxFeePerGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPriorityFeePerGas", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "paymasterAndData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "internalType": "struct UserOperation", + "name": "userOp", + "type": "tuple" + }, + { + "internalType": "bytes32", + "name": "userOpHash", + "type": "bytes32" + }, + { + "internalType": "uint256[2]", + "name": "q", + "type": "uint256[2]" + } + ], + "name": "validateSignature", + "outputs": [ + { + "internalType": "uint256", + "name": "isValid", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0xb23108f3cc5c930a056a1d5d11e764a546b00dd4b22adc9a3cdf3215eb635526", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 15, + "gasUsed": "1809225", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x7fb69d8fc6624e1f2a017bd96806a6983a6d43a27f4412566cb42ad9b48aa371", + "transactionHash": "0xb23108f3cc5c930a056a1d5d11e764a546b00dd4b22adc9a3cdf3215eb635526", + "logs": [], + "blockNumber": 112443517, + "cumulativeGasUsed": "3047967", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 3, + "solcInputHash": "4356503edd8ae34e73cb6dd1c8e2fc8a", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"LibAppStorage__AccountMustBeUninitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LibAppStorage__SignerAlreadyUninitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LibAppStorage__SignerMustBeUninitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Secp256r1VerificationFacet__InvalidSignerLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerificationFacet__InitializationFailure\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerificationFacet__InvalidFacetMapping\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerificationFacet__ValidateOwnerSignatureSelectorNotSet\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"SignerInitialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"SignerUninitialized\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_publicKey\",\"type\":\"bytes\"}],\"name\":\"initializeSigner\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"initSuccess\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_publicKey\",\"type\":\"bytes\"}],\"name\":\"isValidKeyType\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isValid\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_hash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"_signature\",\"type\":\"bytes\"}],\"name\":\"isValidSignature\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"magicValue\",\"type\":\"bytes4\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"signer\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"self\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"uninitializeSigner\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"uninitSuccess\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"userOp\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"}],\"name\":\"validateOwnerSignature\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"validationData\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"validateOwnerSignatureSelector\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"ownerSignatureValidatorSelector\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"userOp\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256[2]\",\"name\":\"q\",\"type\":\"uint256[2]\"}],\"name\":\"validateSignature\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"isValid\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Ruslan Serebriakov (@rsrbk)David Yongjun Kim (@Powerstream3604)\",\"details\":\"Primarily used to verify user ops signed with passkeys\",\"kind\":\"dev\",\"methods\":{\"initializeSigner(bytes)\":{\"details\":\"This method checks if the signer has already been initialized. If already initialized, it reverts. It checks if the public key is in the light format and initializes signer storage in k1 storage.\",\"params\":{\"_publicKey\":\"Bytes of owner public key\"},\"returns\":{\"initSuccess\":\"Uint value representing the success of init operation\"}},\"isValidKeyType(bytes)\":{\"details\":\"For this Secp256k1Verification Facet, the public key should in an uncompressed public key format\",\"params\":{\"_publicKey\":\"Bytes of public key for format check\"},\"returns\":{\"isValid\":\"Boolean variable representing if the format of public key is valid\"}},\"isValidSignature(bytes32,bytes)\":{\"details\":\"This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\",\"params\":{\"_hash\":\"Hash value the owner signed\",\"_signature\":\"Signature that signed the above hash\"},\"returns\":{\"magicValue\":\"Bytes4 value representing the success/failure of validation\"}},\"owner()\":{\"returns\":{\"signer\":\"Bytes of owner address\"}},\"uninitializeSigner()\":{\"details\":\"This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\",\"returns\":{\"uninitSuccess\":\"Uint value representing the success of uninit operation\"}},\"validateOwnerSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32)\":{\"details\":\"This method validates if the user operation is signed by the owner. It internally calls validateSignature with signer public key.\",\"params\":{\"userOp\":\"UserOperation including all information for execution\",\"userOpHash\":\"Hash of UserOperation given from EntryPoint. This hash is used for signature validation\"},\"returns\":{\"validationData\":\"Uint value representing whether the validation is successful. 0 for success, 1 for failure\"}},\"validateOwnerSignatureSelector()\":{\"returns\":{\"ownerSignatureValidatorSelector\":\"Bytes4 selector of function signature to validate account owner's UserOperation signature\"}},\"validateSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256[2])\":{\"details\":\"This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\",\"params\":{\"q\":\"Public Key of signer who signed the contract, to be validated\",\"userOp\":\"UserOperation including all information for execution\",\"userOpHash\":\"Hash of UserOperation given from EntryPoint. This hash is used for signature validation\"},\"returns\":{\"isValid\":\"Uint value representing whether the validation is successful. 0 for success, 1 for failure\"}}},\"title\":\"Secp256r1 verification facet\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"This constructor ensures that this contract can only be used as singleton for Proxy contracts\"},\"initializeSigner(bytes)\":{\"notice\":\"Initializes the signer in R1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\"},\"isValidKeyType(bytes)\":{\"notice\":\"Validates if the format of public key is valid for this verification facet\"},\"isValidSignature(bytes32,bytes)\":{\"notice\":\"Validates if the signature is valid. Function to be compatible with EIP-1271\"},\"owner()\":{\"notice\":\"Returns the owner of the account\"},\"uninitializeSigner()\":{\"notice\":\"Uninitialize signer in R1 Facet Storage. This can only be called when the account is undergoing signature migration and has already been initialized.\"},\"validateOwnerSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32)\":{\"notice\":\"Validates if the user operation is signed by the owner.\"},\"validateOwnerSignatureSelector()\":{\"notice\":\"Returns the selector of function to validate the signature of UserOperation\"},\"validateSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256[2])\":{\"notice\":\"Validates if the signature of UserOperation is signed by the given signer\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/verification/secp256r1/Secp256r1VerificationFacet.sol\":\"Secp256r1VerificationFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/utils/math/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\\n * checks.\\n *\\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\\n * easily result in undesired exploitation or bugs, since developers usually\\n * assume that overflows raise errors. `SafeCast` restores this intuition by\\n * reverting the transaction when such an operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n *\\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\\n * all math on `uint256` and `int256` and then downcasting.\\n */\\nlibrary SafeCast {\\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 * _Available since v4.7._\\n */\\n function toUint248(uint256 value) internal pure returns (uint248) {\\n require(value <= type(uint248).max, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint240(uint256 value) internal pure returns (uint240) {\\n require(value <= type(uint240).max, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint232(uint256 value) internal pure returns (uint232) {\\n require(value <= type(uint232).max, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint224(uint256 value) internal pure returns (uint224) {\\n require(value <= type(uint224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint216(uint256 value) internal pure returns (uint216) {\\n require(value <= type(uint216).max, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint208(uint256 value) internal pure returns (uint208) {\\n require(value <= type(uint208).max, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint200(uint256 value) internal pure returns (uint200) {\\n require(value <= type(uint200).max, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint192(uint256 value) internal pure returns (uint192) {\\n require(value <= type(uint192).max, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint184(uint256 value) internal pure returns (uint184) {\\n require(value <= type(uint184).max, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint176(uint256 value) internal pure returns (uint176) {\\n require(value <= type(uint176).max, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint168(uint256 value) internal pure returns (uint168) {\\n require(value <= type(uint168).max, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint160(uint256 value) internal pure returns (uint160) {\\n require(value <= type(uint160).max, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint152(uint256 value) internal pure returns (uint152) {\\n require(value <= type(uint152).max, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint144(uint256 value) internal pure returns (uint144) {\\n require(value <= type(uint144).max, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint136(uint256 value) internal pure returns (uint136) {\\n require(value <= type(uint136).max, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint128(uint256 value) internal pure returns (uint128) {\\n require(value <= type(uint128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint120(uint256 value) internal pure returns (uint120) {\\n require(value <= type(uint120).max, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint112(uint256 value) internal pure returns (uint112) {\\n require(value <= type(uint112).max, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint104(uint256 value) internal pure returns (uint104) {\\n require(value <= type(uint104).max, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint96(uint256 value) internal pure returns (uint96) {\\n require(value <= type(uint96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint88(uint256 value) internal pure returns (uint88) {\\n require(value <= type(uint88).max, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint80(uint256 value) internal pure returns (uint80) {\\n require(value <= type(uint80).max, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint72(uint256 value) internal pure returns (uint72) {\\n require(value <= type(uint72).max, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint64(uint256 value) internal pure returns (uint64) {\\n require(value <= type(uint64).max, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint56(uint256 value) internal pure returns (uint56) {\\n require(value <= type(uint56).max, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint48(uint256 value) internal pure returns (uint48) {\\n require(value <= type(uint48).max, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint40(uint256 value) internal pure returns (uint40) {\\n require(value <= type(uint40).max, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint32(uint256 value) internal pure returns (uint32) {\\n require(value <= type(uint32).max, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint24(uint256 value) internal pure returns (uint24) {\\n require(value <= type(uint24).max, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint16(uint256 value) internal pure returns (uint16) {\\n require(value <= type(uint16).max, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint8(uint256 value) internal pure returns (uint8) {\\n require(value <= type(uint8).max, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\n */\\n function toUint256(int256 value) internal pure returns (uint256) {\\n require(value >= 0, \\\"SafeCast: value must be positive\\\");\\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 * _Available since v4.7._\\n */\\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\\n downcasted = int248(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\\n downcasted = int240(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\\n downcasted = int232(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\\n downcasted = int224(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\\n downcasted = int216(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\\n downcasted = int208(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\\n downcasted = int200(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\\n downcasted = int192(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\\n downcasted = int184(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\\n downcasted = int176(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\\n downcasted = int168(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\\n downcasted = int160(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\\n downcasted = int152(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\\n downcasted = int144(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\\n downcasted = int136(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\\n downcasted = int128(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\\n downcasted = int120(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\\n downcasted = int112(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\\n downcasted = int104(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\\n downcasted = int96(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\\n downcasted = int88(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\\n downcasted = int80(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\\n downcasted = int72(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\\n downcasted = int64(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\\n downcasted = int56(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\\n downcasted = int48(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\\n downcasted = int40(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\\n downcasted = int32(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\\n downcasted = int24(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\\n downcasted = int16(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\\n downcasted = int8(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\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 require(value <= uint256(type(int256).max), \\\"SafeCast: value doesn't fit in an int256\\\");\\n return int256(value);\\n }\\n}\\n\",\"keccak256\":\"0x52a8cfb0f5239d11b457dcdd1b326992ef672714ca8da71a157255bddd13f3ad\",\"license\":\"MIT\"},\"contracts/aa-4337/core/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable no-inline-assembly */\\n\\n/**\\n * returned data from validateUserOp.\\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\\n * @param aggregator - address(0) - the account validated the signature by itself.\\n * address(1) - the account failed to validate the signature.\\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\\n * @param validAfter - this UserOp is valid only after this timestamp.\\n * @param validaUntil - this UserOp is valid only up to this timestamp.\\n */\\nstruct ValidationData {\\n address aggregator;\\n uint48 validAfter;\\n uint48 validUntil;\\n}\\n\\n//extract sigFailed, validAfter, validUntil.\\n// also convert zero validUntil to type(uint48).max\\nfunction _parseValidationData(\\n uint validationData\\n) pure returns (ValidationData memory data) {\\n address aggregator = address(uint160(validationData));\\n uint48 validUntil = uint48(validationData >> 160);\\n if (validUntil == 0) {\\n validUntil = type(uint48).max;\\n }\\n uint48 validAfter = uint48(validationData >> (48 + 160));\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n// intersect account and paymaster ranges.\\nfunction _intersectTimeRange(\\n uint256 validationData,\\n uint256 paymasterValidationData\\n) pure returns (ValidationData memory) {\\n ValidationData memory accountValidationData = _parseValidationData(\\n validationData\\n );\\n ValidationData memory pmValidationData = _parseValidationData(\\n paymasterValidationData\\n );\\n address aggregator = accountValidationData.aggregator;\\n if (aggregator == address(0)) {\\n aggregator = pmValidationData.aggregator;\\n }\\n uint48 validAfter = accountValidationData.validAfter;\\n uint48 validUntil = accountValidationData.validUntil;\\n uint48 pmValidAfter = pmValidationData.validAfter;\\n uint48 pmValidUntil = pmValidationData.validUntil;\\n\\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp\\n * @param data - the ValidationData to pack\\n */\\nfunction _packValidationData(\\n ValidationData memory data\\n) pure returns (uint256) {\\n return\\n uint160(data.aggregator) |\\n (uint256(data.validUntil) << 160) |\\n (uint256(data.validAfter) << (160 + 48));\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp, when not using an aggregator\\n * @param sigFailed - true for signature failure, false for success\\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\\n * @param validAfter first timestamp this UserOperation is valid\\n */\\nfunction _packValidationData(\\n bool sigFailed,\\n uint48 validUntil,\\n uint48 validAfter\\n) pure returns (uint256) {\\n return\\n (sigFailed ? 1 : 0) |\\n (uint256(validUntil) << 160) |\\n (uint256(validAfter) << (160 + 48));\\n}\\n\\n/**\\n * keccak function over calldata.\\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\\n */\\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\\n assembly {\\n let mem := mload(0x40)\\n let len := data.length\\n calldatacopy(mem, data.offset, len)\\n ret := keccak256(mem, len)\\n }\\n}\\n\",\"keccak256\":\"0xa79f06cd158ecb8c0da95493a2f348933b8627a63e228b99738bff3aa107942d\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAggregator.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\n/**\\n * Aggregated Signatures validator.\\n */\\ninterface IAggregator {\\n /**\\n * validate aggregated signature.\\n * revert if the aggregated signature does not match the given list of operations.\\n */\\n function validateSignatures(\\n UserOperation[] calldata userOps,\\n bytes calldata signature\\n ) external view;\\n\\n /**\\n * validate signature of a single userOp\\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\\n * @param userOp the userOperation received from the user.\\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\\n * (usually empty, unless account and aggregator support some kind of \\\"multisig\\\"\\n */\\n function validateUserOpSignature(\\n UserOperation calldata userOp\\n ) external view returns (bytes memory sigForUserOp);\\n\\n /**\\n * aggregate multiple signatures into a single value.\\n * This method is called off-chain to calculate the signature to pass with handleOps()\\n * bundler MAY use optimized custom code perform this aggregation\\n * @param userOps array of UserOperations to collect the signatures from.\\n * @return aggregatedSignature the aggregated signature\\n */\\n function aggregateSignatures(\\n UserOperation[] calldata userOps\\n ) external view returns (bytes memory aggregatedSignature);\\n}\\n\",\"keccak256\":\"0xdfdcd80568f037716674619b31be630fcd8316262f05a815b41d1e81782c966a\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IEntryPoint.sol\":{\"content\":\"/**\\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\\n ** Only one instance required on each chain.\\n **/\\n// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-inline-assembly */\\n/* solhint-disable reason-string */\\n\\nimport \\\"./UserOperation.sol\\\";\\nimport \\\"./IStakeManager.sol\\\";\\nimport \\\"./IAggregator.sol\\\";\\nimport \\\"./INonceManager.sol\\\";\\n\\ninterface IEntryPoint is IStakeManager, INonceManager {\\n /***\\n * An event emitted after each successful request\\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\\n * @param sender - the account that generates this request.\\n * @param paymaster - if non-null, the paymaster that pays for this request.\\n * @param nonce - the nonce value from the request.\\n * @param success - true if the sender transaction succeeded, false if reverted.\\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\\n */\\n event UserOperationEvent(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address indexed paymaster,\\n uint256 nonce,\\n bool success,\\n uint256 actualGasCost,\\n uint256 actualGasUsed\\n );\\n\\n /**\\n * account \\\"sender\\\" was deployed.\\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\\n * @param sender the account that is deployed\\n * @param factory the factory used to deploy this account (in the initCode)\\n * @param paymaster the paymaster used by this UserOp\\n */\\n event AccountDeployed(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address factory,\\n address paymaster\\n );\\n\\n /**\\n * An event emitted if the UserOperation \\\"callData\\\" reverted with non-zero length\\n * @param userOpHash the request unique identifier.\\n * @param sender the sender of this request\\n * @param nonce the nonce used in the request\\n * @param revertReason - the return bytes from the (reverted) call to \\\"callData\\\".\\n */\\n event UserOperationRevertReason(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n uint256 nonce,\\n bytes revertReason\\n );\\n\\n /**\\n * an event emitted by handleOps(), before starting the execution loop.\\n * any event emitted before this event, is part of the validation.\\n */\\n event BeforeExecution();\\n\\n /**\\n * signature aggregator used by the following UserOperationEvents within this bundle.\\n */\\n event SignatureAggregatorChanged(address indexed aggregator);\\n\\n /**\\n * a custom revert error of handleOps, to identify the offending op.\\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\\n * @param reason - revert reason\\n * The string starts with a unique code \\\"AAmn\\\", where \\\"m\\\" is \\\"1\\\" for factory, \\\"2\\\" for account and \\\"3\\\" for paymaster issues,\\n * so a failure can be attributed to the correct entity.\\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\\n */\\n error FailedOp(uint256 opIndex, string reason);\\n\\n /**\\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\\n */\\n error SignatureValidationFailed(address aggregator);\\n\\n /**\\n * Successful result from simulateValidation.\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n */\\n error ValidationResult(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo\\n );\\n\\n /**\\n * Successful result from simulateValidation, if the account returns a signature aggregator\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\\n * bundler MUST use it to verify the signature, or reject the UserOperation\\n */\\n error ValidationResultWithAggregation(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo,\\n AggregatorStakeInfo aggregatorInfo\\n );\\n\\n /**\\n * return value of getSenderAddress\\n */\\n error SenderAddressResult(address sender);\\n\\n /**\\n * return value of simulateHandleOp\\n */\\n error ExecutionResult(\\n uint256 preOpGas,\\n uint256 paid,\\n uint48 validAfter,\\n uint48 validUntil,\\n bool targetSuccess,\\n bytes targetResult\\n );\\n\\n //UserOps handled, per aggregator\\n struct UserOpsPerAggregator {\\n UserOperation[] userOps;\\n // aggregator address\\n IAggregator aggregator;\\n // aggregated signature\\n bytes signature;\\n }\\n\\n /**\\n * Execute a batch of UserOperation.\\n * no signature aggregator is used.\\n * if any account requires an aggregator (that is, it returned an aggregator when\\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\\n * @param ops the operations to execute\\n * @param beneficiary the address to receive the fees\\n */\\n function handleOps(\\n UserOperation[] calldata ops,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * Execute a batch of UserOperation with Aggregators\\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\\n * @param beneficiary the address to receive the fees\\n */\\n function handleAggregatedOps(\\n UserOpsPerAggregator[] calldata opsPerAggregator,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * generate a request Id - unique identifier for this request.\\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\\n */\\n function getUserOpHash(\\n UserOperation calldata userOp\\n ) external view returns (bytes32);\\n\\n /**\\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\\n * @param userOp the user operation to validate.\\n */\\n function simulateValidation(UserOperation calldata userOp) external;\\n\\n /**\\n * gas and return values during simulation\\n * @param preOpGas the gas used for validation (including preValidationGas)\\n * @param prefund the required prefund for this operation\\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\\n */\\n struct ReturnInfo {\\n uint256 preOpGas;\\n uint256 prefund;\\n bool sigFailed;\\n uint48 validAfter;\\n uint48 validUntil;\\n bytes paymasterContext;\\n }\\n\\n /**\\n * returned aggregated signature info.\\n * the aggregator returned by the account, and its current stake.\\n */\\n struct AggregatorStakeInfo {\\n address aggregator;\\n StakeInfo stakeInfo;\\n }\\n\\n /**\\n * Get counterfactual sender address.\\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\\n * this method always revert, and returns the address in SenderAddressResult error\\n * @param initCode the constructor code to be passed into the UserOperation.\\n */\\n function getSenderAddress(bytes memory initCode) external;\\n\\n /**\\n * simulate full execution of a UserOperation (including both validation and target execution)\\n * this method will always revert with \\\"ExecutionResult\\\".\\n * it performs full validation of the UserOperation, but ignores signature error.\\n * an optional target address is called after the userop succeeds, and its value is returned\\n * (before the entire call is reverted)\\n * Note that in order to collect the the success/failure of the target call, it must be executed\\n * with trace enabled to track the emitted events.\\n * @param op the UserOperation to simulate\\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\\n * are set to the return from that call.\\n * @param targetCallData callData to pass to target address\\n */\\n function simulateHandleOp(\\n UserOperation calldata op,\\n address target,\\n bytes calldata targetCallData\\n ) external;\\n}\\n\",\"keccak256\":\"0x9ccb1b188eda8bbf5f6c2d01bd83c3d8b2b04fcf745283051d31fe96d1d8e40f\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/INonceManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\ninterface INonceManager {\\n /**\\n * Return the next nonce for this sender.\\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\\n * But UserOp with different keys can come with arbitrary order.\\n *\\n * @param sender the account address\\n * @param key the high 192 bit of the nonce\\n * @return nonce a full nonce to pass for next UserOp with this sender.\\n */\\n function getNonce(\\n address sender,\\n uint192 key\\n ) external view returns (uint256 nonce);\\n\\n /**\\n * Manually increment the nonce of the sender.\\n * This method is exposed just for completeness..\\n * Account does NOT need to call it, neither during validation, nor elsewhere,\\n * as the EntryPoint will update the nonce regardless.\\n * Possible use-case is call it with various keys to \\\"initialize\\\" their nonces to one, so that future\\n * UserOperations will not pay extra for the first transaction with a given key.\\n */\\n function incrementNonce(uint192 key) external;\\n}\\n\",\"keccak256\":\"0xce478ad0fa0d18a3b785ac854623029e7ab463d05873dfaa365abfa1bf100912\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IStakeManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8.12;\\n\\n/**\\n * manage deposits and stakes.\\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\\n * stake is value locked for at least \\\"unstakeDelay\\\" by the staked entity.\\n */\\ninterface IStakeManager {\\n event Deposited(address indexed account, uint256 totalDeposit);\\n\\n event Withdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /// Emitted when stake or unstake delay are modified\\n event StakeLocked(\\n address indexed account,\\n uint256 totalStaked,\\n uint256 unstakeDelaySec\\n );\\n\\n /// Emitted once a stake is scheduled for withdrawal\\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\\n\\n event StakeWithdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /**\\n * @param deposit the entity's deposit\\n * @param staked true if this entity is staked.\\n * @param stake actual amount of ether staked for this entity.\\n * @param unstakeDelaySec minimum delay to withdraw the stake.\\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\\n * and the rest fit into a 2nd cell.\\n * 112 bit allows for 10^15 eth\\n * 48 bit for full timestamp\\n * 32 bit allows 150 years for unstake delay\\n */\\n struct DepositInfo {\\n uint112 deposit;\\n bool staked;\\n uint112 stake;\\n uint32 unstakeDelaySec;\\n uint48 withdrawTime;\\n }\\n\\n //API struct used by getStakeInfo and simulateValidation\\n struct StakeInfo {\\n uint256 stake;\\n uint256 unstakeDelaySec;\\n }\\n\\n /// @return info - full deposit information of given account\\n function getDepositInfo(\\n address account\\n ) external view returns (DepositInfo memory info);\\n\\n /// @return the deposit (for gas payment) of the account\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * add to the deposit of the given account\\n */\\n function depositTo(address account) external payable;\\n\\n /**\\n * add to the account's stake - amount and delay\\n * any pending unstake is first cancelled.\\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\\n */\\n function addStake(uint32 _unstakeDelaySec) external payable;\\n\\n /**\\n * attempt to unlock the stake.\\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\\n */\\n function unlockStake() external;\\n\\n /**\\n * withdraw from the (unlocked) stake.\\n * must first call unlockStake and wait for the unstakeDelay to pass\\n * @param withdrawAddress the address to send withdrawn value.\\n */\\n function withdrawStake(address payable withdrawAddress) external;\\n\\n /**\\n * withdraw from the deposit.\\n * @param withdrawAddress the address to send withdrawn value.\\n * @param withdrawAmount the amount to withdraw.\\n */\\n function withdrawTo(\\n address payable withdrawAddress,\\n uint256 withdrawAmount\\n ) external;\\n}\\n\",\"keccak256\":\"0xadcea606c9b7aafe6645441f2154a60f271330b0eee5292a632aa71c1672d546\",\"license\":\"GPL-3.0-only\"},\"contracts/aa-4337/interfaces/UserOperation.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable no-inline-assembly */\\n\\nimport {calldataKeccak} from \\\"../core/Helpers.sol\\\";\\n\\n/**\\n * User Operation struct\\n * @param sender the sender account of this request.\\n * @param nonce unique value the sender uses to verify it is not a replay.\\n * @param initCode if set, the account contract will be created by this constructor/\\n * @param callData the method call to execute on this account.\\n * @param callGasLimit the gas limit passed to the callData method call.\\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\\n * @param maxFeePerGas same as EIP-1559 gas parameter.\\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\\n */\\nstruct UserOperation {\\n address sender;\\n uint256 nonce;\\n bytes initCode;\\n bytes callData;\\n uint256 callGasLimit;\\n uint256 verificationGasLimit;\\n uint256 preVerificationGas;\\n uint256 maxFeePerGas;\\n uint256 maxPriorityFeePerGas;\\n bytes paymasterAndData;\\n bytes signature;\\n}\\n\\n/**\\n * Utility functions helpful when working with UserOperation structs.\\n */\\nlibrary UserOperationLib {\\n function getSender(\\n UserOperation calldata userOp\\n ) internal pure returns (address) {\\n address data;\\n //read sender from userOp, which is first userOp member (saves 800 gas...)\\n assembly {\\n data := calldataload(userOp)\\n }\\n return address(uint160(data));\\n }\\n\\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\\n // pay above what he signed for.\\n function gasPrice(\\n UserOperation calldata userOp\\n ) internal view returns (uint256) {\\n unchecked {\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n if (maxFeePerGas == maxPriorityFeePerGas) {\\n //legacy mode (for networks that don't support basefee opcode)\\n return maxFeePerGas;\\n }\\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\\n }\\n }\\n\\n function pack(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes memory ret) {\\n address sender = getSender(userOp);\\n uint256 nonce = userOp.nonce;\\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\\n bytes32 hashCallData = calldataKeccak(userOp.callData);\\n uint256 callGasLimit = userOp.callGasLimit;\\n uint256 verificationGasLimit = userOp.verificationGasLimit;\\n uint256 preVerificationGas = userOp.preVerificationGas;\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\\n\\n return\\n abi.encode(\\n sender,\\n nonce,\\n hashInitCode,\\n hashCallData,\\n callGasLimit,\\n verificationGasLimit,\\n preVerificationGas,\\n maxFeePerGas,\\n maxPriorityFeePerGas,\\n hashPaymasterAndData\\n );\\n }\\n\\n function hash(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes32) {\\n return keccak256(pack(userOp));\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n}\\n\",\"keccak256\":\"0x2429f5cc546bdee08c7e63858d0dda8491eaa3ab5194df884dc948c1154d2834\",\"license\":\"GPL-3.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/facets/interfaces/IVerificationFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {UserOperation} from \\\"../../aa-4337/interfaces/UserOperation.sol\\\";\\n\\n/**\\n * @title Verification Facet Interface\\n * @dev Implements logic for user ops signature verification\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\ninterface IVerificationFacet {\\n event SignerInitialized(bytes);\\n event SignerUninitialized();\\n\\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\\n error VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\\n error VerificationFacet__InitializationFailure();\\n error VerificationFacet__InvalidFacetMapping();\\n\\n function initializeSigner(bytes memory) external returns (uint256);\\n\\n function uninitializeSigner() external returns (uint256);\\n\\n function validateOwnerSignatureSelector() external view returns (bytes4);\\n\\n function owner() external view returns (bytes memory);\\n\\n function isValidKeyType(bytes calldata) external view returns (bool);\\n\\n function validateOwnerSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x72bc370a1d1b5a6d6bde67f5026733fd8f6ba434bb90e73b0bd8627fb1579928\",\"license\":\"Apache-2.0\"},\"contracts/facets/verification/secp256r1/Secp256r1VerificationFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {UserOperation} from \\\"../../../aa-4337/interfaces/UserOperation.sol\\\";\\nimport {LibAppStorage} from \\\"../../../libraries/LibAppStorage.sol\\\";\\nimport {LibLoupe} from \\\"../../../libraries/LibLoupe.sol\\\";\\nimport {LibFacetStorage, Secp256r1VerificationStorage} from \\\"../../../libraries/LibFacetStorage.sol\\\";\\nimport {Base64} from \\\"./utils/Base64.sol\\\";\\nimport {LibSecp256r1} from \\\"./utils/LibSecp256r1.sol\\\";\\nimport {IERC1271} from \\\"../../../interfaces/ERC/IERC1271.sol\\\";\\nimport {IVerificationFacet} from \\\"../../interfaces/IVerificationFacet.sol\\\";\\n\\n/**\\n * @title Secp256r1 verification facet\\n * @dev Primarily used to verify user ops signed with passkeys\\n * @author Ruslan Serebriakov (@rsrbk)\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract Secp256r1VerificationFacet is IVerificationFacet, IERC1271 {\\n error Secp256r1VerificationFacet__InvalidSignerLength();\\n address public immutable self;\\n\\n /**\\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\\n */\\n constructor() {\\n LibAppStorage.enforceSignerInitialize();\\n self = address(this);\\n }\\n\\n /**\\n * @notice Initializes the signer in R1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\\n * @param _publicKey Bytes of owner public key\\n * @return initSuccess Uint value representing the success of init operation\\n */\\n function initializeSigner(\\n bytes calldata _publicKey\\n ) public override returns (uint256 initSuccess) {\\n LibAppStorage.enforceSignerInitialize();\\n\\n if (!isValidKeyType(_publicKey))\\n revert Secp256r1VerificationFacet__InvalidSignerLength();\\n\\n bytes memory publicKeyCoordinates = _publicKey[1:];\\n uint256[2] memory q;\\n assembly {\\n // Copy the bytes from the input data into the uint256 array\\n mstore(q, mload(add(publicKeyCoordinates, 32)))\\n mstore(add(q, 32), mload(add(publicKeyCoordinates, 64)))\\n }\\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\\n .r1Storage();\\n r1Storage.q = q;\\n\\n bytes4 validateSelector = validateOwnerSignatureSelector();\\n\\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\\n if (LibLoupe.facetAddress(validateSelector) != self)\\n revert VerificationFacet__InvalidFacetMapping();\\n\\n // initialize verification function selector\\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\\n\\n initSuccess = 1;\\n\\n emit SignerInitialized(_publicKey);\\n }\\n\\n /**\\n * @notice Uninitialize signer in R1 Facet Storage. This can only be called when the account is undergoing signature migration\\n * and has already been initialized.\\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\\n * @return uninitSuccess Uint value representing the success of uninit operation\\n */\\n function uninitializeSigner()\\n external\\n override\\n returns (uint256 uninitSuccess)\\n {\\n LibAppStorage.enforceSignerMigration();\\n LibAppStorage.setSignerUninitialized();\\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\\n .r1Storage();\\n r1Storage.q = [0, 0];\\n\\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\\n\\n uninitSuccess = 1;\\n\\n emit SignerUninitialized();\\n }\\n\\n /**\\n * @notice Validates if the user operation is signed by the owner.\\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\\n * signer public key.\\n * @param userOp UserOperation including all information for execution\\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\\n */\\n function validateOwnerSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) public view override returns (uint256 validationData) {\\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\\n .r1Storage();\\n validationData = validateSignature(userOp, userOpHash, r1Storage.q);\\n }\\n\\n /**\\n * @notice Validates if the signature of UserOperation is signed by the given signer\\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\\n * @param userOp UserOperation including all information for execution\\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\\n * @param q Public Key of signer who signed the contract, to be validated\\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\\n */\\n function validateSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n uint256[2] memory q\\n ) public view returns (uint256 isValid) {\\n isValid = (_validateSignature(q, userOpHash, userOp.signature)) ? 0 : 1;\\n }\\n\\n /**\\n * @notice Returns the selector of function to validate the signature of UserOperation\\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\\n */\\n function validateOwnerSignatureSelector()\\n public\\n pure\\n override\\n returns (bytes4 ownerSignatureValidatorSelector)\\n {\\n return this.validateOwnerSignature.selector; // validateOwnerSignature(UserOperation calldata userOp,bytes32 userOpHash)\\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\\n }\\n\\n /**\\n * @notice Returns the owner of the account\\n * @return signer Bytes of owner address\\n */\\n function owner() public view override returns (bytes memory signer) {\\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\\n .r1Storage();\\n signer = abi.encodePacked(r1Storage.q);\\n }\\n\\n /**\\n * @notice Validates if the format of public key is valid for this verification facet\\n * @dev For this Secp256k1Verification Facet, the public key should in an uncompressed public key format\\n * @param _publicKey Bytes of public key for format check\\n * @return isValid Boolean variable representing if the format of public key is valid\\n */\\n function isValidKeyType(\\n bytes memory _publicKey\\n ) public pure override returns (bool isValid) {\\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\\n }\\n\\n /**\\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\\n * @param _hash Hash value the owner signed\\n * @param _signature Signature that signed the above hash\\n * @return magicValue Bytes4 value representing the success/failure of validation\\n */\\n function isValidSignature(\\n bytes32 _hash,\\n bytes memory _signature\\n ) public view override returns (bytes4 magicValue) {\\n magicValue = _validateSignature(\\n LibFacetStorage.r1Storage().q,\\n _hash,\\n _signature\\n )\\n ? this.isValidSignature.selector\\n : bytes4(0xffffffff);\\n }\\n\\n function _validateSignature(\\n uint256[2] memory q,\\n bytes32 _hash,\\n bytes memory _signature\\n ) internal view returns (bool) {\\n (\\n uint256 rValue,\\n uint256 sValue,\\n bytes memory authenticatorData,\\n string memory clientDataJSONPre,\\n string memory clientDataJSONPost\\n ) = abi.decode(_signature, (uint256, uint256, bytes, string, string));\\n bytes32 clientHash;\\n {\\n string memory opHashBase64 = Base64.encode(bytes.concat(_hash));\\n string memory clientDataJSON = string.concat(\\n clientDataJSONPre,\\n opHashBase64,\\n clientDataJSONPost\\n );\\n clientHash = sha256(bytes(clientDataJSON));\\n }\\n bytes32 sigHash = sha256(bytes.concat(authenticatorData, clientHash));\\n return LibSecp256r1.Verify(q, rValue, sValue, uint256(sigHash));\\n }\\n}\\n\",\"keccak256\":\"0xdb3bae77323eef4e16ef5a5342f548527c9e82b44e8e9dab90906dc2c00082ff\",\"license\":\"Apache-2.0\"},\"contracts/facets/verification/secp256r1/utils/Base64.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @dev Provides a set of functions to operate with Base64 strings.\\n * modified for base64url https://datatracker.ietf.org/doc/html/rfc4648#section-5\\n * _Available since v4.5._\\n */\\nlibrary Base64 {\\n /**\\n * @dev Base64 Encoding/Decoding Table\\n */\\n string internal constant _TABLE =\\n \\\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_\\\";\\n\\n /**\\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\\n */\\n function encode(bytes memory data) internal pure returns (string memory) {\\n /**\\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\\n */\\n if (data.length == 0) return \\\"\\\";\\n\\n // Loads the table into memory\\n string memory table = _TABLE;\\n\\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\\n // and split into 4 numbers of 6 bits.\\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\\n // - `data.length + 2` -> Round up\\n // - `/ 3` -> Number of 3-bytes chunks\\n // - `4 *` -> 4 characters for each chunk\\n uint256 newlength = (data.length * 8) / 6;\\n if (data.length % 6 > 0) {\\n newlength++;\\n }\\n string memory result = new string(newlength);\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n // Prepare the lookup table (skip the first \\\"length\\\" byte)\\n let tablePtr := add(table, 1)\\n\\n // Prepare result pointer, jump over length\\n let resultPtr := add(result, 32)\\n\\n // Run over the input, 3 bytes at a time\\n for {\\n let dataPtr := data\\n let endPtr := add(data, mload(data))\\n } lt(dataPtr, endPtr) {\\n\\n } {\\n // Advance 3 bytes\\n dataPtr := add(dataPtr, 3)\\n let input := mload(dataPtr)\\n\\n // To write each character, shift the 3 bytes (18 bits) chunk\\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\\n // and apply logical AND with 0x3F which is the number of\\n // the previous character in the ASCII table prior to the Base64 Table\\n // The result is then added to the table to get the character to write,\\n // and finally write it in the result pointer but with a left shift\\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\\n\\n mstore8(\\n resultPtr,\\n mload(add(tablePtr, and(shr(18, input), 0x3F)))\\n )\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(\\n resultPtr,\\n mload(add(tablePtr, and(shr(12, input), 0x3F)))\\n )\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(\\n resultPtr,\\n mload(add(tablePtr, and(shr(6, input), 0x3F)))\\n )\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n }\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0xbf0afa21e5a128f260c1a8d4333dc0b0e8755a50d37dfa9b5d362d36ef9cdc14\",\"license\":\"Apache-2.0\"},\"contracts/facets/verification/secp256r1/utils/LibSecp256r1.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n// Heavily inspired from\\n// https://github.com/maxrobot/elliptic-solidity/blob/master/contracts/Secp256r1.sol\\n// https://github.com/tdrerup/elliptic-curve-solidity/blob/master/contracts/curves/EllipticCurve.sol\\n// modified to use precompile 0x05 modexp\\n// and modified jacobian double\\n// optimisations to avoid to an from from affine and jacobian coordinates\\n\\n// Additional Elliptic curve Public key / Signature validation added by\\n// David Yonjun Kim (@Powerstream3604)\\n\\nstruct JPoint {\\n uint256 x;\\n uint256 y;\\n uint256 z;\\n}\\n\\nlibrary LibSecp256r1 {\\n uint256 constant gx =\\n 0x6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296;\\n uint256 constant gy =\\n 0x4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5;\\n uint256 public constant pp =\\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF;\\n\\n uint256 public constant nn =\\n 0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551;\\n uint256 constant a =\\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC;\\n uint256 constant b =\\n 0x5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B;\\n uint256 constant MOST_SIGNIFICANT =\\n 0xc000000000000000000000000000000000000000000000000000000000000000;\\n\\n /*\\n * Verify\\n * @description - verifies that a public key has signed a given message\\n * @param Q - public key coordinates X & Y\\n * @param R - signature half R\\n * @param S - signature half S\\n * @param input - hashed message\\n */\\n function Verify(\\n uint256[2] memory q,\\n uint r,\\n uint s,\\n uint e\\n ) internal view returns (bool) {\\n if (q[0] > pp - 1 || q[1] > pp - 1) {\\n return false;\\n }\\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\\n return false;\\n }\\n if (\\n mulmod(q[1], q[1], pp) !=\\n addmod(\\n addmod(\\n mulmod(q[0], mulmod(q[0], q[0], pp), pp),\\n mulmod(a, q[0], pp),\\n pp\\n ),\\n b,\\n pp\\n )\\n ) {\\n return false;\\n }\\n\\n JPoint[16] memory points = _preComputeJacobianPoints(q);\\n return VerifyWithPrecompute(points, r, s, e);\\n }\\n\\n function VerifyWithPrecompute(\\n JPoint[16] memory points,\\n uint r,\\n uint s,\\n uint e\\n ) internal view returns (bool) {\\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\\n return false;\\n }\\n\\n uint w = _primemod(s, nn);\\n\\n uint u1 = mulmod(e, w, nn);\\n uint u2 = mulmod(r, w, nn);\\n\\n uint x;\\n uint y;\\n\\n (x, y) = ShamirMultJacobian(points, u1, u2);\\n return (x == r);\\n }\\n\\n /*\\n * Strauss Shamir trick for EC multiplication\\n * https://stackoverflow.com/questions/50993471/ec-scalar-multiplication-with-strauss-shamir-method\\n * we optimise on this a bit to do with 2 bits at a time rather than a single bit\\n * the individual points for a single pass are precomputed\\n * overall this reduces the number of additions while keeping the same number of doublings\\n */\\n function ShamirMultJacobian(\\n JPoint[16] memory points,\\n uint u1,\\n uint u2\\n ) internal view returns (uint, uint) {\\n uint x = 0;\\n uint y = 0;\\n uint z = 0;\\n uint bits = 128;\\n uint index = 0;\\n\\n while (bits > 0) {\\n if (z > 0) {\\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\\n }\\n index =\\n ((u1 & MOST_SIGNIFICANT) >> 252) |\\n ((u2 & MOST_SIGNIFICANT) >> 254);\\n if (index > 0) {\\n (x, y, z) = _jAdd(\\n x,\\n y,\\n z,\\n points[index].x,\\n points[index].y,\\n points[index].z\\n );\\n }\\n u1 <<= 2;\\n u2 <<= 2;\\n bits--;\\n }\\n (x, y) = _affineFromJacobian(x, y, z);\\n return (x, y);\\n }\\n\\n function _preComputeJacobianPoints(\\n uint256[2] memory q\\n ) internal pure returns (JPoint[16] memory points) {\\n points[0] = JPoint(0, 0, 0);\\n points[1] = JPoint(q[0], q[1], 1); // u2\\n points[2] = _jPointDouble(points[1]);\\n points[3] = _jPointAdd(points[1], points[2]);\\n\\n points[4] = JPoint(gx, gy, 1); // u1Points[1]\\n points[5] = _jPointAdd(points[4], points[1]);\\n points[6] = _jPointAdd(points[4], points[2]);\\n points[7] = _jPointAdd(points[4], points[3]);\\n\\n points[8] = _jPointDouble(points[4]); // u1Points[2]\\n points[9] = _jPointAdd(points[8], points[1]);\\n points[10] = _jPointAdd(points[8], points[2]);\\n points[11] = _jPointAdd(points[8], points[3]);\\n\\n points[12] = _jPointAdd(points[4], points[8]); // u1Points[3]\\n points[13] = _jPointAdd(points[12], points[1]);\\n points[14] = _jPointAdd(points[12], points[2]);\\n points[15] = _jPointAdd(points[12], points[3]);\\n }\\n\\n function _jPointAdd(\\n JPoint memory p1,\\n JPoint memory p2\\n ) internal pure returns (JPoint memory) {\\n uint x;\\n uint y;\\n uint z;\\n (x, y, z) = _jAdd(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z);\\n return JPoint(x, y, z);\\n }\\n\\n function _jPointDouble(\\n JPoint memory p\\n ) internal pure returns (JPoint memory) {\\n uint x;\\n uint y;\\n uint z;\\n (x, y, z) = _modifiedJacobianDouble(p.x, p.y, p.z);\\n return JPoint(x, y, z);\\n }\\n\\n /* _affineFromJacobian\\n * @desription returns affine coordinates from a jacobian input follows\\n * golang elliptic/crypto library\\n */\\n function _affineFromJacobian(\\n uint x,\\n uint y,\\n uint z\\n ) internal view returns (uint ax, uint ay) {\\n if (z == 0) {\\n return (0, 0);\\n }\\n\\n uint zinv = _primemod(z, pp);\\n uint zinvsq = mulmod(zinv, zinv, pp);\\n\\n ax = mulmod(x, zinvsq, pp);\\n ay = mulmod(y, mulmod(zinvsq, zinv, pp), pp);\\n }\\n\\n /*\\n * _jAdd\\n * @description performs Jacobian addition as defined below:\\n * http://www.hyperelliptic.org/EFD/g1p/data/shortw/jacobian/addition/add-2007-bl\\n */\\n function _jAdd(\\n uint p1,\\n uint p2,\\n uint p3,\\n uint q1,\\n uint q2,\\n uint q3\\n ) internal pure returns (uint r1, uint r2, uint r3) {\\n if (p3 == 0) {\\n r1 = q1;\\n r2 = q2;\\n r3 = q3;\\n\\n return (r1, r2, r3);\\n } else if (q3 == 0) {\\n r1 = p1;\\n r2 = p2;\\n r3 = p3;\\n\\n return (r1, r2, r3);\\n }\\n\\n assembly {\\n let\\n pd\\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\\n let z1z1 := mulmod(p3, p3, pd) // Z1Z1 = Z1^2\\n let z2z2 := mulmod(q3, q3, pd) // Z2Z2 = Z2^2\\n\\n let u1 := mulmod(p1, z2z2, pd) // U1 = X1*Z2Z2\\n let u2 := mulmod(q1, z1z1, pd) // U2 = X2*Z1Z1\\n\\n let s1 := mulmod(p2, mulmod(z2z2, q3, pd), pd) // S1 = Y1*Z2*Z2Z2\\n let s2 := mulmod(q2, mulmod(z1z1, p3, pd), pd) // S2 = Y2*Z1*Z1Z1\\n\\n let p3q3 := addmod(p3, q3, pd)\\n\\n if lt(u2, u1) {\\n u2 := add(pd, u2) // u2 = u2+pd\\n }\\n let h := sub(u2, u1) // H = U2-U1\\n\\n let i := mulmod(0x02, h, pd)\\n i := mulmod(i, i, pd) // I = (2*H)^2\\n\\n let j := mulmod(h, i, pd) // J = H*I\\n if lt(s2, s1) {\\n s2 := add(pd, s2) // u2 = u2+pd\\n }\\n let rr := mulmod(0x02, sub(s2, s1), pd) // r = 2*(S2-S1)\\n r1 := mulmod(rr, rr, pd) // X3 = R^2\\n\\n let v := mulmod(u1, i, pd) // V = U1*I\\n let j2v := addmod(j, mulmod(0x02, v, pd), pd)\\n if lt(r1, j2v) {\\n r1 := add(pd, r1) // X3 = X3+pd\\n }\\n r1 := sub(r1, j2v)\\n\\n // Y3 = r*(V-X3)-2*S1*J\\n let s12j := mulmod(mulmod(0x02, s1, pd), j, pd)\\n\\n if lt(v, r1) {\\n v := add(pd, v)\\n }\\n r2 := mulmod(rr, sub(v, r1), pd)\\n\\n if lt(r2, s12j) {\\n r2 := add(pd, r2)\\n }\\n r2 := sub(r2, s12j)\\n\\n // Z3 = ((Z1+Z2)^2-Z1Z1-Z2Z2)*H\\n z1z1 := addmod(z1z1, z2z2, pd)\\n j2v := mulmod(p3q3, p3q3, pd)\\n if lt(j2v, z1z1) {\\n j2v := add(pd, j2v)\\n }\\n r3 := mulmod(sub(j2v, z1z1), h, pd)\\n }\\n return (r1, r2, r3);\\n }\\n\\n // Point doubling on the modified jacobian coordinates\\n // http://point-at-infinity.org/ecc/Prime_Curve_Modified_Jacobian_Coordinates.html\\n function _modifiedJacobianDouble(\\n uint x,\\n uint y,\\n uint z\\n ) internal pure returns (uint x3, uint y3, uint z3) {\\n if (y == 0) return (0, 0, 0);\\n assembly {\\n let\\n pd\\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\\n let z2 := mulmod(z, z, pd)\\n let az4 := mulmod(\\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC,\\n mulmod(z2, z2, pd),\\n pd\\n )\\n let y2 := mulmod(y, y, pd)\\n let s := mulmod(0x04, mulmod(x, y2, pd), pd)\\n let u := mulmod(0x08, mulmod(y2, y2, pd), pd)\\n let m := addmod(mulmod(0x03, mulmod(x, x, pd), pd), az4, pd)\\n let twos := mulmod(0x02, s, pd)\\n let m2 := mulmod(m, m, pd)\\n if lt(m2, twos) {\\n m2 := add(pd, m2)\\n }\\n x3 := sub(m2, twos)\\n if lt(s, x3) {\\n s := add(pd, s)\\n }\\n y3 := mulmod(m, sub(s, x3), pd)\\n if lt(y3, u) {\\n y3 := add(pd, y3)\\n }\\n y3 := sub(y3, u)\\n z3 := mulmod(0x02, mulmod(y, z, pd), pd)\\n }\\n }\\n\\n // Fermats little theorem https://en.wikipedia.org/wiki/Fermat%27s_little_theorem\\n // a^(p-1) = 1 mod p\\n // a^(-1) \\u2245 a^(p-2) (mod p)\\n // we then use the precompile bigModExp to compute a^(-1)\\n function _primemod(uint value, uint p) internal view returns (uint ret) {\\n ret = modexp(value, p - 2, p);\\n return ret;\\n }\\n\\n // Wrapper for built-in BigNumber_modexp (contract 0x5) as described here. https://github.com/ethereum/EIPs/pull/198\\n function modexp(\\n uint _base,\\n uint _exp,\\n uint _mod\\n ) internal view returns (uint ret) {\\n // bigModExp(_base, _exp, _mod);\\n assembly {\\n if gt(_base, _mod) {\\n _base := mod(_base, _mod)\\n }\\n // Free memory pointer is always stored at 0x40\\n let freemem := mload(0x40)\\n\\n mstore(freemem, 0x20)\\n mstore(add(freemem, 0x20), 0x20)\\n mstore(add(freemem, 0x40), 0x20)\\n\\n mstore(add(freemem, 0x60), _base)\\n mstore(add(freemem, 0x80), _exp)\\n mstore(add(freemem, 0xa0), _mod)\\n\\n let success := staticcall(14000, 0x5, freemem, 0xc0, freemem, 0x20)\\n switch success\\n case 0 {\\n revert(0x0, 0x0)\\n }\\n default {\\n ret := mload(freemem)\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb53714ba63cddb379ba312c1e7f6a423f4d7a7e34fa1364ec8295cd57d544024\",\"license\":\"GPL-3.0\"},\"contracts/infrastructure/interfaces/IFacetRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Registry Interface\\n * @dev Interface for Facet Registry contract to keep track of facets & function selectors addable to user wallets\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IFacetRegistry {\\n struct FacetRegistryConfig {\\n bytes4[] selectors;\\n mapping(bytes4 => FacetInfo) info;\\n }\\n struct FacetInfo {\\n bool exists;\\n uint128 index;\\n }\\n\\n event FacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] facetSelectors\\n );\\n event FacetFunctionSelectorsRemoved(address facet, bytes4[] facetSelectors);\\n\\n error FacetRegistry__FacetSelectorAlreadyRegistered();\\n error FacetRegistry__UnregisteredFacetSelector();\\n\\n function registerFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function removeFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function areFacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external view returns (bool);\\n\\n function isFacetFunctionSelectorRegistered(\\n address facet,\\n bytes4 facetSelector\\n ) external view returns (bool);\\n\\n function getFacetFunctionSelectors(\\n address facet\\n ) external view returns (bytes4[] memory);\\n}\\n\",\"keccak256\":\"0x6e6dd2cab346ef7c31230740ec48d2925e4a9ab24c2f2fb268baaf408dcf02ef\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC1271 {\\n function isValidSignature(\\n bytes32 hash,\\n bytes memory signature\\n ) external view returns (bytes4);\\n}\\n\",\"keccak256\":\"0xcdddb7d5641c9d3f2432dec7fd13fddb9ae1480f25c76c21511e2fa16b8bd422\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibAppStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {SafeCast} from \\\"@openzeppelin/contracts/utils/math/SafeCast.sol\\\";\\nimport {IEntryPoint} from \\\"../aa-4337/interfaces/IEntryPoint.sol\\\";\\nimport {IFacetRegistry} from \\\"../infrastructure/interfaces/IFacetRegistry.sol\\\";\\n\\n/*\\n * @title App Storage\\n * @dev App storage for Barz contract to prevent storage collision\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Lock {\\n uint64 release;\\n bytes4 locker;\\n}\\n\\nstruct InitializersStorage {\\n // NOTE: initialized is a variable to make sure the initialization is only done once.\\n uint8 signerInitialized;\\n uint8 accountInitialized;\\n uint8 restrictionsInitialized;\\n}\\n\\nstruct AppStorage {\\n mapping(uint256 => InitializersStorage) initStorage;\\n uint8 signerMigration;\\n bytes4 validateOwnerSignatureSelector;\\n IEntryPoint entryPoint;\\n IFacetRegistry facetRegistry;\\n mapping(uint256 => Lock) locks;\\n}\\n\\nlibrary LibAppStorage {\\n error LibAppStorage__AccountAlreadyUninitialized();\\n error LibAppStorage__AccountMustBeUninitialized();\\n error LibAppStorage__SignerAlreadyUninitialized();\\n error LibAppStorage__SignerMustBeUninitialized();\\n\\n function appStorage() internal pure returns (AppStorage storage ds) {\\n assembly {\\n ds.slot := 0\\n }\\n }\\n\\n function setSignerUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerAlreadyUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 0;\\n }\\n\\n function getValidateOwnerSignatureSelector()\\n internal\\n view\\n returns (bytes4 selector)\\n {\\n selector = appStorage().validateOwnerSignatureSelector;\\n }\\n\\n function setValidateOwnerSignatureSelector(\\n bytes4 _validateOwnerSignatureSelector\\n ) internal {\\n appStorage()\\n .validateOwnerSignatureSelector = _validateOwnerSignatureSelector;\\n }\\n\\n function enforceSignerInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerMustBeUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 1;\\n }\\n\\n function enforceAccountInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].accountInitialized) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n s.initStorage[0].accountInitialized = 1;\\n }\\n\\n function initiateSignerMigration() internal {\\n appStorage().signerMigration = 1;\\n }\\n\\n function enforceSignerMigration() internal view {\\n if (1 != appStorage().signerMigration) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n }\\n\\n function finalizeSignerMigration() internal {\\n appStorage().signerMigration = 0;\\n }\\n\\n function setLock(uint256 _releaseAfter, bytes4 _locker) internal {\\n appStorage().locks[0] = Lock(SafeCast.toUint64(_releaseAfter), _locker);\\n }\\n\\n function enforceRestrictionsInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__SignerMustBeUninitialized();\\n s.initStorage[0].restrictionsInitialized = 1;\\n }\\n\\n function setRestrictionsUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__AccountAlreadyUninitialized();\\n s.initStorage[0].restrictionsInitialized = 0;\\n }\\n}\\n\\ncontract BarzStorage {\\n AppStorage internal s;\\n modifier onlyWhenUnlocked() {\\n require(\\n uint64(block.timestamp) >= s.locks[0].release,\\n \\\"Account Locked\\\"\\n );\\n _;\\n }\\n modifier onlyWhenLocked() {\\n require(\\n uint64(block.timestamp) < s.locks[0].release,\\n \\\"Account Unlocked\\\"\\n );\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x48524007862a6ce0e07f645950613ce6513ce073c37a109c75019683d42bae27\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\\n bytes4(keccak256(\\\"verifyRestrictions(address,address,uint256,bytes)\\\"));\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // Default Fallback Handler of the barz.\\n IDiamondLoupe defaultFallbackHandler;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function enforceIsSelf() internal view {\\n require(msg.sender == address(this), \\\"LibDiamond: Caller not self\\\");\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n\\n unchecked {\\n facetIndex++;\\n }\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n\\n function restrictionsFacet() internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(\\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2cabdc00de859c3a3170ce3bda5d0e5fd3933d47ce904fd1585f9818b02572f8\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibFacetStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Storage\\n * @dev Storage contract to store each facets variables with diamond storage\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Secp256k1VerificationStorage {\\n address signer;\\n}\\n\\nstruct Secp256r1VerificationStorage {\\n uint256[2] q;\\n}\\n\\nstruct GuardianStorage {\\n mapping(bytes32 => uint256) pending;\\n mapping(uint8 => StorageConfig) configs;\\n}\\n\\nstruct Info {\\n bool exists;\\n uint128 index;\\n}\\n\\nstruct StorageConfig {\\n address[] addresses;\\n mapping(address => Info) info;\\n}\\n\\nstruct RecoveryConfig {\\n bytes recoveryPublicKey;\\n uint64 executeAfter;\\n}\\n\\nstruct ApprovalConfig {\\n bool isApproved;\\n uint64 validUntil;\\n}\\n\\nstruct RecoveryApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isNewOwnerApproved;\\n}\\n\\nstruct RecoveryStorage {\\n mapping(uint8 => RecoveryConfig) recoveryConfigs;\\n mapping(uint8 => RecoveryApprovalConfig) recoveryApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct RestrictionsStorage {\\n address[] restrictions;\\n mapping(address => bool) exists;\\n}\\n\\nstruct SignatureMigrationConfig {\\n bytes migrationPublicKey;\\n address migrationVerificationFacet;\\n bytes4[] migrationSelectors;\\n uint64 migrateAfter;\\n}\\n\\nstruct SignatureMigrationApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isMigrationApproved;\\n}\\n\\nstruct SignatureMigrationStorage {\\n mapping(uint8 => SignatureMigrationConfig) migrationConfigs;\\n mapping(uint8 => SignatureMigrationApprovalConfig) migrationApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct DiamondCutApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isDiamondCutApproved;\\n}\\n\\nstruct DiamondCutStorage {\\n mapping(uint8 => DiamondCutApprovalConfig) diamondCutApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct LockStorage {\\n uint128 nonce;\\n}\\n\\nlibrary LibFacetStorage {\\n bytes32 constant K1_STORAGE_POSITION =\\n keccak256(\\n \\\"v0.trustwallet.diamond.storage.Secp256k1VerificationStorage\\\"\\n );\\n bytes32 constant R1_STORAGE_POSITION =\\n keccak256(\\n \\\"v0.trustwallet.diamond.storage.Secp256r1VerificationStorage\\\"\\n );\\n bytes32 constant GUARDIAN_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.GuardianStorage\\\");\\n bytes32 constant RECOVERY_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.RecoveryStorage\\\");\\n bytes32 constant RESTRICTION_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.RestrictionsStorage\\\");\\n bytes32 constant MIGRATION_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.SignatureMigrationStorage\\\");\\n bytes32 constant DIAMONDCUT_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.DiamondCutStorage\\\");\\n bytes32 constant LOCK_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.LockStorage\\\");\\n\\n function k1Storage()\\n internal\\n pure\\n returns (Secp256k1VerificationStorage storage ds)\\n {\\n bytes32 storagePosition = K1_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function r1Storage()\\n internal\\n pure\\n returns (Secp256r1VerificationStorage storage ds)\\n {\\n bytes32 storagePosition = R1_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function guardianStorage()\\n internal\\n pure\\n returns (GuardianStorage storage ds)\\n {\\n bytes32 storagePosition = GUARDIAN_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function recoveryStorage()\\n internal\\n pure\\n returns (RecoveryStorage storage ds)\\n {\\n bytes32 storagePosition = RECOVERY_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function restrictionsStorage()\\n internal\\n pure\\n returns (RestrictionsStorage storage ds)\\n {\\n bytes32 storagePosition = RESTRICTION_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function migrationStorage()\\n internal\\n pure\\n returns (SignatureMigrationStorage storage ds)\\n {\\n bytes32 storagePosition = MIGRATION_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function diamondCutStorage()\\n internal\\n pure\\n returns (DiamondCutStorage storage ds)\\n {\\n bytes32 storagePosition = DIAMONDCUT_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function lockStorage() internal pure returns (LockStorage storage ds) {\\n bytes32 storagePosition = LOCK_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n}\\n\",\"keccak256\":\"0x87c85decfd943deda9540733e464cb1a92eba735a301e89ce6f798016e359761\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\nimport {LibDiamond} from \\\"./LibDiamond.sol\\\";\\n\\n/**\\n * @title LibLoupe\\n * @dev Internal Library to provide utility feature for reading the state of diamond facets\\n * Originally from Diamond's implementation of Mudgen(author of EIP-2535)\\n */\\nlibrary LibLoupe {\\n /// @notice Gets all facets and their selectors.\\n /// @return facets_ Facet\\n function facets()\\n internal\\n view\\n returns (IDiamondLoupe.Facet[] memory facets_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facets_ = new IDiamondLoupe.Facet[](ds.selectorCount);\\n uint16[] memory numFacetSelectors = new uint16[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facets_[facetIndex].facetAddress == facetAddress_) {\\n facets_[facetIndex].functionSelectors[\\n numFacetSelectors[facetIndex]\\n ] = selector;\\n // probably will never have more than 256 functions from one facet contract\\n require(numFacetSelectors[facetIndex] < 255);\\n numFacetSelectors[facetIndex]++;\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facets_[numFacets].facetAddress = facetAddress_;\\n facets_[numFacets].functionSelectors = new bytes4[](\\n ds.selectorCount\\n );\\n facets_[numFacets].functionSelectors[0] = selector;\\n numFacetSelectors[numFacets] = 1;\\n numFacets++;\\n }\\n }\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n uint256 numSelectors = numFacetSelectors[facetIndex];\\n bytes4[] memory selectors = facets_[facetIndex].functionSelectors;\\n // setting the number of selectors\\n assembly {\\n mstore(selectors, numSelectors)\\n }\\n }\\n // setting the number of facets\\n assembly {\\n mstore(facets_, numFacets)\\n }\\n }\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return _facetFunctionSelectors The selectors associated with a facet address.\\n function facetFunctionSelectors(\\n address _facet\\n ) internal view returns (bytes4[] memory _facetFunctionSelectors) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n uint256 numSelectors;\\n _facetFunctionSelectors = new bytes4[](ds.selectorCount);\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facet = address(bytes20(ds.facets[selector]));\\n if (_facet == facet) {\\n _facetFunctionSelectors[numSelectors] = selector;\\n numSelectors++;\\n }\\n }\\n }\\n // Set the number of selectors in the array\\n assembly {\\n mstore(_facetFunctionSelectors, numSelectors)\\n }\\n }\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n internal\\n view\\n returns (address[] memory facetAddresses_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetAddresses_ = new address[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facetAddress_ == facetAddresses_[facetIndex]) {\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facetAddresses_[numFacets] = facetAddress_;\\n numFacets++;\\n }\\n }\\n // Set the number of facet addresses in the array\\n assembly {\\n mstore(facetAddresses_, numFacets)\\n }\\n }\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(LibDiamond.diamondStorage().facets[_functionSelector])\\n );\\n }\\n}\\n\",\"keccak256\":\"0x0b11439c3cc657095e15ec2241fdcf67204b14001357b612fc5db4ff9e760a5a\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x60a060405234801561001057600080fd5b50610019610022565b3060805261008b565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff161561006f57604051637c2cde8b60e01b815260040160405180910390fd5b600080805260209190915260409020805460ff19166001179055565b608051611f746100ad6000396000818161016001526106e10152611f746000f3fe608060405234801561001057600080fd5b50600436106100a35760003560e01c80637104ddb2116100765780638dd501211161005b5780638dd50121146101bc578063cd00e50a146101cf578063cd9b47e4146101d757600080fd5b80637104ddb21461015b5780638da5cb5b146101a757600080fd5b806311cfe388146100a85780631626ba7e146100ce5780633253960f14610112578063392dd6d914610138575b600080fd5b6100bb6100b6366004611823565b6101ea565b6040519081526020015b60405180910390f35b6100e16100dc366004611956565b610252565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020016100c5565b7f8dd50121000000000000000000000000000000000000000000000000000000006100e1565b61014b61014636600461199d565b6102fd565b60405190151581526020016100c5565b6101827f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100c5565b6101af61036f565b6040516100c591906119f6565b6100bb6101ca366004611a47565b6103ba565b6100bb61041f565b6100bb6101e5366004611a8c565b61053a565b600061023982846101ff610140880188611afe565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061083692505050565b610244576001610247565b60005b60ff16949350505050565b60006102aa7f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b1653646040805180820191829052919060029082845b81548152602001906001019080831161028b5750505050508484610836565b6102d4577fffffffff000000000000000000000000000000000000000000000000000000006102f6565b7f1626ba7e000000000000000000000000000000000000000000000000000000005b9392505050565b60008151604114801561036957508160008151811061031e5761031e611b6a565b6020910101517fff00000000000000000000000000000000000000000000000000000000000000167f0400000000000000000000000000000000000000000000000000000000000000145b92915050565b6040516060907f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364906103a5908290602001611b99565b60405160208183030381529060405291505090565b60408051808201918290526000917f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364916104179186918691859060029082845b8154815260200190600101908083116103fa5750505050506101ea565b949350505050565b60006104296109b4565b6104316109f4565b60408051808201909152600080825260208201527f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364906104749082906002611675565b506000610488600154610100900460e01b90565b7fffffffff0000000000000000000000000000000000000000000000000000000016036104e1576040517f127c609a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff169055604051600192507fcccd30db6bc000b8bb8d11162228d2d69e3c361983ca3ae8c1365ce64b0fae9e90600090a15090565b6000610544610a93565b61058383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102fd92505050565b6105b9576040517f6c334d2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006105c88360018187611bcd565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092935061060992506116b8915050565b602082015181526040820151602082015260006106437f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b16536490565b9050610651818360026116d6565b507f8dd50121000000000000000000000000000000000000000000000000000000006000610686600154610100900460e01b90565b7fffffffff0000000000000000000000000000000000000000000000000000000016146106df576040517f5f95a63c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16610770827fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604090205460601c90565b73ffffffffffffffffffffffffffffffffffffffff16146107bd576040517fbb4752b700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff1661010060e084901c02179055600194507f6d54821a69ec281ed7ba1bf2729c700768c47df1d80fad646b0a14cc1d5c39ed8787604051610824929190611bf7565b60405180910390a15050505092915050565b600080600080600080868060200190518101906108539190611c94565b9450945094509450945060008061088a8a60405160200161087691815260200190565b604051602081830303815290604052610b33565b905060008482856040516020016108a393929190611d47565b60405160208183030381529060405290506002816040516108c49190611d8a565b602060405180830381855afa1580156108e1573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906109049190611da6565b9250505060006002858360405160200161091f929190611dbf565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905261095791611d8a565b602060405180830381855afa158015610974573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906109979190611da6565b90506109a58b888884610c6f565b9b9a5050505050505050505050565b6001805460ff16146109f2576040517f38fc28cb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff16600114610a5c576040517fe00d7c7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff1615610af9576040517f7c2cde8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b60608151600003610b5257505060408051602081019091526000815290565b6000604051806060016040528060408152602001611eff6040913990506000600684516008610b819190611e10565b610b8b9190611e56565b9050600060068551610b9d9190611e6a565b1115610bb15780610bad81611e7e565b9150505b60008167ffffffffffffffff811115610bcc57610bcc61177c565b6040519080825280601f01601f191660200182016040528015610bf6576020820181803683370190505b509050600183016020820186875188015b80821015610c62576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f8116850151845350600183019250610c07565b5092979650505050505050565b6000610c9c60017fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611eb6565b85511180610cd75750610cd060017fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611eb6565b6020860151115b15610ce457506000610417565b831580610cef575082155b80610d1a57507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518410155b80610d4557507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518310155b15610d5257506000610417565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff7f5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff8088600060200201517fffffffff00000001000000000000000000000000fffffffffffffffffffffffc0988517fffffffff00000001000000000000000000000000ffffffffffffffffffffffff90819080098a5109080860208601517fffffffff00000001000000000000000000000000ffffffffffffffffffffffff90800914610e4357506000610417565b6000610e4e86610e66565b9050610e5c81868686611062565b9695505050505050565b610e6e611704565b60405180606001604052806000815260200160008152602001600081525081600060108110610e9f57610e9f611b6a565b60200201526040805160608101909152808360006020020151815260200183600160028110610ed057610ed0611b6a565b60200201518152602001600181525081600160108110610ef257610ef2611b6a565b6020020152610f088160015b602002015161116f565b6040820152610f278160015b60200201518260025b60200201516111d1565b6060828101919091526040805191820181527f6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c29682527f4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f560208301526001908201526080820152610fa18160045b6020020151826001610f1d565b60a0820152610fb1816004610f14565b60c0820152610fca8160045b6020020151826003610f1d565b60e0820152610fda816004610efe565b610100820152610feb816008610f94565b610120820152610ffc816008610f14565b61014082015261100d816008610fbd565b610160820152608081015161102490826008610f1d565b61018082015261103581600c610f94565b6101a082015261104681600c610f14565b6101c082015261105781600c610fbd565b6101e0820152919050565b600083158061106f575082155b8061109a57507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518410155b806110c557507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518310155b156110d257506000610417565b60006110fe847fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551611243565b905060007fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551828509905060007fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551838809905060008061115e8a858561125a565b509098149998505050505050505050565b61119360405180606001604052806000815260200160008152602001600081525090565b60008060006111af856000015186602001518760400151611346565b6040805160608101825293845260208401929092529082015295945050505050565b6111f560405180606001604052806000815260200160008152602001600081525090565b6000806000611220866000015187602001518860400151886000015189602001518a60400151611424565b604080516060810182529384526020840192909252908201529695505050505050565b60006102f683611254600285611eb6565b8461155c565b6000808080806080815b81156113285782156112955761127b858585611346565b9196509450925061128d858585611346565b919650945092505b50600c60fc89901c1660fe88901c17801561130b576113038585858d85601081106112c2576112c2611b6a565b6020020151518e86601081106112da576112da611b6a565b6020020151602001518f87601081106112f5576112f5611b6a565b602002015160400151611424565b919650945092505b600298891b989790971b968161132081611ec9565b925050611264565b6113338585856115b0565b909750955050505050505b935093915050565b6000806000846000036113615750600091508190508061141b565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff8085860981828283097fffffffff00000001000000000000000000000000fffffffffffffffffffffffc099050818788098283828b0960040983848384096008099150838385868d8e09600309089250838160020984848509818110156113e65785015b039650868110156113f45783015b8387820384099550508085101561140a57938201935b909303925080808688096002099150505b93509350939050565b60008060008660000361143e575084915083905082611550565b83600003611453575087915086905085611550565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff808889098186870982818d0983838b0984858a85098e0985868e87098c09868b8f08848410156114a357928701925b8484039350878460020988818209905088818609848410156114c457928901925b898585036002099350898485099c50898288099650898a8860020982089150818d10156114f0579b89019b5b818d039c5089818b87600209099450508b86101561150d57948801945b888c870384099a50838b101561152257998801995b838b039a508887890897508882830990508781101561153e5788015b88858983030999505050505050505050505b96509650969350505050565b60008184111561156c5781840693505b60405160208152602080820152602060408201528460608201528360808201528260a082015260208160c08360056136b0fa8080156100a357505051949350505050565b600080826000036115c65750600090508061133e565b60006115f2847fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611243565b905060007fffffffff00000001000000000000000000000000ffffffffffffffffffffffff82830990507fffffffff00000001000000000000000000000000ffffffffffffffffffffffff81880993507fffffffff00000001000000000000000000000000ffffffffffffffffffffffff80838309870992505050935093915050565b82600281019282156116a8579160200282015b828111156116a8578251829060ff16905591602001919060010190611688565b506116b492915061174e565b5090565b60405180604001604052806002906020820280368337509192915050565b82600281019282156116a8579160200282015b828111156116a85782518255916020019190600101906116e9565b6040518061020001604052806010905b61173860405180606001604052806000815260200160008152602001600081525090565b8152602001906001900390816117145790505090565b5b808211156116b4576000815560010161174f565b6000610160828403121561177657600080fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156117ce576117ce61177c565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561181b5761181b61177c565b604052919050565b60008060006080848603121561183857600080fd5b833567ffffffffffffffff81111561184f57600080fd5b61185b86828701611763565b935050602080850135925085605f86011261187557600080fd5b61187d6117ab565b80608087018881111561188f57600080fd5b604088015b818110156118ab5780358452928401928401611894565b50508093505050509250925092565b600067ffffffffffffffff8211156118d4576118d461177c565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261191157600080fd5b813561192461191f826118ba565b6117d4565b81815284602083860101111561193957600080fd5b816020850160208301376000918101602001919091529392505050565b6000806040838503121561196957600080fd5b82359150602083013567ffffffffffffffff81111561198757600080fd5b61199385828601611900565b9150509250929050565b6000602082840312156119af57600080fd5b813567ffffffffffffffff8111156119c657600080fd5b61041784828501611900565b60005b838110156119ed5781810151838201526020016119d5565b50506000910152565b6020815260008251806020840152611a158160408501602087016119d2565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b60008060408385031215611a5a57600080fd5b823567ffffffffffffffff811115611a7157600080fd5b611a7d85828601611763565b95602094909401359450505050565b60008060208385031215611a9f57600080fd5b823567ffffffffffffffff80821115611ab757600080fd5b818501915085601f830112611acb57600080fd5b813581811115611ada57600080fd5b866020828501011115611aec57600080fd5b60209290920196919550909350505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112611b3357600080fd5b83018035915067ffffffffffffffff821115611b4e57600080fd5b602001915036819003821315611b6357600080fd5b9250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008183825b6002811015611bbe578154835260209092019160019182019101611b9f565b50505060408201905092915050565b60008085851115611bdd57600080fd5b83861115611bea57600080fd5b5050820193919092039150565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b6000611c5261191f846118ba565b9050828152838383011115611c6657600080fd5b6102f68360208301846119d2565b600082601f830112611c8557600080fd5b6102f683835160208501611c44565b600080600080600060a08688031215611cac57600080fd5b8551945060208601519350604086015167ffffffffffffffff80821115611cd257600080fd5b818801915088601f830112611ce657600080fd5b611cf589835160208501611c44565b94506060880151915080821115611d0b57600080fd5b611d1789838a01611c74565b93506080880151915080821115611d2d57600080fd5b50611d3a88828901611c74565b9150509295509295909350565b60008451611d598184602089016119d2565b845190830190611d6d8183602089016119d2565b8451910190611d808183602088016119d2565b0195945050505050565b60008251611d9c8184602087016119d2565b9190910192915050565b600060208284031215611db857600080fd5b5051919050565b60008351611dd18184602088016119d2565b9190910191825250602001919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808202811582820484141761036957610369611de1565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082611e6557611e65611e27565b500490565b600082611e7957611e79611e27565b500690565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611eaf57611eaf611de1565b5060010190565b8181038181111561036957610369611de1565b600081611ed857611ed8611de1565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392d5fa2646970667358221220d4142da7b16effb6b95f41adeff2bc8ce0d59d3b70ca8d55e6e83224bbfbec0a64736f6c63430008150033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100a35760003560e01c80637104ddb2116100765780638dd501211161005b5780638dd50121146101bc578063cd00e50a146101cf578063cd9b47e4146101d757600080fd5b80637104ddb21461015b5780638da5cb5b146101a757600080fd5b806311cfe388146100a85780631626ba7e146100ce5780633253960f14610112578063392dd6d914610138575b600080fd5b6100bb6100b6366004611823565b6101ea565b6040519081526020015b60405180910390f35b6100e16100dc366004611956565b610252565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020016100c5565b7f8dd50121000000000000000000000000000000000000000000000000000000006100e1565b61014b61014636600461199d565b6102fd565b60405190151581526020016100c5565b6101827f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100c5565b6101af61036f565b6040516100c591906119f6565b6100bb6101ca366004611a47565b6103ba565b6100bb61041f565b6100bb6101e5366004611a8c565b61053a565b600061023982846101ff610140880188611afe565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061083692505050565b610244576001610247565b60005b60ff16949350505050565b60006102aa7f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b1653646040805180820191829052919060029082845b81548152602001906001019080831161028b5750505050508484610836565b6102d4577fffffffff000000000000000000000000000000000000000000000000000000006102f6565b7f1626ba7e000000000000000000000000000000000000000000000000000000005b9392505050565b60008151604114801561036957508160008151811061031e5761031e611b6a565b6020910101517fff00000000000000000000000000000000000000000000000000000000000000167f0400000000000000000000000000000000000000000000000000000000000000145b92915050565b6040516060907f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364906103a5908290602001611b99565b60405160208183030381529060405291505090565b60408051808201918290526000917f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364916104179186918691859060029082845b8154815260200190600101908083116103fa5750505050506101ea565b949350505050565b60006104296109b4565b6104316109f4565b60408051808201909152600080825260208201527f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364906104749082906002611675565b506000610488600154610100900460e01b90565b7fffffffff0000000000000000000000000000000000000000000000000000000016036104e1576040517f127c609a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff169055604051600192507fcccd30db6bc000b8bb8d11162228d2d69e3c361983ca3ae8c1365ce64b0fae9e90600090a15090565b6000610544610a93565b61058383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102fd92505050565b6105b9576040517f6c334d2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006105c88360018187611bcd565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092935061060992506116b8915050565b602082015181526040820151602082015260006106437f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b16536490565b9050610651818360026116d6565b507f8dd50121000000000000000000000000000000000000000000000000000000006000610686600154610100900460e01b90565b7fffffffff0000000000000000000000000000000000000000000000000000000016146106df576040517f5f95a63c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16610770827fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604090205460601c90565b73ffffffffffffffffffffffffffffffffffffffff16146107bd576040517fbb4752b700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff1661010060e084901c02179055600194507f6d54821a69ec281ed7ba1bf2729c700768c47df1d80fad646b0a14cc1d5c39ed8787604051610824929190611bf7565b60405180910390a15050505092915050565b600080600080600080868060200190518101906108539190611c94565b9450945094509450945060008061088a8a60405160200161087691815260200190565b604051602081830303815290604052610b33565b905060008482856040516020016108a393929190611d47565b60405160208183030381529060405290506002816040516108c49190611d8a565b602060405180830381855afa1580156108e1573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906109049190611da6565b9250505060006002858360405160200161091f929190611dbf565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905261095791611d8a565b602060405180830381855afa158015610974573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906109979190611da6565b90506109a58b888884610c6f565b9b9a5050505050505050505050565b6001805460ff16146109f2576040517f38fc28cb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff16600114610a5c576040517fe00d7c7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff1615610af9576040517f7c2cde8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b60608151600003610b5257505060408051602081019091526000815290565b6000604051806060016040528060408152602001611eff6040913990506000600684516008610b819190611e10565b610b8b9190611e56565b9050600060068551610b9d9190611e6a565b1115610bb15780610bad81611e7e565b9150505b60008167ffffffffffffffff811115610bcc57610bcc61177c565b6040519080825280601f01601f191660200182016040528015610bf6576020820181803683370190505b509050600183016020820186875188015b80821015610c62576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f8116850151845350600183019250610c07565b5092979650505050505050565b6000610c9c60017fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611eb6565b85511180610cd75750610cd060017fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611eb6565b6020860151115b15610ce457506000610417565b831580610cef575082155b80610d1a57507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518410155b80610d4557507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518310155b15610d5257506000610417565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff7f5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff8088600060200201517fffffffff00000001000000000000000000000000fffffffffffffffffffffffc0988517fffffffff00000001000000000000000000000000ffffffffffffffffffffffff90819080098a5109080860208601517fffffffff00000001000000000000000000000000ffffffffffffffffffffffff90800914610e4357506000610417565b6000610e4e86610e66565b9050610e5c81868686611062565b9695505050505050565b610e6e611704565b60405180606001604052806000815260200160008152602001600081525081600060108110610e9f57610e9f611b6a565b60200201526040805160608101909152808360006020020151815260200183600160028110610ed057610ed0611b6a565b60200201518152602001600181525081600160108110610ef257610ef2611b6a565b6020020152610f088160015b602002015161116f565b6040820152610f278160015b60200201518260025b60200201516111d1565b6060828101919091526040805191820181527f6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c29682527f4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f560208301526001908201526080820152610fa18160045b6020020151826001610f1d565b60a0820152610fb1816004610f14565b60c0820152610fca8160045b6020020151826003610f1d565b60e0820152610fda816004610efe565b610100820152610feb816008610f94565b610120820152610ffc816008610f14565b61014082015261100d816008610fbd565b610160820152608081015161102490826008610f1d565b61018082015261103581600c610f94565b6101a082015261104681600c610f14565b6101c082015261105781600c610fbd565b6101e0820152919050565b600083158061106f575082155b8061109a57507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518410155b806110c557507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518310155b156110d257506000610417565b60006110fe847fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551611243565b905060007fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551828509905060007fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551838809905060008061115e8a858561125a565b509098149998505050505050505050565b61119360405180606001604052806000815260200160008152602001600081525090565b60008060006111af856000015186602001518760400151611346565b6040805160608101825293845260208401929092529082015295945050505050565b6111f560405180606001604052806000815260200160008152602001600081525090565b6000806000611220866000015187602001518860400151886000015189602001518a60400151611424565b604080516060810182529384526020840192909252908201529695505050505050565b60006102f683611254600285611eb6565b8461155c565b6000808080806080815b81156113285782156112955761127b858585611346565b9196509450925061128d858585611346565b919650945092505b50600c60fc89901c1660fe88901c17801561130b576113038585858d85601081106112c2576112c2611b6a565b6020020151518e86601081106112da576112da611b6a565b6020020151602001518f87601081106112f5576112f5611b6a565b602002015160400151611424565b919650945092505b600298891b989790971b968161132081611ec9565b925050611264565b6113338585856115b0565b909750955050505050505b935093915050565b6000806000846000036113615750600091508190508061141b565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff8085860981828283097fffffffff00000001000000000000000000000000fffffffffffffffffffffffc099050818788098283828b0960040983848384096008099150838385868d8e09600309089250838160020984848509818110156113e65785015b039650868110156113f45783015b8387820384099550508085101561140a57938201935b909303925080808688096002099150505b93509350939050565b60008060008660000361143e575084915083905082611550565b83600003611453575087915086905085611550565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff808889098186870982818d0983838b0984858a85098e0985868e87098c09868b8f08848410156114a357928701925b8484039350878460020988818209905088818609848410156114c457928901925b898585036002099350898485099c50898288099650898a8860020982089150818d10156114f0579b89019b5b818d039c5089818b87600209099450508b86101561150d57948801945b888c870384099a50838b101561152257998801995b838b039a508887890897508882830990508781101561153e5788015b88858983030999505050505050505050505b96509650969350505050565b60008184111561156c5781840693505b60405160208152602080820152602060408201528460608201528360808201528260a082015260208160c08360056136b0fa8080156100a357505051949350505050565b600080826000036115c65750600090508061133e565b60006115f2847fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611243565b905060007fffffffff00000001000000000000000000000000ffffffffffffffffffffffff82830990507fffffffff00000001000000000000000000000000ffffffffffffffffffffffff81880993507fffffffff00000001000000000000000000000000ffffffffffffffffffffffff80838309870992505050935093915050565b82600281019282156116a8579160200282015b828111156116a8578251829060ff16905591602001919060010190611688565b506116b492915061174e565b5090565b60405180604001604052806002906020820280368337509192915050565b82600281019282156116a8579160200282015b828111156116a85782518255916020019190600101906116e9565b6040518061020001604052806010905b61173860405180606001604052806000815260200160008152602001600081525090565b8152602001906001900390816117145790505090565b5b808211156116b4576000815560010161174f565b6000610160828403121561177657600080fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156117ce576117ce61177c565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561181b5761181b61177c565b604052919050565b60008060006080848603121561183857600080fd5b833567ffffffffffffffff81111561184f57600080fd5b61185b86828701611763565b935050602080850135925085605f86011261187557600080fd5b61187d6117ab565b80608087018881111561188f57600080fd5b604088015b818110156118ab5780358452928401928401611894565b50508093505050509250925092565b600067ffffffffffffffff8211156118d4576118d461177c565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261191157600080fd5b813561192461191f826118ba565b6117d4565b81815284602083860101111561193957600080fd5b816020850160208301376000918101602001919091529392505050565b6000806040838503121561196957600080fd5b82359150602083013567ffffffffffffffff81111561198757600080fd5b61199385828601611900565b9150509250929050565b6000602082840312156119af57600080fd5b813567ffffffffffffffff8111156119c657600080fd5b61041784828501611900565b60005b838110156119ed5781810151838201526020016119d5565b50506000910152565b6020815260008251806020840152611a158160408501602087016119d2565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b60008060408385031215611a5a57600080fd5b823567ffffffffffffffff811115611a7157600080fd5b611a7d85828601611763565b95602094909401359450505050565b60008060208385031215611a9f57600080fd5b823567ffffffffffffffff80821115611ab757600080fd5b818501915085601f830112611acb57600080fd5b813581811115611ada57600080fd5b866020828501011115611aec57600080fd5b60209290920196919550909350505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112611b3357600080fd5b83018035915067ffffffffffffffff821115611b4e57600080fd5b602001915036819003821315611b6357600080fd5b9250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008183825b6002811015611bbe578154835260209092019160019182019101611b9f565b50505060408201905092915050565b60008085851115611bdd57600080fd5b83861115611bea57600080fd5b5050820193919092039150565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b6000611c5261191f846118ba565b9050828152838383011115611c6657600080fd5b6102f68360208301846119d2565b600082601f830112611c8557600080fd5b6102f683835160208501611c44565b600080600080600060a08688031215611cac57600080fd5b8551945060208601519350604086015167ffffffffffffffff80821115611cd257600080fd5b818801915088601f830112611ce657600080fd5b611cf589835160208501611c44565b94506060880151915080821115611d0b57600080fd5b611d1789838a01611c74565b93506080880151915080821115611d2d57600080fd5b50611d3a88828901611c74565b9150509295509295909350565b60008451611d598184602089016119d2565b845190830190611d6d8183602089016119d2565b8451910190611d808183602088016119d2565b0195945050505050565b60008251611d9c8184602087016119d2565b9190910192915050565b600060208284031215611db857600080fd5b5051919050565b60008351611dd18184602088016119d2565b9190910191825250602001919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808202811582820484141761036957610369611de1565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082611e6557611e65611e27565b500490565b600082611e7957611e79611e27565b500690565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611eaf57611eaf611de1565b5060010190565b8181038181111561036957610369611de1565b600081611ed857611ed8611de1565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392d5fa2646970667358221220d4142da7b16effb6b95f41adeff2bc8ce0d59d3b70ca8d55e6e83224bbfbec0a64736f6c63430008150033", + "devdoc": { + "author": "Ruslan Serebriakov (@rsrbk)David Yongjun Kim (@Powerstream3604)", + "details": "Primarily used to verify user ops signed with passkeys", + "kind": "dev", + "methods": { + "initializeSigner(bytes)": { + "details": "This method checks if the signer has already been initialized. If already initialized, it reverts. It checks if the public key is in the light format and initializes signer storage in k1 storage.", + "params": { + "_publicKey": "Bytes of owner public key" + }, + "returns": { + "initSuccess": "Uint value representing the success of init operation" + } + }, + "isValidKeyType(bytes)": { + "details": "For this Secp256k1Verification Facet, the public key should in an uncompressed public key format", + "params": { + "_publicKey": "Bytes of public key for format check" + }, + "returns": { + "isValid": "Boolean variable representing if the format of public key is valid" + } + }, + "isValidSignature(bytes32,bytes)": { + "details": "This method verifies the signature if the owner indeed signed the hash. Returns magic value if true", + "params": { + "_hash": "Hash value the owner signed", + "_signature": "Signature that signed the above hash" + }, + "returns": { + "magicValue": "Bytes4 value representing the success/failure of validation" + } + }, + "owner()": { + "returns": { + "signer": "Bytes of owner address" + } + }, + "uninitializeSigner()": { + "details": "This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.", + "returns": { + "uninitSuccess": "Uint value representing the success of uninit operation" + } + }, + "validateOwnerSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32)": { + "details": "This method validates if the user operation is signed by the owner. It internally calls validateSignature with signer public key.", + "params": { + "userOp": "UserOperation including all information for execution", + "userOpHash": "Hash of UserOperation given from EntryPoint. This hash is used for signature validation" + }, + "returns": { + "validationData": "Uint value representing whether the validation is successful. 0 for success, 1 for failure" + } + }, + "validateOwnerSignatureSelector()": { + "returns": { + "ownerSignatureValidatorSelector": "Bytes4 selector of function signature to validate account owner's UserOperation signature" + } + }, + "validateSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256[2])": { + "details": "This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address", + "params": { + "q": "Public Key of signer who signed the contract, to be validated", + "userOp": "UserOperation including all information for execution", + "userOpHash": "Hash of UserOperation given from EntryPoint. This hash is used for signature validation" + }, + "returns": { + "isValid": "Uint value representing whether the validation is successful. 0 for success, 1 for failure" + } + } + }, + "title": "Secp256r1 verification facet", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "constructor": { + "notice": "This constructor ensures that this contract can only be used as singleton for Proxy contracts" + }, + "initializeSigner(bytes)": { + "notice": "Initializes the signer in R1 Facet Storage. This can only be called when the account is uninitialized or during signature migration." + }, + "isValidKeyType(bytes)": { + "notice": "Validates if the format of public key is valid for this verification facet" + }, + "isValidSignature(bytes32,bytes)": { + "notice": "Validates if the signature is valid. Function to be compatible with EIP-1271" + }, + "owner()": { + "notice": "Returns the owner of the account" + }, + "uninitializeSigner()": { + "notice": "Uninitialize signer in R1 Facet Storage. This can only be called when the account is undergoing signature migration and has already been initialized." + }, + "validateOwnerSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32)": { + "notice": "Validates if the user operation is signed by the owner." + }, + "validateOwnerSignatureSelector()": { + "notice": "Returns the selector of function to validate the signature of UserOperation" + }, + "validateSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256[2])": { + "notice": "Validates if the signature of UserOperation is signed by the given signer" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/optimism/TokenReceiverFacet.json b/deployments/optimism/TokenReceiverFacet.json new file mode 100644 index 0000000..336b43c --- /dev/null +++ b/deployments/optimism/TokenReceiverFacet.json @@ -0,0 +1,239 @@ +{ + "address": "0x3143E1C0Af0Cdc153423863923Cf4e3818e34Daa", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onERC1155BatchReceived", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onERC1155Received", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onERC721Received", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onTokenTransfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "tokensReceived", + "outputs": [], + "stateMutability": "pure", + "type": "function" + } + ], + "transactionHash": "0xfa018f1a0303ce849cf1e23d6c4202a5970bd97733f935b15d043112783e0a67", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 7, + "gasUsed": "329340", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x3be5aaf17f4b988acc6bd15f610a0b09d386c05df81f3dad96779e4fbde2f49e", + "transactionHash": "0xfa018f1a0303ce849cf1e23d6c4202a5970bd97733f935b15d043112783e0a67", + "logs": [], + "blockNumber": 111414431, + "cumulativeGasUsed": "3262229", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "0c861e53801b64e5ccc05669ea62a977", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onERC1155BatchReceived\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onERC1155Received\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onERC721Received\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"tokensReceived\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"Contract that enables receiving ERC721/ERC1155/ERC777/ERC677 Tokens with safe transfer\",\"kind\":\"dev\",\"methods\":{},\"title\":\"TokenReceiver Facet\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\":{\"notice\":\"Handles ERC1155 Token batch callback. return Standardized onERC1155BatchReceived return value.\"},\"onERC1155Received(address,address,uint256,uint256,bytes)\":{\"notice\":\"Handles ERC1155 Token callback. return Standardized onERC1155Received return value.\"},\"onERC721Received(address,address,uint256,bytes)\":{\"notice\":\"Handles ERC721 Token callback. return Standardized onERC721Received return value.\"},\"onTokenTransfer(address,uint256,bytes)\":{\"notice\":\"Handles ERC677 Token callback. return true.\"},\"tokensReceived(address,address,address,uint256,bytes,bytes)\":{\"notice\":\"Handles ERC777 Token callback. Does not return value, empty implementation.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/TokenReceiverFacet.sol\":\"TokenReceiverFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title ERC721 token receiver interface\\n * @dev Interface for any contract that wants to support safeTransfers\\n * from ERC721 asset contracts.\\n */\\ninterface IERC721Receiver {\\n /**\\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\\n * by `operator` from `from`, this function is called.\\n *\\n * It must return its Solidity selector to confirm the token transfer.\\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\\n *\\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\\n */\\n function onERC721Received(\\n address operator,\\n address from,\\n uint256 tokenId,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\\n *\\n * Accounts can be notified of {IERC777} tokens being sent to them by having a\\n * contract implement this interface (contract holders can be their own\\n * implementer) and registering it on the\\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\\n *\\n * See {IERC1820Registry} and {ERC1820Implementer}.\\n */\\ninterface IERC777Recipient {\\n /**\\n * @dev Called by an {IERC777} token contract whenever tokens are being\\n * moved or created into a registered account (`to`). The type of operation\\n * is conveyed by `from` being the zero address or not.\\n *\\n * This call occurs _after_ the token contract's state is updated, so\\n * {IERC777-balanceOf}, etc., can be used to query the post-operation state.\\n *\\n * This function may revert to prevent the operation from being executed.\\n */\\n function tokensReceived(\\n address operator,\\n address from,\\n address to,\\n uint256 amount,\\n bytes calldata userData,\\n bytes calldata operatorData\\n ) external;\\n}\\n\",\"keccak256\":\"0x1a5d61db2733202ba361e6d6741cd2e662380e22b80e987eacfc91973f2267dc\",\"license\":\"MIT\"},\"contracts/facets/TokenReceiverFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IERC721Receiver} from \\\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\\\";\\nimport {IERC777Recipient} from \\\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\\\";\\nimport {IERC1155Receiver} from \\\"../interfaces/ERC/IERC1155Receiver.sol\\\";\\nimport {IERC677Receiver} from \\\"../interfaces/ERC/IERC677Receiver.sol\\\";\\n\\n/**\\n * @title TokenReceiver Facet\\n * @dev Contract that enables receiving ERC721/ERC1155/ERC777/ERC677 Tokens with safe transfer\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract TokenReceiverFacet is\\n IERC721Receiver,\\n IERC1155Receiver,\\n IERC777Recipient,\\n IERC677Receiver\\n{\\n /**\\n * @notice Handles ERC721 Token callback.\\n * return Standardized onERC721Received return value.\\n */\\n function onERC721Received(\\n address,\\n address,\\n uint256,\\n bytes calldata\\n ) external pure override returns (bytes4) {\\n return IERC721Receiver.onERC721Received.selector;\\n }\\n\\n /**\\n * @notice Handles ERC1155 Token callback.\\n * return Standardized onERC1155Received return value.\\n */\\n function onERC1155Received(\\n address,\\n address,\\n uint256,\\n uint256,\\n bytes calldata\\n ) external pure override returns (bytes4) {\\n return IERC1155Receiver.onERC1155Received.selector;\\n }\\n\\n /**\\n * @notice Handles ERC1155 Token batch callback.\\n * return Standardized onERC1155BatchReceived return value.\\n */\\n function onERC1155BatchReceived(\\n address,\\n address,\\n uint256[] calldata,\\n uint256[] calldata,\\n bytes calldata\\n ) external pure override returns (bytes4) {\\n return IERC1155Receiver.onERC1155BatchReceived.selector;\\n }\\n\\n /**\\n * @notice Handles ERC777 Token callback.\\n * Does not return value, empty implementation.\\n */\\n function tokensReceived(\\n address,\\n address,\\n address,\\n uint256,\\n bytes calldata,\\n bytes calldata\\n ) external pure override {}\\n\\n /**\\n * @notice Handles ERC677 Token callback.\\n * return true.\\n */\\n function onTokenTransfer(\\n address,\\n uint256,\\n bytes calldata\\n ) external pure override returns (bool) {\\n return true;\\n }\\n}\\n\",\"keccak256\":\"0xdfe483d05ef4056bb464c34ade19ab527687aff3ed0b6303b447a68b5ff7abb4\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC1155Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\n\\npragma solidity 0.8.21;\\n\\n/**\\n * @dev _Available since v3.1._\\n */\\ninterface IERC1155Receiver {\\n /**\\n * @dev Handles the receipt of a single ERC1155 token type. This function is\\n * called at the end of a `safeTransferFrom` after the balance has been updated.\\n *\\n * NOTE: To accept the transfer, this must return\\n * `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))`\\n * (i.e. 0xf23a6e61, or its own function selector).\\n *\\n * @param operator The address which initiated the transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param id The ID of the token being transferred\\n * @param value The amount of tokens being transferred\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155Received(\\n address operator,\\n address from,\\n uint256 id,\\n uint256 value,\\n bytes calldata data\\n ) external returns (bytes4);\\n\\n /**\\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\\n * is called at the end of a `safeBatchTransferFrom` after the balances have\\n * been updated.\\n *\\n * NOTE: To accept the transfer(s), this must return\\n * `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))`\\n * (i.e. 0xbc197c81, or its own function selector).\\n *\\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155BatchReceived(\\n address operator,\\n address from,\\n uint256[] calldata ids,\\n uint256[] calldata values,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0x3729c6757bae3aba03ac1c5064d67ad13b94e2a9428bf44b9be510373406da0c\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC677Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC677Receiver {\\n function onTokenTransfer(\\n address sender,\\n uint value,\\n bytes calldata data\\n ) external pure returns (bool);\\n}\\n\",\"keccak256\":\"0x4c1631cf45ea6daac0ec158c3edb9453099130b6b64f697004b83f95aa1f7350\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50610502806100206000396000f3fe608060405234801561001057600080fd5b50600436106100665760003560e01c8063a4c0ed3611610050578063a4c0ed36146100f3578063bc197c811461011b578063f23a6e611461015657600080fd5b806223de291461006b578063150b7a0214610085575b600080fd5b610083610079366004610201565b5050505050505050565b005b6100bd6100933660046102ac565b7f150b7a020000000000000000000000000000000000000000000000000000000095945050505050565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020015b60405180910390f35b61010b61010136600461031b565b6001949350505050565b60405190151581526020016100ea565b6100bd6101293660046103ba565b7fbc197c810000000000000000000000000000000000000000000000000000000098975050505050505050565b6100bd610164366004610454565b7ff23a6e61000000000000000000000000000000000000000000000000000000009695505050505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146101b357600080fd5b919050565b60008083601f8401126101ca57600080fd5b50813567ffffffffffffffff8111156101e257600080fd5b6020830191508360208285010111156101fa57600080fd5b9250929050565b60008060008060008060008060c0898b03121561021d57600080fd5b6102268961018f565b975061023460208a0161018f565b965061024260408a0161018f565b955060608901359450608089013567ffffffffffffffff8082111561026657600080fd5b6102728c838d016101b8565b909650945060a08b013591508082111561028b57600080fd5b506102988b828c016101b8565b999c989b5096995094979396929594505050565b6000806000806000608086880312156102c457600080fd5b6102cd8661018f565b94506102db6020870161018f565b935060408601359250606086013567ffffffffffffffff8111156102fe57600080fd5b61030a888289016101b8565b969995985093965092949392505050565b6000806000806060858703121561033157600080fd5b61033a8561018f565b935060208501359250604085013567ffffffffffffffff81111561035d57600080fd5b610369878288016101b8565b95989497509550505050565b60008083601f84011261038757600080fd5b50813567ffffffffffffffff81111561039f57600080fd5b6020830191508360208260051b85010111156101fa57600080fd5b60008060008060008060008060a0898b0312156103d657600080fd5b6103df8961018f565b97506103ed60208a0161018f565b9650604089013567ffffffffffffffff8082111561040a57600080fd5b6104168c838d01610375565b909850965060608b013591508082111561042f57600080fd5b61043b8c838d01610375565b909650945060808b013591508082111561028b57600080fd5b60008060008060008060a0878903121561046d57600080fd5b6104768761018f565b95506104846020880161018f565b94506040870135935060608701359250608087013567ffffffffffffffff8111156104ae57600080fd5b6104ba89828a016101b8565b979a969950949750929593949250505056fea2646970667358221220ae9a97061ae9e1485161ca9c8d3228a23e47b18755fa935f51b40e927816ca2964736f6c63430008150033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100665760003560e01c8063a4c0ed3611610050578063a4c0ed36146100f3578063bc197c811461011b578063f23a6e611461015657600080fd5b806223de291461006b578063150b7a0214610085575b600080fd5b610083610079366004610201565b5050505050505050565b005b6100bd6100933660046102ac565b7f150b7a020000000000000000000000000000000000000000000000000000000095945050505050565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020015b60405180910390f35b61010b61010136600461031b565b6001949350505050565b60405190151581526020016100ea565b6100bd6101293660046103ba565b7fbc197c810000000000000000000000000000000000000000000000000000000098975050505050505050565b6100bd610164366004610454565b7ff23a6e61000000000000000000000000000000000000000000000000000000009695505050505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146101b357600080fd5b919050565b60008083601f8401126101ca57600080fd5b50813567ffffffffffffffff8111156101e257600080fd5b6020830191508360208285010111156101fa57600080fd5b9250929050565b60008060008060008060008060c0898b03121561021d57600080fd5b6102268961018f565b975061023460208a0161018f565b965061024260408a0161018f565b955060608901359450608089013567ffffffffffffffff8082111561026657600080fd5b6102728c838d016101b8565b909650945060a08b013591508082111561028b57600080fd5b506102988b828c016101b8565b999c989b5096995094979396929594505050565b6000806000806000608086880312156102c457600080fd5b6102cd8661018f565b94506102db6020870161018f565b935060408601359250606086013567ffffffffffffffff8111156102fe57600080fd5b61030a888289016101b8565b969995985093965092949392505050565b6000806000806060858703121561033157600080fd5b61033a8561018f565b935060208501359250604085013567ffffffffffffffff81111561035d57600080fd5b610369878288016101b8565b95989497509550505050565b60008083601f84011261038757600080fd5b50813567ffffffffffffffff81111561039f57600080fd5b6020830191508360208260051b85010111156101fa57600080fd5b60008060008060008060008060a0898b0312156103d657600080fd5b6103df8961018f565b97506103ed60208a0161018f565b9650604089013567ffffffffffffffff8082111561040a57600080fd5b6104168c838d01610375565b909850965060608b013591508082111561042f57600080fd5b61043b8c838d01610375565b909650945060808b013591508082111561028b57600080fd5b60008060008060008060a0878903121561046d57600080fd5b6104768761018f565b95506104846020880161018f565b94506040870135935060608701359250608087013567ffffffffffffffff8111156104ae57600080fd5b6104ba89828a016101b8565b979a969950949750929593949250505056fea2646970667358221220ae9a97061ae9e1485161ca9c8d3228a23e47b18755fa935f51b40e927816ca2964736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "Contract that enables receiving ERC721/ERC1155/ERC777/ERC677 Tokens with safe transfer", + "kind": "dev", + "methods": {}, + "title": "TokenReceiver Facet", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)": { + "notice": "Handles ERC1155 Token batch callback. return Standardized onERC1155BatchReceived return value." + }, + "onERC1155Received(address,address,uint256,uint256,bytes)": { + "notice": "Handles ERC1155 Token callback. return Standardized onERC1155Received return value." + }, + "onERC721Received(address,address,uint256,bytes)": { + "notice": "Handles ERC721 Token callback. return Standardized onERC721Received return value." + }, + "onTokenTransfer(address,uint256,bytes)": { + "notice": "Handles ERC677 Token callback. return true." + }, + "tokensReceived(address,address,address,uint256,bytes,bytes)": { + "notice": "Handles ERC777 Token callback. Does not return value, empty implementation." + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/optimism/solcInputs/0c861e53801b64e5ccc05669ea62a977.json b/deployments/optimism/solcInputs/0c861e53801b64e5ccc05669ea62a977.json new file mode 100644 index 0000000..47e9456 --- /dev/null +++ b/deployments/optimism/solcInputs/0c861e53801b64e5ccc05669ea62a977.json @@ -0,0 +1,354 @@ +{ + "language": "Solidity", + "sources": { + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby disabling any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable2Step.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./Ownable.sol\";\n\n/**\n * @dev Contract module which provides access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership} and {acceptOwnership}.\n *\n * This module is used through inheritance. It will make available all functions\n * from parent (Ownable).\n */\nabstract contract Ownable2Step is Ownable {\n address private _pendingOwner;\n\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Returns the address of the pending owner.\n */\n function pendingOwner() public view virtual returns (address) {\n return _pendingOwner;\n }\n\n /**\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual override onlyOwner {\n _pendingOwner = newOwner;\n emit OwnershipTransferStarted(owner(), newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual override {\n delete _pendingOwner;\n super._transferOwnership(newOwner);\n }\n\n /**\n * @dev The new owner accepts the ownership transfer.\n */\n function acceptOwnership() public virtual {\n address sender = _msgSender();\n require(pendingOwner() == sender, \"Ownable2Step: caller is not the new owner\");\n _transferOwnership(sender);\n }\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC1271.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC1271 standard signature validation method for\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\n *\n * _Available since v4.1._\n */\ninterface IERC1271 {\n /**\n * @dev Should return whether the signature provided is valid for the provided data\n * @param hash Hash of the data to be signed\n * @param signature Signature byte array associated with _data\n */\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\n}\n" + }, + "@openzeppelin/contracts/security/ReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor() {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n _nonReentrantBefore();\n _;\n _nonReentrantAfter();\n }\n\n function _nonReentrantBefore() private {\n // On the first call to nonReentrant, _status will be _NOT_ENTERED\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n }\n\n function _nonReentrantAfter() private {\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Returns true if the reentrancy guard is currently set to \"entered\", which indicates there is a\n * `nonReentrant` function in the call stack.\n */\n function _reentrancyGuardEntered() internal view returns (bool) {\n return _status == _ENTERED;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/ERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/ERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC1155.sol\";\nimport \"./IERC1155Receiver.sol\";\nimport \"./extensions/IERC1155MetadataURI.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of the basic standard multi-token.\n * See https://eips.ethereum.org/EIPS/eip-1155\n * Originally based on code by Enjin: https://github.com/enjin/erc-1155\n *\n * _Available since v3.1._\n */\ncontract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {\n using Address for address;\n\n // Mapping from token ID to account balances\n mapping(uint256 => mapping(address => uint256)) private _balances;\n\n // Mapping from account to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json\n string private _uri;\n\n /**\n * @dev See {_setURI}.\n */\n constructor(string memory uri_) {\n _setURI(uri_);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return\n interfaceId == type(IERC1155).interfaceId ||\n interfaceId == type(IERC1155MetadataURI).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC1155MetadataURI-uri}.\n *\n * This implementation returns the same URI for *all* token types. It relies\n * on the token type ID substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * Clients calling this function must replace the `\\{id\\}` substring with the\n * actual token type ID.\n */\n function uri(uint256) public view virtual override returns (string memory) {\n return _uri;\n }\n\n /**\n * @dev See {IERC1155-balanceOf}.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {\n require(account != address(0), \"ERC1155: address zero is not a valid owner\");\n return _balances[id][account];\n }\n\n /**\n * @dev See {IERC1155-balanceOfBatch}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] memory accounts,\n uint256[] memory ids\n ) public view virtual override returns (uint256[] memory) {\n require(accounts.length == ids.length, \"ERC1155: accounts and ids length mismatch\");\n\n uint256[] memory batchBalances = new uint256[](accounts.length);\n\n for (uint256 i = 0; i < accounts.length; ++i) {\n batchBalances[i] = balanceOf(accounts[i], ids[i]);\n }\n\n return batchBalances;\n }\n\n /**\n * @dev See {IERC1155-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC1155-isApprovedForAll}.\n */\n function isApprovedForAll(address account, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[account][operator];\n }\n\n /**\n * @dev See {IERC1155-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n _safeTransferFrom(from, to, id, amount, data);\n }\n\n /**\n * @dev See {IERC1155-safeBatchTransferFrom}.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n _safeBatchTransferFrom(from, to, ids, amounts, data);\n }\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n\n emit TransferSingle(operator, from, to, id, amount);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n for (uint256 i = 0; i < ids.length; ++i) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n }\n\n emit TransferBatch(operator, from, to, ids, amounts);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\n\n _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);\n }\n\n /**\n * @dev Sets a new URI for all token types, by relying on the token type ID\n * substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * By this mechanism, any occurrence of the `\\{id\\}` substring in either the\n * URI or any of the amounts in the JSON file at said URI will be replaced by\n * clients with the token type ID.\n *\n * For example, the `https://token-cdn-domain/\\{id\\}.json` URI would be\n * interpreted by clients as\n * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`\n * for token type ID 0x4cce0.\n *\n * See {uri}.\n *\n * Because these URIs cannot be meaningfully represented by the {URI} event,\n * this function emits no events.\n */\n function _setURI(string memory newuri) internal virtual {\n _uri = newuri;\n }\n\n /**\n * @dev Creates `amount` tokens of token type `id`, and assigns them to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _mint(address to, uint256 id, uint256 amount, bytes memory data) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _balances[id][to] += amount;\n emit TransferSingle(operator, address(0), to, id, amount);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n for (uint256 i = 0; i < ids.length; i++) {\n _balances[ids[i]][to] += amounts[i];\n }\n\n emit TransferBatch(operator, address(0), to, ids, amounts);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);\n }\n\n /**\n * @dev Destroys `amount` tokens of token type `id` from `from`\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `from` must have at least `amount` tokens of token type `id`.\n */\n function _burn(address from, uint256 id, uint256 amount) internal virtual {\n require(from != address(0), \"ERC1155: burn from the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n\n emit TransferSingle(operator, from, address(0), id, amount);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n */\n function _burnBatch(address from, uint256[] memory ids, uint256[] memory amounts) internal virtual {\n require(from != address(0), \"ERC1155: burn from the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n\n for (uint256 i = 0; i < ids.length; i++) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n }\n\n emit TransferBatch(operator, from, address(0), ids, amounts);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {\n require(owner != operator, \"ERC1155: setting approval status for self\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning, as well as batched variants.\n *\n * The same hook is called on both single and batched variants. For single\n * transfers, the length of the `ids` and `amounts` arrays will be 1.\n *\n * Calling conditions (for each `id` and `amount` pair):\n *\n * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * of token type `id` will be transferred to `to`.\n * - When `from` is zero, `amount` tokens of token type `id` will be minted\n * for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n * will be burned.\n * - `from` and `to` are never both zero.\n * - `ids` and `amounts` have the same, non-zero length.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any token transfer. This includes minting\n * and burning, as well as batched variants.\n *\n * The same hook is called on both single and batched variants. For single\n * transfers, the length of the `id` and `amount` arrays will be 1.\n *\n * Calling conditions (for each `id` and `amount` pair):\n *\n * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * of token type `id` will be transferred to `to`.\n * - When `from` is zero, `amount` tokens of token type `id` will be minted\n * for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n * will be burned.\n * - `from` and `to` are never both zero.\n * - `ids` and `amounts` have the same, non-zero length.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {}\n\n function _doSafeTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155Receiver.onERC1155Received.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non-ERC1155Receiver implementer\");\n }\n }\n }\n\n function _doSafeBatchTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (\n bytes4 response\n ) {\n if (response != IERC1155Receiver.onERC1155BatchReceived.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non-ERC1155Receiver implementer\");\n }\n }\n }\n\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {\n uint256[] memory array = new uint256[](1);\n array[0] = element;\n\n return array;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC1155.sol\";\n\n/**\n * @dev Interface of the optional ERC1155MetadataExtension interface, as defined\n * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155MetadataURI is IERC1155 {\n /**\n * @dev Returns the URI for token type `id`.\n *\n * If the `\\{id\\}` substring is present in the URI, it must be replaced by\n * clients with the actual token type ID.\n */\n function uri(uint256 id) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155 is IERC165 {\n /**\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n */\n event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);\n\n /**\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n * transfers.\n */\n event TransferBatch(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\n\n /**\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n * `approved`.\n */\n event ApprovalForAll(address indexed account, address indexed operator, bool approved);\n\n /**\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n *\n * If an {URI} event was emitted for `id`, the standard\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n * returned by {IERC1155MetadataURI-uri}.\n */\n event URI(string value, uint256 indexed id);\n\n /**\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) external view returns (uint256);\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] calldata accounts,\n uint256[] calldata ids\n ) external view returns (uint256[] memory);\n\n /**\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n *\n * Emits an {ApprovalForAll} event.\n *\n * Requirements:\n *\n * - `operator` cannot be the caller.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n *\n * See {setApprovalForAll}.\n */\n function isApprovedForAll(address account, address operator) external view returns (bool);\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155Receiver is IERC165 {\n /**\n * @dev Handles the receipt of a single ERC1155 token type. This function is\n * called at the end of a `safeTransferFrom` after the balance has been updated.\n *\n * NOTE: To accept the transfer, this must return\n * `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n * (i.e. 0xf23a6e61, or its own function selector).\n *\n * @param operator The address which initiated the transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param id The ID of the token being transferred\n * @param value The amount of tokens being transferred\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n ) external returns (bytes4);\n\n /**\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\n * is called at the end of a `safeBatchTransferFrom` after the balances have\n * been updated.\n *\n * NOTE: To accept the transfer(s), this must return\n * `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n * (i.e. 0xbc197c81, or its own function selector).\n *\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the default value returned by this function, unless\n * it's overridden.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(address from, address to, uint256 amount) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\n // decrementing then incrementing.\n _balances[to] += amount;\n }\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n unchecked {\n // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\n _balances[account] += amount;\n }\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n // Overflow not possible: amount <= accountBalance <= totalSupply.\n _totalSupply -= amount;\n }\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\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" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` 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 amount) 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 `amount` as the allowance of `spender` over the 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 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` 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 amount) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/ERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721.sol\";\nimport \"./IERC721Receiver.sol\";\nimport \"./extensions/IERC721Metadata.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/Strings.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\n using Address for address;\n using Strings for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\n\n // Mapping from token ID to approved address\n mapping(uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return\n interfaceId == type(IERC721).interfaceId ||\n interfaceId == type(IERC721Metadata).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _ownerOf(tokenId);\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token owner or approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n _requireMinted(tokenId);\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n _safeTransfer(from, to, tokenId, data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(address from, address to, uint256 tokenId, bytes memory data) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist\n */\n function _ownerOf(uint256 tokenId) internal view virtual returns (address) {\n return _owners[tokenId];\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _ownerOf(tokenId) != address(0);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n address owner = ERC721.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(address to, uint256 tokenId, bytes memory data) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId, 1);\n\n // Check that tokenId was not minted by `_beforeTokenTransfer` hook\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n unchecked {\n // Will not overflow unless all 2**256 token ids are minted to the same owner.\n // Given that tokens are minted one by one, it is impossible in practice that\n // this ever happens. Might change if we allow batch minting.\n // The ERC fails to describe this case.\n _balances[to] += 1;\n }\n\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(address(0), to, tokenId, 1);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n * This is an internal function that does not check if the sender is authorized to operate on the token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId, 1);\n\n // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook\n owner = ERC721.ownerOf(tokenId);\n\n // Clear approvals\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // Cannot overflow, as that would require more tokens to be burned/transferred\n // out than the owner initially received through minting and transferring in.\n _balances[owner] -= 1;\n }\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(owner, address(0), tokenId, 1);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(address from, address to, uint256 tokenId) internal virtual {\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId, 1);\n\n // Check that tokenId was not transferred by `_beforeTokenTransfer` hook\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n\n // Clear approvals from the previous owner\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // `_balances[from]` cannot overflow for the same reason as described in `_burn`:\n // `from`'s balance is the number of token held, which is at least one before the current\n // transfer.\n // `_balances[to]` could overflow in the conditions described in `_mint`. That would require\n // all 2**256 token ids to be minted, which in practice is impossible.\n _balances[from] -= 1;\n _balances[to] += 1;\n }\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId, 1);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721Receiver.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`.\n * - When `from` is zero, the tokens will be minted for `to`.\n * - When `to` is zero, ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}\n\n /**\n * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`.\n * - When `from` is zero, the tokens were minted for `to`.\n * - When `to` is zero, ``from``'s tokens were burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}\n\n /**\n * @dev Unsafe write access to the balances, used by extensions that \"mint\" tokens using an {ownerOf} override.\n *\n * WARNING: Anyone calling this MUST ensure that the balances remain consistent with the ownership. The invariant\n * being that for any address `a` the value returned by `balanceOf(a)` must be equal to the number of tokens such\n * that `ownerOf(tokenId)` is `a`.\n */\n // solhint-disable-next-line func-name-mixedcase\n function __unsafe_increaseBalance(address account, uint256 amount) internal {\n _balances[account] += amount;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721Receiver {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/ERC777.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC777/ERC777.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC777.sol\";\nimport \"./IERC777Recipient.sol\";\nimport \"./IERC777Sender.sol\";\nimport \"../ERC20/IERC20.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/introspection/IERC1820Registry.sol\";\n\n/**\n * @dev Implementation of the {IERC777} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n *\n * Support for ERC20 is included in this contract, as specified by the EIP: both\n * the ERC777 and ERC20 interfaces can be safely used when interacting with it.\n * Both {IERC777-Sent} and {IERC20-Transfer} events are emitted on token\n * movements.\n *\n * Additionally, the {IERC777-granularity} value is hard-coded to `1`, meaning that there\n * are no special restrictions in the amount of tokens that created, moved, or\n * destroyed. This makes integration with ERC20 applications seamless.\n *\n * CAUTION: This file is deprecated as of v4.9 and will be removed in the next major release.\n */\ncontract ERC777 is Context, IERC777, IERC20 {\n using Address for address;\n\n IERC1820Registry internal constant _ERC1820_REGISTRY = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n mapping(address => uint256) private _balances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n bytes32 private constant _TOKENS_SENDER_INTERFACE_HASH = keccak256(\"ERC777TokensSender\");\n bytes32 private constant _TOKENS_RECIPIENT_INTERFACE_HASH = keccak256(\"ERC777TokensRecipient\");\n\n // This isn't ever read from - it's only used to respond to the defaultOperators query.\n address[] private _defaultOperatorsArray;\n\n // Immutable, but accounts may revoke them (tracked in __revokedDefaultOperators).\n mapping(address => bool) private _defaultOperators;\n\n // For each account, a mapping of its operators and revoked default operators.\n mapping(address => mapping(address => bool)) private _operators;\n mapping(address => mapping(address => bool)) private _revokedDefaultOperators;\n\n // ERC20-allowances\n mapping(address => mapping(address => uint256)) private _allowances;\n\n /**\n * @dev `defaultOperators` may be an empty array.\n */\n constructor(string memory name_, string memory symbol_, address[] memory defaultOperators_) {\n _name = name_;\n _symbol = symbol_;\n\n _defaultOperatorsArray = defaultOperators_;\n for (uint256 i = 0; i < defaultOperators_.length; i++) {\n _defaultOperators[defaultOperators_[i]] = true;\n }\n\n // register interfaces\n _ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256(\"ERC777Token\"), address(this));\n _ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256(\"ERC20Token\"), address(this));\n }\n\n /**\n * @dev See {IERC777-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC777-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {ERC20-decimals}.\n *\n * Always returns 18, as per the\n * [ERC777 EIP](https://eips.ethereum.org/EIPS/eip-777#backward-compatibility).\n */\n function decimals() public pure virtual returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC777-granularity}.\n *\n * This implementation always returns `1`.\n */\n function granularity() public view virtual override returns (uint256) {\n return 1;\n }\n\n /**\n * @dev See {IERC777-totalSupply}.\n */\n function totalSupply() public view virtual override(IERC20, IERC777) returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev Returns the amount of tokens owned by an account (`tokenHolder`).\n */\n function balanceOf(address tokenHolder) public view virtual override(IERC20, IERC777) returns (uint256) {\n return _balances[tokenHolder];\n }\n\n /**\n * @dev See {IERC777-send}.\n *\n * Also emits a {IERC20-Transfer} event for ERC20 compatibility.\n */\n function send(address recipient, uint256 amount, bytes memory data) public virtual override {\n _send(_msgSender(), recipient, amount, data, \"\", true);\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Unlike `send`, `recipient` is _not_ required to implement the {IERC777Recipient}\n * interface if it is a contract.\n *\n * Also emits a {Sent} event.\n */\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n _send(_msgSender(), recipient, amount, \"\", \"\", false);\n return true;\n }\n\n /**\n * @dev See {IERC777-burn}.\n *\n * Also emits a {IERC20-Transfer} event for ERC20 compatibility.\n */\n function burn(uint256 amount, bytes memory data) public virtual override {\n _burn(_msgSender(), amount, data, \"\");\n }\n\n /**\n * @dev See {IERC777-isOperatorFor}.\n */\n function isOperatorFor(address operator, address tokenHolder) public view virtual override returns (bool) {\n return\n operator == tokenHolder ||\n (_defaultOperators[operator] && !_revokedDefaultOperators[tokenHolder][operator]) ||\n _operators[tokenHolder][operator];\n }\n\n /**\n * @dev See {IERC777-authorizeOperator}.\n */\n function authorizeOperator(address operator) public virtual override {\n require(_msgSender() != operator, \"ERC777: authorizing self as operator\");\n\n if (_defaultOperators[operator]) {\n delete _revokedDefaultOperators[_msgSender()][operator];\n } else {\n _operators[_msgSender()][operator] = true;\n }\n\n emit AuthorizedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-revokeOperator}.\n */\n function revokeOperator(address operator) public virtual override {\n require(operator != _msgSender(), \"ERC777: revoking self as operator\");\n\n if (_defaultOperators[operator]) {\n _revokedDefaultOperators[_msgSender()][operator] = true;\n } else {\n delete _operators[_msgSender()][operator];\n }\n\n emit RevokedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-defaultOperators}.\n */\n function defaultOperators() public view virtual override returns (address[] memory) {\n return _defaultOperatorsArray;\n }\n\n /**\n * @dev See {IERC777-operatorSend}.\n *\n * Emits {Sent} and {IERC20-Transfer} events.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes memory data,\n bytes memory operatorData\n ) public virtual override {\n require(isOperatorFor(_msgSender(), sender), \"ERC777: caller is not an operator for holder\");\n _send(sender, recipient, amount, data, operatorData, true);\n }\n\n /**\n * @dev See {IERC777-operatorBurn}.\n *\n * Emits {Burned} and {IERC20-Transfer} events.\n */\n function operatorBurn(\n address account,\n uint256 amount,\n bytes memory data,\n bytes memory operatorData\n ) public virtual override {\n require(isOperatorFor(_msgSender(), account), \"ERC777: caller is not an operator for holder\");\n _burn(account, amount, data, operatorData);\n }\n\n /**\n * @dev See {IERC20-allowance}.\n *\n * Note that operator and allowance concepts are orthogonal: operators may\n * not have allowance, and accounts with allowance may not be operators\n * themselves.\n */\n function allowance(address holder, address spender) public view virtual override returns (uint256) {\n return _allowances[holder][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Note that accounts cannot have allowance issued by their operators.\n */\n function approve(address spender, uint256 value) public virtual override returns (bool) {\n address holder = _msgSender();\n _approve(holder, spender, value);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Note that operator and allowance concepts are orthogonal: operators cannot\n * call `transferFrom` (unless they have allowance), and accounts with\n * allowance cannot call `operatorSend` (unless they are operators).\n *\n * Emits {Sent}, {IERC20-Transfer} and {IERC20-Approval} events.\n */\n function transferFrom(address holder, address recipient, uint256 amount) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(holder, spender, amount);\n _send(holder, recipient, amount, \"\", \"\", false);\n return true;\n }\n\n /**\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with the caller address as the `operator` and with\n * `userData` and `operatorData`.\n *\n * See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits {Minted} and {IERC20-Transfer} events.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - if `account` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function _mint(address account, uint256 amount, bytes memory userData, bytes memory operatorData) internal virtual {\n _mint(account, amount, userData, operatorData, true);\n }\n\n /**\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * If `requireReceptionAck` is set to true, and if a send hook is\n * registered for `account`, the corresponding function will be called with\n * `operator`, `data` and `operatorData`.\n *\n * See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits {Minted} and {IERC20-Transfer} events.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - if `account` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function _mint(\n address account,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) internal virtual {\n require(account != address(0), \"ERC777: mint to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), account, amount);\n\n // Update state variables\n _totalSupply += amount;\n _balances[account] += amount;\n\n _callTokensReceived(operator, address(0), account, amount, userData, operatorData, requireReceptionAck);\n\n emit Minted(operator, account, amount, userData, operatorData);\n emit Transfer(address(0), account, amount);\n }\n\n /**\n * @dev Send tokens\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _send(\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) internal virtual {\n require(from != address(0), \"ERC777: transfer from the zero address\");\n require(to != address(0), \"ERC777: transfer to the zero address\");\n\n address operator = _msgSender();\n\n _callTokensToSend(operator, from, to, amount, userData, operatorData);\n\n _move(operator, from, to, amount, userData, operatorData);\n\n _callTokensReceived(operator, from, to, amount, userData, operatorData, requireReceptionAck);\n }\n\n /**\n * @dev Burn tokens\n * @param from address token holder address\n * @param amount uint256 amount of tokens to burn\n * @param data bytes extra information provided by the token holder\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _burn(address from, uint256 amount, bytes memory data, bytes memory operatorData) internal virtual {\n require(from != address(0), \"ERC777: burn from the zero address\");\n\n address operator = _msgSender();\n\n _callTokensToSend(operator, from, address(0), amount, data, operatorData);\n\n _beforeTokenTransfer(operator, from, address(0), amount);\n\n // Update state variables\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC777: burn amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Burned(operator, from, amount, data, operatorData);\n emit Transfer(from, address(0), amount);\n }\n\n function _move(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n ) private {\n _beforeTokenTransfer(operator, from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC777: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Sent(operator, from, to, amount, userData, operatorData);\n emit Transfer(from, to, amount);\n }\n\n /**\n * @dev See {ERC20-_approve}.\n *\n * Note that accounts cannot have allowance issued by their operators.\n */\n function _approve(address holder, address spender, uint256 value) internal virtual {\n require(holder != address(0), \"ERC777: approve from the zero address\");\n require(spender != address(0), \"ERC777: approve to the zero address\");\n\n _allowances[holder][spender] = value;\n emit Approval(holder, spender, value);\n }\n\n /**\n * @dev Call from.tokensToSend() if the interface is registered\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _callTokensToSend(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n ) private {\n address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(from, _TOKENS_SENDER_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Sender(implementer).tokensToSend(operator, from, to, amount, userData, operatorData);\n }\n }\n\n /**\n * @dev Call to.tokensReceived() if the interface is registered. Reverts if the recipient is a contract but\n * tokensReceived() was not registered for the recipient\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _callTokensReceived(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) private {\n address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(to, _TOKENS_RECIPIENT_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Recipient(implementer).tokensReceived(operator, from, to, amount, userData, operatorData);\n } else if (requireReceptionAck) {\n require(!to.isContract(), \"ERC777: token recipient contract has no implementer for ERC777TokensRecipient\");\n }\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {IERC20-Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC777: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes\n * calls to {send}, {transfer}, {operatorSend}, {transferFrom}, minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be to transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address operator, address from, address to, uint256 amount) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC777/IERC777.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777Token standard as defined in the EIP.\n *\n * This contract uses the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 registry standard] to let\n * token holders and recipients react to token movements by using setting implementers\n * for the associated interfaces in said registry. See {IERC1820Registry} and\n * {ERC1820Implementer}.\n */\ninterface IERC777 {\n /**\n * @dev Emitted when `amount` tokens are created by `operator` and assigned to `to`.\n *\n * Note that some additional user `data` and `operatorData` can be logged in the event.\n */\n event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);\n\n /**\n * @dev Emitted when `operator` destroys `amount` tokens from `account`.\n *\n * Note that some additional user `data` and `operatorData` can be logged in the event.\n */\n event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);\n\n /**\n * @dev Emitted when `operator` is made operator for `tokenHolder`.\n */\n event AuthorizedOperator(address indexed operator, address indexed tokenHolder);\n\n /**\n * @dev Emitted when `operator` is revoked its operator status for `tokenHolder`.\n */\n event RevokedOperator(address indexed operator, address indexed tokenHolder);\n\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, usually a shorter version of the\n * name.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the smallest part of the token that is not divisible. This\n * means all token operations (creation, movement and destruction) must have\n * amounts that are a multiple of this number.\n *\n * For most token contracts, this value will equal 1.\n */\n function granularity() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by an account (`owner`).\n */\n function balanceOf(address owner) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * If send or receive hooks are registered for the caller and `recipient`,\n * the corresponding functions will be called with `data` and empty\n * `operatorData`. See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits a {Sent} event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function send(address recipient, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Destroys `amount` tokens from the caller's account, reducing the\n * total supply.\n *\n * If a send hook is registered for the caller, the corresponding function\n * will be called with `data` and empty `operatorData`. See {IERC777Sender}.\n *\n * Emits a {Burned} event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n */\n function burn(uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Returns true if an account is an operator of `tokenHolder`.\n * Operators can send and burn tokens on behalf of their owners. All\n * accounts are their own operator.\n *\n * See {operatorSend} and {operatorBurn}.\n */\n function isOperatorFor(address operator, address tokenHolder) external view returns (bool);\n\n /**\n * @dev Make an account an operator of the caller.\n *\n * See {isOperatorFor}.\n *\n * Emits an {AuthorizedOperator} event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function authorizeOperator(address operator) external;\n\n /**\n * @dev Revoke an account's operator status for the caller.\n *\n * See {isOperatorFor} and {defaultOperators}.\n *\n * Emits a {RevokedOperator} event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function revokeOperator(address operator) external;\n\n /**\n * @dev Returns the list of default operators. These accounts are operators\n * for all token holders, even if {authorizeOperator} was never called on\n * them.\n *\n * This list is immutable, but individual holders may revoke these via\n * {revokeOperator}, in which case {isOperatorFor} will return false.\n */\n function defaultOperators() external view returns (address[] memory);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must\n * be an operator of `sender`.\n *\n * If send or receive hooks are registered for `sender` and `recipient`,\n * the corresponding functions will be called with `data` and\n * `operatorData`. See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits a {Sent} event.\n *\n * Requirements\n *\n * - `sender` cannot be the zero address.\n * - `sender` must have at least `amount` tokens.\n * - the caller must be an operator for `sender`.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes calldata data,\n bytes calldata operatorData\n ) external;\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the total supply.\n * The caller must be an operator of `account`.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with `data` and `operatorData`. See {IERC777Sender}.\n *\n * Emits a {Burned} event.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n * - the caller must be an operator for `account`.\n */\n function operatorBurn(address account, uint256 amount, bytes calldata data, bytes calldata operatorData) external;\n\n event Sent(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes data,\n bytes operatorData\n );\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\n *\n * Accounts can be notified of {IERC777} tokens being sent to them by having a\n * contract implement this interface (contract holders can be their own\n * implementer) and registering it on the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\n *\n * See {IERC1820Registry} and {ERC1820Implementer}.\n */\ninterface IERC777Recipient {\n /**\n * @dev Called by an {IERC777} token contract whenever tokens are being\n * moved or created into a registered account (`to`). The type of operation\n * is conveyed by `from` being the zero address or not.\n *\n * This call occurs _after_ the token contract's state is updated, so\n * {IERC777-balanceOf}, etc., can be used to query the post-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensReceived(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777Sender.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Sender.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777TokensSender standard as defined in the EIP.\n *\n * {IERC777} Token holders can be notified of operations performed on their\n * tokens by having a contract implement this interface (contract holders can be\n * their own implementer) and registering it on the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\n *\n * See {IERC1820Registry} and {ERC1820Implementer}.\n */\ninterface IERC777Sender {\n /**\n * @dev Called by an {IERC777} token contract whenever a registered holder's\n * (`from`) tokens are about to be moved or destroyed. The type of operation\n * is conveyed by `to` being the zero address or not.\n *\n * This call occurs _before_ the token contract's state is updated, so\n * {IERC777-balanceOf}, etc., can be used to query the pre-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensToSend(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n *\n * Furthermore, `isContract` will also return true if the target contract within\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n * which only has an effect at the end of a transaction.\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Counters.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary Counters {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/ECDSA.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Strings.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV // Deprecated in v4.8\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n /// @solidity memory-safe-assembly\n assembly {\n mstore(0x00, \"\\x19Ethereum Signed Message:\\n32\")\n mstore(0x1c, hash)\n message := keccak256(0x00, 0x3c)\n }\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\n /// @solidity memory-safe-assembly\n assembly {\n let ptr := mload(0x40)\n mstore(ptr, \"\\x19\\x01\")\n mstore(add(ptr, 0x02), domainSeparator)\n mstore(add(ptr, 0x22), structHash)\n data := keccak256(ptr, 0x42)\n }\n }\n\n /**\n * @dev Returns an Ethereum Signed Data with intended validator, created from a\n * `validator` and `data` according to the version 0 of EIP-191.\n *\n * See {recover}.\n */\n function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x00\", validator, data));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/SignatureChecker.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSA.sol\";\nimport \"../../interfaces/IERC1271.sol\";\n\n/**\n * @dev Signature verification helper that can be used instead of `ECDSA.recover` to seamlessly support both ECDSA\n * signatures from externally owned accounts (EOAs) as well as ERC1271 signatures from smart contract wallets like\n * Argent and Gnosis Safe.\n *\n * _Available since v4.1._\n */\nlibrary SignatureChecker {\n /**\n * @dev Checks if a signature is valid for a given signer and data hash. If the signer is a smart contract, the\n * signature is validated against that smart contract using ERC1271, otherwise it's validated using `ECDSA.recover`.\n *\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\n */\n function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature) internal view returns (bool) {\n (address recovered, ECDSA.RecoverError error) = ECDSA.tryRecover(hash, signature);\n return\n (error == ECDSA.RecoverError.NoError && recovered == signer) ||\n isValidERC1271SignatureNow(signer, hash, signature);\n }\n\n /**\n * @dev Checks if a signature is valid for a given signer and data hash. The signature is validated\n * against the signer smart contract using ERC1271.\n *\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\n */\n function isValidERC1271SignatureNow(\n address signer,\n bytes32 hash,\n bytes memory signature\n ) internal view returns (bool) {\n (bool success, bytes memory result) = signer.staticcall(\n abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, signature)\n );\n return (success &&\n result.length >= 32 &&\n abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/ERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165 is IERC165 {\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165).interfaceId;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC1820Registry.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/introspection/IERC1820Registry.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the global ERC1820 Registry, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register\n * implementers for interfaces in this registry, as well as query support.\n *\n * Implementers may be shared by multiple accounts, and can also implement more\n * than a single interface for each account. Contracts can implement interfaces\n * for themselves, but externally-owned accounts (EOA) must delegate this to a\n * contract.\n *\n * {IERC165} interfaces can also be queried via the registry.\n *\n * For an in-depth explanation and source code analysis, see the EIP text.\n */\ninterface IERC1820Registry {\n event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer);\n\n event ManagerChanged(address indexed account, address indexed newManager);\n\n /**\n * @dev Sets `newManager` as the manager for `account`. A manager of an\n * account is able to set interface implementers for it.\n *\n * By default, each account is its own manager. Passing a value of `0x0` in\n * `newManager` will reset the manager to this initial state.\n *\n * Emits a {ManagerChanged} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `account`.\n */\n function setManager(address account, address newManager) external;\n\n /**\n * @dev Returns the manager for `account`.\n *\n * See {setManager}.\n */\n function getManager(address account) external view returns (address);\n\n /**\n * @dev Sets the `implementer` contract as ``account``'s implementer for\n * `interfaceHash`.\n *\n * `account` being the zero address is an alias for the caller's address.\n * The zero address can also be used in `implementer` to remove an old one.\n *\n * See {interfaceHash} to learn how these are created.\n *\n * Emits an {InterfaceImplementerSet} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `account`.\n * - `interfaceHash` must not be an {IERC165} interface id (i.e. it must not\n * end in 28 zeroes).\n * - `implementer` must implement {IERC1820Implementer} and return true when\n * queried for support, unless `implementer` is the caller. See\n * {IERC1820Implementer-canImplementInterfaceForAddress}.\n */\n function setInterfaceImplementer(address account, bytes32 _interfaceHash, address implementer) external;\n\n /**\n * @dev Returns the implementer of `interfaceHash` for `account`. If no such\n * implementer is registered, returns the zero address.\n *\n * If `interfaceHash` is an {IERC165} interface id (i.e. it ends with 28\n * zeroes), `account` will be queried for support of it.\n *\n * `account` being the zero address is an alias for the caller's address.\n */\n function getInterfaceImplementer(address account, bytes32 _interfaceHash) external view returns (address);\n\n /**\n * @dev Returns the interface hash for an `interfaceName`, as defined in the\n * corresponding\n * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP].\n */\n function interfaceHash(string calldata interfaceName) external pure returns (bytes32);\n\n /**\n * @notice Updates the cache with whether the contract implements an ERC165 interface or not.\n * @param account Address of the contract for which to update the cache.\n * @param interfaceId ERC165 interface for which to update the cache.\n */\n function updateERC165Cache(address account, bytes4 interfaceId) external;\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not.\n * If the result is not cached a direct lookup on the contract address is performed.\n * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling\n * {updateERC165Cache} with the contract address.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool);\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not without using or updating the cache.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/math/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\n // The surrounding unchecked block does not change this fact.\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1, \"Math: mulDiv overflow\");\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n //\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n //\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n //\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1 << (log2(a) >> 1);\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = sqrt(a);\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 2, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 128;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 64;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 32;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 16;\n }\n if (value >> 8 > 0) {\n value >>= 8;\n result += 8;\n }\n if (value >> 4 > 0) {\n value >>= 4;\n result += 4;\n }\n if (value >> 2 > 0) {\n value >>= 2;\n result += 2;\n }\n if (value >> 1 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log2(value);\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 10, rounded down, of a positive value.\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 + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 256, rounded down, of a positive value.\n * Returns 0 if given 0.\n *\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n */\n function log256(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 16;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 8;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 4;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 2;\n }\n if (value >> 8 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log256(value);\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/SafeCast.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCast {\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 * _Available since v4.7._\n */\n function toUint248(uint256 value) internal pure returns (uint248) {\n require(value <= type(uint248).max, \"SafeCast: value doesn't fit in 248 bits\");\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 * _Available since v4.7._\n */\n function toUint240(uint256 value) internal pure returns (uint240) {\n require(value <= type(uint240).max, \"SafeCast: value doesn't fit in 240 bits\");\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 * _Available since v4.7._\n */\n function toUint232(uint256 value) internal pure returns (uint232) {\n require(value <= type(uint232).max, \"SafeCast: value doesn't fit in 232 bits\");\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 * _Available since v4.2._\n */\n function toUint224(uint256 value) internal pure returns (uint224) {\n require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\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 * _Available since v4.7._\n */\n function toUint216(uint256 value) internal pure returns (uint216) {\n require(value <= type(uint216).max, \"SafeCast: value doesn't fit in 216 bits\");\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 * _Available since v4.7._\n */\n function toUint208(uint256 value) internal pure returns (uint208) {\n require(value <= type(uint208).max, \"SafeCast: value doesn't fit in 208 bits\");\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 * _Available since v4.7._\n */\n function toUint200(uint256 value) internal pure returns (uint200) {\n require(value <= type(uint200).max, \"SafeCast: value doesn't fit in 200 bits\");\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 * _Available since v4.7._\n */\n function toUint192(uint256 value) internal pure returns (uint192) {\n require(value <= type(uint192).max, \"SafeCast: value doesn't fit in 192 bits\");\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 * _Available since v4.7._\n */\n function toUint184(uint256 value) internal pure returns (uint184) {\n require(value <= type(uint184).max, \"SafeCast: value doesn't fit in 184 bits\");\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 * _Available since v4.7._\n */\n function toUint176(uint256 value) internal pure returns (uint176) {\n require(value <= type(uint176).max, \"SafeCast: value doesn't fit in 176 bits\");\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 * _Available since v4.7._\n */\n function toUint168(uint256 value) internal pure returns (uint168) {\n require(value <= type(uint168).max, \"SafeCast: value doesn't fit in 168 bits\");\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 * _Available since v4.7._\n */\n function toUint160(uint256 value) internal pure returns (uint160) {\n require(value <= type(uint160).max, \"SafeCast: value doesn't fit in 160 bits\");\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 * _Available since v4.7._\n */\n function toUint152(uint256 value) internal pure returns (uint152) {\n require(value <= type(uint152).max, \"SafeCast: value doesn't fit in 152 bits\");\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 * _Available since v4.7._\n */\n function toUint144(uint256 value) internal pure returns (uint144) {\n require(value <= type(uint144).max, \"SafeCast: value doesn't fit in 144 bits\");\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 * _Available since v4.7._\n */\n function toUint136(uint256 value) internal pure returns (uint136) {\n require(value <= type(uint136).max, \"SafeCast: value doesn't fit in 136 bits\");\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 * _Available since v2.5._\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\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 * _Available since v4.7._\n */\n function toUint120(uint256 value) internal pure returns (uint120) {\n require(value <= type(uint120).max, \"SafeCast: value doesn't fit in 120 bits\");\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 * _Available since v4.7._\n */\n function toUint112(uint256 value) internal pure returns (uint112) {\n require(value <= type(uint112).max, \"SafeCast: value doesn't fit in 112 bits\");\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 * _Available since v4.7._\n */\n function toUint104(uint256 value) internal pure returns (uint104) {\n require(value <= type(uint104).max, \"SafeCast: value doesn't fit in 104 bits\");\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 * _Available since v4.2._\n */\n function toUint96(uint256 value) internal pure returns (uint96) {\n require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\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 * _Available since v4.7._\n */\n function toUint88(uint256 value) internal pure returns (uint88) {\n require(value <= type(uint88).max, \"SafeCast: value doesn't fit in 88 bits\");\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 * _Available since v4.7._\n */\n function toUint80(uint256 value) internal pure returns (uint80) {\n require(value <= type(uint80).max, \"SafeCast: value doesn't fit in 80 bits\");\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 * _Available since v4.7._\n */\n function toUint72(uint256 value) internal pure returns (uint72) {\n require(value <= type(uint72).max, \"SafeCast: value doesn't fit in 72 bits\");\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 * _Available since v2.5._\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\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 * _Available since v4.7._\n */\n function toUint56(uint256 value) internal pure returns (uint56) {\n require(value <= type(uint56).max, \"SafeCast: value doesn't fit in 56 bits\");\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 * _Available since v4.7._\n */\n function toUint48(uint256 value) internal pure returns (uint48) {\n require(value <= type(uint48).max, \"SafeCast: value doesn't fit in 48 bits\");\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 * _Available since v4.7._\n */\n function toUint40(uint256 value) internal pure returns (uint40) {\n require(value <= type(uint40).max, \"SafeCast: value doesn't fit in 40 bits\");\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 * _Available since v2.5._\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\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 * _Available since v4.7._\n */\n function toUint24(uint256 value) internal pure returns (uint24) {\n require(value <= type(uint24).max, \"SafeCast: value doesn't fit in 24 bits\");\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 * _Available since v2.5._\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\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 * _Available since v2.5._\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\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 * _Available since v3.0._\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\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 * _Available since v4.7._\n */\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\n downcasted = int248(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 248 bits\");\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 * _Available since v4.7._\n */\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\n downcasted = int240(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 240 bits\");\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 * _Available since v4.7._\n */\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\n downcasted = int232(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 232 bits\");\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 * _Available since v4.7._\n */\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\n downcasted = int224(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 224 bits\");\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 * _Available since v4.7._\n */\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\n downcasted = int216(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 216 bits\");\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 * _Available since v4.7._\n */\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\n downcasted = int208(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 208 bits\");\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 * _Available since v4.7._\n */\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\n downcasted = int200(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 200 bits\");\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 * _Available since v4.7._\n */\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\n downcasted = int192(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 192 bits\");\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 * _Available since v4.7._\n */\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\n downcasted = int184(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 184 bits\");\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 * _Available since v4.7._\n */\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\n downcasted = int176(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 176 bits\");\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 * _Available since v4.7._\n */\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\n downcasted = int168(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 168 bits\");\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 * _Available since v4.7._\n */\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\n downcasted = int160(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 160 bits\");\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 * _Available since v4.7._\n */\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\n downcasted = int152(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 152 bits\");\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 * _Available since v4.7._\n */\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\n downcasted = int144(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 144 bits\");\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 * _Available since v4.7._\n */\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\n downcasted = int136(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 136 bits\");\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 * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\n downcasted = int128(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 128 bits\");\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 * _Available since v4.7._\n */\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\n downcasted = int120(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 120 bits\");\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 * _Available since v4.7._\n */\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\n downcasted = int112(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 112 bits\");\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 * _Available since v4.7._\n */\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\n downcasted = int104(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 104 bits\");\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 * _Available since v4.7._\n */\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\n downcasted = int96(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 96 bits\");\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 * _Available since v4.7._\n */\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\n downcasted = int88(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 88 bits\");\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 * _Available since v4.7._\n */\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\n downcasted = int80(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 80 bits\");\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 * _Available since v4.7._\n */\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\n downcasted = int72(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 72 bits\");\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 * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\n downcasted = int64(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 64 bits\");\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 * _Available since v4.7._\n */\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\n downcasted = int56(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 56 bits\");\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 * _Available since v4.7._\n */\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\n downcasted = int48(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 48 bits\");\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 * _Available since v4.7._\n */\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\n downcasted = int40(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 40 bits\");\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 * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\n downcasted = int32(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 32 bits\");\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 * _Available since v4.7._\n */\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\n downcasted = int24(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 24 bits\");\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 * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\n downcasted = int16(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 16 bits\");\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 * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\n downcasted = int8(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 8 bits\");\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 * _Available since v3.0._\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 require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/SignedMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard signed math utilities missing in the Solidity language.\n */\nlibrary SignedMath {\n /**\n * @dev Returns the largest of two signed numbers.\n */\n function max(int256 a, int256 b) internal pure returns (int256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two signed numbers.\n */\n function min(int256 a, int256 b) internal pure returns (int256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two signed numbers without overflow.\n * The result is rounded towards zero.\n */\n function average(int256 a, int256 b) internal pure returns (int256) {\n // Formula from the book \"Hacker's Delight\"\n int256 x = (a & b) + ((a ^ b) >> 1);\n return x + (int256(uint256(x) >> 255) & (a ^ b));\n }\n\n /**\n * @dev Returns the absolute unsigned value of a signed value.\n */\n function abs(int256 n) internal pure returns (uint256) {\n unchecked {\n // must be unchecked in order to support `n = type(int256).min`\n return uint256(n >= 0 ? n : -n);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/Math.sol\";\nimport \"./math/SignedMath.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n unchecked {\n uint256 length = Math.log10(value) + 1;\n string memory buffer = new string(length);\n uint256 ptr;\n /// @solidity memory-safe-assembly\n assembly {\n ptr := add(buffer, add(32, length))\n }\n while (true) {\n ptr--;\n /// @solidity memory-safe-assembly\n assembly {\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n }\n value /= 10;\n if (value == 0) break;\n }\n return buffer;\n }\n }\n\n /**\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\n */\n function toString(int256 value) internal pure returns (string memory) {\n return string(abi.encodePacked(value < 0 ? \"-\" : \"\", toString(SignedMath.abs(value))));\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n unchecked {\n return toHexString(value, Math.log256(value) + 1);\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n\n /**\n * @dev Returns true if the two strings are equal.\n */\n function equal(string memory a, string memory b) internal pure returns (bool) {\n return keccak256(bytes(a)) == keccak256(bytes(b));\n }\n}\n" + }, + "contracts/aa-4337/core/BaseAccount.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-empty-blocks */\n\nimport \"../interfaces/IAccount.sol\";\nimport \"../interfaces/IEntryPoint.sol\";\nimport \"./Helpers.sol\";\n\n/**\n * Basic account implementation.\n * this contract provides the basic logic for implementing the IAccount interface - validateUserOp\n * specific account implementation should inherit it and provide the account-specific logic\n */\nabstract contract BaseAccount is IAccount {\n using UserOperationLib for UserOperation;\n\n //return value in case of signature failure, with no time-range.\n // equivalent to _packValidationData(true,0,0);\n uint256 internal constant SIG_VALIDATION_FAILED = 1;\n\n /**\n * Return the account nonce.\n * This method returns the next sequential nonce.\n * For a nonce of a specific key, use `entrypoint.getNonce(account, key)`\n */\n function getNonce() public view virtual returns (uint256) {\n return entryPoint().getNonce(address(this), 0);\n }\n\n /**\n * return the entryPoint used by this account.\n * subclass should return the current entryPoint used by this account.\n */\n function entryPoint() public view virtual returns (IEntryPoint);\n\n /**\n * Validate user's signature and nonce.\n * subclass doesn't need to override this method. Instead, it should override the specific internal validation methods.\n */\n function validateUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 missingAccountFunds\n ) external virtual override returns (uint256 validationData) {\n _requireFromEntryPoint();\n validationData = _validateSignature(userOp, userOpHash);\n _validateNonce(userOp.nonce);\n _payPrefund(missingAccountFunds);\n }\n\n /**\n * ensure the request comes from the known entrypoint.\n */\n function _requireFromEntryPoint() internal view virtual {\n require(\n msg.sender == address(entryPoint()),\n \"account: not from EntryPoint\"\n );\n }\n\n /**\n * validate the signature is valid for this message.\n * @param userOp validate the userOp.signature field\n * @param userOpHash convenient field: the hash of the request, to check the signature against\n * (also hashes the entrypoint and chain id)\n * @return validationData signature and time-range of this operation\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * If the account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function _validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) internal virtual returns (uint256 validationData);\n\n /**\n * Validate the nonce of the UserOperation.\n * This method may validate the nonce requirement of this account.\n * e.g.\n * To limit the nonce to use sequenced UserOps only (no \"out of order\" UserOps):\n * `require(nonce < type(uint64).max)`\n * For a hypothetical account that *requires* the nonce to be out-of-order:\n * `require(nonce & type(uint64).max == 0)`\n *\n * The actual nonce uniqueness is managed by the EntryPoint, and thus no other\n * action is needed by the account itself.\n *\n * @param nonce to validate\n *\n * solhint-disable-next-line no-empty-blocks\n */\n function _validateNonce(uint256 nonce) internal view virtual {}\n\n /**\n * sends to the entrypoint (msg.sender) the missing funds for this transaction.\n * subclass MAY override this method for better funds management\n * (e.g. send to the entryPoint more than the minimum required, so that in future transactions\n * it will not be required to send again)\n * @param missingAccountFunds the minimum value this method should send the entrypoint.\n * this value MAY be zero, in case there is enough deposit, or the userOp has a paymaster.\n */\n function _payPrefund(uint256 missingAccountFunds) internal virtual {\n if (missingAccountFunds != 0) {\n (bool success, ) = payable(msg.sender).call{\n value: missingAccountFunds,\n gas: type(uint256).max\n }(\"\");\n (success);\n //ignore failure (its EntryPoint's job to verify, not account.)\n }\n }\n}\n" + }, + "contracts/aa-4337/core/EntryPoint.sol": { + "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n\nimport \"../interfaces/IAccount.sol\";\nimport \"../interfaces/IPaymaster.sol\";\nimport \"../interfaces/IEntryPoint.sol\";\n\nimport \"../utils/Exec.sol\";\nimport \"./StakeManager.sol\";\nimport \"./SenderCreator.sol\";\nimport \"./Helpers.sol\";\nimport \"./NonceManager.sol\";\nimport \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\n\ncontract EntryPoint is\n IEntryPoint,\n StakeManager,\n NonceManager,\n ReentrancyGuard\n{\n using UserOperationLib for UserOperation;\n\n SenderCreator private immutable senderCreator = new SenderCreator();\n\n // internal value used during simulation: need to query aggregator.\n address private constant SIMULATE_FIND_AGGREGATOR = address(1);\n\n // marker for inner call revert on out of gas\n bytes32 private constant INNER_OUT_OF_GAS = hex\"deaddead\";\n\n uint256 private constant REVERT_REASON_MAX_LEN = 2048;\n\n /**\n * for simulation purposes, validateUserOp (and validatePaymasterUserOp) must return this value\n * in case of signature failure, instead of revert.\n */\n uint256 public constant SIG_VALIDATION_FAILED = 1;\n\n /**\n * compensate the caller's beneficiary address with the collected fees of all UserOperations.\n * @param beneficiary the address to receive the fees\n * @param amount amount to transfer.\n */\n function _compensate(address payable beneficiary, uint256 amount) internal {\n require(beneficiary != address(0), \"AA90 invalid beneficiary\");\n (bool success, ) = beneficiary.call{value: amount}(\"\");\n require(success, \"AA91 failed send to beneficiary\");\n }\n\n /**\n * execute a user op\n * @param opIndex index into the opInfo array\n * @param userOp the userOp to execute\n * @param opInfo the opInfo filled by validatePrepayment for this userOp.\n * @return collected the total amount this userOp paid.\n */\n function _executeUserOp(\n uint256 opIndex,\n UserOperation calldata userOp,\n UserOpInfo memory opInfo\n ) private returns (uint256 collected) {\n uint256 preGas = gasleft();\n bytes memory context = getMemoryBytesFromOffset(opInfo.contextOffset);\n\n try this.innerHandleOp(userOp.callData, opInfo, context) returns (\n uint256 _actualGasCost\n ) {\n collected = _actualGasCost;\n } catch {\n bytes32 innerRevertCode;\n assembly {\n returndatacopy(0, 0, 32)\n innerRevertCode := mload(0)\n }\n // handleOps was called with gas limit too low. abort entire bundle.\n if (innerRevertCode == INNER_OUT_OF_GAS) {\n //report paymaster, since if it is not deliberately caused by the bundler,\n // it must be a revert caused by paymaster.\n revert FailedOp(opIndex, \"AA95 out of gas\");\n }\n\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n collected = _handlePostOp(\n opIndex,\n IPaymaster.PostOpMode.postOpReverted,\n opInfo,\n context,\n actualGas\n );\n }\n }\n\n /**\n * Execute a batch of UserOperations.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(\n UserOperation[] calldata ops,\n address payable beneficiary\n ) public nonReentrant {\n uint256 opslen = ops.length;\n UserOpInfo[] memory opInfos = new UserOpInfo[](opslen);\n\n unchecked {\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[i];\n (\n uint256 validationData,\n uint256 pmValidationData\n ) = _validatePrepayment(i, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(\n i,\n validationData,\n pmValidationData,\n address(0)\n );\n }\n\n uint256 collected = 0;\n emit BeforeExecution();\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(i, ops[i], opInfos[i]);\n }\n\n _compensate(beneficiary, collected);\n } //unchecked\n }\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) public nonReentrant {\n uint256 opasLen = opsPerAggregator.length;\n uint256 totalOps = 0;\n for (uint256 i = 0; i < opasLen; i++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[i];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n //address(1) is special marker of \"signature error\"\n require(\n address(aggregator) != address(1),\n \"AA96 invalid aggregator\"\n );\n\n if (address(aggregator) != address(0)) {\n // solhint-disable-next-line no-empty-blocks\n try aggregator.validateSignatures(ops, opa.signature) {} catch {\n revert SignatureValidationFailed(address(aggregator));\n }\n }\n\n totalOps += ops.length;\n }\n\n UserOpInfo[] memory opInfos = new UserOpInfo[](totalOps);\n\n emit BeforeExecution();\n\n uint256 opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n uint256 opslen = ops.length;\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[opIndex];\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(opIndex, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(\n i,\n validationData,\n paymasterValidationData,\n address(aggregator)\n );\n opIndex++;\n }\n }\n\n uint256 collected = 0;\n opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n emit SignatureAggregatorChanged(address(opa.aggregator));\n UserOperation[] calldata ops = opa.userOps;\n uint256 opslen = ops.length;\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(opIndex, ops[i], opInfos[opIndex]);\n opIndex++;\n }\n }\n emit SignatureAggregatorChanged(address(0));\n\n _compensate(beneficiary, collected);\n }\n\n /// @inheritdoc IEntryPoint\n function simulateHandleOp(\n UserOperation calldata op,\n address target,\n bytes calldata targetCallData\n ) external override {\n UserOpInfo memory opInfo;\n _simulationOnlyValidations(op);\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(0, op, opInfo);\n ValidationData memory data = _intersectTimeRange(\n validationData,\n paymasterValidationData\n );\n\n numberMarker();\n uint256 paid = _executeUserOp(0, op, opInfo);\n numberMarker();\n bool targetSuccess;\n bytes memory targetResult;\n if (target != address(0)) {\n (targetSuccess, targetResult) = target.call(targetCallData);\n }\n revert ExecutionResult(\n opInfo.preOpGas,\n paid,\n data.validAfter,\n data.validUntil,\n targetSuccess,\n targetResult\n );\n }\n\n // A memory copy of UserOp static fields only.\n // Excluding: callData, initCode and signature. Replacing paymasterAndData with paymaster.\n struct MemoryUserOp {\n address sender;\n uint256 nonce;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n address paymaster;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n }\n\n struct UserOpInfo {\n MemoryUserOp mUserOp;\n bytes32 userOpHash;\n uint256 prefund;\n uint256 contextOffset;\n uint256 preOpGas;\n }\n\n /**\n * inner function to handle a UserOperation.\n * Must be declared \"external\" to open a call context, but it can only be called by handleOps.\n */\n function innerHandleOp(\n bytes memory callData,\n UserOpInfo memory opInfo,\n bytes calldata context\n ) external returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n require(msg.sender == address(this), \"AA92 internal call only\");\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n\n uint callGasLimit = mUserOp.callGasLimit;\n unchecked {\n // handleOps was called with gas limit too low. abort entire bundle.\n if (\n gasleft() < callGasLimit + mUserOp.verificationGasLimit + 5000\n ) {\n assembly {\n mstore(0, INNER_OUT_OF_GAS)\n revert(0, 32)\n }\n }\n }\n\n IPaymaster.PostOpMode mode = IPaymaster.PostOpMode.opSucceeded;\n if (callData.length > 0) {\n bool success = Exec.call(mUserOp.sender, 0, callData, callGasLimit);\n if (!success) {\n bytes memory result = Exec.getReturnData(REVERT_REASON_MAX_LEN);\n if (result.length > 0) {\n emit UserOperationRevertReason(\n opInfo.userOpHash,\n mUserOp.sender,\n mUserOp.nonce,\n result\n );\n }\n mode = IPaymaster.PostOpMode.opReverted;\n }\n }\n\n unchecked {\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n //note: opIndex is ignored (relevant only if mode==postOpReverted, which is only possible outside of innerHandleOp)\n return _handlePostOp(0, mode, opInfo, context, actualGas);\n }\n }\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(\n UserOperation calldata userOp\n ) public view returns (bytes32) {\n return\n keccak256(abi.encode(userOp.hash(), address(this), block.chainid));\n }\n\n /**\n * copy general fields from userOp into the memory opInfo structure.\n */\n function _copyUserOpToMemory(\n UserOperation calldata userOp,\n MemoryUserOp memory mUserOp\n ) internal pure {\n mUserOp.sender = userOp.sender;\n mUserOp.nonce = userOp.nonce;\n mUserOp.callGasLimit = userOp.callGasLimit;\n mUserOp.verificationGasLimit = userOp.verificationGasLimit;\n mUserOp.preVerificationGas = userOp.preVerificationGas;\n mUserOp.maxFeePerGas = userOp.maxFeePerGas;\n mUserOp.maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes calldata paymasterAndData = userOp.paymasterAndData;\n if (paymasterAndData.length > 0) {\n require(\n paymasterAndData.length >= 20,\n \"AA93 invalid paymasterAndData\"\n );\n mUserOp.paymaster = address(bytes20(paymasterAndData[:20]));\n } else {\n mUserOp.paymaster = address(0);\n }\n }\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external {\n UserOpInfo memory outOpInfo;\n\n _simulationOnlyValidations(userOp);\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(0, userOp, outOpInfo);\n StakeInfo memory paymasterInfo = _getStakeInfo(\n outOpInfo.mUserOp.paymaster\n );\n StakeInfo memory senderInfo = _getStakeInfo(outOpInfo.mUserOp.sender);\n StakeInfo memory factoryInfo;\n {\n bytes calldata initCode = userOp.initCode;\n address factory = initCode.length >= 20\n ? address(bytes20(initCode[0:20]))\n : address(0);\n factoryInfo = _getStakeInfo(factory);\n }\n\n ValidationData memory data = _intersectTimeRange(\n validationData,\n paymasterValidationData\n );\n address aggregator = data.aggregator;\n bool sigFailed = aggregator == address(1);\n ReturnInfo memory returnInfo = ReturnInfo(\n outOpInfo.preOpGas,\n outOpInfo.prefund,\n sigFailed,\n data.validAfter,\n data.validUntil,\n getMemoryBytesFromOffset(outOpInfo.contextOffset)\n );\n\n if (aggregator != address(0) && aggregator != address(1)) {\n AggregatorStakeInfo memory aggregatorInfo = AggregatorStakeInfo(\n aggregator,\n _getStakeInfo(aggregator)\n );\n revert ValidationResultWithAggregation(\n returnInfo,\n senderInfo,\n factoryInfo,\n paymasterInfo,\n aggregatorInfo\n );\n }\n revert ValidationResult(\n returnInfo,\n senderInfo,\n factoryInfo,\n paymasterInfo\n );\n }\n\n function _getRequiredPrefund(\n MemoryUserOp memory mUserOp\n ) internal pure returns (uint256 requiredPrefund) {\n unchecked {\n //when using a Paymaster, the verificationGasLimit is used also to as a limit for the postOp call.\n // our security model might call postOp eventually twice\n uint256 mul = mUserOp.paymaster != address(0) ? 3 : 1;\n uint256 requiredGas = mUserOp.callGasLimit +\n mUserOp.verificationGasLimit *\n mul +\n mUserOp.preVerificationGas;\n\n requiredPrefund = requiredGas * mUserOp.maxFeePerGas;\n }\n }\n\n // create the sender's contract if needed.\n function _createSenderIfNeeded(\n uint256 opIndex,\n UserOpInfo memory opInfo,\n bytes calldata initCode\n ) internal {\n if (initCode.length != 0) {\n address sender = opInfo.mUserOp.sender;\n if (sender.code.length != 0)\n revert FailedOp(opIndex, \"AA10 sender already constructed\");\n address sender1 = senderCreator.createSender{\n gas: opInfo.mUserOp.verificationGasLimit\n }(initCode);\n if (sender1 == address(0))\n revert FailedOp(opIndex, \"AA13 initCode failed or OOG\");\n if (sender1 != sender)\n revert FailedOp(opIndex, \"AA14 initCode must return sender\");\n if (sender1.code.length == 0)\n revert FailedOp(opIndex, \"AA15 initCode must create sender\");\n address factory = address(bytes20(initCode[0:20]));\n emit AccountDeployed(\n opInfo.userOpHash,\n sender,\n factory,\n opInfo.mUserOp.paymaster\n );\n }\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes calldata initCode) public {\n address sender = senderCreator.createSender(initCode);\n revert SenderAddressResult(sender);\n }\n\n function _simulationOnlyValidations(\n UserOperation calldata userOp\n ) internal view {\n // solhint-disable-next-line no-empty-blocks\n try\n this._validateSenderAndPaymaster(\n userOp.initCode,\n userOp.sender,\n userOp.paymasterAndData\n )\n {} catch Error(string memory revertReason) {\n if (bytes(revertReason).length != 0) {\n revert FailedOp(0, revertReason);\n }\n }\n }\n\n /**\n * Called only during simulation.\n * This function always reverts to prevent warm/cold storage differentiation in simulation vs execution.\n */\n function _validateSenderAndPaymaster(\n bytes calldata initCode,\n address sender,\n bytes calldata paymasterAndData\n ) external view {\n if (initCode.length == 0 && sender.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA20 account not deployed\");\n }\n if (paymasterAndData.length >= 20) {\n address paymaster = address(bytes20(paymasterAndData[0:20]));\n if (paymaster.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA30 paymaster not deployed\");\n }\n }\n // always revert\n revert(\"\");\n }\n\n /**\n * call account.validateUserOp.\n * revert (with FailedOp) in case validateUserOp reverts, or account didn't send required prefund.\n * decrement account's deposit if needed\n */\n function _validateAccountPrepayment(\n uint256 opIndex,\n UserOperation calldata op,\n UserOpInfo memory opInfo,\n uint256 requiredPrefund\n )\n internal\n returns (\n uint256 gasUsedByValidateAccountPrepayment,\n uint256 validationData\n )\n {\n unchecked {\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n address sender = mUserOp.sender;\n _createSenderIfNeeded(opIndex, opInfo, op.initCode);\n address paymaster = mUserOp.paymaster;\n numberMarker();\n uint256 missingAccountFunds = 0;\n if (paymaster == address(0)) {\n uint256 bal = balanceOf(sender);\n missingAccountFunds = bal > requiredPrefund\n ? 0\n : requiredPrefund - bal;\n }\n try\n IAccount(sender).validateUserOp{\n gas: mUserOp.verificationGasLimit\n }(op, opInfo.userOpHash, missingAccountFunds)\n returns (uint256 _validationData) {\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA23 reverted: \", revertReason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA23 reverted (or OOG)\");\n }\n if (paymaster == address(0)) {\n DepositInfo storage senderInfo = deposits[sender];\n uint256 deposit = senderInfo.deposit;\n if (requiredPrefund > deposit) {\n revert FailedOp(opIndex, \"AA21 didn't pay prefund\");\n }\n senderInfo.deposit = uint112(deposit - requiredPrefund);\n }\n gasUsedByValidateAccountPrepayment = preGas - gasleft();\n }\n }\n\n /**\n * In case the request has a paymaster:\n * Validate paymaster has enough deposit.\n * Call paymaster.validatePaymasterUserOp.\n * Revert with proper FailedOp in case paymaster reverts.\n * Decrement paymaster's deposit\n */\n function _validatePaymasterPrepayment(\n uint256 opIndex,\n UserOperation calldata op,\n UserOpInfo memory opInfo,\n uint256 requiredPreFund,\n uint256 gasUsedByValidateAccountPrepayment\n ) internal returns (bytes memory context, uint256 validationData) {\n unchecked {\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 verificationGasLimit = mUserOp.verificationGasLimit;\n require(\n verificationGasLimit > gasUsedByValidateAccountPrepayment,\n \"AA41 too little verificationGas\"\n );\n uint256 gas = verificationGasLimit -\n gasUsedByValidateAccountPrepayment;\n\n address paymaster = mUserOp.paymaster;\n DepositInfo storage paymasterInfo = deposits[paymaster];\n uint256 deposit = paymasterInfo.deposit;\n if (deposit < requiredPreFund) {\n revert FailedOp(opIndex, \"AA31 paymaster deposit too low\");\n }\n paymasterInfo.deposit = uint112(deposit - requiredPreFund);\n try\n IPaymaster(paymaster).validatePaymasterUserOp{gas: gas}(\n op,\n opInfo.userOpHash,\n requiredPreFund\n )\n returns (bytes memory _context, uint256 _validationData) {\n context = _context;\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA33 reverted: \", revertReason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA33 reverted (or OOG)\");\n }\n }\n }\n\n /**\n * revert if either account validationData or paymaster validationData is expired\n */\n function _validateAccountAndPaymasterValidationData(\n uint256 opIndex,\n uint256 validationData,\n uint256 paymasterValidationData,\n address expectedAggregator\n ) internal view {\n (address aggregator, bool outOfTimeRange) = _getValidationData(\n validationData\n );\n if (expectedAggregator != aggregator) {\n revert FailedOp(opIndex, \"AA24 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA22 expired or not due\");\n }\n //pmAggregator is not a real signature aggregator: we don't have logic to handle it as address.\n // non-zero address means that the paymaster fails due to some signature check (which is ok only during estimation)\n address pmAggregator;\n (pmAggregator, outOfTimeRange) = _getValidationData(\n paymasterValidationData\n );\n if (pmAggregator != address(0)) {\n revert FailedOp(opIndex, \"AA34 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA32 paymaster expired or not due\");\n }\n }\n\n function _getValidationData(\n uint256 validationData\n ) internal view returns (address aggregator, bool outOfTimeRange) {\n if (validationData == 0) {\n return (address(0), false);\n }\n ValidationData memory data = _parseValidationData(validationData);\n // solhint-disable-next-line not-rely-on-time\n outOfTimeRange =\n block.timestamp > data.validUntil ||\n block.timestamp < data.validAfter;\n aggregator = data.aggregator;\n }\n\n /**\n * validate account and paymaster (if defined).\n * also make sure total validation doesn't exceed verificationGasLimit\n * this method is called off-chain (simulateValidation()) and on-chain (from handleOps)\n * @param opIndex the index of this userOp into the \"opInfos\" array\n * @param userOp the userOp to validate\n */\n function _validatePrepayment(\n uint256 opIndex,\n UserOperation calldata userOp,\n UserOpInfo memory outOpInfo\n )\n private\n returns (uint256 validationData, uint256 paymasterValidationData)\n {\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = outOpInfo.mUserOp;\n _copyUserOpToMemory(userOp, mUserOp);\n outOpInfo.userOpHash = getUserOpHash(userOp);\n\n // validate all numeric values in userOp are well below 128 bit, so they can safely be added\n // and multiplied without causing overflow\n uint256 maxGasValues = mUserOp.preVerificationGas |\n mUserOp.verificationGasLimit |\n mUserOp.callGasLimit |\n userOp.maxFeePerGas |\n userOp.maxPriorityFeePerGas;\n require(maxGasValues <= type(uint120).max, \"AA94 gas values overflow\");\n\n uint256 gasUsedByValidateAccountPrepayment;\n uint256 requiredPreFund = _getRequiredPrefund(mUserOp);\n (\n gasUsedByValidateAccountPrepayment,\n validationData\n ) = _validateAccountPrepayment(\n opIndex,\n userOp,\n outOpInfo,\n requiredPreFund\n );\n\n if (!_validateAndUpdateNonce(mUserOp.sender, mUserOp.nonce)) {\n revert FailedOp(opIndex, \"AA25 invalid account nonce\");\n }\n\n //a \"marker\" where account opcode validation is done and paymaster opcode validation is about to start\n // (used only by off-chain simulateValidation)\n numberMarker();\n\n bytes memory context;\n if (mUserOp.paymaster != address(0)) {\n (context, paymasterValidationData) = _validatePaymasterPrepayment(\n opIndex,\n userOp,\n outOpInfo,\n requiredPreFund,\n gasUsedByValidateAccountPrepayment\n );\n }\n unchecked {\n uint256 gasUsed = preGas - gasleft();\n\n if (userOp.verificationGasLimit < gasUsed) {\n revert FailedOp(opIndex, \"AA40 over verificationGasLimit\");\n }\n outOpInfo.prefund = requiredPreFund;\n outOpInfo.contextOffset = getOffsetOfMemoryBytes(context);\n outOpInfo.preOpGas = preGas - gasleft() + userOp.preVerificationGas;\n }\n }\n\n /**\n * process post-operation.\n * called just after the callData is executed.\n * if a paymaster is defined and its validation returned a non-empty context, its postOp is called.\n * the excess amount is refunded to the account (or paymaster - if it was used in the request)\n * @param opIndex index in the batch\n * @param mode - whether is called from innerHandleOp, or outside (postOpReverted)\n * @param opInfo userOp fields and info collected during validation\n * @param context the context returned in validatePaymasterUserOp\n * @param actualGas the gas used so far by this user operation\n */\n function _handlePostOp(\n uint256 opIndex,\n IPaymaster.PostOpMode mode,\n UserOpInfo memory opInfo,\n bytes memory context,\n uint256 actualGas\n ) private returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n unchecked {\n address refundAddress;\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 gasPrice = getUserOpGasPrice(mUserOp);\n\n address paymaster = mUserOp.paymaster;\n if (paymaster == address(0)) {\n refundAddress = mUserOp.sender;\n } else {\n refundAddress = paymaster;\n if (context.length > 0) {\n actualGasCost = actualGas * gasPrice;\n if (mode != IPaymaster.PostOpMode.postOpReverted) {\n IPaymaster(paymaster).postOp{\n gas: mUserOp.verificationGasLimit\n }(mode, context, actualGasCost);\n } else {\n // solhint-disable-next-line no-empty-blocks\n try\n IPaymaster(paymaster).postOp{\n gas: mUserOp.verificationGasLimit\n }(mode, context, actualGasCost)\n {} catch Error(string memory reason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA50 postOp reverted: \", reason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA50 postOp revert\");\n }\n }\n }\n }\n actualGas += preGas - gasleft();\n actualGasCost = actualGas * gasPrice;\n if (opInfo.prefund < actualGasCost) {\n revert FailedOp(opIndex, \"AA51 prefund below actualGasCost\");\n }\n uint256 refund = opInfo.prefund - actualGasCost;\n _incrementDeposit(refundAddress, refund);\n bool success = mode == IPaymaster.PostOpMode.opSucceeded;\n emit UserOperationEvent(\n opInfo.userOpHash,\n mUserOp.sender,\n mUserOp.paymaster,\n mUserOp.nonce,\n success,\n actualGasCost,\n actualGas\n );\n } // unchecked\n }\n\n /**\n * the gas price this UserOp agrees to pay.\n * relayer/block builder might submit the TX with higher priorityFee, but the user should not\n */\n function getUserOpGasPrice(\n MemoryUserOp memory mUserOp\n ) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = mUserOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = mUserOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n function getOffsetOfMemoryBytes(\n bytes memory data\n ) internal pure returns (uint256 offset) {\n assembly {\n offset := data\n }\n }\n\n function getMemoryBytesFromOffset(\n uint256 offset\n ) internal pure returns (bytes memory data) {\n assembly {\n data := offset\n }\n }\n\n //place the NUMBER opcode in the code.\n // this is used as a marker during simulation, as this OP is completely banned from the simulated code of the\n // account and paymaster.\n function numberMarker() internal view {\n assembly {\n mstore(0, number())\n }\n }\n}\n" + }, + "contracts/aa-4337/core/Helpers.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable no-inline-assembly */\n\n/**\n * returned data from validateUserOp.\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\n * @param aggregator - address(0) - the account validated the signature by itself.\n * address(1) - the account failed to validate the signature.\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\n * @param validAfter - this UserOp is valid only after this timestamp.\n * @param validaUntil - this UserOp is valid only up to this timestamp.\n */\nstruct ValidationData {\n address aggregator;\n uint48 validAfter;\n uint48 validUntil;\n}\n\n//extract sigFailed, validAfter, validUntil.\n// also convert zero validUntil to type(uint48).max\nfunction _parseValidationData(\n uint validationData\n) pure returns (ValidationData memory data) {\n address aggregator = address(uint160(validationData));\n uint48 validUntil = uint48(validationData >> 160);\n if (validUntil == 0) {\n validUntil = type(uint48).max;\n }\n uint48 validAfter = uint48(validationData >> (48 + 160));\n return ValidationData(aggregator, validAfter, validUntil);\n}\n\n// intersect account and paymaster ranges.\nfunction _intersectTimeRange(\n uint256 validationData,\n uint256 paymasterValidationData\n) pure returns (ValidationData memory) {\n ValidationData memory accountValidationData = _parseValidationData(\n validationData\n );\n ValidationData memory pmValidationData = _parseValidationData(\n paymasterValidationData\n );\n address aggregator = accountValidationData.aggregator;\n if (aggregator == address(0)) {\n aggregator = pmValidationData.aggregator;\n }\n uint48 validAfter = accountValidationData.validAfter;\n uint48 validUntil = accountValidationData.validUntil;\n uint48 pmValidAfter = pmValidationData.validAfter;\n uint48 pmValidUntil = pmValidationData.validUntil;\n\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\n return ValidationData(aggregator, validAfter, validUntil);\n}\n\n/**\n * helper to pack the return value for validateUserOp\n * @param data - the ValidationData to pack\n */\nfunction _packValidationData(\n ValidationData memory data\n) pure returns (uint256) {\n return\n uint160(data.aggregator) |\n (uint256(data.validUntil) << 160) |\n (uint256(data.validAfter) << (160 + 48));\n}\n\n/**\n * helper to pack the return value for validateUserOp, when not using an aggregator\n * @param sigFailed - true for signature failure, false for success\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\n * @param validAfter first timestamp this UserOperation is valid\n */\nfunction _packValidationData(\n bool sigFailed,\n uint48 validUntil,\n uint48 validAfter\n) pure returns (uint256) {\n return\n (sigFailed ? 1 : 0) |\n (uint256(validUntil) << 160) |\n (uint256(validAfter) << (160 + 48));\n}\n\n/**\n * keccak function over calldata.\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\n */\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\n assembly {\n let mem := mload(0x40)\n let len := data.length\n calldatacopy(mem, data.offset, len)\n ret := keccak256(mem, len)\n }\n}\n" + }, + "contracts/aa-4337/core/NonceManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\nimport \"../interfaces/IEntryPoint.sol\";\n\n/**\n * nonce management functionality\n */\ncontract NonceManager is INonceManager {\n /**\n * The next valid sequence number for a given nonce key.\n */\n mapping(address => mapping(uint192 => uint256)) public nonceSequenceNumber;\n\n function getNonce(\n address sender,\n uint192 key\n ) public view override returns (uint256 nonce) {\n return nonceSequenceNumber[sender][key] | (uint256(key) << 64);\n }\n\n // allow an account to manually increment its own nonce.\n // (mainly so that during construction nonce can be made non-zero,\n // to \"absorb\" the gas cost of first nonce increment to 1st transaction (construction),\n // not to 2nd transaction)\n function incrementNonce(uint192 key) public override {\n nonceSequenceNumber[msg.sender][key]++;\n }\n\n /**\n * validate nonce uniqueness for this account.\n * called just after validateUserOp()\n */\n function _validateAndUpdateNonce(\n address sender,\n uint256 nonce\n ) internal returns (bool) {\n uint192 key = uint192(nonce >> 64);\n uint64 seq = uint64(nonce);\n return nonceSequenceNumber[sender][key]++ == seq;\n }\n}\n" + }, + "contracts/aa-4337/core/SenderCreator.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/**\n * helper contract for EntryPoint, to call userOp.initCode from a \"neutral\" address,\n * which is explicitly not the entryPoint itself.\n */\ncontract SenderCreator {\n /**\n * call the \"initCode\" factory to create and return the sender account address\n * @param initCode the initCode value from a UserOp. contains 20 bytes of factory address, followed by calldata\n * @return sender the returned address of the created account, or zero address on failure.\n */\n function createSender(\n bytes calldata initCode\n ) external returns (address sender) {\n address factory = address(bytes20(initCode[0:20]));\n bytes memory initCallData = initCode[20:];\n bool success;\n /* solhint-disable no-inline-assembly */\n assembly {\n success := call(\n gas(),\n factory,\n 0,\n add(initCallData, 0x20),\n mload(initCallData),\n 0,\n 32\n )\n sender := mload(0)\n }\n if (!success) {\n sender = address(0);\n }\n }\n}\n" + }, + "contracts/aa-4337/core/StakeManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity 0.8.21;\n\nimport \"../interfaces/IStakeManager.sol\";\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable not-rely-on-time */\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by a paymaster.\n */\nabstract contract StakeManager is IStakeManager {\n /// maps paymaster to their deposits and stakes\n mapping(address => DepositInfo) public deposits;\n\n /// @inheritdoc IStakeManager\n function getDepositInfo(\n address account\n ) public view returns (DepositInfo memory info) {\n return deposits[account];\n }\n\n // internal method to return just the stake info\n function _getStakeInfo(\n address addr\n ) internal view returns (StakeInfo memory info) {\n DepositInfo storage depositInfo = deposits[addr];\n info.stake = depositInfo.stake;\n info.unstakeDelaySec = depositInfo.unstakeDelaySec;\n }\n\n /// return the deposit (for gas payment) of the account\n function balanceOf(address account) public view returns (uint256) {\n return deposits[account].deposit;\n }\n\n receive() external payable {\n depositTo(msg.sender);\n }\n\n function _incrementDeposit(address account, uint256 amount) internal {\n DepositInfo storage info = deposits[account];\n uint256 newAmount = info.deposit + amount;\n require(newAmount <= type(uint112).max, \"deposit overflow\");\n info.deposit = uint112(newAmount);\n }\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) public payable {\n _incrementDeposit(account, msg.value);\n DepositInfo storage info = deposits[account];\n emit Deposited(account, info.deposit);\n }\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 unstakeDelaySec) public payable {\n DepositInfo storage info = deposits[msg.sender];\n require(unstakeDelaySec > 0, \"must specify unstake delay\");\n require(\n unstakeDelaySec >= info.unstakeDelaySec,\n \"cannot decrease unstake time\"\n );\n uint256 stake = info.stake + msg.value;\n require(stake > 0, \"no stake specified\");\n require(stake <= type(uint112).max, \"stake overflow\");\n deposits[msg.sender] = DepositInfo(\n info.deposit,\n true,\n uint112(stake),\n unstakeDelaySec,\n 0\n );\n emit StakeLocked(msg.sender, stake, unstakeDelaySec);\n }\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external {\n DepositInfo storage info = deposits[msg.sender];\n require(info.unstakeDelaySec != 0, \"not staked\");\n require(info.staked, \"already unstaking\");\n uint48 withdrawTime = uint48(block.timestamp) + info.unstakeDelaySec;\n info.withdrawTime = withdrawTime;\n info.staked = false;\n emit StakeUnlocked(msg.sender, withdrawTime);\n }\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external {\n DepositInfo storage info = deposits[msg.sender];\n uint256 stake = info.stake;\n require(stake > 0, \"No stake to withdraw\");\n require(info.withdrawTime > 0, \"must call unlockStake() first\");\n require(\n info.withdrawTime <= block.timestamp,\n \"Stake withdrawal is not due\"\n );\n info.unstakeDelaySec = 0;\n info.withdrawTime = 0;\n info.stake = 0;\n emit StakeWithdrawn(msg.sender, withdrawAddress, stake);\n (bool success, ) = withdrawAddress.call{value: stake}(\"\");\n require(success, \"failed to withdraw stake\");\n }\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(\n address payable withdrawAddress,\n uint256 withdrawAmount\n ) external {\n DepositInfo storage info = deposits[msg.sender];\n require(withdrawAmount <= info.deposit, \"Withdraw amount too large\");\n info.deposit = uint112(info.deposit - withdrawAmount);\n emit Withdrawn(msg.sender, withdrawAddress, withdrawAmount);\n (bool success, ) = withdrawAddress.call{value: withdrawAmount}(\"\");\n require(success, \"failed to withdraw\");\n }\n}\n" + }, + "contracts/aa-4337/interfaces/IAccount.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\ninterface IAccount {\n /**\n * Validate user's signature and nonce\n * the entryPoint will make the call to the recipient only if this validation call returns successfully.\n * signature failure should be reported by returning SIG_VALIDATION_FAILED (1).\n * This allows making a \"simulation call\" without a valid signature\n * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure.\n *\n * @dev Must validate caller is the entryPoint.\n * Must validate the signature and nonce\n * @param userOp the operation that is about to be executed.\n * @param userOpHash hash of the user's request data. can be used as the basis for signature.\n * @param missingAccountFunds missing funds on the account's deposit in the entrypoint.\n * This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call.\n * The excess is left as a deposit in the entrypoint, for future calls.\n * can be withdrawn anytime using \"entryPoint.withdrawTo()\"\n * In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero.\n * @return validationData packaged ValidationData structure. use `_packValidationData` and `_unpackValidationData` to encode and decode\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * If an account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validateUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 missingAccountFunds\n ) external returns (uint256 validationData);\n}\n" + }, + "contracts/aa-4337/interfaces/IAggregator.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * Aggregated Signatures validator.\n */\ninterface IAggregator {\n /**\n * validate aggregated signature.\n * revert if the aggregated signature does not match the given list of operations.\n */\n function validateSignatures(\n UserOperation[] calldata userOps,\n bytes calldata signature\n ) external view;\n\n /**\n * validate signature of a single userOp\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\n * @param userOp the userOperation received from the user.\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\n * (usually empty, unless account and aggregator support some kind of \"multisig\"\n */\n function validateUserOpSignature(\n UserOperation calldata userOp\n ) external view returns (bytes memory sigForUserOp);\n\n /**\n * aggregate multiple signatures into a single value.\n * This method is called off-chain to calculate the signature to pass with handleOps()\n * bundler MAY use optimized custom code perform this aggregation\n * @param userOps array of UserOperations to collect the signatures from.\n * @return aggregatedSignature the aggregated signature\n */\n function aggregateSignatures(\n UserOperation[] calldata userOps\n ) external view returns (bytes memory aggregatedSignature);\n}\n" + }, + "contracts/aa-4337/interfaces/IEntryPoint.sol": { + "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n/* solhint-disable reason-string */\n\nimport \"./UserOperation.sol\";\nimport \"./IStakeManager.sol\";\nimport \"./IAggregator.sol\";\nimport \"./INonceManager.sol\";\n\ninterface IEntryPoint is IStakeManager, INonceManager {\n /***\n * An event emitted after each successful request\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\n * @param sender - the account that generates this request.\n * @param paymaster - if non-null, the paymaster that pays for this request.\n * @param nonce - the nonce value from the request.\n * @param success - true if the sender transaction succeeded, false if reverted.\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\n */\n event UserOperationEvent(\n bytes32 indexed userOpHash,\n address indexed sender,\n address indexed paymaster,\n uint256 nonce,\n bool success,\n uint256 actualGasCost,\n uint256 actualGasUsed\n );\n\n /**\n * account \"sender\" was deployed.\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\n * @param sender the account that is deployed\n * @param factory the factory used to deploy this account (in the initCode)\n * @param paymaster the paymaster used by this UserOp\n */\n event AccountDeployed(\n bytes32 indexed userOpHash,\n address indexed sender,\n address factory,\n address paymaster\n );\n\n /**\n * An event emitted if the UserOperation \"callData\" reverted with non-zero length\n * @param userOpHash the request unique identifier.\n * @param sender the sender of this request\n * @param nonce the nonce used in the request\n * @param revertReason - the return bytes from the (reverted) call to \"callData\".\n */\n event UserOperationRevertReason(\n bytes32 indexed userOpHash,\n address indexed sender,\n uint256 nonce,\n bytes revertReason\n );\n\n /**\n * an event emitted by handleOps(), before starting the execution loop.\n * any event emitted before this event, is part of the validation.\n */\n event BeforeExecution();\n\n /**\n * signature aggregator used by the following UserOperationEvents within this bundle.\n */\n event SignatureAggregatorChanged(address indexed aggregator);\n\n /**\n * a custom revert error of handleOps, to identify the offending op.\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\n * @param reason - revert reason\n * The string starts with a unique code \"AAmn\", where \"m\" is \"1\" for factory, \"2\" for account and \"3\" for paymaster issues,\n * so a failure can be attributed to the correct entity.\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\n */\n error FailedOp(uint256 opIndex, string reason);\n\n /**\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\n */\n error SignatureValidationFailed(address aggregator);\n\n /**\n * Successful result from simulateValidation.\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n */\n error ValidationResult(\n ReturnInfo returnInfo,\n StakeInfo senderInfo,\n StakeInfo factoryInfo,\n StakeInfo paymasterInfo\n );\n\n /**\n * Successful result from simulateValidation, if the account returns a signature aggregator\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\n * bundler MUST use it to verify the signature, or reject the UserOperation\n */\n error ValidationResultWithAggregation(\n ReturnInfo returnInfo,\n StakeInfo senderInfo,\n StakeInfo factoryInfo,\n StakeInfo paymasterInfo,\n AggregatorStakeInfo aggregatorInfo\n );\n\n /**\n * return value of getSenderAddress\n */\n error SenderAddressResult(address sender);\n\n /**\n * return value of simulateHandleOp\n */\n error ExecutionResult(\n uint256 preOpGas,\n uint256 paid,\n uint48 validAfter,\n uint48 validUntil,\n bool targetSuccess,\n bytes targetResult\n );\n\n //UserOps handled, per aggregator\n struct UserOpsPerAggregator {\n UserOperation[] userOps;\n // aggregator address\n IAggregator aggregator;\n // aggregated signature\n bytes signature;\n }\n\n /**\n * Execute a batch of UserOperation.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(\n UserOperation[] calldata ops,\n address payable beneficiary\n ) external;\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) external;\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(\n UserOperation calldata userOp\n ) external view returns (bytes32);\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external;\n\n /**\n * gas and return values during simulation\n * @param preOpGas the gas used for validation (including preValidationGas)\n * @param prefund the required prefund for this operation\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\n */\n struct ReturnInfo {\n uint256 preOpGas;\n uint256 prefund;\n bool sigFailed;\n uint48 validAfter;\n uint48 validUntil;\n bytes paymasterContext;\n }\n\n /**\n * returned aggregated signature info.\n * the aggregator returned by the account, and its current stake.\n */\n struct AggregatorStakeInfo {\n address aggregator;\n StakeInfo stakeInfo;\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes memory initCode) external;\n\n /**\n * simulate full execution of a UserOperation (including both validation and target execution)\n * this method will always revert with \"ExecutionResult\".\n * it performs full validation of the UserOperation, but ignores signature error.\n * an optional target address is called after the userop succeeds, and its value is returned\n * (before the entire call is reverted)\n * Note that in order to collect the the success/failure of the target call, it must be executed\n * with trace enabled to track the emitted events.\n * @param op the UserOperation to simulate\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\n * are set to the return from that call.\n * @param targetCallData callData to pass to target address\n */\n function simulateHandleOp(\n UserOperation calldata op,\n address target,\n bytes calldata targetCallData\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/INonceManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\ninterface INonceManager {\n /**\n * Return the next nonce for this sender.\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\n * But UserOp with different keys can come with arbitrary order.\n *\n * @param sender the account address\n * @param key the high 192 bit of the nonce\n * @return nonce a full nonce to pass for next UserOp with this sender.\n */\n function getNonce(\n address sender,\n uint192 key\n ) external view returns (uint256 nonce);\n\n /**\n * Manually increment the nonce of the sender.\n * This method is exposed just for completeness..\n * Account does NOT need to call it, neither during validation, nor elsewhere,\n * as the EntryPoint will update the nonce regardless.\n * Possible use-case is call it with various keys to \"initialize\" their nonces to one, so that future\n * UserOperations will not pay extra for the first transaction with a given key.\n */\n function incrementNonce(uint192 key) external;\n}\n" + }, + "contracts/aa-4337/interfaces/IPaymaster.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * the interface exposed by a paymaster contract, who agrees to pay the gas for user's operations.\n * a paymaster must hold a stake to cover the required entrypoint stake and also the gas for the transaction.\n */\ninterface IPaymaster {\n enum PostOpMode {\n opSucceeded, // user op succeeded\n opReverted, // user op reverted. still has to pay for gas.\n postOpReverted //user op succeeded, but caused postOp to revert. Now it's a 2nd call, after user's op was deliberately reverted.\n }\n\n /**\n * payment validation: check if paymaster agrees to pay.\n * Must verify sender is the entryPoint.\n * Revert to reject this request.\n * Note that bundlers will reject this method if it changes the state, unless the paymaster is trusted (whitelisted)\n * The paymaster pre-pays using its deposit, and receive back a refund after the postOp method returns.\n * @param userOp the user operation\n * @param userOpHash hash of the user's request data.\n * @param maxCost the maximum cost of this transaction (based on maximum gas and gas price from userOp)\n * @return context value to send to a postOp\n * zero length to signify postOp is not required.\n * @return validationData signature and time-range of this operation, encoded the same as the return value of validateUserOperation\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validatePaymasterUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 maxCost\n ) external returns (bytes memory context, uint256 validationData);\n\n /**\n * post-operation handler.\n * Must verify sender is the entryPoint\n * @param mode enum with the following options:\n * opSucceeded - user operation succeeded.\n * opReverted - user op reverted. still has to pay for gas.\n * postOpReverted - user op succeeded, but caused postOp (in mode=opSucceeded) to revert.\n * Now this is the 2nd call, after user's op was deliberately reverted.\n * @param context - the context value returned by validatePaymasterUserOp\n * @param actualGasCost - actual gas used so far (without this postOp call).\n */\n function postOp(\n PostOpMode mode,\n bytes calldata context,\n uint256 actualGasCost\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/IStakeManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.12;\n\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by the staked entity.\n */\ninterface IStakeManager {\n event Deposited(address indexed account, uint256 totalDeposit);\n\n event Withdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /// Emitted when stake or unstake delay are modified\n event StakeLocked(\n address indexed account,\n uint256 totalStaked,\n uint256 unstakeDelaySec\n );\n\n /// Emitted once a stake is scheduled for withdrawal\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\n\n event StakeWithdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /**\n * @param deposit the entity's deposit\n * @param staked true if this entity is staked.\n * @param stake actual amount of ether staked for this entity.\n * @param unstakeDelaySec minimum delay to withdraw the stake.\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\n * and the rest fit into a 2nd cell.\n * 112 bit allows for 10^15 eth\n * 48 bit for full timestamp\n * 32 bit allows 150 years for unstake delay\n */\n struct DepositInfo {\n uint112 deposit;\n bool staked;\n uint112 stake;\n uint32 unstakeDelaySec;\n uint48 withdrawTime;\n }\n\n //API struct used by getStakeInfo and simulateValidation\n struct StakeInfo {\n uint256 stake;\n uint256 unstakeDelaySec;\n }\n\n /// @return info - full deposit information of given account\n function getDepositInfo(\n address account\n ) external view returns (DepositInfo memory info);\n\n /// @return the deposit (for gas payment) of the account\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) external payable;\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 _unstakeDelaySec) external payable;\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external;\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external;\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(\n address payable withdrawAddress,\n uint256 withdrawAmount\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/UserOperation.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable no-inline-assembly */\n\nimport {calldataKeccak} from \"../core/Helpers.sol\";\n\n/**\n * User Operation struct\n * @param sender the sender account of this request.\n * @param nonce unique value the sender uses to verify it is not a replay.\n * @param initCode if set, the account contract will be created by this constructor/\n * @param callData the method call to execute on this account.\n * @param callGasLimit the gas limit passed to the callData method call.\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\n * @param maxFeePerGas same as EIP-1559 gas parameter.\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\n */\nstruct UserOperation {\n address sender;\n uint256 nonce;\n bytes initCode;\n bytes callData;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n bytes paymasterAndData;\n bytes signature;\n}\n\n/**\n * Utility functions helpful when working with UserOperation structs.\n */\nlibrary UserOperationLib {\n function getSender(\n UserOperation calldata userOp\n ) internal pure returns (address) {\n address data;\n //read sender from userOp, which is first userOp member (saves 800 gas...)\n assembly {\n data := calldataload(userOp)\n }\n return address(uint160(data));\n }\n\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\n // pay above what he signed for.\n function gasPrice(\n UserOperation calldata userOp\n ) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function pack(\n UserOperation calldata userOp\n ) internal pure returns (bytes memory ret) {\n address sender = getSender(userOp);\n uint256 nonce = userOp.nonce;\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\n bytes32 hashCallData = calldataKeccak(userOp.callData);\n uint256 callGasLimit = userOp.callGasLimit;\n uint256 verificationGasLimit = userOp.verificationGasLimit;\n uint256 preVerificationGas = userOp.preVerificationGas;\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\n\n return\n abi.encode(\n sender,\n nonce,\n hashInitCode,\n hashCallData,\n callGasLimit,\n verificationGasLimit,\n preVerificationGas,\n maxFeePerGas,\n maxPriorityFeePerGas,\n hashPaymasterAndData\n );\n }\n\n function hash(\n UserOperation calldata userOp\n ) internal pure returns (bytes32) {\n return keccak256(pack(userOp));\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n}\n" + }, + "contracts/aa-4337/utils/Exec.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.5 <0.9.0;\n\n// solhint-disable no-inline-assembly\n\n/**\n * Utility functions helpful when making different kinds of contract calls in Solidity.\n */\nlibrary Exec {\n function call(\n address to,\n uint256 value,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := call(\n txGas,\n to,\n value,\n add(data, 0x20),\n mload(data),\n 0,\n 0\n )\n }\n }\n\n function staticcall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal view returns (bool success) {\n assembly {\n success := staticcall(txGas, to, add(data, 0x20), mload(data), 0, 0)\n }\n }\n\n function delegateCall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := delegatecall(\n txGas,\n to,\n add(data, 0x20),\n mload(data),\n 0,\n 0\n )\n }\n }\n\n // get returned data from last call or calldelegate\n function getReturnData(\n uint256 maxLen\n ) internal pure returns (bytes memory returnData) {\n assembly {\n let len := returndatasize()\n if gt(len, maxLen) {\n len := maxLen\n }\n let ptr := mload(0x40)\n mstore(0x40, add(ptr, add(len, 0x20)))\n mstore(ptr, len)\n returndatacopy(add(ptr, 0x20), 0, len)\n returnData := ptr\n }\n }\n\n // revert with explicit byte array (probably reverted info from call)\n function revertWithData(bytes memory returnData) internal pure {\n assembly {\n revert(add(returnData, 32), mload(returnData))\n }\n }\n\n function callAndRevert(\n address to,\n bytes memory data,\n uint256 maxLen\n ) internal {\n bool success = call(to, 0, data, gasleft());\n if (!success) {\n revertWithData(getReturnData(maxLen));\n }\n }\n}\n" + }, + "contracts/Barz.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"./libraries/LibDiamond.sol\";\nimport {IBarz} from \"./interfaces/IBarz.sol\";\n\n/**\n * @title Barz\n * @dev A diamond proxy wallet with a modular & upgradeable architecture\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract Barz is IBarz {\n /**\n * @notice Initializes Barz with the given parameters. Barz account is intended to be created from Barz Factory for stable deployment.\n * @dev This method makes a delegate call to account facet and account facet handles the initialization.\n * With modular architecture, Barz encompasses wide spectrum of architecture and logic.\n * The only requirement is account facet to comply with initialize() interface.\n * Barz doesn't include built-in functions and is a full proxy, for maximum extensibility and modularity.\n * @param _accountFacet Address of Account Facet in charge of the Barz initialization\n * @param _verificationFacet Address of Verification Facet for verifying the signature. Could be any signature scheme\n * @param _entryPoint Address of Entry Point contract\n * @param _facetRegistry Address of Facet Registry. Facet Registry is a registry holding trusted facets that could be added to user's wallet\n * @param _defaultFallBack Address of Default FallBack Handler. Middleware contract for more efficient deployment\n * @param _ownerPublicKey Bytes of Owner Public Key using for initialization\n */\n constructor(\n address _accountFacet,\n address _verificationFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallBack,\n bytes memory _ownerPublicKey\n ) payable {\n bytes memory initCall = abi.encodeWithSignature(\n \"initialize(address,address,address,address,bytes)\",\n _verificationFacet,\n _entryPoint,\n _facetRegistry,\n _defaultFallBack,\n _ownerPublicKey\n );\n (bool success, bytes memory result) = _accountFacet.delegatecall(\n initCall\n );\n if (!success || uint256(bytes32(result)) != 1) {\n revert Barz__InitializationFailure();\n }\n }\n\n /**\n * @notice Fallback function for Barz complying with Diamond Standard with customization of adding Default Fallback Handler\n * @dev Find facet for function that is called and execute the function if a facet is found and return any value.\n */\n fallback() external payable {\n LibDiamond.DiamondStorage storage ds;\n bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION;\n // get diamond storage\n assembly {\n ds.slot := position\n }\n // get facet from function selector\n address facet = address(bytes20(ds.facets[msg.sig]));\n if (facet == address(0))\n facet = ds.defaultFallbackHandler.facetAddress(msg.sig);\n require(facet != address(0), \"Barz: Function does not exist\");\n // Execute external function from facet using delegatecall and return any value.\n assembly {\n // copy function selector and any arguments\n calldatacopy(0, 0, calldatasize())\n // execute function call using the facet\n let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)\n // get any return value\n returndatacopy(0, 0, returndatasize())\n // return any return value or error back to the caller\n switch result\n case 0 {\n revert(0, returndatasize())\n }\n default {\n return(0, returndatasize())\n }\n }\n }\n\n /**\n * @notice Receive function to receive native token without data\n */\n receive() external payable {}\n}\n" + }, + "contracts/BarzFactory.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Barz} from \"./Barz.sol\";\nimport {IBarzFactory} from \"./interfaces/IBarzFactory.sol\";\n\n/**\n * @title Barz Factory\n * @dev Contract to easily deploy Barz to a pre-computed address with a single call\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract BarzFactory is IBarzFactory {\n event BarzDeployed(address);\n\n address public immutable accountFacet;\n address public immutable entryPoint;\n address public immutable facetRegistry;\n address public immutable defaultFallback;\n\n /**\n * @notice Sets the initialization data for Barz contract initialization\n * @param _accountFacet Account Facet to be used to create Barz\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\n * @param _facetRegistry Facet Registry to be used to create Barz\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\n */\n constructor(\n address _accountFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallback\n ) {\n accountFacet = _accountFacet;\n entryPoint = _entryPoint;\n facetRegistry = _facetRegistry;\n defaultFallback = _defaultFallback;\n }\n\n /**\n * @notice Creates the Barz with a single call. It creates the Barz contract with the givent verification facet\n * @param _verificationFacet Address of verification facet used for creating the barz account\n * @param _owner Public Key of the owner to initialize barz account\n * @param _salt Salt used for deploying barz with create2\n * @return barz Instance of Barz contract deployed with the given parameters\n */\n function createAccount(\n address _verificationFacet,\n bytes calldata _owner,\n uint256 _salt\n ) external override returns (Barz barz) {\n address addr = getAddress(_verificationFacet, _owner, _salt);\n uint codeSize = addr.code.length;\n if (codeSize > 0) {\n return Barz(payable(addr));\n }\n barz = new Barz{salt: bytes32(_salt)}(\n accountFacet,\n _verificationFacet,\n entryPoint,\n facetRegistry,\n defaultFallback,\n _owner\n );\n emit BarzDeployed(address(barz));\n }\n\n /**\n * @notice Calculates the address of Barz with the given parameters\n * @param _verificationFacet Address of verification facet used for creating the barz account\n * @param _owner Public Key of the owner to initialize barz account\n * @param _salt Salt used for deploying barz with create2\n * @return barzAddress Precalculated Barz address\n */\n function getAddress(\n address _verificationFacet,\n bytes calldata _owner,\n uint256 _salt\n ) public view override returns (address barzAddress) {\n bytes memory bytecode = getBytecode(\n accountFacet,\n _verificationFacet,\n entryPoint,\n facetRegistry,\n defaultFallback,\n _owner\n );\n bytes32 hash = keccak256(\n abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(bytecode)\n )\n );\n barzAddress = address(uint160(uint256(hash)));\n }\n\n /**\n * @notice Returns the bytecode of Barz with the given parameter\n * @param _accountFacet Account Facet to be used to create Barz\n * @param _verificationFacet Verification Facet to be used to create Barz\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\n * @param _facetRegistry Facet Registry to be used to create Barz\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\n * @param _ownerPublicKey Public Key of owner to be used to initialize Barz ownership\n * @return barzBytecode Bytecode of Barz\n */\n function getBytecode(\n address _accountFacet,\n address _verificationFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallback,\n bytes calldata _ownerPublicKey\n ) public pure override returns (bytes memory barzBytecode) {\n bytes memory bytecode = type(Barz).creationCode;\n barzBytecode = abi.encodePacked(\n bytecode,\n abi.encode(\n _accountFacet,\n _verificationFacet,\n _entryPoint,\n _facetRegistry,\n _defaultFallback,\n _ownerPublicKey\n )\n );\n }\n\n /**\n * @notice Returns the creation code of the Barz contract\n * @return creationCode Creation code of Barz\n */\n function getCreationCode()\n public\n pure\n override\n returns (bytes memory creationCode)\n {\n creationCode = type(Barz).creationCode;\n }\n}\n" + }, + "contracts/facets/AccountFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {UserOperation} from \"../aa-4337/interfaces/UserOperation.sol\";\nimport {IEntryPoint} from \"../aa-4337/interfaces/IEntryPoint.sol\";\nimport {BaseAccount} from \"../aa-4337/core/BaseAccount.sol\";\nimport {LibAppStorage, BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {IFacetRegistry} from \"../infrastructure/interfaces/IFacetRegistry.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {IERC1271} from \"../interfaces/ERC/IERC1271.sol\";\nimport {IAccountFacet} from \"./interfaces/IAccountFacet.sol\";\n\n/**\n * @title Account Facet\n * @dev Account module contract that provides the account features and initialization of signer\n * compatible with EIP-1271 & EIP-4337\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract AccountFacet is BarzStorage, BaseAccount, IAccountFacet {\n using ECDSA for bytes32;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceAccountInitialize();\n }\n\n /**\n * @notice Returns the address of EntryPoint contract registered to Barz account\n */\n function entryPoint() public view override returns (IEntryPoint) {\n return s.entryPoint;\n }\n\n /**\n * @notice Initializes the initial storage of the Barz contract.\n * @dev This method can only be called during the initialization or signature migration.\n * If the proxy contract was created without initialization, anyone can call initialize.\n * Barz calls initialize in constructor in an atomic transaction during deployment\n * @param _verificationFacet Facet contract handling the verificationi\n * @param _anEntryPoint Entrypoint contract defined in EIP-4337 handling the flow of UserOp\n * @param _facetRegistry Registry of Facets that hold all facet information\n * @param _defaultFallBackHandler Middleware contract for default facets\n * @param _ownerPublicKey Bytes of owner public key\n */\n function initialize(\n address _verificationFacet,\n address _anEntryPoint,\n address _facetRegistry,\n address _defaultFallBackHandler,\n bytes calldata _ownerPublicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceAccountInitialize();\n s.entryPoint = IEntryPoint(_anEntryPoint);\n s.facetRegistry = IFacetRegistry(_facetRegistry);\n LibDiamond.diamondStorage().defaultFallbackHandler = IDiamondLoupe(\n _defaultFallBackHandler\n );\n\n _cutDiamondAccountFacet(_verificationFacet);\n\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n _ownerPublicKey\n );\n // Every Verification Facet should comply with initializeSigner(bytes)\n // to be compatible with the Barz contract(for initialization)\n (bool success, bytes memory result) = _verificationFacet.delegatecall(\n initCall\n );\n if (!success || uint256(bytes32(result)) != 1) {\n revert AccountFacet__InitializationFailure();\n }\n\n initSuccess = 1;\n emit AccountInitialized(s.entryPoint, _ownerPublicKey);\n }\n\n function _cutDiamondAccountFacet(address _verificationFacet) internal {\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](1);\n\n bytes4 ownerVerificationFuncSelector = IVerificationFacet(\n _verificationFacet\n ).validateOwnerSignatureSelector();\n\n bytes4[] memory verificationFunctionSelectors = new bytes4[](3);\n verificationFunctionSelectors[0] = IERC1271.isValidSignature.selector;\n verificationFunctionSelectors[1] = ownerVerificationFuncSelector;\n verificationFunctionSelectors[2] = IVerificationFacet.owner.selector;\n cut[0] = IDiamondCut.FacetCut({\n facetAddress: _verificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: verificationFunctionSelectors\n });\n\n LibDiamond.diamondCut(cut, address(0), \"\");\n }\n\n /**\n * @notice Calls the destination with inputted calldata and value from EntryPoint\n * @dev This method executes the calldata coming from the EntryPoint.\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\n * @param _dest Address of destination where the call will be forwarded to\n * @param _value Amount of native coin the owner is willing to send(e.g. ETH, BNB)\n * @param _func Bytes of calldata to execute in the destination address\n */\n function execute(\n address _dest,\n uint256 _value,\n bytes calldata _func\n ) external override onlyWhenUnlocked {\n _requireFromEntryPoint();\n _call(_dest, _value, _func);\n }\n\n /**\n * @notice Batch calls the destination with inputted calldata and value from EntryPoint\n * @dev This method batch executes the calldata coming from the EntryPoint.\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\n * @param _dest Array of addresses of destination where the call will be forwarded to\n * @param _value Array of amount of native coin the owner is willing to send(e.g. ETH, BNB)\n * @param _func Array of bytes of calldata to execute in the destination address\n */\n function executeBatch(\n address[] calldata _dest,\n uint256[] calldata _value,\n bytes[] calldata _func\n ) external override onlyWhenUnlocked {\n _requireFromEntryPoint();\n uint256 destLength = _dest.length;\n require(\n destLength == _func.length && destLength == _value.length,\n \"wrong array lengths\"\n );\n for (uint256 i; i < destLength; ) {\n _call(_dest[i], _value[i], _func[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Validates the signature field of UserOperation\n * @dev This method validates if the signature of UserOp is indeed valid by delegating the call to Verification Facet\n * Barz makes a call to the pre-registered Verification Facet address in App Storage\n * @param _userOp UserOperation from owner to be validated\n * @param _userOpHash Hash of UserOperation given from the EntryPoint contract\n */\n function _validateSignature(\n UserOperation calldata _userOp,\n bytes32 _userOpHash\n ) internal override returns (uint256 validationData) {\n // Get Facet with Function Selector\n address facet = LibLoupe.facetAddress(s.validateOwnerSignatureSelector);\n if (facet == address(0))\n revert AccountFacet__NonExistentVerificationFacet();\n\n // Make function call to VerificationFacet\n bytes memory validateCall = abi.encodeWithSelector(\n s.validateOwnerSignatureSelector,\n _userOp,\n _userOpHash\n );\n (bool success, bytes memory result) = facet.delegatecall(validateCall);\n if (!success) revert AccountFacet__CallNotSuccessful();\n validationData = uint256(bytes32(result));\n if (validationData == 0) emit VerificationSuccess(_userOpHash);\n else emit VerificationFailure(_userOpHash);\n }\n\n /**\n * @notice Calls the target with the inputted value and calldata\n * @dev This method is the actual function in Barz that makes a call with an arbitrary owner-given data\n * @param _target Address of the destination contract which the call is getting forwarded to\n * @param _value Amount of Native coin the owner is wanting to make in this call\n * @param _data Calldata the owner is forwarding together in the call e.g. Swap/Token Transfer\n */\n function _call(\n address _target,\n uint256 _value,\n bytes memory _data\n ) internal {\n if (_checkRestrictions(_target, _value, _data) == 1)\n revert AccountFacet__RestrictionsFailure();\n\n (bool success, bytes memory result) = _target.call{value: _value}(\n _data\n );\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n }\n\n /**\n * @notice Checks restrictions if the restrictions facet exists\n * @dev This method checks if the restrictions facet exists and makes a verification call to an array of restrictions facet\n * @param _target Address the call is getting forwarded to\n * @param _value Amount of native coin the call is sending together with the call\n * @param _data Calldata to trigger execution in target address\n */\n function _checkRestrictions(\n address _target,\n uint256 _value,\n bytes memory _data\n ) internal returns (uint256 result) {\n address facet = LibDiamond.restrictionsFacet();\n // NOTE: No restrictions facet, so restriction validation passes\n if (facet == address(0)) return 0;\n bytes memory call = abi.encodeWithSignature(\n \"verifyRestrictions(address,address,uint256,bytes)\",\n address(this),\n _target,\n _value,\n _data\n );\n (bool success, bytes memory response) = facet.delegatecall(call);\n if (!success) revert AccountFacet__RestrictionsFailure();\n result = uint256(bytes32(response));\n }\n}\n" + }, + "contracts/facets/AccountRecoveryFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibFacetStorage, RecoveryStorage, RecoveryConfig, RecoveryApprovalConfig, ApprovalConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {IAccountRecoveryFacet} from \"./interfaces/IAccountRecoveryFacet.sol\";\n\n/**\n * @title Account Recovery Facet\n * @dev Contract that enables recovery of accounts when owner key is unavailable\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract AccountRecoveryFacet is IAccountRecoveryFacet, Modifiers {\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Approve recovery of account as guardian\n * @dev This method can only be called by guardian and guardian inputs the public key of the new owner\n * When the threshold(majority of guardians) passes, it automatically executes account recovery\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function approveAccountRecovery(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + _getApprovalValidationPeriod()\n );\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit RecoveryApproved(\n _recoveryPublicKey,\n msg.sender,\n approvalValidUntil\n );\n if (\n getRecoveryApprovalCountWithTimeValidity(recoveryPublicKeyHash) >=\n LibGuardian.majorityOfGuardians()\n ) _executeRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Revoke recovery of account as guardian\n * @dev This method can only be called by guardian and guardian inputs the public key of the new owner\n When the threshold(majority of guardians) passes, it automatically revokes account recovery when recovery is pending\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function revokeAccountRecoveryApproval(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n if (\n !rs\n .isNewOwnerApproved[recoveryPublicKeyHash][msg.sender].isApproved ||\n !(block.timestamp <\n rs\n .isNewOwnerApproved[recoveryPublicKeyHash][msg.sender]\n .validUntil)\n ) revert AccountRecoveryFacet__NonExistentApproval();\n\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(false, 0);\n emit RecoveryApprovalRevoked(_recoveryPublicKey, msg.sender);\n }\n\n /**\n * @notice Executes recovery with signatures or on-chain pre-approvals\n * @dev This method validates the signatures of guardians or checks the on-chain pre-approved calls to check if the threshold passes\n * When the threshold passes, account recovery is executed and revert otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _guardians Array of guardians address that are approving the recovery of Account\n * @param _signatures Array of signature bytes that signed the approval hash\n */\n function executeRecovery(\n bytes calldata _recoveryPublicKey,\n address[] calldata _guardians,\n bytes[] calldata _signatures\n ) external override {\n if (_isRecoveryPending())\n revert AccountRecoveryFacet__RecoveryAlreadyOngoing();\n uint256 guardiansLength = _guardians.length;\n if (guardiansLength != _signatures.length)\n revert AccountRecoveryFacet__InvalidArrayLength();\n validateNewOwner(_recoveryPublicKey);\n\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n\n _checkApprover(_guardians);\n _checkDuplicateOnChainApprover(recoveryPublicKeyHash, _guardians);\n\n if (\n guardiansLength +\n getRecoveryApprovalCountWithTimeValidity(\n recoveryPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians()\n ) revert AccountRecoveryFacet__InsufficientGuardians();\n for (uint256 i; i < guardiansLength; ) {\n if (!LibGuardian.isGuardian(_guardians[i]))\n revert AccountRecoveryFacet__InvalidGuardian();\n if (\n !SignatureChecker.isValidSignatureNow(\n _guardians[i],\n recoveryPublicKeyHash,\n _signatures[i]\n )\n ) revert AccountRecoveryFacet__InvalidGuardianSignature();\n unchecked {\n ++i;\n }\n }\n _executeRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Executes recovery of the account. Note that execution and finalization is a different process\n * @dev Executes the recovery and adds recovery data to recovery configuration. Locks the account\n * @param _recoveryPublicKey Public Key of the account for recovery\n */\n function _executeRecovery(bytes memory _recoveryPublicKey) internal {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n ++rs.nonce;\n uint64 executeAfter = uint64(block.timestamp + _getRecoveryPeriod());\n rs.recoveryConfigs[INNER_STRUCT] = RecoveryConfig(\n _recoveryPublicKey,\n executeAfter // NOTE: Remove guardian Count\n );\n LibAppStorage.setLock(\n block.timestamp + _getLockPeriod(),\n AccountRecoveryFacet.executeRecovery.selector\n );\n emit RecoveryExecuted(_recoveryPublicKey, executeAfter);\n }\n\n /**\n * @notice Finalize recovery after recovery pending period. Recovery pending period can be set by user beforehand in SecurityManager\n * @dev This method finalizes recovery and fully changes the ownership of the account to the newly inputted recovery public key\n */\n function finalizeRecovery() external override {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n if (\n uint64(block.timestamp) <=\n rs.recoveryConfigs[INNER_STRUCT].executeAfter\n ) revert AccountRecoveryFacet__RecoveryPeriodNotOver();\n bytes memory recoveryOwner = rs\n .recoveryConfigs[INNER_STRUCT]\n .recoveryPublicKey;\n\n delete rs.recoveryConfigs[INNER_STRUCT];\n\n LibAppStorage.setLock(0, bytes4(0));\n\n LibAppStorage.initiateSignerMigration();\n address verificationFacet = address(\n bytes20(\n LibDiamond.diamondStorage().facets[\n s.validateOwnerSignatureSelector\n ]\n )\n );\n bytes memory uninitCall = abi.encodeWithSignature(\n \"uninitializeSigner()\"\n );\n (bool success, bytes memory result) = verificationFacet.delegatecall(\n uninitCall\n );\n if (!success) revert AccountRecoveryFacet__CallNotSuccesful();\n uint256 validationData = uint256(bytes32(result));\n if (validationData != 1)\n revert AccountRecoveryFacet__SignerUninitializationFailure();\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n recoveryOwner\n );\n (success, result) = verificationFacet.delegatecall(initCall);\n if (!success) revert AccountRecoveryFacet__CallNotSuccesful();\n validationData = uint256(bytes32(result));\n if (validationData != 1)\n revert AccountRecoveryFacet__SignerInitializationFailure();\n LibAppStorage.finalizeSignerMigration();\n emit RecoveryFinalized(recoveryOwner);\n }\n\n /**\n * @notice Approves the cancellation of recovery\n * @dev This method approves the cancellation of recovery when recovery is still pending - waiting for finalization\n * @param _recoveryPublicKey Bytes of public key which is pending for recovery\n */\n function approveCancelRecovery(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"CancelRecovery\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + _getApprovalValidationPeriod()\n );\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit RecoveryCancellationApproved(_recoveryPublicKey, msg.sender);\n if (\n getRecoveryApprovalCountWithTimeValidity(recoveryPublicKeyHash) >=\n LibGuardian.majorityOfGuardians()\n ) {\n _cancelRecovery(_recoveryPublicKey);\n }\n }\n\n /**\n * @notice Hardstops an ongoing recovery\n * @dev This method provides a safety mechanism to protect owners of malicious guardians.\n * Owners can hardstop recovery when an malicious guardians starts the recovery process.\n * @param _signature Signature of the owner that signs the hash to hardstop recovery\n */\n function hardstopRecovery(bytes calldata _signature) external override {\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n \"0\",\n \"HardstopRecovery\"\n );\n if (\n !SignatureChecker.isValidSignatureNow(\n address(this),\n recoveryPublicKeyHash,\n _signature\n )\n ) revert AccountRecoveryFacet__InvalidOwnerSignature();\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n ++rs.nonce;\n delete rs.recoveryConfigs[INNER_STRUCT];\n LibAppStorage.setLock(0, bytes4(0));\n emit RecoveryHardstopped();\n }\n\n /**\n * @notice Cancels recovery with signatures or on-chain pre-approvals\n * @dev This method validates the signatures of guardians or checks the on-chain pre-approved calls to check if the threshold passes\n * When the threshold passes, account recovery is canceled and revert otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _guardians Array of guardians address that are approving the recovery of Account\n * @param _signatures Array of signature bytes that signed the cancellation approval hash\n */\n function cancelRecovery(\n bytes calldata _recoveryPublicKey,\n address[] calldata _guardians,\n bytes[] calldata _signatures\n ) external override {\n uint256 guardiansLength = _guardians.length;\n if (guardiansLength != _signatures.length)\n revert AccountRecoveryFacet__InvalidArrayLength();\n validateNewOwner(_recoveryPublicKey);\n\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"CancelRecovery\"\n );\n\n _checkApprover(_guardians);\n _checkDuplicateOnChainApprover(recoveryPublicKeyHash, _guardians);\n\n if (\n guardiansLength +\n getRecoveryApprovalCountWithTimeValidity(\n recoveryPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians()\n ) revert AccountRecoveryFacet__InsufficientGuardians();\n for (uint256 i; i < guardiansLength; ) {\n if (!LibGuardian.isGuardian(_guardians[i]))\n revert AccountRecoveryFacet__CallerNotGuardian();\n if (\n !SignatureChecker.isValidSignatureNow(\n _guardians[i],\n recoveryPublicKeyHash,\n _signatures[i]\n )\n ) revert AccountRecoveryFacet__InvalidGuardianSignature();\n unchecked {\n ++i;\n }\n }\n _cancelRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Cancel recovery when the recovery is pending. Unlock the account as well\n * @dev This method checks if the recovery is pending and reverts if not pending.\n * It increases the recovery nonce and deletes the recovery information and gets a small portion of gas in return\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function _cancelRecovery(bytes memory _recoveryPublicKey) internal {\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n LibAppStorage.setLock(0, bytes4(0));\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n ++rs.nonce;\n delete rs.recoveryConfigs[INNER_STRUCT];\n emit RecoveryCanceled(_recoveryPublicKey);\n }\n\n /**\n * @notice Validates the format of public key to be used for recovery\n * @dev This method checks if the public key format is correct and reverts otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function validateNewOwner(bytes memory _recoveryPublicKey) public view {\n if (\n !IVerificationFacet(\n LibLoupe.facetAddress(s.validateOwnerSignatureSelector)\n ).isValidKeyType(_recoveryPublicKey)\n ) revert AccountRecoveryFacet__InvalidRecoveryPublicKey();\n }\n\n /**\n * @notice Checks if recovery is currently pending\n * @return isPending Boolean indicating if recovery is pending\n */\n function _isRecoveryPending() internal view returns (bool isPending) {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n isPending = (rs.recoveryConfigs[INNER_STRUCT].executeAfter > 0);\n }\n\n /**\n * @notice Calculate the recovery hash dependent on chain, wallet address, nonce with EIP-191 prefix for safety\n * @dev Returns the keccak256 hash of EIP-191 msg hash packed with public key, salt, nonce, wallet address, etc\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _saltString Salt string to uniquely identify each recovery hash and for security\n * @return recoveryKeyHash Bytes32 string of the recovery hash\n */\n function getApprovalRecoveryKeyHash(\n bytes memory _recoveryPublicKey,\n string memory _saltString\n ) public view override returns (bytes32 recoveryKeyHash) {\n recoveryKeyHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n _recoveryPublicKey,\n _saltString,\n address(this),\n block.chainid,\n LibFacetStorage.recoveryStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Check the onchain approval of guardians and returns the number of guardians that approved\n * @dev Loop through the guardian addresses and returns the number of guardians that approved this recovery hash\n * @param _recoveryPublicKeyHash Bytes hash of newly recovered public key and recovery value of the account\n * @return approvalCount Number of guardians that approved\n */\n function getRecoveryApprovalCountWithTimeValidity(\n bytes32 _recoveryPublicKeyHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n for (uint256 i; i < guardianLength; ) {\n if (isRecoveryApproved(_recoveryPublicKeyHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Checks if the recovery is approved by the given approver\n * @param _recoveryPublicKeyHash Hash of the public key and configuration for recovery\n * @param _approver Address of approver\n * @return isApproved Bool value if recovery hash is approved\n */\n function isRecoveryApproved(\n bytes32 _recoveryPublicKeyHash,\n address _approver\n ) public view override returns (bool isApproved) {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n if (\n rs\n .isNewOwnerApproved[_recoveryPublicKeyHash][_approver].isApproved &&\n block.timestamp <\n rs.isNewOwnerApproved[_recoveryPublicKeyHash][_approver].validUntil\n ) {\n isApproved = true;\n }\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _recoveryPublicKeyHash Hash of recovery information\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _recoveryPublicKeyHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isRecoveryApproved(_recoveryPublicKeyHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert AccountRecoveryFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the lock period of this wallet address from security manager\n * @return lockPeriod value of lock period\n */\n function _getLockPeriod() internal view returns (uint256 lockPeriod) {\n lockPeriod = securityManager.lockPeriodOf(address(this));\n if (lockPeriod == 0) revert AccountRecoveryFacet__InvalidLockPeriod();\n }\n\n /**\n * @notice Returns the lock period of this wallet address from security manager\n * @return recoveryPeriod value of recovery period\n */\n function _getRecoveryPeriod()\n internal\n view\n returns (uint256 recoveryPeriod)\n {\n recoveryPeriod = securityManager.recoveryPeriodOf(address(this));\n if (recoveryPeriod == 0)\n revert AccountRecoveryFacet__InvalidRecoveryPeriod();\n }\n\n /**\n * @notice Returns the approval validation period of this wallet address from security manager\n * @return approvalValidationPeriod value of approval validation period\n */\n function _getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod == 0)\n revert AccountRecoveryFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the recovery nonce of this wallet address from security manager\n * @return nonce value of recovery nonce\n */\n function getRecoveryNonce() public view override returns (uint128 nonce) {\n nonce = LibFacetStorage.recoveryStorage().nonce;\n }\n\n /**\n * @notice Returns the recovery information of the pending recovery\n * @return recoveryConfig value struct of pending recovery\n */\n function getPendingRecovery()\n public\n view\n override\n returns (RecoveryConfig memory recoveryConfig)\n {\n recoveryConfig = LibFacetStorage.recoveryStorage().recoveryConfigs[\n INNER_STRUCT\n ];\n }\n}\n" + }, + "contracts/facets/base/DiamondCutFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibGuardian} from \"../../libraries/LibGuardian.sol\";\nimport {ISecurityManager} from \"../../infrastructure/interfaces/ISecurityManager.sol\";\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibFacetStorage, DiamondCutApprovalConfig, ApprovalConfig} from \"../../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"../Modifiers.sol\";\nimport {IDiamondCut} from \"./interfaces/IDiamondCut.sol\";\n\n/**\n * @title DiamondCut Facet\n * @dev Responsible for adding/removing/replace facets in Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DiamondCutFacet is Modifiers, IDiamondCut {\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Updates the flag for the interfaceId\n * @param _interfaceId InterfaceID to update the mapping\n * @param _flag Bool value to update the mapping of the given interface ID\n */\n function updateSupportsInterface(\n bytes4 _interfaceId,\n bool _flag\n ) external override onlyWhenUnlocked {\n LibDiamond.enforceIsSelf();\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId] = _flag;\n emit SupportsInterfaceUpdated(_interfaceId, _flag);\n }\n\n /**\n * @notice Add/replace/remove any number of functions and optionally execute\n * a function with delegatecall when guardians don't exist\n * @param _diamondCut Contains the facet addresses and function selectors\n * @param _init The address of the contract or facet to execute _calldata\n * @param _calldata A function call, including function selector and arguments\n * _calldata is executed with delegatecall on _init\n */\n function diamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) external override onlyWhenUnlocked {\n LibDiamond.enforceIsSelf();\n\n _checkFacetCutValidity(_diamondCut);\n // require approval from guardian if guardian exists\n if (0 != LibGuardian.guardianCount())\n revert DiamondCutFacet__InvalidRouteWithGuardian();\n\n ++LibFacetStorage.diamondCutStorage().nonce;\n LibDiamond.diamondCut(_diamondCut, _init, _calldata);\n }\n\n /**\n * @notice Add/replace/remove any number of functions and optionally execute\n * a function with delegatecall when guardians exist\n * @param _diamondCut Contains the facet addresses and function selectors\n * @param _init The address of the contract or facet to execute _calldata\n * @param _calldata A function call, including function selector and arguments\n * _calldata is executed with delegatecall on _init\n * @param _approvers Guardian or owner address that approves the diamond cut\n * @param _signatures Signature of Guardians or owner that approves the diamond cut\n */\n function diamondCutWithGuardian(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n ) external override onlyWhenUnlocked {\n uint256 approverLength = _approvers.length;\n if (approverLength != _signatures.length)\n revert DiamondCutFacet__InvalidArrayLength();\n _checkFacetCutValidity(_diamondCut);\n if (0 == LibGuardian.guardianCount())\n revert DiamondCutFacet__InvalidRouteWithGuardian();\n\n bytes32 cutHash = getDiamondCutHash(_diamondCut, _init, _calldata);\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(cutHash, _approvers);\n\n bool onChainOwnerApproval = getOwnerCutApprovalWithTimeValidity(\n cutHash\n );\n\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n if (\n approverLength +\n getDiamondCutApprovalCountWithTimeValidity(cutHash) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert DiamondCutFacet__InsufficientApprovers();\n\n bool ownerApproved;\n for (uint256 i; i < approverLength; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n _approvers[i] != address(this)\n ) revert DiamondCutFacet__InvalidApprover();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert DiamondCutFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n cutHash,\n _signatures[i]\n )\n ) revert DiamondCutFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n if (!ownerApproved && !onChainOwnerApproval)\n revert DiamondCutFacet__LackOfOwnerApproval();\n\n ++LibFacetStorage.diamondCutStorage().nonce;\n LibDiamond.diamondCut(_diamondCut, _init, _calldata);\n }\n\n /**\n * @notice Approves diamond cut. This can only be called directly from guardian or owner\n * @param _diamondCut Contains the facet addresses and function selectors\n * @param _init The address of the contract or facet to execute _calldata\n * @param _calldata A function call, including function selector and arguments\n * _calldata is executed with delegatecall on _init\n */\n function approveDiamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\n if (LibGuardian.guardianCount() == 0)\n revert DiamondCutFacet__InvalidRouteWithoutGuardian();\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n _checkFacetCutValidity(_diamondCut);\n\n bytes32 cutHash = getDiamondCutHash(_diamondCut, _init, _calldata);\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(\n true,\n approvalValidUntil\n );\n emit DiamondCutApproved(_diamondCut, _init, _calldata);\n if (\n (getDiamondCutApprovalCountWithTimeValidity(cutHash) >=\n LibGuardian.majorityOfGuardians()) &&\n getOwnerCutApprovalWithTimeValidity(cutHash)\n ) {\n ++LibFacetStorage.diamondCutStorage().nonce;\n LibDiamond.diamondCut(_diamondCut, _init, _calldata);\n }\n }\n\n /**\n * @notice Revokes the approval of diamond cut. This can only be called directly from guardian or owner\n * @param _diamondCut Contains the facet addresses and function selectors\n * @param _init The address of the contract or facet to execute _calldata\n * @param _calldata A function call, including function selector and arguments\n * _calldata is executed with delegatecall on _init\n */\n function revokeDiamondCutApproval(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n bytes32 cutHash = getDiamondCutHash(_diamondCut, _init, _calldata);\n if (!ds.isDiamondCutApproved[cutHash][msg.sender].isApproved)\n revert DiamondCutFacet__CannotRevokeUnapproved();\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(false, 0);\n emit DiamondCutApprovalRevoked(_diamondCut, _init, _calldata);\n }\n\n /**\n * @notice Gets the number of approvals of diamond cut from guardians\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n */\n function getDiamondCutApprovalCountWithTimeValidity(\n bytes32 _diamondCutHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardiansLength = guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n if (isCutApproved(_diamondCutHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n return approvalCount;\n }\n\n /**\n * @notice Returns if the owner has approved the diamond cut\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @return isApprovedByOwner Bool value showing if the owner approved the cut\n */\n function getOwnerCutApprovalWithTimeValidity(\n bytes32 _diamondCutHash\n ) public view override returns (bool isApprovedByOwner) {\n isApprovedByOwner = isCutApproved(_diamondCutHash, address(this));\n }\n\n /**\n * @notice Returns if the given approver has approved the diamond cut\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @param _approver Address of approver\n * @return isApproved Bool value showing if the approver approved the cut\n */\n function isCutApproved(\n bytes32 _diamondCutHash,\n address _approver\n ) public view override returns (bool isApproved) {\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n isApproved = (ds\n .isDiamondCutApproved[_diamondCutHash][_approver].isApproved &&\n block.timestamp <\n ds.isDiamondCutApproved[_diamondCutHash][_approver].validUntil);\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _diamondCutHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isCutApproved(_diamondCutHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert DiamondCutFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the diamond cut hash. This function ensures that this hash is safe from replay attack by including\n * salt, address, chainId, and nonce, etc.\n * @param _diamondCut Contains the facet addresses and function selectors\n * @param _init The address of the contract or facet to execute _calldata\n * @param _calldata A function call, including function selector and arguments\n * _calldata is executed with delegatecall on _init\n * @return cutHash Diamond Cut Hash\n */\n function getDiamondCutHash(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) public view override returns (bytes32 cutHash) {\n cutHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n keccak256(abi.encode(_diamondCut)),\n _init,\n _calldata,\n address(this),\n block.chainid,\n LibFacetStorage.diamondCutStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Returns the approval validation Period\n * @dev This method fetches the validation period from the security manager\n * @return approvalValidationPeriod Approval validation period of Barz contract fetched from security manager\n */\n function getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod <= 0)\n revert DiamondCutFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the diamond cut nonce of this wallet\n * @dev This method fetches the nonce from diamond cut storage\n * @return cutNonce Nonce of diamond cut to protect from reply attacks\n */\n function getDiamondCutNonce()\n public\n view\n override\n returns (uint128 cutNonce)\n {\n cutNonce = LibFacetStorage.diamondCutStorage().nonce;\n }\n}\n" + }, + "contracts/facets/base/DiamondLoupeFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {IERC165} from \"../../interfaces/ERC/IERC165.sol\";\nimport {IERC1271} from \"../../interfaces/ERC/IERC1271.sol\";\nimport {IERC677Receiver} from \"../../interfaces/ERC/IERC677Receiver.sol\";\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC1155Receiver} from \"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\";\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../../libraries/LibLoupe.sol\";\nimport {LibUtils} from \"../../libraries/LibUtils.sol\";\nimport {IDiamondCut} from \"../../facets/base/interfaces/IDiamondCut.sol\";\nimport {IStorageLoupe} from \"./interfaces/IStorageLoupe.sol\";\nimport {IDiamondLoupe} from \"./interfaces/IDiamondLoupe.sol\";\n\n/**\n * @title DiamondLoupe Facet\n * @dev DiamondLoupe contract compatible with EIP-2535\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DiamondLoupeFacet is IDiamondLoupe, IStorageLoupe, IERC165 {\n // Diamond Loupe Functions\n ////////////////////////////////////////////////////////////////////\n /// These functions are expected to be called frequently by tools off-chain.\n\n /**\n * @notice Gets all facets and their selectors.\n * @dev Barz uses a special architecture called default fallback handler. Default Fallback handler is used as a middleware\n * that holds the mapping of facet function selector and facet address that Barz uses. This helps Barz to reduce\n * significant amount of gas during the initialization process.\n * Hence, this method aggregates both the facet information from DefaulFallbackHandler and in diamond storage and shows the data to users.\n * @return facets_ Facet\n */\n function facets() public view override returns (Facet[] memory facets_) {\n Facet[] memory defaultFacet = LibDiamond\n .diamondStorage()\n .defaultFallbackHandler\n .facets();\n Facet[] memory _facets = LibLoupe.facets();\n uint256 numFacets = _facets.length;\n bytes4[] memory keys;\n address[] memory values;\n for (uint256 i; i < numFacets; ) {\n uint256 selectorsLength = _facets[i].functionSelectors.length;\n for (uint256 j; j < selectorsLength; ) {\n (keys, values) = LibUtils.setValue(\n keys,\n values,\n _facets[i].functionSelectors[j],\n _facets[i].facetAddress\n );\n unchecked {\n ++j;\n }\n }\n unchecked {\n ++i;\n }\n }\n {\n bool iIncrement;\n for (uint256 i; i < defaultFacet.length; ) {\n bool jIncrement;\n for (\n uint256 j;\n j < defaultFacet[i].functionSelectors.length;\n\n ) {\n if (\n LibUtils.getValue(\n keys,\n values,\n defaultFacet[i].functionSelectors[j]\n ) != address(0)\n ) {\n if (defaultFacet[i].functionSelectors.length == 1) {\n defaultFacet = LibUtils.removeFacetElement(\n defaultFacet,\n i\n );\n iIncrement = true;\n break;\n }\n defaultFacet[i].functionSelectors = LibUtils\n .removeElement(\n defaultFacet[i].functionSelectors,\n j\n );\n jIncrement = true;\n }\n if (!jIncrement) {\n unchecked {\n ++j;\n }\n } else {\n jIncrement = false;\n }\n }\n if (!iIncrement) {\n unchecked {\n ++i;\n }\n } else {\n iIncrement = false;\n }\n }\n }\n {\n uint256 facetLength = numFacets + defaultFacet.length;\n facets_ = new Facet[](facetLength);\n uint256 defaultFacetIndex;\n for (uint256 i; i < facetLength; ) {\n if (i < numFacets) {\n facets_[i] = _facets[i];\n bool jIncrementor;\n for (uint256 j; j < defaultFacet.length; ) {\n if (\n facets_[i].facetAddress ==\n defaultFacet[j].facetAddress\n ) {\n facets_[i].functionSelectors = LibUtils.mergeArrays(\n _facets[i].functionSelectors,\n defaultFacet[j].functionSelectors\n );\n defaultFacet = LibUtils.removeFacetElement(\n defaultFacet,\n j\n );\n jIncrementor = true;\n {\n facets_ = LibUtils.removeFacetElement(\n facets_,\n facets_.length - 1\n );\n }\n --facetLength;\n }\n if (!jIncrementor) {\n unchecked {\n ++j;\n }\n } else {\n jIncrementor = false;\n }\n }\n } else {\n facets_[i] = defaultFacet[defaultFacetIndex];\n ++defaultFacetIndex;\n }\n unchecked {\n ++i;\n }\n }\n }\n }\n\n /**\n * @notice Gets all the function selectors provided by a facet.\n * @param _facet The facet address.\n * @return facetFunctionSelectors_\n */\n function facetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n Facet[] memory facet = facets();\n uint256 facetLength = facet.length;\n for (uint256 i; i < facetLength; ) {\n if (facet[i].facetAddress == _facet)\n return facet[i].functionSelectors;\n unchecked {\n ++i;\n }\n }\n return facetFunctionSelectors_;\n }\n\n /**\n * @notice Get all the facet addresses used by Barz.\n * @return facetAddresses_\n */\n function facetAddresses()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n Facet[] memory facet = facets();\n uint256 facetLength = facet.length;\n facetAddresses_ = new address[](facetLength);\n for (uint256 i; i < facetLength; ) {\n facetAddresses_[i] = facet[i].facetAddress;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Gets the facet that supports the given selector.\n * @dev If facet is not found return address(0).\n * @param _functionSelector The function selector.\n * @return facetAddress_ The facet address.\n */\n function facetAddress(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n\n facetAddress_ = address(bytes20(ds.facets[_functionSelector]));\n if (facetAddress_ == address(0)) {\n facetAddress_ = IDiamondLoupe(ds.defaultFallbackHandler)\n .facetAddress(_functionSelector);\n }\n }\n\n /**\n * @notice SupportInterface to be compatible with EIP 165\n * @param _interfaceId Interface ID for detecting the interface\n * @return isSupported Bool value showing if the standard is supported in the contract\n */\n function supportsInterface(\n bytes4 _interfaceId\n ) external view override returns (bool isSupported) {\n isSupported =\n _interfaceId == type(IERC165).interfaceId ||\n _interfaceId == IDiamondCut.diamondCut.selector ||\n _interfaceId == type(IDiamondLoupe).interfaceId ||\n _interfaceId == type(IERC1155Receiver).interfaceId ||\n _interfaceId == type(IERC721Receiver).interfaceId ||\n _interfaceId == type(IERC777Recipient).interfaceId ||\n _interfaceId == IERC1271.isValidSignature.selector ||\n _interfaceId == type(IERC677Receiver).interfaceId ||\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId];\n }\n\n /**\n * @notice Returns the facet from the diamond storage. This excludes the facets from the default fallback handler\n * @return facets_ Facet information attached directly to diamond storage\n */\n function facetsFromStorage()\n external\n view\n override\n returns (Facet[] memory facets_)\n {\n facets_ = LibLoupe.facets();\n }\n\n /**\n * @notice Returns the facet address attached to the given function selector. This excludes the facets from the default fallback handler\n * @param _functionSelector Function selector to fetch the facet address from diamond storage\n * @return facetAddress_ Facet address mapped with the function selector\n */\n function facetAddressFromStorage(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n facetAddress_ = LibLoupe.facetAddress(_functionSelector);\n }\n\n /**\n * @notice Returns all facet addresses attached directly to diamond storage. This excludes the facets from the default fallback handler\n * @return facetAddresses_ All facet addresses attached directly to diamond storage\n */\n function facetAddressesFromStorage()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n facetAddresses_ = LibLoupe.facetAddresses();\n }\n\n /**\n * @notice Returns function selectors of given facet address attached directly to diamond storage. This excludes the facets from the default fallback handler\n * @param _facet Facet address to fetch the facet function selectors from diamond storage\n * @return facetFunctionSelectors_ Facet function selectors of the given facet address\n */\n function facetFunctionSelectorsFromStorage(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n facetFunctionSelectors_ = LibLoupe.facetFunctionSelectors(_facet);\n }\n}\n" + }, + "contracts/facets/base/interfaces/IDiamondCut.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title DiamondCut Facet Interface\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IDiamondCut {\n error DiamondCutFacet__InvalidRouteWithGuardian();\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\n error DiamondCutFacet__InvalidArrayLength();\n error DiamondCutFacet__InsufficientApprovers();\n error DiamondCutFacet__InvalidApprover();\n error DiamondCutFacet__InvalidApproverSignature();\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\n error DiamondCutFacet__CannotRevokeUnapproved();\n error DiamondCutFacet__GuardianApprovalNotRequired();\n error DiamondCutFacet__LackOfOwnerApproval();\n error DiamondCutFacet__OwnerAlreadyApproved();\n error DiamondCutFacet__DuplicateApproval();\n\n event DiamondCutApproved(\n FacetCut[] diamondCut,\n address init,\n bytes initCalldata\n );\n event DiamondCutApprovalRevoked(\n FacetCut[] diamondCut,\n address init,\n bytes initCalldata\n );\n\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\n\n enum FacetCutAction {\n Add,\n Replace,\n Remove\n }\n // Add=0, Replace=1, Remove=2\n\n struct FacetCut {\n address facetAddress;\n FacetCutAction action;\n bytes4[] functionSelectors;\n }\n\n /// @notice Add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param diamondCut Contains the facet addresses and function selectors\n /// @param init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function diamondCut(\n FacetCut[] calldata diamondCut,\n address init,\n bytes calldata _calldata\n ) external;\n\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\n\n function diamondCutWithGuardian(\n FacetCut[] calldata diamondCut,\n address init,\n bytes calldata _calldata,\n address[] calldata approvers,\n bytes[] calldata signatures\n ) external;\n\n function approveDiamondCut(\n FacetCut[] calldata diamondCut,\n address init,\n bytes calldata _calldata\n ) external;\n\n function revokeDiamondCutApproval(\n FacetCut[] calldata diamondCut,\n address init,\n bytes calldata _calldata\n ) external;\n\n function getDiamondCutApprovalCountWithTimeValidity(\n bytes32 diamondCutHash\n ) external view returns (uint256);\n\n function getOwnerCutApprovalWithTimeValidity(\n bytes32 diamondCutHash\n ) external view returns (bool);\n\n function isCutApproved(\n bytes32 diamondCutHash,\n address approver\n ) external view returns (bool);\n\n function getDiamondCutHash(\n FacetCut[] calldata diamondCut,\n address init,\n bytes calldata _calldata\n ) external view returns (bytes32);\n\n function getDiamondCutNonce() external view returns (uint128);\n}\n" + }, + "contracts/facets/base/interfaces/IDiamondLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n// A loupe is a small magnifying glass used to look at diamonds.\n// These functions look at diamonds\ninterface IDiamondLoupe {\n /// These functions are expected to be called frequently\n /// by tools.\n\n struct Facet {\n address facetAddress;\n bytes4[] functionSelectors;\n }\n\n /// @notice Gets all facet addresses and their four byte function selectors.\n /// @return facets_ Facet\n function facets() external view returns (Facet[] memory facets_);\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n /// @return facetFunctionSelectors_\n function facetFunctionSelectors(\n address _facet\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses()\n external\n view\n returns (address[] memory facetAddresses_);\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(\n bytes4 _functionSelector\n ) external view returns (address facetAddress_);\n}\n" + }, + "contracts/facets/base/interfaces/IStorageLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"./IDiamondLoupe.sol\";\n\n/**\n * @title LoupeFromStorage Interface\n * @dev Interface contract to function as a loupe facet directly attached to diamond storage of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IStorageLoupe {\n /// These functions are expected to be called frequently\n /// by tools.\n\n /// @notice Gets all facet addresses and their four byte function selectors.\n /// @return facets_ Facet\n function facetsFromStorage()\n external\n view\n returns (IDiamondLoupe.Facet[] memory);\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n function facetFunctionSelectorsFromStorage(\n address _facet\n ) external view returns (bytes4[] memory);\n\n /// @notice Get all the facet addresses used by a diamond.\n function facetAddressesFromStorage()\n external\n view\n returns (address[] memory);\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n function facetAddressFromStorage(\n bytes4 _functionSelector\n ) external view returns (address);\n}\n" + }, + "contracts/facets/GuardianFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibFacetStorage, GuardianStorage, StorageConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IGuardianFacet} from \"./interfaces/IGuardianFacet.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Guardian Facet\n * @dev Contract that enables addition/removal of guardians from Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract GuardianFacet is IGuardianFacet {\n ISecurityManager public immutable securityManager;\n uint8 public constant INNER_STRUCT = 0;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Add guardians to Barz.\n * @dev This method internally calls addGuardian which checks the validity of guardian address and adds\n * as guardian if valid\n * @param _guardians Array of addresses to add as guardian\n */\n function addGuardians(address[] calldata _guardians) external override {\n LibDiamond.enforceIsSelf();\n uint256 guardiansLength = _guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n addGuardian(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Add a guardian to Barz.\n * @dev This method checks if the function is called by the owner and validates the address of guardian\n * When the validation passes, guardian address is added to the pending state waiting for confirmation\n * @param _guardian Address to add as guardian\n */\n function addGuardian(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (_guardian == address(this))\n revert GuardianFacet__GuardianCannotBeSelf();\n if (isGuardian(_guardian)) revert GuardianFacet__DuplicateGuardian();\n if (_guardian == address(0))\n revert GuardianFacet__ZeroAddressGuardian();\n if (\n keccak256(abi.encodePacked(_guardian)) ==\n keccak256(IVerificationFacet(address(this)).owner())\n ) revert GuardianFacet__OwnerCannotBeGuardian();\n\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n if (\n gs.pending[id] != 0 ||\n block.timestamp <= gs.pending[id] + getSecurityWindow()\n ) revert GuardianFacet__DuplicateGuardianAddition();\n\n uint256 securityPeriod = getAdditionSecurityPeriod();\n gs.pending[id] = block.timestamp + securityPeriod;\n emit GuardianAdditionRequested(\n _guardian,\n block.timestamp + securityPeriod\n );\n }\n\n /**\n * @notice Remove guardians from Barz.\n * @dev This method internally calls removeGuardian which checks the validity of guardian and removes\n * guardian when the request is valid\n * @param _guardians Array of addresses to be removed\n */\n function removeGuardians(address[] calldata _guardians) external override {\n LibDiamond.enforceIsSelf();\n uint256 guardiansLength = _guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n removeGuardian(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Remove a guardian from Barz.\n * @dev This method validates if the guardian to be removed is a guardian and puts the guardian removal\n * to a pending state waiting to be confirmed.\n * @param _guardian Address of guardian to be removed\n */\n function removeGuardian(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n if (!isGuardian(_guardian)) revert GuardianFacet__NonExistentGuardian();\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n if (\n gs.pending[id] != 0 ||\n block.timestamp <= gs.pending[id] + getSecurityWindow()\n ) revert GuardianFacet__DuplicateGuardianRemoval();\n\n uint256 securityPeriod = getRemovalSecurityPeriod();\n gs.pending[id] = block.timestamp + securityPeriod;\n emit GuardianRemovalRequested(\n _guardian,\n block.timestamp + securityPeriod\n );\n }\n\n /**\n * @notice Confirm addition of guardians\n * @dev This method internally calls confirmGuardianAddition which checks the validity of pending request.\n * Guardians are fully added when they pass the validation. Anyone can call this function.\n * @param _guardians Array of guardian addresses to be added\n */\n function confirmGuardianAdditions(\n address[] calldata _guardians\n ) external override {\n uint256 guardiansLength = _guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n confirmGuardianAddition(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Confirm addition of a guardian\n * @dev This method checks the validity of pending request.\n * Guardians are fully added when they pass the validation. Anyone can call this function.\n * @param _guardian Guardian address to be added\n */\n function confirmGuardianAddition(address _guardian) public override {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingAddition();\n if (gs.pending[id] >= block.timestamp)\n revert GuardianFacet__PendingAdditionNotOver();\n if (block.timestamp >= gs.pending[id] + getSecurityWindow())\n revert GuardianFacet__PendingAdditionExpired();\n\n _addGuardian(_guardian);\n\n delete gs.pending[id];\n emit GuardianAdded(_guardian);\n }\n\n /**\n * @notice Confirm removal of guardians\n * @dev This method internally calls confirmGuardianRemoval to check the validity guardian removal confirmation.\n * Guardians are fully removed when they pass the validation. Anyone can call this function.\n * @param _guardians Array of guardian addresses to be removed\n */\n function confirmGuardianRemovals(\n address[] calldata _guardians\n ) external override {\n uint256 guardiansLength = _guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n confirmGuardianRemoval(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Confirm removal of a guardian\n * @dev This method checks the validity guardian removal confirmation.\n * Guardian is fully removed when they pass the validation. Anyone can call this function.\n * @param _guardian Guardian address to be removed\n */\n function confirmGuardianRemoval(address _guardian) public override {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingRemoval();\n if (gs.pending[id] >= block.timestamp)\n revert GuardianFacet__PendingRemovalNotOver();\n if (block.timestamp >= gs.pending[id] + getSecurityWindow())\n revert GuardianFacet__PendingAdditionExpired();\n\n _removeGuardian(_guardian);\n delete gs.pending[id];\n emit GuardianRemoved(_guardian);\n }\n\n /**\n * @notice Cancel pending guardian addition\n * @dev This method checks if the previous request for guardian request exists.\n * It reverts if previous request is not pending and cancels the addition otherwise.\n * @param _guardian Guardian address to be canceled from addition\n */\n function cancelGuardianAddition(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingAddition();\n delete gs.pending[id];\n emit GuardianAdditionCancelled(_guardian);\n }\n\n /**\n * @notice Cancel pending guardian removal\n * @dev This method checks if the previous request for guardian request exists.\n * It reverts if previous request is not pending and cancels the removal otherwise.\n * @param _guardian Guardian address to be canceled from removal\n */\n function cancelGuardianRemoval(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingRemoval();\n delete gs.pending[id];\n emit GuardianRemovalCancelled(_guardian);\n }\n\n /**\n * @notice Get the addition security period of current account from security manager\n * @dev This method returns the uint value if addition security period\n * @return additionSecurityPeriod Uint256 value of addition security period\n */\n function getAdditionSecurityPeriod()\n public\n view\n override\n returns (uint256 additionSecurityPeriod)\n {\n additionSecurityPeriod = securityManager.additionSecurityPeriodOf(\n address(this)\n );\n if (additionSecurityPeriod == 0)\n revert GuardianFacet__InvalidAdditionSecurityPeriod();\n }\n\n /**\n * @notice Get the removal security period of current account from security manager\n * @dev This method returns the uint value if removal security period\n * @return removalSecurityPeriod Uint256 value of removal security period\n */\n function getRemovalSecurityPeriod()\n public\n view\n override\n returns (uint256 removalSecurityPeriod)\n {\n removalSecurityPeriod = securityManager.removalSecurityPeriodOf(\n address(this)\n );\n if (removalSecurityPeriod == 0)\n revert GuardianFacet__InvalidRemovalSecurityPeriod();\n }\n\n /**\n * @notice Get the security window of current account from security manager\n * @dev This method returns the uint value if security window\n * @return securityWindow Uint256 value of removal security period\n */\n function getSecurityWindow()\n public\n view\n override\n returns (uint256 securityWindow)\n {\n securityWindow = securityManager.securityWindowOf(address(this));\n if (securityWindow == 0) revert GuardianFacet__InvalidSecurityWindow();\n }\n\n /**\n * @notice Checks if the addition of the given guardian address is pending\n * @dev This method returns the bool value of whether the guardian address is pending addition\n * @return isPending Bool value of representing the pending of guardian addition\n */\n function isAdditionPending(\n address _guardian\n ) public view override returns (bool isPending) {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n isPending = _isPending(id);\n }\n\n /**\n * @notice Checks if the removal of the given guardian address is pending\n * @dev This method returns the bool value of whether the guardian address is pending removal\n * @return isPending Bool value of representing the pending of guardian removal\n */\n function isRemovalPending(\n address _guardian\n ) public view override returns (bool isPending) {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n isPending = _isPending(id);\n }\n\n /**\n * @notice Checks if the given hash is pending\n * @dev This method returns the bool value whether the hash is pending\n * @return isPending Bool value of representing the pending of guardian operation\n */\n function _isPending(\n bytes32 _idHash\n ) internal view returns (bool isPending) {\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n isPending = ((gs.pending[_idHash] > 0 &&\n gs.pending[_idHash] < block.timestamp) &&\n block.timestamp < gs.pending[_idHash] + getSecurityWindow());\n }\n\n /**\n * @notice Adds guardian to storage config. This is called when guardian is fully added.\n * @dev This method add guardian address and config information to Facet Storage dedicated for guardian\n * When this function is called, guardian is fully added to this Barz Smart Account\n * @param _guardian Address of guardian to be added\n */\n function _addGuardian(address _guardian) internal {\n if (!isAdditionPending(_guardian))\n revert GuardianFacet__InvalidGuardianAddition();\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n if (config.info[_guardian].exists)\n revert GuardianFacet__AlreadyExists();\n\n config.info[_guardian].exists = true;\n config.info[_guardian].index = uint128(config.addresses.length);\n config.addresses.push(_guardian);\n }\n\n /**\n * @notice Removes guardian to storage config. This is called when guardian is fully removed.\n * @dev This method remove guardian address and config information to Facet Storage dedicated for guardian\n * When this function is called, guardian is fully removed from this Barz Smart Account\n * @param _guardian Address of guardian to be removed\n */\n function _removeGuardian(address _guardian) internal {\n if (!isRemovalPending(_guardian))\n revert GuardianFacet__InvalidGuardianRemoval();\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n if (!config.info[_guardian].exists)\n revert GuardianFacet__NonExistentGuardian();\n\n address lastAddress = config.addresses[config.addresses.length - 1];\n if (_guardian != lastAddress) {\n uint128 targetIndex = config.info[_guardian].index;\n config.addresses[targetIndex] = lastAddress;\n config.info[lastAddress].index = targetIndex;\n }\n config.addresses.pop();\n delete config.info[_guardian];\n\n emit GuardianRemoved(_guardian);\n }\n\n /**\n * @notice Reads guardian storage and fetches the addresses into an array from the storage\n * @dev This method fetches the guardian storage and returns the list of guardian addresses\n * @return addresses Array of addresses comprised of guardian\n */\n function getGuardians()\n public\n view\n override\n returns (address[] memory addresses)\n {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n addresses = new address[](config.addresses.length);\n uint256 addressesLen = config.addresses.length;\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the number of majority of guardians\n * @return majorityOfGuardians_ Number of majority of guardians e.g., 2 if 3 guardians / 3 if 5 guardians\n */\n function majorityOfGuardians()\n public\n view\n override\n returns (uint256 majorityOfGuardians_)\n {\n majorityOfGuardians_ = LibGuardian.majorityOfGuardians();\n }\n\n /**\n * @notice Reads guardian storage and fetches the addresses into an array from the storage\n * @dev This method fetches the guardian storage and returns the list of guardian addresses\n * @return guardianNumber Array of guardians in the account\n */\n function guardianCount()\n public\n view\n override\n returns (uint256 guardianNumber)\n {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n guardianNumber = config.addresses.length;\n }\n\n /**\n * @notice Reads guardian storage and checks if the given address is a guardian\n * @return isGuardian_ Bool value representing if the given address is guardian\n */\n function isGuardian(\n address _guardian\n ) public view override returns (bool isGuardian_) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n isGuardian_ = config.info[_guardian].exists;\n }\n\n /**\n * @notice Checks if the guardian number is zero and returns of guardian facet is okay to be removed\n * @return isRemovable Bool value representing if guardian facet is removable\n */\n function isGuardianFacetRemovable()\n external\n view\n override\n returns (bool isRemovable)\n {\n isRemovable = (0 == guardianCount());\n }\n}\n" + }, + "contracts/facets/interfaces/IAccountFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IEntryPoint} from \"../../aa-4337/interfaces/IEntryPoint.sol\";\n\n/**\n * @title Account Facet Interface\n * @dev Interface of module contract that provides the account features and init/unitialization of signer\n * compatible with EIP-1271 & EIP-4337\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IAccountFacet {\n event AccountInitialized(\n IEntryPoint indexed entryPoint,\n bytes indexed ownerPublicKey\n );\n // NOTE: Added Below Event\n event VerificationSuccess(bytes32);\n event VerificationFailure(bytes32);\n\n error AccountFacet__InitializationFailure();\n error AccountFacet__RestrictionsFailure();\n error AccountFacet__NonExistentVerificationFacet();\n error AccountFacet__CallNotSuccessful();\n\n function initialize(\n address verificationFacet,\n address anEntryPoint,\n address facetRegistry,\n address _defaultFallBack,\n bytes calldata _ownerPublicKey\n ) external returns (uint256);\n\n function execute(address dest, uint256 value, bytes calldata func) external;\n\n function executeBatch(\n address[] calldata dest,\n uint256[] calldata value,\n bytes[] calldata func\n ) external;\n}\n" + }, + "contracts/facets/interfaces/IAccountRecoveryFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {RecoveryConfig} from \"../../libraries/LibFacetStorage.sol\";\n\n/**\n * @title Account Recovery Facet Interface\n * @dev Interface of contract that enables recovery of accounts when owner key is unavailable\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IAccountRecoveryFacet {\n event RecoveryExecuted(\n bytes indexed recoveryPublicKey,\n uint64 executeAfter\n );\n event RecoveryFinalized(bytes indexed recoveryPublicKey);\n event RecoveryCanceled(bytes indexed recoveryPublicKey);\n event RecoveryApproved(\n bytes indexed recoveryPublicKey,\n address indexed guardian,\n uint64 validUntil\n );\n event RecoveryApprovalRevoked(\n bytes indexed recoveryPublicKey,\n address indexed guardian\n );\n event RecoveryCancellationApproved(\n bytes indexed recoveryPublicKey,\n address indexed guardian\n );\n event RecoveryHardstopped();\n\n error AccountRecoveryFacet__CallerNotGuardian();\n error AccountRecoveryFacet__InvalidRecoveryPublicKey();\n error AccountRecoveryFacet__SignerInitializationFailure();\n error AccountRecoveryFacet__SignerUninitializationFailure();\n error AccountRecoveryFacet__InvalidArrayLength();\n error AccountRecoveryFacet__InsufficientGuardians();\n error AccountRecoveryFacet__RecoveryAlreadyOngoing();\n error AccountRecoveryFacet__NonexistentRecovery();\n error AccountRecoveryFacet__NonExistentApproval();\n error AccountRecoveryFacet__RecoveryPeriodNotOver();\n error AccountRecoveryFacet__InvalidLockPeriod();\n error AccountRecoveryFacet__InvalidRecoveryPeriod();\n error AccountRecoveryFacet__InvalidApprovalValidationPeriod();\n error AccountRecoveryFacet__InvalidGuardian();\n error AccountRecoveryFacet__InvalidGuardianSignature();\n error AccountRecoveryFacet__InvalidOwnerSignature();\n error AccountRecoveryFacet__CallNotSuccesful();\n error AccountRecoveryFacet__DuplicateApproval();\n\n function approveAccountRecovery(bytes calldata recoveryPublicKey) external;\n\n function revokeAccountRecoveryApproval(\n bytes calldata recoveryPublicKey\n ) external;\n\n function executeRecovery(\n bytes calldata recoveryPublicKey,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function finalizeRecovery() external;\n\n function approveCancelRecovery(bytes calldata recoveryPublicKey) external;\n\n function cancelRecovery(\n bytes calldata recoveryPublicKey,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function hardstopRecovery(bytes calldata signature) external;\n\n function getApprovalRecoveryKeyHash(\n bytes memory recoveryPublicKey,\n string memory saltString\n ) external view returns (bytes32);\n\n function getRecoveryApprovalCountWithTimeValidity(\n bytes32 recoveryPublicKeyHash\n ) external view returns (uint256);\n\n function isRecoveryApproved(\n bytes32 recoveryPublicKeyHash,\n address approver\n ) external view returns (bool);\n\n function getRecoveryNonce() external view returns (uint128);\n\n function getPendingRecovery() external view returns (RecoveryConfig memory);\n}\n" + }, + "contracts/facets/interfaces/IGuardianFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Guardian Facet Interface\n * @dev Interface of guaridna contract that enables addition/removal of guardians from Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IGuardianFacet {\n event GuardianAdditionRequested(\n address indexed guardian,\n uint256 executeAfter\n );\n event GuardianRemovalRequested(\n address indexed guardian,\n uint256 executeAfter\n );\n event GuardianAdditionCancelled(address indexed guardian);\n event GuardianRemovalCancelled(address indexed guardian);\n event GuardianAdded(address indexed guardian);\n event GuardianRemoved(address indexed guardian);\n\n error GuardianFacet__GuardianCannotBeSelf();\n error GuardianFacet__DuplicateGuardian();\n error GuardianFacet__OwnerCannotBeGuardian();\n error GuardianFacet__DuplicateGuardianAddition();\n error GuardianFacet__DuplicateGuardianRemoval();\n error GuardianFacet__UnknownPendingAddition();\n error GuardianFacet__PendingAdditionNotOver();\n error GuardianFacet__UnknownPendingRemoval();\n error GuardianFacet__PendingRemovalNotOver();\n error GuardianFacet__PendingAdditionExpired();\n error GuardianFacet__InvalidAdditionSecurityPeriod();\n error GuardianFacet__InvalidRemovalSecurityPeriod();\n error GuardianFacet__InvalidSecurityWindow();\n error GuardianFacet__NonExistentGuardian();\n error GuardianFacet__AlreadyExists();\n error GuardianFacet__InvalidGuardianAddition();\n error GuardianFacet__InvalidGuardianRemoval();\n error GuardianFacet__ZeroAddressGuardian();\n\n function addGuardian(address guardian) external;\n\n function addGuardians(address[] calldata guardians) external;\n\n function removeGuardian(address guardian) external;\n\n function removeGuardians(address[] calldata guardians) external;\n\n function confirmGuardianAddition(address guardian) external;\n\n function confirmGuardianAdditions(address[] calldata guardian) external;\n\n function confirmGuardianRemoval(address guardian) external;\n\n function confirmGuardianRemovals(address[] calldata guardian) external;\n\n function cancelGuardianAddition(address guardian) external;\n\n function cancelGuardianRemoval(address guardian) external;\n\n function isGuardian(address guardian) external view returns (bool);\n\n function isAdditionPending(address guardian) external view returns (bool);\n\n function isRemovalPending(address guardian) external view returns (bool);\n\n function isGuardianFacetRemovable() external view returns (bool);\n\n function getAdditionSecurityPeriod() external view returns (uint256);\n\n function getRemovalSecurityPeriod() external view returns (uint256);\n\n function getSecurityWindow() external view returns (uint256);\n\n function getGuardians() external view returns (address[] memory);\n\n function majorityOfGuardians() external view returns (uint256);\n\n function guardianCount() external view returns (uint256);\n}\n" + }, + "contracts/facets/interfaces/ILockFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Lock} from \"../../libraries/LibAppStorage.sol\";\n\n/**\n * @title Lock Facet Interface\n * @dev Interface of Lock contract that enables full lock/unlock of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface ILockFacet {\n event Locked(uint64 releaseAfter);\n event Unlocked();\n\n error LockFacet__InvalidRecoveryPeriod();\n error LockFacet__CannotUnlock();\n error LockFacet__InvalidSignature();\n error LockFacet__InvalidApprover();\n\n function lock() external;\n\n function unlock(address approver, bytes calldata signature) external;\n\n function getLockPeriod() external view returns (uint256);\n\n function isLocked() external view returns (bool);\n\n function getUnlockHash() external view returns (bytes32);\n\n function lockNonce() external view returns (uint128);\n\n function getPendingLock() external view returns (Lock memory);\n}\n" + }, + "contracts/facets/interfaces/IMultiSigFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Multi-sig facet Interface\n * @dev Interface of Multi-signature Facet with custom threshold.\n Wallet that adds this facet becomes a multi-sig wallet\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IMultiSigFacet {\n event ThresholdChanged(uint256 threshold);\n event OwnerAdded(address indexed newOwner);\n event OwnerRemoved(address indexed prevOwner);\n event HashApproved(bytes32 hashToApprove, address indexed owner);\n\n error MultiSigFacet__InvalidThreshold();\n error MultisigFacet__InvalidOwnerCount();\n error MultiSigFacet__InvalidRoute();\n error MultiSigFacet__InsufficientSignerLength();\n error MultiSigFacet__InvalidInitData();\n error MultiSigFacet__InvalidOwnerAddress();\n error MultiSigFacet__InvalidOwnerPair();\n error MultiSigFacet__InvalidSignatureLength();\n error MultiSigFacet__InvalidSignatureType();\n error MultiSigFacet__DuplicateOwner();\n error MultiSigFacet__OnlyOwner();\n\n function checkSignatures(\n bytes32 _dataHash,\n bytes calldata _signatures,\n uint256 _threshold\n ) external view returns (uint256);\n\n function splitSignatures(\n bytes calldata _signatures,\n uint256 _nextOffset\n )\n external\n pure\n returns (\n address owner,\n bytes memory signature,\n uint256 signatureType,\n uint256 nextOffset\n );\n\n function approveHash(bytes32 hashToApprove) external;\n\n function addOwner(address newOwner, uint256 threshold) external;\n\n function removeOwner(\n address prevOwner,\n address removedOwner,\n uint256 threshold\n ) external;\n\n function swapOwner(\n address prevOwner,\n address oldOwner,\n address newOwner\n ) external;\n\n function changeThreshold(uint256 _threshold) external;\n\n function isOwner(address owner) external view returns (bool);\n\n function getThreshold() external view returns (uint256);\n\n function getOwners() external view returns (address[] memory);\n}\n" + }, + "contracts/facets/interfaces/IRestrictionsFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Restrictions Facet Interface\n * @dev Interface of Restrictions contract that enables modular restrictions in Barz\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IRestrictionsFacet {\n event RestrictionAdded(address indexed restriction);\n event RestrictionRemoved(address indexed restriction);\n\n error RestrictionsFacet__EmptyRestrictionsList();\n error RestrictionsFacet__RestrictionNotFound();\n error RestrictionsFacet__RestrictionAlreadyExists();\n error RestrictionsFacet__ZeroAddressRestrictions();\n error RestrictionsFacet__ZeroAddressRestrictionsFacet();\n error RestrictionsFacet__RemainingRestrictionsCantBeEmpty();\n\n function initializeRestrictions(\n address[] memory _restrictions\n ) external returns (uint256);\n\n function uninitializeRestrictions() external returns (uint256);\n\n function getRestrictions() external view returns (address[] memory);\n\n function addRestriction(address restriction) external;\n\n function removeRestriction(address restriction) external;\n\n function verifyRestrictions(\n address from,\n address to,\n uint256 value,\n bytes calldata _calldata\n ) external returns (uint256);\n}\n" + }, + "contracts/facets/interfaces/ISignatureMigrationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureMigrationConfig} from \"../../libraries/LibFacetStorage.sol\";\n\n/**\n * @title Signature Migration Facet Interface\n * @dev Interface of Signature Migration contract for migrating user signature scheme to a new scheme user sets\n * Which could include\n * - ECDSA on Secp256K1 Curve\n * - ECDSA on Secp256R1 Curve\n * - BLS, Schnorr, etc\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface ISignatureMigrationFacet {\n event SignatureSchemeMigration(\n address indexed prevVerificationFacet,\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n event SignatureMigrationApproved(\n bytes newPublicKey,\n address indexed newVerificationFacet,\n bytes4[] verificationFuncSelectors,\n address indexed guardian,\n uint128 approvalValidUntil\n );\n event SignatureMigrationApprovalRevoked(\n bytes newPublicKey,\n address indexed newVerificationFacet,\n bytes4[] verificationFuncSelectors,\n address indexed guardian\n );\n event SignatureMigrationExecuted(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors,\n uint128 migrateAfter\n );\n event SignatureMigrationCanceled(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n event SignatureMigrationCancellationApproved(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n\n error SignatureMigrationFacet__SignerUninitializationFailure();\n error SignatureMigrationFacet__InvalidRouteWithGuardian();\n error SignatureMigrationFacet__InvalidKeyType();\n error SignatureMigrationFacet__InsufficientApprovers();\n error SignatureMigrationFacet__InvalidApproverSignature();\n error SignatureMigrationFacet__InvalidGuardian();\n error SignatureMigrationFacet__NonExistentApprover();\n error SignatureMigrationFacet__InvalidMigrationPeriod();\n error SignatureMigrationFacet__NonexistentMigration();\n error SignatureMigrationFacet__MigrationPeriodNotOver();\n error SignatureMigrationFacet__InvalidArrayLength();\n error SignatureMigrationFacet__InvalidApprovalValidationPeriod();\n error SignatureMigrationFacet__CannotRevokeUnapproved();\n error SignatureMigrationFacet__LackOfOwnerApproval();\n error SignatureMigrationFacet__OwnerAlreadyApproved();\n error SignatureMigrationFacet__NonExistentVerificationFacet();\n error SignatureMigrationFacet__DuplicateApproval();\n\n function migrateSignatureScheme(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function migrateSignatureSchemeWithGuardian(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors,\n address[] calldata approvers,\n bytes[] calldata signatures\n ) external;\n\n function approveSignatureSchemeMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function revokeSignatureMigrationApproval(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function finalizeSignatureMigration() external;\n\n function approveCancelSignatureMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function cancelSignatureMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function getApprovalMigrationKeyHash(\n bytes memory recoveryPublicKey,\n address newVerificationFacet,\n bytes4[] memory newVerificationFuncSelectors,\n string memory saltString\n ) external view returns (bytes32);\n\n function getMigrationOwnerApprovalWithTimeValidity(\n bytes32 publicKeyHash\n ) external view returns (bool);\n\n function getMigrationApprovalCountWithTimeValidity(\n bytes32 publicKeyHash\n ) external view returns (uint256);\n\n function isMigrationApproved(\n bytes32 migrationPublicKeyHash,\n address approver\n ) external view returns (bool);\n\n function getMigrationNonce() external view returns (uint128);\n\n function isMigrationPending() external view returns (bool);\n\n function getPendingMigration()\n external\n view\n returns (SignatureMigrationConfig memory);\n}\n" + }, + "contracts/facets/interfaces/IVerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {UserOperation} from \"../../aa-4337/interfaces/UserOperation.sol\";\n\n/**\n * @title Verification Facet Interface\n * @dev Implements logic for user ops signature verification\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface IVerificationFacet {\n event SignerInitialized(bytes);\n event SignerUninitialized();\n\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n error VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n error VerificationFacet__InitializationFailure();\n error VerificationFacet__InvalidFacetMapping();\n\n function initializeSigner(bytes memory) external returns (uint256);\n\n function uninitializeSigner() external returns (uint256);\n\n function validateOwnerSignatureSelector() external view returns (bytes4);\n\n function owner() external view returns (bytes memory);\n\n function isValidKeyType(bytes calldata) external view returns (bool);\n\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) external view returns (uint256);\n}\n" + }, + "contracts/facets/LockFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage, Lock} from \"../libraries/LibAppStorage.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibFacetStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {ILockFacet} from \"./interfaces/ILockFacet.sol\";\n\n/**\n * @title Lock Facet\n * @dev Contract that enables full lock/unlock of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract LockFacet is ILockFacet, Modifiers {\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Locks the account for the lock period. Lock period is defined in the security manager and it's customizable\n * This function can only be called when account is unlocked by owner or guardians\n * @dev This method checks the caller and if the account is currently locked and locks the account after fetching the\n * Lock period from the owner.\n */\n function lock() external override onlyGuardianOrOwner onlyWhenUnlocked {\n uint256 unlockTime = block.timestamp + getLockPeriod();\n ++LibFacetStorage.lockStorage().nonce;\n LibAppStorage.setLock(unlockTime, LockFacet.lock.selector);\n emit Locked(uint64(unlockTime));\n }\n\n /**\n * @notice Locks the account when the account is locked. This function can be called by anyone but must provide the approver address and signature.\n * The approver should be one of the guardians or owner.\n * @dev This method takes the approver address and the signature. After validating the address and the signature, it unlocks the account immediately.\n * Only one of the guardian or owner is required to lock and unlock the account.\n * @param _approver Address of approver approving the unlock of Barz account\n * @param _signature Signature of the approver that signed the msg hash for unlocking the account\n */\n function unlock(\n address _approver,\n bytes calldata _signature\n ) external override onlyWhenLocked {\n if (_approver != address(this) && !LibGuardian.isGuardian(_approver))\n revert LockFacet__InvalidApprover();\n if (\n !SignatureChecker.isValidSignatureNow(\n _approver,\n getUnlockHash(),\n _signature\n )\n ) revert LockFacet__InvalidSignature();\n _unlock();\n }\n\n /**\n * @notice Unlocks the account and increments the lock nonce\n */\n function _unlock() private {\n if (s.locks[INNER_STRUCT].locker != LockFacet.lock.selector)\n revert LockFacet__CannotUnlock();\n ++LibFacetStorage.lockStorage().nonce;\n LibAppStorage.setLock(0, bytes4(0));\n emit Unlocked();\n }\n\n /**\n * @notice Returns the lock period of current Barz account. Lock period information is held by Security Manager\n * @return lockPeriod Uint value of lock period in seconds\n */\n function getLockPeriod() public view override returns (uint256 lockPeriod) {\n lockPeriod = securityManager.lockPeriodOf(address(this));\n if (lockPeriod == 0) revert LockFacet__InvalidRecoveryPeriod();\n }\n\n /**\n * @notice Returns if the account is locked or not\n * @dev This method fetches the current block timestamp and compares that with release time.\n * After checking the timestamp and release time, it returns if the account is still locked or not.\n * @return isLocked_ Uint value of lock period in seconds\n */\n function isLocked() public view override returns (bool isLocked_) {\n isLocked_ = uint64(block.timestamp) < s.locks[INNER_STRUCT].release;\n }\n\n /**\n * @notice Calculates the unlock hash and returns the unlock hash safe from signature reply attack\n * @dev This method calculates the unlock hash with EIP-191 prefix, wallet address, chainID, and nonce\n * It packs the result and packs them and hashes it.\n * @return unlockHash Bytes32 unlock hash\n */\n function getUnlockHash() public view override returns (bytes32 unlockHash) {\n unlockHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n \"Unlock\",\n address(this),\n block.chainid,\n lockNonce()\n )\n )\n )\n );\n }\n\n /**\n * @notice Returns lock nonce of account. Reads nonce from lock storage within facet storage\n * @return lockNonce_ Uint128 value of lock nonce. This is incremented whenever the account is lock/unlocked\n */\n function lockNonce() public view override returns (uint128 lockNonce_) {\n lockNonce_ = LibFacetStorage.lockStorage().nonce;\n }\n\n /**\n * @notice Returns the overall information of current lock\n * @return pendingLock Struct value including all information of pending lock\n */\n function getPendingLock()\n public\n view\n override\n returns (Lock memory pendingLock)\n {\n pendingLock = s.locks[INNER_STRUCT];\n }\n}\n" + }, + "contracts/facets/Modifiers.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {IFacetRegistry} from \"../infrastructure/interfaces/IFacetRegistry.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\n\n/**\n * @title Modifiers\n * @dev Responsible for providing modifiers/util functions to Facet contracts\n * @author David Yongjun Kim (@Powerstream3604)\n */\nabstract contract Modifiers is BarzStorage {\n uint8 constant INNER_STRUCT = 0;\n\n error CallerNotGuardian();\n error CallerNotGuardianOrOwner();\n error DuplicateApprover();\n error ZeroApproverLength();\n error UnregisteredFacetAndSelectors();\n\n /**\n * @notice Modifier to only allow guardian to make a call, reverts if any other entity is the caller\n */\n modifier onlyGuardian() {\n if (!LibGuardian.isGuardian(msg.sender)) revert CallerNotGuardian();\n _;\n }\n\n /**\n * @notice Modifier to only allow guardian or owner to make a call, reverts if any other entity is the caller\n */\n modifier onlyGuardianOrOwner() {\n if (!LibGuardian.isGuardian(msg.sender) && address(this) != msg.sender)\n revert CallerNotGuardianOrOwner();\n _;\n }\n\n /**\n * @notice Checks if the approver address is the array is unique with no duplicate\n * @dev This method loops through the array and checks if a duplicate address exists, it reverts if duplicate address exists\n * @param approvers Array of address\n */\n function _checkApprover(\n address[] memory approvers\n ) internal pure returns (bool) {\n uint256 approverLength = approvers.length;\n if (0 == approverLength) revert ZeroApproverLength();\n for (uint256 i; i < approverLength - 1; ) {\n for (uint256 j = i + 1; j < approverLength; ) {\n if (approvers[i] == approvers[j]) {\n revert DuplicateApprover(); // Found a duplicate\n }\n unchecked {\n ++j;\n }\n }\n unchecked {\n ++i;\n }\n }\n return false; // No duplicates found\n }\n\n /**\n * @notice Checks if the facet getting added or replaced is registered to facet registry\n * @dev This method loops through the cut and checks if the facet getting added/replaced is registered to facet registry\n * @param _diamondCut Array of FacetCut, data for diamondCut defined in EIP-2535\n */\n function _checkFacetCutValidity(\n IDiamondCut.FacetCut[] memory _diamondCut\n ) internal view {\n uint256 diamondCutLength = _diamondCut.length;\n for (uint256 i; i < diamondCutLength; ) {\n if (\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Add ||\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Replace\n ) {\n if (\n !s.facetRegistry.areFacetFunctionSelectorsRegistered(\n _diamondCut[i].facetAddress,\n _diamondCut[i].functionSelectors\n )\n ) revert UnregisteredFacetAndSelectors();\n }\n unchecked {\n ++i;\n }\n }\n }\n}\n" + }, + "contracts/facets/RestrictionsFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, RestrictionsStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {IRestriction} from \"../restrictions/IRestriction.sol\";\nimport {IRestrictionsFacet} from \"./interfaces/IRestrictionsFacet.sol\";\n\n/**\n * @title Restrictions facet\n * @dev Responsible for storing and verifying different kinds of restrictions, for example:\n * - Whitelist / Blacklist\n * - Daily limits\n * - Trading time restrictions\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract RestrictionsFacet is IRestrictionsFacet {\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceRestrictionsInitialize();\n }\n\n /**\n * @notice Intialize restrictions of Barz. Restrictions facet call restriction contracts for restriction validation\n * before each call\n * @param _restrictions The initial array of restrictions.\n * @return initSuccess Int value showing if the initialization of restriction is successful\n */\n function initializeRestrictions(\n address[] calldata _restrictions\n ) public override returns (uint256 initSuccess) {\n LibDiamond.enforceIsSelf();\n LibAppStorage.enforceRestrictionsInitialize();\n\n uint256 restrictionsLength = _restrictions.length;\n if (restrictionsLength == 0) {\n // You can't initialize RestrictionsFacet with an empty list of restrictions\n revert RestrictionsFacet__EmptyRestrictionsList();\n }\n for (uint256 i; i < restrictionsLength; ) {\n if (_restrictions[i] == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictions();\n unchecked {\n ++i;\n }\n }\n\n LibFacetStorage.restrictionsStorage().restrictions = _restrictions;\n _updateRestrictionsMap(_restrictions, true);\n initSuccess = 1;\n }\n\n /**\n * @notice Unitialize restrictions of Barz\n * @return uninitSuccess Int value showing if the initialization of restriction is successful\n */\n function uninitializeRestrictions()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibDiamond.enforceIsSelf();\n LibAppStorage.setRestrictionsUninitialized();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n _updateRestrictionsMap(restrictionsStorage.restrictions, false);\n restrictionsStorage.restrictions = new address[](0);\n uninitSuccess = 1;\n }\n\n /**\n * @notice Returns the list of Restrictions contract address\n * @return restrictions Addresses of IRestriction which are currently active\n */\n function getRestrictions()\n public\n view\n override\n returns (address[] memory restrictions)\n {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n restrictions = restrictionsStorage.restrictions;\n }\n\n /**\n * @notice Adds restrictions to Barz with validation on the restriction contract address.\n * This method is only callable by the owner(self).\n * @param _restriction The address of the restriction to be added.\n */\n function addRestriction(address _restriction) external override {\n LibDiamond.enforceIsSelf();\n if (LibDiamond.restrictionsFacet() == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictionsFacet();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n if (_restriction == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictions();\n if (restrictionsStorage.exists[_restriction])\n revert RestrictionsFacet__RestrictionAlreadyExists();\n\n restrictionsStorage.restrictions.push(_restriction);\n restrictionsStorage.exists[_restriction] = true;\n\n emit RestrictionAdded(_restriction);\n }\n\n /**\n * @notice Remove restrictions from Barz if it existed. This method is only callable by the owner(self).\n * @param _restriction The address of the restriction to be removed.\n */\n function removeRestriction(address _restriction) external override {\n LibDiamond.enforceIsSelf();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n if (!restrictionsStorage.exists[_restriction])\n revert RestrictionsFacet__RestrictionNotFound();\n\n address[] storage restrictions = restrictionsStorage.restrictions;\n\n uint256 indexToDelete = restrictions.length;\n uint256 restrictionsLen = restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n if (restrictions[i] == _restriction) {\n indexToDelete = i;\n break;\n }\n unchecked {\n ++i;\n }\n }\n\n if (indexToDelete == 0 && restrictionsLen == 1) {\n revert RestrictionsFacet__RemainingRestrictionsCantBeEmpty();\n } else if (indexToDelete == restrictionsLen) {\n revert RestrictionsFacet__RestrictionNotFound();\n } else {\n restrictions[indexToDelete] = restrictions[restrictionsLen - 1];\n restrictions.pop();\n }\n\n restrictionsStorage.exists[_restriction] = false;\n emit RestrictionRemoved(_restriction);\n }\n\n /**\n * @notice Sets the restrictions address value mapping to true or false when adding/removing restriction contracts\n * @param _restrictions List of restriction contracts address\n * @param _newValue Bool value to flag to the list of restrictions contracts\n */\n function _updateRestrictionsMap(\n address[] memory _restrictions,\n bool _newValue\n ) internal {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n uint restrictionsLen = _restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n restrictionsStorage.exists[_restrictions[i]] = _newValue;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @dev Iterates over all restrictions and verifies each of them with the transaction parameters.\n * @param _from The address of the sender, that will be signing the transaction.\n * @param _to The receiving address.\n * @param _value Amount of ETH to transfer from sender to recipient.\n * @param _calldata Optional field to include arbitrary data.\n * @return 0 if all the checks passed, 1 otherwise.\n */\n function verifyRestrictions(\n address _from,\n address _to,\n uint256 _value,\n bytes calldata _calldata\n ) external returns (uint256) {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n uint restrictionsLen = restrictionsStorage.restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n IRestriction restriction = IRestriction(\n restrictionsStorage.restrictions[i]\n );\n bool checkPassed = restriction.check(_from, _to, _value, _calldata);\n if (!checkPassed) {\n return 1;\n }\n unchecked {\n ++i;\n }\n }\n\n return 0;\n }\n}\n" + }, + "contracts/facets/SignatureMigrationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, SignatureMigrationStorage, SignatureMigrationConfig, SignatureMigrationApprovalConfig, ApprovalConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IDiamondCut} from \"./base/interfaces/IDiamondCut.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {ISignatureMigrationFacet} from \"./interfaces/ISignatureMigrationFacet.sol\";\n\n/**\n * @title Signature Migration Facet\n * @dev Responsible for migrating user signature scheme to a new scheme user sets\n * Which could include\n * - ECDSA on Secp256K1 Curve\n * - ECDSA on Secp256R1 Curve\n * - BLS, Schnorr, etc\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract SignatureMigrationFacet is ISignatureMigrationFacet, Modifiers {\n /**\n * @notice This modifier verifies if the public key format matches with the new verification facet\n * @param _publicKey Bytes of public key to be validated for the new verification facet\n * @param _newVerificationFacet Address of new verification facet\n */\n modifier validateKeyType(\n bytes memory _publicKey,\n address _newVerificationFacet\n ) {\n if (\n !IVerificationFacet(_newVerificationFacet).isValidKeyType(\n _publicKey\n )\n ) revert SignatureMigrationFacet__InvalidKeyType();\n _;\n }\n\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n // IMPORTANT NOTE: In the client side when they call this function, the func selectors should be sorted in ascending order\n // to prevent different hash with same items in the array\n /**\n * @notice Moves the state of migration to a pending state. When pending state is over after pending period time,\n * Migration can be finalized. This function can only be called by self and when the account is unlocked.\n * @dev This method checks if the caller is self and if guardians exists. It migrates signature request to a pending state\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function migrateSignatureScheme(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n public\n override\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n // Only self contract can call this function\n LibDiamond.enforceIsSelf();\n // Should revert if guardian exist\n if (0 != LibGuardian.guardianCount())\n revert SignatureMigrationFacet__InvalidRouteWithGuardian();\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n // NOTE: Migration requires a pending period & confirmation from owner to prevent a\n // single call changing the ownership of the wallet\n /**\n * @notice Migrate signature scheme when guardians exists. Verifies the signature of guardians and moves migration to pending state.\n * Which can then be finalized when pending period is over. Owner's approval is mandatory for migration to happen\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _approvers List of approvers. This could include owner\n */\n function migrateSignatureSchemeWithGuardian(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n )\n public\n override\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n // Should revert if does not guardian exist\n if (0 == LibGuardian.guardianCount())\n revert SignatureMigrationFacet__InvalidRouteWithGuardian();\n uint256 approversLength = _approvers.length;\n if (approversLength != _signatures.length)\n revert SignatureMigrationFacet__InvalidArrayLength();\n\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(migrationPublicKeyHash, _approvers);\n\n bool onChainOwnerApproval = getMigrationOwnerApprovalWithTimeValidity(\n migrationPublicKeyHash\n );\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n\n if (\n approversLength +\n getMigrationApprovalCountWithTimeValidity(\n migrationPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert SignatureMigrationFacet__InsufficientApprovers();\n {\n // To prevent Stack too deep\n bool ownerApproved;\n for (uint256 i; i < approversLength; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n address(this) != _approvers[i]\n ) revert SignatureMigrationFacet__InvalidGuardian();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert SignatureMigrationFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n migrationPublicKeyHash,\n _signatures[i]\n )\n ) revert SignatureMigrationFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n\n if (!ownerApproved && !onChainOwnerApproval)\n revert SignatureMigrationFacet__LackOfOwnerApproval();\n }\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Internal function that moves signature mgiration to a pending state.\n * @dev This method increments migration nonce and sets the migration in the migration config. Emits events for migration execution\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _migrateSignatureScheme(\n address _newVerificationFacet,\n bytes memory _newPublicKey,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal {\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n\n ++ms.nonce;\n uint64 migrateAfter = uint64(block.timestamp + getMigrationPeriod());\n\n ms.migrationConfigs[INNER_STRUCT] = SignatureMigrationConfig(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n migrateAfter\n );\n\n emit SignatureMigrationExecuted(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors,\n migrateAfter\n );\n }\n\n /**\n * @notice Approves signature scheme migration on-chain. This can be called by owner or guardian only when the account is unlocked.\n * When the threshold of the migration approval passed and owner approval is granted, it automatically moves migration to a pending state\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function approveSignatureSchemeMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n public\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit SignatureMigrationApproved(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n msg.sender,\n approvalValidUntil\n );\n if (\n getMigrationApprovalCountWithTimeValidity(migrationPublicKeyHash) >=\n LibGuardian.majorityOfGuardians() &&\n getMigrationOwnerApprovalWithTimeValidity(migrationPublicKeyHash)\n )\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Revokes the approval of signature migration done on-chain. Emits revoke event when revoked.\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function revokeSignatureMigrationApproval(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n external\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n if (!isMigrationApproved(migrationPublicKeyHash, msg.sender))\n revert SignatureMigrationFacet__CannotRevokeUnapproved();\n\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(false, 0);\n emit SignatureMigrationApprovalRevoked(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n msg.sender\n );\n }\n\n /**\n * @notice Finalizes the pending signature scheme migration. This function can only be called by owner.\n * It removes the facets of the previous verification facet and adds the new verification facet.\n * After finalizing migration, it emits migration event which shows the change of the verification facet\n */\n function finalizeSignatureMigration() external override {\n // NOTE: Only owner can call this function\n LibDiamond.enforceIsSelf();\n\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n\n if (!isMigrationPending())\n revert SignatureMigrationFacet__NonexistentMigration();\n\n if (\n uint64(block.timestamp) <=\n ms.migrationConfigs[INNER_STRUCT].migrateAfter\n ) revert SignatureMigrationFacet__MigrationPeriodNotOver();\n address newVerificationFacet = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationVerificationFacet;\n bytes4[] memory newVerificationFuncSelectors = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationSelectors;\n bytes memory newPublicKey = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationPublicKey;\n\n address prevVerificationFacet = LibLoupe.facetAddress(\n s.validateOwnerSignatureSelector\n );\n if (prevVerificationFacet == address(0))\n revert SignatureMigrationFacet__NonExistentVerificationFacet();\n\n IDiamondCut.FacetCut[] memory UninitCut;\n IDiamondCut.FacetCut[] memory InitCut;\n {\n bytes4[] memory prevVerificationFuncSelectors = LibLoupe\n .facetFunctionSelectors(prevVerificationFacet);\n\n UninitCut = new IDiamondCut.FacetCut[](1);\n InitCut = new IDiamondCut.FacetCut[](1);\n UninitCut[0] = IDiamondCut.FacetCut({\n facetAddress: address(0),\n action: IDiamondCut.FacetCutAction.Remove,\n functionSelectors: prevVerificationFuncSelectors\n });\n InitCut[0] = IDiamondCut.FacetCut({\n facetAddress: newVerificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: newVerificationFuncSelectors\n });\n {\n IDiamondCut.FacetCut[]\n memory facetCuts = new IDiamondCut.FacetCut[](2);\n facetCuts[0] = UninitCut[0];\n facetCuts[1] = InitCut[0];\n _checkFacetCutValidity(facetCuts);\n }\n LibAppStorage.initiateSignerMigration();\n address verificationFacet = address(\n bytes20(\n LibDiamond.diamondStorage().facets[\n s.validateOwnerSignatureSelector\n ]\n )\n );\n bytes memory uninitCall = abi.encodeWithSignature(\n \"uninitializeSigner()\"\n );\n (bool success, bytes memory result) = verificationFacet\n .delegatecall(uninitCall);\n require(success, \"MigrationFacet: uninitialize not successful\");\n uint256 validationData = uint256(bytes32(result));\n if (validationData == 0)\n revert SignatureMigrationFacet__SignerUninitializationFailure();\n\n LibDiamond.diamondCut(UninitCut, address(0), \"\");\n }\n {\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n newPublicKey\n );\n\n // Every Verification Facet should comply with initializeSigner(bytes)\n // to be compatible with the Barz contract(for initialization)\n LibDiamond.diamondCut(InitCut, newVerificationFacet, initCall);\n LibAppStorage.finalizeSignerMigration();\n emit SignatureSchemeMigration(\n prevVerificationFacet,\n newVerificationFacet,\n newPublicKey,\n newVerificationFuncSelectors\n );\n }\n }\n\n /**\n * @notice Approve cancellation of signature migration. If cancellation approval passes guardian threshold with owner approval\n * it automatically cancels the migration.\n * @dev This method checks if the caller is one of guardian or owner and sets true for the cancellation hash in the approval config.\n * It internally calls _cancelSignatureMigration for canceling the migration\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function approveCancelSignatureMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n external\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"CancelSignatureMigration\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit SignatureMigrationCancellationApproved(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n if (\n getMigrationApprovalCountWithTimeValidity(migrationPublicKeyHash) >=\n LibGuardian.majorityOfGuardians() &&\n getMigrationOwnerApprovalWithTimeValidity(migrationPublicKeyHash)\n )\n _cancelSignatureMigration(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Verifies the signature of guardians/owner and cancels the signature migration.\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _approvers List of approvers. This could include owner\n */\n function cancelSignatureMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n )\n external\n override\n validateKeyType(_newPublicKey, _newVerificationFacet)\n onlyWhenUnlocked\n {\n uint256 approversLength = _approvers.length;\n if (approversLength != _signatures.length)\n revert SignatureMigrationFacet__InvalidArrayLength();\n\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"CancelSignatureMigration\"\n );\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(migrationPublicKeyHash, _approvers);\n\n bool onChainOwnerApproval = getMigrationOwnerApprovalWithTimeValidity(\n migrationPublicKeyHash\n );\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n if (\n approversLength +\n getMigrationApprovalCountWithTimeValidity(\n migrationPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert SignatureMigrationFacet__InsufficientApprovers();\n {\n // To prevent stack too deep\n bool ownerApproved;\n for (uint256 i; i < approversLength; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n address(this) != _approvers[i]\n ) revert SignatureMigrationFacet__NonExistentApprover();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert SignatureMigrationFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n migrationPublicKeyHash,\n _signatures[i]\n )\n ) revert SignatureMigrationFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n if (!ownerApproved && !onChainOwnerApproval)\n revert SignatureMigrationFacet__LackOfOwnerApproval();\n }\n _cancelSignatureMigration(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Internal function that cancels signature migration.\n * @dev This method increments migration nonce and deletes the migration from the migration config. Emits events for migration cancellation\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _cancelSignatureMigration(\n address _newVerificationFacet,\n bytes memory _newPublicKey,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal {\n if (!isMigrationPending())\n revert SignatureMigrationFacet__NonexistentMigration();\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n ++ms.nonce;\n delete ms.migrationConfigs[INNER_STRUCT];\n emit SignatureMigrationCanceled(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Checks if the facets to be added from new verification facet is registered to facet registry\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _checkMigrationCutValidity(\n address _newVerificationFacet,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal view {\n IDiamondCut.FacetCut[] memory facetCuts = new IDiamondCut.FacetCut[](1);\n facetCuts[0] = IDiamondCut.FacetCut({\n facetAddress: _newVerificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: _newVerificationFuncSelectors\n });\n _checkFacetCutValidity(facetCuts);\n }\n\n /**\n * @notice Returns if the migration is pending of not\n * @dev This method fetches the migration storage and checks if the migrate after is above 0 value\n * @return isPending Bool value that shows if the migration is pending\n */\n function isMigrationPending()\n public\n view\n override\n returns (bool isPending)\n {\n SignatureMigrationStorage storage rs = LibFacetStorage\n .migrationStorage();\n isPending = rs.migrationConfigs[INNER_STRUCT].migrateAfter > 0;\n }\n\n /**\n * @notice Returns the migration hash. This function ensures that this hash is safe from replay attack by including\n * public key, verification facet, function selectors, salt, address, chainId, and nonce.\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _saltString Salt value for generating the migration hash\n * @return migrationKeyHash Bytes32 string of the migration key hash\n */\n function getApprovalMigrationKeyHash(\n bytes memory _newPublicKey,\n address _newVerificationFacet,\n bytes4[] memory _newVerificationFuncSelectors,\n string memory _saltString\n ) public view override returns (bytes32 migrationKeyHash) {\n migrationKeyHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n _newPublicKey,\n _newVerificationFacet,\n keccak256(abi.encode(_newVerificationFuncSelectors)),\n _saltString,\n address(this),\n block.chainid,\n LibFacetStorage.migrationStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Checks if the owner approved the hash for migration\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @return isApprovedByOwner Bool value of showing if the owner approved it or not\n */\n function getMigrationOwnerApprovalWithTimeValidity(\n bytes32 _migrationPublicKeyHash\n ) public view override returns (bool isApprovedByOwner) {\n isApprovedByOwner = isMigrationApproved(\n _migrationPublicKeyHash,\n address(this)\n );\n }\n\n /**\n * @notice Checks how many of the guardians approved the migration hash\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @return approvalCount Number of approvals\n */\n function getMigrationApprovalCountWithTimeValidity(\n bytes32 _migrationPublicKeyHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardiansLength = guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n if (isMigrationApproved(_migrationPublicKeyHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n return approvalCount;\n }\n\n /**\n * @notice Checks if the migration is approved by the given approver\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @param _approver Address of approver\n * @return isApproved Bool value if migration hash is approved\n */\n function isMigrationApproved(\n bytes32 _migrationPublicKeyHash,\n address _approver\n ) public view override returns (bool isApproved) {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n isApproved = (ms\n .isMigrationApproved[_migrationPublicKeyHash][_approver].isApproved &&\n block.timestamp <\n ms\n .isMigrationApproved[_migrationPublicKeyHash][_approver]\n .validUntil);\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _migrationPublicKeyHash Hash of migration information\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _migrationPublicKeyHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isMigrationApproved(_migrationPublicKeyHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert SignatureMigrationFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the migration period of this wallet\n * @dev This method fetches the migration period from the security manager\n * @return migrationPeriod Migration period of Barz contract fetched from security manager\n */\n function getMigrationPeriod()\n internal\n view\n returns (uint128 migrationPeriod)\n {\n migrationPeriod = securityManager.migrationPeriodOf(address(this));\n if (migrationPeriod == 0)\n revert SignatureMigrationFacet__InvalidMigrationPeriod();\n }\n\n /**\n * @notice Returns the validation period of this wallet\n * @dev This method fetches the validation period from the security manager\n * @return approvalValidationPeriod Validation period of Barz contract fetched from security manager\n */\n function getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod == 0)\n revert SignatureMigrationFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the migration nonce of this wallet\n * @dev This method fetches the nonce from migration storage\n * @return migrationNonce Nonce of migration to protect from reply attacks\n */\n function getMigrationNonce()\n public\n view\n override\n returns (uint128 migrationNonce)\n {\n migrationNonce = LibFacetStorage.migrationStorage().nonce;\n }\n\n /**\n * @notice Returns the migration configuration of this wallet\n * @dev This method fetches the migration config from the migration storage\n * @return pendingMigrationConfig Migration config currently pending for signature migration\n */\n function getPendingMigration()\n external\n view\n override\n returns (SignatureMigrationConfig memory pendingMigrationConfig)\n {\n pendingMigrationConfig = LibFacetStorage\n .migrationStorage()\n .migrationConfigs[INNER_STRUCT];\n }\n}\n" + }, + "contracts/facets/TokenReceiverFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {IERC1155Receiver} from \"../interfaces/ERC/IERC1155Receiver.sol\";\nimport {IERC677Receiver} from \"../interfaces/ERC/IERC677Receiver.sol\";\n\n/**\n * @title TokenReceiver Facet\n * @dev Contract that enables receiving ERC721/ERC1155/ERC777/ERC677 Tokens with safe transfer\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract TokenReceiverFacet is\n IERC721Receiver,\n IERC1155Receiver,\n IERC777Recipient,\n IERC677Receiver\n{\n /**\n * @notice Handles ERC721 Token callback.\n * return Standardized onERC721Received return value.\n */\n function onERC721Received(\n address,\n address,\n uint256,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC721Receiver.onERC721Received.selector;\n }\n\n /**\n * @notice Handles ERC1155 Token callback.\n * return Standardized onERC1155Received return value.\n */\n function onERC1155Received(\n address,\n address,\n uint256,\n uint256,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC1155Receiver.onERC1155Received.selector;\n }\n\n /**\n * @notice Handles ERC1155 Token batch callback.\n * return Standardized onERC1155BatchReceived return value.\n */\n function onERC1155BatchReceived(\n address,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC1155Receiver.onERC1155BatchReceived.selector;\n }\n\n /**\n * @notice Handles ERC777 Token callback.\n * Does not return value, empty implementation.\n */\n function tokensReceived(\n address,\n address,\n address,\n uint256,\n bytes calldata,\n bytes calldata\n ) external pure override {}\n\n /**\n * @notice Handles ERC677 Token callback.\n * return true.\n */\n function onTokenTransfer(\n address,\n uint256,\n bytes calldata\n ) external pure override returns (bool) {\n return true;\n }\n}\n" + }, + "contracts/facets/verification/MultiSigFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {UserOperation} from \"../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../../libraries/LibLoupe.sol\";\nimport {LibAppStorage} from \"../../libraries/LibAppStorage.sol\";\nimport {LibMultiSigStorage, MultiSigStorage} from \"../../libraries/LibMultiSigStorage.sol\";\nimport {IERC1271} from \"../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../interfaces/IVerificationFacet.sol\";\nimport {IMultiSigFacet} from \"../interfaces/IMultiSigFacet.sol\";\n\n/**\n * @title Multi-sig facet\n * @dev Multi-signature Facet with custom threshold.\n * Wallet that adds this facet becomes a multi-sig wallet.\n * Reference signature_format.md documentation for Multi-sig facet details\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract MultiSigFacet is IMultiSigFacet, IVerificationFacet, IERC1271 {\n using ECDSA for bytes32;\n\n address public immutable self;\n\n address internal constant SENTINEL_OWNERS = address(0x1);\n uint256 internal constant ADDRESS = 20;\n uint256 internal constant SIG_TYPE = 1;\n uint256 internal constant SIG_LEN = 4;\n uint256 internal constant THRESHOLD = 4;\n uint256 internal constant INVALID_SIG = 1;\n uint256 internal constant VALID_SIG = 0;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in Multisig Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the right format and initializes signer storage in k1 storage.\n * @param _owners Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _owners\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n\n if (!isValidKeyType(_owners)) revert MultiSigFacet__InvalidInitData();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n uint256 threshold = uint256(uint32(bytes4(_owners)));\n uint256 ownerCount = (_owners.length - THRESHOLD) / ADDRESS;\n\n if (threshold == 0) revert MultiSigFacet__InvalidThreshold();\n if (ownerCount == 0) revert MultisigFacet__InvalidOwnerCount();\n\n address currentOwner = SENTINEL_OWNERS;\n uint256 ptr = THRESHOLD;\n address owner_;\n for (uint256 i; i < ownerCount; ) {\n owner_ = address(bytes20(_owners[ptr:ptr + ADDRESS]));\n ptr += ADDRESS;\n if (\n owner_ == address(0) ||\n owner_ == SENTINEL_OWNERS ||\n owner_ == address(this) ||\n owner_ == currentOwner\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[owner_] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n\n ms.owners[currentOwner] = owner_;\n currentOwner = owner_;\n\n unchecked {\n ++i;\n }\n }\n ms.owners[currentOwner] = SENTINEL_OWNERS;\n ms.ownerCount = ownerCount;\n ms.threshold = threshold;\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_owners);\n }\n\n /**\n * @notice Uninitialize signer in K1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n ++ms.counter;\n address[] memory ownerlist = getOwners();\n uint256 ownerlistLength = ownerlist.length;\n for (uint256 i; i < ownerlistLength; ) {\n ms.owners[ownerlist[i]] = address(0);\n unchecked {\n ++i;\n }\n }\n ms.owners[SENTINEL_OWNERS] = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls checkSignatures with\n * user operation hash and signature together with the threshold.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n // Data 1 is invalid, Data 0 is valid\n validationData = checkSignatures(\n userOpHash,\n userOp.signature,\n LibMultiSigStorage.multisigStorage().threshold\n );\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n return this.validateOwnerSignature.selector;\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n uint totalLength = ms.ownerCount * ADDRESS;\n bytes memory result = new bytes(totalLength);\n\n // populate return array\n uint256 index;\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n while (currentOwner != SENTINEL_OWNERS) {\n assembly {\n mstore(\n add(result, add(32, mul(index, ADDRESS))),\n shl(96, currentOwner)\n )\n }\n currentOwner = ms.owners[currentOwner];\n index++;\n }\n\n return result;\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key should comply with the format in the signature_format.md doc\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n uint256 publicKeyLength = _publicKey.length;\n if (\n publicKeyLength < ADDRESS + THRESHOLD ||\n (publicKeyLength - THRESHOLD) % ADDRESS != 0\n ) return false;\n\n uint256 threshold = uint256(uint32(bytes4(_publicKey)));\n uint256 ownerCount = (publicKeyLength - THRESHOLD) / ADDRESS;\n\n isValid = !(ownerCount < threshold || threshold == 0);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes calldata _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (checkSignatures(\n _hash,\n _signature,\n LibMultiSigStorage.multisigStorage().threshold\n ) == VALID_SIG)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n\n /**\n * @notice Validates the format of the signature and verifies if the signature is signed by the expected key.\n * Reference signature_format.md doc for details about signature format and signature types\n * @param _dataHash Bytes value of data hash signed by the owners\n * @param _signatures Bytes value of signature which should comply with signature format\n * @param _threshold Uint256 value of current Multi-sig Barz's threshold\n */\n function checkSignatures(\n bytes32 _dataHash,\n bytes calldata _signatures,\n uint256 _threshold\n ) public view returns (uint256) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n address lastOwner = address(0);\n address currentOwner;\n bytes memory signature;\n uint256 signatureType;\n uint256 nextOffset;\n uint256 i;\n for (i; i < _threshold; ) {\n (\n currentOwner,\n signature,\n signatureType,\n nextOffset\n ) = splitSignatures(_signatures, nextOffset);\n if (nextOffset == 0 && i + 1 < _threshold) return INVALID_SIG;\n if (signatureType == 1) {\n // If signatureType is 1 then it is default dataHash signed.\n // This also includes the contract signature\n if (\n !SignatureChecker.isValidSignatureNow(\n currentOwner,\n _dataHash,\n signature\n )\n ) return INVALID_SIG;\n } else if (signatureType == 2) {\n // If signatureType is 2 then it is an approved hash\n if (ms.approvedHashes[ms.counter][currentOwner][_dataHash] == 0)\n return INVALID_SIG;\n } else if (signatureType == 3) {\n // If signatureType is 3 then it is a signed message hash\n // This also includes the contract signature\n bytes32 msgHash = _dataHash.toEthSignedMessageHash();\n if (\n !SignatureChecker.isValidSignatureNow(\n currentOwner,\n msgHash,\n signature\n )\n ) return INVALID_SIG;\n } else revert MultiSigFacet__InvalidRoute();\n if (\n currentOwner <= lastOwner ||\n ms.owners[currentOwner] == address(0) ||\n currentOwner == SENTINEL_OWNERS\n ) return INVALID_SIG;\n lastOwner = currentOwner;\n\n unchecked {\n ++i;\n }\n }\n return VALID_SIG;\n }\n\n /**\n * @notice Split signatures into each individual signatures. Should comply with signature format to be split\n * @param _signatures Bytes value of signature\n * @param _nextOffset Uint256 value of next offset to start splitting the signature\n */\n function splitSignatures(\n bytes calldata _signatures,\n uint256 _nextOffset\n )\n public\n pure\n returns (\n address owner_,\n bytes memory signature,\n uint256 signatureType,\n uint256 nextOffset\n )\n {\n uint256 signaturesLength = _signatures.length;\n\n if (signaturesLength <= _nextOffset + ADDRESS + SIG_LEN)\n revert MultiSigFacet__InsufficientSignerLength();\n\n owner_ = address(\n bytes20(_signatures[_nextOffset:_nextOffset + ADDRESS])\n );\n\n signatureType = uint256(\n uint8(\n bytes1(\n _signatures[_nextOffset + ADDRESS:_nextOffset +\n ADDRESS +\n SIG_TYPE]\n )\n )\n );\n\n if (signatureType > 3 || signatureType == 0)\n revert MultiSigFacet__InvalidSignatureType();\n uint256 offSet = _nextOffset + ADDRESS + SIG_TYPE;\n uint256 siglen = uint256(\n uint32(bytes4(_signatures[offSet:offSet + SIG_LEN]))\n );\n if (offSet + siglen > signaturesLength)\n revert MultiSigFacet__InvalidSignatureLength();\n\n offSet += SIG_LEN;\n if (offSet + siglen == signaturesLength) nextOffset = 0;\n else nextOffset = offSet + siglen;\n\n signature = _signatures[offSet:offSet + siglen];\n }\n\n /**\n * @notice Approves the hash of userOperation on-chain. This can only be called by owners.\n * @param _hashToApprove Bytes value of UserOperation hash to approve\n */\n function approveHash(bytes32 _hashToApprove) external {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (ms.owners[msg.sender] == address(0))\n revert MultiSigFacet__OnlyOwner();\n\n ms.approvedHashes[ms.counter][msg.sender][_hashToApprove] = 1;\n emit HashApproved(_hashToApprove, msg.sender);\n }\n\n /**\n * @notice Add owner to Barz. Update thresold if threshold is given different from current threshold\n * @dev This can only be done via a Self call.\n * @param _newOwner Address of new owner to be added\n * @param _threshold Uint256 value of threshold\n */\n function addOwner(address _newOwner, uint256 _threshold) external {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (\n _newOwner == address(0) ||\n _newOwner == SENTINEL_OWNERS ||\n _newOwner == address(this)\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_newOwner] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n\n ms.owners[_newOwner] = ms.owners[SENTINEL_OWNERS];\n ms.owners[SENTINEL_OWNERS] = _newOwner;\n ++ms.ownerCount;\n emit OwnerAdded(_newOwner);\n\n if (ms.threshold != _threshold) changeThreshold(_threshold);\n }\n\n /**\n * @notice Remove owner from Barz. Update thresold if threshold is given different from current threshold\n * @dev This can only be done via a Self call.\n * @param _prevOwner Address of owner located right behind the removed owner address in the linked list\n * @param _removedOwner Address of owner to be removed\n * @param _threshold Uint256 value of threshold\n */\n function removeOwner(\n address _prevOwner,\n address _removedOwner,\n uint256 _threshold\n ) external {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (ms.ownerCount - 1 < _threshold)\n revert MultiSigFacet__InvalidThreshold();\n if (_removedOwner == address(0) || _removedOwner == SENTINEL_OWNERS)\n revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_prevOwner] != _removedOwner)\n revert MultiSigFacet__InvalidOwnerPair();\n\n ms.owners[_prevOwner] = ms.owners[_removedOwner];\n ms.owners[_removedOwner] = address(0);\n --ms.ownerCount;\n emit OwnerRemoved(_removedOwner);\n\n if (ms.threshold != _threshold) changeThreshold(_threshold);\n }\n\n /**\n * @notice Swap owner in Barz.\n * @dev This can only be done via a Self call.\n * @param _prevOwner Address of owner located right behind the removed owner address in the linked list\n * @param _oldOwner Address of owner to be removed\n * @param _newOwner Address of owner to be added\n */\n function swapOwner(\n address _prevOwner,\n address _oldOwner,\n address _newOwner\n ) public {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (\n _newOwner == address(0) ||\n _newOwner == SENTINEL_OWNERS ||\n _newOwner == address(this)\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_newOwner] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n if (_oldOwner == address(0) || _oldOwner == SENTINEL_OWNERS)\n revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_prevOwner] != _oldOwner)\n revert MultiSigFacet__InvalidOwnerPair();\n\n ms.owners[_newOwner] = ms.owners[_oldOwner];\n ms.owners[_prevOwner] = _newOwner;\n ms.owners[_oldOwner] = address(0);\n emit OwnerRemoved(_oldOwner);\n emit OwnerAdded(_newOwner);\n }\n\n /**\n * @notice Changes the threshold of the Barz to `_threshold`.\n * @dev This can only be done via a Self call.\n * @param _threshold New threshold\n */\n function changeThreshold(uint256 _threshold) public {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (_threshold > ms.ownerCount || _threshold == 0)\n revert MultiSigFacet__InvalidThreshold();\n\n ms.threshold = _threshold;\n emit ThresholdChanged(_threshold);\n }\n\n /**\n * @notice Checks if the given address is owner\n * @param _owner Address to be checked if it's owner\n * @return isOwner_ Bool value showing if it's owner address\n */\n function isOwner(address _owner) public view returns (bool isOwner_) {\n isOwner_ = (_owner != SENTINEL_OWNERS &&\n LibMultiSigStorage.multisigStorage().owners[_owner] != address(0));\n }\n\n /**\n * @notice Returns the threshold of Barz\n * @return threshold Threshold of the Barz account\n */\n function getThreshold() public view returns (uint256 threshold) {\n threshold = LibMultiSigStorage.multisigStorage().threshold;\n }\n\n /**\n * @notice Returns the list of owner addresses\n * @return owners List of owners\n */\n function getOwners() public view returns (address[] memory owners) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n owners = new address[](ms.ownerCount);\n\n uint256 index;\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n while (currentOwner != SENTINEL_OWNERS) {\n owners[index] = currentOwner;\n currentOwner = ms.owners[currentOwner];\n index++;\n }\n }\n\n /**\n * @notice Returns the previous owner in the linked list\n * @param _owner Address of owner\n * @return prevOwner Address of previous owner\n */\n function getPrevOwner(\n address _owner\n ) public view returns (address prevOwner) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n if (currentOwner == _owner) return SENTINEL_OWNERS;\n while (currentOwner != SENTINEL_OWNERS) {\n if (ms.owners[currentOwner] == _owner) return currentOwner;\n\n currentOwner = ms.owners[currentOwner];\n }\n return address(0);\n }\n\n /**\n * @notice Returns of the owner is approved by given owner address\n * @param _owner Address of owner\n * @param _hash Hash of UserOperation\n * @return isApproved Bool value showing if the hash is approved by owner\n */\n function isApprovedHash(\n address _owner,\n bytes32 _hash\n ) public view returns (bool isApproved) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n isApproved = (ms.approvedHashes[ms.counter][_owner][_hash] == 1);\n }\n}\n" + }, + "contracts/facets/verification/secp256k1/Secp256k1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {UserOperation} from \"../../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibAppStorage} from \"../../../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, Secp256k1VerificationStorage} from \"../../../libraries/LibFacetStorage.sol\";\nimport {LibLoupe} from \"../../../libraries/LibLoupe.sol\";\nimport {IERC1271} from \"../../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../../interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Secp256k1 verification facet\n * @dev Default Ethereum's elliptic curve\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract Secp256k1VerificationFacet is IVerificationFacet, IERC1271 {\n using ECDSA for bytes32;\n error Secp256k1VerificationFacet__InvalidSignerLength();\n address public immutable self;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in K1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\n * @param _publicKey Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _publicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n if (!isValidKeyType(_publicKey))\n revert Secp256k1VerificationFacet__InvalidSignerLength();\n\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(uint160(uint256(keccak256(_publicKey[1:]))));\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_publicKey);\n }\n\n /**\n * @notice Uninitialize signer in K1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\n * signer public key.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n validationData = validateSignature(\n userOp,\n userOpHash,\n k1Storage.signer\n );\n }\n\n /**\n * @notice Validates if the signature of UserOperation is signed by the given signer\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @param signer Address of signer who signed the contract, to be validated\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n address signer\n ) public pure returns (uint256 isValid) {\n bytes32 hash = userOpHash.toEthSignedMessageHash();\n isValid = (signer != hash.recover(userOp.signature)) ? 1 : 0;\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n ownerSignatureValidatorSelector = this.validateOwnerSignature.selector;\n // NOTE: The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory signer) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n signer = abi.encodePacked(k1Storage.signer);\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key length should be 65 in an uncompressed public key format\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (_hash.recover(_signature) ==\n LibFacetStorage.k1Storage().signer)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/Secp256r1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {UserOperation} from \"../../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibAppStorage} from \"../../../libraries/LibAppStorage.sol\";\nimport {LibLoupe} from \"../../../libraries/LibLoupe.sol\";\nimport {LibFacetStorage, Secp256r1VerificationStorage} from \"../../../libraries/LibFacetStorage.sol\";\nimport {Base64} from \"./utils/Base64.sol\";\nimport {LibSecp256r1} from \"./utils/LibSecp256r1.sol\";\nimport {IERC1271} from \"../../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../../interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Secp256r1 verification facet\n * @dev Primarily used to verify user ops signed with passkeys\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract Secp256r1VerificationFacet is IVerificationFacet, IERC1271 {\n error Secp256r1VerificationFacet__InvalidSignerLength();\n address public immutable self;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in R1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\n * @param _publicKey Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _publicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n\n if (!isValidKeyType(_publicKey))\n revert Secp256r1VerificationFacet__InvalidSignerLength();\n\n bytes memory publicKeyCoordinates = _publicKey[1:];\n uint256[2] memory q;\n assembly {\n // Copy the bytes from the input data into the uint256 array\n mstore(q, mload(add(publicKeyCoordinates, 32)))\n mstore(add(q, 32), mload(add(publicKeyCoordinates, 64)))\n }\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n r1Storage.q = q;\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_publicKey);\n }\n\n /**\n * @notice Uninitialize signer in R1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n r1Storage.q = [0, 0];\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\n * signer public key.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n validationData = validateSignature(userOp, userOpHash, r1Storage.q);\n }\n\n /**\n * @notice Validates if the signature of UserOperation is signed by the given signer\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @param q Public Key of signer who signed the contract, to be validated\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256[2] memory q\n ) public view returns (uint256 isValid) {\n isValid = (_validateSignature(q, userOpHash, userOp.signature)) ? 0 : 1;\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n return this.validateOwnerSignature.selector; // validateOwnerSignature(UserOperation calldata userOp,bytes32 userOpHash)\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory signer) {\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n signer = abi.encodePacked(r1Storage.q);\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key should in an uncompressed public key format\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = _validateSignature(\n LibFacetStorage.r1Storage().q,\n _hash,\n _signature\n )\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n\n function _validateSignature(\n uint256[2] memory q,\n bytes32 _hash,\n bytes memory _signature\n ) internal view returns (bool) {\n (\n uint256 rValue,\n uint256 sValue,\n bytes memory authenticatorData,\n string memory clientDataJSONPre,\n string memory clientDataJSONPost\n ) = abi.decode(_signature, (uint256, uint256, bytes, string, string));\n bytes32 clientHash;\n {\n string memory opHashBase64 = Base64.encode(bytes.concat(_hash));\n string memory clientDataJSON = string.concat(\n clientDataJSONPre,\n opHashBase64,\n clientDataJSONPost\n );\n clientHash = sha256(bytes(clientDataJSON));\n }\n bytes32 sigHash = sha256(bytes.concat(authenticatorData, clientHash));\n return LibSecp256r1.Verify(q, rValue, sValue, uint256(sigHash));\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/utils/Base64.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @dev Provides a set of functions to operate with Base64 strings.\n * modified for base64url https://datatracker.ietf.org/doc/html/rfc4648#section-5\n * _Available since v4.5._\n */\nlibrary Base64 {\n /**\n * @dev Base64 Encoding/Decoding Table\n */\n string internal constant _TABLE =\n \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_\";\n\n /**\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\n */\n function encode(bytes memory data) internal pure returns (string memory) {\n /**\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\n */\n if (data.length == 0) return \"\";\n\n // Loads the table into memory\n string memory table = _TABLE;\n\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\n // and split into 4 numbers of 6 bits.\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\n // - `data.length + 2` -> Round up\n // - `/ 3` -> Number of 3-bytes chunks\n // - `4 *` -> 4 characters for each chunk\n uint256 newlength = (data.length * 8) / 6;\n if (data.length % 6 > 0) {\n newlength++;\n }\n string memory result = new string(newlength);\n\n /// @solidity memory-safe-assembly\n assembly {\n // Prepare the lookup table (skip the first \"length\" byte)\n let tablePtr := add(table, 1)\n\n // Prepare result pointer, jump over length\n let resultPtr := add(result, 32)\n\n // Run over the input, 3 bytes at a time\n for {\n let dataPtr := data\n let endPtr := add(data, mload(data))\n } lt(dataPtr, endPtr) {\n\n } {\n // Advance 3 bytes\n dataPtr := add(dataPtr, 3)\n let input := mload(dataPtr)\n\n // To write each character, shift the 3 bytes (18 bits) chunk\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\n // and apply logical AND with 0x3F which is the number of\n // the previous character in the ASCII table prior to the Base64 Table\n // The result is then added to the table to get the character to write,\n // and finally write it in the result pointer but with a left shift\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(18, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(12, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(6, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n }\n }\n\n return result;\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/utils/LibSecp256r1.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n// Heavily inspired from\n// https://github.com/maxrobot/elliptic-solidity/blob/master/contracts/Secp256r1.sol\n// https://github.com/tdrerup/elliptic-curve-solidity/blob/master/contracts/curves/EllipticCurve.sol\n// modified to use precompile 0x05 modexp\n// and modified jacobian double\n// optimisations to avoid to an from from affine and jacobian coordinates\n\n// Additional Elliptic curve Public key / Signature validation added by\n// David Yonjun Kim (@Powerstream3604)\n\nstruct JPoint {\n uint256 x;\n uint256 y;\n uint256 z;\n}\n\nlibrary LibSecp256r1 {\n uint256 constant gx =\n 0x6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296;\n uint256 constant gy =\n 0x4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5;\n uint256 public constant pp =\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF;\n\n uint256 public constant nn =\n 0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551;\n uint256 constant a =\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC;\n uint256 constant b =\n 0x5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B;\n uint256 constant MOST_SIGNIFICANT =\n 0xc000000000000000000000000000000000000000000000000000000000000000;\n\n /*\n * Verify\n * @description - verifies that a public key has signed a given message\n * @param Q - public key coordinates X & Y\n * @param R - signature half R\n * @param S - signature half S\n * @param input - hashed message\n */\n function Verify(\n uint256[2] memory q,\n uint r,\n uint s,\n uint e\n ) internal view returns (bool) {\n if (q[0] > pp - 1 || q[1] > pp - 1) {\n return false;\n }\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\n return false;\n }\n if (\n mulmod(q[1], q[1], pp) !=\n addmod(\n addmod(\n mulmod(q[0], mulmod(q[0], q[0], pp), pp),\n mulmod(a, q[0], pp),\n pp\n ),\n b,\n pp\n )\n ) {\n return false;\n }\n\n JPoint[16] memory points = _preComputeJacobianPoints(q);\n return VerifyWithPrecompute(points, r, s, e);\n }\n\n function VerifyWithPrecompute(\n JPoint[16] memory points,\n uint r,\n uint s,\n uint e\n ) internal view returns (bool) {\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\n return false;\n }\n\n uint w = _primemod(s, nn);\n\n uint u1 = mulmod(e, w, nn);\n uint u2 = mulmod(r, w, nn);\n\n uint x;\n uint y;\n\n (x, y) = ShamirMultJacobian(points, u1, u2);\n return (x == r);\n }\n\n /*\n * Strauss Shamir trick for EC multiplication\n * https://stackoverflow.com/questions/50993471/ec-scalar-multiplication-with-strauss-shamir-method\n * we optimise on this a bit to do with 2 bits at a time rather than a single bit\n * the individual points for a single pass are precomputed\n * overall this reduces the number of additions while keeping the same number of doublings\n */\n function ShamirMultJacobian(\n JPoint[16] memory points,\n uint u1,\n uint u2\n ) internal view returns (uint, uint) {\n uint x = 0;\n uint y = 0;\n uint z = 0;\n uint bits = 128;\n uint index = 0;\n\n while (bits > 0) {\n if (z > 0) {\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\n }\n index =\n ((u1 & MOST_SIGNIFICANT) >> 252) |\n ((u2 & MOST_SIGNIFICANT) >> 254);\n if (index > 0) {\n (x, y, z) = _jAdd(\n x,\n y,\n z,\n points[index].x,\n points[index].y,\n points[index].z\n );\n }\n u1 <<= 2;\n u2 <<= 2;\n bits--;\n }\n (x, y) = _affineFromJacobian(x, y, z);\n return (x, y);\n }\n\n function _preComputeJacobianPoints(\n uint256[2] memory q\n ) internal pure returns (JPoint[16] memory points) {\n points[0] = JPoint(0, 0, 0);\n points[1] = JPoint(q[0], q[1], 1); // u2\n points[2] = _jPointDouble(points[1]);\n points[3] = _jPointAdd(points[1], points[2]);\n\n points[4] = JPoint(gx, gy, 1); // u1Points[1]\n points[5] = _jPointAdd(points[4], points[1]);\n points[6] = _jPointAdd(points[4], points[2]);\n points[7] = _jPointAdd(points[4], points[3]);\n\n points[8] = _jPointDouble(points[4]); // u1Points[2]\n points[9] = _jPointAdd(points[8], points[1]);\n points[10] = _jPointAdd(points[8], points[2]);\n points[11] = _jPointAdd(points[8], points[3]);\n\n points[12] = _jPointAdd(points[4], points[8]); // u1Points[3]\n points[13] = _jPointAdd(points[12], points[1]);\n points[14] = _jPointAdd(points[12], points[2]);\n points[15] = _jPointAdd(points[12], points[3]);\n }\n\n function _jPointAdd(\n JPoint memory p1,\n JPoint memory p2\n ) internal pure returns (JPoint memory) {\n uint x;\n uint y;\n uint z;\n (x, y, z) = _jAdd(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z);\n return JPoint(x, y, z);\n }\n\n function _jPointDouble(\n JPoint memory p\n ) internal pure returns (JPoint memory) {\n uint x;\n uint y;\n uint z;\n (x, y, z) = _modifiedJacobianDouble(p.x, p.y, p.z);\n return JPoint(x, y, z);\n }\n\n /* _affineFromJacobian\n * @desription returns affine coordinates from a jacobian input follows\n * golang elliptic/crypto library\n */\n function _affineFromJacobian(\n uint x,\n uint y,\n uint z\n ) internal view returns (uint ax, uint ay) {\n if (z == 0) {\n return (0, 0);\n }\n\n uint zinv = _primemod(z, pp);\n uint zinvsq = mulmod(zinv, zinv, pp);\n\n ax = mulmod(x, zinvsq, pp);\n ay = mulmod(y, mulmod(zinvsq, zinv, pp), pp);\n }\n\n /*\n * _jAdd\n * @description performs Jacobian addition as defined below:\n * http://www.hyperelliptic.org/EFD/g1p/data/shortw/jacobian/addition/add-2007-bl\n */\n function _jAdd(\n uint p1,\n uint p2,\n uint p3,\n uint q1,\n uint q2,\n uint q3\n ) internal pure returns (uint r1, uint r2, uint r3) {\n if (p3 == 0) {\n r1 = q1;\n r2 = q2;\n r3 = q3;\n\n return (r1, r2, r3);\n } else if (q3 == 0) {\n r1 = p1;\n r2 = p2;\n r3 = p3;\n\n return (r1, r2, r3);\n }\n\n assembly {\n let\n pd\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\n let z1z1 := mulmod(p3, p3, pd) // Z1Z1 = Z1^2\n let z2z2 := mulmod(q3, q3, pd) // Z2Z2 = Z2^2\n\n let u1 := mulmod(p1, z2z2, pd) // U1 = X1*Z2Z2\n let u2 := mulmod(q1, z1z1, pd) // U2 = X2*Z1Z1\n\n let s1 := mulmod(p2, mulmod(z2z2, q3, pd), pd) // S1 = Y1*Z2*Z2Z2\n let s2 := mulmod(q2, mulmod(z1z1, p3, pd), pd) // S2 = Y2*Z1*Z1Z1\n\n let p3q3 := addmod(p3, q3, pd)\n\n if lt(u2, u1) {\n u2 := add(pd, u2) // u2 = u2+pd\n }\n let h := sub(u2, u1) // H = U2-U1\n\n let i := mulmod(0x02, h, pd)\n i := mulmod(i, i, pd) // I = (2*H)^2\n\n let j := mulmod(h, i, pd) // J = H*I\n if lt(s2, s1) {\n s2 := add(pd, s2) // u2 = u2+pd\n }\n let rr := mulmod(0x02, sub(s2, s1), pd) // r = 2*(S2-S1)\n r1 := mulmod(rr, rr, pd) // X3 = R^2\n\n let v := mulmod(u1, i, pd) // V = U1*I\n let j2v := addmod(j, mulmod(0x02, v, pd), pd)\n if lt(r1, j2v) {\n r1 := add(pd, r1) // X3 = X3+pd\n }\n r1 := sub(r1, j2v)\n\n // Y3 = r*(V-X3)-2*S1*J\n let s12j := mulmod(mulmod(0x02, s1, pd), j, pd)\n\n if lt(v, r1) {\n v := add(pd, v)\n }\n r2 := mulmod(rr, sub(v, r1), pd)\n\n if lt(r2, s12j) {\n r2 := add(pd, r2)\n }\n r2 := sub(r2, s12j)\n\n // Z3 = ((Z1+Z2)^2-Z1Z1-Z2Z2)*H\n z1z1 := addmod(z1z1, z2z2, pd)\n j2v := mulmod(p3q3, p3q3, pd)\n if lt(j2v, z1z1) {\n j2v := add(pd, j2v)\n }\n r3 := mulmod(sub(j2v, z1z1), h, pd)\n }\n return (r1, r2, r3);\n }\n\n // Point doubling on the modified jacobian coordinates\n // http://point-at-infinity.org/ecc/Prime_Curve_Modified_Jacobian_Coordinates.html\n function _modifiedJacobianDouble(\n uint x,\n uint y,\n uint z\n ) internal pure returns (uint x3, uint y3, uint z3) {\n if (y == 0) return (0, 0, 0);\n assembly {\n let\n pd\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\n let z2 := mulmod(z, z, pd)\n let az4 := mulmod(\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC,\n mulmod(z2, z2, pd),\n pd\n )\n let y2 := mulmod(y, y, pd)\n let s := mulmod(0x04, mulmod(x, y2, pd), pd)\n let u := mulmod(0x08, mulmod(y2, y2, pd), pd)\n let m := addmod(mulmod(0x03, mulmod(x, x, pd), pd), az4, pd)\n let twos := mulmod(0x02, s, pd)\n let m2 := mulmod(m, m, pd)\n if lt(m2, twos) {\n m2 := add(pd, m2)\n }\n x3 := sub(m2, twos)\n if lt(s, x3) {\n s := add(pd, s)\n }\n y3 := mulmod(m, sub(s, x3), pd)\n if lt(y3, u) {\n y3 := add(pd, y3)\n }\n y3 := sub(y3, u)\n z3 := mulmod(0x02, mulmod(y, z, pd), pd)\n }\n }\n\n // Fermats little theorem https://en.wikipedia.org/wiki/Fermat%27s_little_theorem\n // a^(p-1) = 1 mod p\n // a^(-1) ≅ a^(p-2) (mod p)\n // we then use the precompile bigModExp to compute a^(-1)\n function _primemod(uint value, uint p) internal view returns (uint ret) {\n ret = modexp(value, p - 2, p);\n return ret;\n }\n\n // Wrapper for built-in BigNumber_modexp (contract 0x5) as described here. https://github.com/ethereum/EIPs/pull/198\n function modexp(\n uint _base,\n uint _exp,\n uint _mod\n ) internal view returns (uint ret) {\n // bigModExp(_base, _exp, _mod);\n assembly {\n if gt(_base, _mod) {\n _base := mod(_base, _mod)\n }\n // Free memory pointer is always stored at 0x40\n let freemem := mload(0x40)\n\n mstore(freemem, 0x20)\n mstore(add(freemem, 0x20), 0x20)\n mstore(add(freemem, 0x40), 0x20)\n\n mstore(add(freemem, 0x60), _base)\n mstore(add(freemem, 0x80), _exp)\n mstore(add(freemem, 0xa0), _mod)\n\n let success := staticcall(14000, 0x5, freemem, 0xc0, freemem, 0x20)\n switch success\n case 0 {\n revert(0x0, 0x0)\n }\n default {\n ret := mload(freemem)\n }\n }\n }\n}\n" + }, + "contracts/infrastructure/DefaultFallbackHandler.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC1155Receiver} from \"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\";\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {BaseAccount} from \"../aa-4337/core/BaseAccount.sol\";\nimport {DefaultLibDiamond} from \"../libraries/DefaultLibDiamond.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IAccountFacet} from \"../facets/interfaces/IAccountFacet.sol\";\nimport {IStorageLoupe} from \"../facets/base/interfaces/IStorageLoupe.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IERC677Receiver} from \"../interfaces/ERC/IERC677Receiver.sol\";\nimport {IERC165} from \"../interfaces/ERC/IERC165.sol\";\n\n/**\n * @title DefaultFallbackHandler\n * @dev A default fallback handler for Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DefaultFallbackHandler is IDiamondLoupe {\n /**\n * @notice Sets the middleware diamond for Barz wallet as a fallback handler\n * @dev This contract is also a diamond that holds the default facets to reduce gas cost for wallet activation.\n * Within the constructor this conducts diamond cut to initially setup the diamond. This is a non-upgradeable contract\n * @param _diamondCutFacet Address if diamond cut facet\n * @param _accountFacet Address account facet\n * @param _tokenReceiverFacet Address of token receiver facet\n * @param _diamondLoupeFacet Address of diamond loupe facet\n */\n constructor(\n address _diamondCutFacet,\n address _accountFacet,\n address _tokenReceiverFacet,\n address _diamondLoupeFacet\n ) payable {\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](4);\n bytes4[] memory functionSelectors = new bytes4[](1);\n functionSelectors[0] = IDiamondCut.diamondCut.selector;\n\n bytes4[] memory accountFunctionSelectors = new bytes4[](5);\n accountFunctionSelectors[0] = IAccountFacet.execute.selector;\n accountFunctionSelectors[1] = IAccountFacet.executeBatch.selector;\n accountFunctionSelectors[2] = BaseAccount.validateUserOp.selector;\n accountFunctionSelectors[3] = BaseAccount.getNonce.selector;\n accountFunctionSelectors[4] = BaseAccount.entryPoint.selector;\n\n bytes4[] memory receiverFacetSelectors = new bytes4[](5);\n receiverFacetSelectors[0] = IERC721Receiver.onERC721Received.selector;\n receiverFacetSelectors[1] = IERC1155Receiver.onERC1155Received.selector;\n receiverFacetSelectors[2] = IERC1155Receiver\n .onERC1155BatchReceived\n .selector;\n receiverFacetSelectors[3] = IERC777Recipient.tokensReceived.selector;\n receiverFacetSelectors[4] = IERC677Receiver.onTokenTransfer.selector;\n\n bytes4[] memory loupeFacetSelectors = new bytes4[](9);\n loupeFacetSelectors[0] = IDiamondLoupe.facets.selector;\n loupeFacetSelectors[1] = IDiamondLoupe.facetFunctionSelectors.selector;\n loupeFacetSelectors[2] = IDiamondLoupe.facetAddresses.selector;\n loupeFacetSelectors[3] = IDiamondLoupe.facetAddress.selector;\n loupeFacetSelectors[4] = IERC165.supportsInterface.selector;\n loupeFacetSelectors[5] = IStorageLoupe.facetsFromStorage.selector;\n loupeFacetSelectors[6] = IStorageLoupe\n .facetFunctionSelectorsFromStorage\n .selector;\n loupeFacetSelectors[7] = IStorageLoupe\n .facetAddressesFromStorage\n .selector;\n loupeFacetSelectors[8] = IStorageLoupe.facetAddressFromStorage.selector;\n\n {\n cut[0] = IDiamondCut.FacetCut({\n facetAddress: _diamondCutFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: functionSelectors\n });\n cut[1] = IDiamondCut.FacetCut({\n facetAddress: _accountFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: accountFunctionSelectors\n });\n cut[2] = IDiamondCut.FacetCut({\n facetAddress: _tokenReceiverFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: receiverFacetSelectors\n });\n cut[3] = IDiamondCut.FacetCut({\n facetAddress: _diamondLoupeFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: loupeFacetSelectors\n });\n\n DefaultLibDiamond.diamondCut(cut, address(0), \"\");\n }\n }\n\n /**\n * @notice Returns the facet information of call facets registered to this diamond.\n * @return facets_ The facet struct array including all facet information\n */\n function facets() external view override returns (Facet[] memory facets_) {\n DefaultLibDiamond.DiamondStorage storage ds = DefaultLibDiamond\n .diamondStorage();\n uint256 numFacets = ds.facetAddresses.length;\n facets_ = new Facet[](numFacets);\n for (uint256 i; i < numFacets; ) {\n address facetAddress_ = ds.facetAddresses[i];\n facets_[i].facetAddress = facetAddress_;\n facets_[i].functionSelectors = ds\n .facetFunctionSelectors[facetAddress_]\n .functionSelectors;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Gets all the function selectors provided by a facet.\n * @param _facet The facet address.\n * @return facetFunctionSelectors_\n */\n function facetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n facetFunctionSelectors_ = DefaultLibDiamond\n .diamondStorage()\n .facetFunctionSelectors[_facet]\n .functionSelectors;\n }\n\n /**\n * @notice Get all the facet addresses used by a diamond.\n * @return facetAddresses_\n */\n function facetAddresses()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n facetAddresses_ = DefaultLibDiamond.diamondStorage().facetAddresses;\n }\n\n /** @notice Gets the facet that supports the given selector.\n * @dev If facet is not found return address(0).\n * @param _functionSelector The function selector.\n * @return facetAddress_ The facet address.\n */\n function facetAddress(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n facetAddress_ = DefaultLibDiamond\n .diamondStorage()\n .selectorToFacetAndPosition[_functionSelector]\n .facetAddress;\n }\n}\n" + }, + "contracts/infrastructure/FacetRegistry.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport {IFacetRegistry} from \"./interfaces/IFacetRegistry.sol\";\n\n/**\n * @title Facet Registry\n * @dev Contract to keep track of facets & function selectors addable to user wallets\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract FacetRegistry is IFacetRegistry, Ownable2Step {\n mapping(address => FacetRegistryConfig) private facets;\n\n /**\n * @notice Transfers the ownership of the contract to the given owner\n * @param _owner Address of owner who has access to initialize the default security variables for security manager\n */\n constructor(address _owner) {\n transferOwnership(_owner);\n _transferOwnership(_owner);\n }\n\n /**\n * @dev Registers a facet and it's function selectors to registry\n * @param _facet address of facet\n * @param _facetSelectors list of function selectors of the facet\n */\n function registerFacetFunctionSelectors(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external override onlyOwner {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n uint256 facetSelectorsLength = _facetSelectors.length;\n for (uint256 i; i < facetSelectorsLength; ) {\n if (facetConfig.info[_facetSelectors[i]].exists)\n revert FacetRegistry__FacetSelectorAlreadyRegistered();\n\n facetConfig.info[_facetSelectors[i]].exists = true;\n facetConfig.info[_facetSelectors[i]].index = uint128(\n facetConfig.selectors.length\n );\n facetConfig.selectors.push(_facetSelectors[i]);\n unchecked {\n ++i;\n }\n }\n emit FacetFunctionSelectorsRegistered(_facet, _facetSelectors);\n }\n\n /**\n * @dev Removes a registered facet and it's corresponding selectors from registry\n * @param _facet address of facet\n * @param _facetSelectors list of function selectors of the facet\n */\n function removeFacetFunctionSelectors(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external override onlyOwner {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n uint256 facetSelectorsLength = _facetSelectors.length;\n for (uint256 i; i < facetSelectorsLength; ) {\n if (!facetConfig.info[_facetSelectors[i]].exists)\n revert FacetRegistry__UnregisteredFacetSelector();\n\n bytes4 lastSelector = facetConfig.selectors[\n facetConfig.selectors.length - 1\n ];\n if (_facetSelectors[i] != lastSelector) {\n uint128 targetIndex = facetConfig\n .info[_facetSelectors[i]]\n .index;\n facetConfig.selectors[targetIndex] = lastSelector;\n facetConfig.info[lastSelector].index = targetIndex;\n }\n facetConfig.selectors.pop();\n delete facetConfig.info[_facetSelectors[i]];\n\n unchecked {\n ++i;\n }\n }\n emit FacetFunctionSelectorsRemoved(_facet, _facetSelectors);\n }\n\n /**\n * @dev Checks if a facet and it's selectors given is registered to facet registry\n * @param _facet Address of facet\n * @param _facetSelectors List of function selectors of the facet\n */\n function areFacetFunctionSelectorsRegistered(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external view override returns (bool) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n uint256 facetSelectorsLength = _facetSelectors.length;\n if (facetSelectorsLength == 0) return false;\n for (uint256 i; i < facetSelectorsLength; ) {\n if (!facetConfig.info[_facetSelectors[i]].exists) return false;\n unchecked {\n ++i;\n }\n }\n return true;\n }\n\n /**\n * @dev Checks if a facet and it's selector given is registered to facet registry\n * @param _facet Address of facet\n * @param _facetSelector List of function selectors of the facet\n * @return isRegistered Bool value showing if the selector is registered\n */\n function isFacetFunctionSelectorRegistered(\n address _facet,\n bytes4 _facetSelector\n ) external view override returns (bool isRegistered) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n isRegistered = facetConfig.info[_facetSelector].exists;\n }\n\n /**\n * @dev Get the registered selectors of facet from registry\n * @param _facet Address of facet\n * @return selectors Selectors registered to facet\n */\n function getFacetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory selectors) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n selectors = facetConfig.selectors;\n }\n}\n" + }, + "contracts/infrastructure/interfaces/IFacetRegistry.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Registry Interface\n * @dev Interface for Facet Registry contract to keep track of facets & function selectors addable to user wallets\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IFacetRegistry {\n struct FacetRegistryConfig {\n bytes4[] selectors;\n mapping(bytes4 => FacetInfo) info;\n }\n struct FacetInfo {\n bool exists;\n uint128 index;\n }\n\n event FacetFunctionSelectorsRegistered(\n address facet,\n bytes4[] facetSelectors\n );\n event FacetFunctionSelectorsRemoved(address facet, bytes4[] facetSelectors);\n\n error FacetRegistry__FacetSelectorAlreadyRegistered();\n error FacetRegistry__UnregisteredFacetSelector();\n\n function registerFacetFunctionSelectors(\n address facet,\n bytes4[] calldata facetSelectors\n ) external;\n\n function removeFacetFunctionSelectors(\n address facet,\n bytes4[] calldata facetSelectors\n ) external;\n\n function areFacetFunctionSelectorsRegistered(\n address facet,\n bytes4[] calldata facetSelectors\n ) external view returns (bool);\n\n function isFacetFunctionSelectorRegistered(\n address facet,\n bytes4 facetSelector\n ) external view returns (bool);\n\n function getFacetFunctionSelectors(\n address facet\n ) external view returns (bytes4[] memory);\n}\n" + }, + "contracts/infrastructure/interfaces/ISecurityManager.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Registry Interface\n * @dev Infrastructure contract to manage security parameters of users\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface ISecurityManager {\n error SecurityManager__OutOfBoundary();\n error SecurityManager__CallerNotWallet();\n error SecurityManager__AlreadyIntialized();\n\n function initializeAdditionSecurityPeriod(\n uint128 defaultAdditionSecurityPeriod,\n uint128 minAdditionSecurityPeriod,\n uint128 maxAdditionSecurityPeriod\n ) external;\n\n function initializeRemovalSecurityPeriod(\n uint128 defaultRemovalSecurityPeriod,\n uint128 minRemovalSecurityPeriod,\n uint128 maxRemovalSecurityPeriod\n ) external;\n\n function initializeApprovalValidationPeriod(\n uint128 defaultApprovalValidationPeriod,\n uint128 minApprovalValidationPeriod,\n uint128 maxApprovalValidationPeriod\n ) external;\n\n function initializeMigrationPeriod(\n uint128 defaultMigrationPeriod,\n uint128 minMigrationPeriod,\n uint128 maxMigrationPeriod\n ) external;\n\n function initializeLockPeriod(\n uint128 defaultLockPeriod,\n uint128 minLockPeriod,\n uint128 maxLockPeriod\n ) external;\n\n function initializeRecoveryPeriod(\n uint128 defaultRecoveryPeriod,\n uint128 minRecoveryPeriod,\n uint128 maxRecoveryPeriod\n ) external;\n\n function initializeSecurityWindow(\n uint128 defaultSecurityWindow,\n uint128 minSecurityWindow,\n uint128 maxSecurityWindow\n ) external;\n\n function setAdditionSecurityPeriod(\n address wallet,\n uint128 additionSecurityPeriod\n ) external;\n\n function setRemovalSecurityPeriod(\n address wallet,\n uint128 removalSecurityPeriod\n ) external;\n\n function setSecurityWindow(address wallet, uint128 securityWindow) external;\n\n function setRecoveryPeriod(address wallet, uint128 recoveryPeriod) external;\n\n function setLockPeriod(address wallet, uint128 lockPeriod) external;\n\n function setApprovalValidationPeriod(\n address wallet,\n uint128 approvalValidationPeriod\n ) external;\n\n function setMigrationPeriod(\n address wallet,\n uint128 migrationPeriod\n ) external;\n\n function additionSecurityPeriodOf(\n address wallet\n ) external view returns (uint128);\n\n function removalSecurityPeriodOf(\n address wallet\n ) external view returns (uint128);\n\n function securityWindowOf(address wallet) external view returns (uint128);\n\n function recoveryPeriodOf(address wallet) external view returns (uint128);\n\n function lockPeriodOf(address wallet) external view returns (uint128);\n\n function migrationPeriodOf(address wallet) external view returns (uint128);\n\n function approvalValidationPeriodOf(\n address wallet\n ) external view returns (uint128);\n}\n" + }, + "contracts/infrastructure/RemoteStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IGuardianFacet} from \"../facets/interfaces/IGuardianFacet.sol\";\n\n/**\n * @title Remote Storage\n * @dev Remote storage allows you to associate addresses with an array of addresses on a standalone smart contract.\n * This could be useful when you don't want to use the local diamond storage for some purpose.\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\nabstract contract RemoteStorage {\n struct StorageConfig {\n address[] addresses;\n mapping(address => Info) info;\n }\n\n struct Info {\n bool exists;\n uint128 index;\n }\n\n mapping(address => StorageConfig) internal configs;\n\n event Added(address _address);\n event Removed(address _address);\n\n error RemoteStorage__CallerNotOwner();\n error RemoteStorage__CallerNotGuardianOrOwner();\n error RemoteStorage__AlreadyExists();\n error RemoteStorage__NotFound();\n error RemoteStorage__CallerNotGuardian();\n\n bytes4 constant IS_GUARDIAN_SELECTOR =\n bytes4(keccak256(\"isGuardian(address)\"));\n bytes4 constant GUARDIAN_COUNT = bytes4(keccak256(\"guardianCount()\"));\n\n /**\n * @notice Modifier to only allow the self to call. Reverts otherwise\n */\n modifier onlyWallet(address _wallet) {\n if (msg.sender != _wallet) revert RemoteStorage__CallerNotOwner();\n _;\n }\n\n /**\n * @notice Enfore the callet to be wallet of guardian of the wallet\n * @param _wallet Address of wallet\n */\n function enforceGuardianOrWallet(address _wallet) internal view {\n if (msg.sender == _wallet) return;\n address facetAddress = IDiamondLoupe(_wallet).facetAddress(\n IS_GUARDIAN_SELECTOR\n );\n if (facetAddress != address(0))\n if (IGuardianFacet(_wallet).isGuardian(msg.sender)) return;\n revert RemoteStorage__CallerNotGuardianOrOwner();\n }\n\n /**\n * @notice Enforce the caller to be wallet IF guardians doesn't exists and only guardian when guardians exists\n * @param _wallet Target wallet address to be handled by infrastructure contracts\n */\n function enforceWalletOrGuardianIfExists(address _wallet) internal view {\n address facetAddress;\n if (msg.sender == _wallet) {\n facetAddress = IDiamondLoupe(_wallet).facetAddress(GUARDIAN_COUNT);\n if (facetAddress == address(0)) return;\n uint256 guardianCount = IGuardianFacet(_wallet).guardianCount();\n if (guardianCount != 0) revert RemoteStorage__CallerNotGuardian();\n return;\n }\n facetAddress = IDiamondLoupe(_wallet).facetAddress(\n IS_GUARDIAN_SELECTOR\n );\n if (facetAddress != address(0))\n if (IGuardianFacet(_wallet).isGuardian(msg.sender)) return;\n\n revert RemoteStorage__CallerNotGuardianOrOwner();\n }\n\n /**\n * @notice Add address to storage and reverts if the address already exists.\n * This is an internal function callable from contracts that inherit this abstract contract\n * @param _wallet Address of wallet to add the address\n * @param _address Address to be added to wallet\n */\n function addAddress(address _wallet, address _address) internal {\n StorageConfig storage config = configs[_wallet];\n if (config.info[_address].exists) revert RemoteStorage__AlreadyExists();\n\n config.info[_address].exists = true;\n config.info[_address].index = uint128(config.addresses.length);\n config.addresses.push(_address);\n\n emit Added(_address);\n }\n\n /**\n * @notice Remove address from storage and reverts if the address already exists.\n * This is an internal function callable from contracts that inherit this abstract contract\n * @param _wallet Address of wallet to remove the address\n * @param _address Address to be removed from wallet\n */\n function removeAddress(address _wallet, address _address) internal {\n StorageConfig storage config = configs[_wallet];\n if (!config.info[_address].exists) revert RemoteStorage__NotFound();\n\n address lastAddress = config.addresses[config.addresses.length - 1];\n if (_address != lastAddress) {\n uint128 targetIndex = config.info[_address].index;\n config.addresses[targetIndex] = lastAddress;\n config.info[lastAddress].index = targetIndex;\n }\n config.addresses.pop();\n delete config.info[_address];\n\n emit Removed(_address);\n }\n\n /**\n * @notice Returns the address added to the given wallet\n * @param _wallet Address of wallet to fetch the addresses added to it\n * @return addresses List of addresses added to the wallet\n */\n function getAddresses(\n address _wallet\n ) internal view returns (address[] memory addresses) {\n StorageConfig storage config = configs[_wallet];\n addresses = new address[](config.addresses.length);\n uint addressesLen = config.addresses.length;\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns bool value checking if the address exists in the given wallet address\n * @param _wallet Wallet address to check\n * @param _address Address to fetch if the address if added to given wallet\n * @return exists_ Bool value showing if the address exists in wallet\n */\n function exists(\n address _wallet,\n address _address\n ) internal view returns (bool exists_) {\n exists_ = configs[_wallet].info[_address].exists;\n }\n\n /**\n * @notice Returns the number of addresses added to the wallet\n * @param _wallet Address of wallet to check\n * @return count_ Number of addresses added to wallet\n */\n function count(address _wallet) internal view returns (uint256 count_) {\n count_ = configs[_wallet].addresses.length;\n }\n}\n" + }, + "contracts/infrastructure/SecurityManager.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport {ISecurityManager} from \"./interfaces/ISecurityManager.sol\";\n\n/**\n * @title Security Manager\n * @dev Infrastructure contract to manage security parameters of users\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract SecurityManager is ISecurityManager, Ownable2Step {\n uint128 public minAdditionSecurityPeriod;\n uint128 public maxAdditionSecurityPeriod;\n uint128 private defaultAdditionSecurityPeriod;\n\n uint128 public minRemovalSecurityPeriod;\n uint128 public maxRemovalSecurityPeriod;\n uint128 private defaultRemovalSecurityPeriod;\n\n uint128 public minSecurityWindow;\n uint128 public maxSecurityWindow;\n uint128 private defaultSecurityWindow;\n\n uint128 public minRecoveryPeriod;\n uint128 public maxRecoveryPeriod;\n uint128 private defaultRecoveryPeriod;\n\n uint128 public minLockPeriod;\n uint128 public maxLockPeriod;\n uint128 private defaultLockPeriod;\n\n uint128 public minApprovalValidationPeriod;\n uint128 public maxApprovalValidationPeriod;\n uint128 private defaultApprovalValidationPeriod;\n\n uint128 public minMigrationPeriod;\n uint128 public maxMigrationPeriod;\n uint128 private defaultMigrationPeriod;\n\n bool public _isAdditionSecurityPeriodInitialized;\n bool public _isRemovalSecurityPeriodInitialized;\n bool public _isSecurityWindowInitialized;\n bool public _isRecoveryPeriodInitialized;\n bool public _isLockPeriodInitialized;\n bool public _isApprovalValidationPeriodInitialized;\n bool public _isMigrationPeriodInitialized;\n\n mapping(address => CustomSecurityConfig) securityConfigs;\n\n struct CustomSecurityConfig {\n uint128 additionSecurityPeriod;\n uint128 removalSecurityPeriod;\n uint128 securityWindow;\n uint128 recoveryPeriod;\n uint128 lockPeriod;\n uint128 approvalValidationPeriod;\n uint128 migrationPeriod;\n }\n\n /**\n * @notice Modifier to only allow wallet itself to make a call to wallet\n */\n modifier onlyWallet(address _wallet) {\n if (msg.sender != _wallet) revert SecurityManager__CallerNotWallet();\n _;\n }\n\n /**\n * @notice Modifier to revert if the variable is already initialized\n */\n modifier initializer(bool _isInitialized) {\n if (_isInitialized) revert SecurityManager__AlreadyIntialized();\n _;\n }\n\n /**\n * @notice Transfers the ownership of the contract to the given owner\n * @param _owner Address of owner who has access to initialize the default security variables for security manager\n */\n constructor(address _owner) {\n transferOwnership(_owner);\n _transferOwnership(_owner);\n }\n\n /**\n * @notice Sets the initial default/min/max addition security period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultAdditionSecurityPeriod Default Addition Security Period for all Barz contracts\n * @param _minAdditionSecurityPeriod Minimum Addition Security Period for all Barz contracts\n * @param _maxAdditionSecurityPeriod Maximum Addition Security Period for all Barz contracts\n */\n function initializeAdditionSecurityPeriod(\n uint128 _defaultAdditionSecurityPeriod,\n uint128 _minAdditionSecurityPeriod,\n uint128 _maxAdditionSecurityPeriod\n )\n external\n override\n onlyOwner\n initializer(_isAdditionSecurityPeriodInitialized)\n {\n _isAdditionSecurityPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultAdditionSecurityPeriod,\n _minAdditionSecurityPeriod,\n _maxAdditionSecurityPeriod\n );\n defaultAdditionSecurityPeriod = _defaultAdditionSecurityPeriod;\n minAdditionSecurityPeriod = _minAdditionSecurityPeriod;\n maxAdditionSecurityPeriod = _maxAdditionSecurityPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max removal security period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultRemovalSecurityPeriod Default Removal Security Period for all Barz contracts\n * @param _minRemovalSecurityPeriod Minimum Removal Security Period for all Barz contracts\n * @param _maxRemovalSecurityPeriod Maximum Removal Security Period for all Barz contracts\n */\n function initializeRemovalSecurityPeriod(\n uint128 _defaultRemovalSecurityPeriod,\n uint128 _minRemovalSecurityPeriod,\n uint128 _maxRemovalSecurityPeriod\n )\n external\n override\n onlyOwner\n initializer(_isRemovalSecurityPeriodInitialized)\n {\n _isRemovalSecurityPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultRemovalSecurityPeriod,\n _minRemovalSecurityPeriod,\n _maxRemovalSecurityPeriod\n );\n defaultRemovalSecurityPeriod = _defaultRemovalSecurityPeriod;\n minRemovalSecurityPeriod = _minRemovalSecurityPeriod;\n maxRemovalSecurityPeriod = _maxRemovalSecurityPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/maxd security window for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultSecurityWindow Default Security Window for all Barz contracts\n * @param _minSecurityWindow Minimum Security Window for all Barz contracts\n * @param _maxSecurityWindow Maximum Security Window for all Barz contracts\n */\n function initializeSecurityWindow(\n uint128 _defaultSecurityWindow,\n uint128 _minSecurityWindow,\n uint128 _maxSecurityWindow\n ) external override onlyOwner initializer(_isSecurityWindowInitialized) {\n _isSecurityWindowInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultSecurityWindow,\n _minSecurityWindow,\n _maxSecurityWindow\n );\n defaultSecurityWindow = _defaultSecurityWindow;\n minSecurityWindow = _minSecurityWindow;\n maxSecurityWindow = _maxSecurityWindow;\n }\n\n /**\n * @notice Sets the initial default/min/max recovery period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultRecoveryPeriod Default Recovery Period for all Barz contracts\n * @param _minRecoveryPeriod Minimum Recovery Period for all Barz contracts\n * @param _maxRecoveryPeriod Maximum Recovery Period for all Barz contracts\n */\n function initializeRecoveryPeriod(\n uint128 _defaultRecoveryPeriod,\n uint128 _minRecoveryPeriod,\n uint128 _maxRecoveryPeriod\n ) external override onlyOwner initializer(_isRecoveryPeriodInitialized) {\n _isRecoveryPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultRecoveryPeriod,\n _minRecoveryPeriod,\n _maxRecoveryPeriod\n );\n defaultRecoveryPeriod = _defaultRecoveryPeriod;\n minRecoveryPeriod = _minRecoveryPeriod;\n maxRecoveryPeriod = _maxRecoveryPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max lock period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultLockPeriod Default Lock Period for all Barz contracts\n * @param _minLockPeriod Minimum Lock Period for all Barz contracts\n * @param _maxLockPeriod Maximum Lock Period for all Barz contracts\n */\n function initializeLockPeriod(\n uint128 _defaultLockPeriod,\n uint128 _minLockPeriod,\n uint128 _maxLockPeriod\n ) external override onlyOwner initializer(_isLockPeriodInitialized) {\n _isLockPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultLockPeriod,\n _minLockPeriod,\n _maxLockPeriod\n );\n defaultLockPeriod = _defaultLockPeriod;\n minLockPeriod = _minLockPeriod;\n maxLockPeriod = _maxLockPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max approval validation period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultApprovalValidationPeriod Default Approval Validation Period for all Barz contracts\n * @param _minApprovalValidationPeriod Minimum Approval Validation Period for all Barz contracts\n * @param _maxApprovalValidationPeriod Maximum Approval Validation Period for all Barz contracts\n */\n function initializeApprovalValidationPeriod(\n uint128 _defaultApprovalValidationPeriod,\n uint128 _minApprovalValidationPeriod,\n uint128 _maxApprovalValidationPeriod\n )\n external\n override\n onlyOwner\n initializer(_isApprovalValidationPeriodInitialized)\n {\n _isApprovalValidationPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultApprovalValidationPeriod,\n _minApprovalValidationPeriod,\n _maxApprovalValidationPeriod\n );\n defaultApprovalValidationPeriod = _defaultApprovalValidationPeriod;\n minApprovalValidationPeriod = _minApprovalValidationPeriod;\n maxApprovalValidationPeriod = _maxApprovalValidationPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max migration period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultMigrationPeriod Default Migration Period for all Barz contracts\n * @param _minMigrationPeriod Minimum Migration Period for all Barz contracts\n * @param _maxMigrationPeriod Maximum Migration Period for all Barz contracts\n */\n function initializeMigrationPeriod(\n uint128 _defaultMigrationPeriod,\n uint128 _minMigrationPeriod,\n uint128 _maxMigrationPeriod\n ) external override onlyOwner initializer(_isMigrationPeriodInitialized) {\n _isMigrationPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultMigrationPeriod,\n _minMigrationPeriod,\n _maxMigrationPeriod\n );\n defaultMigrationPeriod = _defaultMigrationPeriod;\n minMigrationPeriod = _minMigrationPeriod;\n maxMigrationPeriod = _maxMigrationPeriod;\n }\n\n /**\n * @notice Wallet owner sets the addition security period for the wallet. Only the owner of wallet can call this function.\n * The addition security period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _additionSecurityPeriod Custom Addition Security Period for the wallet\n */\n function setAdditionSecurityPeriod(\n address _wallet,\n uint128 _additionSecurityPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _additionSecurityPeriod,\n minAdditionSecurityPeriod,\n maxAdditionSecurityPeriod\n );\n securityConfigs[_wallet]\n .additionSecurityPeriod = _additionSecurityPeriod;\n }\n\n /**\n * @notice Wallet owner sets the removal security period for the wallet. Only the owner of wallet can call this function.\n * The removal security period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _removalSecurityPeriod Custom Removal Security Period for the wallet\n */\n function setRemovalSecurityPeriod(\n address _wallet,\n uint128 _removalSecurityPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _removalSecurityPeriod,\n minRemovalSecurityPeriod,\n maxRemovalSecurityPeriod\n );\n securityConfigs[_wallet].removalSecurityPeriod = _removalSecurityPeriod;\n }\n\n /**\n * @notice Wallet owner sets the security window for the wallet. Only the owner of wallet can call this function.\n * The security window should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _securityWindow Custom Security Window for the wallet\n */\n function setSecurityWindow(\n address _wallet,\n uint128 _securityWindow\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _securityWindow,\n minSecurityWindow,\n maxSecurityWindow\n );\n securityConfigs[_wallet].securityWindow = _securityWindow;\n }\n\n /**\n * @notice Wallet owner sets the recovery period for the wallet. Only the owner of wallet can call this function.\n * The recovery period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _recoveryPeriod Custom recovery period for the wallet\n */\n function setRecoveryPeriod(\n address _wallet,\n uint128 _recoveryPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _recoveryPeriod,\n minRecoveryPeriod,\n maxRecoveryPeriod\n );\n securityConfigs[_wallet].recoveryPeriod = _recoveryPeriod;\n }\n\n /**\n * @notice Wallet owner sets the lock period for the wallet. Only the owner of wallet can call this function.\n * The lock period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _lockPeriod Custom Lock period for the wallet\n */\n function setLockPeriod(\n address _wallet,\n uint128 _lockPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(_lockPeriod, minLockPeriod, maxLockPeriod);\n securityConfigs[_wallet].lockPeriod = _lockPeriod;\n }\n\n /**\n * @notice Wallet owner sets the approval validation period for the wallet. Only the owner of wallet can call this function.\n * The approval validation period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _approvalValidationPeriod Custom approval validation period for the wallet\n */\n function setApprovalValidationPeriod(\n address _wallet,\n uint128 _approvalValidationPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _approvalValidationPeriod,\n minApprovalValidationPeriod,\n maxApprovalValidationPeriod\n );\n securityConfigs[_wallet]\n .approvalValidationPeriod = _approvalValidationPeriod;\n }\n\n /**\n * @notice Wallet owner sets the migration period for the wallet. Only the owner of wallet can call this function.\n * The migration period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _migrationPeriod Custom migration period for the wallet\n */\n\n function setMigrationPeriod(\n address _wallet,\n uint128 _migrationPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _migrationPeriod,\n minMigrationPeriod,\n maxMigrationPeriod\n );\n securityConfigs[_wallet].migrationPeriod = _migrationPeriod;\n }\n\n /**\n * @notice Returns the addition security period. Returns default value when custom addition security period is not set\n * @param _wallet Address of wallet\n * @return additionSecurityPeriod Addition Security Period of the given Barz account or wallet\n */\n function additionSecurityPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 additionSecurityPeriod)\n {\n additionSecurityPeriod = securityConfigs[_wallet]\n .additionSecurityPeriod;\n additionSecurityPeriod = (additionSecurityPeriod == 0)\n ? defaultAdditionSecurityPeriod\n : additionSecurityPeriod;\n }\n\n /**\n * @notice Returns the removal security period. Returns default value when custom removal security period is not set\n * @param _wallet Address of wallet\n * @return removalSecurityPeriod Removal Security Period of the given Barz account or wallet\n */\n function removalSecurityPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 removalSecurityPeriod)\n {\n removalSecurityPeriod = securityConfigs[_wallet].removalSecurityPeriod;\n removalSecurityPeriod = (removalSecurityPeriod == 0)\n ? defaultRemovalSecurityPeriod\n : removalSecurityPeriod;\n }\n\n /**\n * @notice Returns the security window. Returns default value when custom security window is not set\n * @param _wallet Address of wallet\n * @return securityWindow Security window of the given Barz account or wallet\n */\n function securityWindowOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 securityWindow)\n {\n securityWindow = securityConfigs[_wallet].securityWindow;\n securityWindow = (securityWindow == 0)\n ? defaultSecurityWindow\n : securityWindow;\n }\n\n /**\n * @notice Returns the recovery period. Returns default value when custom recovery period is not set\n * @param _wallet Address of wallet\n * @return recoveryPeriod Recovery Period of the given Barz account or wallet\n */\n function recoveryPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 recoveryPeriod)\n {\n recoveryPeriod = securityConfigs[_wallet].recoveryPeriod;\n recoveryPeriod = (recoveryPeriod == 0)\n ? defaultRecoveryPeriod\n : recoveryPeriod;\n }\n\n /**\n * @notice Returns the lock period. Returns default value when custom lock period is not set\n * @param _wallet Address of wallet\n * @return lockPeriod Lock Period of the given Barz account or wallet\n */\n function lockPeriodOf(\n address _wallet\n ) public view override onlyWallet(_wallet) returns (uint128 lockPeriod) {\n lockPeriod = securityConfigs[_wallet].lockPeriod;\n lockPeriod = (lockPeriod == 0) ? defaultLockPeriod : lockPeriod;\n }\n\n /**\n * @notice Returns the approval validation period. Returns default value when custom approval validation period is not set\n * @param _wallet Address of wallet\n * @return approvalValidationPeriod Approval Validation Period of the given Barz account or wallet\n */\n function approvalValidationPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityConfigs[_wallet]\n .approvalValidationPeriod;\n approvalValidationPeriod = (approvalValidationPeriod == 0)\n ? defaultApprovalValidationPeriod\n : approvalValidationPeriod;\n }\n\n /**\n * @notice Returns the migration period. Returns default value when custom migration period is not set\n * @param _wallet Address of wallet\n * @return migrationPeriod Migration Period of the given Barz account or wallet\n */\n function migrationPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 migrationPeriod)\n {\n migrationPeriod = securityConfigs[_wallet].migrationPeriod;\n migrationPeriod = (migrationPeriod == 0)\n ? defaultMigrationPeriod\n : migrationPeriod;\n }\n\n /**\n * @notice Validates if the period is smaller than the max period or bigger than the min period\n * @param _period Period to be checked\n * @param _minPeriod Minimum period\n * @param _maxPeriod Maximum period\n */\n function _validatePeriodBoundaries(\n uint128 _period,\n uint128 _minPeriod,\n uint128 _maxPeriod\n ) internal pure {\n if (_period >= _maxPeriod || _period <= _minPeriod)\n revert SecurityManager__OutOfBoundary();\n }\n}\n" + }, + "contracts/infrastructure/WhitelistStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {RemoteStorage} from \"./RemoteStorage.sol\";\n\n/**\n * @title Whitelist storage\n * @dev Maps addresses to the corresponsing array of whitelisted addresses for each of them.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract WhitelistStorage is RemoteStorage {\n /**\n * @dev Add the address to the whitelist storage\n * @param _wallet User wallet\n * @param _address Address to be whitelisted\n */\n function whitelistAddress(address _wallet, address _address) external {\n enforceWalletOrGuardianIfExists(_wallet);\n addAddress(_wallet, _address);\n }\n\n /**\n * @dev Removes the address from the whitelist storage\n * @param _wallet User wallet\n * @param _address Address to be removed from the whitelist\n */\n function blacklistAddress(address _wallet, address _address) external {\n enforceGuardianOrWallet(_wallet);\n removeAddress(_wallet, _address);\n }\n\n /**\n * @dev Returns whether the address exists in the whitelist storage, associated with the wallet\n * @param _wallet User wallet\n * @param _address Address to be whitelisted\n */\n function isWhitelisted(\n address _wallet,\n address _address\n ) external view returns (bool) {\n return exists(_wallet, _address);\n }\n\n /**\n * @dev Returns all whitelisted addresses associated with the wallet\n * @param _wallet User wallet\n */\n function getWhitelistedAddresses(\n address _wallet\n ) external view returns (address[] memory) {\n return getAddresses(_wallet);\n }\n}\n" + }, + "contracts/interfaces/ERC/IERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\n\npragma solidity 0.8.21;\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155Receiver {\n /**\n * @dev Handles the receipt of a single ERC1155 token type. This function is\n * called at the end of a `safeTransferFrom` after the balance has been updated.\n *\n * NOTE: To accept the transfer, this must return\n * `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n * (i.e. 0xf23a6e61, or its own function selector).\n *\n * @param operator The address which initiated the transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param id The ID of the token being transferred\n * @param value The amount of tokens being transferred\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n ) external returns (bytes4);\n\n /**\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\n * is called at the end of a `safeBatchTransferFrom` after the balances have\n * been updated.\n *\n * NOTE: To accept the transfer(s), this must return\n * `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n * (i.e. 0xbc197c81, or its own function selector).\n *\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "contracts/interfaces/ERC/IERC1271.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\ninterface IERC1271 {\n function isValidSignature(\n bytes32 hash,\n bytes memory signature\n ) external view returns (bytes4);\n}\n" + }, + "contracts/interfaces/ERC/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\ninterface IERC165 {\n /// @notice Query if a contract implements an interface\n /// @param interfaceId The interface identifier, as specified in ERC-165\n /// @dev Interface identification is specified in ERC-165. This function\n /// uses less than 30,000 gas.\n /// @return `true` if the contract implements `interfaceID` and\n /// `interfaceID` is not 0xffffffff, `false` otherwise\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/IERC173.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\n/// @title ERC-173 Contract Ownership Standard\n/// Note: the ERC-165 identifier for this interface is 0x7f5828d0\n/* is ERC165 */\ninterface IERC173 {\n /// @dev This emits when ownership of a contract changes.\n event OwnershipTransferred(\n address indexed previousOwner,\n address indexed newOwner\n );\n\n /// @notice Get the address of the owner\n /// @return owner_ The address of the owner.\n function owner() external view returns (address owner_);\n\n /// @notice Set the address of the new owner of the contract\n /// @dev Set _newOwner to address(0) to renounce any ownership.\n /// @param _newOwner The address of the new owner of the contract\n function transferOwnership(address _newOwner) external;\n}\n" + }, + "contracts/interfaces/ERC/IERC677Receiver.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\ninterface IERC677Receiver {\n function onTokenTransfer(\n address sender,\n uint value,\n bytes calldata data\n ) external pure returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155 is IERC165 {\n /**\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n */\n event TransferSingle(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256 id,\n uint256 value\n );\n\n /**\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n * transfers.\n */\n event TransferBatch(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\n\n /**\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n * `approved`.\n */\n event ApprovalForAll(\n address indexed account,\n address indexed operator,\n bool approved\n );\n\n /**\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n *\n * If an {URI} event was emitted for `id`, the standard\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n * returned by {IERC1155MetadataURI-uri}.\n */\n event URI(string value, uint256 indexed id);\n\n /**\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(\n address account,\n uint256 id\n ) external view returns (uint256);\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] calldata accounts,\n uint256[] calldata ids\n ) external view returns (uint256[] memory);\n\n /**\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n *\n * Emits an {ApprovalForAll} event.\n *\n * Requirements:\n *\n * - `operator` cannot be the caller.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n *\n * See {setApprovalForAll}.\n */\n function isApprovedForAll(\n address account,\n address operator\n ) external view returns (bool);\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes calldata data\n ) external;\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(\n address indexed owner,\n address indexed spender,\n uint256 value\n );\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` 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 amount) 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(\n address owner,\n address spender\n ) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the 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 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` 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(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(\n address spender,\n uint256 addedValue\n ) external returns (bool);\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(\n address spender,\n uint256 subtractedValue\n ) external returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(\n address indexed from,\n address indexed to,\n uint256 indexed tokenId\n );\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(\n address indexed owner,\n address indexed approved,\n uint256 indexed tokenId\n );\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(\n address indexed owner,\n address indexed operator,\n bool approved\n );\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(\n uint256 tokenId\n ) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(\n address owner,\n address operator\n ) external view returns (bool);\n}\n" + }, + "contracts/interfaces/IBarz.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Barz Interface\n * @dev Interface of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IBarz {\n error Barz__InitializationFailure();\n}\n" + }, + "contracts/interfaces/IBarzFactory.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Barz} from \"../Barz.sol\";\n\n/**\n * @title Barz Factory Interface\n * @dev Interface of contract to easily deploy Barz to a pre-computed address with a single call\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IBarzFactory {\n function createAccount(\n address verificationFacet,\n bytes calldata owner,\n uint256 salt\n ) external returns (Barz);\n\n function getAddress(\n address verificationFacet,\n bytes calldata owner,\n uint256 salt\n ) external view returns (address);\n\n function getBytecode(\n address accountFacet,\n address verificationFacet,\n address entryPoint,\n address facetRegistry,\n address defaultFallback,\n bytes memory ownerPublicKey\n ) external pure returns (bytes memory);\n\n function getCreationCode() external pure returns (bytes memory);\n}\n" + }, + "contracts/libraries/DefaultLibDiamond.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\n\nerror InitializationFunctionReverted(\n address _initializationContractAddress,\n bytes _calldata\n);\n\nlibrary DefaultLibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION =\n keccak256(\"trustwallet.barz.diamond.storage\");\n\n struct FacetAddressAndPosition {\n address facetAddress;\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\n }\n\n struct FacetFunctionSelectors {\n bytes4[] functionSelectors;\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\n }\n\n struct DiamondStorage {\n // maps function selector to the facet address and\n // the position of the selector in the facetFunctionSelectors.selectors array\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\n // maps facet addresses to function selectors\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\n // facet addresses\n address[] facetAddresses;\n // Used to query if a contract implements an interface.\n // Used to implement ERC-165.\n mapping(bytes4 => bool) supportedInterfaces;\n }\n\n function diamondStorage()\n internal\n pure\n returns (DiamondStorage storage ds)\n {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n event DiamondCut(\n IDiamondCut.FacetCut[] _diamondCut,\n address _init,\n bytes _calldata\n );\n\n // Internal function version of diamondCut\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n for (\n uint256 facetIndex;\n facetIndex < _diamondCut.length;\n facetIndex++\n ) {\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\n if (action == IDiamondCut.FacetCutAction.Add) {\n addFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\n replaceFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\n removeFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else {\n revert(\"LibDiamondCut: Incorrect FacetCutAction\");\n }\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Add facet can't be address(0)\"\n );\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n require(\n oldFacetAddress == address(0),\n \"LibDiamondCut: Can't add function that already exists\"\n );\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function replaceFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Replace facet can't be address(0)\"\n );\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n require(\n oldFacetAddress != _facetAddress,\n \"LibDiamondCut: Can't replace function with same facet\"\n );\n removeFunction(ds, oldFacetAddress, selector);\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function removeFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n // if function does not exist then do nothing and return\n require(\n _facetAddress == address(0),\n \"LibDiamondCut: Remove facet address must be address(0)\"\n );\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n removeFunction(ds, oldFacetAddress, selector);\n }\n }\n\n function addFacet(\n DiamondStorage storage ds,\n address _facetAddress\n ) internal {\n enforceHasContractCode(\n _facetAddress,\n \"LibDiamondCut: New facet has no code\"\n );\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds\n .facetAddresses\n .length;\n ds.facetAddresses.push(_facetAddress);\n }\n\n function addFunction(\n DiamondStorage storage ds,\n bytes4 _selector,\n uint96 _selectorPosition,\n address _facetAddress\n ) internal {\n ds\n .selectorToFacetAndPosition[_selector]\n .functionSelectorPosition = _selectorPosition;\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(\n _selector\n );\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\n }\n\n function removeFunction(\n DiamondStorage storage ds,\n address _facetAddress,\n bytes4 _selector\n ) internal {\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Can't remove function that doesn't exist\"\n );\n // an immutable function is a function defined directly in a diamond\n require(\n _facetAddress != address(this),\n \"LibDiamondCut: Can't remove immutable function\"\n );\n // replace selector with last selector, then delete last selector\n uint256 selectorPosition = ds\n .selectorToFacetAndPosition[_selector]\n .functionSelectorPosition;\n uint256 lastSelectorPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors\n .length - 1;\n // if not the same then replace _selector with lastSelector\n if (selectorPosition != lastSelectorPosition) {\n bytes4 lastSelector = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors[lastSelectorPosition];\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[\n selectorPosition\n ] = lastSelector;\n ds\n .selectorToFacetAndPosition[lastSelector]\n .functionSelectorPosition = uint96(selectorPosition);\n }\n // delete the last selector\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\n delete ds.selectorToFacetAndPosition[_selector];\n\n // if no more selectors for facet address then delete the facet address\n if (lastSelectorPosition == 0) {\n // replace facet address with last facet address and delete last facet address\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\n uint256 facetAddressPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .facetAddressPosition;\n if (facetAddressPosition != lastFacetAddressPosition) {\n address lastFacetAddress = ds.facetAddresses[\n lastFacetAddressPosition\n ];\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\n ds\n .facetFunctionSelectors[lastFacetAddress]\n .facetAddressPosition = facetAddressPosition;\n }\n ds.facetAddresses.pop();\n delete ds\n .facetFunctionSelectors[_facetAddress]\n .facetAddressPosition;\n }\n }\n\n function initializeDiamondCut(\n address _init,\n bytes memory _calldata\n ) internal {\n if (_init == address(0)) {\n return;\n }\n enforceHasContractCode(\n _init,\n \"LibDiamondCut: _init address has no code\"\n );\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length > 0) {\n // bubble up error\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(error)\n revert(add(32, error), returndata_size)\n }\n } else {\n revert InitializationFunctionReverted(_init, _calldata);\n }\n }\n }\n\n function enforceHasContractCode(\n address _contract,\n string memory _errorMessage\n ) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize > 0, _errorMessage);\n }\n}\n" + }, + "contracts/libraries/LibAppStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SafeCast} from \"@openzeppelin/contracts/utils/math/SafeCast.sol\";\nimport {IEntryPoint} from \"../aa-4337/interfaces/IEntryPoint.sol\";\nimport {IFacetRegistry} from \"../infrastructure/interfaces/IFacetRegistry.sol\";\n\n/*\n * @title App Storage\n * @dev App storage for Barz contract to prevent storage collision\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\n\nstruct Lock {\n uint64 release;\n bytes4 locker;\n}\n\nstruct InitializersStorage {\n // NOTE: initialized is a variable to make sure the initialization is only done once.\n uint8 signerInitialized;\n uint8 accountInitialized;\n uint8 restrictionsInitialized;\n}\n\nstruct AppStorage {\n mapping(uint256 => InitializersStorage) initStorage;\n uint8 signerMigration;\n bytes4 validateOwnerSignatureSelector;\n IEntryPoint entryPoint;\n IFacetRegistry facetRegistry;\n mapping(uint256 => Lock) locks;\n}\n\nlibrary LibAppStorage {\n error LibAppStorage__AccountAlreadyUninitialized();\n error LibAppStorage__AccountMustBeUninitialized();\n error LibAppStorage__SignerAlreadyUninitialized();\n error LibAppStorage__SignerMustBeUninitialized();\n\n function appStorage() internal pure returns (AppStorage storage ds) {\n assembly {\n ds.slot := 0\n }\n }\n\n function setSignerUninitialized() internal {\n AppStorage storage s = appStorage();\n if (1 != s.initStorage[0].signerInitialized) {\n revert LibAppStorage__SignerAlreadyUninitialized();\n }\n s.initStorage[0].signerInitialized = 0;\n }\n\n function getValidateOwnerSignatureSelector()\n internal\n view\n returns (bytes4 selector)\n {\n selector = appStorage().validateOwnerSignatureSelector;\n }\n\n function setValidateOwnerSignatureSelector(\n bytes4 _validateOwnerSignatureSelector\n ) internal {\n appStorage()\n .validateOwnerSignatureSelector = _validateOwnerSignatureSelector;\n }\n\n function enforceSignerInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].signerInitialized) {\n revert LibAppStorage__SignerMustBeUninitialized();\n }\n s.initStorage[0].signerInitialized = 1;\n }\n\n function enforceAccountInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].accountInitialized) {\n revert LibAppStorage__AccountMustBeUninitialized();\n }\n s.initStorage[0].accountInitialized = 1;\n }\n\n function initiateSignerMigration() internal {\n appStorage().signerMigration = 1;\n }\n\n function enforceSignerMigration() internal view {\n if (1 != appStorage().signerMigration) {\n revert LibAppStorage__AccountMustBeUninitialized();\n }\n }\n\n function finalizeSignerMigration() internal {\n appStorage().signerMigration = 0;\n }\n\n function setLock(uint256 _releaseAfter, bytes4 _locker) internal {\n appStorage().locks[0] = Lock(SafeCast.toUint64(_releaseAfter), _locker);\n }\n\n function enforceRestrictionsInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].restrictionsInitialized)\n revert LibAppStorage__SignerMustBeUninitialized();\n s.initStorage[0].restrictionsInitialized = 1;\n }\n\n function setRestrictionsUninitialized() internal {\n AppStorage storage s = appStorage();\n if (1 != s.initStorage[0].restrictionsInitialized)\n revert LibAppStorage__AccountAlreadyUninitialized();\n s.initStorage[0].restrictionsInitialized = 0;\n }\n}\n\ncontract BarzStorage {\n AppStorage internal s;\n modifier onlyWhenUnlocked() {\n require(\n uint64(block.timestamp) >= s.locks[0].release,\n \"Account Locked\"\n );\n _;\n }\n modifier onlyWhenLocked() {\n require(\n uint64(block.timestamp) < s.locks[0].release,\n \"Account Unlocked\"\n );\n _;\n }\n}\n" + }, + "contracts/libraries/LibDiamond.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\n\nerror InitializationFunctionReverted(\n address _initializationContractAddress,\n bytes _calldata\n);\n\nlibrary LibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION =\n keccak256(\"trustwallet.barz.diamond.storage\");\n\n struct DiamondStorage {\n // maps function selectors to the facets that execute the functions.\n // and maps the selectors to their position in the selectorSlots array.\n // func selector => address facet, selector position\n mapping(bytes4 => bytes32) facets;\n // array of slots of function selectors.\n // each slot holds 8 function selectors.\n mapping(uint256 => bytes32) selectorSlots;\n // The number of function selectors in selectorSlots\n uint16 selectorCount;\n // Used to query if a contract implements an interface.\n // Used to implement ERC-165.\n mapping(bytes4 => bool) supportedInterfaces;\n // Default Fallback Handler of the barz.\n IDiamondLoupe defaultFallbackHandler;\n }\n\n function diamondStorage()\n internal\n pure\n returns (DiamondStorage storage ds)\n {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n function enforceIsSelf() internal view {\n require(msg.sender == address(this), \"LibDiamond: Caller not self\");\n }\n\n event DiamondCut(\n IDiamondCut.FacetCut[] _diamondCut,\n address _init,\n bytes _calldata\n );\n\n bytes32 constant CLEAR_ADDRESS_MASK =\n bytes32(uint256(0xffffffffffffffffffffffff));\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\n\n // Internal function version of diamondCut\n // This code is almost the same as the external diamondCut,\n // except it is using 'Facet[] memory _diamondCut' instead of\n // 'Facet[] calldata _diamondCut'.\n // The code is duplicated to prevent copying calldata to memory which\n // causes an error for a two dimensional array.\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n DiamondStorage storage ds = diamondStorage();\n uint256 originalSelectorCount = ds.selectorCount;\n uint256 selectorCount = originalSelectorCount;\n bytes32 selectorSlot;\n // Check if last selector slot is not full\n // \"selectorCount & 7\" is a gas efficient modulo by eight \"selectorCount % 8\"\n if (selectorCount & 7 > 0) {\n // get last selectorSlot\n // \"selectorSlot >> 3\" is a gas efficient division by 8 \"selectorSlot / 8\"\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\n }\n // loop through diamond cut\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\n selectorCount,\n selectorSlot,\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].action,\n _diamondCut[facetIndex].functionSelectors\n );\n\n unchecked {\n facetIndex++;\n }\n }\n if (selectorCount != originalSelectorCount) {\n ds.selectorCount = uint16(selectorCount);\n }\n // If last selector slot is not full\n // \"selectorCount & 7\" is a gas efficient modulo by eight \"selectorCount % 8\"\n if (selectorCount & 7 > 0) {\n // \"selectorSlot >> 3\" is a gas efficient division by 8 \"selectorSlot / 8\"\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addReplaceRemoveFacetSelectors(\n uint256 _selectorCount,\n bytes32 _selectorSlot,\n address _newFacetAddress,\n IDiamondCut.FacetCutAction _action,\n bytes4[] memory _selectors\n ) internal returns (uint256, bytes32) {\n DiamondStorage storage ds = diamondStorage();\n require(\n _selectors.length > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n if (_action == IDiamondCut.FacetCutAction.Add) {\n enforceHasContractCode(\n _newFacetAddress,\n \"LibDiamondCut: Add facet has no code\"\n );\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n require(\n address(bytes20(oldFacet)) == address(0),\n \"LibDiamondCut: Can't add function that already exists\"\n );\n // add facet for selector\n ds.facets[selector] =\n bytes20(_newFacetAddress) |\n bytes32(_selectorCount);\n // \"_selectorCount & 7\" is a gas efficient modulo by eight \"_selectorCount % 8\"\n // \" << 5 is the same as multiplying by 32 ( * 32)\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\n // clear selector position in slot and add selector\n _selectorSlot =\n (_selectorSlot &\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\n (bytes32(selector) >> selectorInSlotPosition);\n // if slot is full then write it to storage\n if (selectorInSlotPosition == 224) {\n // \"_selectorSlot >> 3\" is a gas efficient division by 8 \"_selectorSlot / 8\"\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\n _selectorSlot = 0;\n }\n _selectorCount++;\n\n unchecked {\n selectorIndex++;\n }\n }\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\n enforceHasContractCode(\n _newFacetAddress,\n \"LibDiamondCut: Replace facet has no code\"\n );\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n address oldFacetAddress = address(bytes20(oldFacet));\n // only useful if immutable functions exist\n require(\n oldFacetAddress != address(this),\n \"LibDiamondCut: Can't replace immutable function\"\n );\n require(\n oldFacetAddress != _newFacetAddress,\n \"LibDiamondCut: Can't replace function with same function\"\n );\n require(\n oldFacetAddress != address(0),\n \"LibDiamondCut: Can't replace function that doesn't exist\"\n );\n // replace old facet address\n ds.facets[selector] =\n (oldFacet & CLEAR_ADDRESS_MASK) |\n bytes20(_newFacetAddress);\n\n unchecked {\n selectorIndex++;\n }\n }\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\n require(\n _newFacetAddress == address(0),\n \"LibDiamondCut: Remove facet address must be address(0)\"\n );\n // \"_selectorCount >> 3\" is a gas efficient division by 8 \"_selectorCount / 8\"\n uint256 selectorSlotCount = _selectorCount >> 3;\n // \"_selectorCount & 7\" is a gas efficient modulo by eight \"_selectorCount % 8\"\n uint256 selectorInSlotIndex = _selectorCount & 7;\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n if (_selectorSlot == 0) {\n // get last selectorSlot\n selectorSlotCount--;\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\n selectorInSlotIndex = 7;\n } else {\n selectorInSlotIndex--;\n }\n bytes4 lastSelector;\n uint256 oldSelectorsSlotCount;\n uint256 oldSelectorInSlotPosition;\n // adding a block here prevents stack too deep error\n {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n require(\n address(bytes20(oldFacet)) != address(0),\n \"LibDiamondCut: Can't remove function that doesn't exist\"\n );\n // only useful if immutable functions exist\n require(\n address(bytes20(oldFacet)) != address(this),\n \"LibDiamondCut: Can't remove immutable function\"\n );\n // replace selector with last selector in ds.facets\n // gets the last selector\n // \" << 5 is the same as multiplying by 32 ( * 32)\n lastSelector = bytes4(\n _selectorSlot << (selectorInSlotIndex << 5)\n );\n if (lastSelector != selector) {\n // update last selector slot position info\n ds.facets[lastSelector] =\n (oldFacet & CLEAR_ADDRESS_MASK) |\n bytes20(ds.facets[lastSelector]);\n }\n delete ds.facets[selector];\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\n // \"oldSelectorCount >> 3\" is a gas efficient division by 8 \"oldSelectorCount / 8\"\n oldSelectorsSlotCount = oldSelectorCount >> 3;\n // \"oldSelectorCount & 7\" is a gas efficient modulo by eight \"oldSelectorCount % 8\"\n // \" << 5 is the same as multiplying by 32 ( * 32)\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\n }\n if (oldSelectorsSlotCount != selectorSlotCount) {\n bytes32 oldSelectorSlot = ds.selectorSlots[\n oldSelectorsSlotCount\n ];\n // clears the selector we are deleting and puts the last selector in its place.\n oldSelectorSlot =\n (oldSelectorSlot &\n ~(CLEAR_SELECTOR_MASK >>\n oldSelectorInSlotPosition)) |\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\n // update storage with the modified slot\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\n } else {\n // clears the selector we are deleting and puts the last selector in its place.\n _selectorSlot =\n (_selectorSlot &\n ~(CLEAR_SELECTOR_MASK >>\n oldSelectorInSlotPosition)) |\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\n }\n if (selectorInSlotIndex == 0) {\n delete ds.selectorSlots[selectorSlotCount];\n _selectorSlot = 0;\n }\n\n unchecked {\n selectorIndex++;\n }\n }\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\n } else {\n revert(\"LibDiamondCut: Incorrect FacetCutAction\");\n }\n return (_selectorCount, _selectorSlot);\n }\n\n function initializeDiamondCut(\n address _init,\n bytes memory _calldata\n ) internal {\n if (_init == address(0)) {\n return;\n }\n enforceHasContractCode(\n _init,\n \"LibDiamondCut: _init address has no code\"\n );\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length > 0) {\n // bubble up error\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(error)\n revert(add(32, error), returndata_size)\n }\n } else {\n revert InitializationFunctionReverted(_init, _calldata);\n }\n }\n }\n\n function enforceHasContractCode(\n address _contract,\n string memory _errorMessage\n ) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize > 0, _errorMessage);\n }\n\n function restrictionsFacet() internal view returns (address facetAddress_) {\n bytes4 selector = bytes4(\n keccak256(\"verifyRestrictions(address,address,uint256,bytes)\")\n );\n facetAddress_ = address(\n bytes20(LibDiamond.diamondStorage().facets[selector])\n );\n }\n}\n" + }, + "contracts/libraries/LibFacetStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Storage\n * @dev Storage contract to store each facets variables with diamond storage\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\n\nstruct Secp256k1VerificationStorage {\n address signer;\n}\n\nstruct Secp256r1VerificationStorage {\n uint256[2] q;\n}\n\nstruct GuardianStorage {\n mapping(bytes32 => uint256) pending;\n mapping(uint8 => StorageConfig) configs;\n}\n\nstruct Info {\n bool exists;\n uint128 index;\n}\n\nstruct StorageConfig {\n address[] addresses;\n mapping(address => Info) info;\n}\n\nstruct RecoveryConfig {\n bytes recoveryPublicKey;\n uint64 executeAfter;\n}\n\nstruct ApprovalConfig {\n bool isApproved;\n uint64 validUntil;\n}\n\nstruct RecoveryApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isNewOwnerApproved;\n}\n\nstruct RecoveryStorage {\n mapping(uint8 => RecoveryConfig) recoveryConfigs;\n mapping(uint8 => RecoveryApprovalConfig) recoveryApprovalConfigs;\n uint128 nonce;\n}\n\nstruct RestrictionsStorage {\n address[] restrictions;\n mapping(address => bool) exists;\n}\n\nstruct SignatureMigrationConfig {\n bytes migrationPublicKey;\n address migrationVerificationFacet;\n bytes4[] migrationSelectors;\n uint64 migrateAfter;\n}\n\nstruct SignatureMigrationApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isMigrationApproved;\n}\n\nstruct SignatureMigrationStorage {\n mapping(uint8 => SignatureMigrationConfig) migrationConfigs;\n mapping(uint8 => SignatureMigrationApprovalConfig) migrationApprovalConfigs;\n uint128 nonce;\n}\n\nstruct DiamondCutApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isDiamondCutApproved;\n}\n\nstruct DiamondCutStorage {\n mapping(uint8 => DiamondCutApprovalConfig) diamondCutApprovalConfigs;\n uint128 nonce;\n}\n\nstruct LockStorage {\n uint128 nonce;\n}\n\nlibrary LibFacetStorage {\n function k1Storage()\n internal\n pure\n returns (Secp256k1VerificationStorage storage ds)\n {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.Secp256k1VerificationStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function r1Storage()\n internal\n pure\n returns (Secp256r1VerificationStorage storage ds)\n {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.Secp256r1VerificationStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function guardianStorage()\n internal\n pure\n returns (GuardianStorage storage ds)\n {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.GuardianStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function recoveryStorage()\n internal\n pure\n returns (RecoveryStorage storage ds)\n {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.RecoveryStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function restrictionsStorage()\n internal\n pure\n returns (RestrictionsStorage storage ds)\n {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.RestrictionsStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function migrationStorage()\n internal\n pure\n returns (SignatureMigrationStorage storage ds)\n {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.SignatureMigrationStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function diamondCutStorage()\n internal\n pure\n returns (DiamondCutStorage storage ds)\n {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.DiamondCutStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function lockStorage() internal pure returns (LockStorage storage ds) {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.LockStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n}\n" + }, + "contracts/libraries/LibGuardian.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibFacetStorage, StorageConfig} from \"./LibFacetStorage.sol\";\n\n/**\n * @title LibGuardian\n * @dev Internal Library to provide utility feature for Guardians stored in Guardian Facet Storage\n * @author David Yongjun Kim (@Powerstream3604)\n */\nlibrary LibGuardian {\n function majorityOfGuardians()\n internal\n view\n returns (uint256 guardianNumber)\n {\n uint256 guardianLength = guardianCount();\n guardianNumber = (guardianLength == 0) ? 0 : guardianLength / 2 + 1;\n }\n\n function isGuardian(address _guardian) internal view returns (bool) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n return config.info[_guardian].exists;\n }\n\n function guardianCount() internal view returns (uint256) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n return config.addresses.length;\n }\n\n function getGuardians() internal view returns (address[] memory) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n address[] memory addresses = new address[](config.addresses.length);\n uint256 addressesLen = config.addresses.length;\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n return addresses;\n }\n}\n" + }, + "contracts/libraries/LibLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {LibDiamond} from \"./LibDiamond.sol\";\n\n/**\n * @title LibLoupe\n * @dev Internal Library to provide utility feature for reading the state of diamond facets\n * @author David Yongjun Kim (@Powerstream3604)\n */\nlibrary LibLoupe {\n /// @notice Gets all facets and their selectors.\n /// @return facets_ Facet\n function facets()\n internal\n view\n returns (IDiamondLoupe.Facet[] memory facets_)\n {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facets_ = new IDiamondLoupe.Facet[](ds.selectorCount);\n uint16[] memory numFacetSelectors = new uint16[](ds.selectorCount);\n uint256 numFacets;\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facetAddress_ = address(bytes20(ds.facets[selector]));\n bool continueLoop;\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n if (facets_[facetIndex].facetAddress == facetAddress_) {\n facets_[facetIndex].functionSelectors[\n numFacetSelectors[facetIndex]\n ] = selector;\n // probably will never have more than 256 functions from one facet contract\n require(numFacetSelectors[facetIndex] < 255);\n numFacetSelectors[facetIndex]++;\n continueLoop = true;\n break;\n }\n }\n if (continueLoop) {\n continue;\n }\n facets_[numFacets].facetAddress = facetAddress_;\n facets_[numFacets].functionSelectors = new bytes4[](\n ds.selectorCount\n );\n facets_[numFacets].functionSelectors[0] = selector;\n numFacetSelectors[numFacets] = 1;\n numFacets++;\n }\n }\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n uint256 numSelectors = numFacetSelectors[facetIndex];\n bytes4[] memory selectors = facets_[facetIndex].functionSelectors;\n // setting the number of selectors\n assembly {\n mstore(selectors, numSelectors)\n }\n }\n // setting the number of facets\n assembly {\n mstore(facets_, numFacets)\n }\n }\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n /// @return _facetFunctionSelectors The selectors associated with a facet address.\n function facetFunctionSelectors(\n address _facet\n ) internal view returns (bytes4[] memory _facetFunctionSelectors) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n uint256 numSelectors;\n _facetFunctionSelectors = new bytes4[](ds.selectorCount);\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facet = address(bytes20(ds.facets[selector]));\n if (_facet == facet) {\n _facetFunctionSelectors[numSelectors] = selector;\n numSelectors++;\n }\n }\n }\n // Set the number of selectors in the array\n assembly {\n mstore(_facetFunctionSelectors, numSelectors)\n }\n }\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses()\n internal\n view\n returns (address[] memory facetAddresses_)\n {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facetAddresses_ = new address[](ds.selectorCount);\n uint256 numFacets;\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facetAddress_ = address(bytes20(ds.facets[selector]));\n bool continueLoop;\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n if (facetAddress_ == facetAddresses_[facetIndex]) {\n continueLoop = true;\n break;\n }\n }\n if (continueLoop) {\n continue;\n }\n facetAddresses_[numFacets] = facetAddress_;\n numFacets++;\n }\n }\n // Set the number of facet addresses in the array\n assembly {\n mstore(facetAddresses_, numFacets)\n }\n }\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(\n bytes4 _functionSelector\n ) internal view returns (address facetAddress_) {\n facetAddress_ = address(\n bytes20(LibDiamond.diamondStorage().facets[_functionSelector])\n );\n }\n}\n" + }, + "contracts/libraries/LibMultiSigStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Multi-sig Storage\n * @dev Storage contract for storing Multi-sig Facet variables in diamond storage pattern\n * @author David Yongjun Kim (@Powerstream3604)\n */\n\nstruct MultiSigStorage {\n mapping(address => address) owners;\n mapping(uint256 => mapping(address => mapping(bytes32 => uint256))) approvedHashes;\n uint256 ownerCount;\n uint256 threshold;\n uint256 counter;\n}\n\nlibrary LibMultiSigStorage {\n function multisigStorage()\n internal\n pure\n returns (MultiSigStorage storage ds)\n {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.MultiSigStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n}\n" + }, + "contracts/libraries/LibRecoverSpender.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title RecoverSpender\n * @dev Library to determine the action and spender of calldata\n * @author Ruslan Serebriakov (@rsrbk)\n */\nlibrary LibRecoverSpender {\n // ERC20, ERC721 & ERC1155 transfers & approvals\n bytes4 private constant ERC20_TRANSFER =\n bytes4(keccak256(\"transfer(address,uint256)\"));\n bytes4 private constant ERC20_APPROVE =\n bytes4(keccak256(\"approve(address,uint256)\"));\n bytes4 private constant ERC20_INCREASE_ALLOWANCE =\n bytes4(keccak256(\"increaseAllowance(address,uint256)\"));\n bytes4 private constant ERC20_DECREASE_ALLOWANCE =\n bytes4(keccak256(\"decreaseAllowance(address,uint256)\"));\n bytes4 private constant ERC721_SET_APPROVAL_FOR_ALL =\n bytes4(keccak256(\"setApprovalForAll(address,bool)\"));\n bytes4 private constant ERC721_TRANSFER_FROM =\n bytes4(keccak256(\"transferFrom(address,address,uint256)\"));\n bytes4 private constant ERC721_SAFE_TRANSFER_FROM =\n bytes4(keccak256(\"safeTransferFrom(address,address,uint256)\"));\n bytes4 private constant ERC721_SAFE_TRANSFER_FROM_BYTES =\n bytes4(keccak256(\"safeTransferFrom(address,address,uint256,bytes)\"));\n bytes4 private constant ERC1155_SAFE_TRANSFER_FROM =\n bytes4(\n keccak256(\"safeTransferFrom(address,address,uint256,uint256,bytes)\")\n );\n bytes4 private constant ERC1155_SAFE_BATCH_TRANSFER_FROM =\n bytes4(\n keccak256(\n \"safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)\"\n )\n );\n\n /**\n * @notice Helper method to recover the spender from a contract call.\n * The method returns the contract unless the call is to a standard method of a ERC20/ERC721/ERC1155 token\n * in which case the spender is recovered from the data.\n * @param _to The target contract.\n * @param _data The data payload.\n */\n function _recover(\n address _to,\n bytes memory _data\n ) internal pure returns (address spender) {\n if (_data.length >= 68) {\n bytes4 methodId;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n methodId := mload(add(_data, 0x20))\n }\n if (\n methodId == ERC20_TRANSFER ||\n methodId == ERC20_APPROVE ||\n methodId == ERC20_INCREASE_ALLOWANCE ||\n methodId == ERC20_DECREASE_ALLOWANCE ||\n methodId == ERC721_SET_APPROVAL_FOR_ALL\n ) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n spender := mload(add(_data, 0x24))\n }\n return spender;\n }\n if (\n methodId == ERC721_TRANSFER_FROM ||\n methodId == ERC721_SAFE_TRANSFER_FROM ||\n methodId == ERC721_SAFE_TRANSFER_FROM_BYTES ||\n methodId == ERC1155_SAFE_TRANSFER_FROM ||\n methodId == ERC1155_SAFE_BATCH_TRANSFER_FROM\n ) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n spender := mload(add(_data, 0x44))\n }\n return spender;\n }\n }\n\n spender = _to;\n }\n}\n" + }, + "contracts/libraries/LibUtils.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\n\nlibrary LibUtils {\n // Internal utility functions\n function mergeArrays(\n bytes4[] memory _array1,\n bytes4[] memory _array2\n ) internal pure returns (bytes4[] memory) {\n uint256 length1 = _array1.length;\n uint256 length2 = _array2.length;\n bytes4[] memory mergedArray = new bytes4[](length1 + length2);\n\n for (uint256 i; i < length1; ) {\n mergedArray[i] = _array1[i];\n unchecked {\n ++i;\n }\n }\n\n for (uint256 i; i < length2; ) {\n mergedArray[length1 + i] = _array2[i];\n unchecked {\n ++i;\n }\n }\n\n return mergedArray;\n }\n\n function removeFacetElement(\n IDiamondLoupe.Facet[] memory _facets,\n uint256 _index\n ) internal pure returns (IDiamondLoupe.Facet[] memory) {\n require(_index < _facets.length, \"Invalid index\");\n require(_facets.length != 0, \"Invalid array\");\n\n // Create a new array with a length of `_facets.length - 1`\n IDiamondLoupe.Facet[] memory newArray = new IDiamondLoupe.Facet[](\n _facets.length - 1\n );\n uint256 newArrayLength = newArray.length;\n // Iterate over the original array, skipping the element at the specified `index`\n for (uint256 i; i < newArrayLength; ) {\n if (i < _index) {\n newArray[i] = _facets[i];\n } else {\n newArray[i] = _facets[i + 1];\n }\n unchecked {\n ++i;\n }\n }\n\n return newArray;\n }\n\n function removeElement(\n bytes4[] memory _array,\n uint256 _index\n ) internal pure returns (bytes4[] memory) {\n require(_index < _array.length, \"Invalid index\");\n require(_array.length != 0, \"Invalid array\");\n\n bytes4[] memory newArray = new bytes4[](_array.length - 1);\n uint256 newArrayLength = newArray.length;\n for (uint256 i; i < newArrayLength; ) {\n if (i < _index) {\n newArray[i] = _array[i];\n } else {\n newArray[i] = _array[i + 1];\n }\n unchecked {\n ++i;\n }\n }\n\n return newArray;\n }\n\n function setValue(\n bytes4[] memory _keys,\n address[] memory _values,\n bytes4 _key,\n address _value\n ) internal pure returns (bytes4[] memory, address[] memory) {\n uint256 index = findIndex(_keys, _key);\n uint256 keysLength = _keys.length;\n if (index < keysLength) {\n _values[index] = _value;\n } else {\n // Create new storage arrays\n bytes4[] memory newKeys = new bytes4[](keysLength + 1);\n address[] memory newValues = new address[](_values.length + 1);\n\n // Copy values to the new storage arrays\n for (uint256 i; i < keysLength; ) {\n newKeys[i] = _keys[i];\n newValues[i] = _values[i];\n\n unchecked {\n ++i;\n }\n }\n\n // Add the new key-value pair\n newKeys[keysLength] = _key;\n newValues[_values.length] = _value;\n\n return (newKeys, newValues);\n }\n\n // If the key already exists, return the original arrays\n return (_keys, _values);\n }\n\n function getValue(\n bytes4[] memory _keys,\n address[] memory _values,\n bytes4 _key\n ) internal pure returns (address) {\n uint256 index = findIndex(_keys, _key);\n if (index >= _keys.length) return address(0);\n\n return _values[index];\n }\n\n function findIndex(\n bytes4[] memory _keys,\n bytes4 _key\n ) internal pure returns (uint256) {\n uint256 keysLength = _keys.length;\n for (uint256 i; i < keysLength; ) {\n if (_keys[i] == _key) {\n return i;\n }\n unchecked {\n ++i;\n }\n }\n return keysLength;\n }\n}\n" + }, + "contracts/restrictions/IRestriction.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Interface for restrictions\n * @dev Restriction is a contract which decides whether to approve a certain kind of transaction, based on its internal logic.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface IRestriction {\n /**\n * @dev Based on restriction's internal logic, it should accept or reject a certain transaction.\n * @param from The address of the sender, that will be signing the transaction.\n * @param to The receiving address.\n * @param value Amount of ETH to transfer from sender to recipient.\n * @param _calldata Optional field to include arbitrary data.\n * @return bool value for whether the check is passed\n */\n function check(\n address from,\n address to,\n uint256 value,\n bytes calldata _calldata\n ) external returns (bool);\n}\n" + }, + "contracts/restrictions/WhitelistRestriction.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibRecoverSpender} from \"../libraries/LibRecoverSpender.sol\";\nimport {WhitelistStorage} from \"../infrastructure/WhitelistStorage.sol\";\nimport {IRestriction} from \"./IRestriction.sol\";\n\n/**\n * @title Whitelist Restriction\n * @dev This restriction defines a list of accepted addresses and denies any interaction with addresses outside of it.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract WhitelistRestriction is IRestriction {\n WhitelistStorage public immutable whitelistStorage;\n\n constructor(WhitelistStorage _whitelistStorage) {\n whitelistStorage = _whitelistStorage;\n }\n\n /**\n * @notice Helper method to recover the spender from a contract call.\n * The method returns the contract unless the call is to a standard method of a ERC20/ERC721/ERC1155 token\n * in which case the spender is recovered from the data.\n * @param _to The target contract.\n * @param _data The data payload.\n */\n function recoverSpender(\n address _to,\n bytes memory _data\n ) public pure returns (address spender) {\n return LibRecoverSpender._recover(_to, _data);\n }\n\n /*\n * @dev IRestriction's implementation. It will allow transaction if the sender is whitelisted, or user, or the whitelist storage.\n * @param _from The address of the sender, that will be signing the transaction.\n * @param _to The receiving address.\n * @param _calldata Optional field to include arbitrary data.\n * @return result value for whether the check is passed\n */\n function check(\n address _from,\n address _to,\n uint256 /*_value*/,\n bytes calldata _calldata\n ) external view override returns (bool result) {\n return\n whitelistStorage.isWhitelisted(\n _from,\n LibRecoverSpender._recover(_to, _calldata)\n ) ||\n _to == address(whitelistStorage) ||\n _to == msg.sender;\n }\n}\n" + }, + "contracts/test/Counter.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\ncontract TestCounter {\n int private count = 0;\n\n function incrementCounter() public {\n count += 1;\n }\n\n function decrementCounter() public {\n count -= 1;\n }\n\n function getCount() public view returns (int) {\n return count;\n }\n}\n" + }, + "contracts/test/TestERC1155.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC1155/ERC1155.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\n\ncontract TestERC1155 is ERC1155 {\n using Counters for Counters.Counter;\n\n Counters.Counter private _tokenIds;\n\n constructor() ERC1155(\"\") {}\n\n function mint(address account, uint256 amount) external {\n uint256 tokenId = _getNextTokenId();\n _mint(account, tokenId, amount, \"\");\n }\n\n function mintBatch(\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes memory data\n ) external {\n require(\n ids.length == amounts.length,\n \"TestERC1155: arrays length mismatch\"\n );\n\n _mintBatch(to, ids, amounts, data);\n }\n\n function _getNextTokenId() private returns (uint256) {\n _tokenIds.increment();\n return _tokenIds.current();\n }\n}\n" + }, + "contracts/test/TestERC777.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC777/ERC777.sol\";\n\ncontract TestERC777 is ERC777 {\n constructor(\n address[] memory _operators\n ) ERC777(\"TestERC777\", \"TERC777\", _operators) {}\n\n function mint(address account, uint256 amount) external {\n _mint(account, amount, \"\", \"\");\n }\n}\n" + }, + "contracts/test/TestInvalidSecp256k1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IVerificationFacet} from \"../facets/interfaces/IVerificationFacet.sol\";\nimport {IERC1271} from \"../interfaces/ERC/IERC1271.sol\";\nimport {AppStorage, LibAppStorage, BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {LibFacetStorage, Secp256k1VerificationStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {UserOperation} from \"../aa-4337/interfaces/UserOperation.sol\";\n\n/**\n * @title Test Secp256k1 verification facet\n * @dev Default Ethereum's elliptic curve\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract TestInvalidSecp256k1VerificationFacet is BarzStorage, IERC1271 {\n using ECDSA for bytes32;\n error Secp256k1VerificationFacet__InvalidSignerLength();\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n\n event SignerUninitialized();\n\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n }\n\n // THIS INVALID FACET DOES NOT INCLUDE initializeSigner()\n // THIS FACET IS USED TO TEST WHEN initializeSigner() DOESN'T EXIST IN FACET\n\n function uninitializeSigner() external returns (uint256 uninitSuccess) {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view returns (uint256 validationData) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n return validateSignature(userOp, userOpHash, k1Storage.signer);\n }\n\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n address signer\n ) public pure returns (uint256) {\n bytes32 hash = userOpHash.toEthSignedMessageHash();\n if (signer != hash.recover(userOp.signature)) return 1;\n return 0;\n }\n\n // This is REMOVED for testing purpose\n function validateOwnerSignatureSelector() public pure returns (bytes4) {\n // return this.validateOwnerSignature.selector;\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n function owner() public view returns (bytes memory) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n return abi.encodePacked(k1Storage.signer);\n }\n\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure returns (bool) {\n return (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (_hash.recover(_signature) ==\n LibFacetStorage.k1Storage().signer)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n}\n" + }, + "contracts/test/TestNFT.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\n\ncontract TestNFT is ERC721 {\n using Counters for Counters.Counter;\n Counters.Counter private currentTokenId;\n\n constructor() ERC721(\"TestNFT\", \"TNFT\") {}\n\n function mint(address recipient) public returns (uint256) {\n currentTokenId.increment();\n uint256 newItemId = currentTokenId.current();\n _safeMint(recipient, newItemId);\n return newItemId;\n }\n}\n" + }, + "contracts/test/TestToken.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract TestToken is ERC20 {\n constructor()\n // solhint-disable-next-line no-empty-blocks\n ERC20(\"TST\", \"TestToken\")\n {}\n\n function mint(address sender, uint256 amount) external {\n _mint(sender, amount);\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 999999 + }, + "evmVersion": "paris", + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/deployments/optimism/solcInputs/167a830377988095f5f829bf03425fb0.json b/deployments/optimism/solcInputs/167a830377988095f5f829bf03425fb0.json new file mode 100644 index 0000000..2833a16 --- /dev/null +++ b/deployments/optimism/solcInputs/167a830377988095f5f829bf03425fb0.json @@ -0,0 +1,354 @@ +{ + "language": "Solidity", + "sources": { + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby disabling any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable2Step.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./Ownable.sol\";\n\n/**\n * @dev Contract module which provides access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership} and {acceptOwnership}.\n *\n * This module is used through inheritance. It will make available all functions\n * from parent (Ownable).\n */\nabstract contract Ownable2Step is Ownable {\n address private _pendingOwner;\n\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Returns the address of the pending owner.\n */\n function pendingOwner() public view virtual returns (address) {\n return _pendingOwner;\n }\n\n /**\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual override onlyOwner {\n _pendingOwner = newOwner;\n emit OwnershipTransferStarted(owner(), newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual override {\n delete _pendingOwner;\n super._transferOwnership(newOwner);\n }\n\n /**\n * @dev The new owner accepts the ownership transfer.\n */\n function acceptOwnership() public virtual {\n address sender = _msgSender();\n require(pendingOwner() == sender, \"Ownable2Step: caller is not the new owner\");\n _transferOwnership(sender);\n }\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC1271.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC1271 standard signature validation method for\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\n *\n * _Available since v4.1._\n */\ninterface IERC1271 {\n /**\n * @dev Should return whether the signature provided is valid for the provided data\n * @param hash Hash of the data to be signed\n * @param signature Signature byte array associated with _data\n */\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\n}\n" + }, + "@openzeppelin/contracts/security/ReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor() {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n _nonReentrantBefore();\n _;\n _nonReentrantAfter();\n }\n\n function _nonReentrantBefore() private {\n // On the first call to nonReentrant, _status will be _NOT_ENTERED\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n }\n\n function _nonReentrantAfter() private {\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Returns true if the reentrancy guard is currently set to \"entered\", which indicates there is a\n * `nonReentrant` function in the call stack.\n */\n function _reentrancyGuardEntered() internal view returns (bool) {\n return _status == _ENTERED;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/ERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/ERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC1155.sol\";\nimport \"./IERC1155Receiver.sol\";\nimport \"./extensions/IERC1155MetadataURI.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of the basic standard multi-token.\n * See https://eips.ethereum.org/EIPS/eip-1155\n * Originally based on code by Enjin: https://github.com/enjin/erc-1155\n *\n * _Available since v3.1._\n */\ncontract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {\n using Address for address;\n\n // Mapping from token ID to account balances\n mapping(uint256 => mapping(address => uint256)) private _balances;\n\n // Mapping from account to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json\n string private _uri;\n\n /**\n * @dev See {_setURI}.\n */\n constructor(string memory uri_) {\n _setURI(uri_);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return\n interfaceId == type(IERC1155).interfaceId ||\n interfaceId == type(IERC1155MetadataURI).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC1155MetadataURI-uri}.\n *\n * This implementation returns the same URI for *all* token types. It relies\n * on the token type ID substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * Clients calling this function must replace the `\\{id\\}` substring with the\n * actual token type ID.\n */\n function uri(uint256) public view virtual override returns (string memory) {\n return _uri;\n }\n\n /**\n * @dev See {IERC1155-balanceOf}.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {\n require(account != address(0), \"ERC1155: address zero is not a valid owner\");\n return _balances[id][account];\n }\n\n /**\n * @dev See {IERC1155-balanceOfBatch}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] memory accounts,\n uint256[] memory ids\n ) public view virtual override returns (uint256[] memory) {\n require(accounts.length == ids.length, \"ERC1155: accounts and ids length mismatch\");\n\n uint256[] memory batchBalances = new uint256[](accounts.length);\n\n for (uint256 i = 0; i < accounts.length; ++i) {\n batchBalances[i] = balanceOf(accounts[i], ids[i]);\n }\n\n return batchBalances;\n }\n\n /**\n * @dev See {IERC1155-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC1155-isApprovedForAll}.\n */\n function isApprovedForAll(address account, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[account][operator];\n }\n\n /**\n * @dev See {IERC1155-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n _safeTransferFrom(from, to, id, amount, data);\n }\n\n /**\n * @dev See {IERC1155-safeBatchTransferFrom}.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n _safeBatchTransferFrom(from, to, ids, amounts, data);\n }\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n\n emit TransferSingle(operator, from, to, id, amount);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n for (uint256 i = 0; i < ids.length; ++i) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n }\n\n emit TransferBatch(operator, from, to, ids, amounts);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\n\n _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);\n }\n\n /**\n * @dev Sets a new URI for all token types, by relying on the token type ID\n * substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * By this mechanism, any occurrence of the `\\{id\\}` substring in either the\n * URI or any of the amounts in the JSON file at said URI will be replaced by\n * clients with the token type ID.\n *\n * For example, the `https://token-cdn-domain/\\{id\\}.json` URI would be\n * interpreted by clients as\n * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`\n * for token type ID 0x4cce0.\n *\n * See {uri}.\n *\n * Because these URIs cannot be meaningfully represented by the {URI} event,\n * this function emits no events.\n */\n function _setURI(string memory newuri) internal virtual {\n _uri = newuri;\n }\n\n /**\n * @dev Creates `amount` tokens of token type `id`, and assigns them to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _mint(address to, uint256 id, uint256 amount, bytes memory data) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _balances[id][to] += amount;\n emit TransferSingle(operator, address(0), to, id, amount);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n for (uint256 i = 0; i < ids.length; i++) {\n _balances[ids[i]][to] += amounts[i];\n }\n\n emit TransferBatch(operator, address(0), to, ids, amounts);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);\n }\n\n /**\n * @dev Destroys `amount` tokens of token type `id` from `from`\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `from` must have at least `amount` tokens of token type `id`.\n */\n function _burn(address from, uint256 id, uint256 amount) internal virtual {\n require(from != address(0), \"ERC1155: burn from the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n\n emit TransferSingle(operator, from, address(0), id, amount);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n */\n function _burnBatch(address from, uint256[] memory ids, uint256[] memory amounts) internal virtual {\n require(from != address(0), \"ERC1155: burn from the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n\n for (uint256 i = 0; i < ids.length; i++) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n }\n\n emit TransferBatch(operator, from, address(0), ids, amounts);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {\n require(owner != operator, \"ERC1155: setting approval status for self\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning, as well as batched variants.\n *\n * The same hook is called on both single and batched variants. For single\n * transfers, the length of the `ids` and `amounts` arrays will be 1.\n *\n * Calling conditions (for each `id` and `amount` pair):\n *\n * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * of token type `id` will be transferred to `to`.\n * - When `from` is zero, `amount` tokens of token type `id` will be minted\n * for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n * will be burned.\n * - `from` and `to` are never both zero.\n * - `ids` and `amounts` have the same, non-zero length.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any token transfer. This includes minting\n * and burning, as well as batched variants.\n *\n * The same hook is called on both single and batched variants. For single\n * transfers, the length of the `id` and `amount` arrays will be 1.\n *\n * Calling conditions (for each `id` and `amount` pair):\n *\n * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * of token type `id` will be transferred to `to`.\n * - When `from` is zero, `amount` tokens of token type `id` will be minted\n * for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n * will be burned.\n * - `from` and `to` are never both zero.\n * - `ids` and `amounts` have the same, non-zero length.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {}\n\n function _doSafeTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155Receiver.onERC1155Received.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non-ERC1155Receiver implementer\");\n }\n }\n }\n\n function _doSafeBatchTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (\n bytes4 response\n ) {\n if (response != IERC1155Receiver.onERC1155BatchReceived.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non-ERC1155Receiver implementer\");\n }\n }\n }\n\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {\n uint256[] memory array = new uint256[](1);\n array[0] = element;\n\n return array;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC1155.sol\";\n\n/**\n * @dev Interface of the optional ERC1155MetadataExtension interface, as defined\n * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155MetadataURI is IERC1155 {\n /**\n * @dev Returns the URI for token type `id`.\n *\n * If the `\\{id\\}` substring is present in the URI, it must be replaced by\n * clients with the actual token type ID.\n */\n function uri(uint256 id) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155 is IERC165 {\n /**\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n */\n event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);\n\n /**\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n * transfers.\n */\n event TransferBatch(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\n\n /**\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n * `approved`.\n */\n event ApprovalForAll(address indexed account, address indexed operator, bool approved);\n\n /**\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n *\n * If an {URI} event was emitted for `id`, the standard\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n * returned by {IERC1155MetadataURI-uri}.\n */\n event URI(string value, uint256 indexed id);\n\n /**\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) external view returns (uint256);\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] calldata accounts,\n uint256[] calldata ids\n ) external view returns (uint256[] memory);\n\n /**\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n *\n * Emits an {ApprovalForAll} event.\n *\n * Requirements:\n *\n * - `operator` cannot be the caller.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n *\n * See {setApprovalForAll}.\n */\n function isApprovedForAll(address account, address operator) external view returns (bool);\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155Receiver is IERC165 {\n /**\n * @dev Handles the receipt of a single ERC1155 token type. This function is\n * called at the end of a `safeTransferFrom` after the balance has been updated.\n *\n * NOTE: To accept the transfer, this must return\n * `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n * (i.e. 0xf23a6e61, or its own function selector).\n *\n * @param operator The address which initiated the transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param id The ID of the token being transferred\n * @param value The amount of tokens being transferred\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n ) external returns (bytes4);\n\n /**\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\n * is called at the end of a `safeBatchTransferFrom` after the balances have\n * been updated.\n *\n * NOTE: To accept the transfer(s), this must return\n * `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n * (i.e. 0xbc197c81, or its own function selector).\n *\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the default value returned by this function, unless\n * it's overridden.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(address from, address to, uint256 amount) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\n // decrementing then incrementing.\n _balances[to] += amount;\n }\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n unchecked {\n // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\n _balances[account] += amount;\n }\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n // Overflow not possible: amount <= accountBalance <= totalSupply.\n _totalSupply -= amount;\n }\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\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" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` 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 amount) 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 `amount` as the allowance of `spender` over the 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 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` 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 amount) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/ERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721.sol\";\nimport \"./IERC721Receiver.sol\";\nimport \"./extensions/IERC721Metadata.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/Strings.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\n using Address for address;\n using Strings for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\n\n // Mapping from token ID to approved address\n mapping(uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return\n interfaceId == type(IERC721).interfaceId ||\n interfaceId == type(IERC721Metadata).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _ownerOf(tokenId);\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token owner or approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n _requireMinted(tokenId);\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n _safeTransfer(from, to, tokenId, data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(address from, address to, uint256 tokenId, bytes memory data) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist\n */\n function _ownerOf(uint256 tokenId) internal view virtual returns (address) {\n return _owners[tokenId];\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _ownerOf(tokenId) != address(0);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n address owner = ERC721.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(address to, uint256 tokenId, bytes memory data) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId, 1);\n\n // Check that tokenId was not minted by `_beforeTokenTransfer` hook\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n unchecked {\n // Will not overflow unless all 2**256 token ids are minted to the same owner.\n // Given that tokens are minted one by one, it is impossible in practice that\n // this ever happens. Might change if we allow batch minting.\n // The ERC fails to describe this case.\n _balances[to] += 1;\n }\n\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(address(0), to, tokenId, 1);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n * This is an internal function that does not check if the sender is authorized to operate on the token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId, 1);\n\n // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook\n owner = ERC721.ownerOf(tokenId);\n\n // Clear approvals\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // Cannot overflow, as that would require more tokens to be burned/transferred\n // out than the owner initially received through minting and transferring in.\n _balances[owner] -= 1;\n }\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(owner, address(0), tokenId, 1);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(address from, address to, uint256 tokenId) internal virtual {\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId, 1);\n\n // Check that tokenId was not transferred by `_beforeTokenTransfer` hook\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n\n // Clear approvals from the previous owner\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // `_balances[from]` cannot overflow for the same reason as described in `_burn`:\n // `from`'s balance is the number of token held, which is at least one before the current\n // transfer.\n // `_balances[to]` could overflow in the conditions described in `_mint`. That would require\n // all 2**256 token ids to be minted, which in practice is impossible.\n _balances[from] -= 1;\n _balances[to] += 1;\n }\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId, 1);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721Receiver.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`.\n * - When `from` is zero, the tokens will be minted for `to`.\n * - When `to` is zero, ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}\n\n /**\n * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`.\n * - When `from` is zero, the tokens were minted for `to`.\n * - When `to` is zero, ``from``'s tokens were burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}\n\n /**\n * @dev Unsafe write access to the balances, used by extensions that \"mint\" tokens using an {ownerOf} override.\n *\n * WARNING: Anyone calling this MUST ensure that the balances remain consistent with the ownership. The invariant\n * being that for any address `a` the value returned by `balanceOf(a)` must be equal to the number of tokens such\n * that `ownerOf(tokenId)` is `a`.\n */\n // solhint-disable-next-line func-name-mixedcase\n function __unsafe_increaseBalance(address account, uint256 amount) internal {\n _balances[account] += amount;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721Receiver {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/ERC777.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC777/ERC777.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC777.sol\";\nimport \"./IERC777Recipient.sol\";\nimport \"./IERC777Sender.sol\";\nimport \"../ERC20/IERC20.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/introspection/IERC1820Registry.sol\";\n\n/**\n * @dev Implementation of the {IERC777} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n *\n * Support for ERC20 is included in this contract, as specified by the EIP: both\n * the ERC777 and ERC20 interfaces can be safely used when interacting with it.\n * Both {IERC777-Sent} and {IERC20-Transfer} events are emitted on token\n * movements.\n *\n * Additionally, the {IERC777-granularity} value is hard-coded to `1`, meaning that there\n * are no special restrictions in the amount of tokens that created, moved, or\n * destroyed. This makes integration with ERC20 applications seamless.\n *\n * CAUTION: This file is deprecated as of v4.9 and will be removed in the next major release.\n */\ncontract ERC777 is Context, IERC777, IERC20 {\n using Address for address;\n\n IERC1820Registry internal constant _ERC1820_REGISTRY = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n mapping(address => uint256) private _balances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n bytes32 private constant _TOKENS_SENDER_INTERFACE_HASH = keccak256(\"ERC777TokensSender\");\n bytes32 private constant _TOKENS_RECIPIENT_INTERFACE_HASH = keccak256(\"ERC777TokensRecipient\");\n\n // This isn't ever read from - it's only used to respond to the defaultOperators query.\n address[] private _defaultOperatorsArray;\n\n // Immutable, but accounts may revoke them (tracked in __revokedDefaultOperators).\n mapping(address => bool) private _defaultOperators;\n\n // For each account, a mapping of its operators and revoked default operators.\n mapping(address => mapping(address => bool)) private _operators;\n mapping(address => mapping(address => bool)) private _revokedDefaultOperators;\n\n // ERC20-allowances\n mapping(address => mapping(address => uint256)) private _allowances;\n\n /**\n * @dev `defaultOperators` may be an empty array.\n */\n constructor(string memory name_, string memory symbol_, address[] memory defaultOperators_) {\n _name = name_;\n _symbol = symbol_;\n\n _defaultOperatorsArray = defaultOperators_;\n for (uint256 i = 0; i < defaultOperators_.length; i++) {\n _defaultOperators[defaultOperators_[i]] = true;\n }\n\n // register interfaces\n _ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256(\"ERC777Token\"), address(this));\n _ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256(\"ERC20Token\"), address(this));\n }\n\n /**\n * @dev See {IERC777-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC777-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {ERC20-decimals}.\n *\n * Always returns 18, as per the\n * [ERC777 EIP](https://eips.ethereum.org/EIPS/eip-777#backward-compatibility).\n */\n function decimals() public pure virtual returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC777-granularity}.\n *\n * This implementation always returns `1`.\n */\n function granularity() public view virtual override returns (uint256) {\n return 1;\n }\n\n /**\n * @dev See {IERC777-totalSupply}.\n */\n function totalSupply() public view virtual override(IERC20, IERC777) returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev Returns the amount of tokens owned by an account (`tokenHolder`).\n */\n function balanceOf(address tokenHolder) public view virtual override(IERC20, IERC777) returns (uint256) {\n return _balances[tokenHolder];\n }\n\n /**\n * @dev See {IERC777-send}.\n *\n * Also emits a {IERC20-Transfer} event for ERC20 compatibility.\n */\n function send(address recipient, uint256 amount, bytes memory data) public virtual override {\n _send(_msgSender(), recipient, amount, data, \"\", true);\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Unlike `send`, `recipient` is _not_ required to implement the {IERC777Recipient}\n * interface if it is a contract.\n *\n * Also emits a {Sent} event.\n */\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n _send(_msgSender(), recipient, amount, \"\", \"\", false);\n return true;\n }\n\n /**\n * @dev See {IERC777-burn}.\n *\n * Also emits a {IERC20-Transfer} event for ERC20 compatibility.\n */\n function burn(uint256 amount, bytes memory data) public virtual override {\n _burn(_msgSender(), amount, data, \"\");\n }\n\n /**\n * @dev See {IERC777-isOperatorFor}.\n */\n function isOperatorFor(address operator, address tokenHolder) public view virtual override returns (bool) {\n return\n operator == tokenHolder ||\n (_defaultOperators[operator] && !_revokedDefaultOperators[tokenHolder][operator]) ||\n _operators[tokenHolder][operator];\n }\n\n /**\n * @dev See {IERC777-authorizeOperator}.\n */\n function authorizeOperator(address operator) public virtual override {\n require(_msgSender() != operator, \"ERC777: authorizing self as operator\");\n\n if (_defaultOperators[operator]) {\n delete _revokedDefaultOperators[_msgSender()][operator];\n } else {\n _operators[_msgSender()][operator] = true;\n }\n\n emit AuthorizedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-revokeOperator}.\n */\n function revokeOperator(address operator) public virtual override {\n require(operator != _msgSender(), \"ERC777: revoking self as operator\");\n\n if (_defaultOperators[operator]) {\n _revokedDefaultOperators[_msgSender()][operator] = true;\n } else {\n delete _operators[_msgSender()][operator];\n }\n\n emit RevokedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-defaultOperators}.\n */\n function defaultOperators() public view virtual override returns (address[] memory) {\n return _defaultOperatorsArray;\n }\n\n /**\n * @dev See {IERC777-operatorSend}.\n *\n * Emits {Sent} and {IERC20-Transfer} events.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes memory data,\n bytes memory operatorData\n ) public virtual override {\n require(isOperatorFor(_msgSender(), sender), \"ERC777: caller is not an operator for holder\");\n _send(sender, recipient, amount, data, operatorData, true);\n }\n\n /**\n * @dev See {IERC777-operatorBurn}.\n *\n * Emits {Burned} and {IERC20-Transfer} events.\n */\n function operatorBurn(\n address account,\n uint256 amount,\n bytes memory data,\n bytes memory operatorData\n ) public virtual override {\n require(isOperatorFor(_msgSender(), account), \"ERC777: caller is not an operator for holder\");\n _burn(account, amount, data, operatorData);\n }\n\n /**\n * @dev See {IERC20-allowance}.\n *\n * Note that operator and allowance concepts are orthogonal: operators may\n * not have allowance, and accounts with allowance may not be operators\n * themselves.\n */\n function allowance(address holder, address spender) public view virtual override returns (uint256) {\n return _allowances[holder][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Note that accounts cannot have allowance issued by their operators.\n */\n function approve(address spender, uint256 value) public virtual override returns (bool) {\n address holder = _msgSender();\n _approve(holder, spender, value);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Note that operator and allowance concepts are orthogonal: operators cannot\n * call `transferFrom` (unless they have allowance), and accounts with\n * allowance cannot call `operatorSend` (unless they are operators).\n *\n * Emits {Sent}, {IERC20-Transfer} and {IERC20-Approval} events.\n */\n function transferFrom(address holder, address recipient, uint256 amount) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(holder, spender, amount);\n _send(holder, recipient, amount, \"\", \"\", false);\n return true;\n }\n\n /**\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with the caller address as the `operator` and with\n * `userData` and `operatorData`.\n *\n * See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits {Minted} and {IERC20-Transfer} events.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - if `account` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function _mint(address account, uint256 amount, bytes memory userData, bytes memory operatorData) internal virtual {\n _mint(account, amount, userData, operatorData, true);\n }\n\n /**\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * If `requireReceptionAck` is set to true, and if a send hook is\n * registered for `account`, the corresponding function will be called with\n * `operator`, `data` and `operatorData`.\n *\n * See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits {Minted} and {IERC20-Transfer} events.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - if `account` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function _mint(\n address account,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) internal virtual {\n require(account != address(0), \"ERC777: mint to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), account, amount);\n\n // Update state variables\n _totalSupply += amount;\n _balances[account] += amount;\n\n _callTokensReceived(operator, address(0), account, amount, userData, operatorData, requireReceptionAck);\n\n emit Minted(operator, account, amount, userData, operatorData);\n emit Transfer(address(0), account, amount);\n }\n\n /**\n * @dev Send tokens\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _send(\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) internal virtual {\n require(from != address(0), \"ERC777: transfer from the zero address\");\n require(to != address(0), \"ERC777: transfer to the zero address\");\n\n address operator = _msgSender();\n\n _callTokensToSend(operator, from, to, amount, userData, operatorData);\n\n _move(operator, from, to, amount, userData, operatorData);\n\n _callTokensReceived(operator, from, to, amount, userData, operatorData, requireReceptionAck);\n }\n\n /**\n * @dev Burn tokens\n * @param from address token holder address\n * @param amount uint256 amount of tokens to burn\n * @param data bytes extra information provided by the token holder\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _burn(address from, uint256 amount, bytes memory data, bytes memory operatorData) internal virtual {\n require(from != address(0), \"ERC777: burn from the zero address\");\n\n address operator = _msgSender();\n\n _callTokensToSend(operator, from, address(0), amount, data, operatorData);\n\n _beforeTokenTransfer(operator, from, address(0), amount);\n\n // Update state variables\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC777: burn amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Burned(operator, from, amount, data, operatorData);\n emit Transfer(from, address(0), amount);\n }\n\n function _move(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n ) private {\n _beforeTokenTransfer(operator, from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC777: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Sent(operator, from, to, amount, userData, operatorData);\n emit Transfer(from, to, amount);\n }\n\n /**\n * @dev See {ERC20-_approve}.\n *\n * Note that accounts cannot have allowance issued by their operators.\n */\n function _approve(address holder, address spender, uint256 value) internal virtual {\n require(holder != address(0), \"ERC777: approve from the zero address\");\n require(spender != address(0), \"ERC777: approve to the zero address\");\n\n _allowances[holder][spender] = value;\n emit Approval(holder, spender, value);\n }\n\n /**\n * @dev Call from.tokensToSend() if the interface is registered\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _callTokensToSend(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n ) private {\n address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(from, _TOKENS_SENDER_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Sender(implementer).tokensToSend(operator, from, to, amount, userData, operatorData);\n }\n }\n\n /**\n * @dev Call to.tokensReceived() if the interface is registered. Reverts if the recipient is a contract but\n * tokensReceived() was not registered for the recipient\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _callTokensReceived(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) private {\n address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(to, _TOKENS_RECIPIENT_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Recipient(implementer).tokensReceived(operator, from, to, amount, userData, operatorData);\n } else if (requireReceptionAck) {\n require(!to.isContract(), \"ERC777: token recipient contract has no implementer for ERC777TokensRecipient\");\n }\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {IERC20-Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC777: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes\n * calls to {send}, {transfer}, {operatorSend}, {transferFrom}, minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be to transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address operator, address from, address to, uint256 amount) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC777/IERC777.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777Token standard as defined in the EIP.\n *\n * This contract uses the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 registry standard] to let\n * token holders and recipients react to token movements by using setting implementers\n * for the associated interfaces in said registry. See {IERC1820Registry} and\n * {ERC1820Implementer}.\n */\ninterface IERC777 {\n /**\n * @dev Emitted when `amount` tokens are created by `operator` and assigned to `to`.\n *\n * Note that some additional user `data` and `operatorData` can be logged in the event.\n */\n event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);\n\n /**\n * @dev Emitted when `operator` destroys `amount` tokens from `account`.\n *\n * Note that some additional user `data` and `operatorData` can be logged in the event.\n */\n event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);\n\n /**\n * @dev Emitted when `operator` is made operator for `tokenHolder`.\n */\n event AuthorizedOperator(address indexed operator, address indexed tokenHolder);\n\n /**\n * @dev Emitted when `operator` is revoked its operator status for `tokenHolder`.\n */\n event RevokedOperator(address indexed operator, address indexed tokenHolder);\n\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, usually a shorter version of the\n * name.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the smallest part of the token that is not divisible. This\n * means all token operations (creation, movement and destruction) must have\n * amounts that are a multiple of this number.\n *\n * For most token contracts, this value will equal 1.\n */\n function granularity() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by an account (`owner`).\n */\n function balanceOf(address owner) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * If send or receive hooks are registered for the caller and `recipient`,\n * the corresponding functions will be called with `data` and empty\n * `operatorData`. See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits a {Sent} event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function send(address recipient, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Destroys `amount` tokens from the caller's account, reducing the\n * total supply.\n *\n * If a send hook is registered for the caller, the corresponding function\n * will be called with `data` and empty `operatorData`. See {IERC777Sender}.\n *\n * Emits a {Burned} event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n */\n function burn(uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Returns true if an account is an operator of `tokenHolder`.\n * Operators can send and burn tokens on behalf of their owners. All\n * accounts are their own operator.\n *\n * See {operatorSend} and {operatorBurn}.\n */\n function isOperatorFor(address operator, address tokenHolder) external view returns (bool);\n\n /**\n * @dev Make an account an operator of the caller.\n *\n * See {isOperatorFor}.\n *\n * Emits an {AuthorizedOperator} event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function authorizeOperator(address operator) external;\n\n /**\n * @dev Revoke an account's operator status for the caller.\n *\n * See {isOperatorFor} and {defaultOperators}.\n *\n * Emits a {RevokedOperator} event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function revokeOperator(address operator) external;\n\n /**\n * @dev Returns the list of default operators. These accounts are operators\n * for all token holders, even if {authorizeOperator} was never called on\n * them.\n *\n * This list is immutable, but individual holders may revoke these via\n * {revokeOperator}, in which case {isOperatorFor} will return false.\n */\n function defaultOperators() external view returns (address[] memory);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must\n * be an operator of `sender`.\n *\n * If send or receive hooks are registered for `sender` and `recipient`,\n * the corresponding functions will be called with `data` and\n * `operatorData`. See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits a {Sent} event.\n *\n * Requirements\n *\n * - `sender` cannot be the zero address.\n * - `sender` must have at least `amount` tokens.\n * - the caller must be an operator for `sender`.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes calldata data,\n bytes calldata operatorData\n ) external;\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the total supply.\n * The caller must be an operator of `account`.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with `data` and `operatorData`. See {IERC777Sender}.\n *\n * Emits a {Burned} event.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n * - the caller must be an operator for `account`.\n */\n function operatorBurn(address account, uint256 amount, bytes calldata data, bytes calldata operatorData) external;\n\n event Sent(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes data,\n bytes operatorData\n );\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\n *\n * Accounts can be notified of {IERC777} tokens being sent to them by having a\n * contract implement this interface (contract holders can be their own\n * implementer) and registering it on the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\n *\n * See {IERC1820Registry} and {ERC1820Implementer}.\n */\ninterface IERC777Recipient {\n /**\n * @dev Called by an {IERC777} token contract whenever tokens are being\n * moved or created into a registered account (`to`). The type of operation\n * is conveyed by `from` being the zero address or not.\n *\n * This call occurs _after_ the token contract's state is updated, so\n * {IERC777-balanceOf}, etc., can be used to query the post-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensReceived(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777Sender.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Sender.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777TokensSender standard as defined in the EIP.\n *\n * {IERC777} Token holders can be notified of operations performed on their\n * tokens by having a contract implement this interface (contract holders can be\n * their own implementer) and registering it on the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\n *\n * See {IERC1820Registry} and {ERC1820Implementer}.\n */\ninterface IERC777Sender {\n /**\n * @dev Called by an {IERC777} token contract whenever a registered holder's\n * (`from`) tokens are about to be moved or destroyed. The type of operation\n * is conveyed by `to` being the zero address or not.\n *\n * This call occurs _before_ the token contract's state is updated, so\n * {IERC777-balanceOf}, etc., can be used to query the pre-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensToSend(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n *\n * Furthermore, `isContract` will also return true if the target contract within\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n * which only has an effect at the end of a transaction.\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Counters.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary Counters {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/ECDSA.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Strings.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV // Deprecated in v4.8\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n /// @solidity memory-safe-assembly\n assembly {\n mstore(0x00, \"\\x19Ethereum Signed Message:\\n32\")\n mstore(0x1c, hash)\n message := keccak256(0x00, 0x3c)\n }\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\n /// @solidity memory-safe-assembly\n assembly {\n let ptr := mload(0x40)\n mstore(ptr, \"\\x19\\x01\")\n mstore(add(ptr, 0x02), domainSeparator)\n mstore(add(ptr, 0x22), structHash)\n data := keccak256(ptr, 0x42)\n }\n }\n\n /**\n * @dev Returns an Ethereum Signed Data with intended validator, created from a\n * `validator` and `data` according to the version 0 of EIP-191.\n *\n * See {recover}.\n */\n function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x00\", validator, data));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/SignatureChecker.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSA.sol\";\nimport \"../../interfaces/IERC1271.sol\";\n\n/**\n * @dev Signature verification helper that can be used instead of `ECDSA.recover` to seamlessly support both ECDSA\n * signatures from externally owned accounts (EOAs) as well as ERC1271 signatures from smart contract wallets like\n * Argent and Gnosis Safe.\n *\n * _Available since v4.1._\n */\nlibrary SignatureChecker {\n /**\n * @dev Checks if a signature is valid for a given signer and data hash. If the signer is a smart contract, the\n * signature is validated against that smart contract using ERC1271, otherwise it's validated using `ECDSA.recover`.\n *\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\n */\n function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature) internal view returns (bool) {\n (address recovered, ECDSA.RecoverError error) = ECDSA.tryRecover(hash, signature);\n return\n (error == ECDSA.RecoverError.NoError && recovered == signer) ||\n isValidERC1271SignatureNow(signer, hash, signature);\n }\n\n /**\n * @dev Checks if a signature is valid for a given signer and data hash. The signature is validated\n * against the signer smart contract using ERC1271.\n *\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\n */\n function isValidERC1271SignatureNow(\n address signer,\n bytes32 hash,\n bytes memory signature\n ) internal view returns (bool) {\n (bool success, bytes memory result) = signer.staticcall(\n abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, signature)\n );\n return (success &&\n result.length >= 32 &&\n abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/ERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165 is IERC165 {\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165).interfaceId;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC1820Registry.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/introspection/IERC1820Registry.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the global ERC1820 Registry, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register\n * implementers for interfaces in this registry, as well as query support.\n *\n * Implementers may be shared by multiple accounts, and can also implement more\n * than a single interface for each account. Contracts can implement interfaces\n * for themselves, but externally-owned accounts (EOA) must delegate this to a\n * contract.\n *\n * {IERC165} interfaces can also be queried via the registry.\n *\n * For an in-depth explanation and source code analysis, see the EIP text.\n */\ninterface IERC1820Registry {\n event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer);\n\n event ManagerChanged(address indexed account, address indexed newManager);\n\n /**\n * @dev Sets `newManager` as the manager for `account`. A manager of an\n * account is able to set interface implementers for it.\n *\n * By default, each account is its own manager. Passing a value of `0x0` in\n * `newManager` will reset the manager to this initial state.\n *\n * Emits a {ManagerChanged} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `account`.\n */\n function setManager(address account, address newManager) external;\n\n /**\n * @dev Returns the manager for `account`.\n *\n * See {setManager}.\n */\n function getManager(address account) external view returns (address);\n\n /**\n * @dev Sets the `implementer` contract as ``account``'s implementer for\n * `interfaceHash`.\n *\n * `account` being the zero address is an alias for the caller's address.\n * The zero address can also be used in `implementer` to remove an old one.\n *\n * See {interfaceHash} to learn how these are created.\n *\n * Emits an {InterfaceImplementerSet} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `account`.\n * - `interfaceHash` must not be an {IERC165} interface id (i.e. it must not\n * end in 28 zeroes).\n * - `implementer` must implement {IERC1820Implementer} and return true when\n * queried for support, unless `implementer` is the caller. See\n * {IERC1820Implementer-canImplementInterfaceForAddress}.\n */\n function setInterfaceImplementer(address account, bytes32 _interfaceHash, address implementer) external;\n\n /**\n * @dev Returns the implementer of `interfaceHash` for `account`. If no such\n * implementer is registered, returns the zero address.\n *\n * If `interfaceHash` is an {IERC165} interface id (i.e. it ends with 28\n * zeroes), `account` will be queried for support of it.\n *\n * `account` being the zero address is an alias for the caller's address.\n */\n function getInterfaceImplementer(address account, bytes32 _interfaceHash) external view returns (address);\n\n /**\n * @dev Returns the interface hash for an `interfaceName`, as defined in the\n * corresponding\n * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP].\n */\n function interfaceHash(string calldata interfaceName) external pure returns (bytes32);\n\n /**\n * @notice Updates the cache with whether the contract implements an ERC165 interface or not.\n * @param account Address of the contract for which to update the cache.\n * @param interfaceId ERC165 interface for which to update the cache.\n */\n function updateERC165Cache(address account, bytes4 interfaceId) external;\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not.\n * If the result is not cached a direct lookup on the contract address is performed.\n * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling\n * {updateERC165Cache} with the contract address.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool);\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not without using or updating the cache.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/math/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\n // The surrounding unchecked block does not change this fact.\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1, \"Math: mulDiv overflow\");\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n //\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n //\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n //\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1 << (log2(a) >> 1);\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = sqrt(a);\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 2, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 128;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 64;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 32;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 16;\n }\n if (value >> 8 > 0) {\n value >>= 8;\n result += 8;\n }\n if (value >> 4 > 0) {\n value >>= 4;\n result += 4;\n }\n if (value >> 2 > 0) {\n value >>= 2;\n result += 2;\n }\n if (value >> 1 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log2(value);\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 10, rounded down, of a positive value.\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 + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 256, rounded down, of a positive value.\n * Returns 0 if given 0.\n *\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n */\n function log256(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 16;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 8;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 4;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 2;\n }\n if (value >> 8 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log256(value);\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/SafeCast.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCast {\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 * _Available since v4.7._\n */\n function toUint248(uint256 value) internal pure returns (uint248) {\n require(value <= type(uint248).max, \"SafeCast: value doesn't fit in 248 bits\");\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 * _Available since v4.7._\n */\n function toUint240(uint256 value) internal pure returns (uint240) {\n require(value <= type(uint240).max, \"SafeCast: value doesn't fit in 240 bits\");\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 * _Available since v4.7._\n */\n function toUint232(uint256 value) internal pure returns (uint232) {\n require(value <= type(uint232).max, \"SafeCast: value doesn't fit in 232 bits\");\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 * _Available since v4.2._\n */\n function toUint224(uint256 value) internal pure returns (uint224) {\n require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\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 * _Available since v4.7._\n */\n function toUint216(uint256 value) internal pure returns (uint216) {\n require(value <= type(uint216).max, \"SafeCast: value doesn't fit in 216 bits\");\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 * _Available since v4.7._\n */\n function toUint208(uint256 value) internal pure returns (uint208) {\n require(value <= type(uint208).max, \"SafeCast: value doesn't fit in 208 bits\");\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 * _Available since v4.7._\n */\n function toUint200(uint256 value) internal pure returns (uint200) {\n require(value <= type(uint200).max, \"SafeCast: value doesn't fit in 200 bits\");\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 * _Available since v4.7._\n */\n function toUint192(uint256 value) internal pure returns (uint192) {\n require(value <= type(uint192).max, \"SafeCast: value doesn't fit in 192 bits\");\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 * _Available since v4.7._\n */\n function toUint184(uint256 value) internal pure returns (uint184) {\n require(value <= type(uint184).max, \"SafeCast: value doesn't fit in 184 bits\");\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 * _Available since v4.7._\n */\n function toUint176(uint256 value) internal pure returns (uint176) {\n require(value <= type(uint176).max, \"SafeCast: value doesn't fit in 176 bits\");\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 * _Available since v4.7._\n */\n function toUint168(uint256 value) internal pure returns (uint168) {\n require(value <= type(uint168).max, \"SafeCast: value doesn't fit in 168 bits\");\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 * _Available since v4.7._\n */\n function toUint160(uint256 value) internal pure returns (uint160) {\n require(value <= type(uint160).max, \"SafeCast: value doesn't fit in 160 bits\");\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 * _Available since v4.7._\n */\n function toUint152(uint256 value) internal pure returns (uint152) {\n require(value <= type(uint152).max, \"SafeCast: value doesn't fit in 152 bits\");\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 * _Available since v4.7._\n */\n function toUint144(uint256 value) internal pure returns (uint144) {\n require(value <= type(uint144).max, \"SafeCast: value doesn't fit in 144 bits\");\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 * _Available since v4.7._\n */\n function toUint136(uint256 value) internal pure returns (uint136) {\n require(value <= type(uint136).max, \"SafeCast: value doesn't fit in 136 bits\");\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 * _Available since v2.5._\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\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 * _Available since v4.7._\n */\n function toUint120(uint256 value) internal pure returns (uint120) {\n require(value <= type(uint120).max, \"SafeCast: value doesn't fit in 120 bits\");\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 * _Available since v4.7._\n */\n function toUint112(uint256 value) internal pure returns (uint112) {\n require(value <= type(uint112).max, \"SafeCast: value doesn't fit in 112 bits\");\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 * _Available since v4.7._\n */\n function toUint104(uint256 value) internal pure returns (uint104) {\n require(value <= type(uint104).max, \"SafeCast: value doesn't fit in 104 bits\");\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 * _Available since v4.2._\n */\n function toUint96(uint256 value) internal pure returns (uint96) {\n require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\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 * _Available since v4.7._\n */\n function toUint88(uint256 value) internal pure returns (uint88) {\n require(value <= type(uint88).max, \"SafeCast: value doesn't fit in 88 bits\");\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 * _Available since v4.7._\n */\n function toUint80(uint256 value) internal pure returns (uint80) {\n require(value <= type(uint80).max, \"SafeCast: value doesn't fit in 80 bits\");\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 * _Available since v4.7._\n */\n function toUint72(uint256 value) internal pure returns (uint72) {\n require(value <= type(uint72).max, \"SafeCast: value doesn't fit in 72 bits\");\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 * _Available since v2.5._\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\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 * _Available since v4.7._\n */\n function toUint56(uint256 value) internal pure returns (uint56) {\n require(value <= type(uint56).max, \"SafeCast: value doesn't fit in 56 bits\");\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 * _Available since v4.7._\n */\n function toUint48(uint256 value) internal pure returns (uint48) {\n require(value <= type(uint48).max, \"SafeCast: value doesn't fit in 48 bits\");\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 * _Available since v4.7._\n */\n function toUint40(uint256 value) internal pure returns (uint40) {\n require(value <= type(uint40).max, \"SafeCast: value doesn't fit in 40 bits\");\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 * _Available since v2.5._\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\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 * _Available since v4.7._\n */\n function toUint24(uint256 value) internal pure returns (uint24) {\n require(value <= type(uint24).max, \"SafeCast: value doesn't fit in 24 bits\");\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 * _Available since v2.5._\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\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 * _Available since v2.5._\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\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 * _Available since v3.0._\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\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 * _Available since v4.7._\n */\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\n downcasted = int248(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 248 bits\");\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 * _Available since v4.7._\n */\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\n downcasted = int240(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 240 bits\");\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 * _Available since v4.7._\n */\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\n downcasted = int232(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 232 bits\");\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 * _Available since v4.7._\n */\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\n downcasted = int224(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 224 bits\");\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 * _Available since v4.7._\n */\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\n downcasted = int216(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 216 bits\");\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 * _Available since v4.7._\n */\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\n downcasted = int208(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 208 bits\");\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 * _Available since v4.7._\n */\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\n downcasted = int200(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 200 bits\");\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 * _Available since v4.7._\n */\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\n downcasted = int192(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 192 bits\");\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 * _Available since v4.7._\n */\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\n downcasted = int184(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 184 bits\");\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 * _Available since v4.7._\n */\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\n downcasted = int176(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 176 bits\");\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 * _Available since v4.7._\n */\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\n downcasted = int168(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 168 bits\");\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 * _Available since v4.7._\n */\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\n downcasted = int160(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 160 bits\");\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 * _Available since v4.7._\n */\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\n downcasted = int152(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 152 bits\");\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 * _Available since v4.7._\n */\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\n downcasted = int144(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 144 bits\");\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 * _Available since v4.7._\n */\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\n downcasted = int136(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 136 bits\");\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 * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\n downcasted = int128(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 128 bits\");\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 * _Available since v4.7._\n */\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\n downcasted = int120(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 120 bits\");\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 * _Available since v4.7._\n */\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\n downcasted = int112(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 112 bits\");\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 * _Available since v4.7._\n */\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\n downcasted = int104(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 104 bits\");\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 * _Available since v4.7._\n */\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\n downcasted = int96(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 96 bits\");\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 * _Available since v4.7._\n */\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\n downcasted = int88(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 88 bits\");\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 * _Available since v4.7._\n */\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\n downcasted = int80(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 80 bits\");\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 * _Available since v4.7._\n */\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\n downcasted = int72(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 72 bits\");\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 * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\n downcasted = int64(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 64 bits\");\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 * _Available since v4.7._\n */\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\n downcasted = int56(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 56 bits\");\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 * _Available since v4.7._\n */\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\n downcasted = int48(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 48 bits\");\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 * _Available since v4.7._\n */\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\n downcasted = int40(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 40 bits\");\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 * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\n downcasted = int32(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 32 bits\");\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 * _Available since v4.7._\n */\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\n downcasted = int24(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 24 bits\");\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 * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\n downcasted = int16(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 16 bits\");\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 * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\n downcasted = int8(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 8 bits\");\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 * _Available since v3.0._\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 require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/SignedMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard signed math utilities missing in the Solidity language.\n */\nlibrary SignedMath {\n /**\n * @dev Returns the largest of two signed numbers.\n */\n function max(int256 a, int256 b) internal pure returns (int256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two signed numbers.\n */\n function min(int256 a, int256 b) internal pure returns (int256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two signed numbers without overflow.\n * The result is rounded towards zero.\n */\n function average(int256 a, int256 b) internal pure returns (int256) {\n // Formula from the book \"Hacker's Delight\"\n int256 x = (a & b) + ((a ^ b) >> 1);\n return x + (int256(uint256(x) >> 255) & (a ^ b));\n }\n\n /**\n * @dev Returns the absolute unsigned value of a signed value.\n */\n function abs(int256 n) internal pure returns (uint256) {\n unchecked {\n // must be unchecked in order to support `n = type(int256).min`\n return uint256(n >= 0 ? n : -n);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/Math.sol\";\nimport \"./math/SignedMath.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n unchecked {\n uint256 length = Math.log10(value) + 1;\n string memory buffer = new string(length);\n uint256 ptr;\n /// @solidity memory-safe-assembly\n assembly {\n ptr := add(buffer, add(32, length))\n }\n while (true) {\n ptr--;\n /// @solidity memory-safe-assembly\n assembly {\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n }\n value /= 10;\n if (value == 0) break;\n }\n return buffer;\n }\n }\n\n /**\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\n */\n function toString(int256 value) internal pure returns (string memory) {\n return string(abi.encodePacked(value < 0 ? \"-\" : \"\", toString(SignedMath.abs(value))));\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n unchecked {\n return toHexString(value, Math.log256(value) + 1);\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n\n /**\n * @dev Returns true if the two strings are equal.\n */\n function equal(string memory a, string memory b) internal pure returns (bool) {\n return keccak256(bytes(a)) == keccak256(bytes(b));\n }\n}\n" + }, + "contracts/aa-4337/core/BaseAccount.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-empty-blocks */\n\nimport \"../interfaces/IAccount.sol\";\nimport \"../interfaces/IEntryPoint.sol\";\nimport \"./Helpers.sol\";\n\n/**\n * Basic account implementation.\n * this contract provides the basic logic for implementing the IAccount interface - validateUserOp\n * specific account implementation should inherit it and provide the account-specific logic\n */\nabstract contract BaseAccount is IAccount {\n using UserOperationLib for UserOperation;\n\n //return value in case of signature failure, with no time-range.\n // equivalent to _packValidationData(true,0,0);\n uint256 internal constant SIG_VALIDATION_FAILED = 1;\n\n /**\n * Return the account nonce.\n * This method returns the next sequential nonce.\n * For a nonce of a specific key, use `entrypoint.getNonce(account, key)`\n */\n function getNonce() public view virtual returns (uint256) {\n return entryPoint().getNonce(address(this), 0);\n }\n\n /**\n * return the entryPoint used by this account.\n * subclass should return the current entryPoint used by this account.\n */\n function entryPoint() public view virtual returns (IEntryPoint);\n\n /**\n * Validate user's signature and nonce.\n * subclass doesn't need to override this method. Instead, it should override the specific internal validation methods.\n */\n function validateUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 missingAccountFunds\n ) external virtual override returns (uint256 validationData) {\n _requireFromEntryPoint();\n validationData = _validateSignature(userOp, userOpHash);\n _validateNonce(userOp.nonce);\n _payPrefund(missingAccountFunds);\n }\n\n /**\n * ensure the request comes from the known entrypoint.\n */\n function _requireFromEntryPoint() internal view virtual {\n require(\n msg.sender == address(entryPoint()),\n \"account: not from EntryPoint\"\n );\n }\n\n /**\n * validate the signature is valid for this message.\n * @param userOp validate the userOp.signature field\n * @param userOpHash convenient field: the hash of the request, to check the signature against\n * (also hashes the entrypoint and chain id)\n * @return validationData signature and time-range of this operation\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * If the account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function _validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) internal virtual returns (uint256 validationData);\n\n /**\n * Validate the nonce of the UserOperation.\n * This method may validate the nonce requirement of this account.\n * e.g.\n * To limit the nonce to use sequenced UserOps only (no \"out of order\" UserOps):\n * `require(nonce < type(uint64).max)`\n * For a hypothetical account that *requires* the nonce to be out-of-order:\n * `require(nonce & type(uint64).max == 0)`\n *\n * The actual nonce uniqueness is managed by the EntryPoint, and thus no other\n * action is needed by the account itself.\n *\n * @param nonce to validate\n *\n * solhint-disable-next-line no-empty-blocks\n */\n function _validateNonce(uint256 nonce) internal view virtual {}\n\n /**\n * sends to the entrypoint (msg.sender) the missing funds for this transaction.\n * subclass MAY override this method for better funds management\n * (e.g. send to the entryPoint more than the minimum required, so that in future transactions\n * it will not be required to send again)\n * @param missingAccountFunds the minimum value this method should send the entrypoint.\n * this value MAY be zero, in case there is enough deposit, or the userOp has a paymaster.\n */\n function _payPrefund(uint256 missingAccountFunds) internal virtual {\n if (missingAccountFunds != 0) {\n (bool success, ) = payable(msg.sender).call{\n value: missingAccountFunds,\n gas: type(uint256).max\n }(\"\");\n (success);\n //ignore failure (its EntryPoint's job to verify, not account.)\n }\n }\n}\n" + }, + "contracts/aa-4337/core/EntryPoint.sol": { + "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n\nimport \"../interfaces/IAccount.sol\";\nimport \"../interfaces/IPaymaster.sol\";\nimport \"../interfaces/IEntryPoint.sol\";\n\nimport \"../utils/Exec.sol\";\nimport \"./StakeManager.sol\";\nimport \"./SenderCreator.sol\";\nimport \"./Helpers.sol\";\nimport \"./NonceManager.sol\";\nimport \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\n\ncontract EntryPoint is\n IEntryPoint,\n StakeManager,\n NonceManager,\n ReentrancyGuard\n{\n using UserOperationLib for UserOperation;\n\n SenderCreator private immutable senderCreator = new SenderCreator();\n\n // internal value used during simulation: need to query aggregator.\n address private constant SIMULATE_FIND_AGGREGATOR = address(1);\n\n // marker for inner call revert on out of gas\n bytes32 private constant INNER_OUT_OF_GAS = hex\"deaddead\";\n\n uint256 private constant REVERT_REASON_MAX_LEN = 2048;\n\n /**\n * for simulation purposes, validateUserOp (and validatePaymasterUserOp) must return this value\n * in case of signature failure, instead of revert.\n */\n uint256 public constant SIG_VALIDATION_FAILED = 1;\n\n /**\n * compensate the caller's beneficiary address with the collected fees of all UserOperations.\n * @param beneficiary the address to receive the fees\n * @param amount amount to transfer.\n */\n function _compensate(address payable beneficiary, uint256 amount) internal {\n require(beneficiary != address(0), \"AA90 invalid beneficiary\");\n (bool success, ) = beneficiary.call{value: amount}(\"\");\n require(success, \"AA91 failed send to beneficiary\");\n }\n\n /**\n * execute a user op\n * @param opIndex index into the opInfo array\n * @param userOp the userOp to execute\n * @param opInfo the opInfo filled by validatePrepayment for this userOp.\n * @return collected the total amount this userOp paid.\n */\n function _executeUserOp(\n uint256 opIndex,\n UserOperation calldata userOp,\n UserOpInfo memory opInfo\n ) private returns (uint256 collected) {\n uint256 preGas = gasleft();\n bytes memory context = getMemoryBytesFromOffset(opInfo.contextOffset);\n\n try this.innerHandleOp(userOp.callData, opInfo, context) returns (\n uint256 _actualGasCost\n ) {\n collected = _actualGasCost;\n } catch {\n bytes32 innerRevertCode;\n assembly {\n returndatacopy(0, 0, 32)\n innerRevertCode := mload(0)\n }\n // handleOps was called with gas limit too low. abort entire bundle.\n if (innerRevertCode == INNER_OUT_OF_GAS) {\n //report paymaster, since if it is not deliberately caused by the bundler,\n // it must be a revert caused by paymaster.\n revert FailedOp(opIndex, \"AA95 out of gas\");\n }\n\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n collected = _handlePostOp(\n opIndex,\n IPaymaster.PostOpMode.postOpReverted,\n opInfo,\n context,\n actualGas\n );\n }\n }\n\n /**\n * Execute a batch of UserOperations.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(\n UserOperation[] calldata ops,\n address payable beneficiary\n ) public nonReentrant {\n uint256 opslen = ops.length;\n UserOpInfo[] memory opInfos = new UserOpInfo[](opslen);\n\n unchecked {\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[i];\n (\n uint256 validationData,\n uint256 pmValidationData\n ) = _validatePrepayment(i, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(\n i,\n validationData,\n pmValidationData,\n address(0)\n );\n }\n\n uint256 collected = 0;\n emit BeforeExecution();\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(i, ops[i], opInfos[i]);\n }\n\n _compensate(beneficiary, collected);\n } //unchecked\n }\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) public nonReentrant {\n uint256 opasLen = opsPerAggregator.length;\n uint256 totalOps = 0;\n for (uint256 i = 0; i < opasLen; i++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[i];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n //address(1) is special marker of \"signature error\"\n require(\n address(aggregator) != address(1),\n \"AA96 invalid aggregator\"\n );\n\n if (address(aggregator) != address(0)) {\n // solhint-disable-next-line no-empty-blocks\n try aggregator.validateSignatures(ops, opa.signature) {} catch {\n revert SignatureValidationFailed(address(aggregator));\n }\n }\n\n totalOps += ops.length;\n }\n\n UserOpInfo[] memory opInfos = new UserOpInfo[](totalOps);\n\n emit BeforeExecution();\n\n uint256 opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n uint256 opslen = ops.length;\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[opIndex];\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(opIndex, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(\n i,\n validationData,\n paymasterValidationData,\n address(aggregator)\n );\n opIndex++;\n }\n }\n\n uint256 collected = 0;\n opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n emit SignatureAggregatorChanged(address(opa.aggregator));\n UserOperation[] calldata ops = opa.userOps;\n uint256 opslen = ops.length;\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(opIndex, ops[i], opInfos[opIndex]);\n opIndex++;\n }\n }\n emit SignatureAggregatorChanged(address(0));\n\n _compensate(beneficiary, collected);\n }\n\n /// @inheritdoc IEntryPoint\n function simulateHandleOp(\n UserOperation calldata op,\n address target,\n bytes calldata targetCallData\n ) external override {\n UserOpInfo memory opInfo;\n _simulationOnlyValidations(op);\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(0, op, opInfo);\n ValidationData memory data = _intersectTimeRange(\n validationData,\n paymasterValidationData\n );\n\n numberMarker();\n uint256 paid = _executeUserOp(0, op, opInfo);\n numberMarker();\n bool targetSuccess;\n bytes memory targetResult;\n if (target != address(0)) {\n (targetSuccess, targetResult) = target.call(targetCallData);\n }\n revert ExecutionResult(\n opInfo.preOpGas,\n paid,\n data.validAfter,\n data.validUntil,\n targetSuccess,\n targetResult\n );\n }\n\n // A memory copy of UserOp static fields only.\n // Excluding: callData, initCode and signature. Replacing paymasterAndData with paymaster.\n struct MemoryUserOp {\n address sender;\n uint256 nonce;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n address paymaster;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n }\n\n struct UserOpInfo {\n MemoryUserOp mUserOp;\n bytes32 userOpHash;\n uint256 prefund;\n uint256 contextOffset;\n uint256 preOpGas;\n }\n\n /**\n * inner function to handle a UserOperation.\n * Must be declared \"external\" to open a call context, but it can only be called by handleOps.\n */\n function innerHandleOp(\n bytes memory callData,\n UserOpInfo memory opInfo,\n bytes calldata context\n ) external returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n require(msg.sender == address(this), \"AA92 internal call only\");\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n\n uint callGasLimit = mUserOp.callGasLimit;\n unchecked {\n // handleOps was called with gas limit too low. abort entire bundle.\n if (\n gasleft() < callGasLimit + mUserOp.verificationGasLimit + 5000\n ) {\n assembly {\n mstore(0, INNER_OUT_OF_GAS)\n revert(0, 32)\n }\n }\n }\n\n IPaymaster.PostOpMode mode = IPaymaster.PostOpMode.opSucceeded;\n if (callData.length > 0) {\n bool success = Exec.call(mUserOp.sender, 0, callData, callGasLimit);\n if (!success) {\n bytes memory result = Exec.getReturnData(REVERT_REASON_MAX_LEN);\n if (result.length > 0) {\n emit UserOperationRevertReason(\n opInfo.userOpHash,\n mUserOp.sender,\n mUserOp.nonce,\n result\n );\n }\n mode = IPaymaster.PostOpMode.opReverted;\n }\n }\n\n unchecked {\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n //note: opIndex is ignored (relevant only if mode==postOpReverted, which is only possible outside of innerHandleOp)\n return _handlePostOp(0, mode, opInfo, context, actualGas);\n }\n }\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(\n UserOperation calldata userOp\n ) public view returns (bytes32) {\n return\n keccak256(abi.encode(userOp.hash(), address(this), block.chainid));\n }\n\n /**\n * copy general fields from userOp into the memory opInfo structure.\n */\n function _copyUserOpToMemory(\n UserOperation calldata userOp,\n MemoryUserOp memory mUserOp\n ) internal pure {\n mUserOp.sender = userOp.sender;\n mUserOp.nonce = userOp.nonce;\n mUserOp.callGasLimit = userOp.callGasLimit;\n mUserOp.verificationGasLimit = userOp.verificationGasLimit;\n mUserOp.preVerificationGas = userOp.preVerificationGas;\n mUserOp.maxFeePerGas = userOp.maxFeePerGas;\n mUserOp.maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes calldata paymasterAndData = userOp.paymasterAndData;\n if (paymasterAndData.length > 0) {\n require(\n paymasterAndData.length >= 20,\n \"AA93 invalid paymasterAndData\"\n );\n mUserOp.paymaster = address(bytes20(paymasterAndData[:20]));\n } else {\n mUserOp.paymaster = address(0);\n }\n }\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external {\n UserOpInfo memory outOpInfo;\n\n _simulationOnlyValidations(userOp);\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(0, userOp, outOpInfo);\n StakeInfo memory paymasterInfo = _getStakeInfo(\n outOpInfo.mUserOp.paymaster\n );\n StakeInfo memory senderInfo = _getStakeInfo(outOpInfo.mUserOp.sender);\n StakeInfo memory factoryInfo;\n {\n bytes calldata initCode = userOp.initCode;\n address factory = initCode.length >= 20\n ? address(bytes20(initCode[0:20]))\n : address(0);\n factoryInfo = _getStakeInfo(factory);\n }\n\n ValidationData memory data = _intersectTimeRange(\n validationData,\n paymasterValidationData\n );\n address aggregator = data.aggregator;\n bool sigFailed = aggregator == address(1);\n ReturnInfo memory returnInfo = ReturnInfo(\n outOpInfo.preOpGas,\n outOpInfo.prefund,\n sigFailed,\n data.validAfter,\n data.validUntil,\n getMemoryBytesFromOffset(outOpInfo.contextOffset)\n );\n\n if (aggregator != address(0) && aggregator != address(1)) {\n AggregatorStakeInfo memory aggregatorInfo = AggregatorStakeInfo(\n aggregator,\n _getStakeInfo(aggregator)\n );\n revert ValidationResultWithAggregation(\n returnInfo,\n senderInfo,\n factoryInfo,\n paymasterInfo,\n aggregatorInfo\n );\n }\n revert ValidationResult(\n returnInfo,\n senderInfo,\n factoryInfo,\n paymasterInfo\n );\n }\n\n function _getRequiredPrefund(\n MemoryUserOp memory mUserOp\n ) internal pure returns (uint256 requiredPrefund) {\n unchecked {\n //when using a Paymaster, the verificationGasLimit is used also to as a limit for the postOp call.\n // our security model might call postOp eventually twice\n uint256 mul = mUserOp.paymaster != address(0) ? 3 : 1;\n uint256 requiredGas = mUserOp.callGasLimit +\n mUserOp.verificationGasLimit *\n mul +\n mUserOp.preVerificationGas;\n\n requiredPrefund = requiredGas * mUserOp.maxFeePerGas;\n }\n }\n\n // create the sender's contract if needed.\n function _createSenderIfNeeded(\n uint256 opIndex,\n UserOpInfo memory opInfo,\n bytes calldata initCode\n ) internal {\n if (initCode.length != 0) {\n address sender = opInfo.mUserOp.sender;\n if (sender.code.length != 0)\n revert FailedOp(opIndex, \"AA10 sender already constructed\");\n address sender1 = senderCreator.createSender{\n gas: opInfo.mUserOp.verificationGasLimit\n }(initCode);\n if (sender1 == address(0))\n revert FailedOp(opIndex, \"AA13 initCode failed or OOG\");\n if (sender1 != sender)\n revert FailedOp(opIndex, \"AA14 initCode must return sender\");\n if (sender1.code.length == 0)\n revert FailedOp(opIndex, \"AA15 initCode must create sender\");\n address factory = address(bytes20(initCode[0:20]));\n emit AccountDeployed(\n opInfo.userOpHash,\n sender,\n factory,\n opInfo.mUserOp.paymaster\n );\n }\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes calldata initCode) public {\n address sender = senderCreator.createSender(initCode);\n revert SenderAddressResult(sender);\n }\n\n function _simulationOnlyValidations(\n UserOperation calldata userOp\n ) internal view {\n // solhint-disable-next-line no-empty-blocks\n try\n this._validateSenderAndPaymaster(\n userOp.initCode,\n userOp.sender,\n userOp.paymasterAndData\n )\n {} catch Error(string memory revertReason) {\n if (bytes(revertReason).length != 0) {\n revert FailedOp(0, revertReason);\n }\n }\n }\n\n /**\n * Called only during simulation.\n * This function always reverts to prevent warm/cold storage differentiation in simulation vs execution.\n */\n function _validateSenderAndPaymaster(\n bytes calldata initCode,\n address sender,\n bytes calldata paymasterAndData\n ) external view {\n if (initCode.length == 0 && sender.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA20 account not deployed\");\n }\n if (paymasterAndData.length >= 20) {\n address paymaster = address(bytes20(paymasterAndData[0:20]));\n if (paymaster.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA30 paymaster not deployed\");\n }\n }\n // always revert\n revert(\"\");\n }\n\n /**\n * call account.validateUserOp.\n * revert (with FailedOp) in case validateUserOp reverts, or account didn't send required prefund.\n * decrement account's deposit if needed\n */\n function _validateAccountPrepayment(\n uint256 opIndex,\n UserOperation calldata op,\n UserOpInfo memory opInfo,\n uint256 requiredPrefund\n )\n internal\n returns (\n uint256 gasUsedByValidateAccountPrepayment,\n uint256 validationData\n )\n {\n unchecked {\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n address sender = mUserOp.sender;\n _createSenderIfNeeded(opIndex, opInfo, op.initCode);\n address paymaster = mUserOp.paymaster;\n numberMarker();\n uint256 missingAccountFunds = 0;\n if (paymaster == address(0)) {\n uint256 bal = balanceOf(sender);\n missingAccountFunds = bal > requiredPrefund\n ? 0\n : requiredPrefund - bal;\n }\n try\n IAccount(sender).validateUserOp{\n gas: mUserOp.verificationGasLimit\n }(op, opInfo.userOpHash, missingAccountFunds)\n returns (uint256 _validationData) {\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA23 reverted: \", revertReason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA23 reverted (or OOG)\");\n }\n if (paymaster == address(0)) {\n DepositInfo storage senderInfo = deposits[sender];\n uint256 deposit = senderInfo.deposit;\n if (requiredPrefund > deposit) {\n revert FailedOp(opIndex, \"AA21 didn't pay prefund\");\n }\n senderInfo.deposit = uint112(deposit - requiredPrefund);\n }\n gasUsedByValidateAccountPrepayment = preGas - gasleft();\n }\n }\n\n /**\n * In case the request has a paymaster:\n * Validate paymaster has enough deposit.\n * Call paymaster.validatePaymasterUserOp.\n * Revert with proper FailedOp in case paymaster reverts.\n * Decrement paymaster's deposit\n */\n function _validatePaymasterPrepayment(\n uint256 opIndex,\n UserOperation calldata op,\n UserOpInfo memory opInfo,\n uint256 requiredPreFund,\n uint256 gasUsedByValidateAccountPrepayment\n ) internal returns (bytes memory context, uint256 validationData) {\n unchecked {\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 verificationGasLimit = mUserOp.verificationGasLimit;\n require(\n verificationGasLimit > gasUsedByValidateAccountPrepayment,\n \"AA41 too little verificationGas\"\n );\n uint256 gas = verificationGasLimit -\n gasUsedByValidateAccountPrepayment;\n\n address paymaster = mUserOp.paymaster;\n DepositInfo storage paymasterInfo = deposits[paymaster];\n uint256 deposit = paymasterInfo.deposit;\n if (deposit < requiredPreFund) {\n revert FailedOp(opIndex, \"AA31 paymaster deposit too low\");\n }\n paymasterInfo.deposit = uint112(deposit - requiredPreFund);\n try\n IPaymaster(paymaster).validatePaymasterUserOp{gas: gas}(\n op,\n opInfo.userOpHash,\n requiredPreFund\n )\n returns (bytes memory _context, uint256 _validationData) {\n context = _context;\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA33 reverted: \", revertReason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA33 reverted (or OOG)\");\n }\n }\n }\n\n /**\n * revert if either account validationData or paymaster validationData is expired\n */\n function _validateAccountAndPaymasterValidationData(\n uint256 opIndex,\n uint256 validationData,\n uint256 paymasterValidationData,\n address expectedAggregator\n ) internal view {\n (address aggregator, bool outOfTimeRange) = _getValidationData(\n validationData\n );\n if (expectedAggregator != aggregator) {\n revert FailedOp(opIndex, \"AA24 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA22 expired or not due\");\n }\n //pmAggregator is not a real signature aggregator: we don't have logic to handle it as address.\n // non-zero address means that the paymaster fails due to some signature check (which is ok only during estimation)\n address pmAggregator;\n (pmAggregator, outOfTimeRange) = _getValidationData(\n paymasterValidationData\n );\n if (pmAggregator != address(0)) {\n revert FailedOp(opIndex, \"AA34 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA32 paymaster expired or not due\");\n }\n }\n\n function _getValidationData(\n uint256 validationData\n ) internal view returns (address aggregator, bool outOfTimeRange) {\n if (validationData == 0) {\n return (address(0), false);\n }\n ValidationData memory data = _parseValidationData(validationData);\n // solhint-disable-next-line not-rely-on-time\n outOfTimeRange =\n block.timestamp > data.validUntil ||\n block.timestamp < data.validAfter;\n aggregator = data.aggregator;\n }\n\n /**\n * validate account and paymaster (if defined).\n * also make sure total validation doesn't exceed verificationGasLimit\n * this method is called off-chain (simulateValidation()) and on-chain (from handleOps)\n * @param opIndex the index of this userOp into the \"opInfos\" array\n * @param userOp the userOp to validate\n */\n function _validatePrepayment(\n uint256 opIndex,\n UserOperation calldata userOp,\n UserOpInfo memory outOpInfo\n )\n private\n returns (uint256 validationData, uint256 paymasterValidationData)\n {\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = outOpInfo.mUserOp;\n _copyUserOpToMemory(userOp, mUserOp);\n outOpInfo.userOpHash = getUserOpHash(userOp);\n\n // validate all numeric values in userOp are well below 128 bit, so they can safely be added\n // and multiplied without causing overflow\n uint256 maxGasValues = mUserOp.preVerificationGas |\n mUserOp.verificationGasLimit |\n mUserOp.callGasLimit |\n userOp.maxFeePerGas |\n userOp.maxPriorityFeePerGas;\n require(maxGasValues <= type(uint120).max, \"AA94 gas values overflow\");\n\n uint256 gasUsedByValidateAccountPrepayment;\n uint256 requiredPreFund = _getRequiredPrefund(mUserOp);\n (\n gasUsedByValidateAccountPrepayment,\n validationData\n ) = _validateAccountPrepayment(\n opIndex,\n userOp,\n outOpInfo,\n requiredPreFund\n );\n\n if (!_validateAndUpdateNonce(mUserOp.sender, mUserOp.nonce)) {\n revert FailedOp(opIndex, \"AA25 invalid account nonce\");\n }\n\n //a \"marker\" where account opcode validation is done and paymaster opcode validation is about to start\n // (used only by off-chain simulateValidation)\n numberMarker();\n\n bytes memory context;\n if (mUserOp.paymaster != address(0)) {\n (context, paymasterValidationData) = _validatePaymasterPrepayment(\n opIndex,\n userOp,\n outOpInfo,\n requiredPreFund,\n gasUsedByValidateAccountPrepayment\n );\n }\n unchecked {\n uint256 gasUsed = preGas - gasleft();\n\n if (userOp.verificationGasLimit < gasUsed) {\n revert FailedOp(opIndex, \"AA40 over verificationGasLimit\");\n }\n outOpInfo.prefund = requiredPreFund;\n outOpInfo.contextOffset = getOffsetOfMemoryBytes(context);\n outOpInfo.preOpGas = preGas - gasleft() + userOp.preVerificationGas;\n }\n }\n\n /**\n * process post-operation.\n * called just after the callData is executed.\n * if a paymaster is defined and its validation returned a non-empty context, its postOp is called.\n * the excess amount is refunded to the account (or paymaster - if it was used in the request)\n * @param opIndex index in the batch\n * @param mode - whether is called from innerHandleOp, or outside (postOpReverted)\n * @param opInfo userOp fields and info collected during validation\n * @param context the context returned in validatePaymasterUserOp\n * @param actualGas the gas used so far by this user operation\n */\n function _handlePostOp(\n uint256 opIndex,\n IPaymaster.PostOpMode mode,\n UserOpInfo memory opInfo,\n bytes memory context,\n uint256 actualGas\n ) private returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n unchecked {\n address refundAddress;\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 gasPrice = getUserOpGasPrice(mUserOp);\n\n address paymaster = mUserOp.paymaster;\n if (paymaster == address(0)) {\n refundAddress = mUserOp.sender;\n } else {\n refundAddress = paymaster;\n if (context.length > 0) {\n actualGasCost = actualGas * gasPrice;\n if (mode != IPaymaster.PostOpMode.postOpReverted) {\n IPaymaster(paymaster).postOp{\n gas: mUserOp.verificationGasLimit\n }(mode, context, actualGasCost);\n } else {\n // solhint-disable-next-line no-empty-blocks\n try\n IPaymaster(paymaster).postOp{\n gas: mUserOp.verificationGasLimit\n }(mode, context, actualGasCost)\n {} catch Error(string memory reason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA50 postOp reverted: \", reason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA50 postOp revert\");\n }\n }\n }\n }\n actualGas += preGas - gasleft();\n actualGasCost = actualGas * gasPrice;\n if (opInfo.prefund < actualGasCost) {\n revert FailedOp(opIndex, \"AA51 prefund below actualGasCost\");\n }\n uint256 refund = opInfo.prefund - actualGasCost;\n _incrementDeposit(refundAddress, refund);\n bool success = mode == IPaymaster.PostOpMode.opSucceeded;\n emit UserOperationEvent(\n opInfo.userOpHash,\n mUserOp.sender,\n mUserOp.paymaster,\n mUserOp.nonce,\n success,\n actualGasCost,\n actualGas\n );\n } // unchecked\n }\n\n /**\n * the gas price this UserOp agrees to pay.\n * relayer/block builder might submit the TX with higher priorityFee, but the user should not\n */\n function getUserOpGasPrice(\n MemoryUserOp memory mUserOp\n ) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = mUserOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = mUserOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n function getOffsetOfMemoryBytes(\n bytes memory data\n ) internal pure returns (uint256 offset) {\n assembly {\n offset := data\n }\n }\n\n function getMemoryBytesFromOffset(\n uint256 offset\n ) internal pure returns (bytes memory data) {\n assembly {\n data := offset\n }\n }\n\n //place the NUMBER opcode in the code.\n // this is used as a marker during simulation, as this OP is completely banned from the simulated code of the\n // account and paymaster.\n function numberMarker() internal view {\n assembly {\n mstore(0, number())\n }\n }\n}\n" + }, + "contracts/aa-4337/core/Helpers.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable no-inline-assembly */\n\n/**\n * returned data from validateUserOp.\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\n * @param aggregator - address(0) - the account validated the signature by itself.\n * address(1) - the account failed to validate the signature.\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\n * @param validAfter - this UserOp is valid only after this timestamp.\n * @param validaUntil - this UserOp is valid only up to this timestamp.\n */\nstruct ValidationData {\n address aggregator;\n uint48 validAfter;\n uint48 validUntil;\n}\n\n//extract sigFailed, validAfter, validUntil.\n// also convert zero validUntil to type(uint48).max\nfunction _parseValidationData(\n uint validationData\n) pure returns (ValidationData memory data) {\n address aggregator = address(uint160(validationData));\n uint48 validUntil = uint48(validationData >> 160);\n if (validUntil == 0) {\n validUntil = type(uint48).max;\n }\n uint48 validAfter = uint48(validationData >> (48 + 160));\n return ValidationData(aggregator, validAfter, validUntil);\n}\n\n// intersect account and paymaster ranges.\nfunction _intersectTimeRange(\n uint256 validationData,\n uint256 paymasterValidationData\n) pure returns (ValidationData memory) {\n ValidationData memory accountValidationData = _parseValidationData(\n validationData\n );\n ValidationData memory pmValidationData = _parseValidationData(\n paymasterValidationData\n );\n address aggregator = accountValidationData.aggregator;\n if (aggregator == address(0)) {\n aggregator = pmValidationData.aggregator;\n }\n uint48 validAfter = accountValidationData.validAfter;\n uint48 validUntil = accountValidationData.validUntil;\n uint48 pmValidAfter = pmValidationData.validAfter;\n uint48 pmValidUntil = pmValidationData.validUntil;\n\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\n return ValidationData(aggregator, validAfter, validUntil);\n}\n\n/**\n * helper to pack the return value for validateUserOp\n * @param data - the ValidationData to pack\n */\nfunction _packValidationData(\n ValidationData memory data\n) pure returns (uint256) {\n return\n uint160(data.aggregator) |\n (uint256(data.validUntil) << 160) |\n (uint256(data.validAfter) << (160 + 48));\n}\n\n/**\n * helper to pack the return value for validateUserOp, when not using an aggregator\n * @param sigFailed - true for signature failure, false for success\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\n * @param validAfter first timestamp this UserOperation is valid\n */\nfunction _packValidationData(\n bool sigFailed,\n uint48 validUntil,\n uint48 validAfter\n) pure returns (uint256) {\n return\n (sigFailed ? 1 : 0) |\n (uint256(validUntil) << 160) |\n (uint256(validAfter) << (160 + 48));\n}\n\n/**\n * keccak function over calldata.\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\n */\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\n assembly {\n let mem := mload(0x40)\n let len := data.length\n calldatacopy(mem, data.offset, len)\n ret := keccak256(mem, len)\n }\n}\n" + }, + "contracts/aa-4337/core/NonceManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\nimport \"../interfaces/IEntryPoint.sol\";\n\n/**\n * nonce management functionality\n */\ncontract NonceManager is INonceManager {\n /**\n * The next valid sequence number for a given nonce key.\n */\n mapping(address => mapping(uint192 => uint256)) public nonceSequenceNumber;\n\n function getNonce(\n address sender,\n uint192 key\n ) public view override returns (uint256 nonce) {\n return nonceSequenceNumber[sender][key] | (uint256(key) << 64);\n }\n\n // allow an account to manually increment its own nonce.\n // (mainly so that during construction nonce can be made non-zero,\n // to \"absorb\" the gas cost of first nonce increment to 1st transaction (construction),\n // not to 2nd transaction)\n function incrementNonce(uint192 key) public override {\n nonceSequenceNumber[msg.sender][key]++;\n }\n\n /**\n * validate nonce uniqueness for this account.\n * called just after validateUserOp()\n */\n function _validateAndUpdateNonce(\n address sender,\n uint256 nonce\n ) internal returns (bool) {\n uint192 key = uint192(nonce >> 64);\n uint64 seq = uint64(nonce);\n return nonceSequenceNumber[sender][key]++ == seq;\n }\n}\n" + }, + "contracts/aa-4337/core/SenderCreator.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/**\n * helper contract for EntryPoint, to call userOp.initCode from a \"neutral\" address,\n * which is explicitly not the entryPoint itself.\n */\ncontract SenderCreator {\n /**\n * call the \"initCode\" factory to create and return the sender account address\n * @param initCode the initCode value from a UserOp. contains 20 bytes of factory address, followed by calldata\n * @return sender the returned address of the created account, or zero address on failure.\n */\n function createSender(\n bytes calldata initCode\n ) external returns (address sender) {\n address factory = address(bytes20(initCode[0:20]));\n bytes memory initCallData = initCode[20:];\n bool success;\n /* solhint-disable no-inline-assembly */\n assembly {\n success := call(\n gas(),\n factory,\n 0,\n add(initCallData, 0x20),\n mload(initCallData),\n 0,\n 32\n )\n sender := mload(0)\n }\n if (!success) {\n sender = address(0);\n }\n }\n}\n" + }, + "contracts/aa-4337/core/StakeManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity 0.8.21;\n\nimport \"../interfaces/IStakeManager.sol\";\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable not-rely-on-time */\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by a paymaster.\n */\nabstract contract StakeManager is IStakeManager {\n /// maps paymaster to their deposits and stakes\n mapping(address => DepositInfo) public deposits;\n\n /// @inheritdoc IStakeManager\n function getDepositInfo(\n address account\n ) public view returns (DepositInfo memory info) {\n return deposits[account];\n }\n\n // internal method to return just the stake info\n function _getStakeInfo(\n address addr\n ) internal view returns (StakeInfo memory info) {\n DepositInfo storage depositInfo = deposits[addr];\n info.stake = depositInfo.stake;\n info.unstakeDelaySec = depositInfo.unstakeDelaySec;\n }\n\n /// return the deposit (for gas payment) of the account\n function balanceOf(address account) public view returns (uint256) {\n return deposits[account].deposit;\n }\n\n receive() external payable {\n depositTo(msg.sender);\n }\n\n function _incrementDeposit(address account, uint256 amount) internal {\n DepositInfo storage info = deposits[account];\n uint256 newAmount = info.deposit + amount;\n require(newAmount <= type(uint112).max, \"deposit overflow\");\n info.deposit = uint112(newAmount);\n }\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) public payable {\n _incrementDeposit(account, msg.value);\n DepositInfo storage info = deposits[account];\n emit Deposited(account, info.deposit);\n }\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 unstakeDelaySec) public payable {\n DepositInfo storage info = deposits[msg.sender];\n require(unstakeDelaySec > 0, \"must specify unstake delay\");\n require(\n unstakeDelaySec >= info.unstakeDelaySec,\n \"cannot decrease unstake time\"\n );\n uint256 stake = info.stake + msg.value;\n require(stake > 0, \"no stake specified\");\n require(stake <= type(uint112).max, \"stake overflow\");\n deposits[msg.sender] = DepositInfo(\n info.deposit,\n true,\n uint112(stake),\n unstakeDelaySec,\n 0\n );\n emit StakeLocked(msg.sender, stake, unstakeDelaySec);\n }\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external {\n DepositInfo storage info = deposits[msg.sender];\n require(info.unstakeDelaySec != 0, \"not staked\");\n require(info.staked, \"already unstaking\");\n uint48 withdrawTime = uint48(block.timestamp) + info.unstakeDelaySec;\n info.withdrawTime = withdrawTime;\n info.staked = false;\n emit StakeUnlocked(msg.sender, withdrawTime);\n }\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external {\n DepositInfo storage info = deposits[msg.sender];\n uint256 stake = info.stake;\n require(stake > 0, \"No stake to withdraw\");\n require(info.withdrawTime > 0, \"must call unlockStake() first\");\n require(\n info.withdrawTime <= block.timestamp,\n \"Stake withdrawal is not due\"\n );\n info.unstakeDelaySec = 0;\n info.withdrawTime = 0;\n info.stake = 0;\n emit StakeWithdrawn(msg.sender, withdrawAddress, stake);\n (bool success, ) = withdrawAddress.call{value: stake}(\"\");\n require(success, \"failed to withdraw stake\");\n }\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(\n address payable withdrawAddress,\n uint256 withdrawAmount\n ) external {\n DepositInfo storage info = deposits[msg.sender];\n require(withdrawAmount <= info.deposit, \"Withdraw amount too large\");\n info.deposit = uint112(info.deposit - withdrawAmount);\n emit Withdrawn(msg.sender, withdrawAddress, withdrawAmount);\n (bool success, ) = withdrawAddress.call{value: withdrawAmount}(\"\");\n require(success, \"failed to withdraw\");\n }\n}\n" + }, + "contracts/aa-4337/interfaces/IAccount.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\ninterface IAccount {\n /**\n * Validate user's signature and nonce\n * the entryPoint will make the call to the recipient only if this validation call returns successfully.\n * signature failure should be reported by returning SIG_VALIDATION_FAILED (1).\n * This allows making a \"simulation call\" without a valid signature\n * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure.\n *\n * @dev Must validate caller is the entryPoint.\n * Must validate the signature and nonce\n * @param userOp the operation that is about to be executed.\n * @param userOpHash hash of the user's request data. can be used as the basis for signature.\n * @param missingAccountFunds missing funds on the account's deposit in the entrypoint.\n * This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call.\n * The excess is left as a deposit in the entrypoint, for future calls.\n * can be withdrawn anytime using \"entryPoint.withdrawTo()\"\n * In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero.\n * @return validationData packaged ValidationData structure. use `_packValidationData` and `_unpackValidationData` to encode and decode\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * If an account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validateUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 missingAccountFunds\n ) external returns (uint256 validationData);\n}\n" + }, + "contracts/aa-4337/interfaces/IAggregator.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * Aggregated Signatures validator.\n */\ninterface IAggregator {\n /**\n * validate aggregated signature.\n * revert if the aggregated signature does not match the given list of operations.\n */\n function validateSignatures(\n UserOperation[] calldata userOps,\n bytes calldata signature\n ) external view;\n\n /**\n * validate signature of a single userOp\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\n * @param userOp the userOperation received from the user.\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\n * (usually empty, unless account and aggregator support some kind of \"multisig\"\n */\n function validateUserOpSignature(\n UserOperation calldata userOp\n ) external view returns (bytes memory sigForUserOp);\n\n /**\n * aggregate multiple signatures into a single value.\n * This method is called off-chain to calculate the signature to pass with handleOps()\n * bundler MAY use optimized custom code perform this aggregation\n * @param userOps array of UserOperations to collect the signatures from.\n * @return aggregatedSignature the aggregated signature\n */\n function aggregateSignatures(\n UserOperation[] calldata userOps\n ) external view returns (bytes memory aggregatedSignature);\n}\n" + }, + "contracts/aa-4337/interfaces/IEntryPoint.sol": { + "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n/* solhint-disable reason-string */\n\nimport \"./UserOperation.sol\";\nimport \"./IStakeManager.sol\";\nimport \"./IAggregator.sol\";\nimport \"./INonceManager.sol\";\n\ninterface IEntryPoint is IStakeManager, INonceManager {\n /***\n * An event emitted after each successful request\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\n * @param sender - the account that generates this request.\n * @param paymaster - if non-null, the paymaster that pays for this request.\n * @param nonce - the nonce value from the request.\n * @param success - true if the sender transaction succeeded, false if reverted.\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\n */\n event UserOperationEvent(\n bytes32 indexed userOpHash,\n address indexed sender,\n address indexed paymaster,\n uint256 nonce,\n bool success,\n uint256 actualGasCost,\n uint256 actualGasUsed\n );\n\n /**\n * account \"sender\" was deployed.\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\n * @param sender the account that is deployed\n * @param factory the factory used to deploy this account (in the initCode)\n * @param paymaster the paymaster used by this UserOp\n */\n event AccountDeployed(\n bytes32 indexed userOpHash,\n address indexed sender,\n address factory,\n address paymaster\n );\n\n /**\n * An event emitted if the UserOperation \"callData\" reverted with non-zero length\n * @param userOpHash the request unique identifier.\n * @param sender the sender of this request\n * @param nonce the nonce used in the request\n * @param revertReason - the return bytes from the (reverted) call to \"callData\".\n */\n event UserOperationRevertReason(\n bytes32 indexed userOpHash,\n address indexed sender,\n uint256 nonce,\n bytes revertReason\n );\n\n /**\n * an event emitted by handleOps(), before starting the execution loop.\n * any event emitted before this event, is part of the validation.\n */\n event BeforeExecution();\n\n /**\n * signature aggregator used by the following UserOperationEvents within this bundle.\n */\n event SignatureAggregatorChanged(address indexed aggregator);\n\n /**\n * a custom revert error of handleOps, to identify the offending op.\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\n * @param reason - revert reason\n * The string starts with a unique code \"AAmn\", where \"m\" is \"1\" for factory, \"2\" for account and \"3\" for paymaster issues,\n * so a failure can be attributed to the correct entity.\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\n */\n error FailedOp(uint256 opIndex, string reason);\n\n /**\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\n */\n error SignatureValidationFailed(address aggregator);\n\n /**\n * Successful result from simulateValidation.\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n */\n error ValidationResult(\n ReturnInfo returnInfo,\n StakeInfo senderInfo,\n StakeInfo factoryInfo,\n StakeInfo paymasterInfo\n );\n\n /**\n * Successful result from simulateValidation, if the account returns a signature aggregator\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\n * bundler MUST use it to verify the signature, or reject the UserOperation\n */\n error ValidationResultWithAggregation(\n ReturnInfo returnInfo,\n StakeInfo senderInfo,\n StakeInfo factoryInfo,\n StakeInfo paymasterInfo,\n AggregatorStakeInfo aggregatorInfo\n );\n\n /**\n * return value of getSenderAddress\n */\n error SenderAddressResult(address sender);\n\n /**\n * return value of simulateHandleOp\n */\n error ExecutionResult(\n uint256 preOpGas,\n uint256 paid,\n uint48 validAfter,\n uint48 validUntil,\n bool targetSuccess,\n bytes targetResult\n );\n\n //UserOps handled, per aggregator\n struct UserOpsPerAggregator {\n UserOperation[] userOps;\n // aggregator address\n IAggregator aggregator;\n // aggregated signature\n bytes signature;\n }\n\n /**\n * Execute a batch of UserOperation.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(\n UserOperation[] calldata ops,\n address payable beneficiary\n ) external;\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) external;\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(\n UserOperation calldata userOp\n ) external view returns (bytes32);\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external;\n\n /**\n * gas and return values during simulation\n * @param preOpGas the gas used for validation (including preValidationGas)\n * @param prefund the required prefund for this operation\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\n */\n struct ReturnInfo {\n uint256 preOpGas;\n uint256 prefund;\n bool sigFailed;\n uint48 validAfter;\n uint48 validUntil;\n bytes paymasterContext;\n }\n\n /**\n * returned aggregated signature info.\n * the aggregator returned by the account, and its current stake.\n */\n struct AggregatorStakeInfo {\n address aggregator;\n StakeInfo stakeInfo;\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes memory initCode) external;\n\n /**\n * simulate full execution of a UserOperation (including both validation and target execution)\n * this method will always revert with \"ExecutionResult\".\n * it performs full validation of the UserOperation, but ignores signature error.\n * an optional target address is called after the userop succeeds, and its value is returned\n * (before the entire call is reverted)\n * Note that in order to collect the the success/failure of the target call, it must be executed\n * with trace enabled to track the emitted events.\n * @param op the UserOperation to simulate\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\n * are set to the return from that call.\n * @param targetCallData callData to pass to target address\n */\n function simulateHandleOp(\n UserOperation calldata op,\n address target,\n bytes calldata targetCallData\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/INonceManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\ninterface INonceManager {\n /**\n * Return the next nonce for this sender.\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\n * But UserOp with different keys can come with arbitrary order.\n *\n * @param sender the account address\n * @param key the high 192 bit of the nonce\n * @return nonce a full nonce to pass for next UserOp with this sender.\n */\n function getNonce(\n address sender,\n uint192 key\n ) external view returns (uint256 nonce);\n\n /**\n * Manually increment the nonce of the sender.\n * This method is exposed just for completeness..\n * Account does NOT need to call it, neither during validation, nor elsewhere,\n * as the EntryPoint will update the nonce regardless.\n * Possible use-case is call it with various keys to \"initialize\" their nonces to one, so that future\n * UserOperations will not pay extra for the first transaction with a given key.\n */\n function incrementNonce(uint192 key) external;\n}\n" + }, + "contracts/aa-4337/interfaces/IPaymaster.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * the interface exposed by a paymaster contract, who agrees to pay the gas for user's operations.\n * a paymaster must hold a stake to cover the required entrypoint stake and also the gas for the transaction.\n */\ninterface IPaymaster {\n enum PostOpMode {\n opSucceeded, // user op succeeded\n opReverted, // user op reverted. still has to pay for gas.\n postOpReverted //user op succeeded, but caused postOp to revert. Now it's a 2nd call, after user's op was deliberately reverted.\n }\n\n /**\n * payment validation: check if paymaster agrees to pay.\n * Must verify sender is the entryPoint.\n * Revert to reject this request.\n * Note that bundlers will reject this method if it changes the state, unless the paymaster is trusted (whitelisted)\n * The paymaster pre-pays using its deposit, and receive back a refund after the postOp method returns.\n * @param userOp the user operation\n * @param userOpHash hash of the user's request data.\n * @param maxCost the maximum cost of this transaction (based on maximum gas and gas price from userOp)\n * @return context value to send to a postOp\n * zero length to signify postOp is not required.\n * @return validationData signature and time-range of this operation, encoded the same as the return value of validateUserOperation\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validatePaymasterUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 maxCost\n ) external returns (bytes memory context, uint256 validationData);\n\n /**\n * post-operation handler.\n * Must verify sender is the entryPoint\n * @param mode enum with the following options:\n * opSucceeded - user operation succeeded.\n * opReverted - user op reverted. still has to pay for gas.\n * postOpReverted - user op succeeded, but caused postOp (in mode=opSucceeded) to revert.\n * Now this is the 2nd call, after user's op was deliberately reverted.\n * @param context - the context value returned by validatePaymasterUserOp\n * @param actualGasCost - actual gas used so far (without this postOp call).\n */\n function postOp(\n PostOpMode mode,\n bytes calldata context,\n uint256 actualGasCost\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/IStakeManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.12;\n\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by the staked entity.\n */\ninterface IStakeManager {\n event Deposited(address indexed account, uint256 totalDeposit);\n\n event Withdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /// Emitted when stake or unstake delay are modified\n event StakeLocked(\n address indexed account,\n uint256 totalStaked,\n uint256 unstakeDelaySec\n );\n\n /// Emitted once a stake is scheduled for withdrawal\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\n\n event StakeWithdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /**\n * @param deposit the entity's deposit\n * @param staked true if this entity is staked.\n * @param stake actual amount of ether staked for this entity.\n * @param unstakeDelaySec minimum delay to withdraw the stake.\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\n * and the rest fit into a 2nd cell.\n * 112 bit allows for 10^15 eth\n * 48 bit for full timestamp\n * 32 bit allows 150 years for unstake delay\n */\n struct DepositInfo {\n uint112 deposit;\n bool staked;\n uint112 stake;\n uint32 unstakeDelaySec;\n uint48 withdrawTime;\n }\n\n //API struct used by getStakeInfo and simulateValidation\n struct StakeInfo {\n uint256 stake;\n uint256 unstakeDelaySec;\n }\n\n /// @return info - full deposit information of given account\n function getDepositInfo(\n address account\n ) external view returns (DepositInfo memory info);\n\n /// @return the deposit (for gas payment) of the account\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) external payable;\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 _unstakeDelaySec) external payable;\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external;\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external;\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(\n address payable withdrawAddress,\n uint256 withdrawAmount\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/UserOperation.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable no-inline-assembly */\n\nimport {calldataKeccak} from \"../core/Helpers.sol\";\n\n/**\n * User Operation struct\n * @param sender the sender account of this request.\n * @param nonce unique value the sender uses to verify it is not a replay.\n * @param initCode if set, the account contract will be created by this constructor/\n * @param callData the method call to execute on this account.\n * @param callGasLimit the gas limit passed to the callData method call.\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\n * @param maxFeePerGas same as EIP-1559 gas parameter.\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\n */\nstruct UserOperation {\n address sender;\n uint256 nonce;\n bytes initCode;\n bytes callData;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n bytes paymasterAndData;\n bytes signature;\n}\n\n/**\n * Utility functions helpful when working with UserOperation structs.\n */\nlibrary UserOperationLib {\n function getSender(\n UserOperation calldata userOp\n ) internal pure returns (address) {\n address data;\n //read sender from userOp, which is first userOp member (saves 800 gas...)\n assembly {\n data := calldataload(userOp)\n }\n return address(uint160(data));\n }\n\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\n // pay above what he signed for.\n function gasPrice(\n UserOperation calldata userOp\n ) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function pack(\n UserOperation calldata userOp\n ) internal pure returns (bytes memory ret) {\n address sender = getSender(userOp);\n uint256 nonce = userOp.nonce;\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\n bytes32 hashCallData = calldataKeccak(userOp.callData);\n uint256 callGasLimit = userOp.callGasLimit;\n uint256 verificationGasLimit = userOp.verificationGasLimit;\n uint256 preVerificationGas = userOp.preVerificationGas;\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\n\n return\n abi.encode(\n sender,\n nonce,\n hashInitCode,\n hashCallData,\n callGasLimit,\n verificationGasLimit,\n preVerificationGas,\n maxFeePerGas,\n maxPriorityFeePerGas,\n hashPaymasterAndData\n );\n }\n\n function hash(\n UserOperation calldata userOp\n ) internal pure returns (bytes32) {\n return keccak256(pack(userOp));\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n}\n" + }, + "contracts/aa-4337/utils/Exec.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.5 <0.9.0;\n\n// solhint-disable no-inline-assembly\n\n/**\n * Utility functions helpful when making different kinds of contract calls in Solidity.\n */\nlibrary Exec {\n function call(\n address to,\n uint256 value,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := call(\n txGas,\n to,\n value,\n add(data, 0x20),\n mload(data),\n 0,\n 0\n )\n }\n }\n\n function staticcall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal view returns (bool success) {\n assembly {\n success := staticcall(txGas, to, add(data, 0x20), mload(data), 0, 0)\n }\n }\n\n function delegateCall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := delegatecall(\n txGas,\n to,\n add(data, 0x20),\n mload(data),\n 0,\n 0\n )\n }\n }\n\n // get returned data from last call or calldelegate\n function getReturnData(\n uint256 maxLen\n ) internal pure returns (bytes memory returnData) {\n assembly {\n let len := returndatasize()\n if gt(len, maxLen) {\n len := maxLen\n }\n let ptr := mload(0x40)\n mstore(0x40, add(ptr, add(len, 0x20)))\n mstore(ptr, len)\n returndatacopy(add(ptr, 0x20), 0, len)\n returnData := ptr\n }\n }\n\n // revert with explicit byte array (probably reverted info from call)\n function revertWithData(bytes memory returnData) internal pure {\n assembly {\n revert(add(returnData, 32), mload(returnData))\n }\n }\n\n function callAndRevert(\n address to,\n bytes memory data,\n uint256 maxLen\n ) internal {\n bool success = call(to, 0, data, gasleft());\n if (!success) {\n revertWithData(getReturnData(maxLen));\n }\n }\n}\n" + }, + "contracts/Barz.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"./libraries/LibDiamond.sol\";\nimport {IBarz} from \"./interfaces/IBarz.sol\";\n\n/**\n * @title Barz\n * @dev A diamond proxy wallet with a modular & upgradeable architecture\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract Barz is IBarz {\n /**\n * @notice Initializes Barz with the given parameters. Barz account is intended to be created from Barz Factory for stable deployment.\n * @dev This method makes a delegate call to account facet and account facet handles the initialization.\n * With modular architecture, Barz encompasses wide spectrum of architecture and logic.\n * The only requirement is account facet to comply with initialize() interface.\n * Barz doesn't include built-in functions and is a full proxy, for maximum extensibility and modularity.\n * @param _accountFacet Address of Account Facet in charge of the Barz initialization\n * @param _verificationFacet Address of Verification Facet for verifying the signature. Could be any signature scheme\n * @param _entryPoint Address of Entry Point contract\n * @param _facetRegistry Address of Facet Registry. Facet Registry is a registry holding trusted facets that could be added to user's wallet\n * @param _defaultFallBack Address of Default FallBack Handler. Middleware contract for more efficient deployment\n * @param _ownerPublicKey Bytes of Owner Public Key using for initialization\n */\n constructor(\n address _accountFacet,\n address _verificationFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallBack,\n bytes memory _ownerPublicKey\n ) payable {\n bytes memory initCall = abi.encodeWithSignature(\n \"initialize(address,address,address,address,bytes)\",\n _verificationFacet,\n _entryPoint,\n _facetRegistry,\n _defaultFallBack,\n _ownerPublicKey\n );\n (bool success, bytes memory result) = _accountFacet.delegatecall(\n initCall\n );\n if (!success || uint256(bytes32(result)) != 1) {\n revert Barz__InitializationFailure();\n }\n }\n\n /**\n * @notice Fallback function for Barz complying with Diamond Standard with customization of adding Default Fallback Handler\n * @dev Find facet for function that is called and execute the function if a facet is found and return any value.\n */\n fallback() external payable {\n LibDiamond.DiamondStorage storage ds;\n bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION;\n // get diamond storage\n assembly {\n ds.slot := position\n }\n // get facet from function selector\n address facet = address(bytes20(ds.facets[msg.sig]));\n if (facet == address(0))\n facet = ds.defaultFallbackHandler.facetAddress(msg.sig);\n require(facet != address(0), \"Barz: Function does not exist\");\n // Execute external function from facet using delegatecall and return any value.\n assembly {\n // copy function selector and any arguments\n calldatacopy(0, 0, calldatasize())\n // execute function call using the facet\n let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)\n // get any return value\n returndatacopy(0, 0, returndatasize())\n // return any return value or error back to the caller\n switch result\n case 0 {\n revert(0, returndatasize())\n }\n default {\n return(0, returndatasize())\n }\n }\n }\n\n /**\n * @notice Receive function to receive native token without data\n */\n receive() external payable {}\n}\n" + }, + "contracts/BarzFactory.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Barz} from \"./Barz.sol\";\nimport {IBarzFactory} from \"./interfaces/IBarzFactory.sol\";\n\n/**\n * @title Barz Factory\n * @dev Contract to easily deploy Barz to a pre-computed address with a single call\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract BarzFactory is IBarzFactory {\n event BarzDeployed(address);\n\n address public immutable accountFacet;\n address public immutable entryPoint;\n address public immutable facetRegistry;\n address public immutable defaultFallback;\n\n /**\n * @notice Sets the initialization data for Barz contract initialization\n * @param _accountFacet Account Facet to be used to create Barz\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\n * @param _facetRegistry Facet Registry to be used to create Barz\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\n */\n constructor(\n address _accountFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallback\n ) {\n accountFacet = _accountFacet;\n entryPoint = _entryPoint;\n facetRegistry = _facetRegistry;\n defaultFallback = _defaultFallback;\n }\n\n /**\n * @notice Creates the Barz with a single call. It creates the Barz contract with the givent verification facet\n * @param _verificationFacet Address of verification facet used for creating the barz account\n * @param _owner Public Key of the owner to initialize barz account\n * @param _salt Salt used for deploying barz with create2\n * @return barz Instance of Barz contract deployed with the given parameters\n */\n function createAccount(\n address _verificationFacet,\n bytes calldata _owner,\n uint256 _salt\n ) external override returns (Barz barz) {\n address addr = getAddress(_verificationFacet, _owner, _salt);\n uint codeSize = addr.code.length;\n if (codeSize > 0) {\n return Barz(payable(addr));\n }\n barz = new Barz{salt: bytes32(_salt)}(\n accountFacet,\n _verificationFacet,\n entryPoint,\n facetRegistry,\n defaultFallback,\n _owner\n );\n emit BarzDeployed(address(barz));\n }\n\n /**\n * @notice Calculates the address of Barz with the given parameters\n * @param _verificationFacet Address of verification facet used for creating the barz account\n * @param _owner Public Key of the owner to initialize barz account\n * @param _salt Salt used for deploying barz with create2\n * @return barzAddress Precalculated Barz address\n */\n function getAddress(\n address _verificationFacet,\n bytes calldata _owner,\n uint256 _salt\n ) public view override returns (address barzAddress) {\n bytes memory bytecode = getBytecode(\n accountFacet,\n _verificationFacet,\n entryPoint,\n facetRegistry,\n defaultFallback,\n _owner\n );\n bytes32 hash = keccak256(\n abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(bytecode)\n )\n );\n barzAddress = address(uint160(uint256(hash)));\n }\n\n /**\n * @notice Returns the bytecode of Barz with the given parameter\n * @param _accountFacet Account Facet to be used to create Barz\n * @param _verificationFacet Verification Facet to be used to create Barz\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\n * @param _facetRegistry Facet Registry to be used to create Barz\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\n * @param _ownerPublicKey Public Key of owner to be used to initialize Barz ownership\n * @return barzBytecode Bytecode of Barz\n */\n function getBytecode(\n address _accountFacet,\n address _verificationFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallback,\n bytes calldata _ownerPublicKey\n ) public pure override returns (bytes memory barzBytecode) {\n bytes memory bytecode = type(Barz).creationCode;\n barzBytecode = abi.encodePacked(\n bytecode,\n abi.encode(\n _accountFacet,\n _verificationFacet,\n _entryPoint,\n _facetRegistry,\n _defaultFallback,\n _ownerPublicKey\n )\n );\n }\n\n /**\n * @notice Returns the creation code of the Barz contract\n * @return creationCode Creation code of Barz\n */\n function getCreationCode()\n public\n pure\n override\n returns (bytes memory creationCode)\n {\n creationCode = type(Barz).creationCode;\n }\n}\n" + }, + "contracts/facets/AccountFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {UserOperation} from \"../aa-4337/interfaces/UserOperation.sol\";\nimport {IEntryPoint} from \"../aa-4337/interfaces/IEntryPoint.sol\";\nimport {BaseAccount} from \"../aa-4337/core/BaseAccount.sol\";\nimport {LibAppStorage, BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {IFacetRegistry} from \"../infrastructure/interfaces/IFacetRegistry.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {IERC1271} from \"../interfaces/ERC/IERC1271.sol\";\nimport {IAccountFacet} from \"./interfaces/IAccountFacet.sol\";\n\n/**\n * @title Account Facet\n * @dev Account module contract that provides the account features and initialization of signer\n * compatible with EIP-1271 & EIP-4337\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract AccountFacet is BarzStorage, BaseAccount, IAccountFacet {\n using ECDSA for bytes32;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceAccountInitialize();\n }\n\n /**\n * @notice Returns the address of EntryPoint contract registered to Barz account\n */\n function entryPoint() public view override returns (IEntryPoint) {\n return s.entryPoint;\n }\n\n /**\n * @notice Initializes the initial storage of the Barz contract.\n * @dev This method can only be called during the initialization or signature migration.\n * If the proxy contract was created without initialization, anyone can call initialize.\n * Barz calls initialize in constructor in an atomic transaction during deployment\n * @param _verificationFacet Facet contract handling the verificationi\n * @param _anEntryPoint Entrypoint contract defined in EIP-4337 handling the flow of UserOp\n * @param _facetRegistry Registry of Facets that hold all facet information\n * @param _defaultFallBackHandler Middleware contract for default facets\n * @param _ownerPublicKey Bytes of owner public key\n */\n function initialize(\n address _verificationFacet,\n address _anEntryPoint,\n address _facetRegistry,\n address _defaultFallBackHandler,\n bytes calldata _ownerPublicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceAccountInitialize();\n s.entryPoint = IEntryPoint(_anEntryPoint);\n s.facetRegistry = IFacetRegistry(_facetRegistry);\n LibDiamond.diamondStorage().defaultFallbackHandler = IDiamondLoupe(\n _defaultFallBackHandler\n );\n\n _cutDiamondAccountFacet(_verificationFacet);\n\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n _ownerPublicKey\n );\n // Every Verification Facet should comply with initializeSigner(bytes)\n // to be compatible with the Barz contract(for initialization)\n (bool success, bytes memory result) = _verificationFacet.delegatecall(\n initCall\n );\n if (!success || uint256(bytes32(result)) != 1) {\n revert AccountFacet__InitializationFailure();\n }\n\n initSuccess = 1;\n emit AccountInitialized(s.entryPoint, _ownerPublicKey);\n }\n\n function _cutDiamondAccountFacet(address _verificationFacet) internal {\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](1);\n\n bytes4 ownerVerificationFuncSelector = IVerificationFacet(\n _verificationFacet\n ).validateOwnerSignatureSelector();\n\n bytes4[] memory verificationFunctionSelectors = new bytes4[](3);\n verificationFunctionSelectors[0] = IERC1271.isValidSignature.selector;\n verificationFunctionSelectors[1] = ownerVerificationFuncSelector;\n verificationFunctionSelectors[2] = IVerificationFacet.owner.selector;\n cut[0] = IDiamondCut.FacetCut({\n facetAddress: _verificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: verificationFunctionSelectors\n });\n\n LibDiamond.diamondCut(cut, address(0), \"\");\n }\n\n /**\n * @notice Calls the destination with inputted calldata and value from EntryPoint\n * @dev This method executes the calldata coming from the EntryPoint.\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\n * @param _dest Address of destination where the call will be forwarded to\n * @param _value Amount of native coin the owner is willing to send(e.g. ETH, BNB)\n * @param _func Bytes of calldata to execute in the destination address\n */\n function execute(\n address _dest,\n uint256 _value,\n bytes calldata _func\n ) external override onlyWhenUnlocked {\n _requireFromEntryPoint();\n _call(_dest, _value, _func);\n }\n\n /**\n * @notice Batch calls the destination with inputted calldata and value from EntryPoint\n * @dev This method batch executes the calldata coming from the EntryPoint.\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\n * @param _dest Array of addresses of destination where the call will be forwarded to\n * @param _value Array of amount of native coin the owner is willing to send(e.g. ETH, BNB)\n * @param _func Array of bytes of calldata to execute in the destination address\n */\n function executeBatch(\n address[] calldata _dest,\n uint256[] calldata _value,\n bytes[] calldata _func\n ) external override onlyWhenUnlocked {\n _requireFromEntryPoint();\n require(\n _dest.length == _func.length && _dest.length == _value.length,\n \"wrong array lengths\"\n );\n for (uint256 i; i < _dest.length; ) {\n _call(_dest[i], _value[i], _func[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Validates the signature field of UserOperation\n * @dev This method validates if the signature of UserOp is indeed valid by delegating the call to Verification Facet\n * Barz makes a call to the pre-registered Verification Facet address in App Storage\n * @param _userOp UserOperation from owner to be validated\n * @param _userOpHash Hash of UserOperation given from the EntryPoint contract\n */\n function _validateSignature(\n UserOperation calldata _userOp,\n bytes32 _userOpHash\n ) internal override returns (uint256 validationData) {\n // Get Facet with Function Selector\n address facet = LibLoupe.facetAddress(s.validateOwnerSignatureSelector);\n if (facet == address(0))\n revert AccountFacet__NonExistentVerificationFacet();\n\n // Make function call to VerificationFacet\n bytes memory validateCall = abi.encodeWithSelector(\n s.validateOwnerSignatureSelector,\n _userOp,\n _userOpHash\n );\n (bool success, bytes memory result) = facet.delegatecall(validateCall);\n if (!success) revert AccountFacet__CallNotSuccessful();\n validationData = uint256(bytes32(result));\n if (validationData == 0) emit VerificationSuccess(_userOpHash);\n else emit VerificationFailure(_userOpHash);\n }\n\n /**\n * @notice Calls the target with the inputted value and calldata\n * @dev This method is the actual function in Barz that makes a call with an arbitrary owner-given data\n * @param _target Address of the destination contract which the call is getting forwarded to\n * @param _value Amount of Native coin the owner is wanting to make in this call\n * @param _data Calldata the owner is forwarding together in the call e.g. Swap/Token Transfer\n */\n function _call(\n address _target,\n uint256 _value,\n bytes memory _data\n ) internal {\n address facet = LibDiamond.restrictionsFacet();\n // NOTE: No restrictions facet, so restriction validation passes\n if (facet != address(0)) {\n if (_checkRestrictions(facet, _target, _value, _data) == 1)\n revert AccountFacet__RestrictionsFailure();\n }\n\n (bool success, bytes memory result) = _target.call{value: _value}(\n _data\n );\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n }\n\n /**\n * @notice Checks restrictions if the restrictions facet exists\n * @dev This method checks if the restrictions facet exists and makes a verification call to an array of restrictions facet\n * @param _facet Address that holds the restrictions logic\n * @param _target Address the call is getting forwarded to\n * @param _value Amount of native coin the call is sending together with the call\n * @param _data Calldata to trigger execution in target address\n */\n function _checkRestrictions(\n address _facet,\n address _target,\n uint256 _value,\n bytes memory _data\n ) internal returns (uint256 result) {\n bytes memory call = abi.encodeWithSignature(\n \"verifyRestrictions(address,address,uint256,bytes)\",\n address(this),\n _target,\n _value,\n _data\n );\n (bool success, bytes memory response) = _facet.delegatecall(call);\n if (!success) revert AccountFacet__RestrictionsFailure();\n result = uint256(bytes32(response));\n }\n}\n" + }, + "contracts/facets/AccountRecoveryFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibFacetStorage, RecoveryStorage, RecoveryConfig, RecoveryApprovalConfig, ApprovalConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {IAccountRecoveryFacet} from \"./interfaces/IAccountRecoveryFacet.sol\";\n\n/**\n * @title Account Recovery Facet\n * @dev Contract that enables recovery of accounts when owner key is unavailable\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract AccountRecoveryFacet is IAccountRecoveryFacet, Modifiers {\n bytes constant UNINIT_CALL =\n abi.encodeWithSignature(\"uninitializeSigner()\");\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Approve recovery of account as guardian\n * @dev This method can only be called by guardian and guardian inputs the public key of the new owner\n * When the threshold(majority of guardians) passes, it automatically executes account recovery\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function approveAccountRecovery(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + _getApprovalValidationPeriod()\n );\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit RecoveryApproved(\n _recoveryPublicKey,\n msg.sender,\n approvalValidUntil\n );\n if (\n getRecoveryApprovalCountWithTimeValidity(recoveryPublicKeyHash) >=\n LibGuardian.majorityOfGuardians()\n ) _executeRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Revoke recovery of account as guardian\n * @dev This method can only be called by guardian and guardian inputs the public key of the new owner\n When the threshold(majority of guardians) passes, it automatically revokes account recovery when recovery is pending\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function revokeAccountRecoveryApproval(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n if (\n !rs\n .isNewOwnerApproved[recoveryPublicKeyHash][msg.sender].isApproved ||\n !(block.timestamp <\n rs\n .isNewOwnerApproved[recoveryPublicKeyHash][msg.sender]\n .validUntil)\n ) revert AccountRecoveryFacet__NonExistentApproval();\n\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(false, 0);\n emit RecoveryApprovalRevoked(_recoveryPublicKey, msg.sender);\n }\n\n /**\n * @notice Executes recovery with signatures or on-chain pre-approvals\n * @dev This method validates the signatures of guardians or checks the on-chain pre-approved calls to check if the threshold passes\n * When the threshold passes, account recovery is executed and revert otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _guardians Array of guardians address that are approving the recovery of Account\n * @param _signatures Array of signature bytes that signed the approval hash\n */\n function executeRecovery(\n bytes calldata _recoveryPublicKey,\n address[] calldata _guardians,\n bytes[] calldata _signatures\n ) external override {\n if (_isRecoveryPending())\n revert AccountRecoveryFacet__RecoveryAlreadyOngoing();\n if (_guardians.length != _signatures.length)\n revert AccountRecoveryFacet__InvalidArrayLength();\n validateNewOwner(_recoveryPublicKey);\n\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n\n _checkApprover(_guardians);\n _checkDuplicateOnChainApprover(recoveryPublicKeyHash, _guardians);\n\n if (\n _guardians.length +\n getRecoveryApprovalCountWithTimeValidity(\n recoveryPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians()\n ) revert AccountRecoveryFacet__InsufficientGuardians();\n for (uint256 i; i < _guardians.length; ) {\n if (!LibGuardian.isGuardian(_guardians[i]))\n revert AccountRecoveryFacet__InvalidGuardian();\n if (\n !SignatureChecker.isValidSignatureNow(\n _guardians[i],\n recoveryPublicKeyHash,\n _signatures[i]\n )\n ) revert AccountRecoveryFacet__InvalidGuardianSignature();\n unchecked {\n ++i;\n }\n }\n _executeRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Executes recovery of the account. Note that execution and finalization is a different process\n * @dev Executes the recovery and adds recovery data to recovery configuration. Locks the account\n * @param _recoveryPublicKey Public Key of the account for recovery\n */\n function _executeRecovery(bytes memory _recoveryPublicKey) internal {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n ++rs.nonce;\n uint64 executeAfter = uint64(block.timestamp + _getRecoveryPeriod());\n rs.recoveryConfigs[INNER_STRUCT] = RecoveryConfig(\n _recoveryPublicKey,\n executeAfter // NOTE: Remove guardian Count\n );\n LibAppStorage.setLock(\n block.timestamp + _getLockPeriod(),\n AccountRecoveryFacet.executeRecovery.selector\n );\n emit RecoveryExecuted(_recoveryPublicKey, executeAfter);\n }\n\n /**\n * @notice Finalize recovery after recovery pending period. Recovery pending period can be set by user beforehand in SecurityManager\n * @dev This method finalizes recovery and fully changes the ownership of the account to the newly inputted recovery public key\n */\n function finalizeRecovery() external override {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n if (\n uint64(block.timestamp) <=\n rs.recoveryConfigs[INNER_STRUCT].executeAfter\n ) revert AccountRecoveryFacet__RecoveryPeriodNotOver();\n bytes memory recoveryOwner = rs\n .recoveryConfigs[INNER_STRUCT]\n .recoveryPublicKey;\n\n delete rs.recoveryConfigs[INNER_STRUCT];\n\n LibAppStorage.setLock(0, bytes4(0));\n\n LibAppStorage.initiateSignerMigration();\n address verificationFacet = address(\n bytes20(\n LibDiamond.diamondStorage().facets[\n s.validateOwnerSignatureSelector\n ]\n )\n );\n (bool success, bytes memory result) = verificationFacet.delegatecall(\n UNINIT_CALL\n );\n if (!success) revert AccountRecoveryFacet__CallNotSuccesful();\n uint256 validationData = uint256(bytes32(result));\n if (validationData != 1)\n revert AccountRecoveryFacet__SignerUninitializationFailure();\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n recoveryOwner\n );\n (success, result) = verificationFacet.delegatecall(initCall);\n if (!success) revert AccountRecoveryFacet__CallNotSuccesful();\n validationData = uint256(bytes32(result));\n if (validationData != 1)\n revert AccountRecoveryFacet__SignerInitializationFailure();\n LibAppStorage.finalizeSignerMigration();\n emit RecoveryFinalized(recoveryOwner);\n }\n\n /**\n * @notice Approves the cancellation of recovery\n * @dev This method approves the cancellation of recovery when recovery is still pending - waiting for finalization\n * @param _recoveryPublicKey Bytes of public key which is pending for recovery\n */\n function approveCancelRecovery(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"CancelRecovery\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + _getApprovalValidationPeriod()\n );\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit RecoveryCancellationApproved(_recoveryPublicKey, msg.sender);\n if (\n getRecoveryApprovalCountWithTimeValidity(recoveryPublicKeyHash) >=\n LibGuardian.majorityOfGuardians()\n ) {\n _cancelRecovery(_recoveryPublicKey);\n }\n }\n\n /**\n * @notice Hardstops an ongoing recovery\n * @dev This method provides a safety mechanism to protect owners of malicious guardians.\n * Owners can hardstop recovery when an malicious guardians starts the recovery process.\n * @param _signature Signature of the owner that signs the hash to hardstop recovery\n */\n function hardstopRecovery(bytes calldata _signature) external override {\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n \"0\",\n \"HardstopRecovery\"\n );\n if (\n !SignatureChecker.isValidSignatureNow(\n address(this),\n recoveryPublicKeyHash,\n _signature\n )\n ) revert AccountRecoveryFacet__InvalidOwnerSignature();\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n ++rs.nonce;\n delete rs.recoveryConfigs[INNER_STRUCT];\n LibAppStorage.setLock(0, bytes4(0));\n emit RecoveryHardstopped();\n }\n\n /**\n * @notice Cancels recovery with signatures or on-chain pre-approvals\n * @dev This method validates the signatures of guardians or checks the on-chain pre-approved calls to check if the threshold passes\n * When the threshold passes, account recovery is canceled and revert otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _guardians Array of guardians address that are approving the recovery of Account\n * @param _signatures Array of signature bytes that signed the cancellation approval hash\n */\n function cancelRecovery(\n bytes calldata _recoveryPublicKey,\n address[] calldata _guardians,\n bytes[] calldata _signatures\n ) external override {\n if (_guardians.length != _signatures.length)\n revert AccountRecoveryFacet__InvalidArrayLength();\n validateNewOwner(_recoveryPublicKey);\n\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"CancelRecovery\"\n );\n\n _checkApprover(_guardians);\n _checkDuplicateOnChainApprover(recoveryPublicKeyHash, _guardians);\n\n if (\n _guardians.length +\n getRecoveryApprovalCountWithTimeValidity(\n recoveryPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians()\n ) revert AccountRecoveryFacet__InsufficientGuardians();\n for (uint256 i; i < _guardians.length; ) {\n if (!LibGuardian.isGuardian(_guardians[i]))\n revert AccountRecoveryFacet__CallerNotGuardian();\n if (\n !SignatureChecker.isValidSignatureNow(\n _guardians[i],\n recoveryPublicKeyHash,\n _signatures[i]\n )\n ) revert AccountRecoveryFacet__InvalidGuardianSignature();\n unchecked {\n ++i;\n }\n }\n _cancelRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Cancel recovery when the recovery is pending. Unlock the account as well\n * @dev This method checks if the recovery is pending and reverts if not pending.\n * It increases the recovery nonce and deletes the recovery information and gets a small portion of gas in return\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function _cancelRecovery(bytes memory _recoveryPublicKey) internal {\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n LibAppStorage.setLock(0, bytes4(0));\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n ++rs.nonce;\n delete rs.recoveryConfigs[INNER_STRUCT];\n emit RecoveryCanceled(_recoveryPublicKey);\n }\n\n /**\n * @notice Validates the format of public key to be used for recovery\n * @dev This method checks if the public key format is correct and reverts otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function validateNewOwner(bytes memory _recoveryPublicKey) public view {\n if (\n !IVerificationFacet(\n LibLoupe.facetAddress(s.validateOwnerSignatureSelector)\n ).isValidKeyType(_recoveryPublicKey)\n ) revert AccountRecoveryFacet__InvalidRecoveryPublicKey();\n }\n\n /**\n * @notice Checks if recovery is currently pending\n * @return isPending Boolean indicating if recovery is pending\n */\n function _isRecoveryPending() internal view returns (bool isPending) {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n isPending = (rs.recoveryConfigs[INNER_STRUCT].executeAfter > 0);\n }\n\n /**\n * @notice Calculate the recovery hash dependent on chain, wallet address, nonce with EIP-191 prefix for safety\n * @dev Returns the keccak256 hash of EIP-191 msg hash packed with public key, salt, nonce, wallet address, etc\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _saltString Salt string to uniquely identify each recovery hash and for security\n * @return recoveryKeyHash Bytes32 string of the recovery hash\n */\n function getApprovalRecoveryKeyHash(\n bytes memory _recoveryPublicKey,\n string memory _saltString\n ) public view override returns (bytes32 recoveryKeyHash) {\n recoveryKeyHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n _recoveryPublicKey,\n _saltString,\n address(this),\n block.chainid,\n LibFacetStorage.recoveryStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Check the onchain approval of guardians and returns the number of guardians that approved\n * @dev Loop through the guardian addresses and returns the number of guardians that approved this recovery hash\n * @param _recoveryPublicKeyHash Bytes hash of newly recovered public key and recovery value of the account\n * @return approvalCount Number of guardians that approved\n */\n function getRecoveryApprovalCountWithTimeValidity(\n bytes32 _recoveryPublicKeyHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n for (uint256 i; i < guardianLength; ) {\n if (isRecoveryApproved(_recoveryPublicKeyHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Checks if the recovery is approved by the given approver\n * @param _recoveryPublicKeyHash Hash of the public key and configuration for recovery\n * @param _approver Address of approver\n * @return isApproved Bool value if recovery hash is approved\n */\n function isRecoveryApproved(\n bytes32 _recoveryPublicKeyHash,\n address _approver\n ) public view override returns (bool isApproved) {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n if (\n rs\n .isNewOwnerApproved[_recoveryPublicKeyHash][_approver].isApproved &&\n block.timestamp <\n rs.isNewOwnerApproved[_recoveryPublicKeyHash][_approver].validUntil\n ) {\n isApproved = true;\n }\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _recoveryPublicKeyHash Hash of recovery information\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _recoveryPublicKeyHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isRecoveryApproved(_recoveryPublicKeyHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert AccountRecoveryFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the lock period of this wallet address from security manager\n * @return lockPeriod value of lock period\n */\n function _getLockPeriod() internal view returns (uint256 lockPeriod) {\n lockPeriod = securityManager.lockPeriodOf(address(this));\n if (lockPeriod == 0) revert AccountRecoveryFacet__InvalidLockPeriod();\n }\n\n /**\n * @notice Returns the lock period of this wallet address from security manager\n * @return recoveryPeriod value of recovery period\n */\n function _getRecoveryPeriod()\n internal\n view\n returns (uint256 recoveryPeriod)\n {\n recoveryPeriod = securityManager.recoveryPeriodOf(address(this));\n if (recoveryPeriod == 0)\n revert AccountRecoveryFacet__InvalidRecoveryPeriod();\n }\n\n /**\n * @notice Returns the approval validation period of this wallet address from security manager\n * @return approvalValidationPeriod value of approval validation period\n */\n function _getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod == 0)\n revert AccountRecoveryFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the recovery nonce of this wallet address from security manager\n * @return nonce value of recovery nonce\n */\n function getRecoveryNonce() public view override returns (uint128 nonce) {\n nonce = LibFacetStorage.recoveryStorage().nonce;\n }\n\n /**\n * @notice Returns the recovery information of the pending recovery\n * @return recoveryConfig value struct of pending recovery\n */\n function getPendingRecovery()\n public\n view\n override\n returns (RecoveryConfig memory recoveryConfig)\n {\n recoveryConfig = LibFacetStorage.recoveryStorage().recoveryConfigs[\n INNER_STRUCT\n ];\n }\n}\n" + }, + "contracts/facets/base/DiamondCutFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibGuardian} from \"../../libraries/LibGuardian.sol\";\nimport {ISecurityManager} from \"../../infrastructure/interfaces/ISecurityManager.sol\";\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibFacetStorage, DiamondCutApprovalConfig, ApprovalConfig} from \"../../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"../Modifiers.sol\";\nimport {IDiamondCut} from \"./interfaces/IDiamondCut.sol\";\n\n/**\n * @title DiamondCut Facet\n * @dev Responsible for adding/removing/replace facets in Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DiamondCutFacet is Modifiers, IDiamondCut {\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Updates the flag for the interfaceId\n * @param _interfaceId InterfaceID to update the mapping\n * @param _flag Bool value to update the mapping of the given interface ID\n */\n function updateSupportsInterface(\n bytes4 _interfaceId,\n bool _flag\n ) external override onlyWhenUnlocked {\n LibDiamond.enforceIsSelf();\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId] = _flag;\n emit SupportsInterfaceUpdated(_interfaceId, _flag);\n }\n\n /**\n * @notice Add/replace/remove any number of functions and optionally execute\n * a function with delegatecall when guardians don't exist\n * @param _diamondCut Contains the facet addresses and function selectors\n * @param _init The address of the contract or facet to execute _calldata. It's prohibited in Barz\n */\n function diamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata\n ) external override onlyWhenUnlocked {\n LibDiamond.enforceIsSelf();\n\n _checkFacetCutValidity(_diamondCut);\n // require approval from guardian if guardian exists\n if (0 != LibGuardian.guardianCount())\n revert DiamondCutFacet__InvalidRouteWithGuardian();\n if (address(0) != _init) revert DiamondCutFacet__InvalidInitAddress();\n\n ++LibFacetStorage.diamondCutStorage().nonce;\n LibDiamond.diamondCut(_diamondCut, address(0), \"\");\n }\n\n /**\n * @notice Add/replace/remove any number of functions and optionally execute\n * a function with delegatecall when guardians exist\n * @param _diamondCut Contains the facet addresses and function selectors\n * @param _approvers Guardian or owner address that approves the diamond cut\n * @param _signatures Signature of Guardians or owner that approves the diamond cut\n */\n function diamondCutWithGuardian(\n FacetCut[] calldata _diamondCut,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n ) external override onlyWhenUnlocked {\n if (_approvers.length != _signatures.length)\n revert DiamondCutFacet__InvalidArrayLength();\n _checkFacetCutValidity(_diamondCut);\n if (0 == LibGuardian.guardianCount())\n revert DiamondCutFacet__InvalidRouteWithGuardian();\n\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(cutHash, _approvers);\n\n bool onChainOwnerApproval = getOwnerCutApprovalWithTimeValidity(\n cutHash\n );\n\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n if (\n _approvers.length +\n getDiamondCutApprovalCountWithTimeValidity(cutHash) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert DiamondCutFacet__InsufficientApprovers();\n\n bool ownerApproved;\n for (uint256 i; i < _approvers.length; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n _approvers[i] != address(this)\n ) revert DiamondCutFacet__InvalidApprover();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert DiamondCutFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n cutHash,\n _signatures[i]\n )\n ) revert DiamondCutFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n if (!ownerApproved && !onChainOwnerApproval)\n revert DiamondCutFacet__LackOfOwnerApproval();\n\n ++LibFacetStorage.diamondCutStorage().nonce;\n LibDiamond.diamondCut(_diamondCut, address(0), \"\");\n }\n\n /**\n * @notice Approves diamond cut. This can only be called directly from guardian or owner\n * @param _diamondCut Contains the facet addresses and function selectors\n */\n function approveDiamondCut(\n FacetCut[] calldata _diamondCut\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\n if (LibGuardian.guardianCount() == 0)\n revert DiamondCutFacet__InvalidRouteWithoutGuardian();\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n _checkFacetCutValidity(_diamondCut);\n\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(\n true,\n approvalValidUntil\n );\n emit DiamondCutApproved(_diamondCut);\n if (\n (getDiamondCutApprovalCountWithTimeValidity(cutHash) >=\n LibGuardian.majorityOfGuardians()) &&\n getOwnerCutApprovalWithTimeValidity(cutHash)\n ) {\n ++LibFacetStorage.diamondCutStorage().nonce;\n LibDiamond.diamondCut(_diamondCut, address(0), \"\");\n }\n }\n\n /**\n * @notice Revokes the approval of diamond cut. This can only be called directly from guardian or owner\n * @param _diamondCut Contains the facet addresses and function selectors\n */\n function revokeDiamondCutApproval(\n FacetCut[] calldata _diamondCut\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\n if (!ds.isDiamondCutApproved[cutHash][msg.sender].isApproved)\n revert DiamondCutFacet__CannotRevokeUnapproved();\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(false, 0);\n emit DiamondCutApprovalRevoked(_diamondCut);\n }\n\n /**\n * @notice Gets the number of approvals of diamond cut from guardians\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n */\n function getDiamondCutApprovalCountWithTimeValidity(\n bytes32 _diamondCutHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardiansLength = guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n if (isCutApproved(_diamondCutHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n return approvalCount;\n }\n\n /**\n * @notice Returns if the owner has approved the diamond cut\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @return isApprovedByOwner Bool value showing if the owner approved the cut\n */\n function getOwnerCutApprovalWithTimeValidity(\n bytes32 _diamondCutHash\n ) public view override returns (bool isApprovedByOwner) {\n isApprovedByOwner = isCutApproved(_diamondCutHash, address(this));\n }\n\n /**\n * @notice Returns if the given approver has approved the diamond cut\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @param _approver Address of approver\n * @return isApproved Bool value showing if the approver approved the cut\n */\n function isCutApproved(\n bytes32 _diamondCutHash,\n address _approver\n ) public view override returns (bool isApproved) {\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n isApproved = (ds\n .isDiamondCutApproved[_diamondCutHash][_approver].isApproved &&\n block.timestamp <\n ds.isDiamondCutApproved[_diamondCutHash][_approver].validUntil);\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _diamondCutHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isCutApproved(_diamondCutHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert DiamondCutFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the diamond cut hash. This function ensures that this hash is safe from replay attack by including\n * salt, address, chainId, and nonce, etc.\n * @param _diamondCut Contains the facet addresses and function selectors\n * @return cutHash Diamond Cut Hash\n */\n function getDiamondCutHash(\n FacetCut[] calldata _diamondCut\n ) public view override returns (bytes32 cutHash) {\n cutHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n keccak256(abi.encode(_diamondCut)),\n address(this),\n block.chainid,\n LibFacetStorage.diamondCutStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Returns the approval validation Period\n * @dev This method fetches the validation period from the security manager\n * @return approvalValidationPeriod Approval validation period of Barz contract fetched from security manager\n */\n function getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod <= 0)\n revert DiamondCutFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the diamond cut nonce of this wallet\n * @dev This method fetches the nonce from diamond cut storage\n * @return cutNonce Nonce of diamond cut to protect from reply attacks\n */\n function getDiamondCutNonce()\n public\n view\n override\n returns (uint128 cutNonce)\n {\n cutNonce = LibFacetStorage.diamondCutStorage().nonce;\n }\n}\n" + }, + "contracts/facets/base/DiamondLoupeFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {IERC165} from \"../../interfaces/ERC/IERC165.sol\";\nimport {IERC1271} from \"../../interfaces/ERC/IERC1271.sol\";\nimport {IERC677Receiver} from \"../../interfaces/ERC/IERC677Receiver.sol\";\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC1155Receiver} from \"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\";\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../../libraries/LibLoupe.sol\";\nimport {LibUtils} from \"../../libraries/LibUtils.sol\";\nimport {IDiamondCut} from \"../../facets/base/interfaces/IDiamondCut.sol\";\nimport {IStorageLoupe} from \"./interfaces/IStorageLoupe.sol\";\nimport {IDiamondLoupe} from \"./interfaces/IDiamondLoupe.sol\";\n\n/**\n * @title DiamondLoupe Facet\n * @dev DiamondLoupe contract compatible with EIP-2535\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DiamondLoupeFacet is IDiamondLoupe, IStorageLoupe, IERC165 {\n // Diamond Loupe Functions\n ////////////////////////////////////////////////////////////////////\n /// These functions are expected to be called frequently by tools off-chain.\n\n /**\n * @notice Gets all facets and their selectors.\n * @dev Barz uses a special architecture called default fallback handler. Default Fallback handler is used as a middleware\n * that holds the mapping of facet function selector and facet address that Barz uses. This helps Barz to reduce\n * significant amount of gas during the initialization process.\n * Hence, this method aggregates both the facet information from DefaulFallbackHandler and in diamond storage and shows the data to users.\n * @return facets_ Facet\n */\n function facets() public view override returns (Facet[] memory facets_) {\n Facet[] memory defaultFacet = LibDiamond\n .diamondStorage()\n .defaultFallbackHandler\n .facets();\n Facet[] memory _facets = LibLoupe.facets();\n uint256 numFacets = _facets.length;\n bytes4[] memory keys;\n address[] memory values;\n for (uint256 i; i < numFacets; ) {\n uint256 selectorsLength = _facets[i].functionSelectors.length;\n for (uint256 j; j < selectorsLength; ) {\n (keys, values) = LibUtils.setValue(\n keys,\n values,\n _facets[i].functionSelectors[j],\n _facets[i].facetAddress\n );\n unchecked {\n ++j;\n }\n }\n unchecked {\n ++i;\n }\n }\n {\n bool iIncrement;\n for (uint256 i; i < defaultFacet.length; ) {\n bool jIncrement;\n for (\n uint256 j;\n j < defaultFacet[i].functionSelectors.length;\n\n ) {\n if (\n LibUtils.getValue(\n keys,\n values,\n defaultFacet[i].functionSelectors[j]\n ) != address(0)\n ) {\n if (defaultFacet[i].functionSelectors.length == 1) {\n defaultFacet = LibUtils.removeFacetElement(\n defaultFacet,\n i\n );\n iIncrement = true;\n break;\n }\n defaultFacet[i].functionSelectors = LibUtils\n .removeElement(\n defaultFacet[i].functionSelectors,\n j\n );\n jIncrement = true;\n }\n if (!jIncrement) {\n unchecked {\n ++j;\n }\n } else {\n jIncrement = false;\n }\n }\n if (!iIncrement) {\n unchecked {\n ++i;\n }\n } else {\n iIncrement = false;\n }\n }\n }\n {\n uint256 facetLength = numFacets + defaultFacet.length;\n facets_ = new Facet[](facetLength);\n uint256 defaultFacetIndex;\n for (uint256 i; i < facetLength; ) {\n if (i < numFacets) {\n facets_[i] = _facets[i];\n bool jIncrementor;\n for (uint256 j; j < defaultFacet.length; ) {\n if (\n facets_[i].facetAddress ==\n defaultFacet[j].facetAddress\n ) {\n facets_[i].functionSelectors = LibUtils.mergeArrays(\n _facets[i].functionSelectors,\n defaultFacet[j].functionSelectors\n );\n defaultFacet = LibUtils.removeFacetElement(\n defaultFacet,\n j\n );\n jIncrementor = true;\n {\n facets_ = LibUtils.removeFacetElement(\n facets_,\n facets_.length - 1\n );\n }\n --facetLength;\n }\n if (!jIncrementor) {\n unchecked {\n ++j;\n }\n } else {\n jIncrementor = false;\n }\n }\n } else {\n facets_[i] = defaultFacet[defaultFacetIndex];\n ++defaultFacetIndex;\n }\n unchecked {\n ++i;\n }\n }\n }\n }\n\n /**\n * @notice Gets all the function selectors provided by a facet.\n * @param _facet The facet address.\n * @return facetFunctionSelectors_\n */\n function facetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n Facet[] memory facet = facets();\n uint256 facetLength = facet.length;\n for (uint256 i; i < facetLength; ) {\n if (facet[i].facetAddress == _facet)\n return facet[i].functionSelectors;\n unchecked {\n ++i;\n }\n }\n return facetFunctionSelectors_;\n }\n\n /**\n * @notice Get all the facet addresses used by Barz.\n * @return facetAddresses_\n */\n function facetAddresses()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n Facet[] memory facet = facets();\n uint256 facetLength = facet.length;\n facetAddresses_ = new address[](facetLength);\n for (uint256 i; i < facetLength; ) {\n facetAddresses_[i] = facet[i].facetAddress;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Gets the facet that supports the given selector.\n * @dev If facet is not found return address(0).\n * @param _functionSelector The function selector.\n * @return facetAddress_ The facet address.\n */\n function facetAddress(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n\n facetAddress_ = address(bytes20(ds.facets[_functionSelector]));\n if (facetAddress_ == address(0)) {\n facetAddress_ = IDiamondLoupe(ds.defaultFallbackHandler)\n .facetAddress(_functionSelector);\n }\n }\n\n /**\n * @notice SupportInterface to be compatible with EIP 165\n * @param _interfaceId Interface ID for detecting the interface\n * @return isSupported Bool value showing if the standard is supported in the contract\n */\n function supportsInterface(\n bytes4 _interfaceId\n ) external view override returns (bool isSupported) {\n isSupported =\n _interfaceId == type(IERC165).interfaceId ||\n _interfaceId == IDiamondCut.diamondCut.selector ||\n _interfaceId == type(IDiamondLoupe).interfaceId ||\n _interfaceId == type(IERC1155Receiver).interfaceId ||\n _interfaceId == type(IERC721Receiver).interfaceId ||\n _interfaceId == type(IERC777Recipient).interfaceId ||\n _interfaceId == IERC1271.isValidSignature.selector ||\n _interfaceId == type(IERC677Receiver).interfaceId ||\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId];\n }\n\n /**\n * @notice Returns the facet from the diamond storage. This excludes the facets from the default fallback handler\n * @return facets_ Facet information attached directly to diamond storage\n */\n function facetsFromStorage()\n external\n view\n override\n returns (Facet[] memory facets_)\n {\n facets_ = LibLoupe.facets();\n }\n\n /**\n * @notice Returns the facet address attached to the given function selector. This excludes the facets from the default fallback handler\n * @param _functionSelector Function selector to fetch the facet address from diamond storage\n * @return facetAddress_ Facet address mapped with the function selector\n */\n function facetAddressFromStorage(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n facetAddress_ = LibLoupe.facetAddress(_functionSelector);\n }\n\n /**\n * @notice Returns all facet addresses attached directly to diamond storage. This excludes the facets from the default fallback handler\n * @return facetAddresses_ All facet addresses attached directly to diamond storage\n */\n function facetAddressesFromStorage()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n facetAddresses_ = LibLoupe.facetAddresses();\n }\n\n /**\n * @notice Returns function selectors of given facet address attached directly to diamond storage. This excludes the facets from the default fallback handler\n * @param _facet Facet address to fetch the facet function selectors from diamond storage\n * @return facetFunctionSelectors_ Facet function selectors of the given facet address\n */\n function facetFunctionSelectorsFromStorage(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n facetFunctionSelectors_ = LibLoupe.facetFunctionSelectors(_facet);\n }\n}\n" + }, + "contracts/facets/base/interfaces/IDiamondCut.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title DiamondCut Facet Interface\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IDiamondCut {\n error DiamondCutFacet__InvalidRouteWithGuardian();\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\n error DiamondCutFacet__InvalidArrayLength();\n error DiamondCutFacet__InsufficientApprovers();\n error DiamondCutFacet__InvalidApprover();\n error DiamondCutFacet__InvalidApproverSignature();\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\n error DiamondCutFacet__CannotRevokeUnapproved();\n error DiamondCutFacet__LackOfOwnerApproval();\n error DiamondCutFacet__OwnerAlreadyApproved();\n error DiamondCutFacet__DuplicateApproval();\n error DiamondCutFacet__InvalidInitAddress();\n\n event DiamondCutApproved(FacetCut[] diamondCut);\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\n\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\n\n enum FacetCutAction {\n Add,\n Replace,\n Remove\n }\n // Add=0, Replace=1, Remove=2\n\n struct FacetCut {\n address facetAddress;\n FacetCutAction action;\n bytes4[] functionSelectors;\n }\n\n /// @notice Add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param diamondCut Contains the facet addresses and function selectors\n /// @param init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function diamondCut(\n FacetCut[] calldata diamondCut,\n address init,\n bytes calldata _calldata\n ) external;\n\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\n\n function diamondCutWithGuardian(\n FacetCut[] calldata diamondCut,\n address[] calldata approvers,\n bytes[] calldata signatures\n ) external;\n\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\n\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\n\n function getDiamondCutApprovalCountWithTimeValidity(\n bytes32 diamondCutHash\n ) external view returns (uint256);\n\n function getOwnerCutApprovalWithTimeValidity(\n bytes32 diamondCutHash\n ) external view returns (bool);\n\n function isCutApproved(\n bytes32 diamondCutHash,\n address approver\n ) external view returns (bool);\n\n function getDiamondCutHash(\n FacetCut[] calldata diamondCut\n ) external view returns (bytes32);\n\n function getDiamondCutNonce() external view returns (uint128);\n}\n" + }, + "contracts/facets/base/interfaces/IDiamondLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n// A loupe is a small magnifying glass used to look at diamonds.\n// These functions look at diamonds\ninterface IDiamondLoupe {\n /// These functions are expected to be called frequently\n /// by tools.\n\n struct Facet {\n address facetAddress;\n bytes4[] functionSelectors;\n }\n\n /// @notice Gets all facet addresses and their four byte function selectors.\n /// @return facets_ Facet\n function facets() external view returns (Facet[] memory facets_);\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n /// @return facetFunctionSelectors_\n function facetFunctionSelectors(\n address _facet\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses()\n external\n view\n returns (address[] memory facetAddresses_);\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(\n bytes4 _functionSelector\n ) external view returns (address facetAddress_);\n}\n" + }, + "contracts/facets/base/interfaces/IStorageLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"./IDiamondLoupe.sol\";\n\n/**\n * @title LoupeFromStorage Interface\n * @dev Interface contract to function as a loupe facet directly attached to diamond storage of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IStorageLoupe {\n /// These functions are expected to be called frequently\n /// by tools.\n\n /// @notice Gets all facet addresses and their four byte function selectors.\n /// @return facets_ Facet\n function facetsFromStorage()\n external\n view\n returns (IDiamondLoupe.Facet[] memory);\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n function facetFunctionSelectorsFromStorage(\n address _facet\n ) external view returns (bytes4[] memory);\n\n /// @notice Get all the facet addresses used by a diamond.\n function facetAddressesFromStorage()\n external\n view\n returns (address[] memory);\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n function facetAddressFromStorage(\n bytes4 _functionSelector\n ) external view returns (address);\n}\n" + }, + "contracts/facets/GuardianFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibFacetStorage, GuardianStorage, StorageConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IGuardianFacet} from \"./interfaces/IGuardianFacet.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Guardian Facet\n * @dev Contract that enables addition/removal of guardians from Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract GuardianFacet is IGuardianFacet {\n ISecurityManager public immutable securityManager;\n uint8 public constant INNER_STRUCT = 0;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Add guardians to Barz.\n * @dev This method internally calls addGuardian which checks the validity of guardian address and adds\n * as guardian if valid\n * @param _guardians Array of addresses to add as guardian\n */\n function addGuardians(address[] calldata _guardians) external override {\n LibDiamond.enforceIsSelf();\n for (uint256 i; i < _guardians.length; ) {\n addGuardian(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Add a guardian to Barz.\n * @dev This method checks if the function is called by the owner and validates the address of guardian\n * When the validation passes, guardian address is added to the pending state waiting for confirmation\n * @param _guardian Address to add as guardian\n */\n function addGuardian(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (_guardian == address(this))\n revert GuardianFacet__GuardianCannotBeSelf();\n if (isGuardian(_guardian)) revert GuardianFacet__DuplicateGuardian();\n if (_guardian == address(0))\n revert GuardianFacet__ZeroAddressGuardian();\n if (\n keccak256(abi.encodePacked(_guardian)) ==\n keccak256(IVerificationFacet(address(this)).owner())\n ) revert GuardianFacet__OwnerCannotBeGuardian();\n\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n if (\n gs.pending[id] != 0 ||\n block.timestamp <= gs.pending[id] + getSecurityWindow()\n ) revert GuardianFacet__DuplicateGuardianAddition();\n\n uint256 securityPeriod = getAdditionSecurityPeriod();\n gs.pending[id] = block.timestamp + securityPeriod;\n emit GuardianAdditionRequested(\n _guardian,\n block.timestamp + securityPeriod\n );\n }\n\n /**\n * @notice Remove guardians from Barz.\n * @dev This method internally calls removeGuardian which checks the validity of guardian and removes\n * guardian when the request is valid\n * @param _guardians Array of addresses to be removed\n */\n function removeGuardians(address[] calldata _guardians) external override {\n LibDiamond.enforceIsSelf();\n for (uint256 i; i < _guardians.length; ) {\n removeGuardian(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Remove a guardian from Barz.\n * @dev This method validates if the guardian to be removed is a guardian and puts the guardian removal\n * to a pending state waiting to be confirmed.\n * @param _guardian Address of guardian to be removed\n */\n function removeGuardian(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n if (!isGuardian(_guardian)) revert GuardianFacet__NonExistentGuardian();\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n if (\n gs.pending[id] != 0 ||\n block.timestamp <= gs.pending[id] + getSecurityWindow()\n ) revert GuardianFacet__DuplicateGuardianRemoval();\n\n uint256 securityPeriod = getRemovalSecurityPeriod();\n gs.pending[id] = block.timestamp + securityPeriod;\n emit GuardianRemovalRequested(\n _guardian,\n block.timestamp + securityPeriod\n );\n }\n\n /**\n * @notice Confirm addition of guardians\n * @dev This method internally calls confirmGuardianAddition which checks the validity of pending request.\n * Guardians are fully added when they pass the validation. Anyone can call this function.\n * @param _guardians Array of guardian addresses to be added\n */\n function confirmGuardianAdditions(\n address[] calldata _guardians\n ) external override {\n for (uint256 i; i < _guardians.length; ) {\n confirmGuardianAddition(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Confirm addition of a guardian\n * @dev This method checks the validity of pending request.\n * Guardians are fully added when they pass the validation. Anyone can call this function.\n * @param _guardian Guardian address to be added\n */\n function confirmGuardianAddition(address _guardian) public override {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingAddition();\n if (gs.pending[id] >= block.timestamp)\n revert GuardianFacet__PendingAdditionNotOver();\n if (block.timestamp >= gs.pending[id] + getSecurityWindow())\n revert GuardianFacet__PendingAdditionExpired();\n\n _addGuardian(_guardian);\n\n delete gs.pending[id];\n emit GuardianAdded(_guardian);\n }\n\n /**\n * @notice Confirm removal of guardians\n * @dev This method internally calls confirmGuardianRemoval to check the validity guardian removal confirmation.\n * Guardians are fully removed when they pass the validation. Anyone can call this function.\n * @param _guardians Array of guardian addresses to be removed\n */\n function confirmGuardianRemovals(\n address[] calldata _guardians\n ) external override {\n for (uint256 i; i < _guardians.length; ) {\n confirmGuardianRemoval(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Confirm removal of a guardian\n * @dev This method checks the validity guardian removal confirmation.\n * Guardian is fully removed when they pass the validation. Anyone can call this function.\n * @param _guardian Guardian address to be removed\n */\n function confirmGuardianRemoval(address _guardian) public override {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingRemoval();\n if (gs.pending[id] >= block.timestamp)\n revert GuardianFacet__PendingRemovalNotOver();\n if (block.timestamp >= gs.pending[id] + getSecurityWindow())\n revert GuardianFacet__PendingAdditionExpired();\n\n _removeGuardian(_guardian);\n delete gs.pending[id];\n emit GuardianRemoved(_guardian);\n }\n\n /**\n * @notice Cancel pending guardian addition\n * @dev This method checks if the previous request for guardian request exists.\n * It reverts if previous request is not pending and cancels the addition otherwise.\n * @param _guardian Guardian address to be canceled from addition\n */\n function cancelGuardianAddition(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingAddition();\n delete gs.pending[id];\n emit GuardianAdditionCancelled(_guardian);\n }\n\n /**\n * @notice Cancel pending guardian removal\n * @dev This method checks if the previous request for guardian request exists.\n * It reverts if previous request is not pending and cancels the removal otherwise.\n * @param _guardian Guardian address to be canceled from removal\n */\n function cancelGuardianRemoval(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingRemoval();\n delete gs.pending[id];\n emit GuardianRemovalCancelled(_guardian);\n }\n\n /**\n * @notice Get the addition security period of current account from security manager\n * @dev This method returns the uint value if addition security period\n * @return additionSecurityPeriod Uint256 value of addition security period\n */\n function getAdditionSecurityPeriod()\n public\n view\n override\n returns (uint256 additionSecurityPeriod)\n {\n additionSecurityPeriod = securityManager.additionSecurityPeriodOf(\n address(this)\n );\n if (additionSecurityPeriod == 0)\n revert GuardianFacet__InvalidAdditionSecurityPeriod();\n }\n\n /**\n * @notice Get the removal security period of current account from security manager\n * @dev This method returns the uint value if removal security period\n * @return removalSecurityPeriod Uint256 value of removal security period\n */\n function getRemovalSecurityPeriod()\n public\n view\n override\n returns (uint256 removalSecurityPeriod)\n {\n removalSecurityPeriod = securityManager.removalSecurityPeriodOf(\n address(this)\n );\n if (removalSecurityPeriod == 0)\n revert GuardianFacet__InvalidRemovalSecurityPeriod();\n }\n\n /**\n * @notice Get the security window of current account from security manager\n * @dev This method returns the uint value if security window\n * @return securityWindow Uint256 value of removal security period\n */\n function getSecurityWindow()\n public\n view\n override\n returns (uint256 securityWindow)\n {\n securityWindow = securityManager.securityWindowOf(address(this));\n if (securityWindow == 0) revert GuardianFacet__InvalidSecurityWindow();\n }\n\n /**\n * @notice Checks if the addition of the given guardian address is pending\n * @dev This method returns the bool value of whether the guardian address is pending addition\n * @return isPending Bool value of representing the pending of guardian addition\n */\n function isAdditionPending(\n address _guardian\n ) public view override returns (bool isPending) {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n isPending = _isPending(id);\n }\n\n /**\n * @notice Checks if the removal of the given guardian address is pending\n * @dev This method returns the bool value of whether the guardian address is pending removal\n * @return isPending Bool value of representing the pending of guardian removal\n */\n function isRemovalPending(\n address _guardian\n ) public view override returns (bool isPending) {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n isPending = _isPending(id);\n }\n\n /**\n * @notice Checks if the given hash is pending\n * @dev This method returns the bool value whether the hash is pending\n * @return isPending Bool value of representing the pending of guardian operation\n */\n function _isPending(\n bytes32 _idHash\n ) internal view returns (bool isPending) {\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n isPending = ((gs.pending[_idHash] > 0 &&\n gs.pending[_idHash] < block.timestamp) &&\n block.timestamp < gs.pending[_idHash] + getSecurityWindow());\n }\n\n /**\n * @notice Adds guardian to storage config. This is called when guardian is fully added.\n * @dev This method add guardian address and config information to Facet Storage dedicated for guardian\n * When this function is called, guardian is fully added to this Barz Smart Account\n * @param _guardian Address of guardian to be added\n */\n function _addGuardian(address _guardian) internal {\n if (!isAdditionPending(_guardian))\n revert GuardianFacet__InvalidGuardianAddition();\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n if (config.info[_guardian].exists)\n revert GuardianFacet__AlreadyExists();\n\n config.info[_guardian].exists = true;\n config.info[_guardian].index = uint128(config.addresses.length);\n config.addresses.push(_guardian);\n }\n\n /**\n * @notice Removes guardian to storage config. This is called when guardian is fully removed.\n * @dev This method remove guardian address and config information to Facet Storage dedicated for guardian\n * When this function is called, guardian is fully removed from this Barz Smart Account\n * @param _guardian Address of guardian to be removed\n */\n function _removeGuardian(address _guardian) internal {\n if (!isRemovalPending(_guardian))\n revert GuardianFacet__InvalidGuardianRemoval();\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n if (!config.info[_guardian].exists)\n revert GuardianFacet__NonExistentGuardian();\n\n address lastAddress = config.addresses[config.addresses.length - 1];\n if (_guardian != lastAddress) {\n uint128 targetIndex = config.info[_guardian].index;\n config.addresses[targetIndex] = lastAddress;\n config.info[lastAddress].index = targetIndex;\n }\n config.addresses.pop();\n delete config.info[_guardian];\n\n emit GuardianRemoved(_guardian);\n }\n\n /**\n * @notice Reads guardian storage and fetches the addresses into an array from the storage\n * @dev This method fetches the guardian storage and returns the list of guardian addresses\n * @return addresses Array of addresses comprised of guardian\n */\n function getGuardians()\n public\n view\n override\n returns (address[] memory addresses)\n {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n addresses = new address[](config.addresses.length);\n uint256 addressesLen = config.addresses.length;\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the number of majority of guardians\n * @return majorityOfGuardians_ Number of majority of guardians e.g., 2 if 3 guardians / 3 if 5 guardians\n */\n function majorityOfGuardians()\n public\n view\n override\n returns (uint256 majorityOfGuardians_)\n {\n majorityOfGuardians_ = LibGuardian.majorityOfGuardians();\n }\n\n /**\n * @notice Reads guardian storage and fetches the addresses into an array from the storage\n * @dev This method fetches the guardian storage and returns the list of guardian addresses\n * @return guardianNumber Array of guardians in the account\n */\n function guardianCount()\n public\n view\n override\n returns (uint256 guardianNumber)\n {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n guardianNumber = config.addresses.length;\n }\n\n /**\n * @notice Reads guardian storage and checks if the given address is a guardian\n * @return isGuardian_ Bool value representing if the given address is guardian\n */\n function isGuardian(\n address _guardian\n ) public view override returns (bool isGuardian_) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n isGuardian_ = config.info[_guardian].exists;\n }\n\n /**\n * @notice Checks if the guardian number is zero and returns of guardian facet is okay to be removed\n * @return isRemovable Bool value representing if guardian facet is removable\n */\n function isGuardianFacetRemovable()\n external\n view\n override\n returns (bool isRemovable)\n {\n isRemovable = (0 == guardianCount());\n }\n}\n" + }, + "contracts/facets/interfaces/IAccountFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IEntryPoint} from \"../../aa-4337/interfaces/IEntryPoint.sol\";\n\n/**\n * @title Account Facet Interface\n * @dev Interface of module contract that provides the account features and init/unitialization of signer\n * compatible with EIP-1271 & EIP-4337\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IAccountFacet {\n event AccountInitialized(\n IEntryPoint indexed entryPoint,\n bytes indexed ownerPublicKey\n );\n // NOTE: Added Below Event\n event VerificationSuccess(bytes32);\n event VerificationFailure(bytes32);\n\n error AccountFacet__InitializationFailure();\n error AccountFacet__RestrictionsFailure();\n error AccountFacet__NonExistentVerificationFacet();\n error AccountFacet__CallNotSuccessful();\n\n function initialize(\n address verificationFacet,\n address anEntryPoint,\n address facetRegistry,\n address _defaultFallBack,\n bytes calldata _ownerPublicKey\n ) external returns (uint256);\n\n function execute(address dest, uint256 value, bytes calldata func) external;\n\n function executeBatch(\n address[] calldata dest,\n uint256[] calldata value,\n bytes[] calldata func\n ) external;\n}\n" + }, + "contracts/facets/interfaces/IAccountRecoveryFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {RecoveryConfig} from \"../../libraries/LibFacetStorage.sol\";\n\n/**\n * @title Account Recovery Facet Interface\n * @dev Interface of contract that enables recovery of accounts when owner key is unavailable\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IAccountRecoveryFacet {\n event RecoveryExecuted(\n bytes indexed recoveryPublicKey,\n uint64 executeAfter\n );\n event RecoveryFinalized(bytes indexed recoveryPublicKey);\n event RecoveryCanceled(bytes indexed recoveryPublicKey);\n event RecoveryApproved(\n bytes indexed recoveryPublicKey,\n address indexed guardian,\n uint64 validUntil\n );\n event RecoveryApprovalRevoked(\n bytes indexed recoveryPublicKey,\n address indexed guardian\n );\n event RecoveryCancellationApproved(\n bytes indexed recoveryPublicKey,\n address indexed guardian\n );\n event RecoveryHardstopped();\n\n error AccountRecoveryFacet__CallerNotGuardian();\n error AccountRecoveryFacet__InvalidRecoveryPublicKey();\n error AccountRecoveryFacet__SignerInitializationFailure();\n error AccountRecoveryFacet__SignerUninitializationFailure();\n error AccountRecoveryFacet__InvalidArrayLength();\n error AccountRecoveryFacet__InsufficientGuardians();\n error AccountRecoveryFacet__RecoveryAlreadyOngoing();\n error AccountRecoveryFacet__NonexistentRecovery();\n error AccountRecoveryFacet__NonExistentApproval();\n error AccountRecoveryFacet__RecoveryPeriodNotOver();\n error AccountRecoveryFacet__InvalidLockPeriod();\n error AccountRecoveryFacet__InvalidRecoveryPeriod();\n error AccountRecoveryFacet__InvalidApprovalValidationPeriod();\n error AccountRecoveryFacet__InvalidGuardian();\n error AccountRecoveryFacet__InvalidGuardianSignature();\n error AccountRecoveryFacet__InvalidOwnerSignature();\n error AccountRecoveryFacet__CallNotSuccesful();\n error AccountRecoveryFacet__DuplicateApproval();\n\n function approveAccountRecovery(bytes calldata recoveryPublicKey) external;\n\n function revokeAccountRecoveryApproval(\n bytes calldata recoveryPublicKey\n ) external;\n\n function executeRecovery(\n bytes calldata recoveryPublicKey,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function finalizeRecovery() external;\n\n function approveCancelRecovery(bytes calldata recoveryPublicKey) external;\n\n function cancelRecovery(\n bytes calldata recoveryPublicKey,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function hardstopRecovery(bytes calldata signature) external;\n\n function getApprovalRecoveryKeyHash(\n bytes memory recoveryPublicKey,\n string memory saltString\n ) external view returns (bytes32);\n\n function getRecoveryApprovalCountWithTimeValidity(\n bytes32 recoveryPublicKeyHash\n ) external view returns (uint256);\n\n function isRecoveryApproved(\n bytes32 recoveryPublicKeyHash,\n address approver\n ) external view returns (bool);\n\n function getRecoveryNonce() external view returns (uint128);\n\n function getPendingRecovery() external view returns (RecoveryConfig memory);\n}\n" + }, + "contracts/facets/interfaces/IGuardianFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Guardian Facet Interface\n * @dev Interface of guaridna contract that enables addition/removal of guardians from Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IGuardianFacet {\n event GuardianAdditionRequested(\n address indexed guardian,\n uint256 executeAfter\n );\n event GuardianRemovalRequested(\n address indexed guardian,\n uint256 executeAfter\n );\n event GuardianAdditionCancelled(address indexed guardian);\n event GuardianRemovalCancelled(address indexed guardian);\n event GuardianAdded(address indexed guardian);\n event GuardianRemoved(address indexed guardian);\n\n error GuardianFacet__GuardianCannotBeSelf();\n error GuardianFacet__DuplicateGuardian();\n error GuardianFacet__OwnerCannotBeGuardian();\n error GuardianFacet__DuplicateGuardianAddition();\n error GuardianFacet__DuplicateGuardianRemoval();\n error GuardianFacet__UnknownPendingAddition();\n error GuardianFacet__PendingAdditionNotOver();\n error GuardianFacet__UnknownPendingRemoval();\n error GuardianFacet__PendingRemovalNotOver();\n error GuardianFacet__PendingAdditionExpired();\n error GuardianFacet__InvalidAdditionSecurityPeriod();\n error GuardianFacet__InvalidRemovalSecurityPeriod();\n error GuardianFacet__InvalidSecurityWindow();\n error GuardianFacet__NonExistentGuardian();\n error GuardianFacet__AlreadyExists();\n error GuardianFacet__InvalidGuardianAddition();\n error GuardianFacet__InvalidGuardianRemoval();\n error GuardianFacet__ZeroAddressGuardian();\n\n function addGuardian(address guardian) external;\n\n function addGuardians(address[] calldata guardians) external;\n\n function removeGuardian(address guardian) external;\n\n function removeGuardians(address[] calldata guardians) external;\n\n function confirmGuardianAddition(address guardian) external;\n\n function confirmGuardianAdditions(address[] calldata guardian) external;\n\n function confirmGuardianRemoval(address guardian) external;\n\n function confirmGuardianRemovals(address[] calldata guardian) external;\n\n function cancelGuardianAddition(address guardian) external;\n\n function cancelGuardianRemoval(address guardian) external;\n\n function isGuardian(address guardian) external view returns (bool);\n\n function isAdditionPending(address guardian) external view returns (bool);\n\n function isRemovalPending(address guardian) external view returns (bool);\n\n function isGuardianFacetRemovable() external view returns (bool);\n\n function getAdditionSecurityPeriod() external view returns (uint256);\n\n function getRemovalSecurityPeriod() external view returns (uint256);\n\n function getSecurityWindow() external view returns (uint256);\n\n function getGuardians() external view returns (address[] memory);\n\n function majorityOfGuardians() external view returns (uint256);\n\n function guardianCount() external view returns (uint256);\n}\n" + }, + "contracts/facets/interfaces/ILockFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Lock} from \"../../libraries/LibAppStorage.sol\";\n\n/**\n * @title Lock Facet Interface\n * @dev Interface of Lock contract that enables full lock/unlock of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface ILockFacet {\n event Locked(uint64 releaseAfter);\n event Unlocked();\n\n error LockFacet__InvalidRecoveryPeriod();\n error LockFacet__CannotUnlock();\n error LockFacet__InvalidSignature();\n error LockFacet__InvalidApprover();\n\n function lock() external;\n\n function unlock(address approver, bytes calldata signature) external;\n\n function getLockPeriod() external view returns (uint256);\n\n function isLocked() external view returns (bool);\n\n function getUnlockHash() external view returns (bytes32);\n\n function lockNonce() external view returns (uint128);\n\n function getPendingLock() external view returns (Lock memory);\n}\n" + }, + "contracts/facets/interfaces/IMultiSigFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Multi-sig facet Interface\n * @dev Interface of Multi-signature Facet with custom threshold.\n Wallet that adds this facet becomes a multi-sig wallet\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IMultiSigFacet {\n event ThresholdChanged(uint256 threshold);\n event OwnerAdded(address indexed newOwner);\n event OwnerRemoved(address indexed prevOwner);\n event HashApproved(bytes32 hashToApprove, address indexed owner);\n\n error MultiSigFacet__InvalidThreshold();\n error MultisigFacet__InvalidOwnerCount();\n error MultiSigFacet__InvalidRoute();\n error MultiSigFacet__InsufficientSignerLength();\n error MultiSigFacet__InvalidInitData();\n error MultiSigFacet__InvalidOwnerAddress();\n error MultiSigFacet__InvalidOwnerPair();\n error MultiSigFacet__InvalidSignatureLength();\n error MultiSigFacet__InvalidSignatureType();\n error MultiSigFacet__DuplicateOwner();\n error MultiSigFacet__OnlyOwner();\n\n function checkSignatures(\n bytes32 _dataHash,\n bytes calldata _signatures,\n uint256 _threshold\n ) external view returns (uint256);\n\n function splitSignatures(\n bytes calldata _signatures,\n uint256 _nextOffset\n )\n external\n pure\n returns (\n address owner,\n bytes memory signature,\n uint256 signatureType,\n uint256 nextOffset\n );\n\n function approveHash(bytes32 hashToApprove) external;\n\n function addOwner(address newOwner, uint256 threshold) external;\n\n function removeOwner(\n address prevOwner,\n address removedOwner,\n uint256 threshold\n ) external;\n\n function swapOwner(\n address prevOwner,\n address oldOwner,\n address newOwner\n ) external;\n\n function changeThreshold(uint256 _threshold) external;\n\n function isOwner(address owner) external view returns (bool);\n\n function getThreshold() external view returns (uint256);\n\n function getOwners() external view returns (address[] memory);\n}\n" + }, + "contracts/facets/interfaces/IRestrictionsFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Restrictions Facet Interface\n * @dev Interface of Restrictions contract that enables modular restrictions in Barz\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IRestrictionsFacet {\n event RestrictionAdded(address indexed restriction);\n event RestrictionRemoved(address indexed restriction);\n\n error RestrictionsFacet__EmptyRestrictionsList();\n error RestrictionsFacet__RestrictionNotFound();\n error RestrictionsFacet__RestrictionAlreadyExists();\n error RestrictionsFacet__ZeroAddressRestrictions();\n error RestrictionsFacet__ZeroAddressRestrictionsFacet();\n error RestrictionsFacet__RemainingRestrictionsCantBeEmpty();\n\n function initializeRestrictions(\n address[] memory _restrictions\n ) external returns (uint256);\n\n function uninitializeRestrictions() external returns (uint256);\n\n function getRestrictions() external view returns (address[] memory);\n\n function addRestriction(address restriction) external;\n\n function removeRestriction(address restriction) external;\n\n function verifyRestrictions(\n address from,\n address to,\n uint256 value,\n bytes calldata _calldata\n ) external returns (uint256);\n}\n" + }, + "contracts/facets/interfaces/ISignatureMigrationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureMigrationConfig} from \"../../libraries/LibFacetStorage.sol\";\n\n/**\n * @title Signature Migration Facet Interface\n * @dev Interface of Signature Migration contract for migrating user signature scheme to a new scheme user sets\n * Which could include\n * - ECDSA on Secp256K1 Curve\n * - ECDSA on Secp256R1 Curve\n * - BLS, Schnorr, etc\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface ISignatureMigrationFacet {\n event SignatureSchemeMigration(\n address indexed prevVerificationFacet,\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n event SignatureMigrationApproved(\n bytes newPublicKey,\n address indexed newVerificationFacet,\n bytes4[] verificationFuncSelectors,\n address indexed guardian,\n uint128 approvalValidUntil\n );\n event SignatureMigrationApprovalRevoked(\n bytes newPublicKey,\n address indexed newVerificationFacet,\n bytes4[] verificationFuncSelectors,\n address indexed guardian\n );\n event SignatureMigrationExecuted(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors,\n uint128 migrateAfter\n );\n event SignatureMigrationCanceled(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n event SignatureMigrationCancellationApproved(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n\n error SignatureMigrationFacet__SignerUninitializationFailure();\n error SignatureMigrationFacet__InvalidRouteWithGuardian();\n error SignatureMigrationFacet__InvalidKeyType();\n error SignatureMigrationFacet__InsufficientApprovers();\n error SignatureMigrationFacet__InvalidApproverSignature();\n error SignatureMigrationFacet__InvalidGuardian();\n error SignatureMigrationFacet__NonExistentApprover();\n error SignatureMigrationFacet__InvalidMigrationPeriod();\n error SignatureMigrationFacet__NonexistentMigration();\n error SignatureMigrationFacet__MigrationPeriodNotOver();\n error SignatureMigrationFacet__InvalidArrayLength();\n error SignatureMigrationFacet__InvalidApprovalValidationPeriod();\n error SignatureMigrationFacet__CannotRevokeUnapproved();\n error SignatureMigrationFacet__LackOfOwnerApproval();\n error SignatureMigrationFacet__OwnerAlreadyApproved();\n error SignatureMigrationFacet__NonExistentVerificationFacet();\n error SignatureMigrationFacet__DuplicateApproval();\n\n function migrateSignatureScheme(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function migrateSignatureSchemeWithGuardian(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors,\n address[] calldata approvers,\n bytes[] calldata signatures\n ) external;\n\n function approveSignatureSchemeMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function revokeSignatureMigrationApproval(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function finalizeSignatureMigration() external;\n\n function approveCancelSignatureMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function cancelSignatureMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function getApprovalMigrationKeyHash(\n bytes memory recoveryPublicKey,\n address newVerificationFacet,\n bytes4[] memory newVerificationFuncSelectors,\n string memory saltString\n ) external view returns (bytes32);\n\n function getMigrationOwnerApprovalWithTimeValidity(\n bytes32 publicKeyHash\n ) external view returns (bool);\n\n function getMigrationApprovalCountWithTimeValidity(\n bytes32 publicKeyHash\n ) external view returns (uint256);\n\n function isMigrationApproved(\n bytes32 migrationPublicKeyHash,\n address approver\n ) external view returns (bool);\n\n function getMigrationNonce() external view returns (uint128);\n\n function isMigrationPending() external view returns (bool);\n\n function getPendingMigration()\n external\n view\n returns (SignatureMigrationConfig memory);\n}\n" + }, + "contracts/facets/interfaces/IVerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {UserOperation} from \"../../aa-4337/interfaces/UserOperation.sol\";\n\n/**\n * @title Verification Facet Interface\n * @dev Implements logic for user ops signature verification\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface IVerificationFacet {\n event SignerInitialized(bytes);\n event SignerUninitialized();\n\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n error VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n error VerificationFacet__InitializationFailure();\n error VerificationFacet__InvalidFacetMapping();\n\n function initializeSigner(bytes memory) external returns (uint256);\n\n function uninitializeSigner() external returns (uint256);\n\n function validateOwnerSignatureSelector() external view returns (bytes4);\n\n function owner() external view returns (bytes memory);\n\n function isValidKeyType(bytes calldata) external view returns (bool);\n\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) external view returns (uint256);\n}\n" + }, + "contracts/facets/LockFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage, Lock} from \"../libraries/LibAppStorage.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibFacetStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {ILockFacet} from \"./interfaces/ILockFacet.sol\";\n\n/**\n * @title Lock Facet\n * @dev Contract that enables full lock/unlock of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract LockFacet is ILockFacet, Modifiers {\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Locks the account for the lock period. Lock period is defined in the security manager and it's customizable\n * This function can only be called when account is unlocked by owner or guardians\n * @dev This method checks the caller and if the account is currently locked and locks the account after fetching the\n * Lock period from the owner.\n */\n function lock() external override onlyGuardianOrOwner onlyWhenUnlocked {\n uint256 unlockTime = block.timestamp + getLockPeriod();\n ++LibFacetStorage.lockStorage().nonce;\n LibAppStorage.setLock(unlockTime, LockFacet.lock.selector);\n emit Locked(uint64(unlockTime));\n }\n\n /**\n * @notice Locks the account when the account is locked. This function can be called by anyone but must provide the approver address and signature.\n * The approver should be one of the guardians or owner.\n * @dev This method takes the approver address and the signature. After validating the address and the signature, it unlocks the account immediately.\n * Only one of the guardian or owner is required to lock and unlock the account.\n * @param _approver Address of approver approving the unlock of Barz account\n * @param _signature Signature of the approver that signed the msg hash for unlocking the account\n */\n function unlock(\n address _approver,\n bytes calldata _signature\n ) external override onlyWhenLocked {\n if (_approver != address(this) && !LibGuardian.isGuardian(_approver))\n revert LockFacet__InvalidApprover();\n if (\n !SignatureChecker.isValidSignatureNow(\n _approver,\n getUnlockHash(),\n _signature\n )\n ) revert LockFacet__InvalidSignature();\n _unlock();\n }\n\n /**\n * @notice Unlocks the account and increments the lock nonce\n */\n function _unlock() private {\n if (s.locks[INNER_STRUCT].locker != LockFacet.lock.selector)\n revert LockFacet__CannotUnlock();\n ++LibFacetStorage.lockStorage().nonce;\n LibAppStorage.setLock(0, bytes4(0));\n emit Unlocked();\n }\n\n /**\n * @notice Returns the lock period of current Barz account. Lock period information is held by Security Manager\n * @return lockPeriod Uint value of lock period in seconds\n */\n function getLockPeriod() public view override returns (uint256 lockPeriod) {\n lockPeriod = securityManager.lockPeriodOf(address(this));\n if (lockPeriod == 0) revert LockFacet__InvalidRecoveryPeriod();\n }\n\n /**\n * @notice Returns if the account is locked or not\n * @dev This method fetches the current block timestamp and compares that with release time.\n * After checking the timestamp and release time, it returns if the account is still locked or not.\n * @return isLocked_ Uint value of lock period in seconds\n */\n function isLocked() public view override returns (bool isLocked_) {\n isLocked_ = uint64(block.timestamp) < s.locks[INNER_STRUCT].release;\n }\n\n /**\n * @notice Calculates the unlock hash and returns the unlock hash safe from signature reply attack\n * @dev This method calculates the unlock hash with EIP-191 prefix, wallet address, chainID, and nonce\n * It packs the result and packs them and hashes it.\n * @return unlockHash Bytes32 unlock hash\n */\n function getUnlockHash() public view override returns (bytes32 unlockHash) {\n unlockHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n \"Unlock\",\n address(this),\n block.chainid,\n lockNonce()\n )\n )\n )\n );\n }\n\n /**\n * @notice Returns lock nonce of account. Reads nonce from lock storage within facet storage\n * @return lockNonce_ Uint128 value of lock nonce. This is incremented whenever the account is lock/unlocked\n */\n function lockNonce() public view override returns (uint128 lockNonce_) {\n lockNonce_ = LibFacetStorage.lockStorage().nonce;\n }\n\n /**\n * @notice Returns the overall information of current lock\n * @return pendingLock Struct value including all information of pending lock\n */\n function getPendingLock()\n public\n view\n override\n returns (Lock memory pendingLock)\n {\n pendingLock = s.locks[INNER_STRUCT];\n }\n}\n" + }, + "contracts/facets/Modifiers.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {IFacetRegistry} from \"../infrastructure/interfaces/IFacetRegistry.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\n\n/**\n * @title Modifiers\n * @dev Responsible for providing modifiers/util functions to Facet contracts\n * @author David Yongjun Kim (@Powerstream3604)\n */\nabstract contract Modifiers is BarzStorage {\n uint8 constant INNER_STRUCT = 0;\n\n error CallerNotGuardian();\n error CallerNotGuardianOrOwner();\n error DuplicateApprover();\n error ZeroApproverLength();\n error UnregisteredFacetAndSelectors();\n\n /**\n * @notice Modifier to only allow guardian to make a call, reverts if any other entity is the caller\n */\n modifier onlyGuardian() {\n if (!LibGuardian.isGuardian(msg.sender)) revert CallerNotGuardian();\n _;\n }\n\n /**\n * @notice Modifier to only allow guardian or owner to make a call, reverts if any other entity is the caller\n */\n modifier onlyGuardianOrOwner() {\n if (!LibGuardian.isGuardian(msg.sender) && address(this) != msg.sender)\n revert CallerNotGuardianOrOwner();\n _;\n }\n\n /**\n * @notice Checks if the approver address is the array is unique with no duplicate\n * @dev This method loops through the array and checks if a duplicate address exists, it reverts if duplicate address exists\n * @param approvers Array of address\n */\n function _checkApprover(\n address[] memory approvers\n ) internal pure returns (bool) {\n uint256 approverLength = approvers.length;\n if (0 == approverLength) revert ZeroApproverLength();\n for (uint256 i; i < approverLength - 1; ) {\n for (uint256 j = i + 1; j < approverLength; ) {\n if (approvers[i] == approvers[j]) {\n revert DuplicateApprover(); // Found a duplicate\n }\n unchecked {\n ++j;\n }\n }\n unchecked {\n ++i;\n }\n }\n return false; // No duplicates found\n }\n\n /**\n * @notice Checks if the facet getting added or replaced is registered to facet registry\n * @dev This method loops through the cut and checks if the facet getting added/replaced is registered to facet registry\n * @param _diamondCut Array of FacetCut, data for diamondCut defined in EIP-2535\n */\n function _checkFacetCutValidity(\n IDiamondCut.FacetCut[] memory _diamondCut\n ) internal view {\n uint256 diamondCutLength = _diamondCut.length;\n for (uint256 i; i < diamondCutLength; ) {\n if (\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Add ||\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Replace\n ) {\n if (\n !s.facetRegistry.areFacetFunctionSelectorsRegistered(\n _diamondCut[i].facetAddress,\n _diamondCut[i].functionSelectors\n )\n ) revert UnregisteredFacetAndSelectors();\n }\n unchecked {\n ++i;\n }\n }\n }\n}\n" + }, + "contracts/facets/RestrictionsFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, RestrictionsStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {IRestriction} from \"../restrictions/IRestriction.sol\";\nimport {IRestrictionsFacet} from \"./interfaces/IRestrictionsFacet.sol\";\n\n/**\n * @title Restrictions facet\n * @dev Responsible for storing and verifying different kinds of restrictions, for example:\n * - Whitelist / Blacklist\n * - Daily limits\n * - Trading time restrictions\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract RestrictionsFacet is IRestrictionsFacet {\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceRestrictionsInitialize();\n }\n\n /**\n * @notice Intialize restrictions of Barz. Restrictions facet call restriction contracts for restriction validation\n * before each call\n * @param _restrictions The initial array of restrictions.\n * @return initSuccess Int value showing if the initialization of restriction is successful\n */\n function initializeRestrictions(\n address[] calldata _restrictions\n ) public override returns (uint256 initSuccess) {\n LibDiamond.enforceIsSelf();\n LibAppStorage.enforceRestrictionsInitialize();\n\n if (_restrictions.length == 0) {\n // You can't initialize RestrictionsFacet with an empty list of restrictions\n revert RestrictionsFacet__EmptyRestrictionsList();\n }\n for (uint256 i; i < _restrictions.length; ) {\n if (_restrictions[i] == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictions();\n unchecked {\n ++i;\n }\n }\n\n LibFacetStorage.restrictionsStorage().restrictions = _restrictions;\n _updateRestrictionsMap(_restrictions, true);\n initSuccess = 1;\n }\n\n /**\n * @notice Unitialize restrictions of Barz\n * @return uninitSuccess Int value showing if the initialization of restriction is successful\n */\n function uninitializeRestrictions()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibDiamond.enforceIsSelf();\n LibAppStorage.setRestrictionsUninitialized();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n _updateRestrictionsMap(restrictionsStorage.restrictions, false);\n restrictionsStorage.restrictions = new address[](0);\n uninitSuccess = 1;\n }\n\n /**\n * @notice Returns the list of Restrictions contract address\n * @return restrictions Addresses of IRestriction which are currently active\n */\n function getRestrictions()\n public\n view\n override\n returns (address[] memory restrictions)\n {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n restrictions = restrictionsStorage.restrictions;\n }\n\n /**\n * @notice Adds restrictions to Barz with validation on the restriction contract address.\n * This method is only callable by the owner(self).\n * @param _restriction The address of the restriction to be added.\n */\n function addRestriction(address _restriction) external override {\n LibDiamond.enforceIsSelf();\n if (LibDiamond.restrictionsFacet() == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictionsFacet();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n if (_restriction == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictions();\n if (restrictionsStorage.exists[_restriction])\n revert RestrictionsFacet__RestrictionAlreadyExists();\n\n restrictionsStorage.restrictions.push(_restriction);\n restrictionsStorage.exists[_restriction] = true;\n\n emit RestrictionAdded(_restriction);\n }\n\n /**\n * @notice Remove restrictions from Barz if it existed. This method is only callable by the owner(self).\n * @param _restriction The address of the restriction to be removed.\n */\n function removeRestriction(address _restriction) external override {\n LibDiamond.enforceIsSelf();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n if (!restrictionsStorage.exists[_restriction])\n revert RestrictionsFacet__RestrictionNotFound();\n\n address[] storage restrictions = restrictionsStorage.restrictions;\n\n uint256 indexToDelete = restrictions.length;\n uint256 restrictionsLen = restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n if (restrictions[i] == _restriction) {\n indexToDelete = i;\n break;\n }\n unchecked {\n ++i;\n }\n }\n\n if (indexToDelete == 0 && restrictionsLen == 1) {\n revert RestrictionsFacet__RemainingRestrictionsCantBeEmpty();\n } else if (indexToDelete == restrictionsLen) {\n revert RestrictionsFacet__RestrictionNotFound();\n } else {\n restrictions[indexToDelete] = restrictions[restrictionsLen - 1];\n restrictions.pop();\n }\n\n restrictionsStorage.exists[_restriction] = false;\n emit RestrictionRemoved(_restriction);\n }\n\n /**\n * @notice Sets the restrictions address value mapping to true or false when adding/removing restriction contracts\n * @param _restrictions List of restriction contracts address\n * @param _newValue Bool value to flag to the list of restrictions contracts\n */\n function _updateRestrictionsMap(\n address[] memory _restrictions,\n bool _newValue\n ) internal {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n uint restrictionsLen = _restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n restrictionsStorage.exists[_restrictions[i]] = _newValue;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @dev Iterates over all restrictions and verifies each of them with the transaction parameters.\n * @param _from The address of the sender, that will be signing the transaction.\n * @param _to The receiving address.\n * @param _value Amount of ETH to transfer from sender to recipient.\n * @param _calldata Optional field to include arbitrary data.\n * @return 0 if all the checks passed, 1 otherwise.\n */\n function verifyRestrictions(\n address _from,\n address _to,\n uint256 _value,\n bytes calldata _calldata\n ) external returns (uint256) {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n uint restrictionsLen = restrictionsStorage.restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n IRestriction restriction = IRestriction(\n restrictionsStorage.restrictions[i]\n );\n bool checkPassed = restriction.check(_from, _to, _value, _calldata);\n if (!checkPassed) {\n return 1;\n }\n unchecked {\n ++i;\n }\n }\n\n return 0;\n }\n}\n" + }, + "contracts/facets/SignatureMigrationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, SignatureMigrationStorage, SignatureMigrationConfig, SignatureMigrationApprovalConfig, ApprovalConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IDiamondCut} from \"./base/interfaces/IDiamondCut.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {ISignatureMigrationFacet} from \"./interfaces/ISignatureMigrationFacet.sol\";\n\n/**\n * @title Signature Migration Facet\n * @dev Responsible for migrating user signature scheme to a new scheme user sets\n * Which could include\n * - ECDSA on Secp256K1 Curve\n * - ECDSA on Secp256R1 Curve\n * - BLS, Schnorr, etc\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract SignatureMigrationFacet is ISignatureMigrationFacet, Modifiers {\n bytes constant UNINIT_CALL =\n abi.encodeWithSignature(\"uninitializeSigner()\");\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This modifier verifies if the public key format matches with the new verification facet\n * @param _publicKey Bytes of public key to be validated for the new verification facet\n * @param _newVerificationFacet Address of new verification facet\n */\n modifier validateKeyType(\n bytes memory _publicKey,\n address _newVerificationFacet\n ) {\n if (\n !IVerificationFacet(_newVerificationFacet).isValidKeyType(\n _publicKey\n )\n ) revert SignatureMigrationFacet__InvalidKeyType();\n _;\n }\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n // IMPORTANT NOTE: In the client side when they call this function, the func selectors should be sorted in ascending order\n // to prevent different hash with same items in the array\n /**\n * @notice Moves the state of migration to a pending state. When pending state is over after pending period time,\n * Migration can be finalized. This function can only be called by self and when the account is unlocked.\n * @dev This method checks if the caller is self and if guardians exists. It migrates signature request to a pending state\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function migrateSignatureScheme(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n public\n override\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n // Only self contract can call this function\n LibDiamond.enforceIsSelf();\n // Should revert if guardian exist\n if (0 != LibGuardian.guardianCount())\n revert SignatureMigrationFacet__InvalidRouteWithGuardian();\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n // NOTE: Migration requires a pending period & confirmation from owner to prevent a\n // single call changing the ownership of the wallet\n /**\n * @notice Migrate signature scheme when guardians exists. Verifies the signature of guardians and moves migration to pending state.\n * Which can then be finalized when pending period is over. Owner's approval is mandatory for migration to happen\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _approvers List of approvers. This could include owner\n */\n function migrateSignatureSchemeWithGuardian(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n )\n public\n override\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n // Should revert if does not guardian exist\n if (0 == LibGuardian.guardianCount())\n revert SignatureMigrationFacet__InvalidRouteWithGuardian();\n if (_approvers.length != _signatures.length)\n revert SignatureMigrationFacet__InvalidArrayLength();\n\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(migrationPublicKeyHash, _approvers);\n\n bool onChainOwnerApproval = getMigrationOwnerApprovalWithTimeValidity(\n migrationPublicKeyHash\n );\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n\n if (\n _approvers.length +\n getMigrationApprovalCountWithTimeValidity(\n migrationPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert SignatureMigrationFacet__InsufficientApprovers();\n {\n // To prevent Stack too deep\n bool ownerApproved;\n for (uint256 i; i < _approvers.length; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n address(this) != _approvers[i]\n ) revert SignatureMigrationFacet__InvalidGuardian();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert SignatureMigrationFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n migrationPublicKeyHash,\n _signatures[i]\n )\n ) revert SignatureMigrationFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n\n if (!ownerApproved && !onChainOwnerApproval)\n revert SignatureMigrationFacet__LackOfOwnerApproval();\n }\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Internal function that moves signature mgiration to a pending state.\n * @dev This method increments migration nonce and sets the migration in the migration config. Emits events for migration execution\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _migrateSignatureScheme(\n address _newVerificationFacet,\n bytes memory _newPublicKey,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal {\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n\n ++ms.nonce;\n uint64 migrateAfter = uint64(block.timestamp + getMigrationPeriod());\n\n ms.migrationConfigs[INNER_STRUCT] = SignatureMigrationConfig(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n migrateAfter\n );\n\n emit SignatureMigrationExecuted(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors,\n migrateAfter\n );\n }\n\n /**\n * @notice Approves signature scheme migration on-chain. This can be called by owner or guardian only when the account is unlocked.\n * When the threshold of the migration approval passed and owner approval is granted, it automatically moves migration to a pending state\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function approveSignatureSchemeMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n public\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit SignatureMigrationApproved(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n msg.sender,\n approvalValidUntil\n );\n if (\n getMigrationApprovalCountWithTimeValidity(migrationPublicKeyHash) >=\n LibGuardian.majorityOfGuardians() &&\n getMigrationOwnerApprovalWithTimeValidity(migrationPublicKeyHash)\n )\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Revokes the approval of signature migration done on-chain. Emits revoke event when revoked.\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function revokeSignatureMigrationApproval(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n external\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n if (!isMigrationApproved(migrationPublicKeyHash, msg.sender))\n revert SignatureMigrationFacet__CannotRevokeUnapproved();\n\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(false, 0);\n emit SignatureMigrationApprovalRevoked(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n msg.sender\n );\n }\n\n /**\n * @notice Finalizes the pending signature scheme migration. This function can only be called by owner.\n * It removes the facets of the previous verification facet and adds the new verification facet.\n * After finalizing migration, it emits migration event which shows the change of the verification facet\n */\n function finalizeSignatureMigration() external override {\n // NOTE: Only owner can call this function\n LibDiamond.enforceIsSelf();\n\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n\n if (!isMigrationPending())\n revert SignatureMigrationFacet__NonexistentMigration();\n\n if (\n uint64(block.timestamp) <=\n ms.migrationConfigs[INNER_STRUCT].migrateAfter\n ) revert SignatureMigrationFacet__MigrationPeriodNotOver();\n address newVerificationFacet = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationVerificationFacet;\n bytes4[] memory newVerificationFuncSelectors = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationSelectors;\n bytes memory newPublicKey = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationPublicKey;\n\n address prevVerificationFacet = LibLoupe.facetAddress(\n s.validateOwnerSignatureSelector\n );\n if (prevVerificationFacet == address(0))\n revert SignatureMigrationFacet__NonExistentVerificationFacet();\n\n IDiamondCut.FacetCut[] memory UninitCut;\n IDiamondCut.FacetCut[] memory InitCut;\n {\n bytes4[] memory prevVerificationFuncSelectors = LibLoupe\n .facetFunctionSelectors(prevVerificationFacet);\n\n UninitCut = new IDiamondCut.FacetCut[](1);\n InitCut = new IDiamondCut.FacetCut[](1);\n UninitCut[0] = IDiamondCut.FacetCut({\n facetAddress: address(0),\n action: IDiamondCut.FacetCutAction.Remove,\n functionSelectors: prevVerificationFuncSelectors\n });\n InitCut[0] = IDiamondCut.FacetCut({\n facetAddress: newVerificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: newVerificationFuncSelectors\n });\n {\n IDiamondCut.FacetCut[]\n memory facetCuts = new IDiamondCut.FacetCut[](2);\n facetCuts[0] = UninitCut[0];\n facetCuts[1] = InitCut[0];\n _checkFacetCutValidity(facetCuts);\n }\n LibAppStorage.initiateSignerMigration();\n address verificationFacet = address(\n bytes20(\n LibDiamond.diamondStorage().facets[\n s.validateOwnerSignatureSelector\n ]\n )\n );\n\n (bool success, bytes memory result) = verificationFacet\n .delegatecall(UNINIT_CALL);\n require(success, \"MigrationFacet: uninitialize not successful\");\n uint256 validationData = uint256(bytes32(result));\n if (validationData == 0)\n revert SignatureMigrationFacet__SignerUninitializationFailure();\n\n LibDiamond.diamondCut(UninitCut, address(0), \"\");\n }\n {\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n newPublicKey\n );\n\n // Every Verification Facet should comply with initializeSigner(bytes)\n // to be compatible with the Barz contract(for initialization)\n LibDiamond.diamondCut(InitCut, newVerificationFacet, initCall);\n LibAppStorage.finalizeSignerMigration();\n emit SignatureSchemeMigration(\n prevVerificationFacet,\n newVerificationFacet,\n newPublicKey,\n newVerificationFuncSelectors\n );\n }\n }\n\n /**\n * @notice Approve cancellation of signature migration. If cancellation approval passes guardian threshold with owner approval\n * it automatically cancels the migration.\n * @dev This method checks if the caller is one of guardian or owner and sets true for the cancellation hash in the approval config.\n * It internally calls _cancelSignatureMigration for canceling the migration\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function approveCancelSignatureMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n external\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"CancelSignatureMigration\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit SignatureMigrationCancellationApproved(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n if (\n getMigrationApprovalCountWithTimeValidity(migrationPublicKeyHash) >=\n LibGuardian.majorityOfGuardians() &&\n getMigrationOwnerApprovalWithTimeValidity(migrationPublicKeyHash)\n )\n _cancelSignatureMigration(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Verifies the signature of guardians/owner and cancels the signature migration.\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _approvers List of approvers. This could include owner\n */\n function cancelSignatureMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n )\n external\n override\n validateKeyType(_newPublicKey, _newVerificationFacet)\n onlyWhenUnlocked\n {\n if (_approvers.length != _signatures.length)\n revert SignatureMigrationFacet__InvalidArrayLength();\n\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"CancelSignatureMigration\"\n );\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(migrationPublicKeyHash, _approvers);\n\n bool onChainOwnerApproval = getMigrationOwnerApprovalWithTimeValidity(\n migrationPublicKeyHash\n );\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n if (\n _approvers.length +\n getMigrationApprovalCountWithTimeValidity(\n migrationPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert SignatureMigrationFacet__InsufficientApprovers();\n {\n // To prevent stack too deep\n bool ownerApproved;\n for (uint256 i; i < _approvers.length; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n address(this) != _approvers[i]\n ) revert SignatureMigrationFacet__NonExistentApprover();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert SignatureMigrationFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n migrationPublicKeyHash,\n _signatures[i]\n )\n ) revert SignatureMigrationFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n if (!ownerApproved && !onChainOwnerApproval)\n revert SignatureMigrationFacet__LackOfOwnerApproval();\n }\n _cancelSignatureMigration(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Internal function that cancels signature migration.\n * @dev This method increments migration nonce and deletes the migration from the migration config. Emits events for migration cancellation\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _cancelSignatureMigration(\n address _newVerificationFacet,\n bytes memory _newPublicKey,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal {\n if (!isMigrationPending())\n revert SignatureMigrationFacet__NonexistentMigration();\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n ++ms.nonce;\n delete ms.migrationConfigs[INNER_STRUCT];\n emit SignatureMigrationCanceled(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Checks if the facets to be added from new verification facet is registered to facet registry\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _checkMigrationCutValidity(\n address _newVerificationFacet,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal view {\n IDiamondCut.FacetCut[] memory facetCuts = new IDiamondCut.FacetCut[](1);\n facetCuts[0] = IDiamondCut.FacetCut({\n facetAddress: _newVerificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: _newVerificationFuncSelectors\n });\n _checkFacetCutValidity(facetCuts);\n }\n\n /**\n * @notice Returns if the migration is pending of not\n * @dev This method fetches the migration storage and checks if the migrate after is above 0 value\n * @return isPending Bool value that shows if the migration is pending\n */\n function isMigrationPending()\n public\n view\n override\n returns (bool isPending)\n {\n SignatureMigrationStorage storage rs = LibFacetStorage\n .migrationStorage();\n isPending = rs.migrationConfigs[INNER_STRUCT].migrateAfter > 0;\n }\n\n /**\n * @notice Returns the migration hash. This function ensures that this hash is safe from replay attack by including\n * public key, verification facet, function selectors, salt, address, chainId, and nonce.\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _saltString Salt value for generating the migration hash\n * @return migrationKeyHash Bytes32 string of the migration key hash\n */\n function getApprovalMigrationKeyHash(\n bytes memory _newPublicKey,\n address _newVerificationFacet,\n bytes4[] memory _newVerificationFuncSelectors,\n string memory _saltString\n ) public view override returns (bytes32 migrationKeyHash) {\n migrationKeyHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n _newPublicKey,\n _newVerificationFacet,\n keccak256(abi.encode(_newVerificationFuncSelectors)),\n _saltString,\n address(this),\n block.chainid,\n LibFacetStorage.migrationStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Checks if the owner approved the hash for migration\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @return isApprovedByOwner Bool value of showing if the owner approved it or not\n */\n function getMigrationOwnerApprovalWithTimeValidity(\n bytes32 _migrationPublicKeyHash\n ) public view override returns (bool isApprovedByOwner) {\n isApprovedByOwner = isMigrationApproved(\n _migrationPublicKeyHash,\n address(this)\n );\n }\n\n /**\n * @notice Checks how many of the guardians approved the migration hash\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @return approvalCount Number of approvals\n */\n function getMigrationApprovalCountWithTimeValidity(\n bytes32 _migrationPublicKeyHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardiansLength = guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n if (isMigrationApproved(_migrationPublicKeyHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n return approvalCount;\n }\n\n /**\n * @notice Checks if the migration is approved by the given approver\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @param _approver Address of approver\n * @return isApproved Bool value if migration hash is approved\n */\n function isMigrationApproved(\n bytes32 _migrationPublicKeyHash,\n address _approver\n ) public view override returns (bool isApproved) {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n isApproved = (ms\n .isMigrationApproved[_migrationPublicKeyHash][_approver].isApproved &&\n block.timestamp <\n ms\n .isMigrationApproved[_migrationPublicKeyHash][_approver]\n .validUntil);\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _migrationPublicKeyHash Hash of migration information\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _migrationPublicKeyHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isMigrationApproved(_migrationPublicKeyHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert SignatureMigrationFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the migration period of this wallet\n * @dev This method fetches the migration period from the security manager\n * @return migrationPeriod Migration period of Barz contract fetched from security manager\n */\n function getMigrationPeriod()\n internal\n view\n returns (uint128 migrationPeriod)\n {\n migrationPeriod = securityManager.migrationPeriodOf(address(this));\n if (migrationPeriod == 0)\n revert SignatureMigrationFacet__InvalidMigrationPeriod();\n }\n\n /**\n * @notice Returns the validation period of this wallet\n * @dev This method fetches the validation period from the security manager\n * @return approvalValidationPeriod Validation period of Barz contract fetched from security manager\n */\n function getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod == 0)\n revert SignatureMigrationFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the migration nonce of this wallet\n * @dev This method fetches the nonce from migration storage\n * @return migrationNonce Nonce of migration to protect from reply attacks\n */\n function getMigrationNonce()\n public\n view\n override\n returns (uint128 migrationNonce)\n {\n migrationNonce = LibFacetStorage.migrationStorage().nonce;\n }\n\n /**\n * @notice Returns the migration configuration of this wallet\n * @dev This method fetches the migration config from the migration storage\n * @return pendingMigrationConfig Migration config currently pending for signature migration\n */\n function getPendingMigration()\n external\n view\n override\n returns (SignatureMigrationConfig memory pendingMigrationConfig)\n {\n pendingMigrationConfig = LibFacetStorage\n .migrationStorage()\n .migrationConfigs[INNER_STRUCT];\n }\n}\n" + }, + "contracts/facets/TokenReceiverFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {IERC1155Receiver} from \"../interfaces/ERC/IERC1155Receiver.sol\";\nimport {IERC677Receiver} from \"../interfaces/ERC/IERC677Receiver.sol\";\n\n/**\n * @title TokenReceiver Facet\n * @dev Contract that enables receiving ERC721/ERC1155/ERC777/ERC677 Tokens with safe transfer\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract TokenReceiverFacet is\n IERC721Receiver,\n IERC1155Receiver,\n IERC777Recipient,\n IERC677Receiver\n{\n /**\n * @notice Handles ERC721 Token callback.\n * return Standardized onERC721Received return value.\n */\n function onERC721Received(\n address,\n address,\n uint256,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC721Receiver.onERC721Received.selector;\n }\n\n /**\n * @notice Handles ERC1155 Token callback.\n * return Standardized onERC1155Received return value.\n */\n function onERC1155Received(\n address,\n address,\n uint256,\n uint256,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC1155Receiver.onERC1155Received.selector;\n }\n\n /**\n * @notice Handles ERC1155 Token batch callback.\n * return Standardized onERC1155BatchReceived return value.\n */\n function onERC1155BatchReceived(\n address,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC1155Receiver.onERC1155BatchReceived.selector;\n }\n\n /**\n * @notice Handles ERC777 Token callback.\n * Does not return value, empty implementation.\n */\n function tokensReceived(\n address,\n address,\n address,\n uint256,\n bytes calldata,\n bytes calldata\n ) external pure override {}\n\n /**\n * @notice Handles ERC677 Token callback.\n * return true.\n */\n function onTokenTransfer(\n address,\n uint256,\n bytes calldata\n ) external pure override returns (bool) {\n return true;\n }\n}\n" + }, + "contracts/facets/verification/MultiSigFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {UserOperation} from \"../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../../libraries/LibLoupe.sol\";\nimport {LibAppStorage} from \"../../libraries/LibAppStorage.sol\";\nimport {LibMultiSigStorage, MultiSigStorage} from \"../../libraries/LibMultiSigStorage.sol\";\nimport {IERC1271} from \"../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../interfaces/IVerificationFacet.sol\";\nimport {IMultiSigFacet} from \"../interfaces/IMultiSigFacet.sol\";\n\n/**\n * @title Multi-sig facet\n * @dev Multi-signature Facet with custom threshold.\n * Wallet that adds this facet becomes a multi-sig wallet.\n * Reference signature_format.md documentation for Multi-sig facet details\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract MultiSigFacet is IMultiSigFacet, IVerificationFacet, IERC1271 {\n using ECDSA for bytes32;\n\n address public immutable self;\n\n address internal constant SENTINEL_OWNERS = address(0x1);\n uint256 internal constant ADDRESS = 20;\n uint256 internal constant SIG_TYPE = 1;\n uint256 internal constant SIG_LEN = 4;\n uint256 internal constant THRESHOLD = 4;\n uint256 internal constant INVALID_SIG = 1;\n uint256 internal constant VALID_SIG = 0;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in Multisig Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the right format and initializes signer storage in k1 storage.\n * @param _owners Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _owners\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n\n if (!isValidKeyType(_owners)) revert MultiSigFacet__InvalidInitData();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n uint256 threshold = uint256(uint32(bytes4(_owners)));\n uint256 ownerCount = (_owners.length - THRESHOLD) / ADDRESS;\n\n if (threshold == 0) revert MultiSigFacet__InvalidThreshold();\n if (ownerCount == 0) revert MultisigFacet__InvalidOwnerCount();\n\n address currentOwner = SENTINEL_OWNERS;\n uint256 ptr = THRESHOLD;\n address owner_;\n for (uint256 i; i < ownerCount; ) {\n owner_ = address(bytes20(_owners[ptr:ptr + ADDRESS]));\n ptr += ADDRESS;\n if (\n owner_ == address(0) ||\n owner_ == SENTINEL_OWNERS ||\n owner_ == address(this) ||\n owner_ == currentOwner\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[owner_] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n\n ms.owners[currentOwner] = owner_;\n currentOwner = owner_;\n\n unchecked {\n ++i;\n }\n }\n ms.owners[currentOwner] = SENTINEL_OWNERS;\n ms.ownerCount = ownerCount;\n ms.threshold = threshold;\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_owners);\n }\n\n /**\n * @notice Uninitialize signer in K1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n ++ms.counter;\n address[] memory ownerlist = getOwners();\n uint256 ownerlistLength = ownerlist.length;\n for (uint256 i; i < ownerlistLength; ) {\n ms.owners[ownerlist[i]] = address(0);\n unchecked {\n ++i;\n }\n }\n ms.owners[SENTINEL_OWNERS] = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls checkSignatures with\n * user operation hash and signature together with the threshold.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n // Data 1 is invalid, Data 0 is valid\n validationData = checkSignatures(\n userOpHash,\n userOp.signature,\n LibMultiSigStorage.multisigStorage().threshold\n );\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n return this.validateOwnerSignature.selector;\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n uint totalLength = ms.ownerCount * ADDRESS;\n bytes memory result = new bytes(totalLength);\n\n // populate return array\n uint256 index;\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n while (currentOwner != SENTINEL_OWNERS) {\n assembly {\n mstore(\n add(result, add(32, mul(index, ADDRESS))),\n shl(96, currentOwner)\n )\n }\n currentOwner = ms.owners[currentOwner];\n index++;\n }\n\n return result;\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key should comply with the format in the signature_format.md doc\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n uint256 publicKeyLength = _publicKey.length;\n if (\n publicKeyLength < ADDRESS + THRESHOLD ||\n (publicKeyLength - THRESHOLD) % ADDRESS != 0\n ) return false;\n\n uint256 threshold = uint256(uint32(bytes4(_publicKey)));\n uint256 ownerCount = (publicKeyLength - THRESHOLD) / ADDRESS;\n\n isValid = !(ownerCount < threshold || threshold == 0);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes calldata _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (checkSignatures(\n _hash,\n _signature,\n LibMultiSigStorage.multisigStorage().threshold\n ) == VALID_SIG)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n\n /**\n * @notice Validates the format of the signature and verifies if the signature is signed by the expected key.\n * Reference signature_format.md doc for details about signature format and signature types\n * @param _dataHash Bytes value of data hash signed by the owners\n * @param _signatures Bytes value of signature which should comply with signature format\n * @param _threshold Uint256 value of current Multi-sig Barz's threshold\n */\n function checkSignatures(\n bytes32 _dataHash,\n bytes calldata _signatures,\n uint256 _threshold\n ) public view returns (uint256) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n address lastOwner = address(0);\n address currentOwner;\n bytes memory signature;\n uint256 signatureType;\n uint256 nextOffset;\n uint256 i;\n for (i; i < _threshold; ) {\n (\n currentOwner,\n signature,\n signatureType,\n nextOffset\n ) = splitSignatures(_signatures, nextOffset);\n if (nextOffset == 0 && i + 1 < _threshold) return INVALID_SIG;\n if (signatureType == 1) {\n // If signatureType is 1 then it is default dataHash signed.\n // This also includes the contract signature\n if (\n !SignatureChecker.isValidSignatureNow(\n currentOwner,\n _dataHash,\n signature\n )\n ) return INVALID_SIG;\n } else if (signatureType == 2) {\n // If signatureType is 2 then it is an approved hash\n if (ms.approvedHashes[ms.counter][currentOwner][_dataHash] == 0)\n return INVALID_SIG;\n } else if (signatureType == 3) {\n // If signatureType is 3 then it is a signed message hash\n // This also includes the contract signature\n bytes32 msgHash = _dataHash.toEthSignedMessageHash();\n if (\n !SignatureChecker.isValidSignatureNow(\n currentOwner,\n msgHash,\n signature\n )\n ) return INVALID_SIG;\n } else revert MultiSigFacet__InvalidRoute();\n if (\n currentOwner <= lastOwner ||\n ms.owners[currentOwner] == address(0) ||\n currentOwner == SENTINEL_OWNERS\n ) return INVALID_SIG;\n lastOwner = currentOwner;\n\n unchecked {\n ++i;\n }\n }\n return VALID_SIG;\n }\n\n /**\n * @notice Split signatures into each individual signatures. Should comply with signature format to be split\n * @param _signatures Bytes value of signature\n * @param _nextOffset Uint256 value of next offset to start splitting the signature\n */\n function splitSignatures(\n bytes calldata _signatures,\n uint256 _nextOffset\n )\n public\n pure\n returns (\n address owner_,\n bytes memory signature,\n uint256 signatureType,\n uint256 nextOffset\n )\n {\n uint256 signaturesLength = _signatures.length;\n\n if (signaturesLength <= _nextOffset + ADDRESS + SIG_LEN)\n revert MultiSigFacet__InsufficientSignerLength();\n\n owner_ = address(\n bytes20(_signatures[_nextOffset:_nextOffset + ADDRESS])\n );\n\n signatureType = uint256(\n uint8(\n bytes1(\n _signatures[_nextOffset + ADDRESS:_nextOffset +\n ADDRESS +\n SIG_TYPE]\n )\n )\n );\n\n if (signatureType > 3 || signatureType == 0)\n revert MultiSigFacet__InvalidSignatureType();\n uint256 offSet = _nextOffset + ADDRESS + SIG_TYPE;\n uint256 siglen = uint256(\n uint32(bytes4(_signatures[offSet:offSet + SIG_LEN]))\n );\n if (offSet + siglen > signaturesLength)\n revert MultiSigFacet__InvalidSignatureLength();\n\n offSet += SIG_LEN;\n if (offSet + siglen == signaturesLength) nextOffset = 0;\n else nextOffset = offSet + siglen;\n\n signature = _signatures[offSet:offSet + siglen];\n }\n\n /**\n * @notice Approves the hash of userOperation on-chain. This can only be called by owners.\n * @param _hashToApprove Bytes value of UserOperation hash to approve\n */\n function approveHash(bytes32 _hashToApprove) external {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (ms.owners[msg.sender] == address(0))\n revert MultiSigFacet__OnlyOwner();\n\n ms.approvedHashes[ms.counter][msg.sender][_hashToApprove] = 1;\n emit HashApproved(_hashToApprove, msg.sender);\n }\n\n /**\n * @notice Add owner to Barz. Update thresold if threshold is given different from current threshold\n * @dev This can only be done via a Self call.\n * @param _newOwner Address of new owner to be added\n * @param _threshold Uint256 value of threshold\n */\n function addOwner(address _newOwner, uint256 _threshold) external {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (\n _newOwner == address(0) ||\n _newOwner == SENTINEL_OWNERS ||\n _newOwner == address(this)\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_newOwner] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n\n ms.owners[_newOwner] = ms.owners[SENTINEL_OWNERS];\n ms.owners[SENTINEL_OWNERS] = _newOwner;\n ++ms.ownerCount;\n emit OwnerAdded(_newOwner);\n\n if (ms.threshold != _threshold) changeThreshold(_threshold);\n }\n\n /**\n * @notice Remove owner from Barz. Update thresold if threshold is given different from current threshold\n * @dev This can only be done via a Self call.\n * @param _prevOwner Address of owner located right behind the removed owner address in the linked list\n * @param _removedOwner Address of owner to be removed\n * @param _threshold Uint256 value of threshold\n */\n function removeOwner(\n address _prevOwner,\n address _removedOwner,\n uint256 _threshold\n ) external {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (ms.ownerCount - 1 < _threshold)\n revert MultiSigFacet__InvalidThreshold();\n if (_removedOwner == address(0) || _removedOwner == SENTINEL_OWNERS)\n revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_prevOwner] != _removedOwner)\n revert MultiSigFacet__InvalidOwnerPair();\n\n ms.owners[_prevOwner] = ms.owners[_removedOwner];\n ms.owners[_removedOwner] = address(0);\n --ms.ownerCount;\n emit OwnerRemoved(_removedOwner);\n\n if (ms.threshold != _threshold) changeThreshold(_threshold);\n }\n\n /**\n * @notice Swap owner in Barz.\n * @dev This can only be done via a Self call.\n * @param _prevOwner Address of owner located right behind the removed owner address in the linked list\n * @param _oldOwner Address of owner to be removed\n * @param _newOwner Address of owner to be added\n */\n function swapOwner(\n address _prevOwner,\n address _oldOwner,\n address _newOwner\n ) public {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (\n _newOwner == address(0) ||\n _newOwner == SENTINEL_OWNERS ||\n _newOwner == address(this)\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_newOwner] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n if (_oldOwner == address(0) || _oldOwner == SENTINEL_OWNERS)\n revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_prevOwner] != _oldOwner)\n revert MultiSigFacet__InvalidOwnerPair();\n\n ms.owners[_newOwner] = ms.owners[_oldOwner];\n ms.owners[_prevOwner] = _newOwner;\n ms.owners[_oldOwner] = address(0);\n emit OwnerRemoved(_oldOwner);\n emit OwnerAdded(_newOwner);\n }\n\n /**\n * @notice Changes the threshold of the Barz to `_threshold`.\n * @dev This can only be done via a Self call.\n * @param _threshold New threshold\n */\n function changeThreshold(uint256 _threshold) public {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (_threshold > ms.ownerCount || _threshold == 0)\n revert MultiSigFacet__InvalidThreshold();\n\n ms.threshold = _threshold;\n emit ThresholdChanged(_threshold);\n }\n\n /**\n * @notice Checks if the given address is owner\n * @param _owner Address to be checked if it's owner\n * @return isOwner_ Bool value showing if it's owner address\n */\n function isOwner(address _owner) public view returns (bool isOwner_) {\n isOwner_ = (_owner != SENTINEL_OWNERS &&\n LibMultiSigStorage.multisigStorage().owners[_owner] != address(0));\n }\n\n /**\n * @notice Returns the threshold of Barz\n * @return threshold Threshold of the Barz account\n */\n function getThreshold() public view returns (uint256 threshold) {\n threshold = LibMultiSigStorage.multisigStorage().threshold;\n }\n\n /**\n * @notice Returns the list of owner addresses\n * @return owners List of owners\n */\n function getOwners() public view returns (address[] memory owners) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n owners = new address[](ms.ownerCount);\n\n uint256 index;\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n while (currentOwner != SENTINEL_OWNERS) {\n owners[index] = currentOwner;\n currentOwner = ms.owners[currentOwner];\n index++;\n }\n }\n\n /**\n * @notice Returns the previous owner in the linked list\n * @param _owner Address of owner\n * @return prevOwner Address of previous owner\n */\n function getPrevOwner(\n address _owner\n ) public view returns (address prevOwner) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n if (currentOwner == _owner) return SENTINEL_OWNERS;\n while (currentOwner != SENTINEL_OWNERS) {\n if (ms.owners[currentOwner] == _owner) return currentOwner;\n\n currentOwner = ms.owners[currentOwner];\n }\n return address(0);\n }\n\n /**\n * @notice Returns of the owner is approved by given owner address\n * @param _owner Address of owner\n * @param _hash Hash of UserOperation\n * @return isApproved Bool value showing if the hash is approved by owner\n */\n function isApprovedHash(\n address _owner,\n bytes32 _hash\n ) public view returns (bool isApproved) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n isApproved = (ms.approvedHashes[ms.counter][_owner][_hash] == 1);\n }\n}\n" + }, + "contracts/facets/verification/secp256k1/Secp256k1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {UserOperation} from \"../../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibAppStorage} from \"../../../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, Secp256k1VerificationStorage} from \"../../../libraries/LibFacetStorage.sol\";\nimport {LibLoupe} from \"../../../libraries/LibLoupe.sol\";\nimport {IERC1271} from \"../../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../../interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Secp256k1 verification facet\n * @dev Default Ethereum's elliptic curve\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract Secp256k1VerificationFacet is IVerificationFacet, IERC1271 {\n using ECDSA for bytes32;\n error Secp256k1VerificationFacet__InvalidSignerLength();\n address public immutable self;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in K1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\n * @param _publicKey Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _publicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n if (!isValidKeyType(_publicKey))\n revert Secp256k1VerificationFacet__InvalidSignerLength();\n\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(uint160(uint256(keccak256(_publicKey[1:]))));\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_publicKey);\n }\n\n /**\n * @notice Uninitialize signer in K1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\n * signer public key.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n validationData = validateSignature(\n userOp,\n userOpHash,\n k1Storage.signer\n );\n }\n\n /**\n * @notice Validates if the signature of UserOperation is signed by the given signer\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @param signer Address of signer who signed the contract, to be validated\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n address signer\n ) public pure returns (uint256 isValid) {\n bytes32 hash = userOpHash.toEthSignedMessageHash();\n isValid = (signer != hash.recover(userOp.signature)) ? 1 : 0;\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n ownerSignatureValidatorSelector = this.validateOwnerSignature.selector;\n // NOTE: The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory signer) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n signer = abi.encodePacked(k1Storage.signer);\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key length should be 65 in an uncompressed public key format\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (_hash.recover(_signature) ==\n LibFacetStorage.k1Storage().signer)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/Secp256r1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {UserOperation} from \"../../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibAppStorage} from \"../../../libraries/LibAppStorage.sol\";\nimport {LibLoupe} from \"../../../libraries/LibLoupe.sol\";\nimport {LibFacetStorage, Secp256r1VerificationStorage} from \"../../../libraries/LibFacetStorage.sol\";\nimport {Base64} from \"./utils/Base64.sol\";\nimport {LibSecp256r1} from \"./utils/LibSecp256r1.sol\";\nimport {IERC1271} from \"../../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../../interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Secp256r1 verification facet\n * @dev Primarily used to verify user ops signed with passkeys\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract Secp256r1VerificationFacet is IVerificationFacet, IERC1271 {\n error Secp256r1VerificationFacet__InvalidSignerLength();\n address public immutable self;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in R1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\n * @param _publicKey Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _publicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n\n if (!isValidKeyType(_publicKey))\n revert Secp256r1VerificationFacet__InvalidSignerLength();\n\n bytes memory publicKeyCoordinates = _publicKey[1:];\n uint256[2] memory q;\n assembly {\n // Copy the bytes from the input data into the uint256 array\n mstore(q, mload(add(publicKeyCoordinates, 32)))\n mstore(add(q, 32), mload(add(publicKeyCoordinates, 64)))\n }\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n r1Storage.q = q;\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_publicKey);\n }\n\n /**\n * @notice Uninitialize signer in R1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n r1Storage.q = [0, 0];\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\n * signer public key.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n validationData = validateSignature(userOp, userOpHash, r1Storage.q);\n }\n\n /**\n * @notice Validates if the signature of UserOperation is signed by the given signer\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @param q Public Key of signer who signed the contract, to be validated\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256[2] memory q\n ) public view returns (uint256 isValid) {\n isValid = (_validateSignature(q, userOpHash, userOp.signature)) ? 0 : 1;\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n return this.validateOwnerSignature.selector; // validateOwnerSignature(UserOperation calldata userOp,bytes32 userOpHash)\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory signer) {\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n signer = abi.encodePacked(r1Storage.q);\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key should in an uncompressed public key format\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = _validateSignature(\n LibFacetStorage.r1Storage().q,\n _hash,\n _signature\n )\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n\n function _validateSignature(\n uint256[2] memory q,\n bytes32 _hash,\n bytes memory _signature\n ) internal view returns (bool) {\n (\n uint256 rValue,\n uint256 sValue,\n bytes memory authenticatorData,\n string memory clientDataJSONPre,\n string memory clientDataJSONPost\n ) = abi.decode(_signature, (uint256, uint256, bytes, string, string));\n bytes32 clientHash;\n {\n string memory opHashBase64 = Base64.encode(bytes.concat(_hash));\n string memory clientDataJSON = string.concat(\n clientDataJSONPre,\n opHashBase64,\n clientDataJSONPost\n );\n clientHash = sha256(bytes(clientDataJSON));\n }\n bytes32 sigHash = sha256(bytes.concat(authenticatorData, clientHash));\n return LibSecp256r1.Verify(q, rValue, sValue, uint256(sigHash));\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/utils/Base64.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @dev Provides a set of functions to operate with Base64 strings.\n * modified for base64url https://datatracker.ietf.org/doc/html/rfc4648#section-5\n * _Available since v4.5._\n */\nlibrary Base64 {\n /**\n * @dev Base64 Encoding/Decoding Table\n */\n string internal constant _TABLE =\n \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_\";\n\n /**\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\n */\n function encode(bytes memory data) internal pure returns (string memory) {\n /**\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\n */\n if (data.length == 0) return \"\";\n\n // Loads the table into memory\n string memory table = _TABLE;\n\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\n // and split into 4 numbers of 6 bits.\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\n // - `data.length + 2` -> Round up\n // - `/ 3` -> Number of 3-bytes chunks\n // - `4 *` -> 4 characters for each chunk\n uint256 newlength = (data.length * 8) / 6;\n if (data.length % 6 > 0) {\n newlength++;\n }\n string memory result = new string(newlength);\n\n /// @solidity memory-safe-assembly\n assembly {\n // Prepare the lookup table (skip the first \"length\" byte)\n let tablePtr := add(table, 1)\n\n // Prepare result pointer, jump over length\n let resultPtr := add(result, 32)\n\n // Run over the input, 3 bytes at a time\n for {\n let dataPtr := data\n let endPtr := add(data, mload(data))\n } lt(dataPtr, endPtr) {\n\n } {\n // Advance 3 bytes\n dataPtr := add(dataPtr, 3)\n let input := mload(dataPtr)\n\n // To write each character, shift the 3 bytes (18 bits) chunk\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\n // and apply logical AND with 0x3F which is the number of\n // the previous character in the ASCII table prior to the Base64 Table\n // The result is then added to the table to get the character to write,\n // and finally write it in the result pointer but with a left shift\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(18, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(12, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(6, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n }\n }\n\n return result;\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/utils/LibSecp256r1.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n// Heavily inspired from\n// https://github.com/maxrobot/elliptic-solidity/blob/master/contracts/Secp256r1.sol\n// https://github.com/tdrerup/elliptic-curve-solidity/blob/master/contracts/curves/EllipticCurve.sol\n// modified to use precompile 0x05 modexp\n// and modified jacobian double\n// optimisations to avoid to an from from affine and jacobian coordinates\n\n// Additional Elliptic curve Public key / Signature validation added by\n// David Yonjun Kim (@Powerstream3604)\n\nstruct JPoint {\n uint256 x;\n uint256 y;\n uint256 z;\n}\n\nlibrary LibSecp256r1 {\n uint256 constant gx =\n 0x6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296;\n uint256 constant gy =\n 0x4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5;\n uint256 public constant pp =\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF;\n\n uint256 public constant nn =\n 0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551;\n uint256 constant a =\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC;\n uint256 constant b =\n 0x5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B;\n uint256 constant MOST_SIGNIFICANT =\n 0xc000000000000000000000000000000000000000000000000000000000000000;\n\n /*\n * Verify\n * @description - verifies that a public key has signed a given message\n * @param Q - public key coordinates X & Y\n * @param R - signature half R\n * @param S - signature half S\n * @param input - hashed message\n */\n function Verify(\n uint256[2] memory q,\n uint r,\n uint s,\n uint e\n ) internal view returns (bool) {\n if (q[0] > pp - 1 || q[1] > pp - 1) {\n return false;\n }\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\n return false;\n }\n if (\n mulmod(q[1], q[1], pp) !=\n addmod(\n addmod(\n mulmod(q[0], mulmod(q[0], q[0], pp), pp),\n mulmod(a, q[0], pp),\n pp\n ),\n b,\n pp\n )\n ) {\n return false;\n }\n\n JPoint[16] memory points = _preComputeJacobianPoints(q);\n return VerifyWithPrecompute(points, r, s, e);\n }\n\n function VerifyWithPrecompute(\n JPoint[16] memory points,\n uint r,\n uint s,\n uint e\n ) internal view returns (bool) {\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\n return false;\n }\n\n uint w = _primemod(s, nn);\n\n uint u1 = mulmod(e, w, nn);\n uint u2 = mulmod(r, w, nn);\n\n uint x;\n uint y;\n\n (x, y) = ShamirMultJacobian(points, u1, u2);\n return (x == r);\n }\n\n /*\n * Strauss Shamir trick for EC multiplication\n * https://stackoverflow.com/questions/50993471/ec-scalar-multiplication-with-strauss-shamir-method\n * we optimise on this a bit to do with 2 bits at a time rather than a single bit\n * the individual points for a single pass are precomputed\n * overall this reduces the number of additions while keeping the same number of doublings\n */\n function ShamirMultJacobian(\n JPoint[16] memory points,\n uint u1,\n uint u2\n ) internal view returns (uint, uint) {\n uint x = 0;\n uint y = 0;\n uint z = 0;\n uint bits = 128;\n uint index = 0;\n\n while (bits > 0) {\n if (z > 0) {\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\n }\n index =\n ((u1 & MOST_SIGNIFICANT) >> 252) |\n ((u2 & MOST_SIGNIFICANT) >> 254);\n if (index > 0) {\n (x, y, z) = _jAdd(\n x,\n y,\n z,\n points[index].x,\n points[index].y,\n points[index].z\n );\n }\n u1 <<= 2;\n u2 <<= 2;\n bits--;\n }\n (x, y) = _affineFromJacobian(x, y, z);\n return (x, y);\n }\n\n function _preComputeJacobianPoints(\n uint256[2] memory q\n ) internal pure returns (JPoint[16] memory points) {\n points[0] = JPoint(0, 0, 0);\n points[1] = JPoint(q[0], q[1], 1); // u2\n points[2] = _jPointDouble(points[1]);\n points[3] = _jPointAdd(points[1], points[2]);\n\n points[4] = JPoint(gx, gy, 1); // u1Points[1]\n points[5] = _jPointAdd(points[4], points[1]);\n points[6] = _jPointAdd(points[4], points[2]);\n points[7] = _jPointAdd(points[4], points[3]);\n\n points[8] = _jPointDouble(points[4]); // u1Points[2]\n points[9] = _jPointAdd(points[8], points[1]);\n points[10] = _jPointAdd(points[8], points[2]);\n points[11] = _jPointAdd(points[8], points[3]);\n\n points[12] = _jPointAdd(points[4], points[8]); // u1Points[3]\n points[13] = _jPointAdd(points[12], points[1]);\n points[14] = _jPointAdd(points[12], points[2]);\n points[15] = _jPointAdd(points[12], points[3]);\n }\n\n function _jPointAdd(\n JPoint memory p1,\n JPoint memory p2\n ) internal pure returns (JPoint memory) {\n uint x;\n uint y;\n uint z;\n (x, y, z) = _jAdd(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z);\n return JPoint(x, y, z);\n }\n\n function _jPointDouble(\n JPoint memory p\n ) internal pure returns (JPoint memory) {\n uint x;\n uint y;\n uint z;\n (x, y, z) = _modifiedJacobianDouble(p.x, p.y, p.z);\n return JPoint(x, y, z);\n }\n\n /* _affineFromJacobian\n * @desription returns affine coordinates from a jacobian input follows\n * golang elliptic/crypto library\n */\n function _affineFromJacobian(\n uint x,\n uint y,\n uint z\n ) internal view returns (uint ax, uint ay) {\n if (z == 0) {\n return (0, 0);\n }\n\n uint zinv = _primemod(z, pp);\n uint zinvsq = mulmod(zinv, zinv, pp);\n\n ax = mulmod(x, zinvsq, pp);\n ay = mulmod(y, mulmod(zinvsq, zinv, pp), pp);\n }\n\n /*\n * _jAdd\n * @description performs Jacobian addition as defined below:\n * http://www.hyperelliptic.org/EFD/g1p/data/shortw/jacobian/addition/add-2007-bl\n */\n function _jAdd(\n uint p1,\n uint p2,\n uint p3,\n uint q1,\n uint q2,\n uint q3\n ) internal pure returns (uint r1, uint r2, uint r3) {\n if (p3 == 0) {\n r1 = q1;\n r2 = q2;\n r3 = q3;\n\n return (r1, r2, r3);\n } else if (q3 == 0) {\n r1 = p1;\n r2 = p2;\n r3 = p3;\n\n return (r1, r2, r3);\n }\n\n assembly {\n let\n pd\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\n let z1z1 := mulmod(p3, p3, pd) // Z1Z1 = Z1^2\n let z2z2 := mulmod(q3, q3, pd) // Z2Z2 = Z2^2\n\n let u1 := mulmod(p1, z2z2, pd) // U1 = X1*Z2Z2\n let u2 := mulmod(q1, z1z1, pd) // U2 = X2*Z1Z1\n\n let s1 := mulmod(p2, mulmod(z2z2, q3, pd), pd) // S1 = Y1*Z2*Z2Z2\n let s2 := mulmod(q2, mulmod(z1z1, p3, pd), pd) // S2 = Y2*Z1*Z1Z1\n\n let p3q3 := addmod(p3, q3, pd)\n\n if lt(u2, u1) {\n u2 := add(pd, u2) // u2 = u2+pd\n }\n let h := sub(u2, u1) // H = U2-U1\n\n let i := mulmod(0x02, h, pd)\n i := mulmod(i, i, pd) // I = (2*H)^2\n\n let j := mulmod(h, i, pd) // J = H*I\n if lt(s2, s1) {\n s2 := add(pd, s2) // u2 = u2+pd\n }\n let rr := mulmod(0x02, sub(s2, s1), pd) // r = 2*(S2-S1)\n r1 := mulmod(rr, rr, pd) // X3 = R^2\n\n let v := mulmod(u1, i, pd) // V = U1*I\n let j2v := addmod(j, mulmod(0x02, v, pd), pd)\n if lt(r1, j2v) {\n r1 := add(pd, r1) // X3 = X3+pd\n }\n r1 := sub(r1, j2v)\n\n // Y3 = r*(V-X3)-2*S1*J\n let s12j := mulmod(mulmod(0x02, s1, pd), j, pd)\n\n if lt(v, r1) {\n v := add(pd, v)\n }\n r2 := mulmod(rr, sub(v, r1), pd)\n\n if lt(r2, s12j) {\n r2 := add(pd, r2)\n }\n r2 := sub(r2, s12j)\n\n // Z3 = ((Z1+Z2)^2-Z1Z1-Z2Z2)*H\n z1z1 := addmod(z1z1, z2z2, pd)\n j2v := mulmod(p3q3, p3q3, pd)\n if lt(j2v, z1z1) {\n j2v := add(pd, j2v)\n }\n r3 := mulmod(sub(j2v, z1z1), h, pd)\n }\n return (r1, r2, r3);\n }\n\n // Point doubling on the modified jacobian coordinates\n // http://point-at-infinity.org/ecc/Prime_Curve_Modified_Jacobian_Coordinates.html\n function _modifiedJacobianDouble(\n uint x,\n uint y,\n uint z\n ) internal pure returns (uint x3, uint y3, uint z3) {\n if (y == 0) return (0, 0, 0);\n assembly {\n let\n pd\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\n let z2 := mulmod(z, z, pd)\n let az4 := mulmod(\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC,\n mulmod(z2, z2, pd),\n pd\n )\n let y2 := mulmod(y, y, pd)\n let s := mulmod(0x04, mulmod(x, y2, pd), pd)\n let u := mulmod(0x08, mulmod(y2, y2, pd), pd)\n let m := addmod(mulmod(0x03, mulmod(x, x, pd), pd), az4, pd)\n let twos := mulmod(0x02, s, pd)\n let m2 := mulmod(m, m, pd)\n if lt(m2, twos) {\n m2 := add(pd, m2)\n }\n x3 := sub(m2, twos)\n if lt(s, x3) {\n s := add(pd, s)\n }\n y3 := mulmod(m, sub(s, x3), pd)\n if lt(y3, u) {\n y3 := add(pd, y3)\n }\n y3 := sub(y3, u)\n z3 := mulmod(0x02, mulmod(y, z, pd), pd)\n }\n }\n\n // Fermats little theorem https://en.wikipedia.org/wiki/Fermat%27s_little_theorem\n // a^(p-1) = 1 mod p\n // a^(-1) ≅ a^(p-2) (mod p)\n // we then use the precompile bigModExp to compute a^(-1)\n function _primemod(uint value, uint p) internal view returns (uint ret) {\n ret = modexp(value, p - 2, p);\n return ret;\n }\n\n // Wrapper for built-in BigNumber_modexp (contract 0x5) as described here. https://github.com/ethereum/EIPs/pull/198\n function modexp(\n uint _base,\n uint _exp,\n uint _mod\n ) internal view returns (uint ret) {\n // bigModExp(_base, _exp, _mod);\n assembly {\n if gt(_base, _mod) {\n _base := mod(_base, _mod)\n }\n // Free memory pointer is always stored at 0x40\n let freemem := mload(0x40)\n\n mstore(freemem, 0x20)\n mstore(add(freemem, 0x20), 0x20)\n mstore(add(freemem, 0x40), 0x20)\n\n mstore(add(freemem, 0x60), _base)\n mstore(add(freemem, 0x80), _exp)\n mstore(add(freemem, 0xa0), _mod)\n\n let success := staticcall(14000, 0x5, freemem, 0xc0, freemem, 0x20)\n switch success\n case 0 {\n revert(0x0, 0x0)\n }\n default {\n ret := mload(freemem)\n }\n }\n }\n}\n" + }, + "contracts/infrastructure/DefaultFallbackHandler.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC1155Receiver} from \"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\";\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {BaseAccount} from \"../aa-4337/core/BaseAccount.sol\";\nimport {DefaultLibDiamond} from \"../libraries/DefaultLibDiamond.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IAccountFacet} from \"../facets/interfaces/IAccountFacet.sol\";\nimport {IStorageLoupe} from \"../facets/base/interfaces/IStorageLoupe.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IERC677Receiver} from \"../interfaces/ERC/IERC677Receiver.sol\";\nimport {IERC165} from \"../interfaces/ERC/IERC165.sol\";\n\n/**\n * @title DefaultFallbackHandler\n * @dev A default fallback handler for Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DefaultFallbackHandler is IDiamondLoupe {\n /**\n * @notice Sets the middleware diamond for Barz wallet as a fallback handler\n * @dev This contract is also a diamond that holds the default facets to reduce gas cost for wallet activation.\n * Within the constructor this conducts diamond cut to initially setup the diamond. This is a non-upgradeable contract\n * @param _diamondCutFacet Address if diamond cut facet\n * @param _accountFacet Address account facet\n * @param _tokenReceiverFacet Address of token receiver facet\n * @param _diamondLoupeFacet Address of diamond loupe facet\n */\n constructor(\n address _diamondCutFacet,\n address _accountFacet,\n address _tokenReceiverFacet,\n address _diamondLoupeFacet\n ) payable {\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](4);\n bytes4[] memory functionSelectors = new bytes4[](1);\n functionSelectors[0] = IDiamondCut.diamondCut.selector;\n\n bytes4[] memory accountFunctionSelectors = new bytes4[](5);\n accountFunctionSelectors[0] = IAccountFacet.execute.selector;\n accountFunctionSelectors[1] = IAccountFacet.executeBatch.selector;\n accountFunctionSelectors[2] = BaseAccount.validateUserOp.selector;\n accountFunctionSelectors[3] = BaseAccount.getNonce.selector;\n accountFunctionSelectors[4] = BaseAccount.entryPoint.selector;\n\n bytes4[] memory receiverFacetSelectors = new bytes4[](5);\n receiverFacetSelectors[0] = IERC721Receiver.onERC721Received.selector;\n receiverFacetSelectors[1] = IERC1155Receiver.onERC1155Received.selector;\n receiverFacetSelectors[2] = IERC1155Receiver\n .onERC1155BatchReceived\n .selector;\n receiverFacetSelectors[3] = IERC777Recipient.tokensReceived.selector;\n receiverFacetSelectors[4] = IERC677Receiver.onTokenTransfer.selector;\n\n bytes4[] memory loupeFacetSelectors = new bytes4[](9);\n loupeFacetSelectors[0] = IDiamondLoupe.facets.selector;\n loupeFacetSelectors[1] = IDiamondLoupe.facetFunctionSelectors.selector;\n loupeFacetSelectors[2] = IDiamondLoupe.facetAddresses.selector;\n loupeFacetSelectors[3] = IDiamondLoupe.facetAddress.selector;\n loupeFacetSelectors[4] = IERC165.supportsInterface.selector;\n loupeFacetSelectors[5] = IStorageLoupe.facetsFromStorage.selector;\n loupeFacetSelectors[6] = IStorageLoupe\n .facetFunctionSelectorsFromStorage\n .selector;\n loupeFacetSelectors[7] = IStorageLoupe\n .facetAddressesFromStorage\n .selector;\n loupeFacetSelectors[8] = IStorageLoupe.facetAddressFromStorage.selector;\n\n {\n cut[0] = IDiamondCut.FacetCut({\n facetAddress: _diamondCutFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: functionSelectors\n });\n cut[1] = IDiamondCut.FacetCut({\n facetAddress: _accountFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: accountFunctionSelectors\n });\n cut[2] = IDiamondCut.FacetCut({\n facetAddress: _tokenReceiverFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: receiverFacetSelectors\n });\n cut[3] = IDiamondCut.FacetCut({\n facetAddress: _diamondLoupeFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: loupeFacetSelectors\n });\n\n DefaultLibDiamond.diamondCut(cut, address(0), \"\");\n }\n }\n\n /**\n * @notice Returns the facet information of call facets registered to this diamond.\n * @return facets_ The facet struct array including all facet information\n */\n function facets() external view override returns (Facet[] memory facets_) {\n DefaultLibDiamond.DiamondStorage storage ds = DefaultLibDiamond\n .diamondStorage();\n uint256 numFacets = ds.facetAddresses.length;\n facets_ = new Facet[](numFacets);\n for (uint256 i; i < numFacets; ) {\n address facetAddress_ = ds.facetAddresses[i];\n facets_[i].facetAddress = facetAddress_;\n facets_[i].functionSelectors = ds\n .facetFunctionSelectors[facetAddress_]\n .functionSelectors;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Gets all the function selectors provided by a facet.\n * @param _facet The facet address.\n * @return facetFunctionSelectors_\n */\n function facetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n facetFunctionSelectors_ = DefaultLibDiamond\n .diamondStorage()\n .facetFunctionSelectors[_facet]\n .functionSelectors;\n }\n\n /**\n * @notice Get all the facet addresses used by a diamond.\n * @return facetAddresses_\n */\n function facetAddresses()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n facetAddresses_ = DefaultLibDiamond.diamondStorage().facetAddresses;\n }\n\n /** @notice Gets the facet that supports the given selector.\n * @dev If facet is not found return address(0).\n * @param _functionSelector The function selector.\n * @return facetAddress_ The facet address.\n */\n function facetAddress(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n facetAddress_ = DefaultLibDiamond\n .diamondStorage()\n .selectorToFacetAndPosition[_functionSelector]\n .facetAddress;\n }\n}\n" + }, + "contracts/infrastructure/FacetRegistry.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport {IFacetRegistry} from \"./interfaces/IFacetRegistry.sol\";\n\n/**\n * @title Facet Registry\n * @dev Contract to keep track of facets & function selectors addable to user wallets\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract FacetRegistry is IFacetRegistry, Ownable2Step {\n mapping(address => FacetRegistryConfig) private facets;\n\n /**\n * @notice Transfers the ownership of the contract to the given owner\n * @param _owner Address of owner who has access to initialize the default security variables for security manager\n */\n constructor(address _owner) {\n transferOwnership(_owner);\n _transferOwnership(_owner);\n }\n\n /**\n * @dev Registers a facet and it's function selectors to registry\n * @param _facet address of facet\n * @param _facetSelectors list of function selectors of the facet\n */\n function registerFacetFunctionSelectors(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external override onlyOwner {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n for (uint256 i; i < _facetSelectors.length; ) {\n if (facetConfig.info[_facetSelectors[i]].exists)\n revert FacetRegistry__FacetSelectorAlreadyRegistered();\n\n facetConfig.info[_facetSelectors[i]].exists = true;\n facetConfig.info[_facetSelectors[i]].index = uint128(\n facetConfig.selectors.length\n );\n facetConfig.selectors.push(_facetSelectors[i]);\n unchecked {\n ++i;\n }\n }\n emit FacetFunctionSelectorsRegistered(_facet, _facetSelectors);\n }\n\n /**\n * @dev Removes a registered facet and it's corresponding selectors from registry\n * @param _facet address of facet\n * @param _facetSelectors list of function selectors of the facet\n */\n function removeFacetFunctionSelectors(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external override onlyOwner {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n for (uint256 i; i < _facetSelectors.length; ) {\n if (!facetConfig.info[_facetSelectors[i]].exists)\n revert FacetRegistry__UnregisteredFacetSelector();\n\n bytes4 lastSelector = facetConfig.selectors[\n facetConfig.selectors.length - 1\n ];\n if (_facetSelectors[i] != lastSelector) {\n uint128 targetIndex = facetConfig\n .info[_facetSelectors[i]]\n .index;\n facetConfig.selectors[targetIndex] = lastSelector;\n facetConfig.info[lastSelector].index = targetIndex;\n }\n facetConfig.selectors.pop();\n delete facetConfig.info[_facetSelectors[i]];\n\n unchecked {\n ++i;\n }\n }\n emit FacetFunctionSelectorsRemoved(_facet, _facetSelectors);\n }\n\n /**\n * @dev Checks if a facet and it's selectors given is registered to facet registry\n * @param _facet Address of facet\n * @param _facetSelectors List of function selectors of the facet\n */\n function areFacetFunctionSelectorsRegistered(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external view override returns (bool) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n if (_facetSelectors.length == 0) return false;\n for (uint256 i; i < _facetSelectors.length; ) {\n if (!facetConfig.info[_facetSelectors[i]].exists) return false;\n unchecked {\n ++i;\n }\n }\n return true;\n }\n\n /**\n * @dev Checks if a facet and it's selector given is registered to facet registry\n * @param _facet Address of facet\n * @param _facetSelector List of function selectors of the facet\n * @return isRegistered Bool value showing if the selector is registered\n */\n function isFacetFunctionSelectorRegistered(\n address _facet,\n bytes4 _facetSelector\n ) external view override returns (bool isRegistered) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n isRegistered = facetConfig.info[_facetSelector].exists;\n }\n\n /**\n * @dev Get the registered selectors of facet from registry\n * @param _facet Address of facet\n * @return selectors Selectors registered to facet\n */\n function getFacetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory selectors) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n selectors = facetConfig.selectors;\n }\n}\n" + }, + "contracts/infrastructure/interfaces/IFacetRegistry.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Registry Interface\n * @dev Interface for Facet Registry contract to keep track of facets & function selectors addable to user wallets\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IFacetRegistry {\n struct FacetRegistryConfig {\n bytes4[] selectors;\n mapping(bytes4 => FacetInfo) info;\n }\n struct FacetInfo {\n bool exists;\n uint128 index;\n }\n\n event FacetFunctionSelectorsRegistered(\n address facet,\n bytes4[] facetSelectors\n );\n event FacetFunctionSelectorsRemoved(address facet, bytes4[] facetSelectors);\n\n error FacetRegistry__FacetSelectorAlreadyRegistered();\n error FacetRegistry__UnregisteredFacetSelector();\n\n function registerFacetFunctionSelectors(\n address facet,\n bytes4[] calldata facetSelectors\n ) external;\n\n function removeFacetFunctionSelectors(\n address facet,\n bytes4[] calldata facetSelectors\n ) external;\n\n function areFacetFunctionSelectorsRegistered(\n address facet,\n bytes4[] calldata facetSelectors\n ) external view returns (bool);\n\n function isFacetFunctionSelectorRegistered(\n address facet,\n bytes4 facetSelector\n ) external view returns (bool);\n\n function getFacetFunctionSelectors(\n address facet\n ) external view returns (bytes4[] memory);\n}\n" + }, + "contracts/infrastructure/interfaces/ISecurityManager.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Registry Interface\n * @dev Infrastructure contract to manage security parameters of users\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface ISecurityManager {\n error SecurityManager__OutOfBoundary();\n error SecurityManager__CallerNotWallet();\n error SecurityManager__AlreadyIntialized();\n\n function initializeAdditionSecurityPeriod(\n uint128 defaultAdditionSecurityPeriod,\n uint128 minAdditionSecurityPeriod,\n uint128 maxAdditionSecurityPeriod\n ) external;\n\n function initializeRemovalSecurityPeriod(\n uint128 defaultRemovalSecurityPeriod,\n uint128 minRemovalSecurityPeriod,\n uint128 maxRemovalSecurityPeriod\n ) external;\n\n function initializeApprovalValidationPeriod(\n uint128 defaultApprovalValidationPeriod,\n uint128 minApprovalValidationPeriod,\n uint128 maxApprovalValidationPeriod\n ) external;\n\n function initializeMigrationPeriod(\n uint128 defaultMigrationPeriod,\n uint128 minMigrationPeriod,\n uint128 maxMigrationPeriod\n ) external;\n\n function initializeLockPeriod(\n uint128 defaultLockPeriod,\n uint128 minLockPeriod,\n uint128 maxLockPeriod\n ) external;\n\n function initializeRecoveryPeriod(\n uint128 defaultRecoveryPeriod,\n uint128 minRecoveryPeriod,\n uint128 maxRecoveryPeriod\n ) external;\n\n function initializeSecurityWindow(\n uint128 defaultSecurityWindow,\n uint128 minSecurityWindow,\n uint128 maxSecurityWindow\n ) external;\n\n function setAdditionSecurityPeriod(\n address wallet,\n uint128 additionSecurityPeriod\n ) external;\n\n function setRemovalSecurityPeriod(\n address wallet,\n uint128 removalSecurityPeriod\n ) external;\n\n function setSecurityWindow(address wallet, uint128 securityWindow) external;\n\n function setRecoveryPeriod(address wallet, uint128 recoveryPeriod) external;\n\n function setLockPeriod(address wallet, uint128 lockPeriod) external;\n\n function setApprovalValidationPeriod(\n address wallet,\n uint128 approvalValidationPeriod\n ) external;\n\n function setMigrationPeriod(\n address wallet,\n uint128 migrationPeriod\n ) external;\n\n function additionSecurityPeriodOf(\n address wallet\n ) external view returns (uint128);\n\n function removalSecurityPeriodOf(\n address wallet\n ) external view returns (uint128);\n\n function securityWindowOf(address wallet) external view returns (uint128);\n\n function recoveryPeriodOf(address wallet) external view returns (uint128);\n\n function lockPeriodOf(address wallet) external view returns (uint128);\n\n function migrationPeriodOf(address wallet) external view returns (uint128);\n\n function approvalValidationPeriodOf(\n address wallet\n ) external view returns (uint128);\n}\n" + }, + "contracts/infrastructure/RemoteStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IGuardianFacet} from \"../facets/interfaces/IGuardianFacet.sol\";\n\n/**\n * @title Remote Storage\n * @dev Remote storage allows you to associate addresses with an array of addresses on a standalone smart contract.\n * This could be useful when you don't want to use the local diamond storage for some purpose.\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\nabstract contract RemoteStorage {\n struct StorageConfig {\n address[] addresses;\n mapping(address => Info) info;\n }\n\n struct Info {\n bool exists;\n uint128 index;\n }\n\n mapping(address => StorageConfig) internal configs;\n\n event Added(address _address);\n event Removed(address _address);\n\n error RemoteStorage__CallerNotOwner();\n error RemoteStorage__CallerNotGuardianOrOwner();\n error RemoteStorage__AlreadyExists();\n error RemoteStorage__NotFound();\n error RemoteStorage__CallerNotGuardian();\n\n bytes4 constant IS_GUARDIAN_SELECTOR =\n bytes4(keccak256(\"isGuardian(address)\"));\n bytes4 constant GUARDIAN_COUNT = bytes4(keccak256(\"guardianCount()\"));\n\n /**\n * @notice Modifier to only allow the self to call. Reverts otherwise\n */\n modifier onlyWallet(address _wallet) {\n if (msg.sender != _wallet) revert RemoteStorage__CallerNotOwner();\n _;\n }\n\n /**\n * @notice Enfore the callet to be wallet of guardian of the wallet\n * @param _wallet Address of wallet\n */\n function enforceGuardianOrWallet(address _wallet) internal view {\n if (msg.sender == _wallet) return;\n address facetAddress = IDiamondLoupe(_wallet).facetAddress(\n IS_GUARDIAN_SELECTOR\n );\n if (facetAddress != address(0))\n if (IGuardianFacet(_wallet).isGuardian(msg.sender)) return;\n revert RemoteStorage__CallerNotGuardianOrOwner();\n }\n\n /**\n * @notice Enforce the caller to be wallet IF guardians doesn't exists and only guardian when guardians exists\n * @param _wallet Target wallet address to be handled by infrastructure contracts\n */\n function enforceWalletOrGuardianIfExists(address _wallet) internal view {\n address facetAddress;\n if (msg.sender == _wallet) {\n facetAddress = IDiamondLoupe(_wallet).facetAddress(GUARDIAN_COUNT);\n if (facetAddress == address(0)) return;\n uint256 guardianCount = IGuardianFacet(_wallet).guardianCount();\n if (guardianCount != 0) revert RemoteStorage__CallerNotGuardian();\n return;\n }\n facetAddress = IDiamondLoupe(_wallet).facetAddress(\n IS_GUARDIAN_SELECTOR\n );\n if (facetAddress != address(0))\n if (IGuardianFacet(_wallet).isGuardian(msg.sender)) return;\n\n revert RemoteStorage__CallerNotGuardianOrOwner();\n }\n\n /**\n * @notice Add address to storage and reverts if the address already exists.\n * This is an internal function callable from contracts that inherit this abstract contract\n * @param _wallet Address of wallet to add the address\n * @param _address Address to be added to wallet\n */\n function addAddress(address _wallet, address _address) internal {\n StorageConfig storage config = configs[_wallet];\n if (config.info[_address].exists) revert RemoteStorage__AlreadyExists();\n\n config.info[_address].exists = true;\n config.info[_address].index = uint128(config.addresses.length);\n config.addresses.push(_address);\n\n emit Added(_address);\n }\n\n /**\n * @notice Remove address from storage and reverts if the address already exists.\n * This is an internal function callable from contracts that inherit this abstract contract\n * @param _wallet Address of wallet to remove the address\n * @param _address Address to be removed from wallet\n */\n function removeAddress(address _wallet, address _address) internal {\n StorageConfig storage config = configs[_wallet];\n if (!config.info[_address].exists) revert RemoteStorage__NotFound();\n\n address lastAddress = config.addresses[config.addresses.length - 1];\n if (_address != lastAddress) {\n uint128 targetIndex = config.info[_address].index;\n config.addresses[targetIndex] = lastAddress;\n config.info[lastAddress].index = targetIndex;\n }\n config.addresses.pop();\n delete config.info[_address];\n\n emit Removed(_address);\n }\n\n /**\n * @notice Returns the address added to the given wallet\n * @param _wallet Address of wallet to fetch the addresses added to it\n * @return addresses List of addresses added to the wallet\n */\n function getAddresses(\n address _wallet\n ) internal view returns (address[] memory addresses) {\n StorageConfig storage config = configs[_wallet];\n addresses = new address[](config.addresses.length);\n uint addressesLen = config.addresses.length;\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns bool value checking if the address exists in the given wallet address\n * @param _wallet Wallet address to check\n * @param _address Address to fetch if the address if added to given wallet\n * @return exists_ Bool value showing if the address exists in wallet\n */\n function exists(\n address _wallet,\n address _address\n ) internal view returns (bool exists_) {\n exists_ = configs[_wallet].info[_address].exists;\n }\n\n /**\n * @notice Returns the number of addresses added to the wallet\n * @param _wallet Address of wallet to check\n * @return count_ Number of addresses added to wallet\n */\n function count(address _wallet) internal view returns (uint256 count_) {\n count_ = configs[_wallet].addresses.length;\n }\n}\n" + }, + "contracts/infrastructure/SecurityManager.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport {ISecurityManager} from \"./interfaces/ISecurityManager.sol\";\n\n/**\n * @title Security Manager\n * @dev Infrastructure contract to manage security parameters of users\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract SecurityManager is ISecurityManager, Ownable2Step {\n uint128 public minAdditionSecurityPeriod;\n uint128 public maxAdditionSecurityPeriod;\n uint128 private defaultAdditionSecurityPeriod;\n\n uint128 public minRemovalSecurityPeriod;\n uint128 public maxRemovalSecurityPeriod;\n uint128 private defaultRemovalSecurityPeriod;\n\n uint128 public minSecurityWindow;\n uint128 public maxSecurityWindow;\n uint128 private defaultSecurityWindow;\n\n uint128 public minRecoveryPeriod;\n uint128 public maxRecoveryPeriod;\n uint128 private defaultRecoveryPeriod;\n\n uint128 public minLockPeriod;\n uint128 public maxLockPeriod;\n uint128 private defaultLockPeriod;\n\n uint128 public minApprovalValidationPeriod;\n uint128 public maxApprovalValidationPeriod;\n uint128 private defaultApprovalValidationPeriod;\n\n uint128 public minMigrationPeriod;\n uint128 public maxMigrationPeriod;\n uint128 private defaultMigrationPeriod;\n\n bool public _isAdditionSecurityPeriodInitialized;\n bool public _isRemovalSecurityPeriodInitialized;\n bool public _isSecurityWindowInitialized;\n bool public _isRecoveryPeriodInitialized;\n bool public _isLockPeriodInitialized;\n bool public _isApprovalValidationPeriodInitialized;\n bool public _isMigrationPeriodInitialized;\n\n mapping(address => CustomSecurityConfig) securityConfigs;\n\n struct CustomSecurityConfig {\n uint128 additionSecurityPeriod;\n uint128 removalSecurityPeriod;\n uint128 securityWindow;\n uint128 recoveryPeriod;\n uint128 lockPeriod;\n uint128 approvalValidationPeriod;\n uint128 migrationPeriod;\n }\n\n /**\n * @notice Modifier to only allow wallet itself to make a call to wallet\n */\n modifier onlyWallet(address _wallet) {\n if (msg.sender != _wallet) revert SecurityManager__CallerNotWallet();\n _;\n }\n\n /**\n * @notice Modifier to revert if the variable is already initialized\n */\n modifier initializer(bool _isInitialized) {\n if (_isInitialized) revert SecurityManager__AlreadyIntialized();\n _;\n }\n\n /**\n * @notice Transfers the ownership of the contract to the given owner\n * @param _owner Address of owner who has access to initialize the default security variables for security manager\n */\n constructor(address _owner) {\n transferOwnership(_owner);\n _transferOwnership(_owner);\n }\n\n /**\n * @notice Sets the initial default/min/max addition security period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultAdditionSecurityPeriod Default Addition Security Period for all Barz contracts\n * @param _minAdditionSecurityPeriod Minimum Addition Security Period for all Barz contracts\n * @param _maxAdditionSecurityPeriod Maximum Addition Security Period for all Barz contracts\n */\n function initializeAdditionSecurityPeriod(\n uint128 _defaultAdditionSecurityPeriod,\n uint128 _minAdditionSecurityPeriod,\n uint128 _maxAdditionSecurityPeriod\n )\n external\n override\n onlyOwner\n initializer(_isAdditionSecurityPeriodInitialized)\n {\n _isAdditionSecurityPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultAdditionSecurityPeriod,\n _minAdditionSecurityPeriod,\n _maxAdditionSecurityPeriod\n );\n defaultAdditionSecurityPeriod = _defaultAdditionSecurityPeriod;\n minAdditionSecurityPeriod = _minAdditionSecurityPeriod;\n maxAdditionSecurityPeriod = _maxAdditionSecurityPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max removal security period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultRemovalSecurityPeriod Default Removal Security Period for all Barz contracts\n * @param _minRemovalSecurityPeriod Minimum Removal Security Period for all Barz contracts\n * @param _maxRemovalSecurityPeriod Maximum Removal Security Period for all Barz contracts\n */\n function initializeRemovalSecurityPeriod(\n uint128 _defaultRemovalSecurityPeriod,\n uint128 _minRemovalSecurityPeriod,\n uint128 _maxRemovalSecurityPeriod\n )\n external\n override\n onlyOwner\n initializer(_isRemovalSecurityPeriodInitialized)\n {\n _isRemovalSecurityPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultRemovalSecurityPeriod,\n _minRemovalSecurityPeriod,\n _maxRemovalSecurityPeriod\n );\n defaultRemovalSecurityPeriod = _defaultRemovalSecurityPeriod;\n minRemovalSecurityPeriod = _minRemovalSecurityPeriod;\n maxRemovalSecurityPeriod = _maxRemovalSecurityPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/maxd security window for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultSecurityWindow Default Security Window for all Barz contracts\n * @param _minSecurityWindow Minimum Security Window for all Barz contracts\n * @param _maxSecurityWindow Maximum Security Window for all Barz contracts\n */\n function initializeSecurityWindow(\n uint128 _defaultSecurityWindow,\n uint128 _minSecurityWindow,\n uint128 _maxSecurityWindow\n ) external override onlyOwner initializer(_isSecurityWindowInitialized) {\n _isSecurityWindowInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultSecurityWindow,\n _minSecurityWindow,\n _maxSecurityWindow\n );\n defaultSecurityWindow = _defaultSecurityWindow;\n minSecurityWindow = _minSecurityWindow;\n maxSecurityWindow = _maxSecurityWindow;\n }\n\n /**\n * @notice Sets the initial default/min/max recovery period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultRecoveryPeriod Default Recovery Period for all Barz contracts\n * @param _minRecoveryPeriod Minimum Recovery Period for all Barz contracts\n * @param _maxRecoveryPeriod Maximum Recovery Period for all Barz contracts\n */\n function initializeRecoveryPeriod(\n uint128 _defaultRecoveryPeriod,\n uint128 _minRecoveryPeriod,\n uint128 _maxRecoveryPeriod\n ) external override onlyOwner initializer(_isRecoveryPeriodInitialized) {\n _isRecoveryPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultRecoveryPeriod,\n _minRecoveryPeriod,\n _maxRecoveryPeriod\n );\n defaultRecoveryPeriod = _defaultRecoveryPeriod;\n minRecoveryPeriod = _minRecoveryPeriod;\n maxRecoveryPeriod = _maxRecoveryPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max lock period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultLockPeriod Default Lock Period for all Barz contracts\n * @param _minLockPeriod Minimum Lock Period for all Barz contracts\n * @param _maxLockPeriod Maximum Lock Period for all Barz contracts\n */\n function initializeLockPeriod(\n uint128 _defaultLockPeriod,\n uint128 _minLockPeriod,\n uint128 _maxLockPeriod\n ) external override onlyOwner initializer(_isLockPeriodInitialized) {\n _isLockPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultLockPeriod,\n _minLockPeriod,\n _maxLockPeriod\n );\n defaultLockPeriod = _defaultLockPeriod;\n minLockPeriod = _minLockPeriod;\n maxLockPeriod = _maxLockPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max approval validation period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultApprovalValidationPeriod Default Approval Validation Period for all Barz contracts\n * @param _minApprovalValidationPeriod Minimum Approval Validation Period for all Barz contracts\n * @param _maxApprovalValidationPeriod Maximum Approval Validation Period for all Barz contracts\n */\n function initializeApprovalValidationPeriod(\n uint128 _defaultApprovalValidationPeriod,\n uint128 _minApprovalValidationPeriod,\n uint128 _maxApprovalValidationPeriod\n )\n external\n override\n onlyOwner\n initializer(_isApprovalValidationPeriodInitialized)\n {\n _isApprovalValidationPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultApprovalValidationPeriod,\n _minApprovalValidationPeriod,\n _maxApprovalValidationPeriod\n );\n defaultApprovalValidationPeriod = _defaultApprovalValidationPeriod;\n minApprovalValidationPeriod = _minApprovalValidationPeriod;\n maxApprovalValidationPeriod = _maxApprovalValidationPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max migration period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultMigrationPeriod Default Migration Period for all Barz contracts\n * @param _minMigrationPeriod Minimum Migration Period for all Barz contracts\n * @param _maxMigrationPeriod Maximum Migration Period for all Barz contracts\n */\n function initializeMigrationPeriod(\n uint128 _defaultMigrationPeriod,\n uint128 _minMigrationPeriod,\n uint128 _maxMigrationPeriod\n ) external override onlyOwner initializer(_isMigrationPeriodInitialized) {\n _isMigrationPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultMigrationPeriod,\n _minMigrationPeriod,\n _maxMigrationPeriod\n );\n defaultMigrationPeriod = _defaultMigrationPeriod;\n minMigrationPeriod = _minMigrationPeriod;\n maxMigrationPeriod = _maxMigrationPeriod;\n }\n\n /**\n * @notice Wallet owner sets the addition security period for the wallet. Only the owner of wallet can call this function.\n * The addition security period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _additionSecurityPeriod Custom Addition Security Period for the wallet\n */\n function setAdditionSecurityPeriod(\n address _wallet,\n uint128 _additionSecurityPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _additionSecurityPeriod,\n minAdditionSecurityPeriod,\n maxAdditionSecurityPeriod\n );\n securityConfigs[_wallet]\n .additionSecurityPeriod = _additionSecurityPeriod;\n }\n\n /**\n * @notice Wallet owner sets the removal security period for the wallet. Only the owner of wallet can call this function.\n * The removal security period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _removalSecurityPeriod Custom Removal Security Period for the wallet\n */\n function setRemovalSecurityPeriod(\n address _wallet,\n uint128 _removalSecurityPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _removalSecurityPeriod,\n minRemovalSecurityPeriod,\n maxRemovalSecurityPeriod\n );\n securityConfigs[_wallet].removalSecurityPeriod = _removalSecurityPeriod;\n }\n\n /**\n * @notice Wallet owner sets the security window for the wallet. Only the owner of wallet can call this function.\n * The security window should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _securityWindow Custom Security Window for the wallet\n */\n function setSecurityWindow(\n address _wallet,\n uint128 _securityWindow\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _securityWindow,\n minSecurityWindow,\n maxSecurityWindow\n );\n securityConfigs[_wallet].securityWindow = _securityWindow;\n }\n\n /**\n * @notice Wallet owner sets the recovery period for the wallet. Only the owner of wallet can call this function.\n * The recovery period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _recoveryPeriod Custom recovery period for the wallet\n */\n function setRecoveryPeriod(\n address _wallet,\n uint128 _recoveryPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _recoveryPeriod,\n minRecoveryPeriod,\n maxRecoveryPeriod\n );\n securityConfigs[_wallet].recoveryPeriod = _recoveryPeriod;\n }\n\n /**\n * @notice Wallet owner sets the lock period for the wallet. Only the owner of wallet can call this function.\n * The lock period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _lockPeriod Custom Lock period for the wallet\n */\n function setLockPeriod(\n address _wallet,\n uint128 _lockPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(_lockPeriod, minLockPeriod, maxLockPeriod);\n securityConfigs[_wallet].lockPeriod = _lockPeriod;\n }\n\n /**\n * @notice Wallet owner sets the approval validation period for the wallet. Only the owner of wallet can call this function.\n * The approval validation period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _approvalValidationPeriod Custom approval validation period for the wallet\n */\n function setApprovalValidationPeriod(\n address _wallet,\n uint128 _approvalValidationPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _approvalValidationPeriod,\n minApprovalValidationPeriod,\n maxApprovalValidationPeriod\n );\n securityConfigs[_wallet]\n .approvalValidationPeriod = _approvalValidationPeriod;\n }\n\n /**\n * @notice Wallet owner sets the migration period for the wallet. Only the owner of wallet can call this function.\n * The migration period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _migrationPeriod Custom migration period for the wallet\n */\n\n function setMigrationPeriod(\n address _wallet,\n uint128 _migrationPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _migrationPeriod,\n minMigrationPeriod,\n maxMigrationPeriod\n );\n securityConfigs[_wallet].migrationPeriod = _migrationPeriod;\n }\n\n /**\n * @notice Returns the addition security period. Returns default value when custom addition security period is not set\n * @param _wallet Address of wallet\n * @return additionSecurityPeriod Addition Security Period of the given Barz account or wallet\n */\n function additionSecurityPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 additionSecurityPeriod)\n {\n additionSecurityPeriod = securityConfigs[_wallet]\n .additionSecurityPeriod;\n additionSecurityPeriod = (additionSecurityPeriod == 0)\n ? defaultAdditionSecurityPeriod\n : additionSecurityPeriod;\n }\n\n /**\n * @notice Returns the removal security period. Returns default value when custom removal security period is not set\n * @param _wallet Address of wallet\n * @return removalSecurityPeriod Removal Security Period of the given Barz account or wallet\n */\n function removalSecurityPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 removalSecurityPeriod)\n {\n removalSecurityPeriod = securityConfigs[_wallet].removalSecurityPeriod;\n removalSecurityPeriod = (removalSecurityPeriod == 0)\n ? defaultRemovalSecurityPeriod\n : removalSecurityPeriod;\n }\n\n /**\n * @notice Returns the security window. Returns default value when custom security window is not set\n * @param _wallet Address of wallet\n * @return securityWindow Security window of the given Barz account or wallet\n */\n function securityWindowOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 securityWindow)\n {\n securityWindow = securityConfigs[_wallet].securityWindow;\n securityWindow = (securityWindow == 0)\n ? defaultSecurityWindow\n : securityWindow;\n }\n\n /**\n * @notice Returns the recovery period. Returns default value when custom recovery period is not set\n * @param _wallet Address of wallet\n * @return recoveryPeriod Recovery Period of the given Barz account or wallet\n */\n function recoveryPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 recoveryPeriod)\n {\n recoveryPeriod = securityConfigs[_wallet].recoveryPeriod;\n recoveryPeriod = (recoveryPeriod == 0)\n ? defaultRecoveryPeriod\n : recoveryPeriod;\n }\n\n /**\n * @notice Returns the lock period. Returns default value when custom lock period is not set\n * @param _wallet Address of wallet\n * @return lockPeriod Lock Period of the given Barz account or wallet\n */\n function lockPeriodOf(\n address _wallet\n ) public view override onlyWallet(_wallet) returns (uint128 lockPeriod) {\n lockPeriod = securityConfigs[_wallet].lockPeriod;\n lockPeriod = (lockPeriod == 0) ? defaultLockPeriod : lockPeriod;\n }\n\n /**\n * @notice Returns the approval validation period. Returns default value when custom approval validation period is not set\n * @param _wallet Address of wallet\n * @return approvalValidationPeriod Approval Validation Period of the given Barz account or wallet\n */\n function approvalValidationPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityConfigs[_wallet]\n .approvalValidationPeriod;\n approvalValidationPeriod = (approvalValidationPeriod == 0)\n ? defaultApprovalValidationPeriod\n : approvalValidationPeriod;\n }\n\n /**\n * @notice Returns the migration period. Returns default value when custom migration period is not set\n * @param _wallet Address of wallet\n * @return migrationPeriod Migration Period of the given Barz account or wallet\n */\n function migrationPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 migrationPeriod)\n {\n migrationPeriod = securityConfigs[_wallet].migrationPeriod;\n migrationPeriod = (migrationPeriod == 0)\n ? defaultMigrationPeriod\n : migrationPeriod;\n }\n\n /**\n * @notice Validates if the period is smaller than the max period or bigger than the min period\n * @param _period Period to be checked\n * @param _minPeriod Minimum period\n * @param _maxPeriod Maximum period\n */\n function _validatePeriodBoundaries(\n uint128 _period,\n uint128 _minPeriod,\n uint128 _maxPeriod\n ) internal pure {\n if (_period >= _maxPeriod || _period <= _minPeriod)\n revert SecurityManager__OutOfBoundary();\n }\n}\n" + }, + "contracts/infrastructure/WhitelistStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {RemoteStorage} from \"./RemoteStorage.sol\";\n\n/**\n * @title Whitelist storage\n * @dev Maps addresses to the corresponsing array of whitelisted addresses for each of them.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract WhitelistStorage is RemoteStorage {\n /**\n * @dev Add the address to the whitelist storage\n * @param _wallet User wallet\n * @param _address Address to be whitelisted\n */\n function whitelistAddress(address _wallet, address _address) external {\n enforceWalletOrGuardianIfExists(_wallet);\n addAddress(_wallet, _address);\n }\n\n /**\n * @dev Removes the address from the whitelist storage\n * @param _wallet User wallet\n * @param _address Address to be removed from the whitelist\n */\n function blacklistAddress(address _wallet, address _address) external {\n enforceGuardianOrWallet(_wallet);\n removeAddress(_wallet, _address);\n }\n\n /**\n * @dev Returns whether the address exists in the whitelist storage, associated with the wallet\n * @param _wallet User wallet\n * @param _address Address to be whitelisted\n */\n function isWhitelisted(\n address _wallet,\n address _address\n ) external view returns (bool) {\n return exists(_wallet, _address);\n }\n\n /**\n * @dev Returns all whitelisted addresses associated with the wallet\n * @param _wallet User wallet\n */\n function getWhitelistedAddresses(\n address _wallet\n ) external view returns (address[] memory) {\n return getAddresses(_wallet);\n }\n}\n" + }, + "contracts/interfaces/ERC/IERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\n\npragma solidity 0.8.21;\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155Receiver {\n /**\n * @dev Handles the receipt of a single ERC1155 token type. This function is\n * called at the end of a `safeTransferFrom` after the balance has been updated.\n *\n * NOTE: To accept the transfer, this must return\n * `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n * (i.e. 0xf23a6e61, or its own function selector).\n *\n * @param operator The address which initiated the transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param id The ID of the token being transferred\n * @param value The amount of tokens being transferred\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n ) external returns (bytes4);\n\n /**\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\n * is called at the end of a `safeBatchTransferFrom` after the balances have\n * been updated.\n *\n * NOTE: To accept the transfer(s), this must return\n * `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n * (i.e. 0xbc197c81, or its own function selector).\n *\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "contracts/interfaces/ERC/IERC1271.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\ninterface IERC1271 {\n function isValidSignature(\n bytes32 hash,\n bytes memory signature\n ) external view returns (bytes4);\n}\n" + }, + "contracts/interfaces/ERC/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\ninterface IERC165 {\n /// @notice Query if a contract implements an interface\n /// @param interfaceId The interface identifier, as specified in ERC-165\n /// @dev Interface identification is specified in ERC-165. This function\n /// uses less than 30,000 gas.\n /// @return `true` if the contract implements `interfaceID` and\n /// `interfaceID` is not 0xffffffff, `false` otherwise\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/IERC173.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\n/// @title ERC-173 Contract Ownership Standard\n/// Note: the ERC-165 identifier for this interface is 0x7f5828d0\n/* is ERC165 */\ninterface IERC173 {\n /// @dev This emits when ownership of a contract changes.\n event OwnershipTransferred(\n address indexed previousOwner,\n address indexed newOwner\n );\n\n /// @notice Get the address of the owner\n /// @return owner_ The address of the owner.\n function owner() external view returns (address owner_);\n\n /// @notice Set the address of the new owner of the contract\n /// @dev Set _newOwner to address(0) to renounce any ownership.\n /// @param _newOwner The address of the new owner of the contract\n function transferOwnership(address _newOwner) external;\n}\n" + }, + "contracts/interfaces/ERC/IERC677Receiver.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\ninterface IERC677Receiver {\n function onTokenTransfer(\n address sender,\n uint value,\n bytes calldata data\n ) external pure returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155 is IERC165 {\n /**\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n */\n event TransferSingle(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256 id,\n uint256 value\n );\n\n /**\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n * transfers.\n */\n event TransferBatch(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\n\n /**\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n * `approved`.\n */\n event ApprovalForAll(\n address indexed account,\n address indexed operator,\n bool approved\n );\n\n /**\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n *\n * If an {URI} event was emitted for `id`, the standard\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n * returned by {IERC1155MetadataURI-uri}.\n */\n event URI(string value, uint256 indexed id);\n\n /**\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(\n address account,\n uint256 id\n ) external view returns (uint256);\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] calldata accounts,\n uint256[] calldata ids\n ) external view returns (uint256[] memory);\n\n /**\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n *\n * Emits an {ApprovalForAll} event.\n *\n * Requirements:\n *\n * - `operator` cannot be the caller.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n *\n * See {setApprovalForAll}.\n */\n function isApprovedForAll(\n address account,\n address operator\n ) external view returns (bool);\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes calldata data\n ) external;\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(\n address indexed owner,\n address indexed spender,\n uint256 value\n );\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` 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 amount) 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(\n address owner,\n address spender\n ) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the 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 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` 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(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(\n address spender,\n uint256 addedValue\n ) external returns (bool);\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(\n address spender,\n uint256 subtractedValue\n ) external returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(\n address indexed from,\n address indexed to,\n uint256 indexed tokenId\n );\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(\n address indexed owner,\n address indexed approved,\n uint256 indexed tokenId\n );\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(\n address indexed owner,\n address indexed operator,\n bool approved\n );\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(\n uint256 tokenId\n ) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(\n address owner,\n address operator\n ) external view returns (bool);\n}\n" + }, + "contracts/interfaces/IBarz.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Barz Interface\n * @dev Interface of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IBarz {\n error Barz__InitializationFailure();\n}\n" + }, + "contracts/interfaces/IBarzFactory.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Barz} from \"../Barz.sol\";\n\n/**\n * @title Barz Factory Interface\n * @dev Interface of contract to easily deploy Barz to a pre-computed address with a single call\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IBarzFactory {\n function createAccount(\n address verificationFacet,\n bytes calldata owner,\n uint256 salt\n ) external returns (Barz);\n\n function getAddress(\n address verificationFacet,\n bytes calldata owner,\n uint256 salt\n ) external view returns (address);\n\n function getBytecode(\n address accountFacet,\n address verificationFacet,\n address entryPoint,\n address facetRegistry,\n address defaultFallback,\n bytes memory ownerPublicKey\n ) external pure returns (bytes memory);\n\n function getCreationCode() external pure returns (bytes memory);\n}\n" + }, + "contracts/libraries/DefaultLibDiamond.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\n\nerror InitializationFunctionReverted(\n address _initializationContractAddress,\n bytes _calldata\n);\n\nlibrary DefaultLibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION =\n keccak256(\"trustwallet.barz.diamond.storage\");\n\n struct FacetAddressAndPosition {\n address facetAddress;\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\n }\n\n struct FacetFunctionSelectors {\n bytes4[] functionSelectors;\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\n }\n\n struct DiamondStorage {\n // maps function selector to the facet address and\n // the position of the selector in the facetFunctionSelectors.selectors array\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\n // maps facet addresses to function selectors\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\n // facet addresses\n address[] facetAddresses;\n // Used to query if a contract implements an interface.\n // Used to implement ERC-165.\n mapping(bytes4 => bool) supportedInterfaces;\n }\n\n function diamondStorage()\n internal\n pure\n returns (DiamondStorage storage ds)\n {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n event DiamondCut(\n IDiamondCut.FacetCut[] _diamondCut,\n address _init,\n bytes _calldata\n );\n\n // Internal function version of diamondCut\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n for (\n uint256 facetIndex;\n facetIndex < _diamondCut.length;\n facetIndex++\n ) {\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\n if (action == IDiamondCut.FacetCutAction.Add) {\n addFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\n replaceFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\n removeFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else {\n revert(\"LibDiamondCut: Incorrect FacetCutAction\");\n }\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Add facet can't be address(0)\"\n );\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n require(\n oldFacetAddress == address(0),\n \"LibDiamondCut: Can't add function that already exists\"\n );\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function replaceFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Replace facet can't be address(0)\"\n );\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n require(\n oldFacetAddress != _facetAddress,\n \"LibDiamondCut: Can't replace function with same facet\"\n );\n removeFunction(ds, oldFacetAddress, selector);\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function removeFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n // if function does not exist then do nothing and return\n require(\n _facetAddress == address(0),\n \"LibDiamondCut: Remove facet address must be address(0)\"\n );\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n removeFunction(ds, oldFacetAddress, selector);\n }\n }\n\n function addFacet(\n DiamondStorage storage ds,\n address _facetAddress\n ) internal {\n enforceHasContractCode(\n _facetAddress,\n \"LibDiamondCut: New facet has no code\"\n );\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds\n .facetAddresses\n .length;\n ds.facetAddresses.push(_facetAddress);\n }\n\n function addFunction(\n DiamondStorage storage ds,\n bytes4 _selector,\n uint96 _selectorPosition,\n address _facetAddress\n ) internal {\n ds\n .selectorToFacetAndPosition[_selector]\n .functionSelectorPosition = _selectorPosition;\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(\n _selector\n );\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\n }\n\n function removeFunction(\n DiamondStorage storage ds,\n address _facetAddress,\n bytes4 _selector\n ) internal {\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Can't remove function that doesn't exist\"\n );\n // an immutable function is a function defined directly in a diamond\n require(\n _facetAddress != address(this),\n \"LibDiamondCut: Can't remove immutable function\"\n );\n // replace selector with last selector, then delete last selector\n uint256 selectorPosition = ds\n .selectorToFacetAndPosition[_selector]\n .functionSelectorPosition;\n uint256 lastSelectorPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors\n .length - 1;\n // if not the same then replace _selector with lastSelector\n if (selectorPosition != lastSelectorPosition) {\n bytes4 lastSelector = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors[lastSelectorPosition];\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[\n selectorPosition\n ] = lastSelector;\n ds\n .selectorToFacetAndPosition[lastSelector]\n .functionSelectorPosition = uint96(selectorPosition);\n }\n // delete the last selector\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\n delete ds.selectorToFacetAndPosition[_selector];\n\n // if no more selectors for facet address then delete the facet address\n if (lastSelectorPosition == 0) {\n // replace facet address with last facet address and delete last facet address\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\n uint256 facetAddressPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .facetAddressPosition;\n if (facetAddressPosition != lastFacetAddressPosition) {\n address lastFacetAddress = ds.facetAddresses[\n lastFacetAddressPosition\n ];\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\n ds\n .facetFunctionSelectors[lastFacetAddress]\n .facetAddressPosition = facetAddressPosition;\n }\n ds.facetAddresses.pop();\n delete ds\n .facetFunctionSelectors[_facetAddress]\n .facetAddressPosition;\n }\n }\n\n function initializeDiamondCut(\n address _init,\n bytes memory _calldata\n ) internal {\n if (_init == address(0)) {\n return;\n }\n enforceHasContractCode(\n _init,\n \"LibDiamondCut: _init address has no code\"\n );\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length > 0) {\n // bubble up error\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(error)\n revert(add(32, error), returndata_size)\n }\n } else {\n revert InitializationFunctionReverted(_init, _calldata);\n }\n }\n }\n\n function enforceHasContractCode(\n address _contract,\n string memory _errorMessage\n ) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize > 0, _errorMessage);\n }\n}\n" + }, + "contracts/libraries/LibAppStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SafeCast} from \"@openzeppelin/contracts/utils/math/SafeCast.sol\";\nimport {IEntryPoint} from \"../aa-4337/interfaces/IEntryPoint.sol\";\nimport {IFacetRegistry} from \"../infrastructure/interfaces/IFacetRegistry.sol\";\n\n/*\n * @title App Storage\n * @dev App storage for Barz contract to prevent storage collision\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\n\nstruct Lock {\n uint64 release;\n bytes4 locker;\n}\n\nstruct InitializersStorage {\n // NOTE: initialized is a variable to make sure the initialization is only done once.\n uint8 signerInitialized;\n uint8 accountInitialized;\n uint8 restrictionsInitialized;\n}\n\nstruct AppStorage {\n mapping(uint256 => InitializersStorage) initStorage;\n uint8 signerMigration;\n bytes4 validateOwnerSignatureSelector;\n IEntryPoint entryPoint;\n IFacetRegistry facetRegistry;\n mapping(uint256 => Lock) locks;\n}\n\nlibrary LibAppStorage {\n error LibAppStorage__AccountAlreadyUninitialized();\n error LibAppStorage__AccountMustBeUninitialized();\n error LibAppStorage__SignerAlreadyUninitialized();\n error LibAppStorage__SignerMustBeUninitialized();\n\n function appStorage() internal pure returns (AppStorage storage ds) {\n assembly {\n ds.slot := 0\n }\n }\n\n function setSignerUninitialized() internal {\n AppStorage storage s = appStorage();\n if (1 != s.initStorage[0].signerInitialized) {\n revert LibAppStorage__SignerAlreadyUninitialized();\n }\n s.initStorage[0].signerInitialized = 0;\n }\n\n function getValidateOwnerSignatureSelector()\n internal\n view\n returns (bytes4 selector)\n {\n selector = appStorage().validateOwnerSignatureSelector;\n }\n\n function setValidateOwnerSignatureSelector(\n bytes4 _validateOwnerSignatureSelector\n ) internal {\n appStorage()\n .validateOwnerSignatureSelector = _validateOwnerSignatureSelector;\n }\n\n function enforceSignerInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].signerInitialized) {\n revert LibAppStorage__SignerMustBeUninitialized();\n }\n s.initStorage[0].signerInitialized = 1;\n }\n\n function enforceAccountInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].accountInitialized) {\n revert LibAppStorage__AccountMustBeUninitialized();\n }\n s.initStorage[0].accountInitialized = 1;\n }\n\n function initiateSignerMigration() internal {\n appStorage().signerMigration = 1;\n }\n\n function enforceSignerMigration() internal view {\n if (1 != appStorage().signerMigration) {\n revert LibAppStorage__AccountMustBeUninitialized();\n }\n }\n\n function finalizeSignerMigration() internal {\n appStorage().signerMigration = 0;\n }\n\n function setLock(uint256 _releaseAfter, bytes4 _locker) internal {\n appStorage().locks[0] = Lock(SafeCast.toUint64(_releaseAfter), _locker);\n }\n\n function enforceRestrictionsInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].restrictionsInitialized)\n revert LibAppStorage__SignerMustBeUninitialized();\n s.initStorage[0].restrictionsInitialized = 1;\n }\n\n function setRestrictionsUninitialized() internal {\n AppStorage storage s = appStorage();\n if (1 != s.initStorage[0].restrictionsInitialized)\n revert LibAppStorage__AccountAlreadyUninitialized();\n s.initStorage[0].restrictionsInitialized = 0;\n }\n}\n\ncontract BarzStorage {\n AppStorage internal s;\n modifier onlyWhenUnlocked() {\n require(\n uint64(block.timestamp) >= s.locks[0].release,\n \"Account Locked\"\n );\n _;\n }\n modifier onlyWhenLocked() {\n require(\n uint64(block.timestamp) < s.locks[0].release,\n \"Account Unlocked\"\n );\n _;\n }\n}\n" + }, + "contracts/libraries/LibDiamond.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\n\nerror InitializationFunctionReverted(\n address _initializationContractAddress,\n bytes _calldata\n);\n\nlibrary LibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION =\n keccak256(\"trustwallet.barz.diamond.storage\");\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\n bytes4(keccak256(\"verifyRestrictions(address,address,uint256,bytes)\"));\n struct DiamondStorage {\n // maps function selectors to the facets that execute the functions.\n // and maps the selectors to their position in the selectorSlots array.\n // func selector => address facet, selector position\n mapping(bytes4 => bytes32) facets;\n // array of slots of function selectors.\n // each slot holds 8 function selectors.\n mapping(uint256 => bytes32) selectorSlots;\n // The number of function selectors in selectorSlots\n uint16 selectorCount;\n // Used to query if a contract implements an interface.\n // Used to implement ERC-165.\n mapping(bytes4 => bool) supportedInterfaces;\n // Default Fallback Handler of the barz.\n IDiamondLoupe defaultFallbackHandler;\n }\n\n function diamondStorage()\n internal\n pure\n returns (DiamondStorage storage ds)\n {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n function enforceIsSelf() internal view {\n require(msg.sender == address(this), \"LibDiamond: Caller not self\");\n }\n\n event DiamondCut(\n IDiamondCut.FacetCut[] _diamondCut,\n address _init,\n bytes _calldata\n );\n\n bytes32 constant CLEAR_ADDRESS_MASK =\n bytes32(uint256(0xffffffffffffffffffffffff));\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\n\n // Internal function version of diamondCut\n // This code is almost the same as the external diamondCut,\n // except it is using 'Facet[] memory _diamondCut' instead of\n // 'Facet[] calldata _diamondCut'.\n // The code is duplicated to prevent copying calldata to memory which\n // causes an error for a two dimensional array.\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n DiamondStorage storage ds = diamondStorage();\n uint256 originalSelectorCount = ds.selectorCount;\n uint256 selectorCount = originalSelectorCount;\n bytes32 selectorSlot;\n // Check if last selector slot is not full\n // \"selectorCount & 7\" is a gas efficient modulo by eight \"selectorCount % 8\"\n if (selectorCount & 7 > 0) {\n // get last selectorSlot\n // \"selectorSlot >> 3\" is a gas efficient division by 8 \"selectorSlot / 8\"\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\n }\n // loop through diamond cut\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\n selectorCount,\n selectorSlot,\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].action,\n _diamondCut[facetIndex].functionSelectors\n );\n\n unchecked {\n facetIndex++;\n }\n }\n if (selectorCount != originalSelectorCount) {\n ds.selectorCount = uint16(selectorCount);\n }\n // If last selector slot is not full\n // \"selectorCount & 7\" is a gas efficient modulo by eight \"selectorCount % 8\"\n if (selectorCount & 7 > 0) {\n // \"selectorSlot >> 3\" is a gas efficient division by 8 \"selectorSlot / 8\"\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addReplaceRemoveFacetSelectors(\n uint256 _selectorCount,\n bytes32 _selectorSlot,\n address _newFacetAddress,\n IDiamondCut.FacetCutAction _action,\n bytes4[] memory _selectors\n ) internal returns (uint256, bytes32) {\n DiamondStorage storage ds = diamondStorage();\n require(\n _selectors.length > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n if (_action == IDiamondCut.FacetCutAction.Add) {\n enforceHasContractCode(\n _newFacetAddress,\n \"LibDiamondCut: Add facet has no code\"\n );\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n require(\n address(bytes20(oldFacet)) == address(0),\n \"LibDiamondCut: Can't add function that already exists\"\n );\n // add facet for selector\n ds.facets[selector] =\n bytes20(_newFacetAddress) |\n bytes32(_selectorCount);\n // \"_selectorCount & 7\" is a gas efficient modulo by eight \"_selectorCount % 8\"\n // \" << 5 is the same as multiplying by 32 ( * 32)\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\n // clear selector position in slot and add selector\n _selectorSlot =\n (_selectorSlot &\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\n (bytes32(selector) >> selectorInSlotPosition);\n // if slot is full then write it to storage\n if (selectorInSlotPosition == 224) {\n // \"_selectorSlot >> 3\" is a gas efficient division by 8 \"_selectorSlot / 8\"\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\n _selectorSlot = 0;\n }\n _selectorCount++;\n\n unchecked {\n selectorIndex++;\n }\n }\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\n enforceHasContractCode(\n _newFacetAddress,\n \"LibDiamondCut: Replace facet has no code\"\n );\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n address oldFacetAddress = address(bytes20(oldFacet));\n // only useful if immutable functions exist\n require(\n oldFacetAddress != address(this),\n \"LibDiamondCut: Can't replace immutable function\"\n );\n require(\n oldFacetAddress != _newFacetAddress,\n \"LibDiamondCut: Can't replace function with same function\"\n );\n require(\n oldFacetAddress != address(0),\n \"LibDiamondCut: Can't replace function that doesn't exist\"\n );\n // replace old facet address\n ds.facets[selector] =\n (oldFacet & CLEAR_ADDRESS_MASK) |\n bytes20(_newFacetAddress);\n\n unchecked {\n selectorIndex++;\n }\n }\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\n require(\n _newFacetAddress == address(0),\n \"LibDiamondCut: Remove facet address must be address(0)\"\n );\n // \"_selectorCount >> 3\" is a gas efficient division by 8 \"_selectorCount / 8\"\n uint256 selectorSlotCount = _selectorCount >> 3;\n // \"_selectorCount & 7\" is a gas efficient modulo by eight \"_selectorCount % 8\"\n uint256 selectorInSlotIndex = _selectorCount & 7;\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n if (_selectorSlot == 0) {\n // get last selectorSlot\n selectorSlotCount--;\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\n selectorInSlotIndex = 7;\n } else {\n selectorInSlotIndex--;\n }\n bytes4 lastSelector;\n uint256 oldSelectorsSlotCount;\n uint256 oldSelectorInSlotPosition;\n // adding a block here prevents stack too deep error\n {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n require(\n address(bytes20(oldFacet)) != address(0),\n \"LibDiamondCut: Can't remove function that doesn't exist\"\n );\n // only useful if immutable functions exist\n require(\n address(bytes20(oldFacet)) != address(this),\n \"LibDiamondCut: Can't remove immutable function\"\n );\n // replace selector with last selector in ds.facets\n // gets the last selector\n // \" << 5 is the same as multiplying by 32 ( * 32)\n lastSelector = bytes4(\n _selectorSlot << (selectorInSlotIndex << 5)\n );\n if (lastSelector != selector) {\n // update last selector slot position info\n ds.facets[lastSelector] =\n (oldFacet & CLEAR_ADDRESS_MASK) |\n bytes20(ds.facets[lastSelector]);\n }\n delete ds.facets[selector];\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\n // \"oldSelectorCount >> 3\" is a gas efficient division by 8 \"oldSelectorCount / 8\"\n oldSelectorsSlotCount = oldSelectorCount >> 3;\n // \"oldSelectorCount & 7\" is a gas efficient modulo by eight \"oldSelectorCount % 8\"\n // \" << 5 is the same as multiplying by 32 ( * 32)\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\n }\n if (oldSelectorsSlotCount != selectorSlotCount) {\n bytes32 oldSelectorSlot = ds.selectorSlots[\n oldSelectorsSlotCount\n ];\n // clears the selector we are deleting and puts the last selector in its place.\n oldSelectorSlot =\n (oldSelectorSlot &\n ~(CLEAR_SELECTOR_MASK >>\n oldSelectorInSlotPosition)) |\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\n // update storage with the modified slot\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\n } else {\n // clears the selector we are deleting and puts the last selector in its place.\n _selectorSlot =\n (_selectorSlot &\n ~(CLEAR_SELECTOR_MASK >>\n oldSelectorInSlotPosition)) |\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\n }\n if (selectorInSlotIndex == 0) {\n delete ds.selectorSlots[selectorSlotCount];\n _selectorSlot = 0;\n }\n\n unchecked {\n selectorIndex++;\n }\n }\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\n } else {\n revert(\"LibDiamondCut: Incorrect FacetCutAction\");\n }\n return (_selectorCount, _selectorSlot);\n }\n\n function initializeDiamondCut(\n address _init,\n bytes memory _calldata\n ) internal {\n if (_init == address(0)) {\n return;\n }\n enforceHasContractCode(\n _init,\n \"LibDiamondCut: _init address has no code\"\n );\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length > 0) {\n // bubble up error\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(error)\n revert(add(32, error), returndata_size)\n }\n } else {\n revert InitializationFunctionReverted(_init, _calldata);\n }\n }\n }\n\n function enforceHasContractCode(\n address _contract,\n string memory _errorMessage\n ) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize > 0, _errorMessage);\n }\n\n function restrictionsFacet() internal view returns (address facetAddress_) {\n facetAddress_ = address(\n bytes20(\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\n )\n );\n }\n}\n" + }, + "contracts/libraries/LibFacetStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Storage\n * @dev Storage contract to store each facets variables with diamond storage\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\n\nstruct Secp256k1VerificationStorage {\n address signer;\n}\n\nstruct Secp256r1VerificationStorage {\n uint256[2] q;\n}\n\nstruct GuardianStorage {\n mapping(bytes32 => uint256) pending;\n mapping(uint8 => StorageConfig) configs;\n}\n\nstruct Info {\n bool exists;\n uint128 index;\n}\n\nstruct StorageConfig {\n address[] addresses;\n mapping(address => Info) info;\n}\n\nstruct RecoveryConfig {\n bytes recoveryPublicKey;\n uint64 executeAfter;\n}\n\nstruct ApprovalConfig {\n bool isApproved;\n uint64 validUntil;\n}\n\nstruct RecoveryApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isNewOwnerApproved;\n}\n\nstruct RecoveryStorage {\n mapping(uint8 => RecoveryConfig) recoveryConfigs;\n mapping(uint8 => RecoveryApprovalConfig) recoveryApprovalConfigs;\n uint128 nonce;\n}\n\nstruct RestrictionsStorage {\n address[] restrictions;\n mapping(address => bool) exists;\n}\n\nstruct SignatureMigrationConfig {\n bytes migrationPublicKey;\n address migrationVerificationFacet;\n bytes4[] migrationSelectors;\n uint64 migrateAfter;\n}\n\nstruct SignatureMigrationApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isMigrationApproved;\n}\n\nstruct SignatureMigrationStorage {\n mapping(uint8 => SignatureMigrationConfig) migrationConfigs;\n mapping(uint8 => SignatureMigrationApprovalConfig) migrationApprovalConfigs;\n uint128 nonce;\n}\n\nstruct DiamondCutApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isDiamondCutApproved;\n}\n\nstruct DiamondCutStorage {\n mapping(uint8 => DiamondCutApprovalConfig) diamondCutApprovalConfigs;\n uint128 nonce;\n}\n\nstruct LockStorage {\n uint128 nonce;\n}\n\nlibrary LibFacetStorage {\n bytes32 constant K1_STORAGE_POSITION =\n keccak256(\n \"v0.trustwallet.diamond.storage.Secp256k1VerificationStorage\"\n );\n bytes32 constant R1_STORAGE_POSITION =\n keccak256(\n \"v0.trustwallet.diamond.storage.Secp256r1VerificationStorage\"\n );\n bytes32 constant GUARDIAN_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.GuardianStorage\");\n bytes32 constant RECOVERY_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.RecoveryStorage\");\n bytes32 constant RESTRICTION_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.RestrictionsStorage\");\n bytes32 constant MIGRATION_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.SignatureMigrationStorage\");\n bytes32 constant DIAMONDCUT_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.DiamondCutStorage\");\n bytes32 constant LOCK_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.LockStorage\");\n\n function k1Storage()\n internal\n pure\n returns (Secp256k1VerificationStorage storage ds)\n {\n bytes32 storagePosition = K1_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function r1Storage()\n internal\n pure\n returns (Secp256r1VerificationStorage storage ds)\n {\n bytes32 storagePosition = R1_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function guardianStorage()\n internal\n pure\n returns (GuardianStorage storage ds)\n {\n bytes32 storagePosition = GUARDIAN_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function recoveryStorage()\n internal\n pure\n returns (RecoveryStorage storage ds)\n {\n bytes32 storagePosition = RECOVERY_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function restrictionsStorage()\n internal\n pure\n returns (RestrictionsStorage storage ds)\n {\n bytes32 storagePosition = RESTRICTION_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function migrationStorage()\n internal\n pure\n returns (SignatureMigrationStorage storage ds)\n {\n bytes32 storagePosition = MIGRATION_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function diamondCutStorage()\n internal\n pure\n returns (DiamondCutStorage storage ds)\n {\n bytes32 storagePosition = DIAMONDCUT_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function lockStorage() internal pure returns (LockStorage storage ds) {\n bytes32 storagePosition = LOCK_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n}\n" + }, + "contracts/libraries/LibGuardian.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibFacetStorage, StorageConfig} from \"./LibFacetStorage.sol\";\n\n/**\n * @title LibGuardian\n * @dev Internal Library to provide utility feature for Guardians stored in Guardian Facet Storage\n * @author David Yongjun Kim (@Powerstream3604)\n */\nlibrary LibGuardian {\n function majorityOfGuardians()\n internal\n view\n returns (uint256 guardianNumber)\n {\n uint256 guardianLength = guardianCount();\n guardianNumber = (guardianLength == 0) ? 0 : guardianLength / 2 + 1;\n }\n\n function isGuardian(address _guardian) internal view returns (bool) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n return config.info[_guardian].exists;\n }\n\n function guardianCount() internal view returns (uint256) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n return config.addresses.length;\n }\n\n function getGuardians() internal view returns (address[] memory) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n address[] memory addresses = new address[](config.addresses.length);\n uint256 addressesLen = config.addresses.length;\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n return addresses;\n }\n}\n" + }, + "contracts/libraries/LibLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {LibDiamond} from \"./LibDiamond.sol\";\n\n/**\n * @title LibLoupe\n * @dev Internal Library to provide utility feature for reading the state of diamond facets\n * @author David Yongjun Kim (@Powerstream3604)\n */\nlibrary LibLoupe {\n /// @notice Gets all facets and their selectors.\n /// @return facets_ Facet\n function facets()\n internal\n view\n returns (IDiamondLoupe.Facet[] memory facets_)\n {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facets_ = new IDiamondLoupe.Facet[](ds.selectorCount);\n uint16[] memory numFacetSelectors = new uint16[](ds.selectorCount);\n uint256 numFacets;\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facetAddress_ = address(bytes20(ds.facets[selector]));\n bool continueLoop;\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n if (facets_[facetIndex].facetAddress == facetAddress_) {\n facets_[facetIndex].functionSelectors[\n numFacetSelectors[facetIndex]\n ] = selector;\n // probably will never have more than 256 functions from one facet contract\n require(numFacetSelectors[facetIndex] < 255);\n numFacetSelectors[facetIndex]++;\n continueLoop = true;\n break;\n }\n }\n if (continueLoop) {\n continue;\n }\n facets_[numFacets].facetAddress = facetAddress_;\n facets_[numFacets].functionSelectors = new bytes4[](\n ds.selectorCount\n );\n facets_[numFacets].functionSelectors[0] = selector;\n numFacetSelectors[numFacets] = 1;\n numFacets++;\n }\n }\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n uint256 numSelectors = numFacetSelectors[facetIndex];\n bytes4[] memory selectors = facets_[facetIndex].functionSelectors;\n // setting the number of selectors\n assembly {\n mstore(selectors, numSelectors)\n }\n }\n // setting the number of facets\n assembly {\n mstore(facets_, numFacets)\n }\n }\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n /// @return _facetFunctionSelectors The selectors associated with a facet address.\n function facetFunctionSelectors(\n address _facet\n ) internal view returns (bytes4[] memory _facetFunctionSelectors) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n uint256 numSelectors;\n _facetFunctionSelectors = new bytes4[](ds.selectorCount);\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facet = address(bytes20(ds.facets[selector]));\n if (_facet == facet) {\n _facetFunctionSelectors[numSelectors] = selector;\n numSelectors++;\n }\n }\n }\n // Set the number of selectors in the array\n assembly {\n mstore(_facetFunctionSelectors, numSelectors)\n }\n }\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses()\n internal\n view\n returns (address[] memory facetAddresses_)\n {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facetAddresses_ = new address[](ds.selectorCount);\n uint256 numFacets;\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facetAddress_ = address(bytes20(ds.facets[selector]));\n bool continueLoop;\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n if (facetAddress_ == facetAddresses_[facetIndex]) {\n continueLoop = true;\n break;\n }\n }\n if (continueLoop) {\n continue;\n }\n facetAddresses_[numFacets] = facetAddress_;\n numFacets++;\n }\n }\n // Set the number of facet addresses in the array\n assembly {\n mstore(facetAddresses_, numFacets)\n }\n }\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(\n bytes4 _functionSelector\n ) internal view returns (address facetAddress_) {\n facetAddress_ = address(\n bytes20(LibDiamond.diamondStorage().facets[_functionSelector])\n );\n }\n}\n" + }, + "contracts/libraries/LibMultiSigStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Multi-sig Storage\n * @dev Storage contract for storing Multi-sig Facet variables in diamond storage pattern\n * @author David Yongjun Kim (@Powerstream3604)\n */\n\nstruct MultiSigStorage {\n mapping(address => address) owners;\n mapping(uint256 => mapping(address => mapping(bytes32 => uint256))) approvedHashes;\n uint256 ownerCount;\n uint256 threshold;\n uint256 counter;\n}\n\nlibrary LibMultiSigStorage {\n function multisigStorage()\n internal\n pure\n returns (MultiSigStorage storage ds)\n {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.MultiSigStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n}\n" + }, + "contracts/libraries/LibRecoverSpender.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title RecoverSpender\n * @dev Library to determine the action and spender of calldata\n * @author Ruslan Serebriakov (@rsrbk)\n */\nlibrary LibRecoverSpender {\n // ERC20, ERC721 & ERC1155 transfers & approvals\n bytes4 private constant ERC20_TRANSFER =\n bytes4(keccak256(\"transfer(address,uint256)\"));\n bytes4 private constant ERC20_APPROVE =\n bytes4(keccak256(\"approve(address,uint256)\"));\n bytes4 private constant ERC20_INCREASE_ALLOWANCE =\n bytes4(keccak256(\"increaseAllowance(address,uint256)\"));\n bytes4 private constant ERC20_DECREASE_ALLOWANCE =\n bytes4(keccak256(\"decreaseAllowance(address,uint256)\"));\n bytes4 private constant ERC721_SET_APPROVAL_FOR_ALL =\n bytes4(keccak256(\"setApprovalForAll(address,bool)\"));\n bytes4 private constant ERC721_TRANSFER_FROM =\n bytes4(keccak256(\"transferFrom(address,address,uint256)\"));\n bytes4 private constant ERC721_SAFE_TRANSFER_FROM =\n bytes4(keccak256(\"safeTransferFrom(address,address,uint256)\"));\n bytes4 private constant ERC721_SAFE_TRANSFER_FROM_BYTES =\n bytes4(keccak256(\"safeTransferFrom(address,address,uint256,bytes)\"));\n bytes4 private constant ERC1155_SAFE_TRANSFER_FROM =\n bytes4(\n keccak256(\"safeTransferFrom(address,address,uint256,uint256,bytes)\")\n );\n bytes4 private constant ERC1155_SAFE_BATCH_TRANSFER_FROM =\n bytes4(\n keccak256(\n \"safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)\"\n )\n );\n\n /**\n * @notice Helper method to recover the spender from a contract call.\n * The method returns the contract unless the call is to a standard method of a ERC20/ERC721/ERC1155 token\n * in which case the spender is recovered from the data.\n * @param _to The target contract.\n * @param _data The data payload.\n */\n function _recover(\n address _to,\n bytes memory _data\n ) internal pure returns (address spender) {\n if (_data.length >= 68) {\n bytes4 methodId;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n methodId := mload(add(_data, 0x20))\n }\n if (\n methodId == ERC20_TRANSFER ||\n methodId == ERC20_APPROVE ||\n methodId == ERC20_INCREASE_ALLOWANCE ||\n methodId == ERC20_DECREASE_ALLOWANCE ||\n methodId == ERC721_SET_APPROVAL_FOR_ALL\n ) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n spender := mload(add(_data, 0x24))\n }\n return spender;\n }\n if (\n methodId == ERC721_TRANSFER_FROM ||\n methodId == ERC721_SAFE_TRANSFER_FROM ||\n methodId == ERC721_SAFE_TRANSFER_FROM_BYTES ||\n methodId == ERC1155_SAFE_TRANSFER_FROM ||\n methodId == ERC1155_SAFE_BATCH_TRANSFER_FROM\n ) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n spender := mload(add(_data, 0x44))\n }\n return spender;\n }\n }\n\n spender = _to;\n }\n}\n" + }, + "contracts/libraries/LibUtils.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\n\nlibrary LibUtils {\n // Internal utility functions\n function mergeArrays(\n bytes4[] memory _array1,\n bytes4[] memory _array2\n ) internal pure returns (bytes4[] memory) {\n uint256 length1 = _array1.length;\n uint256 length2 = _array2.length;\n bytes4[] memory mergedArray = new bytes4[](length1 + length2);\n\n for (uint256 i; i < length1; ) {\n mergedArray[i] = _array1[i];\n unchecked {\n ++i;\n }\n }\n\n for (uint256 i; i < length2; ) {\n mergedArray[length1 + i] = _array2[i];\n unchecked {\n ++i;\n }\n }\n\n return mergedArray;\n }\n\n function removeFacetElement(\n IDiamondLoupe.Facet[] memory _facets,\n uint256 _index\n ) internal pure returns (IDiamondLoupe.Facet[] memory) {\n require(_index < _facets.length, \"Invalid index\");\n require(_facets.length != 0, \"Invalid array\");\n\n // Create a new array with a length of `_facets.length - 1`\n IDiamondLoupe.Facet[] memory newArray = new IDiamondLoupe.Facet[](\n _facets.length - 1\n );\n uint256 newArrayLength = newArray.length;\n // Iterate over the original array, skipping the element at the specified `index`\n for (uint256 i; i < newArrayLength; ) {\n if (i < _index) {\n newArray[i] = _facets[i];\n } else {\n newArray[i] = _facets[i + 1];\n }\n unchecked {\n ++i;\n }\n }\n\n return newArray;\n }\n\n function removeElement(\n bytes4[] memory _array,\n uint256 _index\n ) internal pure returns (bytes4[] memory) {\n require(_index < _array.length, \"Invalid index\");\n require(_array.length != 0, \"Invalid array\");\n\n bytes4[] memory newArray = new bytes4[](_array.length - 1);\n uint256 newArrayLength = newArray.length;\n for (uint256 i; i < newArrayLength; ) {\n if (i < _index) {\n newArray[i] = _array[i];\n } else {\n newArray[i] = _array[i + 1];\n }\n unchecked {\n ++i;\n }\n }\n\n return newArray;\n }\n\n function setValue(\n bytes4[] memory _keys,\n address[] memory _values,\n bytes4 _key,\n address _value\n ) internal pure returns (bytes4[] memory, address[] memory) {\n uint256 index = findIndex(_keys, _key);\n uint256 keysLength = _keys.length;\n if (index < keysLength) {\n _values[index] = _value;\n } else {\n // Create new storage arrays\n bytes4[] memory newKeys = new bytes4[](keysLength + 1);\n address[] memory newValues = new address[](_values.length + 1);\n\n // Copy values to the new storage arrays\n for (uint256 i; i < keysLength; ) {\n newKeys[i] = _keys[i];\n newValues[i] = _values[i];\n\n unchecked {\n ++i;\n }\n }\n\n // Add the new key-value pair\n newKeys[keysLength] = _key;\n newValues[_values.length] = _value;\n\n return (newKeys, newValues);\n }\n\n // If the key already exists, return the original arrays\n return (_keys, _values);\n }\n\n function getValue(\n bytes4[] memory _keys,\n address[] memory _values,\n bytes4 _key\n ) internal pure returns (address) {\n uint256 index = findIndex(_keys, _key);\n if (index >= _keys.length) return address(0);\n\n return _values[index];\n }\n\n function findIndex(\n bytes4[] memory _keys,\n bytes4 _key\n ) internal pure returns (uint256) {\n uint256 keysLength = _keys.length;\n for (uint256 i; i < keysLength; ) {\n if (_keys[i] == _key) {\n return i;\n }\n unchecked {\n ++i;\n }\n }\n return keysLength;\n }\n}\n" + }, + "contracts/restrictions/IRestriction.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Interface for restrictions\n * @dev Restriction is a contract which decides whether to approve a certain kind of transaction, based on its internal logic.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface IRestriction {\n /**\n * @dev Based on restriction's internal logic, it should accept or reject a certain transaction.\n * @param from The address of the sender, that will be signing the transaction.\n * @param to The receiving address.\n * @param value Amount of ETH to transfer from sender to recipient.\n * @param _calldata Optional field to include arbitrary data.\n * @return bool value for whether the check is passed\n */\n function check(\n address from,\n address to,\n uint256 value,\n bytes calldata _calldata\n ) external returns (bool);\n}\n" + }, + "contracts/restrictions/WhitelistRestriction.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibRecoverSpender} from \"../libraries/LibRecoverSpender.sol\";\nimport {WhitelistStorage} from \"../infrastructure/WhitelistStorage.sol\";\nimport {IRestriction} from \"./IRestriction.sol\";\n\n/**\n * @title Whitelist Restriction\n * @dev This restriction defines a list of accepted addresses and denies any interaction with addresses outside of it.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract WhitelistRestriction is IRestriction {\n WhitelistStorage public immutable whitelistStorage;\n\n constructor(WhitelistStorage _whitelistStorage) {\n whitelistStorage = _whitelistStorage;\n }\n\n /**\n * @notice Helper method to recover the spender from a contract call.\n * The method returns the contract unless the call is to a standard method of a ERC20/ERC721/ERC1155 token\n * in which case the spender is recovered from the data.\n * @param _to The target contract.\n * @param _data The data payload.\n */\n function recoverSpender(\n address _to,\n bytes memory _data\n ) public pure returns (address spender) {\n return LibRecoverSpender._recover(_to, _data);\n }\n\n /*\n * @dev IRestriction's implementation. It will allow transaction if the sender is whitelisted, or user, or the whitelist storage.\n * @param _from The address of the sender, that will be signing the transaction.\n * @param _to The receiving address.\n * @param _calldata Optional field to include arbitrary data.\n * @return result value for whether the check is passed\n */\n function check(\n address _from,\n address _to,\n uint256 /*_value*/,\n bytes calldata _calldata\n ) external view override returns (bool result) {\n return\n whitelistStorage.isWhitelisted(\n _from,\n LibRecoverSpender._recover(_to, _calldata)\n ) ||\n _to == address(whitelistStorage) ||\n _to == msg.sender;\n }\n}\n" + }, + "contracts/test/Counter.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\ncontract TestCounter {\n int private count = 0;\n\n function incrementCounter() public {\n count += 1;\n }\n\n function decrementCounter() public {\n count -= 1;\n }\n\n function getCount() public view returns (int) {\n return count;\n }\n}\n" + }, + "contracts/test/TestERC1155.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC1155/ERC1155.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\n\ncontract TestERC1155 is ERC1155 {\n using Counters for Counters.Counter;\n\n Counters.Counter private _tokenIds;\n\n constructor() ERC1155(\"\") {}\n\n function mint(address account, uint256 amount) external {\n uint256 tokenId = _getNextTokenId();\n _mint(account, tokenId, amount, \"\");\n }\n\n function mintBatch(\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes memory data\n ) external {\n require(\n ids.length == amounts.length,\n \"TestERC1155: arrays length mismatch\"\n );\n\n _mintBatch(to, ids, amounts, data);\n }\n\n function _getNextTokenId() private returns (uint256) {\n _tokenIds.increment();\n return _tokenIds.current();\n }\n}\n" + }, + "contracts/test/TestERC777.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC777/ERC777.sol\";\n\ncontract TestERC777 is ERC777 {\n constructor(\n address[] memory _operators\n ) ERC777(\"TestERC777\", \"TERC777\", _operators) {}\n\n function mint(address account, uint256 amount) external {\n _mint(account, amount, \"\", \"\");\n }\n}\n" + }, + "contracts/test/TestInvalidSecp256k1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IVerificationFacet} from \"../facets/interfaces/IVerificationFacet.sol\";\nimport {IERC1271} from \"../interfaces/ERC/IERC1271.sol\";\nimport {AppStorage, LibAppStorage, BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {LibFacetStorage, Secp256k1VerificationStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {UserOperation} from \"../aa-4337/interfaces/UserOperation.sol\";\n\n/**\n * @title Test Secp256k1 verification facet\n * @dev Default Ethereum's elliptic curve\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract TestInvalidSecp256k1VerificationFacet is BarzStorage, IERC1271 {\n using ECDSA for bytes32;\n error Secp256k1VerificationFacet__InvalidSignerLength();\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n\n event SignerUninitialized();\n\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n }\n\n // THIS INVALID FACET DOES NOT INCLUDE initializeSigner()\n // THIS FACET IS USED TO TEST WHEN initializeSigner() DOESN'T EXIST IN FACET\n\n function uninitializeSigner() external returns (uint256 uninitSuccess) {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view returns (uint256 validationData) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n return validateSignature(userOp, userOpHash, k1Storage.signer);\n }\n\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n address signer\n ) public pure returns (uint256) {\n bytes32 hash = userOpHash.toEthSignedMessageHash();\n if (signer != hash.recover(userOp.signature)) return 1;\n return 0;\n }\n\n // This is REMOVED for testing purpose\n function validateOwnerSignatureSelector() public pure returns (bytes4) {\n // return this.validateOwnerSignature.selector;\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n function owner() public view returns (bytes memory) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n return abi.encodePacked(k1Storage.signer);\n }\n\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure returns (bool) {\n return (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (_hash.recover(_signature) ==\n LibFacetStorage.k1Storage().signer)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n}\n" + }, + "contracts/test/TestNFT.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\n\ncontract TestNFT is ERC721 {\n using Counters for Counters.Counter;\n Counters.Counter private currentTokenId;\n\n constructor() ERC721(\"TestNFT\", \"TNFT\") {}\n\n function mint(address recipient) public returns (uint256) {\n currentTokenId.increment();\n uint256 newItemId = currentTokenId.current();\n _safeMint(recipient, newItemId);\n return newItemId;\n }\n}\n" + }, + "contracts/test/TestToken.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract TestToken is ERC20 {\n constructor()\n // solhint-disable-next-line no-empty-blocks\n ERC20(\"TST\", \"TestToken\")\n {}\n\n function mint(address sender, uint256 amount) external {\n _mint(sender, amount);\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 999999 + }, + "evmVersion": "paris", + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/deployments/optimism/solcInputs/4356503edd8ae34e73cb6dd1c8e2fc8a.json b/deployments/optimism/solcInputs/4356503edd8ae34e73cb6dd1c8e2fc8a.json new file mode 100644 index 0000000..db88715 --- /dev/null +++ b/deployments/optimism/solcInputs/4356503edd8ae34e73cb6dd1c8e2fc8a.json @@ -0,0 +1,354 @@ +{ + "language": "Solidity", + "sources": { + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby disabling any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable2Step.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./Ownable.sol\";\n\n/**\n * @dev Contract module which provides access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership} and {acceptOwnership}.\n *\n * This module is used through inheritance. It will make available all functions\n * from parent (Ownable).\n */\nabstract contract Ownable2Step is Ownable {\n address private _pendingOwner;\n\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Returns the address of the pending owner.\n */\n function pendingOwner() public view virtual returns (address) {\n return _pendingOwner;\n }\n\n /**\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual override onlyOwner {\n _pendingOwner = newOwner;\n emit OwnershipTransferStarted(owner(), newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual override {\n delete _pendingOwner;\n super._transferOwnership(newOwner);\n }\n\n /**\n * @dev The new owner accepts the ownership transfer.\n */\n function acceptOwnership() public virtual {\n address sender = _msgSender();\n require(pendingOwner() == sender, \"Ownable2Step: caller is not the new owner\");\n _transferOwnership(sender);\n }\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC1271.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC1271 standard signature validation method for\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\n *\n * _Available since v4.1._\n */\ninterface IERC1271 {\n /**\n * @dev Should return whether the signature provided is valid for the provided data\n * @param hash Hash of the data to be signed\n * @param signature Signature byte array associated with _data\n */\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\n}\n" + }, + "@openzeppelin/contracts/security/ReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor() {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n _nonReentrantBefore();\n _;\n _nonReentrantAfter();\n }\n\n function _nonReentrantBefore() private {\n // On the first call to nonReentrant, _status will be _NOT_ENTERED\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n }\n\n function _nonReentrantAfter() private {\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Returns true if the reentrancy guard is currently set to \"entered\", which indicates there is a\n * `nonReentrant` function in the call stack.\n */\n function _reentrancyGuardEntered() internal view returns (bool) {\n return _status == _ENTERED;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/ERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/ERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC1155.sol\";\nimport \"./IERC1155Receiver.sol\";\nimport \"./extensions/IERC1155MetadataURI.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of the basic standard multi-token.\n * See https://eips.ethereum.org/EIPS/eip-1155\n * Originally based on code by Enjin: https://github.com/enjin/erc-1155\n *\n * _Available since v3.1._\n */\ncontract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {\n using Address for address;\n\n // Mapping from token ID to account balances\n mapping(uint256 => mapping(address => uint256)) private _balances;\n\n // Mapping from account to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json\n string private _uri;\n\n /**\n * @dev See {_setURI}.\n */\n constructor(string memory uri_) {\n _setURI(uri_);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return\n interfaceId == type(IERC1155).interfaceId ||\n interfaceId == type(IERC1155MetadataURI).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC1155MetadataURI-uri}.\n *\n * This implementation returns the same URI for *all* token types. It relies\n * on the token type ID substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * Clients calling this function must replace the `\\{id\\}` substring with the\n * actual token type ID.\n */\n function uri(uint256) public view virtual override returns (string memory) {\n return _uri;\n }\n\n /**\n * @dev See {IERC1155-balanceOf}.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {\n require(account != address(0), \"ERC1155: address zero is not a valid owner\");\n return _balances[id][account];\n }\n\n /**\n * @dev See {IERC1155-balanceOfBatch}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] memory accounts,\n uint256[] memory ids\n ) public view virtual override returns (uint256[] memory) {\n require(accounts.length == ids.length, \"ERC1155: accounts and ids length mismatch\");\n\n uint256[] memory batchBalances = new uint256[](accounts.length);\n\n for (uint256 i = 0; i < accounts.length; ++i) {\n batchBalances[i] = balanceOf(accounts[i], ids[i]);\n }\n\n return batchBalances;\n }\n\n /**\n * @dev See {IERC1155-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC1155-isApprovedForAll}.\n */\n function isApprovedForAll(address account, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[account][operator];\n }\n\n /**\n * @dev See {IERC1155-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n _safeTransferFrom(from, to, id, amount, data);\n }\n\n /**\n * @dev See {IERC1155-safeBatchTransferFrom}.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n _safeBatchTransferFrom(from, to, ids, amounts, data);\n }\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n\n emit TransferSingle(operator, from, to, id, amount);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n for (uint256 i = 0; i < ids.length; ++i) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n }\n\n emit TransferBatch(operator, from, to, ids, amounts);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\n\n _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);\n }\n\n /**\n * @dev Sets a new URI for all token types, by relying on the token type ID\n * substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * By this mechanism, any occurrence of the `\\{id\\}` substring in either the\n * URI or any of the amounts in the JSON file at said URI will be replaced by\n * clients with the token type ID.\n *\n * For example, the `https://token-cdn-domain/\\{id\\}.json` URI would be\n * interpreted by clients as\n * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`\n * for token type ID 0x4cce0.\n *\n * See {uri}.\n *\n * Because these URIs cannot be meaningfully represented by the {URI} event,\n * this function emits no events.\n */\n function _setURI(string memory newuri) internal virtual {\n _uri = newuri;\n }\n\n /**\n * @dev Creates `amount` tokens of token type `id`, and assigns them to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _mint(address to, uint256 id, uint256 amount, bytes memory data) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _balances[id][to] += amount;\n emit TransferSingle(operator, address(0), to, id, amount);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n for (uint256 i = 0; i < ids.length; i++) {\n _balances[ids[i]][to] += amounts[i];\n }\n\n emit TransferBatch(operator, address(0), to, ids, amounts);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);\n }\n\n /**\n * @dev Destroys `amount` tokens of token type `id` from `from`\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `from` must have at least `amount` tokens of token type `id`.\n */\n function _burn(address from, uint256 id, uint256 amount) internal virtual {\n require(from != address(0), \"ERC1155: burn from the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n\n emit TransferSingle(operator, from, address(0), id, amount);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n */\n function _burnBatch(address from, uint256[] memory ids, uint256[] memory amounts) internal virtual {\n require(from != address(0), \"ERC1155: burn from the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n\n for (uint256 i = 0; i < ids.length; i++) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n }\n\n emit TransferBatch(operator, from, address(0), ids, amounts);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {\n require(owner != operator, \"ERC1155: setting approval status for self\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning, as well as batched variants.\n *\n * The same hook is called on both single and batched variants. For single\n * transfers, the length of the `ids` and `amounts` arrays will be 1.\n *\n * Calling conditions (for each `id` and `amount` pair):\n *\n * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * of token type `id` will be transferred to `to`.\n * - When `from` is zero, `amount` tokens of token type `id` will be minted\n * for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n * will be burned.\n * - `from` and `to` are never both zero.\n * - `ids` and `amounts` have the same, non-zero length.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any token transfer. This includes minting\n * and burning, as well as batched variants.\n *\n * The same hook is called on both single and batched variants. For single\n * transfers, the length of the `id` and `amount` arrays will be 1.\n *\n * Calling conditions (for each `id` and `amount` pair):\n *\n * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * of token type `id` will be transferred to `to`.\n * - When `from` is zero, `amount` tokens of token type `id` will be minted\n * for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n * will be burned.\n * - `from` and `to` are never both zero.\n * - `ids` and `amounts` have the same, non-zero length.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {}\n\n function _doSafeTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155Receiver.onERC1155Received.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non-ERC1155Receiver implementer\");\n }\n }\n }\n\n function _doSafeBatchTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (\n bytes4 response\n ) {\n if (response != IERC1155Receiver.onERC1155BatchReceived.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non-ERC1155Receiver implementer\");\n }\n }\n }\n\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {\n uint256[] memory array = new uint256[](1);\n array[0] = element;\n\n return array;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC1155.sol\";\n\n/**\n * @dev Interface of the optional ERC1155MetadataExtension interface, as defined\n * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155MetadataURI is IERC1155 {\n /**\n * @dev Returns the URI for token type `id`.\n *\n * If the `\\{id\\}` substring is present in the URI, it must be replaced by\n * clients with the actual token type ID.\n */\n function uri(uint256 id) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155 is IERC165 {\n /**\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n */\n event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);\n\n /**\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n * transfers.\n */\n event TransferBatch(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\n\n /**\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n * `approved`.\n */\n event ApprovalForAll(address indexed account, address indexed operator, bool approved);\n\n /**\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n *\n * If an {URI} event was emitted for `id`, the standard\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n * returned by {IERC1155MetadataURI-uri}.\n */\n event URI(string value, uint256 indexed id);\n\n /**\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) external view returns (uint256);\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] calldata accounts,\n uint256[] calldata ids\n ) external view returns (uint256[] memory);\n\n /**\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n *\n * Emits an {ApprovalForAll} event.\n *\n * Requirements:\n *\n * - `operator` cannot be the caller.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n *\n * See {setApprovalForAll}.\n */\n function isApprovedForAll(address account, address operator) external view returns (bool);\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155Receiver is IERC165 {\n /**\n * @dev Handles the receipt of a single ERC1155 token type. This function is\n * called at the end of a `safeTransferFrom` after the balance has been updated.\n *\n * NOTE: To accept the transfer, this must return\n * `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n * (i.e. 0xf23a6e61, or its own function selector).\n *\n * @param operator The address which initiated the transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param id The ID of the token being transferred\n * @param value The amount of tokens being transferred\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n ) external returns (bytes4);\n\n /**\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\n * is called at the end of a `safeBatchTransferFrom` after the balances have\n * been updated.\n *\n * NOTE: To accept the transfer(s), this must return\n * `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n * (i.e. 0xbc197c81, or its own function selector).\n *\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the default value returned by this function, unless\n * it's overridden.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(address from, address to, uint256 amount) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\n // decrementing then incrementing.\n _balances[to] += amount;\n }\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n unchecked {\n // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\n _balances[account] += amount;\n }\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n // Overflow not possible: amount <= accountBalance <= totalSupply.\n _totalSupply -= amount;\n }\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\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" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` 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 amount) 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 `amount` as the allowance of `spender` over the 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 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` 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 amount) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/ERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721.sol\";\nimport \"./IERC721Receiver.sol\";\nimport \"./extensions/IERC721Metadata.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/Strings.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\n using Address for address;\n using Strings for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\n\n // Mapping from token ID to approved address\n mapping(uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return\n interfaceId == type(IERC721).interfaceId ||\n interfaceId == type(IERC721Metadata).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _ownerOf(tokenId);\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token owner or approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n _requireMinted(tokenId);\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n _safeTransfer(from, to, tokenId, data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(address from, address to, uint256 tokenId, bytes memory data) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist\n */\n function _ownerOf(uint256 tokenId) internal view virtual returns (address) {\n return _owners[tokenId];\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _ownerOf(tokenId) != address(0);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n address owner = ERC721.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(address to, uint256 tokenId, bytes memory data) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId, 1);\n\n // Check that tokenId was not minted by `_beforeTokenTransfer` hook\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n unchecked {\n // Will not overflow unless all 2**256 token ids are minted to the same owner.\n // Given that tokens are minted one by one, it is impossible in practice that\n // this ever happens. Might change if we allow batch minting.\n // The ERC fails to describe this case.\n _balances[to] += 1;\n }\n\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(address(0), to, tokenId, 1);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n * This is an internal function that does not check if the sender is authorized to operate on the token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId, 1);\n\n // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook\n owner = ERC721.ownerOf(tokenId);\n\n // Clear approvals\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // Cannot overflow, as that would require more tokens to be burned/transferred\n // out than the owner initially received through minting and transferring in.\n _balances[owner] -= 1;\n }\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(owner, address(0), tokenId, 1);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(address from, address to, uint256 tokenId) internal virtual {\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId, 1);\n\n // Check that tokenId was not transferred by `_beforeTokenTransfer` hook\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n\n // Clear approvals from the previous owner\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // `_balances[from]` cannot overflow for the same reason as described in `_burn`:\n // `from`'s balance is the number of token held, which is at least one before the current\n // transfer.\n // `_balances[to]` could overflow in the conditions described in `_mint`. That would require\n // all 2**256 token ids to be minted, which in practice is impossible.\n _balances[from] -= 1;\n _balances[to] += 1;\n }\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId, 1);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721Receiver.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`.\n * - When `from` is zero, the tokens will be minted for `to`.\n * - When `to` is zero, ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}\n\n /**\n * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`.\n * - When `from` is zero, the tokens were minted for `to`.\n * - When `to` is zero, ``from``'s tokens were burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}\n\n /**\n * @dev Unsafe write access to the balances, used by extensions that \"mint\" tokens using an {ownerOf} override.\n *\n * WARNING: Anyone calling this MUST ensure that the balances remain consistent with the ownership. The invariant\n * being that for any address `a` the value returned by `balanceOf(a)` must be equal to the number of tokens such\n * that `ownerOf(tokenId)` is `a`.\n */\n // solhint-disable-next-line func-name-mixedcase\n function __unsafe_increaseBalance(address account, uint256 amount) internal {\n _balances[account] += amount;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721Receiver {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/ERC777.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC777/ERC777.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC777.sol\";\nimport \"./IERC777Recipient.sol\";\nimport \"./IERC777Sender.sol\";\nimport \"../ERC20/IERC20.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/introspection/IERC1820Registry.sol\";\n\n/**\n * @dev Implementation of the {IERC777} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n *\n * Support for ERC20 is included in this contract, as specified by the EIP: both\n * the ERC777 and ERC20 interfaces can be safely used when interacting with it.\n * Both {IERC777-Sent} and {IERC20-Transfer} events are emitted on token\n * movements.\n *\n * Additionally, the {IERC777-granularity} value is hard-coded to `1`, meaning that there\n * are no special restrictions in the amount of tokens that created, moved, or\n * destroyed. This makes integration with ERC20 applications seamless.\n *\n * CAUTION: This file is deprecated as of v4.9 and will be removed in the next major release.\n */\ncontract ERC777 is Context, IERC777, IERC20 {\n using Address for address;\n\n IERC1820Registry internal constant _ERC1820_REGISTRY = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n mapping(address => uint256) private _balances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n bytes32 private constant _TOKENS_SENDER_INTERFACE_HASH = keccak256(\"ERC777TokensSender\");\n bytes32 private constant _TOKENS_RECIPIENT_INTERFACE_HASH = keccak256(\"ERC777TokensRecipient\");\n\n // This isn't ever read from - it's only used to respond to the defaultOperators query.\n address[] private _defaultOperatorsArray;\n\n // Immutable, but accounts may revoke them (tracked in __revokedDefaultOperators).\n mapping(address => bool) private _defaultOperators;\n\n // For each account, a mapping of its operators and revoked default operators.\n mapping(address => mapping(address => bool)) private _operators;\n mapping(address => mapping(address => bool)) private _revokedDefaultOperators;\n\n // ERC20-allowances\n mapping(address => mapping(address => uint256)) private _allowances;\n\n /**\n * @dev `defaultOperators` may be an empty array.\n */\n constructor(string memory name_, string memory symbol_, address[] memory defaultOperators_) {\n _name = name_;\n _symbol = symbol_;\n\n _defaultOperatorsArray = defaultOperators_;\n for (uint256 i = 0; i < defaultOperators_.length; i++) {\n _defaultOperators[defaultOperators_[i]] = true;\n }\n\n // register interfaces\n _ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256(\"ERC777Token\"), address(this));\n _ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256(\"ERC20Token\"), address(this));\n }\n\n /**\n * @dev See {IERC777-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC777-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {ERC20-decimals}.\n *\n * Always returns 18, as per the\n * [ERC777 EIP](https://eips.ethereum.org/EIPS/eip-777#backward-compatibility).\n */\n function decimals() public pure virtual returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC777-granularity}.\n *\n * This implementation always returns `1`.\n */\n function granularity() public view virtual override returns (uint256) {\n return 1;\n }\n\n /**\n * @dev See {IERC777-totalSupply}.\n */\n function totalSupply() public view virtual override(IERC20, IERC777) returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev Returns the amount of tokens owned by an account (`tokenHolder`).\n */\n function balanceOf(address tokenHolder) public view virtual override(IERC20, IERC777) returns (uint256) {\n return _balances[tokenHolder];\n }\n\n /**\n * @dev See {IERC777-send}.\n *\n * Also emits a {IERC20-Transfer} event for ERC20 compatibility.\n */\n function send(address recipient, uint256 amount, bytes memory data) public virtual override {\n _send(_msgSender(), recipient, amount, data, \"\", true);\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Unlike `send`, `recipient` is _not_ required to implement the {IERC777Recipient}\n * interface if it is a contract.\n *\n * Also emits a {Sent} event.\n */\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n _send(_msgSender(), recipient, amount, \"\", \"\", false);\n return true;\n }\n\n /**\n * @dev See {IERC777-burn}.\n *\n * Also emits a {IERC20-Transfer} event for ERC20 compatibility.\n */\n function burn(uint256 amount, bytes memory data) public virtual override {\n _burn(_msgSender(), amount, data, \"\");\n }\n\n /**\n * @dev See {IERC777-isOperatorFor}.\n */\n function isOperatorFor(address operator, address tokenHolder) public view virtual override returns (bool) {\n return\n operator == tokenHolder ||\n (_defaultOperators[operator] && !_revokedDefaultOperators[tokenHolder][operator]) ||\n _operators[tokenHolder][operator];\n }\n\n /**\n * @dev See {IERC777-authorizeOperator}.\n */\n function authorizeOperator(address operator) public virtual override {\n require(_msgSender() != operator, \"ERC777: authorizing self as operator\");\n\n if (_defaultOperators[operator]) {\n delete _revokedDefaultOperators[_msgSender()][operator];\n } else {\n _operators[_msgSender()][operator] = true;\n }\n\n emit AuthorizedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-revokeOperator}.\n */\n function revokeOperator(address operator) public virtual override {\n require(operator != _msgSender(), \"ERC777: revoking self as operator\");\n\n if (_defaultOperators[operator]) {\n _revokedDefaultOperators[_msgSender()][operator] = true;\n } else {\n delete _operators[_msgSender()][operator];\n }\n\n emit RevokedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-defaultOperators}.\n */\n function defaultOperators() public view virtual override returns (address[] memory) {\n return _defaultOperatorsArray;\n }\n\n /**\n * @dev See {IERC777-operatorSend}.\n *\n * Emits {Sent} and {IERC20-Transfer} events.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes memory data,\n bytes memory operatorData\n ) public virtual override {\n require(isOperatorFor(_msgSender(), sender), \"ERC777: caller is not an operator for holder\");\n _send(sender, recipient, amount, data, operatorData, true);\n }\n\n /**\n * @dev See {IERC777-operatorBurn}.\n *\n * Emits {Burned} and {IERC20-Transfer} events.\n */\n function operatorBurn(\n address account,\n uint256 amount,\n bytes memory data,\n bytes memory operatorData\n ) public virtual override {\n require(isOperatorFor(_msgSender(), account), \"ERC777: caller is not an operator for holder\");\n _burn(account, amount, data, operatorData);\n }\n\n /**\n * @dev See {IERC20-allowance}.\n *\n * Note that operator and allowance concepts are orthogonal: operators may\n * not have allowance, and accounts with allowance may not be operators\n * themselves.\n */\n function allowance(address holder, address spender) public view virtual override returns (uint256) {\n return _allowances[holder][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Note that accounts cannot have allowance issued by their operators.\n */\n function approve(address spender, uint256 value) public virtual override returns (bool) {\n address holder = _msgSender();\n _approve(holder, spender, value);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Note that operator and allowance concepts are orthogonal: operators cannot\n * call `transferFrom` (unless they have allowance), and accounts with\n * allowance cannot call `operatorSend` (unless they are operators).\n *\n * Emits {Sent}, {IERC20-Transfer} and {IERC20-Approval} events.\n */\n function transferFrom(address holder, address recipient, uint256 amount) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(holder, spender, amount);\n _send(holder, recipient, amount, \"\", \"\", false);\n return true;\n }\n\n /**\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with the caller address as the `operator` and with\n * `userData` and `operatorData`.\n *\n * See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits {Minted} and {IERC20-Transfer} events.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - if `account` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function _mint(address account, uint256 amount, bytes memory userData, bytes memory operatorData) internal virtual {\n _mint(account, amount, userData, operatorData, true);\n }\n\n /**\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * If `requireReceptionAck` is set to true, and if a send hook is\n * registered for `account`, the corresponding function will be called with\n * `operator`, `data` and `operatorData`.\n *\n * See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits {Minted} and {IERC20-Transfer} events.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - if `account` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function _mint(\n address account,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) internal virtual {\n require(account != address(0), \"ERC777: mint to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), account, amount);\n\n // Update state variables\n _totalSupply += amount;\n _balances[account] += amount;\n\n _callTokensReceived(operator, address(0), account, amount, userData, operatorData, requireReceptionAck);\n\n emit Minted(operator, account, amount, userData, operatorData);\n emit Transfer(address(0), account, amount);\n }\n\n /**\n * @dev Send tokens\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _send(\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) internal virtual {\n require(from != address(0), \"ERC777: transfer from the zero address\");\n require(to != address(0), \"ERC777: transfer to the zero address\");\n\n address operator = _msgSender();\n\n _callTokensToSend(operator, from, to, amount, userData, operatorData);\n\n _move(operator, from, to, amount, userData, operatorData);\n\n _callTokensReceived(operator, from, to, amount, userData, operatorData, requireReceptionAck);\n }\n\n /**\n * @dev Burn tokens\n * @param from address token holder address\n * @param amount uint256 amount of tokens to burn\n * @param data bytes extra information provided by the token holder\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _burn(address from, uint256 amount, bytes memory data, bytes memory operatorData) internal virtual {\n require(from != address(0), \"ERC777: burn from the zero address\");\n\n address operator = _msgSender();\n\n _callTokensToSend(operator, from, address(0), amount, data, operatorData);\n\n _beforeTokenTransfer(operator, from, address(0), amount);\n\n // Update state variables\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC777: burn amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Burned(operator, from, amount, data, operatorData);\n emit Transfer(from, address(0), amount);\n }\n\n function _move(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n ) private {\n _beforeTokenTransfer(operator, from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC777: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Sent(operator, from, to, amount, userData, operatorData);\n emit Transfer(from, to, amount);\n }\n\n /**\n * @dev See {ERC20-_approve}.\n *\n * Note that accounts cannot have allowance issued by their operators.\n */\n function _approve(address holder, address spender, uint256 value) internal virtual {\n require(holder != address(0), \"ERC777: approve from the zero address\");\n require(spender != address(0), \"ERC777: approve to the zero address\");\n\n _allowances[holder][spender] = value;\n emit Approval(holder, spender, value);\n }\n\n /**\n * @dev Call from.tokensToSend() if the interface is registered\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _callTokensToSend(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n ) private {\n address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(from, _TOKENS_SENDER_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Sender(implementer).tokensToSend(operator, from, to, amount, userData, operatorData);\n }\n }\n\n /**\n * @dev Call to.tokensReceived() if the interface is registered. Reverts if the recipient is a contract but\n * tokensReceived() was not registered for the recipient\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _callTokensReceived(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) private {\n address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(to, _TOKENS_RECIPIENT_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Recipient(implementer).tokensReceived(operator, from, to, amount, userData, operatorData);\n } else if (requireReceptionAck) {\n require(!to.isContract(), \"ERC777: token recipient contract has no implementer for ERC777TokensRecipient\");\n }\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {IERC20-Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC777: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes\n * calls to {send}, {transfer}, {operatorSend}, {transferFrom}, minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be to transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address operator, address from, address to, uint256 amount) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC777/IERC777.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777Token standard as defined in the EIP.\n *\n * This contract uses the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 registry standard] to let\n * token holders and recipients react to token movements by using setting implementers\n * for the associated interfaces in said registry. See {IERC1820Registry} and\n * {ERC1820Implementer}.\n */\ninterface IERC777 {\n /**\n * @dev Emitted when `amount` tokens are created by `operator` and assigned to `to`.\n *\n * Note that some additional user `data` and `operatorData` can be logged in the event.\n */\n event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);\n\n /**\n * @dev Emitted when `operator` destroys `amount` tokens from `account`.\n *\n * Note that some additional user `data` and `operatorData` can be logged in the event.\n */\n event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);\n\n /**\n * @dev Emitted when `operator` is made operator for `tokenHolder`.\n */\n event AuthorizedOperator(address indexed operator, address indexed tokenHolder);\n\n /**\n * @dev Emitted when `operator` is revoked its operator status for `tokenHolder`.\n */\n event RevokedOperator(address indexed operator, address indexed tokenHolder);\n\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, usually a shorter version of the\n * name.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the smallest part of the token that is not divisible. This\n * means all token operations (creation, movement and destruction) must have\n * amounts that are a multiple of this number.\n *\n * For most token contracts, this value will equal 1.\n */\n function granularity() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by an account (`owner`).\n */\n function balanceOf(address owner) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * If send or receive hooks are registered for the caller and `recipient`,\n * the corresponding functions will be called with `data` and empty\n * `operatorData`. See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits a {Sent} event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function send(address recipient, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Destroys `amount` tokens from the caller's account, reducing the\n * total supply.\n *\n * If a send hook is registered for the caller, the corresponding function\n * will be called with `data` and empty `operatorData`. See {IERC777Sender}.\n *\n * Emits a {Burned} event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n */\n function burn(uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Returns true if an account is an operator of `tokenHolder`.\n * Operators can send and burn tokens on behalf of their owners. All\n * accounts are their own operator.\n *\n * See {operatorSend} and {operatorBurn}.\n */\n function isOperatorFor(address operator, address tokenHolder) external view returns (bool);\n\n /**\n * @dev Make an account an operator of the caller.\n *\n * See {isOperatorFor}.\n *\n * Emits an {AuthorizedOperator} event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function authorizeOperator(address operator) external;\n\n /**\n * @dev Revoke an account's operator status for the caller.\n *\n * See {isOperatorFor} and {defaultOperators}.\n *\n * Emits a {RevokedOperator} event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function revokeOperator(address operator) external;\n\n /**\n * @dev Returns the list of default operators. These accounts are operators\n * for all token holders, even if {authorizeOperator} was never called on\n * them.\n *\n * This list is immutable, but individual holders may revoke these via\n * {revokeOperator}, in which case {isOperatorFor} will return false.\n */\n function defaultOperators() external view returns (address[] memory);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must\n * be an operator of `sender`.\n *\n * If send or receive hooks are registered for `sender` and `recipient`,\n * the corresponding functions will be called with `data` and\n * `operatorData`. See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits a {Sent} event.\n *\n * Requirements\n *\n * - `sender` cannot be the zero address.\n * - `sender` must have at least `amount` tokens.\n * - the caller must be an operator for `sender`.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes calldata data,\n bytes calldata operatorData\n ) external;\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the total supply.\n * The caller must be an operator of `account`.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with `data` and `operatorData`. See {IERC777Sender}.\n *\n * Emits a {Burned} event.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n * - the caller must be an operator for `account`.\n */\n function operatorBurn(address account, uint256 amount, bytes calldata data, bytes calldata operatorData) external;\n\n event Sent(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes data,\n bytes operatorData\n );\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\n *\n * Accounts can be notified of {IERC777} tokens being sent to them by having a\n * contract implement this interface (contract holders can be their own\n * implementer) and registering it on the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\n *\n * See {IERC1820Registry} and {ERC1820Implementer}.\n */\ninterface IERC777Recipient {\n /**\n * @dev Called by an {IERC777} token contract whenever tokens are being\n * moved or created into a registered account (`to`). The type of operation\n * is conveyed by `from` being the zero address or not.\n *\n * This call occurs _after_ the token contract's state is updated, so\n * {IERC777-balanceOf}, etc., can be used to query the post-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensReceived(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777Sender.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Sender.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777TokensSender standard as defined in the EIP.\n *\n * {IERC777} Token holders can be notified of operations performed on their\n * tokens by having a contract implement this interface (contract holders can be\n * their own implementer) and registering it on the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\n *\n * See {IERC1820Registry} and {ERC1820Implementer}.\n */\ninterface IERC777Sender {\n /**\n * @dev Called by an {IERC777} token contract whenever a registered holder's\n * (`from`) tokens are about to be moved or destroyed. The type of operation\n * is conveyed by `to` being the zero address or not.\n *\n * This call occurs _before_ the token contract's state is updated, so\n * {IERC777-balanceOf}, etc., can be used to query the pre-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensToSend(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n *\n * Furthermore, `isContract` will also return true if the target contract within\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n * which only has an effect at the end of a transaction.\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Counters.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary Counters {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/ECDSA.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Strings.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV // Deprecated in v4.8\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n /// @solidity memory-safe-assembly\n assembly {\n mstore(0x00, \"\\x19Ethereum Signed Message:\\n32\")\n mstore(0x1c, hash)\n message := keccak256(0x00, 0x3c)\n }\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\n /// @solidity memory-safe-assembly\n assembly {\n let ptr := mload(0x40)\n mstore(ptr, \"\\x19\\x01\")\n mstore(add(ptr, 0x02), domainSeparator)\n mstore(add(ptr, 0x22), structHash)\n data := keccak256(ptr, 0x42)\n }\n }\n\n /**\n * @dev Returns an Ethereum Signed Data with intended validator, created from a\n * `validator` and `data` according to the version 0 of EIP-191.\n *\n * See {recover}.\n */\n function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x00\", validator, data));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/SignatureChecker.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSA.sol\";\nimport \"../../interfaces/IERC1271.sol\";\n\n/**\n * @dev Signature verification helper that can be used instead of `ECDSA.recover` to seamlessly support both ECDSA\n * signatures from externally owned accounts (EOAs) as well as ERC1271 signatures from smart contract wallets like\n * Argent and Gnosis Safe.\n *\n * _Available since v4.1._\n */\nlibrary SignatureChecker {\n /**\n * @dev Checks if a signature is valid for a given signer and data hash. If the signer is a smart contract, the\n * signature is validated against that smart contract using ERC1271, otherwise it's validated using `ECDSA.recover`.\n *\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\n */\n function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature) internal view returns (bool) {\n (address recovered, ECDSA.RecoverError error) = ECDSA.tryRecover(hash, signature);\n return\n (error == ECDSA.RecoverError.NoError && recovered == signer) ||\n isValidERC1271SignatureNow(signer, hash, signature);\n }\n\n /**\n * @dev Checks if a signature is valid for a given signer and data hash. The signature is validated\n * against the signer smart contract using ERC1271.\n *\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\n */\n function isValidERC1271SignatureNow(\n address signer,\n bytes32 hash,\n bytes memory signature\n ) internal view returns (bool) {\n (bool success, bytes memory result) = signer.staticcall(\n abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, signature)\n );\n return (success &&\n result.length >= 32 &&\n abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/ERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165 is IERC165 {\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165).interfaceId;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC1820Registry.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/introspection/IERC1820Registry.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the global ERC1820 Registry, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register\n * implementers for interfaces in this registry, as well as query support.\n *\n * Implementers may be shared by multiple accounts, and can also implement more\n * than a single interface for each account. Contracts can implement interfaces\n * for themselves, but externally-owned accounts (EOA) must delegate this to a\n * contract.\n *\n * {IERC165} interfaces can also be queried via the registry.\n *\n * For an in-depth explanation and source code analysis, see the EIP text.\n */\ninterface IERC1820Registry {\n event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer);\n\n event ManagerChanged(address indexed account, address indexed newManager);\n\n /**\n * @dev Sets `newManager` as the manager for `account`. A manager of an\n * account is able to set interface implementers for it.\n *\n * By default, each account is its own manager. Passing a value of `0x0` in\n * `newManager` will reset the manager to this initial state.\n *\n * Emits a {ManagerChanged} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `account`.\n */\n function setManager(address account, address newManager) external;\n\n /**\n * @dev Returns the manager for `account`.\n *\n * See {setManager}.\n */\n function getManager(address account) external view returns (address);\n\n /**\n * @dev Sets the `implementer` contract as ``account``'s implementer for\n * `interfaceHash`.\n *\n * `account` being the zero address is an alias for the caller's address.\n * The zero address can also be used in `implementer` to remove an old one.\n *\n * See {interfaceHash} to learn how these are created.\n *\n * Emits an {InterfaceImplementerSet} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `account`.\n * - `interfaceHash` must not be an {IERC165} interface id (i.e. it must not\n * end in 28 zeroes).\n * - `implementer` must implement {IERC1820Implementer} and return true when\n * queried for support, unless `implementer` is the caller. See\n * {IERC1820Implementer-canImplementInterfaceForAddress}.\n */\n function setInterfaceImplementer(address account, bytes32 _interfaceHash, address implementer) external;\n\n /**\n * @dev Returns the implementer of `interfaceHash` for `account`. If no such\n * implementer is registered, returns the zero address.\n *\n * If `interfaceHash` is an {IERC165} interface id (i.e. it ends with 28\n * zeroes), `account` will be queried for support of it.\n *\n * `account` being the zero address is an alias for the caller's address.\n */\n function getInterfaceImplementer(address account, bytes32 _interfaceHash) external view returns (address);\n\n /**\n * @dev Returns the interface hash for an `interfaceName`, as defined in the\n * corresponding\n * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP].\n */\n function interfaceHash(string calldata interfaceName) external pure returns (bytes32);\n\n /**\n * @notice Updates the cache with whether the contract implements an ERC165 interface or not.\n * @param account Address of the contract for which to update the cache.\n * @param interfaceId ERC165 interface for which to update the cache.\n */\n function updateERC165Cache(address account, bytes4 interfaceId) external;\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not.\n * If the result is not cached a direct lookup on the contract address is performed.\n * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling\n * {updateERC165Cache} with the contract address.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool);\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not without using or updating the cache.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/math/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\n // The surrounding unchecked block does not change this fact.\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1, \"Math: mulDiv overflow\");\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n //\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n //\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n //\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1 << (log2(a) >> 1);\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = sqrt(a);\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 2, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 128;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 64;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 32;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 16;\n }\n if (value >> 8 > 0) {\n value >>= 8;\n result += 8;\n }\n if (value >> 4 > 0) {\n value >>= 4;\n result += 4;\n }\n if (value >> 2 > 0) {\n value >>= 2;\n result += 2;\n }\n if (value >> 1 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log2(value);\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 10, rounded down, of a positive value.\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 + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 256, rounded down, of a positive value.\n * Returns 0 if given 0.\n *\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n */\n function log256(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 16;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 8;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 4;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 2;\n }\n if (value >> 8 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log256(value);\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/SafeCast.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCast {\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 * _Available since v4.7._\n */\n function toUint248(uint256 value) internal pure returns (uint248) {\n require(value <= type(uint248).max, \"SafeCast: value doesn't fit in 248 bits\");\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 * _Available since v4.7._\n */\n function toUint240(uint256 value) internal pure returns (uint240) {\n require(value <= type(uint240).max, \"SafeCast: value doesn't fit in 240 bits\");\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 * _Available since v4.7._\n */\n function toUint232(uint256 value) internal pure returns (uint232) {\n require(value <= type(uint232).max, \"SafeCast: value doesn't fit in 232 bits\");\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 * _Available since v4.2._\n */\n function toUint224(uint256 value) internal pure returns (uint224) {\n require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\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 * _Available since v4.7._\n */\n function toUint216(uint256 value) internal pure returns (uint216) {\n require(value <= type(uint216).max, \"SafeCast: value doesn't fit in 216 bits\");\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 * _Available since v4.7._\n */\n function toUint208(uint256 value) internal pure returns (uint208) {\n require(value <= type(uint208).max, \"SafeCast: value doesn't fit in 208 bits\");\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 * _Available since v4.7._\n */\n function toUint200(uint256 value) internal pure returns (uint200) {\n require(value <= type(uint200).max, \"SafeCast: value doesn't fit in 200 bits\");\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 * _Available since v4.7._\n */\n function toUint192(uint256 value) internal pure returns (uint192) {\n require(value <= type(uint192).max, \"SafeCast: value doesn't fit in 192 bits\");\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 * _Available since v4.7._\n */\n function toUint184(uint256 value) internal pure returns (uint184) {\n require(value <= type(uint184).max, \"SafeCast: value doesn't fit in 184 bits\");\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 * _Available since v4.7._\n */\n function toUint176(uint256 value) internal pure returns (uint176) {\n require(value <= type(uint176).max, \"SafeCast: value doesn't fit in 176 bits\");\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 * _Available since v4.7._\n */\n function toUint168(uint256 value) internal pure returns (uint168) {\n require(value <= type(uint168).max, \"SafeCast: value doesn't fit in 168 bits\");\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 * _Available since v4.7._\n */\n function toUint160(uint256 value) internal pure returns (uint160) {\n require(value <= type(uint160).max, \"SafeCast: value doesn't fit in 160 bits\");\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 * _Available since v4.7._\n */\n function toUint152(uint256 value) internal pure returns (uint152) {\n require(value <= type(uint152).max, \"SafeCast: value doesn't fit in 152 bits\");\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 * _Available since v4.7._\n */\n function toUint144(uint256 value) internal pure returns (uint144) {\n require(value <= type(uint144).max, \"SafeCast: value doesn't fit in 144 bits\");\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 * _Available since v4.7._\n */\n function toUint136(uint256 value) internal pure returns (uint136) {\n require(value <= type(uint136).max, \"SafeCast: value doesn't fit in 136 bits\");\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 * _Available since v2.5._\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\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 * _Available since v4.7._\n */\n function toUint120(uint256 value) internal pure returns (uint120) {\n require(value <= type(uint120).max, \"SafeCast: value doesn't fit in 120 bits\");\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 * _Available since v4.7._\n */\n function toUint112(uint256 value) internal pure returns (uint112) {\n require(value <= type(uint112).max, \"SafeCast: value doesn't fit in 112 bits\");\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 * _Available since v4.7._\n */\n function toUint104(uint256 value) internal pure returns (uint104) {\n require(value <= type(uint104).max, \"SafeCast: value doesn't fit in 104 bits\");\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 * _Available since v4.2._\n */\n function toUint96(uint256 value) internal pure returns (uint96) {\n require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\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 * _Available since v4.7._\n */\n function toUint88(uint256 value) internal pure returns (uint88) {\n require(value <= type(uint88).max, \"SafeCast: value doesn't fit in 88 bits\");\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 * _Available since v4.7._\n */\n function toUint80(uint256 value) internal pure returns (uint80) {\n require(value <= type(uint80).max, \"SafeCast: value doesn't fit in 80 bits\");\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 * _Available since v4.7._\n */\n function toUint72(uint256 value) internal pure returns (uint72) {\n require(value <= type(uint72).max, \"SafeCast: value doesn't fit in 72 bits\");\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 * _Available since v2.5._\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\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 * _Available since v4.7._\n */\n function toUint56(uint256 value) internal pure returns (uint56) {\n require(value <= type(uint56).max, \"SafeCast: value doesn't fit in 56 bits\");\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 * _Available since v4.7._\n */\n function toUint48(uint256 value) internal pure returns (uint48) {\n require(value <= type(uint48).max, \"SafeCast: value doesn't fit in 48 bits\");\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 * _Available since v4.7._\n */\n function toUint40(uint256 value) internal pure returns (uint40) {\n require(value <= type(uint40).max, \"SafeCast: value doesn't fit in 40 bits\");\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 * _Available since v2.5._\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\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 * _Available since v4.7._\n */\n function toUint24(uint256 value) internal pure returns (uint24) {\n require(value <= type(uint24).max, \"SafeCast: value doesn't fit in 24 bits\");\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 * _Available since v2.5._\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\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 * _Available since v2.5._\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\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 * _Available since v3.0._\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\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 * _Available since v4.7._\n */\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\n downcasted = int248(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 248 bits\");\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 * _Available since v4.7._\n */\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\n downcasted = int240(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 240 bits\");\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 * _Available since v4.7._\n */\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\n downcasted = int232(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 232 bits\");\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 * _Available since v4.7._\n */\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\n downcasted = int224(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 224 bits\");\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 * _Available since v4.7._\n */\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\n downcasted = int216(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 216 bits\");\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 * _Available since v4.7._\n */\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\n downcasted = int208(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 208 bits\");\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 * _Available since v4.7._\n */\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\n downcasted = int200(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 200 bits\");\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 * _Available since v4.7._\n */\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\n downcasted = int192(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 192 bits\");\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 * _Available since v4.7._\n */\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\n downcasted = int184(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 184 bits\");\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 * _Available since v4.7._\n */\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\n downcasted = int176(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 176 bits\");\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 * _Available since v4.7._\n */\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\n downcasted = int168(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 168 bits\");\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 * _Available since v4.7._\n */\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\n downcasted = int160(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 160 bits\");\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 * _Available since v4.7._\n */\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\n downcasted = int152(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 152 bits\");\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 * _Available since v4.7._\n */\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\n downcasted = int144(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 144 bits\");\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 * _Available since v4.7._\n */\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\n downcasted = int136(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 136 bits\");\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 * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\n downcasted = int128(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 128 bits\");\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 * _Available since v4.7._\n */\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\n downcasted = int120(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 120 bits\");\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 * _Available since v4.7._\n */\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\n downcasted = int112(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 112 bits\");\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 * _Available since v4.7._\n */\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\n downcasted = int104(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 104 bits\");\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 * _Available since v4.7._\n */\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\n downcasted = int96(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 96 bits\");\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 * _Available since v4.7._\n */\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\n downcasted = int88(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 88 bits\");\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 * _Available since v4.7._\n */\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\n downcasted = int80(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 80 bits\");\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 * _Available since v4.7._\n */\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\n downcasted = int72(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 72 bits\");\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 * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\n downcasted = int64(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 64 bits\");\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 * _Available since v4.7._\n */\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\n downcasted = int56(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 56 bits\");\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 * _Available since v4.7._\n */\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\n downcasted = int48(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 48 bits\");\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 * _Available since v4.7._\n */\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\n downcasted = int40(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 40 bits\");\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 * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\n downcasted = int32(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 32 bits\");\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 * _Available since v4.7._\n */\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\n downcasted = int24(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 24 bits\");\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 * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\n downcasted = int16(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 16 bits\");\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 * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\n downcasted = int8(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 8 bits\");\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 * _Available since v3.0._\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 require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/SignedMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard signed math utilities missing in the Solidity language.\n */\nlibrary SignedMath {\n /**\n * @dev Returns the largest of two signed numbers.\n */\n function max(int256 a, int256 b) internal pure returns (int256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two signed numbers.\n */\n function min(int256 a, int256 b) internal pure returns (int256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two signed numbers without overflow.\n * The result is rounded towards zero.\n */\n function average(int256 a, int256 b) internal pure returns (int256) {\n // Formula from the book \"Hacker's Delight\"\n int256 x = (a & b) + ((a ^ b) >> 1);\n return x + (int256(uint256(x) >> 255) & (a ^ b));\n }\n\n /**\n * @dev Returns the absolute unsigned value of a signed value.\n */\n function abs(int256 n) internal pure returns (uint256) {\n unchecked {\n // must be unchecked in order to support `n = type(int256).min`\n return uint256(n >= 0 ? n : -n);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/Math.sol\";\nimport \"./math/SignedMath.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n unchecked {\n uint256 length = Math.log10(value) + 1;\n string memory buffer = new string(length);\n uint256 ptr;\n /// @solidity memory-safe-assembly\n assembly {\n ptr := add(buffer, add(32, length))\n }\n while (true) {\n ptr--;\n /// @solidity memory-safe-assembly\n assembly {\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n }\n value /= 10;\n if (value == 0) break;\n }\n return buffer;\n }\n }\n\n /**\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\n */\n function toString(int256 value) internal pure returns (string memory) {\n return string(abi.encodePacked(value < 0 ? \"-\" : \"\", toString(SignedMath.abs(value))));\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n unchecked {\n return toHexString(value, Math.log256(value) + 1);\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n\n /**\n * @dev Returns true if the two strings are equal.\n */\n function equal(string memory a, string memory b) internal pure returns (bool) {\n return keccak256(bytes(a)) == keccak256(bytes(b));\n }\n}\n" + }, + "contracts/aa-4337/core/BaseAccount.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-empty-blocks */\n\nimport \"../interfaces/IAccount.sol\";\nimport \"../interfaces/IEntryPoint.sol\";\nimport \"./Helpers.sol\";\n\n/**\n * Basic account implementation.\n * this contract provides the basic logic for implementing the IAccount interface - validateUserOp\n * specific account implementation should inherit it and provide the account-specific logic\n */\nabstract contract BaseAccount is IAccount {\n using UserOperationLib for UserOperation;\n\n //return value in case of signature failure, with no time-range.\n // equivalent to _packValidationData(true,0,0);\n uint256 internal constant SIG_VALIDATION_FAILED = 1;\n\n /**\n * Return the account nonce.\n * This method returns the next sequential nonce.\n * For a nonce of a specific key, use `entrypoint.getNonce(account, key)`\n */\n function getNonce() public view virtual returns (uint256) {\n return entryPoint().getNonce(address(this), 0);\n }\n\n /**\n * return the entryPoint used by this account.\n * subclass should return the current entryPoint used by this account.\n */\n function entryPoint() public view virtual returns (IEntryPoint);\n\n /**\n * Validate user's signature and nonce.\n * subclass doesn't need to override this method. Instead, it should override the specific internal validation methods.\n */\n function validateUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 missingAccountFunds\n ) external virtual override returns (uint256 validationData) {\n _requireFromEntryPoint();\n validationData = _validateSignature(userOp, userOpHash);\n _validateNonce(userOp.nonce);\n _payPrefund(missingAccountFunds);\n }\n\n /**\n * ensure the request comes from the known entrypoint.\n */\n function _requireFromEntryPoint() internal view virtual {\n require(\n msg.sender == address(entryPoint()),\n \"account: not from EntryPoint\"\n );\n }\n\n /**\n * validate the signature is valid for this message.\n * @param userOp validate the userOp.signature field\n * @param userOpHash convenient field: the hash of the request, to check the signature against\n * (also hashes the entrypoint and chain id)\n * @return validationData signature and time-range of this operation\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * If the account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function _validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) internal virtual returns (uint256 validationData);\n\n /**\n * Validate the nonce of the UserOperation.\n * This method may validate the nonce requirement of this account.\n * e.g.\n * To limit the nonce to use sequenced UserOps only (no \"out of order\" UserOps):\n * `require(nonce < type(uint64).max)`\n * For a hypothetical account that *requires* the nonce to be out-of-order:\n * `require(nonce & type(uint64).max == 0)`\n *\n * The actual nonce uniqueness is managed by the EntryPoint, and thus no other\n * action is needed by the account itself.\n *\n * @param nonce to validate\n *\n * solhint-disable-next-line no-empty-blocks\n */\n function _validateNonce(uint256 nonce) internal view virtual {}\n\n /**\n * sends to the entrypoint (msg.sender) the missing funds for this transaction.\n * subclass MAY override this method for better funds management\n * (e.g. send to the entryPoint more than the minimum required, so that in future transactions\n * it will not be required to send again)\n * @param missingAccountFunds the minimum value this method should send the entrypoint.\n * this value MAY be zero, in case there is enough deposit, or the userOp has a paymaster.\n */\n function _payPrefund(uint256 missingAccountFunds) internal virtual {\n if (missingAccountFunds != 0) {\n (bool success, ) = payable(msg.sender).call{\n value: missingAccountFunds,\n gas: type(uint256).max\n }(\"\");\n (success);\n //ignore failure (its EntryPoint's job to verify, not account.)\n }\n }\n}\n" + }, + "contracts/aa-4337/core/EntryPoint.sol": { + "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n\nimport \"../interfaces/IAccount.sol\";\nimport \"../interfaces/IPaymaster.sol\";\nimport \"../interfaces/IEntryPoint.sol\";\n\nimport \"../utils/Exec.sol\";\nimport \"./StakeManager.sol\";\nimport \"./SenderCreator.sol\";\nimport \"./Helpers.sol\";\nimport \"./NonceManager.sol\";\nimport \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\n\ncontract EntryPoint is\n IEntryPoint,\n StakeManager,\n NonceManager,\n ReentrancyGuard\n{\n using UserOperationLib for UserOperation;\n\n SenderCreator private immutable senderCreator = new SenderCreator();\n\n // internal value used during simulation: need to query aggregator.\n address private constant SIMULATE_FIND_AGGREGATOR = address(1);\n\n // marker for inner call revert on out of gas\n bytes32 private constant INNER_OUT_OF_GAS = hex\"deaddead\";\n\n uint256 private constant REVERT_REASON_MAX_LEN = 2048;\n\n /**\n * for simulation purposes, validateUserOp (and validatePaymasterUserOp) must return this value\n * in case of signature failure, instead of revert.\n */\n uint256 public constant SIG_VALIDATION_FAILED = 1;\n\n /**\n * compensate the caller's beneficiary address with the collected fees of all UserOperations.\n * @param beneficiary the address to receive the fees\n * @param amount amount to transfer.\n */\n function _compensate(address payable beneficiary, uint256 amount) internal {\n require(beneficiary != address(0), \"AA90 invalid beneficiary\");\n (bool success, ) = beneficiary.call{value: amount}(\"\");\n require(success, \"AA91 failed send to beneficiary\");\n }\n\n /**\n * execute a user op\n * @param opIndex index into the opInfo array\n * @param userOp the userOp to execute\n * @param opInfo the opInfo filled by validatePrepayment for this userOp.\n * @return collected the total amount this userOp paid.\n */\n function _executeUserOp(\n uint256 opIndex,\n UserOperation calldata userOp,\n UserOpInfo memory opInfo\n ) private returns (uint256 collected) {\n uint256 preGas = gasleft();\n bytes memory context = getMemoryBytesFromOffset(opInfo.contextOffset);\n\n try this.innerHandleOp(userOp.callData, opInfo, context) returns (\n uint256 _actualGasCost\n ) {\n collected = _actualGasCost;\n } catch {\n bytes32 innerRevertCode;\n assembly {\n returndatacopy(0, 0, 32)\n innerRevertCode := mload(0)\n }\n // handleOps was called with gas limit too low. abort entire bundle.\n if (innerRevertCode == INNER_OUT_OF_GAS) {\n //report paymaster, since if it is not deliberately caused by the bundler,\n // it must be a revert caused by paymaster.\n revert FailedOp(opIndex, \"AA95 out of gas\");\n }\n\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n collected = _handlePostOp(\n opIndex,\n IPaymaster.PostOpMode.postOpReverted,\n opInfo,\n context,\n actualGas\n );\n }\n }\n\n /**\n * Execute a batch of UserOperations.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(\n UserOperation[] calldata ops,\n address payable beneficiary\n ) public nonReentrant {\n uint256 opslen = ops.length;\n UserOpInfo[] memory opInfos = new UserOpInfo[](opslen);\n\n unchecked {\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[i];\n (\n uint256 validationData,\n uint256 pmValidationData\n ) = _validatePrepayment(i, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(\n i,\n validationData,\n pmValidationData,\n address(0)\n );\n }\n\n uint256 collected = 0;\n emit BeforeExecution();\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(i, ops[i], opInfos[i]);\n }\n\n _compensate(beneficiary, collected);\n } //unchecked\n }\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) public nonReentrant {\n uint256 opasLen = opsPerAggregator.length;\n uint256 totalOps = 0;\n for (uint256 i = 0; i < opasLen; i++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[i];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n //address(1) is special marker of \"signature error\"\n require(\n address(aggregator) != address(1),\n \"AA96 invalid aggregator\"\n );\n\n if (address(aggregator) != address(0)) {\n // solhint-disable-next-line no-empty-blocks\n try aggregator.validateSignatures(ops, opa.signature) {} catch {\n revert SignatureValidationFailed(address(aggregator));\n }\n }\n\n totalOps += ops.length;\n }\n\n UserOpInfo[] memory opInfos = new UserOpInfo[](totalOps);\n\n emit BeforeExecution();\n\n uint256 opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n uint256 opslen = ops.length;\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[opIndex];\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(opIndex, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(\n i,\n validationData,\n paymasterValidationData,\n address(aggregator)\n );\n opIndex++;\n }\n }\n\n uint256 collected = 0;\n opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n emit SignatureAggregatorChanged(address(opa.aggregator));\n UserOperation[] calldata ops = opa.userOps;\n uint256 opslen = ops.length;\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(opIndex, ops[i], opInfos[opIndex]);\n opIndex++;\n }\n }\n emit SignatureAggregatorChanged(address(0));\n\n _compensate(beneficiary, collected);\n }\n\n /// @inheritdoc IEntryPoint\n function simulateHandleOp(\n UserOperation calldata op,\n address target,\n bytes calldata targetCallData\n ) external override {\n UserOpInfo memory opInfo;\n _simulationOnlyValidations(op);\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(0, op, opInfo);\n ValidationData memory data = _intersectTimeRange(\n validationData,\n paymasterValidationData\n );\n\n numberMarker();\n uint256 paid = _executeUserOp(0, op, opInfo);\n numberMarker();\n bool targetSuccess;\n bytes memory targetResult;\n if (target != address(0)) {\n (targetSuccess, targetResult) = target.call(targetCallData);\n }\n revert ExecutionResult(\n opInfo.preOpGas,\n paid,\n data.validAfter,\n data.validUntil,\n targetSuccess,\n targetResult\n );\n }\n\n // A memory copy of UserOp static fields only.\n // Excluding: callData, initCode and signature. Replacing paymasterAndData with paymaster.\n struct MemoryUserOp {\n address sender;\n uint256 nonce;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n address paymaster;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n }\n\n struct UserOpInfo {\n MemoryUserOp mUserOp;\n bytes32 userOpHash;\n uint256 prefund;\n uint256 contextOffset;\n uint256 preOpGas;\n }\n\n /**\n * inner function to handle a UserOperation.\n * Must be declared \"external\" to open a call context, but it can only be called by handleOps.\n */\n function innerHandleOp(\n bytes memory callData,\n UserOpInfo memory opInfo,\n bytes calldata context\n ) external returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n require(msg.sender == address(this), \"AA92 internal call only\");\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n\n uint callGasLimit = mUserOp.callGasLimit;\n unchecked {\n // handleOps was called with gas limit too low. abort entire bundle.\n if (\n gasleft() < callGasLimit + mUserOp.verificationGasLimit + 5000\n ) {\n assembly {\n mstore(0, INNER_OUT_OF_GAS)\n revert(0, 32)\n }\n }\n }\n\n IPaymaster.PostOpMode mode = IPaymaster.PostOpMode.opSucceeded;\n if (callData.length > 0) {\n bool success = Exec.call(mUserOp.sender, 0, callData, callGasLimit);\n if (!success) {\n bytes memory result = Exec.getReturnData(REVERT_REASON_MAX_LEN);\n if (result.length > 0) {\n emit UserOperationRevertReason(\n opInfo.userOpHash,\n mUserOp.sender,\n mUserOp.nonce,\n result\n );\n }\n mode = IPaymaster.PostOpMode.opReverted;\n }\n }\n\n unchecked {\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n //note: opIndex is ignored (relevant only if mode==postOpReverted, which is only possible outside of innerHandleOp)\n return _handlePostOp(0, mode, opInfo, context, actualGas);\n }\n }\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(\n UserOperation calldata userOp\n ) public view returns (bytes32) {\n return\n keccak256(abi.encode(userOp.hash(), address(this), block.chainid));\n }\n\n /**\n * copy general fields from userOp into the memory opInfo structure.\n */\n function _copyUserOpToMemory(\n UserOperation calldata userOp,\n MemoryUserOp memory mUserOp\n ) internal pure {\n mUserOp.sender = userOp.sender;\n mUserOp.nonce = userOp.nonce;\n mUserOp.callGasLimit = userOp.callGasLimit;\n mUserOp.verificationGasLimit = userOp.verificationGasLimit;\n mUserOp.preVerificationGas = userOp.preVerificationGas;\n mUserOp.maxFeePerGas = userOp.maxFeePerGas;\n mUserOp.maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes calldata paymasterAndData = userOp.paymasterAndData;\n if (paymasterAndData.length > 0) {\n require(\n paymasterAndData.length >= 20,\n \"AA93 invalid paymasterAndData\"\n );\n mUserOp.paymaster = address(bytes20(paymasterAndData[:20]));\n } else {\n mUserOp.paymaster = address(0);\n }\n }\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external {\n UserOpInfo memory outOpInfo;\n\n _simulationOnlyValidations(userOp);\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(0, userOp, outOpInfo);\n StakeInfo memory paymasterInfo = _getStakeInfo(\n outOpInfo.mUserOp.paymaster\n );\n StakeInfo memory senderInfo = _getStakeInfo(outOpInfo.mUserOp.sender);\n StakeInfo memory factoryInfo;\n {\n bytes calldata initCode = userOp.initCode;\n address factory = initCode.length >= 20\n ? address(bytes20(initCode[0:20]))\n : address(0);\n factoryInfo = _getStakeInfo(factory);\n }\n\n ValidationData memory data = _intersectTimeRange(\n validationData,\n paymasterValidationData\n );\n address aggregator = data.aggregator;\n bool sigFailed = aggregator == address(1);\n ReturnInfo memory returnInfo = ReturnInfo(\n outOpInfo.preOpGas,\n outOpInfo.prefund,\n sigFailed,\n data.validAfter,\n data.validUntil,\n getMemoryBytesFromOffset(outOpInfo.contextOffset)\n );\n\n if (aggregator != address(0) && aggregator != address(1)) {\n AggregatorStakeInfo memory aggregatorInfo = AggregatorStakeInfo(\n aggregator,\n _getStakeInfo(aggregator)\n );\n revert ValidationResultWithAggregation(\n returnInfo,\n senderInfo,\n factoryInfo,\n paymasterInfo,\n aggregatorInfo\n );\n }\n revert ValidationResult(\n returnInfo,\n senderInfo,\n factoryInfo,\n paymasterInfo\n );\n }\n\n function _getRequiredPrefund(\n MemoryUserOp memory mUserOp\n ) internal pure returns (uint256 requiredPrefund) {\n unchecked {\n //when using a Paymaster, the verificationGasLimit is used also to as a limit for the postOp call.\n // our security model might call postOp eventually twice\n uint256 mul = mUserOp.paymaster != address(0) ? 3 : 1;\n uint256 requiredGas = mUserOp.callGasLimit +\n mUserOp.verificationGasLimit *\n mul +\n mUserOp.preVerificationGas;\n\n requiredPrefund = requiredGas * mUserOp.maxFeePerGas;\n }\n }\n\n // create the sender's contract if needed.\n function _createSenderIfNeeded(\n uint256 opIndex,\n UserOpInfo memory opInfo,\n bytes calldata initCode\n ) internal {\n if (initCode.length != 0) {\n address sender = opInfo.mUserOp.sender;\n if (sender.code.length != 0)\n revert FailedOp(opIndex, \"AA10 sender already constructed\");\n address sender1 = senderCreator.createSender{\n gas: opInfo.mUserOp.verificationGasLimit\n }(initCode);\n if (sender1 == address(0))\n revert FailedOp(opIndex, \"AA13 initCode failed or OOG\");\n if (sender1 != sender)\n revert FailedOp(opIndex, \"AA14 initCode must return sender\");\n if (sender1.code.length == 0)\n revert FailedOp(opIndex, \"AA15 initCode must create sender\");\n address factory = address(bytes20(initCode[0:20]));\n emit AccountDeployed(\n opInfo.userOpHash,\n sender,\n factory,\n opInfo.mUserOp.paymaster\n );\n }\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes calldata initCode) public {\n address sender = senderCreator.createSender(initCode);\n revert SenderAddressResult(sender);\n }\n\n function _simulationOnlyValidations(\n UserOperation calldata userOp\n ) internal view {\n // solhint-disable-next-line no-empty-blocks\n try\n this._validateSenderAndPaymaster(\n userOp.initCode,\n userOp.sender,\n userOp.paymasterAndData\n )\n {} catch Error(string memory revertReason) {\n if (bytes(revertReason).length != 0) {\n revert FailedOp(0, revertReason);\n }\n }\n }\n\n /**\n * Called only during simulation.\n * This function always reverts to prevent warm/cold storage differentiation in simulation vs execution.\n */\n function _validateSenderAndPaymaster(\n bytes calldata initCode,\n address sender,\n bytes calldata paymasterAndData\n ) external view {\n if (initCode.length == 0 && sender.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA20 account not deployed\");\n }\n if (paymasterAndData.length >= 20) {\n address paymaster = address(bytes20(paymasterAndData[0:20]));\n if (paymaster.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA30 paymaster not deployed\");\n }\n }\n // always revert\n revert(\"\");\n }\n\n /**\n * call account.validateUserOp.\n * revert (with FailedOp) in case validateUserOp reverts, or account didn't send required prefund.\n * decrement account's deposit if needed\n */\n function _validateAccountPrepayment(\n uint256 opIndex,\n UserOperation calldata op,\n UserOpInfo memory opInfo,\n uint256 requiredPrefund\n )\n internal\n returns (\n uint256 gasUsedByValidateAccountPrepayment,\n uint256 validationData\n )\n {\n unchecked {\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n address sender = mUserOp.sender;\n _createSenderIfNeeded(opIndex, opInfo, op.initCode);\n address paymaster = mUserOp.paymaster;\n numberMarker();\n uint256 missingAccountFunds = 0;\n if (paymaster == address(0)) {\n uint256 bal = balanceOf(sender);\n missingAccountFunds = bal > requiredPrefund\n ? 0\n : requiredPrefund - bal;\n }\n try\n IAccount(sender).validateUserOp{\n gas: mUserOp.verificationGasLimit\n }(op, opInfo.userOpHash, missingAccountFunds)\n returns (uint256 _validationData) {\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA23 reverted: \", revertReason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA23 reverted (or OOG)\");\n }\n if (paymaster == address(0)) {\n DepositInfo storage senderInfo = deposits[sender];\n uint256 deposit = senderInfo.deposit;\n if (requiredPrefund > deposit) {\n revert FailedOp(opIndex, \"AA21 didn't pay prefund\");\n }\n senderInfo.deposit = uint112(deposit - requiredPrefund);\n }\n gasUsedByValidateAccountPrepayment = preGas - gasleft();\n }\n }\n\n /**\n * In case the request has a paymaster:\n * Validate paymaster has enough deposit.\n * Call paymaster.validatePaymasterUserOp.\n * Revert with proper FailedOp in case paymaster reverts.\n * Decrement paymaster's deposit\n */\n function _validatePaymasterPrepayment(\n uint256 opIndex,\n UserOperation calldata op,\n UserOpInfo memory opInfo,\n uint256 requiredPreFund,\n uint256 gasUsedByValidateAccountPrepayment\n ) internal returns (bytes memory context, uint256 validationData) {\n unchecked {\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 verificationGasLimit = mUserOp.verificationGasLimit;\n require(\n verificationGasLimit > gasUsedByValidateAccountPrepayment,\n \"AA41 too little verificationGas\"\n );\n uint256 gas = verificationGasLimit -\n gasUsedByValidateAccountPrepayment;\n\n address paymaster = mUserOp.paymaster;\n DepositInfo storage paymasterInfo = deposits[paymaster];\n uint256 deposit = paymasterInfo.deposit;\n if (deposit < requiredPreFund) {\n revert FailedOp(opIndex, \"AA31 paymaster deposit too low\");\n }\n paymasterInfo.deposit = uint112(deposit - requiredPreFund);\n try\n IPaymaster(paymaster).validatePaymasterUserOp{gas: gas}(\n op,\n opInfo.userOpHash,\n requiredPreFund\n )\n returns (bytes memory _context, uint256 _validationData) {\n context = _context;\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA33 reverted: \", revertReason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA33 reverted (or OOG)\");\n }\n }\n }\n\n /**\n * revert if either account validationData or paymaster validationData is expired\n */\n function _validateAccountAndPaymasterValidationData(\n uint256 opIndex,\n uint256 validationData,\n uint256 paymasterValidationData,\n address expectedAggregator\n ) internal view {\n (address aggregator, bool outOfTimeRange) = _getValidationData(\n validationData\n );\n if (expectedAggregator != aggregator) {\n revert FailedOp(opIndex, \"AA24 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA22 expired or not due\");\n }\n //pmAggregator is not a real signature aggregator: we don't have logic to handle it as address.\n // non-zero address means that the paymaster fails due to some signature check (which is ok only during estimation)\n address pmAggregator;\n (pmAggregator, outOfTimeRange) = _getValidationData(\n paymasterValidationData\n );\n if (pmAggregator != address(0)) {\n revert FailedOp(opIndex, \"AA34 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA32 paymaster expired or not due\");\n }\n }\n\n function _getValidationData(\n uint256 validationData\n ) internal view returns (address aggregator, bool outOfTimeRange) {\n if (validationData == 0) {\n return (address(0), false);\n }\n ValidationData memory data = _parseValidationData(validationData);\n // solhint-disable-next-line not-rely-on-time\n outOfTimeRange =\n block.timestamp > data.validUntil ||\n block.timestamp < data.validAfter;\n aggregator = data.aggregator;\n }\n\n /**\n * validate account and paymaster (if defined).\n * also make sure total validation doesn't exceed verificationGasLimit\n * this method is called off-chain (simulateValidation()) and on-chain (from handleOps)\n * @param opIndex the index of this userOp into the \"opInfos\" array\n * @param userOp the userOp to validate\n */\n function _validatePrepayment(\n uint256 opIndex,\n UserOperation calldata userOp,\n UserOpInfo memory outOpInfo\n )\n private\n returns (uint256 validationData, uint256 paymasterValidationData)\n {\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = outOpInfo.mUserOp;\n _copyUserOpToMemory(userOp, mUserOp);\n outOpInfo.userOpHash = getUserOpHash(userOp);\n\n // validate all numeric values in userOp are well below 128 bit, so they can safely be added\n // and multiplied without causing overflow\n uint256 maxGasValues = mUserOp.preVerificationGas |\n mUserOp.verificationGasLimit |\n mUserOp.callGasLimit |\n userOp.maxFeePerGas |\n userOp.maxPriorityFeePerGas;\n require(maxGasValues <= type(uint120).max, \"AA94 gas values overflow\");\n\n uint256 gasUsedByValidateAccountPrepayment;\n uint256 requiredPreFund = _getRequiredPrefund(mUserOp);\n (\n gasUsedByValidateAccountPrepayment,\n validationData\n ) = _validateAccountPrepayment(\n opIndex,\n userOp,\n outOpInfo,\n requiredPreFund\n );\n\n if (!_validateAndUpdateNonce(mUserOp.sender, mUserOp.nonce)) {\n revert FailedOp(opIndex, \"AA25 invalid account nonce\");\n }\n\n //a \"marker\" where account opcode validation is done and paymaster opcode validation is about to start\n // (used only by off-chain simulateValidation)\n numberMarker();\n\n bytes memory context;\n if (mUserOp.paymaster != address(0)) {\n (context, paymasterValidationData) = _validatePaymasterPrepayment(\n opIndex,\n userOp,\n outOpInfo,\n requiredPreFund,\n gasUsedByValidateAccountPrepayment\n );\n }\n unchecked {\n uint256 gasUsed = preGas - gasleft();\n\n if (userOp.verificationGasLimit < gasUsed) {\n revert FailedOp(opIndex, \"AA40 over verificationGasLimit\");\n }\n outOpInfo.prefund = requiredPreFund;\n outOpInfo.contextOffset = getOffsetOfMemoryBytes(context);\n outOpInfo.preOpGas = preGas - gasleft() + userOp.preVerificationGas;\n }\n }\n\n /**\n * process post-operation.\n * called just after the callData is executed.\n * if a paymaster is defined and its validation returned a non-empty context, its postOp is called.\n * the excess amount is refunded to the account (or paymaster - if it was used in the request)\n * @param opIndex index in the batch\n * @param mode - whether is called from innerHandleOp, or outside (postOpReverted)\n * @param opInfo userOp fields and info collected during validation\n * @param context the context returned in validatePaymasterUserOp\n * @param actualGas the gas used so far by this user operation\n */\n function _handlePostOp(\n uint256 opIndex,\n IPaymaster.PostOpMode mode,\n UserOpInfo memory opInfo,\n bytes memory context,\n uint256 actualGas\n ) private returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n unchecked {\n address refundAddress;\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 gasPrice = getUserOpGasPrice(mUserOp);\n\n address paymaster = mUserOp.paymaster;\n if (paymaster == address(0)) {\n refundAddress = mUserOp.sender;\n } else {\n refundAddress = paymaster;\n if (context.length > 0) {\n actualGasCost = actualGas * gasPrice;\n if (mode != IPaymaster.PostOpMode.postOpReverted) {\n IPaymaster(paymaster).postOp{\n gas: mUserOp.verificationGasLimit\n }(mode, context, actualGasCost);\n } else {\n // solhint-disable-next-line no-empty-blocks\n try\n IPaymaster(paymaster).postOp{\n gas: mUserOp.verificationGasLimit\n }(mode, context, actualGasCost)\n {} catch Error(string memory reason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA50 postOp reverted: \", reason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA50 postOp revert\");\n }\n }\n }\n }\n actualGas += preGas - gasleft();\n actualGasCost = actualGas * gasPrice;\n if (opInfo.prefund < actualGasCost) {\n revert FailedOp(opIndex, \"AA51 prefund below actualGasCost\");\n }\n uint256 refund = opInfo.prefund - actualGasCost;\n _incrementDeposit(refundAddress, refund);\n bool success = mode == IPaymaster.PostOpMode.opSucceeded;\n emit UserOperationEvent(\n opInfo.userOpHash,\n mUserOp.sender,\n mUserOp.paymaster,\n mUserOp.nonce,\n success,\n actualGasCost,\n actualGas\n );\n } // unchecked\n }\n\n /**\n * the gas price this UserOp agrees to pay.\n * relayer/block builder might submit the TX with higher priorityFee, but the user should not\n */\n function getUserOpGasPrice(\n MemoryUserOp memory mUserOp\n ) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = mUserOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = mUserOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n function getOffsetOfMemoryBytes(\n bytes memory data\n ) internal pure returns (uint256 offset) {\n assembly {\n offset := data\n }\n }\n\n function getMemoryBytesFromOffset(\n uint256 offset\n ) internal pure returns (bytes memory data) {\n assembly {\n data := offset\n }\n }\n\n //place the NUMBER opcode in the code.\n // this is used as a marker during simulation, as this OP is completely banned from the simulated code of the\n // account and paymaster.\n function numberMarker() internal view {\n assembly {\n mstore(0, number())\n }\n }\n}\n" + }, + "contracts/aa-4337/core/Helpers.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable no-inline-assembly */\n\n/**\n * returned data from validateUserOp.\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\n * @param aggregator - address(0) - the account validated the signature by itself.\n * address(1) - the account failed to validate the signature.\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\n * @param validAfter - this UserOp is valid only after this timestamp.\n * @param validaUntil - this UserOp is valid only up to this timestamp.\n */\nstruct ValidationData {\n address aggregator;\n uint48 validAfter;\n uint48 validUntil;\n}\n\n//extract sigFailed, validAfter, validUntil.\n// also convert zero validUntil to type(uint48).max\nfunction _parseValidationData(\n uint validationData\n) pure returns (ValidationData memory data) {\n address aggregator = address(uint160(validationData));\n uint48 validUntil = uint48(validationData >> 160);\n if (validUntil == 0) {\n validUntil = type(uint48).max;\n }\n uint48 validAfter = uint48(validationData >> (48 + 160));\n return ValidationData(aggregator, validAfter, validUntil);\n}\n\n// intersect account and paymaster ranges.\nfunction _intersectTimeRange(\n uint256 validationData,\n uint256 paymasterValidationData\n) pure returns (ValidationData memory) {\n ValidationData memory accountValidationData = _parseValidationData(\n validationData\n );\n ValidationData memory pmValidationData = _parseValidationData(\n paymasterValidationData\n );\n address aggregator = accountValidationData.aggregator;\n if (aggregator == address(0)) {\n aggregator = pmValidationData.aggregator;\n }\n uint48 validAfter = accountValidationData.validAfter;\n uint48 validUntil = accountValidationData.validUntil;\n uint48 pmValidAfter = pmValidationData.validAfter;\n uint48 pmValidUntil = pmValidationData.validUntil;\n\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\n return ValidationData(aggregator, validAfter, validUntil);\n}\n\n/**\n * helper to pack the return value for validateUserOp\n * @param data - the ValidationData to pack\n */\nfunction _packValidationData(\n ValidationData memory data\n) pure returns (uint256) {\n return\n uint160(data.aggregator) |\n (uint256(data.validUntil) << 160) |\n (uint256(data.validAfter) << (160 + 48));\n}\n\n/**\n * helper to pack the return value for validateUserOp, when not using an aggregator\n * @param sigFailed - true for signature failure, false for success\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\n * @param validAfter first timestamp this UserOperation is valid\n */\nfunction _packValidationData(\n bool sigFailed,\n uint48 validUntil,\n uint48 validAfter\n) pure returns (uint256) {\n return\n (sigFailed ? 1 : 0) |\n (uint256(validUntil) << 160) |\n (uint256(validAfter) << (160 + 48));\n}\n\n/**\n * keccak function over calldata.\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\n */\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\n assembly {\n let mem := mload(0x40)\n let len := data.length\n calldatacopy(mem, data.offset, len)\n ret := keccak256(mem, len)\n }\n}\n" + }, + "contracts/aa-4337/core/NonceManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\nimport \"../interfaces/IEntryPoint.sol\";\n\n/**\n * nonce management functionality\n */\ncontract NonceManager is INonceManager {\n /**\n * The next valid sequence number for a given nonce key.\n */\n mapping(address => mapping(uint192 => uint256)) public nonceSequenceNumber;\n\n function getNonce(\n address sender,\n uint192 key\n ) public view override returns (uint256 nonce) {\n return nonceSequenceNumber[sender][key] | (uint256(key) << 64);\n }\n\n // allow an account to manually increment its own nonce.\n // (mainly so that during construction nonce can be made non-zero,\n // to \"absorb\" the gas cost of first nonce increment to 1st transaction (construction),\n // not to 2nd transaction)\n function incrementNonce(uint192 key) public override {\n nonceSequenceNumber[msg.sender][key]++;\n }\n\n /**\n * validate nonce uniqueness for this account.\n * called just after validateUserOp()\n */\n function _validateAndUpdateNonce(\n address sender,\n uint256 nonce\n ) internal returns (bool) {\n uint192 key = uint192(nonce >> 64);\n uint64 seq = uint64(nonce);\n return nonceSequenceNumber[sender][key]++ == seq;\n }\n}\n" + }, + "contracts/aa-4337/core/SenderCreator.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/**\n * helper contract for EntryPoint, to call userOp.initCode from a \"neutral\" address,\n * which is explicitly not the entryPoint itself.\n */\ncontract SenderCreator {\n /**\n * call the \"initCode\" factory to create and return the sender account address\n * @param initCode the initCode value from a UserOp. contains 20 bytes of factory address, followed by calldata\n * @return sender the returned address of the created account, or zero address on failure.\n */\n function createSender(\n bytes calldata initCode\n ) external returns (address sender) {\n address factory = address(bytes20(initCode[0:20]));\n bytes memory initCallData = initCode[20:];\n bool success;\n /* solhint-disable no-inline-assembly */\n assembly {\n success := call(\n gas(),\n factory,\n 0,\n add(initCallData, 0x20),\n mload(initCallData),\n 0,\n 32\n )\n sender := mload(0)\n }\n if (!success) {\n sender = address(0);\n }\n }\n}\n" + }, + "contracts/aa-4337/core/StakeManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity 0.8.21;\n\nimport \"../interfaces/IStakeManager.sol\";\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable not-rely-on-time */\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by a paymaster.\n */\nabstract contract StakeManager is IStakeManager {\n /// maps paymaster to their deposits and stakes\n mapping(address => DepositInfo) public deposits;\n\n /// @inheritdoc IStakeManager\n function getDepositInfo(\n address account\n ) public view returns (DepositInfo memory info) {\n return deposits[account];\n }\n\n // internal method to return just the stake info\n function _getStakeInfo(\n address addr\n ) internal view returns (StakeInfo memory info) {\n DepositInfo storage depositInfo = deposits[addr];\n info.stake = depositInfo.stake;\n info.unstakeDelaySec = depositInfo.unstakeDelaySec;\n }\n\n /// return the deposit (for gas payment) of the account\n function balanceOf(address account) public view returns (uint256) {\n return deposits[account].deposit;\n }\n\n receive() external payable {\n depositTo(msg.sender);\n }\n\n function _incrementDeposit(address account, uint256 amount) internal {\n DepositInfo storage info = deposits[account];\n uint256 newAmount = info.deposit + amount;\n require(newAmount <= type(uint112).max, \"deposit overflow\");\n info.deposit = uint112(newAmount);\n }\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) public payable {\n _incrementDeposit(account, msg.value);\n DepositInfo storage info = deposits[account];\n emit Deposited(account, info.deposit);\n }\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 unstakeDelaySec) public payable {\n DepositInfo storage info = deposits[msg.sender];\n require(unstakeDelaySec > 0, \"must specify unstake delay\");\n require(\n unstakeDelaySec >= info.unstakeDelaySec,\n \"cannot decrease unstake time\"\n );\n uint256 stake = info.stake + msg.value;\n require(stake > 0, \"no stake specified\");\n require(stake <= type(uint112).max, \"stake overflow\");\n deposits[msg.sender] = DepositInfo(\n info.deposit,\n true,\n uint112(stake),\n unstakeDelaySec,\n 0\n );\n emit StakeLocked(msg.sender, stake, unstakeDelaySec);\n }\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external {\n DepositInfo storage info = deposits[msg.sender];\n require(info.unstakeDelaySec != 0, \"not staked\");\n require(info.staked, \"already unstaking\");\n uint48 withdrawTime = uint48(block.timestamp) + info.unstakeDelaySec;\n info.withdrawTime = withdrawTime;\n info.staked = false;\n emit StakeUnlocked(msg.sender, withdrawTime);\n }\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external {\n DepositInfo storage info = deposits[msg.sender];\n uint256 stake = info.stake;\n require(stake > 0, \"No stake to withdraw\");\n require(info.withdrawTime > 0, \"must call unlockStake() first\");\n require(\n info.withdrawTime <= block.timestamp,\n \"Stake withdrawal is not due\"\n );\n info.unstakeDelaySec = 0;\n info.withdrawTime = 0;\n info.stake = 0;\n emit StakeWithdrawn(msg.sender, withdrawAddress, stake);\n (bool success, ) = withdrawAddress.call{value: stake}(\"\");\n require(success, \"failed to withdraw stake\");\n }\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(\n address payable withdrawAddress,\n uint256 withdrawAmount\n ) external {\n DepositInfo storage info = deposits[msg.sender];\n require(withdrawAmount <= info.deposit, \"Withdraw amount too large\");\n info.deposit = uint112(info.deposit - withdrawAmount);\n emit Withdrawn(msg.sender, withdrawAddress, withdrawAmount);\n (bool success, ) = withdrawAddress.call{value: withdrawAmount}(\"\");\n require(success, \"failed to withdraw\");\n }\n}\n" + }, + "contracts/aa-4337/interfaces/IAccount.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\ninterface IAccount {\n /**\n * Validate user's signature and nonce\n * the entryPoint will make the call to the recipient only if this validation call returns successfully.\n * signature failure should be reported by returning SIG_VALIDATION_FAILED (1).\n * This allows making a \"simulation call\" without a valid signature\n * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure.\n *\n * @dev Must validate caller is the entryPoint.\n * Must validate the signature and nonce\n * @param userOp the operation that is about to be executed.\n * @param userOpHash hash of the user's request data. can be used as the basis for signature.\n * @param missingAccountFunds missing funds on the account's deposit in the entrypoint.\n * This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call.\n * The excess is left as a deposit in the entrypoint, for future calls.\n * can be withdrawn anytime using \"entryPoint.withdrawTo()\"\n * In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero.\n * @return validationData packaged ValidationData structure. use `_packValidationData` and `_unpackValidationData` to encode and decode\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * If an account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validateUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 missingAccountFunds\n ) external returns (uint256 validationData);\n}\n" + }, + "contracts/aa-4337/interfaces/IAggregator.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * Aggregated Signatures validator.\n */\ninterface IAggregator {\n /**\n * validate aggregated signature.\n * revert if the aggregated signature does not match the given list of operations.\n */\n function validateSignatures(\n UserOperation[] calldata userOps,\n bytes calldata signature\n ) external view;\n\n /**\n * validate signature of a single userOp\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\n * @param userOp the userOperation received from the user.\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\n * (usually empty, unless account and aggregator support some kind of \"multisig\"\n */\n function validateUserOpSignature(\n UserOperation calldata userOp\n ) external view returns (bytes memory sigForUserOp);\n\n /**\n * aggregate multiple signatures into a single value.\n * This method is called off-chain to calculate the signature to pass with handleOps()\n * bundler MAY use optimized custom code perform this aggregation\n * @param userOps array of UserOperations to collect the signatures from.\n * @return aggregatedSignature the aggregated signature\n */\n function aggregateSignatures(\n UserOperation[] calldata userOps\n ) external view returns (bytes memory aggregatedSignature);\n}\n" + }, + "contracts/aa-4337/interfaces/IEntryPoint.sol": { + "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n/* solhint-disable reason-string */\n\nimport \"./UserOperation.sol\";\nimport \"./IStakeManager.sol\";\nimport \"./IAggregator.sol\";\nimport \"./INonceManager.sol\";\n\ninterface IEntryPoint is IStakeManager, INonceManager {\n /***\n * An event emitted after each successful request\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\n * @param sender - the account that generates this request.\n * @param paymaster - if non-null, the paymaster that pays for this request.\n * @param nonce - the nonce value from the request.\n * @param success - true if the sender transaction succeeded, false if reverted.\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\n */\n event UserOperationEvent(\n bytes32 indexed userOpHash,\n address indexed sender,\n address indexed paymaster,\n uint256 nonce,\n bool success,\n uint256 actualGasCost,\n uint256 actualGasUsed\n );\n\n /**\n * account \"sender\" was deployed.\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\n * @param sender the account that is deployed\n * @param factory the factory used to deploy this account (in the initCode)\n * @param paymaster the paymaster used by this UserOp\n */\n event AccountDeployed(\n bytes32 indexed userOpHash,\n address indexed sender,\n address factory,\n address paymaster\n );\n\n /**\n * An event emitted if the UserOperation \"callData\" reverted with non-zero length\n * @param userOpHash the request unique identifier.\n * @param sender the sender of this request\n * @param nonce the nonce used in the request\n * @param revertReason - the return bytes from the (reverted) call to \"callData\".\n */\n event UserOperationRevertReason(\n bytes32 indexed userOpHash,\n address indexed sender,\n uint256 nonce,\n bytes revertReason\n );\n\n /**\n * an event emitted by handleOps(), before starting the execution loop.\n * any event emitted before this event, is part of the validation.\n */\n event BeforeExecution();\n\n /**\n * signature aggregator used by the following UserOperationEvents within this bundle.\n */\n event SignatureAggregatorChanged(address indexed aggregator);\n\n /**\n * a custom revert error of handleOps, to identify the offending op.\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\n * @param reason - revert reason\n * The string starts with a unique code \"AAmn\", where \"m\" is \"1\" for factory, \"2\" for account and \"3\" for paymaster issues,\n * so a failure can be attributed to the correct entity.\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\n */\n error FailedOp(uint256 opIndex, string reason);\n\n /**\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\n */\n error SignatureValidationFailed(address aggregator);\n\n /**\n * Successful result from simulateValidation.\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n */\n error ValidationResult(\n ReturnInfo returnInfo,\n StakeInfo senderInfo,\n StakeInfo factoryInfo,\n StakeInfo paymasterInfo\n );\n\n /**\n * Successful result from simulateValidation, if the account returns a signature aggregator\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\n * bundler MUST use it to verify the signature, or reject the UserOperation\n */\n error ValidationResultWithAggregation(\n ReturnInfo returnInfo,\n StakeInfo senderInfo,\n StakeInfo factoryInfo,\n StakeInfo paymasterInfo,\n AggregatorStakeInfo aggregatorInfo\n );\n\n /**\n * return value of getSenderAddress\n */\n error SenderAddressResult(address sender);\n\n /**\n * return value of simulateHandleOp\n */\n error ExecutionResult(\n uint256 preOpGas,\n uint256 paid,\n uint48 validAfter,\n uint48 validUntil,\n bool targetSuccess,\n bytes targetResult\n );\n\n //UserOps handled, per aggregator\n struct UserOpsPerAggregator {\n UserOperation[] userOps;\n // aggregator address\n IAggregator aggregator;\n // aggregated signature\n bytes signature;\n }\n\n /**\n * Execute a batch of UserOperation.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(\n UserOperation[] calldata ops,\n address payable beneficiary\n ) external;\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) external;\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(\n UserOperation calldata userOp\n ) external view returns (bytes32);\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external;\n\n /**\n * gas and return values during simulation\n * @param preOpGas the gas used for validation (including preValidationGas)\n * @param prefund the required prefund for this operation\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\n */\n struct ReturnInfo {\n uint256 preOpGas;\n uint256 prefund;\n bool sigFailed;\n uint48 validAfter;\n uint48 validUntil;\n bytes paymasterContext;\n }\n\n /**\n * returned aggregated signature info.\n * the aggregator returned by the account, and its current stake.\n */\n struct AggregatorStakeInfo {\n address aggregator;\n StakeInfo stakeInfo;\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes memory initCode) external;\n\n /**\n * simulate full execution of a UserOperation (including both validation and target execution)\n * this method will always revert with \"ExecutionResult\".\n * it performs full validation of the UserOperation, but ignores signature error.\n * an optional target address is called after the userop succeeds, and its value is returned\n * (before the entire call is reverted)\n * Note that in order to collect the the success/failure of the target call, it must be executed\n * with trace enabled to track the emitted events.\n * @param op the UserOperation to simulate\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\n * are set to the return from that call.\n * @param targetCallData callData to pass to target address\n */\n function simulateHandleOp(\n UserOperation calldata op,\n address target,\n bytes calldata targetCallData\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/INonceManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\ninterface INonceManager {\n /**\n * Return the next nonce for this sender.\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\n * But UserOp with different keys can come with arbitrary order.\n *\n * @param sender the account address\n * @param key the high 192 bit of the nonce\n * @return nonce a full nonce to pass for next UserOp with this sender.\n */\n function getNonce(\n address sender,\n uint192 key\n ) external view returns (uint256 nonce);\n\n /**\n * Manually increment the nonce of the sender.\n * This method is exposed just for completeness..\n * Account does NOT need to call it, neither during validation, nor elsewhere,\n * as the EntryPoint will update the nonce regardless.\n * Possible use-case is call it with various keys to \"initialize\" their nonces to one, so that future\n * UserOperations will not pay extra for the first transaction with a given key.\n */\n function incrementNonce(uint192 key) external;\n}\n" + }, + "contracts/aa-4337/interfaces/IPaymaster.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * the interface exposed by a paymaster contract, who agrees to pay the gas for user's operations.\n * a paymaster must hold a stake to cover the required entrypoint stake and also the gas for the transaction.\n */\ninterface IPaymaster {\n enum PostOpMode {\n opSucceeded, // user op succeeded\n opReverted, // user op reverted. still has to pay for gas.\n postOpReverted //user op succeeded, but caused postOp to revert. Now it's a 2nd call, after user's op was deliberately reverted.\n }\n\n /**\n * payment validation: check if paymaster agrees to pay.\n * Must verify sender is the entryPoint.\n * Revert to reject this request.\n * Note that bundlers will reject this method if it changes the state, unless the paymaster is trusted (whitelisted)\n * The paymaster pre-pays using its deposit, and receive back a refund after the postOp method returns.\n * @param userOp the user operation\n * @param userOpHash hash of the user's request data.\n * @param maxCost the maximum cost of this transaction (based on maximum gas and gas price from userOp)\n * @return context value to send to a postOp\n * zero length to signify postOp is not required.\n * @return validationData signature and time-range of this operation, encoded the same as the return value of validateUserOperation\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validatePaymasterUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 maxCost\n ) external returns (bytes memory context, uint256 validationData);\n\n /**\n * post-operation handler.\n * Must verify sender is the entryPoint\n * @param mode enum with the following options:\n * opSucceeded - user operation succeeded.\n * opReverted - user op reverted. still has to pay for gas.\n * postOpReverted - user op succeeded, but caused postOp (in mode=opSucceeded) to revert.\n * Now this is the 2nd call, after user's op was deliberately reverted.\n * @param context - the context value returned by validatePaymasterUserOp\n * @param actualGasCost - actual gas used so far (without this postOp call).\n */\n function postOp(\n PostOpMode mode,\n bytes calldata context,\n uint256 actualGasCost\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/IStakeManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.12;\n\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by the staked entity.\n */\ninterface IStakeManager {\n event Deposited(address indexed account, uint256 totalDeposit);\n\n event Withdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /// Emitted when stake or unstake delay are modified\n event StakeLocked(\n address indexed account,\n uint256 totalStaked,\n uint256 unstakeDelaySec\n );\n\n /// Emitted once a stake is scheduled for withdrawal\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\n\n event StakeWithdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /**\n * @param deposit the entity's deposit\n * @param staked true if this entity is staked.\n * @param stake actual amount of ether staked for this entity.\n * @param unstakeDelaySec minimum delay to withdraw the stake.\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\n * and the rest fit into a 2nd cell.\n * 112 bit allows for 10^15 eth\n * 48 bit for full timestamp\n * 32 bit allows 150 years for unstake delay\n */\n struct DepositInfo {\n uint112 deposit;\n bool staked;\n uint112 stake;\n uint32 unstakeDelaySec;\n uint48 withdrawTime;\n }\n\n //API struct used by getStakeInfo and simulateValidation\n struct StakeInfo {\n uint256 stake;\n uint256 unstakeDelaySec;\n }\n\n /// @return info - full deposit information of given account\n function getDepositInfo(\n address account\n ) external view returns (DepositInfo memory info);\n\n /// @return the deposit (for gas payment) of the account\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) external payable;\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 _unstakeDelaySec) external payable;\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external;\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external;\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(\n address payable withdrawAddress,\n uint256 withdrawAmount\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/UserOperation.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable no-inline-assembly */\n\nimport {calldataKeccak} from \"../core/Helpers.sol\";\n\n/**\n * User Operation struct\n * @param sender the sender account of this request.\n * @param nonce unique value the sender uses to verify it is not a replay.\n * @param initCode if set, the account contract will be created by this constructor/\n * @param callData the method call to execute on this account.\n * @param callGasLimit the gas limit passed to the callData method call.\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\n * @param maxFeePerGas same as EIP-1559 gas parameter.\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\n */\nstruct UserOperation {\n address sender;\n uint256 nonce;\n bytes initCode;\n bytes callData;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n bytes paymasterAndData;\n bytes signature;\n}\n\n/**\n * Utility functions helpful when working with UserOperation structs.\n */\nlibrary UserOperationLib {\n function getSender(\n UserOperation calldata userOp\n ) internal pure returns (address) {\n address data;\n //read sender from userOp, which is first userOp member (saves 800 gas...)\n assembly {\n data := calldataload(userOp)\n }\n return address(uint160(data));\n }\n\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\n // pay above what he signed for.\n function gasPrice(\n UserOperation calldata userOp\n ) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function pack(\n UserOperation calldata userOp\n ) internal pure returns (bytes memory ret) {\n address sender = getSender(userOp);\n uint256 nonce = userOp.nonce;\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\n bytes32 hashCallData = calldataKeccak(userOp.callData);\n uint256 callGasLimit = userOp.callGasLimit;\n uint256 verificationGasLimit = userOp.verificationGasLimit;\n uint256 preVerificationGas = userOp.preVerificationGas;\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\n\n return\n abi.encode(\n sender,\n nonce,\n hashInitCode,\n hashCallData,\n callGasLimit,\n verificationGasLimit,\n preVerificationGas,\n maxFeePerGas,\n maxPriorityFeePerGas,\n hashPaymasterAndData\n );\n }\n\n function hash(\n UserOperation calldata userOp\n ) internal pure returns (bytes32) {\n return keccak256(pack(userOp));\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n}\n" + }, + "contracts/aa-4337/utils/Exec.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.5 <0.9.0;\n\n// solhint-disable no-inline-assembly\n\n/**\n * Utility functions helpful when making different kinds of contract calls in Solidity.\n */\nlibrary Exec {\n function call(\n address to,\n uint256 value,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := call(\n txGas,\n to,\n value,\n add(data, 0x20),\n mload(data),\n 0,\n 0\n )\n }\n }\n\n function staticcall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal view returns (bool success) {\n assembly {\n success := staticcall(txGas, to, add(data, 0x20), mload(data), 0, 0)\n }\n }\n\n function delegateCall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := delegatecall(\n txGas,\n to,\n add(data, 0x20),\n mload(data),\n 0,\n 0\n )\n }\n }\n\n // get returned data from last call or calldelegate\n function getReturnData(\n uint256 maxLen\n ) internal pure returns (bytes memory returnData) {\n assembly {\n let len := returndatasize()\n if gt(len, maxLen) {\n len := maxLen\n }\n let ptr := mload(0x40)\n mstore(0x40, add(ptr, add(len, 0x20)))\n mstore(ptr, len)\n returndatacopy(add(ptr, 0x20), 0, len)\n returnData := ptr\n }\n }\n\n // revert with explicit byte array (probably reverted info from call)\n function revertWithData(bytes memory returnData) internal pure {\n assembly {\n revert(add(returnData, 32), mload(returnData))\n }\n }\n\n function callAndRevert(\n address to,\n bytes memory data,\n uint256 maxLen\n ) internal {\n bool success = call(to, 0, data, gasleft());\n if (!success) {\n revertWithData(getReturnData(maxLen));\n }\n }\n}\n" + }, + "contracts/Barz.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"./libraries/LibDiamond.sol\";\nimport {IBarz} from \"./interfaces/IBarz.sol\";\n\n/**\n * @title Barz\n * @dev A diamond proxy wallet with a modular & upgradeable architecture\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract Barz is IBarz {\n /**\n * @notice Initializes Barz with the given parameters. Barz account is intended to be created from Barz Factory for stable deployment.\n * @dev This method makes a delegate call to account facet and account facet handles the initialization.\n * With modular architecture, Barz encompasses wide spectrum of architecture and logic.\n * The only requirement is account facet to comply with initialize() interface.\n * Barz doesn't include built-in functions and is a full proxy, for maximum extensibility and modularity.\n * @param _accountFacet Address of Account Facet in charge of the Barz initialization\n * @param _verificationFacet Address of Verification Facet for verifying the signature. Could be any signature scheme\n * @param _entryPoint Address of Entry Point contract\n * @param _facetRegistry Address of Facet Registry. Facet Registry is a registry holding trusted facets that could be added to user's wallet\n * @param _defaultFallBack Address of Default FallBack Handler. Middleware contract for more efficient deployment\n * @param _ownerPublicKey Bytes of Owner Public Key using for initialization\n */\n constructor(\n address _accountFacet,\n address _verificationFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallBack,\n bytes memory _ownerPublicKey\n ) payable {\n bytes memory initCall = abi.encodeWithSignature(\n \"initialize(address,address,address,address,bytes)\",\n _verificationFacet,\n _entryPoint,\n _facetRegistry,\n _defaultFallBack,\n _ownerPublicKey\n );\n (bool success, bytes memory result) = _accountFacet.delegatecall(\n initCall\n );\n if (!success || uint256(bytes32(result)) != 1) {\n revert Barz__InitializationFailure();\n }\n }\n\n /**\n * @notice Fallback function for Barz complying with Diamond Standard with customization of adding Default Fallback Handler\n * @dev Find facet for function that is called and execute the function if a facet is found and return any value.\n */\n fallback() external payable {\n LibDiamond.DiamondStorage storage ds;\n bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION;\n // get diamond storage\n assembly {\n ds.slot := position\n }\n // get facet from function selector\n address facet = address(bytes20(ds.facets[msg.sig]));\n if (facet == address(0))\n facet = ds.defaultFallbackHandler.facetAddress(msg.sig);\n require(facet != address(0), \"Barz: Function does not exist\");\n // Execute external function from facet using delegatecall and return any value.\n assembly {\n // copy function selector and any arguments\n calldatacopy(0, 0, calldatasize())\n // execute function call using the facet\n let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)\n // get any return value\n returndatacopy(0, 0, returndatasize())\n // return any return value or error back to the caller\n switch result\n case 0 {\n revert(0, returndatasize())\n }\n default {\n return(0, returndatasize())\n }\n }\n }\n\n /**\n * @notice Receive function to receive native token without data\n */\n receive() external payable {}\n}\n" + }, + "contracts/BarzFactory.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Barz} from \"./Barz.sol\";\nimport {IBarzFactory} from \"./interfaces/IBarzFactory.sol\";\n\n/**\n * @title Barz Factory\n * @dev Contract to easily deploy Barz to a pre-computed address with a single call\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract BarzFactory is IBarzFactory {\n address public immutable accountFacet;\n address public immutable entryPoint;\n address public immutable facetRegistry;\n address public immutable defaultFallback;\n\n /**\n * @notice Sets the initialization data for Barz contract initialization\n * @param _accountFacet Account Facet to be used to create Barz\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\n * @param _facetRegistry Facet Registry to be used to create Barz\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\n */\n constructor(\n address _accountFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallback\n ) {\n accountFacet = _accountFacet;\n entryPoint = _entryPoint;\n facetRegistry = _facetRegistry;\n defaultFallback = _defaultFallback;\n }\n\n /**\n * @notice Creates the Barz with a single call. It creates the Barz contract with the givent verification facet\n * @param _verificationFacet Address of verification facet used for creating the barz account\n * @param _owner Public Key of the owner to initialize barz account\n * @param _salt Salt used for deploying barz with create2\n * @return barz Instance of Barz contract deployed with the given parameters\n */\n function createAccount(\n address _verificationFacet,\n bytes calldata _owner,\n uint256 _salt\n ) external override returns (Barz barz) {\n address addr = getAddress(_verificationFacet, _owner, _salt);\n uint codeSize = addr.code.length;\n if (codeSize > 0) {\n return Barz(payable(addr));\n }\n barz = new Barz{salt: bytes32(_salt)}(\n accountFacet,\n _verificationFacet,\n entryPoint,\n facetRegistry,\n defaultFallback,\n _owner\n );\n emit BarzDeployed(address(barz));\n }\n\n /**\n * @notice Calculates the address of Barz with the given parameters\n * @param _verificationFacet Address of verification facet used for creating the barz account\n * @param _owner Public Key of the owner to initialize barz account\n * @param _salt Salt used for deploying barz with create2\n * @return barzAddress Precalculated Barz address\n */\n function getAddress(\n address _verificationFacet,\n bytes calldata _owner,\n uint256 _salt\n ) public view override returns (address barzAddress) {\n bytes memory bytecode = getBytecode(\n accountFacet,\n _verificationFacet,\n entryPoint,\n facetRegistry,\n defaultFallback,\n _owner\n );\n bytes32 hash = keccak256(\n abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(bytecode)\n )\n );\n barzAddress = address(uint160(uint256(hash)));\n }\n\n /**\n * @notice Returns the bytecode of Barz with the given parameter\n * @param _accountFacet Account Facet to be used to create Barz\n * @param _verificationFacet Verification Facet to be used to create Barz\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\n * @param _facetRegistry Facet Registry to be used to create Barz\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\n * @param _ownerPublicKey Public Key of owner to be used to initialize Barz ownership\n * @return barzBytecode Bytecode of Barz\n */\n function getBytecode(\n address _accountFacet,\n address _verificationFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallback,\n bytes calldata _ownerPublicKey\n ) public pure override returns (bytes memory barzBytecode) {\n bytes memory bytecode = type(Barz).creationCode;\n barzBytecode = abi.encodePacked(\n bytecode,\n abi.encode(\n _accountFacet,\n _verificationFacet,\n _entryPoint,\n _facetRegistry,\n _defaultFallback,\n _ownerPublicKey\n )\n );\n }\n\n /**\n * @notice Returns the creation code of the Barz contract\n * @return creationCode Creation code of Barz\n */\n function getCreationCode()\n public\n pure\n override\n returns (bytes memory creationCode)\n {\n creationCode = type(Barz).creationCode;\n }\n}\n" + }, + "contracts/facets/AccountFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {UserOperation} from \"../aa-4337/interfaces/UserOperation.sol\";\nimport {IEntryPoint} from \"../aa-4337/interfaces/IEntryPoint.sol\";\nimport {BaseAccount} from \"../aa-4337/core/BaseAccount.sol\";\nimport {LibAppStorage, BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {IFacetRegistry} from \"../infrastructure/interfaces/IFacetRegistry.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {IERC1271} from \"../interfaces/ERC/IERC1271.sol\";\nimport {IAccountFacet} from \"./interfaces/IAccountFacet.sol\";\n\n/**\n * @title Account Facet\n * @dev Account module contract that provides the account features and initialization of signer\n * compatible with EIP-1271 & EIP-4337\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract AccountFacet is IAccountFacet, BarzStorage, BaseAccount {\n using ECDSA for bytes32;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceAccountInitialize();\n }\n\n /**\n * @notice Returns the address of EntryPoint contract registered to Barz account\n */\n function entryPoint() public view override returns (IEntryPoint) {\n return s.entryPoint;\n }\n\n /**\n * @notice Initializes the initial storage of the Barz contract.\n * @dev This method can only be called during the initialization or signature migration.\n * If the proxy contract was created without initialization, anyone can call initialize.\n * Barz calls initialize in constructor in an atomic transaction during deployment\n * @param _verificationFacet Facet contract handling the verificationi\n * @param _anEntryPoint Entrypoint contract defined in EIP-4337 handling the flow of UserOp\n * @param _facetRegistry Registry of Facets that hold all facet information\n * @param _defaultFallBackHandler Middleware contract for default facets\n * @param _ownerPublicKey Bytes of owner public key\n */\n function initialize(\n address _verificationFacet,\n address _anEntryPoint,\n address _facetRegistry,\n address _defaultFallBackHandler,\n bytes calldata _ownerPublicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceAccountInitialize();\n s.entryPoint = IEntryPoint(_anEntryPoint);\n s.facetRegistry = IFacetRegistry(_facetRegistry);\n LibDiamond.diamondStorage().defaultFallbackHandler = IDiamondLoupe(\n _defaultFallBackHandler\n );\n\n _cutDiamondAccountFacet(_verificationFacet);\n\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n _ownerPublicKey\n );\n // Every Verification Facet should comply with initializeSigner(bytes)\n // to be compatible with the Barz contract(for initialization)\n (bool success, bytes memory result) = _verificationFacet.delegatecall(\n initCall\n );\n if (!success || uint256(bytes32(result)) != 1) {\n revert AccountFacet__InitializationFailure();\n }\n\n initSuccess = 1;\n emit AccountInitialized(s.entryPoint, _ownerPublicKey);\n }\n\n function _cutDiamondAccountFacet(address _verificationFacet) internal {\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](1);\n\n bytes4 ownerVerificationFuncSelector = IVerificationFacet(\n _verificationFacet\n ).validateOwnerSignatureSelector();\n\n bytes4[] memory verificationFunctionSelectors = new bytes4[](3);\n verificationFunctionSelectors[0] = IERC1271.isValidSignature.selector;\n verificationFunctionSelectors[1] = ownerVerificationFuncSelector;\n verificationFunctionSelectors[2] = IVerificationFacet.owner.selector;\n cut[0] = IDiamondCut.FacetCut({\n facetAddress: _verificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: verificationFunctionSelectors\n });\n\n LibDiamond.diamondCut(cut, address(0), \"\");\n }\n\n /**\n * @notice Calls the destination with inputted calldata and value from EntryPoint\n * @dev This method executes the calldata coming from the EntryPoint.\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\n * @param _dest Address of destination where the call will be forwarded to\n * @param _value Amount of native coin the owner is willing to send(e.g. ETH, BNB)\n * @param _func Bytes of calldata to execute in the destination address\n */\n function execute(\n address _dest,\n uint256 _value,\n bytes calldata _func\n ) external override onlyWhenUnlocked {\n _requireFromEntryPoint();\n address restrictionsFacet = LibDiamond.restrictionsFacet();\n if (restrictionsFacet == address(0)) _call(_dest, _value, _func);\n else _callWithRestrictions(_dest, _value, _func, restrictionsFacet);\n }\n\n /**\n * @notice Batch calls the destination with inputted calldata and value from EntryPoint\n * @dev This method batch executes the calldata coming from the EntryPoint.\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\n * @param _dest Array of addresses of destination where the call will be forwarded to\n * @param _value Array of amount of native coin the owner is willing to send(e.g. ETH, BNB)\n * @param _func Array of bytes of calldata to execute in the destination address\n */\n function executeBatch(\n address[] calldata _dest,\n uint256[] calldata _value,\n bytes[] calldata _func\n ) external override onlyWhenUnlocked {\n _requireFromEntryPoint();\n if (_dest.length != _func.length || _dest.length != _value.length)\n revert AccountFacet__InvalidArrayLength();\n address restrictionsFacet = LibDiamond.restrictionsFacet();\n if (restrictionsFacet == address(0)) {\n for (uint256 i; i < _dest.length; ) {\n _call(_dest[i], _value[i], _func[i]);\n unchecked {\n ++i;\n }\n }\n } else {\n for (uint256 i; i < _dest.length; ) {\n _callWithRestrictions(\n _dest[i],\n _value[i],\n _func[i],\n restrictionsFacet\n );\n unchecked {\n ++i;\n }\n }\n }\n }\n\n /**\n * @notice Validates the signature field of UserOperation\n * @dev This method validates if the signature of UserOp is indeed valid by delegating the call to Verification Facet\n * Barz makes a call to the pre-registered Verification Facet address in App Storage\n * @param _userOp UserOperation from owner to be validated\n * @param _userOpHash Hash of UserOperation given from the EntryPoint contract\n */\n function _validateSignature(\n UserOperation calldata _userOp,\n bytes32 _userOpHash\n ) internal override returns (uint256 validationData) {\n // Get Facet with Function Selector\n address facet = LibLoupe.facetAddress(s.validateOwnerSignatureSelector);\n if (facet == address(0))\n revert AccountFacet__NonExistentVerificationFacet();\n\n // Make function call to VerificationFacet\n bytes memory validateCall = abi.encodeWithSelector(\n s.validateOwnerSignatureSelector,\n _userOp,\n _userOpHash\n );\n (bool success, bytes memory result) = facet.delegatecall(validateCall);\n if (!success) revert AccountFacet__CallNotSuccessful();\n validationData = uint256(bytes32(result));\n if (validationData == 0) emit VerificationSuccess(_userOpHash);\n else emit VerificationFailure(_userOpHash);\n }\n\n /**\n * @notice Calls the target with the inputted value and calldata\n * @dev This method is the actual function in Barz that makes a call with an arbitrary owner-given data\n * @param _target Address of the destination contract which the call is getting forwarded to\n * @param _value Amount of Native coin the owner is wanting to make in this call\n * @param _data Calldata the owner is forwarding together in the call e.g. Swap/Token Transfer\n */\n function _call(\n address _target,\n uint256 _value,\n bytes memory _data\n ) internal {\n (bool success, bytes memory result) = _target.call{value: _value}(\n _data\n );\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n }\n\n /**\n * @notice Calls the target with the inputted value and calldata together with restrictions check\n * @dev This method is the actual function in Barz that makes a call with an arbitrary owner-given data\n * @param _target Address of the destination contract which the call is getting forwarded to\n * @param _value Amount of Native coin the owner is wanting to make in this call\n * @param _data Calldata the owner is forwarding together in the call e.g. Swap/Token Transfer\n * @param _restrictionsFacet Address of Facet to validate restrictions\n */\n function _callWithRestrictions(\n address _target,\n uint256 _value,\n bytes memory _data,\n address _restrictionsFacet\n ) internal {\n // NOTE: No restrictions facet, so restriction validation passes\n if (_checkRestrictions(_restrictionsFacet, _target, _value, _data) != 0)\n revert AccountFacet__RestrictionsFailure();\n\n (bool success, bytes memory result) = _target.call{value: _value}(\n _data\n );\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n }\n\n /**\n * @notice Checks restrictions if the restrictions facet exists\n * @dev This method checks if the restrictions facet exists and makes a verification call to an array of restrictions facet\n * @param _facet Address that holds the restrictions logic\n * @param _target Address the call is getting forwarded to\n * @param _value Amount of native coin the call is sending together with the call\n * @param _data Calldata to trigger execution in target address\n */\n function _checkRestrictions(\n address _facet,\n address _target,\n uint256 _value,\n bytes memory _data\n ) internal returns (uint256 result) {\n bytes memory call = abi.encodeWithSignature(\n \"verifyRestrictions(address,address,uint256,bytes)\",\n address(this),\n _target,\n _value,\n _data\n );\n (bool success, bytes memory response) = _facet.delegatecall(call);\n if (!success) revert AccountFacet__RestrictionsFailure();\n result = uint256(bytes32(response));\n }\n}\n" + }, + "contracts/facets/AccountRecoveryFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibFacetStorage, RecoveryStorage, RecoveryConfig, RecoveryApprovalConfig, ApprovalConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {IAccountRecoveryFacet} from \"./interfaces/IAccountRecoveryFacet.sol\";\n\n/**\n * @title Account Recovery Facet\n * @dev Contract that enables recovery of accounts when owner key is unavailable\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract AccountRecoveryFacet is IAccountRecoveryFacet, Modifiers {\n bytes constant UNINIT_CALL =\n abi.encodeWithSignature(\"uninitializeSigner()\");\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Approve recovery of account as guardian\n * @dev This method can only be called by guardian and guardian inputs the public key of the new owner\n * When the threshold(majority of guardians) passes, it automatically executes account recovery\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function approveAccountRecovery(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + _getApprovalValidationPeriod()\n );\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit RecoveryApproved(\n _recoveryPublicKey,\n msg.sender,\n approvalValidUntil\n );\n if (\n getRecoveryApprovalCountWithTimeValidity(recoveryPublicKeyHash) >=\n LibGuardian.majorityOfGuardians()\n ) _executeRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Revoke recovery of account as guardian\n * @dev This method can only be called by guardian and guardian inputs the public key of the new owner\n When the threshold(majority of guardians) passes, it automatically revokes account recovery when recovery is pending\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function revokeAccountRecoveryApproval(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n if (\n !rs\n .isNewOwnerApproved[recoveryPublicKeyHash][msg.sender].isApproved ||\n !(block.timestamp <\n rs\n .isNewOwnerApproved[recoveryPublicKeyHash][msg.sender]\n .validUntil)\n ) revert AccountRecoveryFacet__NonExistentApproval();\n\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(false, 0);\n emit RecoveryApprovalRevoked(_recoveryPublicKey, msg.sender);\n }\n\n /**\n * @notice Executes recovery with signatures or on-chain pre-approvals\n * @dev This method validates the signatures of guardians or checks the on-chain pre-approved calls to check if the threshold passes\n * When the threshold passes, account recovery is executed and revert otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _guardians Array of guardians address that are approving the recovery of Account\n * @param _signatures Array of signature bytes that signed the approval hash\n */\n function executeRecovery(\n bytes calldata _recoveryPublicKey,\n address[] calldata _guardians,\n bytes[] calldata _signatures\n ) external override {\n if (_isRecoveryPending())\n revert AccountRecoveryFacet__RecoveryAlreadyOngoing();\n if (_guardians.length != _signatures.length)\n revert AccountRecoveryFacet__InvalidArrayLength();\n validateNewOwner(_recoveryPublicKey);\n\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n\n _checkApprover(_guardians);\n _checkDuplicateOnChainApprover(recoveryPublicKeyHash, _guardians);\n\n if (\n _guardians.length +\n getRecoveryApprovalCountWithTimeValidity(\n recoveryPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians()\n ) revert AccountRecoveryFacet__InsufficientGuardians();\n for (uint256 i; i < _guardians.length; ) {\n if (!LibGuardian.isGuardian(_guardians[i]))\n revert AccountRecoveryFacet__InvalidGuardian();\n if (\n !SignatureChecker.isValidSignatureNow(\n _guardians[i],\n recoveryPublicKeyHash,\n _signatures[i]\n )\n ) revert AccountRecoveryFacet__InvalidGuardianSignature();\n unchecked {\n ++i;\n }\n }\n _executeRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Executes recovery of the account. Note that execution and finalization is a different process\n * @dev Executes the recovery and adds recovery data to recovery configuration. Locks the account\n * @param _recoveryPublicKey Public Key of the account for recovery\n */\n function _executeRecovery(bytes memory _recoveryPublicKey) internal {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n unchecked {\n ++rs.nonce;\n }\n uint64 executeAfter = uint64(block.timestamp + _getRecoveryPeriod());\n rs.recoveryConfigs[INNER_STRUCT] = RecoveryConfig(\n _recoveryPublicKey,\n executeAfter // NOTE: Remove guardian Count\n );\n LibAppStorage.setLock(\n block.timestamp + _getLockPeriod(),\n AccountRecoveryFacet.executeRecovery.selector\n );\n emit RecoveryExecuted(_recoveryPublicKey, executeAfter);\n }\n\n /**\n * @notice Finalize recovery after recovery pending period. Recovery pending period can be set by user beforehand in SecurityManager\n * @dev This method finalizes recovery and fully changes the ownership of the account to the newly inputted recovery public key\n */\n function finalizeRecovery() external override {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n if (\n uint64(block.timestamp) <=\n rs.recoveryConfigs[INNER_STRUCT].executeAfter\n ) revert AccountRecoveryFacet__RecoveryPeriodNotOver();\n bytes memory recoveryOwner = rs\n .recoveryConfigs[INNER_STRUCT]\n .recoveryPublicKey;\n\n delete rs.recoveryConfigs[INNER_STRUCT];\n\n LibAppStorage.setLock(0, bytes4(0));\n\n LibAppStorage.initiateSignerMigration();\n address verificationFacet = address(\n bytes20(\n LibDiamond.diamondStorage().facets[\n s.validateOwnerSignatureSelector\n ]\n )\n );\n (bool success, bytes memory result) = verificationFacet.delegatecall(\n UNINIT_CALL\n );\n if (!success) revert AccountRecoveryFacet__CallNotSuccesful();\n uint256 validationData = uint256(bytes32(result));\n if (validationData != 1)\n revert AccountRecoveryFacet__SignerUninitializationFailure();\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n recoveryOwner\n );\n (success, result) = verificationFacet.delegatecall(initCall);\n if (!success) revert AccountRecoveryFacet__CallNotSuccesful();\n validationData = uint256(bytes32(result));\n if (validationData != 1)\n revert AccountRecoveryFacet__SignerInitializationFailure();\n LibAppStorage.finalizeSignerMigration();\n emit RecoveryFinalized(recoveryOwner);\n }\n\n /**\n * @notice Approves the cancellation of recovery\n * @dev This method approves the cancellation of recovery when recovery is still pending - waiting for finalization\n * @param _recoveryPublicKey Bytes of public key which is pending for recovery\n */\n function approveCancelRecovery(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"CancelRecovery\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + _getApprovalValidationPeriod()\n );\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit RecoveryCancellationApproved(_recoveryPublicKey, msg.sender);\n if (\n getRecoveryApprovalCountWithTimeValidity(recoveryPublicKeyHash) >=\n LibGuardian.majorityOfGuardians()\n ) {\n _cancelRecovery(_recoveryPublicKey);\n }\n }\n\n /**\n * @notice Hardstops an ongoing recovery\n * @dev This method provides a safety mechanism to protect owners of malicious guardians.\n * Owners can hardstop recovery when an malicious guardians starts the recovery process.\n * @param _signature Signature of the owner that signs the hash to hardstop recovery\n */\n function hardstopRecovery(bytes calldata _signature) external override {\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n \"0\",\n \"HardstopRecovery\"\n );\n if (\n !SignatureChecker.isValidSignatureNow(\n address(this),\n recoveryPublicKeyHash,\n _signature\n )\n ) revert AccountRecoveryFacet__InvalidOwnerSignature();\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n unchecked {\n ++rs.nonce;\n }\n delete rs.recoveryConfigs[INNER_STRUCT];\n LibAppStorage.setLock(0, bytes4(0));\n emit RecoveryHardstopped();\n }\n\n /**\n * @notice Cancels recovery with signatures or on-chain pre-approvals\n * @dev This method validates the signatures of guardians or checks the on-chain pre-approved calls to check if the threshold passes\n * When the threshold passes, account recovery is canceled and revert otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _guardians Array of guardians address that are approving the recovery of Account\n * @param _signatures Array of signature bytes that signed the cancellation approval hash\n */\n function cancelRecovery(\n bytes calldata _recoveryPublicKey,\n address[] calldata _guardians,\n bytes[] calldata _signatures\n ) external override {\n if (_guardians.length != _signatures.length)\n revert AccountRecoveryFacet__InvalidArrayLength();\n validateNewOwner(_recoveryPublicKey);\n\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"CancelRecovery\"\n );\n\n _checkApprover(_guardians);\n _checkDuplicateOnChainApprover(recoveryPublicKeyHash, _guardians);\n\n if (\n _guardians.length +\n getRecoveryApprovalCountWithTimeValidity(\n recoveryPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians()\n ) revert AccountRecoveryFacet__InsufficientGuardians();\n for (uint256 i; i < _guardians.length; ) {\n if (!LibGuardian.isGuardian(_guardians[i]))\n revert AccountRecoveryFacet__CallerNotGuardian();\n if (\n !SignatureChecker.isValidSignatureNow(\n _guardians[i],\n recoveryPublicKeyHash,\n _signatures[i]\n )\n ) revert AccountRecoveryFacet__InvalidGuardianSignature();\n unchecked {\n ++i;\n }\n }\n _cancelRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Cancel recovery when the recovery is pending. Unlock the account as well\n * @dev This method checks if the recovery is pending and reverts if not pending.\n * It increases the recovery nonce and deletes the recovery information and gets a small portion of gas in return\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function _cancelRecovery(bytes memory _recoveryPublicKey) internal {\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n LibAppStorage.setLock(0, bytes4(0));\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n unchecked {\n ++rs.nonce;\n }\n delete rs.recoveryConfigs[INNER_STRUCT];\n emit RecoveryCanceled(_recoveryPublicKey);\n }\n\n /**\n * @notice Validates the format of public key to be used for recovery\n * @dev This method checks if the public key format is correct and reverts otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function validateNewOwner(bytes memory _recoveryPublicKey) public view {\n if (\n !IVerificationFacet(\n LibLoupe.facetAddress(s.validateOwnerSignatureSelector)\n ).isValidKeyType(_recoveryPublicKey)\n ) revert AccountRecoveryFacet__InvalidRecoveryPublicKey();\n }\n\n /**\n * @notice Checks if recovery is currently pending\n * @return isPending Boolean indicating if recovery is pending\n */\n function _isRecoveryPending() internal view returns (bool isPending) {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n isPending = (rs.recoveryConfigs[INNER_STRUCT].executeAfter > 0);\n }\n\n /**\n * @notice Calculate the recovery hash dependent on chain, wallet address, nonce with EIP-191 prefix for safety\n * @dev Returns the keccak256 hash of EIP-191 msg hash packed with public key, salt, nonce, wallet address, etc\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _saltString Salt string to uniquely identify each recovery hash and for security\n * @return recoveryKeyHash Bytes32 string of the recovery hash\n */\n function getApprovalRecoveryKeyHash(\n bytes memory _recoveryPublicKey,\n string memory _saltString\n ) public view override returns (bytes32 recoveryKeyHash) {\n recoveryKeyHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n _recoveryPublicKey,\n _saltString,\n address(this),\n block.chainid,\n LibFacetStorage.recoveryStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Check the onchain approval of guardians and returns the number of guardians that approved\n * @dev Loop through the guardian addresses and returns the number of guardians that approved this recovery hash\n * @param _recoveryPublicKeyHash Bytes hash of newly recovered public key and recovery value of the account\n * @return approvalCount Number of guardians that approved\n */\n function getRecoveryApprovalCountWithTimeValidity(\n bytes32 _recoveryPublicKeyHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n for (uint256 i; i < guardianLength; ) {\n if (isRecoveryApproved(_recoveryPublicKeyHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Checks if the recovery is approved by the given approver\n * @param _recoveryPublicKeyHash Hash of the public key and configuration for recovery\n * @param _approver Address of approver\n * @return isApproved Bool value if recovery hash is approved\n */\n function isRecoveryApproved(\n bytes32 _recoveryPublicKeyHash,\n address _approver\n ) public view override returns (bool isApproved) {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n if (\n rs\n .isNewOwnerApproved[_recoveryPublicKeyHash][_approver].isApproved &&\n block.timestamp <\n rs.isNewOwnerApproved[_recoveryPublicKeyHash][_approver].validUntil\n ) {\n isApproved = true;\n }\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _recoveryPublicKeyHash Hash of recovery information\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _recoveryPublicKeyHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isRecoveryApproved(_recoveryPublicKeyHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert AccountRecoveryFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the lock period of this wallet address from security manager\n * @return lockPeriod value of lock period\n */\n function _getLockPeriod() internal view returns (uint256 lockPeriod) {\n lockPeriod = securityManager.lockPeriodOf(address(this));\n if (lockPeriod == 0) revert AccountRecoveryFacet__InvalidLockPeriod();\n }\n\n /**\n * @notice Returns the lock period of this wallet address from security manager\n * @return recoveryPeriod value of recovery period\n */\n function _getRecoveryPeriod()\n internal\n view\n returns (uint256 recoveryPeriod)\n {\n recoveryPeriod = securityManager.recoveryPeriodOf(address(this));\n if (recoveryPeriod == 0)\n revert AccountRecoveryFacet__InvalidRecoveryPeriod();\n }\n\n /**\n * @notice Returns the approval validation period of this wallet address from security manager\n * @return approvalValidationPeriod value of approval validation period\n */\n function _getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod == 0)\n revert AccountRecoveryFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the recovery nonce of this wallet address from security manager\n * @return nonce value of recovery nonce\n */\n function getRecoveryNonce() public view override returns (uint128 nonce) {\n nonce = LibFacetStorage.recoveryStorage().nonce;\n }\n\n /**\n * @notice Returns the recovery information of the pending recovery\n * @return recoveryConfig value struct of pending recovery\n */\n function getPendingRecovery()\n public\n view\n override\n returns (RecoveryConfig memory recoveryConfig)\n {\n recoveryConfig = LibFacetStorage.recoveryStorage().recoveryConfigs[\n INNER_STRUCT\n ];\n }\n}\n" + }, + "contracts/facets/base/DiamondCutFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibGuardian} from \"../../libraries/LibGuardian.sol\";\nimport {ISecurityManager} from \"../../infrastructure/interfaces/ISecurityManager.sol\";\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibFacetStorage, DiamondCutApprovalConfig, ApprovalConfig} from \"../../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"../Modifiers.sol\";\nimport {IDiamondCut} from \"./interfaces/IDiamondCut.sol\";\n\n/**\n * @title DiamondCut Facet\n * @dev Responsible for adding/removing/replace facets in Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DiamondCutFacet is Modifiers, IDiamondCut {\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Updates the flag for the interfaceId\n * @param _interfaceId InterfaceID to update the mapping\n * @param _flag Bool value to update the mapping of the given interface ID\n */\n function updateSupportsInterface(\n bytes4 _interfaceId,\n bool _flag\n ) external override onlyWhenUnlocked {\n LibDiamond.enforceIsSelf();\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId] = _flag;\n emit SupportsInterfaceUpdated(_interfaceId, _flag);\n }\n\n /**\n * @notice Add/replace/remove any number of functions and optionally execute\n * a function with delegatecall when guardians don't exist\n * @param _diamondCut Contains the facet addresses and function selectors\n * @param _init The address of the contract or facet to execute _calldata. It's prohibited in Barz\n */\n function diamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata\n ) external override onlyWhenUnlocked {\n LibDiamond.enforceIsSelf();\n\n _checkFacetCutValidity(_diamondCut);\n // require approval from guardian if guardian exists\n if (0 != LibGuardian.guardianCount())\n revert DiamondCutFacet__InvalidRouteWithGuardian();\n if (address(0) != _init) revert DiamondCutFacet__InvalidInitAddress();\n\n unchecked {\n ++LibFacetStorage.diamondCutStorage().nonce;\n }\n LibDiamond.diamondCut(_diamondCut, address(0), \"\");\n }\n\n /**\n * @notice Add/replace/remove any number of functions and optionally execute\n * a function with delegatecall when guardians exist\n * @param _diamondCut Contains the facet addresses and function selectors\n * @param _approvers Guardian or owner address that approves the diamond cut\n * @param _signatures Signature of Guardians or owner that approves the diamond cut\n */\n function diamondCutWithGuardian(\n FacetCut[] calldata _diamondCut,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n ) external override onlyWhenUnlocked {\n if (_approvers.length != _signatures.length)\n revert DiamondCutFacet__InvalidArrayLength();\n _checkFacetCutValidity(_diamondCut);\n if (0 == LibGuardian.guardianCount())\n revert DiamondCutFacet__InvalidRouteWithGuardian();\n\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(cutHash, _approvers);\n\n bool onChainOwnerApproval = getOwnerCutApprovalWithTimeValidity(\n cutHash\n );\n\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n if (\n _approvers.length +\n getDiamondCutApprovalCountWithTimeValidity(cutHash) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert DiamondCutFacet__InsufficientApprovers();\n\n bool ownerApproved;\n for (uint256 i; i < _approvers.length; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n _approvers[i] != address(this)\n ) revert DiamondCutFacet__InvalidApprover();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert DiamondCutFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n cutHash,\n _signatures[i]\n )\n ) revert DiamondCutFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n if (!ownerApproved && !onChainOwnerApproval)\n revert DiamondCutFacet__LackOfOwnerApproval();\n\n unchecked {\n ++LibFacetStorage.diamondCutStorage().nonce;\n }\n LibDiamond.diamondCut(_diamondCut, address(0), \"\");\n }\n\n /**\n * @notice Approves diamond cut. This can only be called directly from guardian or owner\n * @param _diamondCut Contains the facet addresses and function selectors\n */\n function approveDiamondCut(\n FacetCut[] calldata _diamondCut\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\n if (LibGuardian.guardianCount() == 0)\n revert DiamondCutFacet__InvalidRouteWithoutGuardian();\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n _checkFacetCutValidity(_diamondCut);\n\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(\n true,\n approvalValidUntil\n );\n emit DiamondCutApproved(_diamondCut);\n if (\n (getDiamondCutApprovalCountWithTimeValidity(cutHash) >=\n LibGuardian.majorityOfGuardians()) &&\n getOwnerCutApprovalWithTimeValidity(cutHash)\n ) {\n unchecked {\n ++LibFacetStorage.diamondCutStorage().nonce;\n }\n LibDiamond.diamondCut(_diamondCut, address(0), \"\");\n }\n }\n\n /**\n * @notice Revokes the approval of diamond cut. This can only be called directly from guardian or owner\n * @param _diamondCut Contains the facet addresses and function selectors\n */\n function revokeDiamondCutApproval(\n FacetCut[] calldata _diamondCut\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\n if (!ds.isDiamondCutApproved[cutHash][msg.sender].isApproved)\n revert DiamondCutFacet__CannotRevokeUnapproved();\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(false, 0);\n emit DiamondCutApprovalRevoked(_diamondCut);\n }\n\n /**\n * @notice Gets the number of approvals of diamond cut from guardians\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n */\n function getDiamondCutApprovalCountWithTimeValidity(\n bytes32 _diamondCutHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardiansLength = guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n if (isCutApproved(_diamondCutHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n return approvalCount;\n }\n\n /**\n * @notice Returns if the owner has approved the diamond cut\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @return isApprovedByOwner Bool value showing if the owner approved the cut\n */\n function getOwnerCutApprovalWithTimeValidity(\n bytes32 _diamondCutHash\n ) public view override returns (bool isApprovedByOwner) {\n isApprovedByOwner = isCutApproved(_diamondCutHash, address(this));\n }\n\n /**\n * @notice Returns if the given approver has approved the diamond cut\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @param _approver Address of approver\n * @return isApproved Bool value showing if the approver approved the cut\n */\n function isCutApproved(\n bytes32 _diamondCutHash,\n address _approver\n ) public view override returns (bool isApproved) {\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n isApproved = (ds\n .isDiamondCutApproved[_diamondCutHash][_approver].isApproved &&\n block.timestamp <\n ds.isDiamondCutApproved[_diamondCutHash][_approver].validUntil);\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _diamondCutHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isCutApproved(_diamondCutHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert DiamondCutFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the diamond cut hash. This function ensures that this hash is safe from replay attack by including\n * salt, address, chainId, and nonce, etc.\n * @param _diamondCut Contains the facet addresses and function selectors\n * @return cutHash Diamond Cut Hash\n */\n function getDiamondCutHash(\n FacetCut[] calldata _diamondCut\n ) public view override returns (bytes32 cutHash) {\n cutHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n keccak256(abi.encode(_diamondCut)),\n address(this),\n block.chainid,\n LibFacetStorage.diamondCutStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Returns the approval validation Period\n * @dev This method fetches the validation period from the security manager\n * @return approvalValidationPeriod Approval validation period of Barz contract fetched from security manager\n */\n function getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod <= 0)\n revert DiamondCutFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the diamond cut nonce of this wallet\n * @dev This method fetches the nonce from diamond cut storage\n * @return cutNonce Nonce of diamond cut to protect from reply attacks\n */\n function getDiamondCutNonce()\n public\n view\n override\n returns (uint128 cutNonce)\n {\n cutNonce = LibFacetStorage.diamondCutStorage().nonce;\n }\n}\n" + }, + "contracts/facets/base/DiamondLoupeFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {IERC165} from \"../../interfaces/ERC/IERC165.sol\";\nimport {IERC1271} from \"../../interfaces/ERC/IERC1271.sol\";\nimport {IERC677Receiver} from \"../../interfaces/ERC/IERC677Receiver.sol\";\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC1155Receiver} from \"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\";\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../../libraries/LibLoupe.sol\";\nimport {LibUtils} from \"../../libraries/LibUtils.sol\";\nimport {IDiamondCut} from \"../../facets/base/interfaces/IDiamondCut.sol\";\nimport {IStorageLoupe} from \"./interfaces/IStorageLoupe.sol\";\nimport {IDiamondLoupe} from \"./interfaces/IDiamondLoupe.sol\";\n\n/**\n * @title DiamondLoupe Facet\n * @dev DiamondLoupe contract compatible with EIP-2535\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DiamondLoupeFacet is IDiamondLoupe, IStorageLoupe, IERC165 {\n // Diamond Loupe Functions\n ////////////////////////////////////////////////////////////////////\n /// These functions are expected to be called frequently by tools off-chain.\n\n /**\n * @notice Gets all facets and their selectors.\n * @dev Barz uses a special architecture called default fallback handler. Default Fallback handler is used as a middleware\n * that holds the mapping of facet function selector and facet address that Barz uses. This helps Barz to reduce\n * significant amount of gas during the initialization process.\n * Hence, this method aggregates both the facet information from DefaulFallbackHandler and in diamond storage and shows the data to users.\n * @return facets_ Facet\n */\n function facets() public view override returns (Facet[] memory facets_) {\n Facet[] memory defaultFacet = LibDiamond\n .diamondStorage()\n .defaultFallbackHandler\n .facets();\n Facet[] memory _facets = LibLoupe.facets();\n uint256 numFacets = _facets.length;\n bytes4[] memory keys;\n address[] memory values;\n for (uint256 i; i < numFacets; ) {\n uint256 selectorsLength = _facets[i].functionSelectors.length;\n for (uint256 j; j < selectorsLength; ) {\n (keys, values) = LibUtils.setValue(\n keys,\n values,\n _facets[i].functionSelectors[j],\n _facets[i].facetAddress\n );\n unchecked {\n ++j;\n }\n }\n unchecked {\n ++i;\n }\n }\n {\n bool iIncrement;\n for (uint256 i; i < defaultFacet.length; ) {\n bool jIncrement;\n for (\n uint256 j;\n j < defaultFacet[i].functionSelectors.length;\n\n ) {\n if (\n LibUtils.getValue(\n keys,\n values,\n defaultFacet[i].functionSelectors[j]\n ) != address(0)\n ) {\n if (defaultFacet[i].functionSelectors.length == 1) {\n defaultFacet = LibUtils.removeFacetElement(\n defaultFacet,\n i\n );\n iIncrement = true;\n break;\n }\n defaultFacet[i].functionSelectors = LibUtils\n .removeElement(\n defaultFacet[i].functionSelectors,\n j\n );\n jIncrement = true;\n }\n if (!jIncrement) {\n unchecked {\n ++j;\n }\n } else {\n jIncrement = false;\n }\n }\n if (!iIncrement) {\n unchecked {\n ++i;\n }\n } else {\n iIncrement = false;\n }\n }\n }\n {\n uint256 facetLength = numFacets + defaultFacet.length;\n facets_ = new Facet[](facetLength);\n uint256 defaultFacetIndex;\n for (uint256 i; i < facetLength; ) {\n if (i < numFacets) {\n facets_[i] = _facets[i];\n bool jIncrementor;\n for (uint256 j; j < defaultFacet.length; ) {\n if (\n facets_[i].facetAddress ==\n defaultFacet[j].facetAddress\n ) {\n facets_[i].functionSelectors = LibUtils.mergeArrays(\n _facets[i].functionSelectors,\n defaultFacet[j].functionSelectors\n );\n defaultFacet = LibUtils.removeFacetElement(\n defaultFacet,\n j\n );\n jIncrementor = true;\n {\n facets_ = LibUtils.removeFacetElement(\n facets_,\n facets_.length - 1\n );\n }\n --facetLength;\n }\n if (!jIncrementor) {\n unchecked {\n ++j;\n }\n } else {\n jIncrementor = false;\n }\n }\n } else {\n facets_[i] = defaultFacet[defaultFacetIndex];\n ++defaultFacetIndex;\n }\n unchecked {\n ++i;\n }\n }\n }\n }\n\n /**\n * @notice Gets all the function selectors provided by a facet.\n * @param _facet The facet address.\n * @return facetFunctionSelectors_\n */\n function facetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n Facet[] memory facet = facets();\n uint256 facetLength = facet.length;\n for (uint256 i; i < facetLength; ) {\n if (facet[i].facetAddress == _facet)\n return facet[i].functionSelectors;\n unchecked {\n ++i;\n }\n }\n return facetFunctionSelectors_;\n }\n\n /**\n * @notice Get all the facet addresses used by Barz.\n * @return facetAddresses_\n */\n function facetAddresses()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n Facet[] memory facet = facets();\n uint256 facetLength = facet.length;\n facetAddresses_ = new address[](facetLength);\n for (uint256 i; i < facetLength; ) {\n facetAddresses_[i] = facet[i].facetAddress;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Gets the facet that supports the given selector.\n * @dev If facet is not found return address(0).\n * @param _functionSelector The function selector.\n * @return facetAddress_ The facet address.\n */\n function facetAddress(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n\n facetAddress_ = address(bytes20(ds.facets[_functionSelector]));\n if (facetAddress_ == address(0)) {\n facetAddress_ = IDiamondLoupe(ds.defaultFallbackHandler)\n .facetAddress(_functionSelector);\n }\n }\n\n /**\n * @notice SupportInterface to be compatible with EIP 165\n * @param _interfaceId Interface ID for detecting the interface\n * @return isSupported Bool value showing if the standard is supported in the contract\n */\n function supportsInterface(\n bytes4 _interfaceId\n ) external view override returns (bool isSupported) {\n isSupported =\n _interfaceId == type(IERC165).interfaceId ||\n _interfaceId == IDiamondCut.diamondCut.selector ||\n _interfaceId == type(IDiamondLoupe).interfaceId ||\n _interfaceId == type(IERC1155Receiver).interfaceId ||\n _interfaceId == type(IERC721Receiver).interfaceId ||\n _interfaceId == type(IERC777Recipient).interfaceId ||\n _interfaceId == IERC1271.isValidSignature.selector ||\n _interfaceId == type(IERC677Receiver).interfaceId ||\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId];\n }\n\n /**\n * @notice Returns the facet from the diamond storage. This excludes the facets from the default fallback handler\n * @return facets_ Facet information attached directly to diamond storage\n */\n function facetsFromStorage()\n external\n view\n override\n returns (Facet[] memory facets_)\n {\n facets_ = LibLoupe.facets();\n }\n\n /**\n * @notice Returns the facet address attached to the given function selector. This excludes the facets from the default fallback handler\n * @param _functionSelector Function selector to fetch the facet address from diamond storage\n * @return facetAddress_ Facet address mapped with the function selector\n */\n function facetAddressFromStorage(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n facetAddress_ = LibLoupe.facetAddress(_functionSelector);\n }\n\n /**\n * @notice Returns all facet addresses attached directly to diamond storage. This excludes the facets from the default fallback handler\n * @return facetAddresses_ All facet addresses attached directly to diamond storage\n */\n function facetAddressesFromStorage()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n facetAddresses_ = LibLoupe.facetAddresses();\n }\n\n /**\n * @notice Returns function selectors of given facet address attached directly to diamond storage. This excludes the facets from the default fallback handler\n * @param _facet Facet address to fetch the facet function selectors from diamond storage\n * @return facetFunctionSelectors_ Facet function selectors of the given facet address\n */\n function facetFunctionSelectorsFromStorage(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n facetFunctionSelectors_ = LibLoupe.facetFunctionSelectors(_facet);\n }\n}\n" + }, + "contracts/facets/base/interfaces/IDiamondCut.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title DiamondCut Facet Interface\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IDiamondCut {\n error DiamondCutFacet__InvalidRouteWithGuardian();\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\n error DiamondCutFacet__InvalidArrayLength();\n error DiamondCutFacet__InsufficientApprovers();\n error DiamondCutFacet__InvalidApprover();\n error DiamondCutFacet__InvalidApproverSignature();\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\n error DiamondCutFacet__CannotRevokeUnapproved();\n error DiamondCutFacet__LackOfOwnerApproval();\n error DiamondCutFacet__OwnerAlreadyApproved();\n error DiamondCutFacet__DuplicateApproval();\n error DiamondCutFacet__InvalidInitAddress();\n\n event DiamondCutApproved(FacetCut[] diamondCut);\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\n\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\n\n enum FacetCutAction {\n Add,\n Replace,\n Remove\n }\n // Add=0, Replace=1, Remove=2\n\n struct FacetCut {\n address facetAddress;\n FacetCutAction action;\n bytes4[] functionSelectors;\n }\n\n /// @notice Add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param diamondCut Contains the facet addresses and function selectors\n /// @param init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function diamondCut(\n FacetCut[] calldata diamondCut,\n address init,\n bytes calldata _calldata\n ) external;\n\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\n\n function diamondCutWithGuardian(\n FacetCut[] calldata diamondCut,\n address[] calldata approvers,\n bytes[] calldata signatures\n ) external;\n\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\n\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\n\n function getDiamondCutApprovalCountWithTimeValidity(\n bytes32 diamondCutHash\n ) external view returns (uint256);\n\n function getOwnerCutApprovalWithTimeValidity(\n bytes32 diamondCutHash\n ) external view returns (bool);\n\n function isCutApproved(\n bytes32 diamondCutHash,\n address approver\n ) external view returns (bool);\n\n function getDiamondCutHash(\n FacetCut[] calldata diamondCut\n ) external view returns (bytes32);\n\n function getDiamondCutNonce() external view returns (uint128);\n}\n" + }, + "contracts/facets/base/interfaces/IDiamondLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n// A loupe is a small magnifying glass used to look at diamonds.\n// These functions look at diamonds\ninterface IDiamondLoupe {\n /// These functions are expected to be called frequently\n /// by tools.\n\n struct Facet {\n address facetAddress;\n bytes4[] functionSelectors;\n }\n\n /// @notice Gets all facet addresses and their four byte function selectors.\n /// @return facets_ Facet\n function facets() external view returns (Facet[] memory facets_);\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n /// @return facetFunctionSelectors_\n function facetFunctionSelectors(\n address _facet\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses()\n external\n view\n returns (address[] memory facetAddresses_);\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(\n bytes4 _functionSelector\n ) external view returns (address facetAddress_);\n}\n" + }, + "contracts/facets/base/interfaces/IStorageLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"./IDiamondLoupe.sol\";\n\n/**\n * @title LoupeFromStorage Interface\n * @dev Interface contract to function as a loupe facet directly attached to diamond storage of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IStorageLoupe {\n /// These functions are expected to be called frequently\n /// by tools.\n\n /// @notice Gets all facet addresses and their four byte function selectors.\n /// @return facets_ Facet\n function facetsFromStorage()\n external\n view\n returns (IDiamondLoupe.Facet[] memory);\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n function facetFunctionSelectorsFromStorage(\n address _facet\n ) external view returns (bytes4[] memory);\n\n /// @notice Get all the facet addresses used by a diamond.\n function facetAddressesFromStorage()\n external\n view\n returns (address[] memory);\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n function facetAddressFromStorage(\n bytes4 _functionSelector\n ) external view returns (address);\n}\n" + }, + "contracts/facets/GuardianFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibFacetStorage, GuardianStorage, StorageConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IGuardianFacet} from \"./interfaces/IGuardianFacet.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Guardian Facet\n * @dev Contract that enables addition/removal of guardians from Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract GuardianFacet is IGuardianFacet {\n ISecurityManager public immutable securityManager;\n uint8 public constant INNER_STRUCT = 0;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Add guardians to Barz.\n * @dev This method internally calls addGuardian which checks the validity of guardian address and adds\n * as guardian if valid\n * @param _guardians Array of addresses to add as guardian\n */\n function addGuardians(address[] calldata _guardians) external override {\n LibDiamond.enforceIsSelf();\n for (uint256 i; i < _guardians.length; ) {\n addGuardian(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Add a guardian to Barz.\n * @dev This method checks if the function is called by the owner and validates the address of guardian\n * When the validation passes, guardian address is added to the pending state waiting for confirmation\n * @param _guardian Address to add as guardian\n */\n function addGuardian(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (_guardian == address(this))\n revert GuardianFacet__GuardianCannotBeSelf();\n if (isGuardian(_guardian)) revert GuardianFacet__DuplicateGuardian();\n if (_guardian == address(0))\n revert GuardianFacet__ZeroAddressGuardian();\n if (\n keccak256(abi.encodePacked(_guardian)) ==\n keccak256(IVerificationFacet(address(this)).owner())\n ) revert GuardianFacet__OwnerCannotBeGuardian();\n\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n if (\n gs.pending[id] != 0 ||\n block.timestamp <= gs.pending[id] + getSecurityWindow()\n ) revert GuardianFacet__DuplicateGuardianAddition();\n\n uint256 securityPeriod = getAdditionSecurityPeriod();\n gs.pending[id] = block.timestamp + securityPeriod;\n emit GuardianAdditionRequested(\n _guardian,\n block.timestamp + securityPeriod\n );\n }\n\n /**\n * @notice Remove guardians from Barz.\n * @dev This method internally calls removeGuardian which checks the validity of guardian and removes\n * guardian when the request is valid\n * @param _guardians Array of addresses to be removed\n */\n function removeGuardians(address[] calldata _guardians) external override {\n LibDiamond.enforceIsSelf();\n for (uint256 i; i < _guardians.length; ) {\n removeGuardian(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Remove a guardian from Barz.\n * @dev This method validates if the guardian to be removed is a guardian and puts the guardian removal\n * to a pending state waiting to be confirmed.\n * @param _guardian Address of guardian to be removed\n */\n function removeGuardian(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n if (!isGuardian(_guardian)) revert GuardianFacet__NonExistentGuardian();\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n if (\n gs.pending[id] != 0 ||\n block.timestamp <= gs.pending[id] + getSecurityWindow()\n ) revert GuardianFacet__DuplicateGuardianRemoval();\n\n uint256 securityPeriod = getRemovalSecurityPeriod();\n gs.pending[id] = block.timestamp + securityPeriod;\n emit GuardianRemovalRequested(\n _guardian,\n block.timestamp + securityPeriod\n );\n }\n\n /**\n * @notice Confirm addition of guardians\n * @dev This method internally calls confirmGuardianAddition which checks the validity of pending request.\n * Guardians are fully added when they pass the validation. Anyone can call this function.\n * @param _guardians Array of guardian addresses to be added\n */\n function confirmGuardianAdditions(\n address[] calldata _guardians\n ) external override {\n for (uint256 i; i < _guardians.length; ) {\n confirmGuardianAddition(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Confirm addition of a guardian\n * @dev This method checks the validity of pending request.\n * Guardians are fully added when they pass the validation. Anyone can call this function.\n * @param _guardian Guardian address to be added\n */\n function confirmGuardianAddition(address _guardian) public override {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingAddition();\n if (gs.pending[id] >= block.timestamp)\n revert GuardianFacet__PendingAdditionNotOver();\n if (block.timestamp >= gs.pending[id] + getSecurityWindow())\n revert GuardianFacet__PendingAdditionExpired();\n\n _addGuardian(_guardian);\n\n delete gs.pending[id];\n emit GuardianAdded(_guardian);\n }\n\n /**\n * @notice Confirm removal of guardians\n * @dev This method internally calls confirmGuardianRemoval to check the validity guardian removal confirmation.\n * Guardians are fully removed when they pass the validation. Anyone can call this function.\n * @param _guardians Array of guardian addresses to be removed\n */\n function confirmGuardianRemovals(\n address[] calldata _guardians\n ) external override {\n for (uint256 i; i < _guardians.length; ) {\n confirmGuardianRemoval(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Confirm removal of a guardian\n * @dev This method checks the validity guardian removal confirmation.\n * Guardian is fully removed when they pass the validation. Anyone can call this function.\n * @param _guardian Guardian address to be removed\n */\n function confirmGuardianRemoval(address _guardian) public override {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingRemoval();\n if (gs.pending[id] >= block.timestamp)\n revert GuardianFacet__PendingRemovalNotOver();\n if (block.timestamp >= gs.pending[id] + getSecurityWindow())\n revert GuardianFacet__PendingAdditionExpired();\n\n _removeGuardian(_guardian);\n delete gs.pending[id];\n emit GuardianRemoved(_guardian);\n }\n\n /**\n * @notice Cancel pending guardian addition\n * @dev This method checks if the previous request for guardian request exists.\n * It reverts if previous request is not pending and cancels the addition otherwise.\n * @param _guardian Guardian address to be canceled from addition\n */\n function cancelGuardianAddition(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingAddition();\n delete gs.pending[id];\n emit GuardianAdditionCancelled(_guardian);\n }\n\n /**\n * @notice Cancel pending guardian removal\n * @dev This method checks if the previous request for guardian request exists.\n * It reverts if previous request is not pending and cancels the removal otherwise.\n * @param _guardian Guardian address to be canceled from removal\n */\n function cancelGuardianRemoval(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingRemoval();\n delete gs.pending[id];\n emit GuardianRemovalCancelled(_guardian);\n }\n\n /**\n * @notice Get the addition security period of current account from security manager\n * @dev This method returns the uint value if addition security period\n * @return additionSecurityPeriod Uint256 value of addition security period\n */\n function getAdditionSecurityPeriod()\n public\n view\n override\n returns (uint256 additionSecurityPeriod)\n {\n additionSecurityPeriod = securityManager.additionSecurityPeriodOf(\n address(this)\n );\n if (additionSecurityPeriod == 0)\n revert GuardianFacet__InvalidAdditionSecurityPeriod();\n }\n\n /**\n * @notice Get the removal security period of current account from security manager\n * @dev This method returns the uint value if removal security period\n * @return removalSecurityPeriod Uint256 value of removal security period\n */\n function getRemovalSecurityPeriod()\n public\n view\n override\n returns (uint256 removalSecurityPeriod)\n {\n removalSecurityPeriod = securityManager.removalSecurityPeriodOf(\n address(this)\n );\n if (removalSecurityPeriod == 0)\n revert GuardianFacet__InvalidRemovalSecurityPeriod();\n }\n\n /**\n * @notice Get the security window of current account from security manager\n * @dev This method returns the uint value if security window\n * @return securityWindow Uint256 value of removal security period\n */\n function getSecurityWindow()\n public\n view\n override\n returns (uint256 securityWindow)\n {\n securityWindow = securityManager.securityWindowOf(address(this));\n if (securityWindow == 0) revert GuardianFacet__InvalidSecurityWindow();\n }\n\n /**\n * @notice Checks if the addition of the given guardian address is pending\n * @dev This method returns the bool value of whether the guardian address is pending addition\n * @return isPending Bool value of representing the pending of guardian addition\n */\n function isAdditionPending(\n address _guardian\n ) public view override returns (bool isPending) {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n isPending = _isPending(id);\n }\n\n /**\n * @notice Checks if the removal of the given guardian address is pending\n * @dev This method returns the bool value of whether the guardian address is pending removal\n * @return isPending Bool value of representing the pending of guardian removal\n */\n function isRemovalPending(\n address _guardian\n ) public view override returns (bool isPending) {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n isPending = _isPending(id);\n }\n\n /**\n * @notice Checks if the given hash is pending\n * @dev This method returns the bool value whether the hash is pending\n * @return isPending Bool value of representing the pending of guardian operation\n */\n function _isPending(\n bytes32 _idHash\n ) internal view returns (bool isPending) {\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n isPending = ((gs.pending[_idHash] > 0 &&\n gs.pending[_idHash] < block.timestamp) &&\n block.timestamp < gs.pending[_idHash] + getSecurityWindow());\n }\n\n /**\n * @notice Adds guardian to storage config. This is called when guardian is fully added.\n * @dev This method add guardian address and config information to Facet Storage dedicated for guardian\n * When this function is called, guardian is fully added to this Barz Smart Account\n * @param _guardian Address of guardian to be added\n */\n function _addGuardian(address _guardian) internal {\n if (!isAdditionPending(_guardian))\n revert GuardianFacet__InvalidGuardianAddition();\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n if (config.info[_guardian].exists)\n revert GuardianFacet__AlreadyExists();\n\n config.info[_guardian].exists = true;\n config.info[_guardian].index = uint128(config.addresses.length);\n config.addresses.push(_guardian);\n }\n\n /**\n * @notice Removes guardian to storage config. This is called when guardian is fully removed.\n * @dev This method remove guardian address and config information to Facet Storage dedicated for guardian\n * When this function is called, guardian is fully removed from this Barz Smart Account\n * @param _guardian Address of guardian to be removed\n */\n function _removeGuardian(address _guardian) internal {\n if (!isRemovalPending(_guardian))\n revert GuardianFacet__InvalidGuardianRemoval();\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n if (!config.info[_guardian].exists)\n revert GuardianFacet__NonExistentGuardian();\n\n address lastAddress = config.addresses[config.addresses.length - 1];\n if (_guardian != lastAddress) {\n uint128 targetIndex = config.info[_guardian].index;\n config.addresses[targetIndex] = lastAddress;\n config.info[lastAddress].index = targetIndex;\n }\n config.addresses.pop();\n delete config.info[_guardian];\n\n emit GuardianRemoved(_guardian);\n }\n\n /**\n * @notice Reads guardian storage and fetches the addresses into an array from the storage\n * @dev This method fetches the guardian storage and returns the list of guardian addresses\n * @return addresses Array of addresses comprised of guardian\n */\n function getGuardians()\n public\n view\n override\n returns (address[] memory addresses)\n {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n uint256 addressesLen = config.addresses.length;\n addresses = new address[](addressesLen);\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the number of majority of guardians\n * @return majorityOfGuardians_ Number of majority of guardians e.g., 2 if 3 guardians / 3 if 5 guardians\n */\n function majorityOfGuardians()\n public\n view\n override\n returns (uint256 majorityOfGuardians_)\n {\n majorityOfGuardians_ = LibGuardian.majorityOfGuardians();\n }\n\n /**\n * @notice Reads guardian storage and fetches the addresses into an array from the storage\n * @dev This method fetches the guardian storage and returns the list of guardian addresses\n * @return guardianNumber Array of guardians in the account\n */\n function guardianCount()\n public\n view\n override\n returns (uint256 guardianNumber)\n {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n guardianNumber = config.addresses.length;\n }\n\n /**\n * @notice Reads guardian storage and checks if the given address is a guardian\n * @return isGuardian_ Bool value representing if the given address is guardian\n */\n function isGuardian(\n address _guardian\n ) public view override returns (bool isGuardian_) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n isGuardian_ = config.info[_guardian].exists;\n }\n\n /**\n * @notice Checks if the guardian number is zero and returns of guardian facet is okay to be removed\n * @return isRemovable Bool value representing if guardian facet is removable\n */\n function isGuardianFacetRemovable()\n external\n view\n override\n returns (bool isRemovable)\n {\n isRemovable = (0 == guardianCount());\n }\n}\n" + }, + "contracts/facets/interfaces/IAccountFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IEntryPoint} from \"../../aa-4337/interfaces/IEntryPoint.sol\";\n\n/**\n * @title Account Facet Interface\n * @dev Interface of module contract that provides the account features and init/unitialization of signer\n * compatible with EIP-1271 & EIP-4337\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IAccountFacet {\n event AccountInitialized(\n IEntryPoint indexed entryPoint,\n bytes indexed ownerPublicKey\n );\n // NOTE: Added Below Event\n event VerificationSuccess(bytes32);\n event VerificationFailure(bytes32);\n\n error AccountFacet__InitializationFailure();\n error AccountFacet__RestrictionsFailure();\n error AccountFacet__NonExistentVerificationFacet();\n error AccountFacet__CallNotSuccessful();\n error AccountFacet__InvalidArrayLength();\n\n function initialize(\n address verificationFacet,\n address anEntryPoint,\n address facetRegistry,\n address _defaultFallBack,\n bytes calldata _ownerPublicKey\n ) external returns (uint256);\n\n function execute(address dest, uint256 value, bytes calldata func) external;\n\n function executeBatch(\n address[] calldata dest,\n uint256[] calldata value,\n bytes[] calldata func\n ) external;\n}\n" + }, + "contracts/facets/interfaces/IAccountRecoveryFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {RecoveryConfig} from \"../../libraries/LibFacetStorage.sol\";\n\n/**\n * @title Account Recovery Facet Interface\n * @dev Interface of contract that enables recovery of accounts when owner key is unavailable\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IAccountRecoveryFacet {\n event RecoveryExecuted(\n bytes indexed recoveryPublicKey,\n uint64 executeAfter\n );\n event RecoveryFinalized(bytes indexed recoveryPublicKey);\n event RecoveryCanceled(bytes indexed recoveryPublicKey);\n event RecoveryApproved(\n bytes indexed recoveryPublicKey,\n address indexed guardian,\n uint64 validUntil\n );\n event RecoveryApprovalRevoked(\n bytes indexed recoveryPublicKey,\n address indexed guardian\n );\n event RecoveryCancellationApproved(\n bytes indexed recoveryPublicKey,\n address indexed guardian\n );\n event RecoveryHardstopped();\n\n error AccountRecoveryFacet__CallerNotGuardian();\n error AccountRecoveryFacet__InvalidRecoveryPublicKey();\n error AccountRecoveryFacet__SignerInitializationFailure();\n error AccountRecoveryFacet__SignerUninitializationFailure();\n error AccountRecoveryFacet__InvalidArrayLength();\n error AccountRecoveryFacet__InsufficientGuardians();\n error AccountRecoveryFacet__RecoveryAlreadyOngoing();\n error AccountRecoveryFacet__NonexistentRecovery();\n error AccountRecoveryFacet__NonExistentApproval();\n error AccountRecoveryFacet__RecoveryPeriodNotOver();\n error AccountRecoveryFacet__InvalidLockPeriod();\n error AccountRecoveryFacet__InvalidRecoveryPeriod();\n error AccountRecoveryFacet__InvalidApprovalValidationPeriod();\n error AccountRecoveryFacet__InvalidGuardian();\n error AccountRecoveryFacet__InvalidGuardianSignature();\n error AccountRecoveryFacet__InvalidOwnerSignature();\n error AccountRecoveryFacet__CallNotSuccesful();\n error AccountRecoveryFacet__DuplicateApproval();\n\n function approveAccountRecovery(bytes calldata recoveryPublicKey) external;\n\n function revokeAccountRecoveryApproval(\n bytes calldata recoveryPublicKey\n ) external;\n\n function executeRecovery(\n bytes calldata recoveryPublicKey,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function finalizeRecovery() external;\n\n function approveCancelRecovery(bytes calldata recoveryPublicKey) external;\n\n function cancelRecovery(\n bytes calldata recoveryPublicKey,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function hardstopRecovery(bytes calldata signature) external;\n\n function getApprovalRecoveryKeyHash(\n bytes memory recoveryPublicKey,\n string memory saltString\n ) external view returns (bytes32);\n\n function getRecoveryApprovalCountWithTimeValidity(\n bytes32 recoveryPublicKeyHash\n ) external view returns (uint256);\n\n function isRecoveryApproved(\n bytes32 recoveryPublicKeyHash,\n address approver\n ) external view returns (bool);\n\n function getRecoveryNonce() external view returns (uint128);\n\n function getPendingRecovery() external view returns (RecoveryConfig memory);\n}\n" + }, + "contracts/facets/interfaces/IGuardianFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Guardian Facet Interface\n * @dev Interface of guaridna contract that enables addition/removal of guardians from Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IGuardianFacet {\n event GuardianAdditionRequested(\n address indexed guardian,\n uint256 executeAfter\n );\n event GuardianRemovalRequested(\n address indexed guardian,\n uint256 executeAfter\n );\n event GuardianAdditionCancelled(address indexed guardian);\n event GuardianRemovalCancelled(address indexed guardian);\n event GuardianAdded(address indexed guardian);\n event GuardianRemoved(address indexed guardian);\n\n error GuardianFacet__GuardianCannotBeSelf();\n error GuardianFacet__DuplicateGuardian();\n error GuardianFacet__OwnerCannotBeGuardian();\n error GuardianFacet__DuplicateGuardianAddition();\n error GuardianFacet__DuplicateGuardianRemoval();\n error GuardianFacet__UnknownPendingAddition();\n error GuardianFacet__PendingAdditionNotOver();\n error GuardianFacet__UnknownPendingRemoval();\n error GuardianFacet__PendingRemovalNotOver();\n error GuardianFacet__PendingAdditionExpired();\n error GuardianFacet__InvalidAdditionSecurityPeriod();\n error GuardianFacet__InvalidRemovalSecurityPeriod();\n error GuardianFacet__InvalidSecurityWindow();\n error GuardianFacet__NonExistentGuardian();\n error GuardianFacet__AlreadyExists();\n error GuardianFacet__InvalidGuardianAddition();\n error GuardianFacet__InvalidGuardianRemoval();\n error GuardianFacet__ZeroAddressGuardian();\n\n function addGuardian(address guardian) external;\n\n function addGuardians(address[] calldata guardians) external;\n\n function removeGuardian(address guardian) external;\n\n function removeGuardians(address[] calldata guardians) external;\n\n function confirmGuardianAddition(address guardian) external;\n\n function confirmGuardianAdditions(address[] calldata guardian) external;\n\n function confirmGuardianRemoval(address guardian) external;\n\n function confirmGuardianRemovals(address[] calldata guardian) external;\n\n function cancelGuardianAddition(address guardian) external;\n\n function cancelGuardianRemoval(address guardian) external;\n\n function isGuardian(address guardian) external view returns (bool);\n\n function isAdditionPending(address guardian) external view returns (bool);\n\n function isRemovalPending(address guardian) external view returns (bool);\n\n function isGuardianFacetRemovable() external view returns (bool);\n\n function getAdditionSecurityPeriod() external view returns (uint256);\n\n function getRemovalSecurityPeriod() external view returns (uint256);\n\n function getSecurityWindow() external view returns (uint256);\n\n function getGuardians() external view returns (address[] memory);\n\n function majorityOfGuardians() external view returns (uint256);\n\n function guardianCount() external view returns (uint256);\n}\n" + }, + "contracts/facets/interfaces/ILockFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Lock} from \"../../libraries/LibAppStorage.sol\";\n\n/**\n * @title Lock Facet Interface\n * @dev Interface of Lock contract that enables full lock/unlock of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface ILockFacet {\n event Locked(uint64 releaseAfter);\n event Unlocked();\n\n error LockFacet__InvalidRecoveryPeriod();\n error LockFacet__CannotUnlock();\n error LockFacet__InvalidSignature();\n error LockFacet__InvalidApprover();\n\n function lock() external;\n\n function unlock(address approver, bytes calldata signature) external;\n\n function getLockPeriod() external view returns (uint256);\n\n function isLocked() external view returns (bool);\n\n function getUnlockHash() external view returns (bytes32);\n\n function lockNonce() external view returns (uint128);\n\n function getPendingLock() external view returns (Lock memory);\n}\n" + }, + "contracts/facets/interfaces/IMultiSigFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Multi-sig facet Interface\n * @dev Interface of Multi-signature Facet with custom threshold.\n Wallet that adds this facet becomes a multi-sig wallet\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IMultiSigFacet {\n event ThresholdChanged(uint256 threshold);\n event OwnerAdded(address indexed newOwner);\n event OwnerRemoved(address indexed prevOwner);\n event HashApproved(bytes32 hashToApprove, address indexed owner);\n\n error MultiSigFacet__InvalidThreshold();\n error MultisigFacet__InvalidOwnerCount();\n error MultiSigFacet__InvalidRoute();\n error MultiSigFacet__InsufficientSignerLength();\n error MultiSigFacet__InvalidInitData();\n error MultiSigFacet__InvalidOwnerAddress();\n error MultiSigFacet__InvalidOwnerPair();\n error MultiSigFacet__InvalidSignatureLength();\n error MultiSigFacet__InvalidSignatureType();\n error MultiSigFacet__DuplicateOwner();\n error MultiSigFacet__OnlyOwner();\n\n function checkSignatures(\n bytes32 _dataHash,\n bytes calldata _signatures,\n uint256 _threshold\n ) external view returns (uint256);\n\n function splitSignatures(\n bytes calldata _signatures,\n uint256 _nextOffset\n )\n external\n pure\n returns (\n address owner,\n bytes memory signature,\n uint256 signatureType,\n uint256 nextOffset\n );\n\n function approveHash(bytes32 hashToApprove) external;\n\n function addOwner(address newOwner, uint256 threshold) external;\n\n function removeOwner(\n address prevOwner,\n address removedOwner,\n uint256 threshold\n ) external;\n\n function swapOwner(\n address prevOwner,\n address oldOwner,\n address newOwner\n ) external;\n\n function changeThreshold(uint256 _threshold) external;\n\n function isOwner(address owner) external view returns (bool);\n\n function getThreshold() external view returns (uint256);\n\n function getOwners() external view returns (address[] memory);\n}\n" + }, + "contracts/facets/interfaces/IRestrictionsFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Restrictions Facet Interface\n * @dev Interface of Restrictions contract that enables modular restrictions in Barz\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IRestrictionsFacet {\n event RestrictionAdded(address indexed restriction);\n event RestrictionRemoved(address indexed restriction);\n\n error RestrictionsFacet__EmptyRestrictionsList();\n error RestrictionsFacet__RestrictionNotFound();\n error RestrictionsFacet__RestrictionAlreadyExists();\n error RestrictionsFacet__ZeroAddressRestrictions();\n error RestrictionsFacet__ZeroAddressRestrictionsFacet();\n error RestrictionsFacet__RemainingRestrictionsCantBeEmpty();\n\n function initializeRestrictions(\n address[] memory _restrictions\n ) external returns (uint256);\n\n function uninitializeRestrictions() external returns (uint256);\n\n function getRestrictions() external view returns (address[] memory);\n\n function addRestriction(address restriction) external;\n\n function removeRestriction(address restriction) external;\n\n function verifyRestrictions(\n address from,\n address to,\n uint256 value,\n bytes calldata _calldata\n ) external returns (uint256);\n}\n" + }, + "contracts/facets/interfaces/ISignatureMigrationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureMigrationConfig} from \"../../libraries/LibFacetStorage.sol\";\n\n/**\n * @title Signature Migration Facet Interface\n * @dev Interface of Signature Migration contract for migrating user signature scheme to a new scheme user sets\n * Which could include\n * - ECDSA on Secp256K1 Curve\n * - ECDSA on Secp256R1 Curve\n * - BLS, Schnorr, etc\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface ISignatureMigrationFacet {\n event SignatureSchemeMigration(\n address indexed prevVerificationFacet,\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n event SignatureMigrationApproved(\n bytes newPublicKey,\n address indexed newVerificationFacet,\n bytes4[] verificationFuncSelectors,\n address indexed guardian,\n uint128 approvalValidUntil\n );\n event SignatureMigrationApprovalRevoked(\n bytes newPublicKey,\n address indexed newVerificationFacet,\n bytes4[] verificationFuncSelectors,\n address indexed guardian\n );\n event SignatureMigrationExecuted(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors,\n uint128 migrateAfter\n );\n event SignatureMigrationCanceled(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n event SignatureMigrationCancellationApproved(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n\n error SignatureMigrationFacet__SignerUninitializationFailure();\n error SignatureMigrationFacet__SignerInitializationFailure();\n error SignatureMigrationFacet__InvalidRouteWithGuardian();\n error SignatureMigrationFacet__InvalidKeyType();\n error SignatureMigrationFacet__InsufficientApprovers();\n error SignatureMigrationFacet__InvalidApproverSignature();\n error SignatureMigrationFacet__InvalidGuardian();\n error SignatureMigrationFacet__NonExistentApprover();\n error SignatureMigrationFacet__InvalidMigrationPeriod();\n error SignatureMigrationFacet__NonexistentMigration();\n error SignatureMigrationFacet__MigrationPeriodNotOver();\n error SignatureMigrationFacet__InvalidArrayLength();\n error SignatureMigrationFacet__InvalidApprovalValidationPeriod();\n error SignatureMigrationFacet__CannotRevokeUnapproved();\n error SignatureMigrationFacet__LackOfOwnerApproval();\n error SignatureMigrationFacet__OwnerAlreadyApproved();\n error SignatureMigrationFacet__NonExistentVerificationFacet();\n error SignatureMigrationFacet__DuplicateApproval();\n\n function migrateSignatureScheme(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function migrateSignatureSchemeWithGuardian(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors,\n address[] calldata approvers,\n bytes[] calldata signatures\n ) external;\n\n function approveSignatureSchemeMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function revokeSignatureMigrationApproval(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function finalizeSignatureMigration() external;\n\n function approveCancelSignatureMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function cancelSignatureMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function getApprovalMigrationKeyHash(\n bytes memory recoveryPublicKey,\n address newVerificationFacet,\n bytes4[] memory newVerificationFuncSelectors,\n string memory saltString\n ) external view returns (bytes32);\n\n function getMigrationOwnerApprovalWithTimeValidity(\n bytes32 publicKeyHash\n ) external view returns (bool);\n\n function getMigrationApprovalCountWithTimeValidity(\n bytes32 publicKeyHash\n ) external view returns (uint256);\n\n function isMigrationApproved(\n bytes32 migrationPublicKeyHash,\n address approver\n ) external view returns (bool);\n\n function getMigrationNonce() external view returns (uint128);\n\n function isMigrationPending() external view returns (bool);\n\n function getPendingMigration()\n external\n view\n returns (SignatureMigrationConfig memory);\n}\n" + }, + "contracts/facets/interfaces/IVerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {UserOperation} from \"../../aa-4337/interfaces/UserOperation.sol\";\n\n/**\n * @title Verification Facet Interface\n * @dev Implements logic for user ops signature verification\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface IVerificationFacet {\n event SignerInitialized(bytes);\n event SignerUninitialized();\n\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n error VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n error VerificationFacet__InitializationFailure();\n error VerificationFacet__InvalidFacetMapping();\n\n function initializeSigner(bytes memory) external returns (uint256);\n\n function uninitializeSigner() external returns (uint256);\n\n function validateOwnerSignatureSelector() external view returns (bytes4);\n\n function owner() external view returns (bytes memory);\n\n function isValidKeyType(bytes calldata) external view returns (bool);\n\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) external view returns (uint256);\n}\n" + }, + "contracts/facets/LockFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage, Lock} from \"../libraries/LibAppStorage.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibFacetStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {ILockFacet} from \"./interfaces/ILockFacet.sol\";\n\n/**\n * @title Lock Facet\n * @dev Contract that enables full lock/unlock of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract LockFacet is ILockFacet, Modifiers {\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Locks the account for the lock period. Lock period is defined in the security manager and it's customizable\n * This function can only be called when account is unlocked by owner or guardians\n * @dev This method checks the caller and if the account is currently locked and locks the account after fetching the\n * Lock period from the owner.\n */\n function lock() external override onlyGuardianOrOwner onlyWhenUnlocked {\n uint256 unlockTime = block.timestamp + getLockPeriod();\n unchecked {\n ++LibFacetStorage.lockStorage().nonce;\n }\n LibAppStorage.setLock(unlockTime, LockFacet.lock.selector);\n emit Locked(uint64(unlockTime));\n }\n\n /**\n * @notice Locks the account when the account is locked. This function can be called by anyone but must provide the approver address and signature.\n * The approver should be one of the guardians or owner.\n * @dev This method takes the approver address and the signature. After validating the address and the signature, it unlocks the account immediately.\n * Only one of the guardian or owner is required to lock and unlock the account.\n * @param _approver Address of approver approving the unlock of Barz account\n * @param _signature Signature of the approver that signed the msg hash for unlocking the account\n */\n function unlock(\n address _approver,\n bytes calldata _signature\n ) external override onlyWhenLocked {\n if (_approver != address(this) && !LibGuardian.isGuardian(_approver))\n revert LockFacet__InvalidApprover();\n if (\n !SignatureChecker.isValidSignatureNow(\n _approver,\n getUnlockHash(),\n _signature\n )\n ) revert LockFacet__InvalidSignature();\n _unlock();\n }\n\n /**\n * @notice Unlocks the account and increments the lock nonce\n */\n function _unlock() private {\n if (s.locks[INNER_STRUCT].locker != LockFacet.lock.selector)\n revert LockFacet__CannotUnlock();\n unchecked {\n ++LibFacetStorage.lockStorage().nonce;\n }\n LibAppStorage.setLock(0, bytes4(0));\n emit Unlocked();\n }\n\n /**\n * @notice Returns the lock period of current Barz account. Lock period information is held by Security Manager\n * @return lockPeriod Uint value of lock period in seconds\n */\n function getLockPeriod() public view override returns (uint256 lockPeriod) {\n lockPeriod = securityManager.lockPeriodOf(address(this));\n if (lockPeriod == 0) revert LockFacet__InvalidRecoveryPeriod();\n }\n\n /**\n * @notice Returns if the account is locked or not\n * @dev This method fetches the current block timestamp and compares that with release time.\n * After checking the timestamp and release time, it returns if the account is still locked or not.\n * @return isLocked_ Uint value of lock period in seconds\n */\n function isLocked() public view override returns (bool isLocked_) {\n isLocked_ = uint64(block.timestamp) < s.locks[INNER_STRUCT].release;\n }\n\n /**\n * @notice Calculates the unlock hash and returns the unlock hash safe from signature reply attack\n * @dev This method calculates the unlock hash with EIP-191 prefix, wallet address, chainID, and nonce\n * It packs the result and packs them and hashes it.\n * @return unlockHash Bytes32 unlock hash\n */\n function getUnlockHash() public view override returns (bytes32 unlockHash) {\n unlockHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n \"Unlock\",\n address(this),\n block.chainid,\n lockNonce()\n )\n )\n )\n );\n }\n\n /**\n * @notice Returns lock nonce of account. Reads nonce from lock storage within facet storage\n * @return lockNonce_ Uint128 value of lock nonce. This is incremented whenever the account is lock/unlocked\n */\n function lockNonce() public view override returns (uint128 lockNonce_) {\n lockNonce_ = LibFacetStorage.lockStorage().nonce;\n }\n\n /**\n * @notice Returns the overall information of current lock\n * @return pendingLock Struct value including all information of pending lock\n */\n function getPendingLock()\n public\n view\n override\n returns (Lock memory pendingLock)\n {\n pendingLock = s.locks[INNER_STRUCT];\n }\n}\n" + }, + "contracts/facets/Modifiers.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\n\n/**\n * @title Modifiers\n * @dev Responsible for providing modifiers/util functions to Facet contracts\n * @author David Yongjun Kim (@Powerstream3604)\n */\nabstract contract Modifiers is BarzStorage {\n uint8 constant INNER_STRUCT = 0;\n\n error CallerNotGuardian();\n error CallerNotGuardianOrOwner();\n error DuplicateApprover();\n error ZeroApproverLength();\n error UnregisteredFacetAndSelectors();\n\n /**\n * @notice Modifier to only allow guardian to make a call, reverts if any other entity is the caller\n */\n modifier onlyGuardian() {\n if (!LibGuardian.isGuardian(msg.sender)) revert CallerNotGuardian();\n _;\n }\n\n /**\n * @notice Modifier to only allow guardian or owner to make a call, reverts if any other entity is the caller\n */\n modifier onlyGuardianOrOwner() {\n if (!LibGuardian.isGuardian(msg.sender) && address(this) != msg.sender)\n revert CallerNotGuardianOrOwner();\n _;\n }\n\n /**\n * @notice Checks if the approver address is the array is unique with no duplicate\n * @dev This method loops through the array and checks if a duplicate address exists, it reverts if duplicate address exists\n * @param approvers Array of address\n */\n function _checkApprover(\n address[] memory approvers\n ) internal pure returns (bool) {\n uint256 approverLength = approvers.length;\n if (0 == approverLength) revert ZeroApproverLength();\n for (uint256 i; i < approverLength - 1; ) {\n for (uint256 j = i + 1; j < approverLength; ) {\n if (approvers[i] == approvers[j]) {\n revert DuplicateApprover(); // Found a duplicate\n }\n unchecked {\n ++j;\n }\n }\n unchecked {\n ++i;\n }\n }\n return false; // No duplicates found\n }\n\n /**\n * @notice Checks if the facet getting added or replaced is registered to facet registry\n * @dev This method loops through the cut and checks if the facet getting added/replaced is registered to facet registry\n * @param _diamondCut Array of FacetCut, data for diamondCut defined in EIP-2535\n */\n function _checkFacetCutValidity(\n IDiamondCut.FacetCut[] memory _diamondCut\n ) internal view {\n uint256 diamondCutLength = _diamondCut.length;\n for (uint256 i; i < diamondCutLength; ) {\n if (\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Add ||\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Replace\n ) {\n if (\n !s.facetRegistry.areFacetFunctionSelectorsRegistered(\n _diamondCut[i].facetAddress,\n _diamondCut[i].functionSelectors\n )\n ) revert UnregisteredFacetAndSelectors();\n }\n unchecked {\n ++i;\n }\n }\n }\n}\n" + }, + "contracts/facets/RestrictionsFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ReentrancyGuard} from \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, RestrictionsStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {IRestriction} from \"../restrictions/IRestriction.sol\";\nimport {IRestrictionsFacet} from \"./interfaces/IRestrictionsFacet.sol\";\n\n/**\n * @title Restrictions facet\n * @dev Responsible for storing and verifying different kinds of restrictions, for example:\n * - Whitelist / Blacklist\n * - Daily limits\n * - Trading time restrictions\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract RestrictionsFacet is IRestrictionsFacet, ReentrancyGuard {\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceRestrictionsInitialize();\n }\n\n /**\n * @notice Intialize restrictions of Barz. Restrictions facet call restriction contracts for restriction validation\n * before each call\n * @param _restrictions The initial array of restrictions.\n * @return initSuccess Int value showing if the initialization of restriction is successful\n */\n function initializeRestrictions(\n address[] calldata _restrictions\n ) public override returns (uint256 initSuccess) {\n LibDiamond.enforceIsSelf();\n LibAppStorage.enforceRestrictionsInitialize();\n\n if (_restrictions.length == 0) {\n // You can't initialize RestrictionsFacet with an empty list of restrictions\n revert RestrictionsFacet__EmptyRestrictionsList();\n }\n for (uint256 i; i < _restrictions.length; ) {\n if (_restrictions[i] == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictions();\n unchecked {\n ++i;\n }\n }\n\n LibFacetStorage.restrictionsStorage().restrictions = _restrictions;\n _updateRestrictionsMap(_restrictions, true);\n initSuccess = 1;\n }\n\n /**\n * @notice Unitialize restrictions of Barz\n * @return uninitSuccess Int value showing if the initialization of restriction is successful\n */\n function uninitializeRestrictions()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibDiamond.enforceIsSelf();\n LibAppStorage.setRestrictionsUninitialized();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n _updateRestrictionsMap(restrictionsStorage.restrictions, false);\n restrictionsStorage.restrictions = new address[](0);\n uninitSuccess = 1;\n }\n\n /**\n * @notice Returns the list of Restrictions contract address\n * @return restrictions Addresses of IRestriction which are currently active\n */\n function getRestrictions()\n public\n view\n override\n returns (address[] memory restrictions)\n {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n restrictions = restrictionsStorage.restrictions;\n }\n\n /**\n * @notice Adds restrictions to Barz with validation on the restriction contract address.\n * This method is only callable by the owner(self).\n * @param _restriction The address of the restriction to be added.\n */\n function addRestriction(address _restriction) external override {\n LibDiamond.enforceIsSelf();\n if (LibDiamond.restrictionsFacet() == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictionsFacet();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n if (_restriction == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictions();\n if (restrictionsStorage.exists[_restriction])\n revert RestrictionsFacet__RestrictionAlreadyExists();\n\n restrictionsStorage.restrictions.push(_restriction);\n restrictionsStorage.exists[_restriction] = true;\n\n emit RestrictionAdded(_restriction);\n }\n\n /**\n * @notice Remove restrictions from Barz if it existed. This method is only callable by the owner(self).\n * @param _restriction The address of the restriction to be removed.\n */\n function removeRestriction(address _restriction) external override {\n LibDiamond.enforceIsSelf();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n if (!restrictionsStorage.exists[_restriction])\n revert RestrictionsFacet__RestrictionNotFound();\n\n address[] storage restrictions = restrictionsStorage.restrictions;\n\n uint256 indexToDelete = restrictions.length;\n uint256 restrictionsLen = restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n if (restrictions[i] == _restriction) {\n indexToDelete = i;\n break;\n }\n unchecked {\n ++i;\n }\n }\n\n if (indexToDelete == 0 && restrictionsLen == 1) {\n revert RestrictionsFacet__RemainingRestrictionsCantBeEmpty();\n } else if (indexToDelete == restrictionsLen) {\n revert RestrictionsFacet__RestrictionNotFound();\n } else {\n restrictions[indexToDelete] = restrictions[restrictionsLen - 1];\n restrictions.pop();\n }\n\n restrictionsStorage.exists[_restriction] = false;\n emit RestrictionRemoved(_restriction);\n }\n\n /**\n * @notice Sets the restrictions address value mapping to true or false when adding/removing restriction contracts\n * @param _restrictions List of restriction contracts address\n * @param _newValue Bool value to flag to the list of restrictions contracts\n */\n function _updateRestrictionsMap(\n address[] memory _restrictions,\n bool _newValue\n ) internal {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n uint restrictionsLen = _restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n restrictionsStorage.exists[_restrictions[i]] = _newValue;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @dev Iterates over all restrictions and verifies each of them with the transaction parameters.\n * @param _from The address of the sender, that will be signing the transaction.\n * @param _to The receiving address.\n * @param _value Amount of ETH to transfer from sender to recipient.\n * @param _calldata Optional field to include arbitrary data.\n * @return 0 if all the checks passed, 1 otherwise.\n */\n function verifyRestrictions(\n address _from,\n address _to,\n uint256 _value,\n bytes calldata _calldata\n ) external nonReentrant returns (uint256) {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n uint restrictionsLen = restrictionsStorage.restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n IRestriction restriction = IRestriction(\n restrictionsStorage.restrictions[i]\n );\n bool checkPassed = restriction.check(_from, _to, _value, _calldata);\n if (!checkPassed) {\n return 1;\n }\n unchecked {\n ++i;\n }\n }\n\n return 0;\n }\n}\n" + }, + "contracts/facets/SignatureMigrationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, SignatureMigrationStorage, SignatureMigrationConfig, SignatureMigrationApprovalConfig, ApprovalConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IDiamondCut} from \"./base/interfaces/IDiamondCut.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {ISignatureMigrationFacet} from \"./interfaces/ISignatureMigrationFacet.sol\";\n\n/**\n * @title Signature Migration Facet\n * @dev Responsible for migrating user signature scheme to a new scheme user sets\n * Which could include\n * - ECDSA on Secp256K1 Curve\n * - ECDSA on Secp256R1 Curve\n * - BLS, Schnorr, etc\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract SignatureMigrationFacet is ISignatureMigrationFacet, Modifiers {\n bytes constant UNINIT_CALL =\n abi.encodeWithSignature(\"uninitializeSigner()\");\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This modifier verifies if the public key format matches with the new verification facet\n * @param _publicKey Bytes of public key to be validated for the new verification facet\n * @param _newVerificationFacet Address of new verification facet\n */\n modifier validateKeyType(\n bytes memory _publicKey,\n address _newVerificationFacet\n ) {\n if (\n !IVerificationFacet(_newVerificationFacet).isValidKeyType(\n _publicKey\n )\n ) revert SignatureMigrationFacet__InvalidKeyType();\n _;\n }\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n // IMPORTANT NOTE: In the client side when they call this function, the func selectors should be sorted in ascending order\n // to prevent different hash with same items in the array\n /**\n * @notice Moves the state of migration to a pending state. When pending state is over after pending period time,\n * Migration can be finalized. This function can only be called by self and when the account is unlocked.\n * @dev This method checks if the caller is self and if guardians exists. It migrates signature request to a pending state\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function migrateSignatureScheme(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n public\n override\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n // Only self contract can call this function\n LibDiamond.enforceIsSelf();\n // Should revert if guardian exist\n if (0 != LibGuardian.guardianCount())\n revert SignatureMigrationFacet__InvalidRouteWithGuardian();\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n // NOTE: Migration requires a pending period & confirmation from owner to prevent a\n // single call changing the ownership of the wallet\n /**\n * @notice Migrate signature scheme when guardians exists. Verifies the signature of guardians and moves migration to pending state.\n * Which can then be finalized when pending period is over. Owner's approval is mandatory for migration to happen\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _approvers List of approvers. This could include owner\n */\n function migrateSignatureSchemeWithGuardian(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n )\n public\n override\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n // Should revert if does not guardian exist\n if (0 == LibGuardian.guardianCount())\n revert SignatureMigrationFacet__InvalidRouteWithGuardian();\n if (_approvers.length != _signatures.length)\n revert SignatureMigrationFacet__InvalidArrayLength();\n\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(migrationPublicKeyHash, _approvers);\n\n bool onChainOwnerApproval = getMigrationOwnerApprovalWithTimeValidity(\n migrationPublicKeyHash\n );\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n\n if (\n _approvers.length +\n getMigrationApprovalCountWithTimeValidity(\n migrationPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert SignatureMigrationFacet__InsufficientApprovers();\n {\n // To prevent Stack too deep\n bool ownerApproved;\n for (uint256 i; i < _approvers.length; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n address(this) != _approvers[i]\n ) revert SignatureMigrationFacet__InvalidGuardian();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert SignatureMigrationFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n migrationPublicKeyHash,\n _signatures[i]\n )\n ) revert SignatureMigrationFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n\n if (!ownerApproved && !onChainOwnerApproval)\n revert SignatureMigrationFacet__LackOfOwnerApproval();\n }\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Internal function that moves signature mgiration to a pending state.\n * @dev This method increments migration nonce and sets the migration in the migration config. Emits events for migration execution\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _migrateSignatureScheme(\n address _newVerificationFacet,\n bytes memory _newPublicKey,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal {\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n unchecked {\n ++ms.nonce;\n }\n uint64 migrateAfter = uint64(block.timestamp + getMigrationPeriod());\n\n ms.migrationConfigs[INNER_STRUCT] = SignatureMigrationConfig(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n migrateAfter\n );\n\n emit SignatureMigrationExecuted(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors,\n migrateAfter\n );\n }\n\n /**\n * @notice Approves signature scheme migration on-chain. This can be called by owner or guardian only when the account is unlocked.\n * When the threshold of the migration approval passed and owner approval is granted, it automatically moves migration to a pending state\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function approveSignatureSchemeMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n public\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit SignatureMigrationApproved(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n msg.sender,\n approvalValidUntil\n );\n if (\n getMigrationApprovalCountWithTimeValidity(migrationPublicKeyHash) >=\n LibGuardian.majorityOfGuardians() &&\n getMigrationOwnerApprovalWithTimeValidity(migrationPublicKeyHash)\n )\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Revokes the approval of signature migration done on-chain. Emits revoke event when revoked.\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function revokeSignatureMigrationApproval(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n external\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n if (!isMigrationApproved(migrationPublicKeyHash, msg.sender))\n revert SignatureMigrationFacet__CannotRevokeUnapproved();\n\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(false, 0);\n emit SignatureMigrationApprovalRevoked(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n msg.sender\n );\n }\n\n /**\n * @notice Finalizes the pending signature scheme migration. This function can only be called by owner.\n * It removes the facets of the previous verification facet and adds the new verification facet.\n * After finalizing migration, it emits migration event which shows the change of the verification facet\n */\n function finalizeSignatureMigration() external override {\n // NOTE: Only owner can call this function\n LibDiamond.enforceIsSelf();\n\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n\n if (!isMigrationPending())\n revert SignatureMigrationFacet__NonexistentMigration();\n\n if (\n uint64(block.timestamp) <=\n ms.migrationConfigs[INNER_STRUCT].migrateAfter\n ) revert SignatureMigrationFacet__MigrationPeriodNotOver();\n address newVerificationFacet = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationVerificationFacet;\n bytes4[] memory newVerificationFuncSelectors = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationSelectors;\n bytes memory newPublicKey = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationPublicKey;\n\n address prevVerificationFacet = LibLoupe.facetAddress(\n s.validateOwnerSignatureSelector\n );\n if (prevVerificationFacet == address(0))\n revert SignatureMigrationFacet__NonExistentVerificationFacet();\n\n IDiamondCut.FacetCut[] memory UninitCut;\n IDiamondCut.FacetCut[] memory InitCut;\n {\n bytes4[] memory prevVerificationFuncSelectors = LibLoupe\n .facetFunctionSelectors(prevVerificationFacet);\n\n UninitCut = new IDiamondCut.FacetCut[](1);\n InitCut = new IDiamondCut.FacetCut[](1);\n UninitCut[0] = IDiamondCut.FacetCut({\n facetAddress: address(0),\n action: IDiamondCut.FacetCutAction.Remove,\n functionSelectors: prevVerificationFuncSelectors\n });\n InitCut[0] = IDiamondCut.FacetCut({\n facetAddress: newVerificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: newVerificationFuncSelectors\n });\n {\n IDiamondCut.FacetCut[]\n memory facetCuts = new IDiamondCut.FacetCut[](2);\n facetCuts[0] = UninitCut[0];\n facetCuts[1] = InitCut[0];\n _checkFacetCutValidity(facetCuts);\n }\n LibAppStorage.initiateSignerMigration();\n address verificationFacet = address(\n bytes20(\n LibDiamond.diamondStorage().facets[\n s.validateOwnerSignatureSelector\n ]\n )\n );\n\n (bool uninitSuccess, bytes memory uninitResult) = verificationFacet\n .delegatecall(UNINIT_CALL);\n if (!uninitSuccess || uint256(bytes32(uninitResult)) != 1)\n revert SignatureMigrationFacet__SignerUninitializationFailure();\n LibAppStorage.finalizeSignerMigration();\n\n LibDiamond.diamondCut(UninitCut, address(0), \"\");\n }\n {\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n newPublicKey\n );\n\n // Every Verification Facet should comply with initializeSigner(bytes)\n // to be compatible with the Barz contract(for initialization)\n LibDiamond.diamondCut(InitCut, address(0), \"\");\n (bool initSuccess, bytes memory initResult) = newVerificationFacet\n .delegatecall(initCall);\n if (!initSuccess || uint256(bytes32(initResult)) != 1)\n revert SignatureMigrationFacet__SignerInitializationFailure();\n\n emit SignatureSchemeMigration(\n prevVerificationFacet,\n newVerificationFacet,\n newPublicKey,\n newVerificationFuncSelectors\n );\n }\n }\n\n /**\n * @notice Approve cancellation of signature migration. If cancellation approval passes guardian threshold with owner approval\n * it automatically cancels the migration.\n * @dev This method checks if the caller is one of guardian or owner and sets true for the cancellation hash in the approval config.\n * It internally calls _cancelSignatureMigration for canceling the migration\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function approveCancelSignatureMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n external\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"CancelSignatureMigration\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit SignatureMigrationCancellationApproved(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n if (\n getMigrationApprovalCountWithTimeValidity(migrationPublicKeyHash) >=\n LibGuardian.majorityOfGuardians() &&\n getMigrationOwnerApprovalWithTimeValidity(migrationPublicKeyHash)\n )\n _cancelSignatureMigration(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Verifies the signature of guardians/owner and cancels the signature migration.\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _approvers List of approvers. This could include owner\n */\n function cancelSignatureMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n )\n external\n override\n validateKeyType(_newPublicKey, _newVerificationFacet)\n onlyWhenUnlocked\n {\n if (_approvers.length != _signatures.length)\n revert SignatureMigrationFacet__InvalidArrayLength();\n\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"CancelSignatureMigration\"\n );\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(migrationPublicKeyHash, _approvers);\n\n bool onChainOwnerApproval = getMigrationOwnerApprovalWithTimeValidity(\n migrationPublicKeyHash\n );\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n if (\n _approvers.length +\n getMigrationApprovalCountWithTimeValidity(\n migrationPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert SignatureMigrationFacet__InsufficientApprovers();\n {\n // To prevent stack too deep\n bool ownerApproved;\n for (uint256 i; i < _approvers.length; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n address(this) != _approvers[i]\n ) revert SignatureMigrationFacet__NonExistentApprover();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert SignatureMigrationFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n migrationPublicKeyHash,\n _signatures[i]\n )\n ) revert SignatureMigrationFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n if (!ownerApproved && !onChainOwnerApproval)\n revert SignatureMigrationFacet__LackOfOwnerApproval();\n }\n _cancelSignatureMigration(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Internal function that cancels signature migration.\n * @dev This method increments migration nonce and deletes the migration from the migration config. Emits events for migration cancellation\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _cancelSignatureMigration(\n address _newVerificationFacet,\n bytes memory _newPublicKey,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal {\n if (!isMigrationPending())\n revert SignatureMigrationFacet__NonexistentMigration();\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n unchecked {\n ++ms.nonce;\n }\n delete ms.migrationConfigs[INNER_STRUCT];\n emit SignatureMigrationCanceled(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Checks if the facets to be added from new verification facet is registered to facet registry\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _checkMigrationCutValidity(\n address _newVerificationFacet,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal view {\n IDiamondCut.FacetCut[] memory facetCuts = new IDiamondCut.FacetCut[](1);\n facetCuts[0] = IDiamondCut.FacetCut({\n facetAddress: _newVerificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: _newVerificationFuncSelectors\n });\n _checkFacetCutValidity(facetCuts);\n }\n\n /**\n * @notice Returns if the migration is pending of not\n * @dev This method fetches the migration storage and checks if the migrate after is above 0 value\n * @return isPending Bool value that shows if the migration is pending\n */\n function isMigrationPending()\n public\n view\n override\n returns (bool isPending)\n {\n SignatureMigrationStorage storage rs = LibFacetStorage\n .migrationStorage();\n isPending = rs.migrationConfigs[INNER_STRUCT].migrateAfter > 0;\n }\n\n /**\n * @notice Returns the migration hash. This function ensures that this hash is safe from replay attack by including\n * public key, verification facet, function selectors, salt, address, chainId, and nonce.\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _saltString Salt value for generating the migration hash\n * @return migrationKeyHash Bytes32 string of the migration key hash\n */\n function getApprovalMigrationKeyHash(\n bytes memory _newPublicKey,\n address _newVerificationFacet,\n bytes4[] memory _newVerificationFuncSelectors,\n string memory _saltString\n ) public view override returns (bytes32 migrationKeyHash) {\n migrationKeyHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n _newPublicKey,\n _newVerificationFacet,\n keccak256(abi.encode(_newVerificationFuncSelectors)),\n _saltString,\n address(this),\n block.chainid,\n LibFacetStorage.migrationStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Checks if the owner approved the hash for migration\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @return isApprovedByOwner Bool value of showing if the owner approved it or not\n */\n function getMigrationOwnerApprovalWithTimeValidity(\n bytes32 _migrationPublicKeyHash\n ) public view override returns (bool isApprovedByOwner) {\n isApprovedByOwner = isMigrationApproved(\n _migrationPublicKeyHash,\n address(this)\n );\n }\n\n /**\n * @notice Checks how many of the guardians approved the migration hash\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @return approvalCount Number of approvals\n */\n function getMigrationApprovalCountWithTimeValidity(\n bytes32 _migrationPublicKeyHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardiansLength = guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n if (isMigrationApproved(_migrationPublicKeyHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n return approvalCount;\n }\n\n /**\n * @notice Checks if the migration is approved by the given approver\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @param _approver Address of approver\n * @return isApproved Bool value if migration hash is approved\n */\n function isMigrationApproved(\n bytes32 _migrationPublicKeyHash,\n address _approver\n ) public view override returns (bool isApproved) {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n isApproved = (ms\n .isMigrationApproved[_migrationPublicKeyHash][_approver].isApproved &&\n block.timestamp <\n ms\n .isMigrationApproved[_migrationPublicKeyHash][_approver]\n .validUntil);\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _migrationPublicKeyHash Hash of migration information\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _migrationPublicKeyHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isMigrationApproved(_migrationPublicKeyHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert SignatureMigrationFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the migration period of this wallet\n * @dev This method fetches the migration period from the security manager\n * @return migrationPeriod Migration period of Barz contract fetched from security manager\n */\n function getMigrationPeriod()\n internal\n view\n returns (uint128 migrationPeriod)\n {\n migrationPeriod = securityManager.migrationPeriodOf(address(this));\n if (migrationPeriod == 0)\n revert SignatureMigrationFacet__InvalidMigrationPeriod();\n }\n\n /**\n * @notice Returns the validation period of this wallet\n * @dev This method fetches the validation period from the security manager\n * @return approvalValidationPeriod Validation period of Barz contract fetched from security manager\n */\n function getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod == 0)\n revert SignatureMigrationFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the migration nonce of this wallet\n * @dev This method fetches the nonce from migration storage\n * @return migrationNonce Nonce of migration to protect from reply attacks\n */\n function getMigrationNonce()\n public\n view\n override\n returns (uint128 migrationNonce)\n {\n migrationNonce = LibFacetStorage.migrationStorage().nonce;\n }\n\n /**\n * @notice Returns the migration configuration of this wallet\n * @dev This method fetches the migration config from the migration storage\n * @return pendingMigrationConfig Migration config currently pending for signature migration\n */\n function getPendingMigration()\n external\n view\n override\n returns (SignatureMigrationConfig memory pendingMigrationConfig)\n {\n pendingMigrationConfig = LibFacetStorage\n .migrationStorage()\n .migrationConfigs[INNER_STRUCT];\n }\n}\n" + }, + "contracts/facets/TokenReceiverFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {IERC1155Receiver} from \"../interfaces/ERC/IERC1155Receiver.sol\";\nimport {IERC677Receiver} from \"../interfaces/ERC/IERC677Receiver.sol\";\n\n/**\n * @title TokenReceiver Facet\n * @dev Contract that enables receiving ERC721/ERC1155/ERC777/ERC677 Tokens with safe transfer\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract TokenReceiverFacet is\n IERC721Receiver,\n IERC1155Receiver,\n IERC777Recipient,\n IERC677Receiver\n{\n /**\n * @notice Handles ERC721 Token callback.\n * return Standardized onERC721Received return value.\n */\n function onERC721Received(\n address,\n address,\n uint256,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC721Receiver.onERC721Received.selector;\n }\n\n /**\n * @notice Handles ERC1155 Token callback.\n * return Standardized onERC1155Received return value.\n */\n function onERC1155Received(\n address,\n address,\n uint256,\n uint256,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC1155Receiver.onERC1155Received.selector;\n }\n\n /**\n * @notice Handles ERC1155 Token batch callback.\n * return Standardized onERC1155BatchReceived return value.\n */\n function onERC1155BatchReceived(\n address,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC1155Receiver.onERC1155BatchReceived.selector;\n }\n\n /**\n * @notice Handles ERC777 Token callback.\n * Does not return value, empty implementation.\n */\n function tokensReceived(\n address,\n address,\n address,\n uint256,\n bytes calldata,\n bytes calldata\n ) external pure override {}\n\n /**\n * @notice Handles ERC677 Token callback.\n * return true.\n */\n function onTokenTransfer(\n address,\n uint256,\n bytes calldata\n ) external pure override returns (bool) {\n return true;\n }\n}\n" + }, + "contracts/facets/verification/MultiSigFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {UserOperation} from \"../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../../libraries/LibLoupe.sol\";\nimport {LibAppStorage} from \"../../libraries/LibAppStorage.sol\";\nimport {LibMultiSigStorage, MultiSigStorage} from \"../../libraries/LibMultiSigStorage.sol\";\nimport {IERC1271} from \"../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../interfaces/IVerificationFacet.sol\";\nimport {IMultiSigFacet} from \"../interfaces/IMultiSigFacet.sol\";\n\n/**\n * @title Multi-sig facet\n * @dev Multi-signature Facet with custom threshold.\n * Wallet that adds this facet becomes a multi-sig wallet.\n * Reference signature_format.md documentation for Multi-sig facet details\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract MultiSigFacet is IMultiSigFacet, IVerificationFacet, IERC1271 {\n using ECDSA for bytes32;\n\n address public immutable self;\n\n address internal constant SENTINEL_OWNERS = address(0x1);\n uint256 internal constant ADDRESS = 20;\n uint256 internal constant SIG_TYPE = 1;\n uint256 internal constant SIG_LEN = 4;\n uint256 internal constant THRESHOLD = 4;\n uint256 internal constant INVALID_SIG = 1;\n uint256 internal constant VALID_SIG = 0;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in Multisig Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the right format and initializes signer storage in k1 storage.\n * @param _owners Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _owners\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n\n if (!isValidKeyType(_owners)) revert MultiSigFacet__InvalidInitData();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n uint256 threshold = uint256(uint32(bytes4(_owners)));\n uint256 ownerCount = (_owners.length - THRESHOLD) / ADDRESS;\n\n if (threshold == 0) revert MultiSigFacet__InvalidThreshold();\n if (ownerCount == 0) revert MultisigFacet__InvalidOwnerCount();\n\n address currentOwner = SENTINEL_OWNERS;\n uint256 ptr = THRESHOLD;\n address owner_;\n for (uint256 i; i < ownerCount; ) {\n owner_ = address(bytes20(_owners[ptr:ptr + ADDRESS]));\n ptr += ADDRESS;\n if (\n owner_ == address(0) ||\n owner_ == SENTINEL_OWNERS ||\n owner_ == address(this) ||\n owner_ == currentOwner\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[owner_] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n\n ms.owners[currentOwner] = owner_;\n currentOwner = owner_;\n\n unchecked {\n ++i;\n }\n }\n ms.owners[currentOwner] = SENTINEL_OWNERS;\n ms.ownerCount = ownerCount;\n ms.threshold = threshold;\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_owners);\n }\n\n /**\n * @notice Uninitialize signer in K1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n ++ms.counter;\n address[] memory ownerlist = getOwners();\n uint256 ownerlistLength = ownerlist.length;\n for (uint256 i; i < ownerlistLength; ) {\n ms.owners[ownerlist[i]] = address(0);\n unchecked {\n ++i;\n }\n }\n ms.owners[SENTINEL_OWNERS] = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls checkSignatures with\n * user operation hash and signature together with the threshold.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n // Data 1 is invalid, Data 0 is valid\n validationData = checkSignatures(\n userOpHash,\n userOp.signature,\n LibMultiSigStorage.multisigStorage().threshold\n );\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n return this.validateOwnerSignature.selector;\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n uint totalLength = ms.ownerCount * ADDRESS;\n bytes memory result = new bytes(totalLength);\n\n // populate return array\n uint256 index;\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n while (currentOwner != SENTINEL_OWNERS) {\n assembly {\n mstore(\n add(result, add(32, mul(index, ADDRESS))),\n shl(96, currentOwner)\n )\n }\n currentOwner = ms.owners[currentOwner];\n index++;\n }\n\n return result;\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key should comply with the format in the signature_format.md doc\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n uint256 publicKeyLength = _publicKey.length;\n if (\n publicKeyLength < ADDRESS + THRESHOLD ||\n (publicKeyLength - THRESHOLD) % ADDRESS != 0\n ) return false;\n\n uint256 threshold = uint256(uint32(bytes4(_publicKey)));\n uint256 ownerCount = (publicKeyLength - THRESHOLD) / ADDRESS;\n\n isValid = !(ownerCount < threshold || threshold == 0);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes calldata _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (checkSignatures(\n _hash,\n _signature,\n LibMultiSigStorage.multisigStorage().threshold\n ) == VALID_SIG)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n\n /**\n * @notice Validates the format of the signature and verifies if the signature is signed by the expected key.\n * Reference signature_format.md doc for details about signature format and signature types\n * @param _dataHash Bytes value of data hash signed by the owners\n * @param _signatures Bytes value of signature which should comply with signature format\n * @param _threshold Uint256 value of current Multi-sig Barz's threshold\n */\n function checkSignatures(\n bytes32 _dataHash,\n bytes calldata _signatures,\n uint256 _threshold\n ) public view returns (uint256) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n address lastOwner = address(0);\n address currentOwner;\n bytes memory signature;\n uint256 signatureType;\n uint256 nextOffset;\n uint256 i;\n for (i; i < _threshold; ) {\n (\n currentOwner,\n signature,\n signatureType,\n nextOffset\n ) = splitSignatures(_signatures, nextOffset);\n if (nextOffset == 0 && i + 1 < _threshold) return INVALID_SIG;\n if (signatureType == 1) {\n // If signatureType is 1 then it is default dataHash signed.\n // This also includes the contract signature\n if (\n !SignatureChecker.isValidSignatureNow(\n currentOwner,\n _dataHash,\n signature\n )\n ) return INVALID_SIG;\n } else if (signatureType == 2) {\n // If signatureType is 2 then it is an approved hash\n if (ms.approvedHashes[ms.counter][currentOwner][_dataHash] == 0)\n return INVALID_SIG;\n } else if (signatureType == 3) {\n // If signatureType is 3 then it is a signed message hash\n // This also includes the contract signature\n bytes32 msgHash = _dataHash.toEthSignedMessageHash();\n if (\n !SignatureChecker.isValidSignatureNow(\n currentOwner,\n msgHash,\n signature\n )\n ) return INVALID_SIG;\n } else revert MultiSigFacet__InvalidRoute();\n if (\n currentOwner <= lastOwner ||\n ms.owners[currentOwner] == address(0) ||\n currentOwner == SENTINEL_OWNERS\n ) return INVALID_SIG;\n lastOwner = currentOwner;\n\n unchecked {\n ++i;\n }\n }\n return VALID_SIG;\n }\n\n /**\n * @notice Split signatures into each individual signatures. Should comply with signature format to be split\n * @param _signatures Bytes value of signature\n * @param _nextOffset Uint256 value of next offset to start splitting the signature\n */\n function splitSignatures(\n bytes calldata _signatures,\n uint256 _nextOffset\n )\n public\n pure\n returns (\n address owner_,\n bytes memory signature,\n uint256 signatureType,\n uint256 nextOffset\n )\n {\n uint256 signaturesLength = _signatures.length;\n\n if (signaturesLength <= _nextOffset + ADDRESS + SIG_LEN)\n revert MultiSigFacet__InsufficientSignerLength();\n\n owner_ = address(\n bytes20(_signatures[_nextOffset:_nextOffset + ADDRESS])\n );\n\n signatureType = uint256(\n uint8(\n bytes1(\n _signatures[_nextOffset + ADDRESS:_nextOffset +\n ADDRESS +\n SIG_TYPE]\n )\n )\n );\n\n if (signatureType > 3 || signatureType == 0)\n revert MultiSigFacet__InvalidSignatureType();\n uint256 offSet = _nextOffset + ADDRESS + SIG_TYPE;\n uint256 siglen = uint256(\n uint32(bytes4(_signatures[offSet:offSet + SIG_LEN]))\n );\n if (offSet + siglen > signaturesLength)\n revert MultiSigFacet__InvalidSignatureLength();\n\n offSet += SIG_LEN;\n if (offSet + siglen == signaturesLength) nextOffset = 0;\n else nextOffset = offSet + siglen;\n\n signature = _signatures[offSet:offSet + siglen];\n }\n\n /**\n * @notice Approves the hash of userOperation on-chain. This can only be called by owners.\n * @param _hashToApprove Bytes value of UserOperation hash to approve\n */\n function approveHash(bytes32 _hashToApprove) external {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (ms.owners[msg.sender] == address(0))\n revert MultiSigFacet__OnlyOwner();\n\n ms.approvedHashes[ms.counter][msg.sender][_hashToApprove] = 1;\n emit HashApproved(_hashToApprove, msg.sender);\n }\n\n /**\n * @notice Add owner to Barz. Update thresold if threshold is given different from current threshold\n * @dev This can only be done via a Self call.\n * @param _newOwner Address of new owner to be added\n * @param _threshold Uint256 value of threshold\n */\n function addOwner(address _newOwner, uint256 _threshold) external {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (\n _newOwner == address(0) ||\n _newOwner == SENTINEL_OWNERS ||\n _newOwner == address(this)\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_newOwner] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n\n ms.owners[_newOwner] = ms.owners[SENTINEL_OWNERS];\n ms.owners[SENTINEL_OWNERS] = _newOwner;\n ++ms.ownerCount;\n emit OwnerAdded(_newOwner);\n\n if (ms.threshold != _threshold) changeThreshold(_threshold);\n }\n\n /**\n * @notice Remove owner from Barz. Update thresold if threshold is given different from current threshold\n * @dev This can only be done via a Self call.\n * @param _prevOwner Address of owner located right behind the removed owner address in the linked list\n * @param _removedOwner Address of owner to be removed\n * @param _threshold Uint256 value of threshold\n */\n function removeOwner(\n address _prevOwner,\n address _removedOwner,\n uint256 _threshold\n ) external {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (ms.ownerCount - 1 < _threshold)\n revert MultiSigFacet__InvalidThreshold();\n if (_removedOwner == address(0) || _removedOwner == SENTINEL_OWNERS)\n revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_prevOwner] != _removedOwner)\n revert MultiSigFacet__InvalidOwnerPair();\n\n ms.owners[_prevOwner] = ms.owners[_removedOwner];\n ms.owners[_removedOwner] = address(0);\n --ms.ownerCount;\n emit OwnerRemoved(_removedOwner);\n\n if (ms.threshold != _threshold) changeThreshold(_threshold);\n }\n\n /**\n * @notice Swap owner in Barz.\n * @dev This can only be done via a Self call.\n * @param _prevOwner Address of owner located right behind the removed owner address in the linked list\n * @param _oldOwner Address of owner to be removed\n * @param _newOwner Address of owner to be added\n */\n function swapOwner(\n address _prevOwner,\n address _oldOwner,\n address _newOwner\n ) public {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (\n _newOwner == address(0) ||\n _newOwner == SENTINEL_OWNERS ||\n _newOwner == address(this)\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_newOwner] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n if (_oldOwner == address(0) || _oldOwner == SENTINEL_OWNERS)\n revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_prevOwner] != _oldOwner)\n revert MultiSigFacet__InvalidOwnerPair();\n\n ms.owners[_newOwner] = ms.owners[_oldOwner];\n ms.owners[_prevOwner] = _newOwner;\n ms.owners[_oldOwner] = address(0);\n emit OwnerRemoved(_oldOwner);\n emit OwnerAdded(_newOwner);\n }\n\n /**\n * @notice Changes the threshold of the Barz to `_threshold`.\n * @dev This can only be done via a Self call.\n * @param _threshold New threshold\n */\n function changeThreshold(uint256 _threshold) public {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (_threshold > ms.ownerCount || _threshold == 0)\n revert MultiSigFacet__InvalidThreshold();\n\n ms.threshold = _threshold;\n emit ThresholdChanged(_threshold);\n }\n\n /**\n * @notice Checks if the given address is owner\n * @param _owner Address to be checked if it's owner\n * @return isOwner_ Bool value showing if it's owner address\n */\n function isOwner(address _owner) public view returns (bool isOwner_) {\n isOwner_ = (_owner != SENTINEL_OWNERS &&\n LibMultiSigStorage.multisigStorage().owners[_owner] != address(0));\n }\n\n /**\n * @notice Returns the threshold of Barz\n * @return threshold Threshold of the Barz account\n */\n function getThreshold() public view returns (uint256 threshold) {\n threshold = LibMultiSigStorage.multisigStorage().threshold;\n }\n\n /**\n * @notice Returns the list of owner addresses\n * @return owners List of owners\n */\n function getOwners() public view returns (address[] memory owners) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n owners = new address[](ms.ownerCount);\n\n uint256 index;\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n while (currentOwner != SENTINEL_OWNERS) {\n owners[index] = currentOwner;\n currentOwner = ms.owners[currentOwner];\n index++;\n }\n }\n\n /**\n * @notice Returns the previous owner in the linked list\n * @param _owner Address of owner\n * @return prevOwner Address of previous owner\n */\n function getPrevOwner(\n address _owner\n ) public view returns (address prevOwner) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n if (currentOwner == _owner) return SENTINEL_OWNERS;\n while (currentOwner != SENTINEL_OWNERS) {\n if (ms.owners[currentOwner] == _owner) return currentOwner;\n\n currentOwner = ms.owners[currentOwner];\n }\n return address(0);\n }\n\n /**\n * @notice Returns of the owner is approved by given owner address\n * @param _owner Address of owner\n * @param _hash Hash of UserOperation\n * @return isApproved Bool value showing if the hash is approved by owner\n */\n function isApprovedHash(\n address _owner,\n bytes32 _hash\n ) public view returns (bool isApproved) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n isApproved = (ms.approvedHashes[ms.counter][_owner][_hash] == 1);\n }\n}\n" + }, + "contracts/facets/verification/secp256k1/Secp256k1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {UserOperation} from \"../../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibAppStorage} from \"../../../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, Secp256k1VerificationStorage} from \"../../../libraries/LibFacetStorage.sol\";\nimport {LibLoupe} from \"../../../libraries/LibLoupe.sol\";\nimport {IERC1271} from \"../../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../../interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Secp256k1 verification facet\n * @dev Default Ethereum's elliptic curve\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract Secp256k1VerificationFacet is IVerificationFacet, IERC1271 {\n using ECDSA for bytes32;\n error Secp256k1VerificationFacet__InvalidSignerLength();\n address public immutable self;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in K1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\n * @param _publicKey Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _publicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n if (!isValidKeyType(_publicKey))\n revert Secp256k1VerificationFacet__InvalidSignerLength();\n\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(uint160(uint256(keccak256(_publicKey[1:]))));\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_publicKey);\n }\n\n /**\n * @notice Uninitialize signer in K1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\n * signer public key.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n validationData = validateSignature(\n userOp,\n userOpHash,\n k1Storage.signer\n );\n }\n\n /**\n * @notice Validates if the signature of UserOperation is signed by the given signer\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @param signer Address of signer who signed the contract, to be validated\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n address signer\n ) public pure returns (uint256 isValid) {\n bytes32 hash = userOpHash.toEthSignedMessageHash();\n isValid = (signer != hash.recover(userOp.signature)) ? 1 : 0;\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n ownerSignatureValidatorSelector = this.validateOwnerSignature.selector;\n // NOTE: The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory signer) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n signer = abi.encodePacked(k1Storage.signer);\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key length should be 65 in an uncompressed public key format\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (_hash.recover(_signature) ==\n LibFacetStorage.k1Storage().signer)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/Secp256r1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {UserOperation} from \"../../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibAppStorage} from \"../../../libraries/LibAppStorage.sol\";\nimport {LibLoupe} from \"../../../libraries/LibLoupe.sol\";\nimport {LibFacetStorage, Secp256r1VerificationStorage} from \"../../../libraries/LibFacetStorage.sol\";\nimport {Base64} from \"./utils/Base64.sol\";\nimport {LibSecp256r1} from \"./utils/LibSecp256r1.sol\";\nimport {IERC1271} from \"../../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../../interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Secp256r1 verification facet\n * @dev Primarily used to verify user ops signed with passkeys\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract Secp256r1VerificationFacet is IVerificationFacet, IERC1271 {\n error Secp256r1VerificationFacet__InvalidSignerLength();\n address public immutable self;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in R1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\n * @param _publicKey Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _publicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n\n if (!isValidKeyType(_publicKey))\n revert Secp256r1VerificationFacet__InvalidSignerLength();\n\n bytes memory publicKeyCoordinates = _publicKey[1:];\n uint256[2] memory q;\n assembly {\n // Copy the bytes from the input data into the uint256 array\n mstore(q, mload(add(publicKeyCoordinates, 32)))\n mstore(add(q, 32), mload(add(publicKeyCoordinates, 64)))\n }\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n r1Storage.q = q;\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_publicKey);\n }\n\n /**\n * @notice Uninitialize signer in R1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n r1Storage.q = [0, 0];\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\n * signer public key.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n validationData = validateSignature(userOp, userOpHash, r1Storage.q);\n }\n\n /**\n * @notice Validates if the signature of UserOperation is signed by the given signer\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @param q Public Key of signer who signed the contract, to be validated\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256[2] memory q\n ) public view returns (uint256 isValid) {\n isValid = (_validateSignature(q, userOpHash, userOp.signature)) ? 0 : 1;\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n return this.validateOwnerSignature.selector; // validateOwnerSignature(UserOperation calldata userOp,bytes32 userOpHash)\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory signer) {\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n signer = abi.encodePacked(r1Storage.q);\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key should in an uncompressed public key format\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = _validateSignature(\n LibFacetStorage.r1Storage().q,\n _hash,\n _signature\n )\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n\n function _validateSignature(\n uint256[2] memory q,\n bytes32 _hash,\n bytes memory _signature\n ) internal view returns (bool) {\n (\n uint256 rValue,\n uint256 sValue,\n bytes memory authenticatorData,\n string memory clientDataJSONPre,\n string memory clientDataJSONPost\n ) = abi.decode(_signature, (uint256, uint256, bytes, string, string));\n bytes32 clientHash;\n {\n string memory opHashBase64 = Base64.encode(bytes.concat(_hash));\n string memory clientDataJSON = string.concat(\n clientDataJSONPre,\n opHashBase64,\n clientDataJSONPost\n );\n clientHash = sha256(bytes(clientDataJSON));\n }\n bytes32 sigHash = sha256(bytes.concat(authenticatorData, clientHash));\n return LibSecp256r1.Verify(q, rValue, sValue, uint256(sigHash));\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/utils/Base64.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @dev Provides a set of functions to operate with Base64 strings.\n * modified for base64url https://datatracker.ietf.org/doc/html/rfc4648#section-5\n * _Available since v4.5._\n */\nlibrary Base64 {\n /**\n * @dev Base64 Encoding/Decoding Table\n */\n string internal constant _TABLE =\n \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_\";\n\n /**\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\n */\n function encode(bytes memory data) internal pure returns (string memory) {\n /**\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\n */\n if (data.length == 0) return \"\";\n\n // Loads the table into memory\n string memory table = _TABLE;\n\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\n // and split into 4 numbers of 6 bits.\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\n // - `data.length + 2` -> Round up\n // - `/ 3` -> Number of 3-bytes chunks\n // - `4 *` -> 4 characters for each chunk\n uint256 newlength = (data.length * 8) / 6;\n if (data.length % 6 > 0) {\n newlength++;\n }\n string memory result = new string(newlength);\n\n /// @solidity memory-safe-assembly\n assembly {\n // Prepare the lookup table (skip the first \"length\" byte)\n let tablePtr := add(table, 1)\n\n // Prepare result pointer, jump over length\n let resultPtr := add(result, 32)\n\n // Run over the input, 3 bytes at a time\n for {\n let dataPtr := data\n let endPtr := add(data, mload(data))\n } lt(dataPtr, endPtr) {\n\n } {\n // Advance 3 bytes\n dataPtr := add(dataPtr, 3)\n let input := mload(dataPtr)\n\n // To write each character, shift the 3 bytes (18 bits) chunk\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\n // and apply logical AND with 0x3F which is the number of\n // the previous character in the ASCII table prior to the Base64 Table\n // The result is then added to the table to get the character to write,\n // and finally write it in the result pointer but with a left shift\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(18, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(12, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(6, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n }\n }\n\n return result;\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/utils/LibSecp256r1.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n// Heavily inspired from\n// https://github.com/maxrobot/elliptic-solidity/blob/master/contracts/Secp256r1.sol\n// https://github.com/tdrerup/elliptic-curve-solidity/blob/master/contracts/curves/EllipticCurve.sol\n// modified to use precompile 0x05 modexp\n// and modified jacobian double\n// optimisations to avoid to an from from affine and jacobian coordinates\n\n// Additional Elliptic curve Public key / Signature validation added by\n// David Yonjun Kim (@Powerstream3604)\n\nstruct JPoint {\n uint256 x;\n uint256 y;\n uint256 z;\n}\n\nlibrary LibSecp256r1 {\n uint256 constant gx =\n 0x6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296;\n uint256 constant gy =\n 0x4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5;\n uint256 public constant pp =\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF;\n\n uint256 public constant nn =\n 0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551;\n uint256 constant a =\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC;\n uint256 constant b =\n 0x5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B;\n uint256 constant MOST_SIGNIFICANT =\n 0xc000000000000000000000000000000000000000000000000000000000000000;\n\n /*\n * Verify\n * @description - verifies that a public key has signed a given message\n * @param Q - public key coordinates X & Y\n * @param R - signature half R\n * @param S - signature half S\n * @param input - hashed message\n */\n function Verify(\n uint256[2] memory q,\n uint r,\n uint s,\n uint e\n ) internal view returns (bool) {\n if (q[0] > pp - 1 || q[1] > pp - 1) {\n return false;\n }\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\n return false;\n }\n if (\n mulmod(q[1], q[1], pp) !=\n addmod(\n addmod(\n mulmod(q[0], mulmod(q[0], q[0], pp), pp),\n mulmod(a, q[0], pp),\n pp\n ),\n b,\n pp\n )\n ) {\n return false;\n }\n\n JPoint[16] memory points = _preComputeJacobianPoints(q);\n return VerifyWithPrecompute(points, r, s, e);\n }\n\n function VerifyWithPrecompute(\n JPoint[16] memory points,\n uint r,\n uint s,\n uint e\n ) internal view returns (bool) {\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\n return false;\n }\n\n uint w = _primemod(s, nn);\n\n uint u1 = mulmod(e, w, nn);\n uint u2 = mulmod(r, w, nn);\n\n uint x;\n uint y;\n\n (x, y) = ShamirMultJacobian(points, u1, u2);\n return (x == r);\n }\n\n /*\n * Strauss Shamir trick for EC multiplication\n * https://stackoverflow.com/questions/50993471/ec-scalar-multiplication-with-strauss-shamir-method\n * we optimise on this a bit to do with 2 bits at a time rather than a single bit\n * the individual points for a single pass are precomputed\n * overall this reduces the number of additions while keeping the same number of doublings\n */\n function ShamirMultJacobian(\n JPoint[16] memory points,\n uint u1,\n uint u2\n ) internal view returns (uint, uint) {\n uint x = 0;\n uint y = 0;\n uint z = 0;\n uint bits = 128;\n uint index = 0;\n\n while (bits > 0) {\n if (z > 0) {\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\n }\n index =\n ((u1 & MOST_SIGNIFICANT) >> 252) |\n ((u2 & MOST_SIGNIFICANT) >> 254);\n if (index > 0) {\n (x, y, z) = _jAdd(\n x,\n y,\n z,\n points[index].x,\n points[index].y,\n points[index].z\n );\n }\n u1 <<= 2;\n u2 <<= 2;\n bits--;\n }\n (x, y) = _affineFromJacobian(x, y, z);\n return (x, y);\n }\n\n function _preComputeJacobianPoints(\n uint256[2] memory q\n ) internal pure returns (JPoint[16] memory points) {\n points[0] = JPoint(0, 0, 0);\n points[1] = JPoint(q[0], q[1], 1); // u2\n points[2] = _jPointDouble(points[1]);\n points[3] = _jPointAdd(points[1], points[2]);\n\n points[4] = JPoint(gx, gy, 1); // u1Points[1]\n points[5] = _jPointAdd(points[4], points[1]);\n points[6] = _jPointAdd(points[4], points[2]);\n points[7] = _jPointAdd(points[4], points[3]);\n\n points[8] = _jPointDouble(points[4]); // u1Points[2]\n points[9] = _jPointAdd(points[8], points[1]);\n points[10] = _jPointAdd(points[8], points[2]);\n points[11] = _jPointAdd(points[8], points[3]);\n\n points[12] = _jPointAdd(points[4], points[8]); // u1Points[3]\n points[13] = _jPointAdd(points[12], points[1]);\n points[14] = _jPointAdd(points[12], points[2]);\n points[15] = _jPointAdd(points[12], points[3]);\n }\n\n function _jPointAdd(\n JPoint memory p1,\n JPoint memory p2\n ) internal pure returns (JPoint memory) {\n uint x;\n uint y;\n uint z;\n (x, y, z) = _jAdd(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z);\n return JPoint(x, y, z);\n }\n\n function _jPointDouble(\n JPoint memory p\n ) internal pure returns (JPoint memory) {\n uint x;\n uint y;\n uint z;\n (x, y, z) = _modifiedJacobianDouble(p.x, p.y, p.z);\n return JPoint(x, y, z);\n }\n\n /* _affineFromJacobian\n * @desription returns affine coordinates from a jacobian input follows\n * golang elliptic/crypto library\n */\n function _affineFromJacobian(\n uint x,\n uint y,\n uint z\n ) internal view returns (uint ax, uint ay) {\n if (z == 0) {\n return (0, 0);\n }\n\n uint zinv = _primemod(z, pp);\n uint zinvsq = mulmod(zinv, zinv, pp);\n\n ax = mulmod(x, zinvsq, pp);\n ay = mulmod(y, mulmod(zinvsq, zinv, pp), pp);\n }\n\n /*\n * _jAdd\n * @description performs Jacobian addition as defined below:\n * http://www.hyperelliptic.org/EFD/g1p/data/shortw/jacobian/addition/add-2007-bl\n */\n function _jAdd(\n uint p1,\n uint p2,\n uint p3,\n uint q1,\n uint q2,\n uint q3\n ) internal pure returns (uint r1, uint r2, uint r3) {\n if (p3 == 0) {\n r1 = q1;\n r2 = q2;\n r3 = q3;\n\n return (r1, r2, r3);\n } else if (q3 == 0) {\n r1 = p1;\n r2 = p2;\n r3 = p3;\n\n return (r1, r2, r3);\n }\n\n assembly {\n let\n pd\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\n let z1z1 := mulmod(p3, p3, pd) // Z1Z1 = Z1^2\n let z2z2 := mulmod(q3, q3, pd) // Z2Z2 = Z2^2\n\n let u1 := mulmod(p1, z2z2, pd) // U1 = X1*Z2Z2\n let u2 := mulmod(q1, z1z1, pd) // U2 = X2*Z1Z1\n\n let s1 := mulmod(p2, mulmod(z2z2, q3, pd), pd) // S1 = Y1*Z2*Z2Z2\n let s2 := mulmod(q2, mulmod(z1z1, p3, pd), pd) // S2 = Y2*Z1*Z1Z1\n\n let p3q3 := addmod(p3, q3, pd)\n\n if lt(u2, u1) {\n u2 := add(pd, u2) // u2 = u2+pd\n }\n let h := sub(u2, u1) // H = U2-U1\n\n let i := mulmod(0x02, h, pd)\n i := mulmod(i, i, pd) // I = (2*H)^2\n\n let j := mulmod(h, i, pd) // J = H*I\n if lt(s2, s1) {\n s2 := add(pd, s2) // u2 = u2+pd\n }\n let rr := mulmod(0x02, sub(s2, s1), pd) // r = 2*(S2-S1)\n r1 := mulmod(rr, rr, pd) // X3 = R^2\n\n let v := mulmod(u1, i, pd) // V = U1*I\n let j2v := addmod(j, mulmod(0x02, v, pd), pd)\n if lt(r1, j2v) {\n r1 := add(pd, r1) // X3 = X3+pd\n }\n r1 := sub(r1, j2v)\n\n // Y3 = r*(V-X3)-2*S1*J\n let s12j := mulmod(mulmod(0x02, s1, pd), j, pd)\n\n if lt(v, r1) {\n v := add(pd, v)\n }\n r2 := mulmod(rr, sub(v, r1), pd)\n\n if lt(r2, s12j) {\n r2 := add(pd, r2)\n }\n r2 := sub(r2, s12j)\n\n // Z3 = ((Z1+Z2)^2-Z1Z1-Z2Z2)*H\n z1z1 := addmod(z1z1, z2z2, pd)\n j2v := mulmod(p3q3, p3q3, pd)\n if lt(j2v, z1z1) {\n j2v := add(pd, j2v)\n }\n r3 := mulmod(sub(j2v, z1z1), h, pd)\n }\n return (r1, r2, r3);\n }\n\n // Point doubling on the modified jacobian coordinates\n // http://point-at-infinity.org/ecc/Prime_Curve_Modified_Jacobian_Coordinates.html\n function _modifiedJacobianDouble(\n uint x,\n uint y,\n uint z\n ) internal pure returns (uint x3, uint y3, uint z3) {\n if (y == 0) return (0, 0, 0);\n assembly {\n let\n pd\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\n let z2 := mulmod(z, z, pd)\n let az4 := mulmod(\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC,\n mulmod(z2, z2, pd),\n pd\n )\n let y2 := mulmod(y, y, pd)\n let s := mulmod(0x04, mulmod(x, y2, pd), pd)\n let u := mulmod(0x08, mulmod(y2, y2, pd), pd)\n let m := addmod(mulmod(0x03, mulmod(x, x, pd), pd), az4, pd)\n let twos := mulmod(0x02, s, pd)\n let m2 := mulmod(m, m, pd)\n if lt(m2, twos) {\n m2 := add(pd, m2)\n }\n x3 := sub(m2, twos)\n if lt(s, x3) {\n s := add(pd, s)\n }\n y3 := mulmod(m, sub(s, x3), pd)\n if lt(y3, u) {\n y3 := add(pd, y3)\n }\n y3 := sub(y3, u)\n z3 := mulmod(0x02, mulmod(y, z, pd), pd)\n }\n }\n\n // Fermats little theorem https://en.wikipedia.org/wiki/Fermat%27s_little_theorem\n // a^(p-1) = 1 mod p\n // a^(-1) ≅ a^(p-2) (mod p)\n // we then use the precompile bigModExp to compute a^(-1)\n function _primemod(uint value, uint p) internal view returns (uint ret) {\n ret = modexp(value, p - 2, p);\n return ret;\n }\n\n // Wrapper for built-in BigNumber_modexp (contract 0x5) as described here. https://github.com/ethereum/EIPs/pull/198\n function modexp(\n uint _base,\n uint _exp,\n uint _mod\n ) internal view returns (uint ret) {\n // bigModExp(_base, _exp, _mod);\n assembly {\n if gt(_base, _mod) {\n _base := mod(_base, _mod)\n }\n // Free memory pointer is always stored at 0x40\n let freemem := mload(0x40)\n\n mstore(freemem, 0x20)\n mstore(add(freemem, 0x20), 0x20)\n mstore(add(freemem, 0x40), 0x20)\n\n mstore(add(freemem, 0x60), _base)\n mstore(add(freemem, 0x80), _exp)\n mstore(add(freemem, 0xa0), _mod)\n\n let success := staticcall(14000, 0x5, freemem, 0xc0, freemem, 0x20)\n switch success\n case 0 {\n revert(0x0, 0x0)\n }\n default {\n ret := mload(freemem)\n }\n }\n }\n}\n" + }, + "contracts/infrastructure/DefaultFallbackHandler.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC1155Receiver} from \"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\";\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {BaseAccount} from \"../aa-4337/core/BaseAccount.sol\";\nimport {DefaultLibDiamond} from \"../libraries/DefaultLibDiamond.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IAccountFacet} from \"../facets/interfaces/IAccountFacet.sol\";\nimport {IStorageLoupe} from \"../facets/base/interfaces/IStorageLoupe.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IERC677Receiver} from \"../interfaces/ERC/IERC677Receiver.sol\";\nimport {IERC165} from \"../interfaces/ERC/IERC165.sol\";\n\n/**\n * @title DefaultFallbackHandler\n * @dev A default fallback handler for Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DefaultFallbackHandler is IDiamondLoupe {\n /**\n * @notice Sets the middleware diamond for Barz wallet as a fallback handler\n * @dev This contract is also a diamond that holds the default facets to reduce gas cost for wallet activation.\n * Within the constructor this conducts diamond cut to initially setup the diamond. This is a non-upgradeable contract\n * @param _diamondCutFacet Address if diamond cut facet\n * @param _accountFacet Address account facet\n * @param _tokenReceiverFacet Address of token receiver facet\n * @param _diamondLoupeFacet Address of diamond loupe facet\n */\n constructor(\n address _diamondCutFacet,\n address _accountFacet,\n address _tokenReceiverFacet,\n address _diamondLoupeFacet\n ) payable {\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](4);\n bytes4[] memory functionSelectors = new bytes4[](1);\n functionSelectors[0] = IDiamondCut.diamondCut.selector;\n\n bytes4[] memory accountFunctionSelectors = new bytes4[](5);\n accountFunctionSelectors[0] = IAccountFacet.execute.selector;\n accountFunctionSelectors[1] = IAccountFacet.executeBatch.selector;\n accountFunctionSelectors[2] = BaseAccount.validateUserOp.selector;\n accountFunctionSelectors[3] = BaseAccount.getNonce.selector;\n accountFunctionSelectors[4] = BaseAccount.entryPoint.selector;\n\n bytes4[] memory receiverFacetSelectors = new bytes4[](5);\n receiverFacetSelectors[0] = IERC721Receiver.onERC721Received.selector;\n receiverFacetSelectors[1] = IERC1155Receiver.onERC1155Received.selector;\n receiverFacetSelectors[2] = IERC1155Receiver\n .onERC1155BatchReceived\n .selector;\n receiverFacetSelectors[3] = IERC777Recipient.tokensReceived.selector;\n receiverFacetSelectors[4] = IERC677Receiver.onTokenTransfer.selector;\n\n bytes4[] memory loupeFacetSelectors = new bytes4[](9);\n loupeFacetSelectors[0] = IDiamondLoupe.facets.selector;\n loupeFacetSelectors[1] = IDiamondLoupe.facetFunctionSelectors.selector;\n loupeFacetSelectors[2] = IDiamondLoupe.facetAddresses.selector;\n loupeFacetSelectors[3] = IDiamondLoupe.facetAddress.selector;\n loupeFacetSelectors[4] = IERC165.supportsInterface.selector;\n loupeFacetSelectors[5] = IStorageLoupe.facetsFromStorage.selector;\n loupeFacetSelectors[6] = IStorageLoupe\n .facetFunctionSelectorsFromStorage\n .selector;\n loupeFacetSelectors[7] = IStorageLoupe\n .facetAddressesFromStorage\n .selector;\n loupeFacetSelectors[8] = IStorageLoupe.facetAddressFromStorage.selector;\n\n {\n cut[0] = IDiamondCut.FacetCut({\n facetAddress: _diamondCutFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: functionSelectors\n });\n cut[1] = IDiamondCut.FacetCut({\n facetAddress: _accountFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: accountFunctionSelectors\n });\n cut[2] = IDiamondCut.FacetCut({\n facetAddress: _tokenReceiverFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: receiverFacetSelectors\n });\n cut[3] = IDiamondCut.FacetCut({\n facetAddress: _diamondLoupeFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: loupeFacetSelectors\n });\n\n DefaultLibDiamond.diamondCut(cut, address(0), \"\");\n }\n }\n\n /**\n * @notice Returns the facet information of call facets registered to this diamond.\n * @return facets_ The facet struct array including all facet information\n */\n function facets() external view override returns (Facet[] memory facets_) {\n DefaultLibDiamond.DiamondStorage storage ds = DefaultLibDiamond\n .diamondStorage();\n uint256 numFacets = ds.facetAddresses.length;\n facets_ = new Facet[](numFacets);\n for (uint256 i; i < numFacets; ) {\n address facetAddress_ = ds.facetAddresses[i];\n facets_[i].facetAddress = facetAddress_;\n facets_[i].functionSelectors = ds\n .facetFunctionSelectors[facetAddress_]\n .functionSelectors;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Gets all the function selectors provided by a facet.\n * @param _facet The facet address.\n * @return facetFunctionSelectors_\n */\n function facetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n facetFunctionSelectors_ = DefaultLibDiamond\n .diamondStorage()\n .facetFunctionSelectors[_facet]\n .functionSelectors;\n }\n\n /**\n * @notice Get all the facet addresses used by a diamond.\n * @return facetAddresses_\n */\n function facetAddresses()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n facetAddresses_ = DefaultLibDiamond.diamondStorage().facetAddresses;\n }\n\n /** @notice Gets the facet that supports the given selector.\n * @dev If facet is not found return address(0).\n * @param _functionSelector The function selector.\n * @return facetAddress_ The facet address.\n */\n function facetAddress(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n facetAddress_ = DefaultLibDiamond\n .diamondStorage()\n .selectorToFacetAndPosition[_functionSelector]\n .facetAddress;\n }\n}\n" + }, + "contracts/infrastructure/FacetRegistry.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport {IFacetRegistry} from \"./interfaces/IFacetRegistry.sol\";\n\n/**\n * @title Facet Registry\n * @dev Contract to keep track of facets & function selectors addable to user wallets\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract FacetRegistry is IFacetRegistry, Ownable2Step {\n mapping(address => FacetRegistryConfig) private facets;\n\n /**\n * @notice Transfers the ownership of the contract to the given owner\n * @param _owner Address of owner who has access to initialize the default security variables for security manager\n */\n constructor(address _owner) {\n transferOwnership(_owner);\n _transferOwnership(_owner);\n }\n\n /**\n * @dev Registers a facet and it's function selectors to registry\n * @param _facet address of facet\n * @param _facetSelectors list of function selectors of the facet\n */\n function registerFacetFunctionSelectors(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external override onlyOwner {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n for (uint256 i; i < _facetSelectors.length; ) {\n if (facetConfig.info[_facetSelectors[i]].exists)\n revert FacetRegistry__FacetSelectorAlreadyRegistered();\n\n facetConfig.info[_facetSelectors[i]].exists = true;\n facetConfig.info[_facetSelectors[i]].index = uint128(\n facetConfig.selectors.length\n );\n facetConfig.selectors.push(_facetSelectors[i]);\n unchecked {\n ++i;\n }\n }\n emit FacetFunctionSelectorsRegistered(_facet, _facetSelectors);\n }\n\n /**\n * @dev Removes a registered facet and it's corresponding selectors from registry\n * @param _facet address of facet\n * @param _facetSelectors list of function selectors of the facet\n */\n function removeFacetFunctionSelectors(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external override onlyOwner {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n for (uint256 i; i < _facetSelectors.length; ) {\n if (!facetConfig.info[_facetSelectors[i]].exists)\n revert FacetRegistry__UnregisteredFacetSelector();\n\n bytes4 lastSelector = facetConfig.selectors[\n facetConfig.selectors.length - 1\n ];\n if (_facetSelectors[i] != lastSelector) {\n uint128 targetIndex = facetConfig\n .info[_facetSelectors[i]]\n .index;\n facetConfig.selectors[targetIndex] = lastSelector;\n facetConfig.info[lastSelector].index = targetIndex;\n }\n facetConfig.selectors.pop();\n delete facetConfig.info[_facetSelectors[i]];\n\n unchecked {\n ++i;\n }\n }\n emit FacetFunctionSelectorsRemoved(_facet, _facetSelectors);\n }\n\n /**\n * @dev Checks if a facet and it's selectors given is registered to facet registry\n * @param _facet Address of facet\n * @param _facetSelectors List of function selectors of the facet\n */\n function areFacetFunctionSelectorsRegistered(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external view override returns (bool) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n if (_facetSelectors.length == 0) return false;\n for (uint256 i; i < _facetSelectors.length; ) {\n if (!facetConfig.info[_facetSelectors[i]].exists) return false;\n unchecked {\n ++i;\n }\n }\n return true;\n }\n\n /**\n * @dev Checks if a facet and it's selector given is registered to facet registry\n * @param _facet Address of facet\n * @param _facetSelector List of function selectors of the facet\n * @return isRegistered Bool value showing if the selector is registered\n */\n function isFacetFunctionSelectorRegistered(\n address _facet,\n bytes4 _facetSelector\n ) external view override returns (bool isRegistered) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n isRegistered = facetConfig.info[_facetSelector].exists;\n }\n\n /**\n * @dev Get the registered selectors of facet from registry\n * @param _facet Address of facet\n * @return selectors Selectors registered to facet\n */\n function getFacetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory selectors) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n selectors = facetConfig.selectors;\n }\n}\n" + }, + "contracts/infrastructure/interfaces/IFacetRegistry.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Registry Interface\n * @dev Interface for Facet Registry contract to keep track of facets & function selectors addable to user wallets\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IFacetRegistry {\n struct FacetRegistryConfig {\n bytes4[] selectors;\n mapping(bytes4 => FacetInfo) info;\n }\n struct FacetInfo {\n bool exists;\n uint128 index;\n }\n\n event FacetFunctionSelectorsRegistered(\n address facet,\n bytes4[] facetSelectors\n );\n event FacetFunctionSelectorsRemoved(address facet, bytes4[] facetSelectors);\n\n error FacetRegistry__FacetSelectorAlreadyRegistered();\n error FacetRegistry__UnregisteredFacetSelector();\n\n function registerFacetFunctionSelectors(\n address facet,\n bytes4[] calldata facetSelectors\n ) external;\n\n function removeFacetFunctionSelectors(\n address facet,\n bytes4[] calldata facetSelectors\n ) external;\n\n function areFacetFunctionSelectorsRegistered(\n address facet,\n bytes4[] calldata facetSelectors\n ) external view returns (bool);\n\n function isFacetFunctionSelectorRegistered(\n address facet,\n bytes4 facetSelector\n ) external view returns (bool);\n\n function getFacetFunctionSelectors(\n address facet\n ) external view returns (bytes4[] memory);\n}\n" + }, + "contracts/infrastructure/interfaces/ISecurityManager.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Registry Interface\n * @dev Infrastructure contract to manage security parameters of users\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface ISecurityManager {\n error SecurityManager__OutOfBoundary();\n error SecurityManager__CallerNotWallet();\n error SecurityManager__AlreadyIntialized();\n\n function initializeAdditionSecurityPeriod(\n uint128 defaultAdditionSecurityPeriod,\n uint128 minAdditionSecurityPeriod,\n uint128 maxAdditionSecurityPeriod\n ) external;\n\n function initializeRemovalSecurityPeriod(\n uint128 defaultRemovalSecurityPeriod,\n uint128 minRemovalSecurityPeriod,\n uint128 maxRemovalSecurityPeriod\n ) external;\n\n function initializeApprovalValidationPeriod(\n uint128 defaultApprovalValidationPeriod,\n uint128 minApprovalValidationPeriod,\n uint128 maxApprovalValidationPeriod\n ) external;\n\n function initializeMigrationPeriod(\n uint128 defaultMigrationPeriod,\n uint128 minMigrationPeriod,\n uint128 maxMigrationPeriod\n ) external;\n\n function initializeLockPeriod(\n uint128 defaultLockPeriod,\n uint128 minLockPeriod,\n uint128 maxLockPeriod\n ) external;\n\n function initializeRecoveryPeriod(\n uint128 defaultRecoveryPeriod,\n uint128 minRecoveryPeriod,\n uint128 maxRecoveryPeriod\n ) external;\n\n function initializeSecurityWindow(\n uint128 defaultSecurityWindow,\n uint128 minSecurityWindow,\n uint128 maxSecurityWindow\n ) external;\n\n function setAdditionSecurityPeriod(\n address wallet,\n uint128 additionSecurityPeriod\n ) external;\n\n function setRemovalSecurityPeriod(\n address wallet,\n uint128 removalSecurityPeriod\n ) external;\n\n function setSecurityWindow(address wallet, uint128 securityWindow) external;\n\n function setRecoveryPeriod(address wallet, uint128 recoveryPeriod) external;\n\n function setLockPeriod(address wallet, uint128 lockPeriod) external;\n\n function setApprovalValidationPeriod(\n address wallet,\n uint128 approvalValidationPeriod\n ) external;\n\n function setMigrationPeriod(\n address wallet,\n uint128 migrationPeriod\n ) external;\n\n function additionSecurityPeriodOf(\n address wallet\n ) external view returns (uint128);\n\n function removalSecurityPeriodOf(\n address wallet\n ) external view returns (uint128);\n\n function securityWindowOf(address wallet) external view returns (uint128);\n\n function recoveryPeriodOf(address wallet) external view returns (uint128);\n\n function lockPeriodOf(address wallet) external view returns (uint128);\n\n function migrationPeriodOf(address wallet) external view returns (uint128);\n\n function approvalValidationPeriodOf(\n address wallet\n ) external view returns (uint128);\n}\n" + }, + "contracts/infrastructure/RemoteStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IGuardianFacet} from \"../facets/interfaces/IGuardianFacet.sol\";\n\n/**\n * @title Remote Storage\n * @dev Remote storage allows you to associate addresses with an array of addresses on a standalone smart contract.\n * This could be useful when you don't want to use the local diamond storage for some purpose.\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\nabstract contract RemoteStorage {\n struct StorageConfig {\n address[] addresses;\n mapping(address => Info) info;\n }\n\n struct Info {\n bool exists;\n uint128 index;\n }\n\n mapping(address => StorageConfig) internal configs;\n\n event Added(address _address);\n event Removed(address _address);\n\n error RemoteStorage__CallerNotOwner();\n error RemoteStorage__CallerNotGuardianOrOwner();\n error RemoteStorage__AlreadyExists();\n error RemoteStorage__NotFound();\n error RemoteStorage__CallerNotGuardian();\n\n bytes4 constant IS_GUARDIAN_SELECTOR =\n bytes4(keccak256(\"isGuardian(address)\"));\n bytes4 constant GUARDIAN_COUNT = bytes4(keccak256(\"guardianCount()\"));\n\n /**\n * @notice Modifier to only allow the self to call. Reverts otherwise\n */\n modifier onlyWallet(address _wallet) {\n if (msg.sender != _wallet) revert RemoteStorage__CallerNotOwner();\n _;\n }\n\n /**\n * @notice Enfore the callet to be wallet of guardian of the wallet\n * @param _wallet Address of wallet\n */\n function enforceGuardianOrWallet(address _wallet) internal view {\n if (msg.sender == _wallet) return;\n address facetAddress = IDiamondLoupe(_wallet).facetAddress(\n IS_GUARDIAN_SELECTOR\n );\n if (facetAddress != address(0))\n if (IGuardianFacet(_wallet).isGuardian(msg.sender)) return;\n revert RemoteStorage__CallerNotGuardianOrOwner();\n }\n\n /**\n * @notice Enforce the caller to be wallet IF guardians doesn't exists and only guardian when guardians exists\n * @param _wallet Target wallet address to be handled by infrastructure contracts\n */\n function enforceWalletOrGuardianIfExists(address _wallet) internal view {\n address facetAddress;\n if (msg.sender == _wallet) {\n facetAddress = IDiamondLoupe(_wallet).facetAddress(GUARDIAN_COUNT);\n if (facetAddress == address(0)) return;\n uint256 guardianCount = IGuardianFacet(_wallet).guardianCount();\n if (guardianCount != 0) revert RemoteStorage__CallerNotGuardian();\n return;\n }\n facetAddress = IDiamondLoupe(_wallet).facetAddress(\n IS_GUARDIAN_SELECTOR\n );\n if (facetAddress != address(0))\n if (IGuardianFacet(_wallet).isGuardian(msg.sender)) return;\n\n revert RemoteStorage__CallerNotGuardianOrOwner();\n }\n\n /**\n * @notice Add address to storage and reverts if the address already exists.\n * This is an internal function callable from contracts that inherit this abstract contract\n * @param _wallet Address of wallet to add the address\n * @param _address Address to be added to wallet\n */\n function addAddress(address _wallet, address _address) internal {\n StorageConfig storage config = configs[_wallet];\n if (config.info[_address].exists) revert RemoteStorage__AlreadyExists();\n\n config.info[_address].exists = true;\n config.info[_address].index = uint128(config.addresses.length);\n config.addresses.push(_address);\n\n emit Added(_address);\n }\n\n /**\n * @notice Remove address from storage and reverts if the address already exists.\n * This is an internal function callable from contracts that inherit this abstract contract\n * @param _wallet Address of wallet to remove the address\n * @param _address Address to be removed from wallet\n */\n function removeAddress(address _wallet, address _address) internal {\n StorageConfig storage config = configs[_wallet];\n if (!config.info[_address].exists) revert RemoteStorage__NotFound();\n\n address lastAddress = config.addresses[config.addresses.length - 1];\n if (_address != lastAddress) {\n uint128 targetIndex = config.info[_address].index;\n config.addresses[targetIndex] = lastAddress;\n config.info[lastAddress].index = targetIndex;\n }\n config.addresses.pop();\n delete config.info[_address];\n\n emit Removed(_address);\n }\n\n /**\n * @notice Returns the address added to the given wallet\n * @param _wallet Address of wallet to fetch the addresses added to it\n * @return addresses List of addresses added to the wallet\n */\n function getAddresses(\n address _wallet\n ) internal view returns (address[] memory addresses) {\n StorageConfig storage config = configs[_wallet];\n addresses = new address[](config.addresses.length);\n uint addressesLen = config.addresses.length;\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns bool value checking if the address exists in the given wallet address\n * @param _wallet Wallet address to check\n * @param _address Address to fetch if the address if added to given wallet\n * @return exists_ Bool value showing if the address exists in wallet\n */\n function exists(\n address _wallet,\n address _address\n ) internal view returns (bool exists_) {\n exists_ = configs[_wallet].info[_address].exists;\n }\n\n /**\n * @notice Returns the number of addresses added to the wallet\n * @param _wallet Address of wallet to check\n * @return count_ Number of addresses added to wallet\n */\n function count(address _wallet) internal view returns (uint256 count_) {\n count_ = configs[_wallet].addresses.length;\n }\n}\n" + }, + "contracts/infrastructure/SecurityManager.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport {ISecurityManager} from \"./interfaces/ISecurityManager.sol\";\n\n/**\n * @title Security Manager\n * @dev Infrastructure contract to manage security parameters of users\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract SecurityManager is ISecurityManager, Ownable2Step {\n uint128 public minAdditionSecurityPeriod;\n uint128 public maxAdditionSecurityPeriod;\n uint128 private defaultAdditionSecurityPeriod;\n\n uint128 public minRemovalSecurityPeriod;\n uint128 public maxRemovalSecurityPeriod;\n uint128 private defaultRemovalSecurityPeriod;\n\n uint128 public minSecurityWindow;\n uint128 public maxSecurityWindow;\n uint128 private defaultSecurityWindow;\n\n uint128 public minRecoveryPeriod;\n uint128 public maxRecoveryPeriod;\n uint128 private defaultRecoveryPeriod;\n\n uint128 public minLockPeriod;\n uint128 public maxLockPeriod;\n uint128 private defaultLockPeriod;\n\n uint128 public minApprovalValidationPeriod;\n uint128 public maxApprovalValidationPeriod;\n uint128 private defaultApprovalValidationPeriod;\n\n uint128 public minMigrationPeriod;\n uint128 public maxMigrationPeriod;\n uint128 private defaultMigrationPeriod;\n\n bool public _isAdditionSecurityPeriodInitialized;\n bool public _isRemovalSecurityPeriodInitialized;\n bool public _isSecurityWindowInitialized;\n bool public _isRecoveryPeriodInitialized;\n bool public _isLockPeriodInitialized;\n bool public _isApprovalValidationPeriodInitialized;\n bool public _isMigrationPeriodInitialized;\n\n mapping(address => CustomSecurityConfig) securityConfigs;\n\n struct CustomSecurityConfig {\n uint128 additionSecurityPeriod;\n uint128 removalSecurityPeriod;\n uint128 securityWindow;\n uint128 recoveryPeriod;\n uint128 lockPeriod;\n uint128 approvalValidationPeriod;\n uint128 migrationPeriod;\n }\n\n /**\n * @notice Modifier to only allow wallet itself to make a call to wallet\n */\n modifier onlyWallet(address _wallet) {\n if (msg.sender != _wallet) revert SecurityManager__CallerNotWallet();\n _;\n }\n\n /**\n * @notice Modifier to revert if the variable is already initialized\n */\n modifier initializer(bool _isInitialized) {\n if (_isInitialized) revert SecurityManager__AlreadyIntialized();\n _;\n }\n\n /**\n * @notice Transfers the ownership of the contract to the given owner\n * @param _owner Address of owner who has access to initialize the default security variables for security manager\n */\n constructor(address _owner) {\n transferOwnership(_owner);\n _transferOwnership(_owner);\n }\n\n /**\n * @notice Sets the initial default/min/max addition security period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultAdditionSecurityPeriod Default Addition Security Period for all Barz contracts\n * @param _minAdditionSecurityPeriod Minimum Addition Security Period for all Barz contracts\n * @param _maxAdditionSecurityPeriod Maximum Addition Security Period for all Barz contracts\n */\n function initializeAdditionSecurityPeriod(\n uint128 _defaultAdditionSecurityPeriod,\n uint128 _minAdditionSecurityPeriod,\n uint128 _maxAdditionSecurityPeriod\n )\n external\n override\n onlyOwner\n initializer(_isAdditionSecurityPeriodInitialized)\n {\n _isAdditionSecurityPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultAdditionSecurityPeriod,\n _minAdditionSecurityPeriod,\n _maxAdditionSecurityPeriod\n );\n defaultAdditionSecurityPeriod = _defaultAdditionSecurityPeriod;\n minAdditionSecurityPeriod = _minAdditionSecurityPeriod;\n maxAdditionSecurityPeriod = _maxAdditionSecurityPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max removal security period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultRemovalSecurityPeriod Default Removal Security Period for all Barz contracts\n * @param _minRemovalSecurityPeriod Minimum Removal Security Period for all Barz contracts\n * @param _maxRemovalSecurityPeriod Maximum Removal Security Period for all Barz contracts\n */\n function initializeRemovalSecurityPeriod(\n uint128 _defaultRemovalSecurityPeriod,\n uint128 _minRemovalSecurityPeriod,\n uint128 _maxRemovalSecurityPeriod\n )\n external\n override\n onlyOwner\n initializer(_isRemovalSecurityPeriodInitialized)\n {\n _isRemovalSecurityPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultRemovalSecurityPeriod,\n _minRemovalSecurityPeriod,\n _maxRemovalSecurityPeriod\n );\n defaultRemovalSecurityPeriod = _defaultRemovalSecurityPeriod;\n minRemovalSecurityPeriod = _minRemovalSecurityPeriod;\n maxRemovalSecurityPeriod = _maxRemovalSecurityPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/maxd security window for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultSecurityWindow Default Security Window for all Barz contracts\n * @param _minSecurityWindow Minimum Security Window for all Barz contracts\n * @param _maxSecurityWindow Maximum Security Window for all Barz contracts\n */\n function initializeSecurityWindow(\n uint128 _defaultSecurityWindow,\n uint128 _minSecurityWindow,\n uint128 _maxSecurityWindow\n ) external override onlyOwner initializer(_isSecurityWindowInitialized) {\n _isSecurityWindowInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultSecurityWindow,\n _minSecurityWindow,\n _maxSecurityWindow\n );\n defaultSecurityWindow = _defaultSecurityWindow;\n minSecurityWindow = _minSecurityWindow;\n maxSecurityWindow = _maxSecurityWindow;\n }\n\n /**\n * @notice Sets the initial default/min/max recovery period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultRecoveryPeriod Default Recovery Period for all Barz contracts\n * @param _minRecoveryPeriod Minimum Recovery Period for all Barz contracts\n * @param _maxRecoveryPeriod Maximum Recovery Period for all Barz contracts\n */\n function initializeRecoveryPeriod(\n uint128 _defaultRecoveryPeriod,\n uint128 _minRecoveryPeriod,\n uint128 _maxRecoveryPeriod\n ) external override onlyOwner initializer(_isRecoveryPeriodInitialized) {\n _isRecoveryPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultRecoveryPeriod,\n _minRecoveryPeriod,\n _maxRecoveryPeriod\n );\n defaultRecoveryPeriod = _defaultRecoveryPeriod;\n minRecoveryPeriod = _minRecoveryPeriod;\n maxRecoveryPeriod = _maxRecoveryPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max lock period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultLockPeriod Default Lock Period for all Barz contracts\n * @param _minLockPeriod Minimum Lock Period for all Barz contracts\n * @param _maxLockPeriod Maximum Lock Period for all Barz contracts\n */\n function initializeLockPeriod(\n uint128 _defaultLockPeriod,\n uint128 _minLockPeriod,\n uint128 _maxLockPeriod\n ) external override onlyOwner initializer(_isLockPeriodInitialized) {\n _isLockPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultLockPeriod,\n _minLockPeriod,\n _maxLockPeriod\n );\n defaultLockPeriod = _defaultLockPeriod;\n minLockPeriod = _minLockPeriod;\n maxLockPeriod = _maxLockPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max approval validation period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultApprovalValidationPeriod Default Approval Validation Period for all Barz contracts\n * @param _minApprovalValidationPeriod Minimum Approval Validation Period for all Barz contracts\n * @param _maxApprovalValidationPeriod Maximum Approval Validation Period for all Barz contracts\n */\n function initializeApprovalValidationPeriod(\n uint128 _defaultApprovalValidationPeriod,\n uint128 _minApprovalValidationPeriod,\n uint128 _maxApprovalValidationPeriod\n )\n external\n override\n onlyOwner\n initializer(_isApprovalValidationPeriodInitialized)\n {\n _isApprovalValidationPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultApprovalValidationPeriod,\n _minApprovalValidationPeriod,\n _maxApprovalValidationPeriod\n );\n defaultApprovalValidationPeriod = _defaultApprovalValidationPeriod;\n minApprovalValidationPeriod = _minApprovalValidationPeriod;\n maxApprovalValidationPeriod = _maxApprovalValidationPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max migration period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultMigrationPeriod Default Migration Period for all Barz contracts\n * @param _minMigrationPeriod Minimum Migration Period for all Barz contracts\n * @param _maxMigrationPeriod Maximum Migration Period for all Barz contracts\n */\n function initializeMigrationPeriod(\n uint128 _defaultMigrationPeriod,\n uint128 _minMigrationPeriod,\n uint128 _maxMigrationPeriod\n ) external override onlyOwner initializer(_isMigrationPeriodInitialized) {\n _isMigrationPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultMigrationPeriod,\n _minMigrationPeriod,\n _maxMigrationPeriod\n );\n defaultMigrationPeriod = _defaultMigrationPeriod;\n minMigrationPeriod = _minMigrationPeriod;\n maxMigrationPeriod = _maxMigrationPeriod;\n }\n\n /**\n * @notice Wallet owner sets the addition security period for the wallet. Only the owner of wallet can call this function.\n * The addition security period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _additionSecurityPeriod Custom Addition Security Period for the wallet\n */\n function setAdditionSecurityPeriod(\n address _wallet,\n uint128 _additionSecurityPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _additionSecurityPeriod,\n minAdditionSecurityPeriod,\n maxAdditionSecurityPeriod\n );\n securityConfigs[_wallet]\n .additionSecurityPeriod = _additionSecurityPeriod;\n }\n\n /**\n * @notice Wallet owner sets the removal security period for the wallet. Only the owner of wallet can call this function.\n * The removal security period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _removalSecurityPeriod Custom Removal Security Period for the wallet\n */\n function setRemovalSecurityPeriod(\n address _wallet,\n uint128 _removalSecurityPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _removalSecurityPeriod,\n minRemovalSecurityPeriod,\n maxRemovalSecurityPeriod\n );\n securityConfigs[_wallet].removalSecurityPeriod = _removalSecurityPeriod;\n }\n\n /**\n * @notice Wallet owner sets the security window for the wallet. Only the owner of wallet can call this function.\n * The security window should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _securityWindow Custom Security Window for the wallet\n */\n function setSecurityWindow(\n address _wallet,\n uint128 _securityWindow\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _securityWindow,\n minSecurityWindow,\n maxSecurityWindow\n );\n securityConfigs[_wallet].securityWindow = _securityWindow;\n }\n\n /**\n * @notice Wallet owner sets the recovery period for the wallet. Only the owner of wallet can call this function.\n * The recovery period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _recoveryPeriod Custom recovery period for the wallet\n */\n function setRecoveryPeriod(\n address _wallet,\n uint128 _recoveryPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _recoveryPeriod,\n minRecoveryPeriod,\n maxRecoveryPeriod\n );\n securityConfigs[_wallet].recoveryPeriod = _recoveryPeriod;\n }\n\n /**\n * @notice Wallet owner sets the lock period for the wallet. Only the owner of wallet can call this function.\n * The lock period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _lockPeriod Custom Lock period for the wallet\n */\n function setLockPeriod(\n address _wallet,\n uint128 _lockPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(_lockPeriod, minLockPeriod, maxLockPeriod);\n securityConfigs[_wallet].lockPeriod = _lockPeriod;\n }\n\n /**\n * @notice Wallet owner sets the approval validation period for the wallet. Only the owner of wallet can call this function.\n * The approval validation period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _approvalValidationPeriod Custom approval validation period for the wallet\n */\n function setApprovalValidationPeriod(\n address _wallet,\n uint128 _approvalValidationPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _approvalValidationPeriod,\n minApprovalValidationPeriod,\n maxApprovalValidationPeriod\n );\n securityConfigs[_wallet]\n .approvalValidationPeriod = _approvalValidationPeriod;\n }\n\n /**\n * @notice Wallet owner sets the migration period for the wallet. Only the owner of wallet can call this function.\n * The migration period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _migrationPeriod Custom migration period for the wallet\n */\n\n function setMigrationPeriod(\n address _wallet,\n uint128 _migrationPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _migrationPeriod,\n minMigrationPeriod,\n maxMigrationPeriod\n );\n securityConfigs[_wallet].migrationPeriod = _migrationPeriod;\n }\n\n /**\n * @notice Returns the addition security period. Returns default value when custom addition security period is not set\n * @param _wallet Address of wallet\n * @return additionSecurityPeriod Addition Security Period of the given Barz account or wallet\n */\n function additionSecurityPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 additionSecurityPeriod)\n {\n additionSecurityPeriod = securityConfigs[_wallet]\n .additionSecurityPeriod;\n additionSecurityPeriod = (additionSecurityPeriod == 0)\n ? defaultAdditionSecurityPeriod\n : additionSecurityPeriod;\n }\n\n /**\n * @notice Returns the removal security period. Returns default value when custom removal security period is not set\n * @param _wallet Address of wallet\n * @return removalSecurityPeriod Removal Security Period of the given Barz account or wallet\n */\n function removalSecurityPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 removalSecurityPeriod)\n {\n removalSecurityPeriod = securityConfigs[_wallet].removalSecurityPeriod;\n removalSecurityPeriod = (removalSecurityPeriod == 0)\n ? defaultRemovalSecurityPeriod\n : removalSecurityPeriod;\n }\n\n /**\n * @notice Returns the security window. Returns default value when custom security window is not set\n * @param _wallet Address of wallet\n * @return securityWindow Security window of the given Barz account or wallet\n */\n function securityWindowOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 securityWindow)\n {\n securityWindow = securityConfigs[_wallet].securityWindow;\n securityWindow = (securityWindow == 0)\n ? defaultSecurityWindow\n : securityWindow;\n }\n\n /**\n * @notice Returns the recovery period. Returns default value when custom recovery period is not set\n * @param _wallet Address of wallet\n * @return recoveryPeriod Recovery Period of the given Barz account or wallet\n */\n function recoveryPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 recoveryPeriod)\n {\n recoveryPeriod = securityConfigs[_wallet].recoveryPeriod;\n recoveryPeriod = (recoveryPeriod == 0)\n ? defaultRecoveryPeriod\n : recoveryPeriod;\n }\n\n /**\n * @notice Returns the lock period. Returns default value when custom lock period is not set\n * @param _wallet Address of wallet\n * @return lockPeriod Lock Period of the given Barz account or wallet\n */\n function lockPeriodOf(\n address _wallet\n ) public view override onlyWallet(_wallet) returns (uint128 lockPeriod) {\n lockPeriod = securityConfigs[_wallet].lockPeriod;\n lockPeriod = (lockPeriod == 0) ? defaultLockPeriod : lockPeriod;\n }\n\n /**\n * @notice Returns the approval validation period. Returns default value when custom approval validation period is not set\n * @param _wallet Address of wallet\n * @return approvalValidationPeriod Approval Validation Period of the given Barz account or wallet\n */\n function approvalValidationPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityConfigs[_wallet]\n .approvalValidationPeriod;\n approvalValidationPeriod = (approvalValidationPeriod == 0)\n ? defaultApprovalValidationPeriod\n : approvalValidationPeriod;\n }\n\n /**\n * @notice Returns the migration period. Returns default value when custom migration period is not set\n * @param _wallet Address of wallet\n * @return migrationPeriod Migration Period of the given Barz account or wallet\n */\n function migrationPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 migrationPeriod)\n {\n migrationPeriod = securityConfigs[_wallet].migrationPeriod;\n migrationPeriod = (migrationPeriod == 0)\n ? defaultMigrationPeriod\n : migrationPeriod;\n }\n\n /**\n * @notice Validates if the period is smaller than the max period or bigger than the min period\n * @param _period Period to be checked\n * @param _minPeriod Minimum period\n * @param _maxPeriod Maximum period\n */\n function _validatePeriodBoundaries(\n uint128 _period,\n uint128 _minPeriod,\n uint128 _maxPeriod\n ) internal pure {\n if (_period >= _maxPeriod || _period <= _minPeriod)\n revert SecurityManager__OutOfBoundary();\n }\n}\n" + }, + "contracts/infrastructure/WhitelistStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {RemoteStorage} from \"./RemoteStorage.sol\";\n\n/**\n * @title Whitelist storage\n * @dev Maps addresses to the corresponsing array of whitelisted addresses for each of them.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract WhitelistStorage is RemoteStorage {\n /**\n * @dev Add the address to the whitelist storage\n * @param _wallet User wallet\n * @param _address Address to be whitelisted\n */\n function whitelistAddress(address _wallet, address _address) external {\n enforceWalletOrGuardianIfExists(_wallet);\n addAddress(_wallet, _address);\n }\n\n /**\n * @dev Removes the address from the whitelist storage\n * @param _wallet User wallet\n * @param _address Address to be removed from the whitelist\n */\n function blacklistAddress(address _wallet, address _address) external {\n enforceGuardianOrWallet(_wallet);\n removeAddress(_wallet, _address);\n }\n\n /**\n * @dev Returns whether the address exists in the whitelist storage, associated with the wallet\n * @param _wallet User wallet\n * @param _address Address to be whitelisted\n */\n function isWhitelisted(\n address _wallet,\n address _address\n ) external view returns (bool) {\n return exists(_wallet, _address);\n }\n\n /**\n * @dev Returns all whitelisted addresses associated with the wallet\n * @param _wallet User wallet\n */\n function getWhitelistedAddresses(\n address _wallet\n ) external view returns (address[] memory) {\n return getAddresses(_wallet);\n }\n}\n" + }, + "contracts/interfaces/ERC/IERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\n\npragma solidity 0.8.21;\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155Receiver {\n /**\n * @dev Handles the receipt of a single ERC1155 token type. This function is\n * called at the end of a `safeTransferFrom` after the balance has been updated.\n *\n * NOTE: To accept the transfer, this must return\n * `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n * (i.e. 0xf23a6e61, or its own function selector).\n *\n * @param operator The address which initiated the transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param id The ID of the token being transferred\n * @param value The amount of tokens being transferred\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n ) external returns (bytes4);\n\n /**\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\n * is called at the end of a `safeBatchTransferFrom` after the balances have\n * been updated.\n *\n * NOTE: To accept the transfer(s), this must return\n * `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n * (i.e. 0xbc197c81, or its own function selector).\n *\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "contracts/interfaces/ERC/IERC1271.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\ninterface IERC1271 {\n function isValidSignature(\n bytes32 hash,\n bytes memory signature\n ) external view returns (bytes4);\n}\n" + }, + "contracts/interfaces/ERC/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\ninterface IERC165 {\n /// @notice Query if a contract implements an interface\n /// @param interfaceId The interface identifier, as specified in ERC-165\n /// @dev Interface identification is specified in ERC-165. This function\n /// uses less than 30,000 gas.\n /// @return `true` if the contract implements `interfaceID` and\n /// `interfaceID` is not 0xffffffff, `false` otherwise\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/IERC173.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\n/// @title ERC-173 Contract Ownership Standard\n/// Note: the ERC-165 identifier for this interface is 0x7f5828d0\n/* is ERC165 */\ninterface IERC173 {\n /// @dev This emits when ownership of a contract changes.\n event OwnershipTransferred(\n address indexed previousOwner,\n address indexed newOwner\n );\n\n /// @notice Get the address of the owner\n /// @return owner_ The address of the owner.\n function owner() external view returns (address owner_);\n\n /// @notice Set the address of the new owner of the contract\n /// @dev Set _newOwner to address(0) to renounce any ownership.\n /// @param _newOwner The address of the new owner of the contract\n function transferOwnership(address _newOwner) external;\n}\n" + }, + "contracts/interfaces/ERC/IERC677Receiver.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\ninterface IERC677Receiver {\n function onTokenTransfer(\n address sender,\n uint value,\n bytes calldata data\n ) external pure returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155 is IERC165 {\n /**\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n */\n event TransferSingle(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256 id,\n uint256 value\n );\n\n /**\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n * transfers.\n */\n event TransferBatch(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\n\n /**\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n * `approved`.\n */\n event ApprovalForAll(\n address indexed account,\n address indexed operator,\n bool approved\n );\n\n /**\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n *\n * If an {URI} event was emitted for `id`, the standard\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n * returned by {IERC1155MetadataURI-uri}.\n */\n event URI(string value, uint256 indexed id);\n\n /**\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(\n address account,\n uint256 id\n ) external view returns (uint256);\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] calldata accounts,\n uint256[] calldata ids\n ) external view returns (uint256[] memory);\n\n /**\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n *\n * Emits an {ApprovalForAll} event.\n *\n * Requirements:\n *\n * - `operator` cannot be the caller.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n *\n * See {setApprovalForAll}.\n */\n function isApprovedForAll(\n address account,\n address operator\n ) external view returns (bool);\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes calldata data\n ) external;\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(\n address indexed owner,\n address indexed spender,\n uint256 value\n );\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` 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 amount) 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(\n address owner,\n address spender\n ) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the 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 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` 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(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(\n address spender,\n uint256 addedValue\n ) external returns (bool);\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(\n address spender,\n uint256 subtractedValue\n ) external returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(\n address indexed from,\n address indexed to,\n uint256 indexed tokenId\n );\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(\n address indexed owner,\n address indexed approved,\n uint256 indexed tokenId\n );\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(\n address indexed owner,\n address indexed operator,\n bool approved\n );\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(\n uint256 tokenId\n ) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(\n address owner,\n address operator\n ) external view returns (bool);\n}\n" + }, + "contracts/interfaces/IBarz.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Barz Interface\n * @dev Interface of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IBarz {\n error Barz__InitializationFailure();\n}\n" + }, + "contracts/interfaces/IBarzFactory.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Barz} from \"../Barz.sol\";\n\n/**\n * @title Barz Factory Interface\n * @dev Interface of contract to easily deploy Barz to a pre-computed address with a single call\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IBarzFactory {\n event BarzDeployed(address);\n\n function createAccount(\n address verificationFacet,\n bytes calldata owner,\n uint256 salt\n ) external returns (Barz);\n\n function getAddress(\n address verificationFacet,\n bytes calldata owner,\n uint256 salt\n ) external view returns (address);\n\n function getBytecode(\n address accountFacet,\n address verificationFacet,\n address entryPoint,\n address facetRegistry,\n address defaultFallback,\n bytes memory ownerPublicKey\n ) external pure returns (bytes memory);\n\n function getCreationCode() external pure returns (bytes memory);\n}\n" + }, + "contracts/libraries/DefaultLibDiamond.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\n\nerror InitializationFunctionReverted(\n address _initializationContractAddress,\n bytes _calldata\n);\n\nlibrary DefaultLibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION =\n keccak256(\"trustwallet.barz.diamond.storage\");\n\n struct FacetAddressAndPosition {\n address facetAddress;\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\n }\n\n struct FacetFunctionSelectors {\n bytes4[] functionSelectors;\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\n }\n\n struct DiamondStorage {\n // maps function selector to the facet address and\n // the position of the selector in the facetFunctionSelectors.selectors array\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\n // maps facet addresses to function selectors\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\n // facet addresses\n address[] facetAddresses;\n // Used to query if a contract implements an interface.\n // Used to implement ERC-165.\n mapping(bytes4 => bool) supportedInterfaces;\n }\n\n function diamondStorage()\n internal\n pure\n returns (DiamondStorage storage ds)\n {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n event DiamondCut(\n IDiamondCut.FacetCut[] _diamondCut,\n address _init,\n bytes _calldata\n );\n\n // Internal function version of diamondCut\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n for (\n uint256 facetIndex;\n facetIndex < _diamondCut.length;\n facetIndex++\n ) {\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\n if (action == IDiamondCut.FacetCutAction.Add) {\n addFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\n replaceFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\n removeFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else {\n revert(\"LibDiamondCut: Incorrect FacetCutAction\");\n }\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Add facet can't be address(0)\"\n );\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n require(\n oldFacetAddress == address(0),\n \"LibDiamondCut: Can't add function that already exists\"\n );\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function replaceFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Replace facet can't be address(0)\"\n );\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n require(\n oldFacetAddress != _facetAddress,\n \"LibDiamondCut: Can't replace function with same facet\"\n );\n removeFunction(ds, oldFacetAddress, selector);\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function removeFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n // if function does not exist then do nothing and return\n require(\n _facetAddress == address(0),\n \"LibDiamondCut: Remove facet address must be address(0)\"\n );\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n removeFunction(ds, oldFacetAddress, selector);\n }\n }\n\n function addFacet(\n DiamondStorage storage ds,\n address _facetAddress\n ) internal {\n enforceHasContractCode(\n _facetAddress,\n \"LibDiamondCut: New facet has no code\"\n );\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds\n .facetAddresses\n .length;\n ds.facetAddresses.push(_facetAddress);\n }\n\n function addFunction(\n DiamondStorage storage ds,\n bytes4 _selector,\n uint96 _selectorPosition,\n address _facetAddress\n ) internal {\n ds\n .selectorToFacetAndPosition[_selector]\n .functionSelectorPosition = _selectorPosition;\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(\n _selector\n );\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\n }\n\n function removeFunction(\n DiamondStorage storage ds,\n address _facetAddress,\n bytes4 _selector\n ) internal {\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Can't remove function that doesn't exist\"\n );\n // an immutable function is a function defined directly in a diamond\n require(\n _facetAddress != address(this),\n \"LibDiamondCut: Can't remove immutable function\"\n );\n // replace selector with last selector, then delete last selector\n uint256 selectorPosition = ds\n .selectorToFacetAndPosition[_selector]\n .functionSelectorPosition;\n uint256 lastSelectorPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors\n .length - 1;\n // if not the same then replace _selector with lastSelector\n if (selectorPosition != lastSelectorPosition) {\n bytes4 lastSelector = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors[lastSelectorPosition];\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[\n selectorPosition\n ] = lastSelector;\n ds\n .selectorToFacetAndPosition[lastSelector]\n .functionSelectorPosition = uint96(selectorPosition);\n }\n // delete the last selector\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\n delete ds.selectorToFacetAndPosition[_selector];\n\n // if no more selectors for facet address then delete the facet address\n if (lastSelectorPosition == 0) {\n // replace facet address with last facet address and delete last facet address\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\n uint256 facetAddressPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .facetAddressPosition;\n if (facetAddressPosition != lastFacetAddressPosition) {\n address lastFacetAddress = ds.facetAddresses[\n lastFacetAddressPosition\n ];\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\n ds\n .facetFunctionSelectors[lastFacetAddress]\n .facetAddressPosition = facetAddressPosition;\n }\n ds.facetAddresses.pop();\n delete ds\n .facetFunctionSelectors[_facetAddress]\n .facetAddressPosition;\n }\n }\n\n function initializeDiamondCut(\n address _init,\n bytes memory _calldata\n ) internal {\n if (_init == address(0)) {\n return;\n }\n enforceHasContractCode(\n _init,\n \"LibDiamondCut: _init address has no code\"\n );\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length > 0) {\n // bubble up error\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(error)\n revert(add(32, error), returndata_size)\n }\n } else {\n revert InitializationFunctionReverted(_init, _calldata);\n }\n }\n }\n\n function enforceHasContractCode(\n address _contract,\n string memory _errorMessage\n ) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize > 0, _errorMessage);\n }\n}\n" + }, + "contracts/libraries/LibAppStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SafeCast} from \"@openzeppelin/contracts/utils/math/SafeCast.sol\";\nimport {IEntryPoint} from \"../aa-4337/interfaces/IEntryPoint.sol\";\nimport {IFacetRegistry} from \"../infrastructure/interfaces/IFacetRegistry.sol\";\n\n/*\n * @title App Storage\n * @dev App storage for Barz contract to prevent storage collision\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\n\nstruct Lock {\n uint64 release;\n bytes4 locker;\n}\n\nstruct InitializersStorage {\n // NOTE: initialized is a variable to make sure the initialization is only done once.\n uint8 signerInitialized;\n uint8 accountInitialized;\n uint8 restrictionsInitialized;\n}\n\nstruct AppStorage {\n mapping(uint256 => InitializersStorage) initStorage;\n uint8 signerMigration;\n bytes4 validateOwnerSignatureSelector;\n IEntryPoint entryPoint;\n IFacetRegistry facetRegistry;\n mapping(uint256 => Lock) locks;\n}\n\nlibrary LibAppStorage {\n error LibAppStorage__AccountAlreadyUninitialized();\n error LibAppStorage__AccountMustBeUninitialized();\n error LibAppStorage__SignerAlreadyUninitialized();\n error LibAppStorage__SignerMustBeUninitialized();\n\n function appStorage() internal pure returns (AppStorage storage ds) {\n assembly {\n ds.slot := 0\n }\n }\n\n function setSignerUninitialized() internal {\n AppStorage storage s = appStorage();\n if (1 != s.initStorage[0].signerInitialized) {\n revert LibAppStorage__SignerAlreadyUninitialized();\n }\n s.initStorage[0].signerInitialized = 0;\n }\n\n function getValidateOwnerSignatureSelector()\n internal\n view\n returns (bytes4 selector)\n {\n selector = appStorage().validateOwnerSignatureSelector;\n }\n\n function setValidateOwnerSignatureSelector(\n bytes4 _validateOwnerSignatureSelector\n ) internal {\n appStorage()\n .validateOwnerSignatureSelector = _validateOwnerSignatureSelector;\n }\n\n function enforceSignerInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].signerInitialized) {\n revert LibAppStorage__SignerMustBeUninitialized();\n }\n s.initStorage[0].signerInitialized = 1;\n }\n\n function enforceAccountInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].accountInitialized) {\n revert LibAppStorage__AccountMustBeUninitialized();\n }\n s.initStorage[0].accountInitialized = 1;\n }\n\n function initiateSignerMigration() internal {\n appStorage().signerMigration = 1;\n }\n\n function enforceSignerMigration() internal view {\n if (1 != appStorage().signerMigration) {\n revert LibAppStorage__AccountMustBeUninitialized();\n }\n }\n\n function finalizeSignerMigration() internal {\n appStorage().signerMigration = 0;\n }\n\n function setLock(uint256 _releaseAfter, bytes4 _locker) internal {\n appStorage().locks[0] = Lock(SafeCast.toUint64(_releaseAfter), _locker);\n }\n\n function enforceRestrictionsInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].restrictionsInitialized)\n revert LibAppStorage__SignerMustBeUninitialized();\n s.initStorage[0].restrictionsInitialized = 1;\n }\n\n function setRestrictionsUninitialized() internal {\n AppStorage storage s = appStorage();\n if (1 != s.initStorage[0].restrictionsInitialized)\n revert LibAppStorage__AccountAlreadyUninitialized();\n s.initStorage[0].restrictionsInitialized = 0;\n }\n}\n\ncontract BarzStorage {\n AppStorage internal s;\n modifier onlyWhenUnlocked() {\n require(\n uint64(block.timestamp) >= s.locks[0].release,\n \"Account Locked\"\n );\n _;\n }\n modifier onlyWhenLocked() {\n require(\n uint64(block.timestamp) < s.locks[0].release,\n \"Account Unlocked\"\n );\n _;\n }\n}\n" + }, + "contracts/libraries/LibDiamond.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\n\nerror InitializationFunctionReverted(\n address _initializationContractAddress,\n bytes _calldata\n);\n\nlibrary LibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION =\n keccak256(\"trustwallet.barz.diamond.storage\");\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\n bytes4(keccak256(\"verifyRestrictions(address,address,uint256,bytes)\"));\n struct DiamondStorage {\n // maps function selectors to the facets that execute the functions.\n // and maps the selectors to their position in the selectorSlots array.\n // func selector => address facet, selector position\n mapping(bytes4 => bytes32) facets;\n // array of slots of function selectors.\n // each slot holds 8 function selectors.\n mapping(uint256 => bytes32) selectorSlots;\n // The number of function selectors in selectorSlots\n uint16 selectorCount;\n // Used to query if a contract implements an interface.\n // Used to implement ERC-165.\n mapping(bytes4 => bool) supportedInterfaces;\n // Default Fallback Handler of the barz.\n IDiamondLoupe defaultFallbackHandler;\n }\n\n function diamondStorage()\n internal\n pure\n returns (DiamondStorage storage ds)\n {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n function enforceIsSelf() internal view {\n require(msg.sender == address(this), \"LibDiamond: Caller not self\");\n }\n\n event DiamondCut(\n IDiamondCut.FacetCut[] _diamondCut,\n address _init,\n bytes _calldata\n );\n\n bytes32 constant CLEAR_ADDRESS_MASK =\n bytes32(uint256(0xffffffffffffffffffffffff));\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\n\n // Internal function version of diamondCut\n // This code is almost the same as the external diamondCut,\n // except it is using 'Facet[] memory _diamondCut' instead of\n // 'Facet[] calldata _diamondCut'.\n // The code is duplicated to prevent copying calldata to memory which\n // causes an error for a two dimensional array.\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n DiamondStorage storage ds = diamondStorage();\n uint256 originalSelectorCount = ds.selectorCount;\n uint256 selectorCount = originalSelectorCount;\n bytes32 selectorSlot;\n // Check if last selector slot is not full\n // \"selectorCount & 7\" is a gas efficient modulo by eight \"selectorCount % 8\"\n if (selectorCount & 7 > 0) {\n // get last selectorSlot\n // \"selectorSlot >> 3\" is a gas efficient division by 8 \"selectorSlot / 8\"\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\n }\n // loop through diamond cut\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\n selectorCount,\n selectorSlot,\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].action,\n _diamondCut[facetIndex].functionSelectors\n );\n\n unchecked {\n facetIndex++;\n }\n }\n if (selectorCount != originalSelectorCount) {\n ds.selectorCount = uint16(selectorCount);\n }\n // If last selector slot is not full\n // \"selectorCount & 7\" is a gas efficient modulo by eight \"selectorCount % 8\"\n if (selectorCount & 7 > 0) {\n // \"selectorSlot >> 3\" is a gas efficient division by 8 \"selectorSlot / 8\"\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addReplaceRemoveFacetSelectors(\n uint256 _selectorCount,\n bytes32 _selectorSlot,\n address _newFacetAddress,\n IDiamondCut.FacetCutAction _action,\n bytes4[] memory _selectors\n ) internal returns (uint256, bytes32) {\n DiamondStorage storage ds = diamondStorage();\n require(\n _selectors.length > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n if (_action == IDiamondCut.FacetCutAction.Add) {\n enforceHasContractCode(\n _newFacetAddress,\n \"LibDiamondCut: Add facet has no code\"\n );\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n require(\n address(bytes20(oldFacet)) == address(0),\n \"LibDiamondCut: Can't add function that already exists\"\n );\n // add facet for selector\n ds.facets[selector] =\n bytes20(_newFacetAddress) |\n bytes32(_selectorCount);\n // \"_selectorCount & 7\" is a gas efficient modulo by eight \"_selectorCount % 8\"\n // \" << 5 is the same as multiplying by 32 ( * 32)\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\n // clear selector position in slot and add selector\n _selectorSlot =\n (_selectorSlot &\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\n (bytes32(selector) >> selectorInSlotPosition);\n // if slot is full then write it to storage\n if (selectorInSlotPosition == 224) {\n // \"_selectorSlot >> 3\" is a gas efficient division by 8 \"_selectorSlot / 8\"\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\n _selectorSlot = 0;\n }\n _selectorCount++;\n\n unchecked {\n selectorIndex++;\n }\n }\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\n enforceHasContractCode(\n _newFacetAddress,\n \"LibDiamondCut: Replace facet has no code\"\n );\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n address oldFacetAddress = address(bytes20(oldFacet));\n // only useful if immutable functions exist\n require(\n oldFacetAddress != address(this),\n \"LibDiamondCut: Can't replace immutable function\"\n );\n require(\n oldFacetAddress != _newFacetAddress,\n \"LibDiamondCut: Can't replace function with same function\"\n );\n require(\n oldFacetAddress != address(0),\n \"LibDiamondCut: Can't replace function that doesn't exist\"\n );\n // replace old facet address\n ds.facets[selector] =\n (oldFacet & CLEAR_ADDRESS_MASK) |\n bytes20(_newFacetAddress);\n\n unchecked {\n selectorIndex++;\n }\n }\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\n require(\n _newFacetAddress == address(0),\n \"LibDiamondCut: Remove facet address must be address(0)\"\n );\n // \"_selectorCount >> 3\" is a gas efficient division by 8 \"_selectorCount / 8\"\n uint256 selectorSlotCount = _selectorCount >> 3;\n // \"_selectorCount & 7\" is a gas efficient modulo by eight \"_selectorCount % 8\"\n uint256 selectorInSlotIndex = _selectorCount & 7;\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n if (_selectorSlot == 0) {\n // get last selectorSlot\n selectorSlotCount--;\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\n selectorInSlotIndex = 7;\n } else {\n selectorInSlotIndex--;\n }\n bytes4 lastSelector;\n uint256 oldSelectorsSlotCount;\n uint256 oldSelectorInSlotPosition;\n // adding a block here prevents stack too deep error\n {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n require(\n address(bytes20(oldFacet)) != address(0),\n \"LibDiamondCut: Can't remove function that doesn't exist\"\n );\n // only useful if immutable functions exist\n require(\n address(bytes20(oldFacet)) != address(this),\n \"LibDiamondCut: Can't remove immutable function\"\n );\n // replace selector with last selector in ds.facets\n // gets the last selector\n // \" << 5 is the same as multiplying by 32 ( * 32)\n lastSelector = bytes4(\n _selectorSlot << (selectorInSlotIndex << 5)\n );\n if (lastSelector != selector) {\n // update last selector slot position info\n ds.facets[lastSelector] =\n (oldFacet & CLEAR_ADDRESS_MASK) |\n bytes20(ds.facets[lastSelector]);\n }\n delete ds.facets[selector];\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\n // \"oldSelectorCount >> 3\" is a gas efficient division by 8 \"oldSelectorCount / 8\"\n oldSelectorsSlotCount = oldSelectorCount >> 3;\n // \"oldSelectorCount & 7\" is a gas efficient modulo by eight \"oldSelectorCount % 8\"\n // \" << 5 is the same as multiplying by 32 ( * 32)\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\n }\n if (oldSelectorsSlotCount != selectorSlotCount) {\n bytes32 oldSelectorSlot = ds.selectorSlots[\n oldSelectorsSlotCount\n ];\n // clears the selector we are deleting and puts the last selector in its place.\n oldSelectorSlot =\n (oldSelectorSlot &\n ~(CLEAR_SELECTOR_MASK >>\n oldSelectorInSlotPosition)) |\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\n // update storage with the modified slot\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\n } else {\n // clears the selector we are deleting and puts the last selector in its place.\n _selectorSlot =\n (_selectorSlot &\n ~(CLEAR_SELECTOR_MASK >>\n oldSelectorInSlotPosition)) |\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\n }\n if (selectorInSlotIndex == 0) {\n delete ds.selectorSlots[selectorSlotCount];\n _selectorSlot = 0;\n }\n\n unchecked {\n selectorIndex++;\n }\n }\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\n } else {\n revert(\"LibDiamondCut: Incorrect FacetCutAction\");\n }\n return (_selectorCount, _selectorSlot);\n }\n\n function initializeDiamondCut(\n address _init,\n bytes memory _calldata\n ) internal {\n if (_init == address(0)) {\n return;\n }\n enforceHasContractCode(\n _init,\n \"LibDiamondCut: _init address has no code\"\n );\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length > 0) {\n // bubble up error\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(error)\n revert(add(32, error), returndata_size)\n }\n } else {\n revert InitializationFunctionReverted(_init, _calldata);\n }\n }\n }\n\n function enforceHasContractCode(\n address _contract,\n string memory _errorMessage\n ) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize > 0, _errorMessage);\n }\n\n function restrictionsFacet() internal view returns (address facetAddress_) {\n facetAddress_ = address(\n bytes20(\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\n )\n );\n }\n}\n" + }, + "contracts/libraries/LibFacetStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Storage\n * @dev Storage contract to store each facets variables with diamond storage\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\n\nstruct Secp256k1VerificationStorage {\n address signer;\n}\n\nstruct Secp256r1VerificationStorage {\n uint256[2] q;\n}\n\nstruct GuardianStorage {\n mapping(bytes32 => uint256) pending;\n mapping(uint8 => StorageConfig) configs;\n}\n\nstruct Info {\n bool exists;\n uint128 index;\n}\n\nstruct StorageConfig {\n address[] addresses;\n mapping(address => Info) info;\n}\n\nstruct RecoveryConfig {\n bytes recoveryPublicKey;\n uint64 executeAfter;\n}\n\nstruct ApprovalConfig {\n bool isApproved;\n uint64 validUntil;\n}\n\nstruct RecoveryApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isNewOwnerApproved;\n}\n\nstruct RecoveryStorage {\n mapping(uint8 => RecoveryConfig) recoveryConfigs;\n mapping(uint8 => RecoveryApprovalConfig) recoveryApprovalConfigs;\n uint128 nonce;\n}\n\nstruct RestrictionsStorage {\n address[] restrictions;\n mapping(address => bool) exists;\n}\n\nstruct SignatureMigrationConfig {\n bytes migrationPublicKey;\n address migrationVerificationFacet;\n bytes4[] migrationSelectors;\n uint64 migrateAfter;\n}\n\nstruct SignatureMigrationApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isMigrationApproved;\n}\n\nstruct SignatureMigrationStorage {\n mapping(uint8 => SignatureMigrationConfig) migrationConfigs;\n mapping(uint8 => SignatureMigrationApprovalConfig) migrationApprovalConfigs;\n uint128 nonce;\n}\n\nstruct DiamondCutApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isDiamondCutApproved;\n}\n\nstruct DiamondCutStorage {\n mapping(uint8 => DiamondCutApprovalConfig) diamondCutApprovalConfigs;\n uint128 nonce;\n}\n\nstruct LockStorage {\n uint128 nonce;\n}\n\nlibrary LibFacetStorage {\n bytes32 constant K1_STORAGE_POSITION =\n keccak256(\n \"v0.trustwallet.diamond.storage.Secp256k1VerificationStorage\"\n );\n bytes32 constant R1_STORAGE_POSITION =\n keccak256(\n \"v0.trustwallet.diamond.storage.Secp256r1VerificationStorage\"\n );\n bytes32 constant GUARDIAN_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.GuardianStorage\");\n bytes32 constant RECOVERY_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.RecoveryStorage\");\n bytes32 constant RESTRICTION_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.RestrictionsStorage\");\n bytes32 constant MIGRATION_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.SignatureMigrationStorage\");\n bytes32 constant DIAMONDCUT_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.DiamondCutStorage\");\n bytes32 constant LOCK_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.LockStorage\");\n\n function k1Storage()\n internal\n pure\n returns (Secp256k1VerificationStorage storage ds)\n {\n bytes32 storagePosition = K1_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function r1Storage()\n internal\n pure\n returns (Secp256r1VerificationStorage storage ds)\n {\n bytes32 storagePosition = R1_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function guardianStorage()\n internal\n pure\n returns (GuardianStorage storage ds)\n {\n bytes32 storagePosition = GUARDIAN_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function recoveryStorage()\n internal\n pure\n returns (RecoveryStorage storage ds)\n {\n bytes32 storagePosition = RECOVERY_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function restrictionsStorage()\n internal\n pure\n returns (RestrictionsStorage storage ds)\n {\n bytes32 storagePosition = RESTRICTION_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function migrationStorage()\n internal\n pure\n returns (SignatureMigrationStorage storage ds)\n {\n bytes32 storagePosition = MIGRATION_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function diamondCutStorage()\n internal\n pure\n returns (DiamondCutStorage storage ds)\n {\n bytes32 storagePosition = DIAMONDCUT_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function lockStorage() internal pure returns (LockStorage storage ds) {\n bytes32 storagePosition = LOCK_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n}\n" + }, + "contracts/libraries/LibGuardian.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibFacetStorage, StorageConfig} from \"./LibFacetStorage.sol\";\n\n/**\n * @title LibGuardian\n * @dev Internal Library to provide utility feature for Guardians stored in Guardian Facet Storage\n * @author David Yongjun Kim (@Powerstream3604)\n */\nlibrary LibGuardian {\n function majorityOfGuardians()\n internal\n view\n returns (uint256 guardianNumber)\n {\n uint256 guardianLength = guardianCount();\n guardianNumber = (guardianLength == 0) ? 0 : guardianLength / 2 + 1;\n }\n\n function isGuardian(address _guardian) internal view returns (bool) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n return config.info[_guardian].exists;\n }\n\n function guardianCount() internal view returns (uint256) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n return config.addresses.length;\n }\n\n function getGuardians() internal view returns (address[] memory) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n address[] memory addresses = new address[](config.addresses.length);\n uint256 addressesLen = config.addresses.length;\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n return addresses;\n }\n}\n" + }, + "contracts/libraries/LibLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {LibDiamond} from \"./LibDiamond.sol\";\n\n/**\n * @title LibLoupe\n * @dev Internal Library to provide utility feature for reading the state of diamond facets\n * Originally from Diamond's implementation of Mudgen(author of EIP-2535)\n */\nlibrary LibLoupe {\n /// @notice Gets all facets and their selectors.\n /// @return facets_ Facet\n function facets()\n internal\n view\n returns (IDiamondLoupe.Facet[] memory facets_)\n {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facets_ = new IDiamondLoupe.Facet[](ds.selectorCount);\n uint16[] memory numFacetSelectors = new uint16[](ds.selectorCount);\n uint256 numFacets;\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facetAddress_ = address(bytes20(ds.facets[selector]));\n bool continueLoop;\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n if (facets_[facetIndex].facetAddress == facetAddress_) {\n facets_[facetIndex].functionSelectors[\n numFacetSelectors[facetIndex]\n ] = selector;\n // probably will never have more than 256 functions from one facet contract\n require(numFacetSelectors[facetIndex] < 255);\n numFacetSelectors[facetIndex]++;\n continueLoop = true;\n break;\n }\n }\n if (continueLoop) {\n continue;\n }\n facets_[numFacets].facetAddress = facetAddress_;\n facets_[numFacets].functionSelectors = new bytes4[](\n ds.selectorCount\n );\n facets_[numFacets].functionSelectors[0] = selector;\n numFacetSelectors[numFacets] = 1;\n numFacets++;\n }\n }\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n uint256 numSelectors = numFacetSelectors[facetIndex];\n bytes4[] memory selectors = facets_[facetIndex].functionSelectors;\n // setting the number of selectors\n assembly {\n mstore(selectors, numSelectors)\n }\n }\n // setting the number of facets\n assembly {\n mstore(facets_, numFacets)\n }\n }\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n /// @return _facetFunctionSelectors The selectors associated with a facet address.\n function facetFunctionSelectors(\n address _facet\n ) internal view returns (bytes4[] memory _facetFunctionSelectors) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n uint256 numSelectors;\n _facetFunctionSelectors = new bytes4[](ds.selectorCount);\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facet = address(bytes20(ds.facets[selector]));\n if (_facet == facet) {\n _facetFunctionSelectors[numSelectors] = selector;\n numSelectors++;\n }\n }\n }\n // Set the number of selectors in the array\n assembly {\n mstore(_facetFunctionSelectors, numSelectors)\n }\n }\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses()\n internal\n view\n returns (address[] memory facetAddresses_)\n {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facetAddresses_ = new address[](ds.selectorCount);\n uint256 numFacets;\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facetAddress_ = address(bytes20(ds.facets[selector]));\n bool continueLoop;\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n if (facetAddress_ == facetAddresses_[facetIndex]) {\n continueLoop = true;\n break;\n }\n }\n if (continueLoop) {\n continue;\n }\n facetAddresses_[numFacets] = facetAddress_;\n numFacets++;\n }\n }\n // Set the number of facet addresses in the array\n assembly {\n mstore(facetAddresses_, numFacets)\n }\n }\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(\n bytes4 _functionSelector\n ) internal view returns (address facetAddress_) {\n facetAddress_ = address(\n bytes20(LibDiamond.diamondStorage().facets[_functionSelector])\n );\n }\n}\n" + }, + "contracts/libraries/LibMultiSigStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Multi-sig Storage\n * @dev Storage contract for storing Multi-sig Facet variables in diamond storage pattern\n * @author David Yongjun Kim (@Powerstream3604)\n */\n\nstruct MultiSigStorage {\n mapping(address => address) owners;\n mapping(uint256 => mapping(address => mapping(bytes32 => uint256))) approvedHashes;\n uint256 ownerCount;\n uint256 threshold;\n uint256 counter;\n}\n\nlibrary LibMultiSigStorage {\n function multisigStorage()\n internal\n pure\n returns (MultiSigStorage storage ds)\n {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.MultiSigStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n}\n" + }, + "contracts/libraries/LibRecoverSpender.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title RecoverSpender\n * @dev Library to determine the action and spender of calldata\n * @author Ruslan Serebriakov (@rsrbk)\n */\nlibrary LibRecoverSpender {\n // ERC20, ERC721 & ERC1155 transfers & approvals\n bytes4 private constant ERC20_TRANSFER =\n bytes4(keccak256(\"transfer(address,uint256)\"));\n bytes4 private constant ERC20_APPROVE =\n bytes4(keccak256(\"approve(address,uint256)\"));\n bytes4 private constant ERC20_INCREASE_ALLOWANCE =\n bytes4(keccak256(\"increaseAllowance(address,uint256)\"));\n bytes4 private constant ERC20_DECREASE_ALLOWANCE =\n bytes4(keccak256(\"decreaseAllowance(address,uint256)\"));\n bytes4 private constant ERC721_SET_APPROVAL_FOR_ALL =\n bytes4(keccak256(\"setApprovalForAll(address,bool)\"));\n bytes4 private constant ERC721_TRANSFER_FROM =\n bytes4(keccak256(\"transferFrom(address,address,uint256)\"));\n bytes4 private constant ERC721_SAFE_TRANSFER_FROM =\n bytes4(keccak256(\"safeTransferFrom(address,address,uint256)\"));\n bytes4 private constant ERC721_SAFE_TRANSFER_FROM_BYTES =\n bytes4(keccak256(\"safeTransferFrom(address,address,uint256,bytes)\"));\n bytes4 private constant ERC1155_SAFE_TRANSFER_FROM =\n bytes4(\n keccak256(\"safeTransferFrom(address,address,uint256,uint256,bytes)\")\n );\n bytes4 private constant ERC1155_SAFE_BATCH_TRANSFER_FROM =\n bytes4(\n keccak256(\n \"safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)\"\n )\n );\n\n /**\n * @notice Helper method to recover the spender from a contract call.\n * The method returns the contract unless the call is to a standard method of a ERC20/ERC721/ERC1155 token\n * in which case the spender is recovered from the data.\n * @param _to The target contract.\n * @param _data The data payload.\n */\n function _recover(\n address _to,\n bytes memory _data\n ) internal pure returns (address spender) {\n if (_data.length >= 68) {\n bytes4 methodId;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n methodId := mload(add(_data, 0x20))\n }\n if (\n methodId == ERC20_TRANSFER ||\n methodId == ERC20_APPROVE ||\n methodId == ERC20_INCREASE_ALLOWANCE ||\n methodId == ERC20_DECREASE_ALLOWANCE ||\n methodId == ERC721_SET_APPROVAL_FOR_ALL\n ) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n spender := mload(add(_data, 0x24))\n }\n return spender;\n }\n if (\n methodId == ERC721_TRANSFER_FROM ||\n methodId == ERC721_SAFE_TRANSFER_FROM ||\n methodId == ERC721_SAFE_TRANSFER_FROM_BYTES ||\n methodId == ERC1155_SAFE_TRANSFER_FROM ||\n methodId == ERC1155_SAFE_BATCH_TRANSFER_FROM\n ) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n spender := mload(add(_data, 0x44))\n }\n return spender;\n }\n }\n\n spender = _to;\n }\n}\n" + }, + "contracts/libraries/LibUtils.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\n\nlibrary LibUtils {\n // Internal utility functions\n function mergeArrays(\n bytes4[] memory _array1,\n bytes4[] memory _array2\n ) internal pure returns (bytes4[] memory) {\n uint256 length1 = _array1.length;\n uint256 length2 = _array2.length;\n bytes4[] memory mergedArray = new bytes4[](length1 + length2);\n\n for (uint256 i; i < length1; ) {\n mergedArray[i] = _array1[i];\n unchecked {\n ++i;\n }\n }\n\n for (uint256 i; i < length2; ) {\n mergedArray[length1 + i] = _array2[i];\n unchecked {\n ++i;\n }\n }\n\n return mergedArray;\n }\n\n function removeFacetElement(\n IDiamondLoupe.Facet[] memory _facets,\n uint256 _index\n ) internal pure returns (IDiamondLoupe.Facet[] memory) {\n require(_index < _facets.length, \"Invalid index\");\n require(_facets.length != 0, \"Invalid array\");\n\n // Create a new array with a length of `_facets.length - 1`\n IDiamondLoupe.Facet[] memory newArray = new IDiamondLoupe.Facet[](\n _facets.length - 1\n );\n uint256 newArrayLength = newArray.length;\n // Iterate over the original array, skipping the element at the specified `index`\n for (uint256 i; i < newArrayLength; ) {\n if (i < _index) {\n newArray[i] = _facets[i];\n } else {\n newArray[i] = _facets[i + 1];\n }\n unchecked {\n ++i;\n }\n }\n\n return newArray;\n }\n\n function removeElement(\n bytes4[] memory _array,\n uint256 _index\n ) internal pure returns (bytes4[] memory) {\n require(_index < _array.length, \"Invalid index\");\n require(_array.length != 0, \"Invalid array\");\n\n bytes4[] memory newArray = new bytes4[](_array.length - 1);\n uint256 newArrayLength = newArray.length;\n for (uint256 i; i < newArrayLength; ) {\n if (i < _index) {\n newArray[i] = _array[i];\n } else {\n newArray[i] = _array[i + 1];\n }\n unchecked {\n ++i;\n }\n }\n\n return newArray;\n }\n\n function setValue(\n bytes4[] memory _keys,\n address[] memory _values,\n bytes4 _key,\n address _value\n ) internal pure returns (bytes4[] memory, address[] memory) {\n uint256 index = findIndex(_keys, _key);\n uint256 keysLength = _keys.length;\n if (index < keysLength) {\n _values[index] = _value;\n } else {\n // Create new storage arrays\n bytes4[] memory newKeys = new bytes4[](keysLength + 1);\n address[] memory newValues = new address[](_values.length + 1);\n\n // Copy values to the new storage arrays\n for (uint256 i; i < keysLength; ) {\n newKeys[i] = _keys[i];\n newValues[i] = _values[i];\n\n unchecked {\n ++i;\n }\n }\n\n // Add the new key-value pair\n newKeys[keysLength] = _key;\n newValues[_values.length] = _value;\n\n return (newKeys, newValues);\n }\n\n // If the key already exists, return the original arrays\n return (_keys, _values);\n }\n\n function getValue(\n bytes4[] memory _keys,\n address[] memory _values,\n bytes4 _key\n ) internal pure returns (address) {\n uint256 index = findIndex(_keys, _key);\n if (index >= _keys.length) return address(0);\n\n return _values[index];\n }\n\n function findIndex(\n bytes4[] memory _keys,\n bytes4 _key\n ) internal pure returns (uint256) {\n uint256 keysLength = _keys.length;\n for (uint256 i; i < keysLength; ) {\n if (_keys[i] == _key) {\n return i;\n }\n unchecked {\n ++i;\n }\n }\n return keysLength;\n }\n}\n" + }, + "contracts/restrictions/IRestriction.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Interface for restrictions\n * @dev Restriction is a contract which decides whether to approve a certain kind of transaction, based on its internal logic.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface IRestriction {\n /**\n * @dev Based on restriction's internal logic, it should accept or reject a certain transaction.\n * @param from The address of the sender, that will be signing the transaction.\n * @param to The receiving address.\n * @param value Amount of ETH to transfer from sender to recipient.\n * @param _calldata Optional field to include arbitrary data.\n * @return bool value for whether the check is passed\n */\n function check(\n address from,\n address to,\n uint256 value,\n bytes calldata _calldata\n ) external returns (bool);\n}\n" + }, + "contracts/restrictions/WhitelistRestriction.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibRecoverSpender} from \"../libraries/LibRecoverSpender.sol\";\nimport {WhitelistStorage} from \"../infrastructure/WhitelistStorage.sol\";\nimport {IRestriction} from \"./IRestriction.sol\";\n\n/**\n * @title Whitelist Restriction\n * @dev This restriction defines a list of accepted addresses and denies any interaction with addresses outside of it.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract WhitelistRestriction is IRestriction {\n WhitelistStorage public immutable whitelistStorage;\n\n constructor(WhitelistStorage _whitelistStorage) {\n whitelistStorage = _whitelistStorage;\n }\n\n /**\n * @notice Helper method to recover the spender from a contract call.\n * The method returns the contract unless the call is to a standard method of a ERC20/ERC721/ERC1155 token\n * in which case the spender is recovered from the data.\n * @param _to The target contract.\n * @param _data The data payload.\n */\n function recoverSpender(\n address _to,\n bytes memory _data\n ) public pure returns (address spender) {\n return LibRecoverSpender._recover(_to, _data);\n }\n\n /*\n * @dev IRestriction's implementation. It will allow transaction if the sender is whitelisted, or user, or the whitelist storage.\n * @param _from The address of the sender, that will be signing the transaction.\n * @param _to The receiving address.\n * @param _calldata Optional field to include arbitrary data.\n * @return result value for whether the check is passed\n */\n function check(\n address _from,\n address _to,\n uint256 /*_value*/,\n bytes calldata _calldata\n ) external view override returns (bool result) {\n return\n whitelistStorage.isWhitelisted(\n _from,\n LibRecoverSpender._recover(_to, _calldata)\n ) ||\n _to == address(whitelistStorage) ||\n _to == msg.sender;\n }\n}\n" + }, + "contracts/test/Counter.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\ncontract TestCounter {\n int private count = 0;\n\n function incrementCounter() public {\n count += 1;\n }\n\n function decrementCounter() public {\n count -= 1;\n }\n\n function getCount() public view returns (int) {\n return count;\n }\n}\n" + }, + "contracts/test/TestERC1155.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC1155/ERC1155.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\n\ncontract TestERC1155 is ERC1155 {\n using Counters for Counters.Counter;\n\n Counters.Counter private _tokenIds;\n\n constructor() ERC1155(\"\") {}\n\n function mint(address account, uint256 amount) external {\n uint256 tokenId = _getNextTokenId();\n _mint(account, tokenId, amount, \"\");\n }\n\n function mintBatch(\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes memory data\n ) external {\n require(\n ids.length == amounts.length,\n \"TestERC1155: arrays length mismatch\"\n );\n\n _mintBatch(to, ids, amounts, data);\n }\n\n function _getNextTokenId() private returns (uint256) {\n _tokenIds.increment();\n return _tokenIds.current();\n }\n}\n" + }, + "contracts/test/TestERC777.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC777/ERC777.sol\";\n\ncontract TestERC777 is ERC777 {\n constructor(\n address[] memory _operators\n ) ERC777(\"TestERC777\", \"TERC777\", _operators) {}\n\n function mint(address account, uint256 amount) external {\n _mint(account, amount, \"\", \"\");\n }\n}\n" + }, + "contracts/test/TestInvalidSecp256k1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IVerificationFacet} from \"../facets/interfaces/IVerificationFacet.sol\";\nimport {IERC1271} from \"../interfaces/ERC/IERC1271.sol\";\nimport {AppStorage, LibAppStorage, BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {LibFacetStorage, Secp256k1VerificationStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {UserOperation} from \"../aa-4337/interfaces/UserOperation.sol\";\n\n/**\n * @title Test Secp256k1 verification facet\n * @dev Default Ethereum's elliptic curve\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract TestInvalidSecp256k1VerificationFacet is BarzStorage, IERC1271 {\n using ECDSA for bytes32;\n error Secp256k1VerificationFacet__InvalidSignerLength();\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n\n event SignerUninitialized();\n\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n }\n\n // THIS INVALID FACET DOES NOT INCLUDE initializeSigner()\n // THIS FACET IS USED TO TEST WHEN initializeSigner() DOESN'T EXIST IN FACET\n\n function uninitializeSigner() external returns (uint256 uninitSuccess) {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view returns (uint256 validationData) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n return validateSignature(userOp, userOpHash, k1Storage.signer);\n }\n\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n address signer\n ) public pure returns (uint256) {\n bytes32 hash = userOpHash.toEthSignedMessageHash();\n if (signer != hash.recover(userOp.signature)) return 1;\n return 0;\n }\n\n // This is REMOVED for testing purpose\n function validateOwnerSignatureSelector() public pure returns (bytes4) {\n // return this.validateOwnerSignature.selector;\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n function owner() public view returns (bytes memory) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n return abi.encodePacked(k1Storage.signer);\n }\n\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure returns (bool) {\n return (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (_hash.recover(_signature) ==\n LibFacetStorage.k1Storage().signer)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n}\n" + }, + "contracts/test/TestNFT.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\n\ncontract TestNFT is ERC721 {\n using Counters for Counters.Counter;\n Counters.Counter private currentTokenId;\n\n constructor() ERC721(\"TestNFT\", \"TNFT\") {}\n\n function mint(address recipient) public returns (uint256) {\n currentTokenId.increment();\n uint256 newItemId = currentTokenId.current();\n _safeMint(recipient, newItemId);\n return newItemId;\n }\n}\n" + }, + "contracts/test/TestToken.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract TestToken is ERC20 {\n constructor()\n // solhint-disable-next-line no-empty-blocks\n ERC20(\"TST\", \"TestToken\")\n {}\n\n function mint(address sender, uint256 amount) external {\n _mint(sender, amount);\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 999999 + }, + "evmVersion": "paris", + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/deployments/polygon/.chainId b/deployments/polygon/.chainId new file mode 100644 index 0000000..0973804 --- /dev/null +++ b/deployments/polygon/.chainId @@ -0,0 +1 @@ +137 \ No newline at end of file diff --git a/deployments/polygon/AccountFacet.json b/deployments/polygon/AccountFacet.json new file mode 100644 index 0000000..d56014d --- /dev/null +++ b/deployments/polygon/AccountFacet.json @@ -0,0 +1,607 @@ +{ + "address": "0xFde53272dcd7938d16E031A6989753c321728332", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "AccountFacet__CallNotSuccessful", + "type": "error" + }, + { + "inputs": [], + "name": "AccountFacet__InitializationFailure", + "type": "error" + }, + { + "inputs": [], + "name": "AccountFacet__InvalidArrayLength", + "type": "error" + }, + { + "inputs": [], + "name": "AccountFacet__NonExistentVerificationFacet", + "type": "error" + }, + { + "inputs": [], + "name": "AccountFacet__RestrictionsFailure", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_initializationContractAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "InitializationFunctionReverted", + "type": "error" + }, + { + "inputs": [], + "name": "LibAppStorage__AccountMustBeUninitialized", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract IEntryPoint", + "name": "entryPoint", + "type": "address" + }, + { + "indexed": true, + "internalType": "bytes", + "name": "ownerPublicKey", + "type": "bytes" + } + ], + "name": "AccountInitialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "indexed": false, + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "DiamondCut", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "VerificationFailure", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "VerificationSuccess", + "type": "event" + }, + { + "inputs": [], + "name": "entryPoint", + "outputs": [ + { + "internalType": "contract IEntryPoint", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_dest", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_func", + "type": "bytes" + } + ], + "name": "execute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_dest", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "_value", + "type": "uint256[]" + }, + { + "internalType": "bytes[]", + "name": "_func", + "type": "bytes[]" + } + ], + "name": "executeBatch", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getNonce", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_verificationFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_anEntryPoint", + "type": "address" + }, + { + "internalType": "address", + "name": "_facetRegistry", + "type": "address" + }, + { + "internalType": "address", + "name": "_defaultFallBackHandler", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_ownerPublicKey", + "type": "bytes" + } + ], + "name": "initialize", + "outputs": [ + { + "internalType": "uint256", + "name": "initSuccess", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "initCode", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "callGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "verificationGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "preVerificationGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxFeePerGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPriorityFeePerGas", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "paymasterAndData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "internalType": "struct UserOperation", + "name": "userOp", + "type": "tuple" + }, + { + "internalType": "bytes32", + "name": "userOpHash", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "missingAccountFunds", + "type": "uint256" + } + ], + "name": "validateUserOp", + "outputs": [ + { + "internalType": "uint256", + "name": "validationData", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0x0bf3e09ce58fd1fbb277236894712f4f810257935b0995345be8a4fec6a08956", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 38, + "gasUsed": "2369950", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000008000000000000000000000000000000000000000000000000000000000800000000000000000000100000000000000000000000000001000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000201000000000000000000000020000000000000000000000000000000000004200000000000000000001000000000000000000000000000000100000000000000000000000000000000000000000000000000000000020000000000000100000", + "blockHash": "0xe6842658c8b30d3cd2d65c2cc717f003a01d47b94be592506241a6b5a72bf120", + "transactionHash": "0x0bf3e09ce58fd1fbb277236894712f4f810257935b0995345be8a4fec6a08956", + "logs": [ + { + "transactionIndex": 38, + "blockNumber": 50172518, + "transactionHash": "0x0bf3e09ce58fd1fbb277236894712f4f810257935b0995345be8a4fec6a08956", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x000000000000000000000000d87df9fd27b9a30fe27e7b294caaa4673f34b6b1", + "0x000000000000000000000000742d13f0b2a19c823bdd362b16305e4704b97a38" + ], + "data": "0x0000000000000000000000000000000000000000000000000162c981f599be62000000000000000000000000000000000000000000000000b8e165a8990066ff000000000000000000000000000000000000000000001aa5cda3b5ce45d95cc7000000000000000000000000000000000000000000000000b77e9c26a366a89d000000000000000000000000000000000000000000001aa5cf067f503b731b29", + "logIndex": 177, + "blockHash": "0xe6842658c8b30d3cd2d65c2cc717f003a01d47b94be592506241a6b5a72bf120" + } + ], + "blockNumber": 50172518, + "cumulativeGasUsed": "10428443", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 3, + "solcInputHash": "4356503edd8ae34e73cb6dd1c8e2fc8a", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AccountFacet__CallNotSuccessful\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AccountFacet__InitializationFailure\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AccountFacet__InvalidArrayLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AccountFacet__NonExistentVerificationFacet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AccountFacet__RestrictionsFailure\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_initializationContractAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"InitializationFunctionReverted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LibAppStorage__AccountMustBeUninitialized\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract IEntryPoint\",\"name\":\"entryPoint\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes\",\"name\":\"ownerPublicKey\",\"type\":\"bytes\"}],\"name\":\"AccountInitialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"DiamondCut\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"VerificationFailure\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"VerificationSuccess\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"entryPoint\",\"outputs\":[{\"internalType\":\"contract IEntryPoint\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_dest\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_func\",\"type\":\"bytes\"}],\"name\":\"execute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_dest\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"_value\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes[]\",\"name\":\"_func\",\"type\":\"bytes[]\"}],\"name\":\"executeBatch\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_verificationFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_anEntryPoint\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_facetRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_defaultFallBackHandler\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_ownerPublicKey\",\"type\":\"bytes\"}],\"name\":\"initialize\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"initSuccess\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"userOp\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"missingAccountFunds\",\"type\":\"uint256\"}],\"name\":\"validateUserOp\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"validationData\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"Account module contract that provides the account features and initialization of signer compatible with EIP-1271 & EIP-4337\",\"kind\":\"dev\",\"methods\":{\"execute(address,uint256,bytes)\":{\"details\":\"This method executes the calldata coming from the EntryPoint. Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\",\"params\":{\"_dest\":\"Address of destination where the call will be forwarded to\",\"_func\":\"Bytes of calldata to execute in the destination address\",\"_value\":\"Amount of native coin the owner is willing to send(e.g. ETH, BNB)\"}},\"executeBatch(address[],uint256[],bytes[])\":{\"details\":\"This method batch executes the calldata coming from the EntryPoint. Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\",\"params\":{\"_dest\":\"Array of addresses of destination where the call will be forwarded to\",\"_func\":\"Array of bytes of calldata to execute in the destination address\",\"_value\":\"Array of amount of native coin the owner is willing to send(e.g. ETH, BNB)\"}},\"initialize(address,address,address,address,bytes)\":{\"details\":\"This method can only be called during the initialization or signature migration. If the proxy contract was created without initialization, anyone can call initialize. Barz calls initialize in constructor in an atomic transaction during deployment\",\"params\":{\"_anEntryPoint\":\"Entrypoint contract defined in EIP-4337 handling the flow of UserOp\",\"_defaultFallBackHandler\":\"Middleware contract for default facets\",\"_facetRegistry\":\"Registry of Facets that hold all facet information\",\"_ownerPublicKey\":\"Bytes of owner public key\",\"_verificationFacet\":\"Facet contract handling the verificationi\"}}},\"title\":\"Account Facet\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"This constructor ensures that this contract can only be used as singleton for Proxy contracts\"},\"entryPoint()\":{\"notice\":\"Returns the address of EntryPoint contract registered to Barz account\"},\"execute(address,uint256,bytes)\":{\"notice\":\"Calls the destination with inputted calldata and value from EntryPoint\"},\"executeBatch(address[],uint256[],bytes[])\":{\"notice\":\"Batch calls the destination with inputted calldata and value from EntryPoint\"},\"getNonce()\":{\"notice\":\"Return the account nonce. This method returns the next sequential nonce. For a nonce of a specific key, use `entrypoint.getNonce(account, key)`\"},\"initialize(address,address,address,address,bytes)\":{\"notice\":\"Initializes the initial storage of the Barz contract.\"},\"validateUserOp((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256)\":{\"notice\":\"Validate user's signature and nonce. subclass doesn't need to override this method. Instead, it should override the specific internal validation methods.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/AccountFacet.sol\":\"AccountFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./math/Math.sol\\\";\\nimport \\\"./math/SignedMath.sol\\\";\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n uint256 length = Math.log10(value) + 1;\\n string memory buffer = new string(length);\\n uint256 ptr;\\n /// @solidity memory-safe-assembly\\n assembly {\\n ptr := add(buffer, add(32, length))\\n }\\n while (true) {\\n ptr--;\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\\n }\\n value /= 10;\\n if (value == 0) break;\\n }\\n return buffer;\\n }\\n }\\n\\n /**\\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\\n */\\n function toString(int256 value) internal pure returns (string memory) {\\n return string(abi.encodePacked(value < 0 ? \\\"-\\\" : \\\"\\\", toString(SignedMath.abs(value))));\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n return toHexString(value, Math.log256(value) + 1);\\n }\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n\\n /**\\n * @dev Returns true if the two strings are equal.\\n */\\n function equal(string memory a, string memory b) internal pure returns (bool) {\\n return keccak256(bytes(a)) == keccak256(bytes(b));\\n }\\n}\\n\",\"keccak256\":\"0x3088eb2868e8d13d89d16670b5f8612c4ab9ff8956272837d8e90106c59c14a0\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Strings.sol\\\";\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSA {\\n enum RecoverError {\\n NoError,\\n InvalidSignature,\\n InvalidSignatureLength,\\n InvalidSignatureS,\\n InvalidSignatureV // Deprecated in v4.8\\n }\\n\\n function _throwError(RecoverError error) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert(\\\"ECDSA: invalid signature\\\");\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert(\\\"ECDSA: invalid signature length\\\");\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert(\\\"ECDSA: invalid signature 's' value\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature` or error string. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n *\\n * Documentation for signature generation:\\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n return tryRecover(hash, v, r, s);\\n } else {\\n return (address(0), RecoverError.InvalidSignatureLength);\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature`. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, signature);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\\n uint8 v = uint8((uint256(vs) >> 255) + 27);\\n return tryRecover(hash, v, r, s);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n *\\n * _Available since v4.2._\\n */\\n function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\\n // the valid range for s in (301): 0 < s < secp256k1n \\u00f7 2 + 1, and for v in (302): v \\u2208 {27, 28}. Most\\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\\n //\\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\\n // these malleable signatures as well.\\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n return (address(0), RecoverError.InvalidSignatureS);\\n }\\n\\n // If the signature is valid (and not malleable), return the signer address\\n address signer = ecrecover(hash, v, r, s);\\n if (signer == address(0)) {\\n return (address(0), RecoverError.InvalidSignature);\\n }\\n\\n return (signer, RecoverError.NoError);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore(0x00, \\\"\\\\x19Ethereum Signed Message:\\\\n32\\\")\\n mstore(0x1c, hash)\\n message := keccak256(0x00, 0x3c)\\n }\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from `s`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n\\\", Strings.toString(s.length), s));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Typed Data, created from a\\n * `domainSeparator` and a `structHash`. This produces hash corresponding\\n * to the one signed with the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n * JSON-RPC method as part of EIP-712.\\n *\\n * See {recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n let ptr := mload(0x40)\\n mstore(ptr, \\\"\\\\x19\\\\x01\\\")\\n mstore(add(ptr, 0x02), domainSeparator)\\n mstore(add(ptr, 0x22), structHash)\\n data := keccak256(ptr, 0x42)\\n }\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Data with intended validator, created from a\\n * `validator` and `data` according to the version 0 of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x00\\\", validator, data));\\n }\\n}\\n\",\"keccak256\":\"0x809bc3edb4bcbef8263fa616c1b60ee0004b50a8a1bfa164d8f57fd31f520c58\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n enum Rounding {\\n Down, // Toward negative infinity\\n Up, // Toward infinity\\n Zero // Toward zero\\n }\\n\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow.\\n return (a & b) + (a ^ b) / 2;\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a == 0 ? 0 : (a - 1) / b + 1;\\n }\\n\\n /**\\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\\n * with further edits by Uniswap Labs also under MIT license.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\\n unchecked {\\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2^256 + prod0.\\n uint256 prod0; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division.\\n if (prod1 == 0) {\\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\\n // The surrounding unchecked block does not change this fact.\\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\\n return prod0 / denominator;\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n require(denominator > prod1, \\\"Math: mulDiv overflow\\\");\\n\\n ///////////////////////////////////////////////\\n // 512 by 256 division.\\n ///////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0].\\n uint256 remainder;\\n assembly {\\n // Compute remainder using mulmod.\\n remainder := mulmod(x, y, denominator)\\n\\n // Subtract 256 bit number from 512 bit number.\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\\n // See https://cs.stackexchange.com/q/138556/92363.\\n\\n // Does not overflow because the denominator cannot be zero at this stage in the function.\\n uint256 twos = denominator & (~denominator + 1);\\n assembly {\\n // Divide denominator by twos.\\n denominator := div(denominator, twos)\\n\\n // Divide [prod1 prod0] by twos.\\n prod0 := div(prod0, twos)\\n\\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\\n twos := add(div(sub(0, twos), twos), 1)\\n }\\n\\n // Shift in bits from prod1 into prod0.\\n prod0 |= prod1 * twos;\\n\\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\\n // four bits. That is, denominator * inv = 1 mod 2^4.\\n uint256 inverse = (3 * denominator) ^ 2;\\n\\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\\n // in modular arithmetic, doubling the correct bits in each step.\\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\\n\\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inverse;\\n return result;\\n }\\n }\\n\\n /**\\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\\n uint256 result = mulDiv(x, y, denominator);\\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\\n result += 1;\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\\n *\\n * Inspired by Henry S. Warren, Jr.'s \\\"Hacker's Delight\\\" (Chapter 11).\\n */\\n function sqrt(uint256 a) internal pure returns (uint256) {\\n if (a == 0) {\\n return 0;\\n }\\n\\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\\n //\\n // We know that the \\\"msb\\\" (most significant bit) of our target number `a` is a power of 2 such that we have\\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\\n //\\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\\n // \\u2192 `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\\n // \\u2192 `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\\n //\\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\\n uint256 result = 1 << (log2(a) >> 1);\\n\\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\\n // into the expected uint128 result.\\n unchecked {\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n return min(result, a / result);\\n }\\n }\\n\\n /**\\n * @notice Calculates sqrt(a), following the selected rounding direction.\\n */\\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = sqrt(a);\\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 2, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 128;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 64;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 32;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 16;\\n }\\n if (value >> 8 > 0) {\\n value >>= 8;\\n result += 8;\\n }\\n if (value >> 4 > 0) {\\n value >>= 4;\\n result += 4;\\n }\\n if (value >> 2 > 0) {\\n value >>= 2;\\n result += 2;\\n }\\n if (value >> 1 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log2(value);\\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 10, rounded down, of a positive value.\\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 + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 256, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n *\\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\\n */\\n function log256(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 16;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 8;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 4;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 2;\\n }\\n if (value >> 8 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log256(value);\\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe4455ac1eb7fc497bb7402579e7b4d64d928b846fce7d2b6fde06d366f21c2b3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\\n * checks.\\n *\\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\\n * easily result in undesired exploitation or bugs, since developers usually\\n * assume that overflows raise errors. `SafeCast` restores this intuition by\\n * reverting the transaction when such an operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n *\\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\\n * all math on `uint256` and `int256` and then downcasting.\\n */\\nlibrary SafeCast {\\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 * _Available since v4.7._\\n */\\n function toUint248(uint256 value) internal pure returns (uint248) {\\n require(value <= type(uint248).max, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint240(uint256 value) internal pure returns (uint240) {\\n require(value <= type(uint240).max, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint232(uint256 value) internal pure returns (uint232) {\\n require(value <= type(uint232).max, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint224(uint256 value) internal pure returns (uint224) {\\n require(value <= type(uint224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint216(uint256 value) internal pure returns (uint216) {\\n require(value <= type(uint216).max, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint208(uint256 value) internal pure returns (uint208) {\\n require(value <= type(uint208).max, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint200(uint256 value) internal pure returns (uint200) {\\n require(value <= type(uint200).max, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint192(uint256 value) internal pure returns (uint192) {\\n require(value <= type(uint192).max, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint184(uint256 value) internal pure returns (uint184) {\\n require(value <= type(uint184).max, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint176(uint256 value) internal pure returns (uint176) {\\n require(value <= type(uint176).max, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint168(uint256 value) internal pure returns (uint168) {\\n require(value <= type(uint168).max, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint160(uint256 value) internal pure returns (uint160) {\\n require(value <= type(uint160).max, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint152(uint256 value) internal pure returns (uint152) {\\n require(value <= type(uint152).max, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint144(uint256 value) internal pure returns (uint144) {\\n require(value <= type(uint144).max, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint136(uint256 value) internal pure returns (uint136) {\\n require(value <= type(uint136).max, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint128(uint256 value) internal pure returns (uint128) {\\n require(value <= type(uint128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint120(uint256 value) internal pure returns (uint120) {\\n require(value <= type(uint120).max, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint112(uint256 value) internal pure returns (uint112) {\\n require(value <= type(uint112).max, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint104(uint256 value) internal pure returns (uint104) {\\n require(value <= type(uint104).max, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint96(uint256 value) internal pure returns (uint96) {\\n require(value <= type(uint96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint88(uint256 value) internal pure returns (uint88) {\\n require(value <= type(uint88).max, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint80(uint256 value) internal pure returns (uint80) {\\n require(value <= type(uint80).max, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint72(uint256 value) internal pure returns (uint72) {\\n require(value <= type(uint72).max, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint64(uint256 value) internal pure returns (uint64) {\\n require(value <= type(uint64).max, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint56(uint256 value) internal pure returns (uint56) {\\n require(value <= type(uint56).max, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint48(uint256 value) internal pure returns (uint48) {\\n require(value <= type(uint48).max, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint40(uint256 value) internal pure returns (uint40) {\\n require(value <= type(uint40).max, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint32(uint256 value) internal pure returns (uint32) {\\n require(value <= type(uint32).max, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint24(uint256 value) internal pure returns (uint24) {\\n require(value <= type(uint24).max, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint16(uint256 value) internal pure returns (uint16) {\\n require(value <= type(uint16).max, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint8(uint256 value) internal pure returns (uint8) {\\n require(value <= type(uint8).max, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\n */\\n function toUint256(int256 value) internal pure returns (uint256) {\\n require(value >= 0, \\\"SafeCast: value must be positive\\\");\\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 * _Available since v4.7._\\n */\\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\\n downcasted = int248(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\\n downcasted = int240(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\\n downcasted = int232(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\\n downcasted = int224(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\\n downcasted = int216(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\\n downcasted = int208(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\\n downcasted = int200(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\\n downcasted = int192(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\\n downcasted = int184(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\\n downcasted = int176(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\\n downcasted = int168(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\\n downcasted = int160(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\\n downcasted = int152(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\\n downcasted = int144(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\\n downcasted = int136(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\\n downcasted = int128(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\\n downcasted = int120(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\\n downcasted = int112(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\\n downcasted = int104(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\\n downcasted = int96(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\\n downcasted = int88(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\\n downcasted = int80(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\\n downcasted = int72(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\\n downcasted = int64(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\\n downcasted = int56(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\\n downcasted = int48(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\\n downcasted = int40(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\\n downcasted = int32(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\\n downcasted = int24(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\\n downcasted = int16(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\\n downcasted = int8(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\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 require(value <= uint256(type(int256).max), \\\"SafeCast: value doesn't fit in an int256\\\");\\n return int256(value);\\n }\\n}\\n\",\"keccak256\":\"0x52a8cfb0f5239d11b457dcdd1b326992ef672714ca8da71a157255bddd13f3ad\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SignedMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard signed math utilities missing in the Solidity language.\\n */\\nlibrary SignedMath {\\n /**\\n * @dev Returns the largest of two signed numbers.\\n */\\n function max(int256 a, int256 b) internal pure returns (int256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two signed numbers.\\n */\\n function min(int256 a, int256 b) internal pure returns (int256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two signed numbers without overflow.\\n * The result is rounded towards zero.\\n */\\n function average(int256 a, int256 b) internal pure returns (int256) {\\n // Formula from the book \\\"Hacker's Delight\\\"\\n int256 x = (a & b) + ((a ^ b) >> 1);\\n return x + (int256(uint256(x) >> 255) & (a ^ b));\\n }\\n\\n /**\\n * @dev Returns the absolute unsigned value of a signed value.\\n */\\n function abs(int256 n) internal pure returns (uint256) {\\n unchecked {\\n // must be unchecked in order to support `n = type(int256).min`\\n return uint256(n >= 0 ? n : -n);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf92515413956f529d95977adc9b0567d583c6203fc31ab1c23824c35187e3ddc\",\"license\":\"MIT\"},\"contracts/aa-4337/core/BaseAccount.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-empty-blocks */\\n\\nimport \\\"../interfaces/IAccount.sol\\\";\\nimport \\\"../interfaces/IEntryPoint.sol\\\";\\nimport \\\"./Helpers.sol\\\";\\n\\n/**\\n * Basic account implementation.\\n * this contract provides the basic logic for implementing the IAccount interface - validateUserOp\\n * specific account implementation should inherit it and provide the account-specific logic\\n */\\nabstract contract BaseAccount is IAccount {\\n using UserOperationLib for UserOperation;\\n\\n //return value in case of signature failure, with no time-range.\\n // equivalent to _packValidationData(true,0,0);\\n uint256 internal constant SIG_VALIDATION_FAILED = 1;\\n\\n /**\\n * Return the account nonce.\\n * This method returns the next sequential nonce.\\n * For a nonce of a specific key, use `entrypoint.getNonce(account, key)`\\n */\\n function getNonce() public view virtual returns (uint256) {\\n return entryPoint().getNonce(address(this), 0);\\n }\\n\\n /**\\n * return the entryPoint used by this account.\\n * subclass should return the current entryPoint used by this account.\\n */\\n function entryPoint() public view virtual returns (IEntryPoint);\\n\\n /**\\n * Validate user's signature and nonce.\\n * subclass doesn't need to override this method. Instead, it should override the specific internal validation methods.\\n */\\n function validateUserOp(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n uint256 missingAccountFunds\\n ) external virtual override returns (uint256 validationData) {\\n _requireFromEntryPoint();\\n validationData = _validateSignature(userOp, userOpHash);\\n _validateNonce(userOp.nonce);\\n _payPrefund(missingAccountFunds);\\n }\\n\\n /**\\n * ensure the request comes from the known entrypoint.\\n */\\n function _requireFromEntryPoint() internal view virtual {\\n require(\\n msg.sender == address(entryPoint()),\\n \\\"account: not from EntryPoint\\\"\\n );\\n }\\n\\n /**\\n * validate the signature is valid for this message.\\n * @param userOp validate the userOp.signature field\\n * @param userOpHash convenient field: the hash of the request, to check the signature against\\n * (also hashes the entrypoint and chain id)\\n * @return validationData signature and time-range of this operation\\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\\n * otherwise, an address of an \\\"authorizer\\\" contract.\\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \\\"indefinite\\\"\\n * <6-byte> validAfter - first timestamp this operation is valid\\n * If the account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\\n */\\n function _validateSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) internal virtual returns (uint256 validationData);\\n\\n /**\\n * Validate the nonce of the UserOperation.\\n * This method may validate the nonce requirement of this account.\\n * e.g.\\n * To limit the nonce to use sequenced UserOps only (no \\\"out of order\\\" UserOps):\\n * `require(nonce < type(uint64).max)`\\n * For a hypothetical account that *requires* the nonce to be out-of-order:\\n * `require(nonce & type(uint64).max == 0)`\\n *\\n * The actual nonce uniqueness is managed by the EntryPoint, and thus no other\\n * action is needed by the account itself.\\n *\\n * @param nonce to validate\\n *\\n * solhint-disable-next-line no-empty-blocks\\n */\\n function _validateNonce(uint256 nonce) internal view virtual {}\\n\\n /**\\n * sends to the entrypoint (msg.sender) the missing funds for this transaction.\\n * subclass MAY override this method for better funds management\\n * (e.g. send to the entryPoint more than the minimum required, so that in future transactions\\n * it will not be required to send again)\\n * @param missingAccountFunds the minimum value this method should send the entrypoint.\\n * this value MAY be zero, in case there is enough deposit, or the userOp has a paymaster.\\n */\\n function _payPrefund(uint256 missingAccountFunds) internal virtual {\\n if (missingAccountFunds != 0) {\\n (bool success, ) = payable(msg.sender).call{\\n value: missingAccountFunds,\\n gas: type(uint256).max\\n }(\\\"\\\");\\n (success);\\n //ignore failure (its EntryPoint's job to verify, not account.)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa0dcc386b0f04711db3e394fb50e55a3b3b1a4d19fac1f10895844e1aa4e3d5c\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/core/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable no-inline-assembly */\\n\\n/**\\n * returned data from validateUserOp.\\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\\n * @param aggregator - address(0) - the account validated the signature by itself.\\n * address(1) - the account failed to validate the signature.\\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\\n * @param validAfter - this UserOp is valid only after this timestamp.\\n * @param validaUntil - this UserOp is valid only up to this timestamp.\\n */\\nstruct ValidationData {\\n address aggregator;\\n uint48 validAfter;\\n uint48 validUntil;\\n}\\n\\n//extract sigFailed, validAfter, validUntil.\\n// also convert zero validUntil to type(uint48).max\\nfunction _parseValidationData(\\n uint validationData\\n) pure returns (ValidationData memory data) {\\n address aggregator = address(uint160(validationData));\\n uint48 validUntil = uint48(validationData >> 160);\\n if (validUntil == 0) {\\n validUntil = type(uint48).max;\\n }\\n uint48 validAfter = uint48(validationData >> (48 + 160));\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n// intersect account and paymaster ranges.\\nfunction _intersectTimeRange(\\n uint256 validationData,\\n uint256 paymasterValidationData\\n) pure returns (ValidationData memory) {\\n ValidationData memory accountValidationData = _parseValidationData(\\n validationData\\n );\\n ValidationData memory pmValidationData = _parseValidationData(\\n paymasterValidationData\\n );\\n address aggregator = accountValidationData.aggregator;\\n if (aggregator == address(0)) {\\n aggregator = pmValidationData.aggregator;\\n }\\n uint48 validAfter = accountValidationData.validAfter;\\n uint48 validUntil = accountValidationData.validUntil;\\n uint48 pmValidAfter = pmValidationData.validAfter;\\n uint48 pmValidUntil = pmValidationData.validUntil;\\n\\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp\\n * @param data - the ValidationData to pack\\n */\\nfunction _packValidationData(\\n ValidationData memory data\\n) pure returns (uint256) {\\n return\\n uint160(data.aggregator) |\\n (uint256(data.validUntil) << 160) |\\n (uint256(data.validAfter) << (160 + 48));\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp, when not using an aggregator\\n * @param sigFailed - true for signature failure, false for success\\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\\n * @param validAfter first timestamp this UserOperation is valid\\n */\\nfunction _packValidationData(\\n bool sigFailed,\\n uint48 validUntil,\\n uint48 validAfter\\n) pure returns (uint256) {\\n return\\n (sigFailed ? 1 : 0) |\\n (uint256(validUntil) << 160) |\\n (uint256(validAfter) << (160 + 48));\\n}\\n\\n/**\\n * keccak function over calldata.\\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\\n */\\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\\n assembly {\\n let mem := mload(0x40)\\n let len := data.length\\n calldatacopy(mem, data.offset, len)\\n ret := keccak256(mem, len)\\n }\\n}\\n\",\"keccak256\":\"0xa79f06cd158ecb8c0da95493a2f348933b8627a63e228b99738bff3aa107942d\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAccount.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\ninterface IAccount {\\n /**\\n * Validate user's signature and nonce\\n * the entryPoint will make the call to the recipient only if this validation call returns successfully.\\n * signature failure should be reported by returning SIG_VALIDATION_FAILED (1).\\n * This allows making a \\\"simulation call\\\" without a valid signature\\n * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure.\\n *\\n * @dev Must validate caller is the entryPoint.\\n * Must validate the signature and nonce\\n * @param userOp the operation that is about to be executed.\\n * @param userOpHash hash of the user's request data. can be used as the basis for signature.\\n * @param missingAccountFunds missing funds on the account's deposit in the entrypoint.\\n * This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call.\\n * The excess is left as a deposit in the entrypoint, for future calls.\\n * can be withdrawn anytime using \\\"entryPoint.withdrawTo()\\\"\\n * In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero.\\n * @return validationData packaged ValidationData structure. use `_packValidationData` and `_unpackValidationData` to encode and decode\\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\\n * otherwise, an address of an \\\"authorizer\\\" contract.\\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \\\"indefinite\\\"\\n * <6-byte> validAfter - first timestamp this operation is valid\\n * If an account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\\n */\\n function validateUserOp(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n uint256 missingAccountFunds\\n ) external returns (uint256 validationData);\\n}\\n\",\"keccak256\":\"0xcbc4b0973cf954c5895b7796335f651fbfcfb55f67dfa789a3d354f8e23c4f2b\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAggregator.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\n/**\\n * Aggregated Signatures validator.\\n */\\ninterface IAggregator {\\n /**\\n * validate aggregated signature.\\n * revert if the aggregated signature does not match the given list of operations.\\n */\\n function validateSignatures(\\n UserOperation[] calldata userOps,\\n bytes calldata signature\\n ) external view;\\n\\n /**\\n * validate signature of a single userOp\\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\\n * @param userOp the userOperation received from the user.\\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\\n * (usually empty, unless account and aggregator support some kind of \\\"multisig\\\"\\n */\\n function validateUserOpSignature(\\n UserOperation calldata userOp\\n ) external view returns (bytes memory sigForUserOp);\\n\\n /**\\n * aggregate multiple signatures into a single value.\\n * This method is called off-chain to calculate the signature to pass with handleOps()\\n * bundler MAY use optimized custom code perform this aggregation\\n * @param userOps array of UserOperations to collect the signatures from.\\n * @return aggregatedSignature the aggregated signature\\n */\\n function aggregateSignatures(\\n UserOperation[] calldata userOps\\n ) external view returns (bytes memory aggregatedSignature);\\n}\\n\",\"keccak256\":\"0xdfdcd80568f037716674619b31be630fcd8316262f05a815b41d1e81782c966a\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IEntryPoint.sol\":{\"content\":\"/**\\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\\n ** Only one instance required on each chain.\\n **/\\n// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-inline-assembly */\\n/* solhint-disable reason-string */\\n\\nimport \\\"./UserOperation.sol\\\";\\nimport \\\"./IStakeManager.sol\\\";\\nimport \\\"./IAggregator.sol\\\";\\nimport \\\"./INonceManager.sol\\\";\\n\\ninterface IEntryPoint is IStakeManager, INonceManager {\\n /***\\n * An event emitted after each successful request\\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\\n * @param sender - the account that generates this request.\\n * @param paymaster - if non-null, the paymaster that pays for this request.\\n * @param nonce - the nonce value from the request.\\n * @param success - true if the sender transaction succeeded, false if reverted.\\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\\n */\\n event UserOperationEvent(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address indexed paymaster,\\n uint256 nonce,\\n bool success,\\n uint256 actualGasCost,\\n uint256 actualGasUsed\\n );\\n\\n /**\\n * account \\\"sender\\\" was deployed.\\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\\n * @param sender the account that is deployed\\n * @param factory the factory used to deploy this account (in the initCode)\\n * @param paymaster the paymaster used by this UserOp\\n */\\n event AccountDeployed(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address factory,\\n address paymaster\\n );\\n\\n /**\\n * An event emitted if the UserOperation \\\"callData\\\" reverted with non-zero length\\n * @param userOpHash the request unique identifier.\\n * @param sender the sender of this request\\n * @param nonce the nonce used in the request\\n * @param revertReason - the return bytes from the (reverted) call to \\\"callData\\\".\\n */\\n event UserOperationRevertReason(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n uint256 nonce,\\n bytes revertReason\\n );\\n\\n /**\\n * an event emitted by handleOps(), before starting the execution loop.\\n * any event emitted before this event, is part of the validation.\\n */\\n event BeforeExecution();\\n\\n /**\\n * signature aggregator used by the following UserOperationEvents within this bundle.\\n */\\n event SignatureAggregatorChanged(address indexed aggregator);\\n\\n /**\\n * a custom revert error of handleOps, to identify the offending op.\\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\\n * @param reason - revert reason\\n * The string starts with a unique code \\\"AAmn\\\", where \\\"m\\\" is \\\"1\\\" for factory, \\\"2\\\" for account and \\\"3\\\" for paymaster issues,\\n * so a failure can be attributed to the correct entity.\\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\\n */\\n error FailedOp(uint256 opIndex, string reason);\\n\\n /**\\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\\n */\\n error SignatureValidationFailed(address aggregator);\\n\\n /**\\n * Successful result from simulateValidation.\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n */\\n error ValidationResult(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo\\n );\\n\\n /**\\n * Successful result from simulateValidation, if the account returns a signature aggregator\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\\n * bundler MUST use it to verify the signature, or reject the UserOperation\\n */\\n error ValidationResultWithAggregation(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo,\\n AggregatorStakeInfo aggregatorInfo\\n );\\n\\n /**\\n * return value of getSenderAddress\\n */\\n error SenderAddressResult(address sender);\\n\\n /**\\n * return value of simulateHandleOp\\n */\\n error ExecutionResult(\\n uint256 preOpGas,\\n uint256 paid,\\n uint48 validAfter,\\n uint48 validUntil,\\n bool targetSuccess,\\n bytes targetResult\\n );\\n\\n //UserOps handled, per aggregator\\n struct UserOpsPerAggregator {\\n UserOperation[] userOps;\\n // aggregator address\\n IAggregator aggregator;\\n // aggregated signature\\n bytes signature;\\n }\\n\\n /**\\n * Execute a batch of UserOperation.\\n * no signature aggregator is used.\\n * if any account requires an aggregator (that is, it returned an aggregator when\\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\\n * @param ops the operations to execute\\n * @param beneficiary the address to receive the fees\\n */\\n function handleOps(\\n UserOperation[] calldata ops,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * Execute a batch of UserOperation with Aggregators\\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\\n * @param beneficiary the address to receive the fees\\n */\\n function handleAggregatedOps(\\n UserOpsPerAggregator[] calldata opsPerAggregator,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * generate a request Id - unique identifier for this request.\\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\\n */\\n function getUserOpHash(\\n UserOperation calldata userOp\\n ) external view returns (bytes32);\\n\\n /**\\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\\n * @param userOp the user operation to validate.\\n */\\n function simulateValidation(UserOperation calldata userOp) external;\\n\\n /**\\n * gas and return values during simulation\\n * @param preOpGas the gas used for validation (including preValidationGas)\\n * @param prefund the required prefund for this operation\\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\\n */\\n struct ReturnInfo {\\n uint256 preOpGas;\\n uint256 prefund;\\n bool sigFailed;\\n uint48 validAfter;\\n uint48 validUntil;\\n bytes paymasterContext;\\n }\\n\\n /**\\n * returned aggregated signature info.\\n * the aggregator returned by the account, and its current stake.\\n */\\n struct AggregatorStakeInfo {\\n address aggregator;\\n StakeInfo stakeInfo;\\n }\\n\\n /**\\n * Get counterfactual sender address.\\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\\n * this method always revert, and returns the address in SenderAddressResult error\\n * @param initCode the constructor code to be passed into the UserOperation.\\n */\\n function getSenderAddress(bytes memory initCode) external;\\n\\n /**\\n * simulate full execution of a UserOperation (including both validation and target execution)\\n * this method will always revert with \\\"ExecutionResult\\\".\\n * it performs full validation of the UserOperation, but ignores signature error.\\n * an optional target address is called after the userop succeeds, and its value is returned\\n * (before the entire call is reverted)\\n * Note that in order to collect the the success/failure of the target call, it must be executed\\n * with trace enabled to track the emitted events.\\n * @param op the UserOperation to simulate\\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\\n * are set to the return from that call.\\n * @param targetCallData callData to pass to target address\\n */\\n function simulateHandleOp(\\n UserOperation calldata op,\\n address target,\\n bytes calldata targetCallData\\n ) external;\\n}\\n\",\"keccak256\":\"0x9ccb1b188eda8bbf5f6c2d01bd83c3d8b2b04fcf745283051d31fe96d1d8e40f\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/INonceManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\ninterface INonceManager {\\n /**\\n * Return the next nonce for this sender.\\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\\n * But UserOp with different keys can come with arbitrary order.\\n *\\n * @param sender the account address\\n * @param key the high 192 bit of the nonce\\n * @return nonce a full nonce to pass for next UserOp with this sender.\\n */\\n function getNonce(\\n address sender,\\n uint192 key\\n ) external view returns (uint256 nonce);\\n\\n /**\\n * Manually increment the nonce of the sender.\\n * This method is exposed just for completeness..\\n * Account does NOT need to call it, neither during validation, nor elsewhere,\\n * as the EntryPoint will update the nonce regardless.\\n * Possible use-case is call it with various keys to \\\"initialize\\\" their nonces to one, so that future\\n * UserOperations will not pay extra for the first transaction with a given key.\\n */\\n function incrementNonce(uint192 key) external;\\n}\\n\",\"keccak256\":\"0xce478ad0fa0d18a3b785ac854623029e7ab463d05873dfaa365abfa1bf100912\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IStakeManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8.12;\\n\\n/**\\n * manage deposits and stakes.\\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\\n * stake is value locked for at least \\\"unstakeDelay\\\" by the staked entity.\\n */\\ninterface IStakeManager {\\n event Deposited(address indexed account, uint256 totalDeposit);\\n\\n event Withdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /// Emitted when stake or unstake delay are modified\\n event StakeLocked(\\n address indexed account,\\n uint256 totalStaked,\\n uint256 unstakeDelaySec\\n );\\n\\n /// Emitted once a stake is scheduled for withdrawal\\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\\n\\n event StakeWithdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /**\\n * @param deposit the entity's deposit\\n * @param staked true if this entity is staked.\\n * @param stake actual amount of ether staked for this entity.\\n * @param unstakeDelaySec minimum delay to withdraw the stake.\\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\\n * and the rest fit into a 2nd cell.\\n * 112 bit allows for 10^15 eth\\n * 48 bit for full timestamp\\n * 32 bit allows 150 years for unstake delay\\n */\\n struct DepositInfo {\\n uint112 deposit;\\n bool staked;\\n uint112 stake;\\n uint32 unstakeDelaySec;\\n uint48 withdrawTime;\\n }\\n\\n //API struct used by getStakeInfo and simulateValidation\\n struct StakeInfo {\\n uint256 stake;\\n uint256 unstakeDelaySec;\\n }\\n\\n /// @return info - full deposit information of given account\\n function getDepositInfo(\\n address account\\n ) external view returns (DepositInfo memory info);\\n\\n /// @return the deposit (for gas payment) of the account\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * add to the deposit of the given account\\n */\\n function depositTo(address account) external payable;\\n\\n /**\\n * add to the account's stake - amount and delay\\n * any pending unstake is first cancelled.\\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\\n */\\n function addStake(uint32 _unstakeDelaySec) external payable;\\n\\n /**\\n * attempt to unlock the stake.\\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\\n */\\n function unlockStake() external;\\n\\n /**\\n * withdraw from the (unlocked) stake.\\n * must first call unlockStake and wait for the unstakeDelay to pass\\n * @param withdrawAddress the address to send withdrawn value.\\n */\\n function withdrawStake(address payable withdrawAddress) external;\\n\\n /**\\n * withdraw from the deposit.\\n * @param withdrawAddress the address to send withdrawn value.\\n * @param withdrawAmount the amount to withdraw.\\n */\\n function withdrawTo(\\n address payable withdrawAddress,\\n uint256 withdrawAmount\\n ) external;\\n}\\n\",\"keccak256\":\"0xadcea606c9b7aafe6645441f2154a60f271330b0eee5292a632aa71c1672d546\",\"license\":\"GPL-3.0-only\"},\"contracts/aa-4337/interfaces/UserOperation.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable no-inline-assembly */\\n\\nimport {calldataKeccak} from \\\"../core/Helpers.sol\\\";\\n\\n/**\\n * User Operation struct\\n * @param sender the sender account of this request.\\n * @param nonce unique value the sender uses to verify it is not a replay.\\n * @param initCode if set, the account contract will be created by this constructor/\\n * @param callData the method call to execute on this account.\\n * @param callGasLimit the gas limit passed to the callData method call.\\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\\n * @param maxFeePerGas same as EIP-1559 gas parameter.\\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\\n */\\nstruct UserOperation {\\n address sender;\\n uint256 nonce;\\n bytes initCode;\\n bytes callData;\\n uint256 callGasLimit;\\n uint256 verificationGasLimit;\\n uint256 preVerificationGas;\\n uint256 maxFeePerGas;\\n uint256 maxPriorityFeePerGas;\\n bytes paymasterAndData;\\n bytes signature;\\n}\\n\\n/**\\n * Utility functions helpful when working with UserOperation structs.\\n */\\nlibrary UserOperationLib {\\n function getSender(\\n UserOperation calldata userOp\\n ) internal pure returns (address) {\\n address data;\\n //read sender from userOp, which is first userOp member (saves 800 gas...)\\n assembly {\\n data := calldataload(userOp)\\n }\\n return address(uint160(data));\\n }\\n\\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\\n // pay above what he signed for.\\n function gasPrice(\\n UserOperation calldata userOp\\n ) internal view returns (uint256) {\\n unchecked {\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n if (maxFeePerGas == maxPriorityFeePerGas) {\\n //legacy mode (for networks that don't support basefee opcode)\\n return maxFeePerGas;\\n }\\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\\n }\\n }\\n\\n function pack(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes memory ret) {\\n address sender = getSender(userOp);\\n uint256 nonce = userOp.nonce;\\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\\n bytes32 hashCallData = calldataKeccak(userOp.callData);\\n uint256 callGasLimit = userOp.callGasLimit;\\n uint256 verificationGasLimit = userOp.verificationGasLimit;\\n uint256 preVerificationGas = userOp.preVerificationGas;\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\\n\\n return\\n abi.encode(\\n sender,\\n nonce,\\n hashInitCode,\\n hashCallData,\\n callGasLimit,\\n verificationGasLimit,\\n preVerificationGas,\\n maxFeePerGas,\\n maxPriorityFeePerGas,\\n hashPaymasterAndData\\n );\\n }\\n\\n function hash(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes32) {\\n return keccak256(pack(userOp));\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n}\\n\",\"keccak256\":\"0x2429f5cc546bdee08c7e63858d0dda8491eaa3ab5194df884dc948c1154d2834\",\"license\":\"GPL-3.0\"},\"contracts/facets/AccountFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {ECDSA} from \\\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\\\";\\nimport {UserOperation} from \\\"../aa-4337/interfaces/UserOperation.sol\\\";\\nimport {IEntryPoint} from \\\"../aa-4337/interfaces/IEntryPoint.sol\\\";\\nimport {BaseAccount} from \\\"../aa-4337/core/BaseAccount.sol\\\";\\nimport {LibAppStorage, BarzStorage} from \\\"../libraries/LibAppStorage.sol\\\";\\nimport {LibDiamond} from \\\"../libraries/LibDiamond.sol\\\";\\nimport {LibLoupe} from \\\"../libraries/LibLoupe.sol\\\";\\nimport {IFacetRegistry} from \\\"../infrastructure/interfaces/IFacetRegistry.sol\\\";\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\nimport {IVerificationFacet} from \\\"./interfaces/IVerificationFacet.sol\\\";\\nimport {IERC1271} from \\\"../interfaces/ERC/IERC1271.sol\\\";\\nimport {IAccountFacet} from \\\"./interfaces/IAccountFacet.sol\\\";\\n\\n/**\\n * @title Account Facet\\n * @dev Account module contract that provides the account features and initialization of signer\\n * compatible with EIP-1271 & EIP-4337\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract AccountFacet is IAccountFacet, BarzStorage, BaseAccount {\\n using ECDSA for bytes32;\\n\\n /**\\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\\n */\\n constructor() {\\n LibAppStorage.enforceAccountInitialize();\\n }\\n\\n /**\\n * @notice Returns the address of EntryPoint contract registered to Barz account\\n */\\n function entryPoint() public view override returns (IEntryPoint) {\\n return s.entryPoint;\\n }\\n\\n /**\\n * @notice Initializes the initial storage of the Barz contract.\\n * @dev This method can only be called during the initialization or signature migration.\\n * If the proxy contract was created without initialization, anyone can call initialize.\\n * Barz calls initialize in constructor in an atomic transaction during deployment\\n * @param _verificationFacet Facet contract handling the verificationi\\n * @param _anEntryPoint Entrypoint contract defined in EIP-4337 handling the flow of UserOp\\n * @param _facetRegistry Registry of Facets that hold all facet information\\n * @param _defaultFallBackHandler Middleware contract for default facets\\n * @param _ownerPublicKey Bytes of owner public key\\n */\\n function initialize(\\n address _verificationFacet,\\n address _anEntryPoint,\\n address _facetRegistry,\\n address _defaultFallBackHandler,\\n bytes calldata _ownerPublicKey\\n ) public override returns (uint256 initSuccess) {\\n LibAppStorage.enforceAccountInitialize();\\n s.entryPoint = IEntryPoint(_anEntryPoint);\\n s.facetRegistry = IFacetRegistry(_facetRegistry);\\n LibDiamond.diamondStorage().defaultFallbackHandler = IDiamondLoupe(\\n _defaultFallBackHandler\\n );\\n\\n _cutDiamondAccountFacet(_verificationFacet);\\n\\n bytes memory initCall = abi.encodeWithSignature(\\n \\\"initializeSigner(bytes)\\\",\\n _ownerPublicKey\\n );\\n // Every Verification Facet should comply with initializeSigner(bytes)\\n // to be compatible with the Barz contract(for initialization)\\n (bool success, bytes memory result) = _verificationFacet.delegatecall(\\n initCall\\n );\\n if (!success || uint256(bytes32(result)) != 1) {\\n revert AccountFacet__InitializationFailure();\\n }\\n\\n initSuccess = 1;\\n emit AccountInitialized(s.entryPoint, _ownerPublicKey);\\n }\\n\\n function _cutDiamondAccountFacet(address _verificationFacet) internal {\\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](1);\\n\\n bytes4 ownerVerificationFuncSelector = IVerificationFacet(\\n _verificationFacet\\n ).validateOwnerSignatureSelector();\\n\\n bytes4[] memory verificationFunctionSelectors = new bytes4[](3);\\n verificationFunctionSelectors[0] = IERC1271.isValidSignature.selector;\\n verificationFunctionSelectors[1] = ownerVerificationFuncSelector;\\n verificationFunctionSelectors[2] = IVerificationFacet.owner.selector;\\n cut[0] = IDiamondCut.FacetCut({\\n facetAddress: _verificationFacet,\\n action: IDiamondCut.FacetCutAction.Add,\\n functionSelectors: verificationFunctionSelectors\\n });\\n\\n LibDiamond.diamondCut(cut, address(0), \\\"\\\");\\n }\\n\\n /**\\n * @notice Calls the destination with inputted calldata and value from EntryPoint\\n * @dev This method executes the calldata coming from the EntryPoint.\\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\\n * @param _dest Address of destination where the call will be forwarded to\\n * @param _value Amount of native coin the owner is willing to send(e.g. ETH, BNB)\\n * @param _func Bytes of calldata to execute in the destination address\\n */\\n function execute(\\n address _dest,\\n uint256 _value,\\n bytes calldata _func\\n ) external override onlyWhenUnlocked {\\n _requireFromEntryPoint();\\n address restrictionsFacet = LibDiamond.restrictionsFacet();\\n if (restrictionsFacet == address(0)) _call(_dest, _value, _func);\\n else _callWithRestrictions(_dest, _value, _func, restrictionsFacet);\\n }\\n\\n /**\\n * @notice Batch calls the destination with inputted calldata and value from EntryPoint\\n * @dev This method batch executes the calldata coming from the EntryPoint.\\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\\n * @param _dest Array of addresses of destination where the call will be forwarded to\\n * @param _value Array of amount of native coin the owner is willing to send(e.g. ETH, BNB)\\n * @param _func Array of bytes of calldata to execute in the destination address\\n */\\n function executeBatch(\\n address[] calldata _dest,\\n uint256[] calldata _value,\\n bytes[] calldata _func\\n ) external override onlyWhenUnlocked {\\n _requireFromEntryPoint();\\n if (_dest.length != _func.length || _dest.length != _value.length)\\n revert AccountFacet__InvalidArrayLength();\\n address restrictionsFacet = LibDiamond.restrictionsFacet();\\n if (restrictionsFacet == address(0)) {\\n for (uint256 i; i < _dest.length; ) {\\n _call(_dest[i], _value[i], _func[i]);\\n unchecked {\\n ++i;\\n }\\n }\\n } else {\\n for (uint256 i; i < _dest.length; ) {\\n _callWithRestrictions(\\n _dest[i],\\n _value[i],\\n _func[i],\\n restrictionsFacet\\n );\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n }\\n\\n /**\\n * @notice Validates the signature field of UserOperation\\n * @dev This method validates if the signature of UserOp is indeed valid by delegating the call to Verification Facet\\n * Barz makes a call to the pre-registered Verification Facet address in App Storage\\n * @param _userOp UserOperation from owner to be validated\\n * @param _userOpHash Hash of UserOperation given from the EntryPoint contract\\n */\\n function _validateSignature(\\n UserOperation calldata _userOp,\\n bytes32 _userOpHash\\n ) internal override returns (uint256 validationData) {\\n // Get Facet with Function Selector\\n address facet = LibLoupe.facetAddress(s.validateOwnerSignatureSelector);\\n if (facet == address(0))\\n revert AccountFacet__NonExistentVerificationFacet();\\n\\n // Make function call to VerificationFacet\\n bytes memory validateCall = abi.encodeWithSelector(\\n s.validateOwnerSignatureSelector,\\n _userOp,\\n _userOpHash\\n );\\n (bool success, bytes memory result) = facet.delegatecall(validateCall);\\n if (!success) revert AccountFacet__CallNotSuccessful();\\n validationData = uint256(bytes32(result));\\n if (validationData == 0) emit VerificationSuccess(_userOpHash);\\n else emit VerificationFailure(_userOpHash);\\n }\\n\\n /**\\n * @notice Calls the target with the inputted value and calldata\\n * @dev This method is the actual function in Barz that makes a call with an arbitrary owner-given data\\n * @param _target Address of the destination contract which the call is getting forwarded to\\n * @param _value Amount of Native coin the owner is wanting to make in this call\\n * @param _data Calldata the owner is forwarding together in the call e.g. Swap/Token Transfer\\n */\\n function _call(\\n address _target,\\n uint256 _value,\\n bytes memory _data\\n ) internal {\\n (bool success, bytes memory result) = _target.call{value: _value}(\\n _data\\n );\\n if (!success) {\\n assembly {\\n revert(add(result, 32), mload(result))\\n }\\n }\\n }\\n\\n /**\\n * @notice Calls the target with the inputted value and calldata together with restrictions check\\n * @dev This method is the actual function in Barz that makes a call with an arbitrary owner-given data\\n * @param _target Address of the destination contract which the call is getting forwarded to\\n * @param _value Amount of Native coin the owner is wanting to make in this call\\n * @param _data Calldata the owner is forwarding together in the call e.g. Swap/Token Transfer\\n * @param _restrictionsFacet Address of Facet to validate restrictions\\n */\\n function _callWithRestrictions(\\n address _target,\\n uint256 _value,\\n bytes memory _data,\\n address _restrictionsFacet\\n ) internal {\\n // NOTE: No restrictions facet, so restriction validation passes\\n if (_checkRestrictions(_restrictionsFacet, _target, _value, _data) != 0)\\n revert AccountFacet__RestrictionsFailure();\\n\\n (bool success, bytes memory result) = _target.call{value: _value}(\\n _data\\n );\\n if (!success) {\\n assembly {\\n revert(add(result, 32), mload(result))\\n }\\n }\\n }\\n\\n /**\\n * @notice Checks restrictions if the restrictions facet exists\\n * @dev This method checks if the restrictions facet exists and makes a verification call to an array of restrictions facet\\n * @param _facet Address that holds the restrictions logic\\n * @param _target Address the call is getting forwarded to\\n * @param _value Amount of native coin the call is sending together with the call\\n * @param _data Calldata to trigger execution in target address\\n */\\n function _checkRestrictions(\\n address _facet,\\n address _target,\\n uint256 _value,\\n bytes memory _data\\n ) internal returns (uint256 result) {\\n bytes memory call = abi.encodeWithSignature(\\n \\\"verifyRestrictions(address,address,uint256,bytes)\\\",\\n address(this),\\n _target,\\n _value,\\n _data\\n );\\n (bool success, bytes memory response) = _facet.delegatecall(call);\\n if (!success) revert AccountFacet__RestrictionsFailure();\\n result = uint256(bytes32(response));\\n }\\n}\\n\",\"keccak256\":\"0xcd92bcdd447010880f78e57e213123269c9e023adfc0a540608daa127d8649ca\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/facets/interfaces/IAccountFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IEntryPoint} from \\\"../../aa-4337/interfaces/IEntryPoint.sol\\\";\\n\\n/**\\n * @title Account Facet Interface\\n * @dev Interface of module contract that provides the account features and init/unitialization of signer\\n * compatible with EIP-1271 & EIP-4337\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IAccountFacet {\\n event AccountInitialized(\\n IEntryPoint indexed entryPoint,\\n bytes indexed ownerPublicKey\\n );\\n // NOTE: Added Below Event\\n event VerificationSuccess(bytes32);\\n event VerificationFailure(bytes32);\\n\\n error AccountFacet__InitializationFailure();\\n error AccountFacet__RestrictionsFailure();\\n error AccountFacet__NonExistentVerificationFacet();\\n error AccountFacet__CallNotSuccessful();\\n error AccountFacet__InvalidArrayLength();\\n\\n function initialize(\\n address verificationFacet,\\n address anEntryPoint,\\n address facetRegistry,\\n address _defaultFallBack,\\n bytes calldata _ownerPublicKey\\n ) external returns (uint256);\\n\\n function execute(address dest, uint256 value, bytes calldata func) external;\\n\\n function executeBatch(\\n address[] calldata dest,\\n uint256[] calldata value,\\n bytes[] calldata func\\n ) external;\\n}\\n\",\"keccak256\":\"0x74a9cb0b8f2f4a5148e366a401a0354426c536c012c025025d07cc25a4cd5382\",\"license\":\"Apache-2.0\"},\"contracts/facets/interfaces/IVerificationFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {UserOperation} from \\\"../../aa-4337/interfaces/UserOperation.sol\\\";\\n\\n/**\\n * @title Verification Facet Interface\\n * @dev Implements logic for user ops signature verification\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\ninterface IVerificationFacet {\\n event SignerInitialized(bytes);\\n event SignerUninitialized();\\n\\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\\n error VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\\n error VerificationFacet__InitializationFailure();\\n error VerificationFacet__InvalidFacetMapping();\\n\\n function initializeSigner(bytes memory) external returns (uint256);\\n\\n function uninitializeSigner() external returns (uint256);\\n\\n function validateOwnerSignatureSelector() external view returns (bytes4);\\n\\n function owner() external view returns (bytes memory);\\n\\n function isValidKeyType(bytes calldata) external view returns (bool);\\n\\n function validateOwnerSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x72bc370a1d1b5a6d6bde67f5026733fd8f6ba434bb90e73b0bd8627fb1579928\",\"license\":\"Apache-2.0\"},\"contracts/infrastructure/interfaces/IFacetRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Registry Interface\\n * @dev Interface for Facet Registry contract to keep track of facets & function selectors addable to user wallets\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IFacetRegistry {\\n struct FacetRegistryConfig {\\n bytes4[] selectors;\\n mapping(bytes4 => FacetInfo) info;\\n }\\n struct FacetInfo {\\n bool exists;\\n uint128 index;\\n }\\n\\n event FacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] facetSelectors\\n );\\n event FacetFunctionSelectorsRemoved(address facet, bytes4[] facetSelectors);\\n\\n error FacetRegistry__FacetSelectorAlreadyRegistered();\\n error FacetRegistry__UnregisteredFacetSelector();\\n\\n function registerFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function removeFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function areFacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external view returns (bool);\\n\\n function isFacetFunctionSelectorRegistered(\\n address facet,\\n bytes4 facetSelector\\n ) external view returns (bool);\\n\\n function getFacetFunctionSelectors(\\n address facet\\n ) external view returns (bytes4[] memory);\\n}\\n\",\"keccak256\":\"0x6e6dd2cab346ef7c31230740ec48d2925e4a9ab24c2f2fb268baaf408dcf02ef\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC1271 {\\n function isValidSignature(\\n bytes32 hash,\\n bytes memory signature\\n ) external view returns (bytes4);\\n}\\n\",\"keccak256\":\"0xcdddb7d5641c9d3f2432dec7fd13fddb9ae1480f25c76c21511e2fa16b8bd422\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibAppStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {SafeCast} from \\\"@openzeppelin/contracts/utils/math/SafeCast.sol\\\";\\nimport {IEntryPoint} from \\\"../aa-4337/interfaces/IEntryPoint.sol\\\";\\nimport {IFacetRegistry} from \\\"../infrastructure/interfaces/IFacetRegistry.sol\\\";\\n\\n/*\\n * @title App Storage\\n * @dev App storage for Barz contract to prevent storage collision\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Lock {\\n uint64 release;\\n bytes4 locker;\\n}\\n\\nstruct InitializersStorage {\\n // NOTE: initialized is a variable to make sure the initialization is only done once.\\n uint8 signerInitialized;\\n uint8 accountInitialized;\\n uint8 restrictionsInitialized;\\n}\\n\\nstruct AppStorage {\\n mapping(uint256 => InitializersStorage) initStorage;\\n uint8 signerMigration;\\n bytes4 validateOwnerSignatureSelector;\\n IEntryPoint entryPoint;\\n IFacetRegistry facetRegistry;\\n mapping(uint256 => Lock) locks;\\n}\\n\\nlibrary LibAppStorage {\\n error LibAppStorage__AccountAlreadyUninitialized();\\n error LibAppStorage__AccountMustBeUninitialized();\\n error LibAppStorage__SignerAlreadyUninitialized();\\n error LibAppStorage__SignerMustBeUninitialized();\\n\\n function appStorage() internal pure returns (AppStorage storage ds) {\\n assembly {\\n ds.slot := 0\\n }\\n }\\n\\n function setSignerUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerAlreadyUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 0;\\n }\\n\\n function getValidateOwnerSignatureSelector()\\n internal\\n view\\n returns (bytes4 selector)\\n {\\n selector = appStorage().validateOwnerSignatureSelector;\\n }\\n\\n function setValidateOwnerSignatureSelector(\\n bytes4 _validateOwnerSignatureSelector\\n ) internal {\\n appStorage()\\n .validateOwnerSignatureSelector = _validateOwnerSignatureSelector;\\n }\\n\\n function enforceSignerInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerMustBeUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 1;\\n }\\n\\n function enforceAccountInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].accountInitialized) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n s.initStorage[0].accountInitialized = 1;\\n }\\n\\n function initiateSignerMigration() internal {\\n appStorage().signerMigration = 1;\\n }\\n\\n function enforceSignerMigration() internal view {\\n if (1 != appStorage().signerMigration) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n }\\n\\n function finalizeSignerMigration() internal {\\n appStorage().signerMigration = 0;\\n }\\n\\n function setLock(uint256 _releaseAfter, bytes4 _locker) internal {\\n appStorage().locks[0] = Lock(SafeCast.toUint64(_releaseAfter), _locker);\\n }\\n\\n function enforceRestrictionsInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__SignerMustBeUninitialized();\\n s.initStorage[0].restrictionsInitialized = 1;\\n }\\n\\n function setRestrictionsUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__AccountAlreadyUninitialized();\\n s.initStorage[0].restrictionsInitialized = 0;\\n }\\n}\\n\\ncontract BarzStorage {\\n AppStorage internal s;\\n modifier onlyWhenUnlocked() {\\n require(\\n uint64(block.timestamp) >= s.locks[0].release,\\n \\\"Account Locked\\\"\\n );\\n _;\\n }\\n modifier onlyWhenLocked() {\\n require(\\n uint64(block.timestamp) < s.locks[0].release,\\n \\\"Account Unlocked\\\"\\n );\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x48524007862a6ce0e07f645950613ce6513ce073c37a109c75019683d42bae27\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\\n bytes4(keccak256(\\\"verifyRestrictions(address,address,uint256,bytes)\\\"));\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // Default Fallback Handler of the barz.\\n IDiamondLoupe defaultFallbackHandler;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function enforceIsSelf() internal view {\\n require(msg.sender == address(this), \\\"LibDiamond: Caller not self\\\");\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n\\n unchecked {\\n facetIndex++;\\n }\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n\\n function restrictionsFacet() internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(\\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2cabdc00de859c3a3170ce3bda5d0e5fd3933d47ce904fd1585f9818b02572f8\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\nimport {LibDiamond} from \\\"./LibDiamond.sol\\\";\\n\\n/**\\n * @title LibLoupe\\n * @dev Internal Library to provide utility feature for reading the state of diamond facets\\n * Originally from Diamond's implementation of Mudgen(author of EIP-2535)\\n */\\nlibrary LibLoupe {\\n /// @notice Gets all facets and their selectors.\\n /// @return facets_ Facet\\n function facets()\\n internal\\n view\\n returns (IDiamondLoupe.Facet[] memory facets_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facets_ = new IDiamondLoupe.Facet[](ds.selectorCount);\\n uint16[] memory numFacetSelectors = new uint16[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facets_[facetIndex].facetAddress == facetAddress_) {\\n facets_[facetIndex].functionSelectors[\\n numFacetSelectors[facetIndex]\\n ] = selector;\\n // probably will never have more than 256 functions from one facet contract\\n require(numFacetSelectors[facetIndex] < 255);\\n numFacetSelectors[facetIndex]++;\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facets_[numFacets].facetAddress = facetAddress_;\\n facets_[numFacets].functionSelectors = new bytes4[](\\n ds.selectorCount\\n );\\n facets_[numFacets].functionSelectors[0] = selector;\\n numFacetSelectors[numFacets] = 1;\\n numFacets++;\\n }\\n }\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n uint256 numSelectors = numFacetSelectors[facetIndex];\\n bytes4[] memory selectors = facets_[facetIndex].functionSelectors;\\n // setting the number of selectors\\n assembly {\\n mstore(selectors, numSelectors)\\n }\\n }\\n // setting the number of facets\\n assembly {\\n mstore(facets_, numFacets)\\n }\\n }\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return _facetFunctionSelectors The selectors associated with a facet address.\\n function facetFunctionSelectors(\\n address _facet\\n ) internal view returns (bytes4[] memory _facetFunctionSelectors) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n uint256 numSelectors;\\n _facetFunctionSelectors = new bytes4[](ds.selectorCount);\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facet = address(bytes20(ds.facets[selector]));\\n if (_facet == facet) {\\n _facetFunctionSelectors[numSelectors] = selector;\\n numSelectors++;\\n }\\n }\\n }\\n // Set the number of selectors in the array\\n assembly {\\n mstore(_facetFunctionSelectors, numSelectors)\\n }\\n }\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n internal\\n view\\n returns (address[] memory facetAddresses_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetAddresses_ = new address[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facetAddress_ == facetAddresses_[facetIndex]) {\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facetAddresses_[numFacets] = facetAddress_;\\n numFacets++;\\n }\\n }\\n // Set the number of facet addresses in the array\\n assembly {\\n mstore(facetAddresses_, numFacets)\\n }\\n }\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(LibDiamond.diamondStorage().facets[_functionSelector])\\n );\\n }\\n}\\n\",\"keccak256\":\"0x0b11439c3cc657095e15ec2241fdcf67204b14001357b612fc5db4ff9e760a5a\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5061001961001e565b61008e565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb554610100900460ff1615610070576040516338fc28cb60e01b815260040160405180910390fd5b600080805260209190915260409020805461ff001916610100179055565b6129b6806200009e6000396000f3fe608060405234801561001057600080fd5b50600436106100725760003560e01c8063b0d691fe11610050578063b0d691fe146100c5578063b61d27f61461010c578063d087d2881461011f57600080fd5b80633a871cdd1461007757806347e1da2a1461009d5780634a936417146100b2575b600080fd5b61008a610085366004611fb5565b610127565b6040519081526020015b60405180910390f35b6100b06100ab366004612055565b61014d565b005b61008a6100c036600461215a565b610450565b60015465010000000000900473ffffffffffffffffffffffffffffffffffffffff1660405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610094565b6100b061011a3660046121ce565b6106d0565b61008a61089d565b600061013161095e565b61013b8484610a16565b905061014682610c5d565b9392505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff9081164290911610156101f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064015b60405180910390fd5b6101fd61095e565b848114158061020c5750848314155b15610243576040517fdde5716100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006102b87fac87185d000000000000000000000000000000000000000000000000000000006000527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020527f6d9f2463c8c0d8cb8be556a773ab21d4321328909a1725f2ef7cae0c320e95da5460601c90565b905073ffffffffffffffffffffffffffffffffffffffff811661038f5760005b86811015610389576103818888838181106102f5576102f5612228565b905060200201602081019061030a9190612257565b87878481811061031c5761031c612228565b9050602002013586868581811061033557610335612228565b90506020028101906103479190612272565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610cc892505050565b6001016102d8565b50610447565b60005b868110156104455761043d8888838181106103af576103af612228565b90506020020160208101906103c49190612257565b8787848181106103d6576103d6612228565b905060200201358686858181106103ef576103ef612228565b90506020028101906104019190612272565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250889250610d45915050565b600101610392565b505b50505050505050565b600061045a610e0d565b6001805473ffffffffffffffffffffffffffffffffffffffff88811665010000000000027fffffffffffffff0000000000000000000000000000000000000000ffffffffff90921691909117909155600280548783167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216179091557f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd492380549287169290911691909117905561051187610eb3565b60008383604051602401610526929190612320565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fcd9b47e40000000000000000000000000000000000000000000000000000000017905251909150600090819073ffffffffffffffffffffffffffffffffffffffff8b16906105c8908590612360565b600060405180830381855af49150503d8060008114610603576040519150601f19603f3d011682016040523d82523d6000602084013e610608565b606091505b5091509150811580610623575061061e8161237c565b600114155b1561065a576040517f1602372100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60019350858560405161066e9291906123c1565b60405190819003812060015490916501000000000090910473ffffffffffffffffffffffffffffffffffffffff16907fd429ff0b972be4ae725700a373d05007287994e4c86cb83315b43ffa85b595fd90600090a35050509695505050505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610773576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064016101ec565b61077b61095e565b60006107f07fac87185d000000000000000000000000000000000000000000000000000000006000527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020527f6d9f2463c8c0d8cb8be556a773ab21d4321328909a1725f2ef7cae0c320e95da5460601c90565b905073ffffffffffffffffffffffffffffffffffffffff81166108535761084e858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610cc892505050565b610896565b610896858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250879250610d45915050565b5050505050565b60015460009065010000000000900473ffffffffffffffffffffffffffffffffffffffff166040517f35567e1a0000000000000000000000000000000000000000000000000000000081523060048201526000602482015273ffffffffffffffffffffffffffffffffffffffff91909116906335567e1a90604401602060405180830381865afa158015610935573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061095991906123d1565b905090565b60015465010000000000900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a14576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f6163636f756e743a206e6f742066726f6d20456e747279506f696e740000000060448201526064016101ec565b565b600154610100900460e01b7fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604081205460601c80610aab576040517f6eb2360200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600154604051600091610100900460e01b90610acd908790879060240161244e565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090506000808373ffffffffffffffffffffffffffffffffffffffff1683604051610b549190612360565b600060405180830381855af49150503d8060008114610b8f576040519150601f19603f3d011682016040523d82523d6000602084013e610b94565b606091505b509150915081610bd0576040517f3cbbb65000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610bd98161237c565b94506000859003610c1c576040518681527f19e781916118c373dadcb7776fae0a2dbb6bbdeedae143ce68031e22801ef8659060200160405180910390a1610c50565b6040518681527fbbfee2df7f28b899771f1015dc85d7840ff9f6162f23f6aa99686e8fbd2ce1319060200160405180910390a15b5050505092915050565b50565b8015610c5a5760405160009033907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90849084818181858888f193505050503d8060008114610896576040519150601f19603f3d011682016040523d82523d6000602084013e610896565b6000808473ffffffffffffffffffffffffffffffffffffffff168484604051610cf19190612360565b60006040518083038185875af1925050503d8060008114610d2e576040519150601f19603f3d011682016040523d82523d6000602084013e610d33565b606091505b50915091508161089657805160208201fd5b610d5181858585611117565b15610d88576040517f01f595e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000808573ffffffffffffffffffffffffffffffffffffffff168585604051610db19190612360565b60006040518083038185875af1925050503d8060008114610dee576040519150601f19603f3d011682016040523d82523d6000602084013e610df3565b606091505b509150915081610e0557805160208201fd5b505050505050565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb554610100900460ff1615610e78576040517f38fc28cb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100179055565b604080516001808252818301909252600091816020015b60408051606080820183526000808352602083015291810191909152815260200190600190039081610eca57905050905060008273ffffffffffffffffffffffffffffffffffffffff16633253960f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f6c9190612592565b604080516003808252608082019092529192506000919060208201606080368337019050509050631626ba7e60e01b81600081518110610fae57610fae612228565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681525050818160018151811061100e5761100e612228565b7fffffffff000000000000000000000000000000000000000000000000000000009092166020928302919091019091015280517f8da5cb5b00000000000000000000000000000000000000000000000000000000908290600290811061107657611076612228565b7fffffffff00000000000000000000000000000000000000000000000000000000909216602092830291909101820152604080516060810190915273ffffffffffffffffffffffffffffffffffffffff861681529081016000815260200182815250836000815181106110eb576110eb612228565b602002602001018190525061111183600060405180602001604052806000815250611264565b50505050565b60008030858585604051602401611131949392919061264d565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fac87185d0000000000000000000000000000000000000000000000000000000017905251909150600090819073ffffffffffffffffffffffffffffffffffffffff8916906111d3908590612360565b600060405180830381855af49150503d806000811461120e576040519150601f19603f3d011682016040523d82523d6000602084013e611213565b606091505b50915091508161124f576040517f01f595e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6112588161237c565b98975050505050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921547f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff8116908190600090600716156112d35750600381901c60009081526001840160205260409020545b60005b87518110156113505761134383838a84815181106112f6576112f6612228565b6020026020010151600001518b858151811061131457611314612228565b6020026020010151602001518c868151811061133257611332612228565b6020026020010151604001516113f0565b90935091506001016112d6565b50828214611389576002840180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff84161790555b60078216156113ab57600382901c600090815260018501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb6738787876040516113de93929190612696565b60405180910390a16104478686611e81565b600080807f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f905060008451116114a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f2063757400000000000000000000000000000000000000000060648201526084016101ec565b60008560028111156114bc576114bc6125d4565b0361168c576114e38660405180606001604052806024815260200161290d60249139611f7a565b60005b845181101561168657600085828151811061150357611503612228565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c156115d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c726561647920657869737473000000000000000000000060648201526084016101ec565b7fffffffff0000000000000000000000000000000000000000000000000000000080831660008181526020879052604090207fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608d901b168e17905560e060058e901b811692831c199c909c1690821c179a81900361166a5760038c901c600090815260018601602052604081209b909b555b8b6116748161282d565b9c5050600190930192506114e6915050565b50611e75565b60018560028111156116a0576116a06125d4565b03611990576116c78660405180606001604052806028815260200161295960289139611f7a565b60005b84518110156116865760008582815181106116e7576116e7612228565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c3081036117bc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4c69624469616d6f6e644375743a2043616e2774207265706c61636520696d6d60448201527f757461626c652066756e6374696f6e000000000000000000000000000000000060648201526084016101ec565b8973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611877576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e000000000000000060648201526084016101ec565b73ffffffffffffffffffffffffffffffffffffffff811661191a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e207468617420646f65736e2774206578697374000000000000000060648201526084016101ec565b507fffffffff0000000000000000000000000000000000000000000000000000000090911660009081526020849052604090206bffffffffffffffffffffffff919091167fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608a901b161790556001016116ca565b60028560028111156119a4576119a46125d4565b03611ded5773ffffffffffffffffffffffffffffffffffffffff861615611a4d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d75737420626520616464726573732830290000000000000000000060648201526084016101ec565b600388901c6007891660005b8651811015611dcd5760008a9003611a955782611a7581612865565b60008181526001870160205260409020549b50935060079250611aa39050565b81611a9f81612865565b9250505b6000806000808a8581518110611abb57611abb612228565b6020908102919091018101517fffffffff0000000000000000000000000000000000000000000000000000000081166000908152918a9052604090912054909150606081901c611b8d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e277420657869737400000000000000000060648201526084016101ec565b30606082901c03611c20576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e00000000000000000000000000000000000060648201526084016101ec565b600587901b8f901b94507fffffffff0000000000000000000000000000000000000000000000000000000080861690831614611cbe577fffffffff000000000000000000000000000000000000000000000000000000008516600090815260208a90526040902080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff83161790555b7fffffffff0000000000000000000000000000000000000000000000000000000091909116600090815260208990526040812055600381901c611fff16925060051b60e0169050858214611d53576000828152600188016020526040902080547fffffffff0000000000000000000000000000000000000000000000000000000080841c19909116908516831c179055611da4565b80837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c817fffffffff0000000000000000000000000000000000000000000000000000000060001b901c198e16179c505b84600003611dc257600086815260018801602052604081208190559c505b505050600101611a59565b5080611dda83600861289a565b611de491906128b7565b99505050611e75565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560448201527f74416374696f6e0000000000000000000000000000000000000000000000000060648201526084016101ec565b50959694955050505050565b73ffffffffffffffffffffffffffffffffffffffff8216611ea0575050565b611ec28260405180606001604052806028815260200161293160289139611f7a565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051611eea9190612360565b600060405180830381855af49150503d8060008114611f25576040519150601f19603f3d011682016040523d82523d6000602084013e611f2a565b606091505b50915091508161111157805115611f445780518082602001fd5b83836040517f192105d70000000000000000000000000000000000000000000000000000000081526004016101ec9291906128ca565b813b8181611111576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101ec91906128f9565b600080600060608486031215611fca57600080fd5b833567ffffffffffffffff811115611fe157600080fd5b84016101608187031215611ff457600080fd5b95602085013595506040909401359392505050565b60008083601f84011261201b57600080fd5b50813567ffffffffffffffff81111561203357600080fd5b6020830191508360208260051b850101111561204e57600080fd5b9250929050565b6000806000806000806060878903121561206e57600080fd5b863567ffffffffffffffff8082111561208657600080fd5b6120928a838b01612009565b909850965060208901359150808211156120ab57600080fd5b6120b78a838b01612009565b909650945060408901359150808211156120d057600080fd5b506120dd89828a01612009565b979a9699509497509295939492505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461211357600080fd5b919050565b60008083601f84011261212a57600080fd5b50813567ffffffffffffffff81111561214257600080fd5b60208301915083602082850101111561204e57600080fd5b60008060008060008060a0878903121561217357600080fd5b61217c876120ef565b955061218a602088016120ef565b9450612198604088016120ef565b93506121a6606088016120ef565b9250608087013567ffffffffffffffff8111156121c257600080fd5b6120dd89828a01612118565b600080600080606085870312156121e457600080fd5b6121ed856120ef565b935060208501359250604085013567ffffffffffffffff81111561221057600080fd5b61221c87828801612118565b95989497509550505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561226957600080fd5b610146826120ef565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126122a757600080fd5b83018035915067ffffffffffffffff8211156122c257600080fd5b60200191503681900382131561204e57600080fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b6020815260006123346020830184866122d7565b949350505050565b60005b8381101561235757818101518382015260200161233f565b50506000910152565b6000825161237281846020870161233c565b9190910192915050565b805160208083015191908110156123bb577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8160200360031b1b821691505b50919050565b8183823760009101908152919050565b6000602082840312156123e357600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261241f57600080fd5b830160208101925035905067ffffffffffffffff81111561243f57600080fd5b80360382131561204e57600080fd5b6040815261247c60408201612462856120ef565b73ffffffffffffffffffffffffffffffffffffffff169052565b60208301356060820152600061249560408501856123ea565b6101608060808601526124ad6101a0860183856122d7565b92506124bc60608801886123ea565b92507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0808786030160a08801526124f48585846122d7565b9450608089013560c088015260a089013560e0880152610100935060c089013584880152610120915060e089013582880152610140848a01358189015261253d838b018b6123ea565b955092508188870301848901526125558686856122d7565b9550612563818b018b6123ea565b9550935050808786030161018088015250506125808383836122d7565b93505050508260208301529392505050565b6000602082840312156125a457600080fd5b81517fffffffff000000000000000000000000000000000000000000000000000000008116811461014657600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6000815180845261261b81602086016020860161233c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600073ffffffffffffffffffffffffffffffffffffffff80871683528086166020840152508360408301526080606083015261268c6080830184612603565b9695505050505050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b848110156127c1577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808a8503018652815188850173ffffffffffffffffffffffffffffffffffffffff82511686528482015160038110612748577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b808310156127ac5783517fffffffff0000000000000000000000000000000000000000000000000000000016825292860192600192909201919086019061276a565b509785019795505050908201906001016126bf565b505073ffffffffffffffffffffffffffffffffffffffff8a169088015286810360408801526127f08189612603565b9a9950505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361285e5761285e6127fe565b5060010190565b600081612874576128746127fe565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b80820281158282048414176128b1576128b16127fe565b92915050565b808201808211156128b1576128b16127fe565b73ffffffffffffffffffffffffffffffffffffffff831681526040602082015260006123346040830184612603565b602081526000610146602083018461260356fe4c69624469616d6f6e644375743a2041646420666163657420686173206e6f20636f64654c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a205265706c61636520666163657420686173206e6f20636f6465a2646970667358221220a952f19990a20474450919a2df9ddff4430a71350892e0954f2bb073575ad64864736f6c63430008150033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100725760003560e01c8063b0d691fe11610050578063b0d691fe146100c5578063b61d27f61461010c578063d087d2881461011f57600080fd5b80633a871cdd1461007757806347e1da2a1461009d5780634a936417146100b2575b600080fd5b61008a610085366004611fb5565b610127565b6040519081526020015b60405180910390f35b6100b06100ab366004612055565b61014d565b005b61008a6100c036600461215a565b610450565b60015465010000000000900473ffffffffffffffffffffffffffffffffffffffff1660405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610094565b6100b061011a3660046121ce565b6106d0565b61008a61089d565b600061013161095e565b61013b8484610a16565b905061014682610c5d565b9392505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff9081164290911610156101f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064015b60405180910390fd5b6101fd61095e565b848114158061020c5750848314155b15610243576040517fdde5716100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006102b87fac87185d000000000000000000000000000000000000000000000000000000006000527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020527f6d9f2463c8c0d8cb8be556a773ab21d4321328909a1725f2ef7cae0c320e95da5460601c90565b905073ffffffffffffffffffffffffffffffffffffffff811661038f5760005b86811015610389576103818888838181106102f5576102f5612228565b905060200201602081019061030a9190612257565b87878481811061031c5761031c612228565b9050602002013586868581811061033557610335612228565b90506020028101906103479190612272565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610cc892505050565b6001016102d8565b50610447565b60005b868110156104455761043d8888838181106103af576103af612228565b90506020020160208101906103c49190612257565b8787848181106103d6576103d6612228565b905060200201358686858181106103ef576103ef612228565b90506020028101906104019190612272565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250889250610d45915050565b600101610392565b505b50505050505050565b600061045a610e0d565b6001805473ffffffffffffffffffffffffffffffffffffffff88811665010000000000027fffffffffffffff0000000000000000000000000000000000000000ffffffffff90921691909117909155600280548783167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216179091557f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd492380549287169290911691909117905561051187610eb3565b60008383604051602401610526929190612320565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fcd9b47e40000000000000000000000000000000000000000000000000000000017905251909150600090819073ffffffffffffffffffffffffffffffffffffffff8b16906105c8908590612360565b600060405180830381855af49150503d8060008114610603576040519150601f19603f3d011682016040523d82523d6000602084013e610608565b606091505b5091509150811580610623575061061e8161237c565b600114155b1561065a576040517f1602372100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60019350858560405161066e9291906123c1565b60405190819003812060015490916501000000000090910473ffffffffffffffffffffffffffffffffffffffff16907fd429ff0b972be4ae725700a373d05007287994e4c86cb83315b43ffa85b595fd90600090a35050509695505050505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610773576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064016101ec565b61077b61095e565b60006107f07fac87185d000000000000000000000000000000000000000000000000000000006000527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020527f6d9f2463c8c0d8cb8be556a773ab21d4321328909a1725f2ef7cae0c320e95da5460601c90565b905073ffffffffffffffffffffffffffffffffffffffff81166108535761084e858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610cc892505050565b610896565b610896858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250879250610d45915050565b5050505050565b60015460009065010000000000900473ffffffffffffffffffffffffffffffffffffffff166040517f35567e1a0000000000000000000000000000000000000000000000000000000081523060048201526000602482015273ffffffffffffffffffffffffffffffffffffffff91909116906335567e1a90604401602060405180830381865afa158015610935573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061095991906123d1565b905090565b60015465010000000000900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a14576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f6163636f756e743a206e6f742066726f6d20456e747279506f696e740000000060448201526064016101ec565b565b600154610100900460e01b7fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604081205460601c80610aab576040517f6eb2360200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600154604051600091610100900460e01b90610acd908790879060240161244e565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090506000808373ffffffffffffffffffffffffffffffffffffffff1683604051610b549190612360565b600060405180830381855af49150503d8060008114610b8f576040519150601f19603f3d011682016040523d82523d6000602084013e610b94565b606091505b509150915081610bd0576040517f3cbbb65000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610bd98161237c565b94506000859003610c1c576040518681527f19e781916118c373dadcb7776fae0a2dbb6bbdeedae143ce68031e22801ef8659060200160405180910390a1610c50565b6040518681527fbbfee2df7f28b899771f1015dc85d7840ff9f6162f23f6aa99686e8fbd2ce1319060200160405180910390a15b5050505092915050565b50565b8015610c5a5760405160009033907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90849084818181858888f193505050503d8060008114610896576040519150601f19603f3d011682016040523d82523d6000602084013e610896565b6000808473ffffffffffffffffffffffffffffffffffffffff168484604051610cf19190612360565b60006040518083038185875af1925050503d8060008114610d2e576040519150601f19603f3d011682016040523d82523d6000602084013e610d33565b606091505b50915091508161089657805160208201fd5b610d5181858585611117565b15610d88576040517f01f595e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000808573ffffffffffffffffffffffffffffffffffffffff168585604051610db19190612360565b60006040518083038185875af1925050503d8060008114610dee576040519150601f19603f3d011682016040523d82523d6000602084013e610df3565b606091505b509150915081610e0557805160208201fd5b505050505050565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb554610100900460ff1615610e78576040517f38fc28cb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100179055565b604080516001808252818301909252600091816020015b60408051606080820183526000808352602083015291810191909152815260200190600190039081610eca57905050905060008273ffffffffffffffffffffffffffffffffffffffff16633253960f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f6c9190612592565b604080516003808252608082019092529192506000919060208201606080368337019050509050631626ba7e60e01b81600081518110610fae57610fae612228565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681525050818160018151811061100e5761100e612228565b7fffffffff000000000000000000000000000000000000000000000000000000009092166020928302919091019091015280517f8da5cb5b00000000000000000000000000000000000000000000000000000000908290600290811061107657611076612228565b7fffffffff00000000000000000000000000000000000000000000000000000000909216602092830291909101820152604080516060810190915273ffffffffffffffffffffffffffffffffffffffff861681529081016000815260200182815250836000815181106110eb576110eb612228565b602002602001018190525061111183600060405180602001604052806000815250611264565b50505050565b60008030858585604051602401611131949392919061264d565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fac87185d0000000000000000000000000000000000000000000000000000000017905251909150600090819073ffffffffffffffffffffffffffffffffffffffff8916906111d3908590612360565b600060405180830381855af49150503d806000811461120e576040519150601f19603f3d011682016040523d82523d6000602084013e611213565b606091505b50915091508161124f576040517f01f595e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6112588161237c565b98975050505050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921547f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff8116908190600090600716156112d35750600381901c60009081526001840160205260409020545b60005b87518110156113505761134383838a84815181106112f6576112f6612228565b6020026020010151600001518b858151811061131457611314612228565b6020026020010151602001518c868151811061133257611332612228565b6020026020010151604001516113f0565b90935091506001016112d6565b50828214611389576002840180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff84161790555b60078216156113ab57600382901c600090815260018501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb6738787876040516113de93929190612696565b60405180910390a16104478686611e81565b600080807f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f905060008451116114a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f2063757400000000000000000000000000000000000000000060648201526084016101ec565b60008560028111156114bc576114bc6125d4565b0361168c576114e38660405180606001604052806024815260200161290d60249139611f7a565b60005b845181101561168657600085828151811061150357611503612228565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c156115d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c726561647920657869737473000000000000000000000060648201526084016101ec565b7fffffffff0000000000000000000000000000000000000000000000000000000080831660008181526020879052604090207fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608d901b168e17905560e060058e901b811692831c199c909c1690821c179a81900361166a5760038c901c600090815260018601602052604081209b909b555b8b6116748161282d565b9c5050600190930192506114e6915050565b50611e75565b60018560028111156116a0576116a06125d4565b03611990576116c78660405180606001604052806028815260200161295960289139611f7a565b60005b84518110156116865760008582815181106116e7576116e7612228565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c3081036117bc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4c69624469616d6f6e644375743a2043616e2774207265706c61636520696d6d60448201527f757461626c652066756e6374696f6e000000000000000000000000000000000060648201526084016101ec565b8973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611877576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e000000000000000060648201526084016101ec565b73ffffffffffffffffffffffffffffffffffffffff811661191a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e207468617420646f65736e2774206578697374000000000000000060648201526084016101ec565b507fffffffff0000000000000000000000000000000000000000000000000000000090911660009081526020849052604090206bffffffffffffffffffffffff919091167fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608a901b161790556001016116ca565b60028560028111156119a4576119a46125d4565b03611ded5773ffffffffffffffffffffffffffffffffffffffff861615611a4d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d75737420626520616464726573732830290000000000000000000060648201526084016101ec565b600388901c6007891660005b8651811015611dcd5760008a9003611a955782611a7581612865565b60008181526001870160205260409020549b50935060079250611aa39050565b81611a9f81612865565b9250505b6000806000808a8581518110611abb57611abb612228565b6020908102919091018101517fffffffff0000000000000000000000000000000000000000000000000000000081166000908152918a9052604090912054909150606081901c611b8d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e277420657869737400000000000000000060648201526084016101ec565b30606082901c03611c20576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e00000000000000000000000000000000000060648201526084016101ec565b600587901b8f901b94507fffffffff0000000000000000000000000000000000000000000000000000000080861690831614611cbe577fffffffff000000000000000000000000000000000000000000000000000000008516600090815260208a90526040902080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff83161790555b7fffffffff0000000000000000000000000000000000000000000000000000000091909116600090815260208990526040812055600381901c611fff16925060051b60e0169050858214611d53576000828152600188016020526040902080547fffffffff0000000000000000000000000000000000000000000000000000000080841c19909116908516831c179055611da4565b80837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c817fffffffff0000000000000000000000000000000000000000000000000000000060001b901c198e16179c505b84600003611dc257600086815260018801602052604081208190559c505b505050600101611a59565b5080611dda83600861289a565b611de491906128b7565b99505050611e75565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560448201527f74416374696f6e0000000000000000000000000000000000000000000000000060648201526084016101ec565b50959694955050505050565b73ffffffffffffffffffffffffffffffffffffffff8216611ea0575050565b611ec28260405180606001604052806028815260200161293160289139611f7a565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051611eea9190612360565b600060405180830381855af49150503d8060008114611f25576040519150601f19603f3d011682016040523d82523d6000602084013e611f2a565b606091505b50915091508161111157805115611f445780518082602001fd5b83836040517f192105d70000000000000000000000000000000000000000000000000000000081526004016101ec9291906128ca565b813b8181611111576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101ec91906128f9565b600080600060608486031215611fca57600080fd5b833567ffffffffffffffff811115611fe157600080fd5b84016101608187031215611ff457600080fd5b95602085013595506040909401359392505050565b60008083601f84011261201b57600080fd5b50813567ffffffffffffffff81111561203357600080fd5b6020830191508360208260051b850101111561204e57600080fd5b9250929050565b6000806000806000806060878903121561206e57600080fd5b863567ffffffffffffffff8082111561208657600080fd5b6120928a838b01612009565b909850965060208901359150808211156120ab57600080fd5b6120b78a838b01612009565b909650945060408901359150808211156120d057600080fd5b506120dd89828a01612009565b979a9699509497509295939492505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461211357600080fd5b919050565b60008083601f84011261212a57600080fd5b50813567ffffffffffffffff81111561214257600080fd5b60208301915083602082850101111561204e57600080fd5b60008060008060008060a0878903121561217357600080fd5b61217c876120ef565b955061218a602088016120ef565b9450612198604088016120ef565b93506121a6606088016120ef565b9250608087013567ffffffffffffffff8111156121c257600080fd5b6120dd89828a01612118565b600080600080606085870312156121e457600080fd5b6121ed856120ef565b935060208501359250604085013567ffffffffffffffff81111561221057600080fd5b61221c87828801612118565b95989497509550505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561226957600080fd5b610146826120ef565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126122a757600080fd5b83018035915067ffffffffffffffff8211156122c257600080fd5b60200191503681900382131561204e57600080fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b6020815260006123346020830184866122d7565b949350505050565b60005b8381101561235757818101518382015260200161233f565b50506000910152565b6000825161237281846020870161233c565b9190910192915050565b805160208083015191908110156123bb577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8160200360031b1b821691505b50919050565b8183823760009101908152919050565b6000602082840312156123e357600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261241f57600080fd5b830160208101925035905067ffffffffffffffff81111561243f57600080fd5b80360382131561204e57600080fd5b6040815261247c60408201612462856120ef565b73ffffffffffffffffffffffffffffffffffffffff169052565b60208301356060820152600061249560408501856123ea565b6101608060808601526124ad6101a0860183856122d7565b92506124bc60608801886123ea565b92507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0808786030160a08801526124f48585846122d7565b9450608089013560c088015260a089013560e0880152610100935060c089013584880152610120915060e089013582880152610140848a01358189015261253d838b018b6123ea565b955092508188870301848901526125558686856122d7565b9550612563818b018b6123ea565b9550935050808786030161018088015250506125808383836122d7565b93505050508260208301529392505050565b6000602082840312156125a457600080fd5b81517fffffffff000000000000000000000000000000000000000000000000000000008116811461014657600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6000815180845261261b81602086016020860161233c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600073ffffffffffffffffffffffffffffffffffffffff80871683528086166020840152508360408301526080606083015261268c6080830184612603565b9695505050505050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b848110156127c1577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808a8503018652815188850173ffffffffffffffffffffffffffffffffffffffff82511686528482015160038110612748577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b808310156127ac5783517fffffffff0000000000000000000000000000000000000000000000000000000016825292860192600192909201919086019061276a565b509785019795505050908201906001016126bf565b505073ffffffffffffffffffffffffffffffffffffffff8a169088015286810360408801526127f08189612603565b9a9950505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361285e5761285e6127fe565b5060010190565b600081612874576128746127fe565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b80820281158282048414176128b1576128b16127fe565b92915050565b808201808211156128b1576128b16127fe565b73ffffffffffffffffffffffffffffffffffffffff831681526040602082015260006123346040830184612603565b602081526000610146602083018461260356fe4c69624469616d6f6e644375743a2041646420666163657420686173206e6f20636f64654c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a205265706c61636520666163657420686173206e6f20636f6465a2646970667358221220a952f19990a20474450919a2df9ddff4430a71350892e0954f2bb073575ad64864736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "Account module contract that provides the account features and initialization of signer compatible with EIP-1271 & EIP-4337", + "kind": "dev", + "methods": { + "execute(address,uint256,bytes)": { + "details": "This method executes the calldata coming from the EntryPoint. Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)", + "params": { + "_dest": "Address of destination where the call will be forwarded to", + "_func": "Bytes of calldata to execute in the destination address", + "_value": "Amount of native coin the owner is willing to send(e.g. ETH, BNB)" + } + }, + "executeBatch(address[],uint256[],bytes[])": { + "details": "This method batch executes the calldata coming from the EntryPoint. Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)", + "params": { + "_dest": "Array of addresses of destination where the call will be forwarded to", + "_func": "Array of bytes of calldata to execute in the destination address", + "_value": "Array of amount of native coin the owner is willing to send(e.g. ETH, BNB)" + } + }, + "initialize(address,address,address,address,bytes)": { + "details": "This method can only be called during the initialization or signature migration. If the proxy contract was created without initialization, anyone can call initialize. Barz calls initialize in constructor in an atomic transaction during deployment", + "params": { + "_anEntryPoint": "Entrypoint contract defined in EIP-4337 handling the flow of UserOp", + "_defaultFallBackHandler": "Middleware contract for default facets", + "_facetRegistry": "Registry of Facets that hold all facet information", + "_ownerPublicKey": "Bytes of owner public key", + "_verificationFacet": "Facet contract handling the verificationi" + } + } + }, + "title": "Account Facet", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "constructor": { + "notice": "This constructor ensures that this contract can only be used as singleton for Proxy contracts" + }, + "entryPoint()": { + "notice": "Returns the address of EntryPoint contract registered to Barz account" + }, + "execute(address,uint256,bytes)": { + "notice": "Calls the destination with inputted calldata and value from EntryPoint" + }, + "executeBatch(address[],uint256[],bytes[])": { + "notice": "Batch calls the destination with inputted calldata and value from EntryPoint" + }, + "getNonce()": { + "notice": "Return the account nonce. This method returns the next sequential nonce. For a nonce of a specific key, use `entrypoint.getNonce(account, key)`" + }, + "initialize(address,address,address,address,bytes)": { + "notice": "Initializes the initial storage of the Barz contract." + }, + "validateUserOp((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256)": { + "notice": "Validate user's signature and nonce. subclass doesn't need to override this method. Instead, it should override the specific internal validation methods." + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 27823, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "s", + "offset": 0, + "slot": "0", + "type": "t_struct(AppStorage)27570_storage" + } + ], + "types": { + "t_bytes4": { + "encoding": "inplace", + "label": "bytes4", + "numberOfBytes": "4" + }, + "t_contract(IEntryPoint)12286": { + "encoding": "inplace", + "label": "contract IEntryPoint", + "numberOfBytes": "20" + }, + "t_contract(IFacetRegistry)26105": { + "encoding": "inplace", + "label": "contract IFacetRegistry", + "numberOfBytes": "20" + }, + "t_mapping(t_uint256,t_struct(InitializersStorage)27549_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => struct InitializersStorage)", + "numberOfBytes": "32", + "value": "t_struct(InitializersStorage)27549_storage" + }, + "t_mapping(t_uint256,t_struct(Lock)27542_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => struct Lock)", + "numberOfBytes": "32", + "value": "t_struct(Lock)27542_storage" + }, + "t_struct(AppStorage)27570_storage": { + "encoding": "inplace", + "label": "struct AppStorage", + "members": [ + { + "astId": 27554, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "initStorage", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_uint256,t_struct(InitializersStorage)27549_storage)" + }, + { + "astId": 27556, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "signerMigration", + "offset": 0, + "slot": "1", + "type": "t_uint8" + }, + { + "astId": 27558, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "validateOwnerSignatureSelector", + "offset": 1, + "slot": "1", + "type": "t_bytes4" + }, + { + "astId": 27561, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "entryPoint", + "offset": 5, + "slot": "1", + "type": "t_contract(IEntryPoint)12286" + }, + { + "astId": 27564, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "facetRegistry", + "offset": 0, + "slot": "2", + "type": "t_contract(IFacetRegistry)26105" + }, + { + "astId": 27569, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "locks", + "offset": 0, + "slot": "3", + "type": "t_mapping(t_uint256,t_struct(Lock)27542_storage)" + } + ], + "numberOfBytes": "128" + }, + "t_struct(InitializersStorage)27549_storage": { + "encoding": "inplace", + "label": "struct InitializersStorage", + "members": [ + { + "astId": 27544, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "signerInitialized", + "offset": 0, + "slot": "0", + "type": "t_uint8" + }, + { + "astId": 27546, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "accountInitialized", + "offset": 1, + "slot": "0", + "type": "t_uint8" + }, + { + "astId": 27548, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "restrictionsInitialized", + "offset": 2, + "slot": "0", + "type": "t_uint8" + } + ], + "numberOfBytes": "32" + }, + "t_struct(Lock)27542_storage": { + "encoding": "inplace", + "label": "struct Lock", + "members": [ + { + "astId": 27539, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "release", + "offset": 0, + "slot": "0", + "type": "t_uint64" + }, + { + "astId": 27541, + "contract": "contracts/facets/AccountFacet.sol:AccountFacet", + "label": "locker", + "offset": 8, + "slot": "0", + "type": "t_bytes4" + } + ], + "numberOfBytes": "32" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint64": { + "encoding": "inplace", + "label": "uint64", + "numberOfBytes": "8" + }, + "t_uint8": { + "encoding": "inplace", + "label": "uint8", + "numberOfBytes": "1" + } + } + } +} \ No newline at end of file diff --git a/deployments/polygon/BarzFactory.json b/deployments/polygon/BarzFactory.json new file mode 100644 index 0000000..a41e98a --- /dev/null +++ b/deployments/polygon/BarzFactory.json @@ -0,0 +1,334 @@ +{ + "address": "0x729c310186a57833f622630a16d13f710b83272a", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_accountFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_entryPoint", + "type": "address" + }, + { + "internalType": "address", + "name": "_facetRegistry", + "type": "address" + }, + { + "internalType": "address", + "name": "_defaultFallback", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "BarzDeployed", + "type": "event" + }, + { + "inputs": [], + "name": "accountFacet", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_verificationFacet", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_owner", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "_salt", + "type": "uint256" + } + ], + "name": "createAccount", + "outputs": [ + { + "internalType": "contract Barz", + "name": "barz", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "defaultFallback", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "entryPoint", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetRegistry", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_verificationFacet", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_owner", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "_salt", + "type": "uint256" + } + ], + "name": "getAddress", + "outputs": [ + { + "internalType": "address", + "name": "barzAddress", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_accountFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_verificationFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_entryPoint", + "type": "address" + }, + { + "internalType": "address", + "name": "_facetRegistry", + "type": "address" + }, + { + "internalType": "address", + "name": "_defaultFallback", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_ownerPublicKey", + "type": "bytes" + } + ], + "name": "getBytecode", + "outputs": [ + { + "internalType": "bytes", + "name": "barzBytecode", + "type": "bytes" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "getCreationCode", + "outputs": [ + { + "internalType": "bytes", + "name": "creationCode", + "type": "bytes" + } + ], + "stateMutability": "pure", + "type": "function" + } + ], + "transactionHash": "0x14ca36cbfa0588970f481be916dec02642b0705a459e523ed7acd1afba50a9de", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 16, + "gasUsed": "801756", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000008000000000000000000000000000000000000000000000000000000000800000000000000000000100000000000000000000000000001000000000000000000000000100000080000000000000000000004000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000020000000004200000000000000000001000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000100000", + "blockHash": "0xd79b78cc2bdcc9d3bdc6493ec313fa34f976c3f78ebd57f2bb2acbb917584cee", + "transactionHash": "0x14ca36cbfa0588970f481be916dec02642b0705a459e523ed7acd1afba50a9de", + "logs": [ + { + "transactionIndex": 16, + "blockNumber": 50172529, + "transactionHash": "0x14ca36cbfa0588970f481be916dec02642b0705a459e523ed7acd1afba50a9de", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x000000000000000000000000d87df9fd27b9a30fe27e7b294caaa4673f34b6b1", + "0x000000000000000000000000eedba2484aaf940f37cd3cd21a5d7c4a7dafbfc0" + ], + "data": "0x00000000000000000000000000000000000000000000000000b4f301781b1fb8000000000000000000000000000000000000000000000000b547eafb087c221400000000000000000000000000000000000000000000c76ab964bbc19f3e8c5d000000000000000000000000000000000000000000000000b492f7f99061025c00000000000000000000000000000000000000000000c76aba19aec31759ac15", + "logIndex": 62, + "blockHash": "0xd79b78cc2bdcc9d3bdc6493ec313fa34f976c3f78ebd57f2bb2acbb917584cee" + } + ], + "blockNumber": 50172529, + "cumulativeGasUsed": "3462084", + "status": 1, + "byzantium": true + }, + "args": [ + "0xFde53272dcd7938d16E031A6989753c321728332", + "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789", + "0xAfCb70e6e9514E2A15B23A01d2a9b9f7A34f2c33", + "0x2e7f1dAe1F3799d20f5c31bEFdc7A620f664728D" + ], + "numDeployments": 3, + "solcInputHash": "4356503edd8ae34e73cb6dd1c8e2fc8a", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_accountFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_entryPoint\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_facetRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_defaultFallback\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"BarzDeployed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"accountFacet\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_verificationFacet\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_owner\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_salt\",\"type\":\"uint256\"}],\"name\":\"createAccount\",\"outputs\":[{\"internalType\":\"contract Barz\",\"name\":\"barz\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"defaultFallback\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"entryPoint\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetRegistry\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_verificationFacet\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_owner\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_salt\",\"type\":\"uint256\"}],\"name\":\"getAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"barzAddress\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_accountFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_verificationFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_entryPoint\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_facetRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_defaultFallback\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_ownerPublicKey\",\"type\":\"bytes\"}],\"name\":\"getBytecode\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"barzBytecode\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCreationCode\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"creationCode\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"Contract to easily deploy Barz to a pre-computed address with a single call\",\"kind\":\"dev\",\"methods\":{\"constructor\":{\"params\":{\"_accountFacet\":\"Account Facet to be used to create Barz\",\"_defaultFallback\":\"Default Fallback Handler to be used to create Barz\",\"_entryPoint\":\"Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\",\"_facetRegistry\":\"Facet Registry to be used to create Barz\"}},\"createAccount(address,bytes,uint256)\":{\"params\":{\"_owner\":\"Public Key of the owner to initialize barz account\",\"_salt\":\"Salt used for deploying barz with create2\",\"_verificationFacet\":\"Address of verification facet used for creating the barz account\"},\"returns\":{\"barz\":\"Instance of Barz contract deployed with the given parameters\"}},\"getAddress(address,bytes,uint256)\":{\"params\":{\"_owner\":\"Public Key of the owner to initialize barz account\",\"_salt\":\"Salt used for deploying barz with create2\",\"_verificationFacet\":\"Address of verification facet used for creating the barz account\"},\"returns\":{\"barzAddress\":\"Precalculated Barz address\"}},\"getBytecode(address,address,address,address,address,bytes)\":{\"params\":{\"_accountFacet\":\"Account Facet to be used to create Barz\",\"_defaultFallback\":\"Default Fallback Handler to be used to create Barz\",\"_entryPoint\":\"Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\",\"_facetRegistry\":\"Facet Registry to be used to create Barz\",\"_ownerPublicKey\":\"Public Key of owner to be used to initialize Barz ownership\",\"_verificationFacet\":\"Verification Facet to be used to create Barz\"},\"returns\":{\"barzBytecode\":\"Bytecode of Barz\"}},\"getCreationCode()\":{\"returns\":{\"creationCode\":\"Creation code of Barz\"}}},\"title\":\"Barz Factory\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"Sets the initialization data for Barz contract initialization\"},\"createAccount(address,bytes,uint256)\":{\"notice\":\"Creates the Barz with a single call. It creates the Barz contract with the givent verification facet\"},\"getAddress(address,bytes,uint256)\":{\"notice\":\"Calculates the address of Barz with the given parameters\"},\"getBytecode(address,address,address,address,address,bytes)\":{\"notice\":\"Returns the bytecode of Barz with the given parameter\"},\"getCreationCode()\":{\"notice\":\"Returns the creation code of the Barz contract\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/BarzFactory.sol\":\"BarzFactory\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"contracts/Barz.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {LibDiamond} from \\\"./libraries/LibDiamond.sol\\\";\\nimport {IBarz} from \\\"./interfaces/IBarz.sol\\\";\\n\\n/**\\n * @title Barz\\n * @dev A diamond proxy wallet with a modular & upgradeable architecture\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract Barz is IBarz {\\n /**\\n * @notice Initializes Barz with the given parameters. Barz account is intended to be created from Barz Factory for stable deployment.\\n * @dev This method makes a delegate call to account facet and account facet handles the initialization.\\n * With modular architecture, Barz encompasses wide spectrum of architecture and logic.\\n * The only requirement is account facet to comply with initialize() interface.\\n * Barz doesn't include built-in functions and is a full proxy, for maximum extensibility and modularity.\\n * @param _accountFacet Address of Account Facet in charge of the Barz initialization\\n * @param _verificationFacet Address of Verification Facet for verifying the signature. Could be any signature scheme\\n * @param _entryPoint Address of Entry Point contract\\n * @param _facetRegistry Address of Facet Registry. Facet Registry is a registry holding trusted facets that could be added to user's wallet\\n * @param _defaultFallBack Address of Default FallBack Handler. Middleware contract for more efficient deployment\\n * @param _ownerPublicKey Bytes of Owner Public Key using for initialization\\n */\\n constructor(\\n address _accountFacet,\\n address _verificationFacet,\\n address _entryPoint,\\n address _facetRegistry,\\n address _defaultFallBack,\\n bytes memory _ownerPublicKey\\n ) payable {\\n bytes memory initCall = abi.encodeWithSignature(\\n \\\"initialize(address,address,address,address,bytes)\\\",\\n _verificationFacet,\\n _entryPoint,\\n _facetRegistry,\\n _defaultFallBack,\\n _ownerPublicKey\\n );\\n (bool success, bytes memory result) = _accountFacet.delegatecall(\\n initCall\\n );\\n if (!success || uint256(bytes32(result)) != 1) {\\n revert Barz__InitializationFailure();\\n }\\n }\\n\\n /**\\n * @notice Fallback function for Barz complying with Diamond Standard with customization of adding Default Fallback Handler\\n * @dev Find facet for function that is called and execute the function if a facet is found and return any value.\\n */\\n fallback() external payable {\\n LibDiamond.DiamondStorage storage ds;\\n bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION;\\n // get diamond storage\\n assembly {\\n ds.slot := position\\n }\\n // get facet from function selector\\n address facet = address(bytes20(ds.facets[msg.sig]));\\n if (facet == address(0))\\n facet = ds.defaultFallbackHandler.facetAddress(msg.sig);\\n require(facet != address(0), \\\"Barz: Function does not exist\\\");\\n // Execute external function from facet using delegatecall and return any value.\\n assembly {\\n // copy function selector and any arguments\\n calldatacopy(0, 0, calldatasize())\\n // execute function call using the facet\\n let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)\\n // get any return value\\n returndatacopy(0, 0, returndatasize())\\n // return any return value or error back to the caller\\n switch result\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @notice Receive function to receive native token without data\\n */\\n receive() external payable {}\\n}\\n\",\"keccak256\":\"0xd1c773409a4b3d1ca0316445d9ea1d686bab9cd5f6731fbdb0766a93edfd7bdb\",\"license\":\"Apache-2.0\"},\"contracts/BarzFactory.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {Barz} from \\\"./Barz.sol\\\";\\nimport {IBarzFactory} from \\\"./interfaces/IBarzFactory.sol\\\";\\n\\n/**\\n * @title Barz Factory\\n * @dev Contract to easily deploy Barz to a pre-computed address with a single call\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract BarzFactory is IBarzFactory {\\n address public immutable accountFacet;\\n address public immutable entryPoint;\\n address public immutable facetRegistry;\\n address public immutable defaultFallback;\\n\\n /**\\n * @notice Sets the initialization data for Barz contract initialization\\n * @param _accountFacet Account Facet to be used to create Barz\\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\\n * @param _facetRegistry Facet Registry to be used to create Barz\\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\\n */\\n constructor(\\n address _accountFacet,\\n address _entryPoint,\\n address _facetRegistry,\\n address _defaultFallback\\n ) {\\n accountFacet = _accountFacet;\\n entryPoint = _entryPoint;\\n facetRegistry = _facetRegistry;\\n defaultFallback = _defaultFallback;\\n }\\n\\n /**\\n * @notice Creates the Barz with a single call. It creates the Barz contract with the givent verification facet\\n * @param _verificationFacet Address of verification facet used for creating the barz account\\n * @param _owner Public Key of the owner to initialize barz account\\n * @param _salt Salt used for deploying barz with create2\\n * @return barz Instance of Barz contract deployed with the given parameters\\n */\\n function createAccount(\\n address _verificationFacet,\\n bytes calldata _owner,\\n uint256 _salt\\n ) external override returns (Barz barz) {\\n address addr = getAddress(_verificationFacet, _owner, _salt);\\n uint codeSize = addr.code.length;\\n if (codeSize > 0) {\\n return Barz(payable(addr));\\n }\\n barz = new Barz{salt: bytes32(_salt)}(\\n accountFacet,\\n _verificationFacet,\\n entryPoint,\\n facetRegistry,\\n defaultFallback,\\n _owner\\n );\\n emit BarzDeployed(address(barz));\\n }\\n\\n /**\\n * @notice Calculates the address of Barz with the given parameters\\n * @param _verificationFacet Address of verification facet used for creating the barz account\\n * @param _owner Public Key of the owner to initialize barz account\\n * @param _salt Salt used for deploying barz with create2\\n * @return barzAddress Precalculated Barz address\\n */\\n function getAddress(\\n address _verificationFacet,\\n bytes calldata _owner,\\n uint256 _salt\\n ) public view override returns (address barzAddress) {\\n bytes memory bytecode = getBytecode(\\n accountFacet,\\n _verificationFacet,\\n entryPoint,\\n facetRegistry,\\n defaultFallback,\\n _owner\\n );\\n bytes32 hash = keccak256(\\n abi.encodePacked(\\n bytes1(0xff),\\n address(this),\\n _salt,\\n keccak256(bytecode)\\n )\\n );\\n barzAddress = address(uint160(uint256(hash)));\\n }\\n\\n /**\\n * @notice Returns the bytecode of Barz with the given parameter\\n * @param _accountFacet Account Facet to be used to create Barz\\n * @param _verificationFacet Verification Facet to be used to create Barz\\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\\n * @param _facetRegistry Facet Registry to be used to create Barz\\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\\n * @param _ownerPublicKey Public Key of owner to be used to initialize Barz ownership\\n * @return barzBytecode Bytecode of Barz\\n */\\n function getBytecode(\\n address _accountFacet,\\n address _verificationFacet,\\n address _entryPoint,\\n address _facetRegistry,\\n address _defaultFallback,\\n bytes calldata _ownerPublicKey\\n ) public pure override returns (bytes memory barzBytecode) {\\n bytes memory bytecode = type(Barz).creationCode;\\n barzBytecode = abi.encodePacked(\\n bytecode,\\n abi.encode(\\n _accountFacet,\\n _verificationFacet,\\n _entryPoint,\\n _facetRegistry,\\n _defaultFallback,\\n _ownerPublicKey\\n )\\n );\\n }\\n\\n /**\\n * @notice Returns the creation code of the Barz contract\\n * @return creationCode Creation code of Barz\\n */\\n function getCreationCode()\\n public\\n pure\\n override\\n returns (bytes memory creationCode)\\n {\\n creationCode = type(Barz).creationCode;\\n }\\n}\\n\",\"keccak256\":\"0x76d6058fa4714f5ef87b876e49ce7e21f581164901eea906ec743e82362b1df6\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IBarz.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Barz Interface\\n * @dev Interface of Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IBarz {\\n error Barz__InitializationFailure();\\n}\\n\",\"keccak256\":\"0xca9f0c2c1ad7d06088fa16ae92d587416f2d10d8f999d7afe8ca5c4d73410aba\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IBarzFactory.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {Barz} from \\\"../Barz.sol\\\";\\n\\n/**\\n * @title Barz Factory Interface\\n * @dev Interface of contract to easily deploy Barz to a pre-computed address with a single call\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IBarzFactory {\\n event BarzDeployed(address);\\n\\n function createAccount(\\n address verificationFacet,\\n bytes calldata owner,\\n uint256 salt\\n ) external returns (Barz);\\n\\n function getAddress(\\n address verificationFacet,\\n bytes calldata owner,\\n uint256 salt\\n ) external view returns (address);\\n\\n function getBytecode(\\n address accountFacet,\\n address verificationFacet,\\n address entryPoint,\\n address facetRegistry,\\n address defaultFallback,\\n bytes memory ownerPublicKey\\n ) external pure returns (bytes memory);\\n\\n function getCreationCode() external pure returns (bytes memory);\\n}\\n\",\"keccak256\":\"0xadb48a6f3025f6395e26ffd5f9319da73ad2383906c8223e8455f41f420fba26\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\\n bytes4(keccak256(\\\"verifyRestrictions(address,address,uint256,bytes)\\\"));\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // Default Fallback Handler of the barz.\\n IDiamondLoupe defaultFallbackHandler;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function enforceIsSelf() internal view {\\n require(msg.sender == address(this), \\\"LibDiamond: Caller not self\\\");\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n\\n unchecked {\\n facetIndex++;\\n }\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n\\n function restrictionsFacet() internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(\\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2cabdc00de859c3a3170ce3bda5d0e5fd3933d47ce904fd1585f9818b02572f8\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x61010060405234801561001157600080fd5b50604051610eba380380610eba8339810160408190526100309161006e565b6001600160a01b0393841660805291831660a052821660c0521660e0526100c2565b80516001600160a01b038116811461006957600080fd5b919050565b6000806000806080858703121561008457600080fd5b61008d85610052565b935061009b60208601610052565b92506100a960408601610052565b91506100b760608601610052565b905092959194509250565b60805160a05160c05160e051610d886101326000396000818161013b015281816102b3015261048101526000818160bf01528181610292015261046001526000818161016301528181610271015261043f01526000818161018b0152818161024f015261041d0152610d886000f3fe60806040523480156200001157600080fd5b5060043610620000925760003560e01c806344409a82116200006257806344409a821462000135578063b0d691fe146200015d578063b0f5d4641462000185578063c8a7adf514620001ad57600080fd5b8062c194db14620000975780630a1acd7314620000b9578063296601cd146200010757806333bb64a7146200011e575b600080fd5b620000a1620001c4565b604051620000b091906200056c565b60405180910390f35b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001620000b0565b620000e16200011836600462000635565b6200020e565b620000a16200012f36600462000695565b6200036d565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e1620001be36600462000635565b62000414565b606060405180602001620001d89062000538565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082820381018352601f90910116604052919050565b6000806200021f8686868662000414565b905073ffffffffffffffffffffffffffffffffffffffff81163b8015620002495750905062000365565b8360001b7f0000000000000000000000000000000000000000000000000000000000000000887f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008b8b604051620002e29062000538565b620002f497969594939291906200073a565b8190604051809103906000f590508015801562000315573d6000803e3d6000fd5b5060405173ffffffffffffffffffffffffffffffffffffffff821681529093507f9e6e326008e68f57877e2bae766a5745c162e42359e34834a7f0661fa82d31b19060200160405180910390a150505b949350505050565b6060600060405180602001620003839062000538565b6020820181038252601f19601f8201166040525090508089898989898989604051602001620003b997969594939291906200073a565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052620003f79291602001620007cd565b604051602081830303815290604052915050979650505050505050565b600080620004a87f0000000000000000000000000000000000000000000000000000000000000000877f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008a8a6200036d565b8051602091820120604080517fff00000000000000000000000000000000000000000000000000000000000000818501523060601b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001660218201526035810196909652605580870192909252805180870390920182526075909501909452835193019290922095945050505050565b610552806200080183390190565b60005b838110156200056357818101518382015260200162000549565b50506000910152565b60208152600082518060208401526200058d81604085016020870162000546565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b803573ffffffffffffffffffffffffffffffffffffffff81168114620005e457600080fd5b919050565b60008083601f840112620005fc57600080fd5b50813567ffffffffffffffff8111156200061557600080fd5b6020830191508360208285010111156200062e57600080fd5b9250929050565b600080600080606085870312156200064c57600080fd5b6200065785620005bf565b9350602085013567ffffffffffffffff8111156200067457600080fd5b6200068287828801620005e9565b9598909750949560400135949350505050565b600080600080600080600060c0888a031215620006b157600080fd5b620006bc88620005bf565b9650620006cc60208901620005bf565b9550620006dc60408901620005bf565b9450620006ec60608901620005bf565b9350620006fc60808901620005bf565b925060a088013567ffffffffffffffff8111156200071957600080fd5b620007278a828b01620005e9565b989b979a50959850939692959293505050565b600073ffffffffffffffffffffffffffffffffffffffff808a16835280891660208401528088166040840152808716606084015280861660808401525060c060a08301528260c0830152828460e0840137600060e0848401015260e07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f850116830101905098975050505050505050565b60008351620007e181846020880162000546565b835190830190620007f781836020880162000546565b0194935050505056fe608060405260405161055238038061055283398101604081905261002291610163565b6000858585858560405160240161003d959493929190610264565b60408051601f198184030181529181526020820180516001600160e01b0316634a93641760e01b1790525190915060009081906001600160a01b038a16906100869085906102c3565b600060405180830381855af49150503d80600081146100c1576040519150601f19603f3d011682016040523d82523d6000602084013e6100c6565b606091505b50915091508115806100e157506100dc816102df565b600114155b156100ff57604051636ff35f8960e01b815260040160405180910390fd5b505050505050505050610306565b80516001600160a01b038116811461012457600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101561015a578181015183820152602001610142565b50506000910152565b60008060008060008060c0878903121561017c57600080fd5b6101858761010d565b95506101936020880161010d565b94506101a16040880161010d565b93506101af6060880161010d565b92506101bd6080880161010d565b60a08801519092506001600160401b03808211156101da57600080fd5b818901915089601f8301126101ee57600080fd5b81518181111561020057610200610129565b604051601f8201601f19908116603f0116810190838211818310171561022857610228610129565b816040528281528c602084870101111561024157600080fd5b61025283602083016020880161013f565b80955050505050509295509295509295565b600060018060a01b0380881683528087166020840152808616604084015280851660608401525060a0608083015282518060a08401526102ab8160c085016020870161013f565b601f01601f19169190910160c0019695505050505050565b600082516102d581846020870161013f565b9190910192915050565b80516020808301519190811015610300576000198160200360031b1b821691505b50919050565b61023d806103156000396000f3fe60806040523661000b57005b600080357fffffffff000000000000000000000000000000000000000000000000000000001681527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020819052604090912054819060601c80610125576004838101546040517fcdffacc60000000000000000000000000000000000000000000000000000000081526000357fffffffff00000000000000000000000000000000000000000000000000000000169281019290925273ffffffffffffffffffffffffffffffffffffffff169063cdffacc690602401602060405180830381865afa1580156100fe573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061012291906101ca565b90505b73ffffffffffffffffffffffffffffffffffffffff81166101a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4261727a3a2046756e6374696f6e20646f6573206e6f74206578697374000000604482015260640160405180910390fd5b3660008037600080366000845af43d6000803e8080156101c5573d6000f35b3d6000fd5b6000602082840312156101dc57600080fd5b815173ffffffffffffffffffffffffffffffffffffffff8116811461020057600080fd5b939250505056fea26469706673582212200f3fa76ace3be8675d8b4c0d6c210a922fff2c2f1444023b817d1f6c908cd56a64736f6c63430008150033a2646970667358221220329ad45a4ef4915180001cb1fc90a5f97ad94a0b280426a580cba65fce28c0f164736f6c63430008150033", + "deployedBytecode": "0x60806040523480156200001157600080fd5b5060043610620000925760003560e01c806344409a82116200006257806344409a821462000135578063b0d691fe146200015d578063b0f5d4641462000185578063c8a7adf514620001ad57600080fd5b8062c194db14620000975780630a1acd7314620000b9578063296601cd146200010757806333bb64a7146200011e575b600080fd5b620000a1620001c4565b604051620000b091906200056c565b60405180910390f35b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001620000b0565b620000e16200011836600462000635565b6200020e565b620000a16200012f36600462000695565b6200036d565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e17f000000000000000000000000000000000000000000000000000000000000000081565b620000e1620001be36600462000635565b62000414565b606060405180602001620001d89062000538565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082820381018352601f90910116604052919050565b6000806200021f8686868662000414565b905073ffffffffffffffffffffffffffffffffffffffff81163b8015620002495750905062000365565b8360001b7f0000000000000000000000000000000000000000000000000000000000000000887f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008b8b604051620002e29062000538565b620002f497969594939291906200073a565b8190604051809103906000f590508015801562000315573d6000803e3d6000fd5b5060405173ffffffffffffffffffffffffffffffffffffffff821681529093507f9e6e326008e68f57877e2bae766a5745c162e42359e34834a7f0661fa82d31b19060200160405180910390a150505b949350505050565b6060600060405180602001620003839062000538565b6020820181038252601f19601f8201166040525090508089898989898989604051602001620003b997969594939291906200073a565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052620003f79291602001620007cd565b604051602081830303815290604052915050979650505050505050565b600080620004a87f0000000000000000000000000000000000000000000000000000000000000000877f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008a8a6200036d565b8051602091820120604080517fff00000000000000000000000000000000000000000000000000000000000000818501523060601b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001660218201526035810196909652605580870192909252805180870390920182526075909501909452835193019290922095945050505050565b610552806200080183390190565b60005b838110156200056357818101518382015260200162000549565b50506000910152565b60208152600082518060208401526200058d81604085016020870162000546565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b803573ffffffffffffffffffffffffffffffffffffffff81168114620005e457600080fd5b919050565b60008083601f840112620005fc57600080fd5b50813567ffffffffffffffff8111156200061557600080fd5b6020830191508360208285010111156200062e57600080fd5b9250929050565b600080600080606085870312156200064c57600080fd5b6200065785620005bf565b9350602085013567ffffffffffffffff8111156200067457600080fd5b6200068287828801620005e9565b9598909750949560400135949350505050565b600080600080600080600060c0888a031215620006b157600080fd5b620006bc88620005bf565b9650620006cc60208901620005bf565b9550620006dc60408901620005bf565b9450620006ec60608901620005bf565b9350620006fc60808901620005bf565b925060a088013567ffffffffffffffff8111156200071957600080fd5b620007278a828b01620005e9565b989b979a50959850939692959293505050565b600073ffffffffffffffffffffffffffffffffffffffff808a16835280891660208401528088166040840152808716606084015280861660808401525060c060a08301528260c0830152828460e0840137600060e0848401015260e07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f850116830101905098975050505050505050565b60008351620007e181846020880162000546565b835190830190620007f781836020880162000546565b0194935050505056fe608060405260405161055238038061055283398101604081905261002291610163565b6000858585858560405160240161003d959493929190610264565b60408051601f198184030181529181526020820180516001600160e01b0316634a93641760e01b1790525190915060009081906001600160a01b038a16906100869085906102c3565b600060405180830381855af49150503d80600081146100c1576040519150601f19603f3d011682016040523d82523d6000602084013e6100c6565b606091505b50915091508115806100e157506100dc816102df565b600114155b156100ff57604051636ff35f8960e01b815260040160405180910390fd5b505050505050505050610306565b80516001600160a01b038116811461012457600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101561015a578181015183820152602001610142565b50506000910152565b60008060008060008060c0878903121561017c57600080fd5b6101858761010d565b95506101936020880161010d565b94506101a16040880161010d565b93506101af6060880161010d565b92506101bd6080880161010d565b60a08801519092506001600160401b03808211156101da57600080fd5b818901915089601f8301126101ee57600080fd5b81518181111561020057610200610129565b604051601f8201601f19908116603f0116810190838211818310171561022857610228610129565b816040528281528c602084870101111561024157600080fd5b61025283602083016020880161013f565b80955050505050509295509295509295565b600060018060a01b0380881683528087166020840152808616604084015280851660608401525060a0608083015282518060a08401526102ab8160c085016020870161013f565b601f01601f19169190910160c0019695505050505050565b600082516102d581846020870161013f565b9190910192915050565b80516020808301519190811015610300576000198160200360031b1b821691505b50919050565b61023d806103156000396000f3fe60806040523661000b57005b600080357fffffffff000000000000000000000000000000000000000000000000000000001681527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6020819052604090912054819060601c80610125576004838101546040517fcdffacc60000000000000000000000000000000000000000000000000000000081526000357fffffffff00000000000000000000000000000000000000000000000000000000169281019290925273ffffffffffffffffffffffffffffffffffffffff169063cdffacc690602401602060405180830381865afa1580156100fe573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061012291906101ca565b90505b73ffffffffffffffffffffffffffffffffffffffff81166101a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4261727a3a2046756e6374696f6e20646f6573206e6f74206578697374000000604482015260640160405180910390fd5b3660008037600080366000845af43d6000803e8080156101c5573d6000f35b3d6000fd5b6000602082840312156101dc57600080fd5b815173ffffffffffffffffffffffffffffffffffffffff8116811461020057600080fd5b939250505056fea26469706673582212200f3fa76ace3be8675d8b4c0d6c210a922fff2c2f1444023b817d1f6c908cd56a64736f6c63430008150033a2646970667358221220329ad45a4ef4915180001cb1fc90a5f97ad94a0b280426a580cba65fce28c0f164736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "Contract to easily deploy Barz to a pre-computed address with a single call", + "kind": "dev", + "methods": { + "constructor": { + "params": { + "_accountFacet": "Account Facet to be used to create Barz", + "_defaultFallback": "Default Fallback Handler to be used to create Barz", + "_entryPoint": "Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF", + "_facetRegistry": "Facet Registry to be used to create Barz" + } + }, + "createAccount(address,bytes,uint256)": { + "params": { + "_owner": "Public Key of the owner to initialize barz account", + "_salt": "Salt used for deploying barz with create2", + "_verificationFacet": "Address of verification facet used for creating the barz account" + }, + "returns": { + "barz": "Instance of Barz contract deployed with the given parameters" + } + }, + "getAddress(address,bytes,uint256)": { + "params": { + "_owner": "Public Key of the owner to initialize barz account", + "_salt": "Salt used for deploying barz with create2", + "_verificationFacet": "Address of verification facet used for creating the barz account" + }, + "returns": { + "barzAddress": "Precalculated Barz address" + } + }, + "getBytecode(address,address,address,address,address,bytes)": { + "params": { + "_accountFacet": "Account Facet to be used to create Barz", + "_defaultFallback": "Default Fallback Handler to be used to create Barz", + "_entryPoint": "Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF", + "_facetRegistry": "Facet Registry to be used to create Barz", + "_ownerPublicKey": "Public Key of owner to be used to initialize Barz ownership", + "_verificationFacet": "Verification Facet to be used to create Barz" + }, + "returns": { + "barzBytecode": "Bytecode of Barz" + } + }, + "getCreationCode()": { + "returns": { + "creationCode": "Creation code of Barz" + } + } + }, + "title": "Barz Factory", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "constructor": { + "notice": "Sets the initialization data for Barz contract initialization" + }, + "createAccount(address,bytes,uint256)": { + "notice": "Creates the Barz with a single call. It creates the Barz contract with the givent verification facet" + }, + "getAddress(address,bytes,uint256)": { + "notice": "Calculates the address of Barz with the given parameters" + }, + "getBytecode(address,address,address,address,address,bytes)": { + "notice": "Returns the bytecode of Barz with the given parameter" + }, + "getCreationCode()": { + "notice": "Returns the creation code of the Barz contract" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/polygon/DefaultFallbackHandler.json b/deployments/polygon/DefaultFallbackHandler.json new file mode 100644 index 0000000..8728e8e --- /dev/null +++ b/deployments/polygon/DefaultFallbackHandler.json @@ -0,0 +1,290 @@ +{ + "address": "0x2e7f1dAe1F3799d20f5c31bEFdc7A620f664728D", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_diamondCutFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_accountFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_tokenReceiverFacet", + "type": "address" + }, + { + "internalType": "address", + "name": "_diamondLoupeFacet", + "type": "address" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_initializationContractAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "InitializationFunctionReverted", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "indexed": false, + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "DiamondCut", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_functionSelector", + "type": "bytes4" + } + ], + "name": "facetAddress", + "outputs": [ + { + "internalType": "address", + "name": "facetAddress_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetAddresses", + "outputs": [ + { + "internalType": "address[]", + "name": "facetAddresses_", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_facet", + "type": "address" + } + ], + "name": "facetFunctionSelectors", + "outputs": [ + { + "internalType": "bytes4[]", + "name": "facetFunctionSelectors_", + "type": "bytes4[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facets", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondLoupe.Facet[]", + "name": "facets_", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0x7ef2f527b0c4c7fb371cb0654fa9ba766263d59fcfdbfe96e13e25d442b8841c", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 44, + "gasUsed": "1438535", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000008000000000000008000000000000000000000000000000000000000000800000000001000000000900002000000000000000000000001000000000000000000000000000000080000000000000000020000000000000000000000000000000000000000000000000000000000000201000000000000000000000020000000000000000000000000000000000004200000000000000000001000000000000000000000000000000100000000000000000000000000000000000000000000000000000000020000000100000100000", + "blockHash": "0x8bc24f53071ffba2ddd4bd048059f914e8d5421b760f0490d051f9b224ba06b6", + "transactionHash": "0x7ef2f527b0c4c7fb371cb0654fa9ba766263d59fcfdbfe96e13e25d442b8841c", + "logs": [ + { + "transactionIndex": 44, + "blockNumber": 50172522, + "transactionHash": "0x7ef2f527b0c4c7fb371cb0654fa9ba766263d59fcfdbfe96e13e25d442b8841c", + "address": "0x2e7f1dAe1F3799d20f5c31bEFdc7A620f664728D", + "topics": [ + "0x8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb673" + ], + "data": "0x000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000580000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000000000000000000000000000000000003600000000000000000000000000b9504140771c3688ff041917192277d2f52e1e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000011f931c1c00000000000000000000000000000000000000000000000000000000000000000000000000000000fde53272dcd7938d16e031a6989753c321728332000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000005b61d27f60000000000000000000000000000000000000000000000000000000047e1da2a000000000000000000000000000000000000000000000000000000003a871cdd00000000000000000000000000000000000000000000000000000000d087d28800000000000000000000000000000000000000000000000000000000b0d691fe000000000000000000000000000000000000000000000000000000000000000000000000000000003143e1c0af0cdc153423863923cf4e3818e34daa000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000005150b7a0200000000000000000000000000000000000000000000000000000000f23a6e6100000000000000000000000000000000000000000000000000000000bc197c81000000000000000000000000000000000000000000000000000000000023de2900000000000000000000000000000000000000000000000000000000a4c0ed3600000000000000000000000000000000000000000000000000000000000000000000000000000000ce36b85d12d81cd619c745c7717f3396e184ac7c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000097a0ed62700000000000000000000000000000000000000000000000000000000adfca15e0000000000000000000000000000000000000000000000000000000052ef6b2c00000000000000000000000000000000000000000000000000000000cdffacc60000000000000000000000000000000000000000000000000000000001ffc9a700000000000000000000000000000000000000000000000000000000f9796ccf0000000000000000000000000000000000000000000000000000000001a5502200000000000000000000000000000000000000000000000000000000d42139a900000000000000000000000000000000000000000000000000000000e3a2f6fe000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "logIndex": 117, + "blockHash": "0x8bc24f53071ffba2ddd4bd048059f914e8d5421b760f0490d051f9b224ba06b6" + }, + { + "transactionIndex": 44, + "blockNumber": 50172522, + "transactionHash": "0x7ef2f527b0c4c7fb371cb0654fa9ba766263d59fcfdbfe96e13e25d442b8841c", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x000000000000000000000000d87df9fd27b9a30fe27e7b294caaa4673f34b6b1", + "0x000000000000000000000000742d13f0b2a19c823bdd362b16305e4704b97a38" + ], + "data": "0x00000000000000000000000000000000000000000000000000e16c7c598b3cb9000000000000000000000000000000000000000000000000b6a50db9381ad5c1000000000000000000000000000000000000000000001aa5edb8b6126453db01000000000000000000000000000000000000000000000000b5c3a13cde8f9908000000000000000000000000000000000000000000001aa5ee9a228ebddf17ba", + "logIndex": 118, + "blockHash": "0x8bc24f53071ffba2ddd4bd048059f914e8d5421b760f0490d051f9b224ba06b6" + } + ], + "blockNumber": 50172522, + "cumulativeGasUsed": "5544526", + "status": 1, + "byzantium": true + }, + "args": [ + "0x0B9504140771C3688Ff041917192277D2f52E1e0", + "0xFde53272dcd7938d16E031A6989753c321728332", + "0x3143E1C0Af0Cdc153423863923Cf4e3818e34Daa", + "0xCe36b85d12D81cd619C745c7717f3396E184Ac7C" + ], + "numDeployments": 3, + "solcInputHash": "4356503edd8ae34e73cb6dd1c8e2fc8a", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_diamondCutFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_accountFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_tokenReceiverFacet\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_diamondLoupeFacet\",\"type\":\"address\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_initializationContractAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"InitializationFunctionReverted\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"DiamondCut\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_functionSelector\",\"type\":\"bytes4\"}],\"name\":\"facetAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"facetAddress_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetAddresses\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"facetAddresses_\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_facet\",\"type\":\"address\"}],\"name\":\"facetFunctionSelectors\",\"outputs\":[{\"internalType\":\"bytes4[]\",\"name\":\"facetFunctionSelectors_\",\"type\":\"bytes4[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facets\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondLoupe.Facet[]\",\"name\":\"facets_\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"A default fallback handler for Barz\",\"kind\":\"dev\",\"methods\":{\"constructor\":{\"details\":\"This contract is also a diamond that holds the default facets to reduce gas cost for wallet activation. Within the constructor this conducts diamond cut to initially setup the diamond. This is a non-upgradeable contract\",\"params\":{\"_accountFacet\":\"Address account facet\",\"_diamondCutFacet\":\"Address if diamond cut facet\",\"_diamondLoupeFacet\":\"Address of diamond loupe facet\",\"_tokenReceiverFacet\":\"Address of token receiver facet\"}},\"facetAddress(bytes4)\":{\"details\":\"If facet is not found return address(0).\",\"params\":{\"_functionSelector\":\"The function selector.\"},\"returns\":{\"facetAddress_\":\"The facet address.\"}},\"facetAddresses()\":{\"returns\":{\"facetAddresses_\":\"facetAddresses_\"}},\"facetFunctionSelectors(address)\":{\"params\":{\"_facet\":\"The facet address.\"},\"returns\":{\"facetFunctionSelectors_\":\"facetFunctionSelectors_\"}},\"facets()\":{\"returns\":{\"facets_\":\"The facet struct array including all facet information\"}}},\"title\":\"DefaultFallbackHandler\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"Sets the middleware diamond for Barz wallet as a fallback handler\"},\"facetAddress(bytes4)\":{\"notice\":\"Gets the facet that supports the given selector.\"},\"facetAddresses()\":{\"notice\":\"Get all the facet addresses used by a diamond.\"},\"facetFunctionSelectors(address)\":{\"notice\":\"Gets all the function selectors provided by a facet.\"},\"facets()\":{\"notice\":\"Returns the facet information of call facets registered to this diamond.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/infrastructure/DefaultFallbackHandler.sol\":\"DefaultFallbackHandler\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/introspection/IERC165.sol\\\";\\n\\n/**\\n * @dev _Available since v3.1._\\n */\\ninterface IERC1155Receiver is IERC165 {\\n /**\\n * @dev Handles the receipt of a single ERC1155 token type. This function is\\n * called at the end of a `safeTransferFrom` after the balance has been updated.\\n *\\n * NOTE: To accept the transfer, this must return\\n * `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))`\\n * (i.e. 0xf23a6e61, or its own function selector).\\n *\\n * @param operator The address which initiated the transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param id The ID of the token being transferred\\n * @param value The amount of tokens being transferred\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155Received(\\n address operator,\\n address from,\\n uint256 id,\\n uint256 value,\\n bytes calldata data\\n ) external returns (bytes4);\\n\\n /**\\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\\n * is called at the end of a `safeBatchTransferFrom` after the balances have\\n * been updated.\\n *\\n * NOTE: To accept the transfer(s), this must return\\n * `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))`\\n * (i.e. 0xbc197c81, or its own function selector).\\n *\\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155BatchReceived(\\n address operator,\\n address from,\\n uint256[] calldata ids,\\n uint256[] calldata values,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xeb373f1fdc7b755c6a750123a9b9e3a8a02c1470042fd6505d875000a80bde0b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title ERC721 token receiver interface\\n * @dev Interface for any contract that wants to support safeTransfers\\n * from ERC721 asset contracts.\\n */\\ninterface IERC721Receiver {\\n /**\\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\\n * by `operator` from `from`, this function is called.\\n *\\n * It must return its Solidity selector to confirm the token transfer.\\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\\n *\\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\\n */\\n function onERC721Received(\\n address operator,\\n address from,\\n uint256 tokenId,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\\n *\\n * Accounts can be notified of {IERC777} tokens being sent to them by having a\\n * contract implement this interface (contract holders can be their own\\n * implementer) and registering it on the\\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\\n *\\n * See {IERC1820Registry} and {ERC1820Implementer}.\\n */\\ninterface IERC777Recipient {\\n /**\\n * @dev Called by an {IERC777} token contract whenever tokens are being\\n * moved or created into a registered account (`to`). The type of operation\\n * is conveyed by `from` being the zero address or not.\\n *\\n * This call occurs _after_ the token contract's state is updated, so\\n * {IERC777-balanceOf}, etc., can be used to query the post-operation state.\\n *\\n * This function may revert to prevent the operation from being executed.\\n */\\n function tokensReceived(\\n address operator,\\n address from,\\n address to,\\n uint256 amount,\\n bytes calldata userData,\\n bytes calldata operatorData\\n ) external;\\n}\\n\",\"keccak256\":\"0x1a5d61db2733202ba361e6d6741cd2e662380e22b80e987eacfc91973f2267dc\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"contracts/aa-4337/core/BaseAccount.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-empty-blocks */\\n\\nimport \\\"../interfaces/IAccount.sol\\\";\\nimport \\\"../interfaces/IEntryPoint.sol\\\";\\nimport \\\"./Helpers.sol\\\";\\n\\n/**\\n * Basic account implementation.\\n * this contract provides the basic logic for implementing the IAccount interface - validateUserOp\\n * specific account implementation should inherit it and provide the account-specific logic\\n */\\nabstract contract BaseAccount is IAccount {\\n using UserOperationLib for UserOperation;\\n\\n //return value in case of signature failure, with no time-range.\\n // equivalent to _packValidationData(true,0,0);\\n uint256 internal constant SIG_VALIDATION_FAILED = 1;\\n\\n /**\\n * Return the account nonce.\\n * This method returns the next sequential nonce.\\n * For a nonce of a specific key, use `entrypoint.getNonce(account, key)`\\n */\\n function getNonce() public view virtual returns (uint256) {\\n return entryPoint().getNonce(address(this), 0);\\n }\\n\\n /**\\n * return the entryPoint used by this account.\\n * subclass should return the current entryPoint used by this account.\\n */\\n function entryPoint() public view virtual returns (IEntryPoint);\\n\\n /**\\n * Validate user's signature and nonce.\\n * subclass doesn't need to override this method. Instead, it should override the specific internal validation methods.\\n */\\n function validateUserOp(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n uint256 missingAccountFunds\\n ) external virtual override returns (uint256 validationData) {\\n _requireFromEntryPoint();\\n validationData = _validateSignature(userOp, userOpHash);\\n _validateNonce(userOp.nonce);\\n _payPrefund(missingAccountFunds);\\n }\\n\\n /**\\n * ensure the request comes from the known entrypoint.\\n */\\n function _requireFromEntryPoint() internal view virtual {\\n require(\\n msg.sender == address(entryPoint()),\\n \\\"account: not from EntryPoint\\\"\\n );\\n }\\n\\n /**\\n * validate the signature is valid for this message.\\n * @param userOp validate the userOp.signature field\\n * @param userOpHash convenient field: the hash of the request, to check the signature against\\n * (also hashes the entrypoint and chain id)\\n * @return validationData signature and time-range of this operation\\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\\n * otherwise, an address of an \\\"authorizer\\\" contract.\\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \\\"indefinite\\\"\\n * <6-byte> validAfter - first timestamp this operation is valid\\n * If the account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\\n */\\n function _validateSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) internal virtual returns (uint256 validationData);\\n\\n /**\\n * Validate the nonce of the UserOperation.\\n * This method may validate the nonce requirement of this account.\\n * e.g.\\n * To limit the nonce to use sequenced UserOps only (no \\\"out of order\\\" UserOps):\\n * `require(nonce < type(uint64).max)`\\n * For a hypothetical account that *requires* the nonce to be out-of-order:\\n * `require(nonce & type(uint64).max == 0)`\\n *\\n * The actual nonce uniqueness is managed by the EntryPoint, and thus no other\\n * action is needed by the account itself.\\n *\\n * @param nonce to validate\\n *\\n * solhint-disable-next-line no-empty-blocks\\n */\\n function _validateNonce(uint256 nonce) internal view virtual {}\\n\\n /**\\n * sends to the entrypoint (msg.sender) the missing funds for this transaction.\\n * subclass MAY override this method for better funds management\\n * (e.g. send to the entryPoint more than the minimum required, so that in future transactions\\n * it will not be required to send again)\\n * @param missingAccountFunds the minimum value this method should send the entrypoint.\\n * this value MAY be zero, in case there is enough deposit, or the userOp has a paymaster.\\n */\\n function _payPrefund(uint256 missingAccountFunds) internal virtual {\\n if (missingAccountFunds != 0) {\\n (bool success, ) = payable(msg.sender).call{\\n value: missingAccountFunds,\\n gas: type(uint256).max\\n }(\\\"\\\");\\n (success);\\n //ignore failure (its EntryPoint's job to verify, not account.)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa0dcc386b0f04711db3e394fb50e55a3b3b1a4d19fac1f10895844e1aa4e3d5c\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/core/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable no-inline-assembly */\\n\\n/**\\n * returned data from validateUserOp.\\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\\n * @param aggregator - address(0) - the account validated the signature by itself.\\n * address(1) - the account failed to validate the signature.\\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\\n * @param validAfter - this UserOp is valid only after this timestamp.\\n * @param validaUntil - this UserOp is valid only up to this timestamp.\\n */\\nstruct ValidationData {\\n address aggregator;\\n uint48 validAfter;\\n uint48 validUntil;\\n}\\n\\n//extract sigFailed, validAfter, validUntil.\\n// also convert zero validUntil to type(uint48).max\\nfunction _parseValidationData(\\n uint validationData\\n) pure returns (ValidationData memory data) {\\n address aggregator = address(uint160(validationData));\\n uint48 validUntil = uint48(validationData >> 160);\\n if (validUntil == 0) {\\n validUntil = type(uint48).max;\\n }\\n uint48 validAfter = uint48(validationData >> (48 + 160));\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n// intersect account and paymaster ranges.\\nfunction _intersectTimeRange(\\n uint256 validationData,\\n uint256 paymasterValidationData\\n) pure returns (ValidationData memory) {\\n ValidationData memory accountValidationData = _parseValidationData(\\n validationData\\n );\\n ValidationData memory pmValidationData = _parseValidationData(\\n paymasterValidationData\\n );\\n address aggregator = accountValidationData.aggregator;\\n if (aggregator == address(0)) {\\n aggregator = pmValidationData.aggregator;\\n }\\n uint48 validAfter = accountValidationData.validAfter;\\n uint48 validUntil = accountValidationData.validUntil;\\n uint48 pmValidAfter = pmValidationData.validAfter;\\n uint48 pmValidUntil = pmValidationData.validUntil;\\n\\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp\\n * @param data - the ValidationData to pack\\n */\\nfunction _packValidationData(\\n ValidationData memory data\\n) pure returns (uint256) {\\n return\\n uint160(data.aggregator) |\\n (uint256(data.validUntil) << 160) |\\n (uint256(data.validAfter) << (160 + 48));\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp, when not using an aggregator\\n * @param sigFailed - true for signature failure, false for success\\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\\n * @param validAfter first timestamp this UserOperation is valid\\n */\\nfunction _packValidationData(\\n bool sigFailed,\\n uint48 validUntil,\\n uint48 validAfter\\n) pure returns (uint256) {\\n return\\n (sigFailed ? 1 : 0) |\\n (uint256(validUntil) << 160) |\\n (uint256(validAfter) << (160 + 48));\\n}\\n\\n/**\\n * keccak function over calldata.\\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\\n */\\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\\n assembly {\\n let mem := mload(0x40)\\n let len := data.length\\n calldatacopy(mem, data.offset, len)\\n ret := keccak256(mem, len)\\n }\\n}\\n\",\"keccak256\":\"0xa79f06cd158ecb8c0da95493a2f348933b8627a63e228b99738bff3aa107942d\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAccount.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\ninterface IAccount {\\n /**\\n * Validate user's signature and nonce\\n * the entryPoint will make the call to the recipient only if this validation call returns successfully.\\n * signature failure should be reported by returning SIG_VALIDATION_FAILED (1).\\n * This allows making a \\\"simulation call\\\" without a valid signature\\n * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure.\\n *\\n * @dev Must validate caller is the entryPoint.\\n * Must validate the signature and nonce\\n * @param userOp the operation that is about to be executed.\\n * @param userOpHash hash of the user's request data. can be used as the basis for signature.\\n * @param missingAccountFunds missing funds on the account's deposit in the entrypoint.\\n * This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call.\\n * The excess is left as a deposit in the entrypoint, for future calls.\\n * can be withdrawn anytime using \\\"entryPoint.withdrawTo()\\\"\\n * In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero.\\n * @return validationData packaged ValidationData structure. use `_packValidationData` and `_unpackValidationData` to encode and decode\\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\\n * otherwise, an address of an \\\"authorizer\\\" contract.\\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \\\"indefinite\\\"\\n * <6-byte> validAfter - first timestamp this operation is valid\\n * If an account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\\n */\\n function validateUserOp(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n uint256 missingAccountFunds\\n ) external returns (uint256 validationData);\\n}\\n\",\"keccak256\":\"0xcbc4b0973cf954c5895b7796335f651fbfcfb55f67dfa789a3d354f8e23c4f2b\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAggregator.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\n/**\\n * Aggregated Signatures validator.\\n */\\ninterface IAggregator {\\n /**\\n * validate aggregated signature.\\n * revert if the aggregated signature does not match the given list of operations.\\n */\\n function validateSignatures(\\n UserOperation[] calldata userOps,\\n bytes calldata signature\\n ) external view;\\n\\n /**\\n * validate signature of a single userOp\\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\\n * @param userOp the userOperation received from the user.\\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\\n * (usually empty, unless account and aggregator support some kind of \\\"multisig\\\"\\n */\\n function validateUserOpSignature(\\n UserOperation calldata userOp\\n ) external view returns (bytes memory sigForUserOp);\\n\\n /**\\n * aggregate multiple signatures into a single value.\\n * This method is called off-chain to calculate the signature to pass with handleOps()\\n * bundler MAY use optimized custom code perform this aggregation\\n * @param userOps array of UserOperations to collect the signatures from.\\n * @return aggregatedSignature the aggregated signature\\n */\\n function aggregateSignatures(\\n UserOperation[] calldata userOps\\n ) external view returns (bytes memory aggregatedSignature);\\n}\\n\",\"keccak256\":\"0xdfdcd80568f037716674619b31be630fcd8316262f05a815b41d1e81782c966a\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IEntryPoint.sol\":{\"content\":\"/**\\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\\n ** Only one instance required on each chain.\\n **/\\n// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-inline-assembly */\\n/* solhint-disable reason-string */\\n\\nimport \\\"./UserOperation.sol\\\";\\nimport \\\"./IStakeManager.sol\\\";\\nimport \\\"./IAggregator.sol\\\";\\nimport \\\"./INonceManager.sol\\\";\\n\\ninterface IEntryPoint is IStakeManager, INonceManager {\\n /***\\n * An event emitted after each successful request\\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\\n * @param sender - the account that generates this request.\\n * @param paymaster - if non-null, the paymaster that pays for this request.\\n * @param nonce - the nonce value from the request.\\n * @param success - true if the sender transaction succeeded, false if reverted.\\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\\n */\\n event UserOperationEvent(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address indexed paymaster,\\n uint256 nonce,\\n bool success,\\n uint256 actualGasCost,\\n uint256 actualGasUsed\\n );\\n\\n /**\\n * account \\\"sender\\\" was deployed.\\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\\n * @param sender the account that is deployed\\n * @param factory the factory used to deploy this account (in the initCode)\\n * @param paymaster the paymaster used by this UserOp\\n */\\n event AccountDeployed(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address factory,\\n address paymaster\\n );\\n\\n /**\\n * An event emitted if the UserOperation \\\"callData\\\" reverted with non-zero length\\n * @param userOpHash the request unique identifier.\\n * @param sender the sender of this request\\n * @param nonce the nonce used in the request\\n * @param revertReason - the return bytes from the (reverted) call to \\\"callData\\\".\\n */\\n event UserOperationRevertReason(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n uint256 nonce,\\n bytes revertReason\\n );\\n\\n /**\\n * an event emitted by handleOps(), before starting the execution loop.\\n * any event emitted before this event, is part of the validation.\\n */\\n event BeforeExecution();\\n\\n /**\\n * signature aggregator used by the following UserOperationEvents within this bundle.\\n */\\n event SignatureAggregatorChanged(address indexed aggregator);\\n\\n /**\\n * a custom revert error of handleOps, to identify the offending op.\\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\\n * @param reason - revert reason\\n * The string starts with a unique code \\\"AAmn\\\", where \\\"m\\\" is \\\"1\\\" for factory, \\\"2\\\" for account and \\\"3\\\" for paymaster issues,\\n * so a failure can be attributed to the correct entity.\\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\\n */\\n error FailedOp(uint256 opIndex, string reason);\\n\\n /**\\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\\n */\\n error SignatureValidationFailed(address aggregator);\\n\\n /**\\n * Successful result from simulateValidation.\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n */\\n error ValidationResult(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo\\n );\\n\\n /**\\n * Successful result from simulateValidation, if the account returns a signature aggregator\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\\n * bundler MUST use it to verify the signature, or reject the UserOperation\\n */\\n error ValidationResultWithAggregation(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo,\\n AggregatorStakeInfo aggregatorInfo\\n );\\n\\n /**\\n * return value of getSenderAddress\\n */\\n error SenderAddressResult(address sender);\\n\\n /**\\n * return value of simulateHandleOp\\n */\\n error ExecutionResult(\\n uint256 preOpGas,\\n uint256 paid,\\n uint48 validAfter,\\n uint48 validUntil,\\n bool targetSuccess,\\n bytes targetResult\\n );\\n\\n //UserOps handled, per aggregator\\n struct UserOpsPerAggregator {\\n UserOperation[] userOps;\\n // aggregator address\\n IAggregator aggregator;\\n // aggregated signature\\n bytes signature;\\n }\\n\\n /**\\n * Execute a batch of UserOperation.\\n * no signature aggregator is used.\\n * if any account requires an aggregator (that is, it returned an aggregator when\\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\\n * @param ops the operations to execute\\n * @param beneficiary the address to receive the fees\\n */\\n function handleOps(\\n UserOperation[] calldata ops,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * Execute a batch of UserOperation with Aggregators\\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\\n * @param beneficiary the address to receive the fees\\n */\\n function handleAggregatedOps(\\n UserOpsPerAggregator[] calldata opsPerAggregator,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * generate a request Id - unique identifier for this request.\\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\\n */\\n function getUserOpHash(\\n UserOperation calldata userOp\\n ) external view returns (bytes32);\\n\\n /**\\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\\n * @param userOp the user operation to validate.\\n */\\n function simulateValidation(UserOperation calldata userOp) external;\\n\\n /**\\n * gas and return values during simulation\\n * @param preOpGas the gas used for validation (including preValidationGas)\\n * @param prefund the required prefund for this operation\\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\\n */\\n struct ReturnInfo {\\n uint256 preOpGas;\\n uint256 prefund;\\n bool sigFailed;\\n uint48 validAfter;\\n uint48 validUntil;\\n bytes paymasterContext;\\n }\\n\\n /**\\n * returned aggregated signature info.\\n * the aggregator returned by the account, and its current stake.\\n */\\n struct AggregatorStakeInfo {\\n address aggregator;\\n StakeInfo stakeInfo;\\n }\\n\\n /**\\n * Get counterfactual sender address.\\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\\n * this method always revert, and returns the address in SenderAddressResult error\\n * @param initCode the constructor code to be passed into the UserOperation.\\n */\\n function getSenderAddress(bytes memory initCode) external;\\n\\n /**\\n * simulate full execution of a UserOperation (including both validation and target execution)\\n * this method will always revert with \\\"ExecutionResult\\\".\\n * it performs full validation of the UserOperation, but ignores signature error.\\n * an optional target address is called after the userop succeeds, and its value is returned\\n * (before the entire call is reverted)\\n * Note that in order to collect the the success/failure of the target call, it must be executed\\n * with trace enabled to track the emitted events.\\n * @param op the UserOperation to simulate\\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\\n * are set to the return from that call.\\n * @param targetCallData callData to pass to target address\\n */\\n function simulateHandleOp(\\n UserOperation calldata op,\\n address target,\\n bytes calldata targetCallData\\n ) external;\\n}\\n\",\"keccak256\":\"0x9ccb1b188eda8bbf5f6c2d01bd83c3d8b2b04fcf745283051d31fe96d1d8e40f\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/INonceManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\ninterface INonceManager {\\n /**\\n * Return the next nonce for this sender.\\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\\n * But UserOp with different keys can come with arbitrary order.\\n *\\n * @param sender the account address\\n * @param key the high 192 bit of the nonce\\n * @return nonce a full nonce to pass for next UserOp with this sender.\\n */\\n function getNonce(\\n address sender,\\n uint192 key\\n ) external view returns (uint256 nonce);\\n\\n /**\\n * Manually increment the nonce of the sender.\\n * This method is exposed just for completeness..\\n * Account does NOT need to call it, neither during validation, nor elsewhere,\\n * as the EntryPoint will update the nonce regardless.\\n * Possible use-case is call it with various keys to \\\"initialize\\\" their nonces to one, so that future\\n * UserOperations will not pay extra for the first transaction with a given key.\\n */\\n function incrementNonce(uint192 key) external;\\n}\\n\",\"keccak256\":\"0xce478ad0fa0d18a3b785ac854623029e7ab463d05873dfaa365abfa1bf100912\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IStakeManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8.12;\\n\\n/**\\n * manage deposits and stakes.\\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\\n * stake is value locked for at least \\\"unstakeDelay\\\" by the staked entity.\\n */\\ninterface IStakeManager {\\n event Deposited(address indexed account, uint256 totalDeposit);\\n\\n event Withdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /// Emitted when stake or unstake delay are modified\\n event StakeLocked(\\n address indexed account,\\n uint256 totalStaked,\\n uint256 unstakeDelaySec\\n );\\n\\n /// Emitted once a stake is scheduled for withdrawal\\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\\n\\n event StakeWithdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /**\\n * @param deposit the entity's deposit\\n * @param staked true if this entity is staked.\\n * @param stake actual amount of ether staked for this entity.\\n * @param unstakeDelaySec minimum delay to withdraw the stake.\\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\\n * and the rest fit into a 2nd cell.\\n * 112 bit allows for 10^15 eth\\n * 48 bit for full timestamp\\n * 32 bit allows 150 years for unstake delay\\n */\\n struct DepositInfo {\\n uint112 deposit;\\n bool staked;\\n uint112 stake;\\n uint32 unstakeDelaySec;\\n uint48 withdrawTime;\\n }\\n\\n //API struct used by getStakeInfo and simulateValidation\\n struct StakeInfo {\\n uint256 stake;\\n uint256 unstakeDelaySec;\\n }\\n\\n /// @return info - full deposit information of given account\\n function getDepositInfo(\\n address account\\n ) external view returns (DepositInfo memory info);\\n\\n /// @return the deposit (for gas payment) of the account\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * add to the deposit of the given account\\n */\\n function depositTo(address account) external payable;\\n\\n /**\\n * add to the account's stake - amount and delay\\n * any pending unstake is first cancelled.\\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\\n */\\n function addStake(uint32 _unstakeDelaySec) external payable;\\n\\n /**\\n * attempt to unlock the stake.\\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\\n */\\n function unlockStake() external;\\n\\n /**\\n * withdraw from the (unlocked) stake.\\n * must first call unlockStake and wait for the unstakeDelay to pass\\n * @param withdrawAddress the address to send withdrawn value.\\n */\\n function withdrawStake(address payable withdrawAddress) external;\\n\\n /**\\n * withdraw from the deposit.\\n * @param withdrawAddress the address to send withdrawn value.\\n * @param withdrawAmount the amount to withdraw.\\n */\\n function withdrawTo(\\n address payable withdrawAddress,\\n uint256 withdrawAmount\\n ) external;\\n}\\n\",\"keccak256\":\"0xadcea606c9b7aafe6645441f2154a60f271330b0eee5292a632aa71c1672d546\",\"license\":\"GPL-3.0-only\"},\"contracts/aa-4337/interfaces/UserOperation.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable no-inline-assembly */\\n\\nimport {calldataKeccak} from \\\"../core/Helpers.sol\\\";\\n\\n/**\\n * User Operation struct\\n * @param sender the sender account of this request.\\n * @param nonce unique value the sender uses to verify it is not a replay.\\n * @param initCode if set, the account contract will be created by this constructor/\\n * @param callData the method call to execute on this account.\\n * @param callGasLimit the gas limit passed to the callData method call.\\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\\n * @param maxFeePerGas same as EIP-1559 gas parameter.\\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\\n */\\nstruct UserOperation {\\n address sender;\\n uint256 nonce;\\n bytes initCode;\\n bytes callData;\\n uint256 callGasLimit;\\n uint256 verificationGasLimit;\\n uint256 preVerificationGas;\\n uint256 maxFeePerGas;\\n uint256 maxPriorityFeePerGas;\\n bytes paymasterAndData;\\n bytes signature;\\n}\\n\\n/**\\n * Utility functions helpful when working with UserOperation structs.\\n */\\nlibrary UserOperationLib {\\n function getSender(\\n UserOperation calldata userOp\\n ) internal pure returns (address) {\\n address data;\\n //read sender from userOp, which is first userOp member (saves 800 gas...)\\n assembly {\\n data := calldataload(userOp)\\n }\\n return address(uint160(data));\\n }\\n\\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\\n // pay above what he signed for.\\n function gasPrice(\\n UserOperation calldata userOp\\n ) internal view returns (uint256) {\\n unchecked {\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n if (maxFeePerGas == maxPriorityFeePerGas) {\\n //legacy mode (for networks that don't support basefee opcode)\\n return maxFeePerGas;\\n }\\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\\n }\\n }\\n\\n function pack(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes memory ret) {\\n address sender = getSender(userOp);\\n uint256 nonce = userOp.nonce;\\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\\n bytes32 hashCallData = calldataKeccak(userOp.callData);\\n uint256 callGasLimit = userOp.callGasLimit;\\n uint256 verificationGasLimit = userOp.verificationGasLimit;\\n uint256 preVerificationGas = userOp.preVerificationGas;\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\\n\\n return\\n abi.encode(\\n sender,\\n nonce,\\n hashInitCode,\\n hashCallData,\\n callGasLimit,\\n verificationGasLimit,\\n preVerificationGas,\\n maxFeePerGas,\\n maxPriorityFeePerGas,\\n hashPaymasterAndData\\n );\\n }\\n\\n function hash(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes32) {\\n return keccak256(pack(userOp));\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n}\\n\",\"keccak256\":\"0x2429f5cc546bdee08c7e63858d0dda8491eaa3ab5194df884dc948c1154d2834\",\"license\":\"GPL-3.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IStorageLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"./IDiamondLoupe.sol\\\";\\n\\n/**\\n * @title LoupeFromStorage Interface\\n * @dev Interface contract to function as a loupe facet directly attached to diamond storage of Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IStorageLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facetsFromStorage()\\n external\\n view\\n returns (IDiamondLoupe.Facet[] memory);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n function facetFunctionSelectorsFromStorage(\\n address _facet\\n ) external view returns (bytes4[] memory);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n function facetAddressesFromStorage()\\n external\\n view\\n returns (address[] memory);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n function facetAddressFromStorage(\\n bytes4 _functionSelector\\n ) external view returns (address);\\n}\\n\",\"keccak256\":\"0xdf5dc9c57319e9087628c9cf9404b4f75585b76d1c2f4f59ee796c933967ea5c\",\"license\":\"Apache-2.0\"},\"contracts/facets/interfaces/IAccountFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IEntryPoint} from \\\"../../aa-4337/interfaces/IEntryPoint.sol\\\";\\n\\n/**\\n * @title Account Facet Interface\\n * @dev Interface of module contract that provides the account features and init/unitialization of signer\\n * compatible with EIP-1271 & EIP-4337\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IAccountFacet {\\n event AccountInitialized(\\n IEntryPoint indexed entryPoint,\\n bytes indexed ownerPublicKey\\n );\\n // NOTE: Added Below Event\\n event VerificationSuccess(bytes32);\\n event VerificationFailure(bytes32);\\n\\n error AccountFacet__InitializationFailure();\\n error AccountFacet__RestrictionsFailure();\\n error AccountFacet__NonExistentVerificationFacet();\\n error AccountFacet__CallNotSuccessful();\\n error AccountFacet__InvalidArrayLength();\\n\\n function initialize(\\n address verificationFacet,\\n address anEntryPoint,\\n address facetRegistry,\\n address _defaultFallBack,\\n bytes calldata _ownerPublicKey\\n ) external returns (uint256);\\n\\n function execute(address dest, uint256 value, bytes calldata func) external;\\n\\n function executeBatch(\\n address[] calldata dest,\\n uint256[] calldata value,\\n bytes[] calldata func\\n ) external;\\n}\\n\",\"keccak256\":\"0x74a9cb0b8f2f4a5148e366a401a0354426c536c012c025025d07cc25a4cd5382\",\"license\":\"Apache-2.0\"},\"contracts/infrastructure/DefaultFallbackHandler.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IERC721Receiver} from \\\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\\\";\\nimport {IERC1155Receiver} from \\\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\\\";\\nimport {IERC777Recipient} from \\\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\\\";\\nimport {BaseAccount} from \\\"../aa-4337/core/BaseAccount.sol\\\";\\nimport {DefaultLibDiamond} from \\\"../libraries/DefaultLibDiamond.sol\\\";\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IAccountFacet} from \\\"../facets/interfaces/IAccountFacet.sol\\\";\\nimport {IStorageLoupe} from \\\"../facets/base/interfaces/IStorageLoupe.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\nimport {IERC677Receiver} from \\\"../interfaces/ERC/IERC677Receiver.sol\\\";\\nimport {IERC165} from \\\"../interfaces/ERC/IERC165.sol\\\";\\n\\n/**\\n * @title DefaultFallbackHandler\\n * @dev A default fallback handler for Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract DefaultFallbackHandler is IDiamondLoupe {\\n /**\\n * @notice Sets the middleware diamond for Barz wallet as a fallback handler\\n * @dev This contract is also a diamond that holds the default facets to reduce gas cost for wallet activation.\\n * Within the constructor this conducts diamond cut to initially setup the diamond. This is a non-upgradeable contract\\n * @param _diamondCutFacet Address if diamond cut facet\\n * @param _accountFacet Address account facet\\n * @param _tokenReceiverFacet Address of token receiver facet\\n * @param _diamondLoupeFacet Address of diamond loupe facet\\n */\\n constructor(\\n address _diamondCutFacet,\\n address _accountFacet,\\n address _tokenReceiverFacet,\\n address _diamondLoupeFacet\\n ) payable {\\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](4);\\n bytes4[] memory functionSelectors = new bytes4[](1);\\n functionSelectors[0] = IDiamondCut.diamondCut.selector;\\n\\n bytes4[] memory accountFunctionSelectors = new bytes4[](5);\\n accountFunctionSelectors[0] = IAccountFacet.execute.selector;\\n accountFunctionSelectors[1] = IAccountFacet.executeBatch.selector;\\n accountFunctionSelectors[2] = BaseAccount.validateUserOp.selector;\\n accountFunctionSelectors[3] = BaseAccount.getNonce.selector;\\n accountFunctionSelectors[4] = BaseAccount.entryPoint.selector;\\n\\n bytes4[] memory receiverFacetSelectors = new bytes4[](5);\\n receiverFacetSelectors[0] = IERC721Receiver.onERC721Received.selector;\\n receiverFacetSelectors[1] = IERC1155Receiver.onERC1155Received.selector;\\n receiverFacetSelectors[2] = IERC1155Receiver\\n .onERC1155BatchReceived\\n .selector;\\n receiverFacetSelectors[3] = IERC777Recipient.tokensReceived.selector;\\n receiverFacetSelectors[4] = IERC677Receiver.onTokenTransfer.selector;\\n\\n bytes4[] memory loupeFacetSelectors = new bytes4[](9);\\n loupeFacetSelectors[0] = IDiamondLoupe.facets.selector;\\n loupeFacetSelectors[1] = IDiamondLoupe.facetFunctionSelectors.selector;\\n loupeFacetSelectors[2] = IDiamondLoupe.facetAddresses.selector;\\n loupeFacetSelectors[3] = IDiamondLoupe.facetAddress.selector;\\n loupeFacetSelectors[4] = IERC165.supportsInterface.selector;\\n loupeFacetSelectors[5] = IStorageLoupe.facetsFromStorage.selector;\\n loupeFacetSelectors[6] = IStorageLoupe\\n .facetFunctionSelectorsFromStorage\\n .selector;\\n loupeFacetSelectors[7] = IStorageLoupe\\n .facetAddressesFromStorage\\n .selector;\\n loupeFacetSelectors[8] = IStorageLoupe.facetAddressFromStorage.selector;\\n\\n {\\n cut[0] = IDiamondCut.FacetCut({\\n facetAddress: _diamondCutFacet,\\n action: IDiamondCut.FacetCutAction.Add,\\n functionSelectors: functionSelectors\\n });\\n cut[1] = IDiamondCut.FacetCut({\\n facetAddress: _accountFacet,\\n action: IDiamondCut.FacetCutAction.Add,\\n functionSelectors: accountFunctionSelectors\\n });\\n cut[2] = IDiamondCut.FacetCut({\\n facetAddress: _tokenReceiverFacet,\\n action: IDiamondCut.FacetCutAction.Add,\\n functionSelectors: receiverFacetSelectors\\n });\\n cut[3] = IDiamondCut.FacetCut({\\n facetAddress: _diamondLoupeFacet,\\n action: IDiamondCut.FacetCutAction.Add,\\n functionSelectors: loupeFacetSelectors\\n });\\n\\n DefaultLibDiamond.diamondCut(cut, address(0), \\\"\\\");\\n }\\n }\\n\\n /**\\n * @notice Returns the facet information of call facets registered to this diamond.\\n * @return facets_ The facet struct array including all facet information\\n */\\n function facets() external view override returns (Facet[] memory facets_) {\\n DefaultLibDiamond.DiamondStorage storage ds = DefaultLibDiamond\\n .diamondStorage();\\n uint256 numFacets = ds.facetAddresses.length;\\n facets_ = new Facet[](numFacets);\\n for (uint256 i; i < numFacets; ) {\\n address facetAddress_ = ds.facetAddresses[i];\\n facets_[i].facetAddress = facetAddress_;\\n facets_[i].functionSelectors = ds\\n .facetFunctionSelectors[facetAddress_]\\n .functionSelectors;\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * @notice Gets all the function selectors provided by a facet.\\n * @param _facet The facet address.\\n * @return facetFunctionSelectors_\\n */\\n function facetFunctionSelectors(\\n address _facet\\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\\n facetFunctionSelectors_ = DefaultLibDiamond\\n .diamondStorage()\\n .facetFunctionSelectors[_facet]\\n .functionSelectors;\\n }\\n\\n /**\\n * @notice Get all the facet addresses used by a diamond.\\n * @return facetAddresses_\\n */\\n function facetAddresses()\\n external\\n view\\n override\\n returns (address[] memory facetAddresses_)\\n {\\n facetAddresses_ = DefaultLibDiamond.diamondStorage().facetAddresses;\\n }\\n\\n /** @notice Gets the facet that supports the given selector.\\n * @dev If facet is not found return address(0).\\n * @param _functionSelector The function selector.\\n * @return facetAddress_ The facet address.\\n */\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view override returns (address facetAddress_) {\\n facetAddress_ = DefaultLibDiamond\\n .diamondStorage()\\n .selectorToFacetAndPosition[_functionSelector]\\n .facetAddress;\\n }\\n}\\n\",\"keccak256\":\"0xa482fe778481e34e9fb3c4074231f8048437e934c0ca9a0c78e8e61d3a24470a\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.21;\\n\\ninterface IERC165 {\\n /// @notice Query if a contract implements an interface\\n /// @param interfaceId The interface identifier, as specified in ERC-165\\n /// @dev Interface identification is specified in ERC-165. This function\\n /// uses less than 30,000 gas.\\n /// @return `true` if the contract implements `interfaceID` and\\n /// `interfaceID` is not 0xffffffff, `false` otherwise\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xbb7f07e170898793c5535cc4b7e8944c4b990a631ac806d0b788e794abc788a3\",\"license\":\"MIT\"},\"contracts/interfaces/ERC/IERC677Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC677Receiver {\\n function onTokenTransfer(\\n address sender,\\n uint value,\\n bytes calldata data\\n ) external pure returns (bool);\\n}\\n\",\"keccak256\":\"0x4c1631cf45ea6daac0ec158c3edb9453099130b6b64f697004b83f95aa1f7350\",\"license\":\"Apache-2.0\"},\"contracts/libraries/DefaultLibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary DefaultLibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (\\n uint256 facetIndex;\\n facetIndex < _diamondCut.length;\\n facetIndex++\\n ) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(\\n address _facetAddress,\\n bytes4[] memory _functionSelectors\\n ) internal {\\n uint256 funcSelectorsLength = _functionSelectors.length;\\n require(\\n funcSelectorsLength > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _facetAddress != address(0),\\n \\\"LibDiamondCut: Add facet can't be address(0)\\\"\\n );\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (\\n uint256 selectorIndex;\\n selectorIndex < funcSelectorsLength;\\n selectorIndex++\\n ) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds\\n .selectorToFacetAndPosition[selector]\\n .facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(\\n address _facetAddress,\\n bytes4[] memory _functionSelectors\\n ) internal {\\n uint256 funcSelectorsLength = _functionSelectors.length;\\n require(\\n funcSelectorsLength > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _facetAddress != address(0),\\n \\\"LibDiamondCut: Replace facet can't be address(0)\\\"\\n );\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (\\n uint256 selectorIndex;\\n selectorIndex < funcSelectorsLength;\\n selectorIndex++\\n ) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds\\n .selectorToFacetAndPosition[selector]\\n .facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same facet\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(\\n address _facetAddress,\\n bytes4[] memory _functionSelectors\\n ) internal {\\n uint256 funcSelectorsLength = _functionSelectors.length;\\n require(\\n funcSelectorsLength > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(\\n _facetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n for (\\n uint256 selectorIndex;\\n selectorIndex < funcSelectorsLength;\\n selectorIndex++\\n ) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds\\n .selectorToFacetAndPosition[selector]\\n .facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(\\n DiamondStorage storage ds,\\n address _facetAddress\\n ) internal {\\n enforceHasContractCode(\\n _facetAddress,\\n \\\"LibDiamondCut: New facet has no code\\\"\\n );\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds\\n .facetAddresses\\n .length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds\\n .selectorToFacetAndPosition[_selector]\\n .functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(\\n _selector\\n );\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(\\n _facetAddress != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // an immutable function is a function defined directly in a diamond\\n require(\\n _facetAddress != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds\\n .selectorToFacetAndPosition[_selector]\\n .functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors[lastSelectorPosition];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n selectorPosition\\n ] = lastSelector;\\n ds\\n .selectorToFacetAndPosition[lastSelector]\\n .functionSelectorPosition = uint96(selectorPosition);\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[\\n lastFacetAddressPosition\\n ];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds\\n .facetFunctionSelectors[lastFacetAddress]\\n .facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds\\n .facetFunctionSelectors[_facetAddress]\\n .facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x1b08f332d62919288bb1f0d154ca4b85f4e167d2a06e680f8ec93dba65be3be1\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x6080604052604051620020183803806200201883398101604081905262000026916200156b565b60408051600480825260a08201909252600091816020015b604080516060808201835260008083526020830152918101919091528152602001906001900390816200003e5750506040805160018082528183019092529192506000919060208083019080368337019050509050631f931c1c60e01b81600081518110620000b157620000b1620015c8565b6001600160e01b03199290921660209283029190910182015260408051600580825260c08201909252600092909190820160a08036833701905050905063b61d27f660e01b816000815181106200010c576200010c620015c8565b6001600160e01b03199092166020928302919091019091015280516323f0ed1560e11b9082906001908110620001465762000146620015c8565b6001600160e01b0319909216602092830291909101909101528051633a871cdd60e01b9082906002908110620001805762000180620015c8565b6001600160e01b0319909216602092830291909101909101528051631a10fa5160e31b9082906003908110620001ba57620001ba620015c8565b6001600160e01b031990921660209283029190910190910152805163586b48ff60e11b9082906004908110620001f457620001f4620015c8565b6001600160e01b03199290921660209283029190910182015260408051600580825260c08201909252600092909190820160a08036833701905050905063150b7a0260e01b816000815181106200024f576200024f620015c8565b6001600160e01b031990921660209283029190910190910152805163f23a6e6160e01b9082906001908110620002895762000289620015c8565b6001600160e01b031990921660209283029190910190910152805163bc197c8160e01b9082906002908110620002c357620002c3620015c8565b6001600160e01b03199092166020928302919091019091015280516223de2960e01b9082906003908110620002fc57620002fc620015c8565b6001600160e01b0319909216602092830291909101909101528051635260769b60e11b9082906004908110620003365762000336620015c8565b6001600160e01b0319929092166020928302919091018201526040805160098082526101408201909252600092909190820161012080368337019050509050637a0ed62760e01b81600081518110620003935762000393620015c8565b6001600160e01b03199092166020928302919091019091015280516356fe50af60e11b9082906001908110620003cd57620003cd620015c8565b6001600160e01b03199092166020928302919091019091015280516314bbdacb60e21b9082906002908110620004075762000407620015c8565b6001600160e01b03199092166020928302919091019091015280516366ffd66360e11b9082906003908110620004415762000441620015c8565b6001600160e01b03199092166020928302919091019091015280516301ffc9a760e01b90829060049081106200047b576200047b620015c8565b6001600160e01b031990921660209283029190910190910152805163f9796ccf60e01b9082906005908110620004b557620004b5620015c8565b6001600160e01b031990921660209283029190910190910152805162d2a81160e11b9082906006908110620004ee57620004ee620015c8565b6001600160e01b031990921660209283029190910190910152805163d42139a960e01b9082906007908110620005285762000528620015c8565b6001600160e01b03199092166020928302919091019091015280516371d17b7f60e11b9082906008908110620005625762000562620015c8565b6001600160e01b031990921660209283029190910182015260408051606081019091526001600160a01b038b168152908101600081526020018581525085600081518110620005b557620005b5620015c8565b60200260200101819052506040518060600160405280896001600160a01b0316815260200160006002811115620005f057620005f0620015de565b815260200184815250856001815181106200060f576200060f620015c8565b60200260200101819052506040518060600160405280886001600160a01b03168152602001600060028111156200064a576200064a620015de565b81526020018381525085600281518110620006695762000669620015c8565b60200260200101819052506040518060600160405280876001600160a01b0316815260200160006002811115620006a457620006a4620015de565b81526020018281525085600381518110620006c357620006c3620015c8565b6020026020010181905250620006f1856000604051806020016040528060008152506200070060201b60201c565b5050505050505050506200184c565b60005b83518110156200090c576000848281518110620007245762000724620015c8565b602002602001015160200151905060006002811115620007485762000748620015de565b8160028111156200075d576200075d620015de565b03620007bb57620007b58583815181106200077c576200077c620015c8565b6020026020010151600001518684815181106200079d576200079d620015c8565b6020026020010151604001516200095b60201b60201c565b620008f6565b6001816002811115620007d257620007d2620015de565b036200082a57620007b5858381518110620007f157620007f1620015c8565b602002602001015160000151868481518110620008125762000812620015c8565b60200260200101516040015162000bf760201b60201c565b6002816002811115620008415762000841620015de565b036200089957620007b5858381518110620008605762000860620015c8565b602002602001015160000151868481518110620008815762000881620015c8565b60200260200101516040015162000ea160201b60201c565b60405162461bcd60e51b815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f727265637420466163657443756044820152663a20b1ba34b7b760c91b60648201526084015b60405180910390fd5b508062000903816200160a565b91505062000703565b507f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb67383838360405162000942939291906200167a565b60405180910390a162000956828262001005565b505050565b805180620009af5760405162461bcd60e51b815260206004820152602b602482015260008051602062001ff883398151915260448201526a1858d95d081d1bc818dd5d60aa1b6064820152608401620008ed565b60008051602062001f8c8339815191526001600160a01b03841662000a2c5760405162461bcd60e51b815260206004820152602c60248201527f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260448201526b65206164647265737328302960a01b6064820152608401620008ed565b6001600160a01b0384166000908152600182016020526040812054906001600160601b038216900362000a655762000a658286620010dd565b60005b8381101562000bef57600085828151811062000a885762000a88620015c8565b6020908102919091018101516001600160e01b031981166000908152918690526040909120549091506001600160a01b0316801562000b305760405162461bcd60e51b815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c72656164792065786973747300000000000000000000006064820152608401620008ed565b6001600160e01b0319821660008181526020878152604080832080546001600160a01b03908116600160a01b6001600160601b038c16021782558d168085526001808c0185529285208054938401815585528385206008840401805463ffffffff60079095166004026101000a948502191660e08a901c94909402939093179092559390925287905281546001600160a01b0319161790558362000bd48162001781565b9450505050808062000be6906200160a565b91505062000a68565b505050505050565b80518062000c4b5760405162461bcd60e51b815260206004820152602b602482015260008051602062001ff883398151915260448201526a1858d95d081d1bc818dd5d60aa1b6064820152608401620008ed565b60008051602062001f8c8339815191526001600160a01b03841662000ccc5760405162461bcd60e51b815260206004820152603060248201527f4c69624469616d6f6e644375743a205265706c6163652066616365742063616e60448201526f2774206265206164647265737328302960801b6064820152608401620008ed565b6001600160a01b0384166000908152600182016020526040812054906001600160601b038216900362000d055762000d058286620010dd565b60005b8381101562000bef57600085828151811062000d285762000d28620015c8565b6020908102919091018101516001600160e01b031981166000908152918690526040909120549091506001600160a01b03908116908816810362000dd55760405162461bcd60e51b815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d6520666163657400000000000000000000006064820152608401620008ed565b62000de28582846200114a565b6001600160e01b0319821660008181526020878152604080832080546001600160a01b03908116600160a01b6001600160601b038c16021782558d168085526001808c0185529285208054938401815585528385206008840401805463ffffffff60079095166004026101000a948502191660e08a901c94909402939093179092559390925287905281546001600160a01b0319161790558362000e868162001781565b9450505050808062000e98906200160a565b91505062000d08565b80518062000ef55760405162461bcd60e51b815260206004820152602b602482015260008051602062001ff883398151915260448201526a1858d95d081d1bc818dd5d60aa1b6064820152608401620008ed565b60008051602062001f8c8339815191526001600160a01b0384161562000f845760405162461bcd60e51b815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d7573742062652061646472657373283029000000000000000000006064820152608401620008ed565b60005b8281101562000ffe57600084828151811062000fa75762000fa7620015c8565b6020908102919091018101516001600160e01b031981166000908152918590526040909120549091506001600160a01b031662000fe68482846200114a565b5050808062000ff5906200160a565b91505062000f87565b5050505050565b6001600160a01b03821662001018575050565b6200103d8260405180606001604052806028815260200162001fac602891396200152a565b600080836001600160a01b0316836040516200105a9190620017b2565b600060405180830381855af49150503d806000811462001097576040519150601f19603f3d011682016040523d82523d6000602084013e6200109c565b606091505b509150915081620010d757805115620010b85780518082602001fd5b838360405163192105d760e01b8152600401620008ed929190620017d0565b50505050565b620011028160405180606001604052806024815260200162001fd4602491396200152a565b6002820180546001600160a01b0390921660008181526001948501602090815260408220860185905594840183559182529290200180546001600160a01b0319169091179055565b6001600160a01b038216620011c85760405162461bcd60e51b815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608401620008ed565b306001600160a01b03831603620012395760405162461bcd60e51b815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201526d3a30b1363290333ab731ba34b7b760911b6064820152608401620008ed565b6001600160e01b03198116600090815260208481526040808320546001600160a01b0386168452600180880190935290832054600160a01b9091046001600160601b031692916200128a91620017fe565b905080821462001383576001600160a01b03841660009081526001860160205260408120805483908110620012c357620012c3620015c8565b600091825260208083206008830401546001600160a01b038916845260018a019091526040909220805460079092166004026101000a90920460e01b925082919085908110620013175762001317620015c8565b600091825260208083206008830401805463ffffffff60079094166004026101000a938402191660e09590951c929092029390931790556001600160e01b03199290921682528690526040902080546001600160a01b0316600160a01b6001600160601b038516021790555b6001600160a01b03841660009081526001860160205260409020805480620013af57620013af6200181a565b60008281526020808220600860001990940193840401805463ffffffff600460078716026101000a0219169055919092556001600160e01b0319851682528690526040812081905581900362000ffe5760028501546000906200141590600190620017fe565b6001600160a01b0386166000908152600180890160205260409091200154909150808214620014cb576000876002018381548110620014585762001458620015c8565b6000918252602090912001546002890180546001600160a01b0390921692508291849081106200148c576200148c620015c8565b600091825260208083209190910180546001600160a01b0319166001600160a01b03948516179055929091168152600189810190925260409020018190555b86600201805480620014e157620014e16200181a565b60008281526020808220830160001990810180546001600160a01b03191690559092019092556001600160a01b0388168252600189810190915260408220015550505050505050565b813b8181620010d75760405162461bcd60e51b8152600401620008ed919062001830565b80516001600160a01b03811681146200156657600080fd5b919050565b600080600080608085870312156200158257600080fd5b6200158d856200154e565b93506200159d602086016200154e565b9250620015ad604086016200154e565b9150620015bd606086016200154e565b905092959194509250565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016200161f576200161f620015f4565b5060010190565b60005b838110156200164357818101518382015260200162001629565b50506000910152565b600081518084526200166681602086016020860162001626565b601f01601f19169290920160200192915050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b848110156200174f57898403607f19018652815180516001600160a01b03168552838101518986019060038110620016eb57634e487b7160e01b600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b80831015620017395783516001600160e01b03191682529286019260019290920191908601906200170d565b50978501979550505090820190600101620016a3565b50506001600160a01b038a169088015286810360408801526200177381896200164c565b9a9950505050505050505050565b60006001600160601b038281166002600160601b03198101620017a857620017a8620015f4565b6001019392505050565b60008251620017c681846020870162001626565b9190910192915050565b6001600160a01b0383168152604060208201819052600090620017f6908301846200164c565b949350505050565b81810381811115620018145762001814620015f4565b92915050565b634e487b7160e01b600052603160045260246000fd5b6020815260006200184560208301846200164c565b9392505050565b610730806200185c6000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806352ef6b2c146100515780637a0ed6271461006f578063adfca15e14610084578063cdffacc6146100a4575b600080fd5b610059610140565b60405161006691906104ab565b60405180910390f35b6100776101d1565b6040516100669190610562565b61009761009236600461060a565b6103d1565b6040516100669190610647565b61011b6100b236600461065a565b7fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610066565b60607f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6002018054806020026020016040519081016040528092919081815260200182805480156101c757602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161019c575b5050505050905090565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f908067ffffffffffffffff8111156102315761023161069c565b60405190808252806020026020018201604052801561027757816020015b60408051808201909152600081526060602082015281526020019060019003908161024f5790505b50925060005b818110156103cb57600083600201828154811061029c5761029c6106cb565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050808583815181106102dc576102dc6106cb565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff928316905290821660009081526001860182526040908190208054825181850281018501909352808352919290919083018282801561039d57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161034a5790505b50505050508583815181106103b4576103b46106cb565b60209081029190910181015101525060010161027d565b50505090565b73ffffffffffffffffffffffffffffffffffffffff811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4920602090815260409182902080548351818402810184019094528084526060939283018282801561049f57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161044c5790505b50505050509050919050565b6020808252825182820181905260009190848201906040850190845b818110156104f957835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016104c7565b50909695505050505050565b600081518084526020808501945080840160005b838110156105575781517fffffffff000000000000000000000000000000000000000000000000000000001687529582019590820190600101610519565b509495945050505050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b838110156105fc578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00185528151805173ffffffffffffffffffffffffffffffffffffffff1684528701518784018790526105e987850182610505565b9588019593505090860190600101610589565b509098975050505050505050565b60006020828403121561061c57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461064057600080fd5b9392505050565b6020815260006106406020830184610505565b60006020828403121561066c57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461064057600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea264697066735822122024a872696a5ad50024326567061c50adea63ff0d49edf0ac60339459d33d571664736f6c63430008150033183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f4c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a204e657720666163657420686173206e6f20636f64654c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e2066", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806352ef6b2c146100515780637a0ed6271461006f578063adfca15e14610084578063cdffacc6146100a4575b600080fd5b610059610140565b60405161006691906104ab565b60405180910390f35b6100776101d1565b6040516100669190610562565b61009761009236600461060a565b6103d1565b6040516100669190610647565b61011b6100b236600461065a565b7fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610066565b60607f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f6002018054806020026020016040519081016040528092919081815260200182805480156101c757602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161019c575b5050505050905090565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f908067ffffffffffffffff8111156102315761023161069c565b60405190808252806020026020018201604052801561027757816020015b60408051808201909152600081526060602082015281526020019060019003908161024f5790505b50925060005b818110156103cb57600083600201828154811061029c5761029c6106cb565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050808583815181106102dc576102dc6106cb565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff928316905290821660009081526001860182526040908190208054825181850281018501909352808352919290919083018282801561039d57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161034a5790505b50505050508583815181106103b4576103b46106cb565b60209081029190910181015101525060010161027d565b50505090565b73ffffffffffffffffffffffffffffffffffffffff811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4920602090815260409182902080548351818402810184019094528084526060939283018282801561049f57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161044c5790505b50505050509050919050565b6020808252825182820181905260009190848201906040850190845b818110156104f957835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016104c7565b50909695505050505050565b600081518084526020808501945080840160005b838110156105575781517fffffffff000000000000000000000000000000000000000000000000000000001687529582019590820190600101610519565b509495945050505050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b838110156105fc578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00185528151805173ffffffffffffffffffffffffffffffffffffffff1684528701518784018790526105e987850182610505565b9588019593505090860190600101610589565b509098975050505050505050565b60006020828403121561061c57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461064057600080fd5b9392505050565b6020815260006106406020830184610505565b60006020828403121561066c57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461064057600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea264697066735822122024a872696a5ad50024326567061c50adea63ff0d49edf0ac60339459d33d571664736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "A default fallback handler for Barz", + "kind": "dev", + "methods": { + "constructor": { + "details": "This contract is also a diamond that holds the default facets to reduce gas cost for wallet activation. Within the constructor this conducts diamond cut to initially setup the diamond. This is a non-upgradeable contract", + "params": { + "_accountFacet": "Address account facet", + "_diamondCutFacet": "Address if diamond cut facet", + "_diamondLoupeFacet": "Address of diamond loupe facet", + "_tokenReceiverFacet": "Address of token receiver facet" + } + }, + "facetAddress(bytes4)": { + "details": "If facet is not found return address(0).", + "params": { + "_functionSelector": "The function selector." + }, + "returns": { + "facetAddress_": "The facet address." + } + }, + "facetAddresses()": { + "returns": { + "facetAddresses_": "facetAddresses_" + } + }, + "facetFunctionSelectors(address)": { + "params": { + "_facet": "The facet address." + }, + "returns": { + "facetFunctionSelectors_": "facetFunctionSelectors_" + } + }, + "facets()": { + "returns": { + "facets_": "The facet struct array including all facet information" + } + } + }, + "title": "DefaultFallbackHandler", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "constructor": { + "notice": "Sets the middleware diamond for Barz wallet as a fallback handler" + }, + "facetAddress(bytes4)": { + "notice": "Gets the facet that supports the given selector." + }, + "facetAddresses()": { + "notice": "Get all the facet addresses used by a diamond." + }, + "facetFunctionSelectors(address)": { + "notice": "Gets all the function selectors provided by a facet." + }, + "facets()": { + "notice": "Returns the facet information of call facets registered to this diamond." + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/polygon/DiamondCutFacet.json b/deployments/polygon/DiamondCutFacet.json new file mode 100644 index 0000000..d7db17c --- /dev/null +++ b/deployments/polygon/DiamondCutFacet.json @@ -0,0 +1,872 @@ +{ + "address": "0x0B9504140771C3688Ff041917192277D2f52E1e0", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_securityManager", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "CallerNotGuardian", + "type": "error" + }, + { + "inputs": [], + "name": "CallerNotGuardianOrOwner", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__CannotRevokeUnapproved", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__DuplicateApproval", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InsufficientApprovers", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidApprovalValidationPeriod", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidApprover", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidApproverSignature", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidArrayLength", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidInitAddress", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidRouteWithGuardian", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__InvalidRouteWithoutGuardian", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__LackOfOwnerApproval", + "type": "error" + }, + { + "inputs": [], + "name": "DiamondCutFacet__OwnerAlreadyApproved", + "type": "error" + }, + { + "inputs": [], + "name": "DuplicateApprover", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_initializationContractAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "InitializationFunctionReverted", + "type": "error" + }, + { + "inputs": [], + "name": "UnregisteredFacetAndSelectors", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroApproverLength", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "indexed": false, + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "DiamondCut", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "diamondCut", + "type": "tuple[]" + } + ], + "name": "DiamondCutApprovalRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "diamondCut", + "type": "tuple[]" + } + ], + "name": "DiamondCutApproved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + }, + { + "indexed": false, + "internalType": "bool", + "name": "_lag", + "type": "bool" + } + ], + "name": "SupportsInterfaceUpdated", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_diamondCutHash", + "type": "bytes32" + }, + { + "internalType": "address[]", + "name": "_approvers", + "type": "address[]" + } + ], + "name": "_checkDuplicateOnChainApprover", + "outputs": [], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + } + ], + "name": "approveDiamondCut", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "diamondCut", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "internalType": "address[]", + "name": "_approvers", + "type": "address[]" + }, + { + "internalType": "bytes[]", + "name": "_signatures", + "type": "bytes[]" + } + ], + "name": "diamondCutWithGuardian", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_diamondCutHash", + "type": "bytes32" + } + ], + "name": "getDiamondCutApprovalCountWithTimeValidity", + "outputs": [ + { + "internalType": "uint256", + "name": "approvalCount", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + } + ], + "name": "getDiamondCutHash", + "outputs": [ + { + "internalType": "bytes32", + "name": "cutHash", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getDiamondCutNonce", + "outputs": [ + { + "internalType": "uint128", + "name": "cutNonce", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_diamondCutHash", + "type": "bytes32" + } + ], + "name": "getOwnerCutApprovalWithTimeValidity", + "outputs": [ + { + "internalType": "bool", + "name": "isApprovedByOwner", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_diamondCutHash", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "_approver", + "type": "address" + } + ], + "name": "isCutApproved", + "outputs": [ + { + "internalType": "bool", + "name": "isApproved", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + } + ], + "name": "revokeDiamondCutApproval", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "securityManager", + "outputs": [ + { + "internalType": "contract ISecurityManager", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_interfaceId", + "type": "bytes4" + }, + { + "internalType": "bool", + "name": "_flag", + "type": "bool" + } + ], + "name": "updateSupportsInterface", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0xfe5a33c2eea185f72cf1f0fc42288e2087b4413d5b4be4ea9959d03be33202b8", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 16, + "gasUsed": "3078987", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000008000000000000000000000000000000000000002000000000000000000800000000000000000000110000000000000000000000000001000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000004200000000000000000001000000000000000000000000000000100000000000000000000000080000000000000000000000000000000000000000000000100000", + "blockHash": "0x582c556e1dc62153df31af89fbcd5c2c8b656258323e257e2f35c3b4d3a2f412", + "transactionHash": "0xfe5a33c2eea185f72cf1f0fc42288e2087b4413d5b4be4ea9959d03be33202b8", + "logs": [ + { + "transactionIndex": 16, + "blockNumber": 50172397, + "transactionHash": "0xfe5a33c2eea185f72cf1f0fc42288e2087b4413d5b4be4ea9959d03be33202b8", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x000000000000000000000000d87df9fd27b9a30fe27e7b294caaa4673f34b6b1", + "0x00000000000000000000000002f70172f7f490653665c9bfac0666147c8af1f5" + ], + "data": "0x00000000000000000000000000000000000000000000000002a26749273a122e000000000000000000000000000000000000000000000000bfdace502f5eff2200000000000000000000000000000000000000000000005cc92007c92d10f0c5000000000000000000000000000000000000000000000000bd3867070824ecf400000000000000000000000000000000000000000000005ccbc26f12544b02f3", + "logIndex": 46, + "blockHash": "0x582c556e1dc62153df31af89fbcd5c2c8b656258323e257e2f35c3b4d3a2f412" + } + ], + "blockNumber": 50172397, + "cumulativeGasUsed": "5297507", + "status": 1, + "byzantium": true + }, + "args": [ + "0xcBe266adbfd7CB32988128e7f37b7c8b3C5521A8" + ], + "numDeployments": 3, + "solcInputHash": "4356503edd8ae34e73cb6dd1c8e2fc8a", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_securityManager\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"CallerNotGuardian\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallerNotGuardianOrOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__CannotRevokeUnapproved\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__DuplicateApproval\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InsufficientApprovers\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidApprovalValidationPeriod\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidApprover\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidApproverSignature\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidArrayLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidInitAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidRouteWithGuardian\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__InvalidRouteWithoutGuardian\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__LackOfOwnerApproval\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DiamondCutFacet__OwnerAlreadyApproved\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateApprover\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_initializationContractAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"InitializationFunctionReverted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnregisteredFacetAndSelectors\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroApproverLength\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"DiamondCut\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"diamondCut\",\"type\":\"tuple[]\"}],\"name\":\"DiamondCutApprovalRevoked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"diamondCut\",\"type\":\"tuple[]\"}],\"name\":\"DiamondCutApproved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"_lag\",\"type\":\"bool\"}],\"name\":\"SupportsInterfaceUpdated\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_diamondCutHash\",\"type\":\"bytes32\"},{\"internalType\":\"address[]\",\"name\":\"_approvers\",\"type\":\"address[]\"}],\"name\":\"_checkDuplicateOnChainApprover\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"}],\"name\":\"approveDiamondCut\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"diamondCut\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"internalType\":\"address[]\",\"name\":\"_approvers\",\"type\":\"address[]\"},{\"internalType\":\"bytes[]\",\"name\":\"_signatures\",\"type\":\"bytes[]\"}],\"name\":\"diamondCutWithGuardian\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_diamondCutHash\",\"type\":\"bytes32\"}],\"name\":\"getDiamondCutApprovalCountWithTimeValidity\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"approvalCount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"}],\"name\":\"getDiamondCutHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"cutHash\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDiamondCutNonce\",\"outputs\":[{\"internalType\":\"uint128\",\"name\":\"cutNonce\",\"type\":\"uint128\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_diamondCutHash\",\"type\":\"bytes32\"}],\"name\":\"getOwnerCutApprovalWithTimeValidity\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isApprovedByOwner\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_diamondCutHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"_approver\",\"type\":\"address\"}],\"name\":\"isCutApproved\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isApproved\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"}],\"name\":\"revokeDiamondCutApproval\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"securityManager\",\"outputs\":[{\"internalType\":\"contract ISecurityManager\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_interfaceId\",\"type\":\"bytes4\"},{\"internalType\":\"bool\",\"name\":\"_flag\",\"type\":\"bool\"}],\"name\":\"updateSupportsInterface\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"Responsible for adding/removing/replace facets in Barz\",\"kind\":\"dev\",\"methods\":{\"_checkDuplicateOnChainApprover(bytes32,address[])\":{\"params\":{\"_approvers\":\"List of approver addresses\",\"_diamondCutHash\":\"Hash of diamondCut information including the facet addresses and function selectors\"}},\"approveDiamondCut((address,uint8,bytes4[])[])\":{\"params\":{\"_diamondCut\":\"Contains the facet addresses and function selectors\"}},\"constructor\":{\"params\":{\"_securityManager\":\"Security Manager contract that holds the security related variables for all wallets\"}},\"diamondCut((address,uint8,bytes4[])[],address,bytes)\":{\"params\":{\"_diamondCut\":\"Contains the facet addresses and function selectors\",\"_init\":\"The address of the contract or facet to execute _calldata. It's prohibited in Barz\"}},\"diamondCutWithGuardian((address,uint8,bytes4[])[],address[],bytes[])\":{\"params\":{\"_approvers\":\"Guardian or owner address that approves the diamond cut\",\"_diamondCut\":\"Contains the facet addresses and function selectors\",\"_signatures\":\"Signature of Guardians or owner that approves the diamond cut\"}},\"getDiamondCutApprovalCountWithTimeValidity(bytes32)\":{\"params\":{\"_diamondCutHash\":\"Hash of diamondCut information including the facet addresses and function selectors\"}},\"getDiamondCutHash((address,uint8,bytes4[])[])\":{\"params\":{\"_diamondCut\":\"Contains the facet addresses and function selectors\"},\"returns\":{\"cutHash\":\"Diamond Cut Hash\"}},\"getDiamondCutNonce()\":{\"details\":\"This method fetches the nonce from diamond cut storage\",\"returns\":{\"cutNonce\":\"Nonce of diamond cut to protect from reply attacks\"}},\"getOwnerCutApprovalWithTimeValidity(bytes32)\":{\"params\":{\"_diamondCutHash\":\"Hash of diamondCut information including the facet addresses and function selectors\"},\"returns\":{\"isApprovedByOwner\":\"Bool value showing if the owner approved the cut\"}},\"isCutApproved(bytes32,address)\":{\"params\":{\"_approver\":\"Address of approver\",\"_diamondCutHash\":\"Hash of diamondCut information including the facet addresses and function selectors\"},\"returns\":{\"isApproved\":\"Bool value showing if the approver approved the cut\"}},\"revokeDiamondCutApproval((address,uint8,bytes4[])[])\":{\"params\":{\"_diamondCut\":\"Contains the facet addresses and function selectors\"}},\"updateSupportsInterface(bytes4,bool)\":{\"params\":{\"_flag\":\"Bool value to update the mapping of the given interface ID\",\"_interfaceId\":\"InterfaceID to update the mapping\"}}},\"title\":\"DiamondCut Facet\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"_checkDuplicateOnChainApprover(bytes32,address[])\":{\"notice\":\"Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval Approvers who approved on-chain should not be included in the off-chain approval\"},\"approveDiamondCut((address,uint8,bytes4[])[])\":{\"notice\":\"Approves diamond cut. This can only be called directly from guardian or owner\"},\"constructor\":{\"notice\":\"This constructor sets the Security Manager address which is an immutable variable. Immutable variables do not impact the storage of diamond\"},\"diamondCut((address,uint8,bytes4[])[],address,bytes)\":{\"notice\":\"Add/replace/remove any number of functions and optionally execute a function with delegatecall when guardians don't exist\"},\"diamondCutWithGuardian((address,uint8,bytes4[])[],address[],bytes[])\":{\"notice\":\"Add/replace/remove any number of functions and optionally execute a function with delegatecall when guardians exist\"},\"getDiamondCutApprovalCountWithTimeValidity(bytes32)\":{\"notice\":\"Gets the number of approvals of diamond cut from guardians\"},\"getDiamondCutHash((address,uint8,bytes4[])[])\":{\"notice\":\"Returns the diamond cut hash. This function ensures that this hash is safe from replay attack by including salt, address, chainId, and nonce, etc.\"},\"getDiamondCutNonce()\":{\"notice\":\"Returns the diamond cut nonce of this wallet\"},\"getOwnerCutApprovalWithTimeValidity(bytes32)\":{\"notice\":\"Returns if the owner has approved the diamond cut\"},\"isCutApproved(bytes32,address)\":{\"notice\":\"Returns if the given approver has approved the diamond cut\"},\"revokeDiamondCutApproval((address,uint8,bytes4[])[])\":{\"notice\":\"Revokes the approval of diamond cut. This can only be called directly from guardian or owner\"},\"updateSupportsInterface(bytes4,bool)\":{\"notice\":\"Updates the flag for the interfaceId\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/base/DiamondCutFacet.sol\":\"DiamondCutFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/interfaces/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC1271 standard signature validation method for\\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC1271 {\\n /**\\n * @dev Should return whether the signature provided is valid for the provided data\\n * @param hash Hash of the data to be signed\\n * @param signature Signature byte array associated with _data\\n */\\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\\n}\\n\",\"keccak256\":\"0x0705a4b1b86d7b0bd8432118f226ba139c44b9dcaba0a6eafba2dd7d0639c544\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./math/Math.sol\\\";\\nimport \\\"./math/SignedMath.sol\\\";\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n uint256 length = Math.log10(value) + 1;\\n string memory buffer = new string(length);\\n uint256 ptr;\\n /// @solidity memory-safe-assembly\\n assembly {\\n ptr := add(buffer, add(32, length))\\n }\\n while (true) {\\n ptr--;\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\\n }\\n value /= 10;\\n if (value == 0) break;\\n }\\n return buffer;\\n }\\n }\\n\\n /**\\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\\n */\\n function toString(int256 value) internal pure returns (string memory) {\\n return string(abi.encodePacked(value < 0 ? \\\"-\\\" : \\\"\\\", toString(SignedMath.abs(value))));\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n return toHexString(value, Math.log256(value) + 1);\\n }\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n\\n /**\\n * @dev Returns true if the two strings are equal.\\n */\\n function equal(string memory a, string memory b) internal pure returns (bool) {\\n return keccak256(bytes(a)) == keccak256(bytes(b));\\n }\\n}\\n\",\"keccak256\":\"0x3088eb2868e8d13d89d16670b5f8612c4ab9ff8956272837d8e90106c59c14a0\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Strings.sol\\\";\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSA {\\n enum RecoverError {\\n NoError,\\n InvalidSignature,\\n InvalidSignatureLength,\\n InvalidSignatureS,\\n InvalidSignatureV // Deprecated in v4.8\\n }\\n\\n function _throwError(RecoverError error) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert(\\\"ECDSA: invalid signature\\\");\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert(\\\"ECDSA: invalid signature length\\\");\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert(\\\"ECDSA: invalid signature 's' value\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature` or error string. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n *\\n * Documentation for signature generation:\\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n return tryRecover(hash, v, r, s);\\n } else {\\n return (address(0), RecoverError.InvalidSignatureLength);\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature`. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, signature);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\\n uint8 v = uint8((uint256(vs) >> 255) + 27);\\n return tryRecover(hash, v, r, s);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n *\\n * _Available since v4.2._\\n */\\n function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\\n // the valid range for s in (301): 0 < s < secp256k1n \\u00f7 2 + 1, and for v in (302): v \\u2208 {27, 28}. Most\\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\\n //\\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\\n // these malleable signatures as well.\\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n return (address(0), RecoverError.InvalidSignatureS);\\n }\\n\\n // If the signature is valid (and not malleable), return the signer address\\n address signer = ecrecover(hash, v, r, s);\\n if (signer == address(0)) {\\n return (address(0), RecoverError.InvalidSignature);\\n }\\n\\n return (signer, RecoverError.NoError);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore(0x00, \\\"\\\\x19Ethereum Signed Message:\\\\n32\\\")\\n mstore(0x1c, hash)\\n message := keccak256(0x00, 0x3c)\\n }\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from `s`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n\\\", Strings.toString(s.length), s));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Typed Data, created from a\\n * `domainSeparator` and a `structHash`. This produces hash corresponding\\n * to the one signed with the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n * JSON-RPC method as part of EIP-712.\\n *\\n * See {recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n let ptr := mload(0x40)\\n mstore(ptr, \\\"\\\\x19\\\\x01\\\")\\n mstore(add(ptr, 0x02), domainSeparator)\\n mstore(add(ptr, 0x22), structHash)\\n data := keccak256(ptr, 0x42)\\n }\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Data with intended validator, created from a\\n * `validator` and `data` according to the version 0 of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x00\\\", validator, data));\\n }\\n}\\n\",\"keccak256\":\"0x809bc3edb4bcbef8263fa616c1b60ee0004b50a8a1bfa164d8f57fd31f520c58\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/SignatureChecker.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./ECDSA.sol\\\";\\nimport \\\"../../interfaces/IERC1271.sol\\\";\\n\\n/**\\n * @dev Signature verification helper that can be used instead of `ECDSA.recover` to seamlessly support both ECDSA\\n * signatures from externally owned accounts (EOAs) as well as ERC1271 signatures from smart contract wallets like\\n * Argent and Gnosis Safe.\\n *\\n * _Available since v4.1._\\n */\\nlibrary SignatureChecker {\\n /**\\n * @dev Checks if a signature is valid for a given signer and data hash. If the signer is a smart contract, the\\n * signature is validated against that smart contract using ERC1271, otherwise it's validated using `ECDSA.recover`.\\n *\\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\\n */\\n function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature) internal view returns (bool) {\\n (address recovered, ECDSA.RecoverError error) = ECDSA.tryRecover(hash, signature);\\n return\\n (error == ECDSA.RecoverError.NoError && recovered == signer) ||\\n isValidERC1271SignatureNow(signer, hash, signature);\\n }\\n\\n /**\\n * @dev Checks if a signature is valid for a given signer and data hash. The signature is validated\\n * against the signer smart contract using ERC1271.\\n *\\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\\n */\\n function isValidERC1271SignatureNow(\\n address signer,\\n bytes32 hash,\\n bytes memory signature\\n ) internal view returns (bool) {\\n (bool success, bytes memory result) = signer.staticcall(\\n abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, signature)\\n );\\n return (success &&\\n result.length >= 32 &&\\n abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector));\\n }\\n}\\n\",\"keccak256\":\"0x3af3ca86df39aac39a0514c84459d691434a108d2151c8ce9d69f32e315cab80\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n enum Rounding {\\n Down, // Toward negative infinity\\n Up, // Toward infinity\\n Zero // Toward zero\\n }\\n\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow.\\n return (a & b) + (a ^ b) / 2;\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a == 0 ? 0 : (a - 1) / b + 1;\\n }\\n\\n /**\\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\\n * with further edits by Uniswap Labs also under MIT license.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\\n unchecked {\\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2^256 + prod0.\\n uint256 prod0; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division.\\n if (prod1 == 0) {\\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\\n // The surrounding unchecked block does not change this fact.\\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\\n return prod0 / denominator;\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n require(denominator > prod1, \\\"Math: mulDiv overflow\\\");\\n\\n ///////////////////////////////////////////////\\n // 512 by 256 division.\\n ///////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0].\\n uint256 remainder;\\n assembly {\\n // Compute remainder using mulmod.\\n remainder := mulmod(x, y, denominator)\\n\\n // Subtract 256 bit number from 512 bit number.\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\\n // See https://cs.stackexchange.com/q/138556/92363.\\n\\n // Does not overflow because the denominator cannot be zero at this stage in the function.\\n uint256 twos = denominator & (~denominator + 1);\\n assembly {\\n // Divide denominator by twos.\\n denominator := div(denominator, twos)\\n\\n // Divide [prod1 prod0] by twos.\\n prod0 := div(prod0, twos)\\n\\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\\n twos := add(div(sub(0, twos), twos), 1)\\n }\\n\\n // Shift in bits from prod1 into prod0.\\n prod0 |= prod1 * twos;\\n\\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\\n // four bits. That is, denominator * inv = 1 mod 2^4.\\n uint256 inverse = (3 * denominator) ^ 2;\\n\\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\\n // in modular arithmetic, doubling the correct bits in each step.\\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\\n\\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inverse;\\n return result;\\n }\\n }\\n\\n /**\\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\\n uint256 result = mulDiv(x, y, denominator);\\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\\n result += 1;\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\\n *\\n * Inspired by Henry S. Warren, Jr.'s \\\"Hacker's Delight\\\" (Chapter 11).\\n */\\n function sqrt(uint256 a) internal pure returns (uint256) {\\n if (a == 0) {\\n return 0;\\n }\\n\\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\\n //\\n // We know that the \\\"msb\\\" (most significant bit) of our target number `a` is a power of 2 such that we have\\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\\n //\\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\\n // \\u2192 `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\\n // \\u2192 `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\\n //\\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\\n uint256 result = 1 << (log2(a) >> 1);\\n\\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\\n // into the expected uint128 result.\\n unchecked {\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n return min(result, a / result);\\n }\\n }\\n\\n /**\\n * @notice Calculates sqrt(a), following the selected rounding direction.\\n */\\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = sqrt(a);\\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 2, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 128;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 64;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 32;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 16;\\n }\\n if (value >> 8 > 0) {\\n value >>= 8;\\n result += 8;\\n }\\n if (value >> 4 > 0) {\\n value >>= 4;\\n result += 4;\\n }\\n if (value >> 2 > 0) {\\n value >>= 2;\\n result += 2;\\n }\\n if (value >> 1 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log2(value);\\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 10, rounded down, of a positive value.\\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 + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 256, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n *\\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\\n */\\n function log256(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 16;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 8;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 4;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 2;\\n }\\n if (value >> 8 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log256(value);\\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe4455ac1eb7fc497bb7402579e7b4d64d928b846fce7d2b6fde06d366f21c2b3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\\n * checks.\\n *\\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\\n * easily result in undesired exploitation or bugs, since developers usually\\n * assume that overflows raise errors. `SafeCast` restores this intuition by\\n * reverting the transaction when such an operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n *\\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\\n * all math on `uint256` and `int256` and then downcasting.\\n */\\nlibrary SafeCast {\\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 * _Available since v4.7._\\n */\\n function toUint248(uint256 value) internal pure returns (uint248) {\\n require(value <= type(uint248).max, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint240(uint256 value) internal pure returns (uint240) {\\n require(value <= type(uint240).max, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint232(uint256 value) internal pure returns (uint232) {\\n require(value <= type(uint232).max, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint224(uint256 value) internal pure returns (uint224) {\\n require(value <= type(uint224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint216(uint256 value) internal pure returns (uint216) {\\n require(value <= type(uint216).max, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint208(uint256 value) internal pure returns (uint208) {\\n require(value <= type(uint208).max, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint200(uint256 value) internal pure returns (uint200) {\\n require(value <= type(uint200).max, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint192(uint256 value) internal pure returns (uint192) {\\n require(value <= type(uint192).max, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint184(uint256 value) internal pure returns (uint184) {\\n require(value <= type(uint184).max, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint176(uint256 value) internal pure returns (uint176) {\\n require(value <= type(uint176).max, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint168(uint256 value) internal pure returns (uint168) {\\n require(value <= type(uint168).max, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint160(uint256 value) internal pure returns (uint160) {\\n require(value <= type(uint160).max, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint152(uint256 value) internal pure returns (uint152) {\\n require(value <= type(uint152).max, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint144(uint256 value) internal pure returns (uint144) {\\n require(value <= type(uint144).max, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint136(uint256 value) internal pure returns (uint136) {\\n require(value <= type(uint136).max, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint128(uint256 value) internal pure returns (uint128) {\\n require(value <= type(uint128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint120(uint256 value) internal pure returns (uint120) {\\n require(value <= type(uint120).max, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint112(uint256 value) internal pure returns (uint112) {\\n require(value <= type(uint112).max, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint104(uint256 value) internal pure returns (uint104) {\\n require(value <= type(uint104).max, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint96(uint256 value) internal pure returns (uint96) {\\n require(value <= type(uint96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint88(uint256 value) internal pure returns (uint88) {\\n require(value <= type(uint88).max, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint80(uint256 value) internal pure returns (uint80) {\\n require(value <= type(uint80).max, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint72(uint256 value) internal pure returns (uint72) {\\n require(value <= type(uint72).max, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint64(uint256 value) internal pure returns (uint64) {\\n require(value <= type(uint64).max, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint56(uint256 value) internal pure returns (uint56) {\\n require(value <= type(uint56).max, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint48(uint256 value) internal pure returns (uint48) {\\n require(value <= type(uint48).max, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint40(uint256 value) internal pure returns (uint40) {\\n require(value <= type(uint40).max, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint32(uint256 value) internal pure returns (uint32) {\\n require(value <= type(uint32).max, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint24(uint256 value) internal pure returns (uint24) {\\n require(value <= type(uint24).max, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint16(uint256 value) internal pure returns (uint16) {\\n require(value <= type(uint16).max, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint8(uint256 value) internal pure returns (uint8) {\\n require(value <= type(uint8).max, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\n */\\n function toUint256(int256 value) internal pure returns (uint256) {\\n require(value >= 0, \\\"SafeCast: value must be positive\\\");\\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 * _Available since v4.7._\\n */\\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\\n downcasted = int248(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\\n downcasted = int240(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\\n downcasted = int232(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\\n downcasted = int224(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\\n downcasted = int216(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\\n downcasted = int208(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\\n downcasted = int200(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\\n downcasted = int192(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\\n downcasted = int184(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\\n downcasted = int176(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\\n downcasted = int168(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\\n downcasted = int160(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\\n downcasted = int152(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\\n downcasted = int144(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\\n downcasted = int136(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\\n downcasted = int128(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\\n downcasted = int120(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\\n downcasted = int112(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\\n downcasted = int104(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\\n downcasted = int96(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\\n downcasted = int88(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\\n downcasted = int80(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\\n downcasted = int72(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\\n downcasted = int64(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\\n downcasted = int56(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\\n downcasted = int48(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\\n downcasted = int40(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\\n downcasted = int32(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\\n downcasted = int24(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\\n downcasted = int16(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\\n downcasted = int8(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\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 require(value <= uint256(type(int256).max), \\\"SafeCast: value doesn't fit in an int256\\\");\\n return int256(value);\\n }\\n}\\n\",\"keccak256\":\"0x52a8cfb0f5239d11b457dcdd1b326992ef672714ca8da71a157255bddd13f3ad\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SignedMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard signed math utilities missing in the Solidity language.\\n */\\nlibrary SignedMath {\\n /**\\n * @dev Returns the largest of two signed numbers.\\n */\\n function max(int256 a, int256 b) internal pure returns (int256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two signed numbers.\\n */\\n function min(int256 a, int256 b) internal pure returns (int256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two signed numbers without overflow.\\n * The result is rounded towards zero.\\n */\\n function average(int256 a, int256 b) internal pure returns (int256) {\\n // Formula from the book \\\"Hacker's Delight\\\"\\n int256 x = (a & b) + ((a ^ b) >> 1);\\n return x + (int256(uint256(x) >> 255) & (a ^ b));\\n }\\n\\n /**\\n * @dev Returns the absolute unsigned value of a signed value.\\n */\\n function abs(int256 n) internal pure returns (uint256) {\\n unchecked {\\n // must be unchecked in order to support `n = type(int256).min`\\n return uint256(n >= 0 ? n : -n);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf92515413956f529d95977adc9b0567d583c6203fc31ab1c23824c35187e3ddc\",\"license\":\"MIT\"},\"contracts/aa-4337/core/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable no-inline-assembly */\\n\\n/**\\n * returned data from validateUserOp.\\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\\n * @param aggregator - address(0) - the account validated the signature by itself.\\n * address(1) - the account failed to validate the signature.\\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\\n * @param validAfter - this UserOp is valid only after this timestamp.\\n * @param validaUntil - this UserOp is valid only up to this timestamp.\\n */\\nstruct ValidationData {\\n address aggregator;\\n uint48 validAfter;\\n uint48 validUntil;\\n}\\n\\n//extract sigFailed, validAfter, validUntil.\\n// also convert zero validUntil to type(uint48).max\\nfunction _parseValidationData(\\n uint validationData\\n) pure returns (ValidationData memory data) {\\n address aggregator = address(uint160(validationData));\\n uint48 validUntil = uint48(validationData >> 160);\\n if (validUntil == 0) {\\n validUntil = type(uint48).max;\\n }\\n uint48 validAfter = uint48(validationData >> (48 + 160));\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n// intersect account and paymaster ranges.\\nfunction _intersectTimeRange(\\n uint256 validationData,\\n uint256 paymasterValidationData\\n) pure returns (ValidationData memory) {\\n ValidationData memory accountValidationData = _parseValidationData(\\n validationData\\n );\\n ValidationData memory pmValidationData = _parseValidationData(\\n paymasterValidationData\\n );\\n address aggregator = accountValidationData.aggregator;\\n if (aggregator == address(0)) {\\n aggregator = pmValidationData.aggregator;\\n }\\n uint48 validAfter = accountValidationData.validAfter;\\n uint48 validUntil = accountValidationData.validUntil;\\n uint48 pmValidAfter = pmValidationData.validAfter;\\n uint48 pmValidUntil = pmValidationData.validUntil;\\n\\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp\\n * @param data - the ValidationData to pack\\n */\\nfunction _packValidationData(\\n ValidationData memory data\\n) pure returns (uint256) {\\n return\\n uint160(data.aggregator) |\\n (uint256(data.validUntil) << 160) |\\n (uint256(data.validAfter) << (160 + 48));\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp, when not using an aggregator\\n * @param sigFailed - true for signature failure, false for success\\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\\n * @param validAfter first timestamp this UserOperation is valid\\n */\\nfunction _packValidationData(\\n bool sigFailed,\\n uint48 validUntil,\\n uint48 validAfter\\n) pure returns (uint256) {\\n return\\n (sigFailed ? 1 : 0) |\\n (uint256(validUntil) << 160) |\\n (uint256(validAfter) << (160 + 48));\\n}\\n\\n/**\\n * keccak function over calldata.\\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\\n */\\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\\n assembly {\\n let mem := mload(0x40)\\n let len := data.length\\n calldatacopy(mem, data.offset, len)\\n ret := keccak256(mem, len)\\n }\\n}\\n\",\"keccak256\":\"0xa79f06cd158ecb8c0da95493a2f348933b8627a63e228b99738bff3aa107942d\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAggregator.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\n/**\\n * Aggregated Signatures validator.\\n */\\ninterface IAggregator {\\n /**\\n * validate aggregated signature.\\n * revert if the aggregated signature does not match the given list of operations.\\n */\\n function validateSignatures(\\n UserOperation[] calldata userOps,\\n bytes calldata signature\\n ) external view;\\n\\n /**\\n * validate signature of a single userOp\\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\\n * @param userOp the userOperation received from the user.\\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\\n * (usually empty, unless account and aggregator support some kind of \\\"multisig\\\"\\n */\\n function validateUserOpSignature(\\n UserOperation calldata userOp\\n ) external view returns (bytes memory sigForUserOp);\\n\\n /**\\n * aggregate multiple signatures into a single value.\\n * This method is called off-chain to calculate the signature to pass with handleOps()\\n * bundler MAY use optimized custom code perform this aggregation\\n * @param userOps array of UserOperations to collect the signatures from.\\n * @return aggregatedSignature the aggregated signature\\n */\\n function aggregateSignatures(\\n UserOperation[] calldata userOps\\n ) external view returns (bytes memory aggregatedSignature);\\n}\\n\",\"keccak256\":\"0xdfdcd80568f037716674619b31be630fcd8316262f05a815b41d1e81782c966a\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IEntryPoint.sol\":{\"content\":\"/**\\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\\n ** Only one instance required on each chain.\\n **/\\n// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-inline-assembly */\\n/* solhint-disable reason-string */\\n\\nimport \\\"./UserOperation.sol\\\";\\nimport \\\"./IStakeManager.sol\\\";\\nimport \\\"./IAggregator.sol\\\";\\nimport \\\"./INonceManager.sol\\\";\\n\\ninterface IEntryPoint is IStakeManager, INonceManager {\\n /***\\n * An event emitted after each successful request\\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\\n * @param sender - the account that generates this request.\\n * @param paymaster - if non-null, the paymaster that pays for this request.\\n * @param nonce - the nonce value from the request.\\n * @param success - true if the sender transaction succeeded, false if reverted.\\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\\n */\\n event UserOperationEvent(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address indexed paymaster,\\n uint256 nonce,\\n bool success,\\n uint256 actualGasCost,\\n uint256 actualGasUsed\\n );\\n\\n /**\\n * account \\\"sender\\\" was deployed.\\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\\n * @param sender the account that is deployed\\n * @param factory the factory used to deploy this account (in the initCode)\\n * @param paymaster the paymaster used by this UserOp\\n */\\n event AccountDeployed(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address factory,\\n address paymaster\\n );\\n\\n /**\\n * An event emitted if the UserOperation \\\"callData\\\" reverted with non-zero length\\n * @param userOpHash the request unique identifier.\\n * @param sender the sender of this request\\n * @param nonce the nonce used in the request\\n * @param revertReason - the return bytes from the (reverted) call to \\\"callData\\\".\\n */\\n event UserOperationRevertReason(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n uint256 nonce,\\n bytes revertReason\\n );\\n\\n /**\\n * an event emitted by handleOps(), before starting the execution loop.\\n * any event emitted before this event, is part of the validation.\\n */\\n event BeforeExecution();\\n\\n /**\\n * signature aggregator used by the following UserOperationEvents within this bundle.\\n */\\n event SignatureAggregatorChanged(address indexed aggregator);\\n\\n /**\\n * a custom revert error of handleOps, to identify the offending op.\\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\\n * @param reason - revert reason\\n * The string starts with a unique code \\\"AAmn\\\", where \\\"m\\\" is \\\"1\\\" for factory, \\\"2\\\" for account and \\\"3\\\" for paymaster issues,\\n * so a failure can be attributed to the correct entity.\\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\\n */\\n error FailedOp(uint256 opIndex, string reason);\\n\\n /**\\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\\n */\\n error SignatureValidationFailed(address aggregator);\\n\\n /**\\n * Successful result from simulateValidation.\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n */\\n error ValidationResult(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo\\n );\\n\\n /**\\n * Successful result from simulateValidation, if the account returns a signature aggregator\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\\n * bundler MUST use it to verify the signature, or reject the UserOperation\\n */\\n error ValidationResultWithAggregation(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo,\\n AggregatorStakeInfo aggregatorInfo\\n );\\n\\n /**\\n * return value of getSenderAddress\\n */\\n error SenderAddressResult(address sender);\\n\\n /**\\n * return value of simulateHandleOp\\n */\\n error ExecutionResult(\\n uint256 preOpGas,\\n uint256 paid,\\n uint48 validAfter,\\n uint48 validUntil,\\n bool targetSuccess,\\n bytes targetResult\\n );\\n\\n //UserOps handled, per aggregator\\n struct UserOpsPerAggregator {\\n UserOperation[] userOps;\\n // aggregator address\\n IAggregator aggregator;\\n // aggregated signature\\n bytes signature;\\n }\\n\\n /**\\n * Execute a batch of UserOperation.\\n * no signature aggregator is used.\\n * if any account requires an aggregator (that is, it returned an aggregator when\\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\\n * @param ops the operations to execute\\n * @param beneficiary the address to receive the fees\\n */\\n function handleOps(\\n UserOperation[] calldata ops,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * Execute a batch of UserOperation with Aggregators\\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\\n * @param beneficiary the address to receive the fees\\n */\\n function handleAggregatedOps(\\n UserOpsPerAggregator[] calldata opsPerAggregator,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * generate a request Id - unique identifier for this request.\\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\\n */\\n function getUserOpHash(\\n UserOperation calldata userOp\\n ) external view returns (bytes32);\\n\\n /**\\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\\n * @param userOp the user operation to validate.\\n */\\n function simulateValidation(UserOperation calldata userOp) external;\\n\\n /**\\n * gas and return values during simulation\\n * @param preOpGas the gas used for validation (including preValidationGas)\\n * @param prefund the required prefund for this operation\\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\\n */\\n struct ReturnInfo {\\n uint256 preOpGas;\\n uint256 prefund;\\n bool sigFailed;\\n uint48 validAfter;\\n uint48 validUntil;\\n bytes paymasterContext;\\n }\\n\\n /**\\n * returned aggregated signature info.\\n * the aggregator returned by the account, and its current stake.\\n */\\n struct AggregatorStakeInfo {\\n address aggregator;\\n StakeInfo stakeInfo;\\n }\\n\\n /**\\n * Get counterfactual sender address.\\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\\n * this method always revert, and returns the address in SenderAddressResult error\\n * @param initCode the constructor code to be passed into the UserOperation.\\n */\\n function getSenderAddress(bytes memory initCode) external;\\n\\n /**\\n * simulate full execution of a UserOperation (including both validation and target execution)\\n * this method will always revert with \\\"ExecutionResult\\\".\\n * it performs full validation of the UserOperation, but ignores signature error.\\n * an optional target address is called after the userop succeeds, and its value is returned\\n * (before the entire call is reverted)\\n * Note that in order to collect the the success/failure of the target call, it must be executed\\n * with trace enabled to track the emitted events.\\n * @param op the UserOperation to simulate\\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\\n * are set to the return from that call.\\n * @param targetCallData callData to pass to target address\\n */\\n function simulateHandleOp(\\n UserOperation calldata op,\\n address target,\\n bytes calldata targetCallData\\n ) external;\\n}\\n\",\"keccak256\":\"0x9ccb1b188eda8bbf5f6c2d01bd83c3d8b2b04fcf745283051d31fe96d1d8e40f\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/INonceManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\ninterface INonceManager {\\n /**\\n * Return the next nonce for this sender.\\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\\n * But UserOp with different keys can come with arbitrary order.\\n *\\n * @param sender the account address\\n * @param key the high 192 bit of the nonce\\n * @return nonce a full nonce to pass for next UserOp with this sender.\\n */\\n function getNonce(\\n address sender,\\n uint192 key\\n ) external view returns (uint256 nonce);\\n\\n /**\\n * Manually increment the nonce of the sender.\\n * This method is exposed just for completeness..\\n * Account does NOT need to call it, neither during validation, nor elsewhere,\\n * as the EntryPoint will update the nonce regardless.\\n * Possible use-case is call it with various keys to \\\"initialize\\\" their nonces to one, so that future\\n * UserOperations will not pay extra for the first transaction with a given key.\\n */\\n function incrementNonce(uint192 key) external;\\n}\\n\",\"keccak256\":\"0xce478ad0fa0d18a3b785ac854623029e7ab463d05873dfaa365abfa1bf100912\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IStakeManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8.12;\\n\\n/**\\n * manage deposits and stakes.\\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\\n * stake is value locked for at least \\\"unstakeDelay\\\" by the staked entity.\\n */\\ninterface IStakeManager {\\n event Deposited(address indexed account, uint256 totalDeposit);\\n\\n event Withdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /// Emitted when stake or unstake delay are modified\\n event StakeLocked(\\n address indexed account,\\n uint256 totalStaked,\\n uint256 unstakeDelaySec\\n );\\n\\n /// Emitted once a stake is scheduled for withdrawal\\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\\n\\n event StakeWithdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /**\\n * @param deposit the entity's deposit\\n * @param staked true if this entity is staked.\\n * @param stake actual amount of ether staked for this entity.\\n * @param unstakeDelaySec minimum delay to withdraw the stake.\\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\\n * and the rest fit into a 2nd cell.\\n * 112 bit allows for 10^15 eth\\n * 48 bit for full timestamp\\n * 32 bit allows 150 years for unstake delay\\n */\\n struct DepositInfo {\\n uint112 deposit;\\n bool staked;\\n uint112 stake;\\n uint32 unstakeDelaySec;\\n uint48 withdrawTime;\\n }\\n\\n //API struct used by getStakeInfo and simulateValidation\\n struct StakeInfo {\\n uint256 stake;\\n uint256 unstakeDelaySec;\\n }\\n\\n /// @return info - full deposit information of given account\\n function getDepositInfo(\\n address account\\n ) external view returns (DepositInfo memory info);\\n\\n /// @return the deposit (for gas payment) of the account\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * add to the deposit of the given account\\n */\\n function depositTo(address account) external payable;\\n\\n /**\\n * add to the account's stake - amount and delay\\n * any pending unstake is first cancelled.\\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\\n */\\n function addStake(uint32 _unstakeDelaySec) external payable;\\n\\n /**\\n * attempt to unlock the stake.\\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\\n */\\n function unlockStake() external;\\n\\n /**\\n * withdraw from the (unlocked) stake.\\n * must first call unlockStake and wait for the unstakeDelay to pass\\n * @param withdrawAddress the address to send withdrawn value.\\n */\\n function withdrawStake(address payable withdrawAddress) external;\\n\\n /**\\n * withdraw from the deposit.\\n * @param withdrawAddress the address to send withdrawn value.\\n * @param withdrawAmount the amount to withdraw.\\n */\\n function withdrawTo(\\n address payable withdrawAddress,\\n uint256 withdrawAmount\\n ) external;\\n}\\n\",\"keccak256\":\"0xadcea606c9b7aafe6645441f2154a60f271330b0eee5292a632aa71c1672d546\",\"license\":\"GPL-3.0-only\"},\"contracts/aa-4337/interfaces/UserOperation.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable no-inline-assembly */\\n\\nimport {calldataKeccak} from \\\"../core/Helpers.sol\\\";\\n\\n/**\\n * User Operation struct\\n * @param sender the sender account of this request.\\n * @param nonce unique value the sender uses to verify it is not a replay.\\n * @param initCode if set, the account contract will be created by this constructor/\\n * @param callData the method call to execute on this account.\\n * @param callGasLimit the gas limit passed to the callData method call.\\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\\n * @param maxFeePerGas same as EIP-1559 gas parameter.\\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\\n */\\nstruct UserOperation {\\n address sender;\\n uint256 nonce;\\n bytes initCode;\\n bytes callData;\\n uint256 callGasLimit;\\n uint256 verificationGasLimit;\\n uint256 preVerificationGas;\\n uint256 maxFeePerGas;\\n uint256 maxPriorityFeePerGas;\\n bytes paymasterAndData;\\n bytes signature;\\n}\\n\\n/**\\n * Utility functions helpful when working with UserOperation structs.\\n */\\nlibrary UserOperationLib {\\n function getSender(\\n UserOperation calldata userOp\\n ) internal pure returns (address) {\\n address data;\\n //read sender from userOp, which is first userOp member (saves 800 gas...)\\n assembly {\\n data := calldataload(userOp)\\n }\\n return address(uint160(data));\\n }\\n\\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\\n // pay above what he signed for.\\n function gasPrice(\\n UserOperation calldata userOp\\n ) internal view returns (uint256) {\\n unchecked {\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n if (maxFeePerGas == maxPriorityFeePerGas) {\\n //legacy mode (for networks that don't support basefee opcode)\\n return maxFeePerGas;\\n }\\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\\n }\\n }\\n\\n function pack(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes memory ret) {\\n address sender = getSender(userOp);\\n uint256 nonce = userOp.nonce;\\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\\n bytes32 hashCallData = calldataKeccak(userOp.callData);\\n uint256 callGasLimit = userOp.callGasLimit;\\n uint256 verificationGasLimit = userOp.verificationGasLimit;\\n uint256 preVerificationGas = userOp.preVerificationGas;\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\\n\\n return\\n abi.encode(\\n sender,\\n nonce,\\n hashInitCode,\\n hashCallData,\\n callGasLimit,\\n verificationGasLimit,\\n preVerificationGas,\\n maxFeePerGas,\\n maxPriorityFeePerGas,\\n hashPaymasterAndData\\n );\\n }\\n\\n function hash(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes32) {\\n return keccak256(pack(userOp));\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n}\\n\",\"keccak256\":\"0x2429f5cc546bdee08c7e63858d0dda8491eaa3ab5194df884dc948c1154d2834\",\"license\":\"GPL-3.0\"},\"contracts/facets/Modifiers.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {LibGuardian} from \\\"../libraries/LibGuardian.sol\\\";\\nimport {BarzStorage} from \\\"../libraries/LibAppStorage.sol\\\";\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\n\\n/**\\n * @title Modifiers\\n * @dev Responsible for providing modifiers/util functions to Facet contracts\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\nabstract contract Modifiers is BarzStorage {\\n uint8 constant INNER_STRUCT = 0;\\n\\n error CallerNotGuardian();\\n error CallerNotGuardianOrOwner();\\n error DuplicateApprover();\\n error ZeroApproverLength();\\n error UnregisteredFacetAndSelectors();\\n\\n /**\\n * @notice Modifier to only allow guardian to make a call, reverts if any other entity is the caller\\n */\\n modifier onlyGuardian() {\\n if (!LibGuardian.isGuardian(msg.sender)) revert CallerNotGuardian();\\n _;\\n }\\n\\n /**\\n * @notice Modifier to only allow guardian or owner to make a call, reverts if any other entity is the caller\\n */\\n modifier onlyGuardianOrOwner() {\\n if (!LibGuardian.isGuardian(msg.sender) && address(this) != msg.sender)\\n revert CallerNotGuardianOrOwner();\\n _;\\n }\\n\\n /**\\n * @notice Checks if the approver address is the array is unique with no duplicate\\n * @dev This method loops through the array and checks if a duplicate address exists, it reverts if duplicate address exists\\n * @param approvers Array of address\\n */\\n function _checkApprover(\\n address[] memory approvers\\n ) internal pure returns (bool) {\\n uint256 approverLength = approvers.length;\\n if (0 == approverLength) revert ZeroApproverLength();\\n for (uint256 i; i < approverLength - 1; ) {\\n for (uint256 j = i + 1; j < approverLength; ) {\\n if (approvers[i] == approvers[j]) {\\n revert DuplicateApprover(); // Found a duplicate\\n }\\n unchecked {\\n ++j;\\n }\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n return false; // No duplicates found\\n }\\n\\n /**\\n * @notice Checks if the facet getting added or replaced is registered to facet registry\\n * @dev This method loops through the cut and checks if the facet getting added/replaced is registered to facet registry\\n * @param _diamondCut Array of FacetCut, data for diamondCut defined in EIP-2535\\n */\\n function _checkFacetCutValidity(\\n IDiamondCut.FacetCut[] memory _diamondCut\\n ) internal view {\\n uint256 diamondCutLength = _diamondCut.length;\\n for (uint256 i; i < diamondCutLength; ) {\\n if (\\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Add ||\\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Replace\\n ) {\\n if (\\n !s.facetRegistry.areFacetFunctionSelectorsRegistered(\\n _diamondCut[i].facetAddress,\\n _diamondCut[i].functionSelectors\\n )\\n ) revert UnregisteredFacetAndSelectors();\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb42956323d199bdec243a5f9859439aae057fbfdd1d79e3a96afc857ecb3115f\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/DiamondCutFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {LibDiamond} from \\\"../../libraries/LibDiamond.sol\\\";\\nimport {LibGuardian} from \\\"../../libraries/LibGuardian.sol\\\";\\nimport {ISecurityManager} from \\\"../../infrastructure/interfaces/ISecurityManager.sol\\\";\\nimport {SignatureChecker} from \\\"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\\\";\\nimport {LibFacetStorage, DiamondCutApprovalConfig, ApprovalConfig} from \\\"../../libraries/LibFacetStorage.sol\\\";\\nimport {Modifiers} from \\\"../Modifiers.sol\\\";\\nimport {IDiamondCut} from \\\"./interfaces/IDiamondCut.sol\\\";\\n\\n/**\\n * @title DiamondCut Facet\\n * @dev Responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract DiamondCutFacet is Modifiers, IDiamondCut {\\n ISecurityManager public immutable securityManager;\\n\\n /**\\n * @notice This constructor sets the Security Manager address which is an immutable variable.\\n * Immutable variables do not impact the storage of diamond\\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\\n */\\n constructor(address _securityManager) {\\n securityManager = ISecurityManager(_securityManager);\\n }\\n\\n /**\\n * @notice Updates the flag for the interfaceId\\n * @param _interfaceId InterfaceID to update the mapping\\n * @param _flag Bool value to update the mapping of the given interface ID\\n */\\n function updateSupportsInterface(\\n bytes4 _interfaceId,\\n bool _flag\\n ) external override onlyWhenUnlocked {\\n LibDiamond.enforceIsSelf();\\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId] = _flag;\\n emit SupportsInterfaceUpdated(_interfaceId, _flag);\\n }\\n\\n /**\\n * @notice Add/replace/remove any number of functions and optionally execute\\n * a function with delegatecall when guardians don't exist\\n * @param _diamondCut Contains the facet addresses and function selectors\\n * @param _init The address of the contract or facet to execute _calldata. It's prohibited in Barz\\n */\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata\\n ) external override onlyWhenUnlocked {\\n LibDiamond.enforceIsSelf();\\n\\n _checkFacetCutValidity(_diamondCut);\\n // require approval from guardian if guardian exists\\n if (0 != LibGuardian.guardianCount())\\n revert DiamondCutFacet__InvalidRouteWithGuardian();\\n if (address(0) != _init) revert DiamondCutFacet__InvalidInitAddress();\\n\\n unchecked {\\n ++LibFacetStorage.diamondCutStorage().nonce;\\n }\\n LibDiamond.diamondCut(_diamondCut, address(0), \\\"\\\");\\n }\\n\\n /**\\n * @notice Add/replace/remove any number of functions and optionally execute\\n * a function with delegatecall when guardians exist\\n * @param _diamondCut Contains the facet addresses and function selectors\\n * @param _approvers Guardian or owner address that approves the diamond cut\\n * @param _signatures Signature of Guardians or owner that approves the diamond cut\\n */\\n function diamondCutWithGuardian(\\n FacetCut[] calldata _diamondCut,\\n address[] calldata _approvers,\\n bytes[] calldata _signatures\\n ) external override onlyWhenUnlocked {\\n if (_approvers.length != _signatures.length)\\n revert DiamondCutFacet__InvalidArrayLength();\\n _checkFacetCutValidity(_diamondCut);\\n if (0 == LibGuardian.guardianCount())\\n revert DiamondCutFacet__InvalidRouteWithGuardian();\\n\\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\\n\\n _checkApprover(_approvers);\\n _checkDuplicateOnChainApprover(cutHash, _approvers);\\n\\n bool onChainOwnerApproval = getOwnerCutApprovalWithTimeValidity(\\n cutHash\\n );\\n\\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\\n if (\\n _approvers.length +\\n getDiamondCutApprovalCountWithTimeValidity(cutHash) <\\n LibGuardian.majorityOfGuardians() + threshold\\n ) revert DiamondCutFacet__InsufficientApprovers();\\n\\n bool ownerApproved;\\n for (uint256 i; i < _approvers.length; ) {\\n if (\\n !LibGuardian.isGuardian(_approvers[i]) &&\\n _approvers[i] != address(this)\\n ) revert DiamondCutFacet__InvalidApprover();\\n if (_approvers[i] == address(this)) {\\n if (onChainOwnerApproval)\\n revert DiamondCutFacet__OwnerAlreadyApproved();\\n ownerApproved = true;\\n }\\n if (\\n !SignatureChecker.isValidSignatureNow(\\n _approvers[i],\\n cutHash,\\n _signatures[i]\\n )\\n ) revert DiamondCutFacet__InvalidApproverSignature();\\n unchecked {\\n ++i;\\n }\\n }\\n if (!ownerApproved && !onChainOwnerApproval)\\n revert DiamondCutFacet__LackOfOwnerApproval();\\n\\n unchecked {\\n ++LibFacetStorage.diamondCutStorage().nonce;\\n }\\n LibDiamond.diamondCut(_diamondCut, address(0), \\\"\\\");\\n }\\n\\n /**\\n * @notice Approves diamond cut. This can only be called directly from guardian or owner\\n * @param _diamondCut Contains the facet addresses and function selectors\\n */\\n function approveDiamondCut(\\n FacetCut[] calldata _diamondCut\\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\\n if (LibGuardian.guardianCount() == 0)\\n revert DiamondCutFacet__InvalidRouteWithoutGuardian();\\n DiamondCutApprovalConfig storage ds = LibFacetStorage\\n .diamondCutStorage()\\n .diamondCutApprovalConfigs[INNER_STRUCT];\\n _checkFacetCutValidity(_diamondCut);\\n\\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\\n uint64 approvalValidUntil = uint64(\\n block.timestamp + getApprovalValidationPeriod()\\n );\\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(\\n true,\\n approvalValidUntil\\n );\\n emit DiamondCutApproved(_diamondCut);\\n if (\\n (getDiamondCutApprovalCountWithTimeValidity(cutHash) >=\\n LibGuardian.majorityOfGuardians()) &&\\n getOwnerCutApprovalWithTimeValidity(cutHash)\\n ) {\\n unchecked {\\n ++LibFacetStorage.diamondCutStorage().nonce;\\n }\\n LibDiamond.diamondCut(_diamondCut, address(0), \\\"\\\");\\n }\\n }\\n\\n /**\\n * @notice Revokes the approval of diamond cut. This can only be called directly from guardian or owner\\n * @param _diamondCut Contains the facet addresses and function selectors\\n */\\n function revokeDiamondCutApproval(\\n FacetCut[] calldata _diamondCut\\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\\n DiamondCutApprovalConfig storage ds = LibFacetStorage\\n .diamondCutStorage()\\n .diamondCutApprovalConfigs[INNER_STRUCT];\\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\\n if (!ds.isDiamondCutApproved[cutHash][msg.sender].isApproved)\\n revert DiamondCutFacet__CannotRevokeUnapproved();\\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(false, 0);\\n emit DiamondCutApprovalRevoked(_diamondCut);\\n }\\n\\n /**\\n * @notice Gets the number of approvals of diamond cut from guardians\\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\\n */\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 _diamondCutHash\\n ) public view override returns (uint256 approvalCount) {\\n address[] memory guardians = LibGuardian.getGuardians();\\n uint256 guardiansLength = guardians.length;\\n for (uint256 i; i < guardiansLength; ) {\\n if (isCutApproved(_diamondCutHash, guardians[i])) {\\n unchecked {\\n ++approvalCount;\\n }\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n return approvalCount;\\n }\\n\\n /**\\n * @notice Returns if the owner has approved the diamond cut\\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\\n * @return isApprovedByOwner Bool value showing if the owner approved the cut\\n */\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 _diamondCutHash\\n ) public view override returns (bool isApprovedByOwner) {\\n isApprovedByOwner = isCutApproved(_diamondCutHash, address(this));\\n }\\n\\n /**\\n * @notice Returns if the given approver has approved the diamond cut\\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\\n * @param _approver Address of approver\\n * @return isApproved Bool value showing if the approver approved the cut\\n */\\n function isCutApproved(\\n bytes32 _diamondCutHash,\\n address _approver\\n ) public view override returns (bool isApproved) {\\n DiamondCutApprovalConfig storage ds = LibFacetStorage\\n .diamondCutStorage()\\n .diamondCutApprovalConfigs[INNER_STRUCT];\\n isApproved = (ds\\n .isDiamondCutApproved[_diamondCutHash][_approver].isApproved &&\\n block.timestamp <\\n ds.isDiamondCutApproved[_diamondCutHash][_approver].validUntil);\\n }\\n\\n /**\\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\\n * Approvers who approved on-chain should not be included in the off-chain approval\\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\\n * @param _approvers List of approver addresses\\n */\\n function _checkDuplicateOnChainApprover(\\n bytes32 _diamondCutHash,\\n address[] memory _approvers\\n ) public view {\\n address[] memory guardians = LibGuardian.getGuardians();\\n uint256 guardianLength = guardians.length;\\n uint256 approversLength = _approvers.length;\\n for (uint256 i; i < guardianLength; ) {\\n if (isCutApproved(_diamondCutHash, guardians[i])) {\\n for (uint256 j; j < approversLength; ) {\\n if (_approvers[j] == guardians[i])\\n revert DiamondCutFacet__DuplicateApproval();\\n unchecked {\\n ++j;\\n }\\n }\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * @notice Returns the diamond cut hash. This function ensures that this hash is safe from replay attack by including\\n * salt, address, chainId, and nonce, etc.\\n * @param _diamondCut Contains the facet addresses and function selectors\\n * @return cutHash Diamond Cut Hash\\n */\\n function getDiamondCutHash(\\n FacetCut[] calldata _diamondCut\\n ) public view override returns (bytes32 cutHash) {\\n cutHash = keccak256(\\n abi.encodePacked(\\n \\\"\\\\x19Ethereum Signed Message:\\\\n32\\\",\\n keccak256(\\n abi.encode(\\n keccak256(abi.encode(_diamondCut)),\\n address(this),\\n block.chainid,\\n LibFacetStorage.diamondCutStorage().nonce\\n )\\n )\\n )\\n );\\n }\\n\\n /**\\n * @notice Returns the approval validation Period\\n * @dev This method fetches the validation period from the security manager\\n * @return approvalValidationPeriod Approval validation period of Barz contract fetched from security manager\\n */\\n function getApprovalValidationPeriod()\\n internal\\n view\\n returns (uint256 approvalValidationPeriod)\\n {\\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\\n address(this)\\n );\\n if (approvalValidationPeriod <= 0)\\n revert DiamondCutFacet__InvalidApprovalValidationPeriod();\\n }\\n\\n /**\\n * @notice Returns the diamond cut nonce of this wallet\\n * @dev This method fetches the nonce from diamond cut storage\\n * @return cutNonce Nonce of diamond cut to protect from reply attacks\\n */\\n function getDiamondCutNonce()\\n public\\n view\\n override\\n returns (uint128 cutNonce)\\n {\\n cutNonce = LibFacetStorage.diamondCutStorage().nonce;\\n }\\n}\\n\",\"keccak256\":\"0xe91a7dd2daabf2e989c94089f4f1eb0da94276c3070559ac8988838e10dd1f5d\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/infrastructure/interfaces/IFacetRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Registry Interface\\n * @dev Interface for Facet Registry contract to keep track of facets & function selectors addable to user wallets\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IFacetRegistry {\\n struct FacetRegistryConfig {\\n bytes4[] selectors;\\n mapping(bytes4 => FacetInfo) info;\\n }\\n struct FacetInfo {\\n bool exists;\\n uint128 index;\\n }\\n\\n event FacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] facetSelectors\\n );\\n event FacetFunctionSelectorsRemoved(address facet, bytes4[] facetSelectors);\\n\\n error FacetRegistry__FacetSelectorAlreadyRegistered();\\n error FacetRegistry__UnregisteredFacetSelector();\\n\\n function registerFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function removeFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function areFacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external view returns (bool);\\n\\n function isFacetFunctionSelectorRegistered(\\n address facet,\\n bytes4 facetSelector\\n ) external view returns (bool);\\n\\n function getFacetFunctionSelectors(\\n address facet\\n ) external view returns (bytes4[] memory);\\n}\\n\",\"keccak256\":\"0x6e6dd2cab346ef7c31230740ec48d2925e4a9ab24c2f2fb268baaf408dcf02ef\",\"license\":\"Apache-2.0\"},\"contracts/infrastructure/interfaces/ISecurityManager.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Registry Interface\\n * @dev Infrastructure contract to manage security parameters of users\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\ninterface ISecurityManager {\\n error SecurityManager__OutOfBoundary();\\n error SecurityManager__CallerNotWallet();\\n error SecurityManager__AlreadyIntialized();\\n\\n function initializeAdditionSecurityPeriod(\\n uint128 defaultAdditionSecurityPeriod,\\n uint128 minAdditionSecurityPeriod,\\n uint128 maxAdditionSecurityPeriod\\n ) external;\\n\\n function initializeRemovalSecurityPeriod(\\n uint128 defaultRemovalSecurityPeriod,\\n uint128 minRemovalSecurityPeriod,\\n uint128 maxRemovalSecurityPeriod\\n ) external;\\n\\n function initializeApprovalValidationPeriod(\\n uint128 defaultApprovalValidationPeriod,\\n uint128 minApprovalValidationPeriod,\\n uint128 maxApprovalValidationPeriod\\n ) external;\\n\\n function initializeMigrationPeriod(\\n uint128 defaultMigrationPeriod,\\n uint128 minMigrationPeriod,\\n uint128 maxMigrationPeriod\\n ) external;\\n\\n function initializeLockPeriod(\\n uint128 defaultLockPeriod,\\n uint128 minLockPeriod,\\n uint128 maxLockPeriod\\n ) external;\\n\\n function initializeRecoveryPeriod(\\n uint128 defaultRecoveryPeriod,\\n uint128 minRecoveryPeriod,\\n uint128 maxRecoveryPeriod\\n ) external;\\n\\n function initializeSecurityWindow(\\n uint128 defaultSecurityWindow,\\n uint128 minSecurityWindow,\\n uint128 maxSecurityWindow\\n ) external;\\n\\n function setAdditionSecurityPeriod(\\n address wallet,\\n uint128 additionSecurityPeriod\\n ) external;\\n\\n function setRemovalSecurityPeriod(\\n address wallet,\\n uint128 removalSecurityPeriod\\n ) external;\\n\\n function setSecurityWindow(address wallet, uint128 securityWindow) external;\\n\\n function setRecoveryPeriod(address wallet, uint128 recoveryPeriod) external;\\n\\n function setLockPeriod(address wallet, uint128 lockPeriod) external;\\n\\n function setApprovalValidationPeriod(\\n address wallet,\\n uint128 approvalValidationPeriod\\n ) external;\\n\\n function setMigrationPeriod(\\n address wallet,\\n uint128 migrationPeriod\\n ) external;\\n\\n function additionSecurityPeriodOf(\\n address wallet\\n ) external view returns (uint128);\\n\\n function removalSecurityPeriodOf(\\n address wallet\\n ) external view returns (uint128);\\n\\n function securityWindowOf(address wallet) external view returns (uint128);\\n\\n function recoveryPeriodOf(address wallet) external view returns (uint128);\\n\\n function lockPeriodOf(address wallet) external view returns (uint128);\\n\\n function migrationPeriodOf(address wallet) external view returns (uint128);\\n\\n function approvalValidationPeriodOf(\\n address wallet\\n ) external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x9ac6566033ef81ba5744c8ed2b08f130b781b498ab9245bcca87567669549552\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibAppStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {SafeCast} from \\\"@openzeppelin/contracts/utils/math/SafeCast.sol\\\";\\nimport {IEntryPoint} from \\\"../aa-4337/interfaces/IEntryPoint.sol\\\";\\nimport {IFacetRegistry} from \\\"../infrastructure/interfaces/IFacetRegistry.sol\\\";\\n\\n/*\\n * @title App Storage\\n * @dev App storage for Barz contract to prevent storage collision\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Lock {\\n uint64 release;\\n bytes4 locker;\\n}\\n\\nstruct InitializersStorage {\\n // NOTE: initialized is a variable to make sure the initialization is only done once.\\n uint8 signerInitialized;\\n uint8 accountInitialized;\\n uint8 restrictionsInitialized;\\n}\\n\\nstruct AppStorage {\\n mapping(uint256 => InitializersStorage) initStorage;\\n uint8 signerMigration;\\n bytes4 validateOwnerSignatureSelector;\\n IEntryPoint entryPoint;\\n IFacetRegistry facetRegistry;\\n mapping(uint256 => Lock) locks;\\n}\\n\\nlibrary LibAppStorage {\\n error LibAppStorage__AccountAlreadyUninitialized();\\n error LibAppStorage__AccountMustBeUninitialized();\\n error LibAppStorage__SignerAlreadyUninitialized();\\n error LibAppStorage__SignerMustBeUninitialized();\\n\\n function appStorage() internal pure returns (AppStorage storage ds) {\\n assembly {\\n ds.slot := 0\\n }\\n }\\n\\n function setSignerUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerAlreadyUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 0;\\n }\\n\\n function getValidateOwnerSignatureSelector()\\n internal\\n view\\n returns (bytes4 selector)\\n {\\n selector = appStorage().validateOwnerSignatureSelector;\\n }\\n\\n function setValidateOwnerSignatureSelector(\\n bytes4 _validateOwnerSignatureSelector\\n ) internal {\\n appStorage()\\n .validateOwnerSignatureSelector = _validateOwnerSignatureSelector;\\n }\\n\\n function enforceSignerInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerMustBeUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 1;\\n }\\n\\n function enforceAccountInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].accountInitialized) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n s.initStorage[0].accountInitialized = 1;\\n }\\n\\n function initiateSignerMigration() internal {\\n appStorage().signerMigration = 1;\\n }\\n\\n function enforceSignerMigration() internal view {\\n if (1 != appStorage().signerMigration) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n }\\n\\n function finalizeSignerMigration() internal {\\n appStorage().signerMigration = 0;\\n }\\n\\n function setLock(uint256 _releaseAfter, bytes4 _locker) internal {\\n appStorage().locks[0] = Lock(SafeCast.toUint64(_releaseAfter), _locker);\\n }\\n\\n function enforceRestrictionsInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__SignerMustBeUninitialized();\\n s.initStorage[0].restrictionsInitialized = 1;\\n }\\n\\n function setRestrictionsUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__AccountAlreadyUninitialized();\\n s.initStorage[0].restrictionsInitialized = 0;\\n }\\n}\\n\\ncontract BarzStorage {\\n AppStorage internal s;\\n modifier onlyWhenUnlocked() {\\n require(\\n uint64(block.timestamp) >= s.locks[0].release,\\n \\\"Account Locked\\\"\\n );\\n _;\\n }\\n modifier onlyWhenLocked() {\\n require(\\n uint64(block.timestamp) < s.locks[0].release,\\n \\\"Account Unlocked\\\"\\n );\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x48524007862a6ce0e07f645950613ce6513ce073c37a109c75019683d42bae27\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\\n bytes4(keccak256(\\\"verifyRestrictions(address,address,uint256,bytes)\\\"));\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // Default Fallback Handler of the barz.\\n IDiamondLoupe defaultFallbackHandler;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function enforceIsSelf() internal view {\\n require(msg.sender == address(this), \\\"LibDiamond: Caller not self\\\");\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n\\n unchecked {\\n facetIndex++;\\n }\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n\\n function restrictionsFacet() internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(\\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2cabdc00de859c3a3170ce3bda5d0e5fd3933d47ce904fd1585f9818b02572f8\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibFacetStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Storage\\n * @dev Storage contract to store each facets variables with diamond storage\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Secp256k1VerificationStorage {\\n address signer;\\n}\\n\\nstruct Secp256r1VerificationStorage {\\n uint256[2] q;\\n}\\n\\nstruct GuardianStorage {\\n mapping(bytes32 => uint256) pending;\\n mapping(uint8 => StorageConfig) configs;\\n}\\n\\nstruct Info {\\n bool exists;\\n uint128 index;\\n}\\n\\nstruct StorageConfig {\\n address[] addresses;\\n mapping(address => Info) info;\\n}\\n\\nstruct RecoveryConfig {\\n bytes recoveryPublicKey;\\n uint64 executeAfter;\\n}\\n\\nstruct ApprovalConfig {\\n bool isApproved;\\n uint64 validUntil;\\n}\\n\\nstruct RecoveryApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isNewOwnerApproved;\\n}\\n\\nstruct RecoveryStorage {\\n mapping(uint8 => RecoveryConfig) recoveryConfigs;\\n mapping(uint8 => RecoveryApprovalConfig) recoveryApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct RestrictionsStorage {\\n address[] restrictions;\\n mapping(address => bool) exists;\\n}\\n\\nstruct SignatureMigrationConfig {\\n bytes migrationPublicKey;\\n address migrationVerificationFacet;\\n bytes4[] migrationSelectors;\\n uint64 migrateAfter;\\n}\\n\\nstruct SignatureMigrationApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isMigrationApproved;\\n}\\n\\nstruct SignatureMigrationStorage {\\n mapping(uint8 => SignatureMigrationConfig) migrationConfigs;\\n mapping(uint8 => SignatureMigrationApprovalConfig) migrationApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct DiamondCutApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isDiamondCutApproved;\\n}\\n\\nstruct DiamondCutStorage {\\n mapping(uint8 => DiamondCutApprovalConfig) diamondCutApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct LockStorage {\\n uint128 nonce;\\n}\\n\\nlibrary LibFacetStorage {\\n bytes32 constant K1_STORAGE_POSITION =\\n keccak256(\\n \\\"v0.trustwallet.diamond.storage.Secp256k1VerificationStorage\\\"\\n );\\n bytes32 constant R1_STORAGE_POSITION =\\n keccak256(\\n \\\"v0.trustwallet.diamond.storage.Secp256r1VerificationStorage\\\"\\n );\\n bytes32 constant GUARDIAN_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.GuardianStorage\\\");\\n bytes32 constant RECOVERY_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.RecoveryStorage\\\");\\n bytes32 constant RESTRICTION_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.RestrictionsStorage\\\");\\n bytes32 constant MIGRATION_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.SignatureMigrationStorage\\\");\\n bytes32 constant DIAMONDCUT_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.DiamondCutStorage\\\");\\n bytes32 constant LOCK_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.LockStorage\\\");\\n\\n function k1Storage()\\n internal\\n pure\\n returns (Secp256k1VerificationStorage storage ds)\\n {\\n bytes32 storagePosition = K1_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function r1Storage()\\n internal\\n pure\\n returns (Secp256r1VerificationStorage storage ds)\\n {\\n bytes32 storagePosition = R1_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function guardianStorage()\\n internal\\n pure\\n returns (GuardianStorage storage ds)\\n {\\n bytes32 storagePosition = GUARDIAN_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function recoveryStorage()\\n internal\\n pure\\n returns (RecoveryStorage storage ds)\\n {\\n bytes32 storagePosition = RECOVERY_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function restrictionsStorage()\\n internal\\n pure\\n returns (RestrictionsStorage storage ds)\\n {\\n bytes32 storagePosition = RESTRICTION_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function migrationStorage()\\n internal\\n pure\\n returns (SignatureMigrationStorage storage ds)\\n {\\n bytes32 storagePosition = MIGRATION_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function diamondCutStorage()\\n internal\\n pure\\n returns (DiamondCutStorage storage ds)\\n {\\n bytes32 storagePosition = DIAMONDCUT_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function lockStorage() internal pure returns (LockStorage storage ds) {\\n bytes32 storagePosition = LOCK_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n}\\n\",\"keccak256\":\"0x87c85decfd943deda9540733e464cb1a92eba735a301e89ce6f798016e359761\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibGuardian.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {LibFacetStorage, StorageConfig} from \\\"./LibFacetStorage.sol\\\";\\n\\n/**\\n * @title LibGuardian\\n * @dev Internal Library to provide utility feature for Guardians stored in Guardian Facet Storage\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\nlibrary LibGuardian {\\n function majorityOfGuardians()\\n internal\\n view\\n returns (uint256 guardianNumber)\\n {\\n uint256 guardianLength = guardianCount();\\n guardianNumber = (guardianLength == 0) ? 0 : guardianLength / 2 + 1;\\n }\\n\\n function isGuardian(address _guardian) internal view returns (bool) {\\n StorageConfig storage config = LibFacetStorage\\n .guardianStorage()\\n .configs[0];\\n return config.info[_guardian].exists;\\n }\\n\\n function guardianCount() internal view returns (uint256) {\\n StorageConfig storage config = LibFacetStorage\\n .guardianStorage()\\n .configs[0];\\n return config.addresses.length;\\n }\\n\\n function getGuardians() internal view returns (address[] memory) {\\n StorageConfig storage config = LibFacetStorage\\n .guardianStorage()\\n .configs[0];\\n address[] memory addresses = new address[](config.addresses.length);\\n uint256 addressesLen = config.addresses.length;\\n for (uint256 i; i < addressesLen; ) {\\n addresses[i] = config.addresses[i];\\n unchecked {\\n ++i;\\n }\\n }\\n return addresses;\\n }\\n}\\n\",\"keccak256\":\"0x6a620992d5535878fc03d1a27a6675f4c1509adfb3ddbbca1c52b546c25392dc\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x60a06040523480156200001157600080fd5b506040516200379b3803806200379b833981016040819052620000349162000046565b6001600160a01b031660805262000078565b6000602082840312156200005957600080fd5b81516001600160a01b03811681146200007157600080fd5b9392505050565b6080516137006200009b600039600081816101f10152611b2501526137006000f3fe608060405234801561001057600080fd5b50600436106100d45760003560e01c806379c0d58d11610081578063afb877bb1161005b578063afb877bb146101d9578063de675a6d146101ec578063e33ecf0a1461023857600080fd5b806379c0d58d14610192578063836d6bfb146101b35780638824a0bb146101c657600080fd5b806326fc3ef4116100b257806326fc3ef4146101145780632f4d98ea1461015c5780633c0985681461017f57600080fd5b806313c34f4b146100d95780631c776dd5146100ee5780631f931c1c14610101575b600080fd5b6100ec6100e7366004612a97565b61024b565b005b6100ec6100fc366004612ad9565b6104df565b6100ec61010f366004612b9c565b610a76565b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9bf546040516fffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b61016f61016a366004612c4a565b610c7b565b6040519015158152602001610153565b6100ec61018d366004612ca4565b610c8d565b6101a56101a0366004612c4a565b610df2565b604051908152602001610153565b61016f6101c1366004612cdb565b610e4c565b6100ec6101d4366004612dd2565b610eed565b6100ec6101e7366004612a97565b610fe1565b6102137f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610153565b6101a5610246366004612a97565b61130e565b3360009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff1615801561028a5750303314155b156102c1576040517f6238ee3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610369576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064015b60405180910390fd5b60008080527f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be6020527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d3906103be848461130e565b60008181526020848152604080832033845290915290205490915060ff16610412576040517fedc5708300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051808201825260008082526020808301828152858352868252848320338452909152908390209151825491517fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000009092169015157fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff161761010067ffffffffffffffff90921691909102179055517f3c3d8c1f0b0faff6fe0ace6b485d0595a0106dce9e303f956fd941ebdbe9a98e906104d19086908690612f54565b60405180910390a150505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610582576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b8281146105bb576040517fe854148500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6105cd6105c886886130aa565b611435565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b754600003610650576040517fa788861700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061065c878761130e565b905061069a8585808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506115b392505050565b506106d881868680806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250610eed92505050565b60006106e382610c7b565b90506000816106f35760016106f6565b60005b60ff169050806107046116d0565b61070e9190613201565b61071784610df2565b6107219088613201565b1015610759576040517f709fb08000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805b878110156109a0576107d989898381811061077a5761077a613214565b905060200201602081019061078f9190613243565b73ffffffffffffffffffffffffffffffffffffffff1660009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff1690565b1580156108225750308989838181106107f4576107f4613214565b90506020020160208101906108099190613243565b73ffffffffffffffffffffffffffffffffffffffff1614155b15610859576040517f7b2cbbb400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3089898381811061086c5761086c613214565b90506020020160208101906108819190613243565b73ffffffffffffffffffffffffffffffffffffffff16036108d95783156108d4576040517fee21708000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600191505b6109628989838181106108ee576108ee613214565b90506020020160208101906109039190613243565b8689898581811061091657610916613214565b90506020028101906109289190613265565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061174f92505050565b610998576040517fac3d341600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60010161075d565b50801580156109ad575082155b156109e4576040517f6d21730400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9bf80546fffffffffffffffffffffffffffffffff808216600101167fffffffffffffffffffffffffffffffff00000000000000000000000000000000909116179055610a6a610a538a8c6130aa565b6000604051806020016040528060008152506117ca565b50505050505050505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610b19576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b610b2161195f565b610b2e6105c885876130aa565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75415610baf576040517fa788861700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff831615610bfd576040517f871cb76100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be5b600190810180547fffffffffffffffffffffffffffffffff0000000000000000000000000000000081166fffffffffffffffffffffffffffffffff91821690930116919091179055610c74610a5385876130aa565b5050505050565b6000610c878230610e4c565b92915050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610d30576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b610d3861195f565b7fffffffff00000000000000000000000000000000000000000000000000000000821660008181527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4922602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001685151590811790915582519384529083015280517f4e6bd17989efa6d6a9607ccaac1bba27b29f99622bc830d99a3a9883b21a19c79281900390910190a15050565b600080610dfd6119ca565b805190915060005b81811015610e4457610e3085848381518110610e2357610e23613214565b6020026020010151610e4c565b15610e3c578360010193505b600101610e05565b505050919050565b60008281527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d36020818152604080842073ffffffffffffffffffffffffffffffffffffffff8616855290915282205460ff168015610ee5575060008481526020828152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152902054610100900467ffffffffffffffff1642105b949350505050565b6000610ef76119ca565b805183519192509060005b82811015610fd957610f2086858381518110610e2357610e23613214565b15610fd15760005b82811015610fcf57848281518110610f4257610f42613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16868281518110610f7257610f72613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603610fc7576040517f50f5729f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600101610f28565b505b600101610f02565b505050505050565b3360009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff161580156110205750303314155b15611057576040517f6238ee3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff9081164290911610156110fa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75460000361117d576040517f3a76e1f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080527f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be6020527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d36111d36105c883856130aa565b60006111df848461130e565b905060006111eb611af4565b6111f59042613201565b6040805180820182526001815267ffffffffffffffff838116602080840191825260008881528982528581203382529091528490209251835491517fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000009092169015157fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff16176101009190921602179055519091507f6248ff757895beed7d43d135bccf59a26b7fbdf0fe8233487c44e82c0f266ba3906112b89087908790612f54565b60405180910390a16112c86116d0565b6112d183610df2565b101580156112e357506112e382610c7b565b15610c74577f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be610c1f565b60008282604051602001611323929190612f54565b6040516020818303038152906040528051906020012030466113627f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be90565b6001015460408051602081019590955273ffffffffffffffffffffffffffffffffffffffff9093169284019290925260608301526fffffffffffffffffffffffffffffffff16608082015260a001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905280516020918201207f19457468657265756d205369676e6564204d6573736167653a0a33320000000091830191909152603c820152605c0160405160208183030381529060405280519060200120905092915050565b805160005b818110156115ae57600083828151811061145657611456613214565b602002602001015160200151600281111561147357611473612e8a565b14806114ad5750600183828151811061148e5761148e613214565b60200260200101516020015160028111156114ab576114ab612e8a565b145b156115a657600254835173ffffffffffffffffffffffffffffffffffffffff9091169063df871f72908590849081106114e8576114e8613214565b60200260200101516000015185848151811061150657611506613214565b6020026020010151604001516040518363ffffffff1660e01b815260040161152f92919061331c565b602060405180830381865afa15801561154c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611570919061334b565b6115a6576040517ff41a931c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60010161143a565b505050565b80516000908082036115f1576040517f3aee2eec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b6115ff600183613368565b8110156116c6576000611613826001613201565b90505b828110156116bd5784818151811061163057611630613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1685838151811061166057611660613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16036116b5576040517f8dd19e7d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600101611616565b506001016115f4565b5060009392505050565b600080611723600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75490565b905080156117465761173660028261337b565b611741906001613201565b611749565b60005b91505090565b600080600061175e8585611bf6565b9092509050600081600481111561177757611777612e8a565b1480156117af57508573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b806117c057506117c0868686611c3b565b9695505050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921547f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff8116908190600090600716156118395750600381901c60009081526001840160205260409020545b60005b87518110156118b6576118a983838a848151811061185c5761185c613214565b6020026020010151600001518b858151811061187a5761187a613214565b6020026020010151602001518c868151811061189857611898613214565b602002602001015160400151611d98565b909350915060010161183c565b508282146118ef576002840180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff84161790555b600782161561191157600382901c600090815260018501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb67387878760405161194493929190613424565b60405180910390a16119568686612829565b50505050505050565b3330146119c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4c69624469616d6f6e643a2043616c6c6572206e6f742073656c6600000000006044820152606401610360565b565b60008080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b780546060929067ffffffffffffffff811115611a3257611a32612d07565b604051908082528060200260200182016040528015611a5b578160200160208202803683370190505b50825490915060005b81811015611aeb57836000018181548110611a8157611a81613214565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16838281518110611abe57611abe613214565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101611a64565b50909392505050565b6040517f52430c8d0000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906352430c8d90602401602060405180830381865afa158015611b81573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ba59190613510565b6fffffffffffffffffffffffffffffffff16905060008111611bf3576040517fdac5ec8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b90565b6000808251604103611c2c5760208301516040840151606085015160001a611c2087828585612928565b94509450505050611c34565b506000905060025b9250929050565b60008060008573ffffffffffffffffffffffffffffffffffffffff16631626ba7e60e01b8686604051602401611c72929190613542565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909416939093179092529051611cfb919061355b565b600060405180830381855afa9150503d8060008114611d36576040519150601f19603f3d011682016040523d82523d6000602084013e611d3b565b606091505b5091509150818015611d4f57506020815110155b80156117c0575080517f1626ba7e0000000000000000000000000000000000000000000000000000000090611d8d9083016020908101908401613577565b149695505050505050565b600080807f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f90506000845111611e50576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610360565b6000856002811115611e6457611e64612e8a565b0361203457611e8b8660405180606001604052806024815260200161365760249139612a17565b60005b845181101561202e576000858281518110611eab57611eab613214565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c15611f7e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c72656164792065786973747300000000000000000000006064820152608401610360565b7fffffffff0000000000000000000000000000000000000000000000000000000080831660008181526020879052604090207fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608d901b168e17905560e060058e901b811692831c199c909c1690821c179a8190036120125760038c901c600090815260018601602052604081209b909b555b8b61201c81613590565b9c505060019093019250611e8e915050565b5061281d565b600185600281111561204857612048612e8a565b036123385761206f866040518060600160405280602881526020016136a360289139612a17565b60005b845181101561202e57600085828151811061208f5761208f613214565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c308103612164576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4c69624469616d6f6e644375743a2043616e2774207265706c61636520696d6d60448201527f757461626c652066756e6374696f6e00000000000000000000000000000000006064820152608401610360565b8973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361221f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e00000000000000006064820152608401610360565b73ffffffffffffffffffffffffffffffffffffffff81166122c2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e207468617420646f65736e277420657869737400000000000000006064820152608401610360565b507fffffffff0000000000000000000000000000000000000000000000000000000090911660009081526020849052604090206bffffffffffffffffffffffff919091167fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608a901b16179055600101612072565b600285600281111561234c5761234c612e8a565b036127955773ffffffffffffffffffffffffffffffffffffffff8616156123f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d7573742062652061646472657373283029000000000000000000006064820152608401610360565b600388901c6007891660005b86518110156127755760008a900361243d578261241d816135c8565b60008181526001870160205260409020549b5093506007925061244b9050565b81612447816135c8565b9250505b6000806000808a858151811061246357612463613214565b6020908102919091018101517fffffffff0000000000000000000000000000000000000000000000000000000081166000908152918a9052604090912054909150606081901c612535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608401610360565b30606082901c036125c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e0000000000000000000000000000000000006064820152608401610360565b600587901b8f901b94507fffffffff0000000000000000000000000000000000000000000000000000000080861690831614612666577fffffffff000000000000000000000000000000000000000000000000000000008516600090815260208a90526040902080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff83161790555b7fffffffff0000000000000000000000000000000000000000000000000000000091909116600090815260208990526040812055600381901c611fff16925060051b60e01690508582146126fb576000828152600188016020526040902080547fffffffff0000000000000000000000000000000000000000000000000000000080841c19909116908516831c17905561274c565b80837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c817fffffffff0000000000000000000000000000000000000000000000000000000060001b901c198e16179c505b8460000361276a57600086815260018801602052604081208190559c505b505050600101612401565b50806127828360086135fd565b61278c9190613201565b9950505061281d565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560448201527f74416374696f6e000000000000000000000000000000000000000000000000006064820152608401610360565b50959694955050505050565b73ffffffffffffffffffffffffffffffffffffffff8216612848575050565b61286a8260405180606001604052806028815260200161367b60289139612a17565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051612892919061355b565b600060405180830381855af49150503d80600081146128cd576040519150601f19603f3d011682016040523d82523d6000602084013e6128d2565b606091505b509150915081612922578051156128ec5780518082602001fd5b83836040517f192105d7000000000000000000000000000000000000000000000000000000008152600401610360929190613614565b50505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561295f5750600090506003612a0e565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156129b3573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116612a0757600060019250925050612a0e565b9150600090505b94509492505050565b813b8181612922576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103609190613643565b60008083601f840112612a6457600080fd5b50813567ffffffffffffffff811115612a7c57600080fd5b6020830191508360208260051b8501011115611c3457600080fd5b60008060208385031215612aaa57600080fd5b823567ffffffffffffffff811115612ac157600080fd5b612acd85828601612a52565b90969095509350505050565b60008060008060008060608789031215612af257600080fd5b863567ffffffffffffffff80821115612b0a57600080fd5b612b168a838b01612a52565b90985096506020890135915080821115612b2f57600080fd5b612b3b8a838b01612a52565b90965094506040890135915080821115612b5457600080fd5b50612b6189828a01612a52565b979a9699509497509295939492505050565b803573ffffffffffffffffffffffffffffffffffffffff81168114612b9757600080fd5b919050565b600080600080600060608688031215612bb457600080fd5b853567ffffffffffffffff80821115612bcc57600080fd5b612bd889838a01612a52565b9097509550859150612bec60208901612b73565b94506040880135915080821115612c0257600080fd5b818801915088601f830112612c1657600080fd5b813581811115612c2557600080fd5b896020828501011115612c3757600080fd5b9699959850939650602001949392505050565b600060208284031215612c5c57600080fd5b5035919050565b80357fffffffff0000000000000000000000000000000000000000000000000000000081168114612b9757600080fd5b8015158114612ca157600080fd5b50565b60008060408385031215612cb757600080fd5b612cc083612c63565b91506020830135612cd081612c93565b809150509250929050565b60008060408385031215612cee57600080fd5b82359150612cfe60208401612b73565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff81118282101715612d5957612d59612d07565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715612da657612da6612d07565b604052919050565b600067ffffffffffffffff821115612dc857612dc8612d07565b5060051b60200190565b60008060408385031215612de557600080fd5b8235915060208084013567ffffffffffffffff811115612e0457600080fd5b8401601f81018613612e1557600080fd5b8035612e28612e2382612dae565b612d5f565b81815260059190911b82018301908381019088831115612e4757600080fd5b928401925b82841015612e6c57612e5d84612b73565b82529284019290840190612e4c565b80955050505050509250929050565b803560038110612b9757600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60038110612ef0577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b8183526000602080850194508260005b85811015612f49577fffffffff00000000000000000000000000000000000000000000000000000000612f3683612c63565b1687529582019590820190600101612f04565b509495945050505050565b60208082528181018390526000906040808401600586811b8601830188865b8981101561309b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc089840301855281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa18c3603018112612fd457600080fd5b8b01606073ffffffffffffffffffffffffffffffffffffffff612ff683612b73565b168552613004898301612e7b565b6130108a870182612eb9565b50878201357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe183360301811261304557600080fd5b90910188810191903567ffffffffffffffff81111561306357600080fd5b80871b360383131561307457600080fd5b81898701526130868287018285612ef4565b978a0197955050509187019150600101612f73565b50909998505050505050505050565b60006130b8612e2384612dae565b83815260208082019190600586811b8601368111156130d657600080fd5b865b818110156131c557803567ffffffffffffffff808211156130f95760008081fd5b818a0191506060823603121561310f5760008081fd5b613117612d36565b61312083612b73565b815261312d878401612e7b565b87820152604080840135838111156131455760008081fd5b939093019236601f85011261315c57600092508283fd5b8335925061316c612e2384612dae565b83815292871b840188019288810190368511156131895760008081fd5b948901945b848610156131ae5761319f86612c63565b8252948901949089019061318e565b9183019190915250885250509483019483016130d8565b5092979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610c8757610c876131d2565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561325557600080fd5b61325e82612b73565b9392505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261329a57600080fd5b83018035915067ffffffffffffffff8211156132b557600080fd5b602001915036819003821315611c3457600080fd5b600081518084526020808501945080840160005b83811015612f495781517fffffffff0000000000000000000000000000000000000000000000000000000016875295820195908201906001016132de565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000610ee560408301846132ca565b60006020828403121561335d57600080fd5b815161325e81612c93565b81810381811115610c8757610c876131d2565b6000826133b1577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60005b838110156133d15781810151838201526020016133b9565b50506000910152565b600081518084526133f28160208601602086016133b6565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6000606080830181845280875180835260808601915060808160051b87010192506020808a0160005b838110156134d4577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80898703018552815173ffffffffffffffffffffffffffffffffffffffff8151168752838101516134a885890182612eb9565b506040908101519087018890526134c1878901826132ca565b965050938201939082019060010161344d565b505073ffffffffffffffffffffffffffffffffffffffff8916908701525050838103604085015261350581866133da565b979650505050505050565b60006020828403121561352257600080fd5b81516fffffffffffffffffffffffffffffffff8116811461325e57600080fd5b828152604060208201526000610ee560408301846133da565b6000825161356d8184602087016133b6565b9190910192915050565b60006020828403121561358957600080fd5b5051919050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036135c1576135c16131d2565b5060010190565b6000816135d7576135d76131d2565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b8082028115828204841417610c8757610c876131d2565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000610ee560408301846133da565b60208152600061325e60208301846133da56fe4c69624469616d6f6e644375743a2041646420666163657420686173206e6f20636f64654c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a205265706c61636520666163657420686173206e6f20636f6465a2646970667358221220c5a8c10b22f20cde3fe0431ff57305237423677a60888f5b349fc6751336ae1464736f6c63430008150033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100d45760003560e01c806379c0d58d11610081578063afb877bb1161005b578063afb877bb146101d9578063de675a6d146101ec578063e33ecf0a1461023857600080fd5b806379c0d58d14610192578063836d6bfb146101b35780638824a0bb146101c657600080fd5b806326fc3ef4116100b257806326fc3ef4146101145780632f4d98ea1461015c5780633c0985681461017f57600080fd5b806313c34f4b146100d95780631c776dd5146100ee5780631f931c1c14610101575b600080fd5b6100ec6100e7366004612a97565b61024b565b005b6100ec6100fc366004612ad9565b6104df565b6100ec61010f366004612b9c565b610a76565b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9bf546040516fffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b61016f61016a366004612c4a565b610c7b565b6040519015158152602001610153565b6100ec61018d366004612ca4565b610c8d565b6101a56101a0366004612c4a565b610df2565b604051908152602001610153565b61016f6101c1366004612cdb565b610e4c565b6100ec6101d4366004612dd2565b610eed565b6100ec6101e7366004612a97565b610fe1565b6102137f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610153565b6101a5610246366004612a97565b61130e565b3360009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff1615801561028a5750303314155b156102c1576040517f6238ee3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610369576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b656400000000000000000000000000000000000060448201526064015b60405180910390fd5b60008080527f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be6020527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d3906103be848461130e565b60008181526020848152604080832033845290915290205490915060ff16610412576040517fedc5708300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051808201825260008082526020808301828152858352868252848320338452909152908390209151825491517fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000009092169015157fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff161761010067ffffffffffffffff90921691909102179055517f3c3d8c1f0b0faff6fe0ace6b485d0595a0106dce9e303f956fd941ebdbe9a98e906104d19086908690612f54565b60405180910390a150505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610582576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b8281146105bb576040517fe854148500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6105cd6105c886886130aa565b611435565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b754600003610650576040517fa788861700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061065c878761130e565b905061069a8585808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506115b392505050565b506106d881868680806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250610eed92505050565b60006106e382610c7b565b90506000816106f35760016106f6565b60005b60ff169050806107046116d0565b61070e9190613201565b61071784610df2565b6107219088613201565b1015610759576040517f709fb08000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805b878110156109a0576107d989898381811061077a5761077a613214565b905060200201602081019061078f9190613243565b73ffffffffffffffffffffffffffffffffffffffff1660009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff1690565b1580156108225750308989838181106107f4576107f4613214565b90506020020160208101906108099190613243565b73ffffffffffffffffffffffffffffffffffffffff1614155b15610859576040517f7b2cbbb400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3089898381811061086c5761086c613214565b90506020020160208101906108819190613243565b73ffffffffffffffffffffffffffffffffffffffff16036108d95783156108d4576040517fee21708000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600191505b6109628989838181106108ee576108ee613214565b90506020020160208101906109039190613243565b8689898581811061091657610916613214565b90506020028101906109289190613265565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061174f92505050565b610998576040517fac3d341600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60010161075d565b50801580156109ad575082155b156109e4576040517f6d21730400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9bf80546fffffffffffffffffffffffffffffffff808216600101167fffffffffffffffffffffffffffffffff00000000000000000000000000000000909116179055610a6a610a538a8c6130aa565b6000604051806020016040528060008152506117ca565b50505050505050505050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610b19576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b610b2161195f565b610b2e6105c885876130aa565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75415610baf576040517fa788861700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff831615610bfd576040517f871cb76100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be5b600190810180547fffffffffffffffffffffffffffffffff0000000000000000000000000000000081166fffffffffffffffffffffffffffffffff91821690930116919091179055610c74610a5385876130aa565b5050505050565b6000610c878230610e4c565b92915050565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff908116429091161015610d30576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b610d3861195f565b7fffffffff00000000000000000000000000000000000000000000000000000000821660008181527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4922602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001685151590811790915582519384529083015280517f4e6bd17989efa6d6a9607ccaac1bba27b29f99622bc830d99a3a9883b21a19c79281900390910190a15050565b600080610dfd6119ca565b805190915060005b81811015610e4457610e3085848381518110610e2357610e23613214565b6020026020010151610e4c565b15610e3c578360010193505b600101610e05565b505050919050565b60008281527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d36020818152604080842073ffffffffffffffffffffffffffffffffffffffff8616855290915282205460ff168015610ee5575060008481526020828152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152902054610100900467ffffffffffffffff1642105b949350505050565b6000610ef76119ca565b805183519192509060005b82811015610fd957610f2086858381518110610e2357610e23613214565b15610fd15760005b82811015610fcf57848281518110610f4257610f42613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16868281518110610f7257610f72613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603610fc7576040517f50f5729f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600101610f28565b505b600101610f02565b505050505050565b3360009081527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b8602052604090205460ff161580156110205750303314155b15611057576040517f6238ee3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5467ffffffffffffffff9081164290911610156110fa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4163636f756e74204c6f636b65640000000000000000000000000000000000006044820152606401610360565b600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75460000361117d576040517f3a76e1f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080527f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be6020527f653b0501de88979dae3f7a0c0d7d06b6188ed90f72b20793f210fd368861e5d36111d36105c883856130aa565b60006111df848461130e565b905060006111eb611af4565b6111f59042613201565b6040805180820182526001815267ffffffffffffffff838116602080840191825260008881528982528581203382529091528490209251835491517fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000009092169015157fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff16176101009190921602179055519091507f6248ff757895beed7d43d135bccf59a26b7fbdf0fe8233487c44e82c0f266ba3906112b89087908790612f54565b60405180910390a16112c86116d0565b6112d183610df2565b101580156112e357506112e382610c7b565b15610c74577f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be610c1f565b60008282604051602001611323929190612f54565b6040516020818303038152906040528051906020012030466113627f19a78b668040d166f9eab1e050eacb85cec34faf6ccf7ddbc201b33f8bb1f9be90565b6001015460408051602081019590955273ffffffffffffffffffffffffffffffffffffffff9093169284019290925260608301526fffffffffffffffffffffffffffffffff16608082015260a001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905280516020918201207f19457468657265756d205369676e6564204d6573736167653a0a33320000000091830191909152603c820152605c0160405160208183030381529060405280519060200120905092915050565b805160005b818110156115ae57600083828151811061145657611456613214565b602002602001015160200151600281111561147357611473612e8a565b14806114ad5750600183828151811061148e5761148e613214565b60200260200101516020015160028111156114ab576114ab612e8a565b145b156115a657600254835173ffffffffffffffffffffffffffffffffffffffff9091169063df871f72908590849081106114e8576114e8613214565b60200260200101516000015185848151811061150657611506613214565b6020026020010151604001516040518363ffffffff1660e01b815260040161152f92919061331c565b602060405180830381865afa15801561154c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611570919061334b565b6115a6576040517ff41a931c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60010161143a565b505050565b80516000908082036115f1576040517f3aee2eec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b6115ff600183613368565b8110156116c6576000611613826001613201565b90505b828110156116bd5784818151811061163057611630613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1685838151811061166057611660613214565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16036116b5576040517f8dd19e7d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600101611616565b506001016115f4565b5060009392505050565b600080611723600080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b75490565b905080156117465761173660028261337b565b611741906001613201565b611749565b60005b91505090565b600080600061175e8585611bf6565b9092509050600081600481111561177757611777612e8a565b1480156117af57508573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b806117c057506117c0868686611c3b565b9695505050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921547f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff8116908190600090600716156118395750600381901c60009081526001840160205260409020545b60005b87518110156118b6576118a983838a848151811061185c5761185c613214565b6020026020010151600001518b858151811061187a5761187a613214565b6020026020010151602001518c868151811061189857611898613214565b602002602001015160400151611d98565b909350915060010161183c565b508282146118ef576002840180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff84161790555b600782161561191157600382901c600090815260018501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb67387878760405161194493929190613424565b60405180910390a16119568686612829565b50505050505050565b3330146119c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4c69624469616d6f6e643a2043616c6c6572206e6f742073656c6600000000006044820152606401610360565b565b60008080527fec37c9d3f62cbc43363a007dfdea31702a2aae2ada4d4d880588e00ded24d6086020527f9d17c72553b2484e633bd2ba080be8cdbe1716b54e87f338837ad775aee316b780546060929067ffffffffffffffff811115611a3257611a32612d07565b604051908082528060200260200182016040528015611a5b578160200160208202803683370190505b50825490915060005b81811015611aeb57836000018181548110611a8157611a81613214565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16838281518110611abe57611abe613214565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101611a64565b50909392505050565b6040517f52430c8d0000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906352430c8d90602401602060405180830381865afa158015611b81573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ba59190613510565b6fffffffffffffffffffffffffffffffff16905060008111611bf3576040517fdac5ec8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b90565b6000808251604103611c2c5760208301516040840151606085015160001a611c2087828585612928565b94509450505050611c34565b506000905060025b9250929050565b60008060008573ffffffffffffffffffffffffffffffffffffffff16631626ba7e60e01b8686604051602401611c72929190613542565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909416939093179092529051611cfb919061355b565b600060405180830381855afa9150503d8060008114611d36576040519150601f19603f3d011682016040523d82523d6000602084013e611d3b565b606091505b5091509150818015611d4f57506020815110155b80156117c0575080517f1626ba7e0000000000000000000000000000000000000000000000000000000090611d8d9083016020908101908401613577565b149695505050505050565b600080807f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f90506000845111611e50576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610360565b6000856002811115611e6457611e64612e8a565b0361203457611e8b8660405180606001604052806024815260200161365760249139612a17565b60005b845181101561202e576000858281518110611eab57611eab613214565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c15611f7e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c72656164792065786973747300000000000000000000006064820152608401610360565b7fffffffff0000000000000000000000000000000000000000000000000000000080831660008181526020879052604090207fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608d901b168e17905560e060058e901b811692831c199c909c1690821c179a8190036120125760038c901c600090815260018601602052604081209b909b555b8b61201c81613590565b9c505060019093019250611e8e915050565b5061281d565b600185600281111561204857612048612e8a565b036123385761206f866040518060600160405280602881526020016136a360289139612a17565b60005b845181101561202e57600085828151811061208f5761208f613214565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291859052604090912054909150606081901c308103612164576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4c69624469616d6f6e644375743a2043616e2774207265706c61636520696d6d60448201527f757461626c652066756e6374696f6e00000000000000000000000000000000006064820152608401610360565b8973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361221f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e00000000000000006064820152608401610360565b73ffffffffffffffffffffffffffffffffffffffff81166122c2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e207468617420646f65736e277420657869737400000000000000006064820152608401610360565b507fffffffff0000000000000000000000000000000000000000000000000000000090911660009081526020849052604090206bffffffffffffffffffffffff919091167fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608a901b16179055600101612072565b600285600281111561234c5761234c612e8a565b036127955773ffffffffffffffffffffffffffffffffffffffff8616156123f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d7573742062652061646472657373283029000000000000000000006064820152608401610360565b600388901c6007891660005b86518110156127755760008a900361243d578261241d816135c8565b60008181526001870160205260409020549b5093506007925061244b9050565b81612447816135c8565b9250505b6000806000808a858151811061246357612463613214565b6020908102919091018101517fffffffff0000000000000000000000000000000000000000000000000000000081166000908152918a9052604090912054909150606081901c612535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608401610360565b30606082901c036125c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e0000000000000000000000000000000000006064820152608401610360565b600587901b8f901b94507fffffffff0000000000000000000000000000000000000000000000000000000080861690831614612666577fffffffff000000000000000000000000000000000000000000000000000000008516600090815260208a90526040902080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff83161790555b7fffffffff0000000000000000000000000000000000000000000000000000000091909116600090815260208990526040812055600381901c611fff16925060051b60e01690508582146126fb576000828152600188016020526040902080547fffffffff0000000000000000000000000000000000000000000000000000000080841c19909116908516831c17905561274c565b80837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c817fffffffff0000000000000000000000000000000000000000000000000000000060001b901c198e16179c505b8460000361276a57600086815260018801602052604081208190559c505b505050600101612401565b50806127828360086135fd565b61278c9190613201565b9950505061281d565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560448201527f74416374696f6e000000000000000000000000000000000000000000000000006064820152608401610360565b50959694955050505050565b73ffffffffffffffffffffffffffffffffffffffff8216612848575050565b61286a8260405180606001604052806028815260200161367b60289139612a17565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051612892919061355b565b600060405180830381855af49150503d80600081146128cd576040519150601f19603f3d011682016040523d82523d6000602084013e6128d2565b606091505b509150915081612922578051156128ec5780518082602001fd5b83836040517f192105d7000000000000000000000000000000000000000000000000000000008152600401610360929190613614565b50505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561295f5750600090506003612a0e565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156129b3573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116612a0757600060019250925050612a0e565b9150600090505b94509492505050565b813b8181612922576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103609190613643565b60008083601f840112612a6457600080fd5b50813567ffffffffffffffff811115612a7c57600080fd5b6020830191508360208260051b8501011115611c3457600080fd5b60008060208385031215612aaa57600080fd5b823567ffffffffffffffff811115612ac157600080fd5b612acd85828601612a52565b90969095509350505050565b60008060008060008060608789031215612af257600080fd5b863567ffffffffffffffff80821115612b0a57600080fd5b612b168a838b01612a52565b90985096506020890135915080821115612b2f57600080fd5b612b3b8a838b01612a52565b90965094506040890135915080821115612b5457600080fd5b50612b6189828a01612a52565b979a9699509497509295939492505050565b803573ffffffffffffffffffffffffffffffffffffffff81168114612b9757600080fd5b919050565b600080600080600060608688031215612bb457600080fd5b853567ffffffffffffffff80821115612bcc57600080fd5b612bd889838a01612a52565b9097509550859150612bec60208901612b73565b94506040880135915080821115612c0257600080fd5b818801915088601f830112612c1657600080fd5b813581811115612c2557600080fd5b896020828501011115612c3757600080fd5b9699959850939650602001949392505050565b600060208284031215612c5c57600080fd5b5035919050565b80357fffffffff0000000000000000000000000000000000000000000000000000000081168114612b9757600080fd5b8015158114612ca157600080fd5b50565b60008060408385031215612cb757600080fd5b612cc083612c63565b91506020830135612cd081612c93565b809150509250929050565b60008060408385031215612cee57600080fd5b82359150612cfe60208401612b73565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff81118282101715612d5957612d59612d07565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715612da657612da6612d07565b604052919050565b600067ffffffffffffffff821115612dc857612dc8612d07565b5060051b60200190565b60008060408385031215612de557600080fd5b8235915060208084013567ffffffffffffffff811115612e0457600080fd5b8401601f81018613612e1557600080fd5b8035612e28612e2382612dae565b612d5f565b81815260059190911b82018301908381019088831115612e4757600080fd5b928401925b82841015612e6c57612e5d84612b73565b82529284019290840190612e4c565b80955050505050509250929050565b803560038110612b9757600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60038110612ef0577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b8183526000602080850194508260005b85811015612f49577fffffffff00000000000000000000000000000000000000000000000000000000612f3683612c63565b1687529582019590820190600101612f04565b509495945050505050565b60208082528181018390526000906040808401600586811b8601830188865b8981101561309b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc089840301855281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa18c3603018112612fd457600080fd5b8b01606073ffffffffffffffffffffffffffffffffffffffff612ff683612b73565b168552613004898301612e7b565b6130108a870182612eb9565b50878201357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe183360301811261304557600080fd5b90910188810191903567ffffffffffffffff81111561306357600080fd5b80871b360383131561307457600080fd5b81898701526130868287018285612ef4565b978a0197955050509187019150600101612f73565b50909998505050505050505050565b60006130b8612e2384612dae565b83815260208082019190600586811b8601368111156130d657600080fd5b865b818110156131c557803567ffffffffffffffff808211156130f95760008081fd5b818a0191506060823603121561310f5760008081fd5b613117612d36565b61312083612b73565b815261312d878401612e7b565b87820152604080840135838111156131455760008081fd5b939093019236601f85011261315c57600092508283fd5b8335925061316c612e2384612dae565b83815292871b840188019288810190368511156131895760008081fd5b948901945b848610156131ae5761319f86612c63565b8252948901949089019061318e565b9183019190915250885250509483019483016130d8565b5092979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610c8757610c876131d2565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561325557600080fd5b61325e82612b73565b9392505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261329a57600080fd5b83018035915067ffffffffffffffff8211156132b557600080fd5b602001915036819003821315611c3457600080fd5b600081518084526020808501945080840160005b83811015612f495781517fffffffff0000000000000000000000000000000000000000000000000000000016875295820195908201906001016132de565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000610ee560408301846132ca565b60006020828403121561335d57600080fd5b815161325e81612c93565b81810381811115610c8757610c876131d2565b6000826133b1577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60005b838110156133d15781810151838201526020016133b9565b50506000910152565b600081518084526133f28160208601602086016133b6565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6000606080830181845280875180835260808601915060808160051b87010192506020808a0160005b838110156134d4577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80898703018552815173ffffffffffffffffffffffffffffffffffffffff8151168752838101516134a885890182612eb9565b506040908101519087018890526134c1878901826132ca565b965050938201939082019060010161344d565b505073ffffffffffffffffffffffffffffffffffffffff8916908701525050838103604085015261350581866133da565b979650505050505050565b60006020828403121561352257600080fd5b81516fffffffffffffffffffffffffffffffff8116811461325e57600080fd5b828152604060208201526000610ee560408301846133da565b6000825161356d8184602087016133b6565b9190910192915050565b60006020828403121561358957600080fd5b5051919050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036135c1576135c16131d2565b5060010190565b6000816135d7576135d76131d2565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b8082028115828204841417610c8757610c876131d2565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000610ee560408301846133da565b60208152600061325e60208301846133da56fe4c69624469616d6f6e644375743a2041646420666163657420686173206e6f20636f64654c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a205265706c61636520666163657420686173206e6f20636f6465a2646970667358221220c5a8c10b22f20cde3fe0431ff57305237423677a60888f5b349fc6751336ae1464736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "Responsible for adding/removing/replace facets in Barz", + "kind": "dev", + "methods": { + "_checkDuplicateOnChainApprover(bytes32,address[])": { + "params": { + "_approvers": "List of approver addresses", + "_diamondCutHash": "Hash of diamondCut information including the facet addresses and function selectors" + } + }, + "approveDiamondCut((address,uint8,bytes4[])[])": { + "params": { + "_diamondCut": "Contains the facet addresses and function selectors" + } + }, + "constructor": { + "params": { + "_securityManager": "Security Manager contract that holds the security related variables for all wallets" + } + }, + "diamondCut((address,uint8,bytes4[])[],address,bytes)": { + "params": { + "_diamondCut": "Contains the facet addresses and function selectors", + "_init": "The address of the contract or facet to execute _calldata. It's prohibited in Barz" + } + }, + "diamondCutWithGuardian((address,uint8,bytes4[])[],address[],bytes[])": { + "params": { + "_approvers": "Guardian or owner address that approves the diamond cut", + "_diamondCut": "Contains the facet addresses and function selectors", + "_signatures": "Signature of Guardians or owner that approves the diamond cut" + } + }, + "getDiamondCutApprovalCountWithTimeValidity(bytes32)": { + "params": { + "_diamondCutHash": "Hash of diamondCut information including the facet addresses and function selectors" + } + }, + "getDiamondCutHash((address,uint8,bytes4[])[])": { + "params": { + "_diamondCut": "Contains the facet addresses and function selectors" + }, + "returns": { + "cutHash": "Diamond Cut Hash" + } + }, + "getDiamondCutNonce()": { + "details": "This method fetches the nonce from diamond cut storage", + "returns": { + "cutNonce": "Nonce of diamond cut to protect from reply attacks" + } + }, + "getOwnerCutApprovalWithTimeValidity(bytes32)": { + "params": { + "_diamondCutHash": "Hash of diamondCut information including the facet addresses and function selectors" + }, + "returns": { + "isApprovedByOwner": "Bool value showing if the owner approved the cut" + } + }, + "isCutApproved(bytes32,address)": { + "params": { + "_approver": "Address of approver", + "_diamondCutHash": "Hash of diamondCut information including the facet addresses and function selectors" + }, + "returns": { + "isApproved": "Bool value showing if the approver approved the cut" + } + }, + "revokeDiamondCutApproval((address,uint8,bytes4[])[])": { + "params": { + "_diamondCut": "Contains the facet addresses and function selectors" + } + }, + "updateSupportsInterface(bytes4,bool)": { + "params": { + "_flag": "Bool value to update the mapping of the given interface ID", + "_interfaceId": "InterfaceID to update the mapping" + } + } + }, + "title": "DiamondCut Facet", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "_checkDuplicateOnChainApprover(bytes32,address[])": { + "notice": "Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval Approvers who approved on-chain should not be included in the off-chain approval" + }, + "approveDiamondCut((address,uint8,bytes4[])[])": { + "notice": "Approves diamond cut. This can only be called directly from guardian or owner" + }, + "constructor": { + "notice": "This constructor sets the Security Manager address which is an immutable variable. Immutable variables do not impact the storage of diamond" + }, + "diamondCut((address,uint8,bytes4[])[],address,bytes)": { + "notice": "Add/replace/remove any number of functions and optionally execute a function with delegatecall when guardians don't exist" + }, + "diamondCutWithGuardian((address,uint8,bytes4[])[],address[],bytes[])": { + "notice": "Add/replace/remove any number of functions and optionally execute a function with delegatecall when guardians exist" + }, + "getDiamondCutApprovalCountWithTimeValidity(bytes32)": { + "notice": "Gets the number of approvals of diamond cut from guardians" + }, + "getDiamondCutHash((address,uint8,bytes4[])[])": { + "notice": "Returns the diamond cut hash. This function ensures that this hash is safe from replay attack by including salt, address, chainId, and nonce, etc." + }, + "getDiamondCutNonce()": { + "notice": "Returns the diamond cut nonce of this wallet" + }, + "getOwnerCutApprovalWithTimeValidity(bytes32)": { + "notice": "Returns if the owner has approved the diamond cut" + }, + "isCutApproved(bytes32,address)": { + "notice": "Returns if the given approver has approved the diamond cut" + }, + "revokeDiamondCutApproval((address,uint8,bytes4[])[])": { + "notice": "Revokes the approval of diamond cut. This can only be called directly from guardian or owner" + }, + "updateSupportsInterface(bytes4,bool)": { + "notice": "Updates the flag for the interfaceId" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 27823, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "s", + "offset": 0, + "slot": "0", + "type": "t_struct(AppStorage)27570_storage" + } + ], + "types": { + "t_bytes4": { + "encoding": "inplace", + "label": "bytes4", + "numberOfBytes": "4" + }, + "t_contract(IEntryPoint)12286": { + "encoding": "inplace", + "label": "contract IEntryPoint", + "numberOfBytes": "20" + }, + "t_contract(IFacetRegistry)26105": { + "encoding": "inplace", + "label": "contract IFacetRegistry", + "numberOfBytes": "20" + }, + "t_mapping(t_uint256,t_struct(InitializersStorage)27549_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => struct InitializersStorage)", + "numberOfBytes": "32", + "value": "t_struct(InitializersStorage)27549_storage" + }, + "t_mapping(t_uint256,t_struct(Lock)27542_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => struct Lock)", + "numberOfBytes": "32", + "value": "t_struct(Lock)27542_storage" + }, + "t_struct(AppStorage)27570_storage": { + "encoding": "inplace", + "label": "struct AppStorage", + "members": [ + { + "astId": 27554, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "initStorage", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_uint256,t_struct(InitializersStorage)27549_storage)" + }, + { + "astId": 27556, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "signerMigration", + "offset": 0, + "slot": "1", + "type": "t_uint8" + }, + { + "astId": 27558, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "validateOwnerSignatureSelector", + "offset": 1, + "slot": "1", + "type": "t_bytes4" + }, + { + "astId": 27561, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "entryPoint", + "offset": 5, + "slot": "1", + "type": "t_contract(IEntryPoint)12286" + }, + { + "astId": 27564, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "facetRegistry", + "offset": 0, + "slot": "2", + "type": "t_contract(IFacetRegistry)26105" + }, + { + "astId": 27569, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "locks", + "offset": 0, + "slot": "3", + "type": "t_mapping(t_uint256,t_struct(Lock)27542_storage)" + } + ], + "numberOfBytes": "128" + }, + "t_struct(InitializersStorage)27549_storage": { + "encoding": "inplace", + "label": "struct InitializersStorage", + "members": [ + { + "astId": 27544, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "signerInitialized", + "offset": 0, + "slot": "0", + "type": "t_uint8" + }, + { + "astId": 27546, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "accountInitialized", + "offset": 1, + "slot": "0", + "type": "t_uint8" + }, + { + "astId": 27548, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "restrictionsInitialized", + "offset": 2, + "slot": "0", + "type": "t_uint8" + } + ], + "numberOfBytes": "32" + }, + "t_struct(Lock)27542_storage": { + "encoding": "inplace", + "label": "struct Lock", + "members": [ + { + "astId": 27539, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "release", + "offset": 0, + "slot": "0", + "type": "t_uint64" + }, + { + "astId": 27541, + "contract": "contracts/facets/base/DiamondCutFacet.sol:DiamondCutFacet", + "label": "locker", + "offset": 8, + "slot": "0", + "type": "t_bytes4" + } + ], + "numberOfBytes": "32" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint64": { + "encoding": "inplace", + "label": "uint64", + "numberOfBytes": "8" + }, + "t_uint8": { + "encoding": "inplace", + "label": "uint8", + "numberOfBytes": "1" + } + } + } +} \ No newline at end of file diff --git a/deployments/polygon/DiamondLoupeFacet.json b/deployments/polygon/DiamondLoupeFacet.json new file mode 100644 index 0000000..2507737 --- /dev/null +++ b/deployments/polygon/DiamondLoupeFacet.json @@ -0,0 +1,290 @@ +{ + "address": "0xCe36b85d12D81cd619C745c7717f3396E184Ac7C", + "abi": [ + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_functionSelector", + "type": "bytes4" + } + ], + "name": "facetAddress", + "outputs": [ + { + "internalType": "address", + "name": "facetAddress_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_functionSelector", + "type": "bytes4" + } + ], + "name": "facetAddressFromStorage", + "outputs": [ + { + "internalType": "address", + "name": "facetAddress_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetAddresses", + "outputs": [ + { + "internalType": "address[]", + "name": "facetAddresses_", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetAddressesFromStorage", + "outputs": [ + { + "internalType": "address[]", + "name": "facetAddresses_", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_facet", + "type": "address" + } + ], + "name": "facetFunctionSelectors", + "outputs": [ + { + "internalType": "bytes4[]", + "name": "facetFunctionSelectors_", + "type": "bytes4[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_facet", + "type": "address" + } + ], + "name": "facetFunctionSelectorsFromStorage", + "outputs": [ + { + "internalType": "bytes4[]", + "name": "facetFunctionSelectors_", + "type": "bytes4[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facets", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondLoupe.Facet[]", + "name": "facets_", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetsFromStorage", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondLoupe.Facet[]", + "name": "facets_", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "isSupported", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "args": [], + "numDeployments": 3, + "solcInputHash": "4356503edd8ae34e73cb6dd1c8e2fc8a", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_functionSelector\",\"type\":\"bytes4\"}],\"name\":\"facetAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"facetAddress_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_functionSelector\",\"type\":\"bytes4\"}],\"name\":\"facetAddressFromStorage\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"facetAddress_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetAddresses\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"facetAddresses_\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetAddressesFromStorage\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"facetAddresses_\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_facet\",\"type\":\"address\"}],\"name\":\"facetFunctionSelectors\",\"outputs\":[{\"internalType\":\"bytes4[]\",\"name\":\"facetFunctionSelectors_\",\"type\":\"bytes4[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_facet\",\"type\":\"address\"}],\"name\":\"facetFunctionSelectorsFromStorage\",\"outputs\":[{\"internalType\":\"bytes4[]\",\"name\":\"facetFunctionSelectors_\",\"type\":\"bytes4[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facets\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondLoupe.Facet[]\",\"name\":\"facets_\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetsFromStorage\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondLoupe.Facet[]\",\"name\":\"facets_\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isSupported\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"DiamondLoupe contract compatible with EIP-2535\",\"kind\":\"dev\",\"methods\":{\"facetAddress(bytes4)\":{\"details\":\"If facet is not found return address(0).\",\"params\":{\"_functionSelector\":\"The function selector.\"},\"returns\":{\"facetAddress_\":\"The facet address.\"}},\"facetAddressFromStorage(bytes4)\":{\"params\":{\"_functionSelector\":\"Function selector to fetch the facet address from diamond storage\"},\"returns\":{\"facetAddress_\":\"Facet address mapped with the function selector\"}},\"facetAddresses()\":{\"returns\":{\"facetAddresses_\":\"facetAddresses_\"}},\"facetAddressesFromStorage()\":{\"returns\":{\"facetAddresses_\":\"All facet addresses attached directly to diamond storage\"}},\"facetFunctionSelectors(address)\":{\"params\":{\"_facet\":\"The facet address.\"},\"returns\":{\"facetFunctionSelectors_\":\"facetFunctionSelectors_\"}},\"facetFunctionSelectorsFromStorage(address)\":{\"params\":{\"_facet\":\"Facet address to fetch the facet function selectors from diamond storage\"},\"returns\":{\"facetFunctionSelectors_\":\"Facet function selectors of the given facet address\"}},\"facets()\":{\"details\":\"Barz uses a special architecture called default fallback handler. Default Fallback handler is used as a middleware that holds the mapping of facet function selector and facet address that Barz uses. This helps Barz to reduce significant amount of gas during the initialization process. Hence, this method aggregates both the facet information from DefaulFallbackHandler and in diamond storage and shows the data to users.\",\"returns\":{\"facets_\":\"Facet\"}},\"facetsFromStorage()\":{\"returns\":{\"facets_\":\"Facet information attached directly to diamond storage\"}},\"supportsInterface(bytes4)\":{\"params\":{\"_interfaceId\":\"Interface ID for detecting the interface\"},\"returns\":{\"isSupported\":\"Bool value showing if the standard is supported in the contract\"}}},\"title\":\"DiamondLoupe Facet\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"facetAddress(bytes4)\":{\"notice\":\"Gets the facet that supports the given selector.\"},\"facetAddressFromStorage(bytes4)\":{\"notice\":\"Returns the facet address attached to the given function selector. This excludes the facets from the default fallback handler\"},\"facetAddresses()\":{\"notice\":\"Get all the facet addresses used by Barz.\"},\"facetAddressesFromStorage()\":{\"notice\":\"Returns all facet addresses attached directly to diamond storage. This excludes the facets from the default fallback handler\"},\"facetFunctionSelectors(address)\":{\"notice\":\"Gets all the function selectors provided by a facet.\"},\"facetFunctionSelectorsFromStorage(address)\":{\"notice\":\"Returns function selectors of given facet address attached directly to diamond storage. This excludes the facets from the default fallback handler\"},\"facets()\":{\"notice\":\"Gets all facets and their selectors.\"},\"facetsFromStorage()\":{\"notice\":\"Returns the facet from the diamond storage. This excludes the facets from the default fallback handler\"},\"supportsInterface(bytes4)\":{\"notice\":\"SupportInterface to be compatible with EIP 165\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/base/DiamondLoupeFacet.sol\":\"DiamondLoupeFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/introspection/IERC165.sol\\\";\\n\\n/**\\n * @dev _Available since v3.1._\\n */\\ninterface IERC1155Receiver is IERC165 {\\n /**\\n * @dev Handles the receipt of a single ERC1155 token type. This function is\\n * called at the end of a `safeTransferFrom` after the balance has been updated.\\n *\\n * NOTE: To accept the transfer, this must return\\n * `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))`\\n * (i.e. 0xf23a6e61, or its own function selector).\\n *\\n * @param operator The address which initiated the transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param id The ID of the token being transferred\\n * @param value The amount of tokens being transferred\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155Received(\\n address operator,\\n address from,\\n uint256 id,\\n uint256 value,\\n bytes calldata data\\n ) external returns (bytes4);\\n\\n /**\\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\\n * is called at the end of a `safeBatchTransferFrom` after the balances have\\n * been updated.\\n *\\n * NOTE: To accept the transfer(s), this must return\\n * `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))`\\n * (i.e. 0xbc197c81, or its own function selector).\\n *\\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155BatchReceived(\\n address operator,\\n address from,\\n uint256[] calldata ids,\\n uint256[] calldata values,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xeb373f1fdc7b755c6a750123a9b9e3a8a02c1470042fd6505d875000a80bde0b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title ERC721 token receiver interface\\n * @dev Interface for any contract that wants to support safeTransfers\\n * from ERC721 asset contracts.\\n */\\ninterface IERC721Receiver {\\n /**\\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\\n * by `operator` from `from`, this function is called.\\n *\\n * It must return its Solidity selector to confirm the token transfer.\\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\\n *\\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\\n */\\n function onERC721Received(\\n address operator,\\n address from,\\n uint256 tokenId,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\\n *\\n * Accounts can be notified of {IERC777} tokens being sent to them by having a\\n * contract implement this interface (contract holders can be their own\\n * implementer) and registering it on the\\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\\n *\\n * See {IERC1820Registry} and {ERC1820Implementer}.\\n */\\ninterface IERC777Recipient {\\n /**\\n * @dev Called by an {IERC777} token contract whenever tokens are being\\n * moved or created into a registered account (`to`). The type of operation\\n * is conveyed by `from` being the zero address or not.\\n *\\n * This call occurs _after_ the token contract's state is updated, so\\n * {IERC777-balanceOf}, etc., can be used to query the post-operation state.\\n *\\n * This function may revert to prevent the operation from being executed.\\n */\\n function tokensReceived(\\n address operator,\\n address from,\\n address to,\\n uint256 amount,\\n bytes calldata userData,\\n bytes calldata operatorData\\n ) external;\\n}\\n\",\"keccak256\":\"0x1a5d61db2733202ba361e6d6741cd2e662380e22b80e987eacfc91973f2267dc\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"contracts/facets/base/DiamondLoupeFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IERC777Recipient} from \\\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\\\";\\nimport {IERC165} from \\\"../../interfaces/ERC/IERC165.sol\\\";\\nimport {IERC1271} from \\\"../../interfaces/ERC/IERC1271.sol\\\";\\nimport {IERC677Receiver} from \\\"../../interfaces/ERC/IERC677Receiver.sol\\\";\\nimport {IERC721Receiver} from \\\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\\\";\\nimport {IERC1155Receiver} from \\\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\\\";\\nimport {LibDiamond} from \\\"../../libraries/LibDiamond.sol\\\";\\nimport {LibLoupe} from \\\"../../libraries/LibLoupe.sol\\\";\\nimport {LibUtils} from \\\"../../libraries/LibUtils.sol\\\";\\nimport {IDiamondCut} from \\\"../../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IStorageLoupe} from \\\"./interfaces/IStorageLoupe.sol\\\";\\nimport {IDiamondLoupe} from \\\"./interfaces/IDiamondLoupe.sol\\\";\\n\\n/**\\n * @title DiamondLoupe Facet\\n * @dev DiamondLoupe contract compatible with EIP-2535\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract DiamondLoupeFacet is IDiamondLoupe, IStorageLoupe, IERC165 {\\n // Diamond Loupe Functions\\n ////////////////////////////////////////////////////////////////////\\n /// These functions are expected to be called frequently by tools off-chain.\\n\\n /**\\n * @notice Gets all facets and their selectors.\\n * @dev Barz uses a special architecture called default fallback handler. Default Fallback handler is used as a middleware\\n * that holds the mapping of facet function selector and facet address that Barz uses. This helps Barz to reduce\\n * significant amount of gas during the initialization process.\\n * Hence, this method aggregates both the facet information from DefaulFallbackHandler and in diamond storage and shows the data to users.\\n * @return facets_ Facet\\n */\\n function facets() public view override returns (Facet[] memory facets_) {\\n Facet[] memory defaultFacet = LibDiamond\\n .diamondStorage()\\n .defaultFallbackHandler\\n .facets();\\n Facet[] memory _facets = LibLoupe.facets();\\n uint256 numFacets = _facets.length;\\n bytes4[] memory keys;\\n address[] memory values;\\n for (uint256 i; i < numFacets; ) {\\n uint256 selectorsLength = _facets[i].functionSelectors.length;\\n for (uint256 j; j < selectorsLength; ) {\\n (keys, values) = LibUtils.setValue(\\n keys,\\n values,\\n _facets[i].functionSelectors[j],\\n _facets[i].facetAddress\\n );\\n unchecked {\\n ++j;\\n }\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n {\\n bool iIncrement;\\n for (uint256 i; i < defaultFacet.length; ) {\\n bool jIncrement;\\n for (\\n uint256 j;\\n j < defaultFacet[i].functionSelectors.length;\\n\\n ) {\\n if (\\n LibUtils.getValue(\\n keys,\\n values,\\n defaultFacet[i].functionSelectors[j]\\n ) != address(0)\\n ) {\\n if (defaultFacet[i].functionSelectors.length == 1) {\\n defaultFacet = LibUtils.removeFacetElement(\\n defaultFacet,\\n i\\n );\\n iIncrement = true;\\n break;\\n }\\n defaultFacet[i].functionSelectors = LibUtils\\n .removeElement(\\n defaultFacet[i].functionSelectors,\\n j\\n );\\n jIncrement = true;\\n }\\n if (!jIncrement) {\\n unchecked {\\n ++j;\\n }\\n } else {\\n jIncrement = false;\\n }\\n }\\n if (!iIncrement) {\\n unchecked {\\n ++i;\\n }\\n } else {\\n iIncrement = false;\\n }\\n }\\n }\\n {\\n uint256 facetLength = numFacets + defaultFacet.length;\\n facets_ = new Facet[](facetLength);\\n uint256 defaultFacetIndex;\\n for (uint256 i; i < facetLength; ) {\\n if (i < numFacets) {\\n facets_[i] = _facets[i];\\n bool jIncrementor;\\n for (uint256 j; j < defaultFacet.length; ) {\\n if (\\n facets_[i].facetAddress ==\\n defaultFacet[j].facetAddress\\n ) {\\n facets_[i].functionSelectors = LibUtils.mergeArrays(\\n _facets[i].functionSelectors,\\n defaultFacet[j].functionSelectors\\n );\\n defaultFacet = LibUtils.removeFacetElement(\\n defaultFacet,\\n j\\n );\\n jIncrementor = true;\\n {\\n facets_ = LibUtils.removeFacetElement(\\n facets_,\\n facets_.length - 1\\n );\\n }\\n --facetLength;\\n }\\n if (!jIncrementor) {\\n unchecked {\\n ++j;\\n }\\n } else {\\n jIncrementor = false;\\n }\\n }\\n } else {\\n facets_[i] = defaultFacet[defaultFacetIndex];\\n ++defaultFacetIndex;\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n }\\n\\n /**\\n * @notice Gets all the function selectors provided by a facet.\\n * @param _facet The facet address.\\n * @return facetFunctionSelectors_\\n */\\n function facetFunctionSelectors(\\n address _facet\\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\\n Facet[] memory facet = facets();\\n uint256 facetLength = facet.length;\\n for (uint256 i; i < facetLength; ) {\\n if (facet[i].facetAddress == _facet)\\n return facet[i].functionSelectors;\\n unchecked {\\n ++i;\\n }\\n }\\n return facetFunctionSelectors_;\\n }\\n\\n /**\\n * @notice Get all the facet addresses used by Barz.\\n * @return facetAddresses_\\n */\\n function facetAddresses()\\n external\\n view\\n override\\n returns (address[] memory facetAddresses_)\\n {\\n Facet[] memory facet = facets();\\n uint256 facetLength = facet.length;\\n facetAddresses_ = new address[](facetLength);\\n for (uint256 i; i < facetLength; ) {\\n facetAddresses_[i] = facet[i].facetAddress;\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * @notice Gets the facet that supports the given selector.\\n * @dev If facet is not found return address(0).\\n * @param _functionSelector The function selector.\\n * @return facetAddress_ The facet address.\\n */\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view override returns (address facetAddress_) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n\\n facetAddress_ = address(bytes20(ds.facets[_functionSelector]));\\n if (facetAddress_ == address(0)) {\\n facetAddress_ = IDiamondLoupe(ds.defaultFallbackHandler)\\n .facetAddress(_functionSelector);\\n }\\n }\\n\\n /**\\n * @notice SupportInterface to be compatible with EIP 165\\n * @param _interfaceId Interface ID for detecting the interface\\n * @return isSupported Bool value showing if the standard is supported in the contract\\n */\\n function supportsInterface(\\n bytes4 _interfaceId\\n ) external view override returns (bool isSupported) {\\n isSupported =\\n _interfaceId == type(IERC165).interfaceId ||\\n _interfaceId == IDiamondCut.diamondCut.selector ||\\n _interfaceId == type(IDiamondLoupe).interfaceId ||\\n _interfaceId == type(IERC1155Receiver).interfaceId ||\\n _interfaceId == type(IERC721Receiver).interfaceId ||\\n _interfaceId == type(IERC777Recipient).interfaceId ||\\n _interfaceId == IERC1271.isValidSignature.selector ||\\n _interfaceId == type(IERC677Receiver).interfaceId ||\\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId];\\n }\\n\\n /**\\n * @notice Returns the facet from the diamond storage. This excludes the facets from the default fallback handler\\n * @return facets_ Facet information attached directly to diamond storage\\n */\\n function facetsFromStorage()\\n external\\n view\\n override\\n returns (Facet[] memory facets_)\\n {\\n facets_ = LibLoupe.facets();\\n }\\n\\n /**\\n * @notice Returns the facet address attached to the given function selector. This excludes the facets from the default fallback handler\\n * @param _functionSelector Function selector to fetch the facet address from diamond storage\\n * @return facetAddress_ Facet address mapped with the function selector\\n */\\n function facetAddressFromStorage(\\n bytes4 _functionSelector\\n ) external view override returns (address facetAddress_) {\\n facetAddress_ = LibLoupe.facetAddress(_functionSelector);\\n }\\n\\n /**\\n * @notice Returns all facet addresses attached directly to diamond storage. This excludes the facets from the default fallback handler\\n * @return facetAddresses_ All facet addresses attached directly to diamond storage\\n */\\n function facetAddressesFromStorage()\\n external\\n view\\n override\\n returns (address[] memory facetAddresses_)\\n {\\n facetAddresses_ = LibLoupe.facetAddresses();\\n }\\n\\n /**\\n * @notice Returns function selectors of given facet address attached directly to diamond storage. This excludes the facets from the default fallback handler\\n * @param _facet Facet address to fetch the facet function selectors from diamond storage\\n * @return facetFunctionSelectors_ Facet function selectors of the given facet address\\n */\\n function facetFunctionSelectorsFromStorage(\\n address _facet\\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\\n facetFunctionSelectors_ = LibLoupe.facetFunctionSelectors(_facet);\\n }\\n}\\n\",\"keccak256\":\"0xf392fde159eec6483fc15fa323ecd6d764028f5b8734a66662c4116292363794\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IStorageLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"./IDiamondLoupe.sol\\\";\\n\\n/**\\n * @title LoupeFromStorage Interface\\n * @dev Interface contract to function as a loupe facet directly attached to diamond storage of Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IStorageLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facetsFromStorage()\\n external\\n view\\n returns (IDiamondLoupe.Facet[] memory);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n function facetFunctionSelectorsFromStorage(\\n address _facet\\n ) external view returns (bytes4[] memory);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n function facetAddressesFromStorage()\\n external\\n view\\n returns (address[] memory);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n function facetAddressFromStorage(\\n bytes4 _functionSelector\\n ) external view returns (address);\\n}\\n\",\"keccak256\":\"0xdf5dc9c57319e9087628c9cf9404b4f75585b76d1c2f4f59ee796c933967ea5c\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC1271 {\\n function isValidSignature(\\n bytes32 hash,\\n bytes memory signature\\n ) external view returns (bytes4);\\n}\\n\",\"keccak256\":\"0xcdddb7d5641c9d3f2432dec7fd13fddb9ae1480f25c76c21511e2fa16b8bd422\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.21;\\n\\ninterface IERC165 {\\n /// @notice Query if a contract implements an interface\\n /// @param interfaceId The interface identifier, as specified in ERC-165\\n /// @dev Interface identification is specified in ERC-165. This function\\n /// uses less than 30,000 gas.\\n /// @return `true` if the contract implements `interfaceID` and\\n /// `interfaceID` is not 0xffffffff, `false` otherwise\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xbb7f07e170898793c5535cc4b7e8944c4b990a631ac806d0b788e794abc788a3\",\"license\":\"MIT\"},\"contracts/interfaces/ERC/IERC677Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC677Receiver {\\n function onTokenTransfer(\\n address sender,\\n uint value,\\n bytes calldata data\\n ) external pure returns (bool);\\n}\\n\",\"keccak256\":\"0x4c1631cf45ea6daac0ec158c3edb9453099130b6b64f697004b83f95aa1f7350\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\\n bytes4(keccak256(\\\"verifyRestrictions(address,address,uint256,bytes)\\\"));\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // Default Fallback Handler of the barz.\\n IDiamondLoupe defaultFallbackHandler;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function enforceIsSelf() internal view {\\n require(msg.sender == address(this), \\\"LibDiamond: Caller not self\\\");\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n\\n unchecked {\\n facetIndex++;\\n }\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n\\n function restrictionsFacet() internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(\\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2cabdc00de859c3a3170ce3bda5d0e5fd3933d47ce904fd1585f9818b02572f8\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\nimport {LibDiamond} from \\\"./LibDiamond.sol\\\";\\n\\n/**\\n * @title LibLoupe\\n * @dev Internal Library to provide utility feature for reading the state of diamond facets\\n * Originally from Diamond's implementation of Mudgen(author of EIP-2535)\\n */\\nlibrary LibLoupe {\\n /// @notice Gets all facets and their selectors.\\n /// @return facets_ Facet\\n function facets()\\n internal\\n view\\n returns (IDiamondLoupe.Facet[] memory facets_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facets_ = new IDiamondLoupe.Facet[](ds.selectorCount);\\n uint16[] memory numFacetSelectors = new uint16[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facets_[facetIndex].facetAddress == facetAddress_) {\\n facets_[facetIndex].functionSelectors[\\n numFacetSelectors[facetIndex]\\n ] = selector;\\n // probably will never have more than 256 functions from one facet contract\\n require(numFacetSelectors[facetIndex] < 255);\\n numFacetSelectors[facetIndex]++;\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facets_[numFacets].facetAddress = facetAddress_;\\n facets_[numFacets].functionSelectors = new bytes4[](\\n ds.selectorCount\\n );\\n facets_[numFacets].functionSelectors[0] = selector;\\n numFacetSelectors[numFacets] = 1;\\n numFacets++;\\n }\\n }\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n uint256 numSelectors = numFacetSelectors[facetIndex];\\n bytes4[] memory selectors = facets_[facetIndex].functionSelectors;\\n // setting the number of selectors\\n assembly {\\n mstore(selectors, numSelectors)\\n }\\n }\\n // setting the number of facets\\n assembly {\\n mstore(facets_, numFacets)\\n }\\n }\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return _facetFunctionSelectors The selectors associated with a facet address.\\n function facetFunctionSelectors(\\n address _facet\\n ) internal view returns (bytes4[] memory _facetFunctionSelectors) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n uint256 numSelectors;\\n _facetFunctionSelectors = new bytes4[](ds.selectorCount);\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facet = address(bytes20(ds.facets[selector]));\\n if (_facet == facet) {\\n _facetFunctionSelectors[numSelectors] = selector;\\n numSelectors++;\\n }\\n }\\n }\\n // Set the number of selectors in the array\\n assembly {\\n mstore(_facetFunctionSelectors, numSelectors)\\n }\\n }\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n internal\\n view\\n returns (address[] memory facetAddresses_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetAddresses_ = new address[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facetAddress_ == facetAddresses_[facetIndex]) {\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facetAddresses_[numFacets] = facetAddress_;\\n numFacets++;\\n }\\n }\\n // Set the number of facet addresses in the array\\n assembly {\\n mstore(facetAddresses_, numFacets)\\n }\\n }\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(LibDiamond.diamondStorage().facets[_functionSelector])\\n );\\n }\\n}\\n\",\"keccak256\":\"0x0b11439c3cc657095e15ec2241fdcf67204b14001357b612fc5db4ff9e760a5a\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibUtils.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nlibrary LibUtils {\\n // Internal utility functions\\n function mergeArrays(\\n bytes4[] memory _array1,\\n bytes4[] memory _array2\\n ) internal pure returns (bytes4[] memory) {\\n uint256 length1 = _array1.length;\\n uint256 length2 = _array2.length;\\n bytes4[] memory mergedArray = new bytes4[](length1 + length2);\\n\\n for (uint256 i; i < length1; ) {\\n mergedArray[i] = _array1[i];\\n unchecked {\\n ++i;\\n }\\n }\\n\\n for (uint256 i; i < length2; ) {\\n mergedArray[length1 + i] = _array2[i];\\n unchecked {\\n ++i;\\n }\\n }\\n\\n return mergedArray;\\n }\\n\\n function removeFacetElement(\\n IDiamondLoupe.Facet[] memory _facets,\\n uint256 _index\\n ) internal pure returns (IDiamondLoupe.Facet[] memory) {\\n require(_index < _facets.length, \\\"Invalid index\\\");\\n require(_facets.length != 0, \\\"Invalid array\\\");\\n\\n // Create a new array with a length of `_facets.length - 1`\\n IDiamondLoupe.Facet[] memory newArray = new IDiamondLoupe.Facet[](\\n _facets.length - 1\\n );\\n uint256 newArrayLength = newArray.length;\\n // Iterate over the original array, skipping the element at the specified `index`\\n for (uint256 i; i < newArrayLength; ) {\\n if (i < _index) {\\n newArray[i] = _facets[i];\\n } else {\\n newArray[i] = _facets[i + 1];\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n\\n return newArray;\\n }\\n\\n function removeElement(\\n bytes4[] memory _array,\\n uint256 _index\\n ) internal pure returns (bytes4[] memory) {\\n require(_index < _array.length, \\\"Invalid index\\\");\\n require(_array.length != 0, \\\"Invalid array\\\");\\n\\n bytes4[] memory newArray = new bytes4[](_array.length - 1);\\n uint256 newArrayLength = newArray.length;\\n for (uint256 i; i < newArrayLength; ) {\\n if (i < _index) {\\n newArray[i] = _array[i];\\n } else {\\n newArray[i] = _array[i + 1];\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n\\n return newArray;\\n }\\n\\n function setValue(\\n bytes4[] memory _keys,\\n address[] memory _values,\\n bytes4 _key,\\n address _value\\n ) internal pure returns (bytes4[] memory, address[] memory) {\\n uint256 index = findIndex(_keys, _key);\\n uint256 keysLength = _keys.length;\\n if (index < keysLength) {\\n _values[index] = _value;\\n } else {\\n // Create new storage arrays\\n bytes4[] memory newKeys = new bytes4[](keysLength + 1);\\n address[] memory newValues = new address[](_values.length + 1);\\n\\n // Copy values to the new storage arrays\\n for (uint256 i; i < keysLength; ) {\\n newKeys[i] = _keys[i];\\n newValues[i] = _values[i];\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n // Add the new key-value pair\\n newKeys[keysLength] = _key;\\n newValues[_values.length] = _value;\\n\\n return (newKeys, newValues);\\n }\\n\\n // If the key already exists, return the original arrays\\n return (_keys, _values);\\n }\\n\\n function getValue(\\n bytes4[] memory _keys,\\n address[] memory _values,\\n bytes4 _key\\n ) internal pure returns (address) {\\n uint256 index = findIndex(_keys, _key);\\n if (index >= _keys.length) return address(0);\\n\\n return _values[index];\\n }\\n\\n function findIndex(\\n bytes4[] memory _keys,\\n bytes4 _key\\n ) internal pure returns (uint256) {\\n uint256 keysLength = _keys.length;\\n for (uint256 i; i < keysLength; ) {\\n if (_keys[i] == _key) {\\n return i;\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n return keysLength;\\n }\\n}\\n\",\"keccak256\":\"0xde8aeefe54c4be483f2b2c055aca11e2830f7094c0586a82e10ec544933b5714\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5061240b806100206000396000f3fe608060405234801561001057600080fd5b50600436106100a35760003560e01c8063adfca15e11610076578063d42139a91161005b578063d42139a914610169578063e3a2f6fe14610171578063f9796ccf1461018457600080fd5b8063adfca15e1461011e578063cdffacc61461013157600080fd5b806301a55022146100a857806301ffc9a7146100d157806352ef6b2c146100f45780637a0ed62714610109575b600080fd5b6100bb6100b6366004611e4b565b61018c565b6040516100c89190611e68565b60405180910390f35b6100e46100df366004611efc565b61019d565b60405190151581526020016100c8565b6100fc610454565b6040516100c89190611f19565b610111610518565b6040516100c89190611f67565b6100bb61012c366004611e4b565b610a63565b61014461013f366004611efc565b610b07565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100c8565b6100fc610c24565b61014461017f366004611efc565b610c33565b610111610c8c565b606061019782610c96565b92915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000148061023057507fffffffff0000000000000000000000000000000000000000000000000000000082167f1f931c1c00000000000000000000000000000000000000000000000000000000145b8061027c57507fffffffff0000000000000000000000000000000000000000000000000000000082167f48e2b09300000000000000000000000000000000000000000000000000000000145b806102c857507fffffffff0000000000000000000000000000000000000000000000000000000082167f4e2312e000000000000000000000000000000000000000000000000000000000145b8061031457507fffffffff0000000000000000000000000000000000000000000000000000000082167f150b7a0200000000000000000000000000000000000000000000000000000000145b8061035f57507fffffffff0000000000000000000000000000000000000000000000000000000082167e23de2900000000000000000000000000000000000000000000000000000000145b806103ab57507fffffffff0000000000000000000000000000000000000000000000000000000082167f1626ba7e00000000000000000000000000000000000000000000000000000000145b806103f757507fffffffff0000000000000000000000000000000000000000000000000000000082167fa4c0ed3600000000000000000000000000000000000000000000000000000000145b806101975750507fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4922602052604090205460ff1690565b60606000610460610518565b80519091508067ffffffffffffffff81111561047e5761047e61205d565b6040519080825280602002602001820160405280156104a7578160200160208202803683370190505b50925060005b81811015610512578281815181106104c7576104c761208c565b6020026020010151600001518482815181106104e5576104e561208c565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526001016104ad565b50505090565b606060007f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f600490810154604080517f7a0ed627000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff90921692637a0ed6279282820192600092908290030181865afa1580156105ac573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526105f29190810190612157565b905060006105fe610e57565b805190915060608060005b838110156106b55760008582815181106106255761062561208c565b60200260200101516020015151905060005b818110156106ab5761069e85858986815181106106565761065661208c565b60200260200101516020015184815181106106735761067361208c565b60200260200101518a878151811061068d5761068d61208c565b60200260200101516000015161134a565b9095509350600101610637565b5050600101610609565b506000805b865181101561081b576000805b8883815181106106d9576106d961208c565b602002602001015160200151518110156107ff57600073ffffffffffffffffffffffffffffffffffffffff1661074687878c878151811061071c5761071c61208c565b60200260200101516020015185815181106107395761073961208c565b60200260200101516115f1565b73ffffffffffffffffffffffffffffffffffffffff16146107e9578883815181106107735761077361208c565b6020026020010151602001515160010361079c576107918984611637565b9850600193506107ff565b6107c38984815181106107b1576107b161208c565b6020026020010151602001518261182a565b8984815181106107d5576107d561208c565b602002602001015160200181905250600191505b816107f6576001016106c7565b600091506106c7565b508261081057816001019150610815565b600092505b506106ba565b5050600085518461082c9190612304565b90508067ffffffffffffffff8111156108475761084761205d565b60405190808252806020026020018201604052801561088d57816020015b6040805180820190915260008152606060208201528152602001906001900390816108655790505b5096506000805b82811015610a585785811015610a0c578681815181106108b6576108b661208c565b60200260200101518982815181106108d0576108d061208c565b60200260200101819052506000805b8951811015610a05578981815181106108fa576108fa61208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff168b848151811061092e5761092e61208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff16036109ef5761099989848151811061096a5761096a61208c565b6020026020010151602001518b83815181106109885761098861208c565b602002602001015160200151611a3d565b8b84815181106109ab576109ab61208c565b6020026020010151602001819052506109c48a82611637565b9950600191506109e18b60018d516109dc9190612317565b611637565b9a506109ec8561232a565b94505b816109fc576001016108df565b600091506108df565b5050610a50565b878281518110610a1e57610a1e61208c565b6020026020010151898281518110610a3857610a3861208c565b602002602001018190525081610a4d9061235f565b91505b600101610894565b505050505050505090565b60606000610a6f610518565b805190915060005b81811015610aff578473ffffffffffffffffffffffffffffffffffffffff16838281518110610aa857610aa861208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1603610af757828181518110610ae157610ae161208c565b6020026020010151602001519350505050919050565b600101610a77565b505050919050565b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602081905260409091205460601c9081610c1e576004818101546040517fcdffacc60000000000000000000000000000000000000000000000000000000081527fffffffff0000000000000000000000000000000000000000000000000000000086169281019290925273ffffffffffffffffffffffffffffffffffffffff169063cdffacc690602401602060405180830381865afa158015610bf7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c1b9190612397565b91505b50919050565b6060610c2e611b8b565b905090565b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604081205460601c610197565b6060610c2e610e57565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9060009061ffff1667ffffffffffffffff811115610cfc57610cfc61205d565b604051908082528060200260200182016040528015610d25578160200160208202803683370190505b5092506000805b600284015461ffff16821015610e4d576000818152600185016020526040812054905b6008811015610e385783610d628161235f565b600288015490955061ffff1685119050610e3857600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020889052604090205460601c73ffffffffffffffffffffffffffffffffffffffff8a16819003610e235781898881518110610de457610de461208c565b7fffffffff000000000000000000000000000000000000000000000000000000009092166020928302919091019091015286610e1f8161235f565b9750505b50508080610e309061235f565b915050610d4f565b50508080610e459061235f565b915050610d2c565b5050825250919050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff1667ffffffffffffffff811115610eba57610eba61205d565b604051908082528060200260200182016040528015610f0057816020015b604080518082019091526000815260606020820152815260200190600190039081610ed85790505b50600282015490925060009061ffff1667ffffffffffffffff811115610f2857610f2861205d565b604051908082528060200260200182016040528015610f51578160200160208202803683370190505b50905060008060005b600285015461ffff168210156112d7576000818152600186016020526040812054905b60088110156112c25783610f908161235f565b600289015490955061ffff16851190506112c257600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020899052604081205460601c90805b88811015611148578273ffffffffffffffffffffffffffffffffffffffff168c82815181106110155761101561208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff160361113657838c828151811061104f5761104f61208c565b6020026020010151602001518b838151811061106d5761106d61208c565b602002602001015161ffff16815181106110895761108961208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152505060ff8a82815181106110e9576110e961208c565b602002602001015161ffff16106110ff57600080fd5b8981815181106111115761111161208c565b602002602001018051809190611126906123b4565b61ffff1690525060019150611148565b806111408161235f565b915050610fe4565b508015611157575050506112b0565b818b898151811061116a5761116a61208c565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff909116905260028a015461ffff1667ffffffffffffffff8111156111b0576111b061205d565b6040519080825280602002602001820160405280156111d9578160200160208202803683370190505b508b89815181106111ec576111ec61208c565b602002602001015160200181905250828b898151811061120e5761120e61208c565b60200260200101516020015160008151811061122c5761122c61208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681525050600189898151811061128c5761128c61208c565b61ffff90921660209283029190910190910152876112a98161235f565b9850505050505b806112ba8161235f565b915050610f7d565b505080806112cf9061235f565b915050610f5a565b5060005b8281101561133f5760008482815181106112f7576112f761208c565b602002602001015161ffff16905060008783815181106113195761131961208c565b6020026020010151602001519050818152505080806113379061235f565b9150506112db565b508185525050505090565b60608060006113598786611da0565b8751909150808210156113b857848783815181106113795761137961208c565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250506115df565b60006113c5826001612304565b67ffffffffffffffff8111156113dd576113dd61205d565b604051908082528060200260200182016040528015611406578160200160208202803683370190505b5090506000885160016114199190612304565b67ffffffffffffffff8111156114315761143161205d565b60405190808252806020026020018201604052801561145a578160200160208202803683370190505b50905060005b83811015611539578a818151811061147a5761147a61208c565b60200260200101518382815181106114945761149461208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815250508981815181106114f2576114f261208c565b602002602001015182828151811061150c5761150c61208c565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101611460565b508782848151811061154d5761154d61208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152505086818a51815181106115ad576115ad61208c565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015290945092506115e8915050565b87879350935050505b94509492505050565b6000806115fe8584611da0565b905084518110611612576000915050611630565b8381815181106116245761162461208c565b60200260200101519150505b9392505050565b6060825182106116a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420696e6465780000000000000000000000000000000000000060448201526064015b60405180910390fd5b8251600003611713576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420617272617900000000000000000000000000000000000000604482015260640161169f565b6000600184516117239190612317565b67ffffffffffffffff81111561173b5761173b61205d565b60405190808252806020026020018201604052801561178157816020015b6040805180820190915260008152606060208201528152602001906001900390816117595790505b50805190915060005b8181101561182057848110156117d6578581815181106117ac576117ac61208c565b60200260200101518382815181106117c6576117c661208c565b6020026020010181905250611818565b856117e2826001612304565b815181106117f2576117f261208c565b602002602001015183828151811061180c5761180c61208c565b60200260200101819052505b60010161178a565b5090949350505050565b606082518210611896576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420696e64657800000000000000000000000000000000000000604482015260640161169f565b8251600003611901576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420617272617900000000000000000000000000000000000000604482015260640161169f565b6000600184516119119190612317565b67ffffffffffffffff8111156119295761192961205d565b604051908082528060200260200182016040528015611952578160200160208202803683370190505b50805190915060005b8181101561182057848110156119cd5785818151811061197d5761197d61208c565b60200260200101518382815181106119975761199761208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152611a35565b856119d9826001612304565b815181106119e9576119e961208c565b6020026020010151838281518110611a0357611a0361208c565b7fffffffff00000000000000000000000000000000000000000000000000000000909216602092830291909101909101525b60010161195b565b81518151606091906000611a518284612304565b67ffffffffffffffff811115611a6957611a6961205d565b604051908082528060200260200182016040528015611a92578160200160208202803683370190505b50905060005b83811015611b0557868181518110611ab257611ab261208c565b6020026020010151828281518110611acc57611acc61208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152600101611a98565b5060005b82811015611b8157858181518110611b2357611b2361208c565b6020026020010151828286611b389190612304565b81518110611b4857611b4861208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152600101611b09565b5095945050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff1667ffffffffffffffff811115611bee57611bee61205d565b604051908082528060200260200182016040528015611c17578160200160208202803683370190505b50915060008060005b600284015461ffff16821015611d98576000818152600185016020526040812054905b6008811015611d835783611c568161235f565b600288015490955061ffff1685119050611d8357600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020889052604081205460601c90805b88811015611d19578a8181518110611cc457611cc461208c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611d075760019150611d19565b80611d118161235f565b915050611caa565b508015611d2857505050611d71565b818a8981518110611d3b57611d3b61208c565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015287611d6a8161235f565b9850505050505b80611d7b8161235f565b915050611c43565b50508080611d909061235f565b915050611c20565b505082525090565b8151600090815b81811015611e1e57837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916858281518110611de157611de161208c565b60200260200101517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603611e165791506101979050565b600101611da7565b509392505050565b73ffffffffffffffffffffffffffffffffffffffff81168114611e4857600080fd5b50565b600060208284031215611e5d57600080fd5b813561163081611e26565b6020808252825182820181905260009190848201906040850190845b81811015611ec25783517fffffffff000000000000000000000000000000000000000000000000000000001683529284019291840191600101611e84565b50909695505050505050565b7fffffffff0000000000000000000000000000000000000000000000000000000081168114611e4857600080fd5b600060208284031215611f0e57600080fd5b813561163081611ece565b6020808252825182820181905260009190848201906040850190845b81811015611ec257835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101611f35565b60006020808301818452808551808352604092508286019150828160051b8701018488016000805b8481101561204e578984037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00186528251805173ffffffffffffffffffffffffffffffffffffffff168552880151888501889052805188860181905290890190839060608701905b808310156120395783517fffffffff00000000000000000000000000000000000000000000000000000000168252928b019260019290920191908b0190611ff7565b50978a01979550505091870191600101611f8f565b50919998505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6040805190810167ffffffffffffffff811182821017156120de576120de61205d565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561212b5761212b61205d565b604052919050565b600067ffffffffffffffff82111561214d5761214d61205d565b5060051b60200190565b6000602080838503121561216a57600080fd5b825167ffffffffffffffff8082111561218257600080fd5b818501915085601f83011261219657600080fd5b81516121a96121a482612133565b6120e4565b81815260059190911b830184019084810190888311156121c857600080fd5b8585015b838110156122c8578051858111156121e45760008081fd5b86016040818c037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00181131561221a5760008081fd5b6122226120bb565b8983015161222f81611e26565b815282820151888111156122435760008081fd5b8084019350508c603f8401126122595760008081fd5b898301516122696121a482612133565b81815260059190911b84018301908b8101908f8311156122895760008081fd5b948401945b828610156122b357855194506122a385611ece565b848252948c0194908c019061228e565b838d01525050855250509186019186016121cc565b5098975050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610197576101976122d5565b81810381811115610197576101976122d5565b600081612339576123396122d5565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612390576123906122d5565b5060010190565b6000602082840312156123a957600080fd5b815161163081611e26565b600061ffff8083168181036123cb576123cb6122d5565b600101939250505056fea26469706673582212205959d8d85aad6f29d5fc37d5a52c404c25392cec49195c3b761da0e863e99b0f64736f6c63430008150033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100a35760003560e01c8063adfca15e11610076578063d42139a91161005b578063d42139a914610169578063e3a2f6fe14610171578063f9796ccf1461018457600080fd5b8063adfca15e1461011e578063cdffacc61461013157600080fd5b806301a55022146100a857806301ffc9a7146100d157806352ef6b2c146100f45780637a0ed62714610109575b600080fd5b6100bb6100b6366004611e4b565b61018c565b6040516100c89190611e68565b60405180910390f35b6100e46100df366004611efc565b61019d565b60405190151581526020016100c8565b6100fc610454565b6040516100c89190611f19565b610111610518565b6040516100c89190611f67565b6100bb61012c366004611e4b565b610a63565b61014461013f366004611efc565b610b07565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100c8565b6100fc610c24565b61014461017f366004611efc565b610c33565b610111610c8c565b606061019782610c96565b92915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000148061023057507fffffffff0000000000000000000000000000000000000000000000000000000082167f1f931c1c00000000000000000000000000000000000000000000000000000000145b8061027c57507fffffffff0000000000000000000000000000000000000000000000000000000082167f48e2b09300000000000000000000000000000000000000000000000000000000145b806102c857507fffffffff0000000000000000000000000000000000000000000000000000000082167f4e2312e000000000000000000000000000000000000000000000000000000000145b8061031457507fffffffff0000000000000000000000000000000000000000000000000000000082167f150b7a0200000000000000000000000000000000000000000000000000000000145b8061035f57507fffffffff0000000000000000000000000000000000000000000000000000000082167e23de2900000000000000000000000000000000000000000000000000000000145b806103ab57507fffffffff0000000000000000000000000000000000000000000000000000000082167f1626ba7e00000000000000000000000000000000000000000000000000000000145b806103f757507fffffffff0000000000000000000000000000000000000000000000000000000082167fa4c0ed3600000000000000000000000000000000000000000000000000000000145b806101975750507fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4922602052604090205460ff1690565b60606000610460610518565b80519091508067ffffffffffffffff81111561047e5761047e61205d565b6040519080825280602002602001820160405280156104a7578160200160208202803683370190505b50925060005b81811015610512578281815181106104c7576104c761208c565b6020026020010151600001518482815181106104e5576104e561208c565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526001016104ad565b50505090565b606060007f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f600490810154604080517f7a0ed627000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff90921692637a0ed6279282820192600092908290030181865afa1580156105ac573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526105f29190810190612157565b905060006105fe610e57565b805190915060608060005b838110156106b55760008582815181106106255761062561208c565b60200260200101516020015151905060005b818110156106ab5761069e85858986815181106106565761065661208c565b60200260200101516020015184815181106106735761067361208c565b60200260200101518a878151811061068d5761068d61208c565b60200260200101516000015161134a565b9095509350600101610637565b5050600101610609565b506000805b865181101561081b576000805b8883815181106106d9576106d961208c565b602002602001015160200151518110156107ff57600073ffffffffffffffffffffffffffffffffffffffff1661074687878c878151811061071c5761071c61208c565b60200260200101516020015185815181106107395761073961208c565b60200260200101516115f1565b73ffffffffffffffffffffffffffffffffffffffff16146107e9578883815181106107735761077361208c565b6020026020010151602001515160010361079c576107918984611637565b9850600193506107ff565b6107c38984815181106107b1576107b161208c565b6020026020010151602001518261182a565b8984815181106107d5576107d561208c565b602002602001015160200181905250600191505b816107f6576001016106c7565b600091506106c7565b508261081057816001019150610815565b600092505b506106ba565b5050600085518461082c9190612304565b90508067ffffffffffffffff8111156108475761084761205d565b60405190808252806020026020018201604052801561088d57816020015b6040805180820190915260008152606060208201528152602001906001900390816108655790505b5096506000805b82811015610a585785811015610a0c578681815181106108b6576108b661208c565b60200260200101518982815181106108d0576108d061208c565b60200260200101819052506000805b8951811015610a05578981815181106108fa576108fa61208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff168b848151811061092e5761092e61208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff16036109ef5761099989848151811061096a5761096a61208c565b6020026020010151602001518b83815181106109885761098861208c565b602002602001015160200151611a3d565b8b84815181106109ab576109ab61208c565b6020026020010151602001819052506109c48a82611637565b9950600191506109e18b60018d516109dc9190612317565b611637565b9a506109ec8561232a565b94505b816109fc576001016108df565b600091506108df565b5050610a50565b878281518110610a1e57610a1e61208c565b6020026020010151898281518110610a3857610a3861208c565b602002602001018190525081610a4d9061235f565b91505b600101610894565b505050505050505090565b60606000610a6f610518565b805190915060005b81811015610aff578473ffffffffffffffffffffffffffffffffffffffff16838281518110610aa857610aa861208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1603610af757828181518110610ae157610ae161208c565b6020026020010151602001519350505050919050565b600101610a77565b505050919050565b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602081905260409091205460601c9081610c1e576004818101546040517fcdffacc60000000000000000000000000000000000000000000000000000000081527fffffffff0000000000000000000000000000000000000000000000000000000086169281019290925273ffffffffffffffffffffffffffffffffffffffff169063cdffacc690602401602060405180830381865afa158015610bf7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c1b9190612397565b91505b50919050565b6060610c2e611b8b565b905090565b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604081205460601c610197565b6060610c2e610e57565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9060009061ffff1667ffffffffffffffff811115610cfc57610cfc61205d565b604051908082528060200260200182016040528015610d25578160200160208202803683370190505b5092506000805b600284015461ffff16821015610e4d576000818152600185016020526040812054905b6008811015610e385783610d628161235f565b600288015490955061ffff1685119050610e3857600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020889052604090205460601c73ffffffffffffffffffffffffffffffffffffffff8a16819003610e235781898881518110610de457610de461208c565b7fffffffff000000000000000000000000000000000000000000000000000000009092166020928302919091019091015286610e1f8161235f565b9750505b50508080610e309061235f565b915050610d4f565b50508080610e459061235f565b915050610d2c565b5050825250919050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff1667ffffffffffffffff811115610eba57610eba61205d565b604051908082528060200260200182016040528015610f0057816020015b604080518082019091526000815260606020820152815260200190600190039081610ed85790505b50600282015490925060009061ffff1667ffffffffffffffff811115610f2857610f2861205d565b604051908082528060200260200182016040528015610f51578160200160208202803683370190505b50905060008060005b600285015461ffff168210156112d7576000818152600186016020526040812054905b60088110156112c25783610f908161235f565b600289015490955061ffff16851190506112c257600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020899052604081205460601c90805b88811015611148578273ffffffffffffffffffffffffffffffffffffffff168c82815181106110155761101561208c565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff160361113657838c828151811061104f5761104f61208c565b6020026020010151602001518b838151811061106d5761106d61208c565b602002602001015161ffff16815181106110895761108961208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152505060ff8a82815181106110e9576110e961208c565b602002602001015161ffff16106110ff57600080fd5b8981815181106111115761111161208c565b602002602001018051809190611126906123b4565b61ffff1690525060019150611148565b806111408161235f565b915050610fe4565b508015611157575050506112b0565b818b898151811061116a5761116a61208c565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff909116905260028a015461ffff1667ffffffffffffffff8111156111b0576111b061205d565b6040519080825280602002602001820160405280156111d9578160200160208202803683370190505b508b89815181106111ec576111ec61208c565b602002602001015160200181905250828b898151811061120e5761120e61208c565b60200260200101516020015160008151811061122c5761122c61208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681525050600189898151811061128c5761128c61208c565b61ffff90921660209283029190910190910152876112a98161235f565b9850505050505b806112ba8161235f565b915050610f7d565b505080806112cf9061235f565b915050610f5a565b5060005b8281101561133f5760008482815181106112f7576112f761208c565b602002602001015161ffff16905060008783815181106113195761131961208c565b6020026020010151602001519050818152505080806113379061235f565b9150506112db565b508185525050505090565b60608060006113598786611da0565b8751909150808210156113b857848783815181106113795761137961208c565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250506115df565b60006113c5826001612304565b67ffffffffffffffff8111156113dd576113dd61205d565b604051908082528060200260200182016040528015611406578160200160208202803683370190505b5090506000885160016114199190612304565b67ffffffffffffffff8111156114315761143161205d565b60405190808252806020026020018201604052801561145a578160200160208202803683370190505b50905060005b83811015611539578a818151811061147a5761147a61208c565b60200260200101518382815181106114945761149461208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815250508981815181106114f2576114f261208c565b602002602001015182828151811061150c5761150c61208c565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101611460565b508782848151811061154d5761154d61208c565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152505086818a51815181106115ad576115ad61208c565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015290945092506115e8915050565b87879350935050505b94509492505050565b6000806115fe8584611da0565b905084518110611612576000915050611630565b8381815181106116245761162461208c565b60200260200101519150505b9392505050565b6060825182106116a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420696e6465780000000000000000000000000000000000000060448201526064015b60405180910390fd5b8251600003611713576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420617272617900000000000000000000000000000000000000604482015260640161169f565b6000600184516117239190612317565b67ffffffffffffffff81111561173b5761173b61205d565b60405190808252806020026020018201604052801561178157816020015b6040805180820190915260008152606060208201528152602001906001900390816117595790505b50805190915060005b8181101561182057848110156117d6578581815181106117ac576117ac61208c565b60200260200101518382815181106117c6576117c661208c565b6020026020010181905250611818565b856117e2826001612304565b815181106117f2576117f261208c565b602002602001015183828151811061180c5761180c61208c565b60200260200101819052505b60010161178a565b5090949350505050565b606082518210611896576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420696e64657800000000000000000000000000000000000000604482015260640161169f565b8251600003611901576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c696420617272617900000000000000000000000000000000000000604482015260640161169f565b6000600184516119119190612317565b67ffffffffffffffff8111156119295761192961205d565b604051908082528060200260200182016040528015611952578160200160208202803683370190505b50805190915060005b8181101561182057848110156119cd5785818151811061197d5761197d61208c565b60200260200101518382815181106119975761199761208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152611a35565b856119d9826001612304565b815181106119e9576119e961208c565b6020026020010151838281518110611a0357611a0361208c565b7fffffffff00000000000000000000000000000000000000000000000000000000909216602092830291909101909101525b60010161195b565b81518151606091906000611a518284612304565b67ffffffffffffffff811115611a6957611a6961205d565b604051908082528060200260200182016040528015611a92578160200160208202803683370190505b50905060005b83811015611b0557868181518110611ab257611ab261208c565b6020026020010151828281518110611acc57611acc61208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152600101611a98565b5060005b82811015611b8157858181518110611b2357611b2361208c565b6020026020010151828286611b389190612304565b81518110611b4857611b4861208c565b7fffffffff0000000000000000000000000000000000000000000000000000000090921660209283029190910190910152600101611b09565b5095945050505050565b7f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd4921546060907f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f9061ffff1667ffffffffffffffff811115611bee57611bee61205d565b604051908082528060200260200182016040528015611c17578160200160208202803683370190505b50915060008060005b600284015461ffff16821015611d98576000818152600185016020526040812054905b6008811015611d835783611c568161235f565b600288015490955061ffff1685119050611d8357600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020889052604081205460601c90805b88811015611d19578a8181518110611cc457611cc461208c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611d075760019150611d19565b80611d118161235f565b915050611caa565b508015611d2857505050611d71565b818a8981518110611d3b57611d3b61208c565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015287611d6a8161235f565b9850505050505b80611d7b8161235f565b915050611c43565b50508080611d909061235f565b915050611c20565b505082525090565b8151600090815b81811015611e1e57837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916858281518110611de157611de161208c565b60200260200101517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603611e165791506101979050565b600101611da7565b509392505050565b73ffffffffffffffffffffffffffffffffffffffff81168114611e4857600080fd5b50565b600060208284031215611e5d57600080fd5b813561163081611e26565b6020808252825182820181905260009190848201906040850190845b81811015611ec25783517fffffffff000000000000000000000000000000000000000000000000000000001683529284019291840191600101611e84565b50909695505050505050565b7fffffffff0000000000000000000000000000000000000000000000000000000081168114611e4857600080fd5b600060208284031215611f0e57600080fd5b813561163081611ece565b6020808252825182820181905260009190848201906040850190845b81811015611ec257835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101611f35565b60006020808301818452808551808352604092508286019150828160051b8701018488016000805b8481101561204e578984037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00186528251805173ffffffffffffffffffffffffffffffffffffffff168552880151888501889052805188860181905290890190839060608701905b808310156120395783517fffffffff00000000000000000000000000000000000000000000000000000000168252928b019260019290920191908b0190611ff7565b50978a01979550505091870191600101611f8f565b50919998505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6040805190810167ffffffffffffffff811182821017156120de576120de61205d565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561212b5761212b61205d565b604052919050565b600067ffffffffffffffff82111561214d5761214d61205d565b5060051b60200190565b6000602080838503121561216a57600080fd5b825167ffffffffffffffff8082111561218257600080fd5b818501915085601f83011261219657600080fd5b81516121a96121a482612133565b6120e4565b81815260059190911b830184019084810190888311156121c857600080fd5b8585015b838110156122c8578051858111156121e45760008081fd5b86016040818c037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00181131561221a5760008081fd5b6122226120bb565b8983015161222f81611e26565b815282820151888111156122435760008081fd5b8084019350508c603f8401126122595760008081fd5b898301516122696121a482612133565b81815260059190911b84018301908b8101908f8311156122895760008081fd5b948401945b828610156122b357855194506122a385611ece565b848252948c0194908c019061228e565b838d01525050855250509186019186016121cc565b5098975050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610197576101976122d5565b81810381811115610197576101976122d5565b600081612339576123396122d5565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612390576123906122d5565b5060010190565b6000602082840312156123a957600080fd5b815161163081611e26565b600061ffff8083168181036123cb576123cb6122d5565b600101939250505056fea26469706673582212205959d8d85aad6f29d5fc37d5a52c404c25392cec49195c3b761da0e863e99b0f64736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "DiamondLoupe contract compatible with EIP-2535", + "kind": "dev", + "methods": { + "facetAddress(bytes4)": { + "details": "If facet is not found return address(0).", + "params": { + "_functionSelector": "The function selector." + }, + "returns": { + "facetAddress_": "The facet address." + } + }, + "facetAddressFromStorage(bytes4)": { + "params": { + "_functionSelector": "Function selector to fetch the facet address from diamond storage" + }, + "returns": { + "facetAddress_": "Facet address mapped with the function selector" + } + }, + "facetAddresses()": { + "returns": { + "facetAddresses_": "facetAddresses_" + } + }, + "facetAddressesFromStorage()": { + "returns": { + "facetAddresses_": "All facet addresses attached directly to diamond storage" + } + }, + "facetFunctionSelectors(address)": { + "params": { + "_facet": "The facet address." + }, + "returns": { + "facetFunctionSelectors_": "facetFunctionSelectors_" + } + }, + "facetFunctionSelectorsFromStorage(address)": { + "params": { + "_facet": "Facet address to fetch the facet function selectors from diamond storage" + }, + "returns": { + "facetFunctionSelectors_": "Facet function selectors of the given facet address" + } + }, + "facets()": { + "details": "Barz uses a special architecture called default fallback handler. Default Fallback handler is used as a middleware that holds the mapping of facet function selector and facet address that Barz uses. This helps Barz to reduce significant amount of gas during the initialization process. Hence, this method aggregates both the facet information from DefaulFallbackHandler and in diamond storage and shows the data to users.", + "returns": { + "facets_": "Facet" + } + }, + "facetsFromStorage()": { + "returns": { + "facets_": "Facet information attached directly to diamond storage" + } + }, + "supportsInterface(bytes4)": { + "params": { + "_interfaceId": "Interface ID for detecting the interface" + }, + "returns": { + "isSupported": "Bool value showing if the standard is supported in the contract" + } + } + }, + "title": "DiamondLoupe Facet", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "facetAddress(bytes4)": { + "notice": "Gets the facet that supports the given selector." + }, + "facetAddressFromStorage(bytes4)": { + "notice": "Returns the facet address attached to the given function selector. This excludes the facets from the default fallback handler" + }, + "facetAddresses()": { + "notice": "Get all the facet addresses used by Barz." + }, + "facetAddressesFromStorage()": { + "notice": "Returns all facet addresses attached directly to diamond storage. This excludes the facets from the default fallback handler" + }, + "facetFunctionSelectors(address)": { + "notice": "Gets all the function selectors provided by a facet." + }, + "facetFunctionSelectorsFromStorage(address)": { + "notice": "Returns function selectors of given facet address attached directly to diamond storage. This excludes the facets from the default fallback handler" + }, + "facets()": { + "notice": "Gets all facets and their selectors." + }, + "facetsFromStorage()": { + "notice": "Returns the facet from the diamond storage. This excludes the facets from the default fallback handler" + }, + "supportsInterface(bytes4)": { + "notice": "SupportInterface to be compatible with EIP 165" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/polygon/Secp256r1VerificationFacet.json b/deployments/polygon/Secp256r1VerificationFacet.json new file mode 100644 index 0000000..95a8540 --- /dev/null +++ b/deployments/polygon/Secp256r1VerificationFacet.json @@ -0,0 +1,499 @@ +{ + "address": "0xeE1AF8E967eC04C84711842796A5E714D2FD33e6", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "LibAppStorage__AccountMustBeUninitialized", + "type": "error" + }, + { + "inputs": [], + "name": "LibAppStorage__SignerAlreadyUninitialized", + "type": "error" + }, + { + "inputs": [], + "name": "LibAppStorage__SignerMustBeUninitialized", + "type": "error" + }, + { + "inputs": [], + "name": "Secp256r1VerificationFacet__InvalidSignerLength", + "type": "error" + }, + { + "inputs": [], + "name": "VerificationFacet__InitializationFailure", + "type": "error" + }, + { + "inputs": [], + "name": "VerificationFacet__InvalidFacetMapping", + "type": "error" + }, + { + "inputs": [], + "name": "VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet", + "type": "error" + }, + { + "inputs": [], + "name": "VerificationFacet__ValidateOwnerSignatureSelectorNotSet", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "SignerInitialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "SignerUninitialized", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_publicKey", + "type": "bytes" + } + ], + "name": "initializeSigner", + "outputs": [ + { + "internalType": "uint256", + "name": "initSuccess", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_publicKey", + "type": "bytes" + } + ], + "name": "isValidKeyType", + "outputs": [ + { + "internalType": "bool", + "name": "isValid", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_hash", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "_signature", + "type": "bytes" + } + ], + "name": "isValidSignature", + "outputs": [ + { + "internalType": "bytes4", + "name": "magicValue", + "type": "bytes4" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "bytes", + "name": "signer", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "self", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "uninitializeSigner", + "outputs": [ + { + "internalType": "uint256", + "name": "uninitSuccess", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "initCode", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "callGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "verificationGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "preVerificationGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxFeePerGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPriorityFeePerGas", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "paymasterAndData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "internalType": "struct UserOperation", + "name": "userOp", + "type": "tuple" + }, + { + "internalType": "bytes32", + "name": "userOpHash", + "type": "bytes32" + } + ], + "name": "validateOwnerSignature", + "outputs": [ + { + "internalType": "uint256", + "name": "validationData", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "validateOwnerSignatureSelector", + "outputs": [ + { + "internalType": "bytes4", + "name": "ownerSignatureValidatorSelector", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "initCode", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "callGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "verificationGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "preVerificationGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxFeePerGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPriorityFeePerGas", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "paymasterAndData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "internalType": "struct UserOperation", + "name": "userOp", + "type": "tuple" + }, + { + "internalType": "bytes32", + "name": "userOpHash", + "type": "bytes32" + }, + { + "internalType": "uint256[2]", + "name": "q", + "type": "uint256[2]" + } + ], + "name": "validateSignature", + "outputs": [ + { + "internalType": "uint256", + "name": "isValid", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0x60bad0b4b5b208e2f65e937196f4bf3b545d510471507340930daab140686d29", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 42, + "gasUsed": "1809225", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000008000000000000000000000000000000000000000000000000000000000800000000000000000000100000000000000000000000000001000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000201000000000000000000000020000000000000000000000000000000000004200000000000000000001000000000000000000000000000000100000000000000000000000000000000000000000000000000000000020000000000000100000", + "blockHash": "0xd5980e43fa40f45818a1c860e72868b3bd0bd47b553ace64991460aa982ee00e", + "transactionHash": "0x60bad0b4b5b208e2f65e937196f4bf3b545d510471507340930daab140686d29", + "logs": [ + { + "transactionIndex": 42, + "blockNumber": 50172513, + "transactionHash": "0x60bad0b4b5b208e2f65e937196f4bf3b545d510471507340930daab140686d29", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x000000000000000000000000d87df9fd27b9a30fe27e7b294caaa4673f34b6b1", + "0x000000000000000000000000742d13f0b2a19c823bdd362b16305e4704b97a38" + ], + "data": "0x00000000000000000000000000000000000000000000000000e8b3804803e6b0000000000000000000000000000000000000000000000000ba8460976b8ef87e000000000000000000000000000000000000000000001aa580416dafeb384b00000000000000000000000000000000000000000000000000b99bad17238b11ce000000000000000000000000000000000000000000001aa5812a2130333c31b0", + "logIndex": 134, + "blockHash": "0xd5980e43fa40f45818a1c860e72868b3bd0bd47b553ace64991460aa982ee00e" + } + ], + "blockNumber": 50172513, + "cumulativeGasUsed": "6679730", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 3, + "solcInputHash": "4356503edd8ae34e73cb6dd1c8e2fc8a", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"LibAppStorage__AccountMustBeUninitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LibAppStorage__SignerAlreadyUninitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LibAppStorage__SignerMustBeUninitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Secp256r1VerificationFacet__InvalidSignerLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerificationFacet__InitializationFailure\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerificationFacet__InvalidFacetMapping\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerificationFacet__ValidateOwnerSignatureSelectorNotSet\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"SignerInitialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"SignerUninitialized\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_publicKey\",\"type\":\"bytes\"}],\"name\":\"initializeSigner\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"initSuccess\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_publicKey\",\"type\":\"bytes\"}],\"name\":\"isValidKeyType\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isValid\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_hash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"_signature\",\"type\":\"bytes\"}],\"name\":\"isValidSignature\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"magicValue\",\"type\":\"bytes4\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"signer\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"self\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"uninitializeSigner\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"uninitSuccess\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"userOp\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"}],\"name\":\"validateOwnerSignature\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"validationData\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"validateOwnerSignatureSelector\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"ownerSignatureValidatorSelector\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"userOp\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256[2]\",\"name\":\"q\",\"type\":\"uint256[2]\"}],\"name\":\"validateSignature\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"isValid\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Ruslan Serebriakov (@rsrbk)David Yongjun Kim (@Powerstream3604)\",\"details\":\"Primarily used to verify user ops signed with passkeys\",\"kind\":\"dev\",\"methods\":{\"initializeSigner(bytes)\":{\"details\":\"This method checks if the signer has already been initialized. If already initialized, it reverts. It checks if the public key is in the light format and initializes signer storage in k1 storage.\",\"params\":{\"_publicKey\":\"Bytes of owner public key\"},\"returns\":{\"initSuccess\":\"Uint value representing the success of init operation\"}},\"isValidKeyType(bytes)\":{\"details\":\"For this Secp256k1Verification Facet, the public key should in an uncompressed public key format\",\"params\":{\"_publicKey\":\"Bytes of public key for format check\"},\"returns\":{\"isValid\":\"Boolean variable representing if the format of public key is valid\"}},\"isValidSignature(bytes32,bytes)\":{\"details\":\"This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\",\"params\":{\"_hash\":\"Hash value the owner signed\",\"_signature\":\"Signature that signed the above hash\"},\"returns\":{\"magicValue\":\"Bytes4 value representing the success/failure of validation\"}},\"owner()\":{\"returns\":{\"signer\":\"Bytes of owner address\"}},\"uninitializeSigner()\":{\"details\":\"This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\",\"returns\":{\"uninitSuccess\":\"Uint value representing the success of uninit operation\"}},\"validateOwnerSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32)\":{\"details\":\"This method validates if the user operation is signed by the owner. It internally calls validateSignature with signer public key.\",\"params\":{\"userOp\":\"UserOperation including all information for execution\",\"userOpHash\":\"Hash of UserOperation given from EntryPoint. This hash is used for signature validation\"},\"returns\":{\"validationData\":\"Uint value representing whether the validation is successful. 0 for success, 1 for failure\"}},\"validateOwnerSignatureSelector()\":{\"returns\":{\"ownerSignatureValidatorSelector\":\"Bytes4 selector of function signature to validate account owner's UserOperation signature\"}},\"validateSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256[2])\":{\"details\":\"This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\",\"params\":{\"q\":\"Public Key of signer who signed the contract, to be validated\",\"userOp\":\"UserOperation including all information for execution\",\"userOpHash\":\"Hash of UserOperation given from EntryPoint. This hash is used for signature validation\"},\"returns\":{\"isValid\":\"Uint value representing whether the validation is successful. 0 for success, 1 for failure\"}}},\"title\":\"Secp256r1 verification facet\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"This constructor ensures that this contract can only be used as singleton for Proxy contracts\"},\"initializeSigner(bytes)\":{\"notice\":\"Initializes the signer in R1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\"},\"isValidKeyType(bytes)\":{\"notice\":\"Validates if the format of public key is valid for this verification facet\"},\"isValidSignature(bytes32,bytes)\":{\"notice\":\"Validates if the signature is valid. Function to be compatible with EIP-1271\"},\"owner()\":{\"notice\":\"Returns the owner of the account\"},\"uninitializeSigner()\":{\"notice\":\"Uninitialize signer in R1 Facet Storage. This can only be called when the account is undergoing signature migration and has already been initialized.\"},\"validateOwnerSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32)\":{\"notice\":\"Validates if the user operation is signed by the owner.\"},\"validateOwnerSignatureSelector()\":{\"notice\":\"Returns the selector of function to validate the signature of UserOperation\"},\"validateSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256[2])\":{\"notice\":\"Validates if the signature of UserOperation is signed by the given signer\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/verification/secp256r1/Secp256r1VerificationFacet.sol\":\"Secp256r1VerificationFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/utils/math/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\\n * checks.\\n *\\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\\n * easily result in undesired exploitation or bugs, since developers usually\\n * assume that overflows raise errors. `SafeCast` restores this intuition by\\n * reverting the transaction when such an operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n *\\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\\n * all math on `uint256` and `int256` and then downcasting.\\n */\\nlibrary SafeCast {\\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 * _Available since v4.7._\\n */\\n function toUint248(uint256 value) internal pure returns (uint248) {\\n require(value <= type(uint248).max, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint240(uint256 value) internal pure returns (uint240) {\\n require(value <= type(uint240).max, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint232(uint256 value) internal pure returns (uint232) {\\n require(value <= type(uint232).max, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint224(uint256 value) internal pure returns (uint224) {\\n require(value <= type(uint224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint216(uint256 value) internal pure returns (uint216) {\\n require(value <= type(uint216).max, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint208(uint256 value) internal pure returns (uint208) {\\n require(value <= type(uint208).max, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint200(uint256 value) internal pure returns (uint200) {\\n require(value <= type(uint200).max, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint192(uint256 value) internal pure returns (uint192) {\\n require(value <= type(uint192).max, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint184(uint256 value) internal pure returns (uint184) {\\n require(value <= type(uint184).max, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint176(uint256 value) internal pure returns (uint176) {\\n require(value <= type(uint176).max, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint168(uint256 value) internal pure returns (uint168) {\\n require(value <= type(uint168).max, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint160(uint256 value) internal pure returns (uint160) {\\n require(value <= type(uint160).max, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint152(uint256 value) internal pure returns (uint152) {\\n require(value <= type(uint152).max, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint144(uint256 value) internal pure returns (uint144) {\\n require(value <= type(uint144).max, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint136(uint256 value) internal pure returns (uint136) {\\n require(value <= type(uint136).max, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint128(uint256 value) internal pure returns (uint128) {\\n require(value <= type(uint128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint120(uint256 value) internal pure returns (uint120) {\\n require(value <= type(uint120).max, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint112(uint256 value) internal pure returns (uint112) {\\n require(value <= type(uint112).max, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint104(uint256 value) internal pure returns (uint104) {\\n require(value <= type(uint104).max, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.2._\\n */\\n function toUint96(uint256 value) internal pure returns (uint96) {\\n require(value <= type(uint96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint88(uint256 value) internal pure returns (uint88) {\\n require(value <= type(uint88).max, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint80(uint256 value) internal pure returns (uint80) {\\n require(value <= type(uint80).max, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint72(uint256 value) internal pure returns (uint72) {\\n require(value <= type(uint72).max, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint64(uint256 value) internal pure returns (uint64) {\\n require(value <= type(uint64).max, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint56(uint256 value) internal pure returns (uint56) {\\n require(value <= type(uint56).max, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint48(uint256 value) internal pure returns (uint48) {\\n require(value <= type(uint48).max, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint40(uint256 value) internal pure returns (uint40) {\\n require(value <= type(uint40).max, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint32(uint256 value) internal pure returns (uint32) {\\n require(value <= type(uint32).max, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toUint24(uint256 value) internal pure returns (uint24) {\\n require(value <= type(uint24).max, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint16(uint256 value) internal pure returns (uint16) {\\n require(value <= type(uint16).max, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v2.5._\\n */\\n function toUint8(uint256 value) internal pure returns (uint8) {\\n require(value <= type(uint8).max, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\n */\\n function toUint256(int256 value) internal pure returns (uint256) {\\n require(value >= 0, \\\"SafeCast: value must be positive\\\");\\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 * _Available since v4.7._\\n */\\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\\n downcasted = int248(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\\n downcasted = int240(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\\n downcasted = int232(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\\n downcasted = int224(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\\n downcasted = int216(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\\n downcasted = int208(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\\n downcasted = int200(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\\n downcasted = int192(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\\n downcasted = int184(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\\n downcasted = int176(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\\n downcasted = int168(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\\n downcasted = int160(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\\n downcasted = int152(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\\n downcasted = int144(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\\n downcasted = int136(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\\n downcasted = int128(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\\n downcasted = int120(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\\n downcasted = int112(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\\n downcasted = int104(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\\n downcasted = int96(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\\n downcasted = int88(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\\n downcasted = int80(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\\n downcasted = int72(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\\n downcasted = int64(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\\n downcasted = int56(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\\n downcasted = int48(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\\n downcasted = int40(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\\n downcasted = int32(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\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 * _Available since v4.7._\\n */\\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\\n downcasted = int24(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\\n downcasted = int16(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\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 * _Available since v3.1._\\n */\\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\\n downcasted = int8(value);\\n require(downcasted == value, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\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 * _Available since v3.0._\\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 require(value <= uint256(type(int256).max), \\\"SafeCast: value doesn't fit in an int256\\\");\\n return int256(value);\\n }\\n}\\n\",\"keccak256\":\"0x52a8cfb0f5239d11b457dcdd1b326992ef672714ca8da71a157255bddd13f3ad\",\"license\":\"MIT\"},\"contracts/aa-4337/core/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n/* solhint-disable no-inline-assembly */\\n\\n/**\\n * returned data from validateUserOp.\\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\\n * @param aggregator - address(0) - the account validated the signature by itself.\\n * address(1) - the account failed to validate the signature.\\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\\n * @param validAfter - this UserOp is valid only after this timestamp.\\n * @param validaUntil - this UserOp is valid only up to this timestamp.\\n */\\nstruct ValidationData {\\n address aggregator;\\n uint48 validAfter;\\n uint48 validUntil;\\n}\\n\\n//extract sigFailed, validAfter, validUntil.\\n// also convert zero validUntil to type(uint48).max\\nfunction _parseValidationData(\\n uint validationData\\n) pure returns (ValidationData memory data) {\\n address aggregator = address(uint160(validationData));\\n uint48 validUntil = uint48(validationData >> 160);\\n if (validUntil == 0) {\\n validUntil = type(uint48).max;\\n }\\n uint48 validAfter = uint48(validationData >> (48 + 160));\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n// intersect account and paymaster ranges.\\nfunction _intersectTimeRange(\\n uint256 validationData,\\n uint256 paymasterValidationData\\n) pure returns (ValidationData memory) {\\n ValidationData memory accountValidationData = _parseValidationData(\\n validationData\\n );\\n ValidationData memory pmValidationData = _parseValidationData(\\n paymasterValidationData\\n );\\n address aggregator = accountValidationData.aggregator;\\n if (aggregator == address(0)) {\\n aggregator = pmValidationData.aggregator;\\n }\\n uint48 validAfter = accountValidationData.validAfter;\\n uint48 validUntil = accountValidationData.validUntil;\\n uint48 pmValidAfter = pmValidationData.validAfter;\\n uint48 pmValidUntil = pmValidationData.validUntil;\\n\\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\\n return ValidationData(aggregator, validAfter, validUntil);\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp\\n * @param data - the ValidationData to pack\\n */\\nfunction _packValidationData(\\n ValidationData memory data\\n) pure returns (uint256) {\\n return\\n uint160(data.aggregator) |\\n (uint256(data.validUntil) << 160) |\\n (uint256(data.validAfter) << (160 + 48));\\n}\\n\\n/**\\n * helper to pack the return value for validateUserOp, when not using an aggregator\\n * @param sigFailed - true for signature failure, false for success\\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\\n * @param validAfter first timestamp this UserOperation is valid\\n */\\nfunction _packValidationData(\\n bool sigFailed,\\n uint48 validUntil,\\n uint48 validAfter\\n) pure returns (uint256) {\\n return\\n (sigFailed ? 1 : 0) |\\n (uint256(validUntil) << 160) |\\n (uint256(validAfter) << (160 + 48));\\n}\\n\\n/**\\n * keccak function over calldata.\\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\\n */\\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\\n assembly {\\n let mem := mload(0x40)\\n let len := data.length\\n calldatacopy(mem, data.offset, len)\\n ret := keccak256(mem, len)\\n }\\n}\\n\",\"keccak256\":\"0xa79f06cd158ecb8c0da95493a2f348933b8627a63e228b99738bff3aa107942d\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IAggregator.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\n/**\\n * Aggregated Signatures validator.\\n */\\ninterface IAggregator {\\n /**\\n * validate aggregated signature.\\n * revert if the aggregated signature does not match the given list of operations.\\n */\\n function validateSignatures(\\n UserOperation[] calldata userOps,\\n bytes calldata signature\\n ) external view;\\n\\n /**\\n * validate signature of a single userOp\\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\\n * @param userOp the userOperation received from the user.\\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\\n * (usually empty, unless account and aggregator support some kind of \\\"multisig\\\"\\n */\\n function validateUserOpSignature(\\n UserOperation calldata userOp\\n ) external view returns (bytes memory sigForUserOp);\\n\\n /**\\n * aggregate multiple signatures into a single value.\\n * This method is called off-chain to calculate the signature to pass with handleOps()\\n * bundler MAY use optimized custom code perform this aggregation\\n * @param userOps array of UserOperations to collect the signatures from.\\n * @return aggregatedSignature the aggregated signature\\n */\\n function aggregateSignatures(\\n UserOperation[] calldata userOps\\n ) external view returns (bytes memory aggregatedSignature);\\n}\\n\",\"keccak256\":\"0xdfdcd80568f037716674619b31be630fcd8316262f05a815b41d1e81782c966a\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IEntryPoint.sol\":{\"content\":\"/**\\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\\n ** Only one instance required on each chain.\\n **/\\n// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-inline-assembly */\\n/* solhint-disable reason-string */\\n\\nimport \\\"./UserOperation.sol\\\";\\nimport \\\"./IStakeManager.sol\\\";\\nimport \\\"./IAggregator.sol\\\";\\nimport \\\"./INonceManager.sol\\\";\\n\\ninterface IEntryPoint is IStakeManager, INonceManager {\\n /***\\n * An event emitted after each successful request\\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\\n * @param sender - the account that generates this request.\\n * @param paymaster - if non-null, the paymaster that pays for this request.\\n * @param nonce - the nonce value from the request.\\n * @param success - true if the sender transaction succeeded, false if reverted.\\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\\n */\\n event UserOperationEvent(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address indexed paymaster,\\n uint256 nonce,\\n bool success,\\n uint256 actualGasCost,\\n uint256 actualGasUsed\\n );\\n\\n /**\\n * account \\\"sender\\\" was deployed.\\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\\n * @param sender the account that is deployed\\n * @param factory the factory used to deploy this account (in the initCode)\\n * @param paymaster the paymaster used by this UserOp\\n */\\n event AccountDeployed(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n address factory,\\n address paymaster\\n );\\n\\n /**\\n * An event emitted if the UserOperation \\\"callData\\\" reverted with non-zero length\\n * @param userOpHash the request unique identifier.\\n * @param sender the sender of this request\\n * @param nonce the nonce used in the request\\n * @param revertReason - the return bytes from the (reverted) call to \\\"callData\\\".\\n */\\n event UserOperationRevertReason(\\n bytes32 indexed userOpHash,\\n address indexed sender,\\n uint256 nonce,\\n bytes revertReason\\n );\\n\\n /**\\n * an event emitted by handleOps(), before starting the execution loop.\\n * any event emitted before this event, is part of the validation.\\n */\\n event BeforeExecution();\\n\\n /**\\n * signature aggregator used by the following UserOperationEvents within this bundle.\\n */\\n event SignatureAggregatorChanged(address indexed aggregator);\\n\\n /**\\n * a custom revert error of handleOps, to identify the offending op.\\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\\n * @param reason - revert reason\\n * The string starts with a unique code \\\"AAmn\\\", where \\\"m\\\" is \\\"1\\\" for factory, \\\"2\\\" for account and \\\"3\\\" for paymaster issues,\\n * so a failure can be attributed to the correct entity.\\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\\n */\\n error FailedOp(uint256 opIndex, string reason);\\n\\n /**\\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\\n */\\n error SignatureValidationFailed(address aggregator);\\n\\n /**\\n * Successful result from simulateValidation.\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n */\\n error ValidationResult(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo\\n );\\n\\n /**\\n * Successful result from simulateValidation, if the account returns a signature aggregator\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\\n * bundler MUST use it to verify the signature, or reject the UserOperation\\n */\\n error ValidationResultWithAggregation(\\n ReturnInfo returnInfo,\\n StakeInfo senderInfo,\\n StakeInfo factoryInfo,\\n StakeInfo paymasterInfo,\\n AggregatorStakeInfo aggregatorInfo\\n );\\n\\n /**\\n * return value of getSenderAddress\\n */\\n error SenderAddressResult(address sender);\\n\\n /**\\n * return value of simulateHandleOp\\n */\\n error ExecutionResult(\\n uint256 preOpGas,\\n uint256 paid,\\n uint48 validAfter,\\n uint48 validUntil,\\n bool targetSuccess,\\n bytes targetResult\\n );\\n\\n //UserOps handled, per aggregator\\n struct UserOpsPerAggregator {\\n UserOperation[] userOps;\\n // aggregator address\\n IAggregator aggregator;\\n // aggregated signature\\n bytes signature;\\n }\\n\\n /**\\n * Execute a batch of UserOperation.\\n * no signature aggregator is used.\\n * if any account requires an aggregator (that is, it returned an aggregator when\\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\\n * @param ops the operations to execute\\n * @param beneficiary the address to receive the fees\\n */\\n function handleOps(\\n UserOperation[] calldata ops,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * Execute a batch of UserOperation with Aggregators\\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\\n * @param beneficiary the address to receive the fees\\n */\\n function handleAggregatedOps(\\n UserOpsPerAggregator[] calldata opsPerAggregator,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * generate a request Id - unique identifier for this request.\\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\\n */\\n function getUserOpHash(\\n UserOperation calldata userOp\\n ) external view returns (bytes32);\\n\\n /**\\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\\n * @param userOp the user operation to validate.\\n */\\n function simulateValidation(UserOperation calldata userOp) external;\\n\\n /**\\n * gas and return values during simulation\\n * @param preOpGas the gas used for validation (including preValidationGas)\\n * @param prefund the required prefund for this operation\\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\\n */\\n struct ReturnInfo {\\n uint256 preOpGas;\\n uint256 prefund;\\n bool sigFailed;\\n uint48 validAfter;\\n uint48 validUntil;\\n bytes paymasterContext;\\n }\\n\\n /**\\n * returned aggregated signature info.\\n * the aggregator returned by the account, and its current stake.\\n */\\n struct AggregatorStakeInfo {\\n address aggregator;\\n StakeInfo stakeInfo;\\n }\\n\\n /**\\n * Get counterfactual sender address.\\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\\n * this method always revert, and returns the address in SenderAddressResult error\\n * @param initCode the constructor code to be passed into the UserOperation.\\n */\\n function getSenderAddress(bytes memory initCode) external;\\n\\n /**\\n * simulate full execution of a UserOperation (including both validation and target execution)\\n * this method will always revert with \\\"ExecutionResult\\\".\\n * it performs full validation of the UserOperation, but ignores signature error.\\n * an optional target address is called after the userop succeeds, and its value is returned\\n * (before the entire call is reverted)\\n * Note that in order to collect the the success/failure of the target call, it must be executed\\n * with trace enabled to track the emitted events.\\n * @param op the UserOperation to simulate\\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\\n * are set to the return from that call.\\n * @param targetCallData callData to pass to target address\\n */\\n function simulateHandleOp(\\n UserOperation calldata op,\\n address target,\\n bytes calldata targetCallData\\n ) external;\\n}\\n\",\"keccak256\":\"0x9ccb1b188eda8bbf5f6c2d01bd83c3d8b2b04fcf745283051d31fe96d1d8e40f\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/INonceManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\ninterface INonceManager {\\n /**\\n * Return the next nonce for this sender.\\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\\n * But UserOp with different keys can come with arbitrary order.\\n *\\n * @param sender the account address\\n * @param key the high 192 bit of the nonce\\n * @return nonce a full nonce to pass for next UserOp with this sender.\\n */\\n function getNonce(\\n address sender,\\n uint192 key\\n ) external view returns (uint256 nonce);\\n\\n /**\\n * Manually increment the nonce of the sender.\\n * This method is exposed just for completeness..\\n * Account does NOT need to call it, neither during validation, nor elsewhere,\\n * as the EntryPoint will update the nonce regardless.\\n * Possible use-case is call it with various keys to \\\"initialize\\\" their nonces to one, so that future\\n * UserOperations will not pay extra for the first transaction with a given key.\\n */\\n function incrementNonce(uint192 key) external;\\n}\\n\",\"keccak256\":\"0xce478ad0fa0d18a3b785ac854623029e7ab463d05873dfaa365abfa1bf100912\",\"license\":\"GPL-3.0\"},\"contracts/aa-4337/interfaces/IStakeManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8.12;\\n\\n/**\\n * manage deposits and stakes.\\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\\n * stake is value locked for at least \\\"unstakeDelay\\\" by the staked entity.\\n */\\ninterface IStakeManager {\\n event Deposited(address indexed account, uint256 totalDeposit);\\n\\n event Withdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /// Emitted when stake or unstake delay are modified\\n event StakeLocked(\\n address indexed account,\\n uint256 totalStaked,\\n uint256 unstakeDelaySec\\n );\\n\\n /// Emitted once a stake is scheduled for withdrawal\\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\\n\\n event StakeWithdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /**\\n * @param deposit the entity's deposit\\n * @param staked true if this entity is staked.\\n * @param stake actual amount of ether staked for this entity.\\n * @param unstakeDelaySec minimum delay to withdraw the stake.\\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\\n * and the rest fit into a 2nd cell.\\n * 112 bit allows for 10^15 eth\\n * 48 bit for full timestamp\\n * 32 bit allows 150 years for unstake delay\\n */\\n struct DepositInfo {\\n uint112 deposit;\\n bool staked;\\n uint112 stake;\\n uint32 unstakeDelaySec;\\n uint48 withdrawTime;\\n }\\n\\n //API struct used by getStakeInfo and simulateValidation\\n struct StakeInfo {\\n uint256 stake;\\n uint256 unstakeDelaySec;\\n }\\n\\n /// @return info - full deposit information of given account\\n function getDepositInfo(\\n address account\\n ) external view returns (DepositInfo memory info);\\n\\n /// @return the deposit (for gas payment) of the account\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * add to the deposit of the given account\\n */\\n function depositTo(address account) external payable;\\n\\n /**\\n * add to the account's stake - amount and delay\\n * any pending unstake is first cancelled.\\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\\n */\\n function addStake(uint32 _unstakeDelaySec) external payable;\\n\\n /**\\n * attempt to unlock the stake.\\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\\n */\\n function unlockStake() external;\\n\\n /**\\n * withdraw from the (unlocked) stake.\\n * must first call unlockStake and wait for the unstakeDelay to pass\\n * @param withdrawAddress the address to send withdrawn value.\\n */\\n function withdrawStake(address payable withdrawAddress) external;\\n\\n /**\\n * withdraw from the deposit.\\n * @param withdrawAddress the address to send withdrawn value.\\n * @param withdrawAmount the amount to withdraw.\\n */\\n function withdrawTo(\\n address payable withdrawAddress,\\n uint256 withdrawAmount\\n ) external;\\n}\\n\",\"keccak256\":\"0xadcea606c9b7aafe6645441f2154a60f271330b0eee5292a632aa71c1672d546\",\"license\":\"GPL-3.0-only\"},\"contracts/aa-4337/interfaces/UserOperation.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable no-inline-assembly */\\n\\nimport {calldataKeccak} from \\\"../core/Helpers.sol\\\";\\n\\n/**\\n * User Operation struct\\n * @param sender the sender account of this request.\\n * @param nonce unique value the sender uses to verify it is not a replay.\\n * @param initCode if set, the account contract will be created by this constructor/\\n * @param callData the method call to execute on this account.\\n * @param callGasLimit the gas limit passed to the callData method call.\\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\\n * @param maxFeePerGas same as EIP-1559 gas parameter.\\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\\n */\\nstruct UserOperation {\\n address sender;\\n uint256 nonce;\\n bytes initCode;\\n bytes callData;\\n uint256 callGasLimit;\\n uint256 verificationGasLimit;\\n uint256 preVerificationGas;\\n uint256 maxFeePerGas;\\n uint256 maxPriorityFeePerGas;\\n bytes paymasterAndData;\\n bytes signature;\\n}\\n\\n/**\\n * Utility functions helpful when working with UserOperation structs.\\n */\\nlibrary UserOperationLib {\\n function getSender(\\n UserOperation calldata userOp\\n ) internal pure returns (address) {\\n address data;\\n //read sender from userOp, which is first userOp member (saves 800 gas...)\\n assembly {\\n data := calldataload(userOp)\\n }\\n return address(uint160(data));\\n }\\n\\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\\n // pay above what he signed for.\\n function gasPrice(\\n UserOperation calldata userOp\\n ) internal view returns (uint256) {\\n unchecked {\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n if (maxFeePerGas == maxPriorityFeePerGas) {\\n //legacy mode (for networks that don't support basefee opcode)\\n return maxFeePerGas;\\n }\\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\\n }\\n }\\n\\n function pack(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes memory ret) {\\n address sender = getSender(userOp);\\n uint256 nonce = userOp.nonce;\\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\\n bytes32 hashCallData = calldataKeccak(userOp.callData);\\n uint256 callGasLimit = userOp.callGasLimit;\\n uint256 verificationGasLimit = userOp.verificationGasLimit;\\n uint256 preVerificationGas = userOp.preVerificationGas;\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\\n\\n return\\n abi.encode(\\n sender,\\n nonce,\\n hashInitCode,\\n hashCallData,\\n callGasLimit,\\n verificationGasLimit,\\n preVerificationGas,\\n maxFeePerGas,\\n maxPriorityFeePerGas,\\n hashPaymasterAndData\\n );\\n }\\n\\n function hash(\\n UserOperation calldata userOp\\n ) internal pure returns (bytes32) {\\n return keccak256(pack(userOp));\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n}\\n\",\"keccak256\":\"0x2429f5cc546bdee08c7e63858d0dda8491eaa3ab5194df884dc948c1154d2834\",\"license\":\"GPL-3.0\"},\"contracts/facets/base/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title DiamondCut Facet Interface\\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IDiamondCut {\\n error DiamondCutFacet__InvalidRouteWithGuardian();\\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\\n error DiamondCutFacet__InvalidArrayLength();\\n error DiamondCutFacet__InsufficientApprovers();\\n error DiamondCutFacet__InvalidApprover();\\n error DiamondCutFacet__InvalidApproverSignature();\\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\\n error DiamondCutFacet__CannotRevokeUnapproved();\\n error DiamondCutFacet__LackOfOwnerApproval();\\n error DiamondCutFacet__OwnerAlreadyApproved();\\n error DiamondCutFacet__DuplicateApproval();\\n error DiamondCutFacet__InvalidInitAddress();\\n\\n event DiamondCutApproved(FacetCut[] diamondCut);\\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\\n\\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\\n\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param diamondCut Contains the facet addresses and function selectors\\n /// @param init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata diamondCut,\\n address init,\\n bytes calldata _calldata\\n ) external;\\n\\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\\n\\n function diamondCutWithGuardian(\\n FacetCut[] calldata diamondCut,\\n address[] calldata approvers,\\n bytes[] calldata signatures\\n ) external;\\n\\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\\n\\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\\n\\n function getDiamondCutApprovalCountWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (uint256);\\n\\n function getOwnerCutApprovalWithTimeValidity(\\n bytes32 diamondCutHash\\n ) external view returns (bool);\\n\\n function isCutApproved(\\n bytes32 diamondCutHash,\\n address approver\\n ) external view returns (bool);\\n\\n function getDiamondCutHash(\\n FacetCut[] calldata diamondCut\\n ) external view returns (bytes32);\\n\\n function getDiamondCutNonce() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x8514213c7677c2122bda0721870b08decaddb68841cb1d6a87b89b04e8f43e1e\",\"license\":\"Apache-2.0\"},\"contracts/facets/base/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n external\\n view\\n returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xd84f7fbb1344f714bceab2c71e4a25a235e3c1457fe7eba6c5538cd95ef5fc0f\",\"license\":\"Apache-2.0\"},\"contracts/facets/interfaces/IVerificationFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {UserOperation} from \\\"../../aa-4337/interfaces/UserOperation.sol\\\";\\n\\n/**\\n * @title Verification Facet Interface\\n * @dev Implements logic for user ops signature verification\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\ninterface IVerificationFacet {\\n event SignerInitialized(bytes);\\n event SignerUninitialized();\\n\\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\\n error VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\\n error VerificationFacet__InitializationFailure();\\n error VerificationFacet__InvalidFacetMapping();\\n\\n function initializeSigner(bytes memory) external returns (uint256);\\n\\n function uninitializeSigner() external returns (uint256);\\n\\n function validateOwnerSignatureSelector() external view returns (bytes4);\\n\\n function owner() external view returns (bytes memory);\\n\\n function isValidKeyType(bytes calldata) external view returns (bool);\\n\\n function validateOwnerSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x72bc370a1d1b5a6d6bde67f5026733fd8f6ba434bb90e73b0bd8627fb1579928\",\"license\":\"Apache-2.0\"},\"contracts/facets/verification/secp256r1/Secp256r1VerificationFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {UserOperation} from \\\"../../../aa-4337/interfaces/UserOperation.sol\\\";\\nimport {LibAppStorage} from \\\"../../../libraries/LibAppStorage.sol\\\";\\nimport {LibLoupe} from \\\"../../../libraries/LibLoupe.sol\\\";\\nimport {LibFacetStorage, Secp256r1VerificationStorage} from \\\"../../../libraries/LibFacetStorage.sol\\\";\\nimport {Base64} from \\\"./utils/Base64.sol\\\";\\nimport {LibSecp256r1} from \\\"./utils/LibSecp256r1.sol\\\";\\nimport {IERC1271} from \\\"../../../interfaces/ERC/IERC1271.sol\\\";\\nimport {IVerificationFacet} from \\\"../../interfaces/IVerificationFacet.sol\\\";\\n\\n/**\\n * @title Secp256r1 verification facet\\n * @dev Primarily used to verify user ops signed with passkeys\\n * @author Ruslan Serebriakov (@rsrbk)\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract Secp256r1VerificationFacet is IVerificationFacet, IERC1271 {\\n error Secp256r1VerificationFacet__InvalidSignerLength();\\n address public immutable self;\\n\\n /**\\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\\n */\\n constructor() {\\n LibAppStorage.enforceSignerInitialize();\\n self = address(this);\\n }\\n\\n /**\\n * @notice Initializes the signer in R1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\\n * @param _publicKey Bytes of owner public key\\n * @return initSuccess Uint value representing the success of init operation\\n */\\n function initializeSigner(\\n bytes calldata _publicKey\\n ) public override returns (uint256 initSuccess) {\\n LibAppStorage.enforceSignerInitialize();\\n\\n if (!isValidKeyType(_publicKey))\\n revert Secp256r1VerificationFacet__InvalidSignerLength();\\n\\n bytes memory publicKeyCoordinates = _publicKey[1:];\\n uint256[2] memory q;\\n assembly {\\n // Copy the bytes from the input data into the uint256 array\\n mstore(q, mload(add(publicKeyCoordinates, 32)))\\n mstore(add(q, 32), mload(add(publicKeyCoordinates, 64)))\\n }\\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\\n .r1Storage();\\n r1Storage.q = q;\\n\\n bytes4 validateSelector = validateOwnerSignatureSelector();\\n\\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\\n if (LibLoupe.facetAddress(validateSelector) != self)\\n revert VerificationFacet__InvalidFacetMapping();\\n\\n // initialize verification function selector\\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\\n\\n initSuccess = 1;\\n\\n emit SignerInitialized(_publicKey);\\n }\\n\\n /**\\n * @notice Uninitialize signer in R1 Facet Storage. This can only be called when the account is undergoing signature migration\\n * and has already been initialized.\\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\\n * @return uninitSuccess Uint value representing the success of uninit operation\\n */\\n function uninitializeSigner()\\n external\\n override\\n returns (uint256 uninitSuccess)\\n {\\n LibAppStorage.enforceSignerMigration();\\n LibAppStorage.setSignerUninitialized();\\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\\n .r1Storage();\\n r1Storage.q = [0, 0];\\n\\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\\n\\n uninitSuccess = 1;\\n\\n emit SignerUninitialized();\\n }\\n\\n /**\\n * @notice Validates if the user operation is signed by the owner.\\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\\n * signer public key.\\n * @param userOp UserOperation including all information for execution\\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\\n */\\n function validateOwnerSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash\\n ) public view override returns (uint256 validationData) {\\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\\n .r1Storage();\\n validationData = validateSignature(userOp, userOpHash, r1Storage.q);\\n }\\n\\n /**\\n * @notice Validates if the signature of UserOperation is signed by the given signer\\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\\n * @param userOp UserOperation including all information for execution\\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\\n * @param q Public Key of signer who signed the contract, to be validated\\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\\n */\\n function validateSignature(\\n UserOperation calldata userOp,\\n bytes32 userOpHash,\\n uint256[2] memory q\\n ) public view returns (uint256 isValid) {\\n isValid = (_validateSignature(q, userOpHash, userOp.signature)) ? 0 : 1;\\n }\\n\\n /**\\n * @notice Returns the selector of function to validate the signature of UserOperation\\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\\n */\\n function validateOwnerSignatureSelector()\\n public\\n pure\\n override\\n returns (bytes4 ownerSignatureValidatorSelector)\\n {\\n return this.validateOwnerSignature.selector; // validateOwnerSignature(UserOperation calldata userOp,bytes32 userOpHash)\\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\\n }\\n\\n /**\\n * @notice Returns the owner of the account\\n * @return signer Bytes of owner address\\n */\\n function owner() public view override returns (bytes memory signer) {\\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\\n .r1Storage();\\n signer = abi.encodePacked(r1Storage.q);\\n }\\n\\n /**\\n * @notice Validates if the format of public key is valid for this verification facet\\n * @dev For this Secp256k1Verification Facet, the public key should in an uncompressed public key format\\n * @param _publicKey Bytes of public key for format check\\n * @return isValid Boolean variable representing if the format of public key is valid\\n */\\n function isValidKeyType(\\n bytes memory _publicKey\\n ) public pure override returns (bool isValid) {\\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\\n }\\n\\n /**\\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\\n * @param _hash Hash value the owner signed\\n * @param _signature Signature that signed the above hash\\n * @return magicValue Bytes4 value representing the success/failure of validation\\n */\\n function isValidSignature(\\n bytes32 _hash,\\n bytes memory _signature\\n ) public view override returns (bytes4 magicValue) {\\n magicValue = _validateSignature(\\n LibFacetStorage.r1Storage().q,\\n _hash,\\n _signature\\n )\\n ? this.isValidSignature.selector\\n : bytes4(0xffffffff);\\n }\\n\\n function _validateSignature(\\n uint256[2] memory q,\\n bytes32 _hash,\\n bytes memory _signature\\n ) internal view returns (bool) {\\n (\\n uint256 rValue,\\n uint256 sValue,\\n bytes memory authenticatorData,\\n string memory clientDataJSONPre,\\n string memory clientDataJSONPost\\n ) = abi.decode(_signature, (uint256, uint256, bytes, string, string));\\n bytes32 clientHash;\\n {\\n string memory opHashBase64 = Base64.encode(bytes.concat(_hash));\\n string memory clientDataJSON = string.concat(\\n clientDataJSONPre,\\n opHashBase64,\\n clientDataJSONPost\\n );\\n clientHash = sha256(bytes(clientDataJSON));\\n }\\n bytes32 sigHash = sha256(bytes.concat(authenticatorData, clientHash));\\n return LibSecp256r1.Verify(q, rValue, sValue, uint256(sigHash));\\n }\\n}\\n\",\"keccak256\":\"0xdb3bae77323eef4e16ef5a5342f548527c9e82b44e8e9dab90906dc2c00082ff\",\"license\":\"Apache-2.0\"},\"contracts/facets/verification/secp256r1/utils/Base64.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @dev Provides a set of functions to operate with Base64 strings.\\n * modified for base64url https://datatracker.ietf.org/doc/html/rfc4648#section-5\\n * _Available since v4.5._\\n */\\nlibrary Base64 {\\n /**\\n * @dev Base64 Encoding/Decoding Table\\n */\\n string internal constant _TABLE =\\n \\\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_\\\";\\n\\n /**\\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\\n */\\n function encode(bytes memory data) internal pure returns (string memory) {\\n /**\\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\\n */\\n if (data.length == 0) return \\\"\\\";\\n\\n // Loads the table into memory\\n string memory table = _TABLE;\\n\\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\\n // and split into 4 numbers of 6 bits.\\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\\n // - `data.length + 2` -> Round up\\n // - `/ 3` -> Number of 3-bytes chunks\\n // - `4 *` -> 4 characters for each chunk\\n uint256 newlength = (data.length * 8) / 6;\\n if (data.length % 6 > 0) {\\n newlength++;\\n }\\n string memory result = new string(newlength);\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n // Prepare the lookup table (skip the first \\\"length\\\" byte)\\n let tablePtr := add(table, 1)\\n\\n // Prepare result pointer, jump over length\\n let resultPtr := add(result, 32)\\n\\n // Run over the input, 3 bytes at a time\\n for {\\n let dataPtr := data\\n let endPtr := add(data, mload(data))\\n } lt(dataPtr, endPtr) {\\n\\n } {\\n // Advance 3 bytes\\n dataPtr := add(dataPtr, 3)\\n let input := mload(dataPtr)\\n\\n // To write each character, shift the 3 bytes (18 bits) chunk\\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\\n // and apply logical AND with 0x3F which is the number of\\n // the previous character in the ASCII table prior to the Base64 Table\\n // The result is then added to the table to get the character to write,\\n // and finally write it in the result pointer but with a left shift\\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\\n\\n mstore8(\\n resultPtr,\\n mload(add(tablePtr, and(shr(18, input), 0x3F)))\\n )\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(\\n resultPtr,\\n mload(add(tablePtr, and(shr(12, input), 0x3F)))\\n )\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(\\n resultPtr,\\n mload(add(tablePtr, and(shr(6, input), 0x3F)))\\n )\\n resultPtr := add(resultPtr, 1) // Advance\\n\\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\\n resultPtr := add(resultPtr, 1) // Advance\\n }\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0xbf0afa21e5a128f260c1a8d4333dc0b0e8755a50d37dfa9b5d362d36ef9cdc14\",\"license\":\"Apache-2.0\"},\"contracts/facets/verification/secp256r1/utils/LibSecp256r1.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity 0.8.21;\\n\\n// Heavily inspired from\\n// https://github.com/maxrobot/elliptic-solidity/blob/master/contracts/Secp256r1.sol\\n// https://github.com/tdrerup/elliptic-curve-solidity/blob/master/contracts/curves/EllipticCurve.sol\\n// modified to use precompile 0x05 modexp\\n// and modified jacobian double\\n// optimisations to avoid to an from from affine and jacobian coordinates\\n\\n// Additional Elliptic curve Public key / Signature validation added by\\n// David Yonjun Kim (@Powerstream3604)\\n\\nstruct JPoint {\\n uint256 x;\\n uint256 y;\\n uint256 z;\\n}\\n\\nlibrary LibSecp256r1 {\\n uint256 constant gx =\\n 0x6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296;\\n uint256 constant gy =\\n 0x4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5;\\n uint256 public constant pp =\\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF;\\n\\n uint256 public constant nn =\\n 0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551;\\n uint256 constant a =\\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC;\\n uint256 constant b =\\n 0x5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B;\\n uint256 constant MOST_SIGNIFICANT =\\n 0xc000000000000000000000000000000000000000000000000000000000000000;\\n\\n /*\\n * Verify\\n * @description - verifies that a public key has signed a given message\\n * @param Q - public key coordinates X & Y\\n * @param R - signature half R\\n * @param S - signature half S\\n * @param input - hashed message\\n */\\n function Verify(\\n uint256[2] memory q,\\n uint r,\\n uint s,\\n uint e\\n ) internal view returns (bool) {\\n if (q[0] > pp - 1 || q[1] > pp - 1) {\\n return false;\\n }\\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\\n return false;\\n }\\n if (\\n mulmod(q[1], q[1], pp) !=\\n addmod(\\n addmod(\\n mulmod(q[0], mulmod(q[0], q[0], pp), pp),\\n mulmod(a, q[0], pp),\\n pp\\n ),\\n b,\\n pp\\n )\\n ) {\\n return false;\\n }\\n\\n JPoint[16] memory points = _preComputeJacobianPoints(q);\\n return VerifyWithPrecompute(points, r, s, e);\\n }\\n\\n function VerifyWithPrecompute(\\n JPoint[16] memory points,\\n uint r,\\n uint s,\\n uint e\\n ) internal view returns (bool) {\\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\\n return false;\\n }\\n\\n uint w = _primemod(s, nn);\\n\\n uint u1 = mulmod(e, w, nn);\\n uint u2 = mulmod(r, w, nn);\\n\\n uint x;\\n uint y;\\n\\n (x, y) = ShamirMultJacobian(points, u1, u2);\\n return (x == r);\\n }\\n\\n /*\\n * Strauss Shamir trick for EC multiplication\\n * https://stackoverflow.com/questions/50993471/ec-scalar-multiplication-with-strauss-shamir-method\\n * we optimise on this a bit to do with 2 bits at a time rather than a single bit\\n * the individual points for a single pass are precomputed\\n * overall this reduces the number of additions while keeping the same number of doublings\\n */\\n function ShamirMultJacobian(\\n JPoint[16] memory points,\\n uint u1,\\n uint u2\\n ) internal view returns (uint, uint) {\\n uint x = 0;\\n uint y = 0;\\n uint z = 0;\\n uint bits = 128;\\n uint index = 0;\\n\\n while (bits > 0) {\\n if (z > 0) {\\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\\n }\\n index =\\n ((u1 & MOST_SIGNIFICANT) >> 252) |\\n ((u2 & MOST_SIGNIFICANT) >> 254);\\n if (index > 0) {\\n (x, y, z) = _jAdd(\\n x,\\n y,\\n z,\\n points[index].x,\\n points[index].y,\\n points[index].z\\n );\\n }\\n u1 <<= 2;\\n u2 <<= 2;\\n bits--;\\n }\\n (x, y) = _affineFromJacobian(x, y, z);\\n return (x, y);\\n }\\n\\n function _preComputeJacobianPoints(\\n uint256[2] memory q\\n ) internal pure returns (JPoint[16] memory points) {\\n points[0] = JPoint(0, 0, 0);\\n points[1] = JPoint(q[0], q[1], 1); // u2\\n points[2] = _jPointDouble(points[1]);\\n points[3] = _jPointAdd(points[1], points[2]);\\n\\n points[4] = JPoint(gx, gy, 1); // u1Points[1]\\n points[5] = _jPointAdd(points[4], points[1]);\\n points[6] = _jPointAdd(points[4], points[2]);\\n points[7] = _jPointAdd(points[4], points[3]);\\n\\n points[8] = _jPointDouble(points[4]); // u1Points[2]\\n points[9] = _jPointAdd(points[8], points[1]);\\n points[10] = _jPointAdd(points[8], points[2]);\\n points[11] = _jPointAdd(points[8], points[3]);\\n\\n points[12] = _jPointAdd(points[4], points[8]); // u1Points[3]\\n points[13] = _jPointAdd(points[12], points[1]);\\n points[14] = _jPointAdd(points[12], points[2]);\\n points[15] = _jPointAdd(points[12], points[3]);\\n }\\n\\n function _jPointAdd(\\n JPoint memory p1,\\n JPoint memory p2\\n ) internal pure returns (JPoint memory) {\\n uint x;\\n uint y;\\n uint z;\\n (x, y, z) = _jAdd(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z);\\n return JPoint(x, y, z);\\n }\\n\\n function _jPointDouble(\\n JPoint memory p\\n ) internal pure returns (JPoint memory) {\\n uint x;\\n uint y;\\n uint z;\\n (x, y, z) = _modifiedJacobianDouble(p.x, p.y, p.z);\\n return JPoint(x, y, z);\\n }\\n\\n /* _affineFromJacobian\\n * @desription returns affine coordinates from a jacobian input follows\\n * golang elliptic/crypto library\\n */\\n function _affineFromJacobian(\\n uint x,\\n uint y,\\n uint z\\n ) internal view returns (uint ax, uint ay) {\\n if (z == 0) {\\n return (0, 0);\\n }\\n\\n uint zinv = _primemod(z, pp);\\n uint zinvsq = mulmod(zinv, zinv, pp);\\n\\n ax = mulmod(x, zinvsq, pp);\\n ay = mulmod(y, mulmod(zinvsq, zinv, pp), pp);\\n }\\n\\n /*\\n * _jAdd\\n * @description performs Jacobian addition as defined below:\\n * http://www.hyperelliptic.org/EFD/g1p/data/shortw/jacobian/addition/add-2007-bl\\n */\\n function _jAdd(\\n uint p1,\\n uint p2,\\n uint p3,\\n uint q1,\\n uint q2,\\n uint q3\\n ) internal pure returns (uint r1, uint r2, uint r3) {\\n if (p3 == 0) {\\n r1 = q1;\\n r2 = q2;\\n r3 = q3;\\n\\n return (r1, r2, r3);\\n } else if (q3 == 0) {\\n r1 = p1;\\n r2 = p2;\\n r3 = p3;\\n\\n return (r1, r2, r3);\\n }\\n\\n assembly {\\n let\\n pd\\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\\n let z1z1 := mulmod(p3, p3, pd) // Z1Z1 = Z1^2\\n let z2z2 := mulmod(q3, q3, pd) // Z2Z2 = Z2^2\\n\\n let u1 := mulmod(p1, z2z2, pd) // U1 = X1*Z2Z2\\n let u2 := mulmod(q1, z1z1, pd) // U2 = X2*Z1Z1\\n\\n let s1 := mulmod(p2, mulmod(z2z2, q3, pd), pd) // S1 = Y1*Z2*Z2Z2\\n let s2 := mulmod(q2, mulmod(z1z1, p3, pd), pd) // S2 = Y2*Z1*Z1Z1\\n\\n let p3q3 := addmod(p3, q3, pd)\\n\\n if lt(u2, u1) {\\n u2 := add(pd, u2) // u2 = u2+pd\\n }\\n let h := sub(u2, u1) // H = U2-U1\\n\\n let i := mulmod(0x02, h, pd)\\n i := mulmod(i, i, pd) // I = (2*H)^2\\n\\n let j := mulmod(h, i, pd) // J = H*I\\n if lt(s2, s1) {\\n s2 := add(pd, s2) // u2 = u2+pd\\n }\\n let rr := mulmod(0x02, sub(s2, s1), pd) // r = 2*(S2-S1)\\n r1 := mulmod(rr, rr, pd) // X3 = R^2\\n\\n let v := mulmod(u1, i, pd) // V = U1*I\\n let j2v := addmod(j, mulmod(0x02, v, pd), pd)\\n if lt(r1, j2v) {\\n r1 := add(pd, r1) // X3 = X3+pd\\n }\\n r1 := sub(r1, j2v)\\n\\n // Y3 = r*(V-X3)-2*S1*J\\n let s12j := mulmod(mulmod(0x02, s1, pd), j, pd)\\n\\n if lt(v, r1) {\\n v := add(pd, v)\\n }\\n r2 := mulmod(rr, sub(v, r1), pd)\\n\\n if lt(r2, s12j) {\\n r2 := add(pd, r2)\\n }\\n r2 := sub(r2, s12j)\\n\\n // Z3 = ((Z1+Z2)^2-Z1Z1-Z2Z2)*H\\n z1z1 := addmod(z1z1, z2z2, pd)\\n j2v := mulmod(p3q3, p3q3, pd)\\n if lt(j2v, z1z1) {\\n j2v := add(pd, j2v)\\n }\\n r3 := mulmod(sub(j2v, z1z1), h, pd)\\n }\\n return (r1, r2, r3);\\n }\\n\\n // Point doubling on the modified jacobian coordinates\\n // http://point-at-infinity.org/ecc/Prime_Curve_Modified_Jacobian_Coordinates.html\\n function _modifiedJacobianDouble(\\n uint x,\\n uint y,\\n uint z\\n ) internal pure returns (uint x3, uint y3, uint z3) {\\n if (y == 0) return (0, 0, 0);\\n assembly {\\n let\\n pd\\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\\n let z2 := mulmod(z, z, pd)\\n let az4 := mulmod(\\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC,\\n mulmod(z2, z2, pd),\\n pd\\n )\\n let y2 := mulmod(y, y, pd)\\n let s := mulmod(0x04, mulmod(x, y2, pd), pd)\\n let u := mulmod(0x08, mulmod(y2, y2, pd), pd)\\n let m := addmod(mulmod(0x03, mulmod(x, x, pd), pd), az4, pd)\\n let twos := mulmod(0x02, s, pd)\\n let m2 := mulmod(m, m, pd)\\n if lt(m2, twos) {\\n m2 := add(pd, m2)\\n }\\n x3 := sub(m2, twos)\\n if lt(s, x3) {\\n s := add(pd, s)\\n }\\n y3 := mulmod(m, sub(s, x3), pd)\\n if lt(y3, u) {\\n y3 := add(pd, y3)\\n }\\n y3 := sub(y3, u)\\n z3 := mulmod(0x02, mulmod(y, z, pd), pd)\\n }\\n }\\n\\n // Fermats little theorem https://en.wikipedia.org/wiki/Fermat%27s_little_theorem\\n // a^(p-1) = 1 mod p\\n // a^(-1) \\u2245 a^(p-2) (mod p)\\n // we then use the precompile bigModExp to compute a^(-1)\\n function _primemod(uint value, uint p) internal view returns (uint ret) {\\n ret = modexp(value, p - 2, p);\\n return ret;\\n }\\n\\n // Wrapper for built-in BigNumber_modexp (contract 0x5) as described here. https://github.com/ethereum/EIPs/pull/198\\n function modexp(\\n uint _base,\\n uint _exp,\\n uint _mod\\n ) internal view returns (uint ret) {\\n // bigModExp(_base, _exp, _mod);\\n assembly {\\n if gt(_base, _mod) {\\n _base := mod(_base, _mod)\\n }\\n // Free memory pointer is always stored at 0x40\\n let freemem := mload(0x40)\\n\\n mstore(freemem, 0x20)\\n mstore(add(freemem, 0x20), 0x20)\\n mstore(add(freemem, 0x40), 0x20)\\n\\n mstore(add(freemem, 0x60), _base)\\n mstore(add(freemem, 0x80), _exp)\\n mstore(add(freemem, 0xa0), _mod)\\n\\n let success := staticcall(14000, 0x5, freemem, 0xc0, freemem, 0x20)\\n switch success\\n case 0 {\\n revert(0x0, 0x0)\\n }\\n default {\\n ret := mload(freemem)\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb53714ba63cddb379ba312c1e7f6a423f4d7a7e34fa1364ec8295cd57d544024\",\"license\":\"GPL-3.0\"},\"contracts/infrastructure/interfaces/IFacetRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Registry Interface\\n * @dev Interface for Facet Registry contract to keep track of facets & function selectors addable to user wallets\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ninterface IFacetRegistry {\\n struct FacetRegistryConfig {\\n bytes4[] selectors;\\n mapping(bytes4 => FacetInfo) info;\\n }\\n struct FacetInfo {\\n bool exists;\\n uint128 index;\\n }\\n\\n event FacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] facetSelectors\\n );\\n event FacetFunctionSelectorsRemoved(address facet, bytes4[] facetSelectors);\\n\\n error FacetRegistry__FacetSelectorAlreadyRegistered();\\n error FacetRegistry__UnregisteredFacetSelector();\\n\\n function registerFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function removeFacetFunctionSelectors(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external;\\n\\n function areFacetFunctionSelectorsRegistered(\\n address facet,\\n bytes4[] calldata facetSelectors\\n ) external view returns (bool);\\n\\n function isFacetFunctionSelectorRegistered(\\n address facet,\\n bytes4 facetSelector\\n ) external view returns (bool);\\n\\n function getFacetFunctionSelectors(\\n address facet\\n ) external view returns (bytes4[] memory);\\n}\\n\",\"keccak256\":\"0x6e6dd2cab346ef7c31230740ec48d2925e4a9ab24c2f2fb268baaf408dcf02ef\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC1271 {\\n function isValidSignature(\\n bytes32 hash,\\n bytes memory signature\\n ) external view returns (bytes4);\\n}\\n\",\"keccak256\":\"0xcdddb7d5641c9d3f2432dec7fd13fddb9ae1480f25c76c21511e2fa16b8bd422\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibAppStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {SafeCast} from \\\"@openzeppelin/contracts/utils/math/SafeCast.sol\\\";\\nimport {IEntryPoint} from \\\"../aa-4337/interfaces/IEntryPoint.sol\\\";\\nimport {IFacetRegistry} from \\\"../infrastructure/interfaces/IFacetRegistry.sol\\\";\\n\\n/*\\n * @title App Storage\\n * @dev App storage for Barz contract to prevent storage collision\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Lock {\\n uint64 release;\\n bytes4 locker;\\n}\\n\\nstruct InitializersStorage {\\n // NOTE: initialized is a variable to make sure the initialization is only done once.\\n uint8 signerInitialized;\\n uint8 accountInitialized;\\n uint8 restrictionsInitialized;\\n}\\n\\nstruct AppStorage {\\n mapping(uint256 => InitializersStorage) initStorage;\\n uint8 signerMigration;\\n bytes4 validateOwnerSignatureSelector;\\n IEntryPoint entryPoint;\\n IFacetRegistry facetRegistry;\\n mapping(uint256 => Lock) locks;\\n}\\n\\nlibrary LibAppStorage {\\n error LibAppStorage__AccountAlreadyUninitialized();\\n error LibAppStorage__AccountMustBeUninitialized();\\n error LibAppStorage__SignerAlreadyUninitialized();\\n error LibAppStorage__SignerMustBeUninitialized();\\n\\n function appStorage() internal pure returns (AppStorage storage ds) {\\n assembly {\\n ds.slot := 0\\n }\\n }\\n\\n function setSignerUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerAlreadyUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 0;\\n }\\n\\n function getValidateOwnerSignatureSelector()\\n internal\\n view\\n returns (bytes4 selector)\\n {\\n selector = appStorage().validateOwnerSignatureSelector;\\n }\\n\\n function setValidateOwnerSignatureSelector(\\n bytes4 _validateOwnerSignatureSelector\\n ) internal {\\n appStorage()\\n .validateOwnerSignatureSelector = _validateOwnerSignatureSelector;\\n }\\n\\n function enforceSignerInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].signerInitialized) {\\n revert LibAppStorage__SignerMustBeUninitialized();\\n }\\n s.initStorage[0].signerInitialized = 1;\\n }\\n\\n function enforceAccountInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].accountInitialized) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n s.initStorage[0].accountInitialized = 1;\\n }\\n\\n function initiateSignerMigration() internal {\\n appStorage().signerMigration = 1;\\n }\\n\\n function enforceSignerMigration() internal view {\\n if (1 != appStorage().signerMigration) {\\n revert LibAppStorage__AccountMustBeUninitialized();\\n }\\n }\\n\\n function finalizeSignerMigration() internal {\\n appStorage().signerMigration = 0;\\n }\\n\\n function setLock(uint256 _releaseAfter, bytes4 _locker) internal {\\n appStorage().locks[0] = Lock(SafeCast.toUint64(_releaseAfter), _locker);\\n }\\n\\n function enforceRestrictionsInitialize() internal {\\n AppStorage storage s = appStorage();\\n if (0 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__SignerMustBeUninitialized();\\n s.initStorage[0].restrictionsInitialized = 1;\\n }\\n\\n function setRestrictionsUninitialized() internal {\\n AppStorage storage s = appStorage();\\n if (1 != s.initStorage[0].restrictionsInitialized)\\n revert LibAppStorage__AccountAlreadyUninitialized();\\n s.initStorage[0].restrictionsInitialized = 0;\\n }\\n}\\n\\ncontract BarzStorage {\\n AppStorage internal s;\\n modifier onlyWhenUnlocked() {\\n require(\\n uint64(block.timestamp) >= s.locks[0].release,\\n \\\"Account Locked\\\"\\n );\\n _;\\n }\\n modifier onlyWhenLocked() {\\n require(\\n uint64(block.timestamp) < s.locks[0].release,\\n \\\"Account Unlocked\\\"\\n );\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x48524007862a6ce0e07f645950613ce6513ce073c37a109c75019683d42bae27\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondCut} from \\\"../facets/base/interfaces/IDiamondCut.sol\\\";\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\n\\nerror InitializationFunctionReverted(\\n address _initializationContractAddress,\\n bytes _calldata\\n);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION =\\n keccak256(\\\"trustwallet.barz.diamond.storage\\\");\\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\\n bytes4(keccak256(\\\"verifyRestrictions(address,address,uint256,bytes)\\\"));\\n struct DiamondStorage {\\n // maps function selectors to the facets that execute the functions.\\n // and maps the selectors to their position in the selectorSlots array.\\n // func selector => address facet, selector position\\n mapping(bytes4 => bytes32) facets;\\n // array of slots of function selectors.\\n // each slot holds 8 function selectors.\\n mapping(uint256 => bytes32) selectorSlots;\\n // The number of function selectors in selectorSlots\\n uint16 selectorCount;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // Default Fallback Handler of the barz.\\n IDiamondLoupe defaultFallbackHandler;\\n }\\n\\n function diamondStorage()\\n internal\\n pure\\n returns (DiamondStorage storage ds)\\n {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n function enforceIsSelf() internal view {\\n require(msg.sender == address(this), \\\"LibDiamond: Caller not self\\\");\\n }\\n\\n event DiamondCut(\\n IDiamondCut.FacetCut[] _diamondCut,\\n address _init,\\n bytes _calldata\\n );\\n\\n bytes32 constant CLEAR_ADDRESS_MASK =\\n bytes32(uint256(0xffffffffffffffffffffffff));\\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\\n\\n // Internal function version of diamondCut\\n // This code is almost the same as the external diamondCut,\\n // except it is using 'Facet[] memory _diamondCut' instead of\\n // 'Facet[] calldata _diamondCut'.\\n // The code is duplicated to prevent copying calldata to memory which\\n // causes an error for a two dimensional array.\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n DiamondStorage storage ds = diamondStorage();\\n uint256 originalSelectorCount = ds.selectorCount;\\n uint256 selectorCount = originalSelectorCount;\\n bytes32 selectorSlot;\\n // Check if last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // get last selectorSlot\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\\n }\\n // loop through diamond cut\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\\n selectorCount,\\n selectorSlot,\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].action,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n\\n unchecked {\\n facetIndex++;\\n }\\n }\\n if (selectorCount != originalSelectorCount) {\\n ds.selectorCount = uint16(selectorCount);\\n }\\n // If last selector slot is not full\\n // \\\"selectorCount & 7\\\" is a gas efficient modulo by eight \\\"selectorCount % 8\\\"\\n if (selectorCount & 7 > 0) {\\n // \\\"selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"selectorSlot / 8\\\"\\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addReplaceRemoveFacetSelectors(\\n uint256 _selectorCount,\\n bytes32 _selectorSlot,\\n address _newFacetAddress,\\n IDiamondCut.FacetCutAction _action,\\n bytes4[] memory _selectors\\n ) internal returns (uint256, bytes32) {\\n DiamondStorage storage ds = diamondStorage();\\n require(\\n _selectors.length > 0,\\n \\\"LibDiamondCut: No selectors in facet to cut\\\"\\n );\\n if (_action == IDiamondCut.FacetCutAction.Add) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Add facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n // add facet for selector\\n ds.facets[selector] =\\n bytes20(_newFacetAddress) |\\n bytes32(_selectorCount);\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\\n // clear selector position in slot and add selector\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\\n (bytes32(selector) >> selectorInSlotPosition);\\n // if slot is full then write it to storage\\n if (selectorInSlotPosition == 224) {\\n // \\\"_selectorSlot >> 3\\\" is a gas efficient division by 8 \\\"_selectorSlot / 8\\\"\\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\\n _selectorSlot = 0;\\n }\\n _selectorCount++;\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\\n enforceHasContractCode(\\n _newFacetAddress,\\n \\\"LibDiamondCut: Replace facet has no code\\\"\\n );\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n address oldFacetAddress = address(bytes20(oldFacet));\\n // only useful if immutable functions exist\\n require(\\n oldFacetAddress != address(this),\\n \\\"LibDiamondCut: Can't replace immutable function\\\"\\n );\\n require(\\n oldFacetAddress != _newFacetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n require(\\n oldFacetAddress != address(0),\\n \\\"LibDiamondCut: Can't replace function that doesn't exist\\\"\\n );\\n // replace old facet address\\n ds.facets[selector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(_newFacetAddress);\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\\n require(\\n _newFacetAddress == address(0),\\n \\\"LibDiamondCut: Remove facet address must be address(0)\\\"\\n );\\n // \\\"_selectorCount >> 3\\\" is a gas efficient division by 8 \\\"_selectorCount / 8\\\"\\n uint256 selectorSlotCount = _selectorCount >> 3;\\n // \\\"_selectorCount & 7\\\" is a gas efficient modulo by eight \\\"_selectorCount % 8\\\"\\n uint256 selectorInSlotIndex = _selectorCount & 7;\\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\\n if (_selectorSlot == 0) {\\n // get last selectorSlot\\n selectorSlotCount--;\\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\\n selectorInSlotIndex = 7;\\n } else {\\n selectorInSlotIndex--;\\n }\\n bytes4 lastSelector;\\n uint256 oldSelectorsSlotCount;\\n uint256 oldSelectorInSlotPosition;\\n // adding a block here prevents stack too deep error\\n {\\n bytes4 selector = _selectors[selectorIndex];\\n bytes32 oldFacet = ds.facets[selector];\\n require(\\n address(bytes20(oldFacet)) != address(0),\\n \\\"LibDiamondCut: Can't remove function that doesn't exist\\\"\\n );\\n // only useful if immutable functions exist\\n require(\\n address(bytes20(oldFacet)) != address(this),\\n \\\"LibDiamondCut: Can't remove immutable function\\\"\\n );\\n // replace selector with last selector in ds.facets\\n // gets the last selector\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n lastSelector = bytes4(\\n _selectorSlot << (selectorInSlotIndex << 5)\\n );\\n if (lastSelector != selector) {\\n // update last selector slot position info\\n ds.facets[lastSelector] =\\n (oldFacet & CLEAR_ADDRESS_MASK) |\\n bytes20(ds.facets[lastSelector]);\\n }\\n delete ds.facets[selector];\\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\\n // \\\"oldSelectorCount >> 3\\\" is a gas efficient division by 8 \\\"oldSelectorCount / 8\\\"\\n oldSelectorsSlotCount = oldSelectorCount >> 3;\\n // \\\"oldSelectorCount & 7\\\" is a gas efficient modulo by eight \\\"oldSelectorCount % 8\\\"\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\\n }\\n if (oldSelectorsSlotCount != selectorSlotCount) {\\n bytes32 oldSelectorSlot = ds.selectorSlots[\\n oldSelectorsSlotCount\\n ];\\n // clears the selector we are deleting and puts the last selector in its place.\\n oldSelectorSlot =\\n (oldSelectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n // update storage with the modified slot\\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\\n } else {\\n // clears the selector we are deleting and puts the last selector in its place.\\n _selectorSlot =\\n (_selectorSlot &\\n ~(CLEAR_SELECTOR_MASK >>\\n oldSelectorInSlotPosition)) |\\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\\n }\\n if (selectorInSlotIndex == 0) {\\n delete ds.selectorSlots[selectorSlotCount];\\n _selectorSlot = 0;\\n }\\n\\n unchecked {\\n selectorIndex++;\\n }\\n }\\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n return (_selectorCount, _selectorSlot);\\n }\\n\\n function initializeDiamondCut(\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(\\n _init,\\n \\\"LibDiamondCut: _init address has no code\\\"\\n );\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(\\n address _contract,\\n string memory _errorMessage\\n ) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n\\n function restrictionsFacet() internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(\\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2cabdc00de859c3a3170ce3bda5d0e5fd3933d47ce904fd1585f9818b02572f8\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibFacetStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\n/**\\n * @title Facet Storage\\n * @dev Storage contract to store each facets variables with diamond storage\\n * @author David Yongjun Kim (@Powerstream3604)\\n * @author Ruslan Serebriakov (@rsrbk)\\n */\\n\\nstruct Secp256k1VerificationStorage {\\n address signer;\\n}\\n\\nstruct Secp256r1VerificationStorage {\\n uint256[2] q;\\n}\\n\\nstruct GuardianStorage {\\n mapping(bytes32 => uint256) pending;\\n mapping(uint8 => StorageConfig) configs;\\n}\\n\\nstruct Info {\\n bool exists;\\n uint128 index;\\n}\\n\\nstruct StorageConfig {\\n address[] addresses;\\n mapping(address => Info) info;\\n}\\n\\nstruct RecoveryConfig {\\n bytes recoveryPublicKey;\\n uint64 executeAfter;\\n}\\n\\nstruct ApprovalConfig {\\n bool isApproved;\\n uint64 validUntil;\\n}\\n\\nstruct RecoveryApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isNewOwnerApproved;\\n}\\n\\nstruct RecoveryStorage {\\n mapping(uint8 => RecoveryConfig) recoveryConfigs;\\n mapping(uint8 => RecoveryApprovalConfig) recoveryApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct RestrictionsStorage {\\n address[] restrictions;\\n mapping(address => bool) exists;\\n}\\n\\nstruct SignatureMigrationConfig {\\n bytes migrationPublicKey;\\n address migrationVerificationFacet;\\n bytes4[] migrationSelectors;\\n uint64 migrateAfter;\\n}\\n\\nstruct SignatureMigrationApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isMigrationApproved;\\n}\\n\\nstruct SignatureMigrationStorage {\\n mapping(uint8 => SignatureMigrationConfig) migrationConfigs;\\n mapping(uint8 => SignatureMigrationApprovalConfig) migrationApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct DiamondCutApprovalConfig {\\n mapping(bytes32 => mapping(address => ApprovalConfig)) isDiamondCutApproved;\\n}\\n\\nstruct DiamondCutStorage {\\n mapping(uint8 => DiamondCutApprovalConfig) diamondCutApprovalConfigs;\\n uint128 nonce;\\n}\\n\\nstruct LockStorage {\\n uint128 nonce;\\n}\\n\\nlibrary LibFacetStorage {\\n bytes32 constant K1_STORAGE_POSITION =\\n keccak256(\\n \\\"v0.trustwallet.diamond.storage.Secp256k1VerificationStorage\\\"\\n );\\n bytes32 constant R1_STORAGE_POSITION =\\n keccak256(\\n \\\"v0.trustwallet.diamond.storage.Secp256r1VerificationStorage\\\"\\n );\\n bytes32 constant GUARDIAN_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.GuardianStorage\\\");\\n bytes32 constant RECOVERY_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.RecoveryStorage\\\");\\n bytes32 constant RESTRICTION_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.RestrictionsStorage\\\");\\n bytes32 constant MIGRATION_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.SignatureMigrationStorage\\\");\\n bytes32 constant DIAMONDCUT_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.DiamondCutStorage\\\");\\n bytes32 constant LOCK_STORAGE_POSITION =\\n keccak256(\\\"v0.trustwallet.diamond.storage.LockStorage\\\");\\n\\n function k1Storage()\\n internal\\n pure\\n returns (Secp256k1VerificationStorage storage ds)\\n {\\n bytes32 storagePosition = K1_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function r1Storage()\\n internal\\n pure\\n returns (Secp256r1VerificationStorage storage ds)\\n {\\n bytes32 storagePosition = R1_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function guardianStorage()\\n internal\\n pure\\n returns (GuardianStorage storage ds)\\n {\\n bytes32 storagePosition = GUARDIAN_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function recoveryStorage()\\n internal\\n pure\\n returns (RecoveryStorage storage ds)\\n {\\n bytes32 storagePosition = RECOVERY_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function restrictionsStorage()\\n internal\\n pure\\n returns (RestrictionsStorage storage ds)\\n {\\n bytes32 storagePosition = RESTRICTION_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function migrationStorage()\\n internal\\n pure\\n returns (SignatureMigrationStorage storage ds)\\n {\\n bytes32 storagePosition = MIGRATION_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function diamondCutStorage()\\n internal\\n pure\\n returns (DiamondCutStorage storage ds)\\n {\\n bytes32 storagePosition = DIAMONDCUT_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n\\n function lockStorage() internal pure returns (LockStorage storage ds) {\\n bytes32 storagePosition = LOCK_STORAGE_POSITION;\\n assembly {\\n ds.slot := storagePosition\\n }\\n }\\n}\\n\",\"keccak256\":\"0x87c85decfd943deda9540733e464cb1a92eba735a301e89ce6f798016e359761\",\"license\":\"Apache-2.0\"},\"contracts/libraries/LibLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IDiamondLoupe} from \\\"../facets/base/interfaces/IDiamondLoupe.sol\\\";\\nimport {LibDiamond} from \\\"./LibDiamond.sol\\\";\\n\\n/**\\n * @title LibLoupe\\n * @dev Internal Library to provide utility feature for reading the state of diamond facets\\n * Originally from Diamond's implementation of Mudgen(author of EIP-2535)\\n */\\nlibrary LibLoupe {\\n /// @notice Gets all facets and their selectors.\\n /// @return facets_ Facet\\n function facets()\\n internal\\n view\\n returns (IDiamondLoupe.Facet[] memory facets_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facets_ = new IDiamondLoupe.Facet[](ds.selectorCount);\\n uint16[] memory numFacetSelectors = new uint16[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facets_[facetIndex].facetAddress == facetAddress_) {\\n facets_[facetIndex].functionSelectors[\\n numFacetSelectors[facetIndex]\\n ] = selector;\\n // probably will never have more than 256 functions from one facet contract\\n require(numFacetSelectors[facetIndex] < 255);\\n numFacetSelectors[facetIndex]++;\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facets_[numFacets].facetAddress = facetAddress_;\\n facets_[numFacets].functionSelectors = new bytes4[](\\n ds.selectorCount\\n );\\n facets_[numFacets].functionSelectors[0] = selector;\\n numFacetSelectors[numFacets] = 1;\\n numFacets++;\\n }\\n }\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n uint256 numSelectors = numFacetSelectors[facetIndex];\\n bytes4[] memory selectors = facets_[facetIndex].functionSelectors;\\n // setting the number of selectors\\n assembly {\\n mstore(selectors, numSelectors)\\n }\\n }\\n // setting the number of facets\\n assembly {\\n mstore(facets_, numFacets)\\n }\\n }\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return _facetFunctionSelectors The selectors associated with a facet address.\\n function facetFunctionSelectors(\\n address _facet\\n ) internal view returns (bytes4[] memory _facetFunctionSelectors) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n uint256 numSelectors;\\n _facetFunctionSelectors = new bytes4[](ds.selectorCount);\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facet = address(bytes20(ds.facets[selector]));\\n if (_facet == facet) {\\n _facetFunctionSelectors[numSelectors] = selector;\\n numSelectors++;\\n }\\n }\\n }\\n // Set the number of selectors in the array\\n assembly {\\n mstore(_facetFunctionSelectors, numSelectors)\\n }\\n }\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses()\\n internal\\n view\\n returns (address[] memory facetAddresses_)\\n {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetAddresses_ = new address[](ds.selectorCount);\\n uint256 numFacets;\\n uint256 selectorIndex;\\n // loop through function selectors\\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\\n bytes32 slot = ds.selectorSlots[slotIndex];\\n for (\\n uint256 selectorSlotIndex;\\n selectorSlotIndex < 8;\\n selectorSlotIndex++\\n ) {\\n selectorIndex++;\\n if (selectorIndex > ds.selectorCount) {\\n break;\\n }\\n // \\\" << 5 is the same as multiplying by 32 ( * 32)\\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\\n address facetAddress_ = address(bytes20(ds.facets[selector]));\\n bool continueLoop;\\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\\n if (facetAddress_ == facetAddresses_[facetIndex]) {\\n continueLoop = true;\\n break;\\n }\\n }\\n if (continueLoop) {\\n continue;\\n }\\n facetAddresses_[numFacets] = facetAddress_;\\n numFacets++;\\n }\\n }\\n // Set the number of facet addresses in the array\\n assembly {\\n mstore(facetAddresses_, numFacets)\\n }\\n }\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) internal view returns (address facetAddress_) {\\n facetAddress_ = address(\\n bytes20(LibDiamond.diamondStorage().facets[_functionSelector])\\n );\\n }\\n}\\n\",\"keccak256\":\"0x0b11439c3cc657095e15ec2241fdcf67204b14001357b612fc5db4ff9e760a5a\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x60a060405234801561001057600080fd5b50610019610022565b3060805261008b565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff161561006f57604051637c2cde8b60e01b815260040160405180910390fd5b600080805260209190915260409020805460ff19166001179055565b608051611f746100ad6000396000818161016001526106e10152611f746000f3fe608060405234801561001057600080fd5b50600436106100a35760003560e01c80637104ddb2116100765780638dd501211161005b5780638dd50121146101bc578063cd00e50a146101cf578063cd9b47e4146101d757600080fd5b80637104ddb21461015b5780638da5cb5b146101a757600080fd5b806311cfe388146100a85780631626ba7e146100ce5780633253960f14610112578063392dd6d914610138575b600080fd5b6100bb6100b6366004611823565b6101ea565b6040519081526020015b60405180910390f35b6100e16100dc366004611956565b610252565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020016100c5565b7f8dd50121000000000000000000000000000000000000000000000000000000006100e1565b61014b61014636600461199d565b6102fd565b60405190151581526020016100c5565b6101827f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100c5565b6101af61036f565b6040516100c591906119f6565b6100bb6101ca366004611a47565b6103ba565b6100bb61041f565b6100bb6101e5366004611a8c565b61053a565b600061023982846101ff610140880188611afe565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061083692505050565b610244576001610247565b60005b60ff16949350505050565b60006102aa7f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b1653646040805180820191829052919060029082845b81548152602001906001019080831161028b5750505050508484610836565b6102d4577fffffffff000000000000000000000000000000000000000000000000000000006102f6565b7f1626ba7e000000000000000000000000000000000000000000000000000000005b9392505050565b60008151604114801561036957508160008151811061031e5761031e611b6a565b6020910101517fff00000000000000000000000000000000000000000000000000000000000000167f0400000000000000000000000000000000000000000000000000000000000000145b92915050565b6040516060907f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364906103a5908290602001611b99565b60405160208183030381529060405291505090565b60408051808201918290526000917f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364916104179186918691859060029082845b8154815260200190600101908083116103fa5750505050506101ea565b949350505050565b60006104296109b4565b6104316109f4565b60408051808201909152600080825260208201527f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364906104749082906002611675565b506000610488600154610100900460e01b90565b7fffffffff0000000000000000000000000000000000000000000000000000000016036104e1576040517f127c609a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff169055604051600192507fcccd30db6bc000b8bb8d11162228d2d69e3c361983ca3ae8c1365ce64b0fae9e90600090a15090565b6000610544610a93565b61058383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102fd92505050565b6105b9576040517f6c334d2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006105c88360018187611bcd565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092935061060992506116b8915050565b602082015181526040820151602082015260006106437f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b16536490565b9050610651818360026116d6565b507f8dd50121000000000000000000000000000000000000000000000000000000006000610686600154610100900460e01b90565b7fffffffff0000000000000000000000000000000000000000000000000000000016146106df576040517f5f95a63c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16610770827fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604090205460601c90565b73ffffffffffffffffffffffffffffffffffffffff16146107bd576040517fbb4752b700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff1661010060e084901c02179055600194507f6d54821a69ec281ed7ba1bf2729c700768c47df1d80fad646b0a14cc1d5c39ed8787604051610824929190611bf7565b60405180910390a15050505092915050565b600080600080600080868060200190518101906108539190611c94565b9450945094509450945060008061088a8a60405160200161087691815260200190565b604051602081830303815290604052610b33565b905060008482856040516020016108a393929190611d47565b60405160208183030381529060405290506002816040516108c49190611d8a565b602060405180830381855afa1580156108e1573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906109049190611da6565b9250505060006002858360405160200161091f929190611dbf565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905261095791611d8a565b602060405180830381855afa158015610974573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906109979190611da6565b90506109a58b888884610c6f565b9b9a5050505050505050505050565b6001805460ff16146109f2576040517f38fc28cb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff16600114610a5c576040517fe00d7c7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff1615610af9576040517f7c2cde8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b60608151600003610b5257505060408051602081019091526000815290565b6000604051806060016040528060408152602001611eff6040913990506000600684516008610b819190611e10565b610b8b9190611e56565b9050600060068551610b9d9190611e6a565b1115610bb15780610bad81611e7e565b9150505b60008167ffffffffffffffff811115610bcc57610bcc61177c565b6040519080825280601f01601f191660200182016040528015610bf6576020820181803683370190505b509050600183016020820186875188015b80821015610c62576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f8116850151845350600183019250610c07565b5092979650505050505050565b6000610c9c60017fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611eb6565b85511180610cd75750610cd060017fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611eb6565b6020860151115b15610ce457506000610417565b831580610cef575082155b80610d1a57507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518410155b80610d4557507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518310155b15610d5257506000610417565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff7f5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff8088600060200201517fffffffff00000001000000000000000000000000fffffffffffffffffffffffc0988517fffffffff00000001000000000000000000000000ffffffffffffffffffffffff90819080098a5109080860208601517fffffffff00000001000000000000000000000000ffffffffffffffffffffffff90800914610e4357506000610417565b6000610e4e86610e66565b9050610e5c81868686611062565b9695505050505050565b610e6e611704565b60405180606001604052806000815260200160008152602001600081525081600060108110610e9f57610e9f611b6a565b60200201526040805160608101909152808360006020020151815260200183600160028110610ed057610ed0611b6a565b60200201518152602001600181525081600160108110610ef257610ef2611b6a565b6020020152610f088160015b602002015161116f565b6040820152610f278160015b60200201518260025b60200201516111d1565b6060828101919091526040805191820181527f6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c29682527f4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f560208301526001908201526080820152610fa18160045b6020020151826001610f1d565b60a0820152610fb1816004610f14565b60c0820152610fca8160045b6020020151826003610f1d565b60e0820152610fda816004610efe565b610100820152610feb816008610f94565b610120820152610ffc816008610f14565b61014082015261100d816008610fbd565b610160820152608081015161102490826008610f1d565b61018082015261103581600c610f94565b6101a082015261104681600c610f14565b6101c082015261105781600c610fbd565b6101e0820152919050565b600083158061106f575082155b8061109a57507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518410155b806110c557507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518310155b156110d257506000610417565b60006110fe847fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551611243565b905060007fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551828509905060007fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551838809905060008061115e8a858561125a565b509098149998505050505050505050565b61119360405180606001604052806000815260200160008152602001600081525090565b60008060006111af856000015186602001518760400151611346565b6040805160608101825293845260208401929092529082015295945050505050565b6111f560405180606001604052806000815260200160008152602001600081525090565b6000806000611220866000015187602001518860400151886000015189602001518a60400151611424565b604080516060810182529384526020840192909252908201529695505050505050565b60006102f683611254600285611eb6565b8461155c565b6000808080806080815b81156113285782156112955761127b858585611346565b9196509450925061128d858585611346565b919650945092505b50600c60fc89901c1660fe88901c17801561130b576113038585858d85601081106112c2576112c2611b6a565b6020020151518e86601081106112da576112da611b6a565b6020020151602001518f87601081106112f5576112f5611b6a565b602002015160400151611424565b919650945092505b600298891b989790971b968161132081611ec9565b925050611264565b6113338585856115b0565b909750955050505050505b935093915050565b6000806000846000036113615750600091508190508061141b565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff8085860981828283097fffffffff00000001000000000000000000000000fffffffffffffffffffffffc099050818788098283828b0960040983848384096008099150838385868d8e09600309089250838160020984848509818110156113e65785015b039650868110156113f45783015b8387820384099550508085101561140a57938201935b909303925080808688096002099150505b93509350939050565b60008060008660000361143e575084915083905082611550565b83600003611453575087915086905085611550565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff808889098186870982818d0983838b0984858a85098e0985868e87098c09868b8f08848410156114a357928701925b8484039350878460020988818209905088818609848410156114c457928901925b898585036002099350898485099c50898288099650898a8860020982089150818d10156114f0579b89019b5b818d039c5089818b87600209099450508b86101561150d57948801945b888c870384099a50838b101561152257998801995b838b039a508887890897508882830990508781101561153e5788015b88858983030999505050505050505050505b96509650969350505050565b60008184111561156c5781840693505b60405160208152602080820152602060408201528460608201528360808201528260a082015260208160c08360056136b0fa8080156100a357505051949350505050565b600080826000036115c65750600090508061133e565b60006115f2847fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611243565b905060007fffffffff00000001000000000000000000000000ffffffffffffffffffffffff82830990507fffffffff00000001000000000000000000000000ffffffffffffffffffffffff81880993507fffffffff00000001000000000000000000000000ffffffffffffffffffffffff80838309870992505050935093915050565b82600281019282156116a8579160200282015b828111156116a8578251829060ff16905591602001919060010190611688565b506116b492915061174e565b5090565b60405180604001604052806002906020820280368337509192915050565b82600281019282156116a8579160200282015b828111156116a85782518255916020019190600101906116e9565b6040518061020001604052806010905b61173860405180606001604052806000815260200160008152602001600081525090565b8152602001906001900390816117145790505090565b5b808211156116b4576000815560010161174f565b6000610160828403121561177657600080fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156117ce576117ce61177c565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561181b5761181b61177c565b604052919050565b60008060006080848603121561183857600080fd5b833567ffffffffffffffff81111561184f57600080fd5b61185b86828701611763565b935050602080850135925085605f86011261187557600080fd5b61187d6117ab565b80608087018881111561188f57600080fd5b604088015b818110156118ab5780358452928401928401611894565b50508093505050509250925092565b600067ffffffffffffffff8211156118d4576118d461177c565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261191157600080fd5b813561192461191f826118ba565b6117d4565b81815284602083860101111561193957600080fd5b816020850160208301376000918101602001919091529392505050565b6000806040838503121561196957600080fd5b82359150602083013567ffffffffffffffff81111561198757600080fd5b61199385828601611900565b9150509250929050565b6000602082840312156119af57600080fd5b813567ffffffffffffffff8111156119c657600080fd5b61041784828501611900565b60005b838110156119ed5781810151838201526020016119d5565b50506000910152565b6020815260008251806020840152611a158160408501602087016119d2565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b60008060408385031215611a5a57600080fd5b823567ffffffffffffffff811115611a7157600080fd5b611a7d85828601611763565b95602094909401359450505050565b60008060208385031215611a9f57600080fd5b823567ffffffffffffffff80821115611ab757600080fd5b818501915085601f830112611acb57600080fd5b813581811115611ada57600080fd5b866020828501011115611aec57600080fd5b60209290920196919550909350505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112611b3357600080fd5b83018035915067ffffffffffffffff821115611b4e57600080fd5b602001915036819003821315611b6357600080fd5b9250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008183825b6002811015611bbe578154835260209092019160019182019101611b9f565b50505060408201905092915050565b60008085851115611bdd57600080fd5b83861115611bea57600080fd5b5050820193919092039150565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b6000611c5261191f846118ba565b9050828152838383011115611c6657600080fd5b6102f68360208301846119d2565b600082601f830112611c8557600080fd5b6102f683835160208501611c44565b600080600080600060a08688031215611cac57600080fd5b8551945060208601519350604086015167ffffffffffffffff80821115611cd257600080fd5b818801915088601f830112611ce657600080fd5b611cf589835160208501611c44565b94506060880151915080821115611d0b57600080fd5b611d1789838a01611c74565b93506080880151915080821115611d2d57600080fd5b50611d3a88828901611c74565b9150509295509295909350565b60008451611d598184602089016119d2565b845190830190611d6d8183602089016119d2565b8451910190611d808183602088016119d2565b0195945050505050565b60008251611d9c8184602087016119d2565b9190910192915050565b600060208284031215611db857600080fd5b5051919050565b60008351611dd18184602088016119d2565b9190910191825250602001919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808202811582820484141761036957610369611de1565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082611e6557611e65611e27565b500490565b600082611e7957611e79611e27565b500690565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611eaf57611eaf611de1565b5060010190565b8181038181111561036957610369611de1565b600081611ed857611ed8611de1565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392d5fa2646970667358221220d4142da7b16effb6b95f41adeff2bc8ce0d59d3b70ca8d55e6e83224bbfbec0a64736f6c63430008150033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100a35760003560e01c80637104ddb2116100765780638dd501211161005b5780638dd50121146101bc578063cd00e50a146101cf578063cd9b47e4146101d757600080fd5b80637104ddb21461015b5780638da5cb5b146101a757600080fd5b806311cfe388146100a85780631626ba7e146100ce5780633253960f14610112578063392dd6d914610138575b600080fd5b6100bb6100b6366004611823565b6101ea565b6040519081526020015b60405180910390f35b6100e16100dc366004611956565b610252565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020016100c5565b7f8dd50121000000000000000000000000000000000000000000000000000000006100e1565b61014b61014636600461199d565b6102fd565b60405190151581526020016100c5565b6101827f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100c5565b6101af61036f565b6040516100c591906119f6565b6100bb6101ca366004611a47565b6103ba565b6100bb61041f565b6100bb6101e5366004611a8c565b61053a565b600061023982846101ff610140880188611afe565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061083692505050565b610244576001610247565b60005b60ff16949350505050565b60006102aa7f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b1653646040805180820191829052919060029082845b81548152602001906001019080831161028b5750505050508484610836565b6102d4577fffffffff000000000000000000000000000000000000000000000000000000006102f6565b7f1626ba7e000000000000000000000000000000000000000000000000000000005b9392505050565b60008151604114801561036957508160008151811061031e5761031e611b6a565b6020910101517fff00000000000000000000000000000000000000000000000000000000000000167f0400000000000000000000000000000000000000000000000000000000000000145b92915050565b6040516060907f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364906103a5908290602001611b99565b60405160208183030381529060405291505090565b60408051808201918290526000917f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364916104179186918691859060029082845b8154815260200190600101908083116103fa5750505050506101ea565b949350505050565b60006104296109b4565b6104316109f4565b60408051808201909152600080825260208201527f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b165364906104749082906002611675565b506000610488600154610100900460e01b90565b7fffffffff0000000000000000000000000000000000000000000000000000000016036104e1576040517f127c609a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff169055604051600192507fcccd30db6bc000b8bb8d11162228d2d69e3c361983ca3ae8c1365ce64b0fae9e90600090a15090565b6000610544610a93565b61058383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102fd92505050565b6105b9576040517f6c334d2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006105c88360018187611bcd565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092935061060992506116b8915050565b602082015181526040820151602082015260006106437f90969be7ff5e035b304bbc87b60c32b79faaf496bc52cb545bc487ff4b16536490565b9050610651818360026116d6565b507f8dd50121000000000000000000000000000000000000000000000000000000006000610686600154610100900460e01b90565b7fffffffff0000000000000000000000000000000000000000000000000000000016146106df576040517f5f95a63c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16610770827fffffffff000000000000000000000000000000000000000000000000000000001660009081527f183cde5d4f6bb7b445b8fc2f7f15d0fd1d162275aded24183babbffee7cd491f602052604090205460601c90565b73ffffffffffffffffffffffffffffffffffffffff16146107bd576040517fbb4752b700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff1661010060e084901c02179055600194507f6d54821a69ec281ed7ba1bf2729c700768c47df1d80fad646b0a14cc1d5c39ed8787604051610824929190611bf7565b60405180910390a15050505092915050565b600080600080600080868060200190518101906108539190611c94565b9450945094509450945060008061088a8a60405160200161087691815260200190565b604051602081830303815290604052610b33565b905060008482856040516020016108a393929190611d47565b60405160208183030381529060405290506002816040516108c49190611d8a565b602060405180830381855afa1580156108e1573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906109049190611da6565b9250505060006002858360405160200161091f929190611dbf565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905261095791611d8a565b602060405180830381855afa158015610974573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906109979190611da6565b90506109a58b888884610c6f565b9b9a5050505050505050505050565b6001805460ff16146109f2576040517f38fc28cb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff16600114610a5c576040517fe00d7c7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b600080805260208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb55460ff1615610af9576040517f7c2cde8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080526020919091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b60608151600003610b5257505060408051602081019091526000815290565b6000604051806060016040528060408152602001611eff6040913990506000600684516008610b819190611e10565b610b8b9190611e56565b9050600060068551610b9d9190611e6a565b1115610bb15780610bad81611e7e565b9150505b60008167ffffffffffffffff811115610bcc57610bcc61177c565b6040519080825280601f01601f191660200182016040528015610bf6576020820181803683370190505b509050600183016020820186875188015b80821015610c62576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f8116850151845350600183019250610c07565b5092979650505050505050565b6000610c9c60017fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611eb6565b85511180610cd75750610cd060017fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611eb6565b6020860151115b15610ce457506000610417565b831580610cef575082155b80610d1a57507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518410155b80610d4557507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518310155b15610d5257506000610417565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff7f5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff8088600060200201517fffffffff00000001000000000000000000000000fffffffffffffffffffffffc0988517fffffffff00000001000000000000000000000000ffffffffffffffffffffffff90819080098a5109080860208601517fffffffff00000001000000000000000000000000ffffffffffffffffffffffff90800914610e4357506000610417565b6000610e4e86610e66565b9050610e5c81868686611062565b9695505050505050565b610e6e611704565b60405180606001604052806000815260200160008152602001600081525081600060108110610e9f57610e9f611b6a565b60200201526040805160608101909152808360006020020151815260200183600160028110610ed057610ed0611b6a565b60200201518152602001600181525081600160108110610ef257610ef2611b6a565b6020020152610f088160015b602002015161116f565b6040820152610f278160015b60200201518260025b60200201516111d1565b6060828101919091526040805191820181527f6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c29682527f4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f560208301526001908201526080820152610fa18160045b6020020151826001610f1d565b60a0820152610fb1816004610f14565b60c0820152610fca8160045b6020020151826003610f1d565b60e0820152610fda816004610efe565b610100820152610feb816008610f94565b610120820152610ffc816008610f14565b61014082015261100d816008610fbd565b610160820152608081015161102490826008610f1d565b61018082015261103581600c610f94565b6101a082015261104681600c610f14565b6101c082015261105781600c610fbd565b6101e0820152919050565b600083158061106f575082155b8061109a57507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518410155b806110c557507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518310155b156110d257506000610417565b60006110fe847fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551611243565b905060007fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551828509905060007fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551838809905060008061115e8a858561125a565b509098149998505050505050505050565b61119360405180606001604052806000815260200160008152602001600081525090565b60008060006111af856000015186602001518760400151611346565b6040805160608101825293845260208401929092529082015295945050505050565b6111f560405180606001604052806000815260200160008152602001600081525090565b6000806000611220866000015187602001518860400151886000015189602001518a60400151611424565b604080516060810182529384526020840192909252908201529695505050505050565b60006102f683611254600285611eb6565b8461155c565b6000808080806080815b81156113285782156112955761127b858585611346565b9196509450925061128d858585611346565b919650945092505b50600c60fc89901c1660fe88901c17801561130b576113038585858d85601081106112c2576112c2611b6a565b6020020151518e86601081106112da576112da611b6a565b6020020151602001518f87601081106112f5576112f5611b6a565b602002015160400151611424565b919650945092505b600298891b989790971b968161132081611ec9565b925050611264565b6113338585856115b0565b909750955050505050505b935093915050565b6000806000846000036113615750600091508190508061141b565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff8085860981828283097fffffffff00000001000000000000000000000000fffffffffffffffffffffffc099050818788098283828b0960040983848384096008099150838385868d8e09600309089250838160020984848509818110156113e65785015b039650868110156113f45783015b8387820384099550508085101561140a57938201935b909303925080808688096002099150505b93509350939050565b60008060008660000361143e575084915083905082611550565b83600003611453575087915086905085611550565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff808889098186870982818d0983838b0984858a85098e0985868e87098c09868b8f08848410156114a357928701925b8484039350878460020988818209905088818609848410156114c457928901925b898585036002099350898485099c50898288099650898a8860020982089150818d10156114f0579b89019b5b818d039c5089818b87600209099450508b86101561150d57948801945b888c870384099a50838b101561152257998801995b838b039a508887890897508882830990508781101561153e5788015b88858983030999505050505050505050505b96509650969350505050565b60008184111561156c5781840693505b60405160208152602080820152602060408201528460608201528360808201528260a082015260208160c08360056136b0fa8080156100a357505051949350505050565b600080826000036115c65750600090508061133e565b60006115f2847fffffffff00000001000000000000000000000000ffffffffffffffffffffffff611243565b905060007fffffffff00000001000000000000000000000000ffffffffffffffffffffffff82830990507fffffffff00000001000000000000000000000000ffffffffffffffffffffffff81880993507fffffffff00000001000000000000000000000000ffffffffffffffffffffffff80838309870992505050935093915050565b82600281019282156116a8579160200282015b828111156116a8578251829060ff16905591602001919060010190611688565b506116b492915061174e565b5090565b60405180604001604052806002906020820280368337509192915050565b82600281019282156116a8579160200282015b828111156116a85782518255916020019190600101906116e9565b6040518061020001604052806010905b61173860405180606001604052806000815260200160008152602001600081525090565b8152602001906001900390816117145790505090565b5b808211156116b4576000815560010161174f565b6000610160828403121561177657600080fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156117ce576117ce61177c565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561181b5761181b61177c565b604052919050565b60008060006080848603121561183857600080fd5b833567ffffffffffffffff81111561184f57600080fd5b61185b86828701611763565b935050602080850135925085605f86011261187557600080fd5b61187d6117ab565b80608087018881111561188f57600080fd5b604088015b818110156118ab5780358452928401928401611894565b50508093505050509250925092565b600067ffffffffffffffff8211156118d4576118d461177c565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261191157600080fd5b813561192461191f826118ba565b6117d4565b81815284602083860101111561193957600080fd5b816020850160208301376000918101602001919091529392505050565b6000806040838503121561196957600080fd5b82359150602083013567ffffffffffffffff81111561198757600080fd5b61199385828601611900565b9150509250929050565b6000602082840312156119af57600080fd5b813567ffffffffffffffff8111156119c657600080fd5b61041784828501611900565b60005b838110156119ed5781810151838201526020016119d5565b50506000910152565b6020815260008251806020840152611a158160408501602087016119d2565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b60008060408385031215611a5a57600080fd5b823567ffffffffffffffff811115611a7157600080fd5b611a7d85828601611763565b95602094909401359450505050565b60008060208385031215611a9f57600080fd5b823567ffffffffffffffff80821115611ab757600080fd5b818501915085601f830112611acb57600080fd5b813581811115611ada57600080fd5b866020828501011115611aec57600080fd5b60209290920196919550909350505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112611b3357600080fd5b83018035915067ffffffffffffffff821115611b4e57600080fd5b602001915036819003821315611b6357600080fd5b9250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008183825b6002811015611bbe578154835260209092019160019182019101611b9f565b50505060408201905092915050565b60008085851115611bdd57600080fd5b83861115611bea57600080fd5b5050820193919092039150565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b6000611c5261191f846118ba565b9050828152838383011115611c6657600080fd5b6102f68360208301846119d2565b600082601f830112611c8557600080fd5b6102f683835160208501611c44565b600080600080600060a08688031215611cac57600080fd5b8551945060208601519350604086015167ffffffffffffffff80821115611cd257600080fd5b818801915088601f830112611ce657600080fd5b611cf589835160208501611c44565b94506060880151915080821115611d0b57600080fd5b611d1789838a01611c74565b93506080880151915080821115611d2d57600080fd5b50611d3a88828901611c74565b9150509295509295909350565b60008451611d598184602089016119d2565b845190830190611d6d8183602089016119d2565b8451910190611d808183602088016119d2565b0195945050505050565b60008251611d9c8184602087016119d2565b9190910192915050565b600060208284031215611db857600080fd5b5051919050565b60008351611dd18184602088016119d2565b9190910191825250602001919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808202811582820484141761036957610369611de1565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082611e6557611e65611e27565b500490565b600082611e7957611e79611e27565b500690565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611eaf57611eaf611de1565b5060010190565b8181038181111561036957610369611de1565b600081611ed857611ed8611de1565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392d5fa2646970667358221220d4142da7b16effb6b95f41adeff2bc8ce0d59d3b70ca8d55e6e83224bbfbec0a64736f6c63430008150033", + "devdoc": { + "author": "Ruslan Serebriakov (@rsrbk)David Yongjun Kim (@Powerstream3604)", + "details": "Primarily used to verify user ops signed with passkeys", + "kind": "dev", + "methods": { + "initializeSigner(bytes)": { + "details": "This method checks if the signer has already been initialized. If already initialized, it reverts. It checks if the public key is in the light format and initializes signer storage in k1 storage.", + "params": { + "_publicKey": "Bytes of owner public key" + }, + "returns": { + "initSuccess": "Uint value representing the success of init operation" + } + }, + "isValidKeyType(bytes)": { + "details": "For this Secp256k1Verification Facet, the public key should in an uncompressed public key format", + "params": { + "_publicKey": "Bytes of public key for format check" + }, + "returns": { + "isValid": "Boolean variable representing if the format of public key is valid" + } + }, + "isValidSignature(bytes32,bytes)": { + "details": "This method verifies the signature if the owner indeed signed the hash. Returns magic value if true", + "params": { + "_hash": "Hash value the owner signed", + "_signature": "Signature that signed the above hash" + }, + "returns": { + "magicValue": "Bytes4 value representing the success/failure of validation" + } + }, + "owner()": { + "returns": { + "signer": "Bytes of owner address" + } + }, + "uninitializeSigner()": { + "details": "This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.", + "returns": { + "uninitSuccess": "Uint value representing the success of uninit operation" + } + }, + "validateOwnerSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32)": { + "details": "This method validates if the user operation is signed by the owner. It internally calls validateSignature with signer public key.", + "params": { + "userOp": "UserOperation including all information for execution", + "userOpHash": "Hash of UserOperation given from EntryPoint. This hash is used for signature validation" + }, + "returns": { + "validationData": "Uint value representing whether the validation is successful. 0 for success, 1 for failure" + } + }, + "validateOwnerSignatureSelector()": { + "returns": { + "ownerSignatureValidatorSelector": "Bytes4 selector of function signature to validate account owner's UserOperation signature" + } + }, + "validateSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256[2])": { + "details": "This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address", + "params": { + "q": "Public Key of signer who signed the contract, to be validated", + "userOp": "UserOperation including all information for execution", + "userOpHash": "Hash of UserOperation given from EntryPoint. This hash is used for signature validation" + }, + "returns": { + "isValid": "Uint value representing whether the validation is successful. 0 for success, 1 for failure" + } + } + }, + "title": "Secp256r1 verification facet", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "constructor": { + "notice": "This constructor ensures that this contract can only be used as singleton for Proxy contracts" + }, + "initializeSigner(bytes)": { + "notice": "Initializes the signer in R1 Facet Storage. This can only be called when the account is uninitialized or during signature migration." + }, + "isValidKeyType(bytes)": { + "notice": "Validates if the format of public key is valid for this verification facet" + }, + "isValidSignature(bytes32,bytes)": { + "notice": "Validates if the signature is valid. Function to be compatible with EIP-1271" + }, + "owner()": { + "notice": "Returns the owner of the account" + }, + "uninitializeSigner()": { + "notice": "Uninitialize signer in R1 Facet Storage. This can only be called when the account is undergoing signature migration and has already been initialized." + }, + "validateOwnerSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32)": { + "notice": "Validates if the user operation is signed by the owner." + }, + "validateOwnerSignatureSelector()": { + "notice": "Returns the selector of function to validate the signature of UserOperation" + }, + "validateSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256[2])": { + "notice": "Validates if the signature of UserOperation is signed by the given signer" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/polygon/TokenReceiverFacet.json b/deployments/polygon/TokenReceiverFacet.json new file mode 100644 index 0000000..cbe1a2f --- /dev/null +++ b/deployments/polygon/TokenReceiverFacet.json @@ -0,0 +1,255 @@ +{ + "address": "0x3143E1C0Af0Cdc153423863923Cf4e3818e34Daa", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onERC1155BatchReceived", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onERC1155Received", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onERC721Received", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onTokenTransfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "tokensReceived", + "outputs": [], + "stateMutability": "pure", + "type": "function" + } + ], + "transactionHash": "0x97ddb0ea7b408b81f625b9430cd05610208a99776d6682e07a03023b75f98cbb", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0xd87dF9Fd27B9a30fe27E7b294CaAa4673F34B6b1", + "contractAddress": null, + "transactionIndex": 49, + "gasUsed": "329340", + "logsBloom": "0x00000000000000000000000400000000000000000000000000000000000000000000000000008000000000000000000000008000000000000000000000000000000000000000000000000000000000800000000000000000000100000000000000000000000000001002000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000004200000000000000000001000000000000000000000000000000100000000000000000000002000000000000000000000000000000000000000000000000100000", + "blockHash": "0x638ccd68d722e7e28a3a10adc9308eb3c3945ba44203250485d0abe7c1307c28", + "transactionHash": "0x97ddb0ea7b408b81f625b9430cd05610208a99776d6682e07a03023b75f98cbb", + "logs": [ + { + "transactionIndex": 49, + "blockNumber": 49217503, + "transactionHash": "0x97ddb0ea7b408b81f625b9430cd05610208a99776d6682e07a03023b75f98cbb", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x000000000000000000000000d87df9fd27b9a30fe27e7b294caaa4673f34b6b1", + "0x000000000000000000000000ec20607aa654d823dd01beb8780a44863c57ed07" + ], + "data": "0x00000000000000000000000000000000000000000000000000230f7b7ec1d71c000000000000000000000000000000000000000000000000cdab37dad5a77e5c0000000000000000000000000000000000000000000001920bd1836c2b0075b6000000000000000000000000000000000000000000000000cd88285f56e5a7400000000000000000000000000000000000000000000001920bf492e7a9c24cd2", + "logIndex": 1049, + "blockHash": "0x638ccd68d722e7e28a3a10adc9308eb3c3945ba44203250485d0abe7c1307c28" + } + ], + "blockNumber": 49217503, + "cumulativeGasUsed": "17874242", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "0c861e53801b64e5ccc05669ea62a977", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onERC1155BatchReceived\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onERC1155Received\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onERC721Received\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"tokensReceived\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"David Yongjun Kim (@Powerstream3604)\",\"details\":\"Contract that enables receiving ERC721/ERC1155/ERC777/ERC677 Tokens with safe transfer\",\"kind\":\"dev\",\"methods\":{},\"title\":\"TokenReceiver Facet\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\":{\"notice\":\"Handles ERC1155 Token batch callback. return Standardized onERC1155BatchReceived return value.\"},\"onERC1155Received(address,address,uint256,uint256,bytes)\":{\"notice\":\"Handles ERC1155 Token callback. return Standardized onERC1155Received return value.\"},\"onERC721Received(address,address,uint256,bytes)\":{\"notice\":\"Handles ERC721 Token callback. return Standardized onERC721Received return value.\"},\"onTokenTransfer(address,uint256,bytes)\":{\"notice\":\"Handles ERC677 Token callback. return true.\"},\"tokensReceived(address,address,address,uint256,bytes,bytes)\":{\"notice\":\"Handles ERC777 Token callback. Does not return value, empty implementation.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/TokenReceiverFacet.sol\":\"TokenReceiverFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title ERC721 token receiver interface\\n * @dev Interface for any contract that wants to support safeTransfers\\n * from ERC721 asset contracts.\\n */\\ninterface IERC721Receiver {\\n /**\\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\\n * by `operator` from `from`, this function is called.\\n *\\n * It must return its Solidity selector to confirm the token transfer.\\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\\n *\\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\\n */\\n function onERC721Received(\\n address operator,\\n address from,\\n uint256 tokenId,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\\n *\\n * Accounts can be notified of {IERC777} tokens being sent to them by having a\\n * contract implement this interface (contract holders can be their own\\n * implementer) and registering it on the\\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\\n *\\n * See {IERC1820Registry} and {ERC1820Implementer}.\\n */\\ninterface IERC777Recipient {\\n /**\\n * @dev Called by an {IERC777} token contract whenever tokens are being\\n * moved or created into a registered account (`to`). The type of operation\\n * is conveyed by `from` being the zero address or not.\\n *\\n * This call occurs _after_ the token contract's state is updated, so\\n * {IERC777-balanceOf}, etc., can be used to query the post-operation state.\\n *\\n * This function may revert to prevent the operation from being executed.\\n */\\n function tokensReceived(\\n address operator,\\n address from,\\n address to,\\n uint256 amount,\\n bytes calldata userData,\\n bytes calldata operatorData\\n ) external;\\n}\\n\",\"keccak256\":\"0x1a5d61db2733202ba361e6d6741cd2e662380e22b80e987eacfc91973f2267dc\",\"license\":\"MIT\"},\"contracts/facets/TokenReceiverFacet.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\nimport {IERC721Receiver} from \\\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\\\";\\nimport {IERC777Recipient} from \\\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\\\";\\nimport {IERC1155Receiver} from \\\"../interfaces/ERC/IERC1155Receiver.sol\\\";\\nimport {IERC677Receiver} from \\\"../interfaces/ERC/IERC677Receiver.sol\\\";\\n\\n/**\\n * @title TokenReceiver Facet\\n * @dev Contract that enables receiving ERC721/ERC1155/ERC777/ERC677 Tokens with safe transfer\\n * @author David Yongjun Kim (@Powerstream3604)\\n */\\ncontract TokenReceiverFacet is\\n IERC721Receiver,\\n IERC1155Receiver,\\n IERC777Recipient,\\n IERC677Receiver\\n{\\n /**\\n * @notice Handles ERC721 Token callback.\\n * return Standardized onERC721Received return value.\\n */\\n function onERC721Received(\\n address,\\n address,\\n uint256,\\n bytes calldata\\n ) external pure override returns (bytes4) {\\n return IERC721Receiver.onERC721Received.selector;\\n }\\n\\n /**\\n * @notice Handles ERC1155 Token callback.\\n * return Standardized onERC1155Received return value.\\n */\\n function onERC1155Received(\\n address,\\n address,\\n uint256,\\n uint256,\\n bytes calldata\\n ) external pure override returns (bytes4) {\\n return IERC1155Receiver.onERC1155Received.selector;\\n }\\n\\n /**\\n * @notice Handles ERC1155 Token batch callback.\\n * return Standardized onERC1155BatchReceived return value.\\n */\\n function onERC1155BatchReceived(\\n address,\\n address,\\n uint256[] calldata,\\n uint256[] calldata,\\n bytes calldata\\n ) external pure override returns (bytes4) {\\n return IERC1155Receiver.onERC1155BatchReceived.selector;\\n }\\n\\n /**\\n * @notice Handles ERC777 Token callback.\\n * Does not return value, empty implementation.\\n */\\n function tokensReceived(\\n address,\\n address,\\n address,\\n uint256,\\n bytes calldata,\\n bytes calldata\\n ) external pure override {}\\n\\n /**\\n * @notice Handles ERC677 Token callback.\\n * return true.\\n */\\n function onTokenTransfer(\\n address,\\n uint256,\\n bytes calldata\\n ) external pure override returns (bool) {\\n return true;\\n }\\n}\\n\",\"keccak256\":\"0xdfe483d05ef4056bb464c34ade19ab527687aff3ed0b6303b447a68b5ff7abb4\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC1155Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\n\\npragma solidity 0.8.21;\\n\\n/**\\n * @dev _Available since v3.1._\\n */\\ninterface IERC1155Receiver {\\n /**\\n * @dev Handles the receipt of a single ERC1155 token type. This function is\\n * called at the end of a `safeTransferFrom` after the balance has been updated.\\n *\\n * NOTE: To accept the transfer, this must return\\n * `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))`\\n * (i.e. 0xf23a6e61, or its own function selector).\\n *\\n * @param operator The address which initiated the transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param id The ID of the token being transferred\\n * @param value The amount of tokens being transferred\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155Received(\\n address operator,\\n address from,\\n uint256 id,\\n uint256 value,\\n bytes calldata data\\n ) external returns (bytes4);\\n\\n /**\\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\\n * is called at the end of a `safeBatchTransferFrom` after the balances have\\n * been updated.\\n *\\n * NOTE: To accept the transfer(s), this must return\\n * `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))`\\n * (i.e. 0xbc197c81, or its own function selector).\\n *\\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155BatchReceived(\\n address operator,\\n address from,\\n uint256[] calldata ids,\\n uint256[] calldata values,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0x3729c6757bae3aba03ac1c5064d67ad13b94e2a9428bf44b9be510373406da0c\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/ERC/IERC677Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.21;\\n\\ninterface IERC677Receiver {\\n function onTokenTransfer(\\n address sender,\\n uint value,\\n bytes calldata data\\n ) external pure returns (bool);\\n}\\n\",\"keccak256\":\"0x4c1631cf45ea6daac0ec158c3edb9453099130b6b64f697004b83f95aa1f7350\",\"license\":\"Apache-2.0\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50610502806100206000396000f3fe608060405234801561001057600080fd5b50600436106100665760003560e01c8063a4c0ed3611610050578063a4c0ed36146100f3578063bc197c811461011b578063f23a6e611461015657600080fd5b806223de291461006b578063150b7a0214610085575b600080fd5b610083610079366004610201565b5050505050505050565b005b6100bd6100933660046102ac565b7f150b7a020000000000000000000000000000000000000000000000000000000095945050505050565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020015b60405180910390f35b61010b61010136600461031b565b6001949350505050565b60405190151581526020016100ea565b6100bd6101293660046103ba565b7fbc197c810000000000000000000000000000000000000000000000000000000098975050505050505050565b6100bd610164366004610454565b7ff23a6e61000000000000000000000000000000000000000000000000000000009695505050505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146101b357600080fd5b919050565b60008083601f8401126101ca57600080fd5b50813567ffffffffffffffff8111156101e257600080fd5b6020830191508360208285010111156101fa57600080fd5b9250929050565b60008060008060008060008060c0898b03121561021d57600080fd5b6102268961018f565b975061023460208a0161018f565b965061024260408a0161018f565b955060608901359450608089013567ffffffffffffffff8082111561026657600080fd5b6102728c838d016101b8565b909650945060a08b013591508082111561028b57600080fd5b506102988b828c016101b8565b999c989b5096995094979396929594505050565b6000806000806000608086880312156102c457600080fd5b6102cd8661018f565b94506102db6020870161018f565b935060408601359250606086013567ffffffffffffffff8111156102fe57600080fd5b61030a888289016101b8565b969995985093965092949392505050565b6000806000806060858703121561033157600080fd5b61033a8561018f565b935060208501359250604085013567ffffffffffffffff81111561035d57600080fd5b610369878288016101b8565b95989497509550505050565b60008083601f84011261038757600080fd5b50813567ffffffffffffffff81111561039f57600080fd5b6020830191508360208260051b85010111156101fa57600080fd5b60008060008060008060008060a0898b0312156103d657600080fd5b6103df8961018f565b97506103ed60208a0161018f565b9650604089013567ffffffffffffffff8082111561040a57600080fd5b6104168c838d01610375565b909850965060608b013591508082111561042f57600080fd5b61043b8c838d01610375565b909650945060808b013591508082111561028b57600080fd5b60008060008060008060a0878903121561046d57600080fd5b6104768761018f565b95506104846020880161018f565b94506040870135935060608701359250608087013567ffffffffffffffff8111156104ae57600080fd5b6104ba89828a016101b8565b979a969950949750929593949250505056fea2646970667358221220ae9a97061ae9e1485161ca9c8d3228a23e47b18755fa935f51b40e927816ca2964736f6c63430008150033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100665760003560e01c8063a4c0ed3611610050578063a4c0ed36146100f3578063bc197c811461011b578063f23a6e611461015657600080fd5b806223de291461006b578063150b7a0214610085575b600080fd5b610083610079366004610201565b5050505050505050565b005b6100bd6100933660046102ac565b7f150b7a020000000000000000000000000000000000000000000000000000000095945050505050565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020015b60405180910390f35b61010b61010136600461031b565b6001949350505050565b60405190151581526020016100ea565b6100bd6101293660046103ba565b7fbc197c810000000000000000000000000000000000000000000000000000000098975050505050505050565b6100bd610164366004610454565b7ff23a6e61000000000000000000000000000000000000000000000000000000009695505050505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146101b357600080fd5b919050565b60008083601f8401126101ca57600080fd5b50813567ffffffffffffffff8111156101e257600080fd5b6020830191508360208285010111156101fa57600080fd5b9250929050565b60008060008060008060008060c0898b03121561021d57600080fd5b6102268961018f565b975061023460208a0161018f565b965061024260408a0161018f565b955060608901359450608089013567ffffffffffffffff8082111561026657600080fd5b6102728c838d016101b8565b909650945060a08b013591508082111561028b57600080fd5b506102988b828c016101b8565b999c989b5096995094979396929594505050565b6000806000806000608086880312156102c457600080fd5b6102cd8661018f565b94506102db6020870161018f565b935060408601359250606086013567ffffffffffffffff8111156102fe57600080fd5b61030a888289016101b8565b969995985093965092949392505050565b6000806000806060858703121561033157600080fd5b61033a8561018f565b935060208501359250604085013567ffffffffffffffff81111561035d57600080fd5b610369878288016101b8565b95989497509550505050565b60008083601f84011261038757600080fd5b50813567ffffffffffffffff81111561039f57600080fd5b6020830191508360208260051b85010111156101fa57600080fd5b60008060008060008060008060a0898b0312156103d657600080fd5b6103df8961018f565b97506103ed60208a0161018f565b9650604089013567ffffffffffffffff8082111561040a57600080fd5b6104168c838d01610375565b909850965060608b013591508082111561042f57600080fd5b61043b8c838d01610375565b909650945060808b013591508082111561028b57600080fd5b60008060008060008060a0878903121561046d57600080fd5b6104768761018f565b95506104846020880161018f565b94506040870135935060608701359250608087013567ffffffffffffffff8111156104ae57600080fd5b6104ba89828a016101b8565b979a969950949750929593949250505056fea2646970667358221220ae9a97061ae9e1485161ca9c8d3228a23e47b18755fa935f51b40e927816ca2964736f6c63430008150033", + "devdoc": { + "author": "David Yongjun Kim (@Powerstream3604)", + "details": "Contract that enables receiving ERC721/ERC1155/ERC777/ERC677 Tokens with safe transfer", + "kind": "dev", + "methods": {}, + "title": "TokenReceiver Facet", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)": { + "notice": "Handles ERC1155 Token batch callback. return Standardized onERC1155BatchReceived return value." + }, + "onERC1155Received(address,address,uint256,uint256,bytes)": { + "notice": "Handles ERC1155 Token callback. return Standardized onERC1155Received return value." + }, + "onERC721Received(address,address,uint256,bytes)": { + "notice": "Handles ERC721 Token callback. return Standardized onERC721Received return value." + }, + "onTokenTransfer(address,uint256,bytes)": { + "notice": "Handles ERC677 Token callback. return true." + }, + "tokensReceived(address,address,address,uint256,bytes,bytes)": { + "notice": "Handles ERC777 Token callback. Does not return value, empty implementation." + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/polygon/solcInputs/0c861e53801b64e5ccc05669ea62a977.json b/deployments/polygon/solcInputs/0c861e53801b64e5ccc05669ea62a977.json new file mode 100644 index 0000000..47e9456 --- /dev/null +++ b/deployments/polygon/solcInputs/0c861e53801b64e5ccc05669ea62a977.json @@ -0,0 +1,354 @@ +{ + "language": "Solidity", + "sources": { + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby disabling any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable2Step.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./Ownable.sol\";\n\n/**\n * @dev Contract module which provides access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership} and {acceptOwnership}.\n *\n * This module is used through inheritance. It will make available all functions\n * from parent (Ownable).\n */\nabstract contract Ownable2Step is Ownable {\n address private _pendingOwner;\n\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Returns the address of the pending owner.\n */\n function pendingOwner() public view virtual returns (address) {\n return _pendingOwner;\n }\n\n /**\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual override onlyOwner {\n _pendingOwner = newOwner;\n emit OwnershipTransferStarted(owner(), newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual override {\n delete _pendingOwner;\n super._transferOwnership(newOwner);\n }\n\n /**\n * @dev The new owner accepts the ownership transfer.\n */\n function acceptOwnership() public virtual {\n address sender = _msgSender();\n require(pendingOwner() == sender, \"Ownable2Step: caller is not the new owner\");\n _transferOwnership(sender);\n }\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC1271.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC1271 standard signature validation method for\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\n *\n * _Available since v4.1._\n */\ninterface IERC1271 {\n /**\n * @dev Should return whether the signature provided is valid for the provided data\n * @param hash Hash of the data to be signed\n * @param signature Signature byte array associated with _data\n */\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\n}\n" + }, + "@openzeppelin/contracts/security/ReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor() {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n _nonReentrantBefore();\n _;\n _nonReentrantAfter();\n }\n\n function _nonReentrantBefore() private {\n // On the first call to nonReentrant, _status will be _NOT_ENTERED\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n }\n\n function _nonReentrantAfter() private {\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Returns true if the reentrancy guard is currently set to \"entered\", which indicates there is a\n * `nonReentrant` function in the call stack.\n */\n function _reentrancyGuardEntered() internal view returns (bool) {\n return _status == _ENTERED;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/ERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/ERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC1155.sol\";\nimport \"./IERC1155Receiver.sol\";\nimport \"./extensions/IERC1155MetadataURI.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of the basic standard multi-token.\n * See https://eips.ethereum.org/EIPS/eip-1155\n * Originally based on code by Enjin: https://github.com/enjin/erc-1155\n *\n * _Available since v3.1._\n */\ncontract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {\n using Address for address;\n\n // Mapping from token ID to account balances\n mapping(uint256 => mapping(address => uint256)) private _balances;\n\n // Mapping from account to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json\n string private _uri;\n\n /**\n * @dev See {_setURI}.\n */\n constructor(string memory uri_) {\n _setURI(uri_);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return\n interfaceId == type(IERC1155).interfaceId ||\n interfaceId == type(IERC1155MetadataURI).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC1155MetadataURI-uri}.\n *\n * This implementation returns the same URI for *all* token types. It relies\n * on the token type ID substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * Clients calling this function must replace the `\\{id\\}` substring with the\n * actual token type ID.\n */\n function uri(uint256) public view virtual override returns (string memory) {\n return _uri;\n }\n\n /**\n * @dev See {IERC1155-balanceOf}.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {\n require(account != address(0), \"ERC1155: address zero is not a valid owner\");\n return _balances[id][account];\n }\n\n /**\n * @dev See {IERC1155-balanceOfBatch}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] memory accounts,\n uint256[] memory ids\n ) public view virtual override returns (uint256[] memory) {\n require(accounts.length == ids.length, \"ERC1155: accounts and ids length mismatch\");\n\n uint256[] memory batchBalances = new uint256[](accounts.length);\n\n for (uint256 i = 0; i < accounts.length; ++i) {\n batchBalances[i] = balanceOf(accounts[i], ids[i]);\n }\n\n return batchBalances;\n }\n\n /**\n * @dev See {IERC1155-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC1155-isApprovedForAll}.\n */\n function isApprovedForAll(address account, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[account][operator];\n }\n\n /**\n * @dev See {IERC1155-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n _safeTransferFrom(from, to, id, amount, data);\n }\n\n /**\n * @dev See {IERC1155-safeBatchTransferFrom}.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n _safeBatchTransferFrom(from, to, ids, amounts, data);\n }\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n\n emit TransferSingle(operator, from, to, id, amount);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n for (uint256 i = 0; i < ids.length; ++i) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n }\n\n emit TransferBatch(operator, from, to, ids, amounts);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\n\n _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);\n }\n\n /**\n * @dev Sets a new URI for all token types, by relying on the token type ID\n * substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * By this mechanism, any occurrence of the `\\{id\\}` substring in either the\n * URI or any of the amounts in the JSON file at said URI will be replaced by\n * clients with the token type ID.\n *\n * For example, the `https://token-cdn-domain/\\{id\\}.json` URI would be\n * interpreted by clients as\n * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`\n * for token type ID 0x4cce0.\n *\n * See {uri}.\n *\n * Because these URIs cannot be meaningfully represented by the {URI} event,\n * this function emits no events.\n */\n function _setURI(string memory newuri) internal virtual {\n _uri = newuri;\n }\n\n /**\n * @dev Creates `amount` tokens of token type `id`, and assigns them to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _mint(address to, uint256 id, uint256 amount, bytes memory data) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _balances[id][to] += amount;\n emit TransferSingle(operator, address(0), to, id, amount);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n for (uint256 i = 0; i < ids.length; i++) {\n _balances[ids[i]][to] += amounts[i];\n }\n\n emit TransferBatch(operator, address(0), to, ids, amounts);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);\n }\n\n /**\n * @dev Destroys `amount` tokens of token type `id` from `from`\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `from` must have at least `amount` tokens of token type `id`.\n */\n function _burn(address from, uint256 id, uint256 amount) internal virtual {\n require(from != address(0), \"ERC1155: burn from the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n\n emit TransferSingle(operator, from, address(0), id, amount);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n */\n function _burnBatch(address from, uint256[] memory ids, uint256[] memory amounts) internal virtual {\n require(from != address(0), \"ERC1155: burn from the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n\n for (uint256 i = 0; i < ids.length; i++) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n }\n\n emit TransferBatch(operator, from, address(0), ids, amounts);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {\n require(owner != operator, \"ERC1155: setting approval status for self\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning, as well as batched variants.\n *\n * The same hook is called on both single and batched variants. For single\n * transfers, the length of the `ids` and `amounts` arrays will be 1.\n *\n * Calling conditions (for each `id` and `amount` pair):\n *\n * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * of token type `id` will be transferred to `to`.\n * - When `from` is zero, `amount` tokens of token type `id` will be minted\n * for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n * will be burned.\n * - `from` and `to` are never both zero.\n * - `ids` and `amounts` have the same, non-zero length.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any token transfer. This includes minting\n * and burning, as well as batched variants.\n *\n * The same hook is called on both single and batched variants. For single\n * transfers, the length of the `id` and `amount` arrays will be 1.\n *\n * Calling conditions (for each `id` and `amount` pair):\n *\n * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * of token type `id` will be transferred to `to`.\n * - When `from` is zero, `amount` tokens of token type `id` will be minted\n * for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n * will be burned.\n * - `from` and `to` are never both zero.\n * - `ids` and `amounts` have the same, non-zero length.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {}\n\n function _doSafeTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155Receiver.onERC1155Received.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non-ERC1155Receiver implementer\");\n }\n }\n }\n\n function _doSafeBatchTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (\n bytes4 response\n ) {\n if (response != IERC1155Receiver.onERC1155BatchReceived.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non-ERC1155Receiver implementer\");\n }\n }\n }\n\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {\n uint256[] memory array = new uint256[](1);\n array[0] = element;\n\n return array;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC1155.sol\";\n\n/**\n * @dev Interface of the optional ERC1155MetadataExtension interface, as defined\n * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155MetadataURI is IERC1155 {\n /**\n * @dev Returns the URI for token type `id`.\n *\n * If the `\\{id\\}` substring is present in the URI, it must be replaced by\n * clients with the actual token type ID.\n */\n function uri(uint256 id) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155 is IERC165 {\n /**\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n */\n event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);\n\n /**\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n * transfers.\n */\n event TransferBatch(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\n\n /**\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n * `approved`.\n */\n event ApprovalForAll(address indexed account, address indexed operator, bool approved);\n\n /**\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n *\n * If an {URI} event was emitted for `id`, the standard\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n * returned by {IERC1155MetadataURI-uri}.\n */\n event URI(string value, uint256 indexed id);\n\n /**\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) external view returns (uint256);\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] calldata accounts,\n uint256[] calldata ids\n ) external view returns (uint256[] memory);\n\n /**\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n *\n * Emits an {ApprovalForAll} event.\n *\n * Requirements:\n *\n * - `operator` cannot be the caller.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n *\n * See {setApprovalForAll}.\n */\n function isApprovedForAll(address account, address operator) external view returns (bool);\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155Receiver is IERC165 {\n /**\n * @dev Handles the receipt of a single ERC1155 token type. This function is\n * called at the end of a `safeTransferFrom` after the balance has been updated.\n *\n * NOTE: To accept the transfer, this must return\n * `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n * (i.e. 0xf23a6e61, or its own function selector).\n *\n * @param operator The address which initiated the transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param id The ID of the token being transferred\n * @param value The amount of tokens being transferred\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n ) external returns (bytes4);\n\n /**\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\n * is called at the end of a `safeBatchTransferFrom` after the balances have\n * been updated.\n *\n * NOTE: To accept the transfer(s), this must return\n * `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n * (i.e. 0xbc197c81, or its own function selector).\n *\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the default value returned by this function, unless\n * it's overridden.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(address from, address to, uint256 amount) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\n // decrementing then incrementing.\n _balances[to] += amount;\n }\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n unchecked {\n // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\n _balances[account] += amount;\n }\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n // Overflow not possible: amount <= accountBalance <= totalSupply.\n _totalSupply -= amount;\n }\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\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" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` 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 amount) 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 `amount` as the allowance of `spender` over the 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 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` 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 amount) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/ERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721.sol\";\nimport \"./IERC721Receiver.sol\";\nimport \"./extensions/IERC721Metadata.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/Strings.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\n using Address for address;\n using Strings for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\n\n // Mapping from token ID to approved address\n mapping(uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return\n interfaceId == type(IERC721).interfaceId ||\n interfaceId == type(IERC721Metadata).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _ownerOf(tokenId);\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token owner or approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n _requireMinted(tokenId);\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n _safeTransfer(from, to, tokenId, data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(address from, address to, uint256 tokenId, bytes memory data) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist\n */\n function _ownerOf(uint256 tokenId) internal view virtual returns (address) {\n return _owners[tokenId];\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _ownerOf(tokenId) != address(0);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n address owner = ERC721.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(address to, uint256 tokenId, bytes memory data) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId, 1);\n\n // Check that tokenId was not minted by `_beforeTokenTransfer` hook\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n unchecked {\n // Will not overflow unless all 2**256 token ids are minted to the same owner.\n // Given that tokens are minted one by one, it is impossible in practice that\n // this ever happens. Might change if we allow batch minting.\n // The ERC fails to describe this case.\n _balances[to] += 1;\n }\n\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(address(0), to, tokenId, 1);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n * This is an internal function that does not check if the sender is authorized to operate on the token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId, 1);\n\n // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook\n owner = ERC721.ownerOf(tokenId);\n\n // Clear approvals\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // Cannot overflow, as that would require more tokens to be burned/transferred\n // out than the owner initially received through minting and transferring in.\n _balances[owner] -= 1;\n }\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(owner, address(0), tokenId, 1);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(address from, address to, uint256 tokenId) internal virtual {\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId, 1);\n\n // Check that tokenId was not transferred by `_beforeTokenTransfer` hook\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n\n // Clear approvals from the previous owner\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // `_balances[from]` cannot overflow for the same reason as described in `_burn`:\n // `from`'s balance is the number of token held, which is at least one before the current\n // transfer.\n // `_balances[to]` could overflow in the conditions described in `_mint`. That would require\n // all 2**256 token ids to be minted, which in practice is impossible.\n _balances[from] -= 1;\n _balances[to] += 1;\n }\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId, 1);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721Receiver.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`.\n * - When `from` is zero, the tokens will be minted for `to`.\n * - When `to` is zero, ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}\n\n /**\n * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`.\n * - When `from` is zero, the tokens were minted for `to`.\n * - When `to` is zero, ``from``'s tokens were burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}\n\n /**\n * @dev Unsafe write access to the balances, used by extensions that \"mint\" tokens using an {ownerOf} override.\n *\n * WARNING: Anyone calling this MUST ensure that the balances remain consistent with the ownership. The invariant\n * being that for any address `a` the value returned by `balanceOf(a)` must be equal to the number of tokens such\n * that `ownerOf(tokenId)` is `a`.\n */\n // solhint-disable-next-line func-name-mixedcase\n function __unsafe_increaseBalance(address account, uint256 amount) internal {\n _balances[account] += amount;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721Receiver {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/ERC777.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC777/ERC777.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC777.sol\";\nimport \"./IERC777Recipient.sol\";\nimport \"./IERC777Sender.sol\";\nimport \"../ERC20/IERC20.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/introspection/IERC1820Registry.sol\";\n\n/**\n * @dev Implementation of the {IERC777} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n *\n * Support for ERC20 is included in this contract, as specified by the EIP: both\n * the ERC777 and ERC20 interfaces can be safely used when interacting with it.\n * Both {IERC777-Sent} and {IERC20-Transfer} events are emitted on token\n * movements.\n *\n * Additionally, the {IERC777-granularity} value is hard-coded to `1`, meaning that there\n * are no special restrictions in the amount of tokens that created, moved, or\n * destroyed. This makes integration with ERC20 applications seamless.\n *\n * CAUTION: This file is deprecated as of v4.9 and will be removed in the next major release.\n */\ncontract ERC777 is Context, IERC777, IERC20 {\n using Address for address;\n\n IERC1820Registry internal constant _ERC1820_REGISTRY = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n mapping(address => uint256) private _balances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n bytes32 private constant _TOKENS_SENDER_INTERFACE_HASH = keccak256(\"ERC777TokensSender\");\n bytes32 private constant _TOKENS_RECIPIENT_INTERFACE_HASH = keccak256(\"ERC777TokensRecipient\");\n\n // This isn't ever read from - it's only used to respond to the defaultOperators query.\n address[] private _defaultOperatorsArray;\n\n // Immutable, but accounts may revoke them (tracked in __revokedDefaultOperators).\n mapping(address => bool) private _defaultOperators;\n\n // For each account, a mapping of its operators and revoked default operators.\n mapping(address => mapping(address => bool)) private _operators;\n mapping(address => mapping(address => bool)) private _revokedDefaultOperators;\n\n // ERC20-allowances\n mapping(address => mapping(address => uint256)) private _allowances;\n\n /**\n * @dev `defaultOperators` may be an empty array.\n */\n constructor(string memory name_, string memory symbol_, address[] memory defaultOperators_) {\n _name = name_;\n _symbol = symbol_;\n\n _defaultOperatorsArray = defaultOperators_;\n for (uint256 i = 0; i < defaultOperators_.length; i++) {\n _defaultOperators[defaultOperators_[i]] = true;\n }\n\n // register interfaces\n _ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256(\"ERC777Token\"), address(this));\n _ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256(\"ERC20Token\"), address(this));\n }\n\n /**\n * @dev See {IERC777-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC777-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {ERC20-decimals}.\n *\n * Always returns 18, as per the\n * [ERC777 EIP](https://eips.ethereum.org/EIPS/eip-777#backward-compatibility).\n */\n function decimals() public pure virtual returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC777-granularity}.\n *\n * This implementation always returns `1`.\n */\n function granularity() public view virtual override returns (uint256) {\n return 1;\n }\n\n /**\n * @dev See {IERC777-totalSupply}.\n */\n function totalSupply() public view virtual override(IERC20, IERC777) returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev Returns the amount of tokens owned by an account (`tokenHolder`).\n */\n function balanceOf(address tokenHolder) public view virtual override(IERC20, IERC777) returns (uint256) {\n return _balances[tokenHolder];\n }\n\n /**\n * @dev See {IERC777-send}.\n *\n * Also emits a {IERC20-Transfer} event for ERC20 compatibility.\n */\n function send(address recipient, uint256 amount, bytes memory data) public virtual override {\n _send(_msgSender(), recipient, amount, data, \"\", true);\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Unlike `send`, `recipient` is _not_ required to implement the {IERC777Recipient}\n * interface if it is a contract.\n *\n * Also emits a {Sent} event.\n */\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n _send(_msgSender(), recipient, amount, \"\", \"\", false);\n return true;\n }\n\n /**\n * @dev See {IERC777-burn}.\n *\n * Also emits a {IERC20-Transfer} event for ERC20 compatibility.\n */\n function burn(uint256 amount, bytes memory data) public virtual override {\n _burn(_msgSender(), amount, data, \"\");\n }\n\n /**\n * @dev See {IERC777-isOperatorFor}.\n */\n function isOperatorFor(address operator, address tokenHolder) public view virtual override returns (bool) {\n return\n operator == tokenHolder ||\n (_defaultOperators[operator] && !_revokedDefaultOperators[tokenHolder][operator]) ||\n _operators[tokenHolder][operator];\n }\n\n /**\n * @dev See {IERC777-authorizeOperator}.\n */\n function authorizeOperator(address operator) public virtual override {\n require(_msgSender() != operator, \"ERC777: authorizing self as operator\");\n\n if (_defaultOperators[operator]) {\n delete _revokedDefaultOperators[_msgSender()][operator];\n } else {\n _operators[_msgSender()][operator] = true;\n }\n\n emit AuthorizedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-revokeOperator}.\n */\n function revokeOperator(address operator) public virtual override {\n require(operator != _msgSender(), \"ERC777: revoking self as operator\");\n\n if (_defaultOperators[operator]) {\n _revokedDefaultOperators[_msgSender()][operator] = true;\n } else {\n delete _operators[_msgSender()][operator];\n }\n\n emit RevokedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-defaultOperators}.\n */\n function defaultOperators() public view virtual override returns (address[] memory) {\n return _defaultOperatorsArray;\n }\n\n /**\n * @dev See {IERC777-operatorSend}.\n *\n * Emits {Sent} and {IERC20-Transfer} events.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes memory data,\n bytes memory operatorData\n ) public virtual override {\n require(isOperatorFor(_msgSender(), sender), \"ERC777: caller is not an operator for holder\");\n _send(sender, recipient, amount, data, operatorData, true);\n }\n\n /**\n * @dev See {IERC777-operatorBurn}.\n *\n * Emits {Burned} and {IERC20-Transfer} events.\n */\n function operatorBurn(\n address account,\n uint256 amount,\n bytes memory data,\n bytes memory operatorData\n ) public virtual override {\n require(isOperatorFor(_msgSender(), account), \"ERC777: caller is not an operator for holder\");\n _burn(account, amount, data, operatorData);\n }\n\n /**\n * @dev See {IERC20-allowance}.\n *\n * Note that operator and allowance concepts are orthogonal: operators may\n * not have allowance, and accounts with allowance may not be operators\n * themselves.\n */\n function allowance(address holder, address spender) public view virtual override returns (uint256) {\n return _allowances[holder][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Note that accounts cannot have allowance issued by their operators.\n */\n function approve(address spender, uint256 value) public virtual override returns (bool) {\n address holder = _msgSender();\n _approve(holder, spender, value);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Note that operator and allowance concepts are orthogonal: operators cannot\n * call `transferFrom` (unless they have allowance), and accounts with\n * allowance cannot call `operatorSend` (unless they are operators).\n *\n * Emits {Sent}, {IERC20-Transfer} and {IERC20-Approval} events.\n */\n function transferFrom(address holder, address recipient, uint256 amount) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(holder, spender, amount);\n _send(holder, recipient, amount, \"\", \"\", false);\n return true;\n }\n\n /**\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with the caller address as the `operator` and with\n * `userData` and `operatorData`.\n *\n * See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits {Minted} and {IERC20-Transfer} events.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - if `account` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function _mint(address account, uint256 amount, bytes memory userData, bytes memory operatorData) internal virtual {\n _mint(account, amount, userData, operatorData, true);\n }\n\n /**\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * If `requireReceptionAck` is set to true, and if a send hook is\n * registered for `account`, the corresponding function will be called with\n * `operator`, `data` and `operatorData`.\n *\n * See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits {Minted} and {IERC20-Transfer} events.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - if `account` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function _mint(\n address account,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) internal virtual {\n require(account != address(0), \"ERC777: mint to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), account, amount);\n\n // Update state variables\n _totalSupply += amount;\n _balances[account] += amount;\n\n _callTokensReceived(operator, address(0), account, amount, userData, operatorData, requireReceptionAck);\n\n emit Minted(operator, account, amount, userData, operatorData);\n emit Transfer(address(0), account, amount);\n }\n\n /**\n * @dev Send tokens\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _send(\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) internal virtual {\n require(from != address(0), \"ERC777: transfer from the zero address\");\n require(to != address(0), \"ERC777: transfer to the zero address\");\n\n address operator = _msgSender();\n\n _callTokensToSend(operator, from, to, amount, userData, operatorData);\n\n _move(operator, from, to, amount, userData, operatorData);\n\n _callTokensReceived(operator, from, to, amount, userData, operatorData, requireReceptionAck);\n }\n\n /**\n * @dev Burn tokens\n * @param from address token holder address\n * @param amount uint256 amount of tokens to burn\n * @param data bytes extra information provided by the token holder\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _burn(address from, uint256 amount, bytes memory data, bytes memory operatorData) internal virtual {\n require(from != address(0), \"ERC777: burn from the zero address\");\n\n address operator = _msgSender();\n\n _callTokensToSend(operator, from, address(0), amount, data, operatorData);\n\n _beforeTokenTransfer(operator, from, address(0), amount);\n\n // Update state variables\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC777: burn amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Burned(operator, from, amount, data, operatorData);\n emit Transfer(from, address(0), amount);\n }\n\n function _move(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n ) private {\n _beforeTokenTransfer(operator, from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC777: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Sent(operator, from, to, amount, userData, operatorData);\n emit Transfer(from, to, amount);\n }\n\n /**\n * @dev See {ERC20-_approve}.\n *\n * Note that accounts cannot have allowance issued by their operators.\n */\n function _approve(address holder, address spender, uint256 value) internal virtual {\n require(holder != address(0), \"ERC777: approve from the zero address\");\n require(spender != address(0), \"ERC777: approve to the zero address\");\n\n _allowances[holder][spender] = value;\n emit Approval(holder, spender, value);\n }\n\n /**\n * @dev Call from.tokensToSend() if the interface is registered\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _callTokensToSend(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n ) private {\n address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(from, _TOKENS_SENDER_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Sender(implementer).tokensToSend(operator, from, to, amount, userData, operatorData);\n }\n }\n\n /**\n * @dev Call to.tokensReceived() if the interface is registered. Reverts if the recipient is a contract but\n * tokensReceived() was not registered for the recipient\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _callTokensReceived(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) private {\n address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(to, _TOKENS_RECIPIENT_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Recipient(implementer).tokensReceived(operator, from, to, amount, userData, operatorData);\n } else if (requireReceptionAck) {\n require(!to.isContract(), \"ERC777: token recipient contract has no implementer for ERC777TokensRecipient\");\n }\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {IERC20-Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC777: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes\n * calls to {send}, {transfer}, {operatorSend}, {transferFrom}, minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be to transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address operator, address from, address to, uint256 amount) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC777/IERC777.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777Token standard as defined in the EIP.\n *\n * This contract uses the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 registry standard] to let\n * token holders and recipients react to token movements by using setting implementers\n * for the associated interfaces in said registry. See {IERC1820Registry} and\n * {ERC1820Implementer}.\n */\ninterface IERC777 {\n /**\n * @dev Emitted when `amount` tokens are created by `operator` and assigned to `to`.\n *\n * Note that some additional user `data` and `operatorData` can be logged in the event.\n */\n event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);\n\n /**\n * @dev Emitted when `operator` destroys `amount` tokens from `account`.\n *\n * Note that some additional user `data` and `operatorData` can be logged in the event.\n */\n event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);\n\n /**\n * @dev Emitted when `operator` is made operator for `tokenHolder`.\n */\n event AuthorizedOperator(address indexed operator, address indexed tokenHolder);\n\n /**\n * @dev Emitted when `operator` is revoked its operator status for `tokenHolder`.\n */\n event RevokedOperator(address indexed operator, address indexed tokenHolder);\n\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, usually a shorter version of the\n * name.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the smallest part of the token that is not divisible. This\n * means all token operations (creation, movement and destruction) must have\n * amounts that are a multiple of this number.\n *\n * For most token contracts, this value will equal 1.\n */\n function granularity() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by an account (`owner`).\n */\n function balanceOf(address owner) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * If send or receive hooks are registered for the caller and `recipient`,\n * the corresponding functions will be called with `data` and empty\n * `operatorData`. See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits a {Sent} event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function send(address recipient, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Destroys `amount` tokens from the caller's account, reducing the\n * total supply.\n *\n * If a send hook is registered for the caller, the corresponding function\n * will be called with `data` and empty `operatorData`. See {IERC777Sender}.\n *\n * Emits a {Burned} event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n */\n function burn(uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Returns true if an account is an operator of `tokenHolder`.\n * Operators can send and burn tokens on behalf of their owners. All\n * accounts are their own operator.\n *\n * See {operatorSend} and {operatorBurn}.\n */\n function isOperatorFor(address operator, address tokenHolder) external view returns (bool);\n\n /**\n * @dev Make an account an operator of the caller.\n *\n * See {isOperatorFor}.\n *\n * Emits an {AuthorizedOperator} event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function authorizeOperator(address operator) external;\n\n /**\n * @dev Revoke an account's operator status for the caller.\n *\n * See {isOperatorFor} and {defaultOperators}.\n *\n * Emits a {RevokedOperator} event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function revokeOperator(address operator) external;\n\n /**\n * @dev Returns the list of default operators. These accounts are operators\n * for all token holders, even if {authorizeOperator} was never called on\n * them.\n *\n * This list is immutable, but individual holders may revoke these via\n * {revokeOperator}, in which case {isOperatorFor} will return false.\n */\n function defaultOperators() external view returns (address[] memory);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must\n * be an operator of `sender`.\n *\n * If send or receive hooks are registered for `sender` and `recipient`,\n * the corresponding functions will be called with `data` and\n * `operatorData`. See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits a {Sent} event.\n *\n * Requirements\n *\n * - `sender` cannot be the zero address.\n * - `sender` must have at least `amount` tokens.\n * - the caller must be an operator for `sender`.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes calldata data,\n bytes calldata operatorData\n ) external;\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the total supply.\n * The caller must be an operator of `account`.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with `data` and `operatorData`. See {IERC777Sender}.\n *\n * Emits a {Burned} event.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n * - the caller must be an operator for `account`.\n */\n function operatorBurn(address account, uint256 amount, bytes calldata data, bytes calldata operatorData) external;\n\n event Sent(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes data,\n bytes operatorData\n );\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\n *\n * Accounts can be notified of {IERC777} tokens being sent to them by having a\n * contract implement this interface (contract holders can be their own\n * implementer) and registering it on the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\n *\n * See {IERC1820Registry} and {ERC1820Implementer}.\n */\ninterface IERC777Recipient {\n /**\n * @dev Called by an {IERC777} token contract whenever tokens are being\n * moved or created into a registered account (`to`). The type of operation\n * is conveyed by `from` being the zero address or not.\n *\n * This call occurs _after_ the token contract's state is updated, so\n * {IERC777-balanceOf}, etc., can be used to query the post-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensReceived(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777Sender.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Sender.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777TokensSender standard as defined in the EIP.\n *\n * {IERC777} Token holders can be notified of operations performed on their\n * tokens by having a contract implement this interface (contract holders can be\n * their own implementer) and registering it on the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\n *\n * See {IERC1820Registry} and {ERC1820Implementer}.\n */\ninterface IERC777Sender {\n /**\n * @dev Called by an {IERC777} token contract whenever a registered holder's\n * (`from`) tokens are about to be moved or destroyed. The type of operation\n * is conveyed by `to` being the zero address or not.\n *\n * This call occurs _before_ the token contract's state is updated, so\n * {IERC777-balanceOf}, etc., can be used to query the pre-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensToSend(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n *\n * Furthermore, `isContract` will also return true if the target contract within\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n * which only has an effect at the end of a transaction.\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Counters.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary Counters {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/ECDSA.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Strings.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV // Deprecated in v4.8\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n /// @solidity memory-safe-assembly\n assembly {\n mstore(0x00, \"\\x19Ethereum Signed Message:\\n32\")\n mstore(0x1c, hash)\n message := keccak256(0x00, 0x3c)\n }\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\n /// @solidity memory-safe-assembly\n assembly {\n let ptr := mload(0x40)\n mstore(ptr, \"\\x19\\x01\")\n mstore(add(ptr, 0x02), domainSeparator)\n mstore(add(ptr, 0x22), structHash)\n data := keccak256(ptr, 0x42)\n }\n }\n\n /**\n * @dev Returns an Ethereum Signed Data with intended validator, created from a\n * `validator` and `data` according to the version 0 of EIP-191.\n *\n * See {recover}.\n */\n function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x00\", validator, data));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/SignatureChecker.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSA.sol\";\nimport \"../../interfaces/IERC1271.sol\";\n\n/**\n * @dev Signature verification helper that can be used instead of `ECDSA.recover` to seamlessly support both ECDSA\n * signatures from externally owned accounts (EOAs) as well as ERC1271 signatures from smart contract wallets like\n * Argent and Gnosis Safe.\n *\n * _Available since v4.1._\n */\nlibrary SignatureChecker {\n /**\n * @dev Checks if a signature is valid for a given signer and data hash. If the signer is a smart contract, the\n * signature is validated against that smart contract using ERC1271, otherwise it's validated using `ECDSA.recover`.\n *\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\n */\n function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature) internal view returns (bool) {\n (address recovered, ECDSA.RecoverError error) = ECDSA.tryRecover(hash, signature);\n return\n (error == ECDSA.RecoverError.NoError && recovered == signer) ||\n isValidERC1271SignatureNow(signer, hash, signature);\n }\n\n /**\n * @dev Checks if a signature is valid for a given signer and data hash. The signature is validated\n * against the signer smart contract using ERC1271.\n *\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\n */\n function isValidERC1271SignatureNow(\n address signer,\n bytes32 hash,\n bytes memory signature\n ) internal view returns (bool) {\n (bool success, bytes memory result) = signer.staticcall(\n abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, signature)\n );\n return (success &&\n result.length >= 32 &&\n abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/ERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165 is IERC165 {\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165).interfaceId;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC1820Registry.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/introspection/IERC1820Registry.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the global ERC1820 Registry, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register\n * implementers for interfaces in this registry, as well as query support.\n *\n * Implementers may be shared by multiple accounts, and can also implement more\n * than a single interface for each account. Contracts can implement interfaces\n * for themselves, but externally-owned accounts (EOA) must delegate this to a\n * contract.\n *\n * {IERC165} interfaces can also be queried via the registry.\n *\n * For an in-depth explanation and source code analysis, see the EIP text.\n */\ninterface IERC1820Registry {\n event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer);\n\n event ManagerChanged(address indexed account, address indexed newManager);\n\n /**\n * @dev Sets `newManager` as the manager for `account`. A manager of an\n * account is able to set interface implementers for it.\n *\n * By default, each account is its own manager. Passing a value of `0x0` in\n * `newManager` will reset the manager to this initial state.\n *\n * Emits a {ManagerChanged} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `account`.\n */\n function setManager(address account, address newManager) external;\n\n /**\n * @dev Returns the manager for `account`.\n *\n * See {setManager}.\n */\n function getManager(address account) external view returns (address);\n\n /**\n * @dev Sets the `implementer` contract as ``account``'s implementer for\n * `interfaceHash`.\n *\n * `account` being the zero address is an alias for the caller's address.\n * The zero address can also be used in `implementer` to remove an old one.\n *\n * See {interfaceHash} to learn how these are created.\n *\n * Emits an {InterfaceImplementerSet} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `account`.\n * - `interfaceHash` must not be an {IERC165} interface id (i.e. it must not\n * end in 28 zeroes).\n * - `implementer` must implement {IERC1820Implementer} and return true when\n * queried for support, unless `implementer` is the caller. See\n * {IERC1820Implementer-canImplementInterfaceForAddress}.\n */\n function setInterfaceImplementer(address account, bytes32 _interfaceHash, address implementer) external;\n\n /**\n * @dev Returns the implementer of `interfaceHash` for `account`. If no such\n * implementer is registered, returns the zero address.\n *\n * If `interfaceHash` is an {IERC165} interface id (i.e. it ends with 28\n * zeroes), `account` will be queried for support of it.\n *\n * `account` being the zero address is an alias for the caller's address.\n */\n function getInterfaceImplementer(address account, bytes32 _interfaceHash) external view returns (address);\n\n /**\n * @dev Returns the interface hash for an `interfaceName`, as defined in the\n * corresponding\n * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP].\n */\n function interfaceHash(string calldata interfaceName) external pure returns (bytes32);\n\n /**\n * @notice Updates the cache with whether the contract implements an ERC165 interface or not.\n * @param account Address of the contract for which to update the cache.\n * @param interfaceId ERC165 interface for which to update the cache.\n */\n function updateERC165Cache(address account, bytes4 interfaceId) external;\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not.\n * If the result is not cached a direct lookup on the contract address is performed.\n * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling\n * {updateERC165Cache} with the contract address.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool);\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not without using or updating the cache.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/math/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\n // The surrounding unchecked block does not change this fact.\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1, \"Math: mulDiv overflow\");\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n //\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n //\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n //\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1 << (log2(a) >> 1);\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = sqrt(a);\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 2, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 128;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 64;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 32;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 16;\n }\n if (value >> 8 > 0) {\n value >>= 8;\n result += 8;\n }\n if (value >> 4 > 0) {\n value >>= 4;\n result += 4;\n }\n if (value >> 2 > 0) {\n value >>= 2;\n result += 2;\n }\n if (value >> 1 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log2(value);\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 10, rounded down, of a positive value.\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 + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 256, rounded down, of a positive value.\n * Returns 0 if given 0.\n *\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n */\n function log256(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 16;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 8;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 4;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 2;\n }\n if (value >> 8 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log256(value);\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/SafeCast.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCast {\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 * _Available since v4.7._\n */\n function toUint248(uint256 value) internal pure returns (uint248) {\n require(value <= type(uint248).max, \"SafeCast: value doesn't fit in 248 bits\");\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 * _Available since v4.7._\n */\n function toUint240(uint256 value) internal pure returns (uint240) {\n require(value <= type(uint240).max, \"SafeCast: value doesn't fit in 240 bits\");\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 * _Available since v4.7._\n */\n function toUint232(uint256 value) internal pure returns (uint232) {\n require(value <= type(uint232).max, \"SafeCast: value doesn't fit in 232 bits\");\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 * _Available since v4.2._\n */\n function toUint224(uint256 value) internal pure returns (uint224) {\n require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\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 * _Available since v4.7._\n */\n function toUint216(uint256 value) internal pure returns (uint216) {\n require(value <= type(uint216).max, \"SafeCast: value doesn't fit in 216 bits\");\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 * _Available since v4.7._\n */\n function toUint208(uint256 value) internal pure returns (uint208) {\n require(value <= type(uint208).max, \"SafeCast: value doesn't fit in 208 bits\");\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 * _Available since v4.7._\n */\n function toUint200(uint256 value) internal pure returns (uint200) {\n require(value <= type(uint200).max, \"SafeCast: value doesn't fit in 200 bits\");\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 * _Available since v4.7._\n */\n function toUint192(uint256 value) internal pure returns (uint192) {\n require(value <= type(uint192).max, \"SafeCast: value doesn't fit in 192 bits\");\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 * _Available since v4.7._\n */\n function toUint184(uint256 value) internal pure returns (uint184) {\n require(value <= type(uint184).max, \"SafeCast: value doesn't fit in 184 bits\");\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 * _Available since v4.7._\n */\n function toUint176(uint256 value) internal pure returns (uint176) {\n require(value <= type(uint176).max, \"SafeCast: value doesn't fit in 176 bits\");\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 * _Available since v4.7._\n */\n function toUint168(uint256 value) internal pure returns (uint168) {\n require(value <= type(uint168).max, \"SafeCast: value doesn't fit in 168 bits\");\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 * _Available since v4.7._\n */\n function toUint160(uint256 value) internal pure returns (uint160) {\n require(value <= type(uint160).max, \"SafeCast: value doesn't fit in 160 bits\");\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 * _Available since v4.7._\n */\n function toUint152(uint256 value) internal pure returns (uint152) {\n require(value <= type(uint152).max, \"SafeCast: value doesn't fit in 152 bits\");\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 * _Available since v4.7._\n */\n function toUint144(uint256 value) internal pure returns (uint144) {\n require(value <= type(uint144).max, \"SafeCast: value doesn't fit in 144 bits\");\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 * _Available since v4.7._\n */\n function toUint136(uint256 value) internal pure returns (uint136) {\n require(value <= type(uint136).max, \"SafeCast: value doesn't fit in 136 bits\");\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 * _Available since v2.5._\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\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 * _Available since v4.7._\n */\n function toUint120(uint256 value) internal pure returns (uint120) {\n require(value <= type(uint120).max, \"SafeCast: value doesn't fit in 120 bits\");\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 * _Available since v4.7._\n */\n function toUint112(uint256 value) internal pure returns (uint112) {\n require(value <= type(uint112).max, \"SafeCast: value doesn't fit in 112 bits\");\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 * _Available since v4.7._\n */\n function toUint104(uint256 value) internal pure returns (uint104) {\n require(value <= type(uint104).max, \"SafeCast: value doesn't fit in 104 bits\");\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 * _Available since v4.2._\n */\n function toUint96(uint256 value) internal pure returns (uint96) {\n require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\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 * _Available since v4.7._\n */\n function toUint88(uint256 value) internal pure returns (uint88) {\n require(value <= type(uint88).max, \"SafeCast: value doesn't fit in 88 bits\");\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 * _Available since v4.7._\n */\n function toUint80(uint256 value) internal pure returns (uint80) {\n require(value <= type(uint80).max, \"SafeCast: value doesn't fit in 80 bits\");\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 * _Available since v4.7._\n */\n function toUint72(uint256 value) internal pure returns (uint72) {\n require(value <= type(uint72).max, \"SafeCast: value doesn't fit in 72 bits\");\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 * _Available since v2.5._\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\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 * _Available since v4.7._\n */\n function toUint56(uint256 value) internal pure returns (uint56) {\n require(value <= type(uint56).max, \"SafeCast: value doesn't fit in 56 bits\");\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 * _Available since v4.7._\n */\n function toUint48(uint256 value) internal pure returns (uint48) {\n require(value <= type(uint48).max, \"SafeCast: value doesn't fit in 48 bits\");\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 * _Available since v4.7._\n */\n function toUint40(uint256 value) internal pure returns (uint40) {\n require(value <= type(uint40).max, \"SafeCast: value doesn't fit in 40 bits\");\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 * _Available since v2.5._\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\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 * _Available since v4.7._\n */\n function toUint24(uint256 value) internal pure returns (uint24) {\n require(value <= type(uint24).max, \"SafeCast: value doesn't fit in 24 bits\");\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 * _Available since v2.5._\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\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 * _Available since v2.5._\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\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 * _Available since v3.0._\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\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 * _Available since v4.7._\n */\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\n downcasted = int248(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 248 bits\");\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 * _Available since v4.7._\n */\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\n downcasted = int240(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 240 bits\");\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 * _Available since v4.7._\n */\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\n downcasted = int232(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 232 bits\");\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 * _Available since v4.7._\n */\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\n downcasted = int224(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 224 bits\");\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 * _Available since v4.7._\n */\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\n downcasted = int216(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 216 bits\");\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 * _Available since v4.7._\n */\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\n downcasted = int208(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 208 bits\");\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 * _Available since v4.7._\n */\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\n downcasted = int200(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 200 bits\");\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 * _Available since v4.7._\n */\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\n downcasted = int192(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 192 bits\");\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 * _Available since v4.7._\n */\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\n downcasted = int184(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 184 bits\");\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 * _Available since v4.7._\n */\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\n downcasted = int176(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 176 bits\");\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 * _Available since v4.7._\n */\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\n downcasted = int168(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 168 bits\");\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 * _Available since v4.7._\n */\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\n downcasted = int160(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 160 bits\");\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 * _Available since v4.7._\n */\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\n downcasted = int152(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 152 bits\");\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 * _Available since v4.7._\n */\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\n downcasted = int144(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 144 bits\");\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 * _Available since v4.7._\n */\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\n downcasted = int136(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 136 bits\");\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 * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\n downcasted = int128(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 128 bits\");\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 * _Available since v4.7._\n */\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\n downcasted = int120(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 120 bits\");\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 * _Available since v4.7._\n */\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\n downcasted = int112(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 112 bits\");\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 * _Available since v4.7._\n */\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\n downcasted = int104(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 104 bits\");\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 * _Available since v4.7._\n */\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\n downcasted = int96(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 96 bits\");\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 * _Available since v4.7._\n */\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\n downcasted = int88(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 88 bits\");\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 * _Available since v4.7._\n */\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\n downcasted = int80(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 80 bits\");\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 * _Available since v4.7._\n */\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\n downcasted = int72(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 72 bits\");\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 * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\n downcasted = int64(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 64 bits\");\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 * _Available since v4.7._\n */\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\n downcasted = int56(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 56 bits\");\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 * _Available since v4.7._\n */\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\n downcasted = int48(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 48 bits\");\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 * _Available since v4.7._\n */\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\n downcasted = int40(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 40 bits\");\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 * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\n downcasted = int32(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 32 bits\");\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 * _Available since v4.7._\n */\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\n downcasted = int24(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 24 bits\");\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 * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\n downcasted = int16(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 16 bits\");\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 * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\n downcasted = int8(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 8 bits\");\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 * _Available since v3.0._\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 require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/SignedMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard signed math utilities missing in the Solidity language.\n */\nlibrary SignedMath {\n /**\n * @dev Returns the largest of two signed numbers.\n */\n function max(int256 a, int256 b) internal pure returns (int256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two signed numbers.\n */\n function min(int256 a, int256 b) internal pure returns (int256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two signed numbers without overflow.\n * The result is rounded towards zero.\n */\n function average(int256 a, int256 b) internal pure returns (int256) {\n // Formula from the book \"Hacker's Delight\"\n int256 x = (a & b) + ((a ^ b) >> 1);\n return x + (int256(uint256(x) >> 255) & (a ^ b));\n }\n\n /**\n * @dev Returns the absolute unsigned value of a signed value.\n */\n function abs(int256 n) internal pure returns (uint256) {\n unchecked {\n // must be unchecked in order to support `n = type(int256).min`\n return uint256(n >= 0 ? n : -n);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/Math.sol\";\nimport \"./math/SignedMath.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n unchecked {\n uint256 length = Math.log10(value) + 1;\n string memory buffer = new string(length);\n uint256 ptr;\n /// @solidity memory-safe-assembly\n assembly {\n ptr := add(buffer, add(32, length))\n }\n while (true) {\n ptr--;\n /// @solidity memory-safe-assembly\n assembly {\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n }\n value /= 10;\n if (value == 0) break;\n }\n return buffer;\n }\n }\n\n /**\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\n */\n function toString(int256 value) internal pure returns (string memory) {\n return string(abi.encodePacked(value < 0 ? \"-\" : \"\", toString(SignedMath.abs(value))));\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n unchecked {\n return toHexString(value, Math.log256(value) + 1);\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n\n /**\n * @dev Returns true if the two strings are equal.\n */\n function equal(string memory a, string memory b) internal pure returns (bool) {\n return keccak256(bytes(a)) == keccak256(bytes(b));\n }\n}\n" + }, + "contracts/aa-4337/core/BaseAccount.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-empty-blocks */\n\nimport \"../interfaces/IAccount.sol\";\nimport \"../interfaces/IEntryPoint.sol\";\nimport \"./Helpers.sol\";\n\n/**\n * Basic account implementation.\n * this contract provides the basic logic for implementing the IAccount interface - validateUserOp\n * specific account implementation should inherit it and provide the account-specific logic\n */\nabstract contract BaseAccount is IAccount {\n using UserOperationLib for UserOperation;\n\n //return value in case of signature failure, with no time-range.\n // equivalent to _packValidationData(true,0,0);\n uint256 internal constant SIG_VALIDATION_FAILED = 1;\n\n /**\n * Return the account nonce.\n * This method returns the next sequential nonce.\n * For a nonce of a specific key, use `entrypoint.getNonce(account, key)`\n */\n function getNonce() public view virtual returns (uint256) {\n return entryPoint().getNonce(address(this), 0);\n }\n\n /**\n * return the entryPoint used by this account.\n * subclass should return the current entryPoint used by this account.\n */\n function entryPoint() public view virtual returns (IEntryPoint);\n\n /**\n * Validate user's signature and nonce.\n * subclass doesn't need to override this method. Instead, it should override the specific internal validation methods.\n */\n function validateUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 missingAccountFunds\n ) external virtual override returns (uint256 validationData) {\n _requireFromEntryPoint();\n validationData = _validateSignature(userOp, userOpHash);\n _validateNonce(userOp.nonce);\n _payPrefund(missingAccountFunds);\n }\n\n /**\n * ensure the request comes from the known entrypoint.\n */\n function _requireFromEntryPoint() internal view virtual {\n require(\n msg.sender == address(entryPoint()),\n \"account: not from EntryPoint\"\n );\n }\n\n /**\n * validate the signature is valid for this message.\n * @param userOp validate the userOp.signature field\n * @param userOpHash convenient field: the hash of the request, to check the signature against\n * (also hashes the entrypoint and chain id)\n * @return validationData signature and time-range of this operation\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * If the account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function _validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) internal virtual returns (uint256 validationData);\n\n /**\n * Validate the nonce of the UserOperation.\n * This method may validate the nonce requirement of this account.\n * e.g.\n * To limit the nonce to use sequenced UserOps only (no \"out of order\" UserOps):\n * `require(nonce < type(uint64).max)`\n * For a hypothetical account that *requires* the nonce to be out-of-order:\n * `require(nonce & type(uint64).max == 0)`\n *\n * The actual nonce uniqueness is managed by the EntryPoint, and thus no other\n * action is needed by the account itself.\n *\n * @param nonce to validate\n *\n * solhint-disable-next-line no-empty-blocks\n */\n function _validateNonce(uint256 nonce) internal view virtual {}\n\n /**\n * sends to the entrypoint (msg.sender) the missing funds for this transaction.\n * subclass MAY override this method for better funds management\n * (e.g. send to the entryPoint more than the minimum required, so that in future transactions\n * it will not be required to send again)\n * @param missingAccountFunds the minimum value this method should send the entrypoint.\n * this value MAY be zero, in case there is enough deposit, or the userOp has a paymaster.\n */\n function _payPrefund(uint256 missingAccountFunds) internal virtual {\n if (missingAccountFunds != 0) {\n (bool success, ) = payable(msg.sender).call{\n value: missingAccountFunds,\n gas: type(uint256).max\n }(\"\");\n (success);\n //ignore failure (its EntryPoint's job to verify, not account.)\n }\n }\n}\n" + }, + "contracts/aa-4337/core/EntryPoint.sol": { + "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n\nimport \"../interfaces/IAccount.sol\";\nimport \"../interfaces/IPaymaster.sol\";\nimport \"../interfaces/IEntryPoint.sol\";\n\nimport \"../utils/Exec.sol\";\nimport \"./StakeManager.sol\";\nimport \"./SenderCreator.sol\";\nimport \"./Helpers.sol\";\nimport \"./NonceManager.sol\";\nimport \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\n\ncontract EntryPoint is\n IEntryPoint,\n StakeManager,\n NonceManager,\n ReentrancyGuard\n{\n using UserOperationLib for UserOperation;\n\n SenderCreator private immutable senderCreator = new SenderCreator();\n\n // internal value used during simulation: need to query aggregator.\n address private constant SIMULATE_FIND_AGGREGATOR = address(1);\n\n // marker for inner call revert on out of gas\n bytes32 private constant INNER_OUT_OF_GAS = hex\"deaddead\";\n\n uint256 private constant REVERT_REASON_MAX_LEN = 2048;\n\n /**\n * for simulation purposes, validateUserOp (and validatePaymasterUserOp) must return this value\n * in case of signature failure, instead of revert.\n */\n uint256 public constant SIG_VALIDATION_FAILED = 1;\n\n /**\n * compensate the caller's beneficiary address with the collected fees of all UserOperations.\n * @param beneficiary the address to receive the fees\n * @param amount amount to transfer.\n */\n function _compensate(address payable beneficiary, uint256 amount) internal {\n require(beneficiary != address(0), \"AA90 invalid beneficiary\");\n (bool success, ) = beneficiary.call{value: amount}(\"\");\n require(success, \"AA91 failed send to beneficiary\");\n }\n\n /**\n * execute a user op\n * @param opIndex index into the opInfo array\n * @param userOp the userOp to execute\n * @param opInfo the opInfo filled by validatePrepayment for this userOp.\n * @return collected the total amount this userOp paid.\n */\n function _executeUserOp(\n uint256 opIndex,\n UserOperation calldata userOp,\n UserOpInfo memory opInfo\n ) private returns (uint256 collected) {\n uint256 preGas = gasleft();\n bytes memory context = getMemoryBytesFromOffset(opInfo.contextOffset);\n\n try this.innerHandleOp(userOp.callData, opInfo, context) returns (\n uint256 _actualGasCost\n ) {\n collected = _actualGasCost;\n } catch {\n bytes32 innerRevertCode;\n assembly {\n returndatacopy(0, 0, 32)\n innerRevertCode := mload(0)\n }\n // handleOps was called with gas limit too low. abort entire bundle.\n if (innerRevertCode == INNER_OUT_OF_GAS) {\n //report paymaster, since if it is not deliberately caused by the bundler,\n // it must be a revert caused by paymaster.\n revert FailedOp(opIndex, \"AA95 out of gas\");\n }\n\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n collected = _handlePostOp(\n opIndex,\n IPaymaster.PostOpMode.postOpReverted,\n opInfo,\n context,\n actualGas\n );\n }\n }\n\n /**\n * Execute a batch of UserOperations.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(\n UserOperation[] calldata ops,\n address payable beneficiary\n ) public nonReentrant {\n uint256 opslen = ops.length;\n UserOpInfo[] memory opInfos = new UserOpInfo[](opslen);\n\n unchecked {\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[i];\n (\n uint256 validationData,\n uint256 pmValidationData\n ) = _validatePrepayment(i, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(\n i,\n validationData,\n pmValidationData,\n address(0)\n );\n }\n\n uint256 collected = 0;\n emit BeforeExecution();\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(i, ops[i], opInfos[i]);\n }\n\n _compensate(beneficiary, collected);\n } //unchecked\n }\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) public nonReentrant {\n uint256 opasLen = opsPerAggregator.length;\n uint256 totalOps = 0;\n for (uint256 i = 0; i < opasLen; i++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[i];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n //address(1) is special marker of \"signature error\"\n require(\n address(aggregator) != address(1),\n \"AA96 invalid aggregator\"\n );\n\n if (address(aggregator) != address(0)) {\n // solhint-disable-next-line no-empty-blocks\n try aggregator.validateSignatures(ops, opa.signature) {} catch {\n revert SignatureValidationFailed(address(aggregator));\n }\n }\n\n totalOps += ops.length;\n }\n\n UserOpInfo[] memory opInfos = new UserOpInfo[](totalOps);\n\n emit BeforeExecution();\n\n uint256 opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n uint256 opslen = ops.length;\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[opIndex];\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(opIndex, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(\n i,\n validationData,\n paymasterValidationData,\n address(aggregator)\n );\n opIndex++;\n }\n }\n\n uint256 collected = 0;\n opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n emit SignatureAggregatorChanged(address(opa.aggregator));\n UserOperation[] calldata ops = opa.userOps;\n uint256 opslen = ops.length;\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(opIndex, ops[i], opInfos[opIndex]);\n opIndex++;\n }\n }\n emit SignatureAggregatorChanged(address(0));\n\n _compensate(beneficiary, collected);\n }\n\n /// @inheritdoc IEntryPoint\n function simulateHandleOp(\n UserOperation calldata op,\n address target,\n bytes calldata targetCallData\n ) external override {\n UserOpInfo memory opInfo;\n _simulationOnlyValidations(op);\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(0, op, opInfo);\n ValidationData memory data = _intersectTimeRange(\n validationData,\n paymasterValidationData\n );\n\n numberMarker();\n uint256 paid = _executeUserOp(0, op, opInfo);\n numberMarker();\n bool targetSuccess;\n bytes memory targetResult;\n if (target != address(0)) {\n (targetSuccess, targetResult) = target.call(targetCallData);\n }\n revert ExecutionResult(\n opInfo.preOpGas,\n paid,\n data.validAfter,\n data.validUntil,\n targetSuccess,\n targetResult\n );\n }\n\n // A memory copy of UserOp static fields only.\n // Excluding: callData, initCode and signature. Replacing paymasterAndData with paymaster.\n struct MemoryUserOp {\n address sender;\n uint256 nonce;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n address paymaster;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n }\n\n struct UserOpInfo {\n MemoryUserOp mUserOp;\n bytes32 userOpHash;\n uint256 prefund;\n uint256 contextOffset;\n uint256 preOpGas;\n }\n\n /**\n * inner function to handle a UserOperation.\n * Must be declared \"external\" to open a call context, but it can only be called by handleOps.\n */\n function innerHandleOp(\n bytes memory callData,\n UserOpInfo memory opInfo,\n bytes calldata context\n ) external returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n require(msg.sender == address(this), \"AA92 internal call only\");\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n\n uint callGasLimit = mUserOp.callGasLimit;\n unchecked {\n // handleOps was called with gas limit too low. abort entire bundle.\n if (\n gasleft() < callGasLimit + mUserOp.verificationGasLimit + 5000\n ) {\n assembly {\n mstore(0, INNER_OUT_OF_GAS)\n revert(0, 32)\n }\n }\n }\n\n IPaymaster.PostOpMode mode = IPaymaster.PostOpMode.opSucceeded;\n if (callData.length > 0) {\n bool success = Exec.call(mUserOp.sender, 0, callData, callGasLimit);\n if (!success) {\n bytes memory result = Exec.getReturnData(REVERT_REASON_MAX_LEN);\n if (result.length > 0) {\n emit UserOperationRevertReason(\n opInfo.userOpHash,\n mUserOp.sender,\n mUserOp.nonce,\n result\n );\n }\n mode = IPaymaster.PostOpMode.opReverted;\n }\n }\n\n unchecked {\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n //note: opIndex is ignored (relevant only if mode==postOpReverted, which is only possible outside of innerHandleOp)\n return _handlePostOp(0, mode, opInfo, context, actualGas);\n }\n }\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(\n UserOperation calldata userOp\n ) public view returns (bytes32) {\n return\n keccak256(abi.encode(userOp.hash(), address(this), block.chainid));\n }\n\n /**\n * copy general fields from userOp into the memory opInfo structure.\n */\n function _copyUserOpToMemory(\n UserOperation calldata userOp,\n MemoryUserOp memory mUserOp\n ) internal pure {\n mUserOp.sender = userOp.sender;\n mUserOp.nonce = userOp.nonce;\n mUserOp.callGasLimit = userOp.callGasLimit;\n mUserOp.verificationGasLimit = userOp.verificationGasLimit;\n mUserOp.preVerificationGas = userOp.preVerificationGas;\n mUserOp.maxFeePerGas = userOp.maxFeePerGas;\n mUserOp.maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes calldata paymasterAndData = userOp.paymasterAndData;\n if (paymasterAndData.length > 0) {\n require(\n paymasterAndData.length >= 20,\n \"AA93 invalid paymasterAndData\"\n );\n mUserOp.paymaster = address(bytes20(paymasterAndData[:20]));\n } else {\n mUserOp.paymaster = address(0);\n }\n }\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external {\n UserOpInfo memory outOpInfo;\n\n _simulationOnlyValidations(userOp);\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(0, userOp, outOpInfo);\n StakeInfo memory paymasterInfo = _getStakeInfo(\n outOpInfo.mUserOp.paymaster\n );\n StakeInfo memory senderInfo = _getStakeInfo(outOpInfo.mUserOp.sender);\n StakeInfo memory factoryInfo;\n {\n bytes calldata initCode = userOp.initCode;\n address factory = initCode.length >= 20\n ? address(bytes20(initCode[0:20]))\n : address(0);\n factoryInfo = _getStakeInfo(factory);\n }\n\n ValidationData memory data = _intersectTimeRange(\n validationData,\n paymasterValidationData\n );\n address aggregator = data.aggregator;\n bool sigFailed = aggregator == address(1);\n ReturnInfo memory returnInfo = ReturnInfo(\n outOpInfo.preOpGas,\n outOpInfo.prefund,\n sigFailed,\n data.validAfter,\n data.validUntil,\n getMemoryBytesFromOffset(outOpInfo.contextOffset)\n );\n\n if (aggregator != address(0) && aggregator != address(1)) {\n AggregatorStakeInfo memory aggregatorInfo = AggregatorStakeInfo(\n aggregator,\n _getStakeInfo(aggregator)\n );\n revert ValidationResultWithAggregation(\n returnInfo,\n senderInfo,\n factoryInfo,\n paymasterInfo,\n aggregatorInfo\n );\n }\n revert ValidationResult(\n returnInfo,\n senderInfo,\n factoryInfo,\n paymasterInfo\n );\n }\n\n function _getRequiredPrefund(\n MemoryUserOp memory mUserOp\n ) internal pure returns (uint256 requiredPrefund) {\n unchecked {\n //when using a Paymaster, the verificationGasLimit is used also to as a limit for the postOp call.\n // our security model might call postOp eventually twice\n uint256 mul = mUserOp.paymaster != address(0) ? 3 : 1;\n uint256 requiredGas = mUserOp.callGasLimit +\n mUserOp.verificationGasLimit *\n mul +\n mUserOp.preVerificationGas;\n\n requiredPrefund = requiredGas * mUserOp.maxFeePerGas;\n }\n }\n\n // create the sender's contract if needed.\n function _createSenderIfNeeded(\n uint256 opIndex,\n UserOpInfo memory opInfo,\n bytes calldata initCode\n ) internal {\n if (initCode.length != 0) {\n address sender = opInfo.mUserOp.sender;\n if (sender.code.length != 0)\n revert FailedOp(opIndex, \"AA10 sender already constructed\");\n address sender1 = senderCreator.createSender{\n gas: opInfo.mUserOp.verificationGasLimit\n }(initCode);\n if (sender1 == address(0))\n revert FailedOp(opIndex, \"AA13 initCode failed or OOG\");\n if (sender1 != sender)\n revert FailedOp(opIndex, \"AA14 initCode must return sender\");\n if (sender1.code.length == 0)\n revert FailedOp(opIndex, \"AA15 initCode must create sender\");\n address factory = address(bytes20(initCode[0:20]));\n emit AccountDeployed(\n opInfo.userOpHash,\n sender,\n factory,\n opInfo.mUserOp.paymaster\n );\n }\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes calldata initCode) public {\n address sender = senderCreator.createSender(initCode);\n revert SenderAddressResult(sender);\n }\n\n function _simulationOnlyValidations(\n UserOperation calldata userOp\n ) internal view {\n // solhint-disable-next-line no-empty-blocks\n try\n this._validateSenderAndPaymaster(\n userOp.initCode,\n userOp.sender,\n userOp.paymasterAndData\n )\n {} catch Error(string memory revertReason) {\n if (bytes(revertReason).length != 0) {\n revert FailedOp(0, revertReason);\n }\n }\n }\n\n /**\n * Called only during simulation.\n * This function always reverts to prevent warm/cold storage differentiation in simulation vs execution.\n */\n function _validateSenderAndPaymaster(\n bytes calldata initCode,\n address sender,\n bytes calldata paymasterAndData\n ) external view {\n if (initCode.length == 0 && sender.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA20 account not deployed\");\n }\n if (paymasterAndData.length >= 20) {\n address paymaster = address(bytes20(paymasterAndData[0:20]));\n if (paymaster.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA30 paymaster not deployed\");\n }\n }\n // always revert\n revert(\"\");\n }\n\n /**\n * call account.validateUserOp.\n * revert (with FailedOp) in case validateUserOp reverts, or account didn't send required prefund.\n * decrement account's deposit if needed\n */\n function _validateAccountPrepayment(\n uint256 opIndex,\n UserOperation calldata op,\n UserOpInfo memory opInfo,\n uint256 requiredPrefund\n )\n internal\n returns (\n uint256 gasUsedByValidateAccountPrepayment,\n uint256 validationData\n )\n {\n unchecked {\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n address sender = mUserOp.sender;\n _createSenderIfNeeded(opIndex, opInfo, op.initCode);\n address paymaster = mUserOp.paymaster;\n numberMarker();\n uint256 missingAccountFunds = 0;\n if (paymaster == address(0)) {\n uint256 bal = balanceOf(sender);\n missingAccountFunds = bal > requiredPrefund\n ? 0\n : requiredPrefund - bal;\n }\n try\n IAccount(sender).validateUserOp{\n gas: mUserOp.verificationGasLimit\n }(op, opInfo.userOpHash, missingAccountFunds)\n returns (uint256 _validationData) {\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA23 reverted: \", revertReason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA23 reverted (or OOG)\");\n }\n if (paymaster == address(0)) {\n DepositInfo storage senderInfo = deposits[sender];\n uint256 deposit = senderInfo.deposit;\n if (requiredPrefund > deposit) {\n revert FailedOp(opIndex, \"AA21 didn't pay prefund\");\n }\n senderInfo.deposit = uint112(deposit - requiredPrefund);\n }\n gasUsedByValidateAccountPrepayment = preGas - gasleft();\n }\n }\n\n /**\n * In case the request has a paymaster:\n * Validate paymaster has enough deposit.\n * Call paymaster.validatePaymasterUserOp.\n * Revert with proper FailedOp in case paymaster reverts.\n * Decrement paymaster's deposit\n */\n function _validatePaymasterPrepayment(\n uint256 opIndex,\n UserOperation calldata op,\n UserOpInfo memory opInfo,\n uint256 requiredPreFund,\n uint256 gasUsedByValidateAccountPrepayment\n ) internal returns (bytes memory context, uint256 validationData) {\n unchecked {\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 verificationGasLimit = mUserOp.verificationGasLimit;\n require(\n verificationGasLimit > gasUsedByValidateAccountPrepayment,\n \"AA41 too little verificationGas\"\n );\n uint256 gas = verificationGasLimit -\n gasUsedByValidateAccountPrepayment;\n\n address paymaster = mUserOp.paymaster;\n DepositInfo storage paymasterInfo = deposits[paymaster];\n uint256 deposit = paymasterInfo.deposit;\n if (deposit < requiredPreFund) {\n revert FailedOp(opIndex, \"AA31 paymaster deposit too low\");\n }\n paymasterInfo.deposit = uint112(deposit - requiredPreFund);\n try\n IPaymaster(paymaster).validatePaymasterUserOp{gas: gas}(\n op,\n opInfo.userOpHash,\n requiredPreFund\n )\n returns (bytes memory _context, uint256 _validationData) {\n context = _context;\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA33 reverted: \", revertReason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA33 reverted (or OOG)\");\n }\n }\n }\n\n /**\n * revert if either account validationData or paymaster validationData is expired\n */\n function _validateAccountAndPaymasterValidationData(\n uint256 opIndex,\n uint256 validationData,\n uint256 paymasterValidationData,\n address expectedAggregator\n ) internal view {\n (address aggregator, bool outOfTimeRange) = _getValidationData(\n validationData\n );\n if (expectedAggregator != aggregator) {\n revert FailedOp(opIndex, \"AA24 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA22 expired or not due\");\n }\n //pmAggregator is not a real signature aggregator: we don't have logic to handle it as address.\n // non-zero address means that the paymaster fails due to some signature check (which is ok only during estimation)\n address pmAggregator;\n (pmAggregator, outOfTimeRange) = _getValidationData(\n paymasterValidationData\n );\n if (pmAggregator != address(0)) {\n revert FailedOp(opIndex, \"AA34 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA32 paymaster expired or not due\");\n }\n }\n\n function _getValidationData(\n uint256 validationData\n ) internal view returns (address aggregator, bool outOfTimeRange) {\n if (validationData == 0) {\n return (address(0), false);\n }\n ValidationData memory data = _parseValidationData(validationData);\n // solhint-disable-next-line not-rely-on-time\n outOfTimeRange =\n block.timestamp > data.validUntil ||\n block.timestamp < data.validAfter;\n aggregator = data.aggregator;\n }\n\n /**\n * validate account and paymaster (if defined).\n * also make sure total validation doesn't exceed verificationGasLimit\n * this method is called off-chain (simulateValidation()) and on-chain (from handleOps)\n * @param opIndex the index of this userOp into the \"opInfos\" array\n * @param userOp the userOp to validate\n */\n function _validatePrepayment(\n uint256 opIndex,\n UserOperation calldata userOp,\n UserOpInfo memory outOpInfo\n )\n private\n returns (uint256 validationData, uint256 paymasterValidationData)\n {\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = outOpInfo.mUserOp;\n _copyUserOpToMemory(userOp, mUserOp);\n outOpInfo.userOpHash = getUserOpHash(userOp);\n\n // validate all numeric values in userOp are well below 128 bit, so they can safely be added\n // and multiplied without causing overflow\n uint256 maxGasValues = mUserOp.preVerificationGas |\n mUserOp.verificationGasLimit |\n mUserOp.callGasLimit |\n userOp.maxFeePerGas |\n userOp.maxPriorityFeePerGas;\n require(maxGasValues <= type(uint120).max, \"AA94 gas values overflow\");\n\n uint256 gasUsedByValidateAccountPrepayment;\n uint256 requiredPreFund = _getRequiredPrefund(mUserOp);\n (\n gasUsedByValidateAccountPrepayment,\n validationData\n ) = _validateAccountPrepayment(\n opIndex,\n userOp,\n outOpInfo,\n requiredPreFund\n );\n\n if (!_validateAndUpdateNonce(mUserOp.sender, mUserOp.nonce)) {\n revert FailedOp(opIndex, \"AA25 invalid account nonce\");\n }\n\n //a \"marker\" where account opcode validation is done and paymaster opcode validation is about to start\n // (used only by off-chain simulateValidation)\n numberMarker();\n\n bytes memory context;\n if (mUserOp.paymaster != address(0)) {\n (context, paymasterValidationData) = _validatePaymasterPrepayment(\n opIndex,\n userOp,\n outOpInfo,\n requiredPreFund,\n gasUsedByValidateAccountPrepayment\n );\n }\n unchecked {\n uint256 gasUsed = preGas - gasleft();\n\n if (userOp.verificationGasLimit < gasUsed) {\n revert FailedOp(opIndex, \"AA40 over verificationGasLimit\");\n }\n outOpInfo.prefund = requiredPreFund;\n outOpInfo.contextOffset = getOffsetOfMemoryBytes(context);\n outOpInfo.preOpGas = preGas - gasleft() + userOp.preVerificationGas;\n }\n }\n\n /**\n * process post-operation.\n * called just after the callData is executed.\n * if a paymaster is defined and its validation returned a non-empty context, its postOp is called.\n * the excess amount is refunded to the account (or paymaster - if it was used in the request)\n * @param opIndex index in the batch\n * @param mode - whether is called from innerHandleOp, or outside (postOpReverted)\n * @param opInfo userOp fields and info collected during validation\n * @param context the context returned in validatePaymasterUserOp\n * @param actualGas the gas used so far by this user operation\n */\n function _handlePostOp(\n uint256 opIndex,\n IPaymaster.PostOpMode mode,\n UserOpInfo memory opInfo,\n bytes memory context,\n uint256 actualGas\n ) private returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n unchecked {\n address refundAddress;\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 gasPrice = getUserOpGasPrice(mUserOp);\n\n address paymaster = mUserOp.paymaster;\n if (paymaster == address(0)) {\n refundAddress = mUserOp.sender;\n } else {\n refundAddress = paymaster;\n if (context.length > 0) {\n actualGasCost = actualGas * gasPrice;\n if (mode != IPaymaster.PostOpMode.postOpReverted) {\n IPaymaster(paymaster).postOp{\n gas: mUserOp.verificationGasLimit\n }(mode, context, actualGasCost);\n } else {\n // solhint-disable-next-line no-empty-blocks\n try\n IPaymaster(paymaster).postOp{\n gas: mUserOp.verificationGasLimit\n }(mode, context, actualGasCost)\n {} catch Error(string memory reason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA50 postOp reverted: \", reason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA50 postOp revert\");\n }\n }\n }\n }\n actualGas += preGas - gasleft();\n actualGasCost = actualGas * gasPrice;\n if (opInfo.prefund < actualGasCost) {\n revert FailedOp(opIndex, \"AA51 prefund below actualGasCost\");\n }\n uint256 refund = opInfo.prefund - actualGasCost;\n _incrementDeposit(refundAddress, refund);\n bool success = mode == IPaymaster.PostOpMode.opSucceeded;\n emit UserOperationEvent(\n opInfo.userOpHash,\n mUserOp.sender,\n mUserOp.paymaster,\n mUserOp.nonce,\n success,\n actualGasCost,\n actualGas\n );\n } // unchecked\n }\n\n /**\n * the gas price this UserOp agrees to pay.\n * relayer/block builder might submit the TX with higher priorityFee, but the user should not\n */\n function getUserOpGasPrice(\n MemoryUserOp memory mUserOp\n ) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = mUserOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = mUserOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n function getOffsetOfMemoryBytes(\n bytes memory data\n ) internal pure returns (uint256 offset) {\n assembly {\n offset := data\n }\n }\n\n function getMemoryBytesFromOffset(\n uint256 offset\n ) internal pure returns (bytes memory data) {\n assembly {\n data := offset\n }\n }\n\n //place the NUMBER opcode in the code.\n // this is used as a marker during simulation, as this OP is completely banned from the simulated code of the\n // account and paymaster.\n function numberMarker() internal view {\n assembly {\n mstore(0, number())\n }\n }\n}\n" + }, + "contracts/aa-4337/core/Helpers.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable no-inline-assembly */\n\n/**\n * returned data from validateUserOp.\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\n * @param aggregator - address(0) - the account validated the signature by itself.\n * address(1) - the account failed to validate the signature.\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\n * @param validAfter - this UserOp is valid only after this timestamp.\n * @param validaUntil - this UserOp is valid only up to this timestamp.\n */\nstruct ValidationData {\n address aggregator;\n uint48 validAfter;\n uint48 validUntil;\n}\n\n//extract sigFailed, validAfter, validUntil.\n// also convert zero validUntil to type(uint48).max\nfunction _parseValidationData(\n uint validationData\n) pure returns (ValidationData memory data) {\n address aggregator = address(uint160(validationData));\n uint48 validUntil = uint48(validationData >> 160);\n if (validUntil == 0) {\n validUntil = type(uint48).max;\n }\n uint48 validAfter = uint48(validationData >> (48 + 160));\n return ValidationData(aggregator, validAfter, validUntil);\n}\n\n// intersect account and paymaster ranges.\nfunction _intersectTimeRange(\n uint256 validationData,\n uint256 paymasterValidationData\n) pure returns (ValidationData memory) {\n ValidationData memory accountValidationData = _parseValidationData(\n validationData\n );\n ValidationData memory pmValidationData = _parseValidationData(\n paymasterValidationData\n );\n address aggregator = accountValidationData.aggregator;\n if (aggregator == address(0)) {\n aggregator = pmValidationData.aggregator;\n }\n uint48 validAfter = accountValidationData.validAfter;\n uint48 validUntil = accountValidationData.validUntil;\n uint48 pmValidAfter = pmValidationData.validAfter;\n uint48 pmValidUntil = pmValidationData.validUntil;\n\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\n return ValidationData(aggregator, validAfter, validUntil);\n}\n\n/**\n * helper to pack the return value for validateUserOp\n * @param data - the ValidationData to pack\n */\nfunction _packValidationData(\n ValidationData memory data\n) pure returns (uint256) {\n return\n uint160(data.aggregator) |\n (uint256(data.validUntil) << 160) |\n (uint256(data.validAfter) << (160 + 48));\n}\n\n/**\n * helper to pack the return value for validateUserOp, when not using an aggregator\n * @param sigFailed - true for signature failure, false for success\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\n * @param validAfter first timestamp this UserOperation is valid\n */\nfunction _packValidationData(\n bool sigFailed,\n uint48 validUntil,\n uint48 validAfter\n) pure returns (uint256) {\n return\n (sigFailed ? 1 : 0) |\n (uint256(validUntil) << 160) |\n (uint256(validAfter) << (160 + 48));\n}\n\n/**\n * keccak function over calldata.\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\n */\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\n assembly {\n let mem := mload(0x40)\n let len := data.length\n calldatacopy(mem, data.offset, len)\n ret := keccak256(mem, len)\n }\n}\n" + }, + "contracts/aa-4337/core/NonceManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\nimport \"../interfaces/IEntryPoint.sol\";\n\n/**\n * nonce management functionality\n */\ncontract NonceManager is INonceManager {\n /**\n * The next valid sequence number for a given nonce key.\n */\n mapping(address => mapping(uint192 => uint256)) public nonceSequenceNumber;\n\n function getNonce(\n address sender,\n uint192 key\n ) public view override returns (uint256 nonce) {\n return nonceSequenceNumber[sender][key] | (uint256(key) << 64);\n }\n\n // allow an account to manually increment its own nonce.\n // (mainly so that during construction nonce can be made non-zero,\n // to \"absorb\" the gas cost of first nonce increment to 1st transaction (construction),\n // not to 2nd transaction)\n function incrementNonce(uint192 key) public override {\n nonceSequenceNumber[msg.sender][key]++;\n }\n\n /**\n * validate nonce uniqueness for this account.\n * called just after validateUserOp()\n */\n function _validateAndUpdateNonce(\n address sender,\n uint256 nonce\n ) internal returns (bool) {\n uint192 key = uint192(nonce >> 64);\n uint64 seq = uint64(nonce);\n return nonceSequenceNumber[sender][key]++ == seq;\n }\n}\n" + }, + "contracts/aa-4337/core/SenderCreator.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/**\n * helper contract for EntryPoint, to call userOp.initCode from a \"neutral\" address,\n * which is explicitly not the entryPoint itself.\n */\ncontract SenderCreator {\n /**\n * call the \"initCode\" factory to create and return the sender account address\n * @param initCode the initCode value from a UserOp. contains 20 bytes of factory address, followed by calldata\n * @return sender the returned address of the created account, or zero address on failure.\n */\n function createSender(\n bytes calldata initCode\n ) external returns (address sender) {\n address factory = address(bytes20(initCode[0:20]));\n bytes memory initCallData = initCode[20:];\n bool success;\n /* solhint-disable no-inline-assembly */\n assembly {\n success := call(\n gas(),\n factory,\n 0,\n add(initCallData, 0x20),\n mload(initCallData),\n 0,\n 32\n )\n sender := mload(0)\n }\n if (!success) {\n sender = address(0);\n }\n }\n}\n" + }, + "contracts/aa-4337/core/StakeManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity 0.8.21;\n\nimport \"../interfaces/IStakeManager.sol\";\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable not-rely-on-time */\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by a paymaster.\n */\nabstract contract StakeManager is IStakeManager {\n /// maps paymaster to their deposits and stakes\n mapping(address => DepositInfo) public deposits;\n\n /// @inheritdoc IStakeManager\n function getDepositInfo(\n address account\n ) public view returns (DepositInfo memory info) {\n return deposits[account];\n }\n\n // internal method to return just the stake info\n function _getStakeInfo(\n address addr\n ) internal view returns (StakeInfo memory info) {\n DepositInfo storage depositInfo = deposits[addr];\n info.stake = depositInfo.stake;\n info.unstakeDelaySec = depositInfo.unstakeDelaySec;\n }\n\n /// return the deposit (for gas payment) of the account\n function balanceOf(address account) public view returns (uint256) {\n return deposits[account].deposit;\n }\n\n receive() external payable {\n depositTo(msg.sender);\n }\n\n function _incrementDeposit(address account, uint256 amount) internal {\n DepositInfo storage info = deposits[account];\n uint256 newAmount = info.deposit + amount;\n require(newAmount <= type(uint112).max, \"deposit overflow\");\n info.deposit = uint112(newAmount);\n }\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) public payable {\n _incrementDeposit(account, msg.value);\n DepositInfo storage info = deposits[account];\n emit Deposited(account, info.deposit);\n }\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 unstakeDelaySec) public payable {\n DepositInfo storage info = deposits[msg.sender];\n require(unstakeDelaySec > 0, \"must specify unstake delay\");\n require(\n unstakeDelaySec >= info.unstakeDelaySec,\n \"cannot decrease unstake time\"\n );\n uint256 stake = info.stake + msg.value;\n require(stake > 0, \"no stake specified\");\n require(stake <= type(uint112).max, \"stake overflow\");\n deposits[msg.sender] = DepositInfo(\n info.deposit,\n true,\n uint112(stake),\n unstakeDelaySec,\n 0\n );\n emit StakeLocked(msg.sender, stake, unstakeDelaySec);\n }\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external {\n DepositInfo storage info = deposits[msg.sender];\n require(info.unstakeDelaySec != 0, \"not staked\");\n require(info.staked, \"already unstaking\");\n uint48 withdrawTime = uint48(block.timestamp) + info.unstakeDelaySec;\n info.withdrawTime = withdrawTime;\n info.staked = false;\n emit StakeUnlocked(msg.sender, withdrawTime);\n }\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external {\n DepositInfo storage info = deposits[msg.sender];\n uint256 stake = info.stake;\n require(stake > 0, \"No stake to withdraw\");\n require(info.withdrawTime > 0, \"must call unlockStake() first\");\n require(\n info.withdrawTime <= block.timestamp,\n \"Stake withdrawal is not due\"\n );\n info.unstakeDelaySec = 0;\n info.withdrawTime = 0;\n info.stake = 0;\n emit StakeWithdrawn(msg.sender, withdrawAddress, stake);\n (bool success, ) = withdrawAddress.call{value: stake}(\"\");\n require(success, \"failed to withdraw stake\");\n }\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(\n address payable withdrawAddress,\n uint256 withdrawAmount\n ) external {\n DepositInfo storage info = deposits[msg.sender];\n require(withdrawAmount <= info.deposit, \"Withdraw amount too large\");\n info.deposit = uint112(info.deposit - withdrawAmount);\n emit Withdrawn(msg.sender, withdrawAddress, withdrawAmount);\n (bool success, ) = withdrawAddress.call{value: withdrawAmount}(\"\");\n require(success, \"failed to withdraw\");\n }\n}\n" + }, + "contracts/aa-4337/interfaces/IAccount.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\ninterface IAccount {\n /**\n * Validate user's signature and nonce\n * the entryPoint will make the call to the recipient only if this validation call returns successfully.\n * signature failure should be reported by returning SIG_VALIDATION_FAILED (1).\n * This allows making a \"simulation call\" without a valid signature\n * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure.\n *\n * @dev Must validate caller is the entryPoint.\n * Must validate the signature and nonce\n * @param userOp the operation that is about to be executed.\n * @param userOpHash hash of the user's request data. can be used as the basis for signature.\n * @param missingAccountFunds missing funds on the account's deposit in the entrypoint.\n * This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call.\n * The excess is left as a deposit in the entrypoint, for future calls.\n * can be withdrawn anytime using \"entryPoint.withdrawTo()\"\n * In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero.\n * @return validationData packaged ValidationData structure. use `_packValidationData` and `_unpackValidationData` to encode and decode\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * If an account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validateUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 missingAccountFunds\n ) external returns (uint256 validationData);\n}\n" + }, + "contracts/aa-4337/interfaces/IAggregator.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * Aggregated Signatures validator.\n */\ninterface IAggregator {\n /**\n * validate aggregated signature.\n * revert if the aggregated signature does not match the given list of operations.\n */\n function validateSignatures(\n UserOperation[] calldata userOps,\n bytes calldata signature\n ) external view;\n\n /**\n * validate signature of a single userOp\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\n * @param userOp the userOperation received from the user.\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\n * (usually empty, unless account and aggregator support some kind of \"multisig\"\n */\n function validateUserOpSignature(\n UserOperation calldata userOp\n ) external view returns (bytes memory sigForUserOp);\n\n /**\n * aggregate multiple signatures into a single value.\n * This method is called off-chain to calculate the signature to pass with handleOps()\n * bundler MAY use optimized custom code perform this aggregation\n * @param userOps array of UserOperations to collect the signatures from.\n * @return aggregatedSignature the aggregated signature\n */\n function aggregateSignatures(\n UserOperation[] calldata userOps\n ) external view returns (bytes memory aggregatedSignature);\n}\n" + }, + "contracts/aa-4337/interfaces/IEntryPoint.sol": { + "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n/* solhint-disable reason-string */\n\nimport \"./UserOperation.sol\";\nimport \"./IStakeManager.sol\";\nimport \"./IAggregator.sol\";\nimport \"./INonceManager.sol\";\n\ninterface IEntryPoint is IStakeManager, INonceManager {\n /***\n * An event emitted after each successful request\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\n * @param sender - the account that generates this request.\n * @param paymaster - if non-null, the paymaster that pays for this request.\n * @param nonce - the nonce value from the request.\n * @param success - true if the sender transaction succeeded, false if reverted.\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\n */\n event UserOperationEvent(\n bytes32 indexed userOpHash,\n address indexed sender,\n address indexed paymaster,\n uint256 nonce,\n bool success,\n uint256 actualGasCost,\n uint256 actualGasUsed\n );\n\n /**\n * account \"sender\" was deployed.\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\n * @param sender the account that is deployed\n * @param factory the factory used to deploy this account (in the initCode)\n * @param paymaster the paymaster used by this UserOp\n */\n event AccountDeployed(\n bytes32 indexed userOpHash,\n address indexed sender,\n address factory,\n address paymaster\n );\n\n /**\n * An event emitted if the UserOperation \"callData\" reverted with non-zero length\n * @param userOpHash the request unique identifier.\n * @param sender the sender of this request\n * @param nonce the nonce used in the request\n * @param revertReason - the return bytes from the (reverted) call to \"callData\".\n */\n event UserOperationRevertReason(\n bytes32 indexed userOpHash,\n address indexed sender,\n uint256 nonce,\n bytes revertReason\n );\n\n /**\n * an event emitted by handleOps(), before starting the execution loop.\n * any event emitted before this event, is part of the validation.\n */\n event BeforeExecution();\n\n /**\n * signature aggregator used by the following UserOperationEvents within this bundle.\n */\n event SignatureAggregatorChanged(address indexed aggregator);\n\n /**\n * a custom revert error of handleOps, to identify the offending op.\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\n * @param reason - revert reason\n * The string starts with a unique code \"AAmn\", where \"m\" is \"1\" for factory, \"2\" for account and \"3\" for paymaster issues,\n * so a failure can be attributed to the correct entity.\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\n */\n error FailedOp(uint256 opIndex, string reason);\n\n /**\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\n */\n error SignatureValidationFailed(address aggregator);\n\n /**\n * Successful result from simulateValidation.\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n */\n error ValidationResult(\n ReturnInfo returnInfo,\n StakeInfo senderInfo,\n StakeInfo factoryInfo,\n StakeInfo paymasterInfo\n );\n\n /**\n * Successful result from simulateValidation, if the account returns a signature aggregator\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\n * bundler MUST use it to verify the signature, or reject the UserOperation\n */\n error ValidationResultWithAggregation(\n ReturnInfo returnInfo,\n StakeInfo senderInfo,\n StakeInfo factoryInfo,\n StakeInfo paymasterInfo,\n AggregatorStakeInfo aggregatorInfo\n );\n\n /**\n * return value of getSenderAddress\n */\n error SenderAddressResult(address sender);\n\n /**\n * return value of simulateHandleOp\n */\n error ExecutionResult(\n uint256 preOpGas,\n uint256 paid,\n uint48 validAfter,\n uint48 validUntil,\n bool targetSuccess,\n bytes targetResult\n );\n\n //UserOps handled, per aggregator\n struct UserOpsPerAggregator {\n UserOperation[] userOps;\n // aggregator address\n IAggregator aggregator;\n // aggregated signature\n bytes signature;\n }\n\n /**\n * Execute a batch of UserOperation.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(\n UserOperation[] calldata ops,\n address payable beneficiary\n ) external;\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) external;\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(\n UserOperation calldata userOp\n ) external view returns (bytes32);\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external;\n\n /**\n * gas and return values during simulation\n * @param preOpGas the gas used for validation (including preValidationGas)\n * @param prefund the required prefund for this operation\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\n */\n struct ReturnInfo {\n uint256 preOpGas;\n uint256 prefund;\n bool sigFailed;\n uint48 validAfter;\n uint48 validUntil;\n bytes paymasterContext;\n }\n\n /**\n * returned aggregated signature info.\n * the aggregator returned by the account, and its current stake.\n */\n struct AggregatorStakeInfo {\n address aggregator;\n StakeInfo stakeInfo;\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes memory initCode) external;\n\n /**\n * simulate full execution of a UserOperation (including both validation and target execution)\n * this method will always revert with \"ExecutionResult\".\n * it performs full validation of the UserOperation, but ignores signature error.\n * an optional target address is called after the userop succeeds, and its value is returned\n * (before the entire call is reverted)\n * Note that in order to collect the the success/failure of the target call, it must be executed\n * with trace enabled to track the emitted events.\n * @param op the UserOperation to simulate\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\n * are set to the return from that call.\n * @param targetCallData callData to pass to target address\n */\n function simulateHandleOp(\n UserOperation calldata op,\n address target,\n bytes calldata targetCallData\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/INonceManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\ninterface INonceManager {\n /**\n * Return the next nonce for this sender.\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\n * But UserOp with different keys can come with arbitrary order.\n *\n * @param sender the account address\n * @param key the high 192 bit of the nonce\n * @return nonce a full nonce to pass for next UserOp with this sender.\n */\n function getNonce(\n address sender,\n uint192 key\n ) external view returns (uint256 nonce);\n\n /**\n * Manually increment the nonce of the sender.\n * This method is exposed just for completeness..\n * Account does NOT need to call it, neither during validation, nor elsewhere,\n * as the EntryPoint will update the nonce regardless.\n * Possible use-case is call it with various keys to \"initialize\" their nonces to one, so that future\n * UserOperations will not pay extra for the first transaction with a given key.\n */\n function incrementNonce(uint192 key) external;\n}\n" + }, + "contracts/aa-4337/interfaces/IPaymaster.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * the interface exposed by a paymaster contract, who agrees to pay the gas for user's operations.\n * a paymaster must hold a stake to cover the required entrypoint stake and also the gas for the transaction.\n */\ninterface IPaymaster {\n enum PostOpMode {\n opSucceeded, // user op succeeded\n opReverted, // user op reverted. still has to pay for gas.\n postOpReverted //user op succeeded, but caused postOp to revert. Now it's a 2nd call, after user's op was deliberately reverted.\n }\n\n /**\n * payment validation: check if paymaster agrees to pay.\n * Must verify sender is the entryPoint.\n * Revert to reject this request.\n * Note that bundlers will reject this method if it changes the state, unless the paymaster is trusted (whitelisted)\n * The paymaster pre-pays using its deposit, and receive back a refund after the postOp method returns.\n * @param userOp the user operation\n * @param userOpHash hash of the user's request data.\n * @param maxCost the maximum cost of this transaction (based on maximum gas and gas price from userOp)\n * @return context value to send to a postOp\n * zero length to signify postOp is not required.\n * @return validationData signature and time-range of this operation, encoded the same as the return value of validateUserOperation\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validatePaymasterUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 maxCost\n ) external returns (bytes memory context, uint256 validationData);\n\n /**\n * post-operation handler.\n * Must verify sender is the entryPoint\n * @param mode enum with the following options:\n * opSucceeded - user operation succeeded.\n * opReverted - user op reverted. still has to pay for gas.\n * postOpReverted - user op succeeded, but caused postOp (in mode=opSucceeded) to revert.\n * Now this is the 2nd call, after user's op was deliberately reverted.\n * @param context - the context value returned by validatePaymasterUserOp\n * @param actualGasCost - actual gas used so far (without this postOp call).\n */\n function postOp(\n PostOpMode mode,\n bytes calldata context,\n uint256 actualGasCost\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/IStakeManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.12;\n\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by the staked entity.\n */\ninterface IStakeManager {\n event Deposited(address indexed account, uint256 totalDeposit);\n\n event Withdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /// Emitted when stake or unstake delay are modified\n event StakeLocked(\n address indexed account,\n uint256 totalStaked,\n uint256 unstakeDelaySec\n );\n\n /// Emitted once a stake is scheduled for withdrawal\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\n\n event StakeWithdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /**\n * @param deposit the entity's deposit\n * @param staked true if this entity is staked.\n * @param stake actual amount of ether staked for this entity.\n * @param unstakeDelaySec minimum delay to withdraw the stake.\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\n * and the rest fit into a 2nd cell.\n * 112 bit allows for 10^15 eth\n * 48 bit for full timestamp\n * 32 bit allows 150 years for unstake delay\n */\n struct DepositInfo {\n uint112 deposit;\n bool staked;\n uint112 stake;\n uint32 unstakeDelaySec;\n uint48 withdrawTime;\n }\n\n //API struct used by getStakeInfo and simulateValidation\n struct StakeInfo {\n uint256 stake;\n uint256 unstakeDelaySec;\n }\n\n /// @return info - full deposit information of given account\n function getDepositInfo(\n address account\n ) external view returns (DepositInfo memory info);\n\n /// @return the deposit (for gas payment) of the account\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) external payable;\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 _unstakeDelaySec) external payable;\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external;\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external;\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(\n address payable withdrawAddress,\n uint256 withdrawAmount\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/UserOperation.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable no-inline-assembly */\n\nimport {calldataKeccak} from \"../core/Helpers.sol\";\n\n/**\n * User Operation struct\n * @param sender the sender account of this request.\n * @param nonce unique value the sender uses to verify it is not a replay.\n * @param initCode if set, the account contract will be created by this constructor/\n * @param callData the method call to execute on this account.\n * @param callGasLimit the gas limit passed to the callData method call.\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\n * @param maxFeePerGas same as EIP-1559 gas parameter.\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\n */\nstruct UserOperation {\n address sender;\n uint256 nonce;\n bytes initCode;\n bytes callData;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n bytes paymasterAndData;\n bytes signature;\n}\n\n/**\n * Utility functions helpful when working with UserOperation structs.\n */\nlibrary UserOperationLib {\n function getSender(\n UserOperation calldata userOp\n ) internal pure returns (address) {\n address data;\n //read sender from userOp, which is first userOp member (saves 800 gas...)\n assembly {\n data := calldataload(userOp)\n }\n return address(uint160(data));\n }\n\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\n // pay above what he signed for.\n function gasPrice(\n UserOperation calldata userOp\n ) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function pack(\n UserOperation calldata userOp\n ) internal pure returns (bytes memory ret) {\n address sender = getSender(userOp);\n uint256 nonce = userOp.nonce;\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\n bytes32 hashCallData = calldataKeccak(userOp.callData);\n uint256 callGasLimit = userOp.callGasLimit;\n uint256 verificationGasLimit = userOp.verificationGasLimit;\n uint256 preVerificationGas = userOp.preVerificationGas;\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\n\n return\n abi.encode(\n sender,\n nonce,\n hashInitCode,\n hashCallData,\n callGasLimit,\n verificationGasLimit,\n preVerificationGas,\n maxFeePerGas,\n maxPriorityFeePerGas,\n hashPaymasterAndData\n );\n }\n\n function hash(\n UserOperation calldata userOp\n ) internal pure returns (bytes32) {\n return keccak256(pack(userOp));\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n}\n" + }, + "contracts/aa-4337/utils/Exec.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.5 <0.9.0;\n\n// solhint-disable no-inline-assembly\n\n/**\n * Utility functions helpful when making different kinds of contract calls in Solidity.\n */\nlibrary Exec {\n function call(\n address to,\n uint256 value,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := call(\n txGas,\n to,\n value,\n add(data, 0x20),\n mload(data),\n 0,\n 0\n )\n }\n }\n\n function staticcall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal view returns (bool success) {\n assembly {\n success := staticcall(txGas, to, add(data, 0x20), mload(data), 0, 0)\n }\n }\n\n function delegateCall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := delegatecall(\n txGas,\n to,\n add(data, 0x20),\n mload(data),\n 0,\n 0\n )\n }\n }\n\n // get returned data from last call or calldelegate\n function getReturnData(\n uint256 maxLen\n ) internal pure returns (bytes memory returnData) {\n assembly {\n let len := returndatasize()\n if gt(len, maxLen) {\n len := maxLen\n }\n let ptr := mload(0x40)\n mstore(0x40, add(ptr, add(len, 0x20)))\n mstore(ptr, len)\n returndatacopy(add(ptr, 0x20), 0, len)\n returnData := ptr\n }\n }\n\n // revert with explicit byte array (probably reverted info from call)\n function revertWithData(bytes memory returnData) internal pure {\n assembly {\n revert(add(returnData, 32), mload(returnData))\n }\n }\n\n function callAndRevert(\n address to,\n bytes memory data,\n uint256 maxLen\n ) internal {\n bool success = call(to, 0, data, gasleft());\n if (!success) {\n revertWithData(getReturnData(maxLen));\n }\n }\n}\n" + }, + "contracts/Barz.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"./libraries/LibDiamond.sol\";\nimport {IBarz} from \"./interfaces/IBarz.sol\";\n\n/**\n * @title Barz\n * @dev A diamond proxy wallet with a modular & upgradeable architecture\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract Barz is IBarz {\n /**\n * @notice Initializes Barz with the given parameters. Barz account is intended to be created from Barz Factory for stable deployment.\n * @dev This method makes a delegate call to account facet and account facet handles the initialization.\n * With modular architecture, Barz encompasses wide spectrum of architecture and logic.\n * The only requirement is account facet to comply with initialize() interface.\n * Barz doesn't include built-in functions and is a full proxy, for maximum extensibility and modularity.\n * @param _accountFacet Address of Account Facet in charge of the Barz initialization\n * @param _verificationFacet Address of Verification Facet for verifying the signature. Could be any signature scheme\n * @param _entryPoint Address of Entry Point contract\n * @param _facetRegistry Address of Facet Registry. Facet Registry is a registry holding trusted facets that could be added to user's wallet\n * @param _defaultFallBack Address of Default FallBack Handler. Middleware contract for more efficient deployment\n * @param _ownerPublicKey Bytes of Owner Public Key using for initialization\n */\n constructor(\n address _accountFacet,\n address _verificationFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallBack,\n bytes memory _ownerPublicKey\n ) payable {\n bytes memory initCall = abi.encodeWithSignature(\n \"initialize(address,address,address,address,bytes)\",\n _verificationFacet,\n _entryPoint,\n _facetRegistry,\n _defaultFallBack,\n _ownerPublicKey\n );\n (bool success, bytes memory result) = _accountFacet.delegatecall(\n initCall\n );\n if (!success || uint256(bytes32(result)) != 1) {\n revert Barz__InitializationFailure();\n }\n }\n\n /**\n * @notice Fallback function for Barz complying with Diamond Standard with customization of adding Default Fallback Handler\n * @dev Find facet for function that is called and execute the function if a facet is found and return any value.\n */\n fallback() external payable {\n LibDiamond.DiamondStorage storage ds;\n bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION;\n // get diamond storage\n assembly {\n ds.slot := position\n }\n // get facet from function selector\n address facet = address(bytes20(ds.facets[msg.sig]));\n if (facet == address(0))\n facet = ds.defaultFallbackHandler.facetAddress(msg.sig);\n require(facet != address(0), \"Barz: Function does not exist\");\n // Execute external function from facet using delegatecall and return any value.\n assembly {\n // copy function selector and any arguments\n calldatacopy(0, 0, calldatasize())\n // execute function call using the facet\n let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)\n // get any return value\n returndatacopy(0, 0, returndatasize())\n // return any return value or error back to the caller\n switch result\n case 0 {\n revert(0, returndatasize())\n }\n default {\n return(0, returndatasize())\n }\n }\n }\n\n /**\n * @notice Receive function to receive native token without data\n */\n receive() external payable {}\n}\n" + }, + "contracts/BarzFactory.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Barz} from \"./Barz.sol\";\nimport {IBarzFactory} from \"./interfaces/IBarzFactory.sol\";\n\n/**\n * @title Barz Factory\n * @dev Contract to easily deploy Barz to a pre-computed address with a single call\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract BarzFactory is IBarzFactory {\n event BarzDeployed(address);\n\n address public immutable accountFacet;\n address public immutable entryPoint;\n address public immutable facetRegistry;\n address public immutable defaultFallback;\n\n /**\n * @notice Sets the initialization data for Barz contract initialization\n * @param _accountFacet Account Facet to be used to create Barz\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\n * @param _facetRegistry Facet Registry to be used to create Barz\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\n */\n constructor(\n address _accountFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallback\n ) {\n accountFacet = _accountFacet;\n entryPoint = _entryPoint;\n facetRegistry = _facetRegistry;\n defaultFallback = _defaultFallback;\n }\n\n /**\n * @notice Creates the Barz with a single call. It creates the Barz contract with the givent verification facet\n * @param _verificationFacet Address of verification facet used for creating the barz account\n * @param _owner Public Key of the owner to initialize barz account\n * @param _salt Salt used for deploying barz with create2\n * @return barz Instance of Barz contract deployed with the given parameters\n */\n function createAccount(\n address _verificationFacet,\n bytes calldata _owner,\n uint256 _salt\n ) external override returns (Barz barz) {\n address addr = getAddress(_verificationFacet, _owner, _salt);\n uint codeSize = addr.code.length;\n if (codeSize > 0) {\n return Barz(payable(addr));\n }\n barz = new Barz{salt: bytes32(_salt)}(\n accountFacet,\n _verificationFacet,\n entryPoint,\n facetRegistry,\n defaultFallback,\n _owner\n );\n emit BarzDeployed(address(barz));\n }\n\n /**\n * @notice Calculates the address of Barz with the given parameters\n * @param _verificationFacet Address of verification facet used for creating the barz account\n * @param _owner Public Key of the owner to initialize barz account\n * @param _salt Salt used for deploying barz with create2\n * @return barzAddress Precalculated Barz address\n */\n function getAddress(\n address _verificationFacet,\n bytes calldata _owner,\n uint256 _salt\n ) public view override returns (address barzAddress) {\n bytes memory bytecode = getBytecode(\n accountFacet,\n _verificationFacet,\n entryPoint,\n facetRegistry,\n defaultFallback,\n _owner\n );\n bytes32 hash = keccak256(\n abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(bytecode)\n )\n );\n barzAddress = address(uint160(uint256(hash)));\n }\n\n /**\n * @notice Returns the bytecode of Barz with the given parameter\n * @param _accountFacet Account Facet to be used to create Barz\n * @param _verificationFacet Verification Facet to be used to create Barz\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\n * @param _facetRegistry Facet Registry to be used to create Barz\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\n * @param _ownerPublicKey Public Key of owner to be used to initialize Barz ownership\n * @return barzBytecode Bytecode of Barz\n */\n function getBytecode(\n address _accountFacet,\n address _verificationFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallback,\n bytes calldata _ownerPublicKey\n ) public pure override returns (bytes memory barzBytecode) {\n bytes memory bytecode = type(Barz).creationCode;\n barzBytecode = abi.encodePacked(\n bytecode,\n abi.encode(\n _accountFacet,\n _verificationFacet,\n _entryPoint,\n _facetRegistry,\n _defaultFallback,\n _ownerPublicKey\n )\n );\n }\n\n /**\n * @notice Returns the creation code of the Barz contract\n * @return creationCode Creation code of Barz\n */\n function getCreationCode()\n public\n pure\n override\n returns (bytes memory creationCode)\n {\n creationCode = type(Barz).creationCode;\n }\n}\n" + }, + "contracts/facets/AccountFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {UserOperation} from \"../aa-4337/interfaces/UserOperation.sol\";\nimport {IEntryPoint} from \"../aa-4337/interfaces/IEntryPoint.sol\";\nimport {BaseAccount} from \"../aa-4337/core/BaseAccount.sol\";\nimport {LibAppStorage, BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {IFacetRegistry} from \"../infrastructure/interfaces/IFacetRegistry.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {IERC1271} from \"../interfaces/ERC/IERC1271.sol\";\nimport {IAccountFacet} from \"./interfaces/IAccountFacet.sol\";\n\n/**\n * @title Account Facet\n * @dev Account module contract that provides the account features and initialization of signer\n * compatible with EIP-1271 & EIP-4337\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract AccountFacet is BarzStorage, BaseAccount, IAccountFacet {\n using ECDSA for bytes32;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceAccountInitialize();\n }\n\n /**\n * @notice Returns the address of EntryPoint contract registered to Barz account\n */\n function entryPoint() public view override returns (IEntryPoint) {\n return s.entryPoint;\n }\n\n /**\n * @notice Initializes the initial storage of the Barz contract.\n * @dev This method can only be called during the initialization or signature migration.\n * If the proxy contract was created without initialization, anyone can call initialize.\n * Barz calls initialize in constructor in an atomic transaction during deployment\n * @param _verificationFacet Facet contract handling the verificationi\n * @param _anEntryPoint Entrypoint contract defined in EIP-4337 handling the flow of UserOp\n * @param _facetRegistry Registry of Facets that hold all facet information\n * @param _defaultFallBackHandler Middleware contract for default facets\n * @param _ownerPublicKey Bytes of owner public key\n */\n function initialize(\n address _verificationFacet,\n address _anEntryPoint,\n address _facetRegistry,\n address _defaultFallBackHandler,\n bytes calldata _ownerPublicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceAccountInitialize();\n s.entryPoint = IEntryPoint(_anEntryPoint);\n s.facetRegistry = IFacetRegistry(_facetRegistry);\n LibDiamond.diamondStorage().defaultFallbackHandler = IDiamondLoupe(\n _defaultFallBackHandler\n );\n\n _cutDiamondAccountFacet(_verificationFacet);\n\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n _ownerPublicKey\n );\n // Every Verification Facet should comply with initializeSigner(bytes)\n // to be compatible with the Barz contract(for initialization)\n (bool success, bytes memory result) = _verificationFacet.delegatecall(\n initCall\n );\n if (!success || uint256(bytes32(result)) != 1) {\n revert AccountFacet__InitializationFailure();\n }\n\n initSuccess = 1;\n emit AccountInitialized(s.entryPoint, _ownerPublicKey);\n }\n\n function _cutDiamondAccountFacet(address _verificationFacet) internal {\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](1);\n\n bytes4 ownerVerificationFuncSelector = IVerificationFacet(\n _verificationFacet\n ).validateOwnerSignatureSelector();\n\n bytes4[] memory verificationFunctionSelectors = new bytes4[](3);\n verificationFunctionSelectors[0] = IERC1271.isValidSignature.selector;\n verificationFunctionSelectors[1] = ownerVerificationFuncSelector;\n verificationFunctionSelectors[2] = IVerificationFacet.owner.selector;\n cut[0] = IDiamondCut.FacetCut({\n facetAddress: _verificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: verificationFunctionSelectors\n });\n\n LibDiamond.diamondCut(cut, address(0), \"\");\n }\n\n /**\n * @notice Calls the destination with inputted calldata and value from EntryPoint\n * @dev This method executes the calldata coming from the EntryPoint.\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\n * @param _dest Address of destination where the call will be forwarded to\n * @param _value Amount of native coin the owner is willing to send(e.g. ETH, BNB)\n * @param _func Bytes of calldata to execute in the destination address\n */\n function execute(\n address _dest,\n uint256 _value,\n bytes calldata _func\n ) external override onlyWhenUnlocked {\n _requireFromEntryPoint();\n _call(_dest, _value, _func);\n }\n\n /**\n * @notice Batch calls the destination with inputted calldata and value from EntryPoint\n * @dev This method batch executes the calldata coming from the EntryPoint.\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\n * @param _dest Array of addresses of destination where the call will be forwarded to\n * @param _value Array of amount of native coin the owner is willing to send(e.g. ETH, BNB)\n * @param _func Array of bytes of calldata to execute in the destination address\n */\n function executeBatch(\n address[] calldata _dest,\n uint256[] calldata _value,\n bytes[] calldata _func\n ) external override onlyWhenUnlocked {\n _requireFromEntryPoint();\n uint256 destLength = _dest.length;\n require(\n destLength == _func.length && destLength == _value.length,\n \"wrong array lengths\"\n );\n for (uint256 i; i < destLength; ) {\n _call(_dest[i], _value[i], _func[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Validates the signature field of UserOperation\n * @dev This method validates if the signature of UserOp is indeed valid by delegating the call to Verification Facet\n * Barz makes a call to the pre-registered Verification Facet address in App Storage\n * @param _userOp UserOperation from owner to be validated\n * @param _userOpHash Hash of UserOperation given from the EntryPoint contract\n */\n function _validateSignature(\n UserOperation calldata _userOp,\n bytes32 _userOpHash\n ) internal override returns (uint256 validationData) {\n // Get Facet with Function Selector\n address facet = LibLoupe.facetAddress(s.validateOwnerSignatureSelector);\n if (facet == address(0))\n revert AccountFacet__NonExistentVerificationFacet();\n\n // Make function call to VerificationFacet\n bytes memory validateCall = abi.encodeWithSelector(\n s.validateOwnerSignatureSelector,\n _userOp,\n _userOpHash\n );\n (bool success, bytes memory result) = facet.delegatecall(validateCall);\n if (!success) revert AccountFacet__CallNotSuccessful();\n validationData = uint256(bytes32(result));\n if (validationData == 0) emit VerificationSuccess(_userOpHash);\n else emit VerificationFailure(_userOpHash);\n }\n\n /**\n * @notice Calls the target with the inputted value and calldata\n * @dev This method is the actual function in Barz that makes a call with an arbitrary owner-given data\n * @param _target Address of the destination contract which the call is getting forwarded to\n * @param _value Amount of Native coin the owner is wanting to make in this call\n * @param _data Calldata the owner is forwarding together in the call e.g. Swap/Token Transfer\n */\n function _call(\n address _target,\n uint256 _value,\n bytes memory _data\n ) internal {\n if (_checkRestrictions(_target, _value, _data) == 1)\n revert AccountFacet__RestrictionsFailure();\n\n (bool success, bytes memory result) = _target.call{value: _value}(\n _data\n );\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n }\n\n /**\n * @notice Checks restrictions if the restrictions facet exists\n * @dev This method checks if the restrictions facet exists and makes a verification call to an array of restrictions facet\n * @param _target Address the call is getting forwarded to\n * @param _value Amount of native coin the call is sending together with the call\n * @param _data Calldata to trigger execution in target address\n */\n function _checkRestrictions(\n address _target,\n uint256 _value,\n bytes memory _data\n ) internal returns (uint256 result) {\n address facet = LibDiamond.restrictionsFacet();\n // NOTE: No restrictions facet, so restriction validation passes\n if (facet == address(0)) return 0;\n bytes memory call = abi.encodeWithSignature(\n \"verifyRestrictions(address,address,uint256,bytes)\",\n address(this),\n _target,\n _value,\n _data\n );\n (bool success, bytes memory response) = facet.delegatecall(call);\n if (!success) revert AccountFacet__RestrictionsFailure();\n result = uint256(bytes32(response));\n }\n}\n" + }, + "contracts/facets/AccountRecoveryFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibFacetStorage, RecoveryStorage, RecoveryConfig, RecoveryApprovalConfig, ApprovalConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {IAccountRecoveryFacet} from \"./interfaces/IAccountRecoveryFacet.sol\";\n\n/**\n * @title Account Recovery Facet\n * @dev Contract that enables recovery of accounts when owner key is unavailable\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract AccountRecoveryFacet is IAccountRecoveryFacet, Modifiers {\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Approve recovery of account as guardian\n * @dev This method can only be called by guardian and guardian inputs the public key of the new owner\n * When the threshold(majority of guardians) passes, it automatically executes account recovery\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function approveAccountRecovery(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + _getApprovalValidationPeriod()\n );\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit RecoveryApproved(\n _recoveryPublicKey,\n msg.sender,\n approvalValidUntil\n );\n if (\n getRecoveryApprovalCountWithTimeValidity(recoveryPublicKeyHash) >=\n LibGuardian.majorityOfGuardians()\n ) _executeRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Revoke recovery of account as guardian\n * @dev This method can only be called by guardian and guardian inputs the public key of the new owner\n When the threshold(majority of guardians) passes, it automatically revokes account recovery when recovery is pending\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function revokeAccountRecoveryApproval(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n if (\n !rs\n .isNewOwnerApproved[recoveryPublicKeyHash][msg.sender].isApproved ||\n !(block.timestamp <\n rs\n .isNewOwnerApproved[recoveryPublicKeyHash][msg.sender]\n .validUntil)\n ) revert AccountRecoveryFacet__NonExistentApproval();\n\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(false, 0);\n emit RecoveryApprovalRevoked(_recoveryPublicKey, msg.sender);\n }\n\n /**\n * @notice Executes recovery with signatures or on-chain pre-approvals\n * @dev This method validates the signatures of guardians or checks the on-chain pre-approved calls to check if the threshold passes\n * When the threshold passes, account recovery is executed and revert otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _guardians Array of guardians address that are approving the recovery of Account\n * @param _signatures Array of signature bytes that signed the approval hash\n */\n function executeRecovery(\n bytes calldata _recoveryPublicKey,\n address[] calldata _guardians,\n bytes[] calldata _signatures\n ) external override {\n if (_isRecoveryPending())\n revert AccountRecoveryFacet__RecoveryAlreadyOngoing();\n uint256 guardiansLength = _guardians.length;\n if (guardiansLength != _signatures.length)\n revert AccountRecoveryFacet__InvalidArrayLength();\n validateNewOwner(_recoveryPublicKey);\n\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n\n _checkApprover(_guardians);\n _checkDuplicateOnChainApprover(recoveryPublicKeyHash, _guardians);\n\n if (\n guardiansLength +\n getRecoveryApprovalCountWithTimeValidity(\n recoveryPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians()\n ) revert AccountRecoveryFacet__InsufficientGuardians();\n for (uint256 i; i < guardiansLength; ) {\n if (!LibGuardian.isGuardian(_guardians[i]))\n revert AccountRecoveryFacet__InvalidGuardian();\n if (\n !SignatureChecker.isValidSignatureNow(\n _guardians[i],\n recoveryPublicKeyHash,\n _signatures[i]\n )\n ) revert AccountRecoveryFacet__InvalidGuardianSignature();\n unchecked {\n ++i;\n }\n }\n _executeRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Executes recovery of the account. Note that execution and finalization is a different process\n * @dev Executes the recovery and adds recovery data to recovery configuration. Locks the account\n * @param _recoveryPublicKey Public Key of the account for recovery\n */\n function _executeRecovery(bytes memory _recoveryPublicKey) internal {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n ++rs.nonce;\n uint64 executeAfter = uint64(block.timestamp + _getRecoveryPeriod());\n rs.recoveryConfigs[INNER_STRUCT] = RecoveryConfig(\n _recoveryPublicKey,\n executeAfter // NOTE: Remove guardian Count\n );\n LibAppStorage.setLock(\n block.timestamp + _getLockPeriod(),\n AccountRecoveryFacet.executeRecovery.selector\n );\n emit RecoveryExecuted(_recoveryPublicKey, executeAfter);\n }\n\n /**\n * @notice Finalize recovery after recovery pending period. Recovery pending period can be set by user beforehand in SecurityManager\n * @dev This method finalizes recovery and fully changes the ownership of the account to the newly inputted recovery public key\n */\n function finalizeRecovery() external override {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n if (\n uint64(block.timestamp) <=\n rs.recoveryConfigs[INNER_STRUCT].executeAfter\n ) revert AccountRecoveryFacet__RecoveryPeriodNotOver();\n bytes memory recoveryOwner = rs\n .recoveryConfigs[INNER_STRUCT]\n .recoveryPublicKey;\n\n delete rs.recoveryConfigs[INNER_STRUCT];\n\n LibAppStorage.setLock(0, bytes4(0));\n\n LibAppStorage.initiateSignerMigration();\n address verificationFacet = address(\n bytes20(\n LibDiamond.diamondStorage().facets[\n s.validateOwnerSignatureSelector\n ]\n )\n );\n bytes memory uninitCall = abi.encodeWithSignature(\n \"uninitializeSigner()\"\n );\n (bool success, bytes memory result) = verificationFacet.delegatecall(\n uninitCall\n );\n if (!success) revert AccountRecoveryFacet__CallNotSuccesful();\n uint256 validationData = uint256(bytes32(result));\n if (validationData != 1)\n revert AccountRecoveryFacet__SignerUninitializationFailure();\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n recoveryOwner\n );\n (success, result) = verificationFacet.delegatecall(initCall);\n if (!success) revert AccountRecoveryFacet__CallNotSuccesful();\n validationData = uint256(bytes32(result));\n if (validationData != 1)\n revert AccountRecoveryFacet__SignerInitializationFailure();\n LibAppStorage.finalizeSignerMigration();\n emit RecoveryFinalized(recoveryOwner);\n }\n\n /**\n * @notice Approves the cancellation of recovery\n * @dev This method approves the cancellation of recovery when recovery is still pending - waiting for finalization\n * @param _recoveryPublicKey Bytes of public key which is pending for recovery\n */\n function approveCancelRecovery(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"CancelRecovery\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + _getApprovalValidationPeriod()\n );\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit RecoveryCancellationApproved(_recoveryPublicKey, msg.sender);\n if (\n getRecoveryApprovalCountWithTimeValidity(recoveryPublicKeyHash) >=\n LibGuardian.majorityOfGuardians()\n ) {\n _cancelRecovery(_recoveryPublicKey);\n }\n }\n\n /**\n * @notice Hardstops an ongoing recovery\n * @dev This method provides a safety mechanism to protect owners of malicious guardians.\n * Owners can hardstop recovery when an malicious guardians starts the recovery process.\n * @param _signature Signature of the owner that signs the hash to hardstop recovery\n */\n function hardstopRecovery(bytes calldata _signature) external override {\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n \"0\",\n \"HardstopRecovery\"\n );\n if (\n !SignatureChecker.isValidSignatureNow(\n address(this),\n recoveryPublicKeyHash,\n _signature\n )\n ) revert AccountRecoveryFacet__InvalidOwnerSignature();\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n ++rs.nonce;\n delete rs.recoveryConfigs[INNER_STRUCT];\n LibAppStorage.setLock(0, bytes4(0));\n emit RecoveryHardstopped();\n }\n\n /**\n * @notice Cancels recovery with signatures or on-chain pre-approvals\n * @dev This method validates the signatures of guardians or checks the on-chain pre-approved calls to check if the threshold passes\n * When the threshold passes, account recovery is canceled and revert otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _guardians Array of guardians address that are approving the recovery of Account\n * @param _signatures Array of signature bytes that signed the cancellation approval hash\n */\n function cancelRecovery(\n bytes calldata _recoveryPublicKey,\n address[] calldata _guardians,\n bytes[] calldata _signatures\n ) external override {\n uint256 guardiansLength = _guardians.length;\n if (guardiansLength != _signatures.length)\n revert AccountRecoveryFacet__InvalidArrayLength();\n validateNewOwner(_recoveryPublicKey);\n\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"CancelRecovery\"\n );\n\n _checkApprover(_guardians);\n _checkDuplicateOnChainApprover(recoveryPublicKeyHash, _guardians);\n\n if (\n guardiansLength +\n getRecoveryApprovalCountWithTimeValidity(\n recoveryPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians()\n ) revert AccountRecoveryFacet__InsufficientGuardians();\n for (uint256 i; i < guardiansLength; ) {\n if (!LibGuardian.isGuardian(_guardians[i]))\n revert AccountRecoveryFacet__CallerNotGuardian();\n if (\n !SignatureChecker.isValidSignatureNow(\n _guardians[i],\n recoveryPublicKeyHash,\n _signatures[i]\n )\n ) revert AccountRecoveryFacet__InvalidGuardianSignature();\n unchecked {\n ++i;\n }\n }\n _cancelRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Cancel recovery when the recovery is pending. Unlock the account as well\n * @dev This method checks if the recovery is pending and reverts if not pending.\n * It increases the recovery nonce and deletes the recovery information and gets a small portion of gas in return\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function _cancelRecovery(bytes memory _recoveryPublicKey) internal {\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n LibAppStorage.setLock(0, bytes4(0));\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n ++rs.nonce;\n delete rs.recoveryConfigs[INNER_STRUCT];\n emit RecoveryCanceled(_recoveryPublicKey);\n }\n\n /**\n * @notice Validates the format of public key to be used for recovery\n * @dev This method checks if the public key format is correct and reverts otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function validateNewOwner(bytes memory _recoveryPublicKey) public view {\n if (\n !IVerificationFacet(\n LibLoupe.facetAddress(s.validateOwnerSignatureSelector)\n ).isValidKeyType(_recoveryPublicKey)\n ) revert AccountRecoveryFacet__InvalidRecoveryPublicKey();\n }\n\n /**\n * @notice Checks if recovery is currently pending\n * @return isPending Boolean indicating if recovery is pending\n */\n function _isRecoveryPending() internal view returns (bool isPending) {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n isPending = (rs.recoveryConfigs[INNER_STRUCT].executeAfter > 0);\n }\n\n /**\n * @notice Calculate the recovery hash dependent on chain, wallet address, nonce with EIP-191 prefix for safety\n * @dev Returns the keccak256 hash of EIP-191 msg hash packed with public key, salt, nonce, wallet address, etc\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _saltString Salt string to uniquely identify each recovery hash and for security\n * @return recoveryKeyHash Bytes32 string of the recovery hash\n */\n function getApprovalRecoveryKeyHash(\n bytes memory _recoveryPublicKey,\n string memory _saltString\n ) public view override returns (bytes32 recoveryKeyHash) {\n recoveryKeyHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n _recoveryPublicKey,\n _saltString,\n address(this),\n block.chainid,\n LibFacetStorage.recoveryStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Check the onchain approval of guardians and returns the number of guardians that approved\n * @dev Loop through the guardian addresses and returns the number of guardians that approved this recovery hash\n * @param _recoveryPublicKeyHash Bytes hash of newly recovered public key and recovery value of the account\n * @return approvalCount Number of guardians that approved\n */\n function getRecoveryApprovalCountWithTimeValidity(\n bytes32 _recoveryPublicKeyHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n for (uint256 i; i < guardianLength; ) {\n if (isRecoveryApproved(_recoveryPublicKeyHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Checks if the recovery is approved by the given approver\n * @param _recoveryPublicKeyHash Hash of the public key and configuration for recovery\n * @param _approver Address of approver\n * @return isApproved Bool value if recovery hash is approved\n */\n function isRecoveryApproved(\n bytes32 _recoveryPublicKeyHash,\n address _approver\n ) public view override returns (bool isApproved) {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n if (\n rs\n .isNewOwnerApproved[_recoveryPublicKeyHash][_approver].isApproved &&\n block.timestamp <\n rs.isNewOwnerApproved[_recoveryPublicKeyHash][_approver].validUntil\n ) {\n isApproved = true;\n }\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _recoveryPublicKeyHash Hash of recovery information\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _recoveryPublicKeyHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isRecoveryApproved(_recoveryPublicKeyHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert AccountRecoveryFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the lock period of this wallet address from security manager\n * @return lockPeriod value of lock period\n */\n function _getLockPeriod() internal view returns (uint256 lockPeriod) {\n lockPeriod = securityManager.lockPeriodOf(address(this));\n if (lockPeriod == 0) revert AccountRecoveryFacet__InvalidLockPeriod();\n }\n\n /**\n * @notice Returns the lock period of this wallet address from security manager\n * @return recoveryPeriod value of recovery period\n */\n function _getRecoveryPeriod()\n internal\n view\n returns (uint256 recoveryPeriod)\n {\n recoveryPeriod = securityManager.recoveryPeriodOf(address(this));\n if (recoveryPeriod == 0)\n revert AccountRecoveryFacet__InvalidRecoveryPeriod();\n }\n\n /**\n * @notice Returns the approval validation period of this wallet address from security manager\n * @return approvalValidationPeriod value of approval validation period\n */\n function _getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod == 0)\n revert AccountRecoveryFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the recovery nonce of this wallet address from security manager\n * @return nonce value of recovery nonce\n */\n function getRecoveryNonce() public view override returns (uint128 nonce) {\n nonce = LibFacetStorage.recoveryStorage().nonce;\n }\n\n /**\n * @notice Returns the recovery information of the pending recovery\n * @return recoveryConfig value struct of pending recovery\n */\n function getPendingRecovery()\n public\n view\n override\n returns (RecoveryConfig memory recoveryConfig)\n {\n recoveryConfig = LibFacetStorage.recoveryStorage().recoveryConfigs[\n INNER_STRUCT\n ];\n }\n}\n" + }, + "contracts/facets/base/DiamondCutFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibGuardian} from \"../../libraries/LibGuardian.sol\";\nimport {ISecurityManager} from \"../../infrastructure/interfaces/ISecurityManager.sol\";\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibFacetStorage, DiamondCutApprovalConfig, ApprovalConfig} from \"../../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"../Modifiers.sol\";\nimport {IDiamondCut} from \"./interfaces/IDiamondCut.sol\";\n\n/**\n * @title DiamondCut Facet\n * @dev Responsible for adding/removing/replace facets in Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DiamondCutFacet is Modifiers, IDiamondCut {\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Updates the flag for the interfaceId\n * @param _interfaceId InterfaceID to update the mapping\n * @param _flag Bool value to update the mapping of the given interface ID\n */\n function updateSupportsInterface(\n bytes4 _interfaceId,\n bool _flag\n ) external override onlyWhenUnlocked {\n LibDiamond.enforceIsSelf();\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId] = _flag;\n emit SupportsInterfaceUpdated(_interfaceId, _flag);\n }\n\n /**\n * @notice Add/replace/remove any number of functions and optionally execute\n * a function with delegatecall when guardians don't exist\n * @param _diamondCut Contains the facet addresses and function selectors\n * @param _init The address of the contract or facet to execute _calldata\n * @param _calldata A function call, including function selector and arguments\n * _calldata is executed with delegatecall on _init\n */\n function diamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) external override onlyWhenUnlocked {\n LibDiamond.enforceIsSelf();\n\n _checkFacetCutValidity(_diamondCut);\n // require approval from guardian if guardian exists\n if (0 != LibGuardian.guardianCount())\n revert DiamondCutFacet__InvalidRouteWithGuardian();\n\n ++LibFacetStorage.diamondCutStorage().nonce;\n LibDiamond.diamondCut(_diamondCut, _init, _calldata);\n }\n\n /**\n * @notice Add/replace/remove any number of functions and optionally execute\n * a function with delegatecall when guardians exist\n * @param _diamondCut Contains the facet addresses and function selectors\n * @param _init The address of the contract or facet to execute _calldata\n * @param _calldata A function call, including function selector and arguments\n * _calldata is executed with delegatecall on _init\n * @param _approvers Guardian or owner address that approves the diamond cut\n * @param _signatures Signature of Guardians or owner that approves the diamond cut\n */\n function diamondCutWithGuardian(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n ) external override onlyWhenUnlocked {\n uint256 approverLength = _approvers.length;\n if (approverLength != _signatures.length)\n revert DiamondCutFacet__InvalidArrayLength();\n _checkFacetCutValidity(_diamondCut);\n if (0 == LibGuardian.guardianCount())\n revert DiamondCutFacet__InvalidRouteWithGuardian();\n\n bytes32 cutHash = getDiamondCutHash(_diamondCut, _init, _calldata);\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(cutHash, _approvers);\n\n bool onChainOwnerApproval = getOwnerCutApprovalWithTimeValidity(\n cutHash\n );\n\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n if (\n approverLength +\n getDiamondCutApprovalCountWithTimeValidity(cutHash) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert DiamondCutFacet__InsufficientApprovers();\n\n bool ownerApproved;\n for (uint256 i; i < approverLength; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n _approvers[i] != address(this)\n ) revert DiamondCutFacet__InvalidApprover();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert DiamondCutFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n cutHash,\n _signatures[i]\n )\n ) revert DiamondCutFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n if (!ownerApproved && !onChainOwnerApproval)\n revert DiamondCutFacet__LackOfOwnerApproval();\n\n ++LibFacetStorage.diamondCutStorage().nonce;\n LibDiamond.diamondCut(_diamondCut, _init, _calldata);\n }\n\n /**\n * @notice Approves diamond cut. This can only be called directly from guardian or owner\n * @param _diamondCut Contains the facet addresses and function selectors\n * @param _init The address of the contract or facet to execute _calldata\n * @param _calldata A function call, including function selector and arguments\n * _calldata is executed with delegatecall on _init\n */\n function approveDiamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\n if (LibGuardian.guardianCount() == 0)\n revert DiamondCutFacet__InvalidRouteWithoutGuardian();\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n _checkFacetCutValidity(_diamondCut);\n\n bytes32 cutHash = getDiamondCutHash(_diamondCut, _init, _calldata);\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(\n true,\n approvalValidUntil\n );\n emit DiamondCutApproved(_diamondCut, _init, _calldata);\n if (\n (getDiamondCutApprovalCountWithTimeValidity(cutHash) >=\n LibGuardian.majorityOfGuardians()) &&\n getOwnerCutApprovalWithTimeValidity(cutHash)\n ) {\n ++LibFacetStorage.diamondCutStorage().nonce;\n LibDiamond.diamondCut(_diamondCut, _init, _calldata);\n }\n }\n\n /**\n * @notice Revokes the approval of diamond cut. This can only be called directly from guardian or owner\n * @param _diamondCut Contains the facet addresses and function selectors\n * @param _init The address of the contract or facet to execute _calldata\n * @param _calldata A function call, including function selector and arguments\n * _calldata is executed with delegatecall on _init\n */\n function revokeDiamondCutApproval(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n bytes32 cutHash = getDiamondCutHash(_diamondCut, _init, _calldata);\n if (!ds.isDiamondCutApproved[cutHash][msg.sender].isApproved)\n revert DiamondCutFacet__CannotRevokeUnapproved();\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(false, 0);\n emit DiamondCutApprovalRevoked(_diamondCut, _init, _calldata);\n }\n\n /**\n * @notice Gets the number of approvals of diamond cut from guardians\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n */\n function getDiamondCutApprovalCountWithTimeValidity(\n bytes32 _diamondCutHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardiansLength = guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n if (isCutApproved(_diamondCutHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n return approvalCount;\n }\n\n /**\n * @notice Returns if the owner has approved the diamond cut\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @return isApprovedByOwner Bool value showing if the owner approved the cut\n */\n function getOwnerCutApprovalWithTimeValidity(\n bytes32 _diamondCutHash\n ) public view override returns (bool isApprovedByOwner) {\n isApprovedByOwner = isCutApproved(_diamondCutHash, address(this));\n }\n\n /**\n * @notice Returns if the given approver has approved the diamond cut\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @param _approver Address of approver\n * @return isApproved Bool value showing if the approver approved the cut\n */\n function isCutApproved(\n bytes32 _diamondCutHash,\n address _approver\n ) public view override returns (bool isApproved) {\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n isApproved = (ds\n .isDiamondCutApproved[_diamondCutHash][_approver].isApproved &&\n block.timestamp <\n ds.isDiamondCutApproved[_diamondCutHash][_approver].validUntil);\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _diamondCutHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isCutApproved(_diamondCutHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert DiamondCutFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the diamond cut hash. This function ensures that this hash is safe from replay attack by including\n * salt, address, chainId, and nonce, etc.\n * @param _diamondCut Contains the facet addresses and function selectors\n * @param _init The address of the contract or facet to execute _calldata\n * @param _calldata A function call, including function selector and arguments\n * _calldata is executed with delegatecall on _init\n * @return cutHash Diamond Cut Hash\n */\n function getDiamondCutHash(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) public view override returns (bytes32 cutHash) {\n cutHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n keccak256(abi.encode(_diamondCut)),\n _init,\n _calldata,\n address(this),\n block.chainid,\n LibFacetStorage.diamondCutStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Returns the approval validation Period\n * @dev This method fetches the validation period from the security manager\n * @return approvalValidationPeriod Approval validation period of Barz contract fetched from security manager\n */\n function getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod <= 0)\n revert DiamondCutFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the diamond cut nonce of this wallet\n * @dev This method fetches the nonce from diamond cut storage\n * @return cutNonce Nonce of diamond cut to protect from reply attacks\n */\n function getDiamondCutNonce()\n public\n view\n override\n returns (uint128 cutNonce)\n {\n cutNonce = LibFacetStorage.diamondCutStorage().nonce;\n }\n}\n" + }, + "contracts/facets/base/DiamondLoupeFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {IERC165} from \"../../interfaces/ERC/IERC165.sol\";\nimport {IERC1271} from \"../../interfaces/ERC/IERC1271.sol\";\nimport {IERC677Receiver} from \"../../interfaces/ERC/IERC677Receiver.sol\";\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC1155Receiver} from \"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\";\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../../libraries/LibLoupe.sol\";\nimport {LibUtils} from \"../../libraries/LibUtils.sol\";\nimport {IDiamondCut} from \"../../facets/base/interfaces/IDiamondCut.sol\";\nimport {IStorageLoupe} from \"./interfaces/IStorageLoupe.sol\";\nimport {IDiamondLoupe} from \"./interfaces/IDiamondLoupe.sol\";\n\n/**\n * @title DiamondLoupe Facet\n * @dev DiamondLoupe contract compatible with EIP-2535\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DiamondLoupeFacet is IDiamondLoupe, IStorageLoupe, IERC165 {\n // Diamond Loupe Functions\n ////////////////////////////////////////////////////////////////////\n /// These functions are expected to be called frequently by tools off-chain.\n\n /**\n * @notice Gets all facets and their selectors.\n * @dev Barz uses a special architecture called default fallback handler. Default Fallback handler is used as a middleware\n * that holds the mapping of facet function selector and facet address that Barz uses. This helps Barz to reduce\n * significant amount of gas during the initialization process.\n * Hence, this method aggregates both the facet information from DefaulFallbackHandler and in diamond storage and shows the data to users.\n * @return facets_ Facet\n */\n function facets() public view override returns (Facet[] memory facets_) {\n Facet[] memory defaultFacet = LibDiamond\n .diamondStorage()\n .defaultFallbackHandler\n .facets();\n Facet[] memory _facets = LibLoupe.facets();\n uint256 numFacets = _facets.length;\n bytes4[] memory keys;\n address[] memory values;\n for (uint256 i; i < numFacets; ) {\n uint256 selectorsLength = _facets[i].functionSelectors.length;\n for (uint256 j; j < selectorsLength; ) {\n (keys, values) = LibUtils.setValue(\n keys,\n values,\n _facets[i].functionSelectors[j],\n _facets[i].facetAddress\n );\n unchecked {\n ++j;\n }\n }\n unchecked {\n ++i;\n }\n }\n {\n bool iIncrement;\n for (uint256 i; i < defaultFacet.length; ) {\n bool jIncrement;\n for (\n uint256 j;\n j < defaultFacet[i].functionSelectors.length;\n\n ) {\n if (\n LibUtils.getValue(\n keys,\n values,\n defaultFacet[i].functionSelectors[j]\n ) != address(0)\n ) {\n if (defaultFacet[i].functionSelectors.length == 1) {\n defaultFacet = LibUtils.removeFacetElement(\n defaultFacet,\n i\n );\n iIncrement = true;\n break;\n }\n defaultFacet[i].functionSelectors = LibUtils\n .removeElement(\n defaultFacet[i].functionSelectors,\n j\n );\n jIncrement = true;\n }\n if (!jIncrement) {\n unchecked {\n ++j;\n }\n } else {\n jIncrement = false;\n }\n }\n if (!iIncrement) {\n unchecked {\n ++i;\n }\n } else {\n iIncrement = false;\n }\n }\n }\n {\n uint256 facetLength = numFacets + defaultFacet.length;\n facets_ = new Facet[](facetLength);\n uint256 defaultFacetIndex;\n for (uint256 i; i < facetLength; ) {\n if (i < numFacets) {\n facets_[i] = _facets[i];\n bool jIncrementor;\n for (uint256 j; j < defaultFacet.length; ) {\n if (\n facets_[i].facetAddress ==\n defaultFacet[j].facetAddress\n ) {\n facets_[i].functionSelectors = LibUtils.mergeArrays(\n _facets[i].functionSelectors,\n defaultFacet[j].functionSelectors\n );\n defaultFacet = LibUtils.removeFacetElement(\n defaultFacet,\n j\n );\n jIncrementor = true;\n {\n facets_ = LibUtils.removeFacetElement(\n facets_,\n facets_.length - 1\n );\n }\n --facetLength;\n }\n if (!jIncrementor) {\n unchecked {\n ++j;\n }\n } else {\n jIncrementor = false;\n }\n }\n } else {\n facets_[i] = defaultFacet[defaultFacetIndex];\n ++defaultFacetIndex;\n }\n unchecked {\n ++i;\n }\n }\n }\n }\n\n /**\n * @notice Gets all the function selectors provided by a facet.\n * @param _facet The facet address.\n * @return facetFunctionSelectors_\n */\n function facetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n Facet[] memory facet = facets();\n uint256 facetLength = facet.length;\n for (uint256 i; i < facetLength; ) {\n if (facet[i].facetAddress == _facet)\n return facet[i].functionSelectors;\n unchecked {\n ++i;\n }\n }\n return facetFunctionSelectors_;\n }\n\n /**\n * @notice Get all the facet addresses used by Barz.\n * @return facetAddresses_\n */\n function facetAddresses()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n Facet[] memory facet = facets();\n uint256 facetLength = facet.length;\n facetAddresses_ = new address[](facetLength);\n for (uint256 i; i < facetLength; ) {\n facetAddresses_[i] = facet[i].facetAddress;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Gets the facet that supports the given selector.\n * @dev If facet is not found return address(0).\n * @param _functionSelector The function selector.\n * @return facetAddress_ The facet address.\n */\n function facetAddress(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n\n facetAddress_ = address(bytes20(ds.facets[_functionSelector]));\n if (facetAddress_ == address(0)) {\n facetAddress_ = IDiamondLoupe(ds.defaultFallbackHandler)\n .facetAddress(_functionSelector);\n }\n }\n\n /**\n * @notice SupportInterface to be compatible with EIP 165\n * @param _interfaceId Interface ID for detecting the interface\n * @return isSupported Bool value showing if the standard is supported in the contract\n */\n function supportsInterface(\n bytes4 _interfaceId\n ) external view override returns (bool isSupported) {\n isSupported =\n _interfaceId == type(IERC165).interfaceId ||\n _interfaceId == IDiamondCut.diamondCut.selector ||\n _interfaceId == type(IDiamondLoupe).interfaceId ||\n _interfaceId == type(IERC1155Receiver).interfaceId ||\n _interfaceId == type(IERC721Receiver).interfaceId ||\n _interfaceId == type(IERC777Recipient).interfaceId ||\n _interfaceId == IERC1271.isValidSignature.selector ||\n _interfaceId == type(IERC677Receiver).interfaceId ||\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId];\n }\n\n /**\n * @notice Returns the facet from the diamond storage. This excludes the facets from the default fallback handler\n * @return facets_ Facet information attached directly to diamond storage\n */\n function facetsFromStorage()\n external\n view\n override\n returns (Facet[] memory facets_)\n {\n facets_ = LibLoupe.facets();\n }\n\n /**\n * @notice Returns the facet address attached to the given function selector. This excludes the facets from the default fallback handler\n * @param _functionSelector Function selector to fetch the facet address from diamond storage\n * @return facetAddress_ Facet address mapped with the function selector\n */\n function facetAddressFromStorage(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n facetAddress_ = LibLoupe.facetAddress(_functionSelector);\n }\n\n /**\n * @notice Returns all facet addresses attached directly to diamond storage. This excludes the facets from the default fallback handler\n * @return facetAddresses_ All facet addresses attached directly to diamond storage\n */\n function facetAddressesFromStorage()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n facetAddresses_ = LibLoupe.facetAddresses();\n }\n\n /**\n * @notice Returns function selectors of given facet address attached directly to diamond storage. This excludes the facets from the default fallback handler\n * @param _facet Facet address to fetch the facet function selectors from diamond storage\n * @return facetFunctionSelectors_ Facet function selectors of the given facet address\n */\n function facetFunctionSelectorsFromStorage(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n facetFunctionSelectors_ = LibLoupe.facetFunctionSelectors(_facet);\n }\n}\n" + }, + "contracts/facets/base/interfaces/IDiamondCut.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title DiamondCut Facet Interface\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IDiamondCut {\n error DiamondCutFacet__InvalidRouteWithGuardian();\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\n error DiamondCutFacet__InvalidArrayLength();\n error DiamondCutFacet__InsufficientApprovers();\n error DiamondCutFacet__InvalidApprover();\n error DiamondCutFacet__InvalidApproverSignature();\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\n error DiamondCutFacet__CannotRevokeUnapproved();\n error DiamondCutFacet__GuardianApprovalNotRequired();\n error DiamondCutFacet__LackOfOwnerApproval();\n error DiamondCutFacet__OwnerAlreadyApproved();\n error DiamondCutFacet__DuplicateApproval();\n\n event DiamondCutApproved(\n FacetCut[] diamondCut,\n address init,\n bytes initCalldata\n );\n event DiamondCutApprovalRevoked(\n FacetCut[] diamondCut,\n address init,\n bytes initCalldata\n );\n\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\n\n enum FacetCutAction {\n Add,\n Replace,\n Remove\n }\n // Add=0, Replace=1, Remove=2\n\n struct FacetCut {\n address facetAddress;\n FacetCutAction action;\n bytes4[] functionSelectors;\n }\n\n /// @notice Add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param diamondCut Contains the facet addresses and function selectors\n /// @param init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function diamondCut(\n FacetCut[] calldata diamondCut,\n address init,\n bytes calldata _calldata\n ) external;\n\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\n\n function diamondCutWithGuardian(\n FacetCut[] calldata diamondCut,\n address init,\n bytes calldata _calldata,\n address[] calldata approvers,\n bytes[] calldata signatures\n ) external;\n\n function approveDiamondCut(\n FacetCut[] calldata diamondCut,\n address init,\n bytes calldata _calldata\n ) external;\n\n function revokeDiamondCutApproval(\n FacetCut[] calldata diamondCut,\n address init,\n bytes calldata _calldata\n ) external;\n\n function getDiamondCutApprovalCountWithTimeValidity(\n bytes32 diamondCutHash\n ) external view returns (uint256);\n\n function getOwnerCutApprovalWithTimeValidity(\n bytes32 diamondCutHash\n ) external view returns (bool);\n\n function isCutApproved(\n bytes32 diamondCutHash,\n address approver\n ) external view returns (bool);\n\n function getDiamondCutHash(\n FacetCut[] calldata diamondCut,\n address init,\n bytes calldata _calldata\n ) external view returns (bytes32);\n\n function getDiamondCutNonce() external view returns (uint128);\n}\n" + }, + "contracts/facets/base/interfaces/IDiamondLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n// A loupe is a small magnifying glass used to look at diamonds.\n// These functions look at diamonds\ninterface IDiamondLoupe {\n /// These functions are expected to be called frequently\n /// by tools.\n\n struct Facet {\n address facetAddress;\n bytes4[] functionSelectors;\n }\n\n /// @notice Gets all facet addresses and their four byte function selectors.\n /// @return facets_ Facet\n function facets() external view returns (Facet[] memory facets_);\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n /// @return facetFunctionSelectors_\n function facetFunctionSelectors(\n address _facet\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses()\n external\n view\n returns (address[] memory facetAddresses_);\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(\n bytes4 _functionSelector\n ) external view returns (address facetAddress_);\n}\n" + }, + "contracts/facets/base/interfaces/IStorageLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"./IDiamondLoupe.sol\";\n\n/**\n * @title LoupeFromStorage Interface\n * @dev Interface contract to function as a loupe facet directly attached to diamond storage of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IStorageLoupe {\n /// These functions are expected to be called frequently\n /// by tools.\n\n /// @notice Gets all facet addresses and their four byte function selectors.\n /// @return facets_ Facet\n function facetsFromStorage()\n external\n view\n returns (IDiamondLoupe.Facet[] memory);\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n function facetFunctionSelectorsFromStorage(\n address _facet\n ) external view returns (bytes4[] memory);\n\n /// @notice Get all the facet addresses used by a diamond.\n function facetAddressesFromStorage()\n external\n view\n returns (address[] memory);\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n function facetAddressFromStorage(\n bytes4 _functionSelector\n ) external view returns (address);\n}\n" + }, + "contracts/facets/GuardianFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibFacetStorage, GuardianStorage, StorageConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IGuardianFacet} from \"./interfaces/IGuardianFacet.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Guardian Facet\n * @dev Contract that enables addition/removal of guardians from Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract GuardianFacet is IGuardianFacet {\n ISecurityManager public immutable securityManager;\n uint8 public constant INNER_STRUCT = 0;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Add guardians to Barz.\n * @dev This method internally calls addGuardian which checks the validity of guardian address and adds\n * as guardian if valid\n * @param _guardians Array of addresses to add as guardian\n */\n function addGuardians(address[] calldata _guardians) external override {\n LibDiamond.enforceIsSelf();\n uint256 guardiansLength = _guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n addGuardian(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Add a guardian to Barz.\n * @dev This method checks if the function is called by the owner and validates the address of guardian\n * When the validation passes, guardian address is added to the pending state waiting for confirmation\n * @param _guardian Address to add as guardian\n */\n function addGuardian(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (_guardian == address(this))\n revert GuardianFacet__GuardianCannotBeSelf();\n if (isGuardian(_guardian)) revert GuardianFacet__DuplicateGuardian();\n if (_guardian == address(0))\n revert GuardianFacet__ZeroAddressGuardian();\n if (\n keccak256(abi.encodePacked(_guardian)) ==\n keccak256(IVerificationFacet(address(this)).owner())\n ) revert GuardianFacet__OwnerCannotBeGuardian();\n\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n if (\n gs.pending[id] != 0 ||\n block.timestamp <= gs.pending[id] + getSecurityWindow()\n ) revert GuardianFacet__DuplicateGuardianAddition();\n\n uint256 securityPeriod = getAdditionSecurityPeriod();\n gs.pending[id] = block.timestamp + securityPeriod;\n emit GuardianAdditionRequested(\n _guardian,\n block.timestamp + securityPeriod\n );\n }\n\n /**\n * @notice Remove guardians from Barz.\n * @dev This method internally calls removeGuardian which checks the validity of guardian and removes\n * guardian when the request is valid\n * @param _guardians Array of addresses to be removed\n */\n function removeGuardians(address[] calldata _guardians) external override {\n LibDiamond.enforceIsSelf();\n uint256 guardiansLength = _guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n removeGuardian(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Remove a guardian from Barz.\n * @dev This method validates if the guardian to be removed is a guardian and puts the guardian removal\n * to a pending state waiting to be confirmed.\n * @param _guardian Address of guardian to be removed\n */\n function removeGuardian(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n if (!isGuardian(_guardian)) revert GuardianFacet__NonExistentGuardian();\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n if (\n gs.pending[id] != 0 ||\n block.timestamp <= gs.pending[id] + getSecurityWindow()\n ) revert GuardianFacet__DuplicateGuardianRemoval();\n\n uint256 securityPeriod = getRemovalSecurityPeriod();\n gs.pending[id] = block.timestamp + securityPeriod;\n emit GuardianRemovalRequested(\n _guardian,\n block.timestamp + securityPeriod\n );\n }\n\n /**\n * @notice Confirm addition of guardians\n * @dev This method internally calls confirmGuardianAddition which checks the validity of pending request.\n * Guardians are fully added when they pass the validation. Anyone can call this function.\n * @param _guardians Array of guardian addresses to be added\n */\n function confirmGuardianAdditions(\n address[] calldata _guardians\n ) external override {\n uint256 guardiansLength = _guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n confirmGuardianAddition(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Confirm addition of a guardian\n * @dev This method checks the validity of pending request.\n * Guardians are fully added when they pass the validation. Anyone can call this function.\n * @param _guardian Guardian address to be added\n */\n function confirmGuardianAddition(address _guardian) public override {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingAddition();\n if (gs.pending[id] >= block.timestamp)\n revert GuardianFacet__PendingAdditionNotOver();\n if (block.timestamp >= gs.pending[id] + getSecurityWindow())\n revert GuardianFacet__PendingAdditionExpired();\n\n _addGuardian(_guardian);\n\n delete gs.pending[id];\n emit GuardianAdded(_guardian);\n }\n\n /**\n * @notice Confirm removal of guardians\n * @dev This method internally calls confirmGuardianRemoval to check the validity guardian removal confirmation.\n * Guardians are fully removed when they pass the validation. Anyone can call this function.\n * @param _guardians Array of guardian addresses to be removed\n */\n function confirmGuardianRemovals(\n address[] calldata _guardians\n ) external override {\n uint256 guardiansLength = _guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n confirmGuardianRemoval(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Confirm removal of a guardian\n * @dev This method checks the validity guardian removal confirmation.\n * Guardian is fully removed when they pass the validation. Anyone can call this function.\n * @param _guardian Guardian address to be removed\n */\n function confirmGuardianRemoval(address _guardian) public override {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingRemoval();\n if (gs.pending[id] >= block.timestamp)\n revert GuardianFacet__PendingRemovalNotOver();\n if (block.timestamp >= gs.pending[id] + getSecurityWindow())\n revert GuardianFacet__PendingAdditionExpired();\n\n _removeGuardian(_guardian);\n delete gs.pending[id];\n emit GuardianRemoved(_guardian);\n }\n\n /**\n * @notice Cancel pending guardian addition\n * @dev This method checks if the previous request for guardian request exists.\n * It reverts if previous request is not pending and cancels the addition otherwise.\n * @param _guardian Guardian address to be canceled from addition\n */\n function cancelGuardianAddition(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingAddition();\n delete gs.pending[id];\n emit GuardianAdditionCancelled(_guardian);\n }\n\n /**\n * @notice Cancel pending guardian removal\n * @dev This method checks if the previous request for guardian request exists.\n * It reverts if previous request is not pending and cancels the removal otherwise.\n * @param _guardian Guardian address to be canceled from removal\n */\n function cancelGuardianRemoval(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingRemoval();\n delete gs.pending[id];\n emit GuardianRemovalCancelled(_guardian);\n }\n\n /**\n * @notice Get the addition security period of current account from security manager\n * @dev This method returns the uint value if addition security period\n * @return additionSecurityPeriod Uint256 value of addition security period\n */\n function getAdditionSecurityPeriod()\n public\n view\n override\n returns (uint256 additionSecurityPeriod)\n {\n additionSecurityPeriod = securityManager.additionSecurityPeriodOf(\n address(this)\n );\n if (additionSecurityPeriod == 0)\n revert GuardianFacet__InvalidAdditionSecurityPeriod();\n }\n\n /**\n * @notice Get the removal security period of current account from security manager\n * @dev This method returns the uint value if removal security period\n * @return removalSecurityPeriod Uint256 value of removal security period\n */\n function getRemovalSecurityPeriod()\n public\n view\n override\n returns (uint256 removalSecurityPeriod)\n {\n removalSecurityPeriod = securityManager.removalSecurityPeriodOf(\n address(this)\n );\n if (removalSecurityPeriod == 0)\n revert GuardianFacet__InvalidRemovalSecurityPeriod();\n }\n\n /**\n * @notice Get the security window of current account from security manager\n * @dev This method returns the uint value if security window\n * @return securityWindow Uint256 value of removal security period\n */\n function getSecurityWindow()\n public\n view\n override\n returns (uint256 securityWindow)\n {\n securityWindow = securityManager.securityWindowOf(address(this));\n if (securityWindow == 0) revert GuardianFacet__InvalidSecurityWindow();\n }\n\n /**\n * @notice Checks if the addition of the given guardian address is pending\n * @dev This method returns the bool value of whether the guardian address is pending addition\n * @return isPending Bool value of representing the pending of guardian addition\n */\n function isAdditionPending(\n address _guardian\n ) public view override returns (bool isPending) {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n isPending = _isPending(id);\n }\n\n /**\n * @notice Checks if the removal of the given guardian address is pending\n * @dev This method returns the bool value of whether the guardian address is pending removal\n * @return isPending Bool value of representing the pending of guardian removal\n */\n function isRemovalPending(\n address _guardian\n ) public view override returns (bool isPending) {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n isPending = _isPending(id);\n }\n\n /**\n * @notice Checks if the given hash is pending\n * @dev This method returns the bool value whether the hash is pending\n * @return isPending Bool value of representing the pending of guardian operation\n */\n function _isPending(\n bytes32 _idHash\n ) internal view returns (bool isPending) {\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n isPending = ((gs.pending[_idHash] > 0 &&\n gs.pending[_idHash] < block.timestamp) &&\n block.timestamp < gs.pending[_idHash] + getSecurityWindow());\n }\n\n /**\n * @notice Adds guardian to storage config. This is called when guardian is fully added.\n * @dev This method add guardian address and config information to Facet Storage dedicated for guardian\n * When this function is called, guardian is fully added to this Barz Smart Account\n * @param _guardian Address of guardian to be added\n */\n function _addGuardian(address _guardian) internal {\n if (!isAdditionPending(_guardian))\n revert GuardianFacet__InvalidGuardianAddition();\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n if (config.info[_guardian].exists)\n revert GuardianFacet__AlreadyExists();\n\n config.info[_guardian].exists = true;\n config.info[_guardian].index = uint128(config.addresses.length);\n config.addresses.push(_guardian);\n }\n\n /**\n * @notice Removes guardian to storage config. This is called when guardian is fully removed.\n * @dev This method remove guardian address and config information to Facet Storage dedicated for guardian\n * When this function is called, guardian is fully removed from this Barz Smart Account\n * @param _guardian Address of guardian to be removed\n */\n function _removeGuardian(address _guardian) internal {\n if (!isRemovalPending(_guardian))\n revert GuardianFacet__InvalidGuardianRemoval();\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n if (!config.info[_guardian].exists)\n revert GuardianFacet__NonExistentGuardian();\n\n address lastAddress = config.addresses[config.addresses.length - 1];\n if (_guardian != lastAddress) {\n uint128 targetIndex = config.info[_guardian].index;\n config.addresses[targetIndex] = lastAddress;\n config.info[lastAddress].index = targetIndex;\n }\n config.addresses.pop();\n delete config.info[_guardian];\n\n emit GuardianRemoved(_guardian);\n }\n\n /**\n * @notice Reads guardian storage and fetches the addresses into an array from the storage\n * @dev This method fetches the guardian storage and returns the list of guardian addresses\n * @return addresses Array of addresses comprised of guardian\n */\n function getGuardians()\n public\n view\n override\n returns (address[] memory addresses)\n {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n addresses = new address[](config.addresses.length);\n uint256 addressesLen = config.addresses.length;\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the number of majority of guardians\n * @return majorityOfGuardians_ Number of majority of guardians e.g., 2 if 3 guardians / 3 if 5 guardians\n */\n function majorityOfGuardians()\n public\n view\n override\n returns (uint256 majorityOfGuardians_)\n {\n majorityOfGuardians_ = LibGuardian.majorityOfGuardians();\n }\n\n /**\n * @notice Reads guardian storage and fetches the addresses into an array from the storage\n * @dev This method fetches the guardian storage and returns the list of guardian addresses\n * @return guardianNumber Array of guardians in the account\n */\n function guardianCount()\n public\n view\n override\n returns (uint256 guardianNumber)\n {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n guardianNumber = config.addresses.length;\n }\n\n /**\n * @notice Reads guardian storage and checks if the given address is a guardian\n * @return isGuardian_ Bool value representing if the given address is guardian\n */\n function isGuardian(\n address _guardian\n ) public view override returns (bool isGuardian_) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n isGuardian_ = config.info[_guardian].exists;\n }\n\n /**\n * @notice Checks if the guardian number is zero and returns of guardian facet is okay to be removed\n * @return isRemovable Bool value representing if guardian facet is removable\n */\n function isGuardianFacetRemovable()\n external\n view\n override\n returns (bool isRemovable)\n {\n isRemovable = (0 == guardianCount());\n }\n}\n" + }, + "contracts/facets/interfaces/IAccountFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IEntryPoint} from \"../../aa-4337/interfaces/IEntryPoint.sol\";\n\n/**\n * @title Account Facet Interface\n * @dev Interface of module contract that provides the account features and init/unitialization of signer\n * compatible with EIP-1271 & EIP-4337\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IAccountFacet {\n event AccountInitialized(\n IEntryPoint indexed entryPoint,\n bytes indexed ownerPublicKey\n );\n // NOTE: Added Below Event\n event VerificationSuccess(bytes32);\n event VerificationFailure(bytes32);\n\n error AccountFacet__InitializationFailure();\n error AccountFacet__RestrictionsFailure();\n error AccountFacet__NonExistentVerificationFacet();\n error AccountFacet__CallNotSuccessful();\n\n function initialize(\n address verificationFacet,\n address anEntryPoint,\n address facetRegistry,\n address _defaultFallBack,\n bytes calldata _ownerPublicKey\n ) external returns (uint256);\n\n function execute(address dest, uint256 value, bytes calldata func) external;\n\n function executeBatch(\n address[] calldata dest,\n uint256[] calldata value,\n bytes[] calldata func\n ) external;\n}\n" + }, + "contracts/facets/interfaces/IAccountRecoveryFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {RecoveryConfig} from \"../../libraries/LibFacetStorage.sol\";\n\n/**\n * @title Account Recovery Facet Interface\n * @dev Interface of contract that enables recovery of accounts when owner key is unavailable\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IAccountRecoveryFacet {\n event RecoveryExecuted(\n bytes indexed recoveryPublicKey,\n uint64 executeAfter\n );\n event RecoveryFinalized(bytes indexed recoveryPublicKey);\n event RecoveryCanceled(bytes indexed recoveryPublicKey);\n event RecoveryApproved(\n bytes indexed recoveryPublicKey,\n address indexed guardian,\n uint64 validUntil\n );\n event RecoveryApprovalRevoked(\n bytes indexed recoveryPublicKey,\n address indexed guardian\n );\n event RecoveryCancellationApproved(\n bytes indexed recoveryPublicKey,\n address indexed guardian\n );\n event RecoveryHardstopped();\n\n error AccountRecoveryFacet__CallerNotGuardian();\n error AccountRecoveryFacet__InvalidRecoveryPublicKey();\n error AccountRecoveryFacet__SignerInitializationFailure();\n error AccountRecoveryFacet__SignerUninitializationFailure();\n error AccountRecoveryFacet__InvalidArrayLength();\n error AccountRecoveryFacet__InsufficientGuardians();\n error AccountRecoveryFacet__RecoveryAlreadyOngoing();\n error AccountRecoveryFacet__NonexistentRecovery();\n error AccountRecoveryFacet__NonExistentApproval();\n error AccountRecoveryFacet__RecoveryPeriodNotOver();\n error AccountRecoveryFacet__InvalidLockPeriod();\n error AccountRecoveryFacet__InvalidRecoveryPeriod();\n error AccountRecoveryFacet__InvalidApprovalValidationPeriod();\n error AccountRecoveryFacet__InvalidGuardian();\n error AccountRecoveryFacet__InvalidGuardianSignature();\n error AccountRecoveryFacet__InvalidOwnerSignature();\n error AccountRecoveryFacet__CallNotSuccesful();\n error AccountRecoveryFacet__DuplicateApproval();\n\n function approveAccountRecovery(bytes calldata recoveryPublicKey) external;\n\n function revokeAccountRecoveryApproval(\n bytes calldata recoveryPublicKey\n ) external;\n\n function executeRecovery(\n bytes calldata recoveryPublicKey,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function finalizeRecovery() external;\n\n function approveCancelRecovery(bytes calldata recoveryPublicKey) external;\n\n function cancelRecovery(\n bytes calldata recoveryPublicKey,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function hardstopRecovery(bytes calldata signature) external;\n\n function getApprovalRecoveryKeyHash(\n bytes memory recoveryPublicKey,\n string memory saltString\n ) external view returns (bytes32);\n\n function getRecoveryApprovalCountWithTimeValidity(\n bytes32 recoveryPublicKeyHash\n ) external view returns (uint256);\n\n function isRecoveryApproved(\n bytes32 recoveryPublicKeyHash,\n address approver\n ) external view returns (bool);\n\n function getRecoveryNonce() external view returns (uint128);\n\n function getPendingRecovery() external view returns (RecoveryConfig memory);\n}\n" + }, + "contracts/facets/interfaces/IGuardianFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Guardian Facet Interface\n * @dev Interface of guaridna contract that enables addition/removal of guardians from Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IGuardianFacet {\n event GuardianAdditionRequested(\n address indexed guardian,\n uint256 executeAfter\n );\n event GuardianRemovalRequested(\n address indexed guardian,\n uint256 executeAfter\n );\n event GuardianAdditionCancelled(address indexed guardian);\n event GuardianRemovalCancelled(address indexed guardian);\n event GuardianAdded(address indexed guardian);\n event GuardianRemoved(address indexed guardian);\n\n error GuardianFacet__GuardianCannotBeSelf();\n error GuardianFacet__DuplicateGuardian();\n error GuardianFacet__OwnerCannotBeGuardian();\n error GuardianFacet__DuplicateGuardianAddition();\n error GuardianFacet__DuplicateGuardianRemoval();\n error GuardianFacet__UnknownPendingAddition();\n error GuardianFacet__PendingAdditionNotOver();\n error GuardianFacet__UnknownPendingRemoval();\n error GuardianFacet__PendingRemovalNotOver();\n error GuardianFacet__PendingAdditionExpired();\n error GuardianFacet__InvalidAdditionSecurityPeriod();\n error GuardianFacet__InvalidRemovalSecurityPeriod();\n error GuardianFacet__InvalidSecurityWindow();\n error GuardianFacet__NonExistentGuardian();\n error GuardianFacet__AlreadyExists();\n error GuardianFacet__InvalidGuardianAddition();\n error GuardianFacet__InvalidGuardianRemoval();\n error GuardianFacet__ZeroAddressGuardian();\n\n function addGuardian(address guardian) external;\n\n function addGuardians(address[] calldata guardians) external;\n\n function removeGuardian(address guardian) external;\n\n function removeGuardians(address[] calldata guardians) external;\n\n function confirmGuardianAddition(address guardian) external;\n\n function confirmGuardianAdditions(address[] calldata guardian) external;\n\n function confirmGuardianRemoval(address guardian) external;\n\n function confirmGuardianRemovals(address[] calldata guardian) external;\n\n function cancelGuardianAddition(address guardian) external;\n\n function cancelGuardianRemoval(address guardian) external;\n\n function isGuardian(address guardian) external view returns (bool);\n\n function isAdditionPending(address guardian) external view returns (bool);\n\n function isRemovalPending(address guardian) external view returns (bool);\n\n function isGuardianFacetRemovable() external view returns (bool);\n\n function getAdditionSecurityPeriod() external view returns (uint256);\n\n function getRemovalSecurityPeriod() external view returns (uint256);\n\n function getSecurityWindow() external view returns (uint256);\n\n function getGuardians() external view returns (address[] memory);\n\n function majorityOfGuardians() external view returns (uint256);\n\n function guardianCount() external view returns (uint256);\n}\n" + }, + "contracts/facets/interfaces/ILockFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Lock} from \"../../libraries/LibAppStorage.sol\";\n\n/**\n * @title Lock Facet Interface\n * @dev Interface of Lock contract that enables full lock/unlock of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface ILockFacet {\n event Locked(uint64 releaseAfter);\n event Unlocked();\n\n error LockFacet__InvalidRecoveryPeriod();\n error LockFacet__CannotUnlock();\n error LockFacet__InvalidSignature();\n error LockFacet__InvalidApprover();\n\n function lock() external;\n\n function unlock(address approver, bytes calldata signature) external;\n\n function getLockPeriod() external view returns (uint256);\n\n function isLocked() external view returns (bool);\n\n function getUnlockHash() external view returns (bytes32);\n\n function lockNonce() external view returns (uint128);\n\n function getPendingLock() external view returns (Lock memory);\n}\n" + }, + "contracts/facets/interfaces/IMultiSigFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Multi-sig facet Interface\n * @dev Interface of Multi-signature Facet with custom threshold.\n Wallet that adds this facet becomes a multi-sig wallet\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IMultiSigFacet {\n event ThresholdChanged(uint256 threshold);\n event OwnerAdded(address indexed newOwner);\n event OwnerRemoved(address indexed prevOwner);\n event HashApproved(bytes32 hashToApprove, address indexed owner);\n\n error MultiSigFacet__InvalidThreshold();\n error MultisigFacet__InvalidOwnerCount();\n error MultiSigFacet__InvalidRoute();\n error MultiSigFacet__InsufficientSignerLength();\n error MultiSigFacet__InvalidInitData();\n error MultiSigFacet__InvalidOwnerAddress();\n error MultiSigFacet__InvalidOwnerPair();\n error MultiSigFacet__InvalidSignatureLength();\n error MultiSigFacet__InvalidSignatureType();\n error MultiSigFacet__DuplicateOwner();\n error MultiSigFacet__OnlyOwner();\n\n function checkSignatures(\n bytes32 _dataHash,\n bytes calldata _signatures,\n uint256 _threshold\n ) external view returns (uint256);\n\n function splitSignatures(\n bytes calldata _signatures,\n uint256 _nextOffset\n )\n external\n pure\n returns (\n address owner,\n bytes memory signature,\n uint256 signatureType,\n uint256 nextOffset\n );\n\n function approveHash(bytes32 hashToApprove) external;\n\n function addOwner(address newOwner, uint256 threshold) external;\n\n function removeOwner(\n address prevOwner,\n address removedOwner,\n uint256 threshold\n ) external;\n\n function swapOwner(\n address prevOwner,\n address oldOwner,\n address newOwner\n ) external;\n\n function changeThreshold(uint256 _threshold) external;\n\n function isOwner(address owner) external view returns (bool);\n\n function getThreshold() external view returns (uint256);\n\n function getOwners() external view returns (address[] memory);\n}\n" + }, + "contracts/facets/interfaces/IRestrictionsFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Restrictions Facet Interface\n * @dev Interface of Restrictions contract that enables modular restrictions in Barz\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IRestrictionsFacet {\n event RestrictionAdded(address indexed restriction);\n event RestrictionRemoved(address indexed restriction);\n\n error RestrictionsFacet__EmptyRestrictionsList();\n error RestrictionsFacet__RestrictionNotFound();\n error RestrictionsFacet__RestrictionAlreadyExists();\n error RestrictionsFacet__ZeroAddressRestrictions();\n error RestrictionsFacet__ZeroAddressRestrictionsFacet();\n error RestrictionsFacet__RemainingRestrictionsCantBeEmpty();\n\n function initializeRestrictions(\n address[] memory _restrictions\n ) external returns (uint256);\n\n function uninitializeRestrictions() external returns (uint256);\n\n function getRestrictions() external view returns (address[] memory);\n\n function addRestriction(address restriction) external;\n\n function removeRestriction(address restriction) external;\n\n function verifyRestrictions(\n address from,\n address to,\n uint256 value,\n bytes calldata _calldata\n ) external returns (uint256);\n}\n" + }, + "contracts/facets/interfaces/ISignatureMigrationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureMigrationConfig} from \"../../libraries/LibFacetStorage.sol\";\n\n/**\n * @title Signature Migration Facet Interface\n * @dev Interface of Signature Migration contract for migrating user signature scheme to a new scheme user sets\n * Which could include\n * - ECDSA on Secp256K1 Curve\n * - ECDSA on Secp256R1 Curve\n * - BLS, Schnorr, etc\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface ISignatureMigrationFacet {\n event SignatureSchemeMigration(\n address indexed prevVerificationFacet,\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n event SignatureMigrationApproved(\n bytes newPublicKey,\n address indexed newVerificationFacet,\n bytes4[] verificationFuncSelectors,\n address indexed guardian,\n uint128 approvalValidUntil\n );\n event SignatureMigrationApprovalRevoked(\n bytes newPublicKey,\n address indexed newVerificationFacet,\n bytes4[] verificationFuncSelectors,\n address indexed guardian\n );\n event SignatureMigrationExecuted(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors,\n uint128 migrateAfter\n );\n event SignatureMigrationCanceled(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n event SignatureMigrationCancellationApproved(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n\n error SignatureMigrationFacet__SignerUninitializationFailure();\n error SignatureMigrationFacet__InvalidRouteWithGuardian();\n error SignatureMigrationFacet__InvalidKeyType();\n error SignatureMigrationFacet__InsufficientApprovers();\n error SignatureMigrationFacet__InvalidApproverSignature();\n error SignatureMigrationFacet__InvalidGuardian();\n error SignatureMigrationFacet__NonExistentApprover();\n error SignatureMigrationFacet__InvalidMigrationPeriod();\n error SignatureMigrationFacet__NonexistentMigration();\n error SignatureMigrationFacet__MigrationPeriodNotOver();\n error SignatureMigrationFacet__InvalidArrayLength();\n error SignatureMigrationFacet__InvalidApprovalValidationPeriod();\n error SignatureMigrationFacet__CannotRevokeUnapproved();\n error SignatureMigrationFacet__LackOfOwnerApproval();\n error SignatureMigrationFacet__OwnerAlreadyApproved();\n error SignatureMigrationFacet__NonExistentVerificationFacet();\n error SignatureMigrationFacet__DuplicateApproval();\n\n function migrateSignatureScheme(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function migrateSignatureSchemeWithGuardian(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors,\n address[] calldata approvers,\n bytes[] calldata signatures\n ) external;\n\n function approveSignatureSchemeMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function revokeSignatureMigrationApproval(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function finalizeSignatureMigration() external;\n\n function approveCancelSignatureMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function cancelSignatureMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function getApprovalMigrationKeyHash(\n bytes memory recoveryPublicKey,\n address newVerificationFacet,\n bytes4[] memory newVerificationFuncSelectors,\n string memory saltString\n ) external view returns (bytes32);\n\n function getMigrationOwnerApprovalWithTimeValidity(\n bytes32 publicKeyHash\n ) external view returns (bool);\n\n function getMigrationApprovalCountWithTimeValidity(\n bytes32 publicKeyHash\n ) external view returns (uint256);\n\n function isMigrationApproved(\n bytes32 migrationPublicKeyHash,\n address approver\n ) external view returns (bool);\n\n function getMigrationNonce() external view returns (uint128);\n\n function isMigrationPending() external view returns (bool);\n\n function getPendingMigration()\n external\n view\n returns (SignatureMigrationConfig memory);\n}\n" + }, + "contracts/facets/interfaces/IVerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {UserOperation} from \"../../aa-4337/interfaces/UserOperation.sol\";\n\n/**\n * @title Verification Facet Interface\n * @dev Implements logic for user ops signature verification\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface IVerificationFacet {\n event SignerInitialized(bytes);\n event SignerUninitialized();\n\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n error VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n error VerificationFacet__InitializationFailure();\n error VerificationFacet__InvalidFacetMapping();\n\n function initializeSigner(bytes memory) external returns (uint256);\n\n function uninitializeSigner() external returns (uint256);\n\n function validateOwnerSignatureSelector() external view returns (bytes4);\n\n function owner() external view returns (bytes memory);\n\n function isValidKeyType(bytes calldata) external view returns (bool);\n\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) external view returns (uint256);\n}\n" + }, + "contracts/facets/LockFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage, Lock} from \"../libraries/LibAppStorage.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibFacetStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {ILockFacet} from \"./interfaces/ILockFacet.sol\";\n\n/**\n * @title Lock Facet\n * @dev Contract that enables full lock/unlock of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract LockFacet is ILockFacet, Modifiers {\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Locks the account for the lock period. Lock period is defined in the security manager and it's customizable\n * This function can only be called when account is unlocked by owner or guardians\n * @dev This method checks the caller and if the account is currently locked and locks the account after fetching the\n * Lock period from the owner.\n */\n function lock() external override onlyGuardianOrOwner onlyWhenUnlocked {\n uint256 unlockTime = block.timestamp + getLockPeriod();\n ++LibFacetStorage.lockStorage().nonce;\n LibAppStorage.setLock(unlockTime, LockFacet.lock.selector);\n emit Locked(uint64(unlockTime));\n }\n\n /**\n * @notice Locks the account when the account is locked. This function can be called by anyone but must provide the approver address and signature.\n * The approver should be one of the guardians or owner.\n * @dev This method takes the approver address and the signature. After validating the address and the signature, it unlocks the account immediately.\n * Only one of the guardian or owner is required to lock and unlock the account.\n * @param _approver Address of approver approving the unlock of Barz account\n * @param _signature Signature of the approver that signed the msg hash for unlocking the account\n */\n function unlock(\n address _approver,\n bytes calldata _signature\n ) external override onlyWhenLocked {\n if (_approver != address(this) && !LibGuardian.isGuardian(_approver))\n revert LockFacet__InvalidApprover();\n if (\n !SignatureChecker.isValidSignatureNow(\n _approver,\n getUnlockHash(),\n _signature\n )\n ) revert LockFacet__InvalidSignature();\n _unlock();\n }\n\n /**\n * @notice Unlocks the account and increments the lock nonce\n */\n function _unlock() private {\n if (s.locks[INNER_STRUCT].locker != LockFacet.lock.selector)\n revert LockFacet__CannotUnlock();\n ++LibFacetStorage.lockStorage().nonce;\n LibAppStorage.setLock(0, bytes4(0));\n emit Unlocked();\n }\n\n /**\n * @notice Returns the lock period of current Barz account. Lock period information is held by Security Manager\n * @return lockPeriod Uint value of lock period in seconds\n */\n function getLockPeriod() public view override returns (uint256 lockPeriod) {\n lockPeriod = securityManager.lockPeriodOf(address(this));\n if (lockPeriod == 0) revert LockFacet__InvalidRecoveryPeriod();\n }\n\n /**\n * @notice Returns if the account is locked or not\n * @dev This method fetches the current block timestamp and compares that with release time.\n * After checking the timestamp and release time, it returns if the account is still locked or not.\n * @return isLocked_ Uint value of lock period in seconds\n */\n function isLocked() public view override returns (bool isLocked_) {\n isLocked_ = uint64(block.timestamp) < s.locks[INNER_STRUCT].release;\n }\n\n /**\n * @notice Calculates the unlock hash and returns the unlock hash safe from signature reply attack\n * @dev This method calculates the unlock hash with EIP-191 prefix, wallet address, chainID, and nonce\n * It packs the result and packs them and hashes it.\n * @return unlockHash Bytes32 unlock hash\n */\n function getUnlockHash() public view override returns (bytes32 unlockHash) {\n unlockHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n \"Unlock\",\n address(this),\n block.chainid,\n lockNonce()\n )\n )\n )\n );\n }\n\n /**\n * @notice Returns lock nonce of account. Reads nonce from lock storage within facet storage\n * @return lockNonce_ Uint128 value of lock nonce. This is incremented whenever the account is lock/unlocked\n */\n function lockNonce() public view override returns (uint128 lockNonce_) {\n lockNonce_ = LibFacetStorage.lockStorage().nonce;\n }\n\n /**\n * @notice Returns the overall information of current lock\n * @return pendingLock Struct value including all information of pending lock\n */\n function getPendingLock()\n public\n view\n override\n returns (Lock memory pendingLock)\n {\n pendingLock = s.locks[INNER_STRUCT];\n }\n}\n" + }, + "contracts/facets/Modifiers.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {IFacetRegistry} from \"../infrastructure/interfaces/IFacetRegistry.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\n\n/**\n * @title Modifiers\n * @dev Responsible for providing modifiers/util functions to Facet contracts\n * @author David Yongjun Kim (@Powerstream3604)\n */\nabstract contract Modifiers is BarzStorage {\n uint8 constant INNER_STRUCT = 0;\n\n error CallerNotGuardian();\n error CallerNotGuardianOrOwner();\n error DuplicateApprover();\n error ZeroApproverLength();\n error UnregisteredFacetAndSelectors();\n\n /**\n * @notice Modifier to only allow guardian to make a call, reverts if any other entity is the caller\n */\n modifier onlyGuardian() {\n if (!LibGuardian.isGuardian(msg.sender)) revert CallerNotGuardian();\n _;\n }\n\n /**\n * @notice Modifier to only allow guardian or owner to make a call, reverts if any other entity is the caller\n */\n modifier onlyGuardianOrOwner() {\n if (!LibGuardian.isGuardian(msg.sender) && address(this) != msg.sender)\n revert CallerNotGuardianOrOwner();\n _;\n }\n\n /**\n * @notice Checks if the approver address is the array is unique with no duplicate\n * @dev This method loops through the array and checks if a duplicate address exists, it reverts if duplicate address exists\n * @param approvers Array of address\n */\n function _checkApprover(\n address[] memory approvers\n ) internal pure returns (bool) {\n uint256 approverLength = approvers.length;\n if (0 == approverLength) revert ZeroApproverLength();\n for (uint256 i; i < approverLength - 1; ) {\n for (uint256 j = i + 1; j < approverLength; ) {\n if (approvers[i] == approvers[j]) {\n revert DuplicateApprover(); // Found a duplicate\n }\n unchecked {\n ++j;\n }\n }\n unchecked {\n ++i;\n }\n }\n return false; // No duplicates found\n }\n\n /**\n * @notice Checks if the facet getting added or replaced is registered to facet registry\n * @dev This method loops through the cut and checks if the facet getting added/replaced is registered to facet registry\n * @param _diamondCut Array of FacetCut, data for diamondCut defined in EIP-2535\n */\n function _checkFacetCutValidity(\n IDiamondCut.FacetCut[] memory _diamondCut\n ) internal view {\n uint256 diamondCutLength = _diamondCut.length;\n for (uint256 i; i < diamondCutLength; ) {\n if (\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Add ||\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Replace\n ) {\n if (\n !s.facetRegistry.areFacetFunctionSelectorsRegistered(\n _diamondCut[i].facetAddress,\n _diamondCut[i].functionSelectors\n )\n ) revert UnregisteredFacetAndSelectors();\n }\n unchecked {\n ++i;\n }\n }\n }\n}\n" + }, + "contracts/facets/RestrictionsFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, RestrictionsStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {IRestriction} from \"../restrictions/IRestriction.sol\";\nimport {IRestrictionsFacet} from \"./interfaces/IRestrictionsFacet.sol\";\n\n/**\n * @title Restrictions facet\n * @dev Responsible for storing and verifying different kinds of restrictions, for example:\n * - Whitelist / Blacklist\n * - Daily limits\n * - Trading time restrictions\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract RestrictionsFacet is IRestrictionsFacet {\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceRestrictionsInitialize();\n }\n\n /**\n * @notice Intialize restrictions of Barz. Restrictions facet call restriction contracts for restriction validation\n * before each call\n * @param _restrictions The initial array of restrictions.\n * @return initSuccess Int value showing if the initialization of restriction is successful\n */\n function initializeRestrictions(\n address[] calldata _restrictions\n ) public override returns (uint256 initSuccess) {\n LibDiamond.enforceIsSelf();\n LibAppStorage.enforceRestrictionsInitialize();\n\n uint256 restrictionsLength = _restrictions.length;\n if (restrictionsLength == 0) {\n // You can't initialize RestrictionsFacet with an empty list of restrictions\n revert RestrictionsFacet__EmptyRestrictionsList();\n }\n for (uint256 i; i < restrictionsLength; ) {\n if (_restrictions[i] == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictions();\n unchecked {\n ++i;\n }\n }\n\n LibFacetStorage.restrictionsStorage().restrictions = _restrictions;\n _updateRestrictionsMap(_restrictions, true);\n initSuccess = 1;\n }\n\n /**\n * @notice Unitialize restrictions of Barz\n * @return uninitSuccess Int value showing if the initialization of restriction is successful\n */\n function uninitializeRestrictions()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibDiamond.enforceIsSelf();\n LibAppStorage.setRestrictionsUninitialized();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n _updateRestrictionsMap(restrictionsStorage.restrictions, false);\n restrictionsStorage.restrictions = new address[](0);\n uninitSuccess = 1;\n }\n\n /**\n * @notice Returns the list of Restrictions contract address\n * @return restrictions Addresses of IRestriction which are currently active\n */\n function getRestrictions()\n public\n view\n override\n returns (address[] memory restrictions)\n {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n restrictions = restrictionsStorage.restrictions;\n }\n\n /**\n * @notice Adds restrictions to Barz with validation on the restriction contract address.\n * This method is only callable by the owner(self).\n * @param _restriction The address of the restriction to be added.\n */\n function addRestriction(address _restriction) external override {\n LibDiamond.enforceIsSelf();\n if (LibDiamond.restrictionsFacet() == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictionsFacet();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n if (_restriction == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictions();\n if (restrictionsStorage.exists[_restriction])\n revert RestrictionsFacet__RestrictionAlreadyExists();\n\n restrictionsStorage.restrictions.push(_restriction);\n restrictionsStorage.exists[_restriction] = true;\n\n emit RestrictionAdded(_restriction);\n }\n\n /**\n * @notice Remove restrictions from Barz if it existed. This method is only callable by the owner(self).\n * @param _restriction The address of the restriction to be removed.\n */\n function removeRestriction(address _restriction) external override {\n LibDiamond.enforceIsSelf();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n if (!restrictionsStorage.exists[_restriction])\n revert RestrictionsFacet__RestrictionNotFound();\n\n address[] storage restrictions = restrictionsStorage.restrictions;\n\n uint256 indexToDelete = restrictions.length;\n uint256 restrictionsLen = restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n if (restrictions[i] == _restriction) {\n indexToDelete = i;\n break;\n }\n unchecked {\n ++i;\n }\n }\n\n if (indexToDelete == 0 && restrictionsLen == 1) {\n revert RestrictionsFacet__RemainingRestrictionsCantBeEmpty();\n } else if (indexToDelete == restrictionsLen) {\n revert RestrictionsFacet__RestrictionNotFound();\n } else {\n restrictions[indexToDelete] = restrictions[restrictionsLen - 1];\n restrictions.pop();\n }\n\n restrictionsStorage.exists[_restriction] = false;\n emit RestrictionRemoved(_restriction);\n }\n\n /**\n * @notice Sets the restrictions address value mapping to true or false when adding/removing restriction contracts\n * @param _restrictions List of restriction contracts address\n * @param _newValue Bool value to flag to the list of restrictions contracts\n */\n function _updateRestrictionsMap(\n address[] memory _restrictions,\n bool _newValue\n ) internal {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n uint restrictionsLen = _restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n restrictionsStorage.exists[_restrictions[i]] = _newValue;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @dev Iterates over all restrictions and verifies each of them with the transaction parameters.\n * @param _from The address of the sender, that will be signing the transaction.\n * @param _to The receiving address.\n * @param _value Amount of ETH to transfer from sender to recipient.\n * @param _calldata Optional field to include arbitrary data.\n * @return 0 if all the checks passed, 1 otherwise.\n */\n function verifyRestrictions(\n address _from,\n address _to,\n uint256 _value,\n bytes calldata _calldata\n ) external returns (uint256) {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n uint restrictionsLen = restrictionsStorage.restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n IRestriction restriction = IRestriction(\n restrictionsStorage.restrictions[i]\n );\n bool checkPassed = restriction.check(_from, _to, _value, _calldata);\n if (!checkPassed) {\n return 1;\n }\n unchecked {\n ++i;\n }\n }\n\n return 0;\n }\n}\n" + }, + "contracts/facets/SignatureMigrationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, SignatureMigrationStorage, SignatureMigrationConfig, SignatureMigrationApprovalConfig, ApprovalConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IDiamondCut} from \"./base/interfaces/IDiamondCut.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {ISignatureMigrationFacet} from \"./interfaces/ISignatureMigrationFacet.sol\";\n\n/**\n * @title Signature Migration Facet\n * @dev Responsible for migrating user signature scheme to a new scheme user sets\n * Which could include\n * - ECDSA on Secp256K1 Curve\n * - ECDSA on Secp256R1 Curve\n * - BLS, Schnorr, etc\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract SignatureMigrationFacet is ISignatureMigrationFacet, Modifiers {\n /**\n * @notice This modifier verifies if the public key format matches with the new verification facet\n * @param _publicKey Bytes of public key to be validated for the new verification facet\n * @param _newVerificationFacet Address of new verification facet\n */\n modifier validateKeyType(\n bytes memory _publicKey,\n address _newVerificationFacet\n ) {\n if (\n !IVerificationFacet(_newVerificationFacet).isValidKeyType(\n _publicKey\n )\n ) revert SignatureMigrationFacet__InvalidKeyType();\n _;\n }\n\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n // IMPORTANT NOTE: In the client side when they call this function, the func selectors should be sorted in ascending order\n // to prevent different hash with same items in the array\n /**\n * @notice Moves the state of migration to a pending state. When pending state is over after pending period time,\n * Migration can be finalized. This function can only be called by self and when the account is unlocked.\n * @dev This method checks if the caller is self and if guardians exists. It migrates signature request to a pending state\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function migrateSignatureScheme(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n public\n override\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n // Only self contract can call this function\n LibDiamond.enforceIsSelf();\n // Should revert if guardian exist\n if (0 != LibGuardian.guardianCount())\n revert SignatureMigrationFacet__InvalidRouteWithGuardian();\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n // NOTE: Migration requires a pending period & confirmation from owner to prevent a\n // single call changing the ownership of the wallet\n /**\n * @notice Migrate signature scheme when guardians exists. Verifies the signature of guardians and moves migration to pending state.\n * Which can then be finalized when pending period is over. Owner's approval is mandatory for migration to happen\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _approvers List of approvers. This could include owner\n */\n function migrateSignatureSchemeWithGuardian(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n )\n public\n override\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n // Should revert if does not guardian exist\n if (0 == LibGuardian.guardianCount())\n revert SignatureMigrationFacet__InvalidRouteWithGuardian();\n uint256 approversLength = _approvers.length;\n if (approversLength != _signatures.length)\n revert SignatureMigrationFacet__InvalidArrayLength();\n\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(migrationPublicKeyHash, _approvers);\n\n bool onChainOwnerApproval = getMigrationOwnerApprovalWithTimeValidity(\n migrationPublicKeyHash\n );\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n\n if (\n approversLength +\n getMigrationApprovalCountWithTimeValidity(\n migrationPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert SignatureMigrationFacet__InsufficientApprovers();\n {\n // To prevent Stack too deep\n bool ownerApproved;\n for (uint256 i; i < approversLength; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n address(this) != _approvers[i]\n ) revert SignatureMigrationFacet__InvalidGuardian();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert SignatureMigrationFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n migrationPublicKeyHash,\n _signatures[i]\n )\n ) revert SignatureMigrationFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n\n if (!ownerApproved && !onChainOwnerApproval)\n revert SignatureMigrationFacet__LackOfOwnerApproval();\n }\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Internal function that moves signature mgiration to a pending state.\n * @dev This method increments migration nonce and sets the migration in the migration config. Emits events for migration execution\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _migrateSignatureScheme(\n address _newVerificationFacet,\n bytes memory _newPublicKey,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal {\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n\n ++ms.nonce;\n uint64 migrateAfter = uint64(block.timestamp + getMigrationPeriod());\n\n ms.migrationConfigs[INNER_STRUCT] = SignatureMigrationConfig(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n migrateAfter\n );\n\n emit SignatureMigrationExecuted(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors,\n migrateAfter\n );\n }\n\n /**\n * @notice Approves signature scheme migration on-chain. This can be called by owner or guardian only when the account is unlocked.\n * When the threshold of the migration approval passed and owner approval is granted, it automatically moves migration to a pending state\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function approveSignatureSchemeMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n public\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit SignatureMigrationApproved(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n msg.sender,\n approvalValidUntil\n );\n if (\n getMigrationApprovalCountWithTimeValidity(migrationPublicKeyHash) >=\n LibGuardian.majorityOfGuardians() &&\n getMigrationOwnerApprovalWithTimeValidity(migrationPublicKeyHash)\n )\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Revokes the approval of signature migration done on-chain. Emits revoke event when revoked.\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function revokeSignatureMigrationApproval(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n external\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n if (!isMigrationApproved(migrationPublicKeyHash, msg.sender))\n revert SignatureMigrationFacet__CannotRevokeUnapproved();\n\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(false, 0);\n emit SignatureMigrationApprovalRevoked(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n msg.sender\n );\n }\n\n /**\n * @notice Finalizes the pending signature scheme migration. This function can only be called by owner.\n * It removes the facets of the previous verification facet and adds the new verification facet.\n * After finalizing migration, it emits migration event which shows the change of the verification facet\n */\n function finalizeSignatureMigration() external override {\n // NOTE: Only owner can call this function\n LibDiamond.enforceIsSelf();\n\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n\n if (!isMigrationPending())\n revert SignatureMigrationFacet__NonexistentMigration();\n\n if (\n uint64(block.timestamp) <=\n ms.migrationConfigs[INNER_STRUCT].migrateAfter\n ) revert SignatureMigrationFacet__MigrationPeriodNotOver();\n address newVerificationFacet = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationVerificationFacet;\n bytes4[] memory newVerificationFuncSelectors = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationSelectors;\n bytes memory newPublicKey = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationPublicKey;\n\n address prevVerificationFacet = LibLoupe.facetAddress(\n s.validateOwnerSignatureSelector\n );\n if (prevVerificationFacet == address(0))\n revert SignatureMigrationFacet__NonExistentVerificationFacet();\n\n IDiamondCut.FacetCut[] memory UninitCut;\n IDiamondCut.FacetCut[] memory InitCut;\n {\n bytes4[] memory prevVerificationFuncSelectors = LibLoupe\n .facetFunctionSelectors(prevVerificationFacet);\n\n UninitCut = new IDiamondCut.FacetCut[](1);\n InitCut = new IDiamondCut.FacetCut[](1);\n UninitCut[0] = IDiamondCut.FacetCut({\n facetAddress: address(0),\n action: IDiamondCut.FacetCutAction.Remove,\n functionSelectors: prevVerificationFuncSelectors\n });\n InitCut[0] = IDiamondCut.FacetCut({\n facetAddress: newVerificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: newVerificationFuncSelectors\n });\n {\n IDiamondCut.FacetCut[]\n memory facetCuts = new IDiamondCut.FacetCut[](2);\n facetCuts[0] = UninitCut[0];\n facetCuts[1] = InitCut[0];\n _checkFacetCutValidity(facetCuts);\n }\n LibAppStorage.initiateSignerMigration();\n address verificationFacet = address(\n bytes20(\n LibDiamond.diamondStorage().facets[\n s.validateOwnerSignatureSelector\n ]\n )\n );\n bytes memory uninitCall = abi.encodeWithSignature(\n \"uninitializeSigner()\"\n );\n (bool success, bytes memory result) = verificationFacet\n .delegatecall(uninitCall);\n require(success, \"MigrationFacet: uninitialize not successful\");\n uint256 validationData = uint256(bytes32(result));\n if (validationData == 0)\n revert SignatureMigrationFacet__SignerUninitializationFailure();\n\n LibDiamond.diamondCut(UninitCut, address(0), \"\");\n }\n {\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n newPublicKey\n );\n\n // Every Verification Facet should comply with initializeSigner(bytes)\n // to be compatible with the Barz contract(for initialization)\n LibDiamond.diamondCut(InitCut, newVerificationFacet, initCall);\n LibAppStorage.finalizeSignerMigration();\n emit SignatureSchemeMigration(\n prevVerificationFacet,\n newVerificationFacet,\n newPublicKey,\n newVerificationFuncSelectors\n );\n }\n }\n\n /**\n * @notice Approve cancellation of signature migration. If cancellation approval passes guardian threshold with owner approval\n * it automatically cancels the migration.\n * @dev This method checks if the caller is one of guardian or owner and sets true for the cancellation hash in the approval config.\n * It internally calls _cancelSignatureMigration for canceling the migration\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function approveCancelSignatureMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n external\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"CancelSignatureMigration\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit SignatureMigrationCancellationApproved(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n if (\n getMigrationApprovalCountWithTimeValidity(migrationPublicKeyHash) >=\n LibGuardian.majorityOfGuardians() &&\n getMigrationOwnerApprovalWithTimeValidity(migrationPublicKeyHash)\n )\n _cancelSignatureMigration(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Verifies the signature of guardians/owner and cancels the signature migration.\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _approvers List of approvers. This could include owner\n */\n function cancelSignatureMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n )\n external\n override\n validateKeyType(_newPublicKey, _newVerificationFacet)\n onlyWhenUnlocked\n {\n uint256 approversLength = _approvers.length;\n if (approversLength != _signatures.length)\n revert SignatureMigrationFacet__InvalidArrayLength();\n\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"CancelSignatureMigration\"\n );\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(migrationPublicKeyHash, _approvers);\n\n bool onChainOwnerApproval = getMigrationOwnerApprovalWithTimeValidity(\n migrationPublicKeyHash\n );\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n if (\n approversLength +\n getMigrationApprovalCountWithTimeValidity(\n migrationPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert SignatureMigrationFacet__InsufficientApprovers();\n {\n // To prevent stack too deep\n bool ownerApproved;\n for (uint256 i; i < approversLength; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n address(this) != _approvers[i]\n ) revert SignatureMigrationFacet__NonExistentApprover();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert SignatureMigrationFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n migrationPublicKeyHash,\n _signatures[i]\n )\n ) revert SignatureMigrationFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n if (!ownerApproved && !onChainOwnerApproval)\n revert SignatureMigrationFacet__LackOfOwnerApproval();\n }\n _cancelSignatureMigration(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Internal function that cancels signature migration.\n * @dev This method increments migration nonce and deletes the migration from the migration config. Emits events for migration cancellation\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _cancelSignatureMigration(\n address _newVerificationFacet,\n bytes memory _newPublicKey,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal {\n if (!isMigrationPending())\n revert SignatureMigrationFacet__NonexistentMigration();\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n ++ms.nonce;\n delete ms.migrationConfigs[INNER_STRUCT];\n emit SignatureMigrationCanceled(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Checks if the facets to be added from new verification facet is registered to facet registry\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _checkMigrationCutValidity(\n address _newVerificationFacet,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal view {\n IDiamondCut.FacetCut[] memory facetCuts = new IDiamondCut.FacetCut[](1);\n facetCuts[0] = IDiamondCut.FacetCut({\n facetAddress: _newVerificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: _newVerificationFuncSelectors\n });\n _checkFacetCutValidity(facetCuts);\n }\n\n /**\n * @notice Returns if the migration is pending of not\n * @dev This method fetches the migration storage and checks if the migrate after is above 0 value\n * @return isPending Bool value that shows if the migration is pending\n */\n function isMigrationPending()\n public\n view\n override\n returns (bool isPending)\n {\n SignatureMigrationStorage storage rs = LibFacetStorage\n .migrationStorage();\n isPending = rs.migrationConfigs[INNER_STRUCT].migrateAfter > 0;\n }\n\n /**\n * @notice Returns the migration hash. This function ensures that this hash is safe from replay attack by including\n * public key, verification facet, function selectors, salt, address, chainId, and nonce.\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _saltString Salt value for generating the migration hash\n * @return migrationKeyHash Bytes32 string of the migration key hash\n */\n function getApprovalMigrationKeyHash(\n bytes memory _newPublicKey,\n address _newVerificationFacet,\n bytes4[] memory _newVerificationFuncSelectors,\n string memory _saltString\n ) public view override returns (bytes32 migrationKeyHash) {\n migrationKeyHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n _newPublicKey,\n _newVerificationFacet,\n keccak256(abi.encode(_newVerificationFuncSelectors)),\n _saltString,\n address(this),\n block.chainid,\n LibFacetStorage.migrationStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Checks if the owner approved the hash for migration\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @return isApprovedByOwner Bool value of showing if the owner approved it or not\n */\n function getMigrationOwnerApprovalWithTimeValidity(\n bytes32 _migrationPublicKeyHash\n ) public view override returns (bool isApprovedByOwner) {\n isApprovedByOwner = isMigrationApproved(\n _migrationPublicKeyHash,\n address(this)\n );\n }\n\n /**\n * @notice Checks how many of the guardians approved the migration hash\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @return approvalCount Number of approvals\n */\n function getMigrationApprovalCountWithTimeValidity(\n bytes32 _migrationPublicKeyHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardiansLength = guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n if (isMigrationApproved(_migrationPublicKeyHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n return approvalCount;\n }\n\n /**\n * @notice Checks if the migration is approved by the given approver\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @param _approver Address of approver\n * @return isApproved Bool value if migration hash is approved\n */\n function isMigrationApproved(\n bytes32 _migrationPublicKeyHash,\n address _approver\n ) public view override returns (bool isApproved) {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n isApproved = (ms\n .isMigrationApproved[_migrationPublicKeyHash][_approver].isApproved &&\n block.timestamp <\n ms\n .isMigrationApproved[_migrationPublicKeyHash][_approver]\n .validUntil);\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _migrationPublicKeyHash Hash of migration information\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _migrationPublicKeyHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isMigrationApproved(_migrationPublicKeyHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert SignatureMigrationFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the migration period of this wallet\n * @dev This method fetches the migration period from the security manager\n * @return migrationPeriod Migration period of Barz contract fetched from security manager\n */\n function getMigrationPeriod()\n internal\n view\n returns (uint128 migrationPeriod)\n {\n migrationPeriod = securityManager.migrationPeriodOf(address(this));\n if (migrationPeriod == 0)\n revert SignatureMigrationFacet__InvalidMigrationPeriod();\n }\n\n /**\n * @notice Returns the validation period of this wallet\n * @dev This method fetches the validation period from the security manager\n * @return approvalValidationPeriod Validation period of Barz contract fetched from security manager\n */\n function getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod == 0)\n revert SignatureMigrationFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the migration nonce of this wallet\n * @dev This method fetches the nonce from migration storage\n * @return migrationNonce Nonce of migration to protect from reply attacks\n */\n function getMigrationNonce()\n public\n view\n override\n returns (uint128 migrationNonce)\n {\n migrationNonce = LibFacetStorage.migrationStorage().nonce;\n }\n\n /**\n * @notice Returns the migration configuration of this wallet\n * @dev This method fetches the migration config from the migration storage\n * @return pendingMigrationConfig Migration config currently pending for signature migration\n */\n function getPendingMigration()\n external\n view\n override\n returns (SignatureMigrationConfig memory pendingMigrationConfig)\n {\n pendingMigrationConfig = LibFacetStorage\n .migrationStorage()\n .migrationConfigs[INNER_STRUCT];\n }\n}\n" + }, + "contracts/facets/TokenReceiverFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {IERC1155Receiver} from \"../interfaces/ERC/IERC1155Receiver.sol\";\nimport {IERC677Receiver} from \"../interfaces/ERC/IERC677Receiver.sol\";\n\n/**\n * @title TokenReceiver Facet\n * @dev Contract that enables receiving ERC721/ERC1155/ERC777/ERC677 Tokens with safe transfer\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract TokenReceiverFacet is\n IERC721Receiver,\n IERC1155Receiver,\n IERC777Recipient,\n IERC677Receiver\n{\n /**\n * @notice Handles ERC721 Token callback.\n * return Standardized onERC721Received return value.\n */\n function onERC721Received(\n address,\n address,\n uint256,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC721Receiver.onERC721Received.selector;\n }\n\n /**\n * @notice Handles ERC1155 Token callback.\n * return Standardized onERC1155Received return value.\n */\n function onERC1155Received(\n address,\n address,\n uint256,\n uint256,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC1155Receiver.onERC1155Received.selector;\n }\n\n /**\n * @notice Handles ERC1155 Token batch callback.\n * return Standardized onERC1155BatchReceived return value.\n */\n function onERC1155BatchReceived(\n address,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC1155Receiver.onERC1155BatchReceived.selector;\n }\n\n /**\n * @notice Handles ERC777 Token callback.\n * Does not return value, empty implementation.\n */\n function tokensReceived(\n address,\n address,\n address,\n uint256,\n bytes calldata,\n bytes calldata\n ) external pure override {}\n\n /**\n * @notice Handles ERC677 Token callback.\n * return true.\n */\n function onTokenTransfer(\n address,\n uint256,\n bytes calldata\n ) external pure override returns (bool) {\n return true;\n }\n}\n" + }, + "contracts/facets/verification/MultiSigFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {UserOperation} from \"../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../../libraries/LibLoupe.sol\";\nimport {LibAppStorage} from \"../../libraries/LibAppStorage.sol\";\nimport {LibMultiSigStorage, MultiSigStorage} from \"../../libraries/LibMultiSigStorage.sol\";\nimport {IERC1271} from \"../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../interfaces/IVerificationFacet.sol\";\nimport {IMultiSigFacet} from \"../interfaces/IMultiSigFacet.sol\";\n\n/**\n * @title Multi-sig facet\n * @dev Multi-signature Facet with custom threshold.\n * Wallet that adds this facet becomes a multi-sig wallet.\n * Reference signature_format.md documentation for Multi-sig facet details\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract MultiSigFacet is IMultiSigFacet, IVerificationFacet, IERC1271 {\n using ECDSA for bytes32;\n\n address public immutable self;\n\n address internal constant SENTINEL_OWNERS = address(0x1);\n uint256 internal constant ADDRESS = 20;\n uint256 internal constant SIG_TYPE = 1;\n uint256 internal constant SIG_LEN = 4;\n uint256 internal constant THRESHOLD = 4;\n uint256 internal constant INVALID_SIG = 1;\n uint256 internal constant VALID_SIG = 0;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in Multisig Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the right format and initializes signer storage in k1 storage.\n * @param _owners Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _owners\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n\n if (!isValidKeyType(_owners)) revert MultiSigFacet__InvalidInitData();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n uint256 threshold = uint256(uint32(bytes4(_owners)));\n uint256 ownerCount = (_owners.length - THRESHOLD) / ADDRESS;\n\n if (threshold == 0) revert MultiSigFacet__InvalidThreshold();\n if (ownerCount == 0) revert MultisigFacet__InvalidOwnerCount();\n\n address currentOwner = SENTINEL_OWNERS;\n uint256 ptr = THRESHOLD;\n address owner_;\n for (uint256 i; i < ownerCount; ) {\n owner_ = address(bytes20(_owners[ptr:ptr + ADDRESS]));\n ptr += ADDRESS;\n if (\n owner_ == address(0) ||\n owner_ == SENTINEL_OWNERS ||\n owner_ == address(this) ||\n owner_ == currentOwner\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[owner_] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n\n ms.owners[currentOwner] = owner_;\n currentOwner = owner_;\n\n unchecked {\n ++i;\n }\n }\n ms.owners[currentOwner] = SENTINEL_OWNERS;\n ms.ownerCount = ownerCount;\n ms.threshold = threshold;\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_owners);\n }\n\n /**\n * @notice Uninitialize signer in K1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n ++ms.counter;\n address[] memory ownerlist = getOwners();\n uint256 ownerlistLength = ownerlist.length;\n for (uint256 i; i < ownerlistLength; ) {\n ms.owners[ownerlist[i]] = address(0);\n unchecked {\n ++i;\n }\n }\n ms.owners[SENTINEL_OWNERS] = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls checkSignatures with\n * user operation hash and signature together with the threshold.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n // Data 1 is invalid, Data 0 is valid\n validationData = checkSignatures(\n userOpHash,\n userOp.signature,\n LibMultiSigStorage.multisigStorage().threshold\n );\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n return this.validateOwnerSignature.selector;\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n uint totalLength = ms.ownerCount * ADDRESS;\n bytes memory result = new bytes(totalLength);\n\n // populate return array\n uint256 index;\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n while (currentOwner != SENTINEL_OWNERS) {\n assembly {\n mstore(\n add(result, add(32, mul(index, ADDRESS))),\n shl(96, currentOwner)\n )\n }\n currentOwner = ms.owners[currentOwner];\n index++;\n }\n\n return result;\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key should comply with the format in the signature_format.md doc\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n uint256 publicKeyLength = _publicKey.length;\n if (\n publicKeyLength < ADDRESS + THRESHOLD ||\n (publicKeyLength - THRESHOLD) % ADDRESS != 0\n ) return false;\n\n uint256 threshold = uint256(uint32(bytes4(_publicKey)));\n uint256 ownerCount = (publicKeyLength - THRESHOLD) / ADDRESS;\n\n isValid = !(ownerCount < threshold || threshold == 0);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes calldata _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (checkSignatures(\n _hash,\n _signature,\n LibMultiSigStorage.multisigStorage().threshold\n ) == VALID_SIG)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n\n /**\n * @notice Validates the format of the signature and verifies if the signature is signed by the expected key.\n * Reference signature_format.md doc for details about signature format and signature types\n * @param _dataHash Bytes value of data hash signed by the owners\n * @param _signatures Bytes value of signature which should comply with signature format\n * @param _threshold Uint256 value of current Multi-sig Barz's threshold\n */\n function checkSignatures(\n bytes32 _dataHash,\n bytes calldata _signatures,\n uint256 _threshold\n ) public view returns (uint256) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n address lastOwner = address(0);\n address currentOwner;\n bytes memory signature;\n uint256 signatureType;\n uint256 nextOffset;\n uint256 i;\n for (i; i < _threshold; ) {\n (\n currentOwner,\n signature,\n signatureType,\n nextOffset\n ) = splitSignatures(_signatures, nextOffset);\n if (nextOffset == 0 && i + 1 < _threshold) return INVALID_SIG;\n if (signatureType == 1) {\n // If signatureType is 1 then it is default dataHash signed.\n // This also includes the contract signature\n if (\n !SignatureChecker.isValidSignatureNow(\n currentOwner,\n _dataHash,\n signature\n )\n ) return INVALID_SIG;\n } else if (signatureType == 2) {\n // If signatureType is 2 then it is an approved hash\n if (ms.approvedHashes[ms.counter][currentOwner][_dataHash] == 0)\n return INVALID_SIG;\n } else if (signatureType == 3) {\n // If signatureType is 3 then it is a signed message hash\n // This also includes the contract signature\n bytes32 msgHash = _dataHash.toEthSignedMessageHash();\n if (\n !SignatureChecker.isValidSignatureNow(\n currentOwner,\n msgHash,\n signature\n )\n ) return INVALID_SIG;\n } else revert MultiSigFacet__InvalidRoute();\n if (\n currentOwner <= lastOwner ||\n ms.owners[currentOwner] == address(0) ||\n currentOwner == SENTINEL_OWNERS\n ) return INVALID_SIG;\n lastOwner = currentOwner;\n\n unchecked {\n ++i;\n }\n }\n return VALID_SIG;\n }\n\n /**\n * @notice Split signatures into each individual signatures. Should comply with signature format to be split\n * @param _signatures Bytes value of signature\n * @param _nextOffset Uint256 value of next offset to start splitting the signature\n */\n function splitSignatures(\n bytes calldata _signatures,\n uint256 _nextOffset\n )\n public\n pure\n returns (\n address owner_,\n bytes memory signature,\n uint256 signatureType,\n uint256 nextOffset\n )\n {\n uint256 signaturesLength = _signatures.length;\n\n if (signaturesLength <= _nextOffset + ADDRESS + SIG_LEN)\n revert MultiSigFacet__InsufficientSignerLength();\n\n owner_ = address(\n bytes20(_signatures[_nextOffset:_nextOffset + ADDRESS])\n );\n\n signatureType = uint256(\n uint8(\n bytes1(\n _signatures[_nextOffset + ADDRESS:_nextOffset +\n ADDRESS +\n SIG_TYPE]\n )\n )\n );\n\n if (signatureType > 3 || signatureType == 0)\n revert MultiSigFacet__InvalidSignatureType();\n uint256 offSet = _nextOffset + ADDRESS + SIG_TYPE;\n uint256 siglen = uint256(\n uint32(bytes4(_signatures[offSet:offSet + SIG_LEN]))\n );\n if (offSet + siglen > signaturesLength)\n revert MultiSigFacet__InvalidSignatureLength();\n\n offSet += SIG_LEN;\n if (offSet + siglen == signaturesLength) nextOffset = 0;\n else nextOffset = offSet + siglen;\n\n signature = _signatures[offSet:offSet + siglen];\n }\n\n /**\n * @notice Approves the hash of userOperation on-chain. This can only be called by owners.\n * @param _hashToApprove Bytes value of UserOperation hash to approve\n */\n function approveHash(bytes32 _hashToApprove) external {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (ms.owners[msg.sender] == address(0))\n revert MultiSigFacet__OnlyOwner();\n\n ms.approvedHashes[ms.counter][msg.sender][_hashToApprove] = 1;\n emit HashApproved(_hashToApprove, msg.sender);\n }\n\n /**\n * @notice Add owner to Barz. Update thresold if threshold is given different from current threshold\n * @dev This can only be done via a Self call.\n * @param _newOwner Address of new owner to be added\n * @param _threshold Uint256 value of threshold\n */\n function addOwner(address _newOwner, uint256 _threshold) external {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (\n _newOwner == address(0) ||\n _newOwner == SENTINEL_OWNERS ||\n _newOwner == address(this)\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_newOwner] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n\n ms.owners[_newOwner] = ms.owners[SENTINEL_OWNERS];\n ms.owners[SENTINEL_OWNERS] = _newOwner;\n ++ms.ownerCount;\n emit OwnerAdded(_newOwner);\n\n if (ms.threshold != _threshold) changeThreshold(_threshold);\n }\n\n /**\n * @notice Remove owner from Barz. Update thresold if threshold is given different from current threshold\n * @dev This can only be done via a Self call.\n * @param _prevOwner Address of owner located right behind the removed owner address in the linked list\n * @param _removedOwner Address of owner to be removed\n * @param _threshold Uint256 value of threshold\n */\n function removeOwner(\n address _prevOwner,\n address _removedOwner,\n uint256 _threshold\n ) external {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (ms.ownerCount - 1 < _threshold)\n revert MultiSigFacet__InvalidThreshold();\n if (_removedOwner == address(0) || _removedOwner == SENTINEL_OWNERS)\n revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_prevOwner] != _removedOwner)\n revert MultiSigFacet__InvalidOwnerPair();\n\n ms.owners[_prevOwner] = ms.owners[_removedOwner];\n ms.owners[_removedOwner] = address(0);\n --ms.ownerCount;\n emit OwnerRemoved(_removedOwner);\n\n if (ms.threshold != _threshold) changeThreshold(_threshold);\n }\n\n /**\n * @notice Swap owner in Barz.\n * @dev This can only be done via a Self call.\n * @param _prevOwner Address of owner located right behind the removed owner address in the linked list\n * @param _oldOwner Address of owner to be removed\n * @param _newOwner Address of owner to be added\n */\n function swapOwner(\n address _prevOwner,\n address _oldOwner,\n address _newOwner\n ) public {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (\n _newOwner == address(0) ||\n _newOwner == SENTINEL_OWNERS ||\n _newOwner == address(this)\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_newOwner] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n if (_oldOwner == address(0) || _oldOwner == SENTINEL_OWNERS)\n revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_prevOwner] != _oldOwner)\n revert MultiSigFacet__InvalidOwnerPair();\n\n ms.owners[_newOwner] = ms.owners[_oldOwner];\n ms.owners[_prevOwner] = _newOwner;\n ms.owners[_oldOwner] = address(0);\n emit OwnerRemoved(_oldOwner);\n emit OwnerAdded(_newOwner);\n }\n\n /**\n * @notice Changes the threshold of the Barz to `_threshold`.\n * @dev This can only be done via a Self call.\n * @param _threshold New threshold\n */\n function changeThreshold(uint256 _threshold) public {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (_threshold > ms.ownerCount || _threshold == 0)\n revert MultiSigFacet__InvalidThreshold();\n\n ms.threshold = _threshold;\n emit ThresholdChanged(_threshold);\n }\n\n /**\n * @notice Checks if the given address is owner\n * @param _owner Address to be checked if it's owner\n * @return isOwner_ Bool value showing if it's owner address\n */\n function isOwner(address _owner) public view returns (bool isOwner_) {\n isOwner_ = (_owner != SENTINEL_OWNERS &&\n LibMultiSigStorage.multisigStorage().owners[_owner] != address(0));\n }\n\n /**\n * @notice Returns the threshold of Barz\n * @return threshold Threshold of the Barz account\n */\n function getThreshold() public view returns (uint256 threshold) {\n threshold = LibMultiSigStorage.multisigStorage().threshold;\n }\n\n /**\n * @notice Returns the list of owner addresses\n * @return owners List of owners\n */\n function getOwners() public view returns (address[] memory owners) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n owners = new address[](ms.ownerCount);\n\n uint256 index;\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n while (currentOwner != SENTINEL_OWNERS) {\n owners[index] = currentOwner;\n currentOwner = ms.owners[currentOwner];\n index++;\n }\n }\n\n /**\n * @notice Returns the previous owner in the linked list\n * @param _owner Address of owner\n * @return prevOwner Address of previous owner\n */\n function getPrevOwner(\n address _owner\n ) public view returns (address prevOwner) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n if (currentOwner == _owner) return SENTINEL_OWNERS;\n while (currentOwner != SENTINEL_OWNERS) {\n if (ms.owners[currentOwner] == _owner) return currentOwner;\n\n currentOwner = ms.owners[currentOwner];\n }\n return address(0);\n }\n\n /**\n * @notice Returns of the owner is approved by given owner address\n * @param _owner Address of owner\n * @param _hash Hash of UserOperation\n * @return isApproved Bool value showing if the hash is approved by owner\n */\n function isApprovedHash(\n address _owner,\n bytes32 _hash\n ) public view returns (bool isApproved) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n isApproved = (ms.approvedHashes[ms.counter][_owner][_hash] == 1);\n }\n}\n" + }, + "contracts/facets/verification/secp256k1/Secp256k1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {UserOperation} from \"../../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibAppStorage} from \"../../../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, Secp256k1VerificationStorage} from \"../../../libraries/LibFacetStorage.sol\";\nimport {LibLoupe} from \"../../../libraries/LibLoupe.sol\";\nimport {IERC1271} from \"../../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../../interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Secp256k1 verification facet\n * @dev Default Ethereum's elliptic curve\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract Secp256k1VerificationFacet is IVerificationFacet, IERC1271 {\n using ECDSA for bytes32;\n error Secp256k1VerificationFacet__InvalidSignerLength();\n address public immutable self;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in K1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\n * @param _publicKey Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _publicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n if (!isValidKeyType(_publicKey))\n revert Secp256k1VerificationFacet__InvalidSignerLength();\n\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(uint160(uint256(keccak256(_publicKey[1:]))));\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_publicKey);\n }\n\n /**\n * @notice Uninitialize signer in K1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\n * signer public key.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n validationData = validateSignature(\n userOp,\n userOpHash,\n k1Storage.signer\n );\n }\n\n /**\n * @notice Validates if the signature of UserOperation is signed by the given signer\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @param signer Address of signer who signed the contract, to be validated\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n address signer\n ) public pure returns (uint256 isValid) {\n bytes32 hash = userOpHash.toEthSignedMessageHash();\n isValid = (signer != hash.recover(userOp.signature)) ? 1 : 0;\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n ownerSignatureValidatorSelector = this.validateOwnerSignature.selector;\n // NOTE: The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory signer) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n signer = abi.encodePacked(k1Storage.signer);\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key length should be 65 in an uncompressed public key format\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (_hash.recover(_signature) ==\n LibFacetStorage.k1Storage().signer)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/Secp256r1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {UserOperation} from \"../../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibAppStorage} from \"../../../libraries/LibAppStorage.sol\";\nimport {LibLoupe} from \"../../../libraries/LibLoupe.sol\";\nimport {LibFacetStorage, Secp256r1VerificationStorage} from \"../../../libraries/LibFacetStorage.sol\";\nimport {Base64} from \"./utils/Base64.sol\";\nimport {LibSecp256r1} from \"./utils/LibSecp256r1.sol\";\nimport {IERC1271} from \"../../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../../interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Secp256r1 verification facet\n * @dev Primarily used to verify user ops signed with passkeys\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract Secp256r1VerificationFacet is IVerificationFacet, IERC1271 {\n error Secp256r1VerificationFacet__InvalidSignerLength();\n address public immutable self;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in R1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\n * @param _publicKey Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _publicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n\n if (!isValidKeyType(_publicKey))\n revert Secp256r1VerificationFacet__InvalidSignerLength();\n\n bytes memory publicKeyCoordinates = _publicKey[1:];\n uint256[2] memory q;\n assembly {\n // Copy the bytes from the input data into the uint256 array\n mstore(q, mload(add(publicKeyCoordinates, 32)))\n mstore(add(q, 32), mload(add(publicKeyCoordinates, 64)))\n }\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n r1Storage.q = q;\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_publicKey);\n }\n\n /**\n * @notice Uninitialize signer in R1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n r1Storage.q = [0, 0];\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\n * signer public key.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n validationData = validateSignature(userOp, userOpHash, r1Storage.q);\n }\n\n /**\n * @notice Validates if the signature of UserOperation is signed by the given signer\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @param q Public Key of signer who signed the contract, to be validated\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256[2] memory q\n ) public view returns (uint256 isValid) {\n isValid = (_validateSignature(q, userOpHash, userOp.signature)) ? 0 : 1;\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n return this.validateOwnerSignature.selector; // validateOwnerSignature(UserOperation calldata userOp,bytes32 userOpHash)\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory signer) {\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n signer = abi.encodePacked(r1Storage.q);\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key should in an uncompressed public key format\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = _validateSignature(\n LibFacetStorage.r1Storage().q,\n _hash,\n _signature\n )\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n\n function _validateSignature(\n uint256[2] memory q,\n bytes32 _hash,\n bytes memory _signature\n ) internal view returns (bool) {\n (\n uint256 rValue,\n uint256 sValue,\n bytes memory authenticatorData,\n string memory clientDataJSONPre,\n string memory clientDataJSONPost\n ) = abi.decode(_signature, (uint256, uint256, bytes, string, string));\n bytes32 clientHash;\n {\n string memory opHashBase64 = Base64.encode(bytes.concat(_hash));\n string memory clientDataJSON = string.concat(\n clientDataJSONPre,\n opHashBase64,\n clientDataJSONPost\n );\n clientHash = sha256(bytes(clientDataJSON));\n }\n bytes32 sigHash = sha256(bytes.concat(authenticatorData, clientHash));\n return LibSecp256r1.Verify(q, rValue, sValue, uint256(sigHash));\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/utils/Base64.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @dev Provides a set of functions to operate with Base64 strings.\n * modified for base64url https://datatracker.ietf.org/doc/html/rfc4648#section-5\n * _Available since v4.5._\n */\nlibrary Base64 {\n /**\n * @dev Base64 Encoding/Decoding Table\n */\n string internal constant _TABLE =\n \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_\";\n\n /**\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\n */\n function encode(bytes memory data) internal pure returns (string memory) {\n /**\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\n */\n if (data.length == 0) return \"\";\n\n // Loads the table into memory\n string memory table = _TABLE;\n\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\n // and split into 4 numbers of 6 bits.\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\n // - `data.length + 2` -> Round up\n // - `/ 3` -> Number of 3-bytes chunks\n // - `4 *` -> 4 characters for each chunk\n uint256 newlength = (data.length * 8) / 6;\n if (data.length % 6 > 0) {\n newlength++;\n }\n string memory result = new string(newlength);\n\n /// @solidity memory-safe-assembly\n assembly {\n // Prepare the lookup table (skip the first \"length\" byte)\n let tablePtr := add(table, 1)\n\n // Prepare result pointer, jump over length\n let resultPtr := add(result, 32)\n\n // Run over the input, 3 bytes at a time\n for {\n let dataPtr := data\n let endPtr := add(data, mload(data))\n } lt(dataPtr, endPtr) {\n\n } {\n // Advance 3 bytes\n dataPtr := add(dataPtr, 3)\n let input := mload(dataPtr)\n\n // To write each character, shift the 3 bytes (18 bits) chunk\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\n // and apply logical AND with 0x3F which is the number of\n // the previous character in the ASCII table prior to the Base64 Table\n // The result is then added to the table to get the character to write,\n // and finally write it in the result pointer but with a left shift\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(18, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(12, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(6, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n }\n }\n\n return result;\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/utils/LibSecp256r1.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n// Heavily inspired from\n// https://github.com/maxrobot/elliptic-solidity/blob/master/contracts/Secp256r1.sol\n// https://github.com/tdrerup/elliptic-curve-solidity/blob/master/contracts/curves/EllipticCurve.sol\n// modified to use precompile 0x05 modexp\n// and modified jacobian double\n// optimisations to avoid to an from from affine and jacobian coordinates\n\n// Additional Elliptic curve Public key / Signature validation added by\n// David Yonjun Kim (@Powerstream3604)\n\nstruct JPoint {\n uint256 x;\n uint256 y;\n uint256 z;\n}\n\nlibrary LibSecp256r1 {\n uint256 constant gx =\n 0x6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296;\n uint256 constant gy =\n 0x4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5;\n uint256 public constant pp =\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF;\n\n uint256 public constant nn =\n 0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551;\n uint256 constant a =\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC;\n uint256 constant b =\n 0x5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B;\n uint256 constant MOST_SIGNIFICANT =\n 0xc000000000000000000000000000000000000000000000000000000000000000;\n\n /*\n * Verify\n * @description - verifies that a public key has signed a given message\n * @param Q - public key coordinates X & Y\n * @param R - signature half R\n * @param S - signature half S\n * @param input - hashed message\n */\n function Verify(\n uint256[2] memory q,\n uint r,\n uint s,\n uint e\n ) internal view returns (bool) {\n if (q[0] > pp - 1 || q[1] > pp - 1) {\n return false;\n }\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\n return false;\n }\n if (\n mulmod(q[1], q[1], pp) !=\n addmod(\n addmod(\n mulmod(q[0], mulmod(q[0], q[0], pp), pp),\n mulmod(a, q[0], pp),\n pp\n ),\n b,\n pp\n )\n ) {\n return false;\n }\n\n JPoint[16] memory points = _preComputeJacobianPoints(q);\n return VerifyWithPrecompute(points, r, s, e);\n }\n\n function VerifyWithPrecompute(\n JPoint[16] memory points,\n uint r,\n uint s,\n uint e\n ) internal view returns (bool) {\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\n return false;\n }\n\n uint w = _primemod(s, nn);\n\n uint u1 = mulmod(e, w, nn);\n uint u2 = mulmod(r, w, nn);\n\n uint x;\n uint y;\n\n (x, y) = ShamirMultJacobian(points, u1, u2);\n return (x == r);\n }\n\n /*\n * Strauss Shamir trick for EC multiplication\n * https://stackoverflow.com/questions/50993471/ec-scalar-multiplication-with-strauss-shamir-method\n * we optimise on this a bit to do with 2 bits at a time rather than a single bit\n * the individual points for a single pass are precomputed\n * overall this reduces the number of additions while keeping the same number of doublings\n */\n function ShamirMultJacobian(\n JPoint[16] memory points,\n uint u1,\n uint u2\n ) internal view returns (uint, uint) {\n uint x = 0;\n uint y = 0;\n uint z = 0;\n uint bits = 128;\n uint index = 0;\n\n while (bits > 0) {\n if (z > 0) {\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\n }\n index =\n ((u1 & MOST_SIGNIFICANT) >> 252) |\n ((u2 & MOST_SIGNIFICANT) >> 254);\n if (index > 0) {\n (x, y, z) = _jAdd(\n x,\n y,\n z,\n points[index].x,\n points[index].y,\n points[index].z\n );\n }\n u1 <<= 2;\n u2 <<= 2;\n bits--;\n }\n (x, y) = _affineFromJacobian(x, y, z);\n return (x, y);\n }\n\n function _preComputeJacobianPoints(\n uint256[2] memory q\n ) internal pure returns (JPoint[16] memory points) {\n points[0] = JPoint(0, 0, 0);\n points[1] = JPoint(q[0], q[1], 1); // u2\n points[2] = _jPointDouble(points[1]);\n points[3] = _jPointAdd(points[1], points[2]);\n\n points[4] = JPoint(gx, gy, 1); // u1Points[1]\n points[5] = _jPointAdd(points[4], points[1]);\n points[6] = _jPointAdd(points[4], points[2]);\n points[7] = _jPointAdd(points[4], points[3]);\n\n points[8] = _jPointDouble(points[4]); // u1Points[2]\n points[9] = _jPointAdd(points[8], points[1]);\n points[10] = _jPointAdd(points[8], points[2]);\n points[11] = _jPointAdd(points[8], points[3]);\n\n points[12] = _jPointAdd(points[4], points[8]); // u1Points[3]\n points[13] = _jPointAdd(points[12], points[1]);\n points[14] = _jPointAdd(points[12], points[2]);\n points[15] = _jPointAdd(points[12], points[3]);\n }\n\n function _jPointAdd(\n JPoint memory p1,\n JPoint memory p2\n ) internal pure returns (JPoint memory) {\n uint x;\n uint y;\n uint z;\n (x, y, z) = _jAdd(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z);\n return JPoint(x, y, z);\n }\n\n function _jPointDouble(\n JPoint memory p\n ) internal pure returns (JPoint memory) {\n uint x;\n uint y;\n uint z;\n (x, y, z) = _modifiedJacobianDouble(p.x, p.y, p.z);\n return JPoint(x, y, z);\n }\n\n /* _affineFromJacobian\n * @desription returns affine coordinates from a jacobian input follows\n * golang elliptic/crypto library\n */\n function _affineFromJacobian(\n uint x,\n uint y,\n uint z\n ) internal view returns (uint ax, uint ay) {\n if (z == 0) {\n return (0, 0);\n }\n\n uint zinv = _primemod(z, pp);\n uint zinvsq = mulmod(zinv, zinv, pp);\n\n ax = mulmod(x, zinvsq, pp);\n ay = mulmod(y, mulmod(zinvsq, zinv, pp), pp);\n }\n\n /*\n * _jAdd\n * @description performs Jacobian addition as defined below:\n * http://www.hyperelliptic.org/EFD/g1p/data/shortw/jacobian/addition/add-2007-bl\n */\n function _jAdd(\n uint p1,\n uint p2,\n uint p3,\n uint q1,\n uint q2,\n uint q3\n ) internal pure returns (uint r1, uint r2, uint r3) {\n if (p3 == 0) {\n r1 = q1;\n r2 = q2;\n r3 = q3;\n\n return (r1, r2, r3);\n } else if (q3 == 0) {\n r1 = p1;\n r2 = p2;\n r3 = p3;\n\n return (r1, r2, r3);\n }\n\n assembly {\n let\n pd\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\n let z1z1 := mulmod(p3, p3, pd) // Z1Z1 = Z1^2\n let z2z2 := mulmod(q3, q3, pd) // Z2Z2 = Z2^2\n\n let u1 := mulmod(p1, z2z2, pd) // U1 = X1*Z2Z2\n let u2 := mulmod(q1, z1z1, pd) // U2 = X2*Z1Z1\n\n let s1 := mulmod(p2, mulmod(z2z2, q3, pd), pd) // S1 = Y1*Z2*Z2Z2\n let s2 := mulmod(q2, mulmod(z1z1, p3, pd), pd) // S2 = Y2*Z1*Z1Z1\n\n let p3q3 := addmod(p3, q3, pd)\n\n if lt(u2, u1) {\n u2 := add(pd, u2) // u2 = u2+pd\n }\n let h := sub(u2, u1) // H = U2-U1\n\n let i := mulmod(0x02, h, pd)\n i := mulmod(i, i, pd) // I = (2*H)^2\n\n let j := mulmod(h, i, pd) // J = H*I\n if lt(s2, s1) {\n s2 := add(pd, s2) // u2 = u2+pd\n }\n let rr := mulmod(0x02, sub(s2, s1), pd) // r = 2*(S2-S1)\n r1 := mulmod(rr, rr, pd) // X3 = R^2\n\n let v := mulmod(u1, i, pd) // V = U1*I\n let j2v := addmod(j, mulmod(0x02, v, pd), pd)\n if lt(r1, j2v) {\n r1 := add(pd, r1) // X3 = X3+pd\n }\n r1 := sub(r1, j2v)\n\n // Y3 = r*(V-X3)-2*S1*J\n let s12j := mulmod(mulmod(0x02, s1, pd), j, pd)\n\n if lt(v, r1) {\n v := add(pd, v)\n }\n r2 := mulmod(rr, sub(v, r1), pd)\n\n if lt(r2, s12j) {\n r2 := add(pd, r2)\n }\n r2 := sub(r2, s12j)\n\n // Z3 = ((Z1+Z2)^2-Z1Z1-Z2Z2)*H\n z1z1 := addmod(z1z1, z2z2, pd)\n j2v := mulmod(p3q3, p3q3, pd)\n if lt(j2v, z1z1) {\n j2v := add(pd, j2v)\n }\n r3 := mulmod(sub(j2v, z1z1), h, pd)\n }\n return (r1, r2, r3);\n }\n\n // Point doubling on the modified jacobian coordinates\n // http://point-at-infinity.org/ecc/Prime_Curve_Modified_Jacobian_Coordinates.html\n function _modifiedJacobianDouble(\n uint x,\n uint y,\n uint z\n ) internal pure returns (uint x3, uint y3, uint z3) {\n if (y == 0) return (0, 0, 0);\n assembly {\n let\n pd\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\n let z2 := mulmod(z, z, pd)\n let az4 := mulmod(\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC,\n mulmod(z2, z2, pd),\n pd\n )\n let y2 := mulmod(y, y, pd)\n let s := mulmod(0x04, mulmod(x, y2, pd), pd)\n let u := mulmod(0x08, mulmod(y2, y2, pd), pd)\n let m := addmod(mulmod(0x03, mulmod(x, x, pd), pd), az4, pd)\n let twos := mulmod(0x02, s, pd)\n let m2 := mulmod(m, m, pd)\n if lt(m2, twos) {\n m2 := add(pd, m2)\n }\n x3 := sub(m2, twos)\n if lt(s, x3) {\n s := add(pd, s)\n }\n y3 := mulmod(m, sub(s, x3), pd)\n if lt(y3, u) {\n y3 := add(pd, y3)\n }\n y3 := sub(y3, u)\n z3 := mulmod(0x02, mulmod(y, z, pd), pd)\n }\n }\n\n // Fermats little theorem https://en.wikipedia.org/wiki/Fermat%27s_little_theorem\n // a^(p-1) = 1 mod p\n // a^(-1) ≅ a^(p-2) (mod p)\n // we then use the precompile bigModExp to compute a^(-1)\n function _primemod(uint value, uint p) internal view returns (uint ret) {\n ret = modexp(value, p - 2, p);\n return ret;\n }\n\n // Wrapper for built-in BigNumber_modexp (contract 0x5) as described here. https://github.com/ethereum/EIPs/pull/198\n function modexp(\n uint _base,\n uint _exp,\n uint _mod\n ) internal view returns (uint ret) {\n // bigModExp(_base, _exp, _mod);\n assembly {\n if gt(_base, _mod) {\n _base := mod(_base, _mod)\n }\n // Free memory pointer is always stored at 0x40\n let freemem := mload(0x40)\n\n mstore(freemem, 0x20)\n mstore(add(freemem, 0x20), 0x20)\n mstore(add(freemem, 0x40), 0x20)\n\n mstore(add(freemem, 0x60), _base)\n mstore(add(freemem, 0x80), _exp)\n mstore(add(freemem, 0xa0), _mod)\n\n let success := staticcall(14000, 0x5, freemem, 0xc0, freemem, 0x20)\n switch success\n case 0 {\n revert(0x0, 0x0)\n }\n default {\n ret := mload(freemem)\n }\n }\n }\n}\n" + }, + "contracts/infrastructure/DefaultFallbackHandler.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC1155Receiver} from \"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\";\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {BaseAccount} from \"../aa-4337/core/BaseAccount.sol\";\nimport {DefaultLibDiamond} from \"../libraries/DefaultLibDiamond.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IAccountFacet} from \"../facets/interfaces/IAccountFacet.sol\";\nimport {IStorageLoupe} from \"../facets/base/interfaces/IStorageLoupe.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IERC677Receiver} from \"../interfaces/ERC/IERC677Receiver.sol\";\nimport {IERC165} from \"../interfaces/ERC/IERC165.sol\";\n\n/**\n * @title DefaultFallbackHandler\n * @dev A default fallback handler for Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DefaultFallbackHandler is IDiamondLoupe {\n /**\n * @notice Sets the middleware diamond for Barz wallet as a fallback handler\n * @dev This contract is also a diamond that holds the default facets to reduce gas cost for wallet activation.\n * Within the constructor this conducts diamond cut to initially setup the diamond. This is a non-upgradeable contract\n * @param _diamondCutFacet Address if diamond cut facet\n * @param _accountFacet Address account facet\n * @param _tokenReceiverFacet Address of token receiver facet\n * @param _diamondLoupeFacet Address of diamond loupe facet\n */\n constructor(\n address _diamondCutFacet,\n address _accountFacet,\n address _tokenReceiverFacet,\n address _diamondLoupeFacet\n ) payable {\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](4);\n bytes4[] memory functionSelectors = new bytes4[](1);\n functionSelectors[0] = IDiamondCut.diamondCut.selector;\n\n bytes4[] memory accountFunctionSelectors = new bytes4[](5);\n accountFunctionSelectors[0] = IAccountFacet.execute.selector;\n accountFunctionSelectors[1] = IAccountFacet.executeBatch.selector;\n accountFunctionSelectors[2] = BaseAccount.validateUserOp.selector;\n accountFunctionSelectors[3] = BaseAccount.getNonce.selector;\n accountFunctionSelectors[4] = BaseAccount.entryPoint.selector;\n\n bytes4[] memory receiverFacetSelectors = new bytes4[](5);\n receiverFacetSelectors[0] = IERC721Receiver.onERC721Received.selector;\n receiverFacetSelectors[1] = IERC1155Receiver.onERC1155Received.selector;\n receiverFacetSelectors[2] = IERC1155Receiver\n .onERC1155BatchReceived\n .selector;\n receiverFacetSelectors[3] = IERC777Recipient.tokensReceived.selector;\n receiverFacetSelectors[4] = IERC677Receiver.onTokenTransfer.selector;\n\n bytes4[] memory loupeFacetSelectors = new bytes4[](9);\n loupeFacetSelectors[0] = IDiamondLoupe.facets.selector;\n loupeFacetSelectors[1] = IDiamondLoupe.facetFunctionSelectors.selector;\n loupeFacetSelectors[2] = IDiamondLoupe.facetAddresses.selector;\n loupeFacetSelectors[3] = IDiamondLoupe.facetAddress.selector;\n loupeFacetSelectors[4] = IERC165.supportsInterface.selector;\n loupeFacetSelectors[5] = IStorageLoupe.facetsFromStorage.selector;\n loupeFacetSelectors[6] = IStorageLoupe\n .facetFunctionSelectorsFromStorage\n .selector;\n loupeFacetSelectors[7] = IStorageLoupe\n .facetAddressesFromStorage\n .selector;\n loupeFacetSelectors[8] = IStorageLoupe.facetAddressFromStorage.selector;\n\n {\n cut[0] = IDiamondCut.FacetCut({\n facetAddress: _diamondCutFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: functionSelectors\n });\n cut[1] = IDiamondCut.FacetCut({\n facetAddress: _accountFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: accountFunctionSelectors\n });\n cut[2] = IDiamondCut.FacetCut({\n facetAddress: _tokenReceiverFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: receiverFacetSelectors\n });\n cut[3] = IDiamondCut.FacetCut({\n facetAddress: _diamondLoupeFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: loupeFacetSelectors\n });\n\n DefaultLibDiamond.diamondCut(cut, address(0), \"\");\n }\n }\n\n /**\n * @notice Returns the facet information of call facets registered to this diamond.\n * @return facets_ The facet struct array including all facet information\n */\n function facets() external view override returns (Facet[] memory facets_) {\n DefaultLibDiamond.DiamondStorage storage ds = DefaultLibDiamond\n .diamondStorage();\n uint256 numFacets = ds.facetAddresses.length;\n facets_ = new Facet[](numFacets);\n for (uint256 i; i < numFacets; ) {\n address facetAddress_ = ds.facetAddresses[i];\n facets_[i].facetAddress = facetAddress_;\n facets_[i].functionSelectors = ds\n .facetFunctionSelectors[facetAddress_]\n .functionSelectors;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Gets all the function selectors provided by a facet.\n * @param _facet The facet address.\n * @return facetFunctionSelectors_\n */\n function facetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n facetFunctionSelectors_ = DefaultLibDiamond\n .diamondStorage()\n .facetFunctionSelectors[_facet]\n .functionSelectors;\n }\n\n /**\n * @notice Get all the facet addresses used by a diamond.\n * @return facetAddresses_\n */\n function facetAddresses()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n facetAddresses_ = DefaultLibDiamond.diamondStorage().facetAddresses;\n }\n\n /** @notice Gets the facet that supports the given selector.\n * @dev If facet is not found return address(0).\n * @param _functionSelector The function selector.\n * @return facetAddress_ The facet address.\n */\n function facetAddress(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n facetAddress_ = DefaultLibDiamond\n .diamondStorage()\n .selectorToFacetAndPosition[_functionSelector]\n .facetAddress;\n }\n}\n" + }, + "contracts/infrastructure/FacetRegistry.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport {IFacetRegistry} from \"./interfaces/IFacetRegistry.sol\";\n\n/**\n * @title Facet Registry\n * @dev Contract to keep track of facets & function selectors addable to user wallets\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract FacetRegistry is IFacetRegistry, Ownable2Step {\n mapping(address => FacetRegistryConfig) private facets;\n\n /**\n * @notice Transfers the ownership of the contract to the given owner\n * @param _owner Address of owner who has access to initialize the default security variables for security manager\n */\n constructor(address _owner) {\n transferOwnership(_owner);\n _transferOwnership(_owner);\n }\n\n /**\n * @dev Registers a facet and it's function selectors to registry\n * @param _facet address of facet\n * @param _facetSelectors list of function selectors of the facet\n */\n function registerFacetFunctionSelectors(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external override onlyOwner {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n uint256 facetSelectorsLength = _facetSelectors.length;\n for (uint256 i; i < facetSelectorsLength; ) {\n if (facetConfig.info[_facetSelectors[i]].exists)\n revert FacetRegistry__FacetSelectorAlreadyRegistered();\n\n facetConfig.info[_facetSelectors[i]].exists = true;\n facetConfig.info[_facetSelectors[i]].index = uint128(\n facetConfig.selectors.length\n );\n facetConfig.selectors.push(_facetSelectors[i]);\n unchecked {\n ++i;\n }\n }\n emit FacetFunctionSelectorsRegistered(_facet, _facetSelectors);\n }\n\n /**\n * @dev Removes a registered facet and it's corresponding selectors from registry\n * @param _facet address of facet\n * @param _facetSelectors list of function selectors of the facet\n */\n function removeFacetFunctionSelectors(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external override onlyOwner {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n uint256 facetSelectorsLength = _facetSelectors.length;\n for (uint256 i; i < facetSelectorsLength; ) {\n if (!facetConfig.info[_facetSelectors[i]].exists)\n revert FacetRegistry__UnregisteredFacetSelector();\n\n bytes4 lastSelector = facetConfig.selectors[\n facetConfig.selectors.length - 1\n ];\n if (_facetSelectors[i] != lastSelector) {\n uint128 targetIndex = facetConfig\n .info[_facetSelectors[i]]\n .index;\n facetConfig.selectors[targetIndex] = lastSelector;\n facetConfig.info[lastSelector].index = targetIndex;\n }\n facetConfig.selectors.pop();\n delete facetConfig.info[_facetSelectors[i]];\n\n unchecked {\n ++i;\n }\n }\n emit FacetFunctionSelectorsRemoved(_facet, _facetSelectors);\n }\n\n /**\n * @dev Checks if a facet and it's selectors given is registered to facet registry\n * @param _facet Address of facet\n * @param _facetSelectors List of function selectors of the facet\n */\n function areFacetFunctionSelectorsRegistered(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external view override returns (bool) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n uint256 facetSelectorsLength = _facetSelectors.length;\n if (facetSelectorsLength == 0) return false;\n for (uint256 i; i < facetSelectorsLength; ) {\n if (!facetConfig.info[_facetSelectors[i]].exists) return false;\n unchecked {\n ++i;\n }\n }\n return true;\n }\n\n /**\n * @dev Checks if a facet and it's selector given is registered to facet registry\n * @param _facet Address of facet\n * @param _facetSelector List of function selectors of the facet\n * @return isRegistered Bool value showing if the selector is registered\n */\n function isFacetFunctionSelectorRegistered(\n address _facet,\n bytes4 _facetSelector\n ) external view override returns (bool isRegistered) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n isRegistered = facetConfig.info[_facetSelector].exists;\n }\n\n /**\n * @dev Get the registered selectors of facet from registry\n * @param _facet Address of facet\n * @return selectors Selectors registered to facet\n */\n function getFacetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory selectors) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n selectors = facetConfig.selectors;\n }\n}\n" + }, + "contracts/infrastructure/interfaces/IFacetRegistry.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Registry Interface\n * @dev Interface for Facet Registry contract to keep track of facets & function selectors addable to user wallets\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IFacetRegistry {\n struct FacetRegistryConfig {\n bytes4[] selectors;\n mapping(bytes4 => FacetInfo) info;\n }\n struct FacetInfo {\n bool exists;\n uint128 index;\n }\n\n event FacetFunctionSelectorsRegistered(\n address facet,\n bytes4[] facetSelectors\n );\n event FacetFunctionSelectorsRemoved(address facet, bytes4[] facetSelectors);\n\n error FacetRegistry__FacetSelectorAlreadyRegistered();\n error FacetRegistry__UnregisteredFacetSelector();\n\n function registerFacetFunctionSelectors(\n address facet,\n bytes4[] calldata facetSelectors\n ) external;\n\n function removeFacetFunctionSelectors(\n address facet,\n bytes4[] calldata facetSelectors\n ) external;\n\n function areFacetFunctionSelectorsRegistered(\n address facet,\n bytes4[] calldata facetSelectors\n ) external view returns (bool);\n\n function isFacetFunctionSelectorRegistered(\n address facet,\n bytes4 facetSelector\n ) external view returns (bool);\n\n function getFacetFunctionSelectors(\n address facet\n ) external view returns (bytes4[] memory);\n}\n" + }, + "contracts/infrastructure/interfaces/ISecurityManager.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Registry Interface\n * @dev Infrastructure contract to manage security parameters of users\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface ISecurityManager {\n error SecurityManager__OutOfBoundary();\n error SecurityManager__CallerNotWallet();\n error SecurityManager__AlreadyIntialized();\n\n function initializeAdditionSecurityPeriod(\n uint128 defaultAdditionSecurityPeriod,\n uint128 minAdditionSecurityPeriod,\n uint128 maxAdditionSecurityPeriod\n ) external;\n\n function initializeRemovalSecurityPeriod(\n uint128 defaultRemovalSecurityPeriod,\n uint128 minRemovalSecurityPeriod,\n uint128 maxRemovalSecurityPeriod\n ) external;\n\n function initializeApprovalValidationPeriod(\n uint128 defaultApprovalValidationPeriod,\n uint128 minApprovalValidationPeriod,\n uint128 maxApprovalValidationPeriod\n ) external;\n\n function initializeMigrationPeriod(\n uint128 defaultMigrationPeriod,\n uint128 minMigrationPeriod,\n uint128 maxMigrationPeriod\n ) external;\n\n function initializeLockPeriod(\n uint128 defaultLockPeriod,\n uint128 minLockPeriod,\n uint128 maxLockPeriod\n ) external;\n\n function initializeRecoveryPeriod(\n uint128 defaultRecoveryPeriod,\n uint128 minRecoveryPeriod,\n uint128 maxRecoveryPeriod\n ) external;\n\n function initializeSecurityWindow(\n uint128 defaultSecurityWindow,\n uint128 minSecurityWindow,\n uint128 maxSecurityWindow\n ) external;\n\n function setAdditionSecurityPeriod(\n address wallet,\n uint128 additionSecurityPeriod\n ) external;\n\n function setRemovalSecurityPeriod(\n address wallet,\n uint128 removalSecurityPeriod\n ) external;\n\n function setSecurityWindow(address wallet, uint128 securityWindow) external;\n\n function setRecoveryPeriod(address wallet, uint128 recoveryPeriod) external;\n\n function setLockPeriod(address wallet, uint128 lockPeriod) external;\n\n function setApprovalValidationPeriod(\n address wallet,\n uint128 approvalValidationPeriod\n ) external;\n\n function setMigrationPeriod(\n address wallet,\n uint128 migrationPeriod\n ) external;\n\n function additionSecurityPeriodOf(\n address wallet\n ) external view returns (uint128);\n\n function removalSecurityPeriodOf(\n address wallet\n ) external view returns (uint128);\n\n function securityWindowOf(address wallet) external view returns (uint128);\n\n function recoveryPeriodOf(address wallet) external view returns (uint128);\n\n function lockPeriodOf(address wallet) external view returns (uint128);\n\n function migrationPeriodOf(address wallet) external view returns (uint128);\n\n function approvalValidationPeriodOf(\n address wallet\n ) external view returns (uint128);\n}\n" + }, + "contracts/infrastructure/RemoteStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IGuardianFacet} from \"../facets/interfaces/IGuardianFacet.sol\";\n\n/**\n * @title Remote Storage\n * @dev Remote storage allows you to associate addresses with an array of addresses on a standalone smart contract.\n * This could be useful when you don't want to use the local diamond storage for some purpose.\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\nabstract contract RemoteStorage {\n struct StorageConfig {\n address[] addresses;\n mapping(address => Info) info;\n }\n\n struct Info {\n bool exists;\n uint128 index;\n }\n\n mapping(address => StorageConfig) internal configs;\n\n event Added(address _address);\n event Removed(address _address);\n\n error RemoteStorage__CallerNotOwner();\n error RemoteStorage__CallerNotGuardianOrOwner();\n error RemoteStorage__AlreadyExists();\n error RemoteStorage__NotFound();\n error RemoteStorage__CallerNotGuardian();\n\n bytes4 constant IS_GUARDIAN_SELECTOR =\n bytes4(keccak256(\"isGuardian(address)\"));\n bytes4 constant GUARDIAN_COUNT = bytes4(keccak256(\"guardianCount()\"));\n\n /**\n * @notice Modifier to only allow the self to call. Reverts otherwise\n */\n modifier onlyWallet(address _wallet) {\n if (msg.sender != _wallet) revert RemoteStorage__CallerNotOwner();\n _;\n }\n\n /**\n * @notice Enfore the callet to be wallet of guardian of the wallet\n * @param _wallet Address of wallet\n */\n function enforceGuardianOrWallet(address _wallet) internal view {\n if (msg.sender == _wallet) return;\n address facetAddress = IDiamondLoupe(_wallet).facetAddress(\n IS_GUARDIAN_SELECTOR\n );\n if (facetAddress != address(0))\n if (IGuardianFacet(_wallet).isGuardian(msg.sender)) return;\n revert RemoteStorage__CallerNotGuardianOrOwner();\n }\n\n /**\n * @notice Enforce the caller to be wallet IF guardians doesn't exists and only guardian when guardians exists\n * @param _wallet Target wallet address to be handled by infrastructure contracts\n */\n function enforceWalletOrGuardianIfExists(address _wallet) internal view {\n address facetAddress;\n if (msg.sender == _wallet) {\n facetAddress = IDiamondLoupe(_wallet).facetAddress(GUARDIAN_COUNT);\n if (facetAddress == address(0)) return;\n uint256 guardianCount = IGuardianFacet(_wallet).guardianCount();\n if (guardianCount != 0) revert RemoteStorage__CallerNotGuardian();\n return;\n }\n facetAddress = IDiamondLoupe(_wallet).facetAddress(\n IS_GUARDIAN_SELECTOR\n );\n if (facetAddress != address(0))\n if (IGuardianFacet(_wallet).isGuardian(msg.sender)) return;\n\n revert RemoteStorage__CallerNotGuardianOrOwner();\n }\n\n /**\n * @notice Add address to storage and reverts if the address already exists.\n * This is an internal function callable from contracts that inherit this abstract contract\n * @param _wallet Address of wallet to add the address\n * @param _address Address to be added to wallet\n */\n function addAddress(address _wallet, address _address) internal {\n StorageConfig storage config = configs[_wallet];\n if (config.info[_address].exists) revert RemoteStorage__AlreadyExists();\n\n config.info[_address].exists = true;\n config.info[_address].index = uint128(config.addresses.length);\n config.addresses.push(_address);\n\n emit Added(_address);\n }\n\n /**\n * @notice Remove address from storage and reverts if the address already exists.\n * This is an internal function callable from contracts that inherit this abstract contract\n * @param _wallet Address of wallet to remove the address\n * @param _address Address to be removed from wallet\n */\n function removeAddress(address _wallet, address _address) internal {\n StorageConfig storage config = configs[_wallet];\n if (!config.info[_address].exists) revert RemoteStorage__NotFound();\n\n address lastAddress = config.addresses[config.addresses.length - 1];\n if (_address != lastAddress) {\n uint128 targetIndex = config.info[_address].index;\n config.addresses[targetIndex] = lastAddress;\n config.info[lastAddress].index = targetIndex;\n }\n config.addresses.pop();\n delete config.info[_address];\n\n emit Removed(_address);\n }\n\n /**\n * @notice Returns the address added to the given wallet\n * @param _wallet Address of wallet to fetch the addresses added to it\n * @return addresses List of addresses added to the wallet\n */\n function getAddresses(\n address _wallet\n ) internal view returns (address[] memory addresses) {\n StorageConfig storage config = configs[_wallet];\n addresses = new address[](config.addresses.length);\n uint addressesLen = config.addresses.length;\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns bool value checking if the address exists in the given wallet address\n * @param _wallet Wallet address to check\n * @param _address Address to fetch if the address if added to given wallet\n * @return exists_ Bool value showing if the address exists in wallet\n */\n function exists(\n address _wallet,\n address _address\n ) internal view returns (bool exists_) {\n exists_ = configs[_wallet].info[_address].exists;\n }\n\n /**\n * @notice Returns the number of addresses added to the wallet\n * @param _wallet Address of wallet to check\n * @return count_ Number of addresses added to wallet\n */\n function count(address _wallet) internal view returns (uint256 count_) {\n count_ = configs[_wallet].addresses.length;\n }\n}\n" + }, + "contracts/infrastructure/SecurityManager.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport {ISecurityManager} from \"./interfaces/ISecurityManager.sol\";\n\n/**\n * @title Security Manager\n * @dev Infrastructure contract to manage security parameters of users\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract SecurityManager is ISecurityManager, Ownable2Step {\n uint128 public minAdditionSecurityPeriod;\n uint128 public maxAdditionSecurityPeriod;\n uint128 private defaultAdditionSecurityPeriod;\n\n uint128 public minRemovalSecurityPeriod;\n uint128 public maxRemovalSecurityPeriod;\n uint128 private defaultRemovalSecurityPeriod;\n\n uint128 public minSecurityWindow;\n uint128 public maxSecurityWindow;\n uint128 private defaultSecurityWindow;\n\n uint128 public minRecoveryPeriod;\n uint128 public maxRecoveryPeriod;\n uint128 private defaultRecoveryPeriod;\n\n uint128 public minLockPeriod;\n uint128 public maxLockPeriod;\n uint128 private defaultLockPeriod;\n\n uint128 public minApprovalValidationPeriod;\n uint128 public maxApprovalValidationPeriod;\n uint128 private defaultApprovalValidationPeriod;\n\n uint128 public minMigrationPeriod;\n uint128 public maxMigrationPeriod;\n uint128 private defaultMigrationPeriod;\n\n bool public _isAdditionSecurityPeriodInitialized;\n bool public _isRemovalSecurityPeriodInitialized;\n bool public _isSecurityWindowInitialized;\n bool public _isRecoveryPeriodInitialized;\n bool public _isLockPeriodInitialized;\n bool public _isApprovalValidationPeriodInitialized;\n bool public _isMigrationPeriodInitialized;\n\n mapping(address => CustomSecurityConfig) securityConfigs;\n\n struct CustomSecurityConfig {\n uint128 additionSecurityPeriod;\n uint128 removalSecurityPeriod;\n uint128 securityWindow;\n uint128 recoveryPeriod;\n uint128 lockPeriod;\n uint128 approvalValidationPeriod;\n uint128 migrationPeriod;\n }\n\n /**\n * @notice Modifier to only allow wallet itself to make a call to wallet\n */\n modifier onlyWallet(address _wallet) {\n if (msg.sender != _wallet) revert SecurityManager__CallerNotWallet();\n _;\n }\n\n /**\n * @notice Modifier to revert if the variable is already initialized\n */\n modifier initializer(bool _isInitialized) {\n if (_isInitialized) revert SecurityManager__AlreadyIntialized();\n _;\n }\n\n /**\n * @notice Transfers the ownership of the contract to the given owner\n * @param _owner Address of owner who has access to initialize the default security variables for security manager\n */\n constructor(address _owner) {\n transferOwnership(_owner);\n _transferOwnership(_owner);\n }\n\n /**\n * @notice Sets the initial default/min/max addition security period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultAdditionSecurityPeriod Default Addition Security Period for all Barz contracts\n * @param _minAdditionSecurityPeriod Minimum Addition Security Period for all Barz contracts\n * @param _maxAdditionSecurityPeriod Maximum Addition Security Period for all Barz contracts\n */\n function initializeAdditionSecurityPeriod(\n uint128 _defaultAdditionSecurityPeriod,\n uint128 _minAdditionSecurityPeriod,\n uint128 _maxAdditionSecurityPeriod\n )\n external\n override\n onlyOwner\n initializer(_isAdditionSecurityPeriodInitialized)\n {\n _isAdditionSecurityPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultAdditionSecurityPeriod,\n _minAdditionSecurityPeriod,\n _maxAdditionSecurityPeriod\n );\n defaultAdditionSecurityPeriod = _defaultAdditionSecurityPeriod;\n minAdditionSecurityPeriod = _minAdditionSecurityPeriod;\n maxAdditionSecurityPeriod = _maxAdditionSecurityPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max removal security period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultRemovalSecurityPeriod Default Removal Security Period for all Barz contracts\n * @param _minRemovalSecurityPeriod Minimum Removal Security Period for all Barz contracts\n * @param _maxRemovalSecurityPeriod Maximum Removal Security Period for all Barz contracts\n */\n function initializeRemovalSecurityPeriod(\n uint128 _defaultRemovalSecurityPeriod,\n uint128 _minRemovalSecurityPeriod,\n uint128 _maxRemovalSecurityPeriod\n )\n external\n override\n onlyOwner\n initializer(_isRemovalSecurityPeriodInitialized)\n {\n _isRemovalSecurityPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultRemovalSecurityPeriod,\n _minRemovalSecurityPeriod,\n _maxRemovalSecurityPeriod\n );\n defaultRemovalSecurityPeriod = _defaultRemovalSecurityPeriod;\n minRemovalSecurityPeriod = _minRemovalSecurityPeriod;\n maxRemovalSecurityPeriod = _maxRemovalSecurityPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/maxd security window for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultSecurityWindow Default Security Window for all Barz contracts\n * @param _minSecurityWindow Minimum Security Window for all Barz contracts\n * @param _maxSecurityWindow Maximum Security Window for all Barz contracts\n */\n function initializeSecurityWindow(\n uint128 _defaultSecurityWindow,\n uint128 _minSecurityWindow,\n uint128 _maxSecurityWindow\n ) external override onlyOwner initializer(_isSecurityWindowInitialized) {\n _isSecurityWindowInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultSecurityWindow,\n _minSecurityWindow,\n _maxSecurityWindow\n );\n defaultSecurityWindow = _defaultSecurityWindow;\n minSecurityWindow = _minSecurityWindow;\n maxSecurityWindow = _maxSecurityWindow;\n }\n\n /**\n * @notice Sets the initial default/min/max recovery period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultRecoveryPeriod Default Recovery Period for all Barz contracts\n * @param _minRecoveryPeriod Minimum Recovery Period for all Barz contracts\n * @param _maxRecoveryPeriod Maximum Recovery Period for all Barz contracts\n */\n function initializeRecoveryPeriod(\n uint128 _defaultRecoveryPeriod,\n uint128 _minRecoveryPeriod,\n uint128 _maxRecoveryPeriod\n ) external override onlyOwner initializer(_isRecoveryPeriodInitialized) {\n _isRecoveryPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultRecoveryPeriod,\n _minRecoveryPeriod,\n _maxRecoveryPeriod\n );\n defaultRecoveryPeriod = _defaultRecoveryPeriod;\n minRecoveryPeriod = _minRecoveryPeriod;\n maxRecoveryPeriod = _maxRecoveryPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max lock period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultLockPeriod Default Lock Period for all Barz contracts\n * @param _minLockPeriod Minimum Lock Period for all Barz contracts\n * @param _maxLockPeriod Maximum Lock Period for all Barz contracts\n */\n function initializeLockPeriod(\n uint128 _defaultLockPeriod,\n uint128 _minLockPeriod,\n uint128 _maxLockPeriod\n ) external override onlyOwner initializer(_isLockPeriodInitialized) {\n _isLockPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultLockPeriod,\n _minLockPeriod,\n _maxLockPeriod\n );\n defaultLockPeriod = _defaultLockPeriod;\n minLockPeriod = _minLockPeriod;\n maxLockPeriod = _maxLockPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max approval validation period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultApprovalValidationPeriod Default Approval Validation Period for all Barz contracts\n * @param _minApprovalValidationPeriod Minimum Approval Validation Period for all Barz contracts\n * @param _maxApprovalValidationPeriod Maximum Approval Validation Period for all Barz contracts\n */\n function initializeApprovalValidationPeriod(\n uint128 _defaultApprovalValidationPeriod,\n uint128 _minApprovalValidationPeriod,\n uint128 _maxApprovalValidationPeriod\n )\n external\n override\n onlyOwner\n initializer(_isApprovalValidationPeriodInitialized)\n {\n _isApprovalValidationPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultApprovalValidationPeriod,\n _minApprovalValidationPeriod,\n _maxApprovalValidationPeriod\n );\n defaultApprovalValidationPeriod = _defaultApprovalValidationPeriod;\n minApprovalValidationPeriod = _minApprovalValidationPeriod;\n maxApprovalValidationPeriod = _maxApprovalValidationPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max migration period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultMigrationPeriod Default Migration Period for all Barz contracts\n * @param _minMigrationPeriod Minimum Migration Period for all Barz contracts\n * @param _maxMigrationPeriod Maximum Migration Period for all Barz contracts\n */\n function initializeMigrationPeriod(\n uint128 _defaultMigrationPeriod,\n uint128 _minMigrationPeriod,\n uint128 _maxMigrationPeriod\n ) external override onlyOwner initializer(_isMigrationPeriodInitialized) {\n _isMigrationPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultMigrationPeriod,\n _minMigrationPeriod,\n _maxMigrationPeriod\n );\n defaultMigrationPeriod = _defaultMigrationPeriod;\n minMigrationPeriod = _minMigrationPeriod;\n maxMigrationPeriod = _maxMigrationPeriod;\n }\n\n /**\n * @notice Wallet owner sets the addition security period for the wallet. Only the owner of wallet can call this function.\n * The addition security period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _additionSecurityPeriod Custom Addition Security Period for the wallet\n */\n function setAdditionSecurityPeriod(\n address _wallet,\n uint128 _additionSecurityPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _additionSecurityPeriod,\n minAdditionSecurityPeriod,\n maxAdditionSecurityPeriod\n );\n securityConfigs[_wallet]\n .additionSecurityPeriod = _additionSecurityPeriod;\n }\n\n /**\n * @notice Wallet owner sets the removal security period for the wallet. Only the owner of wallet can call this function.\n * The removal security period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _removalSecurityPeriod Custom Removal Security Period for the wallet\n */\n function setRemovalSecurityPeriod(\n address _wallet,\n uint128 _removalSecurityPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _removalSecurityPeriod,\n minRemovalSecurityPeriod,\n maxRemovalSecurityPeriod\n );\n securityConfigs[_wallet].removalSecurityPeriod = _removalSecurityPeriod;\n }\n\n /**\n * @notice Wallet owner sets the security window for the wallet. Only the owner of wallet can call this function.\n * The security window should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _securityWindow Custom Security Window for the wallet\n */\n function setSecurityWindow(\n address _wallet,\n uint128 _securityWindow\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _securityWindow,\n minSecurityWindow,\n maxSecurityWindow\n );\n securityConfigs[_wallet].securityWindow = _securityWindow;\n }\n\n /**\n * @notice Wallet owner sets the recovery period for the wallet. Only the owner of wallet can call this function.\n * The recovery period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _recoveryPeriod Custom recovery period for the wallet\n */\n function setRecoveryPeriod(\n address _wallet,\n uint128 _recoveryPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _recoveryPeriod,\n minRecoveryPeriod,\n maxRecoveryPeriod\n );\n securityConfigs[_wallet].recoveryPeriod = _recoveryPeriod;\n }\n\n /**\n * @notice Wallet owner sets the lock period for the wallet. Only the owner of wallet can call this function.\n * The lock period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _lockPeriod Custom Lock period for the wallet\n */\n function setLockPeriod(\n address _wallet,\n uint128 _lockPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(_lockPeriod, minLockPeriod, maxLockPeriod);\n securityConfigs[_wallet].lockPeriod = _lockPeriod;\n }\n\n /**\n * @notice Wallet owner sets the approval validation period for the wallet. Only the owner of wallet can call this function.\n * The approval validation period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _approvalValidationPeriod Custom approval validation period for the wallet\n */\n function setApprovalValidationPeriod(\n address _wallet,\n uint128 _approvalValidationPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _approvalValidationPeriod,\n minApprovalValidationPeriod,\n maxApprovalValidationPeriod\n );\n securityConfigs[_wallet]\n .approvalValidationPeriod = _approvalValidationPeriod;\n }\n\n /**\n * @notice Wallet owner sets the migration period for the wallet. Only the owner of wallet can call this function.\n * The migration period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _migrationPeriod Custom migration period for the wallet\n */\n\n function setMigrationPeriod(\n address _wallet,\n uint128 _migrationPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _migrationPeriod,\n minMigrationPeriod,\n maxMigrationPeriod\n );\n securityConfigs[_wallet].migrationPeriod = _migrationPeriod;\n }\n\n /**\n * @notice Returns the addition security period. Returns default value when custom addition security period is not set\n * @param _wallet Address of wallet\n * @return additionSecurityPeriod Addition Security Period of the given Barz account or wallet\n */\n function additionSecurityPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 additionSecurityPeriod)\n {\n additionSecurityPeriod = securityConfigs[_wallet]\n .additionSecurityPeriod;\n additionSecurityPeriod = (additionSecurityPeriod == 0)\n ? defaultAdditionSecurityPeriod\n : additionSecurityPeriod;\n }\n\n /**\n * @notice Returns the removal security period. Returns default value when custom removal security period is not set\n * @param _wallet Address of wallet\n * @return removalSecurityPeriod Removal Security Period of the given Barz account or wallet\n */\n function removalSecurityPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 removalSecurityPeriod)\n {\n removalSecurityPeriod = securityConfigs[_wallet].removalSecurityPeriod;\n removalSecurityPeriod = (removalSecurityPeriod == 0)\n ? defaultRemovalSecurityPeriod\n : removalSecurityPeriod;\n }\n\n /**\n * @notice Returns the security window. Returns default value when custom security window is not set\n * @param _wallet Address of wallet\n * @return securityWindow Security window of the given Barz account or wallet\n */\n function securityWindowOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 securityWindow)\n {\n securityWindow = securityConfigs[_wallet].securityWindow;\n securityWindow = (securityWindow == 0)\n ? defaultSecurityWindow\n : securityWindow;\n }\n\n /**\n * @notice Returns the recovery period. Returns default value when custom recovery period is not set\n * @param _wallet Address of wallet\n * @return recoveryPeriod Recovery Period of the given Barz account or wallet\n */\n function recoveryPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 recoveryPeriod)\n {\n recoveryPeriod = securityConfigs[_wallet].recoveryPeriod;\n recoveryPeriod = (recoveryPeriod == 0)\n ? defaultRecoveryPeriod\n : recoveryPeriod;\n }\n\n /**\n * @notice Returns the lock period. Returns default value when custom lock period is not set\n * @param _wallet Address of wallet\n * @return lockPeriod Lock Period of the given Barz account or wallet\n */\n function lockPeriodOf(\n address _wallet\n ) public view override onlyWallet(_wallet) returns (uint128 lockPeriod) {\n lockPeriod = securityConfigs[_wallet].lockPeriod;\n lockPeriod = (lockPeriod == 0) ? defaultLockPeriod : lockPeriod;\n }\n\n /**\n * @notice Returns the approval validation period. Returns default value when custom approval validation period is not set\n * @param _wallet Address of wallet\n * @return approvalValidationPeriod Approval Validation Period of the given Barz account or wallet\n */\n function approvalValidationPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityConfigs[_wallet]\n .approvalValidationPeriod;\n approvalValidationPeriod = (approvalValidationPeriod == 0)\n ? defaultApprovalValidationPeriod\n : approvalValidationPeriod;\n }\n\n /**\n * @notice Returns the migration period. Returns default value when custom migration period is not set\n * @param _wallet Address of wallet\n * @return migrationPeriod Migration Period of the given Barz account or wallet\n */\n function migrationPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 migrationPeriod)\n {\n migrationPeriod = securityConfigs[_wallet].migrationPeriod;\n migrationPeriod = (migrationPeriod == 0)\n ? defaultMigrationPeriod\n : migrationPeriod;\n }\n\n /**\n * @notice Validates if the period is smaller than the max period or bigger than the min period\n * @param _period Period to be checked\n * @param _minPeriod Minimum period\n * @param _maxPeriod Maximum period\n */\n function _validatePeriodBoundaries(\n uint128 _period,\n uint128 _minPeriod,\n uint128 _maxPeriod\n ) internal pure {\n if (_period >= _maxPeriod || _period <= _minPeriod)\n revert SecurityManager__OutOfBoundary();\n }\n}\n" + }, + "contracts/infrastructure/WhitelistStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {RemoteStorage} from \"./RemoteStorage.sol\";\n\n/**\n * @title Whitelist storage\n * @dev Maps addresses to the corresponsing array of whitelisted addresses for each of them.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract WhitelistStorage is RemoteStorage {\n /**\n * @dev Add the address to the whitelist storage\n * @param _wallet User wallet\n * @param _address Address to be whitelisted\n */\n function whitelistAddress(address _wallet, address _address) external {\n enforceWalletOrGuardianIfExists(_wallet);\n addAddress(_wallet, _address);\n }\n\n /**\n * @dev Removes the address from the whitelist storage\n * @param _wallet User wallet\n * @param _address Address to be removed from the whitelist\n */\n function blacklistAddress(address _wallet, address _address) external {\n enforceGuardianOrWallet(_wallet);\n removeAddress(_wallet, _address);\n }\n\n /**\n * @dev Returns whether the address exists in the whitelist storage, associated with the wallet\n * @param _wallet User wallet\n * @param _address Address to be whitelisted\n */\n function isWhitelisted(\n address _wallet,\n address _address\n ) external view returns (bool) {\n return exists(_wallet, _address);\n }\n\n /**\n * @dev Returns all whitelisted addresses associated with the wallet\n * @param _wallet User wallet\n */\n function getWhitelistedAddresses(\n address _wallet\n ) external view returns (address[] memory) {\n return getAddresses(_wallet);\n }\n}\n" + }, + "contracts/interfaces/ERC/IERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\n\npragma solidity 0.8.21;\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155Receiver {\n /**\n * @dev Handles the receipt of a single ERC1155 token type. This function is\n * called at the end of a `safeTransferFrom` after the balance has been updated.\n *\n * NOTE: To accept the transfer, this must return\n * `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n * (i.e. 0xf23a6e61, or its own function selector).\n *\n * @param operator The address which initiated the transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param id The ID of the token being transferred\n * @param value The amount of tokens being transferred\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n ) external returns (bytes4);\n\n /**\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\n * is called at the end of a `safeBatchTransferFrom` after the balances have\n * been updated.\n *\n * NOTE: To accept the transfer(s), this must return\n * `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n * (i.e. 0xbc197c81, or its own function selector).\n *\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "contracts/interfaces/ERC/IERC1271.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\ninterface IERC1271 {\n function isValidSignature(\n bytes32 hash,\n bytes memory signature\n ) external view returns (bytes4);\n}\n" + }, + "contracts/interfaces/ERC/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\ninterface IERC165 {\n /// @notice Query if a contract implements an interface\n /// @param interfaceId The interface identifier, as specified in ERC-165\n /// @dev Interface identification is specified in ERC-165. This function\n /// uses less than 30,000 gas.\n /// @return `true` if the contract implements `interfaceID` and\n /// `interfaceID` is not 0xffffffff, `false` otherwise\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/IERC173.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\n/// @title ERC-173 Contract Ownership Standard\n/// Note: the ERC-165 identifier for this interface is 0x7f5828d0\n/* is ERC165 */\ninterface IERC173 {\n /// @dev This emits when ownership of a contract changes.\n event OwnershipTransferred(\n address indexed previousOwner,\n address indexed newOwner\n );\n\n /// @notice Get the address of the owner\n /// @return owner_ The address of the owner.\n function owner() external view returns (address owner_);\n\n /// @notice Set the address of the new owner of the contract\n /// @dev Set _newOwner to address(0) to renounce any ownership.\n /// @param _newOwner The address of the new owner of the contract\n function transferOwnership(address _newOwner) external;\n}\n" + }, + "contracts/interfaces/ERC/IERC677Receiver.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\ninterface IERC677Receiver {\n function onTokenTransfer(\n address sender,\n uint value,\n bytes calldata data\n ) external pure returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155 is IERC165 {\n /**\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n */\n event TransferSingle(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256 id,\n uint256 value\n );\n\n /**\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n * transfers.\n */\n event TransferBatch(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\n\n /**\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n * `approved`.\n */\n event ApprovalForAll(\n address indexed account,\n address indexed operator,\n bool approved\n );\n\n /**\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n *\n * If an {URI} event was emitted for `id`, the standard\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n * returned by {IERC1155MetadataURI-uri}.\n */\n event URI(string value, uint256 indexed id);\n\n /**\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(\n address account,\n uint256 id\n ) external view returns (uint256);\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] calldata accounts,\n uint256[] calldata ids\n ) external view returns (uint256[] memory);\n\n /**\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n *\n * Emits an {ApprovalForAll} event.\n *\n * Requirements:\n *\n * - `operator` cannot be the caller.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n *\n * See {setApprovalForAll}.\n */\n function isApprovedForAll(\n address account,\n address operator\n ) external view returns (bool);\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes calldata data\n ) external;\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(\n address indexed owner,\n address indexed spender,\n uint256 value\n );\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` 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 amount) 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(\n address owner,\n address spender\n ) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the 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 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` 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(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(\n address spender,\n uint256 addedValue\n ) external returns (bool);\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(\n address spender,\n uint256 subtractedValue\n ) external returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(\n address indexed from,\n address indexed to,\n uint256 indexed tokenId\n );\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(\n address indexed owner,\n address indexed approved,\n uint256 indexed tokenId\n );\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(\n address indexed owner,\n address indexed operator,\n bool approved\n );\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(\n uint256 tokenId\n ) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(\n address owner,\n address operator\n ) external view returns (bool);\n}\n" + }, + "contracts/interfaces/IBarz.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Barz Interface\n * @dev Interface of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IBarz {\n error Barz__InitializationFailure();\n}\n" + }, + "contracts/interfaces/IBarzFactory.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Barz} from \"../Barz.sol\";\n\n/**\n * @title Barz Factory Interface\n * @dev Interface of contract to easily deploy Barz to a pre-computed address with a single call\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IBarzFactory {\n function createAccount(\n address verificationFacet,\n bytes calldata owner,\n uint256 salt\n ) external returns (Barz);\n\n function getAddress(\n address verificationFacet,\n bytes calldata owner,\n uint256 salt\n ) external view returns (address);\n\n function getBytecode(\n address accountFacet,\n address verificationFacet,\n address entryPoint,\n address facetRegistry,\n address defaultFallback,\n bytes memory ownerPublicKey\n ) external pure returns (bytes memory);\n\n function getCreationCode() external pure returns (bytes memory);\n}\n" + }, + "contracts/libraries/DefaultLibDiamond.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\n\nerror InitializationFunctionReverted(\n address _initializationContractAddress,\n bytes _calldata\n);\n\nlibrary DefaultLibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION =\n keccak256(\"trustwallet.barz.diamond.storage\");\n\n struct FacetAddressAndPosition {\n address facetAddress;\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\n }\n\n struct FacetFunctionSelectors {\n bytes4[] functionSelectors;\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\n }\n\n struct DiamondStorage {\n // maps function selector to the facet address and\n // the position of the selector in the facetFunctionSelectors.selectors array\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\n // maps facet addresses to function selectors\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\n // facet addresses\n address[] facetAddresses;\n // Used to query if a contract implements an interface.\n // Used to implement ERC-165.\n mapping(bytes4 => bool) supportedInterfaces;\n }\n\n function diamondStorage()\n internal\n pure\n returns (DiamondStorage storage ds)\n {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n event DiamondCut(\n IDiamondCut.FacetCut[] _diamondCut,\n address _init,\n bytes _calldata\n );\n\n // Internal function version of diamondCut\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n for (\n uint256 facetIndex;\n facetIndex < _diamondCut.length;\n facetIndex++\n ) {\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\n if (action == IDiamondCut.FacetCutAction.Add) {\n addFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\n replaceFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\n removeFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else {\n revert(\"LibDiamondCut: Incorrect FacetCutAction\");\n }\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Add facet can't be address(0)\"\n );\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n require(\n oldFacetAddress == address(0),\n \"LibDiamondCut: Can't add function that already exists\"\n );\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function replaceFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Replace facet can't be address(0)\"\n );\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n require(\n oldFacetAddress != _facetAddress,\n \"LibDiamondCut: Can't replace function with same facet\"\n );\n removeFunction(ds, oldFacetAddress, selector);\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function removeFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n // if function does not exist then do nothing and return\n require(\n _facetAddress == address(0),\n \"LibDiamondCut: Remove facet address must be address(0)\"\n );\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n removeFunction(ds, oldFacetAddress, selector);\n }\n }\n\n function addFacet(\n DiamondStorage storage ds,\n address _facetAddress\n ) internal {\n enforceHasContractCode(\n _facetAddress,\n \"LibDiamondCut: New facet has no code\"\n );\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds\n .facetAddresses\n .length;\n ds.facetAddresses.push(_facetAddress);\n }\n\n function addFunction(\n DiamondStorage storage ds,\n bytes4 _selector,\n uint96 _selectorPosition,\n address _facetAddress\n ) internal {\n ds\n .selectorToFacetAndPosition[_selector]\n .functionSelectorPosition = _selectorPosition;\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(\n _selector\n );\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\n }\n\n function removeFunction(\n DiamondStorage storage ds,\n address _facetAddress,\n bytes4 _selector\n ) internal {\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Can't remove function that doesn't exist\"\n );\n // an immutable function is a function defined directly in a diamond\n require(\n _facetAddress != address(this),\n \"LibDiamondCut: Can't remove immutable function\"\n );\n // replace selector with last selector, then delete last selector\n uint256 selectorPosition = ds\n .selectorToFacetAndPosition[_selector]\n .functionSelectorPosition;\n uint256 lastSelectorPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors\n .length - 1;\n // if not the same then replace _selector with lastSelector\n if (selectorPosition != lastSelectorPosition) {\n bytes4 lastSelector = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors[lastSelectorPosition];\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[\n selectorPosition\n ] = lastSelector;\n ds\n .selectorToFacetAndPosition[lastSelector]\n .functionSelectorPosition = uint96(selectorPosition);\n }\n // delete the last selector\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\n delete ds.selectorToFacetAndPosition[_selector];\n\n // if no more selectors for facet address then delete the facet address\n if (lastSelectorPosition == 0) {\n // replace facet address with last facet address and delete last facet address\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\n uint256 facetAddressPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .facetAddressPosition;\n if (facetAddressPosition != lastFacetAddressPosition) {\n address lastFacetAddress = ds.facetAddresses[\n lastFacetAddressPosition\n ];\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\n ds\n .facetFunctionSelectors[lastFacetAddress]\n .facetAddressPosition = facetAddressPosition;\n }\n ds.facetAddresses.pop();\n delete ds\n .facetFunctionSelectors[_facetAddress]\n .facetAddressPosition;\n }\n }\n\n function initializeDiamondCut(\n address _init,\n bytes memory _calldata\n ) internal {\n if (_init == address(0)) {\n return;\n }\n enforceHasContractCode(\n _init,\n \"LibDiamondCut: _init address has no code\"\n );\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length > 0) {\n // bubble up error\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(error)\n revert(add(32, error), returndata_size)\n }\n } else {\n revert InitializationFunctionReverted(_init, _calldata);\n }\n }\n }\n\n function enforceHasContractCode(\n address _contract,\n string memory _errorMessage\n ) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize > 0, _errorMessage);\n }\n}\n" + }, + "contracts/libraries/LibAppStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SafeCast} from \"@openzeppelin/contracts/utils/math/SafeCast.sol\";\nimport {IEntryPoint} from \"../aa-4337/interfaces/IEntryPoint.sol\";\nimport {IFacetRegistry} from \"../infrastructure/interfaces/IFacetRegistry.sol\";\n\n/*\n * @title App Storage\n * @dev App storage for Barz contract to prevent storage collision\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\n\nstruct Lock {\n uint64 release;\n bytes4 locker;\n}\n\nstruct InitializersStorage {\n // NOTE: initialized is a variable to make sure the initialization is only done once.\n uint8 signerInitialized;\n uint8 accountInitialized;\n uint8 restrictionsInitialized;\n}\n\nstruct AppStorage {\n mapping(uint256 => InitializersStorage) initStorage;\n uint8 signerMigration;\n bytes4 validateOwnerSignatureSelector;\n IEntryPoint entryPoint;\n IFacetRegistry facetRegistry;\n mapping(uint256 => Lock) locks;\n}\n\nlibrary LibAppStorage {\n error LibAppStorage__AccountAlreadyUninitialized();\n error LibAppStorage__AccountMustBeUninitialized();\n error LibAppStorage__SignerAlreadyUninitialized();\n error LibAppStorage__SignerMustBeUninitialized();\n\n function appStorage() internal pure returns (AppStorage storage ds) {\n assembly {\n ds.slot := 0\n }\n }\n\n function setSignerUninitialized() internal {\n AppStorage storage s = appStorage();\n if (1 != s.initStorage[0].signerInitialized) {\n revert LibAppStorage__SignerAlreadyUninitialized();\n }\n s.initStorage[0].signerInitialized = 0;\n }\n\n function getValidateOwnerSignatureSelector()\n internal\n view\n returns (bytes4 selector)\n {\n selector = appStorage().validateOwnerSignatureSelector;\n }\n\n function setValidateOwnerSignatureSelector(\n bytes4 _validateOwnerSignatureSelector\n ) internal {\n appStorage()\n .validateOwnerSignatureSelector = _validateOwnerSignatureSelector;\n }\n\n function enforceSignerInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].signerInitialized) {\n revert LibAppStorage__SignerMustBeUninitialized();\n }\n s.initStorage[0].signerInitialized = 1;\n }\n\n function enforceAccountInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].accountInitialized) {\n revert LibAppStorage__AccountMustBeUninitialized();\n }\n s.initStorage[0].accountInitialized = 1;\n }\n\n function initiateSignerMigration() internal {\n appStorage().signerMigration = 1;\n }\n\n function enforceSignerMigration() internal view {\n if (1 != appStorage().signerMigration) {\n revert LibAppStorage__AccountMustBeUninitialized();\n }\n }\n\n function finalizeSignerMigration() internal {\n appStorage().signerMigration = 0;\n }\n\n function setLock(uint256 _releaseAfter, bytes4 _locker) internal {\n appStorage().locks[0] = Lock(SafeCast.toUint64(_releaseAfter), _locker);\n }\n\n function enforceRestrictionsInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].restrictionsInitialized)\n revert LibAppStorage__SignerMustBeUninitialized();\n s.initStorage[0].restrictionsInitialized = 1;\n }\n\n function setRestrictionsUninitialized() internal {\n AppStorage storage s = appStorage();\n if (1 != s.initStorage[0].restrictionsInitialized)\n revert LibAppStorage__AccountAlreadyUninitialized();\n s.initStorage[0].restrictionsInitialized = 0;\n }\n}\n\ncontract BarzStorage {\n AppStorage internal s;\n modifier onlyWhenUnlocked() {\n require(\n uint64(block.timestamp) >= s.locks[0].release,\n \"Account Locked\"\n );\n _;\n }\n modifier onlyWhenLocked() {\n require(\n uint64(block.timestamp) < s.locks[0].release,\n \"Account Unlocked\"\n );\n _;\n }\n}\n" + }, + "contracts/libraries/LibDiamond.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\n\nerror InitializationFunctionReverted(\n address _initializationContractAddress,\n bytes _calldata\n);\n\nlibrary LibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION =\n keccak256(\"trustwallet.barz.diamond.storage\");\n\n struct DiamondStorage {\n // maps function selectors to the facets that execute the functions.\n // and maps the selectors to their position in the selectorSlots array.\n // func selector => address facet, selector position\n mapping(bytes4 => bytes32) facets;\n // array of slots of function selectors.\n // each slot holds 8 function selectors.\n mapping(uint256 => bytes32) selectorSlots;\n // The number of function selectors in selectorSlots\n uint16 selectorCount;\n // Used to query if a contract implements an interface.\n // Used to implement ERC-165.\n mapping(bytes4 => bool) supportedInterfaces;\n // Default Fallback Handler of the barz.\n IDiamondLoupe defaultFallbackHandler;\n }\n\n function diamondStorage()\n internal\n pure\n returns (DiamondStorage storage ds)\n {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n function enforceIsSelf() internal view {\n require(msg.sender == address(this), \"LibDiamond: Caller not self\");\n }\n\n event DiamondCut(\n IDiamondCut.FacetCut[] _diamondCut,\n address _init,\n bytes _calldata\n );\n\n bytes32 constant CLEAR_ADDRESS_MASK =\n bytes32(uint256(0xffffffffffffffffffffffff));\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\n\n // Internal function version of diamondCut\n // This code is almost the same as the external diamondCut,\n // except it is using 'Facet[] memory _diamondCut' instead of\n // 'Facet[] calldata _diamondCut'.\n // The code is duplicated to prevent copying calldata to memory which\n // causes an error for a two dimensional array.\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n DiamondStorage storage ds = diamondStorage();\n uint256 originalSelectorCount = ds.selectorCount;\n uint256 selectorCount = originalSelectorCount;\n bytes32 selectorSlot;\n // Check if last selector slot is not full\n // \"selectorCount & 7\" is a gas efficient modulo by eight \"selectorCount % 8\"\n if (selectorCount & 7 > 0) {\n // get last selectorSlot\n // \"selectorSlot >> 3\" is a gas efficient division by 8 \"selectorSlot / 8\"\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\n }\n // loop through diamond cut\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\n selectorCount,\n selectorSlot,\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].action,\n _diamondCut[facetIndex].functionSelectors\n );\n\n unchecked {\n facetIndex++;\n }\n }\n if (selectorCount != originalSelectorCount) {\n ds.selectorCount = uint16(selectorCount);\n }\n // If last selector slot is not full\n // \"selectorCount & 7\" is a gas efficient modulo by eight \"selectorCount % 8\"\n if (selectorCount & 7 > 0) {\n // \"selectorSlot >> 3\" is a gas efficient division by 8 \"selectorSlot / 8\"\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addReplaceRemoveFacetSelectors(\n uint256 _selectorCount,\n bytes32 _selectorSlot,\n address _newFacetAddress,\n IDiamondCut.FacetCutAction _action,\n bytes4[] memory _selectors\n ) internal returns (uint256, bytes32) {\n DiamondStorage storage ds = diamondStorage();\n require(\n _selectors.length > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n if (_action == IDiamondCut.FacetCutAction.Add) {\n enforceHasContractCode(\n _newFacetAddress,\n \"LibDiamondCut: Add facet has no code\"\n );\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n require(\n address(bytes20(oldFacet)) == address(0),\n \"LibDiamondCut: Can't add function that already exists\"\n );\n // add facet for selector\n ds.facets[selector] =\n bytes20(_newFacetAddress) |\n bytes32(_selectorCount);\n // \"_selectorCount & 7\" is a gas efficient modulo by eight \"_selectorCount % 8\"\n // \" << 5 is the same as multiplying by 32 ( * 32)\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\n // clear selector position in slot and add selector\n _selectorSlot =\n (_selectorSlot &\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\n (bytes32(selector) >> selectorInSlotPosition);\n // if slot is full then write it to storage\n if (selectorInSlotPosition == 224) {\n // \"_selectorSlot >> 3\" is a gas efficient division by 8 \"_selectorSlot / 8\"\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\n _selectorSlot = 0;\n }\n _selectorCount++;\n\n unchecked {\n selectorIndex++;\n }\n }\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\n enforceHasContractCode(\n _newFacetAddress,\n \"LibDiamondCut: Replace facet has no code\"\n );\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n address oldFacetAddress = address(bytes20(oldFacet));\n // only useful if immutable functions exist\n require(\n oldFacetAddress != address(this),\n \"LibDiamondCut: Can't replace immutable function\"\n );\n require(\n oldFacetAddress != _newFacetAddress,\n \"LibDiamondCut: Can't replace function with same function\"\n );\n require(\n oldFacetAddress != address(0),\n \"LibDiamondCut: Can't replace function that doesn't exist\"\n );\n // replace old facet address\n ds.facets[selector] =\n (oldFacet & CLEAR_ADDRESS_MASK) |\n bytes20(_newFacetAddress);\n\n unchecked {\n selectorIndex++;\n }\n }\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\n require(\n _newFacetAddress == address(0),\n \"LibDiamondCut: Remove facet address must be address(0)\"\n );\n // \"_selectorCount >> 3\" is a gas efficient division by 8 \"_selectorCount / 8\"\n uint256 selectorSlotCount = _selectorCount >> 3;\n // \"_selectorCount & 7\" is a gas efficient modulo by eight \"_selectorCount % 8\"\n uint256 selectorInSlotIndex = _selectorCount & 7;\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n if (_selectorSlot == 0) {\n // get last selectorSlot\n selectorSlotCount--;\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\n selectorInSlotIndex = 7;\n } else {\n selectorInSlotIndex--;\n }\n bytes4 lastSelector;\n uint256 oldSelectorsSlotCount;\n uint256 oldSelectorInSlotPosition;\n // adding a block here prevents stack too deep error\n {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n require(\n address(bytes20(oldFacet)) != address(0),\n \"LibDiamondCut: Can't remove function that doesn't exist\"\n );\n // only useful if immutable functions exist\n require(\n address(bytes20(oldFacet)) != address(this),\n \"LibDiamondCut: Can't remove immutable function\"\n );\n // replace selector with last selector in ds.facets\n // gets the last selector\n // \" << 5 is the same as multiplying by 32 ( * 32)\n lastSelector = bytes4(\n _selectorSlot << (selectorInSlotIndex << 5)\n );\n if (lastSelector != selector) {\n // update last selector slot position info\n ds.facets[lastSelector] =\n (oldFacet & CLEAR_ADDRESS_MASK) |\n bytes20(ds.facets[lastSelector]);\n }\n delete ds.facets[selector];\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\n // \"oldSelectorCount >> 3\" is a gas efficient division by 8 \"oldSelectorCount / 8\"\n oldSelectorsSlotCount = oldSelectorCount >> 3;\n // \"oldSelectorCount & 7\" is a gas efficient modulo by eight \"oldSelectorCount % 8\"\n // \" << 5 is the same as multiplying by 32 ( * 32)\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\n }\n if (oldSelectorsSlotCount != selectorSlotCount) {\n bytes32 oldSelectorSlot = ds.selectorSlots[\n oldSelectorsSlotCount\n ];\n // clears the selector we are deleting and puts the last selector in its place.\n oldSelectorSlot =\n (oldSelectorSlot &\n ~(CLEAR_SELECTOR_MASK >>\n oldSelectorInSlotPosition)) |\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\n // update storage with the modified slot\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\n } else {\n // clears the selector we are deleting and puts the last selector in its place.\n _selectorSlot =\n (_selectorSlot &\n ~(CLEAR_SELECTOR_MASK >>\n oldSelectorInSlotPosition)) |\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\n }\n if (selectorInSlotIndex == 0) {\n delete ds.selectorSlots[selectorSlotCount];\n _selectorSlot = 0;\n }\n\n unchecked {\n selectorIndex++;\n }\n }\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\n } else {\n revert(\"LibDiamondCut: Incorrect FacetCutAction\");\n }\n return (_selectorCount, _selectorSlot);\n }\n\n function initializeDiamondCut(\n address _init,\n bytes memory _calldata\n ) internal {\n if (_init == address(0)) {\n return;\n }\n enforceHasContractCode(\n _init,\n \"LibDiamondCut: _init address has no code\"\n );\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length > 0) {\n // bubble up error\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(error)\n revert(add(32, error), returndata_size)\n }\n } else {\n revert InitializationFunctionReverted(_init, _calldata);\n }\n }\n }\n\n function enforceHasContractCode(\n address _contract,\n string memory _errorMessage\n ) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize > 0, _errorMessage);\n }\n\n function restrictionsFacet() internal view returns (address facetAddress_) {\n bytes4 selector = bytes4(\n keccak256(\"verifyRestrictions(address,address,uint256,bytes)\")\n );\n facetAddress_ = address(\n bytes20(LibDiamond.diamondStorage().facets[selector])\n );\n }\n}\n" + }, + "contracts/libraries/LibFacetStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Storage\n * @dev Storage contract to store each facets variables with diamond storage\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\n\nstruct Secp256k1VerificationStorage {\n address signer;\n}\n\nstruct Secp256r1VerificationStorage {\n uint256[2] q;\n}\n\nstruct GuardianStorage {\n mapping(bytes32 => uint256) pending;\n mapping(uint8 => StorageConfig) configs;\n}\n\nstruct Info {\n bool exists;\n uint128 index;\n}\n\nstruct StorageConfig {\n address[] addresses;\n mapping(address => Info) info;\n}\n\nstruct RecoveryConfig {\n bytes recoveryPublicKey;\n uint64 executeAfter;\n}\n\nstruct ApprovalConfig {\n bool isApproved;\n uint64 validUntil;\n}\n\nstruct RecoveryApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isNewOwnerApproved;\n}\n\nstruct RecoveryStorage {\n mapping(uint8 => RecoveryConfig) recoveryConfigs;\n mapping(uint8 => RecoveryApprovalConfig) recoveryApprovalConfigs;\n uint128 nonce;\n}\n\nstruct RestrictionsStorage {\n address[] restrictions;\n mapping(address => bool) exists;\n}\n\nstruct SignatureMigrationConfig {\n bytes migrationPublicKey;\n address migrationVerificationFacet;\n bytes4[] migrationSelectors;\n uint64 migrateAfter;\n}\n\nstruct SignatureMigrationApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isMigrationApproved;\n}\n\nstruct SignatureMigrationStorage {\n mapping(uint8 => SignatureMigrationConfig) migrationConfigs;\n mapping(uint8 => SignatureMigrationApprovalConfig) migrationApprovalConfigs;\n uint128 nonce;\n}\n\nstruct DiamondCutApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isDiamondCutApproved;\n}\n\nstruct DiamondCutStorage {\n mapping(uint8 => DiamondCutApprovalConfig) diamondCutApprovalConfigs;\n uint128 nonce;\n}\n\nstruct LockStorage {\n uint128 nonce;\n}\n\nlibrary LibFacetStorage {\n function k1Storage()\n internal\n pure\n returns (Secp256k1VerificationStorage storage ds)\n {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.Secp256k1VerificationStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function r1Storage()\n internal\n pure\n returns (Secp256r1VerificationStorage storage ds)\n {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.Secp256r1VerificationStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function guardianStorage()\n internal\n pure\n returns (GuardianStorage storage ds)\n {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.GuardianStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function recoveryStorage()\n internal\n pure\n returns (RecoveryStorage storage ds)\n {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.RecoveryStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function restrictionsStorage()\n internal\n pure\n returns (RestrictionsStorage storage ds)\n {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.RestrictionsStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function migrationStorage()\n internal\n pure\n returns (SignatureMigrationStorage storage ds)\n {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.SignatureMigrationStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function diamondCutStorage()\n internal\n pure\n returns (DiamondCutStorage storage ds)\n {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.DiamondCutStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function lockStorage() internal pure returns (LockStorage storage ds) {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.LockStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n}\n" + }, + "contracts/libraries/LibGuardian.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibFacetStorage, StorageConfig} from \"./LibFacetStorage.sol\";\n\n/**\n * @title LibGuardian\n * @dev Internal Library to provide utility feature for Guardians stored in Guardian Facet Storage\n * @author David Yongjun Kim (@Powerstream3604)\n */\nlibrary LibGuardian {\n function majorityOfGuardians()\n internal\n view\n returns (uint256 guardianNumber)\n {\n uint256 guardianLength = guardianCount();\n guardianNumber = (guardianLength == 0) ? 0 : guardianLength / 2 + 1;\n }\n\n function isGuardian(address _guardian) internal view returns (bool) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n return config.info[_guardian].exists;\n }\n\n function guardianCount() internal view returns (uint256) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n return config.addresses.length;\n }\n\n function getGuardians() internal view returns (address[] memory) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n address[] memory addresses = new address[](config.addresses.length);\n uint256 addressesLen = config.addresses.length;\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n return addresses;\n }\n}\n" + }, + "contracts/libraries/LibLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {LibDiamond} from \"./LibDiamond.sol\";\n\n/**\n * @title LibLoupe\n * @dev Internal Library to provide utility feature for reading the state of diamond facets\n * @author David Yongjun Kim (@Powerstream3604)\n */\nlibrary LibLoupe {\n /// @notice Gets all facets and their selectors.\n /// @return facets_ Facet\n function facets()\n internal\n view\n returns (IDiamondLoupe.Facet[] memory facets_)\n {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facets_ = new IDiamondLoupe.Facet[](ds.selectorCount);\n uint16[] memory numFacetSelectors = new uint16[](ds.selectorCount);\n uint256 numFacets;\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facetAddress_ = address(bytes20(ds.facets[selector]));\n bool continueLoop;\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n if (facets_[facetIndex].facetAddress == facetAddress_) {\n facets_[facetIndex].functionSelectors[\n numFacetSelectors[facetIndex]\n ] = selector;\n // probably will never have more than 256 functions from one facet contract\n require(numFacetSelectors[facetIndex] < 255);\n numFacetSelectors[facetIndex]++;\n continueLoop = true;\n break;\n }\n }\n if (continueLoop) {\n continue;\n }\n facets_[numFacets].facetAddress = facetAddress_;\n facets_[numFacets].functionSelectors = new bytes4[](\n ds.selectorCount\n );\n facets_[numFacets].functionSelectors[0] = selector;\n numFacetSelectors[numFacets] = 1;\n numFacets++;\n }\n }\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n uint256 numSelectors = numFacetSelectors[facetIndex];\n bytes4[] memory selectors = facets_[facetIndex].functionSelectors;\n // setting the number of selectors\n assembly {\n mstore(selectors, numSelectors)\n }\n }\n // setting the number of facets\n assembly {\n mstore(facets_, numFacets)\n }\n }\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n /// @return _facetFunctionSelectors The selectors associated with a facet address.\n function facetFunctionSelectors(\n address _facet\n ) internal view returns (bytes4[] memory _facetFunctionSelectors) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n uint256 numSelectors;\n _facetFunctionSelectors = new bytes4[](ds.selectorCount);\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facet = address(bytes20(ds.facets[selector]));\n if (_facet == facet) {\n _facetFunctionSelectors[numSelectors] = selector;\n numSelectors++;\n }\n }\n }\n // Set the number of selectors in the array\n assembly {\n mstore(_facetFunctionSelectors, numSelectors)\n }\n }\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses()\n internal\n view\n returns (address[] memory facetAddresses_)\n {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facetAddresses_ = new address[](ds.selectorCount);\n uint256 numFacets;\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facetAddress_ = address(bytes20(ds.facets[selector]));\n bool continueLoop;\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n if (facetAddress_ == facetAddresses_[facetIndex]) {\n continueLoop = true;\n break;\n }\n }\n if (continueLoop) {\n continue;\n }\n facetAddresses_[numFacets] = facetAddress_;\n numFacets++;\n }\n }\n // Set the number of facet addresses in the array\n assembly {\n mstore(facetAddresses_, numFacets)\n }\n }\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(\n bytes4 _functionSelector\n ) internal view returns (address facetAddress_) {\n facetAddress_ = address(\n bytes20(LibDiamond.diamondStorage().facets[_functionSelector])\n );\n }\n}\n" + }, + "contracts/libraries/LibMultiSigStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Multi-sig Storage\n * @dev Storage contract for storing Multi-sig Facet variables in diamond storage pattern\n * @author David Yongjun Kim (@Powerstream3604)\n */\n\nstruct MultiSigStorage {\n mapping(address => address) owners;\n mapping(uint256 => mapping(address => mapping(bytes32 => uint256))) approvedHashes;\n uint256 ownerCount;\n uint256 threshold;\n uint256 counter;\n}\n\nlibrary LibMultiSigStorage {\n function multisigStorage()\n internal\n pure\n returns (MultiSigStorage storage ds)\n {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.MultiSigStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n}\n" + }, + "contracts/libraries/LibRecoverSpender.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title RecoverSpender\n * @dev Library to determine the action and spender of calldata\n * @author Ruslan Serebriakov (@rsrbk)\n */\nlibrary LibRecoverSpender {\n // ERC20, ERC721 & ERC1155 transfers & approvals\n bytes4 private constant ERC20_TRANSFER =\n bytes4(keccak256(\"transfer(address,uint256)\"));\n bytes4 private constant ERC20_APPROVE =\n bytes4(keccak256(\"approve(address,uint256)\"));\n bytes4 private constant ERC20_INCREASE_ALLOWANCE =\n bytes4(keccak256(\"increaseAllowance(address,uint256)\"));\n bytes4 private constant ERC20_DECREASE_ALLOWANCE =\n bytes4(keccak256(\"decreaseAllowance(address,uint256)\"));\n bytes4 private constant ERC721_SET_APPROVAL_FOR_ALL =\n bytes4(keccak256(\"setApprovalForAll(address,bool)\"));\n bytes4 private constant ERC721_TRANSFER_FROM =\n bytes4(keccak256(\"transferFrom(address,address,uint256)\"));\n bytes4 private constant ERC721_SAFE_TRANSFER_FROM =\n bytes4(keccak256(\"safeTransferFrom(address,address,uint256)\"));\n bytes4 private constant ERC721_SAFE_TRANSFER_FROM_BYTES =\n bytes4(keccak256(\"safeTransferFrom(address,address,uint256,bytes)\"));\n bytes4 private constant ERC1155_SAFE_TRANSFER_FROM =\n bytes4(\n keccak256(\"safeTransferFrom(address,address,uint256,uint256,bytes)\")\n );\n bytes4 private constant ERC1155_SAFE_BATCH_TRANSFER_FROM =\n bytes4(\n keccak256(\n \"safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)\"\n )\n );\n\n /**\n * @notice Helper method to recover the spender from a contract call.\n * The method returns the contract unless the call is to a standard method of a ERC20/ERC721/ERC1155 token\n * in which case the spender is recovered from the data.\n * @param _to The target contract.\n * @param _data The data payload.\n */\n function _recover(\n address _to,\n bytes memory _data\n ) internal pure returns (address spender) {\n if (_data.length >= 68) {\n bytes4 methodId;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n methodId := mload(add(_data, 0x20))\n }\n if (\n methodId == ERC20_TRANSFER ||\n methodId == ERC20_APPROVE ||\n methodId == ERC20_INCREASE_ALLOWANCE ||\n methodId == ERC20_DECREASE_ALLOWANCE ||\n methodId == ERC721_SET_APPROVAL_FOR_ALL\n ) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n spender := mload(add(_data, 0x24))\n }\n return spender;\n }\n if (\n methodId == ERC721_TRANSFER_FROM ||\n methodId == ERC721_SAFE_TRANSFER_FROM ||\n methodId == ERC721_SAFE_TRANSFER_FROM_BYTES ||\n methodId == ERC1155_SAFE_TRANSFER_FROM ||\n methodId == ERC1155_SAFE_BATCH_TRANSFER_FROM\n ) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n spender := mload(add(_data, 0x44))\n }\n return spender;\n }\n }\n\n spender = _to;\n }\n}\n" + }, + "contracts/libraries/LibUtils.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\n\nlibrary LibUtils {\n // Internal utility functions\n function mergeArrays(\n bytes4[] memory _array1,\n bytes4[] memory _array2\n ) internal pure returns (bytes4[] memory) {\n uint256 length1 = _array1.length;\n uint256 length2 = _array2.length;\n bytes4[] memory mergedArray = new bytes4[](length1 + length2);\n\n for (uint256 i; i < length1; ) {\n mergedArray[i] = _array1[i];\n unchecked {\n ++i;\n }\n }\n\n for (uint256 i; i < length2; ) {\n mergedArray[length1 + i] = _array2[i];\n unchecked {\n ++i;\n }\n }\n\n return mergedArray;\n }\n\n function removeFacetElement(\n IDiamondLoupe.Facet[] memory _facets,\n uint256 _index\n ) internal pure returns (IDiamondLoupe.Facet[] memory) {\n require(_index < _facets.length, \"Invalid index\");\n require(_facets.length != 0, \"Invalid array\");\n\n // Create a new array with a length of `_facets.length - 1`\n IDiamondLoupe.Facet[] memory newArray = new IDiamondLoupe.Facet[](\n _facets.length - 1\n );\n uint256 newArrayLength = newArray.length;\n // Iterate over the original array, skipping the element at the specified `index`\n for (uint256 i; i < newArrayLength; ) {\n if (i < _index) {\n newArray[i] = _facets[i];\n } else {\n newArray[i] = _facets[i + 1];\n }\n unchecked {\n ++i;\n }\n }\n\n return newArray;\n }\n\n function removeElement(\n bytes4[] memory _array,\n uint256 _index\n ) internal pure returns (bytes4[] memory) {\n require(_index < _array.length, \"Invalid index\");\n require(_array.length != 0, \"Invalid array\");\n\n bytes4[] memory newArray = new bytes4[](_array.length - 1);\n uint256 newArrayLength = newArray.length;\n for (uint256 i; i < newArrayLength; ) {\n if (i < _index) {\n newArray[i] = _array[i];\n } else {\n newArray[i] = _array[i + 1];\n }\n unchecked {\n ++i;\n }\n }\n\n return newArray;\n }\n\n function setValue(\n bytes4[] memory _keys,\n address[] memory _values,\n bytes4 _key,\n address _value\n ) internal pure returns (bytes4[] memory, address[] memory) {\n uint256 index = findIndex(_keys, _key);\n uint256 keysLength = _keys.length;\n if (index < keysLength) {\n _values[index] = _value;\n } else {\n // Create new storage arrays\n bytes4[] memory newKeys = new bytes4[](keysLength + 1);\n address[] memory newValues = new address[](_values.length + 1);\n\n // Copy values to the new storage arrays\n for (uint256 i; i < keysLength; ) {\n newKeys[i] = _keys[i];\n newValues[i] = _values[i];\n\n unchecked {\n ++i;\n }\n }\n\n // Add the new key-value pair\n newKeys[keysLength] = _key;\n newValues[_values.length] = _value;\n\n return (newKeys, newValues);\n }\n\n // If the key already exists, return the original arrays\n return (_keys, _values);\n }\n\n function getValue(\n bytes4[] memory _keys,\n address[] memory _values,\n bytes4 _key\n ) internal pure returns (address) {\n uint256 index = findIndex(_keys, _key);\n if (index >= _keys.length) return address(0);\n\n return _values[index];\n }\n\n function findIndex(\n bytes4[] memory _keys,\n bytes4 _key\n ) internal pure returns (uint256) {\n uint256 keysLength = _keys.length;\n for (uint256 i; i < keysLength; ) {\n if (_keys[i] == _key) {\n return i;\n }\n unchecked {\n ++i;\n }\n }\n return keysLength;\n }\n}\n" + }, + "contracts/restrictions/IRestriction.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Interface for restrictions\n * @dev Restriction is a contract which decides whether to approve a certain kind of transaction, based on its internal logic.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface IRestriction {\n /**\n * @dev Based on restriction's internal logic, it should accept or reject a certain transaction.\n * @param from The address of the sender, that will be signing the transaction.\n * @param to The receiving address.\n * @param value Amount of ETH to transfer from sender to recipient.\n * @param _calldata Optional field to include arbitrary data.\n * @return bool value for whether the check is passed\n */\n function check(\n address from,\n address to,\n uint256 value,\n bytes calldata _calldata\n ) external returns (bool);\n}\n" + }, + "contracts/restrictions/WhitelistRestriction.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibRecoverSpender} from \"../libraries/LibRecoverSpender.sol\";\nimport {WhitelistStorage} from \"../infrastructure/WhitelistStorage.sol\";\nimport {IRestriction} from \"./IRestriction.sol\";\n\n/**\n * @title Whitelist Restriction\n * @dev This restriction defines a list of accepted addresses and denies any interaction with addresses outside of it.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract WhitelistRestriction is IRestriction {\n WhitelistStorage public immutable whitelistStorage;\n\n constructor(WhitelistStorage _whitelistStorage) {\n whitelistStorage = _whitelistStorage;\n }\n\n /**\n * @notice Helper method to recover the spender from a contract call.\n * The method returns the contract unless the call is to a standard method of a ERC20/ERC721/ERC1155 token\n * in which case the spender is recovered from the data.\n * @param _to The target contract.\n * @param _data The data payload.\n */\n function recoverSpender(\n address _to,\n bytes memory _data\n ) public pure returns (address spender) {\n return LibRecoverSpender._recover(_to, _data);\n }\n\n /*\n * @dev IRestriction's implementation. It will allow transaction if the sender is whitelisted, or user, or the whitelist storage.\n * @param _from The address of the sender, that will be signing the transaction.\n * @param _to The receiving address.\n * @param _calldata Optional field to include arbitrary data.\n * @return result value for whether the check is passed\n */\n function check(\n address _from,\n address _to,\n uint256 /*_value*/,\n bytes calldata _calldata\n ) external view override returns (bool result) {\n return\n whitelistStorage.isWhitelisted(\n _from,\n LibRecoverSpender._recover(_to, _calldata)\n ) ||\n _to == address(whitelistStorage) ||\n _to == msg.sender;\n }\n}\n" + }, + "contracts/test/Counter.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\ncontract TestCounter {\n int private count = 0;\n\n function incrementCounter() public {\n count += 1;\n }\n\n function decrementCounter() public {\n count -= 1;\n }\n\n function getCount() public view returns (int) {\n return count;\n }\n}\n" + }, + "contracts/test/TestERC1155.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC1155/ERC1155.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\n\ncontract TestERC1155 is ERC1155 {\n using Counters for Counters.Counter;\n\n Counters.Counter private _tokenIds;\n\n constructor() ERC1155(\"\") {}\n\n function mint(address account, uint256 amount) external {\n uint256 tokenId = _getNextTokenId();\n _mint(account, tokenId, amount, \"\");\n }\n\n function mintBatch(\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes memory data\n ) external {\n require(\n ids.length == amounts.length,\n \"TestERC1155: arrays length mismatch\"\n );\n\n _mintBatch(to, ids, amounts, data);\n }\n\n function _getNextTokenId() private returns (uint256) {\n _tokenIds.increment();\n return _tokenIds.current();\n }\n}\n" + }, + "contracts/test/TestERC777.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC777/ERC777.sol\";\n\ncontract TestERC777 is ERC777 {\n constructor(\n address[] memory _operators\n ) ERC777(\"TestERC777\", \"TERC777\", _operators) {}\n\n function mint(address account, uint256 amount) external {\n _mint(account, amount, \"\", \"\");\n }\n}\n" + }, + "contracts/test/TestInvalidSecp256k1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IVerificationFacet} from \"../facets/interfaces/IVerificationFacet.sol\";\nimport {IERC1271} from \"../interfaces/ERC/IERC1271.sol\";\nimport {AppStorage, LibAppStorage, BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {LibFacetStorage, Secp256k1VerificationStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {UserOperation} from \"../aa-4337/interfaces/UserOperation.sol\";\n\n/**\n * @title Test Secp256k1 verification facet\n * @dev Default Ethereum's elliptic curve\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract TestInvalidSecp256k1VerificationFacet is BarzStorage, IERC1271 {\n using ECDSA for bytes32;\n error Secp256k1VerificationFacet__InvalidSignerLength();\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n\n event SignerUninitialized();\n\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n }\n\n // THIS INVALID FACET DOES NOT INCLUDE initializeSigner()\n // THIS FACET IS USED TO TEST WHEN initializeSigner() DOESN'T EXIST IN FACET\n\n function uninitializeSigner() external returns (uint256 uninitSuccess) {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view returns (uint256 validationData) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n return validateSignature(userOp, userOpHash, k1Storage.signer);\n }\n\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n address signer\n ) public pure returns (uint256) {\n bytes32 hash = userOpHash.toEthSignedMessageHash();\n if (signer != hash.recover(userOp.signature)) return 1;\n return 0;\n }\n\n // This is REMOVED for testing purpose\n function validateOwnerSignatureSelector() public pure returns (bytes4) {\n // return this.validateOwnerSignature.selector;\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n function owner() public view returns (bytes memory) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n return abi.encodePacked(k1Storage.signer);\n }\n\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure returns (bool) {\n return (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (_hash.recover(_signature) ==\n LibFacetStorage.k1Storage().signer)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n}\n" + }, + "contracts/test/TestNFT.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\n\ncontract TestNFT is ERC721 {\n using Counters for Counters.Counter;\n Counters.Counter private currentTokenId;\n\n constructor() ERC721(\"TestNFT\", \"TNFT\") {}\n\n function mint(address recipient) public returns (uint256) {\n currentTokenId.increment();\n uint256 newItemId = currentTokenId.current();\n _safeMint(recipient, newItemId);\n return newItemId;\n }\n}\n" + }, + "contracts/test/TestToken.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract TestToken is ERC20 {\n constructor()\n // solhint-disable-next-line no-empty-blocks\n ERC20(\"TST\", \"TestToken\")\n {}\n\n function mint(address sender, uint256 amount) external {\n _mint(sender, amount);\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 999999 + }, + "evmVersion": "paris", + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/deployments/polygon/solcInputs/167a830377988095f5f829bf03425fb0.json b/deployments/polygon/solcInputs/167a830377988095f5f829bf03425fb0.json new file mode 100644 index 0000000..2833a16 --- /dev/null +++ b/deployments/polygon/solcInputs/167a830377988095f5f829bf03425fb0.json @@ -0,0 +1,354 @@ +{ + "language": "Solidity", + "sources": { + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby disabling any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable2Step.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./Ownable.sol\";\n\n/**\n * @dev Contract module which provides access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership} and {acceptOwnership}.\n *\n * This module is used through inheritance. It will make available all functions\n * from parent (Ownable).\n */\nabstract contract Ownable2Step is Ownable {\n address private _pendingOwner;\n\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Returns the address of the pending owner.\n */\n function pendingOwner() public view virtual returns (address) {\n return _pendingOwner;\n }\n\n /**\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual override onlyOwner {\n _pendingOwner = newOwner;\n emit OwnershipTransferStarted(owner(), newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual override {\n delete _pendingOwner;\n super._transferOwnership(newOwner);\n }\n\n /**\n * @dev The new owner accepts the ownership transfer.\n */\n function acceptOwnership() public virtual {\n address sender = _msgSender();\n require(pendingOwner() == sender, \"Ownable2Step: caller is not the new owner\");\n _transferOwnership(sender);\n }\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC1271.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC1271 standard signature validation method for\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\n *\n * _Available since v4.1._\n */\ninterface IERC1271 {\n /**\n * @dev Should return whether the signature provided is valid for the provided data\n * @param hash Hash of the data to be signed\n * @param signature Signature byte array associated with _data\n */\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\n}\n" + }, + "@openzeppelin/contracts/security/ReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor() {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n _nonReentrantBefore();\n _;\n _nonReentrantAfter();\n }\n\n function _nonReentrantBefore() private {\n // On the first call to nonReentrant, _status will be _NOT_ENTERED\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n }\n\n function _nonReentrantAfter() private {\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Returns true if the reentrancy guard is currently set to \"entered\", which indicates there is a\n * `nonReentrant` function in the call stack.\n */\n function _reentrancyGuardEntered() internal view returns (bool) {\n return _status == _ENTERED;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/ERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/ERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC1155.sol\";\nimport \"./IERC1155Receiver.sol\";\nimport \"./extensions/IERC1155MetadataURI.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of the basic standard multi-token.\n * See https://eips.ethereum.org/EIPS/eip-1155\n * Originally based on code by Enjin: https://github.com/enjin/erc-1155\n *\n * _Available since v3.1._\n */\ncontract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {\n using Address for address;\n\n // Mapping from token ID to account balances\n mapping(uint256 => mapping(address => uint256)) private _balances;\n\n // Mapping from account to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json\n string private _uri;\n\n /**\n * @dev See {_setURI}.\n */\n constructor(string memory uri_) {\n _setURI(uri_);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return\n interfaceId == type(IERC1155).interfaceId ||\n interfaceId == type(IERC1155MetadataURI).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC1155MetadataURI-uri}.\n *\n * This implementation returns the same URI for *all* token types. It relies\n * on the token type ID substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * Clients calling this function must replace the `\\{id\\}` substring with the\n * actual token type ID.\n */\n function uri(uint256) public view virtual override returns (string memory) {\n return _uri;\n }\n\n /**\n * @dev See {IERC1155-balanceOf}.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {\n require(account != address(0), \"ERC1155: address zero is not a valid owner\");\n return _balances[id][account];\n }\n\n /**\n * @dev See {IERC1155-balanceOfBatch}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] memory accounts,\n uint256[] memory ids\n ) public view virtual override returns (uint256[] memory) {\n require(accounts.length == ids.length, \"ERC1155: accounts and ids length mismatch\");\n\n uint256[] memory batchBalances = new uint256[](accounts.length);\n\n for (uint256 i = 0; i < accounts.length; ++i) {\n batchBalances[i] = balanceOf(accounts[i], ids[i]);\n }\n\n return batchBalances;\n }\n\n /**\n * @dev See {IERC1155-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC1155-isApprovedForAll}.\n */\n function isApprovedForAll(address account, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[account][operator];\n }\n\n /**\n * @dev See {IERC1155-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n _safeTransferFrom(from, to, id, amount, data);\n }\n\n /**\n * @dev See {IERC1155-safeBatchTransferFrom}.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n _safeBatchTransferFrom(from, to, ids, amounts, data);\n }\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n\n emit TransferSingle(operator, from, to, id, amount);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n for (uint256 i = 0; i < ids.length; ++i) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n }\n\n emit TransferBatch(operator, from, to, ids, amounts);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\n\n _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);\n }\n\n /**\n * @dev Sets a new URI for all token types, by relying on the token type ID\n * substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * By this mechanism, any occurrence of the `\\{id\\}` substring in either the\n * URI or any of the amounts in the JSON file at said URI will be replaced by\n * clients with the token type ID.\n *\n * For example, the `https://token-cdn-domain/\\{id\\}.json` URI would be\n * interpreted by clients as\n * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`\n * for token type ID 0x4cce0.\n *\n * See {uri}.\n *\n * Because these URIs cannot be meaningfully represented by the {URI} event,\n * this function emits no events.\n */\n function _setURI(string memory newuri) internal virtual {\n _uri = newuri;\n }\n\n /**\n * @dev Creates `amount` tokens of token type `id`, and assigns them to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _mint(address to, uint256 id, uint256 amount, bytes memory data) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _balances[id][to] += amount;\n emit TransferSingle(operator, address(0), to, id, amount);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n for (uint256 i = 0; i < ids.length; i++) {\n _balances[ids[i]][to] += amounts[i];\n }\n\n emit TransferBatch(operator, address(0), to, ids, amounts);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);\n }\n\n /**\n * @dev Destroys `amount` tokens of token type `id` from `from`\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `from` must have at least `amount` tokens of token type `id`.\n */\n function _burn(address from, uint256 id, uint256 amount) internal virtual {\n require(from != address(0), \"ERC1155: burn from the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n\n emit TransferSingle(operator, from, address(0), id, amount);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n */\n function _burnBatch(address from, uint256[] memory ids, uint256[] memory amounts) internal virtual {\n require(from != address(0), \"ERC1155: burn from the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n\n for (uint256 i = 0; i < ids.length; i++) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n }\n\n emit TransferBatch(operator, from, address(0), ids, amounts);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {\n require(owner != operator, \"ERC1155: setting approval status for self\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning, as well as batched variants.\n *\n * The same hook is called on both single and batched variants. For single\n * transfers, the length of the `ids` and `amounts` arrays will be 1.\n *\n * Calling conditions (for each `id` and `amount` pair):\n *\n * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * of token type `id` will be transferred to `to`.\n * - When `from` is zero, `amount` tokens of token type `id` will be minted\n * for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n * will be burned.\n * - `from` and `to` are never both zero.\n * - `ids` and `amounts` have the same, non-zero length.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any token transfer. This includes minting\n * and burning, as well as batched variants.\n *\n * The same hook is called on both single and batched variants. For single\n * transfers, the length of the `id` and `amount` arrays will be 1.\n *\n * Calling conditions (for each `id` and `amount` pair):\n *\n * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * of token type `id` will be transferred to `to`.\n * - When `from` is zero, `amount` tokens of token type `id` will be minted\n * for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n * will be burned.\n * - `from` and `to` are never both zero.\n * - `ids` and `amounts` have the same, non-zero length.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {}\n\n function _doSafeTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155Receiver.onERC1155Received.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non-ERC1155Receiver implementer\");\n }\n }\n }\n\n function _doSafeBatchTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (\n bytes4 response\n ) {\n if (response != IERC1155Receiver.onERC1155BatchReceived.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non-ERC1155Receiver implementer\");\n }\n }\n }\n\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {\n uint256[] memory array = new uint256[](1);\n array[0] = element;\n\n return array;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC1155.sol\";\n\n/**\n * @dev Interface of the optional ERC1155MetadataExtension interface, as defined\n * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155MetadataURI is IERC1155 {\n /**\n * @dev Returns the URI for token type `id`.\n *\n * If the `\\{id\\}` substring is present in the URI, it must be replaced by\n * clients with the actual token type ID.\n */\n function uri(uint256 id) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155 is IERC165 {\n /**\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n */\n event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);\n\n /**\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n * transfers.\n */\n event TransferBatch(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\n\n /**\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n * `approved`.\n */\n event ApprovalForAll(address indexed account, address indexed operator, bool approved);\n\n /**\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n *\n * If an {URI} event was emitted for `id`, the standard\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n * returned by {IERC1155MetadataURI-uri}.\n */\n event URI(string value, uint256 indexed id);\n\n /**\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) external view returns (uint256);\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] calldata accounts,\n uint256[] calldata ids\n ) external view returns (uint256[] memory);\n\n /**\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n *\n * Emits an {ApprovalForAll} event.\n *\n * Requirements:\n *\n * - `operator` cannot be the caller.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n *\n * See {setApprovalForAll}.\n */\n function isApprovedForAll(address account, address operator) external view returns (bool);\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155Receiver is IERC165 {\n /**\n * @dev Handles the receipt of a single ERC1155 token type. This function is\n * called at the end of a `safeTransferFrom` after the balance has been updated.\n *\n * NOTE: To accept the transfer, this must return\n * `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n * (i.e. 0xf23a6e61, or its own function selector).\n *\n * @param operator The address which initiated the transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param id The ID of the token being transferred\n * @param value The amount of tokens being transferred\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n ) external returns (bytes4);\n\n /**\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\n * is called at the end of a `safeBatchTransferFrom` after the balances have\n * been updated.\n *\n * NOTE: To accept the transfer(s), this must return\n * `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n * (i.e. 0xbc197c81, or its own function selector).\n *\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the default value returned by this function, unless\n * it's overridden.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(address from, address to, uint256 amount) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\n // decrementing then incrementing.\n _balances[to] += amount;\n }\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n unchecked {\n // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\n _balances[account] += amount;\n }\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n // Overflow not possible: amount <= accountBalance <= totalSupply.\n _totalSupply -= amount;\n }\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\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" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` 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 amount) 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 `amount` as the allowance of `spender` over the 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 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` 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 amount) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/ERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721.sol\";\nimport \"./IERC721Receiver.sol\";\nimport \"./extensions/IERC721Metadata.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/Strings.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\n using Address for address;\n using Strings for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\n\n // Mapping from token ID to approved address\n mapping(uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return\n interfaceId == type(IERC721).interfaceId ||\n interfaceId == type(IERC721Metadata).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _ownerOf(tokenId);\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token owner or approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n _requireMinted(tokenId);\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n _safeTransfer(from, to, tokenId, data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(address from, address to, uint256 tokenId, bytes memory data) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist\n */\n function _ownerOf(uint256 tokenId) internal view virtual returns (address) {\n return _owners[tokenId];\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _ownerOf(tokenId) != address(0);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n address owner = ERC721.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(address to, uint256 tokenId, bytes memory data) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId, 1);\n\n // Check that tokenId was not minted by `_beforeTokenTransfer` hook\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n unchecked {\n // Will not overflow unless all 2**256 token ids are minted to the same owner.\n // Given that tokens are minted one by one, it is impossible in practice that\n // this ever happens. Might change if we allow batch minting.\n // The ERC fails to describe this case.\n _balances[to] += 1;\n }\n\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(address(0), to, tokenId, 1);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n * This is an internal function that does not check if the sender is authorized to operate on the token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId, 1);\n\n // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook\n owner = ERC721.ownerOf(tokenId);\n\n // Clear approvals\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // Cannot overflow, as that would require more tokens to be burned/transferred\n // out than the owner initially received through minting and transferring in.\n _balances[owner] -= 1;\n }\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(owner, address(0), tokenId, 1);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(address from, address to, uint256 tokenId) internal virtual {\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId, 1);\n\n // Check that tokenId was not transferred by `_beforeTokenTransfer` hook\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n\n // Clear approvals from the previous owner\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // `_balances[from]` cannot overflow for the same reason as described in `_burn`:\n // `from`'s balance is the number of token held, which is at least one before the current\n // transfer.\n // `_balances[to]` could overflow in the conditions described in `_mint`. That would require\n // all 2**256 token ids to be minted, which in practice is impossible.\n _balances[from] -= 1;\n _balances[to] += 1;\n }\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId, 1);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721Receiver.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`.\n * - When `from` is zero, the tokens will be minted for `to`.\n * - When `to` is zero, ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}\n\n /**\n * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`.\n * - When `from` is zero, the tokens were minted for `to`.\n * - When `to` is zero, ``from``'s tokens were burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}\n\n /**\n * @dev Unsafe write access to the balances, used by extensions that \"mint\" tokens using an {ownerOf} override.\n *\n * WARNING: Anyone calling this MUST ensure that the balances remain consistent with the ownership. The invariant\n * being that for any address `a` the value returned by `balanceOf(a)` must be equal to the number of tokens such\n * that `ownerOf(tokenId)` is `a`.\n */\n // solhint-disable-next-line func-name-mixedcase\n function __unsafe_increaseBalance(address account, uint256 amount) internal {\n _balances[account] += amount;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721Receiver {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/ERC777.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC777/ERC777.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC777.sol\";\nimport \"./IERC777Recipient.sol\";\nimport \"./IERC777Sender.sol\";\nimport \"../ERC20/IERC20.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/introspection/IERC1820Registry.sol\";\n\n/**\n * @dev Implementation of the {IERC777} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n *\n * Support for ERC20 is included in this contract, as specified by the EIP: both\n * the ERC777 and ERC20 interfaces can be safely used when interacting with it.\n * Both {IERC777-Sent} and {IERC20-Transfer} events are emitted on token\n * movements.\n *\n * Additionally, the {IERC777-granularity} value is hard-coded to `1`, meaning that there\n * are no special restrictions in the amount of tokens that created, moved, or\n * destroyed. This makes integration with ERC20 applications seamless.\n *\n * CAUTION: This file is deprecated as of v4.9 and will be removed in the next major release.\n */\ncontract ERC777 is Context, IERC777, IERC20 {\n using Address for address;\n\n IERC1820Registry internal constant _ERC1820_REGISTRY = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n mapping(address => uint256) private _balances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n bytes32 private constant _TOKENS_SENDER_INTERFACE_HASH = keccak256(\"ERC777TokensSender\");\n bytes32 private constant _TOKENS_RECIPIENT_INTERFACE_HASH = keccak256(\"ERC777TokensRecipient\");\n\n // This isn't ever read from - it's only used to respond to the defaultOperators query.\n address[] private _defaultOperatorsArray;\n\n // Immutable, but accounts may revoke them (tracked in __revokedDefaultOperators).\n mapping(address => bool) private _defaultOperators;\n\n // For each account, a mapping of its operators and revoked default operators.\n mapping(address => mapping(address => bool)) private _operators;\n mapping(address => mapping(address => bool)) private _revokedDefaultOperators;\n\n // ERC20-allowances\n mapping(address => mapping(address => uint256)) private _allowances;\n\n /**\n * @dev `defaultOperators` may be an empty array.\n */\n constructor(string memory name_, string memory symbol_, address[] memory defaultOperators_) {\n _name = name_;\n _symbol = symbol_;\n\n _defaultOperatorsArray = defaultOperators_;\n for (uint256 i = 0; i < defaultOperators_.length; i++) {\n _defaultOperators[defaultOperators_[i]] = true;\n }\n\n // register interfaces\n _ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256(\"ERC777Token\"), address(this));\n _ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256(\"ERC20Token\"), address(this));\n }\n\n /**\n * @dev See {IERC777-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC777-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {ERC20-decimals}.\n *\n * Always returns 18, as per the\n * [ERC777 EIP](https://eips.ethereum.org/EIPS/eip-777#backward-compatibility).\n */\n function decimals() public pure virtual returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC777-granularity}.\n *\n * This implementation always returns `1`.\n */\n function granularity() public view virtual override returns (uint256) {\n return 1;\n }\n\n /**\n * @dev See {IERC777-totalSupply}.\n */\n function totalSupply() public view virtual override(IERC20, IERC777) returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev Returns the amount of tokens owned by an account (`tokenHolder`).\n */\n function balanceOf(address tokenHolder) public view virtual override(IERC20, IERC777) returns (uint256) {\n return _balances[tokenHolder];\n }\n\n /**\n * @dev See {IERC777-send}.\n *\n * Also emits a {IERC20-Transfer} event for ERC20 compatibility.\n */\n function send(address recipient, uint256 amount, bytes memory data) public virtual override {\n _send(_msgSender(), recipient, amount, data, \"\", true);\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Unlike `send`, `recipient` is _not_ required to implement the {IERC777Recipient}\n * interface if it is a contract.\n *\n * Also emits a {Sent} event.\n */\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n _send(_msgSender(), recipient, amount, \"\", \"\", false);\n return true;\n }\n\n /**\n * @dev See {IERC777-burn}.\n *\n * Also emits a {IERC20-Transfer} event for ERC20 compatibility.\n */\n function burn(uint256 amount, bytes memory data) public virtual override {\n _burn(_msgSender(), amount, data, \"\");\n }\n\n /**\n * @dev See {IERC777-isOperatorFor}.\n */\n function isOperatorFor(address operator, address tokenHolder) public view virtual override returns (bool) {\n return\n operator == tokenHolder ||\n (_defaultOperators[operator] && !_revokedDefaultOperators[tokenHolder][operator]) ||\n _operators[tokenHolder][operator];\n }\n\n /**\n * @dev See {IERC777-authorizeOperator}.\n */\n function authorizeOperator(address operator) public virtual override {\n require(_msgSender() != operator, \"ERC777: authorizing self as operator\");\n\n if (_defaultOperators[operator]) {\n delete _revokedDefaultOperators[_msgSender()][operator];\n } else {\n _operators[_msgSender()][operator] = true;\n }\n\n emit AuthorizedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-revokeOperator}.\n */\n function revokeOperator(address operator) public virtual override {\n require(operator != _msgSender(), \"ERC777: revoking self as operator\");\n\n if (_defaultOperators[operator]) {\n _revokedDefaultOperators[_msgSender()][operator] = true;\n } else {\n delete _operators[_msgSender()][operator];\n }\n\n emit RevokedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-defaultOperators}.\n */\n function defaultOperators() public view virtual override returns (address[] memory) {\n return _defaultOperatorsArray;\n }\n\n /**\n * @dev See {IERC777-operatorSend}.\n *\n * Emits {Sent} and {IERC20-Transfer} events.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes memory data,\n bytes memory operatorData\n ) public virtual override {\n require(isOperatorFor(_msgSender(), sender), \"ERC777: caller is not an operator for holder\");\n _send(sender, recipient, amount, data, operatorData, true);\n }\n\n /**\n * @dev See {IERC777-operatorBurn}.\n *\n * Emits {Burned} and {IERC20-Transfer} events.\n */\n function operatorBurn(\n address account,\n uint256 amount,\n bytes memory data,\n bytes memory operatorData\n ) public virtual override {\n require(isOperatorFor(_msgSender(), account), \"ERC777: caller is not an operator for holder\");\n _burn(account, amount, data, operatorData);\n }\n\n /**\n * @dev See {IERC20-allowance}.\n *\n * Note that operator and allowance concepts are orthogonal: operators may\n * not have allowance, and accounts with allowance may not be operators\n * themselves.\n */\n function allowance(address holder, address spender) public view virtual override returns (uint256) {\n return _allowances[holder][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Note that accounts cannot have allowance issued by their operators.\n */\n function approve(address spender, uint256 value) public virtual override returns (bool) {\n address holder = _msgSender();\n _approve(holder, spender, value);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Note that operator and allowance concepts are orthogonal: operators cannot\n * call `transferFrom` (unless they have allowance), and accounts with\n * allowance cannot call `operatorSend` (unless they are operators).\n *\n * Emits {Sent}, {IERC20-Transfer} and {IERC20-Approval} events.\n */\n function transferFrom(address holder, address recipient, uint256 amount) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(holder, spender, amount);\n _send(holder, recipient, amount, \"\", \"\", false);\n return true;\n }\n\n /**\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with the caller address as the `operator` and with\n * `userData` and `operatorData`.\n *\n * See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits {Minted} and {IERC20-Transfer} events.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - if `account` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function _mint(address account, uint256 amount, bytes memory userData, bytes memory operatorData) internal virtual {\n _mint(account, amount, userData, operatorData, true);\n }\n\n /**\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * If `requireReceptionAck` is set to true, and if a send hook is\n * registered for `account`, the corresponding function will be called with\n * `operator`, `data` and `operatorData`.\n *\n * See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits {Minted} and {IERC20-Transfer} events.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - if `account` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function _mint(\n address account,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) internal virtual {\n require(account != address(0), \"ERC777: mint to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), account, amount);\n\n // Update state variables\n _totalSupply += amount;\n _balances[account] += amount;\n\n _callTokensReceived(operator, address(0), account, amount, userData, operatorData, requireReceptionAck);\n\n emit Minted(operator, account, amount, userData, operatorData);\n emit Transfer(address(0), account, amount);\n }\n\n /**\n * @dev Send tokens\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _send(\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) internal virtual {\n require(from != address(0), \"ERC777: transfer from the zero address\");\n require(to != address(0), \"ERC777: transfer to the zero address\");\n\n address operator = _msgSender();\n\n _callTokensToSend(operator, from, to, amount, userData, operatorData);\n\n _move(operator, from, to, amount, userData, operatorData);\n\n _callTokensReceived(operator, from, to, amount, userData, operatorData, requireReceptionAck);\n }\n\n /**\n * @dev Burn tokens\n * @param from address token holder address\n * @param amount uint256 amount of tokens to burn\n * @param data bytes extra information provided by the token holder\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _burn(address from, uint256 amount, bytes memory data, bytes memory operatorData) internal virtual {\n require(from != address(0), \"ERC777: burn from the zero address\");\n\n address operator = _msgSender();\n\n _callTokensToSend(operator, from, address(0), amount, data, operatorData);\n\n _beforeTokenTransfer(operator, from, address(0), amount);\n\n // Update state variables\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC777: burn amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Burned(operator, from, amount, data, operatorData);\n emit Transfer(from, address(0), amount);\n }\n\n function _move(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n ) private {\n _beforeTokenTransfer(operator, from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC777: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Sent(operator, from, to, amount, userData, operatorData);\n emit Transfer(from, to, amount);\n }\n\n /**\n * @dev See {ERC20-_approve}.\n *\n * Note that accounts cannot have allowance issued by their operators.\n */\n function _approve(address holder, address spender, uint256 value) internal virtual {\n require(holder != address(0), \"ERC777: approve from the zero address\");\n require(spender != address(0), \"ERC777: approve to the zero address\");\n\n _allowances[holder][spender] = value;\n emit Approval(holder, spender, value);\n }\n\n /**\n * @dev Call from.tokensToSend() if the interface is registered\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _callTokensToSend(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n ) private {\n address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(from, _TOKENS_SENDER_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Sender(implementer).tokensToSend(operator, from, to, amount, userData, operatorData);\n }\n }\n\n /**\n * @dev Call to.tokensReceived() if the interface is registered. Reverts if the recipient is a contract but\n * tokensReceived() was not registered for the recipient\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _callTokensReceived(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) private {\n address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(to, _TOKENS_RECIPIENT_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Recipient(implementer).tokensReceived(operator, from, to, amount, userData, operatorData);\n } else if (requireReceptionAck) {\n require(!to.isContract(), \"ERC777: token recipient contract has no implementer for ERC777TokensRecipient\");\n }\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {IERC20-Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC777: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes\n * calls to {send}, {transfer}, {operatorSend}, {transferFrom}, minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be to transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address operator, address from, address to, uint256 amount) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC777/IERC777.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777Token standard as defined in the EIP.\n *\n * This contract uses the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 registry standard] to let\n * token holders and recipients react to token movements by using setting implementers\n * for the associated interfaces in said registry. See {IERC1820Registry} and\n * {ERC1820Implementer}.\n */\ninterface IERC777 {\n /**\n * @dev Emitted when `amount` tokens are created by `operator` and assigned to `to`.\n *\n * Note that some additional user `data` and `operatorData` can be logged in the event.\n */\n event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);\n\n /**\n * @dev Emitted when `operator` destroys `amount` tokens from `account`.\n *\n * Note that some additional user `data` and `operatorData` can be logged in the event.\n */\n event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);\n\n /**\n * @dev Emitted when `operator` is made operator for `tokenHolder`.\n */\n event AuthorizedOperator(address indexed operator, address indexed tokenHolder);\n\n /**\n * @dev Emitted when `operator` is revoked its operator status for `tokenHolder`.\n */\n event RevokedOperator(address indexed operator, address indexed tokenHolder);\n\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, usually a shorter version of the\n * name.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the smallest part of the token that is not divisible. This\n * means all token operations (creation, movement and destruction) must have\n * amounts that are a multiple of this number.\n *\n * For most token contracts, this value will equal 1.\n */\n function granularity() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by an account (`owner`).\n */\n function balanceOf(address owner) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * If send or receive hooks are registered for the caller and `recipient`,\n * the corresponding functions will be called with `data` and empty\n * `operatorData`. See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits a {Sent} event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function send(address recipient, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Destroys `amount` tokens from the caller's account, reducing the\n * total supply.\n *\n * If a send hook is registered for the caller, the corresponding function\n * will be called with `data` and empty `operatorData`. See {IERC777Sender}.\n *\n * Emits a {Burned} event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n */\n function burn(uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Returns true if an account is an operator of `tokenHolder`.\n * Operators can send and burn tokens on behalf of their owners. All\n * accounts are their own operator.\n *\n * See {operatorSend} and {operatorBurn}.\n */\n function isOperatorFor(address operator, address tokenHolder) external view returns (bool);\n\n /**\n * @dev Make an account an operator of the caller.\n *\n * See {isOperatorFor}.\n *\n * Emits an {AuthorizedOperator} event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function authorizeOperator(address operator) external;\n\n /**\n * @dev Revoke an account's operator status for the caller.\n *\n * See {isOperatorFor} and {defaultOperators}.\n *\n * Emits a {RevokedOperator} event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function revokeOperator(address operator) external;\n\n /**\n * @dev Returns the list of default operators. These accounts are operators\n * for all token holders, even if {authorizeOperator} was never called on\n * them.\n *\n * This list is immutable, but individual holders may revoke these via\n * {revokeOperator}, in which case {isOperatorFor} will return false.\n */\n function defaultOperators() external view returns (address[] memory);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must\n * be an operator of `sender`.\n *\n * If send or receive hooks are registered for `sender` and `recipient`,\n * the corresponding functions will be called with `data` and\n * `operatorData`. See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits a {Sent} event.\n *\n * Requirements\n *\n * - `sender` cannot be the zero address.\n * - `sender` must have at least `amount` tokens.\n * - the caller must be an operator for `sender`.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes calldata data,\n bytes calldata operatorData\n ) external;\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the total supply.\n * The caller must be an operator of `account`.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with `data` and `operatorData`. See {IERC777Sender}.\n *\n * Emits a {Burned} event.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n * - the caller must be an operator for `account`.\n */\n function operatorBurn(address account, uint256 amount, bytes calldata data, bytes calldata operatorData) external;\n\n event Sent(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes data,\n bytes operatorData\n );\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\n *\n * Accounts can be notified of {IERC777} tokens being sent to them by having a\n * contract implement this interface (contract holders can be their own\n * implementer) and registering it on the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\n *\n * See {IERC1820Registry} and {ERC1820Implementer}.\n */\ninterface IERC777Recipient {\n /**\n * @dev Called by an {IERC777} token contract whenever tokens are being\n * moved or created into a registered account (`to`). The type of operation\n * is conveyed by `from` being the zero address or not.\n *\n * This call occurs _after_ the token contract's state is updated, so\n * {IERC777-balanceOf}, etc., can be used to query the post-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensReceived(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777Sender.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Sender.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777TokensSender standard as defined in the EIP.\n *\n * {IERC777} Token holders can be notified of operations performed on their\n * tokens by having a contract implement this interface (contract holders can be\n * their own implementer) and registering it on the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\n *\n * See {IERC1820Registry} and {ERC1820Implementer}.\n */\ninterface IERC777Sender {\n /**\n * @dev Called by an {IERC777} token contract whenever a registered holder's\n * (`from`) tokens are about to be moved or destroyed. The type of operation\n * is conveyed by `to` being the zero address or not.\n *\n * This call occurs _before_ the token contract's state is updated, so\n * {IERC777-balanceOf}, etc., can be used to query the pre-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensToSend(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n *\n * Furthermore, `isContract` will also return true if the target contract within\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n * which only has an effect at the end of a transaction.\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Counters.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary Counters {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/ECDSA.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Strings.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV // Deprecated in v4.8\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n /// @solidity memory-safe-assembly\n assembly {\n mstore(0x00, \"\\x19Ethereum Signed Message:\\n32\")\n mstore(0x1c, hash)\n message := keccak256(0x00, 0x3c)\n }\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\n /// @solidity memory-safe-assembly\n assembly {\n let ptr := mload(0x40)\n mstore(ptr, \"\\x19\\x01\")\n mstore(add(ptr, 0x02), domainSeparator)\n mstore(add(ptr, 0x22), structHash)\n data := keccak256(ptr, 0x42)\n }\n }\n\n /**\n * @dev Returns an Ethereum Signed Data with intended validator, created from a\n * `validator` and `data` according to the version 0 of EIP-191.\n *\n * See {recover}.\n */\n function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x00\", validator, data));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/SignatureChecker.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSA.sol\";\nimport \"../../interfaces/IERC1271.sol\";\n\n/**\n * @dev Signature verification helper that can be used instead of `ECDSA.recover` to seamlessly support both ECDSA\n * signatures from externally owned accounts (EOAs) as well as ERC1271 signatures from smart contract wallets like\n * Argent and Gnosis Safe.\n *\n * _Available since v4.1._\n */\nlibrary SignatureChecker {\n /**\n * @dev Checks if a signature is valid for a given signer and data hash. If the signer is a smart contract, the\n * signature is validated against that smart contract using ERC1271, otherwise it's validated using `ECDSA.recover`.\n *\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\n */\n function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature) internal view returns (bool) {\n (address recovered, ECDSA.RecoverError error) = ECDSA.tryRecover(hash, signature);\n return\n (error == ECDSA.RecoverError.NoError && recovered == signer) ||\n isValidERC1271SignatureNow(signer, hash, signature);\n }\n\n /**\n * @dev Checks if a signature is valid for a given signer and data hash. The signature is validated\n * against the signer smart contract using ERC1271.\n *\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\n */\n function isValidERC1271SignatureNow(\n address signer,\n bytes32 hash,\n bytes memory signature\n ) internal view returns (bool) {\n (bool success, bytes memory result) = signer.staticcall(\n abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, signature)\n );\n return (success &&\n result.length >= 32 &&\n abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/ERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165 is IERC165 {\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165).interfaceId;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC1820Registry.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/introspection/IERC1820Registry.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the global ERC1820 Registry, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register\n * implementers for interfaces in this registry, as well as query support.\n *\n * Implementers may be shared by multiple accounts, and can also implement more\n * than a single interface for each account. Contracts can implement interfaces\n * for themselves, but externally-owned accounts (EOA) must delegate this to a\n * contract.\n *\n * {IERC165} interfaces can also be queried via the registry.\n *\n * For an in-depth explanation and source code analysis, see the EIP text.\n */\ninterface IERC1820Registry {\n event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer);\n\n event ManagerChanged(address indexed account, address indexed newManager);\n\n /**\n * @dev Sets `newManager` as the manager for `account`. A manager of an\n * account is able to set interface implementers for it.\n *\n * By default, each account is its own manager. Passing a value of `0x0` in\n * `newManager` will reset the manager to this initial state.\n *\n * Emits a {ManagerChanged} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `account`.\n */\n function setManager(address account, address newManager) external;\n\n /**\n * @dev Returns the manager for `account`.\n *\n * See {setManager}.\n */\n function getManager(address account) external view returns (address);\n\n /**\n * @dev Sets the `implementer` contract as ``account``'s implementer for\n * `interfaceHash`.\n *\n * `account` being the zero address is an alias for the caller's address.\n * The zero address can also be used in `implementer` to remove an old one.\n *\n * See {interfaceHash} to learn how these are created.\n *\n * Emits an {InterfaceImplementerSet} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `account`.\n * - `interfaceHash` must not be an {IERC165} interface id (i.e. it must not\n * end in 28 zeroes).\n * - `implementer` must implement {IERC1820Implementer} and return true when\n * queried for support, unless `implementer` is the caller. See\n * {IERC1820Implementer-canImplementInterfaceForAddress}.\n */\n function setInterfaceImplementer(address account, bytes32 _interfaceHash, address implementer) external;\n\n /**\n * @dev Returns the implementer of `interfaceHash` for `account`. If no such\n * implementer is registered, returns the zero address.\n *\n * If `interfaceHash` is an {IERC165} interface id (i.e. it ends with 28\n * zeroes), `account` will be queried for support of it.\n *\n * `account` being the zero address is an alias for the caller's address.\n */\n function getInterfaceImplementer(address account, bytes32 _interfaceHash) external view returns (address);\n\n /**\n * @dev Returns the interface hash for an `interfaceName`, as defined in the\n * corresponding\n * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP].\n */\n function interfaceHash(string calldata interfaceName) external pure returns (bytes32);\n\n /**\n * @notice Updates the cache with whether the contract implements an ERC165 interface or not.\n * @param account Address of the contract for which to update the cache.\n * @param interfaceId ERC165 interface for which to update the cache.\n */\n function updateERC165Cache(address account, bytes4 interfaceId) external;\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not.\n * If the result is not cached a direct lookup on the contract address is performed.\n * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling\n * {updateERC165Cache} with the contract address.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool);\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not without using or updating the cache.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/math/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\n // The surrounding unchecked block does not change this fact.\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1, \"Math: mulDiv overflow\");\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n //\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n //\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n //\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1 << (log2(a) >> 1);\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = sqrt(a);\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 2, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 128;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 64;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 32;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 16;\n }\n if (value >> 8 > 0) {\n value >>= 8;\n result += 8;\n }\n if (value >> 4 > 0) {\n value >>= 4;\n result += 4;\n }\n if (value >> 2 > 0) {\n value >>= 2;\n result += 2;\n }\n if (value >> 1 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log2(value);\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 10, rounded down, of a positive value.\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 + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 256, rounded down, of a positive value.\n * Returns 0 if given 0.\n *\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n */\n function log256(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 16;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 8;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 4;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 2;\n }\n if (value >> 8 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log256(value);\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/SafeCast.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCast {\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 * _Available since v4.7._\n */\n function toUint248(uint256 value) internal pure returns (uint248) {\n require(value <= type(uint248).max, \"SafeCast: value doesn't fit in 248 bits\");\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 * _Available since v4.7._\n */\n function toUint240(uint256 value) internal pure returns (uint240) {\n require(value <= type(uint240).max, \"SafeCast: value doesn't fit in 240 bits\");\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 * _Available since v4.7._\n */\n function toUint232(uint256 value) internal pure returns (uint232) {\n require(value <= type(uint232).max, \"SafeCast: value doesn't fit in 232 bits\");\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 * _Available since v4.2._\n */\n function toUint224(uint256 value) internal pure returns (uint224) {\n require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\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 * _Available since v4.7._\n */\n function toUint216(uint256 value) internal pure returns (uint216) {\n require(value <= type(uint216).max, \"SafeCast: value doesn't fit in 216 bits\");\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 * _Available since v4.7._\n */\n function toUint208(uint256 value) internal pure returns (uint208) {\n require(value <= type(uint208).max, \"SafeCast: value doesn't fit in 208 bits\");\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 * _Available since v4.7._\n */\n function toUint200(uint256 value) internal pure returns (uint200) {\n require(value <= type(uint200).max, \"SafeCast: value doesn't fit in 200 bits\");\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 * _Available since v4.7._\n */\n function toUint192(uint256 value) internal pure returns (uint192) {\n require(value <= type(uint192).max, \"SafeCast: value doesn't fit in 192 bits\");\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 * _Available since v4.7._\n */\n function toUint184(uint256 value) internal pure returns (uint184) {\n require(value <= type(uint184).max, \"SafeCast: value doesn't fit in 184 bits\");\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 * _Available since v4.7._\n */\n function toUint176(uint256 value) internal pure returns (uint176) {\n require(value <= type(uint176).max, \"SafeCast: value doesn't fit in 176 bits\");\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 * _Available since v4.7._\n */\n function toUint168(uint256 value) internal pure returns (uint168) {\n require(value <= type(uint168).max, \"SafeCast: value doesn't fit in 168 bits\");\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 * _Available since v4.7._\n */\n function toUint160(uint256 value) internal pure returns (uint160) {\n require(value <= type(uint160).max, \"SafeCast: value doesn't fit in 160 bits\");\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 * _Available since v4.7._\n */\n function toUint152(uint256 value) internal pure returns (uint152) {\n require(value <= type(uint152).max, \"SafeCast: value doesn't fit in 152 bits\");\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 * _Available since v4.7._\n */\n function toUint144(uint256 value) internal pure returns (uint144) {\n require(value <= type(uint144).max, \"SafeCast: value doesn't fit in 144 bits\");\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 * _Available since v4.7._\n */\n function toUint136(uint256 value) internal pure returns (uint136) {\n require(value <= type(uint136).max, \"SafeCast: value doesn't fit in 136 bits\");\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 * _Available since v2.5._\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\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 * _Available since v4.7._\n */\n function toUint120(uint256 value) internal pure returns (uint120) {\n require(value <= type(uint120).max, \"SafeCast: value doesn't fit in 120 bits\");\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 * _Available since v4.7._\n */\n function toUint112(uint256 value) internal pure returns (uint112) {\n require(value <= type(uint112).max, \"SafeCast: value doesn't fit in 112 bits\");\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 * _Available since v4.7._\n */\n function toUint104(uint256 value) internal pure returns (uint104) {\n require(value <= type(uint104).max, \"SafeCast: value doesn't fit in 104 bits\");\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 * _Available since v4.2._\n */\n function toUint96(uint256 value) internal pure returns (uint96) {\n require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\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 * _Available since v4.7._\n */\n function toUint88(uint256 value) internal pure returns (uint88) {\n require(value <= type(uint88).max, \"SafeCast: value doesn't fit in 88 bits\");\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 * _Available since v4.7._\n */\n function toUint80(uint256 value) internal pure returns (uint80) {\n require(value <= type(uint80).max, \"SafeCast: value doesn't fit in 80 bits\");\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 * _Available since v4.7._\n */\n function toUint72(uint256 value) internal pure returns (uint72) {\n require(value <= type(uint72).max, \"SafeCast: value doesn't fit in 72 bits\");\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 * _Available since v2.5._\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\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 * _Available since v4.7._\n */\n function toUint56(uint256 value) internal pure returns (uint56) {\n require(value <= type(uint56).max, \"SafeCast: value doesn't fit in 56 bits\");\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 * _Available since v4.7._\n */\n function toUint48(uint256 value) internal pure returns (uint48) {\n require(value <= type(uint48).max, \"SafeCast: value doesn't fit in 48 bits\");\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 * _Available since v4.7._\n */\n function toUint40(uint256 value) internal pure returns (uint40) {\n require(value <= type(uint40).max, \"SafeCast: value doesn't fit in 40 bits\");\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 * _Available since v2.5._\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\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 * _Available since v4.7._\n */\n function toUint24(uint256 value) internal pure returns (uint24) {\n require(value <= type(uint24).max, \"SafeCast: value doesn't fit in 24 bits\");\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 * _Available since v2.5._\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\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 * _Available since v2.5._\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\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 * _Available since v3.0._\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\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 * _Available since v4.7._\n */\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\n downcasted = int248(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 248 bits\");\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 * _Available since v4.7._\n */\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\n downcasted = int240(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 240 bits\");\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 * _Available since v4.7._\n */\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\n downcasted = int232(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 232 bits\");\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 * _Available since v4.7._\n */\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\n downcasted = int224(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 224 bits\");\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 * _Available since v4.7._\n */\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\n downcasted = int216(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 216 bits\");\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 * _Available since v4.7._\n */\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\n downcasted = int208(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 208 bits\");\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 * _Available since v4.7._\n */\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\n downcasted = int200(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 200 bits\");\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 * _Available since v4.7._\n */\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\n downcasted = int192(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 192 bits\");\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 * _Available since v4.7._\n */\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\n downcasted = int184(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 184 bits\");\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 * _Available since v4.7._\n */\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\n downcasted = int176(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 176 bits\");\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 * _Available since v4.7._\n */\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\n downcasted = int168(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 168 bits\");\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 * _Available since v4.7._\n */\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\n downcasted = int160(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 160 bits\");\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 * _Available since v4.7._\n */\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\n downcasted = int152(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 152 bits\");\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 * _Available since v4.7._\n */\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\n downcasted = int144(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 144 bits\");\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 * _Available since v4.7._\n */\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\n downcasted = int136(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 136 bits\");\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 * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\n downcasted = int128(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 128 bits\");\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 * _Available since v4.7._\n */\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\n downcasted = int120(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 120 bits\");\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 * _Available since v4.7._\n */\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\n downcasted = int112(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 112 bits\");\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 * _Available since v4.7._\n */\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\n downcasted = int104(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 104 bits\");\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 * _Available since v4.7._\n */\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\n downcasted = int96(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 96 bits\");\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 * _Available since v4.7._\n */\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\n downcasted = int88(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 88 bits\");\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 * _Available since v4.7._\n */\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\n downcasted = int80(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 80 bits\");\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 * _Available since v4.7._\n */\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\n downcasted = int72(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 72 bits\");\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 * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\n downcasted = int64(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 64 bits\");\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 * _Available since v4.7._\n */\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\n downcasted = int56(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 56 bits\");\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 * _Available since v4.7._\n */\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\n downcasted = int48(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 48 bits\");\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 * _Available since v4.7._\n */\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\n downcasted = int40(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 40 bits\");\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 * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\n downcasted = int32(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 32 bits\");\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 * _Available since v4.7._\n */\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\n downcasted = int24(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 24 bits\");\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 * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\n downcasted = int16(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 16 bits\");\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 * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\n downcasted = int8(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 8 bits\");\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 * _Available since v3.0._\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 require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/SignedMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard signed math utilities missing in the Solidity language.\n */\nlibrary SignedMath {\n /**\n * @dev Returns the largest of two signed numbers.\n */\n function max(int256 a, int256 b) internal pure returns (int256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two signed numbers.\n */\n function min(int256 a, int256 b) internal pure returns (int256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two signed numbers without overflow.\n * The result is rounded towards zero.\n */\n function average(int256 a, int256 b) internal pure returns (int256) {\n // Formula from the book \"Hacker's Delight\"\n int256 x = (a & b) + ((a ^ b) >> 1);\n return x + (int256(uint256(x) >> 255) & (a ^ b));\n }\n\n /**\n * @dev Returns the absolute unsigned value of a signed value.\n */\n function abs(int256 n) internal pure returns (uint256) {\n unchecked {\n // must be unchecked in order to support `n = type(int256).min`\n return uint256(n >= 0 ? n : -n);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/Math.sol\";\nimport \"./math/SignedMath.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n unchecked {\n uint256 length = Math.log10(value) + 1;\n string memory buffer = new string(length);\n uint256 ptr;\n /// @solidity memory-safe-assembly\n assembly {\n ptr := add(buffer, add(32, length))\n }\n while (true) {\n ptr--;\n /// @solidity memory-safe-assembly\n assembly {\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n }\n value /= 10;\n if (value == 0) break;\n }\n return buffer;\n }\n }\n\n /**\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\n */\n function toString(int256 value) internal pure returns (string memory) {\n return string(abi.encodePacked(value < 0 ? \"-\" : \"\", toString(SignedMath.abs(value))));\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n unchecked {\n return toHexString(value, Math.log256(value) + 1);\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n\n /**\n * @dev Returns true if the two strings are equal.\n */\n function equal(string memory a, string memory b) internal pure returns (bool) {\n return keccak256(bytes(a)) == keccak256(bytes(b));\n }\n}\n" + }, + "contracts/aa-4337/core/BaseAccount.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-empty-blocks */\n\nimport \"../interfaces/IAccount.sol\";\nimport \"../interfaces/IEntryPoint.sol\";\nimport \"./Helpers.sol\";\n\n/**\n * Basic account implementation.\n * this contract provides the basic logic for implementing the IAccount interface - validateUserOp\n * specific account implementation should inherit it and provide the account-specific logic\n */\nabstract contract BaseAccount is IAccount {\n using UserOperationLib for UserOperation;\n\n //return value in case of signature failure, with no time-range.\n // equivalent to _packValidationData(true,0,0);\n uint256 internal constant SIG_VALIDATION_FAILED = 1;\n\n /**\n * Return the account nonce.\n * This method returns the next sequential nonce.\n * For a nonce of a specific key, use `entrypoint.getNonce(account, key)`\n */\n function getNonce() public view virtual returns (uint256) {\n return entryPoint().getNonce(address(this), 0);\n }\n\n /**\n * return the entryPoint used by this account.\n * subclass should return the current entryPoint used by this account.\n */\n function entryPoint() public view virtual returns (IEntryPoint);\n\n /**\n * Validate user's signature and nonce.\n * subclass doesn't need to override this method. Instead, it should override the specific internal validation methods.\n */\n function validateUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 missingAccountFunds\n ) external virtual override returns (uint256 validationData) {\n _requireFromEntryPoint();\n validationData = _validateSignature(userOp, userOpHash);\n _validateNonce(userOp.nonce);\n _payPrefund(missingAccountFunds);\n }\n\n /**\n * ensure the request comes from the known entrypoint.\n */\n function _requireFromEntryPoint() internal view virtual {\n require(\n msg.sender == address(entryPoint()),\n \"account: not from EntryPoint\"\n );\n }\n\n /**\n * validate the signature is valid for this message.\n * @param userOp validate the userOp.signature field\n * @param userOpHash convenient field: the hash of the request, to check the signature against\n * (also hashes the entrypoint and chain id)\n * @return validationData signature and time-range of this operation\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * If the account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function _validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) internal virtual returns (uint256 validationData);\n\n /**\n * Validate the nonce of the UserOperation.\n * This method may validate the nonce requirement of this account.\n * e.g.\n * To limit the nonce to use sequenced UserOps only (no \"out of order\" UserOps):\n * `require(nonce < type(uint64).max)`\n * For a hypothetical account that *requires* the nonce to be out-of-order:\n * `require(nonce & type(uint64).max == 0)`\n *\n * The actual nonce uniqueness is managed by the EntryPoint, and thus no other\n * action is needed by the account itself.\n *\n * @param nonce to validate\n *\n * solhint-disable-next-line no-empty-blocks\n */\n function _validateNonce(uint256 nonce) internal view virtual {}\n\n /**\n * sends to the entrypoint (msg.sender) the missing funds for this transaction.\n * subclass MAY override this method for better funds management\n * (e.g. send to the entryPoint more than the minimum required, so that in future transactions\n * it will not be required to send again)\n * @param missingAccountFunds the minimum value this method should send the entrypoint.\n * this value MAY be zero, in case there is enough deposit, or the userOp has a paymaster.\n */\n function _payPrefund(uint256 missingAccountFunds) internal virtual {\n if (missingAccountFunds != 0) {\n (bool success, ) = payable(msg.sender).call{\n value: missingAccountFunds,\n gas: type(uint256).max\n }(\"\");\n (success);\n //ignore failure (its EntryPoint's job to verify, not account.)\n }\n }\n}\n" + }, + "contracts/aa-4337/core/EntryPoint.sol": { + "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n\nimport \"../interfaces/IAccount.sol\";\nimport \"../interfaces/IPaymaster.sol\";\nimport \"../interfaces/IEntryPoint.sol\";\n\nimport \"../utils/Exec.sol\";\nimport \"./StakeManager.sol\";\nimport \"./SenderCreator.sol\";\nimport \"./Helpers.sol\";\nimport \"./NonceManager.sol\";\nimport \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\n\ncontract EntryPoint is\n IEntryPoint,\n StakeManager,\n NonceManager,\n ReentrancyGuard\n{\n using UserOperationLib for UserOperation;\n\n SenderCreator private immutable senderCreator = new SenderCreator();\n\n // internal value used during simulation: need to query aggregator.\n address private constant SIMULATE_FIND_AGGREGATOR = address(1);\n\n // marker for inner call revert on out of gas\n bytes32 private constant INNER_OUT_OF_GAS = hex\"deaddead\";\n\n uint256 private constant REVERT_REASON_MAX_LEN = 2048;\n\n /**\n * for simulation purposes, validateUserOp (and validatePaymasterUserOp) must return this value\n * in case of signature failure, instead of revert.\n */\n uint256 public constant SIG_VALIDATION_FAILED = 1;\n\n /**\n * compensate the caller's beneficiary address with the collected fees of all UserOperations.\n * @param beneficiary the address to receive the fees\n * @param amount amount to transfer.\n */\n function _compensate(address payable beneficiary, uint256 amount) internal {\n require(beneficiary != address(0), \"AA90 invalid beneficiary\");\n (bool success, ) = beneficiary.call{value: amount}(\"\");\n require(success, \"AA91 failed send to beneficiary\");\n }\n\n /**\n * execute a user op\n * @param opIndex index into the opInfo array\n * @param userOp the userOp to execute\n * @param opInfo the opInfo filled by validatePrepayment for this userOp.\n * @return collected the total amount this userOp paid.\n */\n function _executeUserOp(\n uint256 opIndex,\n UserOperation calldata userOp,\n UserOpInfo memory opInfo\n ) private returns (uint256 collected) {\n uint256 preGas = gasleft();\n bytes memory context = getMemoryBytesFromOffset(opInfo.contextOffset);\n\n try this.innerHandleOp(userOp.callData, opInfo, context) returns (\n uint256 _actualGasCost\n ) {\n collected = _actualGasCost;\n } catch {\n bytes32 innerRevertCode;\n assembly {\n returndatacopy(0, 0, 32)\n innerRevertCode := mload(0)\n }\n // handleOps was called with gas limit too low. abort entire bundle.\n if (innerRevertCode == INNER_OUT_OF_GAS) {\n //report paymaster, since if it is not deliberately caused by the bundler,\n // it must be a revert caused by paymaster.\n revert FailedOp(opIndex, \"AA95 out of gas\");\n }\n\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n collected = _handlePostOp(\n opIndex,\n IPaymaster.PostOpMode.postOpReverted,\n opInfo,\n context,\n actualGas\n );\n }\n }\n\n /**\n * Execute a batch of UserOperations.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(\n UserOperation[] calldata ops,\n address payable beneficiary\n ) public nonReentrant {\n uint256 opslen = ops.length;\n UserOpInfo[] memory opInfos = new UserOpInfo[](opslen);\n\n unchecked {\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[i];\n (\n uint256 validationData,\n uint256 pmValidationData\n ) = _validatePrepayment(i, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(\n i,\n validationData,\n pmValidationData,\n address(0)\n );\n }\n\n uint256 collected = 0;\n emit BeforeExecution();\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(i, ops[i], opInfos[i]);\n }\n\n _compensate(beneficiary, collected);\n } //unchecked\n }\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) public nonReentrant {\n uint256 opasLen = opsPerAggregator.length;\n uint256 totalOps = 0;\n for (uint256 i = 0; i < opasLen; i++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[i];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n //address(1) is special marker of \"signature error\"\n require(\n address(aggregator) != address(1),\n \"AA96 invalid aggregator\"\n );\n\n if (address(aggregator) != address(0)) {\n // solhint-disable-next-line no-empty-blocks\n try aggregator.validateSignatures(ops, opa.signature) {} catch {\n revert SignatureValidationFailed(address(aggregator));\n }\n }\n\n totalOps += ops.length;\n }\n\n UserOpInfo[] memory opInfos = new UserOpInfo[](totalOps);\n\n emit BeforeExecution();\n\n uint256 opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n uint256 opslen = ops.length;\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[opIndex];\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(opIndex, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(\n i,\n validationData,\n paymasterValidationData,\n address(aggregator)\n );\n opIndex++;\n }\n }\n\n uint256 collected = 0;\n opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n emit SignatureAggregatorChanged(address(opa.aggregator));\n UserOperation[] calldata ops = opa.userOps;\n uint256 opslen = ops.length;\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(opIndex, ops[i], opInfos[opIndex]);\n opIndex++;\n }\n }\n emit SignatureAggregatorChanged(address(0));\n\n _compensate(beneficiary, collected);\n }\n\n /// @inheritdoc IEntryPoint\n function simulateHandleOp(\n UserOperation calldata op,\n address target,\n bytes calldata targetCallData\n ) external override {\n UserOpInfo memory opInfo;\n _simulationOnlyValidations(op);\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(0, op, opInfo);\n ValidationData memory data = _intersectTimeRange(\n validationData,\n paymasterValidationData\n );\n\n numberMarker();\n uint256 paid = _executeUserOp(0, op, opInfo);\n numberMarker();\n bool targetSuccess;\n bytes memory targetResult;\n if (target != address(0)) {\n (targetSuccess, targetResult) = target.call(targetCallData);\n }\n revert ExecutionResult(\n opInfo.preOpGas,\n paid,\n data.validAfter,\n data.validUntil,\n targetSuccess,\n targetResult\n );\n }\n\n // A memory copy of UserOp static fields only.\n // Excluding: callData, initCode and signature. Replacing paymasterAndData with paymaster.\n struct MemoryUserOp {\n address sender;\n uint256 nonce;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n address paymaster;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n }\n\n struct UserOpInfo {\n MemoryUserOp mUserOp;\n bytes32 userOpHash;\n uint256 prefund;\n uint256 contextOffset;\n uint256 preOpGas;\n }\n\n /**\n * inner function to handle a UserOperation.\n * Must be declared \"external\" to open a call context, but it can only be called by handleOps.\n */\n function innerHandleOp(\n bytes memory callData,\n UserOpInfo memory opInfo,\n bytes calldata context\n ) external returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n require(msg.sender == address(this), \"AA92 internal call only\");\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n\n uint callGasLimit = mUserOp.callGasLimit;\n unchecked {\n // handleOps was called with gas limit too low. abort entire bundle.\n if (\n gasleft() < callGasLimit + mUserOp.verificationGasLimit + 5000\n ) {\n assembly {\n mstore(0, INNER_OUT_OF_GAS)\n revert(0, 32)\n }\n }\n }\n\n IPaymaster.PostOpMode mode = IPaymaster.PostOpMode.opSucceeded;\n if (callData.length > 0) {\n bool success = Exec.call(mUserOp.sender, 0, callData, callGasLimit);\n if (!success) {\n bytes memory result = Exec.getReturnData(REVERT_REASON_MAX_LEN);\n if (result.length > 0) {\n emit UserOperationRevertReason(\n opInfo.userOpHash,\n mUserOp.sender,\n mUserOp.nonce,\n result\n );\n }\n mode = IPaymaster.PostOpMode.opReverted;\n }\n }\n\n unchecked {\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n //note: opIndex is ignored (relevant only if mode==postOpReverted, which is only possible outside of innerHandleOp)\n return _handlePostOp(0, mode, opInfo, context, actualGas);\n }\n }\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(\n UserOperation calldata userOp\n ) public view returns (bytes32) {\n return\n keccak256(abi.encode(userOp.hash(), address(this), block.chainid));\n }\n\n /**\n * copy general fields from userOp into the memory opInfo structure.\n */\n function _copyUserOpToMemory(\n UserOperation calldata userOp,\n MemoryUserOp memory mUserOp\n ) internal pure {\n mUserOp.sender = userOp.sender;\n mUserOp.nonce = userOp.nonce;\n mUserOp.callGasLimit = userOp.callGasLimit;\n mUserOp.verificationGasLimit = userOp.verificationGasLimit;\n mUserOp.preVerificationGas = userOp.preVerificationGas;\n mUserOp.maxFeePerGas = userOp.maxFeePerGas;\n mUserOp.maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes calldata paymasterAndData = userOp.paymasterAndData;\n if (paymasterAndData.length > 0) {\n require(\n paymasterAndData.length >= 20,\n \"AA93 invalid paymasterAndData\"\n );\n mUserOp.paymaster = address(bytes20(paymasterAndData[:20]));\n } else {\n mUserOp.paymaster = address(0);\n }\n }\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external {\n UserOpInfo memory outOpInfo;\n\n _simulationOnlyValidations(userOp);\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(0, userOp, outOpInfo);\n StakeInfo memory paymasterInfo = _getStakeInfo(\n outOpInfo.mUserOp.paymaster\n );\n StakeInfo memory senderInfo = _getStakeInfo(outOpInfo.mUserOp.sender);\n StakeInfo memory factoryInfo;\n {\n bytes calldata initCode = userOp.initCode;\n address factory = initCode.length >= 20\n ? address(bytes20(initCode[0:20]))\n : address(0);\n factoryInfo = _getStakeInfo(factory);\n }\n\n ValidationData memory data = _intersectTimeRange(\n validationData,\n paymasterValidationData\n );\n address aggregator = data.aggregator;\n bool sigFailed = aggregator == address(1);\n ReturnInfo memory returnInfo = ReturnInfo(\n outOpInfo.preOpGas,\n outOpInfo.prefund,\n sigFailed,\n data.validAfter,\n data.validUntil,\n getMemoryBytesFromOffset(outOpInfo.contextOffset)\n );\n\n if (aggregator != address(0) && aggregator != address(1)) {\n AggregatorStakeInfo memory aggregatorInfo = AggregatorStakeInfo(\n aggregator,\n _getStakeInfo(aggregator)\n );\n revert ValidationResultWithAggregation(\n returnInfo,\n senderInfo,\n factoryInfo,\n paymasterInfo,\n aggregatorInfo\n );\n }\n revert ValidationResult(\n returnInfo,\n senderInfo,\n factoryInfo,\n paymasterInfo\n );\n }\n\n function _getRequiredPrefund(\n MemoryUserOp memory mUserOp\n ) internal pure returns (uint256 requiredPrefund) {\n unchecked {\n //when using a Paymaster, the verificationGasLimit is used also to as a limit for the postOp call.\n // our security model might call postOp eventually twice\n uint256 mul = mUserOp.paymaster != address(0) ? 3 : 1;\n uint256 requiredGas = mUserOp.callGasLimit +\n mUserOp.verificationGasLimit *\n mul +\n mUserOp.preVerificationGas;\n\n requiredPrefund = requiredGas * mUserOp.maxFeePerGas;\n }\n }\n\n // create the sender's contract if needed.\n function _createSenderIfNeeded(\n uint256 opIndex,\n UserOpInfo memory opInfo,\n bytes calldata initCode\n ) internal {\n if (initCode.length != 0) {\n address sender = opInfo.mUserOp.sender;\n if (sender.code.length != 0)\n revert FailedOp(opIndex, \"AA10 sender already constructed\");\n address sender1 = senderCreator.createSender{\n gas: opInfo.mUserOp.verificationGasLimit\n }(initCode);\n if (sender1 == address(0))\n revert FailedOp(opIndex, \"AA13 initCode failed or OOG\");\n if (sender1 != sender)\n revert FailedOp(opIndex, \"AA14 initCode must return sender\");\n if (sender1.code.length == 0)\n revert FailedOp(opIndex, \"AA15 initCode must create sender\");\n address factory = address(bytes20(initCode[0:20]));\n emit AccountDeployed(\n opInfo.userOpHash,\n sender,\n factory,\n opInfo.mUserOp.paymaster\n );\n }\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes calldata initCode) public {\n address sender = senderCreator.createSender(initCode);\n revert SenderAddressResult(sender);\n }\n\n function _simulationOnlyValidations(\n UserOperation calldata userOp\n ) internal view {\n // solhint-disable-next-line no-empty-blocks\n try\n this._validateSenderAndPaymaster(\n userOp.initCode,\n userOp.sender,\n userOp.paymasterAndData\n )\n {} catch Error(string memory revertReason) {\n if (bytes(revertReason).length != 0) {\n revert FailedOp(0, revertReason);\n }\n }\n }\n\n /**\n * Called only during simulation.\n * This function always reverts to prevent warm/cold storage differentiation in simulation vs execution.\n */\n function _validateSenderAndPaymaster(\n bytes calldata initCode,\n address sender,\n bytes calldata paymasterAndData\n ) external view {\n if (initCode.length == 0 && sender.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA20 account not deployed\");\n }\n if (paymasterAndData.length >= 20) {\n address paymaster = address(bytes20(paymasterAndData[0:20]));\n if (paymaster.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA30 paymaster not deployed\");\n }\n }\n // always revert\n revert(\"\");\n }\n\n /**\n * call account.validateUserOp.\n * revert (with FailedOp) in case validateUserOp reverts, or account didn't send required prefund.\n * decrement account's deposit if needed\n */\n function _validateAccountPrepayment(\n uint256 opIndex,\n UserOperation calldata op,\n UserOpInfo memory opInfo,\n uint256 requiredPrefund\n )\n internal\n returns (\n uint256 gasUsedByValidateAccountPrepayment,\n uint256 validationData\n )\n {\n unchecked {\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n address sender = mUserOp.sender;\n _createSenderIfNeeded(opIndex, opInfo, op.initCode);\n address paymaster = mUserOp.paymaster;\n numberMarker();\n uint256 missingAccountFunds = 0;\n if (paymaster == address(0)) {\n uint256 bal = balanceOf(sender);\n missingAccountFunds = bal > requiredPrefund\n ? 0\n : requiredPrefund - bal;\n }\n try\n IAccount(sender).validateUserOp{\n gas: mUserOp.verificationGasLimit\n }(op, opInfo.userOpHash, missingAccountFunds)\n returns (uint256 _validationData) {\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA23 reverted: \", revertReason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA23 reverted (or OOG)\");\n }\n if (paymaster == address(0)) {\n DepositInfo storage senderInfo = deposits[sender];\n uint256 deposit = senderInfo.deposit;\n if (requiredPrefund > deposit) {\n revert FailedOp(opIndex, \"AA21 didn't pay prefund\");\n }\n senderInfo.deposit = uint112(deposit - requiredPrefund);\n }\n gasUsedByValidateAccountPrepayment = preGas - gasleft();\n }\n }\n\n /**\n * In case the request has a paymaster:\n * Validate paymaster has enough deposit.\n * Call paymaster.validatePaymasterUserOp.\n * Revert with proper FailedOp in case paymaster reverts.\n * Decrement paymaster's deposit\n */\n function _validatePaymasterPrepayment(\n uint256 opIndex,\n UserOperation calldata op,\n UserOpInfo memory opInfo,\n uint256 requiredPreFund,\n uint256 gasUsedByValidateAccountPrepayment\n ) internal returns (bytes memory context, uint256 validationData) {\n unchecked {\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 verificationGasLimit = mUserOp.verificationGasLimit;\n require(\n verificationGasLimit > gasUsedByValidateAccountPrepayment,\n \"AA41 too little verificationGas\"\n );\n uint256 gas = verificationGasLimit -\n gasUsedByValidateAccountPrepayment;\n\n address paymaster = mUserOp.paymaster;\n DepositInfo storage paymasterInfo = deposits[paymaster];\n uint256 deposit = paymasterInfo.deposit;\n if (deposit < requiredPreFund) {\n revert FailedOp(opIndex, \"AA31 paymaster deposit too low\");\n }\n paymasterInfo.deposit = uint112(deposit - requiredPreFund);\n try\n IPaymaster(paymaster).validatePaymasterUserOp{gas: gas}(\n op,\n opInfo.userOpHash,\n requiredPreFund\n )\n returns (bytes memory _context, uint256 _validationData) {\n context = _context;\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA33 reverted: \", revertReason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA33 reverted (or OOG)\");\n }\n }\n }\n\n /**\n * revert if either account validationData or paymaster validationData is expired\n */\n function _validateAccountAndPaymasterValidationData(\n uint256 opIndex,\n uint256 validationData,\n uint256 paymasterValidationData,\n address expectedAggregator\n ) internal view {\n (address aggregator, bool outOfTimeRange) = _getValidationData(\n validationData\n );\n if (expectedAggregator != aggregator) {\n revert FailedOp(opIndex, \"AA24 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA22 expired or not due\");\n }\n //pmAggregator is not a real signature aggregator: we don't have logic to handle it as address.\n // non-zero address means that the paymaster fails due to some signature check (which is ok only during estimation)\n address pmAggregator;\n (pmAggregator, outOfTimeRange) = _getValidationData(\n paymasterValidationData\n );\n if (pmAggregator != address(0)) {\n revert FailedOp(opIndex, \"AA34 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA32 paymaster expired or not due\");\n }\n }\n\n function _getValidationData(\n uint256 validationData\n ) internal view returns (address aggregator, bool outOfTimeRange) {\n if (validationData == 0) {\n return (address(0), false);\n }\n ValidationData memory data = _parseValidationData(validationData);\n // solhint-disable-next-line not-rely-on-time\n outOfTimeRange =\n block.timestamp > data.validUntil ||\n block.timestamp < data.validAfter;\n aggregator = data.aggregator;\n }\n\n /**\n * validate account and paymaster (if defined).\n * also make sure total validation doesn't exceed verificationGasLimit\n * this method is called off-chain (simulateValidation()) and on-chain (from handleOps)\n * @param opIndex the index of this userOp into the \"opInfos\" array\n * @param userOp the userOp to validate\n */\n function _validatePrepayment(\n uint256 opIndex,\n UserOperation calldata userOp,\n UserOpInfo memory outOpInfo\n )\n private\n returns (uint256 validationData, uint256 paymasterValidationData)\n {\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = outOpInfo.mUserOp;\n _copyUserOpToMemory(userOp, mUserOp);\n outOpInfo.userOpHash = getUserOpHash(userOp);\n\n // validate all numeric values in userOp are well below 128 bit, so they can safely be added\n // and multiplied without causing overflow\n uint256 maxGasValues = mUserOp.preVerificationGas |\n mUserOp.verificationGasLimit |\n mUserOp.callGasLimit |\n userOp.maxFeePerGas |\n userOp.maxPriorityFeePerGas;\n require(maxGasValues <= type(uint120).max, \"AA94 gas values overflow\");\n\n uint256 gasUsedByValidateAccountPrepayment;\n uint256 requiredPreFund = _getRequiredPrefund(mUserOp);\n (\n gasUsedByValidateAccountPrepayment,\n validationData\n ) = _validateAccountPrepayment(\n opIndex,\n userOp,\n outOpInfo,\n requiredPreFund\n );\n\n if (!_validateAndUpdateNonce(mUserOp.sender, mUserOp.nonce)) {\n revert FailedOp(opIndex, \"AA25 invalid account nonce\");\n }\n\n //a \"marker\" where account opcode validation is done and paymaster opcode validation is about to start\n // (used only by off-chain simulateValidation)\n numberMarker();\n\n bytes memory context;\n if (mUserOp.paymaster != address(0)) {\n (context, paymasterValidationData) = _validatePaymasterPrepayment(\n opIndex,\n userOp,\n outOpInfo,\n requiredPreFund,\n gasUsedByValidateAccountPrepayment\n );\n }\n unchecked {\n uint256 gasUsed = preGas - gasleft();\n\n if (userOp.verificationGasLimit < gasUsed) {\n revert FailedOp(opIndex, \"AA40 over verificationGasLimit\");\n }\n outOpInfo.prefund = requiredPreFund;\n outOpInfo.contextOffset = getOffsetOfMemoryBytes(context);\n outOpInfo.preOpGas = preGas - gasleft() + userOp.preVerificationGas;\n }\n }\n\n /**\n * process post-operation.\n * called just after the callData is executed.\n * if a paymaster is defined and its validation returned a non-empty context, its postOp is called.\n * the excess amount is refunded to the account (or paymaster - if it was used in the request)\n * @param opIndex index in the batch\n * @param mode - whether is called from innerHandleOp, or outside (postOpReverted)\n * @param opInfo userOp fields and info collected during validation\n * @param context the context returned in validatePaymasterUserOp\n * @param actualGas the gas used so far by this user operation\n */\n function _handlePostOp(\n uint256 opIndex,\n IPaymaster.PostOpMode mode,\n UserOpInfo memory opInfo,\n bytes memory context,\n uint256 actualGas\n ) private returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n unchecked {\n address refundAddress;\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 gasPrice = getUserOpGasPrice(mUserOp);\n\n address paymaster = mUserOp.paymaster;\n if (paymaster == address(0)) {\n refundAddress = mUserOp.sender;\n } else {\n refundAddress = paymaster;\n if (context.length > 0) {\n actualGasCost = actualGas * gasPrice;\n if (mode != IPaymaster.PostOpMode.postOpReverted) {\n IPaymaster(paymaster).postOp{\n gas: mUserOp.verificationGasLimit\n }(mode, context, actualGasCost);\n } else {\n // solhint-disable-next-line no-empty-blocks\n try\n IPaymaster(paymaster).postOp{\n gas: mUserOp.verificationGasLimit\n }(mode, context, actualGasCost)\n {} catch Error(string memory reason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA50 postOp reverted: \", reason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA50 postOp revert\");\n }\n }\n }\n }\n actualGas += preGas - gasleft();\n actualGasCost = actualGas * gasPrice;\n if (opInfo.prefund < actualGasCost) {\n revert FailedOp(opIndex, \"AA51 prefund below actualGasCost\");\n }\n uint256 refund = opInfo.prefund - actualGasCost;\n _incrementDeposit(refundAddress, refund);\n bool success = mode == IPaymaster.PostOpMode.opSucceeded;\n emit UserOperationEvent(\n opInfo.userOpHash,\n mUserOp.sender,\n mUserOp.paymaster,\n mUserOp.nonce,\n success,\n actualGasCost,\n actualGas\n );\n } // unchecked\n }\n\n /**\n * the gas price this UserOp agrees to pay.\n * relayer/block builder might submit the TX with higher priorityFee, but the user should not\n */\n function getUserOpGasPrice(\n MemoryUserOp memory mUserOp\n ) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = mUserOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = mUserOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n function getOffsetOfMemoryBytes(\n bytes memory data\n ) internal pure returns (uint256 offset) {\n assembly {\n offset := data\n }\n }\n\n function getMemoryBytesFromOffset(\n uint256 offset\n ) internal pure returns (bytes memory data) {\n assembly {\n data := offset\n }\n }\n\n //place the NUMBER opcode in the code.\n // this is used as a marker during simulation, as this OP is completely banned from the simulated code of the\n // account and paymaster.\n function numberMarker() internal view {\n assembly {\n mstore(0, number())\n }\n }\n}\n" + }, + "contracts/aa-4337/core/Helpers.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable no-inline-assembly */\n\n/**\n * returned data from validateUserOp.\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\n * @param aggregator - address(0) - the account validated the signature by itself.\n * address(1) - the account failed to validate the signature.\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\n * @param validAfter - this UserOp is valid only after this timestamp.\n * @param validaUntil - this UserOp is valid only up to this timestamp.\n */\nstruct ValidationData {\n address aggregator;\n uint48 validAfter;\n uint48 validUntil;\n}\n\n//extract sigFailed, validAfter, validUntil.\n// also convert zero validUntil to type(uint48).max\nfunction _parseValidationData(\n uint validationData\n) pure returns (ValidationData memory data) {\n address aggregator = address(uint160(validationData));\n uint48 validUntil = uint48(validationData >> 160);\n if (validUntil == 0) {\n validUntil = type(uint48).max;\n }\n uint48 validAfter = uint48(validationData >> (48 + 160));\n return ValidationData(aggregator, validAfter, validUntil);\n}\n\n// intersect account and paymaster ranges.\nfunction _intersectTimeRange(\n uint256 validationData,\n uint256 paymasterValidationData\n) pure returns (ValidationData memory) {\n ValidationData memory accountValidationData = _parseValidationData(\n validationData\n );\n ValidationData memory pmValidationData = _parseValidationData(\n paymasterValidationData\n );\n address aggregator = accountValidationData.aggregator;\n if (aggregator == address(0)) {\n aggregator = pmValidationData.aggregator;\n }\n uint48 validAfter = accountValidationData.validAfter;\n uint48 validUntil = accountValidationData.validUntil;\n uint48 pmValidAfter = pmValidationData.validAfter;\n uint48 pmValidUntil = pmValidationData.validUntil;\n\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\n return ValidationData(aggregator, validAfter, validUntil);\n}\n\n/**\n * helper to pack the return value for validateUserOp\n * @param data - the ValidationData to pack\n */\nfunction _packValidationData(\n ValidationData memory data\n) pure returns (uint256) {\n return\n uint160(data.aggregator) |\n (uint256(data.validUntil) << 160) |\n (uint256(data.validAfter) << (160 + 48));\n}\n\n/**\n * helper to pack the return value for validateUserOp, when not using an aggregator\n * @param sigFailed - true for signature failure, false for success\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\n * @param validAfter first timestamp this UserOperation is valid\n */\nfunction _packValidationData(\n bool sigFailed,\n uint48 validUntil,\n uint48 validAfter\n) pure returns (uint256) {\n return\n (sigFailed ? 1 : 0) |\n (uint256(validUntil) << 160) |\n (uint256(validAfter) << (160 + 48));\n}\n\n/**\n * keccak function over calldata.\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\n */\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\n assembly {\n let mem := mload(0x40)\n let len := data.length\n calldatacopy(mem, data.offset, len)\n ret := keccak256(mem, len)\n }\n}\n" + }, + "contracts/aa-4337/core/NonceManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\nimport \"../interfaces/IEntryPoint.sol\";\n\n/**\n * nonce management functionality\n */\ncontract NonceManager is INonceManager {\n /**\n * The next valid sequence number for a given nonce key.\n */\n mapping(address => mapping(uint192 => uint256)) public nonceSequenceNumber;\n\n function getNonce(\n address sender,\n uint192 key\n ) public view override returns (uint256 nonce) {\n return nonceSequenceNumber[sender][key] | (uint256(key) << 64);\n }\n\n // allow an account to manually increment its own nonce.\n // (mainly so that during construction nonce can be made non-zero,\n // to \"absorb\" the gas cost of first nonce increment to 1st transaction (construction),\n // not to 2nd transaction)\n function incrementNonce(uint192 key) public override {\n nonceSequenceNumber[msg.sender][key]++;\n }\n\n /**\n * validate nonce uniqueness for this account.\n * called just after validateUserOp()\n */\n function _validateAndUpdateNonce(\n address sender,\n uint256 nonce\n ) internal returns (bool) {\n uint192 key = uint192(nonce >> 64);\n uint64 seq = uint64(nonce);\n return nonceSequenceNumber[sender][key]++ == seq;\n }\n}\n" + }, + "contracts/aa-4337/core/SenderCreator.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/**\n * helper contract for EntryPoint, to call userOp.initCode from a \"neutral\" address,\n * which is explicitly not the entryPoint itself.\n */\ncontract SenderCreator {\n /**\n * call the \"initCode\" factory to create and return the sender account address\n * @param initCode the initCode value from a UserOp. contains 20 bytes of factory address, followed by calldata\n * @return sender the returned address of the created account, or zero address on failure.\n */\n function createSender(\n bytes calldata initCode\n ) external returns (address sender) {\n address factory = address(bytes20(initCode[0:20]));\n bytes memory initCallData = initCode[20:];\n bool success;\n /* solhint-disable no-inline-assembly */\n assembly {\n success := call(\n gas(),\n factory,\n 0,\n add(initCallData, 0x20),\n mload(initCallData),\n 0,\n 32\n )\n sender := mload(0)\n }\n if (!success) {\n sender = address(0);\n }\n }\n}\n" + }, + "contracts/aa-4337/core/StakeManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity 0.8.21;\n\nimport \"../interfaces/IStakeManager.sol\";\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable not-rely-on-time */\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by a paymaster.\n */\nabstract contract StakeManager is IStakeManager {\n /// maps paymaster to their deposits and stakes\n mapping(address => DepositInfo) public deposits;\n\n /// @inheritdoc IStakeManager\n function getDepositInfo(\n address account\n ) public view returns (DepositInfo memory info) {\n return deposits[account];\n }\n\n // internal method to return just the stake info\n function _getStakeInfo(\n address addr\n ) internal view returns (StakeInfo memory info) {\n DepositInfo storage depositInfo = deposits[addr];\n info.stake = depositInfo.stake;\n info.unstakeDelaySec = depositInfo.unstakeDelaySec;\n }\n\n /// return the deposit (for gas payment) of the account\n function balanceOf(address account) public view returns (uint256) {\n return deposits[account].deposit;\n }\n\n receive() external payable {\n depositTo(msg.sender);\n }\n\n function _incrementDeposit(address account, uint256 amount) internal {\n DepositInfo storage info = deposits[account];\n uint256 newAmount = info.deposit + amount;\n require(newAmount <= type(uint112).max, \"deposit overflow\");\n info.deposit = uint112(newAmount);\n }\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) public payable {\n _incrementDeposit(account, msg.value);\n DepositInfo storage info = deposits[account];\n emit Deposited(account, info.deposit);\n }\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 unstakeDelaySec) public payable {\n DepositInfo storage info = deposits[msg.sender];\n require(unstakeDelaySec > 0, \"must specify unstake delay\");\n require(\n unstakeDelaySec >= info.unstakeDelaySec,\n \"cannot decrease unstake time\"\n );\n uint256 stake = info.stake + msg.value;\n require(stake > 0, \"no stake specified\");\n require(stake <= type(uint112).max, \"stake overflow\");\n deposits[msg.sender] = DepositInfo(\n info.deposit,\n true,\n uint112(stake),\n unstakeDelaySec,\n 0\n );\n emit StakeLocked(msg.sender, stake, unstakeDelaySec);\n }\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external {\n DepositInfo storage info = deposits[msg.sender];\n require(info.unstakeDelaySec != 0, \"not staked\");\n require(info.staked, \"already unstaking\");\n uint48 withdrawTime = uint48(block.timestamp) + info.unstakeDelaySec;\n info.withdrawTime = withdrawTime;\n info.staked = false;\n emit StakeUnlocked(msg.sender, withdrawTime);\n }\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external {\n DepositInfo storage info = deposits[msg.sender];\n uint256 stake = info.stake;\n require(stake > 0, \"No stake to withdraw\");\n require(info.withdrawTime > 0, \"must call unlockStake() first\");\n require(\n info.withdrawTime <= block.timestamp,\n \"Stake withdrawal is not due\"\n );\n info.unstakeDelaySec = 0;\n info.withdrawTime = 0;\n info.stake = 0;\n emit StakeWithdrawn(msg.sender, withdrawAddress, stake);\n (bool success, ) = withdrawAddress.call{value: stake}(\"\");\n require(success, \"failed to withdraw stake\");\n }\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(\n address payable withdrawAddress,\n uint256 withdrawAmount\n ) external {\n DepositInfo storage info = deposits[msg.sender];\n require(withdrawAmount <= info.deposit, \"Withdraw amount too large\");\n info.deposit = uint112(info.deposit - withdrawAmount);\n emit Withdrawn(msg.sender, withdrawAddress, withdrawAmount);\n (bool success, ) = withdrawAddress.call{value: withdrawAmount}(\"\");\n require(success, \"failed to withdraw\");\n }\n}\n" + }, + "contracts/aa-4337/interfaces/IAccount.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\ninterface IAccount {\n /**\n * Validate user's signature and nonce\n * the entryPoint will make the call to the recipient only if this validation call returns successfully.\n * signature failure should be reported by returning SIG_VALIDATION_FAILED (1).\n * This allows making a \"simulation call\" without a valid signature\n * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure.\n *\n * @dev Must validate caller is the entryPoint.\n * Must validate the signature and nonce\n * @param userOp the operation that is about to be executed.\n * @param userOpHash hash of the user's request data. can be used as the basis for signature.\n * @param missingAccountFunds missing funds on the account's deposit in the entrypoint.\n * This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call.\n * The excess is left as a deposit in the entrypoint, for future calls.\n * can be withdrawn anytime using \"entryPoint.withdrawTo()\"\n * In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero.\n * @return validationData packaged ValidationData structure. use `_packValidationData` and `_unpackValidationData` to encode and decode\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * If an account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validateUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 missingAccountFunds\n ) external returns (uint256 validationData);\n}\n" + }, + "contracts/aa-4337/interfaces/IAggregator.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * Aggregated Signatures validator.\n */\ninterface IAggregator {\n /**\n * validate aggregated signature.\n * revert if the aggregated signature does not match the given list of operations.\n */\n function validateSignatures(\n UserOperation[] calldata userOps,\n bytes calldata signature\n ) external view;\n\n /**\n * validate signature of a single userOp\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\n * @param userOp the userOperation received from the user.\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\n * (usually empty, unless account and aggregator support some kind of \"multisig\"\n */\n function validateUserOpSignature(\n UserOperation calldata userOp\n ) external view returns (bytes memory sigForUserOp);\n\n /**\n * aggregate multiple signatures into a single value.\n * This method is called off-chain to calculate the signature to pass with handleOps()\n * bundler MAY use optimized custom code perform this aggregation\n * @param userOps array of UserOperations to collect the signatures from.\n * @return aggregatedSignature the aggregated signature\n */\n function aggregateSignatures(\n UserOperation[] calldata userOps\n ) external view returns (bytes memory aggregatedSignature);\n}\n" + }, + "contracts/aa-4337/interfaces/IEntryPoint.sol": { + "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n/* solhint-disable reason-string */\n\nimport \"./UserOperation.sol\";\nimport \"./IStakeManager.sol\";\nimport \"./IAggregator.sol\";\nimport \"./INonceManager.sol\";\n\ninterface IEntryPoint is IStakeManager, INonceManager {\n /***\n * An event emitted after each successful request\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\n * @param sender - the account that generates this request.\n * @param paymaster - if non-null, the paymaster that pays for this request.\n * @param nonce - the nonce value from the request.\n * @param success - true if the sender transaction succeeded, false if reverted.\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\n */\n event UserOperationEvent(\n bytes32 indexed userOpHash,\n address indexed sender,\n address indexed paymaster,\n uint256 nonce,\n bool success,\n uint256 actualGasCost,\n uint256 actualGasUsed\n );\n\n /**\n * account \"sender\" was deployed.\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\n * @param sender the account that is deployed\n * @param factory the factory used to deploy this account (in the initCode)\n * @param paymaster the paymaster used by this UserOp\n */\n event AccountDeployed(\n bytes32 indexed userOpHash,\n address indexed sender,\n address factory,\n address paymaster\n );\n\n /**\n * An event emitted if the UserOperation \"callData\" reverted with non-zero length\n * @param userOpHash the request unique identifier.\n * @param sender the sender of this request\n * @param nonce the nonce used in the request\n * @param revertReason - the return bytes from the (reverted) call to \"callData\".\n */\n event UserOperationRevertReason(\n bytes32 indexed userOpHash,\n address indexed sender,\n uint256 nonce,\n bytes revertReason\n );\n\n /**\n * an event emitted by handleOps(), before starting the execution loop.\n * any event emitted before this event, is part of the validation.\n */\n event BeforeExecution();\n\n /**\n * signature aggregator used by the following UserOperationEvents within this bundle.\n */\n event SignatureAggregatorChanged(address indexed aggregator);\n\n /**\n * a custom revert error of handleOps, to identify the offending op.\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\n * @param reason - revert reason\n * The string starts with a unique code \"AAmn\", where \"m\" is \"1\" for factory, \"2\" for account and \"3\" for paymaster issues,\n * so a failure can be attributed to the correct entity.\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\n */\n error FailedOp(uint256 opIndex, string reason);\n\n /**\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\n */\n error SignatureValidationFailed(address aggregator);\n\n /**\n * Successful result from simulateValidation.\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n */\n error ValidationResult(\n ReturnInfo returnInfo,\n StakeInfo senderInfo,\n StakeInfo factoryInfo,\n StakeInfo paymasterInfo\n );\n\n /**\n * Successful result from simulateValidation, if the account returns a signature aggregator\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\n * bundler MUST use it to verify the signature, or reject the UserOperation\n */\n error ValidationResultWithAggregation(\n ReturnInfo returnInfo,\n StakeInfo senderInfo,\n StakeInfo factoryInfo,\n StakeInfo paymasterInfo,\n AggregatorStakeInfo aggregatorInfo\n );\n\n /**\n * return value of getSenderAddress\n */\n error SenderAddressResult(address sender);\n\n /**\n * return value of simulateHandleOp\n */\n error ExecutionResult(\n uint256 preOpGas,\n uint256 paid,\n uint48 validAfter,\n uint48 validUntil,\n bool targetSuccess,\n bytes targetResult\n );\n\n //UserOps handled, per aggregator\n struct UserOpsPerAggregator {\n UserOperation[] userOps;\n // aggregator address\n IAggregator aggregator;\n // aggregated signature\n bytes signature;\n }\n\n /**\n * Execute a batch of UserOperation.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(\n UserOperation[] calldata ops,\n address payable beneficiary\n ) external;\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) external;\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(\n UserOperation calldata userOp\n ) external view returns (bytes32);\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external;\n\n /**\n * gas and return values during simulation\n * @param preOpGas the gas used for validation (including preValidationGas)\n * @param prefund the required prefund for this operation\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\n */\n struct ReturnInfo {\n uint256 preOpGas;\n uint256 prefund;\n bool sigFailed;\n uint48 validAfter;\n uint48 validUntil;\n bytes paymasterContext;\n }\n\n /**\n * returned aggregated signature info.\n * the aggregator returned by the account, and its current stake.\n */\n struct AggregatorStakeInfo {\n address aggregator;\n StakeInfo stakeInfo;\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes memory initCode) external;\n\n /**\n * simulate full execution of a UserOperation (including both validation and target execution)\n * this method will always revert with \"ExecutionResult\".\n * it performs full validation of the UserOperation, but ignores signature error.\n * an optional target address is called after the userop succeeds, and its value is returned\n * (before the entire call is reverted)\n * Note that in order to collect the the success/failure of the target call, it must be executed\n * with trace enabled to track the emitted events.\n * @param op the UserOperation to simulate\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\n * are set to the return from that call.\n * @param targetCallData callData to pass to target address\n */\n function simulateHandleOp(\n UserOperation calldata op,\n address target,\n bytes calldata targetCallData\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/INonceManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\ninterface INonceManager {\n /**\n * Return the next nonce for this sender.\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\n * But UserOp with different keys can come with arbitrary order.\n *\n * @param sender the account address\n * @param key the high 192 bit of the nonce\n * @return nonce a full nonce to pass for next UserOp with this sender.\n */\n function getNonce(\n address sender,\n uint192 key\n ) external view returns (uint256 nonce);\n\n /**\n * Manually increment the nonce of the sender.\n * This method is exposed just for completeness..\n * Account does NOT need to call it, neither during validation, nor elsewhere,\n * as the EntryPoint will update the nonce regardless.\n * Possible use-case is call it with various keys to \"initialize\" their nonces to one, so that future\n * UserOperations will not pay extra for the first transaction with a given key.\n */\n function incrementNonce(uint192 key) external;\n}\n" + }, + "contracts/aa-4337/interfaces/IPaymaster.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * the interface exposed by a paymaster contract, who agrees to pay the gas for user's operations.\n * a paymaster must hold a stake to cover the required entrypoint stake and also the gas for the transaction.\n */\ninterface IPaymaster {\n enum PostOpMode {\n opSucceeded, // user op succeeded\n opReverted, // user op reverted. still has to pay for gas.\n postOpReverted //user op succeeded, but caused postOp to revert. Now it's a 2nd call, after user's op was deliberately reverted.\n }\n\n /**\n * payment validation: check if paymaster agrees to pay.\n * Must verify sender is the entryPoint.\n * Revert to reject this request.\n * Note that bundlers will reject this method if it changes the state, unless the paymaster is trusted (whitelisted)\n * The paymaster pre-pays using its deposit, and receive back a refund after the postOp method returns.\n * @param userOp the user operation\n * @param userOpHash hash of the user's request data.\n * @param maxCost the maximum cost of this transaction (based on maximum gas and gas price from userOp)\n * @return context value to send to a postOp\n * zero length to signify postOp is not required.\n * @return validationData signature and time-range of this operation, encoded the same as the return value of validateUserOperation\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validatePaymasterUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 maxCost\n ) external returns (bytes memory context, uint256 validationData);\n\n /**\n * post-operation handler.\n * Must verify sender is the entryPoint\n * @param mode enum with the following options:\n * opSucceeded - user operation succeeded.\n * opReverted - user op reverted. still has to pay for gas.\n * postOpReverted - user op succeeded, but caused postOp (in mode=opSucceeded) to revert.\n * Now this is the 2nd call, after user's op was deliberately reverted.\n * @param context - the context value returned by validatePaymasterUserOp\n * @param actualGasCost - actual gas used so far (without this postOp call).\n */\n function postOp(\n PostOpMode mode,\n bytes calldata context,\n uint256 actualGasCost\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/IStakeManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.12;\n\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by the staked entity.\n */\ninterface IStakeManager {\n event Deposited(address indexed account, uint256 totalDeposit);\n\n event Withdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /// Emitted when stake or unstake delay are modified\n event StakeLocked(\n address indexed account,\n uint256 totalStaked,\n uint256 unstakeDelaySec\n );\n\n /// Emitted once a stake is scheduled for withdrawal\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\n\n event StakeWithdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /**\n * @param deposit the entity's deposit\n * @param staked true if this entity is staked.\n * @param stake actual amount of ether staked for this entity.\n * @param unstakeDelaySec minimum delay to withdraw the stake.\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\n * and the rest fit into a 2nd cell.\n * 112 bit allows for 10^15 eth\n * 48 bit for full timestamp\n * 32 bit allows 150 years for unstake delay\n */\n struct DepositInfo {\n uint112 deposit;\n bool staked;\n uint112 stake;\n uint32 unstakeDelaySec;\n uint48 withdrawTime;\n }\n\n //API struct used by getStakeInfo and simulateValidation\n struct StakeInfo {\n uint256 stake;\n uint256 unstakeDelaySec;\n }\n\n /// @return info - full deposit information of given account\n function getDepositInfo(\n address account\n ) external view returns (DepositInfo memory info);\n\n /// @return the deposit (for gas payment) of the account\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) external payable;\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 _unstakeDelaySec) external payable;\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external;\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external;\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(\n address payable withdrawAddress,\n uint256 withdrawAmount\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/UserOperation.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable no-inline-assembly */\n\nimport {calldataKeccak} from \"../core/Helpers.sol\";\n\n/**\n * User Operation struct\n * @param sender the sender account of this request.\n * @param nonce unique value the sender uses to verify it is not a replay.\n * @param initCode if set, the account contract will be created by this constructor/\n * @param callData the method call to execute on this account.\n * @param callGasLimit the gas limit passed to the callData method call.\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\n * @param maxFeePerGas same as EIP-1559 gas parameter.\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\n */\nstruct UserOperation {\n address sender;\n uint256 nonce;\n bytes initCode;\n bytes callData;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n bytes paymasterAndData;\n bytes signature;\n}\n\n/**\n * Utility functions helpful when working with UserOperation structs.\n */\nlibrary UserOperationLib {\n function getSender(\n UserOperation calldata userOp\n ) internal pure returns (address) {\n address data;\n //read sender from userOp, which is first userOp member (saves 800 gas...)\n assembly {\n data := calldataload(userOp)\n }\n return address(uint160(data));\n }\n\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\n // pay above what he signed for.\n function gasPrice(\n UserOperation calldata userOp\n ) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function pack(\n UserOperation calldata userOp\n ) internal pure returns (bytes memory ret) {\n address sender = getSender(userOp);\n uint256 nonce = userOp.nonce;\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\n bytes32 hashCallData = calldataKeccak(userOp.callData);\n uint256 callGasLimit = userOp.callGasLimit;\n uint256 verificationGasLimit = userOp.verificationGasLimit;\n uint256 preVerificationGas = userOp.preVerificationGas;\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\n\n return\n abi.encode(\n sender,\n nonce,\n hashInitCode,\n hashCallData,\n callGasLimit,\n verificationGasLimit,\n preVerificationGas,\n maxFeePerGas,\n maxPriorityFeePerGas,\n hashPaymasterAndData\n );\n }\n\n function hash(\n UserOperation calldata userOp\n ) internal pure returns (bytes32) {\n return keccak256(pack(userOp));\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n}\n" + }, + "contracts/aa-4337/utils/Exec.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.5 <0.9.0;\n\n// solhint-disable no-inline-assembly\n\n/**\n * Utility functions helpful when making different kinds of contract calls in Solidity.\n */\nlibrary Exec {\n function call(\n address to,\n uint256 value,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := call(\n txGas,\n to,\n value,\n add(data, 0x20),\n mload(data),\n 0,\n 0\n )\n }\n }\n\n function staticcall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal view returns (bool success) {\n assembly {\n success := staticcall(txGas, to, add(data, 0x20), mload(data), 0, 0)\n }\n }\n\n function delegateCall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := delegatecall(\n txGas,\n to,\n add(data, 0x20),\n mload(data),\n 0,\n 0\n )\n }\n }\n\n // get returned data from last call or calldelegate\n function getReturnData(\n uint256 maxLen\n ) internal pure returns (bytes memory returnData) {\n assembly {\n let len := returndatasize()\n if gt(len, maxLen) {\n len := maxLen\n }\n let ptr := mload(0x40)\n mstore(0x40, add(ptr, add(len, 0x20)))\n mstore(ptr, len)\n returndatacopy(add(ptr, 0x20), 0, len)\n returnData := ptr\n }\n }\n\n // revert with explicit byte array (probably reverted info from call)\n function revertWithData(bytes memory returnData) internal pure {\n assembly {\n revert(add(returnData, 32), mload(returnData))\n }\n }\n\n function callAndRevert(\n address to,\n bytes memory data,\n uint256 maxLen\n ) internal {\n bool success = call(to, 0, data, gasleft());\n if (!success) {\n revertWithData(getReturnData(maxLen));\n }\n }\n}\n" + }, + "contracts/Barz.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"./libraries/LibDiamond.sol\";\nimport {IBarz} from \"./interfaces/IBarz.sol\";\n\n/**\n * @title Barz\n * @dev A diamond proxy wallet with a modular & upgradeable architecture\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract Barz is IBarz {\n /**\n * @notice Initializes Barz with the given parameters. Barz account is intended to be created from Barz Factory for stable deployment.\n * @dev This method makes a delegate call to account facet and account facet handles the initialization.\n * With modular architecture, Barz encompasses wide spectrum of architecture and logic.\n * The only requirement is account facet to comply with initialize() interface.\n * Barz doesn't include built-in functions and is a full proxy, for maximum extensibility and modularity.\n * @param _accountFacet Address of Account Facet in charge of the Barz initialization\n * @param _verificationFacet Address of Verification Facet for verifying the signature. Could be any signature scheme\n * @param _entryPoint Address of Entry Point contract\n * @param _facetRegistry Address of Facet Registry. Facet Registry is a registry holding trusted facets that could be added to user's wallet\n * @param _defaultFallBack Address of Default FallBack Handler. Middleware contract for more efficient deployment\n * @param _ownerPublicKey Bytes of Owner Public Key using for initialization\n */\n constructor(\n address _accountFacet,\n address _verificationFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallBack,\n bytes memory _ownerPublicKey\n ) payable {\n bytes memory initCall = abi.encodeWithSignature(\n \"initialize(address,address,address,address,bytes)\",\n _verificationFacet,\n _entryPoint,\n _facetRegistry,\n _defaultFallBack,\n _ownerPublicKey\n );\n (bool success, bytes memory result) = _accountFacet.delegatecall(\n initCall\n );\n if (!success || uint256(bytes32(result)) != 1) {\n revert Barz__InitializationFailure();\n }\n }\n\n /**\n * @notice Fallback function for Barz complying with Diamond Standard with customization of adding Default Fallback Handler\n * @dev Find facet for function that is called and execute the function if a facet is found and return any value.\n */\n fallback() external payable {\n LibDiamond.DiamondStorage storage ds;\n bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION;\n // get diamond storage\n assembly {\n ds.slot := position\n }\n // get facet from function selector\n address facet = address(bytes20(ds.facets[msg.sig]));\n if (facet == address(0))\n facet = ds.defaultFallbackHandler.facetAddress(msg.sig);\n require(facet != address(0), \"Barz: Function does not exist\");\n // Execute external function from facet using delegatecall and return any value.\n assembly {\n // copy function selector and any arguments\n calldatacopy(0, 0, calldatasize())\n // execute function call using the facet\n let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)\n // get any return value\n returndatacopy(0, 0, returndatasize())\n // return any return value or error back to the caller\n switch result\n case 0 {\n revert(0, returndatasize())\n }\n default {\n return(0, returndatasize())\n }\n }\n }\n\n /**\n * @notice Receive function to receive native token without data\n */\n receive() external payable {}\n}\n" + }, + "contracts/BarzFactory.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Barz} from \"./Barz.sol\";\nimport {IBarzFactory} from \"./interfaces/IBarzFactory.sol\";\n\n/**\n * @title Barz Factory\n * @dev Contract to easily deploy Barz to a pre-computed address with a single call\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract BarzFactory is IBarzFactory {\n event BarzDeployed(address);\n\n address public immutable accountFacet;\n address public immutable entryPoint;\n address public immutable facetRegistry;\n address public immutable defaultFallback;\n\n /**\n * @notice Sets the initialization data for Barz contract initialization\n * @param _accountFacet Account Facet to be used to create Barz\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\n * @param _facetRegistry Facet Registry to be used to create Barz\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\n */\n constructor(\n address _accountFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallback\n ) {\n accountFacet = _accountFacet;\n entryPoint = _entryPoint;\n facetRegistry = _facetRegistry;\n defaultFallback = _defaultFallback;\n }\n\n /**\n * @notice Creates the Barz with a single call. It creates the Barz contract with the givent verification facet\n * @param _verificationFacet Address of verification facet used for creating the barz account\n * @param _owner Public Key of the owner to initialize barz account\n * @param _salt Salt used for deploying barz with create2\n * @return barz Instance of Barz contract deployed with the given parameters\n */\n function createAccount(\n address _verificationFacet,\n bytes calldata _owner,\n uint256 _salt\n ) external override returns (Barz barz) {\n address addr = getAddress(_verificationFacet, _owner, _salt);\n uint codeSize = addr.code.length;\n if (codeSize > 0) {\n return Barz(payable(addr));\n }\n barz = new Barz{salt: bytes32(_salt)}(\n accountFacet,\n _verificationFacet,\n entryPoint,\n facetRegistry,\n defaultFallback,\n _owner\n );\n emit BarzDeployed(address(barz));\n }\n\n /**\n * @notice Calculates the address of Barz with the given parameters\n * @param _verificationFacet Address of verification facet used for creating the barz account\n * @param _owner Public Key of the owner to initialize barz account\n * @param _salt Salt used for deploying barz with create2\n * @return barzAddress Precalculated Barz address\n */\n function getAddress(\n address _verificationFacet,\n bytes calldata _owner,\n uint256 _salt\n ) public view override returns (address barzAddress) {\n bytes memory bytecode = getBytecode(\n accountFacet,\n _verificationFacet,\n entryPoint,\n facetRegistry,\n defaultFallback,\n _owner\n );\n bytes32 hash = keccak256(\n abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(bytecode)\n )\n );\n barzAddress = address(uint160(uint256(hash)));\n }\n\n /**\n * @notice Returns the bytecode of Barz with the given parameter\n * @param _accountFacet Account Facet to be used to create Barz\n * @param _verificationFacet Verification Facet to be used to create Barz\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\n * @param _facetRegistry Facet Registry to be used to create Barz\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\n * @param _ownerPublicKey Public Key of owner to be used to initialize Barz ownership\n * @return barzBytecode Bytecode of Barz\n */\n function getBytecode(\n address _accountFacet,\n address _verificationFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallback,\n bytes calldata _ownerPublicKey\n ) public pure override returns (bytes memory barzBytecode) {\n bytes memory bytecode = type(Barz).creationCode;\n barzBytecode = abi.encodePacked(\n bytecode,\n abi.encode(\n _accountFacet,\n _verificationFacet,\n _entryPoint,\n _facetRegistry,\n _defaultFallback,\n _ownerPublicKey\n )\n );\n }\n\n /**\n * @notice Returns the creation code of the Barz contract\n * @return creationCode Creation code of Barz\n */\n function getCreationCode()\n public\n pure\n override\n returns (bytes memory creationCode)\n {\n creationCode = type(Barz).creationCode;\n }\n}\n" + }, + "contracts/facets/AccountFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {UserOperation} from \"../aa-4337/interfaces/UserOperation.sol\";\nimport {IEntryPoint} from \"../aa-4337/interfaces/IEntryPoint.sol\";\nimport {BaseAccount} from \"../aa-4337/core/BaseAccount.sol\";\nimport {LibAppStorage, BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {IFacetRegistry} from \"../infrastructure/interfaces/IFacetRegistry.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {IERC1271} from \"../interfaces/ERC/IERC1271.sol\";\nimport {IAccountFacet} from \"./interfaces/IAccountFacet.sol\";\n\n/**\n * @title Account Facet\n * @dev Account module contract that provides the account features and initialization of signer\n * compatible with EIP-1271 & EIP-4337\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract AccountFacet is BarzStorage, BaseAccount, IAccountFacet {\n using ECDSA for bytes32;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceAccountInitialize();\n }\n\n /**\n * @notice Returns the address of EntryPoint contract registered to Barz account\n */\n function entryPoint() public view override returns (IEntryPoint) {\n return s.entryPoint;\n }\n\n /**\n * @notice Initializes the initial storage of the Barz contract.\n * @dev This method can only be called during the initialization or signature migration.\n * If the proxy contract was created without initialization, anyone can call initialize.\n * Barz calls initialize in constructor in an atomic transaction during deployment\n * @param _verificationFacet Facet contract handling the verificationi\n * @param _anEntryPoint Entrypoint contract defined in EIP-4337 handling the flow of UserOp\n * @param _facetRegistry Registry of Facets that hold all facet information\n * @param _defaultFallBackHandler Middleware contract for default facets\n * @param _ownerPublicKey Bytes of owner public key\n */\n function initialize(\n address _verificationFacet,\n address _anEntryPoint,\n address _facetRegistry,\n address _defaultFallBackHandler,\n bytes calldata _ownerPublicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceAccountInitialize();\n s.entryPoint = IEntryPoint(_anEntryPoint);\n s.facetRegistry = IFacetRegistry(_facetRegistry);\n LibDiamond.diamondStorage().defaultFallbackHandler = IDiamondLoupe(\n _defaultFallBackHandler\n );\n\n _cutDiamondAccountFacet(_verificationFacet);\n\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n _ownerPublicKey\n );\n // Every Verification Facet should comply with initializeSigner(bytes)\n // to be compatible with the Barz contract(for initialization)\n (bool success, bytes memory result) = _verificationFacet.delegatecall(\n initCall\n );\n if (!success || uint256(bytes32(result)) != 1) {\n revert AccountFacet__InitializationFailure();\n }\n\n initSuccess = 1;\n emit AccountInitialized(s.entryPoint, _ownerPublicKey);\n }\n\n function _cutDiamondAccountFacet(address _verificationFacet) internal {\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](1);\n\n bytes4 ownerVerificationFuncSelector = IVerificationFacet(\n _verificationFacet\n ).validateOwnerSignatureSelector();\n\n bytes4[] memory verificationFunctionSelectors = new bytes4[](3);\n verificationFunctionSelectors[0] = IERC1271.isValidSignature.selector;\n verificationFunctionSelectors[1] = ownerVerificationFuncSelector;\n verificationFunctionSelectors[2] = IVerificationFacet.owner.selector;\n cut[0] = IDiamondCut.FacetCut({\n facetAddress: _verificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: verificationFunctionSelectors\n });\n\n LibDiamond.diamondCut(cut, address(0), \"\");\n }\n\n /**\n * @notice Calls the destination with inputted calldata and value from EntryPoint\n * @dev This method executes the calldata coming from the EntryPoint.\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\n * @param _dest Address of destination where the call will be forwarded to\n * @param _value Amount of native coin the owner is willing to send(e.g. ETH, BNB)\n * @param _func Bytes of calldata to execute in the destination address\n */\n function execute(\n address _dest,\n uint256 _value,\n bytes calldata _func\n ) external override onlyWhenUnlocked {\n _requireFromEntryPoint();\n _call(_dest, _value, _func);\n }\n\n /**\n * @notice Batch calls the destination with inputted calldata and value from EntryPoint\n * @dev This method batch executes the calldata coming from the EntryPoint.\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\n * @param _dest Array of addresses of destination where the call will be forwarded to\n * @param _value Array of amount of native coin the owner is willing to send(e.g. ETH, BNB)\n * @param _func Array of bytes of calldata to execute in the destination address\n */\n function executeBatch(\n address[] calldata _dest,\n uint256[] calldata _value,\n bytes[] calldata _func\n ) external override onlyWhenUnlocked {\n _requireFromEntryPoint();\n require(\n _dest.length == _func.length && _dest.length == _value.length,\n \"wrong array lengths\"\n );\n for (uint256 i; i < _dest.length; ) {\n _call(_dest[i], _value[i], _func[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Validates the signature field of UserOperation\n * @dev This method validates if the signature of UserOp is indeed valid by delegating the call to Verification Facet\n * Barz makes a call to the pre-registered Verification Facet address in App Storage\n * @param _userOp UserOperation from owner to be validated\n * @param _userOpHash Hash of UserOperation given from the EntryPoint contract\n */\n function _validateSignature(\n UserOperation calldata _userOp,\n bytes32 _userOpHash\n ) internal override returns (uint256 validationData) {\n // Get Facet with Function Selector\n address facet = LibLoupe.facetAddress(s.validateOwnerSignatureSelector);\n if (facet == address(0))\n revert AccountFacet__NonExistentVerificationFacet();\n\n // Make function call to VerificationFacet\n bytes memory validateCall = abi.encodeWithSelector(\n s.validateOwnerSignatureSelector,\n _userOp,\n _userOpHash\n );\n (bool success, bytes memory result) = facet.delegatecall(validateCall);\n if (!success) revert AccountFacet__CallNotSuccessful();\n validationData = uint256(bytes32(result));\n if (validationData == 0) emit VerificationSuccess(_userOpHash);\n else emit VerificationFailure(_userOpHash);\n }\n\n /**\n * @notice Calls the target with the inputted value and calldata\n * @dev This method is the actual function in Barz that makes a call with an arbitrary owner-given data\n * @param _target Address of the destination contract which the call is getting forwarded to\n * @param _value Amount of Native coin the owner is wanting to make in this call\n * @param _data Calldata the owner is forwarding together in the call e.g. Swap/Token Transfer\n */\n function _call(\n address _target,\n uint256 _value,\n bytes memory _data\n ) internal {\n address facet = LibDiamond.restrictionsFacet();\n // NOTE: No restrictions facet, so restriction validation passes\n if (facet != address(0)) {\n if (_checkRestrictions(facet, _target, _value, _data) == 1)\n revert AccountFacet__RestrictionsFailure();\n }\n\n (bool success, bytes memory result) = _target.call{value: _value}(\n _data\n );\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n }\n\n /**\n * @notice Checks restrictions if the restrictions facet exists\n * @dev This method checks if the restrictions facet exists and makes a verification call to an array of restrictions facet\n * @param _facet Address that holds the restrictions logic\n * @param _target Address the call is getting forwarded to\n * @param _value Amount of native coin the call is sending together with the call\n * @param _data Calldata to trigger execution in target address\n */\n function _checkRestrictions(\n address _facet,\n address _target,\n uint256 _value,\n bytes memory _data\n ) internal returns (uint256 result) {\n bytes memory call = abi.encodeWithSignature(\n \"verifyRestrictions(address,address,uint256,bytes)\",\n address(this),\n _target,\n _value,\n _data\n );\n (bool success, bytes memory response) = _facet.delegatecall(call);\n if (!success) revert AccountFacet__RestrictionsFailure();\n result = uint256(bytes32(response));\n }\n}\n" + }, + "contracts/facets/AccountRecoveryFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibFacetStorage, RecoveryStorage, RecoveryConfig, RecoveryApprovalConfig, ApprovalConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {IAccountRecoveryFacet} from \"./interfaces/IAccountRecoveryFacet.sol\";\n\n/**\n * @title Account Recovery Facet\n * @dev Contract that enables recovery of accounts when owner key is unavailable\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract AccountRecoveryFacet is IAccountRecoveryFacet, Modifiers {\n bytes constant UNINIT_CALL =\n abi.encodeWithSignature(\"uninitializeSigner()\");\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Approve recovery of account as guardian\n * @dev This method can only be called by guardian and guardian inputs the public key of the new owner\n * When the threshold(majority of guardians) passes, it automatically executes account recovery\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function approveAccountRecovery(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + _getApprovalValidationPeriod()\n );\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit RecoveryApproved(\n _recoveryPublicKey,\n msg.sender,\n approvalValidUntil\n );\n if (\n getRecoveryApprovalCountWithTimeValidity(recoveryPublicKeyHash) >=\n LibGuardian.majorityOfGuardians()\n ) _executeRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Revoke recovery of account as guardian\n * @dev This method can only be called by guardian and guardian inputs the public key of the new owner\n When the threshold(majority of guardians) passes, it automatically revokes account recovery when recovery is pending\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function revokeAccountRecoveryApproval(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n if (\n !rs\n .isNewOwnerApproved[recoveryPublicKeyHash][msg.sender].isApproved ||\n !(block.timestamp <\n rs\n .isNewOwnerApproved[recoveryPublicKeyHash][msg.sender]\n .validUntil)\n ) revert AccountRecoveryFacet__NonExistentApproval();\n\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(false, 0);\n emit RecoveryApprovalRevoked(_recoveryPublicKey, msg.sender);\n }\n\n /**\n * @notice Executes recovery with signatures or on-chain pre-approvals\n * @dev This method validates the signatures of guardians or checks the on-chain pre-approved calls to check if the threshold passes\n * When the threshold passes, account recovery is executed and revert otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _guardians Array of guardians address that are approving the recovery of Account\n * @param _signatures Array of signature bytes that signed the approval hash\n */\n function executeRecovery(\n bytes calldata _recoveryPublicKey,\n address[] calldata _guardians,\n bytes[] calldata _signatures\n ) external override {\n if (_isRecoveryPending())\n revert AccountRecoveryFacet__RecoveryAlreadyOngoing();\n if (_guardians.length != _signatures.length)\n revert AccountRecoveryFacet__InvalidArrayLength();\n validateNewOwner(_recoveryPublicKey);\n\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n\n _checkApprover(_guardians);\n _checkDuplicateOnChainApprover(recoveryPublicKeyHash, _guardians);\n\n if (\n _guardians.length +\n getRecoveryApprovalCountWithTimeValidity(\n recoveryPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians()\n ) revert AccountRecoveryFacet__InsufficientGuardians();\n for (uint256 i; i < _guardians.length; ) {\n if (!LibGuardian.isGuardian(_guardians[i]))\n revert AccountRecoveryFacet__InvalidGuardian();\n if (\n !SignatureChecker.isValidSignatureNow(\n _guardians[i],\n recoveryPublicKeyHash,\n _signatures[i]\n )\n ) revert AccountRecoveryFacet__InvalidGuardianSignature();\n unchecked {\n ++i;\n }\n }\n _executeRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Executes recovery of the account. Note that execution and finalization is a different process\n * @dev Executes the recovery and adds recovery data to recovery configuration. Locks the account\n * @param _recoveryPublicKey Public Key of the account for recovery\n */\n function _executeRecovery(bytes memory _recoveryPublicKey) internal {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n ++rs.nonce;\n uint64 executeAfter = uint64(block.timestamp + _getRecoveryPeriod());\n rs.recoveryConfigs[INNER_STRUCT] = RecoveryConfig(\n _recoveryPublicKey,\n executeAfter // NOTE: Remove guardian Count\n );\n LibAppStorage.setLock(\n block.timestamp + _getLockPeriod(),\n AccountRecoveryFacet.executeRecovery.selector\n );\n emit RecoveryExecuted(_recoveryPublicKey, executeAfter);\n }\n\n /**\n * @notice Finalize recovery after recovery pending period. Recovery pending period can be set by user beforehand in SecurityManager\n * @dev This method finalizes recovery and fully changes the ownership of the account to the newly inputted recovery public key\n */\n function finalizeRecovery() external override {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n if (\n uint64(block.timestamp) <=\n rs.recoveryConfigs[INNER_STRUCT].executeAfter\n ) revert AccountRecoveryFacet__RecoveryPeriodNotOver();\n bytes memory recoveryOwner = rs\n .recoveryConfigs[INNER_STRUCT]\n .recoveryPublicKey;\n\n delete rs.recoveryConfigs[INNER_STRUCT];\n\n LibAppStorage.setLock(0, bytes4(0));\n\n LibAppStorage.initiateSignerMigration();\n address verificationFacet = address(\n bytes20(\n LibDiamond.diamondStorage().facets[\n s.validateOwnerSignatureSelector\n ]\n )\n );\n (bool success, bytes memory result) = verificationFacet.delegatecall(\n UNINIT_CALL\n );\n if (!success) revert AccountRecoveryFacet__CallNotSuccesful();\n uint256 validationData = uint256(bytes32(result));\n if (validationData != 1)\n revert AccountRecoveryFacet__SignerUninitializationFailure();\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n recoveryOwner\n );\n (success, result) = verificationFacet.delegatecall(initCall);\n if (!success) revert AccountRecoveryFacet__CallNotSuccesful();\n validationData = uint256(bytes32(result));\n if (validationData != 1)\n revert AccountRecoveryFacet__SignerInitializationFailure();\n LibAppStorage.finalizeSignerMigration();\n emit RecoveryFinalized(recoveryOwner);\n }\n\n /**\n * @notice Approves the cancellation of recovery\n * @dev This method approves the cancellation of recovery when recovery is still pending - waiting for finalization\n * @param _recoveryPublicKey Bytes of public key which is pending for recovery\n */\n function approveCancelRecovery(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"CancelRecovery\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + _getApprovalValidationPeriod()\n );\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit RecoveryCancellationApproved(_recoveryPublicKey, msg.sender);\n if (\n getRecoveryApprovalCountWithTimeValidity(recoveryPublicKeyHash) >=\n LibGuardian.majorityOfGuardians()\n ) {\n _cancelRecovery(_recoveryPublicKey);\n }\n }\n\n /**\n * @notice Hardstops an ongoing recovery\n * @dev This method provides a safety mechanism to protect owners of malicious guardians.\n * Owners can hardstop recovery when an malicious guardians starts the recovery process.\n * @param _signature Signature of the owner that signs the hash to hardstop recovery\n */\n function hardstopRecovery(bytes calldata _signature) external override {\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n \"0\",\n \"HardstopRecovery\"\n );\n if (\n !SignatureChecker.isValidSignatureNow(\n address(this),\n recoveryPublicKeyHash,\n _signature\n )\n ) revert AccountRecoveryFacet__InvalidOwnerSignature();\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n ++rs.nonce;\n delete rs.recoveryConfigs[INNER_STRUCT];\n LibAppStorage.setLock(0, bytes4(0));\n emit RecoveryHardstopped();\n }\n\n /**\n * @notice Cancels recovery with signatures or on-chain pre-approvals\n * @dev This method validates the signatures of guardians or checks the on-chain pre-approved calls to check if the threshold passes\n * When the threshold passes, account recovery is canceled and revert otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _guardians Array of guardians address that are approving the recovery of Account\n * @param _signatures Array of signature bytes that signed the cancellation approval hash\n */\n function cancelRecovery(\n bytes calldata _recoveryPublicKey,\n address[] calldata _guardians,\n bytes[] calldata _signatures\n ) external override {\n if (_guardians.length != _signatures.length)\n revert AccountRecoveryFacet__InvalidArrayLength();\n validateNewOwner(_recoveryPublicKey);\n\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"CancelRecovery\"\n );\n\n _checkApprover(_guardians);\n _checkDuplicateOnChainApprover(recoveryPublicKeyHash, _guardians);\n\n if (\n _guardians.length +\n getRecoveryApprovalCountWithTimeValidity(\n recoveryPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians()\n ) revert AccountRecoveryFacet__InsufficientGuardians();\n for (uint256 i; i < _guardians.length; ) {\n if (!LibGuardian.isGuardian(_guardians[i]))\n revert AccountRecoveryFacet__CallerNotGuardian();\n if (\n !SignatureChecker.isValidSignatureNow(\n _guardians[i],\n recoveryPublicKeyHash,\n _signatures[i]\n )\n ) revert AccountRecoveryFacet__InvalidGuardianSignature();\n unchecked {\n ++i;\n }\n }\n _cancelRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Cancel recovery when the recovery is pending. Unlock the account as well\n * @dev This method checks if the recovery is pending and reverts if not pending.\n * It increases the recovery nonce and deletes the recovery information and gets a small portion of gas in return\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function _cancelRecovery(bytes memory _recoveryPublicKey) internal {\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n LibAppStorage.setLock(0, bytes4(0));\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n ++rs.nonce;\n delete rs.recoveryConfigs[INNER_STRUCT];\n emit RecoveryCanceled(_recoveryPublicKey);\n }\n\n /**\n * @notice Validates the format of public key to be used for recovery\n * @dev This method checks if the public key format is correct and reverts otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function validateNewOwner(bytes memory _recoveryPublicKey) public view {\n if (\n !IVerificationFacet(\n LibLoupe.facetAddress(s.validateOwnerSignatureSelector)\n ).isValidKeyType(_recoveryPublicKey)\n ) revert AccountRecoveryFacet__InvalidRecoveryPublicKey();\n }\n\n /**\n * @notice Checks if recovery is currently pending\n * @return isPending Boolean indicating if recovery is pending\n */\n function _isRecoveryPending() internal view returns (bool isPending) {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n isPending = (rs.recoveryConfigs[INNER_STRUCT].executeAfter > 0);\n }\n\n /**\n * @notice Calculate the recovery hash dependent on chain, wallet address, nonce with EIP-191 prefix for safety\n * @dev Returns the keccak256 hash of EIP-191 msg hash packed with public key, salt, nonce, wallet address, etc\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _saltString Salt string to uniquely identify each recovery hash and for security\n * @return recoveryKeyHash Bytes32 string of the recovery hash\n */\n function getApprovalRecoveryKeyHash(\n bytes memory _recoveryPublicKey,\n string memory _saltString\n ) public view override returns (bytes32 recoveryKeyHash) {\n recoveryKeyHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n _recoveryPublicKey,\n _saltString,\n address(this),\n block.chainid,\n LibFacetStorage.recoveryStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Check the onchain approval of guardians and returns the number of guardians that approved\n * @dev Loop through the guardian addresses and returns the number of guardians that approved this recovery hash\n * @param _recoveryPublicKeyHash Bytes hash of newly recovered public key and recovery value of the account\n * @return approvalCount Number of guardians that approved\n */\n function getRecoveryApprovalCountWithTimeValidity(\n bytes32 _recoveryPublicKeyHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n for (uint256 i; i < guardianLength; ) {\n if (isRecoveryApproved(_recoveryPublicKeyHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Checks if the recovery is approved by the given approver\n * @param _recoveryPublicKeyHash Hash of the public key and configuration for recovery\n * @param _approver Address of approver\n * @return isApproved Bool value if recovery hash is approved\n */\n function isRecoveryApproved(\n bytes32 _recoveryPublicKeyHash,\n address _approver\n ) public view override returns (bool isApproved) {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n if (\n rs\n .isNewOwnerApproved[_recoveryPublicKeyHash][_approver].isApproved &&\n block.timestamp <\n rs.isNewOwnerApproved[_recoveryPublicKeyHash][_approver].validUntil\n ) {\n isApproved = true;\n }\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _recoveryPublicKeyHash Hash of recovery information\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _recoveryPublicKeyHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isRecoveryApproved(_recoveryPublicKeyHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert AccountRecoveryFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the lock period of this wallet address from security manager\n * @return lockPeriod value of lock period\n */\n function _getLockPeriod() internal view returns (uint256 lockPeriod) {\n lockPeriod = securityManager.lockPeriodOf(address(this));\n if (lockPeriod == 0) revert AccountRecoveryFacet__InvalidLockPeriod();\n }\n\n /**\n * @notice Returns the lock period of this wallet address from security manager\n * @return recoveryPeriod value of recovery period\n */\n function _getRecoveryPeriod()\n internal\n view\n returns (uint256 recoveryPeriod)\n {\n recoveryPeriod = securityManager.recoveryPeriodOf(address(this));\n if (recoveryPeriod == 0)\n revert AccountRecoveryFacet__InvalidRecoveryPeriod();\n }\n\n /**\n * @notice Returns the approval validation period of this wallet address from security manager\n * @return approvalValidationPeriod value of approval validation period\n */\n function _getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod == 0)\n revert AccountRecoveryFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the recovery nonce of this wallet address from security manager\n * @return nonce value of recovery nonce\n */\n function getRecoveryNonce() public view override returns (uint128 nonce) {\n nonce = LibFacetStorage.recoveryStorage().nonce;\n }\n\n /**\n * @notice Returns the recovery information of the pending recovery\n * @return recoveryConfig value struct of pending recovery\n */\n function getPendingRecovery()\n public\n view\n override\n returns (RecoveryConfig memory recoveryConfig)\n {\n recoveryConfig = LibFacetStorage.recoveryStorage().recoveryConfigs[\n INNER_STRUCT\n ];\n }\n}\n" + }, + "contracts/facets/base/DiamondCutFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibGuardian} from \"../../libraries/LibGuardian.sol\";\nimport {ISecurityManager} from \"../../infrastructure/interfaces/ISecurityManager.sol\";\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibFacetStorage, DiamondCutApprovalConfig, ApprovalConfig} from \"../../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"../Modifiers.sol\";\nimport {IDiamondCut} from \"./interfaces/IDiamondCut.sol\";\n\n/**\n * @title DiamondCut Facet\n * @dev Responsible for adding/removing/replace facets in Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DiamondCutFacet is Modifiers, IDiamondCut {\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Updates the flag for the interfaceId\n * @param _interfaceId InterfaceID to update the mapping\n * @param _flag Bool value to update the mapping of the given interface ID\n */\n function updateSupportsInterface(\n bytes4 _interfaceId,\n bool _flag\n ) external override onlyWhenUnlocked {\n LibDiamond.enforceIsSelf();\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId] = _flag;\n emit SupportsInterfaceUpdated(_interfaceId, _flag);\n }\n\n /**\n * @notice Add/replace/remove any number of functions and optionally execute\n * a function with delegatecall when guardians don't exist\n * @param _diamondCut Contains the facet addresses and function selectors\n * @param _init The address of the contract or facet to execute _calldata. It's prohibited in Barz\n */\n function diamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata\n ) external override onlyWhenUnlocked {\n LibDiamond.enforceIsSelf();\n\n _checkFacetCutValidity(_diamondCut);\n // require approval from guardian if guardian exists\n if (0 != LibGuardian.guardianCount())\n revert DiamondCutFacet__InvalidRouteWithGuardian();\n if (address(0) != _init) revert DiamondCutFacet__InvalidInitAddress();\n\n ++LibFacetStorage.diamondCutStorage().nonce;\n LibDiamond.diamondCut(_diamondCut, address(0), \"\");\n }\n\n /**\n * @notice Add/replace/remove any number of functions and optionally execute\n * a function with delegatecall when guardians exist\n * @param _diamondCut Contains the facet addresses and function selectors\n * @param _approvers Guardian or owner address that approves the diamond cut\n * @param _signatures Signature of Guardians or owner that approves the diamond cut\n */\n function diamondCutWithGuardian(\n FacetCut[] calldata _diamondCut,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n ) external override onlyWhenUnlocked {\n if (_approvers.length != _signatures.length)\n revert DiamondCutFacet__InvalidArrayLength();\n _checkFacetCutValidity(_diamondCut);\n if (0 == LibGuardian.guardianCount())\n revert DiamondCutFacet__InvalidRouteWithGuardian();\n\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(cutHash, _approvers);\n\n bool onChainOwnerApproval = getOwnerCutApprovalWithTimeValidity(\n cutHash\n );\n\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n if (\n _approvers.length +\n getDiamondCutApprovalCountWithTimeValidity(cutHash) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert DiamondCutFacet__InsufficientApprovers();\n\n bool ownerApproved;\n for (uint256 i; i < _approvers.length; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n _approvers[i] != address(this)\n ) revert DiamondCutFacet__InvalidApprover();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert DiamondCutFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n cutHash,\n _signatures[i]\n )\n ) revert DiamondCutFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n if (!ownerApproved && !onChainOwnerApproval)\n revert DiamondCutFacet__LackOfOwnerApproval();\n\n ++LibFacetStorage.diamondCutStorage().nonce;\n LibDiamond.diamondCut(_diamondCut, address(0), \"\");\n }\n\n /**\n * @notice Approves diamond cut. This can only be called directly from guardian or owner\n * @param _diamondCut Contains the facet addresses and function selectors\n */\n function approveDiamondCut(\n FacetCut[] calldata _diamondCut\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\n if (LibGuardian.guardianCount() == 0)\n revert DiamondCutFacet__InvalidRouteWithoutGuardian();\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n _checkFacetCutValidity(_diamondCut);\n\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(\n true,\n approvalValidUntil\n );\n emit DiamondCutApproved(_diamondCut);\n if (\n (getDiamondCutApprovalCountWithTimeValidity(cutHash) >=\n LibGuardian.majorityOfGuardians()) &&\n getOwnerCutApprovalWithTimeValidity(cutHash)\n ) {\n ++LibFacetStorage.diamondCutStorage().nonce;\n LibDiamond.diamondCut(_diamondCut, address(0), \"\");\n }\n }\n\n /**\n * @notice Revokes the approval of diamond cut. This can only be called directly from guardian or owner\n * @param _diamondCut Contains the facet addresses and function selectors\n */\n function revokeDiamondCutApproval(\n FacetCut[] calldata _diamondCut\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\n if (!ds.isDiamondCutApproved[cutHash][msg.sender].isApproved)\n revert DiamondCutFacet__CannotRevokeUnapproved();\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(false, 0);\n emit DiamondCutApprovalRevoked(_diamondCut);\n }\n\n /**\n * @notice Gets the number of approvals of diamond cut from guardians\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n */\n function getDiamondCutApprovalCountWithTimeValidity(\n bytes32 _diamondCutHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardiansLength = guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n if (isCutApproved(_diamondCutHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n return approvalCount;\n }\n\n /**\n * @notice Returns if the owner has approved the diamond cut\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @return isApprovedByOwner Bool value showing if the owner approved the cut\n */\n function getOwnerCutApprovalWithTimeValidity(\n bytes32 _diamondCutHash\n ) public view override returns (bool isApprovedByOwner) {\n isApprovedByOwner = isCutApproved(_diamondCutHash, address(this));\n }\n\n /**\n * @notice Returns if the given approver has approved the diamond cut\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @param _approver Address of approver\n * @return isApproved Bool value showing if the approver approved the cut\n */\n function isCutApproved(\n bytes32 _diamondCutHash,\n address _approver\n ) public view override returns (bool isApproved) {\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n isApproved = (ds\n .isDiamondCutApproved[_diamondCutHash][_approver].isApproved &&\n block.timestamp <\n ds.isDiamondCutApproved[_diamondCutHash][_approver].validUntil);\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _diamondCutHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isCutApproved(_diamondCutHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert DiamondCutFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the diamond cut hash. This function ensures that this hash is safe from replay attack by including\n * salt, address, chainId, and nonce, etc.\n * @param _diamondCut Contains the facet addresses and function selectors\n * @return cutHash Diamond Cut Hash\n */\n function getDiamondCutHash(\n FacetCut[] calldata _diamondCut\n ) public view override returns (bytes32 cutHash) {\n cutHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n keccak256(abi.encode(_diamondCut)),\n address(this),\n block.chainid,\n LibFacetStorage.diamondCutStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Returns the approval validation Period\n * @dev This method fetches the validation period from the security manager\n * @return approvalValidationPeriod Approval validation period of Barz contract fetched from security manager\n */\n function getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod <= 0)\n revert DiamondCutFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the diamond cut nonce of this wallet\n * @dev This method fetches the nonce from diamond cut storage\n * @return cutNonce Nonce of diamond cut to protect from reply attacks\n */\n function getDiamondCutNonce()\n public\n view\n override\n returns (uint128 cutNonce)\n {\n cutNonce = LibFacetStorage.diamondCutStorage().nonce;\n }\n}\n" + }, + "contracts/facets/base/DiamondLoupeFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {IERC165} from \"../../interfaces/ERC/IERC165.sol\";\nimport {IERC1271} from \"../../interfaces/ERC/IERC1271.sol\";\nimport {IERC677Receiver} from \"../../interfaces/ERC/IERC677Receiver.sol\";\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC1155Receiver} from \"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\";\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../../libraries/LibLoupe.sol\";\nimport {LibUtils} from \"../../libraries/LibUtils.sol\";\nimport {IDiamondCut} from \"../../facets/base/interfaces/IDiamondCut.sol\";\nimport {IStorageLoupe} from \"./interfaces/IStorageLoupe.sol\";\nimport {IDiamondLoupe} from \"./interfaces/IDiamondLoupe.sol\";\n\n/**\n * @title DiamondLoupe Facet\n * @dev DiamondLoupe contract compatible with EIP-2535\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DiamondLoupeFacet is IDiamondLoupe, IStorageLoupe, IERC165 {\n // Diamond Loupe Functions\n ////////////////////////////////////////////////////////////////////\n /// These functions are expected to be called frequently by tools off-chain.\n\n /**\n * @notice Gets all facets and their selectors.\n * @dev Barz uses a special architecture called default fallback handler. Default Fallback handler is used as a middleware\n * that holds the mapping of facet function selector and facet address that Barz uses. This helps Barz to reduce\n * significant amount of gas during the initialization process.\n * Hence, this method aggregates both the facet information from DefaulFallbackHandler and in diamond storage and shows the data to users.\n * @return facets_ Facet\n */\n function facets() public view override returns (Facet[] memory facets_) {\n Facet[] memory defaultFacet = LibDiamond\n .diamondStorage()\n .defaultFallbackHandler\n .facets();\n Facet[] memory _facets = LibLoupe.facets();\n uint256 numFacets = _facets.length;\n bytes4[] memory keys;\n address[] memory values;\n for (uint256 i; i < numFacets; ) {\n uint256 selectorsLength = _facets[i].functionSelectors.length;\n for (uint256 j; j < selectorsLength; ) {\n (keys, values) = LibUtils.setValue(\n keys,\n values,\n _facets[i].functionSelectors[j],\n _facets[i].facetAddress\n );\n unchecked {\n ++j;\n }\n }\n unchecked {\n ++i;\n }\n }\n {\n bool iIncrement;\n for (uint256 i; i < defaultFacet.length; ) {\n bool jIncrement;\n for (\n uint256 j;\n j < defaultFacet[i].functionSelectors.length;\n\n ) {\n if (\n LibUtils.getValue(\n keys,\n values,\n defaultFacet[i].functionSelectors[j]\n ) != address(0)\n ) {\n if (defaultFacet[i].functionSelectors.length == 1) {\n defaultFacet = LibUtils.removeFacetElement(\n defaultFacet,\n i\n );\n iIncrement = true;\n break;\n }\n defaultFacet[i].functionSelectors = LibUtils\n .removeElement(\n defaultFacet[i].functionSelectors,\n j\n );\n jIncrement = true;\n }\n if (!jIncrement) {\n unchecked {\n ++j;\n }\n } else {\n jIncrement = false;\n }\n }\n if (!iIncrement) {\n unchecked {\n ++i;\n }\n } else {\n iIncrement = false;\n }\n }\n }\n {\n uint256 facetLength = numFacets + defaultFacet.length;\n facets_ = new Facet[](facetLength);\n uint256 defaultFacetIndex;\n for (uint256 i; i < facetLength; ) {\n if (i < numFacets) {\n facets_[i] = _facets[i];\n bool jIncrementor;\n for (uint256 j; j < defaultFacet.length; ) {\n if (\n facets_[i].facetAddress ==\n defaultFacet[j].facetAddress\n ) {\n facets_[i].functionSelectors = LibUtils.mergeArrays(\n _facets[i].functionSelectors,\n defaultFacet[j].functionSelectors\n );\n defaultFacet = LibUtils.removeFacetElement(\n defaultFacet,\n j\n );\n jIncrementor = true;\n {\n facets_ = LibUtils.removeFacetElement(\n facets_,\n facets_.length - 1\n );\n }\n --facetLength;\n }\n if (!jIncrementor) {\n unchecked {\n ++j;\n }\n } else {\n jIncrementor = false;\n }\n }\n } else {\n facets_[i] = defaultFacet[defaultFacetIndex];\n ++defaultFacetIndex;\n }\n unchecked {\n ++i;\n }\n }\n }\n }\n\n /**\n * @notice Gets all the function selectors provided by a facet.\n * @param _facet The facet address.\n * @return facetFunctionSelectors_\n */\n function facetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n Facet[] memory facet = facets();\n uint256 facetLength = facet.length;\n for (uint256 i; i < facetLength; ) {\n if (facet[i].facetAddress == _facet)\n return facet[i].functionSelectors;\n unchecked {\n ++i;\n }\n }\n return facetFunctionSelectors_;\n }\n\n /**\n * @notice Get all the facet addresses used by Barz.\n * @return facetAddresses_\n */\n function facetAddresses()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n Facet[] memory facet = facets();\n uint256 facetLength = facet.length;\n facetAddresses_ = new address[](facetLength);\n for (uint256 i; i < facetLength; ) {\n facetAddresses_[i] = facet[i].facetAddress;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Gets the facet that supports the given selector.\n * @dev If facet is not found return address(0).\n * @param _functionSelector The function selector.\n * @return facetAddress_ The facet address.\n */\n function facetAddress(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n\n facetAddress_ = address(bytes20(ds.facets[_functionSelector]));\n if (facetAddress_ == address(0)) {\n facetAddress_ = IDiamondLoupe(ds.defaultFallbackHandler)\n .facetAddress(_functionSelector);\n }\n }\n\n /**\n * @notice SupportInterface to be compatible with EIP 165\n * @param _interfaceId Interface ID for detecting the interface\n * @return isSupported Bool value showing if the standard is supported in the contract\n */\n function supportsInterface(\n bytes4 _interfaceId\n ) external view override returns (bool isSupported) {\n isSupported =\n _interfaceId == type(IERC165).interfaceId ||\n _interfaceId == IDiamondCut.diamondCut.selector ||\n _interfaceId == type(IDiamondLoupe).interfaceId ||\n _interfaceId == type(IERC1155Receiver).interfaceId ||\n _interfaceId == type(IERC721Receiver).interfaceId ||\n _interfaceId == type(IERC777Recipient).interfaceId ||\n _interfaceId == IERC1271.isValidSignature.selector ||\n _interfaceId == type(IERC677Receiver).interfaceId ||\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId];\n }\n\n /**\n * @notice Returns the facet from the diamond storage. This excludes the facets from the default fallback handler\n * @return facets_ Facet information attached directly to diamond storage\n */\n function facetsFromStorage()\n external\n view\n override\n returns (Facet[] memory facets_)\n {\n facets_ = LibLoupe.facets();\n }\n\n /**\n * @notice Returns the facet address attached to the given function selector. This excludes the facets from the default fallback handler\n * @param _functionSelector Function selector to fetch the facet address from diamond storage\n * @return facetAddress_ Facet address mapped with the function selector\n */\n function facetAddressFromStorage(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n facetAddress_ = LibLoupe.facetAddress(_functionSelector);\n }\n\n /**\n * @notice Returns all facet addresses attached directly to diamond storage. This excludes the facets from the default fallback handler\n * @return facetAddresses_ All facet addresses attached directly to diamond storage\n */\n function facetAddressesFromStorage()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n facetAddresses_ = LibLoupe.facetAddresses();\n }\n\n /**\n * @notice Returns function selectors of given facet address attached directly to diamond storage. This excludes the facets from the default fallback handler\n * @param _facet Facet address to fetch the facet function selectors from diamond storage\n * @return facetFunctionSelectors_ Facet function selectors of the given facet address\n */\n function facetFunctionSelectorsFromStorage(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n facetFunctionSelectors_ = LibLoupe.facetFunctionSelectors(_facet);\n }\n}\n" + }, + "contracts/facets/base/interfaces/IDiamondCut.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title DiamondCut Facet Interface\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IDiamondCut {\n error DiamondCutFacet__InvalidRouteWithGuardian();\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\n error DiamondCutFacet__InvalidArrayLength();\n error DiamondCutFacet__InsufficientApprovers();\n error DiamondCutFacet__InvalidApprover();\n error DiamondCutFacet__InvalidApproverSignature();\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\n error DiamondCutFacet__CannotRevokeUnapproved();\n error DiamondCutFacet__LackOfOwnerApproval();\n error DiamondCutFacet__OwnerAlreadyApproved();\n error DiamondCutFacet__DuplicateApproval();\n error DiamondCutFacet__InvalidInitAddress();\n\n event DiamondCutApproved(FacetCut[] diamondCut);\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\n\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\n\n enum FacetCutAction {\n Add,\n Replace,\n Remove\n }\n // Add=0, Replace=1, Remove=2\n\n struct FacetCut {\n address facetAddress;\n FacetCutAction action;\n bytes4[] functionSelectors;\n }\n\n /// @notice Add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param diamondCut Contains the facet addresses and function selectors\n /// @param init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function diamondCut(\n FacetCut[] calldata diamondCut,\n address init,\n bytes calldata _calldata\n ) external;\n\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\n\n function diamondCutWithGuardian(\n FacetCut[] calldata diamondCut,\n address[] calldata approvers,\n bytes[] calldata signatures\n ) external;\n\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\n\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\n\n function getDiamondCutApprovalCountWithTimeValidity(\n bytes32 diamondCutHash\n ) external view returns (uint256);\n\n function getOwnerCutApprovalWithTimeValidity(\n bytes32 diamondCutHash\n ) external view returns (bool);\n\n function isCutApproved(\n bytes32 diamondCutHash,\n address approver\n ) external view returns (bool);\n\n function getDiamondCutHash(\n FacetCut[] calldata diamondCut\n ) external view returns (bytes32);\n\n function getDiamondCutNonce() external view returns (uint128);\n}\n" + }, + "contracts/facets/base/interfaces/IDiamondLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n// A loupe is a small magnifying glass used to look at diamonds.\n// These functions look at diamonds\ninterface IDiamondLoupe {\n /// These functions are expected to be called frequently\n /// by tools.\n\n struct Facet {\n address facetAddress;\n bytes4[] functionSelectors;\n }\n\n /// @notice Gets all facet addresses and their four byte function selectors.\n /// @return facets_ Facet\n function facets() external view returns (Facet[] memory facets_);\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n /// @return facetFunctionSelectors_\n function facetFunctionSelectors(\n address _facet\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses()\n external\n view\n returns (address[] memory facetAddresses_);\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(\n bytes4 _functionSelector\n ) external view returns (address facetAddress_);\n}\n" + }, + "contracts/facets/base/interfaces/IStorageLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"./IDiamondLoupe.sol\";\n\n/**\n * @title LoupeFromStorage Interface\n * @dev Interface contract to function as a loupe facet directly attached to diamond storage of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IStorageLoupe {\n /// These functions are expected to be called frequently\n /// by tools.\n\n /// @notice Gets all facet addresses and their four byte function selectors.\n /// @return facets_ Facet\n function facetsFromStorage()\n external\n view\n returns (IDiamondLoupe.Facet[] memory);\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n function facetFunctionSelectorsFromStorage(\n address _facet\n ) external view returns (bytes4[] memory);\n\n /// @notice Get all the facet addresses used by a diamond.\n function facetAddressesFromStorage()\n external\n view\n returns (address[] memory);\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n function facetAddressFromStorage(\n bytes4 _functionSelector\n ) external view returns (address);\n}\n" + }, + "contracts/facets/GuardianFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibFacetStorage, GuardianStorage, StorageConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IGuardianFacet} from \"./interfaces/IGuardianFacet.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Guardian Facet\n * @dev Contract that enables addition/removal of guardians from Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract GuardianFacet is IGuardianFacet {\n ISecurityManager public immutable securityManager;\n uint8 public constant INNER_STRUCT = 0;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Add guardians to Barz.\n * @dev This method internally calls addGuardian which checks the validity of guardian address and adds\n * as guardian if valid\n * @param _guardians Array of addresses to add as guardian\n */\n function addGuardians(address[] calldata _guardians) external override {\n LibDiamond.enforceIsSelf();\n for (uint256 i; i < _guardians.length; ) {\n addGuardian(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Add a guardian to Barz.\n * @dev This method checks if the function is called by the owner and validates the address of guardian\n * When the validation passes, guardian address is added to the pending state waiting for confirmation\n * @param _guardian Address to add as guardian\n */\n function addGuardian(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (_guardian == address(this))\n revert GuardianFacet__GuardianCannotBeSelf();\n if (isGuardian(_guardian)) revert GuardianFacet__DuplicateGuardian();\n if (_guardian == address(0))\n revert GuardianFacet__ZeroAddressGuardian();\n if (\n keccak256(abi.encodePacked(_guardian)) ==\n keccak256(IVerificationFacet(address(this)).owner())\n ) revert GuardianFacet__OwnerCannotBeGuardian();\n\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n if (\n gs.pending[id] != 0 ||\n block.timestamp <= gs.pending[id] + getSecurityWindow()\n ) revert GuardianFacet__DuplicateGuardianAddition();\n\n uint256 securityPeriod = getAdditionSecurityPeriod();\n gs.pending[id] = block.timestamp + securityPeriod;\n emit GuardianAdditionRequested(\n _guardian,\n block.timestamp + securityPeriod\n );\n }\n\n /**\n * @notice Remove guardians from Barz.\n * @dev This method internally calls removeGuardian which checks the validity of guardian and removes\n * guardian when the request is valid\n * @param _guardians Array of addresses to be removed\n */\n function removeGuardians(address[] calldata _guardians) external override {\n LibDiamond.enforceIsSelf();\n for (uint256 i; i < _guardians.length; ) {\n removeGuardian(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Remove a guardian from Barz.\n * @dev This method validates if the guardian to be removed is a guardian and puts the guardian removal\n * to a pending state waiting to be confirmed.\n * @param _guardian Address of guardian to be removed\n */\n function removeGuardian(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n if (!isGuardian(_guardian)) revert GuardianFacet__NonExistentGuardian();\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n if (\n gs.pending[id] != 0 ||\n block.timestamp <= gs.pending[id] + getSecurityWindow()\n ) revert GuardianFacet__DuplicateGuardianRemoval();\n\n uint256 securityPeriod = getRemovalSecurityPeriod();\n gs.pending[id] = block.timestamp + securityPeriod;\n emit GuardianRemovalRequested(\n _guardian,\n block.timestamp + securityPeriod\n );\n }\n\n /**\n * @notice Confirm addition of guardians\n * @dev This method internally calls confirmGuardianAddition which checks the validity of pending request.\n * Guardians are fully added when they pass the validation. Anyone can call this function.\n * @param _guardians Array of guardian addresses to be added\n */\n function confirmGuardianAdditions(\n address[] calldata _guardians\n ) external override {\n for (uint256 i; i < _guardians.length; ) {\n confirmGuardianAddition(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Confirm addition of a guardian\n * @dev This method checks the validity of pending request.\n * Guardians are fully added when they pass the validation. Anyone can call this function.\n * @param _guardian Guardian address to be added\n */\n function confirmGuardianAddition(address _guardian) public override {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingAddition();\n if (gs.pending[id] >= block.timestamp)\n revert GuardianFacet__PendingAdditionNotOver();\n if (block.timestamp >= gs.pending[id] + getSecurityWindow())\n revert GuardianFacet__PendingAdditionExpired();\n\n _addGuardian(_guardian);\n\n delete gs.pending[id];\n emit GuardianAdded(_guardian);\n }\n\n /**\n * @notice Confirm removal of guardians\n * @dev This method internally calls confirmGuardianRemoval to check the validity guardian removal confirmation.\n * Guardians are fully removed when they pass the validation. Anyone can call this function.\n * @param _guardians Array of guardian addresses to be removed\n */\n function confirmGuardianRemovals(\n address[] calldata _guardians\n ) external override {\n for (uint256 i; i < _guardians.length; ) {\n confirmGuardianRemoval(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Confirm removal of a guardian\n * @dev This method checks the validity guardian removal confirmation.\n * Guardian is fully removed when they pass the validation. Anyone can call this function.\n * @param _guardian Guardian address to be removed\n */\n function confirmGuardianRemoval(address _guardian) public override {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingRemoval();\n if (gs.pending[id] >= block.timestamp)\n revert GuardianFacet__PendingRemovalNotOver();\n if (block.timestamp >= gs.pending[id] + getSecurityWindow())\n revert GuardianFacet__PendingAdditionExpired();\n\n _removeGuardian(_guardian);\n delete gs.pending[id];\n emit GuardianRemoved(_guardian);\n }\n\n /**\n * @notice Cancel pending guardian addition\n * @dev This method checks if the previous request for guardian request exists.\n * It reverts if previous request is not pending and cancels the addition otherwise.\n * @param _guardian Guardian address to be canceled from addition\n */\n function cancelGuardianAddition(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingAddition();\n delete gs.pending[id];\n emit GuardianAdditionCancelled(_guardian);\n }\n\n /**\n * @notice Cancel pending guardian removal\n * @dev This method checks if the previous request for guardian request exists.\n * It reverts if previous request is not pending and cancels the removal otherwise.\n * @param _guardian Guardian address to be canceled from removal\n */\n function cancelGuardianRemoval(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingRemoval();\n delete gs.pending[id];\n emit GuardianRemovalCancelled(_guardian);\n }\n\n /**\n * @notice Get the addition security period of current account from security manager\n * @dev This method returns the uint value if addition security period\n * @return additionSecurityPeriod Uint256 value of addition security period\n */\n function getAdditionSecurityPeriod()\n public\n view\n override\n returns (uint256 additionSecurityPeriod)\n {\n additionSecurityPeriod = securityManager.additionSecurityPeriodOf(\n address(this)\n );\n if (additionSecurityPeriod == 0)\n revert GuardianFacet__InvalidAdditionSecurityPeriod();\n }\n\n /**\n * @notice Get the removal security period of current account from security manager\n * @dev This method returns the uint value if removal security period\n * @return removalSecurityPeriod Uint256 value of removal security period\n */\n function getRemovalSecurityPeriod()\n public\n view\n override\n returns (uint256 removalSecurityPeriod)\n {\n removalSecurityPeriod = securityManager.removalSecurityPeriodOf(\n address(this)\n );\n if (removalSecurityPeriod == 0)\n revert GuardianFacet__InvalidRemovalSecurityPeriod();\n }\n\n /**\n * @notice Get the security window of current account from security manager\n * @dev This method returns the uint value if security window\n * @return securityWindow Uint256 value of removal security period\n */\n function getSecurityWindow()\n public\n view\n override\n returns (uint256 securityWindow)\n {\n securityWindow = securityManager.securityWindowOf(address(this));\n if (securityWindow == 0) revert GuardianFacet__InvalidSecurityWindow();\n }\n\n /**\n * @notice Checks if the addition of the given guardian address is pending\n * @dev This method returns the bool value of whether the guardian address is pending addition\n * @return isPending Bool value of representing the pending of guardian addition\n */\n function isAdditionPending(\n address _guardian\n ) public view override returns (bool isPending) {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n isPending = _isPending(id);\n }\n\n /**\n * @notice Checks if the removal of the given guardian address is pending\n * @dev This method returns the bool value of whether the guardian address is pending removal\n * @return isPending Bool value of representing the pending of guardian removal\n */\n function isRemovalPending(\n address _guardian\n ) public view override returns (bool isPending) {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n isPending = _isPending(id);\n }\n\n /**\n * @notice Checks if the given hash is pending\n * @dev This method returns the bool value whether the hash is pending\n * @return isPending Bool value of representing the pending of guardian operation\n */\n function _isPending(\n bytes32 _idHash\n ) internal view returns (bool isPending) {\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n isPending = ((gs.pending[_idHash] > 0 &&\n gs.pending[_idHash] < block.timestamp) &&\n block.timestamp < gs.pending[_idHash] + getSecurityWindow());\n }\n\n /**\n * @notice Adds guardian to storage config. This is called when guardian is fully added.\n * @dev This method add guardian address and config information to Facet Storage dedicated for guardian\n * When this function is called, guardian is fully added to this Barz Smart Account\n * @param _guardian Address of guardian to be added\n */\n function _addGuardian(address _guardian) internal {\n if (!isAdditionPending(_guardian))\n revert GuardianFacet__InvalidGuardianAddition();\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n if (config.info[_guardian].exists)\n revert GuardianFacet__AlreadyExists();\n\n config.info[_guardian].exists = true;\n config.info[_guardian].index = uint128(config.addresses.length);\n config.addresses.push(_guardian);\n }\n\n /**\n * @notice Removes guardian to storage config. This is called when guardian is fully removed.\n * @dev This method remove guardian address and config information to Facet Storage dedicated for guardian\n * When this function is called, guardian is fully removed from this Barz Smart Account\n * @param _guardian Address of guardian to be removed\n */\n function _removeGuardian(address _guardian) internal {\n if (!isRemovalPending(_guardian))\n revert GuardianFacet__InvalidGuardianRemoval();\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n if (!config.info[_guardian].exists)\n revert GuardianFacet__NonExistentGuardian();\n\n address lastAddress = config.addresses[config.addresses.length - 1];\n if (_guardian != lastAddress) {\n uint128 targetIndex = config.info[_guardian].index;\n config.addresses[targetIndex] = lastAddress;\n config.info[lastAddress].index = targetIndex;\n }\n config.addresses.pop();\n delete config.info[_guardian];\n\n emit GuardianRemoved(_guardian);\n }\n\n /**\n * @notice Reads guardian storage and fetches the addresses into an array from the storage\n * @dev This method fetches the guardian storage and returns the list of guardian addresses\n * @return addresses Array of addresses comprised of guardian\n */\n function getGuardians()\n public\n view\n override\n returns (address[] memory addresses)\n {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n addresses = new address[](config.addresses.length);\n uint256 addressesLen = config.addresses.length;\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the number of majority of guardians\n * @return majorityOfGuardians_ Number of majority of guardians e.g., 2 if 3 guardians / 3 if 5 guardians\n */\n function majorityOfGuardians()\n public\n view\n override\n returns (uint256 majorityOfGuardians_)\n {\n majorityOfGuardians_ = LibGuardian.majorityOfGuardians();\n }\n\n /**\n * @notice Reads guardian storage and fetches the addresses into an array from the storage\n * @dev This method fetches the guardian storage and returns the list of guardian addresses\n * @return guardianNumber Array of guardians in the account\n */\n function guardianCount()\n public\n view\n override\n returns (uint256 guardianNumber)\n {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n guardianNumber = config.addresses.length;\n }\n\n /**\n * @notice Reads guardian storage and checks if the given address is a guardian\n * @return isGuardian_ Bool value representing if the given address is guardian\n */\n function isGuardian(\n address _guardian\n ) public view override returns (bool isGuardian_) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n isGuardian_ = config.info[_guardian].exists;\n }\n\n /**\n * @notice Checks if the guardian number is zero and returns of guardian facet is okay to be removed\n * @return isRemovable Bool value representing if guardian facet is removable\n */\n function isGuardianFacetRemovable()\n external\n view\n override\n returns (bool isRemovable)\n {\n isRemovable = (0 == guardianCount());\n }\n}\n" + }, + "contracts/facets/interfaces/IAccountFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IEntryPoint} from \"../../aa-4337/interfaces/IEntryPoint.sol\";\n\n/**\n * @title Account Facet Interface\n * @dev Interface of module contract that provides the account features and init/unitialization of signer\n * compatible with EIP-1271 & EIP-4337\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IAccountFacet {\n event AccountInitialized(\n IEntryPoint indexed entryPoint,\n bytes indexed ownerPublicKey\n );\n // NOTE: Added Below Event\n event VerificationSuccess(bytes32);\n event VerificationFailure(bytes32);\n\n error AccountFacet__InitializationFailure();\n error AccountFacet__RestrictionsFailure();\n error AccountFacet__NonExistentVerificationFacet();\n error AccountFacet__CallNotSuccessful();\n\n function initialize(\n address verificationFacet,\n address anEntryPoint,\n address facetRegistry,\n address _defaultFallBack,\n bytes calldata _ownerPublicKey\n ) external returns (uint256);\n\n function execute(address dest, uint256 value, bytes calldata func) external;\n\n function executeBatch(\n address[] calldata dest,\n uint256[] calldata value,\n bytes[] calldata func\n ) external;\n}\n" + }, + "contracts/facets/interfaces/IAccountRecoveryFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {RecoveryConfig} from \"../../libraries/LibFacetStorage.sol\";\n\n/**\n * @title Account Recovery Facet Interface\n * @dev Interface of contract that enables recovery of accounts when owner key is unavailable\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IAccountRecoveryFacet {\n event RecoveryExecuted(\n bytes indexed recoveryPublicKey,\n uint64 executeAfter\n );\n event RecoveryFinalized(bytes indexed recoveryPublicKey);\n event RecoveryCanceled(bytes indexed recoveryPublicKey);\n event RecoveryApproved(\n bytes indexed recoveryPublicKey,\n address indexed guardian,\n uint64 validUntil\n );\n event RecoveryApprovalRevoked(\n bytes indexed recoveryPublicKey,\n address indexed guardian\n );\n event RecoveryCancellationApproved(\n bytes indexed recoveryPublicKey,\n address indexed guardian\n );\n event RecoveryHardstopped();\n\n error AccountRecoveryFacet__CallerNotGuardian();\n error AccountRecoveryFacet__InvalidRecoveryPublicKey();\n error AccountRecoveryFacet__SignerInitializationFailure();\n error AccountRecoveryFacet__SignerUninitializationFailure();\n error AccountRecoveryFacet__InvalidArrayLength();\n error AccountRecoveryFacet__InsufficientGuardians();\n error AccountRecoveryFacet__RecoveryAlreadyOngoing();\n error AccountRecoveryFacet__NonexistentRecovery();\n error AccountRecoveryFacet__NonExistentApproval();\n error AccountRecoveryFacet__RecoveryPeriodNotOver();\n error AccountRecoveryFacet__InvalidLockPeriod();\n error AccountRecoveryFacet__InvalidRecoveryPeriod();\n error AccountRecoveryFacet__InvalidApprovalValidationPeriod();\n error AccountRecoveryFacet__InvalidGuardian();\n error AccountRecoveryFacet__InvalidGuardianSignature();\n error AccountRecoveryFacet__InvalidOwnerSignature();\n error AccountRecoveryFacet__CallNotSuccesful();\n error AccountRecoveryFacet__DuplicateApproval();\n\n function approveAccountRecovery(bytes calldata recoveryPublicKey) external;\n\n function revokeAccountRecoveryApproval(\n bytes calldata recoveryPublicKey\n ) external;\n\n function executeRecovery(\n bytes calldata recoveryPublicKey,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function finalizeRecovery() external;\n\n function approveCancelRecovery(bytes calldata recoveryPublicKey) external;\n\n function cancelRecovery(\n bytes calldata recoveryPublicKey,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function hardstopRecovery(bytes calldata signature) external;\n\n function getApprovalRecoveryKeyHash(\n bytes memory recoveryPublicKey,\n string memory saltString\n ) external view returns (bytes32);\n\n function getRecoveryApprovalCountWithTimeValidity(\n bytes32 recoveryPublicKeyHash\n ) external view returns (uint256);\n\n function isRecoveryApproved(\n bytes32 recoveryPublicKeyHash,\n address approver\n ) external view returns (bool);\n\n function getRecoveryNonce() external view returns (uint128);\n\n function getPendingRecovery() external view returns (RecoveryConfig memory);\n}\n" + }, + "contracts/facets/interfaces/IGuardianFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Guardian Facet Interface\n * @dev Interface of guaridna contract that enables addition/removal of guardians from Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IGuardianFacet {\n event GuardianAdditionRequested(\n address indexed guardian,\n uint256 executeAfter\n );\n event GuardianRemovalRequested(\n address indexed guardian,\n uint256 executeAfter\n );\n event GuardianAdditionCancelled(address indexed guardian);\n event GuardianRemovalCancelled(address indexed guardian);\n event GuardianAdded(address indexed guardian);\n event GuardianRemoved(address indexed guardian);\n\n error GuardianFacet__GuardianCannotBeSelf();\n error GuardianFacet__DuplicateGuardian();\n error GuardianFacet__OwnerCannotBeGuardian();\n error GuardianFacet__DuplicateGuardianAddition();\n error GuardianFacet__DuplicateGuardianRemoval();\n error GuardianFacet__UnknownPendingAddition();\n error GuardianFacet__PendingAdditionNotOver();\n error GuardianFacet__UnknownPendingRemoval();\n error GuardianFacet__PendingRemovalNotOver();\n error GuardianFacet__PendingAdditionExpired();\n error GuardianFacet__InvalidAdditionSecurityPeriod();\n error GuardianFacet__InvalidRemovalSecurityPeriod();\n error GuardianFacet__InvalidSecurityWindow();\n error GuardianFacet__NonExistentGuardian();\n error GuardianFacet__AlreadyExists();\n error GuardianFacet__InvalidGuardianAddition();\n error GuardianFacet__InvalidGuardianRemoval();\n error GuardianFacet__ZeroAddressGuardian();\n\n function addGuardian(address guardian) external;\n\n function addGuardians(address[] calldata guardians) external;\n\n function removeGuardian(address guardian) external;\n\n function removeGuardians(address[] calldata guardians) external;\n\n function confirmGuardianAddition(address guardian) external;\n\n function confirmGuardianAdditions(address[] calldata guardian) external;\n\n function confirmGuardianRemoval(address guardian) external;\n\n function confirmGuardianRemovals(address[] calldata guardian) external;\n\n function cancelGuardianAddition(address guardian) external;\n\n function cancelGuardianRemoval(address guardian) external;\n\n function isGuardian(address guardian) external view returns (bool);\n\n function isAdditionPending(address guardian) external view returns (bool);\n\n function isRemovalPending(address guardian) external view returns (bool);\n\n function isGuardianFacetRemovable() external view returns (bool);\n\n function getAdditionSecurityPeriod() external view returns (uint256);\n\n function getRemovalSecurityPeriod() external view returns (uint256);\n\n function getSecurityWindow() external view returns (uint256);\n\n function getGuardians() external view returns (address[] memory);\n\n function majorityOfGuardians() external view returns (uint256);\n\n function guardianCount() external view returns (uint256);\n}\n" + }, + "contracts/facets/interfaces/ILockFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Lock} from \"../../libraries/LibAppStorage.sol\";\n\n/**\n * @title Lock Facet Interface\n * @dev Interface of Lock contract that enables full lock/unlock of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface ILockFacet {\n event Locked(uint64 releaseAfter);\n event Unlocked();\n\n error LockFacet__InvalidRecoveryPeriod();\n error LockFacet__CannotUnlock();\n error LockFacet__InvalidSignature();\n error LockFacet__InvalidApprover();\n\n function lock() external;\n\n function unlock(address approver, bytes calldata signature) external;\n\n function getLockPeriod() external view returns (uint256);\n\n function isLocked() external view returns (bool);\n\n function getUnlockHash() external view returns (bytes32);\n\n function lockNonce() external view returns (uint128);\n\n function getPendingLock() external view returns (Lock memory);\n}\n" + }, + "contracts/facets/interfaces/IMultiSigFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Multi-sig facet Interface\n * @dev Interface of Multi-signature Facet with custom threshold.\n Wallet that adds this facet becomes a multi-sig wallet\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IMultiSigFacet {\n event ThresholdChanged(uint256 threshold);\n event OwnerAdded(address indexed newOwner);\n event OwnerRemoved(address indexed prevOwner);\n event HashApproved(bytes32 hashToApprove, address indexed owner);\n\n error MultiSigFacet__InvalidThreshold();\n error MultisigFacet__InvalidOwnerCount();\n error MultiSigFacet__InvalidRoute();\n error MultiSigFacet__InsufficientSignerLength();\n error MultiSigFacet__InvalidInitData();\n error MultiSigFacet__InvalidOwnerAddress();\n error MultiSigFacet__InvalidOwnerPair();\n error MultiSigFacet__InvalidSignatureLength();\n error MultiSigFacet__InvalidSignatureType();\n error MultiSigFacet__DuplicateOwner();\n error MultiSigFacet__OnlyOwner();\n\n function checkSignatures(\n bytes32 _dataHash,\n bytes calldata _signatures,\n uint256 _threshold\n ) external view returns (uint256);\n\n function splitSignatures(\n bytes calldata _signatures,\n uint256 _nextOffset\n )\n external\n pure\n returns (\n address owner,\n bytes memory signature,\n uint256 signatureType,\n uint256 nextOffset\n );\n\n function approveHash(bytes32 hashToApprove) external;\n\n function addOwner(address newOwner, uint256 threshold) external;\n\n function removeOwner(\n address prevOwner,\n address removedOwner,\n uint256 threshold\n ) external;\n\n function swapOwner(\n address prevOwner,\n address oldOwner,\n address newOwner\n ) external;\n\n function changeThreshold(uint256 _threshold) external;\n\n function isOwner(address owner) external view returns (bool);\n\n function getThreshold() external view returns (uint256);\n\n function getOwners() external view returns (address[] memory);\n}\n" + }, + "contracts/facets/interfaces/IRestrictionsFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Restrictions Facet Interface\n * @dev Interface of Restrictions contract that enables modular restrictions in Barz\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IRestrictionsFacet {\n event RestrictionAdded(address indexed restriction);\n event RestrictionRemoved(address indexed restriction);\n\n error RestrictionsFacet__EmptyRestrictionsList();\n error RestrictionsFacet__RestrictionNotFound();\n error RestrictionsFacet__RestrictionAlreadyExists();\n error RestrictionsFacet__ZeroAddressRestrictions();\n error RestrictionsFacet__ZeroAddressRestrictionsFacet();\n error RestrictionsFacet__RemainingRestrictionsCantBeEmpty();\n\n function initializeRestrictions(\n address[] memory _restrictions\n ) external returns (uint256);\n\n function uninitializeRestrictions() external returns (uint256);\n\n function getRestrictions() external view returns (address[] memory);\n\n function addRestriction(address restriction) external;\n\n function removeRestriction(address restriction) external;\n\n function verifyRestrictions(\n address from,\n address to,\n uint256 value,\n bytes calldata _calldata\n ) external returns (uint256);\n}\n" + }, + "contracts/facets/interfaces/ISignatureMigrationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureMigrationConfig} from \"../../libraries/LibFacetStorage.sol\";\n\n/**\n * @title Signature Migration Facet Interface\n * @dev Interface of Signature Migration contract for migrating user signature scheme to a new scheme user sets\n * Which could include\n * - ECDSA on Secp256K1 Curve\n * - ECDSA on Secp256R1 Curve\n * - BLS, Schnorr, etc\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface ISignatureMigrationFacet {\n event SignatureSchemeMigration(\n address indexed prevVerificationFacet,\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n event SignatureMigrationApproved(\n bytes newPublicKey,\n address indexed newVerificationFacet,\n bytes4[] verificationFuncSelectors,\n address indexed guardian,\n uint128 approvalValidUntil\n );\n event SignatureMigrationApprovalRevoked(\n bytes newPublicKey,\n address indexed newVerificationFacet,\n bytes4[] verificationFuncSelectors,\n address indexed guardian\n );\n event SignatureMigrationExecuted(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors,\n uint128 migrateAfter\n );\n event SignatureMigrationCanceled(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n event SignatureMigrationCancellationApproved(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n\n error SignatureMigrationFacet__SignerUninitializationFailure();\n error SignatureMigrationFacet__InvalidRouteWithGuardian();\n error SignatureMigrationFacet__InvalidKeyType();\n error SignatureMigrationFacet__InsufficientApprovers();\n error SignatureMigrationFacet__InvalidApproverSignature();\n error SignatureMigrationFacet__InvalidGuardian();\n error SignatureMigrationFacet__NonExistentApprover();\n error SignatureMigrationFacet__InvalidMigrationPeriod();\n error SignatureMigrationFacet__NonexistentMigration();\n error SignatureMigrationFacet__MigrationPeriodNotOver();\n error SignatureMigrationFacet__InvalidArrayLength();\n error SignatureMigrationFacet__InvalidApprovalValidationPeriod();\n error SignatureMigrationFacet__CannotRevokeUnapproved();\n error SignatureMigrationFacet__LackOfOwnerApproval();\n error SignatureMigrationFacet__OwnerAlreadyApproved();\n error SignatureMigrationFacet__NonExistentVerificationFacet();\n error SignatureMigrationFacet__DuplicateApproval();\n\n function migrateSignatureScheme(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function migrateSignatureSchemeWithGuardian(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors,\n address[] calldata approvers,\n bytes[] calldata signatures\n ) external;\n\n function approveSignatureSchemeMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function revokeSignatureMigrationApproval(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function finalizeSignatureMigration() external;\n\n function approveCancelSignatureMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function cancelSignatureMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function getApprovalMigrationKeyHash(\n bytes memory recoveryPublicKey,\n address newVerificationFacet,\n bytes4[] memory newVerificationFuncSelectors,\n string memory saltString\n ) external view returns (bytes32);\n\n function getMigrationOwnerApprovalWithTimeValidity(\n bytes32 publicKeyHash\n ) external view returns (bool);\n\n function getMigrationApprovalCountWithTimeValidity(\n bytes32 publicKeyHash\n ) external view returns (uint256);\n\n function isMigrationApproved(\n bytes32 migrationPublicKeyHash,\n address approver\n ) external view returns (bool);\n\n function getMigrationNonce() external view returns (uint128);\n\n function isMigrationPending() external view returns (bool);\n\n function getPendingMigration()\n external\n view\n returns (SignatureMigrationConfig memory);\n}\n" + }, + "contracts/facets/interfaces/IVerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {UserOperation} from \"../../aa-4337/interfaces/UserOperation.sol\";\n\n/**\n * @title Verification Facet Interface\n * @dev Implements logic for user ops signature verification\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface IVerificationFacet {\n event SignerInitialized(bytes);\n event SignerUninitialized();\n\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n error VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n error VerificationFacet__InitializationFailure();\n error VerificationFacet__InvalidFacetMapping();\n\n function initializeSigner(bytes memory) external returns (uint256);\n\n function uninitializeSigner() external returns (uint256);\n\n function validateOwnerSignatureSelector() external view returns (bytes4);\n\n function owner() external view returns (bytes memory);\n\n function isValidKeyType(bytes calldata) external view returns (bool);\n\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) external view returns (uint256);\n}\n" + }, + "contracts/facets/LockFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage, Lock} from \"../libraries/LibAppStorage.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibFacetStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {ILockFacet} from \"./interfaces/ILockFacet.sol\";\n\n/**\n * @title Lock Facet\n * @dev Contract that enables full lock/unlock of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract LockFacet is ILockFacet, Modifiers {\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Locks the account for the lock period. Lock period is defined in the security manager and it's customizable\n * This function can only be called when account is unlocked by owner or guardians\n * @dev This method checks the caller and if the account is currently locked and locks the account after fetching the\n * Lock period from the owner.\n */\n function lock() external override onlyGuardianOrOwner onlyWhenUnlocked {\n uint256 unlockTime = block.timestamp + getLockPeriod();\n ++LibFacetStorage.lockStorage().nonce;\n LibAppStorage.setLock(unlockTime, LockFacet.lock.selector);\n emit Locked(uint64(unlockTime));\n }\n\n /**\n * @notice Locks the account when the account is locked. This function can be called by anyone but must provide the approver address and signature.\n * The approver should be one of the guardians or owner.\n * @dev This method takes the approver address and the signature. After validating the address and the signature, it unlocks the account immediately.\n * Only one of the guardian or owner is required to lock and unlock the account.\n * @param _approver Address of approver approving the unlock of Barz account\n * @param _signature Signature of the approver that signed the msg hash for unlocking the account\n */\n function unlock(\n address _approver,\n bytes calldata _signature\n ) external override onlyWhenLocked {\n if (_approver != address(this) && !LibGuardian.isGuardian(_approver))\n revert LockFacet__InvalidApprover();\n if (\n !SignatureChecker.isValidSignatureNow(\n _approver,\n getUnlockHash(),\n _signature\n )\n ) revert LockFacet__InvalidSignature();\n _unlock();\n }\n\n /**\n * @notice Unlocks the account and increments the lock nonce\n */\n function _unlock() private {\n if (s.locks[INNER_STRUCT].locker != LockFacet.lock.selector)\n revert LockFacet__CannotUnlock();\n ++LibFacetStorage.lockStorage().nonce;\n LibAppStorage.setLock(0, bytes4(0));\n emit Unlocked();\n }\n\n /**\n * @notice Returns the lock period of current Barz account. Lock period information is held by Security Manager\n * @return lockPeriod Uint value of lock period in seconds\n */\n function getLockPeriod() public view override returns (uint256 lockPeriod) {\n lockPeriod = securityManager.lockPeriodOf(address(this));\n if (lockPeriod == 0) revert LockFacet__InvalidRecoveryPeriod();\n }\n\n /**\n * @notice Returns if the account is locked or not\n * @dev This method fetches the current block timestamp and compares that with release time.\n * After checking the timestamp and release time, it returns if the account is still locked or not.\n * @return isLocked_ Uint value of lock period in seconds\n */\n function isLocked() public view override returns (bool isLocked_) {\n isLocked_ = uint64(block.timestamp) < s.locks[INNER_STRUCT].release;\n }\n\n /**\n * @notice Calculates the unlock hash and returns the unlock hash safe from signature reply attack\n * @dev This method calculates the unlock hash with EIP-191 prefix, wallet address, chainID, and nonce\n * It packs the result and packs them and hashes it.\n * @return unlockHash Bytes32 unlock hash\n */\n function getUnlockHash() public view override returns (bytes32 unlockHash) {\n unlockHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n \"Unlock\",\n address(this),\n block.chainid,\n lockNonce()\n )\n )\n )\n );\n }\n\n /**\n * @notice Returns lock nonce of account. Reads nonce from lock storage within facet storage\n * @return lockNonce_ Uint128 value of lock nonce. This is incremented whenever the account is lock/unlocked\n */\n function lockNonce() public view override returns (uint128 lockNonce_) {\n lockNonce_ = LibFacetStorage.lockStorage().nonce;\n }\n\n /**\n * @notice Returns the overall information of current lock\n * @return pendingLock Struct value including all information of pending lock\n */\n function getPendingLock()\n public\n view\n override\n returns (Lock memory pendingLock)\n {\n pendingLock = s.locks[INNER_STRUCT];\n }\n}\n" + }, + "contracts/facets/Modifiers.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {IFacetRegistry} from \"../infrastructure/interfaces/IFacetRegistry.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\n\n/**\n * @title Modifiers\n * @dev Responsible for providing modifiers/util functions to Facet contracts\n * @author David Yongjun Kim (@Powerstream3604)\n */\nabstract contract Modifiers is BarzStorage {\n uint8 constant INNER_STRUCT = 0;\n\n error CallerNotGuardian();\n error CallerNotGuardianOrOwner();\n error DuplicateApprover();\n error ZeroApproverLength();\n error UnregisteredFacetAndSelectors();\n\n /**\n * @notice Modifier to only allow guardian to make a call, reverts if any other entity is the caller\n */\n modifier onlyGuardian() {\n if (!LibGuardian.isGuardian(msg.sender)) revert CallerNotGuardian();\n _;\n }\n\n /**\n * @notice Modifier to only allow guardian or owner to make a call, reverts if any other entity is the caller\n */\n modifier onlyGuardianOrOwner() {\n if (!LibGuardian.isGuardian(msg.sender) && address(this) != msg.sender)\n revert CallerNotGuardianOrOwner();\n _;\n }\n\n /**\n * @notice Checks if the approver address is the array is unique with no duplicate\n * @dev This method loops through the array and checks if a duplicate address exists, it reverts if duplicate address exists\n * @param approvers Array of address\n */\n function _checkApprover(\n address[] memory approvers\n ) internal pure returns (bool) {\n uint256 approverLength = approvers.length;\n if (0 == approverLength) revert ZeroApproverLength();\n for (uint256 i; i < approverLength - 1; ) {\n for (uint256 j = i + 1; j < approverLength; ) {\n if (approvers[i] == approvers[j]) {\n revert DuplicateApprover(); // Found a duplicate\n }\n unchecked {\n ++j;\n }\n }\n unchecked {\n ++i;\n }\n }\n return false; // No duplicates found\n }\n\n /**\n * @notice Checks if the facet getting added or replaced is registered to facet registry\n * @dev This method loops through the cut and checks if the facet getting added/replaced is registered to facet registry\n * @param _diamondCut Array of FacetCut, data for diamondCut defined in EIP-2535\n */\n function _checkFacetCutValidity(\n IDiamondCut.FacetCut[] memory _diamondCut\n ) internal view {\n uint256 diamondCutLength = _diamondCut.length;\n for (uint256 i; i < diamondCutLength; ) {\n if (\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Add ||\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Replace\n ) {\n if (\n !s.facetRegistry.areFacetFunctionSelectorsRegistered(\n _diamondCut[i].facetAddress,\n _diamondCut[i].functionSelectors\n )\n ) revert UnregisteredFacetAndSelectors();\n }\n unchecked {\n ++i;\n }\n }\n }\n}\n" + }, + "contracts/facets/RestrictionsFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, RestrictionsStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {IRestriction} from \"../restrictions/IRestriction.sol\";\nimport {IRestrictionsFacet} from \"./interfaces/IRestrictionsFacet.sol\";\n\n/**\n * @title Restrictions facet\n * @dev Responsible for storing and verifying different kinds of restrictions, for example:\n * - Whitelist / Blacklist\n * - Daily limits\n * - Trading time restrictions\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract RestrictionsFacet is IRestrictionsFacet {\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceRestrictionsInitialize();\n }\n\n /**\n * @notice Intialize restrictions of Barz. Restrictions facet call restriction contracts for restriction validation\n * before each call\n * @param _restrictions The initial array of restrictions.\n * @return initSuccess Int value showing if the initialization of restriction is successful\n */\n function initializeRestrictions(\n address[] calldata _restrictions\n ) public override returns (uint256 initSuccess) {\n LibDiamond.enforceIsSelf();\n LibAppStorage.enforceRestrictionsInitialize();\n\n if (_restrictions.length == 0) {\n // You can't initialize RestrictionsFacet with an empty list of restrictions\n revert RestrictionsFacet__EmptyRestrictionsList();\n }\n for (uint256 i; i < _restrictions.length; ) {\n if (_restrictions[i] == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictions();\n unchecked {\n ++i;\n }\n }\n\n LibFacetStorage.restrictionsStorage().restrictions = _restrictions;\n _updateRestrictionsMap(_restrictions, true);\n initSuccess = 1;\n }\n\n /**\n * @notice Unitialize restrictions of Barz\n * @return uninitSuccess Int value showing if the initialization of restriction is successful\n */\n function uninitializeRestrictions()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibDiamond.enforceIsSelf();\n LibAppStorage.setRestrictionsUninitialized();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n _updateRestrictionsMap(restrictionsStorage.restrictions, false);\n restrictionsStorage.restrictions = new address[](0);\n uninitSuccess = 1;\n }\n\n /**\n * @notice Returns the list of Restrictions contract address\n * @return restrictions Addresses of IRestriction which are currently active\n */\n function getRestrictions()\n public\n view\n override\n returns (address[] memory restrictions)\n {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n restrictions = restrictionsStorage.restrictions;\n }\n\n /**\n * @notice Adds restrictions to Barz with validation on the restriction contract address.\n * This method is only callable by the owner(self).\n * @param _restriction The address of the restriction to be added.\n */\n function addRestriction(address _restriction) external override {\n LibDiamond.enforceIsSelf();\n if (LibDiamond.restrictionsFacet() == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictionsFacet();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n if (_restriction == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictions();\n if (restrictionsStorage.exists[_restriction])\n revert RestrictionsFacet__RestrictionAlreadyExists();\n\n restrictionsStorage.restrictions.push(_restriction);\n restrictionsStorage.exists[_restriction] = true;\n\n emit RestrictionAdded(_restriction);\n }\n\n /**\n * @notice Remove restrictions from Barz if it existed. This method is only callable by the owner(self).\n * @param _restriction The address of the restriction to be removed.\n */\n function removeRestriction(address _restriction) external override {\n LibDiamond.enforceIsSelf();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n if (!restrictionsStorage.exists[_restriction])\n revert RestrictionsFacet__RestrictionNotFound();\n\n address[] storage restrictions = restrictionsStorage.restrictions;\n\n uint256 indexToDelete = restrictions.length;\n uint256 restrictionsLen = restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n if (restrictions[i] == _restriction) {\n indexToDelete = i;\n break;\n }\n unchecked {\n ++i;\n }\n }\n\n if (indexToDelete == 0 && restrictionsLen == 1) {\n revert RestrictionsFacet__RemainingRestrictionsCantBeEmpty();\n } else if (indexToDelete == restrictionsLen) {\n revert RestrictionsFacet__RestrictionNotFound();\n } else {\n restrictions[indexToDelete] = restrictions[restrictionsLen - 1];\n restrictions.pop();\n }\n\n restrictionsStorage.exists[_restriction] = false;\n emit RestrictionRemoved(_restriction);\n }\n\n /**\n * @notice Sets the restrictions address value mapping to true or false when adding/removing restriction contracts\n * @param _restrictions List of restriction contracts address\n * @param _newValue Bool value to flag to the list of restrictions contracts\n */\n function _updateRestrictionsMap(\n address[] memory _restrictions,\n bool _newValue\n ) internal {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n uint restrictionsLen = _restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n restrictionsStorage.exists[_restrictions[i]] = _newValue;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @dev Iterates over all restrictions and verifies each of them with the transaction parameters.\n * @param _from The address of the sender, that will be signing the transaction.\n * @param _to The receiving address.\n * @param _value Amount of ETH to transfer from sender to recipient.\n * @param _calldata Optional field to include arbitrary data.\n * @return 0 if all the checks passed, 1 otherwise.\n */\n function verifyRestrictions(\n address _from,\n address _to,\n uint256 _value,\n bytes calldata _calldata\n ) external returns (uint256) {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n uint restrictionsLen = restrictionsStorage.restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n IRestriction restriction = IRestriction(\n restrictionsStorage.restrictions[i]\n );\n bool checkPassed = restriction.check(_from, _to, _value, _calldata);\n if (!checkPassed) {\n return 1;\n }\n unchecked {\n ++i;\n }\n }\n\n return 0;\n }\n}\n" + }, + "contracts/facets/SignatureMigrationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, SignatureMigrationStorage, SignatureMigrationConfig, SignatureMigrationApprovalConfig, ApprovalConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IDiamondCut} from \"./base/interfaces/IDiamondCut.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {ISignatureMigrationFacet} from \"./interfaces/ISignatureMigrationFacet.sol\";\n\n/**\n * @title Signature Migration Facet\n * @dev Responsible for migrating user signature scheme to a new scheme user sets\n * Which could include\n * - ECDSA on Secp256K1 Curve\n * - ECDSA on Secp256R1 Curve\n * - BLS, Schnorr, etc\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract SignatureMigrationFacet is ISignatureMigrationFacet, Modifiers {\n bytes constant UNINIT_CALL =\n abi.encodeWithSignature(\"uninitializeSigner()\");\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This modifier verifies if the public key format matches with the new verification facet\n * @param _publicKey Bytes of public key to be validated for the new verification facet\n * @param _newVerificationFacet Address of new verification facet\n */\n modifier validateKeyType(\n bytes memory _publicKey,\n address _newVerificationFacet\n ) {\n if (\n !IVerificationFacet(_newVerificationFacet).isValidKeyType(\n _publicKey\n )\n ) revert SignatureMigrationFacet__InvalidKeyType();\n _;\n }\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n // IMPORTANT NOTE: In the client side when they call this function, the func selectors should be sorted in ascending order\n // to prevent different hash with same items in the array\n /**\n * @notice Moves the state of migration to a pending state. When pending state is over after pending period time,\n * Migration can be finalized. This function can only be called by self and when the account is unlocked.\n * @dev This method checks if the caller is self and if guardians exists. It migrates signature request to a pending state\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function migrateSignatureScheme(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n public\n override\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n // Only self contract can call this function\n LibDiamond.enforceIsSelf();\n // Should revert if guardian exist\n if (0 != LibGuardian.guardianCount())\n revert SignatureMigrationFacet__InvalidRouteWithGuardian();\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n // NOTE: Migration requires a pending period & confirmation from owner to prevent a\n // single call changing the ownership of the wallet\n /**\n * @notice Migrate signature scheme when guardians exists. Verifies the signature of guardians and moves migration to pending state.\n * Which can then be finalized when pending period is over. Owner's approval is mandatory for migration to happen\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _approvers List of approvers. This could include owner\n */\n function migrateSignatureSchemeWithGuardian(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n )\n public\n override\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n // Should revert if does not guardian exist\n if (0 == LibGuardian.guardianCount())\n revert SignatureMigrationFacet__InvalidRouteWithGuardian();\n if (_approvers.length != _signatures.length)\n revert SignatureMigrationFacet__InvalidArrayLength();\n\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(migrationPublicKeyHash, _approvers);\n\n bool onChainOwnerApproval = getMigrationOwnerApprovalWithTimeValidity(\n migrationPublicKeyHash\n );\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n\n if (\n _approvers.length +\n getMigrationApprovalCountWithTimeValidity(\n migrationPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert SignatureMigrationFacet__InsufficientApprovers();\n {\n // To prevent Stack too deep\n bool ownerApproved;\n for (uint256 i; i < _approvers.length; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n address(this) != _approvers[i]\n ) revert SignatureMigrationFacet__InvalidGuardian();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert SignatureMigrationFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n migrationPublicKeyHash,\n _signatures[i]\n )\n ) revert SignatureMigrationFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n\n if (!ownerApproved && !onChainOwnerApproval)\n revert SignatureMigrationFacet__LackOfOwnerApproval();\n }\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Internal function that moves signature mgiration to a pending state.\n * @dev This method increments migration nonce and sets the migration in the migration config. Emits events for migration execution\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _migrateSignatureScheme(\n address _newVerificationFacet,\n bytes memory _newPublicKey,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal {\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n\n ++ms.nonce;\n uint64 migrateAfter = uint64(block.timestamp + getMigrationPeriod());\n\n ms.migrationConfigs[INNER_STRUCT] = SignatureMigrationConfig(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n migrateAfter\n );\n\n emit SignatureMigrationExecuted(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors,\n migrateAfter\n );\n }\n\n /**\n * @notice Approves signature scheme migration on-chain. This can be called by owner or guardian only when the account is unlocked.\n * When the threshold of the migration approval passed and owner approval is granted, it automatically moves migration to a pending state\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function approveSignatureSchemeMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n public\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit SignatureMigrationApproved(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n msg.sender,\n approvalValidUntil\n );\n if (\n getMigrationApprovalCountWithTimeValidity(migrationPublicKeyHash) >=\n LibGuardian.majorityOfGuardians() &&\n getMigrationOwnerApprovalWithTimeValidity(migrationPublicKeyHash)\n )\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Revokes the approval of signature migration done on-chain. Emits revoke event when revoked.\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function revokeSignatureMigrationApproval(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n external\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n if (!isMigrationApproved(migrationPublicKeyHash, msg.sender))\n revert SignatureMigrationFacet__CannotRevokeUnapproved();\n\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(false, 0);\n emit SignatureMigrationApprovalRevoked(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n msg.sender\n );\n }\n\n /**\n * @notice Finalizes the pending signature scheme migration. This function can only be called by owner.\n * It removes the facets of the previous verification facet and adds the new verification facet.\n * After finalizing migration, it emits migration event which shows the change of the verification facet\n */\n function finalizeSignatureMigration() external override {\n // NOTE: Only owner can call this function\n LibDiamond.enforceIsSelf();\n\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n\n if (!isMigrationPending())\n revert SignatureMigrationFacet__NonexistentMigration();\n\n if (\n uint64(block.timestamp) <=\n ms.migrationConfigs[INNER_STRUCT].migrateAfter\n ) revert SignatureMigrationFacet__MigrationPeriodNotOver();\n address newVerificationFacet = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationVerificationFacet;\n bytes4[] memory newVerificationFuncSelectors = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationSelectors;\n bytes memory newPublicKey = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationPublicKey;\n\n address prevVerificationFacet = LibLoupe.facetAddress(\n s.validateOwnerSignatureSelector\n );\n if (prevVerificationFacet == address(0))\n revert SignatureMigrationFacet__NonExistentVerificationFacet();\n\n IDiamondCut.FacetCut[] memory UninitCut;\n IDiamondCut.FacetCut[] memory InitCut;\n {\n bytes4[] memory prevVerificationFuncSelectors = LibLoupe\n .facetFunctionSelectors(prevVerificationFacet);\n\n UninitCut = new IDiamondCut.FacetCut[](1);\n InitCut = new IDiamondCut.FacetCut[](1);\n UninitCut[0] = IDiamondCut.FacetCut({\n facetAddress: address(0),\n action: IDiamondCut.FacetCutAction.Remove,\n functionSelectors: prevVerificationFuncSelectors\n });\n InitCut[0] = IDiamondCut.FacetCut({\n facetAddress: newVerificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: newVerificationFuncSelectors\n });\n {\n IDiamondCut.FacetCut[]\n memory facetCuts = new IDiamondCut.FacetCut[](2);\n facetCuts[0] = UninitCut[0];\n facetCuts[1] = InitCut[0];\n _checkFacetCutValidity(facetCuts);\n }\n LibAppStorage.initiateSignerMigration();\n address verificationFacet = address(\n bytes20(\n LibDiamond.diamondStorage().facets[\n s.validateOwnerSignatureSelector\n ]\n )\n );\n\n (bool success, bytes memory result) = verificationFacet\n .delegatecall(UNINIT_CALL);\n require(success, \"MigrationFacet: uninitialize not successful\");\n uint256 validationData = uint256(bytes32(result));\n if (validationData == 0)\n revert SignatureMigrationFacet__SignerUninitializationFailure();\n\n LibDiamond.diamondCut(UninitCut, address(0), \"\");\n }\n {\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n newPublicKey\n );\n\n // Every Verification Facet should comply with initializeSigner(bytes)\n // to be compatible with the Barz contract(for initialization)\n LibDiamond.diamondCut(InitCut, newVerificationFacet, initCall);\n LibAppStorage.finalizeSignerMigration();\n emit SignatureSchemeMigration(\n prevVerificationFacet,\n newVerificationFacet,\n newPublicKey,\n newVerificationFuncSelectors\n );\n }\n }\n\n /**\n * @notice Approve cancellation of signature migration. If cancellation approval passes guardian threshold with owner approval\n * it automatically cancels the migration.\n * @dev This method checks if the caller is one of guardian or owner and sets true for the cancellation hash in the approval config.\n * It internally calls _cancelSignatureMigration for canceling the migration\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function approveCancelSignatureMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n external\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"CancelSignatureMigration\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit SignatureMigrationCancellationApproved(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n if (\n getMigrationApprovalCountWithTimeValidity(migrationPublicKeyHash) >=\n LibGuardian.majorityOfGuardians() &&\n getMigrationOwnerApprovalWithTimeValidity(migrationPublicKeyHash)\n )\n _cancelSignatureMigration(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Verifies the signature of guardians/owner and cancels the signature migration.\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _approvers List of approvers. This could include owner\n */\n function cancelSignatureMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n )\n external\n override\n validateKeyType(_newPublicKey, _newVerificationFacet)\n onlyWhenUnlocked\n {\n if (_approvers.length != _signatures.length)\n revert SignatureMigrationFacet__InvalidArrayLength();\n\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"CancelSignatureMigration\"\n );\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(migrationPublicKeyHash, _approvers);\n\n bool onChainOwnerApproval = getMigrationOwnerApprovalWithTimeValidity(\n migrationPublicKeyHash\n );\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n if (\n _approvers.length +\n getMigrationApprovalCountWithTimeValidity(\n migrationPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert SignatureMigrationFacet__InsufficientApprovers();\n {\n // To prevent stack too deep\n bool ownerApproved;\n for (uint256 i; i < _approvers.length; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n address(this) != _approvers[i]\n ) revert SignatureMigrationFacet__NonExistentApprover();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert SignatureMigrationFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n migrationPublicKeyHash,\n _signatures[i]\n )\n ) revert SignatureMigrationFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n if (!ownerApproved && !onChainOwnerApproval)\n revert SignatureMigrationFacet__LackOfOwnerApproval();\n }\n _cancelSignatureMigration(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Internal function that cancels signature migration.\n * @dev This method increments migration nonce and deletes the migration from the migration config. Emits events for migration cancellation\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _cancelSignatureMigration(\n address _newVerificationFacet,\n bytes memory _newPublicKey,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal {\n if (!isMigrationPending())\n revert SignatureMigrationFacet__NonexistentMigration();\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n ++ms.nonce;\n delete ms.migrationConfigs[INNER_STRUCT];\n emit SignatureMigrationCanceled(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Checks if the facets to be added from new verification facet is registered to facet registry\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _checkMigrationCutValidity(\n address _newVerificationFacet,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal view {\n IDiamondCut.FacetCut[] memory facetCuts = new IDiamondCut.FacetCut[](1);\n facetCuts[0] = IDiamondCut.FacetCut({\n facetAddress: _newVerificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: _newVerificationFuncSelectors\n });\n _checkFacetCutValidity(facetCuts);\n }\n\n /**\n * @notice Returns if the migration is pending of not\n * @dev This method fetches the migration storage and checks if the migrate after is above 0 value\n * @return isPending Bool value that shows if the migration is pending\n */\n function isMigrationPending()\n public\n view\n override\n returns (bool isPending)\n {\n SignatureMigrationStorage storage rs = LibFacetStorage\n .migrationStorage();\n isPending = rs.migrationConfigs[INNER_STRUCT].migrateAfter > 0;\n }\n\n /**\n * @notice Returns the migration hash. This function ensures that this hash is safe from replay attack by including\n * public key, verification facet, function selectors, salt, address, chainId, and nonce.\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _saltString Salt value for generating the migration hash\n * @return migrationKeyHash Bytes32 string of the migration key hash\n */\n function getApprovalMigrationKeyHash(\n bytes memory _newPublicKey,\n address _newVerificationFacet,\n bytes4[] memory _newVerificationFuncSelectors,\n string memory _saltString\n ) public view override returns (bytes32 migrationKeyHash) {\n migrationKeyHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n _newPublicKey,\n _newVerificationFacet,\n keccak256(abi.encode(_newVerificationFuncSelectors)),\n _saltString,\n address(this),\n block.chainid,\n LibFacetStorage.migrationStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Checks if the owner approved the hash for migration\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @return isApprovedByOwner Bool value of showing if the owner approved it or not\n */\n function getMigrationOwnerApprovalWithTimeValidity(\n bytes32 _migrationPublicKeyHash\n ) public view override returns (bool isApprovedByOwner) {\n isApprovedByOwner = isMigrationApproved(\n _migrationPublicKeyHash,\n address(this)\n );\n }\n\n /**\n * @notice Checks how many of the guardians approved the migration hash\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @return approvalCount Number of approvals\n */\n function getMigrationApprovalCountWithTimeValidity(\n bytes32 _migrationPublicKeyHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardiansLength = guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n if (isMigrationApproved(_migrationPublicKeyHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n return approvalCount;\n }\n\n /**\n * @notice Checks if the migration is approved by the given approver\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @param _approver Address of approver\n * @return isApproved Bool value if migration hash is approved\n */\n function isMigrationApproved(\n bytes32 _migrationPublicKeyHash,\n address _approver\n ) public view override returns (bool isApproved) {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n isApproved = (ms\n .isMigrationApproved[_migrationPublicKeyHash][_approver].isApproved &&\n block.timestamp <\n ms\n .isMigrationApproved[_migrationPublicKeyHash][_approver]\n .validUntil);\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _migrationPublicKeyHash Hash of migration information\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _migrationPublicKeyHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isMigrationApproved(_migrationPublicKeyHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert SignatureMigrationFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the migration period of this wallet\n * @dev This method fetches the migration period from the security manager\n * @return migrationPeriod Migration period of Barz contract fetched from security manager\n */\n function getMigrationPeriod()\n internal\n view\n returns (uint128 migrationPeriod)\n {\n migrationPeriod = securityManager.migrationPeriodOf(address(this));\n if (migrationPeriod == 0)\n revert SignatureMigrationFacet__InvalidMigrationPeriod();\n }\n\n /**\n * @notice Returns the validation period of this wallet\n * @dev This method fetches the validation period from the security manager\n * @return approvalValidationPeriod Validation period of Barz contract fetched from security manager\n */\n function getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod == 0)\n revert SignatureMigrationFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the migration nonce of this wallet\n * @dev This method fetches the nonce from migration storage\n * @return migrationNonce Nonce of migration to protect from reply attacks\n */\n function getMigrationNonce()\n public\n view\n override\n returns (uint128 migrationNonce)\n {\n migrationNonce = LibFacetStorage.migrationStorage().nonce;\n }\n\n /**\n * @notice Returns the migration configuration of this wallet\n * @dev This method fetches the migration config from the migration storage\n * @return pendingMigrationConfig Migration config currently pending for signature migration\n */\n function getPendingMigration()\n external\n view\n override\n returns (SignatureMigrationConfig memory pendingMigrationConfig)\n {\n pendingMigrationConfig = LibFacetStorage\n .migrationStorage()\n .migrationConfigs[INNER_STRUCT];\n }\n}\n" + }, + "contracts/facets/TokenReceiverFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {IERC1155Receiver} from \"../interfaces/ERC/IERC1155Receiver.sol\";\nimport {IERC677Receiver} from \"../interfaces/ERC/IERC677Receiver.sol\";\n\n/**\n * @title TokenReceiver Facet\n * @dev Contract that enables receiving ERC721/ERC1155/ERC777/ERC677 Tokens with safe transfer\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract TokenReceiverFacet is\n IERC721Receiver,\n IERC1155Receiver,\n IERC777Recipient,\n IERC677Receiver\n{\n /**\n * @notice Handles ERC721 Token callback.\n * return Standardized onERC721Received return value.\n */\n function onERC721Received(\n address,\n address,\n uint256,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC721Receiver.onERC721Received.selector;\n }\n\n /**\n * @notice Handles ERC1155 Token callback.\n * return Standardized onERC1155Received return value.\n */\n function onERC1155Received(\n address,\n address,\n uint256,\n uint256,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC1155Receiver.onERC1155Received.selector;\n }\n\n /**\n * @notice Handles ERC1155 Token batch callback.\n * return Standardized onERC1155BatchReceived return value.\n */\n function onERC1155BatchReceived(\n address,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC1155Receiver.onERC1155BatchReceived.selector;\n }\n\n /**\n * @notice Handles ERC777 Token callback.\n * Does not return value, empty implementation.\n */\n function tokensReceived(\n address,\n address,\n address,\n uint256,\n bytes calldata,\n bytes calldata\n ) external pure override {}\n\n /**\n * @notice Handles ERC677 Token callback.\n * return true.\n */\n function onTokenTransfer(\n address,\n uint256,\n bytes calldata\n ) external pure override returns (bool) {\n return true;\n }\n}\n" + }, + "contracts/facets/verification/MultiSigFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {UserOperation} from \"../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../../libraries/LibLoupe.sol\";\nimport {LibAppStorage} from \"../../libraries/LibAppStorage.sol\";\nimport {LibMultiSigStorage, MultiSigStorage} from \"../../libraries/LibMultiSigStorage.sol\";\nimport {IERC1271} from \"../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../interfaces/IVerificationFacet.sol\";\nimport {IMultiSigFacet} from \"../interfaces/IMultiSigFacet.sol\";\n\n/**\n * @title Multi-sig facet\n * @dev Multi-signature Facet with custom threshold.\n * Wallet that adds this facet becomes a multi-sig wallet.\n * Reference signature_format.md documentation for Multi-sig facet details\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract MultiSigFacet is IMultiSigFacet, IVerificationFacet, IERC1271 {\n using ECDSA for bytes32;\n\n address public immutable self;\n\n address internal constant SENTINEL_OWNERS = address(0x1);\n uint256 internal constant ADDRESS = 20;\n uint256 internal constant SIG_TYPE = 1;\n uint256 internal constant SIG_LEN = 4;\n uint256 internal constant THRESHOLD = 4;\n uint256 internal constant INVALID_SIG = 1;\n uint256 internal constant VALID_SIG = 0;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in Multisig Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the right format and initializes signer storage in k1 storage.\n * @param _owners Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _owners\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n\n if (!isValidKeyType(_owners)) revert MultiSigFacet__InvalidInitData();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n uint256 threshold = uint256(uint32(bytes4(_owners)));\n uint256 ownerCount = (_owners.length - THRESHOLD) / ADDRESS;\n\n if (threshold == 0) revert MultiSigFacet__InvalidThreshold();\n if (ownerCount == 0) revert MultisigFacet__InvalidOwnerCount();\n\n address currentOwner = SENTINEL_OWNERS;\n uint256 ptr = THRESHOLD;\n address owner_;\n for (uint256 i; i < ownerCount; ) {\n owner_ = address(bytes20(_owners[ptr:ptr + ADDRESS]));\n ptr += ADDRESS;\n if (\n owner_ == address(0) ||\n owner_ == SENTINEL_OWNERS ||\n owner_ == address(this) ||\n owner_ == currentOwner\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[owner_] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n\n ms.owners[currentOwner] = owner_;\n currentOwner = owner_;\n\n unchecked {\n ++i;\n }\n }\n ms.owners[currentOwner] = SENTINEL_OWNERS;\n ms.ownerCount = ownerCount;\n ms.threshold = threshold;\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_owners);\n }\n\n /**\n * @notice Uninitialize signer in K1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n ++ms.counter;\n address[] memory ownerlist = getOwners();\n uint256 ownerlistLength = ownerlist.length;\n for (uint256 i; i < ownerlistLength; ) {\n ms.owners[ownerlist[i]] = address(0);\n unchecked {\n ++i;\n }\n }\n ms.owners[SENTINEL_OWNERS] = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls checkSignatures with\n * user operation hash and signature together with the threshold.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n // Data 1 is invalid, Data 0 is valid\n validationData = checkSignatures(\n userOpHash,\n userOp.signature,\n LibMultiSigStorage.multisigStorage().threshold\n );\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n return this.validateOwnerSignature.selector;\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n uint totalLength = ms.ownerCount * ADDRESS;\n bytes memory result = new bytes(totalLength);\n\n // populate return array\n uint256 index;\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n while (currentOwner != SENTINEL_OWNERS) {\n assembly {\n mstore(\n add(result, add(32, mul(index, ADDRESS))),\n shl(96, currentOwner)\n )\n }\n currentOwner = ms.owners[currentOwner];\n index++;\n }\n\n return result;\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key should comply with the format in the signature_format.md doc\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n uint256 publicKeyLength = _publicKey.length;\n if (\n publicKeyLength < ADDRESS + THRESHOLD ||\n (publicKeyLength - THRESHOLD) % ADDRESS != 0\n ) return false;\n\n uint256 threshold = uint256(uint32(bytes4(_publicKey)));\n uint256 ownerCount = (publicKeyLength - THRESHOLD) / ADDRESS;\n\n isValid = !(ownerCount < threshold || threshold == 0);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes calldata _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (checkSignatures(\n _hash,\n _signature,\n LibMultiSigStorage.multisigStorage().threshold\n ) == VALID_SIG)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n\n /**\n * @notice Validates the format of the signature and verifies if the signature is signed by the expected key.\n * Reference signature_format.md doc for details about signature format and signature types\n * @param _dataHash Bytes value of data hash signed by the owners\n * @param _signatures Bytes value of signature which should comply with signature format\n * @param _threshold Uint256 value of current Multi-sig Barz's threshold\n */\n function checkSignatures(\n bytes32 _dataHash,\n bytes calldata _signatures,\n uint256 _threshold\n ) public view returns (uint256) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n address lastOwner = address(0);\n address currentOwner;\n bytes memory signature;\n uint256 signatureType;\n uint256 nextOffset;\n uint256 i;\n for (i; i < _threshold; ) {\n (\n currentOwner,\n signature,\n signatureType,\n nextOffset\n ) = splitSignatures(_signatures, nextOffset);\n if (nextOffset == 0 && i + 1 < _threshold) return INVALID_SIG;\n if (signatureType == 1) {\n // If signatureType is 1 then it is default dataHash signed.\n // This also includes the contract signature\n if (\n !SignatureChecker.isValidSignatureNow(\n currentOwner,\n _dataHash,\n signature\n )\n ) return INVALID_SIG;\n } else if (signatureType == 2) {\n // If signatureType is 2 then it is an approved hash\n if (ms.approvedHashes[ms.counter][currentOwner][_dataHash] == 0)\n return INVALID_SIG;\n } else if (signatureType == 3) {\n // If signatureType is 3 then it is a signed message hash\n // This also includes the contract signature\n bytes32 msgHash = _dataHash.toEthSignedMessageHash();\n if (\n !SignatureChecker.isValidSignatureNow(\n currentOwner,\n msgHash,\n signature\n )\n ) return INVALID_SIG;\n } else revert MultiSigFacet__InvalidRoute();\n if (\n currentOwner <= lastOwner ||\n ms.owners[currentOwner] == address(0) ||\n currentOwner == SENTINEL_OWNERS\n ) return INVALID_SIG;\n lastOwner = currentOwner;\n\n unchecked {\n ++i;\n }\n }\n return VALID_SIG;\n }\n\n /**\n * @notice Split signatures into each individual signatures. Should comply with signature format to be split\n * @param _signatures Bytes value of signature\n * @param _nextOffset Uint256 value of next offset to start splitting the signature\n */\n function splitSignatures(\n bytes calldata _signatures,\n uint256 _nextOffset\n )\n public\n pure\n returns (\n address owner_,\n bytes memory signature,\n uint256 signatureType,\n uint256 nextOffset\n )\n {\n uint256 signaturesLength = _signatures.length;\n\n if (signaturesLength <= _nextOffset + ADDRESS + SIG_LEN)\n revert MultiSigFacet__InsufficientSignerLength();\n\n owner_ = address(\n bytes20(_signatures[_nextOffset:_nextOffset + ADDRESS])\n );\n\n signatureType = uint256(\n uint8(\n bytes1(\n _signatures[_nextOffset + ADDRESS:_nextOffset +\n ADDRESS +\n SIG_TYPE]\n )\n )\n );\n\n if (signatureType > 3 || signatureType == 0)\n revert MultiSigFacet__InvalidSignatureType();\n uint256 offSet = _nextOffset + ADDRESS + SIG_TYPE;\n uint256 siglen = uint256(\n uint32(bytes4(_signatures[offSet:offSet + SIG_LEN]))\n );\n if (offSet + siglen > signaturesLength)\n revert MultiSigFacet__InvalidSignatureLength();\n\n offSet += SIG_LEN;\n if (offSet + siglen == signaturesLength) nextOffset = 0;\n else nextOffset = offSet + siglen;\n\n signature = _signatures[offSet:offSet + siglen];\n }\n\n /**\n * @notice Approves the hash of userOperation on-chain. This can only be called by owners.\n * @param _hashToApprove Bytes value of UserOperation hash to approve\n */\n function approveHash(bytes32 _hashToApprove) external {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (ms.owners[msg.sender] == address(0))\n revert MultiSigFacet__OnlyOwner();\n\n ms.approvedHashes[ms.counter][msg.sender][_hashToApprove] = 1;\n emit HashApproved(_hashToApprove, msg.sender);\n }\n\n /**\n * @notice Add owner to Barz. Update thresold if threshold is given different from current threshold\n * @dev This can only be done via a Self call.\n * @param _newOwner Address of new owner to be added\n * @param _threshold Uint256 value of threshold\n */\n function addOwner(address _newOwner, uint256 _threshold) external {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (\n _newOwner == address(0) ||\n _newOwner == SENTINEL_OWNERS ||\n _newOwner == address(this)\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_newOwner] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n\n ms.owners[_newOwner] = ms.owners[SENTINEL_OWNERS];\n ms.owners[SENTINEL_OWNERS] = _newOwner;\n ++ms.ownerCount;\n emit OwnerAdded(_newOwner);\n\n if (ms.threshold != _threshold) changeThreshold(_threshold);\n }\n\n /**\n * @notice Remove owner from Barz. Update thresold if threshold is given different from current threshold\n * @dev This can only be done via a Self call.\n * @param _prevOwner Address of owner located right behind the removed owner address in the linked list\n * @param _removedOwner Address of owner to be removed\n * @param _threshold Uint256 value of threshold\n */\n function removeOwner(\n address _prevOwner,\n address _removedOwner,\n uint256 _threshold\n ) external {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (ms.ownerCount - 1 < _threshold)\n revert MultiSigFacet__InvalidThreshold();\n if (_removedOwner == address(0) || _removedOwner == SENTINEL_OWNERS)\n revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_prevOwner] != _removedOwner)\n revert MultiSigFacet__InvalidOwnerPair();\n\n ms.owners[_prevOwner] = ms.owners[_removedOwner];\n ms.owners[_removedOwner] = address(0);\n --ms.ownerCount;\n emit OwnerRemoved(_removedOwner);\n\n if (ms.threshold != _threshold) changeThreshold(_threshold);\n }\n\n /**\n * @notice Swap owner in Barz.\n * @dev This can only be done via a Self call.\n * @param _prevOwner Address of owner located right behind the removed owner address in the linked list\n * @param _oldOwner Address of owner to be removed\n * @param _newOwner Address of owner to be added\n */\n function swapOwner(\n address _prevOwner,\n address _oldOwner,\n address _newOwner\n ) public {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (\n _newOwner == address(0) ||\n _newOwner == SENTINEL_OWNERS ||\n _newOwner == address(this)\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_newOwner] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n if (_oldOwner == address(0) || _oldOwner == SENTINEL_OWNERS)\n revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_prevOwner] != _oldOwner)\n revert MultiSigFacet__InvalidOwnerPair();\n\n ms.owners[_newOwner] = ms.owners[_oldOwner];\n ms.owners[_prevOwner] = _newOwner;\n ms.owners[_oldOwner] = address(0);\n emit OwnerRemoved(_oldOwner);\n emit OwnerAdded(_newOwner);\n }\n\n /**\n * @notice Changes the threshold of the Barz to `_threshold`.\n * @dev This can only be done via a Self call.\n * @param _threshold New threshold\n */\n function changeThreshold(uint256 _threshold) public {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (_threshold > ms.ownerCount || _threshold == 0)\n revert MultiSigFacet__InvalidThreshold();\n\n ms.threshold = _threshold;\n emit ThresholdChanged(_threshold);\n }\n\n /**\n * @notice Checks if the given address is owner\n * @param _owner Address to be checked if it's owner\n * @return isOwner_ Bool value showing if it's owner address\n */\n function isOwner(address _owner) public view returns (bool isOwner_) {\n isOwner_ = (_owner != SENTINEL_OWNERS &&\n LibMultiSigStorage.multisigStorage().owners[_owner] != address(0));\n }\n\n /**\n * @notice Returns the threshold of Barz\n * @return threshold Threshold of the Barz account\n */\n function getThreshold() public view returns (uint256 threshold) {\n threshold = LibMultiSigStorage.multisigStorage().threshold;\n }\n\n /**\n * @notice Returns the list of owner addresses\n * @return owners List of owners\n */\n function getOwners() public view returns (address[] memory owners) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n owners = new address[](ms.ownerCount);\n\n uint256 index;\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n while (currentOwner != SENTINEL_OWNERS) {\n owners[index] = currentOwner;\n currentOwner = ms.owners[currentOwner];\n index++;\n }\n }\n\n /**\n * @notice Returns the previous owner in the linked list\n * @param _owner Address of owner\n * @return prevOwner Address of previous owner\n */\n function getPrevOwner(\n address _owner\n ) public view returns (address prevOwner) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n if (currentOwner == _owner) return SENTINEL_OWNERS;\n while (currentOwner != SENTINEL_OWNERS) {\n if (ms.owners[currentOwner] == _owner) return currentOwner;\n\n currentOwner = ms.owners[currentOwner];\n }\n return address(0);\n }\n\n /**\n * @notice Returns of the owner is approved by given owner address\n * @param _owner Address of owner\n * @param _hash Hash of UserOperation\n * @return isApproved Bool value showing if the hash is approved by owner\n */\n function isApprovedHash(\n address _owner,\n bytes32 _hash\n ) public view returns (bool isApproved) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n isApproved = (ms.approvedHashes[ms.counter][_owner][_hash] == 1);\n }\n}\n" + }, + "contracts/facets/verification/secp256k1/Secp256k1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {UserOperation} from \"../../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibAppStorage} from \"../../../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, Secp256k1VerificationStorage} from \"../../../libraries/LibFacetStorage.sol\";\nimport {LibLoupe} from \"../../../libraries/LibLoupe.sol\";\nimport {IERC1271} from \"../../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../../interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Secp256k1 verification facet\n * @dev Default Ethereum's elliptic curve\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract Secp256k1VerificationFacet is IVerificationFacet, IERC1271 {\n using ECDSA for bytes32;\n error Secp256k1VerificationFacet__InvalidSignerLength();\n address public immutable self;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in K1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\n * @param _publicKey Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _publicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n if (!isValidKeyType(_publicKey))\n revert Secp256k1VerificationFacet__InvalidSignerLength();\n\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(uint160(uint256(keccak256(_publicKey[1:]))));\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_publicKey);\n }\n\n /**\n * @notice Uninitialize signer in K1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\n * signer public key.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n validationData = validateSignature(\n userOp,\n userOpHash,\n k1Storage.signer\n );\n }\n\n /**\n * @notice Validates if the signature of UserOperation is signed by the given signer\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @param signer Address of signer who signed the contract, to be validated\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n address signer\n ) public pure returns (uint256 isValid) {\n bytes32 hash = userOpHash.toEthSignedMessageHash();\n isValid = (signer != hash.recover(userOp.signature)) ? 1 : 0;\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n ownerSignatureValidatorSelector = this.validateOwnerSignature.selector;\n // NOTE: The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory signer) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n signer = abi.encodePacked(k1Storage.signer);\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key length should be 65 in an uncompressed public key format\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (_hash.recover(_signature) ==\n LibFacetStorage.k1Storage().signer)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/Secp256r1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {UserOperation} from \"../../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibAppStorage} from \"../../../libraries/LibAppStorage.sol\";\nimport {LibLoupe} from \"../../../libraries/LibLoupe.sol\";\nimport {LibFacetStorage, Secp256r1VerificationStorage} from \"../../../libraries/LibFacetStorage.sol\";\nimport {Base64} from \"./utils/Base64.sol\";\nimport {LibSecp256r1} from \"./utils/LibSecp256r1.sol\";\nimport {IERC1271} from \"../../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../../interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Secp256r1 verification facet\n * @dev Primarily used to verify user ops signed with passkeys\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract Secp256r1VerificationFacet is IVerificationFacet, IERC1271 {\n error Secp256r1VerificationFacet__InvalidSignerLength();\n address public immutable self;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in R1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\n * @param _publicKey Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _publicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n\n if (!isValidKeyType(_publicKey))\n revert Secp256r1VerificationFacet__InvalidSignerLength();\n\n bytes memory publicKeyCoordinates = _publicKey[1:];\n uint256[2] memory q;\n assembly {\n // Copy the bytes from the input data into the uint256 array\n mstore(q, mload(add(publicKeyCoordinates, 32)))\n mstore(add(q, 32), mload(add(publicKeyCoordinates, 64)))\n }\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n r1Storage.q = q;\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_publicKey);\n }\n\n /**\n * @notice Uninitialize signer in R1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n r1Storage.q = [0, 0];\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\n * signer public key.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n validationData = validateSignature(userOp, userOpHash, r1Storage.q);\n }\n\n /**\n * @notice Validates if the signature of UserOperation is signed by the given signer\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @param q Public Key of signer who signed the contract, to be validated\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256[2] memory q\n ) public view returns (uint256 isValid) {\n isValid = (_validateSignature(q, userOpHash, userOp.signature)) ? 0 : 1;\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n return this.validateOwnerSignature.selector; // validateOwnerSignature(UserOperation calldata userOp,bytes32 userOpHash)\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory signer) {\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n signer = abi.encodePacked(r1Storage.q);\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key should in an uncompressed public key format\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = _validateSignature(\n LibFacetStorage.r1Storage().q,\n _hash,\n _signature\n )\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n\n function _validateSignature(\n uint256[2] memory q,\n bytes32 _hash,\n bytes memory _signature\n ) internal view returns (bool) {\n (\n uint256 rValue,\n uint256 sValue,\n bytes memory authenticatorData,\n string memory clientDataJSONPre,\n string memory clientDataJSONPost\n ) = abi.decode(_signature, (uint256, uint256, bytes, string, string));\n bytes32 clientHash;\n {\n string memory opHashBase64 = Base64.encode(bytes.concat(_hash));\n string memory clientDataJSON = string.concat(\n clientDataJSONPre,\n opHashBase64,\n clientDataJSONPost\n );\n clientHash = sha256(bytes(clientDataJSON));\n }\n bytes32 sigHash = sha256(bytes.concat(authenticatorData, clientHash));\n return LibSecp256r1.Verify(q, rValue, sValue, uint256(sigHash));\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/utils/Base64.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @dev Provides a set of functions to operate with Base64 strings.\n * modified for base64url https://datatracker.ietf.org/doc/html/rfc4648#section-5\n * _Available since v4.5._\n */\nlibrary Base64 {\n /**\n * @dev Base64 Encoding/Decoding Table\n */\n string internal constant _TABLE =\n \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_\";\n\n /**\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\n */\n function encode(bytes memory data) internal pure returns (string memory) {\n /**\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\n */\n if (data.length == 0) return \"\";\n\n // Loads the table into memory\n string memory table = _TABLE;\n\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\n // and split into 4 numbers of 6 bits.\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\n // - `data.length + 2` -> Round up\n // - `/ 3` -> Number of 3-bytes chunks\n // - `4 *` -> 4 characters for each chunk\n uint256 newlength = (data.length * 8) / 6;\n if (data.length % 6 > 0) {\n newlength++;\n }\n string memory result = new string(newlength);\n\n /// @solidity memory-safe-assembly\n assembly {\n // Prepare the lookup table (skip the first \"length\" byte)\n let tablePtr := add(table, 1)\n\n // Prepare result pointer, jump over length\n let resultPtr := add(result, 32)\n\n // Run over the input, 3 bytes at a time\n for {\n let dataPtr := data\n let endPtr := add(data, mload(data))\n } lt(dataPtr, endPtr) {\n\n } {\n // Advance 3 bytes\n dataPtr := add(dataPtr, 3)\n let input := mload(dataPtr)\n\n // To write each character, shift the 3 bytes (18 bits) chunk\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\n // and apply logical AND with 0x3F which is the number of\n // the previous character in the ASCII table prior to the Base64 Table\n // The result is then added to the table to get the character to write,\n // and finally write it in the result pointer but with a left shift\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(18, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(12, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(6, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n }\n }\n\n return result;\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/utils/LibSecp256r1.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n// Heavily inspired from\n// https://github.com/maxrobot/elliptic-solidity/blob/master/contracts/Secp256r1.sol\n// https://github.com/tdrerup/elliptic-curve-solidity/blob/master/contracts/curves/EllipticCurve.sol\n// modified to use precompile 0x05 modexp\n// and modified jacobian double\n// optimisations to avoid to an from from affine and jacobian coordinates\n\n// Additional Elliptic curve Public key / Signature validation added by\n// David Yonjun Kim (@Powerstream3604)\n\nstruct JPoint {\n uint256 x;\n uint256 y;\n uint256 z;\n}\n\nlibrary LibSecp256r1 {\n uint256 constant gx =\n 0x6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296;\n uint256 constant gy =\n 0x4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5;\n uint256 public constant pp =\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF;\n\n uint256 public constant nn =\n 0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551;\n uint256 constant a =\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC;\n uint256 constant b =\n 0x5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B;\n uint256 constant MOST_SIGNIFICANT =\n 0xc000000000000000000000000000000000000000000000000000000000000000;\n\n /*\n * Verify\n * @description - verifies that a public key has signed a given message\n * @param Q - public key coordinates X & Y\n * @param R - signature half R\n * @param S - signature half S\n * @param input - hashed message\n */\n function Verify(\n uint256[2] memory q,\n uint r,\n uint s,\n uint e\n ) internal view returns (bool) {\n if (q[0] > pp - 1 || q[1] > pp - 1) {\n return false;\n }\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\n return false;\n }\n if (\n mulmod(q[1], q[1], pp) !=\n addmod(\n addmod(\n mulmod(q[0], mulmod(q[0], q[0], pp), pp),\n mulmod(a, q[0], pp),\n pp\n ),\n b,\n pp\n )\n ) {\n return false;\n }\n\n JPoint[16] memory points = _preComputeJacobianPoints(q);\n return VerifyWithPrecompute(points, r, s, e);\n }\n\n function VerifyWithPrecompute(\n JPoint[16] memory points,\n uint r,\n uint s,\n uint e\n ) internal view returns (bool) {\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\n return false;\n }\n\n uint w = _primemod(s, nn);\n\n uint u1 = mulmod(e, w, nn);\n uint u2 = mulmod(r, w, nn);\n\n uint x;\n uint y;\n\n (x, y) = ShamirMultJacobian(points, u1, u2);\n return (x == r);\n }\n\n /*\n * Strauss Shamir trick for EC multiplication\n * https://stackoverflow.com/questions/50993471/ec-scalar-multiplication-with-strauss-shamir-method\n * we optimise on this a bit to do with 2 bits at a time rather than a single bit\n * the individual points for a single pass are precomputed\n * overall this reduces the number of additions while keeping the same number of doublings\n */\n function ShamirMultJacobian(\n JPoint[16] memory points,\n uint u1,\n uint u2\n ) internal view returns (uint, uint) {\n uint x = 0;\n uint y = 0;\n uint z = 0;\n uint bits = 128;\n uint index = 0;\n\n while (bits > 0) {\n if (z > 0) {\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\n }\n index =\n ((u1 & MOST_SIGNIFICANT) >> 252) |\n ((u2 & MOST_SIGNIFICANT) >> 254);\n if (index > 0) {\n (x, y, z) = _jAdd(\n x,\n y,\n z,\n points[index].x,\n points[index].y,\n points[index].z\n );\n }\n u1 <<= 2;\n u2 <<= 2;\n bits--;\n }\n (x, y) = _affineFromJacobian(x, y, z);\n return (x, y);\n }\n\n function _preComputeJacobianPoints(\n uint256[2] memory q\n ) internal pure returns (JPoint[16] memory points) {\n points[0] = JPoint(0, 0, 0);\n points[1] = JPoint(q[0], q[1], 1); // u2\n points[2] = _jPointDouble(points[1]);\n points[3] = _jPointAdd(points[1], points[2]);\n\n points[4] = JPoint(gx, gy, 1); // u1Points[1]\n points[5] = _jPointAdd(points[4], points[1]);\n points[6] = _jPointAdd(points[4], points[2]);\n points[7] = _jPointAdd(points[4], points[3]);\n\n points[8] = _jPointDouble(points[4]); // u1Points[2]\n points[9] = _jPointAdd(points[8], points[1]);\n points[10] = _jPointAdd(points[8], points[2]);\n points[11] = _jPointAdd(points[8], points[3]);\n\n points[12] = _jPointAdd(points[4], points[8]); // u1Points[3]\n points[13] = _jPointAdd(points[12], points[1]);\n points[14] = _jPointAdd(points[12], points[2]);\n points[15] = _jPointAdd(points[12], points[3]);\n }\n\n function _jPointAdd(\n JPoint memory p1,\n JPoint memory p2\n ) internal pure returns (JPoint memory) {\n uint x;\n uint y;\n uint z;\n (x, y, z) = _jAdd(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z);\n return JPoint(x, y, z);\n }\n\n function _jPointDouble(\n JPoint memory p\n ) internal pure returns (JPoint memory) {\n uint x;\n uint y;\n uint z;\n (x, y, z) = _modifiedJacobianDouble(p.x, p.y, p.z);\n return JPoint(x, y, z);\n }\n\n /* _affineFromJacobian\n * @desription returns affine coordinates from a jacobian input follows\n * golang elliptic/crypto library\n */\n function _affineFromJacobian(\n uint x,\n uint y,\n uint z\n ) internal view returns (uint ax, uint ay) {\n if (z == 0) {\n return (0, 0);\n }\n\n uint zinv = _primemod(z, pp);\n uint zinvsq = mulmod(zinv, zinv, pp);\n\n ax = mulmod(x, zinvsq, pp);\n ay = mulmod(y, mulmod(zinvsq, zinv, pp), pp);\n }\n\n /*\n * _jAdd\n * @description performs Jacobian addition as defined below:\n * http://www.hyperelliptic.org/EFD/g1p/data/shortw/jacobian/addition/add-2007-bl\n */\n function _jAdd(\n uint p1,\n uint p2,\n uint p3,\n uint q1,\n uint q2,\n uint q3\n ) internal pure returns (uint r1, uint r2, uint r3) {\n if (p3 == 0) {\n r1 = q1;\n r2 = q2;\n r3 = q3;\n\n return (r1, r2, r3);\n } else if (q3 == 0) {\n r1 = p1;\n r2 = p2;\n r3 = p3;\n\n return (r1, r2, r3);\n }\n\n assembly {\n let\n pd\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\n let z1z1 := mulmod(p3, p3, pd) // Z1Z1 = Z1^2\n let z2z2 := mulmod(q3, q3, pd) // Z2Z2 = Z2^2\n\n let u1 := mulmod(p1, z2z2, pd) // U1 = X1*Z2Z2\n let u2 := mulmod(q1, z1z1, pd) // U2 = X2*Z1Z1\n\n let s1 := mulmod(p2, mulmod(z2z2, q3, pd), pd) // S1 = Y1*Z2*Z2Z2\n let s2 := mulmod(q2, mulmod(z1z1, p3, pd), pd) // S2 = Y2*Z1*Z1Z1\n\n let p3q3 := addmod(p3, q3, pd)\n\n if lt(u2, u1) {\n u2 := add(pd, u2) // u2 = u2+pd\n }\n let h := sub(u2, u1) // H = U2-U1\n\n let i := mulmod(0x02, h, pd)\n i := mulmod(i, i, pd) // I = (2*H)^2\n\n let j := mulmod(h, i, pd) // J = H*I\n if lt(s2, s1) {\n s2 := add(pd, s2) // u2 = u2+pd\n }\n let rr := mulmod(0x02, sub(s2, s1), pd) // r = 2*(S2-S1)\n r1 := mulmod(rr, rr, pd) // X3 = R^2\n\n let v := mulmod(u1, i, pd) // V = U1*I\n let j2v := addmod(j, mulmod(0x02, v, pd), pd)\n if lt(r1, j2v) {\n r1 := add(pd, r1) // X3 = X3+pd\n }\n r1 := sub(r1, j2v)\n\n // Y3 = r*(V-X3)-2*S1*J\n let s12j := mulmod(mulmod(0x02, s1, pd), j, pd)\n\n if lt(v, r1) {\n v := add(pd, v)\n }\n r2 := mulmod(rr, sub(v, r1), pd)\n\n if lt(r2, s12j) {\n r2 := add(pd, r2)\n }\n r2 := sub(r2, s12j)\n\n // Z3 = ((Z1+Z2)^2-Z1Z1-Z2Z2)*H\n z1z1 := addmod(z1z1, z2z2, pd)\n j2v := mulmod(p3q3, p3q3, pd)\n if lt(j2v, z1z1) {\n j2v := add(pd, j2v)\n }\n r3 := mulmod(sub(j2v, z1z1), h, pd)\n }\n return (r1, r2, r3);\n }\n\n // Point doubling on the modified jacobian coordinates\n // http://point-at-infinity.org/ecc/Prime_Curve_Modified_Jacobian_Coordinates.html\n function _modifiedJacobianDouble(\n uint x,\n uint y,\n uint z\n ) internal pure returns (uint x3, uint y3, uint z3) {\n if (y == 0) return (0, 0, 0);\n assembly {\n let\n pd\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\n let z2 := mulmod(z, z, pd)\n let az4 := mulmod(\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC,\n mulmod(z2, z2, pd),\n pd\n )\n let y2 := mulmod(y, y, pd)\n let s := mulmod(0x04, mulmod(x, y2, pd), pd)\n let u := mulmod(0x08, mulmod(y2, y2, pd), pd)\n let m := addmod(mulmod(0x03, mulmod(x, x, pd), pd), az4, pd)\n let twos := mulmod(0x02, s, pd)\n let m2 := mulmod(m, m, pd)\n if lt(m2, twos) {\n m2 := add(pd, m2)\n }\n x3 := sub(m2, twos)\n if lt(s, x3) {\n s := add(pd, s)\n }\n y3 := mulmod(m, sub(s, x3), pd)\n if lt(y3, u) {\n y3 := add(pd, y3)\n }\n y3 := sub(y3, u)\n z3 := mulmod(0x02, mulmod(y, z, pd), pd)\n }\n }\n\n // Fermats little theorem https://en.wikipedia.org/wiki/Fermat%27s_little_theorem\n // a^(p-1) = 1 mod p\n // a^(-1) ≅ a^(p-2) (mod p)\n // we then use the precompile bigModExp to compute a^(-1)\n function _primemod(uint value, uint p) internal view returns (uint ret) {\n ret = modexp(value, p - 2, p);\n return ret;\n }\n\n // Wrapper for built-in BigNumber_modexp (contract 0x5) as described here. https://github.com/ethereum/EIPs/pull/198\n function modexp(\n uint _base,\n uint _exp,\n uint _mod\n ) internal view returns (uint ret) {\n // bigModExp(_base, _exp, _mod);\n assembly {\n if gt(_base, _mod) {\n _base := mod(_base, _mod)\n }\n // Free memory pointer is always stored at 0x40\n let freemem := mload(0x40)\n\n mstore(freemem, 0x20)\n mstore(add(freemem, 0x20), 0x20)\n mstore(add(freemem, 0x40), 0x20)\n\n mstore(add(freemem, 0x60), _base)\n mstore(add(freemem, 0x80), _exp)\n mstore(add(freemem, 0xa0), _mod)\n\n let success := staticcall(14000, 0x5, freemem, 0xc0, freemem, 0x20)\n switch success\n case 0 {\n revert(0x0, 0x0)\n }\n default {\n ret := mload(freemem)\n }\n }\n }\n}\n" + }, + "contracts/infrastructure/DefaultFallbackHandler.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC1155Receiver} from \"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\";\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {BaseAccount} from \"../aa-4337/core/BaseAccount.sol\";\nimport {DefaultLibDiamond} from \"../libraries/DefaultLibDiamond.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IAccountFacet} from \"../facets/interfaces/IAccountFacet.sol\";\nimport {IStorageLoupe} from \"../facets/base/interfaces/IStorageLoupe.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IERC677Receiver} from \"../interfaces/ERC/IERC677Receiver.sol\";\nimport {IERC165} from \"../interfaces/ERC/IERC165.sol\";\n\n/**\n * @title DefaultFallbackHandler\n * @dev A default fallback handler for Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DefaultFallbackHandler is IDiamondLoupe {\n /**\n * @notice Sets the middleware diamond for Barz wallet as a fallback handler\n * @dev This contract is also a diamond that holds the default facets to reduce gas cost for wallet activation.\n * Within the constructor this conducts diamond cut to initially setup the diamond. This is a non-upgradeable contract\n * @param _diamondCutFacet Address if diamond cut facet\n * @param _accountFacet Address account facet\n * @param _tokenReceiverFacet Address of token receiver facet\n * @param _diamondLoupeFacet Address of diamond loupe facet\n */\n constructor(\n address _diamondCutFacet,\n address _accountFacet,\n address _tokenReceiverFacet,\n address _diamondLoupeFacet\n ) payable {\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](4);\n bytes4[] memory functionSelectors = new bytes4[](1);\n functionSelectors[0] = IDiamondCut.diamondCut.selector;\n\n bytes4[] memory accountFunctionSelectors = new bytes4[](5);\n accountFunctionSelectors[0] = IAccountFacet.execute.selector;\n accountFunctionSelectors[1] = IAccountFacet.executeBatch.selector;\n accountFunctionSelectors[2] = BaseAccount.validateUserOp.selector;\n accountFunctionSelectors[3] = BaseAccount.getNonce.selector;\n accountFunctionSelectors[4] = BaseAccount.entryPoint.selector;\n\n bytes4[] memory receiverFacetSelectors = new bytes4[](5);\n receiverFacetSelectors[0] = IERC721Receiver.onERC721Received.selector;\n receiverFacetSelectors[1] = IERC1155Receiver.onERC1155Received.selector;\n receiverFacetSelectors[2] = IERC1155Receiver\n .onERC1155BatchReceived\n .selector;\n receiverFacetSelectors[3] = IERC777Recipient.tokensReceived.selector;\n receiverFacetSelectors[4] = IERC677Receiver.onTokenTransfer.selector;\n\n bytes4[] memory loupeFacetSelectors = new bytes4[](9);\n loupeFacetSelectors[0] = IDiamondLoupe.facets.selector;\n loupeFacetSelectors[1] = IDiamondLoupe.facetFunctionSelectors.selector;\n loupeFacetSelectors[2] = IDiamondLoupe.facetAddresses.selector;\n loupeFacetSelectors[3] = IDiamondLoupe.facetAddress.selector;\n loupeFacetSelectors[4] = IERC165.supportsInterface.selector;\n loupeFacetSelectors[5] = IStorageLoupe.facetsFromStorage.selector;\n loupeFacetSelectors[6] = IStorageLoupe\n .facetFunctionSelectorsFromStorage\n .selector;\n loupeFacetSelectors[7] = IStorageLoupe\n .facetAddressesFromStorage\n .selector;\n loupeFacetSelectors[8] = IStorageLoupe.facetAddressFromStorage.selector;\n\n {\n cut[0] = IDiamondCut.FacetCut({\n facetAddress: _diamondCutFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: functionSelectors\n });\n cut[1] = IDiamondCut.FacetCut({\n facetAddress: _accountFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: accountFunctionSelectors\n });\n cut[2] = IDiamondCut.FacetCut({\n facetAddress: _tokenReceiverFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: receiverFacetSelectors\n });\n cut[3] = IDiamondCut.FacetCut({\n facetAddress: _diamondLoupeFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: loupeFacetSelectors\n });\n\n DefaultLibDiamond.diamondCut(cut, address(0), \"\");\n }\n }\n\n /**\n * @notice Returns the facet information of call facets registered to this diamond.\n * @return facets_ The facet struct array including all facet information\n */\n function facets() external view override returns (Facet[] memory facets_) {\n DefaultLibDiamond.DiamondStorage storage ds = DefaultLibDiamond\n .diamondStorage();\n uint256 numFacets = ds.facetAddresses.length;\n facets_ = new Facet[](numFacets);\n for (uint256 i; i < numFacets; ) {\n address facetAddress_ = ds.facetAddresses[i];\n facets_[i].facetAddress = facetAddress_;\n facets_[i].functionSelectors = ds\n .facetFunctionSelectors[facetAddress_]\n .functionSelectors;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Gets all the function selectors provided by a facet.\n * @param _facet The facet address.\n * @return facetFunctionSelectors_\n */\n function facetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n facetFunctionSelectors_ = DefaultLibDiamond\n .diamondStorage()\n .facetFunctionSelectors[_facet]\n .functionSelectors;\n }\n\n /**\n * @notice Get all the facet addresses used by a diamond.\n * @return facetAddresses_\n */\n function facetAddresses()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n facetAddresses_ = DefaultLibDiamond.diamondStorage().facetAddresses;\n }\n\n /** @notice Gets the facet that supports the given selector.\n * @dev If facet is not found return address(0).\n * @param _functionSelector The function selector.\n * @return facetAddress_ The facet address.\n */\n function facetAddress(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n facetAddress_ = DefaultLibDiamond\n .diamondStorage()\n .selectorToFacetAndPosition[_functionSelector]\n .facetAddress;\n }\n}\n" + }, + "contracts/infrastructure/FacetRegistry.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport {IFacetRegistry} from \"./interfaces/IFacetRegistry.sol\";\n\n/**\n * @title Facet Registry\n * @dev Contract to keep track of facets & function selectors addable to user wallets\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract FacetRegistry is IFacetRegistry, Ownable2Step {\n mapping(address => FacetRegistryConfig) private facets;\n\n /**\n * @notice Transfers the ownership of the contract to the given owner\n * @param _owner Address of owner who has access to initialize the default security variables for security manager\n */\n constructor(address _owner) {\n transferOwnership(_owner);\n _transferOwnership(_owner);\n }\n\n /**\n * @dev Registers a facet and it's function selectors to registry\n * @param _facet address of facet\n * @param _facetSelectors list of function selectors of the facet\n */\n function registerFacetFunctionSelectors(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external override onlyOwner {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n for (uint256 i; i < _facetSelectors.length; ) {\n if (facetConfig.info[_facetSelectors[i]].exists)\n revert FacetRegistry__FacetSelectorAlreadyRegistered();\n\n facetConfig.info[_facetSelectors[i]].exists = true;\n facetConfig.info[_facetSelectors[i]].index = uint128(\n facetConfig.selectors.length\n );\n facetConfig.selectors.push(_facetSelectors[i]);\n unchecked {\n ++i;\n }\n }\n emit FacetFunctionSelectorsRegistered(_facet, _facetSelectors);\n }\n\n /**\n * @dev Removes a registered facet and it's corresponding selectors from registry\n * @param _facet address of facet\n * @param _facetSelectors list of function selectors of the facet\n */\n function removeFacetFunctionSelectors(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external override onlyOwner {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n for (uint256 i; i < _facetSelectors.length; ) {\n if (!facetConfig.info[_facetSelectors[i]].exists)\n revert FacetRegistry__UnregisteredFacetSelector();\n\n bytes4 lastSelector = facetConfig.selectors[\n facetConfig.selectors.length - 1\n ];\n if (_facetSelectors[i] != lastSelector) {\n uint128 targetIndex = facetConfig\n .info[_facetSelectors[i]]\n .index;\n facetConfig.selectors[targetIndex] = lastSelector;\n facetConfig.info[lastSelector].index = targetIndex;\n }\n facetConfig.selectors.pop();\n delete facetConfig.info[_facetSelectors[i]];\n\n unchecked {\n ++i;\n }\n }\n emit FacetFunctionSelectorsRemoved(_facet, _facetSelectors);\n }\n\n /**\n * @dev Checks if a facet and it's selectors given is registered to facet registry\n * @param _facet Address of facet\n * @param _facetSelectors List of function selectors of the facet\n */\n function areFacetFunctionSelectorsRegistered(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external view override returns (bool) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n if (_facetSelectors.length == 0) return false;\n for (uint256 i; i < _facetSelectors.length; ) {\n if (!facetConfig.info[_facetSelectors[i]].exists) return false;\n unchecked {\n ++i;\n }\n }\n return true;\n }\n\n /**\n * @dev Checks if a facet and it's selector given is registered to facet registry\n * @param _facet Address of facet\n * @param _facetSelector List of function selectors of the facet\n * @return isRegistered Bool value showing if the selector is registered\n */\n function isFacetFunctionSelectorRegistered(\n address _facet,\n bytes4 _facetSelector\n ) external view override returns (bool isRegistered) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n isRegistered = facetConfig.info[_facetSelector].exists;\n }\n\n /**\n * @dev Get the registered selectors of facet from registry\n * @param _facet Address of facet\n * @return selectors Selectors registered to facet\n */\n function getFacetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory selectors) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n selectors = facetConfig.selectors;\n }\n}\n" + }, + "contracts/infrastructure/interfaces/IFacetRegistry.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Registry Interface\n * @dev Interface for Facet Registry contract to keep track of facets & function selectors addable to user wallets\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IFacetRegistry {\n struct FacetRegistryConfig {\n bytes4[] selectors;\n mapping(bytes4 => FacetInfo) info;\n }\n struct FacetInfo {\n bool exists;\n uint128 index;\n }\n\n event FacetFunctionSelectorsRegistered(\n address facet,\n bytes4[] facetSelectors\n );\n event FacetFunctionSelectorsRemoved(address facet, bytes4[] facetSelectors);\n\n error FacetRegistry__FacetSelectorAlreadyRegistered();\n error FacetRegistry__UnregisteredFacetSelector();\n\n function registerFacetFunctionSelectors(\n address facet,\n bytes4[] calldata facetSelectors\n ) external;\n\n function removeFacetFunctionSelectors(\n address facet,\n bytes4[] calldata facetSelectors\n ) external;\n\n function areFacetFunctionSelectorsRegistered(\n address facet,\n bytes4[] calldata facetSelectors\n ) external view returns (bool);\n\n function isFacetFunctionSelectorRegistered(\n address facet,\n bytes4 facetSelector\n ) external view returns (bool);\n\n function getFacetFunctionSelectors(\n address facet\n ) external view returns (bytes4[] memory);\n}\n" + }, + "contracts/infrastructure/interfaces/ISecurityManager.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Registry Interface\n * @dev Infrastructure contract to manage security parameters of users\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface ISecurityManager {\n error SecurityManager__OutOfBoundary();\n error SecurityManager__CallerNotWallet();\n error SecurityManager__AlreadyIntialized();\n\n function initializeAdditionSecurityPeriod(\n uint128 defaultAdditionSecurityPeriod,\n uint128 minAdditionSecurityPeriod,\n uint128 maxAdditionSecurityPeriod\n ) external;\n\n function initializeRemovalSecurityPeriod(\n uint128 defaultRemovalSecurityPeriod,\n uint128 minRemovalSecurityPeriod,\n uint128 maxRemovalSecurityPeriod\n ) external;\n\n function initializeApprovalValidationPeriod(\n uint128 defaultApprovalValidationPeriod,\n uint128 minApprovalValidationPeriod,\n uint128 maxApprovalValidationPeriod\n ) external;\n\n function initializeMigrationPeriod(\n uint128 defaultMigrationPeriod,\n uint128 minMigrationPeriod,\n uint128 maxMigrationPeriod\n ) external;\n\n function initializeLockPeriod(\n uint128 defaultLockPeriod,\n uint128 minLockPeriod,\n uint128 maxLockPeriod\n ) external;\n\n function initializeRecoveryPeriod(\n uint128 defaultRecoveryPeriod,\n uint128 minRecoveryPeriod,\n uint128 maxRecoveryPeriod\n ) external;\n\n function initializeSecurityWindow(\n uint128 defaultSecurityWindow,\n uint128 minSecurityWindow,\n uint128 maxSecurityWindow\n ) external;\n\n function setAdditionSecurityPeriod(\n address wallet,\n uint128 additionSecurityPeriod\n ) external;\n\n function setRemovalSecurityPeriod(\n address wallet,\n uint128 removalSecurityPeriod\n ) external;\n\n function setSecurityWindow(address wallet, uint128 securityWindow) external;\n\n function setRecoveryPeriod(address wallet, uint128 recoveryPeriod) external;\n\n function setLockPeriod(address wallet, uint128 lockPeriod) external;\n\n function setApprovalValidationPeriod(\n address wallet,\n uint128 approvalValidationPeriod\n ) external;\n\n function setMigrationPeriod(\n address wallet,\n uint128 migrationPeriod\n ) external;\n\n function additionSecurityPeriodOf(\n address wallet\n ) external view returns (uint128);\n\n function removalSecurityPeriodOf(\n address wallet\n ) external view returns (uint128);\n\n function securityWindowOf(address wallet) external view returns (uint128);\n\n function recoveryPeriodOf(address wallet) external view returns (uint128);\n\n function lockPeriodOf(address wallet) external view returns (uint128);\n\n function migrationPeriodOf(address wallet) external view returns (uint128);\n\n function approvalValidationPeriodOf(\n address wallet\n ) external view returns (uint128);\n}\n" + }, + "contracts/infrastructure/RemoteStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IGuardianFacet} from \"../facets/interfaces/IGuardianFacet.sol\";\n\n/**\n * @title Remote Storage\n * @dev Remote storage allows you to associate addresses with an array of addresses on a standalone smart contract.\n * This could be useful when you don't want to use the local diamond storage for some purpose.\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\nabstract contract RemoteStorage {\n struct StorageConfig {\n address[] addresses;\n mapping(address => Info) info;\n }\n\n struct Info {\n bool exists;\n uint128 index;\n }\n\n mapping(address => StorageConfig) internal configs;\n\n event Added(address _address);\n event Removed(address _address);\n\n error RemoteStorage__CallerNotOwner();\n error RemoteStorage__CallerNotGuardianOrOwner();\n error RemoteStorage__AlreadyExists();\n error RemoteStorage__NotFound();\n error RemoteStorage__CallerNotGuardian();\n\n bytes4 constant IS_GUARDIAN_SELECTOR =\n bytes4(keccak256(\"isGuardian(address)\"));\n bytes4 constant GUARDIAN_COUNT = bytes4(keccak256(\"guardianCount()\"));\n\n /**\n * @notice Modifier to only allow the self to call. Reverts otherwise\n */\n modifier onlyWallet(address _wallet) {\n if (msg.sender != _wallet) revert RemoteStorage__CallerNotOwner();\n _;\n }\n\n /**\n * @notice Enfore the callet to be wallet of guardian of the wallet\n * @param _wallet Address of wallet\n */\n function enforceGuardianOrWallet(address _wallet) internal view {\n if (msg.sender == _wallet) return;\n address facetAddress = IDiamondLoupe(_wallet).facetAddress(\n IS_GUARDIAN_SELECTOR\n );\n if (facetAddress != address(0))\n if (IGuardianFacet(_wallet).isGuardian(msg.sender)) return;\n revert RemoteStorage__CallerNotGuardianOrOwner();\n }\n\n /**\n * @notice Enforce the caller to be wallet IF guardians doesn't exists and only guardian when guardians exists\n * @param _wallet Target wallet address to be handled by infrastructure contracts\n */\n function enforceWalletOrGuardianIfExists(address _wallet) internal view {\n address facetAddress;\n if (msg.sender == _wallet) {\n facetAddress = IDiamondLoupe(_wallet).facetAddress(GUARDIAN_COUNT);\n if (facetAddress == address(0)) return;\n uint256 guardianCount = IGuardianFacet(_wallet).guardianCount();\n if (guardianCount != 0) revert RemoteStorage__CallerNotGuardian();\n return;\n }\n facetAddress = IDiamondLoupe(_wallet).facetAddress(\n IS_GUARDIAN_SELECTOR\n );\n if (facetAddress != address(0))\n if (IGuardianFacet(_wallet).isGuardian(msg.sender)) return;\n\n revert RemoteStorage__CallerNotGuardianOrOwner();\n }\n\n /**\n * @notice Add address to storage and reverts if the address already exists.\n * This is an internal function callable from contracts that inherit this abstract contract\n * @param _wallet Address of wallet to add the address\n * @param _address Address to be added to wallet\n */\n function addAddress(address _wallet, address _address) internal {\n StorageConfig storage config = configs[_wallet];\n if (config.info[_address].exists) revert RemoteStorage__AlreadyExists();\n\n config.info[_address].exists = true;\n config.info[_address].index = uint128(config.addresses.length);\n config.addresses.push(_address);\n\n emit Added(_address);\n }\n\n /**\n * @notice Remove address from storage and reverts if the address already exists.\n * This is an internal function callable from contracts that inherit this abstract contract\n * @param _wallet Address of wallet to remove the address\n * @param _address Address to be removed from wallet\n */\n function removeAddress(address _wallet, address _address) internal {\n StorageConfig storage config = configs[_wallet];\n if (!config.info[_address].exists) revert RemoteStorage__NotFound();\n\n address lastAddress = config.addresses[config.addresses.length - 1];\n if (_address != lastAddress) {\n uint128 targetIndex = config.info[_address].index;\n config.addresses[targetIndex] = lastAddress;\n config.info[lastAddress].index = targetIndex;\n }\n config.addresses.pop();\n delete config.info[_address];\n\n emit Removed(_address);\n }\n\n /**\n * @notice Returns the address added to the given wallet\n * @param _wallet Address of wallet to fetch the addresses added to it\n * @return addresses List of addresses added to the wallet\n */\n function getAddresses(\n address _wallet\n ) internal view returns (address[] memory addresses) {\n StorageConfig storage config = configs[_wallet];\n addresses = new address[](config.addresses.length);\n uint addressesLen = config.addresses.length;\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns bool value checking if the address exists in the given wallet address\n * @param _wallet Wallet address to check\n * @param _address Address to fetch if the address if added to given wallet\n * @return exists_ Bool value showing if the address exists in wallet\n */\n function exists(\n address _wallet,\n address _address\n ) internal view returns (bool exists_) {\n exists_ = configs[_wallet].info[_address].exists;\n }\n\n /**\n * @notice Returns the number of addresses added to the wallet\n * @param _wallet Address of wallet to check\n * @return count_ Number of addresses added to wallet\n */\n function count(address _wallet) internal view returns (uint256 count_) {\n count_ = configs[_wallet].addresses.length;\n }\n}\n" + }, + "contracts/infrastructure/SecurityManager.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport {ISecurityManager} from \"./interfaces/ISecurityManager.sol\";\n\n/**\n * @title Security Manager\n * @dev Infrastructure contract to manage security parameters of users\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract SecurityManager is ISecurityManager, Ownable2Step {\n uint128 public minAdditionSecurityPeriod;\n uint128 public maxAdditionSecurityPeriod;\n uint128 private defaultAdditionSecurityPeriod;\n\n uint128 public minRemovalSecurityPeriod;\n uint128 public maxRemovalSecurityPeriod;\n uint128 private defaultRemovalSecurityPeriod;\n\n uint128 public minSecurityWindow;\n uint128 public maxSecurityWindow;\n uint128 private defaultSecurityWindow;\n\n uint128 public minRecoveryPeriod;\n uint128 public maxRecoveryPeriod;\n uint128 private defaultRecoveryPeriod;\n\n uint128 public minLockPeriod;\n uint128 public maxLockPeriod;\n uint128 private defaultLockPeriod;\n\n uint128 public minApprovalValidationPeriod;\n uint128 public maxApprovalValidationPeriod;\n uint128 private defaultApprovalValidationPeriod;\n\n uint128 public minMigrationPeriod;\n uint128 public maxMigrationPeriod;\n uint128 private defaultMigrationPeriod;\n\n bool public _isAdditionSecurityPeriodInitialized;\n bool public _isRemovalSecurityPeriodInitialized;\n bool public _isSecurityWindowInitialized;\n bool public _isRecoveryPeriodInitialized;\n bool public _isLockPeriodInitialized;\n bool public _isApprovalValidationPeriodInitialized;\n bool public _isMigrationPeriodInitialized;\n\n mapping(address => CustomSecurityConfig) securityConfigs;\n\n struct CustomSecurityConfig {\n uint128 additionSecurityPeriod;\n uint128 removalSecurityPeriod;\n uint128 securityWindow;\n uint128 recoveryPeriod;\n uint128 lockPeriod;\n uint128 approvalValidationPeriod;\n uint128 migrationPeriod;\n }\n\n /**\n * @notice Modifier to only allow wallet itself to make a call to wallet\n */\n modifier onlyWallet(address _wallet) {\n if (msg.sender != _wallet) revert SecurityManager__CallerNotWallet();\n _;\n }\n\n /**\n * @notice Modifier to revert if the variable is already initialized\n */\n modifier initializer(bool _isInitialized) {\n if (_isInitialized) revert SecurityManager__AlreadyIntialized();\n _;\n }\n\n /**\n * @notice Transfers the ownership of the contract to the given owner\n * @param _owner Address of owner who has access to initialize the default security variables for security manager\n */\n constructor(address _owner) {\n transferOwnership(_owner);\n _transferOwnership(_owner);\n }\n\n /**\n * @notice Sets the initial default/min/max addition security period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultAdditionSecurityPeriod Default Addition Security Period for all Barz contracts\n * @param _minAdditionSecurityPeriod Minimum Addition Security Period for all Barz contracts\n * @param _maxAdditionSecurityPeriod Maximum Addition Security Period for all Barz contracts\n */\n function initializeAdditionSecurityPeriod(\n uint128 _defaultAdditionSecurityPeriod,\n uint128 _minAdditionSecurityPeriod,\n uint128 _maxAdditionSecurityPeriod\n )\n external\n override\n onlyOwner\n initializer(_isAdditionSecurityPeriodInitialized)\n {\n _isAdditionSecurityPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultAdditionSecurityPeriod,\n _minAdditionSecurityPeriod,\n _maxAdditionSecurityPeriod\n );\n defaultAdditionSecurityPeriod = _defaultAdditionSecurityPeriod;\n minAdditionSecurityPeriod = _minAdditionSecurityPeriod;\n maxAdditionSecurityPeriod = _maxAdditionSecurityPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max removal security period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultRemovalSecurityPeriod Default Removal Security Period for all Barz contracts\n * @param _minRemovalSecurityPeriod Minimum Removal Security Period for all Barz contracts\n * @param _maxRemovalSecurityPeriod Maximum Removal Security Period for all Barz contracts\n */\n function initializeRemovalSecurityPeriod(\n uint128 _defaultRemovalSecurityPeriod,\n uint128 _minRemovalSecurityPeriod,\n uint128 _maxRemovalSecurityPeriod\n )\n external\n override\n onlyOwner\n initializer(_isRemovalSecurityPeriodInitialized)\n {\n _isRemovalSecurityPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultRemovalSecurityPeriod,\n _minRemovalSecurityPeriod,\n _maxRemovalSecurityPeriod\n );\n defaultRemovalSecurityPeriod = _defaultRemovalSecurityPeriod;\n minRemovalSecurityPeriod = _minRemovalSecurityPeriod;\n maxRemovalSecurityPeriod = _maxRemovalSecurityPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/maxd security window for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultSecurityWindow Default Security Window for all Barz contracts\n * @param _minSecurityWindow Minimum Security Window for all Barz contracts\n * @param _maxSecurityWindow Maximum Security Window for all Barz contracts\n */\n function initializeSecurityWindow(\n uint128 _defaultSecurityWindow,\n uint128 _minSecurityWindow,\n uint128 _maxSecurityWindow\n ) external override onlyOwner initializer(_isSecurityWindowInitialized) {\n _isSecurityWindowInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultSecurityWindow,\n _minSecurityWindow,\n _maxSecurityWindow\n );\n defaultSecurityWindow = _defaultSecurityWindow;\n minSecurityWindow = _minSecurityWindow;\n maxSecurityWindow = _maxSecurityWindow;\n }\n\n /**\n * @notice Sets the initial default/min/max recovery period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultRecoveryPeriod Default Recovery Period for all Barz contracts\n * @param _minRecoveryPeriod Minimum Recovery Period for all Barz contracts\n * @param _maxRecoveryPeriod Maximum Recovery Period for all Barz contracts\n */\n function initializeRecoveryPeriod(\n uint128 _defaultRecoveryPeriod,\n uint128 _minRecoveryPeriod,\n uint128 _maxRecoveryPeriod\n ) external override onlyOwner initializer(_isRecoveryPeriodInitialized) {\n _isRecoveryPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultRecoveryPeriod,\n _minRecoveryPeriod,\n _maxRecoveryPeriod\n );\n defaultRecoveryPeriod = _defaultRecoveryPeriod;\n minRecoveryPeriod = _minRecoveryPeriod;\n maxRecoveryPeriod = _maxRecoveryPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max lock period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultLockPeriod Default Lock Period for all Barz contracts\n * @param _minLockPeriod Minimum Lock Period for all Barz contracts\n * @param _maxLockPeriod Maximum Lock Period for all Barz contracts\n */\n function initializeLockPeriod(\n uint128 _defaultLockPeriod,\n uint128 _minLockPeriod,\n uint128 _maxLockPeriod\n ) external override onlyOwner initializer(_isLockPeriodInitialized) {\n _isLockPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultLockPeriod,\n _minLockPeriod,\n _maxLockPeriod\n );\n defaultLockPeriod = _defaultLockPeriod;\n minLockPeriod = _minLockPeriod;\n maxLockPeriod = _maxLockPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max approval validation period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultApprovalValidationPeriod Default Approval Validation Period for all Barz contracts\n * @param _minApprovalValidationPeriod Minimum Approval Validation Period for all Barz contracts\n * @param _maxApprovalValidationPeriod Maximum Approval Validation Period for all Barz contracts\n */\n function initializeApprovalValidationPeriod(\n uint128 _defaultApprovalValidationPeriod,\n uint128 _minApprovalValidationPeriod,\n uint128 _maxApprovalValidationPeriod\n )\n external\n override\n onlyOwner\n initializer(_isApprovalValidationPeriodInitialized)\n {\n _isApprovalValidationPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultApprovalValidationPeriod,\n _minApprovalValidationPeriod,\n _maxApprovalValidationPeriod\n );\n defaultApprovalValidationPeriod = _defaultApprovalValidationPeriod;\n minApprovalValidationPeriod = _minApprovalValidationPeriod;\n maxApprovalValidationPeriod = _maxApprovalValidationPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max migration period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultMigrationPeriod Default Migration Period for all Barz contracts\n * @param _minMigrationPeriod Minimum Migration Period for all Barz contracts\n * @param _maxMigrationPeriod Maximum Migration Period for all Barz contracts\n */\n function initializeMigrationPeriod(\n uint128 _defaultMigrationPeriod,\n uint128 _minMigrationPeriod,\n uint128 _maxMigrationPeriod\n ) external override onlyOwner initializer(_isMigrationPeriodInitialized) {\n _isMigrationPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultMigrationPeriod,\n _minMigrationPeriod,\n _maxMigrationPeriod\n );\n defaultMigrationPeriod = _defaultMigrationPeriod;\n minMigrationPeriod = _minMigrationPeriod;\n maxMigrationPeriod = _maxMigrationPeriod;\n }\n\n /**\n * @notice Wallet owner sets the addition security period for the wallet. Only the owner of wallet can call this function.\n * The addition security period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _additionSecurityPeriod Custom Addition Security Period for the wallet\n */\n function setAdditionSecurityPeriod(\n address _wallet,\n uint128 _additionSecurityPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _additionSecurityPeriod,\n minAdditionSecurityPeriod,\n maxAdditionSecurityPeriod\n );\n securityConfigs[_wallet]\n .additionSecurityPeriod = _additionSecurityPeriod;\n }\n\n /**\n * @notice Wallet owner sets the removal security period for the wallet. Only the owner of wallet can call this function.\n * The removal security period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _removalSecurityPeriod Custom Removal Security Period for the wallet\n */\n function setRemovalSecurityPeriod(\n address _wallet,\n uint128 _removalSecurityPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _removalSecurityPeriod,\n minRemovalSecurityPeriod,\n maxRemovalSecurityPeriod\n );\n securityConfigs[_wallet].removalSecurityPeriod = _removalSecurityPeriod;\n }\n\n /**\n * @notice Wallet owner sets the security window for the wallet. Only the owner of wallet can call this function.\n * The security window should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _securityWindow Custom Security Window for the wallet\n */\n function setSecurityWindow(\n address _wallet,\n uint128 _securityWindow\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _securityWindow,\n minSecurityWindow,\n maxSecurityWindow\n );\n securityConfigs[_wallet].securityWindow = _securityWindow;\n }\n\n /**\n * @notice Wallet owner sets the recovery period for the wallet. Only the owner of wallet can call this function.\n * The recovery period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _recoveryPeriod Custom recovery period for the wallet\n */\n function setRecoveryPeriod(\n address _wallet,\n uint128 _recoveryPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _recoveryPeriod,\n minRecoveryPeriod,\n maxRecoveryPeriod\n );\n securityConfigs[_wallet].recoveryPeriod = _recoveryPeriod;\n }\n\n /**\n * @notice Wallet owner sets the lock period for the wallet. Only the owner of wallet can call this function.\n * The lock period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _lockPeriod Custom Lock period for the wallet\n */\n function setLockPeriod(\n address _wallet,\n uint128 _lockPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(_lockPeriod, minLockPeriod, maxLockPeriod);\n securityConfigs[_wallet].lockPeriod = _lockPeriod;\n }\n\n /**\n * @notice Wallet owner sets the approval validation period for the wallet. Only the owner of wallet can call this function.\n * The approval validation period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _approvalValidationPeriod Custom approval validation period for the wallet\n */\n function setApprovalValidationPeriod(\n address _wallet,\n uint128 _approvalValidationPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _approvalValidationPeriod,\n minApprovalValidationPeriod,\n maxApprovalValidationPeriod\n );\n securityConfigs[_wallet]\n .approvalValidationPeriod = _approvalValidationPeriod;\n }\n\n /**\n * @notice Wallet owner sets the migration period for the wallet. Only the owner of wallet can call this function.\n * The migration period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _migrationPeriod Custom migration period for the wallet\n */\n\n function setMigrationPeriod(\n address _wallet,\n uint128 _migrationPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _migrationPeriod,\n minMigrationPeriod,\n maxMigrationPeriod\n );\n securityConfigs[_wallet].migrationPeriod = _migrationPeriod;\n }\n\n /**\n * @notice Returns the addition security period. Returns default value when custom addition security period is not set\n * @param _wallet Address of wallet\n * @return additionSecurityPeriod Addition Security Period of the given Barz account or wallet\n */\n function additionSecurityPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 additionSecurityPeriod)\n {\n additionSecurityPeriod = securityConfigs[_wallet]\n .additionSecurityPeriod;\n additionSecurityPeriod = (additionSecurityPeriod == 0)\n ? defaultAdditionSecurityPeriod\n : additionSecurityPeriod;\n }\n\n /**\n * @notice Returns the removal security period. Returns default value when custom removal security period is not set\n * @param _wallet Address of wallet\n * @return removalSecurityPeriod Removal Security Period of the given Barz account or wallet\n */\n function removalSecurityPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 removalSecurityPeriod)\n {\n removalSecurityPeriod = securityConfigs[_wallet].removalSecurityPeriod;\n removalSecurityPeriod = (removalSecurityPeriod == 0)\n ? defaultRemovalSecurityPeriod\n : removalSecurityPeriod;\n }\n\n /**\n * @notice Returns the security window. Returns default value when custom security window is not set\n * @param _wallet Address of wallet\n * @return securityWindow Security window of the given Barz account or wallet\n */\n function securityWindowOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 securityWindow)\n {\n securityWindow = securityConfigs[_wallet].securityWindow;\n securityWindow = (securityWindow == 0)\n ? defaultSecurityWindow\n : securityWindow;\n }\n\n /**\n * @notice Returns the recovery period. Returns default value when custom recovery period is not set\n * @param _wallet Address of wallet\n * @return recoveryPeriod Recovery Period of the given Barz account or wallet\n */\n function recoveryPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 recoveryPeriod)\n {\n recoveryPeriod = securityConfigs[_wallet].recoveryPeriod;\n recoveryPeriod = (recoveryPeriod == 0)\n ? defaultRecoveryPeriod\n : recoveryPeriod;\n }\n\n /**\n * @notice Returns the lock period. Returns default value when custom lock period is not set\n * @param _wallet Address of wallet\n * @return lockPeriod Lock Period of the given Barz account or wallet\n */\n function lockPeriodOf(\n address _wallet\n ) public view override onlyWallet(_wallet) returns (uint128 lockPeriod) {\n lockPeriod = securityConfigs[_wallet].lockPeriod;\n lockPeriod = (lockPeriod == 0) ? defaultLockPeriod : lockPeriod;\n }\n\n /**\n * @notice Returns the approval validation period. Returns default value when custom approval validation period is not set\n * @param _wallet Address of wallet\n * @return approvalValidationPeriod Approval Validation Period of the given Barz account or wallet\n */\n function approvalValidationPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityConfigs[_wallet]\n .approvalValidationPeriod;\n approvalValidationPeriod = (approvalValidationPeriod == 0)\n ? defaultApprovalValidationPeriod\n : approvalValidationPeriod;\n }\n\n /**\n * @notice Returns the migration period. Returns default value when custom migration period is not set\n * @param _wallet Address of wallet\n * @return migrationPeriod Migration Period of the given Barz account or wallet\n */\n function migrationPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 migrationPeriod)\n {\n migrationPeriod = securityConfigs[_wallet].migrationPeriod;\n migrationPeriod = (migrationPeriod == 0)\n ? defaultMigrationPeriod\n : migrationPeriod;\n }\n\n /**\n * @notice Validates if the period is smaller than the max period or bigger than the min period\n * @param _period Period to be checked\n * @param _minPeriod Minimum period\n * @param _maxPeriod Maximum period\n */\n function _validatePeriodBoundaries(\n uint128 _period,\n uint128 _minPeriod,\n uint128 _maxPeriod\n ) internal pure {\n if (_period >= _maxPeriod || _period <= _minPeriod)\n revert SecurityManager__OutOfBoundary();\n }\n}\n" + }, + "contracts/infrastructure/WhitelistStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {RemoteStorage} from \"./RemoteStorage.sol\";\n\n/**\n * @title Whitelist storage\n * @dev Maps addresses to the corresponsing array of whitelisted addresses for each of them.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract WhitelistStorage is RemoteStorage {\n /**\n * @dev Add the address to the whitelist storage\n * @param _wallet User wallet\n * @param _address Address to be whitelisted\n */\n function whitelistAddress(address _wallet, address _address) external {\n enforceWalletOrGuardianIfExists(_wallet);\n addAddress(_wallet, _address);\n }\n\n /**\n * @dev Removes the address from the whitelist storage\n * @param _wallet User wallet\n * @param _address Address to be removed from the whitelist\n */\n function blacklistAddress(address _wallet, address _address) external {\n enforceGuardianOrWallet(_wallet);\n removeAddress(_wallet, _address);\n }\n\n /**\n * @dev Returns whether the address exists in the whitelist storage, associated with the wallet\n * @param _wallet User wallet\n * @param _address Address to be whitelisted\n */\n function isWhitelisted(\n address _wallet,\n address _address\n ) external view returns (bool) {\n return exists(_wallet, _address);\n }\n\n /**\n * @dev Returns all whitelisted addresses associated with the wallet\n * @param _wallet User wallet\n */\n function getWhitelistedAddresses(\n address _wallet\n ) external view returns (address[] memory) {\n return getAddresses(_wallet);\n }\n}\n" + }, + "contracts/interfaces/ERC/IERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\n\npragma solidity 0.8.21;\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155Receiver {\n /**\n * @dev Handles the receipt of a single ERC1155 token type. This function is\n * called at the end of a `safeTransferFrom` after the balance has been updated.\n *\n * NOTE: To accept the transfer, this must return\n * `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n * (i.e. 0xf23a6e61, or its own function selector).\n *\n * @param operator The address which initiated the transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param id The ID of the token being transferred\n * @param value The amount of tokens being transferred\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n ) external returns (bytes4);\n\n /**\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\n * is called at the end of a `safeBatchTransferFrom` after the balances have\n * been updated.\n *\n * NOTE: To accept the transfer(s), this must return\n * `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n * (i.e. 0xbc197c81, or its own function selector).\n *\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "contracts/interfaces/ERC/IERC1271.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\ninterface IERC1271 {\n function isValidSignature(\n bytes32 hash,\n bytes memory signature\n ) external view returns (bytes4);\n}\n" + }, + "contracts/interfaces/ERC/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\ninterface IERC165 {\n /// @notice Query if a contract implements an interface\n /// @param interfaceId The interface identifier, as specified in ERC-165\n /// @dev Interface identification is specified in ERC-165. This function\n /// uses less than 30,000 gas.\n /// @return `true` if the contract implements `interfaceID` and\n /// `interfaceID` is not 0xffffffff, `false` otherwise\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/IERC173.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\n/// @title ERC-173 Contract Ownership Standard\n/// Note: the ERC-165 identifier for this interface is 0x7f5828d0\n/* is ERC165 */\ninterface IERC173 {\n /// @dev This emits when ownership of a contract changes.\n event OwnershipTransferred(\n address indexed previousOwner,\n address indexed newOwner\n );\n\n /// @notice Get the address of the owner\n /// @return owner_ The address of the owner.\n function owner() external view returns (address owner_);\n\n /// @notice Set the address of the new owner of the contract\n /// @dev Set _newOwner to address(0) to renounce any ownership.\n /// @param _newOwner The address of the new owner of the contract\n function transferOwnership(address _newOwner) external;\n}\n" + }, + "contracts/interfaces/ERC/IERC677Receiver.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\ninterface IERC677Receiver {\n function onTokenTransfer(\n address sender,\n uint value,\n bytes calldata data\n ) external pure returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155 is IERC165 {\n /**\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n */\n event TransferSingle(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256 id,\n uint256 value\n );\n\n /**\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n * transfers.\n */\n event TransferBatch(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\n\n /**\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n * `approved`.\n */\n event ApprovalForAll(\n address indexed account,\n address indexed operator,\n bool approved\n );\n\n /**\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n *\n * If an {URI} event was emitted for `id`, the standard\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n * returned by {IERC1155MetadataURI-uri}.\n */\n event URI(string value, uint256 indexed id);\n\n /**\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(\n address account,\n uint256 id\n ) external view returns (uint256);\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] calldata accounts,\n uint256[] calldata ids\n ) external view returns (uint256[] memory);\n\n /**\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n *\n * Emits an {ApprovalForAll} event.\n *\n * Requirements:\n *\n * - `operator` cannot be the caller.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n *\n * See {setApprovalForAll}.\n */\n function isApprovedForAll(\n address account,\n address operator\n ) external view returns (bool);\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes calldata data\n ) external;\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(\n address indexed owner,\n address indexed spender,\n uint256 value\n );\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` 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 amount) 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(\n address owner,\n address spender\n ) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the 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 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` 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(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(\n address spender,\n uint256 addedValue\n ) external returns (bool);\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(\n address spender,\n uint256 subtractedValue\n ) external returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(\n address indexed from,\n address indexed to,\n uint256 indexed tokenId\n );\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(\n address indexed owner,\n address indexed approved,\n uint256 indexed tokenId\n );\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(\n address indexed owner,\n address indexed operator,\n bool approved\n );\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(\n uint256 tokenId\n ) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(\n address owner,\n address operator\n ) external view returns (bool);\n}\n" + }, + "contracts/interfaces/IBarz.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Barz Interface\n * @dev Interface of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IBarz {\n error Barz__InitializationFailure();\n}\n" + }, + "contracts/interfaces/IBarzFactory.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Barz} from \"../Barz.sol\";\n\n/**\n * @title Barz Factory Interface\n * @dev Interface of contract to easily deploy Barz to a pre-computed address with a single call\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IBarzFactory {\n function createAccount(\n address verificationFacet,\n bytes calldata owner,\n uint256 salt\n ) external returns (Barz);\n\n function getAddress(\n address verificationFacet,\n bytes calldata owner,\n uint256 salt\n ) external view returns (address);\n\n function getBytecode(\n address accountFacet,\n address verificationFacet,\n address entryPoint,\n address facetRegistry,\n address defaultFallback,\n bytes memory ownerPublicKey\n ) external pure returns (bytes memory);\n\n function getCreationCode() external pure returns (bytes memory);\n}\n" + }, + "contracts/libraries/DefaultLibDiamond.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\n\nerror InitializationFunctionReverted(\n address _initializationContractAddress,\n bytes _calldata\n);\n\nlibrary DefaultLibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION =\n keccak256(\"trustwallet.barz.diamond.storage\");\n\n struct FacetAddressAndPosition {\n address facetAddress;\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\n }\n\n struct FacetFunctionSelectors {\n bytes4[] functionSelectors;\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\n }\n\n struct DiamondStorage {\n // maps function selector to the facet address and\n // the position of the selector in the facetFunctionSelectors.selectors array\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\n // maps facet addresses to function selectors\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\n // facet addresses\n address[] facetAddresses;\n // Used to query if a contract implements an interface.\n // Used to implement ERC-165.\n mapping(bytes4 => bool) supportedInterfaces;\n }\n\n function diamondStorage()\n internal\n pure\n returns (DiamondStorage storage ds)\n {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n event DiamondCut(\n IDiamondCut.FacetCut[] _diamondCut,\n address _init,\n bytes _calldata\n );\n\n // Internal function version of diamondCut\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n for (\n uint256 facetIndex;\n facetIndex < _diamondCut.length;\n facetIndex++\n ) {\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\n if (action == IDiamondCut.FacetCutAction.Add) {\n addFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\n replaceFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\n removeFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else {\n revert(\"LibDiamondCut: Incorrect FacetCutAction\");\n }\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Add facet can't be address(0)\"\n );\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n require(\n oldFacetAddress == address(0),\n \"LibDiamondCut: Can't add function that already exists\"\n );\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function replaceFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Replace facet can't be address(0)\"\n );\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n require(\n oldFacetAddress != _facetAddress,\n \"LibDiamondCut: Can't replace function with same facet\"\n );\n removeFunction(ds, oldFacetAddress, selector);\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function removeFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n // if function does not exist then do nothing and return\n require(\n _facetAddress == address(0),\n \"LibDiamondCut: Remove facet address must be address(0)\"\n );\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n removeFunction(ds, oldFacetAddress, selector);\n }\n }\n\n function addFacet(\n DiamondStorage storage ds,\n address _facetAddress\n ) internal {\n enforceHasContractCode(\n _facetAddress,\n \"LibDiamondCut: New facet has no code\"\n );\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds\n .facetAddresses\n .length;\n ds.facetAddresses.push(_facetAddress);\n }\n\n function addFunction(\n DiamondStorage storage ds,\n bytes4 _selector,\n uint96 _selectorPosition,\n address _facetAddress\n ) internal {\n ds\n .selectorToFacetAndPosition[_selector]\n .functionSelectorPosition = _selectorPosition;\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(\n _selector\n );\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\n }\n\n function removeFunction(\n DiamondStorage storage ds,\n address _facetAddress,\n bytes4 _selector\n ) internal {\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Can't remove function that doesn't exist\"\n );\n // an immutable function is a function defined directly in a diamond\n require(\n _facetAddress != address(this),\n \"LibDiamondCut: Can't remove immutable function\"\n );\n // replace selector with last selector, then delete last selector\n uint256 selectorPosition = ds\n .selectorToFacetAndPosition[_selector]\n .functionSelectorPosition;\n uint256 lastSelectorPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors\n .length - 1;\n // if not the same then replace _selector with lastSelector\n if (selectorPosition != lastSelectorPosition) {\n bytes4 lastSelector = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors[lastSelectorPosition];\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[\n selectorPosition\n ] = lastSelector;\n ds\n .selectorToFacetAndPosition[lastSelector]\n .functionSelectorPosition = uint96(selectorPosition);\n }\n // delete the last selector\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\n delete ds.selectorToFacetAndPosition[_selector];\n\n // if no more selectors for facet address then delete the facet address\n if (lastSelectorPosition == 0) {\n // replace facet address with last facet address and delete last facet address\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\n uint256 facetAddressPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .facetAddressPosition;\n if (facetAddressPosition != lastFacetAddressPosition) {\n address lastFacetAddress = ds.facetAddresses[\n lastFacetAddressPosition\n ];\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\n ds\n .facetFunctionSelectors[lastFacetAddress]\n .facetAddressPosition = facetAddressPosition;\n }\n ds.facetAddresses.pop();\n delete ds\n .facetFunctionSelectors[_facetAddress]\n .facetAddressPosition;\n }\n }\n\n function initializeDiamondCut(\n address _init,\n bytes memory _calldata\n ) internal {\n if (_init == address(0)) {\n return;\n }\n enforceHasContractCode(\n _init,\n \"LibDiamondCut: _init address has no code\"\n );\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length > 0) {\n // bubble up error\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(error)\n revert(add(32, error), returndata_size)\n }\n } else {\n revert InitializationFunctionReverted(_init, _calldata);\n }\n }\n }\n\n function enforceHasContractCode(\n address _contract,\n string memory _errorMessage\n ) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize > 0, _errorMessage);\n }\n}\n" + }, + "contracts/libraries/LibAppStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SafeCast} from \"@openzeppelin/contracts/utils/math/SafeCast.sol\";\nimport {IEntryPoint} from \"../aa-4337/interfaces/IEntryPoint.sol\";\nimport {IFacetRegistry} from \"../infrastructure/interfaces/IFacetRegistry.sol\";\n\n/*\n * @title App Storage\n * @dev App storage for Barz contract to prevent storage collision\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\n\nstruct Lock {\n uint64 release;\n bytes4 locker;\n}\n\nstruct InitializersStorage {\n // NOTE: initialized is a variable to make sure the initialization is only done once.\n uint8 signerInitialized;\n uint8 accountInitialized;\n uint8 restrictionsInitialized;\n}\n\nstruct AppStorage {\n mapping(uint256 => InitializersStorage) initStorage;\n uint8 signerMigration;\n bytes4 validateOwnerSignatureSelector;\n IEntryPoint entryPoint;\n IFacetRegistry facetRegistry;\n mapping(uint256 => Lock) locks;\n}\n\nlibrary LibAppStorage {\n error LibAppStorage__AccountAlreadyUninitialized();\n error LibAppStorage__AccountMustBeUninitialized();\n error LibAppStorage__SignerAlreadyUninitialized();\n error LibAppStorage__SignerMustBeUninitialized();\n\n function appStorage() internal pure returns (AppStorage storage ds) {\n assembly {\n ds.slot := 0\n }\n }\n\n function setSignerUninitialized() internal {\n AppStorage storage s = appStorage();\n if (1 != s.initStorage[0].signerInitialized) {\n revert LibAppStorage__SignerAlreadyUninitialized();\n }\n s.initStorage[0].signerInitialized = 0;\n }\n\n function getValidateOwnerSignatureSelector()\n internal\n view\n returns (bytes4 selector)\n {\n selector = appStorage().validateOwnerSignatureSelector;\n }\n\n function setValidateOwnerSignatureSelector(\n bytes4 _validateOwnerSignatureSelector\n ) internal {\n appStorage()\n .validateOwnerSignatureSelector = _validateOwnerSignatureSelector;\n }\n\n function enforceSignerInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].signerInitialized) {\n revert LibAppStorage__SignerMustBeUninitialized();\n }\n s.initStorage[0].signerInitialized = 1;\n }\n\n function enforceAccountInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].accountInitialized) {\n revert LibAppStorage__AccountMustBeUninitialized();\n }\n s.initStorage[0].accountInitialized = 1;\n }\n\n function initiateSignerMigration() internal {\n appStorage().signerMigration = 1;\n }\n\n function enforceSignerMigration() internal view {\n if (1 != appStorage().signerMigration) {\n revert LibAppStorage__AccountMustBeUninitialized();\n }\n }\n\n function finalizeSignerMigration() internal {\n appStorage().signerMigration = 0;\n }\n\n function setLock(uint256 _releaseAfter, bytes4 _locker) internal {\n appStorage().locks[0] = Lock(SafeCast.toUint64(_releaseAfter), _locker);\n }\n\n function enforceRestrictionsInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].restrictionsInitialized)\n revert LibAppStorage__SignerMustBeUninitialized();\n s.initStorage[0].restrictionsInitialized = 1;\n }\n\n function setRestrictionsUninitialized() internal {\n AppStorage storage s = appStorage();\n if (1 != s.initStorage[0].restrictionsInitialized)\n revert LibAppStorage__AccountAlreadyUninitialized();\n s.initStorage[0].restrictionsInitialized = 0;\n }\n}\n\ncontract BarzStorage {\n AppStorage internal s;\n modifier onlyWhenUnlocked() {\n require(\n uint64(block.timestamp) >= s.locks[0].release,\n \"Account Locked\"\n );\n _;\n }\n modifier onlyWhenLocked() {\n require(\n uint64(block.timestamp) < s.locks[0].release,\n \"Account Unlocked\"\n );\n _;\n }\n}\n" + }, + "contracts/libraries/LibDiamond.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\n\nerror InitializationFunctionReverted(\n address _initializationContractAddress,\n bytes _calldata\n);\n\nlibrary LibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION =\n keccak256(\"trustwallet.barz.diamond.storage\");\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\n bytes4(keccak256(\"verifyRestrictions(address,address,uint256,bytes)\"));\n struct DiamondStorage {\n // maps function selectors to the facets that execute the functions.\n // and maps the selectors to their position in the selectorSlots array.\n // func selector => address facet, selector position\n mapping(bytes4 => bytes32) facets;\n // array of slots of function selectors.\n // each slot holds 8 function selectors.\n mapping(uint256 => bytes32) selectorSlots;\n // The number of function selectors in selectorSlots\n uint16 selectorCount;\n // Used to query if a contract implements an interface.\n // Used to implement ERC-165.\n mapping(bytes4 => bool) supportedInterfaces;\n // Default Fallback Handler of the barz.\n IDiamondLoupe defaultFallbackHandler;\n }\n\n function diamondStorage()\n internal\n pure\n returns (DiamondStorage storage ds)\n {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n function enforceIsSelf() internal view {\n require(msg.sender == address(this), \"LibDiamond: Caller not self\");\n }\n\n event DiamondCut(\n IDiamondCut.FacetCut[] _diamondCut,\n address _init,\n bytes _calldata\n );\n\n bytes32 constant CLEAR_ADDRESS_MASK =\n bytes32(uint256(0xffffffffffffffffffffffff));\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\n\n // Internal function version of diamondCut\n // This code is almost the same as the external diamondCut,\n // except it is using 'Facet[] memory _diamondCut' instead of\n // 'Facet[] calldata _diamondCut'.\n // The code is duplicated to prevent copying calldata to memory which\n // causes an error for a two dimensional array.\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n DiamondStorage storage ds = diamondStorage();\n uint256 originalSelectorCount = ds.selectorCount;\n uint256 selectorCount = originalSelectorCount;\n bytes32 selectorSlot;\n // Check if last selector slot is not full\n // \"selectorCount & 7\" is a gas efficient modulo by eight \"selectorCount % 8\"\n if (selectorCount & 7 > 0) {\n // get last selectorSlot\n // \"selectorSlot >> 3\" is a gas efficient division by 8 \"selectorSlot / 8\"\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\n }\n // loop through diamond cut\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\n selectorCount,\n selectorSlot,\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].action,\n _diamondCut[facetIndex].functionSelectors\n );\n\n unchecked {\n facetIndex++;\n }\n }\n if (selectorCount != originalSelectorCount) {\n ds.selectorCount = uint16(selectorCount);\n }\n // If last selector slot is not full\n // \"selectorCount & 7\" is a gas efficient modulo by eight \"selectorCount % 8\"\n if (selectorCount & 7 > 0) {\n // \"selectorSlot >> 3\" is a gas efficient division by 8 \"selectorSlot / 8\"\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addReplaceRemoveFacetSelectors(\n uint256 _selectorCount,\n bytes32 _selectorSlot,\n address _newFacetAddress,\n IDiamondCut.FacetCutAction _action,\n bytes4[] memory _selectors\n ) internal returns (uint256, bytes32) {\n DiamondStorage storage ds = diamondStorage();\n require(\n _selectors.length > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n if (_action == IDiamondCut.FacetCutAction.Add) {\n enforceHasContractCode(\n _newFacetAddress,\n \"LibDiamondCut: Add facet has no code\"\n );\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n require(\n address(bytes20(oldFacet)) == address(0),\n \"LibDiamondCut: Can't add function that already exists\"\n );\n // add facet for selector\n ds.facets[selector] =\n bytes20(_newFacetAddress) |\n bytes32(_selectorCount);\n // \"_selectorCount & 7\" is a gas efficient modulo by eight \"_selectorCount % 8\"\n // \" << 5 is the same as multiplying by 32 ( * 32)\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\n // clear selector position in slot and add selector\n _selectorSlot =\n (_selectorSlot &\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\n (bytes32(selector) >> selectorInSlotPosition);\n // if slot is full then write it to storage\n if (selectorInSlotPosition == 224) {\n // \"_selectorSlot >> 3\" is a gas efficient division by 8 \"_selectorSlot / 8\"\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\n _selectorSlot = 0;\n }\n _selectorCount++;\n\n unchecked {\n selectorIndex++;\n }\n }\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\n enforceHasContractCode(\n _newFacetAddress,\n \"LibDiamondCut: Replace facet has no code\"\n );\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n address oldFacetAddress = address(bytes20(oldFacet));\n // only useful if immutable functions exist\n require(\n oldFacetAddress != address(this),\n \"LibDiamondCut: Can't replace immutable function\"\n );\n require(\n oldFacetAddress != _newFacetAddress,\n \"LibDiamondCut: Can't replace function with same function\"\n );\n require(\n oldFacetAddress != address(0),\n \"LibDiamondCut: Can't replace function that doesn't exist\"\n );\n // replace old facet address\n ds.facets[selector] =\n (oldFacet & CLEAR_ADDRESS_MASK) |\n bytes20(_newFacetAddress);\n\n unchecked {\n selectorIndex++;\n }\n }\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\n require(\n _newFacetAddress == address(0),\n \"LibDiamondCut: Remove facet address must be address(0)\"\n );\n // \"_selectorCount >> 3\" is a gas efficient division by 8 \"_selectorCount / 8\"\n uint256 selectorSlotCount = _selectorCount >> 3;\n // \"_selectorCount & 7\" is a gas efficient modulo by eight \"_selectorCount % 8\"\n uint256 selectorInSlotIndex = _selectorCount & 7;\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n if (_selectorSlot == 0) {\n // get last selectorSlot\n selectorSlotCount--;\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\n selectorInSlotIndex = 7;\n } else {\n selectorInSlotIndex--;\n }\n bytes4 lastSelector;\n uint256 oldSelectorsSlotCount;\n uint256 oldSelectorInSlotPosition;\n // adding a block here prevents stack too deep error\n {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n require(\n address(bytes20(oldFacet)) != address(0),\n \"LibDiamondCut: Can't remove function that doesn't exist\"\n );\n // only useful if immutable functions exist\n require(\n address(bytes20(oldFacet)) != address(this),\n \"LibDiamondCut: Can't remove immutable function\"\n );\n // replace selector with last selector in ds.facets\n // gets the last selector\n // \" << 5 is the same as multiplying by 32 ( * 32)\n lastSelector = bytes4(\n _selectorSlot << (selectorInSlotIndex << 5)\n );\n if (lastSelector != selector) {\n // update last selector slot position info\n ds.facets[lastSelector] =\n (oldFacet & CLEAR_ADDRESS_MASK) |\n bytes20(ds.facets[lastSelector]);\n }\n delete ds.facets[selector];\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\n // \"oldSelectorCount >> 3\" is a gas efficient division by 8 \"oldSelectorCount / 8\"\n oldSelectorsSlotCount = oldSelectorCount >> 3;\n // \"oldSelectorCount & 7\" is a gas efficient modulo by eight \"oldSelectorCount % 8\"\n // \" << 5 is the same as multiplying by 32 ( * 32)\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\n }\n if (oldSelectorsSlotCount != selectorSlotCount) {\n bytes32 oldSelectorSlot = ds.selectorSlots[\n oldSelectorsSlotCount\n ];\n // clears the selector we are deleting and puts the last selector in its place.\n oldSelectorSlot =\n (oldSelectorSlot &\n ~(CLEAR_SELECTOR_MASK >>\n oldSelectorInSlotPosition)) |\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\n // update storage with the modified slot\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\n } else {\n // clears the selector we are deleting and puts the last selector in its place.\n _selectorSlot =\n (_selectorSlot &\n ~(CLEAR_SELECTOR_MASK >>\n oldSelectorInSlotPosition)) |\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\n }\n if (selectorInSlotIndex == 0) {\n delete ds.selectorSlots[selectorSlotCount];\n _selectorSlot = 0;\n }\n\n unchecked {\n selectorIndex++;\n }\n }\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\n } else {\n revert(\"LibDiamondCut: Incorrect FacetCutAction\");\n }\n return (_selectorCount, _selectorSlot);\n }\n\n function initializeDiamondCut(\n address _init,\n bytes memory _calldata\n ) internal {\n if (_init == address(0)) {\n return;\n }\n enforceHasContractCode(\n _init,\n \"LibDiamondCut: _init address has no code\"\n );\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length > 0) {\n // bubble up error\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(error)\n revert(add(32, error), returndata_size)\n }\n } else {\n revert InitializationFunctionReverted(_init, _calldata);\n }\n }\n }\n\n function enforceHasContractCode(\n address _contract,\n string memory _errorMessage\n ) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize > 0, _errorMessage);\n }\n\n function restrictionsFacet() internal view returns (address facetAddress_) {\n facetAddress_ = address(\n bytes20(\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\n )\n );\n }\n}\n" + }, + "contracts/libraries/LibFacetStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Storage\n * @dev Storage contract to store each facets variables with diamond storage\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\n\nstruct Secp256k1VerificationStorage {\n address signer;\n}\n\nstruct Secp256r1VerificationStorage {\n uint256[2] q;\n}\n\nstruct GuardianStorage {\n mapping(bytes32 => uint256) pending;\n mapping(uint8 => StorageConfig) configs;\n}\n\nstruct Info {\n bool exists;\n uint128 index;\n}\n\nstruct StorageConfig {\n address[] addresses;\n mapping(address => Info) info;\n}\n\nstruct RecoveryConfig {\n bytes recoveryPublicKey;\n uint64 executeAfter;\n}\n\nstruct ApprovalConfig {\n bool isApproved;\n uint64 validUntil;\n}\n\nstruct RecoveryApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isNewOwnerApproved;\n}\n\nstruct RecoveryStorage {\n mapping(uint8 => RecoveryConfig) recoveryConfigs;\n mapping(uint8 => RecoveryApprovalConfig) recoveryApprovalConfigs;\n uint128 nonce;\n}\n\nstruct RestrictionsStorage {\n address[] restrictions;\n mapping(address => bool) exists;\n}\n\nstruct SignatureMigrationConfig {\n bytes migrationPublicKey;\n address migrationVerificationFacet;\n bytes4[] migrationSelectors;\n uint64 migrateAfter;\n}\n\nstruct SignatureMigrationApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isMigrationApproved;\n}\n\nstruct SignatureMigrationStorage {\n mapping(uint8 => SignatureMigrationConfig) migrationConfigs;\n mapping(uint8 => SignatureMigrationApprovalConfig) migrationApprovalConfigs;\n uint128 nonce;\n}\n\nstruct DiamondCutApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isDiamondCutApproved;\n}\n\nstruct DiamondCutStorage {\n mapping(uint8 => DiamondCutApprovalConfig) diamondCutApprovalConfigs;\n uint128 nonce;\n}\n\nstruct LockStorage {\n uint128 nonce;\n}\n\nlibrary LibFacetStorage {\n bytes32 constant K1_STORAGE_POSITION =\n keccak256(\n \"v0.trustwallet.diamond.storage.Secp256k1VerificationStorage\"\n );\n bytes32 constant R1_STORAGE_POSITION =\n keccak256(\n \"v0.trustwallet.diamond.storage.Secp256r1VerificationStorage\"\n );\n bytes32 constant GUARDIAN_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.GuardianStorage\");\n bytes32 constant RECOVERY_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.RecoveryStorage\");\n bytes32 constant RESTRICTION_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.RestrictionsStorage\");\n bytes32 constant MIGRATION_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.SignatureMigrationStorage\");\n bytes32 constant DIAMONDCUT_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.DiamondCutStorage\");\n bytes32 constant LOCK_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.LockStorage\");\n\n function k1Storage()\n internal\n pure\n returns (Secp256k1VerificationStorage storage ds)\n {\n bytes32 storagePosition = K1_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function r1Storage()\n internal\n pure\n returns (Secp256r1VerificationStorage storage ds)\n {\n bytes32 storagePosition = R1_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function guardianStorage()\n internal\n pure\n returns (GuardianStorage storage ds)\n {\n bytes32 storagePosition = GUARDIAN_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function recoveryStorage()\n internal\n pure\n returns (RecoveryStorage storage ds)\n {\n bytes32 storagePosition = RECOVERY_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function restrictionsStorage()\n internal\n pure\n returns (RestrictionsStorage storage ds)\n {\n bytes32 storagePosition = RESTRICTION_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function migrationStorage()\n internal\n pure\n returns (SignatureMigrationStorage storage ds)\n {\n bytes32 storagePosition = MIGRATION_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function diamondCutStorage()\n internal\n pure\n returns (DiamondCutStorage storage ds)\n {\n bytes32 storagePosition = DIAMONDCUT_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function lockStorage() internal pure returns (LockStorage storage ds) {\n bytes32 storagePosition = LOCK_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n}\n" + }, + "contracts/libraries/LibGuardian.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibFacetStorage, StorageConfig} from \"./LibFacetStorage.sol\";\n\n/**\n * @title LibGuardian\n * @dev Internal Library to provide utility feature for Guardians stored in Guardian Facet Storage\n * @author David Yongjun Kim (@Powerstream3604)\n */\nlibrary LibGuardian {\n function majorityOfGuardians()\n internal\n view\n returns (uint256 guardianNumber)\n {\n uint256 guardianLength = guardianCount();\n guardianNumber = (guardianLength == 0) ? 0 : guardianLength / 2 + 1;\n }\n\n function isGuardian(address _guardian) internal view returns (bool) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n return config.info[_guardian].exists;\n }\n\n function guardianCount() internal view returns (uint256) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n return config.addresses.length;\n }\n\n function getGuardians() internal view returns (address[] memory) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n address[] memory addresses = new address[](config.addresses.length);\n uint256 addressesLen = config.addresses.length;\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n return addresses;\n }\n}\n" + }, + "contracts/libraries/LibLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {LibDiamond} from \"./LibDiamond.sol\";\n\n/**\n * @title LibLoupe\n * @dev Internal Library to provide utility feature for reading the state of diamond facets\n * @author David Yongjun Kim (@Powerstream3604)\n */\nlibrary LibLoupe {\n /// @notice Gets all facets and their selectors.\n /// @return facets_ Facet\n function facets()\n internal\n view\n returns (IDiamondLoupe.Facet[] memory facets_)\n {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facets_ = new IDiamondLoupe.Facet[](ds.selectorCount);\n uint16[] memory numFacetSelectors = new uint16[](ds.selectorCount);\n uint256 numFacets;\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facetAddress_ = address(bytes20(ds.facets[selector]));\n bool continueLoop;\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n if (facets_[facetIndex].facetAddress == facetAddress_) {\n facets_[facetIndex].functionSelectors[\n numFacetSelectors[facetIndex]\n ] = selector;\n // probably will never have more than 256 functions from one facet contract\n require(numFacetSelectors[facetIndex] < 255);\n numFacetSelectors[facetIndex]++;\n continueLoop = true;\n break;\n }\n }\n if (continueLoop) {\n continue;\n }\n facets_[numFacets].facetAddress = facetAddress_;\n facets_[numFacets].functionSelectors = new bytes4[](\n ds.selectorCount\n );\n facets_[numFacets].functionSelectors[0] = selector;\n numFacetSelectors[numFacets] = 1;\n numFacets++;\n }\n }\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n uint256 numSelectors = numFacetSelectors[facetIndex];\n bytes4[] memory selectors = facets_[facetIndex].functionSelectors;\n // setting the number of selectors\n assembly {\n mstore(selectors, numSelectors)\n }\n }\n // setting the number of facets\n assembly {\n mstore(facets_, numFacets)\n }\n }\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n /// @return _facetFunctionSelectors The selectors associated with a facet address.\n function facetFunctionSelectors(\n address _facet\n ) internal view returns (bytes4[] memory _facetFunctionSelectors) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n uint256 numSelectors;\n _facetFunctionSelectors = new bytes4[](ds.selectorCount);\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facet = address(bytes20(ds.facets[selector]));\n if (_facet == facet) {\n _facetFunctionSelectors[numSelectors] = selector;\n numSelectors++;\n }\n }\n }\n // Set the number of selectors in the array\n assembly {\n mstore(_facetFunctionSelectors, numSelectors)\n }\n }\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses()\n internal\n view\n returns (address[] memory facetAddresses_)\n {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facetAddresses_ = new address[](ds.selectorCount);\n uint256 numFacets;\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facetAddress_ = address(bytes20(ds.facets[selector]));\n bool continueLoop;\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n if (facetAddress_ == facetAddresses_[facetIndex]) {\n continueLoop = true;\n break;\n }\n }\n if (continueLoop) {\n continue;\n }\n facetAddresses_[numFacets] = facetAddress_;\n numFacets++;\n }\n }\n // Set the number of facet addresses in the array\n assembly {\n mstore(facetAddresses_, numFacets)\n }\n }\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(\n bytes4 _functionSelector\n ) internal view returns (address facetAddress_) {\n facetAddress_ = address(\n bytes20(LibDiamond.diamondStorage().facets[_functionSelector])\n );\n }\n}\n" + }, + "contracts/libraries/LibMultiSigStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Multi-sig Storage\n * @dev Storage contract for storing Multi-sig Facet variables in diamond storage pattern\n * @author David Yongjun Kim (@Powerstream3604)\n */\n\nstruct MultiSigStorage {\n mapping(address => address) owners;\n mapping(uint256 => mapping(address => mapping(bytes32 => uint256))) approvedHashes;\n uint256 ownerCount;\n uint256 threshold;\n uint256 counter;\n}\n\nlibrary LibMultiSigStorage {\n function multisigStorage()\n internal\n pure\n returns (MultiSigStorage storage ds)\n {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.MultiSigStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n}\n" + }, + "contracts/libraries/LibRecoverSpender.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title RecoverSpender\n * @dev Library to determine the action and spender of calldata\n * @author Ruslan Serebriakov (@rsrbk)\n */\nlibrary LibRecoverSpender {\n // ERC20, ERC721 & ERC1155 transfers & approvals\n bytes4 private constant ERC20_TRANSFER =\n bytes4(keccak256(\"transfer(address,uint256)\"));\n bytes4 private constant ERC20_APPROVE =\n bytes4(keccak256(\"approve(address,uint256)\"));\n bytes4 private constant ERC20_INCREASE_ALLOWANCE =\n bytes4(keccak256(\"increaseAllowance(address,uint256)\"));\n bytes4 private constant ERC20_DECREASE_ALLOWANCE =\n bytes4(keccak256(\"decreaseAllowance(address,uint256)\"));\n bytes4 private constant ERC721_SET_APPROVAL_FOR_ALL =\n bytes4(keccak256(\"setApprovalForAll(address,bool)\"));\n bytes4 private constant ERC721_TRANSFER_FROM =\n bytes4(keccak256(\"transferFrom(address,address,uint256)\"));\n bytes4 private constant ERC721_SAFE_TRANSFER_FROM =\n bytes4(keccak256(\"safeTransferFrom(address,address,uint256)\"));\n bytes4 private constant ERC721_SAFE_TRANSFER_FROM_BYTES =\n bytes4(keccak256(\"safeTransferFrom(address,address,uint256,bytes)\"));\n bytes4 private constant ERC1155_SAFE_TRANSFER_FROM =\n bytes4(\n keccak256(\"safeTransferFrom(address,address,uint256,uint256,bytes)\")\n );\n bytes4 private constant ERC1155_SAFE_BATCH_TRANSFER_FROM =\n bytes4(\n keccak256(\n \"safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)\"\n )\n );\n\n /**\n * @notice Helper method to recover the spender from a contract call.\n * The method returns the contract unless the call is to a standard method of a ERC20/ERC721/ERC1155 token\n * in which case the spender is recovered from the data.\n * @param _to The target contract.\n * @param _data The data payload.\n */\n function _recover(\n address _to,\n bytes memory _data\n ) internal pure returns (address spender) {\n if (_data.length >= 68) {\n bytes4 methodId;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n methodId := mload(add(_data, 0x20))\n }\n if (\n methodId == ERC20_TRANSFER ||\n methodId == ERC20_APPROVE ||\n methodId == ERC20_INCREASE_ALLOWANCE ||\n methodId == ERC20_DECREASE_ALLOWANCE ||\n methodId == ERC721_SET_APPROVAL_FOR_ALL\n ) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n spender := mload(add(_data, 0x24))\n }\n return spender;\n }\n if (\n methodId == ERC721_TRANSFER_FROM ||\n methodId == ERC721_SAFE_TRANSFER_FROM ||\n methodId == ERC721_SAFE_TRANSFER_FROM_BYTES ||\n methodId == ERC1155_SAFE_TRANSFER_FROM ||\n methodId == ERC1155_SAFE_BATCH_TRANSFER_FROM\n ) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n spender := mload(add(_data, 0x44))\n }\n return spender;\n }\n }\n\n spender = _to;\n }\n}\n" + }, + "contracts/libraries/LibUtils.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\n\nlibrary LibUtils {\n // Internal utility functions\n function mergeArrays(\n bytes4[] memory _array1,\n bytes4[] memory _array2\n ) internal pure returns (bytes4[] memory) {\n uint256 length1 = _array1.length;\n uint256 length2 = _array2.length;\n bytes4[] memory mergedArray = new bytes4[](length1 + length2);\n\n for (uint256 i; i < length1; ) {\n mergedArray[i] = _array1[i];\n unchecked {\n ++i;\n }\n }\n\n for (uint256 i; i < length2; ) {\n mergedArray[length1 + i] = _array2[i];\n unchecked {\n ++i;\n }\n }\n\n return mergedArray;\n }\n\n function removeFacetElement(\n IDiamondLoupe.Facet[] memory _facets,\n uint256 _index\n ) internal pure returns (IDiamondLoupe.Facet[] memory) {\n require(_index < _facets.length, \"Invalid index\");\n require(_facets.length != 0, \"Invalid array\");\n\n // Create a new array with a length of `_facets.length - 1`\n IDiamondLoupe.Facet[] memory newArray = new IDiamondLoupe.Facet[](\n _facets.length - 1\n );\n uint256 newArrayLength = newArray.length;\n // Iterate over the original array, skipping the element at the specified `index`\n for (uint256 i; i < newArrayLength; ) {\n if (i < _index) {\n newArray[i] = _facets[i];\n } else {\n newArray[i] = _facets[i + 1];\n }\n unchecked {\n ++i;\n }\n }\n\n return newArray;\n }\n\n function removeElement(\n bytes4[] memory _array,\n uint256 _index\n ) internal pure returns (bytes4[] memory) {\n require(_index < _array.length, \"Invalid index\");\n require(_array.length != 0, \"Invalid array\");\n\n bytes4[] memory newArray = new bytes4[](_array.length - 1);\n uint256 newArrayLength = newArray.length;\n for (uint256 i; i < newArrayLength; ) {\n if (i < _index) {\n newArray[i] = _array[i];\n } else {\n newArray[i] = _array[i + 1];\n }\n unchecked {\n ++i;\n }\n }\n\n return newArray;\n }\n\n function setValue(\n bytes4[] memory _keys,\n address[] memory _values,\n bytes4 _key,\n address _value\n ) internal pure returns (bytes4[] memory, address[] memory) {\n uint256 index = findIndex(_keys, _key);\n uint256 keysLength = _keys.length;\n if (index < keysLength) {\n _values[index] = _value;\n } else {\n // Create new storage arrays\n bytes4[] memory newKeys = new bytes4[](keysLength + 1);\n address[] memory newValues = new address[](_values.length + 1);\n\n // Copy values to the new storage arrays\n for (uint256 i; i < keysLength; ) {\n newKeys[i] = _keys[i];\n newValues[i] = _values[i];\n\n unchecked {\n ++i;\n }\n }\n\n // Add the new key-value pair\n newKeys[keysLength] = _key;\n newValues[_values.length] = _value;\n\n return (newKeys, newValues);\n }\n\n // If the key already exists, return the original arrays\n return (_keys, _values);\n }\n\n function getValue(\n bytes4[] memory _keys,\n address[] memory _values,\n bytes4 _key\n ) internal pure returns (address) {\n uint256 index = findIndex(_keys, _key);\n if (index >= _keys.length) return address(0);\n\n return _values[index];\n }\n\n function findIndex(\n bytes4[] memory _keys,\n bytes4 _key\n ) internal pure returns (uint256) {\n uint256 keysLength = _keys.length;\n for (uint256 i; i < keysLength; ) {\n if (_keys[i] == _key) {\n return i;\n }\n unchecked {\n ++i;\n }\n }\n return keysLength;\n }\n}\n" + }, + "contracts/restrictions/IRestriction.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Interface for restrictions\n * @dev Restriction is a contract which decides whether to approve a certain kind of transaction, based on its internal logic.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface IRestriction {\n /**\n * @dev Based on restriction's internal logic, it should accept or reject a certain transaction.\n * @param from The address of the sender, that will be signing the transaction.\n * @param to The receiving address.\n * @param value Amount of ETH to transfer from sender to recipient.\n * @param _calldata Optional field to include arbitrary data.\n * @return bool value for whether the check is passed\n */\n function check(\n address from,\n address to,\n uint256 value,\n bytes calldata _calldata\n ) external returns (bool);\n}\n" + }, + "contracts/restrictions/WhitelistRestriction.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibRecoverSpender} from \"../libraries/LibRecoverSpender.sol\";\nimport {WhitelistStorage} from \"../infrastructure/WhitelistStorage.sol\";\nimport {IRestriction} from \"./IRestriction.sol\";\n\n/**\n * @title Whitelist Restriction\n * @dev This restriction defines a list of accepted addresses and denies any interaction with addresses outside of it.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract WhitelistRestriction is IRestriction {\n WhitelistStorage public immutable whitelistStorage;\n\n constructor(WhitelistStorage _whitelistStorage) {\n whitelistStorage = _whitelistStorage;\n }\n\n /**\n * @notice Helper method to recover the spender from a contract call.\n * The method returns the contract unless the call is to a standard method of a ERC20/ERC721/ERC1155 token\n * in which case the spender is recovered from the data.\n * @param _to The target contract.\n * @param _data The data payload.\n */\n function recoverSpender(\n address _to,\n bytes memory _data\n ) public pure returns (address spender) {\n return LibRecoverSpender._recover(_to, _data);\n }\n\n /*\n * @dev IRestriction's implementation. It will allow transaction if the sender is whitelisted, or user, or the whitelist storage.\n * @param _from The address of the sender, that will be signing the transaction.\n * @param _to The receiving address.\n * @param _calldata Optional field to include arbitrary data.\n * @return result value for whether the check is passed\n */\n function check(\n address _from,\n address _to,\n uint256 /*_value*/,\n bytes calldata _calldata\n ) external view override returns (bool result) {\n return\n whitelistStorage.isWhitelisted(\n _from,\n LibRecoverSpender._recover(_to, _calldata)\n ) ||\n _to == address(whitelistStorage) ||\n _to == msg.sender;\n }\n}\n" + }, + "contracts/test/Counter.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\ncontract TestCounter {\n int private count = 0;\n\n function incrementCounter() public {\n count += 1;\n }\n\n function decrementCounter() public {\n count -= 1;\n }\n\n function getCount() public view returns (int) {\n return count;\n }\n}\n" + }, + "contracts/test/TestERC1155.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC1155/ERC1155.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\n\ncontract TestERC1155 is ERC1155 {\n using Counters for Counters.Counter;\n\n Counters.Counter private _tokenIds;\n\n constructor() ERC1155(\"\") {}\n\n function mint(address account, uint256 amount) external {\n uint256 tokenId = _getNextTokenId();\n _mint(account, tokenId, amount, \"\");\n }\n\n function mintBatch(\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes memory data\n ) external {\n require(\n ids.length == amounts.length,\n \"TestERC1155: arrays length mismatch\"\n );\n\n _mintBatch(to, ids, amounts, data);\n }\n\n function _getNextTokenId() private returns (uint256) {\n _tokenIds.increment();\n return _tokenIds.current();\n }\n}\n" + }, + "contracts/test/TestERC777.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC777/ERC777.sol\";\n\ncontract TestERC777 is ERC777 {\n constructor(\n address[] memory _operators\n ) ERC777(\"TestERC777\", \"TERC777\", _operators) {}\n\n function mint(address account, uint256 amount) external {\n _mint(account, amount, \"\", \"\");\n }\n}\n" + }, + "contracts/test/TestInvalidSecp256k1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IVerificationFacet} from \"../facets/interfaces/IVerificationFacet.sol\";\nimport {IERC1271} from \"../interfaces/ERC/IERC1271.sol\";\nimport {AppStorage, LibAppStorage, BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {LibFacetStorage, Secp256k1VerificationStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {UserOperation} from \"../aa-4337/interfaces/UserOperation.sol\";\n\n/**\n * @title Test Secp256k1 verification facet\n * @dev Default Ethereum's elliptic curve\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract TestInvalidSecp256k1VerificationFacet is BarzStorage, IERC1271 {\n using ECDSA for bytes32;\n error Secp256k1VerificationFacet__InvalidSignerLength();\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n\n event SignerUninitialized();\n\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n }\n\n // THIS INVALID FACET DOES NOT INCLUDE initializeSigner()\n // THIS FACET IS USED TO TEST WHEN initializeSigner() DOESN'T EXIST IN FACET\n\n function uninitializeSigner() external returns (uint256 uninitSuccess) {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view returns (uint256 validationData) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n return validateSignature(userOp, userOpHash, k1Storage.signer);\n }\n\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n address signer\n ) public pure returns (uint256) {\n bytes32 hash = userOpHash.toEthSignedMessageHash();\n if (signer != hash.recover(userOp.signature)) return 1;\n return 0;\n }\n\n // This is REMOVED for testing purpose\n function validateOwnerSignatureSelector() public pure returns (bytes4) {\n // return this.validateOwnerSignature.selector;\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n function owner() public view returns (bytes memory) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n return abi.encodePacked(k1Storage.signer);\n }\n\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure returns (bool) {\n return (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (_hash.recover(_signature) ==\n LibFacetStorage.k1Storage().signer)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n}\n" + }, + "contracts/test/TestNFT.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\n\ncontract TestNFT is ERC721 {\n using Counters for Counters.Counter;\n Counters.Counter private currentTokenId;\n\n constructor() ERC721(\"TestNFT\", \"TNFT\") {}\n\n function mint(address recipient) public returns (uint256) {\n currentTokenId.increment();\n uint256 newItemId = currentTokenId.current();\n _safeMint(recipient, newItemId);\n return newItemId;\n }\n}\n" + }, + "contracts/test/TestToken.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract TestToken is ERC20 {\n constructor()\n // solhint-disable-next-line no-empty-blocks\n ERC20(\"TST\", \"TestToken\")\n {}\n\n function mint(address sender, uint256 amount) external {\n _mint(sender, amount);\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 999999 + }, + "evmVersion": "paris", + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/deployments/polygon/solcInputs/4356503edd8ae34e73cb6dd1c8e2fc8a.json b/deployments/polygon/solcInputs/4356503edd8ae34e73cb6dd1c8e2fc8a.json new file mode 100644 index 0000000..db88715 --- /dev/null +++ b/deployments/polygon/solcInputs/4356503edd8ae34e73cb6dd1c8e2fc8a.json @@ -0,0 +1,354 @@ +{ + "language": "Solidity", + "sources": { + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby disabling any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable2Step.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./Ownable.sol\";\n\n/**\n * @dev Contract module which provides access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership} and {acceptOwnership}.\n *\n * This module is used through inheritance. It will make available all functions\n * from parent (Ownable).\n */\nabstract contract Ownable2Step is Ownable {\n address private _pendingOwner;\n\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Returns the address of the pending owner.\n */\n function pendingOwner() public view virtual returns (address) {\n return _pendingOwner;\n }\n\n /**\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual override onlyOwner {\n _pendingOwner = newOwner;\n emit OwnershipTransferStarted(owner(), newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual override {\n delete _pendingOwner;\n super._transferOwnership(newOwner);\n }\n\n /**\n * @dev The new owner accepts the ownership transfer.\n */\n function acceptOwnership() public virtual {\n address sender = _msgSender();\n require(pendingOwner() == sender, \"Ownable2Step: caller is not the new owner\");\n _transferOwnership(sender);\n }\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC1271.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC1271 standard signature validation method for\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\n *\n * _Available since v4.1._\n */\ninterface IERC1271 {\n /**\n * @dev Should return whether the signature provided is valid for the provided data\n * @param hash Hash of the data to be signed\n * @param signature Signature byte array associated with _data\n */\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\n}\n" + }, + "@openzeppelin/contracts/security/ReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor() {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n _nonReentrantBefore();\n _;\n _nonReentrantAfter();\n }\n\n function _nonReentrantBefore() private {\n // On the first call to nonReentrant, _status will be _NOT_ENTERED\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n }\n\n function _nonReentrantAfter() private {\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Returns true if the reentrancy guard is currently set to \"entered\", which indicates there is a\n * `nonReentrant` function in the call stack.\n */\n function _reentrancyGuardEntered() internal view returns (bool) {\n return _status == _ENTERED;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/ERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/ERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC1155.sol\";\nimport \"./IERC1155Receiver.sol\";\nimport \"./extensions/IERC1155MetadataURI.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of the basic standard multi-token.\n * See https://eips.ethereum.org/EIPS/eip-1155\n * Originally based on code by Enjin: https://github.com/enjin/erc-1155\n *\n * _Available since v3.1._\n */\ncontract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {\n using Address for address;\n\n // Mapping from token ID to account balances\n mapping(uint256 => mapping(address => uint256)) private _balances;\n\n // Mapping from account to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json\n string private _uri;\n\n /**\n * @dev See {_setURI}.\n */\n constructor(string memory uri_) {\n _setURI(uri_);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return\n interfaceId == type(IERC1155).interfaceId ||\n interfaceId == type(IERC1155MetadataURI).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC1155MetadataURI-uri}.\n *\n * This implementation returns the same URI for *all* token types. It relies\n * on the token type ID substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * Clients calling this function must replace the `\\{id\\}` substring with the\n * actual token type ID.\n */\n function uri(uint256) public view virtual override returns (string memory) {\n return _uri;\n }\n\n /**\n * @dev See {IERC1155-balanceOf}.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {\n require(account != address(0), \"ERC1155: address zero is not a valid owner\");\n return _balances[id][account];\n }\n\n /**\n * @dev See {IERC1155-balanceOfBatch}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] memory accounts,\n uint256[] memory ids\n ) public view virtual override returns (uint256[] memory) {\n require(accounts.length == ids.length, \"ERC1155: accounts and ids length mismatch\");\n\n uint256[] memory batchBalances = new uint256[](accounts.length);\n\n for (uint256 i = 0; i < accounts.length; ++i) {\n batchBalances[i] = balanceOf(accounts[i], ids[i]);\n }\n\n return batchBalances;\n }\n\n /**\n * @dev See {IERC1155-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC1155-isApprovedForAll}.\n */\n function isApprovedForAll(address account, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[account][operator];\n }\n\n /**\n * @dev See {IERC1155-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n _safeTransferFrom(from, to, id, amount, data);\n }\n\n /**\n * @dev See {IERC1155-safeBatchTransferFrom}.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n _safeBatchTransferFrom(from, to, ids, amounts, data);\n }\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n\n emit TransferSingle(operator, from, to, id, amount);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n for (uint256 i = 0; i < ids.length; ++i) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n }\n\n emit TransferBatch(operator, from, to, ids, amounts);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\n\n _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);\n }\n\n /**\n * @dev Sets a new URI for all token types, by relying on the token type ID\n * substitution mechanism\n * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n *\n * By this mechanism, any occurrence of the `\\{id\\}` substring in either the\n * URI or any of the amounts in the JSON file at said URI will be replaced by\n * clients with the token type ID.\n *\n * For example, the `https://token-cdn-domain/\\{id\\}.json` URI would be\n * interpreted by clients as\n * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`\n * for token type ID 0x4cce0.\n *\n * See {uri}.\n *\n * Because these URIs cannot be meaningfully represented by the {URI} event,\n * this function emits no events.\n */\n function _setURI(string memory newuri) internal virtual {\n _uri = newuri;\n }\n\n /**\n * @dev Creates `amount` tokens of token type `id`, and assigns them to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _mint(address to, uint256 id, uint256 amount, bytes memory data) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _balances[id][to] += amount;\n emit TransferSingle(operator, address(0), to, id, amount);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n for (uint256 i = 0; i < ids.length; i++) {\n _balances[ids[i]][to] += amounts[i];\n }\n\n emit TransferBatch(operator, address(0), to, ids, amounts);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);\n }\n\n /**\n * @dev Destroys `amount` tokens of token type `id` from `from`\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `from` must have at least `amount` tokens of token type `id`.\n */\n function _burn(address from, uint256 id, uint256 amount) internal virtual {\n require(from != address(0), \"ERC1155: burn from the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n\n emit TransferSingle(operator, from, address(0), id, amount);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n */\n function _burnBatch(address from, uint256[] memory ids, uint256[] memory amounts) internal virtual {\n require(from != address(0), \"ERC1155: burn from the zero address\");\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n\n for (uint256 i = 0; i < ids.length; i++) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n }\n\n emit TransferBatch(operator, from, address(0), ids, amounts);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {\n require(owner != operator, \"ERC1155: setting approval status for self\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning, as well as batched variants.\n *\n * The same hook is called on both single and batched variants. For single\n * transfers, the length of the `ids` and `amounts` arrays will be 1.\n *\n * Calling conditions (for each `id` and `amount` pair):\n *\n * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * of token type `id` will be transferred to `to`.\n * - When `from` is zero, `amount` tokens of token type `id` will be minted\n * for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n * will be burned.\n * - `from` and `to` are never both zero.\n * - `ids` and `amounts` have the same, non-zero length.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any token transfer. This includes minting\n * and burning, as well as batched variants.\n *\n * The same hook is called on both single and batched variants. For single\n * transfers, the length of the `id` and `amount` arrays will be 1.\n *\n * Calling conditions (for each `id` and `amount` pair):\n *\n * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * of token type `id` will be transferred to `to`.\n * - When `from` is zero, `amount` tokens of token type `id` will be minted\n * for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n * will be burned.\n * - `from` and `to` are never both zero.\n * - `ids` and `amounts` have the same, non-zero length.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {}\n\n function _doSafeTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155Receiver.onERC1155Received.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non-ERC1155Receiver implementer\");\n }\n }\n }\n\n function _doSafeBatchTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (\n bytes4 response\n ) {\n if (response != IERC1155Receiver.onERC1155BatchReceived.selector) {\n revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n }\n } catch Error(string memory reason) {\n revert(reason);\n } catch {\n revert(\"ERC1155: transfer to non-ERC1155Receiver implementer\");\n }\n }\n }\n\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {\n uint256[] memory array = new uint256[](1);\n array[0] = element;\n\n return array;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC1155.sol\";\n\n/**\n * @dev Interface of the optional ERC1155MetadataExtension interface, as defined\n * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155MetadataURI is IERC1155 {\n /**\n * @dev Returns the URI for token type `id`.\n *\n * If the `\\{id\\}` substring is present in the URI, it must be replaced by\n * clients with the actual token type ID.\n */\n function uri(uint256 id) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155 is IERC165 {\n /**\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n */\n event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);\n\n /**\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n * transfers.\n */\n event TransferBatch(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\n\n /**\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n * `approved`.\n */\n event ApprovalForAll(address indexed account, address indexed operator, bool approved);\n\n /**\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n *\n * If an {URI} event was emitted for `id`, the standard\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n * returned by {IERC1155MetadataURI-uri}.\n */\n event URI(string value, uint256 indexed id);\n\n /**\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) external view returns (uint256);\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] calldata accounts,\n uint256[] calldata ids\n ) external view returns (uint256[] memory);\n\n /**\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n *\n * Emits an {ApprovalForAll} event.\n *\n * Requirements:\n *\n * - `operator` cannot be the caller.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n *\n * See {setApprovalForAll}.\n */\n function isApprovedForAll(address account, address operator) external view returns (bool);\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155Receiver is IERC165 {\n /**\n * @dev Handles the receipt of a single ERC1155 token type. This function is\n * called at the end of a `safeTransferFrom` after the balance has been updated.\n *\n * NOTE: To accept the transfer, this must return\n * `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n * (i.e. 0xf23a6e61, or its own function selector).\n *\n * @param operator The address which initiated the transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param id The ID of the token being transferred\n * @param value The amount of tokens being transferred\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n ) external returns (bytes4);\n\n /**\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\n * is called at the end of a `safeBatchTransferFrom` after the balances have\n * been updated.\n *\n * NOTE: To accept the transfer(s), this must return\n * `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n * (i.e. 0xbc197c81, or its own function selector).\n *\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the default value returned by this function, unless\n * it's overridden.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(address from, address to, uint256 amount) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\n // decrementing then incrementing.\n _balances[to] += amount;\n }\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n unchecked {\n // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\n _balances[account] += amount;\n }\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n // Overflow not possible: amount <= accountBalance <= totalSupply.\n _totalSupply -= amount;\n }\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\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" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` 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 amount) 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 `amount` as the allowance of `spender` over the 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 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` 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 amount) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/ERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721.sol\";\nimport \"./IERC721Receiver.sol\";\nimport \"./extensions/IERC721Metadata.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/Strings.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\n using Address for address;\n using Strings for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\n\n // Mapping from token ID to approved address\n mapping(uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return\n interfaceId == type(IERC721).interfaceId ||\n interfaceId == type(IERC721Metadata).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _ownerOf(tokenId);\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token owner or approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n _requireMinted(tokenId);\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n _safeTransfer(from, to, tokenId, data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(address from, address to, uint256 tokenId, bytes memory data) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist\n */\n function _ownerOf(uint256 tokenId) internal view virtual returns (address) {\n return _owners[tokenId];\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _ownerOf(tokenId) != address(0);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n address owner = ERC721.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(address to, uint256 tokenId, bytes memory data) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId, 1);\n\n // Check that tokenId was not minted by `_beforeTokenTransfer` hook\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n unchecked {\n // Will not overflow unless all 2**256 token ids are minted to the same owner.\n // Given that tokens are minted one by one, it is impossible in practice that\n // this ever happens. Might change if we allow batch minting.\n // The ERC fails to describe this case.\n _balances[to] += 1;\n }\n\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(address(0), to, tokenId, 1);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n * This is an internal function that does not check if the sender is authorized to operate on the token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId, 1);\n\n // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook\n owner = ERC721.ownerOf(tokenId);\n\n // Clear approvals\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // Cannot overflow, as that would require more tokens to be burned/transferred\n // out than the owner initially received through minting and transferring in.\n _balances[owner] -= 1;\n }\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(owner, address(0), tokenId, 1);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(address from, address to, uint256 tokenId) internal virtual {\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId, 1);\n\n // Check that tokenId was not transferred by `_beforeTokenTransfer` hook\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n\n // Clear approvals from the previous owner\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // `_balances[from]` cannot overflow for the same reason as described in `_burn`:\n // `from`'s balance is the number of token held, which is at least one before the current\n // transfer.\n // `_balances[to]` could overflow in the conditions described in `_mint`. That would require\n // all 2**256 token ids to be minted, which in practice is impossible.\n _balances[from] -= 1;\n _balances[to] += 1;\n }\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId, 1);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721Receiver.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`.\n * - When `from` is zero, the tokens will be minted for `to`.\n * - When `to` is zero, ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}\n\n /**\n * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`.\n * - When `from` is zero, the tokens were minted for `to`.\n * - When `to` is zero, ``from``'s tokens were burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}\n\n /**\n * @dev Unsafe write access to the balances, used by extensions that \"mint\" tokens using an {ownerOf} override.\n *\n * WARNING: Anyone calling this MUST ensure that the balances remain consistent with the ownership. The invariant\n * being that for any address `a` the value returned by `balanceOf(a)` must be equal to the number of tokens such\n * that `ownerOf(tokenId)` is `a`.\n */\n // solhint-disable-next-line func-name-mixedcase\n function __unsafe_increaseBalance(address account, uint256 amount) internal {\n _balances[account] += amount;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721Receiver {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/ERC777.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC777/ERC777.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC777.sol\";\nimport \"./IERC777Recipient.sol\";\nimport \"./IERC777Sender.sol\";\nimport \"../ERC20/IERC20.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/introspection/IERC1820Registry.sol\";\n\n/**\n * @dev Implementation of the {IERC777} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n *\n * Support for ERC20 is included in this contract, as specified by the EIP: both\n * the ERC777 and ERC20 interfaces can be safely used when interacting with it.\n * Both {IERC777-Sent} and {IERC20-Transfer} events are emitted on token\n * movements.\n *\n * Additionally, the {IERC777-granularity} value is hard-coded to `1`, meaning that there\n * are no special restrictions in the amount of tokens that created, moved, or\n * destroyed. This makes integration with ERC20 applications seamless.\n *\n * CAUTION: This file is deprecated as of v4.9 and will be removed in the next major release.\n */\ncontract ERC777 is Context, IERC777, IERC20 {\n using Address for address;\n\n IERC1820Registry internal constant _ERC1820_REGISTRY = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n mapping(address => uint256) private _balances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n bytes32 private constant _TOKENS_SENDER_INTERFACE_HASH = keccak256(\"ERC777TokensSender\");\n bytes32 private constant _TOKENS_RECIPIENT_INTERFACE_HASH = keccak256(\"ERC777TokensRecipient\");\n\n // This isn't ever read from - it's only used to respond to the defaultOperators query.\n address[] private _defaultOperatorsArray;\n\n // Immutable, but accounts may revoke them (tracked in __revokedDefaultOperators).\n mapping(address => bool) private _defaultOperators;\n\n // For each account, a mapping of its operators and revoked default operators.\n mapping(address => mapping(address => bool)) private _operators;\n mapping(address => mapping(address => bool)) private _revokedDefaultOperators;\n\n // ERC20-allowances\n mapping(address => mapping(address => uint256)) private _allowances;\n\n /**\n * @dev `defaultOperators` may be an empty array.\n */\n constructor(string memory name_, string memory symbol_, address[] memory defaultOperators_) {\n _name = name_;\n _symbol = symbol_;\n\n _defaultOperatorsArray = defaultOperators_;\n for (uint256 i = 0; i < defaultOperators_.length; i++) {\n _defaultOperators[defaultOperators_[i]] = true;\n }\n\n // register interfaces\n _ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256(\"ERC777Token\"), address(this));\n _ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256(\"ERC20Token\"), address(this));\n }\n\n /**\n * @dev See {IERC777-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC777-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {ERC20-decimals}.\n *\n * Always returns 18, as per the\n * [ERC777 EIP](https://eips.ethereum.org/EIPS/eip-777#backward-compatibility).\n */\n function decimals() public pure virtual returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC777-granularity}.\n *\n * This implementation always returns `1`.\n */\n function granularity() public view virtual override returns (uint256) {\n return 1;\n }\n\n /**\n * @dev See {IERC777-totalSupply}.\n */\n function totalSupply() public view virtual override(IERC20, IERC777) returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev Returns the amount of tokens owned by an account (`tokenHolder`).\n */\n function balanceOf(address tokenHolder) public view virtual override(IERC20, IERC777) returns (uint256) {\n return _balances[tokenHolder];\n }\n\n /**\n * @dev See {IERC777-send}.\n *\n * Also emits a {IERC20-Transfer} event for ERC20 compatibility.\n */\n function send(address recipient, uint256 amount, bytes memory data) public virtual override {\n _send(_msgSender(), recipient, amount, data, \"\", true);\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Unlike `send`, `recipient` is _not_ required to implement the {IERC777Recipient}\n * interface if it is a contract.\n *\n * Also emits a {Sent} event.\n */\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n _send(_msgSender(), recipient, amount, \"\", \"\", false);\n return true;\n }\n\n /**\n * @dev See {IERC777-burn}.\n *\n * Also emits a {IERC20-Transfer} event for ERC20 compatibility.\n */\n function burn(uint256 amount, bytes memory data) public virtual override {\n _burn(_msgSender(), amount, data, \"\");\n }\n\n /**\n * @dev See {IERC777-isOperatorFor}.\n */\n function isOperatorFor(address operator, address tokenHolder) public view virtual override returns (bool) {\n return\n operator == tokenHolder ||\n (_defaultOperators[operator] && !_revokedDefaultOperators[tokenHolder][operator]) ||\n _operators[tokenHolder][operator];\n }\n\n /**\n * @dev See {IERC777-authorizeOperator}.\n */\n function authorizeOperator(address operator) public virtual override {\n require(_msgSender() != operator, \"ERC777: authorizing self as operator\");\n\n if (_defaultOperators[operator]) {\n delete _revokedDefaultOperators[_msgSender()][operator];\n } else {\n _operators[_msgSender()][operator] = true;\n }\n\n emit AuthorizedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-revokeOperator}.\n */\n function revokeOperator(address operator) public virtual override {\n require(operator != _msgSender(), \"ERC777: revoking self as operator\");\n\n if (_defaultOperators[operator]) {\n _revokedDefaultOperators[_msgSender()][operator] = true;\n } else {\n delete _operators[_msgSender()][operator];\n }\n\n emit RevokedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-defaultOperators}.\n */\n function defaultOperators() public view virtual override returns (address[] memory) {\n return _defaultOperatorsArray;\n }\n\n /**\n * @dev See {IERC777-operatorSend}.\n *\n * Emits {Sent} and {IERC20-Transfer} events.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes memory data,\n bytes memory operatorData\n ) public virtual override {\n require(isOperatorFor(_msgSender(), sender), \"ERC777: caller is not an operator for holder\");\n _send(sender, recipient, amount, data, operatorData, true);\n }\n\n /**\n * @dev See {IERC777-operatorBurn}.\n *\n * Emits {Burned} and {IERC20-Transfer} events.\n */\n function operatorBurn(\n address account,\n uint256 amount,\n bytes memory data,\n bytes memory operatorData\n ) public virtual override {\n require(isOperatorFor(_msgSender(), account), \"ERC777: caller is not an operator for holder\");\n _burn(account, amount, data, operatorData);\n }\n\n /**\n * @dev See {IERC20-allowance}.\n *\n * Note that operator and allowance concepts are orthogonal: operators may\n * not have allowance, and accounts with allowance may not be operators\n * themselves.\n */\n function allowance(address holder, address spender) public view virtual override returns (uint256) {\n return _allowances[holder][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Note that accounts cannot have allowance issued by their operators.\n */\n function approve(address spender, uint256 value) public virtual override returns (bool) {\n address holder = _msgSender();\n _approve(holder, spender, value);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Note that operator and allowance concepts are orthogonal: operators cannot\n * call `transferFrom` (unless they have allowance), and accounts with\n * allowance cannot call `operatorSend` (unless they are operators).\n *\n * Emits {Sent}, {IERC20-Transfer} and {IERC20-Approval} events.\n */\n function transferFrom(address holder, address recipient, uint256 amount) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(holder, spender, amount);\n _send(holder, recipient, amount, \"\", \"\", false);\n return true;\n }\n\n /**\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with the caller address as the `operator` and with\n * `userData` and `operatorData`.\n *\n * See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits {Minted} and {IERC20-Transfer} events.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - if `account` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function _mint(address account, uint256 amount, bytes memory userData, bytes memory operatorData) internal virtual {\n _mint(account, amount, userData, operatorData, true);\n }\n\n /**\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * If `requireReceptionAck` is set to true, and if a send hook is\n * registered for `account`, the corresponding function will be called with\n * `operator`, `data` and `operatorData`.\n *\n * See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits {Minted} and {IERC20-Transfer} events.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - if `account` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function _mint(\n address account,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) internal virtual {\n require(account != address(0), \"ERC777: mint to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), account, amount);\n\n // Update state variables\n _totalSupply += amount;\n _balances[account] += amount;\n\n _callTokensReceived(operator, address(0), account, amount, userData, operatorData, requireReceptionAck);\n\n emit Minted(operator, account, amount, userData, operatorData);\n emit Transfer(address(0), account, amount);\n }\n\n /**\n * @dev Send tokens\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _send(\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) internal virtual {\n require(from != address(0), \"ERC777: transfer from the zero address\");\n require(to != address(0), \"ERC777: transfer to the zero address\");\n\n address operator = _msgSender();\n\n _callTokensToSend(operator, from, to, amount, userData, operatorData);\n\n _move(operator, from, to, amount, userData, operatorData);\n\n _callTokensReceived(operator, from, to, amount, userData, operatorData, requireReceptionAck);\n }\n\n /**\n * @dev Burn tokens\n * @param from address token holder address\n * @param amount uint256 amount of tokens to burn\n * @param data bytes extra information provided by the token holder\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _burn(address from, uint256 amount, bytes memory data, bytes memory operatorData) internal virtual {\n require(from != address(0), \"ERC777: burn from the zero address\");\n\n address operator = _msgSender();\n\n _callTokensToSend(operator, from, address(0), amount, data, operatorData);\n\n _beforeTokenTransfer(operator, from, address(0), amount);\n\n // Update state variables\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC777: burn amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Burned(operator, from, amount, data, operatorData);\n emit Transfer(from, address(0), amount);\n }\n\n function _move(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n ) private {\n _beforeTokenTransfer(operator, from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC777: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Sent(operator, from, to, amount, userData, operatorData);\n emit Transfer(from, to, amount);\n }\n\n /**\n * @dev See {ERC20-_approve}.\n *\n * Note that accounts cannot have allowance issued by their operators.\n */\n function _approve(address holder, address spender, uint256 value) internal virtual {\n require(holder != address(0), \"ERC777: approve from the zero address\");\n require(spender != address(0), \"ERC777: approve to the zero address\");\n\n _allowances[holder][spender] = value;\n emit Approval(holder, spender, value);\n }\n\n /**\n * @dev Call from.tokensToSend() if the interface is registered\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _callTokensToSend(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n ) private {\n address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(from, _TOKENS_SENDER_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Sender(implementer).tokensToSend(operator, from, to, amount, userData, operatorData);\n }\n }\n\n /**\n * @dev Call to.tokensReceived() if the interface is registered. Reverts if the recipient is a contract but\n * tokensReceived() was not registered for the recipient\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _callTokensReceived(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n ) private {\n address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(to, _TOKENS_RECIPIENT_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Recipient(implementer).tokensReceived(operator, from, to, amount, userData, operatorData);\n } else if (requireReceptionAck) {\n require(!to.isContract(), \"ERC777: token recipient contract has no implementer for ERC777TokensRecipient\");\n }\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {IERC20-Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC777: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes\n * calls to {send}, {transfer}, {operatorSend}, {transferFrom}, minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be to transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address operator, address from, address to, uint256 amount) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC777/IERC777.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777Token standard as defined in the EIP.\n *\n * This contract uses the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 registry standard] to let\n * token holders and recipients react to token movements by using setting implementers\n * for the associated interfaces in said registry. See {IERC1820Registry} and\n * {ERC1820Implementer}.\n */\ninterface IERC777 {\n /**\n * @dev Emitted when `amount` tokens are created by `operator` and assigned to `to`.\n *\n * Note that some additional user `data` and `operatorData` can be logged in the event.\n */\n event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);\n\n /**\n * @dev Emitted when `operator` destroys `amount` tokens from `account`.\n *\n * Note that some additional user `data` and `operatorData` can be logged in the event.\n */\n event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);\n\n /**\n * @dev Emitted when `operator` is made operator for `tokenHolder`.\n */\n event AuthorizedOperator(address indexed operator, address indexed tokenHolder);\n\n /**\n * @dev Emitted when `operator` is revoked its operator status for `tokenHolder`.\n */\n event RevokedOperator(address indexed operator, address indexed tokenHolder);\n\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, usually a shorter version of the\n * name.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the smallest part of the token that is not divisible. This\n * means all token operations (creation, movement and destruction) must have\n * amounts that are a multiple of this number.\n *\n * For most token contracts, this value will equal 1.\n */\n function granularity() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by an account (`owner`).\n */\n function balanceOf(address owner) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * If send or receive hooks are registered for the caller and `recipient`,\n * the corresponding functions will be called with `data` and empty\n * `operatorData`. See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits a {Sent} event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function send(address recipient, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Destroys `amount` tokens from the caller's account, reducing the\n * total supply.\n *\n * If a send hook is registered for the caller, the corresponding function\n * will be called with `data` and empty `operatorData`. See {IERC777Sender}.\n *\n * Emits a {Burned} event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n */\n function burn(uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Returns true if an account is an operator of `tokenHolder`.\n * Operators can send and burn tokens on behalf of their owners. All\n * accounts are their own operator.\n *\n * See {operatorSend} and {operatorBurn}.\n */\n function isOperatorFor(address operator, address tokenHolder) external view returns (bool);\n\n /**\n * @dev Make an account an operator of the caller.\n *\n * See {isOperatorFor}.\n *\n * Emits an {AuthorizedOperator} event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function authorizeOperator(address operator) external;\n\n /**\n * @dev Revoke an account's operator status for the caller.\n *\n * See {isOperatorFor} and {defaultOperators}.\n *\n * Emits a {RevokedOperator} event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function revokeOperator(address operator) external;\n\n /**\n * @dev Returns the list of default operators. These accounts are operators\n * for all token holders, even if {authorizeOperator} was never called on\n * them.\n *\n * This list is immutable, but individual holders may revoke these via\n * {revokeOperator}, in which case {isOperatorFor} will return false.\n */\n function defaultOperators() external view returns (address[] memory);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must\n * be an operator of `sender`.\n *\n * If send or receive hooks are registered for `sender` and `recipient`,\n * the corresponding functions will be called with `data` and\n * `operatorData`. See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits a {Sent} event.\n *\n * Requirements\n *\n * - `sender` cannot be the zero address.\n * - `sender` must have at least `amount` tokens.\n * - the caller must be an operator for `sender`.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes calldata data,\n bytes calldata operatorData\n ) external;\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the total supply.\n * The caller must be an operator of `account`.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with `data` and `operatorData`. See {IERC777Sender}.\n *\n * Emits a {Burned} event.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n * - the caller must be an operator for `account`.\n */\n function operatorBurn(address account, uint256 amount, bytes calldata data, bytes calldata operatorData) external;\n\n event Sent(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes data,\n bytes operatorData\n );\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\n *\n * Accounts can be notified of {IERC777} tokens being sent to them by having a\n * contract implement this interface (contract holders can be their own\n * implementer) and registering it on the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\n *\n * See {IERC1820Registry} and {ERC1820Implementer}.\n */\ninterface IERC777Recipient {\n /**\n * @dev Called by an {IERC777} token contract whenever tokens are being\n * moved or created into a registered account (`to`). The type of operation\n * is conveyed by `from` being the zero address or not.\n *\n * This call occurs _after_ the token contract's state is updated, so\n * {IERC777-balanceOf}, etc., can be used to query the post-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensReceived(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC777/IERC777Sender.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Sender.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777TokensSender standard as defined in the EIP.\n *\n * {IERC777} Token holders can be notified of operations performed on their\n * tokens by having a contract implement this interface (contract holders can be\n * their own implementer) and registering it on the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\n *\n * See {IERC1820Registry} and {ERC1820Implementer}.\n */\ninterface IERC777Sender {\n /**\n * @dev Called by an {IERC777} token contract whenever a registered holder's\n * (`from`) tokens are about to be moved or destroyed. The type of operation\n * is conveyed by `to` being the zero address or not.\n *\n * This call occurs _before_ the token contract's state is updated, so\n * {IERC777-balanceOf}, etc., can be used to query the pre-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensToSend(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n *\n * Furthermore, `isContract` will also return true if the target contract within\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n * which only has an effect at the end of a transaction.\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Counters.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary Counters {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/ECDSA.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Strings.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV // Deprecated in v4.8\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n /// @solidity memory-safe-assembly\n assembly {\n mstore(0x00, \"\\x19Ethereum Signed Message:\\n32\")\n mstore(0x1c, hash)\n message := keccak256(0x00, 0x3c)\n }\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\n /// @solidity memory-safe-assembly\n assembly {\n let ptr := mload(0x40)\n mstore(ptr, \"\\x19\\x01\")\n mstore(add(ptr, 0x02), domainSeparator)\n mstore(add(ptr, 0x22), structHash)\n data := keccak256(ptr, 0x42)\n }\n }\n\n /**\n * @dev Returns an Ethereum Signed Data with intended validator, created from a\n * `validator` and `data` according to the version 0 of EIP-191.\n *\n * See {recover}.\n */\n function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x00\", validator, data));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/SignatureChecker.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSA.sol\";\nimport \"../../interfaces/IERC1271.sol\";\n\n/**\n * @dev Signature verification helper that can be used instead of `ECDSA.recover` to seamlessly support both ECDSA\n * signatures from externally owned accounts (EOAs) as well as ERC1271 signatures from smart contract wallets like\n * Argent and Gnosis Safe.\n *\n * _Available since v4.1._\n */\nlibrary SignatureChecker {\n /**\n * @dev Checks if a signature is valid for a given signer and data hash. If the signer is a smart contract, the\n * signature is validated against that smart contract using ERC1271, otherwise it's validated using `ECDSA.recover`.\n *\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\n */\n function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature) internal view returns (bool) {\n (address recovered, ECDSA.RecoverError error) = ECDSA.tryRecover(hash, signature);\n return\n (error == ECDSA.RecoverError.NoError && recovered == signer) ||\n isValidERC1271SignatureNow(signer, hash, signature);\n }\n\n /**\n * @dev Checks if a signature is valid for a given signer and data hash. The signature is validated\n * against the signer smart contract using ERC1271.\n *\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\n */\n function isValidERC1271SignatureNow(\n address signer,\n bytes32 hash,\n bytes memory signature\n ) internal view returns (bool) {\n (bool success, bytes memory result) = signer.staticcall(\n abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, signature)\n );\n return (success &&\n result.length >= 32 &&\n abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/ERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165 is IERC165 {\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165).interfaceId;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC1820Registry.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/introspection/IERC1820Registry.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the global ERC1820 Registry, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register\n * implementers for interfaces in this registry, as well as query support.\n *\n * Implementers may be shared by multiple accounts, and can also implement more\n * than a single interface for each account. Contracts can implement interfaces\n * for themselves, but externally-owned accounts (EOA) must delegate this to a\n * contract.\n *\n * {IERC165} interfaces can also be queried via the registry.\n *\n * For an in-depth explanation and source code analysis, see the EIP text.\n */\ninterface IERC1820Registry {\n event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer);\n\n event ManagerChanged(address indexed account, address indexed newManager);\n\n /**\n * @dev Sets `newManager` as the manager for `account`. A manager of an\n * account is able to set interface implementers for it.\n *\n * By default, each account is its own manager. Passing a value of `0x0` in\n * `newManager` will reset the manager to this initial state.\n *\n * Emits a {ManagerChanged} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `account`.\n */\n function setManager(address account, address newManager) external;\n\n /**\n * @dev Returns the manager for `account`.\n *\n * See {setManager}.\n */\n function getManager(address account) external view returns (address);\n\n /**\n * @dev Sets the `implementer` contract as ``account``'s implementer for\n * `interfaceHash`.\n *\n * `account` being the zero address is an alias for the caller's address.\n * The zero address can also be used in `implementer` to remove an old one.\n *\n * See {interfaceHash} to learn how these are created.\n *\n * Emits an {InterfaceImplementerSet} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `account`.\n * - `interfaceHash` must not be an {IERC165} interface id (i.e. it must not\n * end in 28 zeroes).\n * - `implementer` must implement {IERC1820Implementer} and return true when\n * queried for support, unless `implementer` is the caller. See\n * {IERC1820Implementer-canImplementInterfaceForAddress}.\n */\n function setInterfaceImplementer(address account, bytes32 _interfaceHash, address implementer) external;\n\n /**\n * @dev Returns the implementer of `interfaceHash` for `account`. If no such\n * implementer is registered, returns the zero address.\n *\n * If `interfaceHash` is an {IERC165} interface id (i.e. it ends with 28\n * zeroes), `account` will be queried for support of it.\n *\n * `account` being the zero address is an alias for the caller's address.\n */\n function getInterfaceImplementer(address account, bytes32 _interfaceHash) external view returns (address);\n\n /**\n * @dev Returns the interface hash for an `interfaceName`, as defined in the\n * corresponding\n * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP].\n */\n function interfaceHash(string calldata interfaceName) external pure returns (bytes32);\n\n /**\n * @notice Updates the cache with whether the contract implements an ERC165 interface or not.\n * @param account Address of the contract for which to update the cache.\n * @param interfaceId ERC165 interface for which to update the cache.\n */\n function updateERC165Cache(address account, bytes4 interfaceId) external;\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not.\n * If the result is not cached a direct lookup on the contract address is performed.\n * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling\n * {updateERC165Cache} with the contract address.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool);\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not without using or updating the cache.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/math/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\n // The surrounding unchecked block does not change this fact.\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1, \"Math: mulDiv overflow\");\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n //\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n //\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n //\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1 << (log2(a) >> 1);\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = sqrt(a);\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 2, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 128;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 64;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 32;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 16;\n }\n if (value >> 8 > 0) {\n value >>= 8;\n result += 8;\n }\n if (value >> 4 > 0) {\n value >>= 4;\n result += 4;\n }\n if (value >> 2 > 0) {\n value >>= 2;\n result += 2;\n }\n if (value >> 1 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log2(value);\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 10, rounded down, of a positive value.\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 + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 256, rounded down, of a positive value.\n * Returns 0 if given 0.\n *\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n */\n function log256(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 16;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 8;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 4;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 2;\n }\n if (value >> 8 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log256(value);\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/SafeCast.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCast {\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 * _Available since v4.7._\n */\n function toUint248(uint256 value) internal pure returns (uint248) {\n require(value <= type(uint248).max, \"SafeCast: value doesn't fit in 248 bits\");\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 * _Available since v4.7._\n */\n function toUint240(uint256 value) internal pure returns (uint240) {\n require(value <= type(uint240).max, \"SafeCast: value doesn't fit in 240 bits\");\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 * _Available since v4.7._\n */\n function toUint232(uint256 value) internal pure returns (uint232) {\n require(value <= type(uint232).max, \"SafeCast: value doesn't fit in 232 bits\");\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 * _Available since v4.2._\n */\n function toUint224(uint256 value) internal pure returns (uint224) {\n require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\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 * _Available since v4.7._\n */\n function toUint216(uint256 value) internal pure returns (uint216) {\n require(value <= type(uint216).max, \"SafeCast: value doesn't fit in 216 bits\");\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 * _Available since v4.7._\n */\n function toUint208(uint256 value) internal pure returns (uint208) {\n require(value <= type(uint208).max, \"SafeCast: value doesn't fit in 208 bits\");\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 * _Available since v4.7._\n */\n function toUint200(uint256 value) internal pure returns (uint200) {\n require(value <= type(uint200).max, \"SafeCast: value doesn't fit in 200 bits\");\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 * _Available since v4.7._\n */\n function toUint192(uint256 value) internal pure returns (uint192) {\n require(value <= type(uint192).max, \"SafeCast: value doesn't fit in 192 bits\");\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 * _Available since v4.7._\n */\n function toUint184(uint256 value) internal pure returns (uint184) {\n require(value <= type(uint184).max, \"SafeCast: value doesn't fit in 184 bits\");\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 * _Available since v4.7._\n */\n function toUint176(uint256 value) internal pure returns (uint176) {\n require(value <= type(uint176).max, \"SafeCast: value doesn't fit in 176 bits\");\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 * _Available since v4.7._\n */\n function toUint168(uint256 value) internal pure returns (uint168) {\n require(value <= type(uint168).max, \"SafeCast: value doesn't fit in 168 bits\");\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 * _Available since v4.7._\n */\n function toUint160(uint256 value) internal pure returns (uint160) {\n require(value <= type(uint160).max, \"SafeCast: value doesn't fit in 160 bits\");\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 * _Available since v4.7._\n */\n function toUint152(uint256 value) internal pure returns (uint152) {\n require(value <= type(uint152).max, \"SafeCast: value doesn't fit in 152 bits\");\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 * _Available since v4.7._\n */\n function toUint144(uint256 value) internal pure returns (uint144) {\n require(value <= type(uint144).max, \"SafeCast: value doesn't fit in 144 bits\");\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 * _Available since v4.7._\n */\n function toUint136(uint256 value) internal pure returns (uint136) {\n require(value <= type(uint136).max, \"SafeCast: value doesn't fit in 136 bits\");\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 * _Available since v2.5._\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\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 * _Available since v4.7._\n */\n function toUint120(uint256 value) internal pure returns (uint120) {\n require(value <= type(uint120).max, \"SafeCast: value doesn't fit in 120 bits\");\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 * _Available since v4.7._\n */\n function toUint112(uint256 value) internal pure returns (uint112) {\n require(value <= type(uint112).max, \"SafeCast: value doesn't fit in 112 bits\");\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 * _Available since v4.7._\n */\n function toUint104(uint256 value) internal pure returns (uint104) {\n require(value <= type(uint104).max, \"SafeCast: value doesn't fit in 104 bits\");\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 * _Available since v4.2._\n */\n function toUint96(uint256 value) internal pure returns (uint96) {\n require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\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 * _Available since v4.7._\n */\n function toUint88(uint256 value) internal pure returns (uint88) {\n require(value <= type(uint88).max, \"SafeCast: value doesn't fit in 88 bits\");\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 * _Available since v4.7._\n */\n function toUint80(uint256 value) internal pure returns (uint80) {\n require(value <= type(uint80).max, \"SafeCast: value doesn't fit in 80 bits\");\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 * _Available since v4.7._\n */\n function toUint72(uint256 value) internal pure returns (uint72) {\n require(value <= type(uint72).max, \"SafeCast: value doesn't fit in 72 bits\");\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 * _Available since v2.5._\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\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 * _Available since v4.7._\n */\n function toUint56(uint256 value) internal pure returns (uint56) {\n require(value <= type(uint56).max, \"SafeCast: value doesn't fit in 56 bits\");\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 * _Available since v4.7._\n */\n function toUint48(uint256 value) internal pure returns (uint48) {\n require(value <= type(uint48).max, \"SafeCast: value doesn't fit in 48 bits\");\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 * _Available since v4.7._\n */\n function toUint40(uint256 value) internal pure returns (uint40) {\n require(value <= type(uint40).max, \"SafeCast: value doesn't fit in 40 bits\");\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 * _Available since v2.5._\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\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 * _Available since v4.7._\n */\n function toUint24(uint256 value) internal pure returns (uint24) {\n require(value <= type(uint24).max, \"SafeCast: value doesn't fit in 24 bits\");\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 * _Available since v2.5._\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\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 * _Available since v2.5._\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\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 * _Available since v3.0._\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\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 * _Available since v4.7._\n */\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\n downcasted = int248(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 248 bits\");\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 * _Available since v4.7._\n */\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\n downcasted = int240(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 240 bits\");\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 * _Available since v4.7._\n */\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\n downcasted = int232(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 232 bits\");\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 * _Available since v4.7._\n */\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\n downcasted = int224(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 224 bits\");\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 * _Available since v4.7._\n */\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\n downcasted = int216(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 216 bits\");\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 * _Available since v4.7._\n */\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\n downcasted = int208(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 208 bits\");\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 * _Available since v4.7._\n */\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\n downcasted = int200(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 200 bits\");\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 * _Available since v4.7._\n */\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\n downcasted = int192(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 192 bits\");\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 * _Available since v4.7._\n */\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\n downcasted = int184(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 184 bits\");\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 * _Available since v4.7._\n */\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\n downcasted = int176(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 176 bits\");\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 * _Available since v4.7._\n */\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\n downcasted = int168(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 168 bits\");\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 * _Available since v4.7._\n */\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\n downcasted = int160(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 160 bits\");\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 * _Available since v4.7._\n */\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\n downcasted = int152(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 152 bits\");\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 * _Available since v4.7._\n */\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\n downcasted = int144(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 144 bits\");\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 * _Available since v4.7._\n */\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\n downcasted = int136(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 136 bits\");\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 * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\n downcasted = int128(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 128 bits\");\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 * _Available since v4.7._\n */\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\n downcasted = int120(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 120 bits\");\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 * _Available since v4.7._\n */\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\n downcasted = int112(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 112 bits\");\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 * _Available since v4.7._\n */\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\n downcasted = int104(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 104 bits\");\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 * _Available since v4.7._\n */\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\n downcasted = int96(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 96 bits\");\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 * _Available since v4.7._\n */\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\n downcasted = int88(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 88 bits\");\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 * _Available since v4.7._\n */\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\n downcasted = int80(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 80 bits\");\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 * _Available since v4.7._\n */\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\n downcasted = int72(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 72 bits\");\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 * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\n downcasted = int64(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 64 bits\");\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 * _Available since v4.7._\n */\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\n downcasted = int56(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 56 bits\");\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 * _Available since v4.7._\n */\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\n downcasted = int48(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 48 bits\");\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 * _Available since v4.7._\n */\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\n downcasted = int40(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 40 bits\");\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 * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\n downcasted = int32(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 32 bits\");\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 * _Available since v4.7._\n */\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\n downcasted = int24(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 24 bits\");\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 * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\n downcasted = int16(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 16 bits\");\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 * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\n downcasted = int8(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 8 bits\");\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 * _Available since v3.0._\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 require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/SignedMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard signed math utilities missing in the Solidity language.\n */\nlibrary SignedMath {\n /**\n * @dev Returns the largest of two signed numbers.\n */\n function max(int256 a, int256 b) internal pure returns (int256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two signed numbers.\n */\n function min(int256 a, int256 b) internal pure returns (int256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two signed numbers without overflow.\n * The result is rounded towards zero.\n */\n function average(int256 a, int256 b) internal pure returns (int256) {\n // Formula from the book \"Hacker's Delight\"\n int256 x = (a & b) + ((a ^ b) >> 1);\n return x + (int256(uint256(x) >> 255) & (a ^ b));\n }\n\n /**\n * @dev Returns the absolute unsigned value of a signed value.\n */\n function abs(int256 n) internal pure returns (uint256) {\n unchecked {\n // must be unchecked in order to support `n = type(int256).min`\n return uint256(n >= 0 ? n : -n);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/Math.sol\";\nimport \"./math/SignedMath.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n unchecked {\n uint256 length = Math.log10(value) + 1;\n string memory buffer = new string(length);\n uint256 ptr;\n /// @solidity memory-safe-assembly\n assembly {\n ptr := add(buffer, add(32, length))\n }\n while (true) {\n ptr--;\n /// @solidity memory-safe-assembly\n assembly {\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n }\n value /= 10;\n if (value == 0) break;\n }\n return buffer;\n }\n }\n\n /**\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\n */\n function toString(int256 value) internal pure returns (string memory) {\n return string(abi.encodePacked(value < 0 ? \"-\" : \"\", toString(SignedMath.abs(value))));\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n unchecked {\n return toHexString(value, Math.log256(value) + 1);\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n\n /**\n * @dev Returns true if the two strings are equal.\n */\n function equal(string memory a, string memory b) internal pure returns (bool) {\n return keccak256(bytes(a)) == keccak256(bytes(b));\n }\n}\n" + }, + "contracts/aa-4337/core/BaseAccount.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-empty-blocks */\n\nimport \"../interfaces/IAccount.sol\";\nimport \"../interfaces/IEntryPoint.sol\";\nimport \"./Helpers.sol\";\n\n/**\n * Basic account implementation.\n * this contract provides the basic logic for implementing the IAccount interface - validateUserOp\n * specific account implementation should inherit it and provide the account-specific logic\n */\nabstract contract BaseAccount is IAccount {\n using UserOperationLib for UserOperation;\n\n //return value in case of signature failure, with no time-range.\n // equivalent to _packValidationData(true,0,0);\n uint256 internal constant SIG_VALIDATION_FAILED = 1;\n\n /**\n * Return the account nonce.\n * This method returns the next sequential nonce.\n * For a nonce of a specific key, use `entrypoint.getNonce(account, key)`\n */\n function getNonce() public view virtual returns (uint256) {\n return entryPoint().getNonce(address(this), 0);\n }\n\n /**\n * return the entryPoint used by this account.\n * subclass should return the current entryPoint used by this account.\n */\n function entryPoint() public view virtual returns (IEntryPoint);\n\n /**\n * Validate user's signature and nonce.\n * subclass doesn't need to override this method. Instead, it should override the specific internal validation methods.\n */\n function validateUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 missingAccountFunds\n ) external virtual override returns (uint256 validationData) {\n _requireFromEntryPoint();\n validationData = _validateSignature(userOp, userOpHash);\n _validateNonce(userOp.nonce);\n _payPrefund(missingAccountFunds);\n }\n\n /**\n * ensure the request comes from the known entrypoint.\n */\n function _requireFromEntryPoint() internal view virtual {\n require(\n msg.sender == address(entryPoint()),\n \"account: not from EntryPoint\"\n );\n }\n\n /**\n * validate the signature is valid for this message.\n * @param userOp validate the userOp.signature field\n * @param userOpHash convenient field: the hash of the request, to check the signature against\n * (also hashes the entrypoint and chain id)\n * @return validationData signature and time-range of this operation\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * If the account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function _validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) internal virtual returns (uint256 validationData);\n\n /**\n * Validate the nonce of the UserOperation.\n * This method may validate the nonce requirement of this account.\n * e.g.\n * To limit the nonce to use sequenced UserOps only (no \"out of order\" UserOps):\n * `require(nonce < type(uint64).max)`\n * For a hypothetical account that *requires* the nonce to be out-of-order:\n * `require(nonce & type(uint64).max == 0)`\n *\n * The actual nonce uniqueness is managed by the EntryPoint, and thus no other\n * action is needed by the account itself.\n *\n * @param nonce to validate\n *\n * solhint-disable-next-line no-empty-blocks\n */\n function _validateNonce(uint256 nonce) internal view virtual {}\n\n /**\n * sends to the entrypoint (msg.sender) the missing funds for this transaction.\n * subclass MAY override this method for better funds management\n * (e.g. send to the entryPoint more than the minimum required, so that in future transactions\n * it will not be required to send again)\n * @param missingAccountFunds the minimum value this method should send the entrypoint.\n * this value MAY be zero, in case there is enough deposit, or the userOp has a paymaster.\n */\n function _payPrefund(uint256 missingAccountFunds) internal virtual {\n if (missingAccountFunds != 0) {\n (bool success, ) = payable(msg.sender).call{\n value: missingAccountFunds,\n gas: type(uint256).max\n }(\"\");\n (success);\n //ignore failure (its EntryPoint's job to verify, not account.)\n }\n }\n}\n" + }, + "contracts/aa-4337/core/EntryPoint.sol": { + "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n\nimport \"../interfaces/IAccount.sol\";\nimport \"../interfaces/IPaymaster.sol\";\nimport \"../interfaces/IEntryPoint.sol\";\n\nimport \"../utils/Exec.sol\";\nimport \"./StakeManager.sol\";\nimport \"./SenderCreator.sol\";\nimport \"./Helpers.sol\";\nimport \"./NonceManager.sol\";\nimport \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\n\ncontract EntryPoint is\n IEntryPoint,\n StakeManager,\n NonceManager,\n ReentrancyGuard\n{\n using UserOperationLib for UserOperation;\n\n SenderCreator private immutable senderCreator = new SenderCreator();\n\n // internal value used during simulation: need to query aggregator.\n address private constant SIMULATE_FIND_AGGREGATOR = address(1);\n\n // marker for inner call revert on out of gas\n bytes32 private constant INNER_OUT_OF_GAS = hex\"deaddead\";\n\n uint256 private constant REVERT_REASON_MAX_LEN = 2048;\n\n /**\n * for simulation purposes, validateUserOp (and validatePaymasterUserOp) must return this value\n * in case of signature failure, instead of revert.\n */\n uint256 public constant SIG_VALIDATION_FAILED = 1;\n\n /**\n * compensate the caller's beneficiary address with the collected fees of all UserOperations.\n * @param beneficiary the address to receive the fees\n * @param amount amount to transfer.\n */\n function _compensate(address payable beneficiary, uint256 amount) internal {\n require(beneficiary != address(0), \"AA90 invalid beneficiary\");\n (bool success, ) = beneficiary.call{value: amount}(\"\");\n require(success, \"AA91 failed send to beneficiary\");\n }\n\n /**\n * execute a user op\n * @param opIndex index into the opInfo array\n * @param userOp the userOp to execute\n * @param opInfo the opInfo filled by validatePrepayment for this userOp.\n * @return collected the total amount this userOp paid.\n */\n function _executeUserOp(\n uint256 opIndex,\n UserOperation calldata userOp,\n UserOpInfo memory opInfo\n ) private returns (uint256 collected) {\n uint256 preGas = gasleft();\n bytes memory context = getMemoryBytesFromOffset(opInfo.contextOffset);\n\n try this.innerHandleOp(userOp.callData, opInfo, context) returns (\n uint256 _actualGasCost\n ) {\n collected = _actualGasCost;\n } catch {\n bytes32 innerRevertCode;\n assembly {\n returndatacopy(0, 0, 32)\n innerRevertCode := mload(0)\n }\n // handleOps was called with gas limit too low. abort entire bundle.\n if (innerRevertCode == INNER_OUT_OF_GAS) {\n //report paymaster, since if it is not deliberately caused by the bundler,\n // it must be a revert caused by paymaster.\n revert FailedOp(opIndex, \"AA95 out of gas\");\n }\n\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n collected = _handlePostOp(\n opIndex,\n IPaymaster.PostOpMode.postOpReverted,\n opInfo,\n context,\n actualGas\n );\n }\n }\n\n /**\n * Execute a batch of UserOperations.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(\n UserOperation[] calldata ops,\n address payable beneficiary\n ) public nonReentrant {\n uint256 opslen = ops.length;\n UserOpInfo[] memory opInfos = new UserOpInfo[](opslen);\n\n unchecked {\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[i];\n (\n uint256 validationData,\n uint256 pmValidationData\n ) = _validatePrepayment(i, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(\n i,\n validationData,\n pmValidationData,\n address(0)\n );\n }\n\n uint256 collected = 0;\n emit BeforeExecution();\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(i, ops[i], opInfos[i]);\n }\n\n _compensate(beneficiary, collected);\n } //unchecked\n }\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) public nonReentrant {\n uint256 opasLen = opsPerAggregator.length;\n uint256 totalOps = 0;\n for (uint256 i = 0; i < opasLen; i++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[i];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n //address(1) is special marker of \"signature error\"\n require(\n address(aggregator) != address(1),\n \"AA96 invalid aggregator\"\n );\n\n if (address(aggregator) != address(0)) {\n // solhint-disable-next-line no-empty-blocks\n try aggregator.validateSignatures(ops, opa.signature) {} catch {\n revert SignatureValidationFailed(address(aggregator));\n }\n }\n\n totalOps += ops.length;\n }\n\n UserOpInfo[] memory opInfos = new UserOpInfo[](totalOps);\n\n emit BeforeExecution();\n\n uint256 opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n uint256 opslen = ops.length;\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[opIndex];\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(opIndex, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(\n i,\n validationData,\n paymasterValidationData,\n address(aggregator)\n );\n opIndex++;\n }\n }\n\n uint256 collected = 0;\n opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n emit SignatureAggregatorChanged(address(opa.aggregator));\n UserOperation[] calldata ops = opa.userOps;\n uint256 opslen = ops.length;\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(opIndex, ops[i], opInfos[opIndex]);\n opIndex++;\n }\n }\n emit SignatureAggregatorChanged(address(0));\n\n _compensate(beneficiary, collected);\n }\n\n /// @inheritdoc IEntryPoint\n function simulateHandleOp(\n UserOperation calldata op,\n address target,\n bytes calldata targetCallData\n ) external override {\n UserOpInfo memory opInfo;\n _simulationOnlyValidations(op);\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(0, op, opInfo);\n ValidationData memory data = _intersectTimeRange(\n validationData,\n paymasterValidationData\n );\n\n numberMarker();\n uint256 paid = _executeUserOp(0, op, opInfo);\n numberMarker();\n bool targetSuccess;\n bytes memory targetResult;\n if (target != address(0)) {\n (targetSuccess, targetResult) = target.call(targetCallData);\n }\n revert ExecutionResult(\n opInfo.preOpGas,\n paid,\n data.validAfter,\n data.validUntil,\n targetSuccess,\n targetResult\n );\n }\n\n // A memory copy of UserOp static fields only.\n // Excluding: callData, initCode and signature. Replacing paymasterAndData with paymaster.\n struct MemoryUserOp {\n address sender;\n uint256 nonce;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n address paymaster;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n }\n\n struct UserOpInfo {\n MemoryUserOp mUserOp;\n bytes32 userOpHash;\n uint256 prefund;\n uint256 contextOffset;\n uint256 preOpGas;\n }\n\n /**\n * inner function to handle a UserOperation.\n * Must be declared \"external\" to open a call context, but it can only be called by handleOps.\n */\n function innerHandleOp(\n bytes memory callData,\n UserOpInfo memory opInfo,\n bytes calldata context\n ) external returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n require(msg.sender == address(this), \"AA92 internal call only\");\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n\n uint callGasLimit = mUserOp.callGasLimit;\n unchecked {\n // handleOps was called with gas limit too low. abort entire bundle.\n if (\n gasleft() < callGasLimit + mUserOp.verificationGasLimit + 5000\n ) {\n assembly {\n mstore(0, INNER_OUT_OF_GAS)\n revert(0, 32)\n }\n }\n }\n\n IPaymaster.PostOpMode mode = IPaymaster.PostOpMode.opSucceeded;\n if (callData.length > 0) {\n bool success = Exec.call(mUserOp.sender, 0, callData, callGasLimit);\n if (!success) {\n bytes memory result = Exec.getReturnData(REVERT_REASON_MAX_LEN);\n if (result.length > 0) {\n emit UserOperationRevertReason(\n opInfo.userOpHash,\n mUserOp.sender,\n mUserOp.nonce,\n result\n );\n }\n mode = IPaymaster.PostOpMode.opReverted;\n }\n }\n\n unchecked {\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n //note: opIndex is ignored (relevant only if mode==postOpReverted, which is only possible outside of innerHandleOp)\n return _handlePostOp(0, mode, opInfo, context, actualGas);\n }\n }\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(\n UserOperation calldata userOp\n ) public view returns (bytes32) {\n return\n keccak256(abi.encode(userOp.hash(), address(this), block.chainid));\n }\n\n /**\n * copy general fields from userOp into the memory opInfo structure.\n */\n function _copyUserOpToMemory(\n UserOperation calldata userOp,\n MemoryUserOp memory mUserOp\n ) internal pure {\n mUserOp.sender = userOp.sender;\n mUserOp.nonce = userOp.nonce;\n mUserOp.callGasLimit = userOp.callGasLimit;\n mUserOp.verificationGasLimit = userOp.verificationGasLimit;\n mUserOp.preVerificationGas = userOp.preVerificationGas;\n mUserOp.maxFeePerGas = userOp.maxFeePerGas;\n mUserOp.maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes calldata paymasterAndData = userOp.paymasterAndData;\n if (paymasterAndData.length > 0) {\n require(\n paymasterAndData.length >= 20,\n \"AA93 invalid paymasterAndData\"\n );\n mUserOp.paymaster = address(bytes20(paymasterAndData[:20]));\n } else {\n mUserOp.paymaster = address(0);\n }\n }\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external {\n UserOpInfo memory outOpInfo;\n\n _simulationOnlyValidations(userOp);\n (\n uint256 validationData,\n uint256 paymasterValidationData\n ) = _validatePrepayment(0, userOp, outOpInfo);\n StakeInfo memory paymasterInfo = _getStakeInfo(\n outOpInfo.mUserOp.paymaster\n );\n StakeInfo memory senderInfo = _getStakeInfo(outOpInfo.mUserOp.sender);\n StakeInfo memory factoryInfo;\n {\n bytes calldata initCode = userOp.initCode;\n address factory = initCode.length >= 20\n ? address(bytes20(initCode[0:20]))\n : address(0);\n factoryInfo = _getStakeInfo(factory);\n }\n\n ValidationData memory data = _intersectTimeRange(\n validationData,\n paymasterValidationData\n );\n address aggregator = data.aggregator;\n bool sigFailed = aggregator == address(1);\n ReturnInfo memory returnInfo = ReturnInfo(\n outOpInfo.preOpGas,\n outOpInfo.prefund,\n sigFailed,\n data.validAfter,\n data.validUntil,\n getMemoryBytesFromOffset(outOpInfo.contextOffset)\n );\n\n if (aggregator != address(0) && aggregator != address(1)) {\n AggregatorStakeInfo memory aggregatorInfo = AggregatorStakeInfo(\n aggregator,\n _getStakeInfo(aggregator)\n );\n revert ValidationResultWithAggregation(\n returnInfo,\n senderInfo,\n factoryInfo,\n paymasterInfo,\n aggregatorInfo\n );\n }\n revert ValidationResult(\n returnInfo,\n senderInfo,\n factoryInfo,\n paymasterInfo\n );\n }\n\n function _getRequiredPrefund(\n MemoryUserOp memory mUserOp\n ) internal pure returns (uint256 requiredPrefund) {\n unchecked {\n //when using a Paymaster, the verificationGasLimit is used also to as a limit for the postOp call.\n // our security model might call postOp eventually twice\n uint256 mul = mUserOp.paymaster != address(0) ? 3 : 1;\n uint256 requiredGas = mUserOp.callGasLimit +\n mUserOp.verificationGasLimit *\n mul +\n mUserOp.preVerificationGas;\n\n requiredPrefund = requiredGas * mUserOp.maxFeePerGas;\n }\n }\n\n // create the sender's contract if needed.\n function _createSenderIfNeeded(\n uint256 opIndex,\n UserOpInfo memory opInfo,\n bytes calldata initCode\n ) internal {\n if (initCode.length != 0) {\n address sender = opInfo.mUserOp.sender;\n if (sender.code.length != 0)\n revert FailedOp(opIndex, \"AA10 sender already constructed\");\n address sender1 = senderCreator.createSender{\n gas: opInfo.mUserOp.verificationGasLimit\n }(initCode);\n if (sender1 == address(0))\n revert FailedOp(opIndex, \"AA13 initCode failed or OOG\");\n if (sender1 != sender)\n revert FailedOp(opIndex, \"AA14 initCode must return sender\");\n if (sender1.code.length == 0)\n revert FailedOp(opIndex, \"AA15 initCode must create sender\");\n address factory = address(bytes20(initCode[0:20]));\n emit AccountDeployed(\n opInfo.userOpHash,\n sender,\n factory,\n opInfo.mUserOp.paymaster\n );\n }\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes calldata initCode) public {\n address sender = senderCreator.createSender(initCode);\n revert SenderAddressResult(sender);\n }\n\n function _simulationOnlyValidations(\n UserOperation calldata userOp\n ) internal view {\n // solhint-disable-next-line no-empty-blocks\n try\n this._validateSenderAndPaymaster(\n userOp.initCode,\n userOp.sender,\n userOp.paymasterAndData\n )\n {} catch Error(string memory revertReason) {\n if (bytes(revertReason).length != 0) {\n revert FailedOp(0, revertReason);\n }\n }\n }\n\n /**\n * Called only during simulation.\n * This function always reverts to prevent warm/cold storage differentiation in simulation vs execution.\n */\n function _validateSenderAndPaymaster(\n bytes calldata initCode,\n address sender,\n bytes calldata paymasterAndData\n ) external view {\n if (initCode.length == 0 && sender.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA20 account not deployed\");\n }\n if (paymasterAndData.length >= 20) {\n address paymaster = address(bytes20(paymasterAndData[0:20]));\n if (paymaster.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA30 paymaster not deployed\");\n }\n }\n // always revert\n revert(\"\");\n }\n\n /**\n * call account.validateUserOp.\n * revert (with FailedOp) in case validateUserOp reverts, or account didn't send required prefund.\n * decrement account's deposit if needed\n */\n function _validateAccountPrepayment(\n uint256 opIndex,\n UserOperation calldata op,\n UserOpInfo memory opInfo,\n uint256 requiredPrefund\n )\n internal\n returns (\n uint256 gasUsedByValidateAccountPrepayment,\n uint256 validationData\n )\n {\n unchecked {\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n address sender = mUserOp.sender;\n _createSenderIfNeeded(opIndex, opInfo, op.initCode);\n address paymaster = mUserOp.paymaster;\n numberMarker();\n uint256 missingAccountFunds = 0;\n if (paymaster == address(0)) {\n uint256 bal = balanceOf(sender);\n missingAccountFunds = bal > requiredPrefund\n ? 0\n : requiredPrefund - bal;\n }\n try\n IAccount(sender).validateUserOp{\n gas: mUserOp.verificationGasLimit\n }(op, opInfo.userOpHash, missingAccountFunds)\n returns (uint256 _validationData) {\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA23 reverted: \", revertReason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA23 reverted (or OOG)\");\n }\n if (paymaster == address(0)) {\n DepositInfo storage senderInfo = deposits[sender];\n uint256 deposit = senderInfo.deposit;\n if (requiredPrefund > deposit) {\n revert FailedOp(opIndex, \"AA21 didn't pay prefund\");\n }\n senderInfo.deposit = uint112(deposit - requiredPrefund);\n }\n gasUsedByValidateAccountPrepayment = preGas - gasleft();\n }\n }\n\n /**\n * In case the request has a paymaster:\n * Validate paymaster has enough deposit.\n * Call paymaster.validatePaymasterUserOp.\n * Revert with proper FailedOp in case paymaster reverts.\n * Decrement paymaster's deposit\n */\n function _validatePaymasterPrepayment(\n uint256 opIndex,\n UserOperation calldata op,\n UserOpInfo memory opInfo,\n uint256 requiredPreFund,\n uint256 gasUsedByValidateAccountPrepayment\n ) internal returns (bytes memory context, uint256 validationData) {\n unchecked {\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 verificationGasLimit = mUserOp.verificationGasLimit;\n require(\n verificationGasLimit > gasUsedByValidateAccountPrepayment,\n \"AA41 too little verificationGas\"\n );\n uint256 gas = verificationGasLimit -\n gasUsedByValidateAccountPrepayment;\n\n address paymaster = mUserOp.paymaster;\n DepositInfo storage paymasterInfo = deposits[paymaster];\n uint256 deposit = paymasterInfo.deposit;\n if (deposit < requiredPreFund) {\n revert FailedOp(opIndex, \"AA31 paymaster deposit too low\");\n }\n paymasterInfo.deposit = uint112(deposit - requiredPreFund);\n try\n IPaymaster(paymaster).validatePaymasterUserOp{gas: gas}(\n op,\n opInfo.userOpHash,\n requiredPreFund\n )\n returns (bytes memory _context, uint256 _validationData) {\n context = _context;\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA33 reverted: \", revertReason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA33 reverted (or OOG)\");\n }\n }\n }\n\n /**\n * revert if either account validationData or paymaster validationData is expired\n */\n function _validateAccountAndPaymasterValidationData(\n uint256 opIndex,\n uint256 validationData,\n uint256 paymasterValidationData,\n address expectedAggregator\n ) internal view {\n (address aggregator, bool outOfTimeRange) = _getValidationData(\n validationData\n );\n if (expectedAggregator != aggregator) {\n revert FailedOp(opIndex, \"AA24 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA22 expired or not due\");\n }\n //pmAggregator is not a real signature aggregator: we don't have logic to handle it as address.\n // non-zero address means that the paymaster fails due to some signature check (which is ok only during estimation)\n address pmAggregator;\n (pmAggregator, outOfTimeRange) = _getValidationData(\n paymasterValidationData\n );\n if (pmAggregator != address(0)) {\n revert FailedOp(opIndex, \"AA34 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA32 paymaster expired or not due\");\n }\n }\n\n function _getValidationData(\n uint256 validationData\n ) internal view returns (address aggregator, bool outOfTimeRange) {\n if (validationData == 0) {\n return (address(0), false);\n }\n ValidationData memory data = _parseValidationData(validationData);\n // solhint-disable-next-line not-rely-on-time\n outOfTimeRange =\n block.timestamp > data.validUntil ||\n block.timestamp < data.validAfter;\n aggregator = data.aggregator;\n }\n\n /**\n * validate account and paymaster (if defined).\n * also make sure total validation doesn't exceed verificationGasLimit\n * this method is called off-chain (simulateValidation()) and on-chain (from handleOps)\n * @param opIndex the index of this userOp into the \"opInfos\" array\n * @param userOp the userOp to validate\n */\n function _validatePrepayment(\n uint256 opIndex,\n UserOperation calldata userOp,\n UserOpInfo memory outOpInfo\n )\n private\n returns (uint256 validationData, uint256 paymasterValidationData)\n {\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = outOpInfo.mUserOp;\n _copyUserOpToMemory(userOp, mUserOp);\n outOpInfo.userOpHash = getUserOpHash(userOp);\n\n // validate all numeric values in userOp are well below 128 bit, so they can safely be added\n // and multiplied without causing overflow\n uint256 maxGasValues = mUserOp.preVerificationGas |\n mUserOp.verificationGasLimit |\n mUserOp.callGasLimit |\n userOp.maxFeePerGas |\n userOp.maxPriorityFeePerGas;\n require(maxGasValues <= type(uint120).max, \"AA94 gas values overflow\");\n\n uint256 gasUsedByValidateAccountPrepayment;\n uint256 requiredPreFund = _getRequiredPrefund(mUserOp);\n (\n gasUsedByValidateAccountPrepayment,\n validationData\n ) = _validateAccountPrepayment(\n opIndex,\n userOp,\n outOpInfo,\n requiredPreFund\n );\n\n if (!_validateAndUpdateNonce(mUserOp.sender, mUserOp.nonce)) {\n revert FailedOp(opIndex, \"AA25 invalid account nonce\");\n }\n\n //a \"marker\" where account opcode validation is done and paymaster opcode validation is about to start\n // (used only by off-chain simulateValidation)\n numberMarker();\n\n bytes memory context;\n if (mUserOp.paymaster != address(0)) {\n (context, paymasterValidationData) = _validatePaymasterPrepayment(\n opIndex,\n userOp,\n outOpInfo,\n requiredPreFund,\n gasUsedByValidateAccountPrepayment\n );\n }\n unchecked {\n uint256 gasUsed = preGas - gasleft();\n\n if (userOp.verificationGasLimit < gasUsed) {\n revert FailedOp(opIndex, \"AA40 over verificationGasLimit\");\n }\n outOpInfo.prefund = requiredPreFund;\n outOpInfo.contextOffset = getOffsetOfMemoryBytes(context);\n outOpInfo.preOpGas = preGas - gasleft() + userOp.preVerificationGas;\n }\n }\n\n /**\n * process post-operation.\n * called just after the callData is executed.\n * if a paymaster is defined and its validation returned a non-empty context, its postOp is called.\n * the excess amount is refunded to the account (or paymaster - if it was used in the request)\n * @param opIndex index in the batch\n * @param mode - whether is called from innerHandleOp, or outside (postOpReverted)\n * @param opInfo userOp fields and info collected during validation\n * @param context the context returned in validatePaymasterUserOp\n * @param actualGas the gas used so far by this user operation\n */\n function _handlePostOp(\n uint256 opIndex,\n IPaymaster.PostOpMode mode,\n UserOpInfo memory opInfo,\n bytes memory context,\n uint256 actualGas\n ) private returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n unchecked {\n address refundAddress;\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 gasPrice = getUserOpGasPrice(mUserOp);\n\n address paymaster = mUserOp.paymaster;\n if (paymaster == address(0)) {\n refundAddress = mUserOp.sender;\n } else {\n refundAddress = paymaster;\n if (context.length > 0) {\n actualGasCost = actualGas * gasPrice;\n if (mode != IPaymaster.PostOpMode.postOpReverted) {\n IPaymaster(paymaster).postOp{\n gas: mUserOp.verificationGasLimit\n }(mode, context, actualGasCost);\n } else {\n // solhint-disable-next-line no-empty-blocks\n try\n IPaymaster(paymaster).postOp{\n gas: mUserOp.verificationGasLimit\n }(mode, context, actualGasCost)\n {} catch Error(string memory reason) {\n revert FailedOp(\n opIndex,\n string.concat(\"AA50 postOp reverted: \", reason)\n );\n } catch {\n revert FailedOp(opIndex, \"AA50 postOp revert\");\n }\n }\n }\n }\n actualGas += preGas - gasleft();\n actualGasCost = actualGas * gasPrice;\n if (opInfo.prefund < actualGasCost) {\n revert FailedOp(opIndex, \"AA51 prefund below actualGasCost\");\n }\n uint256 refund = opInfo.prefund - actualGasCost;\n _incrementDeposit(refundAddress, refund);\n bool success = mode == IPaymaster.PostOpMode.opSucceeded;\n emit UserOperationEvent(\n opInfo.userOpHash,\n mUserOp.sender,\n mUserOp.paymaster,\n mUserOp.nonce,\n success,\n actualGasCost,\n actualGas\n );\n } // unchecked\n }\n\n /**\n * the gas price this UserOp agrees to pay.\n * relayer/block builder might submit the TX with higher priorityFee, but the user should not\n */\n function getUserOpGasPrice(\n MemoryUserOp memory mUserOp\n ) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = mUserOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = mUserOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n function getOffsetOfMemoryBytes(\n bytes memory data\n ) internal pure returns (uint256 offset) {\n assembly {\n offset := data\n }\n }\n\n function getMemoryBytesFromOffset(\n uint256 offset\n ) internal pure returns (bytes memory data) {\n assembly {\n data := offset\n }\n }\n\n //place the NUMBER opcode in the code.\n // this is used as a marker during simulation, as this OP is completely banned from the simulated code of the\n // account and paymaster.\n function numberMarker() internal view {\n assembly {\n mstore(0, number())\n }\n }\n}\n" + }, + "contracts/aa-4337/core/Helpers.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/* solhint-disable no-inline-assembly */\n\n/**\n * returned data from validateUserOp.\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\n * @param aggregator - address(0) - the account validated the signature by itself.\n * address(1) - the account failed to validate the signature.\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\n * @param validAfter - this UserOp is valid only after this timestamp.\n * @param validaUntil - this UserOp is valid only up to this timestamp.\n */\nstruct ValidationData {\n address aggregator;\n uint48 validAfter;\n uint48 validUntil;\n}\n\n//extract sigFailed, validAfter, validUntil.\n// also convert zero validUntil to type(uint48).max\nfunction _parseValidationData(\n uint validationData\n) pure returns (ValidationData memory data) {\n address aggregator = address(uint160(validationData));\n uint48 validUntil = uint48(validationData >> 160);\n if (validUntil == 0) {\n validUntil = type(uint48).max;\n }\n uint48 validAfter = uint48(validationData >> (48 + 160));\n return ValidationData(aggregator, validAfter, validUntil);\n}\n\n// intersect account and paymaster ranges.\nfunction _intersectTimeRange(\n uint256 validationData,\n uint256 paymasterValidationData\n) pure returns (ValidationData memory) {\n ValidationData memory accountValidationData = _parseValidationData(\n validationData\n );\n ValidationData memory pmValidationData = _parseValidationData(\n paymasterValidationData\n );\n address aggregator = accountValidationData.aggregator;\n if (aggregator == address(0)) {\n aggregator = pmValidationData.aggregator;\n }\n uint48 validAfter = accountValidationData.validAfter;\n uint48 validUntil = accountValidationData.validUntil;\n uint48 pmValidAfter = pmValidationData.validAfter;\n uint48 pmValidUntil = pmValidationData.validUntil;\n\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\n return ValidationData(aggregator, validAfter, validUntil);\n}\n\n/**\n * helper to pack the return value for validateUserOp\n * @param data - the ValidationData to pack\n */\nfunction _packValidationData(\n ValidationData memory data\n) pure returns (uint256) {\n return\n uint160(data.aggregator) |\n (uint256(data.validUntil) << 160) |\n (uint256(data.validAfter) << (160 + 48));\n}\n\n/**\n * helper to pack the return value for validateUserOp, when not using an aggregator\n * @param sigFailed - true for signature failure, false for success\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\n * @param validAfter first timestamp this UserOperation is valid\n */\nfunction _packValidationData(\n bool sigFailed,\n uint48 validUntil,\n uint48 validAfter\n) pure returns (uint256) {\n return\n (sigFailed ? 1 : 0) |\n (uint256(validUntil) << 160) |\n (uint256(validAfter) << (160 + 48));\n}\n\n/**\n * keccak function over calldata.\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\n */\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\n assembly {\n let mem := mload(0x40)\n let len := data.length\n calldatacopy(mem, data.offset, len)\n ret := keccak256(mem, len)\n }\n}\n" + }, + "contracts/aa-4337/core/NonceManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\nimport \"../interfaces/IEntryPoint.sol\";\n\n/**\n * nonce management functionality\n */\ncontract NonceManager is INonceManager {\n /**\n * The next valid sequence number for a given nonce key.\n */\n mapping(address => mapping(uint192 => uint256)) public nonceSequenceNumber;\n\n function getNonce(\n address sender,\n uint192 key\n ) public view override returns (uint256 nonce) {\n return nonceSequenceNumber[sender][key] | (uint256(key) << 64);\n }\n\n // allow an account to manually increment its own nonce.\n // (mainly so that during construction nonce can be made non-zero,\n // to \"absorb\" the gas cost of first nonce increment to 1st transaction (construction),\n // not to 2nd transaction)\n function incrementNonce(uint192 key) public override {\n nonceSequenceNumber[msg.sender][key]++;\n }\n\n /**\n * validate nonce uniqueness for this account.\n * called just after validateUserOp()\n */\n function _validateAndUpdateNonce(\n address sender,\n uint256 nonce\n ) internal returns (bool) {\n uint192 key = uint192(nonce >> 64);\n uint64 seq = uint64(nonce);\n return nonceSequenceNumber[sender][key]++ == seq;\n }\n}\n" + }, + "contracts/aa-4337/core/SenderCreator.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n/**\n * helper contract for EntryPoint, to call userOp.initCode from a \"neutral\" address,\n * which is explicitly not the entryPoint itself.\n */\ncontract SenderCreator {\n /**\n * call the \"initCode\" factory to create and return the sender account address\n * @param initCode the initCode value from a UserOp. contains 20 bytes of factory address, followed by calldata\n * @return sender the returned address of the created account, or zero address on failure.\n */\n function createSender(\n bytes calldata initCode\n ) external returns (address sender) {\n address factory = address(bytes20(initCode[0:20]));\n bytes memory initCallData = initCode[20:];\n bool success;\n /* solhint-disable no-inline-assembly */\n assembly {\n success := call(\n gas(),\n factory,\n 0,\n add(initCallData, 0x20),\n mload(initCallData),\n 0,\n 32\n )\n sender := mload(0)\n }\n if (!success) {\n sender = address(0);\n }\n }\n}\n" + }, + "contracts/aa-4337/core/StakeManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity 0.8.21;\n\nimport \"../interfaces/IStakeManager.sol\";\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable not-rely-on-time */\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by a paymaster.\n */\nabstract contract StakeManager is IStakeManager {\n /// maps paymaster to their deposits and stakes\n mapping(address => DepositInfo) public deposits;\n\n /// @inheritdoc IStakeManager\n function getDepositInfo(\n address account\n ) public view returns (DepositInfo memory info) {\n return deposits[account];\n }\n\n // internal method to return just the stake info\n function _getStakeInfo(\n address addr\n ) internal view returns (StakeInfo memory info) {\n DepositInfo storage depositInfo = deposits[addr];\n info.stake = depositInfo.stake;\n info.unstakeDelaySec = depositInfo.unstakeDelaySec;\n }\n\n /// return the deposit (for gas payment) of the account\n function balanceOf(address account) public view returns (uint256) {\n return deposits[account].deposit;\n }\n\n receive() external payable {\n depositTo(msg.sender);\n }\n\n function _incrementDeposit(address account, uint256 amount) internal {\n DepositInfo storage info = deposits[account];\n uint256 newAmount = info.deposit + amount;\n require(newAmount <= type(uint112).max, \"deposit overflow\");\n info.deposit = uint112(newAmount);\n }\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) public payable {\n _incrementDeposit(account, msg.value);\n DepositInfo storage info = deposits[account];\n emit Deposited(account, info.deposit);\n }\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 unstakeDelaySec) public payable {\n DepositInfo storage info = deposits[msg.sender];\n require(unstakeDelaySec > 0, \"must specify unstake delay\");\n require(\n unstakeDelaySec >= info.unstakeDelaySec,\n \"cannot decrease unstake time\"\n );\n uint256 stake = info.stake + msg.value;\n require(stake > 0, \"no stake specified\");\n require(stake <= type(uint112).max, \"stake overflow\");\n deposits[msg.sender] = DepositInfo(\n info.deposit,\n true,\n uint112(stake),\n unstakeDelaySec,\n 0\n );\n emit StakeLocked(msg.sender, stake, unstakeDelaySec);\n }\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external {\n DepositInfo storage info = deposits[msg.sender];\n require(info.unstakeDelaySec != 0, \"not staked\");\n require(info.staked, \"already unstaking\");\n uint48 withdrawTime = uint48(block.timestamp) + info.unstakeDelaySec;\n info.withdrawTime = withdrawTime;\n info.staked = false;\n emit StakeUnlocked(msg.sender, withdrawTime);\n }\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external {\n DepositInfo storage info = deposits[msg.sender];\n uint256 stake = info.stake;\n require(stake > 0, \"No stake to withdraw\");\n require(info.withdrawTime > 0, \"must call unlockStake() first\");\n require(\n info.withdrawTime <= block.timestamp,\n \"Stake withdrawal is not due\"\n );\n info.unstakeDelaySec = 0;\n info.withdrawTime = 0;\n info.stake = 0;\n emit StakeWithdrawn(msg.sender, withdrawAddress, stake);\n (bool success, ) = withdrawAddress.call{value: stake}(\"\");\n require(success, \"failed to withdraw stake\");\n }\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(\n address payable withdrawAddress,\n uint256 withdrawAmount\n ) external {\n DepositInfo storage info = deposits[msg.sender];\n require(withdrawAmount <= info.deposit, \"Withdraw amount too large\");\n info.deposit = uint112(info.deposit - withdrawAmount);\n emit Withdrawn(msg.sender, withdrawAddress, withdrawAmount);\n (bool success, ) = withdrawAddress.call{value: withdrawAmount}(\"\");\n require(success, \"failed to withdraw\");\n }\n}\n" + }, + "contracts/aa-4337/interfaces/IAccount.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\ninterface IAccount {\n /**\n * Validate user's signature and nonce\n * the entryPoint will make the call to the recipient only if this validation call returns successfully.\n * signature failure should be reported by returning SIG_VALIDATION_FAILED (1).\n * This allows making a \"simulation call\" without a valid signature\n * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure.\n *\n * @dev Must validate caller is the entryPoint.\n * Must validate the signature and nonce\n * @param userOp the operation that is about to be executed.\n * @param userOpHash hash of the user's request data. can be used as the basis for signature.\n * @param missingAccountFunds missing funds on the account's deposit in the entrypoint.\n * This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call.\n * The excess is left as a deposit in the entrypoint, for future calls.\n * can be withdrawn anytime using \"entryPoint.withdrawTo()\"\n * In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero.\n * @return validationData packaged ValidationData structure. use `_packValidationData` and `_unpackValidationData` to encode and decode\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * If an account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validateUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 missingAccountFunds\n ) external returns (uint256 validationData);\n}\n" + }, + "contracts/aa-4337/interfaces/IAggregator.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * Aggregated Signatures validator.\n */\ninterface IAggregator {\n /**\n * validate aggregated signature.\n * revert if the aggregated signature does not match the given list of operations.\n */\n function validateSignatures(\n UserOperation[] calldata userOps,\n bytes calldata signature\n ) external view;\n\n /**\n * validate signature of a single userOp\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\n * @param userOp the userOperation received from the user.\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\n * (usually empty, unless account and aggregator support some kind of \"multisig\"\n */\n function validateUserOpSignature(\n UserOperation calldata userOp\n ) external view returns (bytes memory sigForUserOp);\n\n /**\n * aggregate multiple signatures into a single value.\n * This method is called off-chain to calculate the signature to pass with handleOps()\n * bundler MAY use optimized custom code perform this aggregation\n * @param userOps array of UserOperations to collect the signatures from.\n * @return aggregatedSignature the aggregated signature\n */\n function aggregateSignatures(\n UserOperation[] calldata userOps\n ) external view returns (bytes memory aggregatedSignature);\n}\n" + }, + "contracts/aa-4337/interfaces/IEntryPoint.sol": { + "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n/* solhint-disable reason-string */\n\nimport \"./UserOperation.sol\";\nimport \"./IStakeManager.sol\";\nimport \"./IAggregator.sol\";\nimport \"./INonceManager.sol\";\n\ninterface IEntryPoint is IStakeManager, INonceManager {\n /***\n * An event emitted after each successful request\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\n * @param sender - the account that generates this request.\n * @param paymaster - if non-null, the paymaster that pays for this request.\n * @param nonce - the nonce value from the request.\n * @param success - true if the sender transaction succeeded, false if reverted.\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\n */\n event UserOperationEvent(\n bytes32 indexed userOpHash,\n address indexed sender,\n address indexed paymaster,\n uint256 nonce,\n bool success,\n uint256 actualGasCost,\n uint256 actualGasUsed\n );\n\n /**\n * account \"sender\" was deployed.\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\n * @param sender the account that is deployed\n * @param factory the factory used to deploy this account (in the initCode)\n * @param paymaster the paymaster used by this UserOp\n */\n event AccountDeployed(\n bytes32 indexed userOpHash,\n address indexed sender,\n address factory,\n address paymaster\n );\n\n /**\n * An event emitted if the UserOperation \"callData\" reverted with non-zero length\n * @param userOpHash the request unique identifier.\n * @param sender the sender of this request\n * @param nonce the nonce used in the request\n * @param revertReason - the return bytes from the (reverted) call to \"callData\".\n */\n event UserOperationRevertReason(\n bytes32 indexed userOpHash,\n address indexed sender,\n uint256 nonce,\n bytes revertReason\n );\n\n /**\n * an event emitted by handleOps(), before starting the execution loop.\n * any event emitted before this event, is part of the validation.\n */\n event BeforeExecution();\n\n /**\n * signature aggregator used by the following UserOperationEvents within this bundle.\n */\n event SignatureAggregatorChanged(address indexed aggregator);\n\n /**\n * a custom revert error of handleOps, to identify the offending op.\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\n * @param reason - revert reason\n * The string starts with a unique code \"AAmn\", where \"m\" is \"1\" for factory, \"2\" for account and \"3\" for paymaster issues,\n * so a failure can be attributed to the correct entity.\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\n */\n error FailedOp(uint256 opIndex, string reason);\n\n /**\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\n */\n error SignatureValidationFailed(address aggregator);\n\n /**\n * Successful result from simulateValidation.\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n */\n error ValidationResult(\n ReturnInfo returnInfo,\n StakeInfo senderInfo,\n StakeInfo factoryInfo,\n StakeInfo paymasterInfo\n );\n\n /**\n * Successful result from simulateValidation, if the account returns a signature aggregator\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\n * bundler MUST use it to verify the signature, or reject the UserOperation\n */\n error ValidationResultWithAggregation(\n ReturnInfo returnInfo,\n StakeInfo senderInfo,\n StakeInfo factoryInfo,\n StakeInfo paymasterInfo,\n AggregatorStakeInfo aggregatorInfo\n );\n\n /**\n * return value of getSenderAddress\n */\n error SenderAddressResult(address sender);\n\n /**\n * return value of simulateHandleOp\n */\n error ExecutionResult(\n uint256 preOpGas,\n uint256 paid,\n uint48 validAfter,\n uint48 validUntil,\n bool targetSuccess,\n bytes targetResult\n );\n\n //UserOps handled, per aggregator\n struct UserOpsPerAggregator {\n UserOperation[] userOps;\n // aggregator address\n IAggregator aggregator;\n // aggregated signature\n bytes signature;\n }\n\n /**\n * Execute a batch of UserOperation.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(\n UserOperation[] calldata ops,\n address payable beneficiary\n ) external;\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) external;\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(\n UserOperation calldata userOp\n ) external view returns (bytes32);\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external;\n\n /**\n * gas and return values during simulation\n * @param preOpGas the gas used for validation (including preValidationGas)\n * @param prefund the required prefund for this operation\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\n */\n struct ReturnInfo {\n uint256 preOpGas;\n uint256 prefund;\n bool sigFailed;\n uint48 validAfter;\n uint48 validUntil;\n bytes paymasterContext;\n }\n\n /**\n * returned aggregated signature info.\n * the aggregator returned by the account, and its current stake.\n */\n struct AggregatorStakeInfo {\n address aggregator;\n StakeInfo stakeInfo;\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes memory initCode) external;\n\n /**\n * simulate full execution of a UserOperation (including both validation and target execution)\n * this method will always revert with \"ExecutionResult\".\n * it performs full validation of the UserOperation, but ignores signature error.\n * an optional target address is called after the userop succeeds, and its value is returned\n * (before the entire call is reverted)\n * Note that in order to collect the the success/failure of the target call, it must be executed\n * with trace enabled to track the emitted events.\n * @param op the UserOperation to simulate\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\n * are set to the return from that call.\n * @param targetCallData callData to pass to target address\n */\n function simulateHandleOp(\n UserOperation calldata op,\n address target,\n bytes calldata targetCallData\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/INonceManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\ninterface INonceManager {\n /**\n * Return the next nonce for this sender.\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\n * But UserOp with different keys can come with arbitrary order.\n *\n * @param sender the account address\n * @param key the high 192 bit of the nonce\n * @return nonce a full nonce to pass for next UserOp with this sender.\n */\n function getNonce(\n address sender,\n uint192 key\n ) external view returns (uint256 nonce);\n\n /**\n * Manually increment the nonce of the sender.\n * This method is exposed just for completeness..\n * Account does NOT need to call it, neither during validation, nor elsewhere,\n * as the EntryPoint will update the nonce regardless.\n * Possible use-case is call it with various keys to \"initialize\" their nonces to one, so that future\n * UserOperations will not pay extra for the first transaction with a given key.\n */\n function incrementNonce(uint192 key) external;\n}\n" + }, + "contracts/aa-4337/interfaces/IPaymaster.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * the interface exposed by a paymaster contract, who agrees to pay the gas for user's operations.\n * a paymaster must hold a stake to cover the required entrypoint stake and also the gas for the transaction.\n */\ninterface IPaymaster {\n enum PostOpMode {\n opSucceeded, // user op succeeded\n opReverted, // user op reverted. still has to pay for gas.\n postOpReverted //user op succeeded, but caused postOp to revert. Now it's a 2nd call, after user's op was deliberately reverted.\n }\n\n /**\n * payment validation: check if paymaster agrees to pay.\n * Must verify sender is the entryPoint.\n * Revert to reject this request.\n * Note that bundlers will reject this method if it changes the state, unless the paymaster is trusted (whitelisted)\n * The paymaster pre-pays using its deposit, and receive back a refund after the postOp method returns.\n * @param userOp the user operation\n * @param userOpHash hash of the user's request data.\n * @param maxCost the maximum cost of this transaction (based on maximum gas and gas price from userOp)\n * @return context value to send to a postOp\n * zero length to signify postOp is not required.\n * @return validationData signature and time-range of this operation, encoded the same as the return value of validateUserOperation\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validatePaymasterUserOp(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256 maxCost\n ) external returns (bytes memory context, uint256 validationData);\n\n /**\n * post-operation handler.\n * Must verify sender is the entryPoint\n * @param mode enum with the following options:\n * opSucceeded - user operation succeeded.\n * opReverted - user op reverted. still has to pay for gas.\n * postOpReverted - user op succeeded, but caused postOp (in mode=opSucceeded) to revert.\n * Now this is the 2nd call, after user's op was deliberately reverted.\n * @param context - the context value returned by validatePaymasterUserOp\n * @param actualGasCost - actual gas used so far (without this postOp call).\n */\n function postOp(\n PostOpMode mode,\n bytes calldata context,\n uint256 actualGasCost\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/IStakeManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.12;\n\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by the staked entity.\n */\ninterface IStakeManager {\n event Deposited(address indexed account, uint256 totalDeposit);\n\n event Withdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /// Emitted when stake or unstake delay are modified\n event StakeLocked(\n address indexed account,\n uint256 totalStaked,\n uint256 unstakeDelaySec\n );\n\n /// Emitted once a stake is scheduled for withdrawal\n event StakeUnlocked(address indexed account, uint256 withdrawTime);\n\n event StakeWithdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /**\n * @param deposit the entity's deposit\n * @param staked true if this entity is staked.\n * @param stake actual amount of ether staked for this entity.\n * @param unstakeDelaySec minimum delay to withdraw the stake.\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\n * and the rest fit into a 2nd cell.\n * 112 bit allows for 10^15 eth\n * 48 bit for full timestamp\n * 32 bit allows 150 years for unstake delay\n */\n struct DepositInfo {\n uint112 deposit;\n bool staked;\n uint112 stake;\n uint32 unstakeDelaySec;\n uint48 withdrawTime;\n }\n\n //API struct used by getStakeInfo and simulateValidation\n struct StakeInfo {\n uint256 stake;\n uint256 unstakeDelaySec;\n }\n\n /// @return info - full deposit information of given account\n function getDepositInfo(\n address account\n ) external view returns (DepositInfo memory info);\n\n /// @return the deposit (for gas payment) of the account\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) external payable;\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 _unstakeDelaySec) external payable;\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external;\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external;\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(\n address payable withdrawAddress,\n uint256 withdrawAmount\n ) external;\n}\n" + }, + "contracts/aa-4337/interfaces/UserOperation.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable no-inline-assembly */\n\nimport {calldataKeccak} from \"../core/Helpers.sol\";\n\n/**\n * User Operation struct\n * @param sender the sender account of this request.\n * @param nonce unique value the sender uses to verify it is not a replay.\n * @param initCode if set, the account contract will be created by this constructor/\n * @param callData the method call to execute on this account.\n * @param callGasLimit the gas limit passed to the callData method call.\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\n * @param maxFeePerGas same as EIP-1559 gas parameter.\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\n */\nstruct UserOperation {\n address sender;\n uint256 nonce;\n bytes initCode;\n bytes callData;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n bytes paymasterAndData;\n bytes signature;\n}\n\n/**\n * Utility functions helpful when working with UserOperation structs.\n */\nlibrary UserOperationLib {\n function getSender(\n UserOperation calldata userOp\n ) internal pure returns (address) {\n address data;\n //read sender from userOp, which is first userOp member (saves 800 gas...)\n assembly {\n data := calldataload(userOp)\n }\n return address(uint160(data));\n }\n\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\n // pay above what he signed for.\n function gasPrice(\n UserOperation calldata userOp\n ) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function pack(\n UserOperation calldata userOp\n ) internal pure returns (bytes memory ret) {\n address sender = getSender(userOp);\n uint256 nonce = userOp.nonce;\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\n bytes32 hashCallData = calldataKeccak(userOp.callData);\n uint256 callGasLimit = userOp.callGasLimit;\n uint256 verificationGasLimit = userOp.verificationGasLimit;\n uint256 preVerificationGas = userOp.preVerificationGas;\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\n\n return\n abi.encode(\n sender,\n nonce,\n hashInitCode,\n hashCallData,\n callGasLimit,\n verificationGasLimit,\n preVerificationGas,\n maxFeePerGas,\n maxPriorityFeePerGas,\n hashPaymasterAndData\n );\n }\n\n function hash(\n UserOperation calldata userOp\n ) internal pure returns (bytes32) {\n return keccak256(pack(userOp));\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n}\n" + }, + "contracts/aa-4337/utils/Exec.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.5 <0.9.0;\n\n// solhint-disable no-inline-assembly\n\n/**\n * Utility functions helpful when making different kinds of contract calls in Solidity.\n */\nlibrary Exec {\n function call(\n address to,\n uint256 value,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := call(\n txGas,\n to,\n value,\n add(data, 0x20),\n mload(data),\n 0,\n 0\n )\n }\n }\n\n function staticcall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal view returns (bool success) {\n assembly {\n success := staticcall(txGas, to, add(data, 0x20), mload(data), 0, 0)\n }\n }\n\n function delegateCall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := delegatecall(\n txGas,\n to,\n add(data, 0x20),\n mload(data),\n 0,\n 0\n )\n }\n }\n\n // get returned data from last call or calldelegate\n function getReturnData(\n uint256 maxLen\n ) internal pure returns (bytes memory returnData) {\n assembly {\n let len := returndatasize()\n if gt(len, maxLen) {\n len := maxLen\n }\n let ptr := mload(0x40)\n mstore(0x40, add(ptr, add(len, 0x20)))\n mstore(ptr, len)\n returndatacopy(add(ptr, 0x20), 0, len)\n returnData := ptr\n }\n }\n\n // revert with explicit byte array (probably reverted info from call)\n function revertWithData(bytes memory returnData) internal pure {\n assembly {\n revert(add(returnData, 32), mload(returnData))\n }\n }\n\n function callAndRevert(\n address to,\n bytes memory data,\n uint256 maxLen\n ) internal {\n bool success = call(to, 0, data, gasleft());\n if (!success) {\n revertWithData(getReturnData(maxLen));\n }\n }\n}\n" + }, + "contracts/Barz.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"./libraries/LibDiamond.sol\";\nimport {IBarz} from \"./interfaces/IBarz.sol\";\n\n/**\n * @title Barz\n * @dev A diamond proxy wallet with a modular & upgradeable architecture\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract Barz is IBarz {\n /**\n * @notice Initializes Barz with the given parameters. Barz account is intended to be created from Barz Factory for stable deployment.\n * @dev This method makes a delegate call to account facet and account facet handles the initialization.\n * With modular architecture, Barz encompasses wide spectrum of architecture and logic.\n * The only requirement is account facet to comply with initialize() interface.\n * Barz doesn't include built-in functions and is a full proxy, for maximum extensibility and modularity.\n * @param _accountFacet Address of Account Facet in charge of the Barz initialization\n * @param _verificationFacet Address of Verification Facet for verifying the signature. Could be any signature scheme\n * @param _entryPoint Address of Entry Point contract\n * @param _facetRegistry Address of Facet Registry. Facet Registry is a registry holding trusted facets that could be added to user's wallet\n * @param _defaultFallBack Address of Default FallBack Handler. Middleware contract for more efficient deployment\n * @param _ownerPublicKey Bytes of Owner Public Key using for initialization\n */\n constructor(\n address _accountFacet,\n address _verificationFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallBack,\n bytes memory _ownerPublicKey\n ) payable {\n bytes memory initCall = abi.encodeWithSignature(\n \"initialize(address,address,address,address,bytes)\",\n _verificationFacet,\n _entryPoint,\n _facetRegistry,\n _defaultFallBack,\n _ownerPublicKey\n );\n (bool success, bytes memory result) = _accountFacet.delegatecall(\n initCall\n );\n if (!success || uint256(bytes32(result)) != 1) {\n revert Barz__InitializationFailure();\n }\n }\n\n /**\n * @notice Fallback function for Barz complying with Diamond Standard with customization of adding Default Fallback Handler\n * @dev Find facet for function that is called and execute the function if a facet is found and return any value.\n */\n fallback() external payable {\n LibDiamond.DiamondStorage storage ds;\n bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION;\n // get diamond storage\n assembly {\n ds.slot := position\n }\n // get facet from function selector\n address facet = address(bytes20(ds.facets[msg.sig]));\n if (facet == address(0))\n facet = ds.defaultFallbackHandler.facetAddress(msg.sig);\n require(facet != address(0), \"Barz: Function does not exist\");\n // Execute external function from facet using delegatecall and return any value.\n assembly {\n // copy function selector and any arguments\n calldatacopy(0, 0, calldatasize())\n // execute function call using the facet\n let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)\n // get any return value\n returndatacopy(0, 0, returndatasize())\n // return any return value or error back to the caller\n switch result\n case 0 {\n revert(0, returndatasize())\n }\n default {\n return(0, returndatasize())\n }\n }\n }\n\n /**\n * @notice Receive function to receive native token without data\n */\n receive() external payable {}\n}\n" + }, + "contracts/BarzFactory.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Barz} from \"./Barz.sol\";\nimport {IBarzFactory} from \"./interfaces/IBarzFactory.sol\";\n\n/**\n * @title Barz Factory\n * @dev Contract to easily deploy Barz to a pre-computed address with a single call\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract BarzFactory is IBarzFactory {\n address public immutable accountFacet;\n address public immutable entryPoint;\n address public immutable facetRegistry;\n address public immutable defaultFallback;\n\n /**\n * @notice Sets the initialization data for Barz contract initialization\n * @param _accountFacet Account Facet to be used to create Barz\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\n * @param _facetRegistry Facet Registry to be used to create Barz\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\n */\n constructor(\n address _accountFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallback\n ) {\n accountFacet = _accountFacet;\n entryPoint = _entryPoint;\n facetRegistry = _facetRegistry;\n defaultFallback = _defaultFallback;\n }\n\n /**\n * @notice Creates the Barz with a single call. It creates the Barz contract with the givent verification facet\n * @param _verificationFacet Address of verification facet used for creating the barz account\n * @param _owner Public Key of the owner to initialize barz account\n * @param _salt Salt used for deploying barz with create2\n * @return barz Instance of Barz contract deployed with the given parameters\n */\n function createAccount(\n address _verificationFacet,\n bytes calldata _owner,\n uint256 _salt\n ) external override returns (Barz barz) {\n address addr = getAddress(_verificationFacet, _owner, _salt);\n uint codeSize = addr.code.length;\n if (codeSize > 0) {\n return Barz(payable(addr));\n }\n barz = new Barz{salt: bytes32(_salt)}(\n accountFacet,\n _verificationFacet,\n entryPoint,\n facetRegistry,\n defaultFallback,\n _owner\n );\n emit BarzDeployed(address(barz));\n }\n\n /**\n * @notice Calculates the address of Barz with the given parameters\n * @param _verificationFacet Address of verification facet used for creating the barz account\n * @param _owner Public Key of the owner to initialize barz account\n * @param _salt Salt used for deploying barz with create2\n * @return barzAddress Precalculated Barz address\n */\n function getAddress(\n address _verificationFacet,\n bytes calldata _owner,\n uint256 _salt\n ) public view override returns (address barzAddress) {\n bytes memory bytecode = getBytecode(\n accountFacet,\n _verificationFacet,\n entryPoint,\n facetRegistry,\n defaultFallback,\n _owner\n );\n bytes32 hash = keccak256(\n abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(bytecode)\n )\n );\n barzAddress = address(uint160(uint256(hash)));\n }\n\n /**\n * @notice Returns the bytecode of Barz with the given parameter\n * @param _accountFacet Account Facet to be used to create Barz\n * @param _verificationFacet Verification Facet to be used to create Barz\n * @param _entryPoint Entrypoint contract to be used to create Barz. This uses canonical EntryPoint deployed by EF\n * @param _facetRegistry Facet Registry to be used to create Barz\n * @param _defaultFallback Default Fallback Handler to be used to create Barz\n * @param _ownerPublicKey Public Key of owner to be used to initialize Barz ownership\n * @return barzBytecode Bytecode of Barz\n */\n function getBytecode(\n address _accountFacet,\n address _verificationFacet,\n address _entryPoint,\n address _facetRegistry,\n address _defaultFallback,\n bytes calldata _ownerPublicKey\n ) public pure override returns (bytes memory barzBytecode) {\n bytes memory bytecode = type(Barz).creationCode;\n barzBytecode = abi.encodePacked(\n bytecode,\n abi.encode(\n _accountFacet,\n _verificationFacet,\n _entryPoint,\n _facetRegistry,\n _defaultFallback,\n _ownerPublicKey\n )\n );\n }\n\n /**\n * @notice Returns the creation code of the Barz contract\n * @return creationCode Creation code of Barz\n */\n function getCreationCode()\n public\n pure\n override\n returns (bytes memory creationCode)\n {\n creationCode = type(Barz).creationCode;\n }\n}\n" + }, + "contracts/facets/AccountFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {UserOperation} from \"../aa-4337/interfaces/UserOperation.sol\";\nimport {IEntryPoint} from \"../aa-4337/interfaces/IEntryPoint.sol\";\nimport {BaseAccount} from \"../aa-4337/core/BaseAccount.sol\";\nimport {LibAppStorage, BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {IFacetRegistry} from \"../infrastructure/interfaces/IFacetRegistry.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {IERC1271} from \"../interfaces/ERC/IERC1271.sol\";\nimport {IAccountFacet} from \"./interfaces/IAccountFacet.sol\";\n\n/**\n * @title Account Facet\n * @dev Account module contract that provides the account features and initialization of signer\n * compatible with EIP-1271 & EIP-4337\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract AccountFacet is IAccountFacet, BarzStorage, BaseAccount {\n using ECDSA for bytes32;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceAccountInitialize();\n }\n\n /**\n * @notice Returns the address of EntryPoint contract registered to Barz account\n */\n function entryPoint() public view override returns (IEntryPoint) {\n return s.entryPoint;\n }\n\n /**\n * @notice Initializes the initial storage of the Barz contract.\n * @dev This method can only be called during the initialization or signature migration.\n * If the proxy contract was created without initialization, anyone can call initialize.\n * Barz calls initialize in constructor in an atomic transaction during deployment\n * @param _verificationFacet Facet contract handling the verificationi\n * @param _anEntryPoint Entrypoint contract defined in EIP-4337 handling the flow of UserOp\n * @param _facetRegistry Registry of Facets that hold all facet information\n * @param _defaultFallBackHandler Middleware contract for default facets\n * @param _ownerPublicKey Bytes of owner public key\n */\n function initialize(\n address _verificationFacet,\n address _anEntryPoint,\n address _facetRegistry,\n address _defaultFallBackHandler,\n bytes calldata _ownerPublicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceAccountInitialize();\n s.entryPoint = IEntryPoint(_anEntryPoint);\n s.facetRegistry = IFacetRegistry(_facetRegistry);\n LibDiamond.diamondStorage().defaultFallbackHandler = IDiamondLoupe(\n _defaultFallBackHandler\n );\n\n _cutDiamondAccountFacet(_verificationFacet);\n\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n _ownerPublicKey\n );\n // Every Verification Facet should comply with initializeSigner(bytes)\n // to be compatible with the Barz contract(for initialization)\n (bool success, bytes memory result) = _verificationFacet.delegatecall(\n initCall\n );\n if (!success || uint256(bytes32(result)) != 1) {\n revert AccountFacet__InitializationFailure();\n }\n\n initSuccess = 1;\n emit AccountInitialized(s.entryPoint, _ownerPublicKey);\n }\n\n function _cutDiamondAccountFacet(address _verificationFacet) internal {\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](1);\n\n bytes4 ownerVerificationFuncSelector = IVerificationFacet(\n _verificationFacet\n ).validateOwnerSignatureSelector();\n\n bytes4[] memory verificationFunctionSelectors = new bytes4[](3);\n verificationFunctionSelectors[0] = IERC1271.isValidSignature.selector;\n verificationFunctionSelectors[1] = ownerVerificationFuncSelector;\n verificationFunctionSelectors[2] = IVerificationFacet.owner.selector;\n cut[0] = IDiamondCut.FacetCut({\n facetAddress: _verificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: verificationFunctionSelectors\n });\n\n LibDiamond.diamondCut(cut, address(0), \"\");\n }\n\n /**\n * @notice Calls the destination with inputted calldata and value from EntryPoint\n * @dev This method executes the calldata coming from the EntryPoint.\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\n * @param _dest Address of destination where the call will be forwarded to\n * @param _value Amount of native coin the owner is willing to send(e.g. ETH, BNB)\n * @param _func Bytes of calldata to execute in the destination address\n */\n function execute(\n address _dest,\n uint256 _value,\n bytes calldata _func\n ) external override onlyWhenUnlocked {\n _requireFromEntryPoint();\n address restrictionsFacet = LibDiamond.restrictionsFacet();\n if (restrictionsFacet == address(0)) _call(_dest, _value, _func);\n else _callWithRestrictions(_dest, _value, _func, restrictionsFacet);\n }\n\n /**\n * @notice Batch calls the destination with inputted calldata and value from EntryPoint\n * @dev This method batch executes the calldata coming from the EntryPoint.\n * Barz will make a call to this function for majority of typical execution(e.g. Swap, Token Transfer)\n * @param _dest Array of addresses of destination where the call will be forwarded to\n * @param _value Array of amount of native coin the owner is willing to send(e.g. ETH, BNB)\n * @param _func Array of bytes of calldata to execute in the destination address\n */\n function executeBatch(\n address[] calldata _dest,\n uint256[] calldata _value,\n bytes[] calldata _func\n ) external override onlyWhenUnlocked {\n _requireFromEntryPoint();\n if (_dest.length != _func.length || _dest.length != _value.length)\n revert AccountFacet__InvalidArrayLength();\n address restrictionsFacet = LibDiamond.restrictionsFacet();\n if (restrictionsFacet == address(0)) {\n for (uint256 i; i < _dest.length; ) {\n _call(_dest[i], _value[i], _func[i]);\n unchecked {\n ++i;\n }\n }\n } else {\n for (uint256 i; i < _dest.length; ) {\n _callWithRestrictions(\n _dest[i],\n _value[i],\n _func[i],\n restrictionsFacet\n );\n unchecked {\n ++i;\n }\n }\n }\n }\n\n /**\n * @notice Validates the signature field of UserOperation\n * @dev This method validates if the signature of UserOp is indeed valid by delegating the call to Verification Facet\n * Barz makes a call to the pre-registered Verification Facet address in App Storage\n * @param _userOp UserOperation from owner to be validated\n * @param _userOpHash Hash of UserOperation given from the EntryPoint contract\n */\n function _validateSignature(\n UserOperation calldata _userOp,\n bytes32 _userOpHash\n ) internal override returns (uint256 validationData) {\n // Get Facet with Function Selector\n address facet = LibLoupe.facetAddress(s.validateOwnerSignatureSelector);\n if (facet == address(0))\n revert AccountFacet__NonExistentVerificationFacet();\n\n // Make function call to VerificationFacet\n bytes memory validateCall = abi.encodeWithSelector(\n s.validateOwnerSignatureSelector,\n _userOp,\n _userOpHash\n );\n (bool success, bytes memory result) = facet.delegatecall(validateCall);\n if (!success) revert AccountFacet__CallNotSuccessful();\n validationData = uint256(bytes32(result));\n if (validationData == 0) emit VerificationSuccess(_userOpHash);\n else emit VerificationFailure(_userOpHash);\n }\n\n /**\n * @notice Calls the target with the inputted value and calldata\n * @dev This method is the actual function in Barz that makes a call with an arbitrary owner-given data\n * @param _target Address of the destination contract which the call is getting forwarded to\n * @param _value Amount of Native coin the owner is wanting to make in this call\n * @param _data Calldata the owner is forwarding together in the call e.g. Swap/Token Transfer\n */\n function _call(\n address _target,\n uint256 _value,\n bytes memory _data\n ) internal {\n (bool success, bytes memory result) = _target.call{value: _value}(\n _data\n );\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n }\n\n /**\n * @notice Calls the target with the inputted value and calldata together with restrictions check\n * @dev This method is the actual function in Barz that makes a call with an arbitrary owner-given data\n * @param _target Address of the destination contract which the call is getting forwarded to\n * @param _value Amount of Native coin the owner is wanting to make in this call\n * @param _data Calldata the owner is forwarding together in the call e.g. Swap/Token Transfer\n * @param _restrictionsFacet Address of Facet to validate restrictions\n */\n function _callWithRestrictions(\n address _target,\n uint256 _value,\n bytes memory _data,\n address _restrictionsFacet\n ) internal {\n // NOTE: No restrictions facet, so restriction validation passes\n if (_checkRestrictions(_restrictionsFacet, _target, _value, _data) != 0)\n revert AccountFacet__RestrictionsFailure();\n\n (bool success, bytes memory result) = _target.call{value: _value}(\n _data\n );\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n }\n\n /**\n * @notice Checks restrictions if the restrictions facet exists\n * @dev This method checks if the restrictions facet exists and makes a verification call to an array of restrictions facet\n * @param _facet Address that holds the restrictions logic\n * @param _target Address the call is getting forwarded to\n * @param _value Amount of native coin the call is sending together with the call\n * @param _data Calldata to trigger execution in target address\n */\n function _checkRestrictions(\n address _facet,\n address _target,\n uint256 _value,\n bytes memory _data\n ) internal returns (uint256 result) {\n bytes memory call = abi.encodeWithSignature(\n \"verifyRestrictions(address,address,uint256,bytes)\",\n address(this),\n _target,\n _value,\n _data\n );\n (bool success, bytes memory response) = _facet.delegatecall(call);\n if (!success) revert AccountFacet__RestrictionsFailure();\n result = uint256(bytes32(response));\n }\n}\n" + }, + "contracts/facets/AccountRecoveryFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibFacetStorage, RecoveryStorage, RecoveryConfig, RecoveryApprovalConfig, ApprovalConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {IAccountRecoveryFacet} from \"./interfaces/IAccountRecoveryFacet.sol\";\n\n/**\n * @title Account Recovery Facet\n * @dev Contract that enables recovery of accounts when owner key is unavailable\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract AccountRecoveryFacet is IAccountRecoveryFacet, Modifiers {\n bytes constant UNINIT_CALL =\n abi.encodeWithSignature(\"uninitializeSigner()\");\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Approve recovery of account as guardian\n * @dev This method can only be called by guardian and guardian inputs the public key of the new owner\n * When the threshold(majority of guardians) passes, it automatically executes account recovery\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function approveAccountRecovery(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + _getApprovalValidationPeriod()\n );\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit RecoveryApproved(\n _recoveryPublicKey,\n msg.sender,\n approvalValidUntil\n );\n if (\n getRecoveryApprovalCountWithTimeValidity(recoveryPublicKeyHash) >=\n LibGuardian.majorityOfGuardians()\n ) _executeRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Revoke recovery of account as guardian\n * @dev This method can only be called by guardian and guardian inputs the public key of the new owner\n When the threshold(majority of guardians) passes, it automatically revokes account recovery when recovery is pending\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function revokeAccountRecoveryApproval(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n if (\n !rs\n .isNewOwnerApproved[recoveryPublicKeyHash][msg.sender].isApproved ||\n !(block.timestamp <\n rs\n .isNewOwnerApproved[recoveryPublicKeyHash][msg.sender]\n .validUntil)\n ) revert AccountRecoveryFacet__NonExistentApproval();\n\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(false, 0);\n emit RecoveryApprovalRevoked(_recoveryPublicKey, msg.sender);\n }\n\n /**\n * @notice Executes recovery with signatures or on-chain pre-approvals\n * @dev This method validates the signatures of guardians or checks the on-chain pre-approved calls to check if the threshold passes\n * When the threshold passes, account recovery is executed and revert otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _guardians Array of guardians address that are approving the recovery of Account\n * @param _signatures Array of signature bytes that signed the approval hash\n */\n function executeRecovery(\n bytes calldata _recoveryPublicKey,\n address[] calldata _guardians,\n bytes[] calldata _signatures\n ) external override {\n if (_isRecoveryPending())\n revert AccountRecoveryFacet__RecoveryAlreadyOngoing();\n if (_guardians.length != _signatures.length)\n revert AccountRecoveryFacet__InvalidArrayLength();\n validateNewOwner(_recoveryPublicKey);\n\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"ExecuteRecovery\"\n );\n\n _checkApprover(_guardians);\n _checkDuplicateOnChainApprover(recoveryPublicKeyHash, _guardians);\n\n if (\n _guardians.length +\n getRecoveryApprovalCountWithTimeValidity(\n recoveryPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians()\n ) revert AccountRecoveryFacet__InsufficientGuardians();\n for (uint256 i; i < _guardians.length; ) {\n if (!LibGuardian.isGuardian(_guardians[i]))\n revert AccountRecoveryFacet__InvalidGuardian();\n if (\n !SignatureChecker.isValidSignatureNow(\n _guardians[i],\n recoveryPublicKeyHash,\n _signatures[i]\n )\n ) revert AccountRecoveryFacet__InvalidGuardianSignature();\n unchecked {\n ++i;\n }\n }\n _executeRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Executes recovery of the account. Note that execution and finalization is a different process\n * @dev Executes the recovery and adds recovery data to recovery configuration. Locks the account\n * @param _recoveryPublicKey Public Key of the account for recovery\n */\n function _executeRecovery(bytes memory _recoveryPublicKey) internal {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n unchecked {\n ++rs.nonce;\n }\n uint64 executeAfter = uint64(block.timestamp + _getRecoveryPeriod());\n rs.recoveryConfigs[INNER_STRUCT] = RecoveryConfig(\n _recoveryPublicKey,\n executeAfter // NOTE: Remove guardian Count\n );\n LibAppStorage.setLock(\n block.timestamp + _getLockPeriod(),\n AccountRecoveryFacet.executeRecovery.selector\n );\n emit RecoveryExecuted(_recoveryPublicKey, executeAfter);\n }\n\n /**\n * @notice Finalize recovery after recovery pending period. Recovery pending period can be set by user beforehand in SecurityManager\n * @dev This method finalizes recovery and fully changes the ownership of the account to the newly inputted recovery public key\n */\n function finalizeRecovery() external override {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n if (\n uint64(block.timestamp) <=\n rs.recoveryConfigs[INNER_STRUCT].executeAfter\n ) revert AccountRecoveryFacet__RecoveryPeriodNotOver();\n bytes memory recoveryOwner = rs\n .recoveryConfigs[INNER_STRUCT]\n .recoveryPublicKey;\n\n delete rs.recoveryConfigs[INNER_STRUCT];\n\n LibAppStorage.setLock(0, bytes4(0));\n\n LibAppStorage.initiateSignerMigration();\n address verificationFacet = address(\n bytes20(\n LibDiamond.diamondStorage().facets[\n s.validateOwnerSignatureSelector\n ]\n )\n );\n (bool success, bytes memory result) = verificationFacet.delegatecall(\n UNINIT_CALL\n );\n if (!success) revert AccountRecoveryFacet__CallNotSuccesful();\n uint256 validationData = uint256(bytes32(result));\n if (validationData != 1)\n revert AccountRecoveryFacet__SignerUninitializationFailure();\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n recoveryOwner\n );\n (success, result) = verificationFacet.delegatecall(initCall);\n if (!success) revert AccountRecoveryFacet__CallNotSuccesful();\n validationData = uint256(bytes32(result));\n if (validationData != 1)\n revert AccountRecoveryFacet__SignerInitializationFailure();\n LibAppStorage.finalizeSignerMigration();\n emit RecoveryFinalized(recoveryOwner);\n }\n\n /**\n * @notice Approves the cancellation of recovery\n * @dev This method approves the cancellation of recovery when recovery is still pending - waiting for finalization\n * @param _recoveryPublicKey Bytes of public key which is pending for recovery\n */\n function approveCancelRecovery(\n bytes calldata _recoveryPublicKey\n ) external override onlyGuardian {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n validateNewOwner(_recoveryPublicKey);\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"CancelRecovery\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + _getApprovalValidationPeriod()\n );\n rs.isNewOwnerApproved[recoveryPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit RecoveryCancellationApproved(_recoveryPublicKey, msg.sender);\n if (\n getRecoveryApprovalCountWithTimeValidity(recoveryPublicKeyHash) >=\n LibGuardian.majorityOfGuardians()\n ) {\n _cancelRecovery(_recoveryPublicKey);\n }\n }\n\n /**\n * @notice Hardstops an ongoing recovery\n * @dev This method provides a safety mechanism to protect owners of malicious guardians.\n * Owners can hardstop recovery when an malicious guardians starts the recovery process.\n * @param _signature Signature of the owner that signs the hash to hardstop recovery\n */\n function hardstopRecovery(bytes calldata _signature) external override {\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n \"0\",\n \"HardstopRecovery\"\n );\n if (\n !SignatureChecker.isValidSignatureNow(\n address(this),\n recoveryPublicKeyHash,\n _signature\n )\n ) revert AccountRecoveryFacet__InvalidOwnerSignature();\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n unchecked {\n ++rs.nonce;\n }\n delete rs.recoveryConfigs[INNER_STRUCT];\n LibAppStorage.setLock(0, bytes4(0));\n emit RecoveryHardstopped();\n }\n\n /**\n * @notice Cancels recovery with signatures or on-chain pre-approvals\n * @dev This method validates the signatures of guardians or checks the on-chain pre-approved calls to check if the threshold passes\n * When the threshold passes, account recovery is canceled and revert otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _guardians Array of guardians address that are approving the recovery of Account\n * @param _signatures Array of signature bytes that signed the cancellation approval hash\n */\n function cancelRecovery(\n bytes calldata _recoveryPublicKey,\n address[] calldata _guardians,\n bytes[] calldata _signatures\n ) external override {\n if (_guardians.length != _signatures.length)\n revert AccountRecoveryFacet__InvalidArrayLength();\n validateNewOwner(_recoveryPublicKey);\n\n bytes32 recoveryPublicKeyHash = getApprovalRecoveryKeyHash(\n _recoveryPublicKey,\n \"CancelRecovery\"\n );\n\n _checkApprover(_guardians);\n _checkDuplicateOnChainApprover(recoveryPublicKeyHash, _guardians);\n\n if (\n _guardians.length +\n getRecoveryApprovalCountWithTimeValidity(\n recoveryPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians()\n ) revert AccountRecoveryFacet__InsufficientGuardians();\n for (uint256 i; i < _guardians.length; ) {\n if (!LibGuardian.isGuardian(_guardians[i]))\n revert AccountRecoveryFacet__CallerNotGuardian();\n if (\n !SignatureChecker.isValidSignatureNow(\n _guardians[i],\n recoveryPublicKeyHash,\n _signatures[i]\n )\n ) revert AccountRecoveryFacet__InvalidGuardianSignature();\n unchecked {\n ++i;\n }\n }\n _cancelRecovery(_recoveryPublicKey);\n }\n\n /**\n * @notice Cancel recovery when the recovery is pending. Unlock the account as well\n * @dev This method checks if the recovery is pending and reverts if not pending.\n * It increases the recovery nonce and deletes the recovery information and gets a small portion of gas in return\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function _cancelRecovery(bytes memory _recoveryPublicKey) internal {\n if (!_isRecoveryPending())\n revert AccountRecoveryFacet__NonexistentRecovery();\n LibAppStorage.setLock(0, bytes4(0));\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n unchecked {\n ++rs.nonce;\n }\n delete rs.recoveryConfigs[INNER_STRUCT];\n emit RecoveryCanceled(_recoveryPublicKey);\n }\n\n /**\n * @notice Validates the format of public key to be used for recovery\n * @dev This method checks if the public key format is correct and reverts otherwise\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n */\n function validateNewOwner(bytes memory _recoveryPublicKey) public view {\n if (\n !IVerificationFacet(\n LibLoupe.facetAddress(s.validateOwnerSignatureSelector)\n ).isValidKeyType(_recoveryPublicKey)\n ) revert AccountRecoveryFacet__InvalidRecoveryPublicKey();\n }\n\n /**\n * @notice Checks if recovery is currently pending\n * @return isPending Boolean indicating if recovery is pending\n */\n function _isRecoveryPending() internal view returns (bool isPending) {\n RecoveryStorage storage rs = LibFacetStorage.recoveryStorage();\n isPending = (rs.recoveryConfigs[INNER_STRUCT].executeAfter > 0);\n }\n\n /**\n * @notice Calculate the recovery hash dependent on chain, wallet address, nonce with EIP-191 prefix for safety\n * @dev Returns the keccak256 hash of EIP-191 msg hash packed with public key, salt, nonce, wallet address, etc\n * @param _recoveryPublicKey Bytes of newly recovered public key of the owner\n * @param _saltString Salt string to uniquely identify each recovery hash and for security\n * @return recoveryKeyHash Bytes32 string of the recovery hash\n */\n function getApprovalRecoveryKeyHash(\n bytes memory _recoveryPublicKey,\n string memory _saltString\n ) public view override returns (bytes32 recoveryKeyHash) {\n recoveryKeyHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n _recoveryPublicKey,\n _saltString,\n address(this),\n block.chainid,\n LibFacetStorage.recoveryStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Check the onchain approval of guardians and returns the number of guardians that approved\n * @dev Loop through the guardian addresses and returns the number of guardians that approved this recovery hash\n * @param _recoveryPublicKeyHash Bytes hash of newly recovered public key and recovery value of the account\n * @return approvalCount Number of guardians that approved\n */\n function getRecoveryApprovalCountWithTimeValidity(\n bytes32 _recoveryPublicKeyHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n for (uint256 i; i < guardianLength; ) {\n if (isRecoveryApproved(_recoveryPublicKeyHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Checks if the recovery is approved by the given approver\n * @param _recoveryPublicKeyHash Hash of the public key and configuration for recovery\n * @param _approver Address of approver\n * @return isApproved Bool value if recovery hash is approved\n */\n function isRecoveryApproved(\n bytes32 _recoveryPublicKeyHash,\n address _approver\n ) public view override returns (bool isApproved) {\n RecoveryApprovalConfig storage rs = LibFacetStorage\n .recoveryStorage()\n .recoveryApprovalConfigs[INNER_STRUCT];\n if (\n rs\n .isNewOwnerApproved[_recoveryPublicKeyHash][_approver].isApproved &&\n block.timestamp <\n rs.isNewOwnerApproved[_recoveryPublicKeyHash][_approver].validUntil\n ) {\n isApproved = true;\n }\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _recoveryPublicKeyHash Hash of recovery information\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _recoveryPublicKeyHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isRecoveryApproved(_recoveryPublicKeyHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert AccountRecoveryFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the lock period of this wallet address from security manager\n * @return lockPeriod value of lock period\n */\n function _getLockPeriod() internal view returns (uint256 lockPeriod) {\n lockPeriod = securityManager.lockPeriodOf(address(this));\n if (lockPeriod == 0) revert AccountRecoveryFacet__InvalidLockPeriod();\n }\n\n /**\n * @notice Returns the lock period of this wallet address from security manager\n * @return recoveryPeriod value of recovery period\n */\n function _getRecoveryPeriod()\n internal\n view\n returns (uint256 recoveryPeriod)\n {\n recoveryPeriod = securityManager.recoveryPeriodOf(address(this));\n if (recoveryPeriod == 0)\n revert AccountRecoveryFacet__InvalidRecoveryPeriod();\n }\n\n /**\n * @notice Returns the approval validation period of this wallet address from security manager\n * @return approvalValidationPeriod value of approval validation period\n */\n function _getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod == 0)\n revert AccountRecoveryFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the recovery nonce of this wallet address from security manager\n * @return nonce value of recovery nonce\n */\n function getRecoveryNonce() public view override returns (uint128 nonce) {\n nonce = LibFacetStorage.recoveryStorage().nonce;\n }\n\n /**\n * @notice Returns the recovery information of the pending recovery\n * @return recoveryConfig value struct of pending recovery\n */\n function getPendingRecovery()\n public\n view\n override\n returns (RecoveryConfig memory recoveryConfig)\n {\n recoveryConfig = LibFacetStorage.recoveryStorage().recoveryConfigs[\n INNER_STRUCT\n ];\n }\n}\n" + }, + "contracts/facets/base/DiamondCutFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibGuardian} from \"../../libraries/LibGuardian.sol\";\nimport {ISecurityManager} from \"../../infrastructure/interfaces/ISecurityManager.sol\";\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibFacetStorage, DiamondCutApprovalConfig, ApprovalConfig} from \"../../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"../Modifiers.sol\";\nimport {IDiamondCut} from \"./interfaces/IDiamondCut.sol\";\n\n/**\n * @title DiamondCut Facet\n * @dev Responsible for adding/removing/replace facets in Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DiamondCutFacet is Modifiers, IDiamondCut {\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Updates the flag for the interfaceId\n * @param _interfaceId InterfaceID to update the mapping\n * @param _flag Bool value to update the mapping of the given interface ID\n */\n function updateSupportsInterface(\n bytes4 _interfaceId,\n bool _flag\n ) external override onlyWhenUnlocked {\n LibDiamond.enforceIsSelf();\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId] = _flag;\n emit SupportsInterfaceUpdated(_interfaceId, _flag);\n }\n\n /**\n * @notice Add/replace/remove any number of functions and optionally execute\n * a function with delegatecall when guardians don't exist\n * @param _diamondCut Contains the facet addresses and function selectors\n * @param _init The address of the contract or facet to execute _calldata. It's prohibited in Barz\n */\n function diamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata\n ) external override onlyWhenUnlocked {\n LibDiamond.enforceIsSelf();\n\n _checkFacetCutValidity(_diamondCut);\n // require approval from guardian if guardian exists\n if (0 != LibGuardian.guardianCount())\n revert DiamondCutFacet__InvalidRouteWithGuardian();\n if (address(0) != _init) revert DiamondCutFacet__InvalidInitAddress();\n\n unchecked {\n ++LibFacetStorage.diamondCutStorage().nonce;\n }\n LibDiamond.diamondCut(_diamondCut, address(0), \"\");\n }\n\n /**\n * @notice Add/replace/remove any number of functions and optionally execute\n * a function with delegatecall when guardians exist\n * @param _diamondCut Contains the facet addresses and function selectors\n * @param _approvers Guardian or owner address that approves the diamond cut\n * @param _signatures Signature of Guardians or owner that approves the diamond cut\n */\n function diamondCutWithGuardian(\n FacetCut[] calldata _diamondCut,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n ) external override onlyWhenUnlocked {\n if (_approvers.length != _signatures.length)\n revert DiamondCutFacet__InvalidArrayLength();\n _checkFacetCutValidity(_diamondCut);\n if (0 == LibGuardian.guardianCount())\n revert DiamondCutFacet__InvalidRouteWithGuardian();\n\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(cutHash, _approvers);\n\n bool onChainOwnerApproval = getOwnerCutApprovalWithTimeValidity(\n cutHash\n );\n\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n if (\n _approvers.length +\n getDiamondCutApprovalCountWithTimeValidity(cutHash) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert DiamondCutFacet__InsufficientApprovers();\n\n bool ownerApproved;\n for (uint256 i; i < _approvers.length; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n _approvers[i] != address(this)\n ) revert DiamondCutFacet__InvalidApprover();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert DiamondCutFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n cutHash,\n _signatures[i]\n )\n ) revert DiamondCutFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n if (!ownerApproved && !onChainOwnerApproval)\n revert DiamondCutFacet__LackOfOwnerApproval();\n\n unchecked {\n ++LibFacetStorage.diamondCutStorage().nonce;\n }\n LibDiamond.diamondCut(_diamondCut, address(0), \"\");\n }\n\n /**\n * @notice Approves diamond cut. This can only be called directly from guardian or owner\n * @param _diamondCut Contains the facet addresses and function selectors\n */\n function approveDiamondCut(\n FacetCut[] calldata _diamondCut\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\n if (LibGuardian.guardianCount() == 0)\n revert DiamondCutFacet__InvalidRouteWithoutGuardian();\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n _checkFacetCutValidity(_diamondCut);\n\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(\n true,\n approvalValidUntil\n );\n emit DiamondCutApproved(_diamondCut);\n if (\n (getDiamondCutApprovalCountWithTimeValidity(cutHash) >=\n LibGuardian.majorityOfGuardians()) &&\n getOwnerCutApprovalWithTimeValidity(cutHash)\n ) {\n unchecked {\n ++LibFacetStorage.diamondCutStorage().nonce;\n }\n LibDiamond.diamondCut(_diamondCut, address(0), \"\");\n }\n }\n\n /**\n * @notice Revokes the approval of diamond cut. This can only be called directly from guardian or owner\n * @param _diamondCut Contains the facet addresses and function selectors\n */\n function revokeDiamondCutApproval(\n FacetCut[] calldata _diamondCut\n ) public override onlyGuardianOrOwner onlyWhenUnlocked {\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n bytes32 cutHash = getDiamondCutHash(_diamondCut);\n if (!ds.isDiamondCutApproved[cutHash][msg.sender].isApproved)\n revert DiamondCutFacet__CannotRevokeUnapproved();\n ds.isDiamondCutApproved[cutHash][msg.sender] = ApprovalConfig(false, 0);\n emit DiamondCutApprovalRevoked(_diamondCut);\n }\n\n /**\n * @notice Gets the number of approvals of diamond cut from guardians\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n */\n function getDiamondCutApprovalCountWithTimeValidity(\n bytes32 _diamondCutHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardiansLength = guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n if (isCutApproved(_diamondCutHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n return approvalCount;\n }\n\n /**\n * @notice Returns if the owner has approved the diamond cut\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @return isApprovedByOwner Bool value showing if the owner approved the cut\n */\n function getOwnerCutApprovalWithTimeValidity(\n bytes32 _diamondCutHash\n ) public view override returns (bool isApprovedByOwner) {\n isApprovedByOwner = isCutApproved(_diamondCutHash, address(this));\n }\n\n /**\n * @notice Returns if the given approver has approved the diamond cut\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @param _approver Address of approver\n * @return isApproved Bool value showing if the approver approved the cut\n */\n function isCutApproved(\n bytes32 _diamondCutHash,\n address _approver\n ) public view override returns (bool isApproved) {\n DiamondCutApprovalConfig storage ds = LibFacetStorage\n .diamondCutStorage()\n .diamondCutApprovalConfigs[INNER_STRUCT];\n isApproved = (ds\n .isDiamondCutApproved[_diamondCutHash][_approver].isApproved &&\n block.timestamp <\n ds.isDiamondCutApproved[_diamondCutHash][_approver].validUntil);\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _diamondCutHash Hash of diamondCut information including the facet addresses and function selectors\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _diamondCutHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isCutApproved(_diamondCutHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert DiamondCutFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the diamond cut hash. This function ensures that this hash is safe from replay attack by including\n * salt, address, chainId, and nonce, etc.\n * @param _diamondCut Contains the facet addresses and function selectors\n * @return cutHash Diamond Cut Hash\n */\n function getDiamondCutHash(\n FacetCut[] calldata _diamondCut\n ) public view override returns (bytes32 cutHash) {\n cutHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n keccak256(abi.encode(_diamondCut)),\n address(this),\n block.chainid,\n LibFacetStorage.diamondCutStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Returns the approval validation Period\n * @dev This method fetches the validation period from the security manager\n * @return approvalValidationPeriod Approval validation period of Barz contract fetched from security manager\n */\n function getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod <= 0)\n revert DiamondCutFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the diamond cut nonce of this wallet\n * @dev This method fetches the nonce from diamond cut storage\n * @return cutNonce Nonce of diamond cut to protect from reply attacks\n */\n function getDiamondCutNonce()\n public\n view\n override\n returns (uint128 cutNonce)\n {\n cutNonce = LibFacetStorage.diamondCutStorage().nonce;\n }\n}\n" + }, + "contracts/facets/base/DiamondLoupeFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {IERC165} from \"../../interfaces/ERC/IERC165.sol\";\nimport {IERC1271} from \"../../interfaces/ERC/IERC1271.sol\";\nimport {IERC677Receiver} from \"../../interfaces/ERC/IERC677Receiver.sol\";\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC1155Receiver} from \"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\";\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../../libraries/LibLoupe.sol\";\nimport {LibUtils} from \"../../libraries/LibUtils.sol\";\nimport {IDiamondCut} from \"../../facets/base/interfaces/IDiamondCut.sol\";\nimport {IStorageLoupe} from \"./interfaces/IStorageLoupe.sol\";\nimport {IDiamondLoupe} from \"./interfaces/IDiamondLoupe.sol\";\n\n/**\n * @title DiamondLoupe Facet\n * @dev DiamondLoupe contract compatible with EIP-2535\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DiamondLoupeFacet is IDiamondLoupe, IStorageLoupe, IERC165 {\n // Diamond Loupe Functions\n ////////////////////////////////////////////////////////////////////\n /// These functions are expected to be called frequently by tools off-chain.\n\n /**\n * @notice Gets all facets and their selectors.\n * @dev Barz uses a special architecture called default fallback handler. Default Fallback handler is used as a middleware\n * that holds the mapping of facet function selector and facet address that Barz uses. This helps Barz to reduce\n * significant amount of gas during the initialization process.\n * Hence, this method aggregates both the facet information from DefaulFallbackHandler and in diamond storage and shows the data to users.\n * @return facets_ Facet\n */\n function facets() public view override returns (Facet[] memory facets_) {\n Facet[] memory defaultFacet = LibDiamond\n .diamondStorage()\n .defaultFallbackHandler\n .facets();\n Facet[] memory _facets = LibLoupe.facets();\n uint256 numFacets = _facets.length;\n bytes4[] memory keys;\n address[] memory values;\n for (uint256 i; i < numFacets; ) {\n uint256 selectorsLength = _facets[i].functionSelectors.length;\n for (uint256 j; j < selectorsLength; ) {\n (keys, values) = LibUtils.setValue(\n keys,\n values,\n _facets[i].functionSelectors[j],\n _facets[i].facetAddress\n );\n unchecked {\n ++j;\n }\n }\n unchecked {\n ++i;\n }\n }\n {\n bool iIncrement;\n for (uint256 i; i < defaultFacet.length; ) {\n bool jIncrement;\n for (\n uint256 j;\n j < defaultFacet[i].functionSelectors.length;\n\n ) {\n if (\n LibUtils.getValue(\n keys,\n values,\n defaultFacet[i].functionSelectors[j]\n ) != address(0)\n ) {\n if (defaultFacet[i].functionSelectors.length == 1) {\n defaultFacet = LibUtils.removeFacetElement(\n defaultFacet,\n i\n );\n iIncrement = true;\n break;\n }\n defaultFacet[i].functionSelectors = LibUtils\n .removeElement(\n defaultFacet[i].functionSelectors,\n j\n );\n jIncrement = true;\n }\n if (!jIncrement) {\n unchecked {\n ++j;\n }\n } else {\n jIncrement = false;\n }\n }\n if (!iIncrement) {\n unchecked {\n ++i;\n }\n } else {\n iIncrement = false;\n }\n }\n }\n {\n uint256 facetLength = numFacets + defaultFacet.length;\n facets_ = new Facet[](facetLength);\n uint256 defaultFacetIndex;\n for (uint256 i; i < facetLength; ) {\n if (i < numFacets) {\n facets_[i] = _facets[i];\n bool jIncrementor;\n for (uint256 j; j < defaultFacet.length; ) {\n if (\n facets_[i].facetAddress ==\n defaultFacet[j].facetAddress\n ) {\n facets_[i].functionSelectors = LibUtils.mergeArrays(\n _facets[i].functionSelectors,\n defaultFacet[j].functionSelectors\n );\n defaultFacet = LibUtils.removeFacetElement(\n defaultFacet,\n j\n );\n jIncrementor = true;\n {\n facets_ = LibUtils.removeFacetElement(\n facets_,\n facets_.length - 1\n );\n }\n --facetLength;\n }\n if (!jIncrementor) {\n unchecked {\n ++j;\n }\n } else {\n jIncrementor = false;\n }\n }\n } else {\n facets_[i] = defaultFacet[defaultFacetIndex];\n ++defaultFacetIndex;\n }\n unchecked {\n ++i;\n }\n }\n }\n }\n\n /**\n * @notice Gets all the function selectors provided by a facet.\n * @param _facet The facet address.\n * @return facetFunctionSelectors_\n */\n function facetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n Facet[] memory facet = facets();\n uint256 facetLength = facet.length;\n for (uint256 i; i < facetLength; ) {\n if (facet[i].facetAddress == _facet)\n return facet[i].functionSelectors;\n unchecked {\n ++i;\n }\n }\n return facetFunctionSelectors_;\n }\n\n /**\n * @notice Get all the facet addresses used by Barz.\n * @return facetAddresses_\n */\n function facetAddresses()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n Facet[] memory facet = facets();\n uint256 facetLength = facet.length;\n facetAddresses_ = new address[](facetLength);\n for (uint256 i; i < facetLength; ) {\n facetAddresses_[i] = facet[i].facetAddress;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Gets the facet that supports the given selector.\n * @dev If facet is not found return address(0).\n * @param _functionSelector The function selector.\n * @return facetAddress_ The facet address.\n */\n function facetAddress(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n\n facetAddress_ = address(bytes20(ds.facets[_functionSelector]));\n if (facetAddress_ == address(0)) {\n facetAddress_ = IDiamondLoupe(ds.defaultFallbackHandler)\n .facetAddress(_functionSelector);\n }\n }\n\n /**\n * @notice SupportInterface to be compatible with EIP 165\n * @param _interfaceId Interface ID for detecting the interface\n * @return isSupported Bool value showing if the standard is supported in the contract\n */\n function supportsInterface(\n bytes4 _interfaceId\n ) external view override returns (bool isSupported) {\n isSupported =\n _interfaceId == type(IERC165).interfaceId ||\n _interfaceId == IDiamondCut.diamondCut.selector ||\n _interfaceId == type(IDiamondLoupe).interfaceId ||\n _interfaceId == type(IERC1155Receiver).interfaceId ||\n _interfaceId == type(IERC721Receiver).interfaceId ||\n _interfaceId == type(IERC777Recipient).interfaceId ||\n _interfaceId == IERC1271.isValidSignature.selector ||\n _interfaceId == type(IERC677Receiver).interfaceId ||\n LibDiamond.diamondStorage().supportedInterfaces[_interfaceId];\n }\n\n /**\n * @notice Returns the facet from the diamond storage. This excludes the facets from the default fallback handler\n * @return facets_ Facet information attached directly to diamond storage\n */\n function facetsFromStorage()\n external\n view\n override\n returns (Facet[] memory facets_)\n {\n facets_ = LibLoupe.facets();\n }\n\n /**\n * @notice Returns the facet address attached to the given function selector. This excludes the facets from the default fallback handler\n * @param _functionSelector Function selector to fetch the facet address from diamond storage\n * @return facetAddress_ Facet address mapped with the function selector\n */\n function facetAddressFromStorage(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n facetAddress_ = LibLoupe.facetAddress(_functionSelector);\n }\n\n /**\n * @notice Returns all facet addresses attached directly to diamond storage. This excludes the facets from the default fallback handler\n * @return facetAddresses_ All facet addresses attached directly to diamond storage\n */\n function facetAddressesFromStorage()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n facetAddresses_ = LibLoupe.facetAddresses();\n }\n\n /**\n * @notice Returns function selectors of given facet address attached directly to diamond storage. This excludes the facets from the default fallback handler\n * @param _facet Facet address to fetch the facet function selectors from diamond storage\n * @return facetFunctionSelectors_ Facet function selectors of the given facet address\n */\n function facetFunctionSelectorsFromStorage(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n facetFunctionSelectors_ = LibLoupe.facetFunctionSelectors(_facet);\n }\n}\n" + }, + "contracts/facets/base/interfaces/IDiamondCut.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title DiamondCut Facet Interface\n * @dev Interface for DiamondCut Facet responsible for adding/removing/replace facets in Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IDiamondCut {\n error DiamondCutFacet__InvalidRouteWithGuardian();\n error DiamondCutFacet__InvalidRouteWithoutGuardian();\n error DiamondCutFacet__InvalidArrayLength();\n error DiamondCutFacet__InsufficientApprovers();\n error DiamondCutFacet__InvalidApprover();\n error DiamondCutFacet__InvalidApproverSignature();\n error DiamondCutFacet__InvalidApprovalValidationPeriod();\n error DiamondCutFacet__CannotRevokeUnapproved();\n error DiamondCutFacet__LackOfOwnerApproval();\n error DiamondCutFacet__OwnerAlreadyApproved();\n error DiamondCutFacet__DuplicateApproval();\n error DiamondCutFacet__InvalidInitAddress();\n\n event DiamondCutApproved(FacetCut[] diamondCut);\n event DiamondCutApprovalRevoked(FacetCut[] diamondCut);\n\n event SupportsInterfaceUpdated(bytes4 interfaceId, bool _lag);\n\n enum FacetCutAction {\n Add,\n Replace,\n Remove\n }\n // Add=0, Replace=1, Remove=2\n\n struct FacetCut {\n address facetAddress;\n FacetCutAction action;\n bytes4[] functionSelectors;\n }\n\n /// @notice Add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param diamondCut Contains the facet addresses and function selectors\n /// @param init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function diamondCut(\n FacetCut[] calldata diamondCut,\n address init,\n bytes calldata _calldata\n ) external;\n\n function updateSupportsInterface(bytes4 interfaceId, bool flag) external;\n\n function diamondCutWithGuardian(\n FacetCut[] calldata diamondCut,\n address[] calldata approvers,\n bytes[] calldata signatures\n ) external;\n\n function approveDiamondCut(FacetCut[] calldata diamondCut) external;\n\n function revokeDiamondCutApproval(FacetCut[] calldata diamondCut) external;\n\n function getDiamondCutApprovalCountWithTimeValidity(\n bytes32 diamondCutHash\n ) external view returns (uint256);\n\n function getOwnerCutApprovalWithTimeValidity(\n bytes32 diamondCutHash\n ) external view returns (bool);\n\n function isCutApproved(\n bytes32 diamondCutHash,\n address approver\n ) external view returns (bool);\n\n function getDiamondCutHash(\n FacetCut[] calldata diamondCut\n ) external view returns (bytes32);\n\n function getDiamondCutNonce() external view returns (uint128);\n}\n" + }, + "contracts/facets/base/interfaces/IDiamondLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n// A loupe is a small magnifying glass used to look at diamonds.\n// These functions look at diamonds\ninterface IDiamondLoupe {\n /// These functions are expected to be called frequently\n /// by tools.\n\n struct Facet {\n address facetAddress;\n bytes4[] functionSelectors;\n }\n\n /// @notice Gets all facet addresses and their four byte function selectors.\n /// @return facets_ Facet\n function facets() external view returns (Facet[] memory facets_);\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n /// @return facetFunctionSelectors_\n function facetFunctionSelectors(\n address _facet\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses()\n external\n view\n returns (address[] memory facetAddresses_);\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(\n bytes4 _functionSelector\n ) external view returns (address facetAddress_);\n}\n" + }, + "contracts/facets/base/interfaces/IStorageLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"./IDiamondLoupe.sol\";\n\n/**\n * @title LoupeFromStorage Interface\n * @dev Interface contract to function as a loupe facet directly attached to diamond storage of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IStorageLoupe {\n /// These functions are expected to be called frequently\n /// by tools.\n\n /// @notice Gets all facet addresses and their four byte function selectors.\n /// @return facets_ Facet\n function facetsFromStorage()\n external\n view\n returns (IDiamondLoupe.Facet[] memory);\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n function facetFunctionSelectorsFromStorage(\n address _facet\n ) external view returns (bytes4[] memory);\n\n /// @notice Get all the facet addresses used by a diamond.\n function facetAddressesFromStorage()\n external\n view\n returns (address[] memory);\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n function facetAddressFromStorage(\n bytes4 _functionSelector\n ) external view returns (address);\n}\n" + }, + "contracts/facets/GuardianFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibFacetStorage, GuardianStorage, StorageConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IGuardianFacet} from \"./interfaces/IGuardianFacet.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Guardian Facet\n * @dev Contract that enables addition/removal of guardians from Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract GuardianFacet is IGuardianFacet {\n ISecurityManager public immutable securityManager;\n uint8 public constant INNER_STRUCT = 0;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Add guardians to Barz.\n * @dev This method internally calls addGuardian which checks the validity of guardian address and adds\n * as guardian if valid\n * @param _guardians Array of addresses to add as guardian\n */\n function addGuardians(address[] calldata _guardians) external override {\n LibDiamond.enforceIsSelf();\n for (uint256 i; i < _guardians.length; ) {\n addGuardian(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Add a guardian to Barz.\n * @dev This method checks if the function is called by the owner and validates the address of guardian\n * When the validation passes, guardian address is added to the pending state waiting for confirmation\n * @param _guardian Address to add as guardian\n */\n function addGuardian(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (_guardian == address(this))\n revert GuardianFacet__GuardianCannotBeSelf();\n if (isGuardian(_guardian)) revert GuardianFacet__DuplicateGuardian();\n if (_guardian == address(0))\n revert GuardianFacet__ZeroAddressGuardian();\n if (\n keccak256(abi.encodePacked(_guardian)) ==\n keccak256(IVerificationFacet(address(this)).owner())\n ) revert GuardianFacet__OwnerCannotBeGuardian();\n\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n if (\n gs.pending[id] != 0 ||\n block.timestamp <= gs.pending[id] + getSecurityWindow()\n ) revert GuardianFacet__DuplicateGuardianAddition();\n\n uint256 securityPeriod = getAdditionSecurityPeriod();\n gs.pending[id] = block.timestamp + securityPeriod;\n emit GuardianAdditionRequested(\n _guardian,\n block.timestamp + securityPeriod\n );\n }\n\n /**\n * @notice Remove guardians from Barz.\n * @dev This method internally calls removeGuardian which checks the validity of guardian and removes\n * guardian when the request is valid\n * @param _guardians Array of addresses to be removed\n */\n function removeGuardians(address[] calldata _guardians) external override {\n LibDiamond.enforceIsSelf();\n for (uint256 i; i < _guardians.length; ) {\n removeGuardian(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Remove a guardian from Barz.\n * @dev This method validates if the guardian to be removed is a guardian and puts the guardian removal\n * to a pending state waiting to be confirmed.\n * @param _guardian Address of guardian to be removed\n */\n function removeGuardian(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n if (!isGuardian(_guardian)) revert GuardianFacet__NonExistentGuardian();\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n if (\n gs.pending[id] != 0 ||\n block.timestamp <= gs.pending[id] + getSecurityWindow()\n ) revert GuardianFacet__DuplicateGuardianRemoval();\n\n uint256 securityPeriod = getRemovalSecurityPeriod();\n gs.pending[id] = block.timestamp + securityPeriod;\n emit GuardianRemovalRequested(\n _guardian,\n block.timestamp + securityPeriod\n );\n }\n\n /**\n * @notice Confirm addition of guardians\n * @dev This method internally calls confirmGuardianAddition which checks the validity of pending request.\n * Guardians are fully added when they pass the validation. Anyone can call this function.\n * @param _guardians Array of guardian addresses to be added\n */\n function confirmGuardianAdditions(\n address[] calldata _guardians\n ) external override {\n for (uint256 i; i < _guardians.length; ) {\n confirmGuardianAddition(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Confirm addition of a guardian\n * @dev This method checks the validity of pending request.\n * Guardians are fully added when they pass the validation. Anyone can call this function.\n * @param _guardian Guardian address to be added\n */\n function confirmGuardianAddition(address _guardian) public override {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingAddition();\n if (gs.pending[id] >= block.timestamp)\n revert GuardianFacet__PendingAdditionNotOver();\n if (block.timestamp >= gs.pending[id] + getSecurityWindow())\n revert GuardianFacet__PendingAdditionExpired();\n\n _addGuardian(_guardian);\n\n delete gs.pending[id];\n emit GuardianAdded(_guardian);\n }\n\n /**\n * @notice Confirm removal of guardians\n * @dev This method internally calls confirmGuardianRemoval to check the validity guardian removal confirmation.\n * Guardians are fully removed when they pass the validation. Anyone can call this function.\n * @param _guardians Array of guardian addresses to be removed\n */\n function confirmGuardianRemovals(\n address[] calldata _guardians\n ) external override {\n for (uint256 i; i < _guardians.length; ) {\n confirmGuardianRemoval(_guardians[i]);\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Confirm removal of a guardian\n * @dev This method checks the validity guardian removal confirmation.\n * Guardian is fully removed when they pass the validation. Anyone can call this function.\n * @param _guardian Guardian address to be removed\n */\n function confirmGuardianRemoval(address _guardian) public override {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingRemoval();\n if (gs.pending[id] >= block.timestamp)\n revert GuardianFacet__PendingRemovalNotOver();\n if (block.timestamp >= gs.pending[id] + getSecurityWindow())\n revert GuardianFacet__PendingAdditionExpired();\n\n _removeGuardian(_guardian);\n delete gs.pending[id];\n emit GuardianRemoved(_guardian);\n }\n\n /**\n * @notice Cancel pending guardian addition\n * @dev This method checks if the previous request for guardian request exists.\n * It reverts if previous request is not pending and cancels the addition otherwise.\n * @param _guardian Guardian address to be canceled from addition\n */\n function cancelGuardianAddition(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingAddition();\n delete gs.pending[id];\n emit GuardianAdditionCancelled(_guardian);\n }\n\n /**\n * @notice Cancel pending guardian removal\n * @dev This method checks if the previous request for guardian request exists.\n * It reverts if previous request is not pending and cancels the removal otherwise.\n * @param _guardian Guardian address to be canceled from removal\n */\n function cancelGuardianRemoval(address _guardian) public override {\n LibDiamond.enforceIsSelf();\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n if (gs.pending[id] == 0) revert GuardianFacet__UnknownPendingRemoval();\n delete gs.pending[id];\n emit GuardianRemovalCancelled(_guardian);\n }\n\n /**\n * @notice Get the addition security period of current account from security manager\n * @dev This method returns the uint value if addition security period\n * @return additionSecurityPeriod Uint256 value of addition security period\n */\n function getAdditionSecurityPeriod()\n public\n view\n override\n returns (uint256 additionSecurityPeriod)\n {\n additionSecurityPeriod = securityManager.additionSecurityPeriodOf(\n address(this)\n );\n if (additionSecurityPeriod == 0)\n revert GuardianFacet__InvalidAdditionSecurityPeriod();\n }\n\n /**\n * @notice Get the removal security period of current account from security manager\n * @dev This method returns the uint value if removal security period\n * @return removalSecurityPeriod Uint256 value of removal security period\n */\n function getRemovalSecurityPeriod()\n public\n view\n override\n returns (uint256 removalSecurityPeriod)\n {\n removalSecurityPeriod = securityManager.removalSecurityPeriodOf(\n address(this)\n );\n if (removalSecurityPeriod == 0)\n revert GuardianFacet__InvalidRemovalSecurityPeriod();\n }\n\n /**\n * @notice Get the security window of current account from security manager\n * @dev This method returns the uint value if security window\n * @return securityWindow Uint256 value of removal security period\n */\n function getSecurityWindow()\n public\n view\n override\n returns (uint256 securityWindow)\n {\n securityWindow = securityManager.securityWindowOf(address(this));\n if (securityWindow == 0) revert GuardianFacet__InvalidSecurityWindow();\n }\n\n /**\n * @notice Checks if the addition of the given guardian address is pending\n * @dev This method returns the bool value of whether the guardian address is pending addition\n * @return isPending Bool value of representing the pending of guardian addition\n */\n function isAdditionPending(\n address _guardian\n ) public view override returns (bool isPending) {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"ADD\"));\n isPending = _isPending(id);\n }\n\n /**\n * @notice Checks if the removal of the given guardian address is pending\n * @dev This method returns the bool value of whether the guardian address is pending removal\n * @return isPending Bool value of representing the pending of guardian removal\n */\n function isRemovalPending(\n address _guardian\n ) public view override returns (bool isPending) {\n bytes32 id = keccak256(abi.encodePacked(_guardian, \"REMOVE\"));\n isPending = _isPending(id);\n }\n\n /**\n * @notice Checks if the given hash is pending\n * @dev This method returns the bool value whether the hash is pending\n * @return isPending Bool value of representing the pending of guardian operation\n */\n function _isPending(\n bytes32 _idHash\n ) internal view returns (bool isPending) {\n GuardianStorage storage gs = LibFacetStorage.guardianStorage();\n isPending = ((gs.pending[_idHash] > 0 &&\n gs.pending[_idHash] < block.timestamp) &&\n block.timestamp < gs.pending[_idHash] + getSecurityWindow());\n }\n\n /**\n * @notice Adds guardian to storage config. This is called when guardian is fully added.\n * @dev This method add guardian address and config information to Facet Storage dedicated for guardian\n * When this function is called, guardian is fully added to this Barz Smart Account\n * @param _guardian Address of guardian to be added\n */\n function _addGuardian(address _guardian) internal {\n if (!isAdditionPending(_guardian))\n revert GuardianFacet__InvalidGuardianAddition();\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n if (config.info[_guardian].exists)\n revert GuardianFacet__AlreadyExists();\n\n config.info[_guardian].exists = true;\n config.info[_guardian].index = uint128(config.addresses.length);\n config.addresses.push(_guardian);\n }\n\n /**\n * @notice Removes guardian to storage config. This is called when guardian is fully removed.\n * @dev This method remove guardian address and config information to Facet Storage dedicated for guardian\n * When this function is called, guardian is fully removed from this Barz Smart Account\n * @param _guardian Address of guardian to be removed\n */\n function _removeGuardian(address _guardian) internal {\n if (!isRemovalPending(_guardian))\n revert GuardianFacet__InvalidGuardianRemoval();\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n if (!config.info[_guardian].exists)\n revert GuardianFacet__NonExistentGuardian();\n\n address lastAddress = config.addresses[config.addresses.length - 1];\n if (_guardian != lastAddress) {\n uint128 targetIndex = config.info[_guardian].index;\n config.addresses[targetIndex] = lastAddress;\n config.info[lastAddress].index = targetIndex;\n }\n config.addresses.pop();\n delete config.info[_guardian];\n\n emit GuardianRemoved(_guardian);\n }\n\n /**\n * @notice Reads guardian storage and fetches the addresses into an array from the storage\n * @dev This method fetches the guardian storage and returns the list of guardian addresses\n * @return addresses Array of addresses comprised of guardian\n */\n function getGuardians()\n public\n view\n override\n returns (address[] memory addresses)\n {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n uint256 addressesLen = config.addresses.length;\n addresses = new address[](addressesLen);\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the number of majority of guardians\n * @return majorityOfGuardians_ Number of majority of guardians e.g., 2 if 3 guardians / 3 if 5 guardians\n */\n function majorityOfGuardians()\n public\n view\n override\n returns (uint256 majorityOfGuardians_)\n {\n majorityOfGuardians_ = LibGuardian.majorityOfGuardians();\n }\n\n /**\n * @notice Reads guardian storage and fetches the addresses into an array from the storage\n * @dev This method fetches the guardian storage and returns the list of guardian addresses\n * @return guardianNumber Array of guardians in the account\n */\n function guardianCount()\n public\n view\n override\n returns (uint256 guardianNumber)\n {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n guardianNumber = config.addresses.length;\n }\n\n /**\n * @notice Reads guardian storage and checks if the given address is a guardian\n * @return isGuardian_ Bool value representing if the given address is guardian\n */\n function isGuardian(\n address _guardian\n ) public view override returns (bool isGuardian_) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[INNER_STRUCT];\n isGuardian_ = config.info[_guardian].exists;\n }\n\n /**\n * @notice Checks if the guardian number is zero and returns of guardian facet is okay to be removed\n * @return isRemovable Bool value representing if guardian facet is removable\n */\n function isGuardianFacetRemovable()\n external\n view\n override\n returns (bool isRemovable)\n {\n isRemovable = (0 == guardianCount());\n }\n}\n" + }, + "contracts/facets/interfaces/IAccountFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IEntryPoint} from \"../../aa-4337/interfaces/IEntryPoint.sol\";\n\n/**\n * @title Account Facet Interface\n * @dev Interface of module contract that provides the account features and init/unitialization of signer\n * compatible with EIP-1271 & EIP-4337\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IAccountFacet {\n event AccountInitialized(\n IEntryPoint indexed entryPoint,\n bytes indexed ownerPublicKey\n );\n // NOTE: Added Below Event\n event VerificationSuccess(bytes32);\n event VerificationFailure(bytes32);\n\n error AccountFacet__InitializationFailure();\n error AccountFacet__RestrictionsFailure();\n error AccountFacet__NonExistentVerificationFacet();\n error AccountFacet__CallNotSuccessful();\n error AccountFacet__InvalidArrayLength();\n\n function initialize(\n address verificationFacet,\n address anEntryPoint,\n address facetRegistry,\n address _defaultFallBack,\n bytes calldata _ownerPublicKey\n ) external returns (uint256);\n\n function execute(address dest, uint256 value, bytes calldata func) external;\n\n function executeBatch(\n address[] calldata dest,\n uint256[] calldata value,\n bytes[] calldata func\n ) external;\n}\n" + }, + "contracts/facets/interfaces/IAccountRecoveryFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {RecoveryConfig} from \"../../libraries/LibFacetStorage.sol\";\n\n/**\n * @title Account Recovery Facet Interface\n * @dev Interface of contract that enables recovery of accounts when owner key is unavailable\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IAccountRecoveryFacet {\n event RecoveryExecuted(\n bytes indexed recoveryPublicKey,\n uint64 executeAfter\n );\n event RecoveryFinalized(bytes indexed recoveryPublicKey);\n event RecoveryCanceled(bytes indexed recoveryPublicKey);\n event RecoveryApproved(\n bytes indexed recoveryPublicKey,\n address indexed guardian,\n uint64 validUntil\n );\n event RecoveryApprovalRevoked(\n bytes indexed recoveryPublicKey,\n address indexed guardian\n );\n event RecoveryCancellationApproved(\n bytes indexed recoveryPublicKey,\n address indexed guardian\n );\n event RecoveryHardstopped();\n\n error AccountRecoveryFacet__CallerNotGuardian();\n error AccountRecoveryFacet__InvalidRecoveryPublicKey();\n error AccountRecoveryFacet__SignerInitializationFailure();\n error AccountRecoveryFacet__SignerUninitializationFailure();\n error AccountRecoveryFacet__InvalidArrayLength();\n error AccountRecoveryFacet__InsufficientGuardians();\n error AccountRecoveryFacet__RecoveryAlreadyOngoing();\n error AccountRecoveryFacet__NonexistentRecovery();\n error AccountRecoveryFacet__NonExistentApproval();\n error AccountRecoveryFacet__RecoveryPeriodNotOver();\n error AccountRecoveryFacet__InvalidLockPeriod();\n error AccountRecoveryFacet__InvalidRecoveryPeriod();\n error AccountRecoveryFacet__InvalidApprovalValidationPeriod();\n error AccountRecoveryFacet__InvalidGuardian();\n error AccountRecoveryFacet__InvalidGuardianSignature();\n error AccountRecoveryFacet__InvalidOwnerSignature();\n error AccountRecoveryFacet__CallNotSuccesful();\n error AccountRecoveryFacet__DuplicateApproval();\n\n function approveAccountRecovery(bytes calldata recoveryPublicKey) external;\n\n function revokeAccountRecoveryApproval(\n bytes calldata recoveryPublicKey\n ) external;\n\n function executeRecovery(\n bytes calldata recoveryPublicKey,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function finalizeRecovery() external;\n\n function approveCancelRecovery(bytes calldata recoveryPublicKey) external;\n\n function cancelRecovery(\n bytes calldata recoveryPublicKey,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function hardstopRecovery(bytes calldata signature) external;\n\n function getApprovalRecoveryKeyHash(\n bytes memory recoveryPublicKey,\n string memory saltString\n ) external view returns (bytes32);\n\n function getRecoveryApprovalCountWithTimeValidity(\n bytes32 recoveryPublicKeyHash\n ) external view returns (uint256);\n\n function isRecoveryApproved(\n bytes32 recoveryPublicKeyHash,\n address approver\n ) external view returns (bool);\n\n function getRecoveryNonce() external view returns (uint128);\n\n function getPendingRecovery() external view returns (RecoveryConfig memory);\n}\n" + }, + "contracts/facets/interfaces/IGuardianFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Guardian Facet Interface\n * @dev Interface of guaridna contract that enables addition/removal of guardians from Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IGuardianFacet {\n event GuardianAdditionRequested(\n address indexed guardian,\n uint256 executeAfter\n );\n event GuardianRemovalRequested(\n address indexed guardian,\n uint256 executeAfter\n );\n event GuardianAdditionCancelled(address indexed guardian);\n event GuardianRemovalCancelled(address indexed guardian);\n event GuardianAdded(address indexed guardian);\n event GuardianRemoved(address indexed guardian);\n\n error GuardianFacet__GuardianCannotBeSelf();\n error GuardianFacet__DuplicateGuardian();\n error GuardianFacet__OwnerCannotBeGuardian();\n error GuardianFacet__DuplicateGuardianAddition();\n error GuardianFacet__DuplicateGuardianRemoval();\n error GuardianFacet__UnknownPendingAddition();\n error GuardianFacet__PendingAdditionNotOver();\n error GuardianFacet__UnknownPendingRemoval();\n error GuardianFacet__PendingRemovalNotOver();\n error GuardianFacet__PendingAdditionExpired();\n error GuardianFacet__InvalidAdditionSecurityPeriod();\n error GuardianFacet__InvalidRemovalSecurityPeriod();\n error GuardianFacet__InvalidSecurityWindow();\n error GuardianFacet__NonExistentGuardian();\n error GuardianFacet__AlreadyExists();\n error GuardianFacet__InvalidGuardianAddition();\n error GuardianFacet__InvalidGuardianRemoval();\n error GuardianFacet__ZeroAddressGuardian();\n\n function addGuardian(address guardian) external;\n\n function addGuardians(address[] calldata guardians) external;\n\n function removeGuardian(address guardian) external;\n\n function removeGuardians(address[] calldata guardians) external;\n\n function confirmGuardianAddition(address guardian) external;\n\n function confirmGuardianAdditions(address[] calldata guardian) external;\n\n function confirmGuardianRemoval(address guardian) external;\n\n function confirmGuardianRemovals(address[] calldata guardian) external;\n\n function cancelGuardianAddition(address guardian) external;\n\n function cancelGuardianRemoval(address guardian) external;\n\n function isGuardian(address guardian) external view returns (bool);\n\n function isAdditionPending(address guardian) external view returns (bool);\n\n function isRemovalPending(address guardian) external view returns (bool);\n\n function isGuardianFacetRemovable() external view returns (bool);\n\n function getAdditionSecurityPeriod() external view returns (uint256);\n\n function getRemovalSecurityPeriod() external view returns (uint256);\n\n function getSecurityWindow() external view returns (uint256);\n\n function getGuardians() external view returns (address[] memory);\n\n function majorityOfGuardians() external view returns (uint256);\n\n function guardianCount() external view returns (uint256);\n}\n" + }, + "contracts/facets/interfaces/ILockFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Lock} from \"../../libraries/LibAppStorage.sol\";\n\n/**\n * @title Lock Facet Interface\n * @dev Interface of Lock contract that enables full lock/unlock of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface ILockFacet {\n event Locked(uint64 releaseAfter);\n event Unlocked();\n\n error LockFacet__InvalidRecoveryPeriod();\n error LockFacet__CannotUnlock();\n error LockFacet__InvalidSignature();\n error LockFacet__InvalidApprover();\n\n function lock() external;\n\n function unlock(address approver, bytes calldata signature) external;\n\n function getLockPeriod() external view returns (uint256);\n\n function isLocked() external view returns (bool);\n\n function getUnlockHash() external view returns (bytes32);\n\n function lockNonce() external view returns (uint128);\n\n function getPendingLock() external view returns (Lock memory);\n}\n" + }, + "contracts/facets/interfaces/IMultiSigFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Multi-sig facet Interface\n * @dev Interface of Multi-signature Facet with custom threshold.\n Wallet that adds this facet becomes a multi-sig wallet\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IMultiSigFacet {\n event ThresholdChanged(uint256 threshold);\n event OwnerAdded(address indexed newOwner);\n event OwnerRemoved(address indexed prevOwner);\n event HashApproved(bytes32 hashToApprove, address indexed owner);\n\n error MultiSigFacet__InvalidThreshold();\n error MultisigFacet__InvalidOwnerCount();\n error MultiSigFacet__InvalidRoute();\n error MultiSigFacet__InsufficientSignerLength();\n error MultiSigFacet__InvalidInitData();\n error MultiSigFacet__InvalidOwnerAddress();\n error MultiSigFacet__InvalidOwnerPair();\n error MultiSigFacet__InvalidSignatureLength();\n error MultiSigFacet__InvalidSignatureType();\n error MultiSigFacet__DuplicateOwner();\n error MultiSigFacet__OnlyOwner();\n\n function checkSignatures(\n bytes32 _dataHash,\n bytes calldata _signatures,\n uint256 _threshold\n ) external view returns (uint256);\n\n function splitSignatures(\n bytes calldata _signatures,\n uint256 _nextOffset\n )\n external\n pure\n returns (\n address owner,\n bytes memory signature,\n uint256 signatureType,\n uint256 nextOffset\n );\n\n function approveHash(bytes32 hashToApprove) external;\n\n function addOwner(address newOwner, uint256 threshold) external;\n\n function removeOwner(\n address prevOwner,\n address removedOwner,\n uint256 threshold\n ) external;\n\n function swapOwner(\n address prevOwner,\n address oldOwner,\n address newOwner\n ) external;\n\n function changeThreshold(uint256 _threshold) external;\n\n function isOwner(address owner) external view returns (bool);\n\n function getThreshold() external view returns (uint256);\n\n function getOwners() external view returns (address[] memory);\n}\n" + }, + "contracts/facets/interfaces/IRestrictionsFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Restrictions Facet Interface\n * @dev Interface of Restrictions contract that enables modular restrictions in Barz\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IRestrictionsFacet {\n event RestrictionAdded(address indexed restriction);\n event RestrictionRemoved(address indexed restriction);\n\n error RestrictionsFacet__EmptyRestrictionsList();\n error RestrictionsFacet__RestrictionNotFound();\n error RestrictionsFacet__RestrictionAlreadyExists();\n error RestrictionsFacet__ZeroAddressRestrictions();\n error RestrictionsFacet__ZeroAddressRestrictionsFacet();\n error RestrictionsFacet__RemainingRestrictionsCantBeEmpty();\n\n function initializeRestrictions(\n address[] memory _restrictions\n ) external returns (uint256);\n\n function uninitializeRestrictions() external returns (uint256);\n\n function getRestrictions() external view returns (address[] memory);\n\n function addRestriction(address restriction) external;\n\n function removeRestriction(address restriction) external;\n\n function verifyRestrictions(\n address from,\n address to,\n uint256 value,\n bytes calldata _calldata\n ) external returns (uint256);\n}\n" + }, + "contracts/facets/interfaces/ISignatureMigrationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureMigrationConfig} from \"../../libraries/LibFacetStorage.sol\";\n\n/**\n * @title Signature Migration Facet Interface\n * @dev Interface of Signature Migration contract for migrating user signature scheme to a new scheme user sets\n * Which could include\n * - ECDSA on Secp256K1 Curve\n * - ECDSA on Secp256R1 Curve\n * - BLS, Schnorr, etc\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface ISignatureMigrationFacet {\n event SignatureSchemeMigration(\n address indexed prevVerificationFacet,\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n event SignatureMigrationApproved(\n bytes newPublicKey,\n address indexed newVerificationFacet,\n bytes4[] verificationFuncSelectors,\n address indexed guardian,\n uint128 approvalValidUntil\n );\n event SignatureMigrationApprovalRevoked(\n bytes newPublicKey,\n address indexed newVerificationFacet,\n bytes4[] verificationFuncSelectors,\n address indexed guardian\n );\n event SignatureMigrationExecuted(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors,\n uint128 migrateAfter\n );\n event SignatureMigrationCanceled(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n event SignatureMigrationCancellationApproved(\n address indexed newVerificationFacet,\n bytes newOwner,\n bytes4[] verificationFuncSelectors\n );\n\n error SignatureMigrationFacet__SignerUninitializationFailure();\n error SignatureMigrationFacet__SignerInitializationFailure();\n error SignatureMigrationFacet__InvalidRouteWithGuardian();\n error SignatureMigrationFacet__InvalidKeyType();\n error SignatureMigrationFacet__InsufficientApprovers();\n error SignatureMigrationFacet__InvalidApproverSignature();\n error SignatureMigrationFacet__InvalidGuardian();\n error SignatureMigrationFacet__NonExistentApprover();\n error SignatureMigrationFacet__InvalidMigrationPeriod();\n error SignatureMigrationFacet__NonexistentMigration();\n error SignatureMigrationFacet__MigrationPeriodNotOver();\n error SignatureMigrationFacet__InvalidArrayLength();\n error SignatureMigrationFacet__InvalidApprovalValidationPeriod();\n error SignatureMigrationFacet__CannotRevokeUnapproved();\n error SignatureMigrationFacet__LackOfOwnerApproval();\n error SignatureMigrationFacet__OwnerAlreadyApproved();\n error SignatureMigrationFacet__NonExistentVerificationFacet();\n error SignatureMigrationFacet__DuplicateApproval();\n\n function migrateSignatureScheme(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function migrateSignatureSchemeWithGuardian(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors,\n address[] calldata approvers,\n bytes[] calldata signatures\n ) external;\n\n function approveSignatureSchemeMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function revokeSignatureMigrationApproval(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function finalizeSignatureMigration() external;\n\n function approveCancelSignatureMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors\n ) external;\n\n function cancelSignatureMigration(\n address newVerificationFacet,\n bytes calldata newPublicKey,\n bytes4[] calldata newVerificationFuncSelectors,\n address[] calldata guardians,\n bytes[] calldata signatures\n ) external;\n\n function getApprovalMigrationKeyHash(\n bytes memory recoveryPublicKey,\n address newVerificationFacet,\n bytes4[] memory newVerificationFuncSelectors,\n string memory saltString\n ) external view returns (bytes32);\n\n function getMigrationOwnerApprovalWithTimeValidity(\n bytes32 publicKeyHash\n ) external view returns (bool);\n\n function getMigrationApprovalCountWithTimeValidity(\n bytes32 publicKeyHash\n ) external view returns (uint256);\n\n function isMigrationApproved(\n bytes32 migrationPublicKeyHash,\n address approver\n ) external view returns (bool);\n\n function getMigrationNonce() external view returns (uint128);\n\n function isMigrationPending() external view returns (bool);\n\n function getPendingMigration()\n external\n view\n returns (SignatureMigrationConfig memory);\n}\n" + }, + "contracts/facets/interfaces/IVerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {UserOperation} from \"../../aa-4337/interfaces/UserOperation.sol\";\n\n/**\n * @title Verification Facet Interface\n * @dev Implements logic for user ops signature verification\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface IVerificationFacet {\n event SignerInitialized(bytes);\n event SignerUninitialized();\n\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n error VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n error VerificationFacet__InitializationFailure();\n error VerificationFacet__InvalidFacetMapping();\n\n function initializeSigner(bytes memory) external returns (uint256);\n\n function uninitializeSigner() external returns (uint256);\n\n function validateOwnerSignatureSelector() external view returns (bytes4);\n\n function owner() external view returns (bytes memory);\n\n function isValidKeyType(bytes calldata) external view returns (bool);\n\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) external view returns (uint256);\n}\n" + }, + "contracts/facets/LockFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage, Lock} from \"../libraries/LibAppStorage.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibFacetStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {ILockFacet} from \"./interfaces/ILockFacet.sol\";\n\n/**\n * @title Lock Facet\n * @dev Contract that enables full lock/unlock of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract LockFacet is ILockFacet, Modifiers {\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n /**\n * @notice Locks the account for the lock period. Lock period is defined in the security manager and it's customizable\n * This function can only be called when account is unlocked by owner or guardians\n * @dev This method checks the caller and if the account is currently locked and locks the account after fetching the\n * Lock period from the owner.\n */\n function lock() external override onlyGuardianOrOwner onlyWhenUnlocked {\n uint256 unlockTime = block.timestamp + getLockPeriod();\n unchecked {\n ++LibFacetStorage.lockStorage().nonce;\n }\n LibAppStorage.setLock(unlockTime, LockFacet.lock.selector);\n emit Locked(uint64(unlockTime));\n }\n\n /**\n * @notice Locks the account when the account is locked. This function can be called by anyone but must provide the approver address and signature.\n * The approver should be one of the guardians or owner.\n * @dev This method takes the approver address and the signature. After validating the address and the signature, it unlocks the account immediately.\n * Only one of the guardian or owner is required to lock and unlock the account.\n * @param _approver Address of approver approving the unlock of Barz account\n * @param _signature Signature of the approver that signed the msg hash for unlocking the account\n */\n function unlock(\n address _approver,\n bytes calldata _signature\n ) external override onlyWhenLocked {\n if (_approver != address(this) && !LibGuardian.isGuardian(_approver))\n revert LockFacet__InvalidApprover();\n if (\n !SignatureChecker.isValidSignatureNow(\n _approver,\n getUnlockHash(),\n _signature\n )\n ) revert LockFacet__InvalidSignature();\n _unlock();\n }\n\n /**\n * @notice Unlocks the account and increments the lock nonce\n */\n function _unlock() private {\n if (s.locks[INNER_STRUCT].locker != LockFacet.lock.selector)\n revert LockFacet__CannotUnlock();\n unchecked {\n ++LibFacetStorage.lockStorage().nonce;\n }\n LibAppStorage.setLock(0, bytes4(0));\n emit Unlocked();\n }\n\n /**\n * @notice Returns the lock period of current Barz account. Lock period information is held by Security Manager\n * @return lockPeriod Uint value of lock period in seconds\n */\n function getLockPeriod() public view override returns (uint256 lockPeriod) {\n lockPeriod = securityManager.lockPeriodOf(address(this));\n if (lockPeriod == 0) revert LockFacet__InvalidRecoveryPeriod();\n }\n\n /**\n * @notice Returns if the account is locked or not\n * @dev This method fetches the current block timestamp and compares that with release time.\n * After checking the timestamp and release time, it returns if the account is still locked or not.\n * @return isLocked_ Uint value of lock period in seconds\n */\n function isLocked() public view override returns (bool isLocked_) {\n isLocked_ = uint64(block.timestamp) < s.locks[INNER_STRUCT].release;\n }\n\n /**\n * @notice Calculates the unlock hash and returns the unlock hash safe from signature reply attack\n * @dev This method calculates the unlock hash with EIP-191 prefix, wallet address, chainID, and nonce\n * It packs the result and packs them and hashes it.\n * @return unlockHash Bytes32 unlock hash\n */\n function getUnlockHash() public view override returns (bytes32 unlockHash) {\n unlockHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n \"Unlock\",\n address(this),\n block.chainid,\n lockNonce()\n )\n )\n )\n );\n }\n\n /**\n * @notice Returns lock nonce of account. Reads nonce from lock storage within facet storage\n * @return lockNonce_ Uint128 value of lock nonce. This is incremented whenever the account is lock/unlocked\n */\n function lockNonce() public view override returns (uint128 lockNonce_) {\n lockNonce_ = LibFacetStorage.lockStorage().nonce;\n }\n\n /**\n * @notice Returns the overall information of current lock\n * @return pendingLock Struct value including all information of pending lock\n */\n function getPendingLock()\n public\n view\n override\n returns (Lock memory pendingLock)\n {\n pendingLock = s.locks[INNER_STRUCT];\n }\n}\n" + }, + "contracts/facets/Modifiers.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\n\n/**\n * @title Modifiers\n * @dev Responsible for providing modifiers/util functions to Facet contracts\n * @author David Yongjun Kim (@Powerstream3604)\n */\nabstract contract Modifiers is BarzStorage {\n uint8 constant INNER_STRUCT = 0;\n\n error CallerNotGuardian();\n error CallerNotGuardianOrOwner();\n error DuplicateApprover();\n error ZeroApproverLength();\n error UnregisteredFacetAndSelectors();\n\n /**\n * @notice Modifier to only allow guardian to make a call, reverts if any other entity is the caller\n */\n modifier onlyGuardian() {\n if (!LibGuardian.isGuardian(msg.sender)) revert CallerNotGuardian();\n _;\n }\n\n /**\n * @notice Modifier to only allow guardian or owner to make a call, reverts if any other entity is the caller\n */\n modifier onlyGuardianOrOwner() {\n if (!LibGuardian.isGuardian(msg.sender) && address(this) != msg.sender)\n revert CallerNotGuardianOrOwner();\n _;\n }\n\n /**\n * @notice Checks if the approver address is the array is unique with no duplicate\n * @dev This method loops through the array and checks if a duplicate address exists, it reverts if duplicate address exists\n * @param approvers Array of address\n */\n function _checkApprover(\n address[] memory approvers\n ) internal pure returns (bool) {\n uint256 approverLength = approvers.length;\n if (0 == approverLength) revert ZeroApproverLength();\n for (uint256 i; i < approverLength - 1; ) {\n for (uint256 j = i + 1; j < approverLength; ) {\n if (approvers[i] == approvers[j]) {\n revert DuplicateApprover(); // Found a duplicate\n }\n unchecked {\n ++j;\n }\n }\n unchecked {\n ++i;\n }\n }\n return false; // No duplicates found\n }\n\n /**\n * @notice Checks if the facet getting added or replaced is registered to facet registry\n * @dev This method loops through the cut and checks if the facet getting added/replaced is registered to facet registry\n * @param _diamondCut Array of FacetCut, data for diamondCut defined in EIP-2535\n */\n function _checkFacetCutValidity(\n IDiamondCut.FacetCut[] memory _diamondCut\n ) internal view {\n uint256 diamondCutLength = _diamondCut.length;\n for (uint256 i; i < diamondCutLength; ) {\n if (\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Add ||\n _diamondCut[i].action == IDiamondCut.FacetCutAction.Replace\n ) {\n if (\n !s.facetRegistry.areFacetFunctionSelectorsRegistered(\n _diamondCut[i].facetAddress,\n _diamondCut[i].functionSelectors\n )\n ) revert UnregisteredFacetAndSelectors();\n }\n unchecked {\n ++i;\n }\n }\n }\n}\n" + }, + "contracts/facets/RestrictionsFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ReentrancyGuard} from \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, RestrictionsStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {IRestriction} from \"../restrictions/IRestriction.sol\";\nimport {IRestrictionsFacet} from \"./interfaces/IRestrictionsFacet.sol\";\n\n/**\n * @title Restrictions facet\n * @dev Responsible for storing and verifying different kinds of restrictions, for example:\n * - Whitelist / Blacklist\n * - Daily limits\n * - Trading time restrictions\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract RestrictionsFacet is IRestrictionsFacet, ReentrancyGuard {\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceRestrictionsInitialize();\n }\n\n /**\n * @notice Intialize restrictions of Barz. Restrictions facet call restriction contracts for restriction validation\n * before each call\n * @param _restrictions The initial array of restrictions.\n * @return initSuccess Int value showing if the initialization of restriction is successful\n */\n function initializeRestrictions(\n address[] calldata _restrictions\n ) public override returns (uint256 initSuccess) {\n LibDiamond.enforceIsSelf();\n LibAppStorage.enforceRestrictionsInitialize();\n\n if (_restrictions.length == 0) {\n // You can't initialize RestrictionsFacet with an empty list of restrictions\n revert RestrictionsFacet__EmptyRestrictionsList();\n }\n for (uint256 i; i < _restrictions.length; ) {\n if (_restrictions[i] == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictions();\n unchecked {\n ++i;\n }\n }\n\n LibFacetStorage.restrictionsStorage().restrictions = _restrictions;\n _updateRestrictionsMap(_restrictions, true);\n initSuccess = 1;\n }\n\n /**\n * @notice Unitialize restrictions of Barz\n * @return uninitSuccess Int value showing if the initialization of restriction is successful\n */\n function uninitializeRestrictions()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibDiamond.enforceIsSelf();\n LibAppStorage.setRestrictionsUninitialized();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n _updateRestrictionsMap(restrictionsStorage.restrictions, false);\n restrictionsStorage.restrictions = new address[](0);\n uninitSuccess = 1;\n }\n\n /**\n * @notice Returns the list of Restrictions contract address\n * @return restrictions Addresses of IRestriction which are currently active\n */\n function getRestrictions()\n public\n view\n override\n returns (address[] memory restrictions)\n {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n restrictions = restrictionsStorage.restrictions;\n }\n\n /**\n * @notice Adds restrictions to Barz with validation on the restriction contract address.\n * This method is only callable by the owner(self).\n * @param _restriction The address of the restriction to be added.\n */\n function addRestriction(address _restriction) external override {\n LibDiamond.enforceIsSelf();\n if (LibDiamond.restrictionsFacet() == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictionsFacet();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n if (_restriction == address(0))\n revert RestrictionsFacet__ZeroAddressRestrictions();\n if (restrictionsStorage.exists[_restriction])\n revert RestrictionsFacet__RestrictionAlreadyExists();\n\n restrictionsStorage.restrictions.push(_restriction);\n restrictionsStorage.exists[_restriction] = true;\n\n emit RestrictionAdded(_restriction);\n }\n\n /**\n * @notice Remove restrictions from Barz if it existed. This method is only callable by the owner(self).\n * @param _restriction The address of the restriction to be removed.\n */\n function removeRestriction(address _restriction) external override {\n LibDiamond.enforceIsSelf();\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n if (!restrictionsStorage.exists[_restriction])\n revert RestrictionsFacet__RestrictionNotFound();\n\n address[] storage restrictions = restrictionsStorage.restrictions;\n\n uint256 indexToDelete = restrictions.length;\n uint256 restrictionsLen = restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n if (restrictions[i] == _restriction) {\n indexToDelete = i;\n break;\n }\n unchecked {\n ++i;\n }\n }\n\n if (indexToDelete == 0 && restrictionsLen == 1) {\n revert RestrictionsFacet__RemainingRestrictionsCantBeEmpty();\n } else if (indexToDelete == restrictionsLen) {\n revert RestrictionsFacet__RestrictionNotFound();\n } else {\n restrictions[indexToDelete] = restrictions[restrictionsLen - 1];\n restrictions.pop();\n }\n\n restrictionsStorage.exists[_restriction] = false;\n emit RestrictionRemoved(_restriction);\n }\n\n /**\n * @notice Sets the restrictions address value mapping to true or false when adding/removing restriction contracts\n * @param _restrictions List of restriction contracts address\n * @param _newValue Bool value to flag to the list of restrictions contracts\n */\n function _updateRestrictionsMap(\n address[] memory _restrictions,\n bool _newValue\n ) internal {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n uint restrictionsLen = _restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n restrictionsStorage.exists[_restrictions[i]] = _newValue;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @dev Iterates over all restrictions and verifies each of them with the transaction parameters.\n * @param _from The address of the sender, that will be signing the transaction.\n * @param _to The receiving address.\n * @param _value Amount of ETH to transfer from sender to recipient.\n * @param _calldata Optional field to include arbitrary data.\n * @return 0 if all the checks passed, 1 otherwise.\n */\n function verifyRestrictions(\n address _from,\n address _to,\n uint256 _value,\n bytes calldata _calldata\n ) external nonReentrant returns (uint256) {\n RestrictionsStorage storage restrictionsStorage = LibFacetStorage\n .restrictionsStorage();\n\n uint restrictionsLen = restrictionsStorage.restrictions.length;\n for (uint256 i; i < restrictionsLen; ) {\n IRestriction restriction = IRestriction(\n restrictionsStorage.restrictions[i]\n );\n bool checkPassed = restriction.check(_from, _to, _value, _calldata);\n if (!checkPassed) {\n return 1;\n }\n unchecked {\n ++i;\n }\n }\n\n return 0;\n }\n}\n" + }, + "contracts/facets/SignatureMigrationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {LibAppStorage} from \"../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, SignatureMigrationStorage, SignatureMigrationConfig, SignatureMigrationApprovalConfig, ApprovalConfig} from \"../libraries/LibFacetStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {LibGuardian} from \"../libraries/LibGuardian.sol\";\nimport {LibLoupe} from \"../libraries/LibLoupe.sol\";\nimport {Modifiers} from \"./Modifiers.sol\";\nimport {ISecurityManager} from \"../infrastructure/interfaces/ISecurityManager.sol\";\nimport {IDiamondCut} from \"./base/interfaces/IDiamondCut.sol\";\nimport {IVerificationFacet} from \"./interfaces/IVerificationFacet.sol\";\nimport {ISignatureMigrationFacet} from \"./interfaces/ISignatureMigrationFacet.sol\";\n\n/**\n * @title Signature Migration Facet\n * @dev Responsible for migrating user signature scheme to a new scheme user sets\n * Which could include\n * - ECDSA on Secp256K1 Curve\n * - ECDSA on Secp256R1 Curve\n * - BLS, Schnorr, etc\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract SignatureMigrationFacet is ISignatureMigrationFacet, Modifiers {\n bytes constant UNINIT_CALL =\n abi.encodeWithSignature(\"uninitializeSigner()\");\n ISecurityManager public immutable securityManager;\n\n /**\n * @notice This modifier verifies if the public key format matches with the new verification facet\n * @param _publicKey Bytes of public key to be validated for the new verification facet\n * @param _newVerificationFacet Address of new verification facet\n */\n modifier validateKeyType(\n bytes memory _publicKey,\n address _newVerificationFacet\n ) {\n if (\n !IVerificationFacet(_newVerificationFacet).isValidKeyType(\n _publicKey\n )\n ) revert SignatureMigrationFacet__InvalidKeyType();\n _;\n }\n\n /**\n * @notice This constructor sets the Security Manager address which is an immutable variable.\n * Immutable variables do not impact the storage of diamond\n * @param _securityManager Security Manager contract that holds the security related variables for all wallets\n */\n constructor(address _securityManager) {\n securityManager = ISecurityManager(_securityManager);\n }\n\n // IMPORTANT NOTE: In the client side when they call this function, the func selectors should be sorted in ascending order\n // to prevent different hash with same items in the array\n /**\n * @notice Moves the state of migration to a pending state. When pending state is over after pending period time,\n * Migration can be finalized. This function can only be called by self and when the account is unlocked.\n * @dev This method checks if the caller is self and if guardians exists. It migrates signature request to a pending state\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function migrateSignatureScheme(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n public\n override\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n // Only self contract can call this function\n LibDiamond.enforceIsSelf();\n // Should revert if guardian exist\n if (0 != LibGuardian.guardianCount())\n revert SignatureMigrationFacet__InvalidRouteWithGuardian();\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n // NOTE: Migration requires a pending period & confirmation from owner to prevent a\n // single call changing the ownership of the wallet\n /**\n * @notice Migrate signature scheme when guardians exists. Verifies the signature of guardians and moves migration to pending state.\n * Which can then be finalized when pending period is over. Owner's approval is mandatory for migration to happen\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _approvers List of approvers. This could include owner\n */\n function migrateSignatureSchemeWithGuardian(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n )\n public\n override\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n // Should revert if does not guardian exist\n if (0 == LibGuardian.guardianCount())\n revert SignatureMigrationFacet__InvalidRouteWithGuardian();\n if (_approvers.length != _signatures.length)\n revert SignatureMigrationFacet__InvalidArrayLength();\n\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(migrationPublicKeyHash, _approvers);\n\n bool onChainOwnerApproval = getMigrationOwnerApprovalWithTimeValidity(\n migrationPublicKeyHash\n );\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n\n if (\n _approvers.length +\n getMigrationApprovalCountWithTimeValidity(\n migrationPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert SignatureMigrationFacet__InsufficientApprovers();\n {\n // To prevent Stack too deep\n bool ownerApproved;\n for (uint256 i; i < _approvers.length; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n address(this) != _approvers[i]\n ) revert SignatureMigrationFacet__InvalidGuardian();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert SignatureMigrationFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n migrationPublicKeyHash,\n _signatures[i]\n )\n ) revert SignatureMigrationFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n\n if (!ownerApproved && !onChainOwnerApproval)\n revert SignatureMigrationFacet__LackOfOwnerApproval();\n }\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Internal function that moves signature mgiration to a pending state.\n * @dev This method increments migration nonce and sets the migration in the migration config. Emits events for migration execution\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _migrateSignatureScheme(\n address _newVerificationFacet,\n bytes memory _newPublicKey,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal {\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n unchecked {\n ++ms.nonce;\n }\n uint64 migrateAfter = uint64(block.timestamp + getMigrationPeriod());\n\n ms.migrationConfigs[INNER_STRUCT] = SignatureMigrationConfig(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n migrateAfter\n );\n\n emit SignatureMigrationExecuted(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors,\n migrateAfter\n );\n }\n\n /**\n * @notice Approves signature scheme migration on-chain. This can be called by owner or guardian only when the account is unlocked.\n * When the threshold of the migration approval passed and owner approval is granted, it automatically moves migration to a pending state\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function approveSignatureSchemeMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n public\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n {\n _checkMigrationCutValidity(\n _newVerificationFacet,\n _newVerificationFuncSelectors\n );\n }\n\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit SignatureMigrationApproved(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n msg.sender,\n approvalValidUntil\n );\n if (\n getMigrationApprovalCountWithTimeValidity(migrationPublicKeyHash) >=\n LibGuardian.majorityOfGuardians() &&\n getMigrationOwnerApprovalWithTimeValidity(migrationPublicKeyHash)\n )\n _migrateSignatureScheme(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Revokes the approval of signature migration done on-chain. Emits revoke event when revoked.\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function revokeSignatureMigrationApproval(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n external\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"MigrateSignature\"\n );\n if (!isMigrationApproved(migrationPublicKeyHash, msg.sender))\n revert SignatureMigrationFacet__CannotRevokeUnapproved();\n\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(false, 0);\n emit SignatureMigrationApprovalRevoked(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n msg.sender\n );\n }\n\n /**\n * @notice Finalizes the pending signature scheme migration. This function can only be called by owner.\n * It removes the facets of the previous verification facet and adds the new verification facet.\n * After finalizing migration, it emits migration event which shows the change of the verification facet\n */\n function finalizeSignatureMigration() external override {\n // NOTE: Only owner can call this function\n LibDiamond.enforceIsSelf();\n\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n\n if (!isMigrationPending())\n revert SignatureMigrationFacet__NonexistentMigration();\n\n if (\n uint64(block.timestamp) <=\n ms.migrationConfigs[INNER_STRUCT].migrateAfter\n ) revert SignatureMigrationFacet__MigrationPeriodNotOver();\n address newVerificationFacet = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationVerificationFacet;\n bytes4[] memory newVerificationFuncSelectors = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationSelectors;\n bytes memory newPublicKey = ms\n .migrationConfigs[INNER_STRUCT]\n .migrationPublicKey;\n\n address prevVerificationFacet = LibLoupe.facetAddress(\n s.validateOwnerSignatureSelector\n );\n if (prevVerificationFacet == address(0))\n revert SignatureMigrationFacet__NonExistentVerificationFacet();\n\n IDiamondCut.FacetCut[] memory UninitCut;\n IDiamondCut.FacetCut[] memory InitCut;\n {\n bytes4[] memory prevVerificationFuncSelectors = LibLoupe\n .facetFunctionSelectors(prevVerificationFacet);\n\n UninitCut = new IDiamondCut.FacetCut[](1);\n InitCut = new IDiamondCut.FacetCut[](1);\n UninitCut[0] = IDiamondCut.FacetCut({\n facetAddress: address(0),\n action: IDiamondCut.FacetCutAction.Remove,\n functionSelectors: prevVerificationFuncSelectors\n });\n InitCut[0] = IDiamondCut.FacetCut({\n facetAddress: newVerificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: newVerificationFuncSelectors\n });\n {\n IDiamondCut.FacetCut[]\n memory facetCuts = new IDiamondCut.FacetCut[](2);\n facetCuts[0] = UninitCut[0];\n facetCuts[1] = InitCut[0];\n _checkFacetCutValidity(facetCuts);\n }\n LibAppStorage.initiateSignerMigration();\n address verificationFacet = address(\n bytes20(\n LibDiamond.diamondStorage().facets[\n s.validateOwnerSignatureSelector\n ]\n )\n );\n\n (bool uninitSuccess, bytes memory uninitResult) = verificationFacet\n .delegatecall(UNINIT_CALL);\n if (!uninitSuccess || uint256(bytes32(uninitResult)) != 1)\n revert SignatureMigrationFacet__SignerUninitializationFailure();\n LibAppStorage.finalizeSignerMigration();\n\n LibDiamond.diamondCut(UninitCut, address(0), \"\");\n }\n {\n bytes memory initCall = abi.encodeWithSignature(\n \"initializeSigner(bytes)\",\n newPublicKey\n );\n\n // Every Verification Facet should comply with initializeSigner(bytes)\n // to be compatible with the Barz contract(for initialization)\n LibDiamond.diamondCut(InitCut, address(0), \"\");\n (bool initSuccess, bytes memory initResult) = newVerificationFacet\n .delegatecall(initCall);\n if (!initSuccess || uint256(bytes32(initResult)) != 1)\n revert SignatureMigrationFacet__SignerInitializationFailure();\n\n emit SignatureSchemeMigration(\n prevVerificationFacet,\n newVerificationFacet,\n newPublicKey,\n newVerificationFuncSelectors\n );\n }\n }\n\n /**\n * @notice Approve cancellation of signature migration. If cancellation approval passes guardian threshold with owner approval\n * it automatically cancels the migration.\n * @dev This method checks if the caller is one of guardian or owner and sets true for the cancellation hash in the approval config.\n * It internally calls _cancelSignatureMigration for canceling the migration\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function approveCancelSignatureMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors\n )\n external\n override\n onlyGuardianOrOwner\n onlyWhenUnlocked\n validateKeyType(_newPublicKey, _newVerificationFacet)\n {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"CancelSignatureMigration\"\n );\n uint64 approvalValidUntil = uint64(\n block.timestamp + getApprovalValidationPeriod()\n );\n ms.isMigrationApproved[migrationPublicKeyHash][\n msg.sender\n ] = ApprovalConfig(true, approvalValidUntil);\n emit SignatureMigrationCancellationApproved(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n if (\n getMigrationApprovalCountWithTimeValidity(migrationPublicKeyHash) >=\n LibGuardian.majorityOfGuardians() &&\n getMigrationOwnerApprovalWithTimeValidity(migrationPublicKeyHash)\n )\n _cancelSignatureMigration(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Verifies the signature of guardians/owner and cancels the signature migration.\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _approvers List of approvers. This could include owner\n */\n function cancelSignatureMigration(\n address _newVerificationFacet,\n bytes calldata _newPublicKey,\n bytes4[] calldata _newVerificationFuncSelectors,\n address[] calldata _approvers,\n bytes[] calldata _signatures\n )\n external\n override\n validateKeyType(_newPublicKey, _newVerificationFacet)\n onlyWhenUnlocked\n {\n if (_approvers.length != _signatures.length)\n revert SignatureMigrationFacet__InvalidArrayLength();\n\n bytes32 migrationPublicKeyHash = getApprovalMigrationKeyHash(\n _newPublicKey,\n _newVerificationFacet,\n _newVerificationFuncSelectors,\n \"CancelSignatureMigration\"\n );\n\n _checkApprover(_approvers);\n _checkDuplicateOnChainApprover(migrationPublicKeyHash, _approvers);\n\n bool onChainOwnerApproval = getMigrationOwnerApprovalWithTimeValidity(\n migrationPublicKeyHash\n );\n uint256 threshold = onChainOwnerApproval ? 0 : 1;\n if (\n _approvers.length +\n getMigrationApprovalCountWithTimeValidity(\n migrationPublicKeyHash\n ) <\n LibGuardian.majorityOfGuardians() + threshold\n ) revert SignatureMigrationFacet__InsufficientApprovers();\n {\n // To prevent stack too deep\n bool ownerApproved;\n for (uint256 i; i < _approvers.length; ) {\n if (\n !LibGuardian.isGuardian(_approvers[i]) &&\n address(this) != _approvers[i]\n ) revert SignatureMigrationFacet__NonExistentApprover();\n if (_approvers[i] == address(this)) {\n if (onChainOwnerApproval)\n revert SignatureMigrationFacet__OwnerAlreadyApproved();\n ownerApproved = true;\n }\n if (\n !SignatureChecker.isValidSignatureNow(\n _approvers[i],\n migrationPublicKeyHash,\n _signatures[i]\n )\n ) revert SignatureMigrationFacet__InvalidApproverSignature();\n unchecked {\n ++i;\n }\n }\n if (!ownerApproved && !onChainOwnerApproval)\n revert SignatureMigrationFacet__LackOfOwnerApproval();\n }\n _cancelSignatureMigration(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Internal function that cancels signature migration.\n * @dev This method increments migration nonce and deletes the migration from the migration config. Emits events for migration cancellation\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _cancelSignatureMigration(\n address _newVerificationFacet,\n bytes memory _newPublicKey,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal {\n if (!isMigrationPending())\n revert SignatureMigrationFacet__NonexistentMigration();\n SignatureMigrationStorage storage ms = LibFacetStorage\n .migrationStorage();\n unchecked {\n ++ms.nonce;\n }\n delete ms.migrationConfigs[INNER_STRUCT];\n emit SignatureMigrationCanceled(\n _newVerificationFacet,\n _newPublicKey,\n _newVerificationFuncSelectors\n );\n }\n\n /**\n * @notice Checks if the facets to be added from new verification facet is registered to facet registry\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n */\n function _checkMigrationCutValidity(\n address _newVerificationFacet,\n bytes4[] memory _newVerificationFuncSelectors\n ) internal view {\n IDiamondCut.FacetCut[] memory facetCuts = new IDiamondCut.FacetCut[](1);\n facetCuts[0] = IDiamondCut.FacetCut({\n facetAddress: _newVerificationFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: _newVerificationFuncSelectors\n });\n _checkFacetCutValidity(facetCuts);\n }\n\n /**\n * @notice Returns if the migration is pending of not\n * @dev This method fetches the migration storage and checks if the migrate after is above 0 value\n * @return isPending Bool value that shows if the migration is pending\n */\n function isMigrationPending()\n public\n view\n override\n returns (bool isPending)\n {\n SignatureMigrationStorage storage rs = LibFacetStorage\n .migrationStorage();\n isPending = rs.migrationConfigs[INNER_STRUCT].migrateAfter > 0;\n }\n\n /**\n * @notice Returns the migration hash. This function ensures that this hash is safe from replay attack by including\n * public key, verification facet, function selectors, salt, address, chainId, and nonce.\n * @param _newPublicKey Public key that will be used for the new verification facet that replaces the previous one\n * @param _newVerificationFacet Verification facet that will replace the existing verification facet\n * @param _newVerificationFuncSelectors Function Selectors of new verification facet that will be added to the diamond\n * @param _saltString Salt value for generating the migration hash\n * @return migrationKeyHash Bytes32 string of the migration key hash\n */\n function getApprovalMigrationKeyHash(\n bytes memory _newPublicKey,\n address _newVerificationFacet,\n bytes4[] memory _newVerificationFuncSelectors,\n string memory _saltString\n ) public view override returns (bytes32 migrationKeyHash) {\n migrationKeyHash = keccak256(\n abi.encodePacked(\n \"\\x19Ethereum Signed Message:\\n32\",\n keccak256(\n abi.encode(\n _newPublicKey,\n _newVerificationFacet,\n keccak256(abi.encode(_newVerificationFuncSelectors)),\n _saltString,\n address(this),\n block.chainid,\n LibFacetStorage.migrationStorage().nonce\n )\n )\n )\n );\n }\n\n /**\n * @notice Checks if the owner approved the hash for migration\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @return isApprovedByOwner Bool value of showing if the owner approved it or not\n */\n function getMigrationOwnerApprovalWithTimeValidity(\n bytes32 _migrationPublicKeyHash\n ) public view override returns (bool isApprovedByOwner) {\n isApprovedByOwner = isMigrationApproved(\n _migrationPublicKeyHash,\n address(this)\n );\n }\n\n /**\n * @notice Checks how many of the guardians approved the migration hash\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @return approvalCount Number of approvals\n */\n function getMigrationApprovalCountWithTimeValidity(\n bytes32 _migrationPublicKeyHash\n ) public view override returns (uint256 approvalCount) {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardiansLength = guardians.length;\n for (uint256 i; i < guardiansLength; ) {\n if (isMigrationApproved(_migrationPublicKeyHash, guardians[i])) {\n unchecked {\n ++approvalCount;\n }\n }\n unchecked {\n ++i;\n }\n }\n return approvalCount;\n }\n\n /**\n * @notice Checks if the migration is approved by the given approver\n * @param _migrationPublicKeyHash Hash of the public key and configuration for migration\n * @param _approver Address of approver\n * @return isApproved Bool value if migration hash is approved\n */\n function isMigrationApproved(\n bytes32 _migrationPublicKeyHash,\n address _approver\n ) public view override returns (bool isApproved) {\n SignatureMigrationApprovalConfig storage ms = LibFacetStorage\n .migrationStorage()\n .migrationApprovalConfigs[INNER_STRUCT];\n isApproved = (ms\n .isMigrationApproved[_migrationPublicKeyHash][_approver].isApproved &&\n block.timestamp <\n ms\n .isMigrationApproved[_migrationPublicKeyHash][_approver]\n .validUntil);\n }\n\n /**\n * @notice Checks if their is duplicate approver is included in off-chain approval verification and on-chain approval\n * Approvers who approved on-chain should not be included in the off-chain approval\n * @param _migrationPublicKeyHash Hash of migration information\n * @param _approvers List of approver addresses\n */\n function _checkDuplicateOnChainApprover(\n bytes32 _migrationPublicKeyHash,\n address[] memory _approvers\n ) public view {\n address[] memory guardians = LibGuardian.getGuardians();\n uint256 guardianLength = guardians.length;\n uint256 approversLength = _approvers.length;\n for (uint256 i; i < guardianLength; ) {\n if (isMigrationApproved(_migrationPublicKeyHash, guardians[i])) {\n for (uint256 j; j < approversLength; ) {\n if (_approvers[j] == guardians[i])\n revert SignatureMigrationFacet__DuplicateApproval();\n unchecked {\n ++j;\n }\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns the migration period of this wallet\n * @dev This method fetches the migration period from the security manager\n * @return migrationPeriod Migration period of Barz contract fetched from security manager\n */\n function getMigrationPeriod()\n internal\n view\n returns (uint128 migrationPeriod)\n {\n migrationPeriod = securityManager.migrationPeriodOf(address(this));\n if (migrationPeriod == 0)\n revert SignatureMigrationFacet__InvalidMigrationPeriod();\n }\n\n /**\n * @notice Returns the validation period of this wallet\n * @dev This method fetches the validation period from the security manager\n * @return approvalValidationPeriod Validation period of Barz contract fetched from security manager\n */\n function getApprovalValidationPeriod()\n internal\n view\n returns (uint256 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityManager.approvalValidationPeriodOf(\n address(this)\n );\n if (approvalValidationPeriod == 0)\n revert SignatureMigrationFacet__InvalidApprovalValidationPeriod();\n }\n\n /**\n * @notice Returns the migration nonce of this wallet\n * @dev This method fetches the nonce from migration storage\n * @return migrationNonce Nonce of migration to protect from reply attacks\n */\n function getMigrationNonce()\n public\n view\n override\n returns (uint128 migrationNonce)\n {\n migrationNonce = LibFacetStorage.migrationStorage().nonce;\n }\n\n /**\n * @notice Returns the migration configuration of this wallet\n * @dev This method fetches the migration config from the migration storage\n * @return pendingMigrationConfig Migration config currently pending for signature migration\n */\n function getPendingMigration()\n external\n view\n override\n returns (SignatureMigrationConfig memory pendingMigrationConfig)\n {\n pendingMigrationConfig = LibFacetStorage\n .migrationStorage()\n .migrationConfigs[INNER_STRUCT];\n }\n}\n" + }, + "contracts/facets/TokenReceiverFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {IERC1155Receiver} from \"../interfaces/ERC/IERC1155Receiver.sol\";\nimport {IERC677Receiver} from \"../interfaces/ERC/IERC677Receiver.sol\";\n\n/**\n * @title TokenReceiver Facet\n * @dev Contract that enables receiving ERC721/ERC1155/ERC777/ERC677 Tokens with safe transfer\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract TokenReceiverFacet is\n IERC721Receiver,\n IERC1155Receiver,\n IERC777Recipient,\n IERC677Receiver\n{\n /**\n * @notice Handles ERC721 Token callback.\n * return Standardized onERC721Received return value.\n */\n function onERC721Received(\n address,\n address,\n uint256,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC721Receiver.onERC721Received.selector;\n }\n\n /**\n * @notice Handles ERC1155 Token callback.\n * return Standardized onERC1155Received return value.\n */\n function onERC1155Received(\n address,\n address,\n uint256,\n uint256,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC1155Receiver.onERC1155Received.selector;\n }\n\n /**\n * @notice Handles ERC1155 Token batch callback.\n * return Standardized onERC1155BatchReceived return value.\n */\n function onERC1155BatchReceived(\n address,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC1155Receiver.onERC1155BatchReceived.selector;\n }\n\n /**\n * @notice Handles ERC777 Token callback.\n * Does not return value, empty implementation.\n */\n function tokensReceived(\n address,\n address,\n address,\n uint256,\n bytes calldata,\n bytes calldata\n ) external pure override {}\n\n /**\n * @notice Handles ERC677 Token callback.\n * return true.\n */\n function onTokenTransfer(\n address,\n uint256,\n bytes calldata\n ) external pure override returns (bool) {\n return true;\n }\n}\n" + }, + "contracts/facets/verification/MultiSigFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {SignatureChecker} from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {UserOperation} from \"../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibDiamond} from \"../../libraries/LibDiamond.sol\";\nimport {LibLoupe} from \"../../libraries/LibLoupe.sol\";\nimport {LibAppStorage} from \"../../libraries/LibAppStorage.sol\";\nimport {LibMultiSigStorage, MultiSigStorage} from \"../../libraries/LibMultiSigStorage.sol\";\nimport {IERC1271} from \"../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../interfaces/IVerificationFacet.sol\";\nimport {IMultiSigFacet} from \"../interfaces/IMultiSigFacet.sol\";\n\n/**\n * @title Multi-sig facet\n * @dev Multi-signature Facet with custom threshold.\n * Wallet that adds this facet becomes a multi-sig wallet.\n * Reference signature_format.md documentation for Multi-sig facet details\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract MultiSigFacet is IMultiSigFacet, IVerificationFacet, IERC1271 {\n using ECDSA for bytes32;\n\n address public immutable self;\n\n address internal constant SENTINEL_OWNERS = address(0x1);\n uint256 internal constant ADDRESS = 20;\n uint256 internal constant SIG_TYPE = 1;\n uint256 internal constant SIG_LEN = 4;\n uint256 internal constant THRESHOLD = 4;\n uint256 internal constant INVALID_SIG = 1;\n uint256 internal constant VALID_SIG = 0;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in Multisig Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the right format and initializes signer storage in k1 storage.\n * @param _owners Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _owners\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n\n if (!isValidKeyType(_owners)) revert MultiSigFacet__InvalidInitData();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n uint256 threshold = uint256(uint32(bytes4(_owners)));\n uint256 ownerCount = (_owners.length - THRESHOLD) / ADDRESS;\n\n if (threshold == 0) revert MultiSigFacet__InvalidThreshold();\n if (ownerCount == 0) revert MultisigFacet__InvalidOwnerCount();\n\n address currentOwner = SENTINEL_OWNERS;\n uint256 ptr = THRESHOLD;\n address owner_;\n for (uint256 i; i < ownerCount; ) {\n owner_ = address(bytes20(_owners[ptr:ptr + ADDRESS]));\n ptr += ADDRESS;\n if (\n owner_ == address(0) ||\n owner_ == SENTINEL_OWNERS ||\n owner_ == address(this) ||\n owner_ == currentOwner\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[owner_] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n\n ms.owners[currentOwner] = owner_;\n currentOwner = owner_;\n\n unchecked {\n ++i;\n }\n }\n ms.owners[currentOwner] = SENTINEL_OWNERS;\n ms.ownerCount = ownerCount;\n ms.threshold = threshold;\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_owners);\n }\n\n /**\n * @notice Uninitialize signer in K1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n ++ms.counter;\n address[] memory ownerlist = getOwners();\n uint256 ownerlistLength = ownerlist.length;\n for (uint256 i; i < ownerlistLength; ) {\n ms.owners[ownerlist[i]] = address(0);\n unchecked {\n ++i;\n }\n }\n ms.owners[SENTINEL_OWNERS] = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls checkSignatures with\n * user operation hash and signature together with the threshold.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n // Data 1 is invalid, Data 0 is valid\n validationData = checkSignatures(\n userOpHash,\n userOp.signature,\n LibMultiSigStorage.multisigStorage().threshold\n );\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n return this.validateOwnerSignature.selector;\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n uint totalLength = ms.ownerCount * ADDRESS;\n bytes memory result = new bytes(totalLength);\n\n // populate return array\n uint256 index;\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n while (currentOwner != SENTINEL_OWNERS) {\n assembly {\n mstore(\n add(result, add(32, mul(index, ADDRESS))),\n shl(96, currentOwner)\n )\n }\n currentOwner = ms.owners[currentOwner];\n index++;\n }\n\n return result;\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key should comply with the format in the signature_format.md doc\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n uint256 publicKeyLength = _publicKey.length;\n if (\n publicKeyLength < ADDRESS + THRESHOLD ||\n (publicKeyLength - THRESHOLD) % ADDRESS != 0\n ) return false;\n\n uint256 threshold = uint256(uint32(bytes4(_publicKey)));\n uint256 ownerCount = (publicKeyLength - THRESHOLD) / ADDRESS;\n\n isValid = !(ownerCount < threshold || threshold == 0);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes calldata _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (checkSignatures(\n _hash,\n _signature,\n LibMultiSigStorage.multisigStorage().threshold\n ) == VALID_SIG)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n\n /**\n * @notice Validates the format of the signature and verifies if the signature is signed by the expected key.\n * Reference signature_format.md doc for details about signature format and signature types\n * @param _dataHash Bytes value of data hash signed by the owners\n * @param _signatures Bytes value of signature which should comply with signature format\n * @param _threshold Uint256 value of current Multi-sig Barz's threshold\n */\n function checkSignatures(\n bytes32 _dataHash,\n bytes calldata _signatures,\n uint256 _threshold\n ) public view returns (uint256) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n address lastOwner = address(0);\n address currentOwner;\n bytes memory signature;\n uint256 signatureType;\n uint256 nextOffset;\n uint256 i;\n for (i; i < _threshold; ) {\n (\n currentOwner,\n signature,\n signatureType,\n nextOffset\n ) = splitSignatures(_signatures, nextOffset);\n if (nextOffset == 0 && i + 1 < _threshold) return INVALID_SIG;\n if (signatureType == 1) {\n // If signatureType is 1 then it is default dataHash signed.\n // This also includes the contract signature\n if (\n !SignatureChecker.isValidSignatureNow(\n currentOwner,\n _dataHash,\n signature\n )\n ) return INVALID_SIG;\n } else if (signatureType == 2) {\n // If signatureType is 2 then it is an approved hash\n if (ms.approvedHashes[ms.counter][currentOwner][_dataHash] == 0)\n return INVALID_SIG;\n } else if (signatureType == 3) {\n // If signatureType is 3 then it is a signed message hash\n // This also includes the contract signature\n bytes32 msgHash = _dataHash.toEthSignedMessageHash();\n if (\n !SignatureChecker.isValidSignatureNow(\n currentOwner,\n msgHash,\n signature\n )\n ) return INVALID_SIG;\n } else revert MultiSigFacet__InvalidRoute();\n if (\n currentOwner <= lastOwner ||\n ms.owners[currentOwner] == address(0) ||\n currentOwner == SENTINEL_OWNERS\n ) return INVALID_SIG;\n lastOwner = currentOwner;\n\n unchecked {\n ++i;\n }\n }\n return VALID_SIG;\n }\n\n /**\n * @notice Split signatures into each individual signatures. Should comply with signature format to be split\n * @param _signatures Bytes value of signature\n * @param _nextOffset Uint256 value of next offset to start splitting the signature\n */\n function splitSignatures(\n bytes calldata _signatures,\n uint256 _nextOffset\n )\n public\n pure\n returns (\n address owner_,\n bytes memory signature,\n uint256 signatureType,\n uint256 nextOffset\n )\n {\n uint256 signaturesLength = _signatures.length;\n\n if (signaturesLength <= _nextOffset + ADDRESS + SIG_LEN)\n revert MultiSigFacet__InsufficientSignerLength();\n\n owner_ = address(\n bytes20(_signatures[_nextOffset:_nextOffset + ADDRESS])\n );\n\n signatureType = uint256(\n uint8(\n bytes1(\n _signatures[_nextOffset + ADDRESS:_nextOffset +\n ADDRESS +\n SIG_TYPE]\n )\n )\n );\n\n if (signatureType > 3 || signatureType == 0)\n revert MultiSigFacet__InvalidSignatureType();\n uint256 offSet = _nextOffset + ADDRESS + SIG_TYPE;\n uint256 siglen = uint256(\n uint32(bytes4(_signatures[offSet:offSet + SIG_LEN]))\n );\n if (offSet + siglen > signaturesLength)\n revert MultiSigFacet__InvalidSignatureLength();\n\n offSet += SIG_LEN;\n if (offSet + siglen == signaturesLength) nextOffset = 0;\n else nextOffset = offSet + siglen;\n\n signature = _signatures[offSet:offSet + siglen];\n }\n\n /**\n * @notice Approves the hash of userOperation on-chain. This can only be called by owners.\n * @param _hashToApprove Bytes value of UserOperation hash to approve\n */\n function approveHash(bytes32 _hashToApprove) external {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (ms.owners[msg.sender] == address(0))\n revert MultiSigFacet__OnlyOwner();\n\n ms.approvedHashes[ms.counter][msg.sender][_hashToApprove] = 1;\n emit HashApproved(_hashToApprove, msg.sender);\n }\n\n /**\n * @notice Add owner to Barz. Update thresold if threshold is given different from current threshold\n * @dev This can only be done via a Self call.\n * @param _newOwner Address of new owner to be added\n * @param _threshold Uint256 value of threshold\n */\n function addOwner(address _newOwner, uint256 _threshold) external {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (\n _newOwner == address(0) ||\n _newOwner == SENTINEL_OWNERS ||\n _newOwner == address(this)\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_newOwner] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n\n ms.owners[_newOwner] = ms.owners[SENTINEL_OWNERS];\n ms.owners[SENTINEL_OWNERS] = _newOwner;\n ++ms.ownerCount;\n emit OwnerAdded(_newOwner);\n\n if (ms.threshold != _threshold) changeThreshold(_threshold);\n }\n\n /**\n * @notice Remove owner from Barz. Update thresold if threshold is given different from current threshold\n * @dev This can only be done via a Self call.\n * @param _prevOwner Address of owner located right behind the removed owner address in the linked list\n * @param _removedOwner Address of owner to be removed\n * @param _threshold Uint256 value of threshold\n */\n function removeOwner(\n address _prevOwner,\n address _removedOwner,\n uint256 _threshold\n ) external {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (ms.ownerCount - 1 < _threshold)\n revert MultiSigFacet__InvalidThreshold();\n if (_removedOwner == address(0) || _removedOwner == SENTINEL_OWNERS)\n revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_prevOwner] != _removedOwner)\n revert MultiSigFacet__InvalidOwnerPair();\n\n ms.owners[_prevOwner] = ms.owners[_removedOwner];\n ms.owners[_removedOwner] = address(0);\n --ms.ownerCount;\n emit OwnerRemoved(_removedOwner);\n\n if (ms.threshold != _threshold) changeThreshold(_threshold);\n }\n\n /**\n * @notice Swap owner in Barz.\n * @dev This can only be done via a Self call.\n * @param _prevOwner Address of owner located right behind the removed owner address in the linked list\n * @param _oldOwner Address of owner to be removed\n * @param _newOwner Address of owner to be added\n */\n function swapOwner(\n address _prevOwner,\n address _oldOwner,\n address _newOwner\n ) public {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (\n _newOwner == address(0) ||\n _newOwner == SENTINEL_OWNERS ||\n _newOwner == address(this)\n ) revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_newOwner] != address(0))\n revert MultiSigFacet__DuplicateOwner();\n if (_oldOwner == address(0) || _oldOwner == SENTINEL_OWNERS)\n revert MultiSigFacet__InvalidOwnerAddress();\n if (ms.owners[_prevOwner] != _oldOwner)\n revert MultiSigFacet__InvalidOwnerPair();\n\n ms.owners[_newOwner] = ms.owners[_oldOwner];\n ms.owners[_prevOwner] = _newOwner;\n ms.owners[_oldOwner] = address(0);\n emit OwnerRemoved(_oldOwner);\n emit OwnerAdded(_newOwner);\n }\n\n /**\n * @notice Changes the threshold of the Barz to `_threshold`.\n * @dev This can only be done via a Self call.\n * @param _threshold New threshold\n */\n function changeThreshold(uint256 _threshold) public {\n LibDiamond.enforceIsSelf();\n\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n if (_threshold > ms.ownerCount || _threshold == 0)\n revert MultiSigFacet__InvalidThreshold();\n\n ms.threshold = _threshold;\n emit ThresholdChanged(_threshold);\n }\n\n /**\n * @notice Checks if the given address is owner\n * @param _owner Address to be checked if it's owner\n * @return isOwner_ Bool value showing if it's owner address\n */\n function isOwner(address _owner) public view returns (bool isOwner_) {\n isOwner_ = (_owner != SENTINEL_OWNERS &&\n LibMultiSigStorage.multisigStorage().owners[_owner] != address(0));\n }\n\n /**\n * @notice Returns the threshold of Barz\n * @return threshold Threshold of the Barz account\n */\n function getThreshold() public view returns (uint256 threshold) {\n threshold = LibMultiSigStorage.multisigStorage().threshold;\n }\n\n /**\n * @notice Returns the list of owner addresses\n * @return owners List of owners\n */\n function getOwners() public view returns (address[] memory owners) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n owners = new address[](ms.ownerCount);\n\n uint256 index;\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n while (currentOwner != SENTINEL_OWNERS) {\n owners[index] = currentOwner;\n currentOwner = ms.owners[currentOwner];\n index++;\n }\n }\n\n /**\n * @notice Returns the previous owner in the linked list\n * @param _owner Address of owner\n * @return prevOwner Address of previous owner\n */\n function getPrevOwner(\n address _owner\n ) public view returns (address prevOwner) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n\n address currentOwner = ms.owners[SENTINEL_OWNERS];\n if (currentOwner == _owner) return SENTINEL_OWNERS;\n while (currentOwner != SENTINEL_OWNERS) {\n if (ms.owners[currentOwner] == _owner) return currentOwner;\n\n currentOwner = ms.owners[currentOwner];\n }\n return address(0);\n }\n\n /**\n * @notice Returns of the owner is approved by given owner address\n * @param _owner Address of owner\n * @param _hash Hash of UserOperation\n * @return isApproved Bool value showing if the hash is approved by owner\n */\n function isApprovedHash(\n address _owner,\n bytes32 _hash\n ) public view returns (bool isApproved) {\n MultiSigStorage storage ms = LibMultiSigStorage.multisigStorage();\n isApproved = (ms.approvedHashes[ms.counter][_owner][_hash] == 1);\n }\n}\n" + }, + "contracts/facets/verification/secp256k1/Secp256k1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {UserOperation} from \"../../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibAppStorage} from \"../../../libraries/LibAppStorage.sol\";\nimport {LibFacetStorage, Secp256k1VerificationStorage} from \"../../../libraries/LibFacetStorage.sol\";\nimport {LibLoupe} from \"../../../libraries/LibLoupe.sol\";\nimport {IERC1271} from \"../../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../../interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Secp256k1 verification facet\n * @dev Default Ethereum's elliptic curve\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract Secp256k1VerificationFacet is IVerificationFacet, IERC1271 {\n using ECDSA for bytes32;\n error Secp256k1VerificationFacet__InvalidSignerLength();\n address public immutable self;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in K1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\n * @param _publicKey Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _publicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n if (!isValidKeyType(_publicKey))\n revert Secp256k1VerificationFacet__InvalidSignerLength();\n\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(uint160(uint256(keccak256(_publicKey[1:]))));\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_publicKey);\n }\n\n /**\n * @notice Uninitialize signer in K1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\n * signer public key.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n validationData = validateSignature(\n userOp,\n userOpHash,\n k1Storage.signer\n );\n }\n\n /**\n * @notice Validates if the signature of UserOperation is signed by the given signer\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @param signer Address of signer who signed the contract, to be validated\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n address signer\n ) public pure returns (uint256 isValid) {\n bytes32 hash = userOpHash.toEthSignedMessageHash();\n isValid = (signer != hash.recover(userOp.signature)) ? 1 : 0;\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n ownerSignatureValidatorSelector = this.validateOwnerSignature.selector;\n // NOTE: The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory signer) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n signer = abi.encodePacked(k1Storage.signer);\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key length should be 65 in an uncompressed public key format\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (_hash.recover(_signature) ==\n LibFacetStorage.k1Storage().signer)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/Secp256r1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {UserOperation} from \"../../../aa-4337/interfaces/UserOperation.sol\";\nimport {LibAppStorage} from \"../../../libraries/LibAppStorage.sol\";\nimport {LibLoupe} from \"../../../libraries/LibLoupe.sol\";\nimport {LibFacetStorage, Secp256r1VerificationStorage} from \"../../../libraries/LibFacetStorage.sol\";\nimport {Base64} from \"./utils/Base64.sol\";\nimport {LibSecp256r1} from \"./utils/LibSecp256r1.sol\";\nimport {IERC1271} from \"../../../interfaces/ERC/IERC1271.sol\";\nimport {IVerificationFacet} from \"../../interfaces/IVerificationFacet.sol\";\n\n/**\n * @title Secp256r1 verification facet\n * @dev Primarily used to verify user ops signed with passkeys\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract Secp256r1VerificationFacet is IVerificationFacet, IERC1271 {\n error Secp256r1VerificationFacet__InvalidSignerLength();\n address public immutable self;\n\n /**\n * @notice This constructor ensures that this contract can only be used as singleton for Proxy contracts\n */\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n self = address(this);\n }\n\n /**\n * @notice Initializes the signer in R1 Facet Storage. This can only be called when the account is uninitialized or during signature migration.\n * @dev This method checks if the signer has already been initialized. If already initialized, it reverts.\n * It checks if the public key is in the light format and initializes signer storage in k1 storage.\n * @param _publicKey Bytes of owner public key\n * @return initSuccess Uint value representing the success of init operation\n */\n function initializeSigner(\n bytes calldata _publicKey\n ) public override returns (uint256 initSuccess) {\n LibAppStorage.enforceSignerInitialize();\n\n if (!isValidKeyType(_publicKey))\n revert Secp256r1VerificationFacet__InvalidSignerLength();\n\n bytes memory publicKeyCoordinates = _publicKey[1:];\n uint256[2] memory q;\n assembly {\n // Copy the bytes from the input data into the uint256 array\n mstore(q, mload(add(publicKeyCoordinates, 32)))\n mstore(add(q, 32), mload(add(publicKeyCoordinates, 64)))\n }\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n r1Storage.q = q;\n\n bytes4 validateSelector = validateOwnerSignatureSelector();\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() != bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorAlreadySet();\n if (LibLoupe.facetAddress(validateSelector) != self)\n revert VerificationFacet__InvalidFacetMapping();\n\n // initialize verification function selector\n LibAppStorage.setValidateOwnerSignatureSelector(validateSelector);\n\n initSuccess = 1;\n\n emit SignerInitialized(_publicKey);\n }\n\n /**\n * @notice Uninitialize signer in R1 Facet Storage. This can only be called when the account is undergoing signature migration\n * and has already been initialized.\n * @dev This method checks if the signature migration is undergoing, signer is initialized and sets the signer to zero value.\n * @return uninitSuccess Uint value representing the success of uninit operation\n */\n function uninitializeSigner()\n external\n override\n returns (uint256 uninitSuccess)\n {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n r1Storage.q = [0, 0];\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n /**\n * @notice Validates if the user operation is signed by the owner.\n * @dev This method validates if the user operation is signed by the owner. It internally calls validateSignature with\n * signer public key.\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @return validationData Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view override returns (uint256 validationData) {\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n validationData = validateSignature(userOp, userOpHash, r1Storage.q);\n }\n\n /**\n * @notice Validates if the signature of UserOperation is signed by the given signer\n * @dev This method uses OpenZeppelin library to validate if the signature of UserOperation is signed by the signer address\n * @param userOp UserOperation including all information for execution\n * @param userOpHash Hash of UserOperation given from EntryPoint. This hash is used for signature validation\n * @param q Public Key of signer who signed the contract, to be validated\n * @return isValid Uint value representing whether the validation is successful. 0 for success, 1 for failure\n */\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n uint256[2] memory q\n ) public view returns (uint256 isValid) {\n isValid = (_validateSignature(q, userOpHash, userOp.signature)) ? 0 : 1;\n }\n\n /**\n * @notice Returns the selector of function to validate the signature of UserOperation\n * @return ownerSignatureValidatorSelector Bytes4 selector of function signature to validate account owner's UserOperation signature\n */\n function validateOwnerSignatureSelector()\n public\n pure\n override\n returns (bytes4 ownerSignatureValidatorSelector)\n {\n return this.validateOwnerSignature.selector; // validateOwnerSignature(UserOperation calldata userOp,bytes32 userOpHash)\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n /**\n * @notice Returns the owner of the account\n * @return signer Bytes of owner address\n */\n function owner() public view override returns (bytes memory signer) {\n Secp256r1VerificationStorage storage r1Storage = LibFacetStorage\n .r1Storage();\n signer = abi.encodePacked(r1Storage.q);\n }\n\n /**\n * @notice Validates if the format of public key is valid for this verification facet\n * @dev For this Secp256k1Verification Facet, the public key should in an uncompressed public key format\n * @param _publicKey Bytes of public key for format check\n * @return isValid Boolean variable representing if the format of public key is valid\n */\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure override returns (bool isValid) {\n isValid = (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n /**\n * @notice Validates if the signature is valid. Function to be compatible with EIP-1271\n * @dev This method verifies the signature if the owner indeed signed the hash. Returns magic value if true\n * @param _hash Hash value the owner signed\n * @param _signature Signature that signed the above hash\n * @return magicValue Bytes4 value representing the success/failure of validation\n */\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = _validateSignature(\n LibFacetStorage.r1Storage().q,\n _hash,\n _signature\n )\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n\n function _validateSignature(\n uint256[2] memory q,\n bytes32 _hash,\n bytes memory _signature\n ) internal view returns (bool) {\n (\n uint256 rValue,\n uint256 sValue,\n bytes memory authenticatorData,\n string memory clientDataJSONPre,\n string memory clientDataJSONPost\n ) = abi.decode(_signature, (uint256, uint256, bytes, string, string));\n bytes32 clientHash;\n {\n string memory opHashBase64 = Base64.encode(bytes.concat(_hash));\n string memory clientDataJSON = string.concat(\n clientDataJSONPre,\n opHashBase64,\n clientDataJSONPost\n );\n clientHash = sha256(bytes(clientDataJSON));\n }\n bytes32 sigHash = sha256(bytes.concat(authenticatorData, clientHash));\n return LibSecp256r1.Verify(q, rValue, sValue, uint256(sigHash));\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/utils/Base64.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @dev Provides a set of functions to operate with Base64 strings.\n * modified for base64url https://datatracker.ietf.org/doc/html/rfc4648#section-5\n * _Available since v4.5._\n */\nlibrary Base64 {\n /**\n * @dev Base64 Encoding/Decoding Table\n */\n string internal constant _TABLE =\n \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_\";\n\n /**\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\n */\n function encode(bytes memory data) internal pure returns (string memory) {\n /**\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\n */\n if (data.length == 0) return \"\";\n\n // Loads the table into memory\n string memory table = _TABLE;\n\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\n // and split into 4 numbers of 6 bits.\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\n // - `data.length + 2` -> Round up\n // - `/ 3` -> Number of 3-bytes chunks\n // - `4 *` -> 4 characters for each chunk\n uint256 newlength = (data.length * 8) / 6;\n if (data.length % 6 > 0) {\n newlength++;\n }\n string memory result = new string(newlength);\n\n /// @solidity memory-safe-assembly\n assembly {\n // Prepare the lookup table (skip the first \"length\" byte)\n let tablePtr := add(table, 1)\n\n // Prepare result pointer, jump over length\n let resultPtr := add(result, 32)\n\n // Run over the input, 3 bytes at a time\n for {\n let dataPtr := data\n let endPtr := add(data, mload(data))\n } lt(dataPtr, endPtr) {\n\n } {\n // Advance 3 bytes\n dataPtr := add(dataPtr, 3)\n let input := mload(dataPtr)\n\n // To write each character, shift the 3 bytes (18 bits) chunk\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\n // and apply logical AND with 0x3F which is the number of\n // the previous character in the ASCII table prior to the Base64 Table\n // The result is then added to the table to get the character to write,\n // and finally write it in the result pointer but with a left shift\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(18, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(12, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(\n resultPtr,\n mload(add(tablePtr, and(shr(6, input), 0x3F)))\n )\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n }\n }\n\n return result;\n }\n}\n" + }, + "contracts/facets/verification/secp256r1/utils/LibSecp256r1.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\n// Heavily inspired from\n// https://github.com/maxrobot/elliptic-solidity/blob/master/contracts/Secp256r1.sol\n// https://github.com/tdrerup/elliptic-curve-solidity/blob/master/contracts/curves/EllipticCurve.sol\n// modified to use precompile 0x05 modexp\n// and modified jacobian double\n// optimisations to avoid to an from from affine and jacobian coordinates\n\n// Additional Elliptic curve Public key / Signature validation added by\n// David Yonjun Kim (@Powerstream3604)\n\nstruct JPoint {\n uint256 x;\n uint256 y;\n uint256 z;\n}\n\nlibrary LibSecp256r1 {\n uint256 constant gx =\n 0x6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296;\n uint256 constant gy =\n 0x4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5;\n uint256 public constant pp =\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF;\n\n uint256 public constant nn =\n 0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551;\n uint256 constant a =\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC;\n uint256 constant b =\n 0x5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B;\n uint256 constant MOST_SIGNIFICANT =\n 0xc000000000000000000000000000000000000000000000000000000000000000;\n\n /*\n * Verify\n * @description - verifies that a public key has signed a given message\n * @param Q - public key coordinates X & Y\n * @param R - signature half R\n * @param S - signature half S\n * @param input - hashed message\n */\n function Verify(\n uint256[2] memory q,\n uint r,\n uint s,\n uint e\n ) internal view returns (bool) {\n if (q[0] > pp - 1 || q[1] > pp - 1) {\n return false;\n }\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\n return false;\n }\n if (\n mulmod(q[1], q[1], pp) !=\n addmod(\n addmod(\n mulmod(q[0], mulmod(q[0], q[0], pp), pp),\n mulmod(a, q[0], pp),\n pp\n ),\n b,\n pp\n )\n ) {\n return false;\n }\n\n JPoint[16] memory points = _preComputeJacobianPoints(q);\n return VerifyWithPrecompute(points, r, s, e);\n }\n\n function VerifyWithPrecompute(\n JPoint[16] memory points,\n uint r,\n uint s,\n uint e\n ) internal view returns (bool) {\n if (r == 0 || s == 0 || r >= nn || s >= nn) {\n return false;\n }\n\n uint w = _primemod(s, nn);\n\n uint u1 = mulmod(e, w, nn);\n uint u2 = mulmod(r, w, nn);\n\n uint x;\n uint y;\n\n (x, y) = ShamirMultJacobian(points, u1, u2);\n return (x == r);\n }\n\n /*\n * Strauss Shamir trick for EC multiplication\n * https://stackoverflow.com/questions/50993471/ec-scalar-multiplication-with-strauss-shamir-method\n * we optimise on this a bit to do with 2 bits at a time rather than a single bit\n * the individual points for a single pass are precomputed\n * overall this reduces the number of additions while keeping the same number of doublings\n */\n function ShamirMultJacobian(\n JPoint[16] memory points,\n uint u1,\n uint u2\n ) internal view returns (uint, uint) {\n uint x = 0;\n uint y = 0;\n uint z = 0;\n uint bits = 128;\n uint index = 0;\n\n while (bits > 0) {\n if (z > 0) {\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\n (x, y, z) = _modifiedJacobianDouble(x, y, z);\n }\n index =\n ((u1 & MOST_SIGNIFICANT) >> 252) |\n ((u2 & MOST_SIGNIFICANT) >> 254);\n if (index > 0) {\n (x, y, z) = _jAdd(\n x,\n y,\n z,\n points[index].x,\n points[index].y,\n points[index].z\n );\n }\n u1 <<= 2;\n u2 <<= 2;\n bits--;\n }\n (x, y) = _affineFromJacobian(x, y, z);\n return (x, y);\n }\n\n function _preComputeJacobianPoints(\n uint256[2] memory q\n ) internal pure returns (JPoint[16] memory points) {\n points[0] = JPoint(0, 0, 0);\n points[1] = JPoint(q[0], q[1], 1); // u2\n points[2] = _jPointDouble(points[1]);\n points[3] = _jPointAdd(points[1], points[2]);\n\n points[4] = JPoint(gx, gy, 1); // u1Points[1]\n points[5] = _jPointAdd(points[4], points[1]);\n points[6] = _jPointAdd(points[4], points[2]);\n points[7] = _jPointAdd(points[4], points[3]);\n\n points[8] = _jPointDouble(points[4]); // u1Points[2]\n points[9] = _jPointAdd(points[8], points[1]);\n points[10] = _jPointAdd(points[8], points[2]);\n points[11] = _jPointAdd(points[8], points[3]);\n\n points[12] = _jPointAdd(points[4], points[8]); // u1Points[3]\n points[13] = _jPointAdd(points[12], points[1]);\n points[14] = _jPointAdd(points[12], points[2]);\n points[15] = _jPointAdd(points[12], points[3]);\n }\n\n function _jPointAdd(\n JPoint memory p1,\n JPoint memory p2\n ) internal pure returns (JPoint memory) {\n uint x;\n uint y;\n uint z;\n (x, y, z) = _jAdd(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z);\n return JPoint(x, y, z);\n }\n\n function _jPointDouble(\n JPoint memory p\n ) internal pure returns (JPoint memory) {\n uint x;\n uint y;\n uint z;\n (x, y, z) = _modifiedJacobianDouble(p.x, p.y, p.z);\n return JPoint(x, y, z);\n }\n\n /* _affineFromJacobian\n * @desription returns affine coordinates from a jacobian input follows\n * golang elliptic/crypto library\n */\n function _affineFromJacobian(\n uint x,\n uint y,\n uint z\n ) internal view returns (uint ax, uint ay) {\n if (z == 0) {\n return (0, 0);\n }\n\n uint zinv = _primemod(z, pp);\n uint zinvsq = mulmod(zinv, zinv, pp);\n\n ax = mulmod(x, zinvsq, pp);\n ay = mulmod(y, mulmod(zinvsq, zinv, pp), pp);\n }\n\n /*\n * _jAdd\n * @description performs Jacobian addition as defined below:\n * http://www.hyperelliptic.org/EFD/g1p/data/shortw/jacobian/addition/add-2007-bl\n */\n function _jAdd(\n uint p1,\n uint p2,\n uint p3,\n uint q1,\n uint q2,\n uint q3\n ) internal pure returns (uint r1, uint r2, uint r3) {\n if (p3 == 0) {\n r1 = q1;\n r2 = q2;\n r3 = q3;\n\n return (r1, r2, r3);\n } else if (q3 == 0) {\n r1 = p1;\n r2 = p2;\n r3 = p3;\n\n return (r1, r2, r3);\n }\n\n assembly {\n let\n pd\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\n let z1z1 := mulmod(p3, p3, pd) // Z1Z1 = Z1^2\n let z2z2 := mulmod(q3, q3, pd) // Z2Z2 = Z2^2\n\n let u1 := mulmod(p1, z2z2, pd) // U1 = X1*Z2Z2\n let u2 := mulmod(q1, z1z1, pd) // U2 = X2*Z1Z1\n\n let s1 := mulmod(p2, mulmod(z2z2, q3, pd), pd) // S1 = Y1*Z2*Z2Z2\n let s2 := mulmod(q2, mulmod(z1z1, p3, pd), pd) // S2 = Y2*Z1*Z1Z1\n\n let p3q3 := addmod(p3, q3, pd)\n\n if lt(u2, u1) {\n u2 := add(pd, u2) // u2 = u2+pd\n }\n let h := sub(u2, u1) // H = U2-U1\n\n let i := mulmod(0x02, h, pd)\n i := mulmod(i, i, pd) // I = (2*H)^2\n\n let j := mulmod(h, i, pd) // J = H*I\n if lt(s2, s1) {\n s2 := add(pd, s2) // u2 = u2+pd\n }\n let rr := mulmod(0x02, sub(s2, s1), pd) // r = 2*(S2-S1)\n r1 := mulmod(rr, rr, pd) // X3 = R^2\n\n let v := mulmod(u1, i, pd) // V = U1*I\n let j2v := addmod(j, mulmod(0x02, v, pd), pd)\n if lt(r1, j2v) {\n r1 := add(pd, r1) // X3 = X3+pd\n }\n r1 := sub(r1, j2v)\n\n // Y3 = r*(V-X3)-2*S1*J\n let s12j := mulmod(mulmod(0x02, s1, pd), j, pd)\n\n if lt(v, r1) {\n v := add(pd, v)\n }\n r2 := mulmod(rr, sub(v, r1), pd)\n\n if lt(r2, s12j) {\n r2 := add(pd, r2)\n }\n r2 := sub(r2, s12j)\n\n // Z3 = ((Z1+Z2)^2-Z1Z1-Z2Z2)*H\n z1z1 := addmod(z1z1, z2z2, pd)\n j2v := mulmod(p3q3, p3q3, pd)\n if lt(j2v, z1z1) {\n j2v := add(pd, j2v)\n }\n r3 := mulmod(sub(j2v, z1z1), h, pd)\n }\n return (r1, r2, r3);\n }\n\n // Point doubling on the modified jacobian coordinates\n // http://point-at-infinity.org/ecc/Prime_Curve_Modified_Jacobian_Coordinates.html\n function _modifiedJacobianDouble(\n uint x,\n uint y,\n uint z\n ) internal pure returns (uint x3, uint y3, uint z3) {\n if (y == 0) return (0, 0, 0);\n assembly {\n let\n pd\n := 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\n let z2 := mulmod(z, z, pd)\n let az4 := mulmod(\n 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC,\n mulmod(z2, z2, pd),\n pd\n )\n let y2 := mulmod(y, y, pd)\n let s := mulmod(0x04, mulmod(x, y2, pd), pd)\n let u := mulmod(0x08, mulmod(y2, y2, pd), pd)\n let m := addmod(mulmod(0x03, mulmod(x, x, pd), pd), az4, pd)\n let twos := mulmod(0x02, s, pd)\n let m2 := mulmod(m, m, pd)\n if lt(m2, twos) {\n m2 := add(pd, m2)\n }\n x3 := sub(m2, twos)\n if lt(s, x3) {\n s := add(pd, s)\n }\n y3 := mulmod(m, sub(s, x3), pd)\n if lt(y3, u) {\n y3 := add(pd, y3)\n }\n y3 := sub(y3, u)\n z3 := mulmod(0x02, mulmod(y, z, pd), pd)\n }\n }\n\n // Fermats little theorem https://en.wikipedia.org/wiki/Fermat%27s_little_theorem\n // a^(p-1) = 1 mod p\n // a^(-1) ≅ a^(p-2) (mod p)\n // we then use the precompile bigModExp to compute a^(-1)\n function _primemod(uint value, uint p) internal view returns (uint ret) {\n ret = modexp(value, p - 2, p);\n return ret;\n }\n\n // Wrapper for built-in BigNumber_modexp (contract 0x5) as described here. https://github.com/ethereum/EIPs/pull/198\n function modexp(\n uint _base,\n uint _exp,\n uint _mod\n ) internal view returns (uint ret) {\n // bigModExp(_base, _exp, _mod);\n assembly {\n if gt(_base, _mod) {\n _base := mod(_base, _mod)\n }\n // Free memory pointer is always stored at 0x40\n let freemem := mload(0x40)\n\n mstore(freemem, 0x20)\n mstore(add(freemem, 0x20), 0x20)\n mstore(add(freemem, 0x40), 0x20)\n\n mstore(add(freemem, 0x60), _base)\n mstore(add(freemem, 0x80), _exp)\n mstore(add(freemem, 0xa0), _mod)\n\n let success := staticcall(14000, 0x5, freemem, 0xc0, freemem, 0x20)\n switch success\n case 0 {\n revert(0x0, 0x0)\n }\n default {\n ret := mload(freemem)\n }\n }\n }\n}\n" + }, + "contracts/infrastructure/DefaultFallbackHandler.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IERC721Receiver} from \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport {IERC1155Receiver} from \"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\";\nimport {IERC777Recipient} from \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport {BaseAccount} from \"../aa-4337/core/BaseAccount.sol\";\nimport {DefaultLibDiamond} from \"../libraries/DefaultLibDiamond.sol\";\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IAccountFacet} from \"../facets/interfaces/IAccountFacet.sol\";\nimport {IStorageLoupe} from \"../facets/base/interfaces/IStorageLoupe.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IERC677Receiver} from \"../interfaces/ERC/IERC677Receiver.sol\";\nimport {IERC165} from \"../interfaces/ERC/IERC165.sol\";\n\n/**\n * @title DefaultFallbackHandler\n * @dev A default fallback handler for Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract DefaultFallbackHandler is IDiamondLoupe {\n /**\n * @notice Sets the middleware diamond for Barz wallet as a fallback handler\n * @dev This contract is also a diamond that holds the default facets to reduce gas cost for wallet activation.\n * Within the constructor this conducts diamond cut to initially setup the diamond. This is a non-upgradeable contract\n * @param _diamondCutFacet Address if diamond cut facet\n * @param _accountFacet Address account facet\n * @param _tokenReceiverFacet Address of token receiver facet\n * @param _diamondLoupeFacet Address of diamond loupe facet\n */\n constructor(\n address _diamondCutFacet,\n address _accountFacet,\n address _tokenReceiverFacet,\n address _diamondLoupeFacet\n ) payable {\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](4);\n bytes4[] memory functionSelectors = new bytes4[](1);\n functionSelectors[0] = IDiamondCut.diamondCut.selector;\n\n bytes4[] memory accountFunctionSelectors = new bytes4[](5);\n accountFunctionSelectors[0] = IAccountFacet.execute.selector;\n accountFunctionSelectors[1] = IAccountFacet.executeBatch.selector;\n accountFunctionSelectors[2] = BaseAccount.validateUserOp.selector;\n accountFunctionSelectors[3] = BaseAccount.getNonce.selector;\n accountFunctionSelectors[4] = BaseAccount.entryPoint.selector;\n\n bytes4[] memory receiverFacetSelectors = new bytes4[](5);\n receiverFacetSelectors[0] = IERC721Receiver.onERC721Received.selector;\n receiverFacetSelectors[1] = IERC1155Receiver.onERC1155Received.selector;\n receiverFacetSelectors[2] = IERC1155Receiver\n .onERC1155BatchReceived\n .selector;\n receiverFacetSelectors[3] = IERC777Recipient.tokensReceived.selector;\n receiverFacetSelectors[4] = IERC677Receiver.onTokenTransfer.selector;\n\n bytes4[] memory loupeFacetSelectors = new bytes4[](9);\n loupeFacetSelectors[0] = IDiamondLoupe.facets.selector;\n loupeFacetSelectors[1] = IDiamondLoupe.facetFunctionSelectors.selector;\n loupeFacetSelectors[2] = IDiamondLoupe.facetAddresses.selector;\n loupeFacetSelectors[3] = IDiamondLoupe.facetAddress.selector;\n loupeFacetSelectors[4] = IERC165.supportsInterface.selector;\n loupeFacetSelectors[5] = IStorageLoupe.facetsFromStorage.selector;\n loupeFacetSelectors[6] = IStorageLoupe\n .facetFunctionSelectorsFromStorage\n .selector;\n loupeFacetSelectors[7] = IStorageLoupe\n .facetAddressesFromStorage\n .selector;\n loupeFacetSelectors[8] = IStorageLoupe.facetAddressFromStorage.selector;\n\n {\n cut[0] = IDiamondCut.FacetCut({\n facetAddress: _diamondCutFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: functionSelectors\n });\n cut[1] = IDiamondCut.FacetCut({\n facetAddress: _accountFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: accountFunctionSelectors\n });\n cut[2] = IDiamondCut.FacetCut({\n facetAddress: _tokenReceiverFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: receiverFacetSelectors\n });\n cut[3] = IDiamondCut.FacetCut({\n facetAddress: _diamondLoupeFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: loupeFacetSelectors\n });\n\n DefaultLibDiamond.diamondCut(cut, address(0), \"\");\n }\n }\n\n /**\n * @notice Returns the facet information of call facets registered to this diamond.\n * @return facets_ The facet struct array including all facet information\n */\n function facets() external view override returns (Facet[] memory facets_) {\n DefaultLibDiamond.DiamondStorage storage ds = DefaultLibDiamond\n .diamondStorage();\n uint256 numFacets = ds.facetAddresses.length;\n facets_ = new Facet[](numFacets);\n for (uint256 i; i < numFacets; ) {\n address facetAddress_ = ds.facetAddresses[i];\n facets_[i].facetAddress = facetAddress_;\n facets_[i].functionSelectors = ds\n .facetFunctionSelectors[facetAddress_]\n .functionSelectors;\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Gets all the function selectors provided by a facet.\n * @param _facet The facet address.\n * @return facetFunctionSelectors_\n */\n function facetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n facetFunctionSelectors_ = DefaultLibDiamond\n .diamondStorage()\n .facetFunctionSelectors[_facet]\n .functionSelectors;\n }\n\n /**\n * @notice Get all the facet addresses used by a diamond.\n * @return facetAddresses_\n */\n function facetAddresses()\n external\n view\n override\n returns (address[] memory facetAddresses_)\n {\n facetAddresses_ = DefaultLibDiamond.diamondStorage().facetAddresses;\n }\n\n /** @notice Gets the facet that supports the given selector.\n * @dev If facet is not found return address(0).\n * @param _functionSelector The function selector.\n * @return facetAddress_ The facet address.\n */\n function facetAddress(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n facetAddress_ = DefaultLibDiamond\n .diamondStorage()\n .selectorToFacetAndPosition[_functionSelector]\n .facetAddress;\n }\n}\n" + }, + "contracts/infrastructure/FacetRegistry.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport {IFacetRegistry} from \"./interfaces/IFacetRegistry.sol\";\n\n/**\n * @title Facet Registry\n * @dev Contract to keep track of facets & function selectors addable to user wallets\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract FacetRegistry is IFacetRegistry, Ownable2Step {\n mapping(address => FacetRegistryConfig) private facets;\n\n /**\n * @notice Transfers the ownership of the contract to the given owner\n * @param _owner Address of owner who has access to initialize the default security variables for security manager\n */\n constructor(address _owner) {\n transferOwnership(_owner);\n _transferOwnership(_owner);\n }\n\n /**\n * @dev Registers a facet and it's function selectors to registry\n * @param _facet address of facet\n * @param _facetSelectors list of function selectors of the facet\n */\n function registerFacetFunctionSelectors(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external override onlyOwner {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n for (uint256 i; i < _facetSelectors.length; ) {\n if (facetConfig.info[_facetSelectors[i]].exists)\n revert FacetRegistry__FacetSelectorAlreadyRegistered();\n\n facetConfig.info[_facetSelectors[i]].exists = true;\n facetConfig.info[_facetSelectors[i]].index = uint128(\n facetConfig.selectors.length\n );\n facetConfig.selectors.push(_facetSelectors[i]);\n unchecked {\n ++i;\n }\n }\n emit FacetFunctionSelectorsRegistered(_facet, _facetSelectors);\n }\n\n /**\n * @dev Removes a registered facet and it's corresponding selectors from registry\n * @param _facet address of facet\n * @param _facetSelectors list of function selectors of the facet\n */\n function removeFacetFunctionSelectors(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external override onlyOwner {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n for (uint256 i; i < _facetSelectors.length; ) {\n if (!facetConfig.info[_facetSelectors[i]].exists)\n revert FacetRegistry__UnregisteredFacetSelector();\n\n bytes4 lastSelector = facetConfig.selectors[\n facetConfig.selectors.length - 1\n ];\n if (_facetSelectors[i] != lastSelector) {\n uint128 targetIndex = facetConfig\n .info[_facetSelectors[i]]\n .index;\n facetConfig.selectors[targetIndex] = lastSelector;\n facetConfig.info[lastSelector].index = targetIndex;\n }\n facetConfig.selectors.pop();\n delete facetConfig.info[_facetSelectors[i]];\n\n unchecked {\n ++i;\n }\n }\n emit FacetFunctionSelectorsRemoved(_facet, _facetSelectors);\n }\n\n /**\n * @dev Checks if a facet and it's selectors given is registered to facet registry\n * @param _facet Address of facet\n * @param _facetSelectors List of function selectors of the facet\n */\n function areFacetFunctionSelectorsRegistered(\n address _facet,\n bytes4[] calldata _facetSelectors\n ) external view override returns (bool) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n if (_facetSelectors.length == 0) return false;\n for (uint256 i; i < _facetSelectors.length; ) {\n if (!facetConfig.info[_facetSelectors[i]].exists) return false;\n unchecked {\n ++i;\n }\n }\n return true;\n }\n\n /**\n * @dev Checks if a facet and it's selector given is registered to facet registry\n * @param _facet Address of facet\n * @param _facetSelector List of function selectors of the facet\n * @return isRegistered Bool value showing if the selector is registered\n */\n function isFacetFunctionSelectorRegistered(\n address _facet,\n bytes4 _facetSelector\n ) external view override returns (bool isRegistered) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n isRegistered = facetConfig.info[_facetSelector].exists;\n }\n\n /**\n * @dev Get the registered selectors of facet from registry\n * @param _facet Address of facet\n * @return selectors Selectors registered to facet\n */\n function getFacetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory selectors) {\n FacetRegistryConfig storage facetConfig = facets[_facet];\n selectors = facetConfig.selectors;\n }\n}\n" + }, + "contracts/infrastructure/interfaces/IFacetRegistry.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Registry Interface\n * @dev Interface for Facet Registry contract to keep track of facets & function selectors addable to user wallets\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IFacetRegistry {\n struct FacetRegistryConfig {\n bytes4[] selectors;\n mapping(bytes4 => FacetInfo) info;\n }\n struct FacetInfo {\n bool exists;\n uint128 index;\n }\n\n event FacetFunctionSelectorsRegistered(\n address facet,\n bytes4[] facetSelectors\n );\n event FacetFunctionSelectorsRemoved(address facet, bytes4[] facetSelectors);\n\n error FacetRegistry__FacetSelectorAlreadyRegistered();\n error FacetRegistry__UnregisteredFacetSelector();\n\n function registerFacetFunctionSelectors(\n address facet,\n bytes4[] calldata facetSelectors\n ) external;\n\n function removeFacetFunctionSelectors(\n address facet,\n bytes4[] calldata facetSelectors\n ) external;\n\n function areFacetFunctionSelectorsRegistered(\n address facet,\n bytes4[] calldata facetSelectors\n ) external view returns (bool);\n\n function isFacetFunctionSelectorRegistered(\n address facet,\n bytes4 facetSelector\n ) external view returns (bool);\n\n function getFacetFunctionSelectors(\n address facet\n ) external view returns (bytes4[] memory);\n}\n" + }, + "contracts/infrastructure/interfaces/ISecurityManager.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Registry Interface\n * @dev Infrastructure contract to manage security parameters of users\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface ISecurityManager {\n error SecurityManager__OutOfBoundary();\n error SecurityManager__CallerNotWallet();\n error SecurityManager__AlreadyIntialized();\n\n function initializeAdditionSecurityPeriod(\n uint128 defaultAdditionSecurityPeriod,\n uint128 minAdditionSecurityPeriod,\n uint128 maxAdditionSecurityPeriod\n ) external;\n\n function initializeRemovalSecurityPeriod(\n uint128 defaultRemovalSecurityPeriod,\n uint128 minRemovalSecurityPeriod,\n uint128 maxRemovalSecurityPeriod\n ) external;\n\n function initializeApprovalValidationPeriod(\n uint128 defaultApprovalValidationPeriod,\n uint128 minApprovalValidationPeriod,\n uint128 maxApprovalValidationPeriod\n ) external;\n\n function initializeMigrationPeriod(\n uint128 defaultMigrationPeriod,\n uint128 minMigrationPeriod,\n uint128 maxMigrationPeriod\n ) external;\n\n function initializeLockPeriod(\n uint128 defaultLockPeriod,\n uint128 minLockPeriod,\n uint128 maxLockPeriod\n ) external;\n\n function initializeRecoveryPeriod(\n uint128 defaultRecoveryPeriod,\n uint128 minRecoveryPeriod,\n uint128 maxRecoveryPeriod\n ) external;\n\n function initializeSecurityWindow(\n uint128 defaultSecurityWindow,\n uint128 minSecurityWindow,\n uint128 maxSecurityWindow\n ) external;\n\n function setAdditionSecurityPeriod(\n address wallet,\n uint128 additionSecurityPeriod\n ) external;\n\n function setRemovalSecurityPeriod(\n address wallet,\n uint128 removalSecurityPeriod\n ) external;\n\n function setSecurityWindow(address wallet, uint128 securityWindow) external;\n\n function setRecoveryPeriod(address wallet, uint128 recoveryPeriod) external;\n\n function setLockPeriod(address wallet, uint128 lockPeriod) external;\n\n function setApprovalValidationPeriod(\n address wallet,\n uint128 approvalValidationPeriod\n ) external;\n\n function setMigrationPeriod(\n address wallet,\n uint128 migrationPeriod\n ) external;\n\n function additionSecurityPeriodOf(\n address wallet\n ) external view returns (uint128);\n\n function removalSecurityPeriodOf(\n address wallet\n ) external view returns (uint128);\n\n function securityWindowOf(address wallet) external view returns (uint128);\n\n function recoveryPeriodOf(address wallet) external view returns (uint128);\n\n function lockPeriodOf(address wallet) external view returns (uint128);\n\n function migrationPeriodOf(address wallet) external view returns (uint128);\n\n function approvalValidationPeriodOf(\n address wallet\n ) external view returns (uint128);\n}\n" + }, + "contracts/infrastructure/RemoteStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {IGuardianFacet} from \"../facets/interfaces/IGuardianFacet.sol\";\n\n/**\n * @title Remote Storage\n * @dev Remote storage allows you to associate addresses with an array of addresses on a standalone smart contract.\n * This could be useful when you don't want to use the local diamond storage for some purpose.\n * @author Ruslan Serebriakov (@rsrbk)\n * @author David Yongjun Kim (@Powerstream3604)\n */\nabstract contract RemoteStorage {\n struct StorageConfig {\n address[] addresses;\n mapping(address => Info) info;\n }\n\n struct Info {\n bool exists;\n uint128 index;\n }\n\n mapping(address => StorageConfig) internal configs;\n\n event Added(address _address);\n event Removed(address _address);\n\n error RemoteStorage__CallerNotOwner();\n error RemoteStorage__CallerNotGuardianOrOwner();\n error RemoteStorage__AlreadyExists();\n error RemoteStorage__NotFound();\n error RemoteStorage__CallerNotGuardian();\n\n bytes4 constant IS_GUARDIAN_SELECTOR =\n bytes4(keccak256(\"isGuardian(address)\"));\n bytes4 constant GUARDIAN_COUNT = bytes4(keccak256(\"guardianCount()\"));\n\n /**\n * @notice Modifier to only allow the self to call. Reverts otherwise\n */\n modifier onlyWallet(address _wallet) {\n if (msg.sender != _wallet) revert RemoteStorage__CallerNotOwner();\n _;\n }\n\n /**\n * @notice Enfore the callet to be wallet of guardian of the wallet\n * @param _wallet Address of wallet\n */\n function enforceGuardianOrWallet(address _wallet) internal view {\n if (msg.sender == _wallet) return;\n address facetAddress = IDiamondLoupe(_wallet).facetAddress(\n IS_GUARDIAN_SELECTOR\n );\n if (facetAddress != address(0))\n if (IGuardianFacet(_wallet).isGuardian(msg.sender)) return;\n revert RemoteStorage__CallerNotGuardianOrOwner();\n }\n\n /**\n * @notice Enforce the caller to be wallet IF guardians doesn't exists and only guardian when guardians exists\n * @param _wallet Target wallet address to be handled by infrastructure contracts\n */\n function enforceWalletOrGuardianIfExists(address _wallet) internal view {\n address facetAddress;\n if (msg.sender == _wallet) {\n facetAddress = IDiamondLoupe(_wallet).facetAddress(GUARDIAN_COUNT);\n if (facetAddress == address(0)) return;\n uint256 guardianCount = IGuardianFacet(_wallet).guardianCount();\n if (guardianCount != 0) revert RemoteStorage__CallerNotGuardian();\n return;\n }\n facetAddress = IDiamondLoupe(_wallet).facetAddress(\n IS_GUARDIAN_SELECTOR\n );\n if (facetAddress != address(0))\n if (IGuardianFacet(_wallet).isGuardian(msg.sender)) return;\n\n revert RemoteStorage__CallerNotGuardianOrOwner();\n }\n\n /**\n * @notice Add address to storage and reverts if the address already exists.\n * This is an internal function callable from contracts that inherit this abstract contract\n * @param _wallet Address of wallet to add the address\n * @param _address Address to be added to wallet\n */\n function addAddress(address _wallet, address _address) internal {\n StorageConfig storage config = configs[_wallet];\n if (config.info[_address].exists) revert RemoteStorage__AlreadyExists();\n\n config.info[_address].exists = true;\n config.info[_address].index = uint128(config.addresses.length);\n config.addresses.push(_address);\n\n emit Added(_address);\n }\n\n /**\n * @notice Remove address from storage and reverts if the address already exists.\n * This is an internal function callable from contracts that inherit this abstract contract\n * @param _wallet Address of wallet to remove the address\n * @param _address Address to be removed from wallet\n */\n function removeAddress(address _wallet, address _address) internal {\n StorageConfig storage config = configs[_wallet];\n if (!config.info[_address].exists) revert RemoteStorage__NotFound();\n\n address lastAddress = config.addresses[config.addresses.length - 1];\n if (_address != lastAddress) {\n uint128 targetIndex = config.info[_address].index;\n config.addresses[targetIndex] = lastAddress;\n config.info[lastAddress].index = targetIndex;\n }\n config.addresses.pop();\n delete config.info[_address];\n\n emit Removed(_address);\n }\n\n /**\n * @notice Returns the address added to the given wallet\n * @param _wallet Address of wallet to fetch the addresses added to it\n * @return addresses List of addresses added to the wallet\n */\n function getAddresses(\n address _wallet\n ) internal view returns (address[] memory addresses) {\n StorageConfig storage config = configs[_wallet];\n addresses = new address[](config.addresses.length);\n uint addressesLen = config.addresses.length;\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice Returns bool value checking if the address exists in the given wallet address\n * @param _wallet Wallet address to check\n * @param _address Address to fetch if the address if added to given wallet\n * @return exists_ Bool value showing if the address exists in wallet\n */\n function exists(\n address _wallet,\n address _address\n ) internal view returns (bool exists_) {\n exists_ = configs[_wallet].info[_address].exists;\n }\n\n /**\n * @notice Returns the number of addresses added to the wallet\n * @param _wallet Address of wallet to check\n * @return count_ Number of addresses added to wallet\n */\n function count(address _wallet) internal view returns (uint256 count_) {\n count_ = configs[_wallet].addresses.length;\n }\n}\n" + }, + "contracts/infrastructure/SecurityManager.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport {ISecurityManager} from \"./interfaces/ISecurityManager.sol\";\n\n/**\n * @title Security Manager\n * @dev Infrastructure contract to manage security parameters of users\n * @author David Yongjun Kim (@Powerstream3604)\n */\ncontract SecurityManager is ISecurityManager, Ownable2Step {\n uint128 public minAdditionSecurityPeriod;\n uint128 public maxAdditionSecurityPeriod;\n uint128 private defaultAdditionSecurityPeriod;\n\n uint128 public minRemovalSecurityPeriod;\n uint128 public maxRemovalSecurityPeriod;\n uint128 private defaultRemovalSecurityPeriod;\n\n uint128 public minSecurityWindow;\n uint128 public maxSecurityWindow;\n uint128 private defaultSecurityWindow;\n\n uint128 public minRecoveryPeriod;\n uint128 public maxRecoveryPeriod;\n uint128 private defaultRecoveryPeriod;\n\n uint128 public minLockPeriod;\n uint128 public maxLockPeriod;\n uint128 private defaultLockPeriod;\n\n uint128 public minApprovalValidationPeriod;\n uint128 public maxApprovalValidationPeriod;\n uint128 private defaultApprovalValidationPeriod;\n\n uint128 public minMigrationPeriod;\n uint128 public maxMigrationPeriod;\n uint128 private defaultMigrationPeriod;\n\n bool public _isAdditionSecurityPeriodInitialized;\n bool public _isRemovalSecurityPeriodInitialized;\n bool public _isSecurityWindowInitialized;\n bool public _isRecoveryPeriodInitialized;\n bool public _isLockPeriodInitialized;\n bool public _isApprovalValidationPeriodInitialized;\n bool public _isMigrationPeriodInitialized;\n\n mapping(address => CustomSecurityConfig) securityConfigs;\n\n struct CustomSecurityConfig {\n uint128 additionSecurityPeriod;\n uint128 removalSecurityPeriod;\n uint128 securityWindow;\n uint128 recoveryPeriod;\n uint128 lockPeriod;\n uint128 approvalValidationPeriod;\n uint128 migrationPeriod;\n }\n\n /**\n * @notice Modifier to only allow wallet itself to make a call to wallet\n */\n modifier onlyWallet(address _wallet) {\n if (msg.sender != _wallet) revert SecurityManager__CallerNotWallet();\n _;\n }\n\n /**\n * @notice Modifier to revert if the variable is already initialized\n */\n modifier initializer(bool _isInitialized) {\n if (_isInitialized) revert SecurityManager__AlreadyIntialized();\n _;\n }\n\n /**\n * @notice Transfers the ownership of the contract to the given owner\n * @param _owner Address of owner who has access to initialize the default security variables for security manager\n */\n constructor(address _owner) {\n transferOwnership(_owner);\n _transferOwnership(_owner);\n }\n\n /**\n * @notice Sets the initial default/min/max addition security period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultAdditionSecurityPeriod Default Addition Security Period for all Barz contracts\n * @param _minAdditionSecurityPeriod Minimum Addition Security Period for all Barz contracts\n * @param _maxAdditionSecurityPeriod Maximum Addition Security Period for all Barz contracts\n */\n function initializeAdditionSecurityPeriod(\n uint128 _defaultAdditionSecurityPeriod,\n uint128 _minAdditionSecurityPeriod,\n uint128 _maxAdditionSecurityPeriod\n )\n external\n override\n onlyOwner\n initializer(_isAdditionSecurityPeriodInitialized)\n {\n _isAdditionSecurityPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultAdditionSecurityPeriod,\n _minAdditionSecurityPeriod,\n _maxAdditionSecurityPeriod\n );\n defaultAdditionSecurityPeriod = _defaultAdditionSecurityPeriod;\n minAdditionSecurityPeriod = _minAdditionSecurityPeriod;\n maxAdditionSecurityPeriod = _maxAdditionSecurityPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max removal security period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultRemovalSecurityPeriod Default Removal Security Period for all Barz contracts\n * @param _minRemovalSecurityPeriod Minimum Removal Security Period for all Barz contracts\n * @param _maxRemovalSecurityPeriod Maximum Removal Security Period for all Barz contracts\n */\n function initializeRemovalSecurityPeriod(\n uint128 _defaultRemovalSecurityPeriod,\n uint128 _minRemovalSecurityPeriod,\n uint128 _maxRemovalSecurityPeriod\n )\n external\n override\n onlyOwner\n initializer(_isRemovalSecurityPeriodInitialized)\n {\n _isRemovalSecurityPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultRemovalSecurityPeriod,\n _minRemovalSecurityPeriod,\n _maxRemovalSecurityPeriod\n );\n defaultRemovalSecurityPeriod = _defaultRemovalSecurityPeriod;\n minRemovalSecurityPeriod = _minRemovalSecurityPeriod;\n maxRemovalSecurityPeriod = _maxRemovalSecurityPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/maxd security window for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultSecurityWindow Default Security Window for all Barz contracts\n * @param _minSecurityWindow Minimum Security Window for all Barz contracts\n * @param _maxSecurityWindow Maximum Security Window for all Barz contracts\n */\n function initializeSecurityWindow(\n uint128 _defaultSecurityWindow,\n uint128 _minSecurityWindow,\n uint128 _maxSecurityWindow\n ) external override onlyOwner initializer(_isSecurityWindowInitialized) {\n _isSecurityWindowInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultSecurityWindow,\n _minSecurityWindow,\n _maxSecurityWindow\n );\n defaultSecurityWindow = _defaultSecurityWindow;\n minSecurityWindow = _minSecurityWindow;\n maxSecurityWindow = _maxSecurityWindow;\n }\n\n /**\n * @notice Sets the initial default/min/max recovery period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultRecoveryPeriod Default Recovery Period for all Barz contracts\n * @param _minRecoveryPeriod Minimum Recovery Period for all Barz contracts\n * @param _maxRecoveryPeriod Maximum Recovery Period for all Barz contracts\n */\n function initializeRecoveryPeriod(\n uint128 _defaultRecoveryPeriod,\n uint128 _minRecoveryPeriod,\n uint128 _maxRecoveryPeriod\n ) external override onlyOwner initializer(_isRecoveryPeriodInitialized) {\n _isRecoveryPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultRecoveryPeriod,\n _minRecoveryPeriod,\n _maxRecoveryPeriod\n );\n defaultRecoveryPeriod = _defaultRecoveryPeriod;\n minRecoveryPeriod = _minRecoveryPeriod;\n maxRecoveryPeriod = _maxRecoveryPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max lock period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultLockPeriod Default Lock Period for all Barz contracts\n * @param _minLockPeriod Minimum Lock Period for all Barz contracts\n * @param _maxLockPeriod Maximum Lock Period for all Barz contracts\n */\n function initializeLockPeriod(\n uint128 _defaultLockPeriod,\n uint128 _minLockPeriod,\n uint128 _maxLockPeriod\n ) external override onlyOwner initializer(_isLockPeriodInitialized) {\n _isLockPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultLockPeriod,\n _minLockPeriod,\n _maxLockPeriod\n );\n defaultLockPeriod = _defaultLockPeriod;\n minLockPeriod = _minLockPeriod;\n maxLockPeriod = _maxLockPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max approval validation period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultApprovalValidationPeriod Default Approval Validation Period for all Barz contracts\n * @param _minApprovalValidationPeriod Minimum Approval Validation Period for all Barz contracts\n * @param _maxApprovalValidationPeriod Maximum Approval Validation Period for all Barz contracts\n */\n function initializeApprovalValidationPeriod(\n uint128 _defaultApprovalValidationPeriod,\n uint128 _minApprovalValidationPeriod,\n uint128 _maxApprovalValidationPeriod\n )\n external\n override\n onlyOwner\n initializer(_isApprovalValidationPeriodInitialized)\n {\n _isApprovalValidationPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultApprovalValidationPeriod,\n _minApprovalValidationPeriod,\n _maxApprovalValidationPeriod\n );\n defaultApprovalValidationPeriod = _defaultApprovalValidationPeriod;\n minApprovalValidationPeriod = _minApprovalValidationPeriod;\n maxApprovalValidationPeriod = _maxApprovalValidationPeriod;\n }\n\n /**\n * @notice Sets the initial default/min/max migration period for all Barz contracts that use this as Security Manager\n * This function can only be called by the owner of the SecurityManager\n * Default value should be bigger than the min and smaller than the max\n * @param _defaultMigrationPeriod Default Migration Period for all Barz contracts\n * @param _minMigrationPeriod Minimum Migration Period for all Barz contracts\n * @param _maxMigrationPeriod Maximum Migration Period for all Barz contracts\n */\n function initializeMigrationPeriod(\n uint128 _defaultMigrationPeriod,\n uint128 _minMigrationPeriod,\n uint128 _maxMigrationPeriod\n ) external override onlyOwner initializer(_isMigrationPeriodInitialized) {\n _isMigrationPeriodInitialized = true;\n\n _validatePeriodBoundaries(\n _defaultMigrationPeriod,\n _minMigrationPeriod,\n _maxMigrationPeriod\n );\n defaultMigrationPeriod = _defaultMigrationPeriod;\n minMigrationPeriod = _minMigrationPeriod;\n maxMigrationPeriod = _maxMigrationPeriod;\n }\n\n /**\n * @notice Wallet owner sets the addition security period for the wallet. Only the owner of wallet can call this function.\n * The addition security period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _additionSecurityPeriod Custom Addition Security Period for the wallet\n */\n function setAdditionSecurityPeriod(\n address _wallet,\n uint128 _additionSecurityPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _additionSecurityPeriod,\n minAdditionSecurityPeriod,\n maxAdditionSecurityPeriod\n );\n securityConfigs[_wallet]\n .additionSecurityPeriod = _additionSecurityPeriod;\n }\n\n /**\n * @notice Wallet owner sets the removal security period for the wallet. Only the owner of wallet can call this function.\n * The removal security period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _removalSecurityPeriod Custom Removal Security Period for the wallet\n */\n function setRemovalSecurityPeriod(\n address _wallet,\n uint128 _removalSecurityPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _removalSecurityPeriod,\n minRemovalSecurityPeriod,\n maxRemovalSecurityPeriod\n );\n securityConfigs[_wallet].removalSecurityPeriod = _removalSecurityPeriod;\n }\n\n /**\n * @notice Wallet owner sets the security window for the wallet. Only the owner of wallet can call this function.\n * The security window should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _securityWindow Custom Security Window for the wallet\n */\n function setSecurityWindow(\n address _wallet,\n uint128 _securityWindow\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _securityWindow,\n minSecurityWindow,\n maxSecurityWindow\n );\n securityConfigs[_wallet].securityWindow = _securityWindow;\n }\n\n /**\n * @notice Wallet owner sets the recovery period for the wallet. Only the owner of wallet can call this function.\n * The recovery period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _recoveryPeriod Custom recovery period for the wallet\n */\n function setRecoveryPeriod(\n address _wallet,\n uint128 _recoveryPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _recoveryPeriod,\n minRecoveryPeriod,\n maxRecoveryPeriod\n );\n securityConfigs[_wallet].recoveryPeriod = _recoveryPeriod;\n }\n\n /**\n * @notice Wallet owner sets the lock period for the wallet. Only the owner of wallet can call this function.\n * The lock period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _lockPeriod Custom Lock period for the wallet\n */\n function setLockPeriod(\n address _wallet,\n uint128 _lockPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(_lockPeriod, minLockPeriod, maxLockPeriod);\n securityConfigs[_wallet].lockPeriod = _lockPeriod;\n }\n\n /**\n * @notice Wallet owner sets the approval validation period for the wallet. Only the owner of wallet can call this function.\n * The approval validation period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _approvalValidationPeriod Custom approval validation period for the wallet\n */\n function setApprovalValidationPeriod(\n address _wallet,\n uint128 _approvalValidationPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _approvalValidationPeriod,\n minApprovalValidationPeriod,\n maxApprovalValidationPeriod\n );\n securityConfigs[_wallet]\n .approvalValidationPeriod = _approvalValidationPeriod;\n }\n\n /**\n * @notice Wallet owner sets the migration period for the wallet. Only the owner of wallet can call this function.\n * The migration period should be within the boundry of min and max value set by the owner\n * @param _wallet Address of wallet\n * @param _migrationPeriod Custom migration period for the wallet\n */\n\n function setMigrationPeriod(\n address _wallet,\n uint128 _migrationPeriod\n ) external override onlyWallet(_wallet) {\n _validatePeriodBoundaries(\n _migrationPeriod,\n minMigrationPeriod,\n maxMigrationPeriod\n );\n securityConfigs[_wallet].migrationPeriod = _migrationPeriod;\n }\n\n /**\n * @notice Returns the addition security period. Returns default value when custom addition security period is not set\n * @param _wallet Address of wallet\n * @return additionSecurityPeriod Addition Security Period of the given Barz account or wallet\n */\n function additionSecurityPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 additionSecurityPeriod)\n {\n additionSecurityPeriod = securityConfigs[_wallet]\n .additionSecurityPeriod;\n additionSecurityPeriod = (additionSecurityPeriod == 0)\n ? defaultAdditionSecurityPeriod\n : additionSecurityPeriod;\n }\n\n /**\n * @notice Returns the removal security period. Returns default value when custom removal security period is not set\n * @param _wallet Address of wallet\n * @return removalSecurityPeriod Removal Security Period of the given Barz account or wallet\n */\n function removalSecurityPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 removalSecurityPeriod)\n {\n removalSecurityPeriod = securityConfigs[_wallet].removalSecurityPeriod;\n removalSecurityPeriod = (removalSecurityPeriod == 0)\n ? defaultRemovalSecurityPeriod\n : removalSecurityPeriod;\n }\n\n /**\n * @notice Returns the security window. Returns default value when custom security window is not set\n * @param _wallet Address of wallet\n * @return securityWindow Security window of the given Barz account or wallet\n */\n function securityWindowOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 securityWindow)\n {\n securityWindow = securityConfigs[_wallet].securityWindow;\n securityWindow = (securityWindow == 0)\n ? defaultSecurityWindow\n : securityWindow;\n }\n\n /**\n * @notice Returns the recovery period. Returns default value when custom recovery period is not set\n * @param _wallet Address of wallet\n * @return recoveryPeriod Recovery Period of the given Barz account or wallet\n */\n function recoveryPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 recoveryPeriod)\n {\n recoveryPeriod = securityConfigs[_wallet].recoveryPeriod;\n recoveryPeriod = (recoveryPeriod == 0)\n ? defaultRecoveryPeriod\n : recoveryPeriod;\n }\n\n /**\n * @notice Returns the lock period. Returns default value when custom lock period is not set\n * @param _wallet Address of wallet\n * @return lockPeriod Lock Period of the given Barz account or wallet\n */\n function lockPeriodOf(\n address _wallet\n ) public view override onlyWallet(_wallet) returns (uint128 lockPeriod) {\n lockPeriod = securityConfigs[_wallet].lockPeriod;\n lockPeriod = (lockPeriod == 0) ? defaultLockPeriod : lockPeriod;\n }\n\n /**\n * @notice Returns the approval validation period. Returns default value when custom approval validation period is not set\n * @param _wallet Address of wallet\n * @return approvalValidationPeriod Approval Validation Period of the given Barz account or wallet\n */\n function approvalValidationPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 approvalValidationPeriod)\n {\n approvalValidationPeriod = securityConfigs[_wallet]\n .approvalValidationPeriod;\n approvalValidationPeriod = (approvalValidationPeriod == 0)\n ? defaultApprovalValidationPeriod\n : approvalValidationPeriod;\n }\n\n /**\n * @notice Returns the migration period. Returns default value when custom migration period is not set\n * @param _wallet Address of wallet\n * @return migrationPeriod Migration Period of the given Barz account or wallet\n */\n function migrationPeriodOf(\n address _wallet\n )\n public\n view\n override\n onlyWallet(_wallet)\n returns (uint128 migrationPeriod)\n {\n migrationPeriod = securityConfigs[_wallet].migrationPeriod;\n migrationPeriod = (migrationPeriod == 0)\n ? defaultMigrationPeriod\n : migrationPeriod;\n }\n\n /**\n * @notice Validates if the period is smaller than the max period or bigger than the min period\n * @param _period Period to be checked\n * @param _minPeriod Minimum period\n * @param _maxPeriod Maximum period\n */\n function _validatePeriodBoundaries(\n uint128 _period,\n uint128 _minPeriod,\n uint128 _maxPeriod\n ) internal pure {\n if (_period >= _maxPeriod || _period <= _minPeriod)\n revert SecurityManager__OutOfBoundary();\n }\n}\n" + }, + "contracts/infrastructure/WhitelistStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {RemoteStorage} from \"./RemoteStorage.sol\";\n\n/**\n * @title Whitelist storage\n * @dev Maps addresses to the corresponsing array of whitelisted addresses for each of them.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract WhitelistStorage is RemoteStorage {\n /**\n * @dev Add the address to the whitelist storage\n * @param _wallet User wallet\n * @param _address Address to be whitelisted\n */\n function whitelistAddress(address _wallet, address _address) external {\n enforceWalletOrGuardianIfExists(_wallet);\n addAddress(_wallet, _address);\n }\n\n /**\n * @dev Removes the address from the whitelist storage\n * @param _wallet User wallet\n * @param _address Address to be removed from the whitelist\n */\n function blacklistAddress(address _wallet, address _address) external {\n enforceGuardianOrWallet(_wallet);\n removeAddress(_wallet, _address);\n }\n\n /**\n * @dev Returns whether the address exists in the whitelist storage, associated with the wallet\n * @param _wallet User wallet\n * @param _address Address to be whitelisted\n */\n function isWhitelisted(\n address _wallet,\n address _address\n ) external view returns (bool) {\n return exists(_wallet, _address);\n }\n\n /**\n * @dev Returns all whitelisted addresses associated with the wallet\n * @param _wallet User wallet\n */\n function getWhitelistedAddresses(\n address _wallet\n ) external view returns (address[] memory) {\n return getAddresses(_wallet);\n }\n}\n" + }, + "contracts/interfaces/ERC/IERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\n\npragma solidity 0.8.21;\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155Receiver {\n /**\n * @dev Handles the receipt of a single ERC1155 token type. This function is\n * called at the end of a `safeTransferFrom` after the balance has been updated.\n *\n * NOTE: To accept the transfer, this must return\n * `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n * (i.e. 0xf23a6e61, or its own function selector).\n *\n * @param operator The address which initiated the transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param id The ID of the token being transferred\n * @param value The amount of tokens being transferred\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n ) external returns (bytes4);\n\n /**\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\n * is called at the end of a `safeBatchTransferFrom` after the balances have\n * been updated.\n *\n * NOTE: To accept the transfer(s), this must return\n * `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n * (i.e. 0xbc197c81, or its own function selector).\n *\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "contracts/interfaces/ERC/IERC1271.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\ninterface IERC1271 {\n function isValidSignature(\n bytes32 hash,\n bytes memory signature\n ) external view returns (bytes4);\n}\n" + }, + "contracts/interfaces/ERC/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\ninterface IERC165 {\n /// @notice Query if a contract implements an interface\n /// @param interfaceId The interface identifier, as specified in ERC-165\n /// @dev Interface identification is specified in ERC-165. This function\n /// uses less than 30,000 gas.\n /// @return `true` if the contract implements `interfaceID` and\n /// `interfaceID` is not 0xffffffff, `false` otherwise\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/IERC173.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\n/// @title ERC-173 Contract Ownership Standard\n/// Note: the ERC-165 identifier for this interface is 0x7f5828d0\n/* is ERC165 */\ninterface IERC173 {\n /// @dev This emits when ownership of a contract changes.\n event OwnershipTransferred(\n address indexed previousOwner,\n address indexed newOwner\n );\n\n /// @notice Get the address of the owner\n /// @return owner_ The address of the owner.\n function owner() external view returns (address owner_);\n\n /// @notice Set the address of the new owner of the contract\n /// @dev Set _newOwner to address(0) to renounce any ownership.\n /// @param _newOwner The address of the new owner of the contract\n function transferOwnership(address _newOwner) external;\n}\n" + }, + "contracts/interfaces/ERC/IERC677Receiver.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\ninterface IERC677Receiver {\n function onTokenTransfer(\n address sender,\n uint value,\n bytes calldata data\n ) external pure returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155 is IERC165 {\n /**\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n */\n event TransferSingle(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256 id,\n uint256 value\n );\n\n /**\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n * transfers.\n */\n event TransferBatch(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\n\n /**\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n * `approved`.\n */\n event ApprovalForAll(\n address indexed account,\n address indexed operator,\n bool approved\n );\n\n /**\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n *\n * If an {URI} event was emitted for `id`, the standard\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n * returned by {IERC1155MetadataURI-uri}.\n */\n event URI(string value, uint256 indexed id);\n\n /**\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(\n address account,\n uint256 id\n ) external view returns (uint256);\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] calldata accounts,\n uint256[] calldata ids\n ) external view returns (uint256[] memory);\n\n /**\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n *\n * Emits an {ApprovalForAll} event.\n *\n * Requirements:\n *\n * - `operator` cannot be the caller.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n *\n * See {setApprovalForAll}.\n */\n function isApprovedForAll(\n address account,\n address operator\n ) external view returns (bool);\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes calldata data\n ) external;\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(\n address indexed owner,\n address indexed spender,\n uint256 value\n );\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` 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 amount) 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(\n address owner,\n address spender\n ) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the 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 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` 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(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(\n address spender,\n uint256 addedValue\n ) external returns (bool);\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(\n address spender,\n uint256 subtractedValue\n ) external returns (bool);\n}\n" + }, + "contracts/interfaces/ERC/Tokens/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(\n address indexed from,\n address indexed to,\n uint256 indexed tokenId\n );\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(\n address indexed owner,\n address indexed approved,\n uint256 indexed tokenId\n );\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(\n address indexed owner,\n address indexed operator,\n bool approved\n );\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(\n uint256 tokenId\n ) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(\n address owner,\n address operator\n ) external view returns (bool);\n}\n" + }, + "contracts/interfaces/IBarz.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Barz Interface\n * @dev Interface of Barz\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IBarz {\n error Barz__InitializationFailure();\n}\n" + }, + "contracts/interfaces/IBarzFactory.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {Barz} from \"../Barz.sol\";\n\n/**\n * @title Barz Factory Interface\n * @dev Interface of contract to easily deploy Barz to a pre-computed address with a single call\n * @author David Yongjun Kim (@Powerstream3604)\n */\ninterface IBarzFactory {\n event BarzDeployed(address);\n\n function createAccount(\n address verificationFacet,\n bytes calldata owner,\n uint256 salt\n ) external returns (Barz);\n\n function getAddress(\n address verificationFacet,\n bytes calldata owner,\n uint256 salt\n ) external view returns (address);\n\n function getBytecode(\n address accountFacet,\n address verificationFacet,\n address entryPoint,\n address facetRegistry,\n address defaultFallback,\n bytes memory ownerPublicKey\n ) external pure returns (bytes memory);\n\n function getCreationCode() external pure returns (bytes memory);\n}\n" + }, + "contracts/libraries/DefaultLibDiamond.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\n\nerror InitializationFunctionReverted(\n address _initializationContractAddress,\n bytes _calldata\n);\n\nlibrary DefaultLibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION =\n keccak256(\"trustwallet.barz.diamond.storage\");\n\n struct FacetAddressAndPosition {\n address facetAddress;\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\n }\n\n struct FacetFunctionSelectors {\n bytes4[] functionSelectors;\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\n }\n\n struct DiamondStorage {\n // maps function selector to the facet address and\n // the position of the selector in the facetFunctionSelectors.selectors array\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\n // maps facet addresses to function selectors\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\n // facet addresses\n address[] facetAddresses;\n // Used to query if a contract implements an interface.\n // Used to implement ERC-165.\n mapping(bytes4 => bool) supportedInterfaces;\n }\n\n function diamondStorage()\n internal\n pure\n returns (DiamondStorage storage ds)\n {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n event DiamondCut(\n IDiamondCut.FacetCut[] _diamondCut,\n address _init,\n bytes _calldata\n );\n\n // Internal function version of diamondCut\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n for (\n uint256 facetIndex;\n facetIndex < _diamondCut.length;\n facetIndex++\n ) {\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\n if (action == IDiamondCut.FacetCutAction.Add) {\n addFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\n replaceFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\n removeFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else {\n revert(\"LibDiamondCut: Incorrect FacetCutAction\");\n }\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Add facet can't be address(0)\"\n );\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n require(\n oldFacetAddress == address(0),\n \"LibDiamondCut: Can't add function that already exists\"\n );\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function replaceFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Replace facet can't be address(0)\"\n );\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n require(\n oldFacetAddress != _facetAddress,\n \"LibDiamondCut: Can't replace function with same facet\"\n );\n removeFunction(ds, oldFacetAddress, selector);\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function removeFunctions(\n address _facetAddress,\n bytes4[] memory _functionSelectors\n ) internal {\n uint256 funcSelectorsLength = _functionSelectors.length;\n require(\n funcSelectorsLength > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n DiamondStorage storage ds = diamondStorage();\n // if function does not exist then do nothing and return\n require(\n _facetAddress == address(0),\n \"LibDiamondCut: Remove facet address must be address(0)\"\n );\n for (\n uint256 selectorIndex;\n selectorIndex < funcSelectorsLength;\n selectorIndex++\n ) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds\n .selectorToFacetAndPosition[selector]\n .facetAddress;\n removeFunction(ds, oldFacetAddress, selector);\n }\n }\n\n function addFacet(\n DiamondStorage storage ds,\n address _facetAddress\n ) internal {\n enforceHasContractCode(\n _facetAddress,\n \"LibDiamondCut: New facet has no code\"\n );\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds\n .facetAddresses\n .length;\n ds.facetAddresses.push(_facetAddress);\n }\n\n function addFunction(\n DiamondStorage storage ds,\n bytes4 _selector,\n uint96 _selectorPosition,\n address _facetAddress\n ) internal {\n ds\n .selectorToFacetAndPosition[_selector]\n .functionSelectorPosition = _selectorPosition;\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(\n _selector\n );\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\n }\n\n function removeFunction(\n DiamondStorage storage ds,\n address _facetAddress,\n bytes4 _selector\n ) internal {\n require(\n _facetAddress != address(0),\n \"LibDiamondCut: Can't remove function that doesn't exist\"\n );\n // an immutable function is a function defined directly in a diamond\n require(\n _facetAddress != address(this),\n \"LibDiamondCut: Can't remove immutable function\"\n );\n // replace selector with last selector, then delete last selector\n uint256 selectorPosition = ds\n .selectorToFacetAndPosition[_selector]\n .functionSelectorPosition;\n uint256 lastSelectorPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors\n .length - 1;\n // if not the same then replace _selector with lastSelector\n if (selectorPosition != lastSelectorPosition) {\n bytes4 lastSelector = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors[lastSelectorPosition];\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[\n selectorPosition\n ] = lastSelector;\n ds\n .selectorToFacetAndPosition[lastSelector]\n .functionSelectorPosition = uint96(selectorPosition);\n }\n // delete the last selector\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\n delete ds.selectorToFacetAndPosition[_selector];\n\n // if no more selectors for facet address then delete the facet address\n if (lastSelectorPosition == 0) {\n // replace facet address with last facet address and delete last facet address\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\n uint256 facetAddressPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .facetAddressPosition;\n if (facetAddressPosition != lastFacetAddressPosition) {\n address lastFacetAddress = ds.facetAddresses[\n lastFacetAddressPosition\n ];\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\n ds\n .facetFunctionSelectors[lastFacetAddress]\n .facetAddressPosition = facetAddressPosition;\n }\n ds.facetAddresses.pop();\n delete ds\n .facetFunctionSelectors[_facetAddress]\n .facetAddressPosition;\n }\n }\n\n function initializeDiamondCut(\n address _init,\n bytes memory _calldata\n ) internal {\n if (_init == address(0)) {\n return;\n }\n enforceHasContractCode(\n _init,\n \"LibDiamondCut: _init address has no code\"\n );\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length > 0) {\n // bubble up error\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(error)\n revert(add(32, error), returndata_size)\n }\n } else {\n revert InitializationFunctionReverted(_init, _calldata);\n }\n }\n }\n\n function enforceHasContractCode(\n address _contract,\n string memory _errorMessage\n ) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize > 0, _errorMessage);\n }\n}\n" + }, + "contracts/libraries/LibAppStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {SafeCast} from \"@openzeppelin/contracts/utils/math/SafeCast.sol\";\nimport {IEntryPoint} from \"../aa-4337/interfaces/IEntryPoint.sol\";\nimport {IFacetRegistry} from \"../infrastructure/interfaces/IFacetRegistry.sol\";\n\n/*\n * @title App Storage\n * @dev App storage for Barz contract to prevent storage collision\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\n\nstruct Lock {\n uint64 release;\n bytes4 locker;\n}\n\nstruct InitializersStorage {\n // NOTE: initialized is a variable to make sure the initialization is only done once.\n uint8 signerInitialized;\n uint8 accountInitialized;\n uint8 restrictionsInitialized;\n}\n\nstruct AppStorage {\n mapping(uint256 => InitializersStorage) initStorage;\n uint8 signerMigration;\n bytes4 validateOwnerSignatureSelector;\n IEntryPoint entryPoint;\n IFacetRegistry facetRegistry;\n mapping(uint256 => Lock) locks;\n}\n\nlibrary LibAppStorage {\n error LibAppStorage__AccountAlreadyUninitialized();\n error LibAppStorage__AccountMustBeUninitialized();\n error LibAppStorage__SignerAlreadyUninitialized();\n error LibAppStorage__SignerMustBeUninitialized();\n\n function appStorage() internal pure returns (AppStorage storage ds) {\n assembly {\n ds.slot := 0\n }\n }\n\n function setSignerUninitialized() internal {\n AppStorage storage s = appStorage();\n if (1 != s.initStorage[0].signerInitialized) {\n revert LibAppStorage__SignerAlreadyUninitialized();\n }\n s.initStorage[0].signerInitialized = 0;\n }\n\n function getValidateOwnerSignatureSelector()\n internal\n view\n returns (bytes4 selector)\n {\n selector = appStorage().validateOwnerSignatureSelector;\n }\n\n function setValidateOwnerSignatureSelector(\n bytes4 _validateOwnerSignatureSelector\n ) internal {\n appStorage()\n .validateOwnerSignatureSelector = _validateOwnerSignatureSelector;\n }\n\n function enforceSignerInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].signerInitialized) {\n revert LibAppStorage__SignerMustBeUninitialized();\n }\n s.initStorage[0].signerInitialized = 1;\n }\n\n function enforceAccountInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].accountInitialized) {\n revert LibAppStorage__AccountMustBeUninitialized();\n }\n s.initStorage[0].accountInitialized = 1;\n }\n\n function initiateSignerMigration() internal {\n appStorage().signerMigration = 1;\n }\n\n function enforceSignerMigration() internal view {\n if (1 != appStorage().signerMigration) {\n revert LibAppStorage__AccountMustBeUninitialized();\n }\n }\n\n function finalizeSignerMigration() internal {\n appStorage().signerMigration = 0;\n }\n\n function setLock(uint256 _releaseAfter, bytes4 _locker) internal {\n appStorage().locks[0] = Lock(SafeCast.toUint64(_releaseAfter), _locker);\n }\n\n function enforceRestrictionsInitialize() internal {\n AppStorage storage s = appStorage();\n if (0 != s.initStorage[0].restrictionsInitialized)\n revert LibAppStorage__SignerMustBeUninitialized();\n s.initStorage[0].restrictionsInitialized = 1;\n }\n\n function setRestrictionsUninitialized() internal {\n AppStorage storage s = appStorage();\n if (1 != s.initStorage[0].restrictionsInitialized)\n revert LibAppStorage__AccountAlreadyUninitialized();\n s.initStorage[0].restrictionsInitialized = 0;\n }\n}\n\ncontract BarzStorage {\n AppStorage internal s;\n modifier onlyWhenUnlocked() {\n require(\n uint64(block.timestamp) >= s.locks[0].release,\n \"Account Locked\"\n );\n _;\n }\n modifier onlyWhenLocked() {\n require(\n uint64(block.timestamp) < s.locks[0].release,\n \"Account Unlocked\"\n );\n _;\n }\n}\n" + }, + "contracts/libraries/LibDiamond.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondCut} from \"../facets/base/interfaces/IDiamondCut.sol\";\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\n\nerror InitializationFunctionReverted(\n address _initializationContractAddress,\n bytes _calldata\n);\n\nlibrary LibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION =\n keccak256(\"trustwallet.barz.diamond.storage\");\n bytes4 constant RESTRICTIONS_FACET_SELECTOR =\n bytes4(keccak256(\"verifyRestrictions(address,address,uint256,bytes)\"));\n struct DiamondStorage {\n // maps function selectors to the facets that execute the functions.\n // and maps the selectors to their position in the selectorSlots array.\n // func selector => address facet, selector position\n mapping(bytes4 => bytes32) facets;\n // array of slots of function selectors.\n // each slot holds 8 function selectors.\n mapping(uint256 => bytes32) selectorSlots;\n // The number of function selectors in selectorSlots\n uint16 selectorCount;\n // Used to query if a contract implements an interface.\n // Used to implement ERC-165.\n mapping(bytes4 => bool) supportedInterfaces;\n // Default Fallback Handler of the barz.\n IDiamondLoupe defaultFallbackHandler;\n }\n\n function diamondStorage()\n internal\n pure\n returns (DiamondStorage storage ds)\n {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n function enforceIsSelf() internal view {\n require(msg.sender == address(this), \"LibDiamond: Caller not self\");\n }\n\n event DiamondCut(\n IDiamondCut.FacetCut[] _diamondCut,\n address _init,\n bytes _calldata\n );\n\n bytes32 constant CLEAR_ADDRESS_MASK =\n bytes32(uint256(0xffffffffffffffffffffffff));\n bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));\n\n // Internal function version of diamondCut\n // This code is almost the same as the external diamondCut,\n // except it is using 'Facet[] memory _diamondCut' instead of\n // 'Facet[] calldata _diamondCut'.\n // The code is duplicated to prevent copying calldata to memory which\n // causes an error for a two dimensional array.\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n DiamondStorage storage ds = diamondStorage();\n uint256 originalSelectorCount = ds.selectorCount;\n uint256 selectorCount = originalSelectorCount;\n bytes32 selectorSlot;\n // Check if last selector slot is not full\n // \"selectorCount & 7\" is a gas efficient modulo by eight \"selectorCount % 8\"\n if (selectorCount & 7 > 0) {\n // get last selectorSlot\n // \"selectorSlot >> 3\" is a gas efficient division by 8 \"selectorSlot / 8\"\n selectorSlot = ds.selectorSlots[selectorCount >> 3];\n }\n // loop through diamond cut\n for (uint256 facetIndex; facetIndex < _diamondCut.length; ) {\n (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors(\n selectorCount,\n selectorSlot,\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].action,\n _diamondCut[facetIndex].functionSelectors\n );\n\n unchecked {\n facetIndex++;\n }\n }\n if (selectorCount != originalSelectorCount) {\n ds.selectorCount = uint16(selectorCount);\n }\n // If last selector slot is not full\n // \"selectorCount & 7\" is a gas efficient modulo by eight \"selectorCount % 8\"\n if (selectorCount & 7 > 0) {\n // \"selectorSlot >> 3\" is a gas efficient division by 8 \"selectorSlot / 8\"\n ds.selectorSlots[selectorCount >> 3] = selectorSlot;\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addReplaceRemoveFacetSelectors(\n uint256 _selectorCount,\n bytes32 _selectorSlot,\n address _newFacetAddress,\n IDiamondCut.FacetCutAction _action,\n bytes4[] memory _selectors\n ) internal returns (uint256, bytes32) {\n DiamondStorage storage ds = diamondStorage();\n require(\n _selectors.length > 0,\n \"LibDiamondCut: No selectors in facet to cut\"\n );\n if (_action == IDiamondCut.FacetCutAction.Add) {\n enforceHasContractCode(\n _newFacetAddress,\n \"LibDiamondCut: Add facet has no code\"\n );\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n require(\n address(bytes20(oldFacet)) == address(0),\n \"LibDiamondCut: Can't add function that already exists\"\n );\n // add facet for selector\n ds.facets[selector] =\n bytes20(_newFacetAddress) |\n bytes32(_selectorCount);\n // \"_selectorCount & 7\" is a gas efficient modulo by eight \"_selectorCount % 8\"\n // \" << 5 is the same as multiplying by 32 ( * 32)\n uint256 selectorInSlotPosition = (_selectorCount & 7) << 5;\n // clear selector position in slot and add selector\n _selectorSlot =\n (_selectorSlot &\n ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |\n (bytes32(selector) >> selectorInSlotPosition);\n // if slot is full then write it to storage\n if (selectorInSlotPosition == 224) {\n // \"_selectorSlot >> 3\" is a gas efficient division by 8 \"_selectorSlot / 8\"\n ds.selectorSlots[_selectorCount >> 3] = _selectorSlot;\n _selectorSlot = 0;\n }\n _selectorCount++;\n\n unchecked {\n selectorIndex++;\n }\n }\n } else if (_action == IDiamondCut.FacetCutAction.Replace) {\n enforceHasContractCode(\n _newFacetAddress,\n \"LibDiamondCut: Replace facet has no code\"\n );\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n address oldFacetAddress = address(bytes20(oldFacet));\n // only useful if immutable functions exist\n require(\n oldFacetAddress != address(this),\n \"LibDiamondCut: Can't replace immutable function\"\n );\n require(\n oldFacetAddress != _newFacetAddress,\n \"LibDiamondCut: Can't replace function with same function\"\n );\n require(\n oldFacetAddress != address(0),\n \"LibDiamondCut: Can't replace function that doesn't exist\"\n );\n // replace old facet address\n ds.facets[selector] =\n (oldFacet & CLEAR_ADDRESS_MASK) |\n bytes20(_newFacetAddress);\n\n unchecked {\n selectorIndex++;\n }\n }\n } else if (_action == IDiamondCut.FacetCutAction.Remove) {\n require(\n _newFacetAddress == address(0),\n \"LibDiamondCut: Remove facet address must be address(0)\"\n );\n // \"_selectorCount >> 3\" is a gas efficient division by 8 \"_selectorCount / 8\"\n uint256 selectorSlotCount = _selectorCount >> 3;\n // \"_selectorCount & 7\" is a gas efficient modulo by eight \"_selectorCount % 8\"\n uint256 selectorInSlotIndex = _selectorCount & 7;\n for (uint256 selectorIndex; selectorIndex < _selectors.length; ) {\n if (_selectorSlot == 0) {\n // get last selectorSlot\n selectorSlotCount--;\n _selectorSlot = ds.selectorSlots[selectorSlotCount];\n selectorInSlotIndex = 7;\n } else {\n selectorInSlotIndex--;\n }\n bytes4 lastSelector;\n uint256 oldSelectorsSlotCount;\n uint256 oldSelectorInSlotPosition;\n // adding a block here prevents stack too deep error\n {\n bytes4 selector = _selectors[selectorIndex];\n bytes32 oldFacet = ds.facets[selector];\n require(\n address(bytes20(oldFacet)) != address(0),\n \"LibDiamondCut: Can't remove function that doesn't exist\"\n );\n // only useful if immutable functions exist\n require(\n address(bytes20(oldFacet)) != address(this),\n \"LibDiamondCut: Can't remove immutable function\"\n );\n // replace selector with last selector in ds.facets\n // gets the last selector\n // \" << 5 is the same as multiplying by 32 ( * 32)\n lastSelector = bytes4(\n _selectorSlot << (selectorInSlotIndex << 5)\n );\n if (lastSelector != selector) {\n // update last selector slot position info\n ds.facets[lastSelector] =\n (oldFacet & CLEAR_ADDRESS_MASK) |\n bytes20(ds.facets[lastSelector]);\n }\n delete ds.facets[selector];\n uint256 oldSelectorCount = uint16(uint256(oldFacet));\n // \"oldSelectorCount >> 3\" is a gas efficient division by 8 \"oldSelectorCount / 8\"\n oldSelectorsSlotCount = oldSelectorCount >> 3;\n // \"oldSelectorCount & 7\" is a gas efficient modulo by eight \"oldSelectorCount % 8\"\n // \" << 5 is the same as multiplying by 32 ( * 32)\n oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;\n }\n if (oldSelectorsSlotCount != selectorSlotCount) {\n bytes32 oldSelectorSlot = ds.selectorSlots[\n oldSelectorsSlotCount\n ];\n // clears the selector we are deleting and puts the last selector in its place.\n oldSelectorSlot =\n (oldSelectorSlot &\n ~(CLEAR_SELECTOR_MASK >>\n oldSelectorInSlotPosition)) |\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\n // update storage with the modified slot\n ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;\n } else {\n // clears the selector we are deleting and puts the last selector in its place.\n _selectorSlot =\n (_selectorSlot &\n ~(CLEAR_SELECTOR_MASK >>\n oldSelectorInSlotPosition)) |\n (bytes32(lastSelector) >> oldSelectorInSlotPosition);\n }\n if (selectorInSlotIndex == 0) {\n delete ds.selectorSlots[selectorSlotCount];\n _selectorSlot = 0;\n }\n\n unchecked {\n selectorIndex++;\n }\n }\n _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex;\n } else {\n revert(\"LibDiamondCut: Incorrect FacetCutAction\");\n }\n return (_selectorCount, _selectorSlot);\n }\n\n function initializeDiamondCut(\n address _init,\n bytes memory _calldata\n ) internal {\n if (_init == address(0)) {\n return;\n }\n enforceHasContractCode(\n _init,\n \"LibDiamondCut: _init address has no code\"\n );\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length > 0) {\n // bubble up error\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(error)\n revert(add(32, error), returndata_size)\n }\n } else {\n revert InitializationFunctionReverted(_init, _calldata);\n }\n }\n }\n\n function enforceHasContractCode(\n address _contract,\n string memory _errorMessage\n ) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize > 0, _errorMessage);\n }\n\n function restrictionsFacet() internal view returns (address facetAddress_) {\n facetAddress_ = address(\n bytes20(\n LibDiamond.diamondStorage().facets[RESTRICTIONS_FACET_SELECTOR]\n )\n );\n }\n}\n" + }, + "contracts/libraries/LibFacetStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Facet Storage\n * @dev Storage contract to store each facets variables with diamond storage\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\n\nstruct Secp256k1VerificationStorage {\n address signer;\n}\n\nstruct Secp256r1VerificationStorage {\n uint256[2] q;\n}\n\nstruct GuardianStorage {\n mapping(bytes32 => uint256) pending;\n mapping(uint8 => StorageConfig) configs;\n}\n\nstruct Info {\n bool exists;\n uint128 index;\n}\n\nstruct StorageConfig {\n address[] addresses;\n mapping(address => Info) info;\n}\n\nstruct RecoveryConfig {\n bytes recoveryPublicKey;\n uint64 executeAfter;\n}\n\nstruct ApprovalConfig {\n bool isApproved;\n uint64 validUntil;\n}\n\nstruct RecoveryApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isNewOwnerApproved;\n}\n\nstruct RecoveryStorage {\n mapping(uint8 => RecoveryConfig) recoveryConfigs;\n mapping(uint8 => RecoveryApprovalConfig) recoveryApprovalConfigs;\n uint128 nonce;\n}\n\nstruct RestrictionsStorage {\n address[] restrictions;\n mapping(address => bool) exists;\n}\n\nstruct SignatureMigrationConfig {\n bytes migrationPublicKey;\n address migrationVerificationFacet;\n bytes4[] migrationSelectors;\n uint64 migrateAfter;\n}\n\nstruct SignatureMigrationApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isMigrationApproved;\n}\n\nstruct SignatureMigrationStorage {\n mapping(uint8 => SignatureMigrationConfig) migrationConfigs;\n mapping(uint8 => SignatureMigrationApprovalConfig) migrationApprovalConfigs;\n uint128 nonce;\n}\n\nstruct DiamondCutApprovalConfig {\n mapping(bytes32 => mapping(address => ApprovalConfig)) isDiamondCutApproved;\n}\n\nstruct DiamondCutStorage {\n mapping(uint8 => DiamondCutApprovalConfig) diamondCutApprovalConfigs;\n uint128 nonce;\n}\n\nstruct LockStorage {\n uint128 nonce;\n}\n\nlibrary LibFacetStorage {\n bytes32 constant K1_STORAGE_POSITION =\n keccak256(\n \"v0.trustwallet.diamond.storage.Secp256k1VerificationStorage\"\n );\n bytes32 constant R1_STORAGE_POSITION =\n keccak256(\n \"v0.trustwallet.diamond.storage.Secp256r1VerificationStorage\"\n );\n bytes32 constant GUARDIAN_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.GuardianStorage\");\n bytes32 constant RECOVERY_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.RecoveryStorage\");\n bytes32 constant RESTRICTION_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.RestrictionsStorage\");\n bytes32 constant MIGRATION_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.SignatureMigrationStorage\");\n bytes32 constant DIAMONDCUT_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.DiamondCutStorage\");\n bytes32 constant LOCK_STORAGE_POSITION =\n keccak256(\"v0.trustwallet.diamond.storage.LockStorage\");\n\n function k1Storage()\n internal\n pure\n returns (Secp256k1VerificationStorage storage ds)\n {\n bytes32 storagePosition = K1_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function r1Storage()\n internal\n pure\n returns (Secp256r1VerificationStorage storage ds)\n {\n bytes32 storagePosition = R1_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function guardianStorage()\n internal\n pure\n returns (GuardianStorage storage ds)\n {\n bytes32 storagePosition = GUARDIAN_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function recoveryStorage()\n internal\n pure\n returns (RecoveryStorage storage ds)\n {\n bytes32 storagePosition = RECOVERY_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function restrictionsStorage()\n internal\n pure\n returns (RestrictionsStorage storage ds)\n {\n bytes32 storagePosition = RESTRICTION_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function migrationStorage()\n internal\n pure\n returns (SignatureMigrationStorage storage ds)\n {\n bytes32 storagePosition = MIGRATION_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function diamondCutStorage()\n internal\n pure\n returns (DiamondCutStorage storage ds)\n {\n bytes32 storagePosition = DIAMONDCUT_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n\n function lockStorage() internal pure returns (LockStorage storage ds) {\n bytes32 storagePosition = LOCK_STORAGE_POSITION;\n assembly {\n ds.slot := storagePosition\n }\n }\n}\n" + }, + "contracts/libraries/LibGuardian.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibFacetStorage, StorageConfig} from \"./LibFacetStorage.sol\";\n\n/**\n * @title LibGuardian\n * @dev Internal Library to provide utility feature for Guardians stored in Guardian Facet Storage\n * @author David Yongjun Kim (@Powerstream3604)\n */\nlibrary LibGuardian {\n function majorityOfGuardians()\n internal\n view\n returns (uint256 guardianNumber)\n {\n uint256 guardianLength = guardianCount();\n guardianNumber = (guardianLength == 0) ? 0 : guardianLength / 2 + 1;\n }\n\n function isGuardian(address _guardian) internal view returns (bool) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n return config.info[_guardian].exists;\n }\n\n function guardianCount() internal view returns (uint256) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n return config.addresses.length;\n }\n\n function getGuardians() internal view returns (address[] memory) {\n StorageConfig storage config = LibFacetStorage\n .guardianStorage()\n .configs[0];\n address[] memory addresses = new address[](config.addresses.length);\n uint256 addressesLen = config.addresses.length;\n for (uint256 i; i < addressesLen; ) {\n addresses[i] = config.addresses[i];\n unchecked {\n ++i;\n }\n }\n return addresses;\n }\n}\n" + }, + "contracts/libraries/LibLoupe.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\nimport {LibDiamond} from \"./LibDiamond.sol\";\n\n/**\n * @title LibLoupe\n * @dev Internal Library to provide utility feature for reading the state of diamond facets\n * Originally from Diamond's implementation of Mudgen(author of EIP-2535)\n */\nlibrary LibLoupe {\n /// @notice Gets all facets and their selectors.\n /// @return facets_ Facet\n function facets()\n internal\n view\n returns (IDiamondLoupe.Facet[] memory facets_)\n {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facets_ = new IDiamondLoupe.Facet[](ds.selectorCount);\n uint16[] memory numFacetSelectors = new uint16[](ds.selectorCount);\n uint256 numFacets;\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facetAddress_ = address(bytes20(ds.facets[selector]));\n bool continueLoop;\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n if (facets_[facetIndex].facetAddress == facetAddress_) {\n facets_[facetIndex].functionSelectors[\n numFacetSelectors[facetIndex]\n ] = selector;\n // probably will never have more than 256 functions from one facet contract\n require(numFacetSelectors[facetIndex] < 255);\n numFacetSelectors[facetIndex]++;\n continueLoop = true;\n break;\n }\n }\n if (continueLoop) {\n continue;\n }\n facets_[numFacets].facetAddress = facetAddress_;\n facets_[numFacets].functionSelectors = new bytes4[](\n ds.selectorCount\n );\n facets_[numFacets].functionSelectors[0] = selector;\n numFacetSelectors[numFacets] = 1;\n numFacets++;\n }\n }\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n uint256 numSelectors = numFacetSelectors[facetIndex];\n bytes4[] memory selectors = facets_[facetIndex].functionSelectors;\n // setting the number of selectors\n assembly {\n mstore(selectors, numSelectors)\n }\n }\n // setting the number of facets\n assembly {\n mstore(facets_, numFacets)\n }\n }\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n /// @return _facetFunctionSelectors The selectors associated with a facet address.\n function facetFunctionSelectors(\n address _facet\n ) internal view returns (bytes4[] memory _facetFunctionSelectors) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n uint256 numSelectors;\n _facetFunctionSelectors = new bytes4[](ds.selectorCount);\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facet = address(bytes20(ds.facets[selector]));\n if (_facet == facet) {\n _facetFunctionSelectors[numSelectors] = selector;\n numSelectors++;\n }\n }\n }\n // Set the number of selectors in the array\n assembly {\n mstore(_facetFunctionSelectors, numSelectors)\n }\n }\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses()\n internal\n view\n returns (address[] memory facetAddresses_)\n {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facetAddresses_ = new address[](ds.selectorCount);\n uint256 numFacets;\n uint256 selectorIndex;\n // loop through function selectors\n for (uint256 slotIndex; selectorIndex < ds.selectorCount; slotIndex++) {\n bytes32 slot = ds.selectorSlots[slotIndex];\n for (\n uint256 selectorSlotIndex;\n selectorSlotIndex < 8;\n selectorSlotIndex++\n ) {\n selectorIndex++;\n if (selectorIndex > ds.selectorCount) {\n break;\n }\n // \" << 5 is the same as multiplying by 32 ( * 32)\n bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));\n address facetAddress_ = address(bytes20(ds.facets[selector]));\n bool continueLoop;\n for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {\n if (facetAddress_ == facetAddresses_[facetIndex]) {\n continueLoop = true;\n break;\n }\n }\n if (continueLoop) {\n continue;\n }\n facetAddresses_[numFacets] = facetAddress_;\n numFacets++;\n }\n }\n // Set the number of facet addresses in the array\n assembly {\n mstore(facetAddresses_, numFacets)\n }\n }\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(\n bytes4 _functionSelector\n ) internal view returns (address facetAddress_) {\n facetAddress_ = address(\n bytes20(LibDiamond.diamondStorage().facets[_functionSelector])\n );\n }\n}\n" + }, + "contracts/libraries/LibMultiSigStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Multi-sig Storage\n * @dev Storage contract for storing Multi-sig Facet variables in diamond storage pattern\n * @author David Yongjun Kim (@Powerstream3604)\n */\n\nstruct MultiSigStorage {\n mapping(address => address) owners;\n mapping(uint256 => mapping(address => mapping(bytes32 => uint256))) approvedHashes;\n uint256 ownerCount;\n uint256 threshold;\n uint256 counter;\n}\n\nlibrary LibMultiSigStorage {\n function multisigStorage()\n internal\n pure\n returns (MultiSigStorage storage ds)\n {\n bytes32 storagePosition = keccak256(\n \"v0.trustwallet.diamond.storage.MultiSigStorage\"\n );\n assembly {\n ds.slot := storagePosition\n }\n }\n}\n" + }, + "contracts/libraries/LibRecoverSpender.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title RecoverSpender\n * @dev Library to determine the action and spender of calldata\n * @author Ruslan Serebriakov (@rsrbk)\n */\nlibrary LibRecoverSpender {\n // ERC20, ERC721 & ERC1155 transfers & approvals\n bytes4 private constant ERC20_TRANSFER =\n bytes4(keccak256(\"transfer(address,uint256)\"));\n bytes4 private constant ERC20_APPROVE =\n bytes4(keccak256(\"approve(address,uint256)\"));\n bytes4 private constant ERC20_INCREASE_ALLOWANCE =\n bytes4(keccak256(\"increaseAllowance(address,uint256)\"));\n bytes4 private constant ERC20_DECREASE_ALLOWANCE =\n bytes4(keccak256(\"decreaseAllowance(address,uint256)\"));\n bytes4 private constant ERC721_SET_APPROVAL_FOR_ALL =\n bytes4(keccak256(\"setApprovalForAll(address,bool)\"));\n bytes4 private constant ERC721_TRANSFER_FROM =\n bytes4(keccak256(\"transferFrom(address,address,uint256)\"));\n bytes4 private constant ERC721_SAFE_TRANSFER_FROM =\n bytes4(keccak256(\"safeTransferFrom(address,address,uint256)\"));\n bytes4 private constant ERC721_SAFE_TRANSFER_FROM_BYTES =\n bytes4(keccak256(\"safeTransferFrom(address,address,uint256,bytes)\"));\n bytes4 private constant ERC1155_SAFE_TRANSFER_FROM =\n bytes4(\n keccak256(\"safeTransferFrom(address,address,uint256,uint256,bytes)\")\n );\n bytes4 private constant ERC1155_SAFE_BATCH_TRANSFER_FROM =\n bytes4(\n keccak256(\n \"safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)\"\n )\n );\n\n /**\n * @notice Helper method to recover the spender from a contract call.\n * The method returns the contract unless the call is to a standard method of a ERC20/ERC721/ERC1155 token\n * in which case the spender is recovered from the data.\n * @param _to The target contract.\n * @param _data The data payload.\n */\n function _recover(\n address _to,\n bytes memory _data\n ) internal pure returns (address spender) {\n if (_data.length >= 68) {\n bytes4 methodId;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n methodId := mload(add(_data, 0x20))\n }\n if (\n methodId == ERC20_TRANSFER ||\n methodId == ERC20_APPROVE ||\n methodId == ERC20_INCREASE_ALLOWANCE ||\n methodId == ERC20_DECREASE_ALLOWANCE ||\n methodId == ERC721_SET_APPROVAL_FOR_ALL\n ) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n spender := mload(add(_data, 0x24))\n }\n return spender;\n }\n if (\n methodId == ERC721_TRANSFER_FROM ||\n methodId == ERC721_SAFE_TRANSFER_FROM ||\n methodId == ERC721_SAFE_TRANSFER_FROM_BYTES ||\n methodId == ERC1155_SAFE_TRANSFER_FROM ||\n methodId == ERC1155_SAFE_BATCH_TRANSFER_FROM\n ) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n spender := mload(add(_data, 0x44))\n }\n return spender;\n }\n }\n\n spender = _to;\n }\n}\n" + }, + "contracts/libraries/LibUtils.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IDiamondLoupe} from \"../facets/base/interfaces/IDiamondLoupe.sol\";\n\nlibrary LibUtils {\n // Internal utility functions\n function mergeArrays(\n bytes4[] memory _array1,\n bytes4[] memory _array2\n ) internal pure returns (bytes4[] memory) {\n uint256 length1 = _array1.length;\n uint256 length2 = _array2.length;\n bytes4[] memory mergedArray = new bytes4[](length1 + length2);\n\n for (uint256 i; i < length1; ) {\n mergedArray[i] = _array1[i];\n unchecked {\n ++i;\n }\n }\n\n for (uint256 i; i < length2; ) {\n mergedArray[length1 + i] = _array2[i];\n unchecked {\n ++i;\n }\n }\n\n return mergedArray;\n }\n\n function removeFacetElement(\n IDiamondLoupe.Facet[] memory _facets,\n uint256 _index\n ) internal pure returns (IDiamondLoupe.Facet[] memory) {\n require(_index < _facets.length, \"Invalid index\");\n require(_facets.length != 0, \"Invalid array\");\n\n // Create a new array with a length of `_facets.length - 1`\n IDiamondLoupe.Facet[] memory newArray = new IDiamondLoupe.Facet[](\n _facets.length - 1\n );\n uint256 newArrayLength = newArray.length;\n // Iterate over the original array, skipping the element at the specified `index`\n for (uint256 i; i < newArrayLength; ) {\n if (i < _index) {\n newArray[i] = _facets[i];\n } else {\n newArray[i] = _facets[i + 1];\n }\n unchecked {\n ++i;\n }\n }\n\n return newArray;\n }\n\n function removeElement(\n bytes4[] memory _array,\n uint256 _index\n ) internal pure returns (bytes4[] memory) {\n require(_index < _array.length, \"Invalid index\");\n require(_array.length != 0, \"Invalid array\");\n\n bytes4[] memory newArray = new bytes4[](_array.length - 1);\n uint256 newArrayLength = newArray.length;\n for (uint256 i; i < newArrayLength; ) {\n if (i < _index) {\n newArray[i] = _array[i];\n } else {\n newArray[i] = _array[i + 1];\n }\n unchecked {\n ++i;\n }\n }\n\n return newArray;\n }\n\n function setValue(\n bytes4[] memory _keys,\n address[] memory _values,\n bytes4 _key,\n address _value\n ) internal pure returns (bytes4[] memory, address[] memory) {\n uint256 index = findIndex(_keys, _key);\n uint256 keysLength = _keys.length;\n if (index < keysLength) {\n _values[index] = _value;\n } else {\n // Create new storage arrays\n bytes4[] memory newKeys = new bytes4[](keysLength + 1);\n address[] memory newValues = new address[](_values.length + 1);\n\n // Copy values to the new storage arrays\n for (uint256 i; i < keysLength; ) {\n newKeys[i] = _keys[i];\n newValues[i] = _values[i];\n\n unchecked {\n ++i;\n }\n }\n\n // Add the new key-value pair\n newKeys[keysLength] = _key;\n newValues[_values.length] = _value;\n\n return (newKeys, newValues);\n }\n\n // If the key already exists, return the original arrays\n return (_keys, _values);\n }\n\n function getValue(\n bytes4[] memory _keys,\n address[] memory _values,\n bytes4 _key\n ) internal pure returns (address) {\n uint256 index = findIndex(_keys, _key);\n if (index >= _keys.length) return address(0);\n\n return _values[index];\n }\n\n function findIndex(\n bytes4[] memory _keys,\n bytes4 _key\n ) internal pure returns (uint256) {\n uint256 keysLength = _keys.length;\n for (uint256 i; i < keysLength; ) {\n if (_keys[i] == _key) {\n return i;\n }\n unchecked {\n ++i;\n }\n }\n return keysLength;\n }\n}\n" + }, + "contracts/restrictions/IRestriction.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\n/**\n * @title Interface for restrictions\n * @dev Restriction is a contract which decides whether to approve a certain kind of transaction, based on its internal logic.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ninterface IRestriction {\n /**\n * @dev Based on restriction's internal logic, it should accept or reject a certain transaction.\n * @param from The address of the sender, that will be signing the transaction.\n * @param to The receiving address.\n * @param value Amount of ETH to transfer from sender to recipient.\n * @param _calldata Optional field to include arbitrary data.\n * @return bool value for whether the check is passed\n */\n function check(\n address from,\n address to,\n uint256 value,\n bytes calldata _calldata\n ) external returns (bool);\n}\n" + }, + "contracts/restrictions/WhitelistRestriction.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {LibRecoverSpender} from \"../libraries/LibRecoverSpender.sol\";\nimport {WhitelistStorage} from \"../infrastructure/WhitelistStorage.sol\";\nimport {IRestriction} from \"./IRestriction.sol\";\n\n/**\n * @title Whitelist Restriction\n * @dev This restriction defines a list of accepted addresses and denies any interaction with addresses outside of it.\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract WhitelistRestriction is IRestriction {\n WhitelistStorage public immutable whitelistStorage;\n\n constructor(WhitelistStorage _whitelistStorage) {\n whitelistStorage = _whitelistStorage;\n }\n\n /**\n * @notice Helper method to recover the spender from a contract call.\n * The method returns the contract unless the call is to a standard method of a ERC20/ERC721/ERC1155 token\n * in which case the spender is recovered from the data.\n * @param _to The target contract.\n * @param _data The data payload.\n */\n function recoverSpender(\n address _to,\n bytes memory _data\n ) public pure returns (address spender) {\n return LibRecoverSpender._recover(_to, _data);\n }\n\n /*\n * @dev IRestriction's implementation. It will allow transaction if the sender is whitelisted, or user, or the whitelist storage.\n * @param _from The address of the sender, that will be signing the transaction.\n * @param _to The receiving address.\n * @param _calldata Optional field to include arbitrary data.\n * @return result value for whether the check is passed\n */\n function check(\n address _from,\n address _to,\n uint256 /*_value*/,\n bytes calldata _calldata\n ) external view override returns (bool result) {\n return\n whitelistStorage.isWhitelisted(\n _from,\n LibRecoverSpender._recover(_to, _calldata)\n ) ||\n _to == address(whitelistStorage) ||\n _to == msg.sender;\n }\n}\n" + }, + "contracts/test/Counter.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\ncontract TestCounter {\n int private count = 0;\n\n function incrementCounter() public {\n count += 1;\n }\n\n function decrementCounter() public {\n count -= 1;\n }\n\n function getCount() public view returns (int) {\n return count;\n }\n}\n" + }, + "contracts/test/TestERC1155.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC1155/ERC1155.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\n\ncontract TestERC1155 is ERC1155 {\n using Counters for Counters.Counter;\n\n Counters.Counter private _tokenIds;\n\n constructor() ERC1155(\"\") {}\n\n function mint(address account, uint256 amount) external {\n uint256 tokenId = _getNextTokenId();\n _mint(account, tokenId, amount, \"\");\n }\n\n function mintBatch(\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes memory data\n ) external {\n require(\n ids.length == amounts.length,\n \"TestERC1155: arrays length mismatch\"\n );\n\n _mintBatch(to, ids, amounts, data);\n }\n\n function _getNextTokenId() private returns (uint256) {\n _tokenIds.increment();\n return _tokenIds.current();\n }\n}\n" + }, + "contracts/test/TestERC777.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC777/ERC777.sol\";\n\ncontract TestERC777 is ERC777 {\n constructor(\n address[] memory _operators\n ) ERC777(\"TestERC777\", \"TERC777\", _operators) {}\n\n function mint(address account, uint256 amount) external {\n _mint(account, amount, \"\", \"\");\n }\n}\n" + }, + "contracts/test/TestInvalidSecp256k1VerificationFacet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.21;\n\nimport {IVerificationFacet} from \"../facets/interfaces/IVerificationFacet.sol\";\nimport {IERC1271} from \"../interfaces/ERC/IERC1271.sol\";\nimport {AppStorage, LibAppStorage, BarzStorage} from \"../libraries/LibAppStorage.sol\";\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {LibFacetStorage, Secp256k1VerificationStorage} from \"../libraries/LibFacetStorage.sol\";\nimport {UserOperation} from \"../aa-4337/interfaces/UserOperation.sol\";\n\n/**\n * @title Test Secp256k1 verification facet\n * @dev Default Ethereum's elliptic curve\n * @author David Yongjun Kim (@Powerstream3604)\n * @author Ruslan Serebriakov (@rsrbk)\n */\ncontract TestInvalidSecp256k1VerificationFacet is BarzStorage, IERC1271 {\n using ECDSA for bytes32;\n error Secp256k1VerificationFacet__InvalidSignerLength();\n error VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n\n event SignerUninitialized();\n\n constructor() {\n LibAppStorage.enforceSignerInitialize();\n }\n\n // THIS INVALID FACET DOES NOT INCLUDE initializeSigner()\n // THIS FACET IS USED TO TEST WHEN initializeSigner() DOESN'T EXIST IN FACET\n\n function uninitializeSigner() external returns (uint256 uninitSuccess) {\n LibAppStorage.enforceSignerMigration();\n LibAppStorage.setSignerUninitialized();\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n k1Storage.signer = address(0);\n\n if (LibAppStorage.getValidateOwnerSignatureSelector() == bytes4(0))\n revert VerificationFacet__ValidateOwnerSignatureSelectorNotSet();\n LibAppStorage.setValidateOwnerSignatureSelector(bytes4(0));\n\n uninitSuccess = 1;\n\n emit SignerUninitialized();\n }\n\n function validateOwnerSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash\n ) public view returns (uint256 validationData) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n return validateSignature(userOp, userOpHash, k1Storage.signer);\n }\n\n function validateSignature(\n UserOperation calldata userOp,\n bytes32 userOpHash,\n address signer\n ) public pure returns (uint256) {\n bytes32 hash = userOpHash.toEthSignedMessageHash();\n if (signer != hash.recover(userOp.signature)) return 1;\n return 0;\n }\n\n // This is REMOVED for testing purpose\n function validateOwnerSignatureSelector() public pure returns (bytes4) {\n // return this.validateOwnerSignature.selector;\n // The signature name could change according to the facet but the param format(UserOp, UserOpHash) should not change\n }\n\n function owner() public view returns (bytes memory) {\n Secp256k1VerificationStorage storage k1Storage = LibFacetStorage\n .k1Storage();\n return abi.encodePacked(k1Storage.signer);\n }\n\n function isValidKeyType(\n bytes memory _publicKey\n ) public pure returns (bool) {\n return (_publicKey.length == 65 && _publicKey[0] == 0x04);\n }\n\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) public view override returns (bytes4 magicValue) {\n magicValue = (_hash.recover(_signature) ==\n LibFacetStorage.k1Storage().signer)\n ? this.isValidSignature.selector\n : bytes4(0xffffffff);\n }\n}\n" + }, + "contracts/test/TestNFT.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\n\ncontract TestNFT is ERC721 {\n using Counters for Counters.Counter;\n Counters.Counter private currentTokenId;\n\n constructor() ERC721(\"TestNFT\", \"TNFT\") {}\n\n function mint(address recipient) public returns (uint256) {\n currentTokenId.increment();\n uint256 newItemId = currentTokenId.current();\n _safeMint(recipient, newItemId);\n return newItemId;\n }\n}\n" + }, + "contracts/test/TestToken.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.21;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract TestToken is ERC20 {\n constructor()\n // solhint-disable-next-line no-empty-blocks\n ERC20(\"TST\", \"TestToken\")\n {}\n\n function mint(address sender, uint256 amount) external {\n _mint(sender, amount);\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 999999 + }, + "evmVersion": "paris", + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/docs/images/Barz_Facet_Architecture.drawio b/docs/images/Barz_Facet_Architecture.drawio new file mode 100644 index 0000000..9333d9f --- /dev/null +++ b/docs/images/Barz_Facet_Architecture.drawio @@ -0,0 +1,115 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/images/Barz_Facet_Architecture.png b/docs/images/Barz_Facet_Architecture.png new file mode 100644 index 0000000..72a6c45 Binary files /dev/null and b/docs/images/Barz_Facet_Architecture.png differ diff --git a/docs/images/Barz_Modular_Signature_Architecture.drawio b/docs/images/Barz_Modular_Signature_Architecture.drawio new file mode 100644 index 0000000..f66c125 --- /dev/null +++ b/docs/images/Barz_Modular_Signature_Architecture.drawio @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/images/Barz_Modular_Signature_Architecture.png b/docs/images/Barz_Modular_Signature_Architecture.png new file mode 100644 index 0000000..db87162 Binary files /dev/null and b/docs/images/Barz_Modular_Signature_Architecture.png differ diff --git a/docs/images/Barz_Storage_Architecture.drawio b/docs/images/Barz_Storage_Architecture.drawio new file mode 100644 index 0000000..0d2d328 --- /dev/null +++ b/docs/images/Barz_Storage_Architecture.drawio @@ -0,0 +1,161 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/images/Barz_Storage_Architecture.png b/docs/images/Barz_Storage_Architecture.png new file mode 100644 index 0000000..ca2aa3b Binary files /dev/null and b/docs/images/Barz_Storage_Architecture.png differ diff --git a/docs/signature_format.md b/docs/signature_format.md new file mode 100644 index 0000000..5ed7804 --- /dev/null +++ b/docs/signature_format.md @@ -0,0 +1,12 @@ +# Barz Multi-sig Facet Signature Format +## Signature +This is the format of the Signature for the UserOperation validation during the Tx execution. + +Each Signature is comprised of the below format and this will be repeated in the Signature section of `UserOperation`: +``Address(20bytes) + SignatureType(1byte) + SignatureLength(4bytes) + Signature(arbitrary bytes)`` + +### SignatureType +SignatureType has 3 main types: +1. SignatureType ``1`` : Sign the raw UserOpHash + also supports contract signature(EIP-1271) +2. SignatureType ``2`` : Pre-approved hash +3. SignatureType ``3`` : Sign the ethSignedMessageHash(EIP-191) of UserOpHash + also supports contract signature(EIP-1271) \ No newline at end of file diff --git a/foundry.toml b/foundry.toml new file mode 100644 index 0000000..23fb5f1 --- /dev/null +++ b/foundry.toml @@ -0,0 +1,7 @@ +[profile.default] +src = 'contracts' +out = 'out' +libs = ['node_modules', 'lib'] +test = 'test/foundry' +cache_path = 'cache_forge' +optimizer_runs=999999 \ No newline at end of file diff --git a/hardhat.config.ts b/hardhat.config.ts new file mode 100644 index 0000000..f62c605 --- /dev/null +++ b/hardhat.config.ts @@ -0,0 +1,94 @@ +import "@nomicfoundation/hardhat-chai-matchers"; +import "@nomicfoundation/hardhat-verify"; +import '@typechain/hardhat' +import * as dotenv from 'dotenv'; +import deploymentConfig from "./scripts/deployment.config"; +import { HardhatUserConfig } from "hardhat/config" +import 'hardhat-contract-sizer' +import 'hardhat-deploy' +import "solidity-coverage"; +import "@nomicfoundation/hardhat-foundry"; +dotenv.config(); + +function getNetworkUrl(name: string): string { + return `https://${name}.infura.io/v3/${process.env.INFURA_ID}` + // NOTE: To use WebSocket -> `wss://${name}.infura.io/ws/v3/${process.env.INFURA_ID}` +} + +const config: HardhatUserConfig = { + solidity: { + version: "0.8.21", + settings: { + optimizer: { + enabled: true, + runs: 999999, + }, + }, + }, + networks: { + local: { + url: `http://localhost:8545/rpc` + }, + hardhat: { + blockGasLimit: 30_000_000, + chainId: 3604, + initialBaseFeePerGas: 10 // Putting gas to low for coverage testing + }, + goerli: { + url: getNetworkUrl('goerli'), + accounts: [deploymentConfig.PRIVATE_KEY || ""], + }, + sepolia: { + url: getNetworkUrl('sepolia'), + accounts: [deploymentConfig.PRIVATE_KEY || ""], + }, + bscTestnet: { + url: "https://data-seed-prebsc-1-s1.binance.org:8545", + accounts: [deploymentConfig.PRIVATE_KEY || ""], + }, + polygonMumbai: { + url: getNetworkUrl('polygon-mumbai'), + accounts: [deploymentConfig.PRIVATE_KEY || ""], + }, + polygon: { + url: getNetworkUrl('polygon-mainnet'), + accounts: [deploymentConfig.PRIVATE_KEY || ""], + }, + optimism: { + url: getNetworkUrl('optimism-mainnet'), + accounts: [deploymentConfig.PRIVATE_KEY || ""], + }, + arbitrum: { + url: getNetworkUrl('arbitrum-mainnet'), + accounts: [deploymentConfig.PRIVATE_KEY || ""], + }, + zkSyncTestnet: { + url: "https://testnet.era.zksync.dev", + accounts: [deploymentConfig.PRIVATE_KEY || ""], + }, + avalanche: { + url: getNetworkUrl('avalanche-mainnet'), + accounts: [deploymentConfig.PRIVATE_KEY || ""], + }, + bsc: { + url: "https://bsc-dataseed.binance.org/", + accounts: [deploymentConfig.PRIVATE_KEY || ""], + }, + opBNB: { + url: "https://opbnb-mainnet-rpc.bnbchain.org", + accounts: [deploymentConfig.PRIVATE_KEY || ""], + }, + base: { + url: getNetworkUrl('base-mainnet'), + accounts: [deploymentConfig.PRIVATE_KEY || ""], + } + }, + mocha: { + timeout: 10000 + }, + etherscan: { + apiKey: process.env.BSCSCAN_API_KEY + } +}; + +export default config; diff --git a/lib/forge-std b/lib/forge-std new file mode 160000 index 0000000..52715a2 --- /dev/null +++ b/lib/forge-std @@ -0,0 +1 @@ +Subproject commit 52715a217dc51d0de15877878ab8213f6cbbbab5 diff --git a/package.json b/package.json new file mode 100644 index 0000000..3ada6d1 --- /dev/null +++ b/package.json @@ -0,0 +1,73 @@ +{ + "name": "barz", + "version": "1.0.0", + "description": "A Smart Contract Wallet enabling mass adoption of Web3", + "main": "index.js", + "scripts": { + "test": "yarn hardhat test", + "compile": "yarn hardhat compile", + "coverage": "yarn hardhat clean; yarn hardhat coverage", + "size": "yarn hardhat size-contracts", + "lint:sol-write": "yarn prettier 'contracts/**/*.sol' --write", + "lint:ts-write": "yarn eslint 'test/**/*.ts' 'scripts/**/*.ts' --fix" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/trustwallet/barz.git" + }, + "keywords": [ + "SCW" + ], + "author": "Trust Wallet Team", + "license": "Apache-2.0", + "bugs": { + "url": "https://github.com/trustwallet/barz/issues" + }, + "homepage": "https://github.com/trustwallet/barz#readme", + "devDependencies": { + "@account-abstraction/utils": "^0.6.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/providers": "^5.4.7", + "@ethersproject/strings": "^5.7.0", + "@nomicfoundation/hardhat-chai-matchers": "^1.0.0", + "@nomicfoundation/hardhat-foundry": "^1.1.1", + "@nomicfoundation/hardhat-network-helpers": "^1.0.0", + "@nomicfoundation/hardhat-verify": "^1.0.2", + "@nomiclabs/hardhat-ethers": "^2.2.3", + "@nomiclabs/hardhat-etherscan": "^3.0.0", + "@typechain/ethers-v5": "^10.2.1", + "@typechain/hardhat": "^6.1.5", + "@types/chai": "^4.3.5", + "@types/mocha": ">=9.1.0", + "@typescript-eslint/eslint-plugin": "^6.21.0", + "@typescript-eslint/parser": "^6.8.0", + "chai": "^4.2.0", + "dotenv": "^16.2.0", + "eslint": "^8.51.0", + "ethereumjs-util": "^7.1.5", + "ethers": "^5.4.7", + "ganache-cli": "^6.12.2", + "hardhat": "^2.16.0", + "hardhat-contract-sizer": "^2.8.0", + "hardhat-deploy": "^0.11.30", + "prettier": "^3.0.3", + "prettier-plugin-solidity": "^1.1.3", + "solhint": "^3.4.1", + "solidity-coverage": "^0.8.3", + "ts-generator": "^0.1.1", + "ts-node": "^10.9.1", + "typechain": "^8.1.1", + "typescript": "^5.1.6" + }, + "dependencies": { + "@openzeppelin/contracts": "^4.9.6", + "@peculiar/asn1-ecc": "^2.3.6", + "@peculiar/asn1-schema": "^2.3.6", + "@types/elliptic": "^6.4.14", + "base64url": "^3.0.1", + "cbor": "^9.0.0", + "ecdsa": "^0.7.0", + "elliptic": "^6.5.4", + "web3-utils": "^4.2.1" + } +} diff --git a/scripts/InfrastructureContract.setup.ts b/scripts/InfrastructureContract.setup.ts new file mode 100644 index 0000000..332de7d --- /dev/null +++ b/scripts/InfrastructureContract.setup.ts @@ -0,0 +1,30 @@ +import * as dotenv from 'dotenv'; + +import { securityManagerFixture } from "../test/fixtures/SecurityManagerFixture"; +import { facetRegistryFixture } from "../test/fixtures/FacetRegistryFixture"; + +dotenv.config(); +async function main() { + + const infrastructureOwner = process.env.INFRASTRUCTURE_OWNER + if (infrastructureOwner == "" || infrastructureOwner == null || infrastructureOwner.length != 42) { + console.error("Infrastructure Owner is not set or is invalid") + process.exit(1) + } + + console.log("-------Setting Up Infrastructure Contracts-------") + // Setting the Security Parmeter will be done externally + const securityManager = await securityManagerFixture(infrastructureOwner) + console.log(" Deployed SecurityManager to: ", securityManager.address) + + const facetRegistry = await facetRegistryFixture(infrastructureOwner) + console.log(" Deployed FacetRegistry to: ", facetRegistry.address) + +} + +// We recommend this pattern to be able to use async/await everywhere +// and properly handle errors. +main().catch((error) => { + console.error(error); + process.exitCode = 1; +}); \ No newline at end of file diff --git a/scripts/deployment.config.ts b/scripts/deployment.config.ts new file mode 100644 index 0000000..7abced2 --- /dev/null +++ b/scripts/deployment.config.ts @@ -0,0 +1,8 @@ +import * as dotenv from 'dotenv'; + +dotenv.config(); + +export default { + ENTRYPOINT_ADDRESS: process.env.ENTRYPOINT_ADDRESS ?? '', + PRIVATE_KEY: process.env.PRIVATE_KEY ?? '0000000000000000000000000000000000000000000000000000000000000000' +} \ No newline at end of file diff --git a/src/Create2Factory.ts b/src/Create2Factory.ts new file mode 100644 index 0000000..b0e78cf --- /dev/null +++ b/src/Create2Factory.ts @@ -0,0 +1,120 @@ +// from: https://github.com/Arachnid/deterministic-deployment-proxy +import { BigNumber, BigNumberish, ethers, Signer } from 'ethers' +import { arrayify, hexConcat, hexlify, hexZeroPad, keccak256 } from 'ethers/lib/utils' +import { Provider } from '@ethersproject/providers' +import { TransactionRequest } from '@ethersproject/abstract-provider' + +export class Create2Factory { + factoryDeployed = false + + // from: https://github.com/Arachnid/deterministic-deployment-proxy + static readonly contractAddress = '0x4e59b44847b379578588920ca78fbf26c0b4956c' + static readonly factoryTx = '0xf8a58085174876e800830186a08080b853604580600e600039806000f350fe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf31ba02222222222222222222222222222222222222222222222222222222222222222a02222222222222222222222222222222222222222222222222222222222222222' + static readonly factoryDeployer = '0x3fab184622dc19b6109349b94811493bf2a45362' + static readonly deploymentGasPrice = 100e9 + static readonly deploymentGasLimit = 100000 + static readonly factoryDeploymentFee = (Create2Factory.deploymentGasPrice * Create2Factory.deploymentGasLimit).toString() + + constructor (readonly provider: Provider, + readonly signer = (provider as ethers.providers.JsonRpcProvider).getSigner()) { + } + + /** + * deploy a contract using our deterministic deployer. + * The deployer is deployed (unless it is already deployed) + * NOTE: this transaction will fail if already deployed. use getDeployedAddress to check it first. + * @param initCode delpoyment code. can be a hex string or factory.getDeploymentTransaction(..) + * @param salt specific salt for deployment + * @param gasLimit gas limit or 'estimate' to use estimateGas. by default, calculate gas based on data size. + */ + async deploy (initCode: string | TransactionRequest, salt: BigNumberish = 0, gasLimit?: BigNumberish | 'estimate'): Promise { + await this.deployFactory() + if (typeof initCode !== 'string') { + // eslint-disable-next-line @typescript-eslint/no-base-to-string + initCode = (initCode as TransactionRequest).data!.toString() + } + + const addr = Create2Factory.getDeployedAddress(initCode, salt) + if (await this.provider.getCode(addr).then(code => code.length) > 2) { + return addr + } + + const deployTx = { + to: Create2Factory.contractAddress, + data: this.getDeployTransactionCallData(initCode, salt) + } + if (gasLimit === 'estimate') { + gasLimit = await this.signer.estimateGas(deployTx) + } + + // manual estimation (its bit larger: we don't know actual deployed code size) + if (gasLimit === undefined) { + gasLimit = arrayify(initCode) + .map(x => x === 0 ? 4 : 16) + .reduce((sum, x) => sum + x) + + 200 * initCode.length / 2 + // actual is usually somewhat smaller (only deposited code, not entire constructor) + 6 * Math.ceil(initCode.length / 64) + // hash price. very minor compared to deposit costs + 32000 + + 21000 + + // deployer requires some extra gas + gasLimit = Math.floor(gasLimit * 64 / 63) + } + + const ret = await this.signer.sendTransaction({ ...deployTx, gasLimit }) + await ret.wait() + if (await this.provider.getCode(addr).then(code => code.length) === 2) { + throw new Error('failed to deploy') + } + return addr + } + + getDeployTransactionCallData (initCode: string, salt: BigNumberish = 0): string { + const saltBytes32 = hexZeroPad(hexlify(salt), 32) + return hexConcat([ + saltBytes32, + initCode + ]) + } + + /** + * return the deployed address of this code. + * (the deployed address to be used by deploy() + * @param initCode + * @param salt + */ + static getDeployedAddress (initCode: string, salt: BigNumberish): string { + const saltBytes32 = hexZeroPad(hexlify(salt), 32) + return '0x' + keccak256(hexConcat([ + '0xff', + Create2Factory.contractAddress, + saltBytes32, + keccak256(initCode) + ])).slice(-40) + } + + // deploy the factory, if not already deployed. + async deployFactory (signer?: Signer): Promise { + if (await this._isFactoryDeployed()) { + return + } + await (signer ?? this.signer).sendTransaction({ + to: Create2Factory.factoryDeployer, + value: BigNumber.from(Create2Factory.factoryDeploymentFee) + }) + await this.provider.sendTransaction(Create2Factory.factoryTx) + if (!await this._isFactoryDeployed()) { + throw new Error('fatal: failed to deploy deterministic deployer') + } + } + + async _isFactoryDeployed (): Promise { + if (!this.factoryDeployed) { + const deployed = await this.provider.getCode(Create2Factory.contractAddress) + if (deployed.length > 2) { + this.factoryDeployed = true + } + } + return this.factoryDeployed + } +} diff --git a/src/Utils.ts b/src/Utils.ts new file mode 100644 index 0000000..f8bc273 --- /dev/null +++ b/src/Utils.ts @@ -0,0 +1,9 @@ +export function validateAddresses (addresses: (string | undefined)[]): boolean { + if (addresses == undefined) + return false; + for (const addr of addresses) { + if (addr == null || addr == '' || addr.length != 42) + return false; + } + return true; +} \ No newline at end of file diff --git a/test/AccountFacet.test.ts b/test/AccountFacet.test.ts new file mode 100644 index 0000000..61ff689 --- /dev/null +++ b/test/AccountFacet.test.ts @@ -0,0 +1,455 @@ +import { ethers } from 'hardhat' +import { Wallet } from 'ethers' + +import { AccountFacet, DiamondCutFacet, Barz, Secp256k1VerificationFacet, SecurityManager, TestCounter, FacetRegistry, GuardianFacet, LockFacet, DiamondLoupeFacet, TokenReceiverFacet, DefaultFallbackHandler, TestInvalidSecp256k1VerificationFacet, Secp256r1VerificationFacet } from '../typechain-types' +import { getChainId, diamondCut, increaseBlockTime, generateKeyPair, guardianSecurityPeriod, isUserOperationSuccessful } from './utils/helpers' +import { addFacetSelectorsViaEntryPointOnK1, addFacetSelectorsViaEntryPointOnR1, getFacetBarz, setupDefaultSecuritManager } from './utils/setup' +import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers' +import { createAccountOwner, fund, callGasLimit, verificationGasLimit, maxFeePerGas, AddressOne } from './utils/testutils' + +const { + FacetCutAction, + getSelectors +} = require('./utils/diamond.js') + +import { expect } from "chai" +import { diamondCutFacetFixture } from './fixtures/DiamondCutFacetFixture' +import { accountFacetFixture } from './fixtures/AccountFacetFixture' +import { secp256k1VerificationFacetFixture } from './fixtures/Secp256k1VerificationFacetFixture' +import { barzFixture } from './fixtures/BarzFixture' +import { testCounterFixture } from './fixtures/TestCounterFixture' +import { facetRegistryFixture } from './fixtures/FacetRegistryFixture' +import { lockFacetFixture } from './fixtures/LockFacetFixture' +import { guardianFacetFixture } from './fixtures/GuardianFacetFixture' +import { testTokenFixture } from './fixtures/TestTokenFixture' +import { executeBatchCallData, executeCallData, fillUserOpDefaults, getUserOpHash, signUserOpK1Curve, signUserOpR1Curve, callFromEntryPointOnK1, callFromEntryPointOnR1 } from './utils/UserOp' +import { EntryPoint } from '../typechain-types/core' +import { entryPointFixture } from './fixtures/EntryPointFixture' +import { diamondLoupeFacetFixture } from './fixtures/DiamondLoupeFacetFixture' +import { secp256r1VerificationFacetFixture } from './fixtures/Secp256r1VerificationFacetFixture' +import { tokenReceiverFacetFixture } from './fixtures/TokenReceiverFacetFixture' +import { defaultFallbackHandlerFixture } from './fixtures/DefaultFallbackHandlerFixture' +import { testInvalidSecp256k1VerificationFacetFixture } from './fixtures/TestInvalidSecp256k1VerificationFacetFixture' + +// TODO: All Test code will be refactored including AccountFacet test + +describe('Account Facet', () => { + let diamondCutFacet: DiamondCutFacet + let diamondCutBarz: DiamondCutFacet + let defaultFallbackHandler: DefaultFallbackHandler + let securityManager: SecurityManager + let facetRegistry: FacetRegistry + let accountFacet: AccountFacet + let accountBarz: AccountFacet + let mockAccountBarz: AccountFacet + let guardianFacet: GuardianFacet + let guardianBarz: GuardianFacet + let k1Facet: Secp256k1VerificationFacet + let r1Facet: Secp256r1VerificationFacet + let testInvalidK1Facet: TestInvalidSecp256k1VerificationFacet + let diamondLoupeFacet: DiamondLoupeFacet + let lockFacet: LockFacet + let lockBarz: LockFacet + let entryPoint: EntryPoint + let tokenReceiverFacet: TokenReceiverFacet + let guardian: SignerWithAddress + let facetRegistryOwner: SignerWithAddress + let securityManagerOwner: SignerWithAddress + let mockEntryPoint: SignerWithAddress + let owner: Wallet + let barz: Barz + let mockBarz: Barz + let testCounter: TestCounter + let incrementCall: any + let chainId: number + let testExecData: any + const value = 0 + let lockFacetSelectors: any + let guardianFacetSelectors: any + + const addGuardian = async (owner: any, newGuardian: SignerWithAddress, nonce: number, isR1 = false): Promise => { + const addGuardianCall = guardianFacet.interface.encodeFunctionData("addGuardian", [newGuardian.address]) + const callData = executeCallData(barz.address, 0, addGuardianCall) + if (isR1) + await callFromEntryPointOnR1(entryPoint, barz.address, owner, callData) + else + await callFromEntryPointOnK1(entryPoint, barz.address, owner, callData) + + await increaseBlockTime(guardianSecurityPeriod) + await expect(guardianBarz.confirmGuardianAddition(newGuardian.address)).to.emit(guardianBarz, "GuardianAdded") + expect(await guardianBarz.isGuardian(newGuardian.address)).to.be.true + return nonce + } + + before(async () => { + [facetRegistryOwner, securityManagerOwner, mockEntryPoint, guardian] = await ethers.getSigners() + + chainId = await getChainId() + testExecData = await executeCallData(AddressOne, 10, "0x00") + securityManager = await setupDefaultSecuritManager(securityManagerOwner) + facetRegistry = await facetRegistryFixture(facetRegistryOwner.address) + accountFacet = await accountFacetFixture() + k1Facet = await secp256k1VerificationFacetFixture() + r1Facet = await secp256r1VerificationFacetFixture() + guardianFacet = await guardianFacetFixture(securityManager) + lockFacet = await lockFacetFixture(securityManager) + diamondCutFacet = await diamondCutFacetFixture(securityManager) + diamondLoupeFacet = await diamondLoupeFacetFixture() + tokenReceiverFacet = await tokenReceiverFacetFixture() + defaultFallbackHandler = await defaultFallbackHandlerFixture(diamondCutFacet, accountFacet, tokenReceiverFacet, diamondLoupeFacet) + + entryPoint = await entryPointFixture() + + testInvalidK1Facet = await testInvalidSecp256k1VerificationFacetFixture() + + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(accountFacet.address, getSelectors(accountFacet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(lockFacet.address, getSelectors(lockFacet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(guardianFacet.address, getSelectors(guardianFacet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(k1Facet.address, getSelectors(k1Facet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(r1Facet.address, getSelectors(r1Facet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(diamondCutFacet.address, getSelectors(diamondCutFacet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(diamondLoupeFacet.address, getSelectors(diamondLoupeFacet)) + + lockFacetSelectors = getSelectors(lockFacet).filter((item: string) => item !== lockFacet.interface.getSighash('securityManager')) + guardianFacetSelectors = getSelectors(guardianFacet).filter((item: string) => item !== guardianFacet.interface.getSighash('securityManager')) + + }) + + beforeEach(async () => { + owner = createAccountOwner() + await fund(owner.address) + + barz = await barzFixture(accountFacet, k1Facet, entryPoint, facetRegistry, defaultFallbackHandler, owner.publicKey) + diamondCutBarz = await getFacetBarz('DiamondCutFacet', barz) + accountBarz = await getFacetBarz("AccountFacet", barz) + + mockBarz = await barzFixture(accountFacet, k1Facet, mockEntryPoint, facetRegistry, defaultFallbackHandler, owner.publicKey) + mockAccountBarz = await getFacetBarz('AccountFacet', mockBarz) + }) + + describe('Setup', () => { + it('Should revert if verification facet do not have initializeSigner', async () => { + const salt = 1 + const Factory = await ethers.getContractFactory("BarzFactory") + const factory = await Factory.deploy(accountFacet.address, entryPoint.address, facetRegistry.address, defaultFallbackHandler.address) + await expect(factory.createAccount(testInvalidK1Facet.address, owner.publicKey, salt)).to.be.reverted + }) + }) + + describe('# entryPoint', () => { + it('Should return valid EntryPoint address', async () => { + expect(await accountBarz.entryPoint()).to.equal(entryPoint.address) + }) + }) + describe('# nonce', () => { + it('Should return valid nonce', async () => { + const nonce = await accountBarz.getNonce() + + expect(nonce).to.equal(0) + }) + }) + + describe('# k1 verification scheme', () => { + + beforeEach(async () => { + testCounter = await testCounterFixture() + incrementCall = testCounter.interface.encodeFunctionData('incrementCounter') + + barz = await barzFixture(accountFacet, k1Facet, entryPoint, facetRegistry, defaultFallbackHandler, owner.publicKey) + diamondCutBarz = await getFacetBarz('DiamondCutFacet', barz) + accountBarz = await getFacetBarz("AccountFacet", barz) + guardianBarz = await getFacetBarz('GuardianFacet', barz) + lockBarz = await getFacetBarz('LockFacet', barz) + + await entryPoint.depositTo(barz.address, { + value: ethers.utils.parseEther('0.5'), + }) + }) + + describe('# execute', () => { + it('Should revert if caller is not EntryPoint', async () => { + await expect(accountBarz.connect(owner).execute(testCounter.address, value, incrementCall, { gasPrice: 1000 })).to.be.revertedWith('account: not from EntryPoint') + }) + it('Should call destination contract through Account', async () => { + // Generate function call + const count = await testCounter.getCount() + expect(count).to.equal(0) + + const callData = executeCallData(testCounter.address, 0, incrementCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, callData)).to.emit(entryPoint, "UserOperationEvent") + + const updatedCount = await testCounter.getCount() + expect(updatedCount).to.equal(1) + }) + + + }) + describe('# executeBatch', () => { + it('Should revert if caller is not EntryPoint', async () => { + await expect(accountBarz.connect(owner).executeBatch([testCounter.address], [value], [incrementCall], { gasPrice: 1000 })).to.be.revertedWith('account: not from EntryPoint') + }) + + it("Should batch execute if caller is EntryPoint", async () => { + const count = await testCounter.getCount(); + expect(count).to.equal(0); + expect( + mockAccountBarz + .connect(mockEntryPoint) + .executeBatch( + [testCounter.address, testCounter.address], + [value, value], + [incrementCall, incrementCall] + ) + ); + + const updatedCount = await testCounter.getCount(); + expect(updatedCount).to.equal(2); + }); + + it('Should revert if functions length is greater than destinations length', async () => { + await expect(mockAccountBarz.connect(mockEntryPoint).executeBatch([testCounter.address], [value, value], [incrementCall, incrementCall])).to.be.revertedWithCustomError(mockAccountBarz, 'AccountFacet__InvalidArrayLength') + }) + + it('Should revert if destinations length is greater than functions length', async () => { + await expect(mockAccountBarz.connect(mockEntryPoint).executeBatch([testCounter.address, owner.address], [value, value], [incrementCall])).to.be.revertedWithCustomError(mockAccountBarz, 'AccountFacet__InvalidArrayLength') + }) + + it('Should revert if value length is differs with functions length', async () => { + await expect(mockAccountBarz.connect(mockEntryPoint).executeBatch([testCounter.address, owner.address], [value, value], [incrementCall])).to.be.revertedWithCustomError(mockAccountBarz, 'AccountFacet__InvalidArrayLength') + }) + + it('Should batch Tx using Multi-call', async () => { + let nonce = 0 + const testToken = await testTokenFixture() + const guardianFacetSelectors = getSelectors(guardianFacet).filter((item: string) => item !== guardianFacet.interface.getSighash('securityManager')) + await addFacetSelectorsViaEntryPointOnK1(barz, owner, guardianFacet, guardianFacetSelectors, entryPoint) + await addFacetSelectorsViaEntryPointOnK1(barz, owner, diamondCutFacet, [diamondCutFacet.interface.getSighash("approveDiamondCut")], entryPoint) + + await addGuardian(owner, guardian, nonce++) + // State Before Multi-call + const countBefore = await testCounter.getCount() + expect(countBefore).to.equal(0) + const balanceBefore = await testToken.balanceOf(owner.address) + expect(balanceBefore).to.equal(0) + await expect(lockBarz.lock()).to.be.revertedWith('Barz: Function does not exist') + // Counter.incrementCounter -> Token.mint -> Token.Transfer -> diamondCut(approve) (eventually doing diamondCut) + const mintAmount = 10 + const mintCall = testToken.interface.encodeFunctionData('mint', [owner.address, mintAmount]) + const lockCut = diamondCut(lockFacet.address, FacetCutAction.Add, getSelectors(lockFacet)) + + const approveDiamondCutCall = diamondCutFacet.interface.encodeFunctionData("approveDiamondCut", [lockCut]) + await diamondCutBarz.connect(guardian).approveDiamondCut(lockCut) + + const callData = executeBatchCallData([testCounter.address, testToken.address, accountBarz.address], [value, value, value], [incrementCall, mintCall, approveDiamondCutCall]) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, callData)).to.emit(diamondCutBarz, "DiamondCut") + + // State After Multi-call + const countAfter = await testCounter.getCount() + expect(countAfter).to.equal(1) + const balanceAfter = await testToken.balanceOf(owner.address) + expect(balanceAfter).to.equal(mintAmount) + await expect(lockBarz.connect(guardian).lock()).to.emit(lockBarz, "Locked") + }) + }) + describe('# validateUserOp', () => { + it('Should revert if caller is not EntryPoint', async () => { + const userOp = signUserOpK1Curve(fillUserOpDefaults({ + sender: owner.address, + callGasLimit, + verificationGasLimit, + maxFeePerGas + }), owner, entryPoint.address, chainId) + const opHash = getUserOpHash(userOp, entryPoint.address, chainId) + // Manually set gasPrice to make Coverage to pass + await expect(accountBarz.connect(owner).validateUserOp(userOp, opHash, 0, { gasPrice: 1000 })).to.be.revertedWith('account: not from EntryPoint') + }) + + it('Should return failure & emit Locked event if Account is Locked', async () => { + let nonce = 0 + + const guardianCutTx = await addFacetSelectorsViaEntryPointOnK1(barz, owner, guardianFacet, guardianFacetSelectors, entryPoint) + const guardianCutReceipt = await guardianCutTx.wait() + expect(guardianCutReceipt.status).to.equal(1) + + const lockCutTx = await addFacetSelectorsViaEntryPointOnK1(barz, owner, lockFacet, lockFacetSelectors, entryPoint) + const lockCutReceipt = await lockCutTx.wait() + expect(lockCutReceipt.status).to.equal(1) + + await addGuardian(owner, guardian, nonce++) + await fund(barz) + + await expect(lockBarz.connect(guardian).lock()).to.emit(lockBarz, "Locked") + expect(await isUserOperationSuccessful(await callFromEntryPointOnK1(entryPoint, barz.address, owner, testExecData))).to.be.false + }) + it('Should emit Success event for valid signature', async () => { + const userOp = signUserOpK1Curve(fillUserOpDefaults({ + sender: barz.address, + callGasLimit, + verificationGasLimit, + maxFeePerGas + }), owner, entryPoint.address, chainId) + const userOpHash = getUserOpHash(userOp, entryPoint.address, chainId) + + await expect(entryPoint.handleOps([userOp], barz.address)).to.emit(accountBarz, "VerificationSuccess").withArgs(userOpHash) + }) + it('Should emit Failure for invalid signature', async () => { + const userOp = signUserOpK1Curve(fillUserOpDefaults({ + sender: barz.address, + callGasLimit, + verificationGasLimit, + maxFeePerGas, + }), owner, entryPoint.address, chainId) + userOp.signature = ethers.utils.randomBytes(32) + + await expect(entryPoint.handleOps([userOp], barz.address)).to.be.reverted + }) + }) + }) + + describe('# r1 verification scheme', () => { + let owner: any + let ownerBytes: any + let isR1True = true + + beforeEach(async () => { + const { keyPair, publicKeyBytes } = generateKeyPair() + owner = keyPair + ownerBytes = publicKeyBytes + testCounter = await testCounterFixture() + incrementCall = testCounter.interface.encodeFunctionData('incrementCounter') + + barz = await barzFixture(accountFacet, r1Facet, entryPoint, facetRegistry, defaultFallbackHandler, ownerBytes) + diamondCutBarz = await getFacetBarz('DiamondCutFacet', barz) + accountBarz = await getFacetBarz("AccountFacet", barz) + guardianBarz = await getFacetBarz('GuardianFacet', barz) + lockBarz = await getFacetBarz('LockFacet', barz) + + mockBarz = await barzFixture(accountFacet, r1Facet, mockEntryPoint, facetRegistry, defaultFallbackHandler, ownerBytes) + mockAccountBarz = await getFacetBarz('AccountFacet', mockBarz) + + await fund(barz.address) + }) + + describe('# execute', () => { + it('Should revert if caller is not EntryPoint', async () => { + await expect(accountBarz.execute(testCounter.address, value, incrementCall, { gasPrice: 1000 })).to.be.revertedWith('account: not from EntryPoint') + }) + it('Should call destination contract through Account', async () => { + // Generate function call + const count = await testCounter.getCount() + expect(count).to.equal(0) + + const callData = executeCallData(testCounter.address, 0, incrementCall) + await expect(callFromEntryPointOnR1(entryPoint, barz.address, owner, callData)).to.emit(entryPoint, "UserOperationEvent") + + const updatedCount = await testCounter.getCount() + expect(updatedCount).to.equal(1) + }) + }) + describe('# executeBatch', () => { + it('Should revert if caller is not EntryPoint', async () => { + await expect(accountBarz.executeBatch([testCounter.address], [value], [incrementCall], { gasPrice: 1000 })).to.be.revertedWith('account: not from EntryPoint') + }) + + it('Should revert if functions length is greater than destinations length', async () => { + await expect(mockAccountBarz.connect(mockEntryPoint).executeBatch([testCounter.address], [value, value], [incrementCall, incrementCall])).to.be.revertedWithCustomError(mockAccountBarz, 'AccountFacet__InvalidArrayLength') + }) + + it('Should revert if destinations length is greater than functions length', async () => { + await expect(mockAccountBarz.connect(mockEntryPoint).executeBatch([testCounter.address, facetRegistryOwner.address], [value, value], [incrementCall])).to.be.revertedWithCustomError(mockAccountBarz, 'AccountFacet__InvalidArrayLength') + }) + + it('Should revert if value length is differs with functions length', async () => { + await expect(mockAccountBarz.connect(mockEntryPoint).executeBatch([testCounter.address, facetRegistryOwner.address], [value, value], [incrementCall])).to.be.revertedWithCustomError(mockAccountBarz, 'AccountFacet__InvalidArrayLength') + }) + + it('Should batch Tx using Multi-call', async () => { + let nonce = 0 + + const randomAddress = ethers.Wallet.createRandom().address + const testToken = await testTokenFixture() + const guardianFacetSelectors = getSelectors(guardianFacet).filter((item: string) => item !== guardianFacet.interface.getSighash('securityManager')) + await addFacetSelectorsViaEntryPointOnR1(barz, owner, guardianFacet, guardianFacetSelectors, entryPoint) + await addFacetSelectorsViaEntryPointOnR1(barz, owner, diamondCutFacet, [diamondCutFacet.interface.getSighash("approveDiamondCut")], entryPoint) + + await addGuardian(owner, guardian, nonce++, isR1True) + // State Before Multi-call + const countBefore = await testCounter.getCount() + expect(countBefore).to.equal(0) + const balanceBefore = await testToken.balanceOf(randomAddress) + expect(balanceBefore).to.equal(0) + await expect(lockBarz.lock()).to.be.revertedWith('Barz: Function does not exist') + // Counter.incrementCounter -> Token.mint -> Token.Transfer -> diamondCut approval (eventually doing diamondCut) + const mintAmount = 10 + const mintCall = testToken.interface.encodeFunctionData('mint', [randomAddress, mintAmount]) + const lockCut = diamondCut(lockFacet.address, FacetCutAction.Add, getSelectors(lockFacet)) + + const approveDiamondCutCall = diamondCutFacet.interface.encodeFunctionData("approveDiamondCut", [lockCut]) + await diamondCutBarz.connect(guardian).approveDiamondCut(lockCut) + + const callData = executeBatchCallData([testCounter.address, testToken.address, accountBarz.address], [value, value, value], [incrementCall, mintCall, approveDiamondCutCall]) + await expect(callFromEntryPointOnR1(entryPoint, barz.address, owner, callData)).to.emit(diamondCutBarz, "DiamondCut") + + // State Before Multi-call + const countAfter = await testCounter.getCount() + expect(countAfter).to.equal(1) + const balanceAfter = await testToken.balanceOf(randomAddress) + expect(balanceAfter).to.equal(mintAmount) + await expect(lockBarz.connect(guardian).lock()).to.emit(lockBarz, "Locked") + }) + }) + describe('# validateUserOp', () => { + it('Should revert if caller is not EntryPoint', async () => { + const userOp = signUserOpR1Curve(fillUserOpDefaults({ + sender: owner.address, + callGasLimit, + verificationGasLimit, + maxFeePerGas + }), owner, entryPoint.address, chainId) + const opHash = getUserOpHash(userOp, entryPoint.address, chainId) + + await expect(accountBarz.validateUserOp(userOp, opHash, 0, { gasPrice: 17180044 })).to.be.revertedWith('account: not from EntryPoint') + }) + + it('Should return failure & emit Locked event if Account is Locked', async () => { + let nonce = 0 + + const guardianCutTx = await addFacetSelectorsViaEntryPointOnR1(barz, owner, guardianFacet, guardianFacetSelectors, entryPoint) + const guardianCutReceipt = await guardianCutTx.wait() + expect(guardianCutReceipt.status).to.equal(1) + + const lockCutTx = await addFacetSelectorsViaEntryPointOnR1(barz, owner, lockFacet, lockFacet, entryPoint) + const lockCutReceipt = await lockCutTx.wait() + expect(lockCutReceipt.status).to.equal(1) + + await addGuardian(owner, guardian, nonce++, isR1True) + await fund(barz) + await expect(lockBarz.connect(guardian).lock()).to.emit(lockBarz, "Locked") + expect(await isUserOperationSuccessful(await callFromEntryPointOnR1(entryPoint, barz.address, owner, testExecData))).to.be.false + }) + it('Should emit Success event for valid signature', async () => { + const verificationGasLimit = 1000000 + const userOp = signUserOpR1Curve(fillUserOpDefaults({ + sender: barz.address, + callGasLimit, + verificationGasLimit, + maxFeePerGas + }), owner, entryPoint.address, chainId) + const userOpHash = getUserOpHash(userOp, entryPoint.address, chainId) + + await expect(entryPoint.handleOps([userOp], barz.address)).to.emit(accountBarz, "VerificationSuccess").withArgs(userOpHash) + }) + it('Should emit Failure for invalid signature', async () => { + const userOp = signUserOpR1Curve(fillUserOpDefaults({ + sender: barz.address, + callGasLimit, + verificationGasLimit, + maxFeePerGas, + }), owner, entryPoint.address, chainId) + userOp.signature = ethers.utils.randomBytes(32) + + await expect(entryPoint.handleOps([userOp], barz.address)).to.be.reverted + }) + }) + }) +}) \ No newline at end of file diff --git a/test/AccountRecoveryFacet.test.ts b/test/AccountRecoveryFacet.test.ts new file mode 100644 index 0000000..bc1fcd1 --- /dev/null +++ b/test/AccountRecoveryFacet.test.ts @@ -0,0 +1,445 @@ +import { ethers } from 'hardhat' +import { BigNumber, Wallet } from 'ethers' + +import { AccountFacet, DiamondCutFacet, Barz, Secp256k1VerificationFacet, SecurityManager, GuardianFacet, FacetRegistry, AccountRecoveryFacet, DiamondLoupeFacet, TokenReceiverFacet, LockFacet, DefaultFallbackHandler } from '../typechain-types' +import { getChainId, increaseBlockTime, guardianSecurityPeriod, recoveryPeriod, getBlockTimestamp, isUserOperationSuccessful, getEthSignMessageHash } from './utils/helpers' +import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers' +import { AddressOne, createAccountOwner, fund, getMessageHash } from './utils/testutils' +import { keccak256 } from "@ethersproject/keccak256"; + +const { + getSelectors +} = require('./utils/diamond.js') + +import { expect } from "chai" +import { diamondCutFacetFixture } from './fixtures/DiamondCutFacetFixture' +import { accountFacetFixture } from './fixtures/AccountFacetFixture' +import { secp256k1VerificationFacetFixture } from './fixtures/Secp256k1VerificationFacetFixture' +import { barzFixture } from './fixtures/BarzFixture' +import { addFacetSelectorsViaEntryPointOnK1, getFacetBarz, setupDefaultSecuritManager } from './utils/setup' +import { guardianFacetFixture } from './fixtures/GuardianFacetFixture' +import { facetRegistryFixture } from './fixtures/FacetRegistryFixture' +import { accountRecoveryFacetFixture } from './fixtures/AccountRecoveryFacetFixture' +import { arrayify } from 'ethers/lib/utils' +import { EntryPoint } from '../typechain-types/core' +import { callFromEntryPointOnK1, executeCallData } from './utils/UserOp' +import { entryPointFixture } from './fixtures/EntryPointFixture' +import { diamondLoupeFacetFixture } from './fixtures/DiamondLoupeFacetFixture' +import { tokenReceiverFacetFixture } from './fixtures/TokenReceiverFacetFixture' +import { lockFacetFixture } from './fixtures/LockFacetFixture' +import { defaultFallbackHandlerFixture } from './fixtures/DefaultFallbackHandlerFixture' +import { ecsign, toRpcSig } from 'ethereumjs-util' + +describe('Account Recovery Facet', () => { + let diamondCutFacet: DiamondCutFacet + let diamondCutBarz: DiamondCutFacet + let securityManager: SecurityManager + let facetRegistry: FacetRegistry + let defaultFallbackHandler: DefaultFallbackHandler + let accountFacet: AccountFacet + let accountBarz: AccountFacet + let k1Facet: Secp256k1VerificationFacet + let k1Barz: Secp256k1VerificationFacet + let accountRecoveryFacet: AccountRecoveryFacet + let accountRecoveryBarz: AccountRecoveryFacet + let diamondLoupeFacet: DiamondLoupeFacet + let tokenReceiverFacet: TokenReceiverFacet + let lockBarz: LockFacet + let lockFacet: LockFacet + let entryPoint: EntryPoint + let guardian1: SignerWithAddress + let guardian2: SignerWithAddress + let recoveryOwner: Wallet + let user1: SignerWithAddress + let securityManagerOwner: SignerWithAddress + let facetRegistryOwner: SignerWithAddress + let owner: Wallet + let barz: Barz + let guardianFacet: GuardianFacet + let guardianBarz: GuardianFacet + let chainId: number + const recoveryNonce = 0 + let ownerSeed = 0 + let testExecData: any + before(async () => { + [guardian1, guardian2, securityManagerOwner, facetRegistryOwner, user1] = await ethers.getSigners() + owner = createAccountOwner(ownerSeed++) + recoveryOwner = createAccountOwner(ownerSeed++) + await fund(owner.address) + + testExecData = executeCallData(AddressOne, 10, "0x00") + + chainId = await getChainId() + + securityManager = await setupDefaultSecuritManager(securityManagerOwner) + facetRegistry = await facetRegistryFixture(facetRegistryOwner.address) + accountFacet = await accountFacetFixture() + k1Facet = await secp256k1VerificationFacetFixture() + guardianFacet = await guardianFacetFixture(securityManager) + accountRecoveryFacet = await accountRecoveryFacetFixture(securityManager) + diamondCutFacet = await diamondCutFacetFixture(securityManager) + entryPoint = await entryPointFixture() + diamondLoupeFacet = await diamondLoupeFacetFixture() + tokenReceiverFacet = await tokenReceiverFacetFixture() + lockFacet = await lockFacetFixture(securityManager) + defaultFallbackHandler = await defaultFallbackHandlerFixture(diamondCutFacet, accountFacet, tokenReceiverFacet, diamondLoupeFacet) + + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(k1Facet.address, getSelectors(k1Facet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(guardianFacet.address, getSelectors(guardianFacet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(diamondCutFacet.address, getSelectors(diamondCutFacet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(accountFacet.address, getSelectors(accountFacet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(accountRecoveryFacet.address, getSelectors(accountRecoveryFacet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(diamondLoupeFacet.address, getSelectors(diamondLoupeFacet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(lockFacet.address, getSelectors(lockFacet)) + + expect(await facetRegistry.owner()).to.equal(facetRegistryOwner.address) + }) + beforeEach(async () => { + barz = await barzFixture(accountFacet, k1Facet, entryPoint, facetRegistry, defaultFallbackHandler, owner.publicKey) + accountBarz = await getFacetBarz('AccountFacet', barz) + guardianBarz = await getFacetBarz('GuardianFacet', barz) + diamondCutBarz = await getFacetBarz('DiamondCutFacet', barz) + accountRecoveryBarz = await getFacetBarz('AccountRecoveryFacet', barz) + k1Barz = await getFacetBarz('Secp256k1VerificationFacet', barz) + lockBarz = await getFacetBarz('LockFacet', barz) + await entryPoint.depositTo(barz.address, { + value: ethers.utils.parseEther('0.5'), + }) + await fund(barz) + }) + const setupAccountRecoveryBarz = async () => { + const verificationFacetSelector = [k1Facet.interface.getSighash('isValidKeyType'), k1Facet.interface.getSighash('initializeSigner'), k1Facet.interface.getSighash('uninitializeSigner')] + await expect(addFacetSelectorsViaEntryPointOnK1(barz, owner, k1Facet, verificationFacetSelector, entryPoint)).to.emit(diamondCutBarz, "DiamondCut") + + const lockFacetSelectors = getSelectors(lockFacet).filter((item: string) => item !== lockFacet.interface.getSighash('securityManager')) + await addFacetSelectorsViaEntryPointOnK1(barz, owner, lockFacet, lockFacetSelectors, entryPoint) + + const guardianFacetSelectors = getSelectors(guardianFacet).filter((item: string) => item !== guardianFacet.interface.getSighash('securityManager')) + await addFacetSelectorsViaEntryPointOnK1(barz, owner, guardianFacet, guardianFacetSelectors, entryPoint); + + const accountRecoveryFacetSelectors = getSelectors(accountRecoveryFacet).filter((item: string) => item !== accountRecoveryFacet.interface.getSighash('securityManager')) + const accountRecoveryCutTx = await addFacetSelectorsViaEntryPointOnK1(barz, owner, accountRecoveryFacet, accountRecoveryFacetSelectors, entryPoint); + const accountRecoveryCutReceipt = await accountRecoveryCutTx.wait() + + expect(accountRecoveryCutReceipt.status).to.equal(1) + } + const addGuardian = async (newGuardian: SignerWithAddress) => { + const addGuardianCall = guardianFacet.interface.encodeFunctionData("addGuardian", [newGuardian.address]) + const callData = executeCallData(barz.address, 0, addGuardianCall) + await callFromEntryPointOnK1(entryPoint, barz.address, owner, callData) + + await increaseBlockTime(guardianSecurityPeriod) + await expect(guardianBarz.confirmGuardianAddition(newGuardian.address)).to.emit(guardianBarz, "GuardianAdded") + + expect(await guardianBarz.isGuardian(newGuardian.address)).to.be.true + } + const getExecuteRecoveryHash = (recoveryOwner: Wallet, accountRecoveryBarz: AccountRecoveryFacet, recoveryNonce: number | BigNumber) => { + const encodedData = ethers.utils.defaultAbiCoder.encode(['bytes', 'string', 'address', 'uint256', 'uint128'], [recoveryOwner.publicKey, 'ExecuteRecovery', accountRecoveryBarz.address, chainId, recoveryNonce]) + return keccak256(encodedData) + } + const getCancelRecoveryHash = (recoveryOwner: Wallet, accountRecoveryBarz: AccountRecoveryFacet, cancelRecoveryNonce: number | BigNumber) => { + const encodedData = ethers.utils.defaultAbiCoder.encode(['bytes', 'string', 'address', 'uint256', 'uint128'], [recoveryOwner.publicKey, 'CancelRecovery', accountRecoveryBarz.address, chainId, cancelRecoveryNonce]) + return keccak256(encodedData) + } + + it("Should add Account Recovery Facet to wallet", async () => { + const accountRecoveryFacetSelectors = getSelectors(accountRecoveryFacet).filter((item: string) => item !== accountRecoveryFacet.interface.getSighash('securityManager')) + const accountRecoveryCutTx = await addFacetSelectorsViaEntryPointOnK1(barz, owner, accountRecoveryFacet, accountRecoveryFacetSelectors, entryPoint); + const accountRecoveryCutReceipt = await accountRecoveryCutTx.wait() + expect(accountRecoveryCutReceipt.status).to.equal(1) + }) + describe("# executeRecovery", () => { + it("Should revert if guardian doesn't exist", async () => { + await setupAccountRecoveryBarz() + + await expect(accountRecoveryBarz.executeRecovery(recoveryOwner.publicKey, [guardian1.address], ["0x00"])).to.be.revertedWithCustomError(accountRecoveryBarz, "AccountRecoveryFacet__InvalidGuardian") + await expect(accountRecoveryBarz.executeRecovery(recoveryOwner.publicKey, [], [])).to.be.revertedWithCustomError(accountRecoveryBarz, "ZeroApproverLength") + }) + it("Should execute recovery with Guardian signature", async () => { + await setupAccountRecoveryBarz() + await addGuardian(guardian1) + + const encodedData = ethers.utils.defaultAbiCoder.encode(['bytes', 'string', 'address', 'uint256', 'uint128'], [recoveryOwner.publicKey, 'ExecuteRecovery', accountRecoveryBarz.address, chainId, recoveryNonce]) + const hash = keccak256(encodedData) + const signature = await guardian1.signMessage(arrayify(hash)) + + await expect(accountRecoveryBarz.executeRecovery(recoveryOwner.publicKey, [guardian1.address], [signature])).to.emit(accountRecoveryBarz, "RecoveryExecuted") + }) + it("Should revert if duplicate guardian executing recovery", async () => { + await setupAccountRecoveryBarz() + + await addGuardian(guardian1) + await addGuardian(guardian2) + const hash = getExecuteRecoveryHash(recoveryOwner, accountRecoveryBarz, recoveryNonce) + const signature = await guardian1.signMessage(arrayify(hash)) + + expect(await k1Barz.owner()).to.equal(owner.address.toLowerCase()) + await expect(accountRecoveryBarz.executeRecovery(recoveryOwner.publicKey, [guardian1.address, guardian1.address], [signature, signature])).to.be.revertedWithCustomError(accountRecoveryBarz, "DuplicateApprover") + }) + it("Should revert if invalid signature in recovery with Guardian", async () => { + await setupAccountRecoveryBarz() + const encodedData = ethers.utils.defaultAbiCoder.encode(['bytes', 'string', 'address', 'uint256', 'uint128'], [recoveryOwner.publicKey, 'InvalidSignature', accountRecoveryBarz.address, chainId, recoveryNonce]) + const hash = keccak256(encodedData) + await addGuardian(guardian1) + const signature = await guardian1.signMessage(arrayify(hash)) + await expect(accountRecoveryBarz.executeRecovery(recoveryOwner.publicKey, [guardian1.address], [signature])).to.be.revertedWithCustomError(accountRecoveryBarz, "AccountRecoveryFacet__InvalidGuardianSignature") + }) + it("Should execute recovery with on-chain approvals", async () => { + await setupAccountRecoveryBarz() + await addGuardian(guardian1) + await addGuardian(guardian2) + + await accountRecoveryBarz.connect(guardian1).approveAccountRecovery(recoveryOwner.publicKey) + await expect(accountRecoveryBarz.connect(guardian2).approveAccountRecovery(recoveryOwner.publicKey)).to.emit(accountRecoveryBarz, "RecoveryExecuted") + }) + it("Should execute recovery with both on-chain and off-chain approvals", async () => { + await setupAccountRecoveryBarz() + await addGuardian(guardian1) + await addGuardian(guardian2) + + await accountRecoveryBarz.connect(guardian2).approveAccountRecovery(recoveryOwner.publicKey) + + const hash = getExecuteRecoveryHash(recoveryOwner, accountRecoveryBarz, recoveryNonce) + const signature = await guardian1.signMessage(arrayify(hash)) + + await expect(accountRecoveryBarz.executeRecovery(recoveryOwner.publicKey, [guardian1.address], [signature])).to.emit(accountRecoveryBarz, "RecoveryExecuted") + }) + it("Should revert if on-chain approver reattempts to approve off-chain", async () => { + await setupAccountRecoveryBarz() + await addGuardian(guardian1) + await addGuardian(guardian2) + + // NOTE: Guardian 1 already approved but wants to approve again with off-chain signature + await accountRecoveryBarz.connect(guardian1).approveAccountRecovery(recoveryOwner.publicKey) + + const hash = getExecuteRecoveryHash(recoveryOwner, accountRecoveryBarz, recoveryNonce) + const signature1 = await guardian1.signMessage(arrayify(hash)) + const signature2 = await guardian2.signMessage(arrayify(hash)) + + await expect(accountRecoveryBarz.executeRecovery(recoveryOwner.publicKey, [guardian2.address, guardian1.address], [signature2, signature1])).to.be.revertedWithCustomError(accountRecoveryBarz, "AccountRecoveryFacet__DuplicateApproval") + await expect(accountRecoveryBarz.executeRecovery(recoveryOwner.publicKey, [guardian1.address], [signature1])).to.be.revertedWithCustomError(accountRecoveryBarz, "AccountRecoveryFacet__DuplicateApproval") + }) + }) + describe("# cancelRecovery", ()=> { + it("Should revert if duplicate guardian canceling recovery", async () => { + await setupAccountRecoveryBarz() + + await addGuardian(guardian1) + await addGuardian(guardian2) + const hash = getExecuteRecoveryHash(recoveryOwner, accountRecoveryBarz, recoveryNonce) + const signature = await guardian1.signMessage(arrayify(hash)) + const signature2 = await guardian2.signMessage(arrayify(hash)) + expect(await k1Barz.owner()).to.equal(owner.address.toLowerCase()) + await expect(accountRecoveryBarz.executeRecovery(recoveryOwner.publicKey, [guardian1.address, guardian2.address], [signature, signature2])).to.emit(accountRecoveryBarz, "RecoveryExecuted") + + const cancelRecoveryNonce = await accountRecoveryBarz.getRecoveryNonce() + const cancelHash = getCancelRecoveryHash(recoveryOwner, accountRecoveryBarz, cancelRecoveryNonce) + + const cancelSignature1 = await guardian1.signMessage(arrayify(cancelHash)) + + await expect(accountRecoveryBarz.cancelRecovery(recoveryOwner.publicKey, [guardian1.address, guardian1.address], [cancelSignature1, cancelSignature1])).to.be.revertedWithCustomError(accountRecoveryBarz, "DuplicateApprover") + }) + it("Should cancel recovery with both on-chain and off-chain approvals", async () => { + await setupAccountRecoveryBarz() + + await addGuardian(guardian1) + await addGuardian(guardian2) + const hash = getExecuteRecoveryHash(recoveryOwner, accountRecoveryBarz, recoveryNonce) + const signature = await guardian1.signMessage(arrayify(hash)) + const signature2 = await guardian2.signMessage(arrayify(hash)) + expect(await k1Barz.owner()).to.equal(owner.address.toLowerCase()) + await expect(accountRecoveryBarz.executeRecovery(recoveryOwner.publicKey, [guardian1.address, guardian2.address], [signature, signature2])).to.emit(accountRecoveryBarz, "RecoveryExecuted") + + await accountRecoveryBarz.connect(guardian2).approveCancelRecovery(recoveryOwner.publicKey) + + const cancelRecoveryNonce = await accountRecoveryBarz.getRecoveryNonce() + const cancelHash = getCancelRecoveryHash(recoveryOwner, accountRecoveryBarz, cancelRecoveryNonce) + + const cancelSignature1 = await guardian1.signMessage(arrayify(cancelHash)) + await expect(accountRecoveryBarz.cancelRecovery(recoveryOwner.publicKey, [guardian1.address], [cancelSignature1])).to.emit(accountRecoveryBarz, "RecoveryCanceled") + }) + it("Should revert if on-chain approver reattempts to approve off-chain", async () => { + await setupAccountRecoveryBarz() + + await addGuardian(guardian1) + await addGuardian(guardian2) + const hash = getExecuteRecoveryHash(recoveryOwner, accountRecoveryBarz, recoveryNonce) + const signature = await guardian1.signMessage(arrayify(hash)) + const signature2 = await guardian2.signMessage(arrayify(hash)) + expect(await k1Barz.owner()).to.equal(owner.address.toLowerCase()) + await expect(accountRecoveryBarz.executeRecovery(recoveryOwner.publicKey, [guardian1.address, guardian2.address], [signature, signature2])).to.emit(accountRecoveryBarz, "RecoveryExecuted") + + // NOTE: Guardian1 approved and tries again with off-chain approval + await accountRecoveryBarz.connect(guardian1).approveCancelRecovery(recoveryOwner.publicKey) + + const cancelRecoveryNonce = await accountRecoveryBarz.getRecoveryNonce() + const cancelHash = getCancelRecoveryHash(recoveryOwner, accountRecoveryBarz, cancelRecoveryNonce) + + const cancelSignature1 = await guardian1.signMessage(arrayify(cancelHash)) + await expect(accountRecoveryBarz.cancelRecovery(recoveryOwner.publicKey, [guardian1.address], [cancelSignature1])).to.be.revertedWithCustomError(accountRecoveryBarz, "AccountRecoveryFacet__DuplicateApproval") + }) + }) + + it("Should recover account if recovery is finalized", async () => { + await setupAccountRecoveryBarz() + await addGuardian(guardian1) + const hash = getExecuteRecoveryHash(recoveryOwner, accountRecoveryBarz, recoveryNonce) + const signature = await guardian1.signMessage(arrayify(hash)) + + expect(await k1Barz.owner()).to.equal(owner.address.toLowerCase()) + await accountRecoveryBarz.executeRecovery(recoveryOwner.publicKey, [guardian1.address], [signature]) + + expect(await isUserOperationSuccessful(await callFromEntryPointOnK1(entryPoint, barz.address, owner, testExecData))).to.equal(false); + + await increaseBlockTime(recoveryPeriod) + + await expect(accountRecoveryBarz.finalizeRecovery()).to.emit(accountRecoveryBarz, "RecoveryFinalized") + expect(await k1Barz.owner()).to.equal(recoveryOwner.address.toLowerCase()) + }) + it("Should revert if non-guardian attempts to approve recovery", async () => { + await setupAccountRecoveryBarz() + + await addGuardian(guardian1) + await expect(accountRecoveryBarz.connect(user1).approveAccountRecovery(recoveryOwner.publicKey)).to.be.revertedWithCustomError(accountRecoveryBarz, "CallerNotGuardian") + }) + it("Should execute recovery with direct call from Guardian", async () => { + await setupAccountRecoveryBarz() + + await addGuardian(guardian1) + await addGuardian(guardian2) + + await expect(accountRecoveryBarz.connect(guardian1).approveAccountRecovery(recoveryOwner.publicKey)).to.emit(accountRecoveryBarz, "RecoveryApproved") + await expect(accountRecoveryBarz.connect(guardian2).approveAccountRecovery(recoveryOwner.publicKey)).to.emit(accountRecoveryBarz, "RecoveryExecuted") + + expect(await isUserOperationSuccessful(await callFromEntryPointOnK1(entryPoint, barz.address, owner, testExecData))).to.be.false + await expect(accountBarz.execute(accountBarz.address, 0, "0x00")).to.be.revertedWith("Account Locked") + }) + it("Should revoke recovery approval if majority of guardians agree", async () => { + await setupAccountRecoveryBarz() + + await addGuardian(guardian1) + await addGuardian(guardian2) + await expect(accountRecoveryBarz.connect(guardian1).approveAccountRecovery(recoveryOwner.publicKey)).to.emit(accountRecoveryBarz, "RecoveryApproved") + + await expect(accountRecoveryBarz.connect(guardian1).revokeAccountRecoveryApproval(recoveryOwner.publicKey)).to.emit(accountRecoveryBarz, "RecoveryApprovalRevoked") + + await expect(accountRecoveryBarz.connect(guardian2).approveAccountRecovery(recoveryOwner.publicKey)).to.emit(accountRecoveryBarz, "RecoveryApproved") + expect(await k1Barz.owner()).to.equal(owner.address.toLowerCase()) + }) + it("Should revert if recovery is not pending for finalization", async () => { + await setupAccountRecoveryBarz() + await expect(accountRecoveryBarz.finalizeRecovery()).to.be.revertedWithCustomError(accountRecoveryBarz, "AccountRecoveryFacet__NonexistentRecovery") + }) + it("Should cancel pending recovery if majority of guardians agree with signature", async () => { + await setupAccountRecoveryBarz() + await addGuardian(guardian1) + await addGuardian(guardian2) + + await expect(accountRecoveryBarz.connect(guardian1).approveAccountRecovery(recoveryOwner.publicKey)).to.emit(accountRecoveryBarz, "RecoveryApproved") + + await expect(accountRecoveryBarz.connect(guardian2).approveAccountRecovery(recoveryOwner.publicKey)).to.emit(accountRecoveryBarz, "RecoveryExecuted") + + expect(await isUserOperationSuccessful(await callFromEntryPointOnK1(entryPoint, barz.address, owner, testExecData))).to.be.false + await expect(accountBarz.execute(accountBarz.address, 0, "0x00")).to.be.revertedWith("Account Locked") + + const recoveryNonce = await accountRecoveryBarz.getRecoveryNonce() + const encodedData = ethers.utils.defaultAbiCoder.encode(['bytes', 'string', 'address', 'uint256', 'uint128'], [recoveryOwner.publicKey, 'CancelRecovery', accountRecoveryBarz.address, chainId, recoveryNonce]) + + const hash = keccak256(encodedData) + const signature1 = await guardian1.signMessage(arrayify(hash)) + const signature2 = await guardian2.signMessage(arrayify(hash)) + + await expect(accountRecoveryBarz.cancelRecovery(recoveryOwner.publicKey, [guardian1.address, guardian2.address], [signature1, signature2])).to.emit(accountRecoveryBarz, "RecoveryCanceled") + }) + it("Should cancel pending recovery if majority of guardians agree with direct call", async () => { + await setupAccountRecoveryBarz() + + await addGuardian(guardian1) + await addGuardian(guardian2) + + await expect(accountRecoveryBarz.connect(guardian1).approveAccountRecovery(recoveryOwner.publicKey)).to.emit(accountRecoveryBarz, "RecoveryApproved") + await expect(accountRecoveryBarz.connect(guardian2).approveAccountRecovery(recoveryOwner.publicKey)).to.emit(accountRecoveryBarz, "RecoveryExecuted") + expect(await isUserOperationSuccessful(await callFromEntryPointOnK1(entryPoint, barz.address, owner, testExecData))).to.be.false + await expect(accountBarz.execute(accountBarz.address, 0, "0x00")).to.be.revertedWith("Account Locked") + + await expect(accountRecoveryBarz.connect(guardian1).approveCancelRecovery(recoveryOwner.publicKey)).to.emit(accountRecoveryBarz, "RecoveryCancellationApproved") + await expect(accountRecoveryBarz.connect(guardian2).approveCancelRecovery(recoveryOwner.publicKey)).to.emit(accountRecoveryBarz, "RecoveryCanceled") + + await expect(accountRecoveryBarz.finalizeRecovery()).to.be.revertedWithCustomError(accountRecoveryBarz, "AccountRecoveryFacet__NonexistentRecovery") + }) + it("Should hardstop recovery if owner approves", async () => { + await setupAccountRecoveryBarz() + + await addGuardian(guardian1) + await addGuardian(guardian2) + + await expect(accountRecoveryBarz.connect(guardian1).approveAccountRecovery(recoveryOwner.publicKey)).to.emit(accountRecoveryBarz, "RecoveryApproved") + await expect(accountRecoveryBarz.connect(guardian2).approveAccountRecovery(recoveryOwner.publicKey)).to.emit(accountRecoveryBarz, "RecoveryExecuted") + + expect(await isUserOperationSuccessful(await callFromEntryPointOnK1(entryPoint, barz.address, owner, testExecData))).to.be.false + await expect(accountBarz.execute(accountBarz.address, 0, "0x00")).to.be.revertedWith("Account Locked") + + const recoveryNonce = await accountRecoveryBarz.getRecoveryNonce() + const encodedData = ethers.utils.defaultAbiCoder.encode(['string', 'string', 'address', 'uint256', 'uint128'], ['0', 'HardstopRecovery', accountRecoveryBarz.address, chainId, recoveryNonce]) + + const hash = keccak256(encodedData) + const prefixedHash = getEthSignMessageHash(hash) + + const finalHash = await getMessageHash(prefixedHash, await getChainId(), lockBarz.address) + const sig = ecsign(Buffer.from(ethers.utils.arrayify(finalHash)), Buffer.from(ethers.utils.arrayify(owner.privateKey))) + + const ownerHardstopSignature = toRpcSig(sig.v, sig.r, sig.s) + await expect(accountRecoveryBarz.hardstopRecovery(ownerHardstopSignature)).to.emit(accountRecoveryBarz, "RecoveryHardstopped") + expect(await lockBarz.isLocked()).to.be.false + + }) + it("Should return valid recovery nonce", async () => { + await setupAccountRecoveryBarz() + + await addGuardian(guardian1) + await addGuardian(guardian2) + + expect(await accountRecoveryBarz.getRecoveryNonce()).to.equal(0) + + await expect(accountRecoveryBarz.connect(guardian1).approveAccountRecovery(recoveryOwner.publicKey)).to.emit(accountRecoveryBarz, "RecoveryApproved") + await expect(accountRecoveryBarz.connect(guardian2).approveAccountRecovery(recoveryOwner.publicKey)).to.emit(accountRecoveryBarz, "RecoveryExecuted") + + expect(await accountRecoveryBarz.getRecoveryNonce()).to.equal(1) + }) + it("Should revert if revoking non-existent recovery approval", async () => { + await setupAccountRecoveryBarz() + + await addGuardian(guardian1) + await addGuardian(guardian2) + + expect(await accountRecoveryBarz.getRecoveryNonce()).to.equal(0) + + await expect(accountRecoveryBarz.connect(guardian1).revokeAccountRecoveryApproval(recoveryOwner.publicKey)).to.be.revertedWithCustomError(accountRecoveryBarz, "AccountRecoveryFacet__NonExistentApproval") + }) + it('Should return valid pending recovery', async () => { + await setupAccountRecoveryBarz() + + await addGuardian(guardian1) + await addGuardian(guardian2) + + expect(await accountRecoveryBarz.getRecoveryNonce()).to.equal(0) + + await expect(accountRecoveryBarz.connect(guardian1).approveAccountRecovery(recoveryOwner.publicKey)).to.emit(accountRecoveryBarz, "RecoveryApproved") + await expect(accountRecoveryBarz.connect(guardian2).approveAccountRecovery(recoveryOwner.publicKey)).to.emit(accountRecoveryBarz, "RecoveryExecuted") + + expect(await accountRecoveryBarz.getRecoveryNonce()).to.equal(1) + const blockTimeStamp = await getBlockTimestamp() + + expect(await accountRecoveryBarz.getPendingRecovery()).to.deep.equal([recoveryOwner.publicKey, blockTimeStamp + recoveryPeriod]) + + await expect(await isUserOperationSuccessful(await callFromEntryPointOnK1(entryPoint, barz.address, owner, testExecData))).to.be.false + await expect(accountBarz.execute(accountBarz.address, 0, "0x00")).to.be.revertedWith("Account Locked") + }) + it('Should return zero value if recovery is not pending', async () => { + await setupAccountRecoveryBarz() + + expect(await accountRecoveryBarz.getRecoveryNonce()).to.equal(0) + + expect(await accountRecoveryBarz.getPendingRecovery()).to.deep.equal(['0x', '0']) + }) +}) \ No newline at end of file diff --git a/test/BarzFactory.test.ts b/test/BarzFactory.test.ts new file mode 100644 index 0000000..7dac666 --- /dev/null +++ b/test/BarzFactory.test.ts @@ -0,0 +1,133 @@ +import { ethers } from 'hardhat' +import { Wallet } from 'ethers' + +import { AccountFacet, DiamondCutFacet, Secp256k1VerificationFacet, SecurityManager, FacetRegistry, BarzFactory, Secp256r1VerificationFacet, DiamondLoupeFacet, TokenReceiverFacet, DefaultFallbackHandler } from '../typechain-types' +import { generateKeyPair } from './utils/helpers' +import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers' +import { createAccountOwner, fund } from './utils/testutils' +const { + getSelectors +} = require('./utils/diamond.js') + +import { expect } from "chai" +import { diamondCutFacetFixture } from './fixtures/DiamondCutFacetFixture' +import { accountFacetFixture } from './fixtures/AccountFacetFixture' +import { secp256k1VerificationFacetFixture } from './fixtures/Secp256k1VerificationFacetFixture' +import { facetRegistryFixture } from './fixtures/FacetRegistryFixture' +import { barzFactoryFixture } from './fixtures/BarzFactoryFixture' +import { secp256r1VerificationFacetFixture } from './fixtures/Secp256r1VerificationFacetFixture' +import { setupDefaultSecuritManager } from './utils/setup' +import { EntryPoint } from '../typechain-types/core' +import { entryPointFixture } from './fixtures/EntryPointFixture' +import { diamondLoupeFacetFixture } from './fixtures/DiamondLoupeFacetFixture' +import { tokenReceiverFacetFixture } from './fixtures/TokenReceiverFacetFixture' +import { defaultFallbackHandlerFixture } from './fixtures/DefaultFallbackHandlerFixture' +import BarzArtifact from "../artifacts/contracts/Barz.sol/Barz.json"; + + +describe('Barz Factory', () => { + let diamondCutFacet: DiamondCutFacet + let securityManager: SecurityManager + let defaultFallbackHandler: DefaultFallbackHandler + let facetRegistry: FacetRegistry + let accountFacet: AccountFacet + let k1Facet: Secp256k1VerificationFacet + let r1Facet: Secp256r1VerificationFacet + let diamondLoupeFacet: DiamondLoupeFacet + let tokenReceiverFacet: TokenReceiverFacet + let entryPoint: EntryPoint + let owner: Wallet + let barzFactory: BarzFactory + let accountBarz: AccountFacet + let securityManagerOwner: SignerWithAddress + let facetRegistryOwner: SignerWithAddress + const salt = 0 + before(async () => { + [securityManagerOwner, facetRegistryOwner] = await ethers.getSigners() + owner = createAccountOwner() + await fund(owner.address) + + securityManager = await setupDefaultSecuritManager(securityManagerOwner) + facetRegistry = await facetRegistryFixture(facetRegistryOwner.address) + diamondCutFacet = await diamondCutFacetFixture(securityManager) + accountFacet = await accountFacetFixture() + k1Facet = await secp256k1VerificationFacetFixture() + r1Facet = await secp256r1VerificationFacetFixture() + entryPoint = await entryPointFixture() + diamondLoupeFacet = await diamondLoupeFacetFixture() + tokenReceiverFacet = await tokenReceiverFacetFixture() + defaultFallbackHandler = await defaultFallbackHandlerFixture(diamondCutFacet, accountFacet, tokenReceiverFacet, diamondLoupeFacet) + + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(accountFacet.address, getSelectors(accountFacet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(k1Facet.address, getSelectors(k1Facet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(r1Facet.address, getSelectors(r1Facet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(diamondCutFacet.address, getSelectors(diamondCutFacet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(diamondLoupeFacet.address, getSelectors(diamondLoupeFacet)) + + }) + beforeEach(async () => { + barzFactory = await barzFactoryFixture(accountFacet, entryPoint, facetRegistry, defaultFallbackHandler) + }) + + describe("# getCreation code", () => { + it("Should return a precomputed address", async () => { + const bytecode = BarzArtifact.bytecode; + const actualCreationCode = await barzFactory.getCreationCode(); + + expect(actualCreationCode).to.equal(bytecode); + }); + }); + describe("# getAddress", () => { + it("Should return a precomputed address", async () => { + const precomputedBarzAddr = await barzFactory.getAddress(k1Facet.address, owner.publicKey, salt) + await expect(barzFactory.createAccount(k1Facet.address, owner.publicKey, salt)).to.emit(barzFactory, "BarzDeployed").withArgs(precomputedBarzAddr) + }) + it("Should check predefined address", async () => { + const precomputedBarzAddr = await barzFactory.getAddress(k1Facet.address, owner.publicKey, salt) + const bytecode = await barzFactory.getBytecode(accountFacet.address, k1Facet.address, entryPoint.address, facetRegistry.address, defaultFallbackHandler.address, owner.publicKey) + const calculatedAddr = await ethers.utils.getCreate2Address(barzFactory.address, "0x0000000000000000000000000000000000000000000000000000000000000000", ethers.utils.keccak256(bytecode)) + expect(precomputedBarzAddr).to.equal(calculatedAddr) + }) + }) + describe("# createAccount", () => { + it("Should deploy Barz with factory", async () => { + const precomputedBarzAddr = await barzFactory.getAddress(k1Facet.address, owner.publicKey, salt) + await expect(barzFactory.createAccount(k1Facet.address, owner.publicKey, salt)).to.emit(barzFactory, "BarzDeployed").withArgs(precomputedBarzAddr) + accountBarz = await ethers.getContractAt('AccountFacet', precomputedBarzAddr) as AccountFacet + + expect(await accountBarz.getNonce()).to.equal(0) + expect(await accountBarz.entryPoint()).to.equal(entryPoint.address) + }) + it("Should not deploy Barz with factory if one already exists", async () => { + const precomputedBarzAddr = await barzFactory.getAddress(k1Facet.address, owner.publicKey, salt); + + await barzFactory.createAccount(k1Facet.address, owner.publicKey, salt); + const codeSizeBefore = await ethers.provider.getCode(precomputedBarzAddr); + expect(codeSizeBefore).to.not.equal("0x"); + const accountBarz = (await ethers.getContractAt("AccountFacet", precomputedBarzAddr)) as AccountFacet; + const nonceBefore = await accountBarz.getNonce(); + + await expect(barzFactory.createAccount(k1Facet.address, owner.publicKey, salt)).to.not.emit(barzFactory, "BarzDeployed"); + + const nonceAfter = await accountBarz.getNonce(); + expect(nonceAfter).to.equal(nonceBefore); + }); + it("Should initialize Barz wallet with accurate param(owner) of k1 facet", async () => { + const precomputedBarzAddr = await barzFactory.getAddress(k1Facet.address, owner.publicKey, salt) + await expect(barzFactory.createAccount(k1Facet.address, owner.publicKey, salt)).to.emit(barzFactory, "BarzDeployed").withArgs(precomputedBarzAddr) + + const k1Barz = await ethers.getContractAt("Secp256k1VerificationFacet", precomputedBarzAddr) + + expect(await k1Barz.owner()).to.equal(owner.address.toLowerCase()) + }) + it("Should initialize Barz wallet with accurate param(owner) of r1 facet", async () => { + const { publicKeyBytes, keyX, keyY } = generateKeyPair() + const precomputedBarzAddr = await barzFactory.getAddress(r1Facet.address, publicKeyBytes, salt) + await expect(barzFactory.createAccount(r1Facet.address, publicKeyBytes, salt)).to.emit(barzFactory, "BarzDeployed").withArgs(precomputedBarzAddr) + + const r1Barz = await ethers.getContractAt("Secp256r1VerificationFacet", precomputedBarzAddr) + + expect(await r1Barz.owner()).to.equal(("0x" + keyX.toString('hex') + keyY.toString('hex')).toLowerCase()) + }) + }) +}) \ No newline at end of file diff --git a/test/DiamondCutFacet.test.ts b/test/DiamondCutFacet.test.ts new file mode 100644 index 0000000..4628244 --- /dev/null +++ b/test/DiamondCutFacet.test.ts @@ -0,0 +1,550 @@ +import { ethers } from "hardhat" +import { Wallet } from 'ethers' + +import { AccountFacet, DiamondCutFacet, Barz, SignatureMigrationFacet, Secp256k1VerificationFacet, Secp256r1VerificationFacet, SecurityManager, FacetRegistry, DiamondLoupeFacet, GuardianFacet, LockFacet, RestrictionsFacet, TokenReceiverFacet, DefaultFallbackHandler } from '../typechain-types' +import { facetCutType, getChainId, diamondCut, guardianSecurityPeriod, increaseBlockTime, getEthSignMessageHash, isUserOperationSuccessful } from './utils/helpers' +import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers' +import { createAccountOwner, fund, AddressZero, AddressOne, getMessageHash } from './utils/testutils' + +const { + FacetCutAction, + getSelectors +} = require('./utils/diamond.js') + +import { expect } from "chai" +import { diamondCutFacetFixture } from './fixtures/DiamondCutFacetFixture' +import { accountFacetFixture } from './fixtures/AccountFacetFixture' +import { secp256k1VerificationFacetFixture } from './fixtures/Secp256k1VerificationFacetFixture' +import { secp256r1VerificationFacetFixture } from './fixtures/Secp256r1VerificationFacetFixture' +import { barzFixture } from './fixtures/BarzFixture' +import { signatureMigrationFacetFixture } from './fixtures/SignatureMigrationFacetFixture' +import { addFacetSelectors, addFacetSelectorsViaEntryPointOnK1, getFacetBarz, setupDefaultSecuritManager } from './utils/setup' +import { facetRegistryFixture } from './fixtures/FacetRegistryFixture' +import { diamondLoupeFacetFixture } from './fixtures/DiamondLoupeFacetFixture' +import { guardianFacetFixture } from './fixtures/GuardianFacetFixture' +import { keccak256 } from '@ethersproject/keccak256' +import { arrayify } from 'ethers/lib/utils' +import { lockFacetFixture } from './fixtures/LockFacetFixture' +import { restrictionsFacetFixture } from './fixtures/RestrictionsFacetFixture' +import { EntryPoint } from "../typechain-types/core" +import { callFromEntryPointOnK1, executeCallData } from "./utils/UserOp" +import { entryPointFixture } from "./fixtures/EntryPointFixture" +import { tokenReceiverFacetFixture } from "./fixtures/TokenReceiverFacetFixture" +import { defaultFallbackHandlerFixture } from "./fixtures/DefaultFallbackHandlerFixture" +import { ecsign, toRpcSig } from "ethereumjs-util" + +describe('Diamond Cut Facet', () => { + let diamondCutFacet: DiamondCutFacet + let diamondCutBarz: DiamondCutFacet + let securityManager: SecurityManager + let facetRegistry: FacetRegistry + let defaultFallbackHandler: DefaultFallbackHandler + let accountFacet: AccountFacet + let k1Facet: Secp256k1VerificationFacet + let r1Facet: Secp256r1VerificationFacet + let migrationFacet: SignatureMigrationFacet + let diamondLoupeFacet: DiamondLoupeFacet + let diamondLoupeBarz: DiamondLoupeFacet + let guardianFacet: GuardianFacet + let guardianBarz: GuardianFacet + let lockFacet: LockFacet + let restrictionsFacet: RestrictionsFacet + let entryPoint: EntryPoint + let mockEntryPoint: EntryPoint + let mockDiamondCutBarz: DiamondCutFacet + let mockAccountBarz: AccountFacet + let tokenReceiverFacet: TokenReceiverFacet + let mockGuardianBarz: GuardianFacet + let user1: SignerWithAddress + let guardian1: SignerWithAddress + let guardian2: SignerWithAddress + let securityManagerOwner: SignerWithAddress + let facetRegistryOwner: SignerWithAddress + let owner: Wallet + let barz: Barz + let mockBarz: Barz + let chainId: number + let cutNonce = 0 + + before(async () => { + [mockEntryPoint, user1, guardian1, guardian2, securityManagerOwner, facetRegistryOwner] = await ethers.getSigners() + owner = createAccountOwner() + await fund(owner.address) + + chainId = await getChainId() + securityManager = await setupDefaultSecuritManager(securityManagerOwner) + facetRegistry = await facetRegistryFixture(facetRegistryOwner.address) + accountFacet = await accountFacetFixture() + k1Facet = await secp256k1VerificationFacetFixture() + r1Facet = await secp256r1VerificationFacetFixture() + guardianFacet = await guardianFacetFixture(securityManager) + diamondCutFacet = await diamondCutFacetFixture(securityManager) + migrationFacet = await signatureMigrationFacetFixture(securityManager) + diamondLoupeFacet = await diamondLoupeFacetFixture() + lockFacet = await lockFacetFixture(securityManager) + restrictionsFacet = await restrictionsFacetFixture() + tokenReceiverFacet = await tokenReceiverFacetFixture() + entryPoint = await entryPointFixture() + defaultFallbackHandler = await defaultFallbackHandlerFixture(diamondCutFacet, accountFacet, tokenReceiverFacet, diamondLoupeFacet) + + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(accountFacet.address, getSelectors(accountFacet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(diamondCutFacet.address, getSelectors(diamondCutFacet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(migrationFacet.address, getSelectors(migrationFacet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(diamondLoupeFacet.address, getSelectors(diamondLoupeFacet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(k1Facet.address, getSelectors(k1Facet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(r1Facet.address, getSelectors(r1Facet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(guardianFacet.address, getSelectors(guardianFacet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(lockFacet.address, getSelectors(lockFacet)) + }) + beforeEach(async () => { + + barz = await barzFixture(accountFacet, k1Facet, entryPoint, facetRegistry, defaultFallbackHandler, owner.publicKey) + mockBarz = await barzFixture(accountFacet, k1Facet, mockEntryPoint, facetRegistry, defaultFallbackHandler, owner.publicKey) + + await entryPoint.depositTo(barz.address, { + value: ethers.utils.parseEther('0.5'), + }) + await entryPoint.depositTo(mockBarz.address, { + value: ethers.utils.parseEther('0.5'), + }) + await setupBarz() + + await setupMockBarz() + }) + const setupBarz = async () => { + cutNonce = 0 + diamondCutBarz = await getFacetBarz('DiamondCutFacet', barz) + diamondLoupeBarz = await getFacetBarz('DiamondLoupeFacet', barz) + guardianBarz = await getFacetBarz('GuardianFacet', barz) + const guardianFacetSelectors = getSelectors(guardianFacet).filter((item: string) => item !== guardianFacet.interface.getSighash('securityManager')) + await addFacetSelectorsViaEntryPointOnK1(barz, owner, guardianFacet, guardianFacetSelectors, entryPoint) + cutNonce++ + const diamondCutSelectors = getSelectors(diamondCutFacet).filter((item: string) => item !== diamondCutFacet.interface.getSighash('diamondCut')) + await addFacetSelectorsViaEntryPointOnK1(barz, owner, diamondCutFacet, diamondCutSelectors, entryPoint) + cutNonce++ + const lockCutSelectors = getSelectors(lockFacet).filter((item: string) => item !== lockFacet.interface.getSighash('securityManager')) + await addFacetSelectorsViaEntryPointOnK1(barz, owner, lockFacet, lockCutSelectors, entryPoint) + cutNonce++ + } + + const setupMockBarz = async () => { + mockDiamondCutBarz = await getFacetBarz('DiamondCutFacet', mockBarz) + mockAccountBarz = await getFacetBarz('AccountFacet', mockBarz) + mockGuardianBarz = await getFacetBarz('GuardianFacet', mockBarz) + const diamondCutSelectors = getSelectors(diamondCutFacet).filter((item: string) => item !== diamondCutFacet.interface.getSighash('diamondCut')) + await addFacetSelectors(mockBarz, diamondCutFacet, diamondCutSelectors, mockEntryPoint) + const guardianFacetSelectors = getSelectors(guardianFacet).filter((item: string) => item !== guardianFacet.interface.getSighash('securityManager')) + await addFacetSelectors(mockBarz, guardianFacet, guardianFacetSelectors, mockEntryPoint) + const lockCutSelectors = getSelectors(lockFacet).filter((item: string) => item !== lockFacet.interface.getSighash('securityManager')) + await addFacetSelectors(mockBarz, lockFacet, lockCutSelectors, mockEntryPoint) + } + + const addGuardian = async (newGuardian: any) => { + const addGuardianCall = guardianFacet.interface.encodeFunctionData("addGuardian", [newGuardian.address]) + const callData = executeCallData(barz.address, 0, addGuardianCall) + await callFromEntryPointOnK1(entryPoint, barz.address, owner, callData) + + await increaseBlockTime(guardianSecurityPeriod) + await expect(guardianBarz.confirmGuardianAddition(newGuardian.address)).to.emit(guardianBarz, "GuardianAdded") + expect(await guardianBarz.isGuardian(newGuardian.address)).to.be.true + } + + const addGuardianMock = async (_newGuardian: any) => { + const addGuardianCall = guardianFacet.interface.encodeFunctionData("addGuardian", [_newGuardian.address]) + await mockAccountBarz.connect(mockEntryPoint).execute(mockAccountBarz.address, 0, addGuardianCall) + + await increaseBlockTime(guardianSecurityPeriod) + await expect(mockGuardianBarz.confirmGuardianAddition(_newGuardian.address)).to.emit(mockGuardianBarz, "GuardianAdded") + } + + describe('# diamondCut', () => { + it('Should revert if caller is not owner', async () => { + const cut = diamondCut(AddressZero, FacetCutAction.Remove, [k1Facet.interface.getSighash('uninitializeSigner')]) + await expect(diamondCutBarz.connect(user1).diamondCut(cut, AddressZero, "0x00")).to.be.revertedWith('LibDiamond: Caller not self') + }) + it('Should revert if guardians exists & owner want to remove facet', async () => { + await addGuardian(guardian1) + await addGuardianMock(guardian1) + + const cut = diamondCut(AddressZero, FacetCutAction.Remove, [k1Facet.interface.getSighash('uninitializeSigner')]) + const diamondCutCall = diamondCutFacet.interface.encodeFunctionData('diamondCut', [cut, AddressZero, "0x00"]) + const callData = executeCallData(diamondCutBarz.address, 0, diamondCutCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, callData)).to.not.emit(diamondCutBarz, "DiamondCut") + + await expect(mockAccountBarz.connect(mockEntryPoint).execute(mockDiamondCutBarz.address, 0, diamondCutCall)).to.be.revertedWithCustomError(diamondCutBarz, "DiamondCutFacet__InvalidRouteWithGuardian") + }) + it('Should revert if init address is not zero', async () => { + const cut = diamondCut(AddressZero, FacetCutAction.Remove, [k1Facet.interface.getSighash('uninitializeSigner')]) + const diamondCutCall = diamondCutFacet.interface.encodeFunctionData('diamondCut', [cut, AddressOne, "0x00"]) + const callData = executeCallData(diamondCutBarz.address, 0, diamondCutCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, callData)).to.not.emit(diamondCutBarz, "DiamondCut") + + await expect(mockAccountBarz.connect(mockEntryPoint).execute(mockDiamondCutBarz.address, 0, diamondCutCall)).to.be.revertedWithCustomError(diamondCutBarz, "DiamondCutFacet__InvalidInitAddress") + }) + it('Should revert if guardians exists & owner want to add facet', async () => { + await addGuardian(guardian1) + await addGuardianMock(guardian1) + + const cut = diamondCut(diamondCutFacet.address, FacetCutAction.Add, [diamondCutFacet.interface.getSighash('diamondCut')]) + const diamondCutCall = diamondCutFacet.interface.encodeFunctionData('diamondCut', [cut, AddressZero, "0x00"]) + const callData = executeCallData(diamondCutBarz.address, 0, diamondCutCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, callData)).to.not.emit(diamondCutBarz, "DiamondCut") + + await expect(mockAccountBarz.connect(mockEntryPoint).execute(mockDiamondCutBarz.address, 0, diamondCutCall)).to.be.revertedWithCustomError(diamondCutBarz, "DiamondCutFacet__InvalidRouteWithGuardian") + }) + it('Should revert if not registered in Facet Registry', async () => { + const cut = diamondCut(restrictionsFacet.address, FacetCutAction.Add, [restrictionsFacet.interface.getSighash('initializeRestrictions')]) + const diamondCutCall = diamondCutFacet.interface.encodeFunctionData('diamondCut', [cut, AddressZero, "0x00"]) + const callData = executeCallData(diamondCutBarz.address, 0, diamondCutCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, callData)).to.not.emit(diamondCutBarz, "DiamondCut") + await expect(mockAccountBarz.connect(mockEntryPoint).execute(mockDiamondCutBarz.address, 0, diamondCutCall)).to.be.revertedWithCustomError(diamondCutFacet, "UnregisteredFacetAndSelectors") + }) + it('Should add Facet & Selectors to Diamond', async () => { + const cut = diamondCut(migrationFacet.address, FacetCutAction.Add, [migrationFacet.interface.getSighash('migrateSignatureScheme')]) + const diamondCutCall = diamondCutFacet.interface.encodeFunctionData('diamondCut', [cut, AddressZero, "0x00"]) + const callData = executeCallData(diamondCutBarz.address, 0, diamondCutCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, callData)).to.emit(diamondCutBarz, "DiamondCut") + + const registeredSelectors = await diamondLoupeBarz.facetFunctionSelectors(migrationFacet.address) + expect(registeredSelectors[0]).to.equal(migrationFacet.interface.getSighash('migrateSignatureScheme')) + }) + it('Should increment Diamond Cut nonce', async () => { + const cutNonceBefore = await diamondCutBarz.getDiamondCutNonce() + const cut = diamondCut(migrationFacet.address, FacetCutAction.Add, [migrationFacet.interface.getSighash('migrateSignatureScheme')]) + const diamondCutCall = diamondCutFacet.interface.encodeFunctionData('diamondCut', [cut, AddressZero, "0x00"]) + const callData = executeCallData(diamondCutBarz.address, 0, diamondCutCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, callData)).to.emit(diamondCutBarz, "DiamondCut") + expect(await diamondCutBarz.getDiamondCutNonce()).to.equal(cutNonceBefore.add(1)) + }) + it('Should emit Diamond Cut event', async () => { + const cut = diamondCut(migrationFacet.address, FacetCutAction.Add, [migrationFacet.interface.getSighash('migrateSignatureScheme')]) + const diamondCutCall = diamondCutFacet.interface.encodeFunctionData('diamondCut', [cut, AddressZero, "0x00"]) + const callData = executeCallData(diamondCutBarz.address, 0, diamondCutCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, callData)).to.emit(diamondCutBarz, "DiamondCut") + }) + }) + + describe('# diamondCutWithGuardian', () => { + it('Should revert if guardian does not exist', async () => { + const cut = diamondCut(AddressZero, FacetCutAction.Remove, [k1Facet.interface.getSighash('owner')]) + + const abiCoder = new ethers.utils.AbiCoder(); + const encodedFacetCuts = abiCoder.encode([facetCutType], [cut]) + const facetCutHash = keccak256(encodedFacetCuts) + + const mockEncodedData = abiCoder.encode(['bytes32', 'address', 'uint256', 'uint128'], [facetCutHash, mockAccountBarz.address, chainId, cutNonce]) + const mockEncodedash = keccak256(arrayify(mockEncodedData)) + const mockGuardiansignature = await guardian1.signMessage(arrayify(mockEncodedash)) + const mockCutCall = diamondCutBarz.interface.encodeFunctionData('diamondCutWithGuardian', [cut, [guardian1.address, guardian1.address, user1.address], [mockGuardiansignature, mockGuardiansignature, mockGuardiansignature]]) + await expect(mockAccountBarz.connect(mockEntryPoint).execute(mockAccountBarz.address, 0, mockCutCall)).to.be.revertedWithCustomError(mockDiamondCutBarz, 'DiamondCutFacet__InvalidRouteWithGuardian') + }) + it('Should revert if duplicate guardian', async () => { + const cut = diamondCut(AddressZero, FacetCutAction.Remove, [k1Facet.interface.getSighash('owner')]) + + const abiCoder = new ethers.utils.AbiCoder(); + const encodedFacetCuts = abiCoder.encode([facetCutType], [cut]) + const facetCutHash = keccak256(encodedFacetCuts) + await addGuardianMock(guardian1) + await addGuardianMock(guardian2) + + const mockEncodedData = abiCoder.encode(['bytes32', 'address', 'uint256', 'uint128'], [facetCutHash, mockAccountBarz.address, chainId, cutNonce]) + const mockEncodedash = keccak256(arrayify(mockEncodedData)) + const mockGuardiansignature = await guardian1.signMessage(arrayify(mockEncodedash)) + const mockCutCall = diamondCutBarz.interface.encodeFunctionData('diamondCutWithGuardian', [cut, [guardian1.address, guardian1.address, user1.address], [mockGuardiansignature, mockGuardiansignature, mockGuardiansignature]]) + await expect(mockAccountBarz.connect(mockEntryPoint).execute(mockAccountBarz.address, 0, mockCutCall)).to.be.revertedWithCustomError(mockDiamondCutBarz, 'DuplicateApprover') + }) + it('Should revert if parameter guardian length and signature length differs', async () => { + const cut = diamondCut(AddressZero, FacetCutAction.Remove, [k1Facet.interface.getSighash('owner')]) + cut.push({ + facetAddress: restrictionsFacet.address, + action: FacetCutAction.Add, + functionSelectors: getSelectors(restrictionsFacet) + }) + await addGuardian(guardian1) + await addGuardianMock(guardian1) + const abiCoder = new ethers.utils.AbiCoder(); + const encodedFacetCuts = abiCoder.encode([facetCutType], [cut]) + const facetCutHash = keccak256(encodedFacetCuts) + const encodedData = abiCoder.encode(['bytes32', 'address', 'uint256', 'uint128'], [facetCutHash, barz.address, chainId, cutNonce]) + const Encodedash = keccak256(arrayify(encodedData)) + const guardianSignature = await guardian1.signMessage(arrayify(Encodedash)) + const cutCall = diamondCutBarz.interface.encodeFunctionData('diamondCutWithGuardian', [cut, [guardian1.address, user1.address], [guardianSignature]]) + const callData = executeCallData(diamondCutBarz.address, 0, cutCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, callData)).to.not.emit(diamondCutBarz, "DiamondCut") + + const mockEncodedData = abiCoder.encode(['bytes32', 'address', 'uint256', 'uint128'], [facetCutHash, mockAccountBarz.address, chainId, cutNonce]) + const mockEncodedash = keccak256(arrayify(mockEncodedData)) + const mockGuardiansignature = await guardian1.signMessage(arrayify(mockEncodedash)) + const mockCutCall = diamondCutBarz.interface.encodeFunctionData('diamondCutWithGuardian', [cut, [guardian1.address, user1.address], [mockGuardiansignature]]) + await expect(mockAccountBarz.connect(mockEntryPoint).execute(mockAccountBarz.address, 0, mockCutCall)).to.be.revertedWithCustomError(mockDiamondCutBarz, 'DiamondCutFacet__InvalidArrayLength') + }) + it('Should revert if not registered in Facet Registry', async () => { + const cut = diamondCut(AddressZero, FacetCutAction.Remove, [k1Facet.interface.getSighash('owner')]) + cut.push({ + facetAddress: restrictionsFacet.address, + action: FacetCutAction.Add, + functionSelectors: getSelectors(restrictionsFacet) + }) + await addGuardian(guardian1) + const abiCoder = new ethers.utils.AbiCoder(); + const encodedFacetCuts = abiCoder.encode([facetCutType], [cut]) + const facetCutHash = keccak256(encodedFacetCuts) + const encodedData = abiCoder.encode(['bytes32', 'address', 'uint256', 'uint128'], [facetCutHash, barz.address, chainId, cutNonce]) + const Encodedash = keccak256(arrayify(encodedData)) + const signature1 = await guardian1.signMessage(arrayify(Encodedash)) + const cutCall = diamondCutFacet.interface.encodeFunctionData('diamondCutWithGuardian', [cut, [guardian1.address], [signature1]]) + const callData = executeCallData(diamondCutBarz.address, 0, cutCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, callData)).to.not.emit(diamondCutBarz, "DiamondCut") + + const mockEncodedData = abiCoder.encode(['bytes32', 'address', 'uint256', 'uint128'], [facetCutHash, mockAccountBarz.address, chainId, cutNonce]) + const mockEncodedash = keccak256(arrayify(mockEncodedData)) + const mockSignature1 = await guardian1.signMessage(arrayify(mockEncodedash)) + const mockCutCall = diamondCutFacet.interface.encodeFunctionData('diamondCutWithGuardian', [cut, [guardian1.address], [mockSignature1]]) + await expect(mockAccountBarz.connect(mockEntryPoint).execute(mockAccountBarz.address, 0, mockCutCall)).to.be.revertedWithCustomError(mockDiamondCutBarz, 'UnregisteredFacetAndSelectors') + }) + it('Should revert if invalid guardian', async () => { + const cut = diamondCut(AddressZero, FacetCutAction.Remove, [k1Facet.interface.getSighash('owner')]) + await addGuardian(guardian1) + await addGuardianMock(guardian1) + const abiCoder = new ethers.utils.AbiCoder(); + const encodedFacetCuts = abiCoder.encode([facetCutType], [cut]) + const facetCutHash = keccak256(encodedFacetCuts) + const encodedData = abiCoder.encode(['bytes32', 'address', 'uint256', 'uint128'], [facetCutHash, barz.address, chainId, cutNonce]) + const EncodedHash = keccak256(arrayify(encodedData)) + const guardianSignature = await guardian1.signMessage(arrayify(EncodedHash)) + const signerSignature = await owner.signMessage(arrayify(EncodedHash)) + const cutCall = diamondCutFacet.interface.encodeFunctionData('diamondCutWithGuardian', [cut, [user1.address, barz.address], [guardianSignature, signerSignature]]) + const callData = executeCallData(diamondCutBarz.address, 0, cutCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, callData)).to.not.emit(diamondCutBarz, "DiamondCut") + + const mockncodedData = abiCoder.encode(['bytes32', 'address', 'uint256', 'uint128'], [facetCutHash, mockAccountBarz.address, chainId, cutNonce]) + const mockEncodedHash = keccak256(arrayify(mockncodedData)) + const mockGuardianSignature = await guardian1.signMessage(arrayify(mockEncodedHash)) + const mockSignerSignature = await owner.signMessage(arrayify(mockEncodedHash)) + // guardian1 is the guardian but we give user1 as guardian to check if it reverts + const mockCutCall = diamondCutFacet.interface.encodeFunctionData('diamondCutWithGuardian', [cut, [user1.address, barz.address], [mockGuardianSignature, mockSignerSignature]]) + await expect(mockAccountBarz.connect(mockEntryPoint).execute(mockAccountBarz.address, 0, mockCutCall)).to.be.revertedWithCustomError(mockDiamondCutBarz, 'DiamondCutFacet__InvalidApprover') + }) + it('Should revert if invalid guardian signature', async () => { + const cut = diamondCut(AddressZero, FacetCutAction.Remove, [k1Facet.interface.getSighash('owner')]) + await addGuardian(guardian1) + await addGuardianMock(guardian1) + const abiCoder = new ethers.utils.AbiCoder(); + const encodedFacetCuts = abiCoder.encode([facetCutType], [cut]) + const facetCutHash = keccak256(encodedFacetCuts) + const invalidNonce = cutNonce + 1 + const encodedData = abiCoder.encode(['bytes32', 'address', 'uint256', 'uint128'], [facetCutHash, barz.address, chainId, invalidNonce]) + const EncodedHash = keccak256(arrayify(encodedData)) + const guardianSignature = await guardian1.signMessage(arrayify(EncodedHash)) + const signerSignature = await owner.signMessage(arrayify(EncodedHash)) + const cutCall = diamondCutBarz.interface.encodeFunctionData('diamondCutWithGuardian', [cut, [guardian1.address, barz.address], [guardianSignature, signerSignature]]) + const callData = executeCallData(diamondCutBarz.address, 0, cutCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, callData)).to.not.emit(diamondCutBarz, "DiamondCut") + + const mockEncodedData = abiCoder.encode(['bytes32', 'address', 'uint256', 'uint128'], [facetCutHash, mockAccountBarz.address, chainId, invalidNonce]) + const mockEncodedHash = keccak256(arrayify(mockEncodedData)) + const mockGuardianSignature = await guardian1.signMessage(arrayify(mockEncodedHash)) + const mockSignerSignature = await owner.signMessage(arrayify(mockEncodedHash)) + const mockCutCall = diamondCutFacet.interface.encodeFunctionData('diamondCutWithGuardian', [cut, [guardian1.address, mockBarz.address], [mockGuardianSignature, mockSignerSignature]]) + await expect(mockAccountBarz.connect(mockEntryPoint).execute(mockAccountBarz.address, 0, mockCutCall)).to.be.revertedWithCustomError(mockDiamondCutBarz, 'DiamondCutFacet__InvalidApproverSignature') + }) + it('Should add Facet & Selectors to Diamond', async () => { + const cut = diamondCut(AddressZero, FacetCutAction.Remove, [k1Facet.interface.getSighash('owner')]) + await addGuardian(guardian1) + await addGuardianMock(guardian1) + const abiCoder = new ethers.utils.AbiCoder() + const encodedFacetCuts = abiCoder.encode([facetCutType], [cut]) + const facetCutHash = keccak256(encodedFacetCuts) + const encodedData = abiCoder.encode(['bytes32', 'address', 'uint256', 'uint128'], [facetCutHash, barz.address, chainId, cutNonce]) + const EncodedHash = keccak256(arrayify(encodedData)) + const guardianSignature = await guardian1.signMessage(arrayify(EncodedHash)) + const prefixedHash = getEthSignMessageHash(EncodedHash) + + const finalHash = await getMessageHash(prefixedHash, await getChainId(), barz.address) + const sig = ecsign(Buffer.from(ethers.utils.arrayify(finalHash)), Buffer.from(ethers.utils.arrayify(owner.privateKey))) + + const ownerSignature = toRpcSig(sig.v, sig.r, sig.s) + const cutCall = diamondCutBarz.interface.encodeFunctionData('diamondCutWithGuardian', [cut, [guardian1.address, barz.address], [guardianSignature, ownerSignature]]) + const callData = executeCallData(diamondCutBarz.address, 0, cutCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, callData)).to.emit(diamondCutBarz, 'DiamondCut') + + const mockEncodedData = abiCoder.encode(['bytes32', 'address', 'uint256', 'uint128'], [facetCutHash, mockAccountBarz.address, chainId, cutNonce]) + const mockEncodedHash = keccak256(arrayify(mockEncodedData)) + const mockGuardianSignature = await guardian1.signMessage(arrayify(mockEncodedHash)) + const mockPrefixedHash = getEthSignMessageHash(mockEncodedHash) + + const mockFinalHash = await getMessageHash(mockPrefixedHash, await getChainId(), mockAccountBarz.address) + const mockSig = ecsign(Buffer.from(ethers.utils.arrayify(mockFinalHash)), Buffer.from(ethers.utils.arrayify(owner.privateKey))) + + const mockOwnerSignature = toRpcSig(mockSig.v, mockSig.r, mockSig.s) + const mockCutCall = diamondCutBarz.interface.encodeFunctionData('diamondCutWithGuardian', [cut, [guardian1.address, mockBarz.address], [mockGuardianSignature, mockOwnerSignature]]) + await expect(mockAccountBarz.connect(mockEntryPoint).execute(mockAccountBarz.address, 0, mockCutCall)).to.emit(mockDiamondCutBarz, 'DiamondCut') + }) + it('Should add Facet & Selectors to Diamond(partially with approval)', async () => { + const cut = diamondCut(AddressZero, FacetCutAction.Remove, [k1Facet.interface.getSighash('owner')]) + await addGuardian(guardian1) + await addGuardian(guardian2) + await diamondCutBarz.connect(guardian2).approveDiamondCut(cut) + const abiCoder = new ethers.utils.AbiCoder(); + const encodedFacetCuts = abiCoder.encode([facetCutType], [cut]) + const facetCutHash = keccak256(encodedFacetCuts) + const customCutNonce = await diamondCutBarz.getDiamondCutNonce() + const encodedData = abiCoder.encode(['bytes32', 'address', 'uint256', 'uint128'], [facetCutHash, barz.address, chainId, customCutNonce]) + const EncodedHash = keccak256(arrayify(encodedData)) + + const guardianSignature1 = await guardian1.signMessage(arrayify(EncodedHash)) + const prefixedHash = getEthSignMessageHash(EncodedHash) + + const finalHash = await getMessageHash(prefixedHash, await getChainId(), barz.address) + const sig = ecsign(Buffer.from(ethers.utils.arrayify(finalHash)), Buffer.from(ethers.utils.arrayify(owner.privateKey))) + + const ownerSignature = toRpcSig(sig.v, sig.r, sig.s) + const cutCall = diamondCutBarz.interface.encodeFunctionData('diamondCutWithGuardian', [cut, [guardian1.address, barz.address], [guardianSignature1, ownerSignature]]) + const callData = executeCallData(diamondCutBarz.address, 0, cutCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, callData)).to.emit(diamondCutBarz, 'DiamondCut') + }) + it('Should revert if on-chain approver reattempts to approve with off-chain approval', async () => { + const cut = diamondCut(AddressZero, FacetCutAction.Remove, [k1Facet.interface.getSighash('owner')]) + await addGuardianMock(guardian1) + await addGuardianMock(guardian2) + await mockDiamondCutBarz.connect(guardian2).approveDiamondCut(cut) + const abiCoder = new ethers.utils.AbiCoder(); + const encodedFacetCuts = abiCoder.encode([facetCutType], [cut]) + const facetCutHash = keccak256(encodedFacetCuts) + const customCutNonce = await mockDiamondCutBarz.getDiamondCutNonce() + const encodedData = abiCoder.encode(['bytes32', 'address', 'uint256', 'uint128'], [facetCutHash, barz.address, chainId, customCutNonce]) + const EncodedHash = keccak256(arrayify(encodedData)) + + const guardianSignature1 = await guardian1.signMessage(arrayify(EncodedHash)) + const guardianSignature2 = await guardian2.signMessage(arrayify(EncodedHash)) + const ownerSignature = await owner.signMessage(arrayify(EncodedHash)) + const cutCall = mockDiamondCutBarz.interface.encodeFunctionData('diamondCutWithGuardian', [cut, [guardian1.address, guardian2.address, barz.address], [guardianSignature1, guardianSignature2, ownerSignature]]) + + await expect(mockAccountBarz.connect(mockEntryPoint).execute(mockAccountBarz.address, 0, cutCall)).to.be.revertedWithCustomError(mockDiamondCutBarz, "DiamondCutFacet__DuplicateApproval") + }) + }) + describe('# approveDiamondCut', () => { + it('Should revert if caller is not guardian or owner', async () => { + const cut = diamondCut(AddressZero, FacetCutAction.Remove, [k1Facet.interface.getSighash('owner')]) + + await expect(diamondCutBarz.connect(user1).approveDiamondCut(cut)).to.be.revertedWithCustomError(diamondCutBarz, "CallerNotGuardianOrOwner") + }) + it('Should revert if not registered in Facet Registry', async () => { + const cut = diamondCut(AddressZero, FacetCutAction.Remove, [k1Facet.interface.getSighash('owner')]) + cut.push({ + facetAddress: restrictionsFacet.address, + action: FacetCutAction.Add, + functionSelectors: getSelectors(restrictionsFacet) + }) + await addGuardian(guardian1) + await expect(diamondCutBarz.connect(guardian1).approveDiamondCut(cut)).to.be.revertedWithCustomError(diamondCutBarz, 'UnregisteredFacetAndSelectors') + }) + it('Should revert if no guardian exists in Barz', async () => { + const cut = diamondCut(AddressZero, FacetCutAction.Remove, [k1Facet.interface.getSighash('owner')]) + const approveCutCall = diamondCutBarz.interface.encodeFunctionData("approveDiamondCut", [cut]) + + await expect(mockAccountBarz.connect(mockEntryPoint).execute(mockAccountBarz.address, 0, approveCutCall)).to.be.revertedWithCustomError(mockDiamondCutBarz, "DiamondCutFacet__InvalidRouteWithoutGuardian") + expect(await isUserOperationSuccessful(await callFromEntryPointOnK1(entryPoint, barz.address, owner, approveCutCall))).to.be.false + }) + it('Should emit Diamond Cut Approved event', async () => { + await addGuardian(guardian1) + + const cut = diamondCut(AddressZero, FacetCutAction.Remove, [k1Facet.interface.getSighash('owner')]) + + await expect(diamondCutBarz.connect(guardian1).approveDiamondCut(cut)).to.emit(diamondCutBarz, "DiamondCutApproved") + }) + it('Should automatically cut Diamond if majority of guardian approve + owner approve : Add', async () => { + // mock entrypoint + await addGuardianMock(guardian1) + const mockCut = diamondCut(k1Facet.address, FacetCutAction.Add, [k1Facet.interface.getSighash('initializeSigner')]) + await expect(mockDiamondCutBarz.connect(guardian1).approveDiamondCut(mockCut)).to.emit(mockDiamondCutBarz, "DiamondCutApproved") + const mockApproveCut = diamondCutBarz.interface.encodeFunctionData('approveDiamondCut', [mockCut]) + + await expect(mockAccountBarz.connect(mockEntryPoint).execute(mockAccountBarz.address, 0, mockApproveCut)).to.emit(mockDiamondCutBarz, 'DiamondCut') + + // real entrypoint + await addGuardian(guardian1) + + const cut = diamondCut(k1Facet.address, FacetCutAction.Add, [k1Facet.interface.getSighash('initializeSigner')]) + + await expect(diamondCutBarz.connect(guardian1).approveDiamondCut(cut)).to.emit(diamondCutBarz, "DiamondCutApproved") + const approveCut = diamondCutBarz.interface.encodeFunctionData('approveDiamondCut', [cut]) + const callData = executeCallData(diamondCutBarz.address, 0, approveCut) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, callData)).to.emit(diamondCutBarz, 'DiamondCut') + }) + it('Should automatically cut Diamond if majority of guardian approve + owner approve : Remove', async () => { + await addGuardian(guardian1) + + const cut = diamondCut(AddressZero, FacetCutAction.Remove, [k1Facet.interface.getSighash('owner')]) + + await expect(diamondCutBarz.connect(guardian1).approveDiamondCut(cut)).to.emit(diamondCutBarz, "DiamondCutApproved") + const approveCut = diamondCutBarz.interface.encodeFunctionData('approveDiamondCut', [cut]) + const callData = executeCallData(diamondCutBarz.address, 0, approveCut) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, callData)).to.emit(diamondCutBarz, 'DiamondCut') + }) + }) + describe('# revokeDiamondCutApproval', () => { + it('Should revert if call is not guardian or owner', async () => { + const cut = diamondCut(AddressZero, FacetCutAction.Remove, [k1Facet.interface.getSighash('owner')]) + + await expect(diamondCutBarz.connect(user1).revokeDiamondCutApproval(cut)).to.be.revertedWithCustomError(diamondCutBarz, "CallerNotGuardianOrOwner") + }) + it('Should revert if trying to revoke Diamond Cut that was not approved', async () => { + await addGuardian(guardian1) + const cut = diamondCut(AddressZero, FacetCutAction.Remove, [k1Facet.interface.getSighash('owner')]) + + await expect(diamondCutBarz.connect(guardian1).revokeDiamondCutApproval(cut)).to.be.revertedWithCustomError(diamondCutBarz, "DiamondCutFacet__CannotRevokeUnapproved") + }) + it('Should deduct Diamond Cut approval count', async () => { + await addGuardian(guardian1) + const cut = diamondCut(AddressZero, FacetCutAction.Remove, [k1Facet.interface.getSighash('owner')]) + + const abiCoder = new ethers.utils.AbiCoder(); + const encodedFacetCuts = abiCoder.encode([facetCutType], [cut]) + const facetCutHash = keccak256(encodedFacetCuts) + const encodedData = abiCoder.encode(['bytes32', 'address', 'uint256', 'uint128'], [facetCutHash, barz.address, chainId, cutNonce]) + const encodedHash = keccak256(arrayify(encodedData)) + const signEthMsgHash = getEthSignMessageHash(encodedHash) + + expect(await diamondCutBarz.getDiamondCutApprovalCountWithTimeValidity(signEthMsgHash)).to.equal(0) + await expect(diamondCutBarz.connect(guardian1).approveDiamondCut(cut)).to.emit(diamondCutBarz, "DiamondCutApproved") + expect(await diamondCutBarz.getDiamondCutApprovalCountWithTimeValidity(signEthMsgHash)).to.equal(1) + + await diamondCutBarz.connect(guardian1).revokeDiamondCutApproval(cut) + expect(await diamondCutBarz.getDiamondCutApprovalCountWithTimeValidity(signEthMsgHash)).to.equal(0) + }) + it('Should emit Approval revoked event', async () => { + await addGuardian(guardian1) + const cut = diamondCut(AddressZero, FacetCutAction.Remove, [k1Facet.interface.getSighash('uninitializeSigner')]) + + await expect(diamondCutBarz.connect(guardian1).approveDiamondCut(cut)).to.emit(diamondCutBarz, "DiamondCutApproved") + + await expect(diamondCutBarz.connect(guardian1).revokeDiamondCutApproval(cut)).to.emit(diamondCutBarz, "DiamondCutApprovalRevoked") + }) + }) + describe('# updateSupportsInterface', () => { + it('Should set supports interface to true', async () => { + const interfaceId = "0x00000000" + expect(await diamondLoupeBarz.supportsInterface(interfaceId)).to.be.false + + const approveCut = diamondCutBarz.interface.encodeFunctionData('updateSupportsInterface', ["0x00000000", true]) + const callData = executeCallData(diamondCutBarz.address, 0, approveCut) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, callData)).to.emit(diamondCutBarz, 'SupportsInterfaceUpdated').withArgs(interfaceId, true) + expect(await diamondLoupeBarz.supportsInterface(interfaceId)).to.be.true + }) + it('Should set supports interface to false', async () => { + const interfaceId = "0x00000000" + expect(await diamondLoupeBarz.supportsInterface(interfaceId)).to.be.false + + const approveCut = diamondCutBarz.interface.encodeFunctionData('updateSupportsInterface', ["0x00000000", true]) + const callData = executeCallData(diamondCutBarz.address, 0, approveCut) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, callData)).to.emit(diamondCutBarz, 'SupportsInterfaceUpdated').withArgs(interfaceId, true) + expect(await diamondLoupeBarz.supportsInterface(interfaceId)).to.be.true + + const falseApproveCut = diamondCutBarz.interface.encodeFunctionData('updateSupportsInterface', ["0x00000000", false]) + const falseCallData = executeCallData(diamondCutBarz.address, 0, falseApproveCut) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, falseCallData)).to.emit(diamondCutBarz, 'SupportsInterfaceUpdated').withArgs(interfaceId, false) + expect(await diamondLoupeBarz.supportsInterface(interfaceId)).to.be.false + }) + }) +}) \ No newline at end of file diff --git a/test/DiamondLoupe.test.ts b/test/DiamondLoupe.test.ts new file mode 100644 index 0000000..b46040a --- /dev/null +++ b/test/DiamondLoupe.test.ts @@ -0,0 +1,762 @@ +import { ethers } from 'hardhat' +import { Wallet } from 'ethers' + +import { AccountFacet, DiamondCutFacet, Barz, Secp256k1VerificationFacet, SecurityManager, FacetRegistry, DiamondLoupeFacet, TokenReceiverFacet, DefaultFallbackHandler, LockFacet } from '../typechain-types' +import { diamondCut } from './utils/helpers' +import { addFacetSelectorsViaEntryPointOnK1, getFacetBarz, setupDefaultSecuritManager } from './utils/setup' +import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers' +const { + getSelectors, + FacetCutAction +} = require('./utils/diamond.js') +import { expect } from "chai" +import { diamondCutFacetFixture } from './fixtures/DiamondCutFacetFixture' +import { accountFacetFixture } from './fixtures/AccountFacetFixture' +import { secp256k1VerificationFacetFixture } from './fixtures/Secp256k1VerificationFacetFixture' +import { barzFixture } from './fixtures/BarzFixture' +import { facetRegistryFixture } from './fixtures/FacetRegistryFixture' +import { EntryPoint } from '../typechain-types/core' +import { entryPointFixture } from './fixtures/EntryPointFixture' +import { diamondLoupeFacetFixture } from './fixtures/DiamondLoupeFacetFixture' +import { tokenReceiverFacetFixture } from './fixtures/TokenReceiverFacetFixture' +import { AddressZero, createAccountOwner, fund } from './utils/testutils' +import { defaultFallbackHandlerFixture } from './fixtures/DefaultFallbackHandlerFixture' +import { lockFacetFixture } from './fixtures/LockFacetFixture' +import { callFromEntryPointOnK1, executeCallData } from './utils/UserOp' + +describe('DiamondLoupe Facet', () => { + let diamondCutFacet: DiamondCutFacet + let diamondCutBarz: DiamondCutFacet + let securityManager: SecurityManager + let facetRegistry: FacetRegistry + let defaultFallbackHandler: DefaultFallbackHandler + let accountFacet: AccountFacet + let lockFacet: LockFacet + let k1Facet: Secp256k1VerificationFacet + let diamondLoupeFacet: DiamondLoupeFacet + let diamondLoupeBarz: DiamondLoupeFacet + let tokenReceiverFacet: TokenReceiverFacet + let entryPoint: EntryPoint + let facetRegistryOwner: SignerWithAddress + let securityManagerOwner: SignerWithAddress + let owner: Wallet + let barz: Barz + let nonce = 0 + before(async () => { + [facetRegistryOwner, securityManagerOwner] = await ethers.getSigners() + + securityManager = await setupDefaultSecuritManager(securityManagerOwner) + facetRegistry = await facetRegistryFixture(facetRegistryOwner.address) + accountFacet = await accountFacetFixture() + k1Facet = await secp256k1VerificationFacetFixture() + diamondCutFacet = await diamondCutFacetFixture(securityManager) + diamondLoupeFacet = await diamondLoupeFacetFixture() + tokenReceiverFacet = await tokenReceiverFacetFixture() + lockFacet = await lockFacetFixture(securityManager) + defaultFallbackHandler = await defaultFallbackHandlerFixture(diamondCutFacet, accountFacet, tokenReceiverFacet, diamondLoupeFacet) + + entryPoint = await entryPointFixture() + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(lockFacet.address, getSelectors(lockFacet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(accountFacet.address, getSelectors(accountFacet)) + + }) + + beforeEach(async () => { + nonce = 0 + owner = await createAccountOwner() + await fund(owner.address) + + barz = await barzFixture(accountFacet, k1Facet, entryPoint, facetRegistry, defaultFallbackHandler, owner.publicKey) + diamondLoupeBarz = await getFacetBarz('DiamondLoupeFacet', barz) + diamondCutBarz = await getFacetBarz('DiamondCutFacet', barz) + + await entryPoint.depositTo(barz.address, { + value: ethers.utils.parseEther('0.5'), + }) + }) + + describe('# supportsInterface', async () => { + it('Should return true for valid selector', async () => { + const ERC165 = '0x01ffc9a7' + expect(await diamondLoupeBarz.supportsInterface(ERC165)).to.be.true + + const ERC721RECEIVER = '0x150b7a02' + expect(await diamondLoupeBarz.supportsInterface(ERC721RECEIVER)).to.be.true + + const ERC1155RECEIVER = '0x4e2312e0' + expect(await diamondLoupeBarz.supportsInterface(ERC1155RECEIVER)).to.be.true + + const DIAMONDLOUPE = '0x48e2b093' + expect(await diamondLoupeBarz.supportsInterface(DIAMONDLOUPE)).to.be.true + + const DIAMONDCUT = diamondCutFacet.interface.getSighash('diamondCut') + expect(await diamondLoupeBarz.supportsInterface(DIAMONDCUT)).to.be.true + + const ERC777RECEIVER = '0x0023de29' + expect(await diamondLoupeBarz.supportsInterface(ERC777RECEIVER)).to.be.true + + const ERC1271 = '0x1626ba7e' + expect(await diamondLoupeBarz.supportsInterface(ERC1271)).to.be.true + + const ERC677RECEIVER = '0xa4c0ed36' + expect(await diamondLoupeBarz.supportsInterface(ERC677RECEIVER)).to.be.true + }) + it('Should return false for invalid selector', async () => { + expect(await diamondLoupeBarz.supportsInterface("0xffffffff")).to.be.false + expect(await diamondLoupeBarz.supportsInterface("0xbaddad42")).to.be.false + }) + }) + describe('# facets', async () => { + it('Should return default facets', async () => { + const facets = await diamondLoupeBarz.facets() + const defaultFacets = [ + [k1Facet.address, + [k1Facet.interface.getSighash("isValidSignature"), + k1Facet.interface.getSighash("validateOwnerSignature"), + k1Facet.interface.getSighash("owner")]], + + [diamondCutFacet.address, + [diamondCutFacet.interface.getSighash("diamondCut")]], + [accountFacet.address, [accountFacet.interface.getSighash("execute"), + accountFacet.interface.getSighash("executeBatch"), + accountFacet.interface.getSighash("validateUserOp"), + accountFacet.interface.getSighash("getNonce"), + accountFacet.interface.getSighash("entryPoint")]], + + [tokenReceiverFacet.address, + [tokenReceiverFacet.interface.getSighash("onERC721Received"), + tokenReceiverFacet.interface.getSighash("onERC1155Received"), + tokenReceiverFacet.interface.getSighash("onERC1155BatchReceived"), + tokenReceiverFacet.interface.getSighash("tokensReceived"), + tokenReceiverFacet.interface.getSighash("onTokenTransfer")]], + + [diamondLoupeFacet.address, + [diamondLoupeFacet.interface.getSighash("facets"), + diamondLoupeFacet.interface.getSighash("facetFunctionSelectors"), + diamondLoupeFacet.interface.getSighash("facetAddresses"), + diamondLoupeFacet.interface.getSighash("facetAddress"), + diamondLoupeFacet.interface.getSighash("supportsInterface"), + diamondLoupeFacet.interface.getSighash("facetsFromStorage"), + diamondLoupeFacet.interface.getSighash("facetFunctionSelectorsFromStorage"), + diamondLoupeFacet.interface.getSighash("facetAddressesFromStorage"), + diamondLoupeFacet.interface.getSighash("facetAddressFromStorage")]], + ] + expect(facets).to.deep.equal(defaultFacets) + }) + it('Should return valid facet after diamondCut', async () => { + const lockFacetSelectors = getSelectors(lockFacet).filter((item: string) => item !== lockFacet.interface.getSighash('securityManager')) + await expect(addFacetSelectorsViaEntryPointOnK1(barz, owner, lockFacet, lockFacetSelectors, entryPoint)).to.emit(diamondCutBarz, "DiamondCut") + const facets = await diamondLoupeBarz.facets() + const defaultAfterCut = [ + [k1Facet.address, + [k1Facet.interface.getSighash("isValidSignature"), + k1Facet.interface.getSighash("validateOwnerSignature"), + k1Facet.interface.getSighash("owner")]], + + [lockFacet.address, lockFacetSelectors], + + [diamondCutFacet.address, + [diamondCutFacet.interface.getSighash("diamondCut")]], + + [accountFacet.address, + [accountFacet.interface.getSighash("execute"), + accountFacet.interface.getSighash("executeBatch"), + accountFacet.interface.getSighash("validateUserOp"), + accountFacet.interface.getSighash("getNonce"), + accountFacet.interface.getSighash("entryPoint")]], + + [tokenReceiverFacet.address, + [tokenReceiverFacet.interface.getSighash("onERC721Received"), + tokenReceiverFacet.interface.getSighash("onERC1155Received"), + tokenReceiverFacet.interface.getSighash("onERC1155BatchReceived"), + tokenReceiverFacet.interface.getSighash("tokensReceived"), + tokenReceiverFacet.interface.getSighash("onTokenTransfer")]], + + [diamondLoupeFacet.address, + [diamondLoupeFacet.interface.getSighash("facets"), + diamondLoupeFacet.interface.getSighash("facetFunctionSelectors"), + diamondLoupeFacet.interface.getSighash("facetAddresses"), + diamondLoupeFacet.interface.getSighash("facetAddress"), + diamondLoupeFacet.interface.getSighash("supportsInterface"), + diamondLoupeFacet.interface.getSighash("facetsFromStorage"), + diamondLoupeFacet.interface.getSighash("facetFunctionSelectorsFromStorage"), + diamondLoupeFacet.interface.getSighash("facetAddressesFromStorage"), + diamondLoupeFacet.interface.getSighash("facetAddressFromStorage")]], + ] + expect(facets).to.deep.equal(defaultAfterCut) + }) + it('Should return valid facet after cutting all defaultFacet', async () => { + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(tokenReceiverFacet.address, getSelectors(tokenReceiverFacet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(diamondLoupeFacet.address, getSelectors(diamondLoupeFacet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(diamondCutFacet.address, getSelectors(diamondCutFacet)) + + + const tokenReceiverFacetSelectors = getSelectors(tokenReceiverFacet) + await expect(addFacetSelectorsViaEntryPointOnK1(barz, owner, tokenReceiverFacet, tokenReceiverFacetSelectors, entryPoint)).to.emit(diamondCutBarz, "DiamondCut") + + const diamondCutFacetSelectors = getSelectors(diamondCutFacet).filter((item: string) => item !== diamondCutFacet.interface.getSighash('securityManager')) + await expect(addFacetSelectorsViaEntryPointOnK1(barz, owner, diamondCutFacet, diamondCutFacetSelectors, entryPoint)).to.emit(diamondCutBarz, "DiamondCut") + + const diamondLoupeFacetSelectors = getSelectors(diamondLoupeFacet) + await expect(addFacetSelectorsViaEntryPointOnK1(barz, owner, diamondLoupeFacet, diamondLoupeFacetSelectors, entryPoint)).to.emit(diamondCutBarz, "DiamondCut") + + const lockFacetSelectors = getSelectors(lockFacet).filter((item: string) => item !== lockFacet.interface.getSighash('securityManager')) + await expect(addFacetSelectorsViaEntryPointOnK1(barz, owner, lockFacet, lockFacetSelectors, entryPoint)).to.emit(diamondCutBarz, "DiamondCut") + + const accountFacetSelectors = getSelectors(accountFacet) + await expect(addFacetSelectorsViaEntryPointOnK1(barz, owner, accountFacet, accountFacetSelectors, entryPoint)).to.emit(diamondCutBarz, "DiamondCut") + + const facets = await diamondLoupeBarz.facets() + const defaultAfterCut = [ + [k1Facet.address, + [k1Facet.interface.getSighash("isValidSignature"), + k1Facet.interface.getSighash("validateOwnerSignature"), + k1Facet.interface.getSighash("owner")]], + + [tokenReceiverFacet.address, + tokenReceiverFacetSelectors], + [diamondCutFacet.address, + diamondCutFacetSelectors], + + [diamondLoupeFacet.address, + diamondLoupeFacetSelectors], + [lockFacet.address, lockFacetSelectors], + + [accountFacet.address, + accountFacetSelectors], + ] + expect(facets).to.deep.equal(defaultAfterCut) + await facetRegistry.connect(facetRegistryOwner).removeFacetFunctionSelectors(tokenReceiverFacet.address, getSelectors(tokenReceiverFacet)) + await facetRegistry.connect(facetRegistryOwner).removeFacetFunctionSelectors(diamondLoupeFacet.address, getSelectors(diamondLoupeFacet)) + await facetRegistry.connect(facetRegistryOwner).removeFacetFunctionSelectors(diamondCutFacet.address, getSelectors(diamondCutFacet)) + + }) + it('Should return valid facets after replacement', async () => { + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(lockFacet.address, [diamondCutFacet.interface.getSighash('diamondCut')]) + + // Replace DiamondCut to lockFacet address: just for test + const cut = diamondCut(lockFacet.address, FacetCutAction.Add, [diamondCutFacet.interface.getSighash('diamondCut')]) + const diamondCutCall = diamondCutFacet.interface.encodeFunctionData('diamondCut', [cut, AddressZero, "0x00"]) + const callData = executeCallData(diamondCutBarz.address, 0, diamondCutCall) + + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, callData)).to.emit(diamondCutBarz, "DiamondCut") + const facets = await diamondLoupeBarz.facets() + const defaultAfterCut = [ + [k1Facet.address, + [k1Facet.interface.getSighash("isValidSignature"), + k1Facet.interface.getSighash("validateOwnerSignature"), + k1Facet.interface.getSighash("owner")]], + + [lockFacet.address, // Originally diamondCutFacet but replaced it to lockFacet + [diamondCutFacet.interface.getSighash("diamondCut")]], + + [accountFacet.address, + [accountFacet.interface.getSighash("execute"), + accountFacet.interface.getSighash("executeBatch"), + accountFacet.interface.getSighash("validateUserOp"), + accountFacet.interface.getSighash("getNonce"), + accountFacet.interface.getSighash("entryPoint")]], + + [tokenReceiverFacet.address, + [tokenReceiverFacet.interface.getSighash("onERC721Received"), + tokenReceiverFacet.interface.getSighash("onERC1155Received"), + tokenReceiverFacet.interface.getSighash("onERC1155BatchReceived"), + tokenReceiverFacet.interface.getSighash("tokensReceived"), + tokenReceiverFacet.interface.getSighash("onTokenTransfer")]], + + [diamondLoupeFacet.address, + [diamondLoupeFacet.interface.getSighash("facets"), + diamondLoupeFacet.interface.getSighash("facetFunctionSelectors"), + diamondLoupeFacet.interface.getSighash("facetAddresses"), + diamondLoupeFacet.interface.getSighash("facetAddress"), + diamondLoupeFacet.interface.getSighash("supportsInterface"), + diamondLoupeFacet.interface.getSighash("facetsFromStorage"), + diamondLoupeFacet.interface.getSighash("facetFunctionSelectorsFromStorage"), + diamondLoupeFacet.interface.getSighash("facetAddressesFromStorage"), + diamondLoupeFacet.interface.getSighash("facetAddressFromStorage")]], + ] + expect(facets).to.deep.equal(defaultAfterCut) + + // Remove from FacetRegistry + await facetRegistry.connect(facetRegistryOwner).removeFacetFunctionSelectors(lockFacet.address, [diamondCutFacet.interface.getSighash('diamondCut')]) + }) + it('Should return valid facets after manipulation', async () => { + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(lockFacet.address, [diamondCutFacet.interface.getSighash('diamondCut')]) + + const lockFacetSelectors = getSelectors(lockFacet).filter((item: string) => item !== lockFacet.interface.getSighash('securityManager')) + await expect(addFacetSelectorsViaEntryPointOnK1(barz, owner, lockFacet, lockFacetSelectors, entryPoint)).to.emit(diamondCutBarz, "DiamondCut") + + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(tokenReceiverFacet.address, [tokenReceiverFacet.interface.getSighash("onERC721Received")]) + + const addCut = diamondCut(tokenReceiverFacet.address, FacetCutAction.Add, [tokenReceiverFacet.interface.getSighash("onERC721Received")]) + const addDiamondCutCall = diamondCutFacet.interface.encodeFunctionData('diamondCut', [addCut, AddressZero, "0x00"]) + const addCallData = executeCallData(diamondCutBarz.address, 0, addDiamondCutCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, addCallData)).to.emit(diamondCutBarz, "DiamondCut") + + const addFacets = await diamondLoupeBarz.facets() + const defaultAfterAddCut = [ + [k1Facet.address, + [k1Facet.interface.getSighash("isValidSignature"), + k1Facet.interface.getSighash("validateOwnerSignature"), + k1Facet.interface.getSighash("owner")]], + + [lockFacet.address, + [...lockFacetSelectors]], + + [tokenReceiverFacet.address, + [tokenReceiverFacet.interface.getSighash("onERC721Received"), + tokenReceiverFacet.interface.getSighash("onERC1155Received"), + tokenReceiverFacet.interface.getSighash("onERC1155BatchReceived"), + tokenReceiverFacet.interface.getSighash("tokensReceived"), + tokenReceiverFacet.interface.getSighash("onTokenTransfer")]], + + [diamondCutFacet.address, + [diamondCutFacet.interface.getSighash("diamondCut")]], + + [accountFacet.address, + [accountFacet.interface.getSighash("execute"), + accountFacet.interface.getSighash("executeBatch"), + accountFacet.interface.getSighash("validateUserOp"), + accountFacet.interface.getSighash("getNonce"), + accountFacet.interface.getSighash("entryPoint")]], + + [diamondLoupeFacet.address, + [diamondLoupeFacet.interface.getSighash("facets"), + diamondLoupeFacet.interface.getSighash("facetFunctionSelectors"), + diamondLoupeFacet.interface.getSighash("facetAddresses"), + diamondLoupeFacet.interface.getSighash("facetAddress"), + diamondLoupeFacet.interface.getSighash("supportsInterface"), + diamondLoupeFacet.interface.getSighash("facetsFromStorage"), + diamondLoupeFacet.interface.getSighash("facetFunctionSelectorsFromStorage"), + diamondLoupeFacet.interface.getSighash("facetAddressesFromStorage"), + diamondLoupeFacet.interface.getSighash("facetAddressFromStorage")]], + ] + expect(addFacets).to.deep.equal(defaultAfterAddCut) + + + const removeCut = diamondCut(AddressZero, FacetCutAction.Remove, [tokenReceiverFacet.interface.getSighash("onERC721Received")]) + const removeDiamondCutCall = diamondCutFacet.interface.encodeFunctionData('diamondCut', [removeCut, AddressZero, "0x00"]) + const removeCallData = executeCallData(diamondCutBarz.address, 0, removeDiamondCutCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, removeCallData)).to.emit(diamondCutBarz, "DiamondCut") + + const facetsAfterRemoval = await diamondLoupeBarz.facets() + const defaultAfterRemovalCut = [ + [k1Facet.address, + [k1Facet.interface.getSighash("isValidSignature"), + k1Facet.interface.getSighash("validateOwnerSignature"), + k1Facet.interface.getSighash("owner")]], + + [lockFacet.address, + [...lockFacetSelectors]], + + [diamondCutFacet.address, + [diamondCutFacet.interface.getSighash("diamondCut")]], + + [accountFacet.address, + [accountFacet.interface.getSighash("execute"), + accountFacet.interface.getSighash("executeBatch"), + accountFacet.interface.getSighash("validateUserOp"), + accountFacet.interface.getSighash("getNonce"), + accountFacet.interface.getSighash("entryPoint")]], + + [tokenReceiverFacet.address, + [tokenReceiverFacet.interface.getSighash("onERC721Received"), + tokenReceiverFacet.interface.getSighash("onERC1155Received"), + tokenReceiverFacet.interface.getSighash("onERC1155BatchReceived"), + tokenReceiverFacet.interface.getSighash("tokensReceived"), + tokenReceiverFacet.interface.getSighash("onTokenTransfer")]], + + [diamondLoupeFacet.address, + [diamondLoupeFacet.interface.getSighash("facets"), + diamondLoupeFacet.interface.getSighash("facetFunctionSelectors"), + diamondLoupeFacet.interface.getSighash("facetAddresses"), + diamondLoupeFacet.interface.getSighash("facetAddress"), + diamondLoupeFacet.interface.getSighash("supportsInterface"), + diamondLoupeFacet.interface.getSighash("facetsFromStorage"), + diamondLoupeFacet.interface.getSighash("facetFunctionSelectorsFromStorage"), + diamondLoupeFacet.interface.getSighash("facetAddressesFromStorage"), + diamondLoupeFacet.interface.getSighash("facetAddressFromStorage")]], + ] + expect(facetsAfterRemoval).to.deep.equal(defaultAfterRemovalCut) + + + const removeLockCut = diamondCut(AddressZero, FacetCutAction.Remove, getSelectors(lockFacet).filter((item: string) => item !== lockFacet.interface.getSighash('securityManager'))) + const removeLockDiamondCutCall = diamondCutFacet.interface.encodeFunctionData('diamondCut', [removeLockCut, AddressZero, "0x00"]) + const removeLockCallData = executeCallData(diamondCutBarz.address, 0, removeLockDiamondCutCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, removeLockCallData)).to.emit(diamondCutBarz, "DiamondCut") + + const facetsAfterLockRemoval = await diamondLoupeBarz.facets() + const defaultAfteLockrRemovalCut = [ + [k1Facet.address, + [k1Facet.interface.getSighash("isValidSignature"), + k1Facet.interface.getSighash("validateOwnerSignature"), + k1Facet.interface.getSighash("owner")]], + + [diamondCutFacet.address, + [diamondCutFacet.interface.getSighash("diamondCut")]], + + [accountFacet.address, + [accountFacet.interface.getSighash("execute"), + accountFacet.interface.getSighash("executeBatch"), + accountFacet.interface.getSighash("validateUserOp"), + accountFacet.interface.getSighash("getNonce"), + accountFacet.interface.getSighash("entryPoint")]], + + [tokenReceiverFacet.address, + [tokenReceiverFacet.interface.getSighash("onERC721Received"), + tokenReceiverFacet.interface.getSighash("onERC1155Received"), + tokenReceiverFacet.interface.getSighash("onERC1155BatchReceived"), + tokenReceiverFacet.interface.getSighash("tokensReceived"), + tokenReceiverFacet.interface.getSighash("onTokenTransfer")]], + + [diamondLoupeFacet.address, + [diamondLoupeFacet.interface.getSighash("facets"), + diamondLoupeFacet.interface.getSighash("facetFunctionSelectors"), + diamondLoupeFacet.interface.getSighash("facetAddresses"), + diamondLoupeFacet.interface.getSighash("facetAddress"), + diamondLoupeFacet.interface.getSighash("supportsInterface"), + diamondLoupeFacet.interface.getSighash("facetsFromStorage"), + diamondLoupeFacet.interface.getSighash("facetFunctionSelectorsFromStorage"), + diamondLoupeFacet.interface.getSighash("facetAddressesFromStorage"), + diamondLoupeFacet.interface.getSighash("facetAddressFromStorage")]], + ] + expect(facetsAfterLockRemoval).to.deep.equal(defaultAfteLockrRemovalCut) + + const cut = diamondCut(lockFacet.address, FacetCutAction.Add, [diamondCutFacet.interface.getSighash('diamondCut')]) + const diamondCutCall = diamondCutFacet.interface.encodeFunctionData('diamondCut', [cut, AddressZero, "0x00"]) + const callData = executeCallData(diamondCutBarz.address, 0, diamondCutCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, callData)).to.emit(diamondCutBarz, "DiamondCut") + + const facets = await diamondLoupeBarz.facets() + const defaultAfterCut = [ + [k1Facet.address, + [k1Facet.interface.getSighash("isValidSignature"), + k1Facet.interface.getSighash("validateOwnerSignature"), + k1Facet.interface.getSighash("owner")]], + + [lockFacet.address, // Replaced diamondCut with LockFacet + [diamondCutFacet.interface.getSighash("diamondCut")]], + + [accountFacet.address, + [accountFacet.interface.getSighash("execute"), + accountFacet.interface.getSighash("executeBatch"), + accountFacet.interface.getSighash("validateUserOp"), + accountFacet.interface.getSighash("getNonce"), + accountFacet.interface.getSighash("entryPoint")]], + + [tokenReceiverFacet.address, + [tokenReceiverFacet.interface.getSighash("onERC721Received"), + tokenReceiverFacet.interface.getSighash("onERC1155Received"), + tokenReceiverFacet.interface.getSighash("onERC1155BatchReceived"), + tokenReceiverFacet.interface.getSighash("tokensReceived"), + tokenReceiverFacet.interface.getSighash("onTokenTransfer")]], + + [diamondLoupeFacet.address, + [diamondLoupeFacet.interface.getSighash("facets"), + diamondLoupeFacet.interface.getSighash("facetFunctionSelectors"), + diamondLoupeFacet.interface.getSighash("facetAddresses"), + diamondLoupeFacet.interface.getSighash("facetAddress"), + diamondLoupeFacet.interface.getSighash("supportsInterface"), + diamondLoupeFacet.interface.getSighash("facetsFromStorage"), + diamondLoupeFacet.interface.getSighash("facetFunctionSelectorsFromStorage"), + diamondLoupeFacet.interface.getSighash("facetAddressesFromStorage"), + diamondLoupeFacet.interface.getSighash("facetAddressFromStorage")]], + ] + expect(facets).to.deep.equal(defaultAfterCut) + + await facetRegistry.connect(facetRegistryOwner).removeFacetFunctionSelectors(tokenReceiverFacet.address, [tokenReceiverFacet.interface.getSighash("onERC721Received")]) + }) + }) + describe('# facetAddresses', () => { + it('Should return default facet addresses', async () => { + const defaultFacetAddresses = [k1Facet.address, diamondCutFacet.address, accountFacet.address, tokenReceiverFacet.address, diamondLoupeFacet.address] + expect(await diamondLoupeBarz.facetAddresses()).to.deep.equal(defaultFacetAddresses) + }) + it('Should return added facet address when added to diamond', async () => { + const expectedFacetAddresses = [k1Facet.address, lockFacet.address, diamondCutFacet.address, accountFacet.address, tokenReceiverFacet.address, diamondLoupeFacet.address] + const lockFacetSelectors = getSelectors(lockFacet).filter((item: string) => item !== lockFacet.interface.getSighash('securityManager')) + const cut = diamondCut(lockFacet.address, FacetCutAction.Add, lockFacetSelectors) + const diamondCutCall = diamondCutFacet.interface.encodeFunctionData('diamondCut', [cut, AddressZero, "0x00"]) + const callData = executeCallData(diamondCutBarz.address, 0, diamondCutCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, callData)).to.emit(diamondCutBarz, "DiamondCut") + expect(await diamondLoupeBarz.facetAddresses()).to.deep.equal(expectedFacetAddresses) + }) + it('Should return replaced facet address', async () => { + // Just for testing + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(tokenReceiverFacet.address, [tokenReceiverFacet.interface.getSighash("onERC721Received")]) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(lockFacet.address, [tokenReceiverFacet.interface.getSighash("onERC721Received")]) + + const beforeFacetAddresses = [k1Facet.address, tokenReceiverFacet.address, diamondCutFacet.address, accountFacet.address, diamondLoupeFacet.address] + const receiverFacetSelector = [tokenReceiverFacet.interface.getSighash("onERC721Received")] + const cut = diamondCut(tokenReceiverFacet.address, FacetCutAction.Add, receiverFacetSelector) + const diamondCutCall = diamondCutFacet.interface.encodeFunctionData('diamondCut', [cut, AddressZero, "0x00"]) + const callData = executeCallData(diamondCutBarz.address, 0, diamondCutCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, callData)).to.emit(diamondCutBarz, "DiamondCut") + expect(await diamondLoupeBarz.facetAddresses()).to.deep.equal(beforeFacetAddresses) + + const afterFacetAddresses = [k1Facet.address, lockFacet.address, diamondCutFacet.address, accountFacet.address, tokenReceiverFacet.address, diamondLoupeFacet.address] + const replaceCut = diamondCut(lockFacet.address, FacetCutAction.Replace, receiverFacetSelector) + const diamondReplaceCutCall = diamondCutFacet.interface.encodeFunctionData('diamondCut', [replaceCut, AddressZero, "0x00"]) + const replaceCallData = executeCallData(diamondCutBarz.address, 0, diamondReplaceCutCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, replaceCallData)).to.emit(diamondCutBarz, "DiamondCut") + expect(await diamondLoupeBarz.facetAddresses()).to.deep.equal(afterFacetAddresses) + + await facetRegistry.connect(facetRegistryOwner).removeFacetFunctionSelectors(lockFacet.address, [tokenReceiverFacet.interface.getSighash("onERC721Received")]) + await facetRegistry.connect(facetRegistryOwner).removeFacetFunctionSelectors(tokenReceiverFacet.address, [tokenReceiverFacet.interface.getSighash("onERC721Received")]) + + }) + }) + describe('# facetFunctionSelectors', () => { + it('Should return default facet function selectors', async () => { + expect(await diamondLoupeBarz.facetFunctionSelectors(k1Facet.address)).to.deep.equal([k1Facet.interface.getSighash('isValidSignature'), k1Facet.interface.getSighash('validateOwnerSignature'), k1Facet.interface.getSighash('owner')]) + }) + it('Should return added facet functions selectors when added to diamond', async () => { + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(lockFacet.address, [tokenReceiverFacet.interface.getSighash("onERC721Received")]) + + const receiverFacetSelector = [tokenReceiverFacet.interface.getSighash("onERC721Received")] + const cut = diamondCut(lockFacet.address, FacetCutAction.Add, receiverFacetSelector) + const diamondCutCall = diamondCutFacet.interface.encodeFunctionData('diamondCut', [cut, AddressZero, "0x00"]) + const callData = executeCallData(diamondCutBarz.address, 0, diamondCutCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, callData)).to.emit(diamondCutBarz, "DiamondCut") + + expect(await diamondLoupeBarz.facetFunctionSelectors(lockFacet.address)).to.deep.equal([tokenReceiverFacet.interface.getSighash('onERC721Received')]) + + await facetRegistry.connect(facetRegistryOwner).removeFacetFunctionSelectors(lockFacet.address, [tokenReceiverFacet.interface.getSighash("onERC721Received")]) + }) + it('Should return empty selectors if facet is attached', async () => { + expect(await diamondLoupeBarz.facetFunctionSelectors(lockFacet.address)).to.deep.equal([]) + }) + }) + describe('# facetAddress', () => { + it('Should return valid facet address of facet function selector', async () => { + const ownerSelector = k1Facet.interface.getSighash('owner') + expect(await diamondLoupeBarz.facetAddress(ownerSelector)).to.equal(k1Facet.address) + + const diamondCutSelector = diamondCutFacet.interface.getSighash('diamondCut') + expect(await diamondLoupeBarz.facetAddress(diamondCutSelector)).to.equal(diamondCutFacet.address) + + const onERC721ReceivedSelector = tokenReceiverFacet.interface.getSighash('onERC721Received') + expect(await diamondLoupeBarz.facetAddress(onERC721ReceivedSelector)).to.equal(tokenReceiverFacet.address) + }) + it('Should return zero address if non-existent function selector', async () => { + const lockSelector = lockFacet.interface.getSighash('lock') + expect(await diamondLoupeBarz.facetAddress(lockSelector)).to.equal(AddressZero) + }) + it('Should return added facet address when added to diamond', async () => { + const lockSelector = lockFacet.interface.getSighash("lock") + const cut = diamondCut(lockFacet.address, FacetCutAction.Add, [lockSelector]) + const diamondCutCall = diamondCutFacet.interface.encodeFunctionData('diamondCut', [cut, AddressZero, "0x00"]) + const callData = executeCallData(diamondCutBarz.address, 0, diamondCutCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, callData)).to.emit(diamondCutBarz, "DiamondCut") + + expect(await diamondLoupeBarz.facetAddress(lockSelector)).to.equal(lockFacet.address) + }) + }) + describe('# facetsFromStorage', () => { + it('Should return verification facet by default', async () => { + const defaultFacets = [ + [k1Facet.address, + [k1Facet.interface.getSighash("isValidSignature"), + k1Facet.interface.getSighash("validateOwnerSignature"), + k1Facet.interface.getSighash("owner")]]] + expect(await diamondLoupeBarz.facetsFromStorage()).to.deep.equal(defaultFacets) + }) + it('Should return added facet when facet is added', async () => { + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(tokenReceiverFacet.address, [tokenReceiverFacet.interface.getSighash("onERC721Received")]) + + const receiverFacetSelector = [tokenReceiverFacet.interface.getSighash("onERC721Received")] + const cut = diamondCut(tokenReceiverFacet.address, FacetCutAction.Add, receiverFacetSelector) + const diamondCutCall = diamondCutFacet.interface.encodeFunctionData('diamondCut', [cut, AddressZero, "0x00"]) + const callData = executeCallData(diamondCutBarz.address, 0, diamondCutCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, callData)).to.emit(diamondCutBarz, "DiamondCut") + + const defaultFacets = [ + [k1Facet.address, + [k1Facet.interface.getSighash("isValidSignature"), + k1Facet.interface.getSighash("validateOwnerSignature"), + k1Facet.interface.getSighash("owner")]], + [tokenReceiverFacet.address, + [tokenReceiverFacet.interface.getSighash("onERC721Received")]] + ] + expect(await diamondLoupeBarz.facetsFromStorage()).to.deep.equal(defaultFacets) + + await facetRegistry.connect(facetRegistryOwner).removeFacetFunctionSelectors(tokenReceiverFacet.address, [tokenReceiverFacet.interface.getSighash("onERC721Received")]) + }) + it('Should exclude removed facet', async () => { + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(tokenReceiverFacet.address, [tokenReceiverFacet.interface.getSighash("onERC721Received")]) + + const receiverFacetSelector = [tokenReceiverFacet.interface.getSighash("onERC721Received")] + const cut = diamondCut(tokenReceiverFacet.address, FacetCutAction.Add, receiverFacetSelector) + const diamondCutCall = diamondCutFacet.interface.encodeFunctionData('diamondCut', [cut, AddressZero, "0x00"]) + const callData = executeCallData(diamondCutBarz.address, 0, diamondCutCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, callData)).to.emit(diamondCutBarz, "DiamondCut") + + const facets = [ + [k1Facet.address, + [k1Facet.interface.getSighash("isValidSignature"), + k1Facet.interface.getSighash("validateOwnerSignature"), + k1Facet.interface.getSighash("owner")]], + [tokenReceiverFacet.address, + [tokenReceiverFacet.interface.getSighash("onERC721Received")]] + ] + expect(await diamondLoupeBarz.facetsFromStorage()).to.deep.equal(facets) + + const removeCut = diamondCut(AddressZero, FacetCutAction.Remove, receiverFacetSelector) + const removeCutCall = diamondCutFacet.interface.encodeFunctionData('diamondCut', [removeCut, AddressZero, "0x00"]) + const removeCallData = executeCallData(diamondCutBarz.address, 0, removeCutCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, removeCallData)).to.emit(diamondCutBarz, "DiamondCut") + + const facetsAfterRemoval = [ + [k1Facet.address, + [k1Facet.interface.getSighash("isValidSignature"), + k1Facet.interface.getSighash("validateOwnerSignature"), + k1Facet.interface.getSighash("owner")]] + ] + expect(await diamondLoupeBarz.facetsFromStorage()).to.deep.equal(facetsAfterRemoval) + + await facetRegistry.connect(facetRegistryOwner).removeFacetFunctionSelectors(tokenReceiverFacet.address, [tokenReceiverFacet.interface.getSighash("onERC721Received")]) + }) + }) + describe('# facetAddressFromStorage', () => { + it('Should return valid address of facet', async () => { + expect(await diamondLoupeBarz.facetAddressFromStorage(k1Facet.interface.getSighash('isValidSignature'))).to.equal(k1Facet.address) + expect(await diamondLoupeBarz.facetAddressFromStorage(k1Facet.interface.getSighash('owner'))).to.equal(k1Facet.address) + expect(await diamondLoupeBarz.facetAddressFromStorage(k1Facet.interface.getSighash('validateOwnerSignature'))).to.equal(k1Facet.address) + expect(await diamondLoupeBarz.facetAddressFromStorage(diamondCutFacet.interface.getSighash('diamondCut'))).to.equal(AddressZero) + }) + it('Should return added facet when facet is added', async () => { + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(tokenReceiverFacet.address, [tokenReceiverFacet.interface.getSighash("onERC721Received")]) + + expect(await diamondLoupeBarz.facetAddressFromStorage(tokenReceiverFacet.interface.getSighash('onERC721Received'))).to.equal(AddressZero) + + const receiverFacetSelector = [tokenReceiverFacet.interface.getSighash("onERC721Received")] + const cut = diamondCut(tokenReceiverFacet.address, FacetCutAction.Add, receiverFacetSelector) + const diamondCutCall = diamondCutFacet.interface.encodeFunctionData('diamondCut', [cut, AddressZero, "0x00"]) + const callData = executeCallData(diamondCutBarz.address, 0, diamondCutCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, callData)).to.emit(diamondCutBarz, "DiamondCut") + + expect(await diamondLoupeBarz.facetAddressFromStorage(tokenReceiverFacet.interface.getSighash('onERC721Received'))).to.equal(tokenReceiverFacet.address) + + await facetRegistry.connect(facetRegistryOwner).removeFacetFunctionSelectors(tokenReceiverFacet.address, [tokenReceiverFacet.interface.getSighash("onERC721Received")]) + }) + }) + describe('# facetAddressesFromStorage', () => { + it('Should return valid list of facet addresses', async () => { + const facetAddresses = [ + k1Facet.address + ] + expect(await diamondLoupeBarz.facetAddressesFromStorage()).to.deep.equal(facetAddresses) + }) + it('Should return added facet when facet is added', async () => { + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(tokenReceiverFacet.address, [tokenReceiverFacet.interface.getSighash("onERC721Received")]) + + expect(await diamondLoupeBarz.facetAddressFromStorage(tokenReceiverFacet.interface.getSighash('onERC721Received'))).to.equal(AddressZero) + + const receiverFacetSelector = [tokenReceiverFacet.interface.getSighash("onERC721Received")] + const cut = diamondCut(tokenReceiverFacet.address, FacetCutAction.Add, receiverFacetSelector) + const diamondCutCall = diamondCutFacet.interface.encodeFunctionData('diamondCut', [cut, AddressZero, "0x00"]) + const callData = executeCallData(diamondCutBarz.address, 0, diamondCutCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, callData)).to.emit(diamondCutBarz, "DiamondCut") + + const facetAddresses = [ + k1Facet.address, + tokenReceiverFacet.address + ] + expect(await diamondLoupeBarz.facetAddressesFromStorage()).to.deep.equal(facetAddresses) + await facetRegistry.connect(facetRegistryOwner).removeFacetFunctionSelectors(tokenReceiverFacet.address, [tokenReceiverFacet.interface.getSighash("onERC721Received")]) + }) + it('Should return exclude facet address when facet is removed', async () => { + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(tokenReceiverFacet.address, [tokenReceiverFacet.interface.getSighash("onERC721Received")]) + + expect(await diamondLoupeBarz.facetAddressFromStorage(tokenReceiverFacet.interface.getSighash('onERC721Received'))).to.equal(AddressZero) + + const receiverFacetSelector = [tokenReceiverFacet.interface.getSighash("onERC721Received")] + const cut = diamondCut(tokenReceiverFacet.address, FacetCutAction.Add, receiverFacetSelector) + const diamondCutCall = diamondCutFacet.interface.encodeFunctionData('diamondCut', [cut, AddressZero, "0x00"]) + const callData = executeCallData(diamondCutBarz.address, 0, diamondCutCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, callData)).to.emit(diamondCutBarz, "DiamondCut") + + const facetAddresses = [ + k1Facet.address, + tokenReceiverFacet.address + ] + expect(await diamondLoupeBarz.facetAddressesFromStorage()).to.deep.equal(facetAddresses) + + const removeCut = diamondCut(AddressZero, FacetCutAction.Remove, receiverFacetSelector) + const removeCutCall = diamondCutFacet.interface.encodeFunctionData('diamondCut', [removeCut, AddressZero, "0x00"]) + const removeCallData = executeCallData(diamondCutBarz.address, 0, removeCutCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, removeCallData)).to.emit(diamondCutBarz, "DiamondCut") + + const facetsAfterRemoval = [ + [k1Facet.address, + [k1Facet.interface.getSighash("isValidSignature"), + k1Facet.interface.getSighash("validateOwnerSignature"), + k1Facet.interface.getSighash("owner")]] + ] + expect(await diamondLoupeBarz.facetsFromStorage()).to.deep.equal(facetsAfterRemoval) + + const facetAddressesAfterRemoval = [ + k1Facet.address + ] + expect(await diamondLoupeBarz.facetAddressesFromStorage()).to.deep.equal(facetAddressesAfterRemoval) + + await facetRegistry.connect(facetRegistryOwner).removeFacetFunctionSelectors(tokenReceiverFacet.address, [tokenReceiverFacet.interface.getSighash("onERC721Received")]) + }) + }) + describe('# facetFunctionSelectorsFromStorage', () => { + it('Should return valid list of facet function selectors', async () => { + const verificationFacetSelectors = [ + k1Facet.interface.getSighash('isValidSignature'), + k1Facet.interface.getSighash('validateOwnerSignature'), + k1Facet.interface.getSighash('owner') + ] + expect(await diamondLoupeBarz.facetFunctionSelectorsFromStorage(k1Facet.address)).to.deep.equal(verificationFacetSelectors) + }) + it('Should return added facet selector when facet is added', async () => { + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(tokenReceiverFacet.address, [tokenReceiverFacet.interface.getSighash("onERC721Received")]) + + expect(await diamondLoupeBarz.facetAddressFromStorage(tokenReceiverFacet.interface.getSighash('onERC721Received'))).to.equal(AddressZero) + + const receiverFacetSelector = [tokenReceiverFacet.interface.getSighash("onERC721Received")] + const cut = diamondCut(tokenReceiverFacet.address, FacetCutAction.Add, receiverFacetSelector) + const diamondCutCall = diamondCutFacet.interface.encodeFunctionData('diamondCut', [cut, AddressZero, "0x00"]) + const callData = executeCallData(diamondCutBarz.address, 0, diamondCutCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, callData)).to.emit(diamondCutBarz, "DiamondCut") + const verificationFacetSelectors = [ + k1Facet.interface.getSighash('isValidSignature'), + k1Facet.interface.getSighash('validateOwnerSignature'), + k1Facet.interface.getSighash('owner') + ] + expect(await diamondLoupeBarz.facetFunctionSelectorsFromStorage(k1Facet.address)).to.deep.equal(verificationFacetSelectors) + expect(await diamondLoupeBarz.facetFunctionSelectorsFromStorage(tokenReceiverFacet.address)).to.deep.equal(receiverFacetSelector) + + await facetRegistry.connect(facetRegistryOwner).removeFacetFunctionSelectors(tokenReceiverFacet.address, [tokenReceiverFacet.interface.getSighash("onERC721Received")]) + }) + it('Should return exclude facet selector when facet is removed', async () => { + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(tokenReceiverFacet.address, [tokenReceiverFacet.interface.getSighash("onERC721Received")]) + + expect(await diamondLoupeBarz.facetAddressFromStorage(tokenReceiverFacet.interface.getSighash('onERC721Received'))).to.equal(AddressZero) + + const receiverFacetSelector = [tokenReceiverFacet.interface.getSighash("onERC721Received")] + const cut = diamondCut(tokenReceiverFacet.address, FacetCutAction.Add, receiverFacetSelector) + const diamondCutCall = diamondCutFacet.interface.encodeFunctionData('diamondCut', [cut, AddressZero, "0x00"]) + const callData = executeCallData(diamondCutBarz.address, 0, diamondCutCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, callData)).to.emit(diamondCutBarz, "DiamondCut") + const verificationFacetSelectors = [ + k1Facet.interface.getSighash('isValidSignature'), + k1Facet.interface.getSighash('validateOwnerSignature'), + k1Facet.interface.getSighash('owner') + ] + expect(await diamondLoupeBarz.facetFunctionSelectorsFromStorage(k1Facet.address)).to.deep.equal(verificationFacetSelectors) + expect(await diamondLoupeBarz.facetFunctionSelectorsFromStorage(tokenReceiverFacet.address)).to.deep.equal(receiverFacetSelector) + + const removeCut = diamondCut(AddressZero, FacetCutAction.Remove, receiverFacetSelector) + const removeCutCall = diamondCutFacet.interface.encodeFunctionData('diamondCut', [removeCut, AddressZero, "0x00"]) + const removeCallData = executeCallData(diamondCutBarz.address, 0, removeCutCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, removeCallData)).to.emit(diamondCutBarz, "DiamondCut") + + expect(await diamondLoupeBarz.facetFunctionSelectorsFromStorage(tokenReceiverFacet.address)).to.deep.equal([]) + expect(await diamondLoupeBarz.facetFunctionSelectorsFromStorage(k1Facet.address)).to.deep.equal(verificationFacetSelectors) + }) + }) +}) diff --git a/test/GuardianFacet.test.ts b/test/GuardianFacet.test.ts new file mode 100644 index 0000000..089dfb9 --- /dev/null +++ b/test/GuardianFacet.test.ts @@ -0,0 +1,403 @@ +import { ethers } from 'hardhat' +import { Wallet } from 'ethers' + +import { AccountFacet, DiamondCutFacet, Barz, Secp256k1VerificationFacet, SecurityManager, GuardianFacet, FacetRegistry, DiamondLoupeFacet, TokenReceiverFacet, DefaultFallbackHandler } from '../typechain-types' +import { increaseBlockTime, guardianSecurityPeriod, guardianSecurityWindow } from './utils/helpers' +import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers' +import { AddressZero, createAccountOwner, fund } from './utils/testutils' + +const { + getSelectors +} = require('./utils/diamond.js') + +import { expect } from "chai" +import { diamondCutFacetFixture } from './fixtures/DiamondCutFacetFixture' +import { accountFacetFixture } from './fixtures/AccountFacetFixture' +import { secp256k1VerificationFacetFixture } from './fixtures/Secp256k1VerificationFacetFixture' +import { barzFixture } from './fixtures/BarzFixture' +import { addFacetSelectors, addFacetSelectorsViaEntryPointOnK1, getFacetBarz, setupDefaultSecuritManager } from './utils/setup' +import { guardianFacetFixture } from './fixtures/GuardianFacetFixture' +import { facetRegistryFixture } from './fixtures/FacetRegistryFixture' +import { EntryPoint } from '../typechain-types/core' +import { entryPointFixture } from './fixtures/EntryPointFixture' +import { callFromEntryPointOnK1, executeCallData } from './utils/UserOp' +import { diamondLoupeFacetFixture } from './fixtures/DiamondLoupeFacetFixture' +import { tokenReceiverFacetFixture } from './fixtures/TokenReceiverFacetFixture' +import { defaultFallbackHandlerFixture } from './fixtures/DefaultFallbackHandlerFixture' + +describe('Guardian Facet', () => { + let diamondCutFacet: DiamondCutFacet + let securityManager: SecurityManager + let facetRegistry: FacetRegistry + let defaultFallbackHandler: DefaultFallbackHandler + let accountFacet: AccountFacet + let tokenReceiverFacet: TokenReceiverFacet + let k1Facet: Secp256k1VerificationFacet + let entryPoint: EntryPoint + let diamondLoupeFacet: DiamondLoupeFacet + let guardian1: SignerWithAddress + let guardian2: SignerWithAddress + let nonGuardian: SignerWithAddress + let mockEntryPoint: SignerWithAddress + let owner: Wallet + let barz: Barz + let mockBarz: Barz + let mockAccountBarz: AccountFacet + let mockGuardianBarz: GuardianFacet + let guardianFacet: GuardianFacet + let guardianBarz: GuardianFacet + let securityManagerOwner: SignerWithAddress + let facetRegistryOwner: SignerWithAddress + let nonce: number + let guardianFacetSelectors: any + + before(async () => { + [mockEntryPoint, guardian1, guardian2, nonGuardian, securityManagerOwner, facetRegistryOwner] = await ethers.getSigners() + owner = createAccountOwner() + await fund(owner.address) + + securityManager = await setupDefaultSecuritManager(securityManagerOwner) + facetRegistry = await facetRegistryFixture(facetRegistryOwner.address) + accountFacet = await accountFacetFixture() + k1Facet = await secp256k1VerificationFacetFixture() + diamondCutFacet = await diamondCutFacetFixture(securityManager) + guardianFacet = await guardianFacetFixture(securityManager) + diamondLoupeFacet = await diamondLoupeFacetFixture() + tokenReceiverFacet = await tokenReceiverFacetFixture() + defaultFallbackHandler = await defaultFallbackHandlerFixture(diamondCutFacet, accountFacet, tokenReceiverFacet, diamondLoupeFacet) + + entryPoint = await entryPointFixture() + guardianFacetSelectors = getSelectors(guardianFacet).filter((item: string) => item !== guardianFacet.interface.getSighash('securityManager')) + + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(guardianFacet.address, getSelectors(guardianFacet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(accountFacet.address, getSelectors(accountFacet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(k1Facet.address, getSelectors(k1Facet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(diamondCutFacet.address, getSelectors(diamondCutFacet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(diamondLoupeFacet.address, getSelectors(diamondLoupeFacet)) + }) + beforeEach(async () => { + barz = await barzFixture(accountFacet, k1Facet, entryPoint, facetRegistry, defaultFallbackHandler, owner.publicKey) + guardianBarz = await getFacetBarz('GuardianFacet', barz) + await fund(barz.address) + + mockBarz = await barzFixture(accountFacet, k1Facet, mockEntryPoint, facetRegistry, defaultFallbackHandler, owner.publicKey) + mockAccountBarz = await getFacetBarz('AccountFacet', mockBarz) + mockGuardianBarz = await getFacetBarz('GuardianFacet', mockBarz) + await fund(mockBarz.address) + + await addFacetSelectors(mockBarz, guardianFacet, guardianFacetSelectors, mockEntryPoint) + }) + const setupGuardianBarz = async () => { + await addFacetSelectorsViaEntryPointOnK1(barz, owner, guardianFacet, guardianFacetSelectors, entryPoint) + } + it("Should add Guardian Facet to wallet", async () => { + const guardianCutTx = await addFacetSelectorsViaEntryPointOnK1(barz, owner, guardianFacet, guardianFacetSelectors, entryPoint) + const guardianCutReceipt = await guardianCutTx.wait() + expect(guardianCutReceipt.status).to.equal(1) + }) + + describe("# addGuardian", () => { + it("Should revert if guardian is zero address", async () => { + const addGuardianCall = guardianFacet.interface.encodeFunctionData("addGuardian", [AddressZero]) + await expect(mockAccountBarz.connect(mockEntryPoint).execute(mockGuardianBarz.address, 0, addGuardianCall)).to.be.revertedWithCustomError(guardianBarz, "GuardianFacet__ZeroAddressGuardian") + }) + it("Should revert if guardian is self", async () => { + const addGuardianCall = guardianFacet.interface.encodeFunctionData("addGuardian", [mockGuardianBarz.address]) + await expect(mockAccountBarz.connect(mockEntryPoint).execute(mockAccountBarz.address, 0, addGuardianCall)).to.be.revertedWithCustomError(mockGuardianBarz, "GuardianFacet__GuardianCannotBeSelf") + }) + it("Should revert if guardian is signer", async () => { + const addGuardianCall = guardianFacet.interface.encodeFunctionData("addGuardian", [guardian1.address]) + await expect(mockAccountBarz.connect(mockEntryPoint).execute(mockAccountBarz.address, 0, addGuardianCall)).to.emit(mockGuardianBarz, "GuardianAdditionRequested") + }) + it("Should revert if guardian addition is duplicate", async () => { + const addGuardianCall = guardianFacet.interface.encodeFunctionData("addGuardian", [guardian1.address]) + await expect(mockAccountBarz.connect(mockEntryPoint).execute(mockAccountBarz.address, 0, addGuardianCall)).to.emit(mockGuardianBarz, "GuardianAdditionRequested") + await expect(mockAccountBarz.connect(mockEntryPoint).execute(mockAccountBarz.address, 0, addGuardianCall)).to.be.revertedWithCustomError(mockGuardianBarz, "GuardianFacet__DuplicateGuardianAddition") + }) + it("Should add guardian to wallet", async () => { + await setupGuardianBarz() + const addGuardianCall = guardianFacet.interface.encodeFunctionData("addGuardian", [guardian1.address]) + const callData = executeCallData(barz.address, 0, addGuardianCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, callData)).to.emit(guardianBarz, "GuardianAdditionRequested") + }) + it("Should revert if guardian is already added", async () => { + const addGuardianCall = guardianFacet.interface.encodeFunctionData("addGuardian", [guardian1.address]) + await expect(mockAccountBarz.connect(mockEntryPoint).execute(mockAccountBarz.address, 0, addGuardianCall)).to.emit(mockGuardianBarz, "GuardianAdditionRequested") + await increaseBlockTime(guardianSecurityPeriod) + await expect(mockGuardianBarz.confirmGuardianAddition(guardian1.address)).to.emit(mockGuardianBarz, "GuardianAdded") + + await expect(mockAccountBarz.connect(mockEntryPoint).execute(mockAccountBarz.address, 0, addGuardianCall)).to.be.revertedWithCustomError(mockGuardianBarz, "GuardianFacet__DuplicateGuardian") + }) + }) + describe("# addGuardians", () => { + it("Should revert if not owner", async () => { + await expect(mockGuardianBarz.addGuardians([guardian1.address, guardian1.address])).to.revertedWith("LibDiamond: Caller not self") + }) + it("Should add multiple guardians", async () => { + const addGuardianCall = guardianFacet.interface.encodeFunctionData("addGuardians", [[guardian1.address, guardian2.address]]) + await expect(mockAccountBarz.connect(mockEntryPoint).execute(mockAccountBarz.address, 0, addGuardianCall)).to.emit(mockGuardianBarz, "GuardianAdditionRequested") + await increaseBlockTime(guardianSecurityPeriod) + await expect(mockGuardianBarz.confirmGuardianAddition(guardian1.address)).to.emit(mockGuardianBarz, "GuardianAdded") + }) + }) + describe("# confirmGuardianAddition", () => { + it("Should revert if unknown addition", async () => { + await expect(mockGuardianBarz.confirmGuardianAddition(guardian1.address)).to.be.revertedWithCustomError(mockGuardianBarz, "GuardianFacet__UnknownPendingAddition") + }) + it("Should revert if pending period is not over", async () => { + const addGuardianCall = guardianFacet.interface.encodeFunctionData("addGuardian", [guardian1.address]) + await expect(mockAccountBarz.connect(mockEntryPoint).execute(mockAccountBarz.address, 0, addGuardianCall)).to.emit(mockGuardianBarz, "GuardianAdditionRequested") + await expect(mockGuardianBarz.confirmGuardianAddition(guardian1.address)).to.be.revertedWithCustomError(mockGuardianBarz, "GuardianFacet__PendingAdditionNotOver") + }) + it("Should revert if security window expired", async () => { + const addGuardianCall = guardianFacet.interface.encodeFunctionData("addGuardian", [guardian1.address]) + await expect(mockAccountBarz.connect(mockEntryPoint).execute(mockAccountBarz.address, 0, addGuardianCall)).to.emit(mockGuardianBarz, "GuardianAdditionRequested") + await increaseBlockTime(guardianSecurityPeriod + guardianSecurityWindow) + await expect(mockGuardianBarz.confirmGuardianAddition(guardian1.address)).to.be.revertedWithCustomError(mockGuardianBarz, "GuardianFacet__PendingAdditionExpired") + }) + it("Should confirm guardian addtion", async () => { + await setupGuardianBarz() + const addGuardianCall = guardianFacet.interface.encodeFunctionData("addGuardian", [guardian1.address]) + const callData = executeCallData(barz.address, 0, addGuardianCall) + await callFromEntryPointOnK1(entryPoint, barz.address, owner, callData) + + await increaseBlockTime(guardianSecurityPeriod) + await expect(guardianBarz.confirmGuardianAddition(guardian1.address)).to.emit(guardianBarz, "GuardianAdded") + expect(await guardianBarz.isGuardian(guardian1.address)).to.be.true + expect(await guardianBarz.getGuardians()).to.deep.equal([guardian1.address]) + }) + }) + describe("# confirmGuardianAdditions", () => { + it("Should confirm multile guardian addition", async () => { + const addGuardianCall = guardianFacet.interface.encodeFunctionData("addGuardians", [[guardian1.address, guardian2.address]]) + await expect(mockAccountBarz.connect(mockEntryPoint).execute(mockAccountBarz.address, 0, addGuardianCall)).to.emit(mockGuardianBarz, "GuardianAdditionRequested") + await increaseBlockTime(guardianSecurityPeriod) + await expect(mockGuardianBarz.confirmGuardianAdditions([guardian1.address, guardian2.address])).to.emit(mockGuardianBarz, "GuardianAdded") + + expect(await mockGuardianBarz.isGuardian(guardian1.address)).to.be.true + expect(await mockGuardianBarz.isGuardian(guardian2.address)).to.be.true + }) + }) + + describe("# removeGuardian", () => { + beforeEach(async () => { + const addGuardianCall = guardianFacet.interface.encodeFunctionData("addGuardians", [[guardian1.address, guardian2.address]]) + await expect(mockAccountBarz.connect(mockEntryPoint).execute(mockAccountBarz.address, 0, addGuardianCall)).to.emit(mockGuardianBarz, "GuardianAdditionRequested") + await increaseBlockTime(guardianSecurityPeriod) + await expect(mockGuardianBarz.confirmGuardianAdditions([guardian1.address, guardian2.address])).to.emit(mockGuardianBarz, "GuardianAdded") + }) + it("Should revert if not owner", async () => { + await expect(mockGuardianBarz.removeGuardian(guardian1.address)).to.be.revertedWith("LibDiamond: Caller not self") + }) + it("Should revert if address getting removed is not guardian", async () => { + const removeGuardianCall = guardianFacet.interface.encodeFunctionData("removeGuardian", [nonGuardian.address]) + await expect(mockAccountBarz.connect(mockEntryPoint).execute(mockAccountBarz.address, 0, removeGuardianCall)).to.be.revertedWithCustomError(mockGuardianBarz, "GuardianFacet__NonExistentGuardian") + }) + it("Should revert if guardian removal already exists", async () => { + const removeGuardianCall = guardianFacet.interface.encodeFunctionData("removeGuardian", [guardian1.address]) + await expect(mockAccountBarz.connect(mockEntryPoint).execute(mockAccountBarz.address, 0, removeGuardianCall)).to.emit(mockGuardianBarz, "GuardianRemovalRequested") + + await expect(mockAccountBarz.connect(mockEntryPoint).execute(mockAccountBarz.address, 0, removeGuardianCall)).to.be.revertedWithCustomError(mockGuardianBarz, "GuardianFacet__DuplicateGuardianRemoval") + }) + it("Should remove guardian from wallet", async () => { + await setupGuardianBarz() + const addGuardianCall = guardianFacet.interface.encodeFunctionData("addGuardian", [guardian1.address]) + const addGuardianCallData = executeCallData(barz.address, 0, addGuardianCall) + await callFromEntryPointOnK1(entryPoint, barz.address, owner, addGuardianCallData) + + await increaseBlockTime(guardianSecurityPeriod) + await expect(guardianBarz.confirmGuardianAddition(guardian1.address)).to.emit(guardianBarz, "GuardianAdded") + expect(await guardianBarz.isGuardian(guardian1.address)).to.be.true + + const removeGuardianCall = guardianFacet.interface.encodeFunctionData("removeGuardian", [guardian1.address]) + const removeGuardianCallData = executeCallData(barz.address, 0, removeGuardianCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, removeGuardianCallData)).to.emit(guardianBarz, "GuardianRemovalRequested") + + expect(await guardianBarz.isGuardian(guardian1.address)).to.be.true + }) + it("Should remove guardian when multiple guardians exists", async () => { + // Add guardian A, B => Remove guardian A + await setupGuardianBarz() + const addGuardianCall = guardianFacet.interface.encodeFunctionData("addGuardians", [[guardian1.address, guardian2.address]]) + const addGuardianCallData = executeCallData(barz.address, 0, addGuardianCall) + await callFromEntryPointOnK1(entryPoint, barz.address, owner, addGuardianCallData) + + await increaseBlockTime(guardianSecurityPeriod) + await expect(guardianBarz.confirmGuardianAdditions([guardian1.address, guardian2.address])).to.emit(guardianBarz, "GuardianAdded") + expect(await guardianBarz.isGuardian(guardian1.address)).to.be.true + expect(await guardianBarz.isGuardian(guardian2.address)).to.be.true + + const removeGuardianCall = guardianFacet.interface.encodeFunctionData("removeGuardian", [guardian1.address]) + const removeGuardianCallData = executeCallData(barz.address, 0, removeGuardianCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, removeGuardianCallData)).to.emit(guardianBarz, "GuardianRemovalRequested") + }) + }) + describe("# removeGuardians", () => { + beforeEach(async () => { + const addGuardianCall = guardianFacet.interface.encodeFunctionData("addGuardians", [[guardian1.address, guardian2.address]]) + await expect(mockAccountBarz.connect(mockEntryPoint).execute(mockAccountBarz.address, 0, addGuardianCall)).to.emit(mockGuardianBarz, "GuardianAdditionRequested") + await increaseBlockTime(guardianSecurityPeriod) + await expect(mockGuardianBarz.confirmGuardianAdditions([guardian1.address, guardian2.address])).to.emit(mockGuardianBarz, "GuardianAdded") + }) + it("Should revert if not owner", async () => { + await expect(mockGuardianBarz.removeGuardians([guardian1.address, guardian2.address])).to.be.revertedWith("LibDiamond: Caller not self") + }) + it("Should remove multiple guardians", async () => { + const removeGuardiansCall = guardianFacet.interface.encodeFunctionData("removeGuardians", [[guardian1.address, guardian2.address]]) + await expect(mockAccountBarz.connect(mockEntryPoint).execute(mockAccountBarz.address, 0, removeGuardiansCall)).to.emit(mockGuardianBarz, "GuardianRemovalRequested") + }) + }) + describe("# confirmGuardianRemoval", () => { + beforeEach(async () => { + const addGuardianCall = guardianFacet.interface.encodeFunctionData("addGuardians", [[guardian1.address, guardian2.address]]) + await expect(mockAccountBarz.connect(mockEntryPoint).execute(mockAccountBarz.address, 0, addGuardianCall)).to.emit(mockGuardianBarz, "GuardianAdditionRequested") + await increaseBlockTime(guardianSecurityPeriod) + await expect(mockGuardianBarz.confirmGuardianAdditions([guardian1.address, guardian2.address])).to.emit(mockGuardianBarz, "GuardianAdded") + }) + it("Should revert if unknown addition", async () => { + await expect(mockGuardianBarz.confirmGuardianRemoval(guardian1.address)).to.be.revertedWithCustomError(mockGuardianBarz, "GuardianFacet__UnknownPendingRemoval") + }) + it("Should revert if pending period is not over", async () => { + const removeGuardianCall = guardianFacet.interface.encodeFunctionData("removeGuardian", [guardian1.address]) + await expect(mockAccountBarz.connect(mockEntryPoint).execute(mockAccountBarz.address, 0, removeGuardianCall)).to.emit(mockGuardianBarz, "GuardianRemovalRequested") + + await expect(mockGuardianBarz.confirmGuardianRemoval(guardian1.address)).to.be.revertedWithCustomError(mockGuardianBarz, "GuardianFacet__PendingRemovalNotOver") + }) + it("Should revert if security window expired", async () => { + const removeGuardianCall = guardianFacet.interface.encodeFunctionData("removeGuardian", [guardian1.address]) + await expect(mockAccountBarz.connect(mockEntryPoint).execute(mockAccountBarz.address, 0, removeGuardianCall)).to.emit(mockGuardianBarz, "GuardianRemovalRequested") + + await increaseBlockTime(guardianSecurityPeriod + guardianSecurityWindow) + + await expect(mockGuardianBarz.confirmGuardianRemoval(guardian1.address)).to.be.revertedWithCustomError(mockGuardianBarz, "GuardianFacet__PendingAdditionExpired") + }) + it("Should confirm guardian removal", async () => { + await setupGuardianBarz() + const addGuardianCall = guardianFacet.interface.encodeFunctionData("addGuardian", [guardian1.address]) + const addGuardianCallData = executeCallData(barz.address, 0, addGuardianCall) + await callFromEntryPointOnK1(entryPoint, barz.address, owner, addGuardianCallData) + + await increaseBlockTime(guardianSecurityPeriod) + await expect(guardianBarz.confirmGuardianAddition(guardian1.address)).to.emit(guardianBarz, "GuardianAdded") + expect(await guardianBarz.isGuardian(guardian1.address)).to.be.true + + const removeGuardianCall = guardianFacet.interface.encodeFunctionData("removeGuardian", [guardian1.address]) + const removeGuardianCallData = executeCallData(barz.address, 0, removeGuardianCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, removeGuardianCallData)).to.emit(guardianBarz, "GuardianRemovalRequested") + + await increaseBlockTime(guardianSecurityPeriod) + await expect(guardianBarz.confirmGuardianRemoval(guardian1.address)).to.emit(guardianBarz, "GuardianRemoved") + + expect(await guardianBarz.isGuardian(guardian1.address)).to.be.false + }) + }) + describe("# cancelGuardianAddition", () => { + beforeEach(async () => { + const addGuardianCall = guardianFacet.interface.encodeFunctionData("addGuardians", [[guardian1.address, guardian2.address]]) + await expect(mockAccountBarz.connect(mockEntryPoint).execute(mockAccountBarz.address, 0, addGuardianCall)).to.emit(mockGuardianBarz, "GuardianAdditionRequested") + }) + it("Should revert if not owner", async () => { + await expect(mockGuardianBarz.cancelGuardianAddition(guardian1.address)).to.be.revertedWith("LibDiamond: Caller not self") + }) + it("Should revert if unknown addition", async () => { + const cancelGuardianAdditionCall = guardianFacet.interface.encodeFunctionData("cancelGuardianAddition", [nonGuardian.address]) + await expect(mockAccountBarz.connect(mockEntryPoint).execute(mockAccountBarz.address, 0, cancelGuardianAdditionCall)).to.be.revertedWithCustomError(mockGuardianBarz, "GuardianFacet__UnknownPendingAddition") + }) + it("Should cancel guardian addition", async () => { + const cancelGuardianAdditionCall = guardianFacet.interface.encodeFunctionData("cancelGuardianAddition", [guardian1.address]) + await expect(mockAccountBarz.connect(mockEntryPoint).execute(mockAccountBarz.address, 0, cancelGuardianAdditionCall)).to.emit(mockGuardianBarz, "GuardianAdditionCancelled") + }) + }) + describe("# cancelGuardianRemoval", () => { + beforeEach(async () => { + const addGuardianCall = guardianFacet.interface.encodeFunctionData("addGuardians", [[guardian1.address, guardian2.address]]) + await expect(mockAccountBarz.connect(mockEntryPoint).execute(mockAccountBarz.address, 0, addGuardianCall)).to.emit(mockGuardianBarz, "GuardianAdditionRequested") + await increaseBlockTime(guardianSecurityPeriod) + await expect(mockGuardianBarz.confirmGuardianAdditions([guardian1.address, guardian2.address])).to.emit(mockGuardianBarz, "GuardianAdded") + + const removeGuardianCall = guardianFacet.interface.encodeFunctionData("removeGuardians", [[guardian1.address, guardian2.address]]) + await expect(mockAccountBarz.connect(mockEntryPoint).execute(mockAccountBarz.address, 0, removeGuardianCall)).to.emit(mockGuardianBarz, "GuardianRemovalRequested") + }) + it("Should revert if not owner", async () => { + await expect(mockGuardianBarz.cancelGuardianRemoval(guardian1.address)).to.be.revertedWith("LibDiamond: Caller not self") + }) + it("Should revert if unknown removal", async () => { + const cancelGuardianRemovalCall = guardianFacet.interface.encodeFunctionData("cancelGuardianRemoval", [nonGuardian.address]) + await expect(mockAccountBarz.connect(mockEntryPoint).execute(mockAccountBarz.address, 0, cancelGuardianRemovalCall)).to.be.revertedWithCustomError(mockGuardianBarz, "GuardianFacet__UnknownPendingRemoval") + }) + it("Should cancel guardian removal", async () => { + const cancelGuardianRemovalCall = guardianFacet.interface.encodeFunctionData("cancelGuardianRemoval", [guardian1.address]) + await expect(mockAccountBarz.connect(mockEntryPoint).execute(mockAccountBarz.address, 0, cancelGuardianRemovalCall)).to.emit(mockGuardianBarz, "GuardianRemovalCancelled") + }) + }) + describe("# confirmGuardianRemovals", () => { + it("Should confirm guardian removals", async () => { + // Add guardians + const addGuardianCall = guardianFacet.interface.encodeFunctionData("addGuardians", [[guardian1.address, guardian2.address]]) + await expect(mockAccountBarz.connect(mockEntryPoint).execute(mockAccountBarz.address, 0, addGuardianCall)).to.emit(mockGuardianBarz, "GuardianAdditionRequested") + + await increaseBlockTime(guardianSecurityPeriod) + await expect(mockGuardianBarz.confirmGuardianAdditions([guardian1.address, guardian2.address])).to.emit(mockGuardianBarz, "GuardianAdded") + + // Request guardian removals + const removeGuardiansCall = guardianFacet.interface.encodeFunctionData("removeGuardians", [[guardian1.address, guardian2.address]]) + await expect(mockAccountBarz.connect(mockEntryPoint).execute(mockAccountBarz.address, 0, removeGuardiansCall)).to.emit(mockGuardianBarz, "GuardianRemovalRequested") + + await increaseBlockTime(guardianSecurityPeriod) + + // Confirm guardian removals + await expect(mockGuardianBarz.confirmGuardianRemovals([guardian1.address, guardian2.address])).to.emit(mockGuardianBarz, "GuardianRemoved") + }) + }) + describe("# getAdditionSecurityPeriod", () => { + it("Should return valid addition security period", async () => { + await setupGuardianBarz() + expect(await guardianBarz.getAdditionSecurityPeriod()).to.equal(guardianSecurityPeriod) + }) + }) + describe("# getRemovalSecurityPeriod", () => { + it("Should return valid removal security period", async () => { + await setupGuardianBarz() + expect(await guardianBarz.getRemovalSecurityPeriod()).to.equal(guardianSecurityPeriod) + }) + }) + describe("# getSecurityWindow", () => { + it("Should return valid removal security period", async () => { + await setupGuardianBarz() + expect(await guardianBarz.getSecurityWindow()).to.equal(guardianSecurityWindow) + }) + }) + describe("# isGuardianFacetRemovable", () => { + it("Should return false when guardians exists", async () => { + await setupGuardianBarz() + + const addGuardianCall = guardianFacet.interface.encodeFunctionData("addGuardian", [guardian1.address]) + const addGuardianCallData = executeCallData(barz.address, 0, addGuardianCall) + await callFromEntryPointOnK1(entryPoint, barz.address, owner, addGuardianCallData) + + await increaseBlockTime(guardianSecurityPeriod) + await expect(guardianBarz.confirmGuardianAddition(guardian1.address)).to.emit(guardianBarz, "GuardianAdded") + expect(await guardianBarz.isGuardian(guardian1.address)).to.be.true + + expect(await guardianBarz.isGuardianFacetRemovable()).to.be.false + }) + it("Should return true when no guardians exists", async () => { + await setupGuardianBarz() + + expect(await guardianBarz.isGuardianFacetRemovable()).to.be.true + }) + }) + describe("# majorityOfGuardians", () => { + it("Should return 0 if guardian doesn't exists", async () => { + expect(await mockGuardianBarz.majorityOfGuardians()).to.equal(0) + }) + it("Should return majority of guardians", async () => { + const addGuardianCall = guardianFacet.interface.encodeFunctionData("addGuardians", [[guardian1.address, guardian2.address]]) + await expect(mockAccountBarz.connect(mockEntryPoint).execute(mockAccountBarz.address, 0, addGuardianCall)).to.emit(mockGuardianBarz, "GuardianAdditionRequested") + + await increaseBlockTime(guardianSecurityPeriod) + await expect(mockGuardianBarz.confirmGuardianAdditions([guardian1.address, guardian2.address])).to.emit(mockGuardianBarz, "GuardianAdded") + expect(await mockGuardianBarz.majorityOfGuardians()).to.equal(2) + }) + }) +}) \ No newline at end of file diff --git a/test/LockFacet.test.ts b/test/LockFacet.test.ts new file mode 100644 index 0000000..0242929 --- /dev/null +++ b/test/LockFacet.test.ts @@ -0,0 +1,357 @@ +import { ethers } from 'hardhat' +import { Wallet } from 'ethers' + +import { AccountFacet, DiamondCutFacet, Barz, Secp256k1VerificationFacet, SecurityManager, FacetRegistry, LockFacet, GuardianFacet, DiamondLoupeFacet, TokenReceiverFacet, DefaultFallbackHandler, AccountRecoveryFacet } from '../typechain-types' +import { getChainId, diamondCut, increaseBlockTime, guardianSecurityPeriod, lockPeriod, getEthSignMessageHash, getBlockTimestamp, isUserOperationSuccessful } from './utils/helpers' +import { addFacetSelectorsViaEntryPointOnK1, getAccountBarz, getFacetBarz, setupDefaultSecuritManager } from './utils/setup' +import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers' +import { AddressZero, createAccountOwner, fund, callGasLimit, verificationGasLimit, maxFeePerGas, AddressOne, getMessageHash } from './utils/testutils' + +const { + FacetCutAction, + getSelectors +} = require('./utils/diamond.js') + +import { expect } from "chai" +import { diamondCutFacetFixture } from './fixtures/DiamondCutFacetFixture' +import { accountFacetFixture } from './fixtures/AccountFacetFixture' +import { secp256k1VerificationFacetFixture } from './fixtures/Secp256k1VerificationFacetFixture' +import { barzFixture } from './fixtures/BarzFixture' +import { facetRegistryFixture } from './fixtures/FacetRegistryFixture' +import { lockFacetFixture } from './fixtures/LockFacetFixture' +import { guardianFacetFixture } from './fixtures/GuardianFacetFixture' +import { callFromEntryPointOnK1, executeCallData, fillUserOpDefaults, getUserOpHash, signUserOpK1Curve } from './utils/UserOp' +import { EntryPoint } from '../typechain-types/core' +import { entryPointFixture } from './fixtures/EntryPointFixture' +import { diamondLoupeFacetFixture } from './fixtures/DiamondLoupeFacetFixture' +import { keccak256 } from '@ethersproject/keccak256' +import { arrayify } from 'ethers/lib/utils' +import { tokenReceiverFacetFixture } from './fixtures/TokenReceiverFacetFixture' +import { defaultFallbackHandlerFixture } from './fixtures/DefaultFallbackHandlerFixture' +import { accountRecoveryFacetFixture } from './fixtures/AccountRecoveryFacetFixture' +import { Account, ecsign, toRpcSig } from 'ethereumjs-util' + +describe('Lock Facet', () => { + let diamondCutFacet: DiamondCutFacet + let diamondCutBarz: DiamondCutFacet + let securityManager: SecurityManager + let defaultFallbackHandler: DefaultFallbackHandler + let facetRegistry: FacetRegistry + let accountFacet: AccountFacet + let accountBarz: AccountFacet + let tokenReceiverFacet: TokenReceiverFacet + let k1Facet: Secp256k1VerificationFacet + let k1Barz: Secp256k1VerificationFacet + let diamondLoupeFacet: DiamondLoupeFacet + let guardianFacet: GuardianFacet + let accountRecoveryFacet: AccountRecoveryFacet + let accountRecoveryBarz: AccountRecoveryFacet + let guardianBarz: GuardianFacet + let lockFacet: LockFacet + let lockBarz: LockFacet + let entryPoint: EntryPoint + let guardian: SignerWithAddress + let securityManagerOwner: SignerWithAddress + let facetRegistryOwner: SignerWithAddress + let owner: Wallet + let recoveryAddress: Wallet + let barz: Barz + let chainId: number + let guardianFacetSelectors: any + let accountRecoverySelectors: any + let testExecData: any + + before(async () => { + [guardian, securityManagerOwner, facetRegistryOwner] = await ethers.getSigners() + owner = createAccountOwner() + recoveryAddress = createAccountOwner() + await fund(owner.address) + + testExecData = executeCallData(AddressOne, 10, "0x00") + + chainId = await getChainId() + + securityManager = await setupDefaultSecuritManager(securityManagerOwner) + facetRegistry = await facetRegistryFixture(facetRegistryOwner.address) + accountFacet = await accountFacetFixture() + k1Facet = await secp256k1VerificationFacetFixture() + diamondCutFacet = await diamondCutFacetFixture(securityManager) + guardianFacet = await guardianFacetFixture(securityManager) + accountRecoveryFacet = await accountRecoveryFacetFixture(securityManager) + lockFacet = await lockFacetFixture(securityManager) + entryPoint = await entryPointFixture() + diamondLoupeFacet = await diamondLoupeFacetFixture() + tokenReceiverFacet = await tokenReceiverFacetFixture() + defaultFallbackHandler = await defaultFallbackHandlerFixture(diamondCutFacet, accountFacet, tokenReceiverFacet, diamondLoupeFacet) + + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(k1Facet.address, getSelectors(k1Facet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(accountFacet.address, getSelectors(accountFacet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(lockFacet.address, getSelectors(lockFacet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(guardianFacet.address, getSelectors(guardianFacet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(diamondCutFacet.address, getSelectors(diamondCutFacet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(diamondLoupeFacet.address, getSelectors(diamondLoupeFacet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(accountRecoveryFacet.address, getSelectors(accountRecoveryFacet)) + guardianFacetSelectors = getSelectors(guardianFacet).filter((item: string) => item !== diamondCutFacet.interface.getSighash('securityManager')) + accountRecoverySelectors = getSelectors(accountRecoveryFacet).filter((item: string) => item !== diamondCutFacet.interface.getSighash('securityManager')) + }) + beforeEach(async () => { + barz = await barzFixture(accountFacet, k1Facet, entryPoint, facetRegistry, defaultFallbackHandler, owner.publicKey) + diamondCutBarz = await getFacetBarz('DiamondCutFacet', barz) + accountBarz = await getAccountBarz(barz) + lockBarz = await getFacetBarz('LockFacet', barz) + guardianBarz = await getFacetBarz('GuardianFacet', barz) + k1Barz = await getFacetBarz('Secp256k1VerificationFacet', barz) + accountRecoveryBarz = await getFacetBarz('AccountRecoveryFacet', barz) + + await entryPoint.depositTo(barz.address, { + value: ethers.utils.parseEther('0.5'), + }) + await fund(barz.address) + }) + + const addGuardian = async (newGuardian: SignerWithAddress) => { + const addGuardianCall = guardianFacet.interface.encodeFunctionData("addGuardian", [newGuardian.address]) + const addGuardianCallData = executeCallData(barz.address, 0, addGuardianCall) + await callFromEntryPointOnK1(entryPoint, barz.address, owner, addGuardianCallData) + + await increaseBlockTime(guardianSecurityPeriod) + await expect(guardianBarz.confirmGuardianAddition(newGuardian.address)).to.emit(guardianBarz, "GuardianAdded") + expect(await guardianBarz.isGuardian(newGuardian.address)).to.be.true + } + + const setupContracts = async () => { + await expect(addFacetSelectorsViaEntryPointOnK1(barz, owner, guardianFacet, guardianFacetSelectors, entryPoint)).to.emit(diamondCutBarz, "DiamondCut") + await expect(addFacetSelectorsViaEntryPointOnK1(barz, owner, lockFacet, lockFacet, entryPoint)).to.emit(diamondCutBarz, "DiamondCut") + await expect(addFacetSelectorsViaEntryPointOnK1(barz, owner, accountRecoveryFacet, accountRecoverySelectors, entryPoint)).to.emit(diamondCutBarz, "DiamondCut") + } + + it('Should be able to add Lock Facet to Barz', async () => { + await setupContracts() + }) + describe('# lock', () => { + it('Should revert lock if not guardian or owner', async () => { + await setupContracts() + await expect(lockBarz.lock()).to.be.revertedWithCustomError(lockBarz, 'CallerNotGuardianOrOwner') + }) + it('Should lock account with guardian', async () => { + await setupContracts() + await addGuardian(guardian) + await expect(lockBarz.connect(guardian).lock()).to.emit(lockBarz, "Locked") + }) + it('Should lock account with owner', async () => { + await setupContracts() + await addGuardian(guardian) + + const lockCall = lockFacet.interface.encodeFunctionData("lock") + const lockCallData = executeCallData(barz.address, 0, lockCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, lockCallData)).to.emit(lockBarz, "Locked") + }) + it("Should increment nonce", async () => { + await setupContracts() + await addGuardian(guardian) + await expect(lockBarz.connect(guardian).lock()).to.emit(lockBarz, "Locked") + expect(await lockBarz.lockNonce()).to.equal(1) + }) + }) + describe('# unlock', () => { + it('Should revert if not locked by lock function', async () => { + await setupContracts() + await addGuardian(guardian) + const recoveryNonce = 0 + const encodedData = ethers.utils.defaultAbiCoder.encode(['bytes', 'string', 'address', 'uint256', 'uint128'], [recoveryAddress.publicKey, 'ExecuteRecovery', accountRecoveryBarz.address, chainId, recoveryNonce]) + const hash = keccak256(encodedData) + const signature = await guardian.signMessage(arrayify(hash)) + + await expect(accountRecoveryBarz.executeRecovery(recoveryAddress.publicKey, [guardian.address], [signature])).to.emit(accountRecoveryBarz, "RecoveryExecuted") + + const unlockEncodedData = ethers.utils.defaultAbiCoder.encode(['string', 'address', 'uint256', 'uint128'], ["Unlock", lockBarz.address, chainId, "0"]) + const unlockHash = keccak256(unlockEncodedData) + const guardianSignature = await guardian.signMessage(arrayify(unlockHash)) + + await expect(lockBarz.unlock(guardian.address, guardianSignature)).to.be.revertedWithCustomError(lockBarz, 'LockFacet__CannotUnlock') + }) + it('Should revert unlock if not guardian or owner', async () => { + await setupContracts() + await addGuardian(guardian) + + const encodedData = ethers.utils.defaultAbiCoder.encode(['string', 'address', 'uint256', 'uint128'], ["Unlock", lockBarz.address, chainId, "1"]) + const hash = keccak256(encodedData) + const guardianSignature = await guardian.signMessage(arrayify(hash)) + await expect(lockBarz.connect(guardian).lock()).to.emit(lockBarz, "Locked") + + // facetRegistryOwner is not guardian or owner + await expect(lockBarz.unlock(facetRegistryOwner.address, guardianSignature)).to.be.revertedWithCustomError(lockBarz, 'LockFacet__InvalidApprover') + }) + it('Should unlock account', async () => { + await setupContracts() + await addGuardian(guardian) + const encodedData = ethers.utils.defaultAbiCoder.encode(['string', 'address', 'uint256', 'uint128'], ["Unlock", lockBarz.address, chainId, "1"]) + const hash = keccak256(encodedData) + const guardianSignature = await guardian.signMessage(arrayify(hash)) + + await expect(lockBarz.connect(guardian).lock()).to.emit(lockBarz, "Locked") + await expect(lockBarz.unlock(guardian.address, guardianSignature)).to.emit(lockBarz, "Unlocked") + }) + it('Should unlock account with owner signature', async () => { + await setupContracts() + await addGuardian(guardian) + const encodedData = ethers.utils.defaultAbiCoder.encode(['string', 'address', 'uint256', 'uint128'], ["Unlock", lockBarz.address, chainId, "1"]) + const hash = keccak256(encodedData) + const prefixedHash = getEthSignMessageHash(hash) + + const finalHash = await getMessageHash(prefixedHash, await getChainId(), lockBarz.address) + const sig = ecsign(Buffer.from(ethers.utils.arrayify(finalHash)), Buffer.from(ethers.utils.arrayify(owner.privateKey))) + + const ownerUnlockSignature = toRpcSig(sig.v, sig.r, sig.s) + + await expect(lockBarz.connect(guardian).lock()).to.emit(lockBarz, "Locked") + await expect(lockBarz.unlock(lockBarz.address, ownerUnlockSignature)).to.emit(lockBarz, "Unlocked") + }) + it('Should unlock account with owner signature -> owner locked', async () => { + await setupContracts() + await addGuardian(guardian) + const encodedData = ethers.utils.defaultAbiCoder.encode(['string', 'address', 'uint256', 'uint128'], ["Unlock", lockBarz.address, chainId, "1"]) + const hash = keccak256(encodedData) + const prefixedHash = getEthSignMessageHash(hash) + + const finalHash = await getMessageHash(prefixedHash, await getChainId(), lockBarz.address) + const sig = ecsign(Buffer.from(ethers.utils.arrayify(finalHash)), Buffer.from(ethers.utils.arrayify(owner.privateKey))) + + const ownerUnlockSignature = toRpcSig(sig.v, sig.r, sig.s) + + const lockCall = lockBarz.interface.encodeFunctionData("lock") + const callData = executeCallData(lockBarz.address, 0, lockCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, callData)).to.emit(lockBarz, "Locked") + await expect(lockBarz.unlock(lockBarz.address, ownerUnlockSignature)).to.emit(lockBarz, "Unlocked") + }) + it("Should increment nonce", async () => { + await setupContracts() + await addGuardian(guardian) + + const encodedData = ethers.utils.defaultAbiCoder.encode(['string', 'address', 'uint256', 'uint128'], ["Unlock", lockBarz.address, chainId, "1"]) + const hash = keccak256(encodedData) + const guardianSignature = await guardian.signMessage(arrayify(hash)) + expect(await lockBarz.lockNonce()).to.equal(0) + + await expect(lockBarz.connect(guardian).lock()).to.emit(lockBarz, "Locked") + expect(await lockBarz.lockNonce()).to.equal(1) + + await expect(lockBarz.unlock(guardian.address, guardianSignature)).to.emit(lockBarz, "Unlocked") + expect(await lockBarz.lockNonce()).to.equal(2) + }) + it("Should revert if invalid signature", async () => { + await setupContracts() + await addGuardian(guardian) + const encodedData = ethers.utils.defaultAbiCoder.encode(['string', 'address', 'uint256', 'uint128'], ["Unlock", lockBarz.address, chainId, "1"]) + // Creating an invalid hash + const hash = keccak256(encodedData + "0000") + const guardianSignature = await guardian.signMessage(arrayify(hash)) + expect(await lockBarz.lockNonce()).to.equal(0) + + await expect(lockBarz.connect(guardian).lock()).to.emit(lockBarz, "Locked") + expect(await lockBarz.lockNonce()).to.equal(1) + + await expect(lockBarz.connect(guardian).unlock(guardian.address, guardianSignature)).to.be.revertedWithCustomError(lockBarz, "LockFacet__InvalidSignature") + }) + it("Should revert if invalid nonce", async () => { + await setupContracts() + await addGuardian(guardian) + const invalidNonce = 100; + const encodedData = ethers.utils.defaultAbiCoder.encode(['string', 'address', 'uint256', 'uint128'], ["Unlock", lockBarz.address, chainId, invalidNonce]) + const hash = keccak256(encodedData) + const guardianSignature = await guardian.signMessage(arrayify(hash)) + expect(await lockBarz.lockNonce()).to.equal(0) + + await expect(lockBarz.connect(guardian).lock()).to.emit(lockBarz, "Locked") + expect(await lockBarz.lockNonce()).to.equal(1) + + await expect(lockBarz.connect(guardian).unlock(guardian.address, guardianSignature)).to.be.revertedWithCustomError(lockBarz, "LockFacet__InvalidSignature") + }) + }) + describe('# getUnlockHash', async () => { + it('Should return valid hash', async () => { + await setupContracts() + const encodedData = ethers.utils.defaultAbiCoder.encode(['string', 'address', 'uint256', 'uint128'], ["Unlock", lockBarz.address, chainId, "0"]) + const hash = keccak256(encodedData) + const signEthMsgHash = getEthSignMessageHash(hash) + + expect(await lockBarz.getUnlockHash()).to.equal(signEthMsgHash) + }) + }) + describe('# getLockPeriod', () => { + it('Should return valid lock period', async () => { + await setupContracts() + expect(await lockBarz.getLockPeriod()).to.equal(lockPeriod) + }) + }) + describe('# isLocked', async () => { + it('Should return true when locked', async () => { + await setupContracts() + await addGuardian(guardian) + await expect(lockBarz.connect(guardian).lock()).to.emit(lockBarz, "Locked") + expect(await lockBarz.isLocked()).to.be.true + }) + it('Should return false when unlocked', async () => { + await setupContracts() + await addGuardian(guardian) + expect(await lockBarz.isLocked()).to.be.false + + await expect(lockBarz.connect(guardian).lock()).to.emit(lockBarz, "Locked") + + const encodedData = ethers.utils.defaultAbiCoder.encode(['string', 'address', 'uint256', 'uint128'], ["Unlock", lockBarz.address, chainId, "1"]) + const hash = keccak256(encodedData) + const guardianSignature = await guardian.signMessage(arrayify(hash)) + await expect(lockBarz.connect(guardian).unlock(guardian.address, guardianSignature)).to.emit(lockBarz, "Unlocked") + expect(await lockBarz.isLocked()).to.be.false + }) + }) + describe('# getPendingLock', async () => { + it('Should return valid lock information', async () => { + await setupContracts() + await addGuardian(guardian) + await expect(lockBarz.connect(guardian).lock()).to.emit(lockBarz, "Locked") + const blockTimeStamp = await getBlockTimestamp() + expect(await lockBarz.getPendingLock()).to.deep.equal([blockTimeStamp + lockPeriod, lockBarz.interface.getSighash('lock')]) + }) + it('Should return empty value if wallet is not locked', async () => { + await setupContracts() + await addGuardian(guardian) + + expect(await lockBarz.getPendingLock()).to.deep.equal([0, '0x00000000']) + }) + }) + + it('Should revert diamond cut when locked', async () => { + await setupContracts() + await addGuardian(guardian) + + await expect(lockBarz.connect(guardian).lock()).to.emit(lockBarz, "Locked") + + const accountCut = diamondCut(accountFacet.address, FacetCutAction.Add, accountFacet) + const cutCall = diamondCutBarz.interface.encodeFunctionData("diamondCut", [accountCut, AddressZero, "0x00"]) + const callData = executeCallData(diamondCutBarz.address, 0, cutCall) + expect(await isUserOperationSuccessful(await callFromEntryPointOnK1(entryPoint, barz.address, owner, callData))).to.be.false + }) + + it('Should fail validation when locked', async () => { + await setupContracts() + await addGuardian(guardian) + await expect(lockBarz.connect(guardian).lock()).to.emit(lockBarz, "Locked") + + const userOp = signUserOpK1Curve(fillUserOpDefaults({ + sender: barz.address, + callGasLimit, + nonce: await accountBarz.getNonce(), + verificationGasLimit, + maxFeePerGas, + callData: testExecData + }), owner, entryPoint.address, chainId) + const opHash = getUserOpHash(userOp, entryPoint.address, chainId) + + const isSignatureValid = await k1Barz.validateOwnerSignature(userOp, opHash) + // 0 equals success, 1 equals SIG_VALIDATION_FAILED + expect(isSignatureValid).to.equal(0) + + expect(await isUserOperationSuccessful(await entryPoint.handleOps([userOp], barz.address))).to.be.false + }) +}) \ No newline at end of file diff --git a/test/MultiSigFacet.test.ts b/test/MultiSigFacet.test.ts new file mode 100644 index 0000000..207d934 --- /dev/null +++ b/test/MultiSigFacet.test.ts @@ -0,0 +1,1120 @@ +import { ethers } from 'hardhat' +import { Wallet } from 'ethers' + +import { AccountFacet, DiamondCutFacet, Barz, Secp256k1VerificationFacet, SecurityManager, FacetRegistry, DiamondLoupeFacet, TokenReceiverFacet, DefaultFallbackHandler, MultiSigFacet, Secp256r1VerificationFacet } from '../typechain-types' +import { getChainId, guardianSecurityPeriod, minGuardianSecurityPeriod, maxGuardianSecurityPeriod, guardianSecurityWindow, minGuardianSecurityWindow, maxGuardianSecurityWindow, recoveryPeriod, minRecoveryPeriod, maxRecoveryPeriod, lockPeriod, minLockPeriod, maxLockPeriod, approvalValidationPeriod, minApprovalValidationPeriod, maxApprovalValidationPeriod, minMigrationPeriod, maxMigrationPeriod, migrationPeriod, diamondCut, generateKeyPair } from './utils/helpers' +import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers' +import { AddressOne, AddressZero, addPrefix, createAccountOwner, fund, getMessageHash, removePrefix, sortSignatures } from './utils/testutils' + +const { + FacetCutAction, + getSelectors +} = require('./utils/diamond.js') + +import { expect } from "chai" +import { diamondCutFacetFixture } from './fixtures/DiamondCutFacetFixture' +import { accountFacetFixture } from './fixtures/AccountFacetFixture' +import { secp256k1VerificationFacetFixture } from './fixtures/Secp256k1VerificationFacetFixture' +import { barzFixture } from './fixtures/BarzFixture' +import { getFacetBarz, setupSecurityManager } from './utils/setup' +import { facetRegistryFixture } from './fixtures/FacetRegistryFixture' +import { EntryPoint } from '../typechain-types/core' +import { executeCallData, fillUserOpDefaults, getUserOpHash, signMsgOnR1Curve, signUserOpK1Curve } from './utils/UserOp' +import { entryPointFixture } from './fixtures/EntryPointFixture' +import { diamondLoupeFacetFixture } from './fixtures/DiamondLoupeFacetFixture' +import { tokenReceiverFacetFixture } from './fixtures/TokenReceiverFacetFixture' +import { defaultFallbackHandlerFixture } from './fixtures/DefaultFallbackHandlerFixture' +import { multiSigFacetFixture } from './fixtures/MultiSigFacetFixture' +import { secp256r1VerificationFacetFixture } from './fixtures/Secp256r1VerificationFacetFixture' +import { testTokenFixture } from './fixtures/TestTokenFixture' +import { ecsign, keccak256, toRpcSig } from 'ethereumjs-util' +import { arrayify } from 'ethers/lib/utils' + +describe('Multi-Sig Facet', () => { + let diamondCutFacet: DiamondCutFacet + let securityManager: SecurityManager + let facetRegistry: FacetRegistry + let defaultFallbackHandler: DefaultFallbackHandler + let accountFacet: AccountFacet + let k1Facet: Secp256k1VerificationFacet + let r1Facet: Secp256r1VerificationFacet + let diamondLoupeFacet: DiamondLoupeFacet + let tokenReceiverFacet: TokenReceiverFacet + let multiSigFacet: MultiSigFacet + let entryPoint: EntryPoint + let owner1: SignerWithAddress + let owner2: SignerWithAddress + let mockEntryPoint: SignerWithAddress + let user1: SignerWithAddress + let securityManagerOwner: SignerWithAddress + let facetRegistryOwner: SignerWithAddress + let owner: Wallet + let subOwner: Wallet + let ownerSeed = 0 + before(async () => { + [owner1, owner2, securityManagerOwner, mockEntryPoint, facetRegistryOwner, user1] = await ethers.getSigners() + owner = createAccountOwner(ownerSeed++) + subOwner = createAccountOwner(ownerSeed++) + await fund(owner.address) + + securityManager = await setupSecurityManager(securityManagerOwner, minGuardianSecurityPeriod, maxGuardianSecurityPeriod, guardianSecurityPeriod, + minGuardianSecurityWindow, maxGuardianSecurityWindow, guardianSecurityWindow, + minRecoveryPeriod, maxRecoveryPeriod, recoveryPeriod, + minLockPeriod, maxLockPeriod, lockPeriod, + minApprovalValidationPeriod, maxApprovalValidationPeriod, approvalValidationPeriod, minMigrationPeriod, maxMigrationPeriod, migrationPeriod) + facetRegistry = await facetRegistryFixture(facetRegistryOwner.address) + accountFacet = await accountFacetFixture() + k1Facet = await secp256k1VerificationFacetFixture() + r1Facet = await secp256r1VerificationFacetFixture() + diamondCutFacet = await diamondCutFacetFixture(securityManager) + entryPoint = await entryPointFixture() + diamondLoupeFacet = await diamondLoupeFacetFixture() + tokenReceiverFacet = await tokenReceiverFacetFixture() + multiSigFacet = await multiSigFacetFixture() + defaultFallbackHandler = await defaultFallbackHandlerFixture(diamondCutFacet, accountFacet, tokenReceiverFacet, diamondLoupeFacet) + + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(k1Facet.address, getSelectors(k1Facet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(r1Facet.address, getSelectors(r1Facet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(diamondCutFacet.address, getSelectors(diamondCutFacet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(accountFacet.address, getSelectors(accountFacet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(multiSigFacet.address, getSelectors(multiSigFacet)) + + expect(await facetRegistry.owner()).to.equal(facetRegistryOwner.address) + }) + describe("# initializeSigner", () => { + let threshold: any + let salt: any + let Factory: any + let factory: any + let initData: any + beforeEach(async () => { + threshold = "00000001" + salt = "0" + Factory = await ethers.getContractFactory("BarzFactory") + factory = await Factory.deploy(accountFacet.address, mockEntryPoint.address, facetRegistry.address, defaultFallbackHandler.address) + }) + it("Should revert if signer is already initialized", async () => { + initData = addPrefix(threshold + removePrefix(owner.address)) + await factory.createAccount(multiSigFacet.address, initData, salt) + const barzAddr = await factory.getAddress(multiSigFacet.address, initData, salt) + const barz = await ethers.getContractAt("Barz", barzAddr) + const multiSigBarz = await getFacetBarz("MultiSigFacet", barz) + const accountBarz = await getFacetBarz("AccountFacet", barz) + + await fund(barzAddr, "1") + await entryPoint.depositTo(barz.address, { + value: ethers.utils.parseEther('0.5'), + }) + const cut = diamondCut(multiSigFacet.address, FacetCutAction.Add, [multiSigBarz.interface.getSighash("initializeSigner")]) + const diamondCutBarz = await getFacetBarz('DiamondCutFacet', barz) + const funcCallData = diamondCutBarz.interface.encodeFunctionData("diamondCut", [cut, AddressZero, "0x00"]) + + await accountBarz.connect(mockEntryPoint).execute(accountBarz.address, 0, funcCallData) + + await expect(multiSigBarz.initializeSigner(initData)).to.be.revertedWithCustomError(multiSigBarz, "LibAppStorage__SignerMustBeUninitialized") + }) + it("Should revert if owners address length is less than 1 address(20bytes) + 1 threshold(4 bytes)", async () => { + threshold = "01" // Invalid Threshold -> should be 4 bytes not 1 byte + initData = addPrefix(threshold + removePrefix(owner1.address)) + await expect(factory.createAccount(multiSigFacet.address, initData, salt)).to.be.reverted + }) + it("Should revert if owners address is not valid address length", async () => { + threshold = "00000001" + initData = addPrefix(threshold + owner1.address.replace("0x", "1111")) + await expect(factory.createAccount(multiSigFacet.address, initData, salt)).to.be.reverted + + threshold = "00000001" + initData = addPrefix(threshold + removePrefix(owner1.address).substring(0, owner.address.length - 4)) + await expect(factory.createAccount(multiSigFacet.address, initData, salt)).to.be.reverted + }) + it("Should revert if number of owner address is less than wallet threshold", async () => { + threshold = "00000002" + initData = addPrefix(threshold + removePrefix(owner1.address)) + await expect(factory.createAccount(multiSigFacet.address, initData, salt)).to.be.reverted + }) + it("Should revert if owner address includes zero address", async () => { + threshold = "00000002" + initData = addPrefix(threshold + removePrefix(owner1.address) + removePrefix(AddressZero)) + await expect(factory.createAccount(multiSigFacet.address, initData, salt)).to.be.reverted + }) + it("Should revert if owner address includes SENTINEL_OWNERS", async () => { + threshold = "00000002" + initData = addPrefix(threshold + removePrefix(owner1.address) + removePrefix(AddressOne)) + await expect(factory.createAccount(multiSigFacet.address, initData, salt)).to.be.reverted + }) + it("Should revert if duplicate owner address", async () => { + threshold = "00000002" + initData = addPrefix(threshold + removePrefix(owner1.address) + removePrefix(owner1.address)) + await expect(factory.createAccount(multiSigFacet.address, initData, salt)).to.be.reverted + }) + it("Should revert if duplicate invalid threshold", async () => { + threshold = "00000000" + initData = addPrefix(threshold + removePrefix(owner1.address) + removePrefix(owner2.address)) + await expect(factory.createAccount(multiSigFacet.address, initData, salt)).to.be.reverted + }) + it("Should successfully set owner addresses with threshold", async () => { + const expectedThreshold = 2 + threshold = "00000002" + initData = addPrefix(threshold + removePrefix(owner1.address) + removePrefix(owner2.address)) + await expect(factory.createAccount(multiSigFacet.address, initData, salt)).to.not.be.reverted + const barzAddr = await factory.getAddress(multiSigFacet.address, initData, salt) + const barz = await ethers.getContractAt("Barz", barzAddr) + const multiSigBarz = await getFacetBarz("MultiSigFacet", barz) + const accountBarz = await getFacetBarz("AccountFacet", barz) + + const cut = diamondCut(multiSigFacet.address, FacetCutAction.Add, [multiSigBarz.interface.getSighash("getThreshold"), multiSigBarz.interface.getSighash("getOwners")]) + const diamondCutBarz = await getFacetBarz('DiamondCutFacet', barz) + const funcCallData = diamondCutBarz.interface.encodeFunctionData("diamondCut", [cut, AddressZero, "0x00"]) + + await accountBarz.connect(mockEntryPoint).execute(accountBarz.address, 0, funcCallData) + expect(await multiSigBarz.getOwners()).to.deep.equal([owner1.address, owner2.address]) + expect(await multiSigBarz.getThreshold()).to.equal(expectedThreshold) + }) + }) + describe("# splitSignature", () => { + let chainId: number + const verificationGasLimit = 1000000 + const callGasLimit = 2000000 + const nonce = 1 + const sampleUserOp = fillUserOpDefaults({ + sender: AddressOne, // Just for a sample + nonce, + verificationGasLimit, + callGasLimit + }) + beforeEach(async () => { + chainId = await getChainId() + }) + it("Should revert if signature length is less than minimum length(address + sig_len)", async () => { + const signatures = "0x0000000000000000000123123123" + + await expect(multiSigFacet.splitSignatures(signatures, 0)).to.be.revertedWithCustomError(multiSigFacet, "MultiSigFacet__InsufficientSignerLength") + }) + it("Should revert if invalid signature type", async () => { + const invalidSignatureType1 = "05" + const signatureLength = "00000041" + let signatures = owner1.address + invalidSignatureType1 + signatureLength + removePrefix(signUserOpK1Curve(sampleUserOp, owner, entryPoint.address, chainId).signature.toString()) + + await expect(multiSigFacet.splitSignatures(signatures, 0)).to.be.revertedWithCustomError(multiSigFacet, "MultiSigFacet__InvalidSignatureType") + + let invalidSignatureType2 = "00" + const signature1 = signUserOpK1Curve(sampleUserOp, owner, entryPoint.address, chainId).signature.toString() + const signature2 = signUserOpK1Curve(sampleUserOp, subOwner, entryPoint.address, chainId).signature.toString() + + signatures = owner.address + invalidSignatureType2 + signatureLength + removePrefix(signature1) + removePrefix(subOwner.address) + invalidSignatureType2 + signatureLength + removePrefix(signature2) + await expect(multiSigFacet.splitSignatures(signatures, 0)).to.be.revertedWithCustomError(multiSigFacet, "MultiSigFacet__InvalidSignatureType") + + invalidSignatureType2 = "04" + signatures = owner.address + invalidSignatureType2 + signatureLength + removePrefix(signature1) + removePrefix(subOwner.address) + invalidSignatureType2 + signatureLength + removePrefix(signature2) + await expect(multiSigFacet.splitSignatures(signatures, 0)).to.be.revertedWithCustomError(multiSigFacet, "MultiSigFacet__InvalidSignatureType") + + invalidSignatureType2 = "12" + signatures = owner.address + invalidSignatureType2 + signatureLength + removePrefix(signature1) + removePrefix(subOwner.address) + invalidSignatureType2 + signatureLength + removePrefix(signature2) + await expect(multiSigFacet.splitSignatures(signatures, 0)).to.be.revertedWithCustomError(multiSigFacet, "MultiSigFacet__InvalidSignatureType") + }) + it("Should revert if signature length is not enough for sign_len", async () => { + const signatureType = "01" + const signatureLength = "00000100" + const signatures = owner1.address + signatureType + signatureLength + removePrefix(signUserOpK1Curve(sampleUserOp, owner, entryPoint.address, chainId).signature.toString()) + + await expect(multiSigFacet.splitSignatures(signatures, 0)).to.be.revertedWithCustomError(multiSigFacet, "MultiSigFacet__InvalidSignatureLength") + }) + it("Should return valid owner from signature", async () => { + const signatureType = "01" + const signatureLength = "00000041" + const signatures = owner1.address + signatureType + signatureLength + removePrefix(signUserOpK1Curve(sampleUserOp, owner, entryPoint.address, chainId).signature.toString()) + + const splitSignature = await multiSigFacet.splitSignatures(signatures, 0) + expect(splitSignature.owner_).to.equal(owner1.address) + }) + it("Should return valid signature from signature", async () => { + const signatureType = "01" + const signatureLength = "00000041" + const signature = signUserOpK1Curve(sampleUserOp, owner, entryPoint.address, chainId).signature.toString() + const signatures = owner1.address + signatureType + signatureLength + removePrefix(signature) + + const splitSignature = await multiSigFacet.splitSignatures(signatures, 0) + expect(splitSignature.signature).to.equal(signature) + }) + it("Should return valid signature type from signature", async () => { + const signatureType = "02" + const expectedSignatureType = 2 + const signatureLength = "00000041" + const signature = signUserOpK1Curve(sampleUserOp, owner, entryPoint.address, chainId).signature.toString() + const signatures = owner1.address + signatureType + signatureLength + removePrefix(signature) + + const splitSignature = await multiSigFacet.splitSignatures(signatures, 0) + expect(splitSignature.signatureType).to.equal(expectedSignatureType) + }) + it("Should return valid next offset", async () => { + const signatureType = "02" + const expectedNextOffset = 20 + 1 + 4 + 65 + const signatureLength = "00000041" + const signature1 = signUserOpK1Curve(sampleUserOp, owner, entryPoint.address, chainId).signature.toString() + const signature2 = signUserOpK1Curve(sampleUserOp, subOwner, entryPoint.address, chainId).signature.toString() + + const signatures = owner.address + signatureType + signatureLength + removePrefix(signature1) + removePrefix(subOwner.address) + signatureType + signatureLength + removePrefix(signature2) + + let splitSignature = await multiSigFacet.splitSignatures(signatures, 0) + expect(splitSignature.nextOffset).to.equal(expectedNextOffset) + + splitSignature = await multiSigFacet.splitSignatures(signatures, expectedNextOffset) + expect(splitSignature.nextOffset).to.equal(0) + }) + }) + describe("# checkSignatures", () => { + const VALID_SIG = 0 + const INVALID_SIG = 1 + const verificationGasLimit = 1000000 + const callGasLimit = 2000000 + const nonce = 1 + const sampleUserOp = fillUserOpDefaults({ + sender: AddressOne, // Just for a sample + nonce, + verificationGasLimit, + callGasLimit + }) + let sampleUserOphash: any + let chainId: any + let salt: any + let Factory: any + let factory: any + beforeEach(async () => { + chainId = await getChainId() + sampleUserOphash = await getUserOpHash(sampleUserOp, entryPoint.address, chainId) + salt = "0" + Factory = await ethers.getContractFactory("BarzFactory") + factory = await Factory.deploy(accountFacet.address, mockEntryPoint.address, facetRegistry.address, defaultFallbackHandler.address) + }) + it("Should revert if invalid signature format", async () => { + const signatures = "0x0000000000000000000123123123" + + await expect(multiSigFacet.checkSignatures(sampleUserOphash, signatures, 1)).to.be.revertedWithCustomError(multiSigFacet, "MultiSigFacet__InsufficientSignerLength") + }) + it("Should revert if invalid signature type", async () => { + const signatureType = "05" + const signatureLength = "00000041" + const signatures = owner1.address + signatureType + signatureLength + removePrefix(signUserOpK1Curve(sampleUserOp, owner, entryPoint.address, chainId).signature.toString()) + + await expect(multiSigFacet.checkSignatures(sampleUserOphash, signatures, 1)).to.be.revertedWithCustomError(multiSigFacet, "MultiSigFacet__InvalidSignatureType") + }) + it("Should return invalid_sig if signature validation fail with signature type 1", async () => { + const signatureType = "01" + const signatureLength = "00000041" + const signatures = owner1.address + signatureType + signatureLength + removePrefix(signUserOpK1Curve(sampleUserOp, owner, entryPoint.address, chainId).signature.toString()) + + expect(await multiSigFacet.checkSignatures(sampleUserOphash, signatures, 1)).to.equal(INVALID_SIG) + }) + it("Should return invalid_sig if hash is not approved sign signature type 2", async () => { + const signatureType = "02" + const signatureLength = "00000000" + const signatures = owner1.address + signatureType + signatureLength + + expect(await multiSigFacet.checkSignatures(sampleUserOphash, signatures, 1)).to.equal(INVALID_SIG) + }) + it("Should return invalid_sig if signature validation fail with signature type 3", async () => { + const signatureType = "03" + const signatureLength = "00000000" + const signatures = owner1.address + signatureType + signatureLength + removePrefix(signUserOpK1Curve(sampleUserOp, owner, entryPoint.address, chainId).signature.toString()) + + expect(await multiSigFacet.checkSignatures(sampleUserOphash, signatures, 1)).to.equal(INVALID_SIG) + }) + it("Should return invalid_sig if duplicate owner address", async () => { + const threshold = "00000003" + const initData = addPrefix(threshold + removePrefix(owner.address) + removePrefix(subOwner.address) + removePrefix(owner1.address)) + await expect(factory.createAccount(multiSigFacet.address, initData, salt)).to.not.be.reverted + const barzAddr = await factory.getAddress(multiSigFacet.address, initData, salt) + const barz = await ethers.getContractAt("Barz", barzAddr) + const multiSigBarz = await getFacetBarz("MultiSigFacet", barz) + const accountBarz = await getFacetBarz("AccountFacet", barz) + + const cut = diamondCut(multiSigFacet.address, FacetCutAction.Add, [multiSigBarz.interface.getSighash("checkSignatures"), multiSigBarz.interface.getSighash("approveHash")]) + const diamondCutBarz = await getFacetBarz('DiamondCutFacet', barz) + const funcCallData = diamondCutBarz.interface.encodeFunctionData("diamondCut", [cut, AddressZero, "0x00"]) + + await accountBarz.connect(mockEntryPoint).execute(accountBarz.address, 0, funcCallData) + + const callData = executeCallData(barz.address, 0, funcCallData) + + const signatureType = "03" + const sampleUserOp = fillUserOpDefaults({ + sender: barzAddr, // Just for a sample + callData, + nonce, + verificationGasLimit, + callGasLimit + }) + const userOpHash = await getUserOpHash(sampleUserOp, mockEntryPoint.address, chainId) + await multiSigBarz.connect(owner1).approveHash(userOpHash) + const ownerSig = removePrefix(owner.address) + signatureType + "00000041" + removePrefix(signUserOpK1Curve(sampleUserOp, owner, mockEntryPoint.address, chainId).signature.toString()) + const subOwnerSig = removePrefix(subOwner.address) + signatureType + "00000041" + removePrefix(signUserOpK1Curve(sampleUserOp, subOwner, mockEntryPoint.address, chainId).signature.toString()) + const owner1Sig = removePrefix(owner1.address) + "02" + "00000000" + const ownerAddr = removePrefix(owner.address) + const subOwnerAddr = removePrefix(subOwner.address) + const owner1Addr = removePrefix(owner1.address) + const mapping: Record = { + [ownerAddr]: ownerSig, + [subOwnerAddr]: subOwnerSig, + [owner1Addr]: owner1Sig + }; + // here we put the owner signature twice intentionally to check if the check fails + let signatures = addPrefix(ownerSig) + signatures += removePrefix(sortSignatures(mapping)) + + expect(await multiSigBarz.checkSignatures(userOpHash, signatures, 3)).to.equal(INVALID_SIG) + }) + it("Should return valid_sig if validation is successful", async () => { + const threshold = "00000003" + const initData = addPrefix(threshold + removePrefix(owner.address) + removePrefix(subOwner.address) + removePrefix(owner1.address)) + await expect(factory.createAccount(multiSigFacet.address, initData, salt)).to.not.be.reverted + const barzAddr = await factory.getAddress(multiSigFacet.address, initData, salt) + const barz = await ethers.getContractAt("Barz", barzAddr) + const multiSigBarz = await getFacetBarz("MultiSigFacet", barz) + const accountBarz = await getFacetBarz("AccountFacet", barz) + + const cut = diamondCut(multiSigFacet.address, FacetCutAction.Add, [multiSigBarz.interface.getSighash("checkSignatures"), multiSigBarz.interface.getSighash("getThreshold"), multiSigBarz.interface.getSighash("getOwners"), multiSigBarz.interface.getSighash("approveHash")]) + const diamondCutBarz = await getFacetBarz('DiamondCutFacet', barz) + const funcCallData = diamondCutBarz.interface.encodeFunctionData("diamondCut", [cut, AddressZero, "0x00"]) + + await accountBarz.connect(mockEntryPoint).execute(accountBarz.address, 0, funcCallData) + + const callData = executeCallData(barz.address, 0, funcCallData) + + const signatureType = "03" + const sampleUserOp = fillUserOpDefaults({ + sender: barzAddr, // Just for a sample + callData, + nonce, + verificationGasLimit, + callGasLimit + }) + const userOpHash = await getUserOpHash(sampleUserOp, mockEntryPoint.address, chainId) + await multiSigBarz.connect(owner1).approveHash(userOpHash) + const ownerSig = removePrefix(owner.address) + signatureType + "00000041" + removePrefix(signUserOpK1Curve(sampleUserOp, owner, mockEntryPoint.address, chainId).signature.toString()) + const subOwnerSig = removePrefix(subOwner.address) + "03" + "00000041" + removePrefix(signUserOpK1Curve(sampleUserOp, subOwner, mockEntryPoint.address, chainId).signature.toString()) + const owner1Sig = removePrefix(owner1.address) + "02" + "00000000" + const ownerAddr = removePrefix(owner.address) + const subOwnerAddr = removePrefix(subOwner.address) + const owner1Addr = removePrefix(owner1.address) + const mapping: Record = { + [ownerAddr]: ownerSig, + [subOwnerAddr]: subOwnerSig, + [owner1Addr]: owner1Sig + }; + // Sort the keys in ascending order + let signatures = sortSignatures(mapping) + + expect(await multiSigBarz.checkSignatures(userOpHash, signatures, 3)).to.equal(VALID_SIG) + }) + }) + describe("# approveHash", () => { + let sampleUserOphash: any + let chainId: any + let salt: any + let Factory: any + let factory: any + let barzAddr: any + let barz: any + let multiSigBarz: MultiSigFacet + let accountBarz: AccountFacet + let cut: any + let diamondCutBarz: DiamondCutFacet + let funcCallData: any + const verificationGasLimit = 1000000 + const callGasLimit = 2000000 + const nonce = 1 + const sampleUserOp = fillUserOpDefaults({ + sender: AddressOne, // Just for a sample + nonce, + verificationGasLimit, + callGasLimit + }) + beforeEach(async () => { + chainId = await getChainId() + sampleUserOphash = await getUserOpHash(sampleUserOp, entryPoint.address, chainId) + salt = "0" + Factory = await ethers.getContractFactory("BarzFactory") + factory = await Factory.deploy(accountFacet.address, mockEntryPoint.address, facetRegistry.address, defaultFallbackHandler.address) + + const threshold = "00000003" + const initData = addPrefix(threshold + removePrefix(owner.address) + removePrefix(subOwner.address) + removePrefix(owner1.address)) + await expect(factory.createAccount(multiSigFacet.address, initData, salt)).to.not.be.reverted + barzAddr = await factory.getAddress(multiSigFacet.address, initData, salt) + barz = await ethers.getContractAt("Barz", barzAddr) + multiSigBarz = await getFacetBarz("MultiSigFacet", barz) + accountBarz = await getFacetBarz("AccountFacet", barz) + + cut = diamondCut(multiSigFacet.address, FacetCutAction.Add, [multiSigBarz.interface.getSighash("checkSignatures"), multiSigBarz.interface.getSighash("getThreshold"), multiSigBarz.interface.getSighash("getOwners"), multiSigBarz.interface.getSighash("approveHash"), multiSigBarz.interface.getSighash("isApprovedHash")]) + diamondCutBarz = await getFacetBarz('DiamondCutFacet', barz) + funcCallData = diamondCutBarz.interface.encodeFunctionData("diamondCut", [cut, AddressZero, "0x00"]) + + await accountBarz.connect(mockEntryPoint).execute(accountBarz.address, 0, funcCallData) + }) + it("Should revert if not owner", async () => { + await expect(multiSigBarz.connect(user1).approveHash(sampleUserOphash)).to.be.revertedWithCustomError(multiSigBarz, "MultiSigFacet__OnlyOwner") + }) + it("Should approve hash", async () => { + await expect(multiSigBarz.connect(owner1).approveHash(sampleUserOphash)) + expect(await multiSigBarz.isApprovedHash(owner1.address, sampleUserOphash)).to.be.true + }) + it("Should emit event", async () => { + await expect(multiSigBarz.connect(owner1).approveHash(sampleUserOphash)).to.emit(multiSigBarz, "HashApproved").withArgs(sampleUserOphash, owner1.address) + expect(await multiSigBarz.isApprovedHash(owner1.address, sampleUserOphash)).to.be.true + }) + }) + describe("# validateOwnerSignature", () => { + let chainId: any + let salt: any + let Factory: any + let factory: any + const VALID_SIG = 0 + const verificationGasLimit = 1000000 + const callGasLimit = 2000000 + const nonce = 1 + beforeEach(async () => { + chainId = await getChainId() + salt = "0" + Factory = await ethers.getContractFactory("BarzFactory") + factory = await Factory.deploy(accountFacet.address, mockEntryPoint.address, facetRegistry.address, defaultFallbackHandler.address) + }) + it("Should validate owner signature", async () => { + const threshold = "00000003" + const initData = addPrefix(threshold + removePrefix(owner.address) + removePrefix(subOwner.address) + removePrefix(owner1.address)) + await expect(factory.createAccount(multiSigFacet.address, initData, salt)).to.not.be.reverted + const barzAddr = await factory.getAddress(multiSigFacet.address, initData, salt) + const barz = await ethers.getContractAt("Barz", barzAddr) + const multiSigBarz = await getFacetBarz("MultiSigFacet", barz) + const accountBarz = await getFacetBarz("AccountFacet", barz) + + const cut = diamondCut(multiSigFacet.address, FacetCutAction.Add, [multiSigBarz.interface.getSighash("checkSignatures"), multiSigBarz.interface.getSighash("getThreshold"), multiSigBarz.interface.getSighash("getOwners"), multiSigBarz.interface.getSighash("approveHash"), multiSigBarz.interface.getSighash("isApprovedHash")]) + const diamondCutBarz = await getFacetBarz('DiamondCutFacet', barz) + const funcCallData = diamondCutBarz.interface.encodeFunctionData("diamondCut", [cut, AddressZero, "0x00"]) + + await accountBarz.connect(mockEntryPoint).execute(accountBarz.address, 0, funcCallData) + + const callData = executeCallData(barz.address, 0, funcCallData) + + const signatureType = "03" + const sampleUserOp = fillUserOpDefaults({ + sender: barzAddr, // Just for a sample + callData, + nonce, + verificationGasLimit, + callGasLimit + }) + const userOpHash = await getUserOpHash(sampleUserOp, mockEntryPoint.address, chainId) + + await multiSigBarz.connect(owner1).approveHash(userOpHash) + const ownerSig = removePrefix(owner.address) + signatureType + "00000041" + removePrefix(signUserOpK1Curve(sampleUserOp, owner, mockEntryPoint.address, chainId).signature.toString()) + const subOwnerSig = removePrefix(subOwner.address) + "03" + "00000041" + removePrefix(signUserOpK1Curve(sampleUserOp, subOwner, mockEntryPoint.address, chainId).signature.toString()) + const owner1Sig = removePrefix(owner1.address) + "02" + "00000000" + const ownerAddr = removePrefix(owner.address) + const subOwnerAddr = removePrefix(subOwner.address) + const owner1Addr = removePrefix(owner1.address) + const mapping: Record = { + [ownerAddr]: ownerSig, + [subOwnerAddr]: subOwnerSig, + [owner1Addr]: owner1Sig + }; + // Sort the keys in ascending order + let signatures = sortSignatures(mapping) + sampleUserOp.signature = signatures + + expect(await multiSigBarz.validateOwnerSignature(sampleUserOp, userOpHash)).to.equal(VALID_SIG) + }) + }) + describe("# validateOwnerSignatureSelector", () => { + it("Should return valid selector", async () => { + expect(await multiSigFacet.validateOwnerSignatureSelector()).to.equal(multiSigFacet.interface.getSighash("validateOwnerSignature")) + }) + }) + describe("# owner", () => { + let salt: any + let Factory: any + let factory: any + beforeEach(async () => { + salt = "0" + Factory = await ethers.getContractFactory("BarzFactory") + factory = await Factory.deploy(accountFacet.address, mockEntryPoint.address, facetRegistry.address, defaultFallbackHandler.address) + }) + it("Should return owner address concatenated data", async () => { + const threshold = "00000003" + const initData = addPrefix(threshold + removePrefix(owner.address) + removePrefix(subOwner.address) + removePrefix(owner1.address)) + await expect(factory.createAccount(multiSigFacet.address, initData, salt)).to.not.be.reverted + const barzAddr = await factory.getAddress(multiSigFacet.address, initData, salt) + const barz = await ethers.getContractAt("Barz", barzAddr) + const multiSigBarz = await getFacetBarz("MultiSigFacet", barz) + const accountBarz = await getFacetBarz("AccountFacet", barz) + + const cut = diamondCut(multiSigFacet.address, FacetCutAction.Add, [multiSigBarz.interface.getSighash("checkSignatures"), multiSigBarz.interface.getSighash("getThreshold"), multiSigBarz.interface.getSighash("getOwners"), multiSigBarz.interface.getSighash("approveHash"), multiSigBarz.interface.getSighash("isApprovedHash")]) + const diamondCutBarz = await getFacetBarz('DiamondCutFacet', barz) + const funcCallData = diamondCutBarz.interface.encodeFunctionData("diamondCut", [cut, AddressZero, "0x00"]) + + await accountBarz.connect(mockEntryPoint).execute(accountBarz.address, 0, funcCallData) + + expect((await multiSigBarz.owner()).toLowerCase()).to.equal((owner.address + removePrefix(subOwner.address) + removePrefix(owner1.address)).toLowerCase()) + }) + it("Should return owner address concatenated data when single owner", async () => { + const threshold = "00000001" + const initData = addPrefix(threshold + removePrefix(owner.address)) + await expect(factory.createAccount(multiSigFacet.address, initData, salt)).to.not.be.reverted + const barzAddr = await factory.getAddress(multiSigFacet.address, initData, salt) + const barz = await ethers.getContractAt("Barz", barzAddr) + const multiSigBarz = await getFacetBarz("MultiSigFacet", barz) + const accountBarz = await getFacetBarz("AccountFacet", barz) + + const cut = diamondCut(multiSigFacet.address, FacetCutAction.Add, [multiSigBarz.interface.getSighash("checkSignatures"), multiSigBarz.interface.getSighash("getThreshold"), multiSigBarz.interface.getSighash("getOwners"), multiSigBarz.interface.getSighash("approveHash"), multiSigBarz.interface.getSighash("isApprovedHash")]) + const diamondCutBarz = await getFacetBarz('DiamondCutFacet', barz) + const funcCallData = diamondCutBarz.interface.encodeFunctionData("diamondCut", [cut, AddressZero, "0x00"]) + + await accountBarz.connect(mockEntryPoint).execute(accountBarz.address, 0, funcCallData) + + expect((await multiSigBarz.owner()).toLowerCase()).to.equal((owner.address).toLowerCase()) + }) + it("Should return owner address concatenated data when multiple owner", async () => { + const threshold = "00000001" + const initData = addPrefix(threshold + removePrefix(owner.address) + removePrefix(subOwner.address)) + await expect(factory.createAccount(multiSigFacet.address, initData, salt)).to.not.be.reverted + const barzAddr = await factory.getAddress(multiSigFacet.address, initData, salt) + const barz = await ethers.getContractAt("Barz", barzAddr) + const multiSigBarz = await getFacetBarz("MultiSigFacet", barz) + const accountBarz = await getFacetBarz("AccountFacet", barz) + + const cut = diamondCut(multiSigFacet.address, FacetCutAction.Add, [multiSigBarz.interface.getSighash("checkSignatures"), multiSigBarz.interface.getSighash("getThreshold"), multiSigBarz.interface.getSighash("getOwners"), multiSigBarz.interface.getSighash("approveHash"), multiSigBarz.interface.getSighash("isApprovedHash")]) + const diamondCutBarz = await getFacetBarz('DiamondCutFacet', barz) + const funcCallData = diamondCutBarz.interface.encodeFunctionData("diamondCut", [cut, AddressZero, "0x00"]) + + await accountBarz.connect(mockEntryPoint).execute(accountBarz.address, 0, funcCallData) + + expect((await multiSigBarz.owner()).toLowerCase()).to.equal((owner.address + removePrefix(subOwner.address)).toLowerCase()) + }) + }) + describe("# isValidKeyType", async () => { + it("Should return false if public key length is shorter than address + threshold", async () => { + const shortPublicKey = "0x1234" + expect(await multiSigFacet.isValidKeyType(shortPublicKey)).to.be.false + }) + it("Should return false if public key length is invalid", async () => { + const invalidPostfix = "bada" + const invalidPublicKey = "0x00000001" + removePrefix(owner.address) + invalidPostfix + expect(await multiSigFacet.isValidKeyType(invalidPublicKey)).to.be.false + }) + it("Should return true if public key length and format is valid", async () => { + let validPublicKey = "0x00000001" + removePrefix(owner.address) + expect(await multiSigFacet.isValidKeyType(validPublicKey)).to.be.true + + validPublicKey = "0x00000001" + removePrefix(owner.address) + removePrefix(owner1.address) + expect(await multiSigFacet.isValidKeyType(validPublicKey)).to.be.true + + validPublicKey = "0x00000001" + removePrefix(owner.address) + removePrefix(owner1.address) + removePrefix(owner2.address) + expect(await multiSigFacet.isValidKeyType(validPublicKey)).to.be.true + }) + }) + describe("# isValidSignature", () => { + let chainId: any + let salt: any + let Factory: any + let factory: any + let barzAddr: string + let barz: Barz + let multiSigBarz: MultiSigFacet + let accountBarz: AccountFacet + let cut: any + let funcCallData: any + let threshold: any + let initData: any + const verificationGasLimit = 1000000 + const callGasLimit = 2000000 + const nonce = 1 + beforeEach(async () => { + chainId = await getChainId() + salt = "0" + Factory = await ethers.getContractFactory("BarzFactory") + factory = await Factory.deploy(accountFacet.address, mockEntryPoint.address, facetRegistry.address, defaultFallbackHandler.address) + threshold = "00000002" + initData = addPrefix(threshold + removePrefix(owner.address) + removePrefix(subOwner.address)) + await expect(factory.createAccount(multiSigFacet.address, initData, salt)).to.not.be.reverted + barzAddr = await factory.getAddress(multiSigFacet.address, initData, salt) + barz = await ethers.getContractAt("Barz", barzAddr) + multiSigBarz = await getFacetBarz("MultiSigFacet", barz) + accountBarz = await getFacetBarz("AccountFacet", barz) + + cut = diamondCut(multiSigFacet.address, FacetCutAction.Add, [multiSigBarz.interface.getSighash("checkSignatures")]) + funcCallData = diamondCutFacet.interface.encodeFunctionData("diamondCut", [cut, AddressZero, "0x00"]) + + await accountBarz.connect(mockEntryPoint).execute(accountBarz.address, 0, funcCallData) + }) + it("Should return non-magic value when signature is invalid", async () => { + const callData = executeCallData(barz.address, 0, funcCallData) + const signatureType = "03" + const signatureLength = "00000041" + const sampleUserOp = fillUserOpDefaults({ + sender: barzAddr, // Just for a sample + callData, + nonce, + verificationGasLimit, + callGasLimit + }) + const invalidChainId = 6666666 + const userOpHash = await getUserOpHash(sampleUserOp, entryPoint.address, invalidChainId) // Signs with an invalid ChainID so wrong signature + const ownerSig = signUserOpK1Curve(sampleUserOp, owner, entryPoint.address, chainId) + const subOwnerSig = signUserOpK1Curve(sampleUserOp, subOwner, entryPoint.address, chainId) + const ownerSignature = removePrefix(owner.address) + signatureType + signatureLength + removePrefix(ownerSig.signature.toString()) + const subOwnerSignature = removePrefix(subOwner.address) + signatureType + signatureLength + removePrefix(subOwnerSig.signature.toString()) + const ownerAddr = owner.address + const subOwnerAddr = subOwner.address + const mapping: Record = { + [ownerAddr]: ownerSignature, + [subOwnerAddr]: subOwnerSignature + }; + // Sort the keys in ascending order + let signatures = sortSignatures(mapping) + + expect(await multiSigBarz.isValidSignature(userOpHash, signatures)).to.equal("0xffffffff") + }) + it("Should return valid value when signature is valid", async () => { + const callData = executeCallData(barz.address, 0, funcCallData) + const signatureType = "01" + const signatureLength = "00000041" + const sampleUserOp = fillUserOpDefaults({ + sender: barzAddr, // Just for a sample + callData, + nonce, + verificationGasLimit, + callGasLimit + }) + const userOpHash = await getUserOpHash(sampleUserOp, entryPoint.address, chainId) + + const finalHash = await getMessageHash(userOpHash, await getChainId(), multiSigBarz.address) + + const oSig = ecsign(Buffer.from(ethers.utils.arrayify(finalHash)), Buffer.from(ethers.utils.arrayify(owner.privateKey))) + const ownerSig = toRpcSig(oSig.v, oSig.r, oSig.s) + + const sSig = ecsign(Buffer.from(ethers.utils.arrayify(finalHash)), Buffer.from(ethers.utils.arrayify(subOwner.privateKey))) + const subOwnerSig = toRpcSig(sSig.v, sSig.r, sSig.s) + + const ownerSignature = removePrefix(owner.address) + signatureType + signatureLength + removePrefix(ownerSig.toString()) + const subOwnerSignature = removePrefix(subOwner.address) + signatureType + signatureLength + removePrefix(subOwnerSig.toString()) + const ownerAddr = owner.address + const subOwnerAddr = subOwner.address + const mapping: Record = { + [ownerAddr]: ownerSignature, + [subOwnerAddr]: subOwnerSignature + }; + + // Sort the keys in ascending order + let signatures = sortSignatures(mapping) + + expect(await multiSigBarz.isValidSignature(userOpHash, signatures)).to.equal("0x1626ba7e") + }) + }) + describe("# addOwner", () => { + let salt: any + let Factory: any + let factory: any + let barzAddr: string + let barz: Barz + let multiSigBarz: MultiSigFacet + let accountBarz: AccountFacet + let cut: any + let diamondCutBarz: DiamondCutFacet + let funcCallData: any + let threshold: any + let initData: any + beforeEach(async () => { + salt = "0" + Factory = await ethers.getContractFactory("BarzFactory") + factory = await Factory.deploy(accountFacet.address, mockEntryPoint.address, facetRegistry.address, defaultFallbackHandler.address) + threshold = "00000002" + initData = addPrefix(threshold + removePrefix(owner.address) + removePrefix(subOwner.address)) + await expect(factory.createAccount(multiSigFacet.address, initData, salt)).to.not.be.reverted + barzAddr = await factory.getAddress(multiSigFacet.address, initData, salt) + barz = await ethers.getContractAt("Barz", barzAddr) + multiSigBarz = await getFacetBarz("MultiSigFacet", barz) + accountBarz = await getFacetBarz("AccountFacet", barz) + + cut = diamondCut(multiSigFacet.address, FacetCutAction.Add, [multiSigBarz.interface.getSighash("checkSignatures"), multiSigBarz.interface.getSighash("getThreshold"), multiSigBarz.interface.getSighash("getOwners"), multiSigBarz.interface.getSighash("approveHash"), multiSigBarz.interface.getSighash("isApprovedHash"), multiSigBarz.interface.getSighash("addOwner")]) + diamondCutBarz = await getFacetBarz('DiamondCutFacet', barz) + funcCallData = diamondCutBarz.interface.encodeFunctionData("diamondCut", [cut, AddressZero, "0x00"]) + + await accountBarz.connect(mockEntryPoint).execute(accountBarz.address, 0, funcCallData) + }) + it("Should revert if new owner is already owner", async () => { + const addOwnerCallData = multiSigFacet.interface.encodeFunctionData("addOwner", [owner.address, 3]) + + await expect(accountBarz.connect(mockEntryPoint).execute(accountBarz.address, 0, addOwnerCallData)).to.be.revertedWithCustomError(multiSigBarz, "MultiSigFacet__DuplicateOwner") + }) + it("Should revert if new owner is zero address", async () => { + const addOwnerCallData = multiSigFacet.interface.encodeFunctionData("addOwner", [AddressZero, 3]) + + await expect(accountBarz.connect(mockEntryPoint).execute(accountBarz.address, 0, addOwnerCallData)).to.be.revertedWithCustomError(multiSigBarz, "MultiSigFacet__InvalidOwnerAddress") + }) + it("Should revert if new owner is SENTINEL_OWNERS", async () => { + const addOwnerCallData = multiSigFacet.interface.encodeFunctionData("addOwner", [AddressOne, 3]) + + await expect(accountBarz.connect(mockEntryPoint).execute(accountBarz.address, 0, addOwnerCallData)).to.be.revertedWithCustomError(multiSigBarz, "MultiSigFacet__InvalidOwnerAddress") + }) + it("Should revert if new owner is address of Barz", async () => { + const addOwnerCallData = multiSigFacet.interface.encodeFunctionData("addOwner", [multiSigBarz.address, 3]) + + await expect(accountBarz.connect(mockEntryPoint).execute(accountBarz.address, 0, addOwnerCallData)).to.be.revertedWithCustomError(multiSigBarz, "MultiSigFacet__InvalidOwnerAddress") + }) + it("Should add owner and emit event", async () => { + const addOwnerCallData = multiSigFacet.interface.encodeFunctionData("addOwner", [owner2.address, 3]) + + await expect(accountBarz.connect(mockEntryPoint).execute(accountBarz.address, 0, addOwnerCallData)).to.emit(multiSigBarz, "OwnerAdded").withArgs(owner2.address) + }) + }) + describe("# removeOwner", () => { + let salt: any + let Factory: any + let factory: any + let barzAddr: string + let barz: Barz + let multiSigBarz: MultiSigFacet + let accountBarz: AccountFacet + let cut: any + let diamondCutBarz: DiamondCutFacet + let funcCallData: any + let threshold: any + let initData: any + beforeEach(async () => { + salt = "0" + Factory = await ethers.getContractFactory("BarzFactory") + factory = await Factory.deploy(accountFacet.address, mockEntryPoint.address, facetRegistry.address, defaultFallbackHandler.address) + + threshold = "00000002" + initData = addPrefix(threshold + removePrefix(owner.address) + removePrefix(subOwner.address)) + await expect(factory.createAccount(multiSigFacet.address, initData, salt)).to.not.be.reverted + barzAddr = await factory.getAddress(multiSigFacet.address, initData, salt) + barz = await ethers.getContractAt("Barz", barzAddr) + multiSigBarz = await getFacetBarz("MultiSigFacet", barz) + accountBarz = await getFacetBarz("AccountFacet", barz) + + cut = diamondCut(multiSigFacet.address, FacetCutAction.Add, [multiSigBarz.interface.getSighash("checkSignatures"), multiSigBarz.interface.getSighash("getThreshold"), multiSigBarz.interface.getSighash("getOwners"), multiSigBarz.interface.getSighash("approveHash"), multiSigBarz.interface.getSighash("isApprovedHash"), multiSigBarz.interface.getSighash("removeOwner")]) + diamondCutBarz = await getFacetBarz('DiamondCutFacet', barz) + funcCallData = diamondCutBarz.interface.encodeFunctionData("diamondCut", [cut, AddressZero, "0x00"]) + + await accountBarz.connect(mockEntryPoint).execute(accountBarz.address, 0, funcCallData) + }) + it("Should revert if owner count is less than new threshold", async () => { + const removeOwnerCallData = multiSigFacet.interface.encodeFunctionData("removeOwner", [owner.address, subOwner.address, 2]) + + await expect(accountBarz.connect(mockEntryPoint).execute(accountBarz.address, 0, removeOwnerCallData)).to.be.revertedWithCustomError(multiSigBarz, "MultiSigFacet__InvalidThreshold") + }) + it("Should revert if removed owner is zero address", async () => { + const removeOwnerCallData = multiSigFacet.interface.encodeFunctionData("removeOwner", [owner.address, AddressZero, 1]) + + await expect(accountBarz.connect(mockEntryPoint).execute(accountBarz.address, 0, removeOwnerCallData)).to.be.revertedWithCustomError(multiSigBarz, "MultiSigFacet__InvalidOwnerAddress") + }) + it("Should revert if removed owner is SENTINEL_OWNERS", async () => { + const removeOwnerCallData = multiSigFacet.interface.encodeFunctionData("removeOwner", [owner.address, AddressOne, 1]) + + await expect(accountBarz.connect(mockEntryPoint).execute(accountBarz.address, 0, removeOwnerCallData)).to.be.revertedWithCustomError(multiSigBarz, "MultiSigFacet__InvalidOwnerAddress") + }) + it("Should revert if linkedlist if incorrect", async () => { + const removeOwnerCallData = multiSigFacet.interface.encodeFunctionData("removeOwner", [owner.address, owner2.address, 1]) + + await expect(accountBarz.connect(mockEntryPoint).execute(accountBarz.address, 0, removeOwnerCallData)).to.be.revertedWithCustomError(multiSigBarz, "MultiSigFacet__InvalidOwnerPair") + }) + it("Should remove owner and emit event", async () => { + const removeOwnerCallData = multiSigFacet.interface.encodeFunctionData("removeOwner", [owner.address, subOwner.address, 1]) + + await expect(accountBarz.connect(mockEntryPoint).execute(accountBarz.address, 0, removeOwnerCallData)).to.emit(multiSigBarz, "OwnerRemoved").withArgs(subOwner.address) + + expect(await multiSigBarz.getThreshold()).to.equal(1) + }) + }) + describe("# swapOwner", () => { + let salt: any + let Factory: any + let factory: any + let threshold: string + let initData: string + let barzAddr: string + let barz: Barz + let multiSigBarz: MultiSigFacet + let accountBarz: AccountFacet + let cut: any + let diamondCutBarz: DiamondCutFacet + let funcCallData: any + beforeEach(async () => { + salt = "0" + Factory = await ethers.getContractFactory("BarzFactory") + factory = await Factory.deploy(accountFacet.address, mockEntryPoint.address, facetRegistry.address, defaultFallbackHandler.address) + threshold = "00000002" + initData = addPrefix(threshold + removePrefix(owner.address) + removePrefix(subOwner.address)) + await expect(factory.createAccount(multiSigFacet.address, initData, salt)).to.not.be.reverted + barzAddr = await factory.getAddress(multiSigFacet.address, initData, salt) + barz = await ethers.getContractAt("Barz", barzAddr) + multiSigBarz = await getFacetBarz("MultiSigFacet", barz) + accountBarz = await getFacetBarz("AccountFacet", barz) + cut = diamondCut(multiSigFacet.address, FacetCutAction.Add, [multiSigBarz.interface.getSighash("swapOwner"), multiSigBarz.interface.getSighash("getThreshold"), multiSigBarz.interface.getSighash("getOwners"), multiSigBarz.interface.getSighash("approveHash"), multiSigBarz.interface.getSighash("isApprovedHash"), multiSigBarz.interface.getSighash("removeOwner")]) + diamondCutBarz = await getFacetBarz('DiamondCutFacet', barz) + funcCallData = diamondCutBarz.interface.encodeFunctionData("diamondCut", [cut, AddressZero, "0x00"]) + + await accountBarz.connect(mockEntryPoint).execute(accountBarz.address, 0, funcCallData) + }) + it("Should revert if new owner is zero address", async () => { + const removeOwnerCallData = multiSigFacet.interface.encodeFunctionData("swapOwner", [owner.address, subOwner.address, AddressZero]) + + await expect(accountBarz.connect(mockEntryPoint).execute(accountBarz.address, 0, removeOwnerCallData)).to.be.revertedWithCustomError(multiSigBarz, "MultiSigFacet__InvalidOwnerAddress") + }) + it("Should revert if new owner is SENTINEL_OWNERS", async () => { + const removeOwnerCallData = multiSigFacet.interface.encodeFunctionData("swapOwner", [owner.address, subOwner.address, AddressOne]) + + await expect(accountBarz.connect(mockEntryPoint).execute(accountBarz.address, 0, removeOwnerCallData)).to.be.revertedWithCustomError(multiSigBarz, "MultiSigFacet__InvalidOwnerAddress") + }) + it("Should revert if new owner is address of Barz", async () => { + const removeOwnerCallData = multiSigFacet.interface.encodeFunctionData("swapOwner", [owner.address, subOwner.address, multiSigBarz.address]) + + await expect(accountBarz.connect(mockEntryPoint).execute(accountBarz.address, 0, removeOwnerCallData)).to.be.revertedWithCustomError(multiSigBarz, "MultiSigFacet__InvalidOwnerAddress") + }) + it("Should revert if removed owner is zero address", async () => { + const removeOwnerCallData = multiSigFacet.interface.encodeFunctionData("swapOwner", [owner.address, AddressZero, multiSigBarz.address]) + + await expect(accountBarz.connect(mockEntryPoint).execute(accountBarz.address, 0, removeOwnerCallData)).to.be.revertedWithCustomError(multiSigBarz, "MultiSigFacet__InvalidOwnerAddress") + }) + it("Should revert if removed owner is SENTINEL_OWNERS", async () => { + const removeOwnerCallData = multiSigFacet.interface.encodeFunctionData("swapOwner", [owner.address, AddressOne, multiSigBarz.address]) + + await expect(accountBarz.connect(mockEntryPoint).execute(accountBarz.address, 0, removeOwnerCallData)).to.be.revertedWithCustomError(multiSigBarz, "MultiSigFacet__InvalidOwnerAddress") + }) + it("Should revert if linkedlist if incorrect", async () => { + const removeOwnerCallData = multiSigFacet.interface.encodeFunctionData("swapOwner", [AddressZero, subOwner.address, owner2.address]) + + await expect(accountBarz.connect(mockEntryPoint).execute(accountBarz.address, 0, removeOwnerCallData)).to.be.revertedWithCustomError(multiSigBarz, "MultiSigFacet__InvalidOwnerPair") + }) + it("Should swap owner and emit event", async () => { + const removeOwnerCallData = multiSigFacet.interface.encodeFunctionData("swapOwner", [owner.address, subOwner.address, owner2.address]) + + const tx = await accountBarz.connect(mockEntryPoint).execute(accountBarz.address, 0, removeOwnerCallData) + await expect(tx).to.emit(multiSigBarz, "OwnerRemoved").withArgs(subOwner.address) + await expect(tx).to.emit(multiSigBarz, "OwnerAdded").withArgs(owner2.address) + }) + it("Should swap owner and emit event even when owner is first element in the list", async () => { + const removeOwnerCallData = multiSigFacet.interface.encodeFunctionData("swapOwner", [AddressOne, owner.address, owner2.address]) + + const tx = await accountBarz.connect(mockEntryPoint).execute(accountBarz.address, 0, removeOwnerCallData) + await expect(tx).to.emit(multiSigBarz, "OwnerRemoved").withArgs(owner.address) + await expect(tx).to.emit(multiSigBarz, "OwnerAdded").withArgs(owner2.address) + }) + }) + describe("# changeThreshold", () => { + let salt: any + let Factory: any + let factory: any + let barzAddr: any + let barz: any + let multiSigBarz: any + let accountBarz: any + let diamondCutBarz: any + let cut: any + let funcCallData: any + beforeEach(async () => { + salt = "0" + Factory = await ethers.getContractFactory("BarzFactory") + factory = await Factory.deploy(accountFacet.address, mockEntryPoint.address, facetRegistry.address, defaultFallbackHandler.address) + + const threshold = "00000002" + const initData = addPrefix(threshold + removePrefix(owner.address) + removePrefix(subOwner.address)) + await expect(factory.createAccount(multiSigFacet.address, initData, salt)).to.not.be.reverted + barzAddr = await factory.getAddress(multiSigFacet.address, initData, salt) + barz = await ethers.getContractAt("Barz", barzAddr) + multiSigBarz = await getFacetBarz("MultiSigFacet", barz) + accountBarz = await getFacetBarz("AccountFacet", barz) + + cut = diamondCut(multiSigFacet.address, FacetCutAction.Add, [multiSigBarz.interface.getSighash("changeThreshold"), multiSigBarz.interface.getSighash("getThreshold"), multiSigBarz.interface.getSighash("getOwners"), multiSigBarz.interface.getSighash("approveHash"), multiSigBarz.interface.getSighash("isApprovedHash"), multiSigBarz.interface.getSighash("removeOwner")]) + diamondCutBarz = await getFacetBarz('DiamondCutFacet', barz) + funcCallData = diamondCutBarz.interface.encodeFunctionData("diamondCut", [cut, AddressZero, "0x00"]) + + await accountBarz.connect(mockEntryPoint).execute(accountBarz.address, 0, funcCallData) + }) + it("Should revert if new threshold is zero", async () => { + const changeThresholdCallData = multiSigFacet.interface.encodeFunctionData("changeThreshold", [0]) + + await expect(accountBarz.connect(mockEntryPoint).execute(accountBarz.address, 0, changeThresholdCallData)).to.be.revertedWithCustomError(multiSigBarz, "MultiSigFacet__InvalidThreshold") + }) + it("Should revert if new threshold is bigger than number of owners", async () => { + const changeThresholdCallData = multiSigFacet.interface.encodeFunctionData("changeThreshold", [5]) + + await expect(accountBarz.connect(mockEntryPoint).execute(accountBarz.address, 0, changeThresholdCallData)).to.be.revertedWithCustomError(multiSigBarz, "MultiSigFacet__InvalidThreshold") + }) + it("Should change threshold", async () => { + const newThreshold = 1 + const changeThresholdCallData = multiSigFacet.interface.encodeFunctionData("changeThreshold", [newThreshold]) + + await accountBarz.connect(mockEntryPoint).execute(accountBarz.address, 0, changeThresholdCallData) + + expect(await multiSigBarz.getThreshold()).to.equal(newThreshold) + }) + it("Should emit event", async () => { + const newThreshold = 1 + const changeThresholdCallData = multiSigFacet.interface.encodeFunctionData("changeThreshold", [newThreshold]) + + await expect(accountBarz.connect(mockEntryPoint).execute(accountBarz.address, 0, changeThresholdCallData)).to.emit(multiSigBarz, "ThresholdChanged").withArgs(newThreshold) + }) + }) + describe("# isOwner", () => { + let salt: any + let Factory: any + let factory: any + let threshold: any + let initData: any + let barzAddr: any + let barz: Barz + let multiSigBarz: MultiSigFacet + let accountBarz: AccountFacet + let cut: any + let diamondCutBarz: DiamondCutFacet + let funcCallData: any + beforeEach(async () => { + salt = "0" + Factory = await ethers.getContractFactory("BarzFactory") + factory = await Factory.deploy(accountFacet.address, mockEntryPoint.address, facetRegistry.address, defaultFallbackHandler.address) + threshold = "00000002" + initData = addPrefix(threshold + removePrefix(owner.address) + removePrefix(subOwner.address)) + await expect(factory.createAccount(multiSigFacet.address, initData, salt)).to.not.be.reverted + barzAddr = await factory.getAddress(multiSigFacet.address, initData, salt) + barz = await ethers.getContractAt("Barz", barzAddr) + multiSigBarz = await getFacetBarz("MultiSigFacet", barz) + accountBarz = await getFacetBarz("AccountFacet", barz) + + cut = diamondCut(multiSigFacet.address, FacetCutAction.Add, [multiSigBarz.interface.getSighash("isOwner")]) + diamondCutBarz = await getFacetBarz('DiamondCutFacet', barz) + funcCallData = diamondCutBarz.interface.encodeFunctionData("diamondCut", [cut, AddressZero, "0x00"]) + + await accountBarz.connect(mockEntryPoint).execute(accountBarz.address, 0, funcCallData) + }) + it("Should return true if owner", async () => { + expect(await multiSigBarz.isOwner(owner.address)).to.be.true + expect(await multiSigBarz.isOwner(subOwner.address)).to.be.true + + }) + it("Should return false if not owner", async () => { + expect(await multiSigBarz.isOwner(owner1.address)).to.be.false + expect(await multiSigBarz.isOwner(owner2.address)).to.be.false + }) + }) + describe("# getPrevOwner", () => { + let salt: any + let Factory: any + let factory: any + let threshold: any + let initData: any + let barzAddr: any + let barz: Barz + let multiSigBarz: MultiSigFacet + let accountBarz: AccountFacet + let cut: any + let diamondCutBarz: DiamondCutFacet + let funcCallData: any + beforeEach(async () => { + salt = "0" + Factory = await ethers.getContractFactory("BarzFactory") + factory = await Factory.deploy(accountFacet.address, mockEntryPoint.address, facetRegistry.address, defaultFallbackHandler.address) + threshold = "00000002" + initData = addPrefix(threshold + removePrefix(owner.address) + removePrefix(subOwner.address)) + await expect(factory.createAccount(multiSigFacet.address, initData, salt)).to.not.be.reverted + barzAddr = await factory.getAddress(multiSigFacet.address, initData, salt) + barz = await ethers.getContractAt("Barz", barzAddr) + multiSigBarz = await getFacetBarz("MultiSigFacet", barz) + accountBarz = await getFacetBarz("AccountFacet", barz) + + cut = diamondCut(multiSigFacet.address, FacetCutAction.Add, [multiSigBarz.interface.getSighash("getPrevOwner")]) + diamondCutBarz = await getFacetBarz('DiamondCutFacet', barz) + funcCallData = diamondCutBarz.interface.encodeFunctionData("diamondCut", [cut, AddressZero, "0x00"]) + + await accountBarz.connect(mockEntryPoint).execute(accountBarz.address, 0, funcCallData) + }) + it("Should return valid prev owner", async () => { + expect(await multiSigBarz.getPrevOwner(subOwner.address)).to.equal(owner.address) + }) + it("Should return SENTINEL_OWNER when first owner", async () => { + expect(await multiSigBarz.getPrevOwner(owner.address)).to.equal(AddressOne) + }) + it("Should return zero address when non-existent owner", async () => { + expect(await multiSigBarz.getPrevOwner(facetRegistryOwner.address)).to.equal(AddressZero) + }) + }) + describe("Functionality Test", () => { + let chainId: any + let salt: any + let Factory: any + let factory: any + const verificationGasLimit = 1000000 + const callGasLimit = 2000000 + const nonce = 0 + beforeEach(async () => { + chainId = await getChainId() + salt = "0" + Factory = await ethers.getContractFactory("BarzFactory") + factory = await Factory.deploy(accountFacet.address, entryPoint.address, facetRegistry.address, defaultFallbackHandler.address) + }) + it("Should send ERC20 Token from Multi-sig account", async () => { + const { keyPair, publicKeyBytes } = generateKeyPair() + + const multiSigOwner1 = await barzFixture(accountFacet, k1Facet, entryPoint, facetRegistry, defaultFallbackHandler, owner.publicKey) + const multiSigOwner2 = await barzFixture(accountFacet, r1Facet, entryPoint, facetRegistry, defaultFallbackHandler, publicKeyBytes) + const multiSigOwner3 = subOwner + // 0. Deploy Barz - 1 Passkeys, approvehash, ECDSA + const threshold = "00000003" + const initData = addPrefix(threshold + removePrefix(multiSigOwner1.address) + removePrefix(multiSigOwner2.address) + removePrefix(multiSigOwner3.address)) + await expect(factory.createAccount(multiSigFacet.address, initData, salt)).to.not.be.reverted + const barzAddr = await factory.getAddress(multiSigFacet.address, initData, salt) + const barz = await ethers.getContractAt("Barz", barzAddr) + + // 1. Deploy & mint token + const mintAmount = 100000 + const transferAmount = 1000 + const testToken = await testTokenFixture() + await testToken.mint(barz.address, mintAmount) + + // 2. SendERC20 token owner 2 address + const funcCallData = testToken.interface.encodeFunctionData("transfer", [user1.address, transferAmount]) + const callData = executeCallData(testToken.address, 0, funcCallData) + + const userOp = fillUserOpDefaults({ + sender: barz.address, + callData, + nonce, + verificationGasLimit, + callGasLimit + }) + const userOpHash = getUserOpHash(userOp, entryPoint.address, chainId) + const finalHash = await getMessageHash(userOpHash, await getChainId(), multiSigOwner1.address) // NOTE: This is not address of Multi-sig Barz, but address of owner1 barz + + const oSig = ecsign(Buffer.from(ethers.utils.arrayify(finalHash)), Buffer.from(ethers.utils.arrayify(owner.privateKey))) + const ownerSig = toRpcSig(oSig.v, oSig.r, oSig.s) + + const owner2Sig = signMsgOnR1Curve(userOpHash, keyPair) + const owner2UserOperationSignatureLength = (owner2Sig.toString().length - 2) / 2 + const paddedHexLength = owner2UserOperationSignatureLength.toString(16).padStart(8, '0') + + const signedMessage1 = await subOwner.signMessage(arrayify(userOpHash)) + + const owner1Signature = removePrefix(multiSigOwner1.address) + "01" + "00000041" + removePrefix(ownerSig.toString()) + const owner2Signature = removePrefix(multiSigOwner2.address) + "01" + paddedHexLength + removePrefix(owner2Sig.toString()) + const owner3Signature = removePrefix(multiSigOwner3.address) + "03" + "00000041" + removePrefix(signedMessage1.toString()) + + const multiSigOwner1Addr = removePrefix(multiSigOwner1.address) + const multiSigOwner2Addr = removePrefix(multiSigOwner2.address) + const multiSigOwner3Addr = removePrefix(multiSigOwner3.address) + + const mapping: Record = { + [multiSigOwner1Addr]: owner1Signature, + [multiSigOwner2Addr]: owner2Signature, + [multiSigOwner3Addr]: owner3Signature + }; + + let signatures = sortSignatures(mapping) + + userOp.signature = signatures + expect(await testToken.balanceOf(barz.address)).to.equal(mintAmount) + expect(await testToken.balanceOf(user1.address)).to.equal(0) + + await entryPoint.handleOps([userOp], user1.address) + expect(await testToken.balanceOf(user1.address)).to.equal(transferAmount) + }) + }) +}) \ No newline at end of file diff --git a/test/RestrictionsFacet.test.ts b/test/RestrictionsFacet.test.ts new file mode 100644 index 0000000..37250ff --- /dev/null +++ b/test/RestrictionsFacet.test.ts @@ -0,0 +1,333 @@ +import { ethers } from 'hardhat' +import { Wallet } from 'ethers' + +import { AccountFacet, DiamondCutFacet, Barz, Secp256k1VerificationFacet, SecurityManager, RestrictionsFacet, WhitelistStorage, FacetRegistry } from './typechain-types' +import { diamondCut } from './utils/helpers' +import { getFacetBarz, setupDefaultSecuritManager } from './utils/setup' +import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers' +import { createAccountOwner, fund, AddressZero } from './utils/testutils' + +const { + FacetCutAction, getSelectors +} = require('././utils/diamond.js') + +import { expect } from "chai" +import { diamondCutFacetFixture } from './fixtures/DiamondCutFacetFixture' +import { accountFacetFixture } from './fixtures/AccountFacetFixture' +import { secp256k1VerificationFacetFixture } from './fixtures/Secp256k1VerificationFacetFixture' +import { barzFixture } from './fixtures/BarzFixture' +import { restrictionsFacetFixture } from './fixtures/RestrictionsFacetFixture' +import { whitelistRestrictionFixture } from './fixtures/WhitelistRestrictionFixture' +import { whitelistStorageFixture } from './fixtures/WhitelistStorageFixture' +import { facetRegistryFixture } from './fixtures/FacetRegistryFixture' +import { WhitelistRestriction } from '../typechain-types/contracts/facets/restrictions/whitelist' +import { EntryPoint } from '../../typechain-types/core' +import { callFromEntryPointOnK1, executeBatchCallData, executeCallData } from './utils/UserOp' +import { entryPointFixture } from './fixtures/EntryPointFixture' +import { diamondLoupeFacetFixture } from './fixtures/DiamondLoupeFacetFixture' +import { DefaultFallbackHandler, DiamondLoupeFacet, TokenReceiverFacet } from '../typechain-types' +import { tokenReceiverFacetFixture } from './fixtures/TokenReceiverFacetFixture' +import { defaultFallbackHandlerFixture } from './fixtures/DefaultFallbackHandlerFixture' + +describe('Restrictions Facet', () => { + let diamondCutFacet: DiamondCutFacet + let diamondCutBarz: DiamondCutFacet + let securityManager: SecurityManager + let facetRegistry: FacetRegistry + let defaultFallbackHandler: DefaultFallbackHandler + let accountBarz: AccountFacet + let accountFacet: AccountFacet + let tokenReceiverFacet: TokenReceiverFacet + let k1Facet: Secp256k1VerificationFacet + let restrictionsFacet: RestrictionsFacet + let diamondLoupeFacet: DiamondLoupeFacet + let whitelistStorage: WhitelistStorage + let entryPoint: EntryPoint + let mockBarz: Barz + let mockEntrypoint: SignerWithAddress + let mockRestrictionsBarz: RestrictionsFacet + let mockAccountBarz: AccountFacet + let mockDiamondCutBarz: DiamondCutFacet + let owner: Wallet + let barz: Barz + let securityManagerOwner: SignerWithAddress + let facetRegistryOwner: SignerWithAddress + + const encodeRestrictionInitialization = (restrictions: any) => { + return restrictionsFacet.interface.encodeFunctionData('initializeRestrictions', [restrictions]) + } + const encodeRestrictionAddition = (restriction: string) => { + return restrictionsFacet.interface.encodeFunctionData('addRestriction', [restriction]) + } + const encodeRestrictionRemoval = (restriction: string) => { + return restrictionsFacet.interface.encodeFunctionData('removeRestriction', [restriction]) + } + + before(async () => { + [mockEntrypoint, securityManagerOwner, facetRegistryOwner] = await ethers.getSigners(); + owner = createAccountOwner() + await fund(owner.address) + + securityManager = await setupDefaultSecuritManager(securityManagerOwner) + diamondCutFacet = await diamondCutFacetFixture(securityManager) + facetRegistry = await facetRegistryFixture(facetRegistryOwner.address) + accountFacet = await accountFacetFixture() + k1Facet = await secp256k1VerificationFacetFixture() + restrictionsFacet = await restrictionsFacetFixture() + entryPoint = await entryPointFixture() + diamondLoupeFacet = await diamondLoupeFacetFixture() + tokenReceiverFacet = await tokenReceiverFacetFixture() + defaultFallbackHandler = await defaultFallbackHandlerFixture(diamondCutFacet, accountFacet, tokenReceiverFacet, diamondLoupeFacet) + + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(diamondCutFacet.address, getSelectors(diamondCutFacet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(accountFacet.address, getSelectors(accountFacet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(restrictionsFacet.address, getSelectors(restrictionsFacet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(k1Facet.address, getSelectors(k1Facet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(diamondLoupeFacet.address, getSelectors(diamondLoupeFacet)) + }) + + describe('# initializeRestrictions / uninitializeRestrictions', () => { + beforeEach(async () => { + barz = await barzFixture(accountFacet, k1Facet, entryPoint, facetRegistry, defaultFallbackHandler, owner.publicKey) + diamondCutBarz = await getFacetBarz('DiamondCutFacet', barz) + accountBarz = await getFacetBarz('AccountFacet', barz) + + mockBarz = await barzFixture(accountFacet, k1Facet, mockEntrypoint, facetRegistry, defaultFallbackHandler, owner.publicKey) + mockRestrictionsBarz = await getFacetBarz("RestrictionsFacet", mockBarz) + mockAccountBarz = await getFacetBarz("AccountFacet", mockBarz) + mockDiamondCutBarz = await getFacetBarz("DiamondCutFacet", mockBarz) + + await entryPoint.depositTo(barz.address, { + value: ethers.utils.parseEther('0.5'), + }) + }) + + it('Should revert adding a Restrictions Facet with no actual restrictions', async () => { + const initCall = encodeRestrictionInitialization([]) + const addCut = diamondCut(restrictionsFacet.address, FacetCutAction.Add, restrictionsFacet) + const addCutCall = diamondCutFacet.interface.encodeFunctionData("diamondCut", [addCut, AddressZero, "0x00"]) + + await expect(mockAccountBarz.connect(mockEntrypoint).executeBatch([mockAccountBarz.address, mockAccountBarz.address], [0, 0], [addCutCall, initCall])).to.be.revertedWithCustomError(mockRestrictionsBarz, 'RestrictionsFacet__EmptyRestrictionsList') + }) + + it('Should revert if restrictions include zero address', async () => { + const initCall = encodeRestrictionInitialization([AddressZero]) + const addCut = diamondCut(restrictionsFacet.address, FacetCutAction.Add, restrictionsFacet) + const addCutCall = diamondCutFacet.interface.encodeFunctionData("diamondCut", [addCut, AddressZero, "0x00"]) + + await expect(mockAccountBarz.connect(mockEntrypoint).executeBatch([mockAccountBarz.address, mockAccountBarz.address], [0, 0], [addCutCall, initCall])).to.be.revertedWithCustomError(mockRestrictionsBarz, 'RestrictionsFacet__ZeroAddressRestrictions') + }) + + it('Should be able to add and remove Restrictions Facet to Barz', async () => { + whitelistStorage = await whitelistStorageFixture() + const whitelistRestriction = await whitelistRestrictionFixture(whitelistStorage) + + const initCall = encodeRestrictionInitialization([whitelistRestriction.address]) + const addCut = diamondCut(restrictionsFacet.address, FacetCutAction.Add, restrictionsFacet) + const addCutCall = diamondCutFacet.interface.encodeFunctionData('diamondCut', [addCut, AddressZero, "0x00"]) + const addTx = await mockAccountBarz.connect(mockEntrypoint).executeBatch([mockAccountBarz.address, mockAccountBarz.address], [0, 0], [addCutCall, initCall]) + const addReceipt = await addTx.wait() + expect(addReceipt.status).to.equal(1) + + const uninitCall = restrictionsFacet.interface.encodeFunctionData('uninitializeRestrictions') + const removeCut = diamondCut(AddressZero, FacetCutAction.Remove, restrictionsFacet) + const removeCutCall = diamondCutFacet.interface.encodeFunctionData("diamondCut", [removeCut, AddressZero, "0x00"]) + const removeTx = await mockAccountBarz.connect(mockEntrypoint).executeBatch([mockAccountBarz.address, mockAccountBarz.address], [0, 0], [uninitCall, removeCutCall]) + const removeReceipt = await removeTx.wait() + + expect(removeReceipt.status).to.equal(1) + }) + it('Should revert adding a Restrictions Facet with no actual restrictions', async () => { + const initCall = encodeRestrictionInitialization([]) + const addCut = diamondCut(restrictionsFacet.address, FacetCutAction.Add, restrictionsFacet) + const addCutCall = diamondCutBarz.interface.encodeFunctionData("diamondCut", [addCut, AddressZero, "0x00"]) + const addTx = mockAccountBarz.connect(mockEntrypoint).executeBatch([mockAccountBarz.address, mockAccountBarz.address], [0, 0], [addCutCall, initCall]) + await expect(addTx).to.be.revertedWithCustomError(restrictionsFacet, 'RestrictionsFacet__EmptyRestrictionsList') + }) + }); + + describe('# verifyRestrictions', () => { + before(async () => { + // Add restrictions facet + whitelistStorage = await whitelistStorageFixture() + const whitelistRestriction = await whitelistRestrictionFixture(whitelistStorage) + const initCall = encodeRestrictionInitialization([whitelistRestriction.address]) + const addCut = diamondCut(restrictionsFacet.address, FacetCutAction.Add, restrictionsFacet) + const addCutCall = diamondCutFacet.interface.encodeFunctionData('diamondCut', [addCut, AddressZero, "0x00"]) + const addCutCallData = executeBatchCallData([barz.address, barz.address], [0, 0], [addCutCall, initCall]) + + await callFromEntryPointOnK1(entryPoint, barz.address, owner, addCutCallData) + await mockAccountBarz.connect(mockEntrypoint).executeBatch([mockBarz.address, mockBarz.address], [0, 0], [addCutCall, initCall]) + + await entryPoint.depositTo(barz.address, { + value: ethers.utils.parseEther('0.5'), + }) + }) + + it('Should reject transactions to a non-whitelisted address', async () => { + const nonWhitelist = "0xf471789937856d80e589f5996cf8b0511ddd9de4" + const transferCalldata = executeCallData(nonWhitelist, 1, "0x00") + await expect(mockAccountBarz.execute(nonWhitelist, 0, transferCalldata)).to.be.revertedWithCustomError(mockAccountBarz, 'AccountFacet__RestrictionsFailure') + }) + + it('Should execute transactions to a whitelisted address', async () => { + const whitelistedAddress = "0xf471789937856d80e589f5996cf8b0511ddd9de4" + + const addAddressCall = whitelistStorage.interface.encodeFunctionData('whitelistAddress', [barz.address, whitelistedAddress]) + const addAddressCallData = executeCallData(whitelistStorage.address, 0, addAddressCall) + const addTx = await callFromEntryPointOnK1(entryPoint, barz.address, owner, addAddressCallData) + const addReceipt = await addTx.wait() + expect(addReceipt.status).to.equal(1) + + await fund(accountBarz.address) + const transferCallData = executeCallData(whitelistedAddress, 0, "0x00") + const transferTx = await callFromEntryPointOnK1(entryPoint, barz.address, owner, transferCallData) + const transferReceipt = await transferTx.wait() + expect(transferReceipt.status).to.equal(1) + + const removeAddressCall = whitelistStorage.interface.encodeFunctionData('blacklistAddress', [barz.address, whitelistedAddress]) + const removeAddressCallData = executeCallData(whitelistStorage.address, 0, removeAddressCall) + const removeTx = await callFromEntryPointOnK1(entryPoint, barz.address, owner, removeAddressCallData) + const removeReceipt = await removeTx.wait() + expect(removeReceipt.status).to.equal(1) + }) + }) + + describe('# getRestrictions', () => { + let whitelistRestriction: WhitelistRestriction + + before(async () => { + barz = await barzFixture(accountFacet, k1Facet, entryPoint, facetRegistry, defaultFallbackHandler, owner.publicKey) + diamondCutBarz = await getFacetBarz('DiamondCutFacet', barz) + accountBarz = await getFacetBarz('AccountFacet', barz) + + await entryPoint.depositTo(barz.address, { + value: ethers.utils.parseEther('0.5'), + }) + + // Add restrictions facet + whitelistStorage = await whitelistStorageFixture() + whitelistRestriction = await whitelistRestrictionFixture(whitelistStorage) + const initCall = encodeRestrictionInitialization([whitelistRestriction.address]) + const addCut = diamondCut(restrictionsFacet.address, FacetCutAction.Add, restrictionsFacet) + const addCutCall = diamondCutFacet.interface.encodeFunctionData("diamondCut", [addCut, AddressZero, "0x00"]) + const addCutCallData = executeBatchCallData([barz.address, barz.address], [0, 0], [addCutCall, initCall]) + await callFromEntryPointOnK1(entryPoint, barz.address, owner, addCutCallData) + }) + + it('Should return the correct list of restrictions', async () => { + const restrictionsBarz = await getFacetBarz('RestrictionsFacet', barz) + expect((await restrictionsBarz.getRestrictions()).length).to.be.equal(1) + expect((await restrictionsBarz.getRestrictions())[0]).to.be.equal(whitelistRestriction.address) + }) + }) + + describe('# addRestriction', () => { + let whitelistRestriction: WhitelistRestriction + + before(async () => { + // Set up Barz + mockBarz = await barzFixture(accountFacet, k1Facet, mockEntrypoint, facetRegistry, defaultFallbackHandler, owner.publicKey) + mockRestrictionsBarz = await getFacetBarz("RestrictionsFacet", mockBarz) + mockAccountBarz = await getFacetBarz("AccountFacet", mockBarz) + mockDiamondCutBarz = await getFacetBarz("DiamondCutFacet", mockBarz) + + // Add whitelist restriction + const whitelistStorage = await whitelistStorageFixture() + whitelistRestriction = await whitelistRestrictionFixture(whitelistStorage) + const initCall = encodeRestrictionInitialization([whitelistRestriction.address]) + const addCut = diamondCut(restrictionsFacet.address, FacetCutAction.Add, restrictionsFacet) + const addCutCall = diamondCutFacet.interface.encodeFunctionData("diamondCut", [addCut, AddressZero, "0x00"]) + await expect(mockAccountBarz.connect(mockEntrypoint).executeBatch([mockAccountBarz.address, mockAccountBarz.address], [0, 0], [addCutCall, initCall])).to.emit(mockDiamondCutBarz, "DiamondCut") + + await entryPoint.depositTo(barz.address, { + value: ethers.utils.parseEther('0.5'), + }) + }) + + it('Should revert adding a duplicated restriction', async () => { + const addRestrictionCall = encodeRestrictionAddition(whitelistRestriction.address) + await expect(mockAccountBarz.connect(mockEntrypoint).execute(mockRestrictionsBarz.address, 0, addRestrictionCall)).to.be.revertedWithCustomError(mockRestrictionsBarz, "RestrictionsFacet__RestrictionAlreadyExists") + }) + + it('Should revert adding a zero address restriction', async () => { + const addRestrictionCall = encodeRestrictionAddition(AddressZero) + await expect(mockAccountBarz.connect(mockEntrypoint).execute(mockRestrictionsBarz.address, 0, addRestrictionCall)).to.be.revertedWithCustomError(mockRestrictionsBarz, "RestrictionsFacet__ZeroAddressRestrictions") + }) + + it('Should revert adding a restriction when the request does not come from barz', async () => { + const whitelistStorage2 = await whitelistStorageFixture() + const whitelistRestriction2 = await whitelistRestrictionFixture(whitelistStorage2) + + const [randomWallet] = await ethers.getSigners() + await expect(mockRestrictionsBarz.connect(randomWallet).addRestriction(whitelistRestriction2.address)).to.be.revertedWith("LibDiamond: Caller not self") + }) + + it('Should add a restriction when the request comes from barz', async () => { + const whitelistStorage2 = await whitelistStorageFixture() + const whitelistRestriction2 = await whitelistRestrictionFixture(whitelistStorage2) + + const addRestrictionCall = encodeRestrictionAddition(whitelistRestriction2.address) + await expect(mockAccountBarz.connect(mockEntrypoint).execute(mockBarz.address, 0, addRestrictionCall)).to.emit(mockRestrictionsBarz, "RestrictionAdded") + + const restrictions = await mockRestrictionsBarz.getRestrictions() + expect(restrictions[restrictions.length-1]).to.be.equal(whitelistRestriction2.address) + + await expect(mockAccountBarz.connect(mockEntrypoint).execute(mockRestrictionsBarz.address, 0, addRestrictionCall)).to.be.revertedWithCustomError(mockRestrictionsBarz, "RestrictionsFacet__RestrictionAlreadyExists") + }) + + }) + + describe('# removeRestriction', () => { + let whitelistRestriction1: WhitelistRestriction + let whitelistRestriction2: WhitelistRestriction + + before(async () => { + // Set up Barz + mockBarz = await barzFixture(accountFacet, k1Facet, mockEntrypoint, facetRegistry, defaultFallbackHandler, owner.publicKey) + mockRestrictionsBarz = await getFacetBarz("RestrictionsFacet", mockBarz) + mockAccountBarz = await getFacetBarz("AccountFacet", mockBarz) + mockDiamondCutBarz = await getFacetBarz("DiamondCutFacet", mockBarz) + + // Add whitelist restriction + whitelistRestriction1 = await whitelistRestrictionFixture(await whitelistStorageFixture()) + whitelistRestriction2 = await whitelistRestrictionFixture(await whitelistStorageFixture()) + + const initCall = encodeRestrictionInitialization([whitelistRestriction1.address, whitelistRestriction2.address]) + const addCut = diamondCut(restrictionsFacet.address, FacetCutAction.Add, restrictionsFacet) + const addCutCall = diamondCutFacet.interface.encodeFunctionData("diamondCut", [addCut, AddressZero, "0x00"]) + await expect(mockAccountBarz.connect(mockEntrypoint).executeBatch([mockAccountBarz.address, mockAccountBarz.address], [0, 0], [addCutCall, initCall])).to.emit(mockDiamondCutBarz, "DiamondCut") + + await entryPoint.depositTo(barz.address, { + value: ethers.utils.parseEther('0.5'), + }) + }) + + it('Should revert removing a restriction when it was not found', async () => { + const randomAddress = ethers.Wallet.createRandom().address; + const removeRestrictionCall = encodeRestrictionRemoval(randomAddress) + await expect(mockAccountBarz.connect(mockEntrypoint).execute(mockAccountBarz.address, 0, removeRestrictionCall)).to.be.revertedWithCustomError(mockRestrictionsBarz, "RestrictionsFacet__RestrictionNotFound") + }) + + it('Should revert adding a restriction when the request does not come from barz', async () => { + const [randomWallet] = await ethers.getSigners() + await expect(mockRestrictionsBarz.connect(randomWallet).removeRestriction(whitelistRestriction2.address)).to.be.revertedWith("LibDiamond: Caller not self") + }) + + it('Should be able to remove all restrictions except the last one', async () => { + const restrictionsBefore = await mockRestrictionsBarz.getRestrictions(); + const removeRestrictionCall = encodeRestrictionRemoval(whitelistRestriction2.address) + await expect(mockAccountBarz.connect(mockEntrypoint).execute(mockAccountBarz.address, 0, removeRestrictionCall)).to.emit(mockRestrictionsBarz, "RestrictionRemoved") + const restrictionsAfter = await mockRestrictionsBarz.getRestrictions(); + expect(restrictionsBefore.length - restrictionsAfter.length).to.be.equal(1) + + const removeRestrictionCall2 = encodeRestrictionRemoval(whitelistRestriction1.address) + await expect(mockAccountBarz.connect(mockEntrypoint).execute(mockBarz.address, 0, removeRestrictionCall2)).to.be.revertedWithCustomError(mockRestrictionsBarz, "RestrictionsFacet__RemainingRestrictionsCantBeEmpty") + }) + + it('Should be able to add a restriction that was previously removed', async () => { + const addRestrictionCall = encodeRestrictionAddition(whitelistRestriction2.address) + await expect(mockAccountBarz.connect(mockEntrypoint).execute(mockAccountBarz.address, 0, addRestrictionCall)).to.emit(mockRestrictionsBarz, "RestrictionAdded") + }) + }) +}) \ No newline at end of file diff --git a/test/Secp256k1VerificationFacet.test.ts b/test/Secp256k1VerificationFacet.test.ts new file mode 100644 index 0000000..41dea29 --- /dev/null +++ b/test/Secp256k1VerificationFacet.test.ts @@ -0,0 +1,194 @@ +import { ethers } from 'hardhat' +import { Wallet } from 'ethers' + +import { AccountFacet, DiamondCutFacet, Barz, Secp256k1VerificationFacet, SecurityManager, FacetRegistry, DiamondLoupeFacet, TokenReceiverFacet, DefaultFallbackHandler } from '../typechain-types' +import { fillUserOpDefaults, getUserOpHash, signUserOpK1Curve } from './utils/UserOp' +import { ecsign, toRpcSig, keccak256 as keccak256_buffer } from 'ethereumjs-util' +import { facetRegistryFixture } from './fixtures/FacetRegistryFixture' +import { getChainId } from './utils/helpers' +import { barzFixture } from './fixtures/BarzFixture' +import { AddressZero, createAccountOwner, fund, callGasLimit, verificationGasLimit, maxFeePerGas, getMessageHash} from './utils/testutils' +const { + getSelectors +} = require('./utils/diamond.js') +import { expect } from "chai" +import { secp256k1VerificationFacetFixture } from './fixtures/Secp256k1VerificationFacetFixture' +import { getFacetBarz, addFacetSelectorsViaEntryPointOnK1, setupDefaultSecuritManager } from './utils/setup' +import { diamondCutFacetFixture } from './fixtures/DiamondCutFacetFixture' +import { accountFacetFixture } from './fixtures/AccountFacetFixture' +import { EntryPoint } from '../typechain-types/core' +import { entryPointFixture } from './fixtures/EntryPointFixture' +import { diamondLoupeFacetFixture } from './fixtures/DiamondLoupeFacetFixture' +import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers' +import { tokenReceiverFacetFixture } from './fixtures/TokenReceiverFacetFixture' +import { defaultFallbackHandlerFixture } from './fixtures/DefaultFallbackHandlerFixture' + +describe('Secp256k1 Verification Facet', () => { + let invalidSigner: Wallet + let signer: Wallet + let chainId: number + let entryPoint: EntryPoint + let defaultFallbackHandler: DefaultFallbackHandler + let facetRegistry: FacetRegistry + let secp256k1VerificationFacet: Secp256k1VerificationFacet + let k1Barz: Secp256k1VerificationFacet + let diamondLoupeFacet: DiamondLoupeFacet + let tokenReceiverFacet: TokenReceiverFacet + let barz: Barz + let securityManager: SecurityManager + let securityManagerOwner: SignerWithAddress + let facetRegistryOwner: SignerWithAddress + let accountFacet: AccountFacet + let diamondCutFacet: DiamondCutFacet + + const enc = ethers.utils.defaultAbiCoder.encode(['string'], ["LOGIN to Trust Wallet Timestamp:1683119999"]) + const msgHash = ethers.utils.keccak256(enc) + const ethSignMsg = Buffer.concat([ + Buffer.from('\x19Ethereum Signed Message:\n32', 'ascii'), + Buffer.from(ethers.utils.arrayify(msgHash)) + ]) + const ethSignMsgHash = keccak256_buffer(ethSignMsg) + + before(async () => { + [securityManagerOwner, facetRegistryOwner] = await ethers.getSigners() + signer = createAccountOwner() + invalidSigner = createAccountOwner(1000) // just a random number + await fund(signer.address) + chainId = await getChainId() + securityManager = await setupDefaultSecuritManager(securityManagerOwner) + facetRegistry = await facetRegistryFixture(facetRegistryOwner.address) + diamondCutFacet = await diamondCutFacetFixture(securityManager) + accountFacet = await accountFacetFixture() + entryPoint = await entryPointFixture() + diamondLoupeFacet = await diamondLoupeFacetFixture() + tokenReceiverFacet = await tokenReceiverFacetFixture() + secp256k1VerificationFacet = await secp256k1VerificationFacetFixture() + defaultFallbackHandler = await defaultFallbackHandlerFixture(diamondCutFacet, accountFacet, tokenReceiverFacet, diamondLoupeFacet) + + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(secp256k1VerificationFacet.address, getSelectors(secp256k1VerificationFacet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(diamondCutFacet.address, getSelectors(diamondCutFacet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(diamondLoupeFacet.address, getSelectors(diamondLoupeFacet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(accountFacet.address, getSelectors(accountFacet)) + + barz = await barzFixture(accountFacet, secp256k1VerificationFacet, entryPoint, facetRegistry, defaultFallbackHandler, signer.publicKey) + await fund(barz.address) + + const diamondBarz = await getFacetBarz("DiamondCutFacet", barz) + const addedSelectors = [secp256k1VerificationFacet.interface.getSighash("validateSignature"), + secp256k1VerificationFacet.interface.getSighash("isValidKeyType"), + secp256k1VerificationFacet.interface.getSighash('validateOwnerSignatureSelector'), + secp256k1VerificationFacet.interface.getSighash('initializeSigner'), + secp256k1VerificationFacet.interface.getSighash('uninitializeSigner')] + await expect(addFacetSelectorsViaEntryPointOnK1(barz, signer, secp256k1VerificationFacet, addedSelectors, entryPoint)).to.emit(diamondBarz, "DiamondCut") + + k1Barz = await getFacetBarz("Secp256k1VerificationFacet", barz) + + }) + describe("# initializeSigner", () => { + it("Should revert if already initialized", async () => { + await expect(k1Barz.initializeSigner(invalidSigner.publicKey)).to.be.revertedWithCustomError(k1Barz, "LibAppStorage__SignerMustBeUninitialized") + }) + }) + describe("#uninitializeSigner", () => { + it("Should revert uninitialization if not middle of signature migration", async () => { + await expect(k1Barz.uninitializeSigner()).to.be.revertedWithCustomError(k1Barz, "LibAppStorage__AccountMustBeUninitialized") + }) + }) + describe("# validateOwnerSignature", () => { + it("Should verify valid ECDSA signature", async () => { + const userOp = signUserOpK1Curve(fillUserOpDefaults({ + sender: signer.address, + callGasLimit, + verificationGasLimit, + maxFeePerGas + }), signer, entryPoint.address, chainId) + const opHash = getUserOpHash(userOp, entryPoint.address, chainId) + const isSignatureValid = await k1Barz.validateOwnerSignature(userOp, opHash) + + // 0 equals success, 1 equals SIG_VALIDATION_FAILED + expect(isSignatureValid).to.equal(0) + }) + it("Should fail to verifiy invalid ECDSA signature", async () => { + const userOp = signUserOpK1Curve(fillUserOpDefaults({ + sender: signer.address, + callGasLimit, + verificationGasLimit, + maxFeePerGas + }), signer, AddressZero, chainId) + const opHash = getUserOpHash(userOp, entryPoint.address, chainId) + // userOp signed is using AddressZero for entrypoint address but userOpHash is generated with mockEntryPoint + const isSignatureValid = await k1Barz.validateOwnerSignature(userOp, opHash) + + // 0 equals success, 1 equals SIG_VALIDATION_FAILED + expect(isSignatureValid).to.equal(1) + }) + }) + describe("# validateSignature", () => { + it("Should return 0 for a valid signature", async () => { + const userOp = signUserOpK1Curve(fillUserOpDefaults({ + sender: signer.address, + callGasLimit, + verificationGasLimit, + maxFeePerGas + }), signer, entryPoint.address, chainId) + const opHash = getUserOpHash(userOp, entryPoint.address, chainId) + + // 0 equals success, 1 equals SIG_VALIDATION_FAILED + // signer signed the UserOp and validating it with signer -> verification success + expect(await k1Barz.validateSignature(userOp, opHash, signer.address.toLowerCase())).to.equal(0) + }) + it("Should return 1 for an invalid signature", async () => { + const randomSigner = ethers.Wallet.createRandom() + const userOp = signUserOpK1Curve(fillUserOpDefaults({ + sender: signer.address, + callGasLimit, + verificationGasLimit, + maxFeePerGas + }), randomSigner, entryPoint.address, chainId) + const opHash = getUserOpHash(userOp, entryPoint.address, chainId) + + // 0 equals success, 1 equals SIG_VALIDATION_FAILED + // signer signed the UserOp but validating it with owner -> verification fail + expect(await k1Barz.validateSignature(userOp, opHash, signer.address)).to.equal(1) + }) + }) + describe("# isValidKeyType", () => { + it("Should return true for a valid key length", async () => { + expect(await k1Barz.isValidKeyType(signer.publicKey)).to.equal(true) + expect(await k1Barz.isValidKeyType(signer.address)).to.equal(true) + }) + it("Should return false for an invalid key length", async () => { + expect(await k1Barz.isValidKeyType(signer.address + "000000")).to.equal(false) + }) + it("Should return false for an invalid key type", async () => { + const publicKey = "0x02" + signer.publicKey.substring(4) + expect(await k1Barz.isValidKeyType(publicKey)).to.equal(false) + }) + }) + describe("# owner", () => { + it("Should return valid owner public key", async () => { + expect(await k1Barz.owner()).to.equal(signer.address.toLowerCase()) + }) + }) + describe("# validateOwnerSignatureSelector", () => { + it("Should return valid selector", async () => { + expect(await k1Barz.validateOwnerSignatureSelector()).to.equal(k1Barz.interface.getSighash('validateOwnerSignature')) + }) + }) + describe("EIP-1271 # isValidSignature", async () => { + it("Should return EIP-1271 magic value if signature is valid", async () => { + const finalHash = await getMessageHash(ethSignMsgHash, await getChainId(), k1Barz.address) + + const sig = ecsign(Buffer.from(ethers.utils.arrayify(finalHash)), Buffer.from(ethers.utils.arrayify(signer.privateKey))) + const signedMessage = toRpcSig(sig.v, sig.r, sig.s) + expect(await k1Barz.isValidSignature(ethSignMsgHash, signedMessage)).to.equal("0x1626ba7e") + }) + it("Should return dummy value when signature is invalid", async () => { + const finalHash = await getMessageHash(ethSignMsgHash, await getChainId(), k1Barz.address) + + const sig = ecsign(Buffer.from(ethers.utils.arrayify(finalHash)), Buffer.from(ethers.utils.arrayify(invalidSigner.privateKey))) + const signedMessage = toRpcSig(sig.v, sig.r, sig.s) + expect(await k1Barz.isValidSignature(ethSignMsgHash, signedMessage)).to.equal("0xffffffff") + }) + }) +}) \ No newline at end of file diff --git a/test/Secp256r1VerificationFacet.test.ts b/test/Secp256r1VerificationFacet.test.ts new file mode 100644 index 0000000..ccdfaae --- /dev/null +++ b/test/Secp256r1VerificationFacet.test.ts @@ -0,0 +1,398 @@ +import { ethers } from 'hardhat' +import { Wallet, BigNumber } from 'ethers' +import { + defaultAbiCoder, + concat, + hexZeroPad, + hexlify, + sha256, + toUtf8Bytes +} from 'ethers/lib/utils' +const { + getSelectors +} = require('./utils/diamond.js') +import { AccountFacet, DiamondCutFacet, Barz, Secp256r1VerificationFacet, SecurityManager, FacetRegistry, DiamondLoupeFacet, TokenReceiverFacet, DefaultFallbackHandler } from '../typechain-types' +import { fillUserOpDefaults, getUserOpHash, signUserOpR1Curve } from './utils/UserOp' +import { getChainId, generateKeyPair, guardianSecurityPeriod, guardianSecurityWindow, recoveryPeriod, lockPeriod, approvalValidationPeriod, migrationPeriod, getEthSignMessageHash } from './utils/helpers' + +import { UserOperation } from './utils/UserOperation' +import { diamondCutFacetFixture } from './fixtures/DiamondCutFacetFixture' +import { accountFacetFixture } from './fixtures/AccountFacetFixture' +import { secp256r1VerificationFacetFixture } from './fixtures/Secp256r1VerificationFacetFixture' +import { facetRegistryFixture } from './fixtures/FacetRegistryFixture' +import { barzFixture } from './fixtures/BarzFixture' +import { createAccountOwner, fund, verificationGasLimit, maxFeePerGas, generateExampleMsgHash} from './utils/testutils' +import base64url from 'base64url' + +import { expect } from "chai" +import { getFacetBarz, setupContracts, addFacetSelectorsViaEntryPointOnR1, setupDefaultSecuritManager } from './utils/setup' +import { EntryPoint } from '../typechain-types/core' +import { entryPointFixture } from './fixtures/EntryPointFixture' +import { diamondLoupeFacetFixture } from './fixtures/DiamondLoupeFacetFixture' +import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers' +import { tokenReceiverFacetFixture } from './fixtures/TokenReceiverFacetFixture' +import { defaultFallbackHandlerFixture } from './fixtures/DefaultFallbackHandlerFixture' + +const callGasLimit = 200000 + +describe('Secp256r1 Verification Facet', () => { + let signer: Wallet + let chainId: number + let entryPoint: EntryPoint + let defaultFallbackHandler: DefaultFallbackHandler + let userOp: UserOperation + let r1Barz: Secp256r1VerificationFacet + let barz: Barz + let securityManager: SecurityManager + let facetRegistry: FacetRegistry + let diamondLoupeFacet: DiamondLoupeFacet + let tokenReceiverFacet: TokenReceiverFacet + let accountFacet: AccountFacet + let diamondCutFacet: DiamondCutFacet + let secp256r1VerificationFacet: Secp256r1VerificationFacet + let securityManagerOwner: SignerWithAddress + let facetRegistryOwner: SignerWithAddress + const clientDataJSONPre = '{"type":"webauthn.get","challenge":"' + const clientDataJSONPost = '","origin":"https://webauthn.me","crossOrigin":false}' + const authenticatorData = concat([ + hexZeroPad("0xf95bc73828ee210f9fd3bbe72d97908013b0a3759e9aea3d0ae318766cd2e1ad", 32), + hexlify("0x0500000000") + ]) + + before(async () => { + [securityManagerOwner, facetRegistryOwner] = await ethers.getSigners() + signer = createAccountOwner() + await fund(signer.address) + chainId = await getChainId() + entryPoint = await entryPointFixture() + }) + const setupR1Barz = async (keyPair: any, publicKeyBytes: any) => { + securityManager = await setupDefaultSecuritManager(securityManagerOwner) + facetRegistry = await facetRegistryFixture(facetRegistryOwner.address) + diamondCutFacet = await diamondCutFacetFixture(securityManager) + accountFacet = await accountFacetFixture() + secp256r1VerificationFacet = await secp256r1VerificationFacetFixture() + diamondLoupeFacet = await diamondLoupeFacetFixture() + tokenReceiverFacet = await tokenReceiverFacetFixture() + defaultFallbackHandler = await defaultFallbackHandlerFixture(diamondCutFacet, accountFacet, tokenReceiverFacet, diamondLoupeFacet) + + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(accountFacet.address, getSelectors(accountFacet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(secp256r1VerificationFacet.address, getSelectors(secp256r1VerificationFacet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(diamondCutFacet.address, getSelectors(diamondCutFacet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(diamondLoupeFacet.address, getSelectors(diamondLoupeFacet)) + barz = await barzFixture(accountFacet, secp256r1VerificationFacet, entryPoint, facetRegistry, defaultFallbackHandler, publicKeyBytes) + + await entryPoint.depositTo(barz.address, { + value: ethers.utils.parseEther('0.5'), + }) + + r1Barz = await getFacetBarz("Secp256r1VerificationFacet", barz) + await addFacetSelectorsViaEntryPointOnR1(barz, keyPair, secp256r1VerificationFacet, [secp256r1VerificationFacet.interface.getSighash("validateSignature"), secp256r1VerificationFacet.interface.getSighash("isValidKeyType"), secp256r1VerificationFacet.interface.getSighash("validateOwnerSignatureSelector"), secp256r1VerificationFacet.interface.getSighash("initializeSigner"), secp256r1VerificationFacet.interface.getSighash("uninitializeSigner")], entryPoint) // validateSignature() + return r1Barz + } + describe("# initializeSigner", () => { + it("Should revert if already initialized", async () => { + const { keyPair, publicKeyBytes } = generateKeyPair() + await setupR1Barz(keyPair, publicKeyBytes) + + await expect(r1Barz.initializeSigner(publicKeyBytes)).to.be.revertedWithCustomError(r1Barz, "LibAppStorage__SignerMustBeUninitialized") + }) + }) + describe("# uninitializeSigner", () => { + it("Should revert uninitialization if not middle of signature migration", async () => { + const { keyPair, publicKeyBytes } = generateKeyPair() + + await setupR1Barz(keyPair, publicKeyBytes) + r1Barz = await getFacetBarz("Secp256r1VerificationFacet", barz) + await expect(r1Barz.initializeSigner(publicKeyBytes)).to.be.revertedWithCustomError(r1Barz, "LibAppStorage__SignerMustBeUninitialized") + }) + }) + describe("# validateOwnerSignature", () => { + it("Should verify valid secp256r1 (passkeys) signature, which is pre-signed using https://webauthn.me", async () => { + const chainId = 97 + const callGasLimit = 200000 + const verificationGasLimit = 100000 + const maxFeePerGas = 1 + const nonce = 0 + const entryPoint = await ethers.getImpersonatedSigner("0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789") + const publicKey = ["c1a5218eec6bbdbf32fca43a9dbc4ad4bde65de9b3f20302149e351c7a5405e9", "cdcebc06a30a01550357bea4a5cf4b84e2f6cd9cf8613b61838c7c0a8149432f"] + const publicKeyBytes = "0x04" + publicKey.join("") + const { barz } = await setupContracts(facetRegistryOwner, securityManagerOwner, entryPoint, publicKeyBytes, guardianSecurityPeriod, guardianSecurityWindow, recoveryPeriod, lockPeriod, approvalValidationPeriod, migrationPeriod, true) + r1Barz = await getFacetBarz("Secp256r1VerificationFacet", barz) + + const signature = ethers.utils.defaultAbiCoder.encode( + ['uint256', 'uint256', 'bytes', 'string', 'string'], + [ + ethers.BigNumber.from("0x7f9576ce011a928c5d595b7ad8ce62aed73df49755c24f0d107c0f16988b27c7"), + ethers.BigNumber.from("0x9430dd40f06e792938e7c0cbfcaf64101c552923e0cd7a897b4f9e83330bb695"), + ethers.utils.concat([ + ethers.utils.hexZeroPad("0xf95bc73828ee210f9fd3bbe72d97908013b0a3759e9aea3d0ae318766cd2e1ad", 32), + ethers.utils.hexlify("0x0500000000") + ]), + '{"type":"webauthn.get","challenge":"', + '","origin":"https://webauthn.me","crossOrigin":false}' + ] + ) + + userOp = fillUserOpDefaults({ + sender: signer.address, + callGasLimit, + verificationGasLimit, + maxFeePerGas, + nonce, + signature + }) + + const userOpHash = getUserOpHash(userOp, entryPoint.address, chainId) + + // 0 equals success, 1 equals SIG_VALIDATION_FAILED + expect(await r1Barz.validateOwnerSignature(userOp, userOpHash)).to.equal(0) + expect(await r1Barz.validateOwnerSignature(userOp, userOpHash.slice(0, -6) + '000000')).to.equal(1) + }) + + it("Should verify valid secp256r1 (passkeys) signature, which is generated on fly", async () => { + const { keyPair, publicKeyBytes } = generateKeyPair() + + const { barz } = await setupContracts(facetRegistryOwner, securityManagerOwner, entryPoint, publicKeyBytes, guardianSecurityPeriod, guardianSecurityWindow, recoveryPeriod, lockPeriod, approvalValidationPeriod, migrationPeriod, true) + r1Barz = await getFacetBarz("Secp256r1VerificationFacet", barz) + + const userOp = signUserOpR1Curve(fillUserOpDefaults({ + sender: barz.address, + callGasLimit, + verificationGasLimit, + maxFeePerGas + }), keyPair, entryPoint.address, chainId) + const userOpHash = getUserOpHash(userOp, entryPoint.address, chainId) + + // 0 equals success, 1 equals SIG_VALIDATION_FAILED + expect(await r1Barz.validateOwnerSignature(userOp, userOpHash)).to.equal(0) + expect(await r1Barz.validateOwnerSignature(userOp, userOpHash.slice(0, -6) + '000000')).to.equal(1) + }) + it("Should fail r = 0 and s = 0 signature verification from Vitalik's address", async () => { + const chainId = 31337 + const entryPoint = await ethers.getImpersonatedSigner("0x70997970C51812dc3A010C7d01b50e0d17dc79C8") + const publicKey = ["a620a8cfc88fd062b11eab31663e56cad95278bef612959be214d98779f645b8", "4e7b905b42917570148b0432f99ba21f2e7eebe018cbf837247e38150a89f771"] + const publicKeyBytes = "0x04" + publicKey.join("") + const { barz } = await setupContracts(facetRegistryOwner, securityManagerOwner, entryPoint, publicKeyBytes, guardianSecurityPeriod, guardianSecurityWindow, recoveryPeriod, lockPeriod, approvalValidationPeriod, migrationPeriod, true) + r1Barz = await getFacetBarz("Secp256r1VerificationFacet", barz) + + const signature = ethers.utils.defaultAbiCoder.encode( + ['uint256', 'uint256', 'bytes', 'string', 'string'], + [ + ethers.BigNumber.from("0"), + ethers.BigNumber.from("0"), + ethers.utils.concat([ + ethers.utils.hexZeroPad("0xf95bc73828ee210f9fd3bbe72d97908013b0a3759e9aea3d0ae318766cd2e1ad", 32), + ethers.utils.hexlify("0x0500000000") + ]), + '{"type":"webauthn.get","challenge":"', + '","origin":"https://webauthn.me","crossOrigin":false}' + ] + ) + + userOp = fillUserOpDefaults({ + sender: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045", + callGasLimit, + verificationGasLimit, + maxFeePerGas, + signature + }) + const userOpHash = getUserOpHash(userOp, entryPoint.address, chainId) + + // 0 equals success, 1 equals SIG_VALIDATION_FAILED. + expect(await r1Barz.validateOwnerSignature(userOp, userOpHash)).to.equal(1) + expect(await r1Barz.validateOwnerSignature(userOp, userOpHash.slice(0, -6) + '000000')).to.equal(1) + }) + it("Should fail valid (passkeys) signature validation if public key in not a point in elliptic curve", async () => { + const chainId = 97 + const callGasLimit = 200000 + const verificationGasLimit = 100000 + const maxFeePerGas = 1 + const nonce = 0 + const entryPoint = await ethers.getImpersonatedSigner("0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789") + const publicKey = ["c1a5218eec6bbdbf32fca43a9dbc4ad4bde65de9b3f20302149e351c7a540000", "cdcebc06a30a01550357bea4a5cf4b84e2f6cd9cf8613b61838c7c0a8149432f"] + const publicKeyBytes = "0x04" + publicKey.join("") + const { barz } = await setupContracts(facetRegistryOwner, securityManagerOwner, entryPoint, publicKeyBytes, guardianSecurityPeriod, guardianSecurityWindow, recoveryPeriod, lockPeriod, approvalValidationPeriod, migrationPeriod, true) + r1Barz = await getFacetBarz("Secp256r1VerificationFacet", barz) + + const signature = ethers.utils.defaultAbiCoder.encode( + ['uint256', 'uint256', 'bytes', 'string', 'string'], + [ + ethers.BigNumber.from("0x7f9576ce011a928c5d595b7ad8ce62aed73df49755c24f0d107c0f16988b27c7"), + ethers.BigNumber.from("0x9430dd40f06e792938e7c0cbfcaf64101c552923e0cd7a897b4f9e83330bb695"), + ethers.utils.concat([ + ethers.utils.hexZeroPad("0xf95bc73828ee210f9fd3bbe72d97908013b0a3759e9aea3d0ae318766cd2e1ad", 32), + ethers.utils.hexlify("0x0500000000") + ]), + '{"type":"webauthn.get","challenge":"', + '","origin":"https://webauthn.me","crossOrigin":false}' + ] + ) + + userOp = fillUserOpDefaults({ + sender: signer.address, + callGasLimit, + verificationGasLimit, + maxFeePerGas, + nonce, + signature, + }) + const userOpHash = getUserOpHash(userOp, entryPoint.address, chainId) + + // 0 equals success, 1 equals SIG_VALIDATION_FAILED + expect(await r1Barz.validateOwnerSignature(userOp, userOpHash)).to.equal(1) + expect(await r1Barz.validateOwnerSignature(userOp, userOpHash.slice(0, -6) + '000000')).to.equal(1) + }) + }) + + describe("# validateSignature", async () => { + it("Should return 0 for a valid signature", async () => { + const { keyPair, publicKeyBytes, keyX, keyY } = generateKeyPair() + await setupR1Barz(keyPair, publicKeyBytes) + + const userOp = signUserOpR1Curve(fillUserOpDefaults({ + sender: barz.address, + callGasLimit, + verificationGasLimit, + maxFeePerGas + }), keyPair, entryPoint.address, chainId) + const userOpHash = getUserOpHash(userOp, entryPoint.address, chainId) + + // 0 equals success, 1 equals SIG_VALIDATION_FAILED + expect(await r1Barz.validateSignature(userOp, userOpHash, [BigNumber.from("0x" + keyX.toString('hex')), BigNumber.from("0x" + keyY.toString('hex'))])).to.equal(0) + }) + it("Should return 1 for an invalid signature", async () => { + const { keyPair, publicKeyBytes } = generateKeyPair() + const invalidKey = generateKeyPair() + await setupR1Barz(keyPair, publicKeyBytes) + + const userOp = signUserOpR1Curve(fillUserOpDefaults({ + sender: barz.address, + callGasLimit, + verificationGasLimit, + maxFeePerGas + }), keyPair, entryPoint.address, chainId) + const userOpHash = getUserOpHash(userOp, entryPoint.address, chainId) + + // 0 equals success, 1 equals SIG_VALIDATION_FAILED + expect(await r1Barz.validateSignature(userOp, userOpHash, [BigNumber.from("0x" + invalidKey.keyX.toString('hex')), BigNumber.from("0x" + invalidKey.keyY.toString('hex'))])).to.equal(1) + }) + }) + describe("# isValidKeyType", async () => { + it("Should return true for a valid key length", async () => { + const { keyPair, publicKeyBytes } = generateKeyPair() + await setupR1Barz(keyPair, publicKeyBytes) + expect(await r1Barz.isValidKeyType(publicKeyBytes)).to.equal(true) + }) + it("Should return false for an invalid key length", async () => { + const { keyPair, publicKeyBytes } = generateKeyPair() + await setupR1Barz(keyPair, publicKeyBytes) + expect(await r1Barz.isValidKeyType(publicKeyBytes.slice(0, 6))).to.equal(false) + }) + + it("Should return false for an invalid key type", async () => { + const { keyPair, publicKeyBytes } = generateKeyPair() + await setupR1Barz(keyPair, publicKeyBytes) + expect(await r1Barz.isValidKeyType("0x02" + publicKeyBytes.substring(4))).to.equal(false) + }) + }) + describe("# owner", async () => { + it("Should return valid owner public key", async () => { + const { keyPair, publicKeyBytes, facetOwnerKey } = generateKeyPair() + await setupR1Barz(keyPair, publicKeyBytes) + const owner = await r1Barz.owner() + expect(owner).to.equal(facetOwnerKey) + }) + }) + describe("# validateOwnerSignatureSelector", async () => { + it("Should return valid selector", async () => { + const { keyPair, publicKeyBytes } = generateKeyPair() + await setupR1Barz(keyPair, publicKeyBytes) + expect(await r1Barz.validateOwnerSignatureSelector()).to.equal(r1Barz.interface.getSighash('validateOwnerSignature')) + }) + }) + describe("EIP-1271 # isValidSignature", async () => { + it("Should return EIP-1271 magic value if signature is valid(signMessage)", async () => { + const { keyPair, publicKeyBytes } = generateKeyPair() + await setupR1Barz(keyPair, publicKeyBytes) + + const msgHash = generateExampleMsgHash() + const ethSignMsgHash = getEthSignMessageHash(msgHash) + + const opHashBase64 = base64url.encode(concat([ethSignMsgHash])) + const clientDataJSON = clientDataJSONPre + opHashBase64 + clientDataJSONPost + + const clientHash = sha256(toUtf8Bytes(clientDataJSON)).toString() + const authenticatorDataHEX = hexlify(authenticatorData) + const sigHash = sha256(concat([authenticatorDataHEX, clientHash])).slice(2) + const signature = keyPair.sign(sigHash) + const signedMessage = defaultAbiCoder.encode( + ['uint256', 'uint256', 'bytes', 'string', 'string'], + [ + BigNumber.from("0x" + signature.r.toString('hex')), + BigNumber.from("0x" + signature.s.toString('hex')), + authenticatorData, + clientDataJSONPre, + clientDataJSONPost + ] + ) + + expect(await r1Barz.isValidSignature(ethSignMsgHash, signedMessage)).to.equal("0x1626ba7e") + }) + it("Should return EIP-1271 magic value if signature is valid(rawHash)", async () => { + const { keyPair, publicKeyBytes } = generateKeyPair() + await setupR1Barz(keyPair, publicKeyBytes) + + const msgHash = generateExampleMsgHash() + + const opHashBase64 = base64url.encode(concat([msgHash])) + const clientDataJSON = clientDataJSONPre + opHashBase64 + clientDataJSONPost + + const clientHash = sha256(toUtf8Bytes(clientDataJSON)).toString() + const authenticatorDataHEX = hexlify(authenticatorData) + const sigHash = sha256(concat([authenticatorDataHEX, clientHash])).slice(2) + const signature = keyPair.sign(sigHash) + const signedMessage = defaultAbiCoder.encode( + ['uint256', 'uint256', 'bytes', 'string', 'string'], + [ + BigNumber.from("0x" + signature.r.toString('hex')), + BigNumber.from("0x" + signature.s.toString('hex')), + authenticatorData, + clientDataJSONPre, + clientDataJSONPost + ] + ) + + expect(await r1Barz.isValidSignature(msgHash, signedMessage)).to.equal("0x1626ba7e") + }) + it("Should return dummy value when signature is invalid", async () => { + const { keyPair, publicKeyBytes } = generateKeyPair() + const invalidKey = generateKeyPair() + await setupR1Barz(keyPair, publicKeyBytes) + + const msgHash = generateExampleMsgHash() + const ethSignMsgHash = getEthSignMessageHash(msgHash) + + const opHashBase64 = base64url.encode(concat([ethSignMsgHash])) + const clientDataJSON = clientDataJSONPre + opHashBase64 + clientDataJSONPost + + const clientHash = sha256(toUtf8Bytes(clientDataJSON)).toString() + const authenticatorDataHEX = hexlify(authenticatorData) + const sigHash = sha256(concat([authenticatorDataHEX, clientHash])).slice(2) + // Signing with invalid key pair + const signature = invalidKey.keyPair.sign(sigHash) + const signedMessage = defaultAbiCoder.encode( + ['uint256', 'uint256', 'bytes', 'string', 'string'], + [ + BigNumber.from("0x" + signature.r.toString('hex')), + BigNumber.from("0x" + signature.s.toString('hex')), + authenticatorData, + clientDataJSONPre, + clientDataJSONPost + ] + ) + + expect(await r1Barz.isValidSignature(ethSignMsgHash, signedMessage)).to.equal("0xffffffff") + }) + }) +}) \ No newline at end of file diff --git a/test/Secp256r1VerificationFacetV2.test.ts b/test/Secp256r1VerificationFacetV2.test.ts new file mode 100644 index 0000000..ff65ba2 --- /dev/null +++ b/test/Secp256r1VerificationFacetV2.test.ts @@ -0,0 +1,393 @@ +import { ethers } from 'hardhat' +import { Wallet, BigNumber } from 'ethers' +import { + defaultAbiCoder, + concat, + hexZeroPad, + hexlify, + sha256, + toUtf8Bytes +} from 'ethers/lib/utils' +import elliptic from 'elliptic' +const { + getSelectors +} = require('./utils/diamond.js') +import { AccountFacet, DiamondCutFacet, Barz, Secp256r1VerificationFacetV2, SecurityManager, FacetRegistry, DiamondLoupeFacet, TokenReceiverFacet, DefaultFallbackHandler } from '../typechain-types' +import { adjustS, fillUserOpDefaults, getUserOpHash, signUserOpR1Curve } from './utils/UserOp' +import { getChainId, generateKeyPair, guardianSecurityPeriod, guardianSecurityWindow, recoveryPeriod, lockPeriod, approvalValidationPeriod, migrationPeriod } from './utils/helpers' + +import { UserOperation } from './utils/UserOperation' +import { keccak256 as keccak256_buffer } from 'ethereumjs-util' +import BN from 'bn.js'; +import { diamondCutFacetFixture } from './fixtures/DiamondCutFacetFixture' +import { accountFacetFixture } from './fixtures/AccountFacetFixture' +import { secp256r1VerificationFacetV2Fixture } from './fixtures/Secp256r1VerificationFacetV2Fixture' +import { facetRegistryFixture } from './fixtures/FacetRegistryFixture' +import { barzFixture } from './fixtures/BarzFixture' +import { createAccountOwner, fund, verificationGasLimit, maxFeePerGas, getMessageHash } from './utils/testutils' +import base64url from 'base64url' + +import { expect } from "chai" +import { getFacetBarz, setupContracts, addFacetSelectorsViaEntryPointOnR1, setupDefaultSecuritManager } from './utils/setup' +import { EntryPoint } from '../typechain-types/core' +import { entryPointFixture } from './fixtures/EntryPointFixture' +import { diamondLoupeFacetFixture } from './fixtures/DiamondLoupeFacetFixture' +import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers' +import { tokenReceiverFacetFixture } from './fixtures/TokenReceiverFacetFixture' +import { defaultFallbackHandlerFixture } from './fixtures/DefaultFallbackHandlerFixture' + +const callGasLimit = 200000 + +describe('Secp256r1 Verification Facet', () => { + let signer: Wallet + let chainId: number + let entryPoint: EntryPoint + let defaultFallbackHandler: DefaultFallbackHandler + let userOp: UserOperation + let r1Barz: Secp256r1VerificationFacetV2 + let barz: Barz + let securityManager: SecurityManager + let facetRegistry: FacetRegistry + let diamondLoupeFacet: DiamondLoupeFacet + let tokenReceiverFacet: TokenReceiverFacet + let accountFacet: AccountFacet + let diamondCutFacet: DiamondCutFacet + let secp256r1VerificationFacetV2: Secp256r1VerificationFacetV2 + let securityManagerOwner: SignerWithAddress + let facetRegistryOwner: SignerWithAddress + const clientDataJSONPre = '{"type":"webauthn.get","challenge":"' + const clientDataJSONPost = '","origin":"https://webauthn.me","crossOrigin":false}' + const authenticatorData = concat([ + hexZeroPad("0xf95bc73828ee210f9fd3bbe72d97908013b0a3759e9aea3d0ae318766cd2e1ad", 32), + hexlify("0x0500000000") + ]) + const ec = new elliptic.ec('p256') + + before(async () => { + [securityManagerOwner, facetRegistryOwner] = await ethers.getSigners() + signer = createAccountOwner() + await fund(signer.address) + chainId = await getChainId() + entryPoint = await entryPointFixture() + }) + const setupR1Barz = async (keyPair: any, publicKeyBytes: any) => { + securityManager = await setupDefaultSecuritManager(securityManagerOwner) + facetRegistry = await facetRegistryFixture(facetRegistryOwner.address) + diamondCutFacet = await diamondCutFacetFixture(securityManager) + accountFacet = await accountFacetFixture() + secp256r1VerificationFacetV2 = await secp256r1VerificationFacetV2Fixture() + diamondLoupeFacet = await diamondLoupeFacetFixture() + tokenReceiverFacet = await tokenReceiverFacetFixture() + defaultFallbackHandler = await defaultFallbackHandlerFixture(diamondCutFacet, accountFacet, tokenReceiverFacet, diamondLoupeFacet) + + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(accountFacet.address, getSelectors(accountFacet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(secp256r1VerificationFacetV2.address, getSelectors(secp256r1VerificationFacetV2)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(diamondCutFacet.address, getSelectors(diamondCutFacet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(diamondLoupeFacet.address, getSelectors(diamondLoupeFacet)) + barz = await barzFixture(accountFacet, secp256r1VerificationFacetV2, entryPoint, facetRegistry, defaultFallbackHandler, publicKeyBytes) + + await entryPoint.depositTo(barz.address, { + value: ethers.utils.parseEther('0.5'), + }) + + r1Barz = await getFacetBarz("Secp256r1VerificationFacetV2", barz) + + await addFacetSelectorsViaEntryPointOnR1(barz, keyPair, secp256r1VerificationFacetV2, [secp256r1VerificationFacetV2.interface.getSighash("validateSignature"), secp256r1VerificationFacetV2.interface.getSighash("isValidKeyType"), secp256r1VerificationFacetV2.interface.getSighash("validateOwnerSignatureSelector"), secp256r1VerificationFacetV2.interface.getSighash("initializeSigner"), secp256r1VerificationFacetV2.interface.getSighash("uninitializeSigner")], entryPoint) // validateSignature() + + return r1Barz + } + describe("# initializeSigner", () => { + it("Should revert if already initialized", async () => { + const { keyPair, publicKeyBytes } = generateKeyPair() + await setupR1Barz(keyPair, publicKeyBytes) + + await expect(r1Barz.initializeSigner(publicKeyBytes)).to.be.revertedWithCustomError(r1Barz, "LibAppStorage__SignerMustBeUninitialized") + }) + }) + describe("# uninitializeSigner", () => { + it("Should revert uninitialization if not middle of signature migration", async () => { + const { keyPair, publicKeyBytes } = generateKeyPair() + + await setupR1Barz(keyPair, publicKeyBytes) + r1Barz = await getFacetBarz("Secp256r1VerificationFacet", barz) + await expect(r1Barz.uninitializeSigner()).to.be.revertedWithCustomError(r1Barz, "LibAppStorage__AccountMustBeUninitialized") + }) + }) + describe("# validateOwnerSignature", () => { + it("Should verify valid secp256r1 (passkeys) signature, which is pre-signed using https://webauthn.me", async () => { + const chainId = 97 + const callGasLimit = 200000 + const verificationGasLimit = 100000 + const maxFeePerGas = 1 + const nonce = 0 + const entryPoint = await ethers.getImpersonatedSigner("0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789") + const publicKey = ["c1a5218eec6bbdbf32fca43a9dbc4ad4bde65de9b3f20302149e351c7a5405e9", "cdcebc06a30a01550357bea4a5cf4b84e2f6cd9cf8613b61838c7c0a8149432f"] + const publicKeyBytes = "0x04" + publicKey.join("") + const { barz } = await setupContracts(facetRegistryOwner, securityManagerOwner, entryPoint, publicKeyBytes, guardianSecurityPeriod, guardianSecurityWindow, recoveryPeriod, lockPeriod, approvalValidationPeriod, migrationPeriod, true, true) + r1Barz = await getFacetBarz("Secp256r1VerificationFacetV2", barz) + const hexString = "0x9430dd40f06e792938e7c0cbfcaf64101c552923e0cd7a897b4f9e83330bb695" + const originS = new BN(hexString.slice(2), 'hex') + const sValue = adjustS(originS, ec.n) + const signature = ethers.utils.defaultAbiCoder.encode( + ['uint256', 'uint256', 'bytes', 'string', 'string'], + [ + ethers.BigNumber.from("0x7f9576ce011a928c5d595b7ad8ce62aed73df49755c24f0d107c0f16988b27c7"), + ethers.BigNumber.from(sValue.toString()), + ethers.utils.concat([ + ethers.utils.hexZeroPad("0xf95bc73828ee210f9fd3bbe72d97908013b0a3759e9aea3d0ae318766cd2e1ad", 32), + ethers.utils.hexlify("0x0500000000") + ]), + '{"type":"webauthn.get","challenge":"', + '","origin":"https://webauthn.me","crossOrigin":false}' + ] + ) + + userOp = fillUserOpDefaults({ + sender: signer.address, + callGasLimit, + verificationGasLimit, + maxFeePerGas, + nonce, + signature + }) + + const userOpHash = getUserOpHash(userOp, entryPoint.address, chainId) + + // 0 equals success, 1 equals SIG_VALIDATION_FAILED + expect(await r1Barz.validateOwnerSignature(userOp, userOpHash)).to.equal(0) + expect(await r1Barz.validateOwnerSignature(userOp, userOpHash.slice(0, -6) + '000000')).to.equal(1) + }) + + it("Should verify valid secp256r1 (passkeys) signature, which is generated on fly", async () => { + const { keyPair, publicKeyBytes } = generateKeyPair() + + const { barz } = await setupContracts(facetRegistryOwner, securityManagerOwner, entryPoint, publicKeyBytes, guardianSecurityPeriod, guardianSecurityWindow, recoveryPeriod, lockPeriod, approvalValidationPeriod, migrationPeriod, true, true) + r1Barz = await getFacetBarz("Secp256r1VerificationFacetV2", barz) + + const userOp = signUserOpR1Curve(fillUserOpDefaults({ + sender: barz.address, + callGasLimit, + verificationGasLimit, + maxFeePerGas + }), keyPair, entryPoint.address, chainId) + const userOpHash = getUserOpHash(userOp, entryPoint.address, chainId) + + // 0 equals success, 1 equals SIG_VALIDATION_FAILED + expect(await r1Barz.validateOwnerSignature(userOp, userOpHash)).to.equal(0) + expect(await r1Barz.validateOwnerSignature(userOp, userOpHash.slice(0, -6) + '000000')).to.equal(1) + }) + it("Should fail r = 0 and s = 0 signature verification from Vitalik's address", async () => { + const chainId = 31337 + const entryPoint = await ethers.getImpersonatedSigner("0x70997970C51812dc3A010C7d01b50e0d17dc79C8") + const publicKey = ["a620a8cfc88fd062b11eab31663e56cad95278bef612959be214d98779f645b8", "4e7b905b42917570148b0432f99ba21f2e7eebe018cbf837247e38150a89f771"] + const publicKeyBytes = "0x04" + publicKey.join("") + const { barz } = await setupContracts(facetRegistryOwner, securityManagerOwner, entryPoint, publicKeyBytes, guardianSecurityPeriod, guardianSecurityWindow, recoveryPeriod, lockPeriod, approvalValidationPeriod, migrationPeriod, true, true) + r1Barz = await getFacetBarz("Secp256r1VerificationFacet", barz) + + const signature = ethers.utils.defaultAbiCoder.encode( + ['uint256', 'uint256', 'bytes', 'string', 'string'], + [ + ethers.BigNumber.from("0"), + ethers.BigNumber.from("0"), + ethers.utils.concat([ + ethers.utils.hexZeroPad("0xf95bc73828ee210f9fd3bbe72d97908013b0a3759e9aea3d0ae318766cd2e1ad", 32), + ethers.utils.hexlify("0x0500000000") + ]), + '{"type":"webauthn.get","challenge":"', + '","origin":"https://webauthn.me","crossOrigin":false}' + ] + ) + + userOp = fillUserOpDefaults({ + sender: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045", + callGasLimit, + verificationGasLimit, + maxFeePerGas, + signature + }) + const userOpHash = getUserOpHash(userOp, entryPoint.address, chainId) + + // 0 equals success, 1 equals SIG_VALIDATION_FAILED. + expect(await r1Barz.validateOwnerSignature(userOp, userOpHash)).to.equal(1) + expect(await r1Barz.validateOwnerSignature(userOp, userOpHash.slice(0, -6) + '000000')).to.equal(1) + }) + it("Should fail valid (passkeys) signature validation if public key in not a point in elliptic curve", async () => { + const chainId = 97 + const callGasLimit = 200000 + const verificationGasLimit = 100000 + const maxFeePerGas = 1 + const nonce = 0 + const entryPoint = await ethers.getImpersonatedSigner("0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789") + const publicKey = ["c1a5218eec6bbdbf32fca43a9dbc4ad4bde65de9b3f20302149e351c7a540000", "cdcebc06a30a01550357bea4a5cf4b84e2f6cd9cf8613b61838c7c0a8149432f"] + const publicKeyBytes = "0x04" + publicKey.join("") + const { barz } = await setupContracts(facetRegistryOwner, securityManagerOwner, entryPoint, publicKeyBytes, guardianSecurityPeriod, guardianSecurityWindow, recoveryPeriod, lockPeriod, approvalValidationPeriod, migrationPeriod, true, true) + r1Barz = await getFacetBarz("Secp256r1VerificationFacetV2", barz) + + const signature = ethers.utils.defaultAbiCoder.encode( + ['uint256', 'uint256', 'bytes', 'string', 'string'], + [ + ethers.BigNumber.from("0x7f9576ce011a928c5d595b7ad8ce62aed73df49755c24f0d107c0f16988b27c7"), + ethers.BigNumber.from("0x9430dd40f06e792938e7c0cbfcaf64101c552923e0cd7a897b4f9e83330bb695"), + ethers.utils.concat([ + ethers.utils.hexZeroPad("0xf95bc73828ee210f9fd3bbe72d97908013b0a3759e9aea3d0ae318766cd2e1ad", 32), + ethers.utils.hexlify("0x0500000000") + ]), + '{"type":"webauthn.get","challenge":"', + '","origin":"https://webauthn.me","crossOrigin":false}' + ] + ) + + userOp = fillUserOpDefaults({ + sender: signer.address, + callGasLimit, + verificationGasLimit, + maxFeePerGas, + nonce, + signature, + }) + const userOpHash = getUserOpHash(userOp, entryPoint.address, chainId) + + // 0 equals success, 1 equals SIG_VALIDATION_FAILED + expect(await r1Barz.validateOwnerSignature(userOp, userOpHash)).to.equal(1) + expect(await r1Barz.validateOwnerSignature(userOp, userOpHash.slice(0, -6) + '000000')).to.equal(1) + }) + }) + + describe("# validateSignature", async () => { + it("Should return 0 for a valid signature", async () => { + const { keyPair, publicKeyBytes, keyX, keyY } = generateKeyPair() + await setupR1Barz(keyPair, publicKeyBytes) + + const userOp = signUserOpR1Curve(fillUserOpDefaults({ + sender: barz.address, + callGasLimit, + verificationGasLimit, + maxFeePerGas + }), keyPair, entryPoint.address, chainId) + const userOpHash = getUserOpHash(userOp, entryPoint.address, chainId) + + // 0 equals success, 1 equals SIG_VALIDATION_FAILED + expect(await r1Barz.validateSignature(userOp, userOpHash, [BigNumber.from("0x" + keyX.toString('hex')), BigNumber.from("0x" + keyY.toString('hex'))])).to.equal(0) + }) + it("Should return 1 for an invalid signature", async () => { + const { keyPair, publicKeyBytes } = generateKeyPair() + const invalidKey = generateKeyPair() + await setupR1Barz(keyPair, publicKeyBytes) + + const userOp = signUserOpR1Curve(fillUserOpDefaults({ + sender: barz.address, + callGasLimit, + verificationGasLimit, + maxFeePerGas + }), keyPair, entryPoint.address, chainId) + const userOpHash = getUserOpHash(userOp, entryPoint.address, chainId) + + // 0 equals success, 1 equals SIG_VALIDATION_FAILED + expect(await r1Barz.validateSignature(userOp, userOpHash, [BigNumber.from("0x" + invalidKey.keyX.toString('hex')), BigNumber.from("0x" + invalidKey.keyY.toString('hex'))])).to.equal(1) + }) + }) + describe("# isValidKeyType", async () => { + it("Should return true for a valid key length", async () => { + const { keyPair, publicKeyBytes } = generateKeyPair() + await setupR1Barz(keyPair, publicKeyBytes) + expect(await r1Barz.isValidKeyType(publicKeyBytes)).to.equal(true) + }) + it("Should return false for an invalid key length", async () => { + const { keyPair, publicKeyBytes } = generateKeyPair() + await setupR1Barz(keyPair, publicKeyBytes) + expect(await r1Barz.isValidKeyType(publicKeyBytes.slice(0, 6))).to.equal(false) + }) + + it("Should return false for an invalid key type", async () => { + const { keyPair, publicKeyBytes } = generateKeyPair() + await setupR1Barz(keyPair, publicKeyBytes) + expect(await r1Barz.isValidKeyType("0x02" + publicKeyBytes.substring(4))).to.equal(false) + }) + }) + describe("# owner", async () => { + it("Should return valid owner public key", async () => { + const { keyPair, publicKeyBytes, facetOwnerKey } = generateKeyPair() + await setupR1Barz(keyPair, publicKeyBytes) + const owner = await r1Barz.owner() + expect(owner).to.equal(facetOwnerKey) + }) + }) + describe("# validateOwnerSignatureSelector", async () => { + it("Should return valid selector", async () => { + const { keyPair, publicKeyBytes } = generateKeyPair() + await setupR1Barz(keyPair, publicKeyBytes) + expect(await r1Barz.validateOwnerSignatureSelector()).to.equal(r1Barz.interface.getSighash('validateOwnerSignature')) + }) + }) + describe("EIP-1271 # isValidSignature", async () => { + it("Should return EIP-1271 magic value if signature is valid", async () => { + const { keyPair, publicKeyBytes } = generateKeyPair() + await setupR1Barz(keyPair, publicKeyBytes) + + const enc = ethers.utils.defaultAbiCoder.encode(['string'], ["LOGIN to TW Wallet Timestamp:1683119999"]) + const msgHash = ethers.utils.keccak256(enc) + const ethSignMsgHash = keccak256_buffer(Buffer.concat([ + Buffer.from('\x19Ethereum Signed Message:\n32', 'ascii'), + Buffer.from(ethers.utils.arrayify(msgHash)) + ])) + + const finalHash = await getMessageHash(ethSignMsgHash, await getChainId(), r1Barz.address) + + const opHashBase64 = base64url.encode(concat([finalHash])) + const clientDataJSON = clientDataJSONPre + opHashBase64 + clientDataJSONPost + + const clientHash = sha256(toUtf8Bytes(clientDataJSON)).toString() + const authenticatorDataHEX = hexlify(authenticatorData) + const sigHash = sha256(concat([authenticatorDataHEX, clientHash])).slice(2) + const signature = keyPair.sign(sigHash) + const sValue = adjustS(signature.s, ec.n) + + const signedMessage = defaultAbiCoder.encode( + ['uint256', 'uint256', 'bytes', 'string', 'string'], + [ + BigNumber.from("0x" + signature.r.toString('hex')), + BigNumber.from(sValue.toString()), + authenticatorData, + clientDataJSONPre, + clientDataJSONPost + ] + ) + + expect(await r1Barz.isValidSignature(ethSignMsgHash, signedMessage)).to.equal("0x1626ba7e") + }) + it("Should return dummy value when signature is invalid", async () => { + const { keyPair, publicKeyBytes } = generateKeyPair() + const invalidKey = generateKeyPair() + await setupR1Barz(keyPair, publicKeyBytes) + + const enc = ethers.utils.defaultAbiCoder.encode(['string'], ["LOGIN to TW Wallet Timestamp:1683119999"]) + const msgHash = ethers.utils.keccak256(enc) + const ethSignMsgHash = keccak256_buffer(Buffer.concat([ + Buffer.from('\x19Ethereum Signed Message:\n32', 'ascii'), + Buffer.from(ethers.utils.arrayify(msgHash)) + ])) + + const finalHash = await getMessageHash(msgHash, await getChainId(), r1Barz.address) + + const opHashBase64 = base64url.encode(concat([finalHash])) + const clientDataJSON = clientDataJSONPre + opHashBase64 + clientDataJSONPost + + const clientHash = sha256(toUtf8Bytes(clientDataJSON)).toString() + const authenticatorDataHEX = hexlify(authenticatorData) + const sigHash = sha256(concat([authenticatorDataHEX, clientHash])).slice(2) + const signature = invalidKey.keyPair.sign(sigHash) + const signedMessage = defaultAbiCoder.encode( + ['uint256', 'uint256', 'bytes', 'string', 'string'], + [ + BigNumber.from("0x" + signature.r.toString('hex')), + BigNumber.from("0x" + signature.s.toString('hex')), + authenticatorData, + clientDataJSONPre, + clientDataJSONPost + ] + ) + + expect(await r1Barz.isValidSignature(ethSignMsgHash, signedMessage)).to.equal("0xffffffff") + }) + }) +}) \ No newline at end of file diff --git a/test/SignatureMigrationFacet.test.ts b/test/SignatureMigrationFacet.test.ts new file mode 100644 index 0000000..01a8b4d --- /dev/null +++ b/test/SignatureMigrationFacet.test.ts @@ -0,0 +1,1734 @@ +import { ethers } from 'hardhat' +import { Wallet } from 'ethers' + +import { AccountFacet, DiamondCutFacet, Barz, SignatureMigrationFacet, Secp256k1VerificationFacet, Secp256r1VerificationFacet, SecurityManager, FacetRegistry, DiamondLoupeFacet, GuardianFacet, TokenReceiverFacet, DefaultFallbackHandler, MultiSigFacet } from '../typechain-types' +import { fillUserOpDefaults, signMsgOnR1Curve, getUserOpHash, signUserOpK1Curve, signUserOpR1Curve, executeCallData, callFromEntryPointOnK1, callFromEntryPointOnR1 } from './utils/UserOp' +import { getEthSignMessageHash, getBlockTimestamp, getChainId, diamondCut, guardianSecurityPeriod, approvalValidationPeriod, migrationPeriod, increaseBlockTime, generateKeyPair } from './utils/helpers' +import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers' +import { createAccountOwner, fund, callGasLimit, verificationGasLimit, maxFeePerGas, AddressZero, getMessageHash, removePrefix, sortSignatures } from './utils/testutils' + +const { + FacetCutAction, + getSelectors +} = require('./utils/diamond.js') + +import { expect } from "chai" +import { diamondCutFacetFixture } from './fixtures/DiamondCutFacetFixture' +import { accountFacetFixture } from './fixtures/AccountFacetFixture' +import { secp256k1VerificationFacetFixture } from './fixtures/Secp256k1VerificationFacetFixture' +import { secp256r1VerificationFacetFixture } from './fixtures/Secp256r1VerificationFacetFixture' +import { barzFixture } from './fixtures/BarzFixture' +import { signatureMigrationFacetFixture } from './fixtures/SignatureMigrationFacetFixture' +import { addFacetSelectors, addFacetSelectorsViaEntryPointOnK1, addFacetSelectorsViaEntryPointOnR1, getFacetBarz, setupDefaultSecuritManager } from './utils/setup' +import { facetRegistryFixture } from './fixtures/FacetRegistryFixture' +import { diamondLoupeFacetFixture } from './fixtures/DiamondLoupeFacetFixture' +import { guardianFacetFixture } from './fixtures/GuardianFacetFixture' +import { keccak256 } from '@ethersproject/keccak256' +import { BytesLike, arrayify } from 'ethers/lib/utils' +import { EntryPoint } from '../typechain-types/core' +import { entryPointFixture } from './fixtures/EntryPointFixture' +import { tokenReceiverFacetFixture } from './fixtures/TokenReceiverFacetFixture' +import { defaultFallbackHandlerFixture } from './fixtures/DefaultFallbackHandlerFixture' +import { multiSigFacetFixture } from './fixtures/MultiSigFacetFixture' +import { ecsign, toRpcSig } from 'ethereumjs-util' + +describe('Signature Migration Facet', () => { + let diamondCutFacet: DiamondCutFacet + let diamondCutBarz: DiamondCutFacet + let securityManager: SecurityManager + let facetRegistry: FacetRegistry + let defaultFallbackHandler: DefaultFallbackHandler + let accountFacet: AccountFacet + let accountBarz: AccountFacet + let mockAccountBarz: AccountFacet + let tokenReceiverFacet: TokenReceiverFacet + let k1Facet: Secp256k1VerificationFacet + let r1Facet: Secp256r1VerificationFacet + let multiSigFacet: MultiSigFacet + let unregisteredR1Facet: Secp256r1VerificationFacet + let migrationFacet: SignatureMigrationFacet + let migrationBarz: SignatureMigrationFacet + let diamondLoupeFacet: DiamondLoupeFacet + let guardianFacet: GuardianFacet + let guardianBarz: GuardianFacet + let entryPoint: EntryPoint + let user1: SignerWithAddress + let guardian1: Wallet + let guardian2: SignerWithAddress + let guardian3: SignerWithAddress + let mockEntryPoint: SignerWithAddress + let securityManagerOwner: SignerWithAddress + let facetRegistryOwner: SignerWithAddress + let mockBarz: Barz + let mockMigrationBarz: SignatureMigrationFacet + let owner: Wallet + let subOwner: Wallet + let barz: Barz + let chainId: number + const migrationNonce = 0 + let ownerSeed = 0 + let migrationFacetSelectors: any + let guardianFacetSelectors: any + let encodedFuncSelectors: any + let encodedFuncSelectorsHash: any + + before(async () => { + [user1, mockEntryPoint, guardian2, guardian3, securityManagerOwner, facetRegistryOwner] = await ethers.getSigners() + owner = createAccountOwner(ownerSeed++) + guardian1 = createAccountOwner(ownerSeed++) + subOwner = createAccountOwner(ownerSeed++) + await fund(owner.address) + await fund(guardian1.address) + + chainId = await getChainId() + securityManager = await setupDefaultSecuritManager(securityManagerOwner) + facetRegistry = await facetRegistryFixture(facetRegistryOwner.address) + accountFacet = await accountFacetFixture() + k1Facet = await secp256k1VerificationFacetFixture() + r1Facet = await secp256r1VerificationFacetFixture() + multiSigFacet = await multiSigFacetFixture() + unregisteredR1Facet = await secp256r1VerificationFacetFixture() + guardianFacet = await guardianFacetFixture(securityManager) + diamondCutFacet = await diamondCutFacetFixture(securityManager) + migrationFacet = await signatureMigrationFacetFixture(securityManager) + diamondLoupeFacet = await diamondLoupeFacetFixture() + tokenReceiverFacet = await tokenReceiverFacetFixture() + entryPoint = await entryPointFixture() + defaultFallbackHandler = await defaultFallbackHandlerFixture(diamondCutFacet, accountFacet, tokenReceiverFacet, diamondLoupeFacet) + + migrationFacetSelectors = getSelectors(migrationFacet).filter((item: string) => item !== migrationFacet.interface.getSighash('securityManager')) + guardianFacetSelectors = getSelectors(guardianFacet).filter((item: string) => item !== guardianFacet.interface.getSighash('securityManager')) + + + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(accountFacet.address, getSelectors(accountFacet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(diamondCutFacet.address, getSelectors(diamondCutFacet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(migrationFacet.address, getSelectors(migrationFacet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(k1Facet.address, getSelectors(k1Facet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(r1Facet.address, getSelectors(r1Facet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(multiSigFacet.address, getSelectors(multiSigFacet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(diamondLoupeFacet.address, getSelectors(diamondLoupeFacet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(guardianFacet.address, getSelectors(guardianFacet)) + + encodedFuncSelectors = ethers.utils.defaultAbiCoder.encode(['bytes4[]'], [getSelectors(r1Facet)]) + encodedFuncSelectorsHash = keccak256(encodedFuncSelectors) + }) + + beforeEach(async () => { + mockBarz = await barzFixture(accountFacet, k1Facet, mockEntryPoint, facetRegistry, defaultFallbackHandler, owner.publicKey) + mockAccountBarz = await getFacetBarz('AccountFacet', mockBarz) + mockMigrationBarz = await getFacetBarz("SignatureMigrationFacet", mockBarz) + await addFacetSelectors(mockBarz, migrationFacet, migrationFacetSelectors, mockEntryPoint) + await addFacetSelectors(mockBarz, guardianFacet, guardianFacet, mockEntryPoint) + }) + + const setupBarz = async (verificationFacet: any, ownerPublicKey: any) => { + barz = await barzFixture(accountFacet, verificationFacet, entryPoint, facetRegistry, defaultFallbackHandler, ownerPublicKey) + diamondCutBarz = await getFacetBarz('DiamondCutFacet', barz) + migrationBarz = await getFacetBarz('SignatureMigrationFacet', barz) + accountBarz = await getFacetBarz('AccountFacet', barz) + guardianBarz = await getFacetBarz('GuardianFacet', barz) + + await entryPoint.depositTo(barz.address, { + value: ethers.utils.parseEther('0.5'), + }) + } + + const addFacetsK1 = async () => { + await addFacetSelectorsViaEntryPointOnK1(barz, owner, k1Facet, [k1Facet.interface.getSighash('isValidKeyType'), k1Facet.interface.getSighash('initializeSigner'), k1Facet.interface.getSighash('uninitializeSigner')], entryPoint) + await addFacetSelectorsViaEntryPointOnK1(barz, owner, migrationFacet, migrationFacetSelectors, entryPoint) + await addFacetSelectorsViaEntryPointOnK1(barz, owner, guardianFacet, guardianFacetSelectors, entryPoint) + } + + const addFacetsR1 = async (keyPair: any) => { + await addFacetSelectorsViaEntryPointOnR1(barz, keyPair, r1Facet, [r1Facet.interface.getSighash('isValidKeyType'), r1Facet.interface.getSighash('initializeSigner'), r1Facet.interface.getSighash('uninitializeSigner')], entryPoint) + await addFacetSelectorsViaEntryPointOnR1(barz, keyPair, migrationFacet, migrationFacetSelectors, entryPoint) + await addFacetSelectorsViaEntryPointOnR1(barz, keyPair, guardianFacet, guardianFacetSelectors, entryPoint) + } + + const addGuardian = async (newGuardian: any) => { + const addGuardianCall = guardianFacet.interface.encodeFunctionData("addGuardian", [newGuardian.address]) + const addGuardianCallData = executeCallData(barz.address, 0, addGuardianCall) + await callFromEntryPointOnK1(entryPoint, barz.address, owner, addGuardianCallData) + + await increaseBlockTime(guardianSecurityPeriod) + await expect(guardianBarz.confirmGuardianAddition(newGuardian.address)).to.emit(guardianBarz, "GuardianAdded") + expect(await guardianBarz.isGuardian(newGuardian.address)).to.be.true + } + + const addGuardianMock = async (_newGuardian: any, _guardianBarz: any, _accountBarz: any) => { + const addGuardianCall = guardianFacet.interface.encodeFunctionData("addGuardian", [_newGuardian.address]) + await _accountBarz.connect(mockEntryPoint).execute(_accountBarz.address, 0, addGuardianCall) + + await increaseBlockTime(guardianSecurityPeriod) + await expect(_guardianBarz.confirmGuardianAddition(_newGuardian.address)).to.emit(_guardianBarz, "GuardianAdded") + } + + const getSignedMigrationHash = async (facet: any, publicKeyBytes: BytesLike, migrationBarz: SignatureMigrationFacet, migrationNonce: number) => { + const encodedFuncSelectors = ethers.utils.defaultAbiCoder.encode(['bytes4[]'], [getSelectors(facet)]) + const encodedFuncSelectorsHash = keccak256(encodedFuncSelectors) + const encodedData = ethers.utils.defaultAbiCoder.encode(['bytes', 'address', 'bytes32', 'string', 'address', 'uint256', 'uint128'], [publicKeyBytes, facet.address, encodedFuncSelectorsHash, 'MigrateSignature', migrationBarz.address, await getChainId(), migrationNonce]) + return keccak256(encodedData) + } + + it('Should change signature scheme from k1 to r1', async () => { + // 1. Deploy SignatureMigrationFacet + // 2. Add migrateSignatureScheme() to diamondCut + // 3. Init with new public key + // 4. Check new public key + // 5. Sign UserOperation with new r1 scheme + // 6. Verify if it works through validateUserOp + const { keyPair, publicKeyBytes, facetOwnerKey } = generateKeyPair() + + await setupBarz(k1Facet, owner.publicKey) + await addFacetsK1() + + const migrateSignatureCall = migrationBarz.interface.encodeFunctionData("migrateSignatureScheme", [r1Facet.address, publicKeyBytes, getSelectors(r1Facet)]) + + const timestamp = await getBlockTimestamp() + const migrateSignatureCallData = executeCallData(migrationBarz.address, 0, migrateSignatureCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, migrateSignatureCallData)).to.emit(migrationBarz, "SignatureMigrationExecuted").withArgs(r1Facet.address, publicKeyBytes, getSelectors(r1Facet), timestamp + migrationPeriod + 1) + + await increaseBlockTime(migrationPeriod) + const finalizeMigrateSignatureCall = migrationBarz.interface.encodeFunctionData("finalizeSignatureMigration") + + const finalizeMigrateSignatureCallData = executeCallData(migrationBarz.address, 0, finalizeMigrateSignatureCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, finalizeMigrateSignatureCallData)).to.emit(migrationBarz, 'SignatureSchemeMigration') + + const diamondR1Facet = await getFacetBarz("Secp256r1VerificationFacet", barz) + const newOwner = await diamondR1Facet.owner() + + expect(newOwner).to.equal(facetOwnerKey) + const userOp = signUserOpR1Curve(fillUserOpDefaults({ + sender: barz.address, + callGasLimit: 5000000, + verificationGasLimit: 5000000, + maxFeePerGas, + nonce: await accountBarz.getNonce() + }), keyPair, entryPoint.address, chainId) + const userOpHash = getUserOpHash(userOp, entryPoint.address, chainId) + + await expect(entryPoint.handleOps([userOp], facetRegistryOwner.address)).to.emit(accountBarz, "VerificationSuccess").withArgs(userOpHash) + }) + it('Should change signature scheme from r1 to k1', async () => { + // 1. Deploy SignatureMigrationFacet + // 2. Add migrateSignatureScheme() to diamondCut + // 3. Init with new public key + // 4. Check new public key + // 5. Sign UserOperation with new r1 scheme + // 6. Verify if it works through validateUserOp + const { keyPair, publicKeyBytes } = generateKeyPair() + + await setupBarz(r1Facet, publicKeyBytes) + await addFacetsR1(keyPair) + + const migrateSignatureCall = migrationFacet.interface.encodeFunctionData("migrateSignatureScheme", [k1Facet.address, owner.publicKey, getSelectors(k1Facet)]) + + const timestamp = await getBlockTimestamp() + + const migrateSignatureCallData = executeCallData(migrationBarz.address, 0, migrateSignatureCall) + await expect(callFromEntryPointOnR1(entryPoint, barz.address, keyPair, migrateSignatureCallData)).to.emit(migrationBarz, "SignatureMigrationExecuted").withArgs(k1Facet.address, owner.publicKey.toLowerCase(), getSelectors(k1Facet), timestamp + migrationPeriod + 1) + await increaseBlockTime(migrationPeriod) + + const finalizeMigrateSignatureCall = migrationBarz.interface.encodeFunctionData("finalizeSignatureMigration") + const finalizeMigrateSignatureCallData = executeCallData(migrationBarz.address, 0, finalizeMigrateSignatureCall) + await expect(callFromEntryPointOnR1(entryPoint, barz.address, keyPair, finalizeMigrateSignatureCallData)).to.emit(migrationBarz, 'SignatureSchemeMigration') + + const diamondK1Barz = await getFacetBarz("Secp256k1VerificationFacet", barz) + const newOwner = await diamondK1Barz.owner() + expect(newOwner.toLowerCase()).to.equal(owner.address.toLowerCase()) + const userOp = signUserOpK1Curve(fillUserOpDefaults({ + sender: barz.address, + nonce: await accountBarz.getNonce(), + callGasLimit, + verificationGasLimit, + maxFeePerGas, + }), owner, entryPoint.address, chainId) + const userOpHash = getUserOpHash(userOp, entryPoint.address, chainId) + + expect(await entryPoint.handleOps([userOp], barz.address)).to.emit(accountBarz, "VerificationSuccess").withArgs([userOpHash]) + }) + it("Should migrate signature scheme from k1 to multi-sig", async () => { + await setupBarz(k1Facet, owner.publicKey) + await addFacetsK1() + + const threshold = "00000002" + const signatureType = "03" + const signatureLength = "00000041" + const initData = "0x" + threshold + removePrefix(owner.address) + removePrefix(subOwner.address) + const migrateSignatureCall = migrationBarz.interface.encodeFunctionData("migrateSignatureScheme", [multiSigFacet.address, initData, getSelectors(multiSigFacet)]) + + const timestamp = await getBlockTimestamp() + const migrateSignatureCallData = executeCallData(migrationBarz.address, 0, migrateSignatureCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, migrateSignatureCallData)).to.emit(migrationBarz, "SignatureMigrationExecuted").withArgs(multiSigFacet.address, initData.toLowerCase(), getSelectors(multiSigFacet), timestamp + migrationPeriod + 1) + + await increaseBlockTime(migrationPeriod) + const finalizeMigrateSignatureCall = migrationBarz.interface.encodeFunctionData("finalizeSignatureMigration") + + + const finalizeMigrateSignatureCallData = executeCallData(migrationBarz.address, 0, finalizeMigrateSignatureCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, finalizeMigrateSignatureCallData)).to.emit(migrationBarz, 'SignatureSchemeMigration') + + + const userOp = fillUserOpDefaults({ + sender: barz.address, + nonce: await accountBarz.getNonce(), + verificationGasLimit, + callGasLimit + }) + const ownerUserOperation = signUserOpK1Curve(userOp, owner, entryPoint.address, chainId) + const subOwnerUserOperation = signUserOpK1Curve(userOp, subOwner, entryPoint.address, chainId) + + const ownerSignature = removePrefix(owner.address) + signatureType + signatureLength + removePrefix(ownerUserOperation.signature.toString()) + const subOwnerSignature = removePrefix(subOwner.address) + signatureType + signatureLength + removePrefix(subOwnerUserOperation.signature.toString()) + + const ownerAddr = owner.address + const subOwnerAddr = subOwner.address + + interface SignatureInfo { + address: string; + signature: string; + } + + const signatureInfo: SignatureInfo[] = [ + { address: ownerAddr, signature: ownerSignature }, + { address: subOwnerAddr, signature: subOwnerSignature }, + ]; + + signatureInfo.sort((a, b) => a.address.localeCompare(b.address)); + + let concatenatedSignatures: any + for (let i = 0; i < signatureInfo.length; i++) { + concatenatedSignatures += signatureInfo[i].signature + } + userOp.signature = "0x" + concatenatedSignatures.replace("undefined", "") + await expect(entryPoint.handleOps([userOp], user1.address)).to.emit(accountBarz, "VerificationSuccess") + }) + it("Should migrate signature scheme from multi-sig to k1", async () => { + const ownerAddr = owner.address + const subOwnerAddr = subOwner.address + + const threshold = "00000002" + const signatureType = "03" + const signatureLength = "00000041" + const initData = "0x" + threshold + removePrefix(owner.address) + removePrefix(subOwner.address) + + await setupBarz(multiSigFacet, initData) + + // 1---- Diamond Cut + const cut = diamondCut(migrationFacet.address, FacetCutAction.Add, getSelectors(migrationFacet)) + const cutCallData = diamondCutBarz.interface.encodeFunctionData("diamondCut", [cut, AddressZero, "0x00"]) + const cutExecuteCallData = executeCallData(migrationBarz.address, 0, cutCallData) + + const cutUserOp = fillUserOpDefaults({ + sender: barz.address, + callData: cutExecuteCallData, + nonce: await accountBarz.getNonce(), + verificationGasLimit, + callGasLimit + }) + const cutOwnerUserOperation = signUserOpK1Curve(cutUserOp, owner, entryPoint.address, chainId) + const cutSubOwnerUserOperation = signUserOpK1Curve(cutUserOp, subOwner, entryPoint.address, chainId) + + const cutOwnerSignature = removePrefix(owner.address) + signatureType + signatureLength + removePrefix(cutOwnerUserOperation.signature.toString()) + const cutSubOwnerSignature = removePrefix(subOwner.address) + signatureType + signatureLength + removePrefix(cutSubOwnerUserOperation.signature.toString()) + + const sigMapping: Record = { + [ownerAddr]: cutOwnerSignature, + [subOwnerAddr]: cutSubOwnerSignature, + }; + + const cutConcatenatedSignatures = sortSignatures(sigMapping) + + cutUserOp.signature = cutConcatenatedSignatures + await expect(entryPoint.handleOps([cutUserOp], user1.address)).to.emit(diamondCutBarz, "DiamondCut") + + // 2---- Migrate Signature Scheme + const migrateSignatureCall = migrationBarz.interface.encodeFunctionData("migrateSignatureScheme", [k1Facet.address, owner.publicKey, getSelectors(k1Facet)]) + + const migrateSignatureCallData = executeCallData(migrationBarz.address, 0, migrateSignatureCall) + + const userOp = fillUserOpDefaults({ + sender: barz.address, + callData: migrateSignatureCallData, + nonce: await accountBarz.getNonce(), + verificationGasLimit, + callGasLimit + }) + const ownerUserOperation = signUserOpK1Curve(userOp, owner, entryPoint.address, chainId) + const subOwnerUserOperation = signUserOpK1Curve(userOp, subOwner, entryPoint.address, chainId) + + const ownerSignature = removePrefix(owner.address) + signatureType + signatureLength + removePrefix(ownerUserOperation.signature.toString()) + const subOwnerSignature = removePrefix(subOwner.address) + signatureType + signatureLength + removePrefix(subOwnerUserOperation.signature.toString()) + + const signatureInfo: SignatureInfo[] = [ + { address: ownerAddr, signature: ownerSignature }, + { address: subOwnerAddr, signature: subOwnerSignature }, + ]; + + signatureInfo.sort((a, b) => a.address.localeCompare(b.address)); + + let concatenatedSignatures: any + for (let i = 0; i < signatureInfo.length; i++) { + concatenatedSignatures += signatureInfo[i].signature + } + userOp.signature = "0x" + concatenatedSignatures.replace("undefined", "") + await expect(entryPoint.handleOps([userOp], user1.address)).to.emit(migrationBarz, "SignatureMigrationExecuted") + + + // 3---- Finalize Signature Migration + await increaseBlockTime(migrationPeriod) + const finalizeMigrateSignatureCall = migrationBarz.interface.encodeFunctionData("finalizeSignatureMigration") + + const finalizeMigrateSignatureCallData = executeCallData(migrationBarz.address, 0, finalizeMigrateSignatureCall) + const finalizeUserOp = fillUserOpDefaults({ + sender: barz.address, + callData: finalizeMigrateSignatureCallData, + nonce: await accountBarz.getNonce(), + verificationGasLimit, + callGasLimit + }) + const finalizeOwnerUserOperation = signUserOpK1Curve(finalizeUserOp, owner, entryPoint.address, chainId) + const finalizeSubOwnerUserOperation = signUserOpK1Curve(finalizeUserOp, subOwner, entryPoint.address, chainId) + + const finalizeOwnerSignature = removePrefix(owner.address) + signatureType + signatureLength + removePrefix(finalizeOwnerUserOperation.signature.toString()) + const finalizeSubOwnerSignature = removePrefix(subOwner.address) + signatureType + signatureLength + removePrefix(finalizeSubOwnerUserOperation.signature.toString()) + + const mapping: Record = { + [ownerAddr]: finalizeOwnerSignature, + [subOwnerAddr]: finalizeSubOwnerSignature, + }; + + finalizeUserOp.signature = sortSignatures(mapping) + await expect(entryPoint.handleOps([finalizeUserOp], user1.address)).to.emit(migrationBarz, 'SignatureSchemeMigration') + + await addFacetSelectorsViaEntryPointOnK1(barz, owner, guardianFacet, guardianFacetSelectors, entryPoint) + + }) + describe('# migrateSignatureScheme', () => { + it('Should revert if not caller is not owner', async () => { + await setupBarz(k1Facet, owner.publicKey) + await addFacetsK1() + + const { publicKeyBytes } = generateKeyPair() + await expect(migrationBarz.connect(user1).migrateSignatureScheme(r1Facet.address, publicKeyBytes, getSelectors(r1Facet))).to.be.revertedWith("LibDiamond: Caller not self") + + const migrateSignatureCall = migrationBarz.interface.encodeFunctionData("migrateSignatureScheme", [r1Facet.address, publicKeyBytes, getSelectors(r1Facet)]) + const migrateSignatureCallData = executeCallData(migrationBarz.address, 0, migrateSignatureCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, migrateSignatureCallData)).to.emit(migrationBarz, "SignatureMigrationExecuted") + }) + it('Should revert if new public key length is not valid', async () => { + await setupBarz(k1Facet, owner.publicKey) + await addFacetsK1() + + const { publicKeyBytes } = generateKeyPair() + + await expect(migrationBarz.migrateSignatureScheme(r1Facet.address, publicKeyBytes + "000000", getSelectors(r1Facet))).to.be.revertedWithCustomError(migrationBarz, "SignatureMigrationFacet__InvalidKeyType") + }) + it('Should revert if guardian exists', async () => { + await setupBarz(k1Facet, owner.publicKey) + await addFacetsK1() + + const { publicKeyBytes } = generateKeyPair() + + await addGuardian(guardian1) + await addGuardian(guardian2) + + const migrateSignatureCall = migrationBarz.interface.encodeFunctionData("migrateSignatureScheme", [r1Facet.address, publicKeyBytes, getSelectors(r1Facet)]) + const migrateSignatureCallData = executeCallData(migrationBarz.address, 0, migrateSignatureCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, migrateSignatureCallData)).to.not.emit(migrationBarz, "SignatureMigrationExecuted") + await addGuardianMock(guardian1, await getFacetBarz("GuardianFacet", mockBarz), await getFacetBarz("AccountFacet", mockBarz)) + + await expect(mockAccountBarz.connect(mockEntryPoint).execute(mockAccountBarz.address, 0, migrateSignatureCall)).to.be.revertedWithCustomError(migrationBarz, "SignatureMigrationFacet__InvalidRouteWithGuardian") + }) + it('Should emit Migration Execution event', async () => { + await setupBarz(k1Facet, owner.publicKey) + await addFacetsK1() + + const { publicKeyBytes } = generateKeyPair() + + const currentTimestamp = await getBlockTimestamp() + const expectedTimestamp = currentTimestamp + migrationPeriod + 1 + const migrateSignatureCall = migrationBarz.interface.encodeFunctionData("migrateSignatureScheme", [r1Facet.address, publicKeyBytes, getSelectors(r1Facet)]) + const migrateSignatureCallData = executeCallData(migrationBarz.address, 0, migrateSignatureCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, migrateSignatureCallData)).to.emit(migrationBarz, "SignatureMigrationExecuted").withArgs(r1Facet.address, publicKeyBytes, getSelectors(r1Facet), expectedTimestamp) + }) + it('Should increment migration nonce', async () => { + await setupBarz(k1Facet, owner.publicKey) + await addFacetsK1() + + const { publicKeyBytes } = generateKeyPair() + let migrationNonce = 0 + expect(await migrationBarz.getMigrationNonce()).to.equal(migrationNonce) + const migrateSignatureCall = migrationBarz.interface.encodeFunctionData("migrateSignatureScheme", [r1Facet.address, publicKeyBytes, getSelectors(r1Facet)]) + const migrateSignatureCallData = executeCallData(migrationBarz.address, 0, migrateSignatureCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, migrateSignatureCallData)).to.not.reverted + expect(await migrationBarz.getMigrationNonce()).to.equal(++migrationNonce) + }) + it('Should revert if new verification facet is unregistered to facet registry', async () => { + await setupBarz(k1Facet, owner.publicKey) + await addFacetsK1() + const { publicKeyBytes } = generateKeyPair() + + const migrateSignatureCall = migrationFacet.interface.encodeFunctionData('migrateSignatureScheme', [unregisteredR1Facet.address, publicKeyBytes, getSelectors(unregisteredR1Facet)]) + + await expect(mockAccountBarz.connect(mockEntryPoint).execute(mockAccountBarz.address, 0, migrateSignatureCall)).to.revertedWithCustomError(mockMigrationBarz, "UnregisteredFacetAndSelectors") + }) + }) + describe('# migrateSignatureSchemeWithGuardian', () => { + it('Should revert if new public key length is not valid', async () => { + await setupBarz(k1Facet, owner.publicKey) + await addFacetsK1() + + const { publicKeyBytes } = generateKeyPair() + await addGuardian(guardian1) + + const encodedFuncSelectors = ethers.utils.defaultAbiCoder.encode(['bytes4[]'], [getSelectors(r1Facet)]) + const encodedFuncSelectorsHash = keccak256(encodedFuncSelectors) + const invalidPublicKeyBytes = publicKeyBytes + "1111" + const encodedData = ethers.utils.defaultAbiCoder.encode(['bytes', 'address', 'bytes32', 'string', 'address', 'uint256', 'uint128'], [invalidPublicKeyBytes, r1Facet.address, encodedFuncSelectorsHash, 'MigrateSignature', migrationBarz.address, chainId, migrationNonce]) + const hash = keccak256(encodedData) + const guardianSignature = await guardian1.signMessage(arrayify(hash)) + const migrateSignatureCall = migrationBarz.interface.encodeFunctionData('migrateSignatureSchemeWithGuardian', [r1Facet.address, invalidPublicKeyBytes, getSelectors(r1Facet), [guardian1.address], [guardianSignature]]) + const migrateSignatureCallData = executeCallData(migrationBarz.address, 0, migrateSignatureCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, migrateSignatureCallData)).to.not.emit(migrationBarz, 'SignatureMigrationExecuted') + + const mockEncodedData = ethers.utils.defaultAbiCoder.encode(['bytes', 'address', 'bytes32', 'string', 'address', 'uint256', 'uint128'], [invalidPublicKeyBytes, r1Facet.address, encodedFuncSelectorsHash, 'MigrateSignature', mockMigrationBarz.address, chainId, migrationNonce]) + const mockHash = keccak256(mockEncodedData) + const mockGuardianSignature = await guardian1.signMessage(arrayify(mockHash)) + + await expect(mockMigrationBarz.migrateSignatureSchemeWithGuardian(r1Facet.address, invalidPublicKeyBytes, getSelectors(r1Facet), [guardian1.address], [mockGuardianSignature])).to.be.revertedWithCustomError(migrationBarz, "SignatureMigrationFacet__InvalidKeyType") + }) + it('Should revert if guardian does not exists', async () => { + await setupBarz(k1Facet, owner.publicKey) + await addFacetsK1() + + const { publicKeyBytes } = generateKeyPair() + + const encodedFuncSelectors = ethers.utils.defaultAbiCoder.encode(['bytes4[]'], [getSelectors(r1Facet)]) + const encodedFuncSelectorsHash = keccak256(encodedFuncSelectors) + + const encodedData = ethers.utils.defaultAbiCoder.encode(['bytes', 'address', 'bytes32', 'string', 'address', 'uint256', 'uint128'], [publicKeyBytes, r1Facet.address, encodedFuncSelectorsHash, 'MigrateSignature', migrationBarz.address, chainId, migrationNonce]) + const hash = keccak256(encodedData) + const signature1 = await guardian1.signMessage(arrayify(hash)) + const migrateSignatureCall = migrationBarz.interface.encodeFunctionData('migrateSignatureSchemeWithGuardian', [r1Facet.address, publicKeyBytes, getSelectors(r1Facet), [guardian1.address], [signature1]]) + const migrateSignatureCallData = executeCallData(migrationBarz.address, 0, migrateSignatureCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, migrateSignatureCallData)).to.not.emit(migrationBarz, "SignatureMigrationExecuted") + + + const customMockBarz = await barzFixture(accountFacet, k1Facet, mockEntryPoint, facetRegistry, defaultFallbackHandler, owner.publicKey) + await addFacetSelectors(customMockBarz, guardianFacet, guardianFacetSelectors, mockEntryPoint) + await addFacetSelectors(customMockBarz, migrationFacet, migrationFacetSelectors, mockEntryPoint) + const customMigrationBarz = await getFacetBarz("SignatureMigrationFacet", customMockBarz) + const mockEncodedData = ethers.utils.defaultAbiCoder.encode(['bytes', 'address', 'bytes32', 'string', 'address', 'uint256', 'uint128'], [publicKeyBytes, r1Facet.address, encodedFuncSelectorsHash, 'MigrateSignature', customMigrationBarz.address, chainId, migrationNonce]) + const mockHash = keccak256(mockEncodedData) + const mockGuardianSignature = await guardian1.signMessage(arrayify(mockHash)) + await expect(customMigrationBarz.migrateSignatureSchemeWithGuardian(r1Facet.address, publicKeyBytes, getSelectors(r1Facet), [guardian1.address], [mockGuardianSignature])).to.be.revertedWithCustomError(customMigrationBarz, 'SignatureMigrationFacet__InvalidRouteWithGuardian') + }) + it('Should revert if parameter guardian length and signature length differs', async () => { + await setupBarz(k1Facet, owner.publicKey) + await addFacetsK1() + + const { publicKeyBytes } = generateKeyPair() + await addGuardian(guardian1) + await addGuardian(guardian2) + await addGuardianMock(guardian1, await getFacetBarz("GuardianFacet", mockBarz), await getFacetBarz("AccountFacet", mockBarz)) + + const encodedFuncSelectors = ethers.utils.defaultAbiCoder.encode(['bytes4[]'], [getSelectors(r1Facet)]) + const encodedFuncSelectorsHash = keccak256(encodedFuncSelectors) + + const encodedData = ethers.utils.defaultAbiCoder.encode(['bytes', 'address', 'bytes32', 'string', 'address', 'uint256', 'uint128'], [publicKeyBytes, r1Facet.address, encodedFuncSelectorsHash, 'MigrateSignature', migrationBarz.address, chainId, migrationNonce]) + const hash = keccak256(encodedData) + const signature1 = await guardian1.signMessage(arrayify(hash)) + const migrateSignatureCall = migrationBarz.interface.encodeFunctionData('migrateSignatureSchemeWithGuardian', [r1Facet.address, publicKeyBytes, getSelectors(r1Facet), [guardian1.address, guardian2.address], [signature1]]) + const migrateSignatureCallData = executeCallData(migrationBarz.address, 0, migrateSignatureCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, migrateSignatureCallData)).to.not.emit(migrationBarz, "SignatureMigrationExecuted") + + const mockEncodedData = ethers.utils.defaultAbiCoder.encode(['bytes', 'address', 'bytes32', 'string', 'address', 'uint256', 'uint128'], [publicKeyBytes, r1Facet.address, encodedFuncSelectorsHash, 'MigrateSignature', mockMigrationBarz.address, chainId, migrationNonce]) + const mockHash = keccak256(mockEncodedData) + const mockGuardianSignature = await guardian1.signMessage(arrayify(mockHash)) + await expect(mockMigrationBarz.migrateSignatureSchemeWithGuardian(r1Facet.address, publicKeyBytes, getSelectors(r1Facet), [guardian1.address, guardian2.address], [mockGuardianSignature])).to.be.revertedWithCustomError(mockMigrationBarz, 'SignatureMigrationFacet__InvalidArrayLength') + }) + it('Should revert if parameter guardian length + approved count < majority of guardians', async () => { + await setupBarz(k1Facet, owner.publicKey) + await addFacetsK1() + + const { publicKeyBytes } = generateKeyPair() + await addGuardian(guardian1) + await addGuardian(guardian2) + + const encodedFuncSelectors = ethers.utils.defaultAbiCoder.encode(['bytes4[]'], [getSelectors(r1Facet)]) + const encodedFuncSelectorsHash = keccak256(encodedFuncSelectors) + + const encodedData = ethers.utils.defaultAbiCoder.encode(['bytes', 'address', 'bytes32', 'string', 'address', 'uint256', 'uint128'], [publicKeyBytes, r1Facet.address, encodedFuncSelectorsHash, 'MigrateSignature', migrationBarz.address, chainId, migrationNonce]) + const hash = keccak256(encodedData) + const signature1 = await guardian1.signMessage(arrayify(hash)) + const migrateSignatureCall = migrationBarz.interface.encodeFunctionData('migrateSignatureSchemeWithGuardian', [r1Facet.address, publicKeyBytes, getSelectors(r1Facet), [guardian1.address], [signature1]]) + const migrateSignatureCallData = executeCallData(migrationBarz.address, 0, migrateSignatureCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, migrateSignatureCallData)).to.not.emit(migrationBarz, "SignatureMigrationExecuted") + const mockBarz = await barzFixture(accountFacet, k1Facet, mockEntryPoint, facetRegistry, defaultFallbackHandler, owner.publicKey) + const mockMigrationBarz = await getFacetBarz("SignatureMigrationFacet", mockBarz) + await addFacetSelectors(mockBarz, migrationFacet, migrationFacetSelectors, mockEntryPoint) + await addFacetSelectors(mockBarz, guardianFacet, guardianFacetSelectors, mockEntryPoint) + + const mockEncodedData = ethers.utils.defaultAbiCoder.encode(['bytes', 'address', 'bytes32', 'string', 'address', 'uint256', 'uint128'], [publicKeyBytes, r1Facet.address, encodedFuncSelectorsHash, 'MigrateSignature', mockMigrationBarz.address, chainId, migrationNonce]) + const mockHash = keccak256(mockEncodedData) + const mockGuardianSignature = await guardian1.signMessage(arrayify(mockHash)) + await addGuardianMock(guardian2, await getFacetBarz("GuardianFacet", mockBarz), await getFacetBarz("AccountFacet", mockBarz)) + await expect(mockMigrationBarz.migrateSignatureSchemeWithGuardian(r1Facet.address, publicKeyBytes, getSelectors(r1Facet), [guardian1.address], [mockGuardianSignature])).to.be.revertedWithCustomError(mockMigrationBarz, "SignatureMigrationFacet__InsufficientApprovers") + + }) + it('Should revert if invalid parameter guardian', async () => { + // Guardian 1 was added but Guardian 2 is given as param + await setupBarz(k1Facet, owner.publicKey) + await addFacetsK1() + + const { publicKeyBytes } = generateKeyPair() + await addGuardian(guardian1) + await addGuardianMock(guardian1, await getFacetBarz("GuardianFacet", mockBarz), await getFacetBarz("AccountFacet", mockBarz)) + + const encodedFuncSelectors = ethers.utils.defaultAbiCoder.encode(['bytes4[]'], [getSelectors(r1Facet)]) + const encodedFuncSelectorsHash = keccak256(encodedFuncSelectors) + + const encodedData = ethers.utils.defaultAbiCoder.encode(['bytes', 'address', 'bytes32', 'string', 'address', 'uint256', 'uint128'], [publicKeyBytes, r1Facet.address, encodedFuncSelectorsHash, 'MigrateSignature', migrationBarz.address, chainId, migrationNonce]) + const hash = keccak256(encodedData) + const signature1 = await guardian2.signMessage(arrayify(hash)) + const signerSignature = await owner.signMessage(arrayify(hash)) + const migrateSignatureCall = migrationBarz.interface.encodeFunctionData('migrateSignatureSchemeWithGuardian', [r1Facet.address, publicKeyBytes, getSelectors(r1Facet), [guardian2.address, barz.address], [signature1, signerSignature]]) + const migrateSignatureCallData = executeCallData(migrationBarz.address, 0, migrateSignatureCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, migrateSignatureCallData)).to.not.emit(migrationBarz, "SignatureMigrationExecuted") + + const mockEncodedData = ethers.utils.defaultAbiCoder.encode(['bytes', 'address', 'bytes32', 'string', 'address', 'uint256', 'uint128'], [publicKeyBytes, r1Facet.address, encodedFuncSelectorsHash, 'MigrateSignature', mockMigrationBarz.address, chainId, migrationNonce]) + const mockHash = keccak256(mockEncodedData) + const mockGuardianSignature = await guardian1.signMessage(arrayify(mockHash)) + const mockSignerSignature = await owner.signMessage(arrayify(mockHash)) + // Guardian is added but Guardian 2 was given + await expect(mockMigrationBarz.migrateSignatureSchemeWithGuardian(r1Facet.address, publicKeyBytes, getSelectors(r1Facet), [guardian2.address, barz.address], [mockGuardianSignature, mockSignerSignature])).to.be.revertedWithCustomError(mockMigrationBarz, "SignatureMigrationFacet__InvalidGuardian") + }) + it('Should revert if invalid guardian signature', async () => { + await setupBarz(k1Facet, owner.publicKey) + await addFacetsK1() + + const { publicKeyBytes } = generateKeyPair() + await addGuardian(guardian1) + await addGuardianMock(guardian1, await getFacetBarz("GuardianFacet", mockBarz), await getFacetBarz("AccountFacet", mockBarz)) + + const encodedFuncSelectors = ethers.utils.defaultAbiCoder.encode(['bytes4[]'], [getSelectors(r1Facet)]) + const encodedFuncSelectorsHash = keccak256(encodedFuncSelectors) + + const encodedData = ethers.utils.defaultAbiCoder.encode(['bytes', 'address', 'bytes32', 'string', 'address', 'uint256', 'uint128'], [publicKeyBytes, r1Facet.address, encodedFuncSelectorsHash, 'InvalidSignature', migrationBarz.address, chainId, migrationNonce]) + const hash = keccak256(encodedData) + const signature1 = await guardian1.signMessage(arrayify(hash)) + const signerSignature = await owner.signMessage(arrayify(hash)) + const migrateSignatureCall = migrationBarz.interface.encodeFunctionData('migrateSignatureSchemeWithGuardian', [r1Facet.address, publicKeyBytes, getSelectors(r1Facet), [guardian1.address, barz.address], [signature1, signerSignature]]) + const migrateSignatureCallData = executeCallData(migrationBarz.address, 0, migrateSignatureCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, migrateSignatureCallData)).to.not.emit(migrationBarz, "SignatureMigrationExecuted") + + const mockEncodedData = ethers.utils.defaultAbiCoder.encode(['bytes', 'address', 'bytes32', 'string', 'address', 'uint256', 'uint128'], [publicKeyBytes, r1Facet.address, encodedFuncSelectorsHash, 'InvalidSignature', mockMigrationBarz.address, chainId, migrationNonce]) + const mockHash = keccak256(mockEncodedData) + const guardianSignature = await guardian1.signMessage(arrayify(mockHash)) + const mockSignerSignature = await owner.signMessage(arrayify(mockHash)) + await expect(mockMigrationBarz.migrateSignatureSchemeWithGuardian(r1Facet.address, publicKeyBytes, getSelectors(r1Facet), [guardian1.address, mockBarz.address], [guardianSignature, mockSignerSignature])).to.be.revertedWithCustomError(mockMigrationBarz, 'SignatureMigrationFacet__InvalidApproverSignature') + }) + it('Should revert if duplicate guardian', async () => { + await setupBarz(k1Facet, owner.publicKey) + await addFacetsK1() + + const { publicKeyBytes } = generateKeyPair() + const encodedFuncSelectors = ethers.utils.defaultAbiCoder.encode(['bytes4[]'], [getSelectors(r1Facet)]) + const encodedFuncSelectorsHash = keccak256(encodedFuncSelectors) + + mockBarz = await barzFixture(accountFacet, k1Facet, mockEntryPoint, facetRegistry, defaultFallbackHandler, owner.publicKey) + + await addFacetSelectors(mockBarz, migrationFacet, migrationFacetSelectors, mockEntryPoint) + await addFacetSelectors(mockBarz, guardianFacet, guardianFacetSelectors, mockEntryPoint) + + const mockMigrationNonce = 0 + const mockEncodedData = ethers.utils.defaultAbiCoder.encode(['bytes', 'address', 'bytes32', 'string', 'address', 'uint256', 'uint128'], [publicKeyBytes, r1Facet.address, encodedFuncSelectorsHash, 'MigrateSignature', mockBarz.address, chainId, mockMigrationNonce]) + const mockHash = keccak256(mockEncodedData) + const mockSignature1 = await guardian1.signMessage(arrayify(mockHash)) + const mockSignerSignature = await owner.signMessage(arrayify(mockHash)) + + const mockAccountBarz = await getFacetBarz("AccountFacet", mockBarz) + const mockGuardianBarz = await getFacetBarz("GuardianFacet", mockBarz) + const mockMigrationBarz = await getFacetBarz("SignatureMigrationFacet", mockBarz) + await addGuardianMock(guardian1, mockGuardianBarz, mockAccountBarz) + await addGuardianMock(guardian2, mockGuardianBarz, mockAccountBarz) + + + const migrateSignatureCall = migrationBarz.interface.encodeFunctionData('migrateSignatureSchemeWithGuardian', [r1Facet.address, publicKeyBytes, getSelectors(r1Facet), [guardian1.address, guardian1.address, barz.address], [mockSignature1, mockSignature1, mockSignerSignature]]) + + await expect(mockAccountBarz.connect(mockEntryPoint).execute(mockAccountBarz.address, 0, migrateSignatureCall)).to.be.revertedWithCustomError(mockMigrationBarz, "DuplicateApprover") + }) + it('Should emit Migration Execution event', async () => { + await setupBarz(k1Facet, owner.publicKey) + await addFacetsK1() + + const { publicKeyBytes } = generateKeyPair() + await addGuardian(guardian1) + + const encodedFuncSelectors = ethers.utils.defaultAbiCoder.encode(['bytes4[]'], [getSelectors(r1Facet)]) + const encodedFuncSelectorsHash = keccak256(encodedFuncSelectors) + + const encodedData = ethers.utils.defaultAbiCoder.encode(['bytes', 'address', 'bytes32', 'string', 'address', 'uint256', 'uint128'], [publicKeyBytes, r1Facet.address, encodedFuncSelectorsHash, 'MigrateSignature', migrationBarz.address, chainId, migrationNonce]) + const hash = keccak256(encodedData) + const signature1 = await guardian1.signMessage(arrayify(hash)) + const prefixedHash = getEthSignMessageHash(hash) + + const finalHash = await getMessageHash(prefixedHash, await getChainId(), barz.address) + const sig = ecsign(Buffer.from(ethers.utils.arrayify(finalHash)), Buffer.from(ethers.utils.arrayify(owner.privateKey))) + + const signerSignature = toRpcSig(sig.v, sig.r, sig.s) + const migrateSignatureCall = migrationBarz.interface.encodeFunctionData('migrateSignatureSchemeWithGuardian', [r1Facet.address, publicKeyBytes, getSelectors(r1Facet), [guardian1.address, barz.address], [signature1, signerSignature]]) + const migrateSignatureCallData = executeCallData(migrationBarz.address, 0, migrateSignatureCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, migrateSignatureCallData)).to.emit(migrationBarz, 'SignatureMigrationExecuted') + }) + it('Should revert if new verification facet is unregistered to facet registry', async () => { + await setupBarz(k1Facet, owner.publicKey) + await addFacetsK1() + + const { publicKeyBytes } = generateKeyPair() + await addGuardian(guardian1) + await addGuardianMock(guardian1, await getFacetBarz("GuardianFacet", mockBarz), await getFacetBarz("AccountFacet", mockBarz)) + + const encodedFuncSelectors = ethers.utils.defaultAbiCoder.encode(['bytes4[]'], [getSelectors(unregisteredR1Facet)]) + const encodedFuncSelectorsHash = keccak256(encodedFuncSelectors) + + const encodedData = ethers.utils.defaultAbiCoder.encode(['bytes', 'address', 'bytes32', 'string', 'address', 'uint256', 'uint128'], [publicKeyBytes, unregisteredR1Facet.address, encodedFuncSelectorsHash, 'MigrateSignature', mockMigrationBarz.address, chainId, migrationNonce]) + const hash = keccak256(encodedData) + const signature1 = await guardian1.signMessage(arrayify(hash)) + const prefixedHash = getEthSignMessageHash(hash) + + const finalHash = await getMessageHash(prefixedHash, await getChainId(), barz.address) + const sig = ecsign(Buffer.from(ethers.utils.arrayify(finalHash)), Buffer.from(ethers.utils.arrayify(owner.privateKey))) + + const signerSignature = toRpcSig(sig.v, sig.r, sig.s) + const migrateSignatureCall = migrationBarz.interface.encodeFunctionData('migrateSignatureSchemeWithGuardian', [unregisteredR1Facet.address, publicKeyBytes, getSelectors(unregisteredR1Facet), [guardian1.address, mockBarz.address], [signature1, signerSignature]]) + await expect(mockAccountBarz.connect(mockEntryPoint).execute(mockAccountBarz.address, 0, migrateSignatureCall)).to.revertedWithCustomError(mockMigrationBarz, "UnregisteredFacetAndSelectors") + }) + it('Should migrate signature scheme even when guardian is a SCW with Secp256k1 Verification Facet', async () => { + await setupBarz(k1Facet, owner.publicKey) + await addFacetsK1() + + const { publicKeyBytes } = generateKeyPair() + const guardian = await barzFixture(accountFacet, k1Facet, entryPoint, facetRegistry, defaultFallbackHandler, guardian1.publicKey) + await addGuardian(guardian) + let migrationNonce = 0 + expect(await migrationBarz.getMigrationNonce()).to.equal(migrationNonce) + + const encodedFuncSelectors = ethers.utils.defaultAbiCoder.encode(['bytes4[]'], [getSelectors(r1Facet)]) + const encodedFuncSelectorsHash = keccak256(encodedFuncSelectors) + + const encodedData = ethers.utils.defaultAbiCoder.encode(['bytes', 'address', 'bytes32', 'string', 'address', 'uint256', 'uint128'], [publicKeyBytes, r1Facet.address, encodedFuncSelectorsHash, 'MigrateSignature', migrationBarz.address, chainId, migrationNonce]) + const hash = keccak256(encodedData) + + const prefixedHash = getEthSignMessageHash(hash) + + const finalGuardianHash = await getMessageHash(prefixedHash, await getChainId(), guardian.address) + const guardianSig = ecsign(Buffer.from(ethers.utils.arrayify(finalGuardianHash)), Buffer.from(ethers.utils.arrayify(guardian1.privateKey))) + const signature1 = toRpcSig(guardianSig.v, guardianSig.r, guardianSig.s) + + const finalHash = await getMessageHash(prefixedHash, await getChainId(), barz.address) + const sig = ecsign(Buffer.from(ethers.utils.arrayify(finalHash)), Buffer.from(ethers.utils.arrayify(owner.privateKey))) + + const signerSignature = toRpcSig(sig.v, sig.r, sig.s) + const migrateSignatureCall = migrationBarz.interface.encodeFunctionData('migrateSignatureSchemeWithGuardian', [r1Facet.address, publicKeyBytes, getSelectors(r1Facet), [guardian.address, barz.address], [signature1, signerSignature]]) + const migrateSignatureCallData = executeCallData(migrationBarz.address, 0, migrateSignatureCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, migrateSignatureCallData)).to.emit(migrationBarz, 'SignatureMigrationExecuted') + expect(await migrationBarz.getMigrationNonce()).to.equal(++migrationNonce) + }) + it('Should migrate signature scheme even when guardian is a SCW with Secp256r1 Verification Facet', async () => { + await setupBarz(k1Facet, owner.publicKey) + await addFacetsK1() + const { keyPair, publicKeyBytes } = generateKeyPair() + const guardian = await barzFixture(accountFacet, r1Facet, entryPoint, facetRegistry, defaultFallbackHandler, publicKeyBytes) + await addGuardian(guardian) + let migrationNonce = 0 + expect(await migrationBarz.getMigrationNonce()).to.equal(migrationNonce) + + const encodedFuncSelectors = ethers.utils.defaultAbiCoder.encode(['bytes4[]'], [getSelectors(r1Facet)]) + const encodedFuncSelectorsHash = keccak256(encodedFuncSelectors) + + const encodedData = ethers.utils.defaultAbiCoder.encode(['bytes', 'address', 'bytes32', 'string', 'address', 'uint256', 'uint128'], [publicKeyBytes, r1Facet.address, encodedFuncSelectorsHash, 'MigrateSignature', migrationBarz.address, chainId, migrationNonce]) + const hash = keccak256(encodedData) + const ethSignMsgHash = keccak256(Buffer.concat([ + Buffer.from('\x19Ethereum Signed Message:\n32', 'ascii'), + Buffer.from(ethers.utils.arrayify(hash)) + ])) + const prefixedHash = getEthSignMessageHash(hash) + + const signature1 = await signMsgOnR1Curve(prefixedHash, keyPair) + + const finalHash = await getMessageHash(prefixedHash, await getChainId(), barz.address) + const sig = ecsign(Buffer.from(ethers.utils.arrayify(finalHash)), Buffer.from(ethers.utils.arrayify(owner.privateKey))) + + const signerSignature = toRpcSig(sig.v, sig.r, sig.s) + const migrateSignatureCall = migrationBarz.interface.encodeFunctionData('migrateSignatureSchemeWithGuardian', [r1Facet.address, publicKeyBytes, getSelectors(r1Facet), [guardian.address, barz.address], [signature1, signerSignature]]) + const migrateSignatureCallData = executeCallData(migrationBarz.address, 0, migrateSignatureCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, migrateSignatureCallData)).to.emit(migrationBarz, 'SignatureMigrationExecuted') + expect(await migrationBarz.getMigrationNonce()).to.equal(++migrationNonce) + }) + it('Should increment migration nonce', async () => { + await setupBarz(k1Facet, owner.publicKey) + await addFacetsK1() + + const { publicKeyBytes } = generateKeyPair() + await addGuardian(guardian1) + let migrationNonce = 0 + expect(await migrationBarz.getMigrationNonce()).to.equal(migrationNonce) + + const encodedFuncSelectors = ethers.utils.defaultAbiCoder.encode(['bytes4[]'], [getSelectors(r1Facet)]) + const encodedFuncSelectorsHash = keccak256(encodedFuncSelectors) + + const encodedData = ethers.utils.defaultAbiCoder.encode(['bytes', 'address', 'bytes32', 'string', 'address', 'uint256', 'uint128'], [publicKeyBytes, r1Facet.address, encodedFuncSelectorsHash, 'MigrateSignature', migrationBarz.address, chainId, migrationNonce]) + const hash = keccak256(encodedData) + const signature1 = await guardian1.signMessage(arrayify(hash)) + const prefixedHash = getEthSignMessageHash(hash) + + const finalHash = await getMessageHash(prefixedHash, await getChainId(), barz.address) + const sig = ecsign(Buffer.from(ethers.utils.arrayify(finalHash)), Buffer.from(ethers.utils.arrayify(owner.privateKey))) + + const signerSignature = toRpcSig(sig.v, sig.r, sig.s) + const migrateSignatureCall = migrationBarz.interface.encodeFunctionData('migrateSignatureSchemeWithGuardian', [r1Facet.address, publicKeyBytes, getSelectors(r1Facet), [guardian1.address, barz.address], [signature1, signerSignature]]) + const migrateSignatureCallData = executeCallData(migrationBarz.address, 0, migrateSignatureCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, migrateSignatureCallData)).to.emit(migrationBarz, 'SignatureMigrationExecuted') + expect(await migrationBarz.getMigrationNonce()).to.equal(++migrationNonce) + }) + it('Should migration signature with both on-chain and off-chain approval', async () => { + await setupBarz(k1Facet, owner.publicKey) + await addFacetsK1() + + const { publicKeyBytes } = generateKeyPair() + await addGuardian(guardian1) + await addGuardian(guardian2) + let migrationNonce = 0 + expect(await migrationBarz.getMigrationNonce()).to.equal(migrationNonce) + + await expect(migrationBarz.connect(guardian2).approveSignatureSchemeMigration(r1Facet.address, publicKeyBytes, getSelectors(r1Facet))).to.emit(migrationBarz, "SignatureMigrationApproved") + + const encodedFuncSelectors = ethers.utils.defaultAbiCoder.encode(['bytes4[]'], [getSelectors(r1Facet)]) + const encodedFuncSelectorsHash = keccak256(encodedFuncSelectors) + const encodedData = ethers.utils.defaultAbiCoder.encode(['bytes', 'address', 'bytes32', 'string', 'address', 'uint256', 'uint128'], [publicKeyBytes, r1Facet.address, encodedFuncSelectorsHash, 'MigrateSignature', migrationBarz.address, chainId, migrationNonce]) + const hash = keccak256(encodedData) + const signature1 = await guardian1.signMessage(arrayify(hash)) + const prefixedHash = getEthSignMessageHash(hash) + + const finalHash = await getMessageHash(prefixedHash, await getChainId(), barz.address) + const sig = ecsign(Buffer.from(ethers.utils.arrayify(finalHash)), Buffer.from(ethers.utils.arrayify(owner.privateKey))) + + const signerSignature = toRpcSig(sig.v, sig.r, sig.s) + const migrateSignatureCall = migrationBarz.interface.encodeFunctionData('migrateSignatureSchemeWithGuardian', [r1Facet.address, publicKeyBytes, getSelectors(r1Facet), [guardian1.address, barz.address], [signature1, signerSignature]]) + const migrateSignatureCallData = executeCallData(migrationBarz.address, 0, migrateSignatureCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, migrateSignatureCallData)).to.emit(migrationBarz, 'SignatureMigrationExecuted') + expect(await migrationBarz.getMigrationNonce()).to.equal(++migrationNonce) + }) + it('Should revert when approver approves with on-chain approval and reattempts off-chain approval', async () => { + await addGuardianMock(guardian1, await getFacetBarz("GuardianFacet", mockBarz), await getFacetBarz("AccountFacet", mockBarz)) + await addGuardianMock(guardian2, await getFacetBarz("GuardianFacet", mockBarz), await getFacetBarz("AccountFacet", mockBarz)) + + const mockMigrationBarz = await getFacetBarz("SignatureMigrationFacet", mockBarz) + + const { publicKeyBytes } = generateKeyPair() + + await expect(mockMigrationBarz.connect(guardian1).approveSignatureSchemeMigration(r1Facet.address, publicKeyBytes, getSelectors(r1Facet))).to.emit(mockMigrationBarz, "SignatureMigrationApproved") + + const encodedFuncSelectors = ethers.utils.defaultAbiCoder.encode(['bytes4[]'], [getSelectors(r1Facet)]) + const encodedFuncSelectorsHash = keccak256(encodedFuncSelectors) + const encodedData = ethers.utils.defaultAbiCoder.encode(['bytes', 'address', 'bytes32', 'string', 'address', 'uint256', 'uint128'], [publicKeyBytes, r1Facet.address, encodedFuncSelectorsHash, 'MigrateSignature', migrationBarz.address, chainId, migrationNonce]) + const hash = keccak256(encodedData) + const signature1 = await guardian1.signMessage(arrayify(hash)) + const prefixedHash = getEthSignMessageHash(hash) + + const finalHash = await getMessageHash(prefixedHash, await getChainId(), barz.address) + const sig = ecsign(Buffer.from(ethers.utils.arrayify(finalHash)), Buffer.from(ethers.utils.arrayify(owner.privateKey))) + + const signerSignature = toRpcSig(sig.v, sig.r, sig.s) + const migrateSignatureCall = migrationBarz.interface.encodeFunctionData('migrateSignatureSchemeWithGuardian', [r1Facet.address, publicKeyBytes, getSelectors(r1Facet), [guardian1.address, barz.address], [signature1, signerSignature]]) + await expect(mockAccountBarz.connect(mockEntryPoint).execute(mockAccountBarz.address, 0, migrateSignatureCall)).to.be.revertedWithCustomError(mockMigrationBarz, "SignatureMigrationFacet__DuplicateApproval") + }) + }) + describe('# approveSignatureSchemeMigration', () => { + it('Should revert if caller is not guardian/owner', async () => { + await setupBarz(k1Facet, owner.publicKey) + await addFacetsK1() + + const { publicKeyBytes } = generateKeyPair() + + await expect(migrationBarz.connect(user1).approveSignatureSchemeMigration(r1Facet.address, publicKeyBytes, getSelectors(r1Facet))).to.be.revertedWithCustomError(migrationBarz, "CallerNotGuardianOrOwner") + }) + it('Should increase migration approval count', async () => { + await setupBarz(k1Facet, owner.publicKey) + await addFacetsK1() + + const { publicKeyBytes } = generateKeyPair() + await addGuardian(guardian1) + let approvalCount = 0 + const encodedFuncSelectors = ethers.utils.defaultAbiCoder.encode(['bytes4[]'], [getSelectors(r1Facet)]) + const encodedFuncSelectorsHash = keccak256(encodedFuncSelectors) + const encodedData = ethers.utils.defaultAbiCoder.encode(['bytes', 'address', 'bytes32', 'string', 'address', 'uint256', 'uint128'], [publicKeyBytes, r1Facet.address, encodedFuncSelectorsHash, 'MigrateSignature', migrationBarz.address, chainId, migrationNonce]) + const hash = keccak256(encodedData) + const signMessageHash = getEthSignMessageHash(hash) + expect(await migrationBarz.getMigrationApprovalCountWithTimeValidity(signMessageHash)).to.equal(approvalCount) + + await expect(migrationBarz.connect(guardian1).approveSignatureSchemeMigration(r1Facet.address, publicKeyBytes, getSelectors(r1Facet))).to.emit(migrationBarz, "SignatureMigrationApproved") + + expect(await migrationBarz.getMigrationApprovalCountWithTimeValidity(signMessageHash)).to.equal(++approvalCount) + }) + it('Should migrate signature scheme when owner approves with no guardian in wallet', async () => { + await setupBarz(k1Facet, owner.publicKey) + await addFacetsK1() + + const { publicKeyBytes } = generateKeyPair() + const approvalCount = 0 + const encodedFuncSelectors = ethers.utils.defaultAbiCoder.encode(['bytes4[]'], [getSelectors(r1Facet)]) + const encodedFuncSelectorsHash = keccak256(encodedFuncSelectors) + const encodedData = ethers.utils.defaultAbiCoder.encode(['bytes', 'address', 'bytes32', 'string', 'address', 'uint256', 'uint128'], [publicKeyBytes, r1Facet.address, encodedFuncSelectorsHash, 'MigrateSignature', migrationBarz.address, chainId, migrationNonce]) + const hash = keccak256(encodedData) + const signMessageHash = getEthSignMessageHash(hash) + expect(await migrationBarz.getMigrationApprovalCountWithTimeValidity(signMessageHash)).to.equal(approvalCount) + + const approveMigrationCall = migrationBarz.interface.encodeFunctionData('approveSignatureSchemeMigration', [r1Facet.address, publicKeyBytes, getSelectors(r1Facet)]) + const approveMigrationCallData = executeCallData(migrationBarz.address, 0, approveMigrationCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, approveMigrationCallData)).to.emit(migrationBarz, 'SignatureMigrationExecuted') + + expect(await migrationBarz.getMigrationOwnerApprovalWithTimeValidity(signMessageHash)).to.be.true + expect(await migrationBarz.isMigrationPending()).to.be.true + }) + it('Should not execute migration if 1 guardian exists and only owner approves', async () => { + await setupBarz(k1Facet, owner.publicKey) + await addFacetsK1() + + const { publicKeyBytes } = generateKeyPair() + await addGuardian(guardian1) + + const approvalCount = 0 + const encodedFuncSelectors = ethers.utils.defaultAbiCoder.encode(['bytes4[]'], [getSelectors(r1Facet)]) + const encodedFuncSelectorsHash = keccak256(encodedFuncSelectors) + const encodedData = ethers.utils.defaultAbiCoder.encode(['bytes', 'address', 'bytes32', 'string', 'address', 'uint256', 'uint128'], [publicKeyBytes, r1Facet.address, encodedFuncSelectorsHash, 'MigrateSignature', migrationBarz.address, chainId, migrationNonce]) + const hash = keccak256(encodedData) + const signMessageHash = getEthSignMessageHash(hash) + expect(await migrationBarz.getMigrationApprovalCountWithTimeValidity(signMessageHash)).to.equal(approvalCount) + + const approveMigrationCall = migrationBarz.interface.encodeFunctionData('approveSignatureSchemeMigration', [r1Facet.address, publicKeyBytes, getSelectors(r1Facet)]) + const approveMigrationCallData = executeCallData(migrationBarz.address, 0, approveMigrationCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, approveMigrationCallData)).to.not.emit(migrationBarz, 'SignatureMigrationExecuted') + + expect(await migrationBarz.getMigrationApprovalCountWithTimeValidity(signMessageHash)).to.equal(0) + expect(await migrationBarz.getMigrationOwnerApprovalWithTimeValidity(signMessageHash)).to.be.true + expect(await migrationBarz.isMigrationPending()).to.be.false + }) + it('Should migrate signature schememe when 1 guardian exists and owner + 1 guardian approves', async () => { + await setupBarz(k1Facet, owner.publicKey) + await addFacetsK1() + + const { publicKeyBytes } = generateKeyPair() + await addGuardian(guardian1) + + const encodedFuncSelectors = ethers.utils.defaultAbiCoder.encode(['bytes4[]'], [getSelectors(r1Facet)]) + const encodedFuncSelectorsHash = keccak256(encodedFuncSelectors) + const encodedData = ethers.utils.defaultAbiCoder.encode(['bytes', 'address', 'bytes32', 'string', 'address', 'uint256', 'uint128'], [publicKeyBytes, r1Facet.address, encodedFuncSelectorsHash, 'MigrateSignature', migrationBarz.address, chainId, migrationNonce]) + const hash = keccak256(encodedData) + const signMessageHash = getEthSignMessageHash(hash) + expect(await migrationBarz.getMigrationApprovalCountWithTimeValidity(signMessageHash)).to.equal(0) + + const approveMigrationCall = migrationBarz.interface.encodeFunctionData('approveSignatureSchemeMigration', [r1Facet.address, publicKeyBytes, getSelectors(r1Facet)]) + const approveMigrationCallData = executeCallData(migrationBarz.address, 0, approveMigrationCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, approveMigrationCallData)).to.not.emit(migrationBarz, 'SignatureMigrationExecuted') + + await expect(migrationBarz.connect(guardian1).approveSignatureSchemeMigration(r1Facet.address, publicKeyBytes, getSelectors(r1Facet))).to.emit(migrationBarz, "SignatureMigrationExecuted") + + expect(await migrationBarz.getMigrationApprovalCountWithTimeValidity(signMessageHash)).to.equal(1) + expect(await migrationBarz.getMigrationOwnerApprovalWithTimeValidity(signMessageHash)).to.be.true + expect(await migrationBarz.isMigrationPending()).to.be.true + }) + it('Should automatically migration signature if majority of guardian + owner approve', async () => { + await setupBarz(k1Facet, owner.publicKey) + await addFacetsK1() + + const { publicKeyBytes } = generateKeyPair() + await addGuardian(guardian1) + await addGuardian(guardian2) + + let approvalMigrationNonce = 0 + const encodedFuncSelectors = ethers.utils.defaultAbiCoder.encode(['bytes4[]'], [getSelectors(r1Facet)]) + const encodedFuncSelectorsHash = keccak256(encodedFuncSelectors) + const encodedData = ethers.utils.defaultAbiCoder.encode(['bytes', 'address', 'bytes32', 'string', 'address', 'uint256', 'uint128'], [publicKeyBytes, r1Facet.address, encodedFuncSelectorsHash, 'MigrateSignature', migrationBarz.address, chainId, migrationNonce]) + const hash = keccak256(encodedData) + const signMessageHash = getEthSignMessageHash(hash) + expect(await migrationBarz.getMigrationNonce()).to.equal(approvalMigrationNonce) + + await expect(migrationBarz.connect(guardian1).approveSignatureSchemeMigration(r1Facet.address, publicKeyBytes, getSelectors(r1Facet))).to.emit(migrationBarz, "SignatureMigrationApproved") + expect(await migrationBarz.getMigrationApprovalCountWithTimeValidity(signMessageHash)).to.equal(1) + + await expect(migrationBarz.connect(guardian2).approveSignatureSchemeMigration(r1Facet.address, publicKeyBytes, getSelectors(r1Facet))).to.emit(migrationBarz, "SignatureMigrationApproved") + expect(await migrationBarz.getMigrationApprovalCountWithTimeValidity(signMessageHash)).to.equal(2) + + const approveSignatureSchemeMigrationCall = migrationBarz.interface.encodeFunctionData("approveSignatureSchemeMigration", [r1Facet.address, publicKeyBytes, getSelectors(r1Facet)]) + const approveSignatureSchemeMigrationCallData = executeCallData(migrationBarz.address, 0, approveSignatureSchemeMigrationCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, approveSignatureSchemeMigrationCallData)).to.emit(migrationBarz, "SignatureMigrationExecuted") + + expect(await migrationBarz.getMigrationNonce()).to.equal(++approvalMigrationNonce) + }) + it('Should deduct approval if approval validation period passes', async () => { + await setupBarz(k1Facet, owner.publicKey) + await addFacetsK1() + + const { publicKeyBytes } = generateKeyPair() + await addGuardian(guardian1) + await addGuardian(guardian2) + + const encodedFuncSelectors = ethers.utils.defaultAbiCoder.encode(['bytes4[]'], [getSelectors(r1Facet)]) + const encodedFuncSelectorsHash = keccak256(encodedFuncSelectors) + const encodedData = ethers.utils.defaultAbiCoder.encode(['bytes', 'address', 'bytes32', 'string', 'address', 'uint256', 'uint128'], [publicKeyBytes, r1Facet.address, encodedFuncSelectorsHash, 'MigrateSignature', migrationBarz.address, chainId, migrationNonce]) + const hash = keccak256(encodedData) + const signMessageHash = getEthSignMessageHash(hash) + expect(await migrationBarz.getMigrationApprovalCountWithTimeValidity(signMessageHash)).to.equal(0) + + await expect(migrationBarz.connect(guardian1).approveSignatureSchemeMigration(r1Facet.address, publicKeyBytes, getSelectors(r1Facet))).to.emit(migrationBarz, "SignatureMigrationApproved") + expect(await migrationBarz.getMigrationApprovalCountWithTimeValidity(signMessageHash)).to.equal(1) + await increaseBlockTime(approvalValidationPeriod + 1) + expect(await migrationBarz.getMigrationApprovalCountWithTimeValidity(signMessageHash)).to.equal(0) + }) + it('Should emit Migration Approved event', async () => { + await setupBarz(k1Facet, owner.publicKey) + await addFacetsK1() + + const { publicKeyBytes } = generateKeyPair() + await addGuardian(guardian1) + await addGuardian(guardian2) + + const approvalMigrationNonce = 0 + const encodedFuncSelectors = ethers.utils.defaultAbiCoder.encode(['bytes4[]'], [getSelectors(r1Facet)]) + const encodedFuncSelectorsHash = keccak256(encodedFuncSelectors) + const encodedData = ethers.utils.defaultAbiCoder.encode(['bytes', 'address', 'bytes32', 'string', 'address', 'uint256', 'uint128'], [publicKeyBytes, r1Facet.address, encodedFuncSelectorsHash, 'MigrateSignature', migrationBarz.address, chainId, migrationNonce]) + const hash = keccak256(encodedData) + const signMessageHash = getEthSignMessageHash(hash) + expect(await migrationBarz.getMigrationNonce()).to.equal(approvalMigrationNonce) + await expect(migrationBarz.connect(guardian1).approveSignatureSchemeMigration(r1Facet.address, publicKeyBytes, getSelectors(r1Facet))).to.emit(migrationBarz, "SignatureMigrationApproved") + expect(await migrationBarz.getMigrationApprovalCountWithTimeValidity(signMessageHash)).to.equal(1) + }) + it('Should revert if new verification facet is unregistered to facet registry', async () => { + await setupBarz(k1Facet, owner.publicKey) + await addFacetsK1() + + const { publicKeyBytes } = generateKeyPair() + await addGuardian(guardian1) + await addGuardian(guardian2) + + await expect(migrationBarz.connect(guardian1).approveSignatureSchemeMigration(unregisteredR1Facet.address, publicKeyBytes, getSelectors(unregisteredR1Facet))).to.revertedWithCustomError(migrationBarz, "UnregisteredFacetAndSelectors") + await expect(migrationBarz.connect(guardian2).approveSignatureSchemeMigration(unregisteredR1Facet.address, publicKeyBytes, getSelectors(unregisteredR1Facet))).to.revertedWithCustomError(migrationBarz, "UnregisteredFacetAndSelectors") + }) + }) + describe('# revokeSignatureMigrationApproval', () => { + it('Should revert if caller is not guardian/owner', async () => { + await setupBarz(k1Facet, owner.publicKey) + await addFacetsK1() + const { publicKeyBytes } = generateKeyPair() + + await expect(migrationBarz.connect(user1).revokeSignatureMigrationApproval(r1Facet.address, publicKeyBytes, getSelectors(r1Facet))).to.be.revertedWithCustomError(migrationBarz, "CallerNotGuardianOrOwner") + }) + it('Should revert if new public key length is not valid', async () => { + await setupBarz(k1Facet, owner.publicKey) + await addFacetsK1() + const { publicKeyBytes } = generateKeyPair() + await addGuardian(guardian1) + await expect(migrationBarz.connect(guardian1).revokeSignatureMigrationApproval(r1Facet.address, publicKeyBytes + "1111", getSelectors(r1Facet))).to.be.revertedWithCustomError(migrationBarz, "SignatureMigrationFacet__InvalidKeyType") + }) + it('Should revert if approval to revoke was not approved', async () => { + await setupBarz(k1Facet, owner.publicKey) + await addFacetsK1() + const { publicKeyBytes } = generateKeyPair() + await addGuardian(guardian1) + await expect(migrationBarz.connect(guardian1).revokeSignatureMigrationApproval(r1Facet.address, publicKeyBytes, getSelectors(r1Facet))).to.be.revertedWithCustomError(migrationBarz, "SignatureMigrationFacet__CannotRevokeUnapproved") + }) + it('Should decrease migration approval count', async () => { + await setupBarz(k1Facet, owner.publicKey) + await addFacetsK1() + const { publicKeyBytes } = generateKeyPair() + await addGuardian(guardian1) + await addGuardian(guardian2) + + const hash = await getSignedMigrationHash(r1Facet, publicKeyBytes, migrationBarz, migrationNonce) + const signMessageHash = getEthSignMessageHash(hash) + expect(await migrationBarz.getMigrationApprovalCountWithTimeValidity(signMessageHash)).to.equal(0) + + await expect(migrationBarz.connect(guardian1).approveSignatureSchemeMigration(r1Facet.address, publicKeyBytes, getSelectors(r1Facet))).to.emit(migrationBarz, "SignatureMigrationApproved") + expect(await migrationBarz.getMigrationApprovalCountWithTimeValidity(signMessageHash)).to.equal(1) + + await expect(migrationBarz.connect(guardian1).revokeSignatureMigrationApproval(r1Facet.address, publicKeyBytes, getSelectors(r1Facet))).to.emit(migrationBarz, "SignatureMigrationApprovalRevoked") + expect(await migrationBarz.getMigrationApprovalCountWithTimeValidity(signMessageHash)).to.equal(0) + + }) + it('Should emit Migration Revoked event', async () => { + await setupBarz(k1Facet, owner.publicKey) + await addFacetsK1() + + const { publicKeyBytes } = generateKeyPair() + await addGuardian(guardian1) + await addGuardian(guardian2) + + const hash = await getSignedMigrationHash(r1Facet, publicKeyBytes, migrationBarz, migrationNonce) + const signMessageHash = getEthSignMessageHash(hash) + expect(await migrationBarz.getMigrationApprovalCountWithTimeValidity(signMessageHash)).to.equal(0) + + await expect(migrationBarz.connect(guardian1).approveSignatureSchemeMigration(r1Facet.address, publicKeyBytes, getSelectors(r1Facet))).to.emit(migrationBarz, "SignatureMigrationApproved") + expect(await migrationBarz.getMigrationApprovalCountWithTimeValidity(signMessageHash)).to.equal(1) + + await expect(migrationBarz.connect(guardian1).revokeSignatureMigrationApproval(r1Facet.address, publicKeyBytes, getSelectors(r1Facet))).to.emit(migrationBarz, "SignatureMigrationApprovalRevoked") + }) + }) + describe('# finalizeSignatureMigration', () => { + it('Should revert if uninitializeSigner() does not exist', async () => { + await setupBarz(k1Facet, owner.publicKey) + await addFacetsK1() + + const { publicKeyBytes } = generateKeyPair() + let migrationNonce = 0 + expect(await migrationBarz.getMigrationNonce()).to.equal(migrationNonce) + const cut = diamondCut(AddressZero, FacetCutAction.Remove, [k1Facet.interface.getSighash('uninitializeSigner')]) + const diamondCutCall = diamondCutFacet.interface.encodeFunctionData('diamondCut', [cut, AddressZero, "0x00"]) + const diamondCutCallData = executeCallData(diamondCutBarz.address, 0, diamondCutCall) + await callFromEntryPointOnK1(entryPoint, barz.address, owner, diamondCutCallData) + + await addGuardian(guardian1) + + const hash = await getSignedMigrationHash(r1Facet, publicKeyBytes, migrationBarz, migrationNonce) + const signature1 = await guardian1.signMessage(arrayify(hash)) + const prefixedHash = getEthSignMessageHash(hash) + + const finalHash = await getMessageHash(prefixedHash, await getChainId(), barz.address) + const sig = ecsign(Buffer.from(ethers.utils.arrayify(finalHash)), Buffer.from(ethers.utils.arrayify(owner.privateKey))) + + const signerSignature = toRpcSig(sig.v, sig.r, sig.s) + const migrateSignatureCall = migrationBarz.interface.encodeFunctionData('migrateSignatureSchemeWithGuardian', [r1Facet.address, publicKeyBytes, getSelectors(r1Facet), [guardian1.address, barz.address], [signature1, signerSignature]]) + const migrateSignatureCallData = executeCallData(migrationBarz.address, 0, migrateSignatureCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, migrateSignatureCallData)).to.emit(migrationBarz, 'SignatureMigrationExecuted') + expect(await migrationBarz.getMigrationNonce()).to.equal(++migrationNonce) + + await increaseBlockTime(migrationPeriod) + const finalizeMigrationCall = migrationBarz.interface.encodeFunctionData('finalizeSignatureMigration') + await callFromEntryPointOnK1(entryPoint, barz.address, owner, finalizeMigrationCall) + }) + it('Should revert if not pending migration', async () => { + await setupBarz(k1Facet, owner.publicKey) + + await addFacetsK1() + const finalizeMigrationCall = migrationBarz.interface.encodeFunctionData('finalizeSignatureMigration') + + await callFromEntryPointOnK1(entryPoint, barz.address, owner, finalizeMigrationCall) + expect(await migrationBarz.getMigrationNonce()).to.equal(0) + + const customMigrationBarz = await getFacetBarz("SignatureMigrationFacet", mockBarz) + const customAccountBarz = await getFacetBarz("AccountFacet", mockBarz) + await expect(customAccountBarz.connect(mockEntryPoint).execute(customAccountBarz.address, 0, finalizeMigrationCall)).to.be.revertedWithCustomError(customMigrationBarz, "SignatureMigrationFacet__NonexistentMigration") + }) + it('Should revert if migration period not passed', async () => { + await setupBarz(k1Facet, owner.publicKey) + await addFacetsK1() + + const { publicKeyBytes } = generateKeyPair() + await addGuardian(guardian1) + let migrationNonce = 0 + expect(await migrationBarz.getMigrationNonce()).to.equal(migrationNonce) + + const hash = await getSignedMigrationHash(r1Facet, publicKeyBytes, migrationBarz, migrationNonce) + const signature1 = await guardian1.signMessage(arrayify(hash)) + const prefixedHash = getEthSignMessageHash(hash) + + const finalHash = await getMessageHash(prefixedHash, await getChainId(), barz.address) + const sig = ecsign(Buffer.from(ethers.utils.arrayify(finalHash)), Buffer.from(ethers.utils.arrayify(owner.privateKey))) + + const signerSignature = toRpcSig(sig.v, sig.r, sig.s) + const migrateSignatureCall = migrationBarz.interface.encodeFunctionData('migrateSignatureSchemeWithGuardian', [r1Facet.address, publicKeyBytes, getSelectors(r1Facet), [guardian1.address, barz.address], [signature1, signerSignature]]) + const migrateSignatureCallData = executeCallData(migrationBarz.address, 0, migrateSignatureCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, migrateSignatureCallData)).to.emit(migrationBarz, 'SignatureMigrationExecuted') + expect(await migrationBarz.getMigrationNonce()).to.equal(++migrationNonce) + + const accountBarz = await getFacetBarz("AccountFacet", mockBarz) + const finalizeMigrationCall = migrationFacet.interface.encodeFunctionData('finalizeSignatureMigration') + await addGuardianMock(guardian1, await getFacetBarz("GuardianFacet", mockBarz), await getFacetBarz("AccountFacet", mockBarz)) + + const mockMigrationNonce = 0 + expect(await mockMigrationBarz.getMigrationNonce()).to.equal(mockMigrationNonce) + + const mockHash = await getSignedMigrationHash(r1Facet, publicKeyBytes, mockMigrationBarz, mockMigrationNonce) + const mockSignature1 = await guardian1.signMessage(arrayify(mockHash)) + const mockPrefixedHash = getEthSignMessageHash(mockHash) + + const mockFinalHash = await getMessageHash(mockPrefixedHash, await getChainId(), mockBarz.address) + const mockSig = ecsign(Buffer.from(ethers.utils.arrayify(mockFinalHash)), Buffer.from(ethers.utils.arrayify(owner.privateKey))) + + const mockSignerSignature = toRpcSig(mockSig.v, mockSig.r, mockSig.s) + await mockMigrationBarz.migrateSignatureSchemeWithGuardian(r1Facet.address, publicKeyBytes, getSelectors(r1Facet), [guardian1.address, mockBarz.address], [mockSignature1, mockSignerSignature]) + + await expect(accountBarz.connect(mockEntryPoint).execute(accountBarz.address, 0, finalizeMigrationCall)).to.be.revertedWithCustomError(migrationBarz, "SignatureMigrationFacet__MigrationPeriodNotOver") + }) + it('Should switch owner and signature scheme', async () => { + await setupBarz(k1Facet, owner.publicKey) + await addFacetsK1() + + const { keyPair, publicKeyBytes, facetOwnerKey } = generateKeyPair() + await addGuardian(guardian1) + let migrationNonce = 0 + expect(await migrationBarz.getMigrationNonce()).to.equal(migrationNonce) + + const hash = await getSignedMigrationHash(r1Facet, publicKeyBytes, migrationBarz, migrationNonce) + const signature1 = await guardian1.signMessage(arrayify(hash)) + const prefixedHash = getEthSignMessageHash(hash) + + const finalHash = await getMessageHash(prefixedHash, await getChainId(), barz.address) + const sig = ecsign(Buffer.from(ethers.utils.arrayify(finalHash)), Buffer.from(ethers.utils.arrayify(owner.privateKey))) + + const signerSignature = toRpcSig(sig.v, sig.r, sig.s) + const migrateSignatureCall = migrationBarz.interface.encodeFunctionData('migrateSignatureSchemeWithGuardian', [r1Facet.address, publicKeyBytes, getSelectors(r1Facet), [guardian1.address, barz.address], [signature1, signerSignature]]) + const migrateSignatureCallData = executeCallData(migrationBarz.address, 0, migrateSignatureCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, migrateSignatureCallData)).to.emit(migrationBarz, 'SignatureMigrationExecuted') + expect(await migrationBarz.getMigrationNonce()).to.equal(++migrationNonce) + + await increaseBlockTime(migrationPeriod) + + const finalizeMigrationCall = migrationBarz.interface.encodeFunctionData('finalizeSignatureMigration') + const finalizeMigrationCallData = executeCallData(migrationBarz.address, 0, finalizeMigrationCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, finalizeMigrationCallData)).to.emit(migrationBarz, "SignatureSchemeMigration") + + // Check if Owner/Signature is switched + const r1Barz = await getFacetBarz('Secp256r1VerificationFacet', barz) + expect(await r1Barz.owner()).to.equal(facetOwnerKey) + await expect(callFromEntryPointOnR1(entryPoint, barz.address, keyPair, "0x00")).to.emit(accountBarz, "VerificationSuccess") + }) + it('Should emit Migration event', async () => { + await setupBarz(k1Facet, owner.publicKey) + await addFacetsK1() + + const { publicKeyBytes } = generateKeyPair() + await addGuardian(guardian1) + let migrationNonce = 0 + expect(await migrationBarz.getMigrationNonce()).to.equal(migrationNonce) + + const hash = await getSignedMigrationHash(r1Facet, publicKeyBytes, migrationBarz, migrationNonce) + const signature1 = await guardian1.signMessage(arrayify(hash)) + const prefixedHash = getEthSignMessageHash(hash) + + const finalHash = await getMessageHash(prefixedHash, await getChainId(), barz.address) + const sig = ecsign(Buffer.from(ethers.utils.arrayify(finalHash)), Buffer.from(ethers.utils.arrayify(owner.privateKey))) + + const signerSignature = toRpcSig(sig.v, sig.r, sig.s) + const migrateSignatureCall = migrationBarz.interface.encodeFunctionData('migrateSignatureSchemeWithGuardian', [r1Facet.address, publicKeyBytes, getSelectors(r1Facet), [guardian1.address, barz.address], [signature1, signerSignature]]) + const migrateSignatureCallData = executeCallData(migrationBarz.address, 0, migrateSignatureCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, migrateSignatureCallData)).to.emit(migrationBarz, 'SignatureMigrationExecuted') + expect(await migrationBarz.getMigrationNonce()).to.equal(++migrationNonce) + await increaseBlockTime(migrationPeriod) + + const finalizeMigrationCall = migrationBarz.interface.encodeFunctionData('finalizeSignatureMigration') + const finalizeMigrationCallData = executeCallData(migrationBarz.address, 0, finalizeMigrationCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, finalizeMigrationCallData)).to.emit(migrationBarz, "SignatureSchemeMigration") + }) + it('Should revert if new verification facet is unregistered to facet registry', async () => { + await setupBarz(k1Facet, owner.publicKey) + await addFacetsK1() + const { publicKeyBytes } = generateKeyPair() + const migrationNonce = 0 + expect(await migrationBarz.getMigrationNonce()).to.equal(migrationNonce) + const migrateSignatureCall = migrationBarz.interface.encodeFunctionData("migrateSignatureScheme", [r1Facet.address, publicKeyBytes, getSelectors(r1Facet)]) + + await mockAccountBarz.connect(mockEntryPoint).execute(mockAccountBarz.address, 0, migrateSignatureCall) + await increaseBlockTime(migrationPeriod) + + // Remove from Facet Registry + await facetRegistry.connect(facetRegistryOwner).removeFacetFunctionSelectors(r1Facet.address, getSelectors(r1Facet)) + + const finalizationCall = migrationFacet.interface.encodeFunctionData('finalizeSignatureMigration') + await expect(mockAccountBarz.connect(mockEntryPoint).execute(mockMigrationBarz.address, 0, finalizationCall)).to.revertedWithCustomError(mockMigrationBarz, "UnregisteredFacetAndSelectors") + + // Add it back + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(r1Facet.address, getSelectors(r1Facet)) + }) + }) + describe('# approveCancelSignatureMigration', () => { + it('Should revert if caller is not guardian/owner', async () => { + await setupBarz(k1Facet, owner.publicKey) + await addFacetsK1() + + const { publicKeyBytes } = generateKeyPair() + + await expect(migrationBarz.connect(user1).approveCancelSignatureMigration(r1Facet.address, publicKeyBytes, getSelectors(r1Facet))).to.be.revertedWithCustomError(migrationBarz, "CallerNotGuardianOrOwner") + }) + it('Should revert if new public key length is not valid', async () => { + await setupBarz(k1Facet, owner.publicKey) + await addFacetsK1() + + const { publicKeyBytes } = generateKeyPair() + await addGuardian(guardian1) + + await expect(migrationBarz.connect(guardian1).approveCancelSignatureMigration(r1Facet.address, publicKeyBytes + "1111", getSelectors(r1Facet))).to.be.revertedWithCustomError(migrationBarz, "SignatureMigrationFacet__InvalidKeyType") + }) + it('Should emit Migration Cancellation Approved event', async () => { + await setupBarz(k1Facet, owner.publicKey) + await addFacetsK1() + + const { publicKeyBytes } = generateKeyPair() + await addGuardian(guardian1) + + await expect(migrationBarz.connect(guardian1).approveCancelSignatureMigration(r1Facet.address, publicKeyBytes, getSelectors(r1Facet))).to.emit(migrationBarz, "SignatureMigrationCancellationApproved") + .withArgs(r1Facet.address, publicKeyBytes, getSelectors(r1Facet)) + }) + it('Should cancel signature schememe migration when 1 guardian exists and owner + 1 guardian approves', async () => { + await setupBarz(k1Facet, owner.publicKey) + await addFacetsK1() + await addGuardian(guardian1) + const { publicKeyBytes } = generateKeyPair() + + const hash = await getSignedMigrationHash(r1Facet, publicKeyBytes, migrationBarz, migrationNonce) + const signature1 = await guardian1.signMessage(arrayify(hash)) + const prefixedHash = getEthSignMessageHash(hash) + + const finalHash = await getMessageHash(prefixedHash, await getChainId(), migrationBarz.address) + const sig = ecsign(Buffer.from(ethers.utils.arrayify(finalHash)), Buffer.from(ethers.utils.arrayify(owner.privateKey))) + + const signerSignature = toRpcSig(sig.v, sig.r, sig.s) + await expect(migrationBarz.migrateSignatureSchemeWithGuardian(r1Facet.address, publicKeyBytes, getSelectors(r1Facet), [guardian1.address, barz.address], [signature1, signerSignature])).to.emit(migrationBarz, "SignatureMigrationExecuted") + + await expect(migrationBarz.connect(guardian1).approveCancelSignatureMigration(r1Facet.address, publicKeyBytes, getSelectors(r1Facet))).to.emit(migrationBarz, "SignatureMigrationCancellationApproved") + .withArgs(r1Facet.address, publicKeyBytes, getSelectors(r1Facet)) + + const migrationCall = migrationBarz.interface.encodeFunctionData("approveCancelSignatureMigration", [r1Facet.address, publicKeyBytes, getSelectors(r1Facet)]) + const migrationCallData = executeCallData(migrationBarz.address, 0, migrationCall) + + expect(await migrationBarz.isMigrationPending()).to.be.true + + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, migrationCallData)).to.emit(migrationBarz, "SignatureMigrationCanceled").withArgs(r1Facet.address, publicKeyBytes, getSelectors(r1Facet)) + + expect(await migrationBarz.isMigrationPending()).to.be.false + }) + it('Should not execute migration cancellation if 1 guardian exists and only owner approves', async () => { + await setupBarz(k1Facet, owner.publicKey) + await addFacetsK1() + await addGuardian(guardian1) + const { publicKeyBytes } = generateKeyPair() + + const hash = await getSignedMigrationHash(r1Facet, publicKeyBytes, migrationBarz, migrationNonce) + const signature1 = await guardian1.signMessage(arrayify(hash)) + const prefixedHash = getEthSignMessageHash(hash) + + const finalHash = await getMessageHash(prefixedHash, await getChainId(), migrationBarz.address) + const sig = ecsign(Buffer.from(ethers.utils.arrayify(finalHash)), Buffer.from(ethers.utils.arrayify(owner.privateKey))) + + const signerSignature = toRpcSig(sig.v, sig.r, sig.s) + await expect(migrationBarz.migrateSignatureSchemeWithGuardian(r1Facet.address, publicKeyBytes, getSelectors(r1Facet), [guardian1.address, barz.address], [signature1, signerSignature])).to.emit(migrationBarz, "SignatureMigrationExecuted") + + const migrationCall = migrationBarz.interface.encodeFunctionData("approveCancelSignatureMigration", [r1Facet.address, publicKeyBytes, getSelectors(r1Facet)]) + const migrationCallData = executeCallData(migrationBarz.address, 0, migrationCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, migrationCallData)).to.not.emit(migrationBarz, "SignatureMigrationCanceled") + expect(await migrationBarz.isMigrationPending()).to.be.true + }) + it('Should not execute migration cancellation if 1 guardian exists and only guardian approves', async () => { + await setupBarz(k1Facet, owner.publicKey) + await addFacetsK1() + await addGuardian(guardian1) + const { publicKeyBytes } = generateKeyPair() + + const hash = await getSignedMigrationHash(r1Facet, publicKeyBytes, migrationBarz, migrationNonce) + const signature1 = await guardian1.signMessage(arrayify(hash)) + const prefixedHash = getEthSignMessageHash(hash) + + const finalHash = await getMessageHash(prefixedHash, await getChainId(), migrationBarz.address) + const sig = ecsign(Buffer.from(ethers.utils.arrayify(finalHash)), Buffer.from(ethers.utils.arrayify(owner.privateKey))) + + const signerSignature = toRpcSig(sig.v, sig.r, sig.s) + await expect(migrationBarz.migrateSignatureSchemeWithGuardian(r1Facet.address, publicKeyBytes, getSelectors(r1Facet), [guardian1.address, barz.address], [signature1, signerSignature])).to.emit(migrationBarz, "SignatureMigrationExecuted") + + await expect(migrationBarz.connect(guardian1).approveCancelSignatureMigration(r1Facet.address, publicKeyBytes, getSelectors(r1Facet))).to.not.emit(migrationBarz, "SignatureMigrationCanceled") + expect(await migrationBarz.isMigrationPending()).to.be.true + }) + it('Should cancel signature scheme migration when owner approves with no guardian in wallet', async () => { + await setupBarz(k1Facet, owner.publicKey) + await addFacetsK1() + const { publicKeyBytes } = generateKeyPair() + + const migrationCall = migrationBarz.interface.encodeFunctionData("migrateSignatureScheme", [r1Facet.address, publicKeyBytes, getSelectors(r1Facet)]) + const migrationCallData = executeCallData(migrationBarz.address, 0, migrationCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, migrationCallData)).to.emit(migrationBarz, "SignatureMigrationExecuted") + expect(await migrationBarz.isMigrationPending()).to.be.true + + const cancelMigrationCall = migrationBarz.interface.encodeFunctionData("approveCancelSignatureMigration", [r1Facet.address, publicKeyBytes, getSelectors(r1Facet)]) + const cancelMigrationCallData = executeCallData(migrationBarz.address, 0, cancelMigrationCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, cancelMigrationCallData)).to.emit(migrationBarz, "SignatureMigrationCanceled") + expect(await migrationBarz.isMigrationPending()).to.be.false + }) + it('Should automatically cancel migration if majority of guardian + owner approve', async () => { + await setupBarz(k1Facet, owner.publicKey) + await addFacetsK1() + + const { publicKeyBytes } = generateKeyPair() + await addGuardian(guardian1) + await addGuardian(guardian2) + + let tmpMigrationNonce = 0 + expect(await migrationBarz.getMigrationNonce()).to.equal(tmpMigrationNonce) + + const hash = await getSignedMigrationHash(r1Facet, publicKeyBytes, migrationBarz, migrationNonce) + const signature1 = await guardian1.signMessage(arrayify(hash)) + const signature2 = await guardian2.signMessage(arrayify(hash)) + const prefixedHash = getEthSignMessageHash(hash) + + const finalHash = await getMessageHash(prefixedHash, await getChainId(), migrationBarz.address) + const sig = ecsign(Buffer.from(ethers.utils.arrayify(finalHash)), Buffer.from(ethers.utils.arrayify(owner.privateKey))) + + const signerSignature = toRpcSig(sig.v, sig.r, sig.s) + await expect(migrationBarz.migrateSignatureSchemeWithGuardian(r1Facet.address, publicKeyBytes, getSelectors(r1Facet), [guardian1.address, guardian2.address, barz.address], [signature1, signature2, signerSignature])).to.emit(migrationBarz, "SignatureMigrationExecuted") + expect(await migrationBarz.getMigrationNonce()).to.equal(++tmpMigrationNonce) + + const cancellationEncodedData = ethers.utils.defaultAbiCoder.encode(['bytes', 'address', 'bytes32', 'string', 'address', 'uint256', 'uint128'], [publicKeyBytes, r1Facet.address, encodedFuncSelectorsHash, 'CancelSignatureMigration', migrationBarz.address, chainId, tmpMigrationNonce]) + const cancelHash = keccak256(cancellationEncodedData) + const signMessageHash = getEthSignMessageHash(cancelHash) + + expect(await migrationBarz.getMigrationApprovalCountWithTimeValidity(signMessageHash)).to.equal(0) + + await expect(migrationBarz.connect(guardian1).approveCancelSignatureMigration(r1Facet.address, publicKeyBytes, getSelectors(r1Facet))).to.emit(migrationBarz, "SignatureMigrationCancellationApproved") + .withArgs(r1Facet.address, publicKeyBytes, getSelectors(r1Facet)) + + expect(await migrationBarz.getMigrationApprovalCountWithTimeValidity(signMessageHash)).to.equal(1) + + await expect(migrationBarz.connect(guardian2).approveCancelSignatureMigration(r1Facet.address, publicKeyBytes, getSelectors(r1Facet))).to.emit(migrationBarz, "SignatureMigrationCancellationApproved") + .withArgs(r1Facet.address, publicKeyBytes, getSelectors(r1Facet)) + + expect(await migrationBarz.getMigrationApprovalCountWithTimeValidity(signMessageHash)).to.equal(2) + expect(await migrationBarz.isMigrationPending()).to.be.true + const migrationCall = migrationBarz.interface.encodeFunctionData("approveCancelSignatureMigration", [r1Facet.address, publicKeyBytes, getSelectors(r1Facet)]) + + const migrationCallData = executeCallData(migrationBarz.address, 0, migrationCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, migrationCallData)).to.emit(migrationBarz, "SignatureMigrationCanceled").withArgs(r1Facet.address, publicKeyBytes, getSelectors(r1Facet)) + expect(await migrationBarz.isMigrationPending()).to.be.false + }) + }) + describe('# cancelSignatureMigration', () => { + let publicKey: any + let migrationNonce = 0 + let mockBarz: Barz + let mockAccountBarz: AccountFacet + let mockGuardianBarz: GuardianFacet + let mockMigrationBarz: SignatureMigrationFacet + + beforeEach(async () => { + await setupBarz(k1Facet, owner.publicKey) + await addFacetsK1() + + migrationBarz = await getFacetBarz("SignatureMigrationFacet", barz) + const { publicKeyBytes } = generateKeyPair() + publicKey = publicKeyBytes + + await addGuardian(guardian1) + await addGuardian(guardian2) + + migrationNonce = 0 + expect(await migrationBarz.getMigrationNonce()).to.equal(migrationNonce) + + const hash = await getSignedMigrationHash(r1Facet, publicKeyBytes, migrationBarz, migrationNonce) + const signature1 = await guardian1.signMessage(arrayify(hash)) + const signature2 = await guardian2.signMessage(arrayify(hash)) + const prefixedHash = getEthSignMessageHash(hash) + + const finalHash = await getMessageHash(prefixedHash, await getChainId(), migrationBarz.address) + const sig = ecsign(Buffer.from(ethers.utils.arrayify(finalHash)), Buffer.from(ethers.utils.arrayify(owner.privateKey))) + + const signerSignature = toRpcSig(sig.v, sig.r, sig.s) + const migrateSignatureCall = migrationBarz.interface.encodeFunctionData('migrateSignatureSchemeWithGuardian', [r1Facet.address, publicKeyBytes, getSelectors(r1Facet), [guardian1.address, guardian2.address, barz.address], [signature1, signature2, signerSignature]]) + const migrateSignatureCallData = executeCallData(migrationBarz.address, 0, migrateSignatureCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, migrateSignatureCallData)).to.emit(migrationBarz, 'SignatureMigrationExecuted') + expect(await migrationBarz.getMigrationNonce()).to.equal(++migrationNonce) + + mockBarz = await barzFixture(accountFacet, k1Facet, mockEntryPoint, facetRegistry, defaultFallbackHandler, owner.publicKey) + + await addFacetSelectors(mockBarz, migrationFacet, migrationFacetSelectors, mockEntryPoint) + await addFacetSelectors(mockBarz, guardianFacet, guardianFacetSelectors, mockEntryPoint) + + mockAccountBarz = await getFacetBarz("AccountFacet", mockBarz) + mockGuardianBarz = await getFacetBarz("GuardianFacet", mockBarz) + mockMigrationBarz = await getFacetBarz("SignatureMigrationFacet", mockBarz) + + const mockMigrationNonce = 0 + expect(await mockMigrationBarz.getMigrationNonce()).to.equal(mockMigrationNonce) + const mockEncodedData = ethers.utils.defaultAbiCoder.encode(['bytes', 'address', 'bytes32', 'string', 'address', 'uint256', 'uint128'], [publicKeyBytes, r1Facet.address, encodedFuncSelectorsHash, 'MigrateSignature', mockBarz.address, chainId, mockMigrationNonce]) + const mockHash = keccak256(mockEncodedData) + const mockSignature1 = await guardian1.signMessage(arrayify(mockHash)) + const mockSignature2 = await guardian2.signMessage(arrayify(mockHash)) + const mockPrefixedHash = getEthSignMessageHash(mockHash) + + const mockFinalHash = await getMessageHash(mockPrefixedHash, await getChainId(), mockMigrationBarz.address) + const mockSig = ecsign(Buffer.from(ethers.utils.arrayify(mockFinalHash)), Buffer.from(ethers.utils.arrayify(owner.privateKey))) + + const mockSignerSignature = toRpcSig(mockSig.v, mockSig.r, mockSig.s) + + await addGuardianMock(guardian1, mockGuardianBarz, mockAccountBarz) + await addGuardianMock(guardian2, mockGuardianBarz, mockAccountBarz) + const mockMigrateSignatureCall = mockMigrationBarz.interface.encodeFunctionData('migrateSignatureSchemeWithGuardian', [r1Facet.address, publicKeyBytes, getSelectors(r1Facet), [guardian1.address, guardian2.address, mockMigrationBarz.address], [mockSignature1, mockSignature2, mockSignerSignature]]) + + await expect(mockAccountBarz.connect(mockEntryPoint).execute(mockMigrationBarz.address, 0, mockMigrateSignatureCall)).to.emit(mockMigrationBarz, 'SignatureMigrationExecuted') + }) + it('Should revert if owner signature is not included', async () => { + await addGuardian(guardian3) + + const encodedData = ethers.utils.defaultAbiCoder.encode(['bytes', 'address', 'bytes32', 'string', 'address', 'uint256', 'uint128'], [publicKey, r1Facet.address, encodedFuncSelectorsHash, 'CancelSignatureMigration', migrationBarz.address, chainId, migrationNonce]) + const hash = keccak256(encodedData) + const signature1 = await guardian1.signMessage(arrayify(hash)) + const signature2 = await guardian2.signMessage(arrayify(hash)) + const signature3 = await guardian3.signMessage(arrayify(hash)) // NOTE: should revert because it's guardian3 not owner + + await expect(migrationBarz.cancelSignatureMigration(r1Facet.address, publicKey, getSelectors(r1Facet), [guardian1.address, guardian2.address, guardian3.address], [signature1, signature2, signature3])).to.be.revertedWithCustomError(migrationBarz, "SignatureMigrationFacet__LackOfOwnerApproval") + }) + it('Should revert if new public key length is not valid', async () => { + const invalidKey = publicKey + '1111' + const encodedData = ethers.utils.defaultAbiCoder.encode(['bytes', 'address', 'bytes32', 'string', 'uint256', 'uint128'], [invalidKey, r1Facet.address, encodedFuncSelectorsHash, 'CancelSignatureMigration', chainId, await accountBarz.getNonce()]) + const hash = keccak256(encodedData) + const signature1 = await guardian1.signMessage(arrayify(hash)) + const signature2 = await guardian2.signMessage(arrayify(hash)) + const cancelSignaterMigrationCall = migrationBarz.interface.encodeFunctionData("cancelSignatureMigration", [r1Facet.address, invalidKey, getSelectors(r1Facet), [guardian1.address, guardian2.address], [signature1, signature2]]) + const cancelSignaterMigrationCallData = executeCallData(migrationBarz.address, 0, cancelSignaterMigrationCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, cancelSignaterMigrationCallData)).to.not.emit(migrationBarz, "SignatureMigrationCanceled") + await expect(migrationBarz.cancelSignatureMigration(r1Facet.address, invalidKey, getSelectors(r1Facet), [guardian1.address, guardian2.address], [signature1, signature2])).to.be.revertedWithCustomError(migrationBarz, "SignatureMigrationFacet__InvalidKeyType") + }) + it('Should revert if parameter guardian length and signature length differs', async () => { + const encodedData = ethers.utils.defaultAbiCoder.encode(['bytes', 'address', 'bytes32', 'string', 'uint256', 'uint128'], [publicKey, r1Facet.address, encodedFuncSelectorsHash, 'CancelSignatureMigration', chainId, migrationNonce]) + const hash = keccak256(encodedData) + const signature1 = await guardian1.signMessage(arrayify(hash)) + + const cancelSignaterMigrationCall = migrationBarz.interface.encodeFunctionData("cancelSignatureMigration", [r1Facet.address, publicKey, getSelectors(r1Facet), [guardian1.address, guardian2.address], [signature1]]) + const cancelSignaterMigrationCallData = executeCallData(migrationBarz.address, 0, cancelSignaterMigrationCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, cancelSignaterMigrationCallData)).to.not.emit(migrationBarz, "SignatureMigrationCanceled") + await expect(mockMigrationBarz.cancelSignatureMigration(r1Facet.address, publicKey, getSelectors(r1Facet), [guardian1.address, guardian2.address], [signature1])).to.be.revertedWithCustomError(migrationBarz, "SignatureMigrationFacet__InvalidArrayLength") + }) + it('Should revert if parameter guardian length + approved count < majority of guardians', async () => { + const encodedData = ethers.utils.defaultAbiCoder.encode(['bytes', 'address', 'bytes32', 'string', 'uint256', 'uint128'], [publicKey, r1Facet.address, encodedFuncSelectorsHash, 'CancelSignatureMigration', chainId, migrationNonce]) + const hash = keccak256(encodedData) + const signature2 = await guardian2.signMessage(arrayify(hash)) + + const cancelSignaterMigrationCall = migrationBarz.interface.encodeFunctionData("cancelSignatureMigration", [r1Facet.address, publicKey, getSelectors(r1Facet), [guardian2.address], [signature2]]) + const cancelSignaterMigrationCallData = executeCallData(migrationBarz.address, 0, cancelSignaterMigrationCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, cancelSignaterMigrationCallData)).to.not.emit(migrationBarz, "SignatureMigrationCanceled") + await expect(mockMigrationBarz.cancelSignatureMigration(r1Facet.address, publicKey, getSelectors(r1Facet), [guardian2.address], [signature2])).to.be.revertedWithCustomError(migrationBarz, "SignatureMigrationFacet__InsufficientApprovers") + }) + it('Should revert if invalid parameter guardian', async () => { + const encodedData = ethers.utils.defaultAbiCoder.encode(['bytes', 'address', 'bytes32', 'string', 'uint256', 'uint128'], [publicKey, r1Facet.address, encodedFuncSelectorsHash, 'CancelSignatureMigration', chainId, migrationNonce]) + const hash = keccak256(encodedData) + const signature1 = await user1.signMessage(arrayify(hash)) + const signature2 = await guardian2.signMessage(arrayify(hash)) + + const prefixedHash = getEthSignMessageHash(hash) + + const finalHash = await getMessageHash(prefixedHash, await getChainId(), migrationBarz.address) + const sig = ecsign(Buffer.from(ethers.utils.arrayify(finalHash)), Buffer.from(ethers.utils.arrayify(owner.privateKey))) + + const signerSignature = toRpcSig(sig.v, sig.r, sig.s) + const cancelSignaterMigrationCall = migrationBarz.interface.encodeFunctionData("cancelSignatureMigration", [r1Facet.address, publicKey, getSelectors(r1Facet), [user1.address, guardian2.address, barz.address], [signature1, signature2, signerSignature]]) + const cancelSignaterMigrationCallData = executeCallData(migrationBarz.address, 0, cancelSignaterMigrationCall) + expect(await migrationBarz.isMigrationPending()).to.be.true + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, cancelSignaterMigrationCallData)).to.not.emit(migrationBarz, "SignatureMigrationCanceled") + expect(await migrationBarz.isMigrationPending()).to.be.true + + const mockSignerSignature = await owner.signMessage(arrayify(hash)) + await expect(mockMigrationBarz.cancelSignatureMigration(r1Facet.address, publicKey, getSelectors(r1Facet), [user1.address, guardian2.address, mockMigrationBarz.address], [signature1, signature2, mockSignerSignature])).to.be.revertedWithCustomError(migrationBarz, "SignatureMigrationFacet__NonExistentApprover") + + }) + it('Should revert if invalid guardian signature', async () => { + const encodedData = ethers.utils.defaultAbiCoder.encode(['bytes', 'address', 'bytes32', 'string', 'address', 'uint256', 'uint128'], [publicKey, r1Facet.address, encodedFuncSelectorsHash, 'InvalidCancelSignatureMigration', migrationBarz.address, chainId, migrationNonce]) + const hash = keccak256(encodedData) + const signature1 = await guardian1.signMessage(arrayify(hash)) + const signature2 = await guardian2.signMessage(arrayify(hash)) + const prefixedHash = getEthSignMessageHash(hash) + + const finalHash = await getMessageHash(prefixedHash, await getChainId(), migrationBarz.address) + const sig = ecsign(Buffer.from(ethers.utils.arrayify(finalHash)), Buffer.from(ethers.utils.arrayify(owner.privateKey))) + + const signerSignature = toRpcSig(sig.v, sig.r, sig.s) + const cancelSignaterMigrationCall = migrationBarz.interface.encodeFunctionData("cancelSignatureMigration", [r1Facet.address, publicKey, getSelectors(r1Facet), [guardian1.address, guardian2.address, barz.address], [signature1, signature2, signerSignature]]) + const cancelSignaterMigrationCallData = executeCallData(migrationBarz.address, 0, cancelSignaterMigrationCall) + await callFromEntryPointOnK1(entryPoint, barz.address, owner, cancelSignaterMigrationCallData) + await expect(mockAccountBarz.connect(mockEntryPoint).execute(mockMigrationBarz.address, 0, cancelSignaterMigrationCall)).to.be.revertedWithCustomError(migrationBarz, "SignatureMigrationFacet__InvalidApproverSignature") + }) + it('Should revert if duplicate guardian', async () => { + const encodedData = ethers.utils.defaultAbiCoder.encode(['bytes', 'address', 'bytes32', 'string', 'address', 'uint256', 'uint128'], [publicKey, r1Facet.address, encodedFuncSelectorsHash, 'CancelSignatureMigration', mockAccountBarz.address, chainId, migrationNonce]) + const hash = keccak256(encodedData) + const signature1 = await guardian1.signMessage(arrayify(hash)) + const prefixedHash = getEthSignMessageHash(hash) + + const finalHash = await getMessageHash(prefixedHash, await getChainId(), migrationBarz.address) + const sig = ecsign(Buffer.from(ethers.utils.arrayify(finalHash)), Buffer.from(ethers.utils.arrayify(owner.privateKey))) + + const signerSignature = toRpcSig(sig.v, sig.r, sig.s) + const cancelSignaterMigrationCall = migrationBarz.interface.encodeFunctionData("cancelSignatureMigration", [r1Facet.address, publicKey, getSelectors(r1Facet), [guardian1.address, guardian1.address, barz.address], [signature1, signature1, signerSignature]]) + + await expect(mockAccountBarz.connect(mockEntryPoint).execute(mockMigrationBarz.address, 0, cancelSignaterMigrationCall)).to.be.revertedWithCustomError(mockMigrationBarz, "DuplicateApprover") + }) + it('Should emit Migration Cancellation event', async () => { + const encodedData = ethers.utils.defaultAbiCoder.encode(['bytes', 'address', 'bytes32', 'string', 'address', 'uint256', 'uint128'], [publicKey, r1Facet.address, encodedFuncSelectorsHash, 'CancelSignatureMigration', migrationBarz.address, chainId, migrationNonce]) + const hash = keccak256(encodedData) + const signature1 = await guardian1.signMessage(arrayify(hash)) + const signature2 = await guardian2.signMessage(arrayify(hash)) + const prefixedHash = getEthSignMessageHash(hash) + + const finalHash = await getMessageHash(prefixedHash, await getChainId(), migrationBarz.address) + const sig = ecsign(Buffer.from(ethers.utils.arrayify(finalHash)), Buffer.from(ethers.utils.arrayify(owner.privateKey))) + + const signerSignature = toRpcSig(sig.v, sig.r, sig.s) + const cancelSignaterMigrationCall = migrationBarz.interface.encodeFunctionData("cancelSignatureMigration", [r1Facet.address, publicKey, getSelectors(r1Facet), [guardian1.address, guardian2.address, barz.address], [signature1, signature2, signerSignature]]) + const cancelSignaterMigrationCallData = executeCallData(migrationBarz.address, 0, cancelSignaterMigrationCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, cancelSignaterMigrationCallData)).to.emit(migrationBarz, "SignatureMigrationCanceled").withArgs(r1Facet.address, publicKey, getSelectors(r1Facet)) + }) + it('Should cancel migration without guardian: mock entrypoint', async () => { + mockBarz = await barzFixture(accountFacet, k1Facet, mockEntryPoint, facetRegistry, defaultFallbackHandler, owner.publicKey) + + await addFacetSelectors(mockBarz, migrationFacet, migrationFacetSelectors, mockEntryPoint) + await addFacetSelectors(mockBarz, guardianFacet, guardianFacetSelectors, mockEntryPoint) + mockAccountBarz = await getFacetBarz("AccountFacet", mockBarz) + mockGuardianBarz = await getFacetBarz("GuardianFacet", mockBarz) + mockMigrationBarz = await getFacetBarz("SignatureMigrationFacet", mockBarz) + + const migrationSignatureCall = mockMigrationBarz.interface.encodeFunctionData("migrateSignatureScheme", [r1Facet.address, publicKey, getSelectors(r1Facet)]) + await expect(mockAccountBarz.connect(mockEntryPoint).execute(mockAccountBarz.address,0 , migrationSignatureCall)).to.emit(mockMigrationBarz, "SignatureMigrationExecuted") + + const encodedData = ethers.utils.defaultAbiCoder.encode(['bytes', 'address', 'bytes32', 'string', 'address', 'uint256', 'uint128'], [publicKey, r1Facet.address, encodedFuncSelectorsHash, 'CancelSignatureMigration', mockMigrationBarz.address, chainId, 1]) + const hash = keccak256(encodedData) + const prefixedHash = getEthSignMessageHash(hash) + + const finalHash = await getMessageHash(prefixedHash, await getChainId(), mockAccountBarz.address) + const sig = ecsign(Buffer.from(ethers.utils.arrayify(finalHash)), Buffer.from(ethers.utils.arrayify(owner.privateKey))) + + const signerSignature = toRpcSig(sig.v, sig.r, sig.s) + const cancelSignatureMigrationCall = migrationBarz.interface.encodeFunctionData("cancelSignatureMigration", [r1Facet.address, publicKey, getSelectors(r1Facet), [mockAccountBarz.address], [signerSignature]]) + await expect(mockAccountBarz.connect(mockEntryPoint).execute(mockAccountBarz.address, 0, cancelSignatureMigrationCall)).to.emit(mockMigrationBarz, "SignatureMigrationCanceled") + }) + it('Should cancel migration without guardian: real entrypoint', async () => { + migrationNonce = 0 + + await setupBarz(k1Facet, owner.publicKey) + await addFacetsK1() + + migrationBarz = await getFacetBarz("SignatureMigrationFacet", barz) + const { publicKeyBytes } = generateKeyPair() + publicKey = publicKeyBytes + + expect(await migrationBarz.getMigrationNonce()).to.equal(migrationNonce) + + const encodedFuncSelectors = ethers.utils.defaultAbiCoder.encode(['bytes4[]'], [getSelectors(r1Facet)]) + encodedFuncSelectorsHash = keccak256(encodedFuncSelectors) + + const migrateSignatureCall = migrationBarz.interface.encodeFunctionData('migrateSignatureScheme', [r1Facet.address, publicKeyBytes, getSelectors(r1Facet)]) + const migrateSignatureCallData = executeCallData(migrationBarz.address, 0, migrateSignatureCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, migrateSignatureCallData)).to.emit(migrationBarz, 'SignatureMigrationExecuted') + + expect(await migrationBarz.getMigrationNonce()).to.equal(++migrationNonce) + + const encodedData = ethers.utils.defaultAbiCoder.encode(['bytes', 'address', 'bytes32', 'string', 'address', 'uint256', 'uint128'], [publicKeyBytes, r1Facet.address, encodedFuncSelectorsHash, 'CancelSignatureMigration', migrationBarz.address, chainId, migrationNonce]) + const hash = keccak256(encodedData) + + const prefixedHash = getEthSignMessageHash(hash) + + const finalHash = await getMessageHash(prefixedHash, await getChainId(), migrationBarz.address) + const sig = ecsign(Buffer.from(ethers.utils.arrayify(finalHash)), Buffer.from(ethers.utils.arrayify(owner.privateKey))) + + const signerSignature = toRpcSig(sig.v, sig.r, sig.s) + const cancelMigrationCall = migrationBarz.interface.encodeFunctionData('cancelSignatureMigration', [r1Facet.address, publicKeyBytes, getSelectors(r1Facet), [accountBarz.address], [signerSignature]]) + const cancelMigrationCallData = executeCallData(migrationBarz.address, 0, cancelMigrationCall) + + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, cancelMigrationCallData)).to.emit(migrationBarz, 'SignatureMigrationCanceled') + + }) + it('Should increment migration nonce', async () => { + const encodedData = ethers.utils.defaultAbiCoder.encode(['bytes', 'address', 'bytes32', 'string', 'address', 'uint256', 'uint128'], [publicKey, r1Facet.address, encodedFuncSelectorsHash, 'CancelSignatureMigration', migrationBarz.address, chainId, migrationNonce]) + const hash = keccak256(encodedData) + const signature1 = await guardian1.signMessage(arrayify(hash)) + const signature2 = await guardian2.signMessage(arrayify(hash)) + const prefixedHash = getEthSignMessageHash(hash) + + const finalHash = await getMessageHash(prefixedHash, await getChainId(), migrationBarz.address) + const sig = ecsign(Buffer.from(ethers.utils.arrayify(finalHash)), Buffer.from(ethers.utils.arrayify(owner.privateKey))) + + const signerSignature = toRpcSig(sig.v, sig.r, sig.s) + expect(await migrationBarz.getMigrationNonce()).to.equal(1) + const cancelSignaterMigrationCall = migrationBarz.interface.encodeFunctionData("cancelSignatureMigration", [r1Facet.address, publicKey, getSelectors(r1Facet), [guardian1.address, guardian2.address, barz.address], [signature1, signature2, signerSignature]]) + const cancelSignaterMigrationCallData = executeCallData(migrationBarz.address, 0, cancelSignaterMigrationCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, cancelSignaterMigrationCallData)).to.emit(migrationBarz, "SignatureMigrationCanceled").withArgs(r1Facet.address, publicKey, getSelectors(r1Facet)) + expect(await migrationBarz.getMigrationNonce()).to.equal(2) + }) + it('Should cancel migration with on-chain and off-chain approval', async () => { + await expect(migrationBarz.connect(guardian2).approveCancelSignatureMigration(r1Facet.address, publicKey, getSelectors(r1Facet))).to.emit(migrationBarz, "SignatureMigrationCancellationApproved") + + const encodedData = ethers.utils.defaultAbiCoder.encode(['bytes', 'address', 'bytes32', 'string', 'address', 'uint256', 'uint128'], [publicKey, r1Facet.address, encodedFuncSelectorsHash, 'CancelSignatureMigration', migrationBarz.address, chainId, migrationNonce]) + const hash = keccak256(encodedData) + const signature1 = await guardian1.signMessage(arrayify(hash)) + const prefixedHash = getEthSignMessageHash(hash) + + const finalHash = await getMessageHash(prefixedHash, await getChainId(), migrationBarz.address) + const sig = ecsign(Buffer.from(ethers.utils.arrayify(finalHash)), Buffer.from(ethers.utils.arrayify(owner.privateKey))) + + const signerSignature = toRpcSig(sig.v, sig.r, sig.s) + expect(await migrationBarz.getMigrationNonce()).to.equal(1) + const cancelSignaterMigrationCall = migrationBarz.interface.encodeFunctionData("cancelSignatureMigration", [r1Facet.address, publicKey, getSelectors(r1Facet), [guardian1.address, barz.address], [signature1, signerSignature]]) + const cancelSignaterMigrationCallData = executeCallData(migrationBarz.address, 0, cancelSignaterMigrationCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, cancelSignaterMigrationCallData)).to.emit(migrationBarz, "SignatureMigrationCanceled").withArgs(r1Facet.address, publicKey, getSelectors(r1Facet)) + expect(await migrationBarz.getMigrationNonce()).to.equal(2) + }) + it('Should revert if on-chain approver reattempts to approve off-chain', async () => { + await expect(mockMigrationBarz.connect(guardian1).approveCancelSignatureMigration(r1Facet.address, publicKey, getSelectors(r1Facet))).to.emit(mockMigrationBarz, "SignatureMigrationCancellationApproved") + + const encodedData = ethers.utils.defaultAbiCoder.encode(['bytes', 'address', 'bytes32', 'string', 'address', 'uint256', 'uint128'], [publicKey, r1Facet.address, encodedFuncSelectorsHash, 'CancelSignatureMigration', migrationBarz.address, chainId, migrationNonce]) + const hash = keccak256(encodedData) + const signature1 = await guardian1.signMessage(arrayify(hash)) + const signerSignature = await owner.signMessage(arrayify(hash)) + const cancelSignaterMigrationCall = migrationBarz.interface.encodeFunctionData("cancelSignatureMigration", [r1Facet.address, publicKey, getSelectors(r1Facet), [guardian1.address, barz.address], [signature1, signerSignature]]) + await expect(mockAccountBarz.connect(mockEntryPoint).execute(mockAccountBarz.address, 0, cancelSignaterMigrationCall)).to.be.revertedWithCustomError(mockMigrationBarz, "SignatureMigrationFacet__DuplicateApproval") + }) + it('Should revert if migration is not pending', async () => { + await setupBarz(k1Facet, owner.publicKey) + await addFacetsK1() + + const encodedData = ethers.utils.defaultAbiCoder.encode(['bytes', 'address', 'bytes32', 'string', 'address', 'uint256', 'uint128'], [publicKey, r1Facet.address, encodedFuncSelectorsHash, 'CancelSignatureMigration', migrationBarz.address, chainId, 0]) + const hash = keccak256(encodedData) + const signature1 = await guardian1.signMessage(arrayify(hash)) + const signature2 = await guardian2.signMessage(arrayify(hash)) + expect(await migrationBarz.getMigrationNonce()).to.equal(0) + expect(await migrationBarz.isMigrationPending()).to.be.false + const cancelSignaterMigrationCall = migrationBarz.interface.encodeFunctionData("cancelSignatureMigration", [r1Facet.address, publicKey, getSelectors(r1Facet), [guardian1.address, guardian2.address], [signature1, signature2]]) + const cancelSignaterMigrationCallData = executeCallData(migrationBarz.address, 0, cancelSignaterMigrationCall) + await callFromEntryPointOnK1(entryPoint, barz.address, owner, cancelSignaterMigrationCallData) + expect(await migrationBarz.isMigrationPending()).to.be.false + }) + }) + describe('# getPendingMigration', async () => { + let encodedFuncSelectorsHash: any + let migrationNonce = 0 + + beforeEach(async () => { + await setupBarz(k1Facet, owner.publicKey) + await addFacetsK1() + migrationBarz = await getFacetBarz("SignatureMigrationFacet", barz) + await addGuardian(guardian1) + await addGuardian(guardian2) + + migrationNonce = 0 + expect(await migrationBarz.getMigrationNonce()).to.equal(migrationNonce) + }) + it('Should return valid migration information', async () => { + const { publicKeyBytes } = generateKeyPair() + + const hash = await getSignedMigrationHash(r1Facet, publicKeyBytes, migrationBarz, migrationNonce) + const signature1 = await guardian1.signMessage(arrayify(hash)) + const signature2 = await guardian2.signMessage(arrayify(hash)) + const prefixedHash = getEthSignMessageHash(hash) + + const finalHash = await getMessageHash(prefixedHash, await getChainId(), migrationBarz.address) + const sig = ecsign(Buffer.from(ethers.utils.arrayify(finalHash)), Buffer.from(ethers.utils.arrayify(owner.privateKey))) + + const signerSignature = toRpcSig(sig.v, sig.r, sig.s) + const migrateSignatureCall = migrationBarz.interface.encodeFunctionData('migrateSignatureSchemeWithGuardian', [r1Facet.address, publicKeyBytes, getSelectors(r1Facet), [guardian1.address, guardian2.address, barz.address], [signature1, signature2, signerSignature]]) + const migrateSignatureCallData = executeCallData(migrationBarz.address, 0, migrateSignatureCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, migrateSignatureCallData)).to.emit(migrationBarz, 'SignatureMigrationExecuted') + expect(await migrationBarz.getMigrationNonce()).to.equal(++migrationNonce) + + const blockTimeStamp = await getBlockTimestamp() + expect(await migrationBarz.getPendingMigration()).to.deep.equal([publicKeyBytes, r1Facet.address, getSelectors(r1Facet), blockTimeStamp + migrationPeriod]) + }) + it('Should return zero migration information if migration is not pending', async () => { + expect(await migrationBarz.getPendingMigration()).to.deep.equal(['0x', AddressZero, [], 0]) + }) + }) +}) \ No newline at end of file diff --git a/test/TokenReceiverFacet.test.ts b/test/TokenReceiverFacet.test.ts new file mode 100644 index 0000000..530a1cb --- /dev/null +++ b/test/TokenReceiverFacet.test.ts @@ -0,0 +1,148 @@ +import { ethers } from 'hardhat' +import { Wallet } from 'ethers' + +import { AccountFacet, DiamondCutFacet, Barz, Secp256k1VerificationFacet, SecurityManager, FacetRegistry, DiamondLoupeFacet, TokenReceiverFacet, TestERC1155, TestNFT, DefaultFallbackHandler } from '../typechain-types' +import { getFacetBarz, setupDefaultSecuritManager } from './utils/setup' +import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers' + +const { + getSelectors +} = require('./utils/diamond.js') + +import { expect } from "chai" +import { diamondCutFacetFixture } from './fixtures/DiamondCutFacetFixture' +import { accountFacetFixture } from './fixtures/AccountFacetFixture' +import { secp256k1VerificationFacetFixture } from './fixtures/Secp256k1VerificationFacetFixture' +import { barzFixture } from './fixtures/BarzFixture' +import { facetRegistryFixture } from './fixtures/FacetRegistryFixture' +import { EntryPoint } from '../typechain-types/core' +import { entryPointFixture } from './fixtures/EntryPointFixture' +import { diamondLoupeFacetFixture } from './fixtures/DiamondLoupeFacetFixture' +import { tokenReceiverFacetFixture } from './fixtures/TokenReceiverFacetFixture' +import { testERC1155Fixture } from './fixtures/TestERC1155Fixture' +import { testNFTFixture } from './fixtures/TestNFTFixture' +import { createAccountOwner, fund } from './utils/testutils' +import { defaultFallbackHandlerFixture } from './fixtures/DefaultFallbackHandlerFixture' + +describe('TokenReceiver Facet', () => { + let diamondCutFacet: DiamondCutFacet + let securityManager: SecurityManager + let defaultFallbackHandler: DefaultFallbackHandler + let facetRegistry: FacetRegistry + let accountFacet: AccountFacet + let k1Facet: Secp256k1VerificationFacet + let diamondLoupeFacet: DiamondLoupeFacet + let tokenReceiverFacet: TokenReceiverFacet + let tokenReceiverBarz: TokenReceiverFacet + let entryPoint: EntryPoint + let facetRegistryOwner: SignerWithAddress + let securityManagerOwner: SignerWithAddress + let owner: Wallet + let barz: Barz + let testERC1155: TestERC1155 + let testNFT: TestNFT + + before(async () => { + [facetRegistryOwner, securityManagerOwner] = await ethers.getSigners() + + securityManager = await setupDefaultSecuritManager(securityManagerOwner) + facetRegistry = await facetRegistryFixture(facetRegistryOwner.address) + accountFacet = await accountFacetFixture() + k1Facet = await secp256k1VerificationFacetFixture() + diamondCutFacet = await diamondCutFacetFixture(securityManager) + diamondLoupeFacet = await diamondLoupeFacetFixture() + tokenReceiverFacet = await tokenReceiverFacetFixture() + defaultFallbackHandler = await defaultFallbackHandlerFixture(diamondCutFacet, accountFacet, tokenReceiverFacet, diamondLoupeFacet) + + entryPoint = await entryPointFixture() + + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(accountFacet.address, getSelectors(accountFacet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(k1Facet.address, getSelectors(k1Facet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(diamondCutFacet.address, getSelectors(diamondCutFacet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(diamondLoupeFacet.address, getSelectors(diamondLoupeFacet)) + + }) + + beforeEach(async () => { + owner = await createAccountOwner() + await fund(owner.address) + + barz = await barzFixture(accountFacet, k1Facet, entryPoint, facetRegistry, defaultFallbackHandler, owner.publicKey) + tokenReceiverBarz = await getFacetBarz('TokenReceiverFacet', barz) + + testERC1155 = await testERC1155Fixture() + testNFT = await testNFTFixture() + await entryPoint.depositTo(barz.address, { + value: ethers.utils.parseEther('0.5'), + }) + }) + + describe('# onERC721Received', async () => { + const tokenId = 1 + + it('Should return valid selector', async () => { + // 0x150b7a02 + expect(await tokenReceiverBarz.onERC721Received(owner.address, owner.address, 1, "0x00")).to.equal("0x150b7a02") + }) + it('Should receive ERC721 safe transfer', async () => { + await testNFT.mint(owner.address) + testNFT = testNFT.connect(owner) + await expect(testNFT['safeTransferFrom(address,address,uint256)'](owner.address, barz.address, tokenId)).to.emit(testNFT, "Transfer").withArgs(owner.address, barz.address, tokenId) + + expect(await testNFT.ownerOf(tokenId)).to.equal(barz.address) + }) + + }) + describe('# onERC1155Received', async () => { + const tokenId = 1 + const mintAmount = 100 + it('Should return valid selector', async () => { + // 0xf23a6e61 + expect(await tokenReceiverBarz.onERC1155Received(owner.address, owner.address, tokenId, mintAmount, "0x00")).to.equal("0xf23a6e61") + }) + it('Should receive ERC1155 safe transfer', async () => { + await testERC1155.mint(owner.address, mintAmount) + expect(await testERC1155.balanceOf(owner.address, tokenId)).to.equal(100) + + testERC1155 = testERC1155.connect(owner) + await expect(testERC1155.safeTransferFrom(owner.address, barz.address, tokenId, mintAmount, "0x00")).to.emit(testERC1155, "TransferSingle") + .withArgs(owner.address, owner.address, barz.address, tokenId, mintAmount) + }) + }) + describe('# onERC1155BatchReceived', async () => { + const mintIds = [1, 2, 3] + const mintAmounts = [100, 200, 300] + const ownerBatch = [owner.address, owner.address, owner.address] + it('Should return valid selector', async () => { + // 0xbc197c81 + expect(await tokenReceiverBarz.onERC1155BatchReceived(owner.address, owner.address, mintIds, mintAmounts, "0x00")).to.equal("0xbc197c81") + }) + it('Should return valid selector from Facet', async () => { + // 0xbc197c81 + expect(await tokenReceiverFacet.onERC1155BatchReceived(owner.address, owner.address, mintIds, mintAmounts, "0x00")).to.equal("0xbc197c81") + }) + it('Should receive ERC1155 safe batch transfer', async () => { + await testERC1155.mintBatch(owner.address, mintIds, mintAmounts, "0x00") + expect(await testERC1155.balanceOfBatch(ownerBatch, mintIds)).to.deep.equal(mintAmounts) + + testERC1155 = testERC1155.connect(owner) + await expect(testERC1155.safeBatchTransferFrom(owner.address, barz.address, mintIds, mintAmounts, "0x00")).to.emit(testERC1155, "TransferBatch") + .withArgs(owner.address, owner.address, barz.address, mintIds, mintAmounts) + }) + }) + describe('# tokensReceived', async () => { + it('Should not revert', async () => { + await expect(tokenReceiverBarz.tokensReceived(owner.address, owner.address, owner.address, 0, "0x00", "0x00")).to.not.reverted + }) + }) + describe('# onTokenTransfer', async () => { + const dummyUint = 1 + it('Should not revert', async () => { + await expect(tokenReceiverBarz.onTokenTransfer(owner.address, dummyUint, "0x00")).to.not.reverted + }) + it('Should return true', async () => { + expect(await tokenReceiverBarz.onTokenTransfer(owner.address, dummyUint, "0x00")).to.be.true + }) + }) + +}) \ No newline at end of file diff --git a/test/fixtures/AccountFacetFixture.ts b/test/fixtures/AccountFacetFixture.ts new file mode 100644 index 0000000..3d929ac --- /dev/null +++ b/test/fixtures/AccountFacetFixture.ts @@ -0,0 +1,7 @@ +import { ethers } from 'hardhat' +import { AccountFacet } from '../../typechain-types' + +export async function accountFacetFixture(): Promise { + const factory = await ethers.getContractFactory("AccountFacet") + return (await factory.deploy()) as AccountFacet +} \ No newline at end of file diff --git a/test/fixtures/AccountRecoveryFacetFixture.ts b/test/fixtures/AccountRecoveryFacetFixture.ts new file mode 100644 index 0000000..2a3e08f --- /dev/null +++ b/test/fixtures/AccountRecoveryFacetFixture.ts @@ -0,0 +1,9 @@ +import { ethers } from 'hardhat' +import { AccountRecoveryFacet, SecurityManager } from '../../typechain-types' + +export async function accountRecoveryFacetFixture( + securityManager: SecurityManager +): Promise { + const factory = await ethers.getContractFactory("AccountRecoveryFacet") + return (await factory.deploy(securityManager.address)) as AccountRecoveryFacet +} \ No newline at end of file diff --git a/test/fixtures/BarzFactoryFixture.ts b/test/fixtures/BarzFactoryFixture.ts new file mode 100644 index 0000000..079b47a --- /dev/null +++ b/test/fixtures/BarzFactoryFixture.ts @@ -0,0 +1,14 @@ +import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers' +import { ethers } from 'hardhat' +import { AccountFacet, BarzFactory, DefaultFallbackHandler, EntryPoint, FacetRegistry } from '../../typechain-types' +import { Contract } from 'ethers' + +export async function barzFactoryFixture( + accountFacet: AccountFacet, + entryPoint: EntryPoint | SignerWithAddress | Contract, + facetRegistry: FacetRegistry, + defaultFallbackHandler: DefaultFallbackHandler +): Promise { + const factory = await ethers.getContractFactory("BarzFactory") + return (await factory.deploy(accountFacet.address, entryPoint.address, facetRegistry.address, defaultFallbackHandler.address)) as BarzFactory +} \ No newline at end of file diff --git a/test/fixtures/BarzFixture.ts b/test/fixtures/BarzFixture.ts new file mode 100644 index 0000000..ce6492d --- /dev/null +++ b/test/fixtures/BarzFixture.ts @@ -0,0 +1,19 @@ +import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers' +import { ethers } from 'hardhat' +import { Barz, AccountFacet, Secp256k1VerificationFacet, Secp256r1VerificationFacet, EntryPoint, FacetRegistry, DefaultFallbackHandler } from '../../typechain-types' + +export async function barzFixture( + accountFacet: AccountFacet, + verificationFacet: Secp256k1VerificationFacet | Secp256r1VerificationFacet, + entryPoint: EntryPoint | SignerWithAddress, + facetRegistry: FacetRegistry, + defaultFallbackHandler: DefaultFallbackHandler, + ownerPublicKey: string, + salt = "0" +): Promise { + const Factory = await ethers.getContractFactory("BarzFactory") + const factory = await Factory.deploy(accountFacet.address, entryPoint.address, facetRegistry.address, defaultFallbackHandler.address) + const barzAddr = await factory.getAddress(verificationFacet.address, ownerPublicKey, salt) + await factory.createAccount(verificationFacet.address, ownerPublicKey, salt) + return (await ethers.getContractAt("Barz", barzAddr)) as Barz +} \ No newline at end of file diff --git a/test/fixtures/DefaultFallbackHandlerFixture.ts b/test/fixtures/DefaultFallbackHandlerFixture.ts new file mode 100644 index 0000000..69a7b8e --- /dev/null +++ b/test/fixtures/DefaultFallbackHandlerFixture.ts @@ -0,0 +1,14 @@ + + +import { ethers } from 'hardhat' +import { AccountFacet, DefaultFallbackHandler, DiamondCutFacet, DiamondLoupeFacet, TokenReceiverFacet } from '../../typechain-types' + +export async function defaultFallbackHandlerFixture( + diamondCutFacet: DiamondCutFacet, + accountFacet: AccountFacet, + tokenReceiverFacet: TokenReceiverFacet, + diamondLoupeFacet: DiamondLoupeFacet +): Promise { + const factory = await ethers.getContractFactory("DefaultFallbackHandler") + return (await factory.deploy(diamondCutFacet.address, accountFacet.address, tokenReceiverFacet.address, diamondLoupeFacet.address)) as DefaultFallbackHandler +} \ No newline at end of file diff --git a/test/fixtures/DiamondCutFacetFixture.ts b/test/fixtures/DiamondCutFacetFixture.ts new file mode 100644 index 0000000..9b34f81 --- /dev/null +++ b/test/fixtures/DiamondCutFacetFixture.ts @@ -0,0 +1,9 @@ +import { ethers } from 'hardhat' +import { DiamondCutFacet, SecurityManager } from '../../typechain-types' + +export async function diamondCutFacetFixture( + securityManager: SecurityManager +): Promise { + const factory = await ethers.getContractFactory("DiamondCutFacet") + return (await factory.deploy(securityManager.address)) as DiamondCutFacet +} \ No newline at end of file diff --git a/test/fixtures/DiamondLoupeFacetFixture.ts b/test/fixtures/DiamondLoupeFacetFixture.ts new file mode 100644 index 0000000..3f07a1e --- /dev/null +++ b/test/fixtures/DiamondLoupeFacetFixture.ts @@ -0,0 +1,7 @@ +import { ethers } from 'hardhat' +import { DiamondLoupeFacet } from '../../typechain-types' + +export async function diamondLoupeFacetFixture(): Promise { + const factory = await ethers.getContractFactory("DiamondLoupeFacet") + return (await factory.deploy()) as DiamondLoupeFacet +} \ No newline at end of file diff --git a/test/fixtures/EntryPointFixture.ts b/test/fixtures/EntryPointFixture.ts new file mode 100644 index 0000000..8cdbbad --- /dev/null +++ b/test/fixtures/EntryPointFixture.ts @@ -0,0 +1,7 @@ +import { ethers } from 'hardhat' +import { EntryPoint } from '../../typechain-types' + +export async function entryPointFixture(): Promise { + const factory = await ethers.getContractFactory("EntryPoint") + return (await factory.deploy()) as EntryPoint +} \ No newline at end of file diff --git a/test/fixtures/FacetRegistryFixture.ts b/test/fixtures/FacetRegistryFixture.ts new file mode 100644 index 0000000..5c4e6a5 --- /dev/null +++ b/test/fixtures/FacetRegistryFixture.ts @@ -0,0 +1,9 @@ +import { ethers } from 'hardhat' +import { FacetRegistry } from '../../typechain-types' + +export async function facetRegistryFixture( + owner: string +): Promise { + const factory = await ethers.getContractFactory("FacetRegistry") + return (await factory.deploy(owner)) as FacetRegistry +} \ No newline at end of file diff --git a/test/fixtures/GuardianFacetFixture.ts b/test/fixtures/GuardianFacetFixture.ts new file mode 100644 index 0000000..c173507 --- /dev/null +++ b/test/fixtures/GuardianFacetFixture.ts @@ -0,0 +1,9 @@ +import { ethers } from 'hardhat' +import { GuardianFacet, SecurityManager } from '../../typechain-types' + +export async function guardianFacetFixture( + securityManager: SecurityManager +): Promise { + const factory = await ethers.getContractFactory("GuardianFacet") + return (await factory.deploy(securityManager.address)) as GuardianFacet +} \ No newline at end of file diff --git a/test/fixtures/LockFacetFixture.ts b/test/fixtures/LockFacetFixture.ts new file mode 100644 index 0000000..9debbe9 --- /dev/null +++ b/test/fixtures/LockFacetFixture.ts @@ -0,0 +1,9 @@ +import { ethers } from 'hardhat' +import { LockFacet, SecurityManager } from '../../typechain-types' + +export async function lockFacetFixture( + securityManager: SecurityManager +): Promise { + const factory = await ethers.getContractFactory("LockFacet") + return (await factory.deploy(securityManager.address)) as LockFacet +} \ No newline at end of file diff --git a/test/fixtures/MultiSigFacetFixture.ts b/test/fixtures/MultiSigFacetFixture.ts new file mode 100644 index 0000000..8e41194 --- /dev/null +++ b/test/fixtures/MultiSigFacetFixture.ts @@ -0,0 +1,7 @@ +import { ethers } from 'hardhat' +import { MultiSigFacet } from '../../typechain-types' + +export async function multiSigFacetFixture(): Promise { + const factory = await ethers.getContractFactory("MultiSigFacet") + return (await factory.deploy()) as MultiSigFacet +} \ No newline at end of file diff --git a/test/fixtures/RestrictionsFacetFixture.ts b/test/fixtures/RestrictionsFacetFixture.ts new file mode 100644 index 0000000..253c5da --- /dev/null +++ b/test/fixtures/RestrictionsFacetFixture.ts @@ -0,0 +1,7 @@ +import {ethers} from 'hardhat' +import { RestrictionsFacet } from '../../typechain-types' + +export async function restrictionsFacetFixture(): Promise { + const factory = await ethers.getContractFactory("RestrictionsFacet") + return (await factory.deploy()) as RestrictionsFacet +} \ No newline at end of file diff --git a/test/fixtures/Secp256k1VerificationFacetFixture.ts b/test/fixtures/Secp256k1VerificationFacetFixture.ts new file mode 100644 index 0000000..df878dd --- /dev/null +++ b/test/fixtures/Secp256k1VerificationFacetFixture.ts @@ -0,0 +1,7 @@ +import { ethers } from 'hardhat' +import { Secp256k1VerificationFacet } from '../../typechain-types' + +export async function secp256k1VerificationFacetFixture(): Promise { + const factory = await ethers.getContractFactory("Secp256k1VerificationFacet") + return (await factory.deploy()) as Secp256k1VerificationFacet +} \ No newline at end of file diff --git a/test/fixtures/Secp256r1VerificationFacetFixture.ts b/test/fixtures/Secp256r1VerificationFacetFixture.ts new file mode 100644 index 0000000..cdbd5b3 --- /dev/null +++ b/test/fixtures/Secp256r1VerificationFacetFixture.ts @@ -0,0 +1,7 @@ +import { ethers } from 'hardhat' +import { Secp256r1VerificationFacet } from '../../typechain-types' + +export async function secp256r1VerificationFacetFixture(): Promise { + const factory = await ethers.getContractFactory("Secp256r1VerificationFacet") + return (await factory.deploy()) as Secp256r1VerificationFacet +} \ No newline at end of file diff --git a/test/fixtures/Secp256r1VerificationFacetV2Fixture.ts b/test/fixtures/Secp256r1VerificationFacetV2Fixture.ts new file mode 100644 index 0000000..e7971f2 --- /dev/null +++ b/test/fixtures/Secp256r1VerificationFacetV2Fixture.ts @@ -0,0 +1,7 @@ +import { ethers } from 'hardhat' +import { Secp256r1VerificationFacetV2 } from '../../typechain-types' + +export async function secp256r1VerificationFacetV2Fixture(): Promise { + const factory = await ethers.getContractFactory("Secp256r1VerificationFacetV2") + return (await factory.deploy()) as Secp256r1VerificationFacetV2 +} \ No newline at end of file diff --git a/test/fixtures/SecurityManagerFixture.ts b/test/fixtures/SecurityManagerFixture.ts new file mode 100644 index 0000000..ab7c647 --- /dev/null +++ b/test/fixtures/SecurityManagerFixture.ts @@ -0,0 +1,9 @@ +import { ethers } from 'hardhat' +import { SecurityManager } from '../../typechain-types' + +export async function securityManagerFixture( + owner: string +): Promise { + const factory = await ethers.getContractFactory("SecurityManager") + return (await factory.deploy(owner)) as SecurityManager +} \ No newline at end of file diff --git a/test/fixtures/SignatureMigrationFacetFixture.ts b/test/fixtures/SignatureMigrationFacetFixture.ts new file mode 100644 index 0000000..08cff11 --- /dev/null +++ b/test/fixtures/SignatureMigrationFacetFixture.ts @@ -0,0 +1,9 @@ +import { ethers } from 'hardhat' +import { SecurityManager, SignatureMigrationFacet } from '../../typechain-types' + +export async function signatureMigrationFacetFixture( + securityManager: SecurityManager +): Promise { + const factory = await ethers.getContractFactory("SignatureMigrationFacet") + return (await factory.deploy(securityManager.address)) as SignatureMigrationFacet +} \ No newline at end of file diff --git a/test/fixtures/TestCounterFixture.ts b/test/fixtures/TestCounterFixture.ts new file mode 100644 index 0000000..9bcc492 --- /dev/null +++ b/test/fixtures/TestCounterFixture.ts @@ -0,0 +1,7 @@ +import { ethers } from 'hardhat' +import { TestCounter } from '../../typechain-types' + +export async function testCounterFixture(): Promise { + const factory = await ethers.getContractFactory("TestCounter") + return (await factory.deploy()) as TestCounter +} \ No newline at end of file diff --git a/test/fixtures/TestERC1155Fixture.ts b/test/fixtures/TestERC1155Fixture.ts new file mode 100644 index 0000000..13e6352 --- /dev/null +++ b/test/fixtures/TestERC1155Fixture.ts @@ -0,0 +1,7 @@ +import { ethers } from 'hardhat' +import { TestERC1155 } from '../../typechain-types' + +export async function testERC1155Fixture(): Promise { + const factory = await ethers.getContractFactory("TestERC1155") + return (await factory.deploy()) as TestERC1155 +} \ No newline at end of file diff --git a/test/fixtures/TestERC777Fixture.ts b/test/fixtures/TestERC777Fixture.ts new file mode 100644 index 0000000..e21e1e4 --- /dev/null +++ b/test/fixtures/TestERC777Fixture.ts @@ -0,0 +1,9 @@ +import { ethers } from 'hardhat' +import { TestERC777 } from '../../typechain-types' + +export async function testERC777ixture( + operators: Array +): Promise { + const factory = await ethers.getContractFactory("TestERC777") + return (await factory.deploy(operators)) as TestERC777 +} \ No newline at end of file diff --git a/test/fixtures/TestInvalidSecp256k1VerificationFacetFixture.ts b/test/fixtures/TestInvalidSecp256k1VerificationFacetFixture.ts new file mode 100644 index 0000000..1c6177e --- /dev/null +++ b/test/fixtures/TestInvalidSecp256k1VerificationFacetFixture.ts @@ -0,0 +1,7 @@ +import { ethers } from 'hardhat' +import { TestInvalidSecp256k1VerificationFacet } from '../../typechain-types' + +export async function testInvalidSecp256k1VerificationFacetFixture(): Promise { + const factory = await ethers.getContractFactory("TestInvalidSecp256k1VerificationFacet") + return (await factory.deploy()) as TestInvalidSecp256k1VerificationFacet +} \ No newline at end of file diff --git a/test/fixtures/TestNFTFixture.ts b/test/fixtures/TestNFTFixture.ts new file mode 100644 index 0000000..242dc92 --- /dev/null +++ b/test/fixtures/TestNFTFixture.ts @@ -0,0 +1,7 @@ +import { ethers } from 'hardhat' +import { TestNFT } from '../../typechain-types' + +export async function testNFTFixture(): Promise { + const factory = await ethers.getContractFactory("TestNFT") + return (await factory.deploy()) as TestNFT +} \ No newline at end of file diff --git a/test/fixtures/TestTokenFixture.ts b/test/fixtures/TestTokenFixture.ts new file mode 100644 index 0000000..8756ede --- /dev/null +++ b/test/fixtures/TestTokenFixture.ts @@ -0,0 +1,7 @@ +import { ethers } from 'hardhat' +import { TestToken } from '../../typechain-types' + +export async function testTokenFixture(): Promise { + const factory = await ethers.getContractFactory("TestToken") + return (await factory.deploy()) as TestToken +} \ No newline at end of file diff --git a/test/fixtures/TokenReceiverFacetFixture.ts b/test/fixtures/TokenReceiverFacetFixture.ts new file mode 100644 index 0000000..2d88451 --- /dev/null +++ b/test/fixtures/TokenReceiverFacetFixture.ts @@ -0,0 +1,7 @@ +import { ethers } from 'hardhat' +import { TokenReceiverFacet } from '../../typechain-types' + +export async function tokenReceiverFacetFixture(): Promise { + const factory = await ethers.getContractFactory("TokenReceiverFacet") + return (await factory.deploy()) as TokenReceiverFacet +} \ No newline at end of file diff --git a/test/fixtures/WhitelistRestrictionFixture.ts b/test/fixtures/WhitelistRestrictionFixture.ts new file mode 100644 index 0000000..54441f2 --- /dev/null +++ b/test/fixtures/WhitelistRestrictionFixture.ts @@ -0,0 +1,9 @@ +import {ethers} from 'hardhat' +import { WhitelistRestriction, WhitelistStorage } from '../../typechain-types' + +export async function whitelistRestrictionFixture( + whitelistStorage: WhitelistStorage +): Promise { + const factory = await ethers.getContractFactory("WhitelistRestriction") + return (await factory.deploy(whitelistStorage.address)) as WhitelistRestriction +} \ No newline at end of file diff --git a/test/fixtures/WhitelistStorageFixture.ts b/test/fixtures/WhitelistStorageFixture.ts new file mode 100644 index 0000000..74a7e1c --- /dev/null +++ b/test/fixtures/WhitelistStorageFixture.ts @@ -0,0 +1,7 @@ +import {ethers} from 'hardhat' +import { WhitelistStorage } from '../../typechain-types' + +export async function whitelistStorageFixture(): Promise { + const factory = await ethers.getContractFactory("WhitelistStorage") + return (await factory.deploy()) as WhitelistStorage +} \ No newline at end of file diff --git a/test/foundry/AccountFacet.t.sol b/test/foundry/AccountFacet.t.sol new file mode 100644 index 0000000..0815422 --- /dev/null +++ b/test/foundry/AccountFacet.t.sol @@ -0,0 +1,136 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.21; + +import "forge-std/Test.sol"; +// base contracts +import {BarzFactory} from "../../contracts/BarzFactory.sol"; +import {Barz} from "../../contracts/Barz.sol"; +// facets +import {AccountFacet} from "../../contracts/facets/AccountFacet.sol"; +import {Secp256k1VerificationFacet} from "../../contracts/facets/verification/secp256k1/Secp256k1VerificationFacet.sol"; +// interfaces +import {IAccountFacet} from "../../contracts/facets/interfaces/IAccountFacet.sol"; +import {IVerificationFacet} from "../../contracts/facets/interfaces/IVerificationFacet.sol"; +import {IDiamondCut} from "../../contracts/facets/base/interfaces/IDiamondCut.sol"; +import {UserOperation} from "../../contracts/aa-4337/interfaces/UserOperation.sol"; +import {IEntryPoint} from "../../contracts/aa-4337/interfaces/IEntryPoint.sol"; +import {IERC1271} from "../../contracts/interfaces/ERC/IERC1271.sol"; +// test contracts +import {TestCounter} from "../../contracts/test/TestCounter.sol"; +// constants & utils +import {Setup} from "./utils/Setup.sol"; +import {AccountFacetTestBase} from "./base/AccountFacetTestBase.sol"; + +contract AccountFacetTest is Test, Setup, AccountFacetTestBase { + + address[] public wallets; + // address public deployer; + address public operator; + address public user1; + + BarzFactory public barzFactory; + Barz public barz; + + TestCounter public testCounter; + + bytes constant callData = abi.encodeWithSignature( + "incrementCounter()" + ); + + function setUp() public { + uint256[] memory signers = new uint256[](2); + signers[0] = user1PrivateKey; + signers[1] = user2PrivateKey; + wallets = _setUpSigners(2, signers, 50 ether); + deployer = wallets[0]; + operator = wallets[1]; + testCounter = new TestCounter(); + barzFactory = _setUpBarzFactory(); + + // k1Facet & r1Facet are deployed during the setup of BarzFactory + barz = barzFactory.createAccount(address(k1Facet), user1PublicKey, walletCreationSalt); + vm.deal(address(barz), 10 ether); + } + + function test_initialze() public { + IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](1); + bytes4[] memory verificationFunctionSelectors = new bytes4[](3); + verificationFunctionSelectors[0] = IERC1271.isValidSignature.selector; + verificationFunctionSelectors[1] = Secp256k1VerificationFacet.validateOwnerSignature.selector; + verificationFunctionSelectors[2] = IVerificationFacet.owner.selector; + cut[0] = IDiamondCut.FacetCut({ + facetAddress: address(k1Facet), + action: IDiamondCut.FacetCutAction.Add, + functionSelectors: verificationFunctionSelectors + }); + + vm.expectEmit(true, true, false, true); + emit DiamondCut(cut, address(0), bytes("")); + + vm.expectEmit(true, false, false, true); + emit SignerInitialized(user1PublicKey); + + vm.expectEmit(true, true, false, true); + emit AccountInitialized(IEntryPoint(address(entryPoint)), user1PublicKey); + + // createAccount automatically calls initialize from the AccountFacet + barz = barzFactory.createAccount(address(k1Facet), user1PublicKey, walletCreationSalt + 0x1234); + // entrypoint + assertEq(address(AccountFacet(address(barz)).entryPoint()), address(IEntryPoint(address(entryPoint)))); + // facetRegistry + assertEq(IVerificationFacet(address(barz)).owner(), abi.encodePacked(publicKeyToAddress(user1PublicKey))); + } + + function test_execute() public { + int expectedCounter = 1; + + bytes memory executeCallData = encodeExecuteCall(address(testCounter), 0, callData); + + UserOperation[] memory userOp = new UserOperation[](1); + uint256[] memory signingKey = new uint256[](1); + userOp[0] = this.prepareUserOp(address(barz), nonce[address(barz)], executeCallData); + signingKey[0] = user1PrivateKey; + + userOp = signUserOperation(userOp, signingKey); + + vm.expectEmit(true, false, false, true, address(testCounter)); + emit CounterIncremented(expectedCounter); + + entryPoint.handleOps(userOp, payable(barz)); + + assertEq(testCounter.getCount(), expectedCounter); + } + + function test_executeBatch() public { + int expectedCounter = 3; + + address[] memory _dest = new address[](3); + uint256[] memory _value = new uint256[](3); + bytes[] memory _callData = new bytes[](3); + + for (uint256 i; i < 3; i++) { + _dest[i] = address(testCounter); + _value[i] = 0; + _callData[i] = callData; + } + + bytes memory executeBatchCallData = encodeExecuteBatchCall(_dest, _value, _callData); + + UserOperation[] memory userOp = new UserOperation[](1); + uint256[] memory signingKey = new uint256[](1); + userOp[0] = this.prepareUserOp(address(barz), nonce[address(barz)], executeBatchCallData); + signingKey[0] = user1PrivateKey; + + userOp = signUserOperation(userOp, signingKey); + + for (uint256 i; i < 3; i++) { + vm.expectEmit(true, false, false, false, address(testCounter)); + emit CounterIncremented(int(i+1)); + } + + entryPoint.handleOps(userOp, payable(barz)); + + assertEq(testCounter.getCount(), expectedCounter); + } + +} \ No newline at end of file diff --git a/test/foundry/AccountRecoveryFacet.t.sol b/test/foundry/AccountRecoveryFacet.t.sol new file mode 100644 index 0000000..7f11665 --- /dev/null +++ b/test/foundry/AccountRecoveryFacet.t.sol @@ -0,0 +1,354 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.21; + +import "forge-std/Test.sol"; +// base contracts +import {BarzFactory} from "../../contracts/BarzFactory.sol"; +import {Barz} from "../../contracts/Barz.sol"; +// facets +import {AccountFacet} from "../../contracts/facets/AccountFacet.sol"; +import {Secp256k1VerificationFacet} from "../../contracts/facets/verification/secp256k1/Secp256k1VerificationFacet.sol"; +import {GuardianFacet} from "../../contracts/facets/GuardianFacet.sol"; +import {AccountRecoveryFacet} from "../../contracts/facets/AccountRecoveryFacet.sol"; +import {LockFacet} from "../../contracts/facets/LockFacet.sol"; +import {RecoveryConfig} from "../../contracts/libraries/LibFacetStorage.sol"; +import {LibVerification} from "../../contracts/libraries/LibVerification.sol"; +// interfaces +import {IDiamondCut} from "../../contracts/facets/base/interfaces/IDiamondCut.sol"; +import {UserOperation} from "../../contracts/aa-4337/interfaces/UserOperation.sol"; +// constants & utils +import {Setup} from "./utils/Setup.sol"; +import {Constants} from "./utils/Constants.sol"; +import {AccountRecoveryFacetTestBase} from "./base/AccountRecoveryFacetTestBase.sol"; + +contract AccountRecoveryFacetTest is Test, Setup, AccountRecoveryFacetTestBase { + + address[] public wallets; + address public operator; + address public user1; + address public guardian1; + address public guardian2; + uint256 public guardian1PrivateKey = 1; + uint256 public guardian2PrivateKey = 2; + bytes constant recoveryPublicKey = user2PublicKey; + + BarzFactory public barzFactory; + Barz public barz; + + function setUp() public { + skip(1706504435); // 1706504435 = Date and time (GMT): Monday, 29 January 2024 05:00:35 + uint256[] memory signers = new uint256[](2); + signers[0] = user1PrivateKey; + signers[1] = user2PrivateKey; + wallets = _setUpSigners(2, signers, 50 ether); + deployer = wallets[0]; + operator = wallets[1]; + guardian1 = vm.addr(guardian1PrivateKey); + guardian2 = vm.addr(guardian2PrivateKey); + + barzFactory = _setUpBarzFactory(); + + // k1Facet & r1Facet are deployed during the setup of BarzFactory + barz = barzFactory.createAccount(address(k1Facet), user1PublicKey, walletCreationSalt); + vm.deal(address(barz), 10 ether); + _addGuardianFacet(); + _addAccountRecoveryFacet(); + _addLockFacet(); + } + + function _addGuardianFacet() internal { + cutFacet(address(guardianFacet), IDiamondCut.FacetCutAction.Add, Constants.guardianFacetSelectors(), address(barz), user1PrivateKey); + } + + function _addAccountRecoveryFacet() internal { + cutFacet(address(accountRecoveryFacet), IDiamondCut.FacetCutAction.Add, Constants.accountRecoveryFacetSelectors(), address(barz), user1PrivateKey); + } + + function _addLockFacet() internal { + cutFacet(address(lockFacet), IDiamondCut.FacetCutAction.Add, Constants.lockFacetSelectors(), address(barz), user1PrivateKey); + } + + function _initiateRecovery() internal { + uint64 expectedExecutionTime = uint64(block.timestamp + Constants.defaultRecoveryPeriod); + + vm.prank(guardian1); + AccountRecoveryFacet(address(barz)).approveAccountRecovery(recoveryPublicKey); + + vm.expectEmit(true, true, false, true); + emit RecoveryExecuted(recoveryPublicKey, expectedExecutionTime); + + vm.prank(guardian2); + AccountRecoveryFacet(address(barz)).approveAccountRecovery(recoveryPublicKey); + } + + function _addGuardian(address _guardian) internal { + UserOperation[] memory userOp = new UserOperation[](1); + uint256[] memory signingKey = new uint256[](1); + + bytes memory addGuardianData = abi.encodeWithSignature("addGuardian(address)", _guardian); + bytes memory callData = encodeExecuteCall(address(barz), 0, addGuardianData); + userOp[0] = this.prepareUserOp(address(barz), nonce[address(barz)]++, callData); + signingKey[0] = user1PrivateKey; + + userOp = signUserOperation(userOp, signingKey); + entryPoint.handleOps(userOp, payable(barz)); + + skip(GuardianFacet(address(barz)).getAdditionSecurityPeriod() + 1); + GuardianFacet(address(barz)).confirmGuardianAddition(_guardian); + + address[] memory expectedGuardian = new address[](1); + expectedGuardian[0] = _guardian; + } + + function test_approveAccountRecovery() public { + _addGuardian(guardian1); + uint64 expectedExpiry = uint64(block.timestamp + Constants.defaultApprovalValidationPeriod); + + vm.expectEmit(true, true, false, true, address(barz)); + emit RecoveryApproved(recoveryPublicKey, guardian1, expectedExpiry); + + vm.prank(guardian1); + AccountRecoveryFacet(address(barz)).approveAccountRecovery(recoveryPublicKey); + } + + function test_revokeAccountRecoveryApproval() public { + _addGuardian(guardian1); + _addGuardian(guardian2); + + uint64 expectedExpiry = uint64(block.timestamp + Constants.defaultApprovalValidationPeriod); + + vm.expectEmit(true, true, false, true, address(barz)); + emit RecoveryApproved(recoveryPublicKey, guardian1, expectedExpiry); + + vm.prank(guardian1); + AccountRecoveryFacet(address(barz)).approveAccountRecovery(recoveryPublicKey); + + vm.expectEmit(true, true, false, true, address(barz)); + emit RecoveryApprovalRevoked(recoveryPublicKey, guardian1); + + vm.prank(guardian1); + AccountRecoveryFacet(address(barz)).revokeAccountRecoveryApproval(recoveryPublicKey); + } + + function test_executeRecovery() public { + _addGuardian(guardian1); + _addGuardian(guardian2); + + address[] memory guardians = new address[](2); + guardians[0] = guardian1; + guardians[1] = guardian2; + bytes[] memory recoveryApprovalSignatures = new bytes[](2); + + bytes32 recoveryPublicKeyHash = AccountRecoveryFacet(address(barz)).getApprovalRecoveryKeyHash(recoveryPublicKey, "ExecuteRecovery"); + + (uint8 v, bytes32 r, bytes32 s) = vm.sign(guardian1PrivateKey, recoveryPublicKeyHash); + recoveryApprovalSignatures[0] = abi.encodePacked(r, s, v); + (v, r, s) = vm.sign(guardian2PrivateKey, recoveryPublicKeyHash); + recoveryApprovalSignatures[1] = abi.encodePacked(r, s, v); + + vm.expectEmit(true, true, false, true); + emit RecoveryExecuted(recoveryPublicKey, uint64(block.timestamp + Constants.defaultRecoveryPeriod)); + + AccountRecoveryFacet(address(barz)).executeRecovery(recoveryPublicKey, guardians, recoveryApprovalSignatures); + + // Barz should be locked if recovery is executed + assertEq(LockFacet(address(barz)).isLocked(), true); + } + + function test_finalizeRecovery() public { + _addGuardian(guardian1); + _addGuardian(guardian2); + + // checking the state of owner before recovery + assertEq(bytesToAddress(Secp256k1VerificationFacet(address(barz)).owner()), publicKeyToAddress(user1PublicKey)); + + // approve on-chain & off-chain + vm.prank(guardian1); + AccountRecoveryFacet(address(barz)).approveAccountRecovery(recoveryPublicKey); + + address[] memory guardians = new address[](1); + guardians[0] = guardian2; + bytes[] memory recoveryApprovalSignatures = new bytes[](1); + + bytes32 recoveryPublicKeyHash = AccountRecoveryFacet(address(barz)).getApprovalRecoveryKeyHash(recoveryPublicKey, "ExecuteRecovery"); + + (uint8 v, bytes32 r, bytes32 s) = vm.sign(guardian2PrivateKey, recoveryPublicKeyHash); + recoveryApprovalSignatures[0] = abi.encodePacked(r, s, v); + + vm.expectEmit(true, true, false, true); + emit RecoveryExecuted(recoveryPublicKey, uint64(block.timestamp + Constants.defaultRecoveryPeriod)); + + AccountRecoveryFacet(address(barz)).executeRecovery(recoveryPublicKey, guardians, recoveryApprovalSignatures); + + skip(Constants.defaultRecoveryPeriod + 1); + + vm.expectEmit(true, false, false, true); + emit RecoveryFinalized(recoveryPublicKey); + + AccountRecoveryFacet(address(barz)).finalizeRecovery(); + + // checking if the owner of Barz has been updated + assertEq(bytesToAddress(Secp256k1VerificationFacet(address(barz)).owner()), publicKeyToAddress(recoveryPublicKey)); + } + + function test_approveCancelRecovery() public { + _addGuardian(guardian1); + _addGuardian(guardian2); + + _initiateRecovery(); + uint64 expectedExecutionTime = uint64(block.timestamp + Constants.defaultRecoveryPeriod); + + RecoveryConfig memory recoveryConfig = AccountRecoveryFacet(address(barz)).getPendingRecovery(); + assertEq(recoveryConfig.recoveryPublicKey, recoveryPublicKey); + assertEq(recoveryConfig.executeAfter, expectedExecutionTime); + + vm.expectEmit(true, true, false, true); + emit RecoveryCancellationApproved(recoveryPublicKey, guardian1); + + vm.prank(guardian1); + AccountRecoveryFacet(address(barz)).approveCancelRecovery(recoveryPublicKey); + + vm.expectEmit(true, false, false, true); + emit RecoveryCanceled(recoveryPublicKey); + + vm.prank(guardian2); + AccountRecoveryFacet(address(barz)).approveCancelRecovery(recoveryPublicKey); + + // check if the final state has been initialized back to 0 + RecoveryConfig memory updatedRecoveryConfig = AccountRecoveryFacet(address(barz)).getPendingRecovery(); + assertEq(updatedRecoveryConfig.recoveryPublicKey, new bytes(0)); + assertEq(updatedRecoveryConfig.executeAfter, uint64(0)); + } + + function test_hardStopRecovery() public { + _addGuardian(guardian1); + _addGuardian(guardian2); + + _initiateRecovery(); + + bytes32 hardstopPublicKeyHash = AccountRecoveryFacet(address(barz)).getApprovalRecoveryKeyHash( + "0", + "HardstopRecovery" + ); + + bytes32 domainSeparator = keccak256(abi.encode(LibVerification.DOMAIN_SEPARATOR_TYPEHASH, block.chainid, address(barz))); + bytes32 encodedMessageHash = keccak256(abi.encode(LibVerification.BARZ_MSG_TYPEHASH, keccak256(abi.encode(hardstopPublicKeyHash)))); + bytes32 msgHash = keccak256(abi.encodePacked("\x19\x01", domainSeparator, encodedMessageHash)); + + (uint8 v, bytes32 r, bytes32 s) = vm.sign(user1PrivateKey, msgHash); + + vm.expectEmit(true, false, false, true); + emit RecoveryHardstopped(); + + AccountRecoveryFacet(address(barz)).hardstopRecovery(abi.encodePacked(r, s, v)); + + assertEq(LockFacet(address(barz)).isLocked(), false); + } + + function test_cancelRecovery() public { + _addGuardian(guardian1); + _addGuardian(guardian2); + + _initiateRecovery(); + + address[] memory guardians = new address[](2); + guardians[0] = guardian1; + guardians[1] = guardian2; + bytes[] memory recoveryApprovalSignatures = new bytes[](2); + + bytes32 recoveryPublicKeyHash = AccountRecoveryFacet(address(barz)).getApprovalRecoveryKeyHash(recoveryPublicKey, "CancelRecovery"); + + (uint8 v, bytes32 r, bytes32 s) = vm.sign(guardian1PrivateKey, recoveryPublicKeyHash); + recoveryApprovalSignatures[0] = abi.encodePacked(r, s, v); + (v, r, s) = vm.sign(guardian2PrivateKey, recoveryPublicKeyHash); + recoveryApprovalSignatures[1] = abi.encodePacked(r, s, v); + + vm.expectEmit(true, true, false, true); + emit RecoveryCanceled(recoveryPublicKey); + + AccountRecoveryFacet(address(barz)).cancelRecovery(recoveryPublicKey, guardians, recoveryApprovalSignatures); + + // Barz should be unlocked if recovery is canceled + assertEq(LockFacet(address(barz)).isLocked(), false); + } + + function test_validateNewOwner() public { + // to be successful with valid public key + AccountRecoveryFacet(address(barz)).validateNewOwner(recoveryPublicKey); + + AccountRecoveryFacet(address(barz)).validateNewOwner(abi.encodePacked(publicKeyToAddress(recoveryPublicKey))); + + // to revert - invalid format for Secp256k1VerificationFacet + vm.expectRevert(AccountRecoveryFacet__InvalidRecoveryPublicKey.selector); + AccountRecoveryFacet(address(barz)).validateNewOwner(abi.encodePacked("0x1234567890")); + } + + function test_getApprovalRecoveryKeyHash() public { + // sample testing with execute recovery hash + bytes32 actualKeyHash = AccountRecoveryFacet(address(barz)).getApprovalRecoveryKeyHash(recoveryPublicKey, "ExecuteRecovery"); + uint256 recoveryFacetNonce = 0; + bytes32 expectedKeyHash = keccak256( + abi.encodePacked( + "\x19Ethereum Signed Message:\n32", + keccak256( + abi.encode( + recoveryPublicKey, + "ExecuteRecovery", + address(barz), + getChainId(), + recoveryFacetNonce + ) + ) + ) + ); + + assertEq(actualKeyHash, expectedKeyHash); + } + + function test_getRecoveryApprovalCountWithTimeValidity() public { + _addGuardian(guardian1); + _addGuardian(guardian2); + + bytes32 recoveryKeyHash = AccountRecoveryFacet(address(barz)).getApprovalRecoveryKeyHash(recoveryPublicKey, "ExecuteRecovery"); + + assertEq(AccountRecoveryFacet(address(barz)).getRecoveryApprovalCountWithTimeValidity(recoveryKeyHash), 0); + + vm.prank(guardian1); + AccountRecoveryFacet(address(barz)).approveAccountRecovery(recoveryPublicKey); + + assertEq(AccountRecoveryFacet(address(barz)).getRecoveryApprovalCountWithTimeValidity(recoveryKeyHash), 1); + + vm.prank(guardian2); + AccountRecoveryFacet(address(barz)).approveAccountRecovery(recoveryPublicKey); + + assertEq(AccountRecoveryFacet(address(barz)).getRecoveryApprovalCountWithTimeValidity(recoveryKeyHash), 2); + + skip(block.timestamp + Constants.defaultApprovalValidationPeriod); + + assertEq(AccountRecoveryFacet(address(barz)).getRecoveryApprovalCountWithTimeValidity(recoveryKeyHash), 0); + } + + function test_isRecoveryApproved() public { + _addGuardian(guardian1); + _addGuardian(guardian2); + + bytes32 recoveryKeyHash = AccountRecoveryFacet(address(barz)).getApprovalRecoveryKeyHash(recoveryPublicKey, "ExecuteRecovery"); + + assertEq(AccountRecoveryFacet(address(barz)).isRecoveryApproved(recoveryKeyHash, guardian1), false); + assertEq(AccountRecoveryFacet(address(barz)).isRecoveryApproved(recoveryKeyHash, guardian2), false); + + vm.prank(guardian1); + AccountRecoveryFacet(address(barz)).approveAccountRecovery(recoveryPublicKey); + assertEq(AccountRecoveryFacet(address(barz)).isRecoveryApproved(recoveryKeyHash, guardian1), true); + + vm.prank(guardian2); + AccountRecoveryFacet(address(barz)).approveAccountRecovery(recoveryPublicKey); + assertEq(AccountRecoveryFacet(address(barz)).isRecoveryApproved(recoveryKeyHash, guardian2), true); + + skip(block.timestamp + Constants.defaultApprovalValidationPeriod); + + assertEq(AccountRecoveryFacet(address(barz)).isRecoveryApproved(recoveryKeyHash, guardian1), false); + assertEq(AccountRecoveryFacet(address(barz)).isRecoveryApproved(recoveryKeyHash, guardian2), false); + } + +} \ No newline at end of file diff --git a/test/foundry/TokenReceiverFacet.t.sol b/test/foundry/TokenReceiverFacet.t.sol new file mode 100644 index 0000000..7217eb4 --- /dev/null +++ b/test/foundry/TokenReceiverFacet.t.sol @@ -0,0 +1,130 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.21; + +import "forge-std/Test.sol"; +// base contracts +import {BarzFactory} from "../../contracts/BarzFactory.sol"; +import {Barz} from "../../contracts/Barz.sol"; +// interfaces +import {IERC1155Receiver} from "../../contracts/interfaces/ERC/IERC1155Receiver.sol"; +import {IERC677Receiver} from "../../contracts/interfaces/ERC/IERC677Receiver.sol"; +import {IERC721Receiver} from "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol"; +import {IERC777Recipient} from "@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol"; +// test token +import {TestNFT} from "../../contracts/test/TestNFT.sol"; +import {TestERC1155} from "../../contracts/test/TestERC1155.sol"; +// utils +import {Setup} from "./utils/Setup.sol"; +import {TokenReceiverFacetTestBase} from "./base/TokenReceiverFacetTestBase.sol"; + +contract TokenReceiverFacetTest is Test, Setup, TokenReceiverFacetTestBase { + address[] public wallets; + // address public deployer; + address public operator; + address public user1; + + BarzFactory public barzFactory; + Barz public barz; + + TestNFT internal testNFT; + TestERC1155 internal testERC1155; + + uint256 mockTokenId = 1; + uint256 mockAmount = 100; + + function setUp() public { + uint256[] memory signers = new uint256[](2); + signers[0] = user1PrivateKey; + signers[1] = user2PrivateKey; + wallets = _setUpSigners(10, signers, 50 ether); + deployer = wallets[0]; + operator = wallets[1]; + user1 = wallets[2]; + + vm.prank(deployer); + + // setup test token contracts + testNFT = new TestNFT(); + testERC1155 = new TestERC1155(); + + barzFactory = _setUpBarzFactory(); + k1Facet = _setUpK1Facet(); + + barz = barzFactory.createAccount(address(k1Facet), user1PublicKey, walletCreationSalt); + vm.deal(address(barz), 10 ether); + vm.stopPrank(); + } + + function test_onERC721Received() public { + // 0x150b7a02 == IERC721Receiver.onERC721Received.selector + assertEq(IERC721Receiver(address(barz)).onERC721Received(deployer, address(operator), mockTokenId, "0x00"), bytes4(0x150b7a02)); + } + + function test_receiveSafeERC721TokenTransfer() public { + testNFT.mint(deployer); + vm.expectEmit(true, true, false, true, address(testNFT)); + emit Transfer(deployer, address(barz), mockTokenId); + + assertEq(testNFT.ownerOf(mockTokenId), deployer); + + vm.prank(deployer); + testNFT.safeTransferFrom(deployer, address(barz), mockTokenId); + + assertEq(testNFT.ownerOf(mockTokenId), address(barz)); + vm.stopPrank(); + } + + function test_onERC1155Received() public { + // 0xf23a6e61 == IERC1155Receiver.onERC1155Received.selector + assertEq(IERC1155Receiver(address(barz)).onERC1155Received(deployer, address(operator), mockTokenId, mockAmount, "0x00"), bytes4(0xf23a6e61)); + } + + function test_receiveSafeERC1155TokenTransfer() public { + testERC1155.mint(deployer, mockAmount); + assertEq(testERC1155.balanceOf(deployer, mockTokenId), mockAmount); + + vm.prank(deployer); + testERC1155.safeTransferFrom(deployer, address(barz), mockTokenId, mockAmount, "0x00"); + + assertEq(testERC1155.balanceOf(address(barz), mockTokenId), mockAmount); + vm.stopPrank(); + } + + function test_onERC1155BatchReceived() public { + uint256[] memory tokenIds = new uint256[](1); + uint256[] memory amounts = new uint256[](1); + + // 0xbc197c81 == IERC1155Receiver.onERC1155BatchReceived.selector + assertEq(IERC1155Receiver(address(barz)).onERC1155BatchReceived(deployer, operator, tokenIds, amounts, "0x00"), bytes4(0xbc197c81)); + } + + function test_receiveSafeERC1155BatchTokenTransfer() public { + address[] memory owners = populateAddressList(deployer, 3); + address[] memory barzOwners = populateAddressList(address(barz), 3); + uint256[] memory tokenIds = new uint256[](3); + tokenIds[0] = 1; + tokenIds[1] = 2; + tokenIds[2] = 3; + uint256[] memory amounts = new uint256[](3); + amounts[0] = 10000; + amounts[1] = 20000; + amounts[2] = 30000; + testERC1155.mintBatch(deployer, tokenIds, amounts, "0x00"); + + assertEq(testERC1155.balanceOfBatch(owners, tokenIds), amounts); + vm.prank(deployer); + testERC1155.safeBatchTransferFrom(deployer, address(barz), tokenIds, amounts, "0x00"); + + assertEq(testERC1155.balanceOfBatch(barzOwners, tokenIds), amounts); + vm.stopPrank(); + } + + function test_tokensReceived() public { + IERC777Recipient(address(barz)).tokensReceived(deployer, deployer, deployer, mockAmount, "0x00", "0x00"); + } + + function test_onTokenTransfer() public { + assertEq(IERC677Receiver(address(barz)).onTokenTransfer(deployer, mockAmount, "0x00"), true); + } + +} \ No newline at end of file diff --git a/test/foundry/base/AccountFacetTestBase.sol b/test/foundry/base/AccountFacetTestBase.sol new file mode 100644 index 0000000..2ea55c4 --- /dev/null +++ b/test/foundry/base/AccountFacetTestBase.sol @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.21; + +import {IEntryPoint} from "../../../contracts/aa-4337/interfaces/IEntryPoint.sol"; +import {IDiamondCut} from "../../../contracts/facets/base/interfaces/IDiamondCut.sol"; + +contract AccountFacetTestBase { + event AccountInitialized( + IEntryPoint indexed entryPoint, + bytes indexed ownerPublicKey + ); + event SignerInitialized(bytes); + + event CounterIncremented(int count); + + event DiamondCut( + IDiamondCut.FacetCut[] _diamondCut, + address _init, + bytes _calldata + ); +} \ No newline at end of file diff --git a/test/foundry/base/AccountRecoveryFacetTestBase.sol b/test/foundry/base/AccountRecoveryFacetTestBase.sol new file mode 100644 index 0000000..1bd16b4 --- /dev/null +++ b/test/foundry/base/AccountRecoveryFacetTestBase.sol @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.21; + +contract AccountRecoveryFacetTestBase { + event RecoveryApproved( + bytes indexed recoveryPublicKey, + address indexed guardian, + uint64 validUntil + ); + event RecoveryApprovalRevoked( + bytes indexed recoveryPublicKey, + address indexed guardian + ); + event RecoveryExecuted( + bytes indexed recoveryPublicKey, + uint64 executeAfter + ); + event RecoveryFinalized(bytes indexed recoveryPublicKey); + event RecoveryCanceled(bytes indexed recoveryPublicKey); + event RecoveryCancellationApproved( + bytes indexed recoveryPublicKey, + address indexed guardian + ); + event RecoveryHardstopped(); + error AccountRecoveryFacet__InvalidRecoveryPublicKey(); +} \ No newline at end of file diff --git a/test/foundry/base/TokenReceiverFacetTestBase.sol b/test/foundry/base/TokenReceiverFacetTestBase.sol new file mode 100644 index 0000000..80e673b --- /dev/null +++ b/test/foundry/base/TokenReceiverFacetTestBase.sol @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + +contract TokenReceiverFacetTestBase { + event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); +} \ No newline at end of file diff --git a/test/foundry/utils/Constants.sol b/test/foundry/utils/Constants.sol new file mode 100644 index 0000000..9a8010e --- /dev/null +++ b/test/foundry/utils/Constants.sol @@ -0,0 +1,201 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.21; + +import {IDiamondCut} from "../../../contracts/facets/base/interfaces/IDiamondCut.sol"; +import {IDiamondLoupe} from "../../../contracts/facets/base/interfaces/IDiamondLoupe.sol"; +import {IStorageLoupe} from "../../../contracts/facets/base/interfaces/IStorageLoupe.sol"; +import {IAccountFacet} from "../../../contracts/facets/interfaces/IAccountFacet.sol"; +import {BaseAccount} from "../../../contracts/aa-4337/core/BaseAccount.sol"; +import {IAccount} from "../../../contracts/aa-4337/interfaces/IAccount.sol"; +import {ILockFacet} from "../../../contracts/facets/interfaces/ILockFacet.sol"; +import {IGuardianFacet} from "../../../contracts/facets/interfaces/IGuardianFacet.sol"; +import {IVerificationFacet} from "../../../contracts/facets/interfaces/IVerificationFacet.sol"; +import {ILockFacet} from "../../../contracts/facets/interfaces/ILockFacet.sol"; +import {IRestrictionsFacet} from "../../../contracts/facets/interfaces/IRestrictionsFacet.sol"; +import {ISignatureMigrationFacet} from "../../../contracts/facets/interfaces/ISignatureMigrationFacet.sol"; +import {IAccountRecoveryFacet} from "../../../contracts/facets/interfaces/IAccountRecoveryFacet.sol"; +import {IERC165} from "../../../contracts/interfaces/ERC/IERC165.sol"; +import {IERC1271} from "../../../contracts/interfaces/ERC/IERC1271.sol"; + +library Constants { + + uint128 public constant defaultAdditionSecurityPeriod = 60 * 60 * 24 * 3; + uint128 public constant minAdditionSecurityPeriod = defaultAdditionSecurityPeriod / 2; + uint128 public constant maxAdditionSecurityPeriod = defaultAdditionSecurityPeriod * 2; + + uint128 public constant defaultRemovalSecurityPeriod = 60 * 60 * 24; + uint128 public constant minRemovalSecurityPeriod = defaultRemovalSecurityPeriod / 2; + uint128 public constant maxRemovalSecurityPeriod = defaultRemovalSecurityPeriod * 2; + + uint128 public constant defaultSecurityWindow = 60 * 60 * 24; + uint128 public constant minSecurityWindow = defaultSecurityWindow / 2; + uint128 public constant maxSecurityWindow = defaultSecurityWindow * 2; + + uint128 public constant defaultRecoveryPeriod = 60 * 60 * 48; + uint128 public constant minRecoveryPeriod = defaultRecoveryPeriod / 2; + uint128 public constant maxRecoveryPeriod = defaultRecoveryPeriod * 2; + + uint128 public constant defaultLockPeriod = 60 * 60 * 24; + uint128 public constant minLockPeriod = defaultLockPeriod / 2; + uint128 public constant maxLockPeriod = defaultLockPeriod * 2; + + uint128 public constant defaultApprovalValidationPeriod = 60 * 60 * 12; + uint128 public constant minApprovalValidationPeriod = defaultApprovalValidationPeriod / 2; + uint128 public constant maxApprovalValidationPeriod = defaultApprovalValidationPeriod * 2; + + uint128 public constant defaultMigrationPeriod = 60 * 60 * 3; + uint128 public constant minMigrationPeriod = defaultMigrationPeriod / 2; + uint128 public constant maxMigrationPeriod = defaultMigrationPeriod * 2; + + function diamondCutFacetSelectors() public pure returns (bytes4[] memory) { + bytes4[] memory facetSelectors = new bytes4[](10); + facetSelectors[0] = IDiamondCut.approveDiamondCut.selector; // approveDiamondCut((address,uint8,bytes4[])[]) + facetSelectors[1] = IDiamondCut.diamondCut.selector; // diamondCut((address,uint8,bytes4[])[],address,bytes) + facetSelectors[2] = IDiamondCut.diamondCutWithGuardian.selector; // diamondCutWithGuardian((address,uint8,bytes4[])[],address[],bytes[]) + facetSelectors[3] = IDiamondCut.getDiamondCutApprovalCountWithTimeValidity.selector; // getDiamondCutApprovalCountWithTimeValidity(bytes32) + facetSelectors[4] = IDiamondCut.getDiamondCutHash.selector; // getDiamondCutHash((address,uint8,bytes4[])[]) + facetSelectors[5] = IDiamondCut.getDiamondCutNonce.selector; // getDiamondCutNonce() + facetSelectors[6] = IDiamondCut.getOwnerCutApprovalWithTimeValidity.selector; // getOwnerCutApprovalWithTimeValidity(bytes32) + facetSelectors[7] = IDiamondCut.isCutApproved.selector; // isCutApproved(bytes32,address) + facetSelectors[8] = IDiamondCut.revokeDiamondCutApproval.selector; // revokeDiamondCutApproval((address,uint8,bytes4[])[]) + facetSelectors[9] = IDiamondCut.updateSupportsInterface.selector; // updateSupportsInterface(bytes4,bool) + return facetSelectors; + } + + function diamondLoupeFacetSelectors() public pure returns (bytes4[] memory) { + bytes4[] memory facetSelectors = new bytes4[](9); + facetSelectors[0] = IDiamondLoupe.facetAddress.selector; // facetAddress(bytes4) + facetSelectors[1] = IStorageLoupe.facetAddressFromStorage.selector; // facetAddressFromStorage(bytes4) + facetSelectors[2] = IDiamondLoupe.facetAddresses.selector; // facetAddresses() + facetSelectors[3] = IStorageLoupe.facetAddressesFromStorage.selector; // facetAddressesFromStorage() + facetSelectors[4] = IDiamondLoupe.facetFunctionSelectors.selector; // facetFunctionSelectors(address) + facetSelectors[5] = IStorageLoupe.facetFunctionSelectorsFromStorage.selector; // facetFunctionSelectorsFromStorage(address) + facetSelectors[6] = IDiamondLoupe.facets.selector; // facets() + facetSelectors[7] = IStorageLoupe.facetsFromStorage.selector; // facetsFromStorage() + facetSelectors[8] = IERC165.supportsInterface.selector; // supportsInterface(bytes4) + return facetSelectors; + } + + function accountFacetSelectors() public pure returns (bytes4[] memory) { + bytes4[] memory facetSelectors = new bytes4[](6); + facetSelectors[0] = BaseAccount.entryPoint.selector; // entryPoint() + facetSelectors[1] = BaseAccount.getNonce.selector; // getNonce() + facetSelectors[2] = IAccountFacet.execute.selector; // execute(address,uint256,bytes) + facetSelectors[3] = IAccountFacet.executeBatch.selector; // executeBatch(address[],uint256[],bytes[]) + facetSelectors[4] = IAccountFacet.initialize.selector; // initialize(address,address,address,address,bytes) + facetSelectors[5] = IAccount.validateUserOp.selector; // validateUserOp((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256) + return facetSelectors; + } + + function lockFacetSelectors() public pure returns (bytes4[] memory) { + bytes4[] memory facetSelectors = new bytes4[](7); + facetSelectors[0] = ILockFacet.getLockPeriod.selector; // getLockPeriod() + facetSelectors[1] = ILockFacet.getPendingLock.selector; // getPendingLock() + facetSelectors[2] = ILockFacet.getUnlockHash.selector; // getUnlockHash() + facetSelectors[3] = ILockFacet.isLocked.selector; // isLocked() + facetSelectors[4] = ILockFacet.lock.selector; // lock() + facetSelectors[5] = ILockFacet.lockNonce.selector; // lockNonce() + facetSelectors[6] = ILockFacet.unlock.selector; // unlock(address,bytes) + return facetSelectors; + } + + function guardianFacetSelectors() public pure returns (bytes4[] memory) { + bytes4[] memory facetSelectors = new bytes4[](20); + facetSelectors[0] = IGuardianFacet.addGuardian.selector; // addGuardian(address) + facetSelectors[1] = IGuardianFacet.addGuardians.selector; // addGuardians(address[]) + facetSelectors[2] = IGuardianFacet.cancelGuardianAddition.selector; // cancelGuardianAddition(address) + facetSelectors[3] = IGuardianFacet.cancelGuardianRemoval.selector; // cancelGuardianRemoval(address) + facetSelectors[4] = IGuardianFacet.confirmGuardianAddition.selector; // confirmGuardianAddition(address) + facetSelectors[5] = IGuardianFacet.confirmGuardianAdditions.selector; // confirmGuardianAdditions(address[]) + facetSelectors[6] = IGuardianFacet.confirmGuardianRemoval.selector; // confirmGuardianRemoval(address) + facetSelectors[7] = IGuardianFacet.confirmGuardianRemovals.selector; // confirmGuardianRemovals(address[]) + facetSelectors[8] = IGuardianFacet.getAdditionSecurityPeriod.selector; // getAdditionSecurityPeriod() + facetSelectors[9] = IGuardianFacet.getGuardians.selector; // getGuardians() + facetSelectors[10] = IGuardianFacet.getRemovalSecurityPeriod.selector; // getRemovalSecurityPeriod() + facetSelectors[11] = IGuardianFacet.getSecurityWindow.selector; // getSecurityWindow() + facetSelectors[12] = IGuardianFacet.guardianCount.selector; // guardianCount() + facetSelectors[13] = IGuardianFacet.isAdditionPending.selector; // isAdditionPending(address) + facetSelectors[14] = IGuardianFacet.isGuardian.selector; // isGuardian(address) + facetSelectors[15] = IGuardianFacet.isGuardianFacetRemovable.selector; // isGuardianFacetRemovable() + facetSelectors[16] = IGuardianFacet.isRemovalPending.selector; // isRemovalPending(address) + facetSelectors[17] = IGuardianFacet.majorityOfGuardians.selector; // majorityOfGuardians() + facetSelectors[18] = IGuardianFacet.removeGuardian.selector; // removeGuardian(address) + facetSelectors[19] = IGuardianFacet.removeGuardians.selector; // removeGuardians(address[]) + return facetSelectors; + } + + function k1FacetSelectors() public pure returns (bytes4[] memory) { + bytes4[] memory facetSelectors = new bytes4[](8); + facetSelectors[0] = IERC1271.isValidSignature.selector; // isValidSignature(bytes32,bytes) + facetSelectors[1] = IVerificationFacet.initializeSigner.selector; // initializeSigner(bytes) + facetSelectors[2] = IVerificationFacet.isValidKeyType.selector; // isValidKeyType(bytes) + facetSelectors[3] = IVerificationFacet.owner.selector; // owner() + facetSelectors[4] = IVerificationFacet.uninitializeSigner.selector; // uninitializeSigner() + facetSelectors[5] = IVerificationFacet.validateOwnerSignature.selector; // validateOwnerSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32) + facetSelectors[6] = IVerificationFacet.validateOwnerSignatureSelector.selector; // validateOwnerSignatureSelector() + facetSelectors[7] = 0xf45007c3; // validateSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,address) + return facetSelectors; + } + + function r1FacetSelectors() public pure returns (bytes4[] memory) { + bytes4[] memory facetSelectors = new bytes4[](8); + facetSelectors[0] = IERC1271.isValidSignature.selector; // isValidSignature(bytes32,bytes) + facetSelectors[1] = IVerificationFacet.initializeSigner.selector; // initializeSigner(bytes) + facetSelectors[2] = IVerificationFacet.isValidKeyType.selector; // isValidKeyType(bytes) + facetSelectors[3] = IVerificationFacet.owner.selector; // owner() + facetSelectors[4] = IVerificationFacet.uninitializeSigner.selector; // uninitializeSigner() + facetSelectors[5] = IVerificationFacet.validateOwnerSignature.selector; // validateOwnerSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32) + facetSelectors[6] = IVerificationFacet.validateOwnerSignatureSelector.selector; // validateOwnerSignatureSelector() + facetSelectors[7] = 0x11cfe388; // validateSignature((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256[2]) + return facetSelectors; + } + + + function restrictionsFacetSelectors() public pure returns (bytes4[] memory) { + bytes4[] memory facetSelectors = new bytes4[](6); + facetSelectors[0] = IRestrictionsFacet.addRestriction.selector; // addRestriction(address) + facetSelectors[1] = IRestrictionsFacet.getRestrictions.selector; // getRestrictions() + facetSelectors[2] = IRestrictionsFacet.initializeRestrictions.selector; // initializeRestrictions(address[]) + facetSelectors[3] = IRestrictionsFacet.removeRestriction.selector; // removeRestriction(address) + facetSelectors[4] = IRestrictionsFacet.uninitializeRestrictions.selector; // uninitializeRestrictions() + facetSelectors[5] = IRestrictionsFacet.verifyRestrictions.selector; // verifyRestrictions(address,address,uint256,bytes) + return facetSelectors; + } + + function signatureMigrationFacetSelectors() public pure returns (bytes4[] memory) { + bytes4[] memory facetSelectors = new bytes4[](14); + facetSelectors[0] = ISignatureMigrationFacet.approveCancelSignatureMigration.selector; // approveCancelSignatureMigration(address,bytes,bytes4[]) + facetSelectors[1] = ISignatureMigrationFacet.approveSignatureSchemeMigration.selector; // approveSignatureSchemeMigration(address,bytes,bytes4[]) + facetSelectors[2] = ISignatureMigrationFacet.cancelSignatureMigration.selector; // cancelSignatureMigration(address,bytes,bytes4[],address[],bytes[]) + facetSelectors[3] = ISignatureMigrationFacet.finalizeSignatureMigration.selector; // finalizeSignatureMigration() + facetSelectors[4] = ISignatureMigrationFacet.getApprovalMigrationKeyHash.selector; // getApprovalMigrationKeyHash(bytes,address,bytes4[],string) + facetSelectors[5] = ISignatureMigrationFacet.getMigrationApprovalCountWithTimeValidity.selector; // getMigrationApprovalCountWithTimeValidity(bytes32) + facetSelectors[6] = ISignatureMigrationFacet.getMigrationNonce.selector; // getMigrationNonce() + facetSelectors[7] = ISignatureMigrationFacet.getMigrationOwnerApprovalWithTimeValidity.selector; // getMigrationOwnerApprovalWithTimeValidity(bytes32) + facetSelectors[8] = ISignatureMigrationFacet.getPendingMigration.selector; // getPendingMigration() + facetSelectors[9] = ISignatureMigrationFacet.isMigrationApproved.selector; // isMigrationApproved(bytes32,address) + facetSelectors[10] = ISignatureMigrationFacet.isMigrationPending.selector; // isMigrationPending() + facetSelectors[11] = ISignatureMigrationFacet.migrateSignatureScheme.selector; // migrateSignatureScheme(address,bytes,bytes4[]) + facetSelectors[12] = ISignatureMigrationFacet.migrateSignatureSchemeWithGuardian.selector; // migrateSignatureSchemeWithGuardian(address,bytes,bytes4[],address[],bytes[]) + facetSelectors[13] = ISignatureMigrationFacet.revokeSignatureMigrationApproval.selector; // revokeSignatureMigrationApproval(address,bytes,bytes4[]) + return facetSelectors; + } + + function accountRecoveryFacetSelectors() public pure returns (bytes4[] memory) { + bytes4[] memory facetSelectors = new bytes4[](13); + facetSelectors[0] = IAccountRecoveryFacet.approveAccountRecovery.selector; // approveAccountRecovery(bytes) + facetSelectors[1] = IAccountRecoveryFacet.approveCancelRecovery.selector; // approveCancelRecovery(bytes) + facetSelectors[2] = IAccountRecoveryFacet.cancelRecovery.selector; // cancelRecovery(bytes,address[],bytes[]) + facetSelectors[3] = IAccountRecoveryFacet.executeRecovery.selector; // executeRecovery(bytes,address[],bytes[]) + facetSelectors[4] = IAccountRecoveryFacet.finalizeRecovery.selector; // finalizeRecovery() + facetSelectors[5] = IAccountRecoveryFacet.getApprovalRecoveryKeyHash.selector; // getApprovalRecoveryKeyHash(bytes,string) + facetSelectors[6] = IAccountRecoveryFacet.getPendingRecovery.selector; // getPendingRecovery() + facetSelectors[7] = IAccountRecoveryFacet.getRecoveryApprovalCountWithTimeValidity.selector; // getRecoveryApprovalCountWithTimeValidity(bytes32) + facetSelectors[8] = IAccountRecoveryFacet.getRecoveryNonce.selector; // getRecoveryNonce() + facetSelectors[9] = IAccountRecoveryFacet.hardstopRecovery.selector; // hardstopRecovery(bytes) + facetSelectors[10] = IAccountRecoveryFacet.isRecoveryApproved.selector; // isRecoveryApproved(bytes32,address) + facetSelectors[11] = IAccountRecoveryFacet.revokeAccountRecoveryApproval.selector; // revokeAccountRecoveryApproval(bytes) + facetSelectors[12] = IAccountRecoveryFacet.validateNewOwner.selector; // validateNewOwner(bytes) + return facetSelectors; + } +} \ No newline at end of file diff --git a/test/foundry/utils/Setup.sol b/test/foundry/utils/Setup.sol new file mode 100644 index 0000000..aac7429 --- /dev/null +++ b/test/foundry/utils/Setup.sol @@ -0,0 +1,416 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.21; + +import "forge-std/Test.sol"; +// base contracts +import {SecurityManager} from "../../../contracts/infrastructure/SecurityManager.sol"; +import {FacetRegistry} from "../../../contracts/infrastructure/FacetRegistry.sol"; +import {DefaultFallbackHandler} from "../../../contracts/infrastructure/DefaultFallbackHandler.sol"; +import {EntryPoint} from "../../../contracts/aa-4337/core/EntryPoint.sol"; +import {BarzFactory} from "../../../contracts/BarzFactory.sol"; +import {Barz} from "../../../contracts/Barz.sol"; +import {LibDiamond} from "../../../contracts/libraries/LibDiamond.sol"; +import {WhitelistStorage} from "../../../contracts/infrastructure/WhitelistStorage.sol"; +import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; +// facets +import {AccountFacet} from "../../../contracts/facets/AccountFacet.sol"; +import {Secp256k1VerificationFacet} from "../../../contracts/facets/verification/secp256k1/Secp256k1VerificationFacet.sol"; +import {Secp256r1VerificationFacet} from "../../../contracts/facets/verification/secp256r1/Secp256r1VerificationFacet.sol"; +import {AccountRecoveryFacet} from "../../../contracts/facets/AccountRecoveryFacet.sol"; +import {GuardianFacet} from "../../../contracts/facets/GuardianFacet.sol"; +import {TokenReceiverFacet} from "../../../contracts/facets/TokenReceiverFacet.sol"; +import {LockFacet} from "../../../contracts/facets/LockFacet.sol"; +import {DiamondCutFacet} from "../../../contracts/facets/base/DiamondCutFacet.sol"; +import {DiamondLoupeFacet} from "../../../contracts/facets/base/DiamondLoupeFacet.sol"; +import {RestrictionsFacet} from "../../../contracts/facets/RestrictionsFacet.sol"; +import {SignatureMigrationFacet} from "../../../contracts/facets/SignatureMigrationFacet.sol"; +// interfaces +import {IDiamondCut} from "../../../contracts/facets/base/interfaces/IDiamondCut.sol"; +import {UserOperationLib, UserOperation} from "../../../contracts/aa-4337/interfaces/UserOperation.sol"; +// constants +import {Constants} from "./Constants.sol"; + +contract Setup is Test { + using ECDSA for bytes32; + + address public deployer; + mapping(address => uint256) public nonce; + + EntryPoint public entryPoint; + SecurityManager public securityManager; + FacetRegistry public facetRegistry; + DefaultFallbackHandler public defaultFallbackHandler; + AccountFacet public accountFacet; + Secp256k1VerificationFacet public k1Facet; + Secp256r1VerificationFacet public r1Facet; + AccountRecoveryFacet public accountRecoveryFacet; + GuardianFacet public guardianFacet; + LockFacet public lockFacet; + DiamondCutFacet public diamondCutFacet; + DiamondLoupeFacet public diamondLoupeFacet; + RestrictionsFacet public restrictionsFacet; + TokenReceiverFacet public tokenReceiverFacet; + + // DISCLAMER: Do not use the below private keys to store funds + uint256 user1PrivateKey = 0x947dd69af402e7f48da1b845dfc1df6be593d01a0d8274bd03ec56712e7164e8; + bytes public constant user1PublicKey = + hex"04a464ab33c92f49bffbe52623b42c0ee045acf45c6a60e86aedd1b8b8ea92461e744d448c5081dac34c9ebc7823ee650e18541e9d21160d88c9b10ebce769d7b4"; + + uint256 user2PrivateKey = 0x6ef4524143bd25de19ee1089aa389a594f580ce248107244a95cafc030dd9c5e; + bytes public constant user2PublicKey = + hex"049b372203900a3f5db35feafc223af7d02e80926e74c9f24db47e494dfcd19e83a7df341689358897c0be2613fad5ab5b92af51835acddede5341b15abd26c625"; + uint256 walletCreationSalt = 1; + + function _setUpBarzFactory() public returns (BarzFactory barzFactory) { + accountFacet = _setUpAccountFacet(); + k1Facet = _setUpK1Facet(); + r1Facet = _setUpR1Facet(); + diamondLoupeFacet = _setUpDiamondLoupeFacet(); + restrictionsFacet = _setUpRestrictionsFacet(); + securityManager = _setUpSecurityManager(); + lockFacet = _setUpLockFacet(address(securityManager)); + accountRecoveryFacet = _setUpAccountRecoveryFacet(address(securityManager)); + guardianFacet = _setUpGuardianFacet(address(securityManager)); + tokenReceiverFacet = _setUpTokenReceiverFacet(); + facetRegistry = _setUpFacetRegistry(address(accountFacet), address(lockFacet), address(guardianFacet), address(k1Facet), address(r1Facet), address(restrictionsFacet), address(accountRecoveryFacet)); + diamondCutFacet = _setUpDiamondCutFacet(address(securityManager)); + defaultFallbackHandler = _setUpDefaultFallbackHandler(address(diamondCutFacet), address(accountFacet), address(tokenReceiverFacet), address(diamondLoupeFacet)); + entryPoint = new EntryPoint(); + + barzFactory = new BarzFactory( + address(accountFacet), + address(entryPoint), + address(facetRegistry), + address(defaultFallbackHandler) + ); + } + + function _setUpDefaultFallbackHandler( + address _diamondCutFacet, + address _accountFacet, + address _tokenReceiverFacet, + address _diamondLoupeFacet + ) internal returns (DefaultFallbackHandler defaultFallbackHandler_) { + vm.startPrank(deployer); + defaultFallbackHandler_ = new DefaultFallbackHandler( + _diamondCutFacet, + _accountFacet, + _tokenReceiverFacet, + _diamondLoupeFacet + ); + vm.stopPrank(); + } + + function _setUpSecurityManager() + internal + returns (SecurityManager securityManager_) + { + vm.startPrank(deployer); + securityManager_ = new SecurityManager(deployer); + securityManager_.initializeSecurityWindow( + Constants.defaultSecurityWindow, + Constants.minSecurityWindow, + Constants.maxSecurityWindow + ); + securityManager_.initializeAdditionSecurityPeriod( + Constants.defaultAdditionSecurityPeriod, + Constants.minAdditionSecurityPeriod, + Constants.maxAdditionSecurityPeriod + ); + securityManager_.initializeRemovalSecurityPeriod( + Constants.defaultRemovalSecurityPeriod, + Constants.minRemovalSecurityPeriod, + Constants.maxRemovalSecurityPeriod + ); + securityManager_.initializeRecoveryPeriod( + Constants.defaultRecoveryPeriod, + Constants.minRecoveryPeriod, + Constants.maxRecoveryPeriod + ); + securityManager_.initializeLockPeriod( + Constants.defaultLockPeriod, + Constants.minLockPeriod, + Constants.maxLockPeriod + ); + securityManager_.initializeMigrationPeriod( + Constants.defaultMigrationPeriod, + Constants.minMigrationPeriod, + Constants.maxMigrationPeriod + ); + securityManager_.initializeApprovalValidationPeriod( + Constants.defaultApprovalValidationPeriod, + Constants.minApprovalValidationPeriod, + Constants.maxApprovalValidationPeriod + ); + vm.stopPrank(); + } + + function _setUpAccountFacet() + internal + returns (AccountFacet accountFacet_) + { + vm.startPrank(deployer); + accountFacet_ = new AccountFacet(); + vm.stopPrank(); + } + + function _setUpK1Facet() + internal + returns (Secp256k1VerificationFacet k1Facet_) + { + vm.startPrank(deployer); + k1Facet_ = new Secp256k1VerificationFacet(); + vm.stopPrank(); + } + + function _setUpR1Facet() + internal + returns (Secp256r1VerificationFacet r1Facet_) + { + vm.startPrank(deployer); + r1Facet_ = new Secp256r1VerificationFacet(); + vm.stopPrank(); + } + + function _setUpLockFacet( + address _securityManager + ) internal returns (LockFacet lockFacet_) { + vm.startPrank(deployer); + lockFacet_ = new LockFacet(_securityManager); + vm.stopPrank(); + } + + function _setUpGuardianFacet( + address _securityManager + ) internal returns (GuardianFacet guardianFacet_) { + vm.startPrank(deployer); + guardianFacet_ = new GuardianFacet(_securityManager); + vm.stopPrank(); + } + + function _setUpAccountRecoveryFacet( + address _securityManager + ) internal returns (AccountRecoveryFacet accountRecoveryFacet_) { + vm.startPrank(deployer); + accountRecoveryFacet_ = new AccountRecoveryFacet(_securityManager); + vm.stopPrank(); + } + + function _setUpDiamondCutFacet( + address _securityManager + ) internal returns (DiamondCutFacet diamondCutFacet_) { + vm.startPrank(deployer); + diamondCutFacet_ = new DiamondCutFacet(_securityManager); + vm.stopPrank(); + } + + function _setUpDiamondLoupeFacet() + internal + returns (DiamondLoupeFacet diamondLoupeFacet_) + { + vm.startPrank(deployer); + diamondLoupeFacet_ = new DiamondLoupeFacet(); + vm.stopPrank(); + } + + function _setUpRestrictionsFacet() + internal + returns (RestrictionsFacet restrictionsFacet_) + { + vm.startPrank(deployer); + restrictionsFacet_ = new RestrictionsFacet(); + vm.stopPrank(); + } + + function _setUpTokenReceiverFacet() + internal + returns (TokenReceiverFacet tokenReceiverFacet_) + { + vm.startPrank(deployer); + tokenReceiverFacet_ = new TokenReceiverFacet(); + vm.stopPrank(); + } + + function _setUpFacetRegistry( + address _accountFacet, + address _lockFacet, + address _guardianFacet, + address _k1Facet, + address _r1Facet, + address _restrictionsFacet, + address _accountRecoveryFacet + ) internal returns (FacetRegistry facetRegistry_) { + vm.startPrank(deployer); + facetRegistry_ = new FacetRegistry(deployer); + facetRegistry_.registerFacetFunctionSelectors( + _accountFacet, + Constants.accountFacetSelectors() + ); + facetRegistry_.registerFacetFunctionSelectors( + _lockFacet, + Constants.lockFacetSelectors() + ); + facetRegistry_.registerFacetFunctionSelectors( + _guardianFacet, + Constants.guardianFacetSelectors() + ); + facetRegistry_.registerFacetFunctionSelectors( + _k1Facet, + Constants.k1FacetSelectors() + ); + facetRegistry_.registerFacetFunctionSelectors( + _r1Facet, + Constants.r1FacetSelectors() + ); + facetRegistry_.registerFacetFunctionSelectors( + _restrictionsFacet, + Constants.restrictionsFacetSelectors() + ); + facetRegistry_.registerFacetFunctionSelectors( + _accountRecoveryFacet, + Constants.accountRecoveryFacetSelectors() + ); + vm.stopPrank(); + } + + function _setUpSigners( + uint256 _count, + uint256[] memory _privateKeys, + uint256 _nativeBalance + ) internal returns (address[] memory signers) { + signers = new address[](_count); + for (uint256 i; i < _count; i++) { + address user; + if (i < _privateKeys.length) { + user = vm.addr(_privateKeys[i]); + } else { + user = vm.addr(i); + } + signers[i] = user; + nonce[user] = 0; + vm.deal(user, _nativeBalance); + } + } + + function publicKeyToAddress( + bytes memory _publicKey + ) public pure returns (address walletAddress) { + require(_publicKey.length == 65, "_publicKey length is not 65 bytes"); + bytes32 addrHash = keccak256(slice(_publicKey, 1, 64)); // Remove 0x04 prefix, then hash + walletAddress = address(uint160(uint256(addrHash))); + } + + function bytesToAddress( + bytes memory _bytesAddress + ) public pure returns (address walletAddress) { + require(_bytesAddress.length == 20, "Invalid length for an address"); + + uint160 addr; + assembly { + addr := mload(add(_bytesAddress, 20)) + } + walletAddress = address(addr); + } + + function slice( + bytes memory _data, + uint _start, + uint _length + ) public pure returns (bytes memory part) { + part = new bytes(_length); + for (uint256 i; i < _length; i++) { + part[i] = _data[i + _start]; + } + } + + function prepareUserOp(address _barz, uint256 _nonce, bytes calldata _calldata) + public pure + returns (UserOperation memory userOp) + { + userOp = UserOperation({ + sender: _barz, + nonce: _nonce, + initCode: new bytes(0x0), + callData: _calldata, + callGasLimit: 2000000, + verificationGasLimit: 200000, + preVerificationGas: 21000, + maxFeePerGas: 1, + maxPriorityFeePerGas: 1e9, + paymasterAndData: new bytes(0x0), + signature: new bytes(0x0) + }); + } + + function signUserOperation(UserOperation[] memory _userOps, uint256[] memory _privateKeys) public view returns (UserOperation[] memory userOps) { + require(_userOps.length == _privateKeys.length, "Setup::signUserOperation UserOp - Key length mismatch"); + for (uint256 i; i< _userOps.length; i++) { + bytes32 hashedUserOp = this.hashUserOp(_userOps[i]); + bytes32 data = keccak256(abi.encode(hashedUserOp, address(entryPoint), getChainId())); + data = data.toEthSignedMessageHash(); + + (uint8 v, bytes32 r, bytes32 s) = vm.sign(_privateKeys[i], data); + _userOps[i].signature = abi.encodePacked(r, s, v); + } + userOps = _userOps; + } + + function getChainId() public view returns (uint256 id) { + assembly { + id := chainid() + } + } + + function hashUserOp(UserOperation calldata userOp) public pure returns (bytes32 hashedUserOp) { + hashedUserOp = UserOperationLib.hash(userOp); + } + + function populateAddressList(address _addr, uint256 _count) internal pure returns (address[] memory owners) { + owners = new address[](_count); + for(uint256 i; i < _count; i++) { + owners[i] = _addr; + } + } + + function encodeExecuteCall(address _destination, uint256 _value, bytes memory _calldata) public pure returns (bytes memory callData) { + callData = + abi.encodeWithSignature("execute(address,uint256,bytes)", _destination, _value, _calldata); + } + + function encodeExecuteBatchCall(address[] memory _destination, uint256[] memory _value, bytes[] memory _calldata) public pure returns (bytes memory callData) { + callData = + abi.encodeWithSignature("executeBatch(address[],uint256[],bytes[])", _destination, _value, _calldata); + } + + function encodeDiamondCutCall(IDiamondCut.FacetCut[] memory _cut, address _init, bytes memory _initData) public pure returns (bytes memory cutData) { + cutData = abi.encodeWithSignature( + "diamondCut((address,uint8,bytes4[])[],address,bytes)", _cut, _init, _initData + ); + } + + function cutFacet(address _facet, IDiamondCut.FacetCutAction _action, bytes4[] memory _selectors, address _barz, uint256 _ownerKey) public { + IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](1); + + cut[0] = IDiamondCut.FacetCut({ + facetAddress: _facet, + action: _action, + functionSelectors: _selectors + }); + + bytes memory cutData = abi.encodeWithSignature( + "diamondCut((address,uint8,bytes4[])[],address,bytes)", cut, address(0), new bytes(0x00) + ); + + bytes memory callData = encodeExecuteCall(_barz, 0, cutData); + UserOperation[] memory userOp = new UserOperation[](1); + uint256[] memory signingKey = new uint256[](1); + + userOp[0] = this.prepareUserOp(address(_barz), nonce[address(_barz)]++, callData); + signingKey[0] = _ownerKey; + + userOp = signUserOperation(userOp, signingKey); + + entryPoint.handleOps(userOp, payable(_barz)); + } + +} diff --git a/test/infrastructure/FacetRegistry.test.ts b/test/infrastructure/FacetRegistry.test.ts new file mode 100644 index 0000000..bd7c2ab --- /dev/null +++ b/test/infrastructure/FacetRegistry.test.ts @@ -0,0 +1,96 @@ +import { ethers } from 'hardhat' + +import { expect } from "chai" +import { AccountFacet, FacetRegistry, Secp256k1VerificationFacet } from '../../typechain-types' +import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers' + +const { + getSelectors +} = require('../utils/diamond.js') + +import { accountFacetFixture } from '../fixtures/AccountFacetFixture' +import { facetRegistryFixture } from '../fixtures/FacetRegistryFixture' +import { secp256k1VerificationFacetFixture } from '../fixtures/Secp256k1VerificationFacetFixture' +import { AddressZero } from '../utils/testutils' + +describe('Facet Registry', () => { + let facetRegistry: FacetRegistry + let accountFacet: AccountFacet + let k1Facet: Secp256k1VerificationFacet + let user: SignerWithAddress + let k1FacetSelectors: any + let accountFacetSelectors: any + let initializeSelector: any + let facetRegistryOwner: SignerWithAddress + + before(async () => { + [user, facetRegistryOwner] = await ethers.getSigners() + + k1Facet = await secp256k1VerificationFacetFixture() + k1FacetSelectors = getSelectors(k1Facet) + accountFacet = await accountFacetFixture() + accountFacetSelectors = getSelectors(accountFacet) + initializeSelector = accountFacet.interface.getSighash("initialize") + }) + beforeEach(async () => { + facetRegistry = await facetRegistryFixture(facetRegistryOwner.address) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(k1Facet.address, k1FacetSelectors) + }) + describe("# registerFacetFunctionSelectors", () => { + it("Should revert if not owner", async () => { + await expect(facetRegistry.connect(user).registerFacetFunctionSelectors(accountFacet.address, accountFacetSelectors)).to.be.revertedWith("Ownable: caller is not the owner") + }) + it("Should set facet information", async () => { + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(accountFacet.address, accountFacetSelectors) + expect(await facetRegistry.getFacetFunctionSelectors(accountFacet.address)).to.deep.equal(accountFacetSelectors) + + expect(await facetRegistry.getFacetFunctionSelectors(k1Facet.address)).to.deep.equal(k1FacetSelectors) + }) + it("Should emit registered event", async () => { + await expect(facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(accountFacet.address, accountFacetSelectors)).to.emit(facetRegistry, "FacetFunctionSelectorsRegistered").withArgs(accountFacet.address, accountFacetSelectors) + }) + }) + describe("# removeFacetFunctionSelectors", () => { + it("Should revert if not owner", async () => { + await expect(facetRegistry.connect(user).removeFacetFunctionSelectors(k1Facet.address, k1FacetSelectors)).to.be.revertedWith("Ownable: caller is not the owner") + }) + it("Should remove facet information", async () => { + await facetRegistry.connect(facetRegistryOwner).removeFacetFunctionSelectors(k1Facet.address, k1FacetSelectors) + expect(await facetRegistry.getFacetFunctionSelectors(k1Facet.address)).to.deep.equal([]) + }) + it("Should emit removed event", async () => { + await expect(facetRegistry.connect(facetRegistryOwner).removeFacetFunctionSelectors(k1Facet.address, k1FacetSelectors)).to.emit(facetRegistry, "FacetFunctionSelectorsRemoved").withArgs(k1Facet.address, k1FacetSelectors) + }) + }) + describe("# areFacetFunctionSelectorsRegistered", () => { + it("Should return false if facet & selectors are not registered", async () => { + expect(await facetRegistry.areFacetFunctionSelectorsRegistered(accountFacet.address, accountFacetSelectors)).to.be.false + }) + it("Should return true if facet & selectors are registered", async () => { + expect(await facetRegistry.areFacetFunctionSelectorsRegistered(k1Facet.address, k1FacetSelectors)).to.be.true + }) + it("Should return false if facet is zero address", async () => { + expect(await facetRegistry.areFacetFunctionSelectorsRegistered(AddressZero, k1FacetSelectors)).to.be.false + }) + it("Should return false if facet selector length is zero", async () => { + expect(await facetRegistry.areFacetFunctionSelectorsRegistered(AddressZero, [])).to.be.false + }) + }) + describe("# isFacetFunctionSelectorRegistered", () => { + it("Should return false if facet & selector is not registered", async () => { + expect(await facetRegistry.isFacetFunctionSelectorRegistered(accountFacet.address, initializeSelector)).to.be.false + }) + it("Should return true if facet & selector are registered", async () => { + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(accountFacet.address, [initializeSelector]) + expect(await facetRegistry.isFacetFunctionSelectorRegistered(accountFacet.address, initializeSelector)).to.be.true + }) + }) + describe("# getFacetFunctionSelectors", () => { + it("Should return emtpy list if facet is not registered", async () => { + expect(await facetRegistry.getFacetFunctionSelectors(accountFacet.address)).to.deep.equal([]) + }) + it("Should return list of selectors registered to facet", async () => { + expect(await facetRegistry.getFacetFunctionSelectors(k1Facet.address)).to.deep.equal(k1FacetSelectors) + }) + }) +}) \ No newline at end of file diff --git a/test/infrastructure/SecurityManager.test.ts b/test/infrastructure/SecurityManager.test.ts new file mode 100644 index 0000000..a35bb7f --- /dev/null +++ b/test/infrastructure/SecurityManager.test.ts @@ -0,0 +1,397 @@ +import { ethers } from 'hardhat' +import { Wallet } from 'ethers' + +import { AccountFacet, DiamondCutFacet, Barz, Secp256k1VerificationFacet, SecurityManager, GuardianFacet, FacetRegistry, DiamondLoupeFacet, TokenReceiverFacet, DefaultFallbackHandler } from '../../typechain-types' +import { guardianSecurityPeriod, minGuardianSecurityPeriod, maxGuardianSecurityPeriod, guardianSecurityWindow, minGuardianSecurityWindow, maxGuardianSecurityWindow, recoveryPeriod, minRecoveryPeriod, maxRecoveryPeriod, lockPeriod, minLockPeriod, maxLockPeriod, approvalValidationPeriod, minApprovalValidationPeriod, maxApprovalValidationPeriod, minMigrationPeriod, maxMigrationPeriod, migrationPeriod } from '../utils/helpers' +import { securityManagerFixture } from '../fixtures/SecurityManagerFixture' +import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers' +import { AddressZero, createAccountOwner, fund } from '../utils/testutils' + +const { + getSelectors +} = require('../utils/diamond.js') + +import { expect } from "chai" +import { diamondCutFacetFixture } from '../fixtures/DiamondCutFacetFixture' +import { accountFacetFixture } from '../fixtures/AccountFacetFixture' +import { secp256k1VerificationFacetFixture } from '../fixtures/Secp256k1VerificationFacetFixture' +import { barzFixture } from '../fixtures/BarzFixture' +import { getFacetBarz, setupSecurityManager } from '../utils/setup' +import { guardianFacetFixture } from '../fixtures/GuardianFacetFixture' +import { facetRegistryFixture } from '../fixtures/FacetRegistryFixture' +import { EntryPoint } from '../typechain-types/core' +import { callFromEntryPointOnK1, executeCallData } from '../utils/UserOp' +import { entryPointFixture } from '../fixtures/EntryPointFixture' +import { diamondLoupeFacetFixture } from '../fixtures/DiamondLoupeFacetFixture' +import { tokenReceiverFacetFixture } from '../fixtures/TokenReceiverFacetFixture' +import { defaultFallbackHandlerFixture } from '../fixtures/DefaultFallbackHandlerFixture' + +describe('Security Manager', () => { + let securityManager: SecurityManager + let diamondCutFacet: DiamondCutFacet + let facetRegistry: FacetRegistry + let defaultFallbackHandler: DefaultFallbackHandler + let accountFacet: AccountFacet + let accountBarz: AccountFacet + let k1Facet: Secp256k1VerificationFacet + let tokenReceiverFacet: TokenReceiverFacet + let entryPoint: EntryPoint + let diamondLoupeFacet: DiamondLoupeFacet + let user1: SignerWithAddress + let securityManagerOwner: SignerWithAddress + let facetRegistryOwner: SignerWithAddress + let owner: Wallet + let barz: Barz + let guardianFacet: GuardianFacet + + before(async () => { + [user1, securityManagerOwner, facetRegistryOwner] = await ethers.getSigners() + owner = createAccountOwner() + await fund(owner.address) + + accountFacet = await accountFacetFixture() + k1Facet = await secp256k1VerificationFacetFixture() + diamondLoupeFacet = await diamondLoupeFacetFixture() + }) + beforeEach(async () => { + securityManager = await setupSecurityManager(securityManagerOwner, minGuardianSecurityPeriod, maxGuardianSecurityPeriod, guardianSecurityPeriod, + minGuardianSecurityWindow, maxGuardianSecurityWindow, guardianSecurityWindow, + minRecoveryPeriod, maxRecoveryPeriod, recoveryPeriod, + minLockPeriod, maxLockPeriod, lockPeriod, + minApprovalValidationPeriod, maxApprovalValidationPeriod, approvalValidationPeriod, minMigrationPeriod, maxMigrationPeriod, migrationPeriod) + + diamondCutFacet = await diamondCutFacetFixture(securityManager) + entryPoint = await entryPointFixture() + guardianFacet = await guardianFacetFixture(securityManager) + tokenReceiverFacet = await tokenReceiverFacetFixture() + + facetRegistry = await facetRegistryFixture(facetRegistryOwner.address) + defaultFallbackHandler = await defaultFallbackHandlerFixture(diamondCutFacet, accountFacet, tokenReceiverFacet, diamondLoupeFacet) + + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(k1Facet.address, getSelectors(k1Facet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(guardianFacet.address, getSelectors(guardianFacet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(diamondCutFacet.address, getSelectors(diamondCutFacet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(accountFacet.address, getSelectors(accountFacet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(diamondLoupeFacet.address, getSelectors(diamondLoupeFacet)) + + barz = await barzFixture(accountFacet, k1Facet, entryPoint, facetRegistry, defaultFallbackHandler, owner.publicKey) + accountBarz = await getFacetBarz('AccountFacet', barz) + + await entryPoint.depositTo(barz.address, { + value: ethers.utils.parseEther('0.5'), + }) + }) + describe("# initialize", () => { + let securityManager: SecurityManager + + before(async () => { + securityManager = await securityManagerFixture(securityManagerOwner.address) + expect(await securityManager.owner()).to.equal(securityManagerOwner.address) + }) + + it("# initializeSecurityWindow", async () => { + await securityManager.connect(securityManagerOwner).initializeSecurityWindow(guardianSecurityWindow, minGuardianSecurityWindow, maxGuardianSecurityWindow) + expect(securityManager.connect(securityManagerOwner).initializeSecurityWindow(guardianSecurityWindow, minGuardianSecurityWindow, maxGuardianSecurityWindow)).to.be.revertedWithCustomError(securityManager, "SecurityManager__AlreadyIntialized") + expect(await securityManager.minSecurityWindow()).to.equal(minGuardianSecurityWindow) + expect(await securityManager.maxSecurityWindow()).to.equal(maxGuardianSecurityWindow) + expect(await securityManager.connect(AddressZero).securityWindowOf(AddressZero)).to.equal(guardianSecurityWindow) + }) + + it("# initializeAdditionSecurityPeriod", async () => { + await securityManager.connect(securityManagerOwner).initializeAdditionSecurityPeriod(guardianSecurityPeriod, minGuardianSecurityPeriod, maxGuardianSecurityPeriod) + expect(securityManager.connect(securityManagerOwner).initializeAdditionSecurityPeriod(guardianSecurityPeriod, minGuardianSecurityPeriod, maxGuardianSecurityPeriod)).to.be.revertedWithCustomError(securityManager, "SecurityManager__AlreadyIntialized") + expect(await securityManager.minAdditionSecurityPeriod()).to.equal(minGuardianSecurityPeriod) + expect(await securityManager.maxAdditionSecurityPeriod()).to.equal(maxGuardianSecurityPeriod) + expect(await securityManager.connect(AddressZero).additionSecurityPeriodOf(AddressZero)).to.equal(guardianSecurityPeriod) + }) + + it("# initializeRemovalSecurityPeriod", async () => { + await securityManager.connect(securityManagerOwner).initializeRemovalSecurityPeriod(guardianSecurityPeriod, minGuardianSecurityPeriod, maxGuardianSecurityPeriod) + expect(securityManager.connect(securityManagerOwner).initializeRemovalSecurityPeriod(guardianSecurityPeriod, minGuardianSecurityPeriod, maxGuardianSecurityPeriod)).to.be.revertedWithCustomError(securityManager, "SecurityManager__AlreadyIntialized") + expect(await securityManager.minRemovalSecurityPeriod()).to.equal(minGuardianSecurityPeriod) + expect(await securityManager.maxRemovalSecurityPeriod()).to.equal(maxGuardianSecurityPeriod) + expect(await securityManager.connect(AddressZero).removalSecurityPeriodOf(AddressZero)).to.equal(guardianSecurityPeriod) + }) + + it("# initializeRecoveryPeriod", async () => { + await securityManager.connect(securityManagerOwner).initializeRecoveryPeriod(recoveryPeriod, minRecoveryPeriod, maxRecoveryPeriod) + expect(securityManager.connect(securityManagerOwner).initializeRecoveryPeriod(recoveryPeriod, minRecoveryPeriod, maxRecoveryPeriod)).to.be.revertedWithCustomError(securityManager, "SecurityManager__AlreadyIntialized") + expect(await securityManager.minRecoveryPeriod()).to.equal(minRecoveryPeriod) + expect(await securityManager.maxRecoveryPeriod()).to.equal(maxRecoveryPeriod) + expect(await securityManager.connect(AddressZero).recoveryPeriodOf(AddressZero)).to.equal(recoveryPeriod) + }) + + it("# initializeLockPeriod", async () => { + await securityManager.connect(securityManagerOwner).initializeLockPeriod(lockPeriod, minLockPeriod, maxLockPeriod) + expect(securityManager.connect(securityManagerOwner).initializeLockPeriod(lockPeriod, minLockPeriod, maxLockPeriod)).to.be.revertedWithCustomError(securityManager, "SecurityManager__AlreadyIntialized") + expect(await securityManager.minLockPeriod()).to.equal(minLockPeriod) + expect(await securityManager.maxLockPeriod()).to.equal(maxLockPeriod) + expect(await securityManager.connect(AddressZero).lockPeriodOf(AddressZero)).to.equal(lockPeriod) + }) + + it("# initializeMigrationPeriod", async () => { + await securityManager.connect(securityManagerOwner).initializeMigrationPeriod(migrationPeriod, minMigrationPeriod, maxMigrationPeriod) + expect(securityManager.connect(securityManagerOwner).initializeMigrationPeriod(migrationPeriod, minMigrationPeriod, maxMigrationPeriod)).to.be.revertedWithCustomError(securityManager, "SecurityManager__AlreadyIntialized") + expect(await securityManager.minMigrationPeriod()).to.equal(minMigrationPeriod) + expect(await securityManager.maxMigrationPeriod()).to.equal(maxMigrationPeriod) + expect(await securityManager.connect(AddressZero).migrationPeriodOf(AddressZero)).to.equal(migrationPeriod) + }) + + it("# initializeApprovalValidationPeriod", async () => { + await securityManager.connect(securityManagerOwner).initializeApprovalValidationPeriod(approvalValidationPeriod, minApprovalValidationPeriod, maxApprovalValidationPeriod) + expect(securityManager.connect(securityManagerOwner).initializeApprovalValidationPeriod(approvalValidationPeriod, minApprovalValidationPeriod, maxApprovalValidationPeriod)).to.be.revertedWithCustomError(securityManager, "SecurityManager__AlreadyIntialized") + expect(await securityManager.minApprovalValidationPeriod()).to.equal(minApprovalValidationPeriod) + expect(await securityManager.maxApprovalValidationPeriod()).to.equal(maxApprovalValidationPeriod) + expect(await securityManager.connect(AddressZero).approvalValidationPeriodOf(AddressZero)).to.equal(approvalValidationPeriod) + }) + }) + describe('# setAdditionSecurityPeriod', async () => { + it("Should revert if not wallet(msg.sender)", async () => { + await expect(securityManager.connect(user1).setAdditionSecurityPeriod(owner.address, guardianSecurityPeriod)).to.be.revertedWithCustomError(securityManager, "SecurityManager__CallerNotWallet") + }) + it("Should revert if new security period is equal/higher than max security period", async () => { + await expect(securityManager.connect(owner).setAdditionSecurityPeriod(owner.address, maxGuardianSecurityPeriod, { gasPrice: 21000 })).to.be.revertedWithCustomError(securityManager, "SecurityManager__OutOfBoundary") + }) + it("Should revert if new security period is equal/lower than min security period", async () => { + await expect(securityManager.connect(owner).setAdditionSecurityPeriod(owner.address, minGuardianSecurityPeriod, { gasPrice: 21000 })).to.be.revertedWithCustomError(securityManager, "SecurityManager__OutOfBoundary") + }) + it("Should set security period", async () => { + const customSecurityPeriod = guardianSecurityPeriod + 100 + const setSecurityPeriodCall = securityManager.interface.encodeFunctionData("setAdditionSecurityPeriod", [accountBarz.address, customSecurityPeriod]) + const setSecurityPeriodCallData = executeCallData(securityManager.address, 0, setSecurityPeriodCall) + await callFromEntryPointOnK1(entryPoint, barz.address, owner, setSecurityPeriodCallData) + expect(await securityManager.connect(accountBarz.address).additionSecurityPeriodOf(accountBarz.address)).to.equal(customSecurityPeriod) + }) + }) + describe('# setRemovalSecurityPeriod', async () => { + it("Should revert if not wallet(msg.sender)", async () => { + await expect(securityManager.connect(user1).setRemovalSecurityPeriod(owner.address, guardianSecurityPeriod)).to.be.revertedWithCustomError(securityManager, "SecurityManager__CallerNotWallet") + }) + it("Should revert if new security period is equal/higher than max security period", async () => { + await expect(securityManager.connect(owner).setRemovalSecurityPeriod(owner.address, maxGuardianSecurityPeriod, { gasPrice: 21000 })).to.be.revertedWithCustomError(securityManager, "SecurityManager__OutOfBoundary") + }) + it("Should revert if new security period is equal/lower than min security period", async () => { + await expect(securityManager.connect(owner).setRemovalSecurityPeriod(owner.address, minGuardianSecurityPeriod, { gasPrice: 21000 })).to.be.revertedWithCustomError(securityManager, "SecurityManager__OutOfBoundary") + }) + it("Should set security period", async () => { + const customSecurityPeriod = guardianSecurityPeriod + 100 + const setSecurityPeriodCall = securityManager.interface.encodeFunctionData("setRemovalSecurityPeriod", [accountBarz.address, customSecurityPeriod]) + const setSecurityPeriodCallData = executeCallData(securityManager.address, 0, setSecurityPeriodCall) + await callFromEntryPointOnK1(entryPoint, barz.address, owner, setSecurityPeriodCallData) + expect(await securityManager.connect(accountBarz.address).removalSecurityPeriodOf(accountBarz.address)).to.equal(customSecurityPeriod) + }) + }) + describe('# setSecurityWindow', async () => { + before(async () => { + securityManager = await setupSecurityManager(securityManagerOwner, minGuardianSecurityPeriod, maxGuardianSecurityPeriod, guardianSecurityPeriod, + minGuardianSecurityWindow, maxGuardianSecurityWindow, guardianSecurityWindow, + minRecoveryPeriod, maxRecoveryPeriod, recoveryPeriod, + minLockPeriod, maxLockPeriod, lockPeriod, + minApprovalValidationPeriod, maxApprovalValidationPeriod, approvalValidationPeriod, minMigrationPeriod, maxMigrationPeriod, migrationPeriod) + }) + + it("Should revert if not wallet(msg.sender)", async () => { + await expect(securityManager.connect(user1).setSecurityWindow(owner.address, guardianSecurityWindow)).to.be.revertedWithCustomError(securityManager, "SecurityManager__CallerNotWallet") + }) + it("Should revert if new security window is equal/higher than max security window", async () => { + await expect(securityManager.connect(owner).setSecurityWindow(owner.address, maxGuardianSecurityWindow, { gasPrice: 21000 })).to.be.revertedWithCustomError(securityManager, "SecurityManager__OutOfBoundary") + }) + it("Should revert if new security window is equal/lower than min security window", async () => { + await expect(securityManager.connect(owner).setSecurityWindow(owner.address, minGuardianSecurityWindow, { gasPrice: 21000 })).to.be.revertedWithCustomError(securityManager, "SecurityManager__OutOfBoundary") + }) + it("Should set security window", async () => { + const customSecurityWindow = guardianSecurityWindow + 100 + const setSecurityWindowCall = securityManager.interface.encodeFunctionData("setSecurityWindow", [accountBarz.address, customSecurityWindow]) + const setSecurityWindowCallData = executeCallData(securityManager.address, 0, setSecurityWindowCall) + await callFromEntryPointOnK1(entryPoint, barz.address, owner, setSecurityWindowCallData) + expect(await securityManager.connect(accountBarz.address).securityWindowOf(accountBarz.address)).to.equal(customSecurityWindow) + }) + }) + describe('# setRecoveryPeriod', async () => { + before(async () => { + securityManager = await setupSecurityManager(securityManagerOwner, minGuardianSecurityPeriod, maxGuardianSecurityPeriod, guardianSecurityPeriod, + minGuardianSecurityWindow, maxGuardianSecurityWindow, guardianSecurityWindow, + minRecoveryPeriod, maxRecoveryPeriod, recoveryPeriod, + minLockPeriod, maxLockPeriod, lockPeriod, + minApprovalValidationPeriod, maxApprovalValidationPeriod, approvalValidationPeriod, minMigrationPeriod, maxMigrationPeriod, migrationPeriod) + }) + + it("Should revert if not wallet(msg.sender)", async () => { + await expect(securityManager.connect(user1).setRecoveryPeriod(owner.address, recoveryPeriod)).to.be.revertedWithCustomError(securityManager, "SecurityManager__CallerNotWallet") + }) + it("Should revert if new security window is equal/higher than max security window", async () => { + await expect(securityManager.connect(owner).setRecoveryPeriod(owner.address, maxRecoveryPeriod, { gasPrice: 21000 })).to.be.revertedWithCustomError(securityManager, "SecurityManager__OutOfBoundary") + }) + it("Should revert if new security window is equal/lower than min security window", async () => { + await expect(securityManager.connect(owner).setRecoveryPeriod(owner.address, minRecoveryPeriod, { gasPrice: 21000 })).to.be.revertedWithCustomError(securityManager, "SecurityManager__OutOfBoundary") + }) + it("Should set recovery period", async () => { + const customRecoveryPeriod = recoveryPeriod + 100 + const setRecoveryPeriodCall = securityManager.interface.encodeFunctionData("setRecoveryPeriod", [accountBarz.address, customRecoveryPeriod]) + const setRecoveryPeriodCallData = executeCallData(securityManager.address, 0, setRecoveryPeriodCall) + await callFromEntryPointOnK1(entryPoint, barz.address, owner, setRecoveryPeriodCallData) + expect(await securityManager.connect(accountBarz.address).recoveryPeriodOf(accountBarz.address)).to.equal(customRecoveryPeriod) + }) + }) + describe('# setLockPeriod', async () => { + before(async () => { + securityManager = await setupSecurityManager(securityManagerOwner, minGuardianSecurityPeriod, maxGuardianSecurityPeriod, guardianSecurityPeriod, + minGuardianSecurityWindow, maxGuardianSecurityWindow, guardianSecurityWindow, + minRecoveryPeriod, maxRecoveryPeriod, recoveryPeriod, + minLockPeriod, maxLockPeriod, lockPeriod, + minApprovalValidationPeriod, maxApprovalValidationPeriod, approvalValidationPeriod, minMigrationPeriod, maxMigrationPeriod, migrationPeriod) + }) + + it("Should revert if not wallet(msg.sender)", async () => { + await expect(securityManager.connect(user1).setLockPeriod(owner.address, lockPeriod)).to.be.revertedWithCustomError(securityManager, "SecurityManager__CallerNotWallet") + }) + it("Should revert if new lock period is higher than max lock period", async () => { + await expect(securityManager.connect(owner).setLockPeriod(owner.address, maxLockPeriod, { gasPrice: 21000 })).to.be.revertedWithCustomError(securityManager, "SecurityManager__OutOfBoundary") + }) + it("Should revert if new lock period is lower than min lock period", async () => { + await expect(securityManager.connect(owner).setLockPeriod(owner.address, minLockPeriod, { gasPrice: 21000 })).to.be.revertedWithCustomError(securityManager, "SecurityManager__OutOfBoundary") + }) + it("Should set lock period", async () => { + const customLockPeriod = lockPeriod + 100 + const setLockPeriodCall = securityManager.interface.encodeFunctionData("setLockPeriod", [accountBarz.address, customLockPeriod]) + const setLockPeriodCallData = executeCallData(securityManager.address, 0, setLockPeriodCall) + await callFromEntryPointOnK1(entryPoint, barz.address, owner, setLockPeriodCallData) + expect(await securityManager.connect(accountBarz.address).lockPeriodOf(accountBarz.address)).to.equal(customLockPeriod) + }) + }) + describe('# setApprovalValidationPeriod', async () => { + before(async () => { + securityManager = await setupSecurityManager(securityManagerOwner, minGuardianSecurityPeriod, maxGuardianSecurityPeriod, guardianSecurityPeriod, + minGuardianSecurityWindow, maxGuardianSecurityWindow, guardianSecurityWindow, + minRecoveryPeriod, maxRecoveryPeriod, recoveryPeriod, + minLockPeriod, maxLockPeriod, lockPeriod, + minApprovalValidationPeriod, maxApprovalValidationPeriod, approvalValidationPeriod, minMigrationPeriod, maxMigrationPeriod, migrationPeriod) + }) + + it("Should revert if not wallet(msg.sender)", async () => { + await expect(securityManager.connect(user1).setApprovalValidationPeriod(owner.address, approvalValidationPeriod)).to.be.revertedWithCustomError(securityManager, "SecurityManager__CallerNotWallet") + }) + it("Should revert if new approval validation period is equal/higher than max approval calidation period", async () => { + await expect(securityManager.connect(owner).setApprovalValidationPeriod(owner.address, maxApprovalValidationPeriod, { gasPrice: 21000 })).to.be.revertedWithCustomError(securityManager, "SecurityManager__OutOfBoundary") + }) + it("Should revert if new approval validation period is equal/lower than min approval validation period", async () => { + await expect(securityManager.connect(owner).setApprovalValidationPeriod(owner.address, minApprovalValidationPeriod, { gasPrice: 21000 })).to.be.revertedWithCustomError(securityManager, "SecurityManager__OutOfBoundary") + }) + it("Should set approval validation period", async () => { + const customApprovalValidationPeriod = approvalValidationPeriod + 100 + const setApprovalValidationPeriodCall = securityManager.interface.encodeFunctionData("setApprovalValidationPeriod", [accountBarz.address, customApprovalValidationPeriod]) + const setApprovalValidationPeriodCallData = executeCallData(securityManager.address, 0, setApprovalValidationPeriodCall) + await callFromEntryPointOnK1(entryPoint, barz.address, owner, setApprovalValidationPeriodCallData) + expect(await securityManager.connect(accountBarz.address).approvalValidationPeriodOf(accountBarz.address)).to.equal(customApprovalValidationPeriod) + }) + }) + describe('# additionSecurityPeriodOf', async () => { + before(async () => { + securityManager = await setupSecurityManager(securityManagerOwner, minGuardianSecurityPeriod, maxGuardianSecurityPeriod, guardianSecurityPeriod, + minGuardianSecurityWindow, maxGuardianSecurityWindow, guardianSecurityWindow, + minRecoveryPeriod, maxRecoveryPeriod, recoveryPeriod, + minLockPeriod, maxLockPeriod, lockPeriod, + minApprovalValidationPeriod, maxApprovalValidationPeriod, approvalValidationPeriod, minMigrationPeriod, maxMigrationPeriod, migrationPeriod) + }) + + it("Should return default security period if unset", async () => { + expect(await securityManager.connect(AddressZero).additionSecurityPeriodOf(AddressZero)).to.equal(guardianSecurityPeriod) + }) + it("Should return custom security period if set", async () => { + const customSecurityPeriod = guardianSecurityPeriod + 100 + await securityManager.connect(owner).setAdditionSecurityPeriod(owner.address, customSecurityPeriod, { gasPrice: 21000 }) + expect(await securityManager.connect(owner.address).additionSecurityPeriodOf(owner.address)).to.equal(customSecurityPeriod) + }) + }) + describe('# removalSecurityPeriodOf', async () => { + before(async () => { + securityManager = await setupSecurityManager(securityManagerOwner, minGuardianSecurityPeriod, maxGuardianSecurityPeriod, guardianSecurityPeriod, + minGuardianSecurityWindow, maxGuardianSecurityWindow, guardianSecurityWindow, + minRecoveryPeriod, maxRecoveryPeriod, recoveryPeriod, + minLockPeriod, maxLockPeriod, lockPeriod, + minApprovalValidationPeriod, maxApprovalValidationPeriod, approvalValidationPeriod, minMigrationPeriod, maxMigrationPeriod, migrationPeriod) + }) + + it("Should return default security period if unset", async () => { + expect(await securityManager.connect(AddressZero).removalSecurityPeriodOf(AddressZero)).to.equal(guardianSecurityPeriod) + }) + it("Should return custom security period if set", async () => { + const customSecurityPeriod = guardianSecurityPeriod + 100 + await securityManager.connect(owner).setRemovalSecurityPeriod(owner.address, customSecurityPeriod, { gasPrice: 21000 }) + expect(await securityManager.connect(owner.address).removalSecurityPeriodOf(owner.address)).to.equal(customSecurityPeriod) + }) + }) + describe('# securityWindowOf', async () => { + before(async () => { + securityManager = await setupSecurityManager(securityManagerOwner, minGuardianSecurityPeriod, maxGuardianSecurityPeriod, guardianSecurityPeriod, + minGuardianSecurityWindow, maxGuardianSecurityWindow, guardianSecurityWindow, + minRecoveryPeriod, maxRecoveryPeriod, recoveryPeriod, + minLockPeriod, maxLockPeriod, lockPeriod, + minApprovalValidationPeriod, maxApprovalValidationPeriod, approvalValidationPeriod, minMigrationPeriod, maxMigrationPeriod, migrationPeriod) + }) + + it("Should return default security window if unset", async () => { + expect(await securityManager.connect(AddressZero).securityWindowOf(AddressZero)).to.equal(guardianSecurityWindow) + }) + it("Should return custom security window if set", async () => { + const customSecurityWindow = guardianSecurityWindow + 100 + await securityManager.connect(owner).setSecurityWindow(owner.address, customSecurityWindow, { gasPrice: 21000 }) + expect(await securityManager.connect(owner.address).securityWindowOf(owner.address)).to.equal(customSecurityWindow) + }) + }) + describe('# recoveryPeriodOf', async () => { + before(async () => { + securityManager = await setupSecurityManager(securityManagerOwner, minGuardianSecurityPeriod, maxGuardianSecurityPeriod, guardianSecurityPeriod, + minGuardianSecurityWindow, maxGuardianSecurityWindow, guardianSecurityWindow, + minRecoveryPeriod, maxRecoveryPeriod, recoveryPeriod, + minLockPeriod, maxLockPeriod, lockPeriod, + minApprovalValidationPeriod, maxApprovalValidationPeriod, approvalValidationPeriod, minMigrationPeriod, maxMigrationPeriod, migrationPeriod) + }) + + it("Should return default recovery period if unset", async () => { + expect(await securityManager.connect(AddressZero).recoveryPeriodOf(AddressZero)).to.equal(recoveryPeriod) + }) + it("Should return custom recovery period if set", async () => { + const customRecoveryPeriod = recoveryPeriod + 100 + await securityManager.connect(owner).setRecoveryPeriod(owner.address, customRecoveryPeriod, { gasPrice: 21000 }) + expect(await securityManager.connect(owner.address).recoveryPeriodOf(owner.address)).to.equal(customRecoveryPeriod) + }) + }) + describe('# lockPeriodOf', async () => { + before(async () => { + securityManager = await setupSecurityManager(securityManagerOwner, minGuardianSecurityPeriod, maxGuardianSecurityPeriod, guardianSecurityPeriod, + minGuardianSecurityWindow, maxGuardianSecurityWindow, guardianSecurityWindow, + minRecoveryPeriod, maxRecoveryPeriod, recoveryPeriod, + minLockPeriod, maxLockPeriod, lockPeriod, + minApprovalValidationPeriod, maxApprovalValidationPeriod, approvalValidationPeriod, minMigrationPeriod, maxMigrationPeriod, migrationPeriod) + }) + + it("Should return default lock period if unset", async () => { + expect(await securityManager.connect(AddressZero).lockPeriodOf(AddressZero)).to.equal(lockPeriod) + }) + it("Should return custom lock period if set", async () => { + const customLockPeriod = lockPeriod + 100 + await securityManager.connect(owner).setLockPeriod(owner.address, customLockPeriod, { gasPrice: 21000 }) + expect(await securityManager.connect(owner.address).lockPeriodOf(owner.address)).to.equal(customLockPeriod) + }) + }) + describe('# approvalValidationPeriodOf', async () => { + before(async () => { + securityManager = await setupSecurityManager(securityManagerOwner, minGuardianSecurityPeriod, maxGuardianSecurityPeriod, guardianSecurityPeriod, + minGuardianSecurityWindow, maxGuardianSecurityWindow, guardianSecurityWindow, + minRecoveryPeriod, maxRecoveryPeriod, recoveryPeriod, + minLockPeriod, maxLockPeriod, lockPeriod, + minApprovalValidationPeriod, maxApprovalValidationPeriod, approvalValidationPeriod, minMigrationPeriod, maxMigrationPeriod, migrationPeriod) + }) + + it("Should return default approval validation period if unset", async () => { + expect(await securityManager.connect(AddressZero).approvalValidationPeriodOf(AddressZero)).to.equal(approvalValidationPeriod) + }) + it("Should return custom approval validation period if set", async () => { + const customApprovalValidationPeriod = approvalValidationPeriod + 10 + + await securityManager.connect(owner).setApprovalValidationPeriod(owner.address, customApprovalValidationPeriod, { gasPrice: 21000 }) + expect(await securityManager.connect(owner.address).approvalValidationPeriodOf(owner.address)).to.equal(customApprovalValidationPeriod) + }) + }) +}) \ No newline at end of file diff --git a/test/restrictions/WhitelistRestriction.test.ts b/test/restrictions/WhitelistRestriction.test.ts new file mode 100644 index 0000000..dd23c64 --- /dev/null +++ b/test/restrictions/WhitelistRestriction.test.ts @@ -0,0 +1,277 @@ +import { ethers } from 'hardhat' +import { Contract, Wallet } from 'ethers' + +import { AccountFacet, Barz, DefaultFallbackHandler, DiamondCutFacet, DiamondLoupeFacet, FacetRegistry, GuardianFacet, Secp256k1VerificationFacet, SecurityManager, TokenReceiverFacet, WhitelistRestriction, WhitelistStorage } from '../../typechain-types' +import { guardianSecurityPeriod, minGuardianSecurityPeriod, maxGuardianSecurityPeriod, guardianSecurityWindow, minGuardianSecurityWindow, maxGuardianSecurityWindow, recoveryPeriod, minRecoveryPeriod, maxRecoveryPeriod, lockPeriod, minLockPeriod, maxLockPeriod, approvalValidationPeriod, minApprovalValidationPeriod, maxApprovalValidationPeriod, minMigrationPeriod, maxMigrationPeriod, migrationPeriod } from '../utils/helpers' +import { whitelistRestrictionFixture } from '../fixtures/WhitelistRestrictionFixture' +import { AddressZero, createAccountOwner, fund } from '../utils/testutils' +import { expect } from 'chai' +import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers' +import { IERC1155__factory, IERC20__factory, IERC721__factory } from '../../typechain-types/factories/contracts/interfaces/ERC/Tokens' +import { whitelistStorageFixture } from '../fixtures/WhitelistStorageFixture' + +const { + getSelectors +} = require('../utils/diamond.js') + +import { diamondCutFacetFixture } from '../fixtures/DiamondCutFacetFixture' +import { accountFacetFixture } from '../fixtures/AccountFacetFixture' +import { secp256k1VerificationFacetFixture } from '../fixtures/Secp256k1VerificationFacetFixture' +import { barzFixture } from '../fixtures/BarzFixture' +import { setupSecurityManager } from '../utils/setup' +import { facetRegistryFixture } from '../fixtures/FacetRegistryFixture' +import { diamondLoupeFacetFixture } from '../fixtures/DiamondLoupeFacetFixture' +import { guardianFacetFixture } from '../fixtures/GuardianFacetFixture' +import { EntryPoint } from "../../typechain-types/core" +import { callFromEntryPointOnK1, executeCallData } from "../utils/UserOp" +import { entryPointFixture } from "../fixtures/EntryPointFixture" +import { tokenReceiverFacetFixture } from '../fixtures/TokenReceiverFacetFixture' +import { defaultFallbackHandlerFixture } from '../fixtures/DefaultFallbackHandlerFixture' + +describe('Whitelist Restriction', () => { + let wallet: SignerWithAddress + let whitelistRestriction: WhitelistRestriction + let whitelistStorage: WhitelistStorage + + let erc20: Contract + let erc721: Contract + let erc1155: Contract + + let tokenAddress: string + let spenderAddress: string + + let defaultFallbackHandler: DefaultFallbackHandler + let diamondCutFacet: DiamondCutFacet + let securityManager: SecurityManager + let facetRegistry: FacetRegistry + let accountFacet: AccountFacet + let k1Facet: Secp256k1VerificationFacet + let diamondLoupeFacet: DiamondLoupeFacet + let guardianFacet: GuardianFacet + let tokenReceiverFacet: TokenReceiverFacet + let entryPoint: EntryPoint + let securityManagerOwner: SignerWithAddress + let facetRegistryOwner: SignerWithAddress + let owner: Wallet + let barz: Barz + let nonce = 0 + + before(async () => { + [wallet, securityManagerOwner, facetRegistryOwner] = await ethers.getSigners() + + whitelistStorage = await whitelistStorageFixture() + whitelistRestriction = await whitelistRestrictionFixture(whitelistStorage) + tokenAddress = ethers.Wallet.createRandom().address + spenderAddress = ethers.Wallet.createRandom().address + erc20 = new ethers.Contract(tokenAddress, IERC20__factory.abi, ethers.provider); + erc721 = new ethers.Contract(tokenAddress, IERC721__factory.abi, ethers.provider); + erc1155 = new ethers.Contract(tokenAddress, IERC1155__factory.abi, ethers.provider); + + owner = createAccountOwner() + await fund(owner.address) + + securityManager = await setupSecurityManager(securityManagerOwner, minGuardianSecurityPeriod, maxGuardianSecurityPeriod, guardianSecurityPeriod, + minGuardianSecurityWindow, maxGuardianSecurityWindow, guardianSecurityWindow, + minRecoveryPeriod, maxRecoveryPeriod, recoveryPeriod, + minLockPeriod, maxLockPeriod, lockPeriod, + minApprovalValidationPeriod, maxApprovalValidationPeriod, approvalValidationPeriod, minMigrationPeriod, maxMigrationPeriod, migrationPeriod) + facetRegistry = await facetRegistryFixture(facetRegistryOwner.address) + accountFacet = await accountFacetFixture() + k1Facet = await secp256k1VerificationFacetFixture() + guardianFacet = await guardianFacetFixture(securityManager) + diamondCutFacet = await diamondCutFacetFixture(securityManager) + diamondLoupeFacet = await diamondLoupeFacetFixture() + tokenReceiverFacet = await tokenReceiverFacetFixture() + entryPoint = await entryPointFixture() + defaultFallbackHandler = await defaultFallbackHandlerFixture(diamondCutFacet, accountFacet, tokenReceiverFacet, diamondLoupeFacet) + + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(accountFacet.address, getSelectors(accountFacet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(diamondCutFacet.address, getSelectors(diamondCutFacet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(diamondLoupeFacet.address, getSelectors(diamondLoupeFacet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(k1Facet.address, getSelectors(k1Facet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(guardianFacet.address, getSelectors(guardianFacet)) + + barz = await barzFixture(accountFacet, k1Facet, entryPoint, facetRegistry, defaultFallbackHandler, owner.publicKey) + await entryPoint.depositTo(barz.address, { + value: ethers.utils.parseEther('0.5'), + }) + }) + + describe("# constructor", () => { + it("Should deploy Whitelist Restriction", async () => { + const whitelistRestriction = await whitelistRestrictionFixture(await whitelistStorageFixture()) + expect(whitelistRestriction.address).to.not.equal(AddressZero) + }) + }) + + describe("# check", () => { + it("Should reject any address for an empty whitelist", async () => { + expect(await whitelistRestriction.check(wallet.address, spenderAddress, 1, "0x00")).to.equal(false) + }) + + it("Should accept own address", async () => { + expect(await whitelistRestriction.connect(wallet).check(wallet.address, wallet.address, 0, "0x00")).to.equal(true) + }) + + it("Should accept whitelisted address", async () => { + const whitelistCall = whitelistStorage.interface.encodeFunctionData('whitelistAddress', [barz.address, spenderAddress]) + let callData = executeCallData(whitelistStorage.address, 0, whitelistCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, callData)).to.emit(whitelistStorage, "Added").withArgs(spenderAddress) + expect(await whitelistRestriction.check(barz.address, spenderAddress, 0, "0x00")).to.equal(true) + const blackListCall = whitelistStorage.interface.encodeFunctionData('blacklistAddress', [barz.address, spenderAddress]) + callData = executeCallData(whitelistStorage.address, 0, blackListCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, callData)).to.emit(whitelistStorage, "Removed").withArgs(spenderAddress) + }) + + it("Should accept transfers to whitelisted address", async () => { + const whitelistCall = whitelistStorage.interface.encodeFunctionData('whitelistAddress', [barz.address, spenderAddress]) + let callData = executeCallData(whitelistStorage.address, 0, whitelistCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, callData)).to.emit(whitelistStorage, "Added").withArgs(spenderAddress) + // Regular transfer + expect(await whitelistRestriction.check(barz.address, spenderAddress, 0, "0x00")).to.equal(true) + // Regular transfer with a random payload + expect(await whitelistRestriction.check(barz.address, spenderAddress, 0, ethers.utils.randomBytes(32))).to.equal(true) + // ERC20 transfer + const erc20Transfer = erc20.interface.encodeFunctionData("transfer", [spenderAddress, 1]); + expect(await whitelistRestriction.check(barz.address, tokenAddress, 0, erc20Transfer)).to.equal(true) + // ERC20 approve + const erc20Approve = erc20.interface.encodeFunctionData("approve", [spenderAddress, 1]); + expect(await whitelistRestriction.check(barz.address, tokenAddress, 0, erc20Approve)).to.equal(true) + // ERC20 increaseAllowance + const erc20IncreaseAllowance = erc20.interface.encodeFunctionData("increaseAllowance", [spenderAddress, 1]); + expect(await whitelistRestriction.check(barz.address, tokenAddress, 0, erc20IncreaseAllowance)).to.equal(true) + // ERC20 decreaseAllowance + const erc20DecreaseAllowance = erc20.interface.encodeFunctionData("decreaseAllowance", [spenderAddress, 1]); + expect(await whitelistRestriction.check(barz.address, tokenAddress, 0, erc20DecreaseAllowance)).to.equal(true) + // ERC721 setApprovalForAll + const erc721SetApprovalForAll = erc721.interface.encodeFunctionData("setApprovalForAll", [spenderAddress, true]); + expect(await whitelistRestriction.check(barz.address, tokenAddress, 0, erc721SetApprovalForAll)).to.equal(true) + // ERC721 transferFrom + const erc721TransferFrom = erc721.interface.encodeFunctionData("transferFrom", [wallet.address, spenderAddress, 1]); + expect(await whitelistRestriction.check(barz.address, tokenAddress, 0, erc721TransferFrom)).to.equal(true) + // ERC721 safeTransferFrom + const erc721SafeTransferFrom = erc721.interface.encodeFunctionData("safeTransferFrom(address,address,uint256)", [wallet.address, spenderAddress, 1]); + expect(await whitelistRestriction.check(barz.address, tokenAddress, 0, erc721SafeTransferFrom)).to.equal(true) + // ERC721 safeTransferFrom (bytes) + const erc721SafeTransferFromBytes = erc721.interface.encodeFunctionData("safeTransferFrom(address,address,uint256,bytes)", [wallet.address, spenderAddress, 1, "0x00"]); + expect(await whitelistRestriction.check(barz.address, tokenAddress, 0, erc721SafeTransferFromBytes)).to.equal(true) + // ERC1155 safeTransferFrom + const erc1155SafeTransferFrom = erc1155.interface.encodeFunctionData("safeTransferFrom", [wallet.address, spenderAddress, 1, 1, "0x00"]); + expect(await whitelistRestriction.check(barz.address, tokenAddress, 0, erc1155SafeTransferFrom)).to.equal(true) + // ERC1155 safeBatchTransferFrom + const erc1155SafeBatchTransferFrom = erc1155.interface.encodeFunctionData("safeBatchTransferFrom", [wallet.address, spenderAddress, [1], [2], "0x00"]) + expect(await whitelistRestriction.check(barz.address, tokenAddress, 0, erc1155SafeBatchTransferFrom)).to.equal(true) + + const blackListCall = whitelistStorage.interface.encodeFunctionData('blacklistAddress', [barz.address, spenderAddress]) + callData = executeCallData(whitelistStorage.address, 0, blackListCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, callData)).to.emit(whitelistStorage, "Removed").withArgs(spenderAddress) + }) + + it("Should reject transfers to non-whitelisted address", async () => { + // Regular transfer + expect(await whitelistRestriction.check(barz.address, spenderAddress, 0, "0x00")).to.equal(false) + // Regular transfer with a random payload + expect(await whitelistRestriction.check(barz.address, spenderAddress, 0, ethers.utils.randomBytes(32))).to.equal(false) + // ERC20 transfer + const erc20Transfer = erc20.interface.encodeFunctionData("transfer", [spenderAddress, 1]); + expect(await whitelistRestriction.check(barz.address, tokenAddress, 0, erc20Transfer)).to.equal(false) + // ERC20 approve + const erc20Approve = erc20.interface.encodeFunctionData("approve", [spenderAddress, 1]); + expect(await whitelistRestriction.check(barz.address, tokenAddress, 0, erc20Approve)).to.equal(false) + // ERC20 increaseAllowance + const erc20IncreaseAllowance = erc20.interface.encodeFunctionData("increaseAllowance", [spenderAddress, 1]); + expect(await whitelistRestriction.check(barz.address, tokenAddress, 0, erc20IncreaseAllowance)).to.equal(false) + // ERC20 decreaseAllowance + const erc20DecreaseAllowance = erc20.interface.encodeFunctionData("decreaseAllowance", [spenderAddress, 1]); + expect(await whitelistRestriction.check(barz.address, tokenAddress, 0, erc20DecreaseAllowance)).to.equal(false) + // ERC721 setApprovalForAll + const erc721SetApprovalForAll = erc721.interface.encodeFunctionData("setApprovalForAll", [spenderAddress, true]); + expect(await whitelistRestriction.check(barz.address, tokenAddress, 0, erc721SetApprovalForAll)).to.equal(false) + // ERC721 transferFrom + const erc721TransferFrom = erc721.interface.encodeFunctionData("transferFrom", [barz.address, spenderAddress, 1]); + expect(await whitelistRestriction.check(barz.address, tokenAddress, 0, erc721TransferFrom)).to.equal(false) + // ERC721 safeTransferFrom + const erc721SafeTransferFrom = erc721.interface.encodeFunctionData("safeTransferFrom(address,address,uint256)", [barz.address, spenderAddress, 1]); + expect(await whitelistRestriction.check(barz.address, tokenAddress, 0, erc721SafeTransferFrom)).to.equal(false) + // ERC721 safeTransferFrom (bytes) + const erc721SafeTransferFromBytes = erc721.interface.encodeFunctionData("safeTransferFrom(address,address,uint256,bytes)", [barz.address, spenderAddress, 1, "0x00"]); + expect(await whitelistRestriction.check(barz.address, tokenAddress, 0, erc721SafeTransferFromBytes)).to.equal(false) + // ERC1155 safeTransferFrom + const erc1155SafeTransferFrom = erc1155.interface.encodeFunctionData("safeTransferFrom", [barz.address, spenderAddress, 1, 1, "0x00"]); + expect(await whitelistRestriction.check(barz.address, tokenAddress, 0, erc1155SafeTransferFrom)).to.equal(false) + }) + }) + + describe("# _recoverSpender", () => { + it("Should recover the spender for a regular transfer", async () => { + const spender = await whitelistRestriction.recoverSpender(spenderAddress, "0x00"); + expect(spender).to.be.equal(spenderAddress) + }) + + it("Should recover the spender for a regular transfer with custom payload", async () => { + const spender = await whitelistRestriction.recoverSpender(spenderAddress, ethers.utils.randomBytes(32)); + expect(spender).to.be.equal(spenderAddress) + }) + + it("Should recover the spender for ERC20 transfer", async () => { + const call = erc20.interface.encodeFunctionData("transfer", [spenderAddress, 1]); + const spender = await whitelistRestriction.recoverSpender(tokenAddress, call); + expect(spender).to.be.equal(spenderAddress) + }) + + it("Should recover the spender for ERC20 approve", async () => { + const call = erc20.interface.encodeFunctionData("approve", [spenderAddress, 1]); + const spender = await whitelistRestriction.recoverSpender(tokenAddress, call); + expect(spender).to.be.equal(spenderAddress) + }) + + it("Should recover the spender for ERC20 increaseAllowance", async () => { + const call = erc20.interface.encodeFunctionData("increaseAllowance", [spenderAddress, 1]); + const spender = await whitelistRestriction.recoverSpender(tokenAddress, call); + expect(spender).to.be.equal(spenderAddress) + }) + + it("Should recover the spender for ERC20 decreaseAllowance", async () => { + const call = erc20.interface.encodeFunctionData("decreaseAllowance", [spenderAddress, 1]); + const spender = await whitelistRestriction.recoverSpender(tokenAddress, call); + expect(spender).to.be.equal(spenderAddress) + }) + + it("Should recover the spender for ERC721 setApprovalForAll", async () => { + const call = erc721.interface.encodeFunctionData("setApprovalForAll", [spenderAddress, true]); + const spender = await whitelistRestriction.recoverSpender(tokenAddress, call); + expect(spender).to.be.equal(spenderAddress) + }) + + it("Should recover the spender for ERC721 transferFrom", async () => { + const call = erc721.interface.encodeFunctionData("transferFrom", [wallet.address, spenderAddress, 1]); + const spender = await whitelistRestriction.recoverSpender(tokenAddress, call); + expect(spender).to.be.equal(spenderAddress) + }) + + it("Should recover the spender for ERC721 safeTransferFrom", async () => { + const call = erc721.interface.encodeFunctionData("safeTransferFrom(address,address,uint256)", [wallet.address, spenderAddress, 1]); + const spender = await whitelistRestriction.recoverSpender(tokenAddress, call); + expect(spender).to.be.equal(spenderAddress) + }) + + it("Should recover the spender for ERC721 safeTransferFrom (bytes)", async () => { + const call = erc721.interface.encodeFunctionData("safeTransferFrom(address,address,uint256,bytes)", [wallet.address, spenderAddress, 1, "0x00"]); + const spender = await whitelistRestriction.recoverSpender(tokenAddress, call); + expect(spender).to.be.equal(spenderAddress) + }) + + it("Should recover the spender for ERC1155 safeTransferFrom", async () => { + const call = erc1155.interface.encodeFunctionData("safeTransferFrom", [wallet.address, spenderAddress, 1, 1, "0x00"]); + const spender = await whitelistRestriction.recoverSpender(tokenAddress, call); + expect(spender).to.be.equal(spenderAddress) + }) + + it("Should recover the spender for ERC1155 safeBatchTransferFrom", async () => { + const call = erc1155.interface.encodeFunctionData("safeBatchTransferFrom", [wallet.address, spenderAddress, [1], [1], "0x00"]); + const spender = await whitelistRestriction.recoverSpender(tokenAddress, call); + expect(spender).to.be.equal(spenderAddress) + }) + + }) +}) \ No newline at end of file diff --git a/test/restrictions/WhitelistStorage.test.ts b/test/restrictions/WhitelistStorage.test.ts new file mode 100644 index 0000000..3e89329 --- /dev/null +++ b/test/restrictions/WhitelistStorage.test.ts @@ -0,0 +1,207 @@ +import { ethers } from 'hardhat' +import { Wallet } from 'ethers' + +import { AccountFacet, Barz, DefaultFallbackHandler, DiamondCutFacet, DiamondLoupeFacet, FacetRegistry, GuardianFacet, Secp256k1VerificationFacet, SecurityManager, TokenReceiverFacet } from '../../typechain-types' +import { guardianSecurityPeriod, minGuardianSecurityPeriod, maxGuardianSecurityPeriod, guardianSecurityWindow, minGuardianSecurityWindow, maxGuardianSecurityWindow, recoveryPeriod, minRecoveryPeriod, maxRecoveryPeriod, lockPeriod, minLockPeriod, maxLockPeriod, approvalValidationPeriod, minApprovalValidationPeriod, maxApprovalValidationPeriod, minMigrationPeriod, maxMigrationPeriod, migrationPeriod, increaseBlockTime } from '../utils/helpers' +import { createAccountOwner, fund } from '../utils/testutils' +import { expect } from 'chai' +import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers' +import { whitelistStorageFixture } from '../fixtures/WhitelistStorageFixture' + +const { + getSelectors +} = require('../utils/diamond.js') + +import { diamondCutFacetFixture } from '../fixtures/DiamondCutFacetFixture' +import { accountFacetFixture } from '../fixtures/AccountFacetFixture' +import { secp256k1VerificationFacetFixture } from '../fixtures/Secp256k1VerificationFacetFixture' +import { barzFixture } from '../fixtures/BarzFixture' +import { addFacetSelectors, addFacetSelectorsViaEntryPointOnK1, getFacetBarz, setupSecurityManager } from '../utils/setup' +import { facetRegistryFixture } from '../fixtures/FacetRegistryFixture' +import { diamondLoupeFacetFixture } from '../fixtures/DiamondLoupeFacetFixture' +import { guardianFacetFixture } from '../fixtures/GuardianFacetFixture' +import { EntryPoint } from "../../typechain-types/core" +import { callFromEntryPointOnK1, executeCallData } from "../utils/UserOp" +import { entryPointFixture } from "../fixtures/EntryPointFixture" +import { tokenReceiverFacetFixture } from '../fixtures/TokenReceiverFacetFixture' +import { defaultFallbackHandlerFixture } from '../fixtures/DefaultFallbackHandlerFixture' + +describe('Whitelist Storage', () => { + let whitelistStorage: any + + let spenderAddress: string + + let defaultFallbackHandler: DefaultFallbackHandler + let diamondCutFacet: DiamondCutFacet + let securityManager: SecurityManager + let facetRegistry: FacetRegistry + let accountFacet: AccountFacet + let tokenReceiverFacet: TokenReceiverFacet + let k1Facet: Secp256k1VerificationFacet + let diamondLoupeFacet: DiamondLoupeFacet + let guardianFacet: GuardianFacet + let guardianBarz: GuardianFacet + let entryPoint: EntryPoint + let mockEntryPoint: SignerWithAddress + let mockAccountBarz: AccountFacet + let mockGuardianBarz: GuardianFacet + let guardian1: SignerWithAddress + let securityManagerOwner: SignerWithAddress + let facetRegistryOwner: SignerWithAddress + let owner: Wallet + let barz: Barz + let mockBarz: Barz + let nonce = 0 + + beforeEach(async () => { + [guardian1, securityManagerOwner, facetRegistryOwner, mockEntryPoint] = await ethers.getSigners() + nonce = 0 + + whitelistStorage = await whitelistStorageFixture() + spenderAddress = ethers.Wallet.createRandom().address + + owner = createAccountOwner() + await fund(owner.address) + + securityManager = await setupSecurityManager(securityManagerOwner, minGuardianSecurityPeriod, maxGuardianSecurityPeriod, guardianSecurityPeriod, + minGuardianSecurityWindow, maxGuardianSecurityWindow, guardianSecurityWindow, + minRecoveryPeriod, maxRecoveryPeriod, recoveryPeriod, + minLockPeriod, maxLockPeriod, lockPeriod, + minApprovalValidationPeriod, maxApprovalValidationPeriod, approvalValidationPeriod, minMigrationPeriod, maxMigrationPeriod, migrationPeriod) + facetRegistry = await facetRegistryFixture(facetRegistryOwner.address) + accountFacet = await accountFacetFixture() + k1Facet = await secp256k1VerificationFacetFixture() + guardianFacet = await guardianFacetFixture(securityManager) + diamondCutFacet = await diamondCutFacetFixture(securityManager) + diamondLoupeFacet = await diamondLoupeFacetFixture() + tokenReceiverFacet = await tokenReceiverFacetFixture() + entryPoint = await entryPointFixture() + defaultFallbackHandler = await defaultFallbackHandlerFixture(diamondCutFacet, accountFacet, tokenReceiverFacet, diamondLoupeFacet) + + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(accountFacet.address, getSelectors(accountFacet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(diamondCutFacet.address, getSelectors(diamondCutFacet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(diamondLoupeFacet.address, getSelectors(diamondLoupeFacet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(k1Facet.address, getSelectors(k1Facet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(guardianFacet.address, getSelectors(guardianFacet)) + + barz = await barzFixture(accountFacet, k1Facet, entryPoint, facetRegistry, defaultFallbackHandler, owner.publicKey) + guardianBarz = await getFacetBarz('GuardianFacet', barz) + + mockBarz = await barzFixture(accountFacet, k1Facet, mockEntryPoint, facetRegistry, defaultFallbackHandler, owner.publicKey) + mockAccountBarz = await getFacetBarz('AccountFacet', mockBarz) + mockGuardianBarz = await getFacetBarz('GuardianFacet', mockBarz) + await addFacetSelectors(mockBarz, guardianFacet, guardianFacet, mockEntryPoint) + + await entryPoint.depositTo(barz.address, { + value: ethers.utils.parseEther('0.5'), + }) + + const guardianCutTx = await addFacetSelectorsViaEntryPointOnK1(barz, owner, guardianFacet, guardianFacet, entryPoint, nonce++) + const guardianCutReceipt = await guardianCutTx.wait() + expect(guardianCutReceipt.status).to.equal(1) + }) + const addGuardian = async (newGuardian: SignerWithAddress, nonce: number): Promise => { + const addGuardianCall = guardianFacet.interface.encodeFunctionData("addGuardian", [newGuardian.address]) + const callData = executeCallData(barz.address, 0, addGuardianCall) + await callFromEntryPointOnK1(entryPoint, barz.address, owner, callData, nonce++) + + await increaseBlockTime(guardianSecurityPeriod) + await expect(guardianBarz.confirmGuardianAddition(newGuardian.address)).to.emit(guardianBarz, "GuardianAdded") + expect(await guardianBarz.isGuardian(newGuardian.address)).to.be.true + return nonce + } + const addGuardianMock = async (_newGuardian: any, _guardianBarz: any, _accountBarz: any) => { + const addGuardianCall = guardianFacet.interface.encodeFunctionData("addGuardian", [_newGuardian.address]) + await _accountBarz.connect(mockEntryPoint).execute(_accountBarz.address, 0, addGuardianCall) + + await increaseBlockTime(guardianSecurityPeriod) + await expect(_guardianBarz.confirmGuardianAddition(_newGuardian.address)).to.emit(_guardianBarz, "GuardianAdded") + } + + describe("# whitelistAddress", () => { + it("Should whitelist with owner if no guardian", async () => { + const whitelistCall = whitelistStorage.interface.encodeFunctionData('whitelistAddress', [barz.address, spenderAddress]) + const callData = executeCallData(whitelistStorage.address, 0, whitelistCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, callData, nonce++)).to.emit(whitelistStorage, "Added").withArgs(spenderAddress) + + expect(await whitelistStorage.isWhitelisted(barz.address, spenderAddress)).to.be.true + }) + it('Should revert if owner whitelists address when guardian exists', async () => { + await addGuardianMock(guardian1, mockGuardianBarz, mockAccountBarz) + const whitelistCall = whitelistStorage.interface.encodeFunctionData('whitelistAddress', [mockBarz.address, spenderAddress]) + + await expect(mockAccountBarz.connect(mockEntryPoint).execute(whitelistStorage.address, 0, whitelistCall)).to.be.revertedWithCustomError(whitelistStorage, "RemoteStorage__CallerNotGuardian") + }) + it('Should revert if caller is not guardian or owner', async () => { + const whitelistCall = whitelistStorage.interface.encodeFunctionData('whitelistAddress', [barz.address, spenderAddress]) + + await expect(mockAccountBarz.connect(mockEntryPoint).execute(whitelistStorage.address, 0, whitelistCall)).to.be.revertedWithCustomError(whitelistStorage, "RemoteStorage__CallerNotGuardianOrOwner") + }) + it('Should whitelist address with guardian for owner wallet', async () => { + nonce = await addGuardian(guardian1, nonce) + await addFacetSelectorsViaEntryPointOnK1(barz, owner, guardianFacet, guardianFacet, entryPoint, nonce) + await expect(whitelistStorage.connect(guardian1).whitelistAddress(barz.address, spenderAddress)).to.emit(whitelistStorage, "Added").withArgs(spenderAddress) + }) + }) + + describe("# blacklistAddress", () => { + it('Should revert if address was not whitelisted', async () => { + const blacklistCall = whitelistStorage.interface.encodeFunctionData('blacklistAddress', [barz.address, spenderAddress]) + const callData = executeCallData(whitelistStorage.address, 0, blacklistCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, callData, nonce++)).to.not.emit(whitelistStorage, "Removed") + + const mockBlacklistCall = whitelistStorage.interface.encodeFunctionData('blacklistAddress', [mockBarz.address, spenderAddress]) + await expect(mockAccountBarz.connect(mockEntryPoint).execute(whitelistStorage.address, 0, mockBlacklistCall)).to.be.revertedWithCustomError(whitelistStorage, "RemoteStorage__NotFound") + }) + it('Should blacklist address with guardian for owner wallet', async () => { + const whitelistCall = whitelistStorage.interface.encodeFunctionData('whitelistAddress', [barz.address, spenderAddress]) + const callData = executeCallData(whitelistStorage.address, 0, whitelistCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, callData, nonce++)).to.emit(whitelistStorage, "Added").withArgs(spenderAddress) + + expect(await whitelistStorage.isWhitelisted(barz.address, spenderAddress)).to.be.true + + await addGuardian(guardian1, nonce) + + await expect(whitelistStorage.connect(guardian1).blacklistAddress(barz.address, spenderAddress)).to.emit(whitelistStorage, "Removed").withArgs(spenderAddress) + + expect(await whitelistStorage.isWhitelisted(barz.address, spenderAddress)).to.be.false + }) + it('Should blacklist address', async () => { + const whitelistCall = whitelistStorage.interface.encodeFunctionData('whitelistAddress', [barz.address, spenderAddress]) + let callData = executeCallData(whitelistStorage.address, 0, whitelistCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, callData, nonce++)).to.emit(whitelistStorage, "Added").withArgs(spenderAddress) + + expect(await whitelistStorage.isWhitelisted(barz.address, spenderAddress)).to.be.true + + const blacklistCall = whitelistStorage.interface.encodeFunctionData('blacklistAddress', [barz.address, spenderAddress]) + callData = executeCallData(whitelistStorage.address, 0, blacklistCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, callData, nonce++)).to.emit(whitelistStorage, "Removed").withArgs(spenderAddress) + + expect(await whitelistStorage.isWhitelisted(barz.address, spenderAddress)).to.be.false + }) + }) + + describe("# isWhitelisted", () => { + it("Should return valid whitelist address", async () => { + const whitelistCall = whitelistStorage.interface.encodeFunctionData('whitelistAddress', [barz.address, spenderAddress]) + const callData = executeCallData(whitelistStorage.address, 0, whitelistCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, callData, nonce++)).to.emit(whitelistStorage, "Added").withArgs(spenderAddress) + + expect(await whitelistStorage.isWhitelisted(barz.address, spenderAddress)).to.be.true + }) + }) + + describe('# getWhitelistedAddresses', () => { + it("Should return valid list of whitelist addresses", async () => { + const whitelistCall = whitelistStorage.interface.encodeFunctionData('whitelistAddress', [barz.address, spenderAddress]) + let callData = executeCallData(whitelistStorage.address, 0, whitelistCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, callData, nonce++)).to.emit(whitelistStorage, "Added").withArgs(spenderAddress) + + const guardianWhitelistCall = whitelistStorage.interface.encodeFunctionData('whitelistAddress', [barz.address, guardian1.address]) + callData = executeCallData(whitelistStorage.address, 0, guardianWhitelistCall) + await expect(callFromEntryPointOnK1(entryPoint, barz.address, owner, callData, nonce++)).to.emit(whitelistStorage, "Added").withArgs(guardian1.address) + + expect(await whitelistStorage.getWhitelistedAddresses(barz.address)).to.deep.equal([spenderAddress, guardian1.address]) + }) + }) +}) \ No newline at end of file diff --git a/test/utils/UserOp.ts b/test/utils/UserOp.ts new file mode 100644 index 0000000..a38c5d3 --- /dev/null +++ b/test/utils/UserOp.ts @@ -0,0 +1,239 @@ +import { + arrayify, + defaultAbiCoder, + keccak256, + concat, + hexZeroPad, + hexlify, + sha256, + toUtf8Bytes, + BytesLike +} from 'ethers/lib/utils' +import { BigNumber, Wallet } from 'ethers' +import { AddressZero } from './testutils' +import { ecsign, toRpcSig, keccak256 as keccak256_buffer } from 'ethereumjs-util' +import { UserOperation } from './UserOperation' +import base64url from 'base64url' +import { AccountFacet__factory } from '../../typechain-types' +import { ethers } from 'hardhat' +import { uint256 } from './solidityTypes' +import { EntryPoint } from '../../typechain-types/core' +import { callGasLimit, verificationGasLimit, maxFeePerGas } from './testutils' +import { getChainId } from './helpers' +import elliptic from 'elliptic' +import { getAccountBarz } from './setup' + +const ec = new elliptic.ec('p256') + +export function packUserOp (op: UserOperation, forSignature = true): string { + if (forSignature) { + return defaultAbiCoder.encode( + ['address', 'uint256', 'bytes32', 'bytes32', + 'uint256', 'uint256', 'uint256', 'uint256', 'uint256', + 'bytes32'], + [op.sender, op.nonce, keccak256(op.initCode), keccak256(op.callData), + op.callGasLimit, op.verificationGasLimit, op.preVerificationGas, op.maxFeePerGas, op.maxPriorityFeePerGas, + keccak256(op.paymasterAndData)]) + } else { + // for the purpose of calculating gas cost encode also signature (and no keccak of bytes) + return defaultAbiCoder.encode( + ['address', 'uint256', 'bytes', 'bytes', + 'uint256', 'uint256', 'uint256', 'uint256', 'uint256', + 'bytes', 'bytes'], + [op.sender, op.nonce, op.initCode, op.callData, + op.callGasLimit, op.verificationGasLimit, op.preVerificationGas, op.maxFeePerGas, op.maxPriorityFeePerGas, + op.paymasterAndData, op.signature]) + } +} + +export function packUserOp1 (op: UserOperation): string { + return defaultAbiCoder.encode([ + 'address', // sender + 'uint256', // nonce + 'bytes32', // initCode + 'bytes32', // callData + 'uint256', // callGasLimit + 'uint256', // verificationGasLimit + 'uint256', // preVerificationGas + 'uint256', // maxFeePerGas + 'uint256', // maxPriorityFeePerGas + 'bytes32' // paymasterAndData + ], [ + op.sender, + op.nonce, + keccak256(op.initCode), + keccak256(op.callData), + op.callGasLimit, + op.verificationGasLimit, + op.preVerificationGas, + op.maxFeePerGas, + op.maxPriorityFeePerGas, + keccak256(op.paymasterAndData) + ]) +} + + +export function getUserOpHash(op: UserOperation, entryPoint: string, chainId: number): string { + const userOpHash = keccak256(packUserOp(op, true)) + const enc = defaultAbiCoder.encode( + ['bytes32', 'address', 'uint256'], + [userOpHash, entryPoint, chainId]) + return keccak256(enc) +} + +export const DefaultsForUserOp: UserOperation = { + sender: AddressZero, + nonce: 0, + initCode: '0x', + callData: '0x', + callGasLimit: 0, + verificationGasLimit: 1000000, // default verification gas. will add create2 cost (3200+200*length) if initCode exists + preVerificationGas: 21000, // should also cover calldata cost. + maxFeePerGas: 0, + maxPriorityFeePerGas: 1e9, + paymasterAndData: '0x', + signature: '0x' +} + +export function signUserOpK1Curve(op: UserOperation, signer: Wallet, entryPoint: string, chainId: number): UserOperation { + const message = getUserOpHash(op, entryPoint, chainId) + const msg1 = Buffer.concat([ + Buffer.from('\x19Ethereum Signed Message:\n32', 'ascii'), + Buffer.from(arrayify(message)) + ]) + + const sig = ecsign(keccak256_buffer(msg1), Buffer.from(arrayify(signer.privateKey))) + // that's equivalent of: await signer.signMessage(message); + // (but without "async" + const signedMessage1 = toRpcSig(sig.v, sig.r, sig.s) + return { + ...op, + signature: signedMessage1 + } +} + +export function signUserOpR1Curve(op: UserOperation, keyPair: any, entryPoint: string, chainId: number): UserOperation { + const opHash = getUserOpHash(op, entryPoint, chainId) + const opHashBase64 = base64url.encode(concat([opHash])) + + const clientDataJSONPre = '{"type":"webauthn.get","challenge":"'; + const clientDataJSONPost = '","origin":"https://webauthn.me","crossOrigin":false}'; + const authenticatorData = concat([ + hexZeroPad("0xf95bc73828ee210f9fd3bbe72d97908013b0a3759e9aea3d0ae318766cd2e1ad", 32), + hexlify("0x0500000000") + ]) + const clientDataJSON = clientDataJSONPre + opHashBase64 + clientDataJSONPost + const clientHash = sha256(toUtf8Bytes(clientDataJSON)).toString() + const authenticatorDataHEX = hexlify(authenticatorData) + const sigHash = sha256(concat([authenticatorDataHEX, clientHash])).slice(2) + const signature = keyPair.sign(sigHash); + + signature.s = adjustS(signature.s, ec.n) + + const signedMessage = defaultAbiCoder.encode( + ['uint256', 'uint256', 'bytes', 'string', 'string'], + [ + BigNumber.from("0x" + signature.r.toString('hex')), + BigNumber.from("0x" + signature.s.toString('hex')), + authenticatorData, + clientDataJSONPre, + clientDataJSONPost + ] + ); + return { + ...op, + signature: signedMessage + } +} + +export function signMsgOnR1Curve(hash: string, keyPair: any): string { + const opHashBase64 = base64url.encode(concat([hash])) + + const clientDataJSONPre = '{"type":"webauthn.get","challenge":"'; + const clientDataJSONPost = '","origin":"https://webauthn.me","crossOrigin":false}'; + const authenticatorData = concat([ + hexZeroPad("0xf95bc73828ee210f9fd3bbe72d97908013b0a3759e9aea3d0ae318766cd2e1ad", 32), + hexlify("0x0500000000") + ]) + const clientDataJSON = clientDataJSONPre + opHashBase64 + clientDataJSONPost + const clientHash = sha256(toUtf8Bytes(clientDataJSON)).toString() + const authenticatorDataHEX = hexlify(authenticatorData) + const sigHash = sha256(concat([authenticatorDataHEX, clientHash])).slice(2) + const signature = keyPair.sign(sigHash); + + signature.s = adjustS(signature.s, ec.n) + + const signedMessage = defaultAbiCoder.encode( + ['uint256', 'uint256', 'bytes', 'string', 'string'], + [ + BigNumber.from("0x" + signature.r.toString('hex')), + BigNumber.from("0x" + signature.s.toString('hex')), + authenticatorData, + clientDataJSONPre, + clientDataJSONPost + ] + ); + return signedMessage +} + +export function adjustS(s: any, n: any) { + // Ensure that 's' and 'n' are BN instances + const halfN = n.divn(2); + // Compare 's' with half of 'n' + if (s.cmp(halfN) > 0) { + // Subtract 's' from 'n' only if 's' is greater than 'n/2' + return n.sub(s); + } + return s;} + +export function fillUserOpDefaults(op: Partial, defaults = DefaultsForUserOp): UserOperation { + const partial: any = { ...op } + // we want "item:undefined" to be used from defaults, and not override defaults, so we must explicitly + // remove those so "merge" will succeed. + for (const key in partial) { + if (partial[key] == null) { + // eslint-disable-next-line @typescript-eslint/no-dynamic-delete + delete partial[key] + } + } + const filled = { ...defaults, ...partial } + return filled +} + +export function executeCallData(dest: BytesLike, value: uint256, callData: BytesLike): BytesLike { + const accountInterface = new ethers.utils.Interface(AccountFacet__factory.abi) + return accountInterface.encodeFunctionData("execute", [dest, value, callData]) +} + +export function executeBatchCallData(dest: BytesLike[], values: uint256[], callData: BytesLike[]): BytesLike { + const accountInterface = new ethers.utils.Interface(AccountFacet__factory.abi) + return accountInterface.encodeFunctionData("executeBatch", [dest, values, callData]) +} + +export async function callFromEntryPointOnK1(entryPoint: EntryPoint, sender: string, signer: Wallet, callData: BytesLike) { + const accountBarz = await getAccountBarz(sender) + const userOp = signUserOpK1Curve(fillUserOpDefaults({ + sender: sender, + nonce: await accountBarz.getNonce(), + callData, + callGasLimit, + verificationGasLimit, + maxFeePerGas, + }), signer, entryPoint.address, await getChainId()) + + return entryPoint.handleOps([userOp], sender) +} + +export async function callFromEntryPointOnR1(entryPoint: EntryPoint, sender: string, signer: any, callData: BytesLike) { + const accountBarz = await getAccountBarz(sender) + const userOp = signUserOpR1Curve(fillUserOpDefaults({ + sender: sender, + nonce: await accountBarz.getNonce(), + callData, + callGasLimit, + verificationGasLimit, + maxFeePerGas, + }), signer, entryPoint.address, await getChainId()) + + return entryPoint.handleOps([userOp], sender) +} \ No newline at end of file diff --git a/test/utils/UserOperation.ts b/test/utils/UserOperation.ts new file mode 100644 index 0000000..8bed5ab --- /dev/null +++ b/test/utils/UserOperation.ts @@ -0,0 +1,16 @@ +import * as typ from './solidityTypes' + +export interface UserOperation { + + sender: typ.address + nonce: typ.uint256 + initCode: typ.bytes + callData: typ.bytes + callGasLimit: typ.uint256 + verificationGasLimit: typ.uint256 + preVerificationGas: typ.uint256 + maxFeePerGas: typ.uint256 + maxPriorityFeePerGas: typ.uint256 + paymasterAndData: typ.bytes + signature: typ.bytes +} diff --git a/test/utils/base64-helpers.ts b/test/utils/base64-helpers.ts new file mode 100644 index 0000000..a9b79ee --- /dev/null +++ b/test/utils/base64-helpers.ts @@ -0,0 +1,159 @@ +import * as base64url from './base64url-arraybuffer'; + +export const bufferToString = (buff: any) => { + const enc = new TextDecoder(); // always utf-8 + return enc.decode(buff); +}; + +export const getEndian = () => { + const arrayBuffer = new ArrayBuffer(2); + const uint8Array = new Uint8Array(arrayBuffer); + const uint16array = new Uint16Array(arrayBuffer); + uint8Array[0] = 0xaa; // set first byte + uint8Array[1] = 0xbb; // set second byte + + if (uint16array[0] === 0xbbaa) return 'little'; + else return 'big'; +}; + +export const readBE16 = (buffer: any) => { + if (buffer.length !== 2) throw new Error('Only 2byte buffer allowed!'); + + if (getEndian() !== 'big') buffer = buffer.reverse(); + + return new Uint16Array(buffer.buffer)[0]; +}; + +export const readBE32 = (counterBuf: any) => { + if (counterBuf.length !== 4) throw new Error('Only 4byte buffers allowed!'); + + if (getEndian() !== 'big') counterBuf = counterBuf.reverse(); + + return new Uint32Array(counterBuf.buffer)[0]; +}; + +export const bufToHex = (buffer: any) => { + // buffer is an ArrayBuffer + return Array.prototype.map + .call(new Uint8Array(buffer), (x) => ('00' + x.toString(16)).slice(-2)) + .join(''); +}; + +export const hexToBuf = (hex: string) => { + const byteLength = hex.length / 2; + const byteArray = new Uint8Array(byteLength); + + for (let i = 0; i < byteLength; i++) { + byteArray[i] = parseInt(hex.substr(i * 2, 2), 16); + } + + return byteArray.buffer; +}; + +export const convertToHex = (buffer: any) => { + const uint8View = new Uint8Array(buffer); + let hexString = ""; + for (let i = 0; i < uint8View.length; i++) { + const hex = uint8View[i].toString(16); + hexString += hex.length === 1 ? "0" + hex : hex; // ensure two-digit hex + } + return hexString +} + +// https://gist.github.com/herrjemand/dbeb2c2b76362052e5268224660b6fbc +export const parseAuthData = (buffer: any) => { + const rpIdHash = buffer.slice(0, 32); + buffer = buffer.slice(32); + const flagsBuf = buffer.slice(0, 1); + buffer = buffer.slice(1); + const flagsInt = flagsBuf[0]; + const flags = { + up: !!(flagsInt & 0x01), + uv: !!(flagsInt & 0x04), + at: !!(flagsInt & 0x40), + ed: !!(flagsInt & 0x80), + flagsInt, + }; + + const counterBuf = buffer.slice(0, 4); + buffer = buffer.slice(4); + const counter = readBE32(counterBuf); + + let aaguid = undefined; + let credID = undefined; + let COSEPublicKey = undefined; + + if (flags.at) { + aaguid = buffer.slice(0, 16); + buffer = buffer.slice(16); + const credIDLenBuf = buffer.slice(0, 2); + buffer = buffer.slice(2); + const credIDLen = readBE16(credIDLenBuf); + credID = buffer.slice(0, credIDLen); + buffer = buffer.slice(credIDLen); + COSEPublicKey = buffer; + } + + return { + rpIdHash, + flagsBuf, + flags, + counter, + counterBuf, + aaguid, + credID, + COSEPublicKey, + }; +}; + +export const generateRandomBuffer = (length: any) => { + if (!length) length = 32; + + const randomBuff = new Uint8Array(length); + window.crypto.getRandomValues(randomBuff); + return randomBuff; +}; + +export const publicKeyCredentialToJSON: any = (pubKeyCred: any) => { + if (pubKeyCred instanceof Array) { + const arr = []; + for (const i of pubKeyCred) arr.push(publicKeyCredentialToJSON(i)); + + return arr; + } + + if (pubKeyCred instanceof ArrayBuffer) { + return base64url.encode(pubKeyCred); + } + + if (pubKeyCred instanceof Object) { + const obj: any = {}; + + for (const key in pubKeyCred) { + obj[key] = publicKeyCredentialToJSON(pubKeyCred[key]); + } + + return obj; + } + + return pubKeyCred; +}; + +export const preformatMakeCredReq = (makeCredReq: any) => { + makeCredReq.challenge = base64url.decode(makeCredReq.challenge); + makeCredReq.user.id = base64url.decode(makeCredReq.user.id); + + return makeCredReq; +}; + +export const preformatGetAssertReq = (getAssert: any) => { + getAssert.challenge = base64url.decode(getAssert.challenge); + + if (getAssert.allowCredentials) { + for (const allowCred of getAssert.allowCredentials) { + allowCred.id = base64url.decode(allowCred.id); + } + } + + return getAssert; +}; diff --git a/test/utils/base64url-arraybuffer.ts b/test/utils/base64url-arraybuffer.ts new file mode 100644 index 0000000..3cd3854 --- /dev/null +++ b/test/utils/base64url-arraybuffer.ts @@ -0,0 +1,56 @@ +const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_' + +// Use a lookup table to find the index. +const lookup = new Uint8Array(256) + +for (let i = 0; i < chars.length; i++) { + lookup[chars.charCodeAt(i)] = i +} + +export const encode = function (arraybuffer: ArrayBuffer) { + const bytes = new Uint8Array(arraybuffer), len = bytes.length + let i, + base64 = '' + + for (i = 0; i < len; i += 3) { + base64 += chars[bytes[i] >> 2] + base64 += chars[((bytes[i] & 3) << 4) | (bytes[i + 1] >> 4)] + base64 += chars[((bytes[i + 1] & 15) << 2) | (bytes[i + 2] >> 6)] + base64 += chars[bytes[i + 2] & 63] + } + + if (len % 3 === 2) { + base64 = base64.substring(0, base64.length - 1) + } else if (len % 3 === 1) { + base64 = base64.substring(0, base64.length - 2) + } + + return base64 +} + +export const decode = function (base64: string) { + const bufferLength = base64.length * 0.75, + len = base64.length + let i, + p = 0, + encoded1, + encoded2, + encoded3, + encoded4 + + const arraybuffer = new ArrayBuffer(bufferLength), + bytes = new Uint8Array(arraybuffer) + + for (i = 0; i < len; i += 4) { + encoded1 = lookup[base64.charCodeAt(i)] + encoded2 = lookup[base64.charCodeAt(i + 1)] + encoded3 = lookup[base64.charCodeAt(i + 2)] + encoded4 = lookup[base64.charCodeAt(i + 3)] + + bytes[p++] = (encoded1 << 2) | (encoded2 >> 4) + bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2) + bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63) + } + + return arraybuffer +} diff --git a/test/utils/cbor.ts b/test/utils/cbor.ts new file mode 100644 index 0000000..c2c583d --- /dev/null +++ b/test/utils/cbor.ts @@ -0,0 +1,360 @@ +export const POW_2_24 = 5.960464477539063e-8, + POW_2_32 = 4294967296, + POW_2_53 = 9007199254740992; + +export function encode(value: any) { + let data = new ArrayBuffer(256); + let dataView = new DataView(data); + let lastLength: any; + let offset = 0; + + function prepareWrite(length: number) { + let newByteLength = data.byteLength; + const requiredLength = offset + length; + while (newByteLength < requiredLength) newByteLength <<= 1; + if (newByteLength !== data.byteLength) { + const oldDataView = dataView; + data = new ArrayBuffer(newByteLength); + dataView = new DataView(data); + const uint32count = (offset + 3) >> 2; + for (let i = 0; i < uint32count; ++i) + dataView.setUint32(i << 2, oldDataView.getUint32(i << 2)); + } + + lastLength = length; + return dataView; + } + function commitWrite() { + offset += lastLength; + } + function writeFloat64(value: any) { + commitWrite(); + prepareWrite(8).setFloat64(offset, value); + } + function writeUint8(value: any) { + commitWrite(); + prepareWrite(1).setUint8(offset, value); + } + function writeUint8Array(value: any) { + const dataView = prepareWrite(value.length); + for (let i = 0; i < value.length; ++i) + dataView.setUint8(offset + i, value[i]); + commitWrite(); + } + function writeUint16(value: any) { + commitWrite(); + prepareWrite(2).setUint16(offset, value); + } + function writeUint32(value: any) { + commitWrite(); + prepareWrite(4).setUint32(offset, value); + } + function writeUint64(value: any) { + const low = value % POW_2_32; + const high = (value - low) / POW_2_32; + const dataView = prepareWrite(8); + dataView.setUint32(offset, high); + dataView.setUint32(offset + 4, low); + commitWrite(); + } + function writeTypeAndLength(type: any, length: any) { + if (length < 24) { + writeUint8((type << 5) | length); + } else if (length < 0x100) { + writeUint8((type << 5) | 24); + writeUint8(length); + } else if (length < 0x10000) { + writeUint8((type << 5) | 25); + writeUint16(length); + } else if (length < 0x100000000) { + writeUint8((type << 5) | 26); + writeUint32(length); + } else { + writeUint8((type << 5) | 27); + writeUint64(length); + } + } + + function encodeItem(value: any) { + let i; + + if (value === false) return writeUint8(0xf4); + if (value === true) return writeUint8(0xf5); + if (value === null) return writeUint8(0xf6); + if (value === undefined) return writeUint8(0xf7); + + switch (typeof value) { + case 'number': + if (Math.floor(value) === value) { + if (0 <= value && value <= POW_2_53) + return writeTypeAndLength(0, value); + if (-POW_2_53 <= value && value < 0) + return writeTypeAndLength(1, -(value + 1)); + } + writeUint8(0xfb); + return writeFloat64(value); + + case 'string': + const utf8data = []; + for (i = 0; i < value.length; ++i) { + let charCode = value.charCodeAt(i); + if (charCode < 0x80) { + utf8data.push(charCode); + } else if (charCode < 0x800) { + utf8data.push(0xc0 | (charCode >> 6)); + utf8data.push(0x80 | (charCode & 0x3f)); + } else if (charCode < 0xd800) { + utf8data.push(0xe0 | (charCode >> 12)); + utf8data.push(0x80 | ((charCode >> 6) & 0x3f)); + utf8data.push(0x80 | (charCode & 0x3f)); + } else { + charCode = (charCode & 0x3ff) << 10; + charCode |= value.charCodeAt(++i) & 0x3ff; + charCode += 0x10000; + + utf8data.push(0xf0 | (charCode >> 18)); + utf8data.push(0x80 | ((charCode >> 12) & 0x3f)); + utf8data.push(0x80 | ((charCode >> 6) & 0x3f)); + utf8data.push(0x80 | (charCode & 0x3f)); + } + } + + writeTypeAndLength(3, utf8data.length); + return writeUint8Array(utf8data); + + default: + let length; + if (Array.isArray(value)) { + length = value.length; + writeTypeAndLength(4, length); + for (i = 0; i < length; ++i) encodeItem(value[i]); + } else if (value instanceof Uint8Array) { + writeTypeAndLength(2, value.length); + writeUint8Array(value); + } else { + const keys = Object.keys(value); + length = keys.length; + writeTypeAndLength(5, length); + for (i = 0; i < length; ++i) { + const key = keys[i]; + encodeItem(key); + encodeItem(value[key]); + } + } + } + } + + encodeItem(value); + + if ('slice' in data) return data.slice(0, offset); + + const ret = new ArrayBuffer(offset); + const retView = new DataView(ret); + for (let i = 0; i < offset; ++i) retView.setUint8(i, dataView.getUint8(i)); + return ret; +} + +export function decode(data: any, tagger: any, simpleValue: any) { + const dataView = new DataView(data); + let offset = 0; + + if (typeof tagger !== 'function') + tagger = function (value: any) { + return value; + }; + if (typeof simpleValue !== 'function') + simpleValue = function () { + return undefined; + }; + + function commitRead(length: any, value: any) { + offset += length; + return value; + } + function readArrayBuffer(length: any) { + return commitRead(length, new Uint8Array(data, offset, length)); + } + function readFloat16() { + const tempArrayBuffer = new ArrayBuffer(4); + const tempDataView = new DataView(tempArrayBuffer); + const value = readUint16(); + + const sign = value & 0x8000; + let exponent = value & 0x7c00; + const fraction = value & 0x03ff; + + if (exponent === 0x7c00) exponent = 0xff << 10; + else if (exponent !== 0) exponent += (127 - 15) << 10; + else if (fraction !== 0) return (sign ? -1 : 1) * fraction * POW_2_24; + + tempDataView.setUint32( + 0, + (sign << 16) | (exponent << 13) | (fraction << 13) + ); + return tempDataView.getFloat32(0); + } + function readFloat32() { + return commitRead(4, dataView.getFloat32(offset)); + } + function readFloat64() { + return commitRead(8, dataView.getFloat64(offset)); + } + function readUint8() { + return commitRead(1, dataView.getUint8(offset)); + } + function readUint16() { + return commitRead(2, dataView.getUint16(offset)); + } + function readUint32() { + return commitRead(4, dataView.getUint32(offset)); + } + function readUint64() { + return readUint32() * POW_2_32 + readUint32(); + } + function readBreak() { + if (dataView.getUint8(offset) !== 0xff) return false; + offset += 1; + return true; + } + function readLength(additionalInformation: any) { + if (additionalInformation < 24) return additionalInformation; + if (additionalInformation === 24) return readUint8(); + if (additionalInformation === 25) return readUint16(); + if (additionalInformation === 26) return readUint32(); + if (additionalInformation === 27) return readUint64(); + if (additionalInformation === 31) return -1; + throw 'Invalid length encoding'; + } + function readIndefiniteStringLength(majorType: any) { + const initialByte = readUint8(); + if (initialByte === 0xff) return -1; + const length = readLength(initialByte & 0x1f); + if (length < 0 || initialByte >> 5 !== majorType) + throw 'Invalid indefinite length element'; + return length; + } + + function appendUtf16Data(utf16data: any, length: any) { + for (let i = 0; i < length; ++i) { + let value = readUint8(); + if (value & 0x80) { + if (value < 0xe0) { + value = ((value & 0x1f) << 6) | (readUint8() & 0x3f); + length -= 1; + } else if (value < 0xf0) { + value = + ((value & 0x0f) << 12) | + ((readUint8() & 0x3f) << 6) | + (readUint8() & 0x3f); + length -= 2; + } else { + value = + ((value & 0x0f) << 18) | + ((readUint8() & 0x3f) << 12) | + ((readUint8() & 0x3f) << 6) | + (readUint8() & 0x3f); + length -= 3; + } + } + + if (value < 0x10000) { + utf16data.push(value); + } else { + value -= 0x10000; + utf16data.push(0xd800 | (value >> 10)); + utf16data.push(0xdc00 | (value & 0x3ff)); + } + } + } + + function decodeItem(): any { + const initialByte = readUint8(); + const majorType = initialByte >> 5; + const additionalInformation = initialByte & 0x1f; + let i; + let length; + + if (majorType === 7) { + switch (additionalInformation) { + case 25: + return readFloat16(); + case 26: + return readFloat32(); + case 27: + return readFloat64(); + } + } + + length = readLength(additionalInformation); + if (length < 0 && (majorType < 2 || 6 < majorType)) throw 'Invalid length'; + + switch (majorType) { + case 0: + return length; + case 1: + return -1 - length; + case 2: + if (length < 0) { + const elements = []; + let fullArrayLength = 0; + while ((length = readIndefiniteStringLength(majorType)) >= 0) { + fullArrayLength += length; + elements.push(readArrayBuffer(length)); + } + const fullArray = new Uint8Array(fullArrayLength); + let fullArrayOffset = 0; + for (i = 0; i < elements.length; ++i) { + fullArray.set(elements[i], fullArrayOffset); + fullArrayOffset += elements[i].length; + } + return fullArray; + } + return readArrayBuffer(length); + case 3: + const utf16data: any = []; + if (length < 0) { + while ((length = readIndefiniteStringLength(majorType)) >= 0) + appendUtf16Data(utf16data, length); + } else appendUtf16Data(utf16data, length); + return String.fromCharCode.apply(null, utf16data); + case 4: + let retArray; + if (length < 0) { + retArray = []; + while (!readBreak()) retArray.push(decodeItem()); + } else { + retArray = new Array(length); + for (i = 0; i < length; ++i) retArray[i] = decodeItem(); + } + return retArray; + case 5: + const retObject: any = {}; + for (i = 0; i < length || (length < 0 && !readBreak()); ++i) { + const key = decodeItem(); + retObject[key] = decodeItem(); + } + return retObject; + case 6: + return tagger(decodeItem(), length); + case 7: + switch (length) { + case 20: + return false; + case 21: + return true; + case 22: + return null; + case 23: + return undefined; + default: + return simpleValue(length); + } + } + } + + const ret = decodeItem(); + if (offset !== data.byteLength) throw 'Remaining bytes'; + return ret; +} + +export const obj = { encode: encode, decode: decode }; diff --git a/test/utils/diamond.js b/test/utils/diamond.js new file mode 100644 index 0000000..af4a20c --- /dev/null +++ b/test/utils/diamond.js @@ -0,0 +1,82 @@ +/* global ethers */ + +const FacetCutAction = { Add: 0, Replace: 1, Remove: 2 } + +// get function selectors from ABI +function getSelectors (contract) { + const signatures = Object.keys(contract.interface.functions) + const selectors = signatures.reduce((acc, val) => { + if (val !== 'init(bytes)') { + acc.push(contract.interface.getSighash(val)) + } + return acc + }, []) + selectors.contract = contract + selectors.remove = remove + selectors.get = get + return selectors +} + +// get function selector from function signature +function getSelector (func) { + const abiInterface = new ethers.utils.Interface([func]) + return abiInterface.getSighash(ethers.utils.Fragment.from(func)) +} + +// used with getSelectors to remove selectors from an array of selectors +// functionNames argument is an array of function signatures +function remove (functionNames) { + const selectors = this.filter((v) => { + for (const functionName of functionNames) { + if (v === this.contract.interface.getSighash(functionName)) { + return false + } + } + return true + }) + selectors.contract = this.contract + selectors.remove = this.remove + selectors.get = this.get + return selectors +} + +// used with getSelectors to get selectors from an array of selectors +// functionNames argument is an array of function signatures +function get (functionNames) { + const selectors = this.filter((v) => { + for (const functionName of functionNames) { + if (v === this.contract.interface.getSighash(functionName)) { + return true + } + } + return false + }) + selectors.contract = this.contract + selectors.remove = this.remove + selectors.get = this.get + return selectors +} + +// remove selectors using an array of signatures +function removeSelectors (selectors, signatures) { + const iface = new ethers.utils.Interface(signatures.map(v => 'function ' + v)) + const removeSelectors = signatures.map(v => iface.getSighash(v)) + selectors = selectors.filter(v => !removeSelectors.includes(v)) + return selectors +} + +// find a particular address position in the return value of diamondLoupeFacet.facets() +function findAddressPositionInFacets (facetAddress, facets) { + for (let i = 0; i < facets.length; i++) { + if (facets[i].facetAddress === facetAddress) { + return i + } + } +} + +exports.getSelectors = getSelectors +exports.getSelector = getSelector +exports.FacetCutAction = FacetCutAction +exports.remove = remove +exports.removeSelectors = removeSelectors +exports.findAddressPositionInFacets = findAddressPositionInFacets diff --git a/test/utils/helpers.ts b/test/utils/helpers.ts new file mode 100644 index 0000000..a71fefe --- /dev/null +++ b/test/utils/helpers.ts @@ -0,0 +1,130 @@ +import { ethers } from 'hardhat' +import { FacetRegistry } from '../../typechain-types' +import elliptic from 'elliptic' +import { keccak256 } from '@ethersproject/keccak256' + +const { + getSelectors, + FacetCutAction +} = require('./diamond.js') + +export const getChainId = async () => { + return await ethers.provider.getNetwork().then(net => net.chainId) +} + +export const addressToBytes = (address: string) => { + return ethers.utils.hexZeroPad(address, 20) +} + +export const deployAndDiamondCut = async (facetNames: Array, facetRegistry: FacetRegistry) => { + const cut = [] + for (const FacetName of facetNames) { + const Facet = await ethers.getContractFactory(FacetName) + const facet = await Facet.deploy() + await facet.deployed() + await facetRegistry.registerFacetFunctionSelectors(facet.address, getSelectors(facet)) + cut.push({ + facetAddress: facet.address, + action: FacetCutAction.Add, + functionSelectors: getSelectors(facet) + }) + } + return cut +} + +export const diamondCut = (facetAddress: string, action: any, selectors: any) => { + const diamondCut = [] + diamondCut.push({ + facetAddress: facetAddress, + action: action, + functionSelectors: Array.isArray(selectors) ? selectors : getSelectors(selectors) + }) + return diamondCut +} + +export const increaseBlockTime = async (seconds: number) => { + const blockNumBefore = await ethers.provider.getBlockNumber(); + const blockBefore = await ethers.provider.getBlock(blockNumBefore); + await ethers.provider.send("evm_mine", [blockBefore.timestamp + seconds]) +} +export const guardianSecurityPeriod = 60 * 60 * 24 * 3 // 3 day +export const minGuardianSecurityPeriod = guardianSecurityPeriod / 2 +export const maxGuardianSecurityPeriod = guardianSecurityPeriod * 2 +export const guardianSecurityWindow = 60 * 60 * 24 // 1 day +export const minGuardianSecurityWindow = guardianSecurityWindow / 2 +export const maxGuardianSecurityWindow = guardianSecurityWindow * 2 +export const recoveryPeriod = 60 * 60 * 24 * 8.5 // 5 day +export const minRecoveryPeriod = recoveryPeriod / 2 +export const maxRecoveryPeriod = recoveryPeriod * 2 +export const lockPeriod = 60 * 60 * 24 * 18 // 18 day +export const minLockPeriod = lockPeriod / 2 +export const maxLockPeriod = lockPeriod * 2 +export const approvalValidationPeriod = 60 * 60 * 24 // 1 day +export const minApprovalValidationPeriod = approvalValidationPeriod / 2 +export const maxApprovalValidationPeriod = approvalValidationPeriod * 2 +export const migrationPeriod = 60 * 60 * 3 // 3 hours +export const minMigrationPeriod = migrationPeriod / 2 +export const maxMigrationPeriod = migrationPeriod * 2 +export const chainId = 3604 + +export enum FacetCutActionEnum { + Add, + Replace, + Remove +} + +export interface FacetCut { + facetAddress: string; + action: FacetCutActionEnum; + functionSelectors: string[]; +} + +export const facetCutType = `tuple(address facetAddress, uint8 action, bytes4[] functionSelectors)[]`; + +export const getBlockTimestamp = async () => { + const blockNumber = await ethers.provider.getBlockNumber(); + const block = await ethers.provider.getBlock(blockNumber); + const timestamp = block.timestamp; + return timestamp +} + +export const getEthSignMessageHash = (hash: string) => { + const prefix = `\x19Ethereum Signed Message:\n32`; + const messageHash = keccak256(ethers.utils.solidityPack(['string', 'bytes32'], [prefix, hash])); + return messageHash +} + +export type generatedKey = { + keyPair: any, + publicKeyBytes: any, + keyX: any, + keyY: any, + facetOwnerKey: any +} + +export function generateKeyPair (): generatedKey { + const ec = new elliptic.ec('p256') + let keyPair = ec.genKeyPair() + let publicKeyBytes: string = "0x04" + keyPair.getPublic().getX().toString('hex')+ keyPair.getPublic().getY().toString('hex') + for (let i = 0; publicKeyBytes.length % 2 !== 0; i++) { + keyPair = ec.genKeyPair() + publicKeyBytes = "0x04" + keyPair.getPublic().getX().toString('hex')+ keyPair.getPublic().getY().toString('hex') + } + const keyX = keyPair.getPublic().getX() + const keyY = keyPair.getPublic().getY() + const facetOwnerKey = "0x" + keyX.toString('hex') + keyY.toString('hex') + + return { + keyPair, + publicKeyBytes, + keyX, + keyY, + facetOwnerKey + } +} + +export const isUserOperationSuccessful = async (tx: any) => { + const receipt = await tx.wait() + const event = receipt.events?.filter((e:any) => e.event === "UserOperationEvent")[0]; + return event?.args?.success +} \ No newline at end of file diff --git a/test/utils/setup.ts b/test/utils/setup.ts new file mode 100644 index 0000000..1897eca --- /dev/null +++ b/test/utils/setup.ts @@ -0,0 +1,176 @@ +import { ethers } from 'hardhat' + +import { AccountFacet, DiamondCutFacet, Barz, Secp256k1VerificationFacet, Secp256r1VerificationFacet, SecurityManager, FacetRegistry } from '../../typechain-types' +import { diamondCut, guardianSecurityPeriod, minGuardianSecurityPeriod, maxGuardianSecurityPeriod, guardianSecurityWindow, minGuardianSecurityWindow, maxGuardianSecurityWindow, recoveryPeriod, minRecoveryPeriod, maxRecoveryPeriod, lockPeriod, minLockPeriod, maxLockPeriod, approvalValidationPeriod, minApprovalValidationPeriod, maxApprovalValidationPeriod, minMigrationPeriod, maxMigrationPeriod, migrationPeriod } from '../utils/helpers' +import { securityManagerFixture } from '../fixtures/SecurityManagerFixture' +import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers' +import { AddressZero } from '../utils/testutils' + +const { + FacetCutAction, + getSelectors +} = require('../utils/diamond.js') + +import { expect } from "chai" +import { diamondCutFacetFixture } from '../fixtures/DiamondCutFacetFixture' +import { accountFacetFixture } from '../fixtures/AccountFacetFixture' +import { secp256k1VerificationFacetFixture } from '../fixtures/Secp256k1VerificationFacetFixture' +import { secp256r1VerificationFacetFixture } from '../fixtures/Secp256r1VerificationFacetFixture' +import { barzFixture } from '../fixtures/BarzFixture' +import { EntryPoint } from '../../typechain-types' +import { facetRegistryFixture } from '../fixtures/FacetRegistryFixture' +import { callFromEntryPointOnK1, callFromEntryPointOnR1, executeCallData } from './UserOp' +import { uint256 } from './solidityTypes' +import { diamondLoupeFacetFixture } from '../fixtures/DiamondLoupeFacetFixture' +import { tokenReceiverFacetFixture } from '../fixtures/TokenReceiverFacetFixture' +import { defaultFallbackHandlerFixture } from '../fixtures/DefaultFallbackHandlerFixture' +import { secp256r1VerificationFacetV2Fixture } from '../fixtures/Secp256r1VerificationFacetV2Fixture' + +type SetupContractsReturnType = { + securityManager: SecurityManager; + diamondCutFacet: DiamondCutFacet; + accountFacet: AccountFacet; + k1Facet: Secp256k1VerificationFacet; + r1Facet: Secp256r1VerificationFacet; + facetRegistry: FacetRegistry; + barz: Barz; +}; + +export const setupContracts = async (facetRegistryOwner: SignerWithAddress, securityManagerOwner: SignerWithAddress, entryPoint: EntryPoint | SignerWithAddress, ownerBytes: string, guardianSecurityPeriod: number, guardianSecurityWindow: number, recoveryPeriod: number, lockPeriod: number, approvalValidationPeriod: number, migrationPeriod: number, isR1 = false, isV2 = false): Promise => { + const minGuardianSecurityPeriod = guardianSecurityPeriod / 2 + const maxGuardianSecurityPeriod = guardianSecurityPeriod * 2 + const minGuardianSecurityWindow = guardianSecurityWindow / 2 + const maxGuardianSecurityWindow = guardianSecurityWindow * 2 + const minRecoveryPeriod = recoveryPeriod / 2 + const maxRecoveryPeriod = recoveryPeriod * 2 + const minLockPeriod = lockPeriod / 2 + const maxLockPeriod = lockPeriod * 2 + const minApprovalValidationPeriod = approvalValidationPeriod / 2 + const maxApprovalValidationPeriod = approvalValidationPeriod * 2 + const minMigrationPeriod = migrationPeriod / 2 + const maxMigrationPeriod = migrationPeriod * 2 + const securityManager = await setupSecurityManager(securityManagerOwner, minGuardianSecurityPeriod, maxGuardianSecurityPeriod, guardianSecurityPeriod, + minGuardianSecurityWindow, maxGuardianSecurityWindow, guardianSecurityWindow, + minRecoveryPeriod, maxRecoveryPeriod, recoveryPeriod, + minLockPeriod, maxLockPeriod, lockPeriod, + minApprovalValidationPeriod, maxApprovalValidationPeriod, approvalValidationPeriod, minMigrationPeriod, maxMigrationPeriod, migrationPeriod) + const diamondCutFacet = await diamondCutFacetFixture(securityManager) + const accountFacet = await accountFacetFixture() + const facetRegistry = await facetRegistryFixture(facetRegistryOwner.address) + + const k1Facet = await secp256k1VerificationFacetFixture() + const r1Facet = await secp256r1VerificationFacetFixture() + const r1FacetV2 = await secp256r1VerificationFacetV2Fixture() + const diamondLoupeFacet = await diamondLoupeFacetFixture() + const tokenReceiverFacet = await tokenReceiverFacetFixture() + const defaultFallbackHandler = await defaultFallbackHandlerFixture(diamondCutFacet, accountFacet, tokenReceiverFacet, diamondLoupeFacet) + + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(accountFacet.address, getSelectors(accountFacet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(k1Facet.address, getSelectors(k1Facet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(r1Facet.address, getSelectors(r1Facet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(diamondCutFacet.address, getSelectors(diamondCutFacet)) + await facetRegistry.connect(facetRegistryOwner).registerFacetFunctionSelectors(diamondLoupeFacet.address, getSelectors(diamondLoupeFacet)) + let verificationFacet = isR1 == false ? k1Facet : r1Facet + verificationFacet = (isR1 && isV2) ? r1FacetV2 : verificationFacet + const barz = await barzFixture(accountFacet, verificationFacet, entryPoint, facetRegistry, defaultFallbackHandler, ownerBytes) + return { + securityManager: securityManager, diamondCutFacet: diamondCutFacet, accountFacet: accountFacet, k1Facet: k1Facet, r1Facet: r1Facet, facetRegistry: facetRegistry, barz: barz + } +} + +export const addAccountFacet = async (barz: Barz, accountFacet: AccountFacet, entryPoint: SignerWithAddress) => { + const accountCut = diamondCut(accountFacet.address, FacetCutAction.Add, accountFacet) + const diamondCutBarz = await getFacetBarz("DiamondCutFacet", barz) + const tx = await diamondCutBarz.connect(entryPoint).diamondCut(accountCut, AddressZero, "0x00") + const receipt = await tx.wait() + expect(receipt.status).to.equal(1) + const accountBarz = await getAccountBarz(barz) + return accountBarz +} + +export const getAccountBarz = async (barz: Barz | string) => { + if (typeof barz == "string") + return ethers.getContractAt("AccountFacet", barz) + else + return ethers.getContractAt("AccountFacet", barz.address) +} + +export const getFacetBarz = async (facetName: string, barz: Barz) => { + return ethers.getContractAt(facetName, barz.address) as any +} + +export const addFacetSelectors = async (barz: Barz, facet: any, selectors: any, entryPoint: SignerWithAddress) => { + const cut = diamondCut(facet.address, FacetCutAction.Add, selectors) + const diamondCutBarz = await getFacetBarz('DiamondCutFacet', barz) + const accountBarz = await getFacetBarz('AccountFacet', barz) + const diamondCutCall = diamondCutBarz.interface.encodeFunctionData("diamondCut", [cut, AddressZero, "0x00"]) + const tx = await accountBarz.connect(entryPoint).execute(barz.address, 0, diamondCutCall) + const receipt = await tx.wait() + return receipt +} + +export const setupDefaultSecuritManager = async ( + securityManagerOwner: SignerWithAddress +) => { + const securityManager = await securityManagerFixture(securityManagerOwner.address) + await securityManager.connect(securityManagerOwner).initializeSecurityWindow(guardianSecurityWindow, minGuardianSecurityWindow, maxGuardianSecurityWindow) + await securityManager.connect(securityManagerOwner).initializeAdditionSecurityPeriod(guardianSecurityPeriod, minGuardianSecurityPeriod, maxGuardianSecurityPeriod) + await securityManager.connect(securityManagerOwner).initializeRemovalSecurityPeriod(guardianSecurityPeriod, minGuardianSecurityPeriod, maxGuardianSecurityPeriod) + await securityManager.connect(securityManagerOwner).initializeRecoveryPeriod(recoveryPeriod, minRecoveryPeriod, maxRecoveryPeriod) + await securityManager.connect(securityManagerOwner).initializeLockPeriod(lockPeriod, minLockPeriod, maxLockPeriod) + await securityManager.connect(securityManagerOwner).initializeMigrationPeriod(migrationPeriod, minMigrationPeriod, maxMigrationPeriod) + await securityManager.connect(securityManagerOwner).initializeApprovalValidationPeriod(approvalValidationPeriod, minApprovalValidationPeriod, maxApprovalValidationPeriod) + + return securityManager +} + +export const setupSecurityManager = async ( + securityManagerOwner: SignerWithAddress, + minSecurityPeriod: number, + maxSecurityPeriod: number, + securityPeriod: number, + minSecurityWindow: number, + maxSecurityWindow: number, + securityWindow: number, + minRecoveryPeriod: number, + maxRecoveryPeriod: number, + recoveryPeriod: number, + minLockPeriod: number, + maxLockPeriod: number, + lockPeriod: number, + minApprovalValidationPeriod: number, + maxApprovalValidationPeriod: number, + approvalValidationPeriod: number, + minMigrationPeriod: number, + maxMigrationPeriod: number, + migrationPeriod: number +) => { + const securityManager = await securityManagerFixture(securityManagerOwner.address) + await securityManager.connect(securityManagerOwner).initializeSecurityWindow(securityWindow, minSecurityWindow, maxSecurityWindow) + await securityManager.connect(securityManagerOwner).initializeAdditionSecurityPeriod(securityPeriod, minSecurityPeriod, maxSecurityPeriod) + await securityManager.connect(securityManagerOwner).initializeRemovalSecurityPeriod(securityPeriod, minSecurityPeriod, maxSecurityPeriod) + await securityManager.connect(securityManagerOwner).initializeRecoveryPeriod(recoveryPeriod, minRecoveryPeriod, maxRecoveryPeriod) + await securityManager.connect(securityManagerOwner).initializeLockPeriod(lockPeriod, minLockPeriod, maxLockPeriod) + await securityManager.connect(securityManagerOwner).initializeMigrationPeriod(migrationPeriod, minMigrationPeriod, maxMigrationPeriod) + await securityManager.connect(securityManagerOwner).initializeApprovalValidationPeriod(approvalValidationPeriod, minApprovalValidationPeriod, maxApprovalValidationPeriod) + + return securityManager +} + +export const addFacetSelectorsViaEntryPointOnK1 = async (barz: Barz, owner: any, facet: any, selectors: any, entryPoint: EntryPoint) => { + const cut = diamondCut(facet.address, FacetCutAction.Add, selectors) + const diamondCutBarz = await getFacetBarz('DiamondCutFacet', barz) + const accountFacetBarz = await getFacetBarz('AccountFacet', barz) + const callData = diamondCutBarz.interface.encodeFunctionData("diamondCut", [cut, AddressZero, "0x00"]) + const wrappedCallData = executeCallData(barz.address, 0, callData) + return callFromEntryPointOnK1(entryPoint, barz.address, owner, wrappedCallData, await accountFacetBarz.getNonce()) +} + +export const addFacetSelectorsViaEntryPointOnR1 = async (barz: Barz, keyPair: any, facet: any, selectors: any, entryPoint: EntryPoint) => { + const cut = diamondCut(facet.address, FacetCutAction.Add, selectors) + const diamondCutBarz = await getFacetBarz('DiamondCutFacet', barz) + const accountFacetBarz = await getFacetBarz('AccountFacet', barz) + const callData = diamondCutBarz.interface.encodeFunctionData("diamondCut", [cut, AddressZero, "0x00"]) + const wrappedCallData = executeCallData(barz.address, 0, callData) + return callFromEntryPointOnR1(entryPoint, barz.address, keyPair, wrappedCallData, await accountFacetBarz.getNonce()) +} \ No newline at end of file diff --git a/test/utils/solidityTypes.ts b/test/utils/solidityTypes.ts new file mode 100644 index 0000000..5026ef9 --- /dev/null +++ b/test/utils/solidityTypes.ts @@ -0,0 +1,10 @@ +// define the same export types as used by export typechain/ethers +import { BigNumberish } from 'ethers' +import { BytesLike } from '@ethersproject/bytes' + +export type address = string +export type uint256 = BigNumberish +export type uint = BigNumberish +export type uint48 = BigNumberish +export type bytes = BytesLike +export type bytes32 = BytesLike diff --git a/test/utils/testutils.ts b/test/utils/testutils.ts new file mode 100644 index 0000000..eda3cc0 --- /dev/null +++ b/test/utils/testutils.ts @@ -0,0 +1,153 @@ +import { ethers } from 'hardhat' +import { + arrayify, + keccak256, + parseEther +} from 'ethers/lib/utils' +import { BigNumber, Contract, Wallet } from 'ethers' + + +export const AddressZero = ethers.constants.AddressZero +export const AddressOne = "0x0000000000000000000000000000000000000001" +export const HashZero = ethers.constants.HashZero +export const ONE_ETH = parseEther('1') +export const TWO_ETH = parseEther('2') +export const FIVE_ETH = parseEther('5') +export const callGasLimit = 2000000 +export const verificationGasLimit = 1000000 +export const maxFeePerGas = 1 + +const panicCodes: { [key: number]: string } = { + // from https://docs.soliditylang.org/en/v0.8.0/control-structures.html + 0x01: 'assert(false)', + 0x11: 'arithmetic overflow/underflow', + 0x12: 'divide by zero', + 0x21: 'invalid enum value', + 0x22: 'storage byte array that is incorrectly encoded', + 0x31: '.pop() on an empty array.', + 0x32: 'array sout-of-bounds or negative index', + 0x41: 'memory overflow', + 0x51: 'zero-initialized variable of internal function type' +} +export function callDataCost(data: string): number { + return ethers.utils.arrayify(data) + .map(x => x === 0 ? 4 : 16) + .reduce((sum, x) => sum + x) +} +export function rethrow(): (e: Error) => void { + const callerStack = new Error().stack!.replace(/Error.*\n.*at.*\n/, '').replace(/.*at.* \(internal[\s\S]*/, '') + + if (arguments[0] != null) { + throw new Error('must use .catch(rethrow()), and NOT .catch(rethrow)') + } + return function (e: Error) { + const solstack = e.stack!.match(/((?:.* at .*\.sol.*\n)+)/) + const stack = (solstack != null ? solstack[1] : '') + callerStack + // const regex = new RegExp('error=.*"data":"(.*?)"').compile() + const found = /error=.*?"data":"(.*?)"/.exec(e.message) + let message: string + if (found != null) { + const data = found[1] + message = decodeRevertReason(data) ?? e.message + ' - ' + data.slice(0, 100) + } else { + message = e.message + } + const err = new Error(message) + err.stack = 'Error: ' + message + '\n' + stack + throw err + } +} + +// just throw 1eth from account[0] to the given address (or contract instance) +export async function fund(contractOrAddress: string | Contract, amountEth = '1'): Promise { + let address: string + if (typeof contractOrAddress === 'string') { + address = contractOrAddress + } else { + address = contractOrAddress.address + } + await ethers.provider.getSigner().sendTransaction({ to: address, value: parseEther(amountEth) }) +} +export function decodeRevertReason(data: string, nullIfNoMatch = true): string | null { + const methodSig = data.slice(0, 10) + const dataParams = '0x' + data.slice(10) + + if (methodSig === '0x08c379a0') { + const [err] = ethers.utils.defaultAbiCoder.decode(['string'], dataParams) + // eslint-disable-next-line @typescript-eslint/restrict-template-expressions + return `Error(${err})` + } else if (methodSig === '0x00fa072b') { + const [opindex, paymaster, msg] = ethers.utils.defaultAbiCoder.decode(['uint256', 'address', 'string'], dataParams) + // eslint-disable-next-line @typescript-eslint/restrict-template-expressions + return `FailedOp(${opindex}, ${paymaster !== AddressZero ? paymaster : 'none'}, ${msg})` + } else if (methodSig === '0x4e487b71') { + const [code] = ethers.utils.defaultAbiCoder.decode(['uint256'], dataParams) + return `Panic(${panicCodes[code] ?? code} + ')` + } + if (!nullIfNoMatch) { + return data + } + return null +} + +// create non-random account, so gas calculations are deterministic +export function createAccountOwner(seed = 3): Wallet { + const privateKey = keccak256(Buffer.from(arrayify(BigNumber.from(seed)))) + return new ethers.Wallet(privateKey, ethers.provider) + // return new ethers.Wallet('0x'.padEnd(66, privkeyBase), ethers.provider); +} +// keccak256( +// "EIP712Domain(uint256 chainId,address verifyingContract)" +// ); +const DOMAIN_SEPARATOR_TYPEHASH = '0x47e79534a245952e8b16893a336b85a3d9ea9fa8c573f3d803afb92a79469218' + +// keccak256("BarzMessage(bytes message)") +const BARZ_MSG_HASH = '0xb1bcb804a4a3a1af3ee7920d949bdfd417ea1b736c3552c8d6563a229a619100' +export async function domainSeparator(chainId: any, contractAddress: any) { + return ethers.utils.keccak256( + ethers.utils.defaultAbiCoder.encode( + ["bytes32", "uint256", "address"], + [DOMAIN_SEPARATOR_TYPEHASH, chainId, contractAddress] + ) + ); +} + +export async function encodeMessageData(message: any, chainId: any, contractAddress: any) { + const messageHash = ethers.utils.keccak256( + ethers.utils.defaultAbiCoder.encode( + ["bytes32", "bytes32"], + [BARZ_MSG_HASH, ethers.utils.keccak256(message)] + ) + ); + const _domainSeparator = await domainSeparator(chainId, contractAddress); + return ethers.utils.solidityPack(["bytes1", "bytes1", "bytes32", "bytes32"], ["0x19", "0x01", _domainSeparator, messageHash]); +} + +export async function getMessageHash(message: any, chainId: any, contractAddress: any) { + const encodedMessage = ethers.utils.defaultAbiCoder.encode(["bytes32"], [message]); + const encodedMessageData = await encodeMessageData(encodedMessage, chainId, contractAddress); + return ethers.utils.keccak256(encodedMessageData); +} + +export function generateExampleMsgHash() { + const enc = ethers.utils.defaultAbiCoder.encode(['string'], ["LOGIN to TW Wallet Timestamp:1683119999"]) + return ethers.utils.keccak256(enc) +} + +export function sortSignatures(mapping: any): string { + let signatures = "" + Object.keys(mapping) + .sort((a, b) => a.localeCompare(b)) + .forEach(key => { + signatures += mapping[key] + }); + return "0x" + signatures.replace("undefined", "") +} + +export function removePrefix(bytes: string): string { + return bytes.replace("0x", "") +} + +export function addPrefix(bytes: string): string { + return "0x" + bytes +} \ No newline at end of file diff --git a/test/utils/webauthn.ts b/test/utils/webauthn.ts new file mode 100644 index 0000000..50ac401 --- /dev/null +++ b/test/utils/webauthn.ts @@ -0,0 +1,69 @@ + +import elliptic from 'elliptic'; +const EC = elliptic.ec; +const ec = new EC('p256'); +import * as cbor from './cbor'; +import { hexToBuf, parseAuthData } from './base64-helpers'; +import { AsnParser } from '@peculiar/asn1-schema'; +import { ECDSASigValue } from '@peculiar/asn1-ecc'; + +enum COSEKEYS { + kty = 1, + alg = 3, + crv = -1, + x = -2, + y = -3, + n = -1, + e = -2, + } + +export const getPublicKey = async (attestationObjectHex: string) => { + const attestationObject = hexToBuf(attestationObjectHex) + const authData = cbor.decode(attestationObject, undefined, undefined) + .authData as Uint8Array; + + const authDataParsed = parseAuthData(authData); + + const pubk = cbor.decode( + authDataParsed.COSEPublicKey.buffer, + undefined, + undefined + ); + + const x = pubk[COSEKEYS.x]; + const y = pubk[COSEKEYS.y]; + + const pk = ec.keyFromPublic({ x, y }); + + return [ + '0x' + pk.getPublic('hex').slice(2, 66), + '0x' + pk.getPublic('hex').slice(-64), + ]; + }; + + export const getRSValues = async (signature: string) => { + const parsedSignature = AsnParser.parse( + hexToBuf(signature), + ECDSASigValue + ); + + let rBytes = new Uint8Array(parsedSignature.r); + let sBytes = new Uint8Array(parsedSignature.s); + + if (shouldRemoveLeadingZero(rBytes)) { + rBytes = rBytes.slice(1); + } + + if (shouldRemoveLeadingZero(sBytes)) { + sBytes = sBytes.slice(1); + } + + return [ + '0x' + Buffer.from(rBytes).toString('hex'), + '0x' + Buffer.from(sBytes).toString('hex'), + ]; + } + + export function shouldRemoveLeadingZero(bytes: Uint8Array): boolean { + return bytes[0] === 0x0 && (bytes[1] & (1 << 7)) !== 0; + } \ No newline at end of file diff --git a/test/webauthn.test.ts b/test/webauthn.test.ts new file mode 100644 index 0000000..acc0b50 --- /dev/null +++ b/test/webauthn.test.ts @@ -0,0 +1,21 @@ +import * as webauthn from "./utils/webauthn" +import { expect } from "chai" + +describe('Webauthn utils tests', () => { + + it("Should extract Q values from the attestation object", async () => { + const attestationObject = "a363666d74646e6f6e656761747453746d74a068617574684461746158a4f95bc73828ee210f9fd3bbe72d97908013b0a3759e9aea3d0ae318766cd2e1ad4500000000adce000235bcc60a648b0b25f1f055030020c720eb493e167ce93183dd91f5661e1004ed8cc1be23d3340d92381da5c0c80ca5010203262001215820a620a8cfc88fd062b11eab31663e56cad95278bef612959be214d98779f645b82258204e7b905b42917570148b0432f99ba21f2e7eebe018cbf837247e38150a89f771" + const q = await webauthn.getPublicKey(attestationObject) + expect(q[0]).to.equal("0xa620a8cfc88fd062b11eab31663e56cad95278bef612959be214d98779f645b8") + expect(q[1]).to.equal("0x4e7b905b42917570148b0432f99ba21f2e7eebe018cbf837247e38150a89f771") + expect(q.length).to.equal(2) + }) + + it("Should extract R and S values from the signature", async () => { + const signature = "3046022100db421231f23d0320dbb8f1284b600cd34b8e9218628139539ff4f1f6c05495da022100ff715aab70d5317dbf8ee224eb18bec3120cfb9db1000dbb31eadaf96c71c1b1" + const rs = await webauthn.getRSValues(signature) + expect(rs[0]).to.equal("0xdb421231f23d0320dbb8f1284b600cd34b8e9218628139539ff4f1f6c05495da") + expect(rs[1]).to.equal("0xff715aab70d5317dbf8ee224eb18bec3120cfb9db1000dbb31eadaf96c71c1b1") + expect(rs.length).to.equal(2) + }) +}) \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..9528edd --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,13 @@ +{ + "compilerOptions": { + "target": "es2020", + "module": "commonjs", + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "skipLibCheck": true, + "resolveJsonModule": true + }, + "include": ["./scripts", "./test", "./typechain-types", "./*.config.ts", "./deploy"], + "files": ["./hardhat.config.ts"] +} diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000..0582126 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,5042 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@aashutoshrathi/word-wrap@^1.2.3": + version "1.2.6" + resolved "https://registry.yarnpkg.com/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz#bd9154aec9983f77b3a034ecaa015c2e4201f6cf" + integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== + +"@account-abstraction/contracts@^0.6.0": + version "0.6.0" + resolved "https://registry.yarnpkg.com/@account-abstraction/contracts/-/contracts-0.6.0.tgz#7188a01839999226e6b2796328af338329543b76" + integrity sha512-8ooRJuR7XzohMDM4MV34I12Ci2bmxfE9+cixakRL7lA4BAwJKQ3ahvd8FbJa9kiwkUPCUNtj+/zxDQWYYalLMQ== + +"@account-abstraction/utils@^0.6.0": + version "0.6.0" + resolved "https://registry.yarnpkg.com/@account-abstraction/utils/-/utils-0.6.0.tgz#78682b3e2c0adf64668ae23ba7aeae0d31e79022" + integrity sha512-K99c3TNrKjxXDkLLAYOP6DCg0v0FGqQmSQh+NCC9R44k8OOzQ7aOrfOxAqhRYWvhZnNiI4+BVdSrkvyzAXaLJw== + dependencies: + "@account-abstraction/contracts" "^0.6.0" + "@ethersproject/abi" "^5.7.0" + "@ethersproject/providers" "^5.7.0" + "@openzeppelin/contracts" "^4.7.3" + debug "^4.3.4" + ethers "^5.7.0" + +"@babel/code-frame@^7.0.0": + version "7.22.13" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.22.13.tgz#e3c1c099402598483b7a8c46a721d1038803755e" + integrity sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w== + dependencies: + "@babel/highlight" "^7.22.13" + chalk "^2.4.2" + +"@babel/helper-validator-identifier@^7.22.20": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz#c4ae002c61d2879e724581d96665583dbc1dc0e0" + integrity sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A== + +"@babel/highlight@^7.22.13": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.22.20.tgz#4ca92b71d80554b01427815e06f2df965b9c1f54" + integrity sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg== + dependencies: + "@babel/helper-validator-identifier" "^7.22.20" + chalk "^2.4.2" + js-tokens "^4.0.0" + +"@chainsafe/as-sha256@^0.3.1": + version "0.3.1" + resolved "https://registry.yarnpkg.com/@chainsafe/as-sha256/-/as-sha256-0.3.1.tgz#3639df0e1435cab03f4d9870cc3ac079e57a6fc9" + integrity sha512-hldFFYuf49ed7DAakWVXSJODuq3pzJEguD8tQ7h+sGkM18vja+OFoJI9krnGmgzyuZC2ETX0NOIcCTy31v2Mtg== + +"@chainsafe/persistent-merkle-tree@^0.4.2": + version "0.4.2" + resolved "https://registry.yarnpkg.com/@chainsafe/persistent-merkle-tree/-/persistent-merkle-tree-0.4.2.tgz#4c9ee80cc57cd3be7208d98c40014ad38f36f7ff" + integrity sha512-lLO3ihKPngXLTus/L7WHKaw9PnNJWizlOF1H9NNzHP6Xvh82vzg9F2bzkXhYIFshMZ2gTCEz8tq6STe7r5NDfQ== + dependencies: + "@chainsafe/as-sha256" "^0.3.1" + +"@chainsafe/persistent-merkle-tree@^0.5.0": + version "0.5.0" + resolved "https://registry.yarnpkg.com/@chainsafe/persistent-merkle-tree/-/persistent-merkle-tree-0.5.0.tgz#2b4a62c9489a5739dedd197250d8d2f5427e9f63" + integrity sha512-l0V1b5clxA3iwQLXP40zYjyZYospQLZXzBVIhhr9kDg/1qHZfzzHw0jj4VPBijfYCArZDlPkRi1wZaV2POKeuw== + dependencies: + "@chainsafe/as-sha256" "^0.3.1" + +"@chainsafe/ssz@^0.10.0": + version "0.10.2" + resolved "https://registry.yarnpkg.com/@chainsafe/ssz/-/ssz-0.10.2.tgz#c782929e1bb25fec66ba72e75934b31fd087579e" + integrity sha512-/NL3Lh8K+0q7A3LsiFq09YXS9fPE+ead2rr7vM2QK8PLzrNsw3uqrif9bpRX5UxgeRjM+vYi+boCM3+GM4ovXg== + dependencies: + "@chainsafe/as-sha256" "^0.3.1" + "@chainsafe/persistent-merkle-tree" "^0.5.0" + +"@chainsafe/ssz@^0.9.2": + version "0.9.4" + resolved "https://registry.yarnpkg.com/@chainsafe/ssz/-/ssz-0.9.4.tgz#696a8db46d6975b600f8309ad3a12f7c0e310497" + integrity sha512-77Qtg2N1ayqs4Bg/wvnWfg5Bta7iy7IRh8XqXh7oNMeP2HBbBwx8m6yTpA8p0EHItWPEBkgZd5S5/LSlp3GXuQ== + dependencies: + "@chainsafe/as-sha256" "^0.3.1" + "@chainsafe/persistent-merkle-tree" "^0.4.2" + case "^1.6.3" + +"@colors/colors@1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9" + integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ== + +"@cspotcode/source-map-support@^0.8.0": + version "0.8.1" + resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" + integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw== + dependencies: + "@jridgewell/trace-mapping" "0.3.9" + +"@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0": + version "4.4.0" + resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" + integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== + dependencies: + eslint-visitor-keys "^3.3.0" + +"@eslint-community/regexpp@^4.5.1", "@eslint-community/regexpp@^4.6.1": + version "4.9.1" + resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.9.1.tgz#449dfa81a57a1d755b09aa58d826c1262e4283b4" + integrity sha512-Y27x+MBLjXa+0JWDhykM3+JE+il3kHKAEqabfEWq3SDhZjLYb6/BHL/JKFnH3fe207JaXkyDo685Oc2Glt6ifA== + +"@eslint/eslintrc@^2.1.2": + version "2.1.2" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.1.2.tgz#c6936b4b328c64496692f76944e755738be62396" + integrity sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g== + dependencies: + ajv "^6.12.4" + debug "^4.3.2" + espree "^9.6.0" + globals "^13.19.0" + ignore "^5.2.0" + import-fresh "^3.2.1" + js-yaml "^4.1.0" + minimatch "^3.1.2" + strip-json-comments "^3.1.1" + +"@eslint/js@8.51.0": + version "8.51.0" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.51.0.tgz#6d419c240cfb2b66da37df230f7e7eef801c32fa" + integrity sha512-HxjQ8Qn+4SI3/AFv6sOrDB+g6PpUTDwSJiQqOrnneEk8L71161srI9gjzzZvYVbzHiVg/BvcH95+cK/zfIt4pg== + +"@ethereumjs/rlp@^4.0.1": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@ethereumjs/rlp/-/rlp-4.0.1.tgz#626fabfd9081baab3d0a3074b0c7ecaf674aaa41" + integrity sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw== + +"@ethereumjs/util@^8.1.0": + version "8.1.0" + resolved "https://registry.yarnpkg.com/@ethereumjs/util/-/util-8.1.0.tgz#299df97fb6b034e0577ce9f94c7d9d1004409ed4" + integrity sha512-zQ0IqbdX8FZ9aw11vP+dZkKDkS+kgIvQPHnSAXzP9pLu+Rfu3D3XEeLbicvoXJTYnhZiPmsZUxgdzXwNKxRPbA== + dependencies: + "@ethereumjs/rlp" "^4.0.1" + ethereum-cryptography "^2.0.0" + micro-ftch "^0.3.1" + +"@ethersproject/abi@5.7.0", "@ethersproject/abi@^5.0.9", "@ethersproject/abi@^5.1.2", "@ethersproject/abi@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.7.0.tgz#b3f3e045bbbeed1af3947335c247ad625a44e449" + integrity sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA== + dependencies: + "@ethersproject/address" "^5.7.0" + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/constants" "^5.7.0" + "@ethersproject/hash" "^5.7.0" + "@ethersproject/keccak256" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/strings" "^5.7.0" + +"@ethersproject/abstract-provider@5.7.0", "@ethersproject/abstract-provider@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz#b0a8550f88b6bf9d51f90e4795d48294630cb9ef" + integrity sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw== + dependencies: + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/networks" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/transactions" "^5.7.0" + "@ethersproject/web" "^5.7.0" + +"@ethersproject/abstract-signer@5.7.0", "@ethersproject/abstract-signer@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz#13f4f32117868452191a4649723cb086d2b596b2" + integrity sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ== + dependencies: + "@ethersproject/abstract-provider" "^5.7.0" + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + +"@ethersproject/address@5.7.0", "@ethersproject/address@^5.0.2", "@ethersproject/address@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.7.0.tgz#19b56c4d74a3b0a46bfdbb6cfcc0a153fc697f37" + integrity sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA== + dependencies: + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/keccak256" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/rlp" "^5.7.0" + +"@ethersproject/base64@5.7.0", "@ethersproject/base64@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/base64/-/base64-5.7.0.tgz#ac4ee92aa36c1628173e221d0d01f53692059e1c" + integrity sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ== + dependencies: + "@ethersproject/bytes" "^5.7.0" + +"@ethersproject/basex@5.7.0", "@ethersproject/basex@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/basex/-/basex-5.7.0.tgz#97034dc7e8938a8ca943ab20f8a5e492ece4020b" + integrity sha512-ywlh43GwZLv2Voc2gQVTKBoVQ1mti3d8HK5aMxsfu/nRDnMmNqaSJ3r3n85HBByT8OpoY96SXM1FogC533T4zw== + dependencies: + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + +"@ethersproject/bignumber@5.7.0", "@ethersproject/bignumber@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.7.0.tgz#e2f03837f268ba655ffba03a57853e18a18dc9c2" + integrity sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw== + dependencies: + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + bn.js "^5.2.1" + +"@ethersproject/bytes@5.7.0", "@ethersproject/bytes@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.7.0.tgz#a00f6ea8d7e7534d6d87f47188af1148d71f155d" + integrity sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A== + dependencies: + "@ethersproject/logger" "^5.7.0" + +"@ethersproject/constants@5.7.0", "@ethersproject/constants@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/constants/-/constants-5.7.0.tgz#df80a9705a7e08984161f09014ea012d1c75295e" + integrity sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA== + dependencies: + "@ethersproject/bignumber" "^5.7.0" + +"@ethersproject/contracts@5.7.0", "@ethersproject/contracts@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/contracts/-/contracts-5.7.0.tgz#c305e775abd07e48aa590e1a877ed5c316f8bd1e" + integrity sha512-5GJbzEU3X+d33CdfPhcyS+z8MzsTrBGk/sc+G+59+tPa9yFkl6HQ9D6L0QMgNTA9q8dT0XKxxkyp883XsQvbbg== + dependencies: + "@ethersproject/abi" "^5.7.0" + "@ethersproject/abstract-provider" "^5.7.0" + "@ethersproject/abstract-signer" "^5.7.0" + "@ethersproject/address" "^5.7.0" + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/constants" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/transactions" "^5.7.0" + +"@ethersproject/hash@5.7.0", "@ethersproject/hash@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/hash/-/hash-5.7.0.tgz#eb7aca84a588508369562e16e514b539ba5240a7" + integrity sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g== + dependencies: + "@ethersproject/abstract-signer" "^5.7.0" + "@ethersproject/address" "^5.7.0" + "@ethersproject/base64" "^5.7.0" + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/keccak256" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/strings" "^5.7.0" + +"@ethersproject/hdnode@5.7.0", "@ethersproject/hdnode@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/hdnode/-/hdnode-5.7.0.tgz#e627ddc6b466bc77aebf1a6b9e47405ca5aef9cf" + integrity sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg== + dependencies: + "@ethersproject/abstract-signer" "^5.7.0" + "@ethersproject/basex" "^5.7.0" + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/pbkdf2" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/sha2" "^5.7.0" + "@ethersproject/signing-key" "^5.7.0" + "@ethersproject/strings" "^5.7.0" + "@ethersproject/transactions" "^5.7.0" + "@ethersproject/wordlists" "^5.7.0" + +"@ethersproject/json-wallets@5.7.0", "@ethersproject/json-wallets@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/json-wallets/-/json-wallets-5.7.0.tgz#5e3355287b548c32b368d91014919ebebddd5360" + integrity sha512-8oee5Xgu6+RKgJTkvEMl2wDgSPSAQ9MB/3JYjFV9jlKvcYHUXZC+cQp0njgmxdHkYWn8s6/IqIZYm0YWCjO/0g== + dependencies: + "@ethersproject/abstract-signer" "^5.7.0" + "@ethersproject/address" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/hdnode" "^5.7.0" + "@ethersproject/keccak256" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/pbkdf2" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/random" "^5.7.0" + "@ethersproject/strings" "^5.7.0" + "@ethersproject/transactions" "^5.7.0" + aes-js "3.0.0" + scrypt-js "3.0.1" + +"@ethersproject/keccak256@5.7.0", "@ethersproject/keccak256@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.7.0.tgz#3186350c6e1cd6aba7940384ec7d6d9db01f335a" + integrity sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg== + dependencies: + "@ethersproject/bytes" "^5.7.0" + js-sha3 "0.8.0" + +"@ethersproject/logger@5.7.0", "@ethersproject/logger@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.7.0.tgz#6ce9ae168e74fecf287be17062b590852c311892" + integrity sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig== + +"@ethersproject/networks@5.7.1", "@ethersproject/networks@^5.7.0": + version "5.7.1" + resolved "https://registry.yarnpkg.com/@ethersproject/networks/-/networks-5.7.1.tgz#118e1a981d757d45ccea6bb58d9fd3d9db14ead6" + integrity sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ== + dependencies: + "@ethersproject/logger" "^5.7.0" + +"@ethersproject/pbkdf2@5.7.0", "@ethersproject/pbkdf2@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/pbkdf2/-/pbkdf2-5.7.0.tgz#d2267d0a1f6e123f3771007338c47cccd83d3102" + integrity sha512-oR/dBRZR6GTyaofd86DehG72hY6NpAjhabkhxgr3X2FpJtJuodEl2auADWBZfhDHgVCbu3/H/Ocq2uC6dpNjjw== + dependencies: + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/sha2" "^5.7.0" + +"@ethersproject/properties@5.7.0", "@ethersproject/properties@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.7.0.tgz#a6e12cb0439b878aaf470f1902a176033067ed30" + integrity sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw== + dependencies: + "@ethersproject/logger" "^5.7.0" + +"@ethersproject/providers@5.7.2", "@ethersproject/providers@^5.4.7", "@ethersproject/providers@^5.7.0", "@ethersproject/providers@^5.7.1", "@ethersproject/providers@^5.7.2": + version "5.7.2" + resolved "https://registry.yarnpkg.com/@ethersproject/providers/-/providers-5.7.2.tgz#f8b1a4f275d7ce58cf0a2eec222269a08beb18cb" + integrity sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg== + dependencies: + "@ethersproject/abstract-provider" "^5.7.0" + "@ethersproject/abstract-signer" "^5.7.0" + "@ethersproject/address" "^5.7.0" + "@ethersproject/base64" "^5.7.0" + "@ethersproject/basex" "^5.7.0" + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/constants" "^5.7.0" + "@ethersproject/hash" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/networks" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/random" "^5.7.0" + "@ethersproject/rlp" "^5.7.0" + "@ethersproject/sha2" "^5.7.0" + "@ethersproject/strings" "^5.7.0" + "@ethersproject/transactions" "^5.7.0" + "@ethersproject/web" "^5.7.0" + bech32 "1.1.4" + ws "7.4.6" + +"@ethersproject/random@5.7.0", "@ethersproject/random@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/random/-/random-5.7.0.tgz#af19dcbc2484aae078bb03656ec05df66253280c" + integrity sha512-19WjScqRA8IIeWclFme75VMXSBvi4e6InrUNuaR4s5pTF2qNhcGdCUwdxUVGtDDqC00sDLCO93jPQoDUH4HVmQ== + dependencies: + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + +"@ethersproject/rlp@5.7.0", "@ethersproject/rlp@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.7.0.tgz#de39e4d5918b9d74d46de93af80b7685a9c21304" + integrity sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w== + dependencies: + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + +"@ethersproject/sha2@5.7.0", "@ethersproject/sha2@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/sha2/-/sha2-5.7.0.tgz#9a5f7a7824ef784f7f7680984e593a800480c9fb" + integrity sha512-gKlH42riwb3KYp0reLsFTokByAKoJdgFCwI+CCiX/k+Jm2mbNs6oOaCjYQSlI1+XBVejwH2KrmCbMAT/GnRDQw== + dependencies: + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + hash.js "1.1.7" + +"@ethersproject/signing-key@5.7.0", "@ethersproject/signing-key@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/signing-key/-/signing-key-5.7.0.tgz#06b2df39411b00bc57c7c09b01d1e41cf1b16ab3" + integrity sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q== + dependencies: + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + bn.js "^5.2.1" + elliptic "6.5.4" + hash.js "1.1.7" + +"@ethersproject/solidity@5.7.0", "@ethersproject/solidity@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/solidity/-/solidity-5.7.0.tgz#5e9c911d8a2acce2a5ebb48a5e2e0af20b631cb8" + integrity sha512-HmabMd2Dt/raavyaGukF4XxizWKhKQ24DoLtdNbBmNKUOPqwjsKQSdV9GQtj9CBEea9DlzETlVER1gYeXXBGaA== + dependencies: + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/keccak256" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/sha2" "^5.7.0" + "@ethersproject/strings" "^5.7.0" + +"@ethersproject/strings@5.7.0", "@ethersproject/strings@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.7.0.tgz#54c9d2a7c57ae8f1205c88a9d3a56471e14d5ed2" + integrity sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg== + dependencies: + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/constants" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + +"@ethersproject/transactions@5.7.0", "@ethersproject/transactions@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/transactions/-/transactions-5.7.0.tgz#91318fc24063e057885a6af13fdb703e1f993d3b" + integrity sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ== + dependencies: + "@ethersproject/address" "^5.7.0" + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/constants" "^5.7.0" + "@ethersproject/keccak256" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/rlp" "^5.7.0" + "@ethersproject/signing-key" "^5.7.0" + +"@ethersproject/units@5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/units/-/units-5.7.0.tgz#637b563d7e14f42deeee39245275d477aae1d8b1" + integrity sha512-pD3xLMy3SJu9kG5xDGI7+xhTEmGXlEqXU4OfNapmfnxLVY4EMSSRp7j1k7eezutBPH7RBN/7QPnwR7hzNlEFeg== + dependencies: + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/constants" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + +"@ethersproject/wallet@5.7.0", "@ethersproject/wallet@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/wallet/-/wallet-5.7.0.tgz#4e5d0790d96fe21d61d38fb40324e6c7ef350b2d" + integrity sha512-MhmXlJXEJFBFVKrDLB4ZdDzxcBxQ3rLyCkhNqVu3CDYvR97E+8r01UgrI+TI99Le+aYm/in/0vp86guJuM7FCA== + dependencies: + "@ethersproject/abstract-provider" "^5.7.0" + "@ethersproject/abstract-signer" "^5.7.0" + "@ethersproject/address" "^5.7.0" + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/hash" "^5.7.0" + "@ethersproject/hdnode" "^5.7.0" + "@ethersproject/json-wallets" "^5.7.0" + "@ethersproject/keccak256" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/random" "^5.7.0" + "@ethersproject/signing-key" "^5.7.0" + "@ethersproject/transactions" "^5.7.0" + "@ethersproject/wordlists" "^5.7.0" + +"@ethersproject/web@5.7.1", "@ethersproject/web@^5.7.0": + version "5.7.1" + resolved "https://registry.yarnpkg.com/@ethersproject/web/-/web-5.7.1.tgz#de1f285b373149bee5928f4eb7bcb87ee5fbb4ae" + integrity sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w== + dependencies: + "@ethersproject/base64" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/strings" "^5.7.0" + +"@ethersproject/wordlists@5.7.0", "@ethersproject/wordlists@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/wordlists/-/wordlists-5.7.0.tgz#8fb2c07185d68c3e09eb3bfd6e779ba2774627f5" + integrity sha512-S2TFNJNfHWVHNE6cNDjbVlZ6MgE17MIxMbMg2zv3wn+3XSJGosL1m9ZVv3GXCf/2ymSsQ+hRI5IzoMJTG6aoVA== + dependencies: + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/hash" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/strings" "^5.7.0" + +"@fastify/busboy@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@fastify/busboy/-/busboy-2.0.0.tgz#f22824caff3ae506b18207bad4126dbc6ccdb6b8" + integrity sha512-JUFJad5lv7jxj926GPgymrWQxxjPYuJNiNjNMzqT+HiuP6Vl3dk5xzG+8sTX96np0ZAluvaMzPsjhHZ5rNuNQQ== + +"@humanwhocodes/config-array@^0.11.11": + version "0.11.12" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.12.tgz#549afec9bfce5232ac6325db12765f407e70e3a0" + integrity sha512-NlGesA1usRNn6ctHCZ21M4/dKPgW9Nn1FypRdIKKgZOKzkVV4T1FlK5mBiLhHBCDmEbdQG0idrcXlbZfksJ+RA== + dependencies: + "@humanwhocodes/object-schema" "^2.0.0" + debug "^4.1.1" + minimatch "^3.0.5" + +"@humanwhocodes/module-importer@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" + integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== + +"@humanwhocodes/object-schema@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.0.tgz#04ad39d82176c7da1591c81e78b993cffd8348d8" + integrity sha512-9S9QrXY2K0L4AGDcSgTi9vgiCcG8VcBv4Mp7/1hDPYoswIy6Z6KO5blYto82BT8M0MZNRWmCFLpCs3HlpYGGdw== + +"@jridgewell/resolve-uri@^3.0.3": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz#c08679063f279615a3326583ba3a90d1d82cc721" + integrity sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA== + +"@jridgewell/sourcemap-codec@^1.4.10": + version "1.4.15" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" + integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== + +"@jridgewell/trace-mapping@0.3.9": + version "0.3.9" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9" + integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== + dependencies: + "@jridgewell/resolve-uri" "^3.0.3" + "@jridgewell/sourcemap-codec" "^1.4.10" + +"@metamask/eth-sig-util@^4.0.0": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@metamask/eth-sig-util/-/eth-sig-util-4.0.1.tgz#3ad61f6ea9ad73ba5b19db780d40d9aae5157088" + integrity sha512-tghyZKLHZjcdlDqCA3gNZmLeR0XvOE9U1qoQO9ohyAZT6Pya+H9vkBPcsyXytmYLNgVoin7CKCmweo/R43V+tQ== + dependencies: + ethereumjs-abi "^0.6.8" + ethereumjs-util "^6.2.1" + ethjs-util "^0.1.6" + tweetnacl "^1.0.3" + tweetnacl-util "^0.15.1" + +"@noble/curves@1.1.0", "@noble/curves@~1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.1.0.tgz#f13fc667c89184bc04cccb9b11e8e7bae27d8c3d" + integrity sha512-091oBExgENk/kGj3AZmtBDMpxQPDtxQABR2B9lb1JbVTs6ytdzZNwvhxQ4MWasRNEzlbEH8jCWFCwhF/Obj5AA== + dependencies: + "@noble/hashes" "1.3.1" + +"@noble/hashes@1.2.0", "@noble/hashes@~1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.2.0.tgz#a3150eeb09cc7ab207ebf6d7b9ad311a9bdbed12" + integrity sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ== + +"@noble/hashes@1.3.1": + version "1.3.1" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.1.tgz#8831ef002114670c603c458ab8b11328406953a9" + integrity sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA== + +"@noble/hashes@~1.3.0", "@noble/hashes@~1.3.1": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.2.tgz#6f26dbc8fbc7205873ce3cee2f690eba0d421b39" + integrity sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ== + +"@noble/secp256k1@1.7.1", "@noble/secp256k1@~1.7.0": + version "1.7.1" + resolved "https://registry.yarnpkg.com/@noble/secp256k1/-/secp256k1-1.7.1.tgz#b251c70f824ce3ca7f8dc3df08d58f005cc0507c" + integrity sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw== + +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== + dependencies: + "@nodelib/fs.stat" "2.0.5" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== + +"@nodelib/fs.walk@^1.2.3", "@nodelib/fs.walk@^1.2.8": + version "1.2.8" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== + dependencies: + "@nodelib/fs.scandir" "2.1.5" + fastq "^1.6.0" + +"@nomicfoundation/ethereumjs-block@5.0.2": + version "5.0.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-block/-/ethereumjs-block-5.0.2.tgz#13a7968f5964f1697da941281b7f7943b0465d04" + integrity sha512-hSe6CuHI4SsSiWWjHDIzWhSiAVpzMUcDRpWYzN0T9l8/Rz7xNn3elwVOJ/tAyS0LqL6vitUD78Uk7lQDXZun7Q== + dependencies: + "@nomicfoundation/ethereumjs-common" "4.0.2" + "@nomicfoundation/ethereumjs-rlp" "5.0.2" + "@nomicfoundation/ethereumjs-trie" "6.0.2" + "@nomicfoundation/ethereumjs-tx" "5.0.2" + "@nomicfoundation/ethereumjs-util" "9.0.2" + ethereum-cryptography "0.1.3" + ethers "^5.7.1" + +"@nomicfoundation/ethereumjs-blockchain@7.0.2": + version "7.0.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-blockchain/-/ethereumjs-blockchain-7.0.2.tgz#45323b673b3d2fab6b5008535340d1b8fea7d446" + integrity sha512-8UUsSXJs+MFfIIAKdh3cG16iNmWzWC/91P40sazNvrqhhdR/RtGDlFk2iFTGbBAZPs2+klZVzhRX8m2wvuvz3w== + dependencies: + "@nomicfoundation/ethereumjs-block" "5.0.2" + "@nomicfoundation/ethereumjs-common" "4.0.2" + "@nomicfoundation/ethereumjs-ethash" "3.0.2" + "@nomicfoundation/ethereumjs-rlp" "5.0.2" + "@nomicfoundation/ethereumjs-trie" "6.0.2" + "@nomicfoundation/ethereumjs-tx" "5.0.2" + "@nomicfoundation/ethereumjs-util" "9.0.2" + abstract-level "^1.0.3" + debug "^4.3.3" + ethereum-cryptography "0.1.3" + level "^8.0.0" + lru-cache "^5.1.1" + memory-level "^1.0.0" + +"@nomicfoundation/ethereumjs-common@4.0.2": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-4.0.2.tgz#a15d1651ca36757588fdaf2a7d381a150662a3c3" + integrity sha512-I2WGP3HMGsOoycSdOTSqIaES0ughQTueOsddJ36aYVpI3SN8YSusgRFLwzDJwRFVIYDKx/iJz0sQ5kBHVgdDwg== + dependencies: + "@nomicfoundation/ethereumjs-util" "9.0.2" + crc-32 "^1.2.0" + +"@nomicfoundation/ethereumjs-ethash@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-ethash/-/ethereumjs-ethash-3.0.2.tgz#da77147f806401ee996bfddfa6487500118addca" + integrity sha512-8PfoOQCcIcO9Pylq0Buijuq/O73tmMVURK0OqdjhwqcGHYC2PwhbajDh7GZ55ekB0Px197ajK3PQhpKoiI/UPg== + dependencies: + "@nomicfoundation/ethereumjs-block" "5.0.2" + "@nomicfoundation/ethereumjs-rlp" "5.0.2" + "@nomicfoundation/ethereumjs-util" "9.0.2" + abstract-level "^1.0.3" + bigint-crypto-utils "^3.0.23" + ethereum-cryptography "0.1.3" + +"@nomicfoundation/ethereumjs-evm@2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-evm/-/ethereumjs-evm-2.0.2.tgz#4c2f4b84c056047102a4fa41c127454e3f0cfcf6" + integrity sha512-rBLcUaUfANJxyOx9HIdMX6uXGin6lANCulIm/pjMgRqfiCRMZie3WKYxTSd8ZE/d+qT+zTedBF4+VHTdTSePmQ== + dependencies: + "@ethersproject/providers" "^5.7.1" + "@nomicfoundation/ethereumjs-common" "4.0.2" + "@nomicfoundation/ethereumjs-tx" "5.0.2" + "@nomicfoundation/ethereumjs-util" "9.0.2" + debug "^4.3.3" + ethereum-cryptography "0.1.3" + mcl-wasm "^0.7.1" + rustbn.js "~0.2.0" + +"@nomicfoundation/ethereumjs-rlp@5.0.2": + version "5.0.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-rlp/-/ethereumjs-rlp-5.0.2.tgz#4fee8dc58a53ac6ae87fb1fca7c15dc06c6b5dea" + integrity sha512-QwmemBc+MMsHJ1P1QvPl8R8p2aPvvVcKBbvHnQOKBpBztEo0omN0eaob6FeZS/e3y9NSe+mfu3nNFBHszqkjTA== + +"@nomicfoundation/ethereumjs-statemanager@2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-statemanager/-/ethereumjs-statemanager-2.0.2.tgz#3ba4253b29b1211cafe4f9265fee5a0d780976e0" + integrity sha512-dlKy5dIXLuDubx8Z74sipciZnJTRSV/uHG48RSijhgm1V7eXYFC567xgKtsKiVZB1ViTP9iFL4B6Je0xD6X2OA== + dependencies: + "@nomicfoundation/ethereumjs-common" "4.0.2" + "@nomicfoundation/ethereumjs-rlp" "5.0.2" + debug "^4.3.3" + ethereum-cryptography "0.1.3" + ethers "^5.7.1" + js-sdsl "^4.1.4" + +"@nomicfoundation/ethereumjs-trie@6.0.2": + version "6.0.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-trie/-/ethereumjs-trie-6.0.2.tgz#9a6dbd28482dca1bc162d12b3733acab8cd12835" + integrity sha512-yw8vg9hBeLYk4YNg5MrSJ5H55TLOv2FSWUTROtDtTMMmDGROsAu+0tBjiNGTnKRi400M6cEzoFfa89Fc5k8NTQ== + dependencies: + "@nomicfoundation/ethereumjs-rlp" "5.0.2" + "@nomicfoundation/ethereumjs-util" "9.0.2" + "@types/readable-stream" "^2.3.13" + ethereum-cryptography "0.1.3" + readable-stream "^3.6.0" + +"@nomicfoundation/ethereumjs-tx@5.0.2": + version "5.0.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-tx/-/ethereumjs-tx-5.0.2.tgz#117813b69c0fdc14dd0446698a64be6df71d7e56" + integrity sha512-T+l4/MmTp7VhJeNloMkM+lPU3YMUaXdcXgTGCf8+ZFvV9NYZTRLFekRwlG6/JMmVfIfbrW+dRRJ9A6H5Q/Z64g== + dependencies: + "@chainsafe/ssz" "^0.9.2" + "@ethersproject/providers" "^5.7.2" + "@nomicfoundation/ethereumjs-common" "4.0.2" + "@nomicfoundation/ethereumjs-rlp" "5.0.2" + "@nomicfoundation/ethereumjs-util" "9.0.2" + ethereum-cryptography "0.1.3" + +"@nomicfoundation/ethereumjs-util@9.0.2": + version "9.0.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-util/-/ethereumjs-util-9.0.2.tgz#16bdc1bb36f333b8a3559bbb4b17dac805ce904d" + integrity sha512-4Wu9D3LykbSBWZo8nJCnzVIYGvGCuyiYLIJa9XXNVt1q1jUzHdB+sJvx95VGCpPkCT+IbLecW6yfzy3E1bQrwQ== + dependencies: + "@chainsafe/ssz" "^0.10.0" + "@nomicfoundation/ethereumjs-rlp" "5.0.2" + ethereum-cryptography "0.1.3" + +"@nomicfoundation/ethereumjs-vm@7.0.2": + version "7.0.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-vm/-/ethereumjs-vm-7.0.2.tgz#3b0852cb3584df0e18c182d0672a3596c9ca95e6" + integrity sha512-Bj3KZT64j54Tcwr7Qm/0jkeZXJMfdcAtRBedou+Hx0dPOSIgqaIr0vvLwP65TpHbak2DmAq+KJbW2KNtIoFwvA== + dependencies: + "@nomicfoundation/ethereumjs-block" "5.0.2" + "@nomicfoundation/ethereumjs-blockchain" "7.0.2" + "@nomicfoundation/ethereumjs-common" "4.0.2" + "@nomicfoundation/ethereumjs-evm" "2.0.2" + "@nomicfoundation/ethereumjs-rlp" "5.0.2" + "@nomicfoundation/ethereumjs-statemanager" "2.0.2" + "@nomicfoundation/ethereumjs-trie" "6.0.2" + "@nomicfoundation/ethereumjs-tx" "5.0.2" + "@nomicfoundation/ethereumjs-util" "9.0.2" + debug "^4.3.3" + ethereum-cryptography "0.1.3" + mcl-wasm "^0.7.1" + rustbn.js "~0.2.0" + +"@nomicfoundation/hardhat-chai-matchers@^1.0.0": + version "1.0.6" + resolved "https://registry.yarnpkg.com/@nomicfoundation/hardhat-chai-matchers/-/hardhat-chai-matchers-1.0.6.tgz#72a2e312e1504ee5dd73fe302932736432ba96bc" + integrity sha512-f5ZMNmabZeZegEfuxn/0kW+mm7+yV7VNDxLpMOMGXWFJ2l/Ct3QShujzDRF9cOkK9Ui/hbDeOWGZqyQALDXVCQ== + dependencies: + "@ethersproject/abi" "^5.1.2" + "@types/chai-as-promised" "^7.1.3" + chai-as-promised "^7.1.1" + deep-eql "^4.0.1" + ordinal "^1.0.3" + +"@nomicfoundation/hardhat-foundry@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@nomicfoundation/hardhat-foundry/-/hardhat-foundry-1.1.1.tgz#db72b1f33f9cfaecc27e67f69ad436f8710162d6" + integrity sha512-cXGCBHAiXas9Pg9MhMOpBVQCkWRYoRFG7GJJAph+sdQsfd22iRs5U5Vs9XmpGEQd1yEvYISQZMeE68Nxj65iUQ== + dependencies: + chalk "^2.4.2" + +"@nomicfoundation/hardhat-network-helpers@^1.0.0": + version "1.0.9" + resolved "https://registry.yarnpkg.com/@nomicfoundation/hardhat-network-helpers/-/hardhat-network-helpers-1.0.9.tgz#767449e8a2acda79306ac84626117583d95d25aa" + integrity sha512-OXWCv0cHpwLUO2u7bFxBna6dQtCC2Gg/aN/KtJLO7gmuuA28vgmVKYFRCDUqrbjujzgfwQ2aKyZ9Y3vSmDqS7Q== + dependencies: + ethereumjs-util "^7.1.4" + +"@nomicfoundation/hardhat-verify@^1.0.2": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@nomicfoundation/hardhat-verify/-/hardhat-verify-1.1.1.tgz#6a433d777ce0172d1f0edf7f2d3e1df14b3ecfc1" + integrity sha512-9QsTYD7pcZaQFEA3tBb/D/oCStYDiEVDN7Dxeo/4SCyHRSm86APypxxdOMEPlGmXsAvd+p1j/dTODcpxb8aztA== + dependencies: + "@ethersproject/abi" "^5.1.2" + "@ethersproject/address" "^5.0.2" + cbor "^8.1.0" + chalk "^2.4.2" + debug "^4.1.1" + lodash.clonedeep "^4.5.0" + semver "^6.3.0" + table "^6.8.0" + undici "^5.14.0" + +"@nomicfoundation/solidity-analyzer-darwin-arm64@0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-darwin-arm64/-/solidity-analyzer-darwin-arm64-0.1.1.tgz#4c858096b1c17fe58a474fe81b46815f93645c15" + integrity sha512-KcTodaQw8ivDZyF+D76FokN/HdpgGpfjc/gFCImdLUyqB6eSWVaZPazMbeAjmfhx3R0zm/NYVzxwAokFKgrc0w== + +"@nomicfoundation/solidity-analyzer-darwin-x64@0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-darwin-x64/-/solidity-analyzer-darwin-x64-0.1.1.tgz#6e25ccdf6e2d22389c35553b64fe6f3fdaec432c" + integrity sha512-XhQG4BaJE6cIbjAVtzGOGbK3sn1BO9W29uhk9J8y8fZF1DYz0Doj8QDMfpMu+A6TjPDs61lbsmeYodIDnfveSA== + +"@nomicfoundation/solidity-analyzer-freebsd-x64@0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-freebsd-x64/-/solidity-analyzer-freebsd-x64-0.1.1.tgz#0a224ea50317139caeebcdedd435c28a039d169c" + integrity sha512-GHF1VKRdHW3G8CndkwdaeLkVBi5A9u2jwtlS7SLhBc8b5U/GcoL39Q+1CSO3hYqePNP+eV5YI7Zgm0ea6kMHoA== + +"@nomicfoundation/solidity-analyzer-linux-arm64-gnu@0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-linux-arm64-gnu/-/solidity-analyzer-linux-arm64-gnu-0.1.1.tgz#dfa085d9ffab9efb2e7b383aed3f557f7687ac2b" + integrity sha512-g4Cv2fO37ZsUENQ2vwPnZc2zRenHyAxHcyBjKcjaSmmkKrFr64yvzeNO8S3GBFCo90rfochLs99wFVGT/0owpg== + +"@nomicfoundation/solidity-analyzer-linux-arm64-musl@0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-linux-arm64-musl/-/solidity-analyzer-linux-arm64-musl-0.1.1.tgz#c9e06b5d513dd3ab02a7ac069c160051675889a4" + integrity sha512-WJ3CE5Oek25OGE3WwzK7oaopY8xMw9Lhb0mlYuJl/maZVo+WtP36XoQTb7bW/i8aAdHW5Z+BqrHMux23pvxG3w== + +"@nomicfoundation/solidity-analyzer-linux-x64-gnu@0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-linux-x64-gnu/-/solidity-analyzer-linux-x64-gnu-0.1.1.tgz#8d328d16839e52571f72f2998c81e46bf320f893" + integrity sha512-5WN7leSr5fkUBBjE4f3wKENUy9HQStu7HmWqbtknfXkkil+eNWiBV275IOlpXku7v3uLsXTOKpnnGHJYI2qsdA== + +"@nomicfoundation/solidity-analyzer-linux-x64-musl@0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-linux-x64-musl/-/solidity-analyzer-linux-x64-musl-0.1.1.tgz#9b49d0634b5976bb5ed1604a1e1b736f390959bb" + integrity sha512-KdYMkJOq0SYPQMmErv/63CwGwMm5XHenEna9X9aB8mQmhDBrYrlAOSsIPgFCUSL0hjxE3xHP65/EPXR/InD2+w== + +"@nomicfoundation/solidity-analyzer-win32-arm64-msvc@0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-win32-arm64-msvc/-/solidity-analyzer-win32-arm64-msvc-0.1.1.tgz#e2867af7264ebbcc3131ef837878955dd6a3676f" + integrity sha512-VFZASBfl4qiBYwW5xeY20exWhmv6ww9sWu/krWSesv3q5hA0o1JuzmPHR4LPN6SUZj5vcqci0O6JOL8BPw+APg== + +"@nomicfoundation/solidity-analyzer-win32-ia32-msvc@0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-win32-ia32-msvc/-/solidity-analyzer-win32-ia32-msvc-0.1.1.tgz#0685f78608dd516c8cdfb4896ed451317e559585" + integrity sha512-JnFkYuyCSA70j6Si6cS1A9Gh1aHTEb8kOTBApp/c7NRTFGNMH8eaInKlyuuiIbvYFhlXW4LicqyYuWNNq9hkpQ== + +"@nomicfoundation/solidity-analyzer-win32-x64-msvc@0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-win32-x64-msvc/-/solidity-analyzer-win32-x64-msvc-0.1.1.tgz#c9a44f7108646f083b82e851486e0f6aeb785836" + integrity sha512-HrVJr6+WjIXGnw3Q9u6KQcbZCtk0caVWhCdFADySvRyUxJ8PnzlaP+MhwNE8oyT8OZ6ejHBRrrgjSqDCFXGirw== + +"@nomicfoundation/solidity-analyzer@^0.1.0": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer/-/solidity-analyzer-0.1.1.tgz#f5f4d36d3f66752f59a57e7208cd856f3ddf6f2d" + integrity sha512-1LMtXj1puAxyFusBgUIy5pZk3073cNXYnXUpuNKFghHbIit/xZgbk0AokpUADbNm3gyD6bFWl3LRFh3dhVdREg== + optionalDependencies: + "@nomicfoundation/solidity-analyzer-darwin-arm64" "0.1.1" + "@nomicfoundation/solidity-analyzer-darwin-x64" "0.1.1" + "@nomicfoundation/solidity-analyzer-freebsd-x64" "0.1.1" + "@nomicfoundation/solidity-analyzer-linux-arm64-gnu" "0.1.1" + "@nomicfoundation/solidity-analyzer-linux-arm64-musl" "0.1.1" + "@nomicfoundation/solidity-analyzer-linux-x64-gnu" "0.1.1" + "@nomicfoundation/solidity-analyzer-linux-x64-musl" "0.1.1" + "@nomicfoundation/solidity-analyzer-win32-arm64-msvc" "0.1.1" + "@nomicfoundation/solidity-analyzer-win32-ia32-msvc" "0.1.1" + "@nomicfoundation/solidity-analyzer-win32-x64-msvc" "0.1.1" + +"@nomiclabs/hardhat-ethers@^2.2.3": + version "2.2.3" + resolved "https://registry.yarnpkg.com/@nomiclabs/hardhat-ethers/-/hardhat-ethers-2.2.3.tgz#b41053e360c31a32c2640c9a45ee981a7e603fe0" + integrity sha512-YhzPdzb612X591FOe68q+qXVXGG2ANZRvDo0RRUtimev85rCrAlv/TLMEZw5c+kq9AbzocLTVX/h2jVIFPL9Xg== + +"@nomiclabs/hardhat-etherscan@^3.0.0": + version "3.1.7" + resolved "https://registry.yarnpkg.com/@nomiclabs/hardhat-etherscan/-/hardhat-etherscan-3.1.7.tgz#72e3d5bd5d0ceb695e097a7f6f5ff6fcbf062b9a" + integrity sha512-tZ3TvSgpvsQ6B6OGmo1/Au6u8BrAkvs1mIC/eURA3xgIfznUZBhmpne8hv7BXUzw9xNL3fXdpOYgOQlVMTcoHQ== + dependencies: + "@ethersproject/abi" "^5.1.2" + "@ethersproject/address" "^5.0.2" + cbor "^8.1.0" + chalk "^2.4.2" + debug "^4.1.1" + fs-extra "^7.0.1" + lodash "^4.17.11" + semver "^6.3.0" + table "^6.8.0" + undici "^5.14.0" + +"@openzeppelin/contracts@^4.7.3", "@openzeppelin/contracts@^4.9.6": + version "4.9.6" + resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.9.6.tgz#2a880a24eb19b4f8b25adc2a5095f2aa27f39677" + integrity sha512-xSmezSupL+y9VkHZJGDoCBpmnB2ogM13ccaYDWqJTfS3dbuHkgjuwDFUmaFauBCboQMGB/S5UqUl2y54X99BmA== + +"@peculiar/asn1-ecc@^2.3.6": + version "2.3.8" + resolved "https://registry.yarnpkg.com/@peculiar/asn1-ecc/-/asn1-ecc-2.3.8.tgz#6b1a18f64f221ae862c1038bb125fbf4342918a0" + integrity sha512-Ah/Q15y3A/CtxbPibiLM/LKcMbnLTdUdLHUgdpB5f60sSvGkXzxJCu5ezGTFHogZXWNX3KSmYqilCrfdmBc6pQ== + dependencies: + "@peculiar/asn1-schema" "^2.3.8" + "@peculiar/asn1-x509" "^2.3.8" + asn1js "^3.0.5" + tslib "^2.6.2" + +"@peculiar/asn1-schema@^2.3.6", "@peculiar/asn1-schema@^2.3.8": + version "2.3.8" + resolved "https://registry.yarnpkg.com/@peculiar/asn1-schema/-/asn1-schema-2.3.8.tgz#04b38832a814e25731232dd5be883460a156da3b" + integrity sha512-ULB1XqHKx1WBU/tTFIA+uARuRoBVZ4pNdOA878RDrRbBfBGcSzi5HBkdScC6ZbHn8z7L8gmKCgPC1LHRrP46tA== + dependencies: + asn1js "^3.0.5" + pvtsutils "^1.3.5" + tslib "^2.6.2" + +"@peculiar/asn1-x509@^2.3.8": + version "2.3.8" + resolved "https://registry.yarnpkg.com/@peculiar/asn1-x509/-/asn1-x509-2.3.8.tgz#865896e2b849cc3c55497ca685040ef889d357a3" + integrity sha512-voKxGfDU1c6r9mKiN5ZUsZWh3Dy1BABvTM3cimf0tztNwyMJPhiXY94eRTgsMQe6ViLfT6EoXxkWVzcm3mFAFw== + dependencies: + "@peculiar/asn1-schema" "^2.3.8" + asn1js "^3.0.5" + ipaddr.js "^2.1.0" + pvtsutils "^1.3.5" + tslib "^2.6.2" + +"@scure/base@~1.1.0": + version "1.1.3" + resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.3.tgz#8584115565228290a6c6c4961973e0903bb3df2f" + integrity sha512-/+SgoRjLq7Xlf0CWuLHq2LUZeL/w65kfzAPG5NH9pcmBhs+nunQTn4gvdwgMTIXnt9b2C/1SeL2XiysZEyIC9Q== + +"@scure/bip32@1.1.5": + version "1.1.5" + resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.1.5.tgz#d2ccae16dcc2e75bc1d75f5ef3c66a338d1ba300" + integrity sha512-XyNh1rB0SkEqd3tXcXMi+Xe1fvg+kUIcoRIEujP1Jgv7DqW2r9lg3Ah0NkFaCs9sTkQAQA8kw7xiRXzENi9Rtw== + dependencies: + "@noble/hashes" "~1.2.0" + "@noble/secp256k1" "~1.7.0" + "@scure/base" "~1.1.0" + +"@scure/bip32@1.3.1": + version "1.3.1" + resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.3.1.tgz#7248aea723667f98160f593d621c47e208ccbb10" + integrity sha512-osvveYtyzdEVbt3OfwwXFr4P2iVBL5u1Q3q4ONBfDY/UpOuXmOlbgwc1xECEboY8wIays8Yt6onaWMUdUbfl0A== + dependencies: + "@noble/curves" "~1.1.0" + "@noble/hashes" "~1.3.1" + "@scure/base" "~1.1.0" + +"@scure/bip39@1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.1.1.tgz#b54557b2e86214319405db819c4b6a370cf340c5" + integrity sha512-t+wDck2rVkh65Hmv280fYdVdY25J9YeEUIgn2LG1WM6gxFkGzcksoDiUkWVpVp3Oex9xGC68JU2dSbUfwZ2jPg== + dependencies: + "@noble/hashes" "~1.2.0" + "@scure/base" "~1.1.0" + +"@scure/bip39@1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.2.1.tgz#5cee8978656b272a917b7871c981e0541ad6ac2a" + integrity sha512-Z3/Fsz1yr904dduJD0NpiyRHhRYHdcnyh73FZWiV+/qhWi83wNJ3NWolYqCEN+ZWsUz2TWwajJggcRE9r1zUYg== + dependencies: + "@noble/hashes" "~1.3.0" + "@scure/base" "~1.1.0" + +"@sentry/core@5.30.0": + version "5.30.0" + resolved "https://registry.yarnpkg.com/@sentry/core/-/core-5.30.0.tgz#6b203664f69e75106ee8b5a2fe1d717379b331f3" + integrity sha512-TmfrII8w1PQZSZgPpUESqjB+jC6MvZJZdLtE/0hZ+SrnKhW3x5WlYLvTXZpcWePYBku7rl2wn1RZu6uT0qCTeg== + dependencies: + "@sentry/hub" "5.30.0" + "@sentry/minimal" "5.30.0" + "@sentry/types" "5.30.0" + "@sentry/utils" "5.30.0" + tslib "^1.9.3" + +"@sentry/hub@5.30.0": + version "5.30.0" + resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-5.30.0.tgz#2453be9b9cb903404366e198bd30c7ca74cdc100" + integrity sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ== + dependencies: + "@sentry/types" "5.30.0" + "@sentry/utils" "5.30.0" + tslib "^1.9.3" + +"@sentry/minimal@5.30.0": + version "5.30.0" + resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-5.30.0.tgz#ce3d3a6a273428e0084adcb800bc12e72d34637b" + integrity sha512-BwWb/owZKtkDX+Sc4zCSTNcvZUq7YcH3uAVlmh/gtR9rmUvbzAA3ewLuB3myi4wWRAMEtny6+J/FN/x+2wn9Xw== + dependencies: + "@sentry/hub" "5.30.0" + "@sentry/types" "5.30.0" + tslib "^1.9.3" + +"@sentry/node@^5.18.1": + version "5.30.0" + resolved "https://registry.yarnpkg.com/@sentry/node/-/node-5.30.0.tgz#4ca479e799b1021285d7fe12ac0858951c11cd48" + integrity sha512-Br5oyVBF0fZo6ZS9bxbJZG4ApAjRqAnqFFurMVJJdunNb80brh7a5Qva2kjhm+U6r9NJAB5OmDyPkA1Qnt+QVg== + dependencies: + "@sentry/core" "5.30.0" + "@sentry/hub" "5.30.0" + "@sentry/tracing" "5.30.0" + "@sentry/types" "5.30.0" + "@sentry/utils" "5.30.0" + cookie "^0.4.1" + https-proxy-agent "^5.0.0" + lru_map "^0.3.3" + tslib "^1.9.3" + +"@sentry/tracing@5.30.0": + version "5.30.0" + resolved "https://registry.yarnpkg.com/@sentry/tracing/-/tracing-5.30.0.tgz#501d21f00c3f3be7f7635d8710da70d9419d4e1f" + integrity sha512-dUFowCr0AIMwiLD7Fs314Mdzcug+gBVo/+NCMyDw8tFxJkwWAKl7Qa2OZxLQ0ZHjakcj1hNKfCQJ9rhyfOl4Aw== + dependencies: + "@sentry/hub" "5.30.0" + "@sentry/minimal" "5.30.0" + "@sentry/types" "5.30.0" + "@sentry/utils" "5.30.0" + tslib "^1.9.3" + +"@sentry/types@5.30.0": + version "5.30.0" + resolved "https://registry.yarnpkg.com/@sentry/types/-/types-5.30.0.tgz#19709bbe12a1a0115bc790b8942917da5636f402" + integrity sha512-R8xOqlSTZ+htqrfteCWU5Nk0CDN5ApUTvrlvBuiH1DyP6czDZ4ktbZB0hAgBlVcK0U+qpD3ag3Tqqpa5Q67rPw== + +"@sentry/utils@5.30.0": + version "5.30.0" + resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-5.30.0.tgz#9a5bd7ccff85ccfe7856d493bffa64cabc41e980" + integrity sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww== + dependencies: + "@sentry/types" "5.30.0" + tslib "^1.9.3" + +"@solidity-parser/parser@^0.16.0": + version "0.16.1" + resolved "https://registry.yarnpkg.com/@solidity-parser/parser/-/parser-0.16.1.tgz#f7c8a686974e1536da0105466c4db6727311253c" + integrity sha512-PdhRFNhbTtu3x8Axm0uYpqOy/lODYQK+MlYSgqIsq2L8SFYEHJPHNUiOTAJbDGzNjjr1/n9AcIayxafR/fWmYw== + dependencies: + antlr4ts "^0.5.0-alpha.4" + +"@tsconfig/node10@^1.0.7": + version "1.0.9" + resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.9.tgz#df4907fc07a886922637b15e02d4cebc4c0021b2" + integrity sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA== + +"@tsconfig/node12@^1.0.7": + version "1.0.11" + resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.11.tgz#ee3def1f27d9ed66dac6e46a295cffb0152e058d" + integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag== + +"@tsconfig/node14@^1.0.0": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.3.tgz#e4386316284f00b98435bf40f72f75a09dabf6c1" + integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow== + +"@tsconfig/node16@^1.0.2": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.4.tgz#0b92dcc0cc1c81f6f306a381f28e31b1a56536e9" + integrity sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA== + +"@typechain/ethers-v5@^10.2.1": + version "10.2.1" + resolved "https://registry.yarnpkg.com/@typechain/ethers-v5/-/ethers-v5-10.2.1.tgz#50241e6957683281ecfa03fb5a6724d8a3ce2391" + integrity sha512-n3tQmCZjRE6IU4h6lqUGiQ1j866n5MTCBJreNEHHVWXa2u9GJTaeYyU1/k+1qLutkyw+sS6VAN+AbeiTqsxd/A== + dependencies: + lodash "^4.17.15" + ts-essentials "^7.0.1" + +"@typechain/hardhat@^6.1.5": + version "6.1.6" + resolved "https://registry.yarnpkg.com/@typechain/hardhat/-/hardhat-6.1.6.tgz#1a749eb35e5054c80df531cf440819cb347c62ea" + integrity sha512-BiVnegSs+ZHVymyidtK472syodx1sXYlYJJixZfRstHVGYTi8V1O7QG4nsjyb0PC/LORcq7sfBUcHto1y6UgJA== + dependencies: + fs-extra "^9.1.0" + +"@types/bn.js@*", "@types/bn.js@^5.1.0": + version "5.1.3" + resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-5.1.3.tgz#0857f00da3bf888a26a44b4a477c7819b17dacc5" + integrity sha512-wT1B4iIO82ecXkdN6waCK8Ou7E71WU+mP1osDA5Q8c6Ur+ozU2vIKUIhSpUr6uE5L2YHocKS1Z2jG2fBC1YVeg== + dependencies: + "@types/node" "*" + +"@types/bn.js@^4.11.3": + version "4.11.6" + resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-4.11.6.tgz#c306c70d9358aaea33cd4eda092a742b9505967c" + integrity sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg== + dependencies: + "@types/node" "*" + +"@types/chai-as-promised@^7.1.3": + version "7.1.7" + resolved "https://registry.yarnpkg.com/@types/chai-as-promised/-/chai-as-promised-7.1.7.tgz#fd16a981ba9542c83d4e1d2f40c7899aae82aa38" + integrity sha512-APucaP5rlmTRYKtRA6FE5QPP87x76ejw5t5guRJ4y5OgMnwtsvigw7HHhKZlx2MGXLeZd6R/GNZR/IqDHcbtQw== + dependencies: + "@types/chai" "*" + +"@types/chai@*", "@types/chai@^4.3.5": + version "4.3.9" + resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.3.9.tgz#144d762491967db8c6dea38e03d2206c2623feec" + integrity sha512-69TtiDzu0bcmKQv3yg1Zx409/Kd7r0b5F1PfpYJfSHzLGtB53547V4u+9iqKYsTu/O2ai6KTb0TInNpvuQ3qmg== + +"@types/elliptic@^6.4.14": + version "6.4.16" + resolved "https://registry.yarnpkg.com/@types/elliptic/-/elliptic-6.4.16.tgz#3a28a7d14e26f9e786d71f2a895ac493e7c8a3be" + integrity sha512-MSN6m9BR51W1/umzcsX0K9dAmJ59ECKxOjZ3XsjvsZAt+q0mTmKlzEdwtU+u4i+Om231d8TuY3xK6FAGIs5MbA== + dependencies: + "@types/bn.js" "*" + +"@types/glob@^7.1.1": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.2.0.tgz#bc1b5bf3aa92f25bd5dd39f35c57361bdce5b2eb" + integrity sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA== + dependencies: + "@types/minimatch" "*" + "@types/node" "*" + +"@types/json-schema@^7.0.12": + version "7.0.14" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.14.tgz#74a97a5573980802f32c8e47b663530ab3b6b7d1" + integrity sha512-U3PUjAudAdJBeC2pgN8uTIKgxrb4nlDF3SF0++EldXQvQBGkpFZMSnwQiIoDU77tv45VgNkl/L4ouD+rEomujw== + +"@types/lru-cache@^5.1.0": + version "5.1.1" + resolved "https://registry.yarnpkg.com/@types/lru-cache/-/lru-cache-5.1.1.tgz#c48c2e27b65d2a153b19bfc1a317e30872e01eef" + integrity sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw== + +"@types/minimatch@*": + version "5.1.2" + resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-5.1.2.tgz#07508b45797cb81ec3f273011b054cd0755eddca" + integrity sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA== + +"@types/mkdirp@^0.5.2": + version "0.5.2" + resolved "https://registry.yarnpkg.com/@types/mkdirp/-/mkdirp-0.5.2.tgz#503aacfe5cc2703d5484326b1b27efa67a339c1f" + integrity sha512-U5icWpv7YnZYGsN4/cmh3WD2onMY0aJIiTE6+51TwJCttdHvtCYmkBNOobHlXwrJRL0nkH9jH4kD+1FAdMN4Tg== + dependencies: + "@types/node" "*" + +"@types/mocha@>=9.1.0": + version "10.0.3" + resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-10.0.3.tgz#4804fe9cd39da26eb62fa65c15ea77615a187812" + integrity sha512-RsOPImTriV/OE4A9qKjMtk2MnXiuLLbcO3nCXK+kvq4nr0iMfFgpjaX3MPLb6f7+EL1FGSelYvuJMV6REH+ZPQ== + +"@types/node@*": + version "20.8.7" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.8.7.tgz#ad23827850843de973096edfc5abc9e922492a25" + integrity sha512-21TKHHh3eUHIi2MloeptJWALuCu5H7HQTdTrWIFReA8ad+aggoX+lRes3ex7/FtpC+sVUpFMQ+QTfYr74mruiQ== + dependencies: + undici-types "~5.25.1" + +"@types/pbkdf2@^3.0.0": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@types/pbkdf2/-/pbkdf2-3.1.1.tgz#c290c1f0d3dc364af94c2c5ee92046a13b7f89fd" + integrity sha512-4HCoGwR3221nOc7G0Z/6KgTNGgaaFGkbGrtUJsB+zlKX2LBVjFHHIUkieMBgHHXgBH5Gq6dZHJKdBYdtlhBQvw== + dependencies: + "@types/node" "*" + +"@types/prettier@^2.1.1": + version "2.7.3" + resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.7.3.tgz#3e51a17e291d01d17d3fc61422015a933af7a08f" + integrity sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA== + +"@types/qs@^6.9.7": + version "6.9.9" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.9.tgz#66f7b26288f6799d279edf13da7ccd40d2fa9197" + integrity sha512-wYLxw35euwqGvTDx6zfY1vokBFnsK0HNrzc6xNHchxfO2hpuRg74GbkEW7e3sSmPvj0TjCDT1VCa6OtHXnubsg== + +"@types/readable-stream@^2.3.13": + version "2.3.15" + resolved "https://registry.yarnpkg.com/@types/readable-stream/-/readable-stream-2.3.15.tgz#3d79c9ceb1b6a57d5f6e6976f489b9b5384321ae" + integrity sha512-oM5JSKQCcICF1wvGgmecmHldZ48OZamtMxcGGVICOJA8o8cahXC1zEVAif8iwoc5j8etxFaRFnf095+CDsuoFQ== + dependencies: + "@types/node" "*" + safe-buffer "~5.1.1" + +"@types/resolve@^0.0.8": + version "0.0.8" + resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-0.0.8.tgz#f26074d238e02659e323ce1a13d041eee280e194" + integrity sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ== + dependencies: + "@types/node" "*" + +"@types/secp256k1@^4.0.1": + version "4.0.5" + resolved "https://registry.yarnpkg.com/@types/secp256k1/-/secp256k1-4.0.5.tgz#14b1766b4fbc198b0af5599d9fd21c89056633ce" + integrity sha512-aIonTBMErtE3T9MxDvTZRzcrT/mCqpEZBw3CCY/i+oG9n57N/+7obBkhFgavUAIrX21bU0LHg1XRgtaLdelBhA== + dependencies: + "@types/node" "*" + +"@types/semver@^7.5.0": + version "7.5.4" + resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.4.tgz#0a41252ad431c473158b22f9bfb9a63df7541cff" + integrity sha512-MMzuxN3GdFwskAnb6fz0orFvhfqi752yjaXylr0Rp4oDg5H0Zn1IuyRhDVvYOwAXoJirx2xuS16I3WjxnAIHiQ== + +"@typescript-eslint/eslint-plugin@^6.21.0": + version "6.21.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.21.0.tgz#30830c1ca81fd5f3c2714e524c4303e0194f9cd3" + integrity sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA== + dependencies: + "@eslint-community/regexpp" "^4.5.1" + "@typescript-eslint/scope-manager" "6.21.0" + "@typescript-eslint/type-utils" "6.21.0" + "@typescript-eslint/utils" "6.21.0" + "@typescript-eslint/visitor-keys" "6.21.0" + debug "^4.3.4" + graphemer "^1.4.0" + ignore "^5.2.4" + natural-compare "^1.4.0" + semver "^7.5.4" + ts-api-utils "^1.0.1" + +"@typescript-eslint/parser@^6.8.0": + version "6.8.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-6.8.0.tgz#bb2a969d583db242f1ee64467542f8b05c2e28cb" + integrity sha512-5tNs6Bw0j6BdWuP8Fx+VH4G9fEPDxnVI7yH1IAPkQH5RUtvKwRoqdecAPdQXv4rSOADAaz1LFBZvZG7VbXivSg== + dependencies: + "@typescript-eslint/scope-manager" "6.8.0" + "@typescript-eslint/types" "6.8.0" + "@typescript-eslint/typescript-estree" "6.8.0" + "@typescript-eslint/visitor-keys" "6.8.0" + debug "^4.3.4" + +"@typescript-eslint/scope-manager@6.21.0": + version "6.21.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz#ea8a9bfc8f1504a6ac5d59a6df308d3a0630a2b1" + integrity sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg== + dependencies: + "@typescript-eslint/types" "6.21.0" + "@typescript-eslint/visitor-keys" "6.21.0" + +"@typescript-eslint/scope-manager@6.8.0": + version "6.8.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-6.8.0.tgz#5cac7977385cde068ab30686889dd59879811efd" + integrity sha512-xe0HNBVwCph7rak+ZHcFD6A+q50SMsFwcmfdjs9Kz4qDh5hWhaPhFjRs/SODEhroBI5Ruyvyz9LfwUJ624O40g== + dependencies: + "@typescript-eslint/types" "6.8.0" + "@typescript-eslint/visitor-keys" "6.8.0" + +"@typescript-eslint/type-utils@6.21.0": + version "6.21.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-6.21.0.tgz#6473281cfed4dacabe8004e8521cee0bd9d4c01e" + integrity sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag== + dependencies: + "@typescript-eslint/typescript-estree" "6.21.0" + "@typescript-eslint/utils" "6.21.0" + debug "^4.3.4" + ts-api-utils "^1.0.1" + +"@typescript-eslint/types@6.21.0": + version "6.21.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-6.21.0.tgz#205724c5123a8fef7ecd195075fa6e85bac3436d" + integrity sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg== + +"@typescript-eslint/types@6.8.0": + version "6.8.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-6.8.0.tgz#1ab5d4fe1d613e3f65f6684026ade6b94f7e3ded" + integrity sha512-p5qOxSum7W3k+llc7owEStXlGmSl8FcGvhYt8Vjy7FqEnmkCVlM3P57XQEGj58oqaBWDQXbJDZxwUWMS/EAPNQ== + +"@typescript-eslint/typescript-estree@6.21.0": + version "6.21.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz#c47ae7901db3b8bddc3ecd73daff2d0895688c46" + integrity sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ== + dependencies: + "@typescript-eslint/types" "6.21.0" + "@typescript-eslint/visitor-keys" "6.21.0" + debug "^4.3.4" + globby "^11.1.0" + is-glob "^4.0.3" + minimatch "9.0.3" + semver "^7.5.4" + ts-api-utils "^1.0.1" + +"@typescript-eslint/typescript-estree@6.8.0": + version "6.8.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-6.8.0.tgz#9565f15e0cd12f55cf5aa0dfb130a6cb0d436ba1" + integrity sha512-ISgV0lQ8XgW+mvv5My/+iTUdRmGspducmQcDw5JxznasXNnZn3SKNrTRuMsEXv+V/O+Lw9AGcQCfVaOPCAk/Zg== + dependencies: + "@typescript-eslint/types" "6.8.0" + "@typescript-eslint/visitor-keys" "6.8.0" + debug "^4.3.4" + globby "^11.1.0" + is-glob "^4.0.3" + semver "^7.5.4" + ts-api-utils "^1.0.1" + +"@typescript-eslint/utils@6.21.0": + version "6.21.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-6.21.0.tgz#4714e7a6b39e773c1c8e97ec587f520840cd8134" + integrity sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ== + dependencies: + "@eslint-community/eslint-utils" "^4.4.0" + "@types/json-schema" "^7.0.12" + "@types/semver" "^7.5.0" + "@typescript-eslint/scope-manager" "6.21.0" + "@typescript-eslint/types" "6.21.0" + "@typescript-eslint/typescript-estree" "6.21.0" + semver "^7.5.4" + +"@typescript-eslint/visitor-keys@6.21.0": + version "6.21.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz#87a99d077aa507e20e238b11d56cc26ade45fe47" + integrity sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A== + dependencies: + "@typescript-eslint/types" "6.21.0" + eslint-visitor-keys "^3.4.1" + +"@typescript-eslint/visitor-keys@6.8.0": + version "6.8.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-6.8.0.tgz#cffebed56ae99c45eba901c378a6447b06be58b8" + integrity sha512-oqAnbA7c+pgOhW2OhGvxm0t1BULX5peQI/rLsNDpGM78EebV3C9IGbX5HNZabuZ6UQrYveCLjKo8Iy/lLlBkkg== + dependencies: + "@typescript-eslint/types" "6.8.0" + eslint-visitor-keys "^3.4.1" + +abbrev@1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== + +abbrev@1.0.x: + version "1.0.9" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.0.9.tgz#91b4792588a7738c25f35dd6f63752a2f8776135" + integrity sha512-LEyx4aLEC3x6T0UguF6YILf+ntvmOaWsVfENmIW0E9H09vKlLDGelMjjSm0jkDHALj8A8quZ/HapKNigzwge+Q== + +abstract-level@^1.0.0, abstract-level@^1.0.2, abstract-level@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/abstract-level/-/abstract-level-1.0.3.tgz#78a67d3d84da55ee15201486ab44c09560070741" + integrity sha512-t6jv+xHy+VYwc4xqZMn2Pa9DjcdzvzZmQGRjTFc8spIbRGHgBrEKbPq+rYXc7CCo0lxgYvSgKVg9qZAhpVQSjA== + dependencies: + buffer "^6.0.3" + catering "^2.1.0" + is-buffer "^2.0.5" + level-supports "^4.0.0" + level-transcoder "^1.0.1" + module-error "^1.0.1" + queue-microtask "^1.2.3" + +acorn-jsx@^5.3.2: + version "5.3.2" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" + integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== + +acorn-walk@^8.1.1: + version "8.2.0" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" + integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== + +acorn@^8.4.1, acorn@^8.9.0: + version "8.10.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" + integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== + +address@^1.0.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/address/-/address-1.2.2.tgz#2b5248dac5485a6390532c6a517fda2e3faac89e" + integrity sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA== + +adm-zip@^0.4.16: + version "0.4.16" + resolved "https://registry.yarnpkg.com/adm-zip/-/adm-zip-0.4.16.tgz#cf4c508fdffab02c269cbc7f471a875f05570365" + integrity sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg== + +aes-js@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.0.0.tgz#e21df10ad6c2053295bcbb8dab40b09dbea87e4d" + integrity sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw== + +agent-base@6: + version "6.0.2" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" + integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== + dependencies: + debug "4" + +aggregate-error@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" + integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== + dependencies: + clean-stack "^2.0.0" + indent-string "^4.0.0" + +ajv@^6.12.4, ajv@^6.12.6: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ajv@^8.0.1: + version "8.12.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.12.0.tgz#d1a0527323e22f53562c567c00991577dfbe19d1" + integrity sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA== + dependencies: + fast-deep-equal "^3.1.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + uri-js "^4.2.2" + +amdefine@>=0.0.4: + version "1.0.1" + resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" + integrity sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg== + +ansi-colors@4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" + integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== + +ansi-colors@^4.1.1: + version "4.1.3" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.3.tgz#37611340eb2243e70cc604cad35d63270d48781b" + integrity sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw== + +ansi-escapes@^4.3.0: + version "4.3.2" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" + integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== + dependencies: + type-fest "^0.21.3" + +ansi-regex@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.1.tgz#164daac87ab2d6f6db3a29875e2d1766582dabed" + integrity sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g== + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-styles@^3.2.0, ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +antlr4@^4.11.0: + version "4.13.1" + resolved "https://registry.yarnpkg.com/antlr4/-/antlr4-4.13.1.tgz#1e0a1830a08faeb86217cb2e6c34716004e4253d" + integrity sha512-kiXTspaRYvnIArgE97z5YVVf/cDVQABr3abFRR6mE7yesLMkgu4ujuyV/sgxafQ8wgve0DJQUJ38Z8tkgA2izA== + +antlr4ts@^0.5.0-alpha.4: + version "0.5.0-alpha.4" + resolved "https://registry.yarnpkg.com/antlr4ts/-/antlr4ts-0.5.0-alpha.4.tgz#71702865a87478ed0b40c0709f422cf14d51652a" + integrity sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ== + +anymatch@~3.1.2: + version "3.1.3" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" + integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +arg@^4.1.0: + version "4.1.3" + resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" + integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + +array-back@^3.0.1, array-back@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/array-back/-/array-back-3.1.0.tgz#b8859d7a508871c9a7b2cf42f99428f65e96bfb0" + integrity sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q== + +array-back@^4.0.1, array-back@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/array-back/-/array-back-4.0.2.tgz#8004e999a6274586beeb27342168652fdb89fa1e" + integrity sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg== + +array-union@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" + integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== + +asn1js@^3.0.5: + version "3.0.5" + resolved "https://registry.yarnpkg.com/asn1js/-/asn1js-3.0.5.tgz#5ea36820443dbefb51cc7f88a2ebb5b462114f38" + integrity sha512-FVnvrKJwpt9LP2lAMl8qZswRNm3T4q9CON+bxldk2iwk3FFpuwhx2FfinyitizWHsVYyaY+y5JzDR0rCMV5yTQ== + dependencies: + pvtsutils "^1.3.2" + pvutils "^1.1.3" + tslib "^2.4.0" + +assertion-error@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" + integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw== + +ast-parents@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/ast-parents/-/ast-parents-0.0.1.tgz#508fd0f05d0c48775d9eccda2e174423261e8dd3" + integrity sha512-XHusKxKz3zoYk1ic8Un640joHbFMhbqneyoZfoKnEGtf2ey9Uh/IdpcQplODdO/kENaMIWsD0nJm4+wX3UNLHA== + +astral-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" + integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== + +async@1.x: + version "1.5.2" + resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" + integrity sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w== + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== + +at-least-node@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" + integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== + +available-typed-arrays@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" + integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== + +axios@^0.21.1: + version "0.21.4" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.4.tgz#c67b90dc0568e5c1cf2b0b858c43ba28e2eda575" + integrity sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg== + dependencies: + follow-redirects "^1.14.0" + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +base-x@^3.0.2: + version "3.0.9" + resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.9.tgz#6349aaabb58526332de9f60995e548a53fe21320" + integrity sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ== + dependencies: + safe-buffer "^5.0.1" + +base64-js@^1.3.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== + +base64url@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/base64url/-/base64url-3.0.1.tgz#6399d572e2bc3f90a9a8b22d5dbb0a32d33f788d" + integrity sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A== + +bech32@1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/bech32/-/bech32-1.1.4.tgz#e38c9f37bf179b8eb16ae3a772b40c356d4832e9" + integrity sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ== + +bigi@^1.1.0, bigi@^1.2.1: + version "1.4.2" + resolved "https://registry.yarnpkg.com/bigi/-/bigi-1.4.2.tgz#9c665a95f88b8b08fc05cfd731f561859d725825" + integrity sha512-ddkU+dFIuEIW8lE7ZwdIAf2UPoM90eaprg5m3YXAVVTmKlqV/9BX4A2M8BOK2yOq6/VgZFVhK6QAxJebhlbhzw== + +bigint-crypto-utils@^3.0.23: + version "3.3.0" + resolved "https://registry.yarnpkg.com/bigint-crypto-utils/-/bigint-crypto-utils-3.3.0.tgz#72ad00ae91062cf07f2b1def9594006c279c1d77" + integrity sha512-jOTSb+drvEDxEq6OuUybOAv/xxoh3cuYRUIPyu8sSHQNKM303UQ2R1DAo45o1AkcIXw6fzbaFI1+xGGdaXs2lg== + +binary-extensions@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + +bip66@^1.1.0: + version "1.1.5" + resolved "https://registry.yarnpkg.com/bip66/-/bip66-1.1.5.tgz#01fa8748785ca70955d5011217d1b3139969ca22" + integrity sha512-nemMHz95EmS38a26XbbdxIYj5csHd3RMP3H5bwQknX0WYHF01qhpufP42mLOwVICuH2JmhIhXiWs89MfUGL7Xw== + dependencies: + safe-buffer "^5.0.1" + +blakejs@^1.1.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/blakejs/-/blakejs-1.2.1.tgz#5057e4206eadb4a97f7c0b6e197a505042fc3814" + integrity sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ== + +bn.js@4.11.6: + version "4.11.6" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.6.tgz#53344adb14617a13f6e8dd2ce28905d1c0ba3215" + integrity sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA== + +bn.js@^4.11.0, bn.js@^4.11.8, bn.js@^4.11.9: + version "4.12.0" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" + integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== + +bn.js@^5.1.2, bn.js@^5.2.0, bn.js@^5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70" + integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ== + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +brace-expansion@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" + integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== + dependencies: + balanced-match "^1.0.0" + +braces@^3.0.2, braces@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +brorand@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" + integrity sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w== + +browser-level@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/browser-level/-/browser-level-1.0.1.tgz#36e8c3183d0fe1c405239792faaab5f315871011" + integrity sha512-XECYKJ+Dbzw0lbydyQuJzwNXtOpbMSq737qxJN11sIRTErOMShvDpbzTlgju7orJKvx4epULolZAuJGLzCmWRQ== + dependencies: + abstract-level "^1.0.2" + catering "^2.1.1" + module-error "^1.0.2" + run-parallel-limit "^1.1.0" + +browser-stdout@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" + integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== + +browserify-aes@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" + integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== + dependencies: + buffer-xor "^1.0.3" + cipher-base "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.3" + inherits "^2.0.1" + safe-buffer "^5.0.1" + +bs58@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a" + integrity sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw== + dependencies: + base-x "^3.0.2" + +bs58check@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/bs58check/-/bs58check-2.1.2.tgz#53b018291228d82a5aa08e7d796fdafda54aebfc" + integrity sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA== + dependencies: + bs58 "^4.0.0" + create-hash "^1.1.0" + safe-buffer "^5.1.2" + +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + +buffer-xor@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" + integrity sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ== + +buffer@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" + integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.2.1" + +bytes@3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" + integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== + +call-bind@^1.0.0, call-bind@^1.0.2, call-bind@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.5.tgz#6fa2b7845ce0ea49bf4d8b9ef64727a2c2e2e513" + integrity sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ== + dependencies: + function-bind "^1.1.2" + get-intrinsic "^1.2.1" + set-function-length "^1.1.1" + +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + +camelcase@^5.0.0: + version "5.3.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== + +camelcase@^6.0.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" + integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== + +case@^1.6.3: + version "1.6.3" + resolved "https://registry.yarnpkg.com/case/-/case-1.6.3.tgz#0a4386e3e9825351ca2e6216c60467ff5f1ea1c9" + integrity sha512-mzDSXIPaFwVDvZAHqZ9VlbyF4yyXRuX6IvB06WvPYkqJVO24kX1PPhv9bfpKNFZyxYFmmgo03HUiD8iklmJYRQ== + +catering@^2.1.0, catering@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/catering/-/catering-2.1.1.tgz#66acba06ed5ee28d5286133982a927de9a04b510" + integrity sha512-K7Qy8O9p76sL3/3m7/zLKbRkyOlSZAgzEaLhyj2mXS8PsCud2Eo4hAb8aLtZqHh0QGqLcb9dlJSu6lHRVENm1w== + +cbor@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/cbor/-/cbor-8.1.0.tgz#cfc56437e770b73417a2ecbfc9caf6b771af60d5" + integrity sha512-DwGjNW9omn6EwP70aXsn7FQJx5kO12tX0bZkaTjzdVFM6/7nhA4t0EENocKGx6D2Bch9PE2KzCUf5SceBdeijg== + dependencies: + nofilter "^3.1.0" + +cbor@^9.0.0: + version "9.0.1" + resolved "https://registry.yarnpkg.com/cbor/-/cbor-9.0.1.tgz#b16e393d4948d44758cd54ac6151379d443b37ae" + integrity sha512-/TQOWyamDxvVIv+DY9cOLNuABkoyz8K/F3QE56539pGVYohx0+MEA1f4lChFTX79dBTBS7R1PF6ovH7G+VtBfQ== + dependencies: + nofilter "^3.1.0" + +chai-as-promised@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/chai-as-promised/-/chai-as-promised-7.1.1.tgz#08645d825deb8696ee61725dbf590c012eb00ca0" + integrity sha512-azL6xMoi+uxu6z4rhWQ1jbdUhOMhis2PvscD/xjLqNMkv3BPPp2JyyuTHOrf9BOosGpNQ11v6BKv/g57RXbiaA== + dependencies: + check-error "^1.0.2" + +chai@^4.2.0: + version "4.3.10" + resolved "https://registry.yarnpkg.com/chai/-/chai-4.3.10.tgz#d784cec635e3b7e2ffb66446a63b4e33bd390384" + integrity sha512-0UXG04VuVbruMUYbJ6JctvH0YnC/4q3/AkT18q4NaITo91CUm0liMS9VqzT9vZhVQ/1eqPanMWjBM+Juhfb/9g== + dependencies: + assertion-error "^1.1.0" + check-error "^1.0.3" + deep-eql "^4.1.3" + get-func-name "^2.0.2" + loupe "^2.3.6" + pathval "^1.1.1" + type-detect "^4.0.8" + +chalk@^2.4.1, chalk@^2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +check-error@^1.0.2, check-error@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.3.tgz#a6502e4312a7ee969f646e83bb3ddd56281bd694" + integrity sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg== + dependencies: + get-func-name "^2.0.2" + +chokidar@3.5.3, chokidar@^3.4.0, chokidar@^3.5.2: + version "3.5.3" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" + integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + +ci-info@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" + integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== + +cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" + integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +classic-level@^1.2.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/classic-level/-/classic-level-1.3.0.tgz#5e36680e01dc6b271775c093f2150844c5edd5c8" + integrity sha512-iwFAJQYtqRTRM0F6L8h4JCt00ZSGdOyqh7yVrhhjrOpFhmBjNlRUey64MCiyo6UmQHMJ+No3c81nujPv+n9yrg== + dependencies: + abstract-level "^1.0.2" + catering "^2.1.0" + module-error "^1.0.1" + napi-macros "^2.2.2" + node-gyp-build "^4.3.0" + +clean-stack@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" + integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== + +cli-table3@^0.6.0: + version "0.6.3" + resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.6.3.tgz#61ab765aac156b52f222954ffc607a6f01dbeeb2" + integrity sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg== + dependencies: + string-width "^4.2.0" + optionalDependencies: + "@colors/colors" "1.5.0" + +cliui@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" + integrity sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA== + dependencies: + string-width "^3.1.0" + strip-ansi "^5.2.0" + wrap-ansi "^5.1.0" + +cliui@^7.0.2: + version "7.0.4" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" + integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^7.0.0" + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +combined-stream@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + +command-exists@^1.2.8: + version "1.2.9" + resolved "https://registry.yarnpkg.com/command-exists/-/command-exists-1.2.9.tgz#c50725af3808c8ab0260fd60b01fbfa25b954f69" + integrity sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w== + +command-line-args@^5.1.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/command-line-args/-/command-line-args-5.2.1.tgz#c44c32e437a57d7c51157696893c5909e9cec42e" + integrity sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg== + dependencies: + array-back "^3.1.0" + find-replace "^3.0.0" + lodash.camelcase "^4.3.0" + typical "^4.0.0" + +command-line-usage@^6.1.0: + version "6.1.3" + resolved "https://registry.yarnpkg.com/command-line-usage/-/command-line-usage-6.1.3.tgz#428fa5acde6a838779dfa30e44686f4b6761d957" + integrity sha512-sH5ZSPr+7UStsloltmDh7Ce5fb8XPlHyoPzTpyyMuYCtervL65+ubVZ6Q61cFtFl62UyJlc8/JwERRbAFPUqgw== + dependencies: + array-back "^4.0.2" + chalk "^2.4.2" + table-layout "^1.0.2" + typical "^5.2.0" + +commander@3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/commander/-/commander-3.0.2.tgz#6837c3fb677ad9933d1cfba42dd14d5117d6b39e" + integrity sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow== + +commander@^10.0.0: + version "10.0.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-10.0.1.tgz#881ee46b4f77d1c1dccc5823433aa39b022cbe06" + integrity sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + +cookie@^0.4.1: + version "0.4.2" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432" + integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== + +cosmiconfig@^8.0.0: + version "8.3.6" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-8.3.6.tgz#060a2b871d66dba6c8538ea1118ba1ac16f5fae3" + integrity sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA== + dependencies: + import-fresh "^3.3.0" + js-yaml "^4.1.0" + parse-json "^5.2.0" + path-type "^4.0.0" + +crc-32@^1.2.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/crc-32/-/crc-32-1.2.2.tgz#3cad35a934b8bf71f25ca524b6da51fb7eace2ff" + integrity sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ== + +create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" + integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== + dependencies: + cipher-base "^1.0.1" + inherits "^2.0.1" + md5.js "^1.3.4" + ripemd160 "^2.0.1" + sha.js "^2.4.0" + +create-hmac@^1.1.4, create-hmac@^1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" + integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== + dependencies: + cipher-base "^1.0.3" + create-hash "^1.1.0" + inherits "^2.0.1" + ripemd160 "^2.0.0" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +create-require@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" + integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== + +cross-spawn@^6.0.0: + version "6.0.5" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" + integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== + dependencies: + nice-try "^1.0.4" + path-key "^2.0.1" + semver "^5.5.0" + shebang-command "^1.2.0" + which "^1.2.9" + +cross-spawn@^7.0.2: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +death@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/death/-/death-1.1.0.tgz#01aa9c401edd92750514470b8266390c66c67318" + integrity sha512-vsV6S4KVHvTGxbEcij7hkWRv0It+sGGWVOM67dQde/o5Xjnr+KmLjxWJii2uEObIrt1CcM9w0Yaovx+iOlIL+w== + +debug@4, debug@4.3.4, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4: + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + +decamelize@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + integrity sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA== + +decamelize@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" + integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== + +deep-eql@^4.0.1, deep-eql@^4.1.3: + version "4.1.3" + resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-4.1.3.tgz#7c7775513092f7df98d8df9996dd085eb668cc6d" + integrity sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw== + dependencies: + type-detect "^4.0.0" + +deep-extend@~0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== + +deep-is@^0.1.3, deep-is@~0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" + integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== + +define-data-property@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.1.tgz#c35f7cd0ab09883480d12ac5cb213715587800b3" + integrity sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ== + dependencies: + get-intrinsic "^1.2.1" + gopd "^1.0.1" + has-property-descriptors "^1.0.0" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== + +depd@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" + integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== + +detect-port@^1.3.0: + version "1.5.1" + resolved "https://registry.yarnpkg.com/detect-port/-/detect-port-1.5.1.tgz#451ca9b6eaf20451acb0799b8ab40dff7718727b" + integrity sha512-aBzdj76lueB6uUst5iAs7+0H/oOjqI5D16XUWxlWMIMROhcM0rfsNVk93zTngq1dDNpoXRr++Sus7ETAExppAQ== + dependencies: + address "^1.0.1" + debug "4" + +diff@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" + integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== + +diff@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" + integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== + +difflib@^0.2.4: + version "0.2.4" + resolved "https://registry.yarnpkg.com/difflib/-/difflib-0.2.4.tgz#b5e30361a6db023176d562892db85940a718f47e" + integrity sha512-9YVwmMb0wQHQNr5J9m6BSj6fk4pfGITGQOOs+D9Fl+INODWFOfvhIU1hNv6GgR1RBoC/9NJcwu77zShxV0kT7w== + dependencies: + heap ">= 0.2.0" + +dir-glob@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== + dependencies: + path-type "^4.0.0" + +doctrine@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== + dependencies: + esutils "^2.0.2" + +dotenv@^16.2.0: + version "16.3.1" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.3.1.tgz#369034de7d7e5b120972693352a3bf112172cc3e" + integrity sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ== + +ecdsa@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/ecdsa/-/ecdsa-0.7.0.tgz#f65ce2300227b1628102902b2b93607c806de1d9" + integrity sha512-8/Xe+kdMMIeI1dNX7taLL4uCvo+HGg8N42Rjp6ta8lCkjKYm0b8PF6fgvoOgsA8sQE+qX5DAE08hIsQScADGZA== + dependencies: + bigi "^1.2.1" + bip66 "^1.1.0" + create-hmac "^1.1.4" + ecurve "^1.0.0" + typeforce "^1.6.1" + +ecurve@^1.0.0: + version "1.0.6" + resolved "https://registry.yarnpkg.com/ecurve/-/ecurve-1.0.6.tgz#dfdabbb7149f8d8b78816be5a7d5b83fcf6de797" + integrity sha512-/BzEjNfiSuB7jIWKcS/z8FK9jNjmEWvUV2YZ4RLSmcDtP7Lq0m6FvDuSnJpBlDpGRpfRQeTLGLBI8H+kEv0r+w== + dependencies: + bigi "^1.1.0" + safe-buffer "^5.0.1" + +elliptic@6.5.4, elliptic@^6.5.2, elliptic@^6.5.4: + version "6.5.4" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" + integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ== + dependencies: + bn.js "^4.11.9" + brorand "^1.1.0" + hash.js "^1.0.0" + hmac-drbg "^1.0.1" + inherits "^2.0.4" + minimalistic-assert "^1.0.1" + minimalistic-crypto-utils "^1.0.1" + +emoji-regex@^7.0.1: + version "7.0.3" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" + integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +encode-utf8@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/encode-utf8/-/encode-utf8-1.0.3.tgz#f30fdd31da07fb596f281beb2f6b027851994cda" + integrity sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw== + +end-of-stream@^1.1.0: + version "1.4.4" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== + dependencies: + once "^1.4.0" + +enquirer@^2.3.0, enquirer@^2.3.6: + version "2.4.1" + resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.4.1.tgz#93334b3fbd74fc7097b224ab4a8fb7e40bf4ae56" + integrity sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ== + dependencies: + ansi-colors "^4.1.1" + strip-ansi "^6.0.1" + +env-paths@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2" + integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A== + +error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + +escape-string-regexp@4.0.0, escape-string-regexp@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + +escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== + +escodegen@1.8.x: + version "1.8.1" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.8.1.tgz#5a5b53af4693110bebb0867aa3430dd3b70a1018" + integrity sha512-yhi5S+mNTOuRvyW4gWlg5W1byMaQGWWSYHXsuFZ7GBo7tpyOwi2EdzMP/QWxh9hwkD2m+wDVHJsxhRIj+v/b/A== + dependencies: + esprima "^2.7.1" + estraverse "^1.9.1" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.2.0" + +eslint-scope@^7.2.2: + version "7.2.2" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.2.tgz#deb4f92563390f32006894af62a22dba1c46423f" + integrity sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg== + dependencies: + esrecurse "^4.3.0" + estraverse "^5.2.0" + +eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3: + version "3.4.3" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" + integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== + +eslint@^8.51.0: + version "8.51.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.51.0.tgz#4a82dae60d209ac89a5cff1604fea978ba4950f3" + integrity sha512-2WuxRZBrlwnXi+/vFSJyjMqrNjtJqiasMzehF0shoLaW7DzS3/9Yvrmq5JiT66+pNjiX4UBnLDiKHcWAr/OInA== + dependencies: + "@eslint-community/eslint-utils" "^4.2.0" + "@eslint-community/regexpp" "^4.6.1" + "@eslint/eslintrc" "^2.1.2" + "@eslint/js" "8.51.0" + "@humanwhocodes/config-array" "^0.11.11" + "@humanwhocodes/module-importer" "^1.0.1" + "@nodelib/fs.walk" "^1.2.8" + ajv "^6.12.4" + chalk "^4.0.0" + cross-spawn "^7.0.2" + debug "^4.3.2" + doctrine "^3.0.0" + escape-string-regexp "^4.0.0" + eslint-scope "^7.2.2" + eslint-visitor-keys "^3.4.3" + espree "^9.6.1" + esquery "^1.4.2" + esutils "^2.0.2" + fast-deep-equal "^3.1.3" + file-entry-cache "^6.0.1" + find-up "^5.0.0" + glob-parent "^6.0.2" + globals "^13.19.0" + graphemer "^1.4.0" + ignore "^5.2.0" + imurmurhash "^0.1.4" + is-glob "^4.0.0" + is-path-inside "^3.0.3" + js-yaml "^4.1.0" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.4.1" + lodash.merge "^4.6.2" + minimatch "^3.1.2" + natural-compare "^1.4.0" + optionator "^0.9.3" + strip-ansi "^6.0.1" + text-table "^0.2.0" + +espree@^9.6.0, espree@^9.6.1: + version "9.6.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f" + integrity sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ== + dependencies: + acorn "^8.9.0" + acorn-jsx "^5.3.2" + eslint-visitor-keys "^3.4.1" + +esprima@2.7.x, esprima@^2.7.1: + version "2.7.3" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581" + integrity sha512-OarPfz0lFCiW4/AV2Oy1Rp9qu0iusTKqykwTspGCZtPxmF81JR4MmIebvF1F9+UOKth2ZubLQ4XGGaU+hSn99A== + +esprima@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +esquery@^1.4.2: + version "1.5.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.5.0.tgz#6ce17738de8577694edd7361c57182ac8cb0db0b" + integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== + dependencies: + estraverse "^5.1.0" + +esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" + +estraverse@^1.9.1: + version "1.9.3" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.9.3.tgz#af67f2dc922582415950926091a4005d29c9bb44" + integrity sha512-25w1fMXQrGdoquWnScXZGckOv+Wes+JDnuN/+7ex3SauFRS72r2lFDec0EKPt2YD1wUJ/IrfEex+9yp4hfSOJA== + +estraverse@^5.1.0, estraverse@^5.2.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +ethereum-bloom-filters@^1.0.6: + version "1.0.10" + resolved "https://registry.yarnpkg.com/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.10.tgz#3ca07f4aed698e75bd134584850260246a5fed8a" + integrity sha512-rxJ5OFN3RwjQxDcFP2Z5+Q9ho4eIdEmSc2ht0fCu8Se9nbXjZ7/031uXoUYJ87KHCOdVeiUuwSnoS7hmYAGVHA== + dependencies: + js-sha3 "^0.8.0" + +ethereum-cryptography@0.1.3, ethereum-cryptography@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz#8d6143cfc3d74bf79bbd8edecdf29e4ae20dd191" + integrity sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ== + dependencies: + "@types/pbkdf2" "^3.0.0" + "@types/secp256k1" "^4.0.1" + blakejs "^1.1.0" + browserify-aes "^1.2.0" + bs58check "^2.1.2" + create-hash "^1.2.0" + create-hmac "^1.1.7" + hash.js "^1.1.7" + keccak "^3.0.0" + pbkdf2 "^3.0.17" + randombytes "^2.1.0" + safe-buffer "^5.1.2" + scrypt-js "^3.0.0" + secp256k1 "^4.0.1" + setimmediate "^1.0.5" + +ethereum-cryptography@^1.0.3: + version "1.2.0" + resolved "https://registry.yarnpkg.com/ethereum-cryptography/-/ethereum-cryptography-1.2.0.tgz#5ccfa183e85fdaf9f9b299a79430c044268c9b3a" + integrity sha512-6yFQC9b5ug6/17CQpCyE3k9eKBMdhyVjzUy1WkiuY/E4vj/SXDBbCw8QEIaXqf0Mf2SnY6RmpDcwlUmBSS0EJw== + dependencies: + "@noble/hashes" "1.2.0" + "@noble/secp256k1" "1.7.1" + "@scure/bip32" "1.1.5" + "@scure/bip39" "1.1.1" + +ethereum-cryptography@^2.0.0, ethereum-cryptography@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ethereum-cryptography/-/ethereum-cryptography-2.1.2.tgz#18fa7108622e56481157a5cb7c01c0c6a672eb67" + integrity sha512-Z5Ba0T0ImZ8fqXrJbpHcbpAvIswRte2wGNR/KePnu8GbbvgJ47lMxT/ZZPG6i9Jaht4azPDop4HaM00J0J59ug== + dependencies: + "@noble/curves" "1.1.0" + "@noble/hashes" "1.3.1" + "@scure/bip32" "1.3.1" + "@scure/bip39" "1.2.1" + +ethereumjs-abi@^0.6.8: + version "0.6.8" + resolved "https://registry.yarnpkg.com/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz#71bc152db099f70e62f108b7cdfca1b362c6fcae" + integrity sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA== + dependencies: + bn.js "^4.11.8" + ethereumjs-util "^6.0.0" + +ethereumjs-util@6.2.1, ethereumjs-util@^6.0.0, ethereumjs-util@^6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz#fcb4e4dd5ceacb9d2305426ab1a5cd93e3163b69" + integrity sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw== + dependencies: + "@types/bn.js" "^4.11.3" + bn.js "^4.11.0" + create-hash "^1.1.2" + elliptic "^6.5.2" + ethereum-cryptography "^0.1.3" + ethjs-util "0.1.6" + rlp "^2.2.3" + +ethereumjs-util@^7.1.4, ethereumjs-util@^7.1.5: + version "7.1.5" + resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz#9ecf04861e4fbbeed7465ece5f23317ad1129181" + integrity sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg== + dependencies: + "@types/bn.js" "^5.1.0" + bn.js "^5.1.2" + create-hash "^1.1.2" + ethereum-cryptography "^0.1.3" + rlp "^2.2.4" + +ethers@^5.4.7, ethers@^5.7.0, ethers@^5.7.1: + version "5.7.2" + resolved "https://registry.yarnpkg.com/ethers/-/ethers-5.7.2.tgz#3a7deeabbb8c030d4126b24f84e525466145872e" + integrity sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg== + dependencies: + "@ethersproject/abi" "5.7.0" + "@ethersproject/abstract-provider" "5.7.0" + "@ethersproject/abstract-signer" "5.7.0" + "@ethersproject/address" "5.7.0" + "@ethersproject/base64" "5.7.0" + "@ethersproject/basex" "5.7.0" + "@ethersproject/bignumber" "5.7.0" + "@ethersproject/bytes" "5.7.0" + "@ethersproject/constants" "5.7.0" + "@ethersproject/contracts" "5.7.0" + "@ethersproject/hash" "5.7.0" + "@ethersproject/hdnode" "5.7.0" + "@ethersproject/json-wallets" "5.7.0" + "@ethersproject/keccak256" "5.7.0" + "@ethersproject/logger" "5.7.0" + "@ethersproject/networks" "5.7.1" + "@ethersproject/pbkdf2" "5.7.0" + "@ethersproject/properties" "5.7.0" + "@ethersproject/providers" "5.7.2" + "@ethersproject/random" "5.7.0" + "@ethersproject/rlp" "5.7.0" + "@ethersproject/sha2" "5.7.0" + "@ethersproject/signing-key" "5.7.0" + "@ethersproject/solidity" "5.7.0" + "@ethersproject/strings" "5.7.0" + "@ethersproject/transactions" "5.7.0" + "@ethersproject/units" "5.7.0" + "@ethersproject/wallet" "5.7.0" + "@ethersproject/web" "5.7.1" + "@ethersproject/wordlists" "5.7.0" + +ethjs-unit@0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/ethjs-unit/-/ethjs-unit-0.1.6.tgz#c665921e476e87bce2a9d588a6fe0405b2c41699" + integrity sha512-/Sn9Y0oKl0uqQuvgFk/zQgR7aw1g36qX/jzSQ5lSwlO0GigPymk4eGQfeNTD03w1dPOqfz8V77Cy43jH56pagw== + dependencies: + bn.js "4.11.6" + number-to-bn "1.7.0" + +ethjs-util@0.1.6, ethjs-util@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/ethjs-util/-/ethjs-util-0.1.6.tgz#f308b62f185f9fe6237132fb2a9818866a5cd536" + integrity sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w== + dependencies: + is-hex-prefixed "1.0.0" + strip-hex-prefix "1.0.0" + +eventemitter3@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-5.0.1.tgz#53f5ffd0a492ac800721bb42c66b841de96423c4" + integrity sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA== + +evp_bytestokey@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" + integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== + dependencies: + md5.js "^1.3.4" + safe-buffer "^5.1.1" + +execa@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" + integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA== + dependencies: + cross-spawn "^6.0.0" + get-stream "^4.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fast-diff@^1.2.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.3.0.tgz#ece407fa550a64d638536cd727e129c61616e0f0" + integrity sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw== + +fast-glob@^3.0.3, fast-glob@^3.2.9: + version "3.3.1" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.1.tgz#784b4e897340f3dbbef17413b3f11acf03c874c4" + integrity sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== + +fastq@^1.6.0: + version "1.15.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.15.0.tgz#d04d07c6a2a68fe4599fea8d2e103a937fae6b3a" + integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw== + dependencies: + reusify "^1.0.4" + +file-entry-cache@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" + integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== + dependencies: + flat-cache "^3.0.4" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +find-replace@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-replace/-/find-replace-3.0.0.tgz#3e7e23d3b05167a76f770c9fbd5258b0def68c38" + integrity sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ== + dependencies: + array-back "^3.0.1" + +find-up@5.0.0, find-up@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + +find-up@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" + integrity sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ== + dependencies: + locate-path "^2.0.0" + +find-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" + integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== + dependencies: + locate-path "^3.0.0" + +flat-cache@^3.0.4: + version "3.1.1" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.1.1.tgz#a02a15fdec25a8f844ff7cc658f03dd99eb4609b" + integrity sha512-/qM2b3LUIaIgviBQovTLvijfyOQXPtSRnRK26ksj2J7rzPIecePUIpJsZ4T02Qg+xiAEKIs5K8dsHEd+VaKa/Q== + dependencies: + flatted "^3.2.9" + keyv "^4.5.3" + rimraf "^3.0.2" + +flat@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" + integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== + +flatted@^3.2.9: + version "3.2.9" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.9.tgz#7eb4c67ca1ba34232ca9d2d93e9886e611ad7daf" + integrity sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ== + +fmix@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/fmix/-/fmix-0.1.0.tgz#c7bbf124dec42c9d191cfb947d0a9778dd986c0c" + integrity sha512-Y6hyofImk9JdzU8k5INtTXX1cu8LDlePWDFU5sftm9H+zKCr5SGrVjdhkvsim646cw5zD0nADj8oHyXMZmCZ9w== + dependencies: + imul "^1.0.0" + +follow-redirects@^1.12.1, follow-redirects@^1.14.0: + version "1.15.6" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.6.tgz#7f815c0cda4249c74ff09e95ef97c23b5fd0399b" + integrity sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA== + +for-each@^0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" + integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== + dependencies: + is-callable "^1.1.3" + +form-data@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" + integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + +fp-ts@1.19.3: + version "1.19.3" + resolved "https://registry.yarnpkg.com/fp-ts/-/fp-ts-1.19.3.tgz#261a60d1088fbff01f91256f91d21d0caaaaa96f" + integrity sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg== + +fp-ts@^1.0.0: + version "1.19.5" + resolved "https://registry.yarnpkg.com/fp-ts/-/fp-ts-1.19.5.tgz#3da865e585dfa1fdfd51785417357ac50afc520a" + integrity sha512-wDNqTimnzs8QqpldiId9OavWK2NptormjXnRJTQecNjzwfyp6P/8s/zG8e4h3ja3oqkKaY72UlTjQYt/1yXf9A== + +fs-extra@^0.30.0: + version "0.30.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.30.0.tgz#f233ffcc08d4da7d432daa449776989db1df93f0" + integrity sha512-UvSPKyhMn6LEd/WpUaV9C9t3zATuqoqfWc3QdPhPLb58prN9tqYPlPWi8Krxi44loBoUzlobqZ3+8tGpxxSzwA== + dependencies: + graceful-fs "^4.1.2" + jsonfile "^2.1.0" + klaw "^1.0.0" + path-is-absolute "^1.0.0" + rimraf "^2.2.8" + +fs-extra@^10.0.0: + version "10.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.1.0.tgz#02873cfbc4084dde127eaa5f9905eef2325d1abf" + integrity sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + +fs-extra@^7.0.0, fs-extra@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9" + integrity sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw== + dependencies: + graceful-fs "^4.1.2" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs-extra@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" + integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs-extra@^9.1.0: + version "9.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" + integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== + dependencies: + at-least-node "^1.0.0" + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== + +fsevents@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== + +function-bind@^1.1.1, function-bind@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" + integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== + +functional-red-black-tree@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" + integrity sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g== + +ganache-cli@^6.12.2: + version "6.12.2" + resolved "https://registry.yarnpkg.com/ganache-cli/-/ganache-cli-6.12.2.tgz#c0920f7db0d4ac062ffe2375cb004089806f627a" + integrity sha512-bnmwnJDBDsOWBUP8E/BExWf85TsdDEFelQSzihSJm9VChVO1SHp94YXLP5BlA4j/OTxp0wR4R1Tje9OHOuAJVw== + dependencies: + ethereumjs-util "6.2.1" + source-map-support "0.5.12" + yargs "13.2.4" + +get-caller-file@^2.0.1, get-caller-file@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +get-func-name@^2.0.1, get-func-name@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.2.tgz#0d7cf20cd13fda808669ffa88f4ffc7a3943fc41" + integrity sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ== + +get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.1.tgz#d295644fed4505fc9cde952c37ee12b477a83d82" + integrity sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-proto "^1.0.1" + has-symbols "^1.0.3" + +get-stream@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" + integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== + dependencies: + pump "^3.0.0" + +ghost-testrpc@^0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/ghost-testrpc/-/ghost-testrpc-0.0.2.tgz#c4de9557b1d1ae7b2d20bbe474a91378ca90ce92" + integrity sha512-i08dAEgJ2g8z5buJIrCTduwPIhih3DP+hOCTyyryikfV8T0bNvHnGXO67i0DD1H4GBDETTclPy9njZbfluQYrQ== + dependencies: + chalk "^2.4.2" + node-emoji "^1.10.0" + +glob-parent@^5.1.2, glob-parent@~5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob-parent@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" + integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== + dependencies: + is-glob "^4.0.3" + +glob@7.1.7: + version "7.1.7" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" + integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" + integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^5.0.15: + version "5.0.15" + resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1" + integrity sha512-c9IPMazfRITpmAAKi22dK1VKxGDX9ehhqfABDriL/lzO92xcUKEJPQHrVA/2YHSNFB4iFlykVmWvwo48nr3OxA== + dependencies: + inflight "^1.0.4" + inherits "2" + minimatch "2 || 3" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^7.0.0, glob@^7.1.2, glob@^7.1.3: + version "7.2.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^8.0.3: + version "8.1.0" + resolved "https://registry.yarnpkg.com/glob/-/glob-8.1.0.tgz#d388f656593ef708ee3e34640fdfb99a9fd1c33e" + integrity sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^5.0.1" + once "^1.3.0" + +global-modules@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-2.0.0.tgz#997605ad2345f27f51539bea26574421215c7780" + integrity sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A== + dependencies: + global-prefix "^3.0.0" + +global-prefix@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-3.0.0.tgz#fc85f73064df69f50421f47f883fe5b913ba9b97" + integrity sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg== + dependencies: + ini "^1.3.5" + kind-of "^6.0.2" + which "^1.3.1" + +globals@^13.19.0: + version "13.23.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.23.0.tgz#ef31673c926a0976e1f61dab4dca57e0c0a8af02" + integrity sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA== + dependencies: + type-fest "^0.20.2" + +globby@^10.0.1: + version "10.0.2" + resolved "https://registry.yarnpkg.com/globby/-/globby-10.0.2.tgz#277593e745acaa4646c3ab411289ec47a0392543" + integrity sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg== + dependencies: + "@types/glob" "^7.1.1" + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.0.3" + glob "^7.1.3" + ignore "^5.1.1" + merge2 "^1.2.3" + slash "^3.0.0" + +globby@^11.1.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" + integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== + dependencies: + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.2.9" + ignore "^5.2.0" + merge2 "^1.4.1" + slash "^3.0.0" + +gopd@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" + integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== + dependencies: + get-intrinsic "^1.1.3" + +graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.0: + version "4.2.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" + integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== + +graphemer@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" + integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== + +handlebars@^4.0.1: + version "4.7.8" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.8.tgz#41c42c18b1be2365439188c77c6afae71c0cd9e9" + integrity sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ== + dependencies: + minimist "^1.2.5" + neo-async "^2.6.2" + source-map "^0.6.1" + wordwrap "^1.0.0" + optionalDependencies: + uglify-js "^3.1.4" + +hardhat-contract-sizer@^2.8.0: + version "2.10.0" + resolved "https://registry.yarnpkg.com/hardhat-contract-sizer/-/hardhat-contract-sizer-2.10.0.tgz#72646f43bfe50e9a5702c9720c9bc3e77d93a2c9" + integrity sha512-QiinUgBD5MqJZJh1hl1jc9dNnpJg7eE/w4/4GEnrcmZJJTDbVFNe3+/3Ep24XqISSkYxRz36czcPHKHd/a0dwA== + dependencies: + chalk "^4.0.0" + cli-table3 "^0.6.0" + strip-ansi "^6.0.0" + +hardhat-deploy@^0.11.30: + version "0.11.43" + resolved "https://registry.yarnpkg.com/hardhat-deploy/-/hardhat-deploy-0.11.43.tgz#b22ff15b3ea201b72ba0f17f4b2e182cc950e73e" + integrity sha512-D760CjDtinwjOCpKOvdyRtIJYLQIYXmhfgkFe+AkxlYM9bPZ/T4tZ/xIB2tR89ZT+z0hF1YuZFBXIL3/G/9T5g== + dependencies: + "@ethersproject/abi" "^5.7.0" + "@ethersproject/abstract-signer" "^5.7.0" + "@ethersproject/address" "^5.7.0" + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/constants" "^5.7.0" + "@ethersproject/contracts" "^5.7.0" + "@ethersproject/providers" "^5.7.2" + "@ethersproject/solidity" "^5.7.0" + "@ethersproject/transactions" "^5.7.0" + "@ethersproject/wallet" "^5.7.0" + "@types/qs" "^6.9.7" + axios "^0.21.1" + chalk "^4.1.2" + chokidar "^3.5.2" + debug "^4.3.2" + enquirer "^2.3.6" + ethers "^5.7.0" + form-data "^4.0.0" + fs-extra "^10.0.0" + match-all "^1.2.6" + murmur-128 "^0.2.1" + qs "^6.9.4" + zksync-web3 "^0.14.3" + +hardhat@^2.16.0: + version "2.18.2" + resolved "https://registry.yarnpkg.com/hardhat/-/hardhat-2.18.2.tgz#e82169bafc83c4b2af9b33ac38bae6da5603074e" + integrity sha512-lUVmJg7DsKcUCDpqv57CJl6vHqo/1PeHSfM3+WIa8UtRKmXyVTj1qQK01TDiuetkZBVg9Dn52qU+ZwaJQynaKA== + dependencies: + "@ethersproject/abi" "^5.1.2" + "@metamask/eth-sig-util" "^4.0.0" + "@nomicfoundation/ethereumjs-block" "5.0.2" + "@nomicfoundation/ethereumjs-blockchain" "7.0.2" + "@nomicfoundation/ethereumjs-common" "4.0.2" + "@nomicfoundation/ethereumjs-evm" "2.0.2" + "@nomicfoundation/ethereumjs-rlp" "5.0.2" + "@nomicfoundation/ethereumjs-statemanager" "2.0.2" + "@nomicfoundation/ethereumjs-trie" "6.0.2" + "@nomicfoundation/ethereumjs-tx" "5.0.2" + "@nomicfoundation/ethereumjs-util" "9.0.2" + "@nomicfoundation/ethereumjs-vm" "7.0.2" + "@nomicfoundation/solidity-analyzer" "^0.1.0" + "@sentry/node" "^5.18.1" + "@types/bn.js" "^5.1.0" + "@types/lru-cache" "^5.1.0" + adm-zip "^0.4.16" + aggregate-error "^3.0.0" + ansi-escapes "^4.3.0" + chalk "^2.4.2" + chokidar "^3.4.0" + ci-info "^2.0.0" + debug "^4.1.1" + enquirer "^2.3.0" + env-paths "^2.2.0" + ethereum-cryptography "^1.0.3" + ethereumjs-abi "^0.6.8" + find-up "^2.1.0" + fp-ts "1.19.3" + fs-extra "^7.0.1" + glob "7.2.0" + immutable "^4.0.0-rc.12" + io-ts "1.10.4" + keccak "^3.0.2" + lodash "^4.17.11" + mnemonist "^0.38.0" + mocha "^10.0.0" + p-map "^4.0.0" + raw-body "^2.4.1" + resolve "1.17.0" + semver "^6.3.0" + solc "0.7.3" + source-map-support "^0.5.13" + stacktrace-parser "^0.1.10" + tsort "0.0.1" + undici "^5.14.0" + uuid "^8.3.2" + ws "^7.4.6" + +has-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" + integrity sha512-DyYHfIYwAJmjAjSSPKANxI8bFY9YtFrgkAfinBojQ8YJTOuOuav64tMUJv584SES4xl74PmuaevIyaLESHdTAA== + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has-property-descriptors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz#610708600606d36961ed04c196193b6a607fa861" + integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ== + dependencies: + get-intrinsic "^1.1.1" + +has-proto@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.1.tgz#1885c1305538958aff469fef37937c22795408e0" + integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg== + +has-symbols@^1.0.2, has-symbols@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" + integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== + +has-tostringtag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" + integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== + dependencies: + has-symbols "^1.0.2" + +has@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.4.tgz#2eb2860e000011dae4f1406a86fe80e530fb2ec6" + integrity sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ== + +hash-base@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.0.tgz#55c381d9e06e1d2997a883b4a3fddfe7f0d3af33" + integrity sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA== + dependencies: + inherits "^2.0.4" + readable-stream "^3.6.0" + safe-buffer "^5.2.0" + +hash.js@1.1.7, hash.js@^1.0.0, hash.js@^1.0.3, hash.js@^1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" + integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== + dependencies: + inherits "^2.0.3" + minimalistic-assert "^1.0.1" + +he@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" + integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== + +"heap@>= 0.2.0": + version "0.2.7" + resolved "https://registry.yarnpkg.com/heap/-/heap-0.2.7.tgz#1e6adf711d3f27ce35a81fe3b7bd576c2260a8fc" + integrity sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg== + +hmac-drbg@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" + integrity sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg== + dependencies: + hash.js "^1.0.3" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.1" + +http-errors@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" + integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== + dependencies: + depd "2.0.0" + inherits "2.0.4" + setprototypeof "1.2.0" + statuses "2.0.1" + toidentifier "1.0.1" + +https-proxy-agent@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" + integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== + dependencies: + agent-base "6" + debug "4" + +iconv-lite@0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +ieee754@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== + +ignore@^5.1.1, ignore@^5.2.0, ignore@^5.2.4: + version "5.2.4" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" + integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== + +immutable@^4.0.0-rc.12: + version "4.3.4" + resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.3.4.tgz#2e07b33837b4bb7662f288c244d1ced1ef65a78f" + integrity sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA== + +import-fresh@^3.2.1, import-fresh@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" + integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + +imul@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/imul/-/imul-1.0.1.tgz#9d5867161e8b3de96c2c38d5dc7cb102f35e2ac9" + integrity sha512-WFAgfwPLAjU66EKt6vRdTlKj4nAgIDQzh29JonLa4Bqtl6D8JrIMvWjCnx7xEjVNmP3U0fM5o8ZObk7d0f62bA== + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== + +indent-string@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" + integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +ini@^1.3.5: + version "1.3.8" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" + integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== + +interpret@^1.0.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e" + integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA== + +invert-kv@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02" + integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA== + +io-ts@1.10.4: + version "1.10.4" + resolved "https://registry.yarnpkg.com/io-ts/-/io-ts-1.10.4.tgz#cd5401b138de88e4f920adbcb7026e2d1967e6e2" + integrity sha512-b23PteSnYXSONJ6JQXRAlvJhuw8KOtkqa87W4wDtvMrud/DTJd5X+NpOOI+O/zZwVq6v0VLAaJ+1EDViKEuN9g== + dependencies: + fp-ts "^1.0.0" + +ipaddr.js@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-2.1.0.tgz#2119bc447ff8c257753b196fc5f1ce08a4cdf39f" + integrity sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ== + +is-arguments@^1.0.4: + version "1.1.1" + resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" + integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-buffer@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.5.tgz#ebc252e400d22ff8d77fa09888821a24a658c191" + integrity sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ== + +is-callable@^1.1.3: + version "1.2.7" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" + integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== + +is-core-module@^2.13.0: + version "2.13.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.0.tgz#bb52aa6e2cbd49a30c2ba68c42bf3435ba6072db" + integrity sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ== + dependencies: + has "^1.0.3" + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== + +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + integrity sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w== + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-generator-function@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.10.tgz#f1558baf1ac17e0deea7c0415c438351ff2b3c72" + integrity sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A== + dependencies: + has-tostringtag "^1.0.0" + +is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-hex-prefixed@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz#7d8d37e6ad77e5d127148913c573e082d777f554" + integrity sha512-WvtOiug1VFrE9v1Cydwm+FnXd3+w9GaeVUss5W4v/SLy3UW00vP+6iNF2SdnfiBoLy4bTqVdkftNGTUeOFVsbA== + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-path-inside@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" + integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== + +is-plain-obj@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" + integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== + +is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + integrity sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ== + +is-typed-array@^1.1.3: + version "1.1.12" + resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.12.tgz#d0bab5686ef4a76f7a73097b95470ab199c57d4a" + integrity sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg== + dependencies: + which-typed-array "^1.1.11" + +is-unicode-supported@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" + integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + +js-sdsl@^4.1.4: + version "4.4.2" + resolved "https://registry.yarnpkg.com/js-sdsl/-/js-sdsl-4.4.2.tgz#2e3c031b1f47d3aca8b775532e3ebb0818e7f847" + integrity sha512-dwXFwByc/ajSV6m5bcKAPwe4yDDF6D614pxmIi5odytzxRlwqF6nwoiCek80Ixc7Cvma5awClxrzFtxCQvcM8w== + +js-sha3@0.8.0, js-sha3@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" + integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q== + +js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-yaml@3.x: + version "3.14.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" + integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +js-yaml@4.1.0, js-yaml@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + +json-buffer@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" + integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== + +json-parse-even-better-errors@^2.3.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" + integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-schema-traverse@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" + integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== + +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== + +jsonfile@^2.1.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8" + integrity sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw== + optionalDependencies: + graceful-fs "^4.1.6" + +jsonfile@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" + integrity sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg== + optionalDependencies: + graceful-fs "^4.1.6" + +jsonfile@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" + integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== + dependencies: + universalify "^2.0.0" + optionalDependencies: + graceful-fs "^4.1.6" + +jsonschema@^1.2.4: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jsonschema/-/jsonschema-1.4.1.tgz#cc4c3f0077fb4542982973d8a083b6b34f482dab" + integrity sha512-S6cATIPVv1z0IlxdN+zUk5EPjkGCdnhN4wVSBlvoUO1tOLJootbo9CquNJmbIh4yikWHiUedhRYrNPn1arpEmQ== + +keccak@^3.0.0, keccak@^3.0.2: + version "3.0.4" + resolved "https://registry.yarnpkg.com/keccak/-/keccak-3.0.4.tgz#edc09b89e633c0549da444432ecf062ffadee86d" + integrity sha512-3vKuW0jV8J3XNTzvfyicFR5qvxrSAGl7KIhvgOu5cmWwM7tZRj3fMbj/pfIf4be7aznbc+prBWGjywox/g2Y6Q== + dependencies: + node-addon-api "^2.0.0" + node-gyp-build "^4.2.0" + readable-stream "^3.6.0" + +keyv@^4.5.3: + version "4.5.4" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93" + integrity sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw== + dependencies: + json-buffer "3.0.1" + +kind-of@^6.0.2: + version "6.0.3" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" + integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== + +klaw@^1.0.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/klaw/-/klaw-1.3.1.tgz#4088433b46b3b1ba259d78785d8e96f73ba02439" + integrity sha512-TED5xi9gGQjGpNnvRWknrwAB1eL5GciPfVFOt3Vk1OJCVDQbzuSfrF3hkUQKlsgKrG1F+0t5W0m+Fje1jIt8rw== + optionalDependencies: + graceful-fs "^4.1.9" + +lcid@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf" + integrity sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA== + dependencies: + invert-kv "^2.0.0" + +level-supports@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/level-supports/-/level-supports-4.0.1.tgz#431546f9d81f10ff0fea0e74533a0e875c08c66a" + integrity sha512-PbXpve8rKeNcZ9C1mUicC9auIYFyGpkV9/i6g76tLgANwWhtG2v7I4xNBUlkn3lE2/dZF3Pi0ygYGtLc4RXXdA== + +level-transcoder@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/level-transcoder/-/level-transcoder-1.0.1.tgz#f8cef5990c4f1283d4c86d949e73631b0bc8ba9c" + integrity sha512-t7bFwFtsQeD8cl8NIoQ2iwxA0CL/9IFw7/9gAjOonH0PWTTiRfY7Hq+Ejbsxh86tXobDQ6IOiddjNYIfOBs06w== + dependencies: + buffer "^6.0.3" + module-error "^1.0.1" + +level@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/level/-/level-8.0.0.tgz#41b4c515dabe28212a3e881b61c161ffead14394" + integrity sha512-ypf0jjAk2BWI33yzEaaotpq7fkOPALKAgDBxggO6Q9HGX2MRXn0wbP1Jn/tJv1gtL867+YOjOB49WaUF3UoJNQ== + dependencies: + browser-level "^1.0.1" + classic-level "^1.2.0" + +levn@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" + integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== + dependencies: + prelude-ls "^1.2.1" + type-check "~0.4.0" + +levn@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + integrity sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA== + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + +lines-and-columns@^1.1.6: + version "1.2.4" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" + integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== + +locate-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" + integrity sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA== + dependencies: + p-locate "^2.0.0" + path-exists "^3.0.0" + +locate-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" + integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== + dependencies: + p-locate "^3.0.0" + path-exists "^3.0.0" + +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + +lodash.camelcase@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" + integrity sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA== + +lodash.clonedeep@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" + integrity sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ== + +lodash.merge@^4.6.2: + version "4.6.2" + resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" + integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== + +lodash.truncate@^4.4.2: + version "4.4.2" + resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" + integrity sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw== + +lodash@^4.17.11, lodash@^4.17.15, lodash@^4.17.21: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + +log-symbols@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" + integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== + dependencies: + chalk "^4.1.0" + is-unicode-supported "^0.1.0" + +loupe@^2.3.6: + version "2.3.7" + resolved "https://registry.yarnpkg.com/loupe/-/loupe-2.3.7.tgz#6e69b7d4db7d3ab436328013d37d1c8c3540c697" + integrity sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA== + dependencies: + get-func-name "^2.0.1" + +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +lru_map@^0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/lru_map/-/lru_map-0.3.3.tgz#b5c8351b9464cbd750335a79650a0ec0e56118dd" + integrity sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ== + +make-error@^1.1.1: + version "1.3.6" + resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" + integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== + +map-age-cleaner@^0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a" + integrity sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w== + dependencies: + p-defer "^1.0.0" + +match-all@^1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/match-all/-/match-all-1.2.6.tgz#66d276ad6b49655551e63d3a6ee53e8be0566f8d" + integrity sha512-0EESkXiTkWzrQQntBu2uzKvLu6vVkUGz40nGPbSZuegcfE5UuSzNjLaIu76zJWuaT/2I3Z/8M06OlUOZLGwLlQ== + +mcl-wasm@^0.7.1: + version "0.7.9" + resolved "https://registry.yarnpkg.com/mcl-wasm/-/mcl-wasm-0.7.9.tgz#c1588ce90042a8700c3b60e40efb339fc07ab87f" + integrity sha512-iJIUcQWA88IJB/5L15GnJVnSQJmf/YaxxV6zRavv83HILHaJQb6y0iFyDMdDO0gN8X37tdxmAOrH/P8B6RB8sQ== + +md5.js@^1.3.4: + version "1.3.5" + resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" + integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +mem@^4.0.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/mem/-/mem-4.3.0.tgz#461af497bc4ae09608cdb2e60eefb69bff744178" + integrity sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w== + dependencies: + map-age-cleaner "^0.1.1" + mimic-fn "^2.0.0" + p-is-promise "^2.0.0" + +memory-level@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/memory-level/-/memory-level-1.0.0.tgz#7323c3fd368f9af2f71c3cd76ba403a17ac41692" + integrity sha512-UXzwewuWeHBz5krr7EvehKcmLFNoXxGcvuYhC41tRnkrTbJohtS7kVn9akmgirtRygg+f7Yjsfi8Uu5SGSQ4Og== + dependencies: + abstract-level "^1.0.0" + functional-red-black-tree "^1.0.1" + module-error "^1.0.1" + +memorystream@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2" + integrity sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw== + +merge2@^1.2.3, merge2@^1.3.0, merge2@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + +micro-ftch@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/micro-ftch/-/micro-ftch-0.3.1.tgz#6cb83388de4c1f279a034fb0cf96dfc050853c5f" + integrity sha512-/0LLxhzP0tfiR5hcQebtudP56gUurs2CLkGarnCiB/OqEyUFQ6U3paQi/tgLv0hBJYt2rnr9MNpxz4fiiugstg== + +micromatch@^4.0.4: + version "4.0.5" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" + integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== + dependencies: + braces "^3.0.2" + picomatch "^2.3.1" + +mime-db@1.52.0: + version "1.52.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + +mime-types@^2.1.12: + version "2.1.35" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + +mimic-fn@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + +minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== + +minimalistic-crypto-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" + integrity sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg== + +"minimatch@2 || 3", minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +minimatch@5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.0.1.tgz#fb9022f7528125187c92bd9e9b6366be1cf3415b" + integrity sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g== + dependencies: + brace-expansion "^2.0.1" + +minimatch@9.0.3: + version "9.0.3" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.3.tgz#a6e00c3de44c3a542bfaae70abfc22420a6da825" + integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== + dependencies: + brace-expansion "^2.0.1" + +minimatch@^5.0.1: + version "5.1.6" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96" + integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== + dependencies: + brace-expansion "^2.0.1" + +minimist@^1.2.5, minimist@^1.2.6: + version "1.2.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" + integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== + +mkdirp@0.5.x, mkdirp@^0.5.1: + version "0.5.6" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" + integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== + dependencies: + minimist "^1.2.6" + +mkdirp@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" + integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== + +mnemonist@^0.38.0: + version "0.38.5" + resolved "https://registry.yarnpkg.com/mnemonist/-/mnemonist-0.38.5.tgz#4adc7f4200491237fe0fa689ac0b86539685cade" + integrity sha512-bZTFT5rrPKtPJxj8KSV0WkPyNxl72vQepqqVUAW2ARUpUSF2qXMB6jZj7hW5/k7C1rtpzqbD/IIbJwLXUjCHeg== + dependencies: + obliterator "^2.0.0" + +mocha@10.2.0, mocha@^10.0.0: + version "10.2.0" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.2.0.tgz#1fd4a7c32ba5ac372e03a17eef435bd00e5c68b8" + integrity sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg== + dependencies: + ansi-colors "4.1.1" + browser-stdout "1.3.1" + chokidar "3.5.3" + debug "4.3.4" + diff "5.0.0" + escape-string-regexp "4.0.0" + find-up "5.0.0" + glob "7.2.0" + he "1.2.0" + js-yaml "4.1.0" + log-symbols "4.1.0" + minimatch "5.0.1" + ms "2.1.3" + nanoid "3.3.3" + serialize-javascript "6.0.0" + strip-json-comments "3.1.1" + supports-color "8.1.1" + workerpool "6.2.1" + yargs "16.2.0" + yargs-parser "20.2.4" + yargs-unparser "2.0.0" + +module-error@^1.0.1, module-error@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/module-error/-/module-error-1.0.2.tgz#8d1a48897ca883f47a45816d4fb3e3c6ba404d86" + integrity sha512-0yuvsqSCv8LbaOKhnsQ/T5JhyFlCYLPXK3U2sgV10zoKQwzs/MyfuQUOZQ1V/6OCOJsK/TRgNVrPuPDqtdMFtA== + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +ms@2.1.3: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +murmur-128@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/murmur-128/-/murmur-128-0.2.1.tgz#a9f6568781d2350ecb1bf80c14968cadbeaa4b4d" + integrity sha512-WseEgiRkI6aMFBbj8Cg9yBj/y+OdipwVC7zUo3W2W1JAJITwouUOtpqsmGSg67EQmwwSyod7hsVsWY5LsrfQVg== + dependencies: + encode-utf8 "^1.0.2" + fmix "^0.1.0" + imul "^1.0.0" + +nanoid@3.3.3: + version "3.3.3" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25" + integrity sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w== + +napi-macros@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/napi-macros/-/napi-macros-2.2.2.tgz#817fef20c3e0e40a963fbf7b37d1600bd0201044" + integrity sha512-hmEVtAGYzVQpCKdbQea4skABsdXW4RUh5t5mJ2zzqowJS2OyXZTU1KhDVFhx+NlWZ4ap9mqR9TcDO3LTTttd+g== + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== + +neo-async@^2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" + integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== + +nice-try@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" + integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== + +node-addon-api@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-2.0.2.tgz#432cfa82962ce494b132e9d72a15b29f71ff5d32" + integrity sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA== + +node-emoji@^1.10.0: + version "1.11.0" + resolved "https://registry.yarnpkg.com/node-emoji/-/node-emoji-1.11.0.tgz#69a0150e6946e2f115e9d7ea4df7971e2628301c" + integrity sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A== + dependencies: + lodash "^4.17.21" + +node-gyp-build@^4.2.0, node-gyp-build@^4.3.0: + version "4.6.1" + resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.6.1.tgz#24b6d075e5e391b8d5539d98c7fc5c210cac8a3e" + integrity sha512-24vnklJmyRS8ViBNI8KbtK/r/DmXQMRiOMXTNz2nrTnAYUwjmEEbnnpB/+kt+yWRv73bPsSPRFddrcIbAxSiMQ== + +nofilter@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/nofilter/-/nofilter-3.1.0.tgz#c757ba68801d41ff930ba2ec55bab52ca184aa66" + integrity sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g== + +nopt@3.x: + version "3.0.6" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" + integrity sha512-4GUt3kSEYmk4ITxzB/b9vaIDfUVWN/Ml1Fwl11IlnIG2iaJ9O6WXZ9SrYM9NLI8OCBieN2Y8SWC2oJV0RQ7qYg== + dependencies: + abbrev "1" + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +npm-run-path@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" + integrity sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw== + dependencies: + path-key "^2.0.0" + +number-to-bn@1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/number-to-bn/-/number-to-bn-1.7.0.tgz#bb3623592f7e5f9e0030b1977bd41a0c53fe1ea0" + integrity sha512-wsJ9gfSz1/s4ZsJN01lyonwuxA1tml6X1yBDnfpMglypcBRFZZkus26EdPSlqS5GJfYddVZa22p3VNb3z5m5Ig== + dependencies: + bn.js "4.11.6" + strip-hex-prefix "1.0.0" + +object-inspect@^1.9.0: + version "1.13.1" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.1.tgz#b96c6109324ccfef6b12216a956ca4dc2ff94bc2" + integrity sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ== + +obliterator@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/obliterator/-/obliterator-2.0.4.tgz#fa650e019b2d075d745e44f1effeb13a2adbe816" + integrity sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ== + +once@1.x, once@^1.3.0, once@^1.3.1, once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + +optionator@^0.8.1: + version "0.8.3" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" + integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== + dependencies: + deep-is "~0.1.3" + fast-levenshtein "~2.0.6" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + word-wrap "~1.2.3" + +optionator@^0.9.3: + version "0.9.3" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.3.tgz#007397d44ed1872fdc6ed31360190f81814e2c64" + integrity sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg== + dependencies: + "@aashutoshrathi/word-wrap" "^1.2.3" + deep-is "^0.1.3" + fast-levenshtein "^2.0.6" + levn "^0.4.1" + prelude-ls "^1.2.1" + type-check "^0.4.0" + +ordinal@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/ordinal/-/ordinal-1.0.3.tgz#1a3c7726a61728112f50944ad7c35c06ae3a0d4d" + integrity sha512-cMddMgb2QElm8G7vdaa02jhUNbTSrhsgAGUz1OokD83uJTwSUn+nKoNoKVVaRa08yF6sgfO7Maou1+bgLd9rdQ== + +os-locale@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.1.0.tgz#a802a6ee17f24c10483ab9935719cef4ed16bf1a" + integrity sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q== + dependencies: + execa "^1.0.0" + lcid "^2.0.0" + mem "^4.0.0" + +os-tmpdir@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + integrity sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g== + +p-defer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c" + integrity sha512-wB3wfAxZpk2AzOfUMJNL+d36xothRSyj8EXOa4f6GMqYDN9BJaaSISbsk+wS9abmnebVw95C2Kb5t85UmpCxuw== + +p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + integrity sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow== + +p-is-promise@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-2.1.0.tgz#918cebaea248a62cf7ffab8e3bca8c5f882fc42e" + integrity sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg== + +p-limit@^1.1.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" + integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== + dependencies: + p-try "^1.0.0" + +p-limit@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + +p-limit@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + +p-locate@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" + integrity sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg== + dependencies: + p-limit "^1.1.0" + +p-locate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" + integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== + dependencies: + p-limit "^2.0.0" + +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" + +p-map@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" + integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== + dependencies: + aggregate-error "^3.0.0" + +p-try@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" + integrity sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww== + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + +parse-json@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" + integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== + dependencies: + "@babel/code-frame" "^7.0.0" + error-ex "^1.3.1" + json-parse-even-better-errors "^2.3.0" + lines-and-columns "^1.1.6" + +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + integrity sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ== + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + +path-key@^2.0.0, path-key@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + integrity sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw== + +path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-parse@^1.0.6, path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + +pathval@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.1.tgz#8534e77a77ce7ac5a2512ea21e0fdb8fcf6c3d8d" + integrity sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ== + +pbkdf2@^3.0.17: + version "3.1.2" + resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.2.tgz#dd822aa0887580e52f1a039dc3eda108efae3075" + integrity sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA== + dependencies: + create-hash "^1.1.2" + create-hmac "^1.1.4" + ripemd160 "^2.0.1" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +pify@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" + integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== + +pluralize@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-8.0.0.tgz#1a6fa16a38d12a1901e0320fa017051c539ce3b1" + integrity sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA== + +prelude-ls@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" + integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== + +prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + integrity sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w== + +prettier-plugin-solidity@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/prettier-plugin-solidity/-/prettier-plugin-solidity-1.1.3.tgz#9a35124f578404caf617634a8cab80862d726cba" + integrity sha512-fQ9yucPi2sBbA2U2Xjh6m4isUTJ7S7QLc/XDDsktqqxYfTwdYKJ0EnnywXHwCGAaYbQNK+HIYPL1OemxuMsgeg== + dependencies: + "@solidity-parser/parser" "^0.16.0" + semver "^7.3.8" + solidity-comments-extractor "^0.0.7" + +prettier@^2.1.2, prettier@^2.3.1, prettier@^2.8.3: + version "2.8.8" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" + integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== + +prettier@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.0.3.tgz#432a51f7ba422d1469096c0fdc28e235db8f9643" + integrity sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg== + +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +punycode@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f" + integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== + +pvtsutils@^1.3.2, pvtsutils@^1.3.5: + version "1.3.5" + resolved "https://registry.yarnpkg.com/pvtsutils/-/pvtsutils-1.3.5.tgz#b8705b437b7b134cd7fd858f025a23456f1ce910" + integrity sha512-ARvb14YB9Nm2Xi6nBq1ZX6dAM0FsJnuk+31aUp4TrcZEdKUlSqOqsxJHUPJDNE3qiIp+iUPEIeR6Je/tgV7zsA== + dependencies: + tslib "^2.6.1" + +pvutils@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/pvutils/-/pvutils-1.1.3.tgz#f35fc1d27e7cd3dfbd39c0826d173e806a03f5a3" + integrity sha512-pMpnA0qRdFp32b1sJl1wOJNxZLQ2cbQx+k6tjNtZ8CpvVhNqEPRgivZ2WOUev2YMajecdH7ctUPDvEe87nariQ== + +qs@^6.9.4: + version "6.11.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.2.tgz#64bea51f12c1f5da1bc01496f48ffcff7c69d7d9" + integrity sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA== + dependencies: + side-channel "^1.0.4" + +queue-microtask@^1.2.2, queue-microtask@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== + +randombytes@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +raw-body@^2.4.1: + version "2.5.2" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.2.tgz#99febd83b90e08975087e8f1f9419a149366b68a" + integrity sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA== + dependencies: + bytes "3.1.2" + http-errors "2.0.0" + iconv-lite "0.4.24" + unpipe "1.0.0" + +readable-stream@^3.6.0: + version "3.6.2" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" + integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + +rechoir@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" + integrity sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw== + dependencies: + resolve "^1.1.6" + +recursive-readdir@^2.2.2: + version "2.2.3" + resolved "https://registry.yarnpkg.com/recursive-readdir/-/recursive-readdir-2.2.3.tgz#e726f328c0d69153bcabd5c322d3195252379372" + integrity sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA== + dependencies: + minimatch "^3.0.5" + +reduce-flatten@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/reduce-flatten/-/reduce-flatten-2.0.0.tgz#734fd84e65f375d7ca4465c69798c25c9d10ae27" + integrity sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w== + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== + +require-from-string@^2.0.0, require-from-string@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" + integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== + +require-main-filename@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" + integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== + +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + +resolve@1.1.x: + version "1.1.7" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" + integrity sha512-9znBF0vBcaSN3W2j7wKvdERPwqTxSpCq+if5C0WoTCyV9n24rua28jeuQ2pL/HOf+yUe/Mef+H/5p60K0Id3bg== + +resolve@1.17.0: + version "1.17.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444" + integrity sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w== + dependencies: + path-parse "^1.0.6" + +resolve@^1.1.6, resolve@^1.8.1: + version "1.22.8" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" + integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== + dependencies: + is-core-module "^2.13.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + +rimraf@^2.2.8: + version "2.7.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" + integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== + dependencies: + glob "^7.1.3" + +rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +ripemd160@^2.0.0, ripemd160@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" + integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + +rlp@^2.2.3, rlp@^2.2.4: + version "2.2.7" + resolved "https://registry.yarnpkg.com/rlp/-/rlp-2.2.7.tgz#33f31c4afac81124ac4b283e2bd4d9720b30beaf" + integrity sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ== + dependencies: + bn.js "^5.2.0" + +run-parallel-limit@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/run-parallel-limit/-/run-parallel-limit-1.1.0.tgz#be80e936f5768623a38a963262d6bef8ff11e7ba" + integrity sha512-jJA7irRNM91jaKc3Hcl1npHsFLOXOoTkPCUL1JEa1R82O2miplXXRaGdjW/KM/98YQWDhJLiSs793CnXfblJUw== + dependencies: + queue-microtask "^1.2.2" + +run-parallel@^1.1.9: + version "1.2.0" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + dependencies: + queue-microtask "^1.2.2" + +rustbn.js@~0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/rustbn.js/-/rustbn.js-0.2.0.tgz#8082cb886e707155fd1cb6f23bd591ab8d55d0ca" + integrity sha512-4VlvkRUuCJvr2J6Y0ImW7NvTCriMi7ErOAqWk1y69vAdoNIzCF3yPmgeNzx+RQTLEDFq5sHfscn1MwHxP9hNfA== + +safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +"safer-buffer@>= 2.1.2 < 3": + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +sc-istanbul@^0.4.5: + version "0.4.6" + resolved "https://registry.yarnpkg.com/sc-istanbul/-/sc-istanbul-0.4.6.tgz#cf6784355ff2076f92d70d59047d71c13703e839" + integrity sha512-qJFF/8tW/zJsbyfh/iT/ZM5QNHE3CXxtLJbZsL+CzdJLBsPD7SedJZoUA4d8iAcN2IoMp/Dx80shOOd2x96X/g== + dependencies: + abbrev "1.0.x" + async "1.x" + escodegen "1.8.x" + esprima "2.7.x" + glob "^5.0.15" + handlebars "^4.0.1" + js-yaml "3.x" + mkdirp "0.5.x" + nopt "3.x" + once "1.x" + resolve "1.1.x" + supports-color "^3.1.0" + which "^1.1.1" + wordwrap "^1.0.0" + +scrypt-js@3.0.1, scrypt-js@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-3.0.1.tgz#d314a57c2aef69d1ad98a138a21fe9eafa9ee312" + integrity sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA== + +secp256k1@^4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/secp256k1/-/secp256k1-4.0.3.tgz#c4559ecd1b8d3c1827ed2d1b94190d69ce267303" + integrity sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA== + dependencies: + elliptic "^6.5.4" + node-addon-api "^2.0.0" + node-gyp-build "^4.2.0" + +semver@^5.5.0: + version "5.7.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" + integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== + +semver@^6.3.0: + version "6.3.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" + integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== + +semver@^7.3.4, semver@^7.3.8, semver@^7.5.2, semver@^7.5.4: + version "7.5.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== + dependencies: + lru-cache "^6.0.0" + +serialize-javascript@6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" + integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== + dependencies: + randombytes "^2.1.0" + +set-blocking@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== + +set-function-length@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.1.1.tgz#4bc39fafb0307224a33e106a7d35ca1218d659ed" + integrity sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ== + dependencies: + define-data-property "^1.1.1" + get-intrinsic "^1.2.1" + gopd "^1.0.1" + has-property-descriptors "^1.0.0" + +setimmediate@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + integrity sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA== + +setprototypeof@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" + integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== + +sha.js@^2.4.0, sha.js@^2.4.8: + version "2.4.11" + resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" + integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + integrity sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg== + dependencies: + shebang-regex "^1.0.0" + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + integrity sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ== + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +shelljs@^0.8.3: + version "0.8.5" + resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.5.tgz#de055408d8361bed66c669d2f000538ced8ee20c" + integrity sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow== + dependencies: + glob "^7.0.0" + interpret "^1.0.0" + rechoir "^0.6.2" + +side-channel@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" + integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== + dependencies: + call-bind "^1.0.0" + get-intrinsic "^1.0.2" + object-inspect "^1.9.0" + +signal-exit@^3.0.0: + version "3.0.7" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== + +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + +slice-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" + integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== + dependencies: + ansi-styles "^4.0.0" + astral-regex "^2.0.0" + is-fullwidth-code-point "^3.0.0" + +solc@0.7.3: + version "0.7.3" + resolved "https://registry.yarnpkg.com/solc/-/solc-0.7.3.tgz#04646961bd867a744f63d2b4e3c0701ffdc7d78a" + integrity sha512-GAsWNAjGzIDg7VxzP6mPjdurby3IkGCjQcM8GFYZT6RyaoUZKmMU6Y7YwG+tFGhv7dwZ8rmR4iwFDrrD99JwqA== + dependencies: + command-exists "^1.2.8" + commander "3.0.2" + follow-redirects "^1.12.1" + fs-extra "^0.30.0" + js-sha3 "0.8.0" + memorystream "^0.3.1" + require-from-string "^2.0.0" + semver "^5.5.0" + tmp "0.0.33" + +solhint@^3.4.1: + version "3.6.2" + resolved "https://registry.yarnpkg.com/solhint/-/solhint-3.6.2.tgz#2b2acbec8fdc37b2c68206a71ba89c7f519943fe" + integrity sha512-85EeLbmkcPwD+3JR7aEMKsVC9YrRSxd4qkXuMzrlf7+z2Eqdfm1wHWq1ffTuo5aDhoZxp2I9yF3QkxZOxOL7aQ== + dependencies: + "@solidity-parser/parser" "^0.16.0" + ajv "^6.12.6" + antlr4 "^4.11.0" + ast-parents "^0.0.1" + chalk "^4.1.2" + commander "^10.0.0" + cosmiconfig "^8.0.0" + fast-diff "^1.2.0" + glob "^8.0.3" + ignore "^5.2.4" + js-yaml "^4.1.0" + lodash "^4.17.21" + pluralize "^8.0.0" + semver "^7.5.2" + strip-ansi "^6.0.1" + table "^6.8.1" + text-table "^0.2.0" + optionalDependencies: + prettier "^2.8.3" + +solidity-comments-extractor@^0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/solidity-comments-extractor/-/solidity-comments-extractor-0.0.7.tgz#99d8f1361438f84019795d928b931f4e5c39ca19" + integrity sha512-wciNMLg/Irp8OKGrh3S2tfvZiZ0NEyILfcRCXCD4mp7SgK/i9gzLfhY2hY7VMCQJ3kH9UB9BzNdibIVMchzyYw== + +solidity-coverage@^0.8.3: + version "0.8.5" + resolved "https://registry.yarnpkg.com/solidity-coverage/-/solidity-coverage-0.8.5.tgz#64071c3a0c06a0cecf9a7776c35f49edc961e875" + integrity sha512-6C6N6OV2O8FQA0FWA95FdzVH+L16HU94iFgg5wAFZ29UpLFkgNI/DRR2HotG1bC0F4gAc/OMs2BJI44Q/DYlKQ== + dependencies: + "@ethersproject/abi" "^5.0.9" + "@solidity-parser/parser" "^0.16.0" + chalk "^2.4.2" + death "^1.1.0" + detect-port "^1.3.0" + difflib "^0.2.4" + fs-extra "^8.1.0" + ghost-testrpc "^0.0.2" + global-modules "^2.0.0" + globby "^10.0.1" + jsonschema "^1.2.4" + lodash "^4.17.15" + mocha "10.2.0" + node-emoji "^1.10.0" + pify "^4.0.1" + recursive-readdir "^2.2.2" + sc-istanbul "^0.4.5" + semver "^7.3.4" + shelljs "^0.8.3" + web3-utils "^1.3.6" + +source-map-support@0.5.12: + version "0.5.12" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.12.tgz#b4f3b10d51857a5af0138d3ce8003b201613d599" + integrity sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map-support@^0.5.13: + version "0.5.21" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" + integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map@^0.6.0, source-map@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +source-map@~0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.2.0.tgz#dab73fbcfc2ba819b4de03bd6f6eaa48164b3f9d" + integrity sha512-CBdZ2oa/BHhS4xj5DlhjWNHcan57/5YuvfdLf17iVmIpd9KRm+DFLmC6nBNj+6Ua7Kt3TmOjDpQT1aTYOQtoUA== + dependencies: + amdefine ">=0.0.4" + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== + +stacktrace-parser@^0.1.10: + version "0.1.10" + resolved "https://registry.yarnpkg.com/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz#29fb0cae4e0d0b85155879402857a1639eb6051a" + integrity sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg== + dependencies: + type-fest "^0.7.1" + +statuses@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" + integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== + +string-format@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/string-format/-/string-format-2.0.0.tgz#f2df2e7097440d3b65de31b6d40d54c96eaffb9b" + integrity sha512-bbEs3scLeYNXLecRRuk6uJxdXUSj6le/8rNPHChIJTn2V79aXVTR1EH2OH5zLKKoz0V02fOUKZZcw01pLUShZA== + +string-width@^3.0.0, string-width@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" + integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== + dependencies: + emoji-regex "^7.0.1" + is-fullwidth-code-point "^2.0.0" + strip-ansi "^5.1.0" + +string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" + integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== + dependencies: + ansi-regex "^4.1.0" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-eof@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" + integrity sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q== + +strip-hex-prefix@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz#0c5f155fef1151373377de9dbb588da05500e36f" + integrity sha512-q8d4ue7JGEiVcypji1bALTos+0pWtyGlivAWyPuTkHzuTCJqrK9sWxYQZUq6Nq3cuyv3bm734IhHvHtGGURU6A== + dependencies: + is-hex-prefixed "1.0.0" + +strip-json-comments@3.1.1, strip-json-comments@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + +supports-color@8.1.1: + version "8.1.1" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + +supports-color@^3.1.0: + version "3.2.3" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" + integrity sha512-Jds2VIYDrlp5ui7t8abHN2bjAu4LV/q4N2KivFPpGH0lrka0BMq/33AmECUXlKPcHigkNaqfXRENFju+rlcy+A== + dependencies: + has-flag "^1.0.0" + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + +table-layout@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/table-layout/-/table-layout-1.0.2.tgz#c4038a1853b0136d63365a734b6931cf4fad4a04" + integrity sha512-qd/R7n5rQTRFi+Zf2sk5XVVd9UQl6ZkduPFC3S7WEGJAmetDTjY3qPN50eSKzwuzEyQKy5TN2TiZdkIjos2L6A== + dependencies: + array-back "^4.0.1" + deep-extend "~0.6.0" + typical "^5.2.0" + wordwrapjs "^4.0.0" + +table@^6.8.0, table@^6.8.1: + version "6.8.1" + resolved "https://registry.yarnpkg.com/table/-/table-6.8.1.tgz#ea2b71359fe03b017a5fbc296204471158080bdf" + integrity sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA== + dependencies: + ajv "^8.0.1" + lodash.truncate "^4.4.2" + slice-ansi "^4.0.0" + string-width "^4.2.3" + strip-ansi "^6.0.1" + +text-table@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== + +tmp@0.0.33: + version "0.0.33" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" + integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== + dependencies: + os-tmpdir "~1.0.2" + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +toidentifier@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" + integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== + +ts-api-utils@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.0.3.tgz#f12c1c781d04427313dbac808f453f050e54a331" + integrity sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg== + +ts-command-line-args@^2.2.0: + version "2.5.1" + resolved "https://registry.yarnpkg.com/ts-command-line-args/-/ts-command-line-args-2.5.1.tgz#e64456b580d1d4f6d948824c274cf6fa5f45f7f0" + integrity sha512-H69ZwTw3rFHb5WYpQya40YAX2/w7Ut75uUECbgBIsLmM+BNuYnxsltfyyLMxy6sEeKxgijLTnQtLd0nKd6+IYw== + dependencies: + chalk "^4.1.0" + command-line-args "^5.1.1" + command-line-usage "^6.1.0" + string-format "^2.0.0" + +ts-essentials@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/ts-essentials/-/ts-essentials-1.0.4.tgz#ce3b5dade5f5d97cf69889c11bf7d2da8555b15a" + integrity sha512-q3N1xS4vZpRouhYHDPwO0bDW3EZ6SK9CrrDHxi/D6BPReSjpVgWIOpLS2o0gSBZm+7q/wyKp6RVM1AeeW7uyfQ== + +ts-essentials@^7.0.1: + version "7.0.3" + resolved "https://registry.yarnpkg.com/ts-essentials/-/ts-essentials-7.0.3.tgz#686fd155a02133eedcc5362dc8b5056cde3e5a38" + integrity sha512-8+gr5+lqO3G84KdiTSMRLtuyJ+nTBVRKuCrK4lidMPdVeEp0uqC875uE5NMcaA7YYMN7XsNiFQuMvasF8HT/xQ== + +ts-generator@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ts-generator/-/ts-generator-0.1.1.tgz#af46f2fb88a6db1f9785977e9590e7bcd79220ab" + integrity sha512-N+ahhZxTLYu1HNTQetwWcx3so8hcYbkKBHTr4b4/YgObFTIKkOSSsaa+nal12w8mfrJAyzJfETXawbNjSfP2gQ== + dependencies: + "@types/mkdirp" "^0.5.2" + "@types/prettier" "^2.1.1" + "@types/resolve" "^0.0.8" + chalk "^2.4.1" + glob "^7.1.2" + mkdirp "^0.5.1" + prettier "^2.1.2" + resolve "^1.8.1" + ts-essentials "^1.0.0" + +ts-node@^10.9.1: + version "10.9.1" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.1.tgz#e73de9102958af9e1f0b168a6ff320e25adcff4b" + integrity sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw== + dependencies: + "@cspotcode/source-map-support" "^0.8.0" + "@tsconfig/node10" "^1.0.7" + "@tsconfig/node12" "^1.0.7" + "@tsconfig/node14" "^1.0.0" + "@tsconfig/node16" "^1.0.2" + acorn "^8.4.1" + acorn-walk "^8.1.1" + arg "^4.1.0" + create-require "^1.1.0" + diff "^4.0.1" + make-error "^1.1.1" + v8-compile-cache-lib "^3.0.1" + yn "3.1.1" + +tslib@^1.9.3: + version "1.14.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" + integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== + +tslib@^2.4.0, tslib@^2.6.1, tslib@^2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" + integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== + +tsort@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/tsort/-/tsort-0.0.1.tgz#e2280f5e817f8bf4275657fd0f9aebd44f5a2786" + integrity sha512-Tyrf5mxF8Ofs1tNoxA13lFeZ2Zrbd6cKbuH3V+MQ5sb6DtBj5FjrXVsRWT8YvNAQTqNoz66dz1WsbigI22aEnw== + +tweetnacl-util@^0.15.1: + version "0.15.1" + resolved "https://registry.yarnpkg.com/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz#b80fcdb5c97bcc508be18c44a4be50f022eea00b" + integrity sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw== + +tweetnacl@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-1.0.3.tgz#ac0af71680458d8a6378d0d0d050ab1407d35596" + integrity sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw== + +type-check@^0.4.0, type-check@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" + integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== + dependencies: + prelude-ls "^1.2.1" + +type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + integrity sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg== + dependencies: + prelude-ls "~1.1.2" + +type-detect@^4.0.0, type-detect@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" + integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== + +type-fest@^0.20.2: + version "0.20.2" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" + integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== + +type-fest@^0.21.3: + version "0.21.3" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" + integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== + +type-fest@^0.7.1: + version "0.7.1" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.7.1.tgz#8dda65feaf03ed78f0a3f9678f1869147f7c5c48" + integrity sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg== + +typechain@^8.1.1: + version "8.3.2" + resolved "https://registry.yarnpkg.com/typechain/-/typechain-8.3.2.tgz#1090dd8d9c57b6ef2aed3640a516bdbf01b00d73" + integrity sha512-x/sQYr5w9K7yv3es7jo4KTX05CLxOf7TRWwoHlrjRh8H82G64g+k7VuWPJlgMo6qrjfCulOdfBjiaDtmhFYD/Q== + dependencies: + "@types/prettier" "^2.1.1" + debug "^4.3.1" + fs-extra "^7.0.0" + glob "7.1.7" + js-sha3 "^0.8.0" + lodash "^4.17.15" + mkdirp "^1.0.4" + prettier "^2.3.1" + ts-command-line-args "^2.2.0" + ts-essentials "^7.0.1" + +typeforce@^1.6.1: + version "1.18.0" + resolved "https://registry.yarnpkg.com/typeforce/-/typeforce-1.18.0.tgz#d7416a2c5845e085034d70fcc5b6cc4a90edbfdc" + integrity sha512-7uc1O8h1M1g0rArakJdf0uLRSSgFcYexrVoKo+bzJd32gd4gDy2L/Z+8/FjPnU9ydY3pEnVPtr9FyscYY60K1g== + +typescript@^5.1.6: + version "5.2.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.2.2.tgz#5ebb5e5a5b75f085f22bc3f8460fba308310fa78" + integrity sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w== + +typical@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/typical/-/typical-4.0.0.tgz#cbeaff3b9d7ae1e2bbfaf5a4e6f11eccfde94fc4" + integrity sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw== + +typical@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/typical/-/typical-5.2.0.tgz#4daaac4f2b5315460804f0acf6cb69c52bb93066" + integrity sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg== + +uglify-js@^3.1.4: + version "3.17.4" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.17.4.tgz#61678cf5fa3f5b7eb789bb345df29afb8257c22c" + integrity sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g== + +undici-types@~5.25.1: + version "5.25.3" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.25.3.tgz#e044115914c85f0bcbb229f346ab739f064998c3" + integrity sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA== + +undici@^5.14.0: + version "5.28.4" + resolved "https://registry.yarnpkg.com/undici/-/undici-5.28.4.tgz#6b280408edb6a1a604a9b20340f45b422e373068" + integrity sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g== + dependencies: + "@fastify/busboy" "^2.0.0" + +universalify@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== + +universalify@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" + integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== + +unpipe@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== + +uri-js@^4.2.2: + version "4.4.1" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + dependencies: + punycode "^2.1.0" + +utf8@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/utf8/-/utf8-3.0.0.tgz#f052eed1364d696e769ef058b183df88c87f69d1" + integrity sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ== + +util-deprecate@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== + +util@^0.12.5: + version "0.12.5" + resolved "https://registry.yarnpkg.com/util/-/util-0.12.5.tgz#5f17a6059b73db61a875668781a1c2b136bd6fbc" + integrity sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA== + dependencies: + inherits "^2.0.3" + is-arguments "^1.0.4" + is-generator-function "^1.0.7" + is-typed-array "^1.1.3" + which-typed-array "^1.1.2" + +uuid@^8.3.2: + version "8.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" + integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== + +v8-compile-cache-lib@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" + integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== + +web3-errors@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/web3-errors/-/web3-errors-1.1.4.tgz#5667a0a5f66fc936e101ef32032ccc1e8ca4d5a1" + integrity sha512-WahtszSqILez+83AxGecVroyZsMuuRT+KmQp4Si5P4Rnqbczno1k748PCrZTS1J4UCPmXMG2/Vt+0Bz2zwXkwQ== + dependencies: + web3-types "^1.3.1" + +web3-types@^1.3.1, web3-types@^1.5.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/web3-types/-/web3-types-1.6.0.tgz#ebe7f140c31f7cc0ad15f238ad7e7ac72797ff3b" + integrity sha512-qgOtADqlD5hw+KPKBUGaXAcdNLL0oh6qTeVgXwewCfbL/lG9R+/GrgMQB1gbTJ3cit8hMwtH8KX2Em6OwO0HRw== + +web3-utils@^1.3.6: + version "1.10.3" + resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.10.3.tgz#f1db99c82549c7d9f8348f04ffe4e0188b449714" + integrity sha512-OqcUrEE16fDBbGoQtZXWdavsPzbGIDc5v3VrRTZ0XrIpefC/viZ1ZU9bGEemazyS0catk/3rkOOxpzTfY+XsyQ== + dependencies: + "@ethereumjs/util" "^8.1.0" + bn.js "^5.2.1" + ethereum-bloom-filters "^1.0.6" + ethereum-cryptography "^2.1.2" + ethjs-unit "0.1.6" + number-to-bn "1.7.0" + randombytes "^2.1.0" + utf8 "3.0.0" + +web3-utils@^4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-4.2.1.tgz#326bc6e9e4d047f7b38ba68bee1399c4f9f621e3" + integrity sha512-Fk29BlEqD9Q9Cnw4pBkKw7czcXiRpsSco/BzEUl4ye0ZTSHANQFfjsfQmNm4t7uY11u6Ah+8F3tNjBeU4CA80A== + dependencies: + ethereum-cryptography "^2.0.0" + eventemitter3 "^5.0.1" + web3-errors "^1.1.4" + web3-types "^1.5.0" + web3-validator "^2.0.4" + +web3-validator@^2.0.4: + version "2.0.5" + resolved "https://registry.yarnpkg.com/web3-validator/-/web3-validator-2.0.5.tgz#de1984bdb34f292251b86400dba7169700db0849" + integrity sha512-2gLOSW8XqEN5pw5jVUm20EB7A8SbQiekpAtiI0JBmCIV0a2rp97v8FgWY5E3UEqnw5WFfEqvcDVW92EyynDTyQ== + dependencies: + ethereum-cryptography "^2.0.0" + util "^0.12.5" + web3-errors "^1.1.4" + web3-types "^1.5.0" + zod "^3.21.4" + +which-module@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.1.tgz#776b1fe35d90aebe99e8ac15eb24093389a4a409" + integrity sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ== + +which-typed-array@^1.1.11, which-typed-array@^1.1.2: + version "1.1.13" + resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.13.tgz#870cd5be06ddb616f504e7b039c4c24898184d36" + integrity sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow== + dependencies: + available-typed-arrays "^1.0.5" + call-bind "^1.0.4" + for-each "^0.3.3" + gopd "^1.0.1" + has-tostringtag "^1.0.0" + +which@^1.1.1, which@^1.2.9, which@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +word-wrap@~1.2.3: + version "1.2.5" + resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.5.tgz#d2c45c6dd4fbce621a66f136cbe328afd0410b34" + integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA== + +wordwrap@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q== + +wordwrapjs@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/wordwrapjs/-/wordwrapjs-4.0.1.tgz#d9790bccfb110a0fc7836b5ebce0937b37a8b98f" + integrity sha512-kKlNACbvHrkpIw6oPeYDSmdCTu2hdMHoyXLTcUKala++lx5Y+wjJ/e474Jqv5abnVmwxw08DiTuHmw69lJGksA== + dependencies: + reduce-flatten "^2.0.0" + typical "^5.2.0" + +workerpool@6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343" + integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw== + +wrap-ansi@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" + integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q== + dependencies: + ansi-styles "^3.2.0" + string-width "^3.0.0" + strip-ansi "^5.0.0" + +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + +ws@7.4.6: + version "7.4.6" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c" + integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A== + +ws@^7.4.6: + version "7.5.9" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.9.tgz#54fa7db29f4c7cec68b1ddd3a89de099942bb591" + integrity sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q== + +y18n@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf" + integrity sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ== + +y18n@^5.0.5: + version "5.0.8" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" + integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== + +yallist@^3.0.2: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +yargs-parser@20.2.4: + version "20.2.4" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" + integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== + +yargs-parser@^13.1.0: + version "13.1.2" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38" + integrity sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + +yargs-parser@^20.2.2: + version "20.2.9" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" + integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== + +yargs-unparser@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" + integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== + dependencies: + camelcase "^6.0.0" + decamelize "^4.0.0" + flat "^5.0.2" + is-plain-obj "^2.1.0" + +yargs@13.2.4: + version "13.2.4" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.2.4.tgz#0b562b794016eb9651b98bd37acf364aa5d6dc83" + integrity sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg== + dependencies: + cliui "^5.0.0" + find-up "^3.0.0" + get-caller-file "^2.0.1" + os-locale "^3.1.0" + require-directory "^2.1.1" + require-main-filename "^2.0.0" + set-blocking "^2.0.0" + string-width "^3.0.0" + which-module "^2.0.0" + y18n "^4.0.0" + yargs-parser "^13.1.0" + +yargs@16.2.0: + version "16.2.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" + integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.0" + y18n "^5.0.5" + yargs-parser "^20.2.2" + +yn@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" + integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== + +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== + +zksync-web3@^0.14.3: + version "0.14.3" + resolved "https://registry.yarnpkg.com/zksync-web3/-/zksync-web3-0.14.3.tgz#64ac2a16d597464c3fc4ae07447a8007631c57c9" + integrity sha512-hT72th4AnqyLW1d5Jlv8N2B/qhEnl2NePK2A3org7tAa24niem/UAaHMkEvmWI3SF9waYUPtqAtjpf+yvQ9zvQ== + +zod@^3.21.4: + version "3.22.4" + resolved "https://registry.yarnpkg.com/zod/-/zod-3.22.4.tgz#f31c3a9386f61b1f228af56faa9255e845cf3fff" + integrity sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==